From 1897bdc4d33167e9036460631d1349e59d841f2d Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 13 Nov 2014 13:46:09 +1100 Subject: [PATCH 0001/9457] mmu_notifier: add mmu_notifier_invalidate_range() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This notifier closes an important gap in the current mmu_notifier implementation, the existing callbacks are called too early or too late to reliably manage a non-CPU TLB. Specifically, invalidate_range_start() is called when all pages are still mapped and invalidate_range_end() when all pages are unmapped and potentially freed. This is fine when the users of the mmu_notifiers manage their own SoftTLB, like KVM does. When the TLB is managed in software it is easy to wipe out entries for a given range and prevent new entries to be established until invalidate_range_end is called. But when the user of mmu_notifiers has to manage a hardware TLB it can still wipe out TLB entries in invalidate_range_start, but it can't make sure that no new TLB entries in the given range are established between invalidate_range_start and invalidate_range_end. To avoid silent data corruption the entries in the non-CPU TLB need to be flushed when the pages are unmapped (at this point in time no _new_ TLB entries can be established in the non-CPU TLB) but not yet freed (as the non-CPU TLB may still have _existing_ entries pointing to the pages about to be freed). To fix this problem we need to catch the moment when the Linux VMM flushes remote TLBs (as a non-CPU TLB is not very CPU TLB), as this is the point in time when the pages are unmapped but _not_ yet freed. The mmu_notifier_invalidate_range() function aims to catch that moment. IOMMU code will be one user of the notifier-callback. Currently this is only the AMD IOMMUv2 driver, but its code is about to be more generalized and converted to a generic IOMMU-API extension to fit the needs of similar functionality in other IOMMUs as well. The current attempt in the AMD IOMMUv2 driver to work around the invalidate_range_start/end() shortcoming is to assign an empty page table to the non-CPU TLB between any invalidata_range_start/end calls. With the empty page-table assigned, every page-table walk to re-fill the non-CPU TLB will cause a page-fault reported to the IOMMU driver via an interrupt, possibly causing interrupt storms. The page-fault handler in the AMD IOMMUv2 driver doesn't handle the fault if an invalidate_range_start/end pair is active, it just reports back SUCCESS to the device and let it refault the page. But existing hardware (newer Radeon GPUs) that makes use of this feature don't re-fault indefinitly, after a certain number of faults for the same address the device enters a failure state and needs to be resetted. To avoid the GPUs entering a failure state we need to get rid of the empty-page-table workaround and use the mmu_notifier_invalidate_range() function introduced with this patch. Signed-off-by: Joerg Roedel Reviewed-by: Andrea Arcangeli Reviewed-by: Jérôme Glisse Cc: Peter Zijlstra Cc: Rik van Riel Cc: Hugh Dickins Cc: Mel Gorman Cc: Johannes Weiner Cc: Jay Cornwall Cc: Oded Gabbay Cc: Suravee Suthikulpanit Cc: Jesse Barnes Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Oded Gabbay --- include/linux/mmu_notifier.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 88787bb4b3b9..17907908d1df 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -242,6 +242,11 @@ static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, __mmu_notifier_invalidate_range_end(mm, start, end); } +static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + static inline void mmu_notifier_mm_init(struct mm_struct *mm) { mm->mmu_notifier_mm = NULL; @@ -342,6 +347,11 @@ static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, { } +static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + static inline void mmu_notifier_mm_init(struct mm_struct *mm) { } -- GitLab From 34ee645e83b60ae3d5955f70ab9ab9a159136673 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 13 Nov 2014 13:46:09 +1100 Subject: [PATCH 0002/9457] mmu_notifier: call mmu_notifier_invalidate_range() from VMM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add calls to the new mmu_notifier_invalidate_range() function to all places in the VMM that need it. Signed-off-by: Joerg Roedel Reviewed-by: Andrea Arcangeli Reviewed-by: Jérôme Glisse Cc: Peter Zijlstra Cc: Rik van Riel Cc: Hugh Dickins Cc: Mel Gorman Cc: Johannes Weiner Cc: Jay Cornwall Cc: Oded Gabbay Cc: Suravee Suthikulpanit Cc: Jesse Barnes Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Oded Gabbay --- include/linux/mmu_notifier.h | 41 ++++++++++++++++++++++++++++++++++++ kernel/events/uprobes.c | 2 +- mm/fremap.c | 2 +- mm/huge_memory.c | 9 ++++---- mm/hugetlb.c | 7 +++++- mm/ksm.c | 4 ++-- mm/memory.c | 3 ++- mm/migrate.c | 3 ++- mm/rmap.c | 2 +- 9 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 17907908d1df..966da2b4b803 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -284,6 +284,44 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) __young; \ }) +#define ptep_clear_flush_notify(__vma, __address, __ptep) \ +({ \ + unsigned long ___addr = __address & PAGE_MASK; \ + struct mm_struct *___mm = (__vma)->vm_mm; \ + pte_t ___pte; \ + \ + ___pte = ptep_clear_flush(__vma, __address, __ptep); \ + mmu_notifier_invalidate_range(___mm, ___addr, \ + ___addr + PAGE_SIZE); \ + \ + ___pte; \ +}) + +#define pmdp_clear_flush_notify(__vma, __haddr, __pmd) \ +({ \ + unsigned long ___haddr = __haddr & HPAGE_PMD_MASK; \ + struct mm_struct *___mm = (__vma)->vm_mm; \ + pmd_t ___pmd; \ + \ + ___pmd = pmdp_clear_flush(__vma, __haddr, __pmd); \ + mmu_notifier_invalidate_range(___mm, ___haddr, \ + ___haddr + HPAGE_PMD_SIZE); \ + \ + ___pmd; \ +}) + +#define pmdp_get_and_clear_notify(__mm, __haddr, __pmd) \ +({ \ + unsigned long ___haddr = __haddr & HPAGE_PMD_MASK; \ + pmd_t ___pmd; \ + \ + ___pmd = pmdp_get_and_clear(__mm, __haddr, __pmd); \ + mmu_notifier_invalidate_range(__mm, ___haddr, \ + ___haddr + HPAGE_PMD_SIZE); \ + \ + ___pmd; \ +}) + /* * set_pte_at_notify() sets the pte _after_ running the notifier. * This is safe to start by updating the secondary MMUs, because the primary MMU @@ -362,6 +400,9 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) #define ptep_clear_flush_young_notify ptep_clear_flush_young #define pmdp_clear_flush_young_notify pmdp_clear_flush_young +#define ptep_clear_flush_notify ptep_clear_flush +#define pmdp_clear_flush_notify pmdp_clear_flush +#define pmdp_get_and_clear_notify pmdp_get_and_clear #define set_pte_at_notify set_pte_at #endif /* CONFIG_MMU_NOTIFIER */ diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 1d0af8a2c646..bc143cf56cab 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -193,7 +193,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, } flush_cache_page(vma, addr, pte_pfn(*ptep)); - ptep_clear_flush(vma, addr, ptep); + ptep_clear_flush_notify(vma, addr, ptep); set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot)); page_remove_rmap(page); diff --git a/mm/fremap.c b/mm/fremap.c index 72b8fa361433..9129013732d7 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -37,7 +37,7 @@ static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, if (pte_present(pte)) { flush_cache_page(vma, addr, pte_pfn(pte)); - pte = ptep_clear_flush(vma, addr, ptep); + pte = ptep_clear_flush_notify(vma, addr, ptep); page = vm_normal_page(vma, addr, pte); if (page) { if (pte_dirty(pte)) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index de984159cf0b..1d89526ed531 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1036,7 +1036,7 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm, goto out_free_pages; VM_BUG_ON_PAGE(!PageHead(page), page); - pmdp_clear_flush(vma, haddr, pmd); + pmdp_clear_flush_notify(vma, haddr, pmd); /* leave pmd empty until pte is filled */ pgtable = pgtable_trans_huge_withdraw(mm, pmd); @@ -1179,7 +1179,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, pmd_t entry; entry = mk_huge_pmd(new_page, vma->vm_page_prot); entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); - pmdp_clear_flush(vma, haddr, pmd); + pmdp_clear_flush_notify(vma, haddr, pmd); page_add_new_anon_rmap(new_page, vma, haddr); mem_cgroup_commit_charge(new_page, memcg, false); lru_cache_add_active_or_unevictable(new_page, vma); @@ -1512,7 +1512,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, pmd_t entry; ret = 1; if (!prot_numa) { - entry = pmdp_get_and_clear(mm, addr, pmd); + entry = pmdp_get_and_clear_notify(mm, addr, pmd); if (pmd_numa(entry)) entry = pmd_mknonnuma(entry); entry = pmd_modify(entry, newprot); @@ -1644,6 +1644,7 @@ static int __split_huge_page_splitting(struct page *page, * serialize against split_huge_page*. */ pmdp_splitting_flush(vma, address, pmd); + ret = 1; spin_unlock(ptl); } @@ -2834,7 +2835,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, pmd_t _pmd; int i; - pmdp_clear_flush(vma, haddr, pmd); + pmdp_clear_flush_notify(vma, haddr, pmd); /* leave pmd empty until pte is filled */ pgtable = pgtable_trans_huge_withdraw(mm, pmd); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9fd722769927..2e6add04fa1b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2598,8 +2598,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, } set_huge_pte_at(dst, addr, dst_pte, entry); } else { - if (cow) + if (cow) { huge_ptep_set_wrprotect(src, addr, src_pte); + mmu_notifier_invalidate_range(src, mmun_start, + mmun_end); + } entry = huge_ptep_get(src_pte); ptepage = pte_page(entry); get_page(ptepage); @@ -2899,6 +2902,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, /* Break COW */ huge_ptep_clear_flush(vma, address, ptep); + mmu_notifier_invalidate_range(mm, mmun_start, mmun_end); set_huge_pte_at(mm, address, ptep, make_huge_pte(vma, new_page, 1)); page_remove_rmap(old_page); @@ -3374,6 +3378,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, * and that page table be reused and filled with junk. */ flush_tlb_range(vma, start, end); + mmu_notifier_invalidate_range(mm, start, end); mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); mmu_notifier_invalidate_range_end(mm, start, end); diff --git a/mm/ksm.c b/mm/ksm.c index 6b2e337bc03c..d247efab5073 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -892,7 +892,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, * this assure us that no O_DIRECT can happen after the check * or in the middle of the check. */ - entry = ptep_clear_flush(vma, addr, ptep); + entry = ptep_clear_flush_notify(vma, addr, ptep); /* * Check that no O_DIRECT or similar I/O is in progress on the * page @@ -960,7 +960,7 @@ static int replace_page(struct vm_area_struct *vma, struct page *page, page_add_anon_rmap(kpage, vma, addr); flush_cache_page(vma, addr, pte_pfn(*ptep)); - ptep_clear_flush(vma, addr, ptep); + ptep_clear_flush_notify(vma, addr, ptep); set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot)); page_remove_rmap(page); diff --git a/mm/memory.c b/mm/memory.c index 3e503831e042..655fd3d34bb0 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -238,6 +238,7 @@ static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) { tlb->need_flush = 0; tlb_flush(tlb); + mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end); #ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); #endif @@ -2234,7 +2235,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, * seen in the presence of one thread doing SMC and another * thread doing COW. */ - ptep_clear_flush(vma, address, page_table); + ptep_clear_flush_notify(vma, address, page_table); page_add_new_anon_rmap(new_page, vma, address); mem_cgroup_commit_charge(new_page, memcg, false); lru_cache_add_active_or_unevictable(new_page, vma); diff --git a/mm/migrate.c b/mm/migrate.c index 01439953abf5..41945cb0ca38 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1854,7 +1854,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, */ flush_cache_range(vma, mmun_start, mmun_end); page_add_anon_rmap(new_page, vma, mmun_start); - pmdp_clear_flush(vma, mmun_start, pmd); + pmdp_clear_flush_notify(vma, mmun_start, pmd); set_pmd_at(mm, mmun_start, pmd, entry); flush_tlb_range(vma, mmun_start, mmun_end); update_mmu_cache_pmd(vma, address, &entry); @@ -1862,6 +1862,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, if (page_count(page) != 2) { set_pmd_at(mm, mmun_start, pmd, orig_entry); flush_tlb_range(vma, mmun_start, mmun_end); + mmu_notifier_invalidate_range(mm, mmun_start, mmun_end); update_mmu_cache_pmd(vma, address, &entry); page_remove_rmap(new_page); goto fail_putback; diff --git a/mm/rmap.c b/mm/rmap.c index 19886fb2f13a..d3eb1e02d1c6 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1378,7 +1378,7 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount, /* Nuke the page table entry. */ flush_cache_page(vma, address, pte_pfn(*pte)); - pteval = ptep_clear_flush(vma, address, pte); + pteval = ptep_clear_flush_notify(vma, address, pte); /* If nonlinear, store the file page offset in the pte. */ if (page->index != linear_page_index(vma, address)) { -- GitLab From 0f0a327fa12cd55de5e7f8c05a70ac3d047f405e Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 13 Nov 2014 13:46:09 +1100 Subject: [PATCH 0003/9457] mmu_notifier: add the callback for mmu_notifier_invalidate_range() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the mmu_notifier_invalidate_range() calls are in place, add the callback to allow subsystems to register against it. Signed-off-by: Joerg Roedel Reviewed-by: Andrea Arcangeli Reviewed-by: Jérôme Glisse Cc: Peter Zijlstra Cc: Rik van Riel Cc: Hugh Dickins Cc: Mel Gorman Cc: Johannes Weiner Cc: Jay Cornwall Cc: Oded Gabbay Cc: Suravee Suthikulpanit Cc: Jesse Barnes Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Oded Gabbay --- include/linux/mmu_notifier.h | 37 +++++++++++++++++++++++++++++++----- mm/mmu_notifier.c | 25 ++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 966da2b4b803..94d19f64cecf 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -98,11 +98,11 @@ struct mmu_notifier_ops { /* * invalidate_range_start() and invalidate_range_end() must be * paired and are called only when the mmap_sem and/or the - * locks protecting the reverse maps are held. The subsystem - * must guarantee that no additional references are taken to - * the pages in the range established between the call to - * invalidate_range_start() and the matching call to - * invalidate_range_end(). + * locks protecting the reverse maps are held. If the subsystem + * can't guarantee that no additional references are taken to + * the pages in the range, it has to implement the + * invalidate_range() notifier to remove any references taken + * after invalidate_range_start(). * * Invalidation of multiple concurrent ranges may be * optionally permitted by the driver. Either way the @@ -144,6 +144,29 @@ struct mmu_notifier_ops { void (*invalidate_range_end)(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long start, unsigned long end); + + /* + * invalidate_range() is either called between + * invalidate_range_start() and invalidate_range_end() when the + * VM has to free pages that where unmapped, but before the + * pages are actually freed, or outside of _start()/_end() when + * a (remote) TLB is necessary. + * + * If invalidate_range() is used to manage a non-CPU TLB with + * shared page-tables, it not necessary to implement the + * invalidate_range_start()/end() notifiers, as + * invalidate_range() alread catches the points in time when an + * external TLB range needs to be flushed. + * + * The invalidate_range() function is called under the ptl + * spin-lock and not allowed to sleep. + * + * Note that this function might be called with just a sub-range + * of what was passed to invalidate_range_start()/end(), if + * called between those functions. + */ + void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, + unsigned long start, unsigned long end); }; /* @@ -190,6 +213,8 @@ extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end); extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, unsigned long start, unsigned long end); +extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, + unsigned long start, unsigned long end); static inline void mmu_notifier_release(struct mm_struct *mm) { @@ -245,6 +270,8 @@ static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, unsigned long start, unsigned long end) { + if (mm_has_notifiers(mm)) + __mmu_notifier_invalidate_range(mm, start, end); } static inline void mmu_notifier_mm_init(struct mm_struct *mm) diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 2c8da9825fe3..3b9b3d0741b2 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -193,6 +193,16 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, id = srcu_read_lock(&srcu); hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { + /* + * Call invalidate_range here too to avoid the need for the + * subsystem of having to register an invalidate_range_end + * call-back when there is invalidate_range already. Usually a + * subsystem registers either invalidate_range_start()/end() or + * invalidate_range(), so this will be no additional overhead + * (besides the pointer check). + */ + if (mn->ops->invalidate_range) + mn->ops->invalidate_range(mn, mm, start, end); if (mn->ops->invalidate_range_end) mn->ops->invalidate_range_end(mn, mm, start, end); } @@ -200,6 +210,21 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, } EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_end); +void __mmu_notifier_invalidate_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + struct mmu_notifier *mn; + int id; + + id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->invalidate_range) + mn->ops->invalidate_range(mn, mm, start, end); + } + srcu_read_unlock(&srcu, id); +} +EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range); + static int do_mmu_notifier_register(struct mmu_notifier *mn, struct mm_struct *mm, int take_mmap_sem) -- GitLab From e7cc3dd48c7b0a4b2135a5a2145ad43a8192fa6a Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 13 Nov 2014 13:46:09 +1100 Subject: [PATCH 0004/9457] iommu/amd: use new invalidate_range mmu-notifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make use of the new invalidate_range mmu_notifier call-back and remove the old logic of assigning an empty page-table between invalidate_range_start and invalidate_range_end. Signed-off-by: Joerg Roedel Tested-by: Oded Gabbay Reviewed-by: Andrea Arcangeli Reviewed-by: Jérôme Glisse Cc: Peter Zijlstra Cc: Rik van Riel Cc: Hugh Dickins Cc: Mel Gorman Cc: Johannes Weiner Cc: Jay Cornwall Cc: Suravee Suthikulpanit Cc: Jesse Barnes Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Oded Gabbay --- drivers/iommu/amd_iommu_v2.c | 61 ++++++------------------------------ 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 90d734bbf467..f724bdc50d25 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -92,13 +92,6 @@ static spinlock_t state_lock; static struct workqueue_struct *iommu_wq; -/* - * Empty page table - Used between - * mmu_notifier_invalidate_range_start and - * mmu_notifier_invalidate_range_end - */ -static u64 *empty_page_table; - static void free_pasid_states(struct device_state *dev_state); static u16 device_id(struct pci_dev *pdev) @@ -418,46 +411,21 @@ static void mn_invalidate_page(struct mmu_notifier *mn, __mn_flush_page(mn, address); } -static void mn_invalidate_range_start(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - struct pasid_state *pasid_state; - struct device_state *dev_state; - unsigned long flags; - - pasid_state = mn_to_state(mn); - dev_state = pasid_state->device_state; - - spin_lock_irqsave(&pasid_state->lock, flags); - if (pasid_state->mmu_notifier_count == 0) { - amd_iommu_domain_set_gcr3(dev_state->domain, - pasid_state->pasid, - __pa(empty_page_table)); - } - pasid_state->mmu_notifier_count += 1; - spin_unlock_irqrestore(&pasid_state->lock, flags); -} - -static void mn_invalidate_range_end(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long start, unsigned long end) +static void mn_invalidate_range(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, unsigned long end) { struct pasid_state *pasid_state; struct device_state *dev_state; - unsigned long flags; pasid_state = mn_to_state(mn); dev_state = pasid_state->device_state; - spin_lock_irqsave(&pasid_state->lock, flags); - pasid_state->mmu_notifier_count -= 1; - if (pasid_state->mmu_notifier_count == 0) { - amd_iommu_domain_set_gcr3(dev_state->domain, - pasid_state->pasid, - __pa(pasid_state->mm->pgd)); - } - spin_unlock_irqrestore(&pasid_state->lock, flags); + if ((start ^ (end - 1)) < PAGE_SIZE) + amd_iommu_flush_page(dev_state->domain, pasid_state->pasid, + start); + else + amd_iommu_flush_tlb(dev_state->domain, pasid_state->pasid); } static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) @@ -482,8 +450,7 @@ static struct mmu_notifier_ops iommu_mn = { .release = mn_release, .clear_flush_young = mn_clear_flush_young, .invalidate_page = mn_invalidate_page, - .invalidate_range_start = mn_invalidate_range_start, - .invalidate_range_end = mn_invalidate_range_end, + .invalidate_range = mn_invalidate_range, }; static void set_pri_tag_status(struct pasid_state *pasid_state, @@ -954,18 +921,10 @@ static int __init amd_iommu_v2_init(void) if (iommu_wq == NULL) goto out; - ret = -ENOMEM; - empty_page_table = (u64 *)get_zeroed_page(GFP_KERNEL); - if (empty_page_table == NULL) - goto out_destroy_wq; - amd_iommu_register_ppr_notifier(&ppr_nb); return 0; -out_destroy_wq: - destroy_workqueue(iommu_wq); - out: return ret; } @@ -999,8 +958,6 @@ static void __exit amd_iommu_v2_exit(void) } destroy_workqueue(iommu_wq); - - free_page((unsigned long)empty_page_table); } module_init(amd_iommu_v2_init); -- GitLab From a015c1e92639cd65ebb49350abdf5ad15bce4448 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 10 Nov 2014 10:57:36 +0200 Subject: [PATCH 0005/9457] iommu/amd: fix accounting of device_state This patch fixes a bug in the accounting of the device_state. In the current code, the device_state was put (decremented) too many times, which sometimes lead to the driver getting stuck permanently in put_device_state_wait(). That happen because the device_state->count would go below zero, which is never supposed to happen. The root cause is that the device_state was decremented in put_pasid_state() and put_pasid_state_wait() but also in all the functions that call those functions. Therefore, the device_state was decremented twice in each of these code paths. The fix is to decouple the device_state accounting from the pasid_state accounting - remove the call to put_device_state() from the put_pasid_state() and the put_pasid_state_wait()) Signed-off-by: Oded Gabbay --- drivers/iommu/amd_iommu_v2.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index f724bdc50d25..1e6360e7ae44 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c @@ -272,10 +272,8 @@ static void free_pasid_state(struct pasid_state *pasid_state) static void put_pasid_state(struct pasid_state *pasid_state) { - if (atomic_dec_and_test(&pasid_state->count)) { - put_device_state(pasid_state->device_state); + if (atomic_dec_and_test(&pasid_state->count)) wake_up(&pasid_state->wq); - } } static void put_pasid_state_wait(struct pasid_state *pasid_state) @@ -284,9 +282,7 @@ static void put_pasid_state_wait(struct pasid_state *pasid_state) prepare_to_wait(&pasid_state->wq, &wait, TASK_UNINTERRUPTIBLE); - if (atomic_dec_and_test(&pasid_state->count)) - put_device_state(pasid_state->device_state); - else + if (!atomic_dec_and_test(&pasid_state->count)) schedule(); finish_wait(&pasid_state->wq, &wait); -- GitLab From 62a7b7fbd08ef745bb51e8728e89125a0ba6327e Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 16 Jan 2014 17:35:44 +0200 Subject: [PATCH 0006/9457] drm/radeon: reduce number of free VMIDs and pipes in KV To support HSA on KV, we need to limit the number of vmids and pipes that are available for radeon's use with KV. This patch reserves VMIDs 8-15 for amdkfd (so radeon can only use VMIDs 0-7) and also makes radeon thinks that KV has only a single MEC with a single pipe in it v3: Use define for static vmid allocation in radeon Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/radeon/cik.c | 48 +++++++++++++++++------------------ drivers/gpu/drm/radeon/cikd.h | 2 ++ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 57a359d34830..03e160b39aa0 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -4684,12 +4684,11 @@ static int cik_mec_init(struct radeon_device *rdev) /* * KV: 2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total * CI/KB: 1 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 32 Queues total + * Nonetheless, we assign only 1 pipe because all other pipes will + * be handled by KFD */ - if (rdev->family == CHIP_KAVERI) - rdev->mec.num_mec = 2; - else - rdev->mec.num_mec = 1; - rdev->mec.num_pipe = 4; + rdev->mec.num_mec = 1; + rdev->mec.num_pipe = 1; rdev->mec.num_queue = rdev->mec.num_mec * rdev->mec.num_pipe * 8; if (rdev->mec.hpd_eop_obj == NULL) { @@ -4831,28 +4830,24 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) /* init the pipes */ mutex_lock(&rdev->srbm_mutex); - for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) { - int me = (i < 4) ? 1 : 2; - int pipe = (i < 4) ? i : (i - 4); - eop_gpu_addr = rdev->mec.hpd_eop_gpu_addr + (i * MEC_HPD_SIZE * 2); + eop_gpu_addr = rdev->mec.hpd_eop_gpu_addr; - cik_srbm_select(rdev, me, pipe, 0, 0); + cik_srbm_select(rdev, 0, 0, 0, 0); - /* write the EOP addr */ - WREG32(CP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); - WREG32(CP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8); + /* write the EOP addr */ + WREG32(CP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); + WREG32(CP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8); - /* set the VMID assigned */ - WREG32(CP_HPD_EOP_VMID, 0); + /* set the VMID assigned */ + WREG32(CP_HPD_EOP_VMID, 0); + + /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ + tmp = RREG32(CP_HPD_EOP_CONTROL); + tmp &= ~EOP_SIZE_MASK; + tmp |= order_base_2(MEC_HPD_SIZE / 8); + WREG32(CP_HPD_EOP_CONTROL, tmp); - /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ - tmp = RREG32(CP_HPD_EOP_CONTROL); - tmp &= ~EOP_SIZE_MASK; - tmp |= order_base_2(MEC_HPD_SIZE / 8); - WREG32(CP_HPD_EOP_CONTROL, tmp); - } - cik_srbm_select(rdev, 0, 0, 0, 0); mutex_unlock(&rdev->srbm_mutex); /* init the queues. Just two for now. */ @@ -5906,8 +5901,13 @@ int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) */ int cik_vm_init(struct radeon_device *rdev) { - /* number of VMs */ - rdev->vm_manager.nvm = 16; + /* + * number of VMs + * VMID 0 is reserved for System + * radeon graphics/compute will use VMIDs 1-7 + * amdkfd will use VMIDs 8-15 + */ + rdev->vm_manager.nvm = RADEON_NUM_OF_VMIDS; /* base offset of vram pages */ if (rdev->flags & RADEON_IS_IGP) { u64 tmp = RREG32(MC_VM_FB_OFFSET); diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 0c6e1b55d968..fae4d0c68478 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -30,6 +30,8 @@ #define CIK_RB_BITMAP_WIDTH_PER_SH 2 #define HAWAII_RB_BITMAP_WIDTH_PER_SH 4 +#define RADEON_NUM_OF_VMIDS 8 + /* DIDT IND registers */ #define DIDT_SQ_CTRL0 0x0 # define DIDT_CTRL_EN (1 << 0) -- GitLab From 28b57b856b635ea0d44f1281e2efdc963c100ea3 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 11 Feb 2014 18:28:24 +0200 Subject: [PATCH 0007/9457] drm/radeon/cik: Don't touch int of pipes 1-7 amdkfd should set interrupts for pipes 1-7. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/radeon/cik.c | 71 +----------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 03e160b39aa0..dd8f50f9962f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7297,8 +7297,7 @@ static int cik_irq_init(struct radeon_device *rdev) int cik_irq_set(struct radeon_device *rdev) { u32 cp_int_cntl; - u32 cp_m1p0, cp_m1p1, cp_m1p2, cp_m1p3; - u32 cp_m2p0, cp_m2p1, cp_m2p2, cp_m2p3; + u32 cp_m1p0; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; u32 grbm_int_cntl = 0; @@ -7332,13 +7331,6 @@ int cik_irq_set(struct radeon_device *rdev) dma_cntl1 = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m1p1 = RREG32(CP_ME1_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m1p2 = RREG32(CP_ME1_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m1p3 = RREG32(CP_ME1_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m2p0 = RREG32(CP_ME2_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m2p1 = RREG32(CP_ME2_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m2p2 = RREG32(CP_ME2_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; - cp_m2p3 = RREG32(CP_ME2_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; if (rdev->flags & RADEON_IS_IGP) thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL) & @@ -7360,33 +7352,6 @@ int cik_irq_set(struct radeon_device *rdev) case 0: cp_m1p0 |= TIME_STAMP_INT_ENABLE; break; - case 1: - cp_m1p1 |= TIME_STAMP_INT_ENABLE; - break; - case 2: - cp_m1p2 |= TIME_STAMP_INT_ENABLE; - break; - case 3: - cp_m1p2 |= TIME_STAMP_INT_ENABLE; - break; - default: - DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe); - break; - } - } else if (ring->me == 2) { - switch (ring->pipe) { - case 0: - cp_m2p0 |= TIME_STAMP_INT_ENABLE; - break; - case 1: - cp_m2p1 |= TIME_STAMP_INT_ENABLE; - break; - case 2: - cp_m2p2 |= TIME_STAMP_INT_ENABLE; - break; - case 3: - cp_m2p2 |= TIME_STAMP_INT_ENABLE; - break; default: DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe); break; @@ -7403,33 +7368,6 @@ int cik_irq_set(struct radeon_device *rdev) case 0: cp_m1p0 |= TIME_STAMP_INT_ENABLE; break; - case 1: - cp_m1p1 |= TIME_STAMP_INT_ENABLE; - break; - case 2: - cp_m1p2 |= TIME_STAMP_INT_ENABLE; - break; - case 3: - cp_m1p2 |= TIME_STAMP_INT_ENABLE; - break; - default: - DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe); - break; - } - } else if (ring->me == 2) { - switch (ring->pipe) { - case 0: - cp_m2p0 |= TIME_STAMP_INT_ENABLE; - break; - case 1: - cp_m2p1 |= TIME_STAMP_INT_ENABLE; - break; - case 2: - cp_m2p2 |= TIME_STAMP_INT_ENABLE; - break; - case 3: - cp_m2p2 |= TIME_STAMP_INT_ENABLE; - break; default: DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe); break; @@ -7518,13 +7456,6 @@ int cik_irq_set(struct radeon_device *rdev) WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, dma_cntl1); WREG32(CP_ME1_PIPE0_INT_CNTL, cp_m1p0); - WREG32(CP_ME1_PIPE1_INT_CNTL, cp_m1p1); - WREG32(CP_ME1_PIPE2_INT_CNTL, cp_m1p2); - WREG32(CP_ME1_PIPE3_INT_CNTL, cp_m1p3); - WREG32(CP_ME2_PIPE0_INT_CNTL, cp_m2p0); - WREG32(CP_ME2_PIPE1_INT_CNTL, cp_m2p1); - WREG32(CP_ME2_PIPE2_INT_CNTL, cp_m2p2); - WREG32(CP_ME2_PIPE3_INT_CNTL, cp_m2p3); WREG32(GRBM_INT_CNTL, grbm_int_cntl); -- GitLab From ebff8453d3a57a2405c4d96d9f9c4f4acc7d4d79 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 28 Jan 2014 14:43:19 +0200 Subject: [PATCH 0008/9457] drm/radeon: Report doorbell configuration to amdkfd radeon and amdkfd share the doorbell aperture. radeon sets it up, takes the doorbells required for its own rings and reports the setup to amdkfd. radeon reserved doorbells are at the start of the doorbell aperture. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/radeon/radeon.h | 4 ++++ drivers/gpu/drm/radeon/radeon_device.c | 31 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 908f349a6362..f6cb42ea43a6 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -701,6 +701,10 @@ struct radeon_doorbell { int radeon_doorbell_get(struct radeon_device *rdev, u32 *page); void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell); +void radeon_doorbell_get_kfd_info(struct radeon_device *rdev, + phys_addr_t *aperture_base, + size_t *aperture_size, + size_t *start_offset); /* * IRQS. diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index ea2676954dde..0b41f5eeb125 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -377,6 +377,37 @@ void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell) __clear_bit(doorbell, rdev->doorbell.used); } +/** + * radeon_doorbell_get_kfd_info - Report doorbell configuration required to + * setup KFD + * + * @rdev: radeon_device pointer + * @aperture_base: output returning doorbell aperture base physical address + * @aperture_size: output returning doorbell aperture size in bytes + * @start_offset: output returning # of doorbell bytes reserved for radeon. + * + * Radeon and the KFD share the doorbell aperture. Radeon sets it up, + * takes doorbells required for its own rings and reports the setup to KFD. + * Radeon reserved doorbells are at the start of the doorbell aperture. + */ +void radeon_doorbell_get_kfd_info(struct radeon_device *rdev, + phys_addr_t *aperture_base, + size_t *aperture_size, + size_t *start_offset) +{ + /* The first num_doorbells are used by radeon. + * KFD takes whatever's left in the aperture. */ + if (rdev->doorbell.size > rdev->doorbell.num_doorbells * sizeof(u32)) { + *aperture_base = rdev->doorbell.base; + *aperture_size = rdev->doorbell.size; + *start_offset = rdev->doorbell.num_doorbells * sizeof(u32); + } else { + *aperture_base = 0; + *aperture_size = 0; + *start_offset = 0; + } +} + /* * radeon_wb_*() * Writeback is the the method by which the the GPU updates special pages -- GitLab From 1c0a46255f8d7daf5b601668836e185fd1294e94 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 14 Jul 2014 15:36:08 +0300 Subject: [PATCH 0009/9457] drm/radeon: adding synchronization for GRBM GFX Implementing a lock for selecting and accessing shader engines and arrays. This lock will make sure that radeon and amdkfd are not colliding when accessing shader engines and arrays with GRBM_GFX_INDEX register. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/radeon/cik.c | 26 ++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon.h | 2 ++ drivers/gpu/drm/radeon/radeon_device.c | 1 + 3 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index dd8f50f9962f..2e742a591dfc 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -1563,6 +1563,8 @@ static const u32 godavari_golden_registers[] = static void cik_init_golden_registers(struct radeon_device *rdev) { + /* Some of the registers might be dependent on GRBM_GFX_INDEX */ + mutex_lock(&rdev->grbm_idx_mutex); switch (rdev->family) { case CHIP_BONAIRE: radeon_program_register_sequence(rdev, @@ -1637,6 +1639,7 @@ static void cik_init_golden_registers(struct radeon_device *rdev) default: break; } + mutex_unlock(&rdev->grbm_idx_mutex); } /** @@ -3428,6 +3431,7 @@ static void cik_setup_rb(struct radeon_device *rdev, u32 disabled_rbs = 0; u32 enabled_rbs = 0; + mutex_lock(&rdev->grbm_idx_mutex); for (i = 0; i < se_num; i++) { for (j = 0; j < sh_per_se; j++) { cik_select_se_sh(rdev, i, j); @@ -3439,6 +3443,7 @@ static void cik_setup_rb(struct radeon_device *rdev, } } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); + mutex_unlock(&rdev->grbm_idx_mutex); mask = 1; for (i = 0; i < max_rb_num_per_se * se_num; i++) { @@ -3449,6 +3454,7 @@ static void cik_setup_rb(struct radeon_device *rdev, rdev->config.cik.backend_enable_mask = enabled_rbs; + mutex_lock(&rdev->grbm_idx_mutex); for (i = 0; i < se_num; i++) { cik_select_se_sh(rdev, i, 0xffffffff); data = 0; @@ -3476,6 +3482,7 @@ static void cik_setup_rb(struct radeon_device *rdev, WREG32(PA_SC_RASTER_CONFIG, data); } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); + mutex_unlock(&rdev->grbm_idx_mutex); } /** @@ -3693,6 +3700,12 @@ static void cik_gpu_init(struct radeon_device *rdev) /* set HW defaults for 3D engine */ WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); + mutex_lock(&rdev->grbm_idx_mutex); + /* + * making sure that the following register writes will be broadcasted + * to all the shaders + */ + cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(SX_DEBUG_1, 0x20); WREG32(TA_CNTL_AUX, 0x00010000); @@ -3748,6 +3761,7 @@ static void cik_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); WREG32(PA_SC_ENHANCE, ENABLE_PA_SC_OUT_OF_ORDER); + mutex_unlock(&rdev->grbm_idx_mutex); udelay(50); } @@ -6068,6 +6082,7 @@ static void cik_wait_for_rlc_serdes(struct radeon_device *rdev) u32 i, j, k; u32 mask; + mutex_lock(&rdev->grbm_idx_mutex); for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { cik_select_se_sh(rdev, i, j); @@ -6079,6 +6094,7 @@ static void cik_wait_for_rlc_serdes(struct radeon_device *rdev) } } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); + mutex_unlock(&rdev->grbm_idx_mutex); mask = SE_MASTER_BUSY_MASK | GC_MASTER_BUSY | TC0_MASTER_BUSY | TC1_MASTER_BUSY; for (k = 0; k < rdev->usec_timeout; k++) { @@ -6213,10 +6229,12 @@ static int cik_rlc_resume(struct radeon_device *rdev) WREG32(RLC_LB_CNTR_INIT, 0); WREG32(RLC_LB_CNTR_MAX, 0x00008000); + mutex_lock(&rdev->grbm_idx_mutex); cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); WREG32(RLC_LB_PARAMS, 0x00600408); WREG32(RLC_LB_CNTL, 0x80000004); + mutex_unlock(&rdev->grbm_idx_mutex); WREG32(RLC_MC_CNTL, 0); WREG32(RLC_UCODE_CNTL, 0); @@ -6283,11 +6301,13 @@ static void cik_enable_cgcg(struct radeon_device *rdev, bool enable) tmp = cik_halt_rlc(rdev); + mutex_lock(&rdev->grbm_idx_mutex); cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); tmp2 = BPM_ADDR_MASK | CGCG_OVERRIDE_0 | CGLS_ENABLE; WREG32(RLC_SERDES_WR_CTRL, tmp2); + mutex_unlock(&rdev->grbm_idx_mutex); cik_update_rlc(rdev, tmp); @@ -6329,11 +6349,13 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) tmp = cik_halt_rlc(rdev); + mutex_lock(&rdev->grbm_idx_mutex); cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); data = BPM_ADDR_MASK | MGCG_OVERRIDE_0; WREG32(RLC_SERDES_WR_CTRL, data); + mutex_unlock(&rdev->grbm_idx_mutex); cik_update_rlc(rdev, tmp); @@ -6377,11 +6399,13 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) tmp = cik_halt_rlc(rdev); + mutex_lock(&rdev->grbm_idx_mutex); cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); data = BPM_ADDR_MASK | MGCG_OVERRIDE_1; WREG32(RLC_SERDES_WR_CTRL, data); + mutex_unlock(&rdev->grbm_idx_mutex); cik_update_rlc(rdev, tmp); } @@ -6810,10 +6834,12 @@ static u32 cik_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh) u32 mask = 0, tmp, tmp1; int i; + mutex_lock(&rdev->grbm_idx_mutex); cik_select_se_sh(rdev, se, sh); tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG); tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG); cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); + mutex_unlock(&rdev->grbm_idx_mutex); tmp &= 0xffff0000; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f6cb42ea43a6..e95718f02de3 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2397,6 +2397,8 @@ struct radeon_device { struct radeon_atcs atcs; /* srbm instance registers */ struct mutex srbm_mutex; + /* GRBM index mutex. Protects concurrents access to GRBM index */ + struct mutex grbm_idx_mutex; /* clock, powergating flags */ u32 cg_flags; u32 pg_flags; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0b41f5eeb125..ae87310fd96e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1303,6 +1303,7 @@ int radeon_device_init(struct radeon_device *rdev, mutex_init(&rdev->pm.mutex); mutex_init(&rdev->gpu_clock_mutex); mutex_init(&rdev->srbm_mutex); + mutex_init(&rdev->grbm_idx_mutex); init_rwsem(&rdev->pm.mclk_lock); init_rwsem(&rdev->exclusive_lock); init_waitqueue_head(&rdev->irq.vblank_queue); -- GitLab From e28740ece34d314002b1ddfa14e8fb7c7b909489 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 15 Jul 2014 13:53:32 +0300 Subject: [PATCH 0010/9457] drm/radeon: Add radeon <--> amdkfd interface This patch adds the interface between the radeon driver and the amdkfd driver. The interface implementation is contained in radeon_kfd.c and radeon_kfd.h. The interface itself is represented by a pointer to struct kfd_dev. The pointer is located inside radeon_device structure. All the register accesses that amdkfd need are done using this interface. This allows us to avoid direct register accesses in amdkfd proper, while also avoiding locking between amdkfd and radeon. The single exception is the doorbells that are used in both of the drivers. However, because they are located in separate pci bar pages, the danger of sharing registers between the drivers is minimal. Having said that, we are planning to move the doorbells as well to radeon. v3: Add interface for sa manager init and fini. The init function will allocate a buffer on system memory and pin it to the GART address space via the radeon sa manager. All mappings of buffers to GART address space are done via the radeon sa manager. The interface of allocate memory will use the radeon sa manager to sub allocate from the single buffer that was allocated during the init function. Change lower_32/upper_32 calls to use linux macros Add documentation for the interface v4: Change ptr field type in kgd_mem from uint32_t* to void* to match to type that is returned by radeon_sa_bo_cpu_addr v5: Change format of mqd structure to work with latest KV firmware Add support for AQL queues creation to enable working with open-source HSA runtime. Move generic kfd-->kgd interface and other generic kgd definitions to a generic header file that will be used by AMD's radeon and amdgpu drivers Signed-off-by: Oded Gabbay --- .../gpu/drm/amd/include/kgd_kfd_interface.h | 185 ++++++ drivers/gpu/drm/radeon/Makefile | 1 + drivers/gpu/drm/radeon/cik.c | 10 + drivers/gpu/drm/radeon/cik_reg.h | 136 +++++ drivers/gpu/drm/radeon/cikd.h | 51 +- drivers/gpu/drm/radeon/radeon.h | 4 + drivers/gpu/drm/radeon/radeon_drv.c | 5 + drivers/gpu/drm/radeon/radeon_kfd.c | 563 ++++++++++++++++++ drivers/gpu/drm/radeon/radeon_kfd.h | 47 ++ drivers/gpu/drm/radeon/radeon_kms.c | 7 + 10 files changed, 1008 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/include/kgd_kfd_interface.h create mode 100644 drivers/gpu/drm/radeon/radeon_kfd.c create mode 100644 drivers/gpu/drm/radeon/radeon_kfd.h diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h new file mode 100644 index 000000000000..9c729dd8dd50 --- /dev/null +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -0,0 +1,185 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * This file defines the private interface between the + * AMD kernel graphics drivers and the AMD KFD. + */ + +#ifndef KGD_KFD_INTERFACE_H_INCLUDED +#define KGD_KFD_INTERFACE_H_INCLUDED + +#include + +struct pci_dev; + +#define KFD_INTERFACE_VERSION 1 + +struct kfd_dev; +struct kgd_dev; + +struct kgd_mem; + +enum kgd_memory_pool { + KGD_POOL_SYSTEM_CACHEABLE = 1, + KGD_POOL_SYSTEM_WRITECOMBINE = 2, + KGD_POOL_FRAMEBUFFER = 3, +}; + +struct kgd2kfd_shared_resources { + /* Bit n == 1 means VMID n is available for KFD. */ + unsigned int compute_vmid_bitmap; + + /* Compute pipes are counted starting from MEC0/pipe0 as 0. */ + unsigned int first_compute_pipe; + + /* Number of MEC pipes available for KFD. */ + unsigned int compute_pipe_count; + + /* Base address of doorbell aperture. */ + phys_addr_t doorbell_physical_address; + + /* Size in bytes of doorbell aperture. */ + size_t doorbell_aperture_size; + + /* Number of bytes at start of aperture reserved for KGD. */ + size_t doorbell_start_offset; +}; + +/** + * struct kgd2kfd_calls + * + * @exit: Notifies amdkfd that kgd module is unloaded + * + * @probe: Notifies amdkfd about a probe done on a device in the kgd driver. + * + * @device_init: Initialize the newly probed device (if it is a device that + * amdkfd supports) + * + * @device_exit: Notifies amdkfd about a removal of a kgd device + * + * @suspend: Notifies amdkfd about a suspend action done to a kgd device + * + * @resume: Notifies amdkfd about a resume action done to a kgd device + * + * This structure contains function callback pointers so the kgd driver + * will notify to the amdkfd about certain status changes. + * + */ +struct kgd2kfd_calls { + void (*exit)(void); + struct kfd_dev* (*probe)(struct kgd_dev *kgd, struct pci_dev *pdev); + bool (*device_init)(struct kfd_dev *kfd, + const struct kgd2kfd_shared_resources *gpu_resources); + void (*device_exit)(struct kfd_dev *kfd); + void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry); + void (*suspend)(struct kfd_dev *kfd); + int (*resume)(struct kfd_dev *kfd); +}; + +/** + * struct kfd2kgd_calls + * + * @init_sa_manager: Initialize an instance of the sa manager, used by + * amdkfd for all system memory allocations that are mapped to the GART + * address space + * + * @fini_sa_manager: Releases all memory allocations for amdkfd that are + * handled by kgd sa manager + * + * @allocate_mem: Allocate a buffer from amdkfd's sa manager. The buffer can + * be used for mqds, hpds, kernel queue, fence and runlists + * + * @free_mem: Frees a buffer that was allocated by amdkfd's sa manager + * + * @get_vmem_size: Retrieves (physical) size of VRAM + * + * @get_gpu_clock_counter: Retrieves GPU clock counter + * + * @get_max_engine_clock_in_mhz: Retrieves maximum GPU clock in MHz + * + * @program_sh_mem_settings: A function that should initiate the memory + * properties such as main aperture memory type (cache / non cached) and + * secondary aperture base address, size and memory type. + * This function is used only for no cp scheduling mode. + * + * @set_pasid_vmid_mapping: Exposes pasid/vmid pair to the H/W for no cp + * scheduling mode. Only used for no cp scheduling mode. + * + * @init_memory: Initializes memory apertures to fixed base/limit address + * and non cached memory types. + * + * @init_pipeline: Initialized the compute pipelines. + * + * @hqd_load: Loads the mqd structure to a H/W hqd slot. used only for no cp + * sceduling mode. + * + * @hqd_is_occupies: Checks if a hqd slot is occupied. + * + * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot. + * + * This structure contains function pointers to services that the kgd driver + * provides to amdkfd driver. + * + */ +struct kfd2kgd_calls { + /* Memory management. */ + int (*init_sa_manager)(struct kgd_dev *kgd, unsigned int size); + void (*fini_sa_manager)(struct kgd_dev *kgd); + int (*allocate_mem)(struct kgd_dev *kgd, size_t size, size_t alignment, + enum kgd_memory_pool pool, struct kgd_mem **mem); + + void (*free_mem)(struct kgd_dev *kgd, struct kgd_mem *mem); + + uint64_t (*get_vmem_size)(struct kgd_dev *kgd); + uint64_t (*get_gpu_clock_counter)(struct kgd_dev *kgd); + + uint32_t (*get_max_engine_clock_in_mhz)(struct kgd_dev *kgd); + + /* Register access functions */ + void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid, + uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, + uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases); + + int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, unsigned int pasid, + unsigned int vmid); + + int (*init_memory)(struct kgd_dev *kgd); + int (*init_pipeline)(struct kgd_dev *kgd, uint32_t pipe_id, + uint32_t hpd_size, uint64_t hpd_gpu_addr); + + int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr); + + bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id); + + int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id); +}; + +bool kgd2kfd_init(unsigned interface_version, + const struct kfd2kgd_calls *f2g, + const struct kgd2kfd_calls **g2f); + +#endif /* KGD_KFD_INTERFACE_H_INCLUDED */ diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index d01b87991422..bad6caa0a727 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -104,6 +104,7 @@ radeon-y += \ radeon_vce.o \ vce_v1_0.o \ vce_v2_0.o \ + radeon_kfd.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 2e742a591dfc..bce73b6203ac 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -32,6 +32,7 @@ #include "cik_blit_shaders.h" #include "radeon_ucode.h" #include "clearstate_ci.h" +#include "radeon_kfd.h" MODULE_FIRMWARE("radeon/BONAIRE_pfp.bin"); MODULE_FIRMWARE("radeon/BONAIRE_me.bin"); @@ -7798,6 +7799,10 @@ int cik_irq_process(struct radeon_device *rdev) while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; + + radeon_kfd_interrupt(rdev, + (const void *) &rdev->ih.ring[ring_index]); + src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; @@ -8487,6 +8492,10 @@ static int cik_startup(struct radeon_device *rdev) if (r) return r; + r = radeon_kfd_resume(rdev); + if (r) + return r; + return 0; } @@ -8535,6 +8544,7 @@ int cik_resume(struct radeon_device *rdev) */ int cik_suspend(struct radeon_device *rdev) { + radeon_kfd_suspend(rdev); radeon_pm_suspend(rdev); dce6_audio_fini(rdev); radeon_vm_manager_fini(rdev); diff --git a/drivers/gpu/drm/radeon/cik_reg.h b/drivers/gpu/drm/radeon/cik_reg.h index ca1bb6133580..79c45e8a536b 100644 --- a/drivers/gpu/drm/radeon/cik_reg.h +++ b/drivers/gpu/drm/radeon/cik_reg.h @@ -147,4 +147,140 @@ #define CIK_LB_DESKTOP_HEIGHT 0x6b0c +#define CP_HQD_IQ_RPTR 0xC970u +#define AQL_ENABLE (1U << 0) + +#define IDLE (1 << 2) + +struct cik_mqd { + uint32_t header; + uint32_t compute_dispatch_initiator; + uint32_t compute_dim_x; + uint32_t compute_dim_y; + uint32_t compute_dim_z; + uint32_t compute_start_x; + uint32_t compute_start_y; + uint32_t compute_start_z; + uint32_t compute_num_thread_x; + uint32_t compute_num_thread_y; + uint32_t compute_num_thread_z; + uint32_t compute_pipelinestat_enable; + uint32_t compute_perfcount_enable; + uint32_t compute_pgm_lo; + uint32_t compute_pgm_hi; + uint32_t compute_tba_lo; + uint32_t compute_tba_hi; + uint32_t compute_tma_lo; + uint32_t compute_tma_hi; + uint32_t compute_pgm_rsrc1; + uint32_t compute_pgm_rsrc2; + uint32_t compute_vmid; + uint32_t compute_resource_limits; + uint32_t compute_static_thread_mgmt_se0; + uint32_t compute_static_thread_mgmt_se1; + uint32_t compute_tmpring_size; + uint32_t compute_static_thread_mgmt_se2; + uint32_t compute_static_thread_mgmt_se3; + uint32_t compute_restart_x; + uint32_t compute_restart_y; + uint32_t compute_restart_z; + uint32_t compute_thread_trace_enable; + uint32_t compute_misc_reserved; + uint32_t compute_user_data_0; + uint32_t compute_user_data_1; + uint32_t compute_user_data_2; + uint32_t compute_user_data_3; + uint32_t compute_user_data_4; + uint32_t compute_user_data_5; + uint32_t compute_user_data_6; + uint32_t compute_user_data_7; + uint32_t compute_user_data_8; + uint32_t compute_user_data_9; + uint32_t compute_user_data_10; + uint32_t compute_user_data_11; + uint32_t compute_user_data_12; + uint32_t compute_user_data_13; + uint32_t compute_user_data_14; + uint32_t compute_user_data_15; + uint32_t cp_compute_csinvoc_count_lo; + uint32_t cp_compute_csinvoc_count_hi; + uint32_t cp_mqd_base_addr_lo; + uint32_t cp_mqd_base_addr_hi; + uint32_t cp_hqd_active; + uint32_t cp_hqd_vmid; + uint32_t cp_hqd_persistent_state; + uint32_t cp_hqd_pipe_priority; + uint32_t cp_hqd_queue_priority; + uint32_t cp_hqd_quantum; + uint32_t cp_hqd_pq_base_lo; + uint32_t cp_hqd_pq_base_hi; + uint32_t cp_hqd_pq_rptr; + uint32_t cp_hqd_pq_rptr_report_addr_lo; + uint32_t cp_hqd_pq_rptr_report_addr_hi; + uint32_t cp_hqd_pq_wptr_poll_addr_lo; + uint32_t cp_hqd_pq_wptr_poll_addr_hi; + uint32_t cp_hqd_pq_doorbell_control; + uint32_t cp_hqd_pq_wptr; + uint32_t cp_hqd_pq_control; + uint32_t cp_hqd_ib_base_addr_lo; + uint32_t cp_hqd_ib_base_addr_hi; + uint32_t cp_hqd_ib_rptr; + uint32_t cp_hqd_ib_control; + uint32_t cp_hqd_iq_timer; + uint32_t cp_hqd_iq_rptr; + uint32_t cp_hqd_dequeue_request; + uint32_t cp_hqd_dma_offload; + uint32_t cp_hqd_sema_cmd; + uint32_t cp_hqd_msg_type; + uint32_t cp_hqd_atomic0_preop_lo; + uint32_t cp_hqd_atomic0_preop_hi; + uint32_t cp_hqd_atomic1_preop_lo; + uint32_t cp_hqd_atomic1_preop_hi; + uint32_t cp_hqd_hq_status0; + uint32_t cp_hqd_hq_control0; + uint32_t cp_mqd_control; + uint32_t cp_mqd_query_time_lo; + uint32_t cp_mqd_query_time_hi; + uint32_t cp_mqd_connect_start_time_lo; + uint32_t cp_mqd_connect_start_time_hi; + uint32_t cp_mqd_connect_end_time_lo; + uint32_t cp_mqd_connect_end_time_hi; + uint32_t cp_mqd_connect_end_wf_count; + uint32_t cp_mqd_connect_end_pq_rptr; + uint32_t cp_mqd_connect_end_pq_wptr; + uint32_t cp_mqd_connect_end_ib_rptr; + uint32_t reserved_96; + uint32_t reserved_97; + uint32_t reserved_98; + uint32_t reserved_99; + uint32_t iqtimer_pkt_header; + uint32_t iqtimer_pkt_dw0; + uint32_t iqtimer_pkt_dw1; + uint32_t iqtimer_pkt_dw2; + uint32_t iqtimer_pkt_dw3; + uint32_t iqtimer_pkt_dw4; + uint32_t iqtimer_pkt_dw5; + uint32_t iqtimer_pkt_dw6; + uint32_t reserved_108; + uint32_t reserved_109; + uint32_t reserved_110; + uint32_t reserved_111; + uint32_t queue_doorbell_id0; + uint32_t queue_doorbell_id1; + uint32_t queue_doorbell_id2; + uint32_t queue_doorbell_id3; + uint32_t queue_doorbell_id4; + uint32_t queue_doorbell_id5; + uint32_t queue_doorbell_id6; + uint32_t queue_doorbell_id7; + uint32_t queue_doorbell_id8; + uint32_t queue_doorbell_id9; + uint32_t queue_doorbell_id10; + uint32_t queue_doorbell_id11; + uint32_t queue_doorbell_id12; + uint32_t queue_doorbell_id13; + uint32_t queue_doorbell_id14; + uint32_t queue_doorbell_id15; +}; + #endif diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index fae4d0c68478..068cbb019326 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -1139,6 +1139,9 @@ #define SH_MEM_ALIGNMENT_MODE_UNALIGNED 3 #define DEFAULT_MTYPE(x) ((x) << 4) #define APE1_MTYPE(x) ((x) << 7) +/* valid for both DEFAULT_MTYPE and APE1_MTYPE */ +#define MTYPE_CACHED 0 +#define MTYPE_NONCACHED 3 #define SX_DEBUG_1 0x9060 @@ -1449,6 +1452,16 @@ #define CP_HQD_ACTIVE 0xC91C #define CP_HQD_VMID 0xC920 +#define CP_HQD_PERSISTENT_STATE 0xC924u +#define DEFAULT_CP_HQD_PERSISTENT_STATE (0x33U << 8) + +#define CP_HQD_PIPE_PRIORITY 0xC928u +#define CP_HQD_QUEUE_PRIORITY 0xC92Cu +#define CP_HQD_QUANTUM 0xC930u +#define QUANTUM_EN 1U +#define QUANTUM_SCALE_1MS (1U << 4) +#define QUANTUM_DURATION(x) ((x) << 8) + #define CP_HQD_PQ_BASE 0xC934 #define CP_HQD_PQ_BASE_HI 0xC938 #define CP_HQD_PQ_RPTR 0xC93C @@ -1476,12 +1489,32 @@ #define PRIV_STATE (1 << 30) #define KMD_QUEUE (1 << 31) -#define CP_HQD_DEQUEUE_REQUEST 0xC974 +#define CP_HQD_IB_BASE_ADDR 0xC95Cu +#define CP_HQD_IB_BASE_ADDR_HI 0xC960u +#define CP_HQD_IB_RPTR 0xC964u +#define CP_HQD_IB_CONTROL 0xC968u +#define IB_ATC_EN (1U << 23) +#define DEFAULT_MIN_IB_AVAIL_SIZE (3U << 20) + +#define CP_HQD_DEQUEUE_REQUEST 0xC974 +#define DEQUEUE_REQUEST_DRAIN 1 +#define DEQUEUE_REQUEST_RESET 2 #define CP_MQD_CONTROL 0xC99C #define MQD_VMID(x) ((x) << 0) #define MQD_VMID_MASK (0xf << 0) +#define CP_HQD_SEMA_CMD 0xC97Cu +#define CP_HQD_MSG_TYPE 0xC980u +#define CP_HQD_ATOMIC0_PREOP_LO 0xC984u +#define CP_HQD_ATOMIC0_PREOP_HI 0xC988u +#define CP_HQD_ATOMIC1_PREOP_LO 0xC98Cu +#define CP_HQD_ATOMIC1_PREOP_HI 0xC990u +#define CP_HQD_HQ_SCHEDULER0 0xC994u +#define CP_HQD_HQ_SCHEDULER1 0xC998u + +#define SH_STATIC_MEM_CONFIG 0x9604u + #define DB_RENDER_CONTROL 0x28000 #define PA_SC_RASTER_CONFIG 0x28350 @@ -2071,4 +2104,20 @@ #define VCE_CMD_IB_AUTO 0x00000005 #define VCE_CMD_SEMAPHORE 0x00000006 +#define ATC_VMID0_PASID_MAPPING 0x339Cu +#define ATC_VMID_PASID_MAPPING_UPDATE_STATUS 0x3398u +#define ATC_VMID_PASID_MAPPING_VALID (1U << 31) + +#define ATC_VM_APERTURE0_CNTL 0x3310u +#define ATS_ACCESS_MODE_NEVER 0 +#define ATS_ACCESS_MODE_ALWAYS 1 + +#define ATC_VM_APERTURE0_CNTL2 0x3318u +#define ATC_VM_APERTURE0_HIGH_ADDR 0x3308u +#define ATC_VM_APERTURE0_LOW_ADDR 0x3300u +#define ATC_VM_APERTURE1_CNTL 0x3314u +#define ATC_VM_APERTURE1_CNTL2 0x331Cu +#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu +#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u + #endif diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e95718f02de3..1f61ff089c9e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2411,6 +2411,10 @@ struct radeon_device { u64 vram_pin_size; u64 gart_pin_size; + /* amdkfd interface */ + struct kfd_dev *kfd; + struct radeon_sa_manager kfd_bo; + struct mutex mn_lock; DECLARE_HASHTABLE(mn_hash, 7); }; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dcffa30ee2db..4f50fb0e3d93 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -41,6 +41,8 @@ #include #include "drm_crtc_helper.h" +#include "radeon_kfd.h" + /* * KMS wrapper. * - 2.0.0 - initial interface @@ -654,12 +656,15 @@ static int __init radeon_init(void) #endif } + radeon_kfd_init(); + /* let modprobe override vga console setting */ return drm_pci_init(driver, pdriver); } static void __exit radeon_exit(void) { + radeon_kfd_fini(); drm_pci_exit(driver, pdriver); radeon_unregister_atpx_handler(); } diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c new file mode 100644 index 000000000000..065d02068ec3 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -0,0 +1,563 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "radeon.h" +#include "cikd.h" +#include "cik_reg.h" +#include "radeon_kfd.h" + +#define CIK_PIPE_PER_MEC (4) + +struct kgd_mem { + struct radeon_sa_bo *sa_bo; + uint64_t gpu_addr; + void *ptr; +}; + +static int init_sa_manager(struct kgd_dev *kgd, unsigned int size); +static void fini_sa_manager(struct kgd_dev *kgd); + +static int allocate_mem(struct kgd_dev *kgd, size_t size, size_t alignment, + enum kgd_memory_pool pool, struct kgd_mem **mem); + +static void free_mem(struct kgd_dev *kgd, struct kgd_mem *mem); + +static uint64_t get_vmem_size(struct kgd_dev *kgd); +static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); + +static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); + +/* + * Register access functions + */ + +static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, + uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, + uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases); + +static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, + unsigned int vmid); + +static int kgd_init_memory(struct kgd_dev *kgd); + +static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, + uint32_t hpd_size, uint64_t hpd_gpu_addr); + +static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr); + +static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id); + +static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id); + +static const struct kfd2kgd_calls kfd2kgd = { + .init_sa_manager = init_sa_manager, + .fini_sa_manager = fini_sa_manager, + .allocate_mem = allocate_mem, + .free_mem = free_mem, + .get_vmem_size = get_vmem_size, + .get_gpu_clock_counter = get_gpu_clock_counter, + .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, + .program_sh_mem_settings = kgd_program_sh_mem_settings, + .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, + .init_memory = kgd_init_memory, + .init_pipeline = kgd_init_pipeline, + .hqd_load = kgd_hqd_load, + .hqd_is_occupies = kgd_hqd_is_occupies, + .hqd_destroy = kgd_hqd_destroy, +}; + +static const struct kgd2kfd_calls *kgd2kfd; + +bool radeon_kfd_init(void) +{ + bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, + const struct kgd2kfd_calls**); + + kgd2kfd_init_p = symbol_request(kgd2kfd_init); + + if (kgd2kfd_init_p == NULL) + return false; + + if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { + symbol_put(kgd2kfd_init); + kgd2kfd = NULL; + + return false; + } + + return true; +} + +void radeon_kfd_fini(void) +{ + if (kgd2kfd) { + kgd2kfd->exit(); + symbol_put(kgd2kfd_init); + } +} + +void radeon_kfd_device_probe(struct radeon_device *rdev) +{ + if (kgd2kfd) + rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev, rdev->pdev); +} + +void radeon_kfd_device_init(struct radeon_device *rdev) +{ + if (rdev->kfd) { + struct kgd2kfd_shared_resources gpu_resources = { + .compute_vmid_bitmap = 0xFF00, + + .first_compute_pipe = 1, + .compute_pipe_count = 8 - 1, + }; + + radeon_doorbell_get_kfd_info(rdev, + &gpu_resources.doorbell_physical_address, + &gpu_resources.doorbell_aperture_size, + &gpu_resources.doorbell_start_offset); + + kgd2kfd->device_init(rdev->kfd, &gpu_resources); + } +} + +void radeon_kfd_device_fini(struct radeon_device *rdev) +{ + if (rdev->kfd) { + kgd2kfd->device_exit(rdev->kfd); + rdev->kfd = NULL; + } +} + +void radeon_kfd_interrupt(struct radeon_device *rdev, const void *ih_ring_entry) +{ + if (rdev->kfd) + kgd2kfd->interrupt(rdev->kfd, ih_ring_entry); +} + +void radeon_kfd_suspend(struct radeon_device *rdev) +{ + if (rdev->kfd) + kgd2kfd->suspend(rdev->kfd); +} + +int radeon_kfd_resume(struct radeon_device *rdev) +{ + int r = 0; + + if (rdev->kfd) + r = kgd2kfd->resume(rdev->kfd); + + return r; +} + +static u32 pool_to_domain(enum kgd_memory_pool p) +{ + switch (p) { + case KGD_POOL_FRAMEBUFFER: return RADEON_GEM_DOMAIN_VRAM; + default: return RADEON_GEM_DOMAIN_GTT; + } +} + +static int init_sa_manager(struct kgd_dev *kgd, unsigned int size) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + int r; + + BUG_ON(kgd == NULL); + + r = radeon_sa_bo_manager_init(rdev, &rdev->kfd_bo, + size, + RADEON_GPU_PAGE_SIZE, + RADEON_GEM_DOMAIN_GTT, + RADEON_GEM_GTT_WC); + + if (r) + return r; + + r = radeon_sa_bo_manager_start(rdev, &rdev->kfd_bo); + if (r) + radeon_sa_bo_manager_fini(rdev, &rdev->kfd_bo); + + return r; +} + +static void fini_sa_manager(struct kgd_dev *kgd) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + + BUG_ON(kgd == NULL); + + radeon_sa_bo_manager_suspend(rdev, &rdev->kfd_bo); + radeon_sa_bo_manager_fini(rdev, &rdev->kfd_bo); +} + +static int allocate_mem(struct kgd_dev *kgd, size_t size, size_t alignment, + enum kgd_memory_pool pool, struct kgd_mem **mem) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + u32 domain; + int r; + + BUG_ON(kgd == NULL); + + domain = pool_to_domain(pool); + if (domain != RADEON_GEM_DOMAIN_GTT) { + dev_err(rdev->dev, + "Only allowed to allocate gart memory for kfd\n"); + return -EINVAL; + } + + *mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL); + if ((*mem) == NULL) + return -ENOMEM; + + r = radeon_sa_bo_new(rdev, &rdev->kfd_bo, &(*mem)->sa_bo, size, + alignment); + if (r) { + dev_err(rdev->dev, "failed to get memory for kfd (%d)\n", r); + return r; + } + + (*mem)->ptr = radeon_sa_bo_cpu_addr((*mem)->sa_bo); + (*mem)->gpu_addr = radeon_sa_bo_gpu_addr((*mem)->sa_bo); + + return 0; +} + +static void free_mem(struct kgd_dev *kgd, struct kgd_mem *mem) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + + BUG_ON(kgd == NULL); + + radeon_sa_bo_free(rdev, &mem->sa_bo, NULL); + kfree(mem); +} + +static uint64_t get_vmem_size(struct kgd_dev *kgd) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + + BUG_ON(kgd == NULL); + + return rdev->mc.real_vram_size; +} + +static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + + return rdev->asic->get_gpu_clock_counter(rdev); +} + +static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) +{ + struct radeon_device *rdev = (struct radeon_device *)kgd; + + /* The sclk is in quantas of 10kHz */ + return rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk / 100; +} + +static inline struct radeon_device *get_radeon_device(struct kgd_dev *kgd) +{ + return (struct radeon_device *)kgd; +} + +static void write_register(struct kgd_dev *kgd, uint32_t offset, uint32_t value) +{ + struct radeon_device *rdev = get_radeon_device(kgd); + + writel(value, (void __iomem *)(rdev->rmmio + offset)); +} + +static uint32_t read_register(struct kgd_dev *kgd, uint32_t offset) +{ + struct radeon_device *rdev = get_radeon_device(kgd); + + return readl((void __iomem *)(rdev->rmmio + offset)); +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, + uint32_t queue, uint32_t vmid) +{ + struct radeon_device *rdev = get_radeon_device(kgd); + uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue); + + mutex_lock(&rdev->srbm_mutex); + write_register(kgd, SRBM_GFX_CNTL, value); +} + +static void unlock_srbm(struct kgd_dev *kgd) +{ + struct radeon_device *rdev = get_radeon_device(kgd); + + write_register(kgd, SRBM_GFX_CNTL, 0); + mutex_unlock(&rdev->srbm_mutex); +} + +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, + uint32_t queue_id) +{ + uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; + uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); + + lock_srbm(kgd, mec, pipe, queue_id, 0); +} + +static void release_queue(struct kgd_dev *kgd) +{ + unlock_srbm(kgd); +} + +static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, + uint32_t sh_mem_config, + uint32_t sh_mem_ape1_base, + uint32_t sh_mem_ape1_limit, + uint32_t sh_mem_bases) +{ + lock_srbm(kgd, 0, 0, 0, vmid); + + write_register(kgd, SH_MEM_CONFIG, sh_mem_config); + write_register(kgd, SH_MEM_APE1_BASE, sh_mem_ape1_base); + write_register(kgd, SH_MEM_APE1_LIMIT, sh_mem_ape1_limit); + write_register(kgd, SH_MEM_BASES, sh_mem_bases); + + unlock_srbm(kgd); +} + +static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, + unsigned int vmid) +{ + /* + * We have to assume that there is no outstanding mapping. + * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 + * because a mapping is in progress or because a mapping finished and + * the SW cleared it. + * So the protocol is to always wait & clear. + */ + uint32_t pasid_mapping = (pasid == 0) ? 0 : + (uint32_t)pasid | ATC_VMID_PASID_MAPPING_VALID; + + write_register(kgd, ATC_VMID0_PASID_MAPPING + vmid*sizeof(uint32_t), + pasid_mapping); + + while (!(read_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS) & + (1U << vmid))) + cpu_relax(); + write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); + + return 0; +} + +static int kgd_init_memory(struct kgd_dev *kgd) +{ + /* + * Configure apertures: + * LDS: 0x60000000'00000000 - 0x60000001'00000000 (4GB) + * Scratch: 0x60000001'00000000 - 0x60000002'00000000 (4GB) + * GPUVM: 0x60010000'00000000 - 0x60020000'00000000 (1TB) + */ + int i; + uint32_t sh_mem_bases = PRIVATE_BASE(0x6000) | SHARED_BASE(0x6000); + + for (i = 8; i < 16; i++) { + uint32_t sh_mem_config; + + lock_srbm(kgd, 0, 0, 0, i); + + sh_mem_config = ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED); + sh_mem_config |= DEFAULT_MTYPE(MTYPE_NONCACHED); + + write_register(kgd, SH_MEM_CONFIG, sh_mem_config); + + write_register(kgd, SH_MEM_BASES, sh_mem_bases); + + /* Scratch aperture is not supported for now. */ + write_register(kgd, SH_STATIC_MEM_CONFIG, 0); + + /* APE1 disabled for now. */ + write_register(kgd, SH_MEM_APE1_BASE, 1); + write_register(kgd, SH_MEM_APE1_LIMIT, 0); + + unlock_srbm(kgd); + } + + return 0; +} + +static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, + uint32_t hpd_size, uint64_t hpd_gpu_addr) +{ + uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; + uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); + + lock_srbm(kgd, mec, pipe, 0, 0); + write_register(kgd, CP_HPD_EOP_BASE_ADDR, + lower_32_bits(hpd_gpu_addr >> 8)); + write_register(kgd, CP_HPD_EOP_BASE_ADDR_HI, + upper_32_bits(hpd_gpu_addr >> 8)); + write_register(kgd, CP_HPD_EOP_VMID, 0); + write_register(kgd, CP_HPD_EOP_CONTROL, hpd_size); + unlock_srbm(kgd); + + return 0; +} + +static inline struct cik_mqd *get_mqd(void *mqd) +{ + return (struct cik_mqd *)mqd; +} + +static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr) +{ + uint32_t wptr_shadow, is_wptr_shadow_valid; + struct cik_mqd *m; + + m = get_mqd(mqd); + + is_wptr_shadow_valid = !get_user(wptr_shadow, wptr); + + acquire_queue(kgd, pipe_id, queue_id); + write_register(kgd, CP_MQD_BASE_ADDR, m->cp_mqd_base_addr_lo); + write_register(kgd, CP_MQD_BASE_ADDR_HI, m->cp_mqd_base_addr_hi); + write_register(kgd, CP_MQD_CONTROL, m->cp_mqd_control); + + write_register(kgd, CP_HQD_PQ_BASE, m->cp_hqd_pq_base_lo); + write_register(kgd, CP_HQD_PQ_BASE_HI, m->cp_hqd_pq_base_hi); + write_register(kgd, CP_HQD_PQ_CONTROL, m->cp_hqd_pq_control); + + write_register(kgd, CP_HQD_IB_CONTROL, m->cp_hqd_ib_control); + write_register(kgd, CP_HQD_IB_BASE_ADDR, m->cp_hqd_ib_base_addr_lo); + write_register(kgd, CP_HQD_IB_BASE_ADDR_HI, m->cp_hqd_ib_base_addr_hi); + + write_register(kgd, CP_HQD_IB_RPTR, m->cp_hqd_ib_rptr); + + write_register(kgd, CP_HQD_PERSISTENT_STATE, + m->cp_hqd_persistent_state); + write_register(kgd, CP_HQD_SEMA_CMD, m->cp_hqd_sema_cmd); + write_register(kgd, CP_HQD_MSG_TYPE, m->cp_hqd_msg_type); + + write_register(kgd, CP_HQD_ATOMIC0_PREOP_LO, + m->cp_hqd_atomic0_preop_lo); + + write_register(kgd, CP_HQD_ATOMIC0_PREOP_HI, + m->cp_hqd_atomic0_preop_hi); + + write_register(kgd, CP_HQD_ATOMIC1_PREOP_LO, + m->cp_hqd_atomic1_preop_lo); + + write_register(kgd, CP_HQD_ATOMIC1_PREOP_HI, + m->cp_hqd_atomic1_preop_hi); + + write_register(kgd, CP_HQD_PQ_RPTR_REPORT_ADDR, + m->cp_hqd_pq_rptr_report_addr_lo); + + write_register(kgd, CP_HQD_PQ_RPTR_REPORT_ADDR_HI, + m->cp_hqd_pq_rptr_report_addr_hi); + + write_register(kgd, CP_HQD_PQ_RPTR, m->cp_hqd_pq_rptr); + + write_register(kgd, CP_HQD_PQ_WPTR_POLL_ADDR, + m->cp_hqd_pq_wptr_poll_addr_lo); + + write_register(kgd, CP_HQD_PQ_WPTR_POLL_ADDR_HI, + m->cp_hqd_pq_wptr_poll_addr_hi); + + write_register(kgd, CP_HQD_PQ_DOORBELL_CONTROL, + m->cp_hqd_pq_doorbell_control); + + write_register(kgd, CP_HQD_VMID, m->cp_hqd_vmid); + + write_register(kgd, CP_HQD_QUANTUM, m->cp_hqd_quantum); + + write_register(kgd, CP_HQD_PIPE_PRIORITY, m->cp_hqd_pipe_priority); + write_register(kgd, CP_HQD_QUEUE_PRIORITY, m->cp_hqd_queue_priority); + + write_register(kgd, CP_HQD_IQ_RPTR, m->cp_hqd_iq_rptr); + + if (is_wptr_shadow_valid) + write_register(kgd, CP_HQD_PQ_WPTR, wptr_shadow); + + write_register(kgd, CP_HQD_ACTIVE, m->cp_hqd_active); + release_queue(kgd); + + return 0; +} + +static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) +{ + uint32_t act; + bool retval = false; + uint32_t low, high; + + acquire_queue(kgd, pipe_id, queue_id); + act = read_register(kgd, CP_HQD_ACTIVE); + if (act) { + low = lower_32_bits(queue_address >> 8); + high = upper_32_bits(queue_address >> 8); + + if (low == read_register(kgd, CP_HQD_PQ_BASE) && + high == read_register(kgd, CP_HQD_PQ_BASE_HI)) + retval = true; + } + release_queue(kgd); + return retval; +} + +static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id) +{ + uint32_t temp; + + acquire_queue(kgd, pipe_id, queue_id); + write_register(kgd, CP_HQD_PQ_DOORBELL_CONTROL, 0); + + write_register(kgd, CP_HQD_DEQUEUE_REQUEST, reset_type); + + while (true) { + temp = read_register(kgd, CP_HQD_ACTIVE); + if (temp & 0x1) + break; + if (timeout == 0) { + pr_err("kfd: cp queue preemption time out (%dms)\n", + temp); + return -ETIME; + } + msleep(20); + timeout -= 20; + } + + release_queue(kgd); + return 0; +} diff --git a/drivers/gpu/drm/radeon/radeon_kfd.h b/drivers/gpu/drm/radeon/radeon_kfd.h new file mode 100644 index 000000000000..f90e161ca507 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_kfd.h @@ -0,0 +1,47 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * radeon_kfd.h defines the private interface between the + * AMD kernel graphics drivers and the AMD KFD. + */ + +#ifndef RADEON_KFD_H_INCLUDED +#define RADEON_KFD_H_INCLUDED + +#include +#include "../amd/include/kgd_kfd_interface.h" + +struct radeon_device; + +bool radeon_kfd_init(void); +void radeon_kfd_fini(void); + +void radeon_kfd_suspend(struct radeon_device *rdev); +int radeon_kfd_resume(struct radeon_device *rdev); +void radeon_kfd_interrupt(struct radeon_device *rdev, + const void *ih_ring_entry); +void radeon_kfd_device_probe(struct radeon_device *rdev); +void radeon_kfd_device_init(struct radeon_device *rdev); +void radeon_kfd_device_fini(struct radeon_device *rdev); + +#endif /* RADEON_KFD_H_INCLUDED */ diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8309b11e674d..6eb561d33eba 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -34,6 +34,8 @@ #include #include +#include "radeon_kfd.h" + #if defined(CONFIG_VGA_SWITCHEROO) bool radeon_has_atpx(void); #else @@ -63,6 +65,8 @@ int radeon_driver_unload_kms(struct drm_device *dev) pm_runtime_get_sync(dev->dev); + radeon_kfd_device_fini(rdev); + radeon_acpi_fini(rdev); radeon_modeset_fini(rdev); @@ -142,6 +146,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); } + radeon_kfd_device_probe(rdev); + radeon_kfd_device_init(rdev); + if (radeon_is_px(dev)) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); -- GitLab From 16423d67936f87e320a7b11771675b982cc9de02 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 15 Jul 2014 13:08:36 +0300 Subject: [PATCH 0011/9457] Update MAINTAINERS and CREDITS files with amdkfd info v6: Update entries to reflect new name & location of driver Signed-off-by: Oded Gabbay --- CREDITS | 7 +++++++ MAINTAINERS | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/CREDITS b/CREDITS index bb6278884f89..c56d8aa10131 100644 --- a/CREDITS +++ b/CREDITS @@ -1197,6 +1197,13 @@ S: R. Tocantins, 89 - Cristo Rei S: 80050-430 - Curitiba - Paraná S: Brazil +N: Oded Gabbay +E: oded.gabbay@gmail.com +D: AMD KFD maintainer +S: 12 Shraga Raphaeli +S: Petah-Tikva, 4906418 +S: Israel + N: Kumar Gala E: galak@kernel.crashing.org D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support diff --git a/MAINTAINERS b/MAINTAINERS index ea4d0058fd1b..3c69a3c73028 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -618,6 +618,16 @@ S: Maintained F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h +AMD KFD +M: Oded Gabbay +L: dri-devel@lists.freedesktop.org +T: git git://people.freedesktop.org/~gabbayo/linux.git +S: Supported +F: drivers/gpu/drm/amd/amdkfd/ +F: drivers/gpu/drm/radeon/radeon_kfd.c +F: drivers/gpu/drm/radeon/radeon_kfd.h +F: include/uapi/linux/kfd_ioctl.h + AMD MICROCODE UPDATE SUPPORT M: Andreas Herrmann L: amd64-microcode@amd64.org -- GitLab From b7facbaec75a20f34c2065121dc423971682f922 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Wed, 16 Jul 2014 15:55:29 +0300 Subject: [PATCH 0012/9457] amdkfd: Add IOCTL set definitions of amdkfd - KFD_IOC_GET_VERSION: Retrieves the interface version of amdkfd - KFD_IOC_CREATE_QUEUE: Creates a usermode queue that runs on a specific GPU device - KFD_IOC_DESTROY_QUEUE: Destroys an existing usermode queue - KFD_IOC_SET_MEMORY_POLICY: Sets the memory policy of the default and alternate aperture of the calling process - KFD_IOC_GET_CLOCK_COUNTERS: Retrieves counters (timestamps) of CPU and GPU - KFD_IOC_GET_PROCESS_APERTURES: Retrieves information about process apertures that were initialized during the open() call of the amdkfd device - KFD_IOC_UPDATE_QUEUE: Updates configuration of an existing usermode queue v3: Remove pragma pack and pmc ioctls. Added parameter for doorbell offset and a comment on counters v5: Add define for AQL queues. Fix arguments of Get Version IOCTL Make IOCTL's structures to be the same size on 32/64 bit v6: Change the version of the amdkfd-thunk interface Signed-off-by: Oded Gabbay --- include/uapi/linux/kfd_ioctl.h | 154 +++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 include/uapi/linux/kfd_ioctl.h diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h new file mode 100644 index 000000000000..7acef41fc209 --- /dev/null +++ b/include/uapi/linux/kfd_ioctl.h @@ -0,0 +1,154 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef KFD_IOCTL_H_INCLUDED +#define KFD_IOCTL_H_INCLUDED + +#include +#include + +#define KFD_IOCTL_MAJOR_VERSION 1 +#define KFD_IOCTL_MINOR_VERSION 0 + +struct kfd_ioctl_get_version_args { + uint32_t major_version; /* from KFD */ + uint32_t minor_version; /* from KFD */ +}; + +/* For kfd_ioctl_create_queue_args.queue_type. */ +#define KFD_IOC_QUEUE_TYPE_COMPUTE 0 +#define KFD_IOC_QUEUE_TYPE_SDMA 1 +#define KFD_IOC_QUEUE_TYPE_COMPUTE_AQL 2 + +#define KFD_MAX_QUEUE_PERCENTAGE 100 +#define KFD_MAX_QUEUE_PRIORITY 15 + +struct kfd_ioctl_create_queue_args { + uint64_t ring_base_address; /* to KFD */ + uint64_t write_pointer_address; /* from KFD */ + uint64_t read_pointer_address; /* from KFD */ + uint64_t doorbell_offset; /* from KFD */ + + uint32_t ring_size; /* to KFD */ + uint32_t gpu_id; /* to KFD */ + uint32_t queue_type; /* to KFD */ + uint32_t queue_percentage; /* to KFD */ + uint32_t queue_priority; /* to KFD */ + uint32_t queue_id; /* from KFD */ + + uint64_t eop_buffer_address; /* to KFD */ + uint64_t eop_buffer_size; /* to KFD */ + uint64_t ctx_save_restore_address; /* to KFD */ + uint64_t ctx_save_restore_size; /* to KFD */ +}; + +struct kfd_ioctl_destroy_queue_args { + uint32_t queue_id; /* to KFD */ + uint32_t pad; +}; + +struct kfd_ioctl_update_queue_args { + uint64_t ring_base_address; /* to KFD */ + + uint32_t queue_id; /* to KFD */ + uint32_t ring_size; /* to KFD */ + uint32_t queue_percentage; /* to KFD */ + uint32_t queue_priority; /* to KFD */ +}; + +/* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */ +#define KFD_IOC_CACHE_POLICY_COHERENT 0 +#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1 + +struct kfd_ioctl_set_memory_policy_args { + uint64_t alternate_aperture_base; /* to KFD */ + uint64_t alternate_aperture_size; /* to KFD */ + + uint32_t gpu_id; /* to KFD */ + uint32_t default_policy; /* to KFD */ + uint32_t alternate_policy; /* to KFD */ + uint32_t pad; +}; + +/* + * All counters are monotonic. They are used for profiling of compute jobs. + * The profiling is done by userspace. + * + * In case of GPU reset, the counter should not be affected. + */ + +struct kfd_ioctl_get_clock_counters_args { + uint64_t gpu_clock_counter; /* from KFD */ + uint64_t cpu_clock_counter; /* from KFD */ + uint64_t system_clock_counter; /* from KFD */ + uint64_t system_clock_freq; /* from KFD */ + + uint32_t gpu_id; /* to KFD */ + uint32_t pad; +}; + +#define NUM_OF_SUPPORTED_GPUS 7 + +struct kfd_process_device_apertures { + uint64_t lds_base; /* from KFD */ + uint64_t lds_limit; /* from KFD */ + uint64_t scratch_base; /* from KFD */ + uint64_t scratch_limit; /* from KFD */ + uint64_t gpuvm_base; /* from KFD */ + uint64_t gpuvm_limit; /* from KFD */ + uint32_t gpu_id; /* from KFD */ + uint32_t pad; +}; + +struct kfd_ioctl_get_process_apertures_args { + struct kfd_process_device_apertures + process_apertures[NUM_OF_SUPPORTED_GPUS];/* from KFD */ + + /* from KFD, should be in the range [1 - NUM_OF_SUPPORTED_GPUS] */ + uint32_t num_of_nodes; + uint32_t pad; +}; + +#define KFD_IOC_MAGIC 'K' + +#define KFD_IOC_GET_VERSION \ + _IOR(KFD_IOC_MAGIC, 1, struct kfd_ioctl_get_version_args) + +#define KFD_IOC_CREATE_QUEUE \ + _IOWR(KFD_IOC_MAGIC, 2, struct kfd_ioctl_create_queue_args) + +#define KFD_IOC_DESTROY_QUEUE \ + _IOWR(KFD_IOC_MAGIC, 3, struct kfd_ioctl_destroy_queue_args) + +#define KFD_IOC_SET_MEMORY_POLICY \ + _IOW(KFD_IOC_MAGIC, 4, struct kfd_ioctl_set_memory_policy_args) + +#define KFD_IOC_GET_CLOCK_COUNTERS \ + _IOWR(KFD_IOC_MAGIC, 5, struct kfd_ioctl_get_clock_counters_args) + +#define KFD_IOC_GET_PROCESS_APERTURES \ + _IOR(KFD_IOC_MAGIC, 6, struct kfd_ioctl_get_process_apertures_args) + +#define KFD_IOC_UPDATE_QUEUE \ + _IOW(KFD_IOC_MAGIC, 7, struct kfd_ioctl_update_queue_args) + +#endif -- GitLab From 4a488a7ad71401169cecee75dc94bcce642e2c53 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Wed, 16 Jul 2014 21:08:55 +0300 Subject: [PATCH 0013/9457] amdkfd: Add amdkfd skeleton driver This patch adds the amdkfd skeleton driver. The driver does nothing except define a /dev/kfd device. It returns -ENODEV on all amdkfd IOCTLs. v3: Move bool field to the end of structure, removed the pmc ioctls and added a meaningful error message for ioctl error. v5: Create a new folder drm/amd and move amdkfd from drm/radeon/ to drm/amd/ Remove scheduler_class from kfd_priv.h as it was never used Add skeleton implementation of the Get Version IOCTL v6: Update module version to the correct number and remove the "default m" from the Kconfig file Signed-off-by: Oded Gabbay --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/amd/amdkfd/Kconfig | 9 + drivers/gpu/drm/amd/amdkfd/Makefile | 9 + drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 210 +++++++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_device.c | 130 ++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_module.c | 101 +++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 81 +++++++++ 8 files changed, 543 insertions(+) create mode 100644 drivers/gpu/drm/amd/amdkfd/Kconfig create mode 100644 drivers/gpu/drm/amd/amdkfd/Makefile create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_device.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_module.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_priv.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index e3b4b0f02b3d..37c5a6ea5bdf 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -200,3 +200,5 @@ source "drivers/gpu/drm/tegra/Kconfig" source "drivers/gpu/drm/panel/Kconfig" source "drivers/gpu/drm/sti/Kconfig" + +source "drivers/gpu/drm/amd/amdkfd/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index c3cf64ce2891..dd9d35bfa690 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -65,3 +65,4 @@ obj-$(CONFIG_DRM_STI) += sti/ obj-y += i2c/ obj-y += panel/ obj-y += bridge/ +obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ diff --git a/drivers/gpu/drm/amd/amdkfd/Kconfig b/drivers/gpu/drm/amd/amdkfd/Kconfig new file mode 100644 index 000000000000..e13c67c8d2c0 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/Kconfig @@ -0,0 +1,9 @@ +# +# Heterogenous system architecture configuration +# + +config HSA_AMD + tristate "HSA kernel driver for AMD GPU devices" + depends on (DRM_RADEON || DRM_AMDGPU) && AMD_IOMMU_V2 && X86_64 + help + Enable this if you want to use HSA features on AMD GPU devices. diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile new file mode 100644 index 000000000000..d875ce4dbda6 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for Heterogenous System Architecture support for AMD GPU devices +# + +ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ + +amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o + +obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c new file mode 100644 index 000000000000..d7c32eb7d16a --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -0,0 +1,210 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kfd_priv.h" + +static long kfd_ioctl(struct file *, unsigned int, unsigned long); +static int kfd_open(struct inode *, struct file *); + +static const char kfd_dev_name[] = "kfd"; + +static const struct file_operations kfd_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = kfd_ioctl, + .compat_ioctl = kfd_ioctl, + .open = kfd_open, +}; + +static int kfd_char_dev_major = -1; +static struct class *kfd_class; +struct device *kfd_device; + +int kfd_chardev_init(void) +{ + int err = 0; + + kfd_char_dev_major = register_chrdev(0, kfd_dev_name, &kfd_fops); + err = kfd_char_dev_major; + if (err < 0) + goto err_register_chrdev; + + kfd_class = class_create(THIS_MODULE, kfd_dev_name); + err = PTR_ERR(kfd_class); + if (IS_ERR(kfd_class)) + goto err_class_create; + + kfd_device = device_create(kfd_class, NULL, + MKDEV(kfd_char_dev_major, 0), + NULL, kfd_dev_name); + err = PTR_ERR(kfd_device); + if (IS_ERR(kfd_device)) + goto err_device_create; + + return 0; + +err_device_create: + class_destroy(kfd_class); +err_class_create: + unregister_chrdev(kfd_char_dev_major, kfd_dev_name); +err_register_chrdev: + return err; +} + +void kfd_chardev_exit(void) +{ + device_destroy(kfd_class, MKDEV(kfd_char_dev_major, 0)); + class_destroy(kfd_class); + unregister_chrdev(kfd_char_dev_major, kfd_dev_name); +} + +struct device *kfd_chardev(void) +{ + return kfd_device; +} + + +static int kfd_open(struct inode *inode, struct file *filep) +{ + if (iminor(inode) != 0) + return -ENODEV; + + return 0; +} + +static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, + void __user *arg) +{ + return -ENODEV; +} + +static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, + void __user *arg) +{ + return -ENODEV; +} + +static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, + void __user *arg) +{ + return -ENODEV; +} + +static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, + void __user *arg) +{ + return -ENODEV; +} + +static long kfd_ioctl_set_memory_policy(struct file *filep, + struct kfd_process *p, void __user *arg) +{ + return -ENODEV; +} + +static long kfd_ioctl_get_clock_counters(struct file *filep, + struct kfd_process *p, void __user *arg) +{ + return -ENODEV; +} + + +static int kfd_ioctl_get_process_apertures(struct file *filp, + struct kfd_process *p, void __user *arg) +{ + return -ENODEV; +} + +static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + struct kfd_process *process; + long err = -EINVAL; + + dev_dbg(kfd_device, + "ioctl cmd 0x%x (#%d), arg 0x%lx\n", + cmd, _IOC_NR(cmd), arg); + + /* TODO: add function that retrieves process */ + process = NULL; + + switch (cmd) { + case KFD_IOC_GET_VERSION: + err = kfd_ioctl_get_version(filep, process, (void __user *)arg); + break; + case KFD_IOC_CREATE_QUEUE: + err = kfd_ioctl_create_queue(filep, process, + (void __user *)arg); + break; + + case KFD_IOC_DESTROY_QUEUE: + err = kfd_ioctl_destroy_queue(filep, process, + (void __user *)arg); + break; + + case KFD_IOC_SET_MEMORY_POLICY: + err = kfd_ioctl_set_memory_policy(filep, process, + (void __user *)arg); + break; + + case KFD_IOC_GET_CLOCK_COUNTERS: + err = kfd_ioctl_get_clock_counters(filep, process, + (void __user *)arg); + break; + + case KFD_IOC_GET_PROCESS_APERTURES: + err = kfd_ioctl_get_process_apertures(filep, process, + (void __user *)arg); + break; + + case KFD_IOC_UPDATE_QUEUE: + err = kfd_ioctl_update_queue(filep, process, + (void __user *)arg); + break; + + default: + dev_err(kfd_device, + "unknown ioctl cmd 0x%x, arg 0x%lx)\n", + cmd, arg); + err = -EINVAL; + break; + } + + if (err < 0) + dev_err(kfd_device, + "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", + err, cmd, _IOC_NR(cmd)); + + return err; +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c new file mode 100644 index 000000000000..d81a58eeec29 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -0,0 +1,130 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "kfd_priv.h" + +static const struct kfd_device_info kaveri_device_info = { + .max_pasid_bits = 16, +}; + +struct kfd_deviceid { + unsigned short did; + const struct kfd_device_info *device_info; +}; + +/* Please keep this sorted by increasing device id. */ +static const struct kfd_deviceid supported_devices[] = { + { 0x1304, &kaveri_device_info }, /* Kaveri */ + { 0x1305, &kaveri_device_info }, /* Kaveri */ + { 0x1306, &kaveri_device_info }, /* Kaveri */ + { 0x1307, &kaveri_device_info }, /* Kaveri */ + { 0x1309, &kaveri_device_info }, /* Kaveri */ + { 0x130A, &kaveri_device_info }, /* Kaveri */ + { 0x130B, &kaveri_device_info }, /* Kaveri */ + { 0x130C, &kaveri_device_info }, /* Kaveri */ + { 0x130D, &kaveri_device_info }, /* Kaveri */ + { 0x130E, &kaveri_device_info }, /* Kaveri */ + { 0x130F, &kaveri_device_info }, /* Kaveri */ + { 0x1310, &kaveri_device_info }, /* Kaveri */ + { 0x1311, &kaveri_device_info }, /* Kaveri */ + { 0x1312, &kaveri_device_info }, /* Kaveri */ + { 0x1313, &kaveri_device_info }, /* Kaveri */ + { 0x1315, &kaveri_device_info }, /* Kaveri */ + { 0x1316, &kaveri_device_info }, /* Kaveri */ + { 0x1317, &kaveri_device_info }, /* Kaveri */ + { 0x1318, &kaveri_device_info }, /* Kaveri */ + { 0x131B, &kaveri_device_info }, /* Kaveri */ + { 0x131C, &kaveri_device_info }, /* Kaveri */ + { 0x131D, &kaveri_device_info }, /* Kaveri */ +}; + +static const struct kfd_device_info *lookup_device_info(unsigned short did) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(supported_devices); i++) { + if (supported_devices[i].did == did) { + BUG_ON(supported_devices[i].device_info == NULL); + return supported_devices[i].device_info; + } + } + + return NULL; +} + +struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) +{ + struct kfd_dev *kfd; + + const struct kfd_device_info *device_info = + lookup_device_info(pdev->device); + + if (!device_info) + return NULL; + + kfd = kzalloc(sizeof(*kfd), GFP_KERNEL); + if (!kfd) + return NULL; + + kfd->kgd = kgd; + kfd->device_info = device_info; + kfd->pdev = pdev; + + return kfd; +} + +bool kgd2kfd_device_init(struct kfd_dev *kfd, + const struct kgd2kfd_shared_resources *gpu_resources) +{ + kfd->shared_resources = *gpu_resources; + + kfd->init_complete = true; + dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor, + kfd->pdev->device); + + return true; +} + +void kgd2kfd_device_exit(struct kfd_dev *kfd) +{ + kfree(kfd); +} + +void kgd2kfd_suspend(struct kfd_dev *kfd) +{ + BUG_ON(kfd == NULL); +} + +int kgd2kfd_resume(struct kfd_dev *kfd) +{ + BUG_ON(kfd == NULL); + + return 0; +} + +void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry) +{ +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c new file mode 100644 index 000000000000..9519f33bd59c --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -0,0 +1,101 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "kfd_priv.h" + +#define KFD_DRIVER_AUTHOR "AMD Inc. and others" + +#define KFD_DRIVER_DESC "Standalone HSA driver for AMD's GPUs" +#define KFD_DRIVER_DATE "20141113" +#define KFD_DRIVER_MAJOR 0 +#define KFD_DRIVER_MINOR 7 +#define KFD_DRIVER_PATCHLEVEL 0 + +const struct kfd2kgd_calls *kfd2kgd; +static const struct kgd2kfd_calls kgd2kfd = { + .exit = kgd2kfd_exit, + .probe = kgd2kfd_probe, + .device_init = kgd2kfd_device_init, + .device_exit = kgd2kfd_device_exit, + .interrupt = kgd2kfd_interrupt, + .suspend = kgd2kfd_suspend, + .resume = kgd2kfd_resume, +}; + +bool kgd2kfd_init(unsigned interface_version, + const struct kfd2kgd_calls *f2g, + const struct kgd2kfd_calls **g2f) +{ + /* + * Only one interface version is supported, + * no kfd/kgd version skew allowed. + */ + if (interface_version != KFD_INTERFACE_VERSION) + return false; + + kfd2kgd = f2g; + *g2f = &kgd2kfd; + + return true; +} +EXPORT_SYMBOL(kgd2kfd_init); + +void kgd2kfd_exit(void) +{ +} + +static int __init kfd_module_init(void) +{ + int err; + + err = kfd_chardev_init(); + if (err < 0) + goto err_ioctl; + + dev_info(kfd_device, "Initialized module\n"); + + return 0; + +err_ioctl: + return err; +} + +static void __exit kfd_module_exit(void) +{ + kfd_chardev_exit(); + dev_info(kfd_device, "Removed module\n"); +} + +module_init(kfd_module_init); +module_exit(kfd_module_exit); + +MODULE_AUTHOR(KFD_DRIVER_AUTHOR); +MODULE_DESCRIPTION(KFD_DRIVER_DESC); +MODULE_LICENSE("GPL and additional rights"); +MODULE_VERSION(__stringify(KFD_DRIVER_MAJOR) "." + __stringify(KFD_DRIVER_MINOR) "." + __stringify(KFD_DRIVER_PATCHLEVEL)); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h new file mode 100644 index 000000000000..219a0d3340f6 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -0,0 +1,81 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef KFD_PRIV_H_INCLUDED +#define KFD_PRIV_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include + +struct kfd_device_info { + unsigned int max_pasid_bits; + size_t ih_ring_entry_size; +}; + +struct kfd_dev { + struct kgd_dev *kgd; + + const struct kfd_device_info *device_info; + struct pci_dev *pdev; + + unsigned int id; /* topology stub index */ + + struct kgd2kfd_shared_resources shared_resources; + + bool init_complete; + +}; + +/* KGD2KFD callbacks */ +void kgd2kfd_exit(void); +struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev); +bool kgd2kfd_device_init(struct kfd_dev *kfd, + const struct kgd2kfd_shared_resources *gpu_resources); +void kgd2kfd_device_exit(struct kfd_dev *kfd); + +extern const struct kfd2kgd_calls *kfd2kgd; + +/* Character device interface */ +int kfd_chardev_init(void); +void kfd_chardev_exit(void); +struct device *kfd_chardev(void); + +/* Process data */ +struct kfd_process { +}; + +extern struct device *kfd_device; + +/* Interrupts */ +void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry); + +/* Power Management */ +void kgd2kfd_suspend(struct kfd_dev *dev); +int kgd2kfd_resume(struct kfd_dev *dev); + +#endif -- GitLab From 5b5c4e40a37e858e2bff8cd91be8e972256392c4 Mon Sep 17 00:00:00 2001 From: Evgeny Pinchuk Date: Wed, 16 Jul 2014 21:22:32 +0300 Subject: [PATCH 0014/9457] amdkfd: Add topology module to amdkfd This patch adds the topology module to the driver. The topology is exposed to userspace through the sysfs. The calls to add and remove a device to/from topology are done by the radeon driver. v3: The CPU information, that is provided in the topology section of the amdkfd driver, is extracted from the CRAT table. Unlike the CPU information located in /sys/devices/system/cpu/cpu*, which is extracted from the SRAT table. While the CPU information provided by the CRAT and the SRAT tables might be identical, the node topology might be different. The SRAT table contains the topology of CPU nodes only. The CRAT table contains the topology of CPU and GPU nodes together (and can be interleaved). For example CPU node 1 in SRAT can be CPU node 3 in CRAT. Furthermore it's worth to mention that the CRAT table contains only HSA compatible nodes (nodes which are compliant with the HSA spec). To recap, amdkfd exposes a different kind of topology than the one exposed by /sys/devices/system/cpu/cpu even though it may contain similar information. v4: The topology module doesn't support uevent handling and doesn't notify the userspace about runtime modifications. It is up to the userspace to acquire snapshots of the topology information created by the amdkfd and exposed in sysfs. The following is an example of how the topology looks on a Kaveri A10-7850K system with amdkfd installed: /sys/devices/virtual/kfd/kfd/ | --- topology/ | |--- generation_id |--- system_properties |--- nodes/ | |--- 0/ | |--- gpu_id |--- name |--- properties |--- caches/ | |--- 0/ | |--- properties |--- 1/ | |--- properties |--- 2/ | |--- properties |--- io_links/ | |--- mem_banks/ | |--- 0/ | |--- properties |--- 1/ | |--- properties |--- 2/ | |--- properties |--- 3/ | |--- properties v5: Move amdkfd from drm/radeon/ to drm/amd/ Add a check if dev->gpu pointer is null before accessing it in the node_show function in kfd_topology.c This situation may occur when amdkfd is loaded and there is a GPU with a CRAT table, but that GPU isn't supported by amdkfd Signed-off-by: Evgeny Pinchuk Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.h | 294 +++++ drivers/gpu/drm/amd/amdkfd/kfd_device.c | 7 + drivers/gpu/drm/amd/amdkfd/kfd_module.c | 7 + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 18 + drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 1235 +++++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 168 +++ 7 files changed, 1730 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_crat.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_topology.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_topology.h diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index d875ce4dbda6..978654f56b4f 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -4,6 +4,6 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ -amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o +amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h new file mode 100644 index 000000000000..a374fa3d3ee6 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h @@ -0,0 +1,294 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef KFD_CRAT_H_INCLUDED +#define KFD_CRAT_H_INCLUDED + +#include + +#pragma pack(1) + +/* + * 4CC signature values for the CRAT and CDIT ACPI tables + */ + +#define CRAT_SIGNATURE "CRAT" +#define CDIT_SIGNATURE "CDIT" + +/* + * Component Resource Association Table (CRAT) + */ + +#define CRAT_OEMID_LENGTH 6 +#define CRAT_OEMTABLEID_LENGTH 8 +#define CRAT_RESERVED_LENGTH 6 + +#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1) + +struct crat_header { + uint32_t signature; + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t oem_id[CRAT_OEMID_LENGTH]; + uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH]; + uint32_t oem_revision; + uint32_t creator_id; + uint32_t creator_revision; + uint32_t total_entries; + uint16_t num_domains; + uint8_t reserved[CRAT_RESERVED_LENGTH]; +}; + +/* + * The header structure is immediately followed by total_entries of the + * data definitions + */ + +/* + * The currently defined subtype entries in the CRAT + */ +#define CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY 0 +#define CRAT_SUBTYPE_MEMORY_AFFINITY 1 +#define CRAT_SUBTYPE_CACHE_AFFINITY 2 +#define CRAT_SUBTYPE_TLB_AFFINITY 3 +#define CRAT_SUBTYPE_CCOMPUTE_AFFINITY 4 +#define CRAT_SUBTYPE_IOLINK_AFFINITY 5 +#define CRAT_SUBTYPE_MAX 6 + +#define CRAT_SIBLINGMAP_SIZE 32 + +/* + * ComputeUnit Affinity structure and definitions + */ +#define CRAT_CU_FLAGS_ENABLED 0x00000001 +#define CRAT_CU_FLAGS_HOT_PLUGGABLE 0x00000002 +#define CRAT_CU_FLAGS_CPU_PRESENT 0x00000004 +#define CRAT_CU_FLAGS_GPU_PRESENT 0x00000008 +#define CRAT_CU_FLAGS_IOMMU_PRESENT 0x00000010 +#define CRAT_CU_FLAGS_RESERVED 0xffffffe0 + +#define CRAT_COMPUTEUNIT_RESERVED_LENGTH 4 + +struct crat_subtype_computeunit { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t proximity_domain; + uint32_t processor_id_low; + uint16_t num_cpu_cores; + uint16_t num_simd_cores; + uint16_t max_waves_simd; + uint16_t io_count; + uint16_t hsa_capability; + uint16_t lds_size_in_kb; + uint8_t wave_front_size; + uint8_t num_banks; + uint16_t micro_engine_id; + uint8_t num_arrays; + uint8_t num_cu_per_array; + uint8_t num_simd_per_cu; + uint8_t max_slots_scatch_cu; + uint8_t reserved2[CRAT_COMPUTEUNIT_RESERVED_LENGTH]; +}; + +/* + * HSA Memory Affinity structure and definitions + */ +#define CRAT_MEM_FLAGS_ENABLED 0x00000001 +#define CRAT_MEM_FLAGS_HOT_PLUGGABLE 0x00000002 +#define CRAT_MEM_FLAGS_NON_VOLATILE 0x00000004 +#define CRAT_MEM_FLAGS_RESERVED 0xfffffff8 + +#define CRAT_MEMORY_RESERVED_LENGTH 8 + +struct crat_subtype_memory { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t promixity_domain; + uint32_t base_addr_low; + uint32_t base_addr_high; + uint32_t length_low; + uint32_t length_high; + uint32_t width; + uint8_t reserved2[CRAT_MEMORY_RESERVED_LENGTH]; +}; + +/* + * HSA Cache Affinity structure and definitions + */ +#define CRAT_CACHE_FLAGS_ENABLED 0x00000001 +#define CRAT_CACHE_FLAGS_DATA_CACHE 0x00000002 +#define CRAT_CACHE_FLAGS_INST_CACHE 0x00000004 +#define CRAT_CACHE_FLAGS_CPU_CACHE 0x00000008 +#define CRAT_CACHE_FLAGS_SIMD_CACHE 0x00000010 +#define CRAT_CACHE_FLAGS_RESERVED 0xffffffe0 + +#define CRAT_CACHE_RESERVED_LENGTH 8 + +struct crat_subtype_cache { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t processor_id_low; + uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE]; + uint32_t cache_size; + uint8_t cache_level; + uint8_t lines_per_tag; + uint16_t cache_line_size; + uint8_t associativity; + uint8_t cache_properties; + uint16_t cache_latency; + uint8_t reserved2[CRAT_CACHE_RESERVED_LENGTH]; +}; + +/* + * HSA TLB Affinity structure and definitions + */ +#define CRAT_TLB_FLAGS_ENABLED 0x00000001 +#define CRAT_TLB_FLAGS_DATA_TLB 0x00000002 +#define CRAT_TLB_FLAGS_INST_TLB 0x00000004 +#define CRAT_TLB_FLAGS_CPU_TLB 0x00000008 +#define CRAT_TLB_FLAGS_SIMD_TLB 0x00000010 +#define CRAT_TLB_FLAGS_RESERVED 0xffffffe0 + +#define CRAT_TLB_RESERVED_LENGTH 4 + +struct crat_subtype_tlb { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t processor_id_low; + uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE]; + uint32_t tlb_level; + uint8_t data_tlb_associativity_2mb; + uint8_t data_tlb_size_2mb; + uint8_t instruction_tlb_associativity_2mb; + uint8_t instruction_tlb_size_2mb; + uint8_t data_tlb_associativity_4k; + uint8_t data_tlb_size_4k; + uint8_t instruction_tlb_associativity_4k; + uint8_t instruction_tlb_size_4k; + uint8_t data_tlb_associativity_1gb; + uint8_t data_tlb_size_1gb; + uint8_t instruction_tlb_associativity_1gb; + uint8_t instruction_tlb_size_1gb; + uint8_t reserved2[CRAT_TLB_RESERVED_LENGTH]; +}; + +/* + * HSA CCompute/APU Affinity structure and definitions + */ +#define CRAT_CCOMPUTE_FLAGS_ENABLED 0x00000001 +#define CRAT_CCOMPUTE_FLAGS_RESERVED 0xfffffffe + +#define CRAT_CCOMPUTE_RESERVED_LENGTH 16 + +struct crat_subtype_ccompute { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t processor_id_low; + uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE]; + uint32_t apu_size; + uint8_t reserved2[CRAT_CCOMPUTE_RESERVED_LENGTH]; +}; + +/* + * HSA IO Link Affinity structure and definitions + */ +#define CRAT_IOLINK_FLAGS_ENABLED 0x00000001 +#define CRAT_IOLINK_FLAGS_COHERENCY 0x00000002 +#define CRAT_IOLINK_FLAGS_RESERVED 0xfffffffc + +/* + * IO interface types + */ +#define CRAT_IOLINK_TYPE_UNDEFINED 0 +#define CRAT_IOLINK_TYPE_HYPERTRANSPORT 1 +#define CRAT_IOLINK_TYPE_PCIEXPRESS 2 +#define CRAT_IOLINK_TYPE_OTHER 3 +#define CRAT_IOLINK_TYPE_MAX 255 + +#define CRAT_IOLINK_RESERVED_LENGTH 24 + +struct crat_subtype_iolink { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; + uint32_t proximity_domain_from; + uint32_t proximity_domain_to; + uint8_t io_interface_type; + uint8_t version_major; + uint16_t version_minor; + uint32_t minimum_latency; + uint32_t maximum_latency; + uint32_t minimum_bandwidth_mbs; + uint32_t maximum_bandwidth_mbs; + uint32_t recommended_transfer_size; + uint8_t reserved2[CRAT_IOLINK_RESERVED_LENGTH]; +}; + +/* + * HSA generic sub-type header + */ + +#define CRAT_SUBTYPE_FLAGS_ENABLED 0x00000001 + +struct crat_subtype_generic { + uint8_t type; + uint8_t length; + uint16_t reserved; + uint32_t flags; +}; + +/* + * Component Locality Distance Information Table (CDIT) + */ +#define CDIT_OEMID_LENGTH 6 +#define CDIT_OEMTABLEID_LENGTH 8 + +struct cdit_header { + uint32_t signature; + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t oem_id[CDIT_OEMID_LENGTH]; + uint8_t oem_table_id[CDIT_OEMTABLEID_LENGTH]; + uint32_t oem_revision; + uint32_t creator_id; + uint32_t creator_revision; + uint32_t total_entries; + uint16_t num_domains; + uint8_t entry[1]; +}; + +#pragma pack() + +#endif /* KFD_CRAT_H_INCLUDED */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index d81a58eeec29..53b2e19cabe0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -101,6 +101,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, { kfd->shared_resources = *gpu_resources; + if (kfd_topology_add_device(kfd) != 0) + return false; + kfd->init_complete = true; dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor, kfd->pdev->device); @@ -110,6 +113,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, void kgd2kfd_device_exit(struct kfd_dev *kfd) { + int err = kfd_topology_remove_device(kfd); + + BUG_ON(err != 0); + kfree(kfd); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index 9519f33bd59c..45654be039ff 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -76,16 +76,23 @@ static int __init kfd_module_init(void) if (err < 0) goto err_ioctl; + err = kfd_topology_init(); + if (err < 0) + goto err_topology; + dev_info(kfd_device, "Initialized module\n"); return 0; +err_topology: + kfd_chardev_exit(); err_ioctl: return err; } static void __exit kfd_module_exit(void) { + kfd_topology_shutdown(); kfd_chardev_exit(); dev_info(kfd_device, "Removed module\n"); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 219a0d3340f6..b58b86dcc057 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -32,6 +32,15 @@ #include #include +#define KFD_SYSFS_FILE_MODE 0444 + +/* GPU ID hash width in bits */ +#define KFD_GPU_ID_HASH_WIDTH 16 + +/* Macro for allocating structures */ +#define kfd_alloc_struct(ptr_to_struct) \ + ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) + struct kfd_device_info { unsigned int max_pasid_bits; size_t ih_ring_entry_size; @@ -71,6 +80,15 @@ struct kfd_process { extern struct device *kfd_device; +/* Topology */ +int kfd_topology_init(void); +void kfd_topology_shutdown(void); +int kfd_topology_add_device(struct kfd_dev *gpu); +int kfd_topology_remove_device(struct kfd_dev *gpu); +struct kfd_dev *kfd_device_by_id(uint32_t gpu_id); +struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); +struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); + /* Interrupts */ void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c new file mode 100644 index 000000000000..77cd7d55b39d --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -0,0 +1,1235 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "kfd_priv.h" +#include "kfd_crat.h" +#include "kfd_topology.h" + +static struct list_head topology_device_list; +static int topology_crat_parsed; +static struct kfd_system_properties sys_props; + +static DECLARE_RWSEM(topology_lock); + +struct kfd_dev *kfd_device_by_id(uint32_t gpu_id) +{ + struct kfd_topology_device *top_dev; + struct kfd_dev *device = NULL; + + down_read(&topology_lock); + + list_for_each_entry(top_dev, &topology_device_list, list) + if (top_dev->gpu_id == gpu_id) { + device = top_dev->gpu; + break; + } + + up_read(&topology_lock); + + return device; +} + +struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev) +{ + struct kfd_topology_device *top_dev; + struct kfd_dev *device = NULL; + + down_read(&topology_lock); + + list_for_each_entry(top_dev, &topology_device_list, list) + if (top_dev->gpu->pdev == pdev) { + device = top_dev->gpu; + break; + } + + up_read(&topology_lock); + + return device; +} + +static int kfd_topology_get_crat_acpi(void *crat_image, size_t *size) +{ + struct acpi_table_header *crat_table; + acpi_status status; + + if (!size) + return -EINVAL; + + /* + * Fetch the CRAT table from ACPI + */ + status = acpi_get_table(CRAT_SIGNATURE, 0, &crat_table); + if (status == AE_NOT_FOUND) { + pr_warn("CRAT table not found\n"); + return -ENODATA; + } else if (ACPI_FAILURE(status)) { + const char *err = acpi_format_exception(status); + + pr_err("CRAT table error: %s\n", err); + return -EINVAL; + } + + if (*size >= crat_table->length && crat_image != 0) + memcpy(crat_image, crat_table, crat_table->length); + + *size = crat_table->length; + + return 0; +} + +static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, + struct crat_subtype_computeunit *cu) +{ + BUG_ON(!dev); + BUG_ON(!cu); + + dev->node_props.cpu_cores_count = cu->num_cpu_cores; + dev->node_props.cpu_core_id_base = cu->processor_id_low; + if (cu->hsa_capability & CRAT_CU_FLAGS_IOMMU_PRESENT) + dev->node_props.capability |= HSA_CAP_ATS_PRESENT; + + pr_info("CU CPU: cores=%d id_base=%d\n", cu->num_cpu_cores, + cu->processor_id_low); +} + +static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev, + struct crat_subtype_computeunit *cu) +{ + BUG_ON(!dev); + BUG_ON(!cu); + + dev->node_props.simd_id_base = cu->processor_id_low; + dev->node_props.simd_count = cu->num_simd_cores; + dev->node_props.lds_size_in_kb = cu->lds_size_in_kb; + dev->node_props.max_waves_per_simd = cu->max_waves_simd; + dev->node_props.wave_front_size = cu->wave_front_size; + dev->node_props.mem_banks_count = cu->num_banks; + dev->node_props.array_count = cu->num_arrays; + dev->node_props.cu_per_simd_array = cu->num_cu_per_array; + dev->node_props.simd_per_cu = cu->num_simd_per_cu; + dev->node_props.max_slots_scratch_cu = cu->max_slots_scatch_cu; + if (cu->hsa_capability & CRAT_CU_FLAGS_HOT_PLUGGABLE) + dev->node_props.capability |= HSA_CAP_HOT_PLUGGABLE; + pr_info("CU GPU: simds=%d id_base=%d\n", cu->num_simd_cores, + cu->processor_id_low); +} + +/* kfd_parse_subtype_cu is called when the topology mutex is already acquired */ +static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu) +{ + struct kfd_topology_device *dev; + int i = 0; + + BUG_ON(!cu); + + pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n", + cu->proximity_domain, cu->hsa_capability); + list_for_each_entry(dev, &topology_device_list, list) { + if (cu->proximity_domain == i) { + if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT) + kfd_populated_cu_info_cpu(dev, cu); + + if (cu->flags & CRAT_CU_FLAGS_GPU_PRESENT) + kfd_populated_cu_info_gpu(dev, cu); + break; + } + i++; + } + + return 0; +} + +/* + * kfd_parse_subtype_mem is called when the topology mutex is + * already acquired + */ +static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) +{ + struct kfd_mem_properties *props; + struct kfd_topology_device *dev; + int i = 0; + + BUG_ON(!mem); + + pr_info("Found memory entry in CRAT table with proximity_domain=%d\n", + mem->promixity_domain); + list_for_each_entry(dev, &topology_device_list, list) { + if (mem->promixity_domain == i) { + props = kfd_alloc_struct(props); + if (props == 0) + return -ENOMEM; + + if (dev->node_props.cpu_cores_count == 0) + props->heap_type = HSA_MEM_HEAP_TYPE_FB_PRIVATE; + else + props->heap_type = HSA_MEM_HEAP_TYPE_SYSTEM; + + if (mem->flags & CRAT_MEM_FLAGS_HOT_PLUGGABLE) + props->flags |= HSA_MEM_FLAGS_HOT_PLUGGABLE; + if (mem->flags & CRAT_MEM_FLAGS_NON_VOLATILE) + props->flags |= HSA_MEM_FLAGS_NON_VOLATILE; + + props->size_in_bytes = + ((uint64_t)mem->length_high << 32) + + mem->length_low; + props->width = mem->width; + + dev->mem_bank_count++; + list_add_tail(&props->list, &dev->mem_props); + + break; + } + i++; + } + + return 0; +} + +/* + * kfd_parse_subtype_cache is called when the topology mutex + * is already acquired + */ +static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) +{ + struct kfd_cache_properties *props; + struct kfd_topology_device *dev; + uint32_t id; + + BUG_ON(!cache); + + id = cache->processor_id_low; + + pr_info("Found cache entry in CRAT table with processor_id=%d\n", id); + list_for_each_entry(dev, &topology_device_list, list) + if (id == dev->node_props.cpu_core_id_base || + id == dev->node_props.simd_id_base) { + props = kfd_alloc_struct(props); + if (props == 0) + return -ENOMEM; + + props->processor_id_low = id; + props->cache_level = cache->cache_level; + props->cache_size = cache->cache_size; + props->cacheline_size = cache->cache_line_size; + props->cachelines_per_tag = cache->lines_per_tag; + props->cache_assoc = cache->associativity; + props->cache_latency = cache->cache_latency; + + if (cache->flags & CRAT_CACHE_FLAGS_DATA_CACHE) + props->cache_type |= HSA_CACHE_TYPE_DATA; + if (cache->flags & CRAT_CACHE_FLAGS_INST_CACHE) + props->cache_type |= HSA_CACHE_TYPE_INSTRUCTION; + if (cache->flags & CRAT_CACHE_FLAGS_CPU_CACHE) + props->cache_type |= HSA_CACHE_TYPE_CPU; + if (cache->flags & CRAT_CACHE_FLAGS_SIMD_CACHE) + props->cache_type |= HSA_CACHE_TYPE_HSACU; + + dev->cache_count++; + dev->node_props.caches_count++; + list_add_tail(&props->list, &dev->cache_props); + + break; + } + + return 0; +} + +/* + * kfd_parse_subtype_iolink is called when the topology mutex + * is already acquired + */ +static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) +{ + struct kfd_iolink_properties *props; + struct kfd_topology_device *dev; + uint32_t i = 0; + uint32_t id_from; + uint32_t id_to; + + BUG_ON(!iolink); + + id_from = iolink->proximity_domain_from; + id_to = iolink->proximity_domain_to; + + pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from); + list_for_each_entry(dev, &topology_device_list, list) { + if (id_from == i) { + props = kfd_alloc_struct(props); + if (props == 0) + return -ENOMEM; + + props->node_from = id_from; + props->node_to = id_to; + props->ver_maj = iolink->version_major; + props->ver_min = iolink->version_minor; + + /* + * weight factor (derived from CDIR), currently always 1 + */ + props->weight = 1; + + props->min_latency = iolink->minimum_latency; + props->max_latency = iolink->maximum_latency; + props->min_bandwidth = iolink->minimum_bandwidth_mbs; + props->max_bandwidth = iolink->maximum_bandwidth_mbs; + props->rec_transfer_size = + iolink->recommended_transfer_size; + + dev->io_link_count++; + dev->node_props.io_links_count++; + list_add_tail(&props->list, &dev->io_link_props); + + break; + } + i++; + } + + return 0; +} + +static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) +{ + struct crat_subtype_computeunit *cu; + struct crat_subtype_memory *mem; + struct crat_subtype_cache *cache; + struct crat_subtype_iolink *iolink; + int ret = 0; + + BUG_ON(!sub_type_hdr); + + switch (sub_type_hdr->type) { + case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY: + cu = (struct crat_subtype_computeunit *)sub_type_hdr; + ret = kfd_parse_subtype_cu(cu); + break; + case CRAT_SUBTYPE_MEMORY_AFFINITY: + mem = (struct crat_subtype_memory *)sub_type_hdr; + ret = kfd_parse_subtype_mem(mem); + break; + case CRAT_SUBTYPE_CACHE_AFFINITY: + cache = (struct crat_subtype_cache *)sub_type_hdr; + ret = kfd_parse_subtype_cache(cache); + break; + case CRAT_SUBTYPE_TLB_AFFINITY: + /* + * For now, nothing to do here + */ + pr_info("Found TLB entry in CRAT table (not processing)\n"); + break; + case CRAT_SUBTYPE_CCOMPUTE_AFFINITY: + /* + * For now, nothing to do here + */ + pr_info("Found CCOMPUTE entry in CRAT table (not processing)\n"); + break; + case CRAT_SUBTYPE_IOLINK_AFFINITY: + iolink = (struct crat_subtype_iolink *)sub_type_hdr; + ret = kfd_parse_subtype_iolink(iolink); + break; + default: + pr_warn("Unknown subtype (%d) in CRAT\n", + sub_type_hdr->type); + } + + return ret; +} + +static void kfd_release_topology_device(struct kfd_topology_device *dev) +{ + struct kfd_mem_properties *mem; + struct kfd_cache_properties *cache; + struct kfd_iolink_properties *iolink; + + BUG_ON(!dev); + + list_del(&dev->list); + + while (dev->mem_props.next != &dev->mem_props) { + mem = container_of(dev->mem_props.next, + struct kfd_mem_properties, list); + list_del(&mem->list); + kfree(mem); + } + + while (dev->cache_props.next != &dev->cache_props) { + cache = container_of(dev->cache_props.next, + struct kfd_cache_properties, list); + list_del(&cache->list); + kfree(cache); + } + + while (dev->io_link_props.next != &dev->io_link_props) { + iolink = container_of(dev->io_link_props.next, + struct kfd_iolink_properties, list); + list_del(&iolink->list); + kfree(iolink); + } + + kfree(dev); + + sys_props.num_devices--; +} + +static void kfd_release_live_view(void) +{ + struct kfd_topology_device *dev; + + while (topology_device_list.next != &topology_device_list) { + dev = container_of(topology_device_list.next, + struct kfd_topology_device, list); + kfd_release_topology_device(dev); +} + + memset(&sys_props, 0, sizeof(sys_props)); +} + +static struct kfd_topology_device *kfd_create_topology_device(void) +{ + struct kfd_topology_device *dev; + + dev = kfd_alloc_struct(dev); + if (dev == 0) { + pr_err("No memory to allocate a topology device"); + return 0; + } + + INIT_LIST_HEAD(&dev->mem_props); + INIT_LIST_HEAD(&dev->cache_props); + INIT_LIST_HEAD(&dev->io_link_props); + + list_add_tail(&dev->list, &topology_device_list); + sys_props.num_devices++; + + return dev; + } + +static int kfd_parse_crat_table(void *crat_image) +{ + struct kfd_topology_device *top_dev; + struct crat_subtype_generic *sub_type_hdr; + uint16_t node_id; + int ret; + struct crat_header *crat_table = (struct crat_header *)crat_image; + uint16_t num_nodes; + uint32_t image_len; + + if (!crat_image) + return -EINVAL; + + num_nodes = crat_table->num_domains; + image_len = crat_table->length; + + pr_info("Parsing CRAT table with %d nodes\n", num_nodes); + + for (node_id = 0; node_id < num_nodes; node_id++) { + top_dev = kfd_create_topology_device(); + if (!top_dev) { + kfd_release_live_view(); + return -ENOMEM; + } + } + + sys_props.platform_id = + (*((uint64_t *)crat_table->oem_id)) & CRAT_OEMID_64BIT_MASK; + sys_props.platform_oem = *((uint64_t *)crat_table->oem_table_id); + sys_props.platform_rev = crat_table->revision; + + sub_type_hdr = (struct crat_subtype_generic *)(crat_table+1); + while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) < + ((char *)crat_image) + image_len) { + if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) { + ret = kfd_parse_subtype(sub_type_hdr); + if (ret != 0) { + kfd_release_live_view(); + return ret; + } + } + + sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + + sub_type_hdr->length); + } + + sys_props.generation_count++; + topology_crat_parsed = 1; + + return 0; +} + + +#define sysfs_show_gen_prop(buffer, fmt, ...) \ + snprintf(buffer, PAGE_SIZE, "%s"fmt, buffer, __VA_ARGS__) +#define sysfs_show_32bit_prop(buffer, name, value) \ + sysfs_show_gen_prop(buffer, "%s %u\n", name, value) +#define sysfs_show_64bit_prop(buffer, name, value) \ + sysfs_show_gen_prop(buffer, "%s %llu\n", name, value) +#define sysfs_show_32bit_val(buffer, value) \ + sysfs_show_gen_prop(buffer, "%u\n", value) +#define sysfs_show_str_val(buffer, value) \ + sysfs_show_gen_prop(buffer, "%s\n", value) + +static ssize_t sysprops_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + ssize_t ret; + + /* Making sure that the buffer is an empty string */ + buffer[0] = 0; + + if (attr == &sys_props.attr_genid) { + ret = sysfs_show_32bit_val(buffer, sys_props.generation_count); + } else if (attr == &sys_props.attr_props) { + sysfs_show_64bit_prop(buffer, "platform_oem", + sys_props.platform_oem); + sysfs_show_64bit_prop(buffer, "platform_id", + sys_props.platform_id); + ret = sysfs_show_64bit_prop(buffer, "platform_rev", + sys_props.platform_rev); + } else { + ret = -EINVAL; + } + + return ret; +} + +static const struct sysfs_ops sysprops_ops = { + .show = sysprops_show, +}; + +static struct kobj_type sysprops_type = { + .sysfs_ops = &sysprops_ops, +}; + +static ssize_t iolink_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + ssize_t ret; + struct kfd_iolink_properties *iolink; + + /* Making sure that the buffer is an empty string */ + buffer[0] = 0; + + iolink = container_of(attr, struct kfd_iolink_properties, attr); + sysfs_show_32bit_prop(buffer, "type", iolink->iolink_type); + sysfs_show_32bit_prop(buffer, "version_major", iolink->ver_maj); + sysfs_show_32bit_prop(buffer, "version_minor", iolink->ver_min); + sysfs_show_32bit_prop(buffer, "node_from", iolink->node_from); + sysfs_show_32bit_prop(buffer, "node_to", iolink->node_to); + sysfs_show_32bit_prop(buffer, "weight", iolink->weight); + sysfs_show_32bit_prop(buffer, "min_latency", iolink->min_latency); + sysfs_show_32bit_prop(buffer, "max_latency", iolink->max_latency); + sysfs_show_32bit_prop(buffer, "min_bandwidth", iolink->min_bandwidth); + sysfs_show_32bit_prop(buffer, "max_bandwidth", iolink->max_bandwidth); + sysfs_show_32bit_prop(buffer, "recommended_transfer_size", + iolink->rec_transfer_size); + ret = sysfs_show_32bit_prop(buffer, "flags", iolink->flags); + + return ret; +} + +static const struct sysfs_ops iolink_ops = { + .show = iolink_show, +}; + +static struct kobj_type iolink_type = { + .sysfs_ops = &iolink_ops, +}; + +static ssize_t mem_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + ssize_t ret; + struct kfd_mem_properties *mem; + + /* Making sure that the buffer is an empty string */ + buffer[0] = 0; + + mem = container_of(attr, struct kfd_mem_properties, attr); + sysfs_show_32bit_prop(buffer, "heap_type", mem->heap_type); + sysfs_show_64bit_prop(buffer, "size_in_bytes", mem->size_in_bytes); + sysfs_show_32bit_prop(buffer, "flags", mem->flags); + sysfs_show_32bit_prop(buffer, "width", mem->width); + ret = sysfs_show_32bit_prop(buffer, "mem_clk_max", mem->mem_clk_max); + + return ret; +} + +static const struct sysfs_ops mem_ops = { + .show = mem_show, +}; + +static struct kobj_type mem_type = { + .sysfs_ops = &mem_ops, +}; + +static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + ssize_t ret; + uint32_t i; + struct kfd_cache_properties *cache; + + /* Making sure that the buffer is an empty string */ + buffer[0] = 0; + + cache = container_of(attr, struct kfd_cache_properties, attr); + sysfs_show_32bit_prop(buffer, "processor_id_low", + cache->processor_id_low); + sysfs_show_32bit_prop(buffer, "level", cache->cache_level); + sysfs_show_32bit_prop(buffer, "size", cache->cache_size); + sysfs_show_32bit_prop(buffer, "cache_line_size", cache->cacheline_size); + sysfs_show_32bit_prop(buffer, "cache_lines_per_tag", + cache->cachelines_per_tag); + sysfs_show_32bit_prop(buffer, "association", cache->cache_assoc); + sysfs_show_32bit_prop(buffer, "latency", cache->cache_latency); + sysfs_show_32bit_prop(buffer, "type", cache->cache_type); + snprintf(buffer, PAGE_SIZE, "%ssibling_map ", buffer); + for (i = 0; i < KFD_TOPOLOGY_CPU_SIBLINGS; i++) + ret = snprintf(buffer, PAGE_SIZE, "%s%d%s", + buffer, cache->sibling_map[i], + (i == KFD_TOPOLOGY_CPU_SIBLINGS-1) ? + "\n" : ","); + + return ret; +} + +static const struct sysfs_ops cache_ops = { + .show = kfd_cache_show, +}; + +static struct kobj_type cache_type = { + .sysfs_ops = &cache_ops, +}; + +static ssize_t node_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + ssize_t ret; + struct kfd_topology_device *dev; + char public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE]; + uint32_t i; + + /* Making sure that the buffer is an empty string */ + buffer[0] = 0; + + if (strcmp(attr->name, "gpu_id") == 0) { + dev = container_of(attr, struct kfd_topology_device, + attr_gpuid); + ret = sysfs_show_32bit_val(buffer, dev->gpu_id); + } else if (strcmp(attr->name, "name") == 0) { + dev = container_of(attr, struct kfd_topology_device, + attr_name); + for (i = 0; i < KFD_TOPOLOGY_PUBLIC_NAME_SIZE; i++) { + public_name[i] = + (char)dev->node_props.marketing_name[i]; + if (dev->node_props.marketing_name[i] == 0) + break; + } + public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE-1] = 0x0; + ret = sysfs_show_str_val(buffer, public_name); + } else { + dev = container_of(attr, struct kfd_topology_device, + attr_props); + sysfs_show_32bit_prop(buffer, "cpu_cores_count", + dev->node_props.cpu_cores_count); + sysfs_show_32bit_prop(buffer, "simd_count", + dev->node_props.simd_count); + + if (dev->mem_bank_count < dev->node_props.mem_banks_count) { + pr_warn("kfd: mem_banks_count truncated from %d to %d\n", + dev->node_props.mem_banks_count, + dev->mem_bank_count); + sysfs_show_32bit_prop(buffer, "mem_banks_count", + dev->mem_bank_count); + } else { + sysfs_show_32bit_prop(buffer, "mem_banks_count", + dev->node_props.mem_banks_count); + } + + sysfs_show_32bit_prop(buffer, "caches_count", + dev->node_props.caches_count); + sysfs_show_32bit_prop(buffer, "io_links_count", + dev->node_props.io_links_count); + sysfs_show_32bit_prop(buffer, "cpu_core_id_base", + dev->node_props.cpu_core_id_base); + sysfs_show_32bit_prop(buffer, "simd_id_base", + dev->node_props.simd_id_base); + sysfs_show_32bit_prop(buffer, "capability", + dev->node_props.capability); + sysfs_show_32bit_prop(buffer, "max_waves_per_simd", + dev->node_props.max_waves_per_simd); + sysfs_show_32bit_prop(buffer, "lds_size_in_kb", + dev->node_props.lds_size_in_kb); + sysfs_show_32bit_prop(buffer, "gds_size_in_kb", + dev->node_props.gds_size_in_kb); + sysfs_show_32bit_prop(buffer, "wave_front_size", + dev->node_props.wave_front_size); + sysfs_show_32bit_prop(buffer, "array_count", + dev->node_props.array_count); + sysfs_show_32bit_prop(buffer, "simd_arrays_per_engine", + dev->node_props.simd_arrays_per_engine); + sysfs_show_32bit_prop(buffer, "cu_per_simd_array", + dev->node_props.cu_per_simd_array); + sysfs_show_32bit_prop(buffer, "simd_per_cu", + dev->node_props.simd_per_cu); + sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu", + dev->node_props.max_slots_scratch_cu); + sysfs_show_32bit_prop(buffer, "engine_id", + dev->node_props.engine_id); + sysfs_show_32bit_prop(buffer, "vendor_id", + dev->node_props.vendor_id); + sysfs_show_32bit_prop(buffer, "device_id", + dev->node_props.device_id); + sysfs_show_32bit_prop(buffer, "location_id", + dev->node_props.location_id); + + if (dev->gpu) { + sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute", + kfd2kgd->get_max_engine_clock_in_mhz( + dev->gpu->kgd)); + sysfs_show_64bit_prop(buffer, "local_mem_size", + kfd2kgd->get_vmem_size(dev->gpu->kgd)); + } + + ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", + cpufreq_quick_get_max(0)/1000); + } + + return ret; +} + +static const struct sysfs_ops node_ops = { + .show = node_show, +}; + +static struct kobj_type node_type = { + .sysfs_ops = &node_ops, +}; + +static void kfd_remove_sysfs_file(struct kobject *kobj, struct attribute *attr) +{ + sysfs_remove_file(kobj, attr); + kobject_del(kobj); + kobject_put(kobj); +} + +static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev) +{ + struct kfd_iolink_properties *iolink; + struct kfd_cache_properties *cache; + struct kfd_mem_properties *mem; + + BUG_ON(!dev); + + if (dev->kobj_iolink) { + list_for_each_entry(iolink, &dev->io_link_props, list) + if (iolink->kobj) { + kfd_remove_sysfs_file(iolink->kobj, + &iolink->attr); + iolink->kobj = 0; + } + kobject_del(dev->kobj_iolink); + kobject_put(dev->kobj_iolink); + dev->kobj_iolink = 0; + } + + if (dev->kobj_cache) { + list_for_each_entry(cache, &dev->cache_props, list) + if (cache->kobj) { + kfd_remove_sysfs_file(cache->kobj, + &cache->attr); + cache->kobj = 0; + } + kobject_del(dev->kobj_cache); + kobject_put(dev->kobj_cache); + dev->kobj_cache = 0; + } + + if (dev->kobj_mem) { + list_for_each_entry(mem, &dev->mem_props, list) + if (mem->kobj) { + kfd_remove_sysfs_file(mem->kobj, &mem->attr); + mem->kobj = 0; + } + kobject_del(dev->kobj_mem); + kobject_put(dev->kobj_mem); + dev->kobj_mem = 0; + } + + if (dev->kobj_node) { + sysfs_remove_file(dev->kobj_node, &dev->attr_gpuid); + sysfs_remove_file(dev->kobj_node, &dev->attr_name); + sysfs_remove_file(dev->kobj_node, &dev->attr_props); + kobject_del(dev->kobj_node); + kobject_put(dev->kobj_node); + dev->kobj_node = 0; + } +} + +static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, + uint32_t id) +{ + struct kfd_iolink_properties *iolink; + struct kfd_cache_properties *cache; + struct kfd_mem_properties *mem; + int ret; + uint32_t i; + + BUG_ON(!dev); + + /* + * Creating the sysfs folders + */ + BUG_ON(dev->kobj_node); + dev->kobj_node = kfd_alloc_struct(dev->kobj_node); + if (!dev->kobj_node) + return -ENOMEM; + + ret = kobject_init_and_add(dev->kobj_node, &node_type, + sys_props.kobj_nodes, "%d", id); + if (ret < 0) + return ret; + + dev->kobj_mem = kobject_create_and_add("mem_banks", dev->kobj_node); + if (!dev->kobj_mem) + return -ENOMEM; + + dev->kobj_cache = kobject_create_and_add("caches", dev->kobj_node); + if (!dev->kobj_cache) + return -ENOMEM; + + dev->kobj_iolink = kobject_create_and_add("io_links", dev->kobj_node); + if (!dev->kobj_iolink) + return -ENOMEM; + + /* + * Creating sysfs files for node properties + */ + dev->attr_gpuid.name = "gpu_id"; + dev->attr_gpuid.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&dev->attr_gpuid); + dev->attr_name.name = "name"; + dev->attr_name.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&dev->attr_name); + dev->attr_props.name = "properties"; + dev->attr_props.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&dev->attr_props); + ret = sysfs_create_file(dev->kobj_node, &dev->attr_gpuid); + if (ret < 0) + return ret; + ret = sysfs_create_file(dev->kobj_node, &dev->attr_name); + if (ret < 0) + return ret; + ret = sysfs_create_file(dev->kobj_node, &dev->attr_props); + if (ret < 0) + return ret; + + i = 0; + list_for_each_entry(mem, &dev->mem_props, list) { + mem->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + if (!mem->kobj) + return -ENOMEM; + ret = kobject_init_and_add(mem->kobj, &mem_type, + dev->kobj_mem, "%d", i); + if (ret < 0) + return ret; + + mem->attr.name = "properties"; + mem->attr.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&mem->attr); + ret = sysfs_create_file(mem->kobj, &mem->attr); + if (ret < 0) + return ret; + i++; + } + + i = 0; + list_for_each_entry(cache, &dev->cache_props, list) { + cache->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + if (!cache->kobj) + return -ENOMEM; + ret = kobject_init_and_add(cache->kobj, &cache_type, + dev->kobj_cache, "%d", i); + if (ret < 0) + return ret; + + cache->attr.name = "properties"; + cache->attr.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&cache->attr); + ret = sysfs_create_file(cache->kobj, &cache->attr); + if (ret < 0) + return ret; + i++; + } + + i = 0; + list_for_each_entry(iolink, &dev->io_link_props, list) { + iolink->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + if (!iolink->kobj) + return -ENOMEM; + ret = kobject_init_and_add(iolink->kobj, &iolink_type, + dev->kobj_iolink, "%d", i); + if (ret < 0) + return ret; + + iolink->attr.name = "properties"; + iolink->attr.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&iolink->attr); + ret = sysfs_create_file(iolink->kobj, &iolink->attr); + if (ret < 0) + return ret; + i++; +} + + return 0; +} + +static int kfd_build_sysfs_node_tree(void) +{ + struct kfd_topology_device *dev; + int ret; + uint32_t i = 0; + + list_for_each_entry(dev, &topology_device_list, list) { + ret = kfd_build_sysfs_node_entry(dev, 0); + if (ret < 0) + return ret; + i++; + } + + return 0; +} + +static void kfd_remove_sysfs_node_tree(void) +{ + struct kfd_topology_device *dev; + + list_for_each_entry(dev, &topology_device_list, list) + kfd_remove_sysfs_node_entry(dev); +} + +static int kfd_topology_update_sysfs(void) +{ + int ret; + + pr_info("Creating topology SYSFS entries\n"); + if (sys_props.kobj_topology == 0) { + sys_props.kobj_topology = + kfd_alloc_struct(sys_props.kobj_topology); + if (!sys_props.kobj_topology) + return -ENOMEM; + + ret = kobject_init_and_add(sys_props.kobj_topology, + &sysprops_type, &kfd_device->kobj, + "topology"); + if (ret < 0) + return ret; + + sys_props.kobj_nodes = kobject_create_and_add("nodes", + sys_props.kobj_topology); + if (!sys_props.kobj_nodes) + return -ENOMEM; + + sys_props.attr_genid.name = "generation_id"; + sys_props.attr_genid.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&sys_props.attr_genid); + ret = sysfs_create_file(sys_props.kobj_topology, + &sys_props.attr_genid); + if (ret < 0) + return ret; + + sys_props.attr_props.name = "system_properties"; + sys_props.attr_props.mode = KFD_SYSFS_FILE_MODE; + sysfs_attr_init(&sys_props.attr_props); + ret = sysfs_create_file(sys_props.kobj_topology, + &sys_props.attr_props); + if (ret < 0) + return ret; + } + + kfd_remove_sysfs_node_tree(); + + return kfd_build_sysfs_node_tree(); +} + +static void kfd_topology_release_sysfs(void) +{ + kfd_remove_sysfs_node_tree(); + if (sys_props.kobj_topology) { + sysfs_remove_file(sys_props.kobj_topology, + &sys_props.attr_genid); + sysfs_remove_file(sys_props.kobj_topology, + &sys_props.attr_props); + if (sys_props.kobj_nodes) { + kobject_del(sys_props.kobj_nodes); + kobject_put(sys_props.kobj_nodes); + sys_props.kobj_nodes = 0; + } + kobject_del(sys_props.kobj_topology); + kobject_put(sys_props.kobj_topology); + sys_props.kobj_topology = 0; + } +} + +int kfd_topology_init(void) +{ + void *crat_image = 0; + size_t image_size = 0; + int ret; + + /* + * Initialize the head for the topology device list + */ + INIT_LIST_HEAD(&topology_device_list); + init_rwsem(&topology_lock); + topology_crat_parsed = 0; + + memset(&sys_props, 0, sizeof(sys_props)); + + /* + * Get the CRAT image from the ACPI + */ + ret = kfd_topology_get_crat_acpi(crat_image, &image_size); + if (ret == 0 && image_size > 0) { + pr_info("Found CRAT image with size=%zd\n", image_size); + crat_image = kmalloc(image_size, GFP_KERNEL); + if (!crat_image) { + ret = -ENOMEM; + pr_err("No memory for allocating CRAT image\n"); + goto err; + } + ret = kfd_topology_get_crat_acpi(crat_image, &image_size); + + if (ret == 0) { + down_write(&topology_lock); + ret = kfd_parse_crat_table(crat_image); + if (ret == 0) + ret = kfd_topology_update_sysfs(); + up_write(&topology_lock); + } else { + pr_err("Couldn't get CRAT table size from ACPI\n"); + } + kfree(crat_image); + } else if (ret == -ENODATA) { + ret = 0; + } else { + pr_err("Couldn't get CRAT table size from ACPI\n"); + } + +err: + pr_info("Finished initializing topology ret=%d\n", ret); + return ret; +} + +void kfd_topology_shutdown(void) +{ + kfd_topology_release_sysfs(); + kfd_release_live_view(); +} + +static void kfd_debug_print_topology(void) +{ + struct kfd_topology_device *dev; + uint32_t i = 0; + + pr_info("DEBUG PRINT OF TOPOLOGY:"); + list_for_each_entry(dev, &topology_device_list, list) { + pr_info("Node: %d\n", i); + pr_info("\tGPU assigned: %s\n", (dev->gpu ? "yes" : "no")); + pr_info("\tCPU count: %d\n", dev->node_props.cpu_cores_count); + pr_info("\tSIMD count: %d", dev->node_props.simd_count); + i++; + } +} + +static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) +{ + uint32_t hashout; + uint32_t buf[7]; + int i; + + if (!gpu) + return 0; + + buf[0] = gpu->pdev->devfn; + buf[1] = gpu->pdev->subsystem_vendor; + buf[2] = gpu->pdev->subsystem_device; + buf[3] = gpu->pdev->device; + buf[4] = gpu->pdev->bus->number; + buf[5] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) & 0xffffffff); + buf[6] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) >> 32); + + for (i = 0, hashout = 0; i < 7; i++) + hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH); + + return hashout; +} + +static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu) +{ + struct kfd_topology_device *dev; + struct kfd_topology_device *out_dev = 0; + + BUG_ON(!gpu); + + list_for_each_entry(dev, &topology_device_list, list) + if (dev->gpu == 0 && dev->node_props.simd_count > 0) { + dev->gpu = gpu; + out_dev = dev; + break; + } + + return out_dev; +} + +static void kfd_notify_gpu_change(uint32_t gpu_id, int arrival) +{ + /* + * TODO: Generate an event for thunk about the arrival/removal + * of the GPU + */ +} + +int kfd_topology_add_device(struct kfd_dev *gpu) +{ + uint32_t gpu_id; + struct kfd_topology_device *dev; + int res; + + BUG_ON(!gpu); + + gpu_id = kfd_generate_gpu_id(gpu); + + pr_debug("kfd: Adding new GPU (ID: 0x%x) to topology\n", gpu_id); + + down_write(&topology_lock); + /* + * Try to assign the GPU to existing topology device (generated from + * CRAT table + */ + dev = kfd_assign_gpu(gpu); + if (!dev) { + pr_info("GPU was not found in the current topology. Extending.\n"); + kfd_debug_print_topology(); + dev = kfd_create_topology_device(); + if (!dev) { + res = -ENOMEM; + goto err; + } + dev->gpu = gpu; + + /* + * TODO: Make a call to retrieve topology information from the + * GPU vBIOS + */ + + /* + * Update the SYSFS tree, since we added another topology device + */ + if (kfd_topology_update_sysfs() < 0) + kfd_topology_release_sysfs(); + + } + + dev->gpu_id = gpu_id; + gpu->id = gpu_id; + dev->node_props.vendor_id = gpu->pdev->vendor; + dev->node_props.device_id = gpu->pdev->device; + dev->node_props.location_id = (gpu->pdev->bus->number << 24) + + (gpu->pdev->devfn & 0xffffff); + /* + * TODO: Retrieve max engine clock values from KGD + */ + + res = 0; + +err: + up_write(&topology_lock); + + if (res == 0) + kfd_notify_gpu_change(gpu_id, 1); + + return res; +} + +int kfd_topology_remove_device(struct kfd_dev *gpu) +{ + struct kfd_topology_device *dev; + uint32_t gpu_id; + int res = -ENODEV; + + BUG_ON(!gpu); + + down_write(&topology_lock); + + list_for_each_entry(dev, &topology_device_list, list) + if (dev->gpu == gpu) { + gpu_id = dev->gpu_id; + kfd_remove_sysfs_node_entry(dev); + kfd_release_topology_device(dev); + res = 0; + if (kfd_topology_update_sysfs() < 0) + kfd_topology_release_sysfs(); + break; + } + + up_write(&topology_lock); + + if (res == 0) + kfd_notify_gpu_change(gpu_id, 0); + + return res; +} + +/* + * When idx is out of bounds, the function will return NULL + */ +struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx) +{ + + struct kfd_topology_device *top_dev; + struct kfd_dev *device = NULL; + uint8_t device_idx = 0; + + down_read(&topology_lock); + + list_for_each_entry(top_dev, &topology_device_list, list) { + if (device_idx == idx) { + device = top_dev->gpu; + break; + } + + device_idx++; + } + + up_read(&topology_lock); + + return device; + +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h new file mode 100644 index 000000000000..989624b3cd14 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h @@ -0,0 +1,168 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __KFD_TOPOLOGY_H__ +#define __KFD_TOPOLOGY_H__ + +#include +#include +#include "kfd_priv.h" + +#define KFD_TOPOLOGY_PUBLIC_NAME_SIZE 128 + +#define HSA_CAP_HOT_PLUGGABLE 0x00000001 +#define HSA_CAP_ATS_PRESENT 0x00000002 +#define HSA_CAP_SHARED_WITH_GRAPHICS 0x00000004 +#define HSA_CAP_QUEUE_SIZE_POW2 0x00000008 +#define HSA_CAP_QUEUE_SIZE_32BIT 0x00000010 +#define HSA_CAP_QUEUE_IDLE_EVENT 0x00000020 +#define HSA_CAP_VA_LIMIT 0x00000040 +#define HSA_CAP_WATCH_POINTS_SUPPORTED 0x00000080 +#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK 0x00000f00 +#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8 +#define HSA_CAP_RESERVED 0xfffff000 + +struct kfd_node_properties { + uint32_t cpu_cores_count; + uint32_t simd_count; + uint32_t mem_banks_count; + uint32_t caches_count; + uint32_t io_links_count; + uint32_t cpu_core_id_base; + uint32_t simd_id_base; + uint32_t capability; + uint32_t max_waves_per_simd; + uint32_t lds_size_in_kb; + uint32_t gds_size_in_kb; + uint32_t wave_front_size; + uint32_t array_count; + uint32_t simd_arrays_per_engine; + uint32_t cu_per_simd_array; + uint32_t simd_per_cu; + uint32_t max_slots_scratch_cu; + uint32_t engine_id; + uint32_t vendor_id; + uint32_t device_id; + uint32_t location_id; + uint32_t max_engine_clk_fcompute; + uint32_t max_engine_clk_ccompute; + uint16_t marketing_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE]; +}; + +#define HSA_MEM_HEAP_TYPE_SYSTEM 0 +#define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1 +#define HSA_MEM_HEAP_TYPE_FB_PRIVATE 2 +#define HSA_MEM_HEAP_TYPE_GPU_GDS 3 +#define HSA_MEM_HEAP_TYPE_GPU_LDS 4 +#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH 5 + +#define HSA_MEM_FLAGS_HOT_PLUGGABLE 0x00000001 +#define HSA_MEM_FLAGS_NON_VOLATILE 0x00000002 +#define HSA_MEM_FLAGS_RESERVED 0xfffffffc + +struct kfd_mem_properties { + struct list_head list; + uint32_t heap_type; + uint64_t size_in_bytes; + uint32_t flags; + uint32_t width; + uint32_t mem_clk_max; + struct kobject *kobj; + struct attribute attr; +}; + +#define KFD_TOPOLOGY_CPU_SIBLINGS 256 + +#define HSA_CACHE_TYPE_DATA 0x00000001 +#define HSA_CACHE_TYPE_INSTRUCTION 0x00000002 +#define HSA_CACHE_TYPE_CPU 0x00000004 +#define HSA_CACHE_TYPE_HSACU 0x00000008 +#define HSA_CACHE_TYPE_RESERVED 0xfffffff0 + +struct kfd_cache_properties { + struct list_head list; + uint32_t processor_id_low; + uint32_t cache_level; + uint32_t cache_size; + uint32_t cacheline_size; + uint32_t cachelines_per_tag; + uint32_t cache_assoc; + uint32_t cache_latency; + uint32_t cache_type; + uint8_t sibling_map[KFD_TOPOLOGY_CPU_SIBLINGS]; + struct kobject *kobj; + struct attribute attr; +}; + +struct kfd_iolink_properties { + struct list_head list; + uint32_t iolink_type; + uint32_t ver_maj; + uint32_t ver_min; + uint32_t node_from; + uint32_t node_to; + uint32_t weight; + uint32_t min_latency; + uint32_t max_latency; + uint32_t min_bandwidth; + uint32_t max_bandwidth; + uint32_t rec_transfer_size; + uint32_t flags; + struct kobject *kobj; + struct attribute attr; +}; + +struct kfd_topology_device { + struct list_head list; + uint32_t gpu_id; + struct kfd_node_properties node_props; + uint32_t mem_bank_count; + struct list_head mem_props; + uint32_t cache_count; + struct list_head cache_props; + uint32_t io_link_count; + struct list_head io_link_props; + struct kfd_dev *gpu; + struct kobject *kobj_node; + struct kobject *kobj_mem; + struct kobject *kobj_cache; + struct kobject *kobj_iolink; + struct attribute attr_gpuid; + struct attribute attr_name; + struct attribute attr_props; +}; + +struct kfd_system_properties { + uint32_t num_devices; /* Number of H-NUMA nodes */ + uint32_t generation_count; + uint64_t platform_oem; + uint64_t platform_id; + uint64_t platform_rev; + struct kobject *kobj_topology; + struct kobject *kobj_nodes; + struct attribute attr_genid; + struct attribute attr_props; +}; + + + +#endif /* __KFD_TOPOLOGY_H__ */ -- GitLab From 19f6d2a660340d01bcdb7a09557efeeee28d1517 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Wed, 16 Jul 2014 23:25:31 +0300 Subject: [PATCH 0015/9457] amdkfd: Add basic modules to amdkfd This patch adds the process module and three helper modules: - kfd_process, which handles process which open /dev/kfd - kfd_doorbell, which provides helper functions for doorbell allocation, release and mapping to userspace - kfd_pasid, which provides helper functions for pasid allocation and release - kfd_aperture, which provides helper functions for managing the LDS, Local GPU memory and Scratch memory apertures of the process This patch only contains the basic kfd_process module, which doesn't contain the reference to the queue scheduler. This was done to allow easier code review. Also, this patch doesn't contain the calls to the IOMMU driver for binding the pasid to the device. Again, this was done to allow easier code review The kfd_process object is created when a process opens /dev/kfd and is closed when the mm_struct of that process is teared-down. v3: Removed kfd_vidmem.c file Replaced direct mmput call to mmu_notifier release Removed typedefs Moved bool field to end of the structure Added new kernel params for gart usage limitation Added initialization of sa manager Fixed debug messages Remove support for LDS in 32 bit Changed code to support mmap of doorbell pages from userspace Added documentation for apertures v4: Replaced RCU by SRCU for kfd_process list management v5: Move amdkfd from drm/radeon/ to drm/amd/ Rename kfd_aperture.c to kfd_flat_memory.c Protect against multiple init calls MQD size is H/W dependent so moved it to device info structure Rename kfd_mem_obj structure's members Use delayed function for process tear-down Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 4 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 31 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 46 ++- drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 255 ++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c | 355 +++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_module.c | 41 +- drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | 97 +++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 147 +++++++ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 383 +++++++++++++++++++ 9 files changed, 1349 insertions(+), 10 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_pasid.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_process.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 978654f56b4f..e829a3fa7d8e 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -4,6 +4,8 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ -amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o +amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ + kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ + kfd_process.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index d7c32eb7d16a..58441cd1b1d2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -38,6 +38,7 @@ static long kfd_ioctl(struct file *, unsigned int, unsigned long); static int kfd_open(struct inode *, struct file *); +static int kfd_mmap(struct file *, struct vm_area_struct *); static const char kfd_dev_name[] = "kfd"; @@ -46,6 +47,7 @@ static const struct file_operations kfd_fops = { .unlocked_ioctl = kfd_ioctl, .compat_ioctl = kfd_ioctl, .open = kfd_open, + .mmap = kfd_mmap, }; static int kfd_char_dev_major = -1; @@ -98,9 +100,22 @@ struct device *kfd_chardev(void) static int kfd_open(struct inode *inode, struct file *filep) { + struct kfd_process *process; + if (iminor(inode) != 0) return -ENODEV; + process = kfd_create_process(current); + if (IS_ERR(process)) + return PTR_ERR(process); + + process->is_32bit_user_mode = is_compat_task(); + + dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n", + process->pasid, process->is_32bit_user_mode); + + kfd_init_apertures(process); + return 0; } @@ -156,8 +171,9 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, _IOC_NR(cmd), arg); - /* TODO: add function that retrieves process */ - process = NULL; + process = kfd_get_process(current); + if (IS_ERR(process)) + return PTR_ERR(process); switch (cmd) { case KFD_IOC_GET_VERSION: @@ -208,3 +224,14 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return err; } + +static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct kfd_process *process; + + process = kfd_get_process(current); + if (IS_ERR(process)) + return PTR_ERR(process); + + return kfd_doorbell_mmap(process, vma); +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 53b2e19cabe0..71a03f7b0049 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -26,8 +26,11 @@ #include #include "kfd_priv.h" +#define MQD_SIZE_ALIGNED 768 + static const struct kfd_device_info kaveri_device_info = { .max_pasid_bits = 16, + .mqd_size_aligned = MQD_SIZE_ALIGNED }; struct kfd_deviceid { @@ -92,6 +95,7 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) kfd->kgd = kgd; kfd->device_info = device_info; kfd->pdev = pdev; + kfd->init_complete = false; return kfd; } @@ -99,23 +103,53 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) bool kgd2kfd_device_init(struct kfd_dev *kfd, const struct kgd2kfd_shared_resources *gpu_resources) { + unsigned int size; + kfd->shared_resources = *gpu_resources; - if (kfd_topology_add_device(kfd) != 0) - return false; + /* calculate max size of mqds needed for queues */ + size = max_num_of_processes * + max_num_of_queues_per_process * + kfd->device_info->mqd_size_aligned; + + /* add another 512KB for all other allocations on gart */ + size += 512 * 1024; + + if (kfd2kgd->init_sa_manager(kfd->kgd, size)) { + dev_err(kfd_device, + "Error initializing sa manager for device (%x:%x)\n", + kfd->pdev->vendor, kfd->pdev->device); + goto out; + } + + kfd_doorbell_init(kfd); + + if (kfd_topology_add_device(kfd) != 0) { + dev_err(kfd_device, + "Error adding device (%x:%x) to topology\n", + kfd->pdev->vendor, kfd->pdev->device); + goto kfd_topology_add_device_error; + } + kfd->init_complete = true; dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor, kfd->pdev->device); - return true; + goto out; + +kfd_topology_add_device_error: + kfd2kgd->fini_sa_manager(kfd->kgd); + dev_err(kfd_device, + "device (%x:%x) NOT added due to errors\n", + kfd->pdev->vendor, kfd->pdev->device); +out: + return kfd->init_complete; } void kgd2kfd_device_exit(struct kfd_dev *kfd) { - int err = kfd_topology_remove_device(kfd); - - BUG_ON(err != 0); + kfd_topology_remove_device(kfd); kfree(kfd); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c new file mode 100644 index 000000000000..0dcb78755686 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c @@ -0,0 +1,255 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "kfd_priv.h" +#include +#include +#include + +/* + * This extension supports a kernel level doorbells management for + * the kernel queues. + * Basically the last doorbells page is devoted to kernel queues + * and that's assures that any user process won't get access to the + * kernel doorbells page + */ +static DEFINE_MUTEX(doorbell_mutex); +static unsigned long doorbell_available_index[ + DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)] = { 0 }; + +#define KERNEL_DOORBELL_PASID 1 +#define KFD_SIZE_OF_DOORBELL_IN_BYTES 4 + +/* + * Each device exposes a doorbell aperture, a PCI MMIO aperture that + * receives 32-bit writes that are passed to queues as wptr values. + * The doorbells are intended to be written by applications as part + * of queueing work on user-mode queues. + * We assign doorbells to applications in PAGE_SIZE-sized and aligned chunks. + * We map the doorbell address space into user-mode when a process creates + * its first queue on each device. + * Although the mapping is done by KFD, it is equivalent to an mmap of + * the /dev/kfd with the particular device encoded in the mmap offset. + * There will be other uses for mmap of /dev/kfd, so only a range of + * offsets (KFD_MMAP_DOORBELL_START-END) is used for doorbells. + */ + +/* # of doorbell bytes allocated for each process. */ +static inline size_t doorbell_process_allocation(void) +{ + return roundup(KFD_SIZE_OF_DOORBELL_IN_BYTES * + KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, + PAGE_SIZE); +} + +/* Doorbell calculations for device init. */ +void kfd_doorbell_init(struct kfd_dev *kfd) +{ + size_t doorbell_start_offset; + size_t doorbell_aperture_size; + size_t doorbell_process_limit; + + /* + * We start with calculations in bytes because the input data might + * only be byte-aligned. + * Only after we have done the rounding can we assume any alignment. + */ + + doorbell_start_offset = + roundup(kfd->shared_resources.doorbell_start_offset, + doorbell_process_allocation()); + + doorbell_aperture_size = + rounddown(kfd->shared_resources.doorbell_aperture_size, + doorbell_process_allocation()); + + if (doorbell_aperture_size > doorbell_start_offset) + doorbell_process_limit = + (doorbell_aperture_size - doorbell_start_offset) / + doorbell_process_allocation(); + else + doorbell_process_limit = 0; + + kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address + + doorbell_start_offset; + + kfd->doorbell_id_offset = doorbell_start_offset / sizeof(u32); + kfd->doorbell_process_limit = doorbell_process_limit - 1; + + kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base, + doorbell_process_allocation()); + + BUG_ON(!kfd->doorbell_kernel_ptr); + + pr_debug("kfd: doorbell initialization:\n"); + pr_debug("kfd: doorbell base == 0x%08lX\n", + (uintptr_t)kfd->doorbell_base); + + pr_debug("kfd: doorbell_id_offset == 0x%08lX\n", + kfd->doorbell_id_offset); + + pr_debug("kfd: doorbell_process_limit == 0x%08lX\n", + doorbell_process_limit); + + pr_debug("kfd: doorbell_kernel_offset == 0x%08lX\n", + (uintptr_t)kfd->doorbell_base); + + pr_debug("kfd: doorbell aperture size == 0x%08lX\n", + kfd->shared_resources.doorbell_aperture_size); + + pr_debug("kfd: doorbell kernel address == 0x%08lX\n", + (uintptr_t)kfd->doorbell_kernel_ptr); +} + +int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma) +{ + phys_addr_t address; + struct kfd_dev *dev; + + /* + * For simplicitly we only allow mapping of the entire doorbell + * allocation of a single device & process. + */ + if (vma->vm_end - vma->vm_start != doorbell_process_allocation()) + return -EINVAL; + + /* Find kfd device according to gpu id */ + dev = kfd_device_by_id(vma->vm_pgoff); + if (dev == NULL) + return -EINVAL; + + /* Find if pdd exists for combination of process and gpu id */ + if (!kfd_get_process_device_data(dev, process, 0)) + return -EINVAL; + + /* Calculate physical address of doorbell */ + address = kfd_get_process_doorbells(dev, process); + + vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | + VM_DONTDUMP | VM_PFNMAP; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + pr_debug("kfd: mapping doorbell page in kfd_doorbell_mmap\n" + " target user address == 0x%08llX\n" + " physical address == 0x%08llX\n" + " vm_flags == 0x%04lX\n" + " size == 0x%04lX\n", + (unsigned long long) vma->vm_start, address, vma->vm_flags, + doorbell_process_allocation()); + + + return io_remap_pfn_range(vma, + vma->vm_start, + address >> PAGE_SHIFT, + doorbell_process_allocation(), + vma->vm_page_prot); +} + + +/* get kernel iomem pointer for a doorbell */ +u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, + unsigned int *doorbell_off) +{ + u32 inx; + + BUG_ON(!kfd || !doorbell_off); + + mutex_lock(&doorbell_mutex); + inx = find_first_zero_bit(doorbell_available_index, + KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); + + __set_bit(inx, doorbell_available_index); + mutex_unlock(&doorbell_mutex); + + if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) + return NULL; + + /* + * Calculating the kernel doorbell offset using "faked" kernel + * pasid that allocated for kernel queues only + */ + *doorbell_off = KERNEL_DOORBELL_PASID * (doorbell_process_allocation() / + sizeof(u32)) + inx; + + pr_debug("kfd: get kernel queue doorbell\n" + " doorbell offset == 0x%08d\n" + " kernel address == 0x%08lX\n", + *doorbell_off, (uintptr_t)(kfd->doorbell_kernel_ptr + inx)); + + return kfd->doorbell_kernel_ptr + inx; +} + +void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr) +{ + unsigned int inx; + + BUG_ON(!kfd || !db_addr); + + inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr); + + mutex_lock(&doorbell_mutex); + __clear_bit(inx, doorbell_available_index); + mutex_unlock(&doorbell_mutex); +} + +inline void write_kernel_doorbell(u32 __iomem *db, u32 value) +{ + if (db) { + writel(value, db); + pr_debug("writing %d to doorbell address 0x%p\n", value, db); + } +} + +/* + * queue_ids are in the range [0,MAX_PROCESS_QUEUES) and are mapped 1:1 + * to doorbells with the process's doorbell page + */ +unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd, + struct kfd_process *process, + unsigned int queue_id) +{ + /* + * doorbell_id_offset accounts for doorbells taken by KGD. + * pasid * doorbell_process_allocation/sizeof(u32) adjusts + * to the process's doorbells + */ + return kfd->doorbell_id_offset + + process->pasid * (doorbell_process_allocation()/sizeof(u32)) + + queue_id; +} + +uint64_t kfd_get_number_elems(struct kfd_dev *kfd) +{ + uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size - + kfd->shared_resources.doorbell_start_offset) / + doorbell_process_allocation() + 1; + + return num_of_elems; + +} + +phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, + struct kfd_process *process) +{ + return dev->doorbell_base + + process->pasid * doorbell_process_allocation(); +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c new file mode 100644 index 000000000000..2dfc4c0e85a4 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c @@ -0,0 +1,355 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kfd_priv.h" +#include +#include +#include + +/* + * The primary memory I/O features being added for revisions of gfxip + * beyond 7.0 (Kaveri) are: + * + * Access to ATC/IOMMU mapped memory w/ associated extension of VA to 48b + * + * “Flat” shader memory access – These are new shader vector memory + * operations that do not reference a T#/V# so a “pointer” is what is + * sourced from the vector gprs for direct access to memory. + * This pointer space has the Shared(LDS) and Private(Scratch) memory + * mapped into this pointer space as apertures. + * The hardware then determines how to direct the memory request + * based on what apertures the request falls in. + * + * Unaligned support and alignment check + * + * + * System Unified Address - SUA + * + * The standard usage for GPU virtual addresses are that they are mapped by + * a set of page tables we call GPUVM and these page tables are managed by + * a combination of vidMM/driver software components. The current virtual + * address (VA) range for GPUVM is 40b. + * + * As of gfxip7.1 and beyond we’re adding the ability for compute memory + * clients (CP/RLC, DMA, SHADER(ifetch, scalar, and vector ops)) to access + * the same page tables used by host x86 processors and that are managed by + * the operating system. This is via a technique and hardware called ATC/IOMMU. + * The GPU has the capability of accessing both the GPUVM and ATC address + * spaces for a given VMID (process) simultaneously and we call this feature + * system unified address (SUA). + * + * There are three fundamental address modes of operation for a given VMID + * (process) on the GPU: + * + * HSA64 – 64b pointers and the default address space is ATC + * HSA32 – 32b pointers and the default address space is ATC + * GPUVM – 64b pointers and the default address space is GPUVM (driver + * model mode) + * + * + * HSA64 - ATC/IOMMU 64b + * + * A 64b pointer in the AMD64/IA64 CPU architecture is not fully utilized + * by the CPU so an AMD CPU can only access the high area + * (VA[63:47] == 0x1FFFF) and low area (VA[63:47 == 0) of the address space + * so the actual VA carried to translation is 48b. There is a “hole” in + * the middle of the 64b VA space. + * + * The GPU not only has access to all of the CPU accessible address space via + * ATC/IOMMU, but it also has access to the GPUVM address space. The “system + * unified address” feature (SUA) is the mapping of GPUVM and ATC address + * spaces into a unified pointer space. The method we take for 64b mode is + * to map the full 40b GPUVM address space into the hole of the 64b address + * space. + + * The GPUVM_Base/GPUVM_Limit defines the aperture in the 64b space where we + * direct requests to be translated via GPUVM page tables instead of the + * IOMMU path. + * + * + * 64b to 49b Address conversion + * + * Note that there are still significant portions of unused regions (holes) + * in the 64b address space even for the GPU. There are several places in + * the pipeline (sw and hw), we wish to compress the 64b virtual address + * to a 49b address. This 49b address is constituted of an “ATC” bit + * plus a 48b virtual address. This 49b address is what is passed to the + * translation hardware. ATC==0 means the 48b address is a GPUVM address + * (max of 2^40 – 1) intended to be translated via GPUVM page tables. + * ATC==1 means the 48b address is intended to be translated via IOMMU + * page tables. + * + * A 64b pointer is compared to the apertures that are defined (Base/Limit), in + * this case the GPUVM aperture (red) is defined and if a pointer falls in this + * aperture, we subtract the GPUVM_Base address and set the ATC bit to zero + * as part of the 64b to 49b conversion. + * + * Where this 64b to 49b conversion is done is a function of the usage. + * Most GPU memory access is via memory objects where the driver builds + * a descriptor which consists of a base address and a memory access by + * the GPU usually consists of some kind of an offset or Cartesian coordinate + * that references this memory descriptor. This is the case for shader + * instructions that reference the T# or V# constants, or for specified + * locations of assets (ex. the shader program location). In these cases + * the driver is what handles the 64b to 49b conversion and the base + * address in the descriptor (ex. V# or T# or shader program location) + * is defined as a 48b address w/ an ATC bit. For this usage a given + * memory object cannot straddle multiple apertures in the 64b address + * space. For example a shader program cannot jump in/out between ATC + * and GPUVM space. + * + * In some cases we wish to pass a 64b pointer to the GPU hardware and + * the GPU hw does the 64b to 49b conversion before passing memory + * requests to the cache/memory system. This is the case for the + * S_LOAD and FLAT_* shader memory instructions where we have 64b pointers + * in scalar and vector GPRs respectively. + * + * In all cases (no matter where the 64b -> 49b conversion is done), the gfxip + * hardware sends a 48b address along w/ an ATC bit, to the memory controller + * on the memory request interfaces. + * + * _MC_rdreq_atc // read request ATC bit + * + * 0 : _MC_rdreq_addr is a GPUVM VA + * + * 1 : _MC_rdreq_addr is a ATC VA + * + * + * “Spare” aperture (APE1) + * + * We use the GPUVM aperture to differentiate ATC vs. GPUVM, but we also use + * apertures to set the Mtype field for S_LOAD/FLAT_* ops which is input to the + * config tables for setting cache policies. The “spare” (APE1) aperture is + * motivated by getting a different Mtype from the default. + * The default aperture isn’t an actual base/limit aperture; it is just the + * address space that doesn’t hit any defined base/limit apertures. + * The following diagram is a complete picture of the gfxip7.x SUA apertures. + * The APE1 can be placed either below or above + * the hole (cannot be in the hole). + * + * + * General Aperture definitions and rules + * + * An aperture register definition consists of a Base, Limit, Mtype, and + * usually an ATC bit indicating which translation tables that aperture uses. + * In all cases (for SUA and DUA apertures discussed later), aperture base + * and limit definitions are 64KB aligned. + * + * _Base[63:0] = { _Base_register[63:16], 0x0000 } + * + * _Limit[63:0] = { _Limit_register[63:16], 0xFFFF } + * + * The base and limit are considered inclusive to an aperture so being + * inside an aperture means (address >= Base) AND (address <= Limit). + * + * In no case is a payload that straddles multiple apertures expected to work. + * For example a load_dword_x4 that starts in one aperture and ends in another, + * does not work. For the vector FLAT_* ops we have detection capability in + * the shader for reporting a “memory violation” back to the + * SQ block for use in traps. + * A memory violation results when an op falls into the hole, + * or a payload straddles multiple apertures. The S_LOAD instruction + * does not have this detection. + * + * Apertures cannot overlap. + * + * + * + * HSA32 - ATC/IOMMU 32b + * + * For HSA32 mode, the pointers are interpreted as 32 bits and use a single GPR + * instead of two for the S_LOAD and FLAT_* ops. The entire GPUVM space of 40b + * will not fit so there is only partial visibility to the GPUVM + * space (defined by the aperture) for S_LOAD and FLAT_* ops. + * There is no spare (APE1) aperture for HSA32 mode. + * + * + * GPUVM 64b mode (driver model) + * + * This mode is related to HSA64 in that the difference really is that + * the default aperture is GPUVM (ATC==0) and not ATC space. + * We have gfxip7.x hardware that has FLAT_* and S_LOAD support for + * SUA GPUVM mode, but does not support HSA32/HSA64. + * + * + * Device Unified Address - DUA + * + * Device unified address (DUA) is the name of the feature that maps the + * Shared(LDS) memory and Private(Scratch) memory into the overall address + * space for use by the new FLAT_* vector memory ops. The Shared and + * Private memories are mapped as apertures into the address space, + * and the hardware detects when a FLAT_* memory request is to be redirected + * to the LDS or Scratch memory when it falls into one of these apertures. + * Like the SUA apertures, the Shared/Private apertures are 64KB aligned and + * the base/limit is “in” the aperture. For both HSA64 and GPUVM SUA modes, + * the Shared/Private apertures are always placed in a limited selection of + * options in the hole of the 64b address space. For HSA32 mode, the + * Shared/Private apertures can be placed anywhere in the 32b space + * except at 0. + * + * + * HSA64 Apertures for FLAT_* vector ops + * + * For HSA64 SUA mode, the Shared and Private apertures are always placed + * in the hole w/ a limited selection of possible locations. The requests + * that fall in the private aperture are expanded as a function of the + * work-item id (tid) and redirected to the location of the + * “hidden private memory”. The hidden private can be placed in either GPUVM + * or ATC space. The addresses that fall in the shared aperture are + * re-directed to the on-chip LDS memory hardware. + * + * + * HSA32 Apertures for FLAT_* vector ops + * + * In HSA32 mode, the Private and Shared apertures can be placed anywhere + * in the 32b space except at 0 (Private or Shared Base at zero disables + * the apertures). If the base address of the apertures are non-zero + * (ie apertures exists), the size is always 64KB. + * + * + * GPUVM Apertures for FLAT_* vector ops + * + * In GPUVM mode, the Shared/Private apertures are specified identically + * to HSA64 mode where they are always in the hole at a limited selection + * of locations. + * + * + * Aperture Definitions for SUA and DUA + * + * The interpretation of the aperture register definitions for a given + * VMID is a function of the “SUA Mode” which is one of HSA64, HSA32, or + * GPUVM64 discussed in previous sections. The mode is first decoded, and + * then the remaining register decode is a function of the mode. + * + * + * SUA Mode Decode + * + * For the S_LOAD and FLAT_* shader operations, the SUA mode is decoded from + * the COMPUTE_DISPATCH_INITIATOR:DATA_ATC bit and + * the SH_MEM_CONFIG:PTR32 bits. + * + * COMPUTE_DISPATCH_INITIATOR:DATA_ATC SH_MEM_CONFIG:PTR32 Mode + * + * 1 0 HSA64 + * + * 1 1 HSA32 + * + * 0 X GPUVM64 + * + * In general the hardware will ignore the PTR32 bit and treat + * as “0” whenever DATA_ATC = “0”, but sw should set PTR32=0 + * when DATA_ATC=0. + * + * The DATA_ATC bit is only set for compute dispatches. + * All “Draw” dispatches are hardcoded to GPUVM64 mode + * for FLAT_* / S_LOAD operations. + */ + +#define MAKE_GPUVM_APP_BASE(gpu_num) \ + (((uint64_t)(gpu_num) << 61) + 0x1000000000000) + +#define MAKE_GPUVM_APP_LIMIT(base) \ + (((uint64_t)(base) & 0xFFFFFF0000000000) | 0xFFFFFFFFFF) + +#define MAKE_SCRATCH_APP_BASE(gpu_num) \ + (((uint64_t)(gpu_num) << 61) + 0x100000000) + +#define MAKE_SCRATCH_APP_LIMIT(base) \ + (((uint64_t)base & 0xFFFFFFFF00000000) | 0xFFFFFFFF) + +#define MAKE_LDS_APP_BASE(gpu_num) \ + (((uint64_t)(gpu_num) << 61) + 0x0) +#define MAKE_LDS_APP_LIMIT(base) \ + (((uint64_t)(base) & 0xFFFFFFFF00000000) | 0xFFFFFFFF) + +int kfd_init_apertures(struct kfd_process *process) +{ + uint8_t id = 0; + struct kfd_dev *dev; + struct kfd_process_device *pdd; + + mutex_lock(&process->mutex); + + /*Iterating over all devices*/ + while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL && + id < NUM_OF_SUPPORTED_GPUS) { + + pdd = kfd_get_process_device_data(dev, process, 1); + + /* + * For 64 bit process aperture will be statically reserved in + * the x86_64 non canonical process address space + * amdkfd doesn't currently support apertures for 32 bit process + */ + if (process->is_32bit_user_mode) { + pdd->lds_base = pdd->lds_limit = 0; + pdd->gpuvm_base = pdd->gpuvm_limit = 0; + pdd->scratch_base = pdd->scratch_limit = 0; + } else { + /* + * node id couldn't be 0 - the three MSB bits of + * aperture shoudn't be 0 + */ + pdd->lds_base = MAKE_LDS_APP_BASE(id + 1); + + pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base); + + pdd->gpuvm_base = MAKE_GPUVM_APP_BASE(id + 1); + + pdd->gpuvm_limit = + MAKE_GPUVM_APP_LIMIT(pdd->gpuvm_base); + + pdd->scratch_base = MAKE_SCRATCH_APP_BASE(id + 1); + + pdd->scratch_limit = + MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base); + } + + dev_dbg(kfd_device, "node id %u\n", id); + dev_dbg(kfd_device, "gpu id %u\n", pdd->dev->id); + dev_dbg(kfd_device, "lds_base %llX\n", pdd->lds_base); + dev_dbg(kfd_device, "lds_limit %llX\n", pdd->lds_limit); + dev_dbg(kfd_device, "gpuvm_base %llX\n", pdd->gpuvm_base); + dev_dbg(kfd_device, "gpuvm_limit %llX\n", pdd->gpuvm_limit); + dev_dbg(kfd_device, "scratch_base %llX\n", pdd->scratch_base); + dev_dbg(kfd_device, "scratch_limit %llX\n", pdd->scratch_limit); + + id++; + } + + mutex_unlock(&process->mutex); + + return 0; +} + + diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index 45654be039ff..a05116b0a07d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include "kfd_priv.h" @@ -46,6 +45,16 @@ static const struct kgd2kfd_calls kgd2kfd = { .resume = kgd2kfd_resume, }; +int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT; +module_param(max_num_of_processes, int, 0444); +MODULE_PARM_DESC(max_num_of_processes, + "Kernel cmdline parameter that defines the amdkfd maximum number of supported processes"); + +int max_num_of_queues_per_process = KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT; +module_param(max_num_of_queues_per_process, int, 0444); +MODULE_PARM_DESC(max_num_of_queues_per_process, + "Kernel cmdline parameter that defines the amdkfd maximum number of supported queues per process"); + bool kgd2kfd_init(unsigned interface_version, const struct kfd2kgd_calls *f2g, const struct kgd2kfd_calls **g2f) @@ -57,6 +66,10 @@ bool kgd2kfd_init(unsigned interface_version, if (interface_version != KFD_INTERFACE_VERSION) return false; + /* Protection against multiple amd kgd loads */ + if (kfd2kgd) + return true; + kfd2kgd = f2g; *g2f = &kgd2kfd; @@ -72,6 +85,26 @@ static int __init kfd_module_init(void) { int err; + kfd2kgd = NULL; + + /* Verify module parameters */ + if ((max_num_of_processes < 0) || + (max_num_of_processes > KFD_MAX_NUM_OF_PROCESSES)) { + pr_err("kfd: max_num_of_processes must be between 0 to KFD_MAX_NUM_OF_PROCESSES\n"); + return -1; + } + + if ((max_num_of_queues_per_process < 0) || + (max_num_of_queues_per_process > + KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)) { + pr_err("kfd: max_num_of_queues_per_process must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_PROCESS\n"); + return -1; + } + + err = kfd_pasid_init(); + if (err < 0) + goto err_pasid; + err = kfd_chardev_init(); if (err < 0) goto err_ioctl; @@ -80,6 +113,8 @@ static int __init kfd_module_init(void) if (err < 0) goto err_topology; + kfd_process_create_wq(); + dev_info(kfd_device, "Initialized module\n"); return 0; @@ -87,13 +122,17 @@ static int __init kfd_module_init(void) err_topology: kfd_chardev_exit(); err_ioctl: + kfd_pasid_exit(); +err_pasid: return err; } static void __exit kfd_module_exit(void) { + kfd_process_destroy_wq(); kfd_topology_shutdown(); kfd_chardev_exit(); + kfd_pasid_exit(); dev_info(kfd_device, "Removed module\n"); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c new file mode 100644 index 000000000000..2458ab7c0c6e --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c @@ -0,0 +1,97 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "kfd_priv.h" + +static unsigned long *pasid_bitmap; +static unsigned int pasid_limit; +static DEFINE_MUTEX(pasid_mutex); + +int kfd_pasid_init(void) +{ + pasid_limit = max_num_of_processes; + + pasid_bitmap = kzalloc(DIV_ROUND_UP(pasid_limit, BITS_PER_BYTE), + GFP_KERNEL); + if (!pasid_bitmap) + return -ENOMEM; + + set_bit(0, pasid_bitmap); /* PASID 0 is reserved. */ + + return 0; +} + +void kfd_pasid_exit(void) +{ + kfree(pasid_bitmap); +} + +bool kfd_set_pasid_limit(unsigned int new_limit) +{ + if (new_limit < pasid_limit) { + bool ok; + + mutex_lock(&pasid_mutex); + + /* ensure that no pasids >= new_limit are in-use */ + ok = (find_next_bit(pasid_bitmap, pasid_limit, new_limit) == + pasid_limit); + if (ok) + pasid_limit = new_limit; + + mutex_unlock(&pasid_mutex); + + return ok; + } + + return true; +} + +inline unsigned int kfd_get_pasid_limit(void) +{ + return pasid_limit; +} + +unsigned int kfd_pasid_alloc(void) +{ + unsigned int found; + + mutex_lock(&pasid_mutex); + + found = find_first_zero_bit(pasid_bitmap, pasid_limit); + if (found == pasid_limit) + found = 0; + else + set_bit(found, pasid_bitmap); + + mutex_unlock(&pasid_mutex); + + return found; +} + +void kfd_pasid_free(unsigned int pasid) +{ + BUG_ON(pasid == 0 || pasid >= pasid_limit); + clear_bit(pasid, pasid_bitmap); +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index b58b86dcc057..77d15dbebb0c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #define KFD_SYSFS_FILE_MODE 0444 @@ -41,9 +42,26 @@ #define kfd_alloc_struct(ptr_to_struct) \ ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) +/* Kernel module parameter to specify maximum number of supported processes */ +extern int max_num_of_processes; + +#define KFD_MAX_NUM_OF_PROCESSES_DEFAULT 32 +#define KFD_MAX_NUM_OF_PROCESSES 512 + +/* + * Kernel module parameter to specify maximum number of supported queues + * per process + */ +extern int max_num_of_queues_per_process; + +#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128 +#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 + + struct kfd_device_info { unsigned int max_pasid_bits; size_t ih_ring_entry_size; + uint16_t mqd_size_aligned; }; struct kfd_dev { @@ -54,6 +72,21 @@ struct kfd_dev { unsigned int id; /* topology stub index */ + phys_addr_t doorbell_base; /* Start of actual doorbells used by + * KFD. It is aligned for mapping + * into user mode + */ + size_t doorbell_id_offset; /* Doorbell offset (from KFD doorbell + * to HW doorbell, GFX reserved some + * at the start) + */ + size_t doorbell_process_limit; /* Number of processes we have doorbell + * space for. + */ + u32 __iomem *doorbell_kernel_ptr; /* This is a pointer for a doorbells + * page used by kernel queue + */ + struct kgd2kfd_shared_resources shared_resources; bool init_complete; @@ -69,15 +102,122 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd); extern const struct kfd2kgd_calls *kfd2kgd; +struct kfd_mem_obj { + void *bo; + uint64_t gpu_addr; + uint32_t *cpu_ptr; +}; + +enum kfd_mempool { + KFD_MEMPOOL_SYSTEM_CACHEABLE = 1, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2, + KFD_MEMPOOL_FRAMEBUFFER = 3, +}; + /* Character device interface */ int kfd_chardev_init(void); void kfd_chardev_exit(void); struct device *kfd_chardev(void); + +/* Data that is per-process-per device. */ +struct kfd_process_device { + /* + * List of all per-device data for a process. + * Starts from kfd_process.per_device_data. + */ + struct list_head per_device_list; + + /* The device that owns this data. */ + struct kfd_dev *dev; + + + /*Apertures*/ + uint64_t lds_base; + uint64_t lds_limit; + uint64_t gpuvm_base; + uint64_t gpuvm_limit; + uint64_t scratch_base; + uint64_t scratch_limit; + + /* Is this process/pasid bound to this device? (amd_iommu_bind_pasid) */ + bool bound; +}; + /* Process data */ struct kfd_process { + /* + * kfd_process are stored in an mm_struct*->kfd_process* + * hash table (kfd_processes in kfd_process.c) + */ + struct hlist_node kfd_processes; + + struct mm_struct *mm; + + struct mutex mutex; + + /* + * In any process, the thread that started main() is the lead + * thread and outlives the rest. + * It is here because amd_iommu_bind_pasid wants a task_struct. + */ + struct task_struct *lead_thread; + + /* We want to receive a notification when the mm_struct is destroyed */ + struct mmu_notifier mmu_notifier; + + /* Use for delayed freeing of kfd_process structure */ + struct rcu_head rcu; + + unsigned int pasid; + + /* + * List of kfd_process_device structures, + * one for each device the process is using. + */ + struct list_head per_device_data; + + /* The process's queues. */ + size_t queue_array_size; + + /* Size is queue_array_size, up to MAX_PROCESS_QUEUES. */ + struct kfd_queue **queues; + + unsigned long allocated_queue_bitmap[DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)]; + + /*Is the user space process 32 bit?*/ + bool is_32bit_user_mode; }; +void kfd_process_create_wq(void); +void kfd_process_destroy_wq(void); +struct kfd_process *kfd_create_process(const struct task_struct *); +struct kfd_process *kfd_get_process(const struct task_struct *); + +struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, + struct kfd_process *p, + int create_pdd); + +/* PASIDs */ +int kfd_pasid_init(void); +void kfd_pasid_exit(void); +bool kfd_set_pasid_limit(unsigned int new_limit); +unsigned int kfd_get_pasid_limit(void); +unsigned int kfd_pasid_alloc(void); +void kfd_pasid_free(unsigned int pasid); + +/* Doorbells */ +void kfd_doorbell_init(struct kfd_dev *kfd); +int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma); +u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, + unsigned int *doorbell_off); +void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr); +u32 read_kernel_doorbell(u32 __iomem *db); +void write_kernel_doorbell(u32 __iomem *db, u32 value); +unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd, + struct kfd_process *process, + unsigned int queue_id); + extern struct device *kfd_device; /* Topology */ @@ -96,4 +236,11 @@ void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry); void kgd2kfd_suspend(struct kfd_dev *dev); int kgd2kfd_resume(struct kfd_dev *dev); +/* amdkfd Apertures */ +int kfd_init_apertures(struct kfd_process *process); + +uint64_t kfd_get_number_elems(struct kfd_dev *kfd); +phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, + struct kfd_process *process); + #endif diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c new file mode 100644 index 000000000000..5596f698cc11 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -0,0 +1,383 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +struct mm_struct; + +#include "kfd_priv.h" + +/* + * Initial size for the array of queues. + * The allocated size is doubled each time + * it is exceeded up to MAX_PROCESS_QUEUES. + */ +#define INITIAL_QUEUE_ARRAY_SIZE 16 + +/* + * List of struct kfd_process (field kfd_process). + * Unique/indexed by mm_struct* + */ +#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */ +static DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE); +static DEFINE_MUTEX(kfd_processes_mutex); + +DEFINE_STATIC_SRCU(kfd_processes_srcu); + +static struct workqueue_struct *kfd_process_wq; + +struct kfd_process_release_work { + struct work_struct kfd_work; + struct kfd_process *p; +}; + +static struct kfd_process *find_process(const struct task_struct *thread); +static struct kfd_process *create_process(const struct task_struct *thread); + +void kfd_process_create_wq(void) +{ + if (!kfd_process_wq) + kfd_process_wq = create_workqueue("kfd_process_wq"); +} + +void kfd_process_destroy_wq(void) +{ + if (kfd_process_wq) { + flush_workqueue(kfd_process_wq); + destroy_workqueue(kfd_process_wq); + kfd_process_wq = NULL; + } +} + +struct kfd_process *kfd_create_process(const struct task_struct *thread) +{ + struct kfd_process *process; + + BUG_ON(!kfd_process_wq); + + if (thread->mm == NULL) + return ERR_PTR(-EINVAL); + + /* Only the pthreads threading model is supported. */ + if (thread->group_leader->mm != thread->mm) + return ERR_PTR(-EINVAL); + + /* Take mmap_sem because we call __mmu_notifier_register inside */ + down_write(&thread->mm->mmap_sem); + + /* + * take kfd processes mutex before starting of process creation + * so there won't be a case where two threads of the same process + * create two kfd_process structures + */ + mutex_lock(&kfd_processes_mutex); + + /* A prior open of /dev/kfd could have already created the process. */ + process = find_process(thread); + if (process) + pr_debug("kfd: process already found\n"); + + if (!process) + process = create_process(thread); + + mutex_unlock(&kfd_processes_mutex); + + up_write(&thread->mm->mmap_sem); + + return process; +} + +struct kfd_process *kfd_get_process(const struct task_struct *thread) +{ + struct kfd_process *process; + + if (thread->mm == NULL) + return ERR_PTR(-EINVAL); + + /* Only the pthreads threading model is supported. */ + if (thread->group_leader->mm != thread->mm) + return ERR_PTR(-EINVAL); + + process = find_process(thread); + + return process; +} + +static struct kfd_process *find_process_by_mm(const struct mm_struct *mm) +{ + struct kfd_process *process; + + hash_for_each_possible_rcu(kfd_processes_table, process, + kfd_processes, (uintptr_t)mm) + if (process->mm == mm) + return process; + + return NULL; +} + +static struct kfd_process *find_process(const struct task_struct *thread) +{ + struct kfd_process *p; + int idx; + + idx = srcu_read_lock(&kfd_processes_srcu); + p = find_process_by_mm(thread->mm); + srcu_read_unlock(&kfd_processes_srcu, idx); + + return p; +} + +static void kfd_process_wq_release(struct work_struct *work) +{ + struct kfd_process_release_work *my_work; + struct kfd_process_device *pdd, *temp; + struct kfd_process *p; + + my_work = (struct kfd_process_release_work *) work; + + p = my_work->p; + + mutex_lock(&p->mutex); + + list_for_each_entry_safe(pdd, temp, &p->per_device_data, + per_device_list) { + list_del(&pdd->per_device_list); + + kfree(pdd); + } + + kfd_pasid_free(p->pasid); + + mutex_unlock(&p->mutex); + + mutex_destroy(&p->mutex); + + kfree(p->queues); + + kfree(p); + + kfree((void *)work); +} + +static void kfd_process_destroy_delayed(struct rcu_head *rcu) +{ + struct kfd_process_release_work *work; + struct kfd_process *p; + + BUG_ON(!kfd_process_wq); + + p = container_of(rcu, struct kfd_process, rcu); + BUG_ON(atomic_read(&p->mm->mm_count) <= 0); + + mmdrop(p->mm); + + work = (struct kfd_process_release_work *) + kmalloc(sizeof(struct kfd_process_release_work), GFP_KERNEL); + + if (work) { + INIT_WORK((struct work_struct *) work, kfd_process_wq_release); + work->p = p; + queue_work(kfd_process_wq, (struct work_struct *) work); + } +} + +static void kfd_process_notifier_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct kfd_process *p; + + /* + * The kfd_process structure can not be free because the + * mmu_notifier srcu is read locked + */ + p = container_of(mn, struct kfd_process, mmu_notifier); + BUG_ON(p->mm != mm); + + mutex_lock(&kfd_processes_mutex); + hash_del_rcu(&p->kfd_processes); + mutex_unlock(&kfd_processes_mutex); + synchronize_srcu(&kfd_processes_srcu); + + /* + * Because we drop mm_count inside kfd_process_destroy_delayed + * and because the mmu_notifier_unregister function also drop + * mm_count we need to take an extra count here. + */ + atomic_inc(&p->mm->mm_count); + mmu_notifier_unregister_no_release(&p->mmu_notifier, p->mm); + mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed); +} + +static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = { + .release = kfd_process_notifier_release, +}; + +static struct kfd_process *create_process(const struct task_struct *thread) +{ + struct kfd_process *process; + int err = -ENOMEM; + + process = kzalloc(sizeof(*process), GFP_KERNEL); + + if (!process) + goto err_alloc_process; + + process->queues = kmalloc_array(INITIAL_QUEUE_ARRAY_SIZE, + sizeof(process->queues[0]), GFP_KERNEL); + if (!process->queues) + goto err_alloc_queues; + + process->pasid = kfd_pasid_alloc(); + if (process->pasid == 0) + goto err_alloc_pasid; + + mutex_init(&process->mutex); + + process->mm = thread->mm; + + /* register notifier */ + process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops; + err = __mmu_notifier_register(&process->mmu_notifier, process->mm); + if (err) + goto err_mmu_notifier; + + hash_add_rcu(kfd_processes_table, &process->kfd_processes, + (uintptr_t)process->mm); + + process->lead_thread = thread->group_leader; + + process->queue_array_size = INITIAL_QUEUE_ARRAY_SIZE; + + INIT_LIST_HEAD(&process->per_device_data); + + return process; + +err_mmu_notifier: + kfd_pasid_free(process->pasid); +err_alloc_pasid: + kfree(process->queues); +err_alloc_queues: + kfree(process); +err_alloc_process: + return ERR_PTR(err); +} + +struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, + struct kfd_process *p, + int create_pdd) +{ + struct kfd_process_device *pdd = NULL; + + list_for_each_entry(pdd, &p->per_device_data, per_device_list) + if (pdd->dev == dev) + return pdd; + + if (create_pdd) { + pdd = kzalloc(sizeof(*pdd), GFP_KERNEL); + if (pdd != NULL) { + pdd->dev = dev; + list_add(&pdd->per_device_list, &p->per_device_data); + } + } + + return pdd; +} + +/* + * Direct the IOMMU to bind the process (specifically the pasid->mm) + * to the device. + * Unbinding occurs when the process dies or the device is removed. + * + * Assumes that the process lock is held. + */ +struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, + struct kfd_process *p) +{ + struct kfd_process_device *pdd = kfd_get_process_device_data(dev, p, 1); + + if (pdd == NULL) + return ERR_PTR(-ENOMEM); + + if (pdd->bound) + return pdd; + + pdd->bound = true; + + return pdd; +} + +void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) +{ + struct kfd_process *p; + struct kfd_process_device *pdd; + int idx, i; + + BUG_ON(dev == NULL); + + idx = srcu_read_lock(&kfd_processes_srcu); + + hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) + if (p->pasid == pasid) + break; + + srcu_read_unlock(&kfd_processes_srcu, idx); + + BUG_ON(p->pasid != pasid); + + mutex_lock(&p->mutex); + + pdd = kfd_get_process_device_data(dev, p, 0); + + /* + * Just mark pdd as unbound, because we still need it to call + * amd_iommu_unbind_pasid() in when the process exits. + * We don't call amd_iommu_unbind_pasid() here + * because the IOMMU called us. + */ + if (pdd) + pdd->bound = false; + + mutex_unlock(&p->mutex); +} + +struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) +{ + return list_first_entry(&p->per_device_data, + struct kfd_process_device, + per_device_list); +} + +struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p, + struct kfd_process_device *pdd) +{ + if (list_is_last(&pdd->per_device_list, &p->per_device_data)) + return NULL; + return list_next_entry(pdd, per_device_list); +} + +bool kfd_has_process_device_data(struct kfd_process *p) +{ + return !(list_empty(&p->per_device_data)); +} -- GitLab From b17f068a09fbe9b193a18080ff8ad5114a900124 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 17 Jul 2014 00:06:27 +0300 Subject: [PATCH 0016/9457] amdkfd: Add binding/unbinding calls to amd_iommu driver This patch adds the functions to bind and unbind pasid from a device through the amd_iommu driver. The unbind function is called when the mm_struct of the process is released. The bind function is not called here because it is called only in the IOCTLs which are not yet implemented at this stage of the patchset. Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 90 +++++++++++++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 + drivers/gpu/drm/amd/amdkfd/kfd_process.c | 12 ++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 71a03f7b0049..4b1cced9b2b7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -100,6 +100,65 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev) return kfd; } +static bool device_iommu_pasid_init(struct kfd_dev *kfd) +{ + const u32 required_iommu_flags = AMD_IOMMU_DEVICE_FLAG_ATS_SUP | + AMD_IOMMU_DEVICE_FLAG_PRI_SUP | + AMD_IOMMU_DEVICE_FLAG_PASID_SUP; + + struct amd_iommu_device_info iommu_info; + unsigned int pasid_limit; + int err; + + err = amd_iommu_device_info(kfd->pdev, &iommu_info); + if (err < 0) { + dev_err(kfd_device, + "error getting iommu info. is the iommu enabled?\n"); + return false; + } + + if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) { + dev_err(kfd_device, "error required iommu flags ats(%i), pri(%i), pasid(%i)\n", + (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0, + (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0, + (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP) != 0); + return false; + } + + pasid_limit = min_t(unsigned int, + (unsigned int)1 << kfd->device_info->max_pasid_bits, + iommu_info.max_pasids); + /* + * last pasid is used for kernel queues doorbells + * in the future the last pasid might be used for a kernel thread. + */ + pasid_limit = min_t(unsigned int, + pasid_limit, + kfd->doorbell_process_limit - 1); + + err = amd_iommu_init_device(kfd->pdev, pasid_limit); + if (err < 0) { + dev_err(kfd_device, "error initializing iommu device\n"); + return false; + } + + if (!kfd_set_pasid_limit(pasid_limit)) { + dev_err(kfd_device, "error setting pasid limit\n"); + amd_iommu_free_device(kfd->pdev); + return false; + } + + return true; +} + +static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, int pasid) +{ + struct kfd_dev *dev = kfd_device_by_pci_dev(pdev); + + if (dev) + kfd_unbind_process_from_device(dev, pasid); +} + bool kgd2kfd_device_init(struct kfd_dev *kfd, const struct kgd2kfd_shared_resources *gpu_resources) { @@ -131,6 +190,14 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_topology_add_device_error; } + if (!device_iommu_pasid_init(kfd)) { + dev_err(kfd_device, + "Error initializing iommuv2 for device (%x:%x)\n", + kfd->pdev->vendor, kfd->pdev->device); + goto device_iommu_pasid_error; + } + amd_iommu_set_invalidate_ctx_cb(kfd->pdev, + iommu_pasid_shutdown_callback); kfd->init_complete = true; dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor, @@ -138,6 +205,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto out; +device_iommu_pasid_error: + kfd_topology_remove_device(kfd); kfd_topology_add_device_error: kfd2kgd->fini_sa_manager(kfd->kgd); dev_err(kfd_device, @@ -149,7 +218,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, void kgd2kfd_device_exit(struct kfd_dev *kfd) { - kfd_topology_remove_device(kfd); + if (kfd->init_complete) { + amd_iommu_free_device(kfd->pdev); + kfd_topology_remove_device(kfd); + } kfree(kfd); } @@ -157,12 +229,28 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) void kgd2kfd_suspend(struct kfd_dev *kfd) { BUG_ON(kfd == NULL); + + if (kfd->init_complete) + amd_iommu_free_device(kfd->pdev); } int kgd2kfd_resume(struct kfd_dev *kfd) { + unsigned int pasid_limit; + int err; + BUG_ON(kfd == NULL); + pasid_limit = kfd_get_pasid_limit(); + + if (kfd->init_complete) { + err = amd_iommu_init_device(kfd->pdev, pasid_limit); + if (err < 0) + return -ENXIO; + amd_iommu_set_invalidate_ctx_cb(kfd->pdev, + iommu_pasid_shutdown_callback); + } + return 0; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 77d15dbebb0c..431a09bbab62 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -194,6 +194,7 @@ void kfd_process_destroy_wq(void); struct kfd_process *kfd_create_process(const struct task_struct *); struct kfd_process *kfd_get_process(const struct task_struct *); +void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid); struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process *p, int create_pdd); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 5596f698cc11..5084794695fb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -24,6 +24,7 @@ #include #include #include +#include #include struct mm_struct; @@ -163,6 +164,7 @@ static void kfd_process_wq_release(struct work_struct *work) list_for_each_entry_safe(pdd, temp, &p->per_device_data, per_device_list) { + amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); list_del(&pdd->per_device_list); kfree(pdd); @@ -316,6 +318,7 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, struct kfd_process *p) { struct kfd_process_device *pdd = kfd_get_process_device_data(dev, p, 1); + int err; if (pdd == NULL) return ERR_PTR(-ENOMEM); @@ -323,6 +326,15 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, if (pdd->bound) return pdd; + err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread); + if (err < 0) + return ERR_PTR(err); + + if (err < 0) { + amd_iommu_unbind_pasid(dev->pdev, p->pasid); + return ERR_PTR(err); + } + pdd->bound = true; return pdd; -- GitLab From ed8aab4594e0c5054b25b4a8810901ccf70efdcf Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 00:18:51 +0300 Subject: [PATCH 0017/9457] amdkfd: Add queue module The queue module enables allocating and initializing queues uniformly. v3: Removed typedef and redundant memset call. Broke long pr_debug print to one liners and Added documentation. v5: Move amdkfd from drm/radeon/ to drm/amd/ Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 124 ++++++++++++++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_queue.c | 85 +++++++++++++++++ 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_queue.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index e829a3fa7d8e..42df022a0912 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -6,6 +6,6 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ - kfd_process.o + kfd_process.o kfd_queue.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 431a09bbab62..5f6f13d1a20d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -57,7 +57,6 @@ extern int max_num_of_queues_per_process; #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128 #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 - struct kfd_device_info { unsigned int max_pasid_bits; size_t ih_ring_entry_size; @@ -120,6 +119,129 @@ void kfd_chardev_exit(void); struct device *kfd_chardev(void); +/** + * enum kfd_queue_type + * + * @KFD_QUEUE_TYPE_COMPUTE: Regular user mode queue type. + * + * @KFD_QUEUE_TYPE_SDMA: Sdma user mode queue type. + * + * @KFD_QUEUE_TYPE_HIQ: HIQ queue type. + * + * @KFD_QUEUE_TYPE_DIQ: DIQ queue type. + */ +enum kfd_queue_type { + KFD_QUEUE_TYPE_COMPUTE, + KFD_QUEUE_TYPE_SDMA, + KFD_QUEUE_TYPE_HIQ, + KFD_QUEUE_TYPE_DIQ +}; + +/** + * struct queue_properties + * + * @type: The queue type. + * + * @queue_id: Queue identifier. + * + * @queue_address: Queue ring buffer address. + * + * @queue_size: Queue ring buffer size. + * + * @priority: Defines the queue priority relative to other queues in the + * process. + * This is just an indication and HW scheduling may override the priority as + * necessary while keeping the relative prioritization. + * the priority granularity is from 0 to f which f is the highest priority. + * currently all queues are initialized with the highest priority. + * + * @queue_percent: This field is partially implemented and currently a zero in + * this field defines that the queue is non active. + * + * @read_ptr: User space address which points to the number of dwords the + * cp read from the ring buffer. This field updates automatically by the H/W. + * + * @write_ptr: Defines the number of dwords written to the ring buffer. + * + * @doorbell_ptr: This field aim is to notify the H/W of new packet written to + * the queue ring buffer. This field should be similar to write_ptr and the user + * should update this field after he updated the write_ptr. + * + * @doorbell_off: The doorbell offset in the doorbell pci-bar. + * + * @is_interop: Defines if this is a interop queue. Interop queue means that the + * queue can access both graphics and compute resources. + * + * @is_active: Defines if the queue is active or not. + * + * @vmid: If the scheduling mode is no cp scheduling the field defines the vmid + * of the queue. + * + * This structure represents the queue properties for each queue no matter if + * it's user mode or kernel mode queue. + * + */ +struct queue_properties { + enum kfd_queue_type type; + unsigned int queue_id; + uint64_t queue_address; + uint64_t queue_size; + uint32_t priority; + uint32_t queue_percent; + uint32_t *read_ptr; + uint32_t *write_ptr; + uint32_t *doorbell_ptr; + uint32_t doorbell_off; + bool is_interop; + bool is_active; + /* Not relevant for user mode queues in cp scheduling */ + unsigned int vmid; +}; + +/** + * struct queue + * + * @list: Queue linked list. + * + * @mqd: The queue MQD. + * + * @mqd_mem_obj: The MQD local gpu memory object. + * + * @gart_mqd_addr: The MQD gart mc address. + * + * @properties: The queue properties. + * + * @mec: Used only in no cp scheduling mode and identifies to micro engine id + * that the queue should be execute on. + * + * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe id. + * + * @queue: Used only in no cp scheduliong mode and identifies the queue's slot. + * + * @process: The kfd process that created this queue. + * + * @device: The kfd device that created this queue. + * + * This structure represents user mode compute queues. + * It contains all the necessary data to handle such queues. + * + */ + +struct queue { + struct list_head list; + void *mqd; + struct kfd_mem_obj *mqd_mem_obj; + uint64_t gart_mqd_addr; + struct queue_properties properties; + + uint32_t mec; + uint32_t pipe; + uint32_t queue; + + struct kfd_process *process; + struct kfd_dev *device; +}; + /* Data that is per-process-per device. */ struct kfd_process_device { /* diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c new file mode 100644 index 000000000000..9a0c90b0702e --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c @@ -0,0 +1,85 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include "kfd_priv.h" + +void print_queue_properties(struct queue_properties *q) +{ + if (!q) + return; + + pr_debug("Printing queue properties:\n"); + pr_debug("Queue Type: %u\n", q->type); + pr_debug("Queue Size: %llu\n", q->queue_size); + pr_debug("Queue percent: %u\n", q->queue_percent); + pr_debug("Queue Address: 0x%llX\n", q->queue_address); + pr_debug("Queue Id: %u\n", q->queue_id); + pr_debug("Queue Process Vmid: %u\n", q->vmid); + pr_debug("Queue Read Pointer: 0x%p\n", q->read_ptr); + pr_debug("Queue Write Pointer: 0x%p\n", q->write_ptr); + pr_debug("Queue Doorbell Pointer: 0x%p\n", q->doorbell_ptr); + pr_debug("Queue Doorbell Offset: %u\n", q->doorbell_off); +} + +void print_queue(struct queue *q) +{ + if (!q) + return; + pr_debug("Printing queue:\n"); + pr_debug("Queue Type: %u\n", q->properties.type); + pr_debug("Queue Size: %llu\n", q->properties.queue_size); + pr_debug("Queue percent: %u\n", q->properties.queue_percent); + pr_debug("Queue Address: 0x%llX\n", q->properties.queue_address); + pr_debug("Queue Id: %u\n", q->properties.queue_id); + pr_debug("Queue Process Vmid: %u\n", q->properties.vmid); + pr_debug("Queue Read Pointer: 0x%p\n", q->properties.read_ptr); + pr_debug("Queue Write Pointer: 0x%p\n", q->properties.write_ptr); + pr_debug("Queue Doorbell Pointer: 0x%p\n", q->properties.doorbell_ptr); + pr_debug("Queue Doorbell Offset: %u\n", q->properties.doorbell_off); + pr_debug("Queue MQD Address: 0x%p\n", q->mqd); + pr_debug("Queue MQD Gart: 0x%llX\n", q->gart_mqd_addr); + pr_debug("Queue Process Address: 0x%p\n", q->process); + pr_debug("Queue Device Address: 0x%p\n", q->device); +} + +int init_queue(struct queue **q, struct queue_properties properties) +{ + struct queue *tmp; + + BUG_ON(!q); + + tmp = kzalloc(sizeof(struct queue), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + memcpy(&tmp->properties, &properties, sizeof(struct queue_properties)); + + *q = tmp; + return 0; +} + +void uninit_queue(struct queue *q) +{ + kfree(q); +} -- GitLab From 6e99df5741b3332dcceb86915b2818af640c51f9 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 00:36:17 +0300 Subject: [PATCH 0018/9457] amdkfd: Add mqd_manager module The mqd_manager module handles MQD data structures. MQD stands for Memory Queue Descriptor, which is used by the H/W to keep the usermode queue state in memory. v3: Removed new typedefs Removed pragma pack 4 Remove cik_mqds.h file Changed lower_32/upper_32 calls to use linux macros Used new gart allocation functions Added documentation v4: Added missing initialization of the addr field in init_mqd() Setting the hqd persistent.preload_req bit ON so that when queues switches on/off, their context will kept and read from the mqd when the cp reassign them, and thus the dispatched workload context kept consistent without any interrupts. v5: Move amdkfd from drm/radeon/ to drm/amd/ Change format of mqd structure to match latest KV firmware Add support for AQL queues creation to enable working with open-source HSA runtime. Various fixes Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- drivers/gpu/drm/amd/amdkfd/cik_regs.h | 221 ++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 346 +++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 91 +++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 22 ++ 5 files changed, 681 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/cik_regs.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 42df022a0912..301e8471e636 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -6,6 +6,6 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ - kfd_process.o kfd_queue.o + kfd_process.o kfd_queue.o kfd_mqd_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/cik_regs.h b/drivers/gpu/drm/amd/amdkfd/cik_regs.h new file mode 100644 index 000000000000..607fc5ceadbe --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/cik_regs.h @@ -0,0 +1,221 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CIK_REGS_H +#define CIK_REGS_H + +#define IH_VMID_0_LUT 0x3D40u + +#define BIF_DOORBELL_CNTL 0x530Cu + +#define SRBM_GFX_CNTL 0xE44 +#define PIPEID(x) ((x) << 0) +#define MEID(x) ((x) << 2) +#define VMID(x) ((x) << 4) +#define QUEUEID(x) ((x) << 8) + +#define SQ_CONFIG 0x8C00 + +#define SH_MEM_BASES 0x8C28 +/* if PTR32, these are the bases for scratch and lds */ +#define PRIVATE_BASE(x) ((x) << 0) /* scratch */ +#define SHARED_BASE(x) ((x) << 16) /* LDS */ +#define SH_MEM_APE1_BASE 0x8C2C +/* if PTR32, this is the base location of GPUVM */ +#define SH_MEM_APE1_LIMIT 0x8C30 +/* if PTR32, this is the upper limit of GPUVM */ +#define SH_MEM_CONFIG 0x8C34 +#define PTR32 (1 << 0) +#define PRIVATE_ATC (1 << 1) +#define ALIGNMENT_MODE(x) ((x) << 2) +#define SH_MEM_ALIGNMENT_MODE_DWORD 0 +#define SH_MEM_ALIGNMENT_MODE_DWORD_STRICT 1 +#define SH_MEM_ALIGNMENT_MODE_STRICT 2 +#define SH_MEM_ALIGNMENT_MODE_UNALIGNED 3 +#define DEFAULT_MTYPE(x) ((x) << 4) +#define APE1_MTYPE(x) ((x) << 7) + +/* valid for both DEFAULT_MTYPE and APE1_MTYPE */ +#define MTYPE_CACHED 0 +#define MTYPE_NONCACHED 3 + + +#define SH_STATIC_MEM_CONFIG 0x9604u + +#define TC_CFG_L1_LOAD_POLICY0 0xAC68 +#define TC_CFG_L1_LOAD_POLICY1 0xAC6C +#define TC_CFG_L1_STORE_POLICY 0xAC70 +#define TC_CFG_L2_LOAD_POLICY0 0xAC74 +#define TC_CFG_L2_LOAD_POLICY1 0xAC78 +#define TC_CFG_L2_STORE_POLICY0 0xAC7C +#define TC_CFG_L2_STORE_POLICY1 0xAC80 +#define TC_CFG_L2_ATOMIC_POLICY 0xAC84 +#define TC_CFG_L1_VOLATILE 0xAC88 +#define TC_CFG_L2_VOLATILE 0xAC8C + +#define CP_PQ_WPTR_POLL_CNTL 0xC20C +#define WPTR_POLL_EN (1 << 31) + +#define CPC_INT_CNTL 0xC2D0 +#define CP_ME1_PIPE0_INT_CNTL 0xC214 +#define CP_ME1_PIPE1_INT_CNTL 0xC218 +#define CP_ME1_PIPE2_INT_CNTL 0xC21C +#define CP_ME1_PIPE3_INT_CNTL 0xC220 +#define CP_ME2_PIPE0_INT_CNTL 0xC224 +#define CP_ME2_PIPE1_INT_CNTL 0xC228 +#define CP_ME2_PIPE2_INT_CNTL 0xC22C +#define CP_ME2_PIPE3_INT_CNTL 0xC230 +#define DEQUEUE_REQUEST_INT_ENABLE (1 << 13) +#define WRM_POLL_TIMEOUT_INT_ENABLE (1 << 17) +#define PRIV_REG_INT_ENABLE (1 << 23) +#define TIME_STAMP_INT_ENABLE (1 << 26) +#define GENERIC2_INT_ENABLE (1 << 29) +#define GENERIC1_INT_ENABLE (1 << 30) +#define GENERIC0_INT_ENABLE (1 << 31) +#define CP_ME1_PIPE0_INT_STATUS 0xC214 +#define CP_ME1_PIPE1_INT_STATUS 0xC218 +#define CP_ME1_PIPE2_INT_STATUS 0xC21C +#define CP_ME1_PIPE3_INT_STATUS 0xC220 +#define CP_ME2_PIPE0_INT_STATUS 0xC224 +#define CP_ME2_PIPE1_INT_STATUS 0xC228 +#define CP_ME2_PIPE2_INT_STATUS 0xC22C +#define CP_ME2_PIPE3_INT_STATUS 0xC230 +#define DEQUEUE_REQUEST_INT_STATUS (1 << 13) +#define WRM_POLL_TIMEOUT_INT_STATUS (1 << 17) +#define PRIV_REG_INT_STATUS (1 << 23) +#define TIME_STAMP_INT_STATUS (1 << 26) +#define GENERIC2_INT_STATUS (1 << 29) +#define GENERIC1_INT_STATUS (1 << 30) +#define GENERIC0_INT_STATUS (1 << 31) + +#define CP_HPD_EOP_BASE_ADDR 0xC904 +#define CP_HPD_EOP_BASE_ADDR_HI 0xC908 +#define CP_HPD_EOP_VMID 0xC90C +#define CP_HPD_EOP_CONTROL 0xC910 +#define EOP_SIZE(x) ((x) << 0) +#define EOP_SIZE_MASK (0x3f << 0) +#define CP_MQD_BASE_ADDR 0xC914 +#define CP_MQD_BASE_ADDR_HI 0xC918 +#define CP_HQD_ACTIVE 0xC91C +#define CP_HQD_VMID 0xC920 + +#define CP_HQD_PERSISTENT_STATE 0xC924u +#define DEFAULT_CP_HQD_PERSISTENT_STATE (0x33U << 8) +#define PRELOAD_REQ (1 << 0) + +#define CP_HQD_PIPE_PRIORITY 0xC928u +#define CP_HQD_QUEUE_PRIORITY 0xC92Cu +#define CP_HQD_QUANTUM 0xC930u +#define QUANTUM_EN 1U +#define QUANTUM_SCALE_1MS (1U << 4) +#define QUANTUM_DURATION(x) ((x) << 8) + +#define CP_HQD_PQ_BASE 0xC934 +#define CP_HQD_PQ_BASE_HI 0xC938 +#define CP_HQD_PQ_RPTR 0xC93C +#define CP_HQD_PQ_RPTR_REPORT_ADDR 0xC940 +#define CP_HQD_PQ_RPTR_REPORT_ADDR_HI 0xC944 +#define CP_HQD_PQ_WPTR_POLL_ADDR 0xC948 +#define CP_HQD_PQ_WPTR_POLL_ADDR_HI 0xC94C +#define CP_HQD_PQ_DOORBELL_CONTROL 0xC950 +#define DOORBELL_OFFSET(x) ((x) << 2) +#define DOORBELL_OFFSET_MASK (0x1fffff << 2) +#define DOORBELL_SOURCE (1 << 28) +#define DOORBELL_SCHD_HIT (1 << 29) +#define DOORBELL_EN (1 << 30) +#define DOORBELL_HIT (1 << 31) +#define CP_HQD_PQ_WPTR 0xC954 +#define CP_HQD_PQ_CONTROL 0xC958 +#define QUEUE_SIZE(x) ((x) << 0) +#define QUEUE_SIZE_MASK (0x3f << 0) +#define RPTR_BLOCK_SIZE(x) ((x) << 8) +#define RPTR_BLOCK_SIZE_MASK (0x3f << 8) +#define MIN_AVAIL_SIZE(x) ((x) << 20) +#define PQ_ATC_EN (1 << 23) +#define PQ_VOLATILE (1 << 26) +#define NO_UPDATE_RPTR (1 << 27) +#define UNORD_DISPATCH (1 << 28) +#define ROQ_PQ_IB_FLIP (1 << 29) +#define PRIV_STATE (1 << 30) +#define KMD_QUEUE (1 << 31) + +#define DEFAULT_RPTR_BLOCK_SIZE RPTR_BLOCK_SIZE(5) +#define DEFAULT_MIN_AVAIL_SIZE MIN_AVAIL_SIZE(3) + +#define CP_HQD_IB_BASE_ADDR 0xC95Cu +#define CP_HQD_IB_BASE_ADDR_HI 0xC960u +#define CP_HQD_IB_RPTR 0xC964u +#define CP_HQD_IB_CONTROL 0xC968u +#define IB_ATC_EN (1U << 23) +#define DEFAULT_MIN_IB_AVAIL_SIZE (3U << 20) + +#define CP_HQD_DEQUEUE_REQUEST 0xC974 +#define DEQUEUE_REQUEST_DRAIN 1 +#define DEQUEUE_REQUEST_RESET 2 +#define DEQUEUE_INT (1U << 8) + +#define CP_HQD_SEMA_CMD 0xC97Cu +#define CP_HQD_MSG_TYPE 0xC980u +#define CP_HQD_ATOMIC0_PREOP_LO 0xC984u +#define CP_HQD_ATOMIC0_PREOP_HI 0xC988u +#define CP_HQD_ATOMIC1_PREOP_LO 0xC98Cu +#define CP_HQD_ATOMIC1_PREOP_HI 0xC990u +#define CP_HQD_HQ_SCHEDULER0 0xC994u +#define CP_HQD_HQ_SCHEDULER1 0xC998u + + +#define CP_MQD_CONTROL 0xC99C +#define MQD_VMID(x) ((x) << 0) +#define MQD_VMID_MASK (0xf << 0) +#define MQD_CONTROL_PRIV_STATE_EN (1U << 8) + +#define GRBM_GFX_INDEX 0x30800 +#define INSTANCE_INDEX(x) ((x) << 0) +#define SH_INDEX(x) ((x) << 8) +#define SE_INDEX(x) ((x) << 16) +#define SH_BROADCAST_WRITES (1 << 29) +#define INSTANCE_BROADCAST_WRITES (1 << 30) +#define SE_BROADCAST_WRITES (1 << 31) + +#define SQC_CACHES 0x30d20 +#define SQC_POLICY 0x8C38u +#define SQC_VOLATILE 0x8C3Cu + +#define CP_PERFMON_CNTL 0x36020 + +#define ATC_VMID0_PASID_MAPPING 0x339Cu +#define ATC_VMID_PASID_MAPPING_UPDATE_STATUS 0x3398u +#define ATC_VMID_PASID_MAPPING_VALID (1U << 31) + +#define ATC_VM_APERTURE0_CNTL 0x3310u +#define ATS_ACCESS_MODE_NEVER 0 +#define ATS_ACCESS_MODE_ALWAYS 1 + +#define ATC_VM_APERTURE0_CNTL2 0x3318u +#define ATC_VM_APERTURE0_HIGH_ADDR 0x3308u +#define ATC_VM_APERTURE0_LOW_ADDR 0x3300u +#define ATC_VM_APERTURE1_CNTL 0x3314u +#define ATC_VM_APERTURE1_CNTL2 0x331Cu +#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu +#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u + +#endif diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c new file mode 100644 index 000000000000..59d240719a08 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -0,0 +1,346 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include "kfd_priv.h" +#include "kfd_mqd_manager.h" +#include "cik_regs.h" +#include "../../radeon/cik_reg.h" + +inline void busy_wait(unsigned long ms) +{ + while (time_before(jiffies, ms)) + cpu_relax(); +} + +static inline struct cik_mqd *get_mqd(void *mqd) +{ + return (struct cik_mqd *)mqd; +} + +static int init_mqd(struct mqd_manager *mm, void **mqd, + struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr, + struct queue_properties *q) +{ + uint64_t addr; + struct cik_mqd *m; + int retval; + + BUG_ON(!mm || !q || !mqd); + + pr_debug("kfd: In func %s\n", __func__); + + retval = kfd2kgd->allocate_mem(mm->dev->kgd, + sizeof(struct cik_mqd), + 256, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) mqd_mem_obj); + + if (retval != 0) + return -ENOMEM; + + m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr; + addr = (*mqd_mem_obj)->gpu_addr; + + memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256)); + + m->header = 0xC0310800; + m->compute_pipelinestat_enable = 1; + m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF; + + /* + * Make sure to use the last queue state saved on mqd when the cp + * reassigns the queue, so when queue is switched on/off (e.g over + * subscription or quantum timeout) the context will be consistent + */ + m->cp_hqd_persistent_state = + DEFAULT_CP_HQD_PERSISTENT_STATE | PRELOAD_REQ; + + m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN; + m->cp_mqd_base_addr_lo = lower_32_bits(addr); + m->cp_mqd_base_addr_hi = upper_32_bits(addr); + + m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN; + /* Although WinKFD writes this, I suspect it should not be necessary */ + m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE; + + m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS | + QUANTUM_DURATION(10); + + /* + * Pipe Priority + * Identifies the pipe relative priority when this queue is connected + * to the pipeline. The pipe priority is against the GFX pipe and HP3D. + * In KFD we are using a fixed pipe priority set to CS_MEDIUM. + * 0 = CS_LOW (typically below GFX) + * 1 = CS_MEDIUM (typically between HP3D and GFX + * 2 = CS_HIGH (typically above HP3D) + */ + m->cp_hqd_pipe_priority = 1; + m->cp_hqd_queue_priority = 15; + + *mqd = m; + if (gart_addr != NULL) + *gart_addr = addr; + retval = mm->update_mqd(mm, m, q); + + return retval; +} + +static void uninit_mqd(struct mqd_manager *mm, void *mqd, + struct kfd_mem_obj *mqd_mem_obj) +{ + BUG_ON(!mm || !mqd); + kfd2kgd->free_mem(mm->dev->kgd, (struct kgd_mem *) mqd_mem_obj); +} + +static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr) +{ + return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr); + +} + +static int update_mqd(struct mqd_manager *mm, void *mqd, + struct queue_properties *q) +{ + struct cik_mqd *m; + + BUG_ON(!mm || !q || !mqd); + + pr_debug("kfd: In func %s\n", __func__); + + m = get_mqd(mqd); + m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE | + DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN; + + /* + * Calculating queue size which is log base 2 of actual queue size -1 + * dwords and another -1 for ffs + */ + m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int)) + - 1 - 1; + m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); + m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); + m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); + m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); + m->cp_hqd_pq_doorbell_control = DOORBELL_EN | + DOORBELL_OFFSET(q->doorbell_off); + + m->cp_hqd_vmid = q->vmid; + + if (q->format == KFD_QUEUE_FORMAT_AQL) { + m->cp_hqd_iq_rptr = AQL_ENABLE; + m->cp_hqd_pq_control |= NO_UPDATE_RPTR; + } + + m->cp_hqd_active = 0; + q->is_active = false; + if (q->queue_size > 0 && + q->queue_address != 0 && + q->queue_percent > 0) { + m->cp_hqd_active = 1; + q->is_active = true; + } + + return 0; +} + +static int destroy_mqd(struct mqd_manager *mm, void *mqd, + enum kfd_preempt_type type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id) +{ + return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout, + pipe_id, queue_id); +} + +bool is_occupied(struct mqd_manager *mm, void *mqd, + uint64_t queue_address, uint32_t pipe_id, + uint32_t queue_id) +{ + + return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, + pipe_id, queue_id); + +} + +/* + * HIQ MQD Implementation, concrete implementation for HIQ MQD implementation. + * The HIQ queue in Kaveri is using the same MQD structure as all the user mode + * queues but with different initial values. + */ + +static int init_mqd_hiq(struct mqd_manager *mm, void **mqd, + struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr, + struct queue_properties *q) +{ + uint64_t addr; + struct cik_mqd *m; + int retval; + + BUG_ON(!mm || !q || !mqd || !mqd_mem_obj); + + pr_debug("kfd: In func %s\n", __func__); + + retval = kfd2kgd->allocate_mem(mm->dev->kgd, + sizeof(struct cik_mqd), + 256, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) mqd_mem_obj); + + if (retval != 0) + return -ENOMEM; + + m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr; + addr = (*mqd_mem_obj)->gpu_addr; + + memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256)); + + m->header = 0xC0310800; + m->compute_pipelinestat_enable = 1; + m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF; + m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF; + + m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE | + PRELOAD_REQ; + m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS | + QUANTUM_DURATION(10); + + m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN; + m->cp_mqd_base_addr_lo = lower_32_bits(addr); + m->cp_mqd_base_addr_hi = upper_32_bits(addr); + + m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE; + + /* + * Pipe Priority + * Identifies the pipe relative priority when this queue is connected + * to the pipeline. The pipe priority is against the GFX pipe and HP3D. + * In KFD we are using a fixed pipe priority set to CS_MEDIUM. + * 0 = CS_LOW (typically below GFX) + * 1 = CS_MEDIUM (typically between HP3D and GFX + * 2 = CS_HIGH (typically above HP3D) + */ + m->cp_hqd_pipe_priority = 1; + m->cp_hqd_queue_priority = 15; + + *mqd = m; + if (gart_addr) + *gart_addr = addr; + retval = mm->update_mqd(mm, m, q); + + return retval; +} + +static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, + struct queue_properties *q) +{ + struct cik_mqd *m; + + BUG_ON(!mm || !q || !mqd); + + pr_debug("kfd: In func %s\n", __func__); + + m = get_mqd(mqd); + m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE | + DEFAULT_MIN_AVAIL_SIZE | + PRIV_STATE | + KMD_QUEUE; + + /* + * Calculating queue size which is log base 2 of actual queue + * size -1 dwords + */ + m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int)) + - 1 - 1; + m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); + m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8); + m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr); + m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr); + m->cp_hqd_pq_doorbell_control = DOORBELL_EN | + DOORBELL_OFFSET(q->doorbell_off); + + m->cp_hqd_vmid = q->vmid; + + m->cp_hqd_active = 0; + q->is_active = false; + if (q->queue_size > 0 && + q->queue_address != 0 && + q->queue_percent > 0) { + m->cp_hqd_active = 1; + q->is_active = true; + } + + return 0; +} + +struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type, + struct kfd_dev *dev) +{ + struct mqd_manager *mqd; + + BUG_ON(!dev); + BUG_ON(type >= KFD_MQD_TYPE_MAX); + + pr_debug("kfd: In func %s\n", __func__); + + mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL); + if (!mqd) + return NULL; + + mqd->dev = dev; + + switch (type) { + case KFD_MQD_TYPE_CIK_CP: + case KFD_MQD_TYPE_CIK_COMPUTE: + mqd->init_mqd = init_mqd; + mqd->uninit_mqd = uninit_mqd; + mqd->load_mqd = load_mqd; + mqd->update_mqd = update_mqd; + mqd->destroy_mqd = destroy_mqd; + mqd->is_occupied = is_occupied; + break; + case KFD_MQD_TYPE_CIK_HIQ: + mqd->init_mqd = init_mqd_hiq; + mqd->uninit_mqd = uninit_mqd; + mqd->load_mqd = load_mqd; + mqd->update_mqd = update_mqd_hiq; + mqd->destroy_mqd = destroy_mqd; + mqd->is_occupied = is_occupied; + break; + default: + kfree(mqd); + return NULL; + } + + return mqd; +} + +/* SDMA queues should be implemented here when the cp will supports them */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h new file mode 100644 index 000000000000..213a71e0b6c7 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h @@ -0,0 +1,91 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef KFD_MQD_MANAGER_H_ +#define KFD_MQD_MANAGER_H_ + +#include "kfd_priv.h" + +/** + * struct mqd_manager + * + * @init_mqd: Allocates the mqd buffer on local gpu memory and initialize it. + * + * @load_mqd: Loads the mqd to a concrete hqd slot. Used only for no cp + * scheduling mode. + * + * @update_mqd: Handles a update call for the MQD + * + * @destroy_mqd: Destroys the HQD slot and by that preempt the relevant queue. + * Used only for no cp scheduling. + * + * @uninit_mqd: Releases the mqd buffer from local gpu memory. + * + * @is_occupied: Checks if the relevant HQD slot is occupied. + * + * @mqd_mutex: Mqd manager mutex. + * + * @dev: The kfd device structure coupled with this module. + * + * MQD stands for Memory Queue Descriptor which represents the current queue + * state in the memory and initiate the HQD (Hardware Queue Descriptor) state. + * This structure is actually a base class for the different types of MQDs + * structures for the variant ASICs that should be supported in the future. + * This base class is also contains all the MQD specific operations. + * Another important thing to mention is that each queue has a MQD that keeps + * his state (or context) after each preemption or reassignment. + * Basically there are a instances of the mqd manager class per MQD type per + * ASIC. Currently the kfd driver supports only Kaveri so there are instances + * per KFD_MQD_TYPE for each device. + * + */ + +struct mqd_manager { + int (*init_mqd)(struct mqd_manager *mm, void **mqd, + struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr, + struct queue_properties *q); + + int (*load_mqd)(struct mqd_manager *mm, void *mqd, + uint32_t pipe_id, uint32_t queue_id, + uint32_t __user *wptr); + + int (*update_mqd)(struct mqd_manager *mm, void *mqd, + struct queue_properties *q); + + int (*destroy_mqd)(struct mqd_manager *mm, void *mqd, + enum kfd_preempt_type type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id); + + void (*uninit_mqd)(struct mqd_manager *mm, void *mqd, + struct kfd_mem_obj *mqd_mem_obj); + + bool (*is_occupied)(struct mqd_manager *mm, void *mqd, + uint64_t queue_address, uint32_t pipe_id, + uint32_t queue_id); + + struct mutex mqd_mutex; + struct kfd_dev *dev; +}; + +#endif /* KFD_MQD_MANAGER_H_ */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 5f6f13d1a20d..0eb20322f374 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -119,6 +119,11 @@ void kfd_chardev_exit(void); struct device *kfd_chardev(void); +enum kfd_preempt_type { + KFD_PREEMPT_TYPE_WAVEFRONT, + KFD_PREEMPT_TYPE_WAVEFRONT_RESET +}; + /** * enum kfd_queue_type * @@ -137,6 +142,11 @@ enum kfd_queue_type { KFD_QUEUE_TYPE_DIQ }; +enum kfd_queue_format { + KFD_QUEUE_FORMAT_PM4, + KFD_QUEUE_FORMAT_AQL +}; + /** * struct queue_properties * @@ -183,6 +193,7 @@ enum kfd_queue_type { */ struct queue_properties { enum kfd_queue_type type; + enum kfd_queue_format format; unsigned int queue_id; uint64_t queue_address; uint64_t queue_size; @@ -242,6 +253,17 @@ struct queue { struct kfd_dev *device; }; +/* + * Please read the kfd_mqd_manager.h description. + */ +enum KFD_MQD_TYPE { + KFD_MQD_TYPE_CIK_COMPUTE = 0, /* for no cp scheduling */ + KFD_MQD_TYPE_CIK_HIQ, /* for hiq */ + KFD_MQD_TYPE_CIK_CP, /* for cp queues and diq */ + KFD_MQD_TYPE_CIK_SDMA, /* for sdma queues */ + KFD_MQD_TYPE_MAX +}; + /* Data that is per-process-per device. */ struct kfd_process_device { /* -- GitLab From ed6e6a3487bd736cbcfc74fe0f9d9220bae00c72 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 00:45:35 +0300 Subject: [PATCH 0019/9457] amdkfd: Add kernel queue module The kernel queue module enables the amdkfd to establish kernel queues, not exposed to user space. The kernel queues are used for HIQ (HSA Interface Queue) and DIQ (Debug Interface Queue) operations v3: Removed use of internal typedefs and added use of the new gart allocation functions v4: Fixed a miscalculation in kernel queue wrapping v5: Move amdkfd from drm/radeon/ to drm/amd/ Change format of mqd structure to match latest KV firmware Add support for AQL queues creation to enable working with open-source HSA runtime Add define for kernel queue size Various fixes Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 3 +- .../drm/amd/amdkfd/kfd_device_queue_manager.h | 101 +++++ drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 347 +++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h | 69 +++ drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h | 405 ++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h | 107 +++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 36 +- 7 files changed, 1066 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 301e8471e636..047b834a15f2 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -6,6 +6,7 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ - kfd_process.o kfd_queue.o kfd_mqd_manager.o + kfd_process.o kfd_queue.o kfd_mqd_manager.o \ + kfd_kernel_queue.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h new file mode 100644 index 000000000000..e495b38a8cfd --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -0,0 +1,101 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef KFD_DEVICE_QUEUE_MANAGER_H_ +#define KFD_DEVICE_QUEUE_MANAGER_H_ + +#include +#include +#include "kfd_priv.h" +#include "kfd_mqd_manager.h" + +#define QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS (500) +#define QUEUES_PER_PIPE (8) +#define PIPE_PER_ME_CP_SCHEDULING (3) +#define CIK_VMID_NUM (8) +#define KFD_VMID_START_OFFSET (8) +#define VMID_PER_DEVICE CIK_VMID_NUM +#define KFD_DQM_FIRST_PIPE (0) + +struct device_process_node { + struct qcm_process_device *qpd; + struct list_head list; +}; + +struct device_queue_manager { + int (*create_queue)(struct device_queue_manager *dqm, + struct queue *q, + struct qcm_process_device *qpd, + int *allocate_vmid); + int (*destroy_queue)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q); + int (*update_queue)(struct device_queue_manager *dqm, + struct queue *q); + struct mqd_manager * (*get_mqd_manager)( + struct device_queue_manager *dqm, + enum KFD_MQD_TYPE type); + + int (*register_process)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd); + int (*unregister_process)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd); + int (*initialize)(struct device_queue_manager *dqm); + int (*start)(struct device_queue_manager *dqm); + int (*stop)(struct device_queue_manager *dqm); + void (*uninitialize)(struct device_queue_manager *dqm); + int (*create_kernel_queue)(struct device_queue_manager *dqm, + struct kernel_queue *kq, + struct qcm_process_device *qpd); + void (*destroy_kernel_queue)(struct device_queue_manager *dqm, + struct kernel_queue *kq, + struct qcm_process_device *qpd); + bool (*set_cache_memory_policy)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + enum cache_policy default_policy, + enum cache_policy alternate_policy, + void __user *alternate_aperture_base, + uint64_t alternate_aperture_size); + + + struct mqd_manager *mqds[KFD_MQD_TYPE_MAX]; + struct packet_manager packets; + struct kfd_dev *dev; + struct mutex lock; + struct list_head queues; + unsigned int processes_count; + unsigned int queue_count; + unsigned int next_pipe_to_allocate; + unsigned int *allocated_queues; + unsigned int vmid_bitmap; + uint64_t pipelines_addr; + struct kfd_mem_obj *pipeline_mem; + uint64_t fence_gpu_addr; + unsigned int *fence_addr; + struct kfd_mem_obj *fence_mem; + bool active_runlist; +}; + + + +#endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c new file mode 100644 index 000000000000..555af4514237 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -0,0 +1,347 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include +#include "kfd_kernel_queue.h" +#include "kfd_priv.h" +#include "kfd_device_queue_manager.h" +#include "kfd_pm4_headers.h" +#include "kfd_pm4_opcodes.h" + +#define PM4_COUNT_ZERO (((1 << 15) - 1) << 16) + +static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, + enum kfd_queue_type type, unsigned int queue_size) +{ + struct queue_properties prop; + int retval; + union PM4_MES_TYPE_3_HEADER nop; + + BUG_ON(!kq || !dev); + BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ); + + pr_debug("kfd: In func %s initializing queue type %d size %d\n", + __func__, KFD_QUEUE_TYPE_HIQ, queue_size); + + nop.opcode = IT_NOP; + nop.type = PM4_TYPE_3; + nop.u32all |= PM4_COUNT_ZERO; + + kq->dev = dev; + kq->nop_packet = nop.u32all; + switch (type) { + case KFD_QUEUE_TYPE_DIQ: + case KFD_QUEUE_TYPE_HIQ: + kq->mqd = dev->dqm->get_mqd_manager(dev->dqm, + KFD_MQD_TYPE_CIK_HIQ); + break; + default: + BUG(); + break; + } + + if (kq->mqd == NULL) + return false; + + prop.doorbell_ptr = + (uint32_t *)kfd_get_kernel_doorbell(dev, &prop.doorbell_off); + + if (prop.doorbell_ptr == NULL) + goto err_get_kernel_doorbell; + + retval = kfd2kgd->allocate_mem(dev->kgd, + queue_size, + PAGE_SIZE, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &kq->pq); + + if (retval != 0) + goto err_pq_allocate_vidmem; + + kq->pq_kernel_addr = kq->pq->cpu_ptr; + kq->pq_gpu_addr = kq->pq->gpu_addr; + + retval = kfd2kgd->allocate_mem(dev->kgd, + sizeof(*kq->rptr_kernel), + 32, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &kq->rptr_mem); + + if (retval != 0) + goto err_rptr_allocate_vidmem; + + kq->rptr_kernel = kq->rptr_mem->cpu_ptr; + kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr; + + retval = kfd2kgd->allocate_mem(dev->kgd, + sizeof(*kq->wptr_kernel), + 32, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &kq->wptr_mem); + + if (retval != 0) + goto err_wptr_allocate_vidmem; + + kq->wptr_kernel = kq->wptr_mem->cpu_ptr; + kq->wptr_gpu_addr = kq->wptr_mem->gpu_addr; + + memset(kq->pq_kernel_addr, 0, queue_size); + memset(kq->rptr_kernel, 0, sizeof(*kq->rptr_kernel)); + memset(kq->wptr_kernel, 0, sizeof(*kq->wptr_kernel)); + + prop.queue_size = queue_size; + prop.is_interop = false; + prop.priority = 1; + prop.queue_percent = 100; + prop.type = type; + prop.vmid = 0; + prop.queue_address = kq->pq_gpu_addr; + prop.read_ptr = (uint32_t *) kq->rptr_gpu_addr; + prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr; + + if (init_queue(&kq->queue, prop) != 0) + goto err_init_queue; + + kq->queue->device = dev; + kq->queue->process = kfd_get_process(current); + + retval = kq->mqd->init_mqd(kq->mqd, &kq->queue->mqd, + &kq->queue->mqd_mem_obj, + &kq->queue->gart_mqd_addr, + &kq->queue->properties); + if (retval != 0) + goto err_init_mqd; + + /* assign HIQ to HQD */ + if (type == KFD_QUEUE_TYPE_HIQ) { + pr_debug("assigning hiq to hqd\n"); + kq->queue->pipe = KFD_CIK_HIQ_PIPE; + kq->queue->queue = KFD_CIK_HIQ_QUEUE; + kq->mqd->load_mqd(kq->mqd, kq->queue->mqd, kq->queue->pipe, + kq->queue->queue, NULL); + } else { + /* allocate fence for DIQ */ + + retval = kfd2kgd->allocate_mem(dev->kgd, + sizeof(uint32_t), + 32, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &kq->fence_mem_obj); + + if (retval != 0) + goto err_alloc_fence; + + kq->fence_kernel_address = kq->fence_mem_obj->cpu_ptr; + kq->fence_gpu_addr = kq->fence_mem_obj->gpu_addr; + } + + print_queue(kq->queue); + + return true; +err_alloc_fence: +err_init_mqd: + uninit_queue(kq->queue); +err_init_queue: + kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->wptr_mem); +err_wptr_allocate_vidmem: + kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->rptr_mem); +err_rptr_allocate_vidmem: + kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq); +err_pq_allocate_vidmem: + pr_err("kfd: error init pq\n"); + kfd_release_kernel_doorbell(dev, (u32 *)prop.doorbell_ptr); +err_get_kernel_doorbell: + pr_err("kfd: error init doorbell"); + return false; + +} + +static void uninitialize(struct kernel_queue *kq) +{ + BUG_ON(!kq); + + if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ) + kq->mqd->destroy_mqd(kq->mqd, + NULL, + false, + QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, + kq->queue->pipe, + kq->queue->queue); + + kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->rptr_mem); + kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->wptr_mem); + kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->pq); + kfd_release_kernel_doorbell(kq->dev, + (u32 *)kq->queue->properties.doorbell_ptr); + uninit_queue(kq->queue); +} + +static int acquire_packet_buffer(struct kernel_queue *kq, + size_t packet_size_in_dwords, unsigned int **buffer_ptr) +{ + size_t available_size; + size_t queue_size_dwords; + uint32_t wptr, rptr; + unsigned int *queue_address; + + BUG_ON(!kq || !buffer_ptr); + + rptr = *kq->rptr_kernel; + wptr = *kq->wptr_kernel; + queue_address = (unsigned int *)kq->pq_kernel_addr; + queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t); + + pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n", + __func__, rptr, wptr, queue_address); + + available_size = (rptr - 1 - wptr + queue_size_dwords) % + queue_size_dwords; + + if (packet_size_in_dwords >= queue_size_dwords || + packet_size_in_dwords >= available_size) + return -ENOMEM; + + if (wptr + packet_size_in_dwords >= queue_size_dwords) { + while (wptr > 0) { + queue_address[wptr] = kq->nop_packet; + wptr = (wptr + 1) % queue_size_dwords; + } + } + + *buffer_ptr = &queue_address[wptr]; + kq->pending_wptr = wptr + packet_size_in_dwords; + + return 0; +} + +static void submit_packet(struct kernel_queue *kq) +{ +#ifdef DEBUG + int i; +#endif + + BUG_ON(!kq); + +#ifdef DEBUG + for (i = *kq->wptr_kernel; i < kq->pending_wptr; i++) { + pr_debug("0x%2X ", kq->pq_kernel_addr[i]); + if (i % 15 == 0) + pr_debug("\n"); + } + pr_debug("\n"); +#endif + + *kq->wptr_kernel = kq->pending_wptr; + write_kernel_doorbell((u32 *)kq->queue->properties.doorbell_ptr, + kq->pending_wptr); +} + +static int sync_with_hw(struct kernel_queue *kq, unsigned long timeout_ms) +{ + unsigned long org_timeout_ms; + + BUG_ON(!kq); + + org_timeout_ms = timeout_ms; + timeout_ms += jiffies * 1000 / HZ; + while (*kq->wptr_kernel != *kq->rptr_kernel) { + if (time_after(jiffies * 1000 / HZ, timeout_ms)) { + pr_err("kfd: kernel_queue %s timeout expired %lu\n", + __func__, org_timeout_ms); + pr_err("kfd: wptr: %d rptr: %d\n", + *kq->wptr_kernel, *kq->rptr_kernel); + return -ETIME; + } + cpu_relax(); + } + + return 0; +} + +static void rollback_packet(struct kernel_queue *kq) +{ + BUG_ON(!kq); + kq->pending_wptr = *kq->queue->properties.write_ptr; +} + +struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, + enum kfd_queue_type type) +{ + struct kernel_queue *kq; + + BUG_ON(!dev); + + kq = kzalloc(sizeof(struct kernel_queue), GFP_KERNEL); + if (!kq) + return NULL; + + kq->initialize = initialize; + kq->uninitialize = uninitialize; + kq->acquire_packet_buffer = acquire_packet_buffer; + kq->submit_packet = submit_packet; + kq->sync_with_hw = sync_with_hw; + kq->rollback_packet = rollback_packet; + + if (kq->initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { + pr_err("kfd: failed to init kernel queue\n"); + kfree(kq); + return NULL; + } + return kq; +} + +void kernel_queue_uninit(struct kernel_queue *kq) +{ + BUG_ON(!kq); + + kq->uninitialize(kq); + kfree(kq); +} + +void test_kq(struct kfd_dev *dev) +{ + struct kernel_queue *kq; + uint32_t *buffer, i; + int retval; + + BUG_ON(!dev); + + pr_debug("kfd: starting kernel queue test\n"); + + kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); + BUG_ON(!kq); + + retval = kq->acquire_packet_buffer(kq, 5, &buffer); + BUG_ON(retval != 0); + for (i = 0; i < 5; i++) + buffer[i] = kq->nop_packet; + kq->submit_packet(kq); + kq->sync_with_hw(kq, 1000); + + pr_debug("kfd: ending kernel queue test\n"); +} + + diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h new file mode 100644 index 000000000000..dcd2bdb68d44 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h @@ -0,0 +1,69 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef KFD_KERNEL_QUEUE_H_ +#define KFD_KERNEL_QUEUE_H_ + +#include +#include +#include "kfd_priv.h" + +struct kernel_queue { + /* interface */ + bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev, + enum kfd_queue_type type, unsigned int queue_size); + void (*uninitialize)(struct kernel_queue *kq); + int (*acquire_packet_buffer)(struct kernel_queue *kq, + size_t packet_size_in_dwords, + unsigned int **buffer_ptr); + + void (*submit_packet)(struct kernel_queue *kq); + int (*sync_with_hw)(struct kernel_queue *kq, + unsigned long timeout_ms); + void (*rollback_packet)(struct kernel_queue *kq); + + /* data */ + struct kfd_dev *dev; + struct mqd_manager *mqd; + struct queue *queue; + uint32_t pending_wptr; + unsigned int nop_packet; + + struct kfd_mem_obj *rptr_mem; + uint32_t *rptr_kernel; + uint64_t rptr_gpu_addr; + struct kfd_mem_obj *wptr_mem; + uint32_t *wptr_kernel; + uint64_t wptr_gpu_addr; + struct kfd_mem_obj *pq; + uint64_t pq_gpu_addr; + uint32_t *pq_kernel_addr; + + struct kfd_mem_obj *fence_mem_obj; + uint64_t fence_gpu_addr; + void *fence_kernel_address; + + struct list_head list; +}; + +#endif /* KFD_KERNEL_QUEUE_H_ */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h new file mode 100644 index 000000000000..071ad5724bd2 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h @@ -0,0 +1,405 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef KFD_PM4_HEADERS_H_ +#define KFD_PM4_HEADERS_H_ + +#ifndef PM4_MES_HEADER_DEFINED +#define PM4_MES_HEADER_DEFINED +union PM4_MES_TYPE_3_HEADER { + struct { + uint32_t reserved1:8; /* < reserved */ + uint32_t opcode:8; /* < IT opcode */ + uint32_t count:14; /* < number of DWORDs - 1 + * in the information body. + */ + uint32_t type:2; /* < packet identifier. + * It should be 3 for type 3 packets + */ + }; + uint32_t u32all; +}; +#endif /* PM4_MES_HEADER_DEFINED */ + +/* --------------------MES_SET_RESOURCES-------------------- */ + +#ifndef PM4_MES_SET_RESOURCES_DEFINED +#define PM4_MES_SET_RESOURCES_DEFINED +enum set_resources_queue_type_enum { + queue_type__mes_set_resources__kernel_interface_queue_kiq = 0, + queue_type__mes_set_resources__hsa_interface_queue_hiq = 1, + queue_type__mes_set_resources__hsa_debug_interface_queue = 4 +}; + +struct pm4_set_resources { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + uint32_t vmid_mask:16; + uint32_t unmap_latency:8; + uint32_t reserved1:5; + enum set_resources_queue_type_enum queue_type:3; + } bitfields2; + uint32_t ordinal2; + }; + + uint32_t queue_mask_lo; + uint32_t queue_mask_hi; + uint32_t gws_mask_lo; + uint32_t gws_mask_hi; + + union { + struct { + uint32_t oac_mask:16; + uint32_t reserved2:16; + } bitfields7; + uint32_t ordinal7; + }; + + union { + struct { + uint32_t gds_heap_base:6; + uint32_t reserved3:5; + uint32_t gds_heap_size:6; + uint32_t reserved4:15; + } bitfields8; + uint32_t ordinal8; + }; + +}; +#endif + +/*--------------------MES_RUN_LIST-------------------- */ + +#ifndef PM4_MES_RUN_LIST_DEFINED +#define PM4_MES_RUN_LIST_DEFINED + +struct pm4_runlist { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + uint32_t reserved1:2; + uint32_t ib_base_lo:30; + } bitfields2; + uint32_t ordinal2; + }; + + union { + struct { + uint32_t ib_base_hi:16; + uint32_t reserved2:16; + } bitfields3; + uint32_t ordinal3; + }; + + union { + struct { + uint32_t ib_size:20; + uint32_t chain:1; + uint32_t offload_polling:1; + uint32_t reserved3:1; + uint32_t valid:1; + uint32_t reserved4:8; + } bitfields4; + uint32_t ordinal4; + }; + +}; +#endif + +/*--------------------MES_MAP_PROCESS-------------------- */ + +#ifndef PM4_MES_MAP_PROCESS_DEFINED +#define PM4_MES_MAP_PROCESS_DEFINED + +struct pm4_map_process { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + uint32_t pasid:16; + uint32_t reserved1:8; + uint32_t diq_enable:1; + uint32_t process_quantum:7; + } bitfields2; + uint32_t ordinal2; + }; + + union { + struct { + uint32_t page_table_base:28; + uint32_t reserved3:4; + } bitfields3; + uint32_t ordinal3; + }; + + uint32_t sh_mem_bases; + uint32_t sh_mem_ape1_base; + uint32_t sh_mem_ape1_limit; + uint32_t sh_mem_config; + uint32_t gds_addr_lo; + uint32_t gds_addr_hi; + + union { + struct { + uint32_t num_gws:6; + uint32_t reserved4:2; + uint32_t num_oac:4; + uint32_t reserved5:4; + uint32_t gds_size:6; + uint32_t num_queues:10; + } bitfields10; + uint32_t ordinal10; + }; + +}; +#endif + +/*--------------------MES_MAP_QUEUES--------------------*/ + +#ifndef PM4_MES_MAP_QUEUES_DEFINED +#define PM4_MES_MAP_QUEUES_DEFINED +enum map_queues_queue_sel_enum { + queue_sel__mes_map_queues__map_to_specified_queue_slots = 0, + queue_sel__mes_map_queues__map_to_hws_determined_queue_slots = 1, + queue_sel__mes_map_queues__enable_process_queues = 2 +}; + +enum map_queues_vidmem_enum { + vidmem__mes_map_queues__uses_no_video_memory = 0, + vidmem__mes_map_queues__uses_video_memory = 1 +}; + +enum map_queues_alloc_format_enum { + alloc_format__mes_map_queues__one_per_pipe = 0, + alloc_format__mes_map_queues__all_on_one_pipe = 1 +}; + +enum map_queues_engine_sel_enum { + engine_sel__mes_map_queues__compute = 0, + engine_sel__mes_map_queues__sdma0 = 2, + engine_sel__mes_map_queues__sdma1 = 3 +}; + +struct pm4_map_queues { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + uint32_t reserved1:4; + enum map_queues_queue_sel_enum queue_sel:2; + uint32_t reserved2:2; + uint32_t vmid:4; + uint32_t reserved3:4; + enum map_queues_vidmem_enum vidmem:2; + uint32_t reserved4:6; + enum map_queues_alloc_format_enum alloc_format:2; + enum map_queues_engine_sel_enum engine_sel:3; + uint32_t num_queues:3; + } bitfields2; + uint32_t ordinal2; + }; + + struct { + union { + struct { + uint32_t reserved5:2; + uint32_t doorbell_offset:21; + uint32_t reserved6:3; + uint32_t queue:6; + } bitfields3; + uint32_t ordinal3; + }; + + uint32_t mqd_addr_lo; + uint32_t mqd_addr_hi; + uint32_t wptr_addr_lo; + uint32_t wptr_addr_hi; + + } mes_map_queues_ordinals[1]; /* 1..N of these ordinal groups */ + +}; +#endif + +/*--------------------MES_QUERY_STATUS--------------------*/ + +#ifndef PM4_MES_QUERY_STATUS_DEFINED +#define PM4_MES_QUERY_STATUS_DEFINED +enum query_status_interrupt_sel_enum { + interrupt_sel__mes_query_status__completion_status = 0, + interrupt_sel__mes_query_status__process_status = 1, + interrupt_sel__mes_query_status__queue_status = 2 +}; + +enum query_status_command_enum { + command__mes_query_status__interrupt_only = 0, + command__mes_query_status__fence_only_immediate = 1, + command__mes_query_status__fence_only_after_write_ack = 2, + command__mes_query_status__fence_wait_for_write_ack_send_interrupt = 3 +}; + +enum query_status_engine_sel_enum { + engine_sel__mes_query_status__compute = 0, + engine_sel__mes_query_status__sdma0_queue = 2, + engine_sel__mes_query_status__sdma1_queue = 3 +}; + +struct pm4_query_status { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + uint32_t context_id:28; + enum query_status_interrupt_sel_enum interrupt_sel:2; + enum query_status_command_enum command:2; + } bitfields2; + uint32_t ordinal2; + }; + + union { + struct { + uint32_t pasid:16; + uint32_t reserved1:16; + } bitfields3a; + struct { + uint32_t reserved2:2; + uint32_t doorbell_offset:21; + uint32_t reserved3:3; + enum query_status_engine_sel_enum engine_sel:3; + uint32_t reserved4:3; + } bitfields3b; + uint32_t ordinal3; + }; + + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t data_lo; + uint32_t data_hi; +}; +#endif + +/*--------------------MES_UNMAP_QUEUES--------------------*/ + +#ifndef PM4_MES_UNMAP_QUEUES_DEFINED +#define PM4_MES_UNMAP_QUEUES_DEFINED +enum unmap_queues_action_enum { + action__mes_unmap_queues__preempt_queues = 0, + action__mes_unmap_queues__reset_queues = 1, + action__mes_unmap_queues__disable_process_queues = 2 +}; + +enum unmap_queues_queue_sel_enum { + queue_sel__mes_unmap_queues__perform_request_on_specified_queues = 0, + queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = 1, + queue_sel__mes_unmap_queues__perform_request_on_all_active_queues = 2 +}; + +enum unmap_queues_engine_sel_enum { + engine_sel__mes_unmap_queues__compute = 0, + engine_sel__mes_unmap_queues__sdma0 = 2, + engine_sel__mes_unmap_queues__sdma1 = 3 +}; + +struct pm4_unmap_queues { + union { + union PM4_MES_TYPE_3_HEADER header; /* header */ + uint32_t ordinal1; + }; + + union { + struct { + enum unmap_queues_action_enum action:2; + uint32_t reserved1:2; + enum unmap_queues_queue_sel_enum queue_sel:2; + uint32_t reserved2:20; + enum unmap_queues_engine_sel_enum engine_sel:3; + uint32_t num_queues:3; + } bitfields2; + uint32_t ordinal2; + }; + + union { + struct { + uint32_t pasid:16; + uint32_t reserved3:16; + } bitfields3a; + struct { + uint32_t reserved4:2; + uint32_t doorbell_offset0:21; + uint32_t reserved5:9; + } bitfields3b; + uint32_t ordinal3; + }; + + union { + struct { + uint32_t reserved6:2; + uint32_t doorbell_offset1:21; + uint32_t reserved7:9; + } bitfields4; + uint32_t ordinal4; + }; + + union { + struct { + uint32_t reserved8:2; + uint32_t doorbell_offset2:21; + uint32_t reserved9:9; + } bitfields5; + uint32_t ordinal5; + }; + + union { + struct { + uint32_t reserved10:2; + uint32_t doorbell_offset3:21; + uint32_t reserved11:9; + } bitfields6; + uint32_t ordinal6; + }; + +}; +#endif + +enum { + CACHE_FLUSH_AND_INV_TS_EVENT = 0x00000014 +}; + +#endif /* KFD_PM4_HEADERS_H_ */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h new file mode 100644 index 000000000000..b72fa3b8c2d4 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h @@ -0,0 +1,107 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#ifndef KFD_PM4_OPCODES_H +#define KFD_PM4_OPCODES_H + +enum it_opcode_type { + IT_NOP = 0x10, + IT_SET_BASE = 0x11, + IT_CLEAR_STATE = 0x12, + IT_INDEX_BUFFER_SIZE = 0x13, + IT_DISPATCH_DIRECT = 0x15, + IT_DISPATCH_INDIRECT = 0x16, + IT_ATOMIC_GDS = 0x1D, + IT_OCCLUSION_QUERY = 0x1F, + IT_SET_PREDICATION = 0x20, + IT_REG_RMW = 0x21, + IT_COND_EXEC = 0x22, + IT_PRED_EXEC = 0x23, + IT_DRAW_INDIRECT = 0x24, + IT_DRAW_INDEX_INDIRECT = 0x25, + IT_INDEX_BASE = 0x26, + IT_DRAW_INDEX_2 = 0x27, + IT_CONTEXT_CONTROL = 0x28, + IT_INDEX_TYPE = 0x2A, + IT_DRAW_INDIRECT_MULTI = 0x2C, + IT_DRAW_INDEX_AUTO = 0x2D, + IT_NUM_INSTANCES = 0x2F, + IT_DRAW_INDEX_MULTI_AUTO = 0x30, + IT_INDIRECT_BUFFER_CNST = 0x33, + IT_STRMOUT_BUFFER_UPDATE = 0x34, + IT_DRAW_INDEX_OFFSET_2 = 0x35, + IT_DRAW_PREAMBLE = 0x36, + IT_WRITE_DATA = 0x37, + IT_DRAW_INDEX_INDIRECT_MULTI = 0x38, + IT_MEM_SEMAPHORE = 0x39, + IT_COPY_DW = 0x3B, + IT_WAIT_REG_MEM = 0x3C, + IT_INDIRECT_BUFFER = 0x3F, + IT_COPY_DATA = 0x40, + IT_PFP_SYNC_ME = 0x42, + IT_SURFACE_SYNC = 0x43, + IT_COND_WRITE = 0x45, + IT_EVENT_WRITE = 0x46, + IT_EVENT_WRITE_EOP = 0x47, + IT_EVENT_WRITE_EOS = 0x48, + IT_RELEASE_MEM = 0x49, + IT_PREAMBLE_CNTL = 0x4A, + IT_DMA_DATA = 0x50, + IT_ACQUIRE_MEM = 0x58, + IT_REWIND = 0x59, + IT_LOAD_UCONFIG_REG = 0x5E, + IT_LOAD_SH_REG = 0x5F, + IT_LOAD_CONFIG_REG = 0x60, + IT_LOAD_CONTEXT_REG = 0x61, + IT_SET_CONFIG_REG = 0x68, + IT_SET_CONTEXT_REG = 0x69, + IT_SET_CONTEXT_REG_INDIRECT = 0x73, + IT_SET_SH_REG = 0x76, + IT_SET_SH_REG_OFFSET = 0x77, + IT_SET_QUEUE_REG = 0x78, + IT_SET_UCONFIG_REG = 0x79, + IT_SCRATCH_RAM_WRITE = 0x7D, + IT_SCRATCH_RAM_READ = 0x7E, + IT_LOAD_CONST_RAM = 0x80, + IT_WRITE_CONST_RAM = 0x81, + IT_DUMP_CONST_RAM = 0x83, + IT_INCREMENT_CE_COUNTER = 0x84, + IT_INCREMENT_DE_COUNTER = 0x85, + IT_WAIT_ON_CE_COUNTER = 0x86, + IT_WAIT_ON_DE_COUNTER_DIFF = 0x88, + IT_SWITCH_BUFFER = 0x8B, + IT_SET_RESOURCES = 0xA0, + IT_MAP_PROCESS = 0xA1, + IT_MAP_QUEUES = 0xA2, + IT_UNMAP_QUEUES = 0xA3, + IT_QUERY_STATUS = 0xA4, + IT_RUN_LIST = 0xA5, +}; + +#define PM4_TYPE_0 0 +#define PM4_TYPE_2 2 +#define PM4_TYPE_3 3 + +#endif /* KFD_PM4_OPCODES_H */ + diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 0eb20322f374..bba3c2ada261 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -35,6 +35,16 @@ #define KFD_SYSFS_FILE_MODE 0444 +/* + * When working with cp scheduler we should assign the HIQ manually or via + * the radeon driver to a fixed hqd slot, here are the fixed HIQ hqd slot + * definitions for Kaveri. In Kaveri only the first ME queues participates + * in the cp scheduling taking that in mind we set the HIQ slot in the + * second ME. + */ +#define KFD_CIK_HIQ_PIPE 4 +#define KFD_CIK_HIQ_QUEUE 0 + /* GPU ID hash width in bits */ #define KFD_GPU_ID_HASH_WIDTH 16 @@ -57,6 +67,13 @@ extern int max_num_of_queues_per_process; #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128 #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 +#define KFD_KERNEL_QUEUE_SIZE 2048 + +enum cache_policy { + cache_policy_coherent, + cache_policy_noncoherent +}; + struct kfd_device_info { unsigned int max_pasid_bits; size_t ih_ring_entry_size; @@ -88,8 +105,10 @@ struct kfd_dev { struct kgd2kfd_shared_resources shared_resources; - bool init_complete; + /* QCM Device instance */ + struct device_queue_manager *dqm; + bool init_complete; }; /* KGD2KFD callbacks */ @@ -384,6 +403,21 @@ int kgd2kfd_resume(struct kfd_dev *dev); /* amdkfd Apertures */ int kfd_init_apertures(struct kfd_process *process); +/* Queue Context Management */ +int init_queue(struct queue **q, struct queue_properties properties); +void uninit_queue(struct queue *q); +void print_queue(struct queue *q); + +/* Packet Manager */ + +struct packet_manager { + struct device_queue_manager *dqm; + struct kernel_queue *priv_queue; + struct mutex lock; + bool allocated; + struct kfd_mem_obj *ib_buffer_obj; +}; + uint64_t kfd_get_number_elems(struct kfd_dev *kfd); phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, struct kfd_process *process); -- GitLab From 31c21fece7a5f279ebdd1ee260493450017183f4 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 00:48:28 +0300 Subject: [PATCH 0020/9457] amdkfd: Add module parameter of scheduling policy This patch adds a new parameter to the amdkfd driver. This parameter enables the user to select the scheduling policy of the CP. The choices are: * CP Scheduling with support for over-subscription * CP Scheduling without support for over-subscription * Without CP Scheduling Note that the third option (Without CP scheduling) is only for debug purposes and bringup of new H/W. As such, it is _not_ guaranteed to work at all times on all H/W versions. v3: Fixed description of parameter, changed the permissions to read_only, added a verification of the value and added documentation v5: Set default sched_policy to HWS as it is now supported by firmware Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_module.c | 12 ++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 30 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index a05116b0a07d..95d5af138e6e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -45,6 +45,11 @@ static const struct kgd2kfd_calls kgd2kfd = { .resume = kgd2kfd_resume, }; +int sched_policy = KFD_SCHED_POLICY_HWS; +module_param(sched_policy, int, 0444); +MODULE_PARM_DESC(sched_policy, + "Kernel cmdline parameter that defines the amdkfd scheduling policy"); + int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT; module_param(max_num_of_processes, int, 0444); MODULE_PARM_DESC(max_num_of_processes, @@ -87,6 +92,13 @@ static int __init kfd_module_init(void) kfd2kgd = NULL; + /* Verify module parameters */ + if ((sched_policy < KFD_SCHED_POLICY_HWS) || + (sched_policy > KFD_SCHED_POLICY_NO_HWS)) { + pr_err("kfd: sched_policy has invalid value\n"); + return -1; + } + /* Verify module parameters */ if ((max_num_of_processes < 0) || (max_num_of_processes > KFD_MAX_NUM_OF_PROCESSES)) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index bba3c2ada261..32bca8a67423 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -69,6 +69,36 @@ extern int max_num_of_queues_per_process; #define KFD_KERNEL_QUEUE_SIZE 2048 +/* Kernel module parameter to specify the scheduling policy */ +extern int sched_policy; + +/** + * enum kfd_sched_policy + * + * @KFD_SCHED_POLICY_HWS: H/W scheduling policy known as command processor (cp) + * scheduling. In this scheduling mode we're using the firmware code to + * schedule the user mode queues and kernel queues such as HIQ and DIQ. + * the HIQ queue is used as a special queue that dispatches the configuration + * to the cp and the user mode queues list that are currently running. + * the DIQ queue is a debugging queue that dispatches debugging commands to the + * firmware. + * in this scheduling mode user mode queues over subscription feature is + * enabled. + * + * @KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION: The same as above but the over + * subscription feature disabled. + * + * @KFD_SCHED_POLICY_NO_HWS: no H/W scheduling policy is a mode which directly + * set the command processor registers and sets the queues "manually". This + * mode is used *ONLY* for debugging proposes. + * + */ +enum kfd_sched_policy { + KFD_SCHED_POLICY_HWS = 0, + KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION, + KFD_SCHED_POLICY_NO_HWS +}; + enum cache_policy { cache_policy_coherent, cache_policy_noncoherent -- GitLab From 241f24f823631ced1c6f162db1deebc35037f7d0 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 00:55:28 +0300 Subject: [PATCH 0021/9457] amdkfd: Add packet manager module The packet manager module builds PM4 packets for the sole use of the CP scheduler. Those packets are used by the HIQ to submit runlists to the CP. v3: Removed include of cik_mqds.h Changed lower_32/upper_32 calls to use linux macros Used new gart allocation functions Added documentation v5: Move amdkfd from drm/radeon/ to drm/amd/ Change format of mqd structure to match latest KV firmware Add support for AQL queues creation to enable working with open-source HSA runtime Always chain runlist if you have more than 1 process or if you have over-subscription over the number of queues. Various fixes (typos, style) Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- .../gpu/drm/amd/amdkfd/kfd_packet_manager.c | 565 ++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 75 +++ 3 files changed, 641 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 047b834a15f2..1164a3a0a7f2 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -7,6 +7,6 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ - kfd_kernel_queue.o + kfd_kernel_queue.o kfd_packet_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c new file mode 100644 index 000000000000..5ce9233d2004 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -0,0 +1,565 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include "kfd_device_queue_manager.h" +#include "kfd_kernel_queue.h" +#include "kfd_priv.h" +#include "kfd_pm4_headers.h" +#include "kfd_pm4_opcodes.h" + +static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes, + unsigned int buffer_size_bytes) +{ + unsigned int temp = *wptr + increment_bytes / sizeof(uint32_t); + + BUG_ON((temp * sizeof(uint32_t)) > buffer_size_bytes); + *wptr = temp; +} + +static unsigned int build_pm4_header(unsigned int opcode, size_t packet_size) +{ + union PM4_MES_TYPE_3_HEADER header; + + header.u32all = 0; + header.opcode = opcode; + header.count = packet_size/sizeof(uint32_t) - 2; + header.type = PM4_TYPE_3; + + return header.u32all; +} + +static void pm_calc_rlib_size(struct packet_manager *pm, + unsigned int *rlib_size, + bool *over_subscription) +{ + unsigned int process_count, queue_count; + + BUG_ON(!pm || !rlib_size || !over_subscription); + + process_count = pm->dqm->processes_count; + queue_count = pm->dqm->queue_count; + + /* check if there is over subscription*/ + *over_subscription = false; + if ((process_count > 1) || + queue_count > PIPE_PER_ME_CP_SCHEDULING * QUEUES_PER_PIPE) { + *over_subscription = true; + pr_debug("kfd: over subscribed runlist\n"); + } + + /* calculate run list ib allocation size */ + *rlib_size = process_count * sizeof(struct pm4_map_process) + + queue_count * sizeof(struct pm4_map_queues); + + /* + * Increase the allocation size in case we need a chained run list + * when over subscription + */ + if (*over_subscription) + *rlib_size += sizeof(struct pm4_runlist); + + pr_debug("kfd: runlist ib size %d\n", *rlib_size); +} + +static int pm_allocate_runlist_ib(struct packet_manager *pm, + unsigned int **rl_buffer, + uint64_t *rl_gpu_buffer, + unsigned int *rl_buffer_size, + bool *is_over_subscription) +{ + int retval; + + BUG_ON(!pm); + BUG_ON(pm->allocated == true); + BUG_ON(is_over_subscription == NULL); + + pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription); + + retval = kfd2kgd->allocate_mem(pm->dqm->dev->kgd, + *rl_buffer_size, + PAGE_SIZE, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &pm->ib_buffer_obj); + + if (retval != 0) { + pr_err("kfd: failed to allocate runlist IB\n"); + return retval; + } + + *(void **)rl_buffer = pm->ib_buffer_obj->cpu_ptr; + *rl_gpu_buffer = pm->ib_buffer_obj->gpu_addr; + + memset(*rl_buffer, 0, *rl_buffer_size); + pm->allocated = true; + return retval; +} + +static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer, + uint64_t ib, size_t ib_size_in_dwords, bool chain) +{ + struct pm4_runlist *packet; + + BUG_ON(!pm || !buffer || !ib); + + packet = (struct pm4_runlist *)buffer; + + memset(buffer, 0, sizeof(struct pm4_runlist)); + packet->header.u32all = build_pm4_header(IT_RUN_LIST, + sizeof(struct pm4_runlist)); + + packet->bitfields4.ib_size = ib_size_in_dwords; + packet->bitfields4.chain = chain ? 1 : 0; + packet->bitfields4.offload_polling = 0; + packet->bitfields4.valid = 1; + packet->ordinal2 = lower_32_bits(ib); + packet->bitfields3.ib_base_hi = upper_32_bits(ib); + + return 0; +} + +static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer, + struct qcm_process_device *qpd) +{ + struct pm4_map_process *packet; + struct queue *cur; + uint32_t num_queues; + + BUG_ON(!pm || !buffer || !qpd); + + packet = (struct pm4_map_process *)buffer; + + pr_debug("kfd: In func %s\n", __func__); + + memset(buffer, 0, sizeof(struct pm4_map_process)); + + packet->header.u32all = build_pm4_header(IT_MAP_PROCESS, + sizeof(struct pm4_map_process)); + packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0; + packet->bitfields2.process_quantum = 1; + packet->bitfields2.pasid = qpd->pqm->process->pasid; + packet->bitfields3.page_table_base = qpd->page_table_base; + packet->bitfields10.gds_size = qpd->gds_size; + packet->bitfields10.num_gws = qpd->num_gws; + packet->bitfields10.num_oac = qpd->num_oac; + num_queues = 0; + list_for_each_entry(cur, &qpd->queues_list, list) + num_queues++; + packet->bitfields10.num_queues = num_queues; + + packet->sh_mem_config = qpd->sh_mem_config; + packet->sh_mem_bases = qpd->sh_mem_bases; + packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base; + packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit; + + packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area); + packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area); + + return 0; +} + +static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer, + struct queue *q) +{ + struct pm4_map_queues *packet; + + BUG_ON(!pm || !buffer || !q); + + pr_debug("kfd: In func %s\n", __func__); + + packet = (struct pm4_map_queues *)buffer; + memset(buffer, 0, sizeof(struct pm4_map_queues)); + + packet->header.u32all = build_pm4_header(IT_MAP_QUEUES, + sizeof(struct pm4_map_queues)); + packet->bitfields2.alloc_format = + alloc_format__mes_map_queues__one_per_pipe; + packet->bitfields2.num_queues = 1; + packet->bitfields2.queue_sel = + queue_sel__mes_map_queues__map_to_hws_determined_queue_slots; + + packet->bitfields2.vidmem = (q->properties.is_interop) ? + vidmem__mes_map_queues__uses_video_memory : + vidmem__mes_map_queues__uses_no_video_memory; + + switch (q->properties.type) { + case KFD_QUEUE_TYPE_COMPUTE: + case KFD_QUEUE_TYPE_DIQ: + packet->bitfields2.engine_sel = + engine_sel__mes_map_queues__compute; + break; + case KFD_QUEUE_TYPE_SDMA: + packet->bitfields2.engine_sel = + engine_sel__mes_map_queues__sdma0; + break; + default: + BUG(); + break; + } + + packet->mes_map_queues_ordinals[0].bitfields3.doorbell_offset = + q->properties.doorbell_off; + + packet->mes_map_queues_ordinals[0].mqd_addr_lo = + lower_32_bits(q->gart_mqd_addr); + + packet->mes_map_queues_ordinals[0].mqd_addr_hi = + upper_32_bits(q->gart_mqd_addr); + + packet->mes_map_queues_ordinals[0].wptr_addr_lo = + lower_32_bits((uint64_t)q->properties.write_ptr); + + packet->mes_map_queues_ordinals[0].wptr_addr_hi = + upper_32_bits((uint64_t)q->properties.write_ptr); + + return 0; +} + +static int pm_create_runlist_ib(struct packet_manager *pm, + struct list_head *queues, + uint64_t *rl_gpu_addr, + size_t *rl_size_bytes) +{ + unsigned int alloc_size_bytes; + unsigned int *rl_buffer, rl_wptr, i; + int retval, proccesses_mapped; + struct device_process_node *cur; + struct qcm_process_device *qpd; + struct queue *q; + struct kernel_queue *kq; + bool is_over_subscription; + + BUG_ON(!pm || !queues || !rl_size_bytes || !rl_gpu_addr); + + rl_wptr = retval = proccesses_mapped = 0; + + retval = pm_allocate_runlist_ib(pm, &rl_buffer, rl_gpu_addr, + &alloc_size_bytes, &is_over_subscription); + if (retval != 0) + return retval; + + *rl_size_bytes = alloc_size_bytes; + + pr_debug("kfd: In func %s\n", __func__); + pr_debug("kfd: building runlist ib process count: %d queues count %d\n", + pm->dqm->processes_count, pm->dqm->queue_count); + + /* build the run list ib packet */ + list_for_each_entry(cur, queues, list) { + qpd = cur->qpd; + /* build map process packet */ + if (proccesses_mapped >= pm->dqm->processes_count) { + pr_debug("kfd: not enough space left in runlist IB\n"); + pm_release_ib(pm); + return -ENOMEM; + } + retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd); + if (retval != 0) + return retval; + proccesses_mapped++; + inc_wptr(&rl_wptr, sizeof(struct pm4_map_process), + alloc_size_bytes); + + list_for_each_entry(kq, &qpd->priv_queue_list, list) { + if (kq->queue->properties.is_active != true) + continue; + retval = pm_create_map_queue(pm, &rl_buffer[rl_wptr], + kq->queue); + if (retval != 0) + return retval; + inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues), + alloc_size_bytes); + } + + list_for_each_entry(q, &qpd->queues_list, list) { + if (q->properties.is_active != true) + continue; + retval = pm_create_map_queue(pm, + &rl_buffer[rl_wptr], q); + if (retval != 0) + return retval; + inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues), + alloc_size_bytes); + } + } + + pr_debug("kfd: finished map process and queues to runlist\n"); + + if (is_over_subscription) + pm_create_runlist(pm, &rl_buffer[rl_wptr], *rl_gpu_addr, + alloc_size_bytes / sizeof(uint32_t), true); + + for (i = 0; i < alloc_size_bytes / sizeof(uint32_t); i++) + pr_debug("0x%2X ", rl_buffer[i]); + pr_debug("\n"); + + return 0; +} + +int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) +{ + BUG_ON(!dqm); + + pm->dqm = dqm; + mutex_init(&pm->lock); + pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ); + if (pm->priv_queue == NULL) { + mutex_destroy(&pm->lock); + return -ENOMEM; + } + pm->allocated = false; + + return 0; +} + +void pm_uninit(struct packet_manager *pm) +{ + BUG_ON(!pm); + + mutex_destroy(&pm->lock); + kernel_queue_uninit(pm->priv_queue); +} + +int pm_send_set_resources(struct packet_manager *pm, + struct scheduling_resources *res) +{ + struct pm4_set_resources *packet; + + BUG_ON(!pm || !res); + + pr_debug("kfd: In func %s\n", __func__); + + mutex_lock(&pm->lock); + pm->priv_queue->acquire_packet_buffer(pm->priv_queue, + sizeof(*packet) / sizeof(uint32_t), + (unsigned int **)&packet); + if (packet == NULL) { + mutex_unlock(&pm->lock); + pr_err("kfd: failed to allocate buffer on kernel queue\n"); + return -ENOMEM; + } + + memset(packet, 0, sizeof(struct pm4_set_resources)); + packet->header.u32all = build_pm4_header(IT_SET_RESOURCES, + sizeof(struct pm4_set_resources)); + + packet->bitfields2.queue_type = + queue_type__mes_set_resources__hsa_interface_queue_hiq; + packet->bitfields2.vmid_mask = res->vmid_mask; + packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY; + packet->bitfields7.oac_mask = res->oac_mask; + packet->bitfields8.gds_heap_base = res->gds_heap_base; + packet->bitfields8.gds_heap_size = res->gds_heap_size; + + packet->gws_mask_lo = lower_32_bits(res->gws_mask); + packet->gws_mask_hi = upper_32_bits(res->gws_mask); + + packet->queue_mask_lo = lower_32_bits(res->queue_mask); + packet->queue_mask_hi = upper_32_bits(res->queue_mask); + + pm->priv_queue->submit_packet(pm->priv_queue); + pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); + + mutex_unlock(&pm->lock); + + return 0; +} + +int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues) +{ + uint64_t rl_gpu_ib_addr; + uint32_t *rl_buffer; + size_t rl_ib_size, packet_size_dwords; + int retval; + + BUG_ON(!pm || !dqm_queues); + + retval = pm_create_runlist_ib(pm, dqm_queues, &rl_gpu_ib_addr, + &rl_ib_size); + if (retval != 0) + goto fail_create_runlist_ib; + + pr_debug("kfd: runlist IB address: 0x%llX\n", rl_gpu_ib_addr); + + packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t); + mutex_lock(&pm->lock); + + retval = pm->priv_queue->acquire_packet_buffer(pm->priv_queue, + packet_size_dwords, &rl_buffer); + if (retval != 0) + goto fail_acquire_packet_buffer; + + retval = pm_create_runlist(pm, rl_buffer, rl_gpu_ib_addr, + rl_ib_size / sizeof(uint32_t), false); + if (retval != 0) + goto fail_create_runlist; + + pm->priv_queue->submit_packet(pm->priv_queue); + pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); + + mutex_unlock(&pm->lock); + + return retval; + +fail_create_runlist: + pm->priv_queue->rollback_packet(pm->priv_queue); +fail_acquire_packet_buffer: + mutex_unlock(&pm->lock); +fail_create_runlist_ib: + if (pm->allocated == true) + pm_release_ib(pm); + return retval; +} + +int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, + uint32_t fence_value) +{ + int retval; + struct pm4_query_status *packet; + + BUG_ON(!pm || !fence_address); + + mutex_lock(&pm->lock); + retval = pm->priv_queue->acquire_packet_buffer( + pm->priv_queue, + sizeof(struct pm4_query_status) / sizeof(uint32_t), + (unsigned int **)&packet); + if (retval != 0) + goto fail_acquire_packet_buffer; + + packet->header.u32all = build_pm4_header(IT_QUERY_STATUS, + sizeof(struct pm4_query_status)); + + packet->bitfields2.context_id = 0; + packet->bitfields2.interrupt_sel = + interrupt_sel__mes_query_status__completion_status; + packet->bitfields2.command = + command__mes_query_status__fence_only_after_write_ack; + + packet->addr_hi = upper_32_bits((uint64_t)fence_address); + packet->addr_lo = lower_32_bits((uint64_t)fence_address); + packet->data_hi = upper_32_bits((uint64_t)fence_value); + packet->data_lo = lower_32_bits((uint64_t)fence_value); + + pm->priv_queue->submit_packet(pm->priv_queue); + pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); + mutex_unlock(&pm->lock); + + return 0; + +fail_acquire_packet_buffer: + mutex_unlock(&pm->lock); + return retval; +} + +int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, + enum kfd_preempt_type_filter mode, + uint32_t filter_param, bool reset, + unsigned int sdma_engine) +{ + int retval; + uint32_t *buffer; + struct pm4_unmap_queues *packet; + + BUG_ON(!pm); + + mutex_lock(&pm->lock); + retval = pm->priv_queue->acquire_packet_buffer( + pm->priv_queue, + sizeof(struct pm4_unmap_queues) / sizeof(uint32_t), + &buffer); + if (retval != 0) + goto err_acquire_packet_buffer; + + packet = (struct pm4_unmap_queues *)buffer; + memset(buffer, 0, sizeof(struct pm4_unmap_queues)); + + packet->header.u32all = build_pm4_header(IT_UNMAP_QUEUES, + sizeof(struct pm4_unmap_queues)); + switch (type) { + case KFD_QUEUE_TYPE_COMPUTE: + case KFD_QUEUE_TYPE_DIQ: + packet->bitfields2.engine_sel = + engine_sel__mes_unmap_queues__compute; + break; + case KFD_QUEUE_TYPE_SDMA: + packet->bitfields2.engine_sel = + engine_sel__mes_unmap_queues__sdma0 + sdma_engine; + break; + default: + BUG(); + break; + } + + if (reset) + packet->bitfields2.action = + action__mes_unmap_queues__reset_queues; + else + packet->bitfields2.action = + action__mes_unmap_queues__preempt_queues; + + switch (mode) { + case KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE: + packet->bitfields2.queue_sel = + queue_sel__mes_unmap_queues__perform_request_on_specified_queues; + packet->bitfields2.num_queues = 1; + packet->bitfields3b.doorbell_offset0 = filter_param; + break; + case KFD_PREEMPT_TYPE_FILTER_BY_PASID: + packet->bitfields2.queue_sel = + queue_sel__mes_unmap_queues__perform_request_on_pasid_queues; + packet->bitfields3a.pasid = filter_param; + break; + case KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES: + packet->bitfields2.queue_sel = + queue_sel__mes_unmap_queues__perform_request_on_all_active_queues; + break; + default: + BUG(); + break; + }; + + pm->priv_queue->submit_packet(pm->priv_queue); + pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT); + + mutex_unlock(&pm->lock); + return 0; + +err_acquire_packet_buffer: + mutex_unlock(&pm->lock); + return retval; +} + +void pm_release_ib(struct packet_manager *pm) +{ + BUG_ON(!pm); + + mutex_lock(&pm->lock); + if (pm->allocated) { + kfd2kgd->free_mem(pm->dqm->dev->kgd, + (struct kgd_mem *) pm->ib_buffer_obj); + pm->allocated = false; + } + mutex_unlock(&pm->lock); +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 32bca8a67423..219c85a261c3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -167,6 +167,23 @@ int kfd_chardev_init(void); void kfd_chardev_exit(void); struct device *kfd_chardev(void); +/** + * enum kfd_preempt_type_filter + * + * @KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE: Preempts single queue. + * + * @KFD_PRERMPT_TYPE_FILTER_ALL_QUEUES: Preempts all queues in the + * running queues list. + * + * @KFD_PRERMPT_TYPE_FILTER_BY_PASID: Preempts queues that belongs to + * specific process. + * + */ +enum kfd_preempt_type_filter { + KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE, + KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, + KFD_PREEMPT_TYPE_FILTER_BY_PASID +}; enum kfd_preempt_type { KFD_PREEMPT_TYPE_WAVEFRONT, @@ -313,6 +330,51 @@ enum KFD_MQD_TYPE { KFD_MQD_TYPE_MAX }; +struct scheduling_resources { + unsigned int vmid_mask; + enum kfd_queue_type type; + uint64_t queue_mask; + uint64_t gws_mask; + uint32_t oac_mask; + uint32_t gds_heap_base; + uint32_t gds_heap_size; +}; + +struct process_queue_manager { + /* data */ + struct kfd_process *process; + unsigned int num_concurrent_processes; + struct list_head queues; + unsigned long *queue_slot_bitmap; +}; + +struct qcm_process_device { + /* The Device Queue Manager that owns this data */ + struct device_queue_manager *dqm; + struct process_queue_manager *pqm; + /* Device Queue Manager lock */ + struct mutex *lock; + /* Queues list */ + struct list_head queues_list; + struct list_head priv_queue_list; + + unsigned int queue_count; + unsigned int vmid; + bool is_debug; + /* + * All the memory management data should be here too + */ + uint64_t gds_context_area; + uint32_t sh_mem_config; + uint32_t sh_mem_bases; + uint32_t sh_mem_ape1_base; + uint32_t sh_mem_ape1_limit; + uint32_t page_table_base; + uint32_t gds_size; + uint32_t num_gws; + uint32_t num_oac; +}; + /* Data that is per-process-per device. */ struct kfd_process_device { /* @@ -434,12 +496,23 @@ int kgd2kfd_resume(struct kfd_dev *dev); int kfd_init_apertures(struct kfd_process *process); /* Queue Context Management */ +inline uint32_t lower_32(uint64_t x); +inline uint32_t upper_32(uint64_t x); + int init_queue(struct queue **q, struct queue_properties properties); void uninit_queue(struct queue *q); void print_queue(struct queue *q); +struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, + enum kfd_queue_type type); +void kernel_queue_uninit(struct kernel_queue *kq); + /* Packet Manager */ +#define KFD_HIQ_TIMEOUT (500) + +#define KFD_UNMAP_LATENCY (150) + struct packet_manager { struct device_queue_manager *dqm; struct kernel_queue *priv_queue; @@ -448,6 +521,8 @@ struct packet_manager { struct kfd_mem_obj *ib_buffer_obj; }; +void pm_release_ib(struct packet_manager *pm); + uint64_t kfd_get_number_elems(struct kfd_dev *kfd); phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, struct kfd_process *process); -- GitLab From 45102048f77ef72a57a877efad0f012b917d4df7 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 01:04:10 +0300 Subject: [PATCH 0022/9457] amdkfd: Add process queue manager module The queue scheduler divides into two sections, one section is process bounded and the other section is device bounded. The process bounded section is handled by this module. The PQM handles usermode queue setup, updates and tear-down. v3: Used kernel parameter to limit queues per process instead of define Added use of doorbell address from user v4: Modified pqm_create_queue so that only when creating usermode queues the driver should return the queue properties to the userspace. Added an info message print when no more queues can be opened because of the queue per process limitation v5: Move amdkfd from drm/radeon/ to drm/amd/ Various fixes Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 26 ++ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 20 + .../amd/amdkfd/kfd_process_queue_manager.c | 342 ++++++++++++++++++ 4 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 1164a3a0a7f2..104f27965b9f 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -7,6 +7,7 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ - kfd_kernel_queue.o kfd_packet_manager.o + kfd_kernel_queue.o kfd_packet_manager.o \ + kfd_process_queue_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 219c85a261c3..72b2e27d466a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -387,6 +387,9 @@ struct kfd_process_device { struct kfd_dev *dev; + /* per-process-per device QCM data structure */ + struct qcm_process_device qpd; + /*Apertures*/ uint64_t lds_base; uint64_t lds_limit; @@ -432,6 +435,8 @@ struct kfd_process { */ struct list_head per_device_data; + struct process_queue_manager pqm; + /* The process's queues. */ size_t queue_array_size; @@ -501,12 +506,33 @@ inline uint32_t upper_32(uint64_t x); int init_queue(struct queue **q, struct queue_properties properties); void uninit_queue(struct queue *q); +void print_queue_properties(struct queue_properties *q); void print_queue(struct queue *q); struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, enum kfd_queue_type type); void kernel_queue_uninit(struct kernel_queue *kq); +/* Process Queue Manager */ +struct process_queue_node { + struct queue *q; + struct kernel_queue *kq; + struct list_head process_queue_list; +}; + +int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p); +void pqm_uninit(struct process_queue_manager *pqm); +int pqm_create_queue(struct process_queue_manager *pqm, + struct kfd_dev *dev, + struct file *f, + struct queue_properties *properties, + unsigned int flags, + enum kfd_queue_type type, + unsigned int *qid); +int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid); +int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, + struct queue_properties *p); + /* Packet Manager */ #define KFD_HIQ_TIMEOUT (500) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 5084794695fb..a17e2dd0f489 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -222,6 +222,13 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, mutex_unlock(&kfd_processes_mutex); synchronize_srcu(&kfd_processes_srcu); + mutex_lock(&p->mutex); + + /* In case our notifier is called before IOMMU notifier */ + pqm_uninit(&p->pqm); + + mutex_unlock(&p->mutex); + /* * Because we drop mm_count inside kfd_process_destroy_delayed * and because the mmu_notifier_unregister function also drop @@ -274,8 +281,16 @@ static struct kfd_process *create_process(const struct task_struct *thread) INIT_LIST_HEAD(&process->per_device_data); + err = pqm_init(&process->pqm, process); + if (err != 0) + goto err_process_pqm_init; + return process; +err_process_pqm_init: + hash_del_rcu(&process->kfd_processes); + synchronize_rcu(); + mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm); err_mmu_notifier: kfd_pasid_free(process->pasid); err_alloc_pasid: @@ -300,6 +315,9 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, pdd = kzalloc(sizeof(*pdd), GFP_KERNEL); if (pdd != NULL) { pdd->dev = dev; + INIT_LIST_HEAD(&pdd->qpd.queues_list); + INIT_LIST_HEAD(&pdd->qpd.priv_queue_list); + pdd->qpd.dqm = dev->dqm; list_add(&pdd->per_device_list, &p->per_device_data); } } @@ -360,6 +378,8 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) mutex_lock(&p->mutex); + pqm_uninit(&p->pqm); + pdd = kfd_get_process_device_data(dev, p, 0); /* diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c new file mode 100644 index 000000000000..c7859fcc25ce --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -0,0 +1,342 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include "kfd_device_queue_manager.h" +#include "kfd_priv.h" +#include "kfd_kernel_queue.h" + +static inline struct process_queue_node *get_queue_by_qid( + struct process_queue_manager *pqm, unsigned int qid) +{ + struct process_queue_node *pqn; + + BUG_ON(!pqm); + + list_for_each_entry(pqn, &pqm->queues, process_queue_list) { + if (pqn->q && pqn->q->properties.queue_id == qid) + return pqn; + if (pqn->kq && pqn->kq->queue->properties.queue_id == qid) + return pqn; + } + + return NULL; +} + +static int find_available_queue_slot(struct process_queue_manager *pqm, + unsigned int *qid) +{ + unsigned long found; + + BUG_ON(!pqm || !qid); + + pr_debug("kfd: in %s\n", __func__); + + found = find_first_zero_bit(pqm->queue_slot_bitmap, + max_num_of_queues_per_process); + + pr_debug("kfd: the new slot id %lu\n", found); + + if (found >= max_num_of_queues_per_process) { + pr_info("amdkfd: Can not open more queues for process with pasid %d\n", + pqm->process->pasid); + return -ENOMEM; + } + + set_bit(found, pqm->queue_slot_bitmap); + *qid = found; + + return 0; +} + +int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) +{ + BUG_ON(!pqm); + + INIT_LIST_HEAD(&pqm->queues); + pqm->queue_slot_bitmap = + kzalloc(DIV_ROUND_UP(max_num_of_queues_per_process, + BITS_PER_BYTE), GFP_KERNEL); + if (pqm->queue_slot_bitmap == NULL) + return -ENOMEM; + pqm->process = p; + + return 0; +} + +void pqm_uninit(struct process_queue_manager *pqm) +{ + int retval; + struct process_queue_node *pqn, *next; + + BUG_ON(!pqm); + + pr_debug("In func %s\n", __func__); + + list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) { + retval = pqm_destroy_queue( + pqm, + (pqn->q != NULL) ? + pqn->q->properties.queue_id : + pqn->kq->queue->properties.queue_id); + + if (retval != 0) { + pr_err("kfd: failed to destroy queue\n"); + return; + } + } + kfree(pqm->queue_slot_bitmap); + pqm->queue_slot_bitmap = NULL; +} + +static int create_cp_queue(struct process_queue_manager *pqm, + struct kfd_dev *dev, struct queue **q, + struct queue_properties *q_properties, + struct file *f, unsigned int qid) +{ + int retval; + + retval = 0; + + /* Doorbell initialized in user space*/ + q_properties->doorbell_ptr = NULL; + + q_properties->doorbell_off = + kfd_queue_id_to_doorbell(dev, pqm->process, qid); + + /* let DQM handle it*/ + q_properties->vmid = 0; + q_properties->queue_id = qid; + q_properties->type = KFD_QUEUE_TYPE_COMPUTE; + + retval = init_queue(q, *q_properties); + if (retval != 0) + goto err_init_queue; + + (*q)->device = dev; + (*q)->process = pqm->process; + + pr_debug("kfd: PQM After init queue"); + + return retval; + +err_init_queue: + return retval; +} + +int pqm_create_queue(struct process_queue_manager *pqm, + struct kfd_dev *dev, + struct file *f, + struct queue_properties *properties, + unsigned int flags, + enum kfd_queue_type type, + unsigned int *qid) +{ + int retval; + struct kfd_process_device *pdd; + struct queue_properties q_properties; + struct queue *q; + struct process_queue_node *pqn; + struct kernel_queue *kq; + + BUG_ON(!pqm || !dev || !properties || !qid); + + memset(&q_properties, 0, sizeof(struct queue_properties)); + memcpy(&q_properties, properties, sizeof(struct queue_properties)); + q = NULL; + kq = NULL; + + pdd = kfd_get_process_device_data(dev, pqm->process, 1); + BUG_ON(!pdd); + + retval = find_available_queue_slot(pqm, qid); + if (retval != 0) + return retval; + + if (list_empty(&pqm->queues)) { + pdd->qpd.pqm = pqm; + dev->dqm->register_process(dev->dqm, &pdd->qpd); + } + + pqn = kzalloc(sizeof(struct process_queue_node), GFP_KERNEL); + if (!pqn) { + retval = -ENOMEM; + goto err_allocate_pqn; + } + + switch (type) { + case KFD_QUEUE_TYPE_COMPUTE: + /* check if there is over subscription */ + if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && + ((dev->dqm->processes_count >= VMID_PER_DEVICE) || + (dev->dqm->queue_count >= PIPE_PER_ME_CP_SCHEDULING * QUEUES_PER_PIPE))) { + pr_err("kfd: over-subscription is not allowed in radeon_kfd.sched_policy == 1\n"); + retval = -EPERM; + goto err_create_queue; + } + + retval = create_cp_queue(pqm, dev, &q, &q_properties, f, *qid); + if (retval != 0) + goto err_create_queue; + pqn->q = q; + pqn->kq = NULL; + retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd, + &q->properties.vmid); + print_queue(q); + break; + case KFD_QUEUE_TYPE_DIQ: + kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ); + if (kq == NULL) { + kernel_queue_uninit(kq); + goto err_create_queue; + } + kq->queue->properties.queue_id = *qid; + pqn->kq = kq; + pqn->q = NULL; + retval = dev->dqm->create_kernel_queue(dev->dqm, kq, &pdd->qpd); + break; + default: + BUG(); + break; + } + + if (retval != 0) { + pr_err("kfd: error dqm create queue\n"); + goto err_create_queue; + } + + pr_debug("kfd: PQM After DQM create queue\n"); + + list_add(&pqn->process_queue_list, &pqm->queues); + + if (q) { + *properties = q->properties; + pr_debug("kfd: PQM done creating queue\n"); + print_queue_properties(properties); + } + + return retval; + +err_create_queue: + kfree(pqn); +err_allocate_pqn: + clear_bit(*qid, pqm->queue_slot_bitmap); + return retval; +} + +int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) +{ + struct process_queue_node *pqn; + struct kfd_process_device *pdd; + struct device_queue_manager *dqm; + struct kfd_dev *dev; + int retval; + + dqm = NULL; + + BUG_ON(!pqm); + retval = 0; + + pr_debug("kfd: In Func %s\n", __func__); + + pqn = get_queue_by_qid(pqm, qid); + if (pqn == NULL) { + pr_err("kfd: queue id does not match any known queue\n"); + return -EINVAL; + } + + dev = NULL; + if (pqn->kq) + dev = pqn->kq->dev; + if (pqn->q) + dev = pqn->q->device; + BUG_ON(!dev); + + pdd = kfd_get_process_device_data(dev, pqm->process, 1); + BUG_ON(!pdd); + + if (pqn->kq) { + /* destroy kernel queue (DIQ) */ + dqm = pqn->kq->dev->dqm; + dqm->destroy_kernel_queue(dqm, pqn->kq, &pdd->qpd); + kernel_queue_uninit(pqn->kq); + } + + if (pqn->q) { + dqm = pqn->q->device->dqm; + retval = dqm->destroy_queue(dqm, &pdd->qpd, pqn->q); + if (retval != 0) + return retval; + + uninit_queue(pqn->q); + } + + list_del(&pqn->process_queue_list); + kfree(pqn); + clear_bit(qid, pqm->queue_slot_bitmap); + + if (list_empty(&pqm->queues)) + dqm->unregister_process(dqm, &pdd->qpd); + + return retval; +} + +int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, + struct queue_properties *p) +{ + int retval; + struct process_queue_node *pqn; + + BUG_ON(!pqm); + + pqn = get_queue_by_qid(pqm, qid); + BUG_ON(!pqn); + + pqn->q->properties.queue_address = p->queue_address; + pqn->q->properties.queue_size = p->queue_size; + pqn->q->properties.queue_percent = p->queue_percent; + pqn->q->properties.priority = p->priority; + + retval = pqn->q->device->dqm->update_queue(pqn->q->device->dqm, pqn->q); + if (retval != 0) + return retval; + + return 0; +} + +struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm, + unsigned int qid) +{ + struct process_queue_node *pqn; + + BUG_ON(!pqm); + + pqn = get_queue_by_qid(pqm, qid); + if (pqn && pqn->kq) + return pqn->kq; + + return NULL; +} + + -- GitLab From 64c7f8cf792776aaca036fb983006b6b21204934 Mon Sep 17 00:00:00 2001 From: Ben Goz Date: Thu, 17 Jul 2014 01:27:00 +0300 Subject: [PATCH 0023/9457] amdkfd: Add device queue manager module The queue scheduler divides into two sections, one section is process bounded and the other section is device bounded. The device bounded section is handled by this module. The DQM module handles queue setup, update and tear-down from the device side. It also supports suspend/resume operation. v3: Changed device_init, added the use of the new gart allocation functions an Added documentation. v4: Fixed a race in DQM queue scheduler where dqm->lock must be held when accessing dqm->queue_count and dqm->processes_count. This fixes runlist IB allocation failures when DQM is under load. Fixed race in DQM queue destruction where queues being destroyed must be removed from qpd->queues_list prior to preemption, or concurrent queue creation activity may reschedule them while their MQD is destroyed. Fixed EOP queue size setting in CP_HPD_EOP_CONTROL, because the size is specified as (log2(size_dwords)-1). The previous calculation assumed the size was specified in bytes, which caused interference between EOP queues when multiple MEC pipelines were active. v5: Move amdkfd from drm/radeon/ to drm/amd/ Change format of mqd structure to match latest KV firmware Add support for AQL queues creation to enable working with open-source HSA runtime Remove unused unmap_queue function Various fixes (Style, typos) Signed-off-by: Ben Goz Signed-off-by: Jay Cornwall Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 29 +- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 1059 +++++++++++++++++ .../drm/amd/amdkfd/kfd_device_queue_manager.h | 49 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 21 + 5 files changed, 1156 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 104f27965b9f..307a309110e6 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -8,6 +8,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ kfd_kernel_queue.o kfd_packet_manager.o \ - kfd_process_queue_manager.o + kfd_process_queue_manager.o kfd_device_queue_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 4b1cced9b2b7..bdf3e94590bd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -25,6 +25,7 @@ #include #include #include "kfd_priv.h" +#include "kfd_device_queue_manager.h" #define MQD_SIZE_ALIGNED 768 @@ -199,12 +200,34 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, amd_iommu_set_invalidate_ctx_cb(kfd->pdev, iommu_pasid_shutdown_callback); + kfd->dqm = device_queue_manager_init(kfd); + if (!kfd->dqm) { + dev_err(kfd_device, + "Error initializing queue manager for device (%x:%x)\n", + kfd->pdev->vendor, kfd->pdev->device); + goto device_queue_manager_error; + } + + if (kfd->dqm->start(kfd->dqm) != 0) { + dev_err(kfd_device, + "Error starting queuen manager for device (%x:%x)\n", + kfd->pdev->vendor, kfd->pdev->device); + goto dqm_start_error; + } + kfd->init_complete = true; dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor, kfd->pdev->device); + pr_debug("kfd: Starting kfd with the following scheduling policy %d\n", + sched_policy); + goto out; +dqm_start_error: + device_queue_manager_uninit(kfd->dqm); +device_queue_manager_error: + amd_iommu_free_device(kfd->pdev); device_iommu_pasid_error: kfd_topology_remove_device(kfd); kfd_topology_add_device_error: @@ -219,6 +242,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, void kgd2kfd_device_exit(struct kfd_dev *kfd) { if (kfd->init_complete) { + device_queue_manager_uninit(kfd->dqm); amd_iommu_free_device(kfd->pdev); kfd_topology_remove_device(kfd); } @@ -230,8 +254,10 @@ void kgd2kfd_suspend(struct kfd_dev *kfd) { BUG_ON(kfd == NULL); - if (kfd->init_complete) + if (kfd->init_complete) { + kfd->dqm->stop(kfd->dqm); amd_iommu_free_device(kfd->pdev); + } } int kgd2kfd_resume(struct kfd_dev *kfd) @@ -249,6 +275,7 @@ int kgd2kfd_resume(struct kfd_dev *kfd) return -ENXIO; amd_iommu_set_invalidate_ctx_cb(kfd->pdev, iommu_pasid_shutdown_callback); + kfd->dqm->start(kfd->dqm); } return 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c new file mode 100644 index 000000000000..8c40d04932b2 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -0,0 +1,1059 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include +#include +#include "kfd_priv.h" +#include "kfd_device_queue_manager.h" +#include "kfd_mqd_manager.h" +#include "cik_regs.h" +#include "kfd_kernel_queue.h" +#include "../../radeon/cik_reg.h" + +/* Size of the per-pipe EOP queue */ +#define CIK_HPD_EOP_BYTES_LOG2 11 +#define CIK_HPD_EOP_BYTES (1U << CIK_HPD_EOP_BYTES_LOG2) + +static bool is_mem_initialized; + +static int init_memory(struct device_queue_manager *dqm); +static int set_pasid_vmid_mapping(struct device_queue_manager *dqm, + unsigned int pasid, unsigned int vmid); + +static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, + struct queue *q, + struct qcm_process_device *qpd); +static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock); +static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock); + + +static inline unsigned int get_pipes_num(struct device_queue_manager *dqm) +{ + BUG_ON(!dqm || !dqm->dev); + return dqm->dev->shared_resources.compute_pipe_count; +} + +static inline unsigned int get_first_pipe(struct device_queue_manager *dqm) +{ + BUG_ON(!dqm); + return dqm->dev->shared_resources.first_compute_pipe; +} + +static inline unsigned int get_pipes_num_cpsch(void) +{ + return PIPE_PER_ME_CP_SCHEDULING; +} + +static unsigned int get_sh_mem_bases_nybble_64(struct kfd_process *process, + struct kfd_dev *dev) +{ + struct kfd_process_device *pdd; + uint32_t nybble; + + pdd = kfd_get_process_device_data(dev, process, 1); + nybble = (pdd->lds_base >> 60) & 0x0E; + + return nybble; + +} + +static unsigned int get_sh_mem_bases_32(struct kfd_process *process, + struct kfd_dev *dev) +{ + struct kfd_process_device *pdd; + unsigned int shared_base; + + pdd = kfd_get_process_device_data(dev, process, 1); + shared_base = (pdd->lds_base >> 16) & 0xFF; + + return shared_base; +} + +static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble); +static void init_process_memory(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + unsigned int temp; + + BUG_ON(!dqm || !qpd); + + /* check if sh_mem_config register already configured */ + if (qpd->sh_mem_config == 0) { + qpd->sh_mem_config = + ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | + DEFAULT_MTYPE(MTYPE_NONCACHED) | + APE1_MTYPE(MTYPE_NONCACHED); + qpd->sh_mem_ape1_limit = 0; + qpd->sh_mem_ape1_base = 0; + } + + if (qpd->pqm->process->is_32bit_user_mode) { + temp = get_sh_mem_bases_32(qpd->pqm->process, dqm->dev); + qpd->sh_mem_bases = SHARED_BASE(temp); + qpd->sh_mem_config |= PTR32; + } else { + temp = get_sh_mem_bases_nybble_64(qpd->pqm->process, dqm->dev); + qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); + } + + pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n", + qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases); +} + +static void program_sh_mem_settings(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid, + qpd->sh_mem_config, + qpd->sh_mem_ape1_base, + qpd->sh_mem_ape1_limit, + qpd->sh_mem_bases); +} + +static int allocate_vmid(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q) +{ + int bit, allocated_vmid; + + if (dqm->vmid_bitmap == 0) + return -ENOMEM; + + bit = find_first_bit((unsigned long *)&dqm->vmid_bitmap, CIK_VMID_NUM); + clear_bit(bit, (unsigned long *)&dqm->vmid_bitmap); + + /* Kaveri kfd vmid's starts from vmid 8 */ + allocated_vmid = bit + KFD_VMID_START_OFFSET; + pr_debug("kfd: vmid allocation %d\n", allocated_vmid); + qpd->vmid = allocated_vmid; + q->properties.vmid = allocated_vmid; + + set_pasid_vmid_mapping(dqm, q->process->pasid, q->properties.vmid); + program_sh_mem_settings(dqm, qpd); + + return 0; +} + +static void deallocate_vmid(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q) +{ + int bit = qpd->vmid - KFD_VMID_START_OFFSET; + + set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); + qpd->vmid = 0; + q->properties.vmid = 0; +} + +static int create_queue_nocpsch(struct device_queue_manager *dqm, + struct queue *q, + struct qcm_process_device *qpd, + int *allocated_vmid) +{ + int retval; + + BUG_ON(!dqm || !q || !qpd || !allocated_vmid); + + pr_debug("kfd: In func %s\n", __func__); + print_queue(q); + + mutex_lock(&dqm->lock); + + if (list_empty(&qpd->queues_list)) { + retval = allocate_vmid(dqm, qpd, q); + if (retval != 0) { + mutex_unlock(&dqm->lock); + return retval; + } + } + *allocated_vmid = qpd->vmid; + q->properties.vmid = qpd->vmid; + + retval = create_compute_queue_nocpsch(dqm, q, qpd); + + if (retval != 0) { + if (list_empty(&qpd->queues_list)) { + deallocate_vmid(dqm, qpd, q); + *allocated_vmid = 0; + } + mutex_unlock(&dqm->lock); + return retval; + } + + list_add(&q->list, &qpd->queues_list); + dqm->queue_count++; + + mutex_unlock(&dqm->lock); + return 0; +} + +static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q) +{ + bool set; + int pipe, bit; + + set = false; + + for (pipe = dqm->next_pipe_to_allocate; pipe < get_pipes_num(dqm); + pipe = (pipe + 1) % get_pipes_num(dqm)) { + if (dqm->allocated_queues[pipe] != 0) { + bit = find_first_bit( + (unsigned long *)&dqm->allocated_queues[pipe], + QUEUES_PER_PIPE); + + clear_bit(bit, + (unsigned long *)&dqm->allocated_queues[pipe]); + q->pipe = pipe; + q->queue = bit; + set = true; + break; + } + } + + if (set == false) + return -EBUSY; + + pr_debug("kfd: DQM %s hqd slot - pipe (%d) queue(%d)\n", + __func__, q->pipe, q->queue); + /* horizontal hqd allocation */ + dqm->next_pipe_to_allocate = (pipe + 1) % get_pipes_num(dqm); + + return 0; +} + +static inline void deallocate_hqd(struct device_queue_manager *dqm, + struct queue *q) +{ + set_bit(q->queue, (unsigned long *)&dqm->allocated_queues[q->pipe]); +} + +static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, + struct queue *q, + struct qcm_process_device *qpd) +{ + int retval; + struct mqd_manager *mqd; + + BUG_ON(!dqm || !q || !qpd); + + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE); + if (mqd == NULL) + return -ENOMEM; + + retval = allocate_hqd(dqm, q); + if (retval != 0) + return retval; + + retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, + &q->gart_mqd_addr, &q->properties); + if (retval != 0) { + deallocate_hqd(dqm, q); + return retval; + } + + return 0; +} + +static int destroy_queue_nocpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q) +{ + int retval; + struct mqd_manager *mqd; + + BUG_ON(!dqm || !q || !q->mqd || !qpd); + + retval = 0; + + pr_debug("kfd: In Func %s\n", __func__); + + mutex_lock(&dqm->lock); + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE); + if (mqd == NULL) { + retval = -ENOMEM; + goto out; + } + + retval = mqd->destroy_mqd(mqd, q->mqd, + KFD_PREEMPT_TYPE_WAVEFRONT, + QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS, + q->pipe, q->queue); + + if (retval != 0) + goto out; + + deallocate_hqd(dqm, q); + + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); + + list_del(&q->list); + if (list_empty(&qpd->queues_list)) + deallocate_vmid(dqm, qpd, q); + dqm->queue_count--; +out: + mutex_unlock(&dqm->lock); + return retval; +} + +static int update_queue(struct device_queue_manager *dqm, struct queue *q) +{ + int retval; + struct mqd_manager *mqd; + + BUG_ON(!dqm || !q || !q->mqd); + + mutex_lock(&dqm->lock); + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE); + if (mqd == NULL) { + mutex_unlock(&dqm->lock); + return -ENOMEM; + } + + retval = mqd->update_mqd(mqd, q->mqd, &q->properties); + if (q->properties.is_active == true) + dqm->queue_count++; + else + dqm->queue_count--; + + if (sched_policy != KFD_SCHED_POLICY_NO_HWS) + retval = execute_queues_cpsch(dqm, false); + + mutex_unlock(&dqm->lock); + return retval; +} + +static struct mqd_manager *get_mqd_manager_nocpsch( + struct device_queue_manager *dqm, enum KFD_MQD_TYPE type) +{ + struct mqd_manager *mqd; + + BUG_ON(!dqm || type >= KFD_MQD_TYPE_MAX); + + pr_debug("kfd: In func %s mqd type %d\n", __func__, type); + + mqd = dqm->mqds[type]; + if (!mqd) { + mqd = mqd_manager_init(type, dqm->dev); + if (mqd == NULL) + pr_err("kfd: mqd manager is NULL"); + dqm->mqds[type] = mqd; + } + + return mqd; +} + +static int register_process_nocpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + struct device_process_node *n; + + BUG_ON(!dqm || !qpd); + + pr_debug("kfd: In func %s\n", __func__); + + n = kzalloc(sizeof(struct device_process_node), GFP_KERNEL); + if (!n) + return -ENOMEM; + + n->qpd = qpd; + + mutex_lock(&dqm->lock); + list_add(&n->list, &dqm->queues); + + init_process_memory(dqm, qpd); + dqm->processes_count++; + + mutex_unlock(&dqm->lock); + + return 0; +} + +static int unregister_process_nocpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd) +{ + int retval; + struct device_process_node *cur, *next; + + BUG_ON(!dqm || !qpd); + + BUG_ON(!list_empty(&qpd->queues_list)); + + pr_debug("kfd: In func %s\n", __func__); + + retval = 0; + mutex_lock(&dqm->lock); + + list_for_each_entry_safe(cur, next, &dqm->queues, list) { + if (qpd == cur->qpd) { + list_del(&cur->list); + dqm->processes_count--; + goto out; + } + } + /* qpd not found in dqm list */ + retval = 1; +out: + mutex_unlock(&dqm->lock); + return retval; +} + +static int +set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, + unsigned int vmid) +{ + uint32_t pasid_mapping; + + pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid | + ATC_VMID_PASID_MAPPING_VALID; + return kfd2kgd->set_pasid_vmid_mapping(dqm->dev->kgd, pasid_mapping, + vmid); +} + +static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) +{ + /* In 64-bit mode, we can only control the top 3 bits of the LDS, + * scratch and GPUVM apertures. + * The hardware fills in the remaining 59 bits according to the + * following pattern: + * LDS: X0000000'00000000 - X0000001'00000000 (4GB) + * Scratch: X0000001'00000000 - X0000002'00000000 (4GB) + * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB) + * + * (where X/Y is the configurable nybble with the low-bit 0) + * + * LDS and scratch will have the same top nybble programmed in the + * top 3 bits of SH_MEM_BASES.PRIVATE_BASE. + * GPUVM can have a different top nybble programmed in the + * top 3 bits of SH_MEM_BASES.SHARED_BASE. + * We don't bother to support different top nybbles + * for LDS/Scratch and GPUVM. + */ + + BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE || + top_address_nybble == 0); + + return PRIVATE_BASE(top_address_nybble << 12) | + SHARED_BASE(top_address_nybble << 12); +} + +static int init_memory(struct device_queue_manager *dqm) +{ + int i, retval; + + for (i = 8; i < 16; i++) + set_pasid_vmid_mapping(dqm, 0, i); + + retval = kfd2kgd->init_memory(dqm->dev->kgd); + if (retval == 0) + is_mem_initialized = true; + return retval; +} + + +static int init_pipelines(struct device_queue_manager *dqm, + unsigned int pipes_num, unsigned int first_pipe) +{ + void *hpdptr; + struct mqd_manager *mqd; + unsigned int i, err, inx; + uint64_t pipe_hpd_addr; + + BUG_ON(!dqm || !dqm->dev); + + pr_debug("kfd: In func %s\n", __func__); + + /* + * Allocate memory for the HPDs. This is hardware-owned per-pipe data. + * The driver never accesses this memory after zeroing it. + * It doesn't even have to be saved/restored on suspend/resume + * because it contains no data when there are no active queues. + */ + + err = kfd2kgd->allocate_mem(dqm->dev->kgd, + CIK_HPD_EOP_BYTES * pipes_num, + PAGE_SIZE, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &dqm->pipeline_mem); + + if (err) { + pr_err("kfd: error allocate vidmem num pipes: %d\n", + pipes_num); + return -ENOMEM; + } + + hpdptr = dqm->pipeline_mem->cpu_ptr; + dqm->pipelines_addr = dqm->pipeline_mem->gpu_addr; + + memset(hpdptr, 0, CIK_HPD_EOP_BYTES * pipes_num); + + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE); + if (mqd == NULL) { + kfd2kgd->free_mem(dqm->dev->kgd, + (struct kgd_mem *) dqm->pipeline_mem); + return -ENOMEM; + } + + for (i = 0; i < pipes_num; i++) { + inx = i + first_pipe; + pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; + pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); + /* = log2(bytes/4)-1 */ + kfd2kgd->init_pipeline(dqm->dev->kgd, i, + CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); + } + + return 0; +} + + +static int init_scheduler(struct device_queue_manager *dqm) +{ + int retval; + + BUG_ON(!dqm); + + pr_debug("kfd: In %s\n", __func__); + + retval = init_pipelines(dqm, get_pipes_num(dqm), KFD_DQM_FIRST_PIPE); + if (retval != 0) + return retval; + + retval = init_memory(dqm); + + return retval; +} + +static int initialize_nocpsch(struct device_queue_manager *dqm) +{ + int i; + + BUG_ON(!dqm); + + pr_debug("kfd: In func %s num of pipes: %d\n", + __func__, get_pipes_num(dqm)); + + mutex_init(&dqm->lock); + INIT_LIST_HEAD(&dqm->queues); + dqm->queue_count = dqm->next_pipe_to_allocate = 0; + dqm->allocated_queues = kcalloc(get_pipes_num(dqm), + sizeof(unsigned int), GFP_KERNEL); + if (!dqm->allocated_queues) { + mutex_destroy(&dqm->lock); + return -ENOMEM; + } + + for (i = 0; i < get_pipes_num(dqm); i++) + dqm->allocated_queues[i] = (1 << QUEUES_PER_PIPE) - 1; + + dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1; + + init_scheduler(dqm); + return 0; +} + +static void uninitialize_nocpsch(struct device_queue_manager *dqm) +{ + BUG_ON(!dqm); + + BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0); + + kfree(dqm->allocated_queues); + mutex_destroy(&dqm->lock); + kfd2kgd->free_mem(dqm->dev->kgd, + (struct kgd_mem *) dqm->pipeline_mem); +} + +static int start_nocpsch(struct device_queue_manager *dqm) +{ + return 0; +} + +static int stop_nocpsch(struct device_queue_manager *dqm) +{ + return 0; +} + +/* + * Device Queue Manager implementation for cp scheduler + */ + +static int set_sched_resources(struct device_queue_manager *dqm) +{ + struct scheduling_resources res; + unsigned int queue_num, queue_mask; + + BUG_ON(!dqm); + + pr_debug("kfd: In func %s\n", __func__); + + queue_num = get_pipes_num_cpsch() * QUEUES_PER_PIPE; + queue_mask = (1 << queue_num) - 1; + res.vmid_mask = (1 << VMID_PER_DEVICE) - 1; + res.vmid_mask <<= KFD_VMID_START_OFFSET; + res.queue_mask = queue_mask << (get_first_pipe(dqm) * QUEUES_PER_PIPE); + res.gws_mask = res.oac_mask = res.gds_heap_base = + res.gds_heap_size = 0; + + pr_debug("kfd: scheduling resources:\n" + " vmid mask: 0x%8X\n" + " queue mask: 0x%8llX\n", + res.vmid_mask, res.queue_mask); + + return pm_send_set_resources(&dqm->packets, &res); +} + +static int initialize_cpsch(struct device_queue_manager *dqm) +{ + int retval; + + BUG_ON(!dqm); + + pr_debug("kfd: In func %s num of pipes: %d\n", + __func__, get_pipes_num_cpsch()); + + mutex_init(&dqm->lock); + INIT_LIST_HEAD(&dqm->queues); + dqm->queue_count = dqm->processes_count = 0; + dqm->active_runlist = false; + retval = init_pipelines(dqm, get_pipes_num(dqm), 0); + if (retval != 0) + goto fail_init_pipelines; + + return 0; + +fail_init_pipelines: + mutex_destroy(&dqm->lock); + return retval; +} + +static int start_cpsch(struct device_queue_manager *dqm) +{ + struct device_process_node *node; + int retval; + + BUG_ON(!dqm); + + retval = 0; + + retval = pm_init(&dqm->packets, dqm); + if (retval != 0) + goto fail_packet_manager_init; + + retval = set_sched_resources(dqm); + if (retval != 0) + goto fail_set_sched_resources; + + pr_debug("kfd: allocating fence memory\n"); + + /* allocate fence memory on the gart */ + retval = kfd2kgd->allocate_mem(dqm->dev->kgd, + sizeof(*dqm->fence_addr), + 32, + KFD_MEMPOOL_SYSTEM_WRITECOMBINE, + (struct kgd_mem **) &dqm->fence_mem); + + if (retval != 0) + goto fail_allocate_vidmem; + + dqm->fence_addr = dqm->fence_mem->cpu_ptr; + dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr; + + list_for_each_entry(node, &dqm->queues, list) + if (node->qpd->pqm->process && dqm->dev) + kfd_bind_process_to_device(dqm->dev, + node->qpd->pqm->process); + + execute_queues_cpsch(dqm, true); + + return 0; +fail_allocate_vidmem: +fail_set_sched_resources: + pm_uninit(&dqm->packets); +fail_packet_manager_init: + return retval; +} + +static int stop_cpsch(struct device_queue_manager *dqm) +{ + struct device_process_node *node; + struct kfd_process_device *pdd; + + BUG_ON(!dqm); + + destroy_queues_cpsch(dqm, true); + + list_for_each_entry(node, &dqm->queues, list) { + pdd = kfd_get_process_device_data(dqm->dev, + node->qpd->pqm->process, 1); + pdd->bound = false; + } + kfd2kgd->free_mem(dqm->dev->kgd, + (struct kgd_mem *) dqm->fence_mem); + pm_uninit(&dqm->packets); + + return 0; +} + +static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, + struct kernel_queue *kq, + struct qcm_process_device *qpd) +{ + BUG_ON(!dqm || !kq || !qpd); + + pr_debug("kfd: In func %s\n", __func__); + + mutex_lock(&dqm->lock); + list_add(&kq->list, &qpd->priv_queue_list); + dqm->queue_count++; + qpd->is_debug = true; + execute_queues_cpsch(dqm, false); + mutex_unlock(&dqm->lock); + + return 0; +} + +static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, + struct kernel_queue *kq, + struct qcm_process_device *qpd) +{ + BUG_ON(!dqm || !kq); + + pr_debug("kfd: In %s\n", __func__); + + mutex_lock(&dqm->lock); + destroy_queues_cpsch(dqm, false); + list_del(&kq->list); + dqm->queue_count--; + qpd->is_debug = false; + execute_queues_cpsch(dqm, false); + mutex_unlock(&dqm->lock); +} + +static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, + struct qcm_process_device *qpd, int *allocate_vmid) +{ + int retval; + struct mqd_manager *mqd; + + BUG_ON(!dqm || !q || !qpd); + + retval = 0; + + if (allocate_vmid) + *allocate_vmid = 0; + + mutex_lock(&dqm->lock); + + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); + if (mqd == NULL) { + mutex_unlock(&dqm->lock); + return -ENOMEM; + } + + retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, + &q->gart_mqd_addr, &q->properties); + if (retval != 0) + goto out; + + list_add(&q->list, &qpd->queues_list); + if (q->properties.is_active) { + dqm->queue_count++; + retval = execute_queues_cpsch(dqm, false); + } + +out: + mutex_unlock(&dqm->lock); + return retval; +} + +int fence_wait_timeout(unsigned int *fence_addr, unsigned int fence_value, + unsigned long timeout) +{ + BUG_ON(!fence_addr); + timeout += jiffies; + + while (*fence_addr != fence_value) { + if (time_after(jiffies, timeout)) { + pr_err("kfd: qcm fence wait loop timeout expired\n"); + return -ETIME; + } + cpu_relax(); + } + + return 0; +} + +static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock) +{ + int retval; + + BUG_ON(!dqm); + + retval = 0; + + if (lock) + mutex_lock(&dqm->lock); + if (dqm->active_runlist == false) + goto out; + retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, + KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0); + if (retval != 0) + goto out; + + *dqm->fence_addr = KFD_FENCE_INIT; + pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr, + KFD_FENCE_COMPLETED); + /* should be timed out */ + fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, + QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS); + pm_release_ib(&dqm->packets); + dqm->active_runlist = false; + +out: + if (lock) + mutex_unlock(&dqm->lock); + return retval; +} + +static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock) +{ + int retval; + + BUG_ON(!dqm); + + if (lock) + mutex_lock(&dqm->lock); + + retval = destroy_queues_cpsch(dqm, false); + if (retval != 0) { + pr_err("kfd: the cp might be in an unrecoverable state due to an unsuccessful queues preemption"); + goto out; + } + + if (dqm->queue_count <= 0 || dqm->processes_count <= 0) { + retval = 0; + goto out; + } + + if (dqm->active_runlist) { + retval = 0; + goto out; + } + + retval = pm_send_runlist(&dqm->packets, &dqm->queues); + if (retval != 0) { + pr_err("kfd: failed to execute runlist"); + goto out; + } + dqm->active_runlist = true; + +out: + if (lock) + mutex_unlock(&dqm->lock); + return retval; +} + +static int destroy_queue_cpsch(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + struct queue *q) +{ + int retval; + struct mqd_manager *mqd; + + BUG_ON(!dqm || !qpd || !q); + + retval = 0; + + /* remove queue from list to prevent rescheduling after preemption */ + mutex_lock(&dqm->lock); + + mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); + if (!mqd) { + retval = -ENOMEM; + goto failed; + } + + list_del(&q->list); + dqm->queue_count--; + + execute_queues_cpsch(dqm, false); + + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); + + mutex_unlock(&dqm->lock); + + return 0; + +failed: + mutex_unlock(&dqm->lock); + return retval; +} + +/* + * Low bits must be 0000/FFFF as required by HW, high bits must be 0 to + * stay in user mode. + */ +#define APE1_FIXED_BITS_MASK 0xFFFF80000000FFFFULL +/* APE1 limit is inclusive and 64K aligned. */ +#define APE1_LIMIT_ALIGNMENT 0xFFFF + +static bool set_cache_memory_policy(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + enum cache_policy default_policy, + enum cache_policy alternate_policy, + void __user *alternate_aperture_base, + uint64_t alternate_aperture_size) +{ + uint32_t default_mtype; + uint32_t ape1_mtype; + + pr_debug("kfd: In func %s\n", __func__); + + mutex_lock(&dqm->lock); + + if (alternate_aperture_size == 0) { + /* base > limit disables APE1 */ + qpd->sh_mem_ape1_base = 1; + qpd->sh_mem_ape1_limit = 0; + } else { + /* + * In FSA64, APE1_Base[63:0] = { 16{SH_MEM_APE1_BASE[31]}, + * SH_MEM_APE1_BASE[31:0], 0x0000 } + * APE1_Limit[63:0] = { 16{SH_MEM_APE1_LIMIT[31]}, + * SH_MEM_APE1_LIMIT[31:0], 0xFFFF } + * Verify that the base and size parameters can be + * represented in this format and convert them. + * Additionally restrict APE1 to user-mode addresses. + */ + + uint64_t base = (uintptr_t)alternate_aperture_base; + uint64_t limit = base + alternate_aperture_size - 1; + + if (limit <= base) + goto out; + + if ((base & APE1_FIXED_BITS_MASK) != 0) + goto out; + + if ((limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) + goto out; + + qpd->sh_mem_ape1_base = base >> 16; + qpd->sh_mem_ape1_limit = limit >> 16; + } + + default_mtype = (default_policy == cache_policy_coherent) ? + MTYPE_NONCACHED : + MTYPE_CACHED; + + ape1_mtype = (alternate_policy == cache_policy_coherent) ? + MTYPE_NONCACHED : + MTYPE_CACHED; + + qpd->sh_mem_config = (qpd->sh_mem_config & PTR32) + | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) + | DEFAULT_MTYPE(default_mtype) + | APE1_MTYPE(ape1_mtype); + + if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0)) + program_sh_mem_settings(dqm, qpd); + + pr_debug("kfd: sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n", + qpd->sh_mem_config, qpd->sh_mem_ape1_base, + qpd->sh_mem_ape1_limit); + + mutex_unlock(&dqm->lock); + return true; + +out: + mutex_unlock(&dqm->lock); + return false; +} + +struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) +{ + struct device_queue_manager *dqm; + + BUG_ON(!dev); + + dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL); + if (!dqm) + return NULL; + + dqm->dev = dev; + switch (sched_policy) { + case KFD_SCHED_POLICY_HWS: + case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION: + /* initialize dqm for cp scheduling */ + dqm->create_queue = create_queue_cpsch; + dqm->initialize = initialize_cpsch; + dqm->start = start_cpsch; + dqm->stop = stop_cpsch; + dqm->destroy_queue = destroy_queue_cpsch; + dqm->update_queue = update_queue; + dqm->get_mqd_manager = get_mqd_manager_nocpsch; + dqm->register_process = register_process_nocpsch; + dqm->unregister_process = unregister_process_nocpsch; + dqm->uninitialize = uninitialize_nocpsch; + dqm->create_kernel_queue = create_kernel_queue_cpsch; + dqm->destroy_kernel_queue = destroy_kernel_queue_cpsch; + dqm->set_cache_memory_policy = set_cache_memory_policy; + break; + case KFD_SCHED_POLICY_NO_HWS: + /* initialize dqm for no cp scheduling */ + dqm->start = start_nocpsch; + dqm->stop = stop_nocpsch; + dqm->create_queue = create_queue_nocpsch; + dqm->destroy_queue = destroy_queue_nocpsch; + dqm->update_queue = update_queue; + dqm->get_mqd_manager = get_mqd_manager_nocpsch; + dqm->register_process = register_process_nocpsch; + dqm->unregister_process = unregister_process_nocpsch; + dqm->initialize = initialize_nocpsch; + dqm->uninitialize = uninitialize_nocpsch; + dqm->set_cache_memory_policy = set_cache_memory_policy; + break; + default: + BUG(); + break; + } + + if (dqm->initialize(dqm) != 0) { + kfree(dqm); + return NULL; + } + + return dqm; +} + +void device_queue_manager_uninit(struct device_queue_manager *dqm) +{ + BUG_ON(!dqm); + + dqm->uninitialize(dqm); + kfree(dqm); +} + diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index e495b38a8cfd..c3f189e8ae35 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -42,6 +42,50 @@ struct device_process_node { struct list_head list; }; +/** + * struct device_queue_manager + * + * @create_queue: Queue creation routine. + * + * @destroy_queue: Queue destruction routine. + * + * @update_queue: Queue update routine. + * + * @get_mqd_manager: Returns the mqd manager according to the mqd type. + * + * @exeute_queues: Dispatches the queues list to the H/W. + * + * @register_process: This routine associates a specific process with device. + * + * @unregister_process: destroys the associations between process to device. + * + * @initialize: Initializes the pipelines and memory module for that device. + * + * @start: Initializes the resources/modules the the device needs for queues + * execution. This function is called on device initialization and after the + * system woke up after suspension. + * + * @stop: This routine stops execution of all the active queue running on the + * H/W and basically this function called on system suspend. + * + * @uninitialize: Destroys all the device queue manager resources allocated in + * initialize routine. + * + * @create_kernel_queue: Creates kernel queue. Used for debug queue. + * + * @destroy_kernel_queue: Destroys kernel queue. Used for debug queue. + * + * @set_cache_memory_policy: Sets memory policy (cached/ non cached) for the + * memory apertures. + * + * This struct is a base class for the kfd queues scheduler in the + * device level. The device base class should expose the basic operations + * for queue creation and queue destruction. This base class hides the + * scheduling mode of the driver and the specific implementation of the + * concrete device. This class is the only class in the queues scheduler + * that configures the H/W. + */ + struct device_queue_manager { int (*create_queue)(struct device_queue_manager *dqm, struct queue *q, @@ -52,8 +96,9 @@ struct device_queue_manager { struct queue *q); int (*update_queue)(struct device_queue_manager *dqm, struct queue *q); - struct mqd_manager * (*get_mqd_manager)( - struct device_queue_manager *dqm, + + struct mqd_manager * (*get_mqd_manager) + (struct device_queue_manager *dqm, enum KFD_MQD_TYPE type); int (*register_process)(struct device_queue_manager *dqm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 72b2e27d466a..7f3b4fdaa26e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -454,6 +454,8 @@ void kfd_process_destroy_wq(void); struct kfd_process *kfd_create_process(const struct task_struct *); struct kfd_process *kfd_get_process(const struct task_struct *); +struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, + struct kfd_process *p); void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid); struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process *p, @@ -509,6 +511,10 @@ void uninit_queue(struct queue *q); void print_queue_properties(struct queue_properties *q); void print_queue(struct queue *q); +struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type, + struct kfd_dev *dev); +struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev); +void device_queue_manager_uninit(struct device_queue_manager *dqm); struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, enum kfd_queue_type type); void kernel_queue_uninit(struct kernel_queue *kq); @@ -537,6 +543,8 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, #define KFD_HIQ_TIMEOUT (500) +#define KFD_FENCE_COMPLETED (100) +#define KFD_FENCE_INIT (10) #define KFD_UNMAP_LATENCY (150) struct packet_manager { @@ -547,6 +555,19 @@ struct packet_manager { struct kfd_mem_obj *ib_buffer_obj; }; +int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm); +void pm_uninit(struct packet_manager *pm); +int pm_send_set_resources(struct packet_manager *pm, + struct scheduling_resources *res); +int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues); +int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address, + uint32_t fence_value); + +int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type, + enum kfd_preempt_type_filter mode, + uint32_t filter_param, bool reset, + unsigned int sdma_engine); + void pm_release_ib(struct packet_manager *pm); uint64_t kfd_get_number_elems(struct kfd_dev *kfd); -- GitLab From b3f5e6b4412e69ebd7094c51aa345188a30a5cbe Mon Sep 17 00:00:00 2001 From: Andrew Lewycky Date: Thu, 17 Jul 2014 01:37:30 +0300 Subject: [PATCH 0024/9457] amdkfd: Add interrupt handling module This patch adds the interrupt handling module, in kfd_interrupt.c, and its related members in different data structures to the amdkfd driver. The amdkfd interrupt module maintains an internal interrupt ring per amdkfd device. The internal interrupt ring contains interrupts that needs further handling. The extra handling is deferred to a later time through a workqueue. There's no acknowledgment for the interrupts we use. The hardware simply queues a new interrupt each time without waiting. The fixed-size internal queue means that it's possible for us to lose interrupts because we have no back-pressure to the hardware. v3: Move amdkfd from drm/radeon/ to drm/amd/ Change device init Made sure spin lock is taken only if init is complete Moved bool field to the end of the structure Signed-off-by: Andrew Lewycky Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 23 ++- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 176 +++++++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 21 ++- 4 files changed, 218 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 307a309110e6..be6246de5091 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -8,6 +8,7 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ kfd_kernel_queue.o kfd_packet_manager.o \ - kfd_process_queue_manager.o kfd_device_queue_manager.o + kfd_process_queue_manager.o kfd_device_queue_manager.o \ + kfd_interrupt.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index bdf3e94590bd..9beb6f7bba9d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -31,6 +31,7 @@ static const struct kfd_device_info kaveri_device_info = { .max_pasid_bits = 16, + .ih_ring_entry_size = 4 * sizeof(uint32_t), .mqd_size_aligned = MQD_SIZE_ALIGNED }; @@ -191,6 +192,13 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_topology_add_device_error; } + if (kfd_interrupt_init(kfd)) { + dev_err(kfd_device, + "Error initializing interrupts for device (%x:%x)\n", + kfd->pdev->vendor, kfd->pdev->device); + goto kfd_interrupt_error; + } + if (!device_iommu_pasid_init(kfd)) { dev_err(kfd_device, "Error initializing iommuv2 for device (%x:%x)\n", @@ -229,6 +237,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, device_queue_manager_error: amd_iommu_free_device(kfd->pdev); device_iommu_pasid_error: + kfd_interrupt_exit(kfd); +kfd_interrupt_error: kfd_topology_remove_device(kfd); kfd_topology_add_device_error: kfd2kgd->fini_sa_manager(kfd->kgd); @@ -244,6 +254,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) if (kfd->init_complete) { device_queue_manager_uninit(kfd->dqm); amd_iommu_free_device(kfd->pdev); + kfd_interrupt_exit(kfd); kfd_topology_remove_device(kfd); } @@ -281,6 +292,16 @@ int kgd2kfd_resume(struct kfd_dev *kfd) return 0; } -void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry) +/* This is called directly from KGD at ISR. */ +void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) { + if (kfd->init_complete) { + spin_lock(&kfd->interrupt_lock); + + if (kfd->interrupts_active + && enqueue_ih_ring_entry(kfd, ih_ring_entry)) + schedule_work(&kfd->interrupt_work); + + spin_unlock(&kfd->interrupt_lock); + } } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c new file mode 100644 index 000000000000..5b999095a1f7 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -0,0 +1,176 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * KFD Interrupts. + * + * AMD GPUs deliver interrupts by pushing an interrupt description onto the + * interrupt ring and then sending an interrupt. KGD receives the interrupt + * in ISR and sends us a pointer to each new entry on the interrupt ring. + * + * We generally can't process interrupt-signaled events from ISR, so we call + * out to each interrupt client module (currently only the scheduler) to ask if + * each interrupt is interesting. If they return true, then it requires further + * processing so we copy it to an internal interrupt ring and call each + * interrupt client again from a work-queue. + * + * There's no acknowledgment for the interrupts we use. The hardware simply + * queues a new interrupt each time without waiting. + * + * The fixed-size internal queue means that it's possible for us to lose + * interrupts because we have no back-pressure to the hardware. + */ + +#include +#include +#include "kfd_priv.h" + +#define KFD_INTERRUPT_RING_SIZE 256 + +static void interrupt_wq(struct work_struct *); + +int kfd_interrupt_init(struct kfd_dev *kfd) +{ + void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE, + kfd->device_info->ih_ring_entry_size, + GFP_KERNEL); + if (!interrupt_ring) + return -ENOMEM; + + kfd->interrupt_ring = interrupt_ring; + kfd->interrupt_ring_size = + KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size; + atomic_set(&kfd->interrupt_ring_wptr, 0); + atomic_set(&kfd->interrupt_ring_rptr, 0); + + spin_lock_init(&kfd->interrupt_lock); + + INIT_WORK(&kfd->interrupt_work, interrupt_wq); + + kfd->interrupts_active = true; + + /* + * After this function returns, the interrupt will be enabled. This + * barrier ensures that the interrupt running on a different processor + * sees all the above writes. + */ + smp_wmb(); + + return 0; +} + +void kfd_interrupt_exit(struct kfd_dev *kfd) +{ + /* + * Stop the interrupt handler from writing to the ring and scheduling + * workqueue items. The spinlock ensures that any interrupt running + * after we have unlocked sees interrupts_active = false. + */ + unsigned long flags; + + spin_lock_irqsave(&kfd->interrupt_lock, flags); + kfd->interrupts_active = false; + spin_unlock_irqrestore(&kfd->interrupt_lock, flags); + + /* + * Flush_scheduled_work ensures that there are no outstanding + * work-queue items that will access interrupt_ring. New work items + * can't be created because we stopped interrupt handling above. + */ + flush_scheduled_work(); + + kfree(kfd->interrupt_ring); +} + +/* + * This assumes that it can't be called concurrently with itself + * but only with dequeue_ih_ring_entry. + */ +bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) +{ + unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); + unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); + + if ((rptr - wptr) % kfd->interrupt_ring_size == + kfd->device_info->ih_ring_entry_size) { + /* This is very bad, the system is likely to hang. */ + dev_err_ratelimited(kfd_chardev(), + "Interrupt ring overflow, dropping interrupt.\n"); + return false; + } + + memcpy(kfd->interrupt_ring + wptr, ih_ring_entry, + kfd->device_info->ih_ring_entry_size); + + wptr = (wptr + kfd->device_info->ih_ring_entry_size) % + kfd->interrupt_ring_size; + smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */ + atomic_set(&kfd->interrupt_ring_wptr, wptr); + + return true; +} + +/* + * This assumes that it can't be called concurrently with itself + * but only with enqueue_ih_ring_entry. + */ +static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) +{ + /* + * Assume that wait queues have an implicit barrier, i.e. anything that + * happened in the ISR before it queued work is visible. + */ + + unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); + unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); + + if (rptr == wptr) + return false; + + memcpy(ih_ring_entry, kfd->interrupt_ring + rptr, + kfd->device_info->ih_ring_entry_size); + + rptr = (rptr + kfd->device_info->ih_ring_entry_size) % + kfd->interrupt_ring_size; + + /* + * Ensure the rptr write update is not visible until + * memcpy has finished reading. + */ + smp_mb(); + atomic_set(&kfd->interrupt_ring_rptr, rptr); + + return true; +} + +static void interrupt_wq(struct work_struct *work) +{ + struct kfd_dev *dev = container_of(work, struct kfd_dev, + interrupt_work); + + uint32_t ih_ring_entry[DIV_ROUND_UP( + dev->device_info->ih_ring_entry_size, + sizeof(uint32_t))]; + + while (dequeue_ih_ring_entry(dev, ih_ring_entry)) + ; +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 7f3b4fdaa26e..2bc34aa1ad95 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -135,10 +135,22 @@ struct kfd_dev { struct kgd2kfd_shared_resources shared_resources; + void *interrupt_ring; + size_t interrupt_ring_size; + atomic_t interrupt_ring_rptr; + atomic_t interrupt_ring_wptr; + struct work_struct interrupt_work; + spinlock_t interrupt_lock; + /* QCM Device instance */ struct device_queue_manager *dqm; bool init_complete; + /* + * Interrupts of interest to KFD are copied + * from the HW ring into a SW ring. + */ + bool interrupts_active; }; /* KGD2KFD callbacks */ @@ -493,11 +505,14 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); /* Interrupts */ -void kgd2kfd_interrupt(struct kfd_dev *dev, const void *ih_ring_entry); +int kfd_interrupt_init(struct kfd_dev *dev); +void kfd_interrupt_exit(struct kfd_dev *dev); +void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); +bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry); /* Power Management */ -void kgd2kfd_suspend(struct kfd_dev *dev); -int kgd2kfd_resume(struct kfd_dev *dev); +void kgd2kfd_suspend(struct kfd_dev *kfd); +int kgd2kfd_resume(struct kfd_dev *kfd); /* amdkfd Apertures */ int kfd_init_apertures(struct kfd_process *process); -- GitLab From 39b027d957d4a9666a815ccf5bdce82e7796b2c6 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Sun, 19 Oct 2014 23:46:40 +0300 Subject: [PATCH 0025/9457] amdkfd: Implement the create/destroy/update queue IOCTLs v3: Removed the use of internal typedefs, fixed debug prints, added checks for parameters and moved to using doorbell address from user v4: Extracted some of the code in the create queue ioctl to a different function that may be also called from other ioctls in the future. Also fixed the check of the ring size argument. v5: Add support for AQL queues creation to enable working with open-source HSA runtime Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 205 ++++++++++++++++++++++- 1 file changed, 202 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 58441cd1b1d2..d342035a8634 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -125,22 +125,221 @@ static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, return -ENODEV; } +static int set_queue_properties_from_user(struct queue_properties *q_properties, + struct kfd_ioctl_create_queue_args *args) +{ + if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { + pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); + return -EINVAL; + } + + if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) { + pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); + return -EINVAL; + } + + if ((args->ring_base_address) && + (!access_ok(VERIFY_WRITE, args->ring_base_address, sizeof(uint64_t)))) { + pr_err("kfd: can't access ring base address\n"); + return -EFAULT; + } + + if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) { + pr_err("kfd: ring size must be a power of 2 or 0\n"); + return -EINVAL; + } + + if (!access_ok(VERIFY_WRITE, args->read_pointer_address, sizeof(uint32_t))) { + pr_err("kfd: can't access read pointer\n"); + return -EFAULT; + } + + if (!access_ok(VERIFY_WRITE, args->write_pointer_address, sizeof(uint32_t))) { + pr_err("kfd: can't access write pointer\n"); + return -EFAULT; + } + + q_properties->is_interop = false; + q_properties->queue_percent = args->queue_percentage; + q_properties->priority = args->queue_priority; + q_properties->queue_address = args->ring_base_address; + q_properties->queue_size = args->ring_size; + q_properties->read_ptr = (uint32_t *) args->read_pointer_address; + q_properties->write_ptr = (uint32_t *) args->write_pointer_address; + if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE || + args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL) + q_properties->type = KFD_QUEUE_TYPE_COMPUTE; + else + return -ENOTSUPP; + + if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL) + q_properties->format = KFD_QUEUE_FORMAT_AQL; + else + q_properties->format = KFD_QUEUE_FORMAT_PM4; + + pr_debug("Queue Percentage (%d, %d)\n", + q_properties->queue_percent, args->queue_percentage); + + pr_debug("Queue Priority (%d, %d)\n", + q_properties->priority, args->queue_priority); + + pr_debug("Queue Address (0x%llX, 0x%llX)\n", + q_properties->queue_address, args->ring_base_address); + + pr_debug("Queue Size (0x%llX, %u)\n", + q_properties->queue_size, args->ring_size); + + pr_debug("Queue r/w Pointers (0x%llX, 0x%llX)\n", + (uint64_t) q_properties->read_ptr, + (uint64_t) q_properties->write_ptr); + + pr_debug("Queue Format (%d)\n", q_properties->format); + + return 0; +} + static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, void __user *arg) { - return -ENODEV; + struct kfd_ioctl_create_queue_args args; + struct kfd_dev *dev; + int err = 0; + unsigned int queue_id; + struct kfd_process_device *pdd; + struct queue_properties q_properties; + + memset(&q_properties, 0, sizeof(struct queue_properties)); + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + pr_debug("kfd: creating queue ioctl\n"); + + err = set_queue_properties_from_user(&q_properties, &args); + if (err) + return err; + + dev = kfd_device_by_id(args.gpu_id); + if (dev == NULL) + return -EINVAL; + + mutex_lock(&p->mutex); + + pdd = kfd_bind_process_to_device(dev, p); + if (IS_ERR(pdd) < 0) { + err = PTR_ERR(pdd); + goto err_bind_process; + } + + pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n", + p->pasid, + dev->id); + + err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, 0, + KFD_QUEUE_TYPE_COMPUTE, &queue_id); + if (err != 0) + goto err_create_queue; + + args.queue_id = queue_id; + + /* Return gpu_id as doorbell offset for mmap usage */ + args.doorbell_offset = args.gpu_id << PAGE_SHIFT; + + if (copy_to_user(arg, &args, sizeof(args))) { + err = -EFAULT; + goto err_copy_args_out; + } + + mutex_unlock(&p->mutex); + + pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); + + pr_debug("ring buffer address == 0x%016llX\n", + args.ring_base_address); + + pr_debug("read ptr address == 0x%016llX\n", + args.read_pointer_address); + + pr_debug("write ptr address == 0x%016llX\n", + args.write_pointer_address); + + return 0; + +err_copy_args_out: + pqm_destroy_queue(&p->pqm, queue_id); +err_create_queue: +err_bind_process: + mutex_unlock(&p->mutex); + return err; } static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, void __user *arg) { - return -ENODEV; + int retval; + struct kfd_ioctl_destroy_queue_args args; + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + pr_debug("kfd: destroying queue id %d for PASID %d\n", + args.queue_id, + p->pasid); + + mutex_lock(&p->mutex); + + retval = pqm_destroy_queue(&p->pqm, args.queue_id); + + mutex_unlock(&p->mutex); + return retval; } static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, void __user *arg) { - return -ENODEV; + int retval; + struct kfd_ioctl_update_queue_args args; + struct queue_properties properties; + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { + pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); + return -EINVAL; + } + + if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { + pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); + return -EINVAL; + } + + if ((args.ring_base_address) && + (!access_ok(VERIFY_WRITE, args.ring_base_address, sizeof(uint64_t)))) { + pr_err("kfd: can't access ring base address\n"); + return -EFAULT; + } + + if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { + pr_err("kfd: ring size must be a power of 2 or 0\n"); + return -EINVAL; + } + + properties.queue_address = args.ring_base_address; + properties.queue_size = args.ring_size; + properties.queue_percent = args.queue_percentage; + properties.priority = args.queue_priority; + + pr_debug("kfd: updating queue id %d for PASID %d\n", + args.queue_id, p->pasid); + + mutex_lock(&p->mutex); + + retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); + + mutex_unlock(&p->mutex); + + return retval; } static long kfd_ioctl_set_memory_policy(struct file *filep, -- GitLab From 41a286fa54e850add4482146c511b088354f6f2d Mon Sep 17 00:00:00 2001 From: Andrew Lewycky Date: Thu, 17 Jul 2014 01:46:17 +0300 Subject: [PATCH 0026/9457] amdkfd: Implement the Set Memory Policy IOCTL Signed-off-by: Andrew Lewycky Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 52 +++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index d342035a8634..1020faf3d703 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -35,6 +35,7 @@ #include #include #include "kfd_priv.h" +#include "kfd_device_queue_manager.h" static long kfd_ioctl(struct file *, unsigned int, unsigned long); static int kfd_open(struct inode *, struct file *); @@ -345,7 +346,56 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, static long kfd_ioctl_set_memory_policy(struct file *filep, struct kfd_process *p, void __user *arg) { - return -ENODEV; + struct kfd_ioctl_set_memory_policy_args args; + struct kfd_dev *dev; + int err = 0; + struct kfd_process_device *pdd; + enum cache_policy default_policy, alternate_policy; + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT + && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { + return -EINVAL; + } + + if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT + && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { + return -EINVAL; + } + + dev = kfd_device_by_id(args.gpu_id); + if (dev == NULL) + return -EINVAL; + + mutex_lock(&p->mutex); + + pdd = kfd_bind_process_to_device(dev, p); + if (IS_ERR(pdd) < 0) { + err = PTR_ERR(pdd); + goto out; + } + + default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) + ? cache_policy_coherent : cache_policy_noncoherent; + + alternate_policy = + (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) + ? cache_policy_coherent : cache_policy_noncoherent; + + if (!dev->dqm->set_cache_memory_policy(dev->dqm, + &pdd->qpd, + default_policy, + alternate_policy, + (void __user *)args.alternate_aperture_base, + args.alternate_aperture_size)) + err = -EINVAL; + +out: + mutex_unlock(&p->mutex); + + return err; } static long kfd_ioctl_get_clock_counters(struct file *filep, -- GitLab From 4fac47c8206750128634622853c400570c44040d Mon Sep 17 00:00:00 2001 From: Evgeny Pinchuk Date: Thu, 17 Jul 2014 01:47:58 +0300 Subject: [PATCH 0027/9457] amdkfd: Implement the Get Clock Counters IOCTL Signed-off-by: Evgeny Pinchuk Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 1020faf3d703..473f8e16b669 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -401,7 +401,34 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, static long kfd_ioctl_get_clock_counters(struct file *filep, struct kfd_process *p, void __user *arg) { - return -ENODEV; + struct kfd_ioctl_get_clock_counters_args args; + struct kfd_dev *dev; + struct timespec time; + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + dev = kfd_device_by_id(args.gpu_id); + if (dev == NULL) + return -EINVAL; + + /* Reading GPU clock counter from KGD */ + args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); + + /* No access to rdtsc. Using raw monotonic time */ + getrawmonotonic(&time); + args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); + + get_monotonic_boottime(&time); + args.system_clock_counter = (uint64_t)timespec_to_ns(&time); + + /* Since the counter is in nano-seconds we use 1GHz frequency */ + args.system_clock_freq = 1000000000; + + if (copy_to_user(arg, &args, sizeof(args))) + return -EFAULT; + + return 0; } -- GitLab From 775921edc1c10f6022ee6614ff2914704fc605bf Mon Sep 17 00:00:00 2001 From: Alexey Skidanov Date: Thu, 17 Jul 2014 01:49:36 +0300 Subject: [PATCH 0028/9457] amdkfd: Implement the Get Process Aperture IOCTL v3: Fixed debug messages Signed-off-by: Alexey Skidanov Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 56 +++++++++++++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 6 +++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 473f8e16b669..3130265e6827 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -435,7 +435,61 @@ static long kfd_ioctl_get_clock_counters(struct file *filep, static int kfd_ioctl_get_process_apertures(struct file *filp, struct kfd_process *p, void __user *arg) { - return -ENODEV; + struct kfd_ioctl_get_process_apertures_args args; + struct kfd_process_device_apertures *pAperture; + struct kfd_process_device *pdd; + + dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + + args.num_of_nodes = 0; + + mutex_lock(&p->mutex); + + /*if the process-device list isn't empty*/ + if (kfd_has_process_device_data(p)) { + /* Run over all pdd of the process */ + pdd = kfd_get_first_process_device_data(p); + do { + pAperture = &args.process_apertures[args.num_of_nodes]; + pAperture->gpu_id = pdd->dev->id; + pAperture->lds_base = pdd->lds_base; + pAperture->lds_limit = pdd->lds_limit; + pAperture->gpuvm_base = pdd->gpuvm_base; + pAperture->gpuvm_limit = pdd->gpuvm_limit; + pAperture->scratch_base = pdd->scratch_base; + pAperture->scratch_limit = pdd->scratch_limit; + + dev_dbg(kfd_device, + "node id %u\n", args.num_of_nodes); + dev_dbg(kfd_device, + "gpu id %u\n", pdd->dev->id); + dev_dbg(kfd_device, + "lds_base %llX\n", pdd->lds_base); + dev_dbg(kfd_device, + "lds_limit %llX\n", pdd->lds_limit); + dev_dbg(kfd_device, + "gpuvm_base %llX\n", pdd->gpuvm_base); + dev_dbg(kfd_device, + "gpuvm_limit %llX\n", pdd->gpuvm_limit); + dev_dbg(kfd_device, + "scratch_base %llX\n", pdd->scratch_base); + dev_dbg(kfd_device, + "scratch_limit %llX\n", pdd->scratch_limit); + + args.num_of_nodes++; + } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && + (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); + } + + mutex_unlock(&p->mutex); + + if (copy_to_user(arg, &args, sizeof(args))) + return -EFAULT; + + return 0; } static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 2bc34aa1ad95..41e608d684b1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -473,6 +473,12 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process *p, int create_pdd); +/* Process device data iterator */ +struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p); +struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p, + struct kfd_process_device *pdd); +bool kfd_has_process_device_data(struct kfd_process *p); + /* PASIDs */ int kfd_pasid_init(void); void kfd_pasid_exit(void); -- GitLab From 8c50f10d73b50139dcfe48bc22f2c8c7822c1983 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Fri, 5 Sep 2014 14:13:16 +0100 Subject: [PATCH 0029/9457] drm/i915: Enable full PPGTT on gen7 Use full PPGTT as the default option in gen7. Note that aliasing PPGTT is the default option for gen8 (see HAS_PPGTT) since we're still fighting troubles around context switching and execlists. This may well come back to bite me later. Signed-off-by: Michel Thierry [danvet: Explain that gen8 full ppgtt is blocked on execlists for now.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6f410cfb0510..14f078c6cb75 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -59,7 +59,7 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) return 0; } - return HAS_ALIASING_PPGTT(dev) ? 1 : 0; + return HAS_PPGTT(dev) ? 2 : HAS_ALIASING_PPGTT(dev) ? 1 : 0; } -- GitLab From d518ce50e7c5bbdf0f1ff404b40cd073930af5a2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Aug 2014 10:43:37 +0200 Subject: [PATCH 0030/9457] drm/i915: WARN if interrupts aren't on in en/disable_pipestat Now that vlv has runtime pm we kinda should check for that like on the pch split platforms. Looks like this was simply lost in the vlv rpm enabling. Cc: Paulo Zanoni Cc: Imre Deak Cc: Jesse Barnes Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c96ddc953531..4847ed58597f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -589,6 +589,7 @@ __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; assert_spin_locked(&dev_priv->irq_lock); + WARN_ON(!intel_irqs_enabled(dev_priv)); if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || status_mask & ~PIPESTAT_INT_STATUS_MASK, @@ -615,6 +616,7 @@ __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; assert_spin_locked(&dev_priv->irq_lock); + WARN_ON(!intel_irqs_enabled(dev_priv)); if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || status_mask & ~PIPESTAT_INT_STATUS_MASK, -- GitLab From eeca778a3ec71022630e50935cfb7edab6f6f9e5 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 5 Sep 2014 17:04:46 -0300 Subject: [PATCH 0031/9457] drm/i915: create struct intel_plane_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new struct will be the storage of src and dst coordinates between the check and commit stages of a plane update. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07ce04683c30..dd5e0f1b2dfd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -34,6 +34,7 @@ #include #include #include +#include /** * _wait_for - magic (register) wait macro @@ -237,6 +238,17 @@ typedef struct dpll { int p; } intel_clock_t; +struct intel_plane_state { + struct drm_crtc *crtc; + struct drm_framebuffer *fb; + struct drm_rect src; + struct drm_rect dst; + struct drm_rect clip; + struct drm_rect orig_src; + struct drm_rect orig_dst; + bool visible; +}; + struct intel_plane_config { bool tiled; int size; -- GitLab From 96d61a7f267ff355a401ca23a732810027d10ba2 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 5 Sep 2014 17:04:47 -0300 Subject: [PATCH 0032/9457] drm/i915: split intel_update_plane into check() and commit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to the upcoming atomic modesetting feature we need to separate some update functions into a check step that can fail and a commit step that should, ideally, never fail. This commit splits intel_update_plane() and its commit part can still fail due to the fb pinning procedure. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 233 +++++++++++++++++----------- 1 file changed, 141 insertions(+), 92 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 07a74ef589bd..a4306cf94f56 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -845,57 +845,24 @@ static bool colorkey_enabled(struct intel_plane *intel_plane) } static int -intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +intel_check_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *state) { - struct drm_device *dev = plane->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc); struct intel_plane *intel_plane = to_intel_plane(plane); - enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *fb = state->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; - struct drm_i915_gem_object *old_obj = intel_plane->obj; - int ret; - bool primary_enabled; - bool visible; + int crtc_x, crtc_y; + unsigned int crtc_w, crtc_h; + uint32_t src_x, src_y, src_w, src_h; + struct drm_rect *src = &state->src; + struct drm_rect *dst = &state->dst; + struct drm_rect *orig_src = &state->orig_src; + const struct drm_rect *clip = &state->clip; int hscale, vscale; int max_scale, min_scale; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - struct drm_rect src = { - /* sample coordinates in 16.16 fixed point */ - .x1 = src_x, - .x2 = src_x + src_w, - .y1 = src_y, - .y2 = src_y + src_h, - }; - struct drm_rect dst = { - /* integer pixels */ - .x1 = crtc_x, - .x2 = crtc_x + crtc_w, - .y1 = crtc_y, - .y2 = crtc_y + crtc_h, - }; - const struct drm_rect clip = { - .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, - .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, - }; - const struct { - int crtc_x, crtc_y; - unsigned int crtc_w, crtc_h; - uint32_t src_x, src_y, src_w, src_h; - } orig = { - .crtc_x = crtc_x, - .crtc_y = crtc_y, - .crtc_w = crtc_w, - .crtc_h = crtc_h, - .src_x = src_x, - .src_y = src_y, - .src_w = src_w, - .src_h = src_h, - }; /* Don't modify another pipe's plane */ if (intel_plane->pipe != intel_crtc->pipe) { @@ -927,55 +894,55 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, max_scale = intel_plane->max_downscale << 16; min_scale = intel_plane->can_scale ? 1 : (1 << 16); - drm_rect_rotate(&src, fb->width << 16, fb->height << 16, + drm_rect_rotate(src, fb->width << 16, fb->height << 16, intel_plane->rotation); - hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); + hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(hscale < 0); - vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale); + vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(vscale < 0); - visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); + state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); - crtc_x = dst.x1; - crtc_y = dst.y1; - crtc_w = drm_rect_width(&dst); - crtc_h = drm_rect_height(&dst); + crtc_x = dst->x1; + crtc_y = dst->y1; + crtc_w = drm_rect_width(dst); + crtc_h = drm_rect_height(dst); - if (visible) { + if (state->visible) { /* check again in case clipping clamped the results */ - hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); + hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); if (hscale < 0) { DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); - drm_rect_debug_print(&src, true); - drm_rect_debug_print(&dst, false); + drm_rect_debug_print(src, true); + drm_rect_debug_print(dst, false); return hscale; } - vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); + vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); if (vscale < 0) { DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); - drm_rect_debug_print(&src, true); - drm_rect_debug_print(&dst, false); + drm_rect_debug_print(src, true); + drm_rect_debug_print(dst, false); return vscale; } /* Make the source viewport size an exact multiple of the scaling factors. */ - drm_rect_adjust_size(&src, - drm_rect_width(&dst) * hscale - drm_rect_width(&src), - drm_rect_height(&dst) * vscale - drm_rect_height(&src)); + drm_rect_adjust_size(src, + drm_rect_width(dst) * hscale - drm_rect_width(src), + drm_rect_height(dst) * vscale - drm_rect_height(src)); - drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16, + drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, intel_plane->rotation); /* sanity check to make sure the src viewport wasn't enlarged */ - WARN_ON(src.x1 < (int) src_x || - src.y1 < (int) src_y || - src.x2 > (int) (src_x + src_w) || - src.y2 > (int) (src_y + src_h)); + WARN_ON(src->x1 < (int) orig_src->x1 || + src->y1 < (int) orig_src->y1 || + src->x2 > (int) orig_src->x2 || + src->y2 > (int) orig_src->y2); /* * Hardware doesn't handle subpixel coordinates. @@ -983,10 +950,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, * increase the source viewport size, because that could * push the downscaling factor out of bounds. */ - src_x = src.x1 >> 16; - src_w = drm_rect_width(&src) >> 16; - src_y = src.y1 >> 16; - src_h = drm_rect_height(&src) >> 16; + src_x = src->x1 >> 16; + src_w = drm_rect_width(src) >> 16; + src_y = src->y1 >> 16; + src_h = drm_rect_height(src) >> 16; if (format_is_yuv(fb->pixel_format)) { src_x &= ~1; @@ -1000,12 +967,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, crtc_w &= ~1; if (crtc_w == 0) - visible = false; + state->visible = false; } } /* Check size restrictions when scaling */ - if (visible && (src_w != crtc_w || src_h != crtc_h)) { + if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { unsigned int width_bytes; WARN_ON(!intel_plane->can_scale); @@ -1013,12 +980,13 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, /* FIXME interlacing min height is 6 */ if (crtc_w < 3 || crtc_h < 3) - visible = false; + state->visible = false; if (src_w < 3 || src_h < 3) - visible = false; + state->visible = false; - width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size; + width_bytes = ((src_x * pixel_size) & 63) + + src_w * pixel_size; if (src_w > 2048 || src_h > 2048 || width_bytes > 4096 || fb->pitches[0] > 4096) { @@ -1027,17 +995,48 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, } } - dst.x1 = crtc_x; - dst.x2 = crtc_x + crtc_w; - dst.y1 = crtc_y; - dst.y2 = crtc_y + crtc_h; + if (state->visible) { + src->x1 = src_x; + src->x2 = src_x + src_w; + src->y1 = src_y; + src->y2 = src_y + src_h; + } + + dst->x1 = crtc_x; + dst->x2 = crtc_x + crtc_w; + dst->y1 = crtc_y; + dst->y2 = crtc_y + crtc_h; + + return 0; +} + +static int +intel_commit_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *state) +{ + struct drm_device *dev = plane->dev; + struct drm_crtc *crtc = state->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane *intel_plane = to_intel_plane(plane); + enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *fb = state->fb; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj = intel_fb->obj; + struct drm_i915_gem_object *old_obj = intel_plane->obj; + int crtc_x, crtc_y; + unsigned int crtc_w, crtc_h; + uint32_t src_x, src_y, src_w, src_h; + struct drm_rect *dst = &state->dst; + const struct drm_rect *clip = &state->clip; + bool primary_enabled; + int ret; /* * If the sprite is completely covering the primary plane, * we can disable the primary and save power. */ - primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane); - WARN_ON(!primary_enabled && !visible && intel_crtc->active); + primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); + WARN_ON(!primary_enabled && !state->visible && intel_crtc->active); mutex_lock(&dev->struct_mutex); @@ -1055,14 +1054,14 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; - intel_plane->crtc_x = orig.crtc_x; - intel_plane->crtc_y = orig.crtc_y; - intel_plane->crtc_w = orig.crtc_w; - intel_plane->crtc_h = orig.crtc_h; - intel_plane->src_x = orig.src_x; - intel_plane->src_y = orig.src_y; - intel_plane->src_w = orig.src_w; - intel_plane->src_h = orig.src_h; + intel_plane->crtc_x = state->orig_dst.x1; + intel_plane->crtc_y = state->orig_dst.y1; + intel_plane->crtc_w = drm_rect_width(&state->orig_dst); + intel_plane->crtc_h = drm_rect_height(&state->orig_dst); + intel_plane->src_x = state->orig_src.x1; + intel_plane->src_y = state->orig_src.y1; + intel_plane->src_w = drm_rect_width(&state->orig_src); + intel_plane->src_h = drm_rect_height(&state->orig_src); intel_plane->obj = obj; if (intel_crtc->active) { @@ -1076,12 +1075,22 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (primary_was_enabled && !primary_enabled) intel_pre_disable_primary(crtc); - if (visible) + if (state->visible) { + crtc_x = state->dst.x1; + crtc_y = state->dst.x2; + crtc_w = drm_rect_width(&state->dst); + crtc_h = drm_rect_height(&state->dst); + src_x = state->src.x1; + src_y = state->src.y1; + src_w = drm_rect_width(&state->src); + src_h = drm_rect_height(&state->src); intel_plane->update_plane(plane, crtc, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h); - else + } else { intel_plane->disable_plane(plane, crtc); + } + intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe)); @@ -1108,6 +1117,46 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, return 0; } +static int +intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct intel_plane_state state; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int ret; + + state.crtc = crtc; + state.fb = fb; + + /* sample coordinates in 16.16 fixed point */ + state.src.x1 = src_x; + state.src.x2 = src_x + src_w; + state.src.y1 = src_y; + state.src.y2 = src_y + src_h; + + /* integer pixels */ + state.dst.x1 = crtc_x; + state.dst.x2 = crtc_x + crtc_w; + state.dst.y1 = crtc_y; + state.dst.y2 = crtc_y + crtc_h; + + state.clip.x1 = 0; + state.clip.y1 = 0; + state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0; + state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0; + state.orig_src = state.src; + state.orig_dst = state.dst; + + ret = intel_check_sprite_plane(plane, &state); + if (ret) + return ret; + + return intel_commit_sprite_plane(plane, &state); +} + static int intel_disable_plane(struct drm_plane *plane) { -- GitLab From 852e787c4cb9fcc34cf81d2a764a1aee2d9f24bd Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 5 Sep 2014 17:22:31 -0300 Subject: [PATCH 0033/9457] drm/i915: split intel_cursor_plane_update() into check() and commit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to the upcoming atomic modesetting feature we need to separate some update functions into a check step that can fail and a commit step that should, ideally, never fail. The commit part can still fail, but that should be solved in another upcoming patch. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 106 +++++++++++++++++---------- 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c5079f2c49f3..8de7d4cf03da 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12040,51 +12040,41 @@ intel_cursor_plane_disable(struct drm_plane *plane) } static int -intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +intel_check_cursor_plane(struct drm_plane *plane, + struct intel_plane_state *state) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct drm_rect dest = { - /* integer pixels */ - .x1 = crtc_x, - .y1 = crtc_y, - .x2 = crtc_x + crtc_w, - .y2 = crtc_y + crtc_h, - }; - struct drm_rect src = { - /* 16.16 fixed point */ - .x1 = src_x, - .y1 = src_y, - .x2 = src_x + src_w, - .y2 = src_y + src_h, - }; - const struct drm_rect clip = { - /* integer pixels */ - .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, - .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, - }; - bool visible; - int ret; + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; + struct drm_rect *dest = &state->dst; + struct drm_rect *src = &state->src; + const struct drm_rect *clip = &state->clip; - ret = drm_plane_helper_check_update(plane, crtc, fb, - &src, &dest, &clip, + return drm_plane_helper_check_update(plane, crtc, fb, + src, dest, clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, - true, true, &visible); - if (ret) - return ret; + true, true, &state->visible); +} - crtc->cursor_x = crtc_x; - crtc->cursor_y = crtc_y; +static int +intel_commit_cursor_plane(struct drm_plane *plane, + struct intel_plane_state *state) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj = intel_fb->obj; + int crtc_w, crtc_h; + + crtc->cursor_x = state->orig_dst.x1; + crtc->cursor_y = state->orig_dst.y1; if (fb != crtc->cursor->fb) { + crtc_w = drm_rect_width(&state->orig_dst); + crtc_h = drm_rect_height(&state->orig_dst); return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h); } else { - intel_crtc_update_cursor(crtc, visible); + intel_crtc_update_cursor(crtc, state->visible); intel_frontbuffer_flip(crtc->dev, INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe)); @@ -12092,6 +12082,48 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return 0; } } + +static int +intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane_state state; + int ret; + + state.crtc = crtc; + state.fb = fb; + + /* sample coordinates in 16.16 fixed point */ + state.src.x1 = src_x; + state.src.x2 = src_x + src_w; + state.src.y1 = src_y; + state.src.y2 = src_y + src_h; + + /* integer pixels */ + state.dst.x1 = crtc_x; + state.dst.x2 = crtc_x + crtc_w; + state.dst.y1 = crtc_y; + state.dst.y2 = crtc_y + crtc_h; + + state.clip.x1 = 0; + state.clip.y1 = 0; + state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0; + state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0; + + state.orig_src = state.src; + state.orig_dst = state.dst; + + ret = intel_check_cursor_plane(plane, &state); + if (ret) + return ret; + + return intel_commit_cursor_plane(plane, &state); +} + static const struct drm_plane_funcs intel_cursor_plane_funcs = { .update_plane = intel_cursor_plane_update, .disable_plane = intel_cursor_plane_disable, -- GitLab From 3c692a4162b7bf9eff9ba677228254d2f633a785 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 5 Sep 2014 17:04:49 -0300 Subject: [PATCH 0034/9457] drm/i915: split intel_primary_plane_setplane() into check() and commit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a preparation for atomic updates we need to split the code to check everything we are going to commit first. This patch starts the work to split intel_primary_plane_setplane() into check() and commit() parts. More work is expected on this to get a better split of the two steps. Ideally the commit() step should never fail. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 133 +++++++++++++++------------ 1 file changed, 75 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8de7d4cf03da..fc1844d7076f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11807,63 +11807,37 @@ intel_primary_plane_disable(struct drm_plane *plane) } static int -intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +intel_check_primary_plane(struct drm_plane *plane, + struct intel_plane_state *state) { + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; + struct drm_rect *dest = &state->dst; + struct drm_rect *src = &state->src; + const struct drm_rect *clip = &state->clip; + + return drm_plane_helper_check_update(plane, crtc, fb, + src, dest, clip, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + false, true, &state->visible); +} + +static int +intel_commit_primary_plane(struct drm_plane *plane, + struct intel_plane_state *state) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); - struct drm_rect dest = { - /* integer pixels */ - .x1 = crtc_x, - .y1 = crtc_y, - .x2 = crtc_x + crtc_w, - .y2 = crtc_y + crtc_h, - }; - struct drm_rect src = { - /* 16.16 fixed point */ - .x1 = src_x, - .y1 = src_y, - .x2 = src_x + src_w, - .y2 = src_y + src_h, - }; - const struct drm_rect clip = { - /* integer pixels */ - .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, - .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, - }; - const struct { - int crtc_x, crtc_y; - unsigned int crtc_w, crtc_h; - uint32_t src_x, src_y, src_w, src_h; - } orig = { - .crtc_x = crtc_x, - .crtc_y = crtc_y, - .crtc_w = crtc_w, - .crtc_h = crtc_h, - .src_x = src_x, - .src_y = src_y, - .src_w = src_w, - .src_h = src_h, - }; struct intel_plane *intel_plane = to_intel_plane(plane); - bool visible; + struct drm_rect *src = &state->src; int ret; - ret = drm_plane_helper_check_update(plane, crtc, fb, - &src, &dest, &clip, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, true, &visible); - - if (ret) - return ret; - /* * If the CRTC isn't enabled, we're just pinning the framebuffer, * updating the fb pointer, and returning without touching the @@ -11898,7 +11872,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, * happens if userspace explicitly disables the plane by passing fb=0 * because plane->fb still gets set and pinned. */ - if (!visible) { + if (!state->visible) { mutex_lock(&dev->struct_mutex); /* @@ -11945,7 +11919,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, intel_disable_fbc(dev); } } - ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb); + ret = intel_pipe_set_base(crtc, src->x1, src->y1, fb); if (ret) return ret; @@ -11953,19 +11927,62 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, intel_enable_primary_hw_plane(plane, crtc); } - intel_plane->crtc_x = orig.crtc_x; - intel_plane->crtc_y = orig.crtc_y; - intel_plane->crtc_w = orig.crtc_w; - intel_plane->crtc_h = orig.crtc_h; - intel_plane->src_x = orig.src_x; - intel_plane->src_y = orig.src_y; - intel_plane->src_w = orig.src_w; - intel_plane->src_h = orig.src_h; + intel_plane->crtc_x = state->orig_dst.x1; + intel_plane->crtc_y = state->orig_dst.y1; + intel_plane->crtc_w = drm_rect_width(&state->orig_dst); + intel_plane->crtc_h = drm_rect_height(&state->orig_dst); + intel_plane->src_x = state->orig_src.x1; + intel_plane->src_y = state->orig_src.y1; + intel_plane->src_w = drm_rect_width(&state->orig_src); + intel_plane->src_h = drm_rect_height(&state->orig_src); intel_plane->obj = obj; return 0; } +static int +intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct intel_plane_state state; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int ret; + + state.crtc = crtc; + state.fb = fb; + + /* sample coordinates in 16.16 fixed point */ + state.src.x1 = src_x; + state.src.x2 = src_x + src_w; + state.src.y1 = src_y; + state.src.y2 = src_y + src_h; + + /* integer pixels */ + state.dst.x1 = crtc_x; + state.dst.x2 = crtc_x + crtc_w; + state.dst.y1 = crtc_y; + state.dst.y2 = crtc_y + crtc_h; + + state.clip.x1 = 0; + state.clip.y1 = 0; + state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0; + state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0; + + state.orig_src = state.src; + state.orig_dst = state.dst; + + ret = intel_check_primary_plane(plane, &state); + if (ret) + return ret; + + intel_commit_primary_plane(plane, &state); + + return 0; +} + /* Common destruction function for both primary and cursor planes */ static void intel_plane_destroy(struct drm_plane *plane) { -- GitLab From 2363d8c97f87738dba7af7d2103f4f26b3bf5916 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 8 Sep 2014 18:28:20 +0200 Subject: [PATCH 0035/9457] drm/i915: Restore resume irq ordering comment This was lost in commit e11aa362308f5de467ce355a2a2471321b15a35c Author: Jesse Barnes Date: Wed Jun 18 09:52:55 2014 -0700 drm/i915: use runtime irq suspend/resume in freeze/thaw which makes the second part of this commen a bit nonsense. Both were originally added in commit 15239099d7a7a9ecdc1ccb5b187ae4cda5488ff9 Author: Daniel Vetter Date: Tue Mar 5 09:50:58 2013 +0100 drm/i915: enable irqs earlier when resuming Cc: Jesse Barnes Cc: Imre Deak Cc: Chris Wilson Cc: Mika Kuoppala Signed-off-by: Daniel Vetter Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 055d5e7fbf12..b8bd0080603e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -680,6 +680,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) } mutex_unlock(&dev->struct_mutex); + /* We need working interrupts for modeset enabling ... */ intel_runtime_pm_restore_interrupts(dev); intel_modeset_init_hw(dev); -- GitLab From 94f598f176600a857817e010f266cdc30efa585b Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Tue, 9 Sep 2014 11:43:19 -0300 Subject: [PATCH 0036/9457] drm/i915: remove !enabled handling from commit primary plane step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The !crtc->enabled case will now be handled by the !visible code, since the handling is basically the same. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fc1844d7076f..870555b3ccf7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11838,32 +11838,6 @@ intel_commit_primary_plane(struct drm_plane *plane, struct drm_rect *src = &state->src; int ret; - /* - * If the CRTC isn't enabled, we're just pinning the framebuffer, - * updating the fb pointer, and returning without touching the - * hardware. This allows us to later do a drmModeSetCrtc with fb=-1 to - * turn on the display with all planes setup as desired. - */ - if (!crtc->enabled) { - mutex_lock(&dev->struct_mutex); - - /* - * If we already called setplane while the crtc was disabled, - * we may have an fb pinned; unpin it. - */ - if (plane->fb) - intel_unpin_fb_obj(old_obj); - - i915_gem_track_fb(old_obj, obj, - INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe)); - - /* Pin and return without programming hardware */ - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - mutex_unlock(&dev->struct_mutex); - - return ret; - } - intel_crtc_wait_for_pending_flips(crtc); /* -- GitLab From 25067bfc060d1a481584dcb51ef4b5680176ecb6 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 10 Sep 2014 12:03:17 -0300 Subject: [PATCH 0037/9457] drm/i915: pin sprite fb only if it changed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optimize code avoiding helding dev mutex if old fb and current fb are the same. v2: take Ville's comments - move comment along with the pin_and_fence call - check for error before calling i915_gem_track_fb - move old_obj != obj to an upper if condition Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 34 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a4306cf94f56..90bb45fdff5a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1038,21 +1038,24 @@ intel_commit_sprite_plane(struct drm_plane *plane, primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); WARN_ON(!primary_enabled && !state->visible && intel_crtc->active); - mutex_lock(&dev->struct_mutex); - - /* Note that this will apply the VT-d workaround for scanouts, - * which is more restrictive than required for sprites. (The - * primary plane requires 256KiB alignment with 64 PTE padding, - * the sprite planes only require 128KiB alignment and 32 PTE padding. - */ - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - i915_gem_track_fb(old_obj, obj, - INTEL_FRONTBUFFER_SPRITE(pipe)); - mutex_unlock(&dev->struct_mutex); + if (old_obj != obj) { + mutex_lock(&dev->struct_mutex); - if (ret) - return ret; + /* Note that this will apply the VT-d workaround for scanouts, + * which is more restrictive than required for sprites. (The + * primary plane requires 256KiB alignment with 64 PTE padding, + * the sprite planes only require 128KiB alignment and 32 PTE + * padding. + */ + ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); + if (ret == 0) + i915_gem_track_fb(old_obj, obj, + INTEL_FRONTBUFFER_SPRITE(pipe)); + mutex_unlock(&dev->struct_mutex); + if (ret) + return ret; + } intel_plane->crtc_x = state->orig_dst.x1; intel_plane->crtc_y = state->orig_dst.y1; @@ -1099,14 +1102,15 @@ intel_commit_sprite_plane(struct drm_plane *plane, } /* Unpin old obj after new one is active to avoid ugliness */ - if (old_obj) { + if (old_obj && old_obj != obj) { + /* * It's fairly common to simply update the position of * an existing object. In that case, we don't need to * wait for vblank to avoid ugliness, we only need to * do the pin & ref bookkeeping. */ - if (old_obj != obj && intel_crtc->active) + if (intel_crtc->active) intel_wait_for_vblank(dev, intel_crtc->pipe); mutex_lock(&dev->struct_mutex); -- GitLab From e30e8f7536f14ce42841f0d30bb2ca3d14f120f3 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 10 Sep 2014 12:04:17 -0300 Subject: [PATCH 0038/9457] drm/i915: create intel_update_pipe_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factor out a piece of code from intel_pipe_set_base() that updates the pipe size and adjust fitter. This will help refactor the update primary plane path. v2: use struct intel_crtc as argument to intel_update_pipe_size() v3: use 'crtc' as argument name Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 70 ++++++++++++++++------------ 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 870555b3ccf7..1556c70e2253 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2779,6 +2779,45 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) return pending; } +static void intel_update_pipe_size(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const struct drm_display_mode *adjusted_mode; + + if (!i915.fastboot) + return; + + /* + * Update pipe size and adjust fitter if needed: the reason for this is + * that in compute_mode_changes we check the native mode (not the pfit + * mode) to see if we can flip rather than do a full mode set. In the + * fastboot case, we'll flip, but if we don't update the pipesrc and + * pfit state, we'll end up with a big fb scanned out into the wrong + * sized surface. + * + * To fix this properly, we need to hoist the checks up into + * compute_mode_changes (or above), check the actual pfit state and + * whether the platform allows pfit disable with pipe active, and only + * then update the pipesrc and pfit state, even on the flip path. + */ + + adjusted_mode = &crtc->config.adjusted_mode; + + I915_WRITE(PIPESRC(crtc->pipe), + ((adjusted_mode->crtc_hdisplay - 1) << 16) | + (adjusted_mode->crtc_vdisplay - 1)); + if (!crtc->config.pch_pfit.enabled && + (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))) { + I915_WRITE(PF_CTL(crtc->pipe), 0); + I915_WRITE(PF_WIN_POS(crtc->pipe), 0); + I915_WRITE(PF_WIN_SZ(crtc->pipe), 0); + } + crtc->config.pipe_src_w = adjusted_mode->crtc_hdisplay; + crtc->config.pipe_src_h = adjusted_mode->crtc_vdisplay; +} + static int intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *fb) @@ -2821,36 +2860,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - /* - * Update pipe size and adjust fitter if needed: the reason for this is - * that in compute_mode_changes we check the native mode (not the pfit - * mode) to see if we can flip rather than do a full mode set. In the - * fastboot case, we'll flip, but if we don't update the pipesrc and - * pfit state, we'll end up with a big fb scanned out into the wrong - * sized surface. - * - * To fix this properly, we need to hoist the checks up into - * compute_mode_changes (or above), check the actual pfit state and - * whether the platform allows pfit disable with pipe active, and only - * then update the pipesrc and pfit state, even on the flip path. - */ - if (i915.fastboot) { - const struct drm_display_mode *adjusted_mode = - &intel_crtc->config.adjusted_mode; - - I915_WRITE(PIPESRC(intel_crtc->pipe), - ((adjusted_mode->crtc_hdisplay - 1) << 16) | - (adjusted_mode->crtc_vdisplay - 1)); - if (!intel_crtc->config.pch_pfit.enabled && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { - I915_WRITE(PF_CTL(intel_crtc->pipe), 0); - I915_WRITE(PF_WIN_POS(intel_crtc->pipe), 0); - I915_WRITE(PF_WIN_SZ(intel_crtc->pipe), 0); - } - intel_crtc->config.pipe_src_w = adjusted_mode->crtc_hdisplay; - intel_crtc->config.pipe_src_h = adjusted_mode->crtc_vdisplay; - } + intel_update_pipe_size(intel_crtc); dev_priv->display.update_primary_plane(crtc, fb, x, y); -- GitLab From be2d599b5da3936ca92e0187ff50b34b6b8ff997 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Sep 2014 19:52:18 +0100 Subject: [PATCH 0039/9457] drm/i915: Remove dead code, i915_gem_verify_gtt The data structure it was supposed to be sanity checking has long gone. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 42 --------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 28f91df2604d..2fb87cfa5b82 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3384,46 +3384,6 @@ static bool i915_gem_valid_gtt_space(struct i915_vma *vma, return true; } -static void i915_gem_verify_gtt(struct drm_device *dev) -{ -#if WATCH_GTT - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int err = 0; - - list_for_each_entry(obj, &dev_priv->mm.gtt_list, global_list) { - if (obj->gtt_space == NULL) { - printk(KERN_ERR "object found on GTT list with no space reserved\n"); - err++; - continue; - } - - if (obj->cache_level != obj->gtt_space->color) { - printk(KERN_ERR "object reserved space [%08lx, %08lx] with wrong color, cache_level=%x, color=%lx\n", - i915_gem_obj_ggtt_offset(obj), - i915_gem_obj_ggtt_offset(obj) + i915_gem_obj_ggtt_size(obj), - obj->cache_level, - obj->gtt_space->color); - err++; - continue; - } - - if (!i915_gem_valid_gtt_space(dev, - obj->gtt_space, - obj->cache_level)) { - printk(KERN_ERR "invalid GTT space found at [%08lx, %08lx] - color=%x\n", - i915_gem_obj_ggtt_offset(obj), - i915_gem_obj_ggtt_offset(obj) + i915_gem_obj_ggtt_size(obj), - obj->cache_level); - err++; - continue; - } - } - - WARN_ON(err); -#endif -} - /** * Finds free space in the GTT aperture and binds the object there. */ @@ -3532,7 +3492,6 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, vma->bind_vma(vma, obj->cache_level, flags & (PIN_MAPPABLE | PIN_GLOBAL) ? GLOBAL_BIND : 0); - i915_gem_verify_gtt(dev); return vma; err_remove_node: @@ -3769,7 +3728,6 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, old_write_domain); } - i915_gem_verify_gtt(dev); return 0; } -- GitLab From e259f172adf25b40c7a0c9baeb71b783f3ef9036 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 11 Sep 2014 17:42:15 -0300 Subject: [PATCH 0040/9457] drm/i915: Fix regression in the sprite plane update split 7e4bf45dbd99a965c7b5d5944c6dc4246f171eb5 introduced the regression. We fix it by doing the right assignment of crtc_y Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83747 Signed-off-by: Gustavo Padovan Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 90bb45fdff5a..78044bbed8c9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1080,7 +1080,7 @@ intel_commit_sprite_plane(struct drm_plane *plane, if (state->visible) { crtc_x = state->dst.x1; - crtc_y = state->dst.x2; + crtc_y = state->dst.y1; crtc_w = drm_rect_width(&state->dst); crtc_h = drm_rect_height(&state->dst); src_x = state->src.x1; -- GitLab From c04d016124f2290762d9535690b817855dd80fc1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Sep 2014 15:18:13 +0200 Subject: [PATCH 0041/9457] drm/i915: Drop get/put_pages for scratch page While discussing/reviewing __GFP_MOVEABLE behaviour and interactions with our various page allocations on irc Chris brought up that the scratch page isn't allocated as moveable, but we still grab/put a reference to lock it in place. Which is unecessary. So drop that. Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 14f078c6cb75..a234446a8678 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1752,7 +1752,6 @@ static int setup_scratch_page(struct drm_device *dev) page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); if (page == NULL) return -ENOMEM; - get_page(page); set_pages_uc(page, 1); #ifdef CONFIG_INTEL_IOMMU @@ -1777,7 +1776,6 @@ static void teardown_scratch_page(struct drm_device *dev) set_pages_wb(page, 1); pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - put_page(page); __free_page(page); } -- GitLab From f77c44b902a032718e2431a5fc9211ef0b0282d3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Sep 2014 15:20:24 +0200 Subject: [PATCH 0042/9457] agp/intel-gtt: Remove get/put_pages If a page isn't allocated as __GFP_MOVEABLE it won't move around, so no need to grab a reference to lock it into place. Discovered while reviewing page allocation handling in i915 gem. Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/char/agp/intel-gtt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9a024f899dd4..f3334829e55a 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -153,7 +153,6 @@ static struct page *i8xx_alloc_pages(void) __free_pages(page, 2); return NULL; } - get_page(page); atomic_inc(&agp_bridge->current_memory_agp); return page; } @@ -164,7 +163,6 @@ static void i8xx_destroy_pages(struct page *page) return; set_pages_wb(page, 4); - put_page(page); __free_pages(page, 2); atomic_dec(&agp_bridge->current_memory_agp); } @@ -300,7 +298,6 @@ static int intel_gtt_setup_scratch_page(void) page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); if (page == NULL) return -ENOMEM; - get_page(page); set_pages_uc(page, 1); if (intel_private.needs_dmar) { @@ -560,7 +557,6 @@ static void intel_gtt_teardown_scratch_page(void) set_pages_wb(intel_private.scratch_page, 1); pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - put_page(intel_private.scratch_page); __free_page(intel_private.scratch_page); } -- GitLab From 99d1f3878baa86d5ce9e275ae9568fd903616f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 12 Sep 2014 20:53:32 +0300 Subject: [PATCH 0043/9457] drm/i915: Move the cursor_base setup to i{845, 9xx}_update_cursor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make the code a bit more undestandable move the intel_crtc->cursor_base assignment into the low level update cursor routines. That's were we compare the current value with the new one so immediately seeing that it gets assigned only afterwards helps one to understand that it gets assigned only after the comparison. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1556c70e2253..fbfdaf4f36b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8258,8 +8258,10 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) intel_crtc->cursor_cntl = 0; } - if (intel_crtc->cursor_base != base) + if (intel_crtc->cursor_base != base) { I915_WRITE(_CURABASE, base); + intel_crtc->cursor_base = base; + } if (intel_crtc->cursor_size != size) { I915_WRITE(CURSIZE, size); @@ -8312,6 +8314,8 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) /* and commit changes on next vblank */ I915_WRITE(CURBASE(pipe), base); POSTING_READ(CURBASE(pipe)); + + intel_crtc->cursor_base = base; } /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ @@ -8362,7 +8366,6 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, i845_update_cursor(crtc, base); else i9xx_update_cursor(crtc, base); - intel_crtc->cursor_base = base; } static bool cursor_size_ok(struct drm_device *dev, -- GitLab From 47bf17a7d1676f5f0e5c8d45f0fd0c5050add78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 12 Sep 2014 20:53:33 +0300 Subject: [PATCH 0044/9457] drm/i915: Only set CURSOR_PIPE_CSC_ENABLE when cursor is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems cleaner if we keep CURCNTR at 0 when the cursor is disabled, so don't set the CURSOR_PIPE_CSC_ENABLE bit unless the cursor is enabled. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fbfdaf4f36b9..007f465227cf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8301,9 +8301,10 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) return; } cntl |= pipe << 28; /* Connect to correct pipe */ + + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + cntl |= CURSOR_PIPE_CSC_ENABLE; } - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - cntl |= CURSOR_PIPE_CSC_ENABLE; if (intel_crtc->cursor_cntl != cntl) { I915_WRITE(CURCNTR(pipe), cntl); -- GitLab From 950eabaf5a87257040e0c207be09487954113f54 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 8 Sep 2014 15:21:09 +0300 Subject: [PATCH 0045/9457] drm/i915: vlv: fix display IRQ enable/disable We want to enable/disable display IRQs only if global i915 IRQs are enabled. To check the latter it's not enough to consult the DRM dev->irq_enabled flag, since runtime PM can disable/enable IRQs and it won't adjust this flag only the i915 specific dev_priv->pm._irqs_disabled flag. Fix this by using the proper intel_irqs_enabled() helper instead. Fortunately this didn't cause an actual problem since even if we enabled display IRQs too early (before enabling global i915 IRQs) the VLV_MASTER_IER would still be clear masking all IRQs. This issue was caught by commit 920dd15a2b2fc60d054646a8a1ffd6aeb6090e05 Author: Daniel Vetter Date: Wed Aug 27 10:43:37 2014 +0200 drm/i915: WARN if interrupts aren't on in en/disable_pipestat Signed-off-by: Imre Deak Cc: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4847ed58597f..d22f87020aee 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3723,7 +3723,7 @@ void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) dev_priv->display_irqs_enabled = true; - if (dev_priv->dev->irq_enabled) + if (intel_irqs_enabled(dev_priv)) valleyview_display_irqs_install(dev_priv); } @@ -3736,7 +3736,7 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) dev_priv->display_irqs_enabled = false; - if (dev_priv->dev->irq_enabled) + if (intel_irqs_enabled(dev_priv)) valleyview_display_irqs_uninstall(dev_priv); } -- GitLab From 7cd512f1520f85bf8e45f75b82fece58f0265cec Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 11:38:57 +0200 Subject: [PATCH 0046/9457] drm/i915: Fix irq checks in ring->irq_get/put functions Yet another place that wasn't properly transformed when implementing SOix. While at it convert the checks to WARN_ON on gen5+ (since we don't have UMS potentially doing stupid things on those platforms). And also add the corresponding checks to the put functions (again with a WARN_ON) for gen5+. v2: Drop the WARNINGS in the irq_put functions (including the existing one for vebox), Chris convinced me that they're not that terribly useful. v3: Don't forget about execlist code. Cc: Imre Deak Cc: Jesse Barnes Cc: "Volkin, Bradley D" Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bafd38b5703e..803fc38664c4 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1063,7 +1063,7 @@ static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 25795f2efdcb..922d6bc1a1b3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1197,7 +1197,7 @@ gen5_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); @@ -1228,7 +1228,7 @@ i9xx_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (!intel_irqs_enabled(dev_priv)) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); @@ -1265,7 +1265,7 @@ i8xx_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (!intel_irqs_enabled(dev_priv)) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); @@ -1399,8 +1399,8 @@ gen6_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) - return false; + if (WARN_ON(!intel_irqs_enabled(dev_priv))) + return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); if (ring->irq_refcount++ == 0) { @@ -1442,7 +1442,7 @@ hsw_vebox_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); @@ -1462,9 +1462,6 @@ hsw_vebox_put_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) - return; - spin_lock_irqsave(&dev_priv->irq_lock, flags); if (--ring->irq_refcount == 0) { I915_WRITE_IMR(ring, ~0); @@ -1480,7 +1477,7 @@ gen8_ring_get_irq(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; - if (!dev->irq_enabled) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return false; spin_lock_irqsave(&dev_priv->irq_lock, flags); -- GitLab From 4dc49272bdfc11cdefb41175771ee811e363dfc7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Sep 2014 16:59:28 +0300 Subject: [PATCH 0047/9457] drm/i915/bios: add missing __packed to structs used for reading vbt This does not seem to make a difference for the structs in question, but document the intent. v2: also pack union child_device_config (Daniel) Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_bios.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 905999bee2ac..7603765c91fc 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -46,7 +46,7 @@ struct bdb_header { u16 version; /**< decimal */ u16 header_size; /**< in bytes */ u16 bdb_size; /**< in bytes */ -}; +} __packed; /* strictly speaking, this is a "skip" block, but it has interesting info */ struct vbios_data { @@ -252,7 +252,7 @@ union child_device_config { /* This one should also be safe to use anywhere, even without version * checks. */ struct common_child_dev_config common; -}; +} __packed; struct bdb_general_definitions { /* DDC GPIO */ @@ -888,12 +888,12 @@ struct mipi_pps_data { u16 bl_disable_delay; u16 panel_off_delay; u16 panel_power_cycle_delay; -}; +} __packed; struct bdb_mipi_config { struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; -}; +} __packed; /* Block 53 contains MIPI sequences as needed by the panel * for enabling it. This block can be variable in size and @@ -902,7 +902,7 @@ struct bdb_mipi_config { struct bdb_mipi_sequence { u8 version; u8 data[0]; -}; +} __packed; /* MIPI Sequnece Block definitions */ enum mipi_seq { -- GitLab From 07f11d49f120dfffb5b8603dd3863e903d50c456 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:35:09 +0200 Subject: [PATCH 0048/9457] drm/i915: Convert backlight_lock to a mutex Originally the irq safe spinlock was required because of asle interrupts. But since commit 91a60f20712179e56b7a6c3d332a5f6f9a54aa11 Author: Jani Nikula Date: Thu Oct 31 18:55:48 2013 +0200 drm/i915: move opregion asle request handling to a work queue there's no need for this any more. So switch to the simpler mutex. v2: Cite the right commit, spotted by Jani. Cc: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_panel.c | 30 ++++++++++++------------------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1403b01e8216..0bc1583114e7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1614,7 +1614,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); - spin_lock_init(&dev_priv->backlight_lock); + mutex_init(&dev_priv->backlight_lock); spin_lock_init(&dev_priv->uncore.lock); spin_lock_init(&dev_priv->mm.object_stat_lock); spin_lock_init(&dev_priv->mmio_flip_lock); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 17dfce0f4e68..07dafa2c2d8c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1528,7 +1528,7 @@ struct drm_i915_private { struct intel_overlay *overlay; /* backlight registers and fields in struct intel_panel */ - spinlock_t backlight_lock; + struct mutex backlight_lock; /* LVDS info */ bool no_aux_handshake; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 18784470a760..f17ada3742de 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -538,14 +538,13 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 val; - unsigned long flags; - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); val = dev_priv->display.get_backlight(connector); val = intel_panel_compute_brightness(connector, val); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); return val; @@ -629,12 +628,11 @@ static void intel_panel_set_backlight(struct intel_connector *connector, struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); u32 hw_level; - unsigned long flags; if (!panel->backlight.present || pipe == INVALID_PIPE) return; - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); WARN_ON(panel->backlight.max == 0); @@ -644,7 +642,7 @@ static void intel_panel_set_backlight(struct intel_connector *connector, if (panel->backlight.enabled) intel_panel_actually_set_backlight(connector, hw_level); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); } /* set backlight brightness to level in range [0..max], assuming hw min is @@ -658,12 +656,11 @@ void intel_panel_set_backlight_acpi(struct intel_connector *connector, struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); u32 hw_level; - unsigned long flags; if (!panel->backlight.present || pipe == INVALID_PIPE) return; - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); WARN_ON(panel->backlight.max == 0); @@ -679,7 +676,7 @@ void intel_panel_set_backlight_acpi(struct intel_connector *connector, if (panel->backlight.enabled) intel_panel_actually_set_backlight(connector, hw_level); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); } static void pch_disable_backlight(struct intel_connector *connector) @@ -733,7 +730,6 @@ void intel_panel_disable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - unsigned long flags; if (!panel->backlight.present || pipe == INVALID_PIPE) return; @@ -749,14 +745,14 @@ void intel_panel_disable_backlight(struct intel_connector *connector) return; } - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_POWERDOWN; panel->backlight.enabled = false; dev_priv->display.disable_backlight(connector); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); } static void bdw_enable_backlight(struct intel_connector *connector) @@ -937,14 +933,13 @@ void intel_panel_enable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - unsigned long flags; if (!panel->backlight.present || pipe == INVALID_PIPE) return; DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); WARN_ON(panel->backlight.max == 0); @@ -962,7 +957,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) if (panel->backlight.device) panel->backlight.device->props.power = FB_BLANK_UNBLANK; - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); } #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) @@ -1267,7 +1262,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_panel *panel = &intel_connector->panel; - unsigned long flags; int ret; if (!dev_priv->vbt.backlight.present) { @@ -1280,9 +1274,9 @@ int intel_panel_setup_backlight(struct drm_connector *connector) } /* set level and max in panel struct */ - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + mutex_lock(&dev_priv->backlight_lock); ret = dev_priv->display.setup_backlight(intel_connector); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + mutex_unlock(&dev_priv->backlight_lock); if (ret) { DRM_DEBUG_KMS("failed to setup backlight for connector %s\n", -- GitLab From 51e31d49c89055299e34b8f44d13f70e19aaaad1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 12:36:02 +0200 Subject: [PATCH 0049/9457] drm/i915: Use generic vblank wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has the upside that it will no longer steal interrupts from the interrupt handler on pre-g4x. Furthermore this will now scream properly on all platforms if we don't have hw counters enabled. v2: Adjust to the new names. Cc: Ville Syrjälä Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 43 +--------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 007f465227cf..474e6155b7c4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -892,18 +892,6 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, return intel_crtc->config.cpu_transcoder; } -static void g4x_wait_for_vblank(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 frame, frame_reg = PIPE_FRMCOUNT_GM45(pipe); - - frame = I915_READ(frame_reg); - - if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50)) - WARN(1, "vblank wait on pipe %c timed out\n", - pipe_name(pipe)); -} - /** * intel_wait_for_vblank - wait for vblank on a given pipe * @dev: drm device @@ -914,36 +902,7 @@ static void g4x_wait_for_vblank(struct drm_device *dev, int pipe) */ void intel_wait_for_vblank(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; - int pipestat_reg = PIPESTAT(pipe); - - if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { - g4x_wait_for_vblank(dev, pipe); - return; - } - - /* Clear existing vblank status. Note this will clear any other - * sticky status fields as well. - * - * This races with i915_driver_irq_handler() with the result - * that either function could miss a vblank event. Here it is not - * fatal, as we will either wait upon the next vblank interrupt or - * timeout. Generally speaking intel_wait_for_vblank() is only - * called during modeset at which time the GPU should be idle and - * should *not* be performing page flips and thus not waiting on - * vblanks... - * Currently, the result of us stealing a vblank from the irq - * handler is that a single frame will be skipped during swapbuffers. - */ - I915_WRITE(pipestat_reg, - I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); - - /* Wait for vblank interrupt bit to set */ - if (wait_for(I915_READ(pipestat_reg) & - PIPE_VBLANK_INTERRUPT_STATUS, - 50)) - DRM_DEBUG_KMS("vblank wait on pipe %c timed out\n", - pipe_name(pipe)); + drm_wait_one_vblank(dev, pipe); } static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) -- GitLab From 4f905cf97fb09b34193c7494bb27e49a56de934b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:12:21 +0200 Subject: [PATCH 0050/9457] drm/i915: static inline for intel_wait_for_vblank Requested by Chris, and also requested to keep it since it's a more accurate name in his opinion. Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 13 ------------- drivers/gpu/drm/i915/intel_drv.h | 6 +++++- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 474e6155b7c4..ef1d8fbfaecd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -892,19 +892,6 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, return intel_crtc->config.cpu_transcoder; } -/** - * intel_wait_for_vblank - wait for vblank on a given pipe - * @dev: drm device - * @pipe: pipe to wait for - * - * Wait for vblank to occur on a given pipe. Needed for various bits of - * mode setting code. - */ -void intel_wait_for_vblank(struct drm_device *dev, int pipe) -{ - drm_wait_one_vblank(dev, pipe); -} - static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index dd5e0f1b2dfd..1b72c15db907 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -853,7 +853,11 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe); -void intel_wait_for_vblank(struct drm_device *dev, int pipe); +static inline void +intel_wait_for_vblank(struct drm_device *dev, int pipe) +{ + drm_wait_one_vblank(dev, pipe); +} int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp); void vlv_wait_port_ready(struct drm_i915_private *dev_priv, struct intel_digital_port *dport); -- GitLab From 4b3a9526fc3228e74011b88f58088336acd2c9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Aug 2014 22:04:37 +0300 Subject: [PATCH 0051/9457] drm/i915: Move vblank enable earlier and disable later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We changed to an interrupt based vblank wait (as opposed to polling) in: commit 44bd93a3d367913d883be6abba9a6e51a53c4e90 Author: Daniel Vetter Date: Fri Jul 25 23:36:44 2014 +0200 drm/i915: Use generic vblank wait However we already had vblank waits on the wrong side of drm_vblank_{on,off}() calls due to various workarounds, so now we get a warning more or less every time we do a modeset, and we fail to wait for the vblank like we should. Move the drm_vblank_{on,off}() calls back out from intel_crtc_{enable,disable}_planes() so that all of these vblank waits return to proper operation. Also move the cxsr wait a bit earlier so that we can keep the encoder disable after we've turned off vblanks. Moving stuff out from the plane enable/disable functions seems preferrable to moving the workaround stuff in since the workarounds are required only on specific platforms. While at it switch over to the drm_crtc_ variants of the vblank on/off functions. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82525 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82490 Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ef1d8fbfaecd..365e04ca9120 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3997,10 +3997,6 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; - assert_vblank_disabled(crtc); - - drm_vblank_on(dev, pipe); - intel_enable_primary_hw_plane(crtc->primary, crtc); intel_enable_planes(crtc); intel_crtc_update_cursor(crtc, true); @@ -4046,10 +4042,6 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) * consider this a flip to a NULL plane. */ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe)); - - drm_vblank_off(dev, pipe); - - assert_vblank_disabled(crtc); } static void ironlake_crtc_enable(struct drm_crtc *crtc) @@ -4119,6 +4111,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (HAS_PCH_CPT(dev)) cpt_verify_modeset(dev, intel_crtc->pipe); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); } @@ -4226,6 +4221,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_opregion_notify_encoder(encoder, true); } + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + /* If we change the relative order between pipe/planes enabling, we need * to change the workaround. */ haswell_mode_set_planes_workaround(intel_crtc); @@ -4261,6 +4259,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) encoder->disable(encoder); @@ -4323,6 +4324,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_crtc_disable_planes(crtc); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) { intel_opregion_notify_encoder(encoder, false); encoder->disable(encoder); @@ -4789,6 +4793,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* Underruns don't raise interrupts, so check manually. */ @@ -4846,6 +4853,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + assert_vblank_disabled(crtc); + drm_crtc_vblank_on(crtc); + intel_crtc_enable_planes(crtc); /* @@ -4909,9 +4919,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_set_memory_cxsr(dev_priv, false); intel_crtc_disable_planes(crtc); - for_each_encoder_on_crtc(dev, crtc, encoder) - encoder->disable(encoder); - /* * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. @@ -4920,6 +4927,12 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) */ intel_wait_for_vblank(dev, pipe); + drm_crtc_vblank_off(crtc); + assert_vblank_disabled(crtc); + + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->disable(encoder); + intel_disable_pipe(intel_crtc); i9xx_pfit_disable(intel_crtc); -- GitLab From 5e2d7afcfefa7cda3f341ce78523bb9b0acdbacf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:22 +0200 Subject: [PATCH 0052/9457] drm/i915: Clarify event_lock locking, process context It's good practice to use the more specific versions for irq save spinlocks both as executable documentation and to enforce saner design. The _irqsave version really should only be used if the calling context is unknown and there's a good reason to call a function from all kinds of places. This is the first step whice replaces all occurances of _irqsave in process context with the simpler irq disable/enable variants. We don't have any funky spinlock nesting going on, especially since the event_lock is the outermost of the irq/vblank related spinlocks. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 5 ++-- drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++---------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 063b44817e08..0ba5c7145240 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -516,7 +516,6 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long flags; struct intel_crtc *crtc; int ret; @@ -529,7 +528,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) const char plane = plane_name(crtc->plane); struct intel_unpin_work *work; - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); work = crtc->unpin_work; if (work == NULL) { seq_printf(m, "No flip due on pipe %c (plane %c)\n", @@ -575,7 +574,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) seq_printf(m, "MMIO update completed? %d\n", addr == work->gtt_offset); } } - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); } mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 365e04ca9120..624d9bfc5c0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2711,16 +2711,15 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long flags; bool pending; if (i915_reset_in_progress(&dev_priv->gpu_error) || intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter)) return false; - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); pending = to_intel_crtc(crtc)->unpin_work != NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); return pending; } @@ -3431,14 +3430,13 @@ void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) !intel_crtc_has_pending_flip(crtc), 60*HZ) == 0)) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long flags; - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); if (intel_crtc->unpin_work) { WARN_ONCE(1, "Removing stuck page flip\n"); page_flip_completed(intel_crtc); } - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); } if (crtc->primary->fb) { @@ -9280,12 +9278,11 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = crtc->dev; struct intel_unpin_work *work; - unsigned long flags; - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); work = intel_crtc->unpin_work; intel_crtc->unpin_work = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); if (work) { cancel_work_sync(&work->work); @@ -9896,7 +9893,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, enum pipe pipe = intel_crtc->pipe; struct intel_unpin_work *work; struct intel_engine_cs *ring; - unsigned long flags; int ret; //trigger software GT busyness calculation @@ -9940,7 +9936,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, goto free_work; /* We borrow the event spin lock for protecting unpin_work */ - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); if (intel_crtc->unpin_work) { /* Before declaring the flip queue wedged, check if * the hardware completed the operation behind our backs. @@ -9950,7 +9946,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, page_flip_completed(intel_crtc); } else { DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); drm_crtc_vblank_put(crtc); kfree(work); @@ -9958,7 +9954,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, } } intel_crtc->unpin_work = work; - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); if (atomic_read(&intel_crtc->unpin_work_count) >= 2) flush_workqueue(dev_priv->wq); @@ -10045,9 +10041,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, mutex_unlock(&dev->struct_mutex); cleanup: - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); intel_crtc->unpin_work = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); drm_crtc_vblank_put(crtc); free_work: @@ -10058,9 +10054,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc_wait_for_pending_flips(crtc); ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb); if (ret == 0 && event) { - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock_irq(&dev->event_lock); drm_send_vblank_event(dev, pipe, event); - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irq(&dev->event_lock); } } return ret; @@ -13769,9 +13765,8 @@ void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file) for_each_intel_crtc(dev, crtc) { struct intel_unpin_work *work; - unsigned long irqflags; - spin_lock_irqsave(&dev->event_lock, irqflags); + spin_lock_irq(&dev->event_lock); work = crtc->unpin_work; @@ -13781,6 +13776,6 @@ void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file) work->event = NULL; } - spin_unlock_irqrestore(&dev->event_lock, irqflags); + spin_unlock_irq(&dev->event_lock); } } -- GitLab From f326038a29092534b59626f736a3c6e599bda017 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:23 +0200 Subject: [PATCH 0053/9457] drm/i915: Clarify event_lock locking, irq&mixed context Now we tackle the functions also called from interrupt handlers. - intel_check_page_flip is exclusively called from irq handlers, so a plain spin_lock is all we need. In i915_irq.c we have the convention to give all such functions an _irq_handler postfix, but that would look strange and als be a bit a misleading name. I've opted for a WARN_ON(!in_irq()) instead. - The other two places left are called both from interrupt handlers and from our reset work, so need the full irqsave dance. Annotate them with a short comment. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 624d9bfc5c0b..0c6350cb201c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9328,6 +9328,10 @@ static void do_intel_finish_page_flip(struct drm_device *dev, if (intel_crtc == NULL) return; + /* + * This is called both by irq handlers and the reset code (to complete + * lost pageflips) so needs the full irqsave spinlocks. + */ spin_lock_irqsave(&dev->event_lock, flags); work = intel_crtc->unpin_work; @@ -9409,7 +9413,12 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]); unsigned long flags; - /* NB: An MMIO update of the plane base pointer will also + + /* + * This is called both by irq handlers and the reset code (to complete + * lost pageflips) so needs the full irqsave spinlocks. + * + * NB: An MMIO update of the plane base pointer will also * generate a page-flip completion irq, i.e. every modeset * is also accompanied by a spurious intel_prepare_page_flip(). */ @@ -9866,18 +9875,19 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long flags; + + WARN_ON(!in_irq()); if (crtc == NULL) return; - spin_lock_irqsave(&dev->event_lock, flags); + spin_lock(&dev->event_lock); if (intel_crtc->unpin_work && __intel_pageflip_stall_check(dev, crtc)) { WARN_ONCE(1, "Kicking stuck page flip: queued at %d, now %d\n", intel_crtc->unpin_work->flip_queued_vblank, drm_vblank_count(dev, pipe)); page_flip_completed(intel_crtc); } - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock(&dev->event_lock); } static int intel_crtc_page_flip(struct drm_crtc *crtc, -- GitLab From 5b254c597871fa638a1ba0621f545e303090e970 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:24 +0200 Subject: [PATCH 0054/9457] drm/i915: Clarify gpu_error.lock locking i915_capture_error_state can be called from all kinds of contexts, so needs the full irqsave dance. But the other two places to grab and release the error state are only called from process context. So simplify them to the plaine _irq spinlock versions to clarify the locking semantics. Cc: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2c87a797213f..386e45dbeff1 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1326,13 +1326,12 @@ void i915_error_state_get(struct drm_device *dev, struct i915_error_state_file_priv *error_priv) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long flags; - spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); + spin_lock_irq(&dev_priv->gpu_error.lock); error_priv->error = dev_priv->gpu_error.first_error; if (error_priv->error) kref_get(&error_priv->error->ref); - spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); + spin_unlock_irq(&dev_priv->gpu_error.lock); } @@ -1346,12 +1345,11 @@ void i915_destroy_error_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_error_state *error; - unsigned long flags; - spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); + spin_lock_irq(&dev_priv->gpu_error.lock); error = dev_priv->gpu_error.first_error; dev_priv->gpu_error.first_error = NULL; - spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); + spin_unlock_irq(&dev_priv->gpu_error.lock); if (error) kref_put(&error->ref, i915_error_state_free); -- GitLab From 2795aa4864c9391c3107ecd91d663e58ff43dbfc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:25 +0200 Subject: [PATCH 0055/9457] drm/i915: Clarify irq_lock locking, intel_tv_detect ->detect callbacks are only ever called from process context, and there's no fancy nesting going on here. So plain _irq spinlock variants is what we want. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_tv.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index c14341ca3ef9..6f5f59b880f5 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1182,18 +1182,17 @@ intel_tv_detect_type(struct intel_tv *intel_tv, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; int type; /* Disable TV interrupts around load detect or we'll recurse */ if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_STATUS | PIPE_HOTPLUG_TV_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } save_tv_dac = tv_dac = I915_READ(TV_DAC); @@ -1266,11 +1265,11 @@ intel_tv_detect_type(struct intel_tv *intel_tv, /* Restore interrupt config */ if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_STATUS | PIPE_HOTPLUG_TV_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } return type; -- GitLab From 4cb21832280643f4ca96cad0edbef6f45baacf8c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:26 +0200 Subject: [PATCH 0056/9457] drm/i915: Clarify irq_lock locking, work functions Work functions are in process context, so plain _irq spinlock variants is all we need. The hpd reenable work didn't follow the _work/_work_func postfix naming scheme, so adjust that while at it. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d22f87020aee..4906823baa11 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1096,18 +1096,17 @@ static void i915_digport_work_func(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, struct drm_i915_private, dig_port_work); - unsigned long irqflags; u32 long_port_mask, short_port_mask; struct intel_digital_port *intel_dig_port; int i, ret; u32 old_bits = 0; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); long_port_mask = dev_priv->long_hpd_port_mask; dev_priv->long_hpd_port_mask = 0; short_port_mask = dev_priv->short_hpd_port_mask; dev_priv->short_hpd_port_mask = 0; - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); for (i = 0; i < I915_MAX_PORTS; i++) { bool valid = false; @@ -1132,9 +1131,9 @@ static void i915_digport_work_func(struct work_struct *work) } if (old_bits) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); dev_priv->hpd_event_bits |= old_bits; - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); schedule_work(&dev_priv->hotplug_work); } } @@ -1153,7 +1152,6 @@ static void i915_hotplug_work_func(struct work_struct *work) struct intel_connector *intel_connector; struct intel_encoder *intel_encoder; struct drm_connector *connector; - unsigned long irqflags; bool hpd_disabled = false; bool changed = false; u32 hpd_event_bits; @@ -1161,7 +1159,7 @@ static void i915_hotplug_work_func(struct work_struct *work) mutex_lock(&mode_config->mutex); DRM_DEBUG_KMS("running encoder hotplug functions\n"); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); hpd_event_bits = dev_priv->hpd_event_bits; dev_priv->hpd_event_bits = 0; @@ -1195,7 +1193,7 @@ static void i915_hotplug_work_func(struct work_struct *work) msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); } - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); list_for_each_entry(connector, &mode_config->connector_list, head) { intel_connector = to_intel_connector(connector); @@ -1490,7 +1488,6 @@ static void ivybridge_parity_work(struct work_struct *work) u32 error_status, row, bank, subbank; char *parity_event[6]; uint32_t misccpctl; - unsigned long flags; uint8_t slice = 0; /* We must turn off DOP level clock gating to access the L3 registers. @@ -1549,9 +1546,9 @@ static void ivybridge_parity_work(struct work_struct *work) out: WARN_ON(dev_priv->l3_parity.which_slice); - spin_lock_irqsave(&dev_priv->irq_lock, flags); + spin_lock_irq(&dev_priv->irq_lock); gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev)); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + spin_unlock_irq(&dev_priv->irq_lock); mutex_unlock(&dev_priv->dev->struct_mutex); } @@ -4606,19 +4603,18 @@ static void i965_irq_uninstall(struct drm_device * dev) I915_WRITE(IIR, I915_READ(IIR)); } -static void intel_hpd_irq_reenable(struct work_struct *work) +static void intel_hpd_irq_reenable_work(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), hotplug_reenable_work.work); struct drm_device *dev = dev_priv->dev; struct drm_mode_config *mode_config = &dev->mode_config; - unsigned long irqflags; int i; intel_runtime_pm_get(dev_priv); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); for (i = (HPD_NONE + 1); i < HPD_NUM_PINS; i++) { struct drm_connector *connector; @@ -4642,7 +4638,7 @@ static void intel_hpd_irq_reenable(struct work_struct *work) } if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); intel_runtime_pm_put(dev_priv); } @@ -4668,7 +4664,7 @@ void intel_irq_init(struct drm_device *dev) i915_hangcheck_elapsed, (unsigned long) dev); INIT_DELAYED_WORK(&dev_priv->hotplug_reenable_work, - intel_hpd_irq_reenable); + intel_hpd_irq_reenable_work); pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); -- GitLab From d62074358de148da197a90262551217f26937b5e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:27 +0200 Subject: [PATCH 0057/9457] drm/i915: Clarify irq_lock locking, interrupt install/uninstall All the interrupt setup/teardown hooks are always run from plain process context. So again just the _irq variant is good enough. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 42 ++++++++++++++------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4906823baa11..a829619aa111 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3603,7 +3603,6 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) static int ironlake_irq_postinstall(struct drm_device *dev) { - unsigned long irqflags; struct drm_i915_private *dev_priv = dev->dev_private; u32 display_mask, extra_mask; @@ -3642,9 +3641,9 @@ static int ironlake_irq_postinstall(struct drm_device *dev) * spinlocking not required here for correctness since interrupt * setup is guaranteed to run in single-threaded context. But we * need it to make the assert_spin_locked happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } return 0; @@ -3740,7 +3739,6 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) static int valleyview_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; dev_priv->irq_mask = ~0; @@ -3754,10 +3752,10 @@ static int valleyview_irq_postinstall(struct drm_device *dev) /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) valleyview_display_irqs_install(dev_priv); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IIR, 0xffffffff); @@ -3848,7 +3846,6 @@ static int cherryview_irq_postinstall(struct drm_device *dev) I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | PIPE_CRC_DONE_INTERRUPT_STATUS; - unsigned long irqflags; int pipe; /* @@ -3860,11 +3857,11 @@ static int cherryview_irq_postinstall(struct drm_device *dev) for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); for_each_pipe(dev_priv, pipe) i915_enable_pipestat(dev_priv, pipe, pipestat_enable); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IMR, dev_priv->irq_mask); @@ -3891,7 +3888,6 @@ static void gen8_irq_uninstall(struct drm_device *dev) static void valleyview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; int pipe; if (!dev_priv) @@ -3906,10 +3902,12 @@ static void valleyview_irq_uninstall(struct drm_device *dev) I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + /* Interrupt setup is already guaranteed to be single-threaded, this is + * just to make the assert_spin_locked check happy. */ + spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) valleyview_display_irqs_uninstall(dev_priv); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); dev_priv->irq_mask = 0; @@ -3995,7 +3993,6 @@ static void i8xx_irq_preinstall(struct drm_device * dev) static int i8xx_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); @@ -4018,10 +4015,10 @@ static int i8xx_irq_postinstall(struct drm_device *dev) /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); return 0; } @@ -4168,7 +4165,6 @@ static int i915_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u32 enable_mask; - unsigned long irqflags; I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); @@ -4206,10 +4202,10 @@ static int i915_irq_postinstall(struct drm_device *dev) /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); return 0; } @@ -4391,7 +4387,6 @@ static int i965_irq_postinstall(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u32 enable_mask; u32 error_mask; - unsigned long irqflags; /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | @@ -4412,11 +4407,11 @@ static int i965_irq_postinstall(struct drm_device *dev) /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); /* * Enable some error detection, note the instruction error mask @@ -4756,7 +4751,6 @@ void intel_hpd_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; - unsigned long irqflags; int i; for (i = 1; i < HPD_NUM_PINS; i++) { @@ -4774,10 +4768,10 @@ void intel_hpd_init(struct drm_device *dev) /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked checks happy. */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } /* Disable interrupts so we can allow runtime PM. */ -- GitLab From 222c7f51b074cc8bfbda5821ee7f875e51f841b5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:28 +0200 Subject: [PATCH 0058/9457] drm/i915: Clarify irq_lock locking, irq handlers irq handlers always run with interrupts locally disabled, so plain spinlocks is all we need. I've also reviewed again that they all follow the _irq_handler postfix convention. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a829619aa111..6a4f389ff2f5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4063,7 +4063,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) struct drm_i915_private *dev_priv = dev->dev_private; u16 iir, new_iir; u32 pipe_stats[2]; - unsigned long irqflags; int pipe; u16 flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | @@ -4079,7 +4078,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) * It doesn't set the bit in iir again, but it still produces * interrupts (for non-MSI). */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock(&dev_priv->irq_lock); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) i915_handle_error(dev, false, "Command parser error, iir 0x%08x", @@ -4095,7 +4094,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) if (pipe_stats[pipe] & 0x8000ffff) I915_WRITE(reg, pipe_stats[pipe]); } - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock(&dev_priv->irq_lock); I915_WRITE16(IIR, iir & ~flip_mask); new_iir = I915_READ16(IIR); /* Flush posted writes */ @@ -4249,7 +4248,6 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) struct drm_device *dev = arg; struct drm_i915_private *dev_priv = dev->dev_private; u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; - unsigned long irqflags; u32 flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; @@ -4265,7 +4263,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) * It doesn't set the bit in iir again, but it still produces * interrupts (for non-MSI). */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock(&dev_priv->irq_lock); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) i915_handle_error(dev, false, "Command parser error, iir 0x%08x", @@ -4281,7 +4279,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) irq_received = true; } } - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock(&dev_priv->irq_lock); if (!irq_received) break; @@ -4476,7 +4474,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) struct drm_i915_private *dev_priv = dev->dev_private; u32 iir, new_iir; u32 pipe_stats[I915_MAX_PIPES]; - unsigned long irqflags; int ret = IRQ_NONE, pipe; u32 flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | @@ -4493,7 +4490,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) * It doesn't set the bit in iir again, but it still produces * interrupts (for non-MSI). */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock(&dev_priv->irq_lock); if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) i915_handle_error(dev, false, "Command parser error, iir 0x%08x", @@ -4511,7 +4508,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) irq_received = true; } } - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock(&dev_priv->irq_lock); if (!irq_received) break; -- GitLab From 133217869ea7f328acedab2ed2ec1ad41b6390bd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:29 +0200 Subject: [PATCH 0059/9457] drm/i915: Clarify irq_lock locking, special cases Grab bag for all the special cases: - i9xx_check_fifo_underruns is only called from crtc_enable hooks, i.e. process context. - i915_enable_asle_pipestat is only called from interrupt postinstall hooks. So again process context. - gen8_irq_power_well_post_enable is called from the runtime pm code, which again means process context. - The open-coded hpd_irq_setup loop in _thaw is also running in process context. So for all of them the plain _irq variant is sufficient. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 5 ++--- drivers/gpu/drm/i915/i915_irq.c | 16 ++++++---------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b8bd0080603e..8ce1b13ad97e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -686,11 +686,10 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) intel_modeset_init_hw(dev); { - unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } intel_dp_mst_resume(dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6a4f389ff2f5..a08cdc62f841 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -310,9 +310,8 @@ void i9xx_check_fifo_underruns(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *crtc; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); + spin_lock_irq(&dev_priv->irq_lock); for_each_intel_crtc(dev, crtc) { u32 reg = PIPESTAT(crtc->pipe); @@ -331,7 +330,7 @@ void i9xx_check_fifo_underruns(struct drm_device *dev) DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + spin_unlock_irq(&dev_priv->irq_lock); } static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, @@ -696,19 +695,18 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, static void i915_enable_asle_pipestat(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; if (!dev_priv->opregion.asle || !IS_MOBILE(dev)) return; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); if (INTEL_INFO(dev)->gen >= 4) i915_enable_pipestat(dev_priv, PIPE_A, PIPE_LEGACY_BLC_EVENT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } /** @@ -3477,14 +3475,12 @@ static void gen8_irq_reset(struct drm_device *dev) void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) { - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irq(&dev_priv->irq_lock); GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], ~dev_priv->de_irq_mask[PIPE_B]); GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], ~dev_priv->de_irq_mask[PIPE_C]); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irq(&dev_priv->irq_lock); } static void cherryview_irq_preinstall(struct drm_device *dev) -- GitLab From d2e40e2741e32e03ce060cc74ef6d47eaf833bf9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:31 +0200 Subject: [PATCH 0060/9457] drm/i915: Clarify uncore.lock locking Only one place looked in need of a bit of polish: hsw_restore_lcpll. It's used by the runtime pm code and hence is always called from process context. No irq flag saving required. Another thing I've stumbled over is that we might need to add a raw forcewake_get/put helpers which don't grab a runtime pm reference but just check that the device isn't suspended - we have this duplicated in the execlist code, too. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0c6350cb201c..8b73d1161ae1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7603,7 +7603,6 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv, static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) { uint32_t val; - unsigned long irqflags; val = I915_READ(LCPLL_CTL); @@ -7623,10 +7622,10 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) * to call special forcewake code that doesn't touch runtime PM and * doesn't enable the forcewake delayed work. */ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + spin_lock_irq(&dev_priv->uncore.lock); if (dev_priv->uncore.forcewake_count++ == 0) dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL); - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + spin_unlock_irq(&dev_priv->uncore.lock); if (val & LCPLL_POWER_DOWN_ALLOW) { val &= ~LCPLL_POWER_DOWN_ALLOW; @@ -7657,10 +7656,10 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) } /* See the big comment above. */ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + spin_lock_irq(&dev_priv->uncore.lock); if (--dev_priv->uncore.forcewake_count == 0) dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + spin_unlock_irq(&dev_priv->uncore.lock); } /* -- GitLab From 24955f2412fa16e30bb678bad1450ebd9fb8e180 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 15 Sep 2014 14:55:32 +0200 Subject: [PATCH 0061/9457] drm/i915: Clarify mmio_flip_lock locking The ->queue_flip callback is always called from process context, so plain _irq spinlock variants are enough. Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b73d1161ae1..5b05ddbfa46f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9792,7 +9792,6 @@ static int intel_queue_mmio_flip(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long irq_flags; int ret; if (WARN_ON(intel_crtc->mmio_flip.seqno)) @@ -9806,10 +9805,10 @@ static int intel_queue_mmio_flip(struct drm_device *dev, return 0; } - spin_lock_irqsave(&dev_priv->mmio_flip_lock, irq_flags); + spin_lock_irq(&dev_priv->mmio_flip_lock); intel_crtc->mmio_flip.seqno = obj->last_write_seqno; intel_crtc->mmio_flip.ring_id = obj->ring->id; - spin_unlock_irqrestore(&dev_priv->mmio_flip_lock, irq_flags); + spin_unlock_irq(&dev_priv->mmio_flip_lock); /* * Double check to catch cases where irq fired before -- GitLab From 01d06e9f963ba6a83154ab81929b7f5e04bbe5dd Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 5 Sep 2014 16:57:20 -0400 Subject: [PATCH 0062/9457] drm/i915: Only flush fbc on sw when fbc is enabled. Avoid touching fbc register when fbc is disabled. Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 675e8a2ce988..6f3b94b7300b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -352,6 +352,9 @@ void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) if (!IS_GEN8(dev)) return; + if (!intel_fbc_enabled(dev)) + return; + I915_WRITE(MSG_FBC_REND_STATE, value); } -- GitLab From 342e36c6b0cab1d7461287d553154ff35fee989d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 17 Sep 2014 16:59:20 -0400 Subject: [PATCH 0063/9457] drm/i915: Avoid reading fbc registers in vain when fbc was never enabled. If it wasn't never enabled by kernel parameter or platform default we can avoid reading registers so many times in vain Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6f3b94b7300b..1ec3c8f689bc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -339,6 +339,12 @@ bool intel_fbc_enabled(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* If it wasn't never enabled by kernel parameter or platform default + * we can avoid reading registers so many times in vain + */ + if (!i915.enable_fbc) + return false; + if (!dev_priv->display.fbc_enabled) return false; -- GitLab From 5cb13c07dae73380d8b3ddc792740487b8742938 Mon Sep 17 00:00:00 2001 From: Deepak S Date: Thu, 18 Sep 2014 18:51:50 +0530 Subject: [PATCH 0064/9457] drm/i915/vlv: Remove check for Old Ack during forcewake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on the HW team inputs. We can should not wait for the old ack, Waiting for old ack might fail, when other forcewake came before the present one is desserted. for example, if forcewake bit 0 was set and before it could get cleared forcewake bit 1 got set, HW eventually clear bit 0, when the bit 1 is cleared. i.e, bit 1 is still sent then forcewake bit 0 will still be set. Signed-off-by: Deepak S Reviewed-by: Ville Syrjälä [danvet: Add comment Ville requested.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 918b76163965..0e99852222e1 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -194,13 +194,15 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) { + /* + * WaRsDontPollForAckOnClearingFWBits:vlv + * Hardware clears ack bits lazily (only when all ack + * bits become 0) so don't poll for individiual ack + * bits to be clear here like on other platforms. + */ + /* Check for Render Engine */ if (FORCEWAKE_RENDER & fw_engine) { - if (wait_for_atomic((__raw_i915_read32(dev_priv, - FORCEWAKE_ACK_VLV) & - FORCEWAKE_KERNEL) == 0, - FORCEWAKE_ACK_TIMEOUT_MS)) - DRM_ERROR("Timed out: Render forcewake old ack to clear.\n"); __raw_i915_write32(dev_priv, FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); @@ -214,11 +216,6 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, /* Check for Media Engine */ if (FORCEWAKE_MEDIA & fw_engine) { - if (wait_for_atomic((__raw_i915_read32(dev_priv, - FORCEWAKE_ACK_MEDIA_VLV) & - FORCEWAKE_KERNEL) == 0, - FORCEWAKE_ACK_TIMEOUT_MS)) - DRM_ERROR("Timed out: Media forcewake old ack to clear.\n"); __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); -- GitLab From 9d533c5a5219ed7e3d52a05309723964be2307b3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 19 Sep 2014 17:07:10 +0200 Subject: [PATCH 0065/9457] drm/i915: Update DRIVER_DATE to 20140919 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 07dafa2c2d8c..03f59ecbb200 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -54,7 +54,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20140905" +#define DRIVER_DATE "20140919" enum pipe { INVALID_PIPE = -1, -- GitLab From 9beb0ccb66ec5d011ac13a02d3b1098035195251 Mon Sep 17 00:00:00 2001 From: Brad Volkin Date: Thu, 18 Sep 2014 16:26:26 -0700 Subject: [PATCH 0066/9457] drm/i915: Re-enable the command parser when using PPGTT In commit commit 896ab1a5d54269b463a24194c2e4a369103b46d8 Author: Daniel Vetter Date: Wed Aug 6 15:04:51 2014 +0200 drm/i915: Fix up checks for aliasing ppgtt it looks like we accidentally inverted the check that the command parser should only run when the driver enables some form of PPGTT. Testcase: igt/gem_exec_parse Cc: Daniel Vetter Signed-off-by: Brad Volkin [danvet: Also drop the comment right above, all production vlv now have hw ppgtt enabled.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index c45856bcc8b9..d40f264bd5f0 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -845,12 +845,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs *ring) if (!ring->needs_cmd_parser) return false; - /* - * XXX: VLV is Gen7 and therefore has cmd_tables, but has PPGTT - * disabled. That will cause all of the parser's PPGTT checks to - * fail. For now, disable parsing when PPGTT is off. - */ - if (USES_PPGTT(ring->dev)) + if (!USES_PPGTT(ring->dev)) return false; return (i915.enable_cmd_parser == 1); -- GitLab From 00caf0199f66871b0e2c28d7c2079de0ce1d646c Mon Sep 17 00:00:00 2001 From: Brad Volkin Date: Thu, 18 Sep 2014 16:26:27 -0700 Subject: [PATCH 0067/9457] drm/i915: Log a message when rejecting LRM to OACONTROL The other paths in the command parser that reject a batch all log a message indicating the reason. We simply missed this one. Signed-off-by: Brad Volkin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index d40f264bd5f0..4c35e2a62689 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -881,8 +881,10 @@ static bool check_cmd(const struct intel_engine_cs *ring, * OACONTROL writes to only MI_LOAD_REGISTER_IMM commands. */ if (reg_addr == OACONTROL) { - if (desc->cmd.value == MI_LOAD_REGISTER_MEM) + if (desc->cmd.value == MI_LOAD_REGISTER_MEM) { + DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n"); return false; + } if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1)) *oacontrol_set = (cmd[2] != 0); -- GitLab From 1893a71b1eba79a46ac5b356208e80f822543fa4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 19 Sep 2014 11:56:27 +0100 Subject: [PATCH 0068/9457] drm/i915: Inline feature detection into sanitize_enable_ppgtt Rather than splitting and hiding away critical parts of sanitize_enable_ppgtt() into single use macros in the headers, inline them into the function for clarity. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem_gtt.c | 14 +++++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 03f59ecbb200..5fce16c9d647 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2139,8 +2139,6 @@ struct drm_i915_cmd_table { #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) #define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 8) -#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >= 6) -#define HAS_PPGTT(dev) (INTEL_INFO(dev)->gen >= 7 && !IS_GEN8(dev)) #define USES_PPGTT(dev) (i915.enable_ppgtt) #define USES_FULL_PPGTT(dev) (i915.enable_ppgtt == 2) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a234446a8678..90c9bf6e71b7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -35,13 +35,21 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv); static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) { - if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) + bool has_aliasing_ppgtt; + bool has_full_ppgtt; + + has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6; + has_full_ppgtt = INTEL_INFO(dev)->gen >= 7; + if (IS_GEN8(dev)) + has_full_ppgtt = false; /* XXX why? */ + + if (enable_ppgtt == 0 || !has_aliasing_ppgtt) return 0; if (enable_ppgtt == 1) return 1; - if (enable_ppgtt == 2 && HAS_PPGTT(dev)) + if (enable_ppgtt == 2 && has_full_ppgtt) return 2; #ifdef CONFIG_INTEL_IOMMU @@ -59,7 +67,7 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) return 0; } - return HAS_PPGTT(dev) ? 2 : HAS_ALIASING_PPGTT(dev) ? 1 : 0; + return has_full_ppgtt ? 2 : has_aliasing_ppgtt ? 1 : 0; } -- GitLab From b680c37a4d145cf4d8f2b24e46b1163e5ceb1d35 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 19 Sep 2014 18:27:27 +0200 Subject: [PATCH 0069/9457] drm/i915: DocBook integration for frontbuffer tracking I shouldn't ask everyone to do this and fail myself ... This extracts all the frontbuffer tracking functions into intel_frontbuffer.c, adds a DOC overview section and also adds the missing kerneldoc for i915_gem_track_fb and also pulls it into the same section for convenience. v2: Don't forget about the header files. v3: Oops, might check compilation next time around. To make my life easier drop the increase_pllclock from set_base_atomic since really, it doesn't matter if you see your Oops or kgdb with a tiny bit of lag. v4: Try to better explain how to actually use this, requested by Paulo on irc. v5: Explain invalidate/flush a bit clearer. v6: s/business/busyness/ Acked-by: Paulo Zanoni Cc: Paulo Zanoni Cc: Vandana Kannan Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 7 + drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_gem.c | 9 + drivers/gpu/drm/i915/intel_display.c | 218 +----------------- drivers/gpu/drm/i915/intel_drv.h | 15 +- drivers/gpu/drm/i915/intel_frontbuffer.c | 277 +++++++++++++++++++++++ 6 files changed, 306 insertions(+), 221 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_frontbuffer.c diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index ca44d9fe7d7d..7ad61284ad5f 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3803,6 +3803,13 @@ int num_ioctls; configuration change. + + Frontbuffer Tracking +!Pdrivers/gpu/drm/i915/intel_frontbuffer.c frontbuffer tracking +!Idrivers/gpu/drm/i915/intel_frontbuffer.c +!Fdrivers/gpu/drm/i915/intel_drv.h intel_frontbuffer_flip +!Fdrivers/gpu/drm/i915/i915_gem.c i915_gem_track_fb + Plane Configuration diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index c1dd485aeb6c..2d8317d36e09 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -43,6 +43,7 @@ i915-y += intel_renderstate_gen6.o \ # modesetting core code i915-y += intel_bios.o \ intel_display.o \ + intel_frontbuffer.o \ intel_modes.o \ intel_overlay.o \ intel_sideband.o \ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2fb87cfa5b82..55a2ebb510bf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5077,6 +5077,15 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) return ret; } +/** + * i915_gem_track_fb - update frontbuffer tracking + * old: current GEM buffer for the frontbuffer slots + * new: new GEM buffer for the frontbuffer slots + * frontbuffer_bits: bitmask of frontbuffer slots + * + * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them + * from @old and setting them in @new. Both @old and @new can be NULL. + */ void i915_gem_track_fb(struct drm_i915_gem_object *old, struct drm_i915_gem_object *new, unsigned frontbuffer_bits) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5b05ddbfa46f..858011d22482 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -76,8 +76,6 @@ static const uint32_t intel_cursor_formats[] = { #define DIV_ROUND_CLOSEST_ULL(ll, d) \ ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) -static void intel_increase_pllclock(struct drm_device *dev, - enum pipe pipe); static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); static void i9xx_crtc_clock_get(struct intel_crtc *crtc, @@ -1138,8 +1136,8 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, state_string(state), state_string(cur_state)); } -static void assert_panel_unlocked(struct drm_i915_private *dev_priv, - enum pipe pipe) +void assert_panel_unlocked(struct drm_i915_private *dev_priv, + enum pipe pipe) { struct drm_device *dev = dev_priv->dev; int pp_reg; @@ -2631,7 +2629,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (dev_priv->display.disable_fbc) dev_priv->display.disable_fbc(dev); - intel_increase_pllclock(dev, to_intel_crtc(crtc)->pipe); dev_priv->display.update_primary_plane(crtc, fb, x, y); @@ -8986,35 +8983,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, return mode; } -static void intel_increase_pllclock(struct drm_device *dev, - enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int dpll_reg = DPLL(pipe); - int dpll; - - if (!HAS_GMCH_DISPLAY(dev)) - return; - - if (!dev_priv->lvds_downclock_avail) - return; - - dpll = I915_READ(dpll_reg); - if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { - DRM_DEBUG_DRIVER("upclocking LVDS\n"); - - assert_panel_unlocked(dev_priv, pipe); - - dpll &= ~DISPLAY_RATE_SELECT_FPA1; - I915_WRITE(dpll_reg, dpll); - intel_wait_for_vblank(dev, pipe); - - dpll = I915_READ(dpll_reg); - if (dpll & DISPLAY_RATE_SELECT_FPA1) - DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); - } -} - static void intel_decrease_pllclock(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -9090,188 +9058,6 @@ void intel_mark_idle(struct drm_device *dev) intel_runtime_pm_put(dev_priv); } - -/** - * intel_mark_fb_busy - mark given planes as busy - * @dev: DRM device - * @frontbuffer_bits: bits for the affected planes - * @ring: optional ring for asynchronous commands - * - * This function gets called every time the screen contents change. It can be - * used to keep e.g. the update rate at the nominal refresh rate with DRRS. - */ -static void intel_mark_fb_busy(struct drm_device *dev, - unsigned frontbuffer_bits, - struct intel_engine_cs *ring) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - enum pipe pipe; - - if (!i915.powersave) - return; - - for_each_pipe(dev_priv, pipe) { - if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe))) - continue; - - intel_increase_pllclock(dev, pipe); - if (ring && intel_fbc_enabled(dev)) - ring->fbc_dirty = true; - } -} - -/** - * intel_fb_obj_invalidate - invalidate frontbuffer object - * @obj: GEM object to invalidate - * @ring: set for asynchronous rendering - * - * This function gets called every time rendering on the given object starts and - * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must - * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed - * until the rendering completes or a flip on this frontbuffer plane is - * scheduled. - */ -void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, - struct intel_engine_cs *ring) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (!obj->frontbuffer_bits) - return; - - if (ring) { - mutex_lock(&dev_priv->fb_tracking.lock); - dev_priv->fb_tracking.busy_bits - |= obj->frontbuffer_bits; - dev_priv->fb_tracking.flip_bits - &= ~obj->frontbuffer_bits; - mutex_unlock(&dev_priv->fb_tracking.lock); - } - - intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring); - - intel_edp_psr_invalidate(dev, obj->frontbuffer_bits); -} - -/** - * intel_frontbuffer_flush - flush frontbuffer - * @dev: DRM device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called every time rendering on the given planes has - * completed and frontbuffer caching can be started again. Flushes will get - * delayed if they're blocked by some oustanding asynchronous rendering. - * - * Can be called without any locks held. - */ -void intel_frontbuffer_flush(struct drm_device *dev, - unsigned frontbuffer_bits) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* Delay flushing when rings are still busy.*/ - mutex_lock(&dev_priv->fb_tracking.lock); - frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; - mutex_unlock(&dev_priv->fb_tracking.lock); - - intel_mark_fb_busy(dev, frontbuffer_bits, NULL); - - intel_edp_psr_flush(dev, frontbuffer_bits); - - /* - * FIXME: Unconditional fbc flushing here is a rather gross hack and - * needs to be reworked into a proper frontbuffer tracking scheme like - * psr employs. - */ - if (IS_BROADWELL(dev)) - gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); -} - -/** - * intel_fb_obj_flush - flush frontbuffer object - * @obj: GEM object to flush - * @retire: set when retiring asynchronous rendering - * - * This function gets called every time rendering on the given object has - * completed and frontbuffer caching can be started again. If @retire is true - * then any delayed flushes will be unblocked. - */ -void intel_fb_obj_flush(struct drm_i915_gem_object *obj, - bool retire) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned frontbuffer_bits; - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (!obj->frontbuffer_bits) - return; - - frontbuffer_bits = obj->frontbuffer_bits; - - if (retire) { - mutex_lock(&dev_priv->fb_tracking.lock); - /* Filter out new bits since rendering started. */ - frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; - - dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; - mutex_unlock(&dev_priv->fb_tracking.lock); - } - - intel_frontbuffer_flush(dev, frontbuffer_bits); -} - -/** - * intel_frontbuffer_flip_prepare - prepare asnychronous frontbuffer flip - * @dev: DRM device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called after scheduling a flip on @obj. The actual - * frontbuffer flushing will be delayed until completion is signalled with - * intel_frontbuffer_flip_complete. If an invalidate happens in between this - * flush will be cancelled. - * - * Can be called without any locks held. - */ -void intel_frontbuffer_flip_prepare(struct drm_device *dev, - unsigned frontbuffer_bits) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->fb_tracking.lock); - dev_priv->fb_tracking.flip_bits - |= frontbuffer_bits; - mutex_unlock(&dev_priv->fb_tracking.lock); -} - -/** - * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flush - * @dev: DRM device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called after the flip has been latched and will complete - * on the next vblank. It will execute the fush if it hasn't been cancalled yet. - * - * Can be called without any locks held. - */ -void intel_frontbuffer_flip_complete(struct drm_device *dev, - unsigned frontbuffer_bits) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->fb_tracking.lock); - /* Mask any cancelled flips. */ - frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; - dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; - mutex_unlock(&dev_priv->fb_tracking.lock); - - intel_frontbuffer_flush(dev, frontbuffer_bits); -} - static void intel_crtc_destroy(struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1b72c15db907..617126786819 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -801,11 +801,7 @@ void intel_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config); void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state); -/* intel_display.c */ -const char *intel_output_name(int output); -bool intel_has_pending_fb_unpin(struct drm_device *dev); -int intel_pch_rawclk(struct drm_device *dev); -void intel_mark_busy(struct drm_device *dev); +/* intel_frontbuffer.c */ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, struct intel_engine_cs *ring); void intel_frontbuffer_flip_prepare(struct drm_device *dev, @@ -833,6 +829,13 @@ void intel_frontbuffer_flip(struct drm_device *dev, } void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); + + +/* intel_display.c */ +const char *intel_output_name(int output); +bool intel_has_pending_fb_unpin(struct drm_device *dev); +int intel_pch_rawclk(struct drm_device *dev); +void intel_mark_busy(struct drm_device *dev); void intel_mark_idle(struct drm_device *dev); void intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_control(struct drm_crtc *crtc, bool enable); @@ -891,6 +894,8 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc); void intel_put_shared_dpll(struct intel_crtc *crtc); /* modesetting asserts */ +void assert_panel_unlocked(struct drm_i915_private *dev_priv, + enum pipe pipe); void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pll_enabled(d, p) assert_pll(d, p, true) diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c new file mode 100644 index 000000000000..f74744c091cb --- /dev/null +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -0,0 +1,277 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Daniel Vetter + */ + +/** + * DOC: frontbuffer tracking + * + * Many features require us to track changes to the currently active + * frontbuffer, especially rendering targetted at the frontbuffer. + * + * To be able to do so GEM tracks frontbuffers using a bitmask for all possible + * frontbuffer slots through i915_gem_track_fb(). The function in this file are + * then called when the contents of the frontbuffer are invalidated, when + * frontbuffer rendering has stopped again to flush out all the changes and when + * the frontbuffer is exchanged with a flip. Subsystems interested in + * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks + * into the relevant places and filter for the frontbuffer slots that they are + * interested int. + * + * On a high level there are two types of powersaving features. The first one + * work like a special cache (FBC and PSR) and are interested when they should + * stop caching and when to restart caching. This is done by placing callbacks + * into the invalidate and the flush functions: At invalidate the caching must + * be stopped and at flush time it can be restarted. And maybe they need to know + * when the frontbuffer changes (e.g. when the hw doesn't initiate an invalidate + * and flush on its own) which can be achieved with placing callbacks into the + * flip functions. + * + * The other type of display power saving feature only cares about busyness + * (e.g. DRRS). In that case all three (invalidate, flush and flip) indicate + * busyness. There is no direct way to detect idleness. Instead an idle timer + * work delayed work should be started from the flush and flip functions and + * cancelled as soon as busyness is detected. + * + * Note that there's also an older frontbuffer activity tracking scheme which + * just trackings general activity. This is done by the various mark_busy and + * mark_idle functions. For display power management features using these + * functions is deprecated and should be avoided. + */ + +#include + +#include "intel_drv.h" +#include "i915_drv.h" + +static void intel_increase_pllclock(struct drm_device *dev, + enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int dpll_reg = DPLL(pipe); + int dpll; + + if (!HAS_GMCH_DISPLAY(dev)) + return; + + if (!dev_priv->lvds_downclock_avail) + return; + + dpll = I915_READ(dpll_reg); + if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { + DRM_DEBUG_DRIVER("upclocking LVDS\n"); + + assert_panel_unlocked(dev_priv, pipe); + + dpll &= ~DISPLAY_RATE_SELECT_FPA1; + I915_WRITE(dpll_reg, dpll); + intel_wait_for_vblank(dev, pipe); + + dpll = I915_READ(dpll_reg); + if (dpll & DISPLAY_RATE_SELECT_FPA1) + DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); + } +} + +/** + * intel_mark_fb_busy - mark given planes as busy + * @dev: DRM device + * @frontbuffer_bits: bits for the affected planes + * @ring: optional ring for asynchronous commands + * + * This function gets called every time the screen contents change. It can be + * used to keep e.g. the update rate at the nominal refresh rate with DRRS. + */ +static void intel_mark_fb_busy(struct drm_device *dev, + unsigned frontbuffer_bits, + struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe; + + if (!i915.powersave) + return; + + for_each_pipe(dev_priv, pipe) { + if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe))) + continue; + + intel_increase_pllclock(dev, pipe); + if (ring && intel_fbc_enabled(dev)) + ring->fbc_dirty = true; + } +} + +/** + * intel_fb_obj_invalidate - invalidate frontbuffer object + * @obj: GEM object to invalidate + * @ring: set for asynchronous rendering + * + * This function gets called every time rendering on the given object starts and + * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must + * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed + * until the rendering completes or a flip on this frontbuffer plane is + * scheduled. + */ +void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, + struct intel_engine_cs *ring) +{ + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + + if (!obj->frontbuffer_bits) + return; + + if (ring) { + mutex_lock(&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.busy_bits + |= obj->frontbuffer_bits; + dev_priv->fb_tracking.flip_bits + &= ~obj->frontbuffer_bits; + mutex_unlock(&dev_priv->fb_tracking.lock); + } + + intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring); + + intel_edp_psr_invalidate(dev, obj->frontbuffer_bits); +} + +/** + * intel_frontbuffer_flush - flush frontbuffer + * @dev: DRM device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called every time rendering on the given planes has + * completed and frontbuffer caching can be started again. Flushes will get + * delayed if they're blocked by some oustanding asynchronous rendering. + * + * Can be called without any locks held. + */ +void intel_frontbuffer_flush(struct drm_device *dev, + unsigned frontbuffer_bits) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + /* Delay flushing when rings are still busy.*/ + mutex_lock(&dev_priv->fb_tracking.lock); + frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; + mutex_unlock(&dev_priv->fb_tracking.lock); + + intel_mark_fb_busy(dev, frontbuffer_bits, NULL); + + intel_edp_psr_flush(dev, frontbuffer_bits); + + /* + * FIXME: Unconditional fbc flushing here is a rather gross hack and + * needs to be reworked into a proper frontbuffer tracking scheme like + * psr employs. + */ + if (IS_BROADWELL(dev)) + gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); +} + +/** + * intel_fb_obj_flush - flush frontbuffer object + * @obj: GEM object to flush + * @retire: set when retiring asynchronous rendering + * + * This function gets called every time rendering on the given object has + * completed and frontbuffer caching can be started again. If @retire is true + * then any delayed flushes will be unblocked. + */ +void intel_fb_obj_flush(struct drm_i915_gem_object *obj, + bool retire) +{ + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned frontbuffer_bits; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + + if (!obj->frontbuffer_bits) + return; + + frontbuffer_bits = obj->frontbuffer_bits; + + if (retire) { + mutex_lock(&dev_priv->fb_tracking.lock); + /* Filter out new bits since rendering started. */ + frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; + + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; + mutex_unlock(&dev_priv->fb_tracking.lock); + } + + intel_frontbuffer_flush(dev, frontbuffer_bits); +} + +/** + * intel_frontbuffer_flip_prepare - prepare asnychronous frontbuffer flip + * @dev: DRM device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called after scheduling a flip on @obj. The actual + * frontbuffer flushing will be delayed until completion is signalled with + * intel_frontbuffer_flip_complete. If an invalidate happens in between this + * flush will be cancelled. + * + * Can be called without any locks held. + */ +void intel_frontbuffer_flip_prepare(struct drm_device *dev, + unsigned frontbuffer_bits) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev_priv->fb_tracking.lock); + dev_priv->fb_tracking.flip_bits + |= frontbuffer_bits; + mutex_unlock(&dev_priv->fb_tracking.lock); +} + +/** + * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flush + * @dev: DRM device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called after the flip has been latched and will complete + * on the next vblank. It will execute the fush if it hasn't been cancalled yet. + * + * Can be called without any locks held. + */ +void intel_frontbuffer_flip_complete(struct drm_device *dev, + unsigned frontbuffer_bits) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev_priv->fb_tracking.lock); + /* Mask any cancelled flips. */ + frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; + dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; + mutex_unlock(&dev_priv->fb_tracking.lock); + + intel_frontbuffer_flush(dev, frontbuffer_bits); +} + -- GitLab From d6be7a02d9cf817d3e3d19167d87e52260620ecd Mon Sep 17 00:00:00 2001 From: Chris Ruffin Date: Mon, 15 Sep 2014 00:38:00 +0100 Subject: [PATCH 0070/9457] staging: iio: accel: remove unnecessary syntax The else clause in the conditional of lis3l02dq_data_rdy_trig_poll() does not make consistent use of braces with the rest of the conditional. Fix this coding style problem by removing the unnecessary conditional altogether. Signed-off-by: Chris Ruffin Acked-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/lis3l02dq_ring.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 1d934ee3bb5f..9efc77b0ebdd 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -34,8 +34,9 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private) if (st->trigger_on) { iio_trigger_poll(st->trig); return IRQ_HANDLED; - } else - return IRQ_WAKE_THREAD; + } + + return IRQ_WAKE_THREAD; } static const u8 read_all_tx_array[] = { -- GitLab From 774623ca41280f74f499416fbbba3b1afbdd910e Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Fri, 19 Sep 2014 13:58:00 +0100 Subject: [PATCH 0071/9457] iio:adc:vf610-adc: Add temperature sensor support Vybrid ADC peripheral includes a temperature sensor which is connected to channel number 26. This patch adds support for the sensor. The raw value is read and the temperature calculated in milli degree Celsius, which is returned using IIO_CHAN_INFO_PROCESSED option. Signed-off-by: Sanchayan Maity Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 4a10ae97dbf2..7ec21b5612ef 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -91,7 +91,7 @@ #define VF610_ADC_CAL 0x80 /* Other field define */ -#define VF610_ADC_ADCHC(x) ((x) & 0xF) +#define VF610_ADC_ADCHC(x) ((x) & 0x1F) #define VF610_ADC_AIEN (0x1 << 7) #define VF610_ADC_CONV_DISABLE 0x1F #define VF610_ADC_HS_COCO0 0x1 @@ -153,6 +153,12 @@ struct vf610_adc { BIT(IIO_CHAN_INFO_SAMP_FREQ), \ } +#define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) { \ + .type = (_chan_type), \ + .channel = (_idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ +} + static const struct iio_chan_spec vf610_adc_iio_channels[] = { VF610_ADC_CHAN(0, IIO_VOLTAGE), VF610_ADC_CHAN(1, IIO_VOLTAGE), @@ -170,6 +176,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = { VF610_ADC_CHAN(13, IIO_VOLTAGE), VF610_ADC_CHAN(14, IIO_VOLTAGE), VF610_ADC_CHAN(15, IIO_VOLTAGE), + VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP), /* sentinel */ }; @@ -451,6 +458,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: mutex_lock(&indio_dev->mlock); reinit_completion(&info->completion); @@ -468,7 +476,23 @@ static int vf610_read_raw(struct iio_dev *indio_dev, return ret; } - *val = info->value; + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->value; + break; + case IIO_TEMP: + /* + * Calculate in degree Celsius times 1000 + * Using sensor slope of 1.84 mV/°C and + * V at 25°C of 696 mV + */ + *val = 25000 - ((int)info->value - 864) * 1000000 / 1840; + break; + default: + mutex_unlock(&indio_dev->mlock); + return -EINVAL; + } + mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; -- GitLab From 4c21bbb475c16be9ec878e8753d5e8373f9b9d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Mon, 15 Sep 2014 22:47:00 +0100 Subject: [PATCH 0072/9457] iio: adc: rockchip_saradc: add support for rk3066-tsadc variant Older Rockchip SoCs, at least the rk3066, used a slightly modified saradc for temperature measurements. This so called tsadc does not contain any active parts like temperature interrupts and only supports polling the current temperature. The returned voltage can then be converted by a suitable thermal driver to and actual temperature and used for thermal handling. Signed-off-by: Heiko Stuebner Acked-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/rockchip-saradc.txt | 2 +- drivers/iio/adc/rockchip_saradc.c | 64 +++++++++++++++---- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt index 5d3ec1df226d..a9a5fe19ff2a 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt @@ -1,7 +1,7 @@ Rockchip Successive Approximation Register (SAR) A/D Converter bindings Required properties: -- compatible: Should be "rockchip,saradc" +- compatible: Should be "rockchip,saradc" or "rockchip,rk3066-tsadc" - reg: physical base address of the controller and length of memory mapped region. - interrupts: The interrupt number to the cpu. The interrupt specifier format diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index e074a0b03f28..b546bc1a9c30 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -18,13 +18,13 @@ #include #include #include +#include #include #include #include #include #define SARADC_DATA 0x00 -#define SARADC_DATA_MASK 0x3ff #define SARADC_STAS 0x04 #define SARADC_STAS_BUSY BIT(0) @@ -38,15 +38,22 @@ #define SARADC_DLY_PU_SOC 0x0c #define SARADC_DLY_PU_SOC_MASK 0x3f -#define SARADC_BITS 10 #define SARADC_TIMEOUT msecs_to_jiffies(100) +struct rockchip_saradc_data { + int num_bits; + const struct iio_chan_spec *channels; + int num_channels; + unsigned long clk_rate; +}; + struct rockchip_saradc { void __iomem *regs; struct clk *pclk; struct clk *clk; struct completion completion; struct regulator *vref; + const struct rockchip_saradc_data *data; u16 last_val; }; @@ -90,7 +97,7 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, } *val = ret / 1000; - *val2 = SARADC_BITS; + *val2 = info->data->num_bits; return IIO_VAL_FRACTIONAL_LOG2; default: return -EINVAL; @@ -103,7 +110,7 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) /* Read value */ info->last_val = readl_relaxed(info->regs + SARADC_DATA); - info->last_val &= SARADC_DATA_MASK; + info->last_val &= GENMASK(info->data->num_bits - 1, 0); /* Clear irq & power down adc */ writel_relaxed(0, info->regs + SARADC_CTRL); @@ -133,12 +140,44 @@ static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { ADC_CHANNEL(2, "adc2"), }; +static const struct rockchip_saradc_data saradc_data = { + .num_bits = 10, + .channels = rockchip_saradc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), + .clk_rate = 1000000, +}; + +static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { + ADC_CHANNEL(0, "adc0"), + ADC_CHANNEL(1, "adc1"), +}; + +static const struct rockchip_saradc_data rk3066_tsadc_data = { + .num_bits = 12, + .channels = rockchip_rk3066_tsadc_iio_channels, + .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), + .clk_rate = 50000, +}; + +static const struct of_device_id rockchip_saradc_match[] = { + { + .compatible = "rockchip,saradc", + .data = &saradc_data, + }, { + .compatible = "rockchip,rk3066-tsadc", + .data = &rk3066_tsadc_data, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, rockchip_saradc_match); + static int rockchip_saradc_probe(struct platform_device *pdev) { struct rockchip_saradc *info = NULL; struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev = NULL; struct resource *mem; + const struct of_device_id *match; int ret; int irq; @@ -152,6 +191,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev) } info = iio_priv(indio_dev); + match = of_match_device(rockchip_saradc_match, &pdev->dev); + info->data = match->data; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); info->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(info->regs)) @@ -192,10 +234,10 @@ static int rockchip_saradc_probe(struct platform_device *pdev) } /* - * Use a default of 1MHz for the converter clock. + * Use a default value for the converter clock. * This may become user-configurable in the future. */ - ret = clk_set_rate(info->clk, 1000000); + ret = clk_set_rate(info->clk, info->data->clk_rate); if (ret < 0) { dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); return ret; @@ -227,8 +269,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) indio_dev->info = &rockchip_saradc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = rockchip_saradc_iio_channels; - indio_dev->num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels); + indio_dev->channels = info->data->channels; + indio_dev->num_channels = info->data->num_channels; ret = iio_device_register(indio_dev); if (ret) @@ -296,12 +338,6 @@ static int rockchip_saradc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, rockchip_saradc_suspend, rockchip_saradc_resume); -static const struct of_device_id rockchip_saradc_match[] = { - { .compatible = "rockchip,saradc" }, - {}, -}; -MODULE_DEVICE_TABLE(of, rockchip_saradc_match); - static struct platform_driver rockchip_saradc_driver = { .probe = rockchip_saradc_probe, .remove = rockchip_saradc_remove, -- GitLab From c20d4dffd537bee8d3db5ec28ca871ef73d44078 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Wed, 17 Sep 2014 01:11:00 +0100 Subject: [PATCH 0073/9457] iio: add documentation for current attribute Add documentation for input current raw sysfs attribute. Signed-off-by: Jacob Pan Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index d760b0224ef7..1ac9ac20f530 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1028,3 +1028,12 @@ Contact: linux-iio@vger.kernel.org Description: Raw value of rotation from true/magnetic north measured with or without compensation from tilt sensors. + +What: /sys/bus/iio/devices/iio:deviceX/in_currentX_raw +KernelVersion: 3.18 +Contact: linux-iio@vger.kernel.org +Description: + Raw current measurement from channel X. Units are in milliamps + after application of scale and offset. If no offset or scale is + present, output should be considered as processed with the + unit in milliamps. -- GitLab From d2dee86cece9deee33923ee71be918f0452c8ebe Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 19 Sep 2014 16:04:54 -0300 Subject: [PATCH 0074/9457] drm/i915: extract intel_init_fbc() Because I plan to expand it a little bit. Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 50 ++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1ec3c8f689bc..2ca9fdba7cb7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7358,33 +7358,39 @@ void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) pm_runtime_disable(device); } +static void intel_init_fbc(struct drm_i915_private *dev_priv) +{ + if (!HAS_FBC(dev_priv)) + return; + + if (INTEL_INFO(dev_priv)->gen >= 7) { + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; + dev_priv->display.enable_fbc = gen7_enable_fbc; + dev_priv->display.disable_fbc = ironlake_disable_fbc; + } else if (INTEL_INFO(dev_priv)->gen >= 5) { + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; + dev_priv->display.enable_fbc = ironlake_enable_fbc; + dev_priv->display.disable_fbc = ironlake_disable_fbc; + } else if (IS_GM45(dev_priv)) { + dev_priv->display.fbc_enabled = g4x_fbc_enabled; + dev_priv->display.enable_fbc = g4x_enable_fbc; + dev_priv->display.disable_fbc = g4x_disable_fbc; + } else { + dev_priv->display.fbc_enabled = i8xx_fbc_enabled; + dev_priv->display.enable_fbc = i8xx_enable_fbc; + dev_priv->display.disable_fbc = i8xx_disable_fbc; + + /* This value was pulled out of someone's hat */ + I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); + } +} + /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (HAS_FBC(dev)) { - if (INTEL_INFO(dev)->gen >= 7) { - dev_priv->display.fbc_enabled = ironlake_fbc_enabled; - dev_priv->display.enable_fbc = gen7_enable_fbc; - dev_priv->display.disable_fbc = ironlake_disable_fbc; - } else if (INTEL_INFO(dev)->gen >= 5) { - dev_priv->display.fbc_enabled = ironlake_fbc_enabled; - dev_priv->display.enable_fbc = ironlake_enable_fbc; - dev_priv->display.disable_fbc = ironlake_disable_fbc; - } else if (IS_GM45(dev)) { - dev_priv->display.fbc_enabled = g4x_fbc_enabled; - dev_priv->display.enable_fbc = g4x_enable_fbc; - dev_priv->display.disable_fbc = g4x_disable_fbc; - } else { - dev_priv->display.fbc_enabled = i8xx_fbc_enabled; - dev_priv->display.enable_fbc = i8xx_enable_fbc; - dev_priv->display.disable_fbc = i8xx_disable_fbc; - - /* This value was pulled out of someone's hat */ - I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); - } - } + intel_init_fbc(dev_priv); /* For cxsr */ if (IS_PINEVIEW(dev)) -- GitLab From 9adccc6063d1cf6ba38a5a26b87001554105be18 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 19 Sep 2014 16:04:55 -0300 Subject: [PATCH 0075/9457] drm/i915: add SW tracking to FBC enabling Currently, calling intel_fbc_enabled() will trigger a register read. And we call it a lot of times, even when FBC is disabled, so saving a few cycles would be a good thing. Another reason for this patch is because we currently call intel_fbc_enabled() while the HW is runtime suspended, so the read makes no sense and triggers a WARN. This happens even if FBC is disabled by default. Of course one could argue that we just shouldn't be calling intel_fbc_enabled() while the driver is runtime suspended, and I agree that's a good argument, but I still think that the reason explained in the first paragraph already justifies the patch. This problem can easily be reproduced with many subtests of igt/pm_rpm, and it is a regression introduced by: commit c5ad011d7d256ecbe173324029e992817194d2b0 Author: Rodrigo Vivi Date: Mon Aug 4 03:51:38 2014 -0700 drm/i915: FBC flush nuke for BDW Testcase: igt/pm_rpm/cursor (and others) Cc: Rodrigo Vivi Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/intel_pm.c | 31 ++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5fce16c9d647..999bd57cab65 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -662,6 +662,10 @@ struct i915_fbc { bool false_color; + /* Tracks whether the HW is actually enabled, not whether the feature is + * possible. */ + bool enabled; + struct intel_fbc_work { struct delayed_work work; struct drm_crtc *crtc; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2ca9fdba7cb7..6b416201240f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -71,6 +71,8 @@ static void i8xx_disable_fbc(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u32 fbc_ctl; + dev_priv->fbc.enabled = false; + /* Disable compression */ fbc_ctl = I915_READ(FBC_CONTROL); if ((fbc_ctl & FBC_CTL_EN) == 0) @@ -99,6 +101,8 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc) int i; u32 fbc_ctl; + dev_priv->fbc.enabled = true; + cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; if (fb->pitches[0] < cfb_pitch) cfb_pitch = fb->pitches[0]; @@ -153,6 +157,8 @@ static void g4x_enable_fbc(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 dpfc_ctl; + dev_priv->fbc.enabled = true; + dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN; if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) dpfc_ctl |= DPFC_CTL_LIMIT_2X; @@ -173,6 +179,8 @@ static void g4x_disable_fbc(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u32 dpfc_ctl; + dev_priv->fbc.enabled = false; + /* Disable compression */ dpfc_ctl = I915_READ(DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { @@ -224,6 +232,8 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 dpfc_ctl; + dev_priv->fbc.enabled = true; + dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane); if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) dev_priv->fbc.threshold++; @@ -264,6 +274,8 @@ static void ironlake_disable_fbc(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; u32 dpfc_ctl; + dev_priv->fbc.enabled = false; + /* Disable compression */ dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { @@ -290,6 +302,8 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); u32 dpfc_ctl; + dev_priv->fbc.enabled = true; + dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane); if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) dev_priv->fbc.threshold++; @@ -339,16 +353,7 @@ bool intel_fbc_enabled(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* If it wasn't never enabled by kernel parameter or platform default - * we can avoid reading registers so many times in vain - */ - if (!i915.enable_fbc) - return false; - - if (!dev_priv->display.fbc_enabled) - return false; - - return dev_priv->display.fbc_enabled(dev); + return dev_priv->fbc.enabled; } void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) @@ -7360,8 +7365,10 @@ void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) static void intel_init_fbc(struct drm_i915_private *dev_priv) { - if (!HAS_FBC(dev_priv)) + if (!HAS_FBC(dev_priv)) { + dev_priv->fbc.enabled = false; return; + } if (INTEL_INFO(dev_priv)->gen >= 7) { dev_priv->display.fbc_enabled = ironlake_fbc_enabled; @@ -7383,6 +7390,8 @@ static void intel_init_fbc(struct drm_i915_private *dev_priv) /* This value was pulled out of someone's hat */ I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); } + + dev_priv->fbc.enabled = dev_priv->display.fbc_enabled(dev_priv->dev); } /* Set up chip specific power management-related functions */ -- GitLab From 64badcb6d6459cc6f7b46f7d45e44c95ab874337 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 11:18:02 +0300 Subject: [PATCH 0076/9457] ath10k: workaround fw beaconing bug Some firmware revisions don't wait for beacon tx completion before sending another SWBA event. This could lead to hardware using old (freed) beacon data in some cases, e.g. tx credit starvation combined with missed TBTT. This is very very rare. On non-IOMMU-enabled hosts this could be a possible security issue because hw could beacon some random data on the air. On IOMMU-enabled hosts DMAR faults would occur in most cases and target device would crash. Since there are no beacon tx completions (implicit nor explicit) propagated to host the only workaround for this is to allocate a DMA-coherent buffer for a lifetime of a vif and use it for all beacon tx commands. Worst case for this approach is some beacons may become corrupted, e.g. garbled IEs or out-of-date TIM bitmap. Keep the original beacon-related code as-is in case future firmware revisions solve this problem so that the old path can be easily re-enabled with a fw_feature flag. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 + drivers/net/wireless/ath/ath10k/mac.c | 106 ++++++++++++++++++------- drivers/net/wireless/ath/ath10k/mac.h | 1 + drivers/net/wireless/ath/ath10k/wmi.c | 36 +++++---- 4 files changed, 102 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fe531ea6926c..d1ea936d14b7 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -234,6 +234,8 @@ struct ath10k_vif { struct sk_buff *beacon; /* protected by data_lock */ bool beacon_sent; + void *beacon_buf; + dma_addr_t beacon_paddr; struct ath10k *ar; struct ieee80211_vif *vif; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c708c100e361..fe00a71a4dba 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -479,6 +479,40 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) /* Interface management */ /************************/ +void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif) +{ + struct ath10k *ar = arvif->ar; + + lockdep_assert_held(&ar->data_lock); + + if (!arvif->beacon) + return; + + if (!arvif->beacon_buf) + dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr, + arvif->beacon->len, DMA_TO_DEVICE); + + dev_kfree_skb_any(arvif->beacon); + + arvif->beacon = NULL; + arvif->beacon_sent = false; +} + +static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif) +{ + struct ath10k *ar = arvif->ar; + + lockdep_assert_held(&ar->data_lock); + + ath10k_mac_vif_beacon_free(arvif); + + if (arvif->beacon_buf) { + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, arvif->beacon_paddr); + arvif->beacon_buf = NULL; + } +} + static inline int ath10k_vdev_setup_sync(struct ath10k *ar) { int ret; @@ -909,15 +943,7 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, arvif->is_up = false; spin_lock_bh(&arvif->ar->data_lock); - if (arvif->beacon) { - dma_unmap_single(arvif->ar->dev, - ATH10K_SKB_CB(arvif->beacon)->paddr, - arvif->beacon->len, DMA_TO_DEVICE); - dev_kfree_skb_any(arvif->beacon); - - arvif->beacon = NULL; - arvif->beacon_sent = false; - } + ath10k_mac_vif_beacon_free(arvif); spin_unlock_bh(&arvif->ar->data_lock); return; @@ -2376,16 +2402,8 @@ void ath10k_halt(struct ath10k *ar) ath10k_hif_power_down(ar); spin_lock_bh(&ar->data_lock); - list_for_each_entry(arvif, &ar->arvifs, list) { - if (!arvif->beacon) - continue; - - dma_unmap_single(arvif->ar->dev, - ATH10K_SKB_CB(arvif->beacon)->paddr, - arvif->beacon->len, DMA_TO_DEVICE); - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; - } + list_for_each_entry(arvif, &ar->arvifs, list) + ath10k_mac_vif_beacon_cleanup(arvif); spin_unlock_bh(&ar->data_lock); } @@ -2804,8 +2822,39 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, break; } - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n", - arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype); + /* Some firmware revisions don't wait for beacon tx completion before + * sending another SWBA event. This could lead to hardware using old + * (freed) beacon data in some cases, e.g. tx credit starvation + * combined with missed TBTT. This is very very rare. + * + * On non-IOMMU-enabled hosts this could be a possible security issue + * because hw could beacon some random data on the air. On + * IOMMU-enabled hosts DMAR faults would occur in most cases and target + * device would crash. + * + * Since there are no beacon tx completions (implicit nor explicit) + * propagated to host the only workaround for this is to allocate a + * DMA-coherent buffer for a lifetime of a vif and use it for all + * beacon tx commands. Worst case for this approach is some beacons may + * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap. + */ + if (vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_AP) { + arvif->beacon_buf = dma_zalloc_coherent(ar->dev, + IEEE80211_MAX_FRAME_LEN, + &arvif->beacon_paddr, + GFP_KERNEL); + if (!arvif->beacon_buf) { + ret = -ENOMEM; + ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", + ret); + goto err; + } + } + + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n", + arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype, + arvif->beacon_buf ? "single-buf" : "per-skb"); ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype, vif->addr); @@ -2912,6 +2961,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, list_del(&arvif->list); err: + if (arvif->beacon_buf) { + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, arvif->beacon_paddr); + arvif->beacon_buf = NULL; + } + mutex_unlock(&ar->conf_mutex); return ret; @@ -2929,14 +2984,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, cancel_work_sync(&arvif->wep_key_work); spin_lock_bh(&ar->data_lock); - if (arvif->beacon) { - dma_unmap_single(arvif->ar->dev, - ATH10K_SKB_CB(arvif->beacon)->paddr, - arvif->beacon->len, DMA_TO_DEVICE); - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; - } - + ath10k_mac_vif_beacon_cleanup(arvif); spin_unlock_bh(&ar->data_lock); ret = ath10k_spectral_vif_stop(arvif); diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index 6c80eeada3e2..965c51117499 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -39,6 +39,7 @@ void ath10k_offchan_tx_work(struct work_struct *work); void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_halt(struct ath10k *ar); +void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 2c42bd504b79..66392f6f1ab1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1579,6 +1579,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) struct wmi_bcn_info *bcn_info; struct ath10k_vif *arvif; struct sk_buff *bcn; + dma_addr_t paddr; int ret, vdev_id = 0; ev = (struct wmi_host_swba_event *)skb->data; @@ -1647,22 +1648,29 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) ath10k_warn(ar, "SWBA overrun on vdev %d\n", arvif->vdev_id); - dma_unmap_single(arvif->ar->dev, - ATH10K_SKB_CB(arvif->beacon)->paddr, - arvif->beacon->len, DMA_TO_DEVICE); - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; + ath10k_mac_vif_beacon_free(arvif); } - ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev, - bcn->data, bcn->len, - DMA_TO_DEVICE); - ret = dma_mapping_error(arvif->ar->dev, - ATH10K_SKB_CB(bcn)->paddr); - if (ret) { - ath10k_warn(ar, "failed to map beacon: %d\n", ret); - dev_kfree_skb_any(bcn); - goto skip; + if (!arvif->beacon_buf) { + paddr = dma_map_single(arvif->ar->dev, bcn->data, + bcn->len, DMA_TO_DEVICE); + ret = dma_mapping_error(arvif->ar->dev, paddr); + if (ret) { + ath10k_warn(ar, "failed to map beacon: %d\n", + ret); + dev_kfree_skb_any(bcn); + goto skip; + } + + ATH10K_SKB_CB(bcn)->paddr = paddr; + } else { + if (bcn->len > IEEE80211_MAX_FRAME_LEN) { + ath10k_warn(ar, "trimming beacon %d -> %d bytes!\n", + bcn->len, IEEE80211_MAX_FRAME_LEN); + skb_trim(bcn, IEEE80211_MAX_FRAME_LEN); + } + memcpy(arvif->beacon_buf, bcn->data, bcn->len); + ATH10K_SKB_CB(bcn)->paddr = arvif->beacon_paddr; } arvif->beacon = bcn; -- GitLab From fdb959c7e408b6b435c999e2fc7d8133fa95863d Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:19 +0200 Subject: [PATCH 0077/9457] ath10k: fix tx/rx chainmask init Firmware reports the number of RF chains so use that for initialization of supp_{tx,rx}_chainmask instead of using a macro for 3x3 chips. This should make tx/rx chainmask reports correct for chips other than 3x3. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 9 --------- drivers/net/wireless/ath/ath10k/wmi.c | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index fe00a71a4dba..d3e450261577 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4848,15 +4848,6 @@ int ath10k_mac_register(struct ath10k *ar) BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { - /* TODO: Have to deal with 2x2 chips if/when the come out. */ - ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK; - ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK; - } else { - ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK; - ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK; - } - ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 66392f6f1ab1..74e258517035 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2206,6 +2206,9 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; } + ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; + ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; + ar->ath_common.regulatory.current_rd = __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); @@ -2276,6 +2279,9 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; } + ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; + ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; + ar->ath_common.regulatory.current_rd = __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); -- GitLab From 1435c2bbdd913281a982f49d6a886cbfbc0a5950 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:20 +0200 Subject: [PATCH 0078/9457] ath10k: remove unused pdev_set_channel command This command is not used anymore and most firmware revisions do not seem to handle it well. Channel switching is done via vdev restarting. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 36 --------------------------- drivers/net/wireless/ath/ath10k/wmi.h | 7 ------ 2 files changed, 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 74e258517035..4f66a580bb3d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2879,42 +2879,6 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, ctl2g, ctl5g); } -int ath10k_wmi_pdev_set_channel(struct ath10k *ar, - const struct wmi_channel_arg *arg) -{ - struct wmi_set_channel_cmd *cmd; - struct sk_buff *skb; - u32 ch_flags = 0; - - if (arg->passive) - return -EINVAL; - - skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - if (arg->chan_radar) - ch_flags |= WMI_CHAN_FLAG_DFS; - - cmd = (struct wmi_set_channel_cmd *)skb->data; - cmd->chan.mhz = __cpu_to_le32(arg->freq); - cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq); - cmd->chan.mode = arg->mode; - cmd->chan.flags |= __cpu_to_le32(ch_flags); - cmd->chan.min_power = arg->min_power; - cmd->chan.max_power = arg->max_power; - cmd->chan.reg_power = arg->max_reg_power; - cmd->chan.reg_classid = arg->reg_class_id; - cmd->chan.antenna_max = arg->max_antenna_gain; - - ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi set channel mode %d freq %d\n", - arg->mode, arg->freq); - - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_channel_cmdid); -} - int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) { struct wmi_pdev_suspend_cmd *cmd; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 86f5ebccfe79..b8098d240620 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2908,11 +2908,6 @@ enum wmi_tp_scale { WMI_TP_SCALE_SIZE = 5, /* max num of enum */ }; -struct wmi_set_channel_cmd { - /* channel (only frequency and mode info are used) */ - struct wmi_channel chan; -} __packed; - struct wmi_pdev_chanlist_update_event { /* number of channels */ __le32 num_chan; @@ -4732,8 +4727,6 @@ int ath10k_wmi_connect(struct ath10k *ar); struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); -int ath10k_wmi_pdev_set_channel(struct ath10k *ar, - const struct wmi_channel_arg *); int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); int ath10k_wmi_pdev_resume_target(struct ath10k *ar); int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, -- GitLab From 2d66721c7bb1a6888eb17dd29758daf642df0b82 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:21 +0200 Subject: [PATCH 0079/9457] ath10k: deduplicate wmi_channel code The structure is being set up in 2 places. Deduplicate the code by creating a helper. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 1 + drivers/net/wireless/ath/ath10k/wmi.c | 77 +++++++++++++-------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index d3e450261577..51b16e1ad677 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1755,6 +1755,7 @@ static int ath10k_update_channel_list(struct ath10k *ar) ch->passive = passive; ch->freq = channel->center_freq; + ch->band_center_freq1 = channel->center_freq; ch->min_power = 0; ch->max_power = channel->max_power * 2; ch->max_reg_power = channel->max_reg_power * 2; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 4f66a580bb3d..34c214b73f99 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -609,6 +609,40 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = { .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, }; +static void +ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, + const struct wmi_channel_arg *arg) +{ + u32 flags = 0; + + memset(ch, 0, sizeof(*ch)); + + if (arg->passive) + flags |= WMI_CHAN_FLAG_PASSIVE; + if (arg->allow_ibss) + flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED; + if (arg->allow_ht) + flags |= WMI_CHAN_FLAG_ALLOW_HT; + if (arg->allow_vht) + flags |= WMI_CHAN_FLAG_ALLOW_VHT; + if (arg->ht40plus) + flags |= WMI_CHAN_FLAG_HT40_PLUS; + if (arg->chan_radar) + flags |= WMI_CHAN_FLAG_DFS; + + ch->mhz = __cpu_to_le32(arg->freq); + ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); + ch->band_center_freq2 = 0; + ch->min_power = arg->min_power; + ch->max_power = arg->max_power; + ch->reg_power = arg->max_reg_power; + ch->antenna_max = arg->max_antenna_gain; + + /* mode & flags share storage */ + ch->mode = arg->mode; + ch->flags |= __cpu_to_le32(flags); +} + int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { int ret; @@ -3510,7 +3544,6 @@ ath10k_wmi_vdev_start_restart(struct ath10k *ar, struct sk_buff *skb; const char *cmdname; u32 flags = 0; - u32 ch_flags = 0; if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) @@ -3537,8 +3570,6 @@ ath10k_wmi_vdev_start_restart(struct ath10k *ar, flags |= WMI_VDEV_START_HIDDEN_SSID; if (arg->pmf_enabled) flags |= WMI_VDEV_START_PMF_ENABLED; - if (arg->channel.chan_radar) - ch_flags |= WMI_CHAN_FLAG_DFS; cmd = (struct wmi_vdev_start_request_cmd *)skb->data; cmd->vdev_id = __cpu_to_le32(arg->vdev_id); @@ -3554,18 +3585,7 @@ ath10k_wmi_vdev_start_restart(struct ath10k *ar, memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); } - cmd->chan.mhz = __cpu_to_le32(arg->channel.freq); - - cmd->chan.band_center_freq1 = - __cpu_to_le32(arg->channel.band_center_freq1); - - cmd->chan.mode = arg->channel.mode; - cmd->chan.flags |= __cpu_to_le32(ch_flags); - cmd->chan.min_power = arg->channel.min_power; - cmd->chan.max_power = arg->channel.max_power; - cmd->chan.reg_power = arg->channel.max_reg_power; - cmd->chan.reg_classid = arg->channel.reg_class_id; - cmd->chan.antenna_max = arg->channel.max_antenna_gain; + ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n", @@ -3946,35 +3966,10 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); for (i = 0; i < arg->n_channels; i++) { - u32 flags = 0; - ch = &arg->channels[i]; ci = &cmd->chan_info[i]; - if (ch->passive) - flags |= WMI_CHAN_FLAG_PASSIVE; - if (ch->allow_ibss) - flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED; - if (ch->allow_ht) - flags |= WMI_CHAN_FLAG_ALLOW_HT; - if (ch->allow_vht) - flags |= WMI_CHAN_FLAG_ALLOW_VHT; - if (ch->ht40plus) - flags |= WMI_CHAN_FLAG_HT40_PLUS; - if (ch->chan_radar) - flags |= WMI_CHAN_FLAG_DFS; - - ci->mhz = __cpu_to_le32(ch->freq); - ci->band_center_freq1 = __cpu_to_le32(ch->freq); - ci->band_center_freq2 = 0; - ci->min_power = ch->min_power; - ci->max_power = ch->max_power; - ci->reg_power = ch->max_reg_power; - ci->antenna_max = ch->max_antenna_gain; - - /* mode & flags share storage */ - ci->mode = ch->mode; - ci->flags |= __cpu_to_le32(flags); + ath10k_wmi_put_wmi_channel(ci, ch); } return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); -- GitLab From cf9fca8f890e04a745fc9997ed75bcf0ed13b12b Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:22 +0200 Subject: [PATCH 0080/9457] ath10k: deduplicate host mem chunk code Simplify the code by deduplicating structure definitions and code. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 103 +++++++------------------- drivers/net/wireless/ath/ath10k/wmi.h | 30 +++----- 2 files changed, 34 insertions(+), 99 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 34c214b73f99..e796305ad5e1 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2963,13 +2963,34 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); } +static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, + struct wmi_host_mem_chunks *chunks) +{ + struct host_memory_chunk *chunk; + int i; + + chunks->count = __cpu_to_le32(ar->wmi.num_mem_chunks); + + for (i = 0; i < ar->wmi.num_mem_chunks; i++) { + chunk = &chunks->items[i]; + chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); + chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len); + chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); + + ath10k_dbg(ar, ATH10K_DBG_WMI, + "wmi chunk %d len %d requested, addr 0x%llx\n", + i, + ar->wmi.mem_chunks[i].len, + (unsigned long long)ar->wmi.mem_chunks[i].paddr); + } +} + static int ath10k_wmi_main_cmd_init(struct ath10k *ar) { struct wmi_init_cmd *cmd; struct sk_buff *buf; struct wmi_resource_config config = {}; u32 len, val; - int i; config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS); @@ -3031,32 +3052,8 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) cmd = (struct wmi_init_cmd *)buf->data; - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - ar->wmi.num_mem_chunks); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%llx\n", - i, - ar->wmi.mem_chunks[i].len, - (unsigned long long)ar->wmi.mem_chunks[i].paddr); - } -out: memcpy(&cmd->resource_config, &config, sizeof(config)); + ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); @@ -3068,7 +3065,6 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) struct sk_buff *buf; struct wmi_resource_config_10x config = {}; u32 len, val; - int i; config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); @@ -3122,32 +3118,8 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) cmd = (struct wmi_init_cmd_10x *)buf->data; - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - ar->wmi.num_mem_chunks); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%llx\n", - i, - ar->wmi.mem_chunks[i].len, - (unsigned long long)ar->wmi.mem_chunks[i].paddr); - } -out: memcpy(&cmd->resource_config, &config, sizeof(config)); + ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); @@ -3159,7 +3131,6 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) struct sk_buff *buf; struct wmi_resource_config_10x config = {}; u32 len, val; - int i; config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); @@ -3213,32 +3184,8 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) cmd = (struct wmi_init_cmd_10_2 *)buf->data; - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - ar->wmi.num_mem_chunks); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%llx\n", - i, - ar->wmi.mem_chunks[i].len, - (unsigned long long)ar->wmi.mem_chunks[i].paddr); - } -out: memcpy(&cmd->resource_config.common, &config, sizeof(config)); + ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index b8098d240620..fc8bc9dd3629 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -1883,38 +1883,26 @@ struct host_memory_chunk { __le32 size; } __packed; +struct wmi_host_mem_chunks { + __le32 count; + /* some fw revisions require at least 1 chunk regardless of count */ + struct host_memory_chunk items[1]; +} __packed; + struct wmi_init_cmd { struct wmi_resource_config resource_config; - __le32 num_host_mem_chunks; - - /* - * variable number of host memory chunks. - * This should be the last element in the structure - */ - struct host_memory_chunk host_mem_chunks[1]; + struct wmi_host_mem_chunks mem_chunks; } __packed; /* _10x stucture is from 10.X FW API */ struct wmi_init_cmd_10x { struct wmi_resource_config_10x resource_config; - __le32 num_host_mem_chunks; - - /* - * variable number of host memory chunks. - * This should be the last element in the structure - */ - struct host_memory_chunk host_mem_chunks[1]; + struct wmi_host_mem_chunks mem_chunks; } __packed; struct wmi_init_cmd_10_2 { struct wmi_resource_config_10_2 resource_config; - __le32 num_host_mem_chunks; - - /* - * variable number of host memory chunks. - * This should be the last element in the structure - */ - struct host_memory_chunk host_mem_chunks[1]; + struct wmi_host_mem_chunks mem_chunks; } __packed; struct wmi_chan_list_entry { -- GitLab From b79b9baac4f9ecec85353b76a45ae2eda4a1e41d Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:23 +0200 Subject: [PATCH 0081/9457] ath10k: relocate wmi attach/deatch functions Init functions should be placed at the end of files in most cases to avoid forward declarations for static functions. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 77 +++++++++++++-------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index e796305ad5e1..cec0c2839e5b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2780,45 +2780,6 @@ static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) } } -/* WMI Initialization functions */ -int ath10k_wmi_attach(struct ath10k *ar) -{ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { - if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) - ar->wmi.cmd = &wmi_10_2_cmd_map; - else - ar->wmi.cmd = &wmi_10x_cmd_map; - - ar->wmi.vdev_param = &wmi_10x_vdev_param_map; - ar->wmi.pdev_param = &wmi_10x_pdev_param_map; - } else { - ar->wmi.cmd = &wmi_cmd_map; - ar->wmi.vdev_param = &wmi_vdev_param_map; - ar->wmi.pdev_param = &wmi_pdev_param_map; - } - - init_completion(&ar->wmi.service_ready); - init_completion(&ar->wmi.unified_ready); - init_waitqueue_head(&ar->wmi.tx_credits_wq); - - return 0; -} - -void ath10k_wmi_detach(struct ath10k *ar) -{ - int i; - - /* free the host memory chunks requested by firmware */ - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - dma_free_coherent(ar->dev, - ar->wmi.mem_chunks[i].len, - ar->wmi.mem_chunks[i].vaddr, - ar->wmi.mem_chunks[i].paddr); - } - - ar->wmi.num_mem_chunks = 0; -} - int ath10k_wmi_connect(struct ath10k *ar) { int status; @@ -4187,3 +4148,41 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid); } + +int ath10k_wmi_attach(struct ath10k *ar) +{ + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) + ar->wmi.cmd = &wmi_10_2_cmd_map; + else + ar->wmi.cmd = &wmi_10x_cmd_map; + + ar->wmi.vdev_param = &wmi_10x_vdev_param_map; + ar->wmi.pdev_param = &wmi_10x_pdev_param_map; + } else { + ar->wmi.cmd = &wmi_cmd_map; + ar->wmi.vdev_param = &wmi_vdev_param_map; + ar->wmi.pdev_param = &wmi_pdev_param_map; + } + + init_completion(&ar->wmi.service_ready); + init_completion(&ar->wmi.unified_ready); + init_waitqueue_head(&ar->wmi.tx_credits_wq); + + return 0; +} + +void ath10k_wmi_detach(struct ath10k *ar) +{ + int i; + + /* free the host memory chunks requested by firmware */ + for (i = 0; i < ar->wmi.num_mem_chunks; i++) { + dma_free_coherent(ar->dev, + ar->wmi.mem_chunks[i].len, + ar->wmi.mem_chunks[i].vaddr, + ar->wmi.mem_chunks[i].paddr); + } + + ar->wmi.num_mem_chunks = 0; +} -- GitLab From 5c01aa3de918c0afc1b338df6d7162d461ad3a55 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:24 +0200 Subject: [PATCH 0082/9457] ath10k: deduplicate wmi service ready logic The logic responsible for processing the event is no different across different firmware binaries. The difference that needs to be dealt with is the ABI of data structures. The intermediate structure uses __le32 to avoid extra memory allocations to byteswap variable-length substructures (i.e. host mem chunks). Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 4 +- drivers/net/wireless/ath/ath10k/debug.c | 2 +- drivers/net/wireless/ath/ath10k/debug.h | 4 +- drivers/net/wireless/ath/ath10k/wmi.c | 237 ++++++++++++------------ drivers/net/wireless/ath/ath10k/wmi.h | 23 ++- 5 files changed, 141 insertions(+), 129 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d1ea936d14b7..8a997b6e11c3 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -96,8 +96,6 @@ struct ath10k_bmi { bool done_sent; }; -#define ATH10K_MAX_MEM_REQS 16 - struct ath10k_mem_chunk { void *vaddr; dma_addr_t paddr; @@ -115,7 +113,7 @@ struct ath10k_wmi { struct wmi_pdev_param_map *pdev_param; u32 num_mem_chunks; - struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS]; + struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS]; }; struct ath10k_peer_stat { diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 3756feba3223..101c6f9cf2a8 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -182,7 +182,7 @@ EXPORT_SYMBOL(ath10k_warn); #ifdef CONFIG_ATH10K_DEBUGFS void ath10k_debug_read_service_map(struct ath10k *ar, - void *service_map, + const void *service_map, size_t map_size) { memcpy(ar->debug.wmi_service_bitmap, service_map, map_size); diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index b3774f7f492c..d6276fea1adf 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -53,7 +53,7 @@ void ath10k_debug_destroy(struct ath10k *ar); int ath10k_debug_register(struct ath10k *ar); void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, - void *service_map, + const void *service_map, size_t map_size); void ath10k_debug_read_target_stats(struct ath10k *ar, struct wmi_stats_event *ev); @@ -93,7 +93,7 @@ static inline void ath10k_debug_unregister(struct ath10k *ar) } static inline void ath10k_debug_read_service_map(struct ath10k *ar, - void *service_map, + const void *service_map, size_t map_size) { } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index cec0c2839e5b..a7c11b292bf4 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2205,30 +2205,113 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, return 0; } +static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb, + struct wmi_svc_rdy_ev_arg *arg) +{ + struct wmi_service_ready_event *ev; + size_t i, n; + + if (skb->len < sizeof(*ev)) + return -EPROTO; + + ev = (void *)skb->data; + skb_pull(skb, sizeof(*ev)); + arg->min_tx_power = ev->hw_min_tx_power; + arg->max_tx_power = ev->hw_max_tx_power; + arg->ht_cap = ev->ht_cap_info; + arg->vht_cap = ev->vht_cap_info; + arg->sw_ver0 = ev->sw_version; + arg->sw_ver1 = ev->sw_version_1; + arg->phy_capab = ev->phy_capability; + arg->num_rf_chains = ev->num_rf_chains; + arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; + arg->num_mem_reqs = ev->num_mem_reqs; + arg->service_map = ev->wmi_service_bitmap; + + n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), + ARRAY_SIZE(arg->mem_reqs)); + for (i = 0; i < n; i++) + arg->mem_reqs[i] = &ev->mem_reqs[i]; + + if (skb->len < + __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) + return -EPROTO; + + return 0; +} + +static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb, + struct wmi_svc_rdy_ev_arg *arg) +{ + struct wmi_10x_service_ready_event *ev; + int i, n; + + if (skb->len < sizeof(*ev)) + return -EPROTO; + + ev = (void *)skb->data; + skb_pull(skb, sizeof(*ev)); + arg->min_tx_power = ev->hw_min_tx_power; + arg->max_tx_power = ev->hw_max_tx_power; + arg->ht_cap = ev->ht_cap_info; + arg->vht_cap = ev->vht_cap_info; + arg->sw_ver0 = ev->sw_version; + arg->phy_capab = ev->phy_capability; + arg->num_rf_chains = ev->num_rf_chains; + arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; + arg->num_mem_reqs = ev->num_mem_reqs; + arg->service_map = ev->wmi_service_bitmap; + + n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), + ARRAY_SIZE(arg->mem_reqs)); + for (i = 0; i < n; i++) + arg->mem_reqs[i] = &ev->mem_reqs[i]; + + if (skb->len < + __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) + return -EPROTO; + + return 0; +} + static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { - struct wmi_service_ready_event *ev = (void *)skb->data; + struct wmi_svc_rdy_ev_arg arg = {}; + u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {}; + int ret; - if (skb->len < sizeof(*ev)) { - ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", - skb->len, sizeof(*ev)); + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg); + wmi_10x_svc_map(arg.service_map, svc_bmap); + } else { + ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg); + wmi_main_svc_map(arg.service_map, svc_bmap); + } + + if (ret) { + ath10k_warn(ar, "failed to parse service ready: %d\n", ret); return; } - ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); - ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); - ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); - ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); + ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power); + ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power); + ar->ht_cap_info = __le32_to_cpu(arg.ht_cap); + ar->vht_cap_info = __le32_to_cpu(arg.vht_cap); ar->fw_version_major = - (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; - ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); + (__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24; + ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff); ar->fw_version_release = - (__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16; - ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff); - ar->phy_capability = __le32_to_cpu(ev->phy_capability); - ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); + (__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16; + ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff); + ar->phy_capability = __le32_to_cpu(arg.phy_capab); + ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains); + ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd); + + ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); + ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", + arg.service_map, sizeof(arg.service_map)); /* only manually set fw features when not using FW IE format */ if (ar->fw_api == 1 && ar->fw_version_build > 636) @@ -2243,14 +2326,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; - ar->ath_common.regulatory.current_rd = - __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - - wmi_main_svc_map(ev->wmi_service_bitmap, svc_bmap); - ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); - ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", - ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap)); - if (strlen(ar->hw->wiphy->fw_version) == 0) { snprintf(ar->hw->wiphy->fw_version, sizeof(ar->hw->wiphy->fw_version), @@ -2261,96 +2336,18 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->fw_version_build); } - /* FIXME: it probably should be better to support this */ - if (__le32_to_cpu(ev->num_mem_reqs) > 0) { - ath10k_warn(ar, "target requested %d memory chunks; ignoring\n", - __le32_to_cpu(ev->num_mem_reqs)); - } - - ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", - __le32_to_cpu(ev->sw_version), - __le32_to_cpu(ev->sw_version_1), - __le32_to_cpu(ev->abi_version), - __le32_to_cpu(ev->phy_capability), - __le32_to_cpu(ev->ht_cap_info), - __le32_to_cpu(ev->vht_cap_info), - __le32_to_cpu(ev->vht_supp_mcs), - __le32_to_cpu(ev->sys_cap_info), - __le32_to_cpu(ev->num_mem_reqs), - __le32_to_cpu(ev->num_rf_chains)); - - complete(&ar->wmi.service_ready); -} - -static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, - struct sk_buff *skb) -{ - u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; - int ret; - struct wmi_service_ready_event_10x *ev = (void *)skb->data; - DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {}; - - if (skb->len < sizeof(*ev)) { - ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", - skb->len, sizeof(*ev)); - return; - } - - ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); - ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); - ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); - ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); - ar->fw_version_major = - (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; - ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); - ar->phy_capability = __le32_to_cpu(ev->phy_capability); - ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); - - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { - ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", - ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); - ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; - } - - ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; - ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; - - ar->ath_common.regulatory.current_rd = - __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - - wmi_10x_svc_map(ev->wmi_service_bitmap, svc_bmap); - ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); - ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", - ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap)); - - if (strlen(ar->hw->wiphy->fw_version) == 0) { - snprintf(ar->hw->wiphy->fw_version, - sizeof(ar->hw->wiphy->fw_version), - "%u.%u", - ar->fw_version_major, - ar->fw_version_minor); - } - - num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); - - if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { + num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs); + if (num_mem_reqs > WMI_MAX_MEM_REQS) { ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n", num_mem_reqs); return; } - if (!num_mem_reqs) - goto exit; - - ath10k_dbg(ar, ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", - num_mem_reqs); - for (i = 0; i < num_mem_reqs; ++i) { - req_id = __le32_to_cpu(ev->mem_reqs[i].req_id); - num_units = __le32_to_cpu(ev->mem_reqs[i].num_units); - unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size); - num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info); + req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id); + num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units); + unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size); + num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info); if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) /* number of units to allocate is number of @@ -2364,7 +2361,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", req_id, - __le32_to_cpu(ev->mem_reqs[i].num_units), + __le32_to_cpu(arg.mem_reqs[i]->num_units), num_unit_info, unit_size, num_units); @@ -2375,18 +2372,18 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, return; } -exit: ath10k_dbg(ar, ATH10K_DBG_WMI, - "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", - __le32_to_cpu(ev->sw_version), - __le32_to_cpu(ev->abi_version), - __le32_to_cpu(ev->phy_capability), - __le32_to_cpu(ev->ht_cap_info), - __le32_to_cpu(ev->vht_cap_info), - __le32_to_cpu(ev->vht_supp_mcs), - __le32_to_cpu(ev->sys_cap_info), - __le32_to_cpu(ev->num_mem_reqs), - __le32_to_cpu(ev->num_rf_chains)); + "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n", + __le32_to_cpu(arg.min_tx_power), + __le32_to_cpu(arg.max_tx_power), + __le32_to_cpu(arg.ht_cap), + __le32_to_cpu(arg.vht_cap), + __le32_to_cpu(arg.sw_ver0), + __le32_to_cpu(arg.sw_ver1), + __le32_to_cpu(arg.phy_capab), + __le32_to_cpu(arg.num_rf_chains), + __le32_to_cpu(arg.eeprom_rd), + __le32_to_cpu(arg.num_mem_reqs)); complete(&ar->wmi.service_ready); } @@ -2634,7 +2631,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_vdev_resume_req(ar, skb); break; case WMI_10X_SERVICE_READY_EVENTID: - ath10k_wmi_10x_service_ready_event_rx(ar, skb); + ath10k_wmi_service_ready_event_rx(ar, skb); break; case WMI_10X_READY_EVENTID: ath10k_wmi_ready_event_rx(ar, skb); @@ -2745,7 +2742,7 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_vdev_resume_req(ar, skb); break; case WMI_10_2_SERVICE_READY_EVENTID: - ath10k_wmi_10x_service_ready_event_rx(ar, skb); + ath10k_wmi_service_ready_event_rx(ar, skb); break; case WMI_10_2_READY_EVENTID: ath10k_wmi_ready_event_rx(ar, skb); diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index fc8bc9dd3629..ca31cdbac557 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -1428,11 +1428,11 @@ struct wmi_service_ready_event { * where FW can access this memory directly (or) by DMA. */ __le32 num_mem_reqs; - struct wlan_host_mem_req mem_reqs[1]; + struct wlan_host_mem_req mem_reqs[0]; } __packed; /* This is the definition from 10.X firmware branch */ -struct wmi_service_ready_event_10x { +struct wmi_10x_service_ready_event { __le32 sw_version; __le32 abi_version; @@ -1467,7 +1467,7 @@ struct wmi_service_ready_event_10x { */ __le32 num_mem_reqs; - struct wlan_host_mem_req mem_reqs[1]; + struct wlan_host_mem_req mem_reqs[0]; } __packed; #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ) @@ -4702,6 +4702,23 @@ struct wmi_dbglog_cfg_cmd { /* By default disable power save for IBSS */ #define ATH10K_DEFAULT_ATIM 0 +#define WMI_MAX_MEM_REQS 16 + +struct wmi_svc_rdy_ev_arg { + __le32 min_tx_power; + __le32 max_tx_power; + __le32 ht_cap; + __le32 vht_cap; + __le32 sw_ver0; + __le32 sw_ver1; + __le32 phy_capab; + __le32 num_rf_chains; + __le32 eeprom_rd; + __le32 num_mem_reqs; + const __le32 *service_map; + const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; +}; + struct ath10k; struct ath10k_vif; -- GitLab From 2332d0ae92f6d2fec5e0a970bc14869801ae10a8 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:25 +0200 Subject: [PATCH 0083/9457] ath10k: clean up phyerr code Make the phyerr structures more compact and easier to understand. Also add constness. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/spectral.c | 34 +++----- drivers/net/wireless/ath/ath10k/spectral.h | 8 +- drivers/net/wireless/ath/ath10k/wmi.c | 90 +++++++++++----------- drivers/net/wireless/ath/ath10k/wmi.h | 83 ++------------------ 4 files changed, 66 insertions(+), 149 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c index 3e1454b74e00..63ce61fcdac8 100644 --- a/drivers/net/wireless/ath/ath10k/spectral.c +++ b/drivers/net/wireless/ath/ath10k/spectral.c @@ -56,14 +56,14 @@ static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len, } int ath10k_spectral_process_fft(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, - struct phyerr_fft_report *fftr, + const struct wmi_phyerr *phyerr, + const struct phyerr_fft_report *fftr, size_t bin_len, u64 tsf) { struct fft_sample_ath10k *fft_sample; u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS]; u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag; - u32 reg0, reg1, nf_list1, nf_list2; + u32 reg0, reg1; u8 chain_idx, *bins; int dc_pos; @@ -82,7 +82,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar, /* TODO: there might be a reason why the hardware reports 20/40/80 MHz, * but the results/plots suggest that its actually 22/44/88 MHz. */ - switch (event->hdr.chan_width_mhz) { + switch (phyerr->chan_width_mhz) { case 20: fft_sample->chan_width_mhz = 22; break; @@ -101,7 +101,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar, fft_sample->chan_width_mhz = 88; break; default: - fft_sample->chan_width_mhz = event->hdr.chan_width_mhz; + fft_sample->chan_width_mhz = phyerr->chan_width_mhz; } fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB); @@ -110,36 +110,22 @@ int ath10k_spectral_process_fft(struct ath10k *ar, peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); fft_sample->max_magnitude = __cpu_to_be16(peak_mag); fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX); - fft_sample->rssi = event->hdr.rssi_combined; + fft_sample->rssi = phyerr->rssi_combined; total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB); base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB); fft_sample->total_gain_db = __cpu_to_be16(total_gain_db); fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db); - freq1 = __le16_to_cpu(event->hdr.freq1); - freq2 = __le16_to_cpu(event->hdr.freq2); + freq1 = __le16_to_cpu(phyerr->freq1); + freq2 = __le16_to_cpu(phyerr->freq2); fft_sample->freq1 = __cpu_to_be16(freq1); fft_sample->freq2 = __cpu_to_be16(freq2); - nf_list1 = __le32_to_cpu(event->hdr.nf_list_1); - nf_list2 = __le32_to_cpu(event->hdr.nf_list_2); chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX); - switch (chain_idx) { - case 0: - fft_sample->noise = __cpu_to_be16(nf_list1 & 0xffffu); - break; - case 1: - fft_sample->noise = __cpu_to_be16((nf_list1 >> 16) & 0xffffu); - break; - case 2: - fft_sample->noise = __cpu_to_be16(nf_list2 & 0xffffu); - break; - case 3: - fft_sample->noise = __cpu_to_be16((nf_list2 >> 16) & 0xffffu); - break; - } + fft_sample->noise = __cpu_to_be16( + __le16_to_cpu(phyerr->nf_chains[chain_idx])); bins = (u8 *)fftr; bins += sizeof(*fftr); diff --git a/drivers/net/wireless/ath/ath10k/spectral.h b/drivers/net/wireless/ath/ath10k/spectral.h index ddc57c557272..042f5b302c75 100644 --- a/drivers/net/wireless/ath/ath10k/spectral.h +++ b/drivers/net/wireless/ath/ath10k/spectral.h @@ -47,8 +47,8 @@ enum ath10k_spectral_mode { #ifdef CONFIG_ATH10K_DEBUGFS int ath10k_spectral_process_fft(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, - struct phyerr_fft_report *fftr, + const struct wmi_phyerr *phyerr, + const struct phyerr_fft_report *fftr, size_t bin_len, u64 tsf); int ath10k_spectral_start(struct ath10k *ar); int ath10k_spectral_vif_stop(struct ath10k_vif *arvif); @@ -59,8 +59,8 @@ void ath10k_spectral_destroy(struct ath10k *ar); static inline int ath10k_spectral_process_fft(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, - struct phyerr_fft_report *fftr, + const struct wmi_phyerr *phyerr, + const struct phyerr_fft_report *fftr, size_t bin_len, u64 tsf) { return 0; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index a7c11b292bf4..ad1b2725c556 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1723,8 +1723,8 @@ static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, } static void ath10k_dfs_radar_report(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, - struct phyerr_radar_report *rr, + const struct wmi_phyerr *phyerr, + const struct phyerr_radar_report *rr, u64 tsf) { u32 reg0, reg1, tsf32l; @@ -1757,12 +1757,12 @@ static void ath10k_dfs_radar_report(struct ath10k *ar, return; /* report event to DFS pattern detector */ - tsf32l = __le32_to_cpu(event->hdr.tsf_timestamp); + tsf32l = __le32_to_cpu(phyerr->tsf_timestamp); tsf64 = tsf & (~0xFFFFFFFFULL); tsf64 |= tsf32l; width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR); - rssi = event->hdr.rssi_combined; + rssi = phyerr->rssi_combined; /* hardware store this as 8 bit signed value, * set to zero if negative number @@ -1801,8 +1801,8 @@ static void ath10k_dfs_radar_report(struct ath10k *ar, } static int ath10k_dfs_fft_report(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, - struct phyerr_fft_report *fftr, + const struct wmi_phyerr *phyerr, + const struct phyerr_fft_report *fftr, u64 tsf) { u32 reg0, reg1; @@ -1810,7 +1810,7 @@ static int ath10k_dfs_fft_report(struct ath10k *ar, reg0 = __le32_to_cpu(fftr->reg0); reg1 = __le32_to_cpu(fftr->reg1); - rssi = event->hdr.rssi_combined; + rssi = phyerr->rssi_combined; ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", @@ -1839,20 +1839,20 @@ static int ath10k_dfs_fft_report(struct ath10k *ar, } static void ath10k_wmi_event_dfs(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, + const struct wmi_phyerr *phyerr, u64 tsf) { int buf_len, tlv_len, res, i = 0; - struct phyerr_tlv *tlv; - struct phyerr_radar_report *rr; - struct phyerr_fft_report *fftr; - u8 *tlv_buf; + const struct phyerr_tlv *tlv; + const struct phyerr_radar_report *rr; + const struct phyerr_fft_report *fftr; + const u8 *tlv_buf; - buf_len = __le32_to_cpu(event->hdr.buf_len); + buf_len = __le32_to_cpu(phyerr->buf_len); ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", - event->hdr.phy_err_code, event->hdr.rssi_combined, - __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len); + phyerr->phy_err_code, phyerr->rssi_combined, + __le32_to_cpu(phyerr->tsf_timestamp), tsf, buf_len); /* Skip event if DFS disabled */ if (!config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) @@ -1867,9 +1867,9 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, return; } - tlv = (struct phyerr_tlv *)&event->bufp[i]; + tlv = (struct phyerr_tlv *)&phyerr->buf[i]; tlv_len = __le16_to_cpu(tlv->len); - tlv_buf = &event->bufp[i + sizeof(*tlv)]; + tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", tlv_len, tlv->tag, tlv->sig); @@ -1883,7 +1883,7 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, } rr = (struct phyerr_radar_report *)tlv_buf; - ath10k_dfs_radar_report(ar, event, rr, tsf); + ath10k_dfs_radar_report(ar, phyerr, rr, tsf); break; case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { @@ -1893,7 +1893,7 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, } fftr = (struct phyerr_fft_report *)tlv_buf; - res = ath10k_dfs_fft_report(ar, event, fftr, tsf); + res = ath10k_dfs_fft_report(ar, phyerr, fftr, tsf); if (res) return; break; @@ -1905,16 +1905,16 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, - struct wmi_single_phyerr_rx_event *event, + const struct wmi_phyerr *phyerr, u64 tsf) { int buf_len, tlv_len, res, i = 0; struct phyerr_tlv *tlv; - u8 *tlv_buf; - struct phyerr_fft_report *fftr; + const void *tlv_buf; + const struct phyerr_fft_report *fftr; size_t fftr_len; - buf_len = __le32_to_cpu(event->hdr.buf_len); + buf_len = __le32_to_cpu(phyerr->buf_len); while (i < buf_len) { if (i + sizeof(*tlv) > buf_len) { @@ -1923,9 +1923,9 @@ ath10k_wmi_event_spectral_scan(struct ath10k *ar, return; } - tlv = (struct phyerr_tlv *)&event->bufp[i]; + tlv = (struct phyerr_tlv *)&phyerr->buf[i]; tlv_len = __le16_to_cpu(tlv->len); - tlv_buf = &event->bufp[i + sizeof(*tlv)]; + tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; if (i + sizeof(*tlv) + tlv_len > buf_len) { ath10k_warn(ar, "failed to parse phyerr tlv payload at byte %d\n", @@ -1942,8 +1942,8 @@ ath10k_wmi_event_spectral_scan(struct ath10k *ar, } fftr_len = tlv_len - sizeof(*fftr); - fftr = (struct phyerr_fft_report *)tlv_buf; - res = ath10k_spectral_process_fft(ar, event, + fftr = tlv_buf; + res = ath10k_spectral_process_fft(ar, phyerr, fftr, fftr_len, tsf); if (res < 0) { @@ -1960,8 +1960,8 @@ ath10k_wmi_event_spectral_scan(struct ath10k *ar, static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) { - struct wmi_comb_phyerr_rx_event *comb_event; - struct wmi_single_phyerr_rx_event *event; + const struct wmi_phyerr_event *ev; + const struct wmi_phyerr *phyerr; u32 count, i, buf_len, phy_err_code; u64 tsf; int left_len = skb->len; @@ -1969,38 +1969,38 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) ATH10K_DFS_STAT_INC(ar, phy_errors); /* Check if combined event available */ - if (left_len < sizeof(*comb_event)) { + if (left_len < sizeof(*ev)) { ath10k_warn(ar, "wmi phyerr combined event wrong len\n"); return; } - left_len -= sizeof(*comb_event); + left_len -= sizeof(*ev); /* Check number of included events */ - comb_event = (struct wmi_comb_phyerr_rx_event *)skb->data; - count = __le32_to_cpu(comb_event->hdr.num_phyerr_events); + ev = (const struct wmi_phyerr_event *)skb->data; + count = __le32_to_cpu(ev->num_phyerrs); - tsf = __le32_to_cpu(comb_event->hdr.tsf_u32); + tsf = __le32_to_cpu(ev->tsf_u32); tsf <<= 32; - tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32); + tsf |= __le32_to_cpu(ev->tsf_l32); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event phyerr count %d tsf64 0x%llX\n", count, tsf); - event = (struct wmi_single_phyerr_rx_event *)comb_event->bufp; + phyerr = ev->phyerrs; for (i = 0; i < count; i++) { /* Check if we can read event header */ - if (left_len < sizeof(*event)) { + if (left_len < sizeof(*phyerr)) { ath10k_warn(ar, "single event (%d) wrong head len\n", i); return; } - left_len -= sizeof(*event); + left_len -= sizeof(*phyerr); - buf_len = __le32_to_cpu(event->hdr.buf_len); - phy_err_code = event->hdr.phy_err_code; + buf_len = __le32_to_cpu(phyerr->buf_len); + phy_err_code = phyerr->phy_err_code; if (left_len < buf_len) { ath10k_warn(ar, "single event (%d) wrong buf len\n", i); @@ -2011,20 +2011,20 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) switch (phy_err_code) { case PHY_ERROR_RADAR: - ath10k_wmi_event_dfs(ar, event, tsf); + ath10k_wmi_event_dfs(ar, phyerr, tsf); break; case PHY_ERROR_SPECTRAL_SCAN: - ath10k_wmi_event_spectral_scan(ar, event, tsf); + ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); break; case PHY_ERROR_FALSE_RADAR_EXT: - ath10k_wmi_event_dfs(ar, event, tsf); - ath10k_wmi_event_spectral_scan(ar, event, tsf); + ath10k_wmi_event_dfs(ar, phyerr, tsf); + ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); break; default: break; } - event += sizeof(*event) + buf_len; + phyerr = (void *)phyerr + sizeof(*phyerr) + buf_len; } } diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index ca31cdbac557..0df5eef21318 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2294,94 +2294,25 @@ struct wmi_mgmt_rx_event_v2 { #define PHY_ERROR_FALSE_RADAR_EXT 0x24 #define PHY_ERROR_RADAR 0x05 -struct wmi_single_phyerr_rx_hdr { - /* TSF timestamp */ +struct wmi_phyerr { __le32 tsf_timestamp; - - /* - * Current freq1, freq2 - * - * [7:0]: freq1[lo] - * [15:8] : freq1[hi] - * [23:16]: freq2[lo] - * [31:24]: freq2[hi] - */ __le16 freq1; __le16 freq2; - - /* - * Combined RSSI over all chains and channel width for this PHY error - * - * [7:0]: RSSI combined - * [15:8]: Channel width (MHz) - * [23:16]: PHY error code - * [24:16]: reserved (future use) - */ u8 rssi_combined; u8 chan_width_mhz; u8 phy_err_code; u8 rsvd0; - - /* - * RSSI on chain 0 through 3 - * - * This is formatted the same as the PPDU_START RX descriptor - * field: - * - * [7:0]: pri20 - * [15:8]: sec20 - * [23:16]: sec40 - * [31:24]: sec80 - */ - - __le32 rssi_chain0; - __le32 rssi_chain1; - __le32 rssi_chain2; - __le32 rssi_chain3; - - /* - * Last calibrated NF value for chain 0 through 3 - * - * nf_list_1: - * - * + [15:0] - chain 0 - * + [31:16] - chain 1 - * - * nf_list_2: - * - * + [15:0] - chain 2 - * + [31:16] - chain 3 - */ - __le32 nf_list_1; - __le32 nf_list_2; - - /* Length of the frame */ + __le32 rssi_chains[4]; + __le16 nf_chains[4]; __le32 buf_len; + u8 buf[0]; } __packed; -struct wmi_single_phyerr_rx_event { - /* Phy error event header */ - struct wmi_single_phyerr_rx_hdr hdr; - /* frame buffer */ - u8 bufp[0]; -} __packed; - -struct wmi_comb_phyerr_rx_hdr { - /* Phy error phy error count */ - __le32 num_phyerr_events; +struct wmi_phyerr_event { + __le32 num_phyerrs; __le32 tsf_l32; __le32 tsf_u32; -} __packed; - -struct wmi_comb_phyerr_rx_event { - /* Phy error phy error count */ - struct wmi_comb_phyerr_rx_hdr hdr; - /* - * frame buffer - contains multiple payloads in the order: - * header - payload, header - payload... - * (The header is of type: wmi_single_phyerr_rx_hdr) - */ - u8 bufp[0]; + struct wmi_phyerr phyerrs[0]; } __packed; #define PHYERR_TLV_SIG 0xBB -- GitLab From b34d2b3d7d0d28888571ad05105b4804b514b7c5 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:26 +0200 Subject: [PATCH 0084/9457] ath10k: unify wmi event function names Make all wmi event functions match the same naming style, i.e. ath10k_wmi_event_. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ad1b2725c556..ca250ffadef7 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2274,8 +2274,8 @@ static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb, return 0; } -static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, - struct sk_buff *skb) +static void ath10k_wmi_event_service_ready(struct ath10k *ar, + struct sk_buff *skb) { struct wmi_svc_rdy_ev_arg arg = {}; u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; @@ -2388,7 +2388,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, complete(&ar->wmi.service_ready); } -static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) +static int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) { struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; @@ -2511,10 +2511,10 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_vdev_install_key_complete(ar, skb); break; case WMI_SERVICE_READY_EVENTID: - ath10k_wmi_service_ready_event_rx(ar, skb); + ath10k_wmi_event_service_ready(ar, skb); break; case WMI_READY_EVENTID: - ath10k_wmi_ready_event_rx(ar, skb); + ath10k_wmi_event_ready(ar, skb); break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); @@ -2631,10 +2631,10 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_vdev_resume_req(ar, skb); break; case WMI_10X_SERVICE_READY_EVENTID: - ath10k_wmi_service_ready_event_rx(ar, skb); + ath10k_wmi_event_service_ready(ar, skb); break; case WMI_10X_READY_EVENTID: - ath10k_wmi_ready_event_rx(ar, skb); + ath10k_wmi_event_ready(ar, skb); break; case WMI_10X_PDEV_UTF_EVENTID: /* ignore utf events */ @@ -2742,10 +2742,10 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_event_vdev_resume_req(ar, skb); break; case WMI_10_2_SERVICE_READY_EVENTID: - ath10k_wmi_service_ready_event_rx(ar, skb); + ath10k_wmi_event_service_ready(ar, skb); break; case WMI_10_2_READY_EVENTID: - ath10k_wmi_ready_event_rx(ar, skb); + ath10k_wmi_event_ready(ar, skb); break; case WMI_10_2_RTT_KEEPALIVE_EVENTID: case WMI_10_2_GPIO_INPUT_EVENTID: -- GitLab From a6aa5da3029670816b3eb9358bc1a63f2e2564fb Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 18 Sep 2014 15:21:27 +0200 Subject: [PATCH 0085/9457] ath10k: re-work scan start command building This gets rid of the ugly scan structure building and uses a saner way to do it. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 191 ++++++++++++++------------ drivers/net/wireless/ath/ath10k/wmi.h | 100 ++------------ 2 files changed, 119 insertions(+), 172 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ca250ffadef7..bfc1fb3708c5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3165,52 +3165,50 @@ int ath10k_wmi_cmd_init(struct ath10k *ar) return ret; } -static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar, - const struct wmi_start_scan_arg *arg) +static int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg) { - int len; + if (arg->ie_len && !arg->ie) + return -EINVAL; + if (arg->n_channels && !arg->channels) + return -EINVAL; + if (arg->n_ssids && !arg->ssids) + return -EINVAL; + if (arg->n_bssids && !arg->bssids) + return -EINVAL; - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - len = sizeof(struct wmi_start_scan_cmd_10x); - else - len = sizeof(struct wmi_start_scan_cmd); + if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN) + return -EINVAL; + if (arg->n_channels > ARRAY_SIZE(arg->channels)) + return -EINVAL; + if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID) + return -EINVAL; + if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID) + return -EINVAL; - if (arg->ie_len) { - if (!arg->ie) - return -EINVAL; - if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN) - return -EINVAL; + return 0; +} +static size_t +ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg) +{ + int len = 0; + + if (arg->ie_len) { len += sizeof(struct wmi_ie_data); len += roundup(arg->ie_len, 4); } if (arg->n_channels) { - if (!arg->channels) - return -EINVAL; - if (arg->n_channels > ARRAY_SIZE(arg->channels)) - return -EINVAL; - len += sizeof(struct wmi_chan_list); len += sizeof(__le32) * arg->n_channels; } if (arg->n_ssids) { - if (!arg->ssids) - return -EINVAL; - if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID) - return -EINVAL; - len += sizeof(struct wmi_ssid_list); len += sizeof(struct wmi_ssid) * arg->n_ssids; } if (arg->n_bssids) { - if (!arg->bssids) - return -EINVAL; - if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID) - return -EINVAL; - len += sizeof(struct wmi_bssid_list); len += sizeof(struct wmi_mac_addr) * arg->n_bssids; } @@ -3218,28 +3216,12 @@ static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar, return len; } -int ath10k_wmi_start_scan(struct ath10k *ar, - const struct wmi_start_scan_arg *arg) +static void +ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, + const struct wmi_start_scan_arg *arg) { - struct wmi_start_scan_cmd *cmd; - struct sk_buff *skb; - struct wmi_ie_data *ie; - struct wmi_chan_list *channels; - struct wmi_ssid_list *ssids; - struct wmi_bssid_list *bssids; u32 scan_id; u32 scan_req_id; - int off; - int len = 0; - int i; - - len = ath10k_wmi_start_scan_calc_len(ar, arg); - if (len < 0) - return len; /* len contains error code here */ - - skb = ath10k_wmi_alloc_skb(ar, len); - if (!skb) - return -ENOMEM; scan_id = WMI_HOST_SCAN_REQ_ID_PREFIX; scan_id |= arg->scan_id; @@ -3247,35 +3229,36 @@ int ath10k_wmi_start_scan(struct ath10k *ar, scan_req_id = WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; scan_req_id |= arg->scan_req_id; - cmd = (struct wmi_start_scan_cmd *)skb->data; - cmd->scan_id = __cpu_to_le32(scan_id); - cmd->scan_req_id = __cpu_to_le32(scan_req_id); - cmd->vdev_id = __cpu_to_le32(arg->vdev_id); - cmd->scan_priority = __cpu_to_le32(arg->scan_priority); - cmd->notify_scan_events = __cpu_to_le32(arg->notify_scan_events); - cmd->dwell_time_active = __cpu_to_le32(arg->dwell_time_active); - cmd->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive); - cmd->min_rest_time = __cpu_to_le32(arg->min_rest_time); - cmd->max_rest_time = __cpu_to_le32(arg->max_rest_time); - cmd->repeat_probe_time = __cpu_to_le32(arg->repeat_probe_time); - cmd->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time); - cmd->idle_time = __cpu_to_le32(arg->idle_time); - cmd->max_scan_time = __cpu_to_le32(arg->max_scan_time); - cmd->probe_delay = __cpu_to_le32(arg->probe_delay); - cmd->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); - - /* TLV list starts after fields included in the struct */ - /* There's just one filed that differes the two start_scan - * structures - burst_duration, which we are not using btw, - no point to make the split here, just shift the buffer to fit with - given FW */ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - off = sizeof(struct wmi_start_scan_cmd_10x); - else - off = sizeof(struct wmi_start_scan_cmd); + cmn->scan_id = __cpu_to_le32(scan_id); + cmn->scan_req_id = __cpu_to_le32(scan_req_id); + cmn->vdev_id = __cpu_to_le32(arg->vdev_id); + cmn->scan_priority = __cpu_to_le32(arg->scan_priority); + cmn->notify_scan_events = __cpu_to_le32(arg->notify_scan_events); + cmn->dwell_time_active = __cpu_to_le32(arg->dwell_time_active); + cmn->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive); + cmn->min_rest_time = __cpu_to_le32(arg->min_rest_time); + cmn->max_rest_time = __cpu_to_le32(arg->max_rest_time); + cmn->repeat_probe_time = __cpu_to_le32(arg->repeat_probe_time); + cmn->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time); + cmn->idle_time = __cpu_to_le32(arg->idle_time); + cmn->max_scan_time = __cpu_to_le32(arg->max_scan_time); + cmn->probe_delay = __cpu_to_le32(arg->probe_delay); + cmn->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); +} + +static void +ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs, + const struct wmi_start_scan_arg *arg) +{ + struct wmi_ie_data *ie; + struct wmi_chan_list *channels; + struct wmi_ssid_list *ssids; + struct wmi_bssid_list *bssids; + void *ptr = tlvs->tlvs; + int i; if (arg->n_channels) { - channels = (void *)skb->data + off; + channels = ptr; channels->tag = __cpu_to_le32(WMI_CHAN_LIST_TAG); channels->num_chan = __cpu_to_le32(arg->n_channels); @@ -3283,12 +3266,12 @@ int ath10k_wmi_start_scan(struct ath10k *ar, channels->channel_list[i].freq = __cpu_to_le16(arg->channels[i]); - off += sizeof(*channels); - off += sizeof(__le32) * arg->n_channels; + ptr += sizeof(*channels); + ptr += sizeof(__le32) * arg->n_channels; } if (arg->n_ssids) { - ssids = (void *)skb->data + off; + ssids = ptr; ssids->tag = __cpu_to_le32(WMI_SSID_LIST_TAG); ssids->num_ssids = __cpu_to_le32(arg->n_ssids); @@ -3300,12 +3283,12 @@ int ath10k_wmi_start_scan(struct ath10k *ar, arg->ssids[i].len); } - off += sizeof(*ssids); - off += sizeof(struct wmi_ssid) * arg->n_ssids; + ptr += sizeof(*ssids); + ptr += sizeof(struct wmi_ssid) * arg->n_ssids; } if (arg->n_bssids) { - bssids = (void *)skb->data + off; + bssids = ptr; bssids->tag = __cpu_to_le32(WMI_BSSID_LIST_TAG); bssids->num_bssid = __cpu_to_le32(arg->n_bssids); @@ -3314,23 +3297,57 @@ int ath10k_wmi_start_scan(struct ath10k *ar, arg->bssids[i].bssid, ETH_ALEN); - off += sizeof(*bssids); - off += sizeof(struct wmi_mac_addr) * arg->n_bssids; + ptr += sizeof(*bssids); + ptr += sizeof(struct wmi_mac_addr) * arg->n_bssids; } if (arg->ie_len) { - ie = (void *)skb->data + off; + ie = ptr; ie->tag = __cpu_to_le32(WMI_IE_TAG); ie->ie_len = __cpu_to_le32(arg->ie_len); memcpy(ie->ie_data, arg->ie, arg->ie_len); - off += sizeof(*ie); - off += roundup(arg->ie_len, 4); + ptr += sizeof(*ie); + ptr += roundup(arg->ie_len, 4); } +} - if (off != skb->len) { - dev_kfree_skb(skb); - return -EINVAL; +int ath10k_wmi_start_scan(struct ath10k *ar, + const struct wmi_start_scan_arg *arg) +{ + struct sk_buff *skb; + size_t len; + int ret; + + ret = ath10k_wmi_start_scan_verify(arg); + if (ret) + return ret; + + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) + len = sizeof(struct wmi_start_scan_cmd) + + ath10k_wmi_start_scan_tlvs_len(arg); + else + len = sizeof(struct wmi_10x_start_scan_cmd) + + ath10k_wmi_start_scan_tlvs_len(arg); + + skb = ath10k_wmi_alloc_skb(ar, len); + if (!skb) + return -ENOMEM; + + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + struct wmi_10x_start_scan_cmd *cmd; + + cmd = (struct wmi_10x_start_scan_cmd *)skb->data; + ath10k_wmi_put_start_scan_common(&cmd->common, arg); + ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); + } else { + struct wmi_start_scan_cmd *cmd; + + cmd = (struct wmi_start_scan_cmd *)skb->data; + cmd->burst_duration_ms = __cpu_to_le32(0); + + ath10k_wmi_put_start_scan_common(&cmd->common, arg); + ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); } ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 0df5eef21318..55d8317ce1a5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -1962,7 +1962,7 @@ enum wmi_scan_priority { WMI_SCAN_PRIORITY_COUNT /* number of priorities supported */ }; -struct wmi_start_scan_cmd { +struct wmi_start_scan_common { /* Scan ID */ __le32 scan_id; /* Scan requestor ID */ @@ -2020,95 +2020,25 @@ struct wmi_start_scan_cmd { __le32 probe_delay; /* Scan control flags */ __le32 scan_ctrl_flags; - - /* Burst duration time in msecs */ - __le32 burst_duration; - /* - * TLV (tag length value ) paramerters follow the scan_cmd structure. - * TLV can contain channel list, bssid list, ssid list and - * ie. the TLV tags are defined above; - */ } __packed; -/* This is the definition from 10.X firmware branch */ -struct wmi_start_scan_cmd_10x { - /* Scan ID */ - __le32 scan_id; - - /* Scan requestor ID */ - __le32 scan_req_id; - - /* VDEV id(interface) that is requesting scan */ - __le32 vdev_id; - - /* Scan Priority, input to scan scheduler */ - __le32 scan_priority; - - /* Scan events subscription */ - __le32 notify_scan_events; - - /* dwell time in msec on active channels */ - __le32 dwell_time_active; - - /* dwell time in msec on passive channels */ - __le32 dwell_time_passive; - - /* - * min time in msec on the BSS channel,only valid if atleast one - * VDEV is active - */ - __le32 min_rest_time; - - /* - * max rest time in msec on the BSS channel,only valid if at least - * one VDEV is active - */ - /* - * the scanner will rest on the bss channel at least min_rest_time - * after min_rest_time the scanner will start checking for tx/rx - * activity on all VDEVs. if there is no activity the scanner will - * switch to off channel. if there is activity the scanner will let - * the radio on the bss channel until max_rest_time expires.at - * max_rest_time scanner will switch to off channel irrespective of - * activity. activity is determined by the idle_time parameter. - */ - __le32 max_rest_time; - - /* - * time before sending next set of probe requests. - * The scanner keeps repeating probe requests transmission with - * period specified by repeat_probe_time. - * The number of probe requests specified depends on the ssid_list - * and bssid_list - */ - __le32 repeat_probe_time; - - /* time in msec between 2 consequetive probe requests with in a set. */ - __le32 probe_spacing_time; - - /* - * data inactivity time in msec on bss channel that will be used by - * scanner for measuring the inactivity. - */ - __le32 idle_time; - - /* maximum time in msec allowed for scan */ - __le32 max_scan_time; - - /* - * delay in msec before sending first probe request after switching - * to a channel +struct wmi_start_scan_tlvs { + /* TLV parameters. These includes channel list, ssid list, bssid list, + * extra ies. */ - __le32 probe_delay; + u8 tlvs[0]; +} __packed; - /* Scan control flags */ - __le32 scan_ctrl_flags; +struct wmi_start_scan_cmd { + struct wmi_start_scan_common common; + __le32 burst_duration_ms; + struct wmi_start_scan_tlvs tlvs; +} __packed; - /* - * TLV (tag length value ) paramerters follow the scan_cmd structure. - * TLV can contain channel list, bssid list, ssid list and - * ie. the TLV tags are defined above; - */ +/* This is the definition from 10.X firmware branch */ +struct wmi_10x_start_scan_cmd { + struct wmi_start_scan_common common; + struct wmi_start_scan_tlvs tlvs; } __packed; struct wmi_ssid_arg { -- GitLab From ba80f4d4266b2c804a2dd6deec6e2df32cb033ce Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 16 Sep 2014 19:19:05 -0400 Subject: [PATCH 0086/9457] drm/i915: PSR: organize setup function. psr_enabled is already by itself a setup once so let's put the W/As there and rename old setup once to setup_vsc. Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 59754451ae50..e0066c03e7f1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1991,10 +1991,8 @@ static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp, POSTING_READ(ctl_reg); } -static void intel_edp_psr_setup(struct intel_dp *intel_dp) +static void intel_edp_psr_setup_vsc(struct intel_dp *intel_dp) { - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; struct edp_vsc_psr psr_vsc; /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ @@ -2004,10 +2002,6 @@ static void intel_edp_psr_setup(struct intel_dp *intel_dp) psr_vsc.sdp_header.HB2 = 0x2; psr_vsc.sdp_header.HB3 = 0x8; intel_edp_psr_write_vsc(intel_dp, &psr_vsc); - - /* Avoid continuous PSR exit by masking memup and hpd */ - I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | - EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); } static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) @@ -2160,8 +2154,11 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) dev_priv->psr.busy_frontbuffer_bits = 0; - /* Setup PSR once */ - intel_edp_psr_setup(intel_dp); + intel_edp_psr_setup_vsc(intel_dp); + + /* Avoid continuous PSR exit by masking memup and hpd */ + I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | + EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); if (intel_edp_psr_match_conditions(intel_dp)) dev_priv->psr.enabled = intel_dp; -- GitLab From 0aa48783979d40a1de59eb5b04989e1398400c3c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 16 Sep 2014 19:19:06 -0400 Subject: [PATCH 0087/9457] drm/i915: PSR: Organize PSR enable function We don't need to setup everything else if it doesn't match all conditions. Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e0066c03e7f1..43b381a087f4 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2148,10 +2148,12 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) mutex_lock(&dev_priv->psr.lock); if (dev_priv->psr.enabled) { DRM_DEBUG_KMS("PSR already in use\n"); - mutex_unlock(&dev_priv->psr.lock); - return; + goto unlock; } + if (!intel_edp_psr_match_conditions(intel_dp)) + goto unlock; + dev_priv->psr.busy_frontbuffer_bits = 0; intel_edp_psr_setup_vsc(intel_dp); @@ -2160,8 +2162,8 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); - if (intel_edp_psr_match_conditions(intel_dp)) - dev_priv->psr.enabled = intel_dp; + dev_priv->psr.enabled = intel_dp; +unlock: mutex_unlock(&dev_priv->psr.lock); } -- GitLab From 72bbf0af0c76cbefe9cecbd2ed670b7555e03625 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 13 Feb 2013 15:27:37 +0000 Subject: [PATCH 0088/9457] drm/i915/skl: Add the Skylake PCI ids v2: Squash in 2nd patch from Damien for more ids (Daniel) v3: info->has*ring -> info->ring_mask conversion. Also add VEBOX support. v4: Fold in update from Damien v5: Rebase and add GEN_DEFAULT_PIPEOFFSETS v6: Add more PCI ID (Vandana) v7: Rebase and add IVB_CURSOR_OFFSETS v8: Renamed the macro from _PCI_IDS to _IDS for consistency Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Vandana Kannan Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 14 +++++++++++++- include/drm/i915_pciids.h | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3870c7359a16..bec58e86bd49 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -356,6 +356,17 @@ static const struct intel_device_info intel_cherryview_info = { CURSOR_OFFSETS, }; +static const struct intel_device_info intel_skylake_info = { + .is_preliminary = 1, + .gen = 9, .num_pipes = 3, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .has_llc = 1, + .has_ddi = 1, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, +}; + /* * Make sure any device matches here are from most specific to most * general. For example, since the Quanta match is based on the subsystem @@ -392,7 +403,8 @@ static const struct intel_device_info intel_cherryview_info = { INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), \ INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), \ INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \ - INTEL_CHV_IDS(&intel_cherryview_info) + INTEL_CHV_IDS(&intel_cherryview_info), \ + INTEL_SKL_IDS(&intel_skylake_info) static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_PCI_IDS, diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index a70d45647898..180ad0e6de21 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -259,4 +259,21 @@ INTEL_VGA_DEVICE(0x22b2, info), \ INTEL_VGA_DEVICE(0x22b3, info) +#define INTEL_SKL_IDS(info) \ + INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ + INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ + INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \ + INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ + INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \ + INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \ + INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ + INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \ + INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ + INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ + INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \ + INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \ + INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \ + INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ + #endif /* _I915_PCIIDS_H */ -- GitLab From b71252dc48697157e114fc12801f89398018b9ef Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 13 Feb 2013 15:27:24 +0000 Subject: [PATCH 0089/9457] drm/i915/skl: Add an IS_GEN9() define Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 19c0dd8e255e..7892428d2844 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2123,6 +2123,7 @@ struct drm_i915_cmd_table { #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) #define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7) #define IS_GEN8(dev) (INTEL_INFO(dev)->gen == 8) +#define IS_GEN9(dev) (INTEL_INFO(dev)->gen == 9) #define RENDER_RING (1< Date: Wed, 2 Apr 2014 11:24:50 +0530 Subject: [PATCH 0090/9457] drm/i915/skl: Add an IS_SKYLAKE macro Adding new macro IS_SKYLAKE for skylake specific implementation. Reviewed-by: Thomas Wood Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bec58e86bd49..a1ba1557154c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -358,6 +358,7 @@ static const struct intel_device_info intel_cherryview_info = { static const struct intel_device_info intel_skylake_info = { .is_preliminary = 1, + .is_skylake = 1, .gen = 9, .num_pipes = 3, .need_gfx_hws = 1, .has_hotplug = 1, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7892428d2844..2c652e8f5726 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -551,6 +551,7 @@ struct intel_uncore { func(is_ivybridge) sep \ func(is_valleyview) sep \ func(is_haswell) sep \ + func(is_skylake) sep \ func(is_preliminary) sep \ func(has_fbc) sep \ func(has_pipe_cxsr) sep \ @@ -2093,6 +2094,7 @@ struct drm_i915_cmd_table { #define IS_CHERRYVIEW(dev) (INTEL_INFO(dev)->is_valleyview && IS_GEN8(dev)) #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) #define IS_BROADWELL(dev) (!INTEL_INFO(dev)->is_valleyview && IS_GEN8(dev)) +#define IS_SKYLAKE(dev) (INTEL_INFO(dev)->is_skylake) #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) -- GitLab From 043efb1111694981c99613b8f944d6eabfb93273 Mon Sep 17 00:00:00 2001 From: Daisy Sun Date: Wed, 23 Apr 2014 17:13:09 -0700 Subject: [PATCH 0091/9457] drm/i915/skl: SKL FBC enablement Enable FBC feature on Skylake Issue: VIZ-3788 Reviewed-by: Thomas Wood Signed-off-by: Daisy Sun Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a1ba1557154c..7088bdea11c7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -364,6 +364,7 @@ static const struct intel_device_info intel_skylake_info = { .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, .has_llc = 1, .has_ddi = 1, + .has_fbc = 1, GEN_DEFAULT_PIPEOFFSETS, IVB_CURSOR_OFFSETS, }; -- GitLab From 01209dd56edf77b02290bf1db7ac0bed32381235 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 13 Feb 2013 15:27:25 +0000 Subject: [PATCH 0092/9457] drm/i915/skl: Fence registers on SKL are the same as SNB v2: Rebased on top of the i915_gpu_error.c extraction. Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_gpu_error.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4ca3a6dcf10b..2a38ef27bfcd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3151,6 +3151,7 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg, obj->stride, obj->tiling_mode); switch (INTEL_INFO(dev)->gen) { + case 9: case 8: case 7: case 6: diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2c87a797213f..68fd7675184f 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -765,6 +765,7 @@ static void i915_gem_record_fences(struct drm_device *dev, /* Fences */ switch (INTEL_INFO(dev)->gen) { + case 9: case 8: case 7: case 6: -- GitLab From da2078cd001e958409b6cef248679ff1772a3ad9 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 13 Feb 2013 15:27:27 +0000 Subject: [PATCH 0093/9457] drm/i915/skl: Provide a placeholder for init_clock_gating() v2: Rebase on top of the broadwell_init_clock_gating() name change Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 45f71e6dc544..d760e0659fa4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -66,6 +66,10 @@ * i915.i915_enable_fbc parameter */ +static void gen9_init_clock_gating(struct drm_device *dev) +{ +} + static void i8xx_disable_fbc(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -7397,6 +7401,8 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.init_clock_gating = haswell_init_clock_gating; else if (INTEL_INFO(dev)->gen == 8) dev_priv->display.init_clock_gating = broadwell_init_clock_gating; + else if (INTEL_INFO(dev)->gen == 9) + dev_priv->display.init_clock_gating = gen9_init_clock_gating; } else if (IS_CHERRYVIEW(dev)) { dev_priv->display.update_wm = cherryview_update_wm; dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; -- GitLab From 8a8b009d133714c0856ee08f7c68b908103e8383 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 8 Apr 2013 15:42:02 +0200 Subject: [PATCH 0094/9457] drm/i915/skl: Skylake shares the interrupt logic with Broadwell Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c96ddc953531..1d2849efd778 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4713,7 +4713,7 @@ void intel_irq_init(struct drm_device *dev) dev->driver->enable_vblank = valleyview_enable_vblank; dev->driver->disable_vblank = valleyview_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; - } else if (IS_GEN8(dev)) { + } else if (INTEL_INFO(dev)->gen >= 8) { dev->driver->irq_handler = gen8_irq_handler; dev->driver->irq_preinstall = gen8_irq_reset; dev->driver->irq_postinstall = gen8_irq_postinstall; -- GitLab From fbdcb06880bf414afafd4053d0d9906725f8b117 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 13 Feb 2013 15:27:34 +0000 Subject: [PATCH 0095/9457] drm/i915/skl: don't set the AsyncFlip performance mode for Gen9+ The following sets the AsyncFlip performance mode for everything above Gen6: commit 4790cb36b3eede8fb0cca529dc1d31b9936fa24b Author: Chris Wilson Date: Sun Jan 20 16:11:20 2013 +0000 drm/i915: Disable AsyncFlip performance optimisations Starting from Gen9 the MI_MODE register layout changes and doesn't include the above bit. Reviewed-by: Thomas Wood Signed-off-by: Imre Deak Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 109de2eeb9a8..a6a64aee8f74 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -823,7 +823,7 @@ static int init_render_ring(struct intel_engine_cs *ring) * * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv */ - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6 && INTEL_INFO(dev)->gen < 9) I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); /* Required for the hardware to program scanline values for waiting */ -- GitLab From 1fada4cc6a49fa8fb4530bba8fb0cfb42708fc6a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 3 Jul 2013 21:06:02 +0100 Subject: [PATCH 0096/9457] drm/i915/skl: Framebuffers need to be aligned to 256KB on Skylake v2: Also align X tiled fbs to 256KB (Thomas) Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1386086ec245..dc264de4e39e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2199,7 +2199,9 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, switch (obj->tiling_mode) { case I915_TILING_NONE: - if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + if (INTEL_INFO(dev)->gen >= 9) + alignment = 256 * 1024; + else if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) alignment = 128 * 1024; else if (INTEL_INFO(dev)->gen >= 4) alignment = 4 * 1024; @@ -2207,8 +2209,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, alignment = 64 * 1024; break; case I915_TILING_X: - /* pin() will align the object as required by fence */ - alignment = 0; + if (INTEL_INFO(dev)->gen >= 9) + alignment = 256 * 1024; + else { + /* pin() will align the object as required by fence */ + alignment = 0; + } break; case I915_TILING_Y: WARN(1, "Y tiled bo slipped through, driver bug!\n"); -- GitLab From 5907f5fb6a16ae70cde25bcf4be201a93dfa0b9c Mon Sep 17 00:00:00 2001 From: Robert Beckett Date: Thu, 23 Jan 2014 14:23:14 +0000 Subject: [PATCH 0097/9457] drm/i915/skl: i915_swizzle_info gen9 fix Fix ARB_MODE register read for gen >= 8 in i915_swizzle_info Reviewed-by: Thomas Wood Signed-off-by: Robert Beckett Signed-off-by: Damien Lespiau --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2cbc85f3b237..707eddd1825f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1986,7 +1986,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data) I915_READ(MAD_DIMM_C2)); seq_printf(m, "TILECTL = 0x%08x\n", I915_READ(TILECTL)); - if (IS_GEN8(dev)) + if (INTEL_INFO(dev)->gen >= 8) seq_printf(m, "GAMTARBMODE = 0x%08x\n", I915_READ(GAMTARBMODE)); else -- GitLab From 70d21f0e914415c39bfdffdcaebb6bc8fb6ce79c Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 3 Jul 2013 21:06:04 +0100 Subject: [PATCH 0098/9457] drm/i915/skl: Implement the new update_plane() for primary planes Skylake makes primary planes the same as sprite planes and call the result "universal planes". This commit emulates a primary plane with plane 0, taking the opportunity to redefine primary and sprite registers to be identical now that the underlying hardware is. It also makes sense as plenty of fields have changed. v2: Rebase on top of the vma code. v3: Follow upstream evolution: - Drop return values. - Remove pipe checks since redudant and BUG instead. - Remove tiling checks and BUG instead. - Drop commented out DISP_MODIFY usage. v4: s/plane/primary_plane/ v5: Misc fixes: - Fix the fields we need to clear up - Disable trickle feed - Correctly use PLANE_OFFSET for the panning v6: (Jesse) Use pipe src size when programming plane size. This makes cloned configs work correctly w/o the use of a panel fitter. v7: Rebase on top of Ville's rmw elimination series v8: Remove clearing the trickle feed bit now that we don't do a RMW (Rodrigo, Damien) Add a comment about the stride unit (Rodrigo) Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau (v1,5,6,7) Signed-off-by: Daniel Vetter (v2,3) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 110 ++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_display.c | 92 +++++++++++++++++++++- 2 files changed, 199 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b65bdfc23ccb..1eaa3411cdb1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -26,8 +26,8 @@ #define _I915_REG_H_ #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) +#define _PLANE(plane, a, b) _PIPE(plane, a, b) #define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a))) - #define _PORT(port, a, b) ((a) + (port)*((b)-(a))) #define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \ (pipe) == PIPE_B ? (b) : (c)) @@ -4499,6 +4499,114 @@ enum punit_power_well { #define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA) #define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC) +/* Skylake plane registers */ + +#define _PLANE_CTL_1_A 0x70180 +#define _PLANE_CTL_2_A 0x70280 +#define _PLANE_CTL_3_A 0x70380 +#define PLANE_CTL_ENABLE (1 << 31) +#define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) +#define PLANE_CTL_FORMAT_MASK (0xf << 24) +#define PLANE_CTL_FORMAT_YUV422 ( 0 << 24) +#define PLANE_CTL_FORMAT_NV12 ( 1 << 24) +#define PLANE_CTL_FORMAT_XRGB_2101010 ( 2 << 24) +#define PLANE_CTL_FORMAT_XRGB_8888 ( 4 << 24) +#define PLANE_CTL_FORMAT_XRGB_16161616F ( 6 << 24) +#define PLANE_CTL_FORMAT_AYUV ( 8 << 24) +#define PLANE_CTL_FORMAT_INDEXED ( 12 << 24) +#define PLANE_CTL_FORMAT_RGB_565 ( 14 << 24) +#define PLANE_CTL_PIPE_CSC_ENABLE (1 << 23) +#define PLANE_CTL_KEY_ENABLE (1 << 22) +#define PLANE_CTL_ORDER_BGRX (0 << 20) +#define PLANE_CTL_ORDER_RGBX (1 << 20) +#define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) +#define PLANE_CTL_YUV422_YUYV ( 0 << 16) +#define PLANE_CTL_YUV422_UYVY ( 1 << 16) +#define PLANE_CTL_YUV422_YVYU ( 2 << 16) +#define PLANE_CTL_YUV422_VYUY ( 3 << 16) +#define PLANE_CTL_DECOMPRESSION_ENABLE (1 << 15) +#define PLANE_CTL_TRICKLE_FEED_DISABLE (1 << 14) +#define PLANE_CTL_PLANE_GAMMA_DISABLE (1 << 13) +#define PLANE_CTL_TILED_MASK (0x7 << 10) +#define PLANE_CTL_TILED_LINEAR ( 0 << 10) +#define PLANE_CTL_TILED_X ( 1 << 10) +#define PLANE_CTL_TILED_Y ( 4 << 10) +#define PLANE_CTL_TILED_YF ( 5 << 10) +#define PLANE_CTL_ALPHA_MASK (0x3 << 4) +#define PLANE_CTL_ALPHA_DISABLE ( 0 << 4) +#define PLANE_CTL_ALPHA_SW_PREMULTIPLY ( 2 << 4) +#define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) +#define _PLANE_STRIDE_1_A 0x70188 +#define _PLANE_STRIDE_2_A 0x70288 +#define _PLANE_STRIDE_3_A 0x70388 +#define _PLANE_POS_1_A 0x7018c +#define _PLANE_POS_2_A 0x7028c +#define _PLANE_POS_3_A 0x7038c +#define _PLANE_SIZE_1_A 0x70190 +#define _PLANE_SIZE_2_A 0x70290 +#define _PLANE_SIZE_3_A 0x70390 +#define _PLANE_SURF_1_A 0x7019c +#define _PLANE_SURF_2_A 0x7029c +#define _PLANE_SURF_3_A 0x7039c +#define _PLANE_OFFSET_1_A 0x701a4 +#define _PLANE_OFFSET_2_A 0x702a4 +#define _PLANE_OFFSET_3_A 0x703a4 + +#define _PLANE_CTL_1_B 0x71180 +#define _PLANE_CTL_2_B 0x71280 +#define _PLANE_CTL_3_B 0x71380 +#define _PLANE_CTL_1(pipe) _PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B) +#define _PLANE_CTL_2(pipe) _PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B) +#define _PLANE_CTL_3(pipe) _PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B) +#define PLANE_CTL(pipe, plane) \ + _PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe)) + +#define _PLANE_STRIDE_1_B 0x71188 +#define _PLANE_STRIDE_2_B 0x71288 +#define _PLANE_STRIDE_3_B 0x71388 +#define _PLANE_STRIDE_1(pipe) \ + _PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B) +#define _PLANE_STRIDE_2(pipe) \ + _PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B) +#define _PLANE_STRIDE_3(pipe) \ + _PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B) +#define PLANE_STRIDE(pipe, plane) \ + _PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe)) + +#define _PLANE_POS_1_B 0x7118c +#define _PLANE_POS_2_B 0x7128c +#define _PLANE_POS_3_B 0x7138c +#define _PLANE_POS_1(pipe) _PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B) +#define _PLANE_POS_2(pipe) _PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B) +#define _PLANE_POS_3(pipe) _PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B) +#define PLANE_POS(pipe, plane) \ + _PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe)) + +#define _PLANE_SIZE_1_B 0x71190 +#define _PLANE_SIZE_2_B 0x71290 +#define _PLANE_SIZE_3_B 0x71390 +#define _PLANE_SIZE_1(pipe) _PIPE(pipe, _PLANE_SIZE_1_A, _PLANE_SIZE_1_B) +#define _PLANE_SIZE_2(pipe) _PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B) +#define _PLANE_SIZE_3(pipe) _PIPE(pipe, _PLANE_SIZE_3_A, _PLANE_SIZE_3_B) +#define PLANE_SIZE(pipe, plane) \ + _PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe)) + +#define _PLANE_SURF_1_B 0x7119c +#define _PLANE_SURF_2_B 0x7129c +#define _PLANE_SURF_3_B 0x7139c +#define _PLANE_SURF_1(pipe) _PIPE(pipe, _PLANE_SURF_1_A, _PLANE_SURF_1_B) +#define _PLANE_SURF_2(pipe) _PIPE(pipe, _PLANE_SURF_2_A, _PLANE_SURF_2_B) +#define _PLANE_SURF_3(pipe) _PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B) +#define PLANE_SURF(pipe, plane) \ + _PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe)) + +#define _PLANE_OFFSET_1_B 0x711a4 +#define _PLANE_OFFSET_2_B 0x712a4 +#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B) +#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B) +#define PLANE_OFFSET(pipe, plane) \ + _PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe)) + /* VBIOS regs */ #define VGACNTRL 0x71400 # define VGA_DISP_DISABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dc264de4e39e..65f4ff668208 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2644,6 +2644,90 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, POSTING_READ(reg); } +static void skylake_update_primary_plane(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_framebuffer *intel_fb; + struct drm_i915_gem_object *obj; + int pipe = intel_crtc->pipe; + u32 plane_ctl, stride; + + if (!intel_crtc->primary_enabled) { + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); + POSTING_READ(PLANE_CTL(pipe, 0)); + return; + } + + plane_ctl = PLANE_CTL_ENABLE | + PLANE_CTL_PIPE_GAMMA_ENABLE | + PLANE_CTL_PIPE_CSC_ENABLE; + + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + plane_ctl |= PLANE_CTL_FORMAT_RGB_565; + break; + case DRM_FORMAT_XRGB8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; + break; + case DRM_FORMAT_XBGR8888: + plane_ctl |= PLANE_CTL_ORDER_RGBX; + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; + break; + case DRM_FORMAT_XRGB2101010: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010; + break; + case DRM_FORMAT_XBGR2101010: + plane_ctl |= PLANE_CTL_ORDER_RGBX; + plane_ctl |= PLANE_CTL_FORMAT_XRGB_2101010; + break; + default: + BUG(); + } + + intel_fb = to_intel_framebuffer(fb); + obj = intel_fb->obj; + + /* + * The stride is either expressed as a multiple of 64 bytes chunks for + * linear buffers or in number of tiles for tiled buffers. + */ + switch (obj->tiling_mode) { + case I915_TILING_NONE: + stride = fb->pitches[0] >> 6; + break; + case I915_TILING_X: + plane_ctl |= PLANE_CTL_TILED_X; + stride = fb->pitches[0] >> 9; + break; + default: + BUG(); + } + + plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; + + I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); + + DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n", + i915_gem_obj_ggtt_offset(obj), + x, y, fb->width, fb->height, + fb->pitches[0]); + + I915_WRITE(PLANE_POS(pipe, 0), 0); + I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x); + I915_WRITE(PLANE_SIZE(pipe, 0), + (intel_crtc->config.pipe_src_h - 1) << 16 | + (intel_crtc->config.pipe_src_w - 1)); + I915_WRITE(PLANE_STRIDE(pipe, 0), stride); + I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj)); + + POSTING_READ(PLANE_SURF(pipe, 0)); +} + /* Assume fb object is pinned & idle & fenced and just update base pointers */ static int intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -12581,8 +12665,12 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; dev_priv->display.off = ironlake_crtc_off; - dev_priv->display.update_primary_plane = - ironlake_update_primary_plane; + if (INTEL_INFO(dev)->gen >= 9) + dev_priv->display.update_primary_plane = + skylake_update_primary_plane; + else + dev_priv->display.update_primary_plane = + ironlake_update_primary_plane; } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.get_plane_config = ironlake_get_plane_config; -- GitLab From 884497edd9e982eaf5c7e1216029625cec3c5f5e Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 3 Dec 2013 13:56:23 +0000 Subject: [PATCH 0099/9457] drm/i915/skl: Don't create a VGA connector on Skylake v2: Rebase on top of the intel_crt_present() addition v3: Fix rebase error (we were patching the wrong function) Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 65f4ff668208..3c3656cd797d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12322,6 +12322,9 @@ static bool intel_crt_present(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + if (INTEL_INFO(dev)->gen >= 9) + return false; + if (IS_ULT(dev)) return false; -- GitLab From ca3704555c1360b98c645a0c5f882a3011a225f0 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 3 Dec 2013 13:56:24 +0000 Subject: [PATCH 0100/9457] drm/i915/skl: Don't try to read out the PCH transcoder state if not present When the platform doesn't have a FDI link, don't try to read out the state of a potential PCH transcoder. Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau [danvet: Don't open-code HAS_FDI if there's only one place that needs it. Acked by Damien on irc.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3c3656cd797d..40f73fc4ce65 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7867,7 +7867,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, * DDI E. So just check whether this pipe is wired to DDI E and whether * the PCH transcoder is on. */ - if ((port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { + if (INTEL_INFO(dev)->gen < 9 && + (port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { pipe_config->has_pch_encoder = true; tmp = I915_READ(FDI_RX_CTL(PIPE_A)); -- GitLab From 7f88e3af2047c008d5bef5632854c883c7d577fb Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 3 Dec 2013 13:56:25 +0000 Subject: [PATCH 0101/9457] drm/i915/skl: Program the DDI buffer translation tables A couple of things have changed compared to Broadwell: - Entry 9 is used for eDP - No more FDI v2: Update the translation values to latest specs. v3: Rebase on top of the BDW HDMI translation patch v4: Remove the low voltage edp tables, Rebase on top of the patch not writing the HDMI entry on eDP/FDI DDIs (Satheesh, Paulo). v5: Apply the / 2 fix for the number of HDMI entries (Satheesh) v6: Rebase on top of Jani's clean up for the DDI_BUF_TRANS tables v7: Restore the commit message that was mangled by error Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b63d4fa204a3..ba1103f23e2f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -127,6 +127,32 @@ static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = { { 0x80FFFFFF, 0x001B0002 }, /* 9: 1000 1000 0 */ }; +static const struct ddi_buf_trans skl_ddi_translations_dp[] = { + { 0x00000018, 0x000000a0 }, + { 0x00004014, 0x00000098 }, + { 0x00006012, 0x00000088 }, + { 0x00008010, 0x00000080 }, + { 0x00000018, 0x00000098 }, + { 0x00004014, 0x00000088 }, + { 0x00006012, 0x00000080 }, + { 0x00000018, 0x00000088 }, + { 0x00004014, 0x00000080 }, +}; + +static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { + /* Idx NT mV T mV db */ + { 0x00000018, 0x000000a0 }, /* 0: 400 400 0 */ + { 0x00004014, 0x00000098 }, /* 1: 400 600 3.5 */ + { 0x00006012, 0x00000088 }, /* 2: 400 800 6 */ + { 0x00000018, 0x0000003c }, /* 3: 450 450 0 */ + { 0x00000018, 0x00000098 }, /* 4: 600 600 0 */ + { 0x00003015, 0x00000088 }, /* 5: 600 800 2.5 */ + { 0x00005013, 0x00000080 }, /* 6: 600 1000 4.5 */ + { 0x00000018, 0x00000088 }, /* 7: 800 800 0 */ + { 0x00000096, 0x00000080 }, /* 8: 800 1000 2 */ + { 0x00000018, 0x00000080 }, /* 9: 1200 1200 0 */ +}; + enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; @@ -169,7 +195,14 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) const struct ddi_buf_trans *ddi_translations_hdmi; const struct ddi_buf_trans *ddi_translations; - if (IS_BROADWELL(dev)) { + if (IS_SKYLAKE(dev)) { + ddi_translations_fdi = NULL; + ddi_translations_dp = skl_ddi_translations_dp; + ddi_translations_edp = skl_ddi_translations_dp; + ddi_translations_hdmi = skl_ddi_translations_hdmi; + n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); + hdmi_800mV_0dB = 7; + } else if (IS_BROADWELL(dev)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_edp = bdw_ddi_translations_edp; @@ -208,7 +241,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) ddi_translations = ddi_translations_dp; break; case PORT_E: - ddi_translations = ddi_translations_fdi; + if (ddi_translations_fdi) + ddi_translations = ddi_translations_fdi; + else + ddi_translations = ddi_translations_dp; break; default: BUG(); -- GitLab From 5a9d1f1a8f62108828641c9224eb5d080db598c5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 3 Dec 2013 13:56:26 +0000 Subject: [PATCH 0102/9457] drm/i915/skl: Add support for DP voltage swings and pre-emphasis They are similar to Haswell. v2: Rebased on top of drm-intel-nightly v3: Rebased on top of Sonika's DP train defines renaming Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2a26774ddb68..581ba1dd0fba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2840,7 +2840,9 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); enum port port = dp_to_dig_port(intel_dp)->port; - if (IS_VALLEYVIEW(dev)) + if (INTEL_INFO(dev)->gen >= 9) + return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; + else if (IS_VALLEYVIEW(dev)) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; else if (IS_GEN7(dev) && port == PORT_A) return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; @@ -2856,7 +2858,18 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) struct drm_device *dev = intel_dp_to_dev(intel_dp); enum port port = dp_to_dig_port(intel_dp)->port; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + if (INTEL_INFO(dev)->gen >= 9) { + switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { + case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: + return DP_TRAIN_PRE_EMPH_LEVEL_3; + case DP_TRAIN_VOLTAGE_SWING_LEVEL_1: + return DP_TRAIN_PRE_EMPH_LEVEL_2; + case DP_TRAIN_VOLTAGE_SWING_LEVEL_2: + return DP_TRAIN_PRE_EMPH_LEVEL_1; + default: + return DP_TRAIN_PRE_EMPH_LEVEL_0; + } + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { case DP_TRAIN_VOLTAGE_SWING_LEVEL_0: return DP_TRAIN_PRE_EMPH_LEVEL_3; @@ -3338,7 +3351,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) uint32_t signal_levels, mask; uint8_t train_set = intel_dp->train_set[0]; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + if (IS_HASWELL(dev) || IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) { signal_levels = intel_hsw_signal_levels(train_set); mask = DDI_BUF_EMP_MASK; } else if (IS_CHERRYVIEW(dev)) { -- GitLab From 1b1aad754cb26fd073b82eb860126cb812157ae9 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 3 Dec 2013 13:56:29 +0000 Subject: [PATCH 0103/9457] drm/i915/skl: Skylake moves AUX_CTL from PCH to CPU So we can apply the old aux_ctl = dp_ctl + 0x10 rule again. Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 581ba1dd0fba..17c69101d086 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -925,7 +925,16 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) BUG(); } - if (!HAS_DDI(dev)) + /* + * The AUX_CTL register is usually DP_CTL + 0x10. + * + * On Haswell and Broadwell though: + * - Both port A DDI_BUF_CTL and DDI_AUX_CTL are on the CPU + * - Port B/C/D AUX channels are on the PCH, DDI_BUF_CTL on the CPU + * + * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU. + */ + if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10; intel_dp->aux.name = name; -- GitLab From 663750141ed953c42b6b0e3cfb2450453bc38151 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 9 Jan 2014 18:02:46 +0000 Subject: [PATCH 0104/9457] drm/i915/skl: Add the additional graphics stolen sizes Skylake introduces new stolen memory sizes starting at 0xf0 (4MB) and growing by 4MB increments from there. v2: Rebase on top of the early-quirk changes from Ville. v3: Rebase on top of the PCI_IDS/IDS macro rename Reviewed-by: Thomas Wood Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- arch/x86/kernel/early-quirks.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 2e1a6853e00c..fe9f0b79a18b 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -455,6 +455,23 @@ struct intel_stolen_funcs { u32 (*base)(int num, int slot, int func, size_t size); }; +static size_t __init gen9_stolen_size(int num, int slot, int func) +{ + u16 gmch_ctrl; + + gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL); + gmch_ctrl >>= BDW_GMCH_GMS_SHIFT; + gmch_ctrl &= BDW_GMCH_GMS_MASK; + + if (gmch_ctrl < 0xf0) + return gmch_ctrl << 25; /* 32 MB units */ + else + /* 4MB increments starting at 0xf0 for 4MB */ + return (gmch_ctrl - 0xf0 + 1) << 22; +} + +typedef size_t (*stolen_size_fn)(int num, int slot, int func); + static const struct intel_stolen_funcs i830_stolen_funcs __initconst = { .base = i830_stolen_base, .size = i830_stolen_size, @@ -490,6 +507,11 @@ static const struct intel_stolen_funcs gen8_stolen_funcs __initconst = { .size = gen8_stolen_size, }; +static const struct intel_stolen_funcs gen9_stolen_funcs __initconst = { + .base = intel_stolen_base, + .size = gen9_stolen_size, +}; + static const struct intel_stolen_funcs chv_stolen_funcs __initconst = { .base = intel_stolen_base, .size = chv_stolen_size, @@ -523,6 +545,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = { INTEL_BDW_M_IDS(&gen8_stolen_funcs), INTEL_BDW_D_IDS(&gen8_stolen_funcs), INTEL_CHV_IDS(&chv_stolen_funcs), + INTEL_SKL_IDS(&gen9_stolen_funcs), }; static void __init intel_graphics_stolen(int num, int slot, int func) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6f410cfb0510..d78695de8101 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1847,6 +1847,18 @@ static size_t chv_get_stolen_size(u16 gmch_ctrl) return (gmch_ctrl - 0x17 + 9) << 22; } +static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl) +{ + gen9_gmch_ctl >>= BDW_GMCH_GMS_SHIFT; + gen9_gmch_ctl &= BDW_GMCH_GMS_MASK; + + if (gen9_gmch_ctl < 0xf0) + return gen9_gmch_ctl << 25; /* 32 MB units */ + else + /* 4MB increments starting at 0xf0 for 4MB */ + return (gen9_gmch_ctl - 0xf0 + 1) << 22; +} + static int ggtt_probe_common(struct drm_device *dev, size_t gtt_size) { @@ -1943,7 +1955,10 @@ static int gen8_gmch_probe(struct drm_device *dev, pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); - if (IS_CHERRYVIEW(dev)) { + if (INTEL_INFO(dev)->gen >= 9) { + *stolen = gen9_get_stolen_size(snb_gmch_ctl); + gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); + } else if (IS_CHERRYVIEW(dev)) { *stolen = chv_get_stolen_size(snb_gmch_ctl); gtt_size = chv_get_total_gtt_size(snb_gmch_ctl); } else { -- GitLab From fb8aad4becbfdf913d09a41e7240ef1f58420f76 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 16 Jan 2014 16:42:32 +0000 Subject: [PATCH 0105/9457] drm/i915/skl: gen9 uses the same bind_vma() vfuncs as gen6+ Temporary plug a BUG() while waiting for a better solution. See: http://lists.freedesktop.org/archives/intel-gfx/2014-January/038132.html However Chris was looking at cleaning-up this as well, so went for the easy intermediate solution instead. Reviewed-by: Ben Widawsky Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d78695de8101..688dd00ecbd2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2130,6 +2130,7 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, vma->obj = obj; switch (INTEL_INFO(vm->dev)->gen) { + case 9: case 8: case 7: case 6: -- GitLab From b6b5e38323b276cae53cf34970d968084de701bc Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 20 Jan 2014 16:00:59 +0000 Subject: [PATCH 0106/9457] drm/i915/skl: Implement the get_aux_clock_divider() DP vfunc We need to provide a vfunc that will make the code in intel_dp_aux_ch() loop once to start the AUX transaction. The return value (clock divider) is unused on SKL, so just return 1. Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 17c69101d086..4d2f704ec0a1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -661,6 +661,16 @@ static uint32_t vlv_get_aux_clock_divider(struct intel_dp *intel_dp, int index) return index ? 0 : 100; } +static uint32_t skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) +{ + /* + * SKL doesn't need us to program the AUX clock divider (Hardware will + * derive the clock from CDCLK automatically). We still implement the + * get_aux_clock_divider vfunc to plug-in into the existing code. + */ + return index ? 0 : 1; +} + static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp, bool has_aux_irq, int send_bytes, @@ -5083,7 +5093,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, intel_dp->pps_pipe = INVALID_PIPE; /* intel_dp vfuncs */ - if (IS_VALLEYVIEW(dev)) + if (INTEL_INFO(dev)->gen >= 9) + intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider; + else if (IS_VALLEYVIEW(dev)) intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider; else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider; -- GitLab From b9ca5fadb3842a7a90934f3ef1795e95b382def1 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 20 Jan 2014 16:01:00 +0000 Subject: [PATCH 0107/9457] drm/i915/skl: Provide a get_aux_send_ctl() vfunc for skylake Skylake doesn't use the pre-charge field now, but, instead, we need to specify the total number of SYNC pulses for the SYNC phase (pre-charge + SYNC pattern pules). Let's use the default value (32) for that. v3: increase DP AUX TX timeout as 400us is not to be used on SKL apparently (Jesse). Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_dp.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1eaa3411cdb1..d4af99ee3e0a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3634,6 +3634,7 @@ enum punit_power_well { #define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) #define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) #define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 +#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) /* * Computing GMCH M and N values for the Display Port link diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4d2f704ec0a1..2e9a6ab1e36d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -701,6 +701,21 @@ static uint32_t i9xx_get_aux_send_ctl(struct intel_dp *intel_dp, (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT); } +static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp, + bool has_aux_irq, + int send_bytes, + uint32_t unused) +{ + return DP_AUX_CH_CTL_SEND_BUSY | + DP_AUX_CH_CTL_DONE | + (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | + DP_AUX_CH_CTL_TIME_OUT_ERROR | + DP_AUX_CH_CTL_TIME_OUT_1600us | + DP_AUX_CH_CTL_RECEIVE_ERROR | + (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | + DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); +} + static int intel_dp_aux_ch(struct intel_dp *intel_dp, uint8_t *send, int send_bytes, @@ -5104,7 +5119,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, else intel_dp->get_aux_clock_divider = i9xx_get_aux_clock_divider; - intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl; + if (INTEL_INFO(dev)->gen >= 9) + intel_dp->get_aux_send_ctl = skl_get_aux_send_ctl; + else + intel_dp->get_aux_send_ctl = i9xx_get_aux_send_ctl; /* Preserve the current hw state. */ intel_dp->DP = I915_READ(intel_dp->output_reg); -- GitLab From 3fdcf80f75814fe2f28db43771b50f9aa70d43b6 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 23 Jan 2014 13:59:49 +0000 Subject: [PATCH 0108/9457] drm/i915/skl: Initialize PPGTT like gen8 gen9 uses very similar memory management to what gen8 has. Just follow the flow. v2: Fix trivial conflict (Damien) Reviewed-by: Rodrigo Vivi Reviewed-by: Ben Widawsky Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 688dd00ecbd2..66e4b2ba345a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1092,7 +1092,7 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) if (INTEL_INFO(dev)->gen < 8) return gen6_ppgtt_init(ppgtt); - else if (IS_GEN8(dev)) + else if (IS_GEN8(dev) || IS_GEN9(dev)) return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); else BUG(); -- GitLab From c3f59a67ad6ff5ac11fefc0c0d9d0f12ff7eb226 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sun, 30 Mar 2014 16:28:23 +0100 Subject: [PATCH 0109/9457] drm/i915/skl: Allow the reg_read ioctl to return RCS_TIMESTAMP Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 918b76163965..3b27fb028762 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -968,7 +968,7 @@ static const struct register_whitelist { /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ uint32_t gen_bitmask; } whitelist[] = { - { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) }, + { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 9) }, }; int i915_reg_read_ioctl(struct drm_device *dev, -- GitLab From 2fcdcd8a2eaa70d110fb27bd297ef4aea3b291fa Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 3 Apr 2014 16:13:29 +0100 Subject: [PATCH 0110/9457] drm/i915/skl: report the same INSTDONE registers as gen8 Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 68fd7675184f..1bf6e6938ac6 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1390,6 +1390,7 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone) WARN_ONCE(1, "Unsupported platform\n"); case 7: case 8: + case 9: instdone[0] = I915_READ(GEN7_INSTDONE_1); instdone[1] = I915_READ(GEN7_SC_INSTDONE); instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); -- GitLab From 2a9b7539667bb347502d7c7e00cae30479c164fb Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 3 Apr 2014 16:17:51 +0100 Subject: [PATCH 0111/9457] drm/i915/skl: Report the PDP regs as in gen8 Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 1bf6e6938ac6..fe1498099f16 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -924,6 +924,7 @@ static void i915_record_ring_state(struct drm_device *dev, ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring)); switch (INTEL_INFO(dev)->gen) { + case 9: case 8: for (i = 0; i < 4; i++) { ering->vm_info.pdp[i] = -- GitLab From a440ca6f2859bc64525dfbb437f031f43163d5ae Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 4 Jun 2014 19:25:23 +0100 Subject: [PATCH 0112/9457] drm/i915/skl: SKL shares the same underrun interrupt as BDW Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1d2849efd778..a8e0bc44c1bd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -503,7 +503,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, ironlake_set_fifo_underrun_reporting(dev, pipe, enable); else if (IS_GEN7(dev)) ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (IS_GEN8(dev)) + else if (IS_GEN8(dev) || IS_GEN9(dev)) broadwell_set_fifo_underrun_reporting(dev, pipe, enable); return old; -- GitLab From 3cdf122ccfd150e022247c2709c0737b9fb235f1 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Tue, 8 Apr 2014 15:46:53 +0530 Subject: [PATCH 0113/9457] drm/i915/skl: SKL pipe misc programming Pipe misc programming in gen9 is similar to BDW. Extending the BDW implementation to gen 9. Reviewed-by: Rodrigo Vivi Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 40f73fc4ce65..901c035514ac 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7064,7 +7064,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); - if (IS_BROADWELL(dev)) { + if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) { val = 0; switch (intel_crtc->config.pipe_bpp) { -- GitLab From 02c292596af4785091a851df441f3c6c27099a29 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Tue, 8 Apr 2014 15:46:54 +0530 Subject: [PATCH 0114/9457] drm/i915/skl: vfuncs for skl eld and global resource Set gen 9 function pointers for eld write and global resource. Implementation remains same as HSW. v2: Rebase on top of Sonika's untangling of the if/else ladder (Damien) Reviewed-by: Rodrigo Vivi Signed-off-by: Satheeshakrishna M (v1) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 901c035514ac..2087e8baa3f9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12758,6 +12758,10 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.modeset_global_resources = valleyview_modeset_global_resources; dev_priv->display.write_eld = ironlake_write_eld; + } else if (INTEL_INFO(dev)->gen >= 9) { + dev_priv->display.write_eld = haswell_write_eld; + dev_priv->display.modeset_global_resources = + haswell_modeset_global_resources; } /* Default just returns -ENODEV to indicate unsupported */ -- GitLab From 7879a7ebff7b5e9313ef6c28019a0bd62046b10d Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Tue, 8 Apr 2014 15:46:55 +0530 Subject: [PATCH 0115/9457] drm/i915/skl: SKL backlight enabling Extending the BDW backlight implementation to SKL. Reviewed-by: Rodrigo Vivi Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 18784470a760..d69a3cb6b689 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1317,7 +1317,7 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_BROADWELL(dev)) { + if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) { dev_priv->display.setup_backlight = bdw_setup_backlight; dev_priv->display.enable_backlight = bdw_enable_backlight; dev_priv->display.disable_backlight = pch_disable_backlight; -- GitLab From 08524a9ffa396c56ff3fbec9cfd80edd3fa6a058 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Tue, 8 Apr 2014 15:46:56 +0530 Subject: [PATCH 0116/9457] drm/i915/skl: Restore pipe B/C interrupts Extending BDW implementation to gen9. Pipe B/C interrupt restoration after exiting LPSP. v2: Fix minor rebasing conflict. Reviewed-by: Rodrigo Vivi Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d760e0659fa4..fa87f1ec44ec 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6277,7 +6277,7 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); - if (IS_BROADWELL(dev)) + if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) gen8_irq_power_well_post_enable(dev_priv); } -- GitLab From 770de83dc0b4f13b3ec1a923b1769ed668221779 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 20 Mar 2014 20:45:01 +0000 Subject: [PATCH 0117/9457] drm/i915/skl: Adjust the display engine interrupts To accomodate the extra planes, the bit definitions were shuffled around a bit. v2: Rebase on top of the for_each_pipe() change adding dev_priv as first argument. v3: Rebase after yet another change int that area (done with wiggle) Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 37 +++++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_reg.h | 13 ++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a8e0bc44c1bd..ba5ba63288db 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2587,7 +2587,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) } for_each_pipe(dev_priv, pipe) { - uint32_t pipe_iir; + uint32_t pipe_iir, flip_done = 0, fault_errors = 0; if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) continue; @@ -2596,11 +2596,17 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) if (pipe_iir) { ret = IRQ_HANDLED; I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); + if (pipe_iir & GEN8_PIPE_VBLANK && intel_pipe_handle_vblank(dev, pipe)) intel_check_page_flip(dev, pipe); - if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) { + if (IS_GEN9(dev)) + flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE; + else + flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE; + + if (flip_done) { intel_prepare_page_flip(dev, pipe); intel_finish_page_flip_plane(dev, pipe); } @@ -2615,11 +2621,16 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) pipe_name(pipe)); } - if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) { + + if (IS_GEN9(dev)) + fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS; + else + fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS; + + if (fault_errors) DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", pipe_name(pipe), pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS); - } } else DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); } @@ -3803,12 +3814,20 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) { - uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE | - GEN8_PIPE_CDCLK_CRC_DONE | - GEN8_DE_PIPE_IRQ_FAULT_ERRORS; - uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | - GEN8_PIPE_FIFO_UNDERRUN; + uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; + uint32_t de_pipe_enables; int pipe; + + if (IS_GEN9(dev_priv)) + de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE | + GEN9_DE_PIPE_IRQ_FAULT_ERRORS; + else + de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE | + GEN8_DE_PIPE_IRQ_FAULT_ERRORS; + + de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | + GEN8_PIPE_FIFO_UNDERRUN; + dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d4af99ee3e0a..5060b51749b4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4844,10 +4844,23 @@ enum punit_power_well { #define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2) #define GEN8_PIPE_VSYNC (1 << 1) #define GEN8_PIPE_VBLANK (1 << 0) +#define GEN9_PIPE_CURSOR_FAULT (1 << 11) +#define GEN9_PIPE_PLANE3_FAULT (1 << 9) +#define GEN9_PIPE_PLANE2_FAULT (1 << 8) +#define GEN9_PIPE_PLANE1_FAULT (1 << 7) +#define GEN9_PIPE_PLANE3_FLIP_DONE (1 << 5) +#define GEN9_PIPE_PLANE2_FLIP_DONE (1 << 4) +#define GEN9_PIPE_PLANE1_FLIP_DONE (1 << 3) +#define GEN9_PIPE_PLANE_FLIP_DONE(p) (1 << (3 + p)) #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \ (GEN8_PIPE_CURSOR_FAULT | \ GEN8_PIPE_SPRITE_FAULT | \ GEN8_PIPE_PRIMARY_FAULT) +#define GEN9_DE_PIPE_IRQ_FAULT_ERRORS \ + (GEN9_PIPE_CURSOR_FAULT | \ + GEN9_PIPE_PLANE3_FAULT | \ + GEN9_PIPE_PLANE2_FAULT | \ + GEN9_PIPE_PLANE1_FAULT) #define GEN8_DE_PORT_ISR 0x44440 #define GEN8_DE_PORT_IMR 0x44444 -- GitLab From e7e7ea20297afae464bb7da69a2e4c67d1d2b354 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Wed, 9 Apr 2014 11:08:57 +0530 Subject: [PATCH 0118/9457] drm/i915/skl: Sunrise Point PCH detection This patch implements detection of SPT and SPT-LP PCH devices. v2: Added HAS_PCH_SPT macro Reviewed-by: Rodrigo Vivi Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++ drivers/gpu/drm/i915/i915_drv.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7088bdea11c7..51fbb3459e50 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -475,6 +475,16 @@ void intel_detect_pch(struct drm_device *dev) DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); WARN_ON(!IS_HASWELL(dev)); WARN_ON(!IS_ULT(dev)); + } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_SPT; + DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); + WARN_ON(!IS_SKYLAKE(dev)); + WARN_ON(IS_ULT(dev)); + } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_SPT; + DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); + WARN_ON(!IS_SKYLAKE(dev)); + WARN_ON(!IS_ULT(dev)); } else continue; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2c652e8f5726..a8d4e23aba45 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -705,6 +705,7 @@ enum intel_pch { PCH_IBX, /* Ibexpeak PCH */ PCH_CPT, /* Cougarpoint PCH */ PCH_LPT, /* Lynxpoint PCH */ + PCH_SPT, /* Sunrisepoint PCH */ PCH_NOP, }; @@ -2191,8 +2192,11 @@ struct drm_i915_cmd_table { #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 #define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 +#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 #define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type) +#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) -- GitLab From acd5c3464038a550359433362055849e83351d89 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 26 Mar 2014 16:55:46 +0000 Subject: [PATCH 0119/9457] drm/i915/skl: Implement WaDisableSDEUnitClockGating:skl Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fa87f1ec44ec..81465e65e876 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -68,6 +68,14 @@ static void gen9_init_clock_gating(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + + /* + * WaDisableSDEUnitClockGating:skl + * This seems to be a pre-production w/a. + */ + I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | + GEN8_SDEUNIT_CLOCK_GATE_DISABLE); } static void i8xx_disable_fbc(struct drm_device *dev) -- GitLab From 91e41d1665c868a26a24580b83c321e04be43dfe Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 26 Mar 2014 17:42:50 +0000 Subject: [PATCH 0120/9457] drm/i915/skl: Implement Wa4x4STCOptimizationDisable:skl Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 81465e65e876..64eb3b82b466 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -76,6 +76,10 @@ static void gen9_init_clock_gating(struct drm_device *dev) */ I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + + /* Wa4x4STCOptimizationDisable:skl */ + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); } static void i8xx_disable_fbc(struct drm_device *dev) -- GitLab From 3ca5da43003a5bd0ef1d4c15d015c77411e0df0d Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 26 Mar 2014 18:18:01 +0000 Subject: [PATCH 0121/9457] drm/i915/skl: Implement WaDisableDgMirrorFixInHalfSliceChicken5:skl Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5060b51749b4..c5c3ee343218 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5866,6 +5866,9 @@ enum punit_power_well { #define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) +#define GEN9_HALF_SLICE_CHICKEN5 0xe188 +#define GEN9_DG_MIRROR_FIX_ENABLE (1<<5) + #define GEN8_ROW_CHICKEN 0xe4f0 #define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE (1<<8) #define STALL_DOP_GATING_DISABLE (1<<5) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 64eb3b82b466..4f5dcf545c89 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -77,6 +77,14 @@ static void gen9_init_clock_gating(struct drm_device *dev) I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + /* + * WaDisableDgMirrorFixInHalfSliceChicken5:skl + * This is a pre-production w/a. + */ + I915_WRITE(GEN9_HALF_SLICE_CHICKEN5, + I915_READ(GEN9_HALF_SLICE_CHICKEN5) & + ~GEN9_DG_MIRROR_FIX_ENABLE); + /* Wa4x4STCOptimizationDisable:skl */ I915_WRITE(CACHE_MODE_1, _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); -- GitLab From 1fc8ac3e5c355fb0f2864f5deebba3c7d77b4f21 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 12 Feb 2014 19:13:31 +0000 Subject: [PATCH 0122/9457] drm/i915/skl: Skylake has 2 "sprite" planes per pipe On Skylake, we use plane1 as primary plane and plane2/3 as sprite planes. v2: Rebase on top of the for_each_pipe() change adding dev_priv as first argument. Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1403b01e8216..f64050d0c345 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1534,7 +1534,7 @@ static void intel_device_info_runtime_init(struct drm_device *dev) info = (struct intel_device_info *)&dev_priv->info; - if (IS_VALLEYVIEW(dev)) + if (IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen == 9) for_each_pipe(dev_priv, pipe) info->num_sprites[pipe] = 2; else -- GitLab From dc2a41b4cd2b54422b788e4a6f35aacd4fa1fea3 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 4 Dec 2013 00:49:41 +0000 Subject: [PATCH 0123/9457] drm/i915/skl: Implement drm_plane vfuncs SKL Uses the same hardware for all planes now, so called "universal" planes. Ie both the primary planes and sprite planes share the same logic. This patch implements the drm_plane vfuncs for "sprites" ie planes that aren't the primary plane. v2: Couple of fixes: - Actually enabled the planes and fix the plane number Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 31 ++++- drivers/gpu/drm/i915/intel_sprite.c | 206 +++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c5c3ee343218..bc14aaa6f091 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4517,7 +4517,9 @@ enum punit_power_well { #define PLANE_CTL_FORMAT_INDEXED ( 12 << 24) #define PLANE_CTL_FORMAT_RGB_565 ( 14 << 24) #define PLANE_CTL_PIPE_CSC_ENABLE (1 << 23) -#define PLANE_CTL_KEY_ENABLE (1 << 22) +#define PLANE_CTL_KEY_ENABLE_MASK (0x3 << 21) +#define PLANE_CTL_KEY_ENABLE_SOURCE ( 1 << 21) +#define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) #define PLANE_CTL_ORDER_BGRX (0 << 20) #define PLANE_CTL_ORDER_RGBX (1 << 20) #define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) @@ -4552,6 +4554,12 @@ enum punit_power_well { #define _PLANE_OFFSET_1_A 0x701a4 #define _PLANE_OFFSET_2_A 0x702a4 #define _PLANE_OFFSET_3_A 0x703a4 +#define _PLANE_KEYVAL_1_A 0x70194 +#define _PLANE_KEYVAL_2_A 0x70294 +#define _PLANE_KEYMSK_1_A 0x70198 +#define _PLANE_KEYMSK_2_A 0x70298 +#define _PLANE_KEYMAX_1_A 0x701a0 +#define _PLANE_KEYMAX_2_A 0x702a0 #define _PLANE_CTL_1_B 0x71180 #define _PLANE_CTL_2_B 0x71280 @@ -4608,6 +4616,27 @@ enum punit_power_well { #define PLANE_OFFSET(pipe, plane) \ _PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe)) +#define _PLANE_KEYVAL_1_B 0x71194 +#define _PLANE_KEYVAL_2_B 0x71294 +#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B) +#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B) +#define PLANE_KEYVAL(pipe, plane) \ + _PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe)) + +#define _PLANE_KEYMSK_1_B 0x71198 +#define _PLANE_KEYMSK_2_B 0x71298 +#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B) +#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B) +#define PLANE_KEYMSK(pipe, plane) \ + _PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe)) + +#define _PLANE_KEYMAX_1_B 0x711a0 +#define _PLANE_KEYMAX_2_B 0x712a0 +#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B) +#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B) +#define PLANE_KEYMAX(pipe, plane) \ + _PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe)) + /* VBIOS regs */ #define VGACNTRL 0x71400 # define VGA_DISP_DISABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 07a74ef589bd..57e7190c4c87 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -138,6 +138,184 @@ static void intel_update_primary_plane(struct intel_crtc *crtc) I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); } +static void +skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t x, uint32_t y, + uint32_t src_w, uint32_t src_h) +{ + struct drm_device *dev = drm_plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + u32 plane_ctl, stride; + int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + + plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); + + /* Mask out pixel format bits in case we change it */ + plane_ctl &= ~PLANE_CTL_FORMAT_MASK; + plane_ctl &= ~PLANE_CTL_ORDER_RGBX; + plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK; + plane_ctl &= ~PLANE_CTL_TILED_MASK; + plane_ctl &= ~PLANE_CTL_ALPHA_MASK; + + /* Trickle feed has to be enabled */ + plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE; + + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + plane_ctl |= PLANE_CTL_FORMAT_RGB_565; + break; + case DRM_FORMAT_XBGR8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; + break; + case DRM_FORMAT_XRGB8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; + break; + /* + * XXX: For ARBG/ABGR formats we default to expecting scanout buffers + * to be already pre-multiplied. We need to add a knob (or a different + * DRM_FORMAT) for user-space to configure that. + */ + case DRM_FORMAT_ABGR8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | + PLANE_CTL_ORDER_RGBX | + PLANE_CTL_ALPHA_SW_PREMULTIPLY; + break; + case DRM_FORMAT_ARGB8888: + plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | + PLANE_CTL_ALPHA_SW_PREMULTIPLY; + break; + case DRM_FORMAT_YUYV: + plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV; + break; + case DRM_FORMAT_YVYU: + plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU; + break; + case DRM_FORMAT_UYVY: + plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; + break; + case DRM_FORMAT_VYUY: + plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; + break; + default: + BUG(); + } + + switch (obj->tiling_mode) { + case I915_TILING_NONE: + stride = fb->pitches[0] >> 6; + break; + case I915_TILING_X: + plane_ctl |= PLANE_CTL_TILED_X; + stride = fb->pitches[0] >> 9; + break; + default: + BUG(); + } + + plane_ctl |= PLANE_CTL_ENABLE; + plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; + + intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, + pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ + src_w--; + src_h--; + crtc_w--; + crtc_h--; + + I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x); + I915_WRITE(PLANE_STRIDE(pipe, plane), stride); + I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x); + I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w); + I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); + I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj)); + POSTING_READ(PLANE_SURF(pipe, plane)); +} + +static void +skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc) +{ + struct drm_device *dev = drm_plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane + 1; + + I915_WRITE(PLANE_CTL(pipe, plane), + I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE); + + /* Activate double buffered register update */ + I915_WRITE(PLANE_CTL(pipe, plane), 0); + POSTING_READ(PLANE_CTL(pipe, plane)); + + intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false); +} + +static int +skl_update_colorkey(struct drm_plane *drm_plane, + struct drm_intel_sprite_colorkey *key) +{ + struct drm_device *dev = drm_plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane; + u32 plane_ctl; + + I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); + I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); + I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask); + + plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); + plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK; + if (key->flags & I915_SET_COLORKEY_DESTINATION) + plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; + else if (key->flags & I915_SET_COLORKEY_SOURCE) + plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; + I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); + + POSTING_READ(PLANE_CTL(pipe, plane)); + + return 0; +} + +static void +skl_get_colorkey(struct drm_plane *drm_plane, + struct drm_intel_sprite_colorkey *key) +{ + struct drm_device *dev = drm_plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_plane *intel_plane = to_intel_plane(drm_plane); + const int pipe = intel_plane->pipe; + const int plane = intel_plane->plane; + u32 plane_ctl; + + key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane)); + key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane)); + key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane)); + + plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); + + switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) { + case PLANE_CTL_KEY_ENABLE_DESTINATION: + key->flags = I915_SET_COLORKEY_DESTINATION; + break; + case PLANE_CTL_KEY_ENABLE_SOURCE: + key->flags = I915_SET_COLORKEY_SOURCE; + break; + default: + key->flags = I915_SET_COLORKEY_NONE; + } +} + static void vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -1305,6 +1483,18 @@ static uint32_t vlv_plane_formats[] = { DRM_FORMAT_VYUY, }; +static uint32_t skl_plane_formats[] = { + DRM_FORMAT_RGB565, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, +}; + int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) { @@ -1368,7 +1558,21 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) num_plane_formats = ARRAY_SIZE(snb_plane_formats); } break; - + case 9: + /* + * FIXME: Skylake planes can be scaled (with some restrictions), + * but this is for another time. + */ + intel_plane->can_scale = false; + intel_plane->max_downscale = 1; + intel_plane->update_plane = skl_update_plane; + intel_plane->disable_plane = skl_disable_plane; + intel_plane->update_colorkey = skl_update_colorkey; + intel_plane->get_colorkey = skl_get_colorkey; + + plane_formats = skl_plane_formats; + num_plane_formats = ARRAY_SIZE(skl_plane_formats); + break; default: kfree(intel_plane); return -ENODEV; -- GitLab From 7feb8b88e7513d6b093539c2b7291cfb87cb917a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 12 Mar 2014 21:05:38 +0000 Subject: [PATCH 0124/9457] drm/i915/skl: Adjust assert_sprites_disabled() Let's put to good use the new PLANE_CTL macros. Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2087e8baa3f9..1bda97c7100a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1335,7 +1335,14 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv, int reg, sprite; u32 val; - if (IS_VALLEYVIEW(dev)) { + if (INTEL_INFO(dev)->gen >= 9) { + for_each_sprite(pipe, sprite) { + val = I915_READ(PLANE_CTL(pipe, sprite)); + WARN(val & PLANE_CTL_ENABLE, + "plane %d assertion failure, should be off on pipe %c but is still active\n", + sprite, pipe_name(pipe)); + } + } else if (IS_VALLEYVIEW(dev)) { for_each_sprite(pipe, sprite) { reg = SPCNTR(pipe, sprite); val = I915_READ(reg); -- GitLab From 84139d1e39265c20a79daace16ef4b6a9a644d9a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 28 Mar 2014 00:18:32 +0530 Subject: [PATCH 0125/9457] drm/i915/skl: Introduce a I915_MAX_PLANES macro This can be useful to declare structures around pipes and planes and don't have to go back auditing the code if the next platorm bump that number. Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a8d4e23aba45..c3dbaaed2ff9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -76,6 +76,14 @@ enum transcoder { }; #define transcoder_name(t) ((t) + 'A') +/* + * This is the maximum (across all platforms) number of planes (primary + + * sprites) that can be active at the same time on one pipe. + * + * This value doesn't count the cursor plane. + */ +#define I915_MAX_PLANES 3 + enum plane { PLANE_A = 0, PLANE_B, -- GitLab From 6af31a653d6c8e1708c27b7f32cafd5435b3bb90 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 28 Mar 2014 00:18:33 +0530 Subject: [PATCH 0126/9457] drm/i915/skl: Introduce intel_num_planes() It can be handy to get the number of planes for this pipe, ie including the primary plane to loop over them. Introduce a little function to do so. Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07ce04683c30..a09e4adda0bf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -731,6 +731,14 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) return container_of(intel_hdmi, struct intel_digital_port, hdmi); } +/* + * Returns the number of planes for this pipe, ie the number of sprites + 1 + * (primary plane). This doesn't count the cursor plane then. + */ +static inline unsigned int intel_num_planes(struct intel_crtc *crtc) +{ + return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1; +} /* i915_irq.c */ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, -- GitLab From c83155a6044341d67b85b441ba719f86058f6e2b Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 28 Mar 2014 00:18:35 +0530 Subject: [PATCH 0127/9457] drm/i915/skl: Move gen9 pm initialization into its own branch Gen9 is different enough (for instance, fetching the memory latency values is different from ILK+) to not take the HAS_PCH_SPLIT() branch, so let's prefer a clean separation. v2: Rebase on top of the broadwell_init_clock_gating() name change Reviewed-by: Rodrigo Vivi Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4f5dcf545c89..81eb8bca5628 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7397,7 +7397,9 @@ void intel_init_pm(struct drm_device *dev) i915_ironlake_get_mem_freq(dev); /* For FIFO watermark updates */ - if (HAS_PCH_SPLIT(dev)) { + if (IS_GEN9(dev)) { + dev_priv->display.init_clock_gating = gen9_init_clock_gating; + } else if (HAS_PCH_SPLIT(dev)) { ilk_setup_wm_latency(dev); if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] && @@ -7421,8 +7423,6 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.init_clock_gating = haswell_init_clock_gating; else if (INTEL_INFO(dev)->gen == 8) dev_priv->display.init_clock_gating = broadwell_init_clock_gating; - else if (INTEL_INFO(dev)->gen == 9) - dev_priv->display.init_clock_gating = gen9_init_clock_gating; } else if (IS_CHERRYVIEW(dev)) { dev_priv->display.update_wm = cherryview_update_wm; dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; -- GitLab From 7ca5a41f4da201371e131fc0641033652f76bf30 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 16 Sep 2014 19:19:07 -0400 Subject: [PATCH 0128/9457] drm/i915: Avoid re-configure panel on every PSR re-enable. The panel has to be reconfigured only when it really loose the power. The traditional enable/disable sequence already take care of this so we can minimize the time spend on every re-enable. Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 43b381a087f4..c5ec821fa5fb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2121,10 +2121,7 @@ static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) WARN_ON(dev_priv->psr.active); lockdep_assert_held(&dev_priv->psr.lock); - /* Enable PSR on the panel */ - intel_edp_psr_enable_sink(intel_dp); - - /* Enable PSR on the host */ + /* Enable/Re-enable PSR on the host */ intel_edp_psr_enable_source(intel_dp); dev_priv->psr.active = true; @@ -2162,6 +2159,9 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); + /* Enable PSR on the panel */ + intel_edp_psr_enable_sink(intel_dp); + dev_priv->psr.enabled = intel_dp; unlock: mutex_unlock(&dev_priv->psr.lock); -- GitLab From 34b28b6e9a66da35e161b2221c62c82ab8d87f38 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 23 Sep 2014 10:22:52 +0200 Subject: [PATCH 0129/9457] ath10k: print wmi version info HTT version is already printed so print WMI version as well for consistency. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 101c6f9cf2a8..4f982c70a6b0 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -126,14 +126,18 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { - ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", + ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d\n", ar->hw_params.name, ar->target_version, ar->chip_id, ar->hw->wiphy->fw_version, ar->fw_api, ar->htt.target_version_major, - ar->htt.target_version_minor); + ar->htt.target_version_minor, + ar->fw_version_major, + ar->fw_version_minor, + ar->fw_version_release, + ar->fw_version_build); ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", config_enabled(CONFIG_ATH10K_DEBUG), config_enabled(CONFIG_ATH10K_DEBUGFS), -- GitLab From 45724a8a82981de911ebb2540e469907ae50a240 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 23 Sep 2014 10:22:53 +0200 Subject: [PATCH 0130/9457] ath10k: dump hex bytes with dev string prefix This makes it easier to debug hex dumps on systems with more than a single ath10k device. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 4f982c70a6b0..5e001de7aafe 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1264,11 +1264,26 @@ void ath10k_dbg_dump(struct ath10k *ar, const char *msg, const char *prefix, const void *buf, size_t len) { + char linebuf[256]; + unsigned int linebuflen; + const void *ptr; + if (ath10k_debug_mask & mask) { if (msg) ath10k_dbg(ar, mask, "%s\n", msg); - print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); + for (ptr = buf; (ptr - buf) < len; ptr += 16) { + linebuflen = 0; + linebuflen += scnprintf(linebuf + linebuflen, + sizeof(linebuf) - linebuflen, + "%s%08x: ", + (prefix ? prefix : ""), + (unsigned int)(ptr - buf)); + hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1, + linebuf + linebuflen, + sizeof(linebuf) - linebuflen, true); + dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf); + } } /* tracing code doesn't like null strings :/ */ -- GitLab From a360e54cda8f3b18365fa6f58392de7f067b07d3 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 23 Sep 2014 10:22:54 +0200 Subject: [PATCH 0131/9457] ath10k: add debug dump for pci rx This makes it easier to debug the device-target communication at a very low level. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 59e0ea83be50..8319d83bb9a8 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -861,6 +861,12 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state) } skb_put(skb, nbytes); + + ath10k_dbg(ar, ATH10K_DBG_PCI, "pci rx ce pipe %d len %d\n", + ce_state->id, skb->len); + ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci rx: ", + skb->data, skb->len); + cb->rx_completion(ar, skb, pipe_info->pipe_num); } -- GitLab From d5d6805bf90f420abbaac30037d5fef6b7c05096 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Wed, 24 Sep 2014 14:16:46 +0300 Subject: [PATCH 0132/9457] ath10k: don't enable interrupts for the diagnostic window The diagnostic window (CE7) uses polling and is not initiliased to retrieve interrupts so disable interrupts altogether for CE7. Otherwise ath10k crashes when using the diagnostic window while the firmware is running due to NULL dereference and polling reads timeout. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 101cadb6e4ba..09ef03e7af89 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -817,7 +817,10 @@ void ath10k_ce_enable_interrupts(struct ath10k *ar) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); int ce_id; - for (ce_id = 0; ce_id < CE_COUNT; ce_id++) + /* Skip the last copy engine, CE7 the diagnostic window, as that + * uses polling and isn't initialized for interrupts. + */ + for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++) ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]); } -- GitLab From eef254051f3c7675e3ac4df23f8ccf7b210c39c5 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Wed, 24 Sep 2014 14:16:52 +0300 Subject: [PATCH 0133/9457] ath10k: add diag_read() to hif ops diag_read() is used for reading from firmware memory via the diagnose window. First user will be cal_data debugfs file. To serialise diagnostic window access and make it safe to use while firmware is running take ce_lock both in ath10k_pci_diag_write_mem() and ath10k_pci_diag_read_mem(). Because of that all the CE calls had to be changed to _nolock variants. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 22 ++++++------ drivers/net/wireless/ath/ath10k/ce.h | 13 +++++++ drivers/net/wireless/ath/ath10k/hif.h | 10 ++++++ drivers/net/wireless/ath/ath10k/pci.c | 51 +++++++++++++++++---------- 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 09ef03e7af89..4745ef2a6f01 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) * Guts of ath10k_ce_completed_recv_next. * The caller takes responsibility for any necessary locking. */ -static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, - void **per_transfer_contextp, - u32 *bufferp, - unsigned int *nbytesp, - unsigned int *transfer_idp, - unsigned int *flagsp) +int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, + void **per_transfer_contextp, + u32 *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *flagsp) { struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; unsigned int nentries_mask = dest_ring->nentries_mask; @@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, * Guts of ath10k_ce_completed_send_next. * The caller takes responsibility for any necessary locking. */ -static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, - void **per_transfer_contextp, - u32 *bufferp, - unsigned int *nbytesp, - unsigned int *transfer_idp) +int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, + void **per_transfer_contextp, + u32 *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp) { struct ath10k_ce_ring *src_ring = ce_state->src_ring; u32 ctrl_addr = ce_state->ctrl_addr; diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 329b7340fa72..608262ab964e 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -192,6 +192,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, unsigned int *nbytesp, unsigned int *transfer_idp); +int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, + void **per_transfer_contextp, + u32 *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp); + /*==================CE Engine Initialization=======================*/ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, @@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, void **per_transfer_contextp, u32 *bufferp); +int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, + void **per_transfer_contextp, + u32 *bufferp, + unsigned int *nbytesp, + unsigned int *transfer_idp, + unsigned int *flagsp); + /* * Support clean shutdown by allowing the caller to cancel * pending sends. Target DMA must be stopped before using diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h index 62323fea27e1..30301f5b6051 100644 --- a/drivers/net/wireless/ath/ath10k/hif.h +++ b/drivers/net/wireless/ath/ath10k/hif.h @@ -43,6 +43,10 @@ struct ath10k_hif_ops { int (*tx_sg)(struct ath10k *ar, u8 pipe_id, struct ath10k_hif_sg_item *items, int n_items); + /* read firmware memory through the diagnose interface */ + int (*diag_read)(struct ath10k *ar, u32 address, void *buf, + size_t buf_len); + /* * API to handle HIF-specific BMI message exchanges, this API is * synchronous and only allowed to be called from a context that @@ -98,6 +102,12 @@ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items); } +static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf, + size_t buf_len) +{ + return ar->hif.ops->diag_read(ar, address, buf, buf_len); +} + static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, void *request, u32 request_len, void *response, u32 *response_len) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 8319d83bb9a8..ae961c6ff74e 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -485,6 +485,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, void *data_buf = NULL; int i; + spin_lock_bh(&ar_pci->ce_lock); + ce_diag = ar_pci->ce_diag; /* @@ -511,7 +513,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, nbytes = min_t(unsigned int, remaining_bytes, DIAG_TRANSFER_LIMIT); - ret = ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data); + ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data); if (ret != 0) goto done; @@ -527,15 +529,15 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); - ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, - 0); + ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, nbytes, 0, + 0); if (ret) goto done; i = 0; - while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, - &completed_nbytes, - &id) != 0) { + while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf, + &completed_nbytes, + &id) != 0) { mdelay(1); if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { ret = -EBUSY; @@ -554,9 +556,9 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, } i = 0; - while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, - &completed_nbytes, - &id, &flags) != 0) { + while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf, + &completed_nbytes, + &id, &flags) != 0) { mdelay(1); if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { @@ -591,6 +593,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, dma_free_coherent(ar->dev, orig_nbytes, data_buf, ce_data_base); + spin_unlock_bh(&ar_pci->ce_lock); + return ret; } @@ -648,6 +652,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, dma_addr_t ce_data_base = 0; int i; + spin_lock_bh(&ar_pci->ce_lock); + ce_diag = ar_pci->ce_diag; /* @@ -688,7 +694,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); /* Set up to receive directly into Target(!) address */ - ret = ath10k_ce_rx_post_buf(ce_diag, NULL, address); + ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, address); if (ret != 0) goto done; @@ -696,15 +702,15 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, * Request CE to send caller-supplied data that * was copied to bounce buffer to Target(!) address. */ - ret = ath10k_ce_send(ce_diag, NULL, (u32)ce_data, - nbytes, 0, 0); + ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data, + nbytes, 0, 0); if (ret != 0) goto done; i = 0; - while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, - &completed_nbytes, - &id) != 0) { + while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf, + &completed_nbytes, + &id) != 0) { mdelay(1); if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { @@ -724,9 +730,9 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, } i = 0; - while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, - &completed_nbytes, - &id, &flags) != 0) { + while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf, + &completed_nbytes, + &id, &flags) != 0) { mdelay(1); if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { @@ -760,6 +766,8 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", address, ret); + spin_unlock_bh(&ar_pci->ce_lock); + return ret; } @@ -942,6 +950,12 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, return err; } +static int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf, + size_t buf_len) +{ + return ath10k_pci_diag_read_mem(ar, address, buf, buf_len); +} + static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); @@ -1927,6 +1941,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar) static const struct ath10k_hif_ops ath10k_pci_hif_ops = { .tx_sg = ath10k_pci_hif_tx_sg, + .diag_read = ath10k_pci_hif_diag_read, .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, .start = ath10k_pci_hif_start, .stop = ath10k_pci_hif_stop, -- GitLab From 7869b4faf53e9d25212b17fcbc59dce22324fce7 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Wed, 24 Sep 2014 14:16:58 +0300 Subject: [PATCH 0134/9457] ath10k: add cal_data debugfs file Provide calibration data used by the firmware to user space via a debugfs file. This makes it easier to debug calibration related problems. Example: sudo cp /sys/kernel/debug/ieee80211/phy0/ath10k/cal_data 1.cal Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 82 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/hw.h | 2 + 2 files changed, 84 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 5e001de7aafe..22b4888444c9 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -23,6 +23,7 @@ #include "core.h" #include "debug.h" +#include "hif.h" /* ms */ #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 @@ -1041,6 +1042,84 @@ static const struct file_operations fops_fw_dbglog = { .llseek = default_llseek, }; +static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file) +{ + struct ath10k *ar = inode->i_private; + void *buf; + u32 hi_addr; + __le32 addr; + int ret; + + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto err; + } + + buf = vmalloc(QCA988X_CAL_DATA_LEN); + if (!buf) { + ret = -ENOMEM; + goto err; + } + + hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); + + ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr)); + if (ret) { + ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret); + goto err_vfree; + } + + ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf, + QCA988X_CAL_DATA_LEN); + if (ret) { + ath10k_warn(ar, "failed to read calibration data: %d\n", ret); + goto err_vfree; + } + + file->private_data = buf; + + mutex_unlock(&ar->conf_mutex); + + return 0; + +err_vfree: + vfree(buf); + +err: + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static ssize_t ath10k_debug_cal_data_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + void *buf = file->private_data; + + return simple_read_from_buffer(user_buf, count, ppos, + buf, QCA988X_CAL_DATA_LEN); +} + +static int ath10k_debug_cal_data_release(struct inode *inode, + struct file *file) +{ + vfree(file->private_data); + + return 0; +} + +static const struct file_operations fops_cal_data = { + .open = ath10k_debug_cal_data_open, + .read = ath10k_debug_cal_data_read, + .release = ath10k_debug_cal_data_release, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath10k_debug_start(struct ath10k *ar) { int ret; @@ -1214,6 +1293,9 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_dbglog); + debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy, + ar, &fops_cal_data); + if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { debugfs_create_file("dfs_simulate_radar", S_IWUSR, ar->debug.debugfs_phy, ar, diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 3cf5702c1e7e..006a9cbc60b2 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -43,6 +43,8 @@ #define REG_DUMP_COUNT_QCA988X 60 +#define QCA988X_CAL_DATA_LEN 2116 + struct ath10k_fw_ie { __le32 id; __le32 len; -- GitLab From babcb3edd942927091ef5e5b284ffc657c652023 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 22 Sep 2014 10:35:34 -0700 Subject: [PATCH 0135/9457] ath: change logging functions to return void The return values are not used by callers of these functions so change the functions to return void. Other miscellanea: o add __printf verification to wil6210 logging functions No format/argument mismatches found Acked-by: Vladimir Kondratiev Signed-off-by: Joe Perches Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 18 ++++---------- drivers/net/wireless/ath/ath10k/debug.h | 6 ++--- drivers/net/wireless/ath/ath6kl/common.h | 2 +- drivers/net/wireless/ath/ath6kl/debug.c | 28 +++++++--------------- drivers/net/wireless/ath/ath6kl/debug.h | 13 +++++----- drivers/net/wireless/ath/wil6210/debug.c | 14 ++++------- drivers/net/wireless/ath/wil6210/wil6210.h | 7 ++++-- 7 files changed, 32 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 22b4888444c9..5d44a4320ad0 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -107,21 +107,18 @@ struct ath10k_dump_file_data { u8 data[0]; } __packed; -int ath10k_info(struct ath10k *ar, const char *fmt, ...) +void ath10k_info(struct ath10k *ar, const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = dev_info(ar->dev, "%pV", &vaf); + dev_info(ar->dev, "%pV", &vaf); trace_ath10k_log_info(ar, &vaf); va_end(args); - - return ret; } EXPORT_SYMBOL(ath10k_info); @@ -148,25 +145,22 @@ void ath10k_print_driver_info(struct ath10k *ar) } EXPORT_SYMBOL(ath10k_print_driver_info); -int ath10k_err(struct ath10k *ar, const char *fmt, ...) +void ath10k_err(struct ath10k *ar, const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = dev_err(ar->dev, "%pV", &vaf); + dev_err(ar->dev, "%pV", &vaf); trace_ath10k_log_err(ar, &vaf); va_end(args); - - return ret; } EXPORT_SYMBOL(ath10k_err); -int ath10k_warn(struct ath10k *ar, const char *fmt, ...) +void ath10k_warn(struct ath10k *ar, const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, @@ -179,8 +173,6 @@ int ath10k_warn(struct ath10k *ar, const char *fmt, ...) trace_ath10k_log_warn(ar, &vaf); va_end(args); - - return 0; } EXPORT_SYMBOL(ath10k_warn); diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index d6276fea1adf..4ae0d8030dce 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -40,9 +40,9 @@ enum ath10k_debug_mask { extern unsigned int ath10k_debug_mask; -__printf(2, 3) int ath10k_info(struct ath10k *ar, const char *fmt, ...); -__printf(2, 3) int ath10k_err(struct ath10k *ar, const char *fmt, ...); -__printf(2, 3) int ath10k_warn(struct ath10k *ar, const char *fmt, ...); +__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...); +__printf(2, 3) void ath10k_err(struct ath10k *ar, const char *fmt, ...); +__printf(2, 3) void ath10k_warn(struct ath10k *ar, const char *fmt, ...); void ath10k_print_driver_info(struct ath10k *ar); #ifdef CONFIG_ATH10K_DEBUGFS diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index 05debf700a84..4f82e8632d37 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -22,7 +22,7 @@ #define ATH6KL_MAX_IE 256 -__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); +__printf(2, 3) void ath6kl_printk(const char *level, const char *fmt, ...); /* * Reflects the version of binary interface exposed by ATH6KL target diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 55c4064dd506..81ba48d2938b 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -37,76 +37,64 @@ struct ath6kl_fwlog_slot { #define ATH6KL_FWLOG_VALID_MASK 0x1ffff -int ath6kl_printk(const char *level, const char *fmt, ...) +void ath6kl_printk(const char *level, const char *fmt, ...) { struct va_format vaf; va_list args; - int rtn; va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - rtn = printk("%sath6kl: %pV", level, &vaf); + printk("%sath6kl: %pV", level, &vaf); va_end(args); - - return rtn; } EXPORT_SYMBOL(ath6kl_printk); -int ath6kl_info(const char *fmt, ...) +void ath6kl_info(const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = ath6kl_printk(KERN_INFO, "%pV", &vaf); + ath6kl_printk(KERN_INFO, "%pV", &vaf); trace_ath6kl_log_info(&vaf); va_end(args); - - return ret; } EXPORT_SYMBOL(ath6kl_info); -int ath6kl_err(const char *fmt, ...) +void ath6kl_err(const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = ath6kl_printk(KERN_ERR, "%pV", &vaf); + ath6kl_printk(KERN_ERR, "%pV", &vaf); trace_ath6kl_log_err(&vaf); va_end(args); - - return ret; } EXPORT_SYMBOL(ath6kl_err); -int ath6kl_warn(const char *fmt, ...) +void ath6kl_warn(const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf); + ath6kl_printk(KERN_WARNING, "%pV", &vaf); trace_ath6kl_log_warn(&vaf); va_end(args); - - return ret; } EXPORT_SYMBOL(ath6kl_warn); diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index e194c10d9f00..19106ed28961 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -50,10 +50,10 @@ enum ATH6K_DEBUG_MASK { }; extern unsigned int debug_mask; -__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); -__printf(1, 2) int ath6kl_info(const char *fmt, ...); -__printf(1, 2) int ath6kl_err(const char *fmt, ...); -__printf(1, 2) int ath6kl_warn(const char *fmt, ...); +__printf(2, 3) void ath6kl_printk(const char *level, const char *fmt, ...); +__printf(1, 2) void ath6kl_info(const char *fmt, ...); +__printf(1, 2) void ath6kl_err(const char *fmt, ...); +__printf(1, 2) void ath6kl_warn(const char *fmt, ...); enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, @@ -81,10 +81,9 @@ int ath6kl_debug_init_fs(struct ath6kl *ar); void ath6kl_debug_cleanup(struct ath6kl *ar); #else -static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask, - const char *fmt, ...) +static inline void ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask, + const char *fmt, ...) { - return 0; } static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c index 9eeabf4a5879..7a925ac291be 100644 --- a/drivers/net/wireless/ath/wil6210/debug.c +++ b/drivers/net/wireless/ath/wil6210/debug.c @@ -17,40 +17,34 @@ #include "wil6210.h" #include "trace.h" -int wil_err(struct wil6210_priv *wil, const char *fmt, ...) +void wil_err(struct wil6210_priv *wil, const char *fmt, ...) { struct net_device *ndev = wil_to_ndev(wil); struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = netdev_err(ndev, "%pV", &vaf); + netdev_err(ndev, "%pV", &vaf); trace_wil6210_log_err(&vaf); va_end(args); - - return ret; } -int wil_info(struct wil6210_priv *wil, const char *fmt, ...) +void wil_info(struct wil6210_priv *wil, const char *fmt, ...) { struct net_device *ndev = wil_to_ndev(wil); struct va_format vaf = { .fmt = fmt, }; va_list args; - int ret; va_start(args, fmt); vaf.va = &args; - ret = netdev_info(ndev, "%pV", &vaf); + netdev_info(ndev, "%pV", &vaf); trace_wil6210_log_info(&vaf); va_end(args); - - return ret; } int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index f8718fe547c4..1300b5505151 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -436,9 +436,12 @@ struct wil6210_priv { #define wil_to_ndev(i) (wil_to_wdev(i)->netdev) #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) +__printf(2, 3) int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); -int wil_err(struct wil6210_priv *wil, const char *fmt, ...); -int wil_info(struct wil6210_priv *wil, const char *fmt, ...); +__printf(2, 3) +void wil_err(struct wil6210_priv *wil, const char *fmt, ...); +__printf(2, 3) +void wil_info(struct wil6210_priv *wil, const char *fmt, ...); #define wil_dbg(wil, fmt, arg...) do { \ netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ wil_dbg_trace(wil, fmt, ##arg); \ -- GitLab From d15fb52006645f9ef1f62313ba19ef29d1a12bf9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 25 Sep 2014 12:33:47 +0200 Subject: [PATCH 0136/9457] ath10k: split wmi stats parsing The parsing function was rather complex. Simplify by splitting it up into firmware branch specific implementations. While at it move the parsing code into wmi.c where it belongs. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 127 ++---------------- drivers/net/wireless/ath/ath10k/debug.h | 5 +- drivers/net/wireless/ath/ath10k/wmi.c | 165 +++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/wmi.h | 24 ++-- 4 files changed, 180 insertions(+), 141 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 5d44a4320ad0..906319f49ca2 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -239,133 +239,22 @@ static const struct file_operations fops_wmi_services = { .llseek = default_llseek, }; -void ath10k_debug_read_target_stats(struct ath10k *ar, - struct wmi_stats_event *ev) +void ath10k_debug_read_target_stats(struct ath10k *ar, struct sk_buff *skb) { - u8 *tmp = ev->data; - struct ath10k_target_stats *stats; - int num_pdev_stats, num_vdev_stats, num_peer_stats; - struct wmi_pdev_stats_10x *ps; - int i; + int ret; spin_lock_bh(&ar->data_lock); - stats = &ar->debug.target_stats; - - num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); /* 0 or 1 */ - num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); /* 0 or max vdevs */ - num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */ - - if (num_pdev_stats) { - ps = (struct wmi_pdev_stats_10x *)tmp; - - stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf); - stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count); - stats->rx_frame_count = __le32_to_cpu(ps->rx_frame_count); - stats->rx_clear_count = __le32_to_cpu(ps->rx_clear_count); - stats->cycle_count = __le32_to_cpu(ps->cycle_count); - stats->phy_err_count = __le32_to_cpu(ps->phy_err_count); - stats->chan_tx_power = __le32_to_cpu(ps->chan_tx_pwr); - - stats->comp_queued = __le32_to_cpu(ps->wal.tx.comp_queued); - stats->comp_delivered = - __le32_to_cpu(ps->wal.tx.comp_delivered); - stats->msdu_enqued = __le32_to_cpu(ps->wal.tx.msdu_enqued); - stats->mpdu_enqued = __le32_to_cpu(ps->wal.tx.mpdu_enqued); - stats->wmm_drop = __le32_to_cpu(ps->wal.tx.wmm_drop); - stats->local_enqued = __le32_to_cpu(ps->wal.tx.local_enqued); - stats->local_freed = __le32_to_cpu(ps->wal.tx.local_freed); - stats->hw_queued = __le32_to_cpu(ps->wal.tx.hw_queued); - stats->hw_reaped = __le32_to_cpu(ps->wal.tx.hw_reaped); - stats->underrun = __le32_to_cpu(ps->wal.tx.underrun); - stats->tx_abort = __le32_to_cpu(ps->wal.tx.tx_abort); - stats->mpdus_requed = __le32_to_cpu(ps->wal.tx.mpdus_requed); - stats->tx_ko = __le32_to_cpu(ps->wal.tx.tx_ko); - stats->data_rc = __le32_to_cpu(ps->wal.tx.data_rc); - stats->self_triggers = __le32_to_cpu(ps->wal.tx.self_triggers); - stats->sw_retry_failure = - __le32_to_cpu(ps->wal.tx.sw_retry_failure); - stats->illgl_rate_phy_err = - __le32_to_cpu(ps->wal.tx.illgl_rate_phy_err); - stats->pdev_cont_xretry = - __le32_to_cpu(ps->wal.tx.pdev_cont_xretry); - stats->pdev_tx_timeout = - __le32_to_cpu(ps->wal.tx.pdev_tx_timeout); - stats->pdev_resets = __le32_to_cpu(ps->wal.tx.pdev_resets); - stats->phy_underrun = __le32_to_cpu(ps->wal.tx.phy_underrun); - stats->txop_ovf = __le32_to_cpu(ps->wal.tx.txop_ovf); - - stats->mid_ppdu_route_change = - __le32_to_cpu(ps->wal.rx.mid_ppdu_route_change); - stats->status_rcvd = __le32_to_cpu(ps->wal.rx.status_rcvd); - stats->r0_frags = __le32_to_cpu(ps->wal.rx.r0_frags); - stats->r1_frags = __le32_to_cpu(ps->wal.rx.r1_frags); - stats->r2_frags = __le32_to_cpu(ps->wal.rx.r2_frags); - stats->r3_frags = __le32_to_cpu(ps->wal.rx.r3_frags); - stats->htt_msdus = __le32_to_cpu(ps->wal.rx.htt_msdus); - stats->htt_mpdus = __le32_to_cpu(ps->wal.rx.htt_mpdus); - stats->loc_msdus = __le32_to_cpu(ps->wal.rx.loc_msdus); - stats->loc_mpdus = __le32_to_cpu(ps->wal.rx.loc_mpdus); - stats->oversize_amsdu = - __le32_to_cpu(ps->wal.rx.oversize_amsdu); - stats->phy_errs = __le32_to_cpu(ps->wal.rx.phy_errs); - stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop); - stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs); - - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, - ar->fw_features)) { - stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad); - stats->rts_bad = __le32_to_cpu(ps->rts_bad); - stats->rts_good = __le32_to_cpu(ps->rts_good); - stats->fcs_bad = __le32_to_cpu(ps->fcs_bad); - stats->no_beacons = __le32_to_cpu(ps->no_beacons); - stats->mib_int_count = __le32_to_cpu(ps->mib_int_count); - tmp += sizeof(struct wmi_pdev_stats_10x); - } else { - tmp += sizeof(struct wmi_pdev_stats_old); - } - } - - /* 0 or max vdevs */ - /* Currently firmware does not support VDEV stats */ - if (num_vdev_stats) { - struct wmi_vdev_stats *vdev_stats; - - for (i = 0; i < num_vdev_stats; i++) { - vdev_stats = (struct wmi_vdev_stats *)tmp; - tmp += sizeof(struct wmi_vdev_stats); - } + ret = ath10k_wmi_pull_fw_stats(ar, skb, &ar->debug.target_stats); + if (ret) { + ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); + goto unlock; } - if (num_peer_stats) { - struct wmi_peer_stats_10x *peer_stats; - struct ath10k_peer_stat *s; - - stats->peers = num_peer_stats; - - for (i = 0; i < num_peer_stats; i++) { - peer_stats = (struct wmi_peer_stats_10x *)tmp; - s = &stats->peer_stat[i]; - - memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr, - ETH_ALEN); - s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi); - s->peer_tx_rate = - __le32_to_cpu(peer_stats->peer_tx_rate); - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, - ar->fw_features)) { - s->peer_rx_rate = - __le32_to_cpu(peer_stats->peer_rx_rate); - tmp += sizeof(struct wmi_peer_stats_10x); - - } else { - tmp += sizeof(struct wmi_peer_stats_old); - } - } - } + complete(&ar->debug.event_stats_compl); +unlock: spin_unlock_bh(&ar->data_lock); - complete(&ar->debug.event_stats_compl); } static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 4ae0d8030dce..8d8b68eb04e6 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -55,8 +55,7 @@ void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size); -void ath10k_debug_read_target_stats(struct ath10k *ar, - struct wmi_stats_event *ev); +void ath10k_debug_read_target_stats(struct ath10k *ar, struct sk_buff *skb); struct ath10k_fw_crash_data * ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); @@ -99,7 +98,7 @@ static inline void ath10k_debug_read_service_map(struct ath10k *ar, } static inline void ath10k_debug_read_target_stats(struct ath10k *ar, - struct wmi_stats_event *ev) + struct sk_buff *skb) { } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index bfc1fb3708c5..8e2d0217686d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1329,14 +1329,171 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) return 0; } +static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, + struct ath10k_target_stats *dst) +{ + const struct wal_dbg_tx_stats *tx = &src->wal.tx; + const struct wal_dbg_rx_stats *rx = &src->wal.rx; + + dst->ch_noise_floor = __le32_to_cpu(src->chan_nf); + dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count); + dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count); + dst->rx_clear_count = __le32_to_cpu(src->rx_clear_count); + dst->cycle_count = __le32_to_cpu(src->cycle_count); + dst->phy_err_count = __le32_to_cpu(src->phy_err_count); + dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr); + + dst->comp_queued = __le32_to_cpu(tx->comp_queued); + dst->comp_delivered = __le32_to_cpu(tx->comp_delivered); + dst->msdu_enqued = __le32_to_cpu(tx->msdu_enqued); + dst->mpdu_enqued = __le32_to_cpu(tx->mpdu_enqued); + dst->wmm_drop = __le32_to_cpu(tx->wmm_drop); + dst->local_enqued = __le32_to_cpu(tx->local_enqued); + dst->local_freed = __le32_to_cpu(tx->local_freed); + dst->hw_queued = __le32_to_cpu(tx->hw_queued); + dst->hw_reaped = __le32_to_cpu(tx->hw_reaped); + dst->underrun = __le32_to_cpu(tx->underrun); + dst->tx_abort = __le32_to_cpu(tx->tx_abort); + dst->mpdus_requed = __le32_to_cpu(tx->mpdus_requed); + dst->tx_ko = __le32_to_cpu(tx->tx_ko); + dst->data_rc = __le32_to_cpu(tx->data_rc); + dst->self_triggers = __le32_to_cpu(tx->self_triggers); + dst->sw_retry_failure = __le32_to_cpu(tx->sw_retry_failure); + dst->illgl_rate_phy_err = __le32_to_cpu(tx->illgl_rate_phy_err); + dst->pdev_cont_xretry = __le32_to_cpu(tx->pdev_cont_xretry); + dst->pdev_tx_timeout = __le32_to_cpu(tx->pdev_tx_timeout); + dst->pdev_resets = __le32_to_cpu(tx->pdev_resets); + dst->phy_underrun = __le32_to_cpu(tx->phy_underrun); + dst->txop_ovf = __le32_to_cpu(tx->txop_ovf); + + dst->mid_ppdu_route_change = __le32_to_cpu(rx->mid_ppdu_route_change); + dst->status_rcvd = __le32_to_cpu(rx->status_rcvd); + dst->r0_frags = __le32_to_cpu(rx->r0_frags); + dst->r1_frags = __le32_to_cpu(rx->r1_frags); + dst->r2_frags = __le32_to_cpu(rx->r2_frags); + dst->r3_frags = __le32_to_cpu(rx->r3_frags); + dst->htt_msdus = __le32_to_cpu(rx->htt_msdus); + dst->htt_mpdus = __le32_to_cpu(rx->htt_mpdus); + dst->loc_msdus = __le32_to_cpu(rx->loc_msdus); + dst->loc_mpdus = __le32_to_cpu(rx->loc_mpdus); + dst->oversize_amsdu = __le32_to_cpu(rx->oversize_amsdu); + dst->phy_errs = __le32_to_cpu(rx->phy_errs); + dst->phy_err_drop = __le32_to_cpu(rx->phy_err_drop); + dst->mpdu_errs = __le32_to_cpu(rx->mpdu_errs); +} + +static void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, + struct ath10k_peer_stat *dst) +{ + ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); + dst->peer_rssi = __le32_to_cpu(src->peer_rssi); + dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate); +} + +static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, + struct sk_buff *skb, + struct ath10k_target_stats *stats) +{ + const struct wmi_stats_event *ev = (void *)skb->data; + u32 num_pdev_stats, num_vdev_stats, num_peer_stats; + int i; + + if (!skb_pull(skb, sizeof(*ev))) + return -EPROTO; + + num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); + num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); + num_peer_stats = __le32_to_cpu(ev->num_peer_stats); + + if (num_pdev_stats) { + const struct wmi_pdev_stats *src; + + src = (void *)skb->data; + if (!skb_pull(skb, sizeof(*src))) + return -EPROTO; + + ath10k_wmi_pull_pdev_stats(src, stats); + } + + /* fw doesn't implement vdev stats */ + + for (i = 0; i < num_peer_stats; i++) { + const struct wmi_peer_stats *src; + + src = (void *)skb->data; + if (!skb_pull(skb, sizeof(*src))) + return -EPROTO; + + ath10k_wmi_pull_peer_stats(src, &stats->peer_stat[i]); + } + + return 0; +} + +static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, + struct sk_buff *skb, + struct ath10k_target_stats *stats) +{ + const struct wmi_stats_event *ev = (void *)skb->data; + u32 num_pdev_stats, num_vdev_stats, num_peer_stats; + int i; + + if (!skb_pull(skb, sizeof(*ev))) + return -EPROTO; + + num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); + num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); + num_peer_stats = __le32_to_cpu(ev->num_peer_stats); + + if (num_pdev_stats) { + const struct wmi_10x_pdev_stats *src; + + src = (void *)skb->data; + if (!skb_pull(skb, sizeof(*src))) + return -EPROTO; + + ath10k_wmi_pull_pdev_stats(&src->old, stats); + + stats->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); + stats->rts_bad = __le32_to_cpu(src->rts_bad); + stats->rts_good = __le32_to_cpu(src->rts_good); + stats->fcs_bad = __le32_to_cpu(src->fcs_bad); + stats->no_beacons = __le32_to_cpu(src->no_beacons); + stats->mib_int_count = __le32_to_cpu(src->mib_int_count); + } + + /* fw doesn't implement vdev stats */ + + for (i = 0; i < num_peer_stats; i++) { + const struct wmi_10x_peer_stats *src; + + src = (void *)skb->data; + if (!skb_pull(skb, sizeof(*src))) + return -EPROTO; + + ath10k_wmi_pull_peer_stats(&src->old, &stats->peer_stat[i]); + + stats->peer_stat[i].peer_rx_rate = + __le32_to_cpu(src->peer_rx_rate); + } + + return 0; +} + +int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, + struct ath10k_target_stats *stats) +{ + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) + return ath10k_wmi_10x_pull_fw_stats(ar, skb, stats); + else + return ath10k_wmi_main_pull_fw_stats(ar, skb, stats); +} + static void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) { - struct wmi_stats_event *ev = (struct wmi_stats_event *)skb->data; - ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); - - ath10k_debug_read_target_stats(ar, ev); + ath10k_debug_read_target_stats(ar, skb); } static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 55d8317ce1a5..4ce8e3c9ca81 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -3021,7 +3021,7 @@ struct wmi_stats_event { * PDEV statistics * TODO: add all PDEV stats here */ -struct wmi_pdev_stats_old { +struct wmi_pdev_stats { __le32 chan_nf; /* Channel noise floor */ __le32 tx_frame_count; /* TX frame count */ __le32 rx_frame_count; /* RX frame count */ @@ -3032,15 +3032,8 @@ struct wmi_pdev_stats_old { struct wal_dbg_stats wal; /* WAL dbg stats */ } __packed; -struct wmi_pdev_stats_10x { - __le32 chan_nf; /* Channel noise floor */ - __le32 tx_frame_count; /* TX frame count */ - __le32 rx_frame_count; /* RX frame count */ - __le32 rx_clear_count; /* rx clear count */ - __le32 cycle_count; /* cycle count */ - __le32 phy_err_count; /* Phy error count */ - __le32 chan_tx_pwr; /* channel tx power */ - struct wal_dbg_stats wal; /* WAL dbg stats */ +struct wmi_10x_pdev_stats { + struct wmi_pdev_stats old; __le32 ack_rx_bad; __le32 rts_bad; __le32 rts_good; @@ -3061,16 +3054,14 @@ struct wmi_vdev_stats { * peer statistics. * TODO: add more stats */ -struct wmi_peer_stats_old { +struct wmi_peer_stats { struct wmi_mac_addr peer_macaddr; __le32 peer_rssi; __le32 peer_tx_rate; } __packed; -struct wmi_peer_stats_10x { - struct wmi_mac_addr peer_macaddr; - __le32 peer_rssi; - __le32 peer_tx_rate; +struct wmi_10x_peer_stats { + struct wmi_peer_stats old; __le32 peer_rx_rate; } __packed; @@ -4582,6 +4573,7 @@ struct wmi_svc_rdy_ev_arg { struct ath10k; struct ath10k_vif; +struct ath10k_target_stats; int ath10k_wmi_attach(struct ath10k *ar); void ath10k_wmi_detach(struct ath10k *ar); @@ -4653,5 +4645,7 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, enum wmi_force_fw_hang_type type, u32 delay_ms); int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); +int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, + struct ath10k_target_stats *stats); #endif /* _WMI_H_ */ -- GitLab From 60ef401aaec79c7d110ed825c083421e62e83f3c Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 25 Sep 2014 12:33:48 +0200 Subject: [PATCH 0137/9457] ath10k: rename fw_stats related stuff The naming was a bit inconsistent. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 11 +++++------ drivers/net/wireless/ath/ath10k/debug.c | 18 +++++++++--------- drivers/net/wireless/ath/ath10k/debug.h | 6 +++--- drivers/net/wireless/ath/ath10k/wmi.c | 12 ++++++------ drivers/net/wireless/ath/ath10k/wmi.h | 4 ++-- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 8a997b6e11c3..082a8dad9938 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -116,14 +116,14 @@ struct ath10k_wmi { struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS]; }; -struct ath10k_peer_stat { +struct ath10k_fw_stats_peer { u8 peer_macaddr[ETH_ALEN]; u32 peer_rssi; u32 peer_tx_rate; u32 peer_rx_rate; /* 10x only */ }; -struct ath10k_target_stats { +struct ath10k_fw_stats { /* PDEV stats */ s32 ch_noise_floor; u32 tx_frame_count; @@ -183,7 +183,7 @@ struct ath10k_target_stats { /* PEER STATS */ u8 peers; - struct ath10k_peer_stat peer_stat[TARGET_NUM_PEERS]; + struct ath10k_fw_stats_peer peer_stat[TARGET_NUM_PEERS]; /* TODO: Beacon filter stats */ @@ -292,11 +292,10 @@ struct ath10k_fw_crash_data { struct ath10k_debug { struct dentry *debugfs_phy; - struct ath10k_target_stats target_stats; + struct ath10k_fw_stats fw_stats; + struct completion fw_stats_complete; DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); - struct completion event_stats_compl; - unsigned long htt_stats_mask; struct delayed_work htt_stats_dwork; struct ath10k_dfs_stats dfs_stats; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 906319f49ca2..9e85533a8ba5 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -239,29 +239,29 @@ static const struct file_operations fops_wmi_services = { .llseek = default_llseek, }; -void ath10k_debug_read_target_stats(struct ath10k *ar, struct sk_buff *skb) +void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) { int ret; spin_lock_bh(&ar->data_lock); - ret = ath10k_wmi_pull_fw_stats(ar, skb, &ar->debug.target_stats); + ret = ath10k_wmi_pull_fw_stats(ar, skb, &ar->debug.fw_stats); if (ret) { ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); goto unlock; } - complete(&ar->debug.event_stats_compl); + complete(&ar->debug.fw_stats_complete); unlock: spin_unlock_bh(&ar->data_lock); } -static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, +static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath10k *ar = file->private_data; - struct ath10k_target_stats *fw_stats; + struct ath10k_fw_stats *fw_stats; char *buf = NULL; unsigned int len = 0, buf_len = 8000; ssize_t ret_cnt = 0; @@ -269,7 +269,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, int i; int ret; - fw_stats = &ar->debug.target_stats; + fw_stats = &ar->debug.fw_stats; mutex_lock(&ar->conf_mutex); @@ -286,7 +286,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, goto exit; } - left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ); + left = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 1*HZ); if (left <= 0) goto exit; @@ -445,7 +445,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, } static const struct file_operations fops_fw_stats = { - .read = ath10k_read_fw_stats, + .read = ath10k_fw_stats_read, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -1147,7 +1147,7 @@ int ath10k_debug_register(struct ath10k *ar) INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, ath10k_debug_htt_stats_dwork); - init_completion(&ar->debug.event_stats_compl); + init_completion(&ar->debug.fw_stats_complete); debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_stats); diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 8d8b68eb04e6..efbcd29fe9a1 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -55,7 +55,7 @@ void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, const void *service_map, size_t map_size); -void ath10k_debug_read_target_stats(struct ath10k *ar, struct sk_buff *skb); +void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); struct ath10k_fw_crash_data * ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); @@ -97,8 +97,8 @@ static inline void ath10k_debug_read_service_map(struct ath10k *ar, { } -static inline void ath10k_debug_read_target_stats(struct ath10k *ar, - struct sk_buff *skb) +static inline void ath10k_debug_fw_stats_process(struct ath10k *ar, + struct sk_buff *skb) { } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 8e2d0217686d..c4640aac55d5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1330,7 +1330,7 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) } static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, - struct ath10k_target_stats *dst) + struct ath10k_fw_stats *dst) { const struct wal_dbg_tx_stats *tx = &src->wal.tx; const struct wal_dbg_rx_stats *rx = &src->wal.rx; @@ -1383,7 +1383,7 @@ static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, } static void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, - struct ath10k_peer_stat *dst) + struct ath10k_fw_stats_peer *dst) { ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); dst->peer_rssi = __le32_to_cpu(src->peer_rssi); @@ -1392,7 +1392,7 @@ static void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, - struct ath10k_target_stats *stats) + struct ath10k_fw_stats *stats) { const struct wmi_stats_event *ev = (void *)skb->data; u32 num_pdev_stats, num_vdev_stats, num_peer_stats; @@ -1432,7 +1432,7 @@ static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, - struct ath10k_target_stats *stats) + struct ath10k_fw_stats *stats) { const struct wmi_stats_event *ev = (void *)skb->data; u32 num_pdev_stats, num_vdev_stats, num_peer_stats; @@ -1481,7 +1481,7 @@ static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, } int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, - struct ath10k_target_stats *stats) + struct ath10k_fw_stats *stats) { if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) return ath10k_wmi_10x_pull_fw_stats(ar, skb, stats); @@ -1493,7 +1493,7 @@ static void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) { ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); - ath10k_debug_read_target_stats(ar, skb); + ath10k_debug_fw_stats_process(ar, skb); } static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 4ce8e3c9ca81..6243dbe756ea 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -4573,7 +4573,7 @@ struct wmi_svc_rdy_ev_arg { struct ath10k; struct ath10k_vif; -struct ath10k_target_stats; +struct ath10k_fw_stats; int ath10k_wmi_attach(struct ath10k *ar); void ath10k_wmi_detach(struct ath10k *ar); @@ -4646,6 +4646,6 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, - struct ath10k_target_stats *stats); + struct ath10k_fw_stats *stats); #endif /* _WMI_H_ */ -- GitLab From fb2e9c0cc7e4e855c86e29f1c15b46d696a0c6c3 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 25 Sep 2014 12:33:49 +0200 Subject: [PATCH 0138/9457] ath10k: request fw_stats once on open Stats were requested and processed for each read call. This caused inconsistent readings. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 110 +++++++++++++++++------- 1 file changed, 79 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 9e85533a8ba5..1ca1fedcf25e 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -257,38 +257,35 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) spin_unlock_bh(&ar->data_lock); } -static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static int ath10k_fw_stats_request(struct ath10k *ar) { - struct ath10k *ar = file->private_data; - struct ath10k_fw_stats *fw_stats; - char *buf = NULL; - unsigned int len = 0, buf_len = 8000; - ssize_t ret_cnt = 0; - long left; - int i; int ret; - fw_stats = &ar->debug.fw_stats; - - mutex_lock(&ar->conf_mutex); - - if (ar->state != ATH10K_STATE_ON) - goto exit; - - buf = kzalloc(buf_len, GFP_KERNEL); - if (!buf) - goto exit; + lockdep_assert_held(&ar->conf_mutex); ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); if (ret) { - ath10k_warn(ar, "could not request stats (%d)\n", ret); - goto exit; + ath10k_warn(ar, "failed to fw stat request command: %d\n", ret); + return ret; } - left = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 1*HZ); - if (left <= 0) - goto exit; + ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 1*HZ); + if (ret <= 0) + return -ETIMEDOUT; + + return 0; +} + +/* FIXME: How to calculate the buffer size sanely? */ +#define ATH10K_FW_STATS_BUF_SIZE (1024*1024) + +static void ath10k_fw_stats_fill(struct ath10k *ar, + struct ath10k_fw_stats *fw_stats, + char *buf) +{ + unsigned int len = 0; + unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; + int i; spin_lock_bh(&ar->data_lock); len += scnprintf(buf + len, buf_len - len, "\n"); @@ -433,20 +430,71 @@ static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, } spin_unlock_bh(&ar->data_lock); - if (len > buf_len) - len = buf_len; + if (len >= buf_len) + buf[len - 1] = 0; + else + buf[len] = 0; +} - ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); +static int ath10k_fw_stats_open(struct inode *inode, struct file *file) +{ + struct ath10k *ar = inode->i_private; + void *buf = NULL; + int ret; + + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH10K_STATE_ON) { + ret = -ENETDOWN; + goto err_unlock; + } + + buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE); + if (!buf) { + ret = -ENOMEM; + goto err_unlock; + } + + ret = ath10k_fw_stats_request(ar); + if (ret) { + ath10k_warn(ar, "failed to request fw stats: %d\n", ret); + goto err_free; + } + + ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf); + file->private_data = buf; -exit: mutex_unlock(&ar->conf_mutex); - kfree(buf); - return ret_cnt; + return 0; + +err_free: + vfree(buf); + +err_unlock: + mutex_unlock(&ar->conf_mutex); + return ret; +} + +static int ath10k_fw_stats_release(struct inode *inode, struct file *file) +{ + vfree(file->private_data); + + return 0; +} + +static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + const char *buf = file->private_data; + unsigned int len = strlen(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } static const struct file_operations fops_fw_stats = { + .open = ath10k_fw_stats_open, + .release = ath10k_fw_stats_release, .read = ath10k_fw_stats_read, - .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, }; -- GitLab From 5326849a866991eef86452fb6a108dd320b92173 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 25 Sep 2014 12:33:50 +0200 Subject: [PATCH 0139/9457] ath10k: fix fw stats processing If stat data exceeds wmi-htc buffer limits firmware splits it into many wmi stats update events which are delivered in a ping-pong fashion triggered by wmi stats request command. Since there's only an implicit start-of-data and no end-of-data indications the driver has to perform some trickery to get complete stat data. kvalo: use %zu to fix a compiler warning and fix a typo in a comment Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 19 +- drivers/net/wireless/ath/ath10k/debug.c | 273 ++++++++++++++++++------ drivers/net/wireless/ath/ath10k/wmi.c | 55 +++-- 3 files changed, 252 insertions(+), 95 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 082a8dad9938..674e38c219e6 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -117,13 +117,17 @@ struct ath10k_wmi { }; struct ath10k_fw_stats_peer { + struct list_head list; + u8 peer_macaddr[ETH_ALEN]; u32 peer_rssi; u32 peer_tx_rate; u32 peer_rx_rate; /* 10x only */ }; -struct ath10k_fw_stats { +struct ath10k_fw_stats_pdev { + struct list_head list; + /* PDEV stats */ s32 ch_noise_floor; u32 tx_frame_count; @@ -178,15 +182,11 @@ struct ath10k_fw_stats { s32 phy_errs; s32 phy_err_drop; s32 mpdu_errs; +}; - /* VDEV STATS */ - - /* PEER STATS */ - u8 peers; - struct ath10k_fw_stats_peer peer_stat[TARGET_NUM_PEERS]; - - /* TODO: Beacon filter stats */ - +struct ath10k_fw_stats { + struct list_head pdevs; + struct list_head peers; }; struct ath10k_dfs_stats { @@ -294,6 +294,7 @@ struct ath10k_debug { struct ath10k_fw_stats fw_stats; struct completion fw_stats_complete; + bool fw_stats_done; DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); unsigned long htt_stats_mask; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 1ca1fedcf25e..680d5088b6f3 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -239,39 +239,154 @@ static const struct file_operations fops_wmi_services = { .llseek = default_llseek, }; +static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head) +{ + struct ath10k_fw_stats_pdev *i, *tmp; + + list_for_each_entry_safe(i, tmp, head, list) { + list_del(&i->list); + kfree(i); + } +} + +static void ath10k_debug_fw_stats_peers_free(struct list_head *head) +{ + struct ath10k_fw_stats_peer *i, *tmp; + + list_for_each_entry_safe(i, tmp, head, list) { + list_del(&i->list); + kfree(i); + } +} + +static void ath10k_debug_fw_stats_reset(struct ath10k *ar) +{ + spin_lock_bh(&ar->data_lock); + ar->debug.fw_stats_done = false; + ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); + ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); + spin_unlock_bh(&ar->data_lock); +} + +static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head) +{ + struct ath10k_fw_stats_peer *i; + size_t num = 0; + + list_for_each_entry(i, head, list) + ++num; + + return num; +} + void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) { + struct ath10k_fw_stats stats = {}; + bool is_start, is_started, is_end; + size_t num_peers; int ret; - spin_lock_bh(&ar->data_lock); + INIT_LIST_HEAD(&stats.pdevs); + INIT_LIST_HEAD(&stats.peers); - ret = ath10k_wmi_pull_fw_stats(ar, skb, &ar->debug.fw_stats); + spin_lock_bh(&ar->data_lock); + ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); if (ret) { ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); goto unlock; } + /* Stat data may exceed htc-wmi buffer limit. In such case firmware + * splits the stats data and delivers it in a ping-pong fashion of + * request cmd-update event. + * + * However there is no explicit end-of-data. Instead start-of-data is + * used as an implicit one. This works as follows: + * a) discard stat update events until one with pdev stats is + * delivered - this skips session started at end of (b) + * b) consume stat update events until another one with pdev stats is + * delivered which is treated as end-of-data and is itself discarded + */ + + if (ar->debug.fw_stats_done) { + ath10k_warn(ar, "received unsolicited stats update event\n"); + goto free; + } + + num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); + is_start = (list_empty(&ar->debug.fw_stats.pdevs) && + !list_empty(&stats.pdevs)); + is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && + !list_empty(&stats.pdevs)); + + if (is_start) + list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); + + if (is_end) + ar->debug.fw_stats_done = true; + + is_started = !list_empty(&ar->debug.fw_stats.pdevs); + + if (is_started && !is_end) { + if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) { + /* Although this is unlikely impose a sane limit to + * prevent firmware from DoS-ing the host. + */ + ath10k_warn(ar, "dropping fw peer stats\n"); + goto free; + } + + list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); + } + complete(&ar->debug.fw_stats_complete); +free: + /* In some cases lists have been spliced and cleared. Free up + * resources if that is not the case. + */ + ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); + ath10k_debug_fw_stats_peers_free(&stats.peers); + unlock: spin_unlock_bh(&ar->data_lock); } -static int ath10k_fw_stats_request(struct ath10k *ar) +static int ath10k_debug_fw_stats_request(struct ath10k *ar) { + unsigned long timeout; int ret; lockdep_assert_held(&ar->conf_mutex); - ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); - if (ret) { - ath10k_warn(ar, "failed to fw stat request command: %d\n", ret); - return ret; - } + timeout = jiffies + msecs_to_jiffies(1*HZ); + + ath10k_debug_fw_stats_reset(ar); + + for (;;) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + reinit_completion(&ar->debug.fw_stats_complete); + + ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); + if (ret) { + ath10k_warn(ar, "could not request stats (%d)\n", ret); + return ret; + } - ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 1*HZ); - if (ret <= 0) - return -ETIMEDOUT; + ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, + 1*HZ); + if (ret <= 0) + return -ETIMEDOUT; + + spin_lock_bh(&ar->data_lock); + if (ar->debug.fw_stats_done) { + spin_unlock_bh(&ar->data_lock); + break; + } + spin_unlock_bh(&ar->data_lock); + } return 0; } @@ -285,9 +400,21 @@ static void ath10k_fw_stats_fill(struct ath10k *ar, { unsigned int len = 0; unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; - int i; + const struct ath10k_fw_stats_pdev *pdev; + const struct ath10k_fw_stats_peer *peer; + size_t num_peers; spin_lock_bh(&ar->data_lock); + + pdev = list_first_entry_or_null(&fw_stats->pdevs, + struct ath10k_fw_stats_pdev, list); + if (!pdev) { + ath10k_warn(ar, "failed to get pdev stats\n"); + goto unlock; + } + + num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); + len += scnprintf(buf + len, buf_len - len, "\n"); len += scnprintf(buf + len, buf_len - len, "%30s\n", "ath10k PDEV stats"); @@ -295,29 +422,29 @@ static void ath10k_fw_stats_fill(struct ath10k *ar, "================="); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Channel noise floor", fw_stats->ch_noise_floor); + "Channel noise floor", pdev->ch_noise_floor); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "Channel TX power", fw_stats->chan_tx_power); + "Channel TX power", pdev->chan_tx_power); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "TX frame count", fw_stats->tx_frame_count); + "TX frame count", pdev->tx_frame_count); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RX frame count", fw_stats->rx_frame_count); + "RX frame count", pdev->rx_frame_count); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RX clear count", fw_stats->rx_clear_count); + "RX clear count", pdev->rx_clear_count); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "Cycle count", fw_stats->cycle_count); + "Cycle count", pdev->cycle_count); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "PHY error count", fw_stats->phy_err_count); + "PHY error count", pdev->phy_err_count); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RTS bad count", fw_stats->rts_bad); + "RTS bad count", pdev->rts_bad); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RTS good count", fw_stats->rts_good); + "RTS good count", pdev->rts_good); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "FCS bad count", fw_stats->fcs_bad); + "FCS bad count", pdev->fcs_bad); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "No beacon count", fw_stats->no_beacons); + "No beacon count", pdev->no_beacons); len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "MIB int count", fw_stats->mib_int_count); + "MIB int count", pdev->mib_int_count); len += scnprintf(buf + len, buf_len - len, "\n"); len += scnprintf(buf + len, buf_len - len, "%30s\n", @@ -326,51 +453,51 @@ static void ath10k_fw_stats_fill(struct ath10k *ar, "================="); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HTT cookies queued", fw_stats->comp_queued); + "HTT cookies queued", pdev->comp_queued); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HTT cookies disp.", fw_stats->comp_delivered); + "HTT cookies disp.", pdev->comp_delivered); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDU queued", fw_stats->msdu_enqued); + "MSDU queued", pdev->msdu_enqued); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU queued", fw_stats->mpdu_enqued); + "MPDU queued", pdev->mpdu_enqued); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs dropped", fw_stats->wmm_drop); + "MSDUs dropped", pdev->wmm_drop); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Local enqued", fw_stats->local_enqued); + "Local enqued", pdev->local_enqued); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Local freed", fw_stats->local_freed); + "Local freed", pdev->local_freed); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HW queued", fw_stats->hw_queued); + "HW queued", pdev->hw_queued); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PPDUs reaped", fw_stats->hw_reaped); + "PPDUs reaped", pdev->hw_reaped); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Num underruns", fw_stats->underrun); + "Num underruns", pdev->underrun); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PPDUs cleaned", fw_stats->tx_abort); + "PPDUs cleaned", pdev->tx_abort); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs requed", fw_stats->mpdus_requed); + "MPDUs requed", pdev->mpdus_requed); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Excessive retries", fw_stats->tx_ko); + "Excessive retries", pdev->tx_ko); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HW rate", fw_stats->data_rc); + "HW rate", pdev->data_rc); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Sched self tiggers", fw_stats->self_triggers); + "Sched self tiggers", pdev->self_triggers); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "Dropped due to SW retries", - fw_stats->sw_retry_failure); + pdev->sw_retry_failure); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "Illegal rate phy errors", - fw_stats->illgl_rate_phy_err); + pdev->illgl_rate_phy_err); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Pdev continous xretry", fw_stats->pdev_cont_xretry); + "Pdev continous xretry", pdev->pdev_cont_xretry); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "TX timeout", fw_stats->pdev_tx_timeout); + "TX timeout", pdev->pdev_tx_timeout); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PDEV resets", fw_stats->pdev_resets); + "PDEV resets", pdev->pdev_resets); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY underrun", fw_stats->phy_underrun); + "PHY underrun", pdev->phy_underrun); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU is more than txop limit", fw_stats->txop_ovf); + "MPDU is more than txop limit", pdev->txop_ovf); len += scnprintf(buf + len, buf_len - len, "\n"); len += scnprintf(buf + len, buf_len - len, "%30s\n", @@ -380,54 +507,53 @@ static void ath10k_fw_stats_fill(struct ath10k *ar, len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", "Mid PPDU route change", - fw_stats->mid_ppdu_route_change); + pdev->mid_ppdu_route_change); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Tot. number of statuses", fw_stats->status_rcvd); + "Tot. number of statuses", pdev->status_rcvd); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 0", fw_stats->r0_frags); + "Extra frags on rings 0", pdev->r0_frags); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 1", fw_stats->r1_frags); + "Extra frags on rings 1", pdev->r1_frags); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 2", fw_stats->r2_frags); + "Extra frags on rings 2", pdev->r2_frags); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 3", fw_stats->r3_frags); + "Extra frags on rings 3", pdev->r3_frags); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs delivered to HTT", fw_stats->htt_msdus); + "MSDUs delivered to HTT", pdev->htt_msdus); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs delivered to HTT", fw_stats->htt_mpdus); + "MPDUs delivered to HTT", pdev->htt_mpdus); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs delivered to stack", fw_stats->loc_msdus); + "MSDUs delivered to stack", pdev->loc_msdus); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs delivered to stack", fw_stats->loc_mpdus); + "MPDUs delivered to stack", pdev->loc_mpdus); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Oversized AMSUs", fw_stats->oversize_amsdu); + "Oversized AMSUs", pdev->oversize_amsdu); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY errors", fw_stats->phy_errs); + "PHY errors", pdev->phy_errs); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY errors drops", fw_stats->phy_err_drop); + "PHY errors drops", pdev->phy_err_drop); len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs); + "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n", - "ath10k PEER stats", fw_stats->peers); + len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", + "ath10k PEER stats", num_peers); len += scnprintf(buf + len, buf_len - len, "%30s\n\n", "================="); - for (i = 0; i < fw_stats->peers; i++) { + list_for_each_entry(peer, &fw_stats->peers, list) { len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", - "Peer MAC address", - fw_stats->peer_stat[i].peer_macaddr); + "Peer MAC address", peer->peer_macaddr); len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer RSSI", fw_stats->peer_stat[i].peer_rssi); + "Peer RSSI", peer->peer_rssi); len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer TX rate", - fw_stats->peer_stat[i].peer_tx_rate); + "Peer TX rate", peer->peer_tx_rate); len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer RX rate", - fw_stats->peer_stat[i].peer_rx_rate); + "Peer RX rate", peer->peer_rx_rate); len += scnprintf(buf + len, buf_len - len, "\n"); } + +unlock: spin_unlock_bh(&ar->data_lock); if (len >= buf_len) @@ -455,7 +581,7 @@ static int ath10k_fw_stats_open(struct inode *inode, struct file *file) goto err_unlock; } - ret = ath10k_fw_stats_request(ar); + ret = ath10k_debug_fw_stats_request(ar); if (ret) { ath10k_warn(ar, "failed to request fw stats: %d\n", ret); goto err_free; @@ -1172,6 +1298,9 @@ int ath10k_debug_create(struct ath10k *ar) if (!ar->debug.fw_crash_data) return -ENOMEM; + INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); + INIT_LIST_HEAD(&ar->debug.fw_stats.peers); + return 0; } @@ -1179,6 +1308,8 @@ void ath10k_debug_destroy(struct ath10k *ar) { vfree(ar->debug.fw_crash_data); ar->debug.fw_crash_data = NULL; + + ath10k_debug_fw_stats_reset(ar); } int ath10k_debug_register(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c4640aac55d5..f65032f9ccee 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1330,7 +1330,7 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) } static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, - struct ath10k_fw_stats *dst) + struct ath10k_fw_stats_pdev *dst) { const struct wal_dbg_tx_stats *tx = &src->wal.tx; const struct wal_dbg_rx_stats *rx = &src->wal.rx; @@ -1405,26 +1405,38 @@ static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); num_peer_stats = __le32_to_cpu(ev->num_peer_stats); - if (num_pdev_stats) { + for (i = 0; i < num_pdev_stats; i++) { const struct wmi_pdev_stats *src; + struct ath10k_fw_stats_pdev *dst; src = (void *)skb->data; if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - ath10k_wmi_pull_pdev_stats(src, stats); + dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + if (!dst) + continue; + + ath10k_wmi_pull_pdev_stats(src, dst); + list_add_tail(&dst->list, &stats->pdevs); } /* fw doesn't implement vdev stats */ for (i = 0; i < num_peer_stats; i++) { const struct wmi_peer_stats *src; + struct ath10k_fw_stats_peer *dst; src = (void *)skb->data; if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - ath10k_wmi_pull_peer_stats(src, &stats->peer_stat[i]); + dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + if (!dst) + continue; + + ath10k_wmi_pull_peer_stats(src, dst); + list_add_tail(&dst->list, &stats->peers); } return 0; @@ -1445,36 +1457,49 @@ static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); num_peer_stats = __le32_to_cpu(ev->num_peer_stats); - if (num_pdev_stats) { + for (i = 0; i < num_pdev_stats; i++) { const struct wmi_10x_pdev_stats *src; + struct ath10k_fw_stats_pdev *dst; src = (void *)skb->data; if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - ath10k_wmi_pull_pdev_stats(&src->old, stats); + dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + if (!dst) + continue; + + ath10k_wmi_pull_pdev_stats(&src->old, dst); + + dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); + dst->rts_bad = __le32_to_cpu(src->rts_bad); + dst->rts_good = __le32_to_cpu(src->rts_good); + dst->fcs_bad = __le32_to_cpu(src->fcs_bad); + dst->no_beacons = __le32_to_cpu(src->no_beacons); + dst->mib_int_count = __le32_to_cpu(src->mib_int_count); - stats->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); - stats->rts_bad = __le32_to_cpu(src->rts_bad); - stats->rts_good = __le32_to_cpu(src->rts_good); - stats->fcs_bad = __le32_to_cpu(src->fcs_bad); - stats->no_beacons = __le32_to_cpu(src->no_beacons); - stats->mib_int_count = __le32_to_cpu(src->mib_int_count); + list_add_tail(&dst->list, &stats->pdevs); } /* fw doesn't implement vdev stats */ for (i = 0; i < num_peer_stats; i++) { const struct wmi_10x_peer_stats *src; + struct ath10k_fw_stats_peer *dst; src = (void *)skb->data; if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - ath10k_wmi_pull_peer_stats(&src->old, &stats->peer_stat[i]); + dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + if (!dst) + continue; + + ath10k_wmi_pull_peer_stats(&src->old, dst); + + dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); - stats->peer_stat[i].peer_rx_rate = - __le32_to_cpu(src->peer_rx_rate); + list_add_tail(&dst->list, &stats->peers); } return 0; -- GitLab From 1d73c2a8f218be3e8b6aa884740fc67110660b54 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 24 Sep 2014 19:50:59 -0400 Subject: [PATCH 0140/9457] drm/i915: Minimize the huge amount of unecessary fbc sw cache clean. The sw cache clean on BDW is a tempoorary workaround because we cannot set cache clean on blt ring with risk of hungs. So we are doing the cache clean on sw. However we are doing much more than needed. Not only when using blt ring. So, with this extra w/a we minimize the ammount of cache cleans and call it only on same cases that it was being called on gen7. The traditional FBC Cache clean happens over LRI on BLT ring when there is a frontbuffer touch happening. frontbuffer tracking set fbc_dirty variable to let BLT flush that it must clean FBC cache. fbc.need_sw_cache_clean works in the opposite information direction of ring->fbc_dirty telling software on frontbuffer tracking to perform the cache clean on sw side. v2: Clean it a little bit and fully check for Broadwell instead of gen8. v3: Rebase after frontbuffer organization. v4: Wiggle confused me. So fixing v3! Cc: Daniel Vetter Cc: Paulo Zanoni Reviewed-by: Paulo Zanoni Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 10 +++++++++- drivers/gpu/drm/i915/intel_frontbuffer.c | 6 ++++-- drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 9 +++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 999bd57cab65..cccb7767e837 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -666,6 +666,14 @@ struct i915_fbc { * possible. */ bool enabled; + /* On gen8 some rings cannont perform fbc clean operation so for now + * we are doing this on SW with mmio. + * This variable works in the opposite information direction + * of ring->fbc_dirty telling software on frontbuffer tracking + * to perform the cache clean on sw side. + */ + bool need_sw_cache_clean; + struct intel_fbc_work { struct delayed_work work; struct drm_crtc *crtc; @@ -2825,7 +2833,7 @@ extern void intel_modeset_setup_hw_state(struct drm_device *dev, extern void i915_redisable_vga(struct drm_device *dev); extern void i915_redisable_vga_power_on(struct drm_device *dev); extern bool intel_fbc_enabled(struct drm_device *dev); -extern void gen8_fbc_sw_flush(struct drm_device *dev, u32 value); +extern void bdw_fbc_sw_flush(struct drm_device *dev, u32 value); extern void intel_disable_fbc(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_init_pch_refclk(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index f74744c091cb..7eb74a62117f 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -189,8 +189,10 @@ void intel_frontbuffer_flush(struct drm_device *dev, * needs to be reworked into a proper frontbuffer tracking scheme like * psr employs. */ - if (IS_BROADWELL(dev)) - gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); + if (dev_priv->fbc.need_sw_cache_clean) { + dev_priv->fbc.need_sw_cache_clean = false; + bdw_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); + } } /** diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6b416201240f..011892d5356e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -356,7 +356,7 @@ bool intel_fbc_enabled(struct drm_device *dev) return dev_priv->fbc.enabled; } -void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) +void bdw_fbc_sw_flush(struct drm_device *dev, u32 value) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 922d6bc1a1b3..620a89dc868b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2237,6 +2237,7 @@ static int gen6_ring_flush(struct intel_engine_cs *ring, u32 invalidate, u32 flush) { struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; uint32_t cmd; int ret; @@ -2267,8 +2268,12 @@ static int gen6_ring_flush(struct intel_engine_cs *ring, } intel_ring_advance(ring); - if (IS_GEN7(dev) && !invalidate && flush) - return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN); + if (!invalidate && flush) { + if (IS_GEN7(dev)) + return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN); + else if (IS_BROADWELL(dev)) + dev_priv->fbc.need_sw_cache_clean = true; + } return 0; } -- GitLab From 8d7f4fe9f561f4e3253478332192d88f6f135c41 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 24 Sep 2014 18:16:58 -0400 Subject: [PATCH 0141/9457] drm/i915: Make sure PSR is ready for been re-enabled. Let's make sure PSR is propperly disabled before to re-enabled it. According to Spec, after disabled PSR CTL, the Idle state might occur up to 24ms, that is one full frame time (1/refresh rate), plus SRD exit training time (max of 6ms), plus SRD aux channel handshake (max of 1.5ms). So if something went wrong PSR will be disabled until next full enable/disable setup. v2: The 24ms above takes in account 16ms for refresh rate on 60Hz mode. However on low frequency modes this can take longer. So let's use 50ms for safeness. v3: Move wait out of psr.lock critical area. Cc: Daniel Vetter Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c5ec821fa5fb..6f42d9568049 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2204,6 +2204,17 @@ static void intel_edp_psr_work(struct work_struct *work) container_of(work, typeof(*dev_priv), psr.work.work); struct intel_dp *intel_dp = dev_priv->psr.enabled; + /* We have to make sure PSR is ready for re-enable + * otherwise it keeps disabled until next full enable/disable cycle. + * PSR might take some time to get fully disabled + * and be ready for re-enable. + */ + if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) & + EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { + DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); + return; + } + mutex_lock(&dev_priv->psr.lock); intel_dp = dev_priv->psr.enabled; -- GitLab From 17b523ba5c3835e6d595c9d7d6a45177b379efcd Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 24 Sep 2014 20:32:43 -0400 Subject: [PATCH 0142/9457] drm/i915: Broadwell DDI Buffer translation changed to give better margin. Reference: Predator r73977 / HSD 4394389 Cc: Arthur Runyan Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Arthur Runyan Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b63d4fa204a3..e3cd159536ec 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -95,8 +95,8 @@ static const struct ddi_buf_trans bdw_ddi_translations_dp[] = { { 0x00BEFFFF, 0x00140006 }, { 0x80B2CFFF, 0x001B0002 }, { 0x00FFFFFF, 0x000E000A }, - { 0x00D75FFF, 0x00180004 }, - { 0x80CB2FFF, 0x001B0002 }, + { 0x00DB6FFF, 0x00160005 }, + { 0x00C71FFF, 0x001A0002 }, { 0x00F7DFFF, 0x00180004 }, { 0x80D75FFF, 0x001B0002 }, }; -- GitLab From 6805b2a7434daaede07969ed5877300b2a0783e7 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 25 Sep 2014 12:28:32 -0400 Subject: [PATCH 0143/9457] drm/i915: Broadwell DDI Buffer translation - more tuning BDW display - DP buffer translation values changed to give better margin. Further change to entry 6; set dword 0 bit 31=1. Both changes were approved already but this one didn't landed BSpec yet this is why it is in a separated patch. Making reviewer's life easier. Also alowing separated tests and any future bisect that might be needed. Reference: Predator r74080 / HSD 4394389 v2: Arthur noticed I was changing the wrong bit. Cc: Arthur Runyan Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Arthur Runyan Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e3cd159536ec..295827811433 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -96,7 +96,7 @@ static const struct ddi_buf_trans bdw_ddi_translations_dp[] = { { 0x80B2CFFF, 0x001B0002 }, { 0x00FFFFFF, 0x000E000A }, { 0x00DB6FFF, 0x00160005 }, - { 0x00C71FFF, 0x001A0002 }, + { 0x80C71FFF, 0x001A0002 }, { 0x00F7DFFF, 0x00180004 }, { 0x80D75FFF, 0x001B0002 }, }; -- GitLab From ad9dc91b6e21266bfc6f466db4b95e10211f31ee Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 16 Sep 2014 19:18:12 -0400 Subject: [PATCH 0144/9457] drm/i915: Fix Sink CRC In some cases like when PSR just got enabled the panel need more vblank times to calculate CRC. I figured that out with the new PSR test cases facing some cases that I had a green screen but a blank CRC. Even with 2 vblank waits on kernel + 2 vblank waits on test case. So let's give up to 6 vblank wait time. However we now check for TEST_CRC_COUNT that shows when panel finished to calculate CRC and has it ready. v2: Jani pointed out attempts decrements was wrong and should never reach the error condition. And Daniel pointed out that EIO is more appropriated than EGAIN. Also I realized that I have to read test_crc_count after setting test_sink v3: Rebase and adding error message Cc: Todd Previte Cc: Daniel Vetter Cc: Jani Nikula Signed-off-by: Rodrigo Vivi Reviewed-by: Todd Previte Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 23 +++++++++++++++++------ include/drm/drm_dp_helper.h | 5 +++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6f42d9568049..3caac0f01265 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3807,21 +3807,32 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) struct drm_device *dev = intel_dig_port->base.base.dev; struct intel_crtc *intel_crtc = to_intel_crtc(intel_dig_port->base.base.crtc); - u8 buf[1]; + u8 buf; + int test_crc_count; + int attempts = 6; - if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, buf) < 0) + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) return -EIO; - if (!(buf[0] & DP_TEST_CRC_SUPPORTED)) + if (!(buf & DP_TEST_CRC_SUPPORTED)) return -ENOTTY; if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, DP_TEST_SINK_START) < 0) return -EIO; - /* Wait 2 vblanks to be sure we will have the correct CRC value */ - intel_wait_for_vblank(dev, intel_crtc->pipe); - intel_wait_for_vblank(dev, intel_crtc->pipe); + drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf); + test_crc_count = buf & DP_TEST_COUNT_MASK; + + do { + drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf); + intel_wait_for_vblank(dev, intel_crtc->pipe); + } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); + + if (attempts == 0) { + DRM_ERROR("Panel is unable to calculate CRC after 6 vblanks\n"); + return -EIO; + } if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) return -EIO; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 9305c718d789..8edeed00c082 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -303,7 +303,8 @@ #define DP_TEST_CRC_B_CB 0x244 #define DP_TEST_SINK_MISC 0x246 -#define DP_TEST_CRC_SUPPORTED (1 << 5) +# define DP_TEST_CRC_SUPPORTED (1 << 5) +# define DP_TEST_COUNT_MASK 0x7 #define DP_TEST_RESPONSE 0x260 # define DP_TEST_ACK (1 << 0) @@ -313,7 +314,7 @@ #define DP_TEST_EDID_CHECKSUM 0x261 #define DP_TEST_SINK 0x270 -#define DP_TEST_SINK_START (1 << 0) +# define DP_TEST_SINK_START (1 << 0) #define DP_PAYLOAD_TABLE_UPDATE_STATUS 0x2c0 /* 1.2 MST */ # define DP_PAYLOAD_TABLE_UPDATED (1 << 0) -- GitLab From a0fcbd95354e5ac2400be74077cc668c91429ea7 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 19 Sep 2014 20:16:26 -0400 Subject: [PATCH 0145/9457] drm/i915: Add IS_BDW_GT3 macro. It will be usefull to specify w/a that affects only BDW GT3. Signed-off-by: Rodrigo Vivi Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cccb7767e837..8f05258ff49b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2111,6 +2111,8 @@ struct drm_i915_cmd_table { ((INTEL_DEVID(dev) & 0xf) == 0x2 || \ (INTEL_DEVID(dev) & 0xf) == 0x6 || \ (INTEL_DEVID(dev) & 0xf) == 0xe)) +#define IS_BDW_GT3(dev) (IS_BROADWELL(dev) && \ + (INTEL_DEVID(dev) & 0x00F0) == 0x0020) #define IS_HSW_ULT(dev) (IS_HASWELL(dev) && \ (INTEL_DEVID(dev) & 0xFF00) == 0x0A00) #define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) -- GitLab From da09654d777c361006f6ea3452f8de4a374d5783 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 19 Sep 2014 20:16:27 -0400 Subject: [PATCH 0146/9457] drm/i915/bdw: WaDisableFenceDestinationToSLM This WA affect BDW GT3 pre-production steppings. Signed-off-by: Rodrigo Vivi Reviewed-by: Mika Kuoppala [danvet: Don't mention steppings ...] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ad8179b40d19..124ea60c1386 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4836,6 +4836,7 @@ enum punit_power_well { /* GEN8 chicken */ #define HDC_CHICKEN0 0x7300 #define HDC_FORCE_NON_COHERENT (1<<4) +#define HDC_FENCE_DEST_SLM_DISABLE (1<<14) /* WaCatErrorRejectionIssue */ #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 620a89dc868b..c21aaad55982 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -740,8 +740,12 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) * workaround for for a possible hang in the unlikely event a TLB * invalidation occurs during a PSD flush. */ + /* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */ intel_ring_emit_wa(ring, HDC_CHICKEN0, - _MASKED_BIT_ENABLE(HDC_FORCE_NON_COHERENT)); + _MASKED_BIT_ENABLE(HDC_FORCE_NON_COHERENT | + (IS_BDW_GT3(dev) ? + HDC_FENCE_DEST_SLM_DISABLE : 0) + )); /* Wa4x4STCOptimizationDisable:bdw */ intel_ring_emit_wa(ring, CACHE_MODE_1, -- GitLab From ce31d9f4fc05964f6c0dd3a8661dc1a1d843a1e2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 29 Sep 2014 18:29:52 -0400 Subject: [PATCH 0147/9457] drm/i915: preserve other DP_TEST_SINK bits. Sink crc was implemented based on dp 1.1 spec that had all TEST_SINK bits reserved reading all 0s. But when reviewing my latest changes on sink crc Todd warned me that on new specs we have other valid bits on this reg that we might want to preserve. Cc: Todd Previte Signed-off-by: Rodrigo Vivi Reviewed-by: Todd Previte Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3caac0f01265..342d624f8312 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3817,8 +3817,9 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) if (!(buf & DP_TEST_CRC_SUPPORTED)) return -ENOTTY; + drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf); if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, - DP_TEST_SINK_START) < 0) + buf | DP_TEST_SINK_START) < 0) return -EIO; drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf); @@ -3837,7 +3838,10 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) return -EIO; - drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, 0); + drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf); + drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, + buf & ~DP_TEST_SINK_START); + return 0; } -- GitLab From f51dbe737441b758628be4763d0c3bcad4fe000f Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 29 Sep 2014 14:41:46 +0300 Subject: [PATCH 0148/9457] ath10k: add firmware crash counters Add three counters related to firmware crashes or resets. Usage: # cat /sys/kernel/debug/ieee80211/phy0/ath10k/fw_reset_stats fw_crash_counter 2 fw_warm_reset_counter 43 fw_cold_reset_counter 0 # kvalo: split into it's own patch, add debugfs file and add locking Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 7 ++++ drivers/net/wireless/ath/ath10k/debug.c | 44 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/pci.c | 14 ++++++++ 3 files changed, 65 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 674e38c219e6..5a1dc98375e1 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -563,6 +563,13 @@ struct ath10k { bool utf_monitor; } testmode; + struct { + /* protected by data_lock */ + u32 fw_crash_counter; + u32 fw_warm_reset_counter; + u32 fw_cold_reset_counter; + } stats; + /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 680d5088b6f3..8d3db1c3f4a8 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -625,6 +625,47 @@ static const struct file_operations fops_fw_stats = { .llseek = default_llseek, }; +static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + int ret, len, buf_len; + char *buf; + + buf_len = 500; + buf = kmalloc(buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + spin_lock_bh(&ar->data_lock); + + len = 0; + len += scnprintf(buf + len, buf_len - len, + "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter); + len += scnprintf(buf + len, buf_len - len, + "fw_warm_reset_counter\t\t%d\n", + ar->stats.fw_warm_reset_counter); + len += scnprintf(buf + len, buf_len - len, + "fw_cold_reset_counter\t\t%d\n", + ar->stats.fw_cold_reset_counter); + + spin_unlock_bh(&ar->data_lock); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + + kfree(buf); + + return ret; +} + +static const struct file_operations fops_fw_reset_stats = { + .open = simple_open, + .read = ath10k_debug_fw_reset_stats_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + /* This is a clean assert crash in firmware. */ static int ath10k_debug_fw_assert(struct ath10k *ar) { @@ -1331,6 +1372,9 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_stats); + debugfs_create_file("fw_reset_stats", S_IRUSR, ar->debug.debugfs_phy, + ar, &fops_fw_reset_stats); + debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_wmi_services); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index ae961c6ff74e..8a04904cccee 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1006,6 +1006,8 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) spin_lock_bh(&ar->data_lock); + ar->stats.fw_crash_counter++; + crash_data = ath10k_debug_get_new_fw_crash_data(ar); if (crash_data) @@ -1692,6 +1694,12 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset\n"); + spin_lock_bh(&ar->data_lock); + + ar->stats.fw_warm_reset_counter++; + + spin_unlock_bh(&ar->data_lock); + /* debug */ val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_CAUSE_ADDRESS); @@ -2308,6 +2316,12 @@ static int ath10k_pci_cold_reset(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n"); + spin_lock_bh(&ar->data_lock); + + ar->stats.fw_cold_reset_counter++; + + spin_unlock_bh(&ar->data_lock); + /* Put Target, including PCIe, into RESET. */ val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); val |= 1; -- GitLab From 6cddcc7ac215a3e988ec2cbf303fb0a39220dc3b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 29 Sep 2014 14:41:46 +0300 Subject: [PATCH 0149/9457] ath10k: support ethtool stats Add support for reading firmware stats through the ethtool API. This may be easier for applications to manipulate compared to parsing a text based debugfs file. kvalo: remove unneeded ifdefs, call ath10k_debug_fw_stats_request() and added simple error handling Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 160 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/debug.h | 13 ++ drivers/net/wireless/ath/ath10k/mac.c | 3 + 3 files changed, 176 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 8d3db1c3f4a8..2bb894f31337 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1130,6 +1130,166 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file, return ret; } +/* TODO: Would be nice to always support ethtool stats, would need to + * move the stats storage out of ath10k_debug, or always have ath10k_debug + * struct available.. + */ + +/* This generally cooresponds to the debugfs fw_stats file */ +static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = { + "tx_pkts_nic", + "tx_bytes_nic", + "rx_pkts_nic", + "rx_bytes_nic", + "d_noise_floor", + "d_cycle_count", + "d_phy_error", + "d_rts_bad", + "d_rts_good", + "d_tx_power", /* in .5 dbM I think */ + "d_rx_crc_err", /* fcs_bad */ + "d_no_beacon", + "d_tx_mpdus_queued", + "d_tx_msdu_queued", + "d_tx_msdu_dropped", + "d_local_enqued", + "d_local_freed", + "d_tx_ppdu_hw_queued", + "d_tx_ppdu_reaped", + "d_tx_fifo_underrun", + "d_tx_ppdu_abort", + "d_tx_mpdu_requed", + "d_tx_excessive_retries", + "d_tx_hw_rate", + "d_tx_dropped_sw_retries", + "d_tx_illegal_rate", + "d_tx_continuous_xretries", + "d_tx_timeout", + "d_tx_mpdu_txop_limit", + "d_pdev_resets", + "d_rx_mid_ppdu_route_change", + "d_rx_status", + "d_rx_extra_frags_ring0", + "d_rx_extra_frags_ring1", + "d_rx_extra_frags_ring2", + "d_rx_extra_frags_ring3", + "d_rx_msdu_htt", + "d_rx_mpdu_htt", + "d_rx_msdu_stack", + "d_rx_mpdu_stack", + "d_rx_phy_err", + "d_rx_phy_err_drops", + "d_rx_mpdu_errors", /* FCS, MIC, ENC */ + "d_fw_crash_count", + "d_fw_warm_reset_count", + "d_fw_cold_reset_count", +}; + +#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats) + +void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset == ETH_SS_STATS) + memcpy(data, *ath10k_gstrings_stats, + sizeof(ath10k_gstrings_stats)); +} + +int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset) +{ + if (sset == ETH_SS_STATS) + return ATH10K_SSTATS_LEN; + + return 0; +} + +void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct ath10k *ar = hw->priv; + static const struct ath10k_fw_stats_pdev zero_stats = {}; + const struct ath10k_fw_stats_pdev *pdev_stats; + int i = 0, ret; + + mutex_lock(&ar->conf_mutex); + + if (ar->state == ATH10K_STATE_ON) { + ret = ath10k_debug_fw_stats_request(ar); + if (ret) { + /* just print a warning and try to use older results */ + ath10k_warn(ar, + "failed to get fw stats for ethtool: %d\n", + ret); + } + } + + pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs, + struct ath10k_fw_stats_pdev, + list); + if (!pdev_stats) { + /* no results available so just return zeroes */ + pdev_stats = &zero_stats; + } + + spin_lock_bh(&ar->data_lock); + + data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */ + data[i++] = 0; /* tx bytes */ + data[i++] = pdev_stats->htt_mpdus; + data[i++] = 0; /* rx bytes */ + data[i++] = pdev_stats->ch_noise_floor; + data[i++] = pdev_stats->cycle_count; + data[i++] = pdev_stats->phy_err_count; + data[i++] = pdev_stats->rts_bad; + data[i++] = pdev_stats->rts_good; + data[i++] = pdev_stats->chan_tx_power; + data[i++] = pdev_stats->fcs_bad; + data[i++] = pdev_stats->no_beacons; + data[i++] = pdev_stats->mpdu_enqued; + data[i++] = pdev_stats->msdu_enqued; + data[i++] = pdev_stats->wmm_drop; + data[i++] = pdev_stats->local_enqued; + data[i++] = pdev_stats->local_freed; + data[i++] = pdev_stats->hw_queued; + data[i++] = pdev_stats->hw_reaped; + data[i++] = pdev_stats->underrun; + data[i++] = pdev_stats->tx_abort; + data[i++] = pdev_stats->mpdus_requed; + data[i++] = pdev_stats->tx_ko; + data[i++] = pdev_stats->data_rc; + data[i++] = pdev_stats->sw_retry_failure; + data[i++] = pdev_stats->illgl_rate_phy_err; + data[i++] = pdev_stats->pdev_cont_xretry; + data[i++] = pdev_stats->pdev_tx_timeout; + data[i++] = pdev_stats->txop_ovf; + data[i++] = pdev_stats->pdev_resets; + data[i++] = pdev_stats->mid_ppdu_route_change; + data[i++] = pdev_stats->status_rcvd; + data[i++] = pdev_stats->r0_frags; + data[i++] = pdev_stats->r1_frags; + data[i++] = pdev_stats->r2_frags; + data[i++] = pdev_stats->r3_frags; + data[i++] = pdev_stats->htt_msdus; + data[i++] = pdev_stats->htt_mpdus; + data[i++] = pdev_stats->loc_msdus; + data[i++] = pdev_stats->loc_mpdus; + data[i++] = pdev_stats->phy_errs; + data[i++] = pdev_stats->phy_err_drop; + data[i++] = pdev_stats->mpdu_errs; + data[i++] = ar->stats.fw_crash_counter; + data[i++] = ar->stats.fw_warm_reset_counter; + data[i++] = ar->stats.fw_cold_reset_counter; + + spin_unlock_bh(&ar->data_lock); + + mutex_unlock(&ar->conf_mutex); + + WARN_ON(i != ATH10K_SSTATS_LEN); +} + static const struct file_operations fops_fw_dbglog = { .read = ath10k_read_fw_dbglog, .write = ath10k_write_fw_dbglog, diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index efbcd29fe9a1..d6a565d2bb74 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -63,6 +63,15 @@ void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) +void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data); +int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset); +void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data); + #else static inline int ath10k_debug_start(struct ath10k *ar) { @@ -115,6 +124,10 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) +#define ath10k_debug_get_et_strings NULL +#define ath10k_debug_get_et_sset_count NULL +#define ath10k_debug_get_et_stats NULL + #endif /* CONFIG_ATH10K_DEBUGFS */ #ifdef CONFIG_ATH10K_DEBUG diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 51b16e1ad677..a65572c3bd5c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4505,6 +4505,9 @@ static const struct ieee80211_ops ath10k_ops = { .sta_rc_update = ath10k_sta_rc_update, .get_tsf = ath10k_get_tsf, .ampdu_action = ath10k_ampdu_action, + .get_et_sset_count = ath10k_debug_get_et_sset_count, + .get_et_stats = ath10k_debug_get_et_stats, + .get_et_strings = ath10k_debug_get_et_strings, CFG80211_TESTMODE_CMD(ath10k_tm_cmd) -- GitLab From 16c1117675e20108612e1579362fdd75fa48a375 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 23 Sep 2014 14:17:16 -0700 Subject: [PATCH 0150/9457] ath10k: use 64-bit vdev map This can allow more than 32 stations to be supported without over-running the bitmap. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 4 ++-- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 21 ++++++++++++--------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index cee18c89d7f2..37e31665628c 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -846,9 +846,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) goto err_hif_stop; if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1; + ar->free_vdev_map = (1LL << TARGET_10X_NUM_VDEVS) - 1; else - ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; + ar->free_vdev_map = (1LL << TARGET_NUM_VDEVS) - 1; INIT_LIST_HEAD(&ar->arvifs); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 5a1dc98375e1..754ecc503368 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -482,7 +482,7 @@ struct ath10k { /* current operating channel definition */ struct cfg80211_chan_def chandef; - int free_vdev_map; + unsigned long long free_vdev_map; bool monitor; int monitor_vdev_id; bool monitor_started; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a65572c3bd5c..4a061a7e0885 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -624,9 +624,9 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar) return -ENOMEM; } - bit = ffs(ar->free_vdev_map); + bit = __ffs64(ar->free_vdev_map); - ar->monitor_vdev_id = bit - 1; + ar->monitor_vdev_id = bit; ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id, WMI_VDEV_TYPE_MONITOR, @@ -637,7 +637,7 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar) return ret; } - ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); + ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id); ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n", ar->monitor_vdev_id); @@ -657,7 +657,7 @@ static int ath10k_monitor_vdev_delete(struct ath10k *ar) return ret; } - ar->free_vdev_map |= 1 << ar->monitor_vdev_id; + ar->free_vdev_map |= 1LL << ar->monitor_vdev_id; ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", ar->monitor_vdev_id); @@ -2791,9 +2791,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, ret = -EBUSY; goto err; } - bit = ffs(ar->free_vdev_map); + bit = __ffs64(ar->free_vdev_map); - arvif->vdev_id = bit - 1; + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n", + bit, ar->free_vdev_map); + + arvif->vdev_id = bit; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; if (ar->p2p) @@ -2865,7 +2868,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, goto err; } - ar->free_vdev_map &= ~(1 << arvif->vdev_id); + ar->free_vdev_map &= ~(1LL << arvif->vdev_id); list_add(&arvif->list, &ar->arvifs); vdev_param = ar->wmi.vdev_param->def_keyid; @@ -2958,7 +2961,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, err_vdev_delete: ath10k_wmi_vdev_delete(ar, arvif->vdev_id); - ar->free_vdev_map |= 1 << arvif->vdev_id; + ar->free_vdev_map |= 1LL << arvif->vdev_id; list_del(&arvif->list); err: @@ -2993,7 +2996,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n", arvif->vdev_id, ret); - ar->free_vdev_map |= 1 << arvif->vdev_id; + ar->free_vdev_map |= 1LL << arvif->vdev_id; list_del(&arvif->list); if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -- GitLab From 11c9b6c628c646894e6ef53f92cfd33a814ee553 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 22:10:52 +0200 Subject: [PATCH 0151/9457] drm/i915: Tighting frontbuffer tracking around flips So I think I've spotted a small gap in the frontbuffer tracking while discussing the logic with Paulo on irc: 1. Userspace schedules gpu rendering to the current frontbuffer. This gets tracked in dev_priv->fb_tracking.busy_bits. 2. We pageflip a fully rendered buffer before the frontbuffer rendering completes. 3. The request retiring will never clear busy_bits (since at retire time the old frontbuffer won't have obj->frontbuffer_bits set), so these bits now are stuck until someone again does a bit of frontbuffer tracking. If we clear stale busy_bits in flip_prepare this gap is closed. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_frontbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index 7eb74a62117f..c5a312d218f7 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -248,8 +248,9 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; mutex_lock(&dev_priv->fb_tracking.lock); - dev_priv->fb_tracking.flip_bits - |= frontbuffer_bits; + dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; + /* Remove stale busy bits due to the old buffer. */ + dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; mutex_unlock(&dev_priv->fb_tracking.lock); } -- GitLab From 5c323b2a78fade2df08a51497fc943a6fd1b868b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 22:10:53 +0200 Subject: [PATCH 0152/9457] drm/i915: spelling fixes for frontbuffer tracking kerneldoc Oh well. v2: Fix one more spelling fail Paulo spotted. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_frontbuffer.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 072e69f4080e..f14f456e08f9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -819,7 +819,7 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, void intel_frontbuffer_flush(struct drm_device *dev, unsigned frontbuffer_bits); /** - * intel_frontbuffer_flip - prepare frontbuffer flip + * intel_frontbuffer_flip - synchronous frontbuffer flip * @dev: DRM device * @frontbuffer_bits: frontbuffer plane tracking bits * diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index c5a312d218f7..58cf2e6b78f4 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -28,7 +28,7 @@ * DOC: frontbuffer tracking * * Many features require us to track changes to the currently active - * frontbuffer, especially rendering targetted at the frontbuffer. + * frontbuffer, especially rendering targeted at the frontbuffer. * * To be able to do so GEM tracks frontbuffers using a bitmask for all possible * frontbuffer slots through i915_gem_track_fb(). The function in this file are @@ -55,7 +55,7 @@ * cancelled as soon as busyness is detected. * * Note that there's also an older frontbuffer activity tracking scheme which - * just trackings general activity. This is done by the various mark_busy and + * just tracks general activity. This is done by the various mark_busy and * mark_idle functions. For display power management features using these * functions is deprecated and should be avoided. */ @@ -166,7 +166,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, * * This function gets called every time rendering on the given planes has * completed and frontbuffer caching can be started again. Flushes will get - * delayed if they're blocked by some oustanding asynchronous rendering. + * delayed if they're blocked by some outstanding asynchronous rendering. * * Can be called without any locks held. */ @@ -231,7 +231,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, } /** - * intel_frontbuffer_flip_prepare - prepare asnychronous frontbuffer flip + * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip * @dev: DRM device * @frontbuffer_bits: frontbuffer plane tracking bits * @@ -255,12 +255,12 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev, } /** - * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flush + * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip * @dev: DRM device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called after the flip has been latched and will complete - * on the next vblank. It will execute the fush if it hasn't been cancalled yet. + * on the next vblank. It will execute the flush if it hasn't been cancelled yet. * * Can be called without any locks held. */ @@ -277,4 +277,3 @@ void intel_frontbuffer_flip_complete(struct drm_device *dev, intel_frontbuffer_flush(dev, frontbuffer_bits); } - -- GitLab From 970104fac6ca0cfdfbaa1a23c70c06a71208e2ac Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:37 +0200 Subject: [PATCH 0153/9457] drm/i915: Remove intel_modeset_suspend_hw Another layer of indirection for just an lpt-only w/a is a bit excessive. Reduce it. This was added in commit 7d708ee40a6b9ca1112a322e554c887df105b025 Author: Imre Deak Date: Wed Apr 17 14:04:50 2013 +0300 drm/i915: HSW: allow PCH clock gating for suspend Cc: Imre Deak Cc: Paulo Zanoni Signed-off-by: Daniel Vetter Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_display.c | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6948877c881c..ea93ff151a74 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -606,7 +606,7 @@ static int i915_drm_freeze(struct drm_device *dev) intel_suspend_gt_powersave(dev); - intel_modeset_suspend_hw(dev); + intel_suspend_hw(dev); } i915_gem_suspend_gtt_mappings(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4cd2aa347f37..622c038f880c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2840,7 +2840,6 @@ static inline void intel_unregister_dsm_handler(void) { return; } /* modesetting */ extern void intel_modeset_init_hw(struct drm_device *dev); -extern void intel_modeset_suspend_hw(struct drm_device *dev); extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_gem_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b8488a8c1e9f..a9605789ad55 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12830,11 +12830,6 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_enable_gt_powersave(dev); } -void intel_modeset_suspend_hw(struct drm_device *dev) -{ - intel_suspend_hw(dev); -} - void intel_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; -- GitLab From 9c065a7d5b679e7fabe3cace4faadb283f2b0c1f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:38 +0200 Subject: [PATCH 0154/9457] drm/i915: Extract intel_runtime_pm.c Geez is the audio hack ugly. Signed-off-by: Daniel Vetter Reviewed-by: Imre Deak [danvet: Rebased on top of the skl patches.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 4 +- drivers/gpu/drm/i915/intel_drv.h | 39 +- drivers/gpu/drm/i915/intel_pm.c | 1160 ---------------------- drivers/gpu/drm/i915/intel_runtime_pm.c | 1190 +++++++++++++++++++++++ 4 files changed, 1214 insertions(+), 1179 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_runtime_pm.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 2d8317d36e09..3a6bce047f6f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -11,7 +11,9 @@ i915-y := i915_drv.o \ i915_params.o \ i915_suspend.o \ i915_sysfs.o \ - intel_pm.o + intel_pm.o \ + intel_runtime_pm.o + i915-$(CONFIG_COMPAT) += i915_ioc32.o i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f14f456e08f9..9d2ee70d51e4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1081,6 +1081,27 @@ extern struct drm_display_mode *intel_find_panel_downclock( struct drm_display_mode *fixed_mode, struct drm_connector *connector); +/* intel_runtime_pm.c */ +int intel_power_domains_init(struct drm_i915_private *); +void intel_power_domains_remove(struct drm_i915_private *); +void intel_power_domains_init_hw(struct drm_i915_private *dev_priv); +void intel_init_runtime_pm(struct drm_i915_private *dev_priv); +void intel_fini_runtime_pm(struct drm_i915_private *dev_priv); + +bool intel_display_power_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); +void intel_display_power_get(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); +void intel_display_power_put(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); +void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv); +void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv); +void intel_runtime_pm_get(struct drm_i915_private *dev_priv); +void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); +void intel_runtime_pm_put(struct drm_i915_private *dev_priv); + /* intel_pm.c */ void intel_init_clock_gating(struct drm_device *dev); void intel_suspend_hw(struct drm_device *dev); @@ -1098,17 +1119,6 @@ bool intel_fbc_enabled(struct drm_device *dev); void intel_update_fbc(struct drm_device *dev); void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_teardown(void); -int intel_power_domains_init(struct drm_i915_private *); -void intel_power_domains_remove(struct drm_i915_private *); -bool intel_display_power_enabled(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); -bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); -void intel_display_power_get(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); -void intel_display_power_put(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); -void intel_power_domains_init_hw(struct drm_i915_private *dev_priv); void intel_init_gt_powersave(struct drm_device *dev); void intel_cleanup_gt_powersave(struct drm_device *dev); void intel_enable_gt_powersave(struct drm_device *dev); @@ -1119,13 +1129,6 @@ void ironlake_teardown_rc6(struct drm_device *dev); void gen6_update_ring_freq(struct drm_device *dev); void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_boost(struct drm_i915_private *dev_priv); -void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv); -void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv); -void intel_runtime_pm_get(struct drm_i915_private *dev_priv); -void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); -void intel_runtime_pm_put(struct drm_i915_private *dev_priv); -void intel_init_runtime_pm(struct drm_i915_private *dev_priv); -void intel_fini_runtime_pm(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 043c5a8eae20..95006e0e982b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -30,9 +30,6 @@ #include "intel_drv.h" #include "../../../platform/x86/intel_ips.h" #include -#include -#include -#include /** * RC6 is a special power stage which allows the GPU to enter an very @@ -6230,1163 +6227,6 @@ void intel_suspend_hw(struct drm_device *dev) lpt_suspend_hw(dev); } -#define for_each_power_well(i, power_well, domain_mask, power_domains) \ - for (i = 0; \ - i < (power_domains)->power_well_count && \ - ((power_well) = &(power_domains)->power_wells[i]); \ - i++) \ - if ((power_well)->domains & (domain_mask)) - -#define for_each_power_well_rev(i, power_well, domain_mask, power_domains) \ - for (i = (power_domains)->power_well_count - 1; \ - i >= 0 && ((power_well) = &(power_domains)->power_wells[i]);\ - i--) \ - if ((power_well)->domains & (domain_mask)) - -/** - * We should only use the power well if we explicitly asked the hardware to - * enable it, so check if it's enabled and also check if we've requested it to - * be enabled. - */ -static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - return I915_READ(HSW_PWR_WELL_DRIVER) == - (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); -} - -bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) -{ - struct i915_power_domains *power_domains; - struct i915_power_well *power_well; - bool is_enabled; - int i; - - if (dev_priv->pm.suspended) - return false; - - power_domains = &dev_priv->power_domains; - - is_enabled = true; - - for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { - if (power_well->always_on) - continue; - - if (!power_well->hw_enabled) { - is_enabled = false; - break; - } - } - - return is_enabled; -} - -bool intel_display_power_enabled(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) -{ - struct i915_power_domains *power_domains; - bool ret; - - power_domains = &dev_priv->power_domains; - - mutex_lock(&power_domains->lock); - ret = intel_display_power_enabled_unlocked(dev_priv, domain); - mutex_unlock(&power_domains->lock); - - return ret; -} - -/* - * Starting with Haswell, we have a "Power Down Well" that can be turned off - * when not needed anymore. We have 4 registers that can request the power well - * to be enabled, and it will only be disabled if none of the registers is - * requesting it to be enabled. - */ -static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - - /* - * After we re-enable the power well, if we touch VGA register 0x3d5 - * we'll get unclaimed register interrupts. This stops after we write - * anything to the VGA MSR register. The vgacon module uses this - * register all the time, so if we unbind our driver and, as a - * consequence, bind vgacon, we'll get stuck in an infinite loop at - * console_unlock(). So make here we touch the VGA MSR register, making - * sure vgacon can keep working normally without triggering interrupts - * and error messages. - */ - vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); - outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); - vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); - - if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) - gen8_irq_power_well_post_enable(dev_priv); -} - -static void hsw_set_power_well(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well, bool enable) -{ - bool is_enabled, enable_requested; - uint32_t tmp; - - tmp = I915_READ(HSW_PWR_WELL_DRIVER); - is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; - enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; - - if (enable) { - if (!enable_requested) - I915_WRITE(HSW_PWR_WELL_DRIVER, - HSW_PWR_WELL_ENABLE_REQUEST); - - if (!is_enabled) { - DRM_DEBUG_KMS("Enabling power well\n"); - if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & - HSW_PWR_WELL_STATE_ENABLED), 20)) - DRM_ERROR("Timeout enabling power well\n"); - } - - hsw_power_well_post_enable(dev_priv); - } else { - if (enable_requested) { - I915_WRITE(HSW_PWR_WELL_DRIVER, 0); - POSTING_READ(HSW_PWR_WELL_DRIVER); - DRM_DEBUG_KMS("Requesting to disable the power well\n"); - } - } -} - -static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - hsw_set_power_well(dev_priv, power_well, power_well->count > 0); - - /* - * We're taking over the BIOS, so clear any requests made by it since - * the driver is in charge now. - */ - if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) - I915_WRITE(HSW_PWR_WELL_BIOS, 0); -} - -static void hsw_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - hsw_set_power_well(dev_priv, power_well, true); -} - -static void hsw_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - hsw_set_power_well(dev_priv, power_well, false); -} - -static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ -} - -static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - return true; -} - -static void vlv_set_power_well(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well, bool enable) -{ - enum punit_power_well power_well_id = power_well->data; - u32 mask; - u32 state; - u32 ctrl; - - mask = PUNIT_PWRGT_MASK(power_well_id); - state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : - PUNIT_PWRGT_PWR_GATE(power_well_id); - - mutex_lock(&dev_priv->rps.hw_lock); - -#define COND \ - ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state) - - if (COND) - goto out; - - ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL); - ctrl &= ~mask; - ctrl |= state; - vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl); - - if (wait_for(COND, 100)) - DRM_ERROR("timout setting power well state %08x (%08x)\n", - state, - vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL)); - -#undef COND - -out: - mutex_unlock(&dev_priv->rps.hw_lock); -} - -static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - vlv_set_power_well(dev_priv, power_well, power_well->count > 0); -} - -static void vlv_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - vlv_set_power_well(dev_priv, power_well, true); -} - -static void vlv_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - vlv_set_power_well(dev_priv, power_well, false); -} - -static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - int power_well_id = power_well->data; - bool enabled = false; - u32 mask; - u32 state; - u32 ctrl; - - mask = PUNIT_PWRGT_MASK(power_well_id); - ctrl = PUNIT_PWRGT_PWR_ON(power_well_id); - - mutex_lock(&dev_priv->rps.hw_lock); - - state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask; - /* - * We only ever set the power-on and power-gate states, anything - * else is unexpected. - */ - WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) && - state != PUNIT_PWRGT_PWR_GATE(power_well_id)); - if (state == ctrl) - enabled = true; - - /* - * A transient state at this point would mean some unexpected party - * is poking at the power controls too. - */ - ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask; - WARN_ON(ctrl != state); - - mutex_unlock(&dev_priv->rps.hw_lock); - - return enabled; -} - -static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); - - vlv_set_power_well(dev_priv, power_well, true); - - spin_lock_irq(&dev_priv->irq_lock); - valleyview_enable_display_irqs(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); - - /* - * During driver initialization/resume we can avoid restoring the - * part of the HW/SW state that will be inited anyway explicitly. - */ - if (dev_priv->power_domains.initializing) - return; - - intel_hpd_init(dev_priv->dev); - - i915_redisable_vga_power_on(dev_priv->dev); -} - -static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); - - spin_lock_irq(&dev_priv->irq_lock); - valleyview_disable_display_irqs(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); - - vlv_set_power_well(dev_priv, power_well, false); - - vlv_power_sequencer_reset(dev_priv); -} - -static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); - - /* - * Enable the CRI clock source so we can get at the - * display and the reference clock for VGA - * hotplug / manual detection. - */ - I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | - DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); - udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ - - vlv_set_power_well(dev_priv, power_well, true); - - /* - * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx - - * 6. De-assert cmn_reset/side_reset. Same as VLV X0. - * a. GUnit 0x2110 bit[0] set to 1 (def 0) - * b. The other bits such as sfr settings / modesel may all - * be set to 0. - * - * This should only be done on init and resume from S3 with - * both PLLs disabled, or we risk losing DPIO and PLL - * synchronization. - */ - I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST); -} - -static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - enum pipe pipe; - - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); - - for_each_pipe(dev_priv, pipe) - assert_pll_disabled(dev_priv, pipe); - - /* Assert common reset */ - I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST); - - vlv_set_power_well(dev_priv, power_well, false); -} - -static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - enum dpio_phy phy; - - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && - power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); - - /* - * Enable the CRI clock source so we can get at the - * display and the reference clock for VGA - * hotplug / manual detection. - */ - if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { - phy = DPIO_PHY0; - I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | - DPLL_REFA_CLK_ENABLE_VLV); - I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | - DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); - } else { - phy = DPIO_PHY1; - I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) | - DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); - } - udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ - vlv_set_power_well(dev_priv, power_well, true); - - /* Poll for phypwrgood signal */ - if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1)) - DRM_ERROR("Display PHY %d is not power up\n", phy); - - I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) | - PHY_COM_LANE_RESET_DEASSERT(phy)); -} - -static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - enum dpio_phy phy; - - WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && - power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); - - if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { - phy = DPIO_PHY0; - assert_pll_disabled(dev_priv, PIPE_A); - assert_pll_disabled(dev_priv, PIPE_B); - } else { - phy = DPIO_PHY1; - assert_pll_disabled(dev_priv, PIPE_C); - } - - I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) & - ~PHY_COM_LANE_RESET_DEASSERT(phy)); - - vlv_set_power_well(dev_priv, power_well, false); -} - -static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - enum pipe pipe = power_well->data; - bool enabled; - u32 state, ctrl; - - mutex_lock(&dev_priv->rps.hw_lock); - - state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe); - /* - * We only ever set the power-on and power-gate states, anything - * else is unexpected. - */ - WARN_ON(state != DP_SSS_PWR_ON(pipe) && state != DP_SSS_PWR_GATE(pipe)); - enabled = state == DP_SSS_PWR_ON(pipe); - - /* - * A transient state at this point would mean some unexpected party - * is poking at the power controls too. - */ - ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe); - WARN_ON(ctrl << 16 != state); - - mutex_unlock(&dev_priv->rps.hw_lock); - - return enabled; -} - -static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well, - bool enable) -{ - enum pipe pipe = power_well->data; - u32 state; - u32 ctrl; - - state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe); - - mutex_lock(&dev_priv->rps.hw_lock); - -#define COND \ - ((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state) - - if (COND) - goto out; - - ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); - ctrl &= ~DP_SSC_MASK(pipe); - ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe); - vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, ctrl); - - if (wait_for(COND, 100)) - DRM_ERROR("timout setting power well state %08x (%08x)\n", - state, - vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ)); - -#undef COND - -out: - mutex_unlock(&dev_priv->rps.hw_lock); -} - -static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0); -} - -static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - WARN_ON_ONCE(power_well->data != PIPE_A && - power_well->data != PIPE_B && - power_well->data != PIPE_C); - - chv_set_pipe_power_well(dev_priv, power_well, true); -} - -static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - WARN_ON_ONCE(power_well->data != PIPE_A && - power_well->data != PIPE_B && - power_well->data != PIPE_C); - - chv_set_pipe_power_well(dev_priv, power_well, false); -} - -static void check_power_well_state(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - bool enabled = power_well->ops->is_enabled(dev_priv, power_well); - - if (power_well->always_on || !i915.disable_power_well) { - if (!enabled) - goto mismatch; - - return; - } - - if (enabled != (power_well->count > 0)) - goto mismatch; - - return; - -mismatch: - WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", - power_well->name, power_well->always_on, enabled, - power_well->count, i915.disable_power_well); -} - -void intel_display_power_get(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) -{ - struct i915_power_domains *power_domains; - struct i915_power_well *power_well; - int i; - - intel_runtime_pm_get(dev_priv); - - power_domains = &dev_priv->power_domains; - - mutex_lock(&power_domains->lock); - - for_each_power_well(i, power_well, BIT(domain), power_domains) { - if (!power_well->count++) { - DRM_DEBUG_KMS("enabling %s\n", power_well->name); - power_well->ops->enable(dev_priv, power_well); - power_well->hw_enabled = true; - } - - check_power_well_state(dev_priv, power_well); - } - - power_domains->domain_use_count[domain]++; - - mutex_unlock(&power_domains->lock); -} - -void intel_display_power_put(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) -{ - struct i915_power_domains *power_domains; - struct i915_power_well *power_well; - int i; - - power_domains = &dev_priv->power_domains; - - mutex_lock(&power_domains->lock); - - WARN_ON(!power_domains->domain_use_count[domain]); - power_domains->domain_use_count[domain]--; - - for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { - WARN_ON(!power_well->count); - - if (!--power_well->count && i915.disable_power_well) { - DRM_DEBUG_KMS("disabling %s\n", power_well->name); - power_well->hw_enabled = false; - power_well->ops->disable(dev_priv, power_well); - } - - check_power_well_state(dev_priv, power_well); - } - - mutex_unlock(&power_domains->lock); - - intel_runtime_pm_put(dev_priv); -} - -static struct i915_power_domains *hsw_pwr; - -/* Display audio driver power well request */ -int i915_request_power_well(void) -{ - struct drm_i915_private *dev_priv; - - if (!hsw_pwr) - return -ENODEV; - - dev_priv = container_of(hsw_pwr, struct drm_i915_private, - power_domains); - intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); - return 0; -} -EXPORT_SYMBOL_GPL(i915_request_power_well); - -/* Display audio driver power well release */ -int i915_release_power_well(void) -{ - struct drm_i915_private *dev_priv; - - if (!hsw_pwr) - return -ENODEV; - - dev_priv = container_of(hsw_pwr, struct drm_i915_private, - power_domains); - intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); - return 0; -} -EXPORT_SYMBOL_GPL(i915_release_power_well); - -/* - * Private interface for the audio driver to get CDCLK in kHz. - * - * Caller must request power well using i915_request_power_well() prior to - * making the call. - */ -int i915_get_cdclk_freq(void) -{ - struct drm_i915_private *dev_priv; - - if (!hsw_pwr) - return -ENODEV; - - dev_priv = container_of(hsw_pwr, struct drm_i915_private, - power_domains); - - return intel_ddi_get_cdclk_freq(dev_priv); -} -EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); - - -#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) - -#define HSW_ALWAYS_ON_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_A) | \ - BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ - BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_CRT) | \ - BIT(POWER_DOMAIN_PLLS) | \ - BIT(POWER_DOMAIN_INIT)) -#define HSW_DISPLAY_POWER_DOMAINS ( \ - (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \ - BIT(POWER_DOMAIN_INIT)) - -#define BDW_ALWAYS_ON_POWER_DOMAINS ( \ - HSW_ALWAYS_ON_POWER_DOMAINS | \ - BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER)) -#define BDW_DISPLAY_POWER_DOMAINS ( \ - (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \ - BIT(POWER_DOMAIN_INIT)) - -#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT) -#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK - -#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_CRT) | \ - BIT(POWER_DOMAIN_INIT)) - -#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_PIPE_A_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_A) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_PIPE_B_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_B) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_PIPE_C_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_C) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_DPIO_CMN_BC_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_DPIO_CMN_D_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_INIT)) - -static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { - .sync_hw = i9xx_always_on_power_well_noop, - .enable = i9xx_always_on_power_well_noop, - .disable = i9xx_always_on_power_well_noop, - .is_enabled = i9xx_always_on_power_well_enabled, -}; - -static const struct i915_power_well_ops chv_pipe_power_well_ops = { - .sync_hw = chv_pipe_power_well_sync_hw, - .enable = chv_pipe_power_well_enable, - .disable = chv_pipe_power_well_disable, - .is_enabled = chv_pipe_power_well_enabled, -}; - -static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = { - .sync_hw = vlv_power_well_sync_hw, - .enable = chv_dpio_cmn_power_well_enable, - .disable = chv_dpio_cmn_power_well_disable, - .is_enabled = vlv_power_well_enabled, -}; - -static struct i915_power_well i9xx_always_on_power_well[] = { - { - .name = "always-on", - .always_on = 1, - .domains = POWER_DOMAIN_MASK, - .ops = &i9xx_always_on_power_well_ops, - }, -}; - -static const struct i915_power_well_ops hsw_power_well_ops = { - .sync_hw = hsw_power_well_sync_hw, - .enable = hsw_power_well_enable, - .disable = hsw_power_well_disable, - .is_enabled = hsw_power_well_enabled, -}; - -static struct i915_power_well hsw_power_wells[] = { - { - .name = "always-on", - .always_on = 1, - .domains = HSW_ALWAYS_ON_POWER_DOMAINS, - .ops = &i9xx_always_on_power_well_ops, - }, - { - .name = "display", - .domains = HSW_DISPLAY_POWER_DOMAINS, - .ops = &hsw_power_well_ops, - }, -}; - -static struct i915_power_well bdw_power_wells[] = { - { - .name = "always-on", - .always_on = 1, - .domains = BDW_ALWAYS_ON_POWER_DOMAINS, - .ops = &i9xx_always_on_power_well_ops, - }, - { - .name = "display", - .domains = BDW_DISPLAY_POWER_DOMAINS, - .ops = &hsw_power_well_ops, - }, -}; - -static const struct i915_power_well_ops vlv_display_power_well_ops = { - .sync_hw = vlv_power_well_sync_hw, - .enable = vlv_display_power_well_enable, - .disable = vlv_display_power_well_disable, - .is_enabled = vlv_power_well_enabled, -}; - -static const struct i915_power_well_ops vlv_dpio_cmn_power_well_ops = { - .sync_hw = vlv_power_well_sync_hw, - .enable = vlv_dpio_cmn_power_well_enable, - .disable = vlv_dpio_cmn_power_well_disable, - .is_enabled = vlv_power_well_enabled, -}; - -static const struct i915_power_well_ops vlv_dpio_power_well_ops = { - .sync_hw = vlv_power_well_sync_hw, - .enable = vlv_power_well_enable, - .disable = vlv_power_well_disable, - .is_enabled = vlv_power_well_enabled, -}; - -static struct i915_power_well vlv_power_wells[] = { - { - .name = "always-on", - .always_on = 1, - .domains = VLV_ALWAYS_ON_POWER_DOMAINS, - .ops = &i9xx_always_on_power_well_ops, - }, - { - .name = "display", - .domains = VLV_DISPLAY_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DISP2D, - .ops = &vlv_display_power_well_ops, - }, - { - .name = "dpio-tx-b-01", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, - }, - { - .name = "dpio-tx-b-23", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, - }, - { - .name = "dpio-tx-c-01", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, - }, - { - .name = "dpio-tx-c-23", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, - }, - { - .name = "dpio-common", - .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DPIO_CMN_BC, - .ops = &vlv_dpio_cmn_power_well_ops, - }, -}; - -static struct i915_power_well chv_power_wells[] = { - { - .name = "always-on", - .always_on = 1, - .domains = VLV_ALWAYS_ON_POWER_DOMAINS, - .ops = &i9xx_always_on_power_well_ops, - }, -#if 0 - { - .name = "display", - .domains = VLV_DISPLAY_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DISP2D, - .ops = &vlv_display_power_well_ops, - }, - { - .name = "pipe-a", - .domains = CHV_PIPE_A_POWER_DOMAINS, - .data = PIPE_A, - .ops = &chv_pipe_power_well_ops, - }, - { - .name = "pipe-b", - .domains = CHV_PIPE_B_POWER_DOMAINS, - .data = PIPE_B, - .ops = &chv_pipe_power_well_ops, - }, - { - .name = "pipe-c", - .domains = CHV_PIPE_C_POWER_DOMAINS, - .data = PIPE_C, - .ops = &chv_pipe_power_well_ops, - }, -#endif - { - .name = "dpio-common-bc", - /* - * XXX: cmnreset for one PHY seems to disturb the other. - * As a workaround keep both powered on at the same - * time for now. - */ - .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DPIO_CMN_BC, - .ops = &chv_dpio_cmn_power_well_ops, - }, - { - .name = "dpio-common-d", - /* - * XXX: cmnreset for one PHY seems to disturb the other. - * As a workaround keep both powered on at the same - * time for now. - */ - .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DPIO_CMN_D, - .ops = &chv_dpio_cmn_power_well_ops, - }, -#if 0 - { - .name = "dpio-tx-b-01", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, - }, - { - .name = "dpio-tx-b-23", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, - }, - { - .name = "dpio-tx-c-01", - .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, - }, - { - .name = "dpio-tx-c-23", - .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, - }, - { - .name = "dpio-tx-d-01", - .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | - CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_01, - }, - { - .name = "dpio-tx-d-23", - .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | - CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_23, - }, -#endif -}; - -static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, - enum punit_power_well power_well_id) -{ - struct i915_power_domains *power_domains = &dev_priv->power_domains; - struct i915_power_well *power_well; - int i; - - for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { - if (power_well->data == power_well_id) - return power_well; - } - - return NULL; -} - -#define set_power_wells(power_domains, __power_wells) ({ \ - (power_domains)->power_wells = (__power_wells); \ - (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ -}) - -int intel_power_domains_init(struct drm_i915_private *dev_priv) -{ - struct i915_power_domains *power_domains = &dev_priv->power_domains; - - mutex_init(&power_domains->lock); - - /* - * The enabling order will be from lower to higher indexed wells, - * the disabling order is reversed. - */ - if (IS_HASWELL(dev_priv->dev)) { - set_power_wells(power_domains, hsw_power_wells); - hsw_pwr = power_domains; - } else if (IS_BROADWELL(dev_priv->dev)) { - set_power_wells(power_domains, bdw_power_wells); - hsw_pwr = power_domains; - } else if (IS_CHERRYVIEW(dev_priv->dev)) { - set_power_wells(power_domains, chv_power_wells); - } else if (IS_VALLEYVIEW(dev_priv->dev)) { - set_power_wells(power_domains, vlv_power_wells); - } else { - set_power_wells(power_domains, i9xx_always_on_power_well); - } - - return 0; -} - -void intel_power_domains_remove(struct drm_i915_private *dev_priv) -{ - hsw_pwr = NULL; -} - -static void intel_power_domains_resume(struct drm_i915_private *dev_priv) -{ - struct i915_power_domains *power_domains = &dev_priv->power_domains; - struct i915_power_well *power_well; - int i; - - mutex_lock(&power_domains->lock); - for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { - power_well->ops->sync_hw(dev_priv, power_well); - power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, - power_well); - } - mutex_unlock(&power_domains->lock); -} - -static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) -{ - struct i915_power_well *cmn = - lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); - struct i915_power_well *disp2d = - lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); - - /* nothing to do if common lane is already off */ - if (!cmn->ops->is_enabled(dev_priv, cmn)) - return; - - /* If the display might be already active skip this */ - if (disp2d->ops->is_enabled(dev_priv, disp2d) && - I915_READ(DPIO_CTL) & DPIO_CMNRST) - return; - - DRM_DEBUG_KMS("toggling display PHY side reset\n"); - - /* cmnlane needs DPLL registers */ - disp2d->ops->enable(dev_priv, disp2d); - - /* - * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx: - * Need to assert and de-assert PHY SB reset by gating the - * common lane power, then un-gating it. - * Simply ungating isn't enough to reset the PHY enough to get - * ports and lanes running. - */ - cmn->ops->disable(dev_priv, cmn); -} - -void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct i915_power_domains *power_domains = &dev_priv->power_domains; - - power_domains->initializing = true; - - if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { - mutex_lock(&power_domains->lock); - vlv_cmnlane_wa(dev_priv); - mutex_unlock(&power_domains->lock); - } - - /* For now, we need the power well to be always enabled. */ - intel_display_set_init_power(dev_priv, true); - intel_power_domains_resume(dev_priv); - power_domains->initializing = false; -} - -void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv) -{ - intel_runtime_pm_get(dev_priv); -} - -void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv) -{ - intel_runtime_pm_put(dev_priv); -} - -void intel_runtime_pm_get(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - pm_runtime_get_sync(device); - WARN(dev_priv->pm.suspended, "Device still suspended.\n"); -} - -void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - WARN(dev_priv->pm.suspended, "Getting nosync-ref while suspended.\n"); - pm_runtime_get_noresume(device); -} - -void intel_runtime_pm_put(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - pm_runtime_mark_last_busy(device); - pm_runtime_put_autosuspend(device); -} - -void intel_init_runtime_pm(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - pm_runtime_set_active(device); - - /* - * RPM depends on RC6 to save restore the GT HW context, so make RC6 a - * requirement. - */ - if (!intel_enable_rc6(dev)) { - DRM_INFO("RC6 disabled, disabling runtime PM support\n"); - return; - } - - pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */ - pm_runtime_mark_last_busy(device); - pm_runtime_use_autosuspend(device); - - pm_runtime_put_autosuspend(device); -} - -void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - if (!intel_enable_rc6(dev)) - return; - - /* Make sure we're not suspended first. */ - pm_runtime_get_sync(device); - pm_runtime_disable(device); -} - static void intel_init_fbc(struct drm_i915_private *dev_priv) { if (!HAS_FBC(dev_priv)) { diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c new file mode 100644 index 000000000000..2344ecfc27cc --- /dev/null +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -0,0 +1,1190 @@ +/* + * Copyright © 2012-2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eugeni Dodonov + * Daniel Vetter + * + */ + +#include +#include + +#include "i915_drv.h" +#include "intel_drv.h" +#include + +static struct i915_power_domains *hsw_pwr; + +#define for_each_power_well(i, power_well, domain_mask, power_domains) \ + for (i = 0; \ + i < (power_domains)->power_well_count && \ + ((power_well) = &(power_domains)->power_wells[i]); \ + i++) \ + if ((power_well)->domains & (domain_mask)) + +#define for_each_power_well_rev(i, power_well, domain_mask, power_domains) \ + for (i = (power_domains)->power_well_count - 1; \ + i >= 0 && ((power_well) = &(power_domains)->power_wells[i]);\ + i--) \ + if ((power_well)->domains & (domain_mask)) + +/** + * We should only use the power well if we explicitly asked the hardware to + * enable it, so check if it's enabled and also check if we've requested it to + * be enabled. + */ +static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + return I915_READ(HSW_PWR_WELL_DRIVER) == + (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); +} + +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) +{ + struct i915_power_domains *power_domains; + struct i915_power_well *power_well; + bool is_enabled; + int i; + + if (dev_priv->pm.suspended) + return false; + + power_domains = &dev_priv->power_domains; + + is_enabled = true; + + for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { + if (power_well->always_on) + continue; + + if (!power_well->hw_enabled) { + is_enabled = false; + break; + } + } + + return is_enabled; +} + +bool intel_display_power_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) +{ + struct i915_power_domains *power_domains; + bool ret; + + power_domains = &dev_priv->power_domains; + + mutex_lock(&power_domains->lock); + ret = intel_display_power_enabled_unlocked(dev_priv, domain); + mutex_unlock(&power_domains->lock); + + return ret; +} + +/* + * Starting with Haswell, we have a "Power Down Well" that can be turned off + * when not needed anymore. We have 4 registers that can request the power well + * to be enabled, and it will only be disabled if none of the registers is + * requesting it to be enabled. + */ +static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + /* + * After we re-enable the power well, if we touch VGA register 0x3d5 + * we'll get unclaimed register interrupts. This stops after we write + * anything to the VGA MSR register. The vgacon module uses this + * register all the time, so if we unbind our driver and, as a + * consequence, bind vgacon, we'll get stuck in an infinite loop at + * console_unlock(). So make here we touch the VGA MSR register, making + * sure vgacon can keep working normally without triggering interrupts + * and error messages. + */ + vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); + outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); + vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); + + if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) + gen8_irq_power_well_post_enable(dev_priv); +} + +static void hsw_set_power_well(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well, bool enable) +{ + bool is_enabled, enable_requested; + uint32_t tmp; + + tmp = I915_READ(HSW_PWR_WELL_DRIVER); + is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; + enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; + + if (enable) { + if (!enable_requested) + I915_WRITE(HSW_PWR_WELL_DRIVER, + HSW_PWR_WELL_ENABLE_REQUEST); + + if (!is_enabled) { + DRM_DEBUG_KMS("Enabling power well\n"); + if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & + HSW_PWR_WELL_STATE_ENABLED), 20)) + DRM_ERROR("Timeout enabling power well\n"); + } + + hsw_power_well_post_enable(dev_priv); + } else { + if (enable_requested) { + I915_WRITE(HSW_PWR_WELL_DRIVER, 0); + POSTING_READ(HSW_PWR_WELL_DRIVER); + DRM_DEBUG_KMS("Requesting to disable the power well\n"); + } + } +} + +static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + hsw_set_power_well(dev_priv, power_well, power_well->count > 0); + + /* + * We're taking over the BIOS, so clear any requests made by it since + * the driver is in charge now. + */ + if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) + I915_WRITE(HSW_PWR_WELL_BIOS, 0); +} + +static void hsw_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + hsw_set_power_well(dev_priv, power_well, true); +} + +static void hsw_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + hsw_set_power_well(dev_priv, power_well, false); +} + +static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ +} + +static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + return true; +} + +static void vlv_set_power_well(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well, bool enable) +{ + enum punit_power_well power_well_id = power_well->data; + u32 mask; + u32 state; + u32 ctrl; + + mask = PUNIT_PWRGT_MASK(power_well_id); + state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : + PUNIT_PWRGT_PWR_GATE(power_well_id); + + mutex_lock(&dev_priv->rps.hw_lock); + +#define COND \ + ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state) + + if (COND) + goto out; + + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL); + ctrl &= ~mask; + ctrl |= state; + vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl); + + if (wait_for(COND, 100)) + DRM_ERROR("timout setting power well state %08x (%08x)\n", + state, + vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL)); + +#undef COND + +out: + mutex_unlock(&dev_priv->rps.hw_lock); +} + +static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + vlv_set_power_well(dev_priv, power_well, power_well->count > 0); +} + +static void vlv_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + vlv_set_power_well(dev_priv, power_well, true); +} + +static void vlv_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + vlv_set_power_well(dev_priv, power_well, false); +} + +static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + int power_well_id = power_well->data; + bool enabled = false; + u32 mask; + u32 state; + u32 ctrl; + + mask = PUNIT_PWRGT_MASK(power_well_id); + ctrl = PUNIT_PWRGT_PWR_ON(power_well_id); + + mutex_lock(&dev_priv->rps.hw_lock); + + state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask; + /* + * We only ever set the power-on and power-gate states, anything + * else is unexpected. + */ + WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) && + state != PUNIT_PWRGT_PWR_GATE(power_well_id)); + if (state == ctrl) + enabled = true; + + /* + * A transient state at this point would mean some unexpected party + * is poking at the power controls too. + */ + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask; + WARN_ON(ctrl != state); + + mutex_unlock(&dev_priv->rps.hw_lock); + + return enabled; +} + +static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); + + vlv_set_power_well(dev_priv, power_well, true); + + spin_lock_irq(&dev_priv->irq_lock); + valleyview_enable_display_irqs(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + + /* + * During driver initialization/resume we can avoid restoring the + * part of the HW/SW state that will be inited anyway explicitly. + */ + if (dev_priv->power_domains.initializing) + return; + + intel_hpd_init(dev_priv->dev); + + i915_redisable_vga_power_on(dev_priv->dev); +} + +static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); + + spin_lock_irq(&dev_priv->irq_lock); + valleyview_disable_display_irqs(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + + vlv_set_power_well(dev_priv, power_well, false); + + vlv_power_sequencer_reset(dev_priv); +} + +static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); + + /* + * Enable the CRI clock source so we can get at the + * display and the reference clock for VGA + * hotplug / manual detection. + */ + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | + DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); + udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ + + vlv_set_power_well(dev_priv, power_well, true); + + /* + * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx - + * 6. De-assert cmn_reset/side_reset. Same as VLV X0. + * a. GUnit 0x2110 bit[0] set to 1 (def 0) + * b. The other bits such as sfr settings / modesel may all + * be set to 0. + * + * This should only be done on init and resume from S3 with + * both PLLs disabled, or we risk losing DPIO and PLL + * synchronization. + */ + I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST); +} + +static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + enum pipe pipe; + + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); + + for_each_pipe(dev_priv, pipe) + assert_pll_disabled(dev_priv, pipe); + + /* Assert common reset */ + I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST); + + vlv_set_power_well(dev_priv, power_well, false); +} + +static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + enum dpio_phy phy; + + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && + power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); + + /* + * Enable the CRI clock source so we can get at the + * display and the reference clock for VGA + * hotplug / manual detection. + */ + if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { + phy = DPIO_PHY0; + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | + DPLL_REFA_CLK_ENABLE_VLV); + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | + DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); + } else { + phy = DPIO_PHY1; + I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) | + DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV); + } + udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ + vlv_set_power_well(dev_priv, power_well, true); + + /* Poll for phypwrgood signal */ + if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1)) + DRM_ERROR("Display PHY %d is not power up\n", phy); + + I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) | + PHY_COM_LANE_RESET_DEASSERT(phy)); +} + +static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + enum dpio_phy phy; + + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && + power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); + + if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { + phy = DPIO_PHY0; + assert_pll_disabled(dev_priv, PIPE_A); + assert_pll_disabled(dev_priv, PIPE_B); + } else { + phy = DPIO_PHY1; + assert_pll_disabled(dev_priv, PIPE_C); + } + + I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) & + ~PHY_COM_LANE_RESET_DEASSERT(phy)); + + vlv_set_power_well(dev_priv, power_well, false); +} + +static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + enum pipe pipe = power_well->data; + bool enabled; + u32 state, ctrl; + + mutex_lock(&dev_priv->rps.hw_lock); + + state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe); + /* + * We only ever set the power-on and power-gate states, anything + * else is unexpected. + */ + WARN_ON(state != DP_SSS_PWR_ON(pipe) && state != DP_SSS_PWR_GATE(pipe)); + enabled = state == DP_SSS_PWR_ON(pipe); + + /* + * A transient state at this point would mean some unexpected party + * is poking at the power controls too. + */ + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe); + WARN_ON(ctrl << 16 != state); + + mutex_unlock(&dev_priv->rps.hw_lock); + + return enabled; +} + +static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well, + bool enable) +{ + enum pipe pipe = power_well->data; + u32 state; + u32 ctrl; + + state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe); + + mutex_lock(&dev_priv->rps.hw_lock); + +#define COND \ + ((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state) + + if (COND) + goto out; + + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + ctrl &= ~DP_SSC_MASK(pipe); + ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, ctrl); + + if (wait_for(COND, 100)) + DRM_ERROR("timout setting power well state %08x (%08x)\n", + state, + vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ)); + +#undef COND + +out: + mutex_unlock(&dev_priv->rps.hw_lock); +} + +static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0); +} + +static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + WARN_ON_ONCE(power_well->data != PIPE_A && + power_well->data != PIPE_B && + power_well->data != PIPE_C); + + chv_set_pipe_power_well(dev_priv, power_well, true); +} + +static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + WARN_ON_ONCE(power_well->data != PIPE_A && + power_well->data != PIPE_B && + power_well->data != PIPE_C); + + chv_set_pipe_power_well(dev_priv, power_well, false); +} + +static void check_power_well_state(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + bool enabled = power_well->ops->is_enabled(dev_priv, power_well); + + if (power_well->always_on || !i915.disable_power_well) { + if (!enabled) + goto mismatch; + + return; + } + + if (enabled != (power_well->count > 0)) + goto mismatch; + + return; + +mismatch: + WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", + power_well->name, power_well->always_on, enabled, + power_well->count, i915.disable_power_well); +} + +void intel_display_power_get(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) +{ + struct i915_power_domains *power_domains; + struct i915_power_well *power_well; + int i; + + intel_runtime_pm_get(dev_priv); + + power_domains = &dev_priv->power_domains; + + mutex_lock(&power_domains->lock); + + for_each_power_well(i, power_well, BIT(domain), power_domains) { + if (!power_well->count++) { + DRM_DEBUG_KMS("enabling %s\n", power_well->name); + power_well->ops->enable(dev_priv, power_well); + power_well->hw_enabled = true; + } + + check_power_well_state(dev_priv, power_well); + } + + power_domains->domain_use_count[domain]++; + + mutex_unlock(&power_domains->lock); +} + +void intel_display_power_put(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) +{ + struct i915_power_domains *power_domains; + struct i915_power_well *power_well; + int i; + + power_domains = &dev_priv->power_domains; + + mutex_lock(&power_domains->lock); + + WARN_ON(!power_domains->domain_use_count[domain]); + power_domains->domain_use_count[domain]--; + + for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { + WARN_ON(!power_well->count); + + if (!--power_well->count && i915.disable_power_well) { + DRM_DEBUG_KMS("disabling %s\n", power_well->name); + power_well->hw_enabled = false; + power_well->ops->disable(dev_priv, power_well); + } + + check_power_well_state(dev_priv, power_well); + } + + mutex_unlock(&power_domains->lock); + + intel_runtime_pm_put(dev_priv); +} + +#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) + +#define HSW_ALWAYS_ON_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PIPE_A) | \ + BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_CRT) | \ + BIT(POWER_DOMAIN_PLLS) | \ + BIT(POWER_DOMAIN_INIT)) +#define HSW_DISPLAY_POWER_DOMAINS ( \ + (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \ + BIT(POWER_DOMAIN_INIT)) + +#define BDW_ALWAYS_ON_POWER_DOMAINS ( \ + HSW_ALWAYS_ON_POWER_DOMAINS | \ + BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER)) +#define BDW_DISPLAY_POWER_DOMAINS ( \ + (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \ + BIT(POWER_DOMAIN_INIT)) + +#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT) +#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK + +#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_CRT) | \ + BIT(POWER_DOMAIN_INIT)) + +#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_PIPE_A_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PIPE_A) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_PIPE_B_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PIPE_B) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_PIPE_C_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PIPE_C) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_DPIO_CMN_BC_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_DPIO_CMN_D_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +#define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ + BIT(POWER_DOMAIN_INIT)) + +static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { + .sync_hw = i9xx_always_on_power_well_noop, + .enable = i9xx_always_on_power_well_noop, + .disable = i9xx_always_on_power_well_noop, + .is_enabled = i9xx_always_on_power_well_enabled, +}; + +static const struct i915_power_well_ops chv_pipe_power_well_ops = { + .sync_hw = chv_pipe_power_well_sync_hw, + .enable = chv_pipe_power_well_enable, + .disable = chv_pipe_power_well_disable, + .is_enabled = chv_pipe_power_well_enabled, +}; + +static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = { + .sync_hw = vlv_power_well_sync_hw, + .enable = chv_dpio_cmn_power_well_enable, + .disable = chv_dpio_cmn_power_well_disable, + .is_enabled = vlv_power_well_enabled, +}; + +static struct i915_power_well i9xx_always_on_power_well[] = { + { + .name = "always-on", + .always_on = 1, + .domains = POWER_DOMAIN_MASK, + .ops = &i9xx_always_on_power_well_ops, + }, +}; + +static const struct i915_power_well_ops hsw_power_well_ops = { + .sync_hw = hsw_power_well_sync_hw, + .enable = hsw_power_well_enable, + .disable = hsw_power_well_disable, + .is_enabled = hsw_power_well_enabled, +}; + +static struct i915_power_well hsw_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = HSW_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "display", + .domains = HSW_DISPLAY_POWER_DOMAINS, + .ops = &hsw_power_well_ops, + }, +}; + +static struct i915_power_well bdw_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = BDW_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "display", + .domains = BDW_DISPLAY_POWER_DOMAINS, + .ops = &hsw_power_well_ops, + }, +}; + +static const struct i915_power_well_ops vlv_display_power_well_ops = { + .sync_hw = vlv_power_well_sync_hw, + .enable = vlv_display_power_well_enable, + .disable = vlv_display_power_well_disable, + .is_enabled = vlv_power_well_enabled, +}; + +static const struct i915_power_well_ops vlv_dpio_cmn_power_well_ops = { + .sync_hw = vlv_power_well_sync_hw, + .enable = vlv_dpio_cmn_power_well_enable, + .disable = vlv_dpio_cmn_power_well_disable, + .is_enabled = vlv_power_well_enabled, +}; + +static const struct i915_power_well_ops vlv_dpio_power_well_ops = { + .sync_hw = vlv_power_well_sync_hw, + .enable = vlv_power_well_enable, + .disable = vlv_power_well_disable, + .is_enabled = vlv_power_well_enabled, +}; + +static struct i915_power_well vlv_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = VLV_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "display", + .domains = VLV_DISPLAY_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DISP2D, + .ops = &vlv_display_power_well_ops, + }, + { + .name = "dpio-tx-b-01", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, + }, + { + .name = "dpio-tx-b-23", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, + }, + { + .name = "dpio-tx-c-01", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, + }, + { + .name = "dpio-tx-c-23", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, + }, + { + .name = "dpio-common", + .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_BC, + .ops = &vlv_dpio_cmn_power_well_ops, + }, +}; + +static struct i915_power_well chv_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = VLV_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, +#if 0 + { + .name = "display", + .domains = VLV_DISPLAY_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DISP2D, + .ops = &vlv_display_power_well_ops, + }, + { + .name = "pipe-a", + .domains = CHV_PIPE_A_POWER_DOMAINS, + .data = PIPE_A, + .ops = &chv_pipe_power_well_ops, + }, + { + .name = "pipe-b", + .domains = CHV_PIPE_B_POWER_DOMAINS, + .data = PIPE_B, + .ops = &chv_pipe_power_well_ops, + }, + { + .name = "pipe-c", + .domains = CHV_PIPE_C_POWER_DOMAINS, + .data = PIPE_C, + .ops = &chv_pipe_power_well_ops, + }, +#endif + { + .name = "dpio-common-bc", + /* + * XXX: cmnreset for one PHY seems to disturb the other. + * As a workaround keep both powered on at the same + * time for now. + */ + .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_BC, + .ops = &chv_dpio_cmn_power_well_ops, + }, + { + .name = "dpio-common-d", + /* + * XXX: cmnreset for one PHY seems to disturb the other. + * As a workaround keep both powered on at the same + * time for now. + */ + .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_D, + .ops = &chv_dpio_cmn_power_well_ops, + }, +#if 0 + { + .name = "dpio-tx-b-01", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, + }, + { + .name = "dpio-tx-b-23", + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, + }, + { + .name = "dpio-tx-c-01", + .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, + }, + { + .name = "dpio-tx-c-23", + .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, + }, + { + .name = "dpio-tx-d-01", + .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | + CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_01, + }, + { + .name = "dpio-tx-d-23", + .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | + CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, + .ops = &vlv_dpio_power_well_ops, + .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_23, + }, +#endif +}; + +static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, + enum punit_power_well power_well_id) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + struct i915_power_well *power_well; + int i; + + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { + if (power_well->data == power_well_id) + return power_well; + } + + return NULL; +} + +#define set_power_wells(power_domains, __power_wells) ({ \ + (power_domains)->power_wells = (__power_wells); \ + (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ +}) + +int intel_power_domains_init(struct drm_i915_private *dev_priv) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + + mutex_init(&power_domains->lock); + + /* + * The enabling order will be from lower to higher indexed wells, + * the disabling order is reversed. + */ + if (IS_HASWELL(dev_priv->dev)) { + set_power_wells(power_domains, hsw_power_wells); + hsw_pwr = power_domains; + } else if (IS_BROADWELL(dev_priv->dev)) { + set_power_wells(power_domains, bdw_power_wells); + hsw_pwr = power_domains; + } else if (IS_CHERRYVIEW(dev_priv->dev)) { + set_power_wells(power_domains, chv_power_wells); + } else if (IS_VALLEYVIEW(dev_priv->dev)) { + set_power_wells(power_domains, vlv_power_wells); + } else { + set_power_wells(power_domains, i9xx_always_on_power_well); + } + + return 0; +} + +void intel_power_domains_remove(struct drm_i915_private *dev_priv) +{ + hsw_pwr = NULL; +} + +static void intel_power_domains_resume(struct drm_i915_private *dev_priv) +{ + struct i915_power_domains *power_domains = &dev_priv->power_domains; + struct i915_power_well *power_well; + int i; + + mutex_lock(&power_domains->lock); + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { + power_well->ops->sync_hw(dev_priv, power_well); + power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, + power_well); + } + mutex_unlock(&power_domains->lock); +} + +static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) +{ + struct i915_power_well *cmn = + lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); + struct i915_power_well *disp2d = + lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); + + /* nothing to do if common lane is already off */ + if (!cmn->ops->is_enabled(dev_priv, cmn)) + return; + + /* If the display might be already active skip this */ + if (disp2d->ops->is_enabled(dev_priv, disp2d) && + I915_READ(DPIO_CTL) & DPIO_CMNRST) + return; + + DRM_DEBUG_KMS("toggling display PHY side reset\n"); + + /* cmnlane needs DPLL registers */ + disp2d->ops->enable(dev_priv, disp2d); + + /* + * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx: + * Need to assert and de-assert PHY SB reset by gating the + * common lane power, then un-gating it. + * Simply ungating isn't enough to reset the PHY enough to get + * ports and lanes running. + */ + cmn->ops->disable(dev_priv, cmn); +} + +void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct i915_power_domains *power_domains = &dev_priv->power_domains; + + power_domains->initializing = true; + + if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { + mutex_lock(&power_domains->lock); + vlv_cmnlane_wa(dev_priv); + mutex_unlock(&power_domains->lock); + } + + /* For now, we need the power well to be always enabled. */ + intel_display_set_init_power(dev_priv, true); + intel_power_domains_resume(dev_priv); + power_domains->initializing = false; +} + +void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv) +{ + intel_runtime_pm_get(dev_priv); +} + +void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv) +{ + intel_runtime_pm_put(dev_priv); +} + +void intel_runtime_pm_get(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + pm_runtime_get_sync(device); + WARN(dev_priv->pm.suspended, "Device still suspended.\n"); +} + +void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + WARN(dev_priv->pm.suspended, "Getting nosync-ref while suspended.\n"); + pm_runtime_get_noresume(device); +} + +void intel_runtime_pm_put(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + pm_runtime_mark_last_busy(device); + pm_runtime_put_autosuspend(device); +} + +void intel_init_runtime_pm(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + pm_runtime_set_active(device); + + /* + * RPM depends on RC6 to save restore the GT HW context, so make RC6 a + * requirement. + */ + if (!intel_enable_rc6(dev)) { + DRM_INFO("RC6 disabled, disabling runtime PM support\n"); + return; + } + + pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */ + pm_runtime_mark_last_busy(device); + pm_runtime_use_autosuspend(device); + + pm_runtime_put_autosuspend(device); +} + +void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + if (!intel_enable_rc6(dev)) + return; + + /* Make sure we're not suspended first. */ + pm_runtime_get_sync(device); + pm_runtime_disable(device); +} + +/* Display audio driver power well request */ +int i915_request_power_well(void) +{ + struct drm_i915_private *dev_priv; + + if (!hsw_pwr) + return -ENODEV; + + dev_priv = container_of(hsw_pwr, struct drm_i915_private, + power_domains); + intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); + return 0; +} +EXPORT_SYMBOL_GPL(i915_request_power_well); + +/* Display audio driver power well release */ +int i915_release_power_well(void) +{ + struct drm_i915_private *dev_priv; + + if (!hsw_pwr) + return -ENODEV; + + dev_priv = container_of(hsw_pwr, struct drm_i915_private, + power_domains); + intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); + return 0; +} +EXPORT_SYMBOL_GPL(i915_release_power_well); + +/* + * Private interface for the audio driver to get CDCLK in kHz. + * + * Caller must request power well using i915_request_power_well() prior to + * making the call. + */ +int i915_get_cdclk_freq(void) +{ + struct drm_i915_private *dev_priv; + + if (!hsw_pwr) + return -ENODEV; + + dev_priv = container_of(hsw_pwr, struct drm_i915_private, + power_domains); + + return intel_ddi_get_cdclk_freq(dev_priv); +} +EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); -- GitLab From f458ebbc3329a6f064e0f40ed5909fe3a7133238 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:39 +0200 Subject: [PATCH 0155/9457] drm/i915: Bikeshed rpm functions name a bit. - fini goes with init, so call it intel_power_domains_fini. While at it shovel some of the fini code that leaked out of it back in. - give power_enabled functions the verb _is_ to make the meaning clearer. Also use a __ prefix instead of _unlocked to really discourage users. - rename runtime_pm_init/fini to enable/disable since that's what they do. Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_dma.c | 12 ++++-------- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_irq.c | 6 +++--- drivers/gpu/drm/i915/intel_crt.c | 2 +- drivers/gpu/drm/i915/intel_ddi.c | 8 ++++---- drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++------------- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 14 ++++++------- drivers/gpu/drm/i915/intel_dsi.c | 2 +- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/intel_lvds.c | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 21 ++++++++++++-------- 13 files changed, 51 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 14c88c22281c..da4036d0bab9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -716,7 +716,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } for_each_pipe(dev_priv, pipe) { - if (!intel_display_power_enabled(dev_priv, + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) { seq_printf(m, "Pipe %c power disabled\n", pipe_name(pipe)); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1c035c49577e..261fc0b60f25 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1798,12 +1798,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN5(dev)) intel_gpu_ips_init(dev_priv); - intel_init_runtime_pm(dev_priv); + intel_runtime_pm_enable(dev_priv); return 0; out_power_well: - intel_power_domains_remove(dev_priv); + intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); out_gem_unload: WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); @@ -1846,15 +1846,11 @@ int i915_driver_unload(struct drm_device *dev) return ret; } - intel_fini_runtime_pm(dev_priv); + intel_runtime_pm_disable(dev_priv); intel_gpu_ips_teardown(); - /* The i915.ko module is still not prepared to be loaded when - * the power well is not enabled, so just enable it in case - * we're going to unload/reload. */ - intel_display_set_init_power(dev_priv, true); - intel_power_domains_remove(dev_priv); + intel_power_domains_fini(dev_priv); i915_teardown_sysfs(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 622c038f880c..5dbd5c92b61b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1411,7 +1411,7 @@ struct ilk_wm_values { * * Our driver uses the autosuspend delay feature, which means we'll only really * suspend if we stay with zero refcount for a certain amount of time. The - * default value is currently very conservative (see intel_init_runtime_pm), but + * default value is currently very conservative (see intel_runtime_pm_enable), but * it can be changed with the standard runtime PM files from sysfs. * * The irqs_disabled variable becomes true exactly after we disable the IRQs and diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 080981b56a4e..eef74ef4736a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3473,8 +3473,8 @@ static void gen8_irq_reset(struct drm_device *dev) gen8_gt_irq_reset(dev_priv); for_each_pipe(dev_priv, pipe) - if (intel_display_power_enabled(dev_priv, - POWER_DOMAIN_PIPE(pipe))) + if (intel_display_power_is_enabled(dev_priv, + POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); GEN5_IRQ_RESET(GEN8_DE_PORT_); @@ -3826,7 +3826,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; for_each_pipe(dev_priv, pipe) - if (intel_display_power_enabled(dev_priv, + if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 9212e6504e0f..dacaad5f4e34 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -72,7 +72,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, u32 tmp; power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; tmp = I915_READ(crt->adpa_reg); diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index c9f4b3c43614..a151de7d13cd 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -998,7 +998,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) uint32_t tmp; power_domain = intel_display_port_power_domain(intel_encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) @@ -1044,7 +1044,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, int i; power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; tmp = I915_READ(DDI_BUF_CTL(port)); @@ -1332,7 +1332,7 @@ static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, { uint32_t val; - if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS)) + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) return false; val = I915_READ(WRPLL_CTL(pll->id)); @@ -1522,7 +1522,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, break; } - if (intel_display_power_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { + if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe * 4))) pipe_config->has_audio = true; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a9605789ad55..ae2d67d4e488 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1210,7 +1210,7 @@ void assert_pipe(struct drm_i915_private *dev_priv, (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) state = true; - if (!intel_display_power_enabled(dev_priv, + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { cur_state = false; } else { @@ -6493,8 +6493,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; uint32_t tmp; - if (!intel_display_power_enabled(dev_priv, - POWER_DOMAIN_PIPE(crtc->pipe))) + if (!intel_display_power_is_enabled(dev_priv, + POWER_DOMAIN_PIPE(crtc->pipe))) return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; @@ -7503,8 +7503,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; uint32_t tmp; - if (!intel_display_power_enabled(dev_priv, - POWER_DOMAIN_PIPE(crtc->pipe))) + if (!intel_display_power_is_enabled(dev_priv, + POWER_DOMAIN_PIPE(crtc->pipe))) return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; @@ -7902,7 +7902,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, enum intel_display_power_domain pfit_domain; uint32_t tmp; - if (!intel_display_power_enabled(dev_priv, + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(crtc->pipe))) return false; @@ -7931,7 +7931,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, pipe_config->cpu_transcoder = TRANSCODER_EDP; } - if (!intel_display_power_enabled(dev_priv, + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) return false; @@ -7944,7 +7944,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, intel_get_pipe_timings(crtc, pipe_config); pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); - if (intel_display_power_enabled(dev_priv, pfit_domain)) + if (intel_display_power_is_enabled(dev_priv, pfit_domain)) ironlake_get_pfit_config(crtc, pipe_config); if (IS_HASWELL(dev)) @@ -11534,7 +11534,7 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, { uint32_t val; - if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS)) + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) return false; val = I915_READ(PCH_DPLL(pll->id)); @@ -13165,7 +13165,7 @@ void i915_redisable_vga(struct drm_device *dev) * level, just check if the power well is enabled instead of trying to * follow the "don't touch the power well if we don't need it" policy * the rest of the driver uses. */ - if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_VGA)) + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_VGA)) return; i915_redisable_vga_power_on(dev); @@ -13543,8 +13543,8 @@ intel_display_capture_error_state(struct drm_device *dev) for_each_pipe(dev_priv, i) { error->pipe[i].power_domain_on = - intel_display_power_enabled_unlocked(dev_priv, - POWER_DOMAIN_PIPE(i)); + __intel_display_power_is_enabled(dev_priv, + POWER_DOMAIN_PIPE(i)); if (!error->pipe[i].power_domain_on) continue; @@ -13579,7 +13579,7 @@ intel_display_capture_error_state(struct drm_device *dev) enum transcoder cpu_transcoder = transcoders[i]; error->transcoder[i].power_domain_on = - intel_display_power_enabled_unlocked(dev_priv, + __intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (!error->transcoder[i].power_domain_on) continue; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 799918f7822c..205363ab758a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1853,7 +1853,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, u32 tmp; power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; tmp = I915_READ(intel_dp->output_reg); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9d2ee70d51e4..dc0c6d55c8fa 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1083,15 +1083,15 @@ extern struct drm_display_mode *intel_find_panel_downclock( /* intel_runtime_pm.c */ int intel_power_domains_init(struct drm_i915_private *); -void intel_power_domains_remove(struct drm_i915_private *); +void intel_power_domains_fini(struct drm_i915_private *); void intel_power_domains_init_hw(struct drm_i915_private *dev_priv); -void intel_init_runtime_pm(struct drm_i915_private *dev_priv); -void intel_fini_runtime_pm(struct drm_i915_private *dev_priv); +void intel_runtime_pm_enable(struct drm_i915_private *dev_priv); +void intel_runtime_pm_disable(struct drm_i915_private *dev_priv); -bool intel_display_power_enabled(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); -bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); +bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); +bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); void intel_display_power_get(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); void intel_display_power_put(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 5bd9e09ad3c5..0b184079de14 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -344,7 +344,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; /* XXX: this only works for one DSI output */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7fed5bedc10f..cf87def7b5b3 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -690,7 +690,7 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, u32 tmp; power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; tmp = I915_READ(intel_hdmi->hdmi_reg); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a6bd1422e38f..2b50c98dd6b0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -76,7 +76,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, u32 tmp; power_domain = intel_display_port_power_domain(encoder); - if (!intel_display_power_enabled(dev_priv, power_domain)) + if (!intel_display_power_is_enabled(dev_priv, power_domain)) return false; tmp = I915_READ(lvds_encoder->reg); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 2344ecfc27cc..dc298c6015c1 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -60,8 +60,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); } -bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) +bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; struct i915_power_well *power_well; @@ -88,8 +88,8 @@ bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, return is_enabled; } -bool intel_display_power_enabled(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) +bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; bool ret; @@ -97,7 +97,7 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, power_domains = &dev_priv->power_domains; mutex_lock(&power_domains->lock); - ret = intel_display_power_enabled_unlocked(dev_priv, domain); + ret = __intel_display_power_is_enabled(dev_priv, domain); mutex_unlock(&power_domains->lock); return ret; @@ -981,8 +981,13 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) return 0; } -void intel_power_domains_remove(struct drm_i915_private *dev_priv) +void intel_power_domains_fini(struct drm_i915_private *dev_priv) { + /* The i915.ko module is still not prepared to be loaded when + * the power well is not enabled, so just enable it in case + * we're going to unload/reload. */ + intel_display_set_init_power(dev_priv, true); + hsw_pwr = NULL; } @@ -1097,7 +1102,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) pm_runtime_put_autosuspend(device); } -void intel_init_runtime_pm(struct drm_i915_private *dev_priv) +void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct device *device = &dev->pdev->dev; @@ -1123,7 +1128,7 @@ void intel_init_runtime_pm(struct drm_i915_private *dev_priv) pm_runtime_put_autosuspend(device); } -void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) +void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct device *device = &dev->pdev->dev; -- GitLab From d9bc89d9e39c2c1a76cd37b5e8cc1592a7898848 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:40 +0200 Subject: [PATCH 0156/9457] drm/i915: Move intel_display_set_init_power to intel_runtime_pm.c I've decided to not move intel_display_port_power_domain because that's just a hack in our design ... Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 14 -------------- drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_runtime_pm.c | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ae2d67d4e488..7877b163b5b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4560,20 +4560,6 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc) return mask; } -void intel_display_set_init_power(struct drm_i915_private *dev_priv, - bool enable) -{ - if (dev_priv->power_domains.init_power_on == enable) - return; - - if (enable) - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - else - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); - - dev_priv->power_domains.init_power_on = enable; -} - static void modeset_update_crtc_power_domains(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index dc0c6d55c8fa..64fe05e3d1a5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -934,7 +934,6 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config, bool intel_crtc_active(struct drm_crtc *crtc); void hsw_enable_ips(struct intel_crtc *crtc); void hsw_disable_ips(struct intel_crtc *crtc); -void intel_display_set_init_power(struct drm_i915_private *dev, bool enable); enum intel_display_power_domain intel_display_port_power_domain(struct intel_encoder *intel_encoder); void intel_mode_from_pipe_config(struct drm_display_mode *mode, @@ -1102,6 +1101,8 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv); void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); void intel_runtime_pm_put(struct drm_i915_private *dev_priv); +void intel_display_set_init_power(struct drm_i915_private *dev, bool enable); + /* intel_pm.c */ void intel_init_clock_gating(struct drm_device *dev); void intel_suspend_hw(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index dc298c6015c1..34f91c1c8de6 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -103,6 +103,20 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, return ret; } +void intel_display_set_init_power(struct drm_i915_private *dev_priv, + bool enable) +{ + if (dev_priv->power_domains.init_power_on == enable) + return; + + if (enable) + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + else + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); + + dev_priv->power_domains.init_power_on = enable; +} + /* * Starting with Haswell, we have a "Power Down Well" that can be turned off * when not needed anymore. We have 4 registers that can request the power well -- GitLab From 41373cd53fdeb658fadd8cd0313591ce49e4342f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:41 +0200 Subject: [PATCH 0157/9457] drm/i915: Call runtime_pm_disable directly Allows us to mark it static and so forgoe the kerneldoc for it. Note that intel_power_domains_fini is also called from failure paths in the driver load sequence. But the call to runtime_pm_disable for that is harmless since by default runtime pm is already disabled. v2: Augment the commit message as discussed with Imre on irc. Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 +-- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_runtime_pm.c | 34 +++++++++++++------------ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 261fc0b60f25..d58c711a55c4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1846,12 +1846,10 @@ int i915_driver_unload(struct drm_device *dev) return ret; } - intel_runtime_pm_disable(dev_priv); + intel_power_domains_fini(dev_priv); intel_gpu_ips_teardown(); - intel_power_domains_fini(dev_priv); - i915_teardown_sysfs(dev); WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 64fe05e3d1a5..1deb5d837049 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1085,7 +1085,6 @@ int intel_power_domains_init(struct drm_i915_private *); void intel_power_domains_fini(struct drm_i915_private *); void intel_power_domains_init_hw(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable(struct drm_i915_private *dev_priv); -void intel_runtime_pm_disable(struct drm_i915_private *dev_priv); bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 34f91c1c8de6..dc63b7890eef 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -995,8 +995,26 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) return 0; } +static void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct device *device = &dev->pdev->dev; + + if (!HAS_RUNTIME_PM(dev)) + return; + + if (!intel_enable_rc6(dev)) + return; + + /* Make sure we're not suspended first. */ + pm_runtime_get_sync(device); + pm_runtime_disable(device); +} + void intel_power_domains_fini(struct drm_i915_private *dev_priv) { + intel_runtime_pm_disable(dev_priv); + /* The i915.ko module is still not prepared to be loaded when * the power well is not enabled, so just enable it in case * we're going to unload/reload. */ @@ -1142,22 +1160,6 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) pm_runtime_put_autosuspend(device); } -void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct device *device = &dev->pdev->dev; - - if (!HAS_RUNTIME_PM(dev)) - return; - - if (!intel_enable_rc6(dev)) - return; - - /* Make sure we're not suspended first. */ - pm_runtime_get_sync(device); - pm_runtime_disable(device); -} - /* Display audio driver power well request */ int i915_request_power_well(void) { -- GitLab From e4e7684fc5c5e6ef9d4fdbbc2f08917a61cbd708 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:42 +0200 Subject: [PATCH 0158/9457] drm/i915: Kerneldoc for intel_runtime_pm.c I've decided not to document the functions exported to the audio driver since really, they shouldn't exist ... v2: Improvements from Imre's review plus a few more spelling fixes I've spotted. Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 12 ++ drivers/gpu/drm/i915/intel_runtime_pm.c | 166 +++++++++++++++++++++++- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 98528b49da65..8627816e58f3 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3787,6 +3787,18 @@ int num_ioctls; blocks. This excludes a set of SoC platforms with an SGX rendering unit, those have basic support through the gma500 drm driver. + + Core Driver Infrastructure + + This section covers core driver infrastructure used by both the display + and the GEM parts of the driver. + + + Runtime Power Management +!Pdrivers/gpu/drm/i915/intel_runtime_pm.c runtime pm +!Idrivers/gpu/drm/i915/intel_runtime_pm.c + + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index dc63b7890eef..abefc98dcc8f 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -33,6 +33,23 @@ #include "intel_drv.h" #include +/** + * DOC: runtime pm + * + * The i915 driver supports dynamic enabling and disabling of entire hardware + * blocks at runtime. This is especially important on the display side where + * software is supposed to control many power gates manually on recent hardware, + * since on the GT side a lot of the power management is done by the hardware. + * But even there some manual control at the device level is required. + * + * Since i915 supports a diverse set of platforms with a unified codebase and + * hardware engineers just love to shuffle functionality around between power + * domains there's a sizeable amount of indirection required. This file provides + * generic functions to the driver for grabbing and releasing references for + * abstract power domains. It then maps those to the actual power wells + * present for a given platform. + */ + static struct i915_power_domains *hsw_pwr; #define for_each_power_well(i, power_well, domain_mask, power_domains) \ @@ -48,7 +65,7 @@ static struct i915_power_domains *hsw_pwr; i--) \ if ((power_well)->domains & (domain_mask)) -/** +/* * We should only use the power well if we explicitly asked the hardware to * enable it, so check if it's enabled and also check if we've requested it to * be enabled. @@ -60,6 +77,18 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); } +/** + * __intel_display_power_is_enabled - unlocked check for a power domain + * @dev_priv: i915 device instance + * @domain: power domain to check + * + * This is the unlocked version of intel_display_power_is_enabled() and should + * only be used from error capture and recovery code where deadlocks are + * possible. + * + * Returns: + * True when the power domain is enabled, false otherwise. + */ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { @@ -88,6 +117,23 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, return is_enabled; } +/** + * intel_display_power_is_enabled - unlocked check for a power domain + * @dev_priv: i915 device instance + * @domain: power domain to check + * + * This function can be used to check the hw power domain state. It is mostly + * used in hardware state readout functions. Everywhere else code should rely + * upon explicit power domain reference counting to ensure that the hardware + * block is powered up before accessing it. + * + * Callers must hold the relevant modesetting locks to ensure that concurrent + * threads can't disable the power well while the caller tries to read a few + * registers. + * + * Returns: + * True when the power domain is enabled, false otherwise. + */ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { @@ -103,6 +149,16 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, return ret; } +/** + * intel_display_set_init_power - set the initial power domain state + * @dev_priv: i915 device instance + * @enable: whether to enable or disable the initial power domain state + * + * For simplicity our driver load/unload and system suspend/resume code assumes + * that all power domains are always enabled. This functions controls the state + * of this little hack. While the initial power domain state is enabled runtime + * pm is effectively disabled. + */ void intel_display_set_init_power(struct drm_i915_private *dev_priv, bool enable) { @@ -556,6 +612,18 @@ static void check_power_well_state(struct drm_i915_private *dev_priv, power_well->count, i915.disable_power_well); } +/** + * intel_display_power_get - grab a power domain reference + * @dev_priv: i915 device instance + * @domain: power domain to reference + * + * This function grabs a power domain reference for @domain and ensures that the + * power domain and all its parents are powered up. Therefore users should only + * grab a reference to the innermost power domain they need. + * + * Any power domain reference obtained by this function must have a symmetric + * call to intel_display_power_put() to release the reference again. + */ void intel_display_power_get(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { @@ -584,6 +652,15 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); } +/** + * intel_display_power_put - release a power domain reference + * @dev_priv: i915 device instance + * @domain: power domain to reference + * + * This function drops the power domain reference obtained by + * intel_display_power_get() and might power down the corresponding hardware + * block right away if this is the last reference. + */ void intel_display_power_put(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { @@ -968,6 +1045,13 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ }) +/** + * intel_power_domains_init - initializes the power domain structures + * @dev_priv: i915 device instance + * + * Initializes the power domain structures for @dev_priv depending upon the + * supported platform. + */ int intel_power_domains_init(struct drm_i915_private *dev_priv) { struct i915_power_domains *power_domains = &dev_priv->power_domains; @@ -1011,6 +1095,14 @@ static void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) pm_runtime_disable(device); } +/** + * intel_power_domains_fini - finalizes the power domain structures + * @dev_priv: i915 device instance + * + * Finalizes the power domain structures for @dev_priv depending upon the + * supported platform. This function also disables runtime pm and ensures that + * the device stays powered up so that the driver can be reloaded. + */ void intel_power_domains_fini(struct drm_i915_private *dev_priv) { intel_runtime_pm_disable(dev_priv); @@ -1069,6 +1161,13 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) cmn->ops->disable(dev_priv, cmn); } +/** + * intel_power_domains_init_hw - initialize hardware power domain state + * @dev_priv: i915 device instance + * + * This function initializes the hardware power domain state and enables all + * power domains using intel_display_set_init_power(). + */ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -1088,16 +1187,46 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) power_domains->initializing = false; } +/** + * intel_aux_display_runtime_get - grab an auxilliary power domain reference + * @dev_priv: i915 device instance + * + * This function grabs a power domain reference for the auxiliary power domain + * (for access to the GMBUS and DP AUX blocks) and ensures that it and all its + * parents are powered up. Therefore users should only grab a reference to the + * innermost power domain they need. + * + * Any power domain reference obtained by this function must have a symmetric + * call to intel_aux_display_runtime_put() to release the reference again. + */ void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv) { intel_runtime_pm_get(dev_priv); } +/** + * intel_aux_display_runtime_put - release an auxilliary power domain reference + * @dev_priv: i915 device instance + * + * This function drops the auxilliary power domain reference obtained by + * intel_aux_display_runtime_get() and might power down the corresponding + * hardware block right away if this is the last reference. + */ void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv) { intel_runtime_pm_put(dev_priv); } +/** + * intel_runtime_pm_get - grab a runtime pm reference + * @dev_priv: i915 device instance + * + * This function grabs a device-level runtime pm reference (mostly used for GEM + * code to ensure the GTT or GT is on) and ensures that it is powered up. + * + * Any runtime pm reference obtained by this function must have a symmetric + * call to intel_runtime_pm_put() to release the reference again. + */ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -1110,6 +1239,23 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) WARN(dev_priv->pm.suspended, "Device still suspended.\n"); } +/** + * intel_runtime_pm_get_noresume - grab a runtime pm reference + * @dev_priv: i915 device instance + * + * This function grabs a device-level runtime pm reference (mostly used for GEM + * code to ensure the GTT or GT is on). + * + * It will _not_ power up the device but instead only check that it's powered + * on. Therefore it is only valid to call this functions from contexts where + * the device is known to be powered up and where trying to power it up would + * result in hilarity and deadlocks. That pretty much means only the system + * suspend/resume code where this is used to grab runtime pm references for + * delayed setup down in work items. + * + * Any runtime pm reference obtained by this function must have a symmetric + * call to intel_runtime_pm_put() to release the reference again. + */ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -1122,6 +1268,14 @@ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) pm_runtime_get_noresume(device); } +/** + * intel_runtime_pm_put - release a runtime pm reference + * @dev_priv: i915 device instance + * + * This function drops the device-level runtime pm reference obtained by + * intel_runtime_pm_get() and might power down the corresponding + * hardware block right away if this is the last reference. + */ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -1134,6 +1288,16 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) pm_runtime_put_autosuspend(device); } +/** + * intel_runtime_pm_enable - enable runtime pm + * @dev_priv: i915 device instance + * + * This function enables runtime pm at the end of the driver load sequence. + * + * Note that this function does currently not enable runtime pm for the + * subordinate display power domains. That is only done on the first modeset + * using intel_display_set_init_power(). + */ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; -- GitLab From d8f2716a1a46bed27ce210e74c7fec3855595200 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Oct 2014 01:02:04 +0200 Subject: [PATCH 0159/9457] drm/i915: Reinstate error level message for non-simulated gpu hangs This seems to have been accidentally lost in commit be62acb4cce1389a28296852737e3917d9cc5b25 Author: Mika Kuoppala Date: Fri Aug 30 16:19:28 2013 +0300 drm/i915: ban badly behaving contexts Without this real gpu hangs only log output at info level, which gets filtered away by piglit's testrunner. v2: Tune down to notice level. Note that we need to add drm/i915 so that at least the automatic igt dmesg filtering still picks it up. v3: git add and lack of coffee don't mix well. v4: Message is in between hw and sw reset, so switch verb to continuous form. v5: Use i915_stop_rings_allow_warn for consistency. For Chris' case of injecting lots of hangs I guess we need to revamp this all anyway when merging. For now this should plug the regression for piglit testing mesa. v6: Make it compile (Mika). Cc: Mika Kuoppala Cc: Chris Wilson Cc: Kenneth Graunke Reported-by: Kenneth Graunke Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ea93ff151a74..66489fa5ce43 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -844,6 +844,9 @@ int i915_reset(struct drm_device *dev) } } + if (i915_stop_ring_allow_warn(dev_priv)) + pr_notice("drm/i915: Resetting chip after gpu hang\n"); + if (ret) { DRM_ERROR("Failed to reset chip: %i\n", ret); mutex_unlock(&dev->struct_mutex); -- GitLab From 5ca476f8874eec7eaec06d402dff2e6b47886d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 1 Oct 2014 16:56:56 +0300 Subject: [PATCH 0160/9457] drm/i915: De-magic the PSR AUX message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use pack_aux() to construct the PSR exit DPMS D0 AUX message, and use the defines from dp_dp_helper.h to populate the message contents. v2: Use sizeof() for message size (Jani) Use a generic loop to write EDP_PSR_AUX_DATA registers Cc: Jani Nikula Cc: Rodrigo Vivi Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 -- drivers/gpu/drm/i915/intel_dp.c | 21 ++++++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c62f3eb3911d..607d7a5d2e4c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2503,9 +2503,7 @@ enum punit_power_well { #define EDP_PSR_AUX_CTL(dev) (EDP_PSR_BASE(dev) + 0x10) #define EDP_PSR_AUX_DATA1(dev) (EDP_PSR_BASE(dev) + 0x14) -#define EDP_PSR_DPCD_COMMAND 0x80060000 #define EDP_PSR_AUX_DATA2(dev) (EDP_PSR_BASE(dev) + 0x18) -#define EDP_PSR_DPCD_NORMAL_OPERATION (1<<24) #define EDP_PSR_AUX_DATA3(dev) (EDP_PSR_BASE(dev) + 0x1c) #define EDP_PSR_AUX_DATA4(dev) (EDP_PSR_BASE(dev) + 0x20) #define EDP_PSR_AUX_DATA5(dev) (EDP_PSR_BASE(dev) + 0x24) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 205363ab758a..7ba3e1bb711a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -225,7 +225,7 @@ intel_dp_mode_valid(struct drm_connector *connector, } static uint32_t -pack_aux(uint8_t *src, int src_bytes) +pack_aux(const uint8_t *src, int src_bytes) { int i; uint32_t v = 0; @@ -2045,8 +2045,17 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dev->dev_private; uint32_t aux_clock_divider; int precharge = 0x3; - int msg_size = 5; /* Header(4) + Message(1) */ bool only_standby = false; + static const uint8_t aux_msg[] = { + [0] = DP_AUX_NATIVE_WRITE << 4, + [1] = DP_SET_POWER >> 8, + [2] = DP_SET_POWER & 0xff, + [3] = 1 - 1, + [4] = DP_SET_POWER_D0, + }; + int i; + + BUILD_BUG_ON(sizeof(aux_msg) > 20); aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); @@ -2062,11 +2071,13 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); /* Setup AUX registers */ - I915_WRITE(EDP_PSR_AUX_DATA1(dev), EDP_PSR_DPCD_COMMAND); - I915_WRITE(EDP_PSR_AUX_DATA2(dev), EDP_PSR_DPCD_NORMAL_OPERATION); + for (i = 0; i < sizeof(aux_msg); i += 4) + I915_WRITE(EDP_PSR_AUX_DATA1(dev) + i, + pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); + I915_WRITE(EDP_PSR_AUX_CTL(dev), DP_AUX_CH_CTL_TIME_OUT_400us | - (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | + (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); } -- GitLab From bd9f74a5e7365546c9c858ca8fa585906cba3979 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Oct 2014 09:45:35 +0200 Subject: [PATCH 0161/9457] drm/i915: Constify send buffer for intel_dp_aux_ch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inspired by Ville constifying the send buffer for pach_aux. Cc: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7ba3e1bb711a..b2aedcf8c8ec 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -718,7 +718,7 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp, static int intel_dp_aux_ch(struct intel_dp *intel_dp, - uint8_t *send, int send_bytes, + const uint8_t *send, int send_bytes, uint8_t *recv, int recv_size) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); -- GitLab From 1dda5f930451a8b9cbe915182cc64811fd67e186 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 1 Oct 2014 07:32:37 -0700 Subject: [PATCH 0162/9457] drm/i915: make sink_crc return -EIO on aux read/write failure Even though it's unliky, we should check each aux transaction not just the first one. Also commit ce31d9f4fc05964f6c0dd3a8661dc1a1d843a1e2 Author: Rodrigo Vivi Date: Mon Sep 29 18:29:52 2014 -0400 drm/i915: preserve other DP_TEST_SINK bits. added a new aux transaction before the one which was checked. Fix this. Cc: Daniel Vetter Cc: Todd Previte Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b2aedcf8c8ec..50bcd09f53be 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3875,16 +3875,21 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) if (!(buf & DP_TEST_CRC_SUPPORTED)) return -ENOTTY; - drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf); + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) + return -EIO; + if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, buf | DP_TEST_SINK_START) < 0) return -EIO; - drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf); + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) + return -EIO; test_crc_count = buf & DP_TEST_COUNT_MASK; do { - drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf); + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_TEST_SINK_MISC, &buf) < 0) + return -EIO; intel_wait_for_vblank(dev, intel_crtc->pipe); } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); @@ -3896,9 +3901,11 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) return -EIO; - drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf); - drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, - buf & ~DP_TEST_SINK_START); + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) + return -EIO; + if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, + buf & ~DP_TEST_SINK_START) < 0) + return -EIO; return 0; } -- GitLab From a26a42508157bc9fda89e3b1d64e47b9e4b55c30 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Wed, 1 Oct 2014 22:28:55 +0200 Subject: [PATCH 0163/9457] HSI: remove deprecated IRQF_DISABLED Remove the use of the IRQF_DISABLED flag from drivers/hsi/clients/nokia-modem.c It's a NOOP since 2.6.35 and it will be removed soon. Signed-off-by: Michael Opdenacker Acked-by: Pavel Machek Signed-off-by: Sebastian Reichel --- drivers/hsi/clients/nokia-modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c index 363b780dacea..e43c3c9acec1 100644 --- a/drivers/hsi/clients/nokia-modem.c +++ b/drivers/hsi/clients/nokia-modem.c @@ -174,7 +174,7 @@ static int nokia_modem_probe(struct device *dev) tasklet_init(&modem->nokia_modem_rst_ind_tasklet, do_nokia_modem_rst_ind_tasklet, (unsigned long)modem); err = devm_request_irq(dev, irq, nokia_modem_rst_ind_isr, - IRQF_DISABLED | pflags, "modem_rst_ind", modem); + pflags, "modem_rst_ind", modem); if (err < 0) { dev_err(dev, "Request rst_ind irq(%d) failed (flags %d)\n", irq, pflags); -- GitLab From a02ef3c7193c942c286cef815c3dc2b2f03660b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 18 Aug 2014 14:42:45 +0300 Subject: [PATCH 0164/9457] drm/i915: Make sure hardware uses the correct swing margin/deemph bits on chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The register can house two different swing marging/deemph settings at once. However only one gets used based on some other bits. Make sure we set those bits correctly to make the hardware use the settings we provided. Signed-off-by: Ville Syrjälä Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 19 +++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 14 ++++++++++++++ drivers/gpu/drm/i915/intel_hdmi.c | 14 ++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 607d7a5d2e4c..d0df76d48184 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -836,12 +836,31 @@ enum punit_power_well { #define _VLV_PCS_DW9_CH0 0x8224 #define _VLV_PCS_DW9_CH1 0x8424 +#define DPIO_PCS_TX2MARGIN_MASK (0x7<<13) +#define DPIO_PCS_TX2MARGIN_000 (0<<13) +#define DPIO_PCS_TX2MARGIN_101 (1<<13) +#define DPIO_PCS_TX1MARGIN_MASK (0x7<<10) +#define DPIO_PCS_TX1MARGIN_000 (0<<10) +#define DPIO_PCS_TX1MARGIN_101 (1<<10) #define VLV_PCS_DW9(ch) _PORT(ch, _VLV_PCS_DW9_CH0, _VLV_PCS_DW9_CH1) +#define _VLV_PCS01_DW9_CH0 0x224 +#define _VLV_PCS23_DW9_CH0 0x424 +#define _VLV_PCS01_DW9_CH1 0x2624 +#define _VLV_PCS23_DW9_CH1 0x2824 +#define VLV_PCS01_DW9(ch) _PORT(ch, _VLV_PCS01_DW9_CH0, _VLV_PCS01_DW9_CH1) +#define VLV_PCS23_DW9(ch) _PORT(ch, _VLV_PCS23_DW9_CH0, _VLV_PCS23_DW9_CH1) + #define _CHV_PCS_DW10_CH0 0x8228 #define _CHV_PCS_DW10_CH1 0x8428 #define DPIO_PCS_SWING_CALC_TX0_TX2 (1<<30) #define DPIO_PCS_SWING_CALC_TX1_TX3 (1<<31) +#define DPIO_PCS_TX2DEEMP_MASK (0xf<<24) +#define DPIO_PCS_TX2DEEMP_9P5 (0<<24) +#define DPIO_PCS_TX2DEEMP_6P0 (2<<24) +#define DPIO_PCS_TX1DEEMP_MASK (0xf<<16) +#define DPIO_PCS_TX1DEEMP_9P5 (0<<16) +#define DPIO_PCS_TX1DEEMP_6P0 (2<<16) #define CHV_PCS_DW10(ch) _PORT(ch, _CHV_PCS_DW10_CH0, _CHV_PCS_DW10_CH1) #define _VLV_PCS01_DW10_CH0 0x0228 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 50bcd09f53be..22d6c3ed371e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3152,12 +3152,26 @@ static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp) /* Clear calc init */ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); + val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); + val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); + val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); + val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch)); + val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); + val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; + vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val); + + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); + val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); + val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val); + /* Program swing deemph */ for (i = 0; i < 4; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i)); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index cf87def7b5b3..386932a256e1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1436,12 +1436,26 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) /* Clear calc init */ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); + val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); + val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); + val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); + val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch)); + val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); + val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; + vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val); + + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); + val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); + val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val); + /* FIXME: Program the support xxx V-dB */ /* Use 800mV-0dB */ for (i = 0; i < 4; i++) { -- GitLab From 570e2a747bc06cd8620662c5125ec2dc964c511b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 18 Aug 2014 14:42:46 +0300 Subject: [PATCH 0165/9457] drm/i915: Clear TX FIFO reset master override bits on chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear the override bits to make sure the hardware manages the TX FIFO reset master on its own. v2: Squash with the earlier attempt at forcing the override bits Signed-off-by: Ville Syrjälä Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ drivers/gpu/drm/i915/intel_hdmi.c | 9 +++++++++ 3 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d0df76d48184..2ed02c391f3b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -796,6 +796,8 @@ enum punit_power_well { #define _VLV_PCS_DW0_CH1 0x8400 #define DPIO_PCS_TX_LANE2_RESET (1<<16) #define DPIO_PCS_TX_LANE1_RESET (1<<7) +#define DPIO_LEFT_TXFIFO_RST_MASTER2 (1<<4) +#define DPIO_RIGHT_TXFIFO_RST_MASTER2 (1<<3) #define VLV_PCS_DW0(ch) _PORT(ch, _VLV_PCS_DW0_CH0, _VLV_PCS_DW0_CH1) #define _VLV_PCS01_DW0_CH0 0x200 @@ -872,8 +874,18 @@ enum punit_power_well { #define _VLV_PCS_DW11_CH0 0x822c #define _VLV_PCS_DW11_CH1 0x842c +#define DPIO_LANEDESKEW_STRAP_OVRD (1<<3) +#define DPIO_LEFT_TXFIFO_RST_MASTER (1<<1) +#define DPIO_RIGHT_TXFIFO_RST_MASTER (1<<0) #define VLV_PCS_DW11(ch) _PORT(ch, _VLV_PCS_DW11_CH0, _VLV_PCS_DW11_CH1) +#define _VLV_PCS01_DW11_CH0 0x022c +#define _VLV_PCS23_DW11_CH0 0x042c +#define _VLV_PCS01_DW11_CH1 0x262c +#define _VLV_PCS23_DW11_CH1 0x282c +#define VLV_PCS01_DW11(ch) _PORT(ch, _VLV_PCS01_DW0_CH0, _VLV_PCS01_DW0_CH1) +#define VLV_PCS23_DW11(ch) _PORT(ch, _VLV_PCS23_DW0_CH0, _VLV_PCS23_DW0_CH1) + #define _VLV_PCS_DW12_CH0 0x8230 #define _VLV_PCS_DW12_CH1 0x8430 #define VLV_PCS_DW12(ch) _PORT(ch, _VLV_PCS_DW12_CH0, _VLV_PCS_DW12_CH1) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 22d6c3ed371e..3fed8cb22f4d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2731,6 +2731,15 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) mutex_lock(&dev_priv->dpio_lock); + /* allow hardware to manage TX FIFO reset source */ + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch)); + val &= ~DPIO_LANEDESKEW_STRAP_OVRD; + vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); + + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); + val &= ~DPIO_LANEDESKEW_STRAP_OVRD; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); + /* Deassert soft data lane reset*/ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch)); val |= CHV_PCS_REQ_SOFTRESET_EN; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 386932a256e1..9cbb7e4a40f5 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1400,6 +1400,15 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) mutex_lock(&dev_priv->dpio_lock); + /* allow hardware to manage TX FIFO reset source */ + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch)); + val &= ~DPIO_LANEDESKEW_STRAP_OVRD; + vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); + + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); + val &= ~DPIO_LANEDESKEW_STRAP_OVRD; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); + /* Deassert soft data lane reset*/ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch)); val |= CHV_PCS_REQ_SOFTRESET_EN; -- GitLab From 2aeb7d3a4d425be7e9185e79dd745918f7f72552 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:43 +0200 Subject: [PATCH 0166/9457] drm/i915: s/pm._irqs_disabled/pm.irqs_enabled/ Double negations just parse harder. Also this allows us to ditch some init code since clearing to 0 dtrt. Also ditch the assignment in intel_pm_setup, that's not redundant since we do the assignement now while setting up interrupts. While at it do engage in a bit of OCD and wrap up the few lines of setup/teardown code into little helper functions: intel_irq_fini for cleanup and intel_irq_init_hw for hw setup. v2: Use _install/_uninstall for the new wrapper function names as Paulo suggested. Signed-off-by: Daniel Vetter Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 9 +-------- drivers/gpu/drm/i915/i915_drv.h | 4 +++- drivers/gpu/drm/i915/i915_irq.c | 26 +++++++++++++++++++++----- drivers/gpu/drm/i915/intel_display.c | 4 +--- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 1 - 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d58c711a55c4..515fa6d3c993 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1338,14 +1338,7 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_power_domains_init_hw(dev_priv); - /* - * We enable some interrupt sources in our postinstall hooks, so mark - * interrupts as enabled _before_ actually enabling them to avoid - * special cases in our ordering checks. - */ - dev_priv->pm._irqs_disabled = false; - - ret = drm_irq_install(dev, dev->pdev->irq); + ret = intel_irq_install(dev_priv); if (ret) goto cleanup_gem_stolen; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5dbd5c92b61b..b4c4f6f1f0e1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1424,7 +1424,7 @@ struct ilk_wm_values { */ struct i915_runtime_pm { bool suspended; - bool _irqs_disabled; + bool irqs_enabled; }; enum intel_pipe_crc_source { @@ -2311,6 +2311,8 @@ void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir, int new_delay); extern void intel_irq_init(struct drm_device *dev); extern void intel_hpd_init(struct drm_device *dev); +int intel_irq_install(struct drm_i915_private *dev_priv); +void intel_irq_uninstall(struct drm_i915_private *dev_priv); extern void intel_uncore_sanitize(struct drm_device *dev); extern void intel_uncore_early_sanitize(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index eef74ef4736a..c07f576c5974 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4675,9 +4675,6 @@ void intel_irq_init(struct drm_device *dev) pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); - /* Haven't installed the IRQ handler yet */ - dev_priv->pm._irqs_disabled = true; - if (IS_GEN2(dev)) { dev->max_vblank_count = 0; dev->driver->get_vblank_counter = i8xx_get_vblank_counter; @@ -4786,13 +4783,32 @@ void intel_hpd_init(struct drm_device *dev) spin_unlock_irq(&dev_priv->irq_lock); } +int intel_irq_install(struct drm_i915_private *dev_priv) +{ + /* + * We enable some interrupt sources in our postinstall hooks, so mark + * interrupts as enabled _before_ actually enabling them to avoid + * special cases in our ordering checks. + */ + dev_priv->pm.irqs_enabled = true; + + return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq); +} + +void intel_irq_uninstall(struct drm_i915_private *dev_priv) +{ + drm_irq_uninstall(dev_priv->dev); + intel_hpd_cancel_work(dev_priv); + dev_priv->pm.irqs_enabled = false; +} + /* Disable interrupts so we can allow runtime PM. */ void intel_runtime_pm_disable_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; dev->driver->irq_uninstall(dev); - dev_priv->pm._irqs_disabled = true; + dev_priv->pm.irqs_enabled = false; } /* Restore interrupts so we can recover from runtime PM. */ @@ -4800,7 +4816,7 @@ void intel_runtime_pm_restore_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->pm._irqs_disabled = false; + dev_priv->pm.irqs_enabled = true; dev->driver->irq_preinstall(dev); dev->driver->irq_postinstall(dev); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7877b163b5b9..6fc77a100cc6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13372,9 +13372,7 @@ void intel_modeset_cleanup(struct drm_device *dev) * Too much stuff here (turning of rps, connectors, ...) would * experience fancy races otherwise. */ - drm_irq_uninstall(dev); - intel_hpd_cancel_work(dev_priv); - dev_priv->pm._irqs_disabled = true; + intel_irq_uninstall(dev_priv); /* * Due to the hpd irq storm handling the hotplug work can re-arm the diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1deb5d837049..2d029d8aaec1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -772,7 +772,7 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) * We only use drm_irq_uninstall() at unload and VT switch, so * this is the only thing we need to check. */ - return !dev_priv->pm._irqs_disabled; + return dev_priv->pm.irqs_enabled; } int intel_get_crtc_scanline(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 95006e0e982b..79108059b79b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6531,5 +6531,4 @@ void intel_pm_setup(struct drm_device *dev) intel_gen6_powersave_work); dev_priv->pm.suspended = false; - dev_priv->pm._irqs_disabled = false; } -- GitLab From b963291cf9af882b2f30693fa8459afbdb0ed288 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:44 +0200 Subject: [PATCH 0167/9457] drm/i915: Use dev_priv instead of dev in irq setup functions It's the new world order! Not going full monty on these here and rolling this out throughout the subsequent call chains since this is just for the kerneldoc. Later on we can go more crazy, especially once we've embedded drm_device correctly. v2: Also frob the runtime_pm functions ... Signed-off-by: Daniel Vetter Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 +-- drivers/gpu/drm/i915/i915_drv.c | 12 ++++---- drivers/gpu/drm/i915/i915_drv.h | 4 +-- drivers/gpu/drm/i915/i915_irq.c | 40 +++++++++++-------------- drivers/gpu/drm/i915/intel_drv.h | 4 +-- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- 6 files changed, 31 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 515fa6d3c993..85d14e169409 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1363,7 +1363,7 @@ static int i915_load_modeset_init(struct drm_device *dev) goto cleanup_gem; /* Only enable hotplug handling once the fbdev is fully set up. */ - intel_hpd_init(dev); + intel_hpd_init(dev_priv); /* * Some ports require correctly set-up hpd registers for detection to @@ -1733,7 +1733,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_freewq; } - intel_irq_init(dev); + intel_irq_init(dev_priv); intel_uncore_sanitize(dev); /* Try to make sure MCHBAR is enabled before poking at it */ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 66489fa5ce43..bd7978cb094f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -599,7 +599,7 @@ static int i915_drm_freeze(struct drm_device *dev) flush_delayed_work(&dev_priv->rps.delayed_resume_work); - intel_runtime_pm_disable_interrupts(dev); + intel_runtime_pm_disable_interrupts(dev_priv); intel_hpd_cancel_work(dev_priv); intel_suspend_encoders(dev_priv); @@ -705,7 +705,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) mutex_unlock(&dev->struct_mutex); /* We need working interrupts for modeset enabling ... */ - intel_runtime_pm_restore_interrupts(dev); + intel_runtime_pm_enable_interrupts(dev_priv); intel_modeset_init_hw(dev); @@ -727,7 +727,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) * bother with the tiny race here where we might loose hotplug * notifications. * */ - intel_hpd_init(dev); + intel_hpd_init(dev_priv); /* Config may have changed between suspend and resume */ drm_helper_hpd_irq_event(dev); } @@ -1473,12 +1473,12 @@ static int intel_runtime_suspend(struct device *device) * intel_mark_idle(). */ cancel_work_sync(&dev_priv->rps.work); - intel_runtime_pm_disable_interrupts(dev); + intel_runtime_pm_disable_interrupts(dev_priv); ret = intel_suspend_complete(dev_priv); if (ret) { DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); - intel_runtime_pm_restore_interrupts(dev); + intel_runtime_pm_enable_interrupts(dev_priv); return ret; } @@ -1538,7 +1538,7 @@ static int intel_runtime_resume(struct device *device) i915_gem_init_swizzling(dev); gen6_update_ring_freq(dev); - intel_runtime_pm_restore_interrupts(dev); + intel_runtime_pm_enable_interrupts(dev_priv); intel_reset_gt_powersave(dev); if (ret) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b4c4f6f1f0e1..9cc13291ccb9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2309,8 +2309,8 @@ void i915_handle_error(struct drm_device *dev, bool wedged, void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir, int new_delay); -extern void intel_irq_init(struct drm_device *dev); -extern void intel_hpd_init(struct drm_device *dev); +extern void intel_irq_init(struct drm_i915_private *dev_priv); +extern void intel_hpd_init(struct drm_i915_private *dev_priv); int intel_irq_install(struct drm_i915_private *dev_priv); void intel_irq_uninstall(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c07f576c5974..97340a9215ea 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4650,9 +4650,9 @@ static void intel_hpd_irq_reenable_work(struct work_struct *work) intel_runtime_pm_put(dev_priv); } -void intel_irq_init(struct drm_device *dev) +void intel_irq_init(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_device *dev = dev_priv->dev; INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->dig_port_work, i915_digport_work_func); @@ -4661,7 +4661,7 @@ void intel_irq_init(struct drm_device *dev) INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); /* Let's track the enabled rps events */ - if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) + if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) /* WaGsvRC0ResidencyMethod:vlv */ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; else @@ -4675,10 +4675,10 @@ void intel_irq_init(struct drm_device *dev) pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); - if (IS_GEN2(dev)) { + if (IS_GEN2(dev_priv)) { dev->max_vblank_count = 0; dev->driver->get_vblank_counter = i8xx_get_vblank_counter; - } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { + } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->driver->get_vblank_counter = gm45_get_vblank_counter; } else { @@ -4691,7 +4691,7 @@ void intel_irq_init(struct drm_device *dev) * Gen2 doesn't have a hardware frame counter and so depends on * vblank interrupts to produce sane vblank seuquence numbers. */ - if (!IS_GEN2(dev)) + if (!IS_GEN2(dev_priv)) dev->vblank_disable_immediate = true; if (drm_core_check_feature(dev, DRIVER_MODESET)) { @@ -4699,7 +4699,7 @@ void intel_irq_init(struct drm_device *dev) dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; } - if (IS_CHERRYVIEW(dev)) { + if (IS_CHERRYVIEW(dev_priv)) { dev->driver->irq_handler = cherryview_irq_handler; dev->driver->irq_preinstall = cherryview_irq_preinstall; dev->driver->irq_postinstall = cherryview_irq_postinstall; @@ -4707,7 +4707,7 @@ void intel_irq_init(struct drm_device *dev) dev->driver->enable_vblank = valleyview_enable_vblank; dev->driver->disable_vblank = valleyview_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; - } else if (IS_VALLEYVIEW(dev)) { + } else if (IS_VALLEYVIEW(dev_priv)) { dev->driver->irq_handler = valleyview_irq_handler; dev->driver->irq_preinstall = valleyview_irq_preinstall; dev->driver->irq_postinstall = valleyview_irq_postinstall; @@ -4715,7 +4715,7 @@ void intel_irq_init(struct drm_device *dev) dev->driver->enable_vblank = valleyview_enable_vblank; dev->driver->disable_vblank = valleyview_disable_vblank; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; - } else if (INTEL_INFO(dev)->gen >= 8) { + } else if (INTEL_INFO(dev_priv)->gen >= 8) { dev->driver->irq_handler = gen8_irq_handler; dev->driver->irq_preinstall = gen8_irq_reset; dev->driver->irq_postinstall = gen8_irq_postinstall; @@ -4732,12 +4732,12 @@ void intel_irq_init(struct drm_device *dev) dev->driver->disable_vblank = ironlake_disable_vblank; dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; } else { - if (INTEL_INFO(dev)->gen == 2) { + if (INTEL_INFO(dev_priv)->gen == 2) { dev->driver->irq_preinstall = i8xx_irq_preinstall; dev->driver->irq_postinstall = i8xx_irq_postinstall; dev->driver->irq_handler = i8xx_irq_handler; dev->driver->irq_uninstall = i8xx_irq_uninstall; - } else if (INTEL_INFO(dev)->gen == 3) { + } else if (INTEL_INFO(dev_priv)->gen == 3) { dev->driver->irq_preinstall = i915_irq_preinstall; dev->driver->irq_postinstall = i915_irq_postinstall; dev->driver->irq_uninstall = i915_irq_uninstall; @@ -4755,9 +4755,9 @@ void intel_irq_init(struct drm_device *dev) } } -void intel_hpd_init(struct drm_device *dev) +void intel_hpd_init(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_device *dev = dev_priv->dev; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; int i; @@ -4803,20 +4803,16 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) } /* Disable interrupts so we can allow runtime PM. */ -void intel_runtime_pm_disable_interrupts(struct drm_device *dev) +void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - - dev->driver->irq_uninstall(dev); + dev_priv->dev->driver->irq_uninstall(dev_priv->dev); dev_priv->pm.irqs_enabled = false; } /* Restore interrupts so we can recover from runtime PM. */ -void intel_runtime_pm_restore_interrupts(struct drm_device *dev) +void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->pm.irqs_enabled = true; - dev->driver->irq_preinstall(dev); - dev->driver->irq_postinstall(dev); + dev_priv->dev->driver->irq_preinstall(dev_priv->dev); + dev_priv->dev->driver->irq_postinstall(dev_priv->dev); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2d029d8aaec1..ffbf38d9b536 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -764,8 +764,8 @@ void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); -void intel_runtime_pm_disable_interrupts(struct drm_device *dev); -void intel_runtime_pm_restore_interrupts(struct drm_device *dev); +void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); +void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) { /* diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index abefc98dcc8f..36749b91d28e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -377,7 +377,7 @@ static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, if (dev_priv->power_domains.initializing) return; - intel_hpd_init(dev_priv->dev); + intel_hpd_init(dev_priv); i915_redisable_vga_power_on(dev_priv->dev); } -- GitLab From fca52a5565fbf4abc4ee4fca81842dc1f6ecdce8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:45 +0200 Subject: [PATCH 0168/9457] drm/i915: kerneldoc for interrupt enable/disable functions Just start with the basics for now. Since there's a lot of different functionality in i915_irq.c I've decided to split it into different sections and pull in just the relevant functions. Splitting into different files looks like a lot more work since the interrupt handlers do an awful lot of reuse all over. v2: Rebase onto changed function names. Signed-off-by: Daniel Vetter Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 9 +++++ drivers/gpu/drm/i915/i915_irq.c | 61 +++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 8627816e58f3..d7cfc98be159 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3798,6 +3798,14 @@ int num_ioctls; !Pdrivers/gpu/drm/i915/intel_runtime_pm.c runtime pm !Idrivers/gpu/drm/i915/intel_runtime_pm.c + + Interrupt Handling +!Pdrivers/gpu/drm/i915/i915_irq.c interrupt handling +!Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_init intel_irq_init_hw intel_hpd_init +!Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_fini +!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts +!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + Display Hardware Handling @@ -3951,5 +3959,6 @@ int num_ioctls; +!Cdrivers/gpu/drm/i915/i915_irq.c diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 97340a9215ea..737b23982b95 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,6 +37,14 @@ #include "i915_trace.h" #include "intel_drv.h" +/** + * DOC: interrupt handling + * + * These functions provide the basic support for enabling and disabling the + * interrupt handling support. There's a lot more functionality in i915_irq.c + * and related files, but that will be described in separate chapters. + */ + static const u32 hpd_ibx[] = { [HPD_CRT] = SDE_CRT_HOTPLUG, [HPD_SDVO_B] = SDE_SDVOB_HOTPLUG, @@ -4650,6 +4658,13 @@ static void intel_hpd_irq_reenable_work(struct work_struct *work) intel_runtime_pm_put(dev_priv); } +/** + * intel_irq_init - initializes irq support + * @dev_priv: i915 device instance + * + * This function initializes all the irq support including work items, timers + * and all the vtables. It does not setup the interrupt itself though. + */ void intel_irq_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -4755,6 +4770,18 @@ void intel_irq_init(struct drm_i915_private *dev_priv) } } +/** + * intel_hpd_init - initializes and enables hpd support + * @dev_priv: i915 device instance + * + * This function enables the hotplug support. It requires that interrupts have + * already been enabled with intel_irq_init_hw(). From this point on hotplug and + * poll request can run concurrently to other code, so locking rules must be + * obeyed. + * + * This is a separate step from interrupt enabling to simplify the locking rules + * in the driver load and resume code. + */ void intel_hpd_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -4783,6 +4810,17 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); } +/** + * intel_irq_install - enables the hardware interrupt + * @dev_priv: i915 device instance + * + * This function enables the hardware interrupt handling, but leaves the hotplug + * handling still disabled. It is called after intel_irq_init(). + * + * In the driver load and resume code we need working interrupts in a few places + * but don't want to deal with the hassle of concurrent probe and hotplug + * workers. Hence the split into this two-stage approach. + */ int intel_irq_install(struct drm_i915_private *dev_priv) { /* @@ -4795,6 +4833,13 @@ int intel_irq_install(struct drm_i915_private *dev_priv) return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq); } +/** + * intel_irq_uninstall - finilizes all irq handling + * @dev_priv: i915 device instance + * + * This stops interrupt and hotplug handling and unregisters and frees all + * resources acquired in the init functions. + */ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { drm_irq_uninstall(dev_priv->dev); @@ -4802,14 +4847,26 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) dev_priv->pm.irqs_enabled = false; } -/* Disable interrupts so we can allow runtime PM. */ +/** + * intel_runtime_pm_disable_interrupts - runtime interrupt disabling + * @dev_priv: i915 device instance + * + * This function is used to disable interrupts at runtime, both in the runtime + * pm and the system suspend/resume code. + */ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->dev->driver->irq_uninstall(dev_priv->dev); dev_priv->pm.irqs_enabled = false; } -/* Restore interrupts so we can recover from runtime PM. */ +/** + * intel_runtime_pm_enable_interrupts - runtime interrupt enabling + * @dev_priv: i915 device instance + * + * This function is used to enable interrupts at runtime, both in the runtime + * pm and the system suspend/resume code. + */ void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->pm.irqs_enabled = true; -- GitLab From 60a5372777b05c78ec25f1bc1883cb59b2418255 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Oct 2014 10:29:51 +0100 Subject: [PATCH 0169/9457] drm/i915: Remove the duplicated logic between the two shrink phases We can use the same logic to walk the different bound/unbound lists during shrinker (as the unbound list is a degenerate case of the bound list), slightly compacting the code. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 49 +++++++++++++-------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e05e0063a3b1..2719c25588cb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1945,7 +1945,14 @@ unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, long target, unsigned flags) { - const bool purgeable_only = flags & I915_SHRINK_PURGEABLE; + const struct { + struct list_head *list; + unsigned int bit; + } phases[] = { + { &dev_priv->mm.unbound_list, I915_SHRINK_UNBOUND }, + { &dev_priv->mm.bound_list, I915_SHRINK_BOUND }, + { NULL, 0 }, + }, *phase; unsigned long count = 0; /* @@ -1967,48 +1974,30 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, * dev->struct_mutex and so we won't ever be able to observe an * object on the bound_list with a reference count equals 0. */ - if (flags & I915_SHRINK_UNBOUND) { + for (phase = phases; phase->list; phase++) { struct list_head still_in_list; - INIT_LIST_HEAD(&still_in_list); - while (count < target && !list_empty(&dev_priv->mm.unbound_list)) { - struct drm_i915_gem_object *obj; - - obj = list_first_entry(&dev_priv->mm.unbound_list, - typeof(*obj), global_list); - list_move_tail(&obj->global_list, &still_in_list); - - if (!i915_gem_object_is_purgeable(obj) && purgeable_only) - continue; - - drm_gem_object_reference(&obj->base); - - if (i915_gem_object_put_pages(obj) == 0) - count += obj->base.size >> PAGE_SHIFT; - - drm_gem_object_unreference(&obj->base); - } - list_splice(&still_in_list, &dev_priv->mm.unbound_list); - } - - if (flags & I915_SHRINK_BOUND) { - struct list_head still_in_list; + if ((flags & phase->bit) == 0) + continue; INIT_LIST_HEAD(&still_in_list); - while (count < target && !list_empty(&dev_priv->mm.bound_list)) { + while (count < target && !list_empty(phase->list)) { struct drm_i915_gem_object *obj; struct i915_vma *vma, *v; - obj = list_first_entry(&dev_priv->mm.bound_list, + obj = list_first_entry(phase->list, typeof(*obj), global_list); list_move_tail(&obj->global_list, &still_in_list); - if (!i915_gem_object_is_purgeable(obj) && purgeable_only) + if (flags & I915_SHRINK_PURGEABLE && + !i915_gem_object_is_purgeable(obj)) continue; drm_gem_object_reference(&obj->base); - list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) + /* For the unbound phase, this should be a no-op! */ + list_for_each_entry_safe(vma, v, + &obj->vma_list, vma_link) if (i915_vma_unbind(vma)) break; @@ -2017,7 +2006,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, drm_gem_object_unreference(&obj->base); } - list_splice(&still_in_list, &dev_priv->mm.bound_list); + list_splice(&still_in_list, phase->list); } return count; -- GitLab From b727735732d5b2fde0a88911210215e03e190d11 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 3 Oct 2014 17:38:34 +0200 Subject: [PATCH 0170/9457] drm/i915: Update DRIVER_DATE to 20141003 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9cc13291ccb9..821ba26438fb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -55,7 +55,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20140919" +#define DRIVER_DATE "20141003" enum pipe { INVALID_PIPE = -1, -- GitLab From a7ee8839daf21c4a3ca439733e7bed25f32e7954 Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:35 +0200 Subject: [PATCH 0171/9457] iio:imu: changed structure name from st_sensors to st_sensor_settings This patch change structure name and related variables names. Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_core.c | 13 +- .../iio/common/st_sensors/st_sensors_core.c | 126 ++++++++++-------- drivers/iio/gyro/st_gyro_core.c | 13 +- drivers/iio/magnetometer/st_magn_core.c | 13 +- drivers/iio/pressure/st_pressure_core.c | 20 +-- include/linux/iio/common/st_sensors.h | 10 +- 6 files changed, 104 insertions(+), 91 deletions(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 087864854c61..7cbdfae03441 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -161,7 +161,7 @@ static const struct iio_chan_spec st_accel_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_accel_sensors[] = { +static const struct st_sensor_settings st_accel_sensors_settings[] = { { .wai = ST_ACCEL_1_WAI_EXP, .sensors_supported = { @@ -470,18 +470,19 @@ int st_accel_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_accel_sensors), st_accel_sensors); + ARRAY_SIZE(st_accel_sensors_settings), + st_accel_sensors_settings); if (err < 0) return err; adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS; - adata->multiread_bit = adata->sensor->multi_read_bit; - indio_dev->channels = adata->sensor->ch; + adata->multiread_bit = adata->sensor_settings->multi_read_bit; + indio_dev->channels = adata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; adata->current_fullscale = (struct st_sensor_fullscale_avl *) - &adata->sensor->fs.fs_avl[0]; - adata->odr = adata->sensor->odr.odr_avl[0].hz; + &adata->sensor_settings->fs.fs_avl[0]; + adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; if (!plat_data) plat_data = diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 24cfe4e044f9..edd13d2b4121 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -44,18 +44,18 @@ static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev, return err; } -static int st_sensors_match_odr(struct st_sensors *sensor, +static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings, unsigned int odr, struct st_sensor_odr_avl *odr_out) { int i, ret = -EINVAL; for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) { - if (sensor->odr.odr_avl[i].hz == 0) + if (sensor_settings->odr.odr_avl[i].hz == 0) goto st_sensors_match_odr_error; - if (sensor->odr.odr_avl[i].hz == odr) { - odr_out->hz = sensor->odr.odr_avl[i].hz; - odr_out->value = sensor->odr.odr_avl[i].value; + if (sensor_settings->odr.odr_avl[i].hz == odr) { + odr_out->hz = sensor_settings->odr.odr_avl[i].hz; + odr_out->value = sensor_settings->odr.odr_avl[i].value; ret = 0; break; } @@ -71,23 +71,26 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); - err = st_sensors_match_odr(sdata->sensor, odr, &odr_out); + err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out); if (err < 0) goto st_sensors_match_odr_error; - if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && - (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { + if ((sdata->sensor_settings->odr.addr == + sdata->sensor_settings->pw.addr) && + (sdata->sensor_settings->odr.mask == + sdata->sensor_settings->pw.mask)) { if (sdata->enabled == true) { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->odr.addr, - sdata->sensor->odr.mask, + sdata->sensor_settings->odr.addr, + sdata->sensor_settings->odr.mask, odr_out.value); } else { err = 0; } } else { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->odr.addr, sdata->sensor->odr.mask, + sdata->sensor_settings->odr.addr, + sdata->sensor_settings->odr.mask, odr_out.value); } if (err >= 0) @@ -98,16 +101,16 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) } EXPORT_SYMBOL(st_sensors_set_odr); -static int st_sensors_match_fs(struct st_sensors *sensor, +static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings, unsigned int fs, int *index_fs_avl) { int i, ret = -EINVAL; for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if (sensor->fs.fs_avl[i].num == 0) + if (sensor_settings->fs.fs_avl[i].num == 0) goto st_sensors_match_odr_error; - if (sensor->fs.fs_avl[i].num == fs) { + if (sensor_settings->fs.fs_avl[i].num == fs) { *index_fs_avl = i; ret = 0; break; @@ -118,25 +121,24 @@ static int st_sensors_match_fs(struct st_sensors *sensor, return ret; } -static int st_sensors_set_fullscale(struct iio_dev *indio_dev, - unsigned int fs) +static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) { int err, i = 0; struct st_sensor_data *sdata = iio_priv(indio_dev); - err = st_sensors_match_fs(sdata->sensor, fs, &i); + err = st_sensors_match_fs(sdata->sensor_settings, fs, &i); if (err < 0) goto st_accel_set_fullscale_error; err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->fs.addr, - sdata->sensor->fs.mask, - sdata->sensor->fs.fs_avl[i].value); + sdata->sensor_settings->fs.addr, + sdata->sensor_settings->fs.mask, + sdata->sensor_settings->fs.fs_avl[i].value); if (err < 0) goto st_accel_set_fullscale_error; sdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &sdata->sensor->fs.fs_avl[i]; + &sdata->sensor_settings->fs.fs_avl[i]; return err; st_accel_set_fullscale_error: @@ -153,10 +155,12 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) struct st_sensor_data *sdata = iio_priv(indio_dev); if (enable) { - tmp_value = sdata->sensor->pw.value_on; - if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && - (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { - err = st_sensors_match_odr(sdata->sensor, + tmp_value = sdata->sensor_settings->pw.value_on; + if ((sdata->sensor_settings->odr.addr == + sdata->sensor_settings->pw.addr) && + (sdata->sensor_settings->odr.mask == + sdata->sensor_settings->pw.mask)) { + err = st_sensors_match_odr(sdata->sensor_settings, sdata->odr, &odr_out); if (err < 0) goto set_enable_error; @@ -164,8 +168,8 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) found = true; } err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->pw.addr, - sdata->sensor->pw.mask, tmp_value); + sdata->sensor_settings->pw.addr, + sdata->sensor_settings->pw.mask, tmp_value); if (err < 0) goto set_enable_error; @@ -175,9 +179,9 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) sdata->odr = odr_out.hz; } else { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->pw.addr, - sdata->sensor->pw.mask, - sdata->sensor->pw.value_off); + sdata->sensor_settings->pw.addr, + sdata->sensor_settings->pw.mask, + sdata->sensor_settings->pw.value_off); if (err < 0) goto set_enable_error; @@ -194,8 +198,9 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable) struct st_sensor_data *sdata = iio_priv(indio_dev); return st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->enable_axis.addr, - sdata->sensor->enable_axis.mask, axis_enable); + sdata->sensor_settings->enable_axis.addr, + sdata->sensor_settings->enable_axis.mask, + axis_enable); } EXPORT_SYMBOL(st_sensors_set_axis_enable); @@ -236,13 +241,13 @@ void st_sensors_power_disable(struct iio_dev *indio_dev) EXPORT_SYMBOL(st_sensors_power_disable); static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) + struct st_sensors_platform_data *pdata) { struct st_sensor_data *sdata = iio_priv(indio_dev); switch (pdata->drdy_int_pin) { case 1: - if (sdata->sensor->drdy_irq.mask_int1 == 0) { + if (sdata->sensor_settings->drdy_irq.mask_int1 == 0) { dev_err(&indio_dev->dev, "DRDY on INT1 not available.\n"); return -EINVAL; @@ -250,7 +255,7 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev, sdata->drdy_int_pin = 1; break; case 2: - if (sdata->sensor->drdy_irq.mask_int2 == 0) { + if (sdata->sensor_settings->drdy_irq.mask_int2 == 0) { dev_err(&indio_dev->dev, "DRDY on INT2 not available.\n"); return -EINVAL; @@ -318,7 +323,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, if (sdata->current_fullscale) { err = st_sensors_set_fullscale(indio_dev, - sdata->current_fullscale->num); + sdata->current_fullscale->num); if (err < 0) return err; } else @@ -330,7 +335,8 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, /* set BDU */ err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true); + sdata->sensor_settings->bdu.addr, + sdata->sensor_settings->bdu.mask, true); if (err < 0) return err; @@ -346,26 +352,28 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable) u8 drdy_mask; struct st_sensor_data *sdata = iio_priv(indio_dev); - if (!sdata->sensor->drdy_irq.addr) + if (!sdata->sensor_settings->drdy_irq.addr) return 0; /* Enable/Disable the interrupt generator 1. */ - if (sdata->sensor->drdy_irq.ig1.en_addr > 0) { + if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) { err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->drdy_irq.ig1.en_addr, - sdata->sensor->drdy_irq.ig1.en_mask, (int)enable); + sdata->sensor_settings->drdy_irq.ig1.en_addr, + sdata->sensor_settings->drdy_irq.ig1.en_mask, + (int)enable); if (err < 0) goto st_accel_set_dataready_irq_error; } if (sdata->drdy_int_pin == 1) - drdy_mask = sdata->sensor->drdy_irq.mask_int1; + drdy_mask = sdata->sensor_settings->drdy_irq.mask_int1; else - drdy_mask = sdata->sensor->drdy_irq.mask_int2; + drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2; /* Enable/Disable the interrupt generator for data ready. */ err = st_sensors_write_data_with_mask(indio_dev, - sdata->sensor->drdy_irq.addr, drdy_mask, (int)enable); + sdata->sensor_settings->drdy_irq.addr, + drdy_mask, (int)enable); st_accel_set_dataready_irq_error: return err; @@ -378,8 +386,8 @@ int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) struct st_sensor_data *sdata = iio_priv(indio_dev); for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if ((sdata->sensor->fs.fs_avl[i].gain == scale) && - (sdata->sensor->fs.fs_avl[i].gain != 0)) { + if ((sdata->sensor_settings->fs.fs_avl[i].gain == scale) && + (sdata->sensor_settings->fs.fs_avl[i].gain != 0)) { err = 0; break; } @@ -388,7 +396,7 @@ int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale) goto st_sensors_match_scale_error; err = st_sensors_set_fullscale(indio_dev, - sdata->sensor->fs.fs_avl[i].num); + sdata->sensor_settings->fs.fs_avl[i].num); st_sensors_match_scale_error: return err; @@ -439,7 +447,7 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, if (err < 0) goto out; - msleep((sdata->sensor->bootime * 1000) / sdata->odr); + msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr); err = st_sensors_read_axis_data(indio_dev, ch, val); if (err < 0) goto out; @@ -456,7 +464,8 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, EXPORT_SYMBOL(st_sensors_read_info_raw); int st_sensors_check_device_support(struct iio_dev *indio_dev, - int num_sensors_list, const struct st_sensors *sensors) + int num_sensors_list, + const struct st_sensor_settings *sensor_settings) { u8 wai; int i, n, err; @@ -470,23 +479,24 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev, } for (i = 0; i < num_sensors_list; i++) { - if (sensors[i].wai == wai) + if (sensor_settings[i].wai == wai) break; } if (i == num_sensors_list) goto device_not_supported; - for (n = 0; n < ARRAY_SIZE(sensors[i].sensors_supported); n++) { + for (n = 0; n < ARRAY_SIZE(sensor_settings[i].sensors_supported); n++) { if (strcmp(indio_dev->name, - &sensors[i].sensors_supported[n][0]) == 0) + &sensor_settings[i].sensors_supported[n][0]) == 0) break; } - if (n == ARRAY_SIZE(sensors[i].sensors_supported)) { + if (n == ARRAY_SIZE(sensor_settings[i].sensors_supported)) { dev_err(&indio_dev->dev, "device name and WhoAmI mismatch.\n"); goto sensor_name_mismatch; } - sdata->sensor = (struct st_sensors *)&sensors[i]; + sdata->sensor_settings = + (struct st_sensor_settings *)&sensor_settings[i]; return i; @@ -508,11 +518,11 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) { - if (sdata->sensor->odr.odr_avl[i].hz == 0) + if (sdata->sensor_settings->odr.odr_avl[i].hz == 0) break; len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", - sdata->sensor->odr.odr_avl[i].hz); + sdata->sensor_settings->odr.odr_avl[i].hz); } mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; @@ -530,11 +540,11 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { - if (sdata->sensor->fs.fs_avl[i].num == 0) + if (sdata->sensor_settings->fs.fs_avl[i].num == 0) break; len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", - sdata->sensor->fs.fs_avl[i].gain); + sdata->sensor_settings->fs.fs_avl[i].gain); } mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index f156fc6c5c6c..9d41b68d24b2 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -103,7 +103,7 @@ static const struct iio_chan_spec st_gyro_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_gyro_sensors[] = { +static const struct st_sensor_settings st_gyro_sensors_settings[] = { { .wai = ST_GYRO_1_WAI_EXP, .sensors_supported = { @@ -322,18 +322,19 @@ int st_gyro_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors); + ARRAY_SIZE(st_gyro_sensors_settings), + st_gyro_sensors_settings); if (err < 0) return err; gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS; - gdata->multiread_bit = gdata->sensor->multi_read_bit; - indio_dev->channels = gdata->sensor->ch; + gdata->multiread_bit = gdata->sensor_settings->multi_read_bit; + indio_dev->channels = gdata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; gdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &gdata->sensor->fs.fs_avl[0]; - gdata->odr = gdata->sensor->odr.odr_avl[0].hz; + &gdata->sensor_settings->fs.fs_avl[0]; + gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz; err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index a4b64130ac2f..b65405fada45 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -146,7 +146,7 @@ static const struct iio_chan_spec st_magn_2_16bit_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3) }; -static const struct st_sensors st_magn_sensors[] = { +static const struct st_sensor_settings st_magn_sensors_settings[] = { { .wai = ST_MAGN_1_WAI_EXP, .sensors_supported = { @@ -366,18 +366,19 @@ int st_magn_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_magn_sensors), st_magn_sensors); + ARRAY_SIZE(st_magn_sensors_settings), + st_magn_sensors_settings); if (err < 0) return err; mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS; - mdata->multiread_bit = mdata->sensor->multi_read_bit; - indio_dev->channels = mdata->sensor->ch; + mdata->multiread_bit = mdata->sensor_settings->multi_read_bit; + indio_dev->channels = mdata->sensor_settings->ch; indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS; mdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &mdata->sensor->fs.fs_avl[0]; - mdata->odr = mdata->sensor->odr.odr_avl[0].hz; + &mdata->sensor_settings->fs.fs_avl[0]; + mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 473d914ef470..9563118c4d36 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -175,7 +175,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(1) }; -static const struct st_sensors st_press_sensors[] = { +static const struct st_sensor_settings st_press_sensors_settings[] = { { .wai = ST_PRESS_LPS331AP_WAI_EXP, .sensors_supported = { @@ -422,24 +422,24 @@ int st_press_common_probe(struct iio_dev *indio_dev, st_sensors_power_enable(indio_dev); err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_press_sensors), - st_press_sensors); + ARRAY_SIZE(st_press_sensors_settings), + st_press_sensors_settings); if (err < 0) return err; pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; - pdata->multiread_bit = pdata->sensor->multi_read_bit; - indio_dev->channels = pdata->sensor->ch; - indio_dev->num_channels = pdata->sensor->num_ch; + pdata->multiread_bit = pdata->sensor_settings->multi_read_bit; + indio_dev->channels = pdata->sensor_settings->ch; + indio_dev->num_channels = pdata->sensor_settings->num_ch; - if (pdata->sensor->fs.addr != 0) + if (pdata->sensor_settings->fs.addr != 0) pdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &pdata->sensor->fs.fs_avl[0]; + &pdata->sensor_settings->fs.fs_avl[0]; - pdata->odr = pdata->sensor->odr.odr_avl[0].hz; + pdata->odr = pdata->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!plat_data && pdata->sensor->drdy_irq.addr) + if (!plat_data && pdata->sensor_settings->drdy_irq.addr) plat_data = (struct st_sensors_platform_data *)&default_press_pdata; diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index d8257ab60bac..2c476acb87d9 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -164,7 +164,7 @@ struct st_sensor_transfer_function { }; /** - * struct st_sensors - ST sensors list + * struct st_sensor_settings - ST specific sensor settings * @wai: Contents of WhoAmI register. * @sensors_supported: List of supported sensors by struct itself. * @ch: IIO channels for the sensor. @@ -177,7 +177,7 @@ struct st_sensor_transfer_function { * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read. * @bootime: samples to discard when sensor passing from power-down to power-up. */ -struct st_sensors { +struct st_sensor_settings { u8 wai; char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME]; struct iio_chan_spec *ch; @@ -196,7 +196,7 @@ struct st_sensors { * struct st_sensor_data - ST sensor device status * @dev: Pointer to instance of struct device (I2C or SPI). * @trig: The trigger in use by the core driver. - * @sensor: Pointer to the current sensor struct in use. + * @sensor_settings: Pointer to the specific sensor settings in use. * @current_fullscale: Maximum range of measure by the sensor. * @vdd: Pointer to sensor's Vdd power supply * @vdd_io: Pointer to sensor's Vdd-IO power supply @@ -213,7 +213,7 @@ struct st_sensors { struct st_sensor_data { struct device *dev; struct iio_trigger *trig; - struct st_sensors *sensor; + struct st_sensor_settings *sensor_settings; struct st_sensor_fullscale_avl *current_fullscale; struct regulator *vdd; struct regulator *vdd_io; @@ -279,7 +279,7 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, int *val); int st_sensors_check_device_support(struct iio_dev *indio_dev, - int num_sensors_list, const struct st_sensors *sensors); + int num_sensors_list, const struct st_sensor_settings *sensor_settings); ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, struct device_attribute *attr, char *buf); -- GitLab From b6e6bda626972d895322474f41fb64a8a731cc0c Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:36 +0200 Subject: [PATCH 0172/9457] iio:accel: Removed unnecessary parameter on common_probe function Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel.h | 3 +-- drivers/iio/accel/st_accel_core.c | 9 ++++----- drivers/iio/accel/st_accel_i2c.c | 2 +- drivers/iio/accel/st_accel_spi.c | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index c3877630b2e4..fa9646034305 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -33,8 +33,7 @@ static const struct st_sensors_platform_data default_accel_pdata = { .drdy_int_pin = 1, }; -int st_accel_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_accel_common_probe(struct iio_dev *indio_dev); void st_accel_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 7cbdfae03441..53f32629283a 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -457,8 +457,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = { #define ST_ACCEL_TRIGGER_OPS NULL #endif -int st_accel_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *plat_data) +int st_accel_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *adata = iio_priv(indio_dev); int irq = adata->get_irq_data_ready(indio_dev); @@ -484,11 +483,11 @@ int st_accel_common_probe(struct iio_dev *indio_dev, &adata->sensor_settings->fs.fs_avl[0]; adata->odr = adata->sensor_settings->odr.odr_avl[0].hz; - if (!plat_data) - plat_data = + if (!adata->dev->platform_data) + adata->dev->platform_data = (struct st_sensors_platform_data *)&default_accel_pdata; - err = st_sensors_init_sensor(indio_dev, plat_data); + err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data); if (err < 0) return err; diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 7164aeff3ab1..40adc7e88a39 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -84,7 +84,7 @@ static int st_accel_i2c_probe(struct i2c_client *client, st_sensors_i2c_configure(indio_dev, client, adata); - err = st_accel_common_probe(indio_dev, client->dev.platform_data); + err = st_accel_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 195639646e34..2090d80062d2 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -33,7 +33,7 @@ static int st_accel_spi_probe(struct spi_device *spi) st_sensors_spi_configure(indio_dev, spi, adata); - err = st_accel_common_probe(indio_dev, spi->dev.platform_data); + err = st_accel_common_probe(indio_dev); if (err < 0) return err; -- GitLab From ef67b341477e54178245dcd7b349a209ec78d29d Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:37 +0200 Subject: [PATCH 0173/9457] iio:gyro: Removed unnecessary parameter on common_probe function Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/st_gyro.h | 3 +-- drivers/iio/gyro/st_gyro_core.c | 6 +++--- drivers/iio/gyro/st_gyro_i2c.c | 3 +-- drivers/iio/gyro/st_gyro_spi.c | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index c197360c450b..5353d6328c54 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h @@ -30,8 +30,7 @@ static const struct st_sensors_platform_data gyro_pdata = { .drdy_int_pin = 2, }; -int st_gyro_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_gyro_common_probe(struct iio_dev *indio_dev); void st_gyro_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 9d41b68d24b2..f07a2336f7dc 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -309,8 +309,7 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = { #define ST_GYRO_TRIGGER_OPS NULL #endif -int st_gyro_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) +int st_gyro_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *gdata = iio_priv(indio_dev); int irq = gdata->get_irq_data_ready(indio_dev); @@ -336,7 +335,8 @@ int st_gyro_common_probe(struct iio_dev *indio_dev, &gdata->sensor_settings->fs.fs_avl[0]; gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev, pdata); + err = st_sensors_init_sensor(indio_dev, + (struct st_sensors_platform_data *)&gyro_pdata); if (err < 0) return err; diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 8fa0ad2ef4ef..94d01fba4a4c 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -72,8 +72,7 @@ static int st_gyro_i2c_probe(struct i2c_client *client, st_sensors_i2c_configure(indio_dev, client, gdata); - err = st_gyro_common_probe(indio_dev, - (struct st_sensors_platform_data *)&gyro_pdata); + err = st_gyro_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index b4ad3be26687..3e7a01af9b61 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -33,8 +33,7 @@ static int st_gyro_spi_probe(struct spi_device *spi) st_sensors_spi_configure(indio_dev, spi, gdata); - err = st_gyro_common_probe(indio_dev, - (struct st_sensors_platform_data *)&gyro_pdata); + err = st_gyro_common_probe(indio_dev); if (err < 0) return err; -- GitLab From 2109eb4c0c7d21669ae2ad0cda90c438b5470bf3 Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:38 +0200 Subject: [PATCH 0174/9457] iio:magnetometer: Removed unnecessary parameter on common_probe function Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/st_magn.h | 3 +-- drivers/iio/magnetometer/st_magn_core.c | 5 ++--- drivers/iio/magnetometer/st_magn_i2c.c | 2 +- drivers/iio/magnetometer/st_magn_spi.c | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h index 694e33e0fb72..7e81d00ef0c3 100644 --- a/drivers/iio/magnetometer/st_magn.h +++ b/drivers/iio/magnetometer/st_magn.h @@ -18,8 +18,7 @@ #define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn" #define LIS3MDL_MAGN_DEV_NAME "lis3mdl" -int st_magn_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_magn_common_probe(struct iio_dev *indio_dev); void st_magn_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index b65405fada45..1f3c1b7be78f 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -353,8 +353,7 @@ static const struct iio_info magn_info = { .write_raw = &st_magn_write_raw, }; -int st_magn_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata) +int st_magn_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *mdata = iio_priv(indio_dev); int irq = mdata->get_irq_data_ready(indio_dev); @@ -380,7 +379,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev, &mdata->sensor_settings->fs.fs_avl[0]; mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev, pdata); + err = st_sensors_init_sensor(indio_dev, NULL); if (err < 0) return err; diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index 689250058442..f8a682374239 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -56,7 +56,7 @@ static int st_magn_i2c_probe(struct i2c_client *client, st_sensors_i2c_configure(indio_dev, client, mdata); - err = st_magn_common_probe(indio_dev, NULL); + err = st_magn_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index a6143ea51dfc..f64214237cf6 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -33,7 +33,7 @@ static int st_magn_spi_probe(struct spi_device *spi) st_sensors_spi_configure(indio_dev, spi, mdata); - err = st_magn_common_probe(indio_dev, NULL); + err = st_magn_common_probe(indio_dev); if (err < 0) return err; -- GitLab From 0baa3fc1b6c1e928260ca099cbdf551ced2cbfa3 Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:39 +0200 Subject: [PATCH 0175/9457] iio:pressure: Removed unnecessary parameter on common_probe function Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/st_pressure.h | 3 +-- drivers/iio/pressure/st_pressure_core.c | 9 ++++----- drivers/iio/pressure/st_pressure_i2c.c | 2 +- drivers/iio/pressure/st_pressure_spi.c | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h index 242943c0c4e4..f5f41490060b 100644 --- a/drivers/iio/pressure/st_pressure.h +++ b/drivers/iio/pressure/st_pressure.h @@ -26,8 +26,7 @@ static const struct st_sensors_platform_data default_press_pdata = { .drdy_int_pin = 1, }; -int st_press_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *pdata); +int st_press_common_probe(struct iio_dev *indio_dev); void st_press_common_remove(struct iio_dev *indio_dev); #ifdef CONFIG_IIO_BUFFER diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 9563118c4d36..ee2ef7def097 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -409,8 +409,7 @@ static const struct iio_trigger_ops st_press_trigger_ops = { #define ST_PRESS_TRIGGER_OPS NULL #endif -int st_press_common_probe(struct iio_dev *indio_dev, - struct st_sensors_platform_data *plat_data) +int st_press_common_probe(struct iio_dev *indio_dev) { struct st_sensor_data *pdata = iio_priv(indio_dev); int irq = pdata->get_irq_data_ready(indio_dev); @@ -439,11 +438,11 @@ int st_press_common_probe(struct iio_dev *indio_dev, pdata->odr = pdata->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!plat_data && pdata->sensor_settings->drdy_irq.addr) - plat_data = + if (!pdata->dev->platform_data && pdata->sensor_settings->drdy_irq.addr) + pdata->dev->platform_data = (struct st_sensors_platform_data *)&default_press_pdata; - err = st_sensors_init_sensor(indio_dev, plat_data); + err = st_sensors_init_sensor(indio_dev, pdata->dev->platform_data); if (err < 0) return err; diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index acaf165260bb..dd733513152d 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -56,7 +56,7 @@ static int st_press_i2c_probe(struct i2c_client *client, st_sensors_i2c_configure(indio_dev, client, pdata); - err = st_press_common_probe(indio_dev, client->dev.platform_data); + err = st_press_common_probe(indio_dev); if (err < 0) return err; diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index f45d430ec529..98c3e8e517ae 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -33,7 +33,7 @@ static int st_press_spi_probe(struct spi_device *spi) st_sensors_spi_configure(indio_dev, spi, pdata); - err = st_press_common_probe(indio_dev, spi->dev.platform_data); + err = st_press_common_probe(indio_dev); if (err < 0) return err; -- GitLab From a1dcf42927a3eebe749b14178441889ef3887ceb Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:40 +0200 Subject: [PATCH 0176/9457] iio:pressure: Changed pressure data variable name to press_data This patch fix pressure data variable name. Usually pdata name it is used for platform data. Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/st_pressure_buffer.c | 12 +++---- drivers/iio/pressure/st_pressure_core.c | 40 ++++++++++++----------- drivers/iio/pressure/st_pressure_i2c.c | 10 +++--- drivers/iio/pressure/st_pressure_spi.c | 10 +++--- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/iio/pressure/st_pressure_buffer.c b/drivers/iio/pressure/st_pressure_buffer.c index b37b1c9ac932..2ff53f222352 100644 --- a/drivers/iio/pressure/st_pressure_buffer.c +++ b/drivers/iio/pressure/st_pressure_buffer.c @@ -38,10 +38,10 @@ static int st_press_buffer_preenable(struct iio_dev *indio_dev) static int st_press_buffer_postenable(struct iio_dev *indio_dev) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); - pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (pdata->buffer_data == NULL) { + press_data->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (press_data->buffer_data == NULL) { err = -ENOMEM; goto allocate_memory_error; } @@ -53,7 +53,7 @@ static int st_press_buffer_postenable(struct iio_dev *indio_dev) return err; st_press_buffer_postenable_error: - kfree(pdata->buffer_data); + kfree(press_data->buffer_data); allocate_memory_error: return err; } @@ -61,7 +61,7 @@ static int st_press_buffer_postenable(struct iio_dev *indio_dev) static int st_press_buffer_predisable(struct iio_dev *indio_dev) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); err = iio_triggered_buffer_predisable(indio_dev); if (err < 0) @@ -70,7 +70,7 @@ static int st_press_buffer_predisable(struct iio_dev *indio_dev) err = st_sensors_set_enable(indio_dev, false); st_press_buffer_predisable_error: - kfree(pdata->buffer_data); + kfree(press_data->buffer_data); return err; } diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index ee2ef7def097..97baf40d424b 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -333,7 +333,7 @@ static int st_press_read_raw(struct iio_dev *indio_dev, int *val2, long mask) { int err; - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); switch (mask) { case IIO_CHAN_INFO_RAW: @@ -347,10 +347,10 @@ static int st_press_read_raw(struct iio_dev *indio_dev, switch (ch->type) { case IIO_PRESSURE: - *val2 = pdata->current_fullscale->gain; + *val2 = press_data->current_fullscale->gain; break; case IIO_TEMP: - *val2 = pdata->current_fullscale->gain2; + *val2 = press_data->current_fullscale->gain2; break; default: err = -EINVAL; @@ -371,7 +371,7 @@ static int st_press_read_raw(struct iio_dev *indio_dev, return IIO_VAL_FRACTIONAL; case IIO_CHAN_INFO_SAMP_FREQ: - *val = pdata->odr; + *val = press_data->odr; return IIO_VAL_INT; default: return -EINVAL; @@ -411,8 +411,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = { int st_press_common_probe(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); - int irq = pdata->get_irq_data_ready(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); + int irq = press_data->get_irq_data_ready(indio_dev); int err; indio_dev->modes = INDIO_DIRECT_MODE; @@ -426,23 +426,25 @@ int st_press_common_probe(struct iio_dev *indio_dev) if (err < 0) return err; - pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; - pdata->multiread_bit = pdata->sensor_settings->multi_read_bit; - indio_dev->channels = pdata->sensor_settings->ch; - indio_dev->num_channels = pdata->sensor_settings->num_ch; + press_data->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; + press_data->multiread_bit = press_data->sensor_settings->multi_read_bit; + indio_dev->channels = press_data->sensor_settings->ch; + indio_dev->num_channels = press_data->sensor_settings->num_ch; - if (pdata->sensor_settings->fs.addr != 0) - pdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &pdata->sensor_settings->fs.fs_avl[0]; + if (press_data->sensor_settings->fs.addr != 0) + press_data->current_fullscale = + (struct st_sensor_fullscale_avl *) + &press_data->sensor_settings->fs.fs_avl[0]; - pdata->odr = pdata->sensor_settings->odr.odr_avl[0].hz; + press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz; /* Some devices don't support a data ready pin. */ - if (!pdata->dev->platform_data && pdata->sensor_settings->drdy_irq.addr) - pdata->dev->platform_data = + if (!press_data->dev->platform_data && + press_data->sensor_settings->drdy_irq.addr) + press_data->dev->platform_data = (struct st_sensors_platform_data *)&default_press_pdata; - err = st_sensors_init_sensor(indio_dev, pdata->dev->platform_data); + err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data); if (err < 0) return err; @@ -478,12 +480,12 @@ EXPORT_SYMBOL(st_press_common_probe); void st_press_common_remove(struct iio_dev *indio_dev) { - struct st_sensor_data *pdata = iio_priv(indio_dev); + struct st_sensor_data *press_data = iio_priv(indio_dev); st_sensors_power_disable(indio_dev); iio_device_unregister(indio_dev); - if (pdata->get_irq_data_ready(indio_dev) > 0) + if (press_data->get_irq_data_ready(indio_dev) > 0) st_sensors_deallocate_trigger(indio_dev); st_press_deallocate_ring(indio_dev); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index dd733513152d..8859e93e6dc6 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -43,18 +43,18 @@ static int st_press_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct iio_dev *indio_dev; - struct st_sensor_data *pdata; + struct st_sensor_data *press_data; int err; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*pdata)); + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data)); if (!indio_dev) return -ENOMEM; - pdata = iio_priv(indio_dev); - pdata->dev = &client->dev; + press_data = iio_priv(indio_dev); + press_data->dev = &client->dev; st_sensors_of_i2c_probe(client, st_press_of_match); - st_sensors_i2c_configure(indio_dev, client, pdata); + st_sensors_i2c_configure(indio_dev, client, press_data); err = st_press_common_probe(indio_dev); if (err < 0) diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 98c3e8e517ae..10c96245f12a 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -21,17 +21,17 @@ static int st_press_spi_probe(struct spi_device *spi) { struct iio_dev *indio_dev; - struct st_sensor_data *pdata; + struct st_sensor_data *press_data; int err; - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*pdata)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*press_data)); if (indio_dev == NULL) return -ENOMEM; - pdata = iio_priv(indio_dev); - pdata->dev = &spi->dev; + press_data = iio_priv(indio_dev); + press_data->dev = &spi->dev; - st_sensors_spi_configure(indio_dev, spi, pdata); + st_sensors_spi_configure(indio_dev, spi, press_data); err = st_press_common_probe(indio_dev); if (err < 0) -- GitLab From 7be178bb48bc3ed5af2f6cfdb69074dba4bd87b9 Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Fri, 3 Oct 2014 17:35:41 +0200 Subject: [PATCH 0177/9457] iio:common: Set the device pointer into ST common sensors library Signed-off-by: Denis Ciocca Signed-off-by: Jonathan Cameron --- drivers/iio/accel/st_accel_i2c.c | 1 - drivers/iio/accel/st_accel_spi.c | 1 - drivers/iio/common/st_sensors/st_sensors_i2c.c | 1 + drivers/iio/common/st_sensors/st_sensors_spi.c | 1 + drivers/iio/gyro/st_gyro_i2c.c | 1 - drivers/iio/gyro/st_gyro_spi.c | 1 - drivers/iio/magnetometer/st_magn_i2c.c | 1 - drivers/iio/magnetometer/st_magn_spi.c | 1 - drivers/iio/pressure/st_pressure_i2c.c | 1 - drivers/iio/pressure/st_pressure_spi.c | 1 - 10 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 40adc7e88a39..c7246bdd30b9 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -79,7 +79,6 @@ static int st_accel_i2c_probe(struct i2c_client *client, return -ENOMEM; adata = iio_priv(indio_dev); - adata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_accel_of_match); st_sensors_i2c_configure(indio_dev, client, adata); diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 2090d80062d2..12ec29389e4b 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -29,7 +29,6 @@ static int st_accel_spi_probe(struct spi_device *spi) return -ENOMEM; adata = iio_priv(indio_dev); - adata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, adata); diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c index bb6f3085f57b..98cfee296d46 100644 --- a/drivers/iio/common/st_sensors/st_sensors_i2c.c +++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c @@ -72,6 +72,7 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev, indio_dev->dev.parent = &client->dev; indio_dev->name = client->name; + sdata->dev = &client->dev; sdata->tf = &st_sensors_tf_i2c; sdata->get_irq_data_ready = st_sensors_i2c_get_irq; } diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c index 251baf6abc25..78a6a1ab3ece 100644 --- a/drivers/iio/common/st_sensors/st_sensors_spi.c +++ b/drivers/iio/common/st_sensors/st_sensors_spi.c @@ -111,6 +111,7 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev, indio_dev->dev.parent = &spi->dev; indio_dev->name = spi->modalias; + sdata->dev = &spi->dev; sdata->tf = &st_sensors_tf_spi; sdata->get_irq_data_ready = st_sensors_spi_get_irq; } diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 94d01fba4a4c..64480b16c689 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -67,7 +67,6 @@ static int st_gyro_i2c_probe(struct i2c_client *client, return -ENOMEM; gdata = iio_priv(indio_dev); - gdata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_gyro_of_match); st_sensors_i2c_configure(indio_dev, client, gdata); diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index 3e7a01af9b61..e59bead6bc3c 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -29,7 +29,6 @@ static int st_gyro_spi_probe(struct spi_device *spi) return -ENOMEM; gdata = iio_priv(indio_dev); - gdata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, gdata); diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index f8a682374239..92e5c15452a3 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -51,7 +51,6 @@ static int st_magn_i2c_probe(struct i2c_client *client, return -ENOMEM; mdata = iio_priv(indio_dev); - mdata->dev = &client->dev; st_sensors_of_i2c_probe(client, st_magn_of_match); st_sensors_i2c_configure(indio_dev, client, mdata); diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index f64214237cf6..7adacf160146 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -29,7 +29,6 @@ static int st_magn_spi_probe(struct spi_device *spi) return -ENOMEM; mdata = iio_priv(indio_dev); - mdata->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, mdata); diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 8859e93e6dc6..137788bba4a3 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -51,7 +51,6 @@ static int st_press_i2c_probe(struct i2c_client *client, return -ENOMEM; press_data = iio_priv(indio_dev); - press_data->dev = &client->dev; st_sensors_of_i2c_probe(client, st_press_of_match); st_sensors_i2c_configure(indio_dev, client, press_data); diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 10c96245f12a..1ffa6d4d349c 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -29,7 +29,6 @@ static int st_press_spi_probe(struct spi_device *spi) return -ENOMEM; press_data = iio_priv(indio_dev); - press_data->dev = &spi->dev; st_sensors_spi_configure(indio_dev, spi, press_data); -- GitLab From 2e3d6675dc2f402d8b799b773324e60af3e2a325 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 2 Oct 2014 22:25:23 -0300 Subject: [PATCH 0178/9457] iio: adc: vf610: Return the error code directly There is no need to pass the error clock code to the variable 'ret'. Just return the error directly. Signed-off-by: Fabio Estevam Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 7ec21b5612ef..ebb73f5d3c3a 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -610,8 +610,7 @@ static int vf610_adc_probe(struct platform_device *pdev) if (IS_ERR(info->clk)) { dev_err(&pdev->dev, "failed getting clock, err = %ld\n", PTR_ERR(info->clk)); - ret = PTR_ERR(info->clk); - return ret; + return PTR_ERR(info->clk); } info->vref = devm_regulator_get(&pdev->dev, "vref"); -- GitLab From 9da64c25ffefa60b969c64176098ae616219f759 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 2 Oct 2014 22:25:24 -0300 Subject: [PATCH 0179/9457] iio: adc: vf610: Disable the regulator on error If clk_prepare_enable() fails we should disable the regulator that was previously enabled. Signed-off-by: Fabio Estevam Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index ebb73f5d3c3a..767e9b975f00 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -704,11 +704,15 @@ static int vf610_adc_resume(struct device *dev) ret = clk_prepare_enable(info->clk); if (ret) - return ret; + goto disable_reg; vf610_adc_hw_init(info); return 0; + +disable_reg: + regulator_disable(info->vref); + return ret; } #endif -- GitLab From ef0d5454930aa687ac2c2337107391f1389aa0f1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 2 Oct 2014 22:25:25 -0300 Subject: [PATCH 0180/9457] iio: adc: vf610: SIMPLE_DEV_PM_OPS can fit on a single line No need to call the SIMPLE_DEV_PM_OPS() macro in several lines. It can fit into the 80-column range. Signed-off-by: Fabio Estevam Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 767e9b975f00..d47fff003b78 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -716,9 +716,7 @@ static int vf610_adc_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, - vf610_adc_suspend, - vf610_adc_resume); +static SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, vf610_adc_suspend, vf610_adc_resume); static struct platform_driver vf610_adc_driver = { .probe = vf610_adc_probe, -- GitLab From 064a74637ccdee608eb898ea3e3847b142b261c6 Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Mon, 29 Sep 2014 13:28:55 -0500 Subject: [PATCH 0181/9457] IIO: add si7020 driver This patch adds support to the Industrial IO subsystem for the Silicon Labs Si7013/20/21 Relative Humidity and Temperature Sensors. Website: http://www.silabs.com/products/sensors/humidity-sensors/Pages/si7013-20-21.aspx These are i2c devices which measure relative humidity and temperature and all use the same protocol. The Si7013 has an additional input with programmable linearization which is not supported because that's complicated and I didn't need it. Signed-off-by: David Barksdale -- Changes since v1: * Renamed to si7020 and replaced Si701x/2x with Si7013/20/21. * Removed unneeded mutex. * Pre-computed floating-point constant expressions. * Removed address_list and I2C_CLASS_HWMON. Changes since v2: * Return correct raw sensor values. * Rename dev variable to indio_dev. * Issue a software reset command during probe. * Un-broke string literal. Changes since v3: * enum changed to #define Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/Kconfig | 10 +++ drivers/iio/humidity/Makefile | 1 + drivers/iio/humidity/si7020.c | 163 ++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 drivers/iio/humidity/si7020.c diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig index e116bd8dd0e4..4813b793b9f7 100644 --- a/drivers/iio/humidity/Kconfig +++ b/drivers/iio/humidity/Kconfig @@ -22,4 +22,14 @@ config SI7005 To compile this driver as a module, choose M here: the module will be called si7005. +config SI7020 + tristate "Si7013/20/21 Relative Humidity and Temperature Sensors" + depends on I2C + help + Say yes here to build support for the Silicon Labs Si7013/20/21 + Relative Humidity and Temperature Sensors. + + To compile this driver as a module, choose M here: the module + will be called si7020. + endmenu diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile index e3f3d942e646..86e2d26e9f4d 100644 --- a/drivers/iio/humidity/Makefile +++ b/drivers/iio/humidity/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DHT11) += dht11.o obj-$(CONFIG_SI7005) += si7005.o +obj-$(CONFIG_SI7020) += si7020.o diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c new file mode 100644 index 000000000000..e336af713f20 --- /dev/null +++ b/drivers/iio/humidity/si7020.c @@ -0,0 +1,163 @@ +/* + * si7020.c - Silicon Labs Si7013/20/21 Relative Humidity and Temp Sensors + * Copyright (c) 2013,2014 Uplogix, Inc. + * David Barksdale + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * The Silicon Labs Si7013/20/21 Relative Humidity and Temperature Sensors + * are i2c devices which have an identical programming interface for + * measuring relative humidity and temperature. The Si7013 has an additional + * temperature input which this driver does not support. + * + * Data Sheets: + * Si7013: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7013.pdf + * Si7020: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7020.pdf + * Si7021: http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7021.pdf + */ + +#include +#include +#include +#include +#include + +#include +#include + +/* Measure Relative Humidity, Hold Master Mode */ +#define SI7020CMD_RH_HOLD 0xE5 +/* Measure Temperature, Hold Master Mode */ +#define SI7020CMD_TEMP_HOLD 0xE3 +/* Software Reset */ +#define SI7020CMD_RESET 0xFE + +static int si7020_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct i2c_client **client = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = i2c_smbus_read_word_data(*client, + chan->type == IIO_TEMP ? + SI7020CMD_TEMP_HOLD : + SI7020CMD_RH_HOLD); + if (ret < 0) + return ret; + if (chan->type == IIO_TEMP) + *val = ret >> 2; + else + *val = (ret & 0x3FFF) >> 2; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_TEMP) + *val = 175720; /* = 175.72 * 1000 */ + else + *val = 125 * 1000; + *val2 = 65536 >> 2; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_OFFSET: + /* + * Since iio_convert_raw_to_processed_unlocked assumes offset + * is an integer we have to round these values and lose + * accuracy. + * Relative humidity will be 0.0032959% too high and + * temperature will be 0.00277344 degrees too high. + * This is no big deal because it's within the accuracy of the + * sensor. + */ + if (chan->type == IIO_TEMP) + *val = -4368; /* = -46.85 * (65536 >> 2) / 175.72 */ + else + *val = -786; /* = -6 * (65536 >> 2) / 125 */ + return IIO_VAL_INT; + default: + break; + } + + return -EINVAL; +} + +static const struct iio_chan_spec si7020_channels[] = { + { + .type = IIO_HUMIDITYRELATIVE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + } +}; + +static const struct iio_info si7020_info = { + .read_raw = si7020_read_raw, + .driver_module = THIS_MODULE, +}; + +static int si7020_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct i2c_client **data; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE | + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -ENODEV; + + /* Reset device, loads default settings. */ + ret = i2c_smbus_write_byte(client, SI7020CMD_RESET); + if (ret < 0) + return ret; + /* Wait the maximum power-up time after software reset. */ + msleep(15); + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*client)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + *data = client; + i2c_set_clientdata(client, indio_dev); + + indio_dev->dev.parent = &client->dev; + indio_dev->name = dev_name(&client->dev); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &si7020_info; + indio_dev->channels = si7020_channels; + indio_dev->num_channels = ARRAY_SIZE(si7020_channels); + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id si7020_id[] = { + { "si7020", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, si7020_id); + +static struct i2c_driver si7020_driver = { + .driver.name = "si7020", + .probe = si7020_probe, + .id_table = si7020_id, +}; + +module_i2c_driver(si7020_driver); +MODULE_DESCRIPTION("Silicon Labs Si7013/20/21 Relative Humidity and Temperature Sensors"); +MODULE_AUTHOR("David Barksdale "); +MODULE_LICENSE("GPL"); -- GitLab From 90174455ae058a1dcf1f3d344a9752385803c1d8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Oct 2014 08:02:33 +0300 Subject: [PATCH 0182/9457] ath10k: add support to configure pktlog filter Add support to configure packet log filters (tx, rx, rate control) via debugfs. To disable htt pktlog events set the filters to 0. ex: To enable pktlog for all filters echo 0x1f > /sys/kernel/debug/ieee80211/phy*/ath10k/pktlog_filter To disable pktlog echo 0 > /sys/kernel/debug/ieee80211/phy*/ath10k/pktlog_filter Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 + drivers/net/wireless/ath/ath10k/debug.c | 85 ++++++++++++++++++++++++- drivers/net/wireless/ath/ath10k/debug.h | 9 +++ drivers/net/wireless/ath/ath10k/wmi.c | 33 ++++++++++ drivers/net/wireless/ath/ath10k/wmi.h | 6 ++ 5 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 754ecc503368..1ac2f1466758 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -302,7 +302,9 @@ struct ath10k_debug { struct ath10k_dfs_stats dfs_stats; struct ath_dfs_pool_stats dfs_pool_stats; + /* protected by conf_mutex */ u32 fw_dbglog_mask; + u32 pktlog_filter; u8 htt_max_amsdu; u8 htt_max_ampdu; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 2bb894f31337..0d94febbb360 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1396,7 +1396,22 @@ int ath10k_debug_start(struct ath10k *ar) ret); } - return 0; + if (ar->debug.pktlog_filter) { + ret = ath10k_wmi_pdev_pktlog_enable(ar, + ar->debug.pktlog_filter); + if (ret) + /* not serious */ + ath10k_warn(ar, + "failed to enable pktlog filter %x: %d\n", + ar->debug.pktlog_filter, ret); + } else { + ret = ath10k_wmi_pdev_pktlog_disable(ar); + if (ret) + /* not serious */ + ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); + } + + return ret; } void ath10k_debug_stop(struct ath10k *ar) @@ -1411,6 +1426,8 @@ void ath10k_debug_stop(struct ath10k *ar) ar->debug.htt_max_amsdu = 0; ar->debug.htt_max_ampdu = 0; + + ath10k_wmi_pdev_pktlog_disable(ar); } static ssize_t ath10k_write_simulate_radar(struct file *file, @@ -1493,6 +1510,69 @@ static const struct file_operations fops_dfs_stats = { .llseek = default_llseek, }; +static ssize_t ath10k_write_pktlog_filter(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u32 filter; + int ret; + + if (kstrtouint_from_user(ubuf, count, 0, &filter)) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH10K_STATE_ON) { + ar->debug.pktlog_filter = filter; + ret = count; + goto out; + } + + if (filter && (filter != ar->debug.pktlog_filter)) { + ret = ath10k_wmi_pdev_pktlog_enable(ar, filter); + if (ret) { + ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", + ar->debug.pktlog_filter, ret); + goto out; + } + } else { + ret = ath10k_wmi_pdev_pktlog_disable(ar); + if (ret) { + ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); + goto out; + } + } + + ar->debug.pktlog_filter = filter; + ret = count; + +out: + mutex_unlock(&ar->conf_mutex); + return ret; +} + +static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char buf[32]; + struct ath10k *ar = file->private_data; + int len = 0; + + mutex_lock(&ar->conf_mutex); + len = scnprintf(buf, sizeof(buf) - len, "%08x\n", + ar->debug.pktlog_filter); + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(ubuf, count, ppos, buf, len); +} + +static const struct file_operations fops_pktlog_filter = { + .read = ath10k_read_pktlog_filter, + .write = ath10k_write_pktlog_filter, + .open = simple_open +}; + int ath10k_debug_create(struct ath10k *ar) { ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); @@ -1574,6 +1654,9 @@ int ath10k_debug_register(struct ath10k *ar) &fops_dfs_stats); } + debugfs_create_file("pktlog_filter", S_IRUGO | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_pktlog_filter); + return 0; } diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index d6a565d2bb74..ce86ed29e119 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -38,6 +38,15 @@ enum ath10k_debug_mask { ATH10K_DBG_ANY = 0xffffffff, }; +enum ath10k_pktlog_filter { + ATH10K_PKTLOG_RX = 0x000000001, + ATH10K_PKTLOG_TX = 0x000000002, + ATH10K_PKTLOG_RCFIND = 0x000000004, + ATH10K_PKTLOG_RCUPDATE = 0x000000008, + ATH10K_PKTLOG_DBG_PRINT = 0x000000010, + ATH10K_PKTLOG_ANY = 0x00000001f, +}; + extern unsigned int ath10k_debug_mask; __printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index f65032f9ccee..c145b985f7a5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4345,6 +4345,39 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid); } +int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) +{ + struct wmi_pdev_pktlog_enable_cmd *cmd; + struct sk_buff *skb; + + skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + ev_bitmap &= ATH10K_PKTLOG_ANY; + ath10k_dbg(ar, ATH10K_DBG_WMI, + "wmi enable pktlog filter:%x\n", ev_bitmap); + + cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data; + cmd->ev_bitmap = __cpu_to_le32(ev_bitmap); + return ath10k_wmi_cmd_send(ar, skb, + ar->wmi.cmd->pdev_pktlog_enable_cmdid); +} + +int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar) +{ + struct sk_buff *skb; + + skb = ath10k_wmi_alloc_skb(ar, 0); + if (!skb) + return -ENOMEM; + + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n"); + + return ath10k_wmi_cmd_send(ar, skb, + ar->wmi.cmd->pdev_pktlog_disable_cmdid); +} + int ath10k_wmi_attach(struct ath10k *ar) { if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 6243dbe756ea..a38d788a6101 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2787,6 +2787,10 @@ struct wmi_pdev_set_channel_cmd { struct wmi_channel chan; } __packed; +struct wmi_pdev_pktlog_enable_cmd { + __le32 ev_bitmap; +} __packed; + /* Customize the DSCP (bit) to TID (0-7) mapping for QOS */ #define WMI_DSCP_MAP_MAX (64) struct wmi_pdev_set_dscp_tid_map_cmd { @@ -4647,5 +4651,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, struct ath10k_fw_stats *stats); +int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list); +int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar); #endif /* _WMI_H_ */ -- GitLab From bfdd7937ab1a3ee0d02dc2d6876c597539a0d37d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Oct 2014 08:02:40 +0300 Subject: [PATCH 0183/9457] ath10k: add tracing for ath10k_htt_pktlog This is useful for collecting pktlog statistics of tx, rx and rate information, so add tracing for the API call. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.h | 1 - drivers/net/wireless/ath/ath10k/htt.h | 2 +- drivers/net/wireless/ath/ath10k/htt_rx.c | 9 ++++++++ drivers/net/wireless/ath/ath10k/hw.h | 9 ++++++++ drivers/net/wireless/ath/ath10k/trace.h | 27 ++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index ce86ed29e119..0c934a8378db 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -69,7 +69,6 @@ struct ath10k_fw_crash_data * ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); - #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 3b44217a6c19..15c58e884b6a 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -725,7 +725,7 @@ static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test) */ struct htt_pktlog_msg { u8 pad[3]; - __le32 payload[1 /* or more */]; + u8 payload[0]; } __packed; struct htt_dbg_stats_rx_reorder_stats { diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 60d40a04508b..a078451b4620 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1674,6 +1674,15 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) case HTT_T2H_MSG_TYPE_RX_DELBA: ath10k_htt_rx_delba(ar, resp); break; + case HTT_T2H_MSG_TYPE_PKTLOG: { + struct ath10k_pktlog_hdr *hdr = + (struct ath10k_pktlog_hdr *)resp->pktlog_msg.payload; + + trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload, + sizeof(*hdr) + + __le16_to_cpu(hdr->size)); + break; + } case HTT_T2H_MSG_TYPE_RX_FLUSH: { /* Ignore this event because mac80211 takes care of Rx * aggregation reordering. diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 006a9cbc60b2..4b86ca363b39 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -80,6 +80,15 @@ enum ath10k_mcast2ucast_mode { ATH10K_MCAST2UCAST_ENABLED = 1, }; +struct ath10k_pktlog_hdr { + __le16 flags; + __le16 missed_cnt; + __le16 log_type; + __le16 size; + __le32 timestamp; + u8 payload[0]; +} __packed; + /* Target specific defines for MAIN firmware */ #define TARGET_NUM_VDEVS 8 #define TARGET_NUM_PEER_AST 2 diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 574b75ab2609..971ff23b6007 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -254,6 +254,33 @@ TRACE_EVENT(ath10k_wmi_dbglog, ) ); +TRACE_EVENT(ath10k_htt_pktlog, + TP_PROTO(struct ath10k *ar, void *buf, u16 buf_len), + + TP_ARGS(ar, buf, buf_len), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(u16, buf_len) + __dynamic_array(u8, pktlog, buf_len) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->buf_len = buf_len; + memcpy(__get_dynamic_array(pktlog), buf, buf_len); + ), + + TP_printk( + "%s %s size %hu", + __get_str(driver), + __get_str(device), + __entry->buf_len + ) +); + #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- GitLab From a0883cf7e75af66917c5ceff7a81ebb6d11b14af Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Oct 2014 08:02:47 +0300 Subject: [PATCH 0184/9457] ath10k: add tracing for rx descriptor Upon the reception of frame, the descriptor status are reported to user space by tracepoint. This is useful for collecting rx statistics. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 ++++ drivers/net/wireless/ath/ath10k/trace.h | 29 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index a078451b4620..7add88ea0e2e 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -316,6 +316,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, int msdu_len, msdu_chaining = 0; struct sk_buff *msdu, *next; struct htt_rx_desc *rx_desc; + u32 tsf; lockdep_assert_held(&htt->rx_ring.lock); @@ -447,6 +448,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & RX_MSDU_END_INFO0_LAST_MSDU; + tsf = __le32_to_cpu(rx_desc->ppdu_end.tsf_timestamp); + trace_ath10k_htt_rx_desc(ar, tsf, &rx_desc->attention, + sizeof(*rx_desc) - sizeof(u32)); if (last_msdu) { msdu->next = NULL; break; diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 971ff23b6007..3841667e3a85 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -281,6 +281,35 @@ TRACE_EVENT(ath10k_htt_pktlog, ) ); +TRACE_EVENT(ath10k_htt_rx_desc, + TP_PROTO(struct ath10k *ar, u32 tsf, void *rxdesc, u16 len), + + TP_ARGS(ar, tsf, rxdesc, len), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(u32, tsf) + __field(u16, len) + __dynamic_array(u8, rxdesc, len) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->tsf = tsf; + __entry->len = len; + memcpy(__get_dynamic_array(rxdesc), rxdesc, len); + ), + + TP_printk( + "%s %s %u len %hu", + __get_str(driver), + __get_str(device), + __entry->tsf, + __entry->len + ) +); #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- GitLab From d1e50f470364b38db0aa25c453403037850edac2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 3 Oct 2014 08:02:54 +0300 Subject: [PATCH 0185/9457] ath10k: add tracing for tx info The tx info such as msdu_id, frame len, vdev id and tid are reported to user space by tracepoint. This is useful for collecting tx statistics. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_tx.c | 1 + drivers/net/wireless/ath/ath10k/trace.h | 60 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/txrx.c | 1 + 3 files changed, 62 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index bd87a35201d8..fdfb1713b173 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -557,6 +557,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); + trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid); ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", flags0, flags1, msdu->len, msdu_id, frags_paddr, diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 3841667e3a85..33b9bf4387f8 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -310,6 +310,66 @@ TRACE_EVENT(ath10k_htt_rx_desc, __entry->len ) ); + +TRACE_EVENT(ath10k_htt_tx, + TP_PROTO(struct ath10k *ar, u16 msdu_id, u16 msdu_len, + u8 vdev_id, u8 tid), + + TP_ARGS(ar, msdu_id, msdu_len, vdev_id, tid), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(u16, msdu_id) + __field(u16, msdu_len) + __field(u8, vdev_id) + __field(u8, tid) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->msdu_id = msdu_id; + __entry->msdu_len = msdu_len; + __entry->vdev_id = vdev_id; + __entry->tid = tid; + ), + + TP_printk( + "%s %s msdu_id %d msdu_len %d vdev_id %d tid %d", + __get_str(driver), + __get_str(device), + __entry->msdu_id, + __entry->msdu_len, + __entry->vdev_id, + __entry->tid + ) +); + +TRACE_EVENT(ath10k_txrx_tx_unref, + TP_PROTO(struct ath10k *ar, u16 msdu_id), + + TP_ARGS(ar, msdu_id), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(u16, msdu_id) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->msdu_id = msdu_id; + ), + + TP_printk( + "%s %s msdu_id %d", + __get_str(driver), + __get_str(device), + __entry->msdu_id + ) +); #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index a0cbc21d0d4b..f9c90e37bc7c 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -78,6 +78,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, info = IEEE80211_SKB_CB(msdu); memset(&info->status, 0, sizeof(info->status)); + trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); if (tx_done->discard) { ieee80211_free_txskb(htt->ar->hw, msdu); -- GitLab From 0f34a0060aebf202010b3f8fef348653a2df2346 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 24 Sep 2014 11:05:10 +0300 Subject: [PATCH 0186/9457] ima: check ima_policy_flag in the ima_file_free() hook This patch completes the switching to the 'ima_policy_flag' variable in the checks at the beginning of IMA functions, starting with the commit a756024e. Checking 'iint_initialized' is completely unnecessary, because S_IMA flag is unset if iint was not allocated. At the same time the integrity cache is allocated with SLAB_PANIC and the kernel will panic if the allocation fails during kernel initialization. So on a running system iint_initialized is always true and can be removed. Changes in v3: * not limiting test to IMA_APPRAISE (spotted by Roberto Sassu) Changes in v2: * 'iint_initialized' removal patch merged to this patch (requested by Mimi) Signed-off-by: Dmitry Kasatkin Acked-by: Roberto Sassu --- security/integrity/iint.c | 3 --- security/integrity/ima/ima_main.c | 2 +- security/integrity/integrity.h | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/security/integrity/iint.c b/security/integrity/iint.c index a521edf4cbd6..cc3eb4de18a1 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -25,8 +25,6 @@ static struct rb_root integrity_iint_tree = RB_ROOT; static DEFINE_RWLOCK(integrity_iint_lock); static struct kmem_cache *iint_cache __read_mostly; -int iint_initialized; - /* * __integrity_iint_find - return the iint associated with an inode */ @@ -166,7 +164,6 @@ static int __init integrity_iintcache_init(void) iint_cache = kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), 0, SLAB_PANIC, init_once); - iint_initialized = 1; return 0; } security_initcall(integrity_iintcache_init); diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 62f59eca32d3..72faf0b5b05c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -143,7 +143,7 @@ void ima_file_free(struct file *file) struct inode *inode = file_inode(file); struct integrity_iint_cache *iint; - if (!iint_initialized || !S_ISREG(inode->i_mode)) + if (!ima_policy_flag || !S_ISREG(inode->i_mode)) return; iint = integrity_iint_find(inode); diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index c0379d13dbe1..883a5fc75449 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -169,6 +169,3 @@ static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, { } #endif - -/* set during initialization */ -extern int iint_initialized; -- GitLab From d16a8585d3715ef161cc9858b50ea5d3c8b6079b Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 1 Oct 2014 21:43:07 +0300 Subject: [PATCH 0187/9457] integrity: add missing '__init' keyword for integrity_init_keyring() integrity_init_keyring() is used only from kernel '__init' functions. Add it there as well. Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/digsig.c | 2 +- security/integrity/integrity.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 8d4fbff8b87c..4f643d1b34dd 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -63,7 +63,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, return -EOPNOTSUPP; } -int integrity_init_keyring(const unsigned int id) +int __init integrity_init_keyring(const unsigned int id) { const struct cred *cred = current_cred(); int err = 0; diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 883a5fc75449..f51ad65c894d 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -129,7 +129,7 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, const char *digest, int digestlen); -int integrity_init_keyring(const unsigned int id); +int __init integrity_init_keyring(const unsigned int id); #else static inline int integrity_digsig_verify(const unsigned int id, -- GitLab From c2baec7ffaf6a2c15e03028ed9ef82a92cc49a94 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 1 Oct 2014 21:43:08 +0300 Subject: [PATCH 0188/9457] evm: skip replacing EVM signature with HMAC on read-only filesystem If filesystem is mounted read-only or file is immutable, updating xattr will fail. This is a usual case during early boot until filesystem is remount read-write. This patch verifies conditions to skip unnecessary attempt to calculate HMAC and set xattr. Changes in v2: * indention changed according to Lindent (requested by Mimi) Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/evm/evm_main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 9685af330de5..b392fe614738 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -162,9 +162,14 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, (const char *)xattr_data, xattr_len, calc.digest, sizeof(calc.digest)); if (!rc) { - /* we probably want to replace rsa with hmac here */ - evm_update_evmxattr(dentry, xattr_name, xattr_value, - xattr_value_len); + /* Replace RSA with HMAC if not mounted readonly and + * not immutable + */ + if (!IS_RDONLY(dentry->d_inode) && + !IS_IMMUTABLE(dentry->d_inode)) + evm_update_evmxattr(dentry, xattr_name, + xattr_value, + xattr_value_len); } break; default: -- GitLab From 456f5fd3f6017f10d04d459159ac7bd9e3815c5e Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 1 Oct 2014 21:43:10 +0300 Subject: [PATCH 0189/9457] ima: use path names cache __getname() uses slab allocation which is faster than kmalloc. Make use of it. Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_api.c | 4 ++-- security/integrity/ima/ima_main.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 86885979918c..a99eb6d4bc09 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -325,11 +325,11 @@ const char *ima_d_path(struct path *path, char **pathbuf) { char *pathname = NULL; - *pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); + *pathbuf = __getname(); if (*pathbuf) { pathname = d_absolute_path(path, *pathbuf, PATH_MAX); if (IS_ERR(pathname)) { - kfree(*pathbuf); + __putname(*pathbuf); *pathbuf = NULL; pathname = NULL; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 72faf0b5b05c..eeee00dce729 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -246,7 +246,8 @@ static int process_measurement(struct file *file, int mask, int function, rc = -EACCES; kfree(xattr_value); out_free: - kfree(pathbuf); + if (pathbuf) + __putname(pathbuf); out: mutex_unlock(&inode->i_mutex); if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) -- GitLab From 2358a544fe65d2b5cde1e4b97bd16c04473394a9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 2 Oct 2014 13:32:55 +0200 Subject: [PATCH 0190/9457] ath10k: warn on unhandled htt events It makes a lot more sense to print these kinds of problems as a warning instead of a debug. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 7add88ea0e2e..27b3051d9ffd 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1694,8 +1694,8 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) break; } default: - ath10k_dbg(ar, ATH10K_DBG_HTT, "htt event (%d) not handled\n", - resp->hdr.msg_type); + ath10k_warn(ar, "htt event (%d) not handled\n", + resp->hdr.msg_type); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", skb->data, skb->len); break; -- GitLab From 3c7984e97f32d39d6cfee1b3e57d5b3ab70665dc Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Thu, 2 Oct 2014 13:56:40 +0200 Subject: [PATCH 0191/9457] ath10k: don't create bssid peer for ibss It's not really necessary to create bssid peer for bssid. Self-address peer is sufficient. This prevents some firmware revisions from crashing. Signed-off-by: Janusz Dziedzic Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 4a061a7e0885..11918575decc 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -992,14 +992,6 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, if (is_zero_ether_addr(arvif->bssid)) return; - ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, - arvif->bssid); - if (ret) { - ath10k_warn(ar, "failed to delete IBSS BSSID peer %pM for vdev %d: %d\n", - arvif->bssid, arvif->vdev_id, ret); - return; - } - memset(arvif->bssid, 0, ETH_ALEN); return; @@ -3127,17 +3119,17 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID && vif->type != NL80211_IFTYPE_AP) { if (!is_zero_ether_addr(info->bssid)) { - ath10k_dbg(ar, ATH10K_DBG_MAC, - "mac vdev %d create peer %pM\n", - arvif->vdev_id, info->bssid); - - ret = ath10k_peer_create(ar, arvif->vdev_id, - info->bssid); - if (ret) - ath10k_warn(ar, "failed to add peer %pM for vdev %d when changing bssid: %i\n", - info->bssid, arvif->vdev_id, ret); - if (vif->type == NL80211_IFTYPE_STATION) { + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac vdev %d create peer %pM\n", + arvif->vdev_id, info->bssid); + + ret = ath10k_peer_create(ar, arvif->vdev_id, + info->bssid); + if (ret) + ath10k_warn(ar, "failed to add peer %pM for vdev %d when changing bssid: %i\n", + info->bssid, arvif->vdev_id, + ret); /* * this is never erased as we it for crypto key * clearing; this is FW requirement -- GitLab From 8026cae7aa02f24c25471269009fa8ffc6f72cd6 Mon Sep 17 00:00:00 2001 From: Bartosz Markowski Date: Mon, 6 Oct 2014 14:16:41 +0200 Subject: [PATCH 0192/9457] ath10k: advertise all possible firmware(-api) files This is required if we take into account possibility to load the driver from initrd (RAM disk), so in other words: very early in the boot process, before the file system is visible. In such case we need to have the firmware files accessible from ram disk too, and this patch guarantee this. Signed-off-by: Bartosz Markowski Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/hw.h | 1 - drivers/net/wireless/ath/ath10k/pci.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 4b86ca363b39..5dd6551801d5 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -28,7 +28,6 @@ #define QCA988X_HW_2_0_CHIP_ID_REV 0x2 #define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" #define QCA988X_HW_2_0_FW_FILE "firmware.bin" -#define QCA988X_HW_2_0_FW_3_FILE "firmware-3.bin" #define QCA988X_HW_2_0_OTP_FILE "otp.bin" #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 8a04904cccee..730bb18c3f45 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2600,5 +2600,7 @@ module_exit(ath10k_pci_exit); MODULE_AUTHOR("Qualcomm Atheros"); MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_3_FILE); +MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE); +MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API2_FILE); +MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API3_FILE); MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE); -- GitLab From 6db0885a6cadbfb5d4f24e0b34c5ff30eb66300f Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Tue, 7 Oct 2014 12:26:43 +0200 Subject: [PATCH 0193/9457] ath10k: fix WMI scan command length Fix WMI scan command length we setup when scan request. This fix issue with 636 firmware when scan always failed with message: ath10k_pci 0000:02:00.0: wmi start scan ath10k_pci 0000:02:00.0: wmi stop scan reqid 1 req_type 0 vdev/scan_id 0 ath10k_pci 0000:02:00.0: failed to stop wmi scan: -11 ath10k_pci 0000:02:00.0: failed to stop scan: -11 ath10k_pci 0000:02:00.0: failed to start hw scan: -110 Signed-off-by: Janusz Dziedzic Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c145b985f7a5..7ca9dcb12847 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3506,10 +3506,10 @@ int ath10k_wmi_start_scan(struct ath10k *ar, return ret; if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - len = sizeof(struct wmi_start_scan_cmd) + + len = sizeof(struct wmi_10x_start_scan_cmd) + ath10k_wmi_start_scan_tlvs_len(arg); else - len = sizeof(struct wmi_10x_start_scan_cmd) + + len = sizeof(struct wmi_start_scan_cmd) + ath10k_wmi_start_scan_tlvs_len(arg); skb = ath10k_wmi_alloc_skb(ar, len); -- GitLab From 9b57f88f1e09e0ac6135e1ca2181ae3d34780606 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 6 Oct 2014 22:39:06 +0530 Subject: [PATCH 0194/9457] ath10k: add tracing for frame transmission Add tracing support to forward management and data frames to user space for packet inspection. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 3 ++ drivers/net/wireless/ath/ath10k/htt_tx.c | 1 + drivers/net/wireless/ath/ath10k/trace.h | 47 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/wmi.c | 2 + 4 files changed, 53 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 27b3051d9ffd..fbb3175d4d6e 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -291,6 +291,9 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) htt->rx_ring.sw_rd_idx.msdu_payld = idx; htt->rx_ring.fill_cnt--; + trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + + skb_tailroom(msdu)); + return msdu; } diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index fdfb1713b173..b0df470250a2 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -564,6 +564,7 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) (u32)skb_cb->paddr, vdev_id, tid); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", msdu->data, msdu->len); + trace_ath10k_htt_tx_msdu(ar, msdu->data, msdu->len); sg_items[0].transfer_id = 0; sg_items[0].transfer_context = NULL; diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 33b9bf4387f8..9d34e7f6c455 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -370,6 +370,53 @@ TRACE_EVENT(ath10k_txrx_tx_unref, __entry->msdu_id ) ); + +DECLARE_EVENT_CLASS(ath10k_data_event, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + + TP_ARGS(ar, data, len), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(size_t, len) + __dynamic_array(u8, data, len) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->len = len; + memcpy(__get_dynamic_array(data), data, len); + ), + + TP_printk( + "%s %s len %zu\n", + __get_str(driver), + __get_str(device), + __entry->len + ) +); + +DEFINE_EVENT(ath10k_data_event, ath10k_htt_tx_msdu, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + TP_ARGS(ar, data, len) +); + +DEFINE_EVENT(ath10k_data_event, ath10k_htt_rx_pop_msdu, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + TP_ARGS(ar, data, len) +); + +DEFINE_EVENT(ath10k_data_event, ath10k_wmi_mgmt_tx, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + TP_ARGS(ar, data, len) +); + +DEFINE_EVENT(ath10k_data_event, ath10k_wmi_bcn_tx, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + TP_ARGS(ar, data, len) +); #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 7ca9dcb12847..829fccfebbff 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -834,6 +834,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); + trace_ath10k_wmi_mgmt_tx(ar, skb->data, skb->len); /* Send the management frame buffer to the target */ ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); @@ -1892,6 +1893,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) arvif->beacon = bcn; arvif->beacon_sent = false; + trace_ath10k_wmi_bcn_tx(ar, bcn->data, bcn->len); ath10k_wmi_tx_beacon_nowait(arvif); skip: spin_unlock_bh(&ar->data_lock); -- GitLab From bd008e5b2953186fc0c6633a885ade95e7043800 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 7 Oct 2014 14:13:51 +0100 Subject: [PATCH 0195/9457] drm: Implement O_NONBLOCK support on /dev/dri/cardN The implmentation is simple in the extreme: we only want to wait for events if the device was opened in blocking mode, otherwise we grab what is available and report an error if there was none. Signed-off-by: Chris Wilson Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jesse Barnes Testcase: igt/kms_flip/nonblocing_read Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fops.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index ed7bc68f7e87..91e1105f2800 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -515,10 +515,12 @@ ssize_t drm_read(struct file *filp, char __user *buffer, size_t total; ssize_t ret; - ret = wait_event_interruptible(file_priv->event_wait, - !list_empty(&file_priv->event_list)); - if (ret < 0) - return ret; + if ((filp->f_flags & O_NONBLOCK) == 0) { + ret = wait_event_interruptible(file_priv->event_wait, + !list_empty(&file_priv->event_list)); + if (ret < 0) + return ret; + } total = 0; while (drm_dequeue_event(file_priv, total, count, &e)) { @@ -532,7 +534,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, e->destroy(e); } - return total; + return total ?: -EAGAIN; } EXPORT_SYMBOL(drm_read); -- GitLab From b7bc9679e4dffe1b5ab75b4ea19e410b7253fa38 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 25 Sep 2014 14:22:18 -0700 Subject: [PATCH 0196/9457] mac80211_hwsim: fix memory leak on netlink TX failure If the packet can't be delivered to userspace (at all or quickly enough) then it can leak - fix that. Signed-off-by: Ben Greear [rewrite commit message] Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index babbdc1ce741..a74227d8a485 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -862,7 +862,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, if (skb_queue_len(&data->pending) >= MAX_QUEUE) { /* Droping until WARN_QUEUE level */ while (skb_queue_len(&data->pending) >= WARN_QUEUE) - skb_dequeue(&data->pending); + ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); } skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -921,6 +921,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, nla_put_failure: printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); + ieee80211_free_txskb(hw, my_skb); } static bool hwsim_chans_compat(struct ieee80211_channel *c1, -- GitLab From 9ebac15f498121693168e61ff42d021cb8dac575 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 25 Sep 2014 14:22:20 -0700 Subject: [PATCH 0197/9457] mac80211_hwsim: fix typo, remove unnecessary goto Trivial cleanups. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index a74227d8a485..f1a0794b33f3 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -436,7 +436,7 @@ struct mac80211_hwsim_data { /* * Only radios in the same group can communicate together (the * channel has to match too). Each bit represents a group. A - * radio can be in more then one group. + * radio can be in more than one group. */ u64 group; @@ -2392,7 +2392,6 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, return 0; err: printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); - goto out; out: dev_kfree_skb(skb); return -EINVAL; -- GitLab From cc61d8df0a0157fabae2a3422f0b7f9f18f81c82 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 29 Sep 2014 02:36:30 +0200 Subject: [PATCH 0198/9457] mac80211: minstrel_ht: fix MCS_GROUP_RATES usage Commit 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability") replaced the constant 8 with MCS_GROUP_RATES when getting the number of streams of an HT MCS. See commit 7a5e3fa2c81c ("mac80211: minstrel_ht: replace some occurences of MCS_GROUP_RATES"). Fixes: 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability") Signed-off-by: Karl Beldan Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index df90ce2db00c..17ef54a7a492 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -135,7 +135,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); static int minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) { - return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, + return GROUP_IDX((rate->idx / 8) + 1, !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); } -- GitLab From 66be7d2bcd826344894be09dc385f9f805136b84 Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Fri, 12 Sep 2014 08:58:49 +0200 Subject: [PATCH 0199/9457] cfg80211: add ops to query mesh proxy path table Add two new cfg80211 operations for querying a table with proxied mesh paths. Signed-off-by: Henning Rogge Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 7 +++ include/uapi/linux/nl80211.h | 6 +++ net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 27 +++++++++- net/wireless/trace.h | 45 ++++++++++++++++ 5 files changed, 183 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a2ddcf2398fd..3f3aaa06adb5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2146,6 +2146,8 @@ struct cfg80211_qos_map { * @change_mpath: change a given mesh path * @get_mpath: get a mesh path for the given parameters * @dump_mpath: dump mesh path callback -- resume dump at index @idx + * @get_mpp: get a mesh proxy path for the given parameters + * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx * @join_mesh: join the mesh network with the specified parameters * (invoked with the wireless_dev mutex held) * @leave_mesh: leave the current mesh network @@ -2396,6 +2398,11 @@ struct cfg80211_ops { int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo); + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, + u8 *dst, u8 *mpp, struct mpath_info *pinfo); + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *dst, u8 *mpp, + struct mpath_info *pinfo); int (*get_mesh_config)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 4b28dc07bcb1..846071b0cde9 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -738,6 +738,10 @@ * before removing a station entry entirely, or before disassociating * or similar, cleanup will happen in the driver/device in this case. * + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -912,6 +916,8 @@ enum nl80211_commands { NL80211_CMD_ADD_TX_TS, NL80211_CMD_DEL_TX_TS, + NL80211_CMD_GET_MPP, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cb9f5a44ffad..d527aa0706c1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4624,6 +4624,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) return rdev_del_mpath(rdev, dev, dst); } +static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + int err; + struct net_device *dev = info->user_ptr[1]; + struct mpath_info pinfo; + struct sk_buff *msg; + u8 *dst = NULL; + u8 mpp[ETH_ALEN]; + + memset(&pinfo, 0, sizeof(pinfo)); + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + dst = nla_data(info->attrs[NL80211_ATTR_MAC]); + + if (!rdev->ops->get_mpp) + return -EOPNOTSUPP; + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; + + err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); + if (err) + return err; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, + dev, dst, mpp, &pinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } + + return genlmsg_reply(msg, info); +} + +static int nl80211_dump_mpp(struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct mpath_info pinfo; + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; + u8 dst[ETH_ALEN]; + u8 mpp[ETH_ALEN]; + int path_idx = cb->args[2]; + int err; + + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (err) + return err; + + if (!rdev->ops->dump_mpp) { + err = -EOPNOTSUPP; + goto out_err; + } + + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { + err = -EOPNOTSUPP; + goto out_err; + } + + while (1) { + err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, + mpp, &pinfo); + if (err == -ENOENT) + break; + if (err) + goto out_err; + + if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + wdev->netdev, dst, mpp, + &pinfo) < 0) + goto out; + + path_idx++; + } + + out: + cb->args[2] = path_idx; + err = skb->len; + out_err: + nl80211_finish_wdev_dump(rdev); + return err; +} + static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -9773,6 +9863,15 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_GET_MPP, + .doit = nl80211_get_mpp, + .dumpit = nl80211_dump_mpp, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, { .cmd = NL80211_CMD_SET_MPATH, .doit = nl80211_set_mpath, diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index f6d457d6a558..c09e697bcb15 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, } +static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, + struct net_device *dev, u8 *dst, u8 *mpp, + struct mpath_info *pinfo) +{ + int ret; + + trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); + ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); + return ret; +} + static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo) @@ -271,7 +283,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, int ret; trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, - pinfo); + pinfo); + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); + return ret; +} + +static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, + struct net_device *dev, int idx, u8 *dst, + u8 *mpp, struct mpath_info *pinfo) + +{ + int ret; + + trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); + ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 625a6e6d1168..8e4f8f04332d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath, MAC_PR_ARG(next_hop)) ); +TRACE_EVENT(rdev_get_mpp, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + u8 *dst, u8 *mpp), + TP_ARGS(wiphy, netdev, dst, mpp), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(dst) + MAC_ENTRY(mpp) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(dst, dst); + MAC_ASSIGN(mpp, mpp); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT + ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, + MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) +); + +TRACE_EVENT(rdev_dump_mpp, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, + u8 *dst, u8 *mpp), + TP_ARGS(wiphy, netdev, idx, mpp, dst), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(dst) + MAC_ENTRY(mpp) + __field(int, idx) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(dst, dst); + MAC_ASSIGN(mpp, mpp); + __entry->idx = idx; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " + MAC_PR_FMT ", mpp: " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), + MAC_PR_ARG(mpp)) +); + TRACE_EVENT(rdev_return_int_mpath_info, TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), TP_ARGS(wiphy, ret, pinfo), -- GitLab From a2db2ed3fb7d35ff2405d08fc012a5db8ddb36e0 Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Fri, 12 Sep 2014 08:58:50 +0200 Subject: [PATCH 0200/9457] mac80211: implement cfg80211_ops to query mesh proxy path table Implement get_mpp and dump_mpp cfg80211_ops to export the content of the 802.11s mesh proxy path table to userspace. Signed-off-by: Henning Rogge Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 53 +++++++++++++++++++++++++++++++++++++ net/mac80211/mesh.h | 3 +++ net/mac80211/mesh_pathtbl.c | 31 ++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fb6a1502b6df..3a04f2edd3c3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1516,6 +1516,57 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, return 0; } +static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, + struct mpath_info *pinfo) +{ + memset(pinfo, 0, sizeof(*pinfo)); + memcpy(mpp, mpath->mpp, ETH_ALEN); + + pinfo->generation = mpp_paths_generation; +} + +static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, + u8 *dst, u8 *mpp, struct mpath_info *pinfo) + +{ + struct ieee80211_sub_if_data *sdata; + struct mesh_path *mpath; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + rcu_read_lock(); + mpath = mpp_path_lookup(sdata, dst); + if (!mpath) { + rcu_read_unlock(); + return -ENOENT; + } + memcpy(dst, mpath->dst, ETH_ALEN); + mpp_set_pinfo(mpath, mpp, pinfo); + rcu_read_unlock(); + return 0; +} + +static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *dst, u8 *mpp, + struct mpath_info *pinfo) +{ + struct ieee80211_sub_if_data *sdata; + struct mesh_path *mpath; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + rcu_read_lock(); + mpath = mpp_path_lookup_by_idx(sdata, idx); + if (!mpath) { + rcu_read_unlock(); + return -ENOENT; + } + memcpy(dst, mpath->dst, ETH_ALEN); + mpp_set_pinfo(mpath, mpp, pinfo); + rcu_read_unlock(); + return 0; +} + static int ieee80211_get_mesh_config(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf) @@ -3547,6 +3598,8 @@ const struct cfg80211_ops mac80211_config_ops = { .change_mpath = ieee80211_change_mpath, .get_mpath = ieee80211_get_mpath, .dump_mpath = ieee80211_dump_mpath, + .get_mpp = ieee80211_get_mpp, + .dump_mpp = ieee80211_dump_mpp, .update_mesh_config = ieee80211_update_mesh_config, .get_mesh_config = ieee80211_get_mesh_config, .join_mesh = ieee80211_join_mesh, diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index f39a19f9090f..50c8473cf9dc 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -270,6 +270,8 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst, const u8 *mpp); struct mesh_path * mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); +struct mesh_path * +mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); void mesh_path_expire(struct ieee80211_sub_if_data *sdata); void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, @@ -317,6 +319,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); extern int mesh_paths_generation; +extern int mpp_paths_generation; #ifdef CONFIG_MAC80211_MESH static inline diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index a6699dceae7c..b890e225a8f1 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -44,6 +44,7 @@ static struct mesh_table __rcu *mesh_paths; static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ int mesh_paths_generation; +int mpp_paths_generation; /* This lock will have the grow table function as writer and add / delete nodes * as readers. RCU provides sufficient protection only when reading the table @@ -409,6 +410,33 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) return NULL; } +/** + * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index + * @idx: index + * @sdata: local subif, or NULL for all entries + * + * Returns: pointer to the proxy path structure, or NULL if not found. + * + * Locking: must be called within a read rcu section. + */ +struct mesh_path * +mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) +{ + struct mesh_table *tbl = rcu_dereference(mpp_paths); + struct mpath_node *node; + int i; + int j = 0; + + for_each_mesh_entry(tbl, node, i) { + if (sdata && node->mpath->sdata != sdata) + continue; + if (j++ == idx) + return node->mpath; + } + + return NULL; +} + /** * mesh_path_add_gate - add the given mpath to a mesh gate to our path table * @mpath: gate path to add to table @@ -691,6 +719,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, spin_unlock(&tbl->hashwlock[hash_idx]); read_unlock_bh(&pathtbl_resize_lock); + + mpp_paths_generation++; + if (grow) { set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); ieee80211_queue_work(&local->hw, &sdata->work); -- GitLab From 2ba45384e5426b9a4aeb77656dce0bf3250ce54e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:35 +0300 Subject: [PATCH 0201/9457] mac80211: add device_timestamp to the ieee80211_channel_switch struct Some devices may need the device timestamp in order to synchronize the channel switch. To pass this value back to the driver, add it to the channel switch structure and copy the device_timestamp value received in the rx info structure into it. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +++ net/mac80211/mlme.c | 15 ++++++++++----- net/mac80211/trace.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 0ad1f47d2dc7..ec0a5b07055b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1117,6 +1117,8 @@ struct ieee80211_conf { * Function (TSF) timer when the frame containing the channel switch * announcement was received. This is simply the rx.mactime parameter * the driver passed into mac80211. + * @device_timestamp: arbitrary timestamp for the device, this is the + * rx.device_timestamp parameter the driver passed to mac80211. * @block_tx: Indicates whether transmission must be blocked before the * scheduled channel switch, as indicated by the AP. * @chandef: the new channel to switch to @@ -1124,6 +1126,7 @@ struct ieee80211_conf { */ struct ieee80211_channel_switch { u64 timestamp; + u32 device_timestamp; bool block_tx; struct cfg80211_chan_def chandef; u8 count; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2de88704278b..f2e048fa250c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1046,7 +1046,8 @@ static void ieee80211_chswitch_timer(unsigned long data) static void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, - u64 timestamp, struct ieee802_11_elems *elems, + u64 timestamp, u32 device_timestamp, + struct ieee802_11_elems *elems, bool beacon) { struct ieee80211_local *local = sdata->local; @@ -1154,6 +1155,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, /* use driver's channel switch callback */ struct ieee80211_channel_switch ch_switch = { .timestamp = timestamp, + .device_timestamp = device_timestamp, .block_tx = csa_ie.mode, .chandef = csa_ie.chandef, .count = csa_ie.count, @@ -3203,6 +3205,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + rx_status->device_timestamp, &elems, true); if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && @@ -3334,8 +3337,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, break; ieee80211_sta_process_chanswitch(sdata, - rx_status->mactime, - &elems, false); + rx_status->mactime, + rx_status->device_timestamp, + &elems, false); } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ies_len = skb->len - offsetof(struct ieee80211_mgmt, @@ -3356,8 +3360,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, &mgmt->u.action.u.ext_chan_switch.data; ieee80211_sta_process_chanswitch(sdata, - rx_status->mactime, - &elems, false); + rx_status->mactime, + rx_status->device_timestamp, + &elems, false); } break; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 38fae7ebe984..853c440218d4 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -995,6 +995,7 @@ TRACE_EVENT(drv_channel_switch, LOCAL_ENTRY CHANDEF_ENTRY __field(u64, timestamp) + __field(u32, device_timestamp) __field(bool, block_tx) __field(u8, count) ), @@ -1003,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch, LOCAL_ASSIGN; CHANDEF_ASSIGN(&ch_switch->chandef) __entry->timestamp = ch_switch->timestamp; + __entry->device_timestamp = ch_switch->device_timestamp; __entry->block_tx = ch_switch->block_tx; __entry->count = ch_switch->count; ), -- GitLab From e9a21949b79414dda42a017855b288901c07e613 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:36 +0300 Subject: [PATCH 0202/9457] mac80211: add extended channel switching capability if the driver supports CSA The Extended Channel Switching capability bit in the extended capabilities element must be set if the driver supports CSA on non-beaconing interfaces. Since this capability needs to be set during driver registration, the extended_capabiliities global variable needs to be moved to the local structure so that it can be modified. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 5 +++++ net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/main.c | 20 +++++++++++--------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index b1be39c76931..5fab17b382b5 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1998,6 +1998,11 @@ enum ieee80211_tdls_actioncode { WLAN_TDLS_DISCOVERY_REQUEST = 10, }; +/* Extended Channel Switching capability to be set in the 1st byte of + * the @WLAN_EID_EXT_CAPABILITY information element + */ +#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) + /* Interworking capabilities are set in 7th bit of 4th byte of the * @WLAN_EID_EXT_CAPABILITY information element */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c2aaec4dfcf0..a9cc49128980 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1307,6 +1307,9 @@ struct ieee80211_local { /* virtual monitor interface */ struct ieee80211_sub_if_data __rcu *monitor_sdata; struct cfg80211_chan_def monitor_chandef; + + /* extended capabilities provided by mac80211 */ + u8 ext_capa[8]; }; static inline struct ieee80211_sub_if_data * diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0de7c93bf62b..107d1c884de3 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -478,11 +478,6 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { }, }; -static const u8 extended_capabilities[] = { - 0, 0, 0, 0, 0, 0, 0, - WLAN_EXT_CAPA8_OPMODE_NOTIF, -}; - struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -539,10 +534,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, WIPHY_FLAG_REPORTS_OBSS | WIPHY_FLAG_OFFCHAN_TX; - wiphy->extended_capabilities = extended_capabilities; - wiphy->extended_capabilities_mask = extended_capabilities; - wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities); - if (ops->remain_on_channel) wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; @@ -591,6 +582,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; + local->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF; + + wiphy->extended_capabilities = local->ext_capa; + wiphy->extended_capabilities_mask = local->ext_capa; + wiphy->extended_capabilities_len = + ARRAY_SIZE(local->ext_capa); + INIT_LIST_HEAD(&local->interfaces); __hw_addr_init(&local->mc_list); @@ -958,6 +956,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + /* mac80211 supports eCSA, if the driver supports STA CSA at all */ + if (local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA) + local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; + local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; result = wiphy_register(local->hw.wiphy); -- GitLab From 6d027bcc8a4e2518ae825b0ff3dd069ab1abfe96 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:37 +0300 Subject: [PATCH 0203/9457] mac80211: add pre_channel_switch driver operation Some drivers may need to prepare for a channel switch also when it is initiated from the remote side (eg. station, P2P client). To make this possible, add a generic callback that can be called for all interface types. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 7 +++++++ net/mac80211/cfg.c | 11 +++++++++++ net/mac80211/driver-ops.h | 18 ++++++++++++++++++ net/mac80211/mlme.c | 25 +++++++++++++++++-------- net/mac80211/trace.h | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 8 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ec0a5b07055b..19e4159ce3a3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2832,6 +2832,10 @@ enum ieee80211_roc_type { * transmitted and then call ieee80211_csa_finish(). * If the CSA count starts as zero or 1, this function will not be called, * since there won't be any time to beacon before the switch anyway. + * @pre_channel_switch: This is an optional callback that is called + * before a channel switch procedure is started (ie. when a STA + * gets a CSA or an userspace initiated channel-switch), allowing + * the driver to prepare for the channel switch. * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A @@ -3038,6 +3042,9 @@ struct ieee80211_ops { void (*channel_switch_beacon)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef); + int (*pre_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel_switch *ch_switch); int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3a04f2edd3c3..647a2f6eb7dc 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3104,6 +3104,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; + struct ieee80211_channel_switch ch_switch; struct ieee80211_chanctx_conf *conf; struct ieee80211_chanctx *chanctx; int err, changed = 0; @@ -3139,6 +3140,10 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } + err = drv_pre_channel_switch(sdata, &ch_switch); + if (err) + goto out; + err = ieee80211_vif_reserve_chanctx(sdata, ¶ms->chandef, chanctx->mode, params->radar_required); @@ -3152,6 +3157,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } + ch_switch.timestamp = 0; + ch_switch.device_timestamp = 0; + ch_switch.block_tx = params->block_tx; + ch_switch.chandef = params->chandef; + ch_switch.count = params->count; + err = ieee80211_set_csa_beacon(sdata, params, &changed); if (err) { ieee80211_vif_unreserve_chanctx(sdata); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 196d48c68134..5522672129ce 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1196,6 +1196,24 @@ drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, } } +static inline int +drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch) +{ + struct ieee80211_local *local = sdata->local; + int ret = 0; + + if (!check_sdata_in_driver(sdata)) + return -EIO; + + trace_drv_pre_channel_switch(local, sdata, ch_switch); + if (local->ops->pre_channel_switch) + ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, + ch_switch); + trace_drv_return_int(local, ret); + return ret; +} + static inline int drv_join_ibss(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f2e048fa250c..d23d6d97e453 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1057,6 +1057,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx *chanctx; enum ieee80211_band current_band; struct ieee80211_csa_ie csa_ie; + struct ieee80211_channel_switch ch_switch; int res; sdata_assert_lock(sdata); @@ -1128,6 +1129,22 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, } } + ch_switch.timestamp = timestamp; + ch_switch.device_timestamp = device_timestamp; + ch_switch.block_tx = csa_ie.mode; + ch_switch.chandef = csa_ie.chandef; + ch_switch.count = csa_ie.count; + + if (drv_pre_channel_switch(sdata, &ch_switch)) { + sdata_info(sdata, + "preparing for channel switch failed, disconnecting\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + return; + } + res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, chanctx->mode, false); if (res) { @@ -1153,14 +1170,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (local->ops->channel_switch) { /* use driver's channel switch callback */ - struct ieee80211_channel_switch ch_switch = { - .timestamp = timestamp, - .device_timestamp = device_timestamp, - .block_tx = csa_ie.mode, - .chandef = csa_ie.chandef, - .count = csa_ie.count, - }; - drv_channel_switch(local, &ch_switch); return; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 853c440218d4..30476d2c7302 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2108,6 +2108,39 @@ TRACE_EVENT(drv_channel_switch_beacon, ) ); +TRACE_EVENT(drv_pre_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch), + + TP_ARGS(local, sdata, ch_switch), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + CHANDEF_ENTRY + __field(u64, timestamp) + __field(bool, block_tx) + __field(u8, count) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + CHANDEF_ASSIGN(&ch_switch->chandef) + __entry->timestamp = ch_switch->timestamp; + __entry->block_tx = ch_switch->block_tx; + __entry->count = ch_switch->count; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " prepare channel switch to " + CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu", + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count, + __entry->block_tx, __entry->timestamp + ) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- GitLab From f1d65583bc5bd43ace8abb9d4f4d9e8da407f708 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:38 +0300 Subject: [PATCH 0204/9457] mac80211: add post_channel_switch driver operation As a counterpart to the pre_channel_switch operation, add a post_channel_switch operation. This allows the drivers to go back to a normal configuration after the channel switch is completed. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ++++++ net/mac80211/cfg.c | 7 ++++++- net/mac80211/driver-ops.h | 16 ++++++++++++++++ net/mac80211/mlme.c | 9 +++++++++ net/mac80211/trace.h | 6 ++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 19e4159ce3a3..7861ed875c4d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2836,6 +2836,9 @@ enum ieee80211_roc_type { * before a channel switch procedure is started (ie. when a STA * gets a CSA or an userspace initiated channel-switch), allowing * the driver to prepare for the channel switch. + * @post_channel_switch: This is an optional callback that is called + * after a channel switch procedure is completed, allowing the + * driver to go back to a normal configuration. * * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all * information in bss_conf is set up and the beacon can be retrieved. A @@ -3046,6 +3049,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch); + int (*post_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); + int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); u32 (*get_expected_throughput)(struct ieee80211_sta *sta); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 647a2f6eb7dc..9d58b30b096a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2919,7 +2919,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) return err; ieee80211_bss_info_change_notify(sdata, changed); - cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, @@ -2927,6 +2926,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) sdata->csa_block_tx = false; } + err = drv_post_channel_switch(sdata); + if (err) + return err; + + cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); + return 0; } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5522672129ce..0a6090644769 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1214,6 +1214,22 @@ drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, return ret; } +static inline int +drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + int ret = 0; + + if (!check_sdata_in_driver(sdata)) + return -EIO; + + trace_drv_post_channel_switch(local, sdata); + if (local->ops->post_channel_switch) + ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); + trace_drv_return_int(local, ret); + return ret; +} + static inline int drv_join_ibss(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d23d6d97e453..cb1a8c3bc73f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1010,6 +1010,15 @@ static void ieee80211_chswitch_work(struct work_struct *work) sdata->csa_block_tx = false; } + ret = drv_post_channel_switch(sdata); + if (ret) { + sdata_info(sdata, + "driver post channel switch failed, disconnecting\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + goto out; + } + ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 30476d2c7302..ca0e12dd23c0 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2141,6 +2141,12 @@ TRACE_EVENT(drv_pre_channel_switch, ) ); +DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata), + TP_ARGS(local, sdata) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- GitLab From 0c21e6320f6ea7c4bd2fc0a8c1d8577b372f92d2 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:39 +0300 Subject: [PATCH 0205/9457] mac80211: wait for the first beacon on the new channel after CSA Instead of immediately reopening the queues (in case of block_tx), calling the post_channel_switch operation and sending the notification, wait for the first beacon on the new channel. This makes sure that we don't lose packets if the AP/GO is not on the new channel yet. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 2 ++ net/mac80211/mlme.c | 45 +++++++++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a9cc49128980..78d6121eb372 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -434,6 +434,8 @@ struct ieee80211_if_managed { unsigned int flags; + bool csa_waiting_bcn; + bool beacon_crc_valid; u32 beacon_crc; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index af237223a8cd..e469b3390f2a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -842,6 +842,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, sdata_lock(sdata); mutex_lock(&local->mtx); sdata->vif.csa_active = false; + if (sdata->vif.type == NL80211_IFTYPE_STATION) + sdata->u.mgd.csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cb1a8c3bc73f..148253c1bd78 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1001,31 +1001,44 @@ static void ieee80211_chswitch_work(struct work_struct *work) /* XXX: shouldn't really modify cfg80211-owned data! */ ifmgd->associated->channel = sdata->csa_chandef.chan; - sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = true; + + ieee80211_sta_reset_beacon_monitor(sdata); + ieee80211_sta_reset_conn_monitor(sdata); + +out: + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + sdata_unlock(sdata); +} + +static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + int ret; + + sdata_assert_lock(sdata); + + WARN_ON(!sdata->vif.csa_active); - /* XXX: wait for a beacon first? */ if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); sdata->csa_block_tx = false; } + sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; + ret = drv_post_channel_switch(sdata); if (ret) { sdata_info(sdata, "driver post channel switch failed, disconnecting\n"); ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); - goto out; + return; } - - ieee80211_sta_reset_beacon_monitor(sdata); - ieee80211_sta_reset_conn_monitor(sdata); - -out: - mutex_unlock(&local->chanctx_mtx); - mutex_unlock(&local->mtx); - sdata_unlock(sdata); } void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) @@ -1943,6 +1956,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ieee80211_vif_release_channel(sdata); sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -2191,6 +2205,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) true, frame_buf); mutex_lock(&local->mtx); sdata->vif.csa_active = false; + ifmgd->csa_waiting_bcn = false; if (sdata->csa_block_tx) { ieee80211_wake_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -3215,6 +3230,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } + if (ifmgd->csa_waiting_bcn) + ieee80211_chswitch_post_beacon(sdata); + if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) return; ifmgd->beacon_crc = ncrc; @@ -3687,11 +3705,12 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) struct ieee80211_sub_if_data *sdata = (struct ieee80211_sub_if_data *) data; struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; if (local->quiescing) return; - if (sdata->vif.csa_active) + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; sdata->u.mgd.connection_loss = false; @@ -3709,7 +3728,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) if (local->quiescing) return; - if (sdata->vif.csa_active) + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) return; ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); -- GitLab From 0f791eb47f8222fd594e6f8a090632344ef23924 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 8 Oct 2014 09:48:40 +0300 Subject: [PATCH 0206/9457] mac80211: allow channel switch with multiple channel contexts Channel switch with multiple channel contexts should now work fine. Remove check that disallows switches when multiple contexts are in use. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlegacy/4965-mac.c | 2 +- drivers/net/wireless/iwlegacy/4965.h | 5 ++-- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 1 + drivers/net/wireless/ti/wlcore/main.c | 23 +++++++----------- include/net/mac80211.h | 1 + net/mac80211/driver-ops.h | 7 +++--- net/mac80211/mlme.c | 26 ++++++++------------- net/mac80211/trace.h | 9 ++++--- 8 files changed, 34 insertions(+), 40 deletions(-) diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 26fec54dcd03..2748fde4b90c 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6063,7 +6063,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } void -il4965_mac_channel_switch(struct ieee80211_hw *hw, +il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct il_priv *il = hw->priv; diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 337dfcf3bbde..3a57f71b8ed5 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -187,8 +187,9 @@ int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u8 buf_size); int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -void il4965_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch); +void +il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel_switch *ch_switch); void il4965_led_enable(struct il_priv *il); diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2364a3c09b9e..a967bf893a89 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -941,6 +941,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, } static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 575c8f6d4009..6ad3fcedab9b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5177,10 +5177,11 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, } static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch) { struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int ret; wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); @@ -5190,14 +5191,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); if (unlikely(wl->state == WLCORE_STATE_OFF)) { - wl12xx_for_each_wlvif_sta(wl, wlvif) { - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); - - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; - + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ieee80211_chswitch_done(vif, false); - } goto out; } else if (unlikely(wl->state != WLCORE_STATE_ON)) { goto out; @@ -5208,11 +5203,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, goto out; /* TODO: change mac80211 to pass vif as param */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - unsigned long delay_usec; - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { + unsigned long delay_usec; ret = wl->ops->channel_switch(wl, wlvif, ch_switch); if (ret) @@ -5222,10 +5215,10 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, /* indicate failure 5 seconds after channel switch time */ delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) * - ch_switch->count; + ch_switch->count; ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work, - usecs_to_jiffies(delay_usec) + - msecs_to_jiffies(5000)); + usecs_to_jiffies(delay_usec) + + msecs_to_jiffies(5000)); } out_sleep: diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7861ed875c4d..9bb2fc73aeaa 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2969,6 +2969,7 @@ struct ieee80211_ops { void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_channel_switch *ch_switch); int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 0a6090644769..1bbb0790264f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -764,12 +764,13 @@ static inline void drv_flush(struct ieee80211_local *local, } static inline void drv_channel_switch(struct ieee80211_local *local, - struct ieee80211_channel_switch *ch_switch) + struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel_switch *ch_switch) { might_sleep(); - trace_drv_channel_switch(local, ch_switch); - local->ops->channel_switch(&local->hw, ch_switch); + trace_drv_channel_switch(local, sdata, ch_switch); + local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); trace_drv_return_void(local); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 148253c1bd78..fb6561509caf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1134,21 +1134,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, chanctx = container_of(conf, struct ieee80211_chanctx, conf); - if (local->use_chanctx) { - u32 num_chanctx = 0; - list_for_each_entry(chanctx, &local->chanctx_list, list) - num_chanctx++; - - if (num_chanctx > 1 || - !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { - sdata_info(sdata, - "not handling chan-switch with channel contexts\n"); - ieee80211_queue_work(&local->hw, - &ifmgd->csa_connection_drop_work); - mutex_unlock(&local->chanctx_mtx); - mutex_unlock(&local->mtx); - return; - } + if (local->use_chanctx && + !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { + sdata_info(sdata, + "driver doesn't support chan-switch with channel contexts\n"); + ieee80211_queue_work(&local->hw, + &ifmgd->csa_connection_drop_work); + mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->mtx); + return; } ch_switch.timestamp = timestamp; @@ -1192,7 +1186,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (local->ops->channel_switch) { /* use driver's channel switch callback */ - drv_channel_switch(local, &ch_switch); + drv_channel_switch(local, sdata, &ch_switch); return; } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index ca0e12dd23c0..976606aebac9 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -987,12 +987,14 @@ TRACE_EVENT(drv_flush, TRACE_EVENT(drv_channel_switch, TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, struct ieee80211_channel_switch *ch_switch), - TP_ARGS(local, ch_switch), + TP_ARGS(local, sdata, ch_switch), TP_STRUCT__entry( LOCAL_ENTRY + VIF_ENTRY CHANDEF_ENTRY __field(u64, timestamp) __field(u32, device_timestamp) @@ -1002,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch, TP_fast_assign( LOCAL_ASSIGN; + VIF_ASSIGN; CHANDEF_ASSIGN(&ch_switch->chandef) __entry->timestamp = ch_switch->timestamp; __entry->device_timestamp = ch_switch->device_timestamp; @@ -1010,8 +1013,8 @@ TRACE_EVENT(drv_channel_switch, ), TP_printk( - LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", - LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count + LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d", + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count ) ); -- GitLab From e9ed49bf4c2c2bd4d57667f14d595864d7596ded Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 9 Oct 2014 15:27:51 +0300 Subject: [PATCH 0207/9457] mac80211-hwsim: Add support for HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE Add support for new attribute HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE which can be set by the user space component. The attribute will cause the kernel to destroy all those radios that were created by a process if that process dies. The old behaviour i.e., radios are persistent is still the default. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 40 +++++++++++++++++++++++++-- drivers/net/wireless/mac80211_hwsim.h | 3 ++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index f1a0794b33f3..6ffe07323e6e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -412,6 +412,9 @@ struct mac80211_hwsim_data { struct mac_address addresses[2]; int channels, idx; bool use_chanctx; + bool destroy_on_close; + struct work_struct destroy_work; + u32 portid; struct ieee80211_channel *tmp_chan; struct delayed_work roc_done; @@ -496,6 +499,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 }, [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG }, [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG }, + [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG }, }; static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, @@ -1947,7 +1951,8 @@ static struct ieee80211_ops mac80211_hwsim_mchan_ops; static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, const struct ieee80211_regdomain *regd, bool reg_strict, bool p2p_device, - bool use_chanctx) + bool use_chanctx, bool destroy_on_close, + u32 portid) { int err; u8 addr[ETH_ALEN]; @@ -2007,6 +2012,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, data->channels = channels; data->use_chanctx = use_chanctx; data->idx = idx; + data->destroy_on_close = destroy_on_close; + data->portid = portid; if (data->use_chanctx) { hw->wiphy->max_scan_ssids = 255; @@ -2434,6 +2441,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) const struct ieee80211_regdomain *regd = NULL; bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; + bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; bool use_chanctx; if (info->attrs[HWSIM_ATTR_CHANNELS]) @@ -2456,7 +2464,8 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) } return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, - p2p_device, use_chanctx); + p2p_device, use_chanctx, + destroy_on_close, info->snd_portid); } static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) @@ -2514,6 +2523,29 @@ static const struct genl_ops hwsim_ops[] = { }, }; +static void destroy_radio(struct work_struct *work) +{ + struct mac80211_hwsim_data *data = + container_of(work, struct mac80211_hwsim_data, destroy_work); + + mac80211_hwsim_destroy_radio(data); +} + +static void remove_user_radios(u32 portid) +{ + struct mac80211_hwsim_data *entry, *tmp; + + spin_lock_bh(&hwsim_radio_lock); + list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { + if (entry->destroy_on_close && entry->portid == portid) { + list_del(&entry->list); + INIT_WORK(&entry->destroy_work, destroy_radio); + schedule_work(&entry->destroy_work); + } + } + spin_unlock_bh(&hwsim_radio_lock); +} + static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, unsigned long state, void *_notify) @@ -2523,6 +2555,8 @@ static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, if (state != NETLINK_URELEASE) return NOTIFY_DONE; + remove_user_radios(notify->portid); + if (notify->portid == wmediumd_portid) { printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" " socket, switching to perfect channel medium\n"); @@ -2676,7 +2710,7 @@ static int __init init_mac80211_hwsim(void) err = mac80211_hwsim_create_radio(channels, reg_alpha2, regd, reg_strict, support_p2p_device, - channels > 1); + channels > 1, false, 0); if (err < 0) goto out_free_radios; } diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index c9d0315575ba..b96d8670a703 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -111,6 +111,8 @@ enum { * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO * command to force use of channel contexts even when only a * single channel is supported + * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO + * command to force radio removal when process that created the radio dies * @__HWSIM_ATTR_MAX: enum limit */ @@ -132,6 +134,7 @@ enum { HWSIM_ATTR_REG_STRICT_REG, HWSIM_ATTR_SUPPORT_P2P_DEVICE, HWSIM_ATTR_USE_CHANCTX, + HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) -- GitLab From 408b18abf677841f49d64ceb884e2b196ca1cf05 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 9 Oct 2014 20:36:22 +0200 Subject: [PATCH 0208/9457] mac80211: directly return ieee80211_vif_use_reserved_context() No need to store ieee80211_vif_use_reserved_context() result and test it before returning. Signed-off-by: Fabian Frederick Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 9d58b30b096a..4bb2d34b2dd7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2901,11 +2901,7 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) if (sdata->reserved_ready) return 0; - err = ieee80211_vif_use_reserved_context(sdata); - if (err) - return err; - - return 0; + return ieee80211_vif_use_reserved_context(sdata); } if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, -- GitLab From b12206e917ac34bec41b9ff93d37d8bd53a2b3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Andersen?= Date: Wed, 8 Oct 2014 20:42:00 +0200 Subject: [PATCH 0209/9457] iio: adc: mcp320x. Add support for more ADCs Signed-off-by: Soeren Andersen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mcp320x.c | 222 ++++++++++++++++++++++++++++++++------ 1 file changed, 187 insertions(+), 35 deletions(-) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 28a086e48776..efbfd12a4bfd 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -1,9 +1,30 @@ /* * Copyright (C) 2013 Oskar Andero + * Copyright (C) 2014 Rose Technology + * Allan Bendorff Jensen + * Soren Andersen + * + * Driver for following ADC chips from Microchip Technology's: + * 10 Bit converter + * MCP3001 + * MCP3002 + * MCP3004 + * MCP3008 + * ------------ + * 12 bit converter + * MCP3201 + * MCP3202 + * MCP3204 + * MCP3208 + * ------------ * - * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips. * Datasheet can be found here: - * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf + * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf mcp3002 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf mcp3004/08 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf mcp3201 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,19 +32,29 @@ */ #include +#include #include #include #include #include -#define MCP_SINGLE_ENDED (1 << 3) -#define MCP_START_BIT (1 << 4) - enum { + mcp3001, + mcp3002, + mcp3004, + mcp3008, + mcp3201, + mcp3202, mcp3204, mcp3208, }; +struct mcp320x_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; + unsigned int resolution; +}; + struct mcp320x { struct spi_device *spi; struct spi_message msg; @@ -34,19 +65,69 @@ struct mcp320x { struct regulator *reg; struct mutex lock; + const struct mcp320x_chip_info *chip_info; }; -static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg) +static int mcp320x_channel_to_tx_data(int device_index, + const unsigned int channel, bool differential) +{ + int start_bit = 1; + + switch (device_index) { + case mcp3001: + case mcp3201: + return 0; + case mcp3002: + case mcp3202: + return ((start_bit << 4) | (!differential << 3) | + (channel << 2)); + case mcp3004: + case mcp3204: + case mcp3008: + case mcp3208: + return ((start_bit << 6) | (!differential << 5) | + (channel << 2)); + default: + return -EINVAL; + } +} + +static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, + bool differential, int device_index) { int ret; - adc->tx_buf = msg; - ret = spi_sync(adc->spi, &adc->msg); - if (ret < 0) - return ret; + adc->rx_buf[0] = 0; + adc->rx_buf[1] = 0; + adc->tx_buf = mcp320x_channel_to_tx_data(device_index, + channel, differential); + + if (device_index != mcp3001 && device_index != mcp3201) { + ret = spi_sync(adc->spi, &adc->msg); + if (ret < 0) + return ret; + } else { + ret = spi_read(adc->spi, &adc->rx_buf, sizeof(adc->rx_buf)); + if (ret < 0) + return ret; + } - return ((adc->rx_buf[0] & 0x3f) << 6) | - (adc->rx_buf[1] >> 2); + switch (device_index) { + case mcp3001: + return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + case mcp3002: + case mcp3004: + case mcp3008: + return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + case mcp3201: + return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + case mcp3202: + case mcp3204: + case mcp3208: + return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + default: + return -EINVAL; + } } static int mcp320x_read_raw(struct iio_dev *indio_dev, @@ -55,18 +136,17 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, { struct mcp320x *adc = iio_priv(indio_dev); int ret = -EINVAL; + int device_index = 0; mutex_lock(&adc->lock); + device_index = spi_get_device_id(adc->spi)->driver_data; + switch (mask) { case IIO_CHAN_INFO_RAW: - if (channel->differential) - ret = mcp320x_adc_conversion(adc, - MCP_START_BIT | channel->address); - else - ret = mcp320x_adc_conversion(adc, - MCP_START_BIT | MCP_SINGLE_ENDED | - channel->address); + ret = mcp320x_adc_conversion(adc, channel->address, + channel->differential, device_index); + if (ret < 0) goto out; @@ -75,18 +155,15 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, break; case IIO_CHAN_INFO_SCALE: - /* Digital output code = (4096 * Vin) / Vref */ ret = regulator_get_voltage(adc->reg); if (ret < 0) goto out; + /* convert regulator output voltage to mV */ *val = ret / 1000; - *val2 = 12; + *val2 = adc->chip_info->resolution; ret = IIO_VAL_FRACTIONAL_LOG2; break; - - default: - break; } out: @@ -117,6 +194,16 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ } +static const struct iio_chan_spec mcp3201_channels[] = { + MCP320X_VOLTAGE_CHANNEL_DIFF(0), +}; + +static const struct iio_chan_spec mcp3202_channels[] = { + MCP320X_VOLTAGE_CHANNEL(0), + MCP320X_VOLTAGE_CHANNEL(1), + MCP320X_VOLTAGE_CHANNEL_DIFF(0), +}; + static const struct iio_chan_spec mcp3204_channels[] = { MCP320X_VOLTAGE_CHANNEL(0), MCP320X_VOLTAGE_CHANNEL(1), @@ -146,19 +233,46 @@ static const struct iio_info mcp320x_info = { .driver_module = THIS_MODULE, }; -struct mcp3208_chip_info { - const struct iio_chan_spec *channels; - unsigned int num_channels; -}; - -static const struct mcp3208_chip_info mcp3208_chip_infos[] = { +static const struct mcp320x_chip_info mcp320x_chip_infos[] = { + [mcp3001] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 10 + }, + [mcp3002] = { + .channels = mcp3202_channels, + .num_channels = ARRAY_SIZE(mcp3202_channels), + .resolution = 10 + }, + [mcp3004] = { + .channels = mcp3204_channels, + .num_channels = ARRAY_SIZE(mcp3204_channels), + .resolution = 10 + }, + [mcp3008] = { + .channels = mcp3208_channels, + .num_channels = ARRAY_SIZE(mcp3208_channels), + .resolution = 10 + }, + [mcp3201] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 12 + }, + [mcp3202] = { + .channels = mcp3202_channels, + .num_channels = ARRAY_SIZE(mcp3202_channels), + .resolution = 12 + }, [mcp3204] = { .channels = mcp3204_channels, - .num_channels = ARRAY_SIZE(mcp3204_channels) + .num_channels = ARRAY_SIZE(mcp3204_channels), + .resolution = 12 }, [mcp3208] = { .channels = mcp3208_channels, - .num_channels = ARRAY_SIZE(mcp3208_channels) + .num_channels = ARRAY_SIZE(mcp3208_channels), + .resolution = 12 }, }; @@ -166,7 +280,7 @@ static int mcp320x_probe(struct spi_device *spi) { struct iio_dev *indio_dev; struct mcp320x *adc; - const struct mcp3208_chip_info *chip_info; + const struct mcp320x_chip_info *chip_info; int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); @@ -181,7 +295,7 @@ static int mcp320x_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp320x_info; - chip_info = &mcp3208_chip_infos[spi_get_device_id(spi)->driver_data]; + chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; indio_dev->channels = chip_info->channels; indio_dev->num_channels = chip_info->num_channels; @@ -226,7 +340,45 @@ static int mcp320x_remove(struct spi_device *spi) return 0; } +#if defined(CONFIG_OF) +static const struct of_device_id mcp320x_dt_ids[] = { + { + .compatible = "mcp3001", + .data = &mcp320x_chip_infos[mcp3001], + }, { + .compatible = "mcp3002", + .data = &mcp320x_chip_infos[mcp3002], + }, { + .compatible = "mcp3004", + .data = &mcp320x_chip_infos[mcp3004], + }, { + .compatible = "mcp3008", + .data = &mcp320x_chip_infos[mcp3008], + }, { + .compatible = "mcp3201", + .data = &mcp320x_chip_infos[mcp3201], + }, { + .compatible = "mcp3202", + .data = &mcp320x_chip_infos[mcp3202], + }, { + .compatible = "mcp3204", + .data = &mcp320x_chip_infos[mcp3204], + }, { + .compatible = "mcp3208", + .data = &mcp320x_chip_infos[mcp3208], + }, { + } +}; +MODULE_DEVICE_TABLE(of, mcp320x_dt_ids); +#endif + static const struct spi_device_id mcp320x_id[] = { + { "mcp3001", mcp3001 }, + { "mcp3002", mcp3002 }, + { "mcp3004", mcp3004 }, + { "mcp3008", mcp3008 }, + { "mcp3201", mcp3201 }, + { "mcp3202", mcp3202 }, { "mcp3204", mcp3204 }, { "mcp3208", mcp3208 }, { } @@ -245,5 +397,5 @@ static struct spi_driver mcp320x_driver = { module_spi_driver(mcp320x_driver); MODULE_AUTHOR("Oskar Andero "); -MODULE_DESCRIPTION("Microchip Technology MCP3204/08"); +MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08"); MODULE_LICENSE("GPL v2"); -- GitLab From 486cf4c08fe8b2b049bfccb76ce445ec1088fa25 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 10 Oct 2014 12:43:23 +0200 Subject: [PATCH 0210/9457] mac80211: enable DFS with channel contexts It is okay to enable DFS for channel contexts based drivers as long as no combination advertises radar detection and multi-channel operation at the same time. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/main.c | 5 +++-- net/mac80211/util.c | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 107d1c884de3..9e322dce64ec 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -785,13 +785,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) return -EINVAL; - /* DFS currently not supported with channel context drivers */ + /* DFS is not supported with multi-channel combinations yet */ for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { const struct ieee80211_iface_combination *comb; comb = &local->hw.wiphy->iface_combinations[i]; - if (comb->radar_detect_widths) + if (comb->radar_detect_widths && + comb->num_different_channels > 1) return -EINVAL; } } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3c61060a4d2b..c76c9d7294ae 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2526,11 +2526,23 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) struct ieee80211_local *local = container_of(work, struct ieee80211_local, radar_detected_work); struct cfg80211_chan_def chandef = local->hw.conf.chandef; + struct ieee80211_chanctx *ctx; + int num_chanctx = 0; + + mutex_lock(&local->chanctx_mtx); + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) + continue; + + num_chanctx++; + chandef = ctx->conf.def; + } + mutex_unlock(&local->chanctx_mtx); ieee80211_dfs_cac_cancel(local); - if (local->use_chanctx) - /* currently not handled */ + if (num_chanctx > 1) + /* XXX: multi-channel is not supported yet */ WARN_ON(1); else cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); -- GitLab From 2a84ee8625953fbce38b541aed77344044688a3e Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Tue, 7 Oct 2014 11:42:18 +0200 Subject: [PATCH 0211/9457] cfg80211: set the rates mask in connection probes over specified freq ATM, specifying the frequency when connecting sends a void 'supported rates' EID. Signed-off-by: Karl Beldan [fix memory leak in error path] Signed-off-by: Johannes Berg --- net/wireless/sme.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index dc1668ff543b..0ab3711c79a0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -80,9 +80,18 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) if (!request) return -ENOMEM; - if (wdev->conn->params.channel) + if (wdev->conn->params.channel) { + enum ieee80211_band band = wdev->conn->params.channel->band; + struct ieee80211_supported_band *sband = + wdev->wiphy->bands[band]; + + if (!sband) { + kfree(request); + return -EINVAL; + } request->channels[0] = wdev->conn->params.channel; - else { + request->rates[band] = (1 << sband->n_bitrates) - 1; + } else { int i = 0, j; enum ieee80211_band band; struct ieee80211_supported_band *bands; -- GitLab From 78bb5d0b4fe1988ae1a2a0cad0776134846414bd Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 3 Oct 2014 14:40:18 +0300 Subject: [PATCH 0212/9457] ima: report policy load status Audit messages are rate limited, often causing the policy update info to not be visible. Report policy loading status also using pr_info. Changes in v2: * reporting moved to ima_release_policy to notice parsing errors * reporting both completed and failed status Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_fs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index da92fcc08d15..16d85273d408 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -311,6 +311,8 @@ static int ima_open_policy(struct inode *inode, struct file *filp) */ static int ima_release_policy(struct inode *inode, struct file *file) { + pr_info("IMA: policy update %s\n", + valid_policy ? "completed" : "failed"); if (!valid_policy) { ima_delete_rules(); valid_policy = 1; -- GitLab From 272a6e90ffee1dea39efd6fdf9592edc83a0738e Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 3 Oct 2014 14:40:19 +0300 Subject: [PATCH 0213/9457] ima: no need to allocate entry for comment If a rule is a comment, there is no need to allocate an entry. Move the checking for comments before allocating the entry. Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_policy.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index cdc620b2152f..bf232b98011e 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -694,6 +694,12 @@ ssize_t ima_parse_add_rule(char *rule) return -EACCES; } + p = strsep(&rule, "\n"); + len = strlen(p) + 1; + + if (*p == '#') + return len; + entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) { integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, @@ -703,14 +709,6 @@ ssize_t ima_parse_add_rule(char *rule) INIT_LIST_HEAD(&entry->list); - p = strsep(&rule, "\n"); - len = strlen(p) + 1; - - if (*p == '#') { - kfree(entry); - return len; - } - result = ima_parse_rule(p, entry); if (result) { kfree(entry); -- GitLab From 7178784f0a94e2e6c668f587665fde41d405a23c Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 3 Oct 2014 14:40:20 +0300 Subject: [PATCH 0214/9457] ima: ignore empty and with whitespaces policy lines Empty policy lines cause parsing failures which is, especially for new users, hard to spot. This patch prevents it. Changes in v2: * strip leading blanks and tabs in rules to prevent parsing failures Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_policy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index bf232b98011e..d2c47d4df7b7 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -696,8 +696,9 @@ ssize_t ima_parse_add_rule(char *rule) p = strsep(&rule, "\n"); len = strlen(p) + 1; + p += strspn(p, " \t"); - if (*p == '#') + if (*p == '#' || *p == '\0') return len; entry = kzalloc(sizeof(*entry), GFP_KERNEL); -- GitLab From 0716abbb58e3c47e04354c2502083854f49c34e5 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 3 Oct 2014 14:40:21 +0300 Subject: [PATCH 0215/9457] ima: use atomic bit operations to protect policy update interface The current implementation uses an atomic counter to provide exclusive access to the sysfs 'policy' entry to update the IMA policy. While it is highly unlikely, the usage of a counter might potentially allow another process to overflow the counter, open the interface and insert additional rules into the policy being loaded. This patch replaces using an atomic counter with atomic bit operations which is more reliable and a widely used method to provide exclusive access. As bit operation keep the interface locked after successful update, it makes it unnecessary to verify if the default policy was set or not during parsing and interface closing. This patch also removes that code. Changes in v3: * move audit log message to ima_relead_policy() to report successful and unsuccessful result * unnecessary comment removed Changes in v2: * keep interface locked after successful policy load as in original design * remove sysfs entry as in original design Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_fs.c | 23 ++++++++++++++++------- security/integrity/ima/ima_policy.c | 23 ++--------------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 16d85273d408..973b5683a92e 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -288,7 +288,12 @@ static struct dentry *runtime_measurements_count; static struct dentry *violations; static struct dentry *ima_policy; -static atomic_t policy_opencount = ATOMIC_INIT(1); +enum ima_fs_flags { + IMA_FS_BUSY, +}; + +static unsigned long ima_fs_flags; + /* * ima_open_policy: sequentialize access to the policy file */ @@ -297,9 +302,9 @@ static int ima_open_policy(struct inode *inode, struct file *filp) /* No point in being allowed to open it if you aren't going to write */ if (!(filp->f_flags & O_WRONLY)) return -EACCES; - if (atomic_dec_and_test(&policy_opencount)) - return 0; - return -EBUSY; + if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) + return -EBUSY; + return 0; } /* @@ -311,12 +316,16 @@ static int ima_open_policy(struct inode *inode, struct file *filp) */ static int ima_release_policy(struct inode *inode, struct file *file) { - pr_info("IMA: policy update %s\n", - valid_policy ? "completed" : "failed"); + const char *cause = valid_policy ? "completed" : "failed"; + + pr_info("IMA: policy update %s\n", cause); + integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, + "policy_update", cause, !valid_policy, 0); + if (!valid_policy) { ima_delete_rules(); valid_policy = 1; - atomic_set(&policy_opencount, 1); + clear_bit(IMA_FS_BUSY, &ima_fs_flags); return 0; } ima_update_policy(); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d2c47d4df7b7..0d14d2591805 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -356,19 +356,8 @@ void __init ima_init_policy(void) */ void ima_update_policy(void) { - static const char op[] = "policy_update"; - const char *cause = "already-exists"; - int result = 1; - int audit_info = 0; - - if (ima_rules == &ima_default_rules) { - ima_rules = &ima_policy_rules; - ima_update_policy_flag(); - cause = "complete"; - result = 0; - } - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, cause, result, audit_info); + ima_rules = &ima_policy_rules; + ima_update_policy_flag(); } enum { @@ -686,14 +675,6 @@ ssize_t ima_parse_add_rule(char *rule) ssize_t result, len; int audit_info = 0; - /* Prevent installed policy from changing */ - if (ima_rules != &ima_default_rules) { - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "already-exists", - -EACCES, audit_info); - return -EACCES; - } - p = strsep(&rule, "\n"); len = strlen(p) + 1; p += strspn(p, " \t"); -- GitLab From 82d7aba71541a308bc19e869f7cf7423672dee37 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 10 Oct 2014 17:38:27 +0530 Subject: [PATCH 0216/9457] ath10k: fix kernel panic while shutting down AP Based on GFP flag given to DMA coherent allocation, the behaviour of dma_free_coherent is changed. This behavioural diffrence is noticeable in ARM platform. If DMA memory is allocated with GFP_KERNEL, free coherent can not be called inside spin lock. This is causing kernel crash in ARM platforms. Fix this by changing GFP flag to atomic. This is most likely a regression from commit 64badcb6d645 ("ath10k: workaround fw beaconing bug"). Cc: Michal Kazior Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 11918575decc..b2bd80c4f72c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2839,7 +2839,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, arvif->beacon_buf = dma_zalloc_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, &arvif->beacon_paddr, - GFP_KERNEL); + GFP_ATOMIC); if (!arvif->beacon_buf) { ret = -ENOMEM; ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", -- GitLab From a1f1a79c51fd493887bb66d932ee66a23f8b1527 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 11 Oct 2014 22:08:57 -0700 Subject: [PATCH 0217/9457] drm: drm_err: Remove unnecessary __func__ argument Removing the unnecessary drm_err __func__ argument by using the equivalent %pf and __builtin_return_address(0) makes the code smaller for every use of the DRM_ERROR macro. For instance: (allmodconfig) $ size drivers/gpu/drm/i915/i915.o* text data bss dec hex filename 922447 193257 296736 1412440 158d58 drivers/gpu/drm/i915/i915.o.new 928111 193257 296736 1418104 15a378 drivers/gpu/drm/i915/i915.o.old Signed-off-by: Joe Perches Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_drv.c | 5 +++-- include/drm/drmP.h | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index bc3da32d4585..2e5c7d941313 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -56,7 +56,7 @@ static struct idr drm_minors_idr; struct class *drm_class; static struct dentry *drm_debugfs_root; -void drm_err(const char *func, const char *format, ...) +void drm_err(const char *format, ...) { struct va_format vaf; va_list args; @@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...) vaf.fmt = format; vaf.va = &args; - printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf); + printk(KERN_ERR "[" DRM_NAME ":%pf] *ERROR* %pV", + __builtin_return_address(0), &vaf); va_end(args); } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 53ed87698a74..d7ebd7b207e3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -125,8 +125,8 @@ struct dma_buf_attachment; extern __printf(2, 3) void drm_ut_debug_printk(const char *function_name, const char *format, ...); -extern __printf(2, 3) -void drm_err(const char *func, const char *format, ...); +extern __printf(1, 2) +void drm_err(const char *format, ...); /***********************************************************************/ /** \name DRM template customization defaults */ @@ -155,7 +155,7 @@ void drm_err(const char *func, const char *format, ...); * \param arg arguments */ #define DRM_ERROR(fmt, ...) \ - drm_err(__func__, fmt, ##__VA_ARGS__) + drm_err(fmt, ##__VA_ARGS__) /** * Rate limited error output. Like DRM_ERROR() but won't flood the log. @@ -170,7 +170,7 @@ void drm_err(const char *func, const char *format, ...); DEFAULT_RATELIMIT_BURST); \ \ if (__ratelimit(&_rs)) \ - drm_err(__func__, fmt, ##__VA_ARGS__); \ + drm_err(fmt, ##__VA_ARGS__); \ }) #define DRM_INFO(fmt, ...) \ -- GitLab From d87af4d10558fedf636e3df1b10dd2954f9e2a78 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 12 Oct 2014 00:02:32 +0200 Subject: [PATCH 0218/9457] gpu: drm: drm_dp_mst_topology.c: Fix improper use of strncat Fixed wrong usage of strncat, switched to strlcpy. While sending the string size to function to reduce the potential for misuse in future. Signed-off-by: Rickard Strandqvist Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_dp_mst_topology.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b3adf1445020..094af1d17e95 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -995,19 +995,20 @@ static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb, static void build_mst_prop_path(struct drm_dp_mst_port *port, struct drm_dp_mst_branch *mstb, - char *proppath) + char *proppath, + size_t proppath_size) { int i; char temp[8]; - snprintf(proppath, 255, "mst:%d", mstb->mgr->conn_base_id); + snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id); for (i = 0; i < (mstb->lct - 1); i++) { int shift = (i % 2) ? 0 : 4; int port_num = mstb->rad[i / 2] >> shift; - snprintf(temp, 8, "-%d", port_num); - strncat(proppath, temp, 255); + snprintf(temp, sizeof(temp), "-%d", port_num); + strlcat(proppath, temp, proppath_size); } - snprintf(temp, 8, "-%d", port->port_num); - strncat(proppath, temp, 255); + snprintf(temp, sizeof(temp), "-%d", port->port_num); + strlcat(proppath, temp, proppath_size); } static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, @@ -1078,7 +1079,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, if (created && !port->input) { char proppath[255]; - build_mst_prop_path(port, mstb, proppath); + build_mst_prop_path(port, mstb, proppath, sizeof(proppath)); port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); } -- GitLab From d26833bfce5e56017bea9f1f50838f20e18e7b7e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sat, 11 Oct 2014 21:10:36 +0530 Subject: [PATCH 0219/9457] spi/dw: use dmaengine_slave_config() API The drivers should use dmaengine_slave_config() API instead of accessing the device_control which will be deprecated soon Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index ecae30fe28af..1ca8f66ca2ea 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -143,8 +143,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) txconf.dst_addr_width = dws->dma_width; txconf.device_fc = false; - txchan->device->device_control(txchan, DMA_SLAVE_CONFIG, - (unsigned long) &txconf); + dmaengine_slave_config(txchan, &txconf); memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl)); dws->tx_sgl.dma_address = dws->tx_dma; @@ -166,8 +165,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) rxconf.src_addr_width = dws->dma_width; rxconf.device_fc = false; - rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, - (unsigned long) &rxconf); + dmaengine_slave_config(txchan, &rxconf); memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl)); dws->rx_sgl.dma_address = dws->rx_dma; -- GitLab From 71fed2eee0ea76b236f491006078c9d636323184 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 13 Oct 2014 14:08:38 +0200 Subject: [PATCH 0220/9457] ima: added error messages to template-related functions This patch adds some error messages to inform users about the following events: template descriptor not found, invalid template descriptor, template field not found and template initialization failed. Changelog: - v2: - display an error message if the format string contains too many fields (Roberto Sassu) Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_template.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index e854862c9337..1310afc587f3 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -52,8 +52,11 @@ static int __init ima_template_setup(char *str) * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. */ template_desc = lookup_template_desc(str); - if (!template_desc) + if (!template_desc) { + pr_err("template %s not found, using %s\n", + str, CONFIG_IMA_DEFAULT_TEMPLATE); return 1; + } /* * Verify whether the current hash algorithm is supported @@ -117,8 +120,11 @@ static int template_desc_init_fields(const char *template_fmt, int template_num_fields = template_fmt_size(template_fmt); int i, result = 0; - if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) + if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) { + pr_err("format string '%s' contains too many fields\n", + template_fmt); return -EINVAL; + } /* copying is needed as strsep() modifies the original buffer */ template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); @@ -137,6 +143,7 @@ static int template_desc_init_fields(const char *template_fmt, struct ima_template_field *f = lookup_template_field(c); if (!f) { + pr_err("field '%s' not found\n", c); result = -ENOENT; goto out; } @@ -163,8 +170,13 @@ struct ima_template_desc *ima_template_desc_current(void) int __init ima_init_template(void) { struct ima_template_desc *template = ima_template_desc_current(); + int result; - return template_desc_init_fields(template->fmt, - &(template->fields), - &(template->num_fields)); + result = template_desc_init_fields(template->fmt, + &(template->fields), + &(template->num_fields)); + if (result < 0) + pr_err("template %s init failed, result: %d\n", template->name); + + return result; } -- GitLab From 7dbdb4206bd69bf518fd76e01f4c5c64cda96455 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 13 Oct 2014 14:08:39 +0200 Subject: [PATCH 0221/9457] ima: display template format in meas. list if template name length is zero With the introduction of the 'ima_template_fmt' kernel cmdline parameter, a user can define a new template descriptor with custom format. However, in this case, userspace tools will be unable to parse the measurements list because the new template is unknown. For this reason, this patch modifies the current IMA behavior to display in the list the template format instead of the name (only if the length of the latter is zero) so that a tool can extract needed information if it can handle listed fields. This patch also correctly displays the error log message in ima_init_template() if the selected template cannot be initialized. Changelog: - v3: - check the first byte of 'e->template_desc->name' instead of using strlen() in ima_fs.c (suggested by Mimi Zohar) - v2: - print the template format in ima_init_template(), if the selected template is custom (Roberto Sassu) - v1: - fixed patch description (Roberto Sassu, suggested by Mimi Zohar) - set 'template_name' variable in ima_fs.c only once (Roberto Sassu, suggested by Mimi Zohar) Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_fs.c | 16 ++++++++++++---- security/integrity/ima/ima_template.c | 4 +++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 973b5683a92e..461215e5fd31 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -118,6 +118,7 @@ static int ima_measurements_show(struct seq_file *m, void *v) /* the list never shrinks, so we don't need a lock here */ struct ima_queue_entry *qe = v; struct ima_template_entry *e; + char *template_name; int namelen; u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; bool is_ima_template = false; @@ -128,6 +129,9 @@ static int ima_measurements_show(struct seq_file *m, void *v) if (e == NULL) return -1; + template_name = (e->template_desc->name[0] != '\0') ? + e->template_desc->name : e->template_desc->fmt; + /* * 1st: PCRIndex * PCR used is always the same (config option) in @@ -139,14 +143,14 @@ static int ima_measurements_show(struct seq_file *m, void *v) ima_putc(m, e->digest, TPM_DIGEST_SIZE); /* 3rd: template name size */ - namelen = strlen(e->template_desc->name); + namelen = strlen(template_name); ima_putc(m, &namelen, sizeof(namelen)); /* 4th: template name */ - ima_putc(m, e->template_desc->name, namelen); + ima_putc(m, template_name, namelen); /* 5th: template length (except for 'ima' template) */ - if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) + if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0) is_ima_template = true; if (!is_ima_template) @@ -200,6 +204,7 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v) /* the list never shrinks, so we don't need a lock here */ struct ima_queue_entry *qe = v; struct ima_template_entry *e; + char *template_name; int i; /* get entry */ @@ -207,6 +212,9 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v) if (e == NULL) return -1; + template_name = (e->template_desc->name[0] != '\0') ? + e->template_desc->name : e->template_desc->fmt; + /* 1st: PCR used (config option) */ seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); @@ -214,7 +222,7 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v) ima_print_digest(m, e->digest, TPM_DIGEST_SIZE); /* 3th: template name */ - seq_printf(m, " %s", e->template_desc->name); + seq_printf(m, " %s", template_name); /* 4th: template specific data */ for (i = 0; i < e->template_desc->num_fields; i++) { diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 1310afc587f3..b7b359ca39ee 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -176,7 +176,9 @@ int __init ima_init_template(void) &(template->fields), &(template->num_fields)); if (result < 0) - pr_err("template %s init failed, result: %d\n", template->name); + pr_err("template %s init failed, result: %d\n", + (strlen(template->name) ? + template->name : template->fmt), result); return result; } -- GitLab From 9f3166b8ca3b89c27b9f1c9039d3662ab7812cfa Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 13 Oct 2014 14:08:40 +0200 Subject: [PATCH 0222/9457] ima: don't allocate a copy of template_fmt in template_desc_init_fields() This patch removes the allocation of a copy of 'template_fmt', needed for iterating over all fields in the passed template format string. The removal was possible by replacing strcspn(), which modifies the passed string, with strchrnul(). The currently processed template field is copied in a temporary variable. The purpose of this change is use template_desc_init_fields() in two ways: for just validating a template format string (the function should work if called by a setup function, when memory cannot be allocated), and for actually initializing a template descriptor. The implementation of this feature will be complete with the next patch. Changelog: - v3: - added 'goto out' in template_desc_init_fields() to free allocated memory if a template field length is not valid (suggested by Mimi Zohar) Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_template.c | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index b7b359ca39ee..d93a58e603df 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -116,9 +116,9 @@ static int template_desc_init_fields(const char *template_fmt, struct ima_template_field ***fields, int *num_fields) { - char *c, *template_fmt_copy, *template_fmt_ptr; + const char *template_fmt_ptr; int template_num_fields = template_fmt_size(template_fmt); - int i, result = 0; + int i, len, result = 0; if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) { pr_err("format string '%s' contains too many fields\n", @@ -126,24 +126,29 @@ static int template_desc_init_fields(const char *template_fmt, return -EINVAL; } - /* copying is needed as strsep() modifies the original buffer */ - template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); - if (template_fmt_copy == NULL) - return -ENOMEM; - *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); if (*fields == NULL) { result = -ENOMEM; goto out; } - template_fmt_ptr = template_fmt_copy; - for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && - i < template_num_fields; i++) { - struct ima_template_field *f = lookup_template_field(c); + for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields; + i++, template_fmt_ptr += len + 1) { + char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1]; + struct ima_template_field *f; + + len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr; + if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) { + pr_err("Invalid field with length %d\n", len); + result = -EINVAL; + goto out; + } + memcpy(tmp_field_id, template_fmt_ptr, len); + tmp_field_id[len] = '\0'; + f = lookup_template_field(tmp_field_id); if (!f) { - pr_err("field '%s' not found\n", c); + pr_err("field '%s' not found\n", tmp_field_id); result = -ENOENT; goto out; } @@ -155,7 +160,6 @@ static int template_desc_init_fields(const char *template_fmt, kfree(*fields); *fields = NULL; } - kfree(template_fmt_copy); return result; } -- GitLab From 1bd7face74391ddfc568b3e638f156da1ed77aa6 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 13 Oct 2014 14:08:41 +0200 Subject: [PATCH 0223/9457] ima: allocate field pointers array on demand in template_desc_init_fields() The allocation of a field pointers array is moved at the end of template_desc_init_fields() and done only if the value of the 'fields' and 'num_fields' parameters is not NULL. For just validating a template format string, retrieved template field pointers are placed in a temporary array. Changelog: - v3: - do not check in this patch if 'fields' and 'num_fields' are NULL (suggested by Mimi Zohar) Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_template.c | 34 ++++++++++----------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index d93a58e603df..65117ba06809 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -117,8 +117,9 @@ static int template_desc_init_fields(const char *template_fmt, int *num_fields) { const char *template_fmt_ptr; + struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX]; int template_num_fields = template_fmt_size(template_fmt); - int i, len, result = 0; + int i, len; if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) { pr_err("format string '%s' contains too many fields\n", @@ -126,41 +127,32 @@ static int template_desc_init_fields(const char *template_fmt, return -EINVAL; } - *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); - if (*fields == NULL) { - result = -ENOMEM; - goto out; - } - for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields; i++, template_fmt_ptr += len + 1) { char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1]; - struct ima_template_field *f; len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr; if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) { pr_err("Invalid field with length %d\n", len); - result = -EINVAL; - goto out; + return -EINVAL; } memcpy(tmp_field_id, template_fmt_ptr, len); tmp_field_id[len] = '\0'; - f = lookup_template_field(tmp_field_id); - if (!f) { + found_fields[i] = lookup_template_field(tmp_field_id); + if (!found_fields[i]) { pr_err("field '%s' not found\n", tmp_field_id); - result = -ENOENT; - goto out; + return -ENOENT; } - (*fields)[i] = f; } + + *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); + if (*fields == NULL) + return -ENOMEM; + + memcpy(*fields, found_fields, i * sizeof(*fields)); *num_fields = i; -out: - if (result < 0) { - kfree(*fields); - *fields = NULL; - } - return result; + return 0; } struct ima_template_desc *ima_template_desc_current(void) -- GitLab From c2426d2ad5027397342107b7ff094aa9b234acb8 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 13 Oct 2014 14:08:42 +0200 Subject: [PATCH 0224/9457] ima: added support for new kernel cmdline parameter ima_template_fmt This patch allows users to provide a custom template format through the new kernel command line parameter 'ima_template_fmt'. If the supplied format is not valid, IMA uses the default template descriptor. Changelog: - v3: - added check for 'fields' and 'num_fields' in template_desc_init_fields() (suggested by Mimi Zohar) - v2: - using template_desc_init_fields() to validate a format string (Roberto Sassu) - updated documentation by stating that only the chosen template descriptor is initialized (Roberto Sassu) - v1: - simplified code of ima_template_fmt_setup() (Roberto Sassu, suggested by Mimi Zohar) Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar --- Documentation/kernel-parameters.txt | 4 +++ Documentation/security/IMA-templates.txt | 29 +++++++++--------- security/integrity/ima/ima_template.c | 39 +++++++++++++++++++++--- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 802a3fd9e485..06b2cd5739dd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1318,6 +1318,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Formats: { "ima" | "ima-ng" } Default: "ima-ng" + ima_template_fmt= + [IMA] Define a custom template format. + Format: { "field1|...|fieldN" } + ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage Format: Set the minimal file size for using asynchronous hash. diff --git a/Documentation/security/IMA-templates.txt b/Documentation/security/IMA-templates.txt index a4e102dddfea..839b5dad9226 100644 --- a/Documentation/security/IMA-templates.txt +++ b/Documentation/security/IMA-templates.txt @@ -27,25 +27,22 @@ Managing templates with these structures is very simple. To support a new data type, developers define the field identifier and implement two functions, init() and show(), respectively to generate and display measurement entries. Defining a new template descriptor requires -specifying the template format, a string of field identifiers separated -by the '|' character. While in the current implementation it is possible -to define new template descriptors only by adding their definition in the -template specific code (ima_template.c), in a future version it will be -possible to register a new template on a running kernel by supplying to IMA -the desired format string. In this version, IMA initializes at boot time -all defined template descriptors by translating the format into an array -of template fields structures taken from the set of the supported ones. +specifying the template format (a string of field identifiers separated +by the '|' character) through the 'ima_template_fmt' kernel command line +parameter. At boot time, IMA initializes the chosen template descriptor +by translating the format into an array of template fields structures taken +from the set of the supported ones. After the initialization step, IMA will call ima_alloc_init_template() (new function defined within the patches for the new template management mechanism) to generate a new measurement entry by using the template descriptor chosen through the kernel configuration or through the newly -introduced 'ima_template=' kernel command line parameter. It is during this -phase that the advantages of the new architecture are clearly shown: -the latter function will not contain specific code to handle a given template -but, instead, it simply calls the init() method of the template fields -associated to the chosen template descriptor and store the result (pointer -to allocated data and data length) in the measurement entry structure. +introduced 'ima_template' and 'ima_template_fmt' kernel command line parameters. +It is during this phase that the advantages of the new architecture are +clearly shown: the latter function will not contain specific code to handle +a given template but, instead, it simply calls the init() method of the template +fields associated to the chosen template descriptor and store the result +(pointer to allocated data and data length) in the measurement entry structure. The same mechanism is employed to display measurements entries. The functions ima[_ascii]_measurements_show() retrieve, for each entry, @@ -86,4 +83,6 @@ currently the following methods are supported: - select a template descriptor among those supported in the kernel configuration ('ima-ng' is the default choice); - specify a template descriptor name from the kernel command line through - the 'ima_template=' parameter. + the 'ima_template=' parameter; + - register a new template descriptor with custom format through the kernel + command line parameter 'ima_template_fmt='. diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 65117ba06809..0b7404ebfa80 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -24,6 +24,7 @@ static struct ima_template_desc defined_templates[] = { {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, {.name = "ima-ng", .fmt = "d-ng|n-ng"}, {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, + {.name = "", .fmt = ""}, /* placeholder for a custom format */ }; static struct ima_template_field supported_fields[] = { @@ -41,12 +42,18 @@ static struct ima_template_field supported_fields[] = { static struct ima_template_desc *ima_template; static struct ima_template_desc *lookup_template_desc(const char *name); +static int template_desc_init_fields(const char *template_fmt, + struct ima_template_field ***fields, + int *num_fields); static int __init ima_template_setup(char *str) { struct ima_template_desc *template_desc; int template_len = strlen(str); + if (ima_template) + return 1; + /* * Verify that a template with the supplied name exists. * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. @@ -73,6 +80,25 @@ static int __init ima_template_setup(char *str) } __setup("ima_template=", ima_template_setup); +static int __init ima_template_fmt_setup(char *str) +{ + int num_templates = ARRAY_SIZE(defined_templates); + + if (ima_template) + return 1; + + if (template_desc_init_fields(str, NULL, NULL) < 0) { + pr_err("format string '%s' not valid, using template %s\n", + str, CONFIG_IMA_DEFAULT_TEMPLATE); + return 1; + } + + defined_templates[num_templates - 1].fmt = str; + ima_template = defined_templates + num_templates - 1; + return 1; +} +__setup("ima_template_fmt=", ima_template_fmt_setup); + static struct ima_template_desc *lookup_template_desc(const char *name) { int i; @@ -146,12 +172,15 @@ static int template_desc_init_fields(const char *template_fmt, } } - *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); - if (*fields == NULL) - return -ENOMEM; + if (fields && num_fields) { + *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL); + if (*fields == NULL) + return -ENOMEM; + + memcpy(*fields, found_fields, i * sizeof(*fields)); + *num_fields = i; + } - memcpy(*fields, found_fields, i * sizeof(*fields)); - *num_fields = i; return 0; } -- GitLab From 6a40dc5ab5036722d8102ba7190dbd9d72982637 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 13 Oct 2014 11:37:18 +0530 Subject: [PATCH 0225/9457] ALSA: au88x0: added reference of vortex_t added a pointer of the vortex in the following functions : vortex_alsafmt_aspfmt vortex_Vort3D_InitializeSource a3dsrc_ZeroStateA3D so that we can have a reference of the vortex in the function. this reference of the vortex will actually be used in a later patch to convert the pr_* macro to dev_*. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0.h | 4 ++-- sound/pci/au88x0/au88x0_a3d.c | 6 +++--- sound/pci/au88x0/au88x0_core.c | 5 +++-- sound/pci/au88x0/au88x0_pcm.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index 466a5c8e8354..3a8fefefea77 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -243,7 +243,7 @@ static int vortex_core_init(vortex_t * card); static int vortex_core_shutdown(vortex_t * card); static void vortex_enable_int(vortex_t * card); static irqreturn_t vortex_interrupt(int irq, void *dev_id); -static int vortex_alsafmt_aspfmt(int alsafmt); +static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v); /* Connection stuff. */ static void vortex_connect_default(vortex_t * vortex, int en); @@ -278,7 +278,7 @@ static void vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix, static void vortex_Vort3D_enable(vortex_t * v); static void vortex_Vort3D_disable(vortex_t * v); static void vortex_Vort3D_connect(vortex_t * vortex, int en); -static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en); +static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v); #endif /* Driver stuff. */ diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c index 30f760e3d2c0..bc9cda3aa725 100644 --- a/sound/pci/au88x0/au88x0_a3d.c +++ b/sound/pci/au88x0/au88x0_a3d.c @@ -484,7 +484,7 @@ static void a3dsrc_ZeroState(a3dsrc_t * a) } /* Reset entire A3D engine */ -static void a3dsrc_ZeroStateA3D(a3dsrc_t * a) +static void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v) { int i, var, var2; @@ -601,7 +601,7 @@ static void vortex_Vort3D_enable(vortex_t *v) Vort3DRend_Initialize(v, XT_HEADPHONE); for (i = 0; i < NR_A3D; i++) { vortex_A3dSourceHw_Initialize(v, i % 4, i >> 2); - a3dsrc_ZeroStateA3D(&(v->a3d[0])); + a3dsrc_ZeroStateA3D(&v->a3d[0], v); } /* Register ALSA controls */ vortex_a3d_register_controls(v); @@ -676,7 +676,7 @@ static void vortex_Vort3D_connect(vortex_t * v, int en) } /* Initialize one single A3D source. */ -static void vortex_Vort3D_InitializeSource(a3dsrc_t * a, int en) +static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v) { if (a->vortex == NULL) { pr_warn diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 72e81286b70e..00e209617c52 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -2177,7 +2177,8 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, return -EBUSY; } /* (De)Initialize A3D hardware source. */ - vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en); + vortex_Vort3D_InitializeSource(&vortex->a3d[a3d], en, + vortex); } /* Make SPDIF out exclusive to "spdif" device when in use. */ if ((stream->type == VORTEX_PCM_SPDIF) && (en)) { @@ -2765,7 +2766,7 @@ static int vortex_core_shutdown(vortex_t * vortex) /* Alsa support. */ -static int vortex_alsafmt_aspfmt(int alsafmt) +static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v) { int fmt; diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 5adc6b92ffab..bdde182f1372 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -332,7 +332,7 @@ static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream) dir = 1; else dir = 0; - fmt = vortex_alsafmt_aspfmt(runtime->format); + fmt = vortex_alsafmt_aspfmt(runtime->format, chip); spin_lock_irq(&chip->lock); if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { vortex_adbdma_setmode(chip, dma, 1, dir, fmt, -- GitLab From 70c84418bf74f582e29906f1eeb19f2e9da53ddd Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 13 Oct 2014 11:37:19 +0530 Subject: [PATCH 0226/9457] ALSA: au88x0: pr_* replaced with dev_* pr_* macros replaced with dev_* as they are more preffered over pr_*. each file which had pr_* was reviewed manually and replaced with dev_*. here we have actually used the reference of the vortex which was added to some functions in the previous patch of this series. The prefix of the CARD_NAME and prefix of "vortex:" was also removed as the dev_* will print the device name. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0.c | 33 ++++++----- sound/pci/au88x0/au88x0_a3d.c | 15 ++--- sound/pci/au88x0/au88x0_core.c | 97 +++++++++++++++++--------------- sound/pci/au88x0/au88x0_eq.c | 3 +- sound/pci/au88x0/au88x0_game.c | 3 +- sound/pci/au88x0/au88x0_mpu401.c | 2 +- sound/pci/au88x0/au88x0_pcm.c | 6 +- sound/pci/au88x0/au88x0_synth.c | 17 +++--- 8 files changed, 94 insertions(+), 82 deletions(-) diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 21ce31f636bc..e9c3833f6d44 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -48,11 +48,10 @@ static void vortex_fix_latency(struct pci_dev *vortex) { int rc; if (!(rc = pci_write_config_byte(vortex, 0x40, 0xff))) { - pr_info( CARD_NAME - ": vortex latency is 0xff\n"); + dev_info(&vortex->dev, "vortex latency is 0xff\n"); } else { - pr_warn( CARD_NAME - ": could not set vortex latency: pci error 0x%x\n", rc); + dev_warn(&vortex->dev, + "could not set vortex latency: pci error 0x%x\n", rc); } } @@ -70,11 +69,10 @@ static void vortex_fix_agp_bridge(struct pci_dev *via) if (!(rc = pci_read_config_byte(via, 0x42, &value)) && ((value & 0x10) || !(rc = pci_write_config_byte(via, 0x42, value | 0x10)))) { - pr_info( CARD_NAME - ": bridge config is 0x%x\n", value | 0x10); + dev_info(&via->dev, "bridge config is 0x%x\n", value | 0x10); } else { - pr_warn( CARD_NAME - ": could not set vortex latency: pci error 0x%x\n", rc); + dev_warn(&via->dev, + "could not set vortex latency: pci error 0x%x\n", rc); } } @@ -97,7 +95,8 @@ static void snd_vortex_workaround(struct pci_dev *vortex, int fix) PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); } if (via) { - pr_info( CARD_NAME ": Activating latency workaround...\n"); + dev_info(&vortex->dev, + "Activating latency workaround...\n"); vortex_fix_latency(vortex); vortex_fix_agp_bridge(via); } @@ -153,7 +152,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) return err; if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 || pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) { - pr_err( "error to set DMA mask\n"); + dev_err(card->dev, "error to set DMA mask\n"); pci_disable_device(pci); return -ENXIO; } @@ -182,7 +181,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) chip->mmio = pci_ioremap_bar(pci, 0); if (!chip->mmio) { - pr_err( "MMIO area remap failed.\n"); + dev_err(card->dev, "MMIO area remap failed.\n"); err = -ENOMEM; goto ioremap_out; } @@ -191,14 +190,14 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) * This must be done before we do request_irq otherwise we can get spurious * interrupts that we do not handle properly and make a mess of things */ if ((err = vortex_core_init(chip)) != 0) { - pr_err( "hw core init failed\n"); + dev_err(card->dev, "hw core init failed\n"); goto core_out; } if ((err = request_irq(pci->irq, vortex_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) != 0) { - pr_err( "cannot grab irq\n"); + dev_err(card->dev, "cannot grab irq\n"); goto irq_out; } chip->irq = pci->irq; @@ -342,11 +341,11 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) chip->rev = pci->revision; #ifdef CHIP_AU8830 if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) { - pr_alert( - "vortex: The revision (%x) of your card has not been seen before.\n", + dev_alert(card->dev, + "The revision (%x) of your card has not been seen before.\n", chip->rev); - pr_alert( - "vortex: Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); + dev_alert(card->dev, + "Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n"); snd_card_free(card); err = -ENODEV; return err; diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c index bc9cda3aa725..ab0f87312911 100644 --- a/sound/pci/au88x0/au88x0_a3d.c +++ b/sound/pci/au88x0/au88x0_a3d.c @@ -489,7 +489,8 @@ static void a3dsrc_ZeroStateA3D(a3dsrc_t *a, vortex_t *v) int i, var, var2; if ((a->vortex) == NULL) { - pr_err( "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n"); + dev_err(v->card->dev, + "ZeroStateA3D: ERROR: a->vortex is NULL\n"); return; } @@ -628,15 +629,15 @@ static void vortex_Vort3D_connect(vortex_t * v, int en) v->mixxtlk[0] = vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); if (v->mixxtlk[0] < 0) { - pr_warn - ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n"); + dev_warn(v->card->dev, + "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); return; } v->mixxtlk[1] = vortex_adb_checkinout(v, v->fixed_res, en, VORTEX_RESOURCE_MIXIN); if (v->mixxtlk[1] < 0) { - pr_warn - ("vortex: vortex_Vort3D: ERROR: not enough free mixer resources.\n"); + dev_warn(v->card->dev, + "vortex_Vort3D: ERROR: not enough free mixer resources.\n"); return; } #endif @@ -679,8 +680,8 @@ static void vortex_Vort3D_connect(vortex_t * v, int en) static void vortex_Vort3D_InitializeSource(a3dsrc_t *a, int en, vortex_t *v) { if (a->vortex == NULL) { - pr_warn - ("vortex: Vort3D_InitializeSource: A3D source not initialized\n"); + dev_warn(v->card->dev, + "Vort3D_InitializeSource: A3D source not initialized\n"); return; } if (en) { diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 00e209617c52..4667c3232b7f 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -285,8 +285,8 @@ vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) temp = hwread(vortex->mmio, prev); //printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp); if ((++lifeboat) > 0xf) { - pr_err( - "vortex_mixer_addWTD: lifeboat overflow\n"); + dev_err(vortex->card->dev, + "vortex_mixer_addWTD: lifeboat overflow\n"); return 0; } } @@ -303,7 +303,7 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) eax = hwread(vortex->mmio, VORTEX_MIXER_SR); if (((1 << ch) & eax) == 0) { - pr_err( "mix ALARM %x\n", eax); + dev_err(vortex->card->dev, "mix ALARM %x\n", eax); return 0; } ebp = VORTEX_MIXER_CHNBASE + (ch << 2); @@ -324,8 +324,8 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) //printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); while ((edx & 0xf) != mix) { if ((esi) > 0xf) { - pr_err( - "vortex: mixdelWTD: error lifeboat overflow\n"); + dev_err(vortex->card->dev, + "mixdelWTD: error lifeboat overflow\n"); return 0; } esp14 = ebx; @@ -492,7 +492,7 @@ vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio) hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio); temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2)); if ((++lifeboat) > 0x9) { - pr_err( "Vortex: Src cvr fail\n"); + dev_err(vortex->card->dev, "Src cvr fail\n"); break; } } @@ -684,8 +684,8 @@ vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch) temp = hwread(vortex->mmio, prev); //printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp); if ((++lifeboat) > 0xf) { - pr_err( - "vortex_src_addWTD: lifeboat overflow\n"); + dev_err(vortex->card->dev, + "vortex_src_addWTD: lifeboat overflow\n"); return 0; } } @@ -703,7 +703,7 @@ vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch) eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR); if (((1 << ch) & eax) == 0) { - pr_err( "src alarm\n"); + dev_err(vortex->card->dev, "src alarm\n"); return 0; } ebp = VORTEX_SRC_CHNBASE + (ch << 2); @@ -724,8 +724,8 @@ vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch) //printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src); while ((edx & 0xf) != src) { if ((esi) > 0xf) { - pr_warn - ("vortex: srcdelWTD: error, lifeboat overflow\n"); + dev_warn(vortex->card->dev, + "srcdelWTD: error, lifeboat overflow\n"); return 0; } esp14 = ebx; @@ -819,8 +819,8 @@ vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority, do { temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)); if (lifeboat++ > 0xbb8) { - pr_err( - "Vortex: vortex_fifo_setadbctrl fail\n"); + dev_err(vortex->card->dev, + "vortex_fifo_setadbctrl fail\n"); break; } } @@ -915,7 +915,8 @@ vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority, do { temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)); if (lifeboat++ > 0xbb8) { - pr_err( "Vortex: vortex_fifo_setwtctrl fail\n"); + dev_err(vortex->card->dev, + "vortex_fifo_setwtctrl fail\n"); break; } } @@ -1042,7 +1043,7 @@ static void vortex_fifo_init(vortex_t * vortex) for (x = NR_ADB - 1; x >= 0; x--) { hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) - pr_err( "bad adb fifo reset!"); + dev_err(vortex->card->dev, "bad adb fifo reset!"); vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); addr -= 4; } @@ -1053,9 +1054,9 @@ static void vortex_fifo_init(vortex_t * vortex) for (x = NR_WT - 1; x >= 0; x--) { hwwrite(vortex->mmio, addr, FIFO_U0); if (hwread(vortex->mmio, addr) != FIFO_U0) - pr_err( - "bad wt fifo reset (0x%08x, 0x%08x)!\n", - addr, hwread(vortex->mmio, addr)); + dev_err(vortex->card->dev, + "bad wt fifo reset (0x%08x, 0x%08x)!\n", + addr, hwread(vortex->mmio, addr)); vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); addr -= 4; } @@ -1213,8 +1214,9 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma) if (dma->period_virt >= dma->nr_periods) dma->period_virt -= dma->nr_periods; if (delta != 1) - pr_info( "vortex: %d virt=%d, real=%d, delta=%d\n", - adbdma, dma->period_virt, dma->period_real, delta); + dev_info(vortex->card->dev, + "%d virt=%d, real=%d, delta=%d\n", + adbdma, dma->period_virt, dma->period_real, delta); return delta; } @@ -1482,8 +1484,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma) dma->period_real = page; if (delta != 1) - pr_warn( "vortex: wt virt = %d, delta = %d\n", - dma->period_virt, delta); + dev_warn(vortex->card->dev, "wt virt = %d, delta = %d\n", + dma->period_virt, delta); return delta; } @@ -1667,9 +1669,9 @@ vortex_adb_addroutes(vortex_t * vortex, unsigned char channel, hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK; if ((lifeboat++) > ADB_MASK) { - pr_err( - "vortex_adb_addroutes: unending route! 0x%x\n", - *route); + dev_err(vortex->card->dev, + "vortex_adb_addroutes: unending route! 0x%x\n", + *route); return; } } @@ -1703,9 +1705,9 @@ vortex_adb_delroutes(vortex_t * vortex, unsigned char channel, hwread(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK; if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) { - pr_err( - "vortex_adb_delroutes: route not found! 0x%x\n", - route0); + dev_err(vortex->card->dev, + "vortex_adb_delroutes: route not found! 0x%x\n", + route0); return; } } @@ -2045,7 +2047,9 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) } } } - pr_err( "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype); + dev_err(vortex->card->dev, + "FATAL: ResManager: resource type %d exhausted.\n", + restype); return -ENOMEM; } @@ -2173,7 +2177,8 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, memset(stream->resources, 0, sizeof(unsigned char) * VORTEX_RESOURCE_LAST); - pr_err( "vortex: out of A3D sources. Sorry\n"); + dev_err(vortex->card->dev, + "out of A3D sources. Sorry\n"); return -EBUSY; } /* (De)Initialize A3D hardware source. */ @@ -2422,7 +2427,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) hwread(vortex->mmio, VORTEX_IRQ_SOURCE); // Is at least one IRQ flag set? if (source == 0) { - pr_err( "vortex: missing irq source\n"); + dev_err(vortex->card->dev, "missing irq source\n"); return IRQ_NONE; } @@ -2430,19 +2435,19 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) // Attend every interrupt source. if (unlikely(source & IRQ_ERR_MASK)) { if (source & IRQ_FATAL) { - pr_err( "vortex: IRQ fatal error\n"); + dev_err(vortex->card->dev, "IRQ fatal error\n"); } if (source & IRQ_PARITY) { - pr_err( "vortex: IRQ parity error\n"); + dev_err(vortex->card->dev, "IRQ parity error\n"); } if (source & IRQ_REG) { - pr_err( "vortex: IRQ reg error\n"); + dev_err(vortex->card->dev, "IRQ reg error\n"); } if (source & IRQ_FIFO) { - pr_err( "vortex: IRQ fifo error\n"); + dev_err(vortex->card->dev, "IRQ fifo error\n"); } if (source & IRQ_DMA) { - pr_err( "vortex: IRQ dma error\n"); + dev_err(vortex->card->dev, "IRQ dma error\n"); } handled = 1; } @@ -2490,7 +2495,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) } if (!handled) { - pr_err( "vortex: unknown irq source %x\n", source); + dev_err(vortex->card->dev, "unknown irq source %x\n", source); } return IRQ_RETVAL(handled); } @@ -2547,7 +2552,7 @@ vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { udelay(100); if (lifeboat++ > POLL_COUNT) { - pr_err( "vortex: ac97 codec stuck busy\n"); + dev_err(card->card->dev, "ac97 codec stuck busy\n"); return; } } @@ -2573,7 +2578,7 @@ static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { udelay(100); if (lifeboat++ > POLL_COUNT) { - pr_err( "vortex: ac97 codec stuck busy\n"); + dev_err(card->card->dev, "ac97 codec stuck busy\n"); return 0xffff; } } @@ -2587,7 +2592,8 @@ static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short udelay(100); data = hwread(card->mmio, VORTEX_CODEC_IO); if (lifeboat++ > POLL_COUNT) { - pr_err( "vortex: ac97 address never arrived\n"); + dev_err(card->card->dev, + "ac97 address never arrived\n"); return 0xffff; } } while ((data & VORTEX_CODEC_ADDMASK) != @@ -2684,7 +2690,7 @@ static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode) static int vortex_core_init(vortex_t *vortex) { - pr_info( "Vortex: init.... "); + dev_info(vortex->card->dev, "init started\n"); /* Hardware Init. */ hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff); msleep(5); @@ -2729,7 +2735,7 @@ static int vortex_core_init(vortex_t *vortex) //vortex_enable_timer_int(vortex); //vortex_disable_timer_int(vortex); - pr_info( "done.\n"); + dev_info(vortex->card->dev, "init.... done.\n"); spin_lock_init(&vortex->lock); return 0; @@ -2738,7 +2744,7 @@ static int vortex_core_init(vortex_t *vortex) static int vortex_core_shutdown(vortex_t * vortex) { - pr_info( "Vortex: shutdown..."); + dev_info(vortex->card->dev, "shutdown started\n"); #ifndef CHIP_AU8820 vortex_eq_free(vortex); vortex_Vort3D_disable(vortex); @@ -2760,7 +2766,7 @@ static int vortex_core_shutdown(vortex_t * vortex) msleep(5); hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff); - pr_info( "done.\n"); + dev_info(vortex->card->dev, "shutdown.... done.\n"); return 0; } @@ -2794,7 +2800,8 @@ static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v) break; default: fmt = 0x8; - pr_err( "vortex: format unsupported %d\n", alsafmt); + dev_err(v->card->dev, + "format unsupported %d\n", alsafmt); break; } return fmt; diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index 9404ba73eaf6..9585c5c63b96 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c @@ -845,7 +845,8 @@ snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); if (count != 20) { - pr_err( "vortex: peak count error 20 != %d \n", count); + dev_err(vortex->card->dev, + "peak count error 20 != %d\n", count); return -1; } for (i = 0; i < 20; i++) diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c index 72daf6cf8169..151815b857a0 100644 --- a/sound/pci/au88x0/au88x0_game.c +++ b/sound/pci/au88x0/au88x0_game.c @@ -98,7 +98,8 @@ static int vortex_gameport_register(vortex_t *vortex) vortex->gameport = gp = gameport_allocate_port(); if (!gp) { - pr_err( "vortex: cannot allocate memory for gameport\n"); + dev_err(vortex->card->dev, + "cannot allocate memory for gameport\n"); return -ENOMEM; } diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 328c1943c0c3..1025e55ca854 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c @@ -73,7 +73,7 @@ static int snd_vortex_midi(vortex_t *vortex) /* Check if anything is OK. */ temp = hwread(vortex->mmio, VORTEX_MIDI_DATA); if (temp != MPU401_ACK /*0xfe */ ) { - pr_err( "midi port doesn't acknowledge!\n"); + dev_err(vortex->card->dev, "midi port doesn't acknowledge!\n"); return -ENODEV; } /* Enable MPU401 interrupts. */ diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index bdde182f1372..a6d6d8d0867a 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -227,7 +227,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) { - pr_err( "Vortex: pcm page alloc failed!\n"); + dev_err(chip->card->dev, "Vortex: pcm page alloc failed!\n"); return err; } /* @@ -371,7 +371,7 @@ static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd) } #ifndef CHIP_AU8810 else { - pr_info( "vortex: wt start %d\n", dma); + dev_info(chip->card->dev, "wt start %d\n", dma); vortex_wtdma_startfifo(chip, dma); } #endif @@ -384,7 +384,7 @@ static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd) vortex_adbdma_stopfifo(chip, dma); #ifndef CHIP_AU8810 else { - pr_info( "vortex: wt stop %d\n", dma); + dev_info(chip->card->dev, "wt stop %d\n", dma); vortex_wtdma_stopfifo(chip, dma); } #endif diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index f094bac24291..78e12f4796f3 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c @@ -90,7 +90,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); temp = hwread(vortex->mmio, WT_PARM(wt, 3)); - pr_debug( "vortex: WT PARM3: %x\n", temp); + dev_dbg(vortex->card->dev, "WT PARM3: %x\n", temp); //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); @@ -98,7 +98,8 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); - pr_debug( "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt))); + dev_dbg(vortex->card->dev, "WT GMODE: %x\n", + hwread(vortex->mmio, WT_GMODE(wt))); hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); @@ -106,7 +107,8 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch) voice->parm0 = voice->parm1 = 0xcfb23e2f; hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); - pr_debug( "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt))); + dev_dbg(vortex->card->dev, "WT GMODE 2 : %x\n", + hwread(vortex->mmio, WT_GMODE(wt))); return 0; } @@ -196,14 +198,15 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) { if (wt >= (NR_WT / NR_WT_PB)) { - pr_warn - ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n", - reg, wt); + dev_warn(vortex->card->dev, + "WT SetReg: bank out of range. reg=0x%x, wt=%d\n", + reg, wt); return 0; } } else { if (wt >= NR_WT) { - pr_err( "vortex: WT SetReg: voice out of range\n"); + dev_err(vortex->card->dev, + "WT SetReg: voice out of range\n"); return 0; } } -- GitLab From 54841a06c54eb55918948c12ab9b5f02cacb6ab3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Oct 2014 14:00:16 +0200 Subject: [PATCH 0227/9457] ALSA: seq: Use atomic ops for autoload refcount ... just to robustify for races. Signed-off-by: Takashi Iwai --- sound/core/seq/seq_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 91a786a783e1..775ea9390110 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -127,15 +127,15 @@ static void snd_seq_device_info(struct snd_info_entry *entry, #ifdef CONFIG_MODULES /* avoid auto-loading during module_init() */ -static int snd_seq_in_init; +static atomic_t snd_seq_in_init = ATOMIC_INIT(0); void snd_seq_autoload_lock(void) { - snd_seq_in_init++; + atomic_inc(&snd_seq_in_init); } void snd_seq_autoload_unlock(void) { - snd_seq_in_init--; + atomic_dec(&snd_seq_in_init); } #endif @@ -147,7 +147,7 @@ void snd_seq_device_load_drivers(void) /* Calling request_module during module_init() * may cause blocking. */ - if (snd_seq_in_init) + if (atomic_read(&snd_seq_in_init)) return; mutex_lock(&ops_mutex); -- GitLab From b615bbbff1c4d6fcd13007e75d75f6510aeb3808 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Wed, 13 Aug 2014 09:04:49 -0700 Subject: [PATCH 0228/9457] arm: use generic fixmap.h ARM is different from other architectures in that fixmap pages are indexed with a positive offset from FIXADDR_START. Other architectures index with a negative offset from FIXADDR_TOP. In order to use the generic fixmap.h definitions, this patch redefines FIXADDR_TOP to be inclusive of the useable range. That is, FIXADDR_TOP is the virtual address of the topmost fixed page. The newly defined FIXADDR_END is the first virtual address past the fixed mappings. Signed-off-by: Mark Salter Reviewed-by: Doug Anderson [kees: update for a05e54c103b0 ("ARM: 8031/2: change fixmap ...")] Signed-off-by: Kees Cook Cc: Laura Abbott Cc: Rob Herring Acked-by: Nicolas Pitre --- arch/arm/include/asm/fixmap.h | 27 +++++++++------------------ arch/arm/mm/init.c | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 74124b0d0d79..a7add6f9315d 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -2,27 +2,18 @@ #define _ASM_FIXMAP_H #define FIXADDR_START 0xffc00000UL -#define FIXADDR_TOP 0xffe00000UL -#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) +#define FIXADDR_END 0xffe00000UL +#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE) -#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) +#include -#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) +enum fixed_addresses { + FIX_KMAP_BEGIN, + FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, -extern void __this_fixmap_does_not_exist(void); + __end_of_fixed_addresses +}; -static inline unsigned long fix_to_virt(const unsigned int idx) -{ - if (idx >= FIX_KMAP_NR_PTES) - __this_fixmap_does_not_exist(); - return __fix_to_virt(idx); -} - -static inline unsigned int virt_to_fix(const unsigned long vaddr) -{ - BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); - return __virt_to_fix(vaddr); -} +#include #endif diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 659c75d808dc..ad82c05bfc3a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -570,7 +570,7 @@ void __init mem_init(void) MLK(DTCM_OFFSET, (unsigned long) dtcm_end), MLK(ITCM_OFFSET, (unsigned long) itcm_end), #endif - MLK(FIXADDR_START, FIXADDR_TOP), + MLK(FIXADDR_START, FIXADDR_END), MLM(VMALLOC_START, VMALLOC_END), MLM(PAGE_OFFSET, (unsigned long)high_memory), #ifdef CONFIG_HIGHMEM -- GitLab From 836a24183273e9db1c092246bd8e306b297d9917 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 2 Jul 2014 02:01:15 -0500 Subject: [PATCH 0229/9457] ARM: expand fixmap region to 3MB With commit a05e54c103b0 ("ARM: 8031/2: change fixmap mapping region to support 32 CPUs"), the fixmap region was expanded to 2MB, but it precluded any other uses of the fixmap region. In order to support other uses the fixmap region needs to be expanded beyond 2MB. Fortunately, the adjacent 1MB range 0xffe00000-0xfff00000 is availabe. Remove fixmap_page_table ptr and lookup the page table via the virtual address so that the fixmap region can span more that one pmd. The 2nd pmd is already created since it is shared with the vector page. Signed-off-by: Rob Herring [kees: fixed CONFIG_DEBUG_HIGHMEM get_fixmap() calls] [kees: moved pte allocation outside of CONFIG_HIGHMEM] Signed-off-by: Kees Cook Acked-by: Nicolas Pitre --- Documentation/arm/memory.txt | 2 +- arch/arm/include/asm/fixmap.h | 2 +- arch/arm/mm/highmem.c | 15 ++++++++------- arch/arm/mm/mmu.c | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt index 38dc06d0a791..4178ebda6e66 100644 --- a/Documentation/arm/memory.txt +++ b/Documentation/arm/memory.txt @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with fffe0000 fffe7fff ITCM mapping area for platforms with ITCM mounted inside the CPU. -ffc00000 ffdfffff Fixmap mapping region. Addresses provided +ffc00000 ffefffff Fixmap mapping region. Addresses provided by fix_to_virt() will be located here. fee00000 feffffff Mapping of PCI I/O space. This is a static diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index a7add6f9315d..d984ca69ce19 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -2,7 +2,7 @@ #define _ASM_FIXMAP_H #define FIXADDR_START 0xffc00000UL -#define FIXADDR_END 0xffe00000UL +#define FIXADDR_END 0xfff00000UL #define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE) #include diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 45aeaaca9052..81061987ac45 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -18,19 +18,20 @@ #include #include "mm.h" -pte_t *fixmap_page_table; - static inline void set_fixmap_pte(int idx, pte_t pte) { unsigned long vaddr = __fix_to_virt(idx); - set_pte_ext(fixmap_page_table + idx, pte, 0); + pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr); + + set_pte_ext(ptep, pte, 0); local_flush_tlb_kernel_page(vaddr); } static inline pte_t get_fixmap_pte(unsigned long vaddr) { - unsigned long idx = __virt_to_fix(vaddr); - return *(fixmap_page_table + idx); + pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr); + + return *ptep; } void *kmap(struct page *page) @@ -84,7 +85,7 @@ void *kmap_atomic(struct page *page) * With debugging enabled, kunmap_atomic forces that entry to 0. * Make sure it was indeed properly unmapped. */ - BUG_ON(!pte_none(*(fixmap_page_table + idx))); + BUG_ON(!pte_none(get_fixmap_pte(vaddr))); #endif /* * When debugging is off, kunmap_atomic leaves the previous mapping @@ -134,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn) idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(fixmap_page_table + idx))); + BUG_ON(!pte_none(get_fixmap_pte(vaddr))); #endif set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 8348ed6b2efe..7fa0966cd15f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1326,10 +1326,10 @@ static void __init kmap_init(void) #ifdef CONFIG_HIGHMEM pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE), PKMAP_BASE, _PAGE_KERNEL_TABLE); - - fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START), - FIXADDR_START, _PAGE_KERNEL_TABLE); #endif + + early_pte_alloc(pmd_off_k(FIXADDR_START), FIXADDR_START, + _PAGE_KERNEL_TABLE); } static void __init map_lowmem(void) -- GitLab From 99b4ac9afce4129323b5b4c7002a942a9489914c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 4 Apr 2014 23:27:49 +0200 Subject: [PATCH 0230/9457] arm: fixmap: implement __set_fixmap() This is used from set_fixmap() and clear_fixmap() via asm-generic/fixmap.h. Also makes sure that the fixmap allocation fits into the expected range. Based on patch by Rabin Vincent. Signed-off-by: Kees Cook Cc: Rabin Vincent Acked-by: Nicolas Pitre --- arch/arm/include/asm/fixmap.h | 2 ++ arch/arm/mm/mmu.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index d984ca69ce19..714606f70425 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -14,6 +14,8 @@ enum fixed_addresses { __end_of_fixed_addresses }; +void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot); + #include #endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 7fa0966cd15f..bdf5c94f7c36 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -392,6 +393,29 @@ SET_MEMORY_FN(rw, pte_set_rw) SET_MEMORY_FN(x, pte_set_x) SET_MEMORY_FN(nx, pte_set_nx) +/* + * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range(). + * As a result, this can only be called with preemption disabled, as under + * stop_machine(). + */ +void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) +{ + unsigned long vaddr = __fix_to_virt(idx); + pte_t *pte = pte_offset_kernel(pmd_off_k(vaddr), vaddr); + + /* Make sure fixmap region does not exceed available allocation. */ + BUILD_BUG_ON(FIXADDR_START + (__end_of_fixed_addresses * PAGE_SIZE) > + FIXADDR_END); + BUG_ON(idx >= __end_of_fixed_addresses); + + if (pgprot_val(prot)) + set_pte_at(NULL, vaddr, pte, + pfn_pte(phys >> PAGE_SHIFT, prot)); + else + pte_clear(NULL, vaddr, pte); + local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); +} + /* * Adjust the PMD section entries according to the CPU in use. */ -- GitLab From ab0615e2d6fb074764a3e4d05f1326fa2fdb4627 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Thu, 24 Apr 2014 23:28:57 +0200 Subject: [PATCH 0231/9457] arm: use fixmap for text patching when text is RO Use fixmaps for text patching when the kernel text is read-only, inspired by x86. This makes jump labels and kprobes work with the currently available CONFIG_DEBUG_SET_MODULE_RONX and the upcoming CONFIG_DEBUG_RODATA options. Signed-off-by: Rabin Vincent [kees: fixed up for merge with "arm: use generic fixmap.h"] [kees: added parse acquire/release annotations to pass C=1 builds] [kees: always use stop_machine to keep TLB flushing local] Signed-off-by: Kees Cook Acked-by: Nicolas Pitre --- arch/arm/include/asm/fixmap.h | 4 ++ arch/arm/kernel/jump_label.c | 2 +- arch/arm/kernel/patch.c | 92 +++++++++++++++++++++++++++-------- arch/arm/kernel/patch.h | 12 ++++- 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 714606f70425..0415eae1df27 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -11,6 +11,10 @@ enum fixed_addresses { FIX_KMAP_BEGIN, FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, + /* Support writing RO kernel text via kprobes, jump labels, etc. */ + FIX_TEXT_POKE0, + FIX_TEXT_POKE1, + __end_of_fixed_addresses }; diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c index 4ce4f789446d..afeeb9ea6f43 100644 --- a/arch/arm/kernel/jump_label.c +++ b/arch/arm/kernel/jump_label.c @@ -19,7 +19,7 @@ static void __arch_jump_label_transform(struct jump_entry *entry, insn = arm_gen_nop(); if (is_static) - __patch_text(addr, insn); + __patch_text_early(addr, insn); else patch_text(addr, insn); } diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c index 07314af47733..5038960e3c55 100644 --- a/arch/arm/kernel/patch.c +++ b/arch/arm/kernel/patch.c @@ -1,8 +1,11 @@ #include +#include #include +#include #include #include +#include #include #include @@ -13,21 +16,77 @@ struct patch { unsigned int insn; }; -void __kprobes __patch_text(void *addr, unsigned int insn) +static DEFINE_SPINLOCK(patch_lock); + +static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags) + __acquires(&patch_lock) +{ + unsigned int uintaddr = (uintptr_t) addr; + bool module = !core_kernel_text(uintaddr); + struct page *page; + + if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX)) + page = vmalloc_to_page(addr); + else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA)) + page = virt_to_page(addr); + else + return addr; + + if (flags) + spin_lock_irqsave(&patch_lock, *flags); + else + __acquire(&patch_lock); + + set_fixmap(fixmap, page_to_phys(page)); + + return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK)); +} + +static void __kprobes patch_unmap(int fixmap, unsigned long *flags) + __releases(&patch_lock) +{ + clear_fixmap(fixmap); + + if (flags) + spin_unlock_irqrestore(&patch_lock, *flags); + else + __release(&patch_lock); +} + +void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap) { bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL); + unsigned int uintaddr = (uintptr_t) addr; + bool twopage = false; + unsigned long flags; + void *waddr = addr; int size; + if (remap) + waddr = patch_map(addr, FIX_TEXT_POKE0, &flags); + else + __acquire(&patch_lock); + if (thumb2 && __opcode_is_thumb16(insn)) { - *(u16 *)addr = __opcode_to_mem_thumb16(insn); + *(u16 *)waddr = __opcode_to_mem_thumb16(insn); size = sizeof(u16); - } else if (thumb2 && ((uintptr_t)addr & 2)) { + } else if (thumb2 && (uintaddr & 2)) { u16 first = __opcode_thumb32_first(insn); u16 second = __opcode_thumb32_second(insn); - u16 *addrh = addr; + u16 *addrh0 = waddr; + u16 *addrh1 = waddr + 2; + + twopage = (uintaddr & ~PAGE_MASK) == PAGE_SIZE - 2; + if (twopage && remap) + addrh1 = patch_map(addr + 2, FIX_TEXT_POKE1, NULL); + + *addrh0 = __opcode_to_mem_thumb16(first); + *addrh1 = __opcode_to_mem_thumb16(second); - addrh[0] = __opcode_to_mem_thumb16(first); - addrh[1] = __opcode_to_mem_thumb16(second); + if (twopage && addrh1 != addr + 2) { + flush_kernel_vmap_range(addrh1, 2); + patch_unmap(FIX_TEXT_POKE1, NULL); + } size = sizeof(u32); } else { @@ -36,10 +95,16 @@ void __kprobes __patch_text(void *addr, unsigned int insn) else insn = __opcode_to_mem_arm(insn); - *(u32 *)addr = insn; + *(u32 *)waddr = insn; size = sizeof(u32); } + if (waddr != addr) { + flush_kernel_vmap_range(waddr, twopage ? size / 2 : size); + patch_unmap(FIX_TEXT_POKE0, &flags); + } else + __release(&patch_lock); + flush_icache_range((uintptr_t)(addr), (uintptr_t)(addr) + size); } @@ -60,16 +125,5 @@ void __kprobes patch_text(void *addr, unsigned int insn) .insn = insn, }; - if (cache_ops_need_broadcast()) { - stop_machine(patch_text_stop_machine, &patch, cpu_online_mask); - } else { - bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL) - && __opcode_is_thumb32(insn) - && ((uintptr_t)addr & 2); - - if (straddles_word) - stop_machine(patch_text_stop_machine, &patch, NULL); - else - __patch_text(addr, insn); - } + stop_machine(patch_text_stop_machine, &patch, NULL); } diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h index b4731f2dac38..77e054c2f6cd 100644 --- a/arch/arm/kernel/patch.h +++ b/arch/arm/kernel/patch.h @@ -2,6 +2,16 @@ #define _ARM_KERNEL_PATCH_H void patch_text(void *addr, unsigned int insn); -void __patch_text(void *addr, unsigned int insn); +void __patch_text_real(void *addr, unsigned int insn, bool remap); + +static inline void __patch_text(void *addr, unsigned int insn) +{ + __patch_text_real(addr, insn, true); +} + +static inline void __patch_text_early(void *addr, unsigned int insn) +{ + __patch_text_real(addr, insn, false); +} #endif -- GitLab From 42d720d1731a9d7035c2812437c35e271ec4dd78 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Mon, 12 May 2014 10:31:56 +0100 Subject: [PATCH 0232/9457] ARM: kexec: Make .text R/W in machine_kexec With the introduction of Kees Cook's patch to make the kernel .text read-only the existing method by which kexec works got broken since it directly pokes some values in the template code, which resides in the .text section. The current patch changes the way those values are inserted so that poking .text section occurs only in machine_kexec (e.g when we are about to nuke the old kernel and are beyond the point of return). This allows to use set_kernel_text_rw() to directly patch the values in the .text section. I had already sent a patch which achieved this but it was significantly more complicated, so this is a cleaner/straight-forward approach. Signed-off-by: Nikolay Borisov Acked-by: Will Deacon [kees: collapsed kexec_boot_atags (will.daecon)] [kees: for bisectability, moved set_kernel_text_rw() to RODATA patch] Signed-off-by: Kees Cook Acked-by: Nicolas Pitre --- arch/arm/kernel/machine_kexec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8cf0996aa1a8..8f75250cbe30 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -29,6 +29,7 @@ extern unsigned long kexec_boot_atags; static atomic_t waiting_for_crash_ipi; +static unsigned long dt_mem; /* * Provide a dummy crash_notes definition while crash dump arrives to arm. * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. @@ -64,7 +65,7 @@ int machine_kexec_prepare(struct kimage *image) return err; if (be32_to_cpu(header) == OF_DT_HEADER) - kexec_boot_atags = current_segment->mem; + dt_mem = current_segment->mem; } return 0; } @@ -166,9 +167,8 @@ void machine_kexec(struct kimage *image) kexec_start_address = image->start; kexec_indirection_page = page_list; kexec_mach_type = machine_arch_type; - if (!kexec_boot_atags) - kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; - + kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET + + KEXEC_ARM_ATAGS_OFFSET; /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, -- GitLab From 23a4e4050ba9c98ab67db0980a9fb20e5096d9ea Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 22 Apr 2014 15:14:51 -0700 Subject: [PATCH 0233/9457] arm: kgdb: Handle read-only text / modules Handle the case where someone has set the text segment of the kernel as read-only by using the newly introduced "patch" mechanism. Signed-off-by: Doug Anderson [kees: switched structure size check to BUILD_BUG_ON (sboyd)] Signed-off-by: Kees Cook Acked-by: Nicolas Pitre --- arch/arm/kernel/Makefile | 2 +- arch/arm/kernel/kgdb.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 38ddd9f83d0e..70b730766330 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -67,7 +67,7 @@ test-kprobes-objs += kprobes-test-arm.o endif obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o -obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_KGDB) += kgdb.o patch.o obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_HAVE_TCM) += tcm.o obj-$(CONFIG_OF) += devtree.o diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index a74b53c1b7df..07db2f8a1b45 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -12,8 +12,12 @@ #include #include #include +#include + #include +#include "patch.h" + struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { { "r0", 4, offsetof(struct pt_regs, ARM_r0)}, @@ -244,6 +248,31 @@ void kgdb_arch_exit(void) unregister_die_notifier(&kgdb_notifier); } +int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) +{ + int err; + + /* patch_text() only supports int-sized breakpoints */ + BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE); + + err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, + BREAK_INSTR_SIZE); + if (err) + return err; + + patch_text((void *)bpt->bpt_addr, + *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr); + + return err; +} + +int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) +{ + patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr); + + return 0; +} + /* * Register our undef instruction hooks with ARM undef core. * We regsiter a hook specifically looking for the KGB break inst -- GitLab From 1e6b48116a95046ec51f3d40f83aff8b006674d7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 3 Apr 2014 17:28:11 -0700 Subject: [PATCH 0234/9457] ARM: mm: allow non-text sections to be non-executable Adds CONFIG_ARM_KERNMEM_PERMS to separate the kernel memory regions into section-sized areas that can have different permisions. Performs the NX permission changes during free_initmem, so that init memory can be reclaimed. This uses section size instead of PMD size to reduce memory lost to padding on non-LPAE systems. Based on work by Brad Spengler, Larry Bassel, and Laura Abbott. Signed-off-by: Kees Cook Tested-by: Laura Abbott Acked-by: Nicolas Pitre --- arch/arm/kernel/vmlinux.lds.S | 16 ++++++ arch/arm/mm/Kconfig | 9 +++ arch/arm/mm/init.c | 101 +++++++++++++++++++++++++++++++++- arch/arm/mm/mmu.c | 9 ++- 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 6f57cb94367f..18fd68a295ea 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -8,6 +8,9 @@ #include #include #include +#ifdef CONFIG_ARM_KERNMEM_PERMS +#include +#endif #define PROC_INFO \ . = ALIGN(4); \ @@ -90,6 +93,11 @@ SECTIONS _text = .; HEAD_TEXT } + +#ifdef CONFIG_ARM_KERNMEM_PERMS + . = ALIGN(1< #include #include +#include #include #include @@ -615,7 +616,99 @@ void __init mem_init(void) } } -void free_initmem(void) +#ifdef CONFIG_ARM_KERNMEM_PERMS +struct section_perm { + unsigned long start; + unsigned long end; + pmdval_t mask; + pmdval_t prot; +}; + +struct section_perm nx_perms[] = { + /* Make pages tables, etc before _stext RW (set NX). */ + { + .start = PAGE_OFFSET, + .end = (unsigned long)_stext, + .mask = ~PMD_SECT_XN, + .prot = PMD_SECT_XN, + }, + /* Make init RW (set NX). */ + { + .start = (unsigned long)__init_begin, + .end = (unsigned long)_sdata, + .mask = ~PMD_SECT_XN, + .prot = PMD_SECT_XN, + }, +}; + +/* + * Updates section permissions only for the current mm (sections are + * copied into each mm). During startup, this is the init_mm. Is only + * safe to be called with preemption disabled, as under stop_machine(). + */ +static inline void section_update(unsigned long addr, pmdval_t mask, + pmdval_t prot) +{ + struct mm_struct *mm; + pmd_t *pmd; + + mm = current->active_mm; + pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr); + +#ifdef CONFIG_ARM_LPAE + pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot); +#else + if (addr & SECTION_SIZE) + pmd[1] = __pmd((pmd_val(pmd[1]) & mask) | prot); + else + pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot); +#endif + flush_pmd_entry(pmd); + local_flush_tlb_kernel_range(addr, addr + SECTION_SIZE); +} + +/* Make sure extended page tables are in use. */ +static inline bool arch_has_strict_perms(void) +{ + if (cpu_architecture() < CPU_ARCH_ARMv6) + return false; + + return !!(get_cr() & CR_XP); +} + +#define set_section_perms(perms, field) { \ + size_t i; \ + unsigned long addr; \ + \ + if (!arch_has_strict_perms()) \ + return; \ + \ + for (i = 0; i < ARRAY_SIZE(perms); i++) { \ + if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || \ + !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { \ + pr_err("BUG: section %lx-%lx not aligned to %lx\n", \ + perms[i].start, perms[i].end, \ + SECTION_SIZE); \ + continue; \ + } \ + \ + for (addr = perms[i].start; \ + addr < perms[i].end; \ + addr += SECTION_SIZE) \ + section_update(addr, perms[i].mask, \ + perms[i].field); \ + } \ +} + +static inline void fix_kernmem_perms(void) +{ + set_section_perms(nx_perms, prot); +} +#else +static inline void fix_kernmem_perms(void) { } +#endif /* CONFIG_ARM_KERNMEM_PERMS */ + +void free_tcmmem(void) { #ifdef CONFIG_HAVE_TCM extern char __tcm_start, __tcm_end; @@ -623,6 +716,12 @@ void free_initmem(void) poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link"); #endif +} + +void free_initmem(void) +{ + fix_kernmem_perms(); + free_tcmmem(); poison_init_mem(__init_begin, __init_end - __init_begin); if (!machine_is_integrator() && !machine_is_cintegrator()) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index bdf5c94f7c36..1c52c8e94372 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1373,12 +1373,19 @@ static void __init map_lowmem(void) if (start >= end) break; - if (end < kernel_x_start || start >= kernel_x_end) { + if (end < kernel_x_start) { map.pfn = __phys_to_pfn(start); map.virtual = __phys_to_virt(start); map.length = end - start; map.type = MT_MEMORY_RWX; + create_mapping(&map); + } else if (start >= kernel_x_end) { + map.pfn = __phys_to_pfn(start); + map.virtual = __phys_to_virt(start); + map.length = end - start; + map.type = MT_MEMORY_RW; + create_mapping(&map); } else { /* This better cover the entire kernel */ -- GitLab From 80d6b0c2eed2a504f6740cd1f5ea76dc50abfc4d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 3 Apr 2014 13:29:50 -0700 Subject: [PATCH 0235/9457] ARM: mm: allow text and rodata sections to be read-only This introduces CONFIG_DEBUG_RODATA, making kernel text and rodata read-only. Additionally, this splits rodata from text so that rodata can also be NX, which may lead to wasted memory when aligning to SECTION_SIZE. The read-only areas are made writable during ftrace updates and kexec. Signed-off-by: Kees Cook Tested-by: Laura Abbott Acked-by: Nicolas Pitre --- arch/arm/include/asm/cacheflush.h | 10 +++++++ arch/arm/kernel/ftrace.c | 19 ++++++++++++ arch/arm/kernel/machine_kexec.c | 1 + arch/arm/kernel/vmlinux.lds.S | 3 ++ arch/arm/mm/Kconfig | 12 ++++++++ arch/arm/mm/init.c | 48 ++++++++++++++++++++++++++++++- 6 files changed, 92 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 10e78d00a0bb..2d46862e7bef 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -487,6 +487,16 @@ int set_memory_rw(unsigned long addr, int numpages); int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); +#ifdef CONFIG_DEBUG_RODATA +void mark_rodata_ro(void); +void set_kernel_text_rw(void); +void set_kernel_text_ro(void); +#else +static inline void set_kernel_text_rw(void) { } +static inline void set_kernel_text_ro(void) { } +#endif + void flush_uprobe_xol_access(struct page *page, unsigned long uaddr, void *kaddr, unsigned long len); + #endif diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index af9a8a927a4e..b8c75e45a950 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,22 @@ #define OLD_NOP 0xe1a00000 /* mov r0, r0 */ +static int __ftrace_modify_code(void *data) +{ + int *command = data; + + set_kernel_text_rw(); + ftrace_modify_all_code(*command); + set_kernel_text_ro(); + + return 0; +} + +void arch_ftrace_update_code(int command) +{ + stop_machine(__ftrace_modify_code, &command, NULL); +} + static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec) { return rec->arch.old_mcount ? OLD_NOP : NOP; @@ -73,6 +90,8 @@ int ftrace_arch_code_modify_prepare(void) int ftrace_arch_code_modify_post_process(void) { set_all_modules_text_ro(); + /* Make sure any TLB misses during machine stop are cleared. */ + flush_tlb_all(); return 0; } diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8f75250cbe30..4423a565ef6f 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -164,6 +164,7 @@ void machine_kexec(struct kimage *image) reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ + set_kernel_text_rw(); kexec_start_address = image->start; kexec_indirection_page = page_list; kexec_mach_type = machine_arch_type; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 18fd68a295ea..3afcb6c2cf06 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -120,6 +120,9 @@ SECTIONS ARM_CPU_KEEP(PROC_INFO) } +#ifdef CONFIG_DEBUG_RODATA + . = ALIGN(1< Date: Wed, 15 Oct 2014 14:06:25 +0200 Subject: [PATCH 0236/9457] ALSA: seq: bind seq driver automatically Currently the sequencer module binding is performed independently from the card module itself. The reason behind it is to keep the sequencer stuff optional and allow the system running without it (e.g. for using PCM or rawmidi only). This works in most cases, but a remaining problem is that the binding isn't done automatically when a new driver module is probed. Typically this becomes visible when a hotplug driver like usb audio is used. This patch tries to address this and other potential issues. First, the seq-binder (seq_device.c) tries to load a missing driver module at creating a new device object. This is done asynchronously in a workq for avoiding the deadlock (modprobe call in module init path). This action, however, should be enabled only when the sequencer stuff was already initialized, i.e. snd-seq module was already loaded. For that, a new function, snd_seq_autoload_init() is introduced here; this clears the blocking of autoloading, and also tries to load all pending driver modules. Reported-by: Adam Goode Signed-off-by: Takashi Iwai --- include/sound/seq_kernel.h | 4 ++ sound/core/seq/seq.c | 3 ++ sound/core/seq/seq_device.c | 92 +++++++++++++++++++++++++++---------- 3 files changed, 76 insertions(+), 23 deletions(-) diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index 2398521f0998..eea5400fe373 100644 --- a/include/sound/seq_kernel.h +++ b/include/sound/seq_kernel.h @@ -108,9 +108,13 @@ int snd_seq_event_port_detach(int client, int port); #ifdef CONFIG_MODULES void snd_seq_autoload_lock(void); void snd_seq_autoload_unlock(void); +void snd_seq_autoload_init(void); +#define snd_seq_autoload_exit() snd_seq_autoload_lock() #else #define snd_seq_autoload_lock() #define snd_seq_autoload_unlock() +#define snd_seq_autoload_init() +#define snd_seq_autoload_exit() #endif #endif /* __SOUND_SEQ_KERNEL_H */ diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 712110561082..bebdd2e920ca 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -110,6 +110,7 @@ static int __init alsa_seq_init(void) if ((err = snd_seq_system_client_init()) < 0) goto error; + snd_seq_autoload_init(); error: snd_seq_autoload_unlock(); return err; @@ -131,6 +132,8 @@ static void __exit alsa_seq_exit(void) /* release event memory */ snd_sequencer_memory_done(); + + snd_seq_autoload_exit(); } module_init(alsa_seq_init) diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 775ea9390110..a8e2c6016800 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -56,6 +56,7 @@ MODULE_LICENSE("GPL"); #define DRIVER_LOADED (1<<0) #define DRIVER_REQUESTED (1<<1) #define DRIVER_LOCKED (1<<2) +#define DRIVER_REQUESTING (1<<3) struct ops_list { char id[ID_LEN]; /* driver id */ @@ -127,7 +128,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, #ifdef CONFIG_MODULES /* avoid auto-loading during module_init() */ -static atomic_t snd_seq_in_init = ATOMIC_INIT(0); +static atomic_t snd_seq_in_init = ATOMIC_INIT(1); /* blocked as default */ void snd_seq_autoload_lock(void) { atomic_inc(&snd_seq_in_init); @@ -137,32 +138,72 @@ void snd_seq_autoload_unlock(void) { atomic_dec(&snd_seq_in_init); } -#endif -void snd_seq_device_load_drivers(void) +static void autoload_drivers(void) { -#ifdef CONFIG_MODULES - struct ops_list *ops; + /* avoid reentrance */ + if (atomic_inc_return(&snd_seq_in_init) == 1) { + struct ops_list *ops; + + mutex_lock(&ops_mutex); + list_for_each_entry(ops, &opslist, list) { + if ((ops->driver & DRIVER_REQUESTING) && + !(ops->driver & DRIVER_REQUESTED)) { + ops->used++; + mutex_unlock(&ops_mutex); + ops->driver |= DRIVER_REQUESTED; + request_module("snd-%s", ops->id); + mutex_lock(&ops_mutex); + ops->used--; + } + } + mutex_unlock(&ops_mutex); + } + atomic_dec(&snd_seq_in_init); +} - /* Calling request_module during module_init() - * may cause blocking. - */ - if (atomic_read(&snd_seq_in_init)) - return; +static void call_autoload(struct work_struct *work) +{ + autoload_drivers(); +} - mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { - if (! (ops->driver & DRIVER_LOADED) && - ! (ops->driver & DRIVER_REQUESTED)) { - ops->used++; - mutex_unlock(&ops_mutex); - ops->driver |= DRIVER_REQUESTED; - request_module("snd-%s", ops->id); - mutex_lock(&ops_mutex); - ops->used--; - } +static DECLARE_WORK(autoload_work, call_autoload); + +static void try_autoload(struct ops_list *ops) +{ + if (!ops->driver) { + ops->driver |= DRIVER_REQUESTING; + schedule_work(&autoload_work); } +} + +static void queue_autoload_drivers(void) +{ + struct ops_list *ops; + + mutex_lock(&ops_mutex); + list_for_each_entry(ops, &opslist, list) + try_autoload(ops); mutex_unlock(&ops_mutex); +} + +void snd_seq_autoload_init(void) +{ + atomic_dec(&snd_seq_in_init); +#ifdef CONFIG_SND_SEQUENCER_MODULE + /* initial autoload only when snd-seq is a module */ + queue_autoload_drivers(); +#endif +} +#else +#define try_autoload(ops) /* NOP */ +#endif + +void snd_seq_device_load_drivers(void) +{ +#ifdef CONFIG_MODULES + queue_autoload_drivers(); + flush_work(&autoload_work); #endif } @@ -214,13 +255,14 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, ops->num_devices++; mutex_unlock(&ops->reg_mutex); - unlock_driver(ops); - if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) { snd_seq_device_free(dev); return err; } + try_autoload(ops); + unlock_driver(ops); + if (result) *result = dev; @@ -554,6 +596,9 @@ static int __init alsa_seq_device_init(void) static void __exit alsa_seq_device_exit(void) { +#ifdef CONFIG_MODULES + cancel_work_sync(&autoload_work); +#endif remove_drivers(); #ifdef CONFIG_PROC_FS snd_info_free_entry(info_entry); @@ -570,6 +615,7 @@ EXPORT_SYMBOL(snd_seq_device_new); EXPORT_SYMBOL(snd_seq_device_register_driver); EXPORT_SYMBOL(snd_seq_device_unregister_driver); #ifdef CONFIG_MODULES +EXPORT_SYMBOL(snd_seq_autoload_init); EXPORT_SYMBOL(snd_seq_autoload_lock); EXPORT_SYMBOL(snd_seq_autoload_unlock); #endif -- GitLab From d5129f33a0d155d69cb0652cfc87bbc4d132ca17 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 15 Oct 2014 14:09:42 +0200 Subject: [PATCH 0237/9457] Subject: ALSA: seq: Remove autoload locks in driver registration Since we're calling request_module() asynchronously now, we can get rid of the autoload lock in snd_seq_device_register_driver(), as well as in the snd-seq driver registration itself. This enables the automatic loading of dependent sequencer modules, such as snd-seq-virmidi from snd-emu10k1-synth. Signed-off-by: Takashi Iwai --- sound/core/seq/seq.c | 2 -- sound/core/seq/seq_device.c | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index bebdd2e920ca..7e0aabb808a6 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -86,7 +86,6 @@ static int __init alsa_seq_init(void) { int err; - snd_seq_autoload_lock(); if ((err = client_init_data()) < 0) goto error; @@ -112,7 +111,6 @@ static int __init alsa_seq_init(void) snd_seq_autoload_init(); error: - snd_seq_autoload_unlock(); return err; } diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index a8e2c6016800..0631bdadd12b 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -360,16 +360,12 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, entry->init_device == NULL || entry->free_device == NULL) return -EINVAL; - snd_seq_autoload_lock(); ops = find_driver(id, 1); - if (ops == NULL) { - snd_seq_autoload_unlock(); + if (ops == NULL) return -ENOMEM; - } if (ops->driver & DRIVER_LOADED) { pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id); unlock_driver(ops); - snd_seq_autoload_unlock(); return -EBUSY; } @@ -386,7 +382,6 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, mutex_unlock(&ops->reg_mutex); unlock_driver(ops); - snd_seq_autoload_unlock(); return 0; } -- GitLab From 49fd46d2ffc92de3f4bd2e337f60b8b6052dc8b6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 19 Oct 2014 09:11:25 +0200 Subject: [PATCH 0238/9457] ALSA: snd-usb: drop unused varible assigments Don't assign 'len' in cases where we don't make use of the returned value. Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 2e4a9dbc51fa..63a8adb1705e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1290,9 +1290,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, kctl->id.name, sizeof(kctl->id.name), 1); if (!len) - len = snprintf(kctl->id.name, - sizeof(kctl->id.name), - "Feature %d", unitid); + snprintf(kctl->id.name, sizeof(kctl->id.name), + "Feature %d", unitid); } if (!mapped_name) @@ -1305,9 +1304,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, */ if (!mapped_name && !(state->oterm.type >> 16)) { if ((state->oterm.type & 0xff00) == 0x0100) - len = append_ctl_name(kctl, " Capture"); + append_ctl_name(kctl, " Capture"); else - len = append_ctl_name(kctl, " Playback"); + append_ctl_name(kctl, " Playback"); } append_ctl_name(kctl, control == UAC_FU_MUTE ? " Switch" : " Volume"); -- GitLab From 068afbbebe14cdb628f7d738d1d289cf01a3b5d9 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 20 Oct 2014 00:11:59 +0200 Subject: [PATCH 0239/9457] HSI: omap_ssi_port: Don't print uninitialized err MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not print err variable, that has nothing to do with the error. This fixes a warning, that is printed at build time: drivers/hsi/controllers/omap_ssi_port.c: In function ‘ssi_port_probe’: drivers/hsi/controllers/omap_ssi_port.c:1121:10: warning: ‘err’ may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Sebastian Reichel --- drivers/hsi/controllers/omap_ssi_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 4c0b5820581e..7e31eccf353a 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -1118,8 +1118,7 @@ static int __init ssi_port_probe(struct platform_device *pd) dev_dbg(&pd->dev, "init ssi port...\n"); if (!try_module_get(ssi->owner)) { - dev_err(&pd->dev, "could not increment parent module refcount (err=%d)\n", - err); + dev_err(&pd->dev, "could not increment parent module refcount\n"); return -ENODEV; } -- GitLab From 0f431ff7a38e8235b6c5c30e7aea84a426109f4f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:43 -0400 Subject: [PATCH 0240/9457] staging: unisys: clean up enums in uisqueue.h Get rid of typedefs in enums SWITCH_TYPE and IOPART_MSG_TYPE, and use the enum names directly instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 5178270b98d1..534c7d85a92c 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -34,7 +34,6 @@ #include "controlvmcompletionstatus.h" struct uisqueue_info { - CHANNEL_HEADER __iomem *chan; /* channel containing queues in which scsi commands & * responses are queued @@ -149,10 +148,10 @@ struct device_info { unsigned long long last_on_list_cnt; }; -typedef enum { +enum switch_type { RECOVERY_LAN = 1, IB_LAN = 2 -} SWITCH_TYPE; +}; struct bus_info { u32 busNo, deviceCount; @@ -199,7 +198,7 @@ struct network_policy { */ -typedef enum { +enum iopart_msg_type { IOPART_ADD_VNIC, IOPART_DEL_VNIC, IOPART_DEL_ALL_VNICS, @@ -219,7 +218,7 @@ typedef enum { IOPART_RESUME_VDISK, IOPART_ADD_DEVICE, /* add generic device */ IOPART_DEL_DEVICE, /* del generic device */ -} IOPART_MSG_TYPE; +}; struct add_virt_iopart { void *chanptr; /* pointer to data channel */ @@ -297,8 +296,7 @@ struct del_switch_iopart { /* destroy switch */ }; struct io_msgs { - - IOPART_MSG_TYPE msgtype; + enum iopart_msg_type msgtype; /* additional params needed by some messages */ union { @@ -394,7 +392,6 @@ struct init_chipset_guestpart { }; struct guest_msgs { - GUESTPART_MSG_TYPE msgtype; /* additional params needed by messages */ -- GitLab From bae4e2ad834db505d39b2d332e9a3593e1419591 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:44 -0400 Subject: [PATCH 0241/9457] staging: unisys: clean up GUESTPART_MSG_TYPE typedef Switch GUESTPART_MSG_TYPE over to enum guestpart_msg_type. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 534c7d85a92c..8a84c2474fc5 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -197,7 +197,6 @@ struct network_policy { * code that processes the ControlVm channel messages. */ - enum iopart_msg_type { IOPART_ADD_VNIC, IOPART_DEL_VNIC, @@ -327,7 +326,7 @@ struct io_msgs { * the ControlVm channel messages. */ -typedef enum { +enum guestpart_msg_type { GUEST_ADD_VBUS, GUEST_ADD_VHBA, GUEST_ADD_VNIC, @@ -342,7 +341,7 @@ typedef enum { GUEST_PAUSE_VNIC, GUEST_RESUME_VHBA, GUEST_RESUME_VNIC -} GUESTPART_MSG_TYPE; +}; struct add_vbus_guestpart { void __iomem *chanptr; /* pointer to data channel for bus - @@ -392,7 +391,7 @@ struct init_chipset_guestpart { }; struct guest_msgs { - GUESTPART_MSG_TYPE msgtype; + enum guestpart_msg_type msgtype; /* additional params needed by messages */ union { -- GitLab From 43ecb9fe08ee6adaf67710519099711fa1e6c2db Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:45 -0400 Subject: [PATCH 0242/9457] staging: unisys: Clean up CamelCase in struct bus_info Clean up CamelCase names: busNo => bus_no deviceCount => device_count guestHandle => guest_handle recvBusInterruptHandle => recv_bus_irq_handle busInstGuid => inst_uuid pBusChannel => bus_channel busChannelBytes => bus_channel_bytes partitionName => partition_name localVnic => local_vnic Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 14 ++-- drivers/staging/unisys/uislib/uislib.c | 80 +++++++++++------------ 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 8a84c2474fc5..60961f25346b 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -154,18 +154,18 @@ enum switch_type { }; struct bus_info { - u32 busNo, deviceCount; + u32 bus_no, device_count; struct device_info **device; - u64 guestHandle, recvBusInterruptHandle; - uuid_le busInstGuid; - ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *pBusChannel; - int busChannelBytes; + u64 guest_handle, recv_bus_irq_handle; + uuid_le bus_inst_uuid; + ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *bus_channel; + int bus_channel_bytes; struct proc_dir_entry *proc_dir; /* proc/uislib/vbus/ */ struct proc_dir_entry *proc_info; /* proc/uislib/vbus//info */ char name[25]; - char partitionName[99]; + char partition_name[99]; struct bus_info *next; - u8 localVnic; /* 1 if local vnic created internally + u8 local_vnic; /* 1 if local vnic created internally * by IOVM; 0 otherwise... */ }; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 706f1c0c2c6e..d31da1ca70d9 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -190,23 +190,23 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) */ if (msg->hdr.Flags.testMessage) { /* This implies we're the IOVM so set guest handle to 0... */ - bus->guestHandle = 0; - bus->busNo = busNo; - bus->localVnic = 1; + bus->guest_handle = 0; + bus->bus_no = busNo; + bus->local_vnic = 1; } else - bus->busNo = bus->guestHandle = busNo; - sprintf(bus->name, "%d", (int) bus->busNo); - bus->deviceCount = deviceCount; + bus->bus_no = bus->guest_handle = busNo; + sprintf(bus->name, "%d", (int) bus->bus_no); + bus->device_count = deviceCount; bus->device = (struct device_info **) ((char *) bus + sizeof(struct bus_info)); - bus->busInstGuid = msg->cmd.createBus.busInstGuid; - bus->busChannelBytes = 0; - bus->pBusChannel = NULL; + bus->bus_inst_uuid = msg->cmd.createBus.busInstGuid; + bus->bus_channel_bytes = 0; + bus->bus_channel = NULL; /* add bus to our bus list - but check for duplicates first */ read_lock(&BusListLock); for (tmp = BusListHead; tmp; tmp = tmp->next) { - if (tmp->busNo == bus->busNo) + if (tmp->bus_no == bus->bus_no) break; } read_unlock(&BusListLock); @@ -215,16 +215,16 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) * reject add */ LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n", - bus->busNo); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + bus->bus_no); + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_ALREADY_DONE; } if ((msg->cmd.createBus.channelAddr != 0) && (msg->cmd.createBus.channelBytes != 0)) { - bus->busChannelBytes = msg->cmd.createBus.channelBytes; - bus->pBusChannel = + bus->bus_channel_bytes = msg->cmd.createBus.channelBytes; + bus->bus_channel = init_vbus_channel(msg->cmd.createBus.channelAddr, msg->cmd.createBus.channelBytes); } @@ -234,20 +234,20 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) cmd.msgtype = GUEST_ADD_VBUS; cmd.add_vbus.busNo = busNo; - cmd.add_vbus.chanptr = bus->pBusChannel; + cmd.add_vbus.chanptr = bus->bus_channel; cmd.add_vbus.deviceCount = deviceCount; cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid; cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid; if (!VirtControlChanFunc) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!VirtControlChanFunc(&cmd)) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error."); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return @@ -266,7 +266,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) BusListCount++; write_unlock(&BusListLock); - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->busNo, + POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no, POSTCODE_SEVERITY_INFO); return CONTROLVM_RESP_SUCCESS; } @@ -285,7 +285,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) bus = BusListHead; while (bus) { - if (bus->busNo == busNo) + if (bus->bus_no == busNo) break; prev = bus; bus = bus->next; @@ -299,7 +299,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) } /* verify that this bus has no devices. */ - for (i = 0; i < bus->deviceCount; i++) { + for (i = 0; i < bus->device_count; i++) { if (bus->device[i] != NULL) { LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.", i, busNo); @@ -335,9 +335,9 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) BusListCount--; write_unlock(&BusListLock); - if (bus->pBusChannel) { - uislib_iounmap(bus->pBusChannel); - bus->pBusChannel = NULL; + if (bus->bus_channel) { + uislib_iounmap(bus->bus_channel); + bus->bus_channel = NULL; } kfree(bus); @@ -412,11 +412,11 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); result = CONTROLVM_RESP_ERROR_MAX_DEVICES; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, @@ -555,11 +555,11 @@ pause_device(CONTROLVM_MESSAGE *msg) read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -623,11 +623,11 @@ resume_device(CONTROLVM_MESSAGE *msg) read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -693,11 +693,11 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) read_lock(&BusListLock); LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).", - devNo, bus->deviceCount); + devNo, bus->device_count); retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID; } else { /* make sure this device exists */ @@ -1206,17 +1206,17 @@ info_debugfs_read_helper(char **buff, int *buff_len) for (bus = BusListHead; bus; bus = bus->next) { if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n", - bus, bus->busNo, bus->deviceCount) < 0) + bus, bus->bus_no, bus->device_count) < 0) goto err_done_unlock; if (PLINE(" Devices:\n") < 0) goto err_done_unlock; - for (i = 0; i < bus->deviceCount; i++) { + for (i = 0; i < bus->device_count; i++) { if (bus->device[i]) { if (PLINE(" busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n", - bus->busNo, i, bus->device[i], + bus->bus_no, i, bus->device[i], bus->device[i]->chanptr, bus->device[i]->swtch) < 0) goto err_done_unlock; @@ -1294,9 +1294,9 @@ find_dev(u32 busNo, u32 devNo) read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { - if (bus->busNo == busNo) { + if (bus->bus_no == busNo) { /* make sure the device number is valid */ - if (devNo >= bus->deviceCount) { + if (devNo >= bus->device_count) { LOGERR("%s bad busNo, devNo=%d,%d", __func__, (int) (busNo), (int) (devNo)); -- GitLab From 34e6230b21dc397592c41ca9164a06adad0c86e6 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:46 -0400 Subject: [PATCH 0243/9457] staging: unisys: fix CamelCase in struct add_vbus_guestpart Clean up CamelCase names: busNo => bus_no deviceCount => dev_count busTypeGuid => bus_uuid busInstGuid => instance_guid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 8 ++++---- drivers/staging/unisys/uislib/uislib.c | 8 ++++---- drivers/staging/unisys/virtpci/virtpci.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 60961f25346b..04f51e66ebf0 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -346,10 +346,10 @@ enum guestpart_msg_type { struct add_vbus_guestpart { void __iomem *chanptr; /* pointer to data channel for bus - * NOT YET USED */ - u32 busNo; /* bus number to be created/deleted */ - u32 deviceCount; /* max num of devices on bus */ - uuid_le busTypeGuid; /* indicates type of bus */ - uuid_le busInstGuid; /* instance guid for device */ + u32 bus_no; /* bus number to be created/deleted */ + u32 dev_count; /* max num of devices on bus */ + uuid_le bus_uuid; /* indicates type of bus */ + uuid_le instance_uuid; /* instance guid for device */ }; struct del_vbus_guestpart { diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index d31da1ca70d9..f7f855538d80 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -233,11 +233,11 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) struct guest_msgs cmd; cmd.msgtype = GUEST_ADD_VBUS; - cmd.add_vbus.busNo = busNo; + cmd.add_vbus.bus_no = busNo; cmd.add_vbus.chanptr = bus->bus_channel; - cmd.add_vbus.deviceCount = deviceCount; - cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid; - cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid; + cmd.add_vbus.dev_count = deviceCount; + cmd.add_vbus.bus_uuid = msg->cmd.createBus.busDataTypeGuid; + cmd.add_vbus.instance_uuid = msg->cmd.createBus.busInstGuid; if (!VirtControlChanFunc) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index ee9f8260cd15..91f939570b38 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -262,7 +262,7 @@ static int add_vbus(struct add_vbus_guestpart *addparams) if (!vbus) return 0; - dev_set_name(vbus, "vbus%d", addparams->busNo); + dev_set_name(vbus, "vbus%d", addparams->bus_no); vbus->release = virtpci_bus_release; vbus->parent = &virtpci_rootbus_device; /* root bus is parent */ vbus->bus = &virtpci_bus_type; /* bus type */ @@ -283,7 +283,7 @@ static int add_vbus(struct add_vbus_guestpart *addparams) &Chipset_DriverInfo); write_vbus_busInfo(vbus->platform_data /* chanptr */ , &Bus_DriverInfo); LOGINF("Added vbus %d; device %s created successfully\n", - addparams->busNo, BUS_ID(vbus)); + addparams->bus_no, BUS_ID(vbus)); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 1; } -- GitLab From 2df7cc6267035c2da2f5e92fe632356178735825 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:47 -0400 Subject: [PATCH 0244/9457] staging: unisys: Fix CamelCase function pointers in uisutils Fix CamelCase names: UisnicControlChanFunc => uisnic_control_chan_func UissdControlChanFunc => uissd_control_chan_func VirtControlChanFunc => virt_control_chan_func Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 6 ++--- drivers/staging/unisys/uislib/uislib.c | 30 +++++++++++------------ drivers/staging/unisys/uislib/uisutils.c | 8 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 74e7cf65502c..85d49e4860a6 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -43,9 +43,9 @@ /* global function pointers that act as callback functions into * uisnicmod, uissdmod, and virtpcimod */ -extern int (*UisnicControlChanFunc)(struct io_msgs *); -extern int (*UissdControlChanFunc)(struct io_msgs *); -extern int (*VirtControlChanFunc)(struct guest_msgs *); +extern int (*uisnic_control_chan_func)(struct io_msgs *); +extern int (*uissd_control_chan_func)(struct io_msgs *); +extern int (*virt_control_chan_func)(struct guest_msgs *); /* Return values of above callback functions: */ #define CCF_ERROR 0 /* completed and failed */ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index f7f855538d80..b48b962165ff 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -57,7 +57,7 @@ #define __MYFILE__ "uislib.c" /* global function pointers that act as callback functions into virtpcimod */ -int (*VirtControlChanFunc)(struct guest_msgs *); +int (*virt_control_chan_func)(struct guest_msgs *); static int ProcReadBufferValid; static char *ProcReadBuffer; /* Note this MUST be global, @@ -238,14 +238,14 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) cmd.add_vbus.dev_count = deviceCount; cmd.add_vbus.bus_uuid = msg->cmd.createBus.busDataTypeGuid; cmd.add_vbus.instance_uuid = msg->cmd.createBus.busInstGuid; - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, POSTCODE_SEVERITY_ERR); @@ -316,11 +316,11 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) with this bus. */ cmd.msgtype = GUEST_DEL_VBUS; cmd.del_vbus.bus_no = busNo; - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } @@ -500,7 +500,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) goto Away; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_4 (DEVICE_CREATE_FAILURE_PC, devNo, @@ -509,7 +509,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) goto Away; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error."); POSTCODE_LINUX_4 (DEVICE_CREATE_FAILURE_PC, devNo, @@ -596,11 +596,11 @@ pause_device(CONTROLVM_MESSAGE *msg) LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -665,11 +665,11 @@ resume_device(CONTROLVM_MESSAGE *msg) LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n"); return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -736,12 +736,12 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN; } - if (!VirtControlChanFunc) { + if (!virt_control_chan_func) { LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } - if (!VirtControlChanFunc(&cmd)) { + if (!virt_control_chan_func(&cmd)) { LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error."); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; @@ -783,7 +783,7 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf) * functions. */ if (!msg->hdr.Flags.testMessage) - WAIT_ON_CALLBACK(VirtControlChanFunc); + WAIT_ON_CALLBACK(virt_control_chan_func); chipset_inited = 1; POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -1574,7 +1574,7 @@ uislib_mod_init(void) BusListHead = NULL; BusListCount = MaxBusCount = 0; rwlock_init(&BusListLock); - VirtControlChanFunc = NULL; + virt_control_chan_func = NULL; /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and * then map this physical address to a virtual address. */ diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 8ff6d26ff00b..3001819aba96 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -82,13 +82,13 @@ uisctrl_register_req_handler(int type, void *fptr, switch (type) { case 2: if (fptr) { - if (!VirtControlChanFunc) + if (!virt_control_chan_func) atomic_inc(&UisUtils_Registered_Services); - VirtControlChanFunc = fptr; + virt_control_chan_func = fptr; } else { - if (VirtControlChanFunc) + if (virt_control_chan_func) atomic_dec(&UisUtils_Registered_Services); - VirtControlChanFunc = NULL; + virt_control_chan_func = NULL; } break; -- GitLab From e9b9262a24bd5fa2c7de074a4fcd95eb6c6928d7 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:48 -0400 Subject: [PATCH 0245/9457] staging: unisys: fix CamelCase name for registered services variable Fix CamelCase names: UisUtils_Registered_Services => uisutils_registered_services Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 2 +- drivers/staging/unisys/uislib/uisutils.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 85d49e4860a6..3c9aadb657d2 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -51,7 +51,7 @@ extern int (*virt_control_chan_func)(struct guest_msgs *); #define CCF_ERROR 0 /* completed and failed */ #define CCF_OK 1 /* completed successfully */ #define CCF_PENDING 2 /* operation still pending */ -extern atomic_t UisUtils_Registered_Services; +extern atomic_t uisutils_registered_services; typedef unsigned int MACARRAY[MAX_MACADDR_LEN]; typedef struct ReqHandlerInfo_struct { diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index b48b962165ff..b1c9d4942cd6 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1232,7 +1232,7 @@ info_debugfs_read_helper(char **buff, int *buff_len) read_unlock(&BusListLock); if (PLINE("UisUtils_Registered_Services: %d\n", - atomic_read(&UisUtils_Registered_Services)) < 0) + atomic_read(&uisutils_registered_services)) < 0) goto err_done; if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n", cycles_before_wait, wait_cycles) < 0) diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 3001819aba96..82230f2c61ae 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -39,7 +39,7 @@ #define __MYFILE__ "uisutils.c" /* exports */ -atomic_t UisUtils_Registered_Services = ATOMIC_INIT(0); +atomic_t uisutils_registered_services = ATOMIC_INIT(0); /* num registrations via * uisctrl_register_req_handler() or * uisctrl_register_req_handler_ex() */ @@ -83,11 +83,11 @@ uisctrl_register_req_handler(int type, void *fptr, case 2: if (fptr) { if (!virt_control_chan_func) - atomic_inc(&UisUtils_Registered_Services); + atomic_inc(&uisutils_registered_services); virt_control_chan_func = fptr; } else { if (virt_control_chan_func) - atomic_dec(&UisUtils_Registered_Services); + atomic_dec(&uisutils_registered_services); virt_control_chan_func = NULL; } break; @@ -145,7 +145,7 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, goto Away; } - atomic_inc(&UisUtils_Registered_Services); + atomic_inc(&uisutils_registered_services); rc = 1; /* success */ Away: if (rc) { @@ -170,7 +170,7 @@ uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid) &switchTypeGuid); goto Away; } - atomic_dec(&UisUtils_Registered_Services); + atomic_dec(&uisutils_registered_services); rc = 1; /* success */ Away: if (!rc) -- GitLab From 9aee8f970dd9a82e468f625eee56f71bfaa7dd52 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:49 -0400 Subject: [PATCH 0246/9457] staging: unisys: get rid of MACARRAY typedef Remove the MACARRAY typedef entirely and switch over to u8*[ETH_ALEN], like everybody else seems to use. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 3c9aadb657d2..0dee798ad4e0 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "vmcallinterface.h" #include "channel.h" @@ -53,7 +54,6 @@ extern int (*virt_control_chan_func)(struct guest_msgs *); #define CCF_PENDING 2 /* operation still pending */ extern atomic_t uisutils_registered_services; -typedef unsigned int MACARRAY[MAX_MACADDR_LEN]; typedef struct ReqHandlerInfo_struct { uuid_le switchTypeGuid; int (*controlfunc)(struct io_msgs *); @@ -132,7 +132,7 @@ void util_unmap_virt(struct phys_info *sg); unsigned char *util_map_virt_atomic(struct phys_info *sg); void util_unmap_virt_atomic(void *buf); int uislib_server_inject_add_vnic(u32 switchNo, u32 BusNo, u32 numIntPorts, - u32 numExtPorts, MACARRAY pmac[], + u32 numExtPorts, u8 *pmac[ETH_ALEN], pCHANNEL_HEADER **chan); void uislib_server_inject_del_vnic(u32 switchNo, u32 busNo, u32 numIntPorts, u32 numExtPorts); -- GitLab From 38ab19b63373ef301a0ecee4800cb7cd938c3814 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:50 -0400 Subject: [PATCH 0247/9457] staging: unisys: remove typedef ReqHandlerInfo_t Convert all references to the typedef to struct req_handler_info. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 14 +++++++------- drivers/staging/unisys/uislib/uislib.c | 2 +- drivers/staging/unisys/uislib/uisutils.c | 18 +++++++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 0dee798ad4e0..9bb95d597d5c 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -54,7 +54,7 @@ extern int (*virt_control_chan_func)(struct guest_msgs *); #define CCF_PENDING 2 /* operation still pending */ extern atomic_t uisutils_registered_services; -typedef struct ReqHandlerInfo_struct { +struct req_handler_info { uuid_le switchTypeGuid; int (*controlfunc)(struct io_msgs *); unsigned long min_channel_bytes; @@ -63,18 +63,18 @@ typedef struct ReqHandlerInfo_struct { (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes); char switch_type_name[99]; struct list_head list_link; /* links into ReqHandlerInfo_list */ -} ReqHandlerInfo_t; +}; -ReqHandlerInfo_t *ReqHandlerAdd(uuid_le switchTypeGuid, +struct req_handler_info *ReqHandlerAdd(uuid_le switchTypeGuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, int (*Server_Channel_Ok)(unsigned long channelBytes), - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes)); -ReqHandlerInfo_t *ReqHandlerFind(uuid_le switchTypeGuid); + int (*Server_Channel_Init)(void *x, + unsigned char *clientStr, + u32 clientStrLen, u64 bytes)); +struct req_handler_info *ReqHandlerFind(uuid_le switchTypeGuid); int ReqHandlerDel(uuid_le switchTypeGuid); #define uislib_ioremap_cache(addr, size) \ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index b1c9d4942cd6..c438d8334e23 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -352,7 +352,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) u32 busNo, devNo; int result = CONTROLVM_RESP_SUCCESS; u64 minSize = MIN_IO_CHANNEL_SIZE; - ReqHandlerInfo_t *pReqHandler; + struct req_handler_info *pReqHandler; busNo = msg->cmd.createDevice.busNo; devNo = msg->cmd.createDevice.devNo; diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 82230f2c61ae..f3a23a62d6fe 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -116,7 +116,7 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, u32 clientStrLen, u64 bytes), ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo) { - ReqHandlerInfo_t *pReqHandlerInfo; + struct req_handler_info *pReqHandlerInfo; int rc = 0; /* assume failure */ LOGINF("type=%pUL, controlfunc=0x%p.\n", @@ -275,10 +275,10 @@ dolist: if (skb_shinfo(skb)->frag_list) { } EXPORT_SYMBOL_GPL(uisutil_copy_fragsinfo_from_skb); -static LIST_HEAD(ReqHandlerInfo_list); /* list of ReqHandlerInfo_t */ +static LIST_HEAD(ReqHandlerInfo_list); /* list of struct req_handler_info */ static DEFINE_SPINLOCK(ReqHandlerInfo_list_lock); -ReqHandlerInfo_t * +struct req_handler_info * ReqHandlerAdd(uuid_le switchTypeGuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), @@ -287,7 +287,7 @@ ReqHandlerAdd(uuid_le switchTypeGuid, int (*Server_Channel_Init) (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes)) { - ReqHandlerInfo_t *rc = NULL; + struct req_handler_info *rc = NULL; rc = kzalloc(sizeof(*rc), GFP_ATOMIC); if (!rc) @@ -307,15 +307,15 @@ ReqHandlerAdd(uuid_le switchTypeGuid, return rc; } -ReqHandlerInfo_t * +struct req_handler_info * ReqHandlerFind(uuid_le switchTypeGuid) { struct list_head *lelt, *tmp; - ReqHandlerInfo_t *entry = NULL; + struct req_handler_info *entry = NULL; spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { - entry = list_entry(lelt, ReqHandlerInfo_t, list_link); + entry = list_entry(lelt, struct req_handler_info, list_link); if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { spin_unlock(&ReqHandlerInfo_list_lock); return entry; @@ -329,12 +329,12 @@ int ReqHandlerDel(uuid_le switchTypeGuid) { struct list_head *lelt, *tmp; - ReqHandlerInfo_t *entry = NULL; + struct req_handler_info *entry = NULL; int rc = -1; spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { - entry = list_entry(lelt, ReqHandlerInfo_t, list_link); + entry = list_entry(lelt, struct req_handler_info, list_link); if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { list_del(lelt); kfree(entry); -- GitLab From 157764e776139ce7996190a3ef44e3b0ee582d82 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:51 -0400 Subject: [PATCH 0248/9457] staging: unisys: fix CamelCase in struct req_handler_info Fix CamelCase names: switchTypeGuid => switch_uuid Server_Channel_Ok => server_channel_ok channelBytes => channel_bytes Server_Channel_Init => server_channel_init clientStr => client_str clientStrLen => client_str_len Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 8 ++++---- drivers/staging/unisys/uislib/uisutils.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 9bb95d597d5c..992c8cdfb725 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -55,12 +55,12 @@ extern int (*virt_control_chan_func)(struct guest_msgs *); extern atomic_t uisutils_registered_services; struct req_handler_info { - uuid_le switchTypeGuid; + uuid_le switch_uuid; int (*controlfunc)(struct io_msgs *); unsigned long min_channel_bytes; - int (*Server_Channel_Ok)(unsigned long channelBytes); - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes); + int (*server_channel_ok)(unsigned long channel_bytes); + int (*server_channel_init) + (void *x, unsigned char *client_str, u32 client_str_len, u64 bytes); char switch_type_name[99]; struct list_head list_link; /* links into ReqHandlerInfo_list */ }; diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index f3a23a62d6fe..7006c470d6ac 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -292,11 +292,11 @@ ReqHandlerAdd(uuid_le switchTypeGuid, rc = kzalloc(sizeof(*rc), GFP_ATOMIC); if (!rc) return NULL; - rc->switchTypeGuid = switchTypeGuid; + rc->switch_uuid = switchTypeGuid; rc->controlfunc = controlfunc; rc->min_channel_bytes = min_channel_bytes; - rc->Server_Channel_Ok = Server_Channel_Ok; - rc->Server_Channel_Init = Server_Channel_Init; + rc->server_channel_ok = Server_Channel_Ok; + rc->server_channel_init = Server_Channel_Init; if (switch_type_name) strncpy(rc->switch_type_name, switch_type_name, sizeof(rc->switch_type_name) - 1); @@ -316,7 +316,7 @@ ReqHandlerFind(uuid_le switchTypeGuid) spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { entry = list_entry(lelt, struct req_handler_info, list_link); - if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { + if (uuid_le_cmp(entry->switch_uuid, switchTypeGuid) == 0) { spin_unlock(&ReqHandlerInfo_list_lock); return entry; } @@ -335,7 +335,7 @@ ReqHandlerDel(uuid_le switchTypeGuid) spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { entry = list_entry(lelt, struct req_handler_info, list_link); - if (uuid_le_cmp(entry->switchTypeGuid, switchTypeGuid) == 0) { + if (uuid_le_cmp(entry->switch_uuid, switchTypeGuid) == 0) { list_del(lelt); kfree(entry); rc++; -- GitLab From 3636c0da3d048a058c01e5be71cd601fbdbb1c7e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:52 -0400 Subject: [PATCH 0249/9457] staging: unisys: fix CamelCase names in ReqHandlerAdd() Fix CamelCase names: ReqHandlerAdd => req_handler_add Server_Channel_Ok => svr_channel_ok channelBytes => channel_bytes Server_Channel_Init => svr_channel_init clientStr => client_str ClientStrLen => client_str_len Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 16 ++++++++-------- drivers/staging/unisys/uislib/uisutils.c | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 992c8cdfb725..1455c73a5479 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -65,15 +65,15 @@ struct req_handler_info { struct list_head list_link; /* links into ReqHandlerInfo_list */ }; -struct req_handler_info *ReqHandlerAdd(uuid_le switchTypeGuid, +struct req_handler_info *req_handler_add(uuid_le switch_uuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long - channelBytes), - int (*Server_Channel_Init)(void *x, - unsigned char *clientStr, - u32 clientStrLen, u64 bytes)); + int (*svr_channel_ok)(unsigned long + channel_bytes), + int (*svr_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, u64 bytes)); struct req_handler_info *ReqHandlerFind(uuid_le switchTypeGuid); int ReqHandlerDel(uuid_le switchTypeGuid); @@ -119,9 +119,9 @@ int uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, const char *switch_type_name, int (*fptr)(struct io_msgs *), unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long + int (*svr_channel_ok)(unsigned long channelBytes), - int (*Server_Channel_Init) + int (*svr_channel_init) (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes), ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo); diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 7006c470d6ac..b336debe1d73 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -135,7 +135,7 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, &switchTypeGuid); goto Away; } - pReqHandlerInfo = ReqHandlerAdd(switchTypeGuid, + pReqHandlerInfo = req_handler_add(switchTypeGuid, switch_type_name, controlfunc, min_channel_bytes, @@ -279,7 +279,7 @@ static LIST_HEAD(ReqHandlerInfo_list); /* list of struct req_handler_info */ static DEFINE_SPINLOCK(ReqHandlerInfo_list_lock); struct req_handler_info * -ReqHandlerAdd(uuid_le switchTypeGuid, +req_handler_add(uuid_le switch_uuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, @@ -292,7 +292,7 @@ ReqHandlerAdd(uuid_le switchTypeGuid, rc = kzalloc(sizeof(*rc), GFP_ATOMIC); if (!rc) return NULL; - rc->switch_uuid = switchTypeGuid; + rc->switch_uuid = switch_uuid; rc->controlfunc = controlfunc; rc->min_channel_bytes = min_channel_bytes; rc->server_channel_ok = Server_Channel_Ok; -- GitLab From ea2cfd65315b479eeadd77df4ac311f7f5a1cb16 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:53 -0400 Subject: [PATCH 0250/9457] staging: unisys: fix CamelCase in ReqHandlerFind() Fix CamelCase names: ReqHandlerFind => req_handler_find switchTypeGuid => switch_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 2 +- drivers/staging/unisys/uislib/uisutils.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 1455c73a5479..65ded5eeab26 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -74,7 +74,7 @@ struct req_handler_info *req_handler_add(uuid_le switch_uuid, int (*svr_channel_init)(void *x, unsigned char *client_str, u32 client_str_len, u64 bytes)); -struct req_handler_info *ReqHandlerFind(uuid_le switchTypeGuid); +struct req_handler_info *req_handler_find(uuid_le switch_uuid); int ReqHandlerDel(uuid_le switchTypeGuid); #define uislib_ioremap_cache(addr, size) \ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index c438d8334e23..0ae008bfa199 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -379,7 +379,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) if (msg->hdr.Flags.testMessage) dev->chanptr = (void __iomem *)__va(dev->channel_addr); else { - pReqHandler = ReqHandlerFind(dev->channel_uuid); + pReqHandler = req_handler_find(dev->channel_uuid); if (pReqHandler) /* generic service handler registered for this * channel diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index b336debe1d73..b62b680f23c5 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -308,7 +308,7 @@ req_handler_add(uuid_le switch_uuid, } struct req_handler_info * -ReqHandlerFind(uuid_le switchTypeGuid) +req_handler_find(uuid_le switch_uuid) { struct list_head *lelt, *tmp; struct req_handler_info *entry = NULL; @@ -316,7 +316,7 @@ ReqHandlerFind(uuid_le switchTypeGuid) spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { entry = list_entry(lelt, struct req_handler_info, list_link); - if (uuid_le_cmp(entry->switch_uuid, switchTypeGuid) == 0) { + if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { spin_unlock(&ReqHandlerInfo_list_lock); return entry; } -- GitLab From 7692544dcfab0a9ad1e68ed98b8637f39428bea4 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:54 -0400 Subject: [PATCH 0251/9457] staging: unisys: fix CamelCase in ReqHandlerDel Fix CamelCase names: ReqHandlerDel => req_handler_del switchTypeGuid => switch_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uisutils.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 65ded5eeab26..ba71a471ecdf 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -75,7 +75,7 @@ struct req_handler_info *req_handler_add(uuid_le switch_uuid, unsigned char *client_str, u32 client_str_len, u64 bytes)); struct req_handler_info *req_handler_find(uuid_le switch_uuid); -int ReqHandlerDel(uuid_le switchTypeGuid); +int req_handler_del(uuid_le switch_uuid); #define uislib_ioremap_cache(addr, size) \ dbg_ioremap_cache(addr, size, __FILE__, __LINE__) diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index b62b680f23c5..5231c19bb74a 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -165,7 +165,7 @@ uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid) int rc = 0; /* assume failure */ LOGINF("type=%pUL.\n", &switchTypeGuid); - if (ReqHandlerDel(switchTypeGuid) < 0) { + if (req_handler_del(switchTypeGuid) < 0) { LOGERR("failed to remove %pUL from server list\n", &switchTypeGuid); goto Away; @@ -326,7 +326,7 @@ req_handler_find(uuid_le switch_uuid) } int -ReqHandlerDel(uuid_le switchTypeGuid) +req_handler_del(uuid_le switch_uuid) { struct list_head *lelt, *tmp; struct req_handler_info *entry = NULL; @@ -335,7 +335,7 @@ ReqHandlerDel(uuid_le switchTypeGuid) spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { entry = list_entry(lelt, struct req_handler_info, list_link); - if (uuid_le_cmp(entry->switch_uuid, switchTypeGuid) == 0) { + if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { list_del(lelt); kfree(entry); rc++; -- GitLab From f9dd5dda30cd700d38ed24196bfb2b1f5a690b0c Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:55 -0400 Subject: [PATCH 0252/9457] staging: unisys: fix indentation in req_handler_info Fix the indentation around server_channel_init, so the parameters line up nicely. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index ba71a471ecdf..3f481364ff5a 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -59,8 +59,8 @@ struct req_handler_info { int (*controlfunc)(struct io_msgs *); unsigned long min_channel_bytes; int (*server_channel_ok)(unsigned long channel_bytes); - int (*server_channel_init) - (void *x, unsigned char *client_str, u32 client_str_len, u64 bytes); + int (*server_channel_init)(void *x, unsigned char *client_str, + u32 client_str_len, u64 bytes); char switch_type_name[99]; struct list_head list_link; /* links into ReqHandlerInfo_list */ }; -- GitLab From 1032885d7299217995c134e5cd36dd0b333b3bdb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:56 -0400 Subject: [PATCH 0253/9457] staging: unisys: fix CamelCase in uisctrl_register_req_handler_ex Fix CamelCase names: switchTypeGuid => switch_uuid clientStr => client_str clientStrLent => client_str_len chipset_driverInfo => chipset_driver_info Server_Channel_Ok => server_channel_ok Server_Channel_Init => server_channel_init Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 13 ++++---- drivers/staging/unisys/uislib/uisutils.c | 38 +++++++++++------------ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 3f481364ff5a..9fb9aaa6f90a 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -115,16 +115,17 @@ int uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, int uisctrl_register_req_handler(int type, void *fptr, ULTRA_VBUS_DEVICEINFO *chipset_driver_info); -int uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, +int uisctrl_register_req_handler_ex(uuid_le switch_guid, const char *switch_type_name, int (*fptr)(struct io_msgs *), unsigned long min_channel_bytes, int (*svr_channel_ok)(unsigned long - channelBytes), - int (*svr_channel_init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo); + channel_bytes), + int (*svr_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, + u64 bytes), + ULTRA_VBUS_DEVICEINFO *chipset_driver_info); int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid); unsigned char *util_map_virt(struct phys_info *sg); diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 5231c19bb74a..6211ac1ada44 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -105,43 +105,43 @@ uisctrl_register_req_handler(int type, void *fptr, EXPORT_SYMBOL_GPL(uisctrl_register_req_handler); int -uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, +uisctrl_register_req_handler_ex(uuid_le switch_uuid, const char *switch_type_name, int (*controlfunc)(struct io_msgs *), unsigned long min_channel_bytes, - int (*Server_Channel_Ok)(unsigned long - channelBytes), - int (*Server_Channel_Init) - (void *x, unsigned char *clientStr, - u32 clientStrLen, u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo) + int (*server_channel_ok)(unsigned long + channel_bytes), + int (*server_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, u64 bytes), + ULTRA_VBUS_DEVICEINFO *chipset_driver_info) { struct req_handler_info *pReqHandlerInfo; int rc = 0; /* assume failure */ LOGINF("type=%pUL, controlfunc=0x%p.\n", - &switchTypeGuid, controlfunc); + &switch_uuid, controlfunc); if (!controlfunc) { - LOGERR("%pUL: controlfunc must be supplied\n", &switchTypeGuid); + LOGERR("%pUL: controlfunc must be supplied\n", &switch_uuid); goto Away; } - if (!Server_Channel_Ok) { + if (!server_channel_ok) { LOGERR("%pUL: Server_Channel_Ok must be supplied\n", - &switchTypeGuid); + &switch_uuid); goto Away; } - if (!Server_Channel_Init) { + if (!server_channel_init) { LOGERR("%pUL: Server_Channel_Init must be supplied\n", - &switchTypeGuid); + &switch_uuid); goto Away; } - pReqHandlerInfo = req_handler_add(switchTypeGuid, + pReqHandlerInfo = req_handler_add(switch_uuid, switch_type_name, controlfunc, min_channel_bytes, - Server_Channel_Ok, Server_Channel_Init); + server_channel_ok, server_channel_init); if (!pReqHandlerInfo) { - LOGERR("failed to add %pUL to server list\n", &switchTypeGuid); + LOGERR("failed to add %pUL to server list\n", &switch_uuid); goto Away; } @@ -149,11 +149,11 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, rc = 1; /* success */ Away: if (rc) { - if (chipset_DriverInfo) - bus_device_info_init(chipset_DriverInfo, "chipset", + if (chipset_driver_info) + bus_device_info_init(chipset_driver_info, "chipset", "uislib", VERSION, NULL); } else - LOGERR("failed to register type %pUL.\n", &switchTypeGuid); + LOGERR("failed to register type %pUL.\n", &switch_uuid); return rc; } -- GitLab From d44694af501ebeb16da450bfcfd286b0a18fa8cb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:57 -0400 Subject: [PATCH 0254/9457] staging: unisys: fix CamelCase in uisctrl_unregister_req_handler_ex Fix CamelCase names: switchTypeGuid => switch_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uisutils.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 9fb9aaa6f90a..ea8708b078ec 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -127,7 +127,7 @@ int uisctrl_register_req_handler_ex(uuid_le switch_guid, u64 bytes), ULTRA_VBUS_DEVICEINFO *chipset_driver_info); -int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid); +int uisctrl_unregister_req_handler_ex(uuid_le switch_uuid); unsigned char *util_map_virt(struct phys_info *sg); void util_unmap_virt(struct phys_info *sg); unsigned char *util_map_virt_atomic(struct phys_info *sg); diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 6211ac1ada44..31f517aa141f 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -160,21 +160,21 @@ uisctrl_register_req_handler_ex(uuid_le switch_uuid, EXPORT_SYMBOL_GPL(uisctrl_register_req_handler_ex); int -uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid) +uisctrl_unregister_req_handler_ex(uuid_le switch_uuid) { int rc = 0; /* assume failure */ - LOGINF("type=%pUL.\n", &switchTypeGuid); - if (req_handler_del(switchTypeGuid) < 0) { + LOGINF("type=%pUL.\n", &switch_uuid); + if (req_handler_del(switch_uuid) < 0) { LOGERR("failed to remove %pUL from server list\n", - &switchTypeGuid); + &switch_uuid); goto Away; } atomic_dec(&uisutils_registered_services); rc = 1; /* success */ Away: if (!rc) - LOGERR("failed to unregister type %pUL.\n", &switchTypeGuid); + LOGERR("failed to unregister type %pUL.\n", &switch_uuid); return rc; } EXPORT_SYMBOL_GPL(uisctrl_unregister_req_handler_ex); -- GitLab From 99c4c5ae69e01976a2541961a2200b570d153f28 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:58 -0400 Subject: [PATCH 0255/9457] staging: unisys: remove uislib_server_inject_add/del_vnic() prototypes These functions contain CamelCase names but are not used. Delete the prototypes from uisutils.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index ea8708b078ec..1520c8dcbf48 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -132,11 +132,6 @@ unsigned char *util_map_virt(struct phys_info *sg); void util_unmap_virt(struct phys_info *sg); unsigned char *util_map_virt_atomic(struct phys_info *sg); void util_unmap_virt_atomic(void *buf); -int uislib_server_inject_add_vnic(u32 switchNo, u32 BusNo, u32 numIntPorts, - u32 numExtPorts, u8 *pmac[ETH_ALEN], - pCHANNEL_HEADER **chan); -void uislib_server_inject_del_vnic(u32 switchNo, u32 busNo, u32 numIntPorts, - u32 numExtPorts); int uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, u64 channelAddr, ulong nChannelBytes); int uislib_client_inject_del_bus(u32 busNo); -- GitLab From e1242538b1d049e97ee975da79a461bc297d9992 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:08:59 -0400 Subject: [PATCH 0256/9457] staging: unisys: Fix CamelCase in uislib_client_inject_add_bus() Fix CamelCase names: busNo => bus_no instGuid => inst_uuid channelAddr => channel_addr nChannelBytes => n_channel_bytes Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 23 ++++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 1520c8dcbf48..1902244f662f 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -132,8 +132,8 @@ unsigned char *util_map_virt(struct phys_info *sg); void util_unmap_virt(struct phys_info *sg); unsigned char *util_map_virt_atomic(struct phys_info *sg); void util_unmap_virt_atomic(void *buf); -int uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, - u64 channelAddr, ulong nChannelBytes); +int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, + u64 channel_addr, ulong n_channel_bytes); int uislib_client_inject_del_bus(u32 busNo); int uislib_client_inject_add_vhba(u32 busNo, u32 devNo, diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 0ae008bfa199..2a2e68bfc905 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -822,14 +822,14 @@ delete_device_glue(u32 busNo, u32 devNo) } int -uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, - u64 channelAddr, ulong nChannelBytes) +uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, + u64 channel_addr, ulong n_channel_bytes) { CONTROLVM_MESSAGE msg; - LOGINF("enter busNo=0x%x\n", busNo); + LOGINF("enter busNo=0x%x\n", bus_no); /* step 0: init the chipset */ - POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); if (!chipset_inited) { /* step: initialize the chipset */ @@ -848,24 +848,25 @@ uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid, return 0; } LOGINF("chipset initialized\n"); - POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, busNo, + POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); } /* step 1: create a bus */ - POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_WARNING); + POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, + POSTCODE_SEVERITY_WARNING); init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); - msg.cmd.createBus.busNo = busNo; + msg.cmd.createBus.busNo = bus_no; msg.cmd.createBus.deviceCount = 23; /* devNo+1; */ - msg.cmd.createBus.channelAddr = channelAddr; - msg.cmd.createBus.channelBytes = nChannelBytes; + msg.cmd.createBus.channelAddr = channel_addr; + msg.cmd.createBus.channelBytes = n_channel_bytes; if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("create_bus failed.\n"); - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo, + POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); return 1; } -- GitLab From ac15ba594e9b1344119130017287878410653231 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:00 -0400 Subject: [PATCH 0257/9457] staging: unisys: fix CamelCase in uislib_client_inject_del_bus() Fix CamelCase names: busNo => bus_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 1902244f662f..4610b4ffca29 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -134,7 +134,7 @@ unsigned char *util_map_virt_atomic(struct phys_info *sg); void util_unmap_virt_atomic(void *buf); int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, u64 channel_addr, ulong n_channel_bytes); -int uislib_client_inject_del_bus(u32 busNo); +int uislib_client_inject_del_bus(u32 bus_no); int uislib_client_inject_add_vhba(u32 busNo, u32 devNo, u64 phys_chan_addr, u32 chan_bytes, diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 2a2e68bfc905..4d85a327fb7c 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -874,9 +874,9 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus); int -uislib_client_inject_del_bus(u32 busNo) +uislib_client_inject_del_bus(u32 bus_no) { - return delete_bus_glue(busNo); + return delete_bus_glue(bus_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus); -- GitLab From 3d3b7154a38141886b945f8b93a3316ba414a0de Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:01 -0400 Subject: [PATCH 0258/9457] staging: unisys: Fix CamelCase in uislib_client_inject_add_vhba() Clean up CamelCase names: busNo => bus_no devNo => dev_no instGuid => inst_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 4610b4ffca29..8ed82c4bd6e7 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -136,9 +136,9 @@ int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, u64 channel_addr, ulong n_channel_bytes); int uislib_client_inject_del_bus(u32 bus_no); -int uislib_client_inject_add_vhba(u32 busNo, u32 devNo, +int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, + int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); int uislib_client_inject_pause_vhba(u32 busNo, u32 devNo); int uislib_client_inject_resume_vhba(u32 busNo, u32 devNo); diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 4d85a327fb7c..9f62462f9966 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -922,19 +922,19 @@ uislib_client_inject_resume_vhba(u32 busNo, u32 devNo) EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba); int -uislib_client_inject_add_vhba(u32 busNo, u32 devNo, +uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, + int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr) { CONTROLVM_MESSAGE msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo); + LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VHBA device on the * bus */ - POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); @@ -943,9 +943,9 @@ uislib_client_inject_add_vhba(u32 busNo, u32 devNo, * need to be ioremap()ed */ msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = instGuid; + msg.cmd.createDevice.busNo = bus_no; + msg.cmd.createDevice.devNo = dev_no; + msg.cmd.createDevice.devInstGuid = inst_uuid; if (intr) msg.cmd.createDevice.intr = *intr; else @@ -963,11 +963,11 @@ uislib_client_inject_add_vhba(u32 busNo, u32 devNo, msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA create_device failed.\n"); - POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, devNo, busNo, + POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); return 1; } -- GitLab From 062d312d81acd4e9ea5a8d3d7e3f6945b2b7ecd9 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:02 -0400 Subject: [PATCH 0259/9457] staging: unisys: Fix CamelCase in uislib_client_inject_pause_vhba() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 8ed82c4bd6e7..27dc876d0316 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -140,7 +140,7 @@ int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); -int uislib_client_inject_pause_vhba(u32 busNo, u32 devNo); +int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vhba(u32 busNo, u32 devNo); int uislib_client_inject_del_vhba(u32 busNo, u32 devNo); int uislib_client_inject_add_vnic(u32 busNo, u32 devNo, diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 9f62462f9966..132126944acf 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -881,19 +881,19 @@ uislib_client_inject_del_bus(u32 bus_no) EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus); int -uislib_client_inject_pause_vhba(u32 busNo, u32 devNo) +uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) { CONTROLVM_MESSAGE msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; + msg.cmd.deviceChangeState.busNo = bus_no; + msg.cmd.deviceChangeState.devNo = dev_no; msg.cmd.deviceChangeState.state = SegmentStateStandby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return rc; } return 0; -- GitLab From ae47a51bfba0a848a15d580aa68ec7eeda377ddf Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:03 -0400 Subject: [PATCH 0260/9457] staging: unisys: Fix CamelCase in uislib_client_inject_resume_vhba() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 27dc876d0316..408dca2d9d30 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -141,7 +141,7 @@ int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_resume_vhba(u32 busNo, u32 devNo); +int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_del_vhba(u32 busNo, u32 devNo); int uislib_client_inject_add_vnic(u32 busNo, u32 devNo, u64 phys_chan_addr, u32 chan_bytes, diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 132126944acf..96e38bfcc1f8 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -901,19 +901,19 @@ uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba); int -uislib_client_inject_resume_vhba(u32 busNo, u32 devNo) +uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) { CONTROLVM_MESSAGE msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; + msg.cmd.deviceChangeState.busNo = bus_no; + msg.cmd.deviceChangeState.devNo = dev_no; msg.cmd.deviceChangeState.state = SegmentStateRunning; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return rc; } return 0; -- GitLab From 6bc962ac9390c185496c9d60b45415b2dc7dc817 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:04 -0400 Subject: [PATCH 0261/9457] staging: unisys: Fix CamelCase in uislib_client_inject_del_vhba() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 408dca2d9d30..3a232bebed6b 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -142,7 +142,7 @@ int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, struct InterruptInfo *intr); int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_del_vhba(u32 busNo, u32 devNo); +int uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_add_vnic(u32 busNo, u32 devNo, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le instGuid, diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 96e38bfcc1f8..5b897a9bb3e7 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -974,9 +974,9 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba); int -uislib_client_inject_del_vhba(u32 busNo, u32 devNo) +uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no) { - return delete_device_glue(busNo, devNo); + return delete_device_glue(bus_no, dev_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba); -- GitLab From 94a887da6fe4cbe253493099895f939003c4c372 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:05 -0400 Subject: [PATCH 0262/9457] staging: unisys: Fix CamelCase in uislib_client_inject_add_vnic() Fix CamelCase names: busNo => bus_no devNo => dev_no instGuid => inst_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 3a232bebed6b..cbfbd9eac5a5 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -143,9 +143,9 @@ int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no); -int uislib_client_inject_add_vnic(u32 busNo, u32 devNo, +int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, + int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); int uislib_client_inject_pause_vnic(u32 busNo, u32 devNo); int uislib_client_inject_resume_vnic(u32 busNo, u32 devNo); diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 5b897a9bb3e7..368b366bb476 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -981,19 +981,19 @@ uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no) EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba); int -uislib_client_inject_add_vnic(u32 busNo, u32 devNo, +uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, - int is_test_addr, uuid_le instGuid, + int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr) { CONTROLVM_MESSAGE msg; - LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo); + LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - * Verify it still exists step 2: create the VNIC device on the * bus */ - POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); @@ -1002,9 +1002,9 @@ uislib_client_inject_add_vnic(u32 busNo, u32 devNo, * need to be ioremap()ed */ msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = instGuid; + msg.cmd.createDevice.busNo = bus_no; + msg.cmd.createDevice.devNo = dev_no; + msg.cmd.createDevice.devInstGuid = inst_uuid; if (intr) msg.cmd.createDevice.intr = *intr; else @@ -1022,12 +1022,12 @@ uislib_client_inject_add_vnic(u32 busNo, u32 devNo, msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC create_device failed.\n"); - POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, POSTCODE_SEVERITY_ERR); return 0; } - POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, devNo, busNo, + POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, dev_no, bus_no, POSTCODE_SEVERITY_INFO); return 1; } -- GitLab From 68a4b12c9293104a7c65167888125412b441fc8b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:06 -0400 Subject: [PATCH 0263/9457] staging: unisys: Fix CamelCase in uislib_client_inject_pause_vnic() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index cbfbd9eac5a5..f08d51f392b0 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -147,7 +147,7 @@ int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); -int uislib_client_inject_pause_vnic(u32 busNo, u32 devNo); +int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vnic(u32 busNo, u32 devNo); int uislib_client_inject_del_vnic(u32 busNo, u32 devNo); #ifdef STORAGE_CHANNEL diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 368b366bb476..da1887d552f3 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1034,19 +1034,19 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic); int -uislib_client_inject_pause_vnic(u32 busNo, u32 devNo) +uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) { CONTROLVM_MESSAGE msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; + msg.cmd.deviceChangeState.busNo = bus_no; + msg.cmd.deviceChangeState.devNo = dev_no; msg.cmd.deviceChangeState.state = SegmentStateStandby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return -1; } return 0; -- GitLab From 3fe7cec47780878f5c44723097bb842b67d69dae Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:07 -0400 Subject: [PATCH 0264/9457] staging: unisys: Fix CamelCase in uislib_client_inject_resume_vnic() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index f08d51f392b0..28e6f1f17615 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -148,7 +148,7 @@ int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, int is_test_addr, uuid_le inst_uuid, struct InterruptInfo *intr); int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); -int uislib_client_inject_resume_vnic(u32 busNo, u32 devNo); +int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no); int uislib_client_inject_del_vnic(u32 busNo, u32 devNo); #ifdef STORAGE_CHANNEL u64 uislib_storage_channel(int client_id); diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index da1887d552f3..09c71637778f 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1054,19 +1054,19 @@ uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic); int -uislib_client_inject_resume_vnic(u32 busNo, u32 devNo) +uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) { CONTROLVM_MESSAGE msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = busNo; - msg.cmd.deviceChangeState.devNo = devNo; + msg.cmd.deviceChangeState.busNo = bus_no; + msg.cmd.deviceChangeState.devNo = dev_no; msg.cmd.deviceChangeState.state = SegmentStateRunning; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n", - busNo, devNo); + bus_no, dev_no); return -1; } return 0; -- GitLab From bdb628d080e02936fc8e52d577f55cde0dfb4b22 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:08 -0400 Subject: [PATCH 0265/9457] staging: unisys: fix CamelCase in uislib_client_inject_del_vnic() Fix CamelCase names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 28e6f1f17615..54427a2d12af 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -149,7 +149,7 @@ int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, struct InterruptInfo *intr); int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no); -int uislib_client_inject_del_vnic(u32 busNo, u32 devNo); +int uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no); #ifdef STORAGE_CHANNEL u64 uislib_storage_channel(int client_id); #endif diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 09c71637778f..3d32c43e68e9 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1075,9 +1075,9 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic); int -uislib_client_inject_del_vnic(u32 busNo, u32 devNo) +uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no) { - return delete_device_glue(busNo, devNo); + return delete_device_glue(bus_no, dev_no); } EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic); -- GitLab From c12ad837bf45c45f9c9583dd0176028722cbf2c1 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:09 -0400 Subject: [PATCH 0266/9457] staging: unisys: fix CamelCase struct name PciId Fix CamelCase name: PciId => pci_id Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 2 +- drivers/staging/unisys/include/uisqueue.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index d08c198e0de3..8c32be291aaa 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -148,7 +148,7 @@ struct InterruptInfo { u8 reserved[3]; /* Natural alignment purposes */ }; -struct PciId { +struct pci_id { u16 Domain; u8 Bus; u8 Slot; diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 04f51e66ebf0..8c307cf7ec23 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -118,7 +118,7 @@ struct extport_info { */ struct switch_info *swtch; - struct PciId pci_id; + struct pci_id pci_id; char name[MAX_NAME_SIZE_UISQUEUE]; union { struct vhba_wwnn wwnn; -- GitLab From 4eddbf13902ad72123898830876ca5039560f510 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:10 -0400 Subject: [PATCH 0267/9457] staging: unisys: fix CamelCase name for struct InterruptInfo Fix CamelCase names: InterruptInfo => irq_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 4 ++-- drivers/staging/unisys/include/uisqueue.h | 6 +++--- drivers/staging/unisys/include/uisutils.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 10 +++++----- drivers/staging/unisys/virthba/virthba.c | 2 +- drivers/staging/unisys/virtpci/virtpci.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset.h | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 8c32be291aaa..cbe152f8ea27 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -119,7 +119,7 @@ typedef enum { } CONTROLVM_ID; -struct InterruptInfo { +struct irq_info { /**< specifies interrupt info. It is used to send interrupts * for this channel. The peer at the end of this channel * who has registered an interrupt (using recv fields @@ -298,7 +298,7 @@ typedef struct _CONTROLVM_PACKET_DEVICE_CREATE { u64 channelBytes; /**< specifies size of the channel in bytes */ uuid_le dataTypeGuid;/**< specifies format of data in channel */ uuid_le devInstGuid; /**< instance guid for the device */ - struct InterruptInfo intr; /**< specifies interrupt information */ + struct irq_info intr; /**< specifies interrupt information */ } CONTROLVM_PACKET_DEVICE_CREATE; /* for CONTROLVM_DEVICE_CREATE */ typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 8c307cf7ec23..cde29a22a7f4 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -132,7 +132,7 @@ struct device_info { u64 channel_bytes; uuid_le channel_uuid; uuid_le instance_uuid; - struct InterruptInfo intr; + struct irq_info intr; struct switch_info *swtch; char devid[30]; /* "vbus:dev" */ u16 polling; @@ -226,7 +226,7 @@ struct add_virt_iopart { * for DMA, for ex. */ u64 recv_bus_irq_handle; /* used to register to receive * bus level interrupts. */ - struct InterruptInfo intr; /* contains recv & send + struct irq_info intr; /* contains recv & send * interrupt info */ /* recvInterruptHandle is used to register to receive * interrupts on the data channel. Used by GuestLinux/Windows @@ -364,7 +364,7 @@ struct add_virt_guestpart { u32 bus_no; /* bus number for the operation */ u32 device_no; /* number of device on the bus */ uuid_le instance_uuid; /* instance guid for device */ - struct InterruptInfo intr; /* recv/send interrupt info */ + struct irq_info intr; /* recv/send interrupt info */ /* recvInterruptHandle contains info needed in order to * register to receive interrupts on the data channel. * sendInterruptHandle contains handle which is provided to diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 54427a2d12af..d6859c68477d 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -139,14 +139,14 @@ int uislib_client_inject_del_bus(u32 bus_no); int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, - struct InterruptInfo *intr); + struct irq_info *intr); int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no); int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, - struct InterruptInfo *intr); + struct irq_info *intr); int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no); int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no); int uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no); diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 3d32c43e68e9..b1f6c6ef801b 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -925,7 +925,7 @@ int uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, - struct InterruptInfo *intr) + struct irq_info *intr) { CONTROLVM_MESSAGE msg; @@ -950,7 +950,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, msg.cmd.createDevice.intr = *intr; else memset(&msg.cmd.createDevice.intr, 0, - sizeof(struct InterruptInfo)); + sizeof(struct irq_info)); msg.cmd.createDevice.channelAddr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", @@ -984,7 +984,7 @@ int uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, u64 phys_chan_addr, u32 chan_bytes, int is_test_addr, uuid_le inst_uuid, - struct InterruptInfo *intr) + struct irq_info *intr) { CONTROLVM_MESSAGE msg; @@ -1009,7 +1009,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, msg.cmd.createDevice.intr = *intr; else memset(&msg.cmd.createDevice.intr, 0, - sizeof(struct InterruptInfo)); + sizeof(struct irq_info)); msg.cmd.createDevice.channelAddr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", @@ -1106,7 +1106,7 @@ uislib_client_add_vnic(u32 busNo) msg.cmd.createDevice.busNo = busNo; msg.cmd.createDevice.devNo = devNo; msg.cmd.createDevice.devInstGuid = NULL_UUID_LE; - memset(&msg.cmd.createDevice.intr, 0, sizeof(struct InterruptInfo)); + memset(&msg.cmd.createDevice.intr, 0, sizeof(struct irq_info)); msg.cmd.createDevice.channelAddr = PhysicalDataChan; msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE; msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 938e2c82c1ab..e4130c9714fc 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -172,7 +172,7 @@ struct virthba_info { struct virtpci_dev *virtpcidev; struct list_head dev_info_list; struct chaninfo chinfo; - struct InterruptInfo intr; /* use recvInterrupt info to receive + struct irq_info intr; /* use recvInterrupt info to receive interrupts when IOs complete */ int interrupt_vector; struct scsipending pending[MAX_PENDING_REQUESTS]; /* Tracks the requests diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index 6e26956c79f4..8a0d43947596 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -60,7 +60,7 @@ struct virtpci_dev { unsigned short device; /* device id for device */ u32 busNo; /* number of bus on which device exists */ u32 deviceNo; /* device's number on the bus */ - struct InterruptInfo intr; /* interrupt info */ + struct irq_info intr; /* interrupt info */ struct device generic_dev; /* generic device */ union { struct scsi_adap_info scsi; diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 2bf2e2f368ef..af35728a7e1d 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -63,7 +63,7 @@ typedef enum { typedef struct { VISORCHIPSET_ADDRESSTYPE addrType; HOSTADDRESS channelAddr; - struct InterruptInfo intr; + struct irq_info intr; u64 nChannelBytes; uuid_le channelTypeGuid; uuid_le channelInstGuid; -- GitLab From 0e2906ac9f15b5f87145b211b88696e47334232f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:11 -0400 Subject: [PATCH 0268/9457] staging: unisys: remove DEDICATED_SWITCH macro Nobody is using this macro anymore so remove it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index cde29a22a7f4..19c8d5d7dc8b 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -169,9 +169,6 @@ struct bus_info { * by IOVM; 0 otherwise... */ }; -#define DEDICATED_SWITCH(s) ((s->extPortCount == 1) && \ - (s->intPortCount == 1)) - struct sn_list_entry { struct uisscsi_dest pdest; /* scsi bus, target, lun for * phys disk */ -- GitLab From 51121ffc8b084adeed670fb4cb42a74a30e45d81 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:12 -0400 Subject: [PATCH 0269/9457] staging: unisys: fix typedef of ULTRA_VBUS_CHANNEL_PROTOCOL Get rid of the typedef ULTRA_VBUS_CHANNEL_PROTOCOL, in favor of the name struct ultra_vbus_channel_protocol. This change finishes the warnings clean up for include/uisqueue.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/vbuschannel.h | 8 ++++---- drivers/staging/unisys/include/uisqueue.h | 2 +- drivers/staging/unisys/virtpci/virtpci.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 1231c454176f..20e0753af945 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -47,7 +47,7 @@ static const uuid_le UltraVbusChannelProtocolGuid = (ULTRA_check_channel_client(pChannel, \ UltraVbusChannelProtocolGuid, \ "vbus", \ - sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \ + sizeof(struct ultra_vbus_channel_protocol),\ ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE, \ __FILE__, __LINE__, logCtx)) @@ -55,7 +55,7 @@ static const uuid_le UltraVbusChannelProtocolGuid = #define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes, logCtx) \ (ULTRA_check_channel_server(UltraVbusChannelProtocolGuid, \ "vbus", \ - sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \ + sizeof(struct ultra_vbus_channel_protocol),\ actualBytes, \ __FILE__, __LINE__, logCtx)) @@ -75,7 +75,7 @@ typedef struct _ULTRA_VBUS_HEADERINFO { u8 reserved[104]; } ULTRA_VBUS_HEADERINFO; -typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL { +struct ultra_vbus_channel_protocol { ULTRA_CHANNEL_PROTOCOL ChannelHeader; /* initialized by server */ ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */ /* the remainder of this channel is filled in by the client */ @@ -86,7 +86,7 @@ typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL { ULTRA_VBUS_DEVICEINFO DevInfo[0]; /* describes client device and * driver for */ /* each device on the bus */ -} ULTRA_VBUS_CHANNEL_PROTOCOL; +}; #define VBUS_CH_SIZE_EXACT(MAXDEVICES) \ (sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL) + ((MAXDEVICES) * \ diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 19c8d5d7dc8b..6e0ec05a4a43 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -158,7 +158,7 @@ struct bus_info { struct device_info **device; u64 guest_handle, recv_bus_irq_handle; uuid_le bus_inst_uuid; - ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *bus_channel; + struct ultra_vbus_channel_protocol __iomem *bus_channel; int bus_channel_bytes; struct proc_dir_entry *proc_dir; /* proc/uislib/vbus/ */ struct proc_dir_entry *proc_info; /* proc/uislib/vbus//info */ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 91f939570b38..83f1a00c6bed 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -186,7 +186,7 @@ int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */ -static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, +static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, ULTRA_VBUS_DEVICEINFO *info) { int off; @@ -205,7 +205,7 @@ static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */ -static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, +static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, ULTRA_VBUS_DEVICEINFO *info) { int off; @@ -227,7 +227,7 @@ static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, * ULTRA_VBUS_CHANNEL_PROTOCOL.DevInfo[]. */ static int -write_vbus_devInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan, +write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, ULTRA_VBUS_DEVICEINFO *info, int devix) { int off; -- GitLab From f42aea3cb254ea15bc48df24964c446a4caefc2f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:13 -0400 Subject: [PATCH 0270/9457] staging: unisys: Fix VMCALL_IO_CONTROLVM_ADDR_PARAMS structure Remove the typedef from VMCALL_IO_CONTROLVM_ADDR_PARAMS and switch to use struct vmcall_io_controlvm_addr_params. Fix the CamelCase names: ChannelAddress => address ChannelBytes => channel_bytes Unused => unused Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/vmcallinterface.h | 10 +++++----- drivers/staging/unisys/include/uisutils.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index 0b5b5626af5a..4eeb40184c84 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -113,15 +113,15 @@ typedef struct phys_info IO_DATA_STRUCTURE; /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */ -typedef struct _VMCALL_IO_CONTROLVM_ADDR_PARAMS { +struct vmcall_io_controlvm_addr_params { /* The Guest-relative physical address of the ControlVm channel. * This VMCall fills this in with the appropriate address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ + u64 address; /* contents provided by this VMCALL (OUT) */ /* the size of the ControlVm channel in bytes This VMCall fills this * in with the appropriate address. */ - u32 ChannelBytes; /* contents provided by this VMCALL (OUT) */ - u8 Unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ -} VMCALL_IO_CONTROLVM_ADDR_PARAMS; + u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ + u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index d6859c68477d..60c7bce46018 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -220,15 +220,15 @@ unsigned int uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, static inline unsigned int issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) { - VMCALL_IO_CONTROLVM_ADDR_PARAMS params; + struct vmcall_io_controlvm_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) { - *control_addr = params.ChannelAddress; - *control_bytes = params.ChannelBytes; + *control_addr = params.address; + *control_bytes = params.channel_bytes; } return result; } -- GitLab From 3dbf7b739f781f4195e4ac87c11bb9f250118682 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:14 -0400 Subject: [PATCH 0271/9457] staging: unisys: Fix VMCALL_IO_DIAG_ADDR_PARAMS Remove the typedef from VMCALL_IO_DIAG_ADDR_PARAMS and use the name struct vmcall_io_diag_addr_params instead. Fix CamelCase member names: ChannelAddress => address Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/vmcallinterface.h | 6 +++--- drivers/staging/unisys/include/uisutils.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index 4eeb40184c84..a7830cac9b8c 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -130,11 +130,11 @@ struct vmcall_io_controlvm_addr_params { /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_DIAG_ADDR interface */ -typedef struct _VMCALL_IO_DIAG_ADDR_PARAMS { +struct vmcall_io_diag_addr_params { /* The Guest-relative physical address of the diagnostic channel. * This VMCall fills this in with the appropriate address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ -} VMCALL_IO_DIAG_ADDR_PARAMS; + u64 address; /* contents provided by this VMCALL (OUT) */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 60c7bce46018..2ccf155b08cd 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -235,14 +235,14 @@ issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) static inline unsigned int issue_vmcall_io_diag_addr(u64 *diag_channel_addr) { - VMCALL_IO_DIAG_ADDR_PARAMS params; + struct vmcall_io_diag_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_DIAG_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) - *diag_channel_addr = params.ChannelAddress; + *diag_channel_addr = params.address; return result; } -- GitLab From 0520cfb1f6bbd47cb80908e1b589218159b52e8d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:15 -0400 Subject: [PATCH 0272/9457] staging: unisys: fix VMCALL_IO_VISORSERIAL_ADDR_PARAMS Remove the typedef from VMCALL_IO_VISORSERIAL_ADDR_PARAMS and use the name struct vmcall_io_visorserial_addr_params instead. Fix CamelCase member names: ChannelAddress => address Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/vmcallinterface.h | 6 +++--- drivers/staging/unisys/include/uisutils.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index a7830cac9b8c..c9dc51896287 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -143,12 +143,12 @@ struct vmcall_io_diag_addr_params { /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ #pragma pack(push, 1) /* Parameters to VMCALL_IO_VISORSERIAL_ADDR interface */ -typedef struct _VMCALL_IO_VISORSERIAL_ADDR_PARAMS { +struct vmcall_io_visorserial_addr_params { /* The Guest-relative physical address of the serial console * channel. This VMCall fills this in with the appropriate * address. */ - u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */ -} VMCALL_IO_VISORSERIAL_ADDR_PARAMS; + u64 address; /* contents provided by this VMCALL (OUT) */ +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 2ccf155b08cd..d6e8983be4c6 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -248,14 +248,14 @@ static inline unsigned int issue_vmcall_io_diag_addr(u64 *diag_channel_addr) static inline unsigned int issue_vmcall_io_visorserial_addr(u64 *channel_addr) { - VMCALL_IO_VISORSERIAL_ADDR_PARAMS params; + struct vmcall_io_visorserial_addr_params params; int result = VMCALL_SUCCESS; u64 physaddr; physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_IO_VISORSERIAL_ADDR, physaddr, result); if (VMCALL_SUCCESSFUL(result)) - *channel_addr = params.ChannelAddress; + *channel_addr = params.address; return result; } -- GitLab From 3301335fc8228d50e92d0715a48cfcf22e7a8dfc Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:16 -0400 Subject: [PATCH 0273/9457] staging: unisys: remove volatile from struct log_info_t There's no need for last_cycles to be declared volatile. Take that out. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index d6e8983be4c6..cf9423e46c48 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -279,7 +279,7 @@ static inline s64 issue_vmcall_measurement_do_nothing(void) } struct log_info_t { - volatile unsigned long long last_cycles; + unsigned long long last_cycles; unsigned long long delta_sum[64]; unsigned long long delta_cnt[64]; unsigned long long max_delta[64]; -- GitLab From a09ad889f5805e77ec1b42508d5706666304b44a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:17 -0400 Subject: [PATCH 0274/9457] staging: unisys: Fix VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS Get rid of the typedef for VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, and use the name struct vmcall_channel_version_mismatch_params instead. Fix CamelCase member names: ChannelName => chname ItemName => item_name SourceFileName => file_name SourceLineNumber => line_no And get rid of the lengthof macro in issue_vmcall_channel_mismatch(). Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/vmcallinterface.h | 12 ++++++------ drivers/staging/unisys/include/uisutils.h | 19 +++++++------------ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index c9dc51896287..7750086e5bb3 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -154,14 +154,14 @@ struct vmcall_io_visorserial_addr_params { /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ /* Parameters to VMCALL_CHANNEL_MISMATCH interface */ -typedef struct _VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS { - u8 ChannelName[32]; /* Null terminated string giving name of channel +struct vmcall_channel_version_mismatch_params { + u8 chname[32]; /* Null terminated string giving name of channel * (IN) */ - u8 ItemName[32]; /* Null terminated string giving name of + u8 item_name[32]; /* Null terminated string giving name of * mismatched item (IN) */ - u32 SourceLineNumber; /* line# where invoked. (IN) */ - u8 SourceFileName[36]; /* source code where invoked - Null terminated + u32 line_no; /* line# where invoked. (IN) */ + u8 file_name[36]; /* source code where invoked - Null terminated * string (IN) */ -} VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS; +}; #endif /* __IOMONINTF_H__ */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index cf9423e46c48..5f249dc55c68 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -298,28 +298,23 @@ static inline unsigned int issue_vmcall_channel_mismatch(const char *chname, const char *item_name, u32 line_no, const char *path_n_fn) { - VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS params; + struct vmcall_channel_version_mismatch_params params; int result = VMCALL_SUCCESS; u64 physaddr; char *last_slash = NULL; - strlcpy(params.ChannelName, chname, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ChannelName)); - strlcpy(params.ItemName, item_name, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ItemName)); - params.SourceLineNumber = line_no; + strlcpy(params.chname, chname, sizeof(params.chname)); + strlcpy(params.item_name, item_name, sizeof(params.item_name)); + params.line_no = line_no; last_slash = strrchr(path_n_fn, '/'); if (last_slash != NULL) { last_slash++; - strlcpy(params.SourceFileName, last_slash, - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, - SourceFileName)); + strlcpy(params.file_name, last_slash, sizeof(params.file_name)); } else - strlcpy(params.SourceFileName, + strlcpy(params.file_name, "Cannot determine source filename", - lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, - SourceFileName)); + sizeof(params.file_name)); physaddr = virt_to_phys(¶ms); ISSUE_IO_VMCALL(VMCALL_CHANNEL_VERSION_MISMATCH, physaddr, result); -- GitLab From 32b6b291871ef333ae49ada031ee3c5a407a0a94 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:18 -0400 Subject: [PATCH 0275/9457] staging: unisys: Fix ULTRA_VBUS_DEVICEINFO Remove the typedef from ULTRA_VBUS_DEVICEINFO and use struct ultra_vbus_deviceinfo instead. Fix CamelCase member names: devType => devtype drvName => drvname infoStrings => infostrs Fix indentation on function definitions that were affected by the structure's name change. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/vbuschannel.h | 13 +++++----- .../common-spar/include/vbusdeviceinfo.h | 24 +++++++++---------- drivers/staging/unisys/include/uisutils.h | 22 ++++++++--------- drivers/staging/unisys/include/vbushelper.h | 16 ++++++------- drivers/staging/unisys/uislib/uisutils.c | 15 ++++++------ drivers/staging/unisys/virtpci/virtpci.c | 12 +++++----- .../unisys/visorchipset/visorchipset.h | 4 ++-- .../unisys/visorchipset/visorchipset_main.c | 4 ++-- 8 files changed, 54 insertions(+), 56 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 20e0753af945..5b854243bcaf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -79,13 +79,12 @@ struct ultra_vbus_channel_protocol { ULTRA_CHANNEL_PROTOCOL ChannelHeader; /* initialized by server */ ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */ /* the remainder of this channel is filled in by the client */ - ULTRA_VBUS_DEVICEINFO ChpInfo; /* describes client chipset device and - * driver */ - ULTRA_VBUS_DEVICEINFO BusInfo; /* describes client bus device and - * driver */ - ULTRA_VBUS_DEVICEINFO DevInfo[0]; /* describes client device and - * driver for */ - /* each device on the bus */ + struct ultra_vbus_deviceinfo ChpInfo; + /* describes client chipset device and driver */ + struct ultra_vbus_deviceinfo BusInfo; + /* describes client bus device and driver */ + struct ultra_vbus_deviceinfo DevInfo[0]; + /* describes client device and driver for each device on the bus */ }; #define VBUS_CH_SIZE_EXACT(MAXDEVICES) \ diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 3bbdc2bb7ebf..f13dddc1b5c8 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -25,13 +25,13 @@ * It is filled in by the client side to provide info about the device * and driver from the client's perspective. */ -typedef struct _ULTRA_VBUS_DEVICEINFO { - u8 devType[16]; /* short string identifying the device type */ - u8 drvName[16]; /* driver .sys file name */ - u8 infoStrings[96]; /* sequence of tab-delimited id strings: */ +struct ultra_vbus_deviceinfo { + u8 devtype[16]; /* short string identifying the device type */ + u8 drvname[16]; /* driver .sys file name */ + u8 infostrs[96]; /* sequence of tab-delimited id strings: */ /* */ u8 reserved[128]; /* pad size to 256 bytes */ -} ULTRA_VBUS_DEVICEINFO; +}; #pragma pack(pop) @@ -147,15 +147,15 @@ vbuschannel_itoa(char *p, int remain, int num) * Returns the number of bytes written to

. */ static inline int -vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, +vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, char *p, int remain, int devix) { char *psrc; int nsrc, x, i, pad; int chars = 0; - psrc = &(devinfo->devType[0]); - nsrc = sizeof(devinfo->devType); + psrc = &(devinfo->devtype[0]); + nsrc = sizeof(devinfo->devtype); if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0) return 0; @@ -184,8 +184,8 @@ vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit driver name */ - psrc = &(devinfo->drvName[0]); - nsrc = sizeof(devinfo->drvName); + psrc = &(devinfo->drvname[0]); + nsrc = sizeof(devinfo->drvname); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; remain -= x; @@ -196,8 +196,8 @@ vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit strings */ - psrc = &(devinfo->infoStrings[0]); - nsrc = sizeof(devinfo->infoStrings); + psrc = &(devinfo->infostrs[0]); + nsrc = sizeof(devinfo->infostrs); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; remain -= x; diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 5f249dc55c68..b47543bef71b 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -114,18 +114,18 @@ int uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, char *format, ...); int uisctrl_register_req_handler(int type, void *fptr, - ULTRA_VBUS_DEVICEINFO *chipset_driver_info); + struct ultra_vbus_deviceinfo *chipset_driver_info); int uisctrl_register_req_handler_ex(uuid_le switch_guid, - const char *switch_type_name, - int (*fptr)(struct io_msgs *), - unsigned long min_channel_bytes, - int (*svr_channel_ok)(unsigned long - channel_bytes), - int (*svr_channel_init)(void *x, - unsigned char *client_str, - u32 client_str_len, - u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_driver_info); + const char *switch_type_name, + int (*fptr)(struct io_msgs *), + unsigned long min_channel_bytes, + int (*svr_channel_ok)(unsigned long + channel_bytes), + int (*svr_channel_init)(void *x, + unsigned char *client_str, + u32 client_str_len, + u64 bytes), + struct ultra_vbus_deviceinfo *chipset_driver_info); int uisctrl_unregister_req_handler_ex(uuid_le switch_uuid); unsigned char *util_map_virt(struct phys_info *sg); diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h index 1bde549ec0df..84abe5f99f54 100644 --- a/drivers/staging/unisys/include/vbushelper.h +++ b/drivers/staging/unisys/include/vbushelper.h @@ -26,19 +26,19 @@ #define TARGET_HOSTNAME "linuxguest" static inline void bus_device_info_init( - ULTRA_VBUS_DEVICEINFO * bus_device_info_ptr, + struct ultra_vbus_deviceinfo *bus_device_info_ptr, const char *dev_type, const char *drv_name, const char *ver, const char *ver_tag) { - memset(bus_device_info_ptr, 0, sizeof(ULTRA_VBUS_DEVICEINFO)); - snprintf(bus_device_info_ptr->devType, - sizeof(bus_device_info_ptr->devType), + memset(bus_device_info_ptr, 0, sizeof(struct ultra_vbus_deviceinfo)); + snprintf(bus_device_info_ptr->devtype, + sizeof(bus_device_info_ptr->devtype), "%s", (dev_type) ? dev_type : "unknownType"); - snprintf(bus_device_info_ptr->drvName, - sizeof(bus_device_info_ptr->drvName), + snprintf(bus_device_info_ptr->drvname, + sizeof(bus_device_info_ptr->drvname), "%s", (drv_name) ? drv_name : "unknownDriver"); - snprintf(bus_device_info_ptr->infoStrings, - sizeof(bus_device_info_ptr->infoStrings), "%s\t%s\t%s", + snprintf(bus_device_info_ptr->infostrs, + sizeof(bus_device_info_ptr->infostrs), "%s\t%s\t%s", (ver) ? ver : "unknownVer", (ver_tag) ? ver_tag : "unknownVerTag", TARGET_HOSTNAME); diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 31f517aa141f..a8466e30c22a 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -75,7 +75,7 @@ EXPORT_SYMBOL_GPL(uisutil_add_proc_line_ex); int uisctrl_register_req_handler(int type, void *fptr, - ULTRA_VBUS_DEVICEINFO *chipset_driver_info) + struct ultra_vbus_deviceinfo *chipset_driver_info) { LOGINF("type = %d, fptr = 0x%p.\n", type, fptr); @@ -106,15 +106,14 @@ EXPORT_SYMBOL_GPL(uisctrl_register_req_handler); int uisctrl_register_req_handler_ex(uuid_le switch_uuid, - const char *switch_type_name, - int (*controlfunc)(struct io_msgs *), - unsigned long min_channel_bytes, - int (*server_channel_ok)(unsigned long - channel_bytes), - int (*server_channel_init)(void *x, + const char *switch_type_name, + int (*controlfunc)(struct io_msgs *), + unsigned long min_channel_bytes, + int (*server_channel_ok)(unsigned long channel_bytes), + int (*server_channel_init)(void *x, unsigned char *client_str, u32 client_str_len, u64 bytes), - ULTRA_VBUS_DEVICEINFO *chipset_driver_info) + struct ultra_vbus_deviceinfo *chipset_driver_info) { struct req_handler_info *pReqHandlerInfo; int rc = 0; /* assume failure */ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 83f1a00c6bed..73d4329f9a4a 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -137,7 +137,7 @@ static struct device virtpci_rootbus_device = { }; /* filled in with info about parent chipset driver when we register with it */ -static ULTRA_VBUS_DEVICEINFO Chipset_DriverInfo; +static struct ultra_vbus_deviceinfo Chipset_DriverInfo; static const struct sysfs_ops virtpci_driver_sysfs_ops = { .show = virtpci_driver_attr_show, @@ -152,7 +152,7 @@ static struct virtpci_dev *VpcidevListHead; static DEFINE_RWLOCK(VpcidevListLock); /* filled in with info about this driver, wrt it servicing client busses */ -static ULTRA_VBUS_DEVICEINFO Bus_DriverInfo; +static struct ultra_vbus_deviceinfo Bus_DriverInfo; /*****************************************************/ /* debugfs entries */ @@ -187,7 +187,7 @@ int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, - ULTRA_VBUS_DEVICEINFO *info) + struct ultra_vbus_deviceinfo *info) { int off; @@ -206,7 +206,7 @@ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, - ULTRA_VBUS_DEVICEINFO *info) + struct ultra_vbus_deviceinfo *info) { int off; @@ -228,7 +228,7 @@ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, */ static int write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, - ULTRA_VBUS_DEVICEINFO *info, int devix) + struct ultra_vbus_deviceinfo *info, int devix) { int off; @@ -760,7 +760,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, { struct device *vbus; void *pChan; - ULTRA_VBUS_DEVICEINFO devInfo; + struct ultra_vbus_deviceinfo devInfo; const char *stype; if (!dev) { diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index af35728a7e1d..23834765a468 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -254,7 +254,7 @@ typedef struct { void visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo); + struct ultra_vbus_deviceinfo *driverInfo); /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is @@ -265,7 +265,7 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, void visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo); + struct ultra_vbus_deviceinfo *driverInfo); typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (CONTROLVM_MESSAGE *msg, int status); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index e5df39554a1a..ce4e731a2e4a 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -587,7 +587,7 @@ clear_chipset_events(void) void visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo) + struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); if (notifiers == NULL) { @@ -611,7 +611,7 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server); void visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, - ULTRA_VBUS_DEVICEINFO *driverInfo) + struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); if (notifiers == NULL) { -- GitLab From e99454578a571f248a852180cb7560d45ed6a5dd Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:19 -0400 Subject: [PATCH 0276/9457] staging: unisys: remove old doxygen comments from timskmod.h Remove doxygen comments and fix what's left so it's still useful. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index b14494ff6c1b..98e8b20a44a0 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -71,7 +71,6 @@ /** Try to evaulate the provided expression, and do a RETINT(x) iff * the expression evaluates to < 0. - * @param x the expression to try */ #define ASSERT(cond) \ do { if (!(cond)) \ @@ -89,11 +88,6 @@ (void *)(p2) = SWAPPOINTERS_TEMP; \ } while (0) -/** - * @addtogroup driverlogging - * @{ - */ - #define PRINTKDRV(fmt, args...) LOGINF(fmt, ## args) #define TBDDRV(fmt, args...) LOGERR(fmt, ## args) #define HUHDRV(fmt, args...) LOGERR(fmt, ## args) @@ -114,8 +108,6 @@ #define INFODEVX(devno, fmt, args...) LOGINFDEVX(devno, fmt, ## args) #define DEBUGDEV(devname, fmt, args...) DBGINFDEV(devname, fmt, ## args) -/* @} */ - /** Verifies the consistency of your PRIVATEDEVICEDATA structure using * conventional "signature" fields: *

@@ -139,7 +131,7 @@ ((fd)->sig2 == fd)) /** Sleep for an indicated number of seconds (for use in kernel mode). - * @param x the number of seconds to sleep. + * x - the number of seconds to sleep. */ #define SLEEP(x) \ do { current->state = TASK_INTERRUPTIBLE; \ @@ -147,7 +139,7 @@ } while (0) /** Sleep for an indicated number of jiffies (for use in kernel mode). - * @param x the number of jiffies to sleep. + * x - the number of jiffies to sleep. */ #define SLEEPJIFFIES(x) \ do { current->state = TASK_INTERRUPTIBLE; \ -- GitLab From 38d1fd3d0e2bf9f91e9b018b05c3730a2a454ee8 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:20 -0400 Subject: [PATCH 0277/9457] staging: unisys: remove redundant max macro No need to have another max macro when the kernel has one already. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index 98e8b20a44a0..de11f440e1e3 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -146,10 +146,6 @@ schedule_timeout(x); \ } while (0) -#ifndef max -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#endif - static inline struct cdev *cdev_alloc_init(struct module *owner, const struct file_operations *fops) { -- GitLab From 9024db5584454b1b9b361f087e206611f8c4c55f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:21 -0400 Subject: [PATCH 0278/9457] staging: unisys: remove unused struct network_policy Nobody is using this structure, so remove it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 6e0ec05a4a43..e87f3cd1f55e 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -179,16 +179,6 @@ struct sn_list_entry { struct sn_list_entry *next; }; -struct network_policy { - u32 promiscuous:1; - u32 macassign:1; - u32 peerforwarding:1; - u32 nonotify:1; - u32 standby:1; - u32 callhome:2; - char ip_addr[30]; -}; - /* * IO messages sent to UisnicControlChanFunc & UissdControlChanFunc by * code that processes the ControlVm channel messages. -- GitLab From def249afb3beb07e6eb1cd9f8d5979c3dead1310 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:22 -0400 Subject: [PATCH 0279/9457] staging: unisys: remove unused fields from iopart structures The bus_no and dev_no fields in several of the iopart command parameter structures are unused. Remove them. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index e87f3cd1f55e..db9d2051ae2f 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -244,21 +244,15 @@ struct add_vdisk_iopart { struct uisscsi_dest pdest; /* scsi bus, target, lun for phys disk */ u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */ u32 serlen; /* length of serial num */ - u32 bus_no; - u32 dev_no; }; struct del_vdisk_iopart { void *chanptr; /* pointer to data channel */ struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ - u32 bus_no; - u32 dev_no; }; struct del_virt_iopart { void *chanptr; /* pointer to data channel */ - u32 bus_no; - u32 dev_no; }; struct det_virt_iopart { /* detach internal port */ -- GitLab From 96b38e0d5274735d193dd5d57c201ac6e0691e90 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 3 Oct 2014 14:09:23 -0400 Subject: [PATCH 0280/9457] staging: unisys: remove unused vmcall functions from uisutils.h Delete the issue_vmcall_measurement_do_nothing() and issue_vmcall_fatal() functions, because they are unused. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index b47543bef71b..677ed7e609af 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -269,15 +269,6 @@ static inline s64 issue_vmcall_query_guest_virtual_time_offset(void) return result; } -static inline s64 issue_vmcall_measurement_do_nothing(void) -{ - u64 result = VMCALL_SUCCESS; - u64 physaddr = 0; - - ISSUE_IO_VMCALL(VMCALL_MEASUREMENT_DO_NOTHING, physaddr, result); - return result; -} - struct log_info_t { unsigned long long last_cycles; unsigned long long delta_sum[64]; @@ -321,16 +312,6 @@ static inline unsigned int issue_vmcall_channel_mismatch(const char *chname, return result; } -static inline unsigned int issue_vmcall_fatal(void) -{ - int result = VMCALL_SUCCESS; - u64 physaddr = 0; - - ISSUE_IO_VMCALL(VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER, physaddr, - result); - return result; -} - #define UIS_DAEMONIZE(nam) void *uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln); #define UISCACHEALLOC(cur_pool) uislib_cache_alloc(cur_pool, __FILE__, __LINE__) -- GitLab From 682adec4d8c5f111b5a1cba6fb64b24607fe4362 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:39 +0530 Subject: [PATCH 0281/9457] staging: unisys: common-spar: include: channels: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- .../unisys/common-spar/include/channels/vbuschannel.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index b1dd73d1f42c..806d5b3bca48 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -594,7 +594,7 @@ struct uiscmdrsp_scsitaskmgmt { * For windows guests, this is a pointer to a location that a waiting * thread is testing to see if the taskmgmt command has completed. * When the rsp is received by guest, the thread receiving the - * response uses this to notify the the thread waiting for taskmgmt + * response uses this to notify the thread waiting for taskmgmt * command completion. Its value is preserved by iopart & returned * as is in the task mgmt rsp. */ void *notifyresult; @@ -641,7 +641,7 @@ struct uiscmdrsp_vdiskmgmt { * For windows guests, this is a pointer to a location that a waiting * thread is testing to see if the taskmgmt command has completed. * When the rsp is received by guest, the thread receiving the - * response uses this to notify the the thread waiting for taskmgmt + * response uses this to notify the thread waiting for taskmgmt * command completion. Its value is preserved by iopart & returned * as is in the task mgmt rsp. */ void *notifyresult; diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 5b854243bcaf..420b7d859522 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -67,11 +67,11 @@ typedef struct _ULTRA_VBUS_HEADERINFO { u32 devInfoCount; /* num of items in DevInfo member */ /* (this is the allocated size) */ u32 chpInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the ChpInfo struct (below) */ + /* to the ChpInfo struct (below) */ u32 busInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the BusInfo struct (below) */ + /* to the BusInfo struct (below) */ u32 devInfoByteOffset; /* byte offset from beginning of this struct */ - /* to the the DevInfo array (below) */ + /* to the DevInfo array (below) */ u8 reserved[104]; } ULTRA_VBUS_HEADERINFO; -- GitLab From 9b0a6292df615a62269e6849a02332d85fd3b52a Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:50 +0530 Subject: [PATCH 0282/9457] staging: unisys: virtpci: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 73d4329f9a4a..f782916cbf2b 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -752,7 +752,7 @@ static int virtpci_device_resume(struct device *dev) /* For a child device just created on a client bus, fill in * information about the driver that is controlling this device into - * the the appropriate slot within the vbus channel of the bus + * the appropriate slot within the vbus channel of the bus * instance. */ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, -- GitLab From 7ba75289115b9059d261de297041f8b754899f22 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Sun, 5 Oct 2014 01:26:47 +0300 Subject: [PATCH 0283/9457] staging: rts5208: Delete braces are not necessary Fix checkpatch.pl warning: WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index bbbf7968a0b6..11610826acf1 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -584,9 +584,8 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) case MAKE_MEDIUM_READY: case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) { + if (check_card_ready(chip, lun)) return TRANSPORT_GOOD; - } set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); -- GitLab From e3fe42b149c4c8ee13ade4112ed38e6d9a85c7b7 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 3 Oct 2014 09:16:53 +0530 Subject: [PATCH 0284/9457] Staging: iio: adc: Refine delay computation As per comment in function ad7280_delay, conversion delay may take up to 250us. We cannot rely on msleep for this because it may sleep longer than intended time for values less than 20ms, so use usleep_range instead. Problem detected using checkpatch.pl. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7280a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index d215edf66af2..4d4870787eed 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -188,7 +188,7 @@ static void ad7280_delay(struct ad7280_state *st) if (st->readback_delay_us < 50) udelay(st->readback_delay_us); else - msleep(1); + usleep_range(250, 500); } static int __ad7280_read32(struct ad7280_state *st, unsigned *val) -- GitLab From 29aeb33aca91724a71289fbe8520d2689b5c9b71 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 6 Oct 2014 15:10:25 +0530 Subject: [PATCH 0285/9457] Staging: iio: adc: Fix line over 80 characters This patch fixes the following checkpatch.pl warning: WARNING: line over 80 characters Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7192.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index c110a255d4e8..f6526aa22e8a 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -223,7 +223,8 @@ static int ad7192_setup(struct ad7192_state *st, id &= AD7192_ID_MASK; if (id != st->devid) - dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id); + dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", + id); switch (pdata->clock_source_sel) { case AD7192_CLK_EXT_MCLK1_2: -- GitLab From 31c4670ff3eda5036121811a18785c6e6a9a9e78 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 6 Oct 2014 15:11:06 +0530 Subject: [PATCH 0286/9457] Staging: iio: adc: Fixing line over 80 characters This patch fixes the following checkpatch.pl warning: WARNING: line over 80 charcaters Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7816.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 734a7e4886a0..48b1c3740030 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -152,7 +152,8 @@ static ssize_t ad7816_show_available_modes(struct device *dev, return sprintf(buf, "full\npower-save\n"); } -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, NULL, 0); +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, + NULL, 0); static ssize_t ad7816_show_channel(struct device *dev, struct device_attribute *attr, -- GitLab From 33341553562ce1293795b4bef0e305a96385a9a1 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Fri, 3 Oct 2014 15:02:48 +0300 Subject: [PATCH 0287/9457] staging: iio: light: Remove unnecessary line continuations This fixes the following checkpatch.pl warning: WARNING: Avoid unnecessary line continuations Signed-off-by: Roberta Dobrescu Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index e0d88fa2a5b5..b3d73a9a42ab 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1573,8 +1573,7 @@ static struct attribute *tsl2x7x_ALS_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1591,8 +1590,7 @@ static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1611,8 +1609,7 @@ static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { &dev_attr_power_state.attr, &dev_attr_in_illuminance0_calibscale_available.attr, &dev_attr_in_illuminance0_integration_time.attr, - &iio_const_attr_in_illuminance0_integration_time_available\ - .dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, -- GitLab From a724d08d01116a0019c84e3c54c8e5e37ce4dcbb Mon Sep 17 00:00:00 2001 From: Darshana Padmadas Date: Fri, 3 Oct 2014 19:27:29 +0530 Subject: [PATCH 0288/9457] Staging: iio: meter: Kconfig: Add module name information in Kconfig This patch updates Kconfig with paragraphs that describe config symbol fully. Found using checkpatch.pl. Signed-off-by: Darshana Padmadas Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/Kconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index e53274b64ae1..64cd3704ec6e 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -10,6 +10,9 @@ config ADE7753 Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface. + To compile this driver as a module, choose M here: the + module will be called ade7753. + config ADE7754 tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver" depends on SPI @@ -17,6 +20,9 @@ config ADE7754 Say yes here to build support for Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver. + To compile this driver as a module, choose M here: the + module will be called ade7754. + config ADE7758 tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver" depends on SPI @@ -26,6 +32,9 @@ config ADE7758 Say yes here to build support for Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC with Per Phase Information Driver. + To compile this driver as a module, choose M here: the + module will be called ade7758. + config ADE7759 tristate "Analog Devices ADE7759 Active Energy Metering IC Driver" depends on SPI @@ -33,6 +42,9 @@ config ADE7759 Say yes here to build support for Analog Devices ADE7758 Active Energy Metering IC with di/dt Sensor Interface. + To compile this driver as a module, choose M here: the + module will be called ade7759. + config ADE7854 tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver" depends on SPI || I2C @@ -40,6 +52,9 @@ config ADE7854 Say yes here to build support for Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver. + To compile this driver as a module, choose M here: the + module will be called ade7854. + config ADE7854_I2C tristate "support I2C bus connection" depends on ADE7854 && I2C -- GitLab From ff39a252cdeaec8dda1ed40a86b4a44173aad008 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Fri, 3 Oct 2014 23:34:50 +0300 Subject: [PATCH 0289/9457] staging: iio: Fix missing blank line warning Fixes "Missing a blank line after declarations" checkpatch.pl warning in Documentation/generic_buffer.c Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 044ea196aa6f..31dfb21587ff 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -47,6 +47,7 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels) { int bytes = 0; int i = 0; + while (i < num_channels) { if (bytes % channels[i].bytes == 0) channels[i].location = bytes; @@ -74,12 +75,14 @@ void print2byte(int input, struct iio_channel_info *info) input = input >> info->shift; if (info->is_signed) { int16_t val = input; + val &= (1 << info->bits_used) - 1; val = (int16_t)(val << (16 - info->bits_used)) >> (16 - info->bits_used); printf("%05f ", ((float)val + info->offset)*info->scale); } else { uint16_t val = input; + val &= (1 << info->bits_used) - 1; printf("%05f ", ((float)val + info->offset)*info->scale); } @@ -97,6 +100,7 @@ void process_scan(char *data, int num_channels) { int k; + for (k = 0; k < num_channels; k++) switch (channels[k].bytes) { /* only a few cases implemented so far */ -- GitLab From 79bdd48a7f25132588e819d214a5ce9b9f1c266f Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Fri, 3 Oct 2014 23:35:54 +0300 Subject: [PATCH 0290/9457] staging: iio: Fix missing blank line warning Fixes "Missing a blank line after declarations" checkpatch.pl warning in Documentation/iio_utils.h Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 0973a092224a..568eff06f803 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -34,6 +34,7 @@ inline int iioutils_break_up_name(const char *full_name, char *current; char *w, *r; char *working; + current = strdup(full_name); working = strtok(current, "_\0"); w = working; @@ -335,6 +336,7 @@ inline int build_channel_array(const char *device_dir, if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), "_en") == 0) { int current_enabled = 0; + current = &(*ci_array)[count++]; ret = asprintf(&filename, "%s/%s", scan_el_dir, ent->d_name); @@ -506,6 +508,7 @@ inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) FILE *sysfsfp; int test; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) return -ENOMEM; sprintf(temp, "%s/%s", basedir, filename); @@ -554,6 +557,7 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed\n"); return -ENOMEM; @@ -614,6 +618,7 @@ int read_sysfs_posint(char *filename, char *basedir) int ret; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; @@ -636,6 +641,7 @@ int read_sysfs_float(char *filename, char *basedir, float *val) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; @@ -658,6 +664,7 @@ int read_sysfs_string(const char *filename, const char *basedir, char *str) int ret = 0; FILE *sysfsfp; char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { printf("Memory allocation failed"); return -ENOMEM; -- GitLab From 96cb9ab1892d28ec424ab2fde05791c80d4716ca Mon Sep 17 00:00:00 2001 From: Roxana Blaj Date: Sat, 4 Oct 2014 14:26:13 +0300 Subject: [PATCH 0291/9457] staging: iio: addac: fix line over 80 characters This fixes checkpatch.pl warning: WARNING: line over 80 characters Signed-off-by: Roxana Blaj Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/addac/adt7316.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index ec50bf34628d..ec40fbb698a6 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h @@ -30,6 +30,7 @@ extern const struct dev_pm_ops adt7316_pm_ops; #else #define ADT7316_PM_OPS NULL #endif -int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); +int adt7316_probe(struct device *dev, struct adt7316_bus *bus, + const char *name); #endif -- GitLab From 237d0bf9b5e15c102c690e2a4e38bf1d592624cc Mon Sep 17 00:00:00 2001 From: Roxana Blaj Date: Tue, 7 Oct 2014 00:18:48 +0300 Subject: [PATCH 0292/9457] staging: iio: addac: annotate Kconfig entries with module name information This fixes the checkpatch.pl warning: WARNING: please write a paragraph that describes the config symbol fully Signed-off-by: Roxana Blaj Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/addac/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/iio/addac/Kconfig b/drivers/staging/iio/addac/Kconfig index e6795e0bed1d..0ed7e13e2283 100644 --- a/drivers/staging/iio/addac/Kconfig +++ b/drivers/staging/iio/addac/Kconfig @@ -10,6 +10,9 @@ config ADT7316 Say yes here to build support for Analog Devices ADT7316, ADT7317, ADT7318 and ADT7516, ADT7517, ADT7519 temperature sensors, ADC and DAC. + To compile this driver as a module, choose M here: the module will + be called adt7316. + config ADT7316_SPI tristate "support SPI bus connection" depends on SPI && ADT7316 @@ -18,6 +21,9 @@ config ADT7316_SPI Say yes here to build SPI bus support for Analog Devices ADT7316/7/8 and ADT7516/7/9. + To compile this driver as a module, choose M here: the module will + be called adt7316_spi. + config ADT7316_I2C tristate "support I2C bus connection" depends on I2C && ADT7316 @@ -25,4 +31,7 @@ config ADT7316_I2C Say yes here to build I2C bus support for Analog Devices ADT7316/7/8 and ADT7516/7/9. + To compile this driver as a module, choose M here: the module will + be called adt7316_i2c. + endmenu -- GitLab From 76ad1c42bbb58abdae86a13c86fc38714d6c7db2 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Sat, 4 Oct 2014 18:39:53 +0530 Subject: [PATCH 0293/9457] Staging: iio: gyro: Added description for config symbol. The following patch fixes the checkpatch.pl warning by adding description for a config symbol. WARNING: please write a paragraph that describes the config symbol fully. Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 88b199bb2926..f62f68fd6f3f 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -7,7 +7,10 @@ config ADIS16060 tristate "Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver" depends on SPI help - Say yes here to build support for Analog Devices adis16060 wide bandwidth + Say Y (yes) here to build support for Analog Devices adis16060 wide bandwidth yaw rate gyroscope with SPI. + To compile this driver as a module, say M here: the module will be + called adis16060. If unsure, say N. + endmenu -- GitLab From 30439b29b8edaaecd611f96051dd292dd1474a5e Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sat, 4 Oct 2014 19:54:25 +0530 Subject: [PATCH 0294/9457] staging: iio: accel: Update Kconfig description with module name information This patch fixes checkpatch.pl warning. WARNING: please write a paragraph that describes the config symbol fully Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 39 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index ad45dfbdf417..07b7ffa00ab5 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -9,53 +9,71 @@ config ADIS16201 select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16201 dual-axis + Say Y here to build support for Analog Devices adis16201 dual-axis digital inclinometer and accelerometer. + To compile this driver as a module, say M here: the module will + be called adis16201. + config ADIS16203 tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16203 Programmable + Say Y here to build support for Analog Devices adis16203 Programmable 360 Degrees Inclinometer. + To compile this driver as a module, say M here: the module will be + called adis16203. + config ADIS16204 tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16204 Programmable + Say Y here to build support for Analog Devices adis16204 Programmable High-g Digital Impact Sensor and Recorder. + To compile this driver as a module, say M here: the module will be + called adis16204. + config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer + Say Y here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. + To compile this driver as a module, say M here: the module will be + called adis16209. + config ADIS16220 tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" depends on SPI select IIO_ADIS_LIB help - Say yes here to build support for Analog Devices adis16220 programmable + Say Y here to build support for Analog Devices adis16220 programmable digital vibration sensor. + To compile this driver as a module, say M here: the module will be + called adis16220. + config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI select IIO_ADIS_LIB select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help - Say yes here to build support for Analog Devices adis16240 programmable + Say Y here to build support for Analog Devices adis16240 programmable impact Sensor and recorder. + To compile this driver as a module, say M here: the module will be + called adis16240. + config LIS3L02DQ tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver" depends on SPI @@ -63,16 +81,21 @@ config LIS3L02DQ depends on !IIO_BUFFER || IIO_KFIFO_BUF depends on GPIOLIB help - Say yes here to build SPI support for the ST microelectronics + Say Y here to build SPI support for the ST microelectronics accelerometer. The driver supplies direct access via sysfs files and an event interface via a character device. + To compile this driver as a module, say M here: the module will be + called lis3l02dq. + config SCA3000 depends on IIO_BUFFER depends on SPI tristate "VTI SCA3000 series accelerometers" help - Say yes here to build support for the VTI SCA3000 series of SPI + Say Y here to build support for the VTI SCA3000 series of SPI accelerometers. These devices use a hardware ring buffer. + To compile this driver as a module, say M here: the module will be + called sca3000. endmenu -- GitLab From d1e5041345d3976af580d9ac9728e1819b458e3c Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 17:03:31 +0530 Subject: [PATCH 0295/9457] Staging: iio: Documentation: Added missing blank line after declarations. The following patch fixes the following checkpatch.pl warning by adding a blank line after declarations. WARNING: Missing blank line after declarations. Signed-off-by: Heena Sirwani Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/lsiio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/iio/Documentation/lsiio.c b/drivers/staging/iio/Documentation/lsiio.c index 24ae9694eb41..a82c93da10bd 100644 --- a/drivers/staging/iio/Documentation/lsiio.c +++ b/drivers/staging/iio/Documentation/lsiio.c @@ -46,6 +46,7 @@ static int dump_channels(const char *dev_dir_name) { DIR *dp; const struct dirent *ent; + dp = opendir(dev_dir_name); if (dp == NULL) return -errno; @@ -107,6 +108,7 @@ static void dump_devices(void) while (ent = readdir(dp), ent != NULL) { if (check_prefix(ent->d_name, type_device)) { char *dev_dir_name; + asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); dump_one_device(dev_dir_name); free(dev_dir_name); @@ -118,6 +120,7 @@ static void dump_devices(void) while (ent = readdir(dp), ent != NULL) { if (check_prefix(ent->d_name, type_trigger)) { char *dev_dir_name; + asprintf(&dev_dir_name, "%s%s", iio_dir, ent->d_name); dump_one_trigger(dev_dir_name); free(dev_dir_name); -- GitLab From edead9b1f9fa1e28e493ccaa831d0ac7aa0de74b Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 17:04:10 +0530 Subject: [PATCH 0296/9457] Staging: iio: Documentation: Simplify error handling. This also has the nice effect of removing of a temporary variable from stack and fixes the following checkpatch.pl warning: WARNING: Missing blank line after declarations. Signed-off-by: Heena Sirwani Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/lsiio.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/Documentation/lsiio.c b/drivers/staging/iio/Documentation/lsiio.c index a82c93da10bd..3b436f13b872 100644 --- a/drivers/staging/iio/Documentation/lsiio.c +++ b/drivers/staging/iio/Documentation/lsiio.c @@ -69,11 +69,8 @@ static int dump_one_device(const char *dev_dir_name) read_sysfs_string("name", dev_dir_name, name); printf("Device %03d: %s\n", dev_idx, name); - if (verblevel >= VERBLEVEL_SENSORS) { - int ret = dump_channels(dev_dir_name); - if (ret) - return ret; - } + if (verblevel >= VERBLEVEL_SENSORS) + return dump_channels(dev_dir_name); return 0; } -- GitLab From d0e68ce1999e34a29d6b71ced4088d0f916878d4 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 17:04:43 +0530 Subject: [PATCH 0297/9457] Staging: iio: Documentation: Added check for sscanf return value. The following patch fixes the following checkpatch.pl warning by adding a check for sscanf return value. WARNING: unchecked sscanf return value. Signed-off-by: Heena Sirwani Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/lsiio.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/Documentation/lsiio.c b/drivers/staging/iio/Documentation/lsiio.c index 3b436f13b872..98a0de098130 100644 --- a/drivers/staging/iio/Documentation/lsiio.c +++ b/drivers/staging/iio/Documentation/lsiio.c @@ -63,9 +63,12 @@ static int dump_one_device(const char *dev_dir_name) { char name[IIO_MAX_NAME_LENGTH]; int dev_idx; + int retval; - sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), + retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i", &dev_idx); + if (retval != 1) + return -EINVAL; read_sysfs_string("name", dev_dir_name, name); printf("Device %03d: %s\n", dev_idx, name); @@ -78,9 +81,12 @@ static int dump_one_trigger(const char *dev_dir_name) { char name[IIO_MAX_NAME_LENGTH]; int dev_idx; + int retval; - sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), + retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), "%i", &dev_idx); + if (retval != 1) + return -EINVAL; read_sysfs_string("name", dev_dir_name, name); printf("Trigger %03d: %s\n", dev_idx, name); return 0; -- GitLab From 5c0ec98eba9537cf754b5cb2025e16fb71088cec Mon Sep 17 00:00:00 2001 From: Darshana Padmadas Date: Sat, 4 Oct 2014 21:55:26 +0530 Subject: [PATCH 0298/9457] Staging: iio: trigger: Add module name information in Kconfig This patch updates Kconfig with paragraphs that describe config symbol fully. Found using checkpatch.pl. Signed-off-by: Darshana Padmadas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index 2fd18c60323d..710a2f3e787e 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -1,4 +1,4 @@ -# + # # Industrial I/O standalone triggers # comment "Triggers - standalone" @@ -12,6 +12,9 @@ config IIO_PERIODIC_RTC_TRIGGER Provides support for using periodic capable real time clocks as IIO triggers. + To compile this driver as a module, choose M here: the + module will be called iio-trig-periodic-rtc. + config IIO_BFIN_TMR_TRIGGER tristate "Blackfin TIMER trigger" depends on BLACKFIN -- GitLab From a2bc425bb372caf4d471309353889c6228120287 Mon Sep 17 00:00:00 2001 From: Darshana Padmadas Date: Sat, 4 Oct 2014 21:55:27 +0530 Subject: [PATCH 0299/9457] Staging: iio: trigger: Break line over 80 characters This patch breaks a line that is over 80 characters as reported by checkpatch.pl Signed-off-by: Darshana Padmadas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 8f0a2ffa7150..d1df701909b3 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -72,7 +72,8 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev, if (val > 0) { ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val); if (ret == 0 && trig_info->state && trig_info->frequency == 0) - ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 1); + ret = rtc_irq_set_state(trig_info->rtc, + &trig_info->task, 1); } else if (val == 0) { ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0); } else -- GitLab From 18434f3b41e60f5ca80b1d55a793ad85134181a6 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 3 Oct 2014 09:27:18 +0530 Subject: [PATCH 0300/9457] Staging: lustre: lnet: Declare ping_srv_workitems static This patch makes ping_srv_workitems static as it is used only in the file ping_test.c This problem is detected by sparse. Signed-off-by: Vaishali Thakkar Acked-by: Daniel Baluta Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/ping_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index 750cac4afbb2..d8c0df6e6852 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -44,7 +44,7 @@ #define LST_PING_TEST_MAGIC 0xbabeface -int ping_srv_workitems = SFW_TEST_WI_MAX; +static int ping_srv_workitems = SFW_TEST_WI_MAX; module_param(ping_srv_workitems, int, 0644); MODULE_PARM_DESC(ping_srv_workitems, "# PING server workitems"); -- GitLab From ec17e8113b5a17bc3326de7c50ea7f42c6272b48 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Fri, 3 Oct 2014 10:44:25 +0530 Subject: [PATCH 0301/9457] Staging: lustre: lnet: selftest: Made a function static. The following patch makes a function static as it is not used by other files. The patch fixes the warning: WARNING: symbol 'brw_check_bulk' was not declared. Should it be static? The above warning was reported by sparse. Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index a94f336d578c..bf6f125064eb 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -233,7 +233,7 @@ brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) } } -int +static int brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { int i; -- GitLab From 6888871cb05cd4d182bf504ed3f804a9bba20ce8 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Fri, 3 Oct 2014 10:44:58 +0530 Subject: [PATCH 0302/9457] Staging: lustre: lnet: selftest: Made a function static. The following patch makes a function static as it is not used by other files. The patch fixes the warning: WARNING: symbol 'brw_server_rpc_done' was not declared. Should it be static? The above warning was reported by sparse. Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index bf6f125064eb..9e04695bfdbc 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -358,7 +358,7 @@ brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc) return; } -void +static void brw_server_rpc_done(srpc_server_rpc_t *rpc) { srpc_bulk_t *blk = rpc->srpc_bulk; -- GitLab From 0c05ef92f64e6e16095e0cf8ae3ec3529624621f Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Fri, 3 Oct 2014 10:45:38 +0530 Subject: [PATCH 0303/9457] Staging: lustre: lnet: selftest: Made a function static. The following patch makes a function static as it is not used by other files. The patch fixes the warning: WARNING: symbol 'brw_bulk_ready' was not declared. Should it be static? The above warning was reported by sparse. Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index 9e04695bfdbc..d7b26b0a57e2 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -378,7 +378,7 @@ brw_server_rpc_done(srpc_server_rpc_t *rpc) sfw_free_pages(rpc); } -int +static int brw_bulk_ready(srpc_server_rpc_t *rpc, int status) { __u64 magic = BRW_MAGIC; -- GitLab From 4a1b86dc6c3e0678cbad701599b161b3d9f9ce42 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Fri, 3 Oct 2014 10:46:09 +0530 Subject: [PATCH 0304/9457] Staging: lustre: lnet: selftest: Made a function static. The following patch makes a function static as it is not used by other files. The patch fixes the warning: WARNING: symbol 'brw_server_handle' was not declared. Should it be static? The above warning was reported by sparse. Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index d7b26b0a57e2..463da076fa70 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -414,7 +414,7 @@ brw_bulk_ready(srpc_server_rpc_t *rpc, int status) return 0; } -int +static int brw_server_handle(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; -- GitLab From 12afe4935a35c2bdd71da59e86afa6e9d5fd6562 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Sun, 5 Oct 2014 17:28:06 +0530 Subject: [PATCH 0305/9457] Staging: lustre: Replace non-standard spin-lock's macro This patch replaces non-standard spin lock macro with standard linux function. This is done using Coccinelle and semantic patch used is as follows: @@ expression x; @@ - TREE_READ_LOCK_IRQ(x) + spin_lock_irq(&x->tree_lock) @@ expression x; @@ - TREE_READ_UNLOCK_IRQ(x) + spin_unlock_irq(&x->tree_lock) Signed-off-by: Vaishali Thakkar Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index b0bb7095dde5..662bdf04a451 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -275,14 +275,14 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, struct page *page; int found; - TREE_READ_LOCK_IRQ(mapping); + spin_lock_irq(&mapping->tree_lock); found = radix_tree_gang_lookup(&mapping->page_tree, (void **)&page, offset, 1); if (found > 0) { struct lu_dirpage *dp; page_cache_get(page); - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); /* * In contrast to find_lock_page() we are sure that directory * page cannot be truncated (while DLM lock is held) and, @@ -326,7 +326,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash, } } else { - TREE_READ_UNLOCK_IRQ(mapping); + spin_unlock_irq(&mapping->tree_lock); page = NULL; } return page; -- GitLab From c4226c547f3c1e69989f843cf8d3d7b2f295ad3f Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Sun, 5 Oct 2014 17:28:12 +0530 Subject: [PATCH 0306/9457] Staging: lustre: Replace non-standard spinlock macro definations This patch replaces non-standard spin lock macro with standard linux function. This is done using Coccinelle and semantic patch used is as follows: @@ expression x; @@ - TREE_READ_LOCK_IRQ(x) + spin_lock_irq(&(x)->tree_lock) @@ expression x; @@ - TREE_READ_UNLOCK_IRQ(x) + spin_unlock_irq(&(x)->tree_lock) Also semantic patch result is modified by droping ->, inner & and adding . for simplification of code. Signed-off-by: Vaishali Thakkar Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index a8bcc51057f1..d614752c4c20 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1880,8 +1880,8 @@ void ll_delete_inode(struct inode *inode) /* Workaround for LU-118 */ if (inode->i_data.nrpages) { - TREE_READ_LOCK_IRQ(&inode->i_data); - TREE_READ_UNLOCK_IRQ(&inode->i_data); + spin_lock_irq(&inode->i_data.tree_lock); + spin_unlock_irq(&inode->i_data.tree_lock); LASSERTF(inode->i_data.nrpages == 0, "inode=%lu/%u(%p) nrpages=%lu, see " "http://jira.whamcloud.com/browse/LU-118\n", -- GitLab From 0f320bd82d243713fac7274f2cbe3d2ab7dba40d Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Sun, 5 Oct 2014 17:28:18 +0530 Subject: [PATCH 0307/9457] Staging: lustre: Remove non-standard spinlock macro definitions This patch removes non-standard spinlock's macros as they are no longer used by this driver. Signed-off-by: Vaishali Thakkar Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/linux/lustre_compat25.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h index e94ab343ab25..e03775606712 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h @@ -91,8 +91,6 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, # define inode_dio_read(i) atomic_inc(&(i)->i_dio_count) /* inode_dio_done(i) use as-is for read unlock */ -#define TREE_READ_LOCK_IRQ(mapping) spin_lock_irq(&(mapping)->tree_lock) -#define TREE_READ_UNLOCK_IRQ(mapping) spin_unlock_irq(&(mapping)->tree_lock) #ifndef FS_HAS_FIEMAP #define FS_HAS_FIEMAP (0) -- GitLab From fa4d19c4effee121198dc33d419c00a375e65b27 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:10 +0530 Subject: [PATCH 0308/9457] staging: lustre: lustre: ptlrpc: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/pinger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 20341b27a06a..e8d00408117a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -448,7 +448,7 @@ struct timeout_item* ptlrpc_new_timeout(int time, enum timeout_event event, } /** - * Register timeout event on the the pinger thread. + * Register timeout event on the pinger thread. * Note: the timeout list is an sorted list with increased timeout value. */ static struct timeout_item* -- GitLab From c2487192be5a8fe87a5be5fd92e4bc56c9f0da4d Mon Sep 17 00:00:00 2001 From: Kumari Radha Date: Sun, 5 Oct 2014 20:22:54 +0530 Subject: [PATCH 0309/9457] staging: lustre: lustre: obdclass: Added missing line after declaration Added missing line after declaration fixing the following checkpatch.pl warning in dt_object.c: WARNING: Missing a blank line after declarations Signed-off-by: Kumari Radha Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/dt_object.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c index 52256c26bf07..909f542f8b86 100644 --- a/drivers/staging/lustre/lustre/obdclass/dt_object.c +++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c @@ -950,8 +950,8 @@ int lprocfs_dt_rd_blksize(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%u\n", @@ -967,8 +967,8 @@ int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_blocks; @@ -989,8 +989,8 @@ int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bfree; @@ -1011,8 +1011,8 @@ int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { __u32 blk_size = osfs.os_bsize >> 10; __u64 result = osfs.os_bavail; @@ -1033,8 +1033,8 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%llu\n", osfs.os_files); @@ -1049,8 +1049,8 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off, { struct dt_device *dt = data; struct obd_statfs osfs; - int rc = dt_statfs(NULL, dt, &osfs); + if (rc == 0) { *eof = 1; rc = snprintf(page, count, "%llu\n", osfs.os_ffree); -- GitLab From f09b372b154391b70e571f4404ec45c014a01594 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:00 +0530 Subject: [PATCH 0310/9457] staging: lustre: lustre: llite: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index c99b74117152..f1f75c7edee0 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -368,7 +368,7 @@ int ll_file_release(struct inode *inode, struct file *file) fd = LUSTRE_FPRIVATE(file); LASSERT(fd != NULL); - /* The last ref on @file, maybe not the the owner pid of statahead. + /* The last ref on @file, maybe not the owner pid of statahead. * Different processes can open the same dir, "ll_opendir_key" means: * it is me that should stop the statahead thread. */ if (S_ISDIR(inode->i_mode) && lli->lli_opendir_key == fd && -- GitLab From 5ed57d6dc6aab12515a8afc62e0d2cd0ae95c3f8 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:26:14 +0530 Subject: [PATCH 0311/9457] Staging: lustre: lustre: lmv: Removed variable that is not very useful. The following patch removes a variable that is not very useful using coccinelle. The semantic patch used was: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 1a5821289c39..9543c15f990e 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2310,7 +2310,6 @@ static int lmv_unlink(struct obd_export *exp, struct md_op_data *op_data, static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { struct lmv_obd *lmv = &obd->u.lmv; - int rc = 0; switch (stage) { case OBD_CLEANUP_EARLY: @@ -2324,7 +2323,7 @@ static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) default: break; } - return rc; + return 0; } static int lmv_get_info(const struct lu_env *env, struct obd_export *exp, -- GitLab From 8482727897ff03f16fae8694c4496bd079a65feb Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:26:47 +0530 Subject: [PATCH 0312/9457] Staging: lustre: lustre: mgc: Remove variable that is not very useful. The following patch removes a variable that is not very useful using coccinelle. The semantic patch used was: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mgc/mgc_request.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index bc263adf09d4..bbef5c96d605 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -510,8 +510,6 @@ static void do_requeue(struct config_llog_data *cld) static int mgc_requeue_thread(void *data) { - int rc = 0; - CDEBUG(D_MGC, "Starting requeue thread\n"); /* Keep trying failed locks periodically */ @@ -592,7 +590,7 @@ static int mgc_requeue_thread(void *data) complete(&rq_exit); CDEBUG(D_MGC, "Ending requeue thread\n"); - return rc; + return 0; } /* Add a cld to the list to requeue. Start the requeue thread if needed. @@ -1055,8 +1053,6 @@ static int mgc_import_event(struct obd_device *obd, struct obd_import *imp, enum obd_import_event event) { - int rc = 0; - LASSERT(imp->imp_obd == obd); CDEBUG(D_MGC, "import event %#x\n", event); @@ -1090,7 +1086,7 @@ static int mgc_import_event(struct obd_device *obd, CERROR("Unknown import event %#x\n", event); LBUG(); } - return rc; + return 0; } enum { -- GitLab From e588f1bf8e8e9ec43369a35c11d4d8c8a846a4a7 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:27:18 +0530 Subject: [PATCH 0313/9457] Staging: lustre: lustre: lov: Remove variable that is not very useful. The following patch removes a variable that is not very useful using coccinelle. The semantic patch used was: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lov/lov_obd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 94dfd64bd283..71ad166e2cbc 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -847,7 +847,6 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg) static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { - int rc = 0; struct lov_obd *lov = &obd->u.lov; switch (stage) { @@ -865,7 +864,7 @@ static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) break; } - return rc; + return 0; } static int lov_cleanup(struct obd_device *obd) -- GitLab From 114114a2a340e999277ce3fa833b4546f4e9b853 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:27:54 +0530 Subject: [PATCH 0314/9457] Staging: lustre: lustre: osc: Remove variable that is not very useful. The following patch removes a variable that is not very useful using coccinelle. The semantic patch used was: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 7734d666b7a1..806fd397b721 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -539,7 +539,6 @@ static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur, int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) { struct osc_object *obj = ext->oe_obj; - int rc = 0; LASSERT(atomic_read(&ext->oe_users) > 0); LASSERT(sanity_check(ext) == 0); @@ -571,7 +570,7 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) osc_io_unplug_async(env, osc_cli(obj), obj); } osc_extent_put(env, ext); - return rc; + return 0; } static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2) -- GitLab From 41f8d410aee43a00b2e5e1c3b916049fad0f8643 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:28:30 +0530 Subject: [PATCH 0315/9457] Staging: lustre: lustre: osc: Remove variable that is not very useful. The following patch removes a variable that is not very useful using coccinelle. The semantic patch used was: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_request.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 44657a06b8a5..ca16c081e9df 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -3217,8 +3217,6 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) { - int rc = 0; - switch (stage) { case OBD_CLEANUP_EARLY: { struct obd_import *imp; @@ -3253,7 +3251,7 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) break; } } - return rc; + return 0; } int osc_cleanup(struct obd_device *obd) -- GitLab From 882e7e215db8934c1c1f2ff4f71c19d2275596b2 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 17:29:11 +0530 Subject: [PATCH 0316/9457] Staging: lustre: lustre: osc: Changed the return code of a function from int to void. The following patch changes the return code of a function from int to void as the return value was not used by the callers. Signed-off-by: Heena Sirwani Reviewed-by: Octavian Purdila Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_cache.c | 3 +-- drivers/staging/lustre/lustre/osc/osc_cl_internal.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 806fd397b721..ec04935c65ea 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -536,7 +536,7 @@ static int osc_extent_merge(const struct lu_env *env, struct osc_extent *cur, /** * Drop user count of osc_extent, and unplug IO asynchronously. */ -int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) +void osc_extent_release(const struct lu_env *env, struct osc_extent *ext) { struct osc_object *obj = ext->oe_obj; @@ -570,7 +570,6 @@ int osc_extent_release(const struct lu_env *env, struct osc_extent *ext) osc_io_unplug_async(env, osc_cli(obj), obj); } osc_extent_put(env, ext); - return 0; } static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2) diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index ebbd95c0cea8..365b2787b3c8 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -678,7 +678,7 @@ struct osc_extent { int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, int sent, int rc); -int osc_extent_release(const struct lu_env *env, struct osc_extent *ext); +void osc_extent_release(const struct lu_env *env, struct osc_extent *ext); /** @} osc */ -- GitLab From cf29a7b6eae8f74a2bb39fe01ee8aed9a3a5f665 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Wed, 8 Oct 2014 00:42:05 +0530 Subject: [PATCH 0317/9457] Staging: lustre: Fix checkpatch warning: Missing blank line The following checkpatch warning was fixed : WARNING: Missing a blank line after declarations Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index d614752c4c20..09b90f6a41c8 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -712,6 +712,7 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) list_for_each(tmp, &dentry->d_subdirs) { struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child); + lustre_dump_dentry(d, recur - 1); } } @@ -1152,6 +1153,7 @@ struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock) lock_res_and_lock(lock); if (lock->l_resource->lr_lvb_inode) { struct ll_inode_info *lli; + lli = ll_i2info(lock->l_resource->lr_lvb_inode); if (lli->lli_inode_magic == LLI_INODE_MAGIC) { inode = igrab(lock->l_resource->lr_lvb_inode); @@ -1850,6 +1852,7 @@ void ll_read_inode2(struct inode *inode, void *opaque) if (S_ISREG(inode->i_mode)) { struct ll_sb_info *sbi = ll_i2sbi(inode); + inode->i_op = &ll_file_inode_operations; inode->i_fop = sbi->ll_fop; inode->i_mapping->a_ops = (struct address_space_operations *)&ll_aops; -- GitLab From 566be54df121cf36b99d01515ab267424117c89c Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Wed, 8 Oct 2014 00:42:06 +0530 Subject: [PATCH 0318/9457] Staging: lustre: Fix checkpatch warning: Unnecessary braces The following checkpatch warning was fixed : WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 09b90f6a41c8..3c086b4d0ea5 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1122,9 +1122,8 @@ void ll_put_super(struct super_block *sb) } next = 0; - while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) !=NULL) { + while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) !=NULL) class_manual_cleanup(obd); - } if (sbi->ll_flags & LL_SBI_VERBOSE) LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : ""); @@ -1734,11 +1733,10 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLTYPE) inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); LASSERT(inode->i_mode != 0); - if (S_ISREG(inode->i_mode)) { + if (S_ISREG(inode->i_mode)) inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1, LL_MAX_BLKSIZE_BITS); - } else { + else inode->i_blkbits = inode->i_sb->s_blocksize_bits; - } if (body->valid & OBD_MD_FLUID) inode->i_uid = make_kuid(&init_user_ns, body->uid); if (body->valid & OBD_MD_FLGID) -- GitLab From f44b902adf7c9f0e794540e3537fc328dae17298 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:30 +0530 Subject: [PATCH 0319/9457] staging: rtl8712: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index d9c1561e3272..5aae4cce8477 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -527,7 +527,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); psecnetwork->IELength = 0; - /* If the the driver wants to use the bssid to create the connection. + /* If the driver wants to use the bssid to create the connection. * If not, we copy the connecting AP's MAC address to it so that * the driver just has the bssid information for PMKIDList searching. */ -- GitLab From 14ad732c2d19858cc43b4b7421d63b82575bc84e Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Fri, 3 Oct 2014 19:33:39 +0530 Subject: [PATCH 0320/9457] staging: rtl8712: Fixed else not required after return WARNING: else is generally not required after return checkpatch.pl warning in osdep_service.h Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/osdep_service.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index d7a357b8d2d1..5153ad9c2c75 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -88,17 +88,13 @@ static inline u32 _down_sema(struct semaphore *sema) { if (down_interruptible(sema)) return _FAIL; - else - return _SUCCESS; + return _SUCCESS; } static inline u32 end_of_queue_search(struct list_head *head, struct list_head *plist) { - if (head == plist) - return true; - else - return false; + return (head == plist); } static inline void sleep_schedulable(int ms) -- GitLab From 366ba427032eaefdec9d3fd318f23eea2b26ead6 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 14:23:18 +0530 Subject: [PATCH 0321/9457] staging: rtl8712: Delete explicit comparison with false and NULL This patch delete explicit comparison to false and NULL in files of rtl8712. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/recv_linux.c | 2 +- drivers/staging/rtl8712/rtl871x_io.c | 2 +- drivers/staging/rtl8712/rtl871x_ioctl_set.c | 20 +++++++++----------- drivers/staging/rtl8712/rtl871x_mp.c | 4 ++-- drivers/staging/rtl8712/usb_intf.c | 10 +++++----- drivers/staging/rtl8712/usb_ops_linux.c | 6 +++--- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 495ee1205e02..0631f3638257 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -146,7 +146,7 @@ void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf) dev_kfree_skb_any(precvbuf->pskb); precvbuf->pskb = NULL; precvbuf->reuse = false; - if (precvbuf->irp_pending == false) + if (!precvbuf->irp_pending) r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); } diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c index d7b63aedead7..3a0236606396 100644 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ b/drivers/staging/rtl8712/rtl871x_io.c @@ -93,7 +93,7 @@ static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl) pintfhdl->intf_option = 0; pintfhdl->adapter = dev; pintfhdl->intf_dev = (u8 *)&(adapter->dvobjpriv); - if (_init_intf_hdl(adapter, pintfhdl) == false) + if (!_init_intf_hdl(adapter, pintfhdl)) goto register_intf_hdl_fail; return _SUCCESS; register_intf_hdl_fail: diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index 9d47eb472837..a240b6389683 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -77,7 +77,7 @@ static u8 do_join(struct _adapter *padapter) /* when set_ssid/set_bssid for do_join(), but scanning queue * is empty we try to issue sitesurvey firstly */ - if (pmlmepriv->sitesurveyctrl.traffic_busy == false) + if (!pmlmepriv->sitesurveyctrl.traffic_busy) r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); return true; } else { @@ -143,8 +143,7 @@ u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { - if (check_fwstate(pmlmepriv, - WIFI_STATION_STATE) == false) + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) goto _Abort_Set_BSSID; /* driver is in * WIFI_ADHOC_MASTER_STATE */ } else { @@ -177,7 +176,7 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; - if (padapter->hw_init_completed == false) + if (!padapter->hw_init_completed) return; spin_lock_irqsave(&pmlmepriv->lock, irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { @@ -188,10 +187,9 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { - if ((check_fwstate(pmlmepriv, - WIFI_STATION_STATE) == false)) { - if (r8712_is_same_ibss(padapter, - pnetwork) == false) { + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + if (!r8712_is_same_ibss(padapter, + pnetwork)) { /* if in WIFI_ADHOC_MASTER_STATE or * WIFI_ADHOC_STATE, create bss or * rejoin again @@ -227,7 +225,7 @@ void r8712_set_802_11_ssid(struct _adapter *padapter, } if (padapter->securitypriv.btkip_countermeasure == true) goto _Abort_Set_SSID; - if (validate_ssid(ssid) == false) + if (!validate_ssid(ssid)) goto _Abort_Set_SSID; memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false; @@ -308,10 +306,10 @@ u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter) unsigned long irqL; u8 ret = true; - if (padapter == NULL) + if (!padapter) return false; pmlmepriv = &padapter->mlmepriv; - if (padapter->hw_init_completed == false) + if (!padapter->hw_init_completed) return false; spin_lock_irqsave(&pmlmepriv->lock, irqL); if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) || diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c index 2ec660ad78af..3d913b9701bb 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ b/drivers/staging/rtl8712/rtl871x_mp.c @@ -56,7 +56,7 @@ static int init_mp_priv(struct mp_priv *pmp_priv) pmp_priv->pallocated_mp_xmitframe_buf = kmalloc(NR_MP_XMITFRAME * sizeof(struct mp_xmit_frame) + 4, GFP_ATOMIC); - if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) { + if (!pmp_priv->pallocated_mp_xmitframe_buf) { res = _FAIL; goto _exit_init_mp_priv; } @@ -173,7 +173,7 @@ u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value) oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8)); value = oldValue | (newValue << (shift * 8)); - if (fw_iocmd_write(pAdapter, iocmd, value) == false) + if (!fw_iocmd_write(pAdapter, iocmd, value)) return false; iocmd.value += 4; oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index a3d733b145eb..da3856dda728 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -292,13 +292,13 @@ static void r8712_usb_dvobj_deinit(struct _adapter *padapter) void rtl871x_intf_stop(struct _adapter *padapter) { /*disable_hw_interrupt*/ - if (padapter->bSurpriseRemoved == false) { + if (!padapter->bSurpriseRemoved) { /*device still exists, so driver can do i/o operation * TODO: */ } /* cancel in irp */ - if (padapter->dvobjpriv.inirp_deinit != NULL) + if (padapter->dvobjpriv.inirp_deinit) padapter->dvobjpriv.inirp_deinit(padapter); /* cancel out irp */ r8712_usb_write_port_cancel(padapter); @@ -318,7 +318,7 @@ void r871x_dev_unload(struct _adapter *padapter) r8712_stop_drv_threads(padapter); /*s5.*/ - if (padapter->bSurpriseRemoved == false) { + if (!padapter->bSurpriseRemoved) { padapter->hw_init_completed = false; rtl8712_hal_deinit(padapter); } @@ -402,7 +402,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, /* step 3. * initialize the dvobj_priv */ - if (padapter->dvobj_init == NULL) + if (!padapter->dvobj_init) goto error; else { status = padapter->dvobj_init(padapter); @@ -568,7 +568,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, ((mac[0] == 0x00) && (mac[1] == 0x00) && (mac[2] == 0x00) && (mac[3] == 0x00) && (mac[4] == 0x00) && (mac[5] == 0x00)) || - (AutoloadFail == false)) { + (!AutoloadFail)) { mac[0] = 0x00; mac[1] = 0xe0; mac[2] = 0x4c; diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index e89d2b07fcb9..e0a155a4fac1 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -267,7 +267,7 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) if (adapter->bDriverStopped || adapter->bSurpriseRemoved || adapter->pwrctrlpriv.pnp_bstop_trx) return _FAIL; - if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) { + if (!precvbuf->reuse == false || !precvbuf->pskb) { precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); if (NULL != precvbuf->pskb) precvbuf->reuse = true; @@ -275,10 +275,10 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) if (precvbuf != NULL) { r8712_init_recvbuf(adapter, precvbuf); /* re-assign for linux based on skb */ - if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) { + if (!precvbuf->reuse || !precvbuf->pskb) { precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (precvbuf->pskb == NULL) + if (!precvbuf->pskb) return _FAIL; tmpaddr = (addr_t)precvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); -- GitLab From a724e4e3b2bfdd3c1988820ff44d9a514591ebd4 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Sun, 5 Oct 2014 01:41:58 +0300 Subject: [PATCH 0322/9457] staging: rtl8723au: include: fix space prohibited before Fix checkpatch.pl issues with space prohibited before semicolon in Hal8723UHWImg_CE.h Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h b/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h index bbeaab48057a..c834b3a738d7 100644 --- a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h +++ b/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h @@ -19,7 +19,7 @@ extern u8 Rtl8723UFwUMCBCutImgArrayWithoutBT[Rtl8723UUMCBCutImgArrayWithoutBTLen extern const u8 Rtl8723SFwUMCBCutMPImgArray[Rtl8723SUMCBCutMPImgArrayLength]; #define Rtl8723EBTImgArrayLength 15276 -extern u8 Rtl8723EFwBTImgArray[Rtl8723EBTImgArrayLength] ; +extern u8 Rtl8723EFwBTImgArray[Rtl8723EBTImgArrayLength]; #define Rtl8723UPHY_REG_Array_PGLength 336 extern u32 Rtl8723UPHY_REG_Array_PG[Rtl8723UPHY_REG_Array_PGLength]; -- GitLab From 15c389c14ce638ae3e93c26182218fb7ad6b0b4d Mon Sep 17 00:00:00 2001 From: Mahati Chamarthy Date: Sun, 5 Oct 2014 13:11:39 +0530 Subject: [PATCH 0323/9457] Staging: rtl8723au: include: Remove unnecessary macro This patch removes a macro which is not used anywhere except in the header file. Existing usage in the header file is replaced with the actual value. Signed-off-by: Mahati Chamarthy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm_debug.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm_debug.h b/drivers/staging/rtl8723au/include/odm_debug.h index 4d935a33ccb3..8509a04b6a52 100644 --- a/drivers/staging/rtl8723au/include/odm_debug.h +++ b/drivers/staging/rtl8723au/include/odm_debug.h @@ -91,8 +91,7 @@ #define ODM_COMP_INIT BIT(31) /*------------------------Export Macro Definition---------------------------*/ - #define DbgPrint printk - #define RT_PRINTK(fmt, args...) DbgPrint("%s(): " fmt, __func__, ## args); + #define RT_PRINTK(fmt, args...) printk("%s(): " fmt, __func__, ## args); #ifndef ASSERT #define ASSERT(expr) @@ -101,7 +100,7 @@ #define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ { \ - DbgPrint("[ODM-8723A] "); \ + printk("[ODM-8723A] "); \ RT_PRINTK fmt; \ } @@ -113,25 +112,25 @@ #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if(!(expr)) { \ - DbgPrint("Assertion failed! %s at ......\n", #expr); \ - DbgPrint(" ......%s,%s,line=%d\n", __FILE__, __func__, __LINE__);\ + printk("Assertion failed! %s at ......\n", #expr); \ + printk(" ......%s,%s,line=%d\n", __FILE__, __func__, __LINE__);\ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { DbgPrint("==> %s\n", __func__); } -#define ODM_dbg_exit() { DbgPrint("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __func__, str); } +#define ODM_dbg_enter() { printk("==> %s\n", __func__); } +#define ODM_dbg_exit() { printk("<== %s\n", __func__); } +#define ODM_dbg_trace(str) { printk("%s:%s\n", __func__, str); } #define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel){ \ int __i; \ u8 * __ptr = (u8 *)ptr; \ - DbgPrint("[ODM] "); \ - DbgPrint(title_str); \ - DbgPrint(" "); \ + printk("[ODM] "); \ + printk(title_str); \ + printk(" "); \ for (__i=0; __i < 6; __i++) \ - DbgPrint("%02X%s", __ptr[__i], (__i == 5) ? "" : "-"); \ - DbgPrint("\n"); \ + printk("%02X%s", __ptr[__i], (__i == 5) ? "" : "-"); \ + printk("\n"); \ } void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm); -- GitLab From 911f2921c41cece94689bc0bb4dc9f7723d40839 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 14:45:56 +0530 Subject: [PATCH 0324/9457] Staging: rtl8723au: os_dep: Removed variable that is always 0. The following patch removes a variable that is always 0 using coccinelle. The semaintic patch used is as follows: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index bd6953af0a03..de2a3f546cfb 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -471,7 +471,6 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index, int set_tx, const u8 *sta_addr, struct key_params *keyparms) { - int ret = 0; int key_len; struct sta_info *psta = NULL, *pbcmc_sta = NULL; struct rtw_adapter *padapter = netdev_priv(dev); @@ -708,7 +707,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index, exit: - return ret; + return 0; } #endif @@ -2432,20 +2431,16 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter, static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static int rtw_cfg80211_monitor_if_close(struct net_device *ndev) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, @@ -2574,11 +2569,9 @@ static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) { - int ret = 0; - DBG_8723A("%s\n", __func__); - return ret; + return 0; } static const struct net_device_ops rtw_cfg80211_monitor_if_ops = { -- GitLab From f9800f82b6c403d4ba595383859030360b67dae0 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Tue, 7 Oct 2014 14:46:30 +0530 Subject: [PATCH 0325/9457] Staging: rtl8723au: core: Removed variable that is always 0. The following patch removes a variable that is always 0 using coccinelle. The following semantic patch was used: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index 6b4092f05da5..eb5d60ca2397 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -1122,7 +1122,6 @@ int rtw_acl_remove_sta23a(struct rtw_adapter *padapter, u8 *addr) struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q; - int ret = 0; DBG_8723A("%s(acl_num =%d) = %pM\n", __func__, pacl_list->num, addr); @@ -1148,7 +1147,7 @@ int rtw_acl_remove_sta23a(struct rtw_adapter *padapter, u8 *addr) DBG_8723A("%s, acl_num =%d\n", __func__, pacl_list->num); - return ret; + return 0; } static void update_bcn_fixed_ie(struct rtw_adapter *padapter) @@ -1698,7 +1697,6 @@ u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool acti int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_offset) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1706,7 +1704,7 @@ int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_o u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if ((pmlmeinfo->state&0x03) != MSR_AP) - return ret; + return 0; DBG_8723A("%s(%s): with ch:%u, offset:%u\n", __func__, padapter->pnetdev->name, new_ch, ch_offset); @@ -1724,13 +1722,12 @@ int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_o issue_action_spct_ch_switch23a (padapter, bc_addr, new_ch, ch_offset); - return ret; + return 0; } int rtw_sta_flush23a(struct rtw_adapter *padapter) { struct list_head *phead, *plist, *ptmp; - int ret = 0; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1743,7 +1740,7 @@ int rtw_sta_flush23a(struct rtw_adapter *padapter) DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name); if ((pmlmeinfo->state&0x03) != MSR_AP) - return ret; + return 0; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; @@ -1769,7 +1766,7 @@ int rtw_sta_flush23a(struct rtw_adapter *padapter) associated_clients_update23a(padapter, true); - return ret; + return 0; } /* called > TSR LEVEL for USB or SDIO Interface*/ -- GitLab From 6d36fe3edc99165c8d1be60445b807a613d2c918 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Fri, 3 Oct 2014 13:08:21 +0300 Subject: [PATCH 0326/9457] staging: rtl8188eu: Fix prefer ether_addr_copy() over memcpy() This patch fixes "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in rtw_ap.c Pahole showed that the addresses are aligned. Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_ap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 9224e029ef2b..7de7ba197be1 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -888,7 +888,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->Rssi = 0; - memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN); + ether_addr_copy(pbss_network->MacAddress, myid(&(padapter->eeprompriv))); /* beacon interval */ p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */ @@ -1164,7 +1164,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) if (!paclnode->valid) { INIT_LIST_HEAD(&paclnode->list); - memcpy(paclnode->addr, addr, ETH_ALEN); + ether_addr_copy(paclnode->addr, addr); paclnode->valid = true; -- GitLab From c9e27530b25fd8a01149a749488aef1353856c5e Mon Sep 17 00:00:00 2001 From: Mahati Chamarthy Date: Sat, 4 Oct 2014 21:57:02 +0530 Subject: [PATCH 0327/9457] Staging: rtl8188eu: include: Remove unnecessary macro This patch removes a macro which is not used anywhere except in the header file. The existing usage in the header file is replaced with the actual value. Signed-off-by: Mahati Chamarthy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/include/odm_debug.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/odm_debug.h b/drivers/staging/rtl8188eu/include/odm_debug.h index db7b44e16c48..6bc905756d1e 100644 --- a/drivers/staging/rtl8188eu/include/odm_debug.h +++ b/drivers/staging/rtl8188eu/include/odm_debug.h @@ -83,9 +83,8 @@ #define ODM_COMP_INIT BIT31 /*------------------------Export Marco Definition---------------------------*/ -#define DbgPrint pr_info #define RT_PRINTK(fmt, args...) \ - DbgPrint("%s(): " fmt, __func__, ## args); + pr_info("%s(): " fmt, __func__, ## args); #ifndef ASSERT #define ASSERT(expr) @@ -94,7 +93,7 @@ #define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ if (((comp) & pDM_Odm->DebugComponents) && \ (level <= pDM_Odm->DebugLevel)) { \ - DbgPrint("[ODM-8188E] "); \ + pr_info("[ODM-8188E] "); \ RT_PRINTK fmt; \ } @@ -106,27 +105,27 @@ #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if (!(expr)) { \ - DbgPrint("Assertion failed! %s at ......\n", #expr); \ - DbgPrint(" ......%s,%s,line=%d\n", __FILE__, \ + pr_info("Assertion failed! %s at ......\n", #expr); \ + pr_info(" ......%s,%s,line=%d\n", __FILE__, \ __func__, __LINE__); \ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { DbgPrint("==> %s\n", __func__); } -#define ODM_dbg_exit() { DbgPrint("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __func__, str); } +#define ODM_dbg_enter() { pr_info("==> %s\n", __func__); } +#define ODM_dbg_exit() { pr_info("<== %s\n", __func__); } +#define ODM_dbg_trace(str) { pr_info("%s:%s\n", __func__, str); } #define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ if (((comp) & pDM_Odm->DebugComponents) && \ (level <= pDM_Odm->DebugLevel)) { \ int __i; \ u8 *__ptr = (u8 *)ptr; \ - DbgPrint("[ODM] "); \ - DbgPrint(title_str); \ - DbgPrint(" "); \ + pr_info("[ODM] "); \ + pr_info(title_str); \ + pr_info(" "); \ for (__i = 0; __i < 6; __i++) \ - DbgPrint("%02X%s", __ptr[__i], (__i == 5)?"":"-");\ - DbgPrint("\n"); \ + pr_info("%02X%s", __ptr[__i], (__i == 5)?"":"-");\ + pr_info("\n"); \ } void ODM_InitDebugSetting(struct odm_dm_struct *pDM_Odm); -- GitLab From 049845dfd60968edab1f928993ae0d7fcb27703e Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:27:21 +0530 Subject: [PATCH 0328/9457] staging: rtl8188eu: core: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 9935e66935af..350d2e73b419 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -456,7 +456,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork->IELength = 0; /* Added by Albert 2009/02/18 */ - /* If the the driver wants to use the bssid to create the connection. */ + /* If the driver wants to use the bssid to create the connection. */ /* If not, we have to copy the connecting AP's MAC address to it so that */ /* the driver just has the bssid information for PMKIDList searching. */ -- GitLab From 0b7d9bc2a44908363dfaf119b2538e839aab45c0 Mon Sep 17 00:00:00 2001 From: Mahati Chamarthy Date: Mon, 6 Oct 2014 22:07:17 +0530 Subject: [PATCH 0329/9457] Staging: rtl8188eu: include: Remove unused macros This patch removes macros that are never used. Signed-off-by: Mahati Chamarthy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/include/odm_debug.h | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/odm_debug.h b/drivers/staging/rtl8188eu/include/odm_debug.h index 6bc905756d1e..914f831a5b77 100644 --- a/drivers/staging/rtl8188eu/include/odm_debug.h +++ b/drivers/staging/rtl8188eu/include/odm_debug.h @@ -97,12 +97,6 @@ RT_PRINTK fmt; \ } -#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ - if (((comp) & pDM_Odm->DebugComponents) && \ - (level <= pDM_Odm->DebugLevel)) { \ - RT_PRINTK fmt; \ - } - #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if (!(expr)) { \ pr_info("Assertion failed! %s at ......\n", #expr); \ @@ -111,22 +105,6 @@ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { pr_info("==> %s\n", __func__); } -#define ODM_dbg_exit() { pr_info("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { pr_info("%s:%s\n", __func__, str); } - -#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ - if (((comp) & pDM_Odm->DebugComponents) && \ - (level <= pDM_Odm->DebugLevel)) { \ - int __i; \ - u8 *__ptr = (u8 *)ptr; \ - pr_info("[ODM] "); \ - pr_info(title_str); \ - pr_info(" "); \ - for (__i = 0; __i < 6; __i++) \ - pr_info("%02X%s", __ptr[__i], (__i == 5)?"":"-");\ - pr_info("\n"); \ - } void ODM_InitDebugSetting(struct odm_dm_struct *pDM_Odm); -- GitLab From 9cc56fa82765203cf32429dbb47f4f2c73f138aa Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 18:39:47 +0530 Subject: [PATCH 0330/9457] Staging: rtl8188eu: core: Remove variable that is not very useful. The following patch removes a variable which is not very useful using coccinelle. The following semaintic patch was used: @@ identifier ret; @@ -int ret = 0; ... when != ret when strict -return ret; +return 0; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_ap.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index 7de7ba197be1..d61842ed673e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -1186,7 +1186,6 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr) int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) { struct list_head *plist, *phead; - int ret = 0; struct rtw_wlan_acl_node *paclnode; struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; @@ -1217,7 +1216,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) spin_unlock_bh(&(pacl_node_q->lock)); DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); - return ret; + return 0; } static void update_bcn_fixed_ie(struct adapter *padapter) @@ -1753,7 +1752,6 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta, int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1761,7 +1759,7 @@ int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) - return ret; + return 0; DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); @@ -1782,13 +1780,12 @@ int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset) issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); - return ret; + return 0; } int rtw_sta_flush(struct adapter *padapter) { struct list_head *phead, *plist; - int ret = 0; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -1798,7 +1795,7 @@ int rtw_sta_flush(struct adapter *padapter) DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) - return ret; + return 0; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; @@ -1822,7 +1819,7 @@ int rtw_sta_flush(struct adapter *padapter) associated_clients_update(padapter, true); - return ret; + return 0; } /* called > TSR LEVEL for USB or SDIO Interface*/ -- GitLab From 44396c7bce449eb6bcb862c6336f5da9ff44c867 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Fri, 3 Oct 2014 13:23:00 +0300 Subject: [PATCH 0331/9457] staging: gs_fpgaboot: remove unnecessary 'out of memory' message This patch fixes "Possible unnecessary 'out of memory' message" checkpatch.pl warning in gs_fpgaboot.c Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 6aa9d7c30139..1875bd3b823f 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -316,10 +316,8 @@ static int gs_fpgaboot(void) struct fpgaimage *fimage; fimage = kmalloc(sizeof(struct fpgaimage), GFP_KERNEL); - if (fimage == NULL) { - pr_err("No memory is available\n"); + if (fimage == NULL) goto err_out; - } err = gs_load_image(fimage, file); if (err) { -- GitLab From 1f74d5f688faea24107de37893b7fd5a0e56ac49 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Fri, 3 Oct 2014 14:04:25 +0300 Subject: [PATCH 0332/9457] staging: speakup: Fixed else after return or break warning The following patch fixes the checkpatch.pl warning: drivers/staging/speakup/kobjects.c:812 warning: else is not generally useful after a break or return Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/kobjects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index bcc7f62654f4..1486147f3bac 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -809,10 +809,10 @@ static ssize_t message_store_helper(const char *buf, size_t count, if (msg_stored == -ENOMEM) reset = 1; break; - } else { - used++; } + used++; + cp = linefeed + 1; } -- GitLab From 333c474b828e52bce8731e97fef27c2e950b5728 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Sat, 4 Oct 2014 13:36:27 +0300 Subject: [PATCH 0333/9457] staging: speakup: Change char * array type as static const This patch fixes "char * array declaration might be better as static const" checkpatch.pl warning in kobjects.c Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/kobjects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index 1486147f3bac..b12c76de60b0 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -81,7 +81,7 @@ static ssize_t chars_chartab_show(struct kobject *kobj, static void report_char_chartab_status(int reset, int received, int used, int rejected, int do_characters) { - char *object_type[] = { + static char const *object_type[] = { "character class entries", "character descriptions", }; -- GitLab From 0f709488c52c11abc36f7f9ba077f8232cb7cd9d Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Tue, 7 Oct 2014 10:59:18 +0300 Subject: [PATCH 0334/9457] staging: speakup: Change char * array type as static const This patch fixes "char * array declaration might be better as static const" checkpatch.pl warning in main.c Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 3f30a1b6e72c..e9f0c150d246 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -695,7 +695,7 @@ static void say_next_word(struct vc_data *vc) static void spell_word(struct vc_data *vc) { - static char *delay_str[] = { "", ",", ".", ". .", ". . ." }; + static char const *delay_str[] = { "", ",", ".", ". .", ". . ." }; char *cp = buf, *str_cap = spk_str_caps_stop; char *cp1, *last_cap = spk_str_caps_stop; u_char ch; -- GitLab From c65cfb5e5a456759bce8b4986407d95a2d02e8a8 Mon Sep 17 00:00:00 2001 From: Esra Altintas Date: Tue, 7 Oct 2014 22:45:55 +0300 Subject: [PATCH 0335/9457] staging: speakup: remove jiffies comparison using time_after_eq() in speakup_dtlk.c The following patch fixes the checkpatch.pl warning: WARNING: Comparing jiffies is almost always wrong; prefer time_after, time_before and friends Signed-off-by: Esra Altintas Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/speakup_dtlk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index d7d515273896..4e059ea78d4c 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -231,7 +231,7 @@ static void do_catch_up(struct spk_synth *synth) if (ch == '\n') ch = PROCSPEECH; spk_out(ch); - if ((jiffies >= jiff_max) && (ch == SPACE)) { + if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { spk_out(PROCSPEECH); spin_lock_irqsave(&speakup_info.spinlock, flags); delay_time_val = delay_time->u.n.value; -- GitLab From c9a114e70ab0da81797da84e5bc8737e4e82ad91 Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Tue, 7 Oct 2014 06:33:54 +0530 Subject: [PATCH 0336/9457] staging: octeon-usb: Removed unnessecary else after return WARNING: else is generally not useful after return or break checkpatch.pl warning in octeon-hcd.c Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon-usb/octeon-hcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 5f9db4cbb381..6ddde6af7e3a 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -640,8 +640,7 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe) { if (pipe->pid_toggle) return 2; /* Data1 */ - else - return 0; /* Data0 */ + return 0; /* Data0 */ } /** -- GitLab From 6c71ea543a0f0132edbe40854b0e31bf9507af5b Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Tue, 7 Oct 2014 15:58:48 +0300 Subject: [PATCH 0337/9457] staging: octeon: Fix warning of prefer ether_addr_copy. This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file ethernet.c Pahole shows that the addresses are aligned. Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 8f9e3fb4871d..47d4277dc1ab 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -452,7 +452,7 @@ int cvm_oct_common_init(struct net_device *dev) mac = of_get_mac_address(priv->of_node); if (mac) - memcpy(dev->dev_addr, mac, ETH_ALEN); + ether_addr_copy(dev->dev_addr, mac); else eth_hw_addr_random(dev); -- GitLab From 109d672065bd9045cbb00a0759faa1c94d8a7f98 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Wed, 8 Oct 2014 00:41:10 +0200 Subject: [PATCH 0338/9457] staging: unisys: Remove typedef and rename struct to lowercase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove typedef and rename struct to lowercase (ultra_segment_state) in unisys Signed-off-by: Veronika Kabátová Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlframework.h | 10 +++++----- .../include/channels/controlvmchannel.h | 6 +++--- .../unisys/visorchipset/visorchipset_main.c | 15 ++++++++------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index fd4726e754ea..bbcf5ac4f0b7 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -36,7 +36,7 @@ /* Define Ki scale page to be traditional 4KB page */ #define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki) -typedef struct _ULTRA_SEGMENT_STATE { +struct ultra_segment_state { u16 Enabled:1; /* Bit 0: May enter other states */ u16 Active:1; /* Bit 1: Assigned to active partition */ u16 Alive:1; /* Bit 2: Configure message sent to @@ -53,14 +53,14 @@ typedef struct _ULTRA_SEGMENT_STATE { * operating */ /* Note: don't use high bit unless we need to switch to ushort * which is non-compliant */ -} ULTRA_SEGMENT_STATE; -static const ULTRA_SEGMENT_STATE SegmentStateRunning = { +}; +static const struct ultra_segment_state SegmentStateRunning = { 1, 1, 1, 0, 1, 1, 1, 1 }; -static const ULTRA_SEGMENT_STATE SegmentStatePaused = { +static const struct ultra_segment_state SegmentStatePaused = { 1, 1, 1, 0, 1, 1, 1, 0 }; -static const ULTRA_SEGMENT_STATE SegmentStateStandby = { +static const struct ultra_segment_state SegmentStateStandby = { 1, 1, 0, 0, 1, 1, 1, 0 }; typedef union { diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index cbe152f8ea27..cfd99997cfee 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -390,13 +390,13 @@ typedef struct _CONTROLVM_MESSAGE_PACKET { } reconfigureDevice; /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { u32 busNo; - ULTRA_SEGMENT_STATE state; + struct ultra_segment_state state; u8 reserved[2]; /* Natural alignment purposes */ } busChangeState; /* for CONTROLVM_BUS_CHANGESTATE */ struct { u32 busNo; u32 devNo; - ULTRA_SEGMENT_STATE state; + struct ultra_segment_state state; struct { u32 physicalDevice:1; /* =1 if message is for * a physical device */ @@ -407,7 +407,7 @@ typedef struct _CONTROLVM_MESSAGE_PACKET { struct { u32 busNo; u32 devNo; - ULTRA_SEGMENT_STATE state; + struct ultra_segment_state state; u8 reserved[6]; /* Natural alignment purposes */ } deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index ce4e731a2e4a..320124a240ac 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -346,9 +346,9 @@ static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response); static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, ULTRA_CHIPSET_FEATURE features); -static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER * - msgHdr, int response, - ULTRA_SEGMENT_STATE state); +static void controlvm_respond_physdev_changestate( + CONTROLVM_MESSAGE_HEADER *msgHdr, int response, + struct ultra_segment_state state); static ssize_t toolaction_show(struct device *dev, struct device_attribute *attr, @@ -741,7 +741,8 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, ULTRA_SEGMENT_STATE state) + int response, struct ultra_segment_state + state) { CONTROLVM_MESSAGE outmsg; @@ -857,7 +858,7 @@ bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) static void device_changestate_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response, - ULTRA_SEGMENT_STATE responseState) + struct ultra_segment_state responseState) { VISORCHIPSET_DEVICE_INFO *p = NULL; CONTROLVM_MESSAGE outmsg; @@ -991,7 +992,7 @@ bus_epilog(u32 busNo, } static void -device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, +device_epilog(u32 busNo, u32 devNo, struct ultra_segment_state state, u32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr, int response, BOOL needResponse, BOOL for_visorbus) { @@ -1303,7 +1304,7 @@ my_device_changestate(CONTROLVM_MESSAGE *inmsg) CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; ulong busNo = cmd->deviceChangeState.busNo; ulong devNo = cmd->deviceChangeState.devNo; - ULTRA_SEGMENT_STATE state = cmd->deviceChangeState.state; + struct ultra_segment_state state = cmd->deviceChangeState.state; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; -- GitLab From ab08cda0e9af22d0bb03af4b69c63644a142d886 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Sun, 5 Oct 2014 01:47:37 +0300 Subject: [PATCH 0339/9457] staging: comedi: Fix cast to restricted __be32 This patch fixes "cast to restricted __be32" sparse warning in ni_stc.h Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_stc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index 29efce30eb7f..131e9049f21b 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -1464,7 +1464,7 @@ struct ni_private { unsigned short ai_fifo_buffer[0x2000]; uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; - uint32_t serial_number; + __be32 serial_number; struct mite_struct *mite; struct mite_channel *ai_mite_chan; -- GitLab From 2d00485cacf729149eccceccadac95f86df3b1e1 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:26:49 +0530 Subject: [PATCH 0340/9457] staging: comedi: drivers: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 01796cd28e5b..8ed150689f97 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -35,7 +35,7 @@ * automatically. * * The PCI230+ and PCI260+ have the same PCI device IDs as the PCI230 and - * PCI260, but can be distinguished by the the size of the PCI regions. A + * PCI260, but can be distinguished by the size of the PCI regions. A * card will be configured as a "+" model if detected as such. * * Subdevices: -- GitLab From ea0db9b2fd284104a9fd1cead85252a83375c71f Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 11:59:29 +0530 Subject: [PATCH 0341/9457] Staging: comedi: drivers: Compressed two lines of code into one. The following patch compresses two lines of code into one using coccinelle and removes an unused variable. The following semantic patch was used: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Heena Sirwani Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mite.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 4f7829010a99..a43b5beffc4b 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -494,13 +494,10 @@ EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub); unsigned mite_dma_tcr(struct mite_channel *mite_chan) { struct mite_struct *mite = mite_chan->mite; - int tcr; int lkar; lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); - tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); - - return tcr; + return readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); } EXPORT_SYMBOL_GPL(mite_dma_tcr); -- GitLab From fe43ec5350d34244dedf3e6647f991f7c348c82d Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 13:46:09 +0530 Subject: [PATCH 0342/9457] Staging: comedi: Compressed two lines of code into one. The following patch compressed two lines of code into one using coccinelle and removed an unused variable. The semantic patch used is as follows: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 495969f46e76..224af2b2a685 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1718,7 +1718,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file) { struct comedi_subdevice *s; - int ret; if (arg >= dev->n_subdevices) return -EINVAL; @@ -1732,9 +1731,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, if (s->busy != file) return -EBUSY; - ret = do_cancel(dev, s); - - return ret; + return do_cancel(dev, s); } /* -- GitLab From c6c04f05115eaca1badc0232a8f75e2e120f8f15 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 7 Oct 2014 23:20:24 +0530 Subject: [PATCH 0343/9457] staging: comedi: Remove unecessary function and it's call Function aref_invalid has unreachable code as it right now just returns 0 after declaring a variable. This patch removes this function and it's single call. As it is static so it's obvious that it is not used anywhere other than this file or somewhere, where this is included. I also build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/range.c | 36 +--------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index b6849545b810..9a1dc56f21d1 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -97,39 +97,6 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, return 0; } -static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) -{ - unsigned int aref; - - /* disable reporting invalid arefs... maybe someday */ - return 0; - - aref = CR_AREF(chanspec); - switch (aref) { - case AREF_DIFF: - if (s->subdev_flags & SDF_DIFF) - return 0; - break; - case AREF_COMMON: - if (s->subdev_flags & SDF_COMMON) - return 0; - break; - case AREF_GROUND: - if (s->subdev_flags & SDF_GROUND) - return 0; - break; - case AREF_OTHER: - if (s->subdev_flags & SDF_OTHER) - return 0; - break; - default: - break; - } - dev_dbg(s->device->class_dev, "subdevice does not support aref %i", - aref); - return 1; -} - /** * comedi_check_chanlist() - Validate each element in a chanlist. * @s: comedi_subdevice struct @@ -153,8 +120,7 @@ int comedi_check_chanlist(struct comedi_subdevice *s, int n, else range_len = 0; if (chan >= s->n_chan || - CR_RANGE(chanspec) >= range_len || - aref_invalid(s, chanspec)) { + CR_RANGE(chanspec) >= range_len) { dev_warn(dev->class_dev, "bad chanlist[%d]=0x%08x chan=%d range length=%d\n", i, chanspec, chan, range_len); -- GitLab From ca4be88731488574e436406f540881fd7cf19b8d Mon Sep 17 00:00:00 2001 From: Thomas Gummerer Date: Tue, 7 Oct 2014 10:10:32 +0200 Subject: [PATCH 0344/9457] staging: lustre: fix sparse errors Mark functions static that are not used or declared outside of lo.c. Signed-off-by: Thomas Gummerer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/lo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c index be31dfc5fa4b..17e1643fd675 100644 --- a/drivers/staging/lustre/lnet/lnet/lo.c +++ b/drivers/staging/lustre/lnet/lnet/lo.c @@ -35,7 +35,7 @@ #define DEBUG_SUBSYSTEM S_LNET #include "../../include/linux/lnet/lib-lnet.h" -int +static int lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) { LASSERT(!lntmsg->msg_routing); @@ -44,7 +44,7 @@ lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) return lnet_parse(ni, &lntmsg->msg_hdr, ni->ni_nid, lntmsg, 0); } -int +static int lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed, unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov, @@ -86,7 +86,7 @@ lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, static int lolnd_instanced; -void +static void lolnd_shutdown(lnet_ni_t *ni) { CDEBUG(D_NET, "shutdown\n"); @@ -95,7 +95,7 @@ lolnd_shutdown(lnet_ni_t *ni) lolnd_instanced = 0; } -int +static int lolnd_startup(lnet_ni_t *ni) { LASSERT(ni->ni_lnd == &the_lolnd); -- GitLab From 4d1d413aea840f0cc2fa025c0f52702bab9a53dc Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Fri, 3 Oct 2014 10:17:22 -0500 Subject: [PATCH 0345/9457] drivers: staging: lustre: Fix "else should follow close brace '}'" errors Fix checkpatch.pl "else should follow close brace '}'" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/include/linux/lustre_compat25.h | 6 ++---- drivers/staging/lustre/lustre/llite/dir.c | 3 +-- drivers/staging/lustre/lustre/lov/lov_pack.c | 3 +-- drivers/staging/lustre/lustre/obdclass/dt_object.c | 3 +-- drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c | 3 +-- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h index e03775606712..8156b4c0f568 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h @@ -137,8 +137,7 @@ ll_quota_on(struct super_block *sb, int off, int ver, char *name, int remount) ); path_put(&path); return rc; - } - else + } else return -ENOSYS; } @@ -147,8 +146,7 @@ static inline int ll_quota_off(struct super_block *sb, int off, int remount) if (sb->s_qcop->quota_off) { return sb->s_qcop->quota_off(sb, off ); - } - else + } else return -ENOSYS; } diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 662bdf04a451..9e8bfdcfe5a4 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1509,8 +1509,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) cmd == LL_IOC_MDC_GETINFO)) { rc = 0; goto skip_lmm; - } - else + } else goto out_req; } diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index 5edd6a3a9c54..5356d5324176 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -438,8 +438,7 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, if (copy_from_user(&lum, lump, lum_size)) { rc = -EFAULT; goto out_set; - } - else if ((lum.lmm_magic != LOV_USER_MAGIC) && + } else if ((lum.lmm_magic != LOV_USER_MAGIC) && (lum.lmm_magic != LOV_USER_MAGIC_V3)) { rc = -EINVAL; goto out_set; diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c index 909f542f8b86..e7be26ec7521 100644 --- a/drivers/staging/lustre/lustre/obdclass/dt_object.c +++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c @@ -332,8 +332,7 @@ static struct dt_object *dt_reg_open(const struct lu_env *env, result = dt_lookup_dir(env, p, name, fid); if (result == 0){ o = dt_locate(env, dt, fid); - } - else + } else o = ERR_PTR(result); return o; diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index 87b9764a4f19..1f4e76896da5 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -694,8 +694,7 @@ static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file, if (queue == PTLRPC_NRS_QUEUE_HP && !nrs_svc_has_hp(svc)) { rc = -ENODEV; goto out; - } - else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc)) + } else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc)) queue = PTLRPC_NRS_QUEUE_REG; /** -- GitLab From 9c234f6cb4c4cfe681bc8364c24152443684639f Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Thu, 2 Oct 2014 18:10:23 -0500 Subject: [PATCH 0346/9457] drivers: staging: lustre: Fix "'foo* bar' should be 'foo *bar'" errors Fix checkpatch.pl "'foo* bar' should be 'foo *bar'" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/dt_object.h | 2 +- drivers/staging/lustre/lustre/include/lu_object.h | 4 ++-- drivers/staging/lustre/lustre/include/lustre_lib.h | 2 +- drivers/staging/lustre/lustre/include/lustre_net.h | 2 +- drivers/staging/lustre/lustre/include/obd_class.h | 2 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- drivers/staging/lustre/lustre/llite/statahead.c | 2 +- drivers/staging/lustre/lustre/obdclass/llog_obd.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/pinger.c | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h index 212ebaea8555..c2e7622469ca 100644 --- a/drivers/staging/lustre/lustre/include/dt_object.h +++ b/drivers/staging/lustre/lustre/include/dt_object.h @@ -617,7 +617,7 @@ struct dt_index_operations { int (*load)(const struct lu_env *env, const struct dt_it *di, __u64 hash); int (*key_rec)(const struct lu_env *env, - const struct dt_it *di, void* key_rec); + const struct dt_it *di, void *key_rec); } dio_it; }; diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index 6015ee5c4b64..2ddb2b054d8d 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -1120,7 +1120,7 @@ struct lu_context_key { }; #define LU_KEY_INIT(mod, type) \ - static void* mod##_key_init(const struct lu_context *ctx, \ + static void *mod##_key_init(const struct lu_context *ctx, \ struct lu_context_key *key) \ { \ type *value; \ @@ -1137,7 +1137,7 @@ struct lu_context_key { #define LU_KEY_FINI(mod, type) \ static void mod##_key_fini(const struct lu_context *ctx, \ - struct lu_context_key *key, void* data) \ + struct lu_context_key *key, void *data) \ { \ type *info = data; \ \ diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index 12c7590e61fa..bf135630c39a 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -85,7 +85,7 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id); /* client.c */ -int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg* lcfg); +int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg); struct client_obd *client_conn2cli(struct lustre_handle *conn); struct md_open_data; diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 0a024d3cfeb7..d4da2431b407 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -2951,7 +2951,7 @@ void ptlrpcd_decref(void); * procfs output related functions * @{ */ -const char* ll_opcode2str(__u32 opcode); +const char *ll_opcode2str(__u32 opcode); #if defined (CONFIG_PROC_FS) void ptlrpc_lprocfs_register_obd(struct obd_device *obd); void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd); diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 882e40bd584c..4a29261c514d 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -414,7 +414,7 @@ do { \ #define EXP_MD_COUNTER_INCREMENT(exp, op) #endif -static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat* tmp) +static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat *tmp) { /* Always add in ldlm_stats */ tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 3c086b4d0ea5..e45070d7f219 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -2399,7 +2399,7 @@ char *ll_get_fsname(struct super_block *sb, char *buf, int buflen) return buf; } -static char* ll_d_path(struct dentry *dentry, char *buf, int bufsize) +static char *ll_d_path(struct dentry *dentry, char *buf, int bufsize) { char *path = NULL; diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 06b71bcf97a7..85d451f17c02 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -915,7 +915,7 @@ static int do_sa_revalidate(struct inode *dir, struct ll_sa_entry *entry, return rc; } -static void ll_statahead_one(struct dentry *parent, const char* entry_name, +static void ll_statahead_one(struct dentry *parent, const char *entry_name, int entry_name_len) { struct inode *dir = parent->d_inode; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c index da769db0af77..978d886a1103 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c @@ -42,7 +42,7 @@ #include "llog_internal.h" /* helper functions for calling the llog obd methods */ -static struct llog_ctxt* llog_new_ctxt(struct obd_device *obd) +static struct llog_ctxt *llog_new_ctxt(struct obd_device *obd) { struct llog_ctxt *ctxt; diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index 1f4e76896da5..0c3f667d498f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -175,7 +175,7 @@ const char *ll_opcode2str(__u32 opcode) return ll_rpc_opcode_table[offset].opname; } -const char* ll_eopcode2str(__u32 opcode) +const char *ll_eopcode2str(__u32 opcode) { LASSERT(ll_eopcode_table[opcode].opcode == opcode); return ll_eopcode_table[opcode].opname; diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index e8d00408117a..b9cbbbd5322e 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -428,7 +428,7 @@ EXPORT_SYMBOL(ptlrpc_pinger_del_import); * Register a timeout callback to the pinger list, and the callback will * be called when timeout happens. */ -struct timeout_item* ptlrpc_new_timeout(int time, enum timeout_event event, +struct timeout_item *ptlrpc_new_timeout(int time, enum timeout_event event, timeout_cb_t cb, void *data) { struct timeout_item *ti; -- GitLab From c15fd709a657ee67c5a4dacc74a696af767939e3 Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Tue, 7 Oct 2014 01:26:00 +0530 Subject: [PATCH 0347/9457] staging: bcm: Removed else which was not required after return WARNING:else is generally not required after return checkpatch.pl warning in LeakyBucket.c Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/LeakyBucket.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index d6b55f993b57..86b79d6438d4 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -82,13 +82,12 @@ static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet if (false != psSF->bValid && psSF->ucDirection) { if (0 != psSF->uiCurrentTokenCount) { return psSF->uiCurrentTokenCount; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, - DBG_LVL_ALL, - "Not enough tokens in queue %zd Available %u\n", - psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); - psSF->uiPendedLast = 1; } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, + DBG_LVL_ALL, + "Not enough tokens in queue %zd Available %u\n", + psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); + psSF->uiPendedLast = 1; } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", -- GitLab From 9d1ffa072462443cdf0fdb24d81db7c9e7a4867d Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Tue, 7 Oct 2014 06:09:19 +0530 Subject: [PATCH 0348/9457] staging: bcm: Removed unnecessary else after return WARNING: else is generally not required after return chaeckpatch.pl warning in led_control.c Signed-off-by: Sarah Khan Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/led_control.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index 074fc39ed678..181f17ff0a24 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -95,8 +95,7 @@ static INT ScaleRateofTransfer(ULONG rate) return 9; else if ((rate > 500) && (rate <= 600)) return 10; - else - return MAX_NUM_OF_BLINKS; + return MAX_NUM_OF_BLINKS; } static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad, -- GitLab From 821a464c1c369bce8b2b82565fb702836b78a99e Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Tue, 7 Oct 2014 17:59:24 +0530 Subject: [PATCH 0349/9457] staging: bcm: Removed unnecessary braces after return WARNING: else is generally not useful after return checkpatch.pl warning in PHSModule.c Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/PHSModule.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 5f4e503d54ec..262613436d1e 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -1244,19 +1244,15 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, if (eClsContext == eActiveClassifierRuleContext) return ERR_CLSASSIFIER_TABLE_FULL; - else { - /* Lets replace the oldest rule if we are looking in - * old Rule table */ - if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) - psaClassifiertable->uiOldestPhsRuleIndex = 0; - - iClassifierIndex = - psaClassifiertable->uiOldestPhsRuleIndex; - psClassifierRules = - &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + /* Lets replace the oldest rule if we are looking in + * old Rule table */ + if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) + psaClassifiertable->uiOldestPhsRuleIndex = 0; - (psaClassifiertable->uiOldestPhsRuleIndex)++; - } + iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; + psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; + + psaClassifiertable->uiOldestPhsRuleIndex++; } if (eClsContext == eOldClassifierRuleContext) { -- GitLab From f39b81f55012a1d27012fcdc850b537d3050be1f Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Tue, 7 Oct 2014 14:37:31 +0300 Subject: [PATCH 0350/9457] staging: bcm: Fixed else after return or break warning This patch fixes checkpatch.pl warning in files of bcm WARNING : else is not generally useful after a break or return Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index e5bcfec2a6cf..1f31b8f05884 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -102,12 +102,11 @@ int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, DBG_LVL_ALL, "WRM failed status :%d", retval); psIntfAdapter->psAdapter->DeviceAccess = false; return retval; - } else { - psIntfAdapter->psAdapter->DeviceAccess = false; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, - DBG_LVL_ALL, "WRM sent %d", retval); - return STATUS_SUCCESS; } + psIntfAdapter->psAdapter->DeviceAccess = false; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, + DBG_LVL_ALL, "WRM sent %d", retval); + return STATUS_SUCCESS; } int BcmRDM(void *arg, -- GitLab From 0bfacefd092130a397ce8f5fc13d10f846c96e28 Mon Sep 17 00:00:00 2001 From: Roxana Blaj Date: Fri, 3 Oct 2014 15:36:11 +0300 Subject: [PATCH 0351/9457] staging: rtl8192u: add spaces around '=', '+=', '<', '||' This fixes the checkpatch.pl errors: ERROR: spaces required around that '=' (ctx:VxV) ERROR: spaces required around that '+=' (ctx:VxV) ERROR: spaces required around that '<' (ctx:VxV) ERROR: spaces required around that '||' (ctx:VxE) Signed-off-by: Roxana Blaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index f66ad8a0dfe0..b301b757d2f5 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -78,17 +78,17 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, * Transform from little endian to big endian * and pending zero */ - for (i=0; i < frag_length; i+=4) { - *seg_ptr++ = ((i+0)txbuf_size= (u16)i; + tcb_desc->txbuf_size = (u16)i; skb_put(skb, i); - if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ + if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||\ (priv->ieee80211->queue_stop)) { RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); -- GitLab From 896be407e61abcfd5eb978e64e3b1acdd3519a7e Mon Sep 17 00:00:00 2001 From: Roxana Blaj Date: Fri, 3 Oct 2014 15:36:12 +0300 Subject: [PATCH 0352/9457] staging: rtl8192u: remove unnecessary line continuations This fixes the checkpatch.pl warning: WARNING: Avoid unnecessary line continuations Signed-off-by: Roxana Blaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index b301b757d2f5..2c321b7b8bae 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -88,7 +88,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, skb_put(skb, i); if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index) || - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||\ + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || (priv->ieee80211->queue_stop)) { RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); -- GitLab From 095ff453473b3fdbb529e8d3b555dcaff00edc6f Mon Sep 17 00:00:00 2001 From: Roxana Blaj Date: Fri, 3 Oct 2014 15:36:13 +0300 Subject: [PATCH 0353/9457] staging: rtl8192u: add intermediate variable This use for more readability. It also fixes checkpatch.pl warning: WARNING: line over 80 characters Signed-off-by: Roxana Blaj Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 2c321b7b8bae..c230be290ab6 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -45,6 +45,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, unsigned char *seg_ptr; cb_desc *tcb_desc; u8 bLastIniPkt; + u8 index; firmware_init_param(dev); //Fragmentation might be required @@ -87,9 +88,10 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, tcb_desc->txbuf_size = (u16)i; skb_put(skb, i); - if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index) || - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || - (priv->ieee80211->queue_stop)) { + index = tcb_desc->queue_index; + if (!priv->ieee80211->check_nic_enough_desc(dev, index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[index])) || + (priv->ieee80211->queue_stop)) { RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); } else { -- GitLab From f8c6b7e3c33d422e9bef47660619d7ff6ce7e85b Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Sat, 4 Oct 2014 22:25:46 +0300 Subject: [PATCH 0354/9457] staging: rtl8192u: Remove defined but unused function This patch fixes "symbol 'dm_change_rxpath_selection_setting' was not declared. Should it be static?" sparse warning in r8192U_dm.c After setting it as static, it causes to unused function sparse warning, because it is not used anywhere. Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_dm.c | 79 ---------------------------- 1 file changed, 79 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index b0b66fba563b..bda153d55f7a 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1810,85 +1810,6 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, } } /* DM_ChangeDynamicInitGainThresh */ -void -dm_change_rxpath_selection_setting( - struct net_device *dev, - s32 DM_Type, - s32 DM_Value) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - prate_adaptive pRA = (prate_adaptive)&(priv->rate_adaptive); - - - if(DM_Type == 0) - { - if(DM_Value > 1) - DM_Value = 1; - DM_RxPathSelTable.Enable = (u8)DM_Value; - } - else if(DM_Type == 1) - { - if(DM_Value > 1) - DM_Value = 1; - DM_RxPathSelTable.DbgMode = (u8)DM_Value; - } - else if(DM_Type == 2) - { - if(DM_Value > 40) - DM_Value = 40; - DM_RxPathSelTable.SS_TH_low = (u8)DM_Value; - } - else if(DM_Type == 3) - { - if(DM_Value > 25) - DM_Value = 25; - DM_RxPathSelTable.diff_TH = (u8)DM_Value; - } - else if(DM_Type == 4) - { - if(DM_Value >= CCK_Rx_Version_MAX) - DM_Value = CCK_Rx_Version_1; - DM_RxPathSelTable.cck_method= (u8)DM_Value; - } - else if(DM_Type == 10) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value; - } - else if(DM_Type == 11) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value; - } - else if(DM_Type == 12) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value; - } - else if(DM_Type == 13) - { - if(DM_Value > 100) - DM_Value = 50; - DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value; - } - else if(DM_Type == 20) - { - if(DM_Value > 1) - DM_Value = 1; - pRA->ping_rssi_enable = (u8)DM_Value; - } - else if(DM_Type == 21) - { - if(DM_Value > 30) - DM_Value = 30; - pRA->ping_rssi_thresh_for_ra = DM_Value; - } -} - - /*----------------------------------------------------------------------------- * Function: dm_dig_init() * -- GitLab From c7a348cf8db9cf2c202850f7eb1b70e4d7401da0 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Sat, 4 Oct 2014 22:25:47 +0300 Subject: [PATCH 0355/9457] staging: rtl8192u: Fixes symbol as static This patch fixes "symbol 'ieee80211_send_probe_requests_rsl' was not declared. Should it be static?" sparse warning in ieee80211_softmac.c Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index a85bb232be97..88f4836176c6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -411,7 +411,7 @@ static void ieee80211_send_probe(struct ieee80211_device *ieee) } } -void ieee80211_send_probe_requests(struct ieee80211_device *ieee) +static void ieee80211_send_probe_requests(struct ieee80211_device *ieee) { if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ ieee80211_send_probe(ieee); -- GitLab From 657eb9798aed8f62685e97ea0cd6dc6df6b9f458 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Tue, 7 Oct 2014 00:05:45 +0300 Subject: [PATCH 0356/9457] staging: rtl8192u: Missing a blank line after declarations. Missing a blank line after declarations" checkpatch.pl warning in r819xU_phy.c Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_phy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index e9c15fe8ded5..058960251bac 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -1463,6 +1463,7 @@ void rtl8192_SwChnl_WorkItem(struct net_device *dev) u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) { struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_CH, "%s(), SwChnlInProgress: %d\n", __func__, priv->SwChnlInProgress); if (!priv->up) -- GitLab From f9eb26cfcad6a684fbb2671ca32a6961ae601c04 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 7 Oct 2014 23:21:07 +0530 Subject: [PATCH 0357/9457] staging: rtl8192u: ieee80211: Indent if statement This patch indents single statement below if statement in files of rtl8192u: ieee80211. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 6 +++--- drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 88f4836176c6..a1c745b1cf99 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -517,7 +517,7 @@ static void ieee80211_softmac_scan_wq(struct work_struct *work) goto out; ieee->set_chan(ieee->dev, ieee->current_network.channel); if(channel_map[ieee->current_network.channel] == 1) - ieee80211_send_probe_requests(ieee); + ieee80211_send_probe_requests(ieee); queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); @@ -1103,7 +1103,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco if(ieee->short_slot) hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); if (wmm_info_len) //QOS - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); hdr->listen_interval = 0xa; //FIXME @@ -1533,7 +1533,7 @@ void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) break; if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) - ieee80211_softmac_new_net(ieee, target); + ieee80211_softmac_new_net(ieee, target); } spin_unlock_irqrestore(&ieee->lock, flags); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 68f5ede86633..ae1b3cf2866c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -172,7 +172,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, iwe.cmd = IWEVCUSTOM; iwe.u.data.length = p - custom; if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); + start = iwe_stream_add_point(info, start, stop, &iwe, custom); /* Add quality statistics */ /* TODO: Fix these values... */ iwe.cmd = IWEVQUAL; -- GitLab From 3286ae5f62a51edccdc40729a79ed5da54f00646 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Tue, 7 Oct 2014 15:16:17 +0300 Subject: [PATCH 0358/9457] staging: rtl8192u: Add space after enum definition Fix checkpatch.pl warning: WARNING:missing space after enum definition Signed-off-by: Melike Yurtoglu Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_firmware.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_firmware.h b/drivers/staging/rtl8192u/r819xU_firmware.h index c48c884aa1af..cfa222350a9a 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.h +++ b/drivers/staging/rtl8192u/r819xU_firmware.h @@ -12,15 +12,15 @@ #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN) //#endif -typedef enum _firmware_init_step{ +typedef enum _firmware_init_step { FW_INIT_STEP0_BOOT = 0, FW_INIT_STEP1_MAIN = 1, FW_INIT_STEP2_DATA = 2, -}firmware_init_step_e; +} firmware_init_step_e; -typedef enum _opt_rst_type{ +typedef enum _opt_rst_type { OPT_SYSTEM_RESET = 0, OPT_FIRMWARE_RESET = 1, -}opt_rst_type_e; +} opt_rst_type_e; #endif -- GitLab From ac23fed85801685017fc7bf4567c6dfa024719b7 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Fri, 3 Oct 2014 16:13:06 +0300 Subject: [PATCH 0359/9457] staging: vt6655: Fixed else after return or break warning The following patch fixes the checkpatch.pl warning: drivers/staging/vt6655/hostap.c warning: else is not generally useful after a break or return Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/hostap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index ae0dade229d8..2db08df0656d 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -182,8 +182,7 @@ int vt6655_hostap_set_hostapd(struct vnt_private *pDevice, if (val) return hostap_enable_hostapd(pDevice, rtnl_locked); - else - return hostap_disable_hostapd(pDevice, rtnl_locked); + return hostap_disable_hostapd(pDevice, rtnl_locked); } /* -- GitLab From 99fdb36ec3651f946122c0f6261738bf4f89b8ae Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Fri, 3 Oct 2014 17:09:49 +0300 Subject: [PATCH 0360/9457] staging: vt6655: Fixed else after return or break warning The following patch fixes the checkpatch.pl warning: drivers/staging/vt6655/vntwifi.c warning: else is not generally useful after a break or return Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/vntwifi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 59f66fe47352..9cc3a67399ed 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -578,8 +578,7 @@ VNTWIFIbyGetKeyCypher( if (bGroupKey) return pMgmt->byCSSGK; - else - return pMgmt->byCSSPK; + return pMgmt->byCSSPK; } bool @@ -614,8 +613,7 @@ VNTWIFIwGetMaxSupportRate( if (pMgmt->eCurrentPHYMode == PHY_TYPE_11A) return RATE_6M; - else - return RATE_1M; + return RATE_1M; } void -- GitLab From d84e63378b69bc5e12ffd1cdecbf3401badc62eb Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Mon, 6 Oct 2014 13:23:35 +0300 Subject: [PATCH 0361/9457] staging: vt6655: Fix do not use // c99 comments. This patch fixes "do not use // C99 comments" errors in datarate.h Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/datarate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index 0509c4fd2a42..d55b07455cc2 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -75,4 +75,4 @@ DATARATEbyGetRateIdx( unsigned char byRate ); -#endif //__DATARATE_H__ +#endif /* __DATARATE_H__ */ -- GitLab From b7f0790d73f189ef1584656644ca53663fa96c22 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Mon, 6 Oct 2014 16:21:46 +0300 Subject: [PATCH 0362/9457] staging: vt6655: Fixed else after return or break warning. This patch fixes multiple instances of checkpatch.pl WARNING : else is not generally useful after a break or return in device_main.c Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 54e16f40d8ed..8baeb8c4f4f1 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2915,9 +2915,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { rc = -EFAULT; break; - } else { - rc = 0; } + rc = 0; pReq = (PSCmdRequest)rq; pReq->wResult = MAGIC_CODE; break; @@ -2934,9 +2933,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { rc = -EFAULT; break; - } else { - rc = 0; } + rc = 0; if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy))) return -EBUSY; -- GitLab From 3aaa06e1cbfcd8d24be2f369b414242c29776eb2 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Mon, 6 Oct 2014 23:26:50 +0300 Subject: [PATCH 0363/9457] staging: vt6655: fix do not use // c99 comments. This patch fixes "do not use // C99 comments" checkpatch.pl errors in hostap.h Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/hostap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h index 17df4e403fcf..fc5f9ed4674b 100644 --- a/drivers/staging/vt6655/hostap.h +++ b/drivers/staging/vt6655/hostap.h @@ -55,4 +55,4 @@ int vt6655_hostap_set_hostapd(struct vnt_private *, int val, int rtnl_locked); int vt6655_hostap_ioctl(struct vnt_private *, struct iw_point *p); -#endif // __HOSTAP_H__ +#endif /* __HOSTAP_H__ */ -- GitLab From 14cd1df4baf1f6f2dd0b521ec99afa151427b06b Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 15:46:53 +0300 Subject: [PATCH 0364/9457] staging: vt6655: Remove unnecessary else after return This patch fixes checkpatch.pl warning in files of vt6655 WARNING: else is not generally useful after a break or return Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index de54923e8861..b8a64c07b97a 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1792,18 +1792,17 @@ BBuGetFrameTime( uFrameTime++; return uPreamble + uFrameTime; - } else { - uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */ - uTmp = ((uFrameTime * uRate) - 22) / 8; - if (cbFrameLength != uTmp) - uFrameTime++; + } + uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */ + uTmp = ((uFrameTime * uRate) - 22) / 8; + if (cbFrameLength != uTmp) + uFrameTime++; - uFrameTime = uFrameTime * 4; /* ??????? */ - if (byPktType != PK_TYPE_11A) - uFrameTime += 6; /* ?????? */ + uFrameTime = uFrameTime * 4; /* ??????? */ + if (byPktType != PK_TYPE_11A) + uFrameTime += 6; /* ?????? */ - return 20 + uFrameTime; /* ?????? */ - } + return 20 + uFrameTime; /* ?????? */ } /* -- GitLab From 61d566a5a3b6ee9aed5c89463af4342a26f295dc Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 20:41:48 +0530 Subject: [PATCH 0365/9457] staging: vt6655: Remove unnecessary cast for argument of kfree This patch removes all occurrences of unnecessary cast on the argument to kfree, all over in rtl8712. There is no need of the cast on the argument to kfree. Greped to find occurrences. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 8baeb8c4f4f1..1e1664ec1663 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1204,7 +1204,7 @@ static void device_free_rd0_ring(struct vnt_private *pDevice) dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); + kfree(pDesc->pRDInfo); } } @@ -1221,7 +1221,7 @@ static void device_free_rd1_ring(struct vnt_private *pDevice) dev_kfree_skb(pRDInfo->skb); - kfree((void *)pDesc->pRDInfo); + kfree(pDesc->pRDInfo); } } @@ -1305,7 +1305,7 @@ static void device_free_td0_ring(struct vnt_private *pDevice) if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); + kfree(pDesc->pTDInfo); } } @@ -1324,7 +1324,7 @@ static void device_free_td1_ring(struct vnt_private *pDevice) if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((void *)pDesc->pTDInfo); + kfree(pDesc->pTDInfo); } } -- GitLab From 0c074871f75e11c4dd383e0d83fc9b09ae685125 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 19:01:47 +0300 Subject: [PATCH 0366/9457] staging: vt6655: Removing else after break statement to fix warning This patch fixes the checkpatch.pl warning in key.c file WARNING: else is not useful after a break or return Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/key.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 211afae306c7..12e8b87c0a60 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -374,9 +374,8 @@ bool KeybRemoveKey( } s_vCheckKeyTableValid(pTable, dwIoBase); return true; - } else { - return false; } + return false; } for (i = 0; i < MAX_KEY_TABLE; i++) { @@ -394,9 +393,8 @@ bool KeybRemoveKey( } s_vCheckKeyTableValid(pTable, dwIoBase); return true; - } else { - return false; } + return false; } } return false; -- GitLab From 5de55f6524b3d8687f5d13aa7827e2798fd2cff7 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 18:38:51 +0300 Subject: [PATCH 0367/9457] staging: vt6655: Use ether_addr_copy function This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file key.c Pahole shows that the addresses are aligned Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 12e8b87c0a60..02caffb06e59 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -267,7 +267,7 @@ bool KeybSetKey( } } if (j < (MAX_KEY_TABLE-1)) { - memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN); + ether_addr_copy(pTable->KeyTable[j].abyBSSID, pbyBSSID); pTable->KeyTable[j].bInUse = true; if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key -- GitLab From c5e1150178abe6fc3d967953dc74694e51b07ff3 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 18:25:31 +0300 Subject: [PATCH 0368/9457] staging: vt6655: Use ether_addr_copy function This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file device_main.c Pahole shows that the addresses are aligned Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 1e1664ec1663..3eb8e5c5366e 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -362,9 +362,9 @@ device_set_options(struct vnt_private *pDevice) unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); + ether_addr_copy(pDevice->abyBroadcastAddr, abyBroadcastAddr); + ether_addr_copy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042); + ether_addr_copy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel); pDevice->uChannel = pDevice->sOpts.channel_num; pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh; -- GitLab From 5ab665eb2485e6fbbb763eceb7cc60930461a4e8 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 16:05:47 +0300 Subject: [PATCH 0369/9457] staging: vt6655: Use ether_addr_copy function This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file iwctl.c Pahole shows that the addresses are aligned Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iwctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 14a62bdae278..94b4859e2f25 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -1756,7 +1756,7 @@ int iwctl_siwencodeext(struct net_device *dev, } /**************Translate iw_encode_ext to viawget_wpa_param****************/ - memcpy(param->addr, addr, ETH_ALEN); + ether_addr_copy(param->addr, addr); param->u.wpa_key.alg_name = (int)alg_name; param->u.wpa_key.set_tx = set_tx; param->u.wpa_key.key_index = key_idx; -- GitLab From cfafe92c1e9408190748f528a8d21d6d8678c248 Mon Sep 17 00:00:00 2001 From: Kumari Radha Date: Wed, 8 Oct 2014 12:44:57 +0530 Subject: [PATCH 0370/9457] staging: media: omap24xx: Remove unnecessary 'out of memory' message This patch removes unnecessay out of memory message fixing the following checkpach.pl warning in omap24xxcam.c: WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Kumari Radha Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap24xx/omap24xxcam.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/media/omap24xx/omap24xxcam.c b/drivers/staging/media/omap24xx/omap24xxcam.c index d590b3e8b70c..5ca2bf5353fe 100644 --- a/drivers/staging/media/omap24xx/omap24xxcam.c +++ b/drivers/staging/media/omap24xx/omap24xxcam.c @@ -1737,10 +1737,8 @@ static int omap24xxcam_probe(struct platform_device *pdev) int irq; cam = kzalloc(sizeof(*cam), GFP_KERNEL); - if (!cam) { - dev_err(&pdev->dev, "could not allocate memory\n"); + if (!cam) goto err; - } platform_set_drvdata(pdev, cam); -- GitLab From b717a65a7b3156d8b078a72559d6ae63a1b55d54 Mon Sep 17 00:00:00 2001 From: Kumari Radha Date: Wed, 8 Oct 2014 12:45:44 +0530 Subject: [PATCH 0371/9457] staging: media: omap4iss: Remove unnecessary 'out of memory' message This patch removes unnecessay out of memory message fixing the following checkpach.pl warning in iss.c: WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Kumari Radha Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap4iss/iss.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index d548371db65a..6e9e869e5875 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1357,10 +1357,8 @@ static int iss_probe(struct platform_device *pdev) return -EINVAL; iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL); - if (!iss) { - dev_err(&pdev->dev, "Could not allocate memory\n"); + if (!iss) return -ENOMEM; - } mutex_init(&iss->iss_mutex); -- GitLab From d92c54f6c079988317c5c95bdd2dadf7ce71e45c Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 7 Oct 2014 23:20:07 +0530 Subject: [PATCH 0372/9457] staging: media: ompa4iss: Replace sprintf with snprintf This patch replaces sprintf with snprintf as sprintf does not check for buffer overflow. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap4iss/iss_csi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 92c2d5b743c7..47f86b306cb6 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1231,7 +1231,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) v4l2_subdev_init(sd, &csi2_ops); sd->internal_ops = &csi2_internal_ops; - sprintf(name, "CSI2%s", subname); + snprintf(name, sizeof(name), "CSI2%s", subname); snprintf(sd->name, sizeof(sd->name), "OMAP4 ISS %s", name); sd->grp_id = 1 << 16; /* group ID for iss subdevs */ -- GitLab From c3cefd3c3c289e93934bba7b6c746b3d6698777c Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 11:17:28 +0530 Subject: [PATCH 0373/9457] staging: media: cxd2009: use usleep_range() This patch fixes checkpatch.pl warning in file cxd2099.c WARNING : msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/cxd2099/cxd2099.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c index 73e7b2c9e4a7..657ea480c6e7 100644 --- a/drivers/staging/media/cxd2099/cxd2099.c +++ b/drivers/staging/media/cxd2099/cxd2099.c @@ -527,7 +527,7 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot) u8 val; #endif for (i = 0; i < 100; i++) { - msleep(10); + usleep_range(10000, 11000); #if 0 read_reg(ci, 0x06, &val); dev_info(&ci->i2c->dev, "%d:%02x\n", i, val); -- GitLab From 2129e17ef511a3682a731fdee9b678596bc32b75 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 09:12:17 +0530 Subject: [PATCH 0374/9457] staging: media: davinci_vpfe: Replace *__iomem with __iomem * This patch fixes defective positional use of __iomem, wherever present in media: davinci_vpfe. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- .../staging/media/davinci_vpfe/dm365_ipipe.h | 4 +- .../media/davinci_vpfe/dm365_ipipe_hw.c | 62 +++++++++---------- .../media/davinci_vpfe/dm365_ipipe_hw.h | 58 ++++++++--------- .../media/davinci_vpfe/dm365_ipipeif.h | 2 +- .../staging/media/davinci_vpfe/dm365_isif.c | 10 +-- .../staging/media/davinci_vpfe/dm365_isif.h | 6 +- .../media/davinci_vpfe/dm365_resizer.h | 2 +- 7 files changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe.h index cf4204603eb8..d81b29e19309 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.h @@ -120,8 +120,8 @@ struct vpfe_ipipe_device { enum ipipe_input_entity input; unsigned int output; struct v4l2_ctrl_handler ctrls; - void *__iomem base_addr; - void *__iomem isp5_base_addr; + void __iomem *base_addr; + void __iomem *isp5_base_addr; struct ipipe_module_params config; }; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c index b2daf5e63f88..e2cdbb1a0454 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c @@ -24,7 +24,7 @@ #define IPIPE_MODE_CONTINUOUS 0 #define IPIPE_MODE_SINGLE_SHOT 1 -static void ipipe_clock_enable(void *__iomem base_addr) +static void ipipe_clock_enable(void __iomem *base_addr) { /* enable IPIPE MMR for register write access */ regw_ip(base_addr, IPIPE_GCK_MMR_DEFAULT, IPIPE_GCK_MMR); @@ -34,7 +34,7 @@ static void ipipe_clock_enable(void *__iomem base_addr) } static void -rsz_set_common_params(void *__iomem rsz_base, struct resizer_params *params) +rsz_set_common_params(void __iomem *rsz_base, struct resizer_params *params) { struct rsz_common_params *rsz_common = ¶ms->rsz_common; u32 val; @@ -66,7 +66,7 @@ rsz_set_common_params(void *__iomem rsz_base, struct resizer_params *params) } static void -rsz_set_rsz_regs(void *__iomem rsz_base, unsigned int rsz_id, +rsz_set_rsz_regs(void __iomem *rsz_base, unsigned int rsz_id, struct resizer_params *params) { struct resizer_scale_param *rsc_params; @@ -171,7 +171,7 @@ rsz_set_rsz_regs(void *__iomem rsz_base, unsigned int rsz_id, /*set the registers of either RSZ0 or RSZ1 */ static void -ipipe_setup_resizer(void *__iomem rsz_base, struct resizer_params *params) +ipipe_setup_resizer(void __iomem *rsz_base, struct resizer_params *params) { /* enable MMR gate to write to Resizer */ regw_rsz(rsz_base, 1, RSZ_GCK_MMR); @@ -302,8 +302,8 @@ int config_rsz_hw(struct vpfe_resizer_device *resizer, struct resizer_params *config) { struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); - void *__iomem ipipe_base = vpfe_dev->vpfe_ipipe.base_addr; - void *__iomem rsz_base = vpfe_dev->vpfe_resizer.base_addr; + void __iomem *ipipe_base = vpfe_dev->vpfe_ipipe.base_addr; + void __iomem *rsz_base = vpfe_dev->vpfe_resizer.base_addr; /* enable VPSS clock */ vpss_enable_clock(VPSS_IPIPE_CLOCK, 1); @@ -315,7 +315,7 @@ int config_rsz_hw(struct vpfe_resizer_device *resizer, } static void -rsz_set_y_address(void *__iomem rsz_base, unsigned int address, +rsz_set_y_address(void __iomem *rsz_base, unsigned int address, unsigned int offset) { u32 val; @@ -330,7 +330,7 @@ rsz_set_y_address(void *__iomem rsz_base, unsigned int address, } static void -rsz_set_c_address(void *__iomem rsz_base, unsigned int address, +rsz_set_c_address(void __iomem *rsz_base, unsigned int address, unsigned int offset) { u32 val; @@ -352,7 +352,7 @@ rsz_set_c_address(void *__iomem rsz_base, unsigned int address, * @address: the address to set */ int -resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, +resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params, int resize_no, unsigned int address) { struct resizer_scale_param *rsc_param; @@ -411,7 +411,7 @@ resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, } void -ipipe_set_lutdpc_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_lutdpc_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_lutdpc *dpc) { u32 max_tbl_size = LUT_DPC_MAX_SIZE >> 1; @@ -446,7 +446,7 @@ ipipe_set_lutdpc_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } static void -set_dpc_thresholds(void *__iomem base_addr, +set_dpc_thresholds(void __iomem *base_addr, struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_thr) { regw_ip(base_addr, dpc_thr->corr_thr.r & OTFDPC_DPC2_THR_MASK, @@ -467,7 +467,7 @@ set_dpc_thresholds(void *__iomem base_addr, DPC_OTF_2D_THR_B); } -void ipipe_set_otfdpc_regs(void *__iomem base_addr, +void ipipe_set_otfdpc_regs(void __iomem *base_addr, struct vpfe_ipipe_otfdpc *otfdpc) { struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0 = &otfdpc->alg_cfg.dpc_2_0; @@ -523,7 +523,7 @@ void ipipe_set_otfdpc_regs(void *__iomem base_addr, /* 2D Noise filter */ void -ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, +ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_nf *noise_filter) { @@ -571,7 +571,7 @@ ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, (((decimal & 0x1f) | ((integer & 0x7) << 5))) /* Green Imbalance Correction */ -void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic) +void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic) { u32 val; @@ -609,7 +609,7 @@ void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic) #define IPIPE_U13Q9(decimal, integer) \ (((decimal & 0x1ff) | ((integer & 0xf) << 9))) /* White balance */ -void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb) +void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb) { u32 val; @@ -635,7 +635,7 @@ void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb) } /* CFA */ -void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa) +void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa) { ipipe_clock_enable(base_addr); @@ -671,7 +671,7 @@ void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa) } void -ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, +ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_rgb2rgb *rgb) { u32 offset_mask = RGB2RGB_1_OFST_MASK; @@ -724,7 +724,7 @@ ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, } static void -ipipe_update_gamma_tbl(void *__iomem isp5_base_addr, +ipipe_update_gamma_tbl(void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma_entry *table, int size, u32 addr) { int count; @@ -738,7 +738,7 @@ ipipe_update_gamma_tbl(void *__iomem isp5_base_addr, } void -ipipe_set_gamma_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_gamma_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma *gamma) { int table_size; @@ -770,7 +770,7 @@ ipipe_set_gamma_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } void -ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_3d_lut_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d) { struct vpfe_ipipe_3d_lut_entry *tbl; @@ -819,7 +819,7 @@ ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, /* Lumina adjustments */ void -ipipe_set_lum_adj_regs(void *__iomem base_addr, struct ipipe_lum_adj *lum_adj) +ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj) { u32 val; @@ -834,7 +834,7 @@ ipipe_set_lum_adj_regs(void *__iomem base_addr, struct ipipe_lum_adj *lum_adj) #define IPIPE_S12Q8(decimal, integer) \ (((decimal & 0xff) | ((integer & 0xf) << 8))) -void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, +void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr, struct vpfe_ipipe_rgb2yuv *yuv) { u32 val; @@ -866,7 +866,7 @@ void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, /* YUV 422 conversion */ void -ipipe_set_yuv422_conv_regs(void *__iomem base_addr, +ipipe_set_yuv422_conv_regs(void __iomem *base_addr, struct vpfe_ipipe_yuv422_conv *conv) { u32 val; @@ -879,7 +879,7 @@ ipipe_set_yuv422_conv_regs(void *__iomem base_addr, } void -ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_gbce_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_gbce *gbce) { unsigned int count; @@ -906,7 +906,7 @@ ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } void -ipipe_set_ee_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, +ipipe_set_ee_regs(void __iomem *base_addr, void __iomem *isp5_base_addr, struct vpfe_ipipe_yee *ee) { unsigned int count; @@ -950,7 +950,7 @@ ipipe_set_ee_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, } /* Chromatic Artifact Correction. CAR */ -static void ipipe_set_mf(void *__iomem base_addr) +static void ipipe_set_mf(void __iomem *base_addr) { /* typ to dynamic switch */ regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP); @@ -959,7 +959,7 @@ static void ipipe_set_mf(void *__iomem base_addr) } static void -ipipe_set_gain_ctrl(void *__iomem base_addr, struct vpfe_ipipe_car *car) +ipipe_set_gain_ctrl(void __iomem *base_addr, struct vpfe_ipipe_car *car) { regw_ip(base_addr, VPFE_IPIPE_CAR_CHR_GAIN_CTRL, CAR_TYP); regw_ip(base_addr, car->hpf, CAR_HPF_TYP); @@ -975,7 +975,7 @@ ipipe_set_gain_ctrl(void *__iomem base_addr, struct vpfe_ipipe_car *car) CAR_GN2_MIN); } -void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car) +void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car) { u32 val; @@ -1010,7 +1010,7 @@ void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car) } /* Chromatic Gain Suppression */ -void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs) +void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs) { ipipe_clock_enable(base_addr); regw_ip(base_addr, cgs->en, CGS_EN); @@ -1025,12 +1025,12 @@ void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs) regw_ip(base_addr, cgs->h_min, CGS_GN1_H_MIN); } -void rsz_src_enable(void *__iomem rsz_base, int enable) +void rsz_src_enable(void __iomem *rsz_base, int enable) { regw_rsz(rsz_base, enable, RSZ_SRC_EN); } -int rsz_enable(void *__iomem rsz_base, int rsz_id, int enable) +int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable) { if (rsz_id == RSZ_A) { regw_rsz(rsz_base, enable, RSZ_EN_A); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h index 81176fb9d164..2bf2f7a69173 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h @@ -490,29 +490,29 @@ #define RSZ_RGB_TYP_SHIFT 0 #define RSZ_RGB_ALPHA_MASK 0xff -static inline u32 regr_ip(void *__iomem addr, u32 offset) +static inline u32 regr_ip(void __iomem *addr, u32 offset) { return readl(addr + offset); } -static inline void regw_ip(void *__iomem addr, u32 val, u32 offset) +static inline void regw_ip(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); } -static inline u32 w_ip_table(void *__iomem addr, u32 val, u32 offset) +static inline u32 w_ip_table(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); return val; } -static inline u32 regr_rsz(void *__iomem addr, u32 offset) +static inline u32 regr_rsz(void __iomem *addr, u32 offset) { return readl(addr + offset); } -static inline u32 regw_rsz(void *__iomem addr, u32 val, u32 offset) +static inline u32 regw_rsz(void __iomem *addr, u32 val, u32 offset) { writel(val, addr + offset); @@ -520,39 +520,39 @@ static inline u32 regw_rsz(void *__iomem addr, u32 val, u32 offset) } int config_ipipe_hw(struct vpfe_ipipe_device *ipipe); -int resizer_set_outaddr(void *__iomem rsz_base, struct resizer_params *params, +int resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params, int resize_no, unsigned int address); -int rsz_enable(void *__iomem rsz_base, int rsz_id, int enable); -void rsz_src_enable(void *__iomem rsz_base, int enable); +int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable); +void rsz_src_enable(void __iomem *rsz_base, int enable); void rsz_set_in_pix_format(unsigned char y_c); int config_rsz_hw(struct vpfe_resizer_device *resizer, struct resizer_params *config); -void ipipe_set_d2f_regs(void *__iomem base_addr, unsigned int id, +void ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_nf *noise_filter); -void ipipe_set_rgb2rgb_regs(void *__iomem base_addr, unsigned int id, +void ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id, struct vpfe_ipipe_rgb2rgb *rgb); -void ipipe_set_yuv422_conv_regs(void *__iomem base_addr, +void ipipe_set_yuv422_conv_regs(void __iomem *base_addr, struct vpfe_ipipe_yuv422_conv *conv); -void ipipe_set_lum_adj_regs(void *__iomem base_addr, +void ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj); -void ipipe_set_rgb2ycbcr_regs(void *__iomem base_addr, +void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr, struct vpfe_ipipe_rgb2yuv *yuv); -void ipipe_set_lutdpc_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_lutdpc *lutdpc); -void ipipe_set_otfdpc_regs(void *__iomem base_addr, +void ipipe_set_lutdpc_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_lutdpc *lutdpc); +void ipipe_set_otfdpc_regs(void __iomem *base_addr, struct vpfe_ipipe_otfdpc *otfdpc); -void ipipe_set_3d_lut_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d); -void ipipe_set_gamma_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_gamma *gamma); -void ipipe_set_ee_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_yee *ee); -void ipipe_set_gbce_regs(void *__iomem base_addr, - void *__iomem isp5_base_addr, struct vpfe_ipipe_gbce *gbce); -void ipipe_set_gic_regs(void *__iomem base_addr, struct vpfe_ipipe_gic *gic); -void ipipe_set_cfa_regs(void *__iomem base_addr, struct vpfe_ipipe_cfa *cfa); -void ipipe_set_car_regs(void *__iomem base_addr, struct vpfe_ipipe_car *car); -void ipipe_set_cgs_regs(void *__iomem base_addr, struct vpfe_ipipe_cgs *cgs); -void ipipe_set_wb_regs(void *__iomem base_addr, struct vpfe_ipipe_wb *wb); +void ipipe_set_3d_lut_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d); +void ipipe_set_gamma_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma *gamma); +void ipipe_set_ee_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_yee *ee); +void ipipe_set_gbce_regs(void __iomem *base_addr, + void __iomem *isp5_base_addr, struct vpfe_ipipe_gbce *gbce); +void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic); +void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa); +void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car); +void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs); +void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb); #endif /* _DAVINCI_VPFE_DM365_IPIPE_HW_H */ diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h index 608701fc5fed..cea3d61335af 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h @@ -134,7 +134,7 @@ struct vpfe_ipipeif_device { unsigned int output; struct vpfe_video_device video_in; struct v4l2_ctrl_handler ctrls; - void *__iomem ipipeif_base_addr; + void __iomem *ipipeif_base_addr; struct ipipeif_params config; int dpcm_predictor; int gain; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 0d535b062e4e..f00cd9f23227 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -70,17 +70,17 @@ static const u32 isif_srggb_pattern = ISIF_COLPTN_Gb_G << ISIF_CCOLP_CP15_4 | ISIF_COLPTN_B_Mg << ISIF_CCOLP_CP17_6; -static inline u32 isif_read(void *__iomem base_addr, u32 offset) +static inline u32 isif_read(void __iomem *base_addr, u32 offset) { return readl(base_addr + offset); } -static inline void isif_write(void *__iomem base_addr, u32 val, u32 offset) +static inline void isif_write(void __iomem *base_addr, u32 val, u32 offset) { writel(val, base_addr + offset); } -static inline u32 isif_merge(void *__iomem base_addr, u32 mask, u32 val, +static inline u32 isif_merge(void __iomem *base_addr, u32 mask, u32 val, u32 offset) { u32 new_val = (isif_read(base_addr, offset) & ~mask) | (val & mask); @@ -646,7 +646,7 @@ static void isif_config_gain_offset(struct vpfe_isif_device *isif) { struct vpfe_isif_gain_offsets_adj *gain_off_ptr = &isif->isif_cfg.bayer.config_params.gain_offset; - void *__iomem base = isif->isif_cfg.base_addr; + void __iomem *base = isif->isif_cfg.base_addr; u32 val; val = ((gain_off_ptr->gain_sdram_en & 1) << GAIN_SDRAM_EN_SHIFT) | @@ -1991,7 +1991,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev) struct media_entity *me = &sd->entity; static resource_size_t res_len; struct resource *res; - void *__iomem addr; + void __iomem *addr; int status; int i = 0; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.h b/drivers/staging/media/davinci_vpfe/dm365_isif.h index 473fd2cfe350..89e814e9c0d7 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.h +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.h @@ -159,9 +159,9 @@ struct isif_oper_config { struct isif_params_raw bayer; enum isif_data_pack data_pack; struct isif_gain_values isif_gain_params; - void *__iomem base_addr; - void *__iomem linear_tbl0_addr; - void *__iomem linear_tbl1_addr; + void __iomem *base_addr; + void __iomem *linear_tbl0_addr; + void __iomem *linear_tbl1_addr; }; #define ISIF_PAD_SINK 0 diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.h b/drivers/staging/media/davinci_vpfe/dm365_resizer.h index 59a79422b914..93b0f44030aa 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.h +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.h @@ -228,7 +228,7 @@ struct vpfe_resizer_device { struct dm365_resizer_device resizer_a; struct dm365_resizer_device resizer_b; struct resizer_params config; - void *__iomem base_addr; + void __iomem *base_addr; }; int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, -- GitLab From 2430454e92860003cb52122fd661177e9eeb6165 Mon Sep 17 00:00:00 2001 From: Mahati Chamarthy Date: Wed, 8 Oct 2014 19:55:16 +0530 Subject: [PATCH 0375/9457] Staging: rtl8723au: include: Remove unused macros This patch removes macros that are never used. Signed-off-by: Mahati Chamarthy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/odm_debug.h | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/staging/rtl8723au/include/odm_debug.h b/drivers/staging/rtl8723au/include/odm_debug.h index 8509a04b6a52..83be5bab9e09 100644 --- a/drivers/staging/rtl8723au/include/odm_debug.h +++ b/drivers/staging/rtl8723au/include/odm_debug.h @@ -104,12 +104,6 @@ RT_PRINTK fmt; \ } -#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ - if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \ - { \ - RT_PRINTK fmt; \ - } - #define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ if(!(expr)) { \ printk("Assertion failed! %s at ......\n", #expr); \ @@ -117,21 +111,6 @@ RT_PRINTK fmt; \ ASSERT(false); \ } -#define ODM_dbg_enter() { printk("==> %s\n", __func__); } -#define ODM_dbg_exit() { printk("<== %s\n", __func__); } -#define ODM_dbg_trace(str) { printk("%s:%s\n", __func__, str); } - -#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ - if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel){ \ - int __i; \ - u8 * __ptr = (u8 *)ptr; \ - printk("[ODM] "); \ - printk(title_str); \ - printk(" "); \ - for (__i=0; __i < 6; __i++) \ - printk("%02X%s", __ptr[__i], (__i == 5) ? "" : "-"); \ - printk("\n"); \ - } void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm); -- GitLab From 4ecdc381d768eb978b782ccb66c959db7231f2d8 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 10:15:42 +0530 Subject: [PATCH 0376/9457] staging: rtl8723au: core: Replace open coded version with existing hweight function This patch replaces the open coded version with Linux's existing hweight functions. The original version checked each of the low four bits, accumulating and returning the result. Instead, use a mask to select those four bits, and pass the result to hweight8. It also makes the code in this function simpler. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 9f6ce7d071cd..799b9cf63263 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -117,12 +117,7 @@ Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType) u8 Efuse_CalculateWordCnts23a(u8 word_en) { - u8 word_cnts = 0; - if (!(word_en & BIT(0))) word_cnts++; /* 0 : write enable */ - if (!(word_en & BIT(1))) word_cnts++; - if (!(word_en & BIT(2))) word_cnts++; - if (!(word_en & BIT(3))) word_cnts++; - return word_cnts; + return hweight8((~word_en) & 0xf); } /* */ -- GitLab From aa21894b3c16d673eb394fc14f445a78cc572cb2 Mon Sep 17 00:00:00 2001 From: Kumari Radha Date: Sat, 4 Oct 2014 00:45:14 +0530 Subject: [PATCH 0377/9457] staging: ft1000: ft1000-pcmcia: Replace printks with netdev_ and dev_ This patch replaces printk(KERN_INFO ... with dev_info and printk(KERN_ERR ... with netdev_err fixing following checkpatch.pl warnings in ft1000_hw.c: WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... WARNING: Prefer [subsystem eg: netdev]_err([subsystem]dev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: Kumari Radha Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 44575c78cf0c..9574775ba3b5 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -2154,14 +2154,14 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, if (flarion_ft1000_cnt > 1) { flarion_ft1000_cnt--; - printk(KERN_INFO - "ft1000: This driver can not support more than one instance\n"); + dev_info(&link->dev, + "This driver can not support more than one instance\n"); return NULL; } dev = alloc_etherdev(sizeof(struct ft1000_info)); if (!dev) { - printk(KERN_ERR "ft1000: failed to allocate etherdev\n"); + dev_err(&link->dev, "Failed to allocate etherdev\n"); return NULL; } @@ -2209,17 +2209,17 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, dev->irq = link->irq; dev->base_addr = link->resource[0]->start; if (pcmcia_get_mac_from_cis(link, dev)) { - printk(KERN_ERR "ft1000: Could not read mac address\n"); + netdev_err(dev, "Could not read mac address\n"); goto err_dev; } if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) { - printk(KERN_ERR "ft1000: Could not request_irq\n"); + netdev_err(dev, "Could not request_irq\n"); goto err_dev; } if (request_region(dev->base_addr, 256, dev->name) == NULL) { - printk(KERN_ERR "ft1000: Could not request_region\n"); + netdev_err(dev, "Could not request_region\n"); goto err_irq; } -- GitLab From a15dbf99abd0ea9db59749a5cafd7caea84472dc Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Wed, 8 Oct 2014 12:20:23 +0530 Subject: [PATCH 0378/9457] Staging: lustre: Fix checkpatch error: Unnecessary comparison Removed unnecessary comparison against NULL to remove following checkpatch error: ERROR: spaces required around that '!=' Signed-off-by: Tina Johnson Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index e45070d7f219..0311b96a2eeb 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1122,7 +1122,7 @@ void ll_put_super(struct super_block *sb) } next = 0; - while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) !=NULL) + while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next))) class_manual_cleanup(obd); if (sbi->ll_flags & LL_SBI_VERBOSE) -- GitLab From ef96fdddcd386c88fee1f2078a174943472b615e Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 22:56:44 +0530 Subject: [PATCH 0379/9457] staging: lustre: lustre: llite: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Coccinelle script used : // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/rw26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 4c77ae8b9350..eac2131e6b85 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -417,7 +417,7 @@ static ssize_t ll_direct_IO_26(int rw, struct kiocb *iocb, result = iov_iter_get_pages_alloc(iter, &pages, count, &offs); if (likely(result > 0)) { - int n = (result + offs + PAGE_SIZE - 1) / PAGE_SIZE; + int n = DIV_ROUND_UP(result + offs, PAGE_SIZE); result = ll_direct_IO_26_seg(env, io, rw, inode, file->f_mapping, result, file_offset, -- GitLab From 7489df369598abef03f22ff97b1e2bfb044f1d02 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sun, 5 Oct 2014 10:33:56 +0200 Subject: [PATCH 0380/9457] staging: wlan-ng: add blank lines after declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes "missing blank line after declaration" warnings by checkpatch.pl Signed-off-by: Veronika Kabátová Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 1f2c78cc0086..20d146b61ba7 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -1376,6 +1376,7 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len); static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val) { int result = 0; + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); if (result == 0) *((u16 *) val) = le16_to_cpu(*((u16 *) val)); @@ -1385,6 +1386,7 @@ static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val) static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); } @@ -1402,6 +1404,7 @@ static inline int hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val) { u16 value = cpu_to_le16(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), NULL, NULL); } -- GitLab From fb282bcd9c957387097cde370905784993281df6 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Sat, 4 Oct 2014 02:30:35 +0300 Subject: [PATCH 0381/9457] staging: wlan-ng: remove unnecessary 'out of memory' message This patch fixes "Possible unnecessary 'out of memory' message" checkpatch.pl warning in hfa384x_usb.c Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 898bde73c59a..55d2f563e308 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3583,12 +3583,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, } skb = dev_alloc_skb(skblen); - if (skb == NULL) { - netdev_err(hw->wlandev->netdev, - "alloc_skb failed trying to allocate %d bytes\n", - skblen); + if (skb == NULL) return; - } /* only prepend the prism header if in the right mode */ if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && -- GitLab From 8e4ec4fe040861b69fcb2c60394355f0c600e38f Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 6 Oct 2014 11:26:39 +0530 Subject: [PATCH 0382/9457] staging: android: ion: Replace "the the " with "the" This patch replace "the the " with "the". The replacement couldn't be automated because sometimes the first "the" was meant to be another word. Signed-off-by: Tapasweni Pathak Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 56604f41ec48..290d4d22c102 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -902,7 +902,7 @@ void ion_pages_sync_for_device(struct device *dev, struct page *page, sg_set_page(&sg, page, size, 0); /* * This is not correct - sg_dma_address needs a dma_addr_t that is valid - * for the the targeted device, but this works on the currently targeted + * for the targeted device, but this works on the currently targeted * hardware. */ sg_dma_address(&sg) = page_to_phys(page); -- GitLab From 2ff6179f162b205fc98bb2083b653f46c52d6642 Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Sun, 5 Oct 2014 01:05:57 +0300 Subject: [PATCH 0383/9457] staging: vt6656: remove unnecessary 'out of memory' message This patch fixes "Possible unnecessary 'out of memory' message" checkpatch.pl warning in main_usb.c Signed-off-by: Melike Yurtoglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 2fbff907ce8a..04ae6a22f138 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -431,11 +431,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(struct vnt_usb_send_context), GFP_KERNEL); - if (tx_context == NULL) { - dev_err(&priv->usb->dev, - "allocate tx usb context failed\n"); + if (tx_context == NULL) goto free_tx; - } priv->tx_context[ii] = tx_context; tx_context->priv = priv; @@ -471,10 +468,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) } rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (rcb->skb == NULL) { - dev_err(&priv->usb->dev, "Failed to alloc rx skb\n"); + if (rcb->skb == NULL) goto free_rx_tx; - } rcb->in_use = false; @@ -491,7 +486,6 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); if (priv->int_buf.data_buf == NULL) { - dev_err(&priv->usb->dev, "Failed to alloc int buf\n"); usb_free_urb(priv->interrupt_urb); goto free_rx_tx; } -- GitLab From ca5dd0b83da6132a85b3c384eb0504a2c9cfd008 Mon Sep 17 00:00:00 2001 From: Heena Sirwani Date: Mon, 6 Oct 2014 10:19:09 +0530 Subject: [PATCH 0384/9457] Staging: dgnc: Compress two lines of code into one. The following patch merges two lines of code into one using coccinelle and removes unused variables. The semantic patch used is as follows: @@ expression ret; identifier f; @@ -ret = +return f(...); -return ret; Signed-off-by: Heena Sirwani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index a17f4f6095c8..f0b1ec7847e7 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -964,7 +964,6 @@ static int cls_drain(struct tty_struct *tty, uint seconds) unsigned long flags; struct channel_t *ch; struct un_t *un; - int rc = 0; if (!tty || tty->magic != TTY_MAGIC) return -ENXIO; @@ -984,12 +983,11 @@ static int cls_drain(struct tty_struct *tty, uint seconds) /* * NOTE: Do something with time passed in. */ - rc = wait_event_interruptible(un->un_flags_wait, - ((un->un_flags & UN_EMPTY) == 0)); /* If ret is non-zero, user ctrl-c'ed us */ - return rc; + return wait_event_interruptible(un->un_flags_wait, + ((un->un_flags & UN_EMPTY) == 0)); } -- GitLab From 1f26adc94a9f11440f4756e41b2f572afde61f5e Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Tue, 7 Oct 2014 13:08:12 +0300 Subject: [PATCH 0385/9457] staging: dgnc: Remove non-standard APR/RAPR printing macros This patch removes non-standard macros used by dgnc driver for printing error or debugging messages. These are replaced by dev_err/dev_dbg (when possible) or pr_err. There were cases where the message is completely removed since is not adding any useful information. Signed-off-by: Roberta Dobrescu Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 18 ++++-------------- drivers/staging/dgnc/dgnc_driver.c | 20 +++++++++----------- drivers/staging/dgnc/dgnc_driver.h | 15 ++------------- drivers/staging/dgnc/dgnc_neo.c | 25 +++++++++---------------- drivers/staging/dgnc/dgnc_tty.c | 15 +++++++++++---- 5 files changed, 35 insertions(+), 58 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index f0b1ec7847e7..c1c4bb9b0354 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -724,10 +724,8 @@ static void cls_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) { - APR(("poll_tasklet() - NULL or bad bd.\n")); + if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - } /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); @@ -799,20 +797,12 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) unsigned char poll_reg; unsigned long flags; - if (!brd) { - APR(("Received interrupt (%d) with null board associated\n", - irq)); - return IRQ_NONE; - } - /* - * Check to make sure its for us. + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. */ - if (brd->magic != DGNC_BOARD_MAGIC) { - APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", - irq)); + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return IRQ_NONE; - } spin_lock_irqsave(&brd->bd_intr_lock, flags); diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 21546659ff07..0eafd1f35a82 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -207,8 +207,6 @@ static int __init dgnc_init_module(void) { int rc = 0; - APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART)); - /* * Initialize global stuff */ @@ -254,8 +252,6 @@ static int dgnc_start(void) /* make sure that the globals are init'd before we do anything else */ dgnc_init_globals(); - APR(("For the tools package or updated drivers please visit http://www.digi.com\n")); - /* * Register our base character device into the kernel. * This allows the download daemon to connect to the downld device @@ -265,7 +261,7 @@ static int dgnc_start(void) */ rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); if (rc <= 0) { - APR(("Can't register dgnc driver device (%d)\n", rc)); + pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); return -ENXIO; } dgnc_Major = rc; @@ -281,7 +277,7 @@ static int dgnc_start(void) rc = dgnc_tty_preinit(); if (rc < 0) { - APR(("tty preinit - not enough memory (%d)\n", rc)); + pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc); return rc; } @@ -468,7 +464,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->membase = pci_resource_start(pdev, 4); if (!brd->membase) { - APR(("card has no PCI IO resources, failing board.\n")); + dev_err(&brd->pdev->dev, + "Card has no PCI IO resources, failing.\n"); return -ENODEV; } @@ -555,7 +552,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) break; default: - APR(("Did not find any compatible Neo or Classic PCI boards in system.\n")); + dev_err(&brd->pdev->dev, + "Didn't find any compatible Neo/Classic PCI boards.\n"); return -ENXIO; } @@ -567,7 +565,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_tty_register(brd); if (rc < 0) { dgnc_tty_uninit(brd); - APR(("Can't register tty devices (%d)\n", rc)); + pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; goto failed; @@ -575,7 +573,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_finalize_board_init(brd); if (rc < 0) { - APR(("Can't finalize board init (%d)\n", rc)); + pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; @@ -585,7 +583,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) rc = dgnc_tty_init(brd); if (rc < 0) { dgnc_tty_uninit(brd); - APR(("Can't init tty devices (%d)\n", rc)); + pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index f901957c757f..d5de3e2f2945 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -42,21 +42,10 @@ * *************************************************************************/ -/* - * Driver identification, error and debugging statments - * - * In theory, you can change all occurrences of "digi" in the next - * three lines, and the driver printk's will all automagically change. - * - * APR((fmt, args, ...)); Always prints message - */ +/* Driver identification, error and debugging statments */ #define PROCSTR "dgnc" /* /proc entries */ #define DEVSTR "/dev/dg/dgnc" /* /dev entries */ -#define DRVSTR "dgnc" /* Driver name string - * displayed by APR */ -#define APR(args) do { printk(DRVSTR": "); printk args; \ - } while (0) -#define RAPR(args) do { printk args; } while (0) +#define DRVSTR "dgnc" /* Driver name string */ #define TRC_TO_CONSOLE 1 diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index a5bd08fef270..27a525ead878 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -530,10 +530,11 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) int linestatus; unsigned long flags; - if (!brd) - return; - - if (brd->magic != DGNC_BOARD_MAGIC) + /* + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. + */ + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return; if (port > brd->maxports) @@ -869,10 +870,8 @@ static void neo_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) { - APR(("poll_tasklet() - NULL or bad bd.\n")); + if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - } /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); @@ -955,18 +954,12 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) unsigned long flags; unsigned long flags2; - if (!brd) { - APR(("Received interrupt (%d) with null board associated\n", irq)); - return IRQ_NONE; - } - /* - * Check to make sure its for us. + * Check to make sure it didn't receive interrupt with a null board + * associated or a board pointer that wasn't ours. */ - if (brd->magic != DGNC_BOARD_MAGIC) { - APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", irq)); + if (!brd || brd->magic != DGNC_BOARD_MAGIC) return IRQ_NONE; - } brd->intr_count++; diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 03c15069731f..1580bccc6a2d 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -233,7 +233,8 @@ int dgnc_tty_register(struct dgnc_board *brd) /* Register tty devices */ rc = tty_register_driver(&brd->SerialDriver); if (rc < 0) { - APR(("Can't register tty device (%d)\n", rc)); + dev_dbg(&brd->pdev->dev, + "Can't register tty device (%d)\n", rc); return rc; } brd->dgnc_Major_Serial_Registered = TRUE; @@ -281,7 +282,9 @@ int dgnc_tty_register(struct dgnc_board *brd) /* Register Transparent Print devices */ rc = tty_register_driver(&brd->PrintDriver); if (rc < 0) { - APR(("Can't register Transparent Print device (%d)\n", rc)); + dev_dbg(&brd->pdev->dev, + "Can't register Transparent Print device(%d)\n", + rc); return rc; } brd->dgnc_Major_TransparentPrint_Registered = TRUE; @@ -1546,14 +1549,18 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) * one, we've got real problems, since it means the * serial port won't be shutdown. */ - APR(("tty->count is 1, un open count is %d\n", un->un_open_count)); + dev_dbg(tty->dev, + "tty->count is 1, un open count is %d\n", + un->un_open_count); un->un_open_count = 1; } if (un->un_open_count) un->un_open_count--; else - APR(("bad serial port open count of %d\n", un->un_open_count)); + dev_dbg(tty->dev, + "bad serial port open count of %d\n", + un->un_open_count); ch->ch_open_count--; -- GitLab From feba47a74d21c8a9f31e1d6e7f60802bb3807246 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 13:49:51 +0300 Subject: [PATCH 0386/9457] staging: dgnc: Remove space before tabs This patch fixes the warning of "Please, no space before tab" produced by checkpatch.pl. The modified file: dgnc_tty.c Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 1580bccc6a2d..b0fcbe7bdfe4 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -3096,7 +3096,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, struct digi_getcounter buf; buf.norun = ch->ch_err_overrun; - buf.noflow = 0; /* The driver doesn't keep this stat */ + buf.noflow = 0; /* The driver doesn't keep this stat */ buf.nframe = ch->ch_err_frame; buf.nparity = ch->ch_err_parity; buf.nbreak = ch->ch_err_break; -- GitLab From 399521341942bf7458302c23ef5736be4501ef49 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Tue, 7 Oct 2014 15:26:23 +0300 Subject: [PATCH 0387/9457] staging: gdm724x: Fix warning of prefer ether_addr_copy. This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file gdm_lte.c Pahole shows that the addresses are aligned. Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_lte.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index c657639f884b..73eede163820 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -626,7 +626,7 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf, void *addr = buf + sizeof(struct iphdr) + sizeof(struct udphdr) + offsetof(struct dhcp_packet, chaddr); - memcpy(nic->dest_mac_addr, addr, ETH_ALEN); + ether_addr_copy(nic->dest_mac_addr, addr); } } @@ -639,7 +639,7 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf, } /* Format the data so that it can be put to skb */ - memcpy(mac_header_data, nic->dest_mac_addr, ETH_ALEN); + ether_addr_copy(mac_header_data, nic->dest_mac_addr); memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); vlan_eth.h_vlan_TCI = htons(nic->vlan_id); @@ -842,9 +842,9 @@ static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, { /* Form the dev_addr */ if (!mac_address) - memcpy(dev_addr, gdm_lte_macaddr, ETH_ALEN); + ether_addr_copy(dev_addr, gdm_lte_macaddr); else - memcpy(dev_addr, mac_address, ETH_ALEN); + ether_addr_copy(dev_addr, mac_address); /* The last byte of the mac address * should be less than or equal to 0xFC @@ -858,7 +858,7 @@ static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, memcpy(nic_src, dev_addr, 3); /* Copy the nic_dest from dev_addr*/ - memcpy(nic_dest, dev_addr, ETH_ALEN); + ether_addr_copy(nic_dest, dev_addr); } static void validate_mac_address(u8 *mac_address) -- GitLab From 48131a6bda18d65a6c63de1e6c54dcf40eb6057c Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Tue, 7 Oct 2014 11:41:08 +0300 Subject: [PATCH 0388/9457] staging: gdm724x: Fix incorrect type in assignment This patch fixes following sparse warnings: drivers/staging/gdm724x/gdm_mux.c:389:32: warning: incorrect type in assignment (different base types) drivers/staging/gdm724x/gdm_mux.c:389:32: expected unsigned int [unsigned] start_flag drivers/staging/gdm724x/gdm_mux.c:389:32: got restricted __le32 [usertype] drivers/staging/gdm724x/gdm_mux.c:391:34: warning: incorrect type in assignment (different base types) drivers/staging/gdm724x/gdm_mux.c:391:34: expected unsigned int [unsigned] payload_size drivers/staging/gdm724x/gdm_mux.c:391:34: got restricted __le32 [usertype] drivers/staging/gdm724x/gdm_mux.c:392:33: warning: incorrect type in assignment (different base types) drivers/staging/gdm724x/gdm_mux.c:392:33: expected unsigned short [unsigned] packet_type drivers/staging/gdm724x/gdm_mux.c:392:33: got restricted __le16 [usertype] Sparse found above warnings, so this patch changes variable types of structs. Because expected and got variable types are different. Signed-off-by: Ebru Akagunduz Reviewed-by: Octavian Purdila Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_mux.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_mux.h b/drivers/staging/gdm724x/gdm_mux.h index 0163b243d3e0..3d50383c6ced 100644 --- a/drivers/staging/gdm724x/gdm_mux.h +++ b/drivers/staging/gdm724x/gdm_mux.h @@ -35,10 +35,10 @@ #define RETRY_TIMER 30 /* msec */ struct mux_pkt_header { - unsigned int start_flag; - unsigned int seq_num; - unsigned int payload_size; - unsigned short packet_type; + __le32 start_flag; + __le32 seq_num; + __le32 payload_size; + __le16 packet_type; unsigned char data[0]; }; -- GitLab From 35b042a550e727cdc32a5d0a146ea5947b6a1c53 Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Mon, 6 Oct 2014 00:25:51 +0530 Subject: [PATCH 0389/9457] staging: gdm72xx: Removed unnecesarry out of memory usage WARNING: Possible unnecessary out of memory usage checkpatch.pl warning in gdm_wimax.c Signed-off-by: Sarah Khan Acked-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index f5a3378c3951..5b7747f6b847 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -605,10 +605,8 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len) int ret; skb = dev_alloc_skb(len + 2); - if (!skb) { - netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__); + if (!skb) return; - } skb_reserve(skb, 2); dev->stats.rx_packets++; -- GitLab From d8ad8b0cad4cb9596b751a2dc10ff7559cee721c Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Wed, 8 Oct 2014 03:59:55 +0200 Subject: [PATCH 0390/9457] staging: unisys: Remove typedef and rename enum to lowercase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove typedef and rename enum to lowercase (control_vm_id) Signed-off-by: Veronika Kabátová Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 6 +++--- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset.h | 8 ++++---- drivers/staging/unisys/visorchipset/visorchipset_main.c | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index cfd99997cfee..f7ca6d167d60 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -88,7 +88,7 @@ static const uuid_le UltraControlvmChannelProtocolGuid = * - issued on the EventQueue queue (q #2) in the ControlVm channel * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ -typedef enum { +enum control_vm_id { CONTROLVM_INVALID = 0, /* SWITCH commands required Parameter: SwitchNumber */ /* BUS commands required Parameter: BusNumber */ @@ -117,7 +117,7 @@ typedef enum { CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */ CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */ -} CONTROLVM_ID; +}; struct irq_info { /**< specifies interrupt info. It is used to send interrupts @@ -239,7 +239,7 @@ typedef enum { * looking at the flags.response field. */ typedef struct _CONTROLVM_MESSAGE_HEADER { - u32 Id; /* See CONTROLVM_ID. */ + u32 Id; /* See control_vm_id. */ /* For requests, indicates the message type. */ /* For responses, indicates the type of message we are responding to. */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 677ed7e609af..f8ffa0263e29 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -155,7 +155,7 @@ u64 uislib_storage_channel(int client_id); #endif int uislib_get_owned_pdest(struct uisscsi_dest *pdest); -int uislib_send_event(CONTROLVM_ID id, CONTROLVM_MESSAGE_PACKET *event); +int uislib_send_event(enum control_vm_id id, CONTROLVM_MESSAGE_PACKET *event); /* structure used by vhba & vnic to keep track of queue & thread info */ struct chaninfo { diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 23834765a468..cb93da931f75 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -82,7 +82,7 @@ typedef struct { uuid_le devInstGuid; VISORCHIPSET_STATE state; VISORCHIPSET_CHANNEL_INFO chanInfo; - u32 Reserved1; /* CONTROLVM_ID */ + u32 Reserved1; /* control_vm_id */ u64 Reserved2; u32 switchNo; /* when devState.attached==1 */ u32 internalPortNo; /* when devState.attached==1 */ @@ -169,7 +169,7 @@ typedef struct { u8 *authService3; u8 *securityContext; u64 Reserved; - u32 Reserved2; /* CONTROLVM_ID */ + u32 Reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; CONTROLVM_MESSAGE_HEADER pendingMsgHdr; @@ -192,7 +192,7 @@ typedef struct { u8 *ipGateway; u8 *ipDNS; u64 Reserved1; - u32 Reserved2; /* CONTROLVM_ID */ + u32 Reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; CONTROLVM_MESSAGE_HEADER pendingMsgHdr; @@ -209,7 +209,7 @@ typedef struct { u32 busNo; /* valid only when state.attached == 1 */ u32 devNo; /* valid only when state.attached == 1 */ u64 Reserved1; - u32 Reserved2; /* CONTROLVM_ID */ + u32 Reserved2; /* control_vm_id */ CONTROLVM_MESSAGE_HEADER pendingMsgHdr; MYPROCOBJECT *procObject; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 320124a240ac..ee03c59dc889 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -817,7 +817,7 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) EXPORT_SYMBOL_GPL(visorchipset_save_message); static void -bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) +bus_responder(enum control_vm_id cmdId, ulong busNo, int response) { VISORCHIPSET_BUS_INFO *p = NULL; BOOL need_clear = FALSE; @@ -856,7 +856,7 @@ bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response) } static void -device_changestate_responder(CONTROLVM_ID cmdId, +device_changestate_responder(enum control_vm_id cmdId, ulong busNo, ulong devNo, int response, struct ultra_segment_state responseState) { @@ -893,7 +893,7 @@ device_changestate_responder(CONTROLVM_ID cmdId, } static void -device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response) +device_responder(enum control_vm_id cmdId, ulong busNo, ulong devNo, int response) { VISORCHIPSET_DEVICE_INFO *p = NULL; BOOL need_clear = FALSE; -- GitLab From 3830d03dee563f95833801b6c72a596f5fb3aa4e Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Wed, 8 Oct 2014 03:47:35 +0200 Subject: [PATCH 0391/9457] staging: unisys: Union ULTRA_COMPONENT_VERSION not used, removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unused union ULTRA_COMPONENT_VERSION Signed-off-by: Veronika Kabátová Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlframework.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index bbcf5ac4f0b7..e718557f1c20 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -63,15 +63,5 @@ static const struct ultra_segment_state SegmentStatePaused = { static const struct ultra_segment_state SegmentStateStandby = { 1, 1, 0, 0, 1, 1, 1, 0 }; -typedef union { - u64 Full; - struct { - u8 Major; /* will be 1 for the first release and - * increment thereafter */ - u8 Minor; - u16 Maintenance; - u32 Revision; /* Subversion revision */ - } Part; -} ULTRA_COMPONENT_VERSION; #endif /* _CONTROL_FRAMEWORK_H_ not defined */ -- GitLab From a7a4f87e3c7462ec70533e78ad2bce19d158e9d7 Mon Sep 17 00:00:00 2001 From: Kumari Radha Date: Wed, 8 Oct 2014 14:48:44 +0530 Subject: [PATCH 0392/9457] staging: vme: devices: Added a paragraph to describe Kconfig symbol This patch adds module name information about config symbol fixing the following checkpatch.pl warning in Kconfig: WARNING: please write a paragraph that describes the config symbol fully Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig index 8e8bbb1dcd9b..1d2ff0cc41f1 100644 --- a/drivers/staging/vme/devices/Kconfig +++ b/drivers/staging/vme/devices/Kconfig @@ -8,6 +8,9 @@ config VME_USER VME windows in a manner at least semi-compatible with the interface provided with the original driver at . + To compile this driver as a module, choose M here. The module will + be called vme_user. If unsure, say N. + config VME_PIO2 tristate "GE PIO2 VME" depends on STAGING && GPIOLIB -- GitLab From f999ac00c76f998b5ef861a599c72fb4572dc9c0 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Tue, 7 Oct 2014 02:50:28 +0300 Subject: [PATCH 0393/9457] staging: slicoss: Fix warning of prefer ether_addr_copy(). This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file slicoss.c Pahole shows that the addresses are aligned. Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 56ca3b6c1444..f48eeb168e0b 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1788,7 +1788,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address) if (mcaddr == NULL) return 1; - memcpy(mcaddr->address, address, ETH_ALEN); + ether_addr_copy(mcaddr->address, address); mcaddr->next = adapter->mcastaddrs; adapter->mcastaddrs = mcaddr; -- GitLab From 646da830fd61a74947581b3675e1919361f16cd2 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 20:41:26 +0530 Subject: [PATCH 0394/9457] staging: rtl8712: Remove unnecessary cast for argument of kfree This patch removes all occurrences of unnecessary cast on the argument to kfree, all over in rtl8712. There is no need of the cast on the argument to kfree. Greped to find occurrences. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_cmd.c | 54 +++++++++---------- drivers/staging/rtl8712/rtl871x_io.c | 4 +- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 4 +- drivers/staging/rtl8712/rtl871x_mlme.c | 4 +- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 5aae4cce8477..92101b98c49a 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -205,12 +205,12 @@ void r8712_free_cmd_obj(struct cmd_obj *pcmd) { if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) - kfree((unsigned char *)pcmd->parmbuf); + kfree(pcmd->parmbuf); if (pcmd->rsp != NULL) { if (pcmd->rspsz != 0) - kfree((unsigned char *)pcmd->rsp); + kfree(pcmd->rsp); } - kfree((unsigned char *)pcmd); + kfree(pcmd); } /* @@ -232,7 +232,7 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, return _FAIL; psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC); if (psurveyPara == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, @@ -264,7 +264,7 @@ u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset) return _FAIL; pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); if (pbsetdataratepara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, @@ -286,7 +286,7 @@ u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan) return _FAIL; psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC); if (psetchplanpara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara, @@ -307,7 +307,7 @@ u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset) return _FAIL; pssetbasicratepara = kmalloc(sizeof(*pssetbasicratepara), GFP_ATOMIC); if (pssetbasicratepara == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, @@ -329,7 +329,7 @@ u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetPT)); @@ -349,7 +349,7 @@ u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetDIG)); @@ -369,7 +369,7 @@ u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type) return _FAIL; pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC); if (pwriteptmparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetRA)); @@ -389,7 +389,7 @@ u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val) return _FAIL; pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC); if (pwriterfparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); @@ -410,7 +410,7 @@ u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval) return _FAIL; prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC); if (prdrfparm == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } INIT_LIST_HEAD(&ph2c->list); @@ -626,7 +626,7 @@ u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */ return _FAIL; pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC); if (pdisconnect == NULL) { - kfree((u8 *)pdisconnect_cmd); + kfree(pdisconnect_cmd); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect, @@ -648,7 +648,7 @@ u8 r8712_setopmode_cmd(struct _adapter *padapter, return _FAIL; psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC); if (psetop == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); @@ -672,13 +672,13 @@ u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key) return _FAIL; psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC); if (psetstakey_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC); if (psetstakey_rsp == NULL) { - kfree((u8 *) ph2c); - kfree((u8 *) psetstakey_para); + kfree(ph2c); + kfree(psetstakey_para); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); @@ -712,7 +712,7 @@ u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode) return _FAIL; psetrfintfsparm = kmalloc(sizeof(*psetrfintfsparm), GFP_ATOMIC); if (psetrfintfsparm == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetrfintfsparm, @@ -734,7 +734,7 @@ u8 r8712_setrttbl_cmd(struct _adapter *padapter, return _FAIL; psetrttblparm = kmalloc(sizeof(*psetrttblparm), GFP_ATOMIC); if (psetrttblparm == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, @@ -755,7 +755,7 @@ u8 r8712_gettssi_cmd(struct _adapter *padapter, u8 offset, u8 *pval) return _FAIL; prdtssiparm = kmalloc(sizeof(*prdtssiparm), GFP_ATOMIC); if (prdtssiparm == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } INIT_LIST_HEAD(&ph2c->list); @@ -781,7 +781,7 @@ u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr) return _FAIL; psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC); if (psetMacAddr_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para, @@ -803,13 +803,13 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr) return _FAIL; psetassocsta_para = kmalloc(sizeof(*psetassocsta_para), GFP_ATOMIC); if (psetassocsta_para == NULL) { - kfree((u8 *) ph2c); + kfree(ph2c); return _FAIL; } psetassocsta_rsp = kmalloc(sizeof(*psetassocsta_rsp), GFP_ATOMIC); if (psetassocsta_rsp == NULL) { - kfree((u8 *)ph2c); - kfree((u8 *)psetassocsta_para); + kfree(ph2c); + kfree(psetassocsta_para); return _FAIL; } init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); @@ -831,7 +831,7 @@ u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid) return _FAIL; paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC); if (paddbareq_parm == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } paddbareq_parm->tid = tid; @@ -852,7 +852,7 @@ u8 r8712_wdg_wk_cmd(struct _adapter *padapter) return _FAIL; pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC); if (pdrvintcmd_param == NULL) { - kfree((unsigned char *)ph2c); + kfree(ph2c); return _FAIL; } pdrvintcmd_param->i_cid = WDG_WK_CID; @@ -1026,7 +1026,7 @@ u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, return _FAIL; param = kzalloc(sizeof(*param), GFP_ATOMIC); if (param == NULL) { - kfree((unsigned char *) ph2c); + kfree(ph2c); return _FAIL; } diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c index 3a0236606396..e4e5b13cb927 100644 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ b/drivers/staging/rtl8712/rtl871x_io.c @@ -142,7 +142,7 @@ uint r8712_alloc_io_queue(struct _adapter *adapter) alloc_io_queue_fail: if (pio_queue) { kfree(pio_queue->pallocated_free_ioreqs_buf); - kfree((u8 *)pio_queue); + kfree(pio_queue); } adapter->pio_queue = NULL; return _FAIL; @@ -156,6 +156,6 @@ void r8712_free_io_queue(struct _adapter *adapter) kfree(pio_queue->pallocated_free_ioreqs_buf); adapter->pio_queue = NULL; unregister_intf_hdl(&pio_queue->intf); - kfree((u8 *)pio_queue); + kfree(pio_queue); } } diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 8e42ce06e5d7..b4ffc0e31110 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -505,7 +505,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, } } exit: - kfree((u8 *)pwep); + kfree(pwep); return ret; } @@ -2216,7 +2216,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) } if (ret == 0 && copy_to_user(p->pointer, param, p->length)) ret = -EFAULT; - kfree((u8 *)param); + kfree(param); return ret; } diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 00f2e0fc4ac5..4b602fe1dba1 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -923,7 +923,7 @@ void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) ignore_joinbss_callback: spin_unlock_irqrestore(&pmlmepriv->lock, irqL); if (sizeof(struct list_head) == 4 * sizeof(u32)) - kfree((u8 *)pnetwork); + kfree(pnetwork); } void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) @@ -1218,7 +1218,7 @@ sint r8712_set_auth(struct _adapter *adapter, psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); if (psetauthparm == NULL) { - kfree((unsigned char *)pcmd); + kfree(pcmd); return _FAIL; } psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; -- GitLab From ad96f37f06596c6a7bd4dae3cf364bbb4ab7d7a4 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 23:33:40 +0530 Subject: [PATCH 0395/9457] staging: wlan-ng: replace kmalloc and memset with kzalloc Replace kmalloc and memset with a single call of kzalloc in file of wlan-ng. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 6c38f797d1ab..e907380f9163 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -986,8 +986,8 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, u32 currlen; u32 currdaddr; - rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL); - rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL); + rstmsg = kzalloc(sizeof(*rstmsg), GFP_KERNEL); + rwrmsg = kzalloc(sizeof(*rwrmsg), GFP_KERNEL); if (!rstmsg || !rwrmsg) { kfree(rstmsg); kfree(rwrmsg); @@ -997,7 +997,6 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, } /* Initialize the messages */ - memset(rstmsg, 0, sizeof(*rstmsg)); strcpy(rstmsg->devname, wlandev->name); rstmsg->msgcode = DIDmsg_p2req_ramdl_state; rstmsg->msglen = sizeof(*rstmsg); @@ -1011,7 +1010,6 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, rstmsg->exeaddr.len = sizeof(u32); rstmsg->resultcode.len = sizeof(u32); - memset(rwrmsg, 0, sizeof(*rwrmsg)); strcpy(rwrmsg->devname, wlandev->name); rwrmsg->msgcode = DIDmsg_p2req_ramdl_write; rwrmsg->msglen = sizeof(*rwrmsg); -- GitLab From 146ea83566881aecb68dbf15e30a1c945116d1c4 Mon Sep 17 00:00:00 2001 From: Esra Altintas Date: Wed, 8 Oct 2014 14:32:10 +0300 Subject: [PATCH 0396/9457] staging: speakup: Use time_after_eq to compare jiffies in speakup_keypc.c The following patch fixes the checkpatch.pl warning: WARNING: Comparing jiffies is almost always wrong; prefer time_after, time_before and friends Signed-off-by: Esra Altintas Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/speakup_keypc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index 4ed38898a17a..cef20fdda646 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -229,7 +229,7 @@ spin_lock_irqsave(&speakup_info.spinlock, flags); ch = PROCSPEECH; outb_p(ch, synth_port); SWAIT; - if ((jiffies >= jiff_max) && (ch == SPACE)) { + if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) { timeout = 1000; while (synth_writable()) if (--timeout <= 0) -- GitLab From 583bea6c40fa281a6735a717d1855f31f2c6b187 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 22:55:45 +0530 Subject: [PATCH 0397/9457] staging: comedi: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Coccinelle script used : // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 3e5bccbc9c39..859b722188cc 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -317,8 +317,7 @@ unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s) case COMEDI_SUBD_DO: case COMEDI_SUBD_DIO: bits_per_sample = 8 * bytes_per_sample(s); - num_samples = (cmd->chanlist_len + bits_per_sample - 1) / - bits_per_sample; + num_samples = DIV_ROUND_UP(cmd->chanlist_len, bits_per_sample); break; default: num_samples = cmd->chanlist_len; -- GitLab From 97996da1787d55cda95fd4209a4affbef9346c53 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 22:56:01 +0530 Subject: [PATCH 0398/9457] staging: comedi: drivers: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Coccinelle script used : // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 0e7621e890c3..bc0745058057 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1976,7 +1976,7 @@ static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags) divider = (*nanosec) / base; break; case CMDF_ROUND_UP: - divider = (*nanosec + base - 1) / base; + divider = DIV_ROUND_UP(*nanosec, base); break; } -- GitLab From ffceca8c1739938b58cdc5ce375d33a13150f7af Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 22:56:15 +0530 Subject: [PATCH 0399/9457] staging: iio: adc: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Coccinelle script used : // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/spear_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index c5492ba50751..67a364c2e794 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -98,7 +98,7 @@ static void spear_adc_set_clk(struct spear_adc_state *st, u32 val) u32 clk_high, clk_low, count; u32 apb_clk = clk_get_rate(st->clk); - count = (apb_clk + val - 1) / val; + count = DIV_ROUND_UP(apb_clk, val); clk_low = count / 2; clk_high = count - clk_low; st->current_clk = apb_clk / count; -- GitLab From dea7503ac4c53edfd0d25d6a1c8b360b3db700d7 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 22:56:57 +0530 Subject: [PATCH 0400/9457] staging: octeon-usb: use DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Coccinelle script used : // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon-usb/octeon-hcd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 6ddde6af7e3a..7ac64efc6520 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -743,7 +743,7 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb, * such that USB is as close as possible to 125Mhz */ { - int divisor = (octeon_get_clock_rate()+125000000-1)/125000000; + int divisor = DIV_ROUND_UP(octeon_get_clock_rate(), 125000000); /* Lower than 4 doesn't seem to work properly */ if (divisor < 4) divisor = 4; @@ -1606,8 +1606,8 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb, * Calculate the number of packets to transfer. If the length is zero * we still need to transfer one packet */ - packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / - pipe->max_packet; + packets_to_transfer = DIV_ROUND_UP(bytes_to_transfer, + pipe->max_packet); if (packets_to_transfer == 0) packets_to_transfer = 1; else if ((packets_to_transfer > 1) && @@ -1852,8 +1852,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb, * zero we still need to transfer one packet */ packets_to_transfer = - (bytes_to_transfer + pipe->max_packet - 1) / - pipe->max_packet; + DIV_ROUND_UP(bytes_to_transfer, pipe->max_packet); if (packets_to_transfer == 0) packets_to_transfer = 1; else if ((packets_to_transfer > 1) && -- GitLab From d9798aa6c33b4da68d9f798e71dca138c9501f74 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 8 Oct 2014 23:13:47 +0530 Subject: [PATCH 0401/9457] staging: comedi: drivers: Use DIV_ROUND_CLOSEST The kernel.h macro DIV_ROUND_CLOSEST performs the computation (x + d/2)/d but is perhaps more readable. The Coccinelle script used: // @haskernel@ @@ @depends on haskernel@ expression x,__divisor; @@ - (((x) + ((__divisor) / 2)) / (__divisor)) + DIV_ROUND_CLOSEST(x,__divisor) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index bc0745058057..11a12d787e4c 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1970,7 +1970,7 @@ static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags) switch (flags & CMDF_ROUND_MASK) { case CMDF_ROUND_NEAREST: default: - divider = (*nanosec + base / 2) / base; + divider = DIV_ROUND_CLOSEST(*nanosec, base); break; case CMDF_ROUND_DOWN: divider = (*nanosec) / base; -- GitLab From 84995ca471ab409413b4938b8133a56ec36ff2f5 Mon Sep 17 00:00:00 2001 From: Esra Altintas Date: Wed, 8 Oct 2014 21:21:50 +0300 Subject: [PATCH 0402/9457] staging: bcm: Removed unnecessary 'else' after 'return' statement in Qos.c The following patch fixes the checkpatch.pl warning: WARNING: else is not generally useful after a break or return Signed-off-by: Esra Altintas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Qos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index b3ac614cd35f..0f16c6342799 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -978,8 +978,7 @@ static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, if (pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2]) return TRUE; - else - return false; + return false; } -- GitLab From 038862c4a3853c680d09b3884ae003803d4cbdfe Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Wed, 8 Oct 2014 23:32:11 +0300 Subject: [PATCH 0403/9457] staging: vt6655: Use ether_addr_copy function This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file iwctl.c Pahole shows that the addresses are aligned Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iwctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 94b4859e2f25..8f3e190a55b9 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -1728,7 +1728,7 @@ int iwctl_siwencodeext(struct net_device *dev, goto error; } //recover addr - memcpy(addr, ext->addr.sa_data, ETH_ALEN); + ether_addr_copy(addr, ext->addr.sa_data); //recover key_idx key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; //recover set_tx -- GitLab From aa59d88f9916bf046298c19e402d9c48d0613d3c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:14 -0700 Subject: [PATCH 0404/9457] staging: comedi: adl_pci9111: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index d18d8f21af23..076866e121a0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -561,7 +561,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) dev_dbg(dev->class_dev, "fifo overflow\n"); outb(0, dev->iobase + PCI9111_INT_CLR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -578,7 +578,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device) spin_unlock_irqrestore(&dev->spinlock, irq_flags); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From f5b5164d935ed0a1603a040d631afc6b7004d449 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:15 -0700 Subject: [PATCH 0405/9457] staging: comedi: adl_pci9118: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index e18fd9569a2b..7b1720f8fb30 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -766,7 +766,7 @@ static irqreturn_t pci9118_interrupt(int irq, void *d) interrupt_pci9118_ai_onesample(dev, s); interrupt_exit: - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From c55e892b0635f0e55f2bfaee02b747e4abe7ed7a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:16 -0700 Subject: [PATCH 0406/9457] staging: comedi: adv_pci1710: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5539bd294862..5f387fabe1f5 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -749,14 +749,14 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, if (status & Status_FE) { dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (status & Status_FF) { dev_dbg(dev->class_dev, "A/D FIFO Full status (Fatal Error!) (%4x)\n", status); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } @@ -790,7 +790,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } /* @@ -837,14 +837,14 @@ static void pci1710_handle_fifo(struct comedi_device *dev, if (!(m & Status_FH)) { dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (m & Status_FF) { dev_dbg(dev->class_dev, "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } @@ -865,12 +865,12 @@ static void pci1710_handle_fifo(struct comedi_device *dev, devpriv->ai_act_scan >= cmd->stop_arg) { /* all data sampled */ s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */ - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } /* -- GitLab From 781f1f189e9726da6134cc8483b39fb7d56b073d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:17 -0700 Subject: [PATCH 0407/9457] staging: comedi: amplc_pci224: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 3bbbb57f19d6..7ca6a6179cf2 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -537,7 +537,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, devpriv->ao_stop_count == 0) { /* FIFO empty at end of counted acquisition. */ s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } break; @@ -618,7 +618,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int pci224_ao_inttrig_start(struct comedi_device *dev, -- GitLab From f923f780704b810d31b62b2ad4e19198e6be0b63 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:18 -0700 Subject: [PATCH 0408/9457] staging: comedi: cb_pcidas: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 1ec363b7505c..e7ab6bcfa90b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1319,7 +1319,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) spin_unlock_irqrestore(&dev->spinlock, flags); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t cb_pcidas_interrupt(int irq, void *d) @@ -1419,7 +1419,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 62fc6407ea18267858963ee01c1238240ddce621 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:19 -0700 Subject: [PATCH 0409/9457] staging: comedi: cb_pcidas64: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 3b6bffc66918..eafbe9f56060 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2836,7 +2836,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static inline unsigned int prev_ao_dma_index(struct comedi_device *dev) @@ -3020,7 +3020,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, if (ao_stopped_by_error(dev, cmd)) async->events |= COMEDI_CB_ERROR; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t handle_interrupt(int irq, void *d) -- GitLab From 2588ab409c6eaf82061b7ac1b4e86801862fbf13 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:20 -0700 Subject: [PATCH 0410/9457] staging: comedi: das16: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 2d8e86cec47a..222a32ff0d32 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -586,7 +586,7 @@ static void das16_interrupt(struct comedi_device *dev) cfc_write_array_to_buffer(s, devpriv->dma_buffer[buffer_index], num_bytes); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void das16_timer_interrupt(unsigned long arg) -- GitLab From 05664aa4d378f05629c4bbcb7dd59d775578c482 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:21 -0700 Subject: [PATCH 0411/9457] staging: comedi: das16m1: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 24b63c452f51..f98bcbe0d72a 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -460,7 +460,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status) dev_err(dev->class_dev, "fifo overflow\n"); } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s) -- GitLab From 837a12643bd8367e0999b73a9a1e746fa52863f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:22 -0700 Subject: [PATCH 0412/9457] staging: comedi: das800: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das800.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index d75e5528258c..e284d202b7e7 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -521,7 +521,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) if (fifo_overflow) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -537,7 +537,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) das800_disable(dev); async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From fe43b8f5ded501013c61924efcbbe836d73a4ad6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:23 -0700 Subject: [PATCH 0413/9457] staging: comedi: das1800: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index a53d87ce9b14..7b0b65e883f6 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -656,7 +656,7 @@ static void das1800_ai_handler(struct comedi_device *dev) outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); dev_err(dev->class_dev, "FIFO overflow\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } /* stop taking data if appropriate */ @@ -674,7 +674,7 @@ static void das1800_ai_handler(struct comedi_device *dev) async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int das1800_ai_poll(struct comedi_device *dev, -- GitLab From 4f6f009b204fca46136de98c10332de5f3e91ce8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:24 -0700 Subject: [PATCH 0414/9457] staging: comedi: dt282x: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index cc974a5e5cf6..f23d883f2544 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -579,8 +579,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) handled = 1; } #endif - cfc_handle_events(dev, s); - cfc_handle_events(dev, s_ao); + comedi_handle_events(dev, s); + comedi_handle_events(dev, s_ao); return IRQ_RETVAL(handled); } -- GitLab From 5d758b98fab68055854134b8012cf0cf1774b7e1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:25 -0700 Subject: [PATCH 0415/9457] staging: comedi: dt3000: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 825561046b6f..6544f4482740 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -363,7 +363,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) if (debug_n_ints >= 10) s->async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From b48e57e5b40469c81df768b2c2f0d54224feff79 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:26 -0700 Subject: [PATCH 0416/9457] staging: comedi: gsc_hpdi: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index b8975a4606ea..e99edaa3b9fa 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -272,7 +272,7 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d) if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 9e1a0824cb02ce376c5315028e54a2eef61b1d31 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:27 -0700 Subject: [PATCH 0417/9457] staging: comedi: ni_660x: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5b6794c8232e..1e4dd82b12ea 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -780,7 +780,7 @@ static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, struct ni_gpct *counter = s->private; ni_tio_handle_interrupt(counter, s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t ni_660x_interrupt(int irq, void *d) -- GitLab From 4a706e2e2de33db474c67a7011c29326d2891693 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:28 -0700 Subject: [PATCH 0418/9457] staging: comedi: ni_at_a2150: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 72ec857d073e..f1fe9efda6df 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -188,14 +188,14 @@ static irqreturn_t a2150_interrupt(int irq, void *d) if (status & OVFL_BIT) { dev_err(dev->class_dev, "fifo overflow\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } if ((status & DMA_TC_BIT) == 0) { dev_err(dev->class_dev, "caught non-dma interrupt? Aborting.\n"); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -255,7 +255,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) async->events |= COMEDI_CB_BLOCK; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); /* clear interrupt */ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG); -- GitLab From 1c27ce6055d47305670e0d67ea02446795f82fe0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:29 -0700 Subject: [PATCH 0419/9457] staging: comedi: ni_labpc_common: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 35bc2c25ddfb..72dc78632cd5 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -876,7 +876,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* clear error interrupt */ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); dev_err(dev->class_dev, "overrun\n"); return IRQ_HANDLED; } @@ -896,7 +896,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* clear error interrupt */ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); dev_err(dev->class_dev, "overflow\n"); return IRQ_HANDLED; } @@ -914,7 +914,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA; } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From b9a69a19c999e43036137b629e80d25e9053386c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:30 -0700 Subject: [PATCH 0420/9457] staging: comedi: ni_mio_common: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 320b080149b6..c855787e28f3 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1462,7 +1462,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev, ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index], s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); #endif } @@ -1518,7 +1518,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (comedi_is_subdevice_running(s)) { s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } return; } @@ -1533,7 +1533,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (status & (AI_Overrun_St | AI_Overflow_St)) s->async->events |= COMEDI_CB_OVERFLOW; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return; } if (status & AI_SC_TC_St) { @@ -1559,7 +1559,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if ((status & AI_STOP_St)) ni_handle_eos(dev, s); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) @@ -1635,7 +1635,7 @@ static void handle_b_interrupt(struct comedi_device *dev, } #endif - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, @@ -3693,7 +3693,7 @@ static void handle_cdio_interrupt(struct comedi_device *dev) M_Offset_CDIO_Command); /* s->async->events |= COMEDI_CB_EOA; */ } - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } static int ni_serial_hw_readwrite8(struct comedi_device *dev, -- GitLab From bd5ebdf0722e5624292c05456057e00547e7e2c4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:31 -0700 Subject: [PATCH 0421/9457] staging: comedi: ni_pcidio: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 5252cba82e5e..0bb776366264 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -485,7 +485,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } out: - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); #if 0 if (!tag) writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control); -- GitLab From fa0e93d573734e19a18f782af9ca21182c2058c8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:32 -0700 Subject: [PATCH 0422/9457] staging: comedi: pcl812: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index fd5ea6e01619..700e4ef49019 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -939,7 +939,7 @@ static irqreturn_t pcl812_interrupt(int irq, void *d) pcl812_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From a2ca8c86515aec54f772533b3fc7e21a635cdab3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:33 -0700 Subject: [PATCH 0423/9457] staging: comedi: pcl816: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index aa6487132017..e4383ac2b505 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -355,7 +355,7 @@ static irqreturn_t pcl816_interrupt(int irq, void *d) pcl816_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } @@ -566,7 +566,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_poll_ptr = top1; /* new buffer position */ spin_unlock_irqrestore(&dev->spinlock, flags); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return comedi_buf_n_bytes_ready(s); } -- GitLab From 11e7c09aee65e496dbe27e4d57bede97f7a5af4c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:34 -0700 Subject: [PATCH 0424/9457] staging: comedi: pcl818: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index ac19e83ce62a..618591d3b3b3 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -669,7 +669,7 @@ static irqreturn_t pcl818_interrupt(int irq, void *d) pcl818_ai_clear_eoc(dev); - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 44aaad2d5f775e9dcb269f5202d2bc4b9d10d3fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:35 -0700 Subject: [PATCH 0425/9457] staging: comedi: quatech_daqp_cs: use comedi_handle_events() cfc_handle_events() is just a wrapper around comedi_handle_events(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 6407df0404f0..21e99fdf28ad 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -247,7 +247,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) s->async->events |= COMEDI_CB_BLOCK; - cfc_handle_events(dev, s); + comedi_handle_events(dev, s); } return IRQ_HANDLED; } -- GitLab From 48b89ec6fa370c45da9761334b77962e5bc4b505 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:11:36 -0700 Subject: [PATCH 0426/9457] staging: comedi: comedi_fc.h: remove cfc_handle_events() This inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index ce2835972507..d381bc1b2a2b 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -60,12 +60,6 @@ cfc_read_array_from_buffer(struct comedi_subdevice *s, void *data, return comedi_read_array_from_buffer(s, data, num_bytes); } -static inline unsigned int cfc_handle_events(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - return comedi_handle_events(dev, s); -} - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate -- GitLab From a2c344e94e0918bf1bf96f5335088fbd9eab382f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:18 -0700 Subject: [PATCH 0427/9457] staging: comedi: hwdrv_apci3200: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 5e321f91172f..470b3f0d457f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -2560,8 +2560,7 @@ static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) comedi_buf_write_free(s, (7 + 12) * sizeof(unsigned int)); - /* Send events */ - comedi_event(dev, s); + comedi_handle_events(dev, s); /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ -- GitLab From c8fd3539713008f134b8934f14f943606ae987e3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:19 -0700 Subject: [PATCH 0428/9457] staging: comedi: addi_apci_1032: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 840cb289507a..12601a9337f3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -260,7 +260,7 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; comedi_buf_put(s, s->state); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); /* enable the interrupt */ outl(ctrl, dev->iobase + APCI1032_CTRL_REG); -- GitLab From 5b6f0e9482921c4c8eeae2c01f246147b2cb4faa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:20 -0700 Subject: [PATCH 0429/9457] staging: comedi: addi_apci_1564: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 688b015a834e..cf544ab1fc65 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -97,7 +97,7 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) & 0xffff; comedi_buf_put(s, s->state); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); /* enable the interrupt */ outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); -- GitLab From f47906a3421af0864dc93c812347c553efa208ee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:21 -0700 Subject: [PATCH 0430/9457] staging: comedi: addi_apci_3xxx: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index a296bd5b2c0c..fe9ac2d72694 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -374,7 +374,7 @@ static irqreturn_t apci3xxx_irq_handler(int irq, void *d) comedi_buf_put(s, val); s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From a2c4e3671c0ae8559f82fb11083a688f61bce23e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:22 -0700 Subject: [PATCH 0431/9457] staging: comedi: amplc_pc236_common: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index 963c5d868b81..04c3d73ec5ba 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -137,7 +137,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d) if (dev->attached && handled) { comedi_buf_put(s, 0); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); } return IRQ_RETVAL(handled); } -- GitLab From bc8816511dd91352c15cf20698e2af022aa6f862 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:23 -0700 Subject: [PATCH 0432/9457] staging: comedi: comedi_parport: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_parport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index bf002988192d..0bc3844073ee 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -228,7 +228,7 @@ static irqreturn_t parport_interrupt(int irq, void *d) comedi_buf_put(s, 0); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 285d1ff1629b1a83ee7c09b23b74fd2a92854d80 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:24 -0700 Subject: [PATCH 0433/9457] staging: comedi: dmm32at: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dmm32at.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 7215e09305cf..7e69d317b7ef 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -514,8 +514,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d) } } - /* flush the buffer */ - comedi_event(dev, s); + comedi_handle_events(dev, s); } /* reset the interrupt */ -- GitLab From 001cce48b407d63d09b5dfb27a04017cbfc9e4e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:25 -0700 Subject: [PATCH 0434/9457] staging: comedi: dt2814: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2814.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 9216c35c414e..9805be13005a 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -230,7 +230,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) s->async->events |= COMEDI_CB_EOA; } - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 0c56f057dc1e4f9ee0303f412f0814d720d76f34 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:26 -0700 Subject: [PATCH 0435/9457] staging: comedi: ni_6527: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 45fb601e4080..b77354bc75e6 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -210,7 +210,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d) if (status & NI6527_STATUS_EDGE) { comedi_buf_put(s, 0); s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); } writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG); -- GitLab From 9207b6b0aa320eb0ef02084e6199e709c20d522b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:27 -0700 Subject: [PATCH 0436/9457] staging: comedi: ni_65xx: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 3b642861eb36..3c27f532aa6e 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -510,7 +510,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) comedi_buf_put(s, 0); s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From c827d2b7500eb5d7efa768177a1d89336df09d61 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:28 -0700 Subject: [PATCH 0437/9457] staging: comedi: ni_atmio16d: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio16d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index fc3c19de7005..24f8bca9ba05 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -220,7 +220,7 @@ static irqreturn_t atmio16d_interrupt(int irq, void *d) comedi_buf_put(s, inw(dev->iobase + AD_FIFO_REG)); - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From ae4ac0dbf1385a2e33a6621235b5bcddae5cba4e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:29 -0700 Subject: [PATCH 0438/9457] staging: comedi: pcl726: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl726.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index dc179bd02dfd..be43cdaf9479 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -237,7 +237,7 @@ static irqreturn_t pcl726_interrupt(int irq, void *d) comedi_buf_put(s, 0); s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - comedi_event(dev, s); + comedi_handle_events(dev, s); } return IRQ_HANDLED; -- GitLab From ff6f21a5eee870f565aad1e29e71d9b5a4f255f3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:30 -0700 Subject: [PATCH 0439/9457] staging: comedi: hwdrv_apci3120: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 2950815b65f4..db6e14269c92 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1329,15 +1329,14 @@ static void apci3120_interrupt_dma(int irq, void *d) if (!(cmd->flags & CMDF_WAKE_EOS)) { s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + comedi_handle_events(dev, s); } } if (cmd->stop_src == TRIG_COUNT) if (devpriv->ui_AiActualScan >= cmd->stop_arg) { /* all data sampled */ - apci3120_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); + comedi_handle_events(dev, s); return; } @@ -1416,7 +1415,7 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) if (err == 0) s->async->events |= COMEDI_CB_OVERFLOW; - comedi_event(dev, s); + comedi_handle_events(dev, s); return 0; } @@ -1539,12 +1538,8 @@ static void apci3120_interrupt(int irq, void *d) outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - /* stop timer 0 and timer 1 */ - apci3120_cancel(dev, s); - - /* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */ s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); + comedi_handle_events(dev, s); break; -- GitLab From 215ecf8a524b3892536fc38317bb1dad2a47be04 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:31 -0700 Subject: [PATCH 0440/9457] staging: comedi: hwdrv_apci3120: do comedi_handle_events() at end of interrupt Currently comedi_handle_events() is done by both the DMA and non-DMA helper functions that are called by the interrupt handler. For aesthetics, move the comedi_handle_events() to the end of the interrupt handler and do it in one place. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index db6e14269c92..b06142b27df7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1327,16 +1327,13 @@ static void apci3120_interrupt_dma(int irq, void *d) devpriv->ul_DmaBufferVirtual[devpriv-> ui_DmaActualBuffer], samplesinbuf); - if (!(cmd->flags & CMDF_WAKE_EOS)) { + if (!(cmd->flags & CMDF_WAKE_EOS)) s->async->events |= COMEDI_CB_EOS; - comedi_handle_events(dev, s); - } } if (cmd->stop_src == TRIG_COUNT) if (devpriv->ui_AiActualScan >= cmd->stop_arg) { /* all data sampled */ s->async->events |= COMEDI_CB_EOA; - comedi_handle_events(dev, s); return; } @@ -1415,8 +1412,6 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) if (err == 0) s->async->events |= COMEDI_CB_OVERFLOW; - comedi_handle_events(dev, s); - return 0; } @@ -1539,8 +1534,6 @@ static void apci3120_interrupt(int irq, void *d) dev->iobase + APCI3120_WR_ADDRESS); s->async->events |= COMEDI_CB_EOA; - comedi_handle_events(dev, s); - break; case APCI3120_TIMER: @@ -1593,6 +1586,7 @@ static void apci3120_interrupt(int irq, void *d) } } + comedi_handle_events(dev, s); } /* -- GitLab From 7ff4b5847c7063c2f60bd1c40f59160389ae2449 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:32 -0700 Subject: [PATCH 0441/9457] staging: comedi: addi_apci_2032: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Also, comedi_handle_events() does nothing if no events are set so the local variable 'do_event' can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_2032.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index aea3da325359..ad7529459429 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -178,7 +178,6 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) struct comedi_cmd *cmd = &s->async->cmd; struct apci2032_int_private *subpriv; unsigned int val; - bool do_event = false; if (!dev->attached) return IRQ_NONE; @@ -220,19 +219,16 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) if (subpriv->stop_count == 0) { /* end of acquisition */ s->async->events |= COMEDI_CB_EOA; - apci2032_int_stop(dev, s); } } } else { - apci2032_int_stop(dev, s); s->async->events |= COMEDI_CB_OVERFLOW; } - do_event = true; } spin_unlock(&subpriv->spinlock); - if (do_event) - comedi_event(dev, s); + + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 066021912a40c1ae76e696f24f87451becb7612b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:33 -0700 Subject: [PATCH 0442/9457] staging: comedi: amplc_dio200_common: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Also, comedi_handle_events() does nothing if no events are set so the local variable 'oldevents' can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200_common.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 2c1bfb09601d..944d454b7a37 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -272,7 +272,6 @@ static void dio200_read_scan_intr(struct comedi_device *dev, s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); } else { /* Error! Stop acquisition. */ - dio200_stop_intr(dev, s); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; dev_err(dev->class_dev, "buffer overflow\n"); } @@ -281,10 +280,8 @@ static void dio200_read_scan_intr(struct comedi_device *dev, if (cmd->stop_src == TRIG_COUNT) { if (subpriv->stopcount > 0) { subpriv->stopcount--; - if (subpriv->stopcount == 0) { + if (subpriv->stopcount == 0) s->async->events |= COMEDI_CB_EOA; - dio200_stop_intr(dev, s); - } } } } @@ -297,13 +294,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev, unsigned triggered; unsigned intstat; unsigned cur_enabled; - unsigned int oldevents; unsigned long flags; triggered = 0; spin_lock_irqsave(&subpriv->spinlock, flags); - oldevents = s->async->events; if (board->has_int_sce) { /* * Collect interrupt sources that have triggered and disable @@ -356,8 +351,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, } spin_unlock_irqrestore(&subpriv->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); return (triggered != 0); } -- GitLab From 2405124744245aff25e72c625456f609bca8ccd2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:34 -0700 Subject: [PATCH 0443/9457] staging: comedi: comedi_test: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. For aesthetics, add a local variable for the comedi_subdevice pointer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 00c03df72523..8845075cd3cc 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -164,7 +164,8 @@ static void waveform_ai_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; struct waveform_private *devpriv = dev->private; - struct comedi_async *async = dev->read_subdev->async; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int i, j; /* all times in microsec */ @@ -203,7 +204,7 @@ static void waveform_ai_interrupt(unsigned long arg) devpriv->usec_current + i * devpriv->scan_period + j * devpriv->convert_period); - cfc_write_to_buffer(dev->read_subdev, sample); + cfc_write_to_buffer(s, sample); } } @@ -216,7 +217,7 @@ static void waveform_ai_interrupt(unsigned long arg) else mod_timer(&devpriv->timer, jiffies + 1); - comedi_event(dev, dev->read_subdev); + comedi_handle_events(dev, s); } static int waveform_ai_cmdtest(struct comedi_device *dev, -- GitLab From 3fa1eb64d6d670676946ccd42d48452aecb96c2d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:35 -0700 Subject: [PATCH 0444/9457] staging: comedi: me4000: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Also, comedi_handle_events() does nothing if no events are set so the check can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 6561b00bea59..6516ac0c7b46 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1178,8 +1178,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); } - if (s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From 421c600dc408e98035ec7f297133f96e37d21d29 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:36 -0700 Subject: [PATCH 0445/9457] staging: comedi: pcl711: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. The pcl711_ai_set_mode() call when the end-of-acquisition is detected can then be removed. The (*cancel) does the same thing. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl711.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 47f4887108a7..b6e7f342935d 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -217,12 +217,10 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) s->async->events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; } else { s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - if (cmd->stop_src == TRIG_COUNT && !(--devpriv->ntrig)) { - pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG); + if (cmd->stop_src == TRIG_COUNT && !(--devpriv->ntrig)) s->async->events |= COMEDI_CB_EOA; - } } - comedi_event(dev, s); + comedi_handle_events(dev, s); return IRQ_HANDLED; } -- GitLab From c746db4e2b92ee603e8071302fbe56700c05aa61 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:37 -0700 Subject: [PATCH 0446/9457] staging: comedi: pcmmio: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Also, comedi_handle_events() does nothing if no events are set so the local variable 'oldevents' can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmmio.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index fc40ee2b34e9..6d60d40733f4 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -337,7 +337,6 @@ static void pcmmio_handle_dio_intr(struct comedi_device *dev, { struct pcmmio_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int oldevents = s->async->events; unsigned int val = 0; unsigned long flags; int i; @@ -359,29 +358,20 @@ static void pcmmio_handle_dio_intr(struct comedi_device *dev, /* Write the scan to the buffer. */ if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) { + comedi_buf_put(s, val >> 16)) s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Overflow! Stop acquisition!! */ - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr(dev, s); - } /* Check for end of acquisition. */ if (cmd->stop_src == TRIG_COUNT && devpriv->stop_count > 0) { devpriv->stop_count--; - if (devpriv->stop_count == 0) { + if (devpriv->stop_count == 0) s->async->events |= COMEDI_CB_EOA; - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr(dev, s); - } } done: spin_unlock_irqrestore(&devpriv->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); } static irqreturn_t interrupt_pcmmio(int irq, void *d) -- GitLab From bc43ae066239c122d643f4fefac38b03221be6d1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:38 -0700 Subject: [PATCH 0447/9457] staging: comedi: pcmuio: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Also, comedi_handle_events() does nothing if no events are set so the local variable 'oldevents' can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmuio.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index d4fe2ec25ecf..28e659889e4f 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -317,7 +317,6 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, int asic = pcmuio_subdevice_to_asic(s); struct pcmuio_asic *chip = &devpriv->asics[asic]; struct comedi_cmd *cmd = &s->async->cmd; - unsigned oldevents = s->async->events; unsigned int val = 0; unsigned long flags; unsigned int i; @@ -339,31 +338,22 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, /* Write the scan to the buffer. */ if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) { + comedi_buf_put(s, val >> 16)) s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Overflow! Stop acquisition!! */ - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmuio_stop_intr(dev, s); - } /* Check for end of acquisition. */ if (cmd->stop_src == TRIG_COUNT) { if (chip->stop_count > 0) { chip->stop_count--; - if (chip->stop_count == 0) { + if (chip->stop_count == 0) s->async->events |= COMEDI_CB_EOA; - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmuio_stop_intr(dev, s); - } } } done: spin_unlock_irqrestore(&chip->spinlock, flags); - if (oldevents != s->async->events) - comedi_event(dev, s); + comedi_handle_events(dev, s); } static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic) -- GitLab From 365dae93f72fdb281cf04cc43b93d4e044f3c70d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:39 -0700 Subject: [PATCH 0448/9457] staging: comedi: s626: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. The s626_mc_disable() call when the end-of-acquisition is detected can then be removed. The (*cancel) does the same thing. For aesthetics, also remove the 'finished' local variable and just return the ai_cmd_running state. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 11a12d787e4c..efd438f0ca62 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1480,7 +1480,6 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev) * from the final ADC of the previous poll list scan. */ uint32_t *readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1; - bool finished = false; int i; /* get the data and hand it over to comedi */ @@ -1505,25 +1504,16 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev) devpriv->ai_sample_count--; if (devpriv->ai_sample_count <= 0) { devpriv->ai_cmd_running = 0; - - /* Stop RPS program */ - s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1); - - /* send end of acquisition */ async->events |= COMEDI_CB_EOA; - - /* disable master interrupt */ - finished = true; } } if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) s626_dio_set_irq(dev, cmd->scan_begin_arg); - /* tell comedi that data is there */ - comedi_event(dev, s); + comedi_handle_events(dev, s); - return finished; + return !devpriv->ai_cmd_running; } static irqreturn_t s626_irq_handler(int irq, void *d) -- GitLab From 351a7bffbd4a02dd8a46209a4c6582860a72601d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:40 -0700 Subject: [PATCH 0449/9457] staging: comedi: rtd520: clear FIFO when canceling async command Clear the A/D FIFO as part of the analog input (*cancel) to help with cleaning up the async command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 7d4cb140959c..7d04a7ec3d30 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1083,6 +1083,7 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_count = 0; /* stop and don't transfer any more */ status = readw(dev->mmio + LAS0_IT); overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; + writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); return 0; } -- GitLab From a708e091598cd8937bcdba66d49d01d81df9b9ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:41 -0700 Subject: [PATCH 0450/9457] staging: comedi: rtd520: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. The code to cancel the async command can then be removed from rtd_interrupt(). Since the (*cancel) will also clear the FIFO, the ai_read_dregs() function can also be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 55 +++---------------------- 1 file changed, 6 insertions(+), 49 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 7d04a7ec3d30..1a62e8f249ae 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -632,35 +632,6 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } -/* - unknown amout of data is waiting in fifo. -*/ -static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct rtd_private *devpriv = dev->private; - - while (readl(dev->mmio + LAS0_ADC) & FS_ADC_NOT_EMPTY) { - unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO); - - if (0 == devpriv->ai_count) { /* done */ - continue; /* read rest */ - } - - d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ - d = comedi_offset_munge(s, d); - d &= s->maxdata; - - if (!comedi_buf_put(s, d)) - return -1; - - if (devpriv->ai_count > 0) /* < 0, means read forever */ - devpriv->ai_count--; - } - return 0; -} - /* Handle all rtd520 interrupts. Runs atomically and is never re-entered. @@ -703,8 +674,6 @@ static irqreturn_t rtd_interrupt(int irq, void *d) if (0 == devpriv->ai_count) goto xfer_done; - - comedi_event(dev, s); } else if (devpriv->xfer_count > 0) { if (fifo_status & FS_ADC_NOT_EMPTY) { /* FIFO not empty */ @@ -713,8 +682,6 @@ static irqreturn_t rtd_interrupt(int irq, void *d) if (0 == devpriv->ai_count) goto xfer_done; - - comedi_event(dev, s); } } } @@ -726,28 +693,16 @@ static irqreturn_t rtd_interrupt(int irq, void *d) /* clear the interrupt */ writew(status, dev->mmio + LAS0_CLEAR); readw(dev->mmio + LAS0_CLEAR); + + comedi_handle_events(dev, s); + return IRQ_HANDLED; xfer_abort: - writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); s->async->events |= COMEDI_CB_ERROR; - devpriv->ai_count = 0; /* stop and don't transfer any more */ - /* fall into xfer_done */ xfer_done: - /* pacer stop source: SOFTWARE */ - writel(0, dev->mmio + LAS0_PACER_STOP); - writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ - writel(0, dev->mmio + LAS0_ADC_CONVERSION); - writew(0, dev->mmio + LAS0_IT); - - if (devpriv->ai_count > 0) { /* there shouldn't be anything left */ - fifo_status = readl(dev->mmio + LAS0_ADC); - ai_read_dregs(dev, s); /* read anything left in FIFO */ - } - - s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */ - comedi_event(dev, s); + s->async->events |= COMEDI_CB_EOA; /* clear the interrupt */ status = readw(dev->mmio + LAS0_IT); @@ -757,6 +712,8 @@ static irqreturn_t rtd_interrupt(int irq, void *d) fifo_status = readl(dev->mmio + LAS0_ADC); overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; + comedi_handle_events(dev, s); + return IRQ_HANDLED; } -- GitLab From 39064f23284c68d3ce98e7f7b673a0ffa78c17ce Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:35:42 -0700 Subject: [PATCH 0451/9457] staging: comedi: amplc_pci230: use comedi_handle_events() Use comedi_handle_events() to automatically (*cancel) the async command for an end-of-acquisition or if an error/overflow occurs. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 8ed150689f97..b8fded313d64 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1089,8 +1089,6 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, ret = comedi_buf_get(s, &data); if (ret == 0) { s->async->events |= COMEDI_CB_OVERFLOW; - pci230_ao_stop(dev, s); - dev_err(dev->class_dev, "AO buffer underrun\n"); return; } pci230_ao_write_nofifo(dev, data, chan); @@ -1102,7 +1100,6 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, if (devpriv->ao_scan_count == 0) { /* End of acquisition. */ async->events |= COMEDI_CB_EOA; - pci230_ao_stop(dev, s); } } } @@ -1204,13 +1201,10 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; } } - if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { - /* Stopping AO due to completion or error. */ - pci230_ao_stop(dev, s); + if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) running = false; - } else { + else running = true; - } async->events |= events; return running; } @@ -1235,7 +1229,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, /* Not using DAC FIFO. */ spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); pci230_handle_ao_nofifo(dev, s); - comedi_event(dev, s); + comedi_handle_events(dev, s); } else { /* Using DAC FIFO. */ /* Read DACSWTRIG register to trigger conversion. */ @@ -1265,7 +1259,7 @@ static void pci230_ao_start(struct comedi_device *dev, /* Preload FIFO data. */ run = pci230_handle_ao_fifo(dev, s); - comedi_event(dev, s); + comedi_handle_events(dev, s); if (!run) { /* Stopped. */ return; @@ -2134,11 +2128,8 @@ static void pci230_handle_ai(struct comedi_device *dev, events |= COMEDI_CB_BLOCK; } async->events |= events; - if (async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) { - /* disable hardware conversions */ - pci230_ai_stop(dev, s); - } else { + if (!(async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | + COMEDI_CB_OVERFLOW))) { /* update FIFO interrupt trigger level */ pci230_ai_update_fifo_trigger_level(dev, s); } @@ -2355,7 +2346,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d) unsigned char status_int, valid_status_int, temp_ier; struct comedi_device *dev = (struct comedi_device *)d; struct pci230_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s_ao = dev->write_subdev; + struct comedi_subdevice *s_ai = dev->read_subdev; unsigned long irqflags; /* Read interrupt status/enable register. */ @@ -2385,23 +2377,14 @@ static irqreturn_t pci230_interrupt(int irq, void *d) * two. */ - if (valid_status_int & PCI230_INT_ZCLK_CT1) { - s = dev->write_subdev; - pci230_handle_ao_nofifo(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230_INT_ZCLK_CT1) + pci230_handle_ao_nofifo(dev, s_ao); - if (valid_status_int & PCI230P2_INT_DAC) { - s = dev->write_subdev; - pci230_handle_ao_fifo(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230P2_INT_DAC) + pci230_handle_ao_fifo(dev, s_ao); - if (valid_status_int & PCI230_INT_ADC) { - s = dev->read_subdev; - pci230_handle_ai(dev, s); - comedi_event(dev, s); - } + if (valid_status_int & PCI230_INT_ADC) + pci230_handle_ai(dev, s_ai); /* Reenable interrupts. */ spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); @@ -2410,6 +2393,9 @@ static irqreturn_t pci230_interrupt(int irq, void *d) devpriv->intr_running = false; spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + comedi_handle_events(dev, s_ao); + comedi_handle_events(dev, s_ai); + return IRQ_HANDLED; } -- GitLab From 46a5c3913bd2b0fa102f3d4ce9f7e9bdf9942772 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:13 -0700 Subject: [PATCH 0452/9457] staging: comedi: amplc_pci224: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 7ca6a6179cf2..9fcf6f77c96e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -514,7 +514,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, { struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int bytes_per_scan = cfc_bytes_per_scan(s); + unsigned int bytes_per_scan = comedi_bytes_per_scan(s); unsigned int num_scans; unsigned int room; unsigned short dacstat; -- GitLab From 36df06978adb2e960bad458a47a44e3f1cd4be2b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:14 -0700 Subject: [PATCH 0453/9457] staging: comedi: amplc_pci230: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index b8fded313d64..a04ce6bd3705 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1124,7 +1124,7 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, /* Get DAC FIFO status. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / cfc_bytes_per_scan(s); + num_scans = comedi_buf_read_n_available(s) / comedi_bytes_per_scan(s); if (cmd->stop_src == TRIG_COUNT) { /* Fixed number of scans. */ if (num_scans > devpriv->ao_scan_count) -- GitLab From 1b8db39fd9c403e90238797529694ba45d36b4e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:15 -0700 Subject: [PATCH 0454/9457] staging: comedi: das16: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 222a32ff0d32..5d47d0a1d45f 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -764,7 +764,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) return -1; } - devpriv->adc_byte_count = cmd->stop_arg * cfc_bytes_per_scan(s); + devpriv->adc_byte_count = cmd->stop_arg * comedi_bytes_per_scan(s); if (devpriv->can_burst) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG); -- GitLab From f4fc1dbe2944784457279a794cd77b72883fd9cb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:16 -0700 Subject: [PATCH 0455/9457] staging: comedi: mite: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index a43b5beffc4b..bc12765368ec 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -550,7 +550,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, { struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - u32 stop_count = cmd->stop_arg * cfc_bytes_per_scan(s); + u32 stop_count = cmd->stop_arg * comedi_bytes_per_scan(s); unsigned int old_alloc_count = async->buf_read_alloc_count; u32 nbytes_ub, nbytes_lb; int count; -- GitLab From 03bb28fcfd20a883c82b41e1a2e4c53db61405f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:17 -0700 Subject: [PATCH 0456/9457] staging: comedi: pcl812: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 700e4ef49019..72ae48f4d256 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -556,8 +556,8 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, /* we use EOS, so adapt DMA buffer to one scan */ if (devpriv->ai_eos) { - devpriv->dmabytestomove[0] = cfc_bytes_per_scan(s); - devpriv->dmabytestomove[1] = cfc_bytes_per_scan(s); + devpriv->dmabytestomove[0] = comedi_bytes_per_scan(s); + devpriv->dmabytestomove[1] = comedi_bytes_per_scan(s); devpriv->dma_runs_to_end = 1; } else { devpriv->dmabytestomove[0] = devpriv->hwdmasize; @@ -572,7 +572,7 @@ static void pcl812_ai_setup_dma(struct comedi_device *dev, devpriv->dma_runs_to_end = 1; } else { /* how many samples we must transfer? */ - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ devpriv->dma_runs_to_end = -- GitLab From 3d18aa60ec898092462d28e5e8e50b89082357d4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:18 -0700 Subject: [PATCH 0457/9457] staging: comedi: pcl816: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index e4383ac2b505..65cbafb85698 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -160,7 +160,7 @@ static void pcl816_ai_setup_dma(struct comedi_device *dev, bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { /* how many */ - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); /* how many DMA pages we must fill */ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; -- GitLab From ab192afc6571c49570ff52ab9c833a8f61ae6b18 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:19 -0700 Subject: [PATCH 0458/9457] staging: comedi: pcl818: use comedi_bytes_per_scan() This inline function is just a wrapper around comedi_bytes_per_scan(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 618591d3b3b3..9921e1fa7515 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -352,7 +352,7 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev, disable_dma(devpriv->dma); /* disable dma */ bytes = devpriv->hwdmasize; if (cmd->stop_src == TRIG_COUNT) { - bytes = cmd->stop_arg * cfc_bytes_per_scan(s); + bytes = cmd->stop_arg * comedi_bytes_per_scan(s); devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize; devpriv->last_dma_run = bytes % devpriv->hwdmasize; devpriv->dma_runs_to_end--; -- GitLab From f3055f9ef3b12b8c4c2029fb76d0163733090594 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:41:20 -0700 Subject: [PATCH 0459/9457] staging: comedi: comedi_fc.h: remove cfc_bytes_per_scan() This inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index d381bc1b2a2b..d8a6a8e27c51 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -23,11 +23,6 @@ #include "../comedidev.h" -static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *s) -{ - return comedi_bytes_per_scan(s); -} - static inline void cfc_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes) { -- GitLab From eac783a6b723672b4b684a92e9cc3d4e8383e03e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:46:05 -0700 Subject: [PATCH 0460/9457] staging: comedi: mite: use comedi_inc_scan_progress() This inline function is just a wrapper around comedi_inc_scan_progress(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index bc12765368ec..ffc9e61d6cdd 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -539,7 +539,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, return 0; comedi_buf_write_free(s, count); - cfc_inc_scan_progress(s, count); + comedi_inc_scan_progress(s, count); async->events |= COMEDI_CB_BLOCK; return 0; } -- GitLab From 5d0d813d34cded724450f1149e9402bc6fbc3270 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 18 Sep 2014 11:46:06 -0700 Subject: [PATCH 0461/9457] staging: comedi: comedi_fc.h: remove cfc_inc_scan_progress() This inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index d8a6a8e27c51..0f4b360cf9ec 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -23,12 +23,6 @@ #include "../comedidev.h" -static inline void cfc_inc_scan_progress(struct comedi_subdevice *s, - unsigned int num_bytes) -{ - comedi_inc_scan_progress(s, num_bytes); -} - static inline unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes) -- GitLab From 5d096c3b2609d894d93348e4df90a720f8645dd1 Mon Sep 17 00:00:00 2001 From: Rahul Bedarkar Date: Wed, 1 Oct 2014 22:26:01 +0530 Subject: [PATCH 0462/9457] staging: bcm: fix sparse warning in module_param This patch fixes sparse warning in module_param warning: pointer targets in return differ in signedness [-Wpointer-sign] Signed-off-by: Rahul Bedarkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index bb61d34886b3..9eaffd884a4c 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -15,7 +15,7 @@ static struct usb_device_id InterfaceUsbtable[] = { MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); static int debug = -1; -module_param(debug, uint, 0600); +module_param(debug, int, 0600); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static const u32 default_msg = -- GitLab From 748d9dd1b1b6cd88a0dbc0b3dd49fb51dcb1c9de Mon Sep 17 00:00:00 2001 From: Rahul Bedarkar Date: Wed, 1 Oct 2014 22:41:36 +0530 Subject: [PATCH 0463/9457] staging: dgap: remove unused variable 'orig_count' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes sparse warning warning: variable ‘orig_count’ set but not used [-Wunused-but-set-variable] Signed-off-by: Rahul Bedarkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index d0be1cebf5a9..2f2aa59600e5 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -2629,7 +2629,6 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, char __iomem *vaddr; u16 head, tail, tmask, remain; int bufcount, n; - int orig_count; ulong lock_flags; if (!tty) @@ -2650,13 +2649,6 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, if (!count) return 0; - /* - * Store original amount of characters passed in. - * This helps to figure out if we should ask the FEP - * to send us an event when it has more space available. - */ - orig_count = count; - spin_lock_irqsave(&ch->ch_lock, lock_flags); /* Get our space available for the channel from the board */ -- GitLab From 9f2b744475b141a2d8e1bf047ecd06a054f300e3 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 8 Oct 2014 20:12:48 +0900 Subject: [PATCH 0464/9457] staging: dgap: remove unnecessary if statement for checking NULL dgap_release_remap() function is only called after the memory has been remapped so if statement for checking NULL doesn't need. And also release_mem_region() calls are moved after iounmap() calls. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 2f2aa59600e5..38077878f61a 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -1013,15 +1013,10 @@ static int dgap_do_remap(struct board_t *brd) static void dgap_release_remap(struct board_t *brd) { - if (brd->re_map_membase) { - release_mem_region(brd->membase, 0x200000); - iounmap(brd->re_map_membase); - } - - if (brd->re_map_port) { - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - iounmap(brd->re_map_port); - } + iounmap(brd->re_map_port); + iounmap(brd->re_map_membase); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + release_mem_region(brd->membase, 0x200000); } /***************************************************************************** * -- GitLab From 263bd1cb84a86c675a8edff6eee5b8c12c889f50 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 8 Oct 2014 20:13:21 +0900 Subject: [PATCH 0465/9457] staging: dgap: change function names properly dgap_do_remap() and dgap_release_remap() names could be changed to dgap_remap() and dgap_unmap(). Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 38077878f61a..d0eb5ea43965 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -78,8 +78,8 @@ static void dgap_cleanup_board(struct board_t *brd); static void dgap_poll_handler(ulong dummy); static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static void dgap_remove_one(struct pci_dev *dev); -static int dgap_do_remap(struct board_t *brd); -static void dgap_release_remap(struct board_t *brd); +static int dgap_remap(struct board_t *brd); +static void dgap_unmap(struct board_t *brd); static irqreturn_t dgap_intr(int irq, void *voidbrd); static int dgap_tty_open(struct tty_struct *tty, struct file *file); @@ -621,7 +621,7 @@ static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dgap_free_flipbuf(brd); cleanup_brd: dgap_cleanup_nodes(); - dgap_release_remap(brd); + dgap_unmap(brd); kfree(brd); return rc; @@ -683,7 +683,7 @@ static void dgap_cleanup_board(struct board_t *brd) tasklet_kill(&brd->helper_tasklet); - dgap_release_remap(brd); + dgap_unmap(brd); /* Free all allocated channels structs */ for (i = 0; i < MAXPORTS ; i++) @@ -804,7 +804,7 @@ static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet, (unsigned long) brd); - ret = dgap_do_remap(brd); + ret = dgap_remap(brd); if (ret) goto free_brd; @@ -979,7 +979,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, /* * Remap PCI memory. */ -static int dgap_do_remap(struct board_t *brd) +static int dgap_remap(struct board_t *brd) { if (!brd || brd->magic != DGAP_BOARD_MAGIC) return -EIO; @@ -1011,7 +1011,7 @@ static int dgap_do_remap(struct board_t *brd) return 0; } -static void dgap_release_remap(struct board_t *brd) +static void dgap_unmap(struct board_t *brd) { iounmap(brd->re_map_port); iounmap(brd->re_map_membase); -- GitLab From e92c3511b91fa1e5b76b755fadece3637bb0de61 Mon Sep 17 00:00:00 2001 From: Nitin Kuppelur Date: Wed, 1 Oct 2014 17:04:27 +0200 Subject: [PATCH 0466/9457] Staging: rtl8712:ieee80211 remove unnecessary else Removed unnecessary else after return/break to solve checkpatch.pl warning Signed-off-by: Nitin Kuppelur Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/ieee80211.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index fe9459e483c5..eb23b08cb7fd 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -124,11 +124,10 @@ u8 *r8712_get_ie(u8 *pbuf, sint index, sint *len, sint limit) if (*p == index) { *len = *(p + 1); return p; - } else { - tmp = *(p + 1); - p += (tmp + 2); - i += (tmp + 2); } + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); if (i >= limit) break; } @@ -237,10 +236,9 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) goto check_next_ie; *wpa_ie_len = *(pbuf + 1); return pbuf; - } else { - *wpa_ie_len = 0; - return NULL; } + *wpa_ie_len = 0; + return NULL; check_next_ie: limit = limit - (pbuf - pie) - 2 - len; if (limit <= 0) @@ -414,7 +412,7 @@ int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) cnt += in_ie[cnt+1]+2; match = true; break; - } else + } cnt += in_ie[cnt+1]+2; /* goto next */ } return match; -- GitLab From a15522c0a4208ce076f093668e9658a7b08c20b1 Mon Sep 17 00:00:00 2001 From: Serguey Parkhomovsky Date: Tue, 7 Oct 2014 20:42:45 -0700 Subject: [PATCH 0467/9457] staging: rtl8712: fix unnecessary elses after return/break in rtl8712_efuse.c This patch fixes two unnecessary else conditions that were found by checkpatch.pl. Signed-off-by: Serguey Parkhomovsky Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl8712_efuse.c | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index c9eeb4270ab9..97b78392e6c8 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -414,19 +414,18 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, bResult = false; } break; - } else { /* write header fail */ - bResult = false; - if (0xFF == efuse_data) - return bResult; /* nothing damaged. */ - /* call rescue procedure */ - if (fix_header(padapter, efuse_data, efuse_addr) == - false) - return false; /* rescue fail */ - - if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ - break; - /* otherwise, take another risk... */ } + /* write header fail */ + bResult = false; + if (0xFF == efuse_data) + return bResult; /* nothing damaged. */ + /* call rescue procedure */ + if (!fix_header(padapter, efuse_data, efuse_addr)) + return false; /* rescue fail */ + + if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ + break; + /* otherwise, take another risk... */ } return bResult; } @@ -541,15 +540,16 @@ u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, u16 cnts, } idx++; break; - } else { - if ((data[idx] != pktdata[i]) || (data[idx+1] != - pktdata[i+1])) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = data[idx + 1]; - } - idx += 2; } + + if ((data[idx] != pktdata[i]) || (data[idx+1] != + pktdata[i+1])) { + word_en &= ~BIT(i >> 1); + newdata[j++] = data[idx]; + newdata[j++] = data[idx + 1]; + } + idx += 2; + if (idx == cnts) break; } -- GitLab From 6232876b723bb7954dd23405963155d8fb8dd654 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 7 Oct 2014 17:53:20 +0200 Subject: [PATCH 0468/9457] staging: gs_fpgaboot: Use print_hex_dump_bytes instead of pr_info Use print_hex_dump_bytes instead of pr_info Signed-off-by: Dzmitry Sledneu Reviewed-by: Insop Song Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 25 ++--------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 1875bd3b823f..cbf70cefe6f5 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -46,27 +46,6 @@ static char *file = "xlinx_fpga_firmware.bit"; module_param(file, charp, S_IRUGO); MODULE_PARM_DESC(file, "Xilinx FPGA firmware file."); -#ifdef DEBUG_FPGA -static void datadump(char *msg, void *m, int n) -{ - int i; - unsigned char *c; - - pr_info("=== %s ===\n", msg); - - c = m; - - for (i = 0; i < n; i++) { - if ((i&0xf) == 0) - pr_info(KERN_INFO "\n 0x%4x: ", i); - - pr_info("%02X ", c[i]); - } - - pr_info("\n"); -} -#endif /* DEBUG_FPGA */ - static void read_bitstream(char *bitdata, char *buf, int *offset, int rdsize) { memcpy(buf, bitdata + *offset, rdsize); @@ -220,9 +199,9 @@ static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes) size = fimage->lendata; #ifdef DEBUG_FPGA - datadump("bitfile sample", bitdata, 0x100); + print_hex_dump_bytes("bitfile sample: ", DUMP_PREFIX_OFFSET, + bitdata, 0x100); #endif /* DEBUG_FPGA */ - if (!xl_supported_prog_bus_width(bus_bytes)) { pr_err("unsupported program bus width %d\n", bus_bytes); -- GitLab From 812283cd54637633c1b5aa8d86667afe6c507f0e Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Thu, 2 Oct 2014 09:13:35 -0700 Subject: [PATCH 0469/9457] staging: Add Xilinx Clocking Wizard driver Add a driver for the Xilinx Clocking Wizard soft IP. The clocking wizard provides an AXI interface to dynamically reconfigure the clocking resources of Xilinx FPGAs. Signed-off-by: Soren Brinkmann Acked-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/clocking-wizard/Kconfig | 9 + drivers/staging/clocking-wizard/Makefile | 1 + drivers/staging/clocking-wizard/TODO | 12 + .../clocking-wizard/clk-xlnx-clock-wizard.c | 335 ++++++++++++++++++ .../staging/clocking-wizard/dt-binding.txt | 30 ++ 7 files changed, 390 insertions(+) create mode 100644 drivers/staging/clocking-wizard/Kconfig create mode 100644 drivers/staging/clocking-wizard/Makefile create mode 100644 drivers/staging/clocking-wizard/TODO create mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c create mode 100644 drivers/staging/clocking-wizard/dt-binding.txt diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4690ae9a267f..80ad2078eea2 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -108,4 +108,6 @@ source "drivers/staging/skein/Kconfig" source "drivers/staging/unisys/Kconfig" +source "drivers/staging/clocking-wizard/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c780a0e70e15..17aa2231e208 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -46,3 +46,4 @@ obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ obj-$(CONFIG_CRYPTO_SKEIN) += skein/ obj-$(CONFIG_UNISYSSPAR) += unisys/ +obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ diff --git a/drivers/staging/clocking-wizard/Kconfig b/drivers/staging/clocking-wizard/Kconfig new file mode 100644 index 000000000000..357af02c562c --- /dev/null +++ b/drivers/staging/clocking-wizard/Kconfig @@ -0,0 +1,9 @@ +# +# Xilinx Clocking Wizard Driver +# + +config COMMON_CLK_XLNX_CLKWZRD + tristate "Xilinx Clocking Wizard" + depends on COMMON_CLK && OF + ---help--- + Support for the Xilinx Clocking Wizard IP core clock generator. diff --git a/drivers/staging/clocking-wizard/Makefile b/drivers/staging/clocking-wizard/Makefile new file mode 100644 index 000000000000..5ad352f521fe --- /dev/null +++ b/drivers/staging/clocking-wizard/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o diff --git a/drivers/staging/clocking-wizard/TODO b/drivers/staging/clocking-wizard/TODO new file mode 100644 index 000000000000..ebe99db7d153 --- /dev/null +++ b/drivers/staging/clocking-wizard/TODO @@ -0,0 +1,12 @@ +TODO: + - support for fractional multiplier + - support for fractional divider (output 0 only) + - support for set_rate() operations (may benefit from Stephen Boyd's + refactoring of the clk primitives: https://lkml.org/lkml/2014/9/5/766) + - review arithmetic + - overflow after multiplication? + - maximize accuracy before divisions + +Patches to: + Greg Kroah-Hartman + Sören Brinkmann diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c new file mode 100644 index 000000000000..b8d89525bffd --- /dev/null +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c @@ -0,0 +1,335 @@ +/* + * Xilinx 'Clocking Wizard' driver + * + * Copyright (C) 2013 - 2014 Xilinx + * + * Sören Brinkmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define WZRD_NUM_OUTPUTS 7 +#define WZRD_ACLK_MAX_FREQ 250000000UL + +#define WZRD_CLK_CFG_REG(n) (0x200 + 4 * n) + +#define WZRD_CLkOUT0_FRAC_EN BIT(18) +#define WZRD_CLkFBOUT_FRAC_EN BIT(26) + +#define WZRD_CLKFBOUT_MULT_SHIFT 8 +#define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT) +#define WZRD_DIVCLK_DIVIDE_SHIFT 0 +#define WZRD_DIVCLK_DIVIDE_MASK (0xff << WZRD_DIVCLK_DIVIDE_SHIFT) +#define WZRD_CLKOUT_DIVIDE_SHIFT 0 +#define WZRD_CLKOUT_DIVIDE_MASK (0xff << WZRD_DIVCLK_DIVIDE_SHIFT) + +enum clk_wzrd_int_clks { + wzrd_clk_mul, + wzrd_clk_mul_div, + wzrd_clk_int_max +}; + +/** + * struct clk_wzrd: + * @clk_data: Clock data + * @nb: Notifier block + * @base: Memory base + * @clk_in1: Handle to input clock 'clk_in1' + * @axi_clk: Handle to input clock 's_axi_aclk' + * @clks_internal: Internal clocks + * @clkout: Output clocks + * @speed_grade: Speed grade of the device + * @suspended: Flag indicating power state of the device + */ +struct clk_wzrd { + struct clk_onecell_data clk_data; + struct notifier_block nb; + void __iomem *base; + struct clk *clk_in1; + struct clk *axi_clk; + struct clk *clks_internal[wzrd_clk_int_max]; + struct clk *clkout[WZRD_NUM_OUTPUTS]; + int speed_grade; + bool suspended; +}; +#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb) + +/* maximum frequencies for input/output clocks per speed grade */ +static const unsigned long clk_wzrd_max_freq[] = { + 800000000UL, + 933000000UL, + 1066000000UL +}; + +static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event, + void *data) +{ + unsigned long max; + struct clk_notifier_data *ndata = data; + struct clk_wzrd *clk_wzrd = to_clk_wzrd(nb); + + if (clk_wzrd->suspended) + return NOTIFY_OK; + + if (ndata->clk == clk_wzrd->clk_in1) + max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1]; + if (ndata->clk == clk_wzrd->axi_clk) + max = WZRD_ACLK_MAX_FREQ; + + switch (event) { + case PRE_RATE_CHANGE: + if (ndata->new_rate > max) + return NOTIFY_BAD; + return NOTIFY_OK; + case POST_RATE_CHANGE: + case ABORT_RATE_CHANGE: + default: + return NOTIFY_DONE; + } +} + +static int __maybe_unused clk_wzrd_suspend(struct device *dev) +{ + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); + + clk_disable_unprepare(clk_wzrd->axi_clk); + clk_wzrd->suspended = true; + + return 0; +} + +static int __maybe_unused clk_wzrd_resume(struct device *dev) +{ + int ret; + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); + + ret = clk_prepare_enable(clk_wzrd->axi_clk); + if (ret) { + dev_err(dev, "unable to enable s_axi_aclk\n"); + return ret; + } + + clk_wzrd->suspended = false; + + return 0; +} + +static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend, + clk_wzrd_resume); + +static int clk_wzrd_probe(struct platform_device *pdev) +{ + int i, ret; + u32 reg; + unsigned long rate; + const char *clk_name; + struct clk_wzrd *clk_wzrd; + struct resource *mem; + struct device_node *np = pdev->dev.of_node; + + clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL); + if (!clk_wzrd) + return -ENOMEM; + platform_set_drvdata(pdev, clk_wzrd); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + clk_wzrd->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(clk_wzrd->base)) + return PTR_ERR(clk_wzrd->base); + + ret = of_property_read_u32(np, "speed-grade", &clk_wzrd->speed_grade); + if (!ret) { + if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { + dev_warn(&pdev->dev, "invalid speed grade '%d'\n", + clk_wzrd->speed_grade); + clk_wzrd->speed_grade = 0; + } + } + + clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); + if (IS_ERR(clk_wzrd->clk_in1)) { + if (clk_wzrd->clk_in1 != ERR_PTR(-EPROBE_DEFER)) + dev_err(&pdev->dev, "clk_in1 not found\n"); + return PTR_ERR(clk_wzrd->clk_in1); + } + + clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clk_wzrd->axi_clk)) { + if (clk_wzrd->axi_clk != ERR_PTR(-EPROBE_DEFER)) + dev_err(&pdev->dev, "s_axi_aclk not found\n"); + return PTR_ERR(clk_wzrd->axi_clk); + } + ret = clk_prepare_enable(clk_wzrd->axi_clk); + if (ret) { + dev_err(&pdev->dev, "enabling s_axi_aclk failed\n"); + return ret; + } + rate = clk_get_rate(clk_wzrd->axi_clk); + if (rate > WZRD_ACLK_MAX_FREQ) { + dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", + rate); + ret = -EINVAL; + goto err_disable_clk; + } + + /* we don't support fractional div/mul yet */ + reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_CLkFBOUT_FRAC_EN; + reg |= readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2)) & + WZRD_CLkOUT0_FRAC_EN; + if (reg) + dev_warn(&pdev->dev, "fractional div/mul not supported\n"); + + /* register multiplier */ + reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_CLKFBOUT_MULT_MASK) >> WZRD_CLKFBOUT_MULT_SHIFT; + clk_name = kasprintf(GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); + if (!clk_name) { + ret = -ENOMEM; + goto err_disable_clk; + } + clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor( + &pdev->dev, clk_name, + __clk_get_name(clk_wzrd->clk_in1), + 0, reg, 1); + kfree(clk_name); + if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { + dev_err(&pdev->dev, "unable to register fixed-factor clock\n"); + ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); + goto err_disable_clk; + } + + /* register div */ + reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) & + WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT; + clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); + clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor( + &pdev->dev, clk_name, + __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), + 0, 1, reg); + if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { + dev_err(&pdev->dev, "unable to register divider clock\n"); + ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); + goto err_rm_int_clk; + } + + /* register div per output */ + for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) { + const char *clkout_name; + if (of_property_read_string_index(np, "clock-output-names", i, + &clkout_name)) { + dev_err(&pdev->dev, + "clock output name not specified\n"); + ret = -EINVAL; + goto err_rm_int_clks; + } + reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2) + i * 12); + reg &= WZRD_CLKOUT_DIVIDE_MASK; + reg >>= WZRD_CLKOUT_DIVIDE_SHIFT; + clk_wzrd->clkout[i] = clk_register_fixed_factor(&pdev->dev, + clkout_name, clk_name, 0, 1, reg); + if (IS_ERR(clk_wzrd->clkout[i])) { + int j; + for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++) + clk_unregister(clk_wzrd->clkout[j]); + dev_err(&pdev->dev, + "unable to register divider clock\n"); + ret = PTR_ERR(clk_wzrd->clkout[i]); + goto err_rm_int_clks; + } + } + + kfree(clk_name); + + clk_wzrd->clk_data.clks = clk_wzrd->clkout; + clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data); + + if (clk_wzrd->speed_grade) { + clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; + + ret = clk_notifier_register(clk_wzrd->clk_in1, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + + ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + } + + return 0; + +err_rm_int_clks: + clk_unregister(clk_wzrd->clks_internal[1]); +err_rm_int_clk: + kfree(clk_name); + clk_unregister(clk_wzrd->clks_internal[0]); +err_disable_clk: + clk_disable_unprepare(clk_wzrd->axi_clk); + + return ret; +} + +static int clk_wzrd_remove(struct platform_device *pdev) +{ + int i; + struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + + for (i = 0; i < WZRD_NUM_OUTPUTS; i++) + clk_unregister(clk_wzrd->clkout[i]); + for (i = 0; i < wzrd_clk_int_max; i++) + clk_unregister(clk_wzrd->clks_internal[i]); + + if (clk_wzrd->speed_grade) { + clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb); + clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb); + } + + clk_disable_unprepare(clk_wzrd->axi_clk); + + return 0; +} + +static const struct of_device_id clk_wzrd_ids[] = { + { .compatible = "xlnx,clocking-wizard" }, + { }, +}; +MODULE_DEVICE_TABLE(of, clk_wzrd_ids); + +static struct platform_driver clk_wzrd_driver = { + .driver = { + .name = "clk-wizard", + .of_match_table = clk_wzrd_ids, + .pm = &clk_wzrd_dev_pm_ops, + }, + .probe = clk_wzrd_probe, + .remove = clk_wzrd_remove, +}; +module_platform_driver(clk_wzrd_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Soeren Brinkmann ; + compatible = "xlnx,clocking-wizard"; + speed-grade = <1>; + clock-names = "clk_in1", "s_axi_aclk"; + clocks = <&clkc 15>, <&clkc 15>; + clock-output-names = "clk_out0", "clk_out1", "clk_out2", + "clk_out3", "clk_out4", "clk_out5", + "clk_out6", "clk_out7"; + }; -- GitLab From 8e3d161acc23ccf46c5d7b10c934d06ed79a7e48 Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Thu, 2 Oct 2014 18:28:41 -0500 Subject: [PATCH 0470/9457] drivers: staging: rtl8723au: core: Fix "'foo * bar' should be 'foo *bar'" errors Fix checkpatch.pl "'foo * bar' should be 'foo *bar'" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 2 +- drivers/staging/rtl8723au/core/rtw_led.c | 3 ++- drivers/staging/rtl8723au/core/rtw_mlme.c | 2 +- drivers/staging/rtl8723au/core/rtw_security.c | 27 ++++++++++--------- .../staging/rtl8723au/core/rtw_wlan_util.c | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index eb5d60ca2397..aedbd8f77529 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -1816,7 +1816,7 @@ void rtw_ap_restore_network(struct rtw_adapter *padapter) { struct mlme_priv *mlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *psta; struct security_priv *psecuritypriv = &padapter->securitypriv; struct list_head *phead, *plist, *ptmp; diff --git a/drivers/staging/rtl8723au/core/rtw_led.c b/drivers/staging/rtl8723au/core/rtw_led.c index 989cda29a57e..fa3dcff263d7 100644 --- a/drivers/staging/rtl8723au/core/rtw_led.c +++ b/drivers/staging/rtl8723au/core/rtw_led.c @@ -51,7 +51,8 @@ void BlinkWorkItemCallback23a(struct work_struct *work) /* Description: */ /* Reset status of led_8723a object. */ /* */ -void ResetLedStatus23a(struct led_8723a * pLed) { +void ResetLedStatus23a(struct led_8723a *pLed) +{ pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */ pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */ diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 1f6006439bbb..00e7ad06b5bd 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -1766,7 +1766,7 @@ int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv) return ret; } -int rtw_set_auth23a(struct rtw_adapter * adapter, +int rtw_set_auth23a(struct rtw_adapter *adapter, struct security_priv *psecuritypriv) { struct cmd_obj *pcmd; diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index 76371ae69377..b4886222fd5e 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -30,12 +30,12 @@ struct arc4context u8 state[256]; }; -static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len) +static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) { u32 t, u; u32 keyindex; u32 stateindex; - u8 * state; + u8 *state; u32 counter; state = parc4ctx->state; @@ -62,7 +62,7 @@ static u32 arcfour_byte( struct arc4context *parc4ctx) u32 x; u32 y; u32 sx, sy; - u8 * state; + u8 *state; state = parc4ctx->state; x = (parc4ctx->x + 1) & 0xff; @@ -78,8 +78,8 @@ static u32 arcfour_byte( struct arc4context *parc4ctx) } static void arcfour_encrypt( struct arc4context *parc4ctx, - u8 * dest, - u8 * src, + u8 *dest, + u8 *src, u32 len) { u32 i; @@ -221,7 +221,7 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter, u8 keyindex; struct rx_pkt_attrib *prxattrib = &precvframe->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sk_buff * skb = precvframe->pkt; + struct sk_buff *skb = precvframe->pkt; pframe = skb->data; @@ -266,7 +266,7 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter, /* 3 ===== TKIP related ===== */ -static u32 secmicgetuint32(u8 * p) +static u32 secmicgetuint32(u8 *p) /* Convert from Byte[] to u32 in a portable way */ { s32 i; @@ -280,7 +280,7 @@ static u32 secmicgetuint32(u8 * p) return res; } -static void secmicputuint32(u8 * p, u32 val) +static void secmicputuint32(u8 *p, u32 val) /* Convert from long to Byte[] in a portable way */ { long i; @@ -304,7 +304,7 @@ static void secmicclear(struct mic_data *pmicdata) } -void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 * key) +void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 *key) { /* Set the key */ @@ -340,7 +340,7 @@ void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b) } -void rtw_secmicappend23a(struct mic_data *pmicdata, u8 * src, u32 nbytes) +void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbytes) { /* This is simple */ @@ -352,7 +352,7 @@ void rtw_secmicappend23a(struct mic_data *pmicdata, u8 * src, u32 nbytes) } -void rtw_secgetmic23a(struct mic_data *pmicdata, u8 * dst) +void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst) { /* Append the minimum padding */ @@ -374,7 +374,8 @@ void rtw_secgetmic23a(struct mic_data *pmicdata, u8 * dst) } -void rtw_seccalctkipmic23a(u8 * key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri) +void rtw_seccalctkipmic23a(u8 *key, u8 *header, u8 *data, u32 data_len, + u8 *mic_code, u8 pri) { struct mic_data micdata; @@ -728,7 +729,7 @@ int rtw_tkip_decrypt23a(struct rtw_adapter *padapter, struct sta_info *stainfo; struct rx_pkt_attrib *prxattrib = &precvframe->attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sk_buff * skb = precvframe->pkt; + struct sk_buff *skb = precvframe->pkt; int res = _SUCCESS; pframe = skb->data; diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index 09c44a55d4a6..5c4006aa23b2 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -1080,7 +1080,7 @@ bool is_ap_in_tkip23a(struct rtw_adapter *padapter) return false; } -bool should_forbid_n_rate23a(struct rtw_adapter * padapter) +bool should_forbid_n_rate23a(struct rtw_adapter *padapter) { u32 i; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; -- GitLab From 8ce6b2d2b7e3d4a5d08c31b6ba5c659800c28daf Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Fri, 3 Oct 2014 10:36:40 -0500 Subject: [PATCH 0471/9457] drivers: staging: rtl8723au: Fix "open brace '{' following struct go on the same line" errors Fix checkpatch.pl "open brace '{' following struct go on the same line" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_security.c | 3 +-- drivers/staging/rtl8723au/include/rtl8723a_dm.h | 3 +-- drivers/staging/rtl8723au/include/rtl8723a_recv.h | 3 +-- drivers/staging/rtl8723au/include/rtw_cmd.h | 3 +-- drivers/staging/rtl8723au/include/rtw_ht.h | 3 +-- drivers/staging/rtl8723au/include/rtw_mlme_ext.h | 6 ++---- 6 files changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index b4886222fd5e..5da620c7ba82 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -23,8 +23,7 @@ #define CRC32_POLY 0x04c11db7 -struct arc4context -{ +struct arc4context { u32 x; u32 y; u8 state[256]; diff --git a/drivers/staging/rtl8723au/include/rtl8723a_dm.h b/drivers/staging/rtl8723au/include/rtl8723a_dm.h index 18112225e53f..bf236e8e47a2 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_dm.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_dm.h @@ -37,8 +37,7 @@ enum{ #define IQK_BB_REG_NUM 9 #define HP_THERMAL_NUM 8 /* duplicate code,will move to ODM ######### */ -struct dm_priv -{ +struct dm_priv { u32 InitODMFlag; /* Upper and Lower Signal threshold for Rate Adaptive*/ diff --git a/drivers/staging/rtl8723au/include/rtl8723a_recv.h b/drivers/staging/rtl8723au/include/rtl8723a_recv.h index 885d4d3859f8..0109052a4fbb 100644 --- a/drivers/staging/rtl8723au/include/rtl8723a_recv.h +++ b/drivers/staging/rtl8723au/include/rtl8723a_recv.h @@ -35,8 +35,7 @@ #define PHY_LINKQUALITY_SLID_WIN_MAX 20 -struct phy_stat -{ +struct phy_stat { unsigned int phydw0; unsigned int phydw1; unsigned int phydw2; diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h index ef67068a5fe3..8ffe5def3d4d 100644 --- a/drivers/staging/rtl8723au/include/rtw_cmd.h +++ b/drivers/staging/rtl8723au/include/rtw_cmd.h @@ -450,8 +450,7 @@ struct getrfintfs_parm { u8 rfintfs; }; -struct Tx_Beacon_param -{ +struct Tx_Beacon_param { struct wlan_bssid_ex network; }; diff --git a/drivers/staging/rtl8723au/include/rtw_ht.h b/drivers/staging/rtl8723au/include/rtw_ht.h index cfc947daf08b..780eb8944118 100644 --- a/drivers/staging/rtl8723au/include/rtw_ht.h +++ b/drivers/staging/rtl8723au/include/rtw_ht.h @@ -19,8 +19,7 @@ #include "linux/ieee80211.h" #include "wifi.h" -struct ht_priv -{ +struct ht_priv { bool ht_option; bool ampdu_enable;/* for enable Tx A-MPDU */ /* u8 baddbareq_issued[16]; */ diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h index 97c3c4478f29..51dba1fa4c5d 100644 --- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h @@ -270,8 +270,7 @@ struct action_handler { int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame); }; -struct ss_res -{ +struct ss_res { int state; int bss_cnt; int channel_idx; @@ -318,8 +317,7 @@ struct FW_Sta_Info { * 5. ... and so on, till survey done. */ -struct mlme_ext_info -{ +struct mlme_ext_info { u32 state; u32 reauth_count; u32 reassoc_count; -- GitLab From 175dbfae60c79a2a413abdf2d99b75089cc86e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 4 Oct 2014 00:31:17 +0300 Subject: [PATCH 0472/9457] staging: rts5208: combine ifs where possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Join together chained if's where possible to lower the indentation level. In a lot of places of this code the indentation level is already very high. As a result, this patch increases the code flow and readability. Signed-off-by: Giedrius Statkevičius Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 100 ++++++++++++---------------- 1 file changed, 44 insertions(+), 56 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index a7ade8b4e7f2..0db63fbe3db4 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -289,12 +289,10 @@ int rtsx_reset_chip(struct rtsx_chip *chip) /* Enable ASPM */ if (chip->aspm_l0s_l1_en) { if (chip->dynamic_aspm) { - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } + if (CHK_SDIO_EXIST(chip) && CHECK_PID(chip, 0x5288)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); } } else { if (CHECK_PID(chip, 0x5208)) @@ -350,18 +348,14 @@ int rtsx_reset_chip(struct rtsx_chip *chip) } - if (CHECK_PID(chip, 0x5288)) { - if (!CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, - 0x0103); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); + if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); - } + retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); } RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); @@ -1727,10 +1721,8 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) chip->ocp_int = ocp_int & status; #endif - if (chip->sd_io) { - if (chip->int_reg & DATA_DONE_INT) - chip->int_reg &= ~(u32)DATA_DONE_INT; - } + if (chip->sd_io && (chip->int_reg & DATA_DONE_INT)) + chip->int_reg &= ~(u32)DATA_DONE_INT; return STATUS_SUCCESS; } @@ -1796,31 +1788,29 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) void rtsx_enable_aspm(struct rtsx_chip *chip) { - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (!chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); - chip->aspm_enabled = 1; + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && !chip->aspm_enabled) { + dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); + chip->aspm_enabled = 1; - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0); - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); - } else { - rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - } + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0); + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, + 0x30 | chip->aspm_level[0]); + } else { + rtsx_write_config_byte(chip, LCTLR, + chip->aspm_l0s_l1_en); + } - if (CHK_SDIO_EXIST(chip)) { - u16 val = chip->aspm_l0s_l1_en | 0x0100; + if (CHK_SDIO_EXIST(chip)) { + u16 val = chip->aspm_l0s_l1_en | 0x0100; - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFFFF, val); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFFFF, val); - } + if (CHECK_PID(chip, 0x5288)) + rtsx_write_cfg_dw(chip, 2, 0xC0, + 0xFFFF, val); + else + rtsx_write_cfg_dw(chip, 1, 0xC0, + 0xFFFF, val); } } } @@ -1830,21 +1820,19 @@ void rtsx_disable_aspm(struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5208)) rtsx_monitor_aspm_config(chip); - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); - chip->aspm_enabled = 0; + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && chip->aspm_enabled) { + dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); + chip->aspm_enabled = 0; - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) - rtsx_write_register(chip, ASPM_FORCE_CTL, - 0xF3, 0x30); - else - rtsx_write_config_byte(chip, LCTLR, 0x00); + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0x0129); + if (CHECK_PID(chip, 0x5208)) + rtsx_write_register(chip, ASPM_FORCE_CTL, + 0xF3, 0x30); + else + rtsx_write_config_byte(chip, LCTLR, 0x00); - wait_timeout(1); - } + wait_timeout(1); } } -- GitLab From e050dda1e5de6e39dc6b3dbed9571e6b430e6f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 4 Oct 2014 00:31:18 +0300 Subject: [PATCH 0473/9457] staging: rts5208: get rid of Camel Case, remove unneeded lines and parantheses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert labels from Camel Case to lower case, remove unnecessary parantheses around operands of dereference operators and remove unneeded empty lines before }. Gets rid of a checkpatch.pl "check" that code should avoid Camel Case, also the code had a bunch of &(a) where a is some variable so it gets rid of them too. Finally, in a few places there were a empty line before } so remove them. Signed-off-by: Giedrius Statkevičius Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 52 ++++++++++++----------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 0db63fbe3db4..146b33734b74 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -314,7 +314,6 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } chip->aspm_enabled = 1; @@ -345,7 +344,6 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) { @@ -397,7 +395,6 @@ int rtsx_reset_chip(struct rtsx_chip *chip) reg); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->driver_first_load && @@ -416,7 +413,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) chip->int_reg = rtsx_readl(chip, RTSX_BIPR); if (chip->hw_bypass_sd) - goto NextCard; + goto nextcard; dev_dbg(rtsx_dev(chip), "In %s, chip->int_reg = 0x%x\n", __func__, chip->int_reg); if (chip->int_reg & SD_EXIST) { @@ -440,7 +437,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) 0); } -NextCard: +nextcard: if (chip->int_reg & XD_EXIST) chip->need_reset |= XD_CARD; if (chip->int_reg & MS_EXIST) @@ -646,7 +643,6 @@ static int rts5288_init(struct rtsx_chip *chip) chip->lun_mode = SD_MS_1LUN; else chip->lun_mode = DEFAULT_SINGLE; - } return STATUS_SUCCESS; @@ -654,9 +650,9 @@ static int rts5288_init(struct rtsx_chip *chip) int rtsx_init_chip(struct rtsx_chip *chip) { - struct sd_info *sd_card = &(chip->sd_card); - struct xd_info *xd_card = &(chip->xd_card); - struct ms_info *ms_card = &(chip->ms_card); + struct sd_info *sd_card = &chip->sd_card; + struct xd_info *xd_card = &chip->xd_card; + struct ms_info *ms_card = &chip->ms_card; int retval; unsigned int i; @@ -734,7 +730,6 @@ int rtsx_init_chip(struct rtsx_chip *chip) retval = rts5288_init(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (chip->ss_en == 2) @@ -836,7 +831,6 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) } else { if (reg0 & 0x03) maybe_support_aspm = 1; - } if (reg_changed) { @@ -861,7 +855,7 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) void rtsx_polling_func(struct rtsx_chip *chip) { #ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); + struct sd_info *sd_card = &chip->sd_card; #endif int ss_allowed; @@ -869,7 +863,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) return; if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) - goto Delink_Stage; + goto delink_stage; if (chip->polling_config) { u8 val; @@ -882,7 +876,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_OCP if (chip->ocp_int) { - rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat)); + rtsx_read_register(chip, OCPSTAT, &chip->ocp_stat); if (chip->card_exist & SD_CARD) sd_power_off_card3v3(chip); @@ -926,7 +920,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) rtsx_read_cfg_dw(chip, 1, 0x04, &val); if (val & 0x07) ss_allowed = 0; - } } } else { @@ -984,7 +977,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - } } @@ -1007,7 +999,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) break; } - #ifdef SUPPORT_OCP if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { if (chip->ocp_stat & @@ -1053,7 +1044,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) } #endif -Delink_Stage: +delink_stage: if (chip->auto_delink_en && chip->auto_delink_allowed && !chip->card_ready && !chip->card_ejected && !chip->sd_io) { int enter_L1 = chip->auto_delink_in_L1 && ( @@ -1095,7 +1086,6 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (enter_L1) rtsx_enter_L1(chip); - } } @@ -1670,12 +1660,12 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) if (status & SD_INT) { if (status & SD_EXIST) { - set_bit(SD_NR, &(chip->need_reset)); + set_bit(SD_NR, &chip->need_reset); } else { - set_bit(SD_NR, &(chip->need_release)); + set_bit(SD_NR, &chip->need_release); chip->sd_reset_counter = 0; chip->sd_show_cnt = 0; - clear_bit(SD_NR, &(chip->need_reset)); + clear_bit(SD_NR, &chip->need_reset); } } else { /* If multi-luns, it's possible that @@ -1685,35 +1675,35 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) all existed cards should be reset. */ if (exit_ss && (status & SD_EXIST)) - set_bit(SD_NR, &(chip->need_reinit)); + set_bit(SD_NR, &chip->need_reinit); } if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { if (status & XD_INT) { if (status & XD_EXIST) { - set_bit(XD_NR, &(chip->need_reset)); + set_bit(XD_NR, &chip->need_reset); } else { - set_bit(XD_NR, &(chip->need_release)); + set_bit(XD_NR, &chip->need_release); chip->xd_reset_counter = 0; chip->xd_show_cnt = 0; - clear_bit(XD_NR, &(chip->need_reset)); + clear_bit(XD_NR, &chip->need_reset); } } else { if (exit_ss && (status & XD_EXIST)) - set_bit(XD_NR, &(chip->need_reinit)); + set_bit(XD_NR, &chip->need_reinit); } } if (status & MS_INT) { if (status & MS_EXIST) { - set_bit(MS_NR, &(chip->need_reset)); + set_bit(MS_NR, &chip->need_reset); } else { - set_bit(MS_NR, &(chip->need_release)); + set_bit(MS_NR, &chip->need_release); chip->ms_reset_counter = 0; chip->ms_show_cnt = 0; - clear_bit(MS_NR, &(chip->need_reset)); + clear_bit(MS_NR, &chip->need_reset); } } else { if (exit_ss && (status & MS_EXIST)) - set_bit(MS_NR, &(chip->need_reinit)); + set_bit(MS_NR, &chip->need_reinit); } } -- GitLab From 21e69b7274ca82b0d180a0a7353ab79bed98509a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 4 Oct 2014 00:31:19 +0300 Subject: [PATCH 0474/9457] staging: rts5208: align divided lines to opening paranthesis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make all divided lines aligned to the opening paranthesis. Basically makes all lines aligned to the opening paranthesis to make the code more readable and it also gets rid of a lot of checkpatch.pl "checks". Signed-off-by: Giedrius Statkevičius Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 87 +++++++++++++++-------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 146b33734b74..b47eadee2571 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -126,10 +126,11 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { if (chip->asic_code) { RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + MS_INS_PU | SD_WP_PU | + SD_CD_PU | SD_CMD_PU); } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, - FPGA_SD_PULL_CTL_EN); + FPGA_SD_PULL_CTL_EN); } RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD); @@ -137,7 +138,7 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01); RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); + SDIO_BUS_CTRL | SDIO_CD_CTRL); chip->sd_int = 1; chip->sd_io = 1; @@ -201,7 +202,7 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); + FPGA_SD_PULL_CTL_BIT | 0x20, 0); } retval = card_share_mode(chip, SD_CARD); if (retval != STATUS_SUCCESS) @@ -268,7 +269,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) #ifdef LED_AUTO_BLINK RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, - LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); + LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); #endif if (chip->asic_code) { @@ -297,7 +298,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) } else { if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, - 0xFF, 0x3F); + 0xFF, 0x3F); retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); @@ -337,10 +338,10 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip)) { if (CHECK_PID(chip, 0x5288)) retval = rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFF00, 0x0100); + 0xFF00, 0x0100); else retval = rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFF00, 0x0100); + 0xFF00, 0x0100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); @@ -381,7 +382,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) reg &= 0xFE7F; reg |= 0x80; retval = rtsx_write_phy_register(chip, 0x00, - reg); + reg); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); @@ -392,13 +393,13 @@ int rtsx_reset_chip(struct rtsx_chip *chip) reg &= 0xFFF7; retval = rtsx_write_phy_register(chip, 0x1C, - reg); + reg); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } if (chip->driver_first_load && - (chip->ic_version < IC_VER_C)) + (chip->ic_version < IC_VER_C)) rtsx_calibration(chip); } else { @@ -434,7 +435,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip) } else { chip->sd_io = 0; RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, - 0); + 0); } nextcard: @@ -475,10 +476,10 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (chip->ft2_fast_mode) { RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, - MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); + MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); udelay(chip->pmos_pwr_on_interval); RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, - MS_POWER_ON | SD_POWER_ON); + MS_POWER_ON | SD_POWER_ON); wait_timeout(200); } @@ -847,8 +848,8 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) chip->sdio_aspm = 0; } rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, - 0x30 | chip->aspm_level[0] | - (chip->aspm_level[1] << 2)); + 0x30 | chip->aspm_level[0] | + (chip->aspm_level[1] << 2)); } } @@ -945,7 +946,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) #ifdef SUPPORT_SDIO_ASPM if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && - chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + chip->aspm_l0s_l1_en && chip->dynamic_aspm) { if (chip->sd_io) { dynamic_configure_sdio_aspm(chip); } else { @@ -1009,7 +1010,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { if (chip->card_exist & SD_CARD) { rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - 0); + 0); card_power_off(chip, SD_CARD); chip->card_fail |= SD_CARD; } @@ -1017,7 +1018,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { if (chip->card_exist & MS_CARD) { rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - 0); + 0); card_power_off(chip, MS_CARD); chip->card_fail |= MS_CARD; } @@ -1028,15 +1029,15 @@ void rtsx_polling_func(struct rtsx_chip *chip) chip->ocp_stat); if (chip->card_exist & SD_CARD) { rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - 0); + 0); chip->card_fail |= SD_CARD; } else if (chip->card_exist & MS_CARD) { rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - 0); + 0); chip->card_fail |= MS_CARD; } else if (chip->card_exist & XD_CARD) { rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, - 0); + 0); chip->card_fail |= XD_CARD; } card_power_off(chip, SD_CARD); @@ -1046,7 +1047,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) delink_stage: if (chip->auto_delink_en && chip->auto_delink_allowed && - !chip->card_ready && !chip->card_ejected && !chip->sd_io) { + !chip->card_ready && !chip->card_ejected && !chip->sd_io) { int enter_L1 = chip->auto_delink_in_L1 && ( chip->aspm_l0s_l1_en || chip->ss_en); int delink_stage1_cnt = chip->delink_stage1_step; @@ -1069,8 +1070,8 @@ void rtsx_polling_func(struct rtsx_chip *chip) rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); rtsx_write_register(chip, - CHANGE_LINK_STATE, 0x0A, - 0x0A); + CHANGE_LINK_STATE, + 0x0A, 0x0A); if (enter_L1) rtsx_enter_L1(chip); @@ -1082,7 +1083,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (enter_L1) rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); + rtsx_write_register(chip, + CHANGE_LINK_STATE, + 0x02, 0x02); if (enter_L1) rtsx_enter_L1(chip); @@ -1099,7 +1102,7 @@ void rtsx_polling_func(struct rtsx_chip *chip) rtsx_set_phy_reg_bit(chip, 0x1C, 2); rtsx_write_register(chip, CHANGE_LINK_STATE, - 0x0A, 0x0A); + 0x0A, 0x0A); } chip->auto_delink_cnt++; @@ -1203,7 +1206,7 @@ int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) } int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, - u32 val) + u32 val) { u8 mode = 0, tmp; int i; @@ -1263,7 +1266,7 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) } int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) + int len) { u32 *data, *mask; u16 offset = addr % 4; @@ -1308,7 +1311,7 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, for (i = 0; i < dw_len; i++) { retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, - mask[i], data[i]); + mask[i], data[i]); if (retval != STATUS_SUCCESS) { vfree(data); vfree(mask); @@ -1323,7 +1326,7 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, } int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) + int len) { u32 *data; u16 offset = addr % 4; @@ -1344,7 +1347,7 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, for (i = 0; i < dw_len; i++) { retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, - data + i); + data + i); if (retval != STATUS_SUCCESS) { vfree(data); TRACE_RET(chip, STATUS_FAIL); @@ -1650,7 +1653,7 @@ int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) chip->int_reg = rtsx_readl(chip, RTSX_BIPR); if (((chip->int_reg & int_enable) == 0) || - (chip->int_reg == 0xFFFFFFFF)) + (chip->int_reg == 0xFFFFFFFF)) return STATUS_FAIL; status = chip->int_reg &= (int_enable | 0x7FFFFF); @@ -1756,14 +1759,14 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) if (pm_stat == PM_S1) { dev_dbg(rtsx_dev(chip), "Host enter S1\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S1); + HOST_ENTER_S1); } else if (pm_stat == PM_S3) { if (chip->s3_pwr_off_delay > 0) wait_timeout(chip->s3_pwr_off_delay); dev_dbg(rtsx_dev(chip), "Host enter S3\n"); rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S3); + HOST_ENTER_S3); } if (chip->do_delink_before_power_down && chip->auto_delink_en) @@ -1786,10 +1789,10 @@ void rtsx_enable_aspm(struct rtsx_chip *chip) rtsx_write_phy_register(chip, 0x07, 0); if (CHECK_PID(chip, 0x5208)) { rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); + 0x30 | chip->aspm_level[0]); } else { rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); + chip->aspm_l0s_l1_en); } if (CHK_SDIO_EXIST(chip)) { @@ -1797,10 +1800,10 @@ void rtsx_enable_aspm(struct rtsx_chip *chip) if (CHECK_PID(chip, 0x5288)) rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFFFF, val); + 0xFFFF, val); else rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFFFF, val); + 0xFFFF, val); } } } @@ -1818,7 +1821,7 @@ void rtsx_disable_aspm(struct rtsx_chip *chip) rtsx_write_phy_register(chip, 0x07, 0x0129); if (CHECK_PID(chip, 0x5208)) rtsx_write_register(chip, ASPM_FORCE_CTL, - 0xF3, 0x30); + 0xF3, 0x30); else rtsx_write_config_byte(chip, LCTLR, 0x00); @@ -1885,7 +1888,7 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) for (j = 0; j < 256; j++) { rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); + *ptr); ptr++; } @@ -1899,7 +1902,7 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) for (j = 0; j < buf_len%256; j++) { rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); + *ptr); ptr++; } -- GitLab From fbbf359c4ca026e631fde19caff765af5c1afb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 4 Oct 2014 00:31:20 +0300 Subject: [PATCH 0475/9457] staging: rts5208: divide lines to make them less than 80 characters long MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make a couple of lines shorter than the max limit by diving them and also make sure to align them properly where possible. Signed-off-by: Giedrius Statkevičius Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 31 ++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index b47eadee2571..71dc6eea75d3 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -291,7 +291,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (chip->aspm_l0s_l1_en) { if (chip->dynamic_aspm) { if (CHK_SDIO_EXIST(chip) && CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, + chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } @@ -309,9 +310,13 @@ int rtsx_reset_chip(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip)) { chip->aspm_level[1] = chip->aspm_l0s_l1_en; if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + retval = rtsx_write_cfg_dw(chip, 2, + 0xC0, 0xFF, + chip->aspm_l0s_l1_en); else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + retval = rtsx_write_cfg_dw(chip, 1, + 0xC0, 0xFF, + chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); @@ -954,7 +959,8 @@ void rtsx_polling_func(struct rtsx_chip *chip) dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); + 0x30 | + (chip->aspm_level[1] << 2)); chip->sdio_aspm = 1; } } @@ -976,8 +982,10 @@ void rtsx_polling_func(struct rtsx_chip *chip) turn_off_led(chip, LED_GPIO); - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + if (chip->auto_power_down && !chip->card_ready && + !chip->sd_io) + rtsx_force_power_down(chip, + SSC_PDCTL | OC_PDCTL); } } @@ -1067,7 +1075,9 @@ void rtsx_polling_func(struct rtsx_chip *chip) dev_dbg(rtsx_dev(chip), "False card inserted, do force delink\n"); if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + rtsx_write_register(chip, + HOST_SLEEP_STATE, + 0x03, 1); rtsx_write_register(chip, CHANGE_LINK_STATE, @@ -1076,12 +1086,15 @@ void rtsx_polling_func(struct rtsx_chip *chip) if (enter_L1) rtsx_enter_L1(chip); - chip->auto_delink_cnt = delink_stage3_cnt + 1; + chip->auto_delink_cnt = + delink_stage3_cnt + 1; } else { dev_dbg(rtsx_dev(chip), "No card inserted, do delink\n"); if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + rtsx_write_register(chip, + HOST_SLEEP_STATE, + 0x03, 1); rtsx_write_register(chip, CHANGE_LINK_STATE, -- GitLab From 609fc15ef8908aff8822f26a7a987d12246cbc3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 4 Oct 2014 00:31:21 +0300 Subject: [PATCH 0476/9457] staging: rts5208: use ternary operators to reduce indentation level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert code in format of if (a) if(b) { [...] } to one line with a simple ternary operation to avoid unnecesary increase of indentation level. Signed-off-by: Giedrius Statkevičius Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 90 ++++++++--------------------- 1 file changed, 23 insertions(+), 67 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 71dc6eea75d3..ffcf5deb49b2 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -309,14 +309,10 @@ int rtsx_reset_chip(struct rtsx_chip *chip) chip->aspm_level[0] = chip->aspm_l0s_l1_en; if (CHK_SDIO_EXIST(chip)) { chip->aspm_level[1] = chip->aspm_l0s_l1_en; - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, - 0xC0, 0xFF, - chip->aspm_l0s_l1_en); - else - retval = rtsx_write_cfg_dw(chip, 1, - 0xC0, 0xFF, - chip->aspm_l0s_l1_en); + retval = rtsx_write_cfg_dw(chip, + CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF, + chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); @@ -341,12 +337,9 @@ int rtsx_reset_chip(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFF00, 0x0100); - else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFF00, 0x0100); + retval = rtsx_write_cfg_dw(chip, + CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF00, 0x0100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); @@ -537,10 +530,7 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; + chip->asic_code = val == 0 ? 1 : 0; if (chip->asic_code) { retval = rtsx_read_phy_register(chip, 0x1C, ®); @@ -550,10 +540,7 @@ static int rts5208_init(struct rtsx_chip *chip) dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n", reg); chip->ic_version = (reg >> 4) & 0x07; - if (reg & PHY_DEBUG_MODE) - chip->phy_debug_mode = 1; - else - chip->phy_debug_mode = 0; + chip->phy_debug_mode = reg & PHY_DEBUG_MODE ? 1 : 0; } else { RTSX_READ_REG(chip, 0xFE80, &val); @@ -563,16 +550,10 @@ static int rts5208_init(struct rtsx_chip *chip) RTSX_READ_REG(chip, PDINFO, &val); dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; + chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; RTSX_READ_REG(chip, 0xFE50, &val); - if (val & 0x01) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; + chip->hw_bypass_sd = val & 0x01 ? 1 : 0; rtsx_read_config_byte(chip, 0x0E, &val); if (val & 0x80) @@ -582,10 +563,7 @@ static int rts5208_init(struct rtsx_chip *chip) if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; + chip->auto_delink_en = val & 0x80 ? 1 : 0; } return STATUS_SUCCESS; @@ -599,33 +577,21 @@ static int rts5288_init(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; + chip->asic_code = val == 0 ? 1 : 0; chip->ic_version = 0; chip->phy_debug_mode = 0; RTSX_READ_REG(chip, PDINFO, &val); dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; + chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val); - if (val & 0x04) - chip->baro_pkg = QFN; - else - chip->baro_pkg = LQFP; + chip->baro_pkg = val & 0x04 ? QFN : LQFP; RTSX_READ_REG(chip, 0xFE5A, &val); - if (val & 0x10) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; + chip->hw_bypass_sd = val & 0x10 ? 1 : 0; retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); if (retval != STATUS_SUCCESS) @@ -640,10 +606,7 @@ static int rts5288_init(struct rtsx_chip *chip) if (chip->use_hw_setting) { RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; + chip->auto_delink_en = val & 0x80 ? 1 : 0; if (CHECK_BARO_PKG(chip, LQFP)) chip->lun_mode = SD_MS_1LUN; @@ -1522,7 +1485,7 @@ int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - if (0 == (value & (1 << bit))) { + if ((value & (1 << bit)) == 0) { value |= (1 << bit); retval = rtsx_write_phy_register(chip, reg, value); if (retval != STATUS_SUCCESS) @@ -1595,12 +1558,9 @@ void rtsx_enter_ss(struct rtsx_chip *chip) rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); } - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - } + if (CHK_SDIO_EXIST(chip)) + rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF00, 0x0100); if (chip->auto_delink_en) { rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); @@ -1811,12 +1771,8 @@ void rtsx_enable_aspm(struct rtsx_chip *chip) if (CHK_SDIO_EXIST(chip)) { u16 val = chip->aspm_l0s_l1_en | 0x0100; - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, - 0xFFFF, val); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, - 0xFFFF, val); + rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFFF, val); } } } -- GitLab From 9109fcff29c67ccdd541fa2bcd1cd58a1134ddf9 Mon Sep 17 00:00:00 2001 From: Aleh Suprunovich Date: Tue, 7 Oct 2014 14:52:52 +0300 Subject: [PATCH 0477/9457] staging: octeon-usb: fix checkpatch.pl warnings fixed several 'line over 80 characters' in places where it can be done without changing/refactoring code Signed-off-by: Aleh Suprunovich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon-usb/octeon-hcd.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 7ac64efc6520..4337a2fe282e 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -1327,7 +1327,8 @@ static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb) /* Loop writing the FIFO data for this packet into memory */ while (bytes > 0) { - *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index)); + *ptr++ = __cvmx_usb_read_csr32(usb, + USB_FIFO_ADDRESS(channel, usb->index)); bytes -= 4; } CVMX_SYNCW; @@ -1478,7 +1479,8 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel) fifo = &usb->nonperiodic; fifo->entry[fifo->head].channel = channel; - fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8); + fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, + CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8); fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2; fifo->head++; if (fifo->head > MAX_CHANNELS) @@ -1699,7 +1701,9 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb, usbc_hcintmsk.s.stallmsk = 1; usbc_hcintmsk.s.xfercomplmsk = 1; } - __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32); + __cvmx_usb_write_csr32(usb, + CVMX_USBCX_HCINTMSKX(channel, usb->index), + usbc_hcintmsk.u32); /* Enable the channel interrupt to propagate */ usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, @@ -2879,9 +2883,11 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) struct usb_ctrlrequest *header = cvmx_phys_to_ptr(transaction->control_header); if (header->wLength) - transaction->stage = CVMX_USB_STAGE_DATA; + transaction->stage = + CVMX_USB_STAGE_DATA; else - transaction->stage = CVMX_USB_STAGE_STATUS; + transaction->stage = + CVMX_USB_STAGE_STATUS; } break; case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE: @@ -2889,9 +2895,11 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) struct usb_ctrlrequest *header = cvmx_phys_to_ptr(transaction->control_header); if (header->wLength) - transaction->stage = CVMX_USB_STAGE_DATA; + transaction->stage = + CVMX_USB_STAGE_DATA; else - transaction->stage = CVMX_USB_STAGE_STATUS; + transaction->stage = + CVMX_USB_STAGE_STATUS; } break; case CVMX_USB_STAGE_DATA: @@ -3013,7 +3021,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) * is complete, the pipe sleeps until the next * schedule interval */ - if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) { + if (pipe->transfer_dir == + CVMX_USB_DIRECTION_OUT) { /* * If no space left or this wasn't a max * size packet then this transfer is -- GitLab From b9fc9cf29e5d5a545bd00b7fa4eed2c9ae3e3ccb Mon Sep 17 00:00:00 2001 From: Roberto Medina Date: Wed, 8 Oct 2014 21:18:44 +0200 Subject: [PATCH 0478/9457] Staging: octeon: ethernet-tx: fixed coding style warnings, missing blank lines Fixed coding style warnings due to missing blank lines. Dubious additions removed. Signed-off-by: Roberto Medina Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-tx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 4e54d8540219..b7a7854d3f7e 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -77,6 +77,7 @@ static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0); static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau) { int32_t undo; + undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE; if (undo > 0) @@ -89,6 +90,7 @@ static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau) static void cvm_oct_kick_tx_poll_watchdog(void) { union cvmx_ciu_timx ciu_timx; + ciu_timx.u64 = 0; ciu_timx.s.one_shot = 1; ciu_timx.s.len = cvm_oct_tx_poll_interval; @@ -118,9 +120,11 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) total_freed += skb_to_free; if (skb_to_free > 0) { struct sk_buff *to_free_list = NULL; + spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags); while (skb_to_free > 0) { struct sk_buff *t; + t = __skb_dequeue(&priv->tx_free_list[qos]); t->next = to_free_list; to_free_list = t; @@ -131,6 +135,7 @@ static void cvm_oct_free_tx_skbs(struct net_device *dev) /* Do the actual freeing outside of the lock. */ while (to_free_list) { struct sk_buff *t = to_free_list; + to_free_list = to_free_list->next; dev_kfree_skb_any(t); } @@ -258,6 +263,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); if (gmx_prt_cfg.s.duplex == 0) { int add_bytes = 64 - skb->len; + if ((skb_tail_pointer(skb) + add_bytes) <= skb_end_pointer(skb)) memset(__skb_put(skb, add_bytes), 0, @@ -289,6 +295,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i; + hw_buffer.s.addr = XKPHYS_TO_PHYS( (u64)(page_address(fs->page.p) + fs->page_offset)); @@ -495,6 +502,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) while (skb_to_free > 0) { struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]); + t->next = to_free_list; to_free_list = t; skb_to_free--; @@ -505,6 +513,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) /* Do the actual freeing outside of the lock. */ while (to_free_list) { struct sk_buff *t = to_free_list; + to_free_list = to_free_list->next; dev_kfree_skb_any(t); } @@ -550,6 +559,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Get a work queue entry */ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL); + if (unlikely(work == NULL)) { printk_ratelimited("%s: Failed to allocate a work queue entry\n", dev->name); @@ -713,6 +723,7 @@ static void cvm_oct_tx_do_cleanup(unsigned long arg) for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) { if (cvm_oct_device[port]) { struct net_device *dev = cvm_oct_device[port]; + cvm_oct_free_tx_skbs(dev); } } -- GitLab From fbc6d797e90fb502c3b2151158fb8e9d3feae7db Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:10 +0300 Subject: [PATCH 0479/9457] staging: rtl8723au: core: rtw_cmd: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_ap.c Warning: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_cmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index 4eaa50297b95..d2d7edf38fc6 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -359,6 +359,7 @@ int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, /* prepare ssid list */ if (ssid) { int i; + for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { if (ssid[i].ssid_len) { memcpy(&psurveyPara->ssid[i], &ssid[i], @@ -371,6 +372,7 @@ int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, /* prepare channel list */ if (ch) { int i; + for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { if (ch[i].hw_value && !(ch[i].flags & IEEE80211_CHAN_DISABLED)) { @@ -719,6 +721,7 @@ int rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key) memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); } else { int idx = psecuritypriv->dot118021XGrpKeyid; + memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[idx].skey, 16); } -- GitLab From 99ea15d6599177149393d62075ec29d61bea5fc3 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:12 +0300 Subject: [PATCH 0480/9457] staging: rtl8723au: core: rtw_ieee80211: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_ieee80211.c Warning: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ieee80211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c index 6274cb397c92..c78d6eb0ef89 100644 --- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c @@ -69,6 +69,7 @@ int rtw_get_bit_value_from_ieee_value23a(u8 val) {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0}; int i = 0; + while (dot11_rate_table[i] != 0) { if (dot11_rate_table[i] == val) return BIT(i); -- GitLab From 96d92eb7165170f45dd62dc6c71361ecca25e4b8 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:13 +0300 Subject: [PATCH 0481/9457] staging: rtl8723au: core: rtw_led: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_led.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_led.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8723au/core/rtw_led.c b/drivers/staging/rtl8723au/core/rtw_led.c index fa3dcff263d7..c66e727a2bca 100644 --- a/drivers/staging/rtl8723au/core/rtw_led.c +++ b/drivers/staging/rtl8723au/core/rtw_led.c @@ -44,6 +44,7 @@ static void BlinkTimerCallback(unsigned long data) void BlinkWorkItemCallback23a(struct work_struct *work) { struct led_8723a *pLed = container_of(work, struct led_8723a, BlinkWorkItem); + BlinkHandler23a(pLed); } -- GitLab From 29ed932fb25a952b80d4f64c860c7d6e3c6ea796 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:14 +0300 Subject: [PATCH 0482/9457] staging: rtl8723au: core: rtw_mlme: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_mlme.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 00e7ad06b5bd..62894702be29 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -1515,18 +1515,21 @@ void rtw_dynamic_check_timer_handler(unsigned long data) inline bool rtw_is_scan_deny(struct rtw_adapter *adapter) { struct mlme_priv *mlmepriv = &adapter->mlmepriv; + return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false; } void rtw_clear_scan_deny(struct rtw_adapter *adapter) { struct mlme_priv *mlmepriv = &adapter->mlmepriv; + atomic_set(&mlmepriv->set_scan_deny, 0); } void rtw_set_scan_deny_timer_hdl(unsigned long data) { struct rtw_adapter *adapter = (struct rtw_adapter *)data; + rtw_clear_scan_deny(adapter); } @@ -2151,6 +2154,7 @@ bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie, if (p && p[1] > 0) { u32 rx_packet_offset, max_recvbuf_sz; + if (pmlmepriv->qos_option == 0) { out_len = *pout_len; pframe = rtw_set_ie23a(out_ie + out_len, -- GitLab From 2ce71bda7bc16e1d2530f48e506a26529141231f Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:15 +0300 Subject: [PATCH 0483/9457] staging: rtl8723au: core: rtw_mlme_ext: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_mlme_ext.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 3eb77de17e3a..9298b382b6c6 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -331,6 +331,7 @@ rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt) int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch) { int i; + for (i = 0; ch_set[i]. ChannelNum != 0; i++) { if (ch == ch_set[i].ChannelNum) break; @@ -1572,6 +1573,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) pstat->uapsd_bk = 0; if (pmlmepriv->qos_option) { const u8 *end = pos + left; + p = pos; for (;;) { @@ -2599,7 +2601,9 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da, if (ssid_ie && cur_network->Ssid.ssid_len) { uint remainder_ielen; u8 *remainder_ie; + remainder_ie = ssid_ie + 2; + remainder_ielen = pframe - remainder_ie; DBG_8723A_LEVEL(_drv_warning_, "%s(%s): " @@ -2862,6 +2866,7 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta, if (psta) { /* for AP mode */ #ifdef CONFIG_8723AU_AP_MODE unsigned short val16; + ether_addr_copy(mgmt->da, psta->hwaddr); ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv)); @@ -3306,6 +3311,7 @@ static void issue_assocreq(struct rtw_adapter *padapter) !memcmp(p + 2, WMM_OUI23A, 4) || !memcmp(p + 2, WPS_OUI23A, 4)) { u8 plen = p[1]; + if (!padapter->registrypriv.wifi_spec) { /* Commented by Kurt 20110629 */ /* In some older APs, WPS handshake */ @@ -4070,6 +4076,7 @@ static void rtw_site_survey(struct rtw_adapter *padapter) if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */ { int i; + for (i = 0;isitesurvey_res.ssid[i].ssid_len) { /* todo: to issue two probe req??? */ @@ -4293,6 +4300,7 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, bssid->IELength); if (p && p[1] > 0) { struct ieee80211_ht_cap *pHT_caps; + pHT_caps = (struct ieee80211_ht_cap *)(p + 2); if (pHT_caps->cap_info & @@ -4319,6 +4327,7 @@ static void start_create_ibss(struct rtw_adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network; + pmlmeext->cur_channel = (u8)pnetwork->DSConfig; pmlmeinfo->bcn_interval = pnetwork->beacon_interval; -- GitLab From d2db1cff21f6b49c10f56eac692a86eb7ce59eba Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:16 +0300 Subject: [PATCH 0484/9457] staging: rtl8723au: core: rtw_pwrctrl: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_pwrctrl.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_pwrctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c index 1b2af7381d82..bf72c5ed6e24 100644 --- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c @@ -178,6 +178,7 @@ void rtw_ps_processor23a(struct rtw_adapter *padapter) static void pwr_state_check_handler(unsigned long data) { struct rtw_adapter *padapter = (struct rtw_adapter *)data; + rtw_ps_cmd23a(padapter); } @@ -470,6 +471,7 @@ void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter) inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms) { struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms); } -- GitLab From 547f975e60ce64b2b5318e47f210fec4cd225d7e Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:17 +0300 Subject: [PATCH 0485/9457] staging: rtl8723au: core: rtw_wlan_util: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_wlan_util.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index 5c4006aa23b2..c0b0047a9d3a 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -1153,6 +1153,7 @@ bool is_ap_in_wep23a(struct rtw_adapter *padapter) static int wifirate2_ratetbl_inx23a(unsigned char rate) { int inx = 0; + rate = rate & 0x7f; switch (rate) { @@ -1311,6 +1312,7 @@ unsigned char check_assoc_AP23a(u8 *pframe, uint len) u8 epigram_vendor_flag; u8 ralink_vendor_flag; const u8 *p; + epigram_vendor_flag = 0; ralink_vendor_flag = 0; -- GitLab From 831fa5f6f68f368e60bdaafb944827d829a8ced7 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:18 +0300 Subject: [PATCH 0486/9457] staging: rtl8723au: core: rtw_recv: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_recv.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_recv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 5bc7734d9a72..4dca863657ec 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -215,6 +215,7 @@ u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter) { u32 cnt = 0; struct recv_frame *pending_frame; + while ((pending_frame = rtw_alloc_recvframe23a(&adapter->recvpriv.uc_swdec_pending_queue))) { rtw_free_recvframe23a(pending_frame); DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__); @@ -239,6 +240,7 @@ int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue * int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue) { unsigned long irqL; + spin_lock_irqsave(&queue->lock, irqL); list_del_init(&precvbuf->list); @@ -364,6 +366,7 @@ int recvframe_chkmic(struct rtw_adapter *adapter, if (bmic_err == true) { int i; + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n *(pframemic-8)-*(pframemic-1) =" "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:" @@ -483,6 +486,7 @@ struct recv_frame *decryptor(struct rtw_adapter *padapter, if (prxattrib->encrypt > 0) { u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen; + prxattrib->key_index = (((iv[3]) >> 6) & 0x3); if (prxattrib->key_index > WEP_KEYS) { @@ -1066,6 +1070,7 @@ int sta2ap_data_frame(struct rtw_adapter *adapter, } } else { u8 *myhwaddr = myid(&adapter->eeprompriv); + if (!ether_addr_equal(pattrib->ra, myhwaddr)) { ret = RTW_RX_HANDLED; goto exit; -- GitLab From b8576413516065cba71b1dd48174397737337e40 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 01:22:19 +0300 Subject: [PATCH 0487/9457] staging: rtl8723au: core: rtw_xmit: Add blank line after declarations The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_xmit.c WARNING: Missing a blank line after declarations Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_xmit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c index 7a8038156cea..6c75794af82d 100644 --- a/drivers/staging/rtl8723au/core/rtw_xmit.c +++ b/drivers/staging/rtl8723au/core/rtw_xmit.c @@ -315,6 +315,7 @@ static void update_attrib_vcs_info(struct rtw_adapter *padapter, struct xmit_fra /* check HT op mode */ if (pattrib->ht_en) { u8 HTOpMode = pmlmeinfo->HT_protection; + if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) || (!pmlmeext->cur_bwmode && HTOpMode == 3)) { pattrib->vcs_mode = RTS_CTS; @@ -464,6 +465,7 @@ static int update_attrib(struct rtw_adapter *padapter, if (pattrib->pktlen > 282 + 24) { if (pattrib->ether_type == ETH_P_IP) {/* IP header */ u8 *pframe = skb->data; + pframe += ETH_HLEN; if ((pframe[21] == 68 && pframe[23] == 67) || -- GitLab From 25ef419dc92a16d64380d85655b4381a2fb22dfb Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Thu, 9 Oct 2014 22:46:32 +0300 Subject: [PATCH 0488/9457] staging: vt6655: Use ether_addr_copy function This patch fixes the following checkpatch.pl warnings: WARNING: "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)" in file device_main.c Pahole shows that the addresses are aligned Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 3eb8e5c5366e..ed5e71237007 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1591,7 +1591,7 @@ static int device_open(struct net_device *dev) device_init_registers(pDevice); MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr); device_set_multi(pDevice->dev); // Init for Key Management -- GitLab From f3512d5fe86097a09267c547d60d15c8f3b61e15 Mon Sep 17 00:00:00 2001 From: Esra Altintas Date: Thu, 9 Oct 2014 21:37:44 +0300 Subject: [PATCH 0489/9457] staging: vt6655: Fixed C99 // comment errors in wpa.h The following patch fixes the checkpatch.pl warning: ERROR: do not use C99 // comments Signed-off-by: Esra Altintas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wpa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h index 1d1918a12641..d012cb97043f 100644 --- a/drivers/staging/vt6655/wpa.h +++ b/drivers/staging/vt6655/wpa.h @@ -80,4 +80,4 @@ WPAb_Is_RSN( PWLAN_IE_RSN_EXT pRSN ); -#endif // __WPA_H__ +#endif /* __WPA_H__ */ -- GitLab From 3ad96c140d3c49dd90359d08a70275c9030e7f4a Mon Sep 17 00:00:00 2001 From: Esra Altintas Date: Thu, 9 Oct 2014 20:20:25 +0300 Subject: [PATCH 0490/9457] staging: rtl8712: Fix unnecessary parentheses style warning in rtl871x_xmit.c This fixes the following checkpatch.pl warning: WARNING: Unnecessary parentheses - maybe == should be = ? Signed-off-by: Esra Altintas Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index f49acaf04076..9d26fd26d0d4 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -486,7 +486,7 @@ static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr, memset(hdr, 0, WLANHDR_OFFSET); SetFrameSubType(fctrl, pattrib->subtype); if (pattrib->subtype & WIFI_DATA_TYPE) { - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { /* to_ds = 1, fr_ds = 0; */ SetToDs(fctrl); memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), -- GitLab From e6768831352fb78b10347e6d421e79bd9e2c82f4 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Thu, 9 Oct 2014 19:30:05 +0530 Subject: [PATCH 0491/9457] Staging: lustre: Fix line over 80 characters warning The following checkpatch warning was fixed: WARNING: line over 80 characters Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 0311b96a2eeb..43ab250b087e 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -250,7 +250,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, data->ocd_brw_size = MD_MAX_BRW_SIZE; - err = obd_connect(NULL, &sbi->ll_md_exp, obd, &sbi->ll_sb_uuid, data, NULL); + err = obd_connect(NULL, &sbi->ll_md_exp, obd, &sbi->ll_sb_uuid, + data, NULL); if (err == -EBUSY) { LCONSOLE_ERROR_MSG(0x14f, "An MDT (md %s) is performing " "recovery, of which this client is not a " @@ -757,9 +758,9 @@ void ll_kill_super(struct super_block *sb) return; sbi = ll_s2sbi(sb); - /* we need to restore s_dev from changed for clustered NFS before put_super - * because new kernels have cached s_dev and change sb->s_dev in - * put_super not affected real removing devices */ + /* we need to restore s_dev from changed for clustered NFS before + * put_super because new kernels have cached s_dev and change sb->s_dev + * in put_super not affected real removing devices */ if (sbi) { sb->s_dev = sbi->ll_sdev_orig; sbi->ll_umounting = 1; @@ -1734,7 +1735,8 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); LASSERT(inode->i_mode != 0); if (S_ISREG(inode->i_mode)) - inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1, LL_MAX_BLKSIZE_BITS); + inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1, + LL_MAX_BLKSIZE_BITS); else inode->i_blkbits = inode->i_sb->s_blocksize_bits; if (body->valid & OBD_MD_FLUID) -- GitLab From f4c84dafdb892e5f2ae3a10bf753745cdfbecbd5 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 9 Oct 2014 08:29:11 +0530 Subject: [PATCH 0492/9457] staging: rtl8192u: Remove unused code Below return statement dm_send_rssi_tofw function has dead code. This patch removes dead code from dm_send_rssi_tofw. This was detected by smatch. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_dm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index bda153d55f7a..cf4d3dc5dc76 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -3475,7 +3475,6 @@ static void dm_check_txrateandretrycount(struct net_device *dev) static void dm_send_rssi_tofw(struct net_device *dev) { - DCMD_TXCMD_T tx_cmd; struct r8192_priv *priv = ieee80211_priv(dev); // If we test chariot, we should stop the TX command ? @@ -3483,9 +3482,6 @@ static void dm_send_rssi_tofw(struct net_device *dev) // 0x1e0(byte) to notify driver. write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; - tx_cmd.Op = TXCMD_SET_RX_RSSI; - tx_cmd.Length = 4; - tx_cmd.Value = priv->undecorated_smoothed_pwdb; } /*---------------------------Define function prototype------------------------*/ -- GitLab From 9dfb753b2d65f449844fe5d7fce15770a3c27cb6 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 16:35:29 +0300 Subject: [PATCH 0493/9457] staging: rtl8723au: core: rtw_mlme: fix void function return statements The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_mlme.c WARNING: void function return statements are not generally useful Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 62894702be29..7b6a5a9dc9b4 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -218,8 +218,6 @@ void rtw_generate_random_ibss23a(u8 *pibss) pibss[3] = curtime & 0xff;/* p[0]; */ pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */ pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */ - - return; } void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming) @@ -579,8 +577,6 @@ void rtw_atimdone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf) { RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n")); - - return; } void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf) @@ -650,8 +646,6 @@ void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf) kfree(survey->bss); survey->bss = NULL; - - return; } void -- GitLab From 6ff432714e6064250e02ec55628836cadd923e91 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 16:35:30 +0300 Subject: [PATCH 0494/9457] staging: rtl8723au: core: rtw_pwrctrl: Fix void function return statements style warning. The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_pwrctrl.c WARNING: void function return statements are not generally useful Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_pwrctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c index bf72c5ed6e24..32f1ab515f91 100644 --- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c @@ -172,7 +172,6 @@ void rtw_ps_processor23a(struct rtw_adapter *padapter) exit: rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); pwrpriv->ps_processing = false; - return; } static void pwr_state_check_handler(unsigned long data) -- GitLab From a2d50bc892d3a6d7d9d7b60603dc67f6278749e2 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 16:35:31 +0300 Subject: [PATCH 0495/9457] staging: rtl8723au: core: rtw_wlan_util: Fix void function return statements style warning. The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_wlan_util.c WARNING: void function return statements are not generally useful Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index c0b0047a9d3a..0126a3fa7fc9 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -608,8 +608,6 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter) DBG_8723A("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); } - - return; } static void bwmode_update_check(struct rtw_adapter *padapter, const u8 *p) @@ -750,7 +748,6 @@ void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p) else cap->mcs.rx_mask[i] &= MCS_rate_2R23A[i]; } - return; } void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p) @@ -771,7 +768,6 @@ void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p) pmlmeinfo->HT_info_enable = 1; memcpy(&pmlmeinfo->HT_info, p + 2, p[1]); - return; } void HTOnAssocRsp23a(struct rtw_adapter *padapter) -- GitLab From 22d59f4eb1d66de2748011189ca5d77cd33d01c4 Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 16:35:32 +0300 Subject: [PATCH 0496/9457] staging: rtl8723au: core: rtw_security: Fix void function return statements style warning. The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_security.c WARNING: void function return statements are not generally useful Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_security.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index 5da620c7ba82..60e944554ec5 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -259,8 +259,6 @@ void rtw_wep_decrypt23a(struct rtw_adapter *padapter, crc[1], payload[length - 3], crc[0], payload[length - 4])); } - - return; } /* 3 ===== TKIP related ===== */ -- GitLab From 2c7c63a30595ea99fbd65eff0d020948a5b882be Mon Sep 17 00:00:00 2001 From: Yeliz Taneroglu Date: Thu, 9 Oct 2014 16:35:33 +0300 Subject: [PATCH 0497/9457] staging: rtl8723au: core: rtw_ap: Fix void function return statements style warning. The following patch fixes the checkpatch.pl warning: drivers/staging/rtl8723au/core/rtw_ap.c WARNING: void function return statements are not generally useful Signed-off-by: Yeliz Taneroglu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index aedbd8f77529..75ae2492699a 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -1216,8 +1216,6 @@ static void update_bcn_wmm_ie(struct rtw_adapter *padapter) static void update_bcn_wps_ie(struct rtw_adapter *padapter) { DBG_8723A("%s\n", __func__); - - return; } static void update_bcn_p2p_ie(struct rtw_adapter *padapter) -- GitLab From 5e8dc1cbf7bf18306221ec3fea57be0683107b7a Mon Sep 17 00:00:00 2001 From: "Vladimir A. Nazarenko" Date: Thu, 9 Oct 2014 15:37:17 +1100 Subject: [PATCH 0498/9457] staging: vt6655: delete non-standard ioctl 0xFF Custom ioctl 0xff is legacy code that was used for patched version of wpa_supplicant, where function wpa_authen_Status_transfer() called this ioctl to tell authentication status to the driver. While from upstream was added only driver code to the kernel but not patches to the wpa_supplicant we can safely remove this unused ioctl. Signed-off-by: Vladimir A. Nazarenko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 970e80d92fb9..f8e990fcc6fd 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -618,38 +618,6 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) pReq->wResult = 0; break; -#ifdef WPA_SM_Transtatus - case 0xFF: - memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); - wpa_Result.proto = 0; - wpa_Result.key_mgmt = 0; - wpa_Result.eap_type = 0; - wpa_Result.authenticated = false; - pDevice->fWPA_Authened = false; - if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) { - result = -EFAULT; - break; - } - - if (wpa_Result.authenticated == true) { -#ifdef SndEvt_ToAPI - { - union iwreq_data wrqu; - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG; - wrqu.data.length = pItemSSID->len; - wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID); - } -#endif - pDevice->fWPA_Authened = true; /* is successful peer to wpa_Result.authenticated? */ - } - pReq->wResult = 0; - break; -#endif - default: pr_debug("Private command not support..\n"); } -- GitLab From 5ba1b07a6eae38886b7e27d662da2786d0613386 Mon Sep 17 00:00:00 2001 From: "Vladimir A. Nazarenko" Date: Thu, 9 Oct 2014 15:38:23 +1100 Subject: [PATCH 0499/9457] staging: vt6655: remove global variable wpa_Result This variable unused, so remove it. Signed-off-by: Vladimir A. Nazarenko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 8 -------- drivers/staging/vt6655/ioctl.c | 4 ---- 2 files changed, 12 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ed5e71237007..ff8bd7a5db87 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1553,9 +1553,6 @@ static int device_open(struct net_device *dev) { struct vnt_private *pDevice = netdev_priv(dev); int i; -#ifdef WPA_SM_Transtatus - extern SWPAResult wpa_Result; -#endif pDevice->rx_buf_sz = PKT_BUF_SZ; if (!device_init_rings(pDevice)) @@ -1567,11 +1564,6 @@ static int device_open(struct net_device *dev) return i; #ifdef WPA_SM_Transtatus - memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname)); - wpa_Result.proto = 0; - wpa_Result.key_mgmt = 0; - wpa_Result.eap_type = 0; - wpa_Result.authenticated = false; pDevice->fWPA_Authened = false; #endif pr_debug("call device init rd0 ring\n"); diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index f8e990fcc6fd..628f5b2359c5 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -38,10 +38,6 @@ #include "wpactl.h" #include "rf.h" -#ifdef WPA_SM_Transtatus -SWPAResult wpa_Result; -#endif - int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) { PSCmdRequest pReq = (PSCmdRequest)rq; -- GitLab From ebf72ccf53f0fd494c41e856f255d09bc19d2ff4 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 9 Oct 2014 13:40:11 +0900 Subject: [PATCH 0500/9457] staging: dgap: introduce dgap_stop() The dgap_init_module() need to unwind for cleanup variables properly. Because dgap_init_module() calls dgap_cleanup_module() for freeing variables but this function is possible to free variables which are not allocated. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index d0eb5ea43965..ad8c8ecaaf06 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -71,6 +71,7 @@ MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product lin MODULE_SUPPORTED_DEVICE("dgap"); static int dgap_start(void); +static void dgap_stop(void); static void dgap_init_globals(void); static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, int boardnum); @@ -479,19 +480,20 @@ static int dgap_init_module(void) rc = pci_register_driver(&dgap_driver); if (rc) - goto err_cleanup; + goto err_stop; rc = dgap_create_driver_sysfiles(&dgap_driver); if (rc) - goto err_cleanup; + goto err_unregister; dgap_driver_state = DRIVER_READY; return 0; -err_cleanup: - - dgap_cleanup_module(); +err_unregister: + pci_unregister_driver(&dgap_driver); +err_stop: + dgap_stop(); return rc; } @@ -561,6 +563,21 @@ static int dgap_start(void) return rc; } +static void dgap_stop(void) +{ + unsigned long lock_flags; + + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); + + del_timer_sync(&dgap_poll_timer); + + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); +} + static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; -- GitLab From 402eede3c0b29949cb9c46fcbc2d476c5d266d76 Mon Sep 17 00:00:00 2001 From: "Vladimir A. Nazarenko" Date: Thu, 9 Oct 2014 16:33:33 +1100 Subject: [PATCH 0501/9457] staging: vt6655: remove useless #if 1 There is code encapsulated in #if 1, let's remove it. Signed-off-by: Vladimir A. Nazarenko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ---- drivers/staging/vt6655/wpactl.c | 3 --- 2 files changed, 7 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ff8bd7a5db87..6a77f0df1a63 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -854,8 +854,6 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) return -ENODEV; } -#if 1 - #ifdef DEBUG pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size); @@ -892,8 +890,6 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) } } } -#endif - #endif pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size); diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index dab1e8078652..cc39829cbacc 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -550,8 +550,6 @@ static int wpa_get_scan(struct vnt_private *pDevice, int ret = 0; u16 count = 0; u16 ii, jj; -#if 1 - unsigned char *ptempBSS; ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC); @@ -583,7 +581,6 @@ static int wpa_get_scan(struct vnt_private *pDevice, } kfree(ptempBSS); -#endif //******mike:bubble sort by stronger RSSI*****// -- GitLab From 02c2d43c2615ddc5d6e25f071b0f8d39ebc2d35d Mon Sep 17 00:00:00 2001 From: Dzmitry Sledneu Date: Thu, 9 Oct 2014 09:22:43 +0200 Subject: [PATCH 0502/9457] staging: gs_fpgaboot: Fix "out of memory" error handling Fix "out of memory" error handling Signed-off-by: Dzmitry Sledneu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index cbf70cefe6f5..0c18c4c311b4 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -295,8 +295,8 @@ static int gs_fpgaboot(void) struct fpgaimage *fimage; fimage = kmalloc(sizeof(struct fpgaimage), GFP_KERNEL); - if (fimage == NULL) - goto err_out; + if (!fimage) + return -ENOMEM; err = gs_load_image(fimage, file); if (err) { @@ -338,7 +338,6 @@ static int gs_fpgaboot(void) err_out1: kfree(fimage); -err_out: return -1; } -- GitLab From f582d9a8b95535d7728a0b9ea54afa1f59df3f68 Mon Sep 17 00:00:00 2001 From: Rene Kolarik Date: Thu, 9 Oct 2014 20:29:32 +0200 Subject: [PATCH 0503/9457] drivers: staging: imx-drm driver cleanup Wrapping two too long lines in two files of the imx-drm driver. Signed-off-by: Rene Kolarik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/imx-drm-core.c | 3 ++- drivers/staging/imx-drm/imx-tve.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 9cb222e2996f..3ca1acdae72b 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -632,7 +632,8 @@ static int imx_drm_platform_probe(struct platform_device *pdev) continue; } - component_match_add(&pdev->dev, &match, compare_of, remote); + component_match_add(&pdev->dev, &match, compare_of, + remote); of_node_put(remote); } of_node_put(port); diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 42c651be6c20..f22b2ac4627e 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -665,7 +665,8 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val); if (ret < 0) { - dev_err(dev, "failed to read configuration register: %d\n", ret); + dev_err(dev, "failed to read configuration register: %d\n", + ret); return ret; } if (val != 0x00100000) { -- GitLab From 3f8ddea02c1c8f42a7a88d5db8ebf045cb0e82fa Mon Sep 17 00:00:00 2001 From: John Ledbetter Date: Thu, 9 Oct 2014 11:05:08 -0400 Subject: [PATCH 0504/9457] staging: rtl8192e: Fix pointer type declaration style errors This fixes the following checkpatch.pl errors: drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c:1290 error: "foo* bar" should be "foo *bar" drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c:1305 error: "foo * bar" should be "foo *bar" Signed-off-by: John Ledbetter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 0ffed2d06b58..552d943b1761 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -1287,7 +1287,7 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, void rtl8192_tx_fill_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, - struct cb_desc *cb_desc, struct sk_buff* skb) + struct cb_desc *cb_desc, struct sk_buff *skb) { struct r8192_priv *priv = rtllib_priv(dev); dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, @@ -1302,7 +1302,7 @@ void rtl8192_tx_fill_cmd_desc(struct net_device *dev, if (cb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { entry->CmdInit = DESC_PACKET_TYPE_INIT; } else { - struct tx_desc * entry_tmp = (struct tx_desc *)entry; + struct tx_desc *entry_tmp = (struct tx_desc *)entry; entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL; entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; -- GitLab From 586e8b6845a9efdc2cfefc91e949a10806d2c623 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 10 Oct 2014 07:43:36 +0530 Subject: [PATCH 0505/9457] staging: vt6655: Remove unused code inside switch case This patch removes dead code in private_ioctl function and iwctl_siwmode function, in file ioctl.c. Inside switch, for a case no code gets executed after break. This was detected by smatch. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.c | 40 ---------------------------------- drivers/staging/vt6655/iwctl.c | 9 -------- 2 files changed, 49 deletions(-) diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 628f5b2359c5..c2b6763c8ab9 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -45,7 +45,6 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) int result = 0; PWLAN_IE_SSID pItemSSID; SCmdBSSJoin sJoinCmd; - SCmdZoneTypeSet sZoneTypeCmd; SCmdScan sScanCmd; SCmdStartAP sStartAPCmd; SCmdSetWEP sWEPCmd; @@ -108,45 +107,6 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) result = -EOPNOTSUPP; break; - if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) { - result = -EFAULT; - break; - } - - if (sZoneTypeCmd.bWrite == true) { - /* write zonetype */ - if (sZoneTypeCmd.ZoneType == ZoneType_USA) { - /* set to USA */ - pr_debug("set_ZoneType:USA\n"); - } else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) { - /* set to Japan */ - pr_debug("set_ZoneType:Japan\n"); - } else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) { - /* set to Europe */ - pr_debug("set_ZoneType:Europe\n"); - } - } else { - /* read zonetype */ - unsigned char zonetype = 0; - - if (zonetype == 0x00) { /* USA */ - sZoneTypeCmd.ZoneType = ZoneType_USA; - } else if (zonetype == 0x01) { /* Japan */ - sZoneTypeCmd.ZoneType = ZoneType_Japan; - } else if (zonetype == 0x02) { /* Europe */ - sZoneTypeCmd.ZoneType = ZoneType_Europe; - } else { /* Unknown ZoneType */ - pr_err("Error:ZoneType[%x] Unknown ???\n", zonetype); - result = -EFAULT; - break; - } - if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) { - result = -EFAULT; - break; - } - } - break; - case WLAN_CMD_BSS_JOIN: if (pDevice->bMACSuspend == true) { if (pDevice->bRadioOff == true) diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 8f3e190a55b9..cc261d7dd058 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -464,15 +464,6 @@ int iwctl_siwmode(struct net_device *dev, rc = -EOPNOTSUPP; break; - if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to Access Point\n"); - break; - case IW_MODE_REPEAT: pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; rc = -EOPNOTSUPP; -- GitLab From 4a2bc3bdfffcb31e7ba4d47358c0193d4fc259dc Mon Sep 17 00:00:00 2001 From: "Vladimir A. Nazarenko" Date: Fri, 10 Oct 2014 12:27:01 +1100 Subject: [PATCH 0506/9457] staging: vt6655: delete SndEvt_ToAPI code It's never enabled, so we can safely remove it. Signed-off-by: Vladimir A. Nazarenko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 6a77f0df1a63..c8f262f58c7b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2911,14 +2911,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case IOCTL_CMD_SET: -#ifdef SndEvt_ToAPI - if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) && - !(pDevice->flags & DEVICE_FLAGS_OPENED)) -#else - if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && - (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA)) -#endif - { + if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && + (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA)) { rc = -EFAULT; break; } -- GitLab From 30e89958bca3da4288cb47d59e439d06364e4bd0 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:24 +0200 Subject: [PATCH 0507/9457] staging: rtl8723au: Fix alignment of mac_addr for ether_addr_copy() usage Make sure struct eeprom_priv->mac_addr is 2 byte aligned to work with ether_addr_copy() Reported-by: Dan Carpenter Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/rtw_eeprom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/include/rtw_eeprom.h b/drivers/staging/rtl8723au/include/rtw_eeprom.h index e5121a2a64b4..a86f36e49dd1 100644 --- a/drivers/staging/rtl8723au/include/rtw_eeprom.h +++ b/drivers/staging/rtl8723au/include/rtw_eeprom.h @@ -107,12 +107,12 @@ enum rt_customer_id }; struct eeprom_priv { + u8 mac_addr[6]; /* PermanentAddress */ u8 bautoload_fail_flag; u8 bloadfile_fail_flag; u8 bloadmac_fail_flag; /* u8 bempty; */ /* u8 sys_config; */ - u8 mac_addr[6]; /* PermanentAddress */ /* u8 config0; */ u16 channel_plan; /* u8 country_string[3]; */ -- GitLab From 0f200704837fc110b8265efe97afa94ca1fa30c4 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:27 +0200 Subject: [PATCH 0508/9457] staging: rtl8723au: Remove write-only struct xmit_priv->vcs_type Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/rtw_xmit.h | 1 - drivers/staging/rtl8723au/os_dep/os_intfs.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 32a844170327..134ad6e50025 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -297,7 +297,6 @@ struct xmit_priv { u8 vcs_setting; u8 vcs; - u8 vcs_type; u64 tx_bytes; u64 tx_pkts; diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index b34eaec9dd48..19cb11bde2ce 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c @@ -389,7 +389,6 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) /* xmit_priv */ pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; pxmitpriv->vcs = pregistrypriv->vcs_type; - pxmitpriv->vcs_type = pregistrypriv->vcs_type; /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */ pxmitpriv->frag_len = pregistrypriv->frag_thresh; -- GitLab From 0ceb7b15e8b637d66574bb28d8422dc20933203f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:28 +0200 Subject: [PATCH 0509/9457] staging: rtl8723au: Use enum values for vcs_type Be consistent in the use of enum VCS_TYPE Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index 0126a3fa7fc9..c0325c96d616 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -829,7 +829,7 @@ void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->cts2self = 0; break; case 1: /* on */ - if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */ + if (pregpriv->vcs_type == RTS_CTS) { psta->rtsen = 1; psta->cts2self = 0; } else { @@ -840,7 +840,7 @@ void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta) case 2: /* auto */ default: if (pmlmeinfo->ERP_enable && pmlmeinfo->ERP_IE & BIT(1)) { - if (pregpriv->vcs_type == 1) { + if (pregpriv->vcs_type == RTS_CTS) { psta->rtsen = 1; psta->cts2self = 0; } else { -- GitLab From 70b88f5b36720acf8640c1807ab73bc851ccfd85 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:29 +0200 Subject: [PATCH 0510/9457] staging: rtl8723au: Eliminate write-once variable xmit_priv->vcs_setting Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_xmit.c | 2 +- drivers/staging/rtl8723au/include/rtw_xmit.h | 1 - drivers/staging/rtl8723au/os_dep/os_intfs.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c index 6c75794af82d..8994bd848af8 100644 --- a/drivers/staging/rtl8723au/core/rtw_xmit.c +++ b/drivers/staging/rtl8723au/core/rtw_xmit.c @@ -1295,7 +1295,7 @@ void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len) uint protection; const u8 *p; - switch (pxmitpriv->vcs_setting) { + switch (pregistrypriv->vrtl_carrier_sense) { case DISABLE_VCS: pxmitpriv->vcs = NONE_VCS; break; diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 134ad6e50025..70cd4b69d8f8 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -295,7 +295,6 @@ struct xmit_priv { struct rtw_adapter *adapter; - u8 vcs_setting; u8 vcs; u64 tx_bytes; diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index 19cb11bde2ce..ddd0a9f1eefb 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c @@ -387,7 +387,6 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) int ret = _SUCCESS; /* xmit_priv */ - pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; pxmitpriv->vcs = pregistrypriv->vcs_type; /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */ pxmitpriv->frag_len = pregistrypriv->frag_thresh; -- GitLab From b1950117408a6f38ce254ef3cca9399038188613 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:31 +0200 Subject: [PATCH 0511/9457] staging: rtl8723au: Use register define REQ_NQOS_SEQ instead of hardcoded value Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_sreset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_sreset.c b/drivers/staging/rtl8723au/core/rtw_sreset.c index 58ed980795a6..29a29d92a6ac 100644 --- a/drivers/staging/rtl8723au/core/rtw_sreset.c +++ b/drivers/staging/rtl8723au/core/rtw_sreset.c @@ -107,7 +107,7 @@ static void sreset_restore_network_station(struct rtw_adapter *padapter) mlmeext_joinbss_event_callback23a(padapter, 1); /* restore Sequence No. */ - rtl8723au_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn); + rtl8723au_write8(padapter, REG_NQOS_SEQ, padapter->xmitpriv.nqos_ssn); sreset_restore_security_station(padapter); } -- GitLab From 516f29e1c8013bfd66eb093cc97ec5d7b7182e4f Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:32 +0200 Subject: [PATCH 0512/9457] staging: rtl8723au: Don't read REQ_NQOS_SEQ 16 bits and write back 8 bits This fixes a potential endian bug Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/hal/hal_com.c | 2 +- drivers/staging/rtl8723au/include/rtw_xmit.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c index bf919f6e4128..f906317579bc 100644 --- a/drivers/staging/rtl8723au/hal/hal_com.c +++ b/drivers/staging/rtl8723au/hal/hal_com.c @@ -727,7 +727,7 @@ void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter) rtl8723au_write8(padapter, REG_TXPAUSE, 0xff); /* keep sn */ - padapter->xmitpriv.nqos_ssn = rtl8723au_read16(padapter, REG_NQOS_SEQ); + padapter->xmitpriv.nqos_ssn = rtl8723au_read8(padapter, REG_NQOS_SEQ); if (pwrpriv->bkeepfwalive != true) { u32 v32; diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 70cd4b69d8f8..780ec0665f20 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -330,7 +330,7 @@ struct xmit_priv { struct list_head xmitextbuf_list; /* track buffers for cleanup */ uint free_xmit_extbuf_cnt; - u16 nqos_ssn; + u8 nqos_ssn; int ack_tx; struct mutex ack_tx_mutex; struct submit_ctx ack_tx_ops; -- GitLab From f7d6e7c77022569712dfdb59b170870c8d624702 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:33 +0200 Subject: [PATCH 0513/9457] staging: rtl8723au: Re-organize struct xmit_priv for better packing Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/rtw_xmit.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 780ec0665f20..4318f50d6df7 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -295,8 +295,6 @@ struct xmit_priv { struct rtw_adapter *adapter; - u8 vcs; - u64 tx_bytes; u64 tx_pkts; u64 tx_drop; @@ -305,6 +303,8 @@ struct xmit_priv { struct hw_xmit *hwxmits; u8 hwxmit_entry; + u8 vcs; + u8 nqos_ssn; u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength from * large to small. it's value is 0->vo, 1->vi, @@ -330,7 +330,6 @@ struct xmit_priv { struct list_head xmitextbuf_list; /* track buffers for cleanup */ uint free_xmit_extbuf_cnt; - u8 nqos_ssn; int ack_tx; struct mutex ack_tx_mutex; struct submit_ctx ack_tx_ops; -- GitLab From f8cfb86e890028fec730804d56e782781cfb0c1a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:35 +0200 Subject: [PATCH 0514/9457] staging: rtl8723au: Remove unused struct zero_bulkout_content Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/os_dep/usb_ops_linux.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c index a3349ac57bae..c333bef90efe 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c @@ -18,13 +18,6 @@ #include #include -struct zero_bulkout_context { - void *pbuf; - void *purb; - void *pirp; - void *padapter; -}; - void rtl8723au_read_port_cancel(struct rtw_adapter *padapter) { struct recv_buf *precvbuf; -- GitLab From 60b152ced8a86b267fdfadd67377b47cf18b0b75 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:36 +0200 Subject: [PATCH 0515/9457] staging: rtl8723au: Fold struct wlan_phy_info into struct wlan_bssid_ex Half the entries of struct wlan_phy_info weren't used and this makes the code a little cleaner Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 40 +++++++++---------- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 6 +-- .../staging/rtl8723au/include/wlan_bssdef.h | 10 +---- .../staging/rtl8723au/os_dep/ioctl_cfg80211.c | 3 +- 4 files changed, 26 insertions(+), 33 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 7b6a5a9dc9b4..92bf1e415a95 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -354,12 +354,12 @@ rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue) void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, struct rtw_adapter *padapter, bool update_ie) { - u8 ss_ori = dst->PhyInfo.SignalStrength; - u8 sq_ori = dst->PhyInfo.SignalQuality; + u8 ss_ori = dst->SignalStrength; + u8 sq_ori = dst->SignalQuality; long rssi_ori = dst->Rssi; - u8 ss_smp = src->PhyInfo.SignalStrength; - u8 sq_smp = src->PhyInfo.SignalQuality; + u8 ss_smp = src->SignalStrength; + u8 sq_smp = src->SignalQuality; long rssi_smp = src->Rssi; u8 ss_final; @@ -387,16 +387,16 @@ void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, rssi_final = rssi_ori; } else { if (sq_smp != 101) { /* from the right channel */ - ss_final = ((u32)src->PhyInfo.SignalStrength + - (u32)dst->PhyInfo.SignalStrength * 4) / 5; - sq_final = ((u32)src->PhyInfo.SignalQuality + - (u32)dst->PhyInfo.SignalQuality * 4) / 5; + ss_final = ((u32)src->SignalStrength + + (u32)dst->SignalStrength * 4) / 5; + sq_final = ((u32)src->SignalQuality + + (u32)dst->SignalQuality * 4) / 5; rssi_final = src->Rssi+dst->Rssi * 4 / 5; } else { /* bss info not receiving from the right channel, use the original RX signal infos */ - ss_final = dst->PhyInfo.SignalStrength; - sq_final = dst->PhyInfo.SignalQuality; + ss_final = dst->SignalStrength; + sq_final = dst->SignalQuality; rssi_final = dst->Rssi; } @@ -405,14 +405,13 @@ void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, if (update_ie) memcpy(dst, src, get_wlan_bssid_ex_sz(src)); - dst->PhyInfo.SignalStrength = ss_final; - dst->PhyInfo.SignalQuality = sq_final; + dst->SignalStrength = ss_final; + dst->SignalQuality = sq_final; dst->Rssi = rssi_final; DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, " "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress, - dst->PhyInfo.SignalStrength, - dst->PhyInfo.SignalQuality, dst->Rssi); + dst->SignalStrength, dst->SignalQuality, dst->Rssi); } static void update_current_network(struct rtw_adapter *adapter, @@ -489,8 +488,8 @@ static void rtw_update_scanned_network(struct rtw_adapter *adapter, pnetwork->join_res = 0; /* bss info not receiving from the right channel */ - if (pnetwork->network.PhyInfo.SignalQuality == 101) - pnetwork->network.PhyInfo.SignalQuality = 0; + if (pnetwork->network.SignalQuality == 101) + pnetwork->network.SignalQuality = 0; } else { /* * we have an entry and we are going to update it. But @@ -1026,15 +1025,14 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter, rtw_set_signal_stat_timer(&padapter->recvpriv); padapter->recvpriv.signal_strength = - ptarget_wlan->network.PhyInfo.SignalStrength; - padapter->recvpriv.signal_qual = - ptarget_wlan->network.PhyInfo.SignalQuality; + ptarget_wlan->network.SignalStrength; + padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality; /* * the ptarget_wlan->network.Rssi is raw data, we use - * ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) + * ptarget_wlan->network.SignalStrength instead (has scaled) */ padapter->recvpriv.rssi = translate_percentage_to_dbm( - ptarget_wlan->network.PhyInfo.SignalStrength); + ptarget_wlan->network.SignalStrength); DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u\n", __func__, padapter->recvpriv.signal_strength, padapter->recvpriv.rssi, padapter->recvpriv.signal_qual); diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 9298b382b6c6..0dd7d22eba28 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -4204,9 +4204,9 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, /* get the signal strength */ /* in dBM.raw data */ bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower; - bssid->PhyInfo.SignalQuality = + bssid->SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */ - bssid->PhyInfo.SignalStrength = + bssid->SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */ /* checking SSID */ @@ -4313,7 +4313,7 @@ static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter, /* mark bss info receiving from nearby channel as SignalQuality 101 */ if (bssid->DSConfig != rtw_get_oper_ch23a(padapter)) - bssid->PhyInfo.SignalQuality = 101; + bssid->SignalQuality = 101; return bssid; fail: diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h index 96e8074a7c18..037942c27d9b 100644 --- a/drivers/staging/rtl8723au/include/wlan_bssdef.h +++ b/drivers/staging/rtl8723au/include/wlan_bssdef.h @@ -67,13 +67,6 @@ struct ndis_802_11_key { u8 KeyMaterial[32]; /* variable length depending on above field */ }; -struct wlan_phy_info { - u8 SignalStrength;/* in percentage) */ - u8 SignalQuality;/* in percentage) */ - u8 Optimum_antenna; /* for Antenna diversity */ - u8 Reserved_0; -}; - struct wlan_bcn_info { /* these infor get from rtw_get_encrypt_info when * * translate scan to UI */ @@ -99,7 +92,8 @@ struct wlan_bssid_ex { u32 DSConfig; /* Frequency, units are kHz */ enum nl80211_iftype ifmode; unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; - struct wlan_phy_info PhyInfo; + u8 SignalStrength;/* in percentage */ + u8 SignalQuality;/* in percentage */ u32 IELength; u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and capability info*/ } __packed; diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index de2a3f546cfb..c567df6c6321 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -275,7 +275,8 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter, &pnetwork->network)) { notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */ } else { - notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */ + notify_signal = 100 * translate_percentage_to_dbm( + pnetwork->network.SignalStrength); /* dbm */ } bss = cfg80211_inform_bss(wiphy, notify_channel, -- GitLab From 218189b7dc847681516285a1af89b6fb0b17a061 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:37 +0200 Subject: [PATCH 0516/9457] staging: rtl8723au: Remove unused struct ndis_802_11_key Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/include/wlan_bssdef.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h index 037942c27d9b..8acc41840e32 100644 --- a/drivers/staging/rtl8723au/include/wlan_bssdef.h +++ b/drivers/staging/rtl8723au/include/wlan_bssdef.h @@ -57,16 +57,6 @@ enum { Ndis802_11Encryption3KeyAbsent, }; -/* Key mapping keys require a BSSID */ -struct ndis_802_11_key { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - u32 KeyLength; /* length of key in bytes */ - unsigned char BSSID[6]; - unsigned long long KeyRSC; - u8 KeyMaterial[32]; /* variable length depending on above field */ -}; - struct wlan_bcn_info { /* these infor get from rtw_get_encrypt_info when * * translate scan to UI */ -- GitLab From eb18cf6b23c007859a72d3ed425840d8f480ecfa Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:38 +0200 Subject: [PATCH 0517/9457] staging: rtl8723au: Eliminate write-only struct wlan_network->aid Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 3 --- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 2 +- drivers/staging/rtl8723au/include/wlan_bssdef.h | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 92bf1e415a95..21484e757b15 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -110,7 +110,6 @@ struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp) pnetwork->network_type = 0; pnetwork->fixed = false; pnetwork->last_scanned = jiffies; - pnetwork->aid = 0; pnetwork->join_res = 0; } @@ -484,7 +483,6 @@ static void rtw_update_scanned_network(struct rtw_adapter *adapter, pnetwork->last_scanned = jiffies; pnetwork->network_type = 0; - pnetwork->aid = 0; pnetwork->join_res = 0; /* bss info not receiving from the right channel */ @@ -1021,7 +1019,6 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter, cur_network->network.beacon_interval = ptarget_wlan->network.beacon_interval; cur_network->network.tsf = ptarget_wlan->network.tsf; - cur_network->aid = pnetwork->join_res; rtw_set_signal_stat_timer(&padapter->recvpriv); padapter->recvpriv.signal_strength = diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 0dd7d22eba28..e4f4934e357d 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -4875,7 +4875,7 @@ void report_join_res23a(struct rtw_adapter *padapter, int res) pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); memcpy((unsigned char *)&pjoinbss_evt->network.network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex)); - pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; + pjoinbss_evt->network.join_res = res; DBG_8723A("report_join_res23a(%d)\n", res); diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h index 8acc41840e32..95b32e15a4d0 100644 --- a/drivers/staging/rtl8723au/include/wlan_bssdef.h +++ b/drivers/staging/rtl8723au/include/wlan_bssdef.h @@ -99,7 +99,6 @@ struct wlan_network { /* set to fixed when not to be removed as site-surveying */ int fixed; unsigned long last_scanned; /* timestamp for the network */ - int aid; /* will only be valid when a BSS is joined. */ int join_res; struct wlan_bssid_ex network; /* must be the last item */ struct wlan_bcn_info BcnInfo; -- GitLab From ab3136cc876ac5c109cfe28d05f8c1247a899d39 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:34 +0200 Subject: [PATCH 0518/9457] staging: rtl8723au: Remove a stack of write only counters We don't do anything with these, so get rid of them Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_xmit.c | 6 ------ drivers/staging/rtl8723au/include/rtw_xmit.h | 5 ----- drivers/staging/rtl8723au/os_dep/usb_ops_linux.c | 16 ---------------- 3 files changed, 27 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c index 8994bd848af8..4c2f0a1201bf 100644 --- a/drivers/staging/rtl8723au/core/rtw_xmit.c +++ b/drivers/staging/rtl8723au/core/rtw_xmit.c @@ -184,12 +184,6 @@ int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv, sema_init(&pxmitpriv->tx_retevt, 0); - /* per AC pending irp */ - pxmitpriv->beq_cnt = 0; - pxmitpriv->bkq_cnt = 0; - pxmitpriv->viq_cnt = 0; - pxmitpriv->voq_cnt = 0; - pxmitpriv->ack_tx = false; mutex_init(&pxmitpriv->ack_tx_mutex); rtw_sctx_init23a(&pxmitpriv->ack_tx_ops, 0); diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index 4318f50d6df7..abe4316b9124 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -315,11 +315,6 @@ struct xmit_priv { u8 txirp_cnt;/* */ struct tasklet_struct xmit_tasklet; - /* per AC pending irp */ - int beq_cnt; - int bkq_cnt; - int viq_cnt; - int voq_cnt; struct rtw_queue free_xmitbuf_queue; struct list_head xmitbuf_list; /* track buffers for cleanup */ diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c index c333bef90efe..3e19b3b2c1c2 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c @@ -46,18 +46,6 @@ static void usb_write_port23a_complete(struct urb *purb) unsigned long irqL; switch (pxmitbuf->flags) { - case VO_QUEUE_INX: - pxmitpriv->voq_cnt--; - break; - case VI_QUEUE_INX: - pxmitpriv->viq_cnt--; - break; - case BE_QUEUE_INX: - pxmitpriv->beq_cnt--; - break; - case BK_QUEUE_INX: - pxmitpriv->bkq_cnt--; - break; case HIGH_QUEUE_INX: #ifdef CONFIG_8723AU_AP_MODE rtw_chk_hi_queue_cmd23a(padapter); @@ -159,19 +147,15 @@ int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt, switch (addr) { case VO_QUEUE_INX: - pxmitpriv->voq_cnt++; pxmitbuf->flags = VO_QUEUE_INX; break; case VI_QUEUE_INX: - pxmitpriv->viq_cnt++; pxmitbuf->flags = VI_QUEUE_INX; break; case BE_QUEUE_INX: - pxmitpriv->beq_cnt++; pxmitbuf->flags = BE_QUEUE_INX; break; case BK_QUEUE_INX: - pxmitpriv->bkq_cnt++; pxmitbuf->flags = BK_QUEUE_INX; break; case HIGH_QUEUE_INX: -- GitLab From e1499e81497cd46f296c4680096323f0aadd2604 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 11 Oct 2014 02:25:34 +0200 Subject: [PATCH 0519/9457] staging: vt6655: card.c: replace memcpy() by ether_addr_copy() using coccinelle This patch focuses on fixing the following warning generated by checkpatch.pl for the file rxtx.c : Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2) The changes were applied using the following coccinelle rule: @@ expression e1, e2; @@ - memcpy(e1, e2, ETH_ALEN); + ether_addr_copy(e1, e2); According to ether_addr_copy() description and functionality, all Ethernet addresses should align to the u16 datatype. Here is the output of pahole for the relevant datastructures: struct pmkid_candidate { NDIS_802_11_MAC_ADDRESS BSSID; /* 0 6 */ /* XXX 2 bytes hole, try to pack */ long unsigned int Flags; /* 8 4 */ /* size: 12, cachelines: 1, members: 2 */ /* sum members: 10, holes: 1, sum holes: 2 */ /* last cacheline: 12 bytes */ }; Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 5a6950264bdc..f2a33a9742c6 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1000,7 +1000,7 @@ CARDbAdd_PMKID_Candidate( else pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); + ether_addr_copy(pCandidateList->BSSID, pbyBSSID); pDevice->gsPMKIDCandidate.NumCandidates++; pr_debug("NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); -- GitLab From 87bb326eada535ed72ca312878bb5ba69bad870b Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 11 Oct 2014 02:34:07 +0200 Subject: [PATCH 0520/9457] staging: vt6655: dpc.c: replace memcpy() by ether_addr_copy() using coccinelle This patch focuses on fixing the following warning generated by checkpatch.pl for the file dpc.c : Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2) The changes were applied using the following coccinelle rule: @@ expression e1, e2; @@ - memcpy(e1, e2, ETH_ALEN); + ether_addr_copy(e1, e2); According to ether_addr_copy() description and functionality, all Ethernet addresses should align to the u16 datatype. Here is the output of pahole for the relevant datastructures: struct tagS802_11Header { short unsigned int wFrameCtl; /* 0 2 */ short unsigned int wDurationID; /* 2 2 */ unsigned char abyAddr1[6]; /* 4 6 */ unsigned char abyAddr2[6]; /* 10 6 */ unsigned char abyAddr3[6]; /* 16 6 */ short unsigned int wSeqCtl; /* 22 2 */ unsigned char abyAddr4[6]; /* 24 6 */ /* size: 30, cachelines: 1, members: 7 */ /* last cacheline: 30 bytes */ }; struct iw_michaelmicfailure { __u32 flags; /* 0 4 */ struct sockaddr src_addr; /* 4 16 */ __u8 tsc[8]; /* 20 8 */ /* size: 28, cachelines: 1, members: 3 */ /* last cacheline: 28 bytes */ }; struct sockaddr { sa_family_t sa_family; /* 0 2 */ char sa_data[14]; /* 2 14 */ /* size: 16, cachelines: 1, members: 2 */ /* last cacheline: 16 bytes */ }; There is one thing to note though, sa_data is a char array of size 14. And the number of bytes copied using memcpy() or ether_addr_copy() is 6. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 8515b8c80801..344e12f1184e 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -742,7 +742,8 @@ device_receive_frame( } ev.src_addr.sa_family = ARPHRD_ETHER; - memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN); + ether_addr_copy(ev.src_addr.sa_data, + pMACHeader->abyAddr2); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = sizeof(ev); wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); -- GitLab From 85061eb97aac1f7848a57bb5a6a6754c0f0489a0 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 11 Oct 2014 02:37:21 +0200 Subject: [PATCH 0521/9457] staging: vt6655: wmgr.c and wmgr.h: replace memcpy() by ether_addr_copy() using coccinelle and pack variable This patch focuses on fixing the following warning generated by checkpatch.pl for the file wmgr.c : Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2) The changes were applied using the following coccinelle rule: @@ expression e1, e2; @@ - memcpy(e1, e2, ETH_ALEN); + ether_addr_copy(e1, e2); According to ether_addr_copy() description and functionality, all Ethernet addresses should align to the u16 datatype. To maintain that the array abyCurrBSSID in tagSMgmtObject is aligned, it was placed after the int uCurrChannel in the struct definition. This was done in wmgr.h Here is the output of pahole for the relevant datastructures: struct sockaddr { sa_family_t sa_family; /* 0 2 */ char sa_data[14]; /* 2 14 */ /* size: 16, cachelines: 1, members: 2 */ /* last cacheline: 16 bytes */ }; struct tagSMgmtObject { void * pAdapter; /* 0 4 */ unsigned char abyMACAddr[6]; /* 4 6 */ /* XXX 2 bytes hole, try to pack */ WMAC_CONFIG_MODE eConfigMode; /* 12 4 */ CARD_PHY_TYPE eCurrentPHYMode; /* 16 4 */ CARD_PHY_TYPE eConfigPHYMode; /* 20 4 */ WMAC_CURRENT_MODE eCurrMode; /* 24 4 */ WMAC_BSS_STATE eCurrState; /* 28 4 */ PKnownBSS pCurrBSS; /* 32 4 */ unsigned char byCSSGK; /* 36 1 */ unsigned char byCSSPK; /* 37 1 */ /* XXX 2 bytes hole, try to pack */ unsigned int uCurrChannel; /* 40 4 */ unsigned char abyCurrBSSID[6]; /* 44 6 */ unsigned char abyCurrSuppRates[19]; /* 50 19 */ /* --- cacheline 1 boundary (64 bytes) was 5 bytes ago --- */ unsigned char abyCurrExtSuppRates[19]; /* 69 19 */ unsigned char abyCurrSSID[35]; /* 88 35 */ /* XXX 1 byte hole, try to pack */ short unsigned int wCurrCapInfo; /* 124 2 */ short unsigned int wCurrAID; /* 126 2 */ /* --- cacheline 2 boundary (128 bytes) --- */ short unsigned int wCurrATIMWindow; /* 128 2 */ short unsigned int wCurrBeaconPeriod; /* 130 2 */ bool bIsDS; /* 132 1 */ unsigned char byERPContext; /* 133 1 */ /* XXX 2 bytes hole, try to pack */ CMD_STATE eCommandState; /* 136 4 */ unsigned int uScanChannel; /* 140 4 */ unsigned char abyDesireSSID[35]; /* 144 35 */ unsigned char abyDesireBSSID[6]; /* 179 6 */ /* XXX 1 byte hole, try to pack */ short unsigned int wIBSSBeaconPeriod; /* 186 2 */ short unsigned int wIBSSATIMWindow; /* 188 2 */ /* XXX 2 bytes hole, try to pack */ /* --- cacheline 3 boundary (192 bytes) --- */ unsigned int uIBSSChannel; /* 192 4 */ unsigned char abyIBSSSuppRates[19]; /* 196 19 */ unsigned char byAPBBType; /* 215 1 */ unsigned char abyWPAIE[64]; /* 216 64 */ /* --- cacheline 4 boundary (256 bytes) was 24 bytes ago --- */ short unsigned int wWPAIELen; /* 280 2 */ /* XXX 2 bytes hole, try to pack */ unsigned int uAssocCount; /* 284 4 */ bool bMoreData; /* 288 1 */ /* XXX 3 bytes hole, try to pack */ WMAC_SCAN_STATE eScanState; /* 292 4 */ WMAC_SCAN_TYPE eScanType; /* 296 4 */ unsigned int uScanStartCh; /* 300 4 */ unsigned int uScanEndCh; /* 304 4 */ short unsigned int wScanSteps; /* 308 2 */ /* XXX 2 bytes hole, try to pack */ unsigned int uScanBSSType; /* 312 4 */ unsigned char abyScanSSID[35]; /* 316 35 */ /* --- cacheline 5 boundary (320 bytes) was 31 bytes ago --- */ unsigned char abyScanBSSID[6]; /* 351 6 */ /* XXX 3 bytes hole, try to pack */ WMAC_AUTHENTICATION_MODE eAuthenMode; /* 360 4 */ WMAC_ENCRYPTION_MODE eEncryptionMode; /* 364 4 */ bool bShareKeyAlgorithm; /* 368 1 */ unsigned char abyChallenge[128]; /* 369 128 */ /* --- cacheline 7 boundary (448 bytes) was 49 bytes ago --- */ bool bPrivacyInvoked; /* 497 1 */ bool bInTIM; /* 498 1 */ bool bMulticastTIM; /* 499 1 */ unsigned char byDTIMCount; /* 500 1 */ unsigned char byDTIMPeriod; /* 501 1 */ /* XXX 2 bytes hole, try to pack */ WMAC_POWER_MODE ePSMode; /* 504 4 */ short unsigned int wListenInterval; /* 508 2 */ short unsigned int wCountToWakeUp; /* 510 2 */ /* --- cacheline 8 boundary (512 bytes) --- */ bool bInTIMWake; /* 512 1 */ /* XXX 3 bytes hole, try to pack */ unsigned char * pbyPSPacketPool; /* 516 4 */ unsigned char byPSPacketPool[36]; /* 520 36 */ bool bRxBeaconInTBTTWake; /* 556 1 */ unsigned char abyPSTxMap[65]; /* 557 65 */ /* XXX 2 bytes hole, try to pack */ /* --- cacheline 9 boundary (576 bytes) was 48 bytes ago --- */ unsigned int uCmdBusy; /* 624 4 */ unsigned int uCmdHostAPBusy; /* 628 4 */ unsigned char * pbyMgmtPacketPool; /* 632 4 */ unsigned char byMgmtPacketPool[2352]; /* 636 2352 */ /* --- cacheline 46 boundary (2944 bytes) was 44 bytes ago --- */ struct timer_list sTimerSecondCallback; /* 2988 52 */ /* --- cacheline 47 boundary (3008 bytes) was 32 bytes ago --- */ SRxMgmtPacket sRxPacket; /* 3040 28 */ KnownBSS sBSSList[42]; /* 3068 57288 */ /* --- cacheline 943 boundary (60352 bytes) was 4 bytes ago --- */ KnownNodeDB sNodeDBTable[65]; /* 60356 20800 */ /* --- cacheline 1268 boundary (81152 bytes) was 4 bytes ago --- */ /* Bitfield combined with previous fields */ SPMKIDCache gsPMKIDCache; /* 0 356 */ bool bRoaming; /* 0 1 */ SAssocInfo sAssocInfo; /* 0 7064 */ bool b11hEnable; /* 0 1 */ bool bSwitchChannel; /* 0 1 */ unsigned char byNewChannel; /* 0 1 */ PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; /* 0 4 */ unsigned int uLengthOfRepEIDs; /* 0 4 */ unsigned char abyCurrentMSRReq[2352]; /* 0 2352 */ unsigned char abyCurrentMSRRep[2352]; /* 0 2352 */ unsigned char abyIECountry[2340]; /* 0 2340 */ unsigned char abyIBSSDFSOwner[6]; /* 0 6 */ unsigned char byIBSSDFSRecovery; /* 0 1 */ struct sk_buff skb; /* 0 192 */ /* XXX last struct has 4 bytes of padding */ /* --- cacheline 1497 boundary (95808 bytes) was 32 bytes ago --- */ /* size: 95840, cachelines: 1498, members: 81 */ /* sum members: 95813, holes: 13, sum holes: 27 */ /* padding: 30112 */ /* paddings: 1, sum paddings: 4 */ /* last cacheline: 32 bytes */ /* BRAIN FART ALERT! 95840 != 95813 + 27(holes), diff = 0 */ }; struct pmkid_candidate { NDIS_802_11_MAC_ADDRESS BSSID; /* 0 6 */ /* XXX 2 bytes hole, try to pack */ long unsigned int Flags; /* 8 4 */ /* size: 12, cachelines: 1, members: 2 */ /* sum members: 10, holes: 1, sum holes: 2 */ /* last cacheline: 12 bytes */ }; Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wmgr.c | 5 +++-- drivers/staging/vt6655/wmgr.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index c73c39d7adfd..a1bada1173f3 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -1022,7 +1022,8 @@ s_vMgrRxAssocResponse( } memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN); + ether_addr_copy(wrqu.ap_addr.sa_data, + &pMgmt->abyCurrBSSID[0]); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } @@ -4419,7 +4420,7 @@ bAdd_PMKID_Candidate( else pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); + ether_addr_copy(pCandidateList->BSSID, pbyBSSID); pDevice->gsPMKIDCandidate.NumCandidates++; pr_debug("NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index ce939b30ac2a..a00652bfec4e 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -204,10 +204,10 @@ typedef struct tagSMgmtObject { // Current state vars unsigned int uCurrChannel; + unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; unsigned short wCurrCapInfo; unsigned short wCurrAID; unsigned short wCurrATIMWindow; -- GitLab From 2359b5c2d950a101af883e51bdbffc1bf83325c4 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 11 Oct 2014 02:42:45 +0200 Subject: [PATCH 0522/9457] staging: vt6655: replace memcpy() by ether_addr_copy() using coccinelle and pack variables This patch focuses on fixing the following warning generated by checkpatch.pl for the file rxtx.c : Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2) The changes were applied using the following coccinelle rule: @@ expression e1, e2; @@ - memcpy(e1, e2, ETH_ALEN); + ether_addr_copy(e1, e2); After applying the rule, some referencing operations were adjusted manually to avoid a gcc compilation warning. According to ether_addr_copy() description and functionality, all Ethernet addresses should align to the u16 datatype. A check was made on the following datastructures: - vnt_mic_hdr - tagS802_11Header - tagSEthernetHeader - vnt_rts_g - ieee80211_rts - vnt_private To maintain that the array abyCurrentNetAddr in vnt_private is aligned, it was placed before the boolean bLinkPass in the struct definition. The definition can be found in device.h. A couple of variables were packed in holes detected by pahole. Output of pahole when running it on rxtx.o after the changes: truct tagSEthernetHeader { unsigned char abyDstAddr[6]; /* 0 6 */ unsigned char abySrcAddr[6]; /* 6 6 */ short unsigned int wType; /* 12 2 */ /* size: 14, cachelines: 1, members: 3 */ /* last cacheline: 14 bytes */ }; struct tagS802_11Header { short unsigned int wFrameCtl; /* 0 2 */ short unsigned int wDurationID; /* 2 2 */ unsigned char abyAddr1[6]; /* 4 6 */ unsigned char abyAddr2[6]; /* 10 6 */ unsigned char abyAddr3[6]; /* 16 6 */ short unsigned int wSeqCtl; /* 22 2 */ unsigned char abyAddr4[6]; /* 24 6 */ /* size: 30, cachelines: 1, members: 7 */ /* last cacheline: 30 bytes */ }; struct ieee80211_rts { __le16 frame_control; /* 0 2 */ __le16 duration; /* 2 2 */ u8 ra[6]; /* 4 6 */ u8 ta[6]; /* 10 6 */ /* size: 16, cachelines: 1, members: 4 */ /* last cacheline: 16 bytes */ }; struct vnt_private { struct pci_dev * pcid; /* 0 4 */ struct net_device * dev; /* 4 4 */ dma_addr_t pool_dma; /* 8 4 */ dma_addr_t rd0_pool_dma; /* 12 4 */ dma_addr_t rd1_pool_dma; /* 16 4 */ dma_addr_t td0_pool_dma; /* 20 4 */ dma_addr_t td1_pool_dma; /* 24 4 */ dma_addr_t tx_bufs_dma0; /* 28 4 */ dma_addr_t tx_bufs_dma1; /* 32 4 */ dma_addr_t tx_beacon_dma; /* 36 4 */ unsigned char * tx0_bufs; /* 40 4 */ unsigned char * tx1_bufs; /* 44 4 */ unsigned char * tx_beacon_bufs; /* 48 4 */ CHIP_TYPE chip_id; /* 52 4 */ void * PortOffset; /* 56 4 */ long unsigned int dwIsr; /* 60 4 */ /*--- cacheline 1 boundary (64 bytes) ---*/ u32 memaddr; /* 64 4 */ u32 ioaddr; /* 68 4 */ u32 io_size; /* 72 4 */ unsigned char byRevId; /* 76 1 */ unsigned char byRxMode; /* 77 1 */ short unsigned int SubSystemID; /* 78 2 */ short unsigned int SubVendorID; /* 80 2 */ spinlock_t lock; /* 82 2 */ int nTxQueues; /* 84 4 */ volatile int iTDUsed; /* 88 8 */ volatile PSTxDesc apCurrTD; /* 96 8 */ volatile PSTxDesc apTailTD; /* 104 8 */ volatile PSTxDesc apTD0Rings; /* 112 4 */ volatile PSTxDesc apTD1Rings; /* 116 4 */ volatile PSRxDesc aRD0Ring; /* 120 4 */ volatile PSRxDesc aRD1Ring; /* 124 4 */ /*--- cacheline 2 boundary (128 bytes) ---*/ volatile PSRxDesc pCurrRD; /* 128 8 */ SCache sDupRxCache; /* 136 44 */ SDeFragControlBlock sRxDFCB[64]; /* 180 2048 */ /*--- cacheline 34 boundary (2176 bytes) was 52 bytes ago ---*/ unsigned int cbDFCB; /* 2228 4 */ unsigned int cbFreeDFCB; /* 2232 4 */ unsigned int uCurrentDFCBIdx; /* 2236 4 */ /*--- cacheline 35 boundary (2240 bytes) ---*/ OPTIONS sOpts; /* 2240 52 */ u32 flags; /* 2292 4 */ u32 rx_buf_sz; /* 2296 4 */ int multicast_limit; /* 2300 4 */ /*--- cacheline 36 boundary (2304 bytes) ---*/ pid_t MLMEThr_pid; /* 2304 4 */ struct completion notify; /* 2308 16 */ struct semaphore mlme_semaphore; /* 2324 16 */ u32 rx_bytes; /* 2340 4 */ unsigned char byLocalID; /* 2344 1 */ unsigned char byRFType; /* 2345 1 */ unsigned char byMaxPwrLevel; /* 2346 1 */ unsigned char byZoneType; /* 2347 1 */ bool bZoneRegExist; /* 2348 1 */ unsigned char byOriginalZonetype; /* 2349 1 */ unsigned char abyMacContext[384]; /* 2350 384 */ /*--- cacheline 42 boundary (2688 bytes) was 46 bytes ago ---*/ unsigned char abyCurrentNetAddr[6]; /* 2734 6 */ bool bLinkPass; /* 2740 1 */ /* XXX 3 bytes hole, try to pack */ SStatCounter scStatistic; /* 2744 776 */ /*--- cacheline 55 boundary (3520 bytes) ---*/ SDot11Counters s802_11Counter; /* 3520 172 */ /*--- cacheline 57 boundary (3648 bytes) was 44 bytes ago ---*/ PSMgmtObject pMgmt; /* 3692 4 */ SMgmtObject sMgmtObj; /* 3696 95840 */ /*--- cacheline 1555 boundary (99520 bytes) was 16 bytes ago ---*/ /* Bitfield combined with previous fields */ unsigned int uCurrRSSI; /* 0 4 */ unsigned char byCurrSQ; /* 0 1 */ long unsigned int dwTxAntennaSel; /* 0 4 */ long unsigned int dwRxAntennaSel; /* 0 4 */ unsigned char byAntennaCount; /* 0 1 */ unsigned char byRxAntennaMode; /* 0 1 */ unsigned char byTxAntennaMode; /* 0 1 */ bool bTxRxAntInv; /* 0 1 */ unsigned char * pbyTmpBuff; /* 0 4 */ unsigned int uSIFS; /* 0 4 */ unsigned int uDIFS; /* 0 4 */ unsigned int uEIFS; /* 0 4 */ unsigned int uSlot; /* 0 4 */ unsigned int uCwMin; /* 0 4 */ unsigned int uCwMax; /* 0 4 */ unsigned char bySIFS; /* 0 1 */ unsigned char byDIFS; /* 0 1 */ unsigned char byEIFS; /* 0 1 */ unsigned char bySlot; /* 0 1 */ unsigned char byCWMaxMin; /* 0 1 */ CARD_PHY_TYPE eCurrentPHYType; /* 0 4 */ VIA_BB_TYPE byBBType; /* 0 4 */ VIA_PKT_TYPE byPacketType; /* 0 4 */ short unsigned int wBasicRate; /* 0 2 */ unsigned char byACKRate; /* 0 1 */ unsigned char byTopOFDMBasicRate; /* 0 1 */ unsigned char byTopCCKBasicRate; /* 0 1 */ unsigned char byMinChannel; /* 0 1 */ unsigned char byMaxChannel; /* 0 1 */ unsigned int uConnectionRate; /* 0 4 */ unsigned char byPreambleType; /* 0 1 */ unsigned char byShortPreamble; /* 0 1 */ short unsigned int wCurrentRate; /* 0 2 */ short unsigned int wRTSThreshold; /* 0 2 */ short unsigned int wFragmentationThreshold; /* 0 2 */ unsigned char byShortRetryLimit; /* 0 1 */ unsigned char byLongRetryLimit; /* 0 1 */ enum nl80211_iftype op_mode; /* 0 4 */ unsigned char byOpMode; /* 0 1 */ bool bBSSIDFilter; /* 0 1 */ short unsigned int wMaxTransmitMSDULifetime; /* 0 2 */ unsigned char abyBSSID[6]; /* 0 6 */ unsigned char abyDesireBSSID[6]; /* 0 6 */ short unsigned int wACKDuration; /* 0 2 */ short unsigned int wRTSTransmitLen; /* 0 2 */ unsigned char byRTSServiceField; /* 0 1 */ unsigned char byRTSSignalField; /* 0 1 */ long unsigned int dwMaxReceiveLifetime; /* 0 4 */ bool bEncryptionEnable; /* 0 1 */ bool bLongHeader; /* 0 1 */ bool bShortSlotTime; /* 0 1 */ bool bProtectMode; /* 0 1 */ bool bNonERPPresent; /* 0 1 */ bool bBarkerPreambleMd; /* 0 1 */ unsigned char byERPFlag; /* 0 1 */ short unsigned int wUseProtectCntDown; /* 0 2 */ bool bRadioControlOff; /* 0 1 */ bool bRadioOff; /* 0 1 */ bool bEnablePSMode; /* 0 1 */ short unsigned int wListenInterval; /* 0 2 */ bool bPWBitOn; /* 0 1 */ WMAC_POWER_MODE ePSMode; /* 0 4 */ unsigned char byRadioCtl; /* 0 1 */ unsigned char byGPIO; /* 0 1 */ bool bHWRadioOff; /* 0 1 */ bool bPrvActive4RadioOFF; /* 0 1 */ bool bGPIOBlockRead; /* 0 1 */ short unsigned int wSeqCounter; /* 0 2 */ short unsigned int wBCNBufLen; /* 0 2 */ bool bBeaconBufReady; /* 0 1 */ bool bBeaconSent; /* 0 1 */ bool bIsBeaconBufReadySet; /* 0 1 */ unsigned int cbBeaconBufReadySetCnt; /* 0 4 */ bool bFixRate; /* 0 1 */ unsigned char byCurrentCh; /* 0 1 */ unsigned int uScanTime; /* 0 4 */ CMD_STATE eCommandState; /* 0 4 */ CMD_CODE eCommand; /* 0 4 */ bool bBeaconTx; /* 0 1 */ bool bStopBeacon; /* 0 1 */ bool bStopDataPkt; /* 0 1 */ bool bStopTx0Pkt; /* 0 1 */ unsigned int uAutoReConnectTime; /* 0 4 */ CMD_ITEM eCmdQueue[32]; /* 0 1408 */ unsigned int uCmdDequeueIdx; /* 0 4 */ unsigned int uCmdEnqueueIdx; /* 0 4 */ unsigned int cbFreeCmdQueue; /* 0 4 */ bool bCmdRunning; /* 0 1 */ bool bCmdClear; /* 0 1 */ bool bRoaming; /* 0 1 */ unsigned char abyIPAddr[4]; /* 0 4 */ long unsigned int ulTxPower; /* 0 4 */ NDIS_802_11_WEP_STATUS eEncryptionStatus; /* 0 4 */ bool bTransmitKey; /* 0 1 */ NDIS_802_11_WEP_STATUS eOldEncryptionStatus; /* 0 4 */ SKeyManagement sKey; /* 0 3784 */ long unsigned int dwIVCounter; /* 0 4 */ u64 qwPacketNumber; /* 0 8 */ unsigned int uCurrentWEPMode; /* 0 4 */ RC4Ext SBox; /* 0 264 */ unsigned char abyPRNG[35]; /* 0 35 */ unsigned char byKeyIndex; /* 0 1 */ unsigned int uKeyLength; /* 0 4 */ unsigned char abyKey[29]; /* 0 29 */ bool bAES; /* 0 1 */ unsigned char byCntMeasure; /* 0 1 */ unsigned int uAssocCount; /* 0 4 */ bool bMoreData; /* 0 1 */ bool bGrpAckPolicy; /* 0 1 */ bool bAssocInfoSet; /* 0 1 */ unsigned char byAutoFBCtrl; /* 0 1 */ bool bTxMICFail; /* 0 1 */ bool bRxMICFail; /* 0 1 */ unsigned int uRATEIdx; /* 0 4 */ bool bUpdateBBVGA; /* 0 1 */ unsigned int uBBVGADiffCount; /* 0 4 */ unsigned char byBBVGANew; /* 0 1 */ unsigned char byBBVGACurrent; /* 0 1 */ unsigned char abyBBVGA[4]; /* 0 4 */ long int ldBmThreshold[4]; /* 0 16 */ unsigned char byBBPreEDRSSI; /* 0 1 */ unsigned char byBBPreEDIndex; /* 0 1 */ bool bRadioCmd; /* 0 1 */ long unsigned int dwDiagRefCount; /* 0 4 */ unsigned char byFOETuning; /* 0 1 */ unsigned char byAutoPwrTunning; /* 0 1 */ short int sPSetPointCCK; /* 0 2 */ short int sPSetPointOFDMG; /* 0 2 */ short int sPSetPointOFDMA; /* 0 2 */ long int lPFormulaOffset; /* 0 4 */ short int sPThreshold; /* 0 2 */ char cAdjustStep; /* 0 1 */ char cMinTxAGC; /* 0 1 */ unsigned char byCCKPwr; /* 0 1 */ unsigned char byOFDMPwrG; /* 0 1 */ unsigned char byCurPwr; /* 0 1 */ char byCurPwrdBm; /* 0 1 */ unsigned char abyCCKPwrTbl[15]; /* 0 15 */ unsigned char abyOFDMPwrTbl[57]; /* 0 57 */ char abyCCKDefaultPwr[15]; /* 0 15 */ char abyOFDMDefaultPwr[57]; /* 0 57 */ char abyRegPwr[57]; /* 0 57 */ char abyLocalPwr[57]; /* 0 57 */ unsigned char byBBCR4d; /* 0 1 */ unsigned char byBBCRc9; /* 0 1 */ unsigned char byBBCR88; /* 0 1 */ unsigned char byBBCR09; /* 0 1 */ struct timer_list sTimerCommand; /* 0 52 */ struct timer_list sTimerTxData; /* 0 52 */ long unsigned int nTxDataTimeCout; /* 0 4 */ bool fTxDataInSleep; /* 0 1 */ bool IsTxDataTrigger; /* 0 1 */ bool fWPA_Authened; /* 0 1 */ unsigned char byReAssocCount; /* 0 1 */ unsigned char byLinkWaitCount; /* 0 1 */ unsigned char abyNodeName[17]; /* 0 17 */ bool bDiversityRegCtlON; /* 0 1 */ bool bDiversityEnable; /* 0 1 */ long unsigned int ulDiversityNValue; /* 0 4 */ long unsigned int ulDiversityMValue; /* 0 4 */ unsigned char byTMax; /* 0 1 */ unsigned char byTMax2; /* 0 1 */ unsigned char byTMax3; /* 0 1 */ long unsigned int ulSQ3TH; /* 0 4 */ long unsigned int uDiversityCnt; /* 0 4 */ unsigned char byAntennaState; /* 0 1 */ long unsigned int ulRatio_State0; /* 0 4 */ long unsigned int ulRatio_State1; /* 0 4 */ struct timer_list TimerSQ3Tmax1; /* 0 52 */ struct timer_list TimerSQ3Tmax2; /* 0 52 */ struct timer_list TimerSQ3Tmax3; /* 0 52 */ long unsigned int uNumSQ3[12]; /* 0 48 */ short unsigned int wAntDiversityMaxRate; /* 0 2 */ SEthernetHeader sTxEthHeader; /* 0 14 */ SEthernetHeader sRxEthHeader; /* 0 14 */ unsigned char abyBroadcastAddr[6]; /* 0 6 */ unsigned char abySNAP_RFC1042[6]; /* 0 6 */ unsigned char abySNAP_Bridgetunnel[6]; /* 0 6 */ unsigned char abyEEPROM[256]; /* 0 256 */ SPMKID gsPMKID; /* 0 360 */ SPMKIDCandidateEvent gsPMKIDCandidate; /* 0 72 */ bool b11hEnable; /* 0 1 */ unsigned char abyCountryCode[3]; /* 0 3 */ unsigned int uNumOfMeasureEIDs; /* 0 4 */ PWLAN_IE_MEASURE_REQ pCurrMeasureEID; /* 0 4 */ bool bMeasureInProgress; /* 0 1 */ unsigned char byOrgChannel; /* 0 1 */ unsigned char byOrgRCR; /* 0 1 */ long unsigned int dwOrgMAR0; /* 0 4 */ long unsigned int dwOrgMAR4; /* 0 4 */ unsigned char byBasicMap; /* 0 1 */ unsigned char byCCAFraction; /* 0 1 */ unsigned char abyRPIs[8]; /* 0 8 */ long unsigned int dwRPIs[8]; /* 0 32 */ bool bChannelSwitch; /* 0 1 */ unsigned char byNewChannel; /* 0 1 */ unsigned char byChannelSwitchCount; /* 0 1 */ bool bQuietEnable; /* 0 1 */ bool bEnableFirstQuiet; /* 0 1 */ unsigned char byQuietStartCount; /* 0 1 */ unsigned int uQuietEnqueue; /* 0 4 */ long unsigned int dwCurrentQuietEndTime; /* 0 4 */ SQuietControl sQuiet[8]; /* 0 96 */ bool bCountryInfo5G; /* 0 1 */ bool bCountryInfo24G; /* 0 1 */ short unsigned int wBeaconInterval; /* 0 2 */ struct net_device * wpadev; /* 0 4 */ bool bWPADEVUp; /* 0 1 */ struct sk_buff * skb; /* 0 4 */ unsigned int bwextcount; /* 0 4 */ bool bWPASuppWextEnabled; /* 0 1 */ bool bEnableHostapd; /* 0 1 */ bool bEnable8021x; /* 0 1 */ bool bEnableHostWEP; /* 0 1 */ struct net_device * apdev; /* 0 4 */ int (*tx_80211)(struct sk_buff *, struct net_device *); /* 0 4 */ unsigned int uChannel; /* 0 4 */ bool bMACSuspend; /* 0 1 */ struct iw_statistics wstats; /* 0 32 */ bool bCommit; /* 0 1 */ /*--- cacheline 1672 boundary (107008 bytes) ---*/ /* size: 107008, cachelines: 1672, members: 279 */ /* sum members: 107005, holes: 1, sum holes: 3 */ /* padding: 41471 */ /* BRAIN FART ALERT! 107008 != 107005 + 3(holes), diff = 0 */ }; struct vnt_mic_hdr { u8 id; /* 0 1 */ u8 tx_priority; /* 1 1 */ u8 mic_addr2[6]; /* 2 6 */ u8 ccmp_pn[6]; /* 8 6 */ __be16 payload_len; /* 14 2 */ __be16 hlen; /* 16 2 */ __le16 frame_control; /* 18 2 */ u8 addr1[6]; /* 20 6 */ u8 addr2[6]; /* 26 6 */ u8 addr3[6]; /* 32 6 */ __le16 seq_ctrl; /* 38 2 */ u8 addr4[6]; /* 40 6 */ u16 packing; /* 46 2 */ /* size: 48, cachelines: 1, members: 13 */ /* last cacheline: 48 bytes */ }; struct vnt_rts_g { struct vnt_phy_field b; /* 0 4 */ struct vnt_phy_field a; /* 4 4 */ __le16 duration_ba; /* 8 2 */ __le16 duration_aa; /* 10 2 */ __le16 duration_bb; /* 12 2 */ u16 reserved; /* 14 2 */ struct ieee80211_rts data; /* 16 16 */ /* size: 32, cachelines: 1, members: 7 */ /* last cacheline: 32 bytes */ }; Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 8 +-- drivers/staging/vt6655/rxtx.c | 113 +++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index ddd356aa7eaf..ab6be41d4964 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -356,9 +356,12 @@ struct vnt_private { u32 io_size; unsigned char byRevId; + unsigned char byRxMode; unsigned short SubSystemID; unsigned short SubVendorID; + spinlock_t lock; + int nTxQueues; volatile int iTDUsed[TYPE_MAXTD]; @@ -384,9 +387,6 @@ struct vnt_private { u32 rx_buf_sz; int multicast_limit; - unsigned char byRxMode; - - spinlock_t lock; pid_t MLMEThr_pid; struct completion notify; @@ -403,8 +403,8 @@ struct vnt_private { bool bZoneRegExist; unsigned char byOriginalZonetype; unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; - bool bLinkPass; // link status: OK or fail unsigned char abyCurrentNetAddr[ETH_ALEN]; + bool bLinkPass; // link status: OK or fail // Adapter statistics SStatCounter scStatistic; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 7a183f55e7eb..da7c0a8674b6 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -264,7 +264,7 @@ s_vFillTxKey( /* MICHDR0 */ mic_hdr->id = 0x59; mic_hdr->tx_priority = 0; - memcpy(mic_hdr->mic_addr2, pMACHeader->abyAddr2, ETH_ALEN); + ether_addr_copy(mic_hdr->mic_addr2, pMACHeader->abyAddr2); /* ccmp pn big endian order */ mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24); @@ -282,17 +282,17 @@ s_vFillTxKey( else mic_hdr->hlen = cpu_to_be16(22); - memcpy(mic_hdr->addr1, pMACHeader->abyAddr1, ETH_ALEN); - memcpy(mic_hdr->addr2, pMACHeader->abyAddr2, ETH_ALEN); + ether_addr_copy(mic_hdr->addr1, pMACHeader->abyAddr1); + ether_addr_copy(mic_hdr->addr2, pMACHeader->abyAddr2); /* MICHDR2 */ - memcpy(mic_hdr->addr3, pMACHeader->abyAddr3, ETH_ALEN); + ether_addr_copy(mic_hdr->addr3, pMACHeader->abyAddr3); mic_hdr->frame_control = cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f); mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf); if (pDevice->bLongHeader) - memcpy(mic_hdr->addr4, pMACHeader->abyAddr4, ETH_ALEN); + ether_addr_copy(mic_hdr->addr4, pMACHeader->abyAddr4); } } @@ -853,14 +853,18 @@ s_vFillRTSHead( if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + psEthHeader->abyDstAddr); } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyBSSID); } if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ta, + pDevice->abyBSSID); else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ta, + psEthHeader->abySrcAddr); } else { struct vnt_rts_g_fb *buf = pvRTS; @@ -917,15 +921,19 @@ s_vFillRTSHead( if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + psEthHeader->abyDstAddr); } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyBSSID); } if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ta, + pDevice->abyBSSID); else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ta, + psEthHeader->abySrcAddr); } // if (byFBOption == AUTO_FB_NONE) } else if (byPktType == PK_TYPE_11A) { @@ -950,15 +958,19 @@ s_vFillRTSHead( if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + psEthHeader->abyDstAddr); } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyBSSID); } if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ta, + pDevice->abyBSSID); else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ta, + psEthHeader->abySrcAddr); } else { struct vnt_rts_a_fb *buf = pvRTS; @@ -990,14 +1002,18 @@ s_vFillRTSHead( if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + psEthHeader->abyDstAddr); } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyBSSID); } if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ta, + pDevice->abyBSSID); else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ta, + psEthHeader->abySrcAddr); } } else if (byPktType == PK_TYPE_11B) { struct vnt_rts_ab *buf = pvRTS; @@ -1018,15 +1034,17 @@ s_vFillRTSHead( if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || (pDevice->op_mode == NL80211_IFTYPE_AP)) { - memcpy(&buf->data.ra, psEthHeader->abyDstAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + psEthHeader->abyDstAddr); } else { - memcpy(&buf->data.ra, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ra, pDevice->abyBSSID); } if (pDevice->op_mode == NL80211_IFTYPE_AP) - memcpy(&buf->data.ta, pDevice->abyBSSID, ETH_ALEN); + ether_addr_copy(buf->data.ta, pDevice->abyBSSID); else - memcpy(&buf->data.ta, psEthHeader->abySrcAddr, ETH_ALEN); + ether_addr_copy(buf->data.ta, + psEthHeader->abySrcAddr); } } @@ -1093,7 +1111,8 @@ s_vFillCTSHead( buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) struct vnt_cts *buf = pvCTS; /* Get SignalField, ServiceField & Length */ @@ -1116,7 +1135,8 @@ s_vFillCTSHead( IEEE80211_STYPE_CTS); buf->reserved2 = 0x0; - memcpy(&buf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN); + ether_addr_copy(buf->data.ra, + pDevice->abyCurrentNetAddr); } } } @@ -2105,19 +2125,28 @@ vGenerateMACHeader( pMACHeader->wFrameCtl = TYPE_802_11_DATA; if (pDevice->op_mode == NL80211_IFTYPE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + ether_addr_copy(&(pMACHeader->abyAddr1[0]), + &(psEthHeader->abyDstAddr[0])); + ether_addr_copy(&(pMACHeader->abyAddr2[0]), + &(pDevice->abyBSSID[0])); + ether_addr_copy(&(pMACHeader->abyAddr3[0]), + &(psEthHeader->abySrcAddr[0])); pMACHeader->wFrameCtl |= FC_FROMDS; } else { if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + ether_addr_copy(&(pMACHeader->abyAddr1[0]), + &(psEthHeader->abyDstAddr[0])); + ether_addr_copy(&(pMACHeader->abyAddr2[0]), + &(psEthHeader->abySrcAddr[0])); + ether_addr_copy(&(pMACHeader->abyAddr3[0]), + &(pDevice->abyBSSID[0])); } else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + ether_addr_copy(&(pMACHeader->abyAddr3[0]), + &(psEthHeader->abyDstAddr[0])); + ether_addr_copy(&(pMACHeader->abyAddr2[0]), + &(psEthHeader->abySrcAddr[0])); + ether_addr_copy(&(pMACHeader->abyAddr1[0]), + &(pDevice->abyBSSID[0])); pMACHeader->wFrameCtl |= FC_TODS; } } @@ -2311,8 +2340,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); + ether_addr_copy(&(sEthHeader.abyDstAddr[0]), + &(pPacket->p80211Header->sA3.abyAddr1[0])); + ether_addr_copy(&(sEthHeader.abySrcAddr[0]), + &(pPacket->p80211Header->sA3.abyAddr2[0])); //========================= // No Fragmentation //========================= @@ -2804,8 +2835,10 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, } memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); + ether_addr_copy(&(sEthHeader.abyDstAddr[0]), + &(p80211Header->sA3.abyAddr1[0])); + ether_addr_copy(&(sEthHeader.abySrcAddr[0]), + &(p80211Header->sA3.abyAddr2[0])); //========================= // No Fragmentation //========================= -- GitLab From d09e9b160fc18116942101743693f5535bc5136a Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Wed, 15 Oct 2014 15:53:27 -0700 Subject: [PATCH 0523/9457] staging: bcm: remove driver The Beceem WiMAX driver was barely function in its current state and was non-functional on 64 bit systems. Based on repeated statements from Greg KH that he wanted the driver removed, I am removing the driver. CC: Matthias Beyer CC: Kevin McKinney Signed-off-by: Jeff Kirsher Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 7 - drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/bcm/Adapter.h | 474 -- drivers/staging/bcm/Bcmchar.c | 2652 ---------- drivers/staging/bcm/Bcmnet.c | 240 - drivers/staging/bcm/CmHost.c | 2254 -------- drivers/staging/bcm/CmHost.h | 62 - drivers/staging/bcm/DDRInit.c | 1355 ----- drivers/staging/bcm/DDRInit.h | 9 - drivers/staging/bcm/Debug.h | 242 - drivers/staging/bcm/HandleControlPacket.c | 241 - drivers/staging/bcm/HostMIBSInterface.h | 192 - drivers/staging/bcm/IPv6Protocol.c | 476 -- drivers/staging/bcm/IPv6ProtocolHdr.h | 85 - drivers/staging/bcm/InterfaceAdapter.h | 79 - drivers/staging/bcm/InterfaceDld.c | 317 -- drivers/staging/bcm/InterfaceIdleMode.c | 274 - drivers/staging/bcm/InterfaceIdleMode.h | 15 - drivers/staging/bcm/InterfaceInit.c | 729 --- drivers/staging/bcm/InterfaceInit.h | 26 - drivers/staging/bcm/InterfaceIsr.c | 190 - drivers/staging/bcm/InterfaceIsr.h | 15 - drivers/staging/bcm/InterfaceMacros.h | 18 - drivers/staging/bcm/InterfaceMisc.c | 246 - drivers/staging/bcm/InterfaceMisc.h | 42 - drivers/staging/bcm/InterfaceRx.c | 289 - drivers/staging/bcm/InterfaceRx.h | 7 - drivers/staging/bcm/InterfaceTx.c | 213 - drivers/staging/bcm/InterfaceTx.h | 7 - drivers/staging/bcm/Ioctl.h | 226 - drivers/staging/bcm/Kconfig | 6 - drivers/staging/bcm/LeakyBucket.c | 363 -- drivers/staging/bcm/Macros.h | 352 -- drivers/staging/bcm/Makefile | 12 - drivers/staging/bcm/Misc.c | 1587 ------ drivers/staging/bcm/PHSDefines.h | 94 - drivers/staging/bcm/PHSModule.c | 1699 ------ drivers/staging/bcm/PHSModule.h | 59 - drivers/staging/bcm/Protocol.h | 128 - drivers/staging/bcm/Prototypes.h | 217 - drivers/staging/bcm/Qos.c | 1199 ----- drivers/staging/bcm/Queue.h | 29 - drivers/staging/bcm/TODO | 26 - drivers/staging/bcm/Transmit.c | 271 - drivers/staging/bcm/Typedefs.h | 47 - .../staging/bcm/cntrl_SignalingInterface.h | 311 -- drivers/staging/bcm/headers.h | 78 - drivers/staging/bcm/hostmibs.c | 164 - drivers/staging/bcm/led_control.c | 951 ---- drivers/staging/bcm/led_control.h | 84 - drivers/staging/bcm/nvm.c | 4661 ----------------- drivers/staging/bcm/nvm.h | 286 - drivers/staging/bcm/sort.c | 52 - drivers/staging/bcm/target_params.h | 57 - drivers/staging/bcm/vendorspecificextn.c | 145 - drivers/staging/bcm/vendorspecificextn.h | 18 - 57 files changed, 23881 deletions(-) delete mode 100644 drivers/staging/bcm/Adapter.h delete mode 100644 drivers/staging/bcm/Bcmchar.c delete mode 100644 drivers/staging/bcm/Bcmnet.c delete mode 100644 drivers/staging/bcm/CmHost.c delete mode 100644 drivers/staging/bcm/CmHost.h delete mode 100644 drivers/staging/bcm/DDRInit.c delete mode 100644 drivers/staging/bcm/DDRInit.h delete mode 100644 drivers/staging/bcm/Debug.h delete mode 100644 drivers/staging/bcm/HandleControlPacket.c delete mode 100644 drivers/staging/bcm/HostMIBSInterface.h delete mode 100644 drivers/staging/bcm/IPv6Protocol.c delete mode 100644 drivers/staging/bcm/IPv6ProtocolHdr.h delete mode 100644 drivers/staging/bcm/InterfaceAdapter.h delete mode 100644 drivers/staging/bcm/InterfaceDld.c delete mode 100644 drivers/staging/bcm/InterfaceIdleMode.c delete mode 100644 drivers/staging/bcm/InterfaceIdleMode.h delete mode 100644 drivers/staging/bcm/InterfaceInit.c delete mode 100644 drivers/staging/bcm/InterfaceInit.h delete mode 100644 drivers/staging/bcm/InterfaceIsr.c delete mode 100644 drivers/staging/bcm/InterfaceIsr.h delete mode 100644 drivers/staging/bcm/InterfaceMacros.h delete mode 100644 drivers/staging/bcm/InterfaceMisc.c delete mode 100644 drivers/staging/bcm/InterfaceMisc.h delete mode 100644 drivers/staging/bcm/InterfaceRx.c delete mode 100644 drivers/staging/bcm/InterfaceRx.h delete mode 100644 drivers/staging/bcm/InterfaceTx.c delete mode 100644 drivers/staging/bcm/InterfaceTx.h delete mode 100644 drivers/staging/bcm/Ioctl.h delete mode 100644 drivers/staging/bcm/Kconfig delete mode 100644 drivers/staging/bcm/LeakyBucket.c delete mode 100644 drivers/staging/bcm/Macros.h delete mode 100644 drivers/staging/bcm/Makefile delete mode 100644 drivers/staging/bcm/Misc.c delete mode 100644 drivers/staging/bcm/PHSDefines.h delete mode 100644 drivers/staging/bcm/PHSModule.c delete mode 100644 drivers/staging/bcm/PHSModule.h delete mode 100644 drivers/staging/bcm/Protocol.h delete mode 100644 drivers/staging/bcm/Prototypes.h delete mode 100644 drivers/staging/bcm/Qos.c delete mode 100644 drivers/staging/bcm/Queue.h delete mode 100644 drivers/staging/bcm/TODO delete mode 100644 drivers/staging/bcm/Transmit.c delete mode 100644 drivers/staging/bcm/Typedefs.h delete mode 100644 drivers/staging/bcm/cntrl_SignalingInterface.h delete mode 100644 drivers/staging/bcm/headers.h delete mode 100644 drivers/staging/bcm/hostmibs.c delete mode 100644 drivers/staging/bcm/led_control.c delete mode 100644 drivers/staging/bcm/led_control.h delete mode 100644 drivers/staging/bcm/nvm.c delete mode 100644 drivers/staging/bcm/nvm.h delete mode 100644 drivers/staging/bcm/sort.c delete mode 100644 drivers/staging/bcm/target_params.h delete mode 100644 drivers/staging/bcm/vendorspecificextn.c delete mode 100644 drivers/staging/bcm/vendorspecificextn.h diff --git a/MAINTAINERS b/MAINTAINERS index a20df9bf8ab0..d0dd1f35b81d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1883,13 +1883,6 @@ W: http://bcache.evilpiepirate.org S: Maintained: F: drivers/md/bcache/ -BECEEM BCS200/BCS220-3/BCSM250 WIMAX SUPPORT -M: Kevin McKinney -M: Matthias Beyer -L: devel@driverdev.osuosl.org -S: Maintained -F: drivers/staging/bcm* - BEFS FILE SYSTEM S: Orphan F: Documentation/filesystems/befs.txt diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 80ad2078eea2..3b01fef54a35 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -62,8 +62,6 @@ source "drivers/staging/xgifb/Kconfig" source "drivers/staging/emxx_udc/Kconfig" -source "drivers/staging/bcm/Kconfig" - source "drivers/staging/ft1000/Kconfig" source "drivers/staging/speakup/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 17aa2231e208..26ecead09901 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ -obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h deleted file mode 100644 index 940c852e17b7..000000000000 --- a/drivers/staging/bcm/Adapter.h +++ /dev/null @@ -1,474 +0,0 @@ -/*********************************** -* Adapter.h -************************************/ -#ifndef __ADAPTER_H__ -#define __ADAPTER_H__ - -#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 -#include "Debug.h" - -struct bcm_leader { - USHORT Vcid; - USHORT PLength; - UCHAR Status; - UCHAR Unused[3]; -} __packed; - -struct bcm_packettosend { - struct bcm_leader Leader; - UCHAR ucPayload; -} __packed; - -struct bcm_control_packet { - PVOID ControlBuff; - UINT ControlBuffLen; - struct bcm_control_packet *next; -} __packed; - -struct bcm_link_request { - struct bcm_leader Leader; - UCHAR szData[4]; -} __packed; - -#define MAX_IP_RANGE_LENGTH 4 -#define MAX_PORT_RANGE 4 -#define MAX_PROTOCOL_LENGTH 32 -#define IPV6_ADDRESS_SIZEINBYTES 0x10 - -union u_ip_address { - struct { - /* Source Ip Address Range */ - ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH]; - /* Source Ip Mask Address Range */ - ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH]; - }; - struct { - /* Source Ip Address Range */ - ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4]; - /* Source Ip Mask Address Range */ - ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4]; - }; - struct { - UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; - UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; - }; - struct { - UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; - UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; - }; -}; - -struct bcm_hdr_suppression_contextinfo { - /* Intermediate buffer to accumulate pkt Header for PHS */ - UCHAR ucaHdrSuppressionInBuf[MAX_PHS_LENGTHS]; - /* Intermediate buffer containing pkt Header after PHS */ - UCHAR ucaHdrSuppressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; -}; - -struct bcm_classifier_rule { - ULONG ulSFID; - UCHAR ucReserved[2]; - B_UINT16 uiClassifierRuleIndex; - bool bUsed; - USHORT usVCID_Value; - /* This field detemines the Classifier Priority */ - B_UINT8 u8ClassifierRulePriority; - union u_ip_address stSrcIpAddress; - UCHAR ucIPSourceAddressLength; /* Ip Source Address Length */ - - union u_ip_address stDestIpAddress; - /* Ip Destination Address Length */ - UCHAR ucIPDestinationAddressLength; - UCHAR ucIPTypeOfServiceLength; /* Type of service Length */ - UCHAR ucTosLow; /* Tos Low */ - UCHAR ucTosHigh; /* Tos High */ - UCHAR ucTosMask; /* Tos Mask */ - - UCHAR ucProtocolLength; /* protocol Length */ - UCHAR ucProtocol[MAX_PROTOCOL_LENGTH]; /* protocol Length */ - USHORT usSrcPortRangeLo[MAX_PORT_RANGE]; - USHORT usSrcPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucSrcPortRangeLength; - - USHORT usDestPortRangeLo[MAX_PORT_RANGE]; - USHORT usDestPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucDestPortRangeLength; - - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - - /* For IPv6 Addressing */ - UCHAR ucDirection; - bool bIpv6Protocol; - UINT32 u32PHSRuleID; - struct bcm_phs_rule sPhsRule; - UCHAR u8AssociatedPHSI; - - /* Classification fields for ETH CS */ - UCHAR ucEthCSSrcMACLen; - UCHAR au8EThCSSrcMAC[MAC_ADDRESS_SIZE]; - UCHAR au8EThCSSrcMACMask[MAC_ADDRESS_SIZE]; - UCHAR ucEthCSDestMACLen; - UCHAR au8EThCSDestMAC[MAC_ADDRESS_SIZE]; - UCHAR au8EThCSDestMACMask[MAC_ADDRESS_SIZE]; - UCHAR ucEtherTypeLen; - UCHAR au8EthCSEtherType[NUM_ETHERTYPE_BYTES]; - UCHAR usUserPriority[2]; - USHORT usVLANID; - USHORT usValidityBitMap; -}; - -struct bcm_fragmented_packet_info { - bool bUsed; - ULONG ulSrcIpAddress; - USHORT usIpIdentification; - struct bcm_classifier_rule *pstMatchedClassifierEntry; - bool bOutOfOrderFragment; -}; - -struct bcm_packet_info { - /* classification extension Rule */ - ULONG ulSFID; - USHORT usVCID_Value; - UINT uiThreshold; - /* This field determines the priority of the SF Queues */ - B_UINT8 u8TrafficPriority; - - bool bValid; - bool bActive; - bool bActivateRequestSent; - - B_UINT8 u8QueueType; /* BE or rtPS */ - - /* maximum size of the bucket for the queue */ - UINT uiMaxBucketSize; - UINT uiCurrentQueueDepthOnTarget; - UINT uiCurrentBytesOnHost; - UINT uiCurrentPacketsOnHost; - UINT uiDroppedCountBytes; - UINT uiDroppedCountPackets; - UINT uiSentBytes; - UINT uiSentPackets; - UINT uiCurrentDrainRate; - UINT uiThisPeriodSentBytes; - LARGE_INTEGER liDrainCalculated; - UINT uiCurrentTokenCount; - LARGE_INTEGER liLastUpdateTokenAt; - UINT uiMaxAllowedRate; - UINT NumOfPacketsSent; - UCHAR ucDirection; - USHORT usCID; - struct bcm_mibs_parameters stMibsExtServiceFlowTable; - UINT uiCurrentRxRate; - UINT uiThisPeriodRxBytes; - UINT uiTotalRxBytes; - UINT uiTotalTxBytes; - UINT uiPendedLast; - UCHAR ucIpVersion; - - union { - struct { - struct sk_buff *FirstTxQueue; - struct sk_buff *LastTxQueue; - }; - struct { - struct sk_buff *ControlHead; - struct sk_buff *ControlTail; - }; - }; - - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - - bool bActiveSet; - bool bAdmittedSet; - bool bAuthorizedSet; - bool bClassifierPriority; - UCHAR ucServiceClassName[MAX_CLASS_NAME_LENGTH]; - bool bHeaderSuppressionEnabled; - spinlock_t SFQueueLock; - void *pstSFIndication; - struct timeval stLastUpdateTokenAt; - atomic_t uiPerSFTxResourceCount; - UINT uiMaxLatency; - UCHAR bIPCSSupport; - UCHAR bEthCSSupport; -}; - -struct bcm_tarang_data { - struct bcm_tarang_data *next; - struct bcm_mini_adapter *Adapter; - struct sk_buff *RxAppControlHead; - struct sk_buff *RxAppControlTail; - int AppCtrlQueueLen; - bool MacTracingEnabled; - bool bApplicationToExit; - struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs; - ULONG RxCntrlMsgBitMask; -}; - -struct bcm_targetdsx_buffer { - ULONG ulTargetDsxBuffer; - B_UINT16 tid; - bool valid; -}; - -typedef int (*FP_FLASH_WRITE)(struct bcm_mini_adapter *, UINT, PVOID); - -typedef int (*FP_FLASH_WRITE_STATUS)(struct bcm_mini_adapter *, UINT, PVOID); - -/* - * Driver adapter data structure - */ -struct bcm_mini_adapter { - struct bcm_mini_adapter *next; - struct net_device *dev; - u32 msg_enable; - CHAR *caDsxReqResp; - atomic_t ApplicationRunning; - bool AppCtrlQueueOverFlow; - atomic_t CurrentApplicationCount; - atomic_t RegisteredApplicationCount; - bool LinkUpStatus; - bool TimerActive; - u32 StatisticsPointer; - struct sk_buff *RxControlHead; - struct sk_buff *RxControlTail; - struct semaphore RxAppControlQueuelock; - struct semaphore fw_download_sema; - struct bcm_tarang_data *pTarangs; - spinlock_t control_queue_lock; - wait_queue_head_t process_read_wait_queue; - - /* the pointer to the first packet we have queued in send - * deserialized miniport support variables - */ - atomic_t TotalPacketCount; - atomic_t TxPktAvail; - - /* this to keep track of the Tx and Rx MailBox Registers. */ - atomic_t CurrNumFreeTxDesc; - /* to keep track the no of byte received */ - USHORT PrevNumRecvDescs; - USHORT CurrNumRecvDescs; - UINT u32TotalDSD; - struct bcm_packet_info PackInfo[NO_OF_QUEUES]; - struct bcm_classifier_rule astClassifierTable[MAX_CLASSIFIERS]; - bool TransferMode; - - /*************** qos ******************/ - bool bETHCSEnabled; - ULONG BEBucketSize; - ULONG rtPSBucketSize; - UCHAR LinkStatus; - bool AutoLinkUp; - bool AutoSyncup; - - int major; - int minor; - wait_queue_head_t tx_packet_wait_queue; - wait_queue_head_t process_rx_cntrlpkt; - atomic_t process_waiting; - bool fw_download_done; - - char *txctlpacket[MAX_CNTRL_PKTS]; - atomic_t cntrlpktCnt; - atomic_t index_app_read_cntrlpkt; - atomic_t index_wr_txcntrlpkt; - atomic_t index_rd_txcntrlpkt; - UINT index_datpkt; - struct semaphore rdmwrmsync; - - struct bcm_targetdsx_buffer astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; - ULONG ulFreeTargetBufferCnt; - ULONG ulCurrentTargetBuffer; - ULONG ulTotalTargetBuffersAvailable; - unsigned long chip_id; - wait_queue_head_t lowpower_mode_wait_queue; - bool bFlashBoot; - bool bBinDownloaded; - bool bCfgDownloaded; - bool bSyncUpRequestSent; - USHORT usBestEffortQueueIndex; - wait_queue_head_t ioctl_fw_dnld_wait_queue; - bool waiting_to_fw_download_done; - pid_t fw_download_process_pid; - struct bcm_target_params *pstargetparams; - bool device_removed; - bool DeviceAccess; - bool bIsAutoCorrectEnabled; - bool bDDRInitDone; - int DDRSetting; - ULONG ulPowerSaveMode; - spinlock_t txtransmitlock; - B_UINT8 txtransmit_running; - /* Thread for control packet handling */ - struct task_struct *control_packet_handler; - /* thread for transmitting packets. */ - struct task_struct *transmit_packet_thread; - - /* LED Related Structures */ - struct bcm_led_info LEDInfo; - - /* Driver State for LED Blinking */ - enum bcm_led_events DriverState; - /* Interface Specific */ - PVOID pvInterfaceAdapter; - int (*bcm_file_download)(PVOID, - struct file *, - unsigned int); - int (*bcm_file_readback_from_chip)(PVOID, - struct file *, - unsigned int); - int (*interface_rdm)(PVOID, - UINT, - PVOID, - int); - int (*interface_wrm)(PVOID, - UINT, - PVOID, - int); - int (*interface_transmit)(PVOID, PVOID , UINT); - bool IdleMode; - bool bDregRequestSentInIdleMode; - bool bTriedToWakeUpFromlowPowerMode; - bool bShutStatus; - bool bWakeUpDevice; - unsigned int usIdleModePattern; - /* BOOLEAN bTriedToWakeUpFromShutdown; */ - bool bLinkDownRequested; - int downloadDDR; - struct bcm_phs_extension stBCMPhsContext; - struct bcm_hdr_suppression_contextinfo stPhsTxContextInfo; - uint8_t ucaPHSPktRestoreBuf[2048]; - uint8_t bPHSEnabled; - bool AutoFirmDld; - bool bMipsConfig; - bool bDPLLConfig; - UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - struct bcm_fragmented_packet_info - astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; - atomic_t uiMBupdate; - UINT32 PmuMode; - enum bcm_nvm_type eNVMType; - UINT uiSectorSize; - UINT uiSectorSizeInCFG; - bool bSectorSizeOverride; - bool bStatusWrite; - UINT uiNVMDSDSize; - UINT uiVendorExtnFlag; - /* it will always represent chosen DSD at any point of time. - * Generally it is Active DSD but in case of NVM RD/WR it - * might be different. - */ - UINT ulFlashCalStart; - ULONG ulFlashControlSectionStart; - ULONG ulFlashWriteSize; - ULONG ulFlashID; - FP_FLASH_WRITE fpFlashWrite; - FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck; - - struct semaphore NVMRdmWrmLock; - struct device *pstCreatedClassDevice; - - /* BOOLEAN InterfaceUpStatus; */ - struct bcm_flash2x_cs_info *psFlash2xCSInfo; - struct bcm_flash_cs_info *psFlashCSInfo; - struct bcm_flash2x_vendor_info *psFlash2xVendorInfo; - UINT uiFlashBaseAdd; /* Flash start address */ - /* Active ISO offset chosen before f/w download */ - UINT uiActiveISOOffset; - enum bcm_flash2x_section_val eActiveISO; /* Active ISO section val */ - /* Active DSD val chosen before f/w download */ - enum bcm_flash2x_section_val eActiveDSD; - /* For accessing Active DSD chosen before f/w download */ - UINT uiActiveDSDOffsetAtFwDld; - UINT uiFlashLayoutMajorVersion; - UINT uiFlashLayoutMinorVersion; - bool bAllDSDWriteAllow; - bool bSigCorrupted; - /* this should be set who so ever want to change the Headers. - * after Write it should be reset immediately. - */ - bool bHeaderChangeAllowed; - int SelectedChip; - bool bEndPointHalted; - /* while bFlashRawRead will be true, Driver - * ignore map lay out and consider flash as of without any map. - */ - bool bFlashRawRead; - bool bPreparingForLowPowerMode; - bool bDoSuspend; - UINT syscfgBefFwDld; - bool StopAllXaction; - /* Used to Support extended CAPI requirements from */ - UINT32 liTimeSinceLastNetEntry; - struct semaphore LowPowerModeSync; - ULONG liDrainCalculated; - UINT gpioBitMap; - struct bcm_debug_state stDebugState; -}; - -#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) - -struct bcm_eth_header { - UCHAR au8DestinationAddress[6]; - UCHAR au8SourceAddress[6]; - USHORT u16Etype; -} __packed; - -struct bcm_firmware_info { - void __user *pvMappedFirmwareAddress; - ULONG u32FirmwareLength; - ULONG u32StartingAddress; -} __packed; - -/* holds the value of net_device structure.. */ -extern struct net_device *gblpnetdev; - -struct bcm_ddr_setting { - UINT ulRegAddress; - UINT ulRegValue; -}; -int InitAdapter(struct bcm_mini_adapter *psAdapter); - -/* ===================================================================== - * Beceem vendor request codes for EP0 - * ===================================================================== - */ - -#define BCM_REQUEST_READ 0x2 -#define BCM_REQUEST_WRITE 0x1 -#define EP2_MPS_REG 0x0F0110A0 -#define EP2_MPS 0x40 - -#define EP2_CFG_REG 0x0F0110A8 -#define EP2_CFG_INT 0x27 -#define EP2_CFG_BULK 0x25 - -#define EP4_MPS_REG 0x0F0110F0 -#define EP4_MPS 0x8C - -#define EP4_CFG_REG 0x0F0110F8 - -#define ISO_MPS_REG 0x0F0110C8 -#define ISO_MPS 0x00000000 - -#define EP1 0 -#define EP2 1 -#define EP3 2 -#define EP4 3 -#define EP5 4 -#define EP6 5 - -enum bcm_einterface_setting { - DEFAULT_SETTING_0 = 0, - ALTERNATE_SETTING_1 = 1, -}; - -#endif /* __ADAPTER_H__ */ diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c deleted file mode 100644 index 88ce2da531c6..000000000000 --- a/drivers/staging/bcm/Bcmchar.c +++ /dev/null @@ -1,2652 +0,0 @@ -#include - -#include "headers.h" - -static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, - PUCHAR read_data, - struct bcm_nvm_readwrite *nvm_rw) -{ - INT status = STATUS_FAILURE; - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return -EACCES; - } - - status = BeceemNVMRead(ad, (PUINT)read_data, - nvm_rw->uiOffset, - nvm_rw->uiNumBytes); - up(&ad->NVMRdmWrmLock); - - if (status != STATUS_SUCCESS) { - kfree(read_data); - return status; - } - - if (copy_to_user(nvm_rw->pBuffer, read_data, nvm_rw->uiNumBytes)) { - kfree(read_data); - return -EFAULT; - } - - return STATUS_SUCCESS; -} - -static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, - PUCHAR read_data, - struct bcm_nvm_readwrite *nvm_rw) -{ - /* - * New Requirement:- - * DSD section updation will be allowed in two case:- - * 1. if DSD sig is present in DSD header means dongle - * is ok and updation is fruitfull - * 2. if point 1 failes then user buff should have - * DSD sig. this point ensures that if dongle is - * corrupted then user space program first modify - * the DSD header with valid DSD sig so that this - * as well as further write may be worthwhile. - * - * This restriction has been put assuming that - * if DSD sig is corrupted, DSD data won't be - * considered valid. - */ - INT status; - ULONG dsd_magic_num_in_usr_buff = 0; - - status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); - if (status == STATUS_SUCCESS) - return STATUS_SUCCESS; - - if (((nvm_rw->uiOffset + nvm_rw->uiNumBytes) != - ad->uiNVMDSDSize) || - (nvm_rw->uiNumBytes < SIGNATURE_SIZE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "DSD Sig is present neither in Flash nor User provided Input.."); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return status; - } - - dsd_magic_num_in_usr_buff = - ntohl(*(PUINT)(read_data + nvm_rw->uiNumBytes - - SIGNATURE_SIZE)); - if (dsd_magic_num_in_usr_buff != DSD_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "DSD Sig is present neither in Flash nor User provided Input.."); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return status; - } - - return STATUS_SUCCESS; -} - -/*************************************************************** -* Function - bcm_char_open() -* -* Description - This is the "open" entry point for the character -* driver. -* -* Parameters - inode: Pointer to the Inode structure of char device -* filp : File pointer of the char device -* -* Returns - Zero(Success) -****************************************************************/ - -static int bcm_char_open(struct inode *inode, struct file *filp) -{ - struct bcm_mini_adapter *ad = NULL; - struct bcm_tarang_data *tarang = NULL; - - ad = GET_BCM_ADAPTER(gblpnetdev); - tarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); - if (!tarang) - return -ENOMEM; - - tarang->Adapter = ad; - tarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); - - down(&ad->RxAppControlQueuelock); - tarang->next = ad->pTarangs; - ad->pTarangs = tarang; - up(&ad->RxAppControlQueuelock); - - /* Store the Adapter structure */ - filp->private_data = tarang; - - /* Start Queuing the control response Packets */ - atomic_inc(&ad->ApplicationRunning); - - nonseekable_open(inode, filp); - return 0; -} - -static int bcm_char_release(struct inode *inode, struct file *filp) -{ - struct bcm_tarang_data *tarang, *tmp, *ptmp; - struct bcm_mini_adapter *ad = NULL; - struct sk_buff *pkt, *npkt; - - tarang = (struct bcm_tarang_data *)filp->private_data; - - if (tarang == NULL) - return 0; - - ad = tarang->Adapter; - - down(&ad->RxAppControlQueuelock); - - tmp = ad->pTarangs; - for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) { - if (tmp == tarang) - break; - } - - if (tmp) { - if (!ptmp) - ad->pTarangs = tmp->next; - else - ptmp->next = tmp->next; - } else { - up(&ad->RxAppControlQueuelock); - return 0; - } - - pkt = tarang->RxAppControlHead; - while (pkt) { - npkt = pkt->next; - kfree_skb(pkt); - pkt = npkt; - } - - up(&ad->RxAppControlQueuelock); - - /* Stop Queuing the control response Packets */ - atomic_dec(&ad->ApplicationRunning); - - kfree(tarang); - - /* remove this filp from the asynchronously notified filp's */ - filp->private_data = NULL; - return 0; -} - -static ssize_t bcm_char_read(struct file *filp, - char __user *buf, - size_t size, - loff_t *f_pos) -{ - struct bcm_tarang_data *tarang = filp->private_data; - struct bcm_mini_adapter *ad = tarang->Adapter; - struct sk_buff *packet = NULL; - ssize_t pkt_len = 0; - int wait_ret_val = 0; - unsigned long ret = 0; - - wait_ret_val = wait_event_interruptible( - ad->process_read_wait_queue, - (tarang->RxAppControlHead || - ad->device_removed)); - - if ((wait_ret_val == -ERESTARTSYS)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Exiting as i've been asked to exit!!!\n"); - return wait_ret_val; - } - - if (ad->device_removed) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device Removed... Killing the Apps...\n"); - return -ENODEV; - } - - if (false == ad->fw_download_done) - return -EACCES; - - down(&ad->RxAppControlQueuelock); - - if (tarang->RxAppControlHead) { - packet = tarang->RxAppControlHead; - DEQUEUEPACKET(tarang->RxAppControlHead, - tarang->RxAppControlTail); - tarang->AppCtrlQueueLen--; - } - - up(&ad->RxAppControlQueuelock); - - if (packet) { - pkt_len = packet->len; - ret = copy_to_user(buf, packet->data, - min_t(size_t, pkt_len, size)); - if (ret) { - dev_kfree_skb(packet); - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Returning from copy to user failure\n"); - return -EFAULT; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Read %zd Bytes From Adapter packet = %p by process %d!\n", - pkt_len, packet, current->pid); - dev_kfree_skb(packet); - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); - return pkt_len; -} - -static int bcm_char_ioctl_reg_read_private(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_rdm_buffer rdm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - PCHAR temp_buff; - INT status = STATUS_FAILURE; - UINT buff_len; - u16 temp_value; - int bytes; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(rdm_buff)) - return -EINVAL; - - if (copy_from_user(&rdm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (io_buff.OutputLength > USHRT_MAX || - io_buff.OutputLength == 0) { - return -EINVAL; - } - - buff_len = io_buff.OutputLength; - temp_value = 4 - (buff_len % 4); - buff_len += temp_value % 4; - - temp_buff = kmalloc(buff_len, GFP_KERNEL); - if (!temp_buff) - return -ENOMEM; - - bytes = rdmalt(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, buff_len); - if (bytes > 0) { - status = STATUS_SUCCESS; - if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { - kfree(temp_buff); - return -EFAULT; - } - } else { - status = bytes; - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_reg_write_private(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_wrm_buffer wrm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status; - - /* Copy Ioctl Buffer structure */ - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(wrm_buff)) - return -EINVAL; - - /* Get WrmBuffer structure */ - if (copy_from_user(&wrm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - tmp = wrm_buff.Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4))) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - status = wrmalt(ad, (UINT)wrm_buff.Register, - (PUINT)wrm_buff.Data, sizeof(ULONG)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Done\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Failed\n"); - status = -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_rdm_buffer rdm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - PCHAR temp_buff = NULL; - UINT tmp = 0; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle Mode, Blocking Rdms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(rdm_buff)) - return -EINVAL; - - if (copy_from_user(&rdm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (io_buff.OutputLength > USHRT_MAX || - io_buff.OutputLength == 0) { - return -EINVAL; - } - - temp_buff = kmalloc(io_buff.OutputLength, GFP_KERNEL); - if (!temp_buff) - return STATUS_FAILURE; - - if ((((ULONG)rdm_buff.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)rdm_buff.Register & 0x3)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM Done On invalid Address : %x Access Denied.\n", - (int)rdm_buff.Register); - - kfree(temp_buff); - return -EINVAL; - } - - tmp = rdm_buff.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, io_buff.OutputLength); - - if (bytes > 0) { - status = STATUS_SUCCESS; - if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { - kfree(temp_buff); - return -EFAULT; - } - } else { - status = bytes; - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, - struct bcm_mini_adapter *ad, - UINT cmd) -{ - struct bcm_wrm_buffer wrm_buff = {0}; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle Mode, Blocking Wrms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(wrm_buff)) - return -EINVAL; - - /* Get WrmBuffer structure */ - if (copy_from_user(&wrm_buff, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if ((((ULONG)wrm_buff.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)wrm_buff.Register & 0x3)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM Done On invalid Address : %x Access Denied.\n", - (int)wrm_buff.Register); - return -EINVAL; - } - - tmp = wrm_buff.Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - status = wrmaltWithLock(ad, (UINT)wrm_buff.Register, - (PUINT)wrm_buff.Data, - wrm_buff.Length); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, - DBG_LVL_ALL, "WRM Done\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "WRM Failed\n"); - status = -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_gpio_set_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_info gpio_info = {0}; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - UINT value = 0; - UINT bit = 0; - UINT operation = 0; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "GPIO Can't be set/clear in Low power Mode"); - return -EACCES; - } - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_info)) - return -EINVAL; - - if (copy_from_user(&gpio_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bit = gpio_info.uiGpioNumber; - operation = gpio_info.uiGpioValue; - value = (1< is not correspond to LED !!!", - value); - return -EINVAL; - } - - /* Set - setting 1 */ - if (operation) { - /* Set the gpio output register */ - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_SET_REG, - (PUINT)(&value), sizeof(UINT)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Set the GPIO bit\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Failed to set the %dth GPIO\n", - bit); - return status; - } - } else { - /* Set the gpio output register */ - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_CLR_REG, - (PUINT)(&value), sizeof(UINT)); - - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Set the GPIO bit\n"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Failed to clear the %dth GPIO\n", - bit); - return status; - } - } - - bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "GPIO_MODE_REGISTER read failed"); - return status; - } - status = STATUS_SUCCESS; - - /* Set the gpio mode register to output */ - *(UINT *)reset_val |= (1<IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "GPIO Can't be set/clear in Low power Mode"); - return -EACCES; - } - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(thread_req)) - return -EINVAL; - - if (copy_from_user(&thread_req, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - /* if LED thread is running(Actively or Inactively) - * set it state to make inactive - */ - if (ad->LEDInfo.led_thread_running) { - if (thread_req.ThreadState == LED_THREAD_ACTIVATION_REQ) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "Activating thread req"); - ad->DriverState = LED_THREAD_ACTIVE; - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, - "DeActivating Thread req....."); - ad->DriverState = LED_THREAD_INACTIVE; - } - - /* signal thread. */ - wake_up(&ad->LEDInfo.notify_led_event); - } - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_gpio_status_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_info gpio_info = {0}; - struct bcm_ioctl_buffer io_buff; - ULONG bit = 0; - UCHAR read[4]; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EACCES; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_info)) - return -EINVAL; - - if (copy_from_user(&gpio_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bit = gpio_info.uiGpioNumber; - - /* Set the gpio output register */ - bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER, - (PUINT)read, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM Failed\n"); - return status; - } - status = STATUS_SUCCESS; - return status; -} - -static int bcm_char_ioctl_gpio_multi_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX]; - struct bcm_gpio_multi_info *pgpio_multi_info = - (struct bcm_gpio_multi_info *)gpio_multi_info; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - INT status = STATUS_FAILURE; - int bytes; - - memset(pgpio_multi_info, 0, - MAX_IDX * sizeof(struct bcm_gpio_multi_info)); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EINVAL; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_multi_info)) - return -EINVAL; - if (io_buff.OutputLength > sizeof(gpio_multi_info)) - io_buff.OutputLength = sizeof(gpio_multi_info); - - if (copy_from_user(&gpio_multi_info, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - if (IsReqGpioIsLedInNVM(ad, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) - == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_info[WIMAX_IDX].uiGPIOMask, - ad->gpioBitMap); - return -EINVAL; - } - - /* Set the gpio output register */ - if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & - (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) { - /* Set 1's in GPIO OUTPUT REGISTER */ - *(UINT *)reset_val = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - pgpio_multi_info[WIMAX_IDX].uiGPIOValue; - - if (*(UINT *) reset_val) - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_SET_REG, - (PUINT)reset_val, sizeof(ULONG)); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); - return status; - } - - /* Clear to 0's in GPIO OUTPUT REGISTER */ - *(UINT *)reset_val = - (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); - - if (*(UINT *) reset_val) - status = wrmaltWithLock(ad, - BCM_GPIO_OUTPUT_CLR_REG, (PUINT)reset_val, - sizeof(ULONG)); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); - return status; - } - } - - if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) { - bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "RDM to GPIO_PIN_STATE_REGISTER Failed."); - return status; - } - status = STATUS_SUCCESS; - - pgpio_multi_info[WIMAX_IDX].uiGPIOValue = - (*(UINT *)reset_val & - pgpio_multi_info[WIMAX_IDX].uiGPIOMask); - } - - status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_info, - io_buff.OutputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed while copying Content to IOBufer for user space err:%d", - status); - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_gpio_mode_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX]; - struct bcm_gpio_multi_mode *pgpio_multi_mode = - (struct bcm_gpio_multi_mode *)gpio_multi_mode; - struct bcm_ioctl_buffer io_buff; - UCHAR reset_val[4]; - INT status; - int bytes; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) - return -EINVAL; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength > sizeof(gpio_multi_mode)) - return -EINVAL; - if (io_buff.OutputLength > sizeof(gpio_multi_mode)) - io_buff.OutputLength = sizeof(gpio_multi_mode); - - if (copy_from_user(&gpio_multi_mode, io_buff.InputBuffer, - io_buff.InputLength)) - return -EFAULT; - - bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(UINT)); - - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Read of GPIO_MODE_REGISTER failed"); - return status; - } - status = STATUS_SUCCESS; - - /* Validating the request */ - if (IsReqGpioIsLedInNVM(ad, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) - == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, - ad->gpioBitMap); - return -EINVAL; - } - - if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) { - /* write all OUT's (1's) */ - *(UINT *) reset_val |= - (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - - /* write all IN's (0's) */ - *(UINT *) reset_val &= - ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - - /* Currently implemented return the modes of all GPIO's - * else needs to bit AND with mask - */ - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val; - - status = wrmaltWithLock(ad, GPIO_MODE_REGISTER, - (PUINT)reset_val, sizeof(ULONG)); - if (status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "WRM to GPIO_MODE_REGISTER Done"); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "WRM to GPIO_MODE_REGISTER Failed"); - return -EFAULT; - } - } else { - /* if uiGPIOMask is 0 then return mode register configuration */ - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val; - } - - status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_mode, - io_buff.OutputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed while copying Content to IOBufer for user space err:%d", - status); - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_misc_request(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - PVOID buff = NULL; - INT status; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength < sizeof(struct bcm_link_request)) - return -EINVAL; - - if (io_buff.InputLength > MAX_CNTL_PKT_SIZE) - return -EINVAL; - - buff = memdup_user(io_buff.InputBuffer, - io_buff.InputLength); - if (IS_ERR(buff)) - return PTR_ERR(buff); - - down(&ad->LowPowerModeSync); - status = wait_event_interruptible_timeout( - ad->lowpower_mode_wait_queue, - !ad->bPreparingForLowPowerMode, - (1 * HZ)); - - if (status == -ERESTARTSYS) - goto cntrlEnd; - - if (ad->bPreparingForLowPowerMode) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Preparing Idle Mode is still True - Hence Rejecting control message\n"); - status = STATUS_FAILURE; - goto cntrlEnd; - } - status = CopyBufferToControlPacket(ad, (PVOID)buff); - -cntrlEnd: - up(&ad->LowPowerModeSync); - kfree(buff); - return status; -} - -static int bcm_char_ioctl_buffer_download_start( - struct bcm_mini_adapter *ad) -{ - INT status; - - if (down_trylock(&ad->NVMRdmWrmLock)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Starting the firmware download PID =0x%x!!!!\n", - current->pid); - - if (down_trylock(&ad->fw_download_sema)) - return -EBUSY; - - ad->bBinDownloaded = false; - ad->fw_download_process_pid = current->pid; - ad->bCfgDownloaded = false; - ad->fw_download_done = false; - netif_carrier_off(ad->dev); - netif_stop_queue(ad->dev); - status = reset_card_proc(ad); - if (status) { - pr_err(PFX "%s: reset_card_proc Failed!\n", ad->dev->name); - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; - } - mdelay(10); - - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_buffer_download(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_firmware_info *fw_info = NULL; - struct bcm_ioctl_buffer io_buff; - INT status; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Starting the firmware download PID =0x%x!!!!\n", current->pid); - - if (!down_trylock(&ad->fw_download_sema)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Invalid way to download buffer. Use Start and then call this!!!\n"); - up(&ad->fw_download_sema); - return -EINVAL; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - up(&ad->fw_download_sema); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Length for FW DLD is : %lx\n", io_buff.InputLength); - - if (io_buff.InputLength > sizeof(struct bcm_firmware_info)) { - up(&ad->fw_download_sema); - return -EINVAL; - } - - fw_info = kmalloc(sizeof(*fw_info), GFP_KERNEL); - if (!fw_info) { - up(&ad->fw_download_sema); - return -ENOMEM; - } - - if (copy_from_user(fw_info, io_buff.InputBuffer, - io_buff.InputLength)) { - up(&ad->fw_download_sema); - kfree(fw_info); - return -EFAULT; - } - - if (!fw_info->pvMappedFirmwareAddress || - (fw_info->u32FirmwareLength == 0)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Something else is wrong %lu\n", - fw_info->u32FirmwareLength); - up(&ad->fw_download_sema); - kfree(fw_info); - status = -EINVAL; - return status; - } - - status = bcm_ioctl_fw_download(ad, fw_info); - - if (status != STATUS_SUCCESS) { - if (fw_info->u32StartingAddress == CONFIG_BEGIN_ADDR) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL: Configuration File Upload Failed\n"); - else - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL: Firmware File Upload Failed\n"); - - /* up(&ad->fw_download_sema); */ - - if (ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ad->DriverState = DRIVER_INIT; - ad->LEDInfo.bLedInitDone = false; - wake_up(&ad->LEDInfo.notify_led_event); - } - } - - if (status != STATUS_SUCCESS) - up(&ad->fw_download_sema); - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, - "IOCTL: Firmware File Uploaded\n"); - kfree(fw_info); - return status; -} - -static int bcm_char_ioctl_buffer_download_stop(void __user *argp, - struct bcm_mini_adapter *ad) -{ - INT status; - int timeout = 0; - - if (!down_trylock(&ad->fw_download_sema)) { - up(&ad->fw_download_sema); - return -EINVAL; - } - - if (down_trylock(&ad->NVMRdmWrmLock)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "FW download blocked as EEPROM Read/Write is in progress\n"); - up(&ad->fw_download_sema); - return -EACCES; - } - - ad->bBinDownloaded = TRUE; - ad->bCfgDownloaded = TRUE; - atomic_set(&ad->CurrNumFreeTxDesc, 0); - ad->CurrNumRecvDescs = 0; - ad->downloadDDR = 0; - - /* setting the Mips to Run */ - status = run_card_proc(ad); - - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Firm Download Failed\n"); - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "Firm Download Over...\n"); - - mdelay(10); - - /* Wait for MailBox Interrupt */ - if (StartInterruptUrb((struct bcm_interface_adapter *)ad->pvInterfaceAdapter)) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Unable to send interrupt...\n"); - - timeout = 5*HZ; - ad->waiting_to_fw_download_done = false; - wait_event_timeout(ad->ioctl_fw_dnld_wait_queue, - ad->waiting_to_fw_download_done, timeout); - ad->fw_download_process_pid = INVALID_PID; - ad->fw_download_done = TRUE; - atomic_set(&ad->CurrNumFreeTxDesc, 0); - ad->CurrNumRecvDescs = 0; - ad->PrevNumRecvDescs = 0; - atomic_set(&ad->cntrlpktCnt, 0); - ad->LinkUpStatus = 0; - ad->LinkStatus = 0; - - if (ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ad->DriverState = FW_DOWNLOAD_DONE; - wake_up(&ad->LEDInfo.notify_led_event); - } - - if (!timeout) - status = -ENODEV; - - up(&ad->fw_download_sema); - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *ad) -{ - INT status; - INT nvm_access; - - nvm_access = down_trylock(&ad->NVMRdmWrmLock); - if (nvm_access) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; - } - - down(&ad->RxAppControlQueuelock); - status = reset_card_proc(ad); - flushAllAppQ(); - up(&ad->RxAppControlQueuelock); - up(&ad->NVMRdmWrmLock); - ResetCounters(ad); - return status; -} - -static int bcm_char_ioctl_qos_threshold(ULONG arg, - struct bcm_mini_adapter *ad) -{ - USHORT i; - - for (i = 0; i < NO_OF_QUEUES; i++) { - if (get_user(ad->PackInfo[i].uiThreshold, - (unsigned long __user *)arg)) { - return -EFAULT; - } - } - return 0; -} - -static int bcm_char_ioctl_switch_transfer_mode(void __user *argp, - struct bcm_mini_adapter *ad) -{ - UINT data = 0; - - if (copy_from_user(&data, argp, sizeof(UINT))) - return -EFAULT; - - if (data) { - /* Allow All Packets */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); - ad->TransferMode = ETH_PACKET_TUNNELING_MODE; - } else { - /* Allow IP only Packets */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); - ad->TransferMode = IP_PACKET_ONLY_MODE; - } - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_driver_version(void __user *argp) -{ - struct bcm_ioctl_buffer io_buff; - ulong len; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - len = min_t(ulong, io_buff.OutputLength, strlen(DRV_VERSION) + 1); - - if (copy_to_user(io_buff.OutputBuffer, DRV_VERSION, len)) - return -EFAULT; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_current_status(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_link_state link_state; - struct bcm_ioctl_buffer io_buff; - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "copy_from_user failed..\n"); - return -EFAULT; - } - - if (io_buff.OutputLength != sizeof(link_state)) - return -EINVAL; - - memset(&link_state, 0, sizeof(link_state)); - link_state.bIdleMode = ad->IdleMode; - link_state.bShutdownMode = ad->bShutStatus; - link_state.ucLinkStatus = ad->LinkStatus; - - if (copy_to_user(io_buff.OutputBuffer, &link_state, min_t(size_t, - sizeof(link_state), io_buff.OutputLength))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy_to_user Failed..\n"); - return -EFAULT; - } - return STATUS_SUCCESS; -} - - -static int bcm_char_ioctl_set_mac_tracing(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - UINT tracing_flag; - - /* copy ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&tracing_flag, io_buff.InputBuffer, sizeof(UINT))) - return -EFAULT; - - if (tracing_flag) - ad->pTarangs->MacTracingEnabled = TRUE; - else - ad->pTarangs->MacTracingEnabled = false; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_dsx_indication(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - ULONG sf_id = 0; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(struct bcm_add_indication_alt)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Mismatch req: %lx needed is =0x%zx!!!", - io_buff.OutputLength, - sizeof(struct bcm_add_indication_alt)); - return -EINVAL; - } - - if (copy_from_user(&sf_id, io_buff.InputBuffer, sizeof(sf_id))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Get DSX Data SF ID is =%lx\n", sf_id); - get_dsx_sf_data_to_application(ad, sf_id, io_buff.OutputBuffer); - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_get_host_mibs(void __user *argp, - struct bcm_mini_adapter *ad, - struct bcm_tarang_data *tarang) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - PVOID temp_buff; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength != sizeof(struct bcm_host_stats_mibs)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Length Check failed %lu %zd\n", io_buff.OutputLength, - sizeof(struct bcm_host_stats_mibs)); - return -EINVAL; - } - - /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ - temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL); - if (!temp_buff) - return STATUS_FAILURE; - - status = ProcessGetHostMibs(ad, temp_buff); - GetDroppedAppCntrlPktMibs(temp_buff, tarang); - - if (status != STATUS_FAILURE) { - if (copy_to_user(io_buff.OutputBuffer, temp_buff, - sizeof(struct bcm_host_stats_mibs))) { - kfree(temp_buff); - return -EFAULT; - } - } - - kfree(temp_buff); - return status; -} - -static int bcm_char_ioctl_bulk_wrm(void __user *argp, - struct bcm_mini_adapter *ad, UINT cmd) -{ - struct bcm_bulk_wrm_buffer *bulk_buff; - struct bcm_ioctl_buffer io_buff; - UINT tmp = 0; - INT status = STATUS_FAILURE; - PCHAR buff = NULL; - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "Device in Idle/Shutdown Mode, Blocking Wrms\n"); - return -EACCES; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.InputLength < sizeof(ULONG) * 2) - return -EINVAL; - - buff = memdup_user(io_buff.InputBuffer, - io_buff.InputLength); - if (IS_ERR(buff)) - return PTR_ERR(buff); - - bulk_buff = (struct bcm_bulk_wrm_buffer *)buff; - - if (((ULONG)bulk_buff->Register & 0x0F000000) != 0x0F000000 || - ((ULONG)bulk_buff->Register & 0x3)) { - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "WRM Done On invalid Address : %x Access Denied.\n", - (int)bulk_buff->Register); - kfree(buff); - return -EINVAL; - } - - tmp = bulk_buff->Register & EEPROM_REJECT_MASK; - if (!((ad->pstargetparams->m_u32Customize)&VSG_MODE) && - ((tmp == EEPROM_REJECT_REG_1) || - (tmp == EEPROM_REJECT_REG_2) || - (tmp == EEPROM_REJECT_REG_3) || - (tmp == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) { - - kfree(buff); - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - - if (bulk_buff->SwapEndian == false) - status = wrmWithLock(ad, (UINT)bulk_buff->Register, - (PCHAR)bulk_buff->Values, - io_buff.InputLength - 2*sizeof(ULONG)); - else - status = wrmaltWithLock(ad, (UINT)bulk_buff->Register, - (PUINT)bulk_buff->Values, - io_buff.InputLength - 2*sizeof(ULONG)); - - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); - - kfree(buff); - return status; -} - -static int bcm_char_ioctl_get_nvm_size(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (ad->eNVMType == NVM_EEPROM || ad->eNVMType == NVM_FLASH) { - if (copy_to_user(io_buff.OutputBuffer, &ad->uiNVMDSDSize, - sizeof(UINT))) - return -EFAULT; - } - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_cal_init(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - UINT sector_size = 0; - INT status = STATUS_FAILURE; - - if (ad->eNVMType == NVM_FLASH) { - if (copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(§or_size, io_buff.InputBuffer, - sizeof(UINT))) - return -EFAULT; - - if ((sector_size < MIN_SECTOR_SIZE) || - (sector_size > MAX_SECTOR_SIZE)) { - if (copy_to_user(io_buff.OutputBuffer, - &ad->uiSectorSize, sizeof(UINT))) - return -EFAULT; - } else { - if (IsFlash2x(ad)) { - if (copy_to_user(io_buff.OutputBuffer, - &ad->uiSectorSize, sizeof(UINT))) - return -EFAULT; - } else { - if ((TRUE == ad->bShutStatus) || - (TRUE == ad->IdleMode)) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_PRINTK, 0, 0, - "Device is in Idle/Shutdown Mode\n"); - return -EACCES; - } - - ad->uiSectorSize = sector_size; - BcmUpdateSectorSize(ad, - ad->uiSectorSize); - } - } - status = STATUS_SUCCESS; - } else { - status = STATUS_FAILURE; - } - return status; -} - -static int bcm_char_ioctl_set_debug(void __user *argp, - struct bcm_mini_adapter *ad) -{ -#ifdef DEBUG - struct bcm_ioctl_buffer io_buff; - struct bcm_user_debug_state user_debug_state; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "In SET_DEBUG ioctl\n"); - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&user_debug_state, io_buff.InputBuffer, - sizeof(struct bcm_user_debug_state))) - return -EFAULT; - - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", - user_debug_state.OnOff, user_debug_state.Type); - /* user_debug_state.Subtype <<= 1; */ - user_debug_state.Subtype = 1 << user_debug_state.Subtype; - BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0, - "actual Subtype=0x%x\n", user_debug_state.Subtype); - - /* Update new 'DebugState' in the ad */ - ad->stDebugState.type |= user_debug_state.Type; - /* Subtype: A bitmap of 32 bits for Subtype per Type. - * Valid indexes in 'subtype' array: 1,2,4,8 - * corresponding to valid Type values. Hence we can use the 'Type' field - * as the index value, ignoring the array entries 0,3,5,6,7 ! - */ - if (user_debug_state.OnOff) - ad->stDebugState.subtype[user_debug_state.Type] |= - user_debug_state.Subtype; - else - ad->stDebugState.subtype[user_debug_state.Type] &= - ~user_debug_state.Subtype; - - BCM_SHOW_DEBUG_BITMAP(ad); -#endif - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_nvm_rw(void __user *argp, - struct bcm_mini_adapter *ad, UINT cmd) -{ - struct bcm_nvm_readwrite nvm_rw; - struct timeval tv0, tv1; - struct bcm_ioctl_buffer io_buff; - PUCHAR read_data = NULL; - INT status = STATUS_FAILURE; - - memset(&tv0, 0, sizeof(struct timeval)); - memset(&tv1, 0, sizeof(struct timeval)); - if ((ad->eNVMType == NVM_FLASH) && - (ad->uiFlashLayoutMajorVersion == 0)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); - return -EFAULT; - } - - if (IsFlash2x(ad)) { - if ((ad->eActiveDSD != DSD0) && - (ad->eActiveDSD != DSD1) && - (ad->eActiveDSD != DSD2)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "No DSD is active..hence NVM Command is blocked"); - return STATUS_FAILURE; - } - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (copy_from_user(&nvm_rw, - (IOCTL_BCM_NVM_READ == cmd) ? - io_buff.OutputBuffer : io_buff.InputBuffer, - sizeof(struct bcm_nvm_readwrite))) - return -EFAULT; - - /* - * Deny the access if the offset crosses the cal area limit. - */ - if (nvm_rw.uiNumBytes > ad->uiNVMDSDSize) - return STATUS_FAILURE; - - if (nvm_rw.uiOffset > - ad->uiNVMDSDSize - nvm_rw.uiNumBytes) - return STATUS_FAILURE; - - read_data = memdup_user(nvm_rw.pBuffer, - nvm_rw.uiNumBytes); - if (IS_ERR(read_data)) - return PTR_ERR(read_data); - - do_gettimeofday(&tv0); - if (IOCTL_BCM_NVM_READ == cmd) { - int ret = bcm_handle_nvm_read_cmd(ad, read_data, - &nvm_rw); - if (ret != STATUS_SUCCESS) - return ret; - } else { - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_data); - return -EACCES; - } - - ad->bHeaderChangeAllowed = TRUE; - if (IsFlash2x(ad)) { - int ret = handle_flash2x_adapter(ad, - read_data, - &nvm_rw); - if (ret != STATUS_SUCCESS) - return ret; - } - - status = BeceemNVMWrite(ad, (PUINT)read_data, - nvm_rw.uiOffset, nvm_rw.uiNumBytes, - nvm_rw.bVerify); - if (IsFlash2x(ad)) - BcmFlash2xWriteSig(ad, ad->eActiveDSD); - - ad->bHeaderChangeAllowed = false; - - up(&ad->NVMRdmWrmLock); - - if (status != STATUS_SUCCESS) { - kfree(read_data); - return status; - } - } - - do_gettimeofday(&tv1); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - " timetaken by Write/read :%ld msec\n", - (tv1.tv_sec - tv0.tv_sec)*1000 + - (tv1.tv_usec - tv0.tv_usec)/1000); - - kfree(read_data); - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_flash2x_section_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_readwrite flash_2x_read = {0}; - struct bcm_ioctl_buffer io_buff; - PUCHAR read_buff = NULL; - UINT nob = 0; - UINT buff_size = 0; - UINT read_bytes = 0; - UINT read_offset = 0; - INT status = STATUS_FAILURE; - void __user *OutPutBuff; - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - /* Reading FLASH 2.x READ structure */ - if (copy_from_user(&flash_2x_read, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_readwrite))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.Section :%x", - flash_2x_read.Section); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.offset :%x", - flash_2x_read.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.numOfBytes :%x", - flash_2x_read.numOfBytes); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nflash_2x_read.bVerify :%x\n", - flash_2x_read.bVerify); - - /* This was internal to driver for raw read. - * now it has ben exposed to user space app. - */ - if (validateFlash2xReadWrite(ad, &flash_2x_read) == false) - return STATUS_FAILURE; - - nob = flash_2x_read.numOfBytes; - if (nob > ad->uiSectorSize) - buff_size = ad->uiSectorSize; - else - buff_size = nob; - - read_offset = flash_2x_read.offset; - OutPutBuff = io_buff.OutputBuffer; - read_buff = kzalloc(buff_size , GFP_KERNEL); - - if (read_buff == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory allocation failed for Flash 2.x Read Structure"); - return -ENOMEM; - } - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EACCES; - } - - while (nob) { - if (nob > ad->uiSectorSize) - read_bytes = ad->uiSectorSize; - else - read_bytes = nob; - - /* Reading the data from Flash 2.x */ - status = BcmFlash2xBulkRead(ad, (PUINT)read_buff, - flash_2x_read.Section, read_offset, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Flash 2x read err with status :%d", - status); - break; - } - - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, read_buff, read_bytes); - - status = copy_to_user(OutPutBuff, read_buff, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Copy to use failed with status :%d", status); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EFAULT; - } - nob = nob - read_bytes; - if (nob) { - read_offset = read_offset + read_bytes; - OutPutBuff = OutPutBuff + read_bytes; - } - } - - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return status; -} - -static int bcm_char_ioctl_flash2x_section_write(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_readwrite sFlash2xWrite = {0}; - struct bcm_ioctl_buffer io_buff; - PUCHAR write_buff; - void __user *input_addr; - UINT nob = 0; - UINT buff_size = 0; - UINT write_off = 0; - UINT write_bytes = 0; - INT status = STATUS_FAILURE; - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - /* First make this False so that we can enable the Sector - * Permission Check in BeceemFlashBulkWrite - */ - ad->bAllDSDWriteAllow = false; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - /* Reading FLASH 2.x READ structure */ - if (copy_from_user(&sFlash2xWrite, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_readwrite))) - return -EFAULT; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.Section :%x", sFlash2xWrite.Section); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.offset :%d", sFlash2xWrite.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.numOfBytes :%x", sFlash2xWrite.numOfBytes); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\nsFlash2xWrite.bVerify :%x\n", sFlash2xWrite.bVerify); - - if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) - && (sFlash2xWrite.Section != VSA2)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Only VSA write is allowed"); - return -EINVAL; - } - - if (validateFlash2xReadWrite(ad, &sFlash2xWrite) == false) - return STATUS_FAILURE; - - input_addr = sFlash2xWrite.pDataBuff; - write_off = sFlash2xWrite.offset; - nob = sFlash2xWrite.numOfBytes; - - if (nob > ad->uiSectorSize) - buff_size = ad->uiSectorSize; - else - buff_size = nob; - - write_buff = kmalloc(buff_size, GFP_KERNEL); - - if (write_buff == NULL) - return -ENOMEM; - - /* extracting the remainder of the given offset. */ - write_bytes = ad->uiSectorSize; - if (write_off % ad->uiSectorSize) { - write_bytes = ad->uiSectorSize - - (write_off % ad->uiSectorSize); - } - - if (nob < write_bytes) - write_bytes = nob; - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return -EACCES; - } - - BcmFlash2xCorruptSig(ad, sFlash2xWrite.Section); - do { - status = copy_from_user(write_buff, input_addr, write_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy to user failed with status :%d", status); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return -EFAULT; - } - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, - OSAL_DBG, DBG_LVL_ALL, write_buff, write_bytes); - - /* Writing the data from Flash 2.x */ - status = BcmFlash2xBulkWrite(ad, (PUINT)write_buff, - sFlash2xWrite.Section, - write_off, - write_bytes, - sFlash2xWrite.bVerify); - - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash 2x read err with status :%d", status); - break; - } - - nob = nob - write_bytes; - if (nob) { - write_off = write_off + write_bytes; - input_addr = input_addr + write_bytes; - if (nob > ad->uiSectorSize) - write_bytes = ad->uiSectorSize; - else - write_bytes = nob; - } - } while (nob > 0); - - BcmFlash2xWriteSig(ad, sFlash2xWrite.Section); - up(&ad->NVMRdmWrmLock); - kfree(write_buff); - return status; -} - -static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_bitmap *flash_2x_bit_map; - struct bcm_ioctl_buffer io_buff; - -BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength != sizeof(struct bcm_flash2x_bitmap)) - return -EINVAL; - - flash_2x_bit_map = kzalloc(sizeof(struct bcm_flash2x_bitmap), - GFP_KERNEL); - - if (flash_2x_bit_map == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory is not available"); - return -ENOMEM; - } - - /* Reading the Flash Sectio Bit map */ - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - kfree(flash_2x_bit_map); - return -EACCES; - } - - BcmGetFlash2xSectionalBitMap(ad, flash_2x_bit_map); - up(&ad->NVMRdmWrmLock); - if (copy_to_user(io_buff.OutputBuffer, flash_2x_bit_map, - sizeof(struct bcm_flash2x_bitmap))) { - kfree(flash_2x_bit_map); - return -EFAULT; - } - - kfree(flash_2x_bit_map); - return STATUS_FAILURE; -} - -static int bcm_char_ioctl_set_active_section(void __user *argp, - struct bcm_mini_adapter *ad) -{ - enum bcm_flash2x_section_val flash_2x_section_val = 0; - INT status = STATUS_FAILURE; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SET_ACTIVE_SECTION Called"); - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - - status = copy_from_user(&flash_2x_section_val, - io_buff.InputBuffer, sizeof(INT)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of flash section val failed"); - return -EFAULT; - } - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - status = BcmSetActiveSection(ad, flash_2x_section_val); - if (status) - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Failed to make it's priority Highest. status %d", - status); - - up(&ad->NVMRdmWrmLock); - - return status; -} - -static int bcm_char_ioctl_copy_section(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_flash2x_copy_section copy_sect_strut = {0}; - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_COPY_SECTION Called"); - - ad->bAllDSDWriteAllow = false; - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed status :%d", - status); - return -EFAULT; - } - - status = copy_from_user(©_sect_strut, io_buff.InputBuffer, - sizeof(struct bcm_flash2x_copy_section)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of Copy_Section_Struct failed with status :%d", - status); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Source SEction :%x", copy_sect_strut.SrcSection); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Destination SEction :%x", copy_sect_strut.DstSection); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "offset :%x", copy_sect_strut.offset); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "nob :%x", copy_sect_strut.numOfBytes); - - if (IsSectionExistInFlash(ad, copy_sect_strut.SrcSection) == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Source Section<%x> does not exist in Flash ", - copy_sect_strut.SrcSection); - return -EINVAL; - } - - if (IsSectionExistInFlash(ad, copy_sect_strut.DstSection) == false) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Destinatio Section<%x> does not exist in Flash ", - copy_sect_strut.DstSection); - return -EINVAL; - } - - if (copy_sect_strut.SrcSection == copy_sect_strut.DstSection) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Source and Destination section should be different"); - return -EINVAL; - } - - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - if (copy_sect_strut.SrcSection == ISO_IMAGE1 || - copy_sect_strut.SrcSection == ISO_IMAGE2) { - if (IsNonCDLessDevice(ad)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Device is Non-CDLess hence won't have ISO !!"); - status = -EINVAL; - } else if (copy_sect_strut.numOfBytes == 0) { - status = BcmCopyISO(ad, copy_sect_strut); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Partial Copy of ISO section is not Allowed.."); - status = STATUS_FAILURE; - } - up(&ad->NVMRdmWrmLock); - return status; - } - - status = BcmCopySection(ad, copy_sect_strut.SrcSection, - copy_sect_strut.DstSection, - copy_sect_strut.offset, - copy_sect_strut.numOfBytes); - up(&ad->NVMRdmWrmLock); - return status; -} - -static int bcm_char_ioctl_get_flash_cs_info(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - " IOCTL_BCM_GET_FLASH_CS_INFO Called"); - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - - if (ad->eNVMType != NVM_FLASH) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Connected device does not have flash"); - return -EINVAL; - } - - if (IsFlash2x(ad) == TRUE) { - if (io_buff.OutputLength < sizeof(struct bcm_flash2x_cs_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, - ad->psFlash2xCSInfo, - sizeof(struct bcm_flash2x_cs_info))) - return -EFAULT; - } else { - if (io_buff.OutputLength < sizeof(struct bcm_flash_cs_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, ad->psFlashCSInfo, - sizeof(struct bcm_flash_cs_info))) - return -EFAULT; - } - return status; -} - -static int bcm_char_ioctl_select_dsd(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - UINT sect_offset = 0; - enum bcm_flash2x_section_val flash_2x_section_val; - - flash_2x_section_val = NO_SECTION_VAL; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_SELECT_DSD Called"); - - if (IsFlash2x(ad) != TRUE) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash Does not have 2.x map"); - return -EINVAL; - } - - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - status = copy_from_user(&flash_2x_section_val, io_buff.InputBuffer, - sizeof(INT)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy of flash section val failed"); - return -EFAULT; - } - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Read Section :%d", flash_2x_section_val); - if ((flash_2x_section_val != DSD0) && - (flash_2x_section_val != DSD1) && - (flash_2x_section_val != DSD2)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Passed section<%x> is not DSD section", - flash_2x_section_val); - return STATUS_FAILURE; - } - - sect_offset = BcmGetSectionValStartOffset(ad, flash_2x_section_val); - if (sect_offset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Provided Section val <%d> does not exist in Flash 2.x", - flash_2x_section_val); - return -EINVAL; - } - - ad->bAllDSDWriteAllow = TRUE; - ad->ulFlashCalStart = sect_offset; - ad->eActiveDSD = flash_2x_section_val; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_nvm_raw_read(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_nvm_readwrite nvm_read; - struct bcm_ioctl_buffer io_buff; - unsigned int nob; - INT buff_size; - INT read_offset = 0; - UINT read_bytes = 0; - PUCHAR read_buff; - void __user *OutPutBuff; - INT status = STATUS_FAILURE; - - if (ad->eNVMType != NVM_FLASH) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "NVM TYPE is not Flash"); - return -EINVAL; - } - - /* Copy Ioctl Buffer structure */ - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "copy_from_user 1 failed\n"); - return -EFAULT; - } - - if (copy_from_user(&nvm_read, io_buff.OutputBuffer, - sizeof(struct bcm_nvm_readwrite))) - return -EFAULT; - - nob = nvm_read.uiNumBytes; - /* In Raw-Read max Buff size : 64MB */ - - if (nob > DEFAULT_BUFF_SIZE) - buff_size = DEFAULT_BUFF_SIZE; - else - buff_size = nob; - - read_offset = nvm_read.uiOffset; - OutPutBuff = nvm_read.pBuffer; - - read_buff = kzalloc(buff_size , GFP_KERNEL); - if (read_buff == NULL) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Memory allocation failed for Flash 2.x Read Structure"); - return -ENOMEM; - } - down(&ad->NVMRdmWrmLock); - - if ((ad->IdleMode == TRUE) || - (ad->bShutStatus == TRUE) || - (ad->bPreparingForLowPowerMode == TRUE)) { - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Device is in Idle/Shutdown Mode\n"); - kfree(read_buff); - up(&ad->NVMRdmWrmLock); - return -EACCES; - } - - ad->bFlashRawRead = TRUE; - - while (nob) { - if (nob > DEFAULT_BUFF_SIZE) - read_bytes = DEFAULT_BUFF_SIZE; - else - read_bytes = nob; - - /* Reading the data from Flash 2.x */ - status = BeceemNVMRead(ad, (PUINT)read_buff, - read_offset, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Flash 2x read err with status :%d", - status); - break; - } - - BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG, - DBG_LVL_ALL, read_buff, read_bytes); - - status = copy_to_user(OutPutBuff, read_buff, read_bytes); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, - "Copy to use failed with status :%d", - status); - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return -EFAULT; - } - nob = nob - read_bytes; - if (nob) { - read_offset = read_offset + read_bytes; - OutPutBuff = OutPutBuff + read_bytes; - } - } - ad->bFlashRawRead = false; - up(&ad->NVMRdmWrmLock); - kfree(read_buff); - return status; -} - -static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp, - struct bcm_mini_adapter *ad, - struct bcm_tarang_data *tarang) -{ - struct bcm_ioctl_buffer io_buff; - INT status = STATUS_FAILURE; - ULONG rx_cntrl_msg_bit_mask = 0; - - /* Copy Ioctl Buffer structure */ - status = copy_from_user(&io_buff, argp, - sizeof(struct bcm_ioctl_buffer)); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "copy of Ioctl buffer is failed from user space"); - return -EFAULT; - } - - if (io_buff.InputLength != sizeof(unsigned long)) - return -EINVAL; - - status = copy_from_user(&rx_cntrl_msg_bit_mask, io_buff.InputBuffer, - io_buff.InputLength); - if (status) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "copy of control bit mask failed from user space"); - return -EFAULT; - } - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "\n Got user defined cntrl msg bit mask :%lx", - rx_cntrl_msg_bit_mask); - tarang->RxCntrlMsgBitMask = rx_cntrl_msg_bit_mask; - - return status; -} - -static int bcm_char_ioctl_get_device_driver_info(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_driver_info dev_info; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); - - memset(&dev_info, 0, sizeof(dev_info)); - dev_info.MaxRDMBufferSize = BUFFER_4K; - dev_info.u32DSDStartOffset = EEPROM_CALPARAM_START; - dev_info.u32RxAlignmentCorrection = 0; - dev_info.u32NVMType = ad->eNVMType; - dev_info.u32InterfaceType = BCM_USB; - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(dev_info)) - return -EINVAL; - - if (copy_to_user(io_buff.OutputBuffer, &dev_info, sizeof(dev_info))) - return -EFAULT; - - return STATUS_SUCCESS; -} - -static int bcm_char_ioctl_time_since_net_entry(void __user *argp, - struct bcm_mini_adapter *ad) -{ - struct bcm_time_elapsed time_elapsed_since_net_entry = {0}; - struct bcm_ioctl_buffer io_buff; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); - - if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) - return -EFAULT; - - if (io_buff.OutputLength < sizeof(struct bcm_time_elapsed)) - return -EINVAL; - - time_elapsed_since_net_entry.ul64TimeElapsedSinceNetEntry = - get_seconds() - ad->liTimeSinceLastNetEntry; - - if (copy_to_user(io_buff.OutputBuffer, &time_elapsed_since_net_entry, - sizeof(struct bcm_time_elapsed))) - return -EFAULT; - - return STATUS_SUCCESS; -} - - -static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) -{ - struct bcm_tarang_data *tarang = filp->private_data; - void __user *argp = (void __user *)arg; - struct bcm_mini_adapter *ad = tarang->Adapter; - INT status = STATUS_FAILURE; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", - cmd, arg); - - if (_IOC_TYPE(cmd) != BCM_IOCTL) - return -EFAULT; - if (_IOC_DIR(cmd) & _IOC_READ) - status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); - else if (_IOC_DIR(cmd) & _IOC_WRITE) - status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); - else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) - status = STATUS_SUCCESS; - - if (status) - return -EFAULT; - - if (ad->device_removed) - return -EFAULT; - - if (false == ad->fw_download_done) { - switch (cmd) { - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - case IOCTL_BCM_GPIO_SET_REQUEST: - case IOCTL_BCM_GPIO_STATUS_REQUEST: - return -EACCES; - default: - break; - } - } - - status = vendorextnIoctl(ad, cmd, arg); - if (status != CONTINUE_COMMON_PATH) - return status; - - switch (cmd) { - /* Rdms for Swin Idle... */ - case IOCTL_BCM_REGISTER_READ_PRIVATE: - status = bcm_char_ioctl_reg_read_private(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_WRITE_PRIVATE: - status = bcm_char_ioctl_reg_write_private(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_READ: - case IOCTL_BCM_EEPROM_REGISTER_READ: - status = bcm_char_ioctl_eeprom_reg_read(argp, ad); - return status; - - case IOCTL_BCM_REGISTER_WRITE: - case IOCTL_BCM_EEPROM_REGISTER_WRITE: - status = bcm_char_ioctl_eeprom_reg_write(argp, ad, cmd); - return status; - - case IOCTL_BCM_GPIO_SET_REQUEST: - status = bcm_char_ioctl_gpio_set_request(argp, ad); - return status; - - case BCM_LED_THREAD_STATE_CHANGE_REQ: - status = bcm_char_ioctl_led_thread_state_change_req(argp, - ad); - return status; - - case IOCTL_BCM_GPIO_STATUS_REQUEST: - status = bcm_char_ioctl_gpio_status_request(argp, ad); - return status; - - case IOCTL_BCM_GPIO_MULTI_REQUEST: - status = bcm_char_ioctl_gpio_multi_request(argp, ad); - return status; - - case IOCTL_BCM_GPIO_MODE_REQUEST: - status = bcm_char_ioctl_gpio_mode_request(argp, ad); - return status; - - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - status = bcm_char_ioctl_misc_request(argp, ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD_START: - status = bcm_char_ioctl_buffer_download_start(ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD: - status = bcm_char_ioctl_buffer_download(argp, ad); - return status; - - case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: - status = bcm_char_ioctl_buffer_download_stop(argp, ad); - return status; - - - case IOCTL_BE_BUCKET_SIZE: - status = 0; - if (get_user(ad->BEBucketSize, - (unsigned long __user *)arg)) - status = -EFAULT; - break; - - case IOCTL_RTPS_BUCKET_SIZE: - status = 0; - if (get_user(ad->rtPSBucketSize, - (unsigned long __user *)arg)) - status = -EFAULT; - break; - - case IOCTL_CHIP_RESET: - status = bcm_char_ioctl_chip_reset(ad); - return status; - - case IOCTL_QOS_THRESHOLD: - status = bcm_char_ioctl_qos_threshold(arg, ad); - return status; - - case IOCTL_DUMP_PACKET_INFO: - DumpPackInfo(ad); - DumpPhsRules(&ad->stBCMPhsContext); - status = STATUS_SUCCESS; - break; - - case IOCTL_GET_PACK_INFO: - if (copy_to_user(argp, &ad->PackInfo, - sizeof(struct bcm_packet_info)*NO_OF_QUEUES)) - return -EFAULT; - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_SWITCH_TRANSFER_MODE: - status = bcm_char_ioctl_switch_transfer_mode(argp, ad); - return status; - - case IOCTL_BCM_GET_DRIVER_VERSION: - status = bcm_char_ioctl_get_driver_version(argp); - return status; - - case IOCTL_BCM_GET_CURRENT_STATUS: - status = bcm_char_ioctl_get_current_status(argp, ad); - return status; - - case IOCTL_BCM_SET_MAC_TRACING: - status = bcm_char_ioctl_set_mac_tracing(argp, ad); - return status; - - case IOCTL_BCM_GET_DSX_INDICATION: - status = bcm_char_ioctl_get_dsx_indication(argp, ad); - return status; - - case IOCTL_BCM_GET_HOST_MIBS: - status = bcm_char_ioctl_get_host_mibs(argp, ad, tarang); - return status; - - case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: - if ((false == ad->bTriedToWakeUpFromlowPowerMode) && - (TRUE == ad->IdleMode)) { - ad->usIdleModePattern = ABORT_IDLE_MODE; - ad->bWakeUpDevice = TRUE; - wake_up(&ad->process_rx_cntrlpkt); - } - - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_BULK_WRM: - status = bcm_char_ioctl_bulk_wrm(argp, ad, cmd); - return status; - - case IOCTL_BCM_GET_NVM_SIZE: - status = bcm_char_ioctl_get_nvm_size(argp, ad); - return status; - - case IOCTL_BCM_CAL_INIT: - status = bcm_char_ioctl_cal_init(argp, ad); - return status; - - case IOCTL_BCM_SET_DEBUG: - status = bcm_char_ioctl_set_debug(argp, ad); - return status; - - case IOCTL_BCM_NVM_READ: - case IOCTL_BCM_NVM_WRITE: - status = bcm_char_ioctl_nvm_rw(argp, ad, cmd); - return status; - - case IOCTL_BCM_FLASH2X_SECTION_READ: - status = bcm_char_ioctl_flash2x_section_read(argp, ad); - return status; - - case IOCTL_BCM_FLASH2X_SECTION_WRITE: - status = bcm_char_ioctl_flash2x_section_write(argp, ad); - return status; - - case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: - status = bcm_char_ioctl_flash2x_section_bitmap(argp, ad); - return status; - - case IOCTL_BCM_SET_ACTIVE_SECTION: - status = bcm_char_ioctl_set_active_section(argp, ad); - return status; - - case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: - /* Right Now we are taking care of only DSD */ - ad->bAllDSDWriteAllow = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); - status = STATUS_SUCCESS; - break; - - case IOCTL_BCM_COPY_SECTION: - status = bcm_char_ioctl_copy_section(argp, ad); - return status; - - case IOCTL_BCM_GET_FLASH_CS_INFO: - status = bcm_char_ioctl_get_flash_cs_info(argp, ad); - return status; - - case IOCTL_BCM_SELECT_DSD: - status = bcm_char_ioctl_select_dsd(argp, ad); - return status; - - case IOCTL_BCM_NVM_RAW_READ: - status = bcm_char_ioctl_nvm_raw_read(argp, ad); - return status; - - case IOCTL_BCM_CNTRLMSG_MASK: - status = bcm_char_ioctl_cntrlmsg_mask(argp, ad, tarang); - return status; - - case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: - status = bcm_char_ioctl_get_device_driver_info(argp, ad); - return status; - - case IOCTL_BCM_TIME_SINCE_NET_ENTRY: - status = bcm_char_ioctl_time_since_net_entry(argp, ad); - return status; - - case IOCTL_CLOSE_NOTIFICATION: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, - "IOCTL_CLOSE_NOTIFICATION"); - break; - - default: - pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); - status = STATUS_FAILURE; - break; - } - return status; -} - - -static const struct file_operations bcm_fops = { - .owner = THIS_MODULE, - .open = bcm_char_open, - .release = bcm_char_release, - .read = bcm_char_read, - .unlocked_ioctl = bcm_char_ioctl, - .llseek = no_llseek, -}; - -int register_control_device_interface(struct bcm_mini_adapter *ad) -{ - - if (ad->major > 0) - return ad->major; - - ad->major = register_chrdev(0, DEV_NAME, &bcm_fops); - if (ad->major < 0) { - pr_err(DRV_NAME ": could not created character device\n"); - return ad->major; - } - - ad->pstCreatedClassDevice = device_create(bcm_class, NULL, - MKDEV(ad->major, 0), - ad, DEV_NAME); - - if (IS_ERR(ad->pstCreatedClassDevice)) { - pr_err(DRV_NAME ": class device create failed\n"); - unregister_chrdev(ad->major, DEV_NAME); - return PTR_ERR(ad->pstCreatedClassDevice); - } - - return 0; -} - -void unregister_control_device_interface(struct bcm_mini_adapter *ad) -{ - if (ad->major > 0) { - device_destroy(bcm_class, MKDEV(ad->major, 0)); - unregister_chrdev(ad->major, DEV_NAME); - } -} - diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c deleted file mode 100644 index e57767684cee..000000000000 --- a/drivers/staging/bcm/Bcmnet.c +++ /dev/null @@ -1,240 +0,0 @@ -#include "headers.h" - -struct net_device *gblpnetdev; - -static INT bcm_open(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - if (ad->fw_download_done == false) { - pr_notice(PFX "%s: link up failed (download in progress)\n", - dev->name); - return -EBUSY; - } - - if (netif_msg_ifup(ad)) - pr_info(PFX "%s: enabling interface\n", dev->name); - - if (ad->LinkUpStatus) { - if (netif_msg_link(ad)) - pr_info(PFX "%s: link up\n", dev->name); - - netif_carrier_on(ad->dev); - netif_start_queue(ad->dev); - } - - return 0; -} - -static INT bcm_close(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - if (netif_msg_ifdown(ad)) - pr_info(PFX "%s: disabling interface\n", dev->name); - - netif_carrier_off(dev); - netif_stop_queue(dev); - - return 0; -} - -static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, - void *accel_priv, select_queue_fallback_t fallback) -{ - return ClassifyPacket(netdev_priv(dev), skb); -} - -/******************************************************************* -* Function - bcm_transmit() -* -* Description - This is the main transmit function for our virtual -* interface(eth0). It handles the ARP packets. It -* clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). -* -* Parameter - skb - Pointer to the socket buffer structure -* dev - Pointer to the virtual net device structure -* -*********************************************************************/ - -static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - u16 qindex = skb_get_queue_mapping(skb); - - - if (ad->device_removed || !ad->LinkUpStatus) - goto drop; - - if (ad->TransferMode != IP_PACKET_ONLY_MODE) - goto drop; - - if (INVALID_QUEUE_INDEX == qindex) - goto drop; - - if (ad->PackInfo[qindex].uiCurrentPacketsOnHost >= - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) - return NETDEV_TX_BUSY; - - /* Now Enqueue the packet */ - if (netif_msg_tx_queued(ad)) - pr_info(PFX "%s: enqueueing packet to queue %d\n", - dev->name, qindex); - - spin_lock(&ad->PackInfo[qindex].SFQueueLock); - ad->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; - ad->PackInfo[qindex].uiCurrentPacketsOnHost++; - - *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies; - ENQUEUEPACKET(ad->PackInfo[qindex].FirstTxQueue, - ad->PackInfo[qindex].LastTxQueue, skb); - atomic_inc(&ad->TotalPacketCount); - spin_unlock(&ad->PackInfo[qindex].SFQueueLock); - - /* FIXME - this is racy and incorrect, replace with work queue */ - if (!atomic_read(&ad->TxPktAvail)) { - atomic_set(&ad->TxPktAvail, 1); - wake_up(&ad->tx_packet_wait_queue); - } - return NETDEV_TX_OK; - - drop: - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - - - -/** -@ingroup init_functions -Register other driver entry points with the kernel -*/ -static const struct net_device_ops bcmNetDevOps = { - .ndo_open = bcm_open, - .ndo_stop = bcm_close, - .ndo_start_xmit = bcm_transmit, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_select_queue = bcm_select_queue, -}; - -static struct device_type wimax_type = { - .name = "wimax", -}; - -static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - cmd->speed = SPEED_10000; - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - return 0; -} - -static void bcm_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_device *udev = interface_to_usbdev(intf_ad->interface); - - strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_VERSION, sizeof(info->version)); - snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u", - ad->uiFlashLayoutMajorVersion, - ad->uiFlashLayoutMinorVersion); - - usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); -} - -static u32 bcm_get_link(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - return ad->LinkUpStatus; -} - -static u32 bcm_get_msglevel(struct net_device *dev) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - return ad->msg_enable; -} - -static void bcm_set_msglevel(struct net_device *dev, u32 level) -{ - struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); - - ad->msg_enable = level; -} - -static const struct ethtool_ops bcm_ethtool_ops = { - .get_settings = bcm_get_settings, - .get_drvinfo = bcm_get_drvinfo, - .get_link = bcm_get_link, - .get_msglevel = bcm_get_msglevel, - .set_msglevel = bcm_set_msglevel, -}; - -int register_networkdev(struct bcm_mini_adapter *ad) -{ - struct net_device *net = ad->dev; - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_interface *udev = intf_ad->interface; - struct usb_device *xdev = intf_ad->udev; - - int result; - - net->netdev_ops = &bcmNetDevOps; - net->ethtool_ops = &bcm_ethtool_ops; - net->mtu = MTU_SIZE; /* 1400 Bytes */ - net->tx_queue_len = TX_QLEN; - net->flags |= IFF_NOARP; - - netif_carrier_off(net); - - SET_NETDEV_DEVTYPE(net, &wimax_type); - - /* Read the MAC Address from EEPROM */ - result = ReadMacAddressFromNVM(ad); - if (result != STATUS_SUCCESS) { - dev_err(&udev->dev, - PFX "Error in Reading the mac Address: %d", result); - return -EIO; - } - - result = register_netdev(net); - if (result) - return result; - - gblpnetdev = ad->dev; - - if (netif_msg_probe(ad)) - dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n", - net->name, xdev->bus->bus_name, xdev->devpath, - net->dev_addr); - - return 0; -} - -void unregister_networkdev(struct bcm_mini_adapter *ad) -{ - struct net_device *net = ad->dev; - struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; - struct usb_interface *udev = intf_ad->interface; - struct usb_device *xdev = intf_ad->udev; - - if (netif_msg_probe(ad)) - dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n", - net->name, xdev->bus->bus_name, xdev->devpath); - - unregister_netdev(ad->dev); -} diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c deleted file mode 100644 index adca0ce4d05f..000000000000 --- a/drivers/staging/bcm/CmHost.c +++ /dev/null @@ -1,2254 +0,0 @@ -/************************************************************ - * CMHOST.C - * This file contains the routines for handling Connection - * Management. - ************************************************************/ - -#include "headers.h" - -enum E_CLASSIFIER_ACTION { - eInvalidClassifierAction, - eAddClassifier, - eReplaceClassifier, - eDeleteClassifier -}; - -static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, - B_UINT16 tid); -static void restore_endianess_of_pstClassifierEntry( - struct bcm_classifier_rule *pstClassifierEntry, - enum bcm_ipaddr_context eIpAddrContext); - -static void apply_phs_rule_to_all_classifiers( - register struct bcm_mini_adapter *Adapter, - register UINT uiSearchRuleIndex, - USHORT uVCID, - struct bcm_phs_rule *sPhsRule, - struct bcm_phs_rules *cPhsRule, - struct bcm_add_indication_alt *pstAddIndication); - -/************************************************************ - * Function - SearchSfid - * - * Description - This routinue would search QOS queues having - * specified SFID as input parameter. - * - * Parameters - Adapter: Pointer to the Adapter structure - * uiSfid : Given SFID for matching - * - * Returns - Queue index for this SFID(If matched) - * Else Invalid Queue Index(If Not matched) - ************************************************************/ -int SearchSfid(struct bcm_mini_adapter *Adapter, UINT uiSfid) -{ - int i; - - for (i = (NO_OF_QUEUES-1); i >= 0; i--) - if (Adapter->PackInfo[i].ulSFID == uiSfid) - return i; - - return NO_OF_QUEUES+1; -} - -/*************************************************************** - * Function -SearchFreeSfid - * - * Description - This routinue would search Free available SFID. - * - * Parameter - Adapter: Pointer to the Adapter structure - * - * Returns - Queue index for the free SFID - * Else returns Invalid Index. - ****************************************************************/ -static int SearchFreeSfid(struct bcm_mini_adapter *Adapter) -{ - int i; - - for (i = 0; i < (NO_OF_QUEUES-1); i++) - if (Adapter->PackInfo[i].ulSFID == 0) - return i; - - return NO_OF_QUEUES+1; -} - -/* - * Function: SearchClsid - * Description: This routinue would search Classifier having specified ClassifierID as input parameter - * Input parameters: struct bcm_mini_adapter *Adapter - Adapter Context - * unsigned int uiSfid - The SF in which the classifier is to searched - * B_UINT16 uiClassifierID - The classifier ID to be searched - * Return: int :Classifier table index of matching entry - */ -static int SearchClsid(struct bcm_mini_adapter *Adapter, - ULONG ulSFID, - B_UINT16 uiClassifierID) -{ - int i; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if ((Adapter->astClassifierTable[i].bUsed) && - (Adapter->astClassifierTable[i].uiClassifierRuleIndex - == uiClassifierID) && - (Adapter->astClassifierTable[i].ulSFID == ulSFID)) - return i; - } - - return MAX_CLASSIFIERS+1; -} - -/* - * @ingroup ctrl_pkt_functions - * This routinue would search Free available Classifier entry in classifier table. - * @return free Classifier Entry index in classifier table for specified SF - */ -static int SearchFreeClsid(struct bcm_mini_adapter *Adapter /**Adapter Context*/) -{ - int i; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if (!Adapter->astClassifierTable[i].bUsed) - return i; - } - - return MAX_CLASSIFIERS+1; -} - -static VOID deleteSFBySfid(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex) -{ - /* deleting all the packet held in the SF */ - flush_queue(Adapter, uiSearchRuleIndex); - - /* Deleting the all classifiers for this SF */ - DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex); - - /* Resetting only MIBS related entries in the SF */ - memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, - sizeof(struct bcm_mibs_table)); -} - -static inline VOID -CopyIpAddrToClassifier(struct bcm_classifier_rule *pstClassifierEntry, - B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc, - bool bIpVersion6, enum bcm_ipaddr_context eIpAddrContext) -{ - int i = 0; - UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; - UCHAR *ptrClassifierIpAddress = NULL; - UCHAR *ptrClassifierIpMask = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (bIpVersion6) - nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES; - - /* Destination Ip Address */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Address Range Length:0x%X ", u8IpAddressLen); - if ((bIpVersion6 ? (IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2) : - (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) { - - union u_ip_address *st_dest_ip = - &pstClassifierEntry->stDestIpAddress; - - union u_ip_address *st_src_ip = - &pstClassifierEntry->stSrcIpAddress; - - /* - * checking both the mask and address togethor in Classification. - * So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2 - * (nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask) - */ - if (eIpAddrContext == eDestIpAddress) { - pstClassifierEntry->ucIPDestinationAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if (bIpVersion6) { - ptrClassifierIpAddress = - st_dest_ip->ucIpv6Address; - ptrClassifierIpMask = - st_dest_ip->ucIpv6Mask; - } else { - ptrClassifierIpAddress = - st_dest_ip->ucIpv4Address; - ptrClassifierIpMask = - st_dest_ip->ucIpv4Mask; - } - } else if (eIpAddrContext == eSrcIpAddress) { - pstClassifierEntry->ucIPSourceAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if (bIpVersion6) { - ptrClassifierIpAddress = - st_src_ip->ucIpv6Address; - ptrClassifierIpMask = st_src_ip->ucIpv6Mask; - } else { - ptrClassifierIpAddress = - st_src_ip->ucIpv4Address; - ptrClassifierIpMask = st_src_ip->ucIpv4Mask; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Address Length:0x%X\n", - pstClassifierEntry->ucIPDestinationAddressLength); - while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) - && (i < MAX_IP_RANGE_LENGTH)) { - memcpy(ptrClassifierIpAddress + - (i * nSizeOfIPAddressInBytes), - (pu8IpAddressMaskSrc - + (i * nSizeOfIPAddressInBytes * 2)), - nSizeOfIPAddressInBytes); - - if (!bIpVersion6) { - if (eIpAddrContext == eSrcIpAddress) { - st_src_ip->ulIpv4Addr[i] = - ntohl(st_src_ip->ulIpv4Addr[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Src Ip Address:0x%luX ", - st_src_ip->ulIpv4Addr[i]); - } else if (eIpAddrContext == eDestIpAddress) { - st_dest_ip->ulIpv4Addr[i] = - ntohl(st_dest_ip->ulIpv4Addr[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Dest Ip Address:0x%luX ", - st_dest_ip->ulIpv4Addr[i]); - } - } - u8IpAddressLen -= nSizeOfIPAddressInBytes; - if (u8IpAddressLen >= nSizeOfIPAddressInBytes) { - memcpy(ptrClassifierIpMask + - (i * nSizeOfIPAddressInBytes), - (pu8IpAddressMaskSrc - + nSizeOfIPAddressInBytes - + (i * nSizeOfIPAddressInBytes * 2)), - nSizeOfIPAddressInBytes); - - if (!bIpVersion6) { - if (eIpAddrContext == eSrcIpAddress) { - st_src_ip->ulIpv4Mask[i] = - ntohl(st_src_ip->ulIpv4Mask[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Src Ip Mask Address:0x%luX ", - st_src_ip->ulIpv4Mask[i]); - } else if (eIpAddrContext == eDestIpAddress) { - st_dest_ip->ulIpv4Mask[i] = - ntohl(st_dest_ip->ulIpv4Mask[i]); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Dest Ip Mask Address:0x%luX ", - st_dest_ip->ulIpv4Mask[i]); - } - } - u8IpAddressLen -= nSizeOfIPAddressInBytes; - } - if (u8IpAddressLen == 0) - pstClassifierEntry->bDestIpValid = TRUE; - - i++; - } - if (bIpVersion6) { - /* Restore EndianNess of Struct */ - restore_endianess_of_pstClassifierEntry( - pstClassifierEntry, - eIpAddrContext - ); - } - } -} - -void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, bool bFreeAll) -{ - int i; - struct bcm_targetdsx_buffer *curr_buf; - - for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { - curr_buf = &Adapter->astTargetDsxBuffer[i]; - - if (curr_buf->valid) - continue; - - if ((bFreeAll) || (curr_buf->tid == TID)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", - TID, curr_buf->ulTargetDsxBuffer); - curr_buf->valid = 1; - curr_buf->tid = 0; - Adapter->ulFreeTargetBufferCnt++; - } - } -} - -/* - * @ingroup ctrl_pkt_functions - * copy classifier rule into the specified SF index - */ -static inline VOID CopyClassifierRuleToSF(struct bcm_mini_adapter *Adapter, - struct bcm_convergence_types *psfCSType, - UINT uiSearchRuleIndex, - UINT nClassifierIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - /* VOID *pvPhsContext = NULL; */ - int i; - /* UCHAR ucProtocolLength=0; */ - /* ULONG ulPhsStatus; */ - - struct bcm_packet_class_rules *pack_class_rule = - &psfCSType->cCPacketClassificationRule; - - if (Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 || - nClassifierIndex > (MAX_CLASSIFIERS-1)) - return; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Storing Classifier Rule Index : %X", - ntohs(pack_class_rule->u16PacketClassificationRuleIndex)); - - if (nClassifierIndex > MAX_CLASSIFIERS-1) - return; - - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if (pstClassifierEntry) { - /* Store if Ipv6 */ - pstClassifierEntry->bIpv6Protocol = - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false; - - /* Destinaiton Port */ - pstClassifierEntry->ucDestPortRangeLength = - pack_class_rule->u8ProtocolDestPortRangeLength / 4; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Destination Port Range Length:0x%X ", - pstClassifierEntry->ucDestPortRangeLength); - - if (pack_class_rule->u8ProtocolDestPortRangeLength <= MAX_PORT_RANGE) { - for (i = 0; i < (pstClassifierEntry->ucDestPortRangeLength); i++) { - pstClassifierEntry->usDestPortRangeLo[i] = - *((PUSHORT)(pack_class_rule->u8ProtocolDestPortRange+i)); - pstClassifierEntry->usDestPortRangeHi[i] = - *((PUSHORT)(pack_class_rule->u8ProtocolDestPortRange+2+i)); - pstClassifierEntry->usDestPortRangeLo[i] = - ntohs(pstClassifierEntry->usDestPortRangeLo[i]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Destination Port Range Lo:0x%X ", - pstClassifierEntry->usDestPortRangeLo[i]); - pstClassifierEntry->usDestPortRangeHi[i] = - ntohs(pstClassifierEntry->usDestPortRangeHi[i]); - } - } else { - pstClassifierEntry->ucDestPortRangeLength = 0; - } - - /* Source Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Source Port Range Length:0x%X ", - pack_class_rule->u8ProtocolSourcePortRangeLength); - if (pack_class_rule->u8ProtocolSourcePortRangeLength <= MAX_PORT_RANGE) { - pstClassifierEntry->ucSrcPortRangeLength = - pack_class_rule->u8ProtocolSourcePortRangeLength/4; - for (i = 0; i < (pstClassifierEntry->ucSrcPortRangeLength); i++) { - pstClassifierEntry->usSrcPortRangeLo[i] = - *((PUSHORT)(pack_class_rule-> - u8ProtocolSourcePortRange+i)); - pstClassifierEntry->usSrcPortRangeHi[i] = - *((PUSHORT)(pack_class_rule-> - u8ProtocolSourcePortRange+2+i)); - pstClassifierEntry->usSrcPortRangeLo[i] = - ntohs(pstClassifierEntry->usSrcPortRangeLo[i]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Source Port Range Lo:0x%X ", - pstClassifierEntry->usSrcPortRangeLo[i]); - pstClassifierEntry->usSrcPortRangeHi[i] = - ntohs(pstClassifierEntry->usSrcPortRangeHi[i]); - } - } - /* Destination Ip Address and Mask */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Destination Parameters : "); - CopyIpAddrToClassifier(pstClassifierEntry, - pack_class_rule->u8IPDestinationAddressLength, - pack_class_rule->u8IPDestinationAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? - TRUE : false, eDestIpAddress); - - /* Source Ip Address and Mask */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Ip Source Parameters : "); - - CopyIpAddrToClassifier(pstClassifierEntry, - pack_class_rule->u8IPMaskedSourceAddressLength, - pack_class_rule->u8IPMaskedSourceAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : false, - eSrcIpAddress); - - /* TOS */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "TOS Length:0x%X ", - pack_class_rule->u8IPTypeOfServiceLength); - if (pack_class_rule->u8IPTypeOfServiceLength == 3) { - pstClassifierEntry->ucIPTypeOfServiceLength = - pack_class_rule->u8IPTypeOfServiceLength; - pstClassifierEntry->ucTosLow = - pack_class_rule->u8IPTypeOfService[0]; - pstClassifierEntry->ucTosHigh = - pack_class_rule->u8IPTypeOfService[1]; - pstClassifierEntry->ucTosMask = - pack_class_rule->u8IPTypeOfService[2]; - pstClassifierEntry->bTOSValid = TRUE; - } - if (pack_class_rule->u8Protocol == 0) { - /* we didn't get protocol field filled in by the BS */ - pstClassifierEntry->ucProtocolLength = 0; - } else { - pstClassifierEntry->ucProtocolLength = 1; /* 1 valid protocol */ - } - - pstClassifierEntry->ucProtocol[0] = pack_class_rule->u8Protocol; - pstClassifierEntry->u8ClassifierRulePriority = - pack_class_rule->u8ClassifierRulePriority; - - /* store the classifier rule ID and set this classifier entry as valid */ - pstClassifierEntry->ucDirection = - Adapter->PackInfo[uiSearchRuleIndex].ucDirection; - pstClassifierEntry->uiClassifierRuleIndex = - ntohs(pack_class_rule->u16PacketClassificationRuleIndex); - pstClassifierEntry->usVCID_Value = - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - pstClassifierEntry->ulSFID = - Adapter->PackInfo[uiSearchRuleIndex].ulSFID; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Search Index %d Dir: %d, Index: %d, Vcid: %d\n", - uiSearchRuleIndex, - pstClassifierEntry->ucDirection, - pstClassifierEntry->uiClassifierRuleIndex, - pstClassifierEntry->usVCID_Value); - - if (pack_class_rule->u8AssociatedPHSI) - pstClassifierEntry->u8AssociatedPHSI = - pack_class_rule->u8AssociatedPHSI; - - /* Copy ETH CS Parameters */ - pstClassifierEntry->ucEthCSSrcMACLen = - (pack_class_rule->u8EthernetSourceMACAddressLength); - memcpy(pstClassifierEntry->au8EThCSSrcMAC, - pack_class_rule->u8EthernetSourceMACAddress, - MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSSrcMACMask, - pack_class_rule->u8EthernetSourceMACAddress - + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); - pstClassifierEntry->ucEthCSDestMACLen = - (pack_class_rule->u8EthernetDestMacAddressLength); - memcpy(pstClassifierEntry->au8EThCSDestMAC, - pack_class_rule->u8EthernetDestMacAddress, - MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSDestMACMask, - pack_class_rule->u8EthernetDestMacAddress - + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); - pstClassifierEntry->ucEtherTypeLen = - (pack_class_rule->u8EthertypeLength); - memcpy(pstClassifierEntry->au8EthCSEtherType, - pack_class_rule->u8Ethertype, - NUM_ETHERTYPE_BYTES); - memcpy(pstClassifierEntry->usUserPriority, - &pack_class_rule->u16UserPriority, 2); - pstClassifierEntry->usVLANID = - ntohs(pack_class_rule->u16VLANID); - pstClassifierEntry->usValidityBitMap = - ntohs(pack_class_rule->u16ValidityBitMap); - - pstClassifierEntry->bUsed = TRUE; - } -} - -/* - * @ingroup ctrl_pkt_functions - */ -static inline VOID DeleteClassifierRuleFromSF(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex, UINT nClassifierIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - B_UINT16 u16PacketClassificationRuleIndex; - USHORT usVCID; - /* VOID *pvPhsContext = NULL; */ - /*ULONG ulPhsStatus; */ - - usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - - if (nClassifierIndex > MAX_CLASSIFIERS-1) - return; - - if (usVCID == 0) - return; - - u16PacketClassificationRuleIndex = - Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex; - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if (pstClassifierEntry) { - pstClassifierEntry->bUsed = false; - pstClassifierEntry->uiClassifierRuleIndex = 0; - memset(pstClassifierEntry, 0, - sizeof(struct bcm_classifier_rule)); - - /* Delete the PHS Rule for this classifier */ - PhsDeleteClassifierRule(&Adapter->stBCMPhsContext, usVCID, - u16PacketClassificationRuleIndex); - } -} - -/* - * @ingroup ctrl_pkt_functions - */ -VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, - UINT uiSearchRuleIndex) -{ - struct bcm_classifier_rule *pstClassifierEntry = NULL; - int i; - /* B_UINT16 u16PacketClassificationRuleIndex; */ - USHORT ulVCID; - /* VOID *pvPhsContext = NULL; */ - /* ULONG ulPhsStatus; */ - - ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - - if (ulVCID == 0) - return; - - for (i = 0; i < MAX_CLASSIFIERS; i++) { - if (Adapter->astClassifierTable[i].usVCID_Value == ulVCID) { - pstClassifierEntry = &Adapter->astClassifierTable[i]; - - if (pstClassifierEntry->bUsed) - DeleteClassifierRuleFromSF(Adapter, - uiSearchRuleIndex, i); - } - } - - /* Delete All Phs Rules Associated with this SF */ - PhsDeleteSFRules(&Adapter->stBCMPhsContext, ulVCID); -} - -/* - * This routinue copies the Connection Management - * related data into the Adapter structure. - * @ingroup ctrl_pkt_functions - */ -static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* PackInfo[uiSearchRuleIndex]; - USHORT uVCID = curr_packinfo->usVCID_Value; - UINT UGIValue = 0; - - curr_packinfo->bValid = TRUE; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Search Rule Index = %d\n", uiSearchRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s: SFID= %x ", __func__, ntohl(psfLocalSet->u32SFID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Updating Queue %d", uiSearchRuleIndex); - - ulSFID = ntohl(psfLocalSet->u32SFID); - /* Store IP Version used */ - /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ - - curr_packinfo->bIPCSSupport = 0; - curr_packinfo->bEthCSSupport = 0; - - /* Enable IP/ETh CS Support As Required */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "CopyToAdapter : u8CSSpecification : %X\n", - psfLocalSet->u8CSSpecification); - switch (psfLocalSet->u8CSSpecification) { - case eCSPacketIPV4: - curr_packinfo->bIPCSSupport = IPV4_CS; - break; - case eCSPacketIPV6: - curr_packinfo->bIPCSSupport = IPV6_CS; - break; - case eCS802_3PacketEthernet: - case eCS802_1QPacketVLAN: - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - case eCSPacketIPV4Over802_1QVLAN: - case eCSPacketIPV4Over802_3Ethernet: - curr_packinfo->bIPCSSupport = IPV4_CS; - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - case eCSPacketIPV6Over802_1QVLAN: - case eCSPacketIPV6Over802_3Ethernet: - curr_packinfo->bIPCSSupport = IPV6_CS; - curr_packinfo->bEthCSSupport = ETH_CS_802_3; - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Error in value of CS Classification.. setting default to IP CS\n"); - curr_packinfo->bIPCSSupport = IPV4_CS; - break; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X\n", - uiSearchRuleIndex, - curr_packinfo->bEthCSSupport, - curr_packinfo->bIPCSSupport); - - /* Store IP Version used */ - /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ - if (curr_packinfo->bIPCSSupport == IPV6_CS) - curr_packinfo->ucIpVersion = IPV6; - else - curr_packinfo->ucIpVersion = IPV4; - - /* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */ - if (!Adapter->bETHCSEnabled) - curr_packinfo->bEthCSSupport = 0; - - if (psfLocalSet->u8ServiceClassNameLength > 0 && psfLocalSet->u8ServiceClassNameLength < 32) - memcpy(curr_packinfo->ucServiceClassName, - psfLocalSet->u8ServiceClassName, - psfLocalSet->u8ServiceClassNameLength); - - curr_packinfo->u8QueueType = psfLocalSet->u8ServiceFlowSchedulingType; - - if (curr_packinfo->u8QueueType == BE && curr_packinfo->ucDirection) - Adapter->usBestEffortQueueIndex = uiSearchRuleIndex; - - curr_packinfo->ulSFID = ntohl(psfLocalSet->u32SFID); - - curr_packinfo->u8TrafficPriority = psfLocalSet->u8TrafficPriority; - - /* copy all the classifier in the Service Flow param structure */ - for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Classifier index =%d", i); - psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Classifier index =%d", i); - - if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - curr_packinfo->bClassifierPriority = TRUE; - - if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - curr_packinfo->bClassifierPriority = TRUE; - - if (ucDsxType == DSA_ACK) { - eClassifierAction = eAddClassifier; - } else if (ucDsxType == DSC_ACK) { - switch (psfCSType->u8ClassfierDSCAction) { - case 0: /* DSC Add Classifier */ - eClassifierAction = eAddClassifier; - break; - case 1: /* DSC Replace Classifier */ - eClassifierAction = eReplaceClassifier; - break; - case 2: /* DSC Delete Classifier */ - eClassifierAction = eDeleteClassifier; - break; - default: - eClassifierAction = eInvalidClassifierAction; - } - } - - u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - switch (eClassifierAction) { - case eAddClassifier: - /* Get a Free Classifier Index From Classifier table for this SF to add the Classifier */ - /* Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, - ulSFID, - u16PacketClassificationRuleIndex); - - if (nClassifierIndex > MAX_CLASSIFIERS) { - nClassifierIndex = SearchFreeClsid(Adapter); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To get a free Entry */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "Error Failed To get a free Classifier Entry"); - break; - } - /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ - CopyClassifierRuleToSF(Adapter, psfCSType, - uiSearchRuleIndex, - nClassifierIndex); - } else { - /* This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, - DBG_LVL_ALL, - "CopyToAdapter: Error The Specified Classifier Already Exists and attempted To Add Classifier with Same PCRI : 0x%x\n", - u16PacketClassificationRuleIndex); - } - break; - case eReplaceClassifier: - /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ - /* with the new classifier Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, ulSFID, - u16PacketClassificationRuleIndex); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To search the classifier */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Error Search for Classifier To be replaced failed"); - break; - } - /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ - CopyClassifierRuleToSF(Adapter, psfCSType, - uiSearchRuleIndex, nClassifierIndex); - break; - case eDeleteClassifier: - /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ - /* with the new classifier Contained in this message */ - nClassifierIndex = SearchClsid(Adapter, ulSFID, - u16PacketClassificationRuleIndex); - if (nClassifierIndex > MAX_CLASSIFIERS) { - /* Failed To search the classifier */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CONN_MSG, DBG_LVL_ALL, - "Error Search for Classifier To be deleted failed"); - break; - } - - /* Delete This classifier */ - DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, - nClassifierIndex); - break; - default: - /* Invalid Action for classifier */ - break; - } - } - - /* Repeat parsing Classification Entries to process PHS Rules */ - for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { - psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "psfCSType->u8PhsDSCAction : 0x%x\n", - psfCSType->u8PhsDSCAction); - - switch (psfCSType->u8PhsDSCAction) { - case eDeleteAllPHSRules: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "Deleting All PHS Rules For VCID: 0x%X\n", - uVCID); - - /* Delete All the PHS rules for this Service flow */ - PhsDeleteSFRules(&Adapter->stBCMPhsContext, uVCID); - break; - case eDeletePHSRule: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "PHS DSC Action = Delete PHS Rule\n"); - - if (psfCSType->cPhsRule.u8PHSI) - PhsDeletePHSRule(&Adapter->stBCMPhsContext, - uVCID, - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - - break; - default: - if (ucDsxType == DSC_ACK) { - /* BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC\n",psfCSType->cPhsRule.u8PHSI)); */ - break; /* FOr DSC ACK Case PHS DSC Action must be in valid set */ - } - /* Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified */ - /* No Break Here . Intentionally! */ - - case eAddPHSRule: - case eSetPHSRule: - if (psfCSType->cPhsRule.u8PHSI) { - /* Apply This PHS Rule to all classifiers whose Associated PHSI Match */ - apply_phs_rule_to_all_classifiers(Adapter, - uiSearchRuleIndex, - uVCID, - &sPhsRule, - &psfCSType->cPhsRule, - pstAddIndication); - } - break; - } - } - - if (psfLocalSet->u32MaxSustainedTrafficRate == 0) { - /* No Rate Limit . Set Max Sustained Traffic Rate to Maximum */ - curr_packinfo->uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; - } else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > WIMAX_MAX_ALLOWED_RATE) { - /* Too large Allowed Rate specified. Limiting to Wi Max Allowed rate */ - curr_packinfo->uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; - } else { - curr_packinfo->uiMaxAllowedRate = - ntohl(psfLocalSet->u32MaxSustainedTrafficRate); - } - - curr_packinfo->uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency); - if (curr_packinfo->uiMaxLatency == 0) /* 0 should be treated as infinite */ - curr_packinfo->uiMaxLatency = MAX_LATENCY_ALLOWED; - - if ((curr_packinfo->u8QueueType == ERTPS || - curr_packinfo->u8QueueType == UGS)) - UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval); - - if (UGIValue == 0) - UGIValue = DEFAULT_UG_INTERVAL; - - /* - * For UGI based connections... - * DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host... - * The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput... - * In case of non-UGI based connection, 200 frames worth of data is the max token count at host... - */ - curr_packinfo->uiMaxBucketSize = - (DEFAULT_UGI_FACTOR*curr_packinfo->uiMaxAllowedRate*UGIValue)/1000; - - if (curr_packinfo->uiMaxBucketSize < WIMAX_MAX_MTU*8) { - UINT UGIFactor = 0; - /* Special Handling to ensure the biggest size of packet can go out from host to FW as follows: - * 1. Any packet from Host to FW can go out in different packet size. - * 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped. - * 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer - */ - UGIFactor = (curr_packinfo->uiMaxLatency/UGIValue + 1); - - if (UGIFactor > DEFAULT_UGI_FACTOR) - curr_packinfo->uiMaxBucketSize = - (UGIFactor*curr_packinfo->uiMaxAllowedRate*UGIValue)/1000; - - if (curr_packinfo->uiMaxBucketSize > WIMAX_MAX_MTU*8) - curr_packinfo->uiMaxBucketSize = WIMAX_MAX_MTU*8; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "LAT: %d, UGI: %d\n", curr_packinfo->uiMaxLatency, - UGIValue); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x", - curr_packinfo->uiMaxAllowedRate, - ntohl(psfLocalSet->u32MaxSustainedTrafficRate), - curr_packinfo->uiMaxBucketSize); - - /* copy the extended SF Parameters to Support MIBS */ - CopyMIBSExtendedSFParameters(Adapter, psfLocalSet, uiSearchRuleIndex); - - /* store header suppression enabled flag per SF */ - curr_packinfo->bHeaderSuppressionEnabled = - !(psfLocalSet->u8RequesttransmissionPolicy & - MASK_DISABLE_HEADER_SUPPRESSION); - - kfree(curr_packinfo->pstSFIndication); - curr_packinfo->pstSFIndication = pstAddIndication; - - /* Re Sort the SF list in PackInfo according to Traffic Priority */ - SortPackInfo(Adapter); - - /* Re Sort the Classifier Rules table and re - arrange - * according to Classifier Rule Priority - */ - SortClassifiers(Adapter); - DumpPhsRules(&Adapter->stBCMPhsContext); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s <=====", __func__); -} - -/*********************************************************************** - * Function - DumpCmControlPacket - * - * Description - This routinue Dumps the Contents of the AddIndication - * Structure in the Connection Management Control Packet - * - * Parameter - pvBuffer: Pointer to the buffer containing the - * AddIndication data. - * - * Returns - None - *************************************************************************/ -static VOID DumpCmControlPacket(PVOID pvBuffer) -{ - int uiLoopIndex; - int nIndex; - struct bcm_add_indication_alt *pstAddIndication; - UINT nCurClassifierCnt; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - pstAddIndication = pvBuffer; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID: 0x%X", ntohs(pstAddIndication->u16VCID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", htonl(pstAddIndication->sfAuthorizedSet.u32SFID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", htons(pstAddIndication->sfAuthorizedSet.u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[3], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4], - pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%X", pstAddIndication->sfAuthorizedSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%X", pstAddIndication->sfAuthorizedSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%X, %p", - pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate: 0x%X 0x%p", - pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate, - &pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAuthorizedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X", - pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfAuthorizedSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%X", pstAddIndication->sfAuthorizedSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%X", pstAddIndication->sfAuthorizedSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%X", - pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAuthorizedSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAuthorizedSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval: 0x%X", - pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", - *(unsigned int *)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, - *(unsigned int *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4], - *(USHORT *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%X", - pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead); - if (!pstAddIndication->sfAuthorizedSet.bValid) - pstAddIndication->sfAuthorizedSet.bValid = 1; - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - - psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex]; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); - - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetDestMacAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetSourceMACAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", - 6, psfCSType->cCPacketClassificationRule. - u8IPv6FlowLable); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%02X", pstAddIndication->sfAuthorizedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfAdmittedSet.u32SFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", - pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - "u8ServiceClassName: 0x%*ph", - 6, pstAddIndication->sfAdmittedSet.u8ServiceClassName); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", - pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", - pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAdmittedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAdmittedSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%02X", pstAddIndication->sfAdmittedSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%02X", pstAddIndication->sfAdmittedSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%02X", pstAddIndication->sfAdmittedSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%02X", - pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAdmittedSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAdmittedSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%02X", - pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAdmittedSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - - psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%*ph", - 3, psfCSType->cCPacketClassificationRule. - u8IPTypeOfService); - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%*ph ", - 4, psfCSType->cCPacketClassificationRule. - u8ProtocolSourcePortRange); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%*ph ", - 4, psfCSType->cCPacketClassificationRule. - u8ProtocolDestPortRange); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetDestMacAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: %pM", - psfCSType->cCPacketClassificationRule. - u8EthernetSourceMACAddress); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8Ethertype[3]: 0x%*ph", - 3, psfCSType->cCPacketClassificationRule. - u8Ethertype); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%02X", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x%*ph ", - 6, psfCSType->cCPacketClassificationRule. - u8IPv6FlowLable); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%X", pstAddIndication->sfAdmittedSet.bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - "u8ServiceClassName: 0x%*ph", - 6, pstAddIndication->sfActiveSet.u8ServiceClassName); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfActiveSet.u8TrafficPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfActiveSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", - pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", - pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfActiveSet.u32ToleratedJitter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfActiveSet.u32MaximumLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfActiveSet.u8SDUSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID: 0x%X", pstAddIndication->sfActiveSet.u16TargetSAID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable: 0x%X", pstAddIndication->sfActiveSet.u8ARQEnable); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQWindowSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfActiveSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification: 0x%X", pstAddIndication->sfActiveSet.u8CSSpecification); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService: 0x%X", - pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfActiveSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase: 0x%X", pstAddIndication->sfActiveSet.u16TimeBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference: 0x%X", pstAddIndication->sfActiveSet.u8PagingPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference: 0x%X", - pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfActiveSet.u8TotalClassifiers); - - nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers; - if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - - for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { - struct bcm_convergence_types *psfCSType = NULL; - struct bcm_packet_class_rules *clsRule = NULL; - - psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; - clsRule = &psfCSType->cCPacketClassificationRule; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8ClassifierRulePriority: 0x%X ", - clsRule->u8ClassifierRulePriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8IPTypeOfServiceLength: 0x%X ", - clsRule->u8IPTypeOfServiceLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", - clsRule->u8IPTypeOfService[0], - clsRule->u8IPTypeOfService[1], - clsRule->u8IPTypeOfService[2]); - - for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8Protocol: 0x%X ", - clsRule->u8Protocol); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPMaskedSourceAddressLength: 0x%X ", - clsRule->u8IPMaskedSourceAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPMaskedSourceAddress[32]: 0x%X ", - clsRule->u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8IPDestinationAddressLength: 0x%02X ", - clsRule->u8IPDestinationAddressLength); - - for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPDestinationAddress[32]:0x%X ", - clsRule->u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolSourcePortRangeLength: 0x%X ", - clsRule->u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolSourcePortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8ProtocolSourcePortRange[0], - clsRule->u8ProtocolSourcePortRange[1], - clsRule->u8ProtocolSourcePortRange[2], - clsRule->u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolDestPortRangeLength: 0x%X ", - clsRule->u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8ProtocolDestPortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8ProtocolDestPortRange[0], - clsRule->u8ProtocolDestPortRange[1], - clsRule->u8ProtocolDestPortRange[2], - clsRule->u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetDestMacAddressLength: 0x%X ", - clsRule->u8EthernetDestMacAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetDestMacAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - clsRule->u8EthernetDestMacAddress[0], - clsRule->u8EthernetDestMacAddress[1], - clsRule->u8EthernetDestMacAddress[2], - clsRule->u8EthernetDestMacAddress[3], - clsRule->u8EthernetDestMacAddress[4], - clsRule->u8EthernetDestMacAddress[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8EthernetSourceMACAddressLength: 0x%X ", - clsRule->u8EthernetDestMacAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - "u8EthernetSourceMACAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - clsRule->u8EthernetSourceMACAddress[0], - clsRule->u8EthernetSourceMACAddress[1], - clsRule->u8EthernetSourceMACAddress[2], - clsRule->u8EthernetSourceMACAddress[3], - clsRule->u8EthernetSourceMACAddress[4], - clsRule->u8EthernetSourceMACAddress[5]); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8EthertypeLength: 0x%X ", - clsRule->u8EthertypeLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8Ethertype[3]: 0x%X ,0x%X ,0x%X ", - clsRule->u8Ethertype[0], - clsRule->u8Ethertype[1], - clsRule->u8Ethertype[2]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u16UserPriority: 0x%X ", - clsRule->u16UserPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u16VLANID: 0x%X ", - clsRule->u16VLANID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8AssociatedPHSI: 0x%X ", - clsRule->u8AssociatedPHSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u16PacketClassificationRuleIndex:0x%X ", - clsRule->u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8VendorSpecificClassifierParamLength:0x%X ", - clsRule->u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8VendorSpecificClassifierParam[1]:0x%X ", - clsRule->u8VendorSpecificClassifierParam[0]); -#ifdef VERSION_D5 - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, " u8IPv6FlowLableLength: 0x%X ", - clsRule->u8IPv6FlowLableLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, - DBG_LVL_ALL, - " u8IPv6FlowLable[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ", - clsRule->u8IPv6FlowLable[0], - clsRule->u8IPv6FlowLable[1], - clsRule->u8IPv6FlowLable[2], - clsRule->u8IPv6FlowLable[3], - clsRule->u8IPv6FlowLable[4], - clsRule->u8IPv6FlowLable[5]); -#endif - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, - " bValid: 0x%X", pstAddIndication->sfActiveSet.bValid); -} - -static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter, - ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer) -{ - UINT nBytesToRead = sizeof(struct bcm_connect_mgr_params); - - if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Got Param address as 0!!"); - return 0; - } - ulAddrSFParamSet = ntohl(ulAddrSFParamSet); - - /* Read out the SF Param Set At the indicated Location */ - if (rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) - return STATUS_FAILURE; - - return 1; -} - -static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, - ULONG ulAddrSFParamSet) -{ - UINT nBytesToWrite = sizeof(struct bcm_connect_mgr_params); - int ret = 0; - - if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) - return 0; - - ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite); - if (ret < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "%s:%d WRM failed", __func__, __LINE__); - return ret; - } - return 1; -} - -ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, - PVOID pvBuffer, UINT *puBufferLength) -{ - struct bcm_add_indication_alt *pstAddIndicationAlt = NULL; - struct bcm_add_indication *pstAddIndication = NULL; - struct bcm_del_request *pstDeletionRequest; - UINT uiSearchRuleIndex; - ULONG ulSFID; - - pstAddIndicationAlt = pvBuffer; - - /* - * In case of DSD Req By MS, we should immediately delete this SF so that - * we can stop the further classifying the pkt for this SF. - */ - if (pstAddIndicationAlt->u8Type == DSD_REQ) { - pstDeletionRequest = pvBuffer; - - ulSFID = ntohl(pstDeletionRequest->u32SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - deleteSFBySfid(Adapter, uiSearchRuleIndex); - Adapter->u32TotalDSD++; - } - return 1; - } - - if ((pstAddIndicationAlt->u8Type == DSD_RSP) || - (pstAddIndicationAlt->u8Type == DSD_ACK)) { - /* No Special handling send the message as it is */ - return 1; - } - /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */ - - pstAddIndication = kmalloc(sizeof(struct bcm_add_indication), - GFP_KERNEL); - if (pstAddIndication == NULL) - return 0; - - /* AUTHORIZED SET */ - pstAddIndication->psfAuthorizedSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfAuthorizedSet) { - kfree(pstAddIndication); - return 0; - } - - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet, - (ULONG)pstAddIndication->psfAuthorizedSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - /* this can't possibly be right */ - pstAddIndication->psfAuthorizedSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG)pstAddIndication->psfAuthorizedSet); - - if (pstAddIndicationAlt->u8Type == DSA_REQ) { - struct bcm_add_request AddRequest; - - AddRequest.u8Type = pstAddIndicationAlt->u8Type; - AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction; - AddRequest.u16TID = pstAddIndicationAlt->u16TID; - AddRequest.u16CID = pstAddIndicationAlt->u16CID; - AddRequest.u16VCID = pstAddIndicationAlt->u16VCID; - AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet; - (*puBufferLength) = sizeof(struct bcm_add_request); - memcpy(pvBuffer, &AddRequest, sizeof(struct bcm_add_request)); - kfree(pstAddIndication); - return 1; - } - - /* Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt */ - /* We need to extract the structure from the buffer and pack it differently */ - - pstAddIndication->u8Type = pstAddIndicationAlt->u8Type; - pstAddIndication->eConnectionDir = pstAddIndicationAlt->u8Direction; - pstAddIndication->u16TID = pstAddIndicationAlt->u16TID; - pstAddIndication->u16CID = pstAddIndicationAlt->u16CID; - pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID; - pstAddIndication->u8CC = pstAddIndicationAlt->u8CC; - - /* ADMITTED SET */ - pstAddIndication->psfAdmittedSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfAdmittedSet) { - kfree(pstAddIndication); - return 0; - } - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAdmittedSet, - (ULONG)pstAddIndication->psfAdmittedSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - pstAddIndication->psfAdmittedSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG) pstAddIndication->psfAdmittedSet); - - /* ACTIVE SET */ - pstAddIndication->psfActiveSet = (struct bcm_connect_mgr_params *) - GetNextTargetBufferLocation(Adapter, - pstAddIndicationAlt->u16TID); - if (!pstAddIndication->psfActiveSet) { - kfree(pstAddIndication); - return 0; - } - if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfActiveSet, - (ULONG)pstAddIndication->psfActiveSet) != 1) { - kfree(pstAddIndication); - return 0; - } - - pstAddIndication->psfActiveSet = - (struct bcm_connect_mgr_params *) ntohl( - (ULONG)pstAddIndication->psfActiveSet); - - (*puBufferLength) = sizeof(struct bcm_add_indication); - *(struct bcm_add_indication *)pvBuffer = *pstAddIndication; - kfree(pstAddIndication); - return 1; -} - -static inline struct bcm_add_indication_alt -*RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, - register PVOID pvBuffer) -{ - ULONG ulStatus = 0; - struct bcm_add_indication *pstAddIndication = NULL; - struct bcm_add_indication_alt *pstAddIndicationDest = NULL; - - pstAddIndication = pvBuffer; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "=====>"); - if ((pstAddIndication->u8Type == DSD_REQ) || - (pstAddIndication->u8Type == DSD_RSP) || - (pstAddIndication->u8Type == DSD_ACK)) - return pvBuffer; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Inside RestoreCmControlResponseMessage "); - /* - * Need to Allocate memory to contain the SUPER Large structures - * Our driver can't create these structures on Stack :( - */ - pstAddIndicationDest = kmalloc(sizeof(struct bcm_add_indication_alt), - GFP_KERNEL); - - if (pstAddIndicationDest) { - memset(pstAddIndicationDest, 0, - sizeof(struct bcm_add_indication_alt)); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "Failed to allocate memory for SF Add Indication Structure "); - return NULL; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8Type : 0x%X", - pstAddIndication->u8Type); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8Direction : 0x%X", - pstAddIndication->eConnectionDir); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8TID : 0x%X", - ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u8CID : 0x%X", - ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-u16VCID : 0x%X", - ntohs(pstAddIndication->u16VCID)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-autorized set loc : %p", - pstAddIndication->psfAuthorizedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-admitted set loc : %p", - pstAddIndication->psfAdmittedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "AddIndication-Active set loc : %p", - pstAddIndication->psfActiveSet); - - pstAddIndicationDest->u8Type = pstAddIndication->u8Type; - pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir; - pstAddIndicationDest->u16TID = pstAddIndication->u16TID; - pstAddIndicationDest->u16CID = pstAddIndication->u16CID; - pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID; - pstAddIndicationDest->u8CC = pstAddIndication->u8CC; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Active Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfActiveSet, - (PUCHAR)&pstAddIndicationDest->sfActiveSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Admitted Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfAdmittedSet, - (PUCHAR)&pstAddIndicationDest->sfAdmittedSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Restoring Authorized Set "); - ulStatus = RestoreSFParam(Adapter, - (ULONG)pstAddIndication->psfAuthorizedSet, - (PUCHAR)&pstAddIndicationDest->sfAuthorizedSet); - if (ulStatus != 1) - goto failed_restore_sf_param; - - if (pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) - pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = - MAX_CLASSIFIERS_IN_SF; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Dumping the whole raw packet"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "============================================================"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - " pstAddIndicationDest->sfActiveSet size %zx %p", - sizeof(*pstAddIndicationDest), pstAddIndicationDest); - /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, - * DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, - * sizeof(*pstAddIndicationDest)); - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "============================================================"); - return pstAddIndicationDest; -failed_restore_sf_param: - kfree(pstAddIndicationDest); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "<====="); - return NULL; -} - -ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) -{ - ULONG ulTargetDsxBuffersBase = 0; - ULONG ulCntTargetBuffers; - ULONG i; - int Status; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Adapter was NULL!!!"); - return 0; - } - - if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) - return 1; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Size of Each DSX Buffer(Also size of connection manager parameters): %zx ", - sizeof(struct bcm_connect_mgr_params)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Reading DSX buffer From Target location %x ", - DSX_MESSAGE_EXCHANGE_BUFFER); - - Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, - (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); - if (Status < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "RDM failed!!"); - return 0; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Base Address Of DSX Target Buffer : 0x%lx", - ulTargetDsxBuffersBase); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase); - ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / - sizeof(struct bcm_connect_mgr_params); - - Adapter->ulTotalTargetBuffersAvailable = - ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ? - MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - " Total Target DSX Buffer setup %lx ", - Adapter->ulTotalTargetBuffersAvailable); - - for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { - Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase; - Adapter->astTargetDsxBuffer[i].valid = 1; - Adapter->astTargetDsxBuffer[i].tid = 0; - ulTargetDsxBuffersBase += sizeof(struct bcm_connect_mgr_params); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", - i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer); - } - Adapter->ulCurrentTargetBuffer = 0; - Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable; - return 1; -} - -static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, - B_UINT16 tid) -{ - ULONG dsx_buf; - ULONG idx, max_try; - - if ((Adapter->ulTotalTargetBuffersAvailable == 0) - || (Adapter->ulFreeTargetBufferCnt == 0)) { - ClearTargetDSXBuffer(Adapter, tid, false); - return 0; - } - - idx = Adapter->ulCurrentTargetBuffer; - max_try = Adapter->ulTotalTargetBuffersAvailable; - while ((max_try) && (Adapter->astTargetDsxBuffer[idx].valid != 1)) { - idx = (idx+1) % Adapter->ulTotalTargetBuffersAvailable; - max_try--; - } - - if (max_try == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", - Adapter->ulFreeTargetBufferCnt); - ClearTargetDSXBuffer(Adapter, tid, false); - return 0; - } - - dsx_buf = Adapter->astTargetDsxBuffer[idx].ulTargetDsxBuffer; - Adapter->astTargetDsxBuffer[idx].valid = 0; - Adapter->astTargetDsxBuffer[idx].tid = tid; - Adapter->ulFreeTargetBufferCnt--; - idx = (idx+1)%Adapter->ulTotalTargetBuffersAvailable; - Adapter->ulCurrentTargetBuffer = idx; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "GetNextTargetBufferLocation :Returning address %lx tid %d\n", - dsx_buf, tid); - - return dsx_buf; -} - -int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) -{ - /* - * Need to Allocate memory to contain the SUPER Large structures - * Our driver can't create these structures on Stack - */ - Adapter->caDsxReqResp = kmalloc(sizeof(struct bcm_add_indication_alt) - + LEADER_SIZE, GFP_KERNEL); - if (!Adapter->caDsxReqResp) - return -ENOMEM; - - return 0; -} - -int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) -{ - kfree(Adapter->caDsxReqResp); - return 0; -} - -/* - * @ingroup ctrl_pkt_functions - * This routinue would process the Control responses - * for the Connection Management. - * @return - Queue index for the free SFID else returns Invalid Index. - */ -bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); - return false; - } - - DumpCmControlPacket(pstAddIndication); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>"); - pLeader = (struct bcm_leader *)Adapter->caDsxReqResp; - - pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; - pLeader->Vcid = 0; - - ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID); - switch (pstAddIndication->u8Type) { - case DSA_REQ: - pLeader->PLength = sizeof(struct bcm_add_indication_alt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength); - *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - kfree(pstAddIndication); - break; - case DSA_RSP: - pLeader->PLength = sizeof(struct bcm_add_indication_alt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", - pLeader->PLength); - *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; - /* FALLTHROUGH */ - case DSA_ACK: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X", - ntohs(pstAddIndication->u16VCID)); - uiSearchRuleIndex = SearchFreeSfid(Adapter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiSearchRuleIndex:0x%X ", - uiSearchRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Direction:0x%X ", - pstAddIndication->u8Direction); - if (uiSearchRuleIndex < NO_OF_QUEUES) { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = - pstAddIndication->u8Direction; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ", - pstAddIndication->sfActiveSet.bValid); - if (pstAddIndication->sfActiveSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; - - if (pstAddIndication->sfAuthorizedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; - - if (pstAddIndication->sfAdmittedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - - if (pstAddIndication->sfActiveSet.bValid == false) { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false; - if (pstAddIndication->sfAdmittedSet.bValid) - psfLocalSet = &pstAddIndication->sfAdmittedSet; - else if (pstAddIndication->sfAuthorizedSet.bValid) - psfLocalSet = &pstAddIndication->sfAuthorizedSet; - } else { - psfLocalSet = &pstAddIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; - } - - if (!psfLocalSet) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } else if (psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK"); - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstAddIndication->u16VCID); - Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstAddIndication->u16CID); - - if (UPLINK_DIR == pstAddIndication->u8Direction) - atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT); - - CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSA_ACK, pstAddIndication); - /* don't free pstAddIndication */ - - /* Inside CopyToAdapter, Sorting of all the SFs take place. - * Hence any access to the newly added SF through uiSearchRuleIndex is invalid. - * SHOULD BE STRICTLY AVOIDED. - */ - /* *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; */ - memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4); - - if (pstAddIndication->sfActiveSet.bValid == TRUE) { - if (UPLINK_DIR == pstAddIndication->u8Direction) { - if (!Adapter->LinkUpStatus) { - netif_carrier_on(Adapter->dev); - netif_start_queue(Adapter->dev); - Adapter->LinkUpStatus = 1; - if (netif_msg_link(Adapter)) - pr_info(PFX "%s: link up\n", Adapter->dev->name); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - Adapter->liTimeSinceLastNetEntry = get_seconds(); - } - } - } - } else { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); - kfree(pstAddIndication); - return false; - } - break; - case DSC_REQ: - pLeader->PLength = sizeof(struct bcm_change_indication); - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); - - *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; - - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - kfree(pstAddIndication); - break; - case DSC_RSP: - pLeader->PLength = sizeof(struct bcm_change_indication); - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); - *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; - /* FALLTHROUGH */ - case DSC_ACK: - pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; - uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID)); - if (uiSearchRuleIndex > NO_OF_QUEUES-1) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction; - if (pstChangeIndication->sfActiveSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; - - if (pstChangeIndication->sfAuthorizedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; - - if (pstChangeIndication->sfAdmittedSet.bValid == TRUE) - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - - if (pstChangeIndication->sfActiveSet.bValid == false) { - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = false; - - if (pstChangeIndication->sfAdmittedSet.bValid) - psfLocalSet = &pstChangeIndication->sfAdmittedSet; - else if (pstChangeIndication->sfAuthorizedSet.bValid) - psfLocalSet = &pstChangeIndication->sfAuthorizedSet; - } else { - psfLocalSet = &pstChangeIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; - } - - if (!psfLocalSet) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); - Adapter->PackInfo[uiSearchRuleIndex].bActive = false; - Adapter->PackInfo[uiSearchRuleIndex].bValid = false; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; - kfree(pstAddIndication); - } else if (psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) { - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstChangeIndication->u16VCID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n", - pstChangeIndication->u8CC, psfLocalSet->bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID)); - Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstChangeIndication->u16CID); - CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSC_ACK, pstAddIndication); - - *(PULONG)(((PUCHAR)pvBuffer)+1) = psfLocalSet->u32SFID; - } else if (pstChangeIndication->u8CC == 6) { - deleteSFBySfid(Adapter, uiSearchRuleIndex); - kfree(pstAddIndication); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); - kfree(pstAddIndication); - return false; - } - break; - case DSD_REQ: - pLeader->PLength = sizeof(struct bcm_del_indication); - *((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((struct bcm_del_indication *)pstAddIndication); - - ulSFID = ntohl(((struct bcm_del_indication *)pstAddIndication)->u32SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex); - - if (uiSearchRuleIndex < NO_OF_QUEUES) { - /* Delete All Classifiers Associated with this SFID */ - deleteSFBySfid(Adapter, uiSearchRuleIndex); - Adapter->u32TotalDSD++; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC"); - ((struct bcm_del_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; - CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); - /* FALLTHROUGH */ - case DSD_RSP: - /* Do nothing as SF has already got Deleted */ - break; - case DSD_ACK: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n"); - break; - default: - kfree(pstAddIndication); - return false; - } - return TRUE; -} - -int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, - UINT uiSFId, void __user *user_buffer) -{ - int status = 0; - struct bcm_packet_info *psSfInfo = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "status =%d", status); - status = SearchSfid(Adapter, uiSFId); - if (status >= NO_OF_QUEUES) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "SFID %d not present in queue !!!", uiSFId); - return -EINVAL; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "status =%d", status); - psSfInfo = &Adapter->PackInfo[status]; - if (psSfInfo->pstSFIndication - && copy_to_user(user_buffer, psSfInfo->pstSFIndication, - sizeof(struct bcm_add_indication_alt))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "copy to user failed SFID %d, present in queue !!!", - uiSFId); - status = -EFAULT; - return status; - } - return STATUS_SUCCESS; -} - -VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, - PUINT puiBuffer) -{ - B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); - struct bcm_stim_sfhostnotify *pHostInfo = NULL; - UINT uiSearchRuleIndex = 0; - ULONG ulSFID = 0; - - puiBuffer += 2; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "u32NumofSFsinMsg: 0x%x\n", u32NumofSFsinMsg); - - while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) { - u32NumofSFsinMsg--; - pHostInfo = (struct bcm_stim_sfhostnotify *)puiBuffer; - puiBuffer = (PUINT)(pHostInfo + 1); - - ulSFID = ntohl(pHostInfo->SFID); - uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "SFID: 0x%lx\n", ulSFID); - - if (uiSearchRuleIndex >= NO_OF_QUEUES - || uiSearchRuleIndex == HiPriority) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "The SFID <%lx> doesn't exist in host entry or is Invalid\n", - ulSFID); - continue; - } - - if (pHostInfo->RetainSF == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "Going to Delete SF"); - deleteSFBySfid(Adapter, uiSearchRuleIndex); - } else { - struct bcm_packet_info *packinfo = - &Adapter->PackInfo[uiSearchRuleIndex]; - - packinfo->usVCID_Value = ntohs(pHostInfo->VCID); - packinfo->usCID = ntohs(pHostInfo->newCID); - packinfo->bActive = false; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, - "pHostInfo->QoSParamSet: 0x%x\n", - pHostInfo->QoSParamSet); - - if (pHostInfo->QoSParamSet & 0x1) - packinfo->bAuthorizedSet = TRUE; - if (pHostInfo->QoSParamSet & 0x2) - packinfo->bAdmittedSet = TRUE; - if (pHostInfo->QoSParamSet & 0x4) { - packinfo->bActiveSet = TRUE; - packinfo->bActive = TRUE; - } - } - } -} - -static void restore_endianess_of_pstClassifierEntry( - struct bcm_classifier_rule *pstClassifierEntry, - enum bcm_ipaddr_context eIpAddrContext) -{ - int i; - union u_ip_address *stSrc = &pstClassifierEntry->stSrcIpAddress; - union u_ip_address *stDest = &pstClassifierEntry->stDestIpAddress; - - for (i = 0; i < MAX_IP_RANGE_LENGTH * 4; i++) { - if (eIpAddrContext == eSrcIpAddress) { - stSrc->ulIpv6Addr[i] = ntohl(stSrc->ulIpv6Addr[i]); - stSrc->ulIpv6Mask[i] = ntohl(stSrc->ulIpv6Mask[i]); - } else if (eIpAddrContext == eDestIpAddress) { - stDest->ulIpv6Addr[i] = ntohl(stDest->ulIpv6Addr[i]); - stDest->ulIpv6Mask[i] = ntohl(stDest->ulIpv6Mask[i]); - } - } -} - -static void apply_phs_rule_to_all_classifiers( - register struct bcm_mini_adapter *Adapter, /* u8Direction == UPLINK_DIR) { - for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { - curr_classifier = - &Adapter->astClassifierTable[uiClassifierIndex]; - if ((curr_classifier->bUsed) && - (curr_classifier->ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) && - (curr_classifier->u8AssociatedPHSI == cPhsRule->u8PHSI)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, - "Adding PHS Rule For Classifier: 0x%x cPhsRule.u8PHSI: 0x%x\n", - curr_classifier->uiClassifierRuleIndex, - cPhsRule->u8PHSI); - /* Update The PHS Rule for this classifier as Associated PHSI id defined */ - - /* Copy the PHS Rule */ - sPhsRule->u8PHSI = cPhsRule->u8PHSI; - sPhsRule->u8PHSFLength = cPhsRule->u8PHSFLength; - sPhsRule->u8PHSMLength = cPhsRule->u8PHSMLength; - sPhsRule->u8PHSS = cPhsRule->u8PHSS; - sPhsRule->u8PHSV = cPhsRule->u8PHSV; - memcpy(sPhsRule->u8PHSF, cPhsRule->u8PHSF, MAX_PHS_LENGTHS); - memcpy(sPhsRule->u8PHSM, cPhsRule->u8PHSM, MAX_PHS_LENGTHS); - sPhsRule->u8RefCnt = 0; - sPhsRule->bUnclassifiedPHSRule = false; - sPhsRule->PHSModifiedBytes = 0; - sPhsRule->PHSModifiedNumPackets = 0; - sPhsRule->PHSErrorNumPackets = 0; - - /* bPHSRuleAssociated = TRUE; */ - /* Store The PHS Rule for this classifier */ - - PhsUpdateClassifierRule( - &Adapter->stBCMPhsContext, - uVCID, - curr_classifier->uiClassifierRuleIndex, - sPhsRule, - curr_classifier->u8AssociatedPHSI); - - /* Update PHS Rule For the Classifier */ - if (sPhsRule->u8PHSI) { - curr_classifier->u32PHSRuleID = sPhsRule->u8PHSI; - memcpy(&curr_classifier->sPhsRule, sPhsRule, sizeof(struct bcm_phs_rule)); - } - } - } - } else { - /* Error PHS Rule specified in signaling could not be applied to any classifier */ - - /* Copy the PHS Rule */ - sPhsRule->u8PHSI = cPhsRule->u8PHSI; - sPhsRule->u8PHSFLength = cPhsRule->u8PHSFLength; - sPhsRule->u8PHSMLength = cPhsRule->u8PHSMLength; - sPhsRule->u8PHSS = cPhsRule->u8PHSS; - sPhsRule->u8PHSV = cPhsRule->u8PHSV; - memcpy(sPhsRule->u8PHSF, cPhsRule->u8PHSF, MAX_PHS_LENGTHS); - memcpy(sPhsRule->u8PHSM, cPhsRule->u8PHSM, MAX_PHS_LENGTHS); - sPhsRule->u8RefCnt = 0; - sPhsRule->bUnclassifiedPHSRule = TRUE; - sPhsRule->PHSModifiedBytes = 0; - sPhsRule->PHSModifiedNumPackets = 0; - sPhsRule->PHSErrorNumPackets = 0; - /* Store The PHS Rule for this classifier */ - - /* - * Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule, - * clsid will be zero hence we can't have multiple PHS rules for the same SF. - * To support multiple PHS rule, passing u8PHSI. - */ - PhsUpdateClassifierRule( - &Adapter->stBCMPhsContext, - uVCID, - sPhsRule->u8PHSI, - sPhsRule, - sPhsRule->u8PHSI); - } -} diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h deleted file mode 100644 index 0887d3f49e2f..000000000000 --- a/drivers/staging/bcm/CmHost.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * (c) Beceem Communications Inc. - * All Rights Reserved - * - * file : CmHost.h - * author: Rajeev Tirumala - * date : September 8 , 2006 - * brief : Definitions for Connection Management Requests structure - * which we will use to setup our connection structures.Its high - * time we had a header file for CmHost.cpp to isolate the way - * f/w sends DSx messages and the way we interpret them in code. - * Revision History - * - * Date Author Version Description - * 08-Sep-06 Rajeev 0.1 Created - ***************************************************************************/ -#ifndef _CM_HOST_H -#define _CM_HOST_H - -#pragma once -#pragma pack(push, 4) - -#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ -#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ - -struct bcm_add_indication_alt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - u16 u16CID; - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; - u8 u8CC; /* < Confirmation Code */ - u8 u8Padd; - u16 u16Padd; -}; - -struct bcm_change_indication { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - u16 u16CID; - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; - u8 u8CC; /* < Confirmation Code */ - u8 u8Padd; - u16 u16Padd; -}; - -unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength); -int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); -bool CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer); - -#pragma pack(pop) - -#endif diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c deleted file mode 100644 index 4226c931cd45..000000000000 --- a/drivers/staging/bcm/DDRInit.c +++ /dev/null @@ -1,1355 +0,0 @@ -#include "headers.h" - - - -#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00 -#define MIPS_CLOCK_REG 0x0f000820 - -/* DDR INIT-133Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0F000800, 0x00007212}, - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00000F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a04C, 0x0000000C}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020202}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x110a0200}, - {0x0F00703C, 0x02101010}, - {0x0F007040, 0x45751200}, - {0x0F007044, 0x110a0d00}, - {0x0F007048, 0x081b0306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010246c}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; -/* 80Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07f1ffff}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a000, 0x00000016}, - {0x0F00a04C, 0x0000000C}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01000000}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x02020201}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x04000000}, - {0x0F007034, 0x00000002}, - {0x0F007038, 0x1F060200}, - {0x0F00703C, 0x1C22221F}, - {0x0F007040, 0x8A006600}, - {0x0F007044, 0x221a0800}, - {0x0F007048, 0x02690204}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x000A15D6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00004000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; -/* 100Mhz */ -#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0F000800, 0x00007008}, - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13E3F}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a04C, 0x0000000C}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020201}, - {0x0F00702c, 0x0204040A}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x20080200}, - {0x0F00703C, 0x02030320}, - {0x0F007040, 0x6E7F1200}, - {0x0F007044, 0x01190A00}, - {0x0F007048, 0x06120305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001C}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -/* Net T3B DDR Settings - * DDR INIT-133Mhz - */ -static struct bcm_ddr_setting asDPLL_266MHZ[] = { - {0x0F000800, 0x00007212}, - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00000F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF1B00}, - {0x0f000870, 0x00000002} -}; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000810, 0x00000F95}, - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13652}, - {0x0f000840, 0x0FFF0800}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020202}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x130a0200}, - {0x0F00703C, 0x02101012}, - {0x0F007040, 0x457D1200}, - {0x0F007044, 0x11130d00}, - {0x0F007048, 0x040D0306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0000001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010246c}, - {0x0F007064, 0x00000012}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000}, - }; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F13FFF}, - {0x0f000840, 0x0FFF1F00}, - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00a000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01000000}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x02020201}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x04000000}, - {0x0F007034, 0x02000002}, - {0x0F007038, 0x1F060202}, - {0x0F00703C, 0x1C22221F}, - {0x0F007040, 0x8A006600}, - {0x0F007044, 0x221a0800}, - {0x0F007048, 0x02690204}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x000A15D6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00004000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -/* 100Mhz */ -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00000F95}, - {0x0f000820, 0x07F1369B}, - {0x0f000840, 0x0FFF0800}, - {0x0f000880, 0x000003DD}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020201}, - {0x0F00702c, 0x0204040A}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x02000004}, - {0x0F007038, 0x20080200}, - {0x0F00703C, 0x02030320}, - {0x0F007040, 0x6E7F1200}, - {0x0F007044, 0x01190A00}, - {0x0F007048, 0x06120305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001C}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00000104}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F1365B}, - {0x0f000810, 0x00002F95}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020200}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x200a0200}, - {0x0F00703C, 0x02101020}, - {0x0F007040, 0x45711200}, - {0x0F007044, 0x110D0D00}, - {0x0F007048, 0x04080306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010245F}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00040000}, - {0x0F007098, 0x00000000}, - {0x0F0070c8, 0x00000104}, - /* Enable 2 ports within X-bar */ - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00002F95}, - {0x0f000820, 0x03F1369B}, - {0x0f000840, 0x0fff0000}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020200}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x1F080200}, - {0x0F00703C, 0x0203031F}, - {0x0F007040, 0x6e001200}, - {0x0F007044, 0x011a0a00}, - {0x0F007048, 0x03000305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - {0x0F007094, 0x00010000}, - {0x0F007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00002F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF1F00}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0F00a084, 0x1Cffffff}, - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000000}, - {0x0f007008, 0x01000001}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000000}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04020107}, - {0x0f007024, 0x00000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0204040a}, - {0x0f007030, 0x04000000}, - {0x0f007034, 0x00000002}, - {0x0f007038, 0x1d060200}, - {0x0f00703c, 0x1c22221d}, - {0x0f007040, 0x8A116600}, - {0x0f007044, 0x222d0800}, - {0x0f007048, 0x02690204}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0100001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x000A15D6}, - {0x0f007064, 0x0000000A}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00004000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00010000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - - - -/* T3 LP-B (UMA-B) */ - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F137DB}, - {0x0f000810, 0x01842795}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF0400}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* this is flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* Now dump from her in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000001}, - {0x0f007008, 0x01000101}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000100}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04030107}, - {0x0f007024, 0x02000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0206060a}, - {0x0f007030, 0x050d0d00}, - {0x0f007034, 0x00000003}, - {0x0f007038, 0x170a0200}, - {0x0f00703c, 0x02101012}, - {0x0f007040, 0x45161200}, - {0x0f007044, 0x11250c00}, - {0x0f007048, 0x04da0307}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0000001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x00142bb6}, - {0x0f007064, 0x20430014}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00009000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00040000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x03F1365B}, - {0x0f000810, 0x00002F95}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0f000860, 0x00000000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020001}, - {0x0F007020, 0x04030107}, - {0x0F007024, 0x02000007}, - {0x0F007028, 0x02020200}, - {0x0F00702c, 0x0206060a}, - {0x0F007030, 0x05000000}, - {0x0F007034, 0x00000003}, - {0x0F007038, 0x190a0200}, - {0x0F00703C, 0x02101017}, - {0x0F007040, 0x45171200}, - {0x0F007044, 0x11290D00}, - {0x0F007048, 0x04080306}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x0010245F}, - {0x0F007064, 0x00000010}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00007000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - /* Enable BW improvement within memory controller */ - {0x0F007094, 0x00040000}, - {0x0F007098, 0x00000000}, - {0x0F0070c8, 0x00000104}, - /* Enable 2 ports within X-bar */ - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { - /* DPLL Clock Setting */ - {0x0f000810, 0x00002F95}, - {0x0f000820, 0x03F1369B}, - {0x0f000840, 0x0fff0000}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - /* Changed source for X-bar and MIPS clock to APLL */ - {0x0f000840, 0x0FFF0000}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which - * set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - /* Memcontroller Default values */ - {0x0F007000, 0x00010001}, - {0x0F007004, 0x01010100}, - {0x0F007008, 0x01000001}, - {0x0F00700c, 0x00000000}, - {0x0F007010, 0x01000000}, - {0x0F007014, 0x01000100}, - {0x0F007018, 0x01000000}, - {0x0F00701c, 0x01020000}, - {0x0F007020, 0x04020107}, - {0x0F007024, 0x00000007}, - {0x0F007028, 0x01020200}, - {0x0F00702c, 0x0204040a}, - {0x0F007030, 0x06000000}, - {0x0F007034, 0x00000004}, - {0x0F007038, 0x1F080200}, - {0x0F00703C, 0x0203031F}, - {0x0F007040, 0x6e001200}, - {0x0F007044, 0x011a0a00}, - {0x0F007048, 0x03000305}, - {0x0F00704c, 0x00000000}, - {0x0F007050, 0x0100001c}, - {0x0F007054, 0x00000000}, - {0x0F007058, 0x00000000}, - {0x0F00705c, 0x00000000}, - {0x0F007060, 0x00082ED6}, - {0x0F007064, 0x0000000A}, - {0x0F007068, 0x00000000}, - {0x0F00706c, 0x00000001}, - {0x0F007070, 0x00005000}, - {0x0F007074, 0x00000000}, - {0x0F007078, 0x00000000}, - {0x0F00707C, 0x00000000}, - {0x0F007080, 0x00000000}, - {0x0F007084, 0x00000000}, - {0x0F007088, 0x01000001}, - {0x0F00708c, 0x00000101}, - {0x0F007090, 0x00000000}, - {0x0F007094, 0x00010000}, - {0x0F007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - /* Enable 2 ports within X-bar */ - {0x0F00A000, 0x00000016}, - /* Enable start bit within memory controller */ - {0x0F007018, 0x01010000} -}; - -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 /* index for 0x0F007000 */ -static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = { - /* DPLL Clock Setting */ - {0x0f000820, 0x07F13FFF}, - {0x0f000810, 0x00002F95}, - {0x0f000860, 0x00000000}, - {0x0f000880, 0x000003DD}, - {0x0f000840, 0x0FFF1F00}, - {0x0F00a044, 0x1fffffff}, - {0x0F00a040, 0x1f000000}, - {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor - * which set the flash clock to 20 MHz */ - {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ - {0x0F00a080, 0x1C000000}, - {0x0F00A000, 0x00000016}, - {0x0f007000, 0x00010001}, - {0x0f007004, 0x01000000}, - {0x0f007008, 0x01000001}, - {0x0f00700c, 0x00000000}, - {0x0f007010, 0x01000000}, - {0x0f007014, 0x01000100}, - {0x0f007018, 0x01000000}, - {0x0f00701c, 0x01020000}, - {0x0f007020, 0x04020107}, - {0x0f007024, 0x00000007}, - {0x0f007028, 0x02020200}, - {0x0f00702c, 0x0204040a}, - {0x0f007030, 0x04000000}, - {0x0f007034, 0x00000002}, - {0x0f007038, 0x1d060200}, - {0x0f00703c, 0x1c22221d}, - {0x0f007040, 0x8A116600}, - {0x0f007044, 0x222d0800}, - {0x0f007048, 0x02690204}, - {0x0f00704c, 0x00000000}, - {0x0f007050, 0x0100001c}, - {0x0f007054, 0x00000000}, - {0x0f007058, 0x00000000}, - {0x0f00705c, 0x00000000}, - {0x0f007060, 0x000A15D6}, - {0x0f007064, 0x0000000A}, - {0x0f007068, 0x00000000}, - {0x0f00706c, 0x00000001}, - {0x0f007070, 0x00004000}, - {0x0f007074, 0x00000000}, - {0x0f007078, 0x00000000}, - {0x0f00707c, 0x00000000}, - {0x0f007080, 0x00000000}, - {0x0f007084, 0x00000000}, - {0x0f007088, 0x01000001}, - {0x0f00708c, 0x00000101}, - {0x0f007090, 0x00000000}, - {0x0f007094, 0x00010000}, - {0x0f007098, 0x00000000}, - {0x0F0070C8, 0x00000104}, - {0x0F007018, 0x01010000} -}; - - -int ddr_init(struct bcm_mini_adapter *Adapter) -{ - struct bcm_ddr_setting *psDDRSetting = NULL; - ULONG RegCount = 0; - UINT value = 0; - UINT uiResetValue = 0; - UINT uiClockSetting = 0; - int retval = STATUS_SUCCESS; - - switch (Adapter->chip_id) { - case 0xbece3200: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = (sizeof(asT3LP_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = (sizeof(asT3LP_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = (sizeof(asT3LP_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F13652; - else - uiClockSetting = 0x03F1365B; - break; - default: - return -EINVAL; - } - - break; - case T3LPB: - case BCS220_2: - case BCS220_2BC: - case BCS250_BC: - case BCS220_3: - /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive - * (please check current value and additionally set these bits) - */ - if ((Adapter->chip_id != BCS220_2) && - (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3)) { - retval = rdmalt(Adapter, (UINT)0x0f000830, &uiResetValue, - sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, __LINE__); - return retval; - } - uiResetValue |= 0x44; - retval = wrmalt(Adapter, (UINT)0x0f000830, &uiResetValue, - sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, __LINE__); - return retval; - } - } - switch (Adapter->DDRSetting) { - - - - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F13652; - else - uiClockSetting = 0x03F1365B; - break; - - case DDR_160_MHZ: - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz) / - sizeof(struct bcm_ddr_setting); - - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x03F137D2; - else - uiClockSetting = 0x03F137DB; - } - break; - - case 0xbece0110: - case 0xbece0120: - case 0xbece0121: - case 0xbece0130: - case 0xbece0300: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "DDR Setting: %x\n", Adapter->DDRSetting); - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = (sizeof(asT3_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = (sizeof(asT3_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = (sizeof(asT3_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - break; - default: - return -EINVAL; - } - case 0xbece0310: - { - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz) / - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - - /* 266Mhz PLL selected. */ - if (Adapter->bDPLLConfig == PLL_266_MHZ) { - memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, - sizeof(asDPLL_266MHZ)); - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - } else { - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz) / - sizeof(struct bcm_ddr_setting)); - if (Adapter->bMipsConfig == MIPS_200_MHZ) - uiClockSetting = 0x07F13652; - else - uiClockSetting = 0x07F1365B; - } - break; - default: - return -EINVAL; - } - break; - - } - default: - return -EINVAL; - } - - value = 0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Register Count is =%lu\n", RegCount); - while (RegCount && !retval) { - if (uiClockSetting - && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) - value = uiClockSetting; - else - value = psDDRSetting->ulRegValue; - retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, - sizeof(value)); - if (STATUS_SUCCESS != retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - break; - } - - RegCount--; - psDDRSetting++; - } - - if (Adapter->chip_id >= 0xbece3300) { - - mdelay(3); - if ((Adapter->chip_id != BCS220_2) && - (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3)) { - /* drive MDDR to half in case of UMA-B: */ - uiResetValue = 0x01010001; - retval = wrmalt(Adapter, (UINT)0x0F007018, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x00040020; - retval = wrmalt(Adapter, (UINT)0x0F007094, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x01020101; - retval = wrmalt(Adapter, (UINT)0x0F00701c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x01010000; - retval = wrmalt(Adapter, (UINT)0x0F007018, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } - mdelay(3); - - /* DC/DC standby change... - * This is to be done only for Hybrid PMU mode. - * with the current h/w there is no way to detect this. - * and since we dont have internal PMU lets do it under - * UMA-B chip id. we will change this when we will have - * internal PMU. - */ - if (Adapter->PmuMode == HYBRID_MODE_7C) { - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x1322a8; - retval = wrmalt(Adapter, (UINT)0x0f000d1c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x132296; - retval = wrmalt(Adapter, (UINT)0x0f000d14, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } else if (Adapter->PmuMode == HYBRID_MODE_6) { - - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x6003229a; - retval = wrmalt(Adapter, (UINT)0x0f000d14, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - retval = rdmalt(Adapter, (UINT)0x0f000c00, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - uiResetValue = 0x1322a8; - retval = wrmalt(Adapter, (UINT)0x0f000d1c, - &uiResetValue, sizeof(uiResetValue)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, - DBG_LVL_ALL, - "%s:%d RDM failed\n", - __func__, - __LINE__); - return retval; - } - } - - } - Adapter->bDDRInitDone = TRUE; - return retval; -} - -int download_ddr_settings(struct bcm_mini_adapter *Adapter) -{ - struct bcm_ddr_setting *psDDRSetting = NULL; - ULONG RegCount = 0; - unsigned long ul_ddr_setting_load_addr = - DDR_DUMP_INTERNAL_DEVICE_MEMORY; - UINT value = 0; - int retval = STATUS_SUCCESS; - bool bOverrideSelfRefresh = false; - - switch (Adapter->chip_id) { - case 0xbece3200: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - default: - return -EINVAL; - } - break; - - case T3LPB: - case BCS220_2: - case BCS220_2BC: - case BCS250_BC: - case BCS220_3: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting80MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - - case DDR_160_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - - break; - default: - return -EINVAL; - } - break; - case 0xbece0300: - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); - RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - default: - return -EINVAL; - } - break; - case 0xbece0310: - { - switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - } - break; - } - default: - return -EINVAL; - } - /* total number of Register that has to be dumped */ - value = RegCount; - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - - return retval; - } - ul_ddr_setting_load_addr += sizeof(ULONG); - /* signature */ - value = (0x1d1e0dd0); - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - return retval; - } - - ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount *= (sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); - - while (RegCount && !retval) { - value = psDDRSetting->ulRegAddress; - retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, - sizeof(value)); - ul_ddr_setting_load_addr += sizeof(ULONG); - if (!retval) { - if (bOverrideSelfRefresh - && (psDDRSetting->ulRegAddress - == 0x0F007018)) - value = (psDDRSetting->ulRegValue | (1<<8)); - else - value = psDDRSetting->ulRegValue; - - if (STATUS_SUCCESS != wrmalt(Adapter, - ul_ddr_setting_load_addr, - &value, - sizeof(value))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "%s:%d\n", __func__, __LINE__); - break; - } - } - ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount--; - psDDRSetting++; - } - return retval; -} diff --git a/drivers/staging/bcm/DDRInit.h b/drivers/staging/bcm/DDRInit.h deleted file mode 100644 index b0196fce9255..000000000000 --- a/drivers/staging/bcm/DDRInit.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _DDR_INIT_H_ -#define _DDR_INIT_H_ - - - -int ddr_init(struct bcm_mini_adapter *psAdapter); -int download_ddr_settings(struct bcm_mini_adapter *psAdapter); - -#endif diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h deleted file mode 100644 index 7b331215c1ac..000000000000 --- a/drivers/staging/bcm/Debug.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Debug.h - * - * Dynamic (runtime) debug framework implementation. - * -kaiwan. - */ -#ifndef _DEBUG_H -#define _DEBUG_H -#include -#define NONE 0xFFFF - -/* TYPE and SUBTYPE - * Define valid TYPE (or category or code-path, however you like to think of it) - * and SUBTYPE s. - * Type and SubType are treated as bitmasks. - */ -#define DBG_TYPE_INITEXIT (1 << 0) /* 1 */ -#define DBG_TYPE_TX (1 << 1) /* 2 */ -#define DBG_TYPE_RX (1 << 2) /* 4 */ -#define DBG_TYPE_OTHERS (1 << 3) /* 8 */ -#define NUMTYPES 4 - -/* -SUBTYPEs for TX : TYPE is DBG_TYPE_TX -----// - * Transmit.c ,Arp.c, LeakyBucket.c, And Qos.c - * total 17 macros - */ -/* Transmit.c */ -#define TX 1 -#define MP_SEND (TX << 0) -#define NEXT_SEND (TX << 1) -#define TX_FIFO (TX << 2) -#define TX_CONTROL (TX << 3) - -/* Arp.c */ -#define IP_ADDR (TX << 4) -#define ARP_REQ (TX << 5) -#define ARP_RESP (TX << 6) - -/* Leakybucket.c */ -#define TOKEN_COUNTS (TX << 8) -#define CHECK_TOKENS (TX << 9) -#define TX_PACKETS (TX << 10) -#define TIMER (TX << 11) - -/* Qos.c */ -#define QOS TX -#define QUEUE_INDEX (QOS << 12) -#define IPV4_DBG (QOS << 13) -#define IPV6_DBG (QOS << 14) -#define PRUNE_QUEUE (QOS << 15) -#define SEND_QUEUE (QOS << 16) - -/* TX_Misc */ -#define TX_OSAL_DBG (TX << 17) - -/* --SUBTYPEs for ------INIT & EXIT--------------------- - * ------------ TYPE is DBG_TYPE_INITEXIT -----// - * DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c - */ -#define MP 1 -#define DRV_ENTRY (MP << 0) -#define MP_INIT (MP << 1) -#define READ_REG (MP << 3) -#define DISPATCH (MP << 2) -#define CLAIM_ADAP (MP << 4) -#define REG_IO_PORT (MP << 5) -#define INIT_DISP (MP << 6) -#define RX_INIT (MP << 7) - -/* -SUBTYPEs for --RX---------------------------------- - * ------------RX : TYPE is DBG_TYPE_RX -----// - * Receive.c - */ -#define RX 1 -#define RX_DPC (RX << 0) -#define RX_CTRL (RX << 3) -#define RX_DATA (RX << 4) -#define MP_RETURN (RX << 1) -#define LINK_MSG (RX << 2) - -/* -SUBTYPEs for ----OTHER ROUTINES------------------ - * ------------OTHERS : TYPE is DBG_TYPE_OTHER -----// - * HaltnReset,CheckForHang,PnP,Misc,CmHost - * total 12 macros - */ -#define OTHERS 1 -#define ISR OTHERS -#define MP_DPC (ISR << 0) - -/* HaltnReset.c */ -#define HALT OTHERS -#define MP_HALT (HALT << 1) -#define CHECK_HANG (HALT << 2) -#define MP_RESET (HALT << 3) -#define MP_SHUTDOWN (HALT << 4) - -/* pnp.c */ -#define PNP OTHERS -#define MP_PNP (PNP << 5) - -/* Misc.c */ -#define MISC OTHERS -#define DUMP_INFO (MISC << 6) -#define CLASSIFY (MISC << 7) -#define LINK_UP_MSG (MISC << 8) -#define CP_CTRL_PKT (MISC << 9) -#define DUMP_CONTROL (MISC << 10) -#define LED_DUMP_INFO (MISC << 11) - -/* CmHost.c */ -#define CMHOST OTHERS -#define SERIAL (OTHERS << 12) -#define IDLE_MODE (OTHERS << 13) -#define WRM (OTHERS << 14) -#define RDM (OTHERS << 15) - -/* TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ? */ -#define PHS_SEND (OTHERS << 16) -#define PHS_RECEIVE (OTHERS << 17) -#define PHS_MODULE (OTHERS << 18) - -#define INTF_INIT (OTHERS << 19) -#define INTF_ERR (OTHERS << 20) -#define INTF_WARN (OTHERS << 21) -#define INTF_NORM (OTHERS << 22) - -#define IRP_COMPLETION (OTHERS << 23) -#define SF_DESCRIPTOR_CNTS (OTHERS << 24) -#define PHS_DISPATCH (OTHERS << 25) -#define OSAL_DBG (OTHERS << 26) -#define NVM_RW (OTHERS << 27) - -#define HOST_MIBS (OTHERS << 28) -#define CONN_MSG (CMHOST << 29) - -/* Debug level - * We have 8 debug levels, in (numerical) increasing order of verbosity. - * IMP: Currently implementing ONLY DBG_LVL_ALL , i.e. , all debug prints will - * appear (of course, iff global debug flag is ON and we match the Type and SubType). - * Finer granularity debug levels are currently not in use, although the feature exists. - * - * Another way to say this: - * All the debug prints currently have 'debug_level' set to DBG_LVL_ALL . - * You can compile-time change that to any of the below, if you wish to. However, as of now, there's - * no dynamic facility to have the userspace 'TestApp' set debug_level. Slated for future expansion. - */ -#define BCM_ALL 7 -#define BCM_LOW 6 -#define BCM_PRINT 5 -#define BCM_NORMAL 4 -#define BCM_MEDIUM 3 -#define BCM_SCREAM 2 -#define BCM_ERR 1 -/* Not meant for developer in debug prints. - * To be used to disable all prints by setting the DBG_LVL_CURR to this value - */ -#define BCM_NONE 0 - -/* The current driver logging level. - * Everything at this level and (numerically) lower (meaning higher prio) - * is logged. - * Replace 'BCM_ALL' in the DBG_LVL_CURR macro with the logging level desired. - * For eg. to set the logging level to 'errors only' use: - * #define DBG_LVL_CURR (BCM_ERR) - */ - -#define DBG_LVL_CURR (BCM_ALL) -#define DBG_LVL_ALL BCM_ALL - -/* ---Userspace mapping of Debug State. - * Delibrately matches that of the Windows driver.. - * The TestApp's ioctl passes this struct to us. - */ -struct bcm_user_debug_state { - unsigned int Subtype, Type; - unsigned int OnOff; -/* unsigned int debug_level; future expansion */ -} __packed; - -/* ---Kernel-space mapping of Debug State */ -struct bcm_debug_state { - unsigned int type; - /* A bitmap of 32 bits for Subtype per Type. - * Valid indexes in 'subtype' array are *only* 1,2,4 and 8, - * corresponding to valid Type values. Hence we use the 'Type' field - * as the index value, ignoring the array entries 0,3,5,6,7 ! - */ - unsigned int subtype[(NUMTYPES*2)+1]; - unsigned int debug_level; -}; -/* Instantiated in the Adapter structure - * We'll reuse the debug level parameter to include a bit (the MSB) to indicate whether or not - * we want the function's name printed. - */ -#define DBG_NO_FUNC_PRINT (1 << 31) -#define DBG_LVL_BITMASK 0xFF - -/* --- Only for direct printk's; "hidden" to API. */ -#define DBG_TYPE_PRINTK 3 - -#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \ - do { \ - if (DBG_TYPE_PRINTK == Type) \ - pr_info("%s:" string, __func__, ##args); \ - else if (Adapter && \ - (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ - (Type & Adapter->stDebugState.type) && \ - (SubType & Adapter->stDebugState.subtype[Type])) { \ - if (dbg_level & DBG_NO_FUNC_PRINT) \ - pr_debug("%s:\n", string); \ - else \ - pr_debug("%s:\n" string, __func__, ##args); \ - } \ - } while (0) - -#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) \ - do { \ - if (DBG_TYPE_PRINTK == Type || \ - (Adapter && \ - (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ - (Type & Adapter->stDebugState.type) && \ - (SubType & Adapter->stDebugState.subtype[Type]))) { \ - pr_debug("%s:\n", __func__); \ - print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, \ - 16, 1, buffer, bufferlen, false); \ - } \ - } while (0) - -#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \ - int i; \ - for (i = 0; i < (NUMTYPES * 2) + 1; i++) { \ - if ((i == 1) || (i == 2) || (i == 4) || (i == 8)) { \ - /* CAUTION! Forcefully turn on ALL debug paths and subpaths! \ - * Adapter->stDebugState.subtype[i] = 0xffffffff; \ - */ \ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "subtype[%d] = 0x%08x\n", \ - i, Adapter->stDebugState.subtype[i]); \ - } \ - } \ -} while (0) - -#endif diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c deleted file mode 100644 index dd5d138a6528..000000000000 --- a/drivers/staging/bcm/HandleControlPacket.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * @file HandleControlPacket.c - * This file contains the routines to deal with - * sending and receiving of control packets. - */ -#include "headers.h" - -/** - * When a control packet is received, analyze the - * "status" and call appropriate response function. - * Enqueue the control packet for Application. - * @return None - */ -static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, - struct sk_buff *skb) -{ - struct bcm_tarang_data *pTarang = NULL; - bool HighPriorityMessage = false; - struct sk_buff *newPacket = NULL; - CHAR cntrl_msg_mask_bit = 0; - bool drop_pkt_flag = TRUE; - USHORT usStatus = *(PUSHORT)(skb->data); - - if (netif_msg_pktdata(Adapter)) - print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE, - 16, 1, skb->data, skb->len, 0); - - switch (usStatus) { - case CM_RESPONSES: /* 0xA0 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, - "MAC Version Seems to be Non Multi-Classifier, rejected by Driver"); - HighPriorityMessage = TRUE; - break; - case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: - HighPriorityMessage = TRUE; - if (Adapter->LinkStatus == LINKUP_DONE) - CmControlResponseMessage(Adapter, - (skb->data + sizeof(USHORT))); - break; - case LINK_CONTROL_RESP: /* 0xA2 */ - case STATUS_RSP: /* 0xA1 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "LINK_CONTROL_RESP"); - HighPriorityMessage = TRUE; - LinkControlResponseMessage(Adapter, - (skb->data + sizeof(USHORT))); - break; - case STATS_POINTER_RESP: /* 0xA6 */ - HighPriorityMessage = TRUE; - StatisticsResponse(Adapter, (skb->data + sizeof(USHORT))); - break; - case IDLE_MODE_STATUS: /* 0xA3 */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, - "IDLE_MODE_STATUS Type Message Got from F/W"); - InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data + - sizeof(USHORT))); - HighPriorityMessage = TRUE; - break; - - case AUTH_SS_HOST_MSG: - HighPriorityMessage = TRUE; - break; - - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "Got Default Response"); - /* Let the Application Deal with This Packet */ - break; - } - - /* Queue The Control Packet to The Application Queues */ - down(&Adapter->RxAppControlQueuelock); - - for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { - if (Adapter->device_removed) - break; - - drop_pkt_flag = TRUE; - /* - * There are cntrl msg from A0 to AC. It has been mapped to 0 to - * C bit in the cntrl mask. - * Also, by default AD to BF has been masked to the rest of the - * bits... which wil be ON by default. - * if mask bit is enable to particular pkt status, send it out - * to app else stop it. - */ - cntrl_msg_mask_bit = (usStatus & 0x1F); - /* - * printk("\ninew msg mask bit which is disable in mask:%X", - * cntrl_msg_mask_bit); - */ - if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit)) - drop_pkt_flag = false; - - if ((drop_pkt_flag == TRUE) || - (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN) - || ((pTarang->AppCtrlQueueLen > - MAX_APP_QUEUE_LEN / 2) && - (HighPriorityMessage == false))) { - /* - * Assumption:- - * 1. every tarang manages it own dropped pkt - * statitistics - * 2. Total packet dropped per tarang will be equal to - * the sum of all types of dropped pkt by that - * tarang only. - */ - struct bcm_mibs_dropped_cntrl_msg *msg = - &pTarang->stDroppedAppCntrlMsgs; - switch (*(PUSHORT)skb->data) { - case CM_RESPONSES: - msg->cm_responses++; - break; - case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP: - msg->cm_control_newdsx_multiclassifier_resp++; - break; - case LINK_CONTROL_RESP: - msg->link_control_resp++; - break; - case STATUS_RSP: - msg->status_rsp++; - break; - case STATS_POINTER_RESP: - msg->stats_pointer_resp++; - break; - case IDLE_MODE_STATUS: - msg->idle_mode_status++; - break; - case AUTH_SS_HOST_MSG: - msg->auth_ss_host_msg++; - break; - default: - msg->low_priority_message++; - break; - } - - continue; - } - - newPacket = skb_clone(skb, GFP_KERNEL); - if (!newPacket) - break; - ENQUEUEPACKET(pTarang->RxAppControlHead, - pTarang->RxAppControlTail, newPacket); - pTarang->AppCtrlQueueLen++; - } - up(&Adapter->RxAppControlQueuelock); - wake_up(&Adapter->process_read_wait_queue); - dev_kfree_skb(skb); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, - "After wake_up_interruptible"); -} - -/** - * @ingroup ctrl_pkt_functions - * Thread to handle control pkt reception - */ - -/* pointer to adapter object*/ -int control_packet_handler(struct bcm_mini_adapter *Adapter) -{ - struct sk_buff *ctrl_packet = NULL; - unsigned long flags = 0; - /* struct timeval tv; */ - /* int *puiBuffer = NULL; */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, - "Entering to make thread wait on control packet event!"); - while (1) { - wait_event_interruptible(Adapter->process_rx_cntrlpkt, - atomic_read(&Adapter->cntrlpktCnt) || - Adapter->bWakeUpDevice || - kthread_should_stop()); - - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, - DBG_LVL_ALL, "Exiting\n"); - return 0; - } - if (TRUE == Adapter->bWakeUpDevice) { - Adapter->bWakeUpDevice = false; - if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) - && ((TRUE == Adapter->IdleMode) || - (TRUE == Adapter->bShutStatus))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - CP_CTRL_PKT, DBG_LVL_ALL, - "Calling InterfaceAbortIdlemode\n"); - /* - * Adapter->bTriedToWakeUpFromlowPowerMode - * = TRUE; - */ - InterfaceIdleModeWakeup(Adapter); - } - continue; - } - - while (atomic_read(&Adapter->cntrlpktCnt)) { - spin_lock_irqsave(&Adapter->control_queue_lock, flags); - ctrl_packet = Adapter->RxControlHead; - if (ctrl_packet) { - DEQUEUEPACKET(Adapter->RxControlHead, - Adapter->RxControlTail); - /* Adapter->RxControlHead=ctrl_packet->next; */ - } - - spin_unlock_irqrestore(&Adapter->control_queue_lock, - flags); - handle_rx_control_packet(Adapter, ctrl_packet); - atomic_dec(&Adapter->cntrlpktCnt); - } - - SetUpTargetDsxBuffers(Adapter); - } - return STATUS_SUCCESS; -} - -INT flushAllAppQ(void) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_tarang_data *pTarang = NULL; - struct sk_buff *PacketToDrop = NULL; - - for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) { - while (pTarang->RxAppControlHead != NULL) { - PacketToDrop = pTarang->RxAppControlHead; - DEQUEUEPACKET(pTarang->RxAppControlHead, - pTarang->RxAppControlTail); - dev_kfree_skb(PacketToDrop); - } - pTarang->AppCtrlQueueLen = 0; - /* dropped contrl packet statistics also should be reset. */ - memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, - sizeof(struct bcm_mibs_dropped_cntrl_msg)); - - } - return STATUS_SUCCESS; -} - - diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h deleted file mode 100644 index f922ac49b70e..000000000000 --- a/drivers/staging/bcm/HostMIBSInterface.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef _HOST_MIBSINTERFACE_H -#define _HOST_MIBSINTERFACE_H - -/* - * Copyright (c) 2007 Beceem Communications Pvt. Ltd - * File Name: HostMIBSInterface.h - * Abstract: This file contains DS used by the Host to update the Host - * statistics used for the MIBS. - */ - -#define MIBS_MAX_CLASSIFIERS 100 -#define MIBS_MAX_PHSRULES 100 -#define MIBS_MAX_SERVICEFLOWS 17 -#define MIBS_MAX_IP_RANGE_LENGTH 4 -#define MIBS_MAX_PORT_RANGE 4 -#define MIBS_MAX_PROTOCOL_LENGTH 32 -#define MIBS_MAX_PHS_LENGTHS 255 -#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10 -#define MIBS_IP_LENGTH_OF_ADDRESS 4 -#define MIBS_MAX_HIST_ENTRIES 12 -#define MIBS_PKTSIZEHIST_RANGE 128 - -union bcm_mibs_ip_addr { - struct { - /* Source Ip Address Range */ - unsigned long ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH]; - /* Source Ip Mask Address Range */ - unsigned long ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH]; - }; - struct { - /* Source Ip Address Range */ - unsigned long ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4]; - /* Source Ip Mask Address Range */ - unsigned long ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4]; - }; - struct { - unsigned char ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS]; - unsigned char ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IP_LENGTH_OF_ADDRESS]; - }; - struct { - unsigned char ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; - unsigned char ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES]; - }; -}; - -struct bcm_mibs_host_info { - u64 GoodTransmits; - u64 GoodReceives; - /* this to keep track of the Tx and Rx MailBox Registers. */ - unsigned long NumDesUsed; - unsigned long CurrNumFreeDesc; - unsigned long PrevNumFreeDesc; - /* to keep track the no of byte received */ - unsigned long PrevNumRcevBytes; - unsigned long CurrNumRcevBytes; - /* QOS Related */ - unsigned long BEBucketSize; - unsigned long rtPSBucketSize; - unsigned long LastTxQueueIndex; - bool TxOutofDescriptors; - bool TimerActive; - u32 u32TotalDSD; - u32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; - u32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; -}; - -struct bcm_mibs_classifier_rule { - unsigned long ulSFID; - unsigned char ucReserved[2]; - u16 uiClassifierRuleIndex; - bool bUsed; - unsigned short usVCID_Value; - u8 u8ClassifierRulePriority; - union bcm_mibs_ip_addr stSrcIpAddress; - /* IP Source Address Length */ - unsigned char ucIPSourceAddressLength; - union bcm_mibs_ip_addr stDestIpAddress; - /* IP Destination Address Length */ - unsigned char ucIPDestinationAddressLength; - unsigned char ucIPTypeOfServiceLength; - unsigned char ucTosLow; - unsigned char ucTosHigh; - unsigned char ucTosMask; - unsigned char ucProtocolLength; - unsigned char ucProtocol[MIBS_MAX_PROTOCOL_LENGTH]; - unsigned short usSrcPortRangeLo[MIBS_MAX_PORT_RANGE]; - unsigned short usSrcPortRangeHi[MIBS_MAX_PORT_RANGE]; - unsigned char ucSrcPortRangeLength; - unsigned short usDestPortRangeLo[MIBS_MAX_PORT_RANGE]; - unsigned short usDestPortRangeHi[MIBS_MAX_PORT_RANGE]; - unsigned char ucDestPortRangeLength; - bool bProtocolValid; - bool bTOSValid; - bool bDestIpValid; - bool bSrcIpValid; - unsigned char ucDirection; - bool bIpv6Protocol; - u32 u32PHSRuleID; -}; - -struct bcm_mibs_phs_rule { - unsigned long ulSFID; - u8 u8PHSI; - u8 u8PHSFLength; - u8 u8PHSF[MIBS_MAX_PHS_LENGTHS]; - u8 u8PHSMLength; - u8 u8PHSM[MIBS_MAX_PHS_LENGTHS]; - u8 u8PHSS; - u8 u8PHSV; - u8 reserved[5]; - long PHSModifiedBytes; - unsigned long PHSModifiedNumPackets; - unsigned long PHSErrorNumPackets; -}; - -struct bcm_mibs_parameters { - u32 wmanIfSfid; - u32 wmanIfCmnCpsSfState; - u32 wmanIfCmnCpsMaxSustainedRate; - u32 wmanIfCmnCpsMaxTrafficBurst; - u32 wmanIfCmnCpsMinReservedRate; - u32 wmanIfCmnCpsToleratedJitter; - u32 wmanIfCmnCpsMaxLatency; - u32 wmanIfCmnCpsFixedVsVariableSduInd; - u32 wmanIfCmnCpsSduSize; - u32 wmanIfCmnCpsSfSchedulingType; - u32 wmanIfCmnCpsArqEnable; - u32 wmanIfCmnCpsArqWindowSize; - u32 wmanIfCmnCpsArqBlockLifetime; - u32 wmanIfCmnCpsArqSyncLossTimeout; - u32 wmanIfCmnCpsArqDeliverInOrder; - u32 wmanIfCmnCpsArqRxPurgeTimeout; - u32 wmanIfCmnCpsArqBlockSize; - u32 wmanIfCmnCpsMinRsvdTolerableRate; - u32 wmanIfCmnCpsReqTxPolicy; - u32 wmanIfCmnSfCsSpecification; - u32 wmanIfCmnCpsTargetSaid; -}; - -struct bcm_mibs_table { - unsigned long ulSFID; - unsigned short usVCID_Value; - unsigned int uiThreshold; - u8 u8TrafficPriority; - bool bValid; - bool bActive; - bool bActivateRequestSent; - u8 u8QueueType; - unsigned int uiMaxBucketSize; - unsigned int uiCurrentQueueDepthOnTarget; - unsigned int uiCurrentBytesOnHost; - unsigned int uiCurrentPacketsOnHost; - unsigned int uiDroppedCountBytes; - unsigned int uiDroppedCountPackets; - unsigned int uiSentBytes; - unsigned int uiSentPackets; - unsigned int uiCurrentDrainRate; - unsigned int uiThisPeriodSentBytes; - u64 liDrainCalculated; - unsigned int uiCurrentTokenCount; - u64 liLastUpdateTokenAt; - unsigned int uiMaxAllowedRate; - unsigned int NumOfPacketsSent; - unsigned char ucDirection; - unsigned short usCID; - struct bcm_mibs_parameters stMibsExtServiceFlowTable; - unsigned int uiCurrentRxRate; - unsigned int uiThisPeriodRxBytes; - unsigned int uiTotalRxBytes; - unsigned int uiTotalTxBytes; -}; - -struct bcm_mibs_dropped_cntrl_msg { - unsigned long cm_responses; - unsigned long cm_control_newdsx_multiclassifier_resp; - unsigned long link_control_resp; - unsigned long status_rsp; - unsigned long stats_pointer_resp; - unsigned long idle_mode_status; - unsigned long auth_ss_host_msg; - unsigned long low_priority_message; -}; - -struct bcm_host_stats_mibs { - struct bcm_mibs_host_info stHostInfo; - struct bcm_mibs_classifier_rule astClassifierTable[MIBS_MAX_CLASSIFIERS]; - struct bcm_mibs_table astSFtable[MIBS_MAX_SERVICEFLOWS]; - struct bcm_mibs_phs_rule astPhsRulesTable[MIBS_MAX_PHSRULES]; - struct bcm_mibs_dropped_cntrl_msg stDroppedAppCntrlMsgs; -}; - -#endif diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c deleted file mode 100644 index 27f3f416f184..000000000000 --- a/drivers/staging/bcm/IPv6Protocol.c +++ /dev/null @@ -1,476 +0,0 @@ -#include "headers.h" - -static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header); -static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header); -static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header); - -static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, - UCHAR *pucNextHeader, bool *bParseDone, USHORT *pusPayloadLength) -{ - UCHAR *pucRetHeaderPtr = NULL; - UCHAR *pucPayloadPtr = NULL; - USHORT usNextHeaderOffset = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if ((ppucPayload == NULL) || (*pusPayloadLength == 0) || - (*bParseDone)) { - *bParseDone = TRUE; - return NULL; - } - - pucRetHeaderPtr = *ppucPayload; - pucPayloadPtr = *ppucPayload; - - if (!pucRetHeaderPtr || !pucPayloadPtr) { - *bParseDone = TRUE; - return NULL; - } - - /* Get the Nextt Header Type */ - *bParseDone = false; - - - switch (*pucNextHeader) { - case IPV6HDR_TYPE_HOPBYHOP: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 HopByHop Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr); - break; - - case IPV6HDR_TYPE_ROUTING: - { - struct bcm_ipv6_routing_hdr *pstIpv6RoutingHeader; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Routing Header"); - pstIpv6RoutingHeader = - (struct bcm_ipv6_routing_hdr *)pucPayloadPtr; - usNextHeaderOffset += sizeof(struct bcm_ipv6_routing_hdr); - usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * - IPV6_ADDRESS_SIZEINBYTES; - } - break; - - case IPV6HDR_TYPE_FRAGMENTATION: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Fragmentation Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr); - break; - - case IPV6HDR_TYPE_DESTOPTS: - { - struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr = - (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr; - int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 DestOpts Header Header"); - usNextHeaderOffset += sizeof(struct bcm_ipv6_dest_options_hdr); - usNextHeaderOffset += nTotalOptions * - IPV6_DESTOPTS_HDR_OPTIONSIZE; - } - break; - - - case IPV6HDR_TYPE_AUTHENTICATION: - { - struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr = - (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr; - int nHdrLen = pstIpv6AuthHdr->ucLength; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Authentication Header"); - usNextHeaderOffset += nHdrLen * 4; - } - break; - - case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Encrypted Security Payload Header"); - *bParseDone = TRUE; - break; - - case IPV6_ICMP_HDR_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nICMP Header"); - *bParseDone = TRUE; - break; - - case TCP_HEADER_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nTCP Header"); - *bParseDone = TRUE; - break; - - case UDP_HEADER_TYPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nUDP Header"); - *bParseDone = TRUE; - break; - - default: - *bParseDone = TRUE; - break; - } - - if (*bParseDone == false) { - if (*pusPayloadLength <= usNextHeaderOffset) { - *bParseDone = TRUE; - } else { - *pucNextHeader = *pucPayloadPtr; - pucPayloadPtr += usNextHeaderOffset; - (*pusPayloadLength) -= usNextHeaderOffset; - } - - } - - *ppucPayload = pucPayloadPtr; - return pucRetHeaderPtr; -} - - -static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, - USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) -{ - UCHAR *pIpv6HdrScanContext = pucPayload; - bool bDone = false; - UCHAR ucHeaderType = 0; - UCHAR *pucNextHeader = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (!pucPayload || (usPayloadLength == 0)) - return 0; - - *pusSrcPort = *pusDestPort = 0; - ucHeaderType = ucNextHeader; - while (!bDone) { - pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, - &ucHeaderType, - &bDone, - &usPayloadLength); - if (bDone) { - if ((ucHeaderType == TCP_HEADER_TYPE) || - (ucHeaderType == UDP_HEADER_TYPE)) { - *pusSrcPort = *((PUSHORT)(pucNextHeader)); - *pusDestPort = *((PUSHORT)(pucNextHeader+2)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", - ntohs(*pusSrcPort), - ntohs(*pusDestPort)); - } - break; - - } - } - return ucHeaderType; -} - - -/* - * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver control - * structure - * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet - */ -USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader, - struct bcm_classifier_rule *pstClassifierRule) -{ - USHORT ushDestPort = 0; - USHORT ushSrcPort = 0; - UCHAR ucNextProtocolAboveIP = 0; - struct bcm_ipv6_hdr *pstIpv6Header = NULL; - bool bClassificationSucceed = false; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "IpVersion6 ==========>\n"); - - pstIpv6Header = pcIpHeader; - - DumpIpv6Header(pstIpv6Header); - - /* - * Try to get the next higher layer protocol - * and the Ports Nos if TCP or UDP - */ - ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + - sizeof(struct bcm_ipv6_hdr)), - &ushSrcPort, - &ushDestPort, - pstIpv6Header->usPayloadLength, - pstIpv6Header->ucNextHeader); - - do { - if (pstClassifierRule->ucDirection == 0) { - /* - * cannot be processed for classification. - * it is a down link connection - */ - break; - } - - if (!pstClassifierRule->bIpv6Protocol) { - /* - * We are looking for Ipv6 Classifiers - * Lets ignore this classifier and try the next one - */ - break; - } - - bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, - pstIpv6Header); - if (!bClassificationSucceed) - break; - - bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, - pstIpv6Header); - if (!bClassificationSucceed) - break; - - /* - * Match the protocol type. - * For IPv6 the next protocol at end of - * Chain of IPv6 prot headers - */ - bClassificationSucceed = MatchProtocol(pstClassifierRule, - ucNextProtocolAboveIP); - if (!bClassificationSucceed) - break; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Protocol Matched"); - - if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || - (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { - /* Match Src Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", - ntohs(ushSrcPort)); - bClassificationSucceed = MatchSrcPort(pstClassifierRule, - ntohs(ushSrcPort)); - if (!bClassificationSucceed) - break; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, "\nIPv6 Src Port Matched"); - - /* Match Dest Port */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Destination Port:%x\n", - ntohs(ushDestPort)); - bClassificationSucceed = MatchDestPort(pstClassifierRule, - ntohs(ushDestPort)); - if (!bClassificationSucceed) - break; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "\nIPv6 Dest Port Matched"); - } - } while (0); - - if (bClassificationSucceed == TRUE) { - INT iMatchedSFQueueIndex = 0; - - iMatchedSFQueueIndex = SearchSfid(Adapter, - pstClassifierRule->ulSFID); - if ((iMatchedSFQueueIndex >= NO_OF_QUEUES) || - (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false)) - bClassificationSucceed = false; - } - - return bClassificationSucceed; -} - - -static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header) -{ - UINT uiLoopIndex = 0; - UINT uiIpv6AddIndex = 0; - UINT uiIpv6AddrNoLongWords = 4; - ULONG aulSrcIP[4]; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *src_addr = &pstClassifierRule->stSrcIpAddress; - - /* - * This is the no. of Src Addresses ie Range of IP Addresses contained - * in the classifier rule for which we need to match - */ - UINT uiCountIPSrcAddresses = - (UINT)pstClassifierRule->ucIPSourceAddressLength; - - - if (uiCountIPSrcAddresses == 0) - return TRUE; - - - /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) - aulSrcIP[uiIpv6AddIndex] = - ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); - - for (uiLoopIndex = 0; - uiLoopIndex < uiCountIPSrcAddresses; - uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Address In Received Packet :\n "); - DumpIpv6Address(aulSrcIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Mask In Classifier Rule:\n"); - DumpIpv6Address(&src_addr->ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Src Ipv6 Address In Classifier Rule :\n"); - DumpIpv6Address(&src_addr->ulIpv6Addr[uiLoopIndex]); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - if ((src_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & - aulSrcIP[uiIpv6AddIndex]) != - src_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* - * Match failed for current Ipv6 Address - * Try next Ipv6 Address - */ - break; - } - - if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "Ipv6 Src Ip Address Matched\n"); - return TRUE; - } - } - } - return false; -} - -static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule, - struct bcm_ipv6_hdr *pstIpv6Header) -{ - UINT uiLoopIndex = 0; - UINT uiIpv6AddIndex = 0; - UINT uiIpv6AddrNoLongWords = 4; - ULONG aulDestIP[4]; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress; - - /* - * This is the no. of Destination Addresses - * ie Range of IP Addresses contained in the classifier rule - * for which we need to match - */ - UINT uiCountIPDestinationAddresses = - (UINT)pstClassifierRule->ucIPDestinationAddressLength; - - if (uiCountIPDestinationAddresses == 0) - return TRUE; - - - /* First Convert the Ip Address in the packet to Host Endian order */ - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) - aulDestIP[uiIpv6AddIndex] = - ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); - - for (uiLoopIndex = 0; - uiLoopIndex < uiCountIPDestinationAddresses; - uiLoopIndex += uiIpv6AddrNoLongWords) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Address In Received Packet :\n "); - DumpIpv6Address(aulDestIP); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Mask In Classifier Rule :\n"); - DumpIpv6Address(&dest_addr->ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "\n Destination Ipv6 Address In Classifier Rule :\n"); - DumpIpv6Address(&dest_addr->ulIpv6Addr[uiLoopIndex]); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - if ((dest_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & - aulDestIP[uiIpv6AddIndex]) != - dest_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { - /* - * Match failed for current Ipv6 Address. - * Try next Ipv6 Address - */ - break; - } - - if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { - /* Match Found */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, - DBG_LVL_ALL, - "Ipv6 Destination Ip Address Matched\n"); - return TRUE; - } - } - } - return false; - -} - -VOID DumpIpv6Address(ULONG *puIpv6Address) -{ - UINT uiIpv6AddrNoLongWords = 4; - UINT uiIpv6AddIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - for (uiIpv6AddIndex = 0; - uiIpv6AddIndex < uiIpv6AddrNoLongWords; - uiIpv6AddIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - ":%lx", puIpv6Address[uiIpv6AddIndex]); - } - -} - -static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header) -{ - UCHAR ucVersion; - UCHAR ucPrio; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "----Ipv6 Header---"); - ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Version : %x\n", ucVersion); - ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Priority : %x\n", ucPrio); - /* - * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Payload Length : %x\n", - ntohs(pstIpv6Header->usPayloadLength)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Next Header : %x\n", pstIpv6Header->ucNextHeader); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Src Address :\n"); - DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "Dest Address :\n"); - DumpIpv6Address(pstIpv6Header->ulDestIpAddress); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, - "----Ipv6 Header End---"); - - -} diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h deleted file mode 100644 index 96b36a579af2..000000000000 --- a/drivers/staging/bcm/IPv6ProtocolHdr.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _IPV6_PROTOCOL_DEFINES_ -#define _IPV6_PROTOCOL_DEFINES_ - -#define IPV6HDR_TYPE_HOPBYHOP 0x0 -#define IPV6HDR_TYPE_ROUTING 0x2B -#define IPV6HDR_TYPE_FRAGMENTATION 0x2C -#define IPV6HDR_TYPE_DESTOPTS 0x3c -#define IPV6HDR_TYPE_AUTHENTICATION 0x33 -#define IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD 0x34 -#define MASK_IPV6_CS_SPEC 0x2 - -#define TCP_HEADER_TYPE 0x6 -#define UDP_HEADER_TYPE 0x11 -#define IPV6_ICMP_HDR_TYPE 0x2 -#define IPV6_FLOWLABEL_BITOFFSET 9 - -#define IPV6_MAX_CHAINEDHDR_BUFFBYTES 0x64 -/* - * Size of Dest Options field of Destinations Options Header - * in bytes. - */ -#define IPV6_DESTOPTS_HDR_OPTIONSIZE 0x8 - -struct bcm_ipv6_hdr { - unsigned char ucVersionPrio; - unsigned char aucFlowLabel[3]; - unsigned short usPayloadLength; - unsigned char ucNextHeader; - unsigned char ucHopLimit; - unsigned long ulSrcIpAddress[4]; - unsigned long ulDestIpAddress[4]; -}; - -struct bcm_ipv6_routing_hdr { - unsigned char ucNextHeader; - unsigned char ucRoutingType; - unsigned char ucNumAddresses; - unsigned char ucNextAddress; - unsigned long ulReserved; -}; - -struct bcm_ipv6_fragment_hdr { - unsigned char ucNextHeader; - unsigned char ucReserved; - unsigned short usFragmentOffset; - unsigned long ulIdentification; -}; - -struct bcm_ipv6_dest_options_hdr { - unsigned char ucNextHeader; - unsigned char ucHdrExtLen; - unsigned char ucDestOptions[6]; -}; - -struct bcm_ipv6_options_hdr { - unsigned char ucNextHeader; - unsigned char ucMisc[3]; - unsigned long ulJumboPayloadLen; -}; - -struct bcm_ipv6_authentication_hdr { - unsigned char ucNextHeader; - unsigned char ucLength; - unsigned short usReserved; - unsigned long ulSecurityParametersIndex; -}; - -enum bcm_ipaddr_context { - eSrcIpAddress, - eDestIpAddress -}; - -/* Function Prototypes */ - -unsigned short IpVersion6(struct bcm_mini_adapter *Adapter, /* < Pointer to the driver control structure */ - void *pcIpHeader, /* psAdapter; */ - char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - - if (!buff) - return -ENOMEM; - - while (1) { - oldfs = get_fs(); - set_fs(get_ds()); - len = vfs_read(flp, (void __force __user *)buff, - MAX_TRANSFER_CTRL_BYTE_USB, &pos); - set_fs(oldfs); - if (len <= 0) { - if (len < 0) - errno = len; - else - errno = 0; - break; - } - /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, - * DBG_LVL_ALL, buff, - * MAX_TRANSFER_CTRL_BYTE_USB); - */ - errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); - if (errno) - break; - on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; - } - - kfree(buff); - return errno; -} - -int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, - unsigned int on_chip_loc) -{ - char *buff, *buff_readback; - unsigned int reg = 0; - mm_segment_t oldfs = {0}; - int errno = 0, len = 0, is_config_file = 0; - loff_t pos = 0; - static int fw_down; - INT Status = STATUS_SUCCESS; - struct bcm_interface_adapter *psIntfAdapter = arg; - int bytes; - - buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); - buff_readback = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); - if (!buff || !buff_readback) { - kfree(buff); - kfree(buff_readback); - - return -ENOMEM; - } - - is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0; - - while (1) { - oldfs = get_fs(); - set_fs(get_ds()); - len = vfs_read(flp, (void __force __user *)buff, - MAX_TRANSFER_CTRL_BYTE_USB, &pos); - set_fs(oldfs); - fw_down++; - - if (len <= 0) { - if (len < 0) - errno = len; - else - errno = 0; - break; - } - - bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, - buff_readback, len); - if (bytes < 0) { - Status = bytes; - goto exit; - } - reg++; - if ((len-sizeof(unsigned int)) < 4) { - if (memcmp(buff_readback, buff, len)) { - Status = -EIO; - goto exit; - } - } else { - len -= 4; - - while (len) { - if (*(unsigned int *)&buff_readback[len] != - *(unsigned int *)&buff[len]) { - Status = -EIO; - goto exit; - } - len -= 4; - } - } - on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; - } /* End of while(1) */ - -exit: - kfree(buff); - kfree(buff_readback); - return Status; -} - -static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, - struct bcm_firmware_info *psFwInfo) -{ - int retval = STATUS_SUCCESS; - B_UINT32 value = 0; - - if (Adapter->pstargetparams == NULL) { - Adapter->pstargetparams = - kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); - if (Adapter->pstargetparams == NULL) - return -ENOMEM; - } - - if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params)) - return -EIO; - - retval = copy_from_user(Adapter->pstargetparams, - psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength); - if (retval) { - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -EFAULT; - } - - /* Parse the structure and then Download the Firmware */ - beceem_parse_target_struct(Adapter); - - /* Initializing the NVM. */ - BcmInitNVM(Adapter); - retval = InitLedSettings(Adapter); - - if (retval) - return retval; - - if (Adapter->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->LEDInfo.bLedInitDone = false; - Adapter->DriverState = DRIVER_INIT; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - if (Adapter->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = FW_DOWNLOAD; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - /* Initialize the DDR Controller */ - retval = ddr_init(Adapter); - if (retval) - return retval; - - value = 0; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, - &value, sizeof(value)); - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, - &value, sizeof(value)); - - if (Adapter->eNVMType == NVM_FLASH) { - retval = PropagateCalParamsFromFlashToMemory(Adapter); - if (retval) - return retval; - } - - retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, - sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR); - - if (retval) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, - MP_INIT, DBG_LVL_ALL, - "configuration file not downloaded properly"); - else - Adapter->bCfgDownloaded = TRUE; - - return retval; -} - -int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, - struct bcm_firmware_info *psFwInfo) -{ - int retval = STATUS_SUCCESS; - PUCHAR buff = NULL; - - /* Config File is needed for the Driver to download the Config file and - * Firmware. Check for the Config file to be first to be sent from the - * Application - */ - atomic_set(&Adapter->uiMBupdate, false); - if (!Adapter->bCfgDownloaded && - psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { - /* Can't Download Firmware. */ - return -EINVAL; - } - - /* If Config File, Finish the DDR Settings and then Download CFG File */ - if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { - retval = bcm_download_config_file(Adapter, psFwInfo); - } else { - buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); - if (buff == NULL) - return -ENOMEM; - - retval = copy_from_user(buff, - psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength); - if (retval != STATUS_SUCCESS) { - retval = -EFAULT; - goto error; - } - - retval = buffDnldVerify(Adapter, - buff, - psFwInfo->u32FirmwareLength, - psFwInfo->u32StartingAddress); - - if (retval != STATUS_SUCCESS) - goto error; - } - -error: - kfree(buff); - return retval; -} - -static INT buffDnld(struct bcm_mini_adapter *Adapter, - PUCHAR mappedbuffer, UINT u32FirmwareLength, - ULONG u32StartingAddress) -{ - unsigned int len = 0; - int retval = STATUS_SUCCESS; - - len = u32FirmwareLength; - - while (u32FirmwareLength) { - len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); - - if (retval) - break; - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer += len; - } - return retval; -} - -static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, - PUCHAR mappedbuffer, UINT u32FirmwareLength, - ULONG u32StartingAddress) -{ - UINT len = u32FirmwareLength; - INT retval = STATUS_SUCCESS; - PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - int bytes; - - if (NULL == readbackbuff) - return -ENOMEM; - - while (u32FirmwareLength && !retval) { - len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len); - - if (bytes < 0) { - retval = bytes; - break; - } - - if (memcmp(readbackbuff, mappedbuffer, len) != 0) { - pr_err("%s() failed. The firmware doesn't match what was written", - __func__); - retval = -EIO; - } - - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer += len; - - } /* end of while (u32FirmwareLength && !retval) */ - kfree(readbackbuff); - return retval; -} - -INT buffDnldVerify(struct bcm_mini_adapter *Adapter, - unsigned char *mappedbuffer, - unsigned int u32FirmwareLength, - unsigned long u32StartingAddress) -{ - INT status = STATUS_SUCCESS; - - status = buffDnld(Adapter, mappedbuffer, - u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) - goto error; - - status = buffRdbkVerify(Adapter, mappedbuffer, - u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) - goto error; -error: - return status; -} diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c deleted file mode 100644 index 612c89fba341..000000000000 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ /dev/null @@ -1,274 +0,0 @@ -#include "headers.h" - -/* -Function: InterfaceIdleModeWakeup - -Description: This is the hardware specific Function for - waking up HW device from Idle mode. - A software abort pattern is written to the - device to wake it and necessary power state - transitions from host are performed here. - -Input parameters: IN struct bcm_mini_adapter *Adapter - - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface - was successful. - Other - If an error occurred. -*/ - -/* -Function: InterfaceIdleModeRespond - -Description: This is the hardware specific Function for - responding to Idle mode request from target. - Necessary power state transitions from host for - idle mode or other device specific initializations - are performed here. - -Input parameters: IN struct bcm_mini_adapter * Adapter - - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Idle mode response related - HW configuration was successful. - Other - If an error occurred. -*/ - -/* -"dmem bfc02f00 100" tells how many time device went in Idle mode. -this value will be at address bfc02fa4.just before value d0ea1dle. - -Set time value by writing at bfc02f98 7d0 - -checking the Ack timer expire on kannon by running command -d qcslog .. if it shows e means host has not send response -to f/w with in 200 ms. Response should be -send to f/w with in 200 ms after the Idle/Shutdown req issued - -*/ - - -int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, - unsigned int *puiBuffer) -{ - int status = STATUS_SUCCESS; - unsigned int uiRegRead = 0; - int bytes; - - if (ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) { - if (ntohl(*(puiBuffer+1)) == 0) { - - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - uiRegRead = 0x00000000; - status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - } - /* Below Register should not br read in case of - * Manual and Protocol Idle mode */ - else if (Adapter->ulPowerSaveMode != - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - } - - /* Set Idle Mode Flag to False and - * Clear IdleMode reg. */ - Adapter->IdleMode = false; - Adapter->bTriedToWakeUpFromlowPowerMode = false; - - wake_up(&Adapter->lowpower_mode_wait_queue); - - } else { - if (TRUE == Adapter->IdleMode) - return status; - - uiRegRead = 0; - - if (Adapter->chip_id == BCS220_2 || - Adapter->chip_id == BCS220_2BC || - Adapter->chip_id == BCS250_BC || - Adapter->chip_id == BCS220_3) { - - bytes = rdmalt(Adapter, HPM_CONFIG_MSW, - &uiRegRead, sizeof(uiRegRead)); - if (bytes < 0) { - status = bytes; - return status; - } - - - uiRegRead |= (1<<17); - - status = wrmalt(Adapter, HPM_CONFIG_MSW, - &uiRegRead, sizeof(uiRegRead)); - if (status) - return status; - } - SendIdleModeResponse(Adapter); - } - } else if (ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) { - OverrideServiceFlowParams(Adapter, puiBuffer); - } - return status; -} - -static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, - unsigned int Pattern) -{ - int status = STATUS_SUCCESS; - unsigned int value; - unsigned int chip_id; - unsigned long timeout = 0, itr = 0; - - int lenwritten = 0; - unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF}; - struct bcm_interface_adapter *psInterfaceAdapter = - Adapter->pvInterfaceAdapter; - - /* Abort Bus suspend if its already suspended */ - if ((TRUE == psInterfaceAdapter->bSuspended) && - (TRUE == Adapter->bDoSuspend)) - status = usb_autopm_get_interface( - psInterfaceAdapter->interface); - - if ((Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) || - (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { - /* write the SW abort pattern. */ - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &Pattern, sizeof(Pattern)); - if (status) - return status; - } - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - value = 0x80000000; - status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &value, sizeof(value)); - if (status) - return status; - } else if (Adapter->ulPowerSaveMode != - DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - /* - * Get a Interrupt Out URB and send 8 Bytes Down - * To be Done in Thread Context. - * Not using Asynchronous Mechanism. - */ - status = usb_interrupt_msg(psInterfaceAdapter->udev, - usb_sndintpipe(psInterfaceAdapter->udev, - psInterfaceAdapter->sIntrOut.int_out_endpointAddr), - aucAbortPattern, - 8, - &lenwritten, - 5000); - if (status) - return status; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "NOB Sent down :%d", lenwritten); - - /* mdelay(25); */ - - timeout = jiffies + msecs_to_jiffies(50); - while (time_after(timeout, jiffies)) { - itr++; - rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT)); - if (0xbece3200 == (chip_id&~(0xF0))) - chip_id = chip_id&~(0xF0); - if (chip_id == Adapter->chip_id) - break; - } - if (time_before(timeout, jiffies)) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Not able to read chip-id even after 25 msec"); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Number of completed iteration to read chip-id :%lu", itr); - - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, - &Pattern, sizeof(status)); - if (status) - return status; - } - return status; -} -int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->bTriedToWakeUpFromlowPowerMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - IDLE_MODE, DBG_LVL_ALL, - "Wake up already attempted.. ignoring\n"); - } else { - Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; - InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern); - - } - return 0; -} - -void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiRegVal = 0; - INT Status = 0; - int bytes; - - if (Adapter->ulPowerSaveMode == - DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - /* clear idlemode interrupt. */ - uiRegVal = 0; - Status = wrmalt(Adapter, - DEBUG_INTERRUPT_GENERATOR_REGISTOR, - &uiRegVal, sizeof(uiRegVal)); - if (Status) - return; - } - - else { - -/* clear Interrupt EP registers. */ - bytes = rdmalt(Adapter, - DEVICE_INT_OUT_EP_REG0, - &uiRegVal, sizeof(uiRegVal)); - if (bytes < 0) { - Status = bytes; - return; - } - - bytes = rdmalt(Adapter, - DEVICE_INT_OUT_EP_REG1, - &uiRegVal, sizeof(uiRegVal)); - if (bytes < 0) { - Status = bytes; - return; - } - } -} - diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h deleted file mode 100644 index 2ef64003aa89..000000000000 --- a/drivers/staging/bcm/InterfaceIdleMode.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _INTERFACE_IDLEMODE_H -#define _INTERFACE_IDLEMODE_H - -INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter); - -INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, - unsigned int *puiBuffer); - -VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter); - -INT InterfaceWakeUp(struct bcm_mini_adapter *Adapter); - -VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter); -#endif - diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c deleted file mode 100644 index 9eaffd884a4c..000000000000 --- a/drivers/staging/bcm/InterfaceInit.c +++ /dev/null @@ -1,729 +0,0 @@ -#include "headers.h" -#include -static struct usb_device_id InterfaceUsbtable[] = { - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) }, - { } -}; -MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); - -static int debug = -1; -module_param(debug, int, 0600); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -static const u32 default_msg = - NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; - -static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter); - -static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter) -{ - int i = 0; - struct bcm_mini_adapter *ps_ad = psIntfAdapter->psAdapter; - - /* Wake up the wait_queue... */ - if (ps_ad->LEDInfo.led_thread_running & - BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_ad->DriverState = DRIVER_HALT; - wake_up(&ps_ad->LEDInfo.notify_led_event); - } - reset_card_proc(ps_ad); - - /* - * worst case time taken by the RDM/WRM will be 5 sec. will check after - * every 100 ms to accertain the device is not being accessed. After - * this No RDM/WRM should be made. - */ - while (ps_ad->DeviceAccess) { - BCM_DEBUG_PRINT(ps_ad, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "Device is being accessed.\n"); - msleep(100); - } - /* Free interrupt URB */ - /* ps_ad->device_removed = TRUE; */ - usb_free_urb(psIntfAdapter->psInterruptUrb); - - /* Free transmit URBs */ - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - if (psIntfAdapter->asUsbTcb[i].urb != NULL) { - usb_free_urb(psIntfAdapter->asUsbTcb[i].urb); - psIntfAdapter->asUsbTcb[i].urb = NULL; - } - } - /* Free receive URB and buffers */ - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - if (psIntfAdapter->asUsbRcb[i].urb != NULL) { - kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); - usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); - psIntfAdapter->asUsbRcb[i].urb = NULL; - } - } - AdapterFree(ps_ad); -} - -static void ConfigureEndPointTypesThroughEEPROM( - struct bcm_mini_adapter *Adapter) -{ - u32 ulReg; - int bytes; - struct bcm_interface_adapter *interfaceAdapter; - - /* Program EP2 MAX_PKT_SIZE */ - ulReg = ntohl(EP2_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x128, 4, TRUE); - ulReg = ntohl(EP2_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x12C, 4, TRUE); - - ulReg = ntohl(EP2_CFG_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE); - interfaceAdapter = - (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); - if (interfaceAdapter->bHighSpeedDevice) { - ulReg = ntohl(EP2_CFG_INT); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); - } else { - /* USE BULK EP as TX in FS mode. */ - ulReg = ntohl(EP2_CFG_BULK); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); - } - - /* Program EP4 MAX_PKT_SIZE. */ - ulReg = ntohl(EP4_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x13C, 4, TRUE); - ulReg = ntohl(EP4_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE); - - /* Program TX EP as interrupt(Alternate Setting) */ - bytes = rdmalt(Adapter, 0x0F0110F8, &ulReg, sizeof(u32)); - if (bytes < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "reading of Tx EP failed\n"); - return; - } - ulReg |= 0x6; - - ulReg = ntohl(ulReg); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1CC, 4, TRUE); - - ulReg = ntohl(EP4_CFG_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C8, 4, TRUE); - /* Program ISOCHRONOUS EP size to zero. */ - ulReg = ntohl(ISO_MPS_REG); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D2, 4, TRUE); - ulReg = ntohl(ISO_MPS); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D6, 4, TRUE); - - /* - * Update EEPROM Version. - * Read 4 bytes from 508 and modify 511 and 510. - */ - ReadBeceemEEPROM(Adapter, 0x1FC, &ulReg); - ulReg &= 0x0101FFFF; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE); - - /* - * Update length field if required. - * Also make the string NULL terminated. - */ - - ReadBeceemEEPROM(Adapter, 0xA8, &ulReg); - if ((ulReg&0x00FF0000)>>16 > 0x30) { - ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE); - } - ReadBeceemEEPROM(Adapter, 0x148, &ulReg); - if ((ulReg&0x00FF0000)>>16 > 0x30) { - ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE); - } - ulReg = 0; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x122, 4, TRUE); - ulReg = 0; - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE); -} - -static int usbbcm_device_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int retval; - struct bcm_mini_adapter *psAdapter; - struct bcm_interface_adapter *psIntfAdapter; - struct net_device *ndev; - - /* Reserve one extra queue for the bit-bucket */ - ndev = alloc_etherdev_mq(sizeof(struct bcm_mini_adapter), - NO_OF_QUEUES + 1); - if (ndev == NULL) { - dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); - return -ENOMEM; - } - - SET_NETDEV_DEV(ndev, &intf->dev); - - psAdapter = netdev_priv(ndev); - psAdapter->dev = ndev; - psAdapter->msg_enable = netif_msg_init(debug, default_msg); - - /* Init default driver debug state */ - - psAdapter->stDebugState.debug_level = DBG_LVL_CURR; - psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; - - /* - * Technically, one can start using BCM_DEBUG_PRINT after this point. - * However, realize that by default the Type/Subtype bitmaps are all - * zero now; so no prints will actually appear until the TestApp turns - * on debug paths via the ioctl(); so practically speaking, in early - * init, no logging happens. - * - * A solution (used below): we explicitly set the bitmaps to 1 for - * Type=DBG_TYPE_INITEXIT and ALL subtype's of the same. Now all bcm - * debug statements get logged, enabling debug during early init. - * Further, we turn this OFF once init_module() completes. - */ - - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; - BCM_SHOW_DEBUG_BITMAP(psAdapter); - - retval = InitAdapter(psAdapter); - if (retval) { - dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n"); - AdapterFree(psAdapter); - return retval; - } - - /* Allocate interface adapter structure */ - psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter), - GFP_KERNEL); - if (psIntfAdapter == NULL) { - AdapterFree(psAdapter); - return -ENOMEM; - } - - psAdapter->pvInterfaceAdapter = psIntfAdapter; - psIntfAdapter->psAdapter = psAdapter; - - /* Store usb interface in Interface Adapter */ - psIntfAdapter->interface = intf; - usb_set_intfdata(intf, psIntfAdapter); - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "psIntfAdapter 0x%p\n", psIntfAdapter); - retval = InterfaceAdapterInit(psIntfAdapter); - if (retval) { - /* If the Firmware/Cfg File is not present - * then return success, let the application - * download the files. - */ - if (-ENOENT == retval) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "File Not Found. Use app to download.\n"); - return STATUS_SUCCESS; - } - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, "InterfaceAdapterInit failed.\n"); - usb_set_intfdata(intf, NULL); - udev = interface_to_usbdev(intf); - usb_put_dev(udev); - InterfaceAdapterFree(psIntfAdapter); - return retval; - } - if (psAdapter->chip_id > T3) { - uint32_t uiNackZeroLengthInt = 4; - - retval = - wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, - &uiNackZeroLengthInt, - sizeof(uiNackZeroLengthInt)); - if (retval) - return retval; - } - - /* Check whether the USB-Device Supports remote Wake-Up */ - if (USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) { - /* If Suspend then only support dynamic suspend */ - if (psAdapter->bDoSuspend) { -#ifdef CONFIG_PM - pm_runtime_set_autosuspend_delay(&udev->dev, 0); - intf->needs_remote_wakeup = 1; - usb_enable_autosuspend(udev); - device_init_wakeup(&intf->dev, 1); - INIT_WORK(&psIntfAdapter->usbSuspendWork, - putUsbSuspend); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Enabling USB Auto-Suspend\n"); -#endif - } else { - intf->needs_remote_wakeup = 0; - usb_disable_autosuspend(udev); - } - } - - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; - return retval; -} - -static void usbbcm_disconnect(struct usb_interface *intf) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - struct bcm_mini_adapter *psAdapter; - struct usb_device *udev = interface_to_usbdev(intf); - - if (psIntfAdapter == NULL) - return; - - psAdapter = psIntfAdapter->psAdapter; - netif_device_detach(psAdapter->dev); - - if (psAdapter->bDoSuspend) - intf->needs_remote_wakeup = 0; - - psAdapter->device_removed = TRUE; - usb_set_intfdata(intf, NULL); - InterfaceAdapterFree(psIntfAdapter); - usb_put_dev(udev); -} - -static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter) -{ - int i = 0; - - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); - - if (psIntfAdapter->asUsbTcb[i].urb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Tx urb for index %d\n", - i); - return -ENOMEM; - } - } - - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); - - if (psIntfAdapter->asUsbRcb[i].urb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Rx urb for index %d\n", - i); - return -ENOMEM; - } - - psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = - kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL); - - if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Can't allocate Rx buffer for index %d\n", - i); - return -ENOMEM; - } - psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = - MAX_DATA_BUFFER_SIZE; - } - return 0; -} - -static int device_run(struct bcm_interface_adapter *psIntfAdapter) -{ - int value = 0; - UINT status = STATUS_SUCCESS; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - status = InitCardAndDownloadFirmware(psAd); - if (status != STATUS_SUCCESS) { - pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n"); - return status; - } - if (psAd->fw_download_done) { - if (StartInterruptUrb(psIntfAdapter)) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Cannot send interrupt in URB\n"); - } - - /* - * now register the cntrl interface. after downloading the f/w - * waiting for 5 sec to get the mailbox interrupt. - */ - psAd->waiting_to_fw_download_done = false; - value = wait_event_timeout(psAd->ioctl_fw_dnld_wait_queue, - psAd->waiting_to_fw_download_done, - 5 * HZ); - - if (value == 0) - pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n"); - - if (register_control_device_interface(psAd) < 0) { - pr_err(DRV_NAME ": Register Control Device failed.\n"); - return -EIO; - } - } - return 0; -} - -static int select_alternate_setting_for_highspeed_modem( - struct bcm_interface_adapter *psIntfAdapter, - struct usb_endpoint_descriptor **endpoint, - const struct usb_host_interface *iface_desc, - int *usedIntOutForBulkTransfer) -{ - int retval = 0; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - /* selecting alternate setting one as a default setting - * for High Speed modem. */ - if (psIntfAdapter->bHighSpeedDevice) - retval = usb_set_interface(psIntfAdapter->udev, - DEFAULT_SETTING_0, - ALTERNATE_SETTING_1); - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "BCM16 is applicable on this dongle\n"); - if (retval || !psIntfAdapter->bHighSpeedDevice) { - *usedIntOutForBulkTransfer = EP2; - *endpoint = &iface_desc->endpoint[EP2].desc; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n"); - /* - * If Modem is high speed device EP2 should be - * INT OUT End point - * - * If Mode is FS then EP2 should be bulk end - * point - */ - if ((psIntfAdapter->bHighSpeedDevice && - !usb_endpoint_is_int_out(*endpoint)) || - (!psIntfAdapter->bHighSpeedDevice && - !usb_endpoint_is_bulk_out(*endpoint))) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Configuring the EEPROM\n"); - /* change the EP2, EP4 to INT OUT end point */ - ConfigureEndPointTypesThroughEEPROM( - psAd); - - /* - * It resets the device and if any thing - * gets changed in USB descriptor it - * will show fail and re-enumerate the - * device - */ - retval = usb_reset_device(psIntfAdapter->udev); - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, - DRV_ENTRY, DBG_LVL_ALL, - "reset failed. Re-enumerating the device.\n"); - return retval; - } - - } - if (!psIntfAdapter->bHighSpeedDevice && - usb_endpoint_is_bulk_out(*endpoint)) { - /* - * Once BULK is selected in FS mode. - * Revert it back to INT. - * Else USB_IF will fail. - */ - UINT _uiData = ntohl(EP2_CFG_INT); - - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Reverting Bulk to INT as it is in Full Speed mode.\n"); - BeceemEEPROMBulkWrite(psAd, (PUCHAR) & _uiData, 0x136, - 4, TRUE); - } - } else { - *usedIntOutForBulkTransfer = EP4; - *endpoint = &iface_desc->endpoint[EP4].desc; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Choosing AltSetting as a default setting.\n"); - if (!usb_endpoint_is_int_out(*endpoint)) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Dongle does not have BCM16 Fix.\n"); - /* - * change the EP2, EP4 to INT OUT end point and use EP4 - * in altsetting - */ - ConfigureEndPointTypesThroughEEPROM(psAd); - - /* - * It resets the device and if any thing - * gets changed in USB descriptor it - * will show fail and re-enumerate the - * device - */ - retval = usb_reset_device(psIntfAdapter->udev); - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, - DRV_ENTRY, DBG_LVL_ALL, - "reset failed. Re-enumerating the device.\n"); - return retval; - } - } - } - - return 0; -} - -static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter) -{ - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - size_t buffer_size; - unsigned long value; - int retval = 0; - int usedIntOutForBulkTransfer = 0; - bool bBcm16 = false; - UINT uiData = 0; - int bytes; - struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter; - - /* Store the usb dev into interface adapter */ - psIntfAdapter->udev = - usb_get_dev(interface_to_usbdev(psIntfAdapter->interface)); - - psIntfAdapter->bHighSpeedDevice = - (psIntfAdapter->udev->speed == USB_SPEED_HIGH); - psAd->interface_rdm = BcmRDM; - psAd->interface_wrm = BcmWRM; - - bytes = rdmalt(psAd, CHIP_ID_REG, (u32 *) &(psAd->chip_id), - sizeof(u32)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0, - "CHIP ID Read Failed\n"); - return retval; - } - - if (0xbece3200 == (psAd->chip_id & ~(0xF0))) - psAd->chip_id &= ~0xF0; - - dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n", - psAd->chip_id); - - iface_desc = psIntfAdapter->interface->cur_altsetting; - - if (psAd->chip_id == T3B) { - /* T3B device will have EEPROM, check if EEPROM is proper and - * BCM16 can be done or not. */ - BeceemEEPROMBulkRead(psAd, &uiData, 0x0, 4); - if (uiData == BECM) - bBcm16 = TRUE; - - dev_info(&psIntfAdapter->udev->dev, - "number of alternate setting %d\n", - psIntfAdapter->interface->num_altsetting); - - if (bBcm16 == TRUE) { - retval = select_alternate_setting_for_highspeed_modem( - psIntfAdapter, &endpoint, iface_desc, - &usedIntOutForBulkTransfer); - if (retval) - return retval; - } - } - - iface_desc = psIntfAdapter->interface->cur_altsetting; - - for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) { - endpoint = &iface_desc->endpoint[value].desc; - - if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && - usb_endpoint_is_bulk_in(endpoint)) { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; - psIntfAdapter->sBulkIn.bulk_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkIn.bulk_in_pipe = usb_rcvbulkpipe( - psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_endpointAddr); - } - - if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && - usb_endpoint_is_bulk_out(endpoint)) { - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndbulkpipe( - psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_endpointAddr); - } - - if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && - usb_endpoint_is_int_in(endpoint)) { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrIn.int_in_size = buffer_size; - psIntfAdapter->sIntrIn.int_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrIn.int_in_interval = - endpoint->bInterval; - psIntfAdapter->sIntrIn.int_in_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!psIntfAdapter->sIntrIn.int_in_buffer) - return -EINVAL; - } - - if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && - usb_endpoint_is_int_out(endpoint)) { - if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && - (psAd->chip_id == T3B) && - (value == usedIntOutForBulkTransfer)) { - /* - * use first intout end point as a bulk out end - * point - */ - buffer_size = - le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkOut.bulk_out_size = - buffer_size; - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = - usb_sndintpipe(psIntfAdapter->udev, - psIntfAdapter->sBulkOut - .bulk_out_endpointAddr); - psIntfAdapter->sBulkOut.int_out_interval = - endpoint->bInterval; - } else if (value == EP6) { - buffer_size = - le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrOut.int_out_size = - buffer_size; - psIntfAdapter->sIntrOut.int_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrOut.int_out_interval = - endpoint->bInterval; - psIntfAdapter->sIntrOut.int_out_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!psIntfAdapter->sIntrOut.int_out_buffer) - return -EINVAL; - } - } - } - - usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); - - psAd->bcm_file_download = InterfaceFileDownload; - psAd->bcm_file_readback_from_chip = InterfaceFileReadbackFromChip; - psAd->interface_transmit = InterfaceTransmitPacket; - - retval = CreateInterruptUrb(psIntfAdapter); - - if (retval) { - BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0, - "Cannot create interrupt urb\n"); - return retval; - } - - retval = AllocUsbCb(psIntfAdapter); - if (retval) - return retval; - - return device_run(psIntfAdapter); -} - -static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - - psIntfAdapter->bSuspended = TRUE; - - if (psIntfAdapter->bPreparingForBusSuspend) { - psIntfAdapter->bPreparingForBusSuspend = false; - - if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) { - psIntfAdapter->psAdapter->IdleMode = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Host Entered in PMU Idle Mode.\n"); - } else { - psIntfAdapter->psAdapter->bShutStatus = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, DRV_ENTRY, - DBG_LVL_ALL, - "Host Entered in PMU Shutdown Mode.\n"); - } - } - psIntfAdapter->psAdapter->bPreparingForLowPowerMode = false; - - /* Signaling the control pkt path */ - wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); - - return 0; -} - -static int InterfaceResume(struct usb_interface *intf) -{ - struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); - - mdelay(100); - psIntfAdapter->bSuspended = false; - - StartInterruptUrb(psIntfAdapter); - InterfaceRx(psIntfAdapter); - return 0; -} - -static struct usb_driver usbbcm_driver = { - .name = "usbbcm", - .probe = usbbcm_device_probe, - .disconnect = usbbcm_disconnect, - .suspend = InterfaceSuspend, - .resume = InterfaceResume, - .id_table = InterfaceUsbtable, - .supports_autosuspend = 1, -}; - -struct class *bcm_class; - -static __init int bcm_init(void) -{ - int retval; - - pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); - pr_info("%s\n", DRV_COPYRIGHT); - - bcm_class = class_create(THIS_MODULE, DRV_NAME); - if (IS_ERR(bcm_class)) { - pr_err(DRV_NAME ": could not create class\n"); - return PTR_ERR(bcm_class); - } - - retval = usb_register(&usbbcm_driver); - if (retval < 0) { - pr_err(DRV_NAME ": could not register usb driver\n"); - class_destroy(bcm_class); - return retval; - } - return 0; -} - -static __exit void bcm_exit(void) -{ - usb_deregister(&usbbcm_driver); - class_destroy(bcm_class); -} - -module_init(bcm_init); -module_exit(bcm_exit); - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h deleted file mode 100644 index ffa6e9667ec4..000000000000 --- a/drivers/staging/bcm/InterfaceInit.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _INTERFACE_INIT_H -#define _INTERFACE_INIT_H - -#define BCM_USB_VENDOR_ID_T3 0x198f -#define BCM_USB_VENDOR_ID_FOXCONN 0x0489 -#define BCM_USB_VENDOR_ID_ZTE 0x19d2 - -#define BCM_USB_PRODUCT_ID_T3 0x0300 -#define BCM_USB_PRODUCT_ID_T3B 0x0210 -#define BCM_USB_PRODUCT_ID_T3L 0x0220 -#define BCM_USB_PRODUCT_ID_SYM 0x15E -#define BCM_USB_PRODUCT_ID_1901 0xe017 -#define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */ -#define BCM_USB_PRODUCT_ID_ZTE_226 0x172 -#define BCM_USB_PRODUCT_ID_ZTE_326 0x173 /* ZTE AX326 */ -#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 - -#define BCM_USB_MINOR_BASE 192 - -int InterfaceInitialize(void); - -int InterfaceExit(void); - -int usbbcm_worker_thread(struct bcm_interface_adapter *psIntfAdapter); - -#endif diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c deleted file mode 100644 index b9f8a7aa24fe..000000000000 --- a/drivers/staging/bcm/InterfaceIsr.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "headers.h" - - -static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) -{ - int status = urb->status; - struct bcm_interface_adapter *psIntfAdapter = - (struct bcm_interface_adapter *)urb->context; - struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; - - if (netif_msg_intr(Adapter)) - pr_info(PFX "%s: interrupt status %d\n", - Adapter->dev->name, status); - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Device has Got Removed."); - return; - } - - if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) || - psIntfAdapter->bSuspended || - psIntfAdapter->bPreparingForBusSuspend) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Interrupt call back is called while suspending the device"); - return; - } - - switch (status) { - /* success */ - case STATUS_SUCCESS: - if (urb->actual_length) { - - if (psIntfAdapter->ulInterruptData[1] & 0xFF) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "Got USIM interrupt"); - } - - if (psIntfAdapter->ulInterruptData[1] & 0xFF00) { - atomic_set(&Adapter->CurrNumFreeTxDesc, - (psIntfAdapter->ulInterruptData[1] & - 0xFF00) >> 8); - atomic_set(&Adapter->uiMBupdate, TRUE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "TX mailbox contains %d", - atomic_read(&Adapter->CurrNumFreeTxDesc)); - } - if (psIntfAdapter->ulInterruptData[1] >> 16) { - Adapter->CurrNumRecvDescs = - (psIntfAdapter->ulInterruptData[1] >> 16); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "RX mailbox contains %d", - Adapter->CurrNumRecvDescs); - InterfaceRx(psIntfAdapter); - } - if (Adapter->fw_download_done && - !Adapter->downloadDDR && - atomic_read(&Adapter->CurrNumFreeTxDesc)) { - - psIntfAdapter->psAdapter->downloadDDR += 1; - wake_up(&Adapter->tx_packet_wait_queue); - } - if (!Adapter->waiting_to_fw_download_done) { - Adapter->waiting_to_fw_download_done = TRUE; - wake_up(&Adapter->ioctl_fw_dnld_wait_queue); - } - if (!atomic_read(&Adapter->TxPktAvail)) { - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Firing interrupt in URB"); - } - break; - case -ENOENT: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "URB has got disconnected...."); - return; - case -EINPROGRESS: - /* - * This situation may happened when URBunlink is used. for - * detail check usb_unlink_urb documentation. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Impossibe condition has occurred... something very bad is going on"); - break; - /* return; */ - case -EPIPE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Interrupt IN endPoint has got halted/stalled...need to clear this"); - Adapter->bEndPointHalted = TRUE; - wake_up(&Adapter->tx_packet_wait_queue); - urb->status = STATUS_SUCCESS; - return; - /* software-driven interface shutdown */ - case -ECONNRESET: /* URB got unlinked */ - case -ESHUTDOWN: /* hardware gone. this is the serious problem */ - /* - * Occurs only when something happens with the - * host controller device - */ - case -ENODEV: /* Device got removed */ - case -EINVAL: - /* - * Some thing very bad happened with the URB. No - * description is available. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "interrupt urb error %d", status); - urb->status = STATUS_SUCCESS; - break; - /* return; */ - default: - /* - * This is required to check what is the defaults conditions - * when it occurs.. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", - status); - break; - } - - StartInterruptUrb(psIntfAdapter); - - -} - -int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) -{ - psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); - if (!psIntfAdapter->psInterruptUrb) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, - INTF_INIT, DBG_LVL_ALL, - "Cannot allocate interrupt urb"); - return -ENOMEM; - } - psIntfAdapter->psInterruptUrb->transfer_buffer = - psIntfAdapter->ulInterruptData; - psIntfAdapter->psInterruptUrb->transfer_buffer_length = - sizeof(psIntfAdapter->ulInterruptData); - - psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_endpointAddr); - - usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_pipe, - psIntfAdapter->psInterruptUrb->transfer_buffer, - psIntfAdapter->psInterruptUrb->transfer_buffer_length, - read_int_callback, psIntfAdapter, - psIntfAdapter->sIntrIn.int_in_interval); - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, "Interrupt Interval: %d\n", - psIntfAdapter->sIntrIn.int_in_interval); - return 0; -} - - -INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) -{ - INT status = 0; - - if (!(psIntfAdapter->psAdapter->device_removed || - psIntfAdapter->psAdapter->bEndPointHalted || - psIntfAdapter->bSuspended || - psIntfAdapter->bPreparingForBusSuspend || - psIntfAdapter->psAdapter->StopAllXaction)) { - status = - usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC); - if (status) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, - "Cannot send inturb %d\n", status); - if (status == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = - TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - } - } - return status; -} - diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h deleted file mode 100644 index 3073bd71cfeb..000000000000 --- a/drivers/staging/bcm/InterfaceIsr.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _INTERFACE_ISR_H -#define _INTERFACE_ISR_H - -int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); - - -INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); - - -VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter); - -VOID InterfaceDisableInterrupt(struct bcm_mini_adapter *Adapter); - -#endif - diff --git a/drivers/staging/bcm/InterfaceMacros.h b/drivers/staging/bcm/InterfaceMacros.h deleted file mode 100644 index fedb79437f33..000000000000 --- a/drivers/staging/bcm/InterfaceMacros.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _INTERFACE_MACROS_H -#define _INTERFACE_MACROS_H - -#define BCM_USB_MAX_READ_LENGTH 2048 - -#define MAXIMUM_USB_TCB 128 -#define MAXIMUM_USB_RCB 128 - -#define MAX_BUFFERS_PER_QUEUE 256 - -#define MAX_DATA_BUFFER_SIZE 2048 - -/* Num of Asynchronous reads pending */ -#define NUM_RX_DESC 64 - -#define SYS_CFG 0x0F000C00 - -#endif diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c deleted file mode 100644 index 1f31b8f05884..000000000000 --- a/drivers/staging/bcm/InterfaceMisc.c +++ /dev/null @@ -1,246 +0,0 @@ -#include "headers.h" - -static int adapter_err_occurred(const struct bcm_interface_adapter *ad) -{ - if (ad->psAdapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "Device got removed"); - return -ENODEV; - } - - if ((ad->psAdapter->StopAllXaction == TRUE) && - (ad->psAdapter->chip_id >= T3LPB)) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, - "Currently Xaction is not allowed on the bus"); - return -EACCES; - } - - if (ad->bSuspended == TRUE || ad->bPreparingForBusSuspend == TRUE) { - BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, - "Bus is in suspended states hence RDM not allowed.."); - return -EACCES; - } - - return 0; -} - -int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, - unsigned int addr, - void *buff, - int len) -{ - int bytes; - int err = 0; - - if (!psIntfAdapter) - return -EINVAL; - - err = adapter_err_occurred(psIntfAdapter); - if (err) - return err; - - psIntfAdapter->psAdapter->DeviceAccess = TRUE; - - bytes = usb_control_msg(psIntfAdapter->udev, - usb_rcvctrlpipe(psIntfAdapter->udev, 0), - 0x02, - 0xC2, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - if (-ENODEV == bytes) - psIntfAdapter->psAdapter->device_removed = TRUE; - - if (bytes < 0) - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, "RDM failed status :%d", bytes); - else - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, - DBG_LVL_ALL, "RDM sent %d", bytes); - - psIntfAdapter->psAdapter->DeviceAccess = false; - return bytes; -} - -int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, - unsigned int addr, - void *buff, - int len) -{ - int retval = 0; - int err = 0; - - if (!psIntfAdapter) - return -EINVAL; - - err = adapter_err_occurred(psIntfAdapter); - if (err) - return err; - - psIntfAdapter->psAdapter->DeviceAccess = TRUE; - - retval = usb_control_msg(psIntfAdapter->udev, - usb_sndctrlpipe(psIntfAdapter->udev, 0), - 0x01, - 0x42, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - if (-ENODEV == retval) - psIntfAdapter->psAdapter->device_removed = TRUE; - - if (retval < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, - DBG_LVL_ALL, "WRM failed status :%d", retval); - psIntfAdapter->psAdapter->DeviceAccess = false; - return retval; - } - psIntfAdapter->psAdapter->DeviceAccess = false; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, - DBG_LVL_ALL, "WRM sent %d", retval); - return STATUS_SUCCESS; -} - -int BcmRDM(void *arg, - unsigned int addr, - void *buff, - int len) -{ - return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff, - len); -} - -int BcmWRM(void *arg, - unsigned int addr, - void *buff, - int len) -{ - return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, - len); -} - -int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) -{ - struct bcm_interface_adapter *psIntfAdapter = - (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); - int status = STATUS_SUCCESS; - - /* - * usb_clear_halt - tells device to clear endpoint halt/stall condition - * @dev: device whose endpoint is halted - * @pipe: endpoint "pipe" being cleared - * @ Context: !in_interrupt () - * - * usb_clear_halt is the synchrnous call and returns 0 on success else - * returns with error code. - * This is used to clear halt conditions for bulk and interrupt - * endpoints only. - * Control and isochronous endpoints never halts. - * - * Any URBs queued for such an endpoint should normally be unlinked by - * the driver before clearing the halt condition. - * - */ - - /* Killing all the submitted urbs to different end points. */ - Bcm_kill_all_URBs(psIntfAdapter); - - /* clear the halted/stalled state for every end point */ - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sIntrIn.int_in_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Interrupt IN end point. :%d ", - status); - - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Bulk IN end point. :%d ", - status); - - status = usb_clear_halt(psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe); - if (status != STATUS_SUCCESS) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, - DBG_LVL_ALL, - "Unable to Clear Halt of Bulk OUT end point. :%d ", - status); - - return status; -} - -void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter) -{ - struct urb *tempUrb = NULL; - unsigned int i; - - /* - * usb_kill_urb - cancel a transfer request and wait for it to finish - * @urb: pointer to URB describing a previously submitted request, - * returns nothing as it is void returned API. - * - * This routine cancels an in-progress request. It is guaranteed that - * upon return all completion handlers will have finished and the URB - * will be totally idle and available for reuse - * - * This routine may not be used in an interrupt context (such as a - * bottom half or a completion handler), or when holding a spinlock, or - * in other situations where the caller can't schedule(). - * - */ - - /* Cancel submitted Interrupt-URB's */ - if (psIntfAdapter->psInterruptUrb) { - if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) - usb_kill_urb(psIntfAdapter->psInterruptUrb); - } - - /* Cancel All submitted TX URB's */ - for (i = 0; i < MAXIMUM_USB_TCB; i++) { - tempUrb = psIntfAdapter->asUsbTcb[i].urb; - if (tempUrb) { - if (tempUrb->status == -EINPROGRESS) - usb_kill_urb(tempUrb); - } - } - - for (i = 0; i < MAXIMUM_USB_RCB; i++) { - tempUrb = psIntfAdapter->asUsbRcb[i].urb; - if (tempUrb) { - if (tempUrb->status == -EINPROGRESS) - usb_kill_urb(tempUrb); - } - } - - atomic_set(&psIntfAdapter->uNumTcbUsed, 0); - atomic_set(&psIntfAdapter->uCurrTcb, 0); - - atomic_set(&psIntfAdapter->uNumRcbUsed, 0); - atomic_set(&psIntfAdapter->uCurrRcb, 0); -} - -void putUsbSuspend(struct work_struct *work) -{ - struct bcm_interface_adapter *psIntfAdapter = NULL; - struct usb_interface *intf = NULL; - - psIntfAdapter = container_of(work, struct bcm_interface_adapter, - usbSuspendWork); - intf = psIntfAdapter->interface; - - if (psIntfAdapter->bSuspended == false) - usb_autopm_put_interface(intf); -} - diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h deleted file mode 100644 index 0e5e38b26329..000000000000 --- a/drivers/staging/bcm/InterfaceMisc.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __INTERFACE_MISC_H -#define __INTERFACE_MISC_H - -INT -InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, - UINT addr, - PVOID buff, - INT len); - -INT -InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, - UINT addr, - PVOID buff, - INT len); - - -int InterfaceFileDownload(PVOID psIntfAdapter, - struct file *flp, - unsigned int on_chip_loc); - -int InterfaceFileReadbackFromChip(PVOID psIntfAdapter, - struct file *flp, - unsigned int on_chip_loc); - - -int BcmRDM(PVOID arg, - UINT addr, - PVOID buff, - INT len); - -int BcmWRM(PVOID arg, - UINT addr, - PVOID buff, - INT len); - -INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter); - -VOID Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter); - -#define DISABLE_USB_ZERO_LEN_INT 0x0F011878 - -#endif /* __INTERFACE_MISC_H */ diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c deleted file mode 100644 index 0f179b9382d3..000000000000 --- a/drivers/staging/bcm/InterfaceRx.c +++ /dev/null @@ -1,289 +0,0 @@ -#include "headers.h" - -static void handle_control_packet(struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ad, - struct bcm_leader *leader, - struct sk_buff *skb, - struct urb *urb) -{ - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, - "Received control pkt..."); - *(PUSHORT)skb->data = leader->Status; - memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + - (sizeof(struct bcm_leader)), leader->PLength); - skb->len = leader->PLength + sizeof(USHORT); - - spin_lock(&ad->control_queue_lock); - ENQUEUEPACKET(ad->RxControlHead, ad->RxControlTail, skb); - spin_unlock(&ad->control_queue_lock); - - atomic_inc(&ad->cntrlpktCnt); - wake_up(&ad->process_rx_cntrlpkt); -} - -static void format_eth_hdr_to_stack(struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ad, - struct bcm_leader *p_leader, - struct sk_buff *skb, - struct urb *urb, - UINT ui_index, - int queue_index, - bool b_header_supression_endabled) -{ - /* - * Data Packet, Format a proper Ethernet Header - * and give it to the stack - */ - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, - DBG_LVL_ALL, "Received Data pkt..."); - skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); - memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + - sizeof(struct bcm_leader), p_leader->PLength); - skb->dev = ad->dev; - - /* currently skb->len has extra ETH_HLEN bytes in the beginning */ - skb_put(skb, p_leader->PLength + ETH_HLEN); - ad->PackInfo[queue_index].uiTotalRxBytes += p_leader->PLength; - ad->PackInfo[queue_index].uiThisPeriodRxBytes += p_leader->PLength; - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA, - DBG_LVL_ALL, "Received Data pkt of len :0x%X", - p_leader->PLength); - - if (netif_running(ad->dev)) { - /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ - skb_pull(skb, ETH_HLEN); - PHSReceive(ad, p_leader->Vcid, skb, &skb->len, - NULL, b_header_supression_endabled); - - if (!ad->PackInfo[queue_index].bEthCSSupport) { - skb_push(skb, ETH_HLEN); - - memcpy(skb->data, skb->dev->dev_addr, 6); - memcpy(skb->data+6, skb->dev->dev_addr, 6); - (*(skb->data+11))++; - *(skb->data+12) = 0x08; - *(skb->data+13) = 0x00; - p_leader->PLength += ETH_HLEN; - } - - skb->protocol = eth_type_trans(skb, ad->dev); - netif_rx(skb); - } else { - BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, - RX_DATA, DBG_LVL_ALL, - "i/f not up hance freeing SKB..."); - dev_kfree_skb(skb); - } - - ++ad->dev->stats.rx_packets; - ad->dev->stats.rx_bytes += p_leader->PLength; - - for (ui_index = 0; ui_index < MIBS_MAX_HIST_ENTRIES; ui_index++) { - if ((p_leader->PLength <= - MIBS_PKTSIZEHIST_RANGE*(ui_index+1)) && - (p_leader->PLength > MIBS_PKTSIZEHIST_RANGE*(ui_index))) - - ad->aRxPktSizeHist[ui_index]++; - } -} - -static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid) -{ - int iIndex = 0; - - for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) - if (Adapter->PackInfo[iIndex].usVCID_Value == usVcid) - return iIndex; - return NO_OF_QUEUES+1; - -} - - -static struct bcm_usb_rcb * -GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) -{ - struct bcm_usb_rcb *pRcb = NULL; - UINT index = 0; - - if ((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && - (psIntfAdapter->psAdapter->StopAllXaction == false)) { - index = atomic_read(&psIntfAdapter->uCurrRcb); - pRcb = &psIntfAdapter->asUsbRcb[index]; - pRcb->bUsed = TRUE; - pRcb->psIntfAdapter = psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, - DBG_LVL_ALL, "Got Rx desc %d used %d", index, - atomic_read(&psIntfAdapter->uNumRcbUsed)); - index = (index + 1) % MAXIMUM_USB_RCB; - atomic_set(&psIntfAdapter->uCurrRcb, index); - atomic_inc(&psIntfAdapter->uNumRcbUsed); - } - return pRcb; -} - -/*this is receive call back - when pkt available for receive (BULK IN- end point)*/ -static void read_bulk_callback(struct urb *urb) -{ - struct sk_buff *skb = NULL; - bool bHeaderSupressionEnabled = false; - int QueueIndex = NO_OF_QUEUES + 1; - UINT uiIndex = 0; - struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context; - struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; - struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; - struct bcm_leader *pLeader = urb->transfer_buffer; - - if (unlikely(netif_msg_rx_status(Adapter))) - pr_info(PFX "%s: rx urb status %d length %d\n", - Adapter->dev->name, urb->status, urb->actual_length); - - if ((Adapter->device_removed == TRUE) || - (TRUE == Adapter->bEndPointHalted) || - (0 == urb->actual_length)) { - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - - if (urb->status != STATUS_SUCCESS) { - if (urb->status == -EPIPE) { - Adapter->bEndPointHalted = TRUE; - wake_up(&Adapter->tx_packet_wait_queue); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, - DBG_LVL_ALL, - "Rx URB has got cancelled. status :%d", - urb->status); - } - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - urb->status = STATUS_SUCCESS; - return; - } - - if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "device is going in low power mode while PMU option selected..hence rx packet should not be process"); - return; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Read back done len %d\n", pLeader->PLength); - if (!pLeader->PLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Leader Length 0"); - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, - "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", - pLeader->Status, pLeader->PLength, pLeader->Vcid); - if (MAX_CNTL_PKT_SIZE < pLeader->PLength) { - if (netif_msg_rx_err(Adapter)) - pr_info(PFX "%s: corrupted leader length...%d\n", - Adapter->dev->name, pLeader->PLength); - ++Adapter->dev->stats.rx_dropped; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - - QueueIndex = SearchVcid(Adapter, pLeader->Vcid); - if (QueueIndex < NO_OF_QUEUES) { - bHeaderSupressionEnabled = - Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; - bHeaderSupressionEnabled = - bHeaderSupressionEnabled & Adapter->bPHSEnabled; - } - - skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES + - SKB_RESERVE_ETHERNET_HEADER); - if (!skb) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, - "NO SKBUFF!!! Dropping the Packet"); - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - /* If it is a control Packet, then call handle_bcm_packet ()*/ - if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || - (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { - handle_control_packet(psIntfAdapter, Adapter, pLeader, skb, - urb); - } else { - format_eth_hdr_to_stack(psIntfAdapter, Adapter, pLeader, skb, - urb, uiIndex, QueueIndex, - bHeaderSupressionEnabled); - } - Adapter->PrevNumRecvDescs++; - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); -} - -static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, - struct bcm_usb_rcb *pRcb) -{ - struct urb *urb = pRcb->urb; - int retval = 0; - - usb_fill_bulk_urb(urb, psIntfAdapter->udev, - usb_rcvbulkpipe(psIntfAdapter->udev, - psIntfAdapter->sBulkIn.bulk_in_endpointAddr), - urb->transfer_buffer, - BCM_USB_MAX_READ_LENGTH, - read_bulk_callback, pRcb); - - if (false == psIntfAdapter->psAdapter->device_removed && - false == psIntfAdapter->psAdapter->bEndPointHalted && - false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) { - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, - RX_DPC, DBG_LVL_ALL, - "failed submitting read urb, error %d", - retval); - /* if this return value is because of pipe halt. need to clear this. */ - if (retval == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - - } - } - return retval; -} - -/* -Function: InterfaceRx - -Description: This is the hardware specific Function for Receiving - data packet/control packets from the device. - -Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - - - -Return: TRUE - If Rx was successful. - Other - If an error occurred. -*/ - -bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter) -{ - USHORT RxDescCount = NUM_RX_DESC - - atomic_read(&psIntfAdapter->uNumRcbUsed); - - struct bcm_usb_rcb *pRcb = NULL; - - while (RxDescCount) { - pRcb = GetBulkInRcb(psIntfAdapter); - if (pRcb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "Unable to get Rcb pointer"); - return false; - } - ReceiveRcb(psIntfAdapter, pRcb); - RxDescCount--; - } - return TRUE; -} - diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h deleted file mode 100644 index b4e858bcda34..000000000000 --- a/drivers/staging/bcm/InterfaceRx.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _INTERFACE_RX_H -#define _INTERFACE_RX_H - -bool InterfaceRx(struct bcm_interface_adapter *Adapter); - -#endif - diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c deleted file mode 100644 index 9b3f64b821ed..000000000000 --- a/drivers/staging/bcm/InterfaceTx.c +++ /dev/null @@ -1,213 +0,0 @@ -#include "headers.h" - -static void prepare_low_power_mode(struct urb *urb, - struct bcm_interface_adapter *interface, - struct bcm_mini_adapter *ps_adapter, - struct bcm_mini_adapter *ad, - struct bcm_link_request *p_control_msg, - bool *b_power_down_msg) -{ - if (((p_control_msg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && - (p_control_msg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { - - *b_power_down_msg = TRUE; - /* - * This covers the bus err while Idle Request msg - * sent down. - */ - if (urb->status != STATUS_SUCCESS) { - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Idle Mode Request msg failed to reach to Modem"); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - StartInterruptUrb(interface); - return; - } - - if (ps_adapter->bDoSuspend == false) { - ps_adapter->IdleMode = TRUE; - /* since going in Idle mode completed hence making this var false */ - ps_adapter->bPreparingForLowPowerMode = false; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Host Entered in Idle Mode State..."); - /* Signalling the cntrl pkt path in Ioctl*/ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - } - - } else if ((p_control_msg->Leader.Status == LINK_UP_CONTROL_REQ) && - (p_control_msg->szData[0] == LINK_UP_ACK) && - (p_control_msg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && - (p_control_msg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { - /* - * This covers the bus err while shutdown Request - * msg sent down. - */ - if (urb->status != STATUS_SUCCESS) { - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Shutdown Request Msg failed to reach to Modem"); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - StartInterruptUrb(interface); - return; - } - - *b_power_down_msg = TRUE; - if (ps_adapter->bDoSuspend == false) { - ps_adapter->bShutStatus = TRUE; - /* - * since going in shutdown mode completed hence - * making this var false - */ - ps_adapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Host Entered in shutdown Mode State..."); - /* Signalling the cntrl pkt path in Ioctl */ - wake_up(&ps_adapter->lowpower_mode_wait_queue); - } - } - - if (ps_adapter->bDoSuspend && *b_power_down_msg) { - /* issuing bus suspend request */ - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "Issuing the Bus suspend request to USB stack"); - interface->bPreparingForBusSuspend = TRUE; - schedule_work(&interface->usbSuspendWork); - } -} - -/*this is transmit call-back(BULK OUT)*/ -static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) -{ - struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; - struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; - struct bcm_link_request *pControlMsg = - (struct bcm_link_request *)urb->transfer_buffer; - struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; - bool bpowerDownMsg = false; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (unlikely(netif_msg_tx_done(Adapter))) - pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, - urb->status); - - if (urb->status != STATUS_SUCCESS) { - if (urb->status == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "Tx URB has got cancelled. status :%d", - urb->status); - } - } - - pTcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumTcbUsed); - - if (TRUE == psAdapter->bPreparingForLowPowerMode) { - prepare_low_power_mode(urb, psIntfAdapter, psAdapter, Adapter, - pControlMsg, &bpowerDownMsg); - } - - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); -} - - -static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) -{ - struct bcm_usb_tcb *pTcb = NULL; - UINT index = 0; - - if ((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && - (psIntfAdapter->psAdapter->StopAllXaction == false)) { - index = atomic_read(&psIntfAdapter->uCurrTcb); - pTcb = &psIntfAdapter->asUsbTcb[index]; - pTcb->bUsed = TRUE; - pTcb->psIntfAdapter = psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, - NEXT_SEND, DBG_LVL_ALL, - "Got Tx desc %d used %d", - index, - atomic_read(&psIntfAdapter->uNumTcbUsed)); - index = (index + 1) % MAXIMUM_USB_TCB; - atomic_set(&psIntfAdapter->uCurrTcb, index); - atomic_inc(&psIntfAdapter->uNumTcbUsed); - } - return pTcb; -} - -static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, - struct bcm_usb_tcb *pTcb, PVOID data, int len) -{ - - struct urb *urb = pTcb->urb; - int retval = 0; - - urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, - GFP_ATOMIC, &urb->transfer_dma); - if (!urb->transfer_buffer) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "Error allocating memory\n"); - return -ENOMEM; - } - memcpy(urb->transfer_buffer, data, len); - urb->transfer_buffer_length = len; - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, "Sending Bulk out packet\n"); - /* For T3B,INT OUT end point will be used as bulk out end point */ - if ((psIntfAdapter->psAdapter->chip_id == T3B) && - (psIntfAdapter->bHighSpeedDevice == TRUE)) { - usb_fill_int_urb(urb, psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe, - urb->transfer_buffer, len, write_bulk_callback, pTcb, - psIntfAdapter->sBulkOut.int_out_interval); - } else { - usb_fill_bulk_urb(urb, psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe, - urb->transfer_buffer, len, write_bulk_callback, pTcb); - } - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ - - if (false == psIntfAdapter->psAdapter->device_removed && - false == psIntfAdapter->psAdapter->bEndPointHalted && - false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) { - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, - NEXT_SEND, DBG_LVL_ALL, - "failed submitting write urb, error %d", - retval); - if (retval == -EPIPE) { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE; - wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - } - } - return retval; -} - -int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) -{ - struct bcm_usb_tcb *pTcb = NULL; - struct bcm_interface_adapter *psIntfAdapter = arg; - - pTcb = GetBulkOutTcb(psIntfAdapter); - if (pTcb == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, - "No URB to transmit packet, dropping packet"); - return -EFAULT; - } - return TransmitTcb(psIntfAdapter, pTcb, data, len); -} - diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h deleted file mode 100644 index 273147577c17..000000000000 --- a/drivers/staging/bcm/InterfaceTx.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _INTERFACE_TX_H -#define _INTERFACE_TX_H - -INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len); - -#endif - diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h deleted file mode 100644 index fa5f8671612e..000000000000 --- a/drivers/staging/bcm/Ioctl.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef _IOCTL_H_ -#define _IOCTL_H_ - -struct bcm_rdm_buffer { - unsigned long Register; - unsigned long Length; -} __packed; - -struct bcm_wrm_buffer { - unsigned long Register; - unsigned long Length; - unsigned char Data[4]; -} __packed; - -struct bcm_ioctl_buffer { - void __user *InputBuffer; - unsigned long InputLength; - void __user *OutputBuffer; - unsigned long OutputLength; -} __packed; - -struct bcm_gpio_info { - unsigned int uiGpioNumber; /* valid numbers 0-15 */ - unsigned int uiGpioValue; /* 1 set ; 0 not set */ -} __packed; - -struct bcm_user_thread_req { - /* 0->Inactivate LED thread. */ - /* 1->Activate the LED thread */ - unsigned int ThreadState; -} __packed; - -#define LED_THREAD_ACTIVATION_REQ 1 -#define BCM_IOCTL 'k' -#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801, int) -#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) -#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) -#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int) -#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int) -#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int) -#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int) -#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int) -#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int) -#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int) -#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int) -#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int) -#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int) -#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int) -#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int) -#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int) -#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int) -#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int) -#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char) -#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814) -#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815) -#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, struct bcm_ioctl_buffer) -#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816) -#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char) -#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817, char) -#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long) -#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long) -#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long) -#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821) -#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int) -#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int) -#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int) -#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int) -#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int) -#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int) -#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int) -#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char) -#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char) -#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, struct bcm_ioctl_buffer) -#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int) -#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int) -#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int) -#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int) -#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int) -#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int) -#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int) -#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int) -#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int) -#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int) -#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int) -#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int) -#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL, 0x867, int) -#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL, 0x868, int) -#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL, 0x869) -#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870, int) -#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int) -#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int) -#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int) -#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int) -#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int) -#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int) -#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int) -#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, struct bcm_ioctl_buffer) -#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, struct bcm_ioctl_buffer) - -enum bcm_interface_type { - BCM_MII, - BCM_CARDBUS, - BCM_USB, - BCM_SDIO, - BCM_PCMCIA -}; - -struct bcm_driver_info { - enum bcm_nvm_type u32NVMType; - unsigned int MaxRDMBufferSize; - enum bcm_interface_type u32InterfaceType; - unsigned int u32DSDStartOffset; - unsigned int u32RxAlignmentCorrection; - unsigned int u32Reserved[10]; -}; - -struct bcm_nvm_readwrite { - void __user *pBuffer; - uint32_t uiOffset; - uint32_t uiNumBytes; - bool bVerify; -}; - -struct bcm_bulk_wrm_buffer { - unsigned long Register; - unsigned long SwapEndian; - unsigned long Values[1]; -}; - -enum bcm_flash2x_section_val { - NO_SECTION_VAL = 0, /* no section chosen when absolute offset is given for RD/WR */ - ISO_IMAGE1, - ISO_IMAGE2, - DSD0, - DSD1, - DSD2, - VSA0, - VSA1, - VSA2, - SCSI, - CONTROL_SECTION, - ISO_IMAGE1_PART2, - ISO_IMAGE1_PART3, - ISO_IMAGE2_PART2, - ISO_IMAGE2_PART3, - TOTAL_SECTIONS -}; - -/* - * Structure used for READ/WRITE Flash Map2.x - */ -struct bcm_flash2x_readwrite { - enum bcm_flash2x_section_val Section; /* section to be read/written */ - u32 offset; /* offset within section. */ - u32 numOfBytes; /* number of bytes from the offset */ - u32 bVerify; - void __user *pDataBuff; /* buffer for reading/writing */ -}; - -/* - * This structure is used for coping one section to other. - * there are two ways to copy one section to other. - * it NOB =0, complete section will be copied on to other. - * if NOB !=0, only NOB will be copied from the given offset. - */ - -struct bcm_flash2x_copy_section { - enum bcm_flash2x_section_val SrcSection; - enum bcm_flash2x_section_val DstSection; - u32 offset; - u32 numOfBytes; -}; - -/* - * This section provide the complete bitmap of the Flash. - * using this map lib/APP will issue read/write command. - * Fields are defined as : - * Bit [0] = section is present //1:present, 0: Not present - * Bit [1] = section is valid //1: valid, 0: not valid - * Bit [2] = Section is R/W //0: RW, 1: RO - * Bit [3] = Section is Active or not 1 means Active, 0->inactive - * Bit [7...3] = Reserved - */ - -struct bcm_flash2x_bitmap { - unsigned char ISO_IMAGE1; - unsigned char ISO_IMAGE2; - unsigned char DSD0; - unsigned char DSD1; - unsigned char DSD2; - unsigned char VSA0; - unsigned char VSA1; - unsigned char VSA2; - unsigned char SCSI; - unsigned char CONTROL_SECTION; - /* Reserved for future use */ - unsigned char Reserved0; - unsigned char Reserved1; - unsigned char Reserved2; -}; - -struct bcm_time_elapsed { - u64 ul64TimeElapsedSinceNetEntry; - u32 uiReserved[4]; -}; - -enum { - WIMAX_IDX = 0, /* To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */ - HOST_IDX, /* To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE */ - MAX_IDX -}; - -struct bcm_gpio_multi_info { - unsigned int uiGPIOCommand; /* 1 for set and 0 for get */ - unsigned int uiGPIOMask; /* set the corresponding bit to 1 to access GPIO */ - unsigned int uiGPIOValue; /* 0 or 1; value to be set when command is 1. */ -} __packed; - -struct bcm_gpio_multi_mode { - unsigned int uiGPIOMode; /* 1 for OUT mode, 0 for IN mode */ - unsigned int uiGPIOMask; /* GPIO mask to set mode */ -} __packed; - -#endif diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig deleted file mode 100644 index 8acf4b24a7c9..000000000000 --- a/drivers/staging/bcm/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config BCM_WIMAX - tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support" - depends on USB && NET - help - This is an experimental driver for the Beceem WIMAX chipset used - by Sprint 4G. diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c deleted file mode 100644 index 86b79d6438d4..000000000000 --- a/drivers/staging/bcm/LeakyBucket.c +++ /dev/null @@ -1,363 +0,0 @@ -/********************************************************************** -* LEAKYBUCKET.C -* This file contains the routines related to Leaky Bucket Algorithm. -***********************************************************************/ -#include "headers.h" - -/** - * UpdateTokenCount() - Calculates the token count for each channel - * and updates the same in Adapter structure - * @Adapter: Pointer to the Adapter structure. - * - * Return: None - */ -static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter) -{ - ULONG liCurrentTime; - INT i = 0; - struct timeval tv; - struct bcm_packet_info *curr_pi; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "=====>\n"); - if (NULL == Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, - DBG_LVL_ALL, "Adapter found NULL!\n"); - return; - } - - do_gettimeofday(&tv); - for (i = 0; i < NO_OF_QUEUES; i++) { - curr_pi = &Adapter->PackInfo[i]; - - if (TRUE == curr_pi->bValid && (1 == curr_pi->ucDirection)) { - liCurrentTime = ((tv.tv_sec - - curr_pi->stLastUpdateTokenAt.tv_sec)*1000 + - (tv.tv_usec - curr_pi->stLastUpdateTokenAt.tv_usec) / - 1000); - if (0 != liCurrentTime) { - curr_pi->uiCurrentTokenCount += (ULONG) - ((curr_pi->uiMaxAllowedRate) * - ((ULONG)((liCurrentTime)))/1000); - memcpy(&curr_pi->stLastUpdateTokenAt, &tv, - sizeof(struct timeval)); - curr_pi->liLastUpdateTokenAt = liCurrentTime; - if (curr_pi->uiCurrentTokenCount >= - curr_pi->uiMaxBucketSize) { - curr_pi->uiCurrentTokenCount = - curr_pi->uiMaxBucketSize; - } - } - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "<=====\n"); -} - - -/** - * IsPacketAllowedForFlow() - This function checks whether the given - * packet from the specified queue can be allowed for transmission by - * checking the token count. - * @Adapter: Pointer to the Adpater structure. - * @iQIndex: The queue Identifier. - * @ulPacketLength: Number of bytes to be transmitted. - * - * Returns: The number of bytes allowed for transmission. - */ -static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IsPacketAllowedForFlow ===>"); - - /* Validate the parameters */ - if (NULL == Adapter || (psSF < Adapter->PackInfo && - (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", - Adapter, (psSF-Adapter->PackInfo)); - return 0; - } - - if (false != psSF->bValid && psSF->ucDirection) { - if (0 != psSF->uiCurrentTokenCount) { - return psSF->uiCurrentTokenCount; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, - DBG_LVL_ALL, - "Not enough tokens in queue %zd Available %u\n", - psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); - psSF->uiPendedLast = 1; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IPAFF: Queue %zd not valid\n", - psSF-Adapter->PackInfo); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, - "IsPacketAllowedForFlow <==="); - return 0; -} - -/** -@ingroup tx_functions -This function despatches packet from the specified queue. -@return Zero(success) or Negative value(failure) -*/ -static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**"); - if (!Adapter || !Packet || !psSF) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, - "Got NULL Adapter or Packet"); - return -EINVAL; - } - - if (psSF->liDrainCalculated == 0) - psSF->liDrainCalculated = jiffies; - /* send the packet to the fifo.. */ - PktLen = Packet->len; - Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); - if (Status == 0) { - for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) { - if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && - (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) - Adapter->aTxPktSizeHist[uiIndex]++; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, - "<====="); - return Status; -} - -static void get_data_packet(struct bcm_mini_adapter *ad, - struct bcm_packet_info *ps_sf) -{ - int packet_len; - struct sk_buff *qpacket; - - if (!ps_sf->ucDirection) - return; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "UpdateTokenCount "); - if (ad->IdleMode || ad->bPreparingForLowPowerMode) - return; /* in idle mode */ - - /* Check for Free Descriptors */ - if (atomic_read(&ad->CurrNumFreeTxDesc) <= - MINIMUM_PENDING_DESCRIPTORS) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - " No Free Tx Descriptor(%d) is available for Data pkt..", - atomic_read(&ad->CurrNumFreeTxDesc)); - return; - } - - spin_lock_bh(&ps_sf->SFQueueLock); - qpacket = ps_sf->FirstTxQueue; - - if (qpacket) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Dequeuing Data Packet"); - - if (ps_sf->bEthCSSupport) - packet_len = qpacket->len; - else - packet_len = qpacket->len - ETH_HLEN; - - packet_len <<= 3; - if (packet_len <= GetSFTokenCount(ad, ps_sf)) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "Allowed bytes %d", - (packet_len >> 3)); - - DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue); - ps_sf->uiCurrentBytesOnHost -= (qpacket->len); - ps_sf->uiCurrentPacketsOnHost--; - atomic_dec(&ad->TotalPacketCount); - spin_unlock_bh(&ps_sf->SFQueueLock); - - SendPacketFromQueue(ad, ps_sf, qpacket); - ps_sf->uiPendedLast = false; - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "For Queue: %zd\n", - ps_sf - ad->PackInfo); - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "\nAvailable Tokens = %d required = %d\n", - ps_sf->uiCurrentTokenCount, - packet_len); - /* - this part indicates that because of - non-availability of the tokens - pkt has not been send out hence setting the - pending flag indicating the host to send it out - first next iteration. - */ - ps_sf->uiPendedLast = TRUE; - spin_unlock_bh(&ps_sf->SFQueueLock); - } - } else { - spin_unlock_bh(&ps_sf->SFQueueLock); - } -} - -static void send_control_packet(struct bcm_mini_adapter *ad, - struct bcm_packet_info *ps_sf) -{ - char *ctrl_packet = NULL; - INT status = 0; - - if ((atomic_read(&ad->CurrNumFreeTxDesc) > 0) && - (atomic_read(&ad->index_rd_txcntrlpkt) != - atomic_read(&ad->index_wr_txcntrlpkt))) { - ctrl_packet = ad->txctlpacket - [(atomic_read(&ad->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)]; - if (ctrl_packet) { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "Sending Control packet"); - status = SendControlPacket(ad, ctrl_packet); - if (STATUS_SUCCESS == status) { - spin_lock_bh(&ps_sf->SFQueueLock); - ps_sf->NumOfPacketsSent++; - ps_sf->uiSentBytes += ((struct bcm_leader *)ctrl_packet)->PLength; - ps_sf->uiSentPackets++; - atomic_dec(&ad->TotalPacketCount); - ps_sf->uiCurrentBytesOnHost -= ((struct bcm_leader *)ctrl_packet)->PLength; - ps_sf->uiCurrentPacketsOnHost--; - atomic_inc(&ad->index_rd_txcntrlpkt); - spin_unlock_bh(&ps_sf->SFQueueLock); - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "SendControlPacket Failed\n"); - } - } else { - BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - " Control Pkt is not available, Indexing is wrong...."); - } - } -} - -/** - * CheckAndSendPacketFromIndex() - This function dequeues the - * data/control packet from the specified queue for transmission. - * @Adapter: Pointer to the driver control structure. - * @iQIndex: The queue Identifier. - * - * Returns: None. - */ -static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, - struct bcm_packet_info *psSF) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "%zd ====>", (psSF-Adapter->PackInfo)); - if ((psSF != &Adapter->PackInfo[HiPriority]) && - Adapter->LinkUpStatus && - atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */ - - get_data_packet(Adapter, psSF); - } else { - send_control_packet(Adapter, psSF); - } -} - - -/** - * transmit_packets() - This function transmits the packets from - * different queues, if free descriptors are available on target. - * @Adapter: Pointer to the Adapter structure. - * - * Returns: None. - */ -VOID transmit_packets(struct bcm_mini_adapter *Adapter) -{ - UINT uiPrevTotalCount = 0; - int iIndex = 0; - - bool exit_flag = TRUE; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "=====>"); - - if (NULL == Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Got NULL Adapter"); - return; - } - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Device removed"); - return; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "\nUpdateTokenCount ====>\n"); - - UpdateTokenCount(Adapter); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "\nPruneQueueAllSF ====>\n"); - - PruneQueueAllSF(Adapter); - - uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount); - - for (iIndex = HiPriority; iIndex >= 0; iIndex--) { - if (!uiPrevTotalCount || (TRUE == Adapter->device_removed)) - break; - - if (Adapter->PackInfo[iIndex].bValid && - Adapter->PackInfo[iIndex].uiPendedLast && - Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, - "Calling CheckAndSendPacketFromIndex.."); - CheckAndSendPacketFromIndex(Adapter, - &Adapter->PackInfo[iIndex]); - uiPrevTotalCount--; - } - } - - while (uiPrevTotalCount > 0 && !Adapter->device_removed) { - exit_flag = TRUE; - /* second iteration to parse non-pending queues */ - for (iIndex = HiPriority; iIndex >= 0; iIndex--) { - if (!uiPrevTotalCount || - (TRUE == Adapter->device_removed)) - break; - - if (Adapter->PackInfo[iIndex].bValid && - Adapter->PackInfo[iIndex].uiCurrentBytesOnHost && - !Adapter->PackInfo[iIndex].uiPendedLast) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, - TX_PACKETS, DBG_LVL_ALL, - "Calling CheckAndSendPacketFromIndex.."); - CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); - uiPrevTotalCount--; - exit_flag = false; - } - } - - if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "In Idle Mode\n"); - break; - } - if (exit_flag == TRUE) - break; - } /* end of inner while loop */ - - update_per_cid_rx(Adapter); - Adapter->txtransmit_running = 0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "<======"); -} diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h deleted file mode 100644 index dc01e3016d4f..000000000000 --- a/drivers/staging/bcm/Macros.h +++ /dev/null @@ -1,352 +0,0 @@ -/************************************* -* Macros.h -**************************************/ -#ifndef __MACROS_H__ -#define __MACROS_H__ - -#define TX_TIMER_PERIOD 10 /*10 msec*/ -#define MAX_CLASSIFIERS 100 -#define MAX_TARGET_DSX_BUFFERS 24 - -#define MAX_CNTRL_PKTS 100 -#define MAX_DATA_PKTS 200 -#define MAX_ETH_SIZE 1536 -#define MAX_CNTL_PKT_SIZE 2048 - -#define MTU_SIZE 1400 -#define TX_QLEN 5 - -#define MAC_ADDR_REGISTER 0xbf60d000 - - -/* Quality of Service */ -#define NO_OF_QUEUES 17 -#define HiPriority (NO_OF_QUEUES-1) -#define LowPriority 0 -#define BE 2 -#define rtPS 4 -#define ERTPS 5 -#define UGS 6 - -#define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */ -#define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */ -#define MAX_ALLOWED_RATE (1024*1024*100) -#define TX_PACKET_THRESHOLD 10 -#define XSECONDS (1*HZ) -#define DSC_ACTIVATE_REQUEST 248 -#define QUEUE_DEPTH_OFFSET 0x1fc01000 -#define MAX_DEVICE_DESC_SIZE 2040 -#define MAX_CTRL_QUEUE_LEN 100 -#define MAX_APP_QUEUE_LEN 200 -#define MAX_LATENCY_ALLOWED 0xFFFFFFFF -#define DEFAULT_UG_INTERVAL 250 -#define DEFAULT_UGI_FACTOR 4 - -#define DEFAULT_PERSFCOUNT 60 -#define MAX_CONNECTIONS 10 -#define MAX_CLASS_NAME_LENGTH 32 - -#define ETH_LENGTH_OF_ADDRESS 6 -#define MAX_MULTICAST_ADDRESSES 32 -#define IP_LENGTH_OF_ADDRESS 4 - -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 - -/* Link Request */ -#define SET_MAC_ADDRESS_REQUEST 0 -#define SYNC_UP_REQUEST 1 -#define SYNCED_UP 2 -#define LINK_UP_REQUEST 3 -#define LINK_CONNECTED 4 -#define SYNC_UP_NOTIFICATION 2 -#define LINK_UP_NOTIFICATION 4 - - -#define LINK_NET_ENTRY 0x0002 -#define HMC_STATUS 0x0004 -#define LINK_UP_CONTROL_REQ 0x83 - -#define STATS_POINTER_REQ_STATUS 0x86 -#define NETWORK_ENTRY_REQ_PAYLOAD 198 -#define LINK_DOWN_REQ_PAYLOAD 226 -#define SYNC_UP_REQ_PAYLOAD 228 -#define STATISTICS_POINTER_REQ 237 -#define LINK_UP_REQ_PAYLOAD 245 -#define LINK_UP_ACK 246 - -#define STATS_MSG_SIZE 4 -#define INDEX_TO_DATA 4 - -#define GO_TO_IDLE_MODE_PAYLOAD 210 -#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 -#define IDLE_MODE_SF_UPDATE_MSG 187 - -#define SKB_RESERVE_ETHERNET_HEADER 16 -#define SKB_RESERVE_PHS_BYTES 32 - -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 - -#define ETH_CS_802_3 1 -#define ETH_CS_802_1Q_VLAN 3 -#define IPV4_CS 1 -#define IPV6_CS 2 -#define ETH_CS_MASK 0x3f - -/** \brief Validity bit maps for TLVs in packet classification rule */ - -#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 -#define PKT_CLASSIFICATION_VLANID_VALID 1 - -#ifndef MIN -#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - - -/*Leader related terms */ -#define LEADER_STATUS 0x00 -#define LEADER_STATUS_TCP_ACK 0x1 -#define LEADER_SIZE sizeof(struct bcm_leader) -#define MAC_ADDR_REQ_SIZE sizeof(struct bcm_packettosend) -#define SS_INFO_REQ_SIZE sizeof(struct bcm_packettosend) -#define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) -#define IDLE_REQ_SIZE sizeof(struct bcm_packettosend) - - -#define MAX_TRANSFER_CTRL_BYTE_USB (2*1024) - -#define GET_MAILBOX1_REG_REQUEST 0x87 -#define GET_MAILBOX1_REG_RESPONSE 0x67 -#define VCID_CONTROL_PACKET 0x00 - -#define TRANSMIT_NETWORK_DATA 0x00 -#define RECEIVED_NETWORK_DATA 0x20 - -#define CM_RESPONSES 0xA0 -#define STATUS_RSP 0xA1 -#define LINK_CONTROL_RESP 0xA2 -#define IDLE_MODE_STATUS 0xA3 -#define STATS_POINTER_RESP 0xA6 -#define MGMT_MSG_INFO_SW_STATUS 0xA7 -#define AUTH_SS_HOST_MSG 0xA8 - -#define CM_DSA_ACK_PAYLOAD 247 -#define CM_DSC_ACK_PAYLOAD 248 -#define CM_DSD_ACK_PAYLOAD 249 -#define CM_DSDEACTVATE 250 -#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 - -#define MAC_REQ 0 -#define LINK_RESP 1 -#define RSSI_INDICATION 2 - -#define SS_INFO 4 -#define STATISTICS_INFO 5 -#define CM_INDICATION 6 -#define PARAM_RESP 7 -#define BUFFER_1K 1024 -#define BUFFER_2K (BUFFER_1K*2) -#define BUFFER_4K (BUFFER_2K*2) -#define BUFFER_8K (BUFFER_4K*2) -#define BUFFER_16K (BUFFER_8K*2) -#define DOWNLINK_DIR 0 -#define UPLINK_DIR 1 - -#define BCM_SIGNATURE "BECEEM" - - -#define GPIO_OUTPUT_REGISTER 0x0F00003C -#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 -#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 -#define GPIO_MODE_REGISTER 0x0F000034 -#define GPIO_PIN_STATE_REGISTER 0x0F000038 - -struct bcm_link_state { - unsigned char ucLinkStatus; - unsigned char bIdleMode; - unsigned char bShutdownMode; -}; - -enum enLinkStatus { - WAIT_FOR_SYNC = 1, - PHY_SYNC_ACHIVED = 2, - LINKUP_IN_PROGRESS = 3, - LINKUP_DONE = 4, - DREG_RECEIVED = 5, - LINK_STATUS_RESET_RECEIVED = 6, - PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, - LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, - COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW = 9 -}; - -enum bcm_phs_dsc_action { - eAddPHSRule = 0, - eSetPHSRule, - eDeletePHSRule, - eDeleteAllPHSRules -}; - -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */ -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */ -#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */ -#define MINIMUM_PENDING_DESCRIPTORS 5 - -#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC -#define SHUTDOWN_ACK_FROM_DRIVER 0x1 -#define SHUTDOWN_NACK_FROM_DRIVER 0x2 - -#define LINK_SYNC_UP_SUBTYPE 0x0001 -#define LINK_SYNC_DOWN_SUBTYPE 0x0001 - - - -#define CONT_MODE 1 -#define SINGLE_DESCRIPTOR 1 - - -#define DESCRIPTOR_LENGTH 0x30 -#define FIRMWARE_DESCS_ADDRESS 0x1F100000 - - -#define CLOCK_RESET_CNTRL_REG_1 0x0F00000C -#define CLOCK_RESET_CNTRL_REG_2 0x0F000840 - - - -#define TX_DESCRIPTOR_HEAD_REGISTER 0x0F010034 -#define RX_DESCRIPTOR_HEAD_REGISTER 0x0F010094 - -#define STATISTICS_BEGIN_ADDR 0xbf60f02c - -#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) - -#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) -#define AUTO_LINKUP_ENABLE 0x2 -#define AUTO_SYNC_DISABLE 0x1 -#define AUTO_FIRM_DOWNLOAD 0x1 -#define SETTLE_DOWN_TIME 50 - -#define HOST_BUS_SUSPEND_BIT 16 - -#define IDLE_MESSAGE 0x81 - -#define MIPS_CLOCK_133MHz 1 - -#define TARGET_CAN_GO_TO_IDLE_MODE 2 -#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 -#define IDLE_MODE_PAYLOAD_LENGTH 8 - -#define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer)) -#define IPV4 4 -#define IP_VERSION(byte) (((byte&0xF0)>>4)) - -#define SET_MAC_ADDRESS 193 -#define SET_MAC_ADDRESS_RESPONSE 236 - -#define IDLE_MODE_WAKEUP_PATTERN 0xd0ea1d1e -#define IDLE_MODE_WAKEUP_NOTIFIER_ADDRESS 0x1FC02FA8 -#define IDLE_MODE_MAX_RETRY_COUNT 1000 - -#define CONFIG_BEGIN_ADDR 0xBF60B000 - -#define FIRMWARE_BEGIN_ADDR 0xBFC00000 - -#define INVALID_QUEUE_INDEX NO_OF_QUEUES - -#define INVALID_PID ((pid_t)-1) -#define DDR_80_MHZ 0 -#define DDR_100_MHZ 1 -#define DDR_120_MHZ 2 /* Additional Frequency for T3LP */ -#define DDR_133_MHZ 3 -#define DDR_140_MHZ 4 /* Not Used (Reserved for future) */ -#define DDR_160_MHZ 5 /* Additional Frequency for T3LP */ -#define DDR_180_MHZ 6 /* Not Used (Reserved for future) */ -#define DDR_200_MHZ 7 /* Not Used (Reserved for future) */ - -#define MIPS_200_MHZ 0 -#define MIPS_160_MHZ 1 - -#define PLL_800_MHZ 0 -#define PLL_266_MHZ 1 - -#define DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING 0 -#define DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING 1 -#define DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN 2 -#define DEVICE_POWERSAVE_MODE_AS_RESERVED 3 -#define DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE 4 - - -#define EEPROM_REJECT_REG_1 0x0f003018 -#define EEPROM_REJECT_REG_2 0x0f00301c -#define EEPROM_REJECT_REG_3 0x0f003008 -#define EEPROM_REJECT_REG_4 0x0f003020 -#define EEPROM_REJECT_MASK 0x0fffffff -#define VSG_MODE 0x3 - -/* Idle Mode Related Registers */ -#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C -#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC - -#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e -#define DEVICE_INT_OUT_EP_REG0 0x0F011870 -#define DEVICE_INT_OUT_EP_REG1 0x0F011874 - -#define BIN_FILE "/lib/firmware/macxvi200.bin" -#define CFG_FILE "/lib/firmware/macxvi.cfg" -#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 -#define MIN_VAL(x, y) ((x) < (y) ? (x) : (y)) -#define MAC_ADDRESS_SIZE 6 -#define EEPROM_COMMAND_Q_REG 0x0F003018 -#define EEPROM_READ_DATA_Q_REG 0x0F003020 -#define CHIP_ID_REG 0x0F000000 -#define GPIO_MODE_REG 0x0F000034 -#define GPIO_OUTPUT_REG 0x0F00003C -#define WIMAX_MAX_ALLOWED_RATE (1024*1024*50) - -#define T3 0xbece0300 -#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 - -#define RWM_READ 0 -#define RWM_WRITE 1 - -#define T3LPB 0xbece3300 -#define BCS220_2 0xbece3311 -#define BCS220_2BC 0xBECE3310 -#define BCS250_BC 0xbece3301 -#define BCS220_3 0xbece3321 - - -#define HPM_CONFIG_LDO145 0x0F000D54 -#define HPM_CONFIG_MSW 0x0F000D58 - -#define T3B 0xbece0310 -enum bcm_nvm_type { - NVM_AUTODETECT = 0, - NVM_EEPROM, - NVM_FLASH, - NVM_UNKNOWN -}; - -enum bcm_pmu_modes { - HYBRID_MODE_7C = 0, - INTERNAL_MODE_6 = 1, - HYBRID_MODE_6 = 2 -}; - -#define MAX_RDM_WRM_RETIRES 1 - -enum eAbortPattern { - ABORT_SHUTDOWN_MODE = 1, - ABORT_IDLE_REG = 1, - ABORT_IDLE_MODE = 2, - ABORT_IDLE_SYNCDOWN = 3 -}; - - -/* Offsets used by driver in skb cb variable */ -#define SKB_CB_CLASSIFICATION_OFFSET 0 -#define SKB_CB_LATENCY_OFFSET 1 -#define SKB_CB_TCPACK_OFFSET 2 - -#endif /* __MACROS_H__ */ diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile deleted file mode 100644 index 652b7f87737c..000000000000 --- a/drivers/staging/bcm/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for Beceem USB Wimax card -# - -obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o - -bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \ - InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \ - CmHost.o IPv6Protocol.o Qos.o Transmit.o\ - Bcmnet.o DDRInit.o HandleControlPacket.o\ - LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ - led_control.o nvm.o vendorspecificextn.o diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c deleted file mode 100644 index 883f7394dee6..000000000000 --- a/drivers/staging/bcm/Misc.c +++ /dev/null @@ -1,1587 +0,0 @@ -#include "headers.h" - -static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc); -static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter); -static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); -static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter); -static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter); - -static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiLoopIndex; - - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) { - Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD; - Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate = MAX_ALLOWED_RATE; - Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize = 20*1024*1024; - } - - Adapter->BEBucketSize = BE_BUCKET_SIZE; - Adapter->rtPSBucketSize = rtPS_BUCKET_SIZE; - Adapter->LinkStatus = SYNC_UP_REQUEST; - Adapter->TransferMode = IP_PACKET_ONLY_MODE; - Adapter->usBestEffortQueueIndex = -1; -} - -int InitAdapter(struct bcm_mini_adapter *psAdapter) -{ - int i = 0; - int Status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter); - - if (psAdapter == NULL) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL"); - return -EINVAL; - } - - sema_init(&psAdapter->NVMRdmWrmLock, 1); - sema_init(&psAdapter->rdmwrmsync, 1); - spin_lock_init(&psAdapter->control_queue_lock); - spin_lock_init(&psAdapter->txtransmitlock); - sema_init(&psAdapter->RxAppControlQueuelock, 1); - sema_init(&psAdapter->fw_download_sema, 1); - sema_init(&psAdapter->LowPowerModeSync, 1); - - for (i = 0; i < NO_OF_QUEUES; i++) - spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock); - i = 0; - - init_waitqueue_head(&psAdapter->process_rx_cntrlpkt); - init_waitqueue_head(&psAdapter->tx_packet_wait_queue); - init_waitqueue_head(&psAdapter->process_read_wait_queue); - init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue); - init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue); - psAdapter->waiting_to_fw_download_done = TRUE; - psAdapter->fw_download_done = false; - - default_wimax_protocol_initialize(psAdapter); - for (i = 0; i < MAX_CNTRL_PKTS; i++) { - psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL); - if (!psAdapter->txctlpacket[i]) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); - return -ENOMEM; - } - } - - if (AllocAdapterDsxBuffer(psAdapter)) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers"); - return -EINVAL; - } - - /* Initialize PHS interface */ - if (phs_init(&psAdapter->stBCMPhsContext, psAdapter) != 0) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __func__, __LINE__); - return -ENOMEM; - } - - Status = BcmAllocFlashCSStructure(psAdapter); - if (Status) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Memory Allocation for Flash structure failed"); - return Status; - } - - Status = vendorextnInit(psAdapter); - - if (STATUS_SUCCESS != Status) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Vendor Init Failed"); - return Status; - } - - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised"); - - return STATUS_SUCCESS; -} - -void AdapterFree(struct bcm_mini_adapter *Adapter) -{ - int count; - - beceem_protocol_reset(Adapter); - vendorextnExit(Adapter); - - if (Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) - kthread_stop(Adapter->control_packet_handler); - - if (Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) - kthread_stop(Adapter->transmit_packet_thread); - - wake_up(&Adapter->process_read_wait_queue); - - if (Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) - kthread_stop(Adapter->LEDInfo.led_cntrl_threadid); - - unregister_networkdev(Adapter); - - /* FIXME: use proper wait_event and refcounting */ - while (atomic_read(&Adapter->ApplicationRunning)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n", atomic_read(&Adapter->ApplicationRunning)); - msleep(100); - } - unregister_control_device_interface(Adapter); - kfree(Adapter->pstargetparams); - - for (count = 0; count < MAX_CNTRL_PKTS; count++) - kfree(Adapter->txctlpacket[count]); - - FreeAdapterDsxBuffer(Adapter); - kfree(Adapter->pvInterfaceAdapter); - - /* Free the PHS Interface */ - PhsCleanup(&Adapter->stBCMPhsContext); - - BcmDeAllocFlashCSStructure(Adapter); - - free_netdev(Adapter->dev); -} - -static int create_worker_threads(struct bcm_mini_adapter *psAdapter) -{ - /* Rx Control Packets Processing */ - psAdapter->control_packet_handler = kthread_run((int (*)(void *)) - control_packet_handler, psAdapter, "%s-rx", DRV_NAME); - if (IS_ERR(psAdapter->control_packet_handler)) { - pr_notice(DRV_NAME ": could not create control thread\n"); - return PTR_ERR(psAdapter->control_packet_handler); - } - - /* Tx Thread */ - psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) - tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME); - if (IS_ERR(psAdapter->transmit_packet_thread)) { - pr_notice(DRV_NAME ": could not creat transmit thread\n"); - kthread_stop(psAdapter->control_packet_handler); - return PTR_ERR(psAdapter->transmit_packet_thread); - } - return 0; -} - -static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path) -{ - struct file *flp = filp_open(path, O_RDONLY, S_IRWXU); - - if (IS_ERR(flp)) { - pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp)); - flp = NULL; - } - - if (Adapter->device_removed) - flp = NULL; - - return flp; -} - -/* Arguments: - * Logical Adapter - * Path to image file - * Download Address on the chip - */ -static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc) -{ - int errorno = 0; - struct file *flp = NULL; - struct timeval tv = {0}; - - flp = open_firmware_file(Adapter, path); - if (!flp) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path); - return -ENOENT; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path, (unsigned long)file_inode(flp)->i_size, loc); - do_gettimeofday(&tv); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))); - if (Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error %x!!!", -EIO); - errorno = -EIO; - goto exit_download; - } - vfs_llseek(flp, 0, 0); - if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!"); - errorno = -EIO; - goto exit_download; - } - -exit_download: - filp_close(flp, NULL); - return errorno; -} - -/** - * @ingroup ctrl_pkt_functions - * This function copies the contents of given buffer - * to the control packet and queues it for transmission. - * @note Do not acquire the spinlock, as it it already acquired. - * @return SUCCESS/FAILURE. - * Arguments: - * Logical Adapter - * Control Packet Buffer - */ -int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) -{ - struct bcm_leader *pLeader = NULL; - int Status = 0; - unsigned char *ctrl_buff; - unsigned int pktlen = 0; - struct bcm_link_request *pLinkReq = NULL; - PUCHAR pucAddIndication = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>"); - if (!ioBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got Null Buffer\n"); - return -EINVAL; - } - - pLinkReq = (struct bcm_link_request *)ioBuffer; - pLeader = (struct bcm_leader *)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ - - if (Adapter->bShutStatus == TRUE && - pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD && - pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) { - - /* Got sync down in SHUTDOWN..we could not process this. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n"); - return STATUS_FAILURE; - } - - if ((pLeader->Status == LINK_UP_CONTROL_REQ) && - ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD && - (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) || /* Sync Up Command */ - pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) /* Net Entry Command */ { - - if (Adapter->LinkStatus > PHY_SYNC_ACHIVED) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "LinkStatus is Greater than PHY_SYN_ACHIEVED"); - return STATUS_FAILURE; - } - - if (Adapter->bShutStatus == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); - if (Adapter->bTriedToWakeUpFromlowPowerMode == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n"); - Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; /* change it to 1 for current support. */ - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->bShutStatus, (5 * HZ)); - - if (Status == -ERESTARTSYS) - return Status; - - if (Adapter->bShutStatus) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n"); - return STATUS_FAILURE; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Wakeup has been tried already...\n"); - } - } - } - - if (Adapter->IdleMode == TRUE) { - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */ - if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || - pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) { - - if ((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD)) { - if (pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Link Down Sent in Idle Mode\n"); - Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN; /* LINK DOWN sent in Idle Mode */ - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); - Adapter->usIdleModePattern = ABORT_IDLE_REG; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - } - - /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent - * the wake up from idlemode is from host - */ - /* Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; */ - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - - /* We should not send DREG message down while in idlemode. */ - if (LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0]) - return STATUS_SUCCESS; - - Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->IdleMode, (5 * HZ)); - - if (Status == -ERESTARTSYS) - return Status; - - if (Adapter->IdleMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n"); - return STATUS_FAILURE; - } - } else { - return STATUS_SUCCESS; - } - } - - /* The Driver has to send control messages with a particular VCID */ - pLeader->Vcid = VCID_CONTROL_PACKET; /* VCID for control packet. */ - - /* Allocate skb for Control Packet */ - pktlen = pLeader->PLength; - ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS]; - - if (!ctrl_buff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); - return -ENOMEM; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", - atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); - - if (pLeader) { - if ((pLeader->Status == 0x80) || - (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) { - /* - * Restructure the DSX message to handle Multiple classifier Support - * Write the Service Flow param Structures directly to the target - * and embed the pointers in the DSX messages sent to target. - */ - /* Lets store the current length of the control packet we are transmitting */ - pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; - pktlen = pLeader->PLength; - Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); - if (Status != 1) { - ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, false); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); - return STATUS_FAILURE; - } - /* - * update the leader to use the new length - * The length of the control packet is length of message being sent + Leader length - */ - pLeader->PLength = pktlen; - } - } - - if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE) - return -EINVAL; - - memset(ctrl_buff, 0, pktlen+LEADER_SIZE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); - *(struct bcm_leader *)ctrl_buff = *pLeader; - memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); - - /* Update the statistics counters */ - spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength; - Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].bValid = TRUE; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, - Adapter->PackInfo[HiPriority].bValid); - Status = STATUS_SUCCESS; - /*Queue the packet for transmission */ - atomic_inc(&Adapter->index_wr_txcntrlpkt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets"); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); - return Status; -} - -/****************************************************************** -* Function - LinkMessage() -* -* Description - This function builds the Sync-up and Link-up request -* packet messages depending on the device Link status. -* -* Parameters - Adapter: Pointer to the Adapter structure. -* -* Returns - None. -*******************************************************************/ -void LinkMessage(struct bcm_mini_adapter *Adapter) -{ - struct bcm_link_request *pstLinkRequest = NULL; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); - if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) { - pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); - if (!pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); - return; - } - /* sync up request... */ - Adapter->LinkStatus = WAIT_FOR_SYNC; /* current link status */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); - pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; - pstLinkRequest->szData[1] = LINK_SYNC_UP_SUBTYPE; - pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; - pstLinkRequest->Leader.PLength = sizeof(ULONG); - Adapter->bSyncUpRequestSent = TRUE; - - } else if (Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) { - pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC); - if (!pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); - return; - } - /* LINK_UP_REQUEST */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); - pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; - pstLinkRequest->szData[1] = LINK_NET_ENTRY; - pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; - pstLinkRequest->Leader.PLength = sizeof(ULONG); - } - if (pstLinkRequest) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); - CopyBufferToControlPacket(Adapter, pstLinkRequest); - kfree(pstLinkRequest); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); - return; -} - -/********************************************************************** -* Function - StatisticsResponse() -* -* Description - This function handles the Statistics response packet. -* -* Parameters - Adapter : Pointer to the Adapter structure. -* - pvBuffer: Starting address of Statistic response data. -* -* Returns - None. -************************************************************************/ -void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); - Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__); -} - -/********************************************************************** -* Function - LinkControlResponseMessage() -* -* Description - This function handles the Link response packets. -* -* Parameters - Adapter : Pointer to the Adapter structure. -* - pucBuffer: Starting address of Link response data. -* -* Returns - None. -***********************************************************************/ -void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); - - if (*pucBuffer == LINK_UP_ACK) { - switch (*(pucBuffer+1)) { - case PHY_SYNC_ACHIVED: /* SYNCed UP */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED"); - - if (Adapter->LinkStatus == LINKUP_DONE) - beceem_protocol_reset(Adapter); - - Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; - Adapter->LinkStatus = PHY_SYNC_ACHIVED; - - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - LinkMessage(Adapter); - break; - - case LINKUP_DONE: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE"); - Adapter->LinkStatus = LINKUP_DONE; - Adapter->bPHSEnabled = *(pucBuffer+3); - Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x\n", Adapter->bPHSEnabled); - - if ((false == Adapter->bShutStatus) && (false == Adapter->IdleMode)) { - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NORMAL_OPERATION; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - } - LinkMessage(Adapter); - break; - - case WAIT_FOR_SYNC: - /* - * Driver to ignore the DREG_RECEIVED - * WiMAX Application should handle this Message - */ - /* Adapter->liTimeSinceLastNetEntry = 0; */ - Adapter->LinkUpStatus = 0; - Adapter->LinkStatus = 0; - Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; - Adapter->bTriedToWakeUpFromlowPowerMode = false; - Adapter->IdleMode = false; - beceem_protocol_reset(Adapter); - - break; - case LINK_SHUTDOWN_REQ_FROM_FIRMWARE: - case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW: - { - HandleShutDownModeRequest(Adapter, pucBuffer); - } - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x", *(pucBuffer + 1)); - break; - } - } else if (SET_MAC_ADDRESS_RESPONSE == *pucBuffer) { - PUCHAR puMacAddr = (pucBuffer + 1); - - Adapter->LinkStatus = SYNC_UP_REQUEST; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP"); - LinkMessage(Adapter); - memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====", __func__); -} - -void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) -{ - int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; - struct timeval tv; - struct bcm_link_request stIdleResponse = {{0} }; - - memset(&tv, 0, sizeof(tv)); - stIdleResponse.Leader.Status = IDLE_MESSAGE; - stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH; - stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, " ============>"); - - /********************************* - *down_trylock - - * if [ semaphore is available ] - * acquire semaphone and return value 0 ; - * else - * return non-zero value ; - * - ***********************************/ - - NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); - - - if ((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) && - (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - - stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!"); - Adapter->bPreparingForLowPowerMode = false; - } else { - stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; /* 2; Idle ACK */ - Adapter->StatisticsPointer = 0; - - /* Wait for the LED to TURN OFF before sending ACK response */ - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - int iRetVal = 0; - - /* Wake the LED Thread with IDLEMODE_ENTER State */ - Adapter->DriverState = LOWPOWER_MODE_ENTER; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld", jiffies); - wake_up(&Adapter->LEDInfo.notify_led_event); - - /* Wait for 1 SEC for LED to OFF */ - iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); - - /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ - if (iRetVal <= 0) { - stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ - Adapter->DriverState = NORMAL_OPERATION; - wake_up(&Adapter->LEDInfo.notify_led_event); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!"); - } - } - - if (stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "ACKING IDLE MODE !!!!!!!!!"); - down(&Adapter->rdmwrmsync); - Adapter->bPreparingForLowPowerMode = TRUE; - up(&Adapter->rdmwrmsync); - /* Killing all URBS. */ - if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } else { - Adapter->bPreparingForLowPowerMode = false; - } - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - } - - status = CopyBufferToControlPacket(Adapter, &stIdleResponse); - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n"); - Adapter->bPreparingForLowPowerMode = false; - StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } - do_gettimeofday(&tv); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000); -} - -/****************************************************************** -* Function - DumpPackInfo() -* -* Description - This function dumps the all Queue(PackInfo[]) details. -* -* Parameters - Adapter: Pointer to the Adapter structure. -* -* Returns - None. -*******************************************************************/ -void DumpPackInfo(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiLoopIndex = 0; - unsigned int uiIndex = 0; - unsigned int uiClsfrIndex = 0; - struct bcm_classifier_rule *pstClassifierEntry = NULL; - - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "*********** Showing Details Of Queue %d***** ******", uiLoopIndex); - if (false == Adapter->PackInfo[uiLoopIndex].bValid) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is false for %X index\n", uiLoopIndex); - continue; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " Dumping SF Rule Entry For SFID %lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " ucDirection %X\n", Adapter->PackInfo[uiLoopIndex].ucDirection); - - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv6 Service Flow\n"); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv4 Service Flow\n"); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SF Traffic Priority %X\n", Adapter->PackInfo[uiLoopIndex].u8TrafficPriority); - - for (uiClsfrIndex = 0; uiClsfrIndex < MAX_CLASSIFIERS; uiClsfrIndex++) { - pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex]; - if (!pstClassifierEntry->bUsed) - continue; - - if (pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID) - continue; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n", uiClsfrIndex, pstClassifierEntry->uiClassifierRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n", uiClsfrIndex, pstClassifierEntry->usVCID_Value); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n", uiClsfrIndex, pstClassifierEntry->bProtocolValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n", uiClsfrIndex, pstClassifierEntry->bTOSValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bDestIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bSrcIpValid); - - for (uiIndex = 0; uiIndex < MAX_PORT_RANGE; uiIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeLo:%X\n", pstClassifierEntry->usSrcPortRangeLo[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeHi:%X\n", pstClassifierEntry->usSrcPortRangeHi[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeLo:%X\n", pstClassifierEntry->usDestPortRangeLo[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeHi:%X\n", pstClassifierEntry->usDestPortRangeHi[uiIndex]); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPSourceAddressLength : 0x%x\n", pstClassifierEntry->ucIPSourceAddressLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPDestinationAddressLength : 0x%x\n", pstClassifierEntry->ucIPDestinationAddressLength); - for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPSourceAddressLength; uiIndex++) { - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpAddr :\n"); - DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpMask :\n"); - DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpAddr:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpMask:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]); - } - } - - for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPDestinationAddressLength; uiIndex++) { - if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpAddr :\n"); - DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpMask :\n"); - DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpAddr:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpMask:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]); - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucProtocol:0x%X\n", pstClassifierEntry->ucProtocol[0]); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tu8ClassifierRulePriority:%X\n", pstClassifierEntry->u8ClassifierRulePriority); - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ulSFID:%lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "usVCID_Value:%X\n", Adapter->PackInfo[uiLoopIndex].usVCID_Value); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "PhsEnabled: 0x%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThreshold:%X\n", Adapter->PackInfo[uiLoopIndex].uiThreshold); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid:%X\n", Adapter->PackInfo[uiLoopIndex].bValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bActive:%X\n", Adapter->PackInfo[uiLoopIndex].bActive); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "u8QueueType:%X\n", Adapter->PackInfo[uiLoopIndex].u8QueueType); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxBucketSize:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPerSFTxResourceCount:%X\n", atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount)); - /* DumpDebug(DUMP_INFO,("bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentBytesOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentPacketsOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentPackets); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentDrainRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThisPeriodSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liDrainCalculated:%llX\n", Adapter->PackInfo[uiLoopIndex].liDrainCalculated); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentTokenCount:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liLastUpdateTokenAt:%llX\n", Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxAllowedRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPendedLast:%X\n", Adapter->PackInfo[uiLoopIndex].uiPendedLast); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "NumOfPacketsSent:%X\n", Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, - DBG_LVL_ALL, "ServiceClassName: %*ph\n", - 4, Adapter->PackInfo[uiLoopIndex]. - ucServiceClassName); -/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); - * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); - * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); - * DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount)); - */ - } - - for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aRxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aRxPktSizeHist[uiLoopIndex]); - - for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aTxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aTxPktSizeHist[uiLoopIndex]); -} - -int reset_card_proc(struct bcm_mini_adapter *ps_adapter) -{ - int retval = STATUS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_interface_adapter *psIntfAdapter = NULL; - unsigned int value = 0, uiResetValue = 0; - int bytes; - - psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter)); - ps_adapter->bDDRInitDone = false; - - if (ps_adapter->chip_id >= T3LPB) { - /* SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before */ - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - - /* making bit[6...5] same as was before f/w download. this setting force the h/w to */ - /* re-populated the SP RAM area with the string descriptor. */ - value = value | (ps_adapter->syscfgBefFwDld & 0x00000060); - wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - } - - /* killing all submitted URBs. */ - psIntfAdapter->psAdapter->StopAllXaction = TRUE; - Bcm_kill_all_URBs(psIntfAdapter); - /* Reset the UMA-B Device */ - if (ps_adapter->chip_id >= T3LPB) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n"); - retval = usb_reset_device(psIntfAdapter->udev); - psIntfAdapter->psAdapter->StopAllXaction = false; - - if (retval != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval); - goto err_exit; - } - - if (ps_adapter->chip_id == BCS220_2 || - ps_adapter->chip_id == BCS220_2BC || - ps_adapter->chip_id == BCS250_BC || - ps_adapter->chip_id == BCS220_3) { - - bytes = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); - goto err_exit; - } - /* setting 0th bit */ - value |= (1<<0); - retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - } - } else { - bytes = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); - if (bytes < 0) { - retval = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); - goto err_exit; - } - value &= (~(1<<16)); - retval = wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - - /* Toggling the GPIO 8, 9 */ - value = 0; - retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - value = 0x300; - retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)); - if (retval < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); - goto err_exit; - } - mdelay(50); - } - - /* ps_adapter->downloadDDR = false; */ - if (ps_adapter->bFlashBoot) { - /* In flash boot mode MIPS state register has reverse polarity. - * So just or with setting bit 30. - * Make the MIPS in Reset state. - */ - rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); - uiResetValue |= (1<<30); - wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); - } - - if (ps_adapter->chip_id >= T3LPB) { - uiResetValue = 0; - /* - * WA for SYSConfig Issue. - * Read SYSCFG Twice to make it writable. - */ - rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); - if (uiResetValue & (1<<4)) { - uiResetValue = 0; - rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); /* 2nd read to make it writable. */ - uiResetValue &= (~(1<<4)); - wrmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); - } - } - uiResetValue = 0; - wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue)); - -err_exit: - psIntfAdapter->psAdapter->StopAllXaction = false; - return retval; -} - -int run_card_proc(struct bcm_mini_adapter *ps_adapter) -{ - int status = STATUS_SUCCESS; - int bytes; - - unsigned int value = 0; - { - bytes = rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)); - if (bytes < 0) { - status = bytes; - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); - return status; - } - - if (ps_adapter->bFlashBoot) - value &= (~(1<<30)); - else - value |= (1<<30); - - if (wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); - return STATUS_FAILURE; - } - } - return status; -} - -int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter) -{ - int status; - unsigned int value = 0; - /* - * Create the threads first and then download the - * Firm/DDR Settings.. - */ - status = create_worker_threads(ps_adapter); - if (status < 0) - return status; - - status = bcm_parse_target_params(ps_adapter); - if (status) - return status; - - if (ps_adapter->chip_id >= T3LPB) { - rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); - ps_adapter->syscfgBefFwDld = value; - - if ((value & 0x60) == 0) - ps_adapter->bFlashBoot = TRUE; - } - - reset_card_proc(ps_adapter); - - /* Initializing the NVM. */ - BcmInitNVM(ps_adapter); - status = ddr_init(ps_adapter); - if (status) { - pr_err(DRV_NAME "ddr_init Failed\n"); - return status; - } - - /* Download cfg file */ - status = buffDnldVerify(ps_adapter, - (PUCHAR)ps_adapter->pstargetparams, - sizeof(struct bcm_target_params), - CONFIG_BEGIN_ADDR); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); - goto OUT; - } - - if (register_networkdev(ps_adapter)) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); - return -EIO; - } - - if (false == ps_adapter->AutoFirmDld) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n"); - /* If Auto f/w download is disable, register the control interface, */ - /* register the control interface after the mailbox. */ - if (register_control_device_interface(ps_adapter) < 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); - return -EIO; - } - return STATUS_SUCCESS; - } - - /* - * Do the LED Settings here. It will be used by the Firmware Download - * Thread. - */ - - /* - * 1. If the LED Settings fails, do not stop and do the Firmware download. - * 2. This init would happened only if the cfg file is present, else - * call from the ioctl context. - */ - - status = InitLedSettings(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "INIT LED FAILED\n"); - return status; - } - - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = DRIVER_INIT; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = FW_DOWNLOAD; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - value = 0; - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - - if (ps_adapter->eNVMType == NVM_FLASH) { - status = PropagateCalParamsFromFlashToMemory(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Propagation of Cal param failed .."); - goto OUT; - } - } - - /* Download Firmare */ - status = BcmFileDownload(ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR); - if (status != 0) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present...\n"); - goto OUT; - } - - status = run_card_proc(ps_adapter); - if (status) { - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n"); - goto OUT; - } - - ps_adapter->fw_download_done = TRUE; - mdelay(10); - -OUT: - if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - ps_adapter->DriverState = FW_DOWNLOAD_DONE; - wake_up(&ps_adapter->LEDInfo.notify_led_event); - } - - return status; -} - -static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter) -{ - struct file *flp = NULL; - char *buff; - int len = 0; - - buff = kmalloc(BUFFER_1K, GFP_KERNEL); - if (!buff) - return -ENOMEM; - - Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); - if (Adapter->pstargetparams == NULL) { - kfree(buff); - return -ENOMEM; - } - - flp = open_firmware_file(Adapter, CFG_FILE); - if (!flp) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE\n", CFG_FILE); - kfree(buff); - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -ENOENT; - } - len = kernel_read(flp, 0, buff, BUFFER_1K); - filp_close(flp, NULL); - - if (len != sizeof(struct bcm_target_params)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n"); - kfree(buff); - kfree(Adapter->pstargetparams); - Adapter->pstargetparams = NULL; - return -ENOENT; - } - - /* Check for autolink in config params */ - /* - * Values in Adapter->pstargetparams are in network byte order - */ - memcpy(Adapter->pstargetparams, buff, sizeof(struct bcm_target_params)); - kfree(buff); - beceem_parse_target_struct(Adapter); - return STATUS_SUCCESS; -} - -void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; - - if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { - pr_info(DRV_NAME ": AutoSyncup is Disabled\n"); - Adapter->AutoSyncup = false; - } else { - pr_info(DRV_NAME ": AutoSyncup is Enabled\n"); - Adapter->AutoSyncup = TRUE; - } - - if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) { - pr_info(DRV_NAME ": Enabling autolink up"); - Adapter->AutoLinkUp = TRUE; - } else { - pr_info(DRV_NAME ": Disabling autolink up"); - Adapter->AutoLinkUp = false; - } - /* Setting the DDR Setting.. */ - Adapter->DDRSetting = (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >> 8)&0x0F; - Adapter->ulPowerSaveMode = (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; - pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting); - pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode); - if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) { - pr_info(DRV_NAME ": Enabling Auto Firmware Download\n"); - Adapter->AutoFirmDld = TRUE; - } else { - pr_info(DRV_NAME ": Disabling Auto Firmware Download\n"); - Adapter->AutoFirmDld = false; - } - uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6); - Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01; - pr_info(DRV_NAME ": MIPSConfig : 0x%X\n", Adapter->bMipsConfig); - /* used for backward compatibility. */ - Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01; - Adapter->PmuMode = (uiHostDrvrCfg6 >> 24) & 0x03; - pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode); - - if ((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT) & (0x01)) { - Adapter->bDoSuspend = TRUE; - pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile"); - } - - uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag); - pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n", uiEEPROMFlag); - Adapter->eNVMType = (enum bcm_nvm_type)((uiEEPROMFlag>>4)&0x3); - Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1; - Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4)); - Adapter->bSectorSizeOverride = (bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; - - if (ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x01) - Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE; - - if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) - doPowerAutoCorrection(Adapter); -} - -static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) -{ - unsigned int reporting_mode; - - reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02; - psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); - - if (reporting_mode) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable"); - psAdapter->bDoSuspend = false; - } - - if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) { - /* If reporting mode is enable, switch PMU to PMC */ - { - psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; - psAdapter->bDoSuspend = false; - } - - /* clearing space bit[15..12] */ - psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12))); - /* placing the power save mode option */ - psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12)); - } else if (psAdapter->bIsAutoCorrectEnabled == false) { - /* remove the autocorrect disable bit set before dumping. */ - psAdapter->ulPowerSaveMode &= ~(1 << 3); - psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15)); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode); - } -} - -static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount) -{ - unsigned int uiIndex = 0; - - if (RWM_WRITE == rwFlag) { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) - puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]); - } else { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) - puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]); - } -} - -int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, - uiAddress, pucBuff, sSize); -} - -int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - int iRetVal; - - iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter, - uiAddress, pucBuff, sSize); - return iRetVal; -} - -int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - convertEndian(RWM_WRITE, pucBuff, size); - return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); -} - -int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int uiRetVal = 0; - - uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size); - convertEndian(RWM_READ, (unsigned int *)pucBuff, size); - - return uiRetVal; -} - -int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) -{ - int status = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - status = -EACCES; - goto exit; - } - - status = wrm(Adapter, uiAddress, pucBuff, sSize); -exit: - up(&Adapter->rdmwrmsync); - return status; -} - -int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int iRetVal = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - iRetVal = -EACCES; - goto exit; - } - - iRetVal = wrmalt(Adapter, uiAddress, pucBuff, size); -exit: - up(&Adapter->rdmwrmsync); - return iRetVal; -} - -int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) -{ - int uiRetVal = STATUS_SUCCESS; - - down(&Adapter->rdmwrmsync); - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { - - uiRetVal = -EACCES; - goto exit; - } - - uiRetVal = rdmalt(Adapter, uiAddress, pucBuff, size); -exit: - up(&Adapter->rdmwrmsync); - return uiRetVal; -} - -static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) -{ - int clear_abort_pattern = 0, Status = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); - /* target has woken up From Shut Down */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); - Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); - return; - } - - if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { - msleep(100); - InterfaceHandleShutdownModeWakeup(Adapter); - msleep(100); - } - - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - - Adapter->bTriedToWakeUpFromlowPowerMode = false; - Adapter->bShutStatus = false; - wake_up(&Adapter->lowpower_mode_wait_queue); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); -} - -static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) -{ - struct bcm_link_request stShutdownResponse; - unsigned int NVMAccess = 0, lowPwrAbortMsg = 0; - unsigned int Status = 0; - - memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request)); - stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; - stShutdownResponse.Leader.PLength = 8; /* 8 bytes; */ - stShutdownResponse.szData[0] = LINK_UP_ACK; - stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE; - - /********************************* - * down_trylock - - * if [ semaphore is available ] - * acquire semaphone and return value 0 ; - * else - * return non-zero value ; - * - ***********************************/ - - NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); - - if (NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) { - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n"); - stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ - Adapter->bPreparingForLowPowerMode = false; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n"); - stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER; /* ShutDown ACK */ - - /* Wait for the LED to TURN OFF before sending ACK response */ - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - int iRetVal = 0; - - /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */ - Adapter->DriverState = LOWPOWER_MODE_ENTER; - wake_up(&Adapter->LEDInfo.notify_led_event); - - /* Wait for 1 SEC for LED to OFF */ - iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); - - /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ - if (iRetVal <= 0) { - stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ - Adapter->DriverState = NO_NETWORK_ENTRY; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - } - - if (stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ACKING SHUTDOWN MODE !!!!!!!!!"); - down(&Adapter->rdmwrmsync); - Adapter->bPreparingForLowPowerMode = TRUE; - up(&Adapter->rdmwrmsync); - /* Killing all URBS. */ - if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } else { - Adapter->bPreparingForLowPowerMode = false; - } - - if (!NVMAccess) - up(&Adapter->NVMRdmWrmLock); - - if (!lowPwrAbortMsg) - up(&Adapter->LowPowerModeSync); - } - - Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse); - if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n"); - Adapter->bPreparingForLowPowerMode = false; - StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); - } -} - -static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) -{ - unsigned int uiResetValue = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); - - if (*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) { - HandleShutDownModeWakeup(Adapter); - } else if (*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) { - /* Target wants to go to Shut Down Mode */ - /* InterfacePrepareForShutdown(Adapter); */ - if (Adapter->chip_id == BCS220_2 || - Adapter->chip_id == BCS220_2BC || - Adapter->chip_id == BCS250_BC || - Adapter->chip_id == BCS220_3) { - - rdmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); - uiResetValue |= (1<<17); - wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); - } - - SendShutModeResponse(Adapter); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); -} - -void ResetCounters(struct bcm_mini_adapter *Adapter) -{ - beceem_protocol_reset(Adapter); - Adapter->CurrNumRecvDescs = 0; - Adapter->PrevNumRecvDescs = 0; - Adapter->LinkUpStatus = 0; - Adapter->LinkStatus = 0; - atomic_set(&Adapter->cntrlpktCnt, 0); - atomic_set(&Adapter->TotalPacketCount, 0); - Adapter->fw_download_done = false; - Adapter->LinkStatus = 0; - Adapter->AutoLinkUp = false; - Adapter->IdleMode = false; - Adapter->bShutStatus = false; -} - -struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIP) && - !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment) - - return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry; - } - return NULL; -} - -void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) { - memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info)); - break; - } - } -} - -void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp) -{ - unsigned int uiIndex = 0; - - for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { - if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && - (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIp)) - - memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(struct bcm_fragmented_packet_info)); - } -} - -void update_per_cid_rx(struct bcm_mini_adapter *Adapter) -{ - unsigned int qindex = 0; - - if ((jiffies - Adapter->liDrainCalculated) < XSECONDS) - return; - - for (qindex = 0; qindex < HiPriority; qindex++) { - if (Adapter->PackInfo[qindex].ucDirection == 0) { - Adapter->PackInfo[qindex].uiCurrentRxRate = - (Adapter->PackInfo[qindex].uiCurrentRxRate + - Adapter->PackInfo[qindex].uiThisPeriodRxBytes) / 2; - - Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0; - } else { - Adapter->PackInfo[qindex].uiCurrentDrainRate = - (Adapter->PackInfo[qindex].uiCurrentDrainRate + - Adapter->PackInfo[qindex].uiThisPeriodSentBytes) / 2; - Adapter->PackInfo[qindex].uiThisPeriodSentBytes = 0; - } - } - Adapter->liDrainCalculated = jiffies; -} - -void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) -{ - int iIndex = 0; - u32 uibuff[MAX_TARGET_DSX_BUFFERS]; - int bytes; - - if (!atomic_read(&Adapter->uiMBupdate)) - return; - - bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS); - if (bytes < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); - return; - } - - for (iIndex = 0; iIndex < HiPriority; iIndex++) { - if (Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) { - if (Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS) - atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]); - else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x\n", Adapter->PackInfo[iIndex].usVCID_Value); - } - } - atomic_set(&Adapter->uiMBupdate, false); -} - -void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex) -{ - struct sk_buff *PacketToDrop = NULL; - struct net_device_stats *netstats = &Adapter->dev->stats; - - spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); - - while (Adapter->PackInfo[iQIndex].FirstTxQueue && atomic_read(&Adapter->TotalPacketCount)) { - PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; - if (PacketToDrop && PacketToDrop->len) { - netstats->tx_dropped++; - DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, Adapter->PackInfo[iQIndex].LastTxQueue); - Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; - Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len; - - /* Adding dropped statistics */ - Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len; - Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; - dev_kfree_skb(PacketToDrop); - atomic_dec(&Adapter->TotalPacketCount); - } - } - spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); -} - -static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter) -{ - int i; - - if (netif_msg_link(Adapter)) - pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name); - - netif_carrier_off(Adapter->dev); - netif_stop_queue(Adapter->dev); - - Adapter->IdleMode = false; - Adapter->LinkUpStatus = false; - ClearTargetDSXBuffer(Adapter, 0, TRUE); - /* Delete All Classifier Rules */ - - for (i = 0; i < HiPriority; i++) - DeleteAllClassifiersForSF(Adapter, i); - - flush_all_queues(Adapter); - - if (Adapter->TimerActive == TRUE) - Adapter->TimerActive = false; - - memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(struct bcm_fragmented_packet_info) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); - - for (i = 0; i < HiPriority; i++) { - /* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */ - /* It is same between MIBs and SF. */ - memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(struct bcm_mibs_parameters)); - } -} diff --git a/drivers/staging/bcm/PHSDefines.h b/drivers/staging/bcm/PHSDefines.h deleted file mode 100644 index cd78ee4ffa22..000000000000 --- a/drivers/staging/bcm/PHSDefines.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef BCM_PHS_DEFINES_H -#define BCM_PHS_DEFINES_H - -#define PHS_INVALID_TABLE_INDEX 0xffffffff -#define PHS_MEM_TAG "_SHP" - -/* PHS Defines */ -#define STATUS_PHS_COMPRESSED 0xa1 -#define STATUS_PHS_NOCOMPRESSION 0xa2 -#define APPLY_PHS 1 -#define MAX_NO_BIT 7 -#define ZERO_PHSI 0 -#define VERIFY 0 -#define SIZE_MULTIPLE_32 4 -#define UNCOMPRESSED_PACKET 0 -#define DYNAMIC 0 -#define SUPPRESS 0x80 -#define NO_CLASSIFIER_MATCH 0 -#define SEND_PACKET_UNCOMPRESSED 0 -#define PHSI_IS_ZERO 0 -#define PHSI_LEN 1 -#define ERROR_LEN 0 -#define PHS_BUFFER_SIZE 1532 -#define MAX_PHSRULE_PER_SF 20 -#define MAX_SERVICEFLOWS 17 - -/* PHS Error Defines */ -#define PHS_SUCCESS 0 -#define ERR_PHS_INVALID_DEVICE_EXETENSION 0x800 -#define ERR_PHS_INVALID_PHS_RULE 0x801 -#define ERR_PHS_RULE_ALREADY_EXISTS 0x802 -#define ERR_SF_MATCH_FAIL 0x803 -#define ERR_INVALID_CLASSIFIERTABLE_FOR_SF 0x804 -#define ERR_SFTABLE_FULL 0x805 -#define ERR_CLSASSIFIER_TABLE_FULL 0x806 -#define ERR_PHSRULE_MEMALLOC_FAIL 0x807 -#define ERR_CLSID_MATCH_FAIL 0x808 -#define ERR_PHSRULE_MATCH_FAIL 0x809 - -struct bcm_phs_rule { - u8 u8PHSI; - u8 u8PHSFLength; - u8 u8PHSF[MAX_PHS_LENGTHS]; - u8 u8PHSMLength; - u8 u8PHSM[MAX_PHS_LENGTHS]; - u8 u8PHSS; - u8 u8PHSV; - u8 u8RefCnt; - u8 bUnclassifiedPHSRule; - u8 u8Reserved[3]; - long PHSModifiedBytes; - unsigned long PHSModifiedNumPackets; - unsigned long PHSErrorNumPackets; -}; - -enum bcm_phs_classifier_context { - eActiveClassifierRuleContext, - eOldClassifierRuleContext -}; - -struct bcm_phs_classifier_entry { - u8 bUsed; - u16 uiClassifierRuleId; - u8 u8PHSI; - struct bcm_phs_rule *pstPhsRule; - u8 bUnclassifiedPHSRule; -}; - -struct bcm_phs_classifier_table { - u16 uiTotalClassifiers; - struct bcm_phs_classifier_entry stActivePhsRulesList[MAX_PHSRULE_PER_SF]; - struct bcm_phs_classifier_entry stOldPhsRulesList[MAX_PHSRULE_PER_SF]; - u16 uiOldestPhsRuleIndex; -}; - -struct bcm_phs_entry { - u8 bUsed; - u16 uiVcid; - struct bcm_phs_classifier_table *pstClassifierTable; -}; - -struct bcm_phs_table { - u16 uiTotalServiceFlows; - struct bcm_phs_entry stSFList[MAX_SERVICEFLOWS]; -}; - -struct bcm_phs_extension { - /* PHS Specific data */ - struct bcm_phs_table *pstServiceFlowPhsRulesTable; - void *CompressedTxBuffer; - void *UnCompressedRxBuffer; -}; - -#endif diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c deleted file mode 100644 index 262613436d1e..000000000000 --- a/drivers/staging/bcm/PHSModule.c +++ /dev/null @@ -1,1699 +0,0 @@ -#include "headers.h" - -static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext, - B_UINT8 u8AssociatedPHSI); - -static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule); - -static bool DerefPhsRule(B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule); - -static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_classifier_entry **ppstClassifierEntry); - -static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, - B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - struct bcm_phs_rule **ppstPhsRule); - -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable); - -static int phs_compress(struct bcm_phs_rule *phs_members, - unsigned char *in_buf, - unsigned char *out_buf, - unsigned int *header_size, - UINT *new_header_size); - -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size); - -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *phs_rules, - UINT *header_size); - -static ULONG PhsCompress(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pOldHeaderSize, - UINT *pNewHeaderSize); - -static ULONG PhsDeCompress(void *pvContext, - B_UINT16 uiVcid, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pInHeaderSize, - UINT *pOutHeaderSize); - -#define IN -#define OUT - -/* - * Function: PHSTransmit - * Description: This routine handle PHS(Payload Header Suppression for Tx path. - * It extracts a fragment of the NDIS_PACKET containing the header - * to be suppressed. It then suppresses the header by invoking PHS exported compress routine. - * The header data after suppression is copied back to the NDIS_PACKET. - * - * Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context - * IN Packet - NDIS packet containing data to be transmitted - * IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to - * identify PHS rule to be applied. - * B_UINT16 uiClassifierRuleID - Classifier Rule ID - * BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF. - * - * Return: STATUS_SUCCESS - If the send was successful. - * Other - If an error occurred. - */ - -int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - bool bHeaderSuppressionEnabled, - UINT *PacketLen, - UCHAR bEthCSSupport) -{ - /* PHS Sepcific */ - UINT unPHSPktHdrBytesCopied = 0; - UINT unPhsOldHdrSize = 0; - UINT unPHSNewPktHeaderLen = 0; - /* Pointer to PHS IN Hdr Buffer */ - PUCHAR pucPHSPktHdrInBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf; - /* Pointer to PHS OUT Hdr Buffer */ - PUCHAR pucPHSPktHdrOutBuf = - Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf; - UINT usPacketType; - UINT BytesToRemove = 0; - bool bPHSI = 0; - LONG ulPhsStatus = 0; - UINT numBytesCompressed = 0; - struct sk_buff *newPacket = NULL; - struct sk_buff *Packet = *pPacket; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "In PHSTransmit"); - - if (!bEthCSSupport) - BytesToRemove = ETH_HLEN; - /* - * Accumulate the header upto the size we support suppression - * from NDIS packet - */ - - usPacketType = ((struct ethhdr *)(Packet->data))->h_proto; - - pucPHSPktHdrInBuf = Packet->data + BytesToRemove; - /* considering data after ethernet header */ - if ((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS) - unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove); - else - unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS; - - if ((unPHSPktHdrBytesCopied > 0) && - (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) { - - /* - * Step 2 Suppress Header using PHS and fill into intermediate - * ucaPHSPktHdrOutBuf. - * Suppress only if IP Header and PHS Enabled For the - * Service Flow - */ - if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) || - (usPacketType == ETHERNET_FRAMETYPE_IPV6)) && - (bHeaderSuppressionEnabled)) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nTrying to PHS Compress Using Classifier rule 0x%X", - uiClassifierRuleID); - unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied; - ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext, - Vcid, - uiClassifierRuleID, - pucPHSPktHdrInBuf, - pucPHSPktHdrOutBuf, - &unPhsOldHdrSize, - &unPHSNewPktHeaderLen); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, - DBG_LVL_ALL, - "\nPHS Old header Size : %d New Header Size %d\n", - unPhsOldHdrSize, unPHSNewPktHeaderLen); - - if (unPHSNewPktHeaderLen == unPhsOldHdrSize) { - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) - bPHSI = *pucPHSPktHdrOutBuf; - - ulPhsStatus = STATUS_PHS_NOCOMPRESSION; - } - - if (ulPhsStatus == STATUS_PHS_COMPRESSED) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "PHS Sending packet Compressed"); - - if (skb_cloned(Packet)) { - newPacket = - skb_copy(Packet, GFP_ATOMIC); - - if (newPacket == NULL) - return STATUS_FAILURE; - - dev_kfree_skb(Packet); - *pPacket = Packet = newPacket; - pucPHSPktHdrInBuf = - Packet->data + BytesToRemove; - } - - numBytesCompressed = unPhsOldHdrSize - - (unPHSNewPktHeaderLen + PHSI_LEN); - - memcpy(pucPHSPktHdrInBuf + numBytesCompressed, - pucPHSPktHdrOutBuf, - unPHSNewPktHeaderLen + PHSI_LEN); - memcpy(Packet->data + numBytesCompressed, - Packet->data, BytesToRemove); - skb_pull(Packet, numBytesCompressed); - - return STATUS_SUCCESS; - } else { - /* if one byte headroom is not available, - * increase it through skb_cow - */ - if (!(skb_headroom(Packet) > 0)) { - - if (skb_cow(Packet, 1)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, - 0, 0, - "SKB Cow Failed\n"); - return STATUS_FAILURE; - } - } - skb_push(Packet, 1); - - /* - * CAUTION: The MAC Header is getting corrupted - * here for IP CS - can be saved by copying 14 - * Bytes. not needed .... hence corrupting it. - */ - *(Packet->data + BytesToRemove) = bPHSI; - return STATUS_SUCCESS; - } - } else { - - if (!bHeaderSuppressionEnabled) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - PHS_SEND, DBG_LVL_ALL, - "\nHeader Suppression Disabled For SF: No PHS\n"); - - return STATUS_SUCCESS; - } - } - - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - * "PHSTransmit : Dumping data packet After PHS"); */ - return STATUS_SUCCESS; -} - -int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT bHeaderSuppressionEnabled) -{ - u32 nStandardPktHdrLen = 0; - u32 nTotalsuppressedPktHdrBytes = 0; - int ulPhsStatus = 0; - PUCHAR pucInBuff = NULL; - UINT TotalBytesAdded = 0; - - if (!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nPhs Disabled for incoming packet"); - return ulPhsStatus; - } - - pucInBuff = packet->data; - - /* Restore PHS suppressed header */ - nStandardPktHdrLen = packet->len; - ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext, - usVcid, - pucInBuff, - Adapter->ucaPHSPktRestoreBuf, - &nTotalsuppressedPktHdrBytes, - &nStandardPktHdrLen); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", - nTotalsuppressedPktHdrBytes, nStandardPktHdrLen); - - if (ulPhsStatus != STATUS_PHS_COMPRESSED) { - skb_pull(packet, 1); - return STATUS_SUCCESS; - } else { - TotalBytesAdded = nStandardPktHdrLen - - nTotalsuppressedPktHdrBytes - PHSI_LEN; - - if (TotalBytesAdded) { - if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded)) - skb_push(packet, TotalBytesAdded); - else { - if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_PRINTK, 0, 0, - "cow failed in receive\n"); - return STATUS_FAILURE; - } - - skb_push(packet, TotalBytesAdded); - } - } - - memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, - nStandardPktHdrLen); - } - - return STATUS_SUCCESS; -} - -void DumpFullPacket(UCHAR *pBuf, UINT nPktLen) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - "Dumping Data Packet"); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, - pBuf, nPktLen); -} - -/* - * Procedure: phs_init - * - * Description: This routine is responsible for allocating memory for classifier - * and PHS rules. - * - * Arguments: - * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules - * and PHS Rules , RX, TX buffer etc - * - * Returns: - * TRUE(1) -If allocation of memory was successful. - * FALSE -If allocation of memory fails. - */ -int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, - struct bcm_mini_adapter *Adapter) -{ - int i; - struct bcm_phs_table *pstServiceFlowTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\nPHS:phs_init function"); - - if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable) - return -EINVAL; - - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = - kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL); - - if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAllocation ServiceFlowPhsRulesTable failed"); - return -ENOMEM; - } - - pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable; - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry sServiceFlow = - pstServiceFlowTable->stSFList[i]; - sServiceFlow.pstClassifierTable = - kzalloc(sizeof(struct bcm_phs_classifier_table), - GFP_KERNEL); - if (!sServiceFlow.pstClassifierTable) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - } - - pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->CompressedTxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - pPhsdeviceExtension->UnCompressedRxBuffer = - kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); - if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nAllocation failed"); - kfree(pPhsdeviceExtension->CompressedTxBuffer); - free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); - pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; - return -ENOMEM; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "\n phs_init Successful"); - return STATUS_SUCCESS; -} - -int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt) -{ - if (pPHSDeviceExt->pstServiceFlowPhsRulesTable) { - free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable); - pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; - } - - kfree(pPHSDeviceExt->CompressedTxBuffer); - pPHSDeviceExt->CompressedTxBuffer = NULL; - - kfree(pPHSDeviceExt->UnCompressedRxBuffer); - pPHSDeviceExt->UnCompressedRxBuffer = NULL; - - return 0; -} - -/* - * PHS functions - * PhsUpdateClassifierRule - * - * Routine Description: - * Exported function to add or modify a PHS Rule. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * IN struct bcm_phs_rule *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsUpdateClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid , - IN B_UINT16 uiClsId , - IN struct bcm_phs_rule *psPhsRule, - IN B_UINT8 u8AssociatedPHSI) -{ - ULONG lStatus = 0; - UINT nSFIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS With Corr2 Changes\n"); - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - if (u8AssociatedPHSI == 0) - return ERR_PHS_INVALID_PHS_RULE; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - /* This is a new SF. Create a mapping entry for this */ - lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId, - pDeviceExtension->pstServiceFlowPhsRulesTable, - psPhsRule, - u8AssociatedPHSI); - return lStatus; - } - - /* SF already Exists Add PHS Rule to existing SF */ - lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId, - pstServiceFlowEntry, - psPhsRule, - u8AssociatedPHSI); - - return lStatus; -} - -/* - * PhsDeletePHSRule - * - * Routine Description: - * Deletes the specified phs Rule within Vcid - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeletePHSRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT8 u8PHSI) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_entry; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "======>\n"); - - if (pDeviceExtension) { - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - if (curr_entry->bUsed && - curr_entry->pstPhsRule && - (curr_entry->pstPhsRule->u8PHSI == u8PHSI)) { - - if (curr_entry->pstPhsRule->u8RefCnt) - curr_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_entry->pstPhsRule->u8RefCnt) - kfree(curr_entry->pstPhsRule); - - memset(curr_entry, - 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - } - } - return 0; -} - -/* - * PhsDeleteClassifierRule - * - * Routine Description: - * Exported function to Delete a PHS Rule for the SFID,CLSID Pair. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies - * IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteClassifierRule(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - if (pstClassifierEntry->pstPhsRule) { - if (pstClassifierEntry->pstPhsRule->u8RefCnt) - pstClassifierEntry->pstPhsRule->u8RefCnt--; - - if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt) - kfree(pstClassifierEntry->pstPhsRule); - } - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - - nClsidIndex = - GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eOldClassifierRuleContext, - &pstClassifierEntry); - - if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && - (!pstClassifierEntry->bUnclassifiedPHSRule)) { - kfree(pstClassifierEntry->pstPhsRule); - memset(pstClassifierEntry, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - -out: - return 0; -} - -/* - * PhsDeleteSFRules - * - * Routine Description: - * Exported function to Delete a all PHS Rules for the SFID. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context - * IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - struct bcm_phs_classifier_entry *curr_clsf_entry; - struct bcm_phs_classifier_entry *curr_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "====>\n"); - - if (!pDeviceExtension) - goto out; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "SFID Match Failed\n"); - return ERR_SF_MATCH_FAIL; - } - - pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable; - if (pstClassifierRulesTable) { - for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) { - curr_clsf_entry = - &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]; - - curr_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]; - - if (curr_clsf_entry->pstPhsRule) { - - if (curr_clsf_entry->pstPhsRule->u8RefCnt) - curr_clsf_entry->pstPhsRule->u8RefCnt--; - - if (0 == curr_clsf_entry->pstPhsRule->u8RefCnt) - kfree(curr_clsf_entry->pstPhsRule); - - curr_clsf_entry->pstPhsRule = NULL; - } - memset(curr_clsf_entry, 0, - sizeof(struct bcm_phs_classifier_entry)); - if (curr_rules_list->pstPhsRule) { - - if (curr_rules_list->pstPhsRule->u8RefCnt) - curr_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_rules_list->pstPhsRule); - - curr_rules_list->pstPhsRule = NULL; - } - memset(curr_rules_list, 0, - sizeof(struct bcm_phs_classifier_entry)); - } - } - pstServiceFlowEntry->bUsed = false; - pstServiceFlowEntry->uiVcid = 0; - -out: - return 0; -} - -/* - * PhsCompress - * - * Routine Description: - * Exported function to compress the data using PHS. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header compression applies. - * IN UINT uiClsId - The Classifier ID to which current packet - * header compression applies. - * IN void *pvInputBuffer - The Input buffer containg packet header - * data - * IN void *pvOutputBuffer - The output buffer returned by this - * function after PHS - * IN UINT *pOldHeaderSize - The actual size of the header before PHS - * IN UINT *pNewHeaderSize - The new size of the header after applying - * PHS - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pOldHeaderSize, - OUT UINT *pNewHeaderSize) -{ - UINT nSFIndex = 0, nClsidIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - ULONG lStatus = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Invalid Device Extension\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "Suppressing header\n"); - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "SFID Match Failed\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, - uiClsId, eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClsidIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "No PHS Rule Defined For Classifier\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* get rule from SF id,Cls ID pair and proceed */ - pstPhsRule = pstClassifierEntry->pstPhsRule; - if (!ValidatePHSRuleComplete(pstPhsRule)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "PHS Rule Defined For Classifier But Not Complete\n"); - lStatus = STATUS_PHS_NOCOMPRESSION; - return lStatus; - } - - /* Compress Packet */ - lStatus = phs_compress(pstPhsRule, - (PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pOldHeaderSize, - pNewHeaderSize); - - if (lStatus == STATUS_PHS_COMPRESSED) { - pstPhsRule->PHSModifiedBytes += - *pOldHeaderSize - *pNewHeaderSize - 1; - pstPhsRule->PHSModifiedNumPackets++; - } else { - pstPhsRule->PHSErrorNumPackets++; - } - - return lStatus; -} - -/* - * PhsDeCompress - * - * Routine Description: - * Exported function to restore the packet header in Rx path. - * - * Arguments: - * IN void* pvContext - PHS Driver Specific Context. - * IN B_UINT16 uiVcid - The Service Flow ID to which current - * packet header restoration applies. - * IN void *pvInputBuffer - The Input buffer containg suppressed - * packet header data - * OUT void *pvOutputBuffer - The output buffer returned by this - * function after restoration - * OUT UINT *pHeaderSize - The packet header size after restoration - * is returned in this parameter. - * - * Return Value: - * - * 0 if successful, - * >0 Error. - */ -static ULONG PhsDeCompress(IN void *pvContext, - IN B_UINT16 uiVcid, - IN void *pvInputBuffer, - OUT void *pvOutputBuffer, - OUT UINT *pInHeaderSize, - OUT UINT *pOutHeaderSize) -{ - UINT nSFIndex = 0, nPhsRuleIndex = 0; - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - UINT phsi; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_extension *pDeviceExtension = - (struct bcm_phs_extension *)pvContext; - - *pInHeaderSize = 0; - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return ERR_PHS_INVALID_DEVICE_EXETENSION; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "Restoring header\n"); - - phsi = *((unsigned char *)(pvInputBuffer)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "PHSI To Be Used For restore : %x\n", phsi); - if (phsi == UNCOMPRESSED_PACKET) - return STATUS_PHS_NOCOMPRESSION; - - /* Retrieve the SFID Entry Index for requested Service Flow */ - nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, - uiVcid, &pstServiceFlowEntry); - if (nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "SFID Match Failed During Lookup\n"); - return ERR_SF_MATCH_FAIL; - } - - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eActiveClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) { - /* Phs Rule does not exist in active rules table. Lets try - * in the old rules table. */ - nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, - phsi, - eOldClassifierRuleContext, - &pstPhsRule); - if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) - return ERR_PHSRULE_MATCH_FAIL; - } - - *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer, - (PUCHAR)pvOutputBuffer, - pstPhsRule, - pOutHeaderSize); - - pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1; - - pstPhsRule->PHSModifiedNumPackets++; - return STATUS_PHS_COMPRESSED; -} - -/* - * Procedure: free_phs_serviceflow_rules - * - * Description: This routine is responsible for freeing memory allocated for - * PHS rules. - * - * Arguments: - * rules - ptr to S_SERVICEFLOW_TABLE structure. - * - * Returns: - * Does not return any value. - */ -static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable) -{ - int i, j; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - struct bcm_phs_classifier_entry *curr_act_rules_list; - struct bcm_phs_classifier_entry *curr_old_rules_list; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "=======>\n"); - - if (!psServiceFlowRulesTable) - goto out; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - struct bcm_phs_entry stServiceFlowEntry = - psServiceFlowRulesTable->stSFList[i]; - struct bcm_phs_classifier_table *pstClassifierRulesTable = - stServiceFlowEntry.pstClassifierTable; - - if (pstClassifierRulesTable) { - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - curr_act_rules_list = - &pstClassifierRulesTable->stActivePhsRulesList[j]; - - curr_old_rules_list = - &pstClassifierRulesTable->stOldPhsRulesList[j]; - - if (curr_act_rules_list->pstPhsRule) { - - if (curr_act_rules_list->pstPhsRule->u8RefCnt) - curr_act_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_act_rules_list->pstPhsRule); - - curr_act_rules_list->pstPhsRule = NULL; - } - - if (curr_old_rules_list->pstPhsRule) { - - if (curr_old_rules_list->pstPhsRule->u8RefCnt) - curr_old_rules_list->pstPhsRule->u8RefCnt--; - - if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt) - kfree(curr_old_rules_list->pstPhsRule); - - curr_old_rules_list->pstPhsRule = NULL; - } - } - kfree(pstClassifierRulesTable); - stServiceFlowEntry.pstClassifierTable = - pstClassifierRulesTable = NULL; - } - } - -out: - - kfree(psServiceFlowRulesTable); - psServiceFlowRulesTable = NULL; -} - -static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule) -{ - return (psPhsRule && - psPhsRule->u8PHSI && - psPhsRule->u8PHSS && - psPhsRule->u8PHSFLength); -} - -UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable, - IN B_UINT16 uiVcid, - struct bcm_phs_entry **ppstServiceFlowEntry) -{ - int i; - struct bcm_phs_entry *curr_sf_list; - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - curr_sf_list = &psServiceFlowTable->stSFList[i]; - if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) { - *ppstServiceFlowEntry = curr_sf_list; - return i; - } - } - - *ppstServiceFlowEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiClsid, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_classifier_entry **ppstClassifierEntry) -{ - int i; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = - &pstClassifierTable->stActivePhsRulesList[i]; - else - psClassifierRules = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (psClassifierRules->bUsed && - (psClassifierRules->uiClassifierRuleId == uiClsid)) { - *ppstClassifierEntry = psClassifierRules; - return i; - } - } - - *ppstClassifierEntry = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable, - IN B_UINT32 uiPHSI, - enum bcm_phs_classifier_context eClsContext, - OUT struct bcm_phs_rule **ppstPhsRule) -{ - int i; - struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - - for (i = 0; i < MAX_PHSRULE_PER_SF; i++) { - if (eClsContext == eActiveClassifierRuleContext) - pstClassifierRule = - &pstClassifierTable->stActivePhsRulesList[i]; - else - pstClassifierRule = - &pstClassifierTable->stOldPhsRulesList[i]; - - if (pstClassifierRule->bUsed && - (pstClassifierRule->u8PHSI == uiPHSI)) { - *ppstPhsRule = pstClassifierRule->pstPhsRule; - return i; - } - } - - *ppstPhsRule = NULL; - return PHS_INVALID_TABLE_INDEX; -} - -static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_table *psServiceFlowTable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - UINT uiStatus = 0; - int iSfIndex; - bool bFreeEntryFound = false; - struct bcm_phs_entry *curr_list; - - /* Check for a free entry in SFID table */ - for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) { - curr_list = &psServiceFlowTable->stSFList[iSfIndex]; - if (!curr_list->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - - if (!bFreeEntryFound) - return ERR_SFTABLE_FULL; - - psaClassifiertable = curr_list->pstClassifierTable; - uiStatus = CreateClassifierPHSRule(uiClsId, - psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - if (uiStatus == PHS_SUCCESS) { - /* Add entry at free index to the SF */ - curr_list->bUsed = TRUE; - curr_list->uiVcid = uiVcid; - } - - return uiStatus; -} - -static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, - IN B_UINT16 uiClsId, - IN struct bcm_phs_entry *pstServiceFlowEntry, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_classifier_entry *pstClassifierEntry = NULL; - UINT uiStatus = PHS_SUCCESS; - UINT nClassifierIndex = 0; - struct bcm_phs_classifier_table *psaClassifiertable = NULL; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psaClassifiertable = pstServiceFlowEntry->pstClassifierTable; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "==>"); - - /* Check if the supplied Classifier already exists */ - nClassifierIndex = GetClassifierEntry( - pstServiceFlowEntry->pstClassifierTable, - uiClsId, - eActiveClassifierRuleContext, - &pstClassifierEntry); - - if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier doesn't exist. So its a new classifier being - * added. - * Add new entry to associate PHS Rule to the Classifier - */ - - uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, - psPhsRule, - eActiveClassifierRuleContext, - u8AssociatedPHSI); - return uiStatus; - } - - /* - * The Classifier exists.The PHS Rule for this classifier - * is being modified - */ - - if (pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI) { - if (pstClassifierEntry->pstPhsRule == NULL) - return ERR_PHS_INVALID_PHS_RULE; - - /* - * This rule already exists if any fields are changed for this - * PHS rule update them. - */ - /* If any part of PHSF is valid then we update PHSF */ - if (psPhsRule->u8PHSFLength) { - /* update PHSF */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, - psPhsRule->u8PHSF, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSFLength) { - /* update PHSFLen */ - pstClassifierEntry->pstPhsRule->u8PHSFLength = - psPhsRule->u8PHSFLength; - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM */ - memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, - psPhsRule->u8PHSM, - MAX_PHS_LENGTHS); - } - - if (psPhsRule->u8PHSMLength) { - /* update PHSM Len */ - pstClassifierEntry->pstPhsRule->u8PHSMLength = - psPhsRule->u8PHSMLength; - } - - if (psPhsRule->u8PHSS) { - /* update PHSS */ - pstClassifierEntry->pstPhsRule->u8PHSS = - psPhsRule->u8PHSS; - } - - /* update PHSV */ - pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV; - } else { - /* A new rule is being set for this classifier. */ - uiStatus = UpdateClassifierPHSRule(uiClsId, - pstClassifierEntry, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - } - - return uiStatus; -} - -static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - enum bcm_phs_classifier_context eClsContext, - B_UINT8 u8AssociatedPHSI) -{ - UINT iClassifierIndex = 0; - bool bFreeEntryFound = false; - struct bcm_phs_classifier_entry *psClassifierRules = NULL; - UINT nStatus = PHS_SUCCESS; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, - "Inside CreateClassifierPHSRule"); - - if (psaClassifiertable == NULL) - return ERR_INVALID_CLASSIFIERTABLE_FOR_SF; - - if (eClsContext == eOldClassifierRuleContext) { - /* - * If An Old Entry for this classifier ID already exists in the - * old rules table replace it. - */ - - iClassifierIndex = GetClassifierEntry(psaClassifiertable, - uiClsId, - eClsContext, - &psClassifierRules); - - if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) { - /* - * The Classifier already exists in the old rules table - * Lets replace the old classifier with the new one. - */ - bFreeEntryFound = TRUE; - } - } - - if (!bFreeEntryFound) { - /* Continue to search for a free location to add the rule */ - for (iClassifierIndex = 0; iClassifierIndex < - MAX_PHSRULE_PER_SF; iClassifierIndex++) { - if (eClsContext == eActiveClassifierRuleContext) - psClassifierRules = &psaClassifiertable->stActivePhsRulesList[iClassifierIndex]; - else - psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - if (!psClassifierRules->bUsed) { - bFreeEntryFound = TRUE; - break; - } - } - } - - if (!bFreeEntryFound) { - - if (eClsContext == eActiveClassifierRuleContext) - return ERR_CLSASSIFIER_TABLE_FULL; - /* Lets replace the oldest rule if we are looking in - * old Rule table */ - if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF) - psaClassifiertable->uiOldestPhsRuleIndex = 0; - - iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex; - psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex]; - - psaClassifiertable->uiOldestPhsRuleIndex++; - } - - if (eClsContext == eOldClassifierRuleContext) { - - if (psClassifierRules->pstPhsRule == NULL) { - - psClassifierRules->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - - if (NULL == psClassifierRules->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - - psClassifierRules->bUsed = TRUE; - psClassifierRules->uiClassifierRuleId = uiClsId; - psClassifierRules->u8PHSI = psPhsRule->u8PHSI; - psClassifierRules->bUnclassifiedPHSRule = - psPhsRule->bUnclassifiedPHSRule; - - /* Update The PHS rule */ - memcpy(psClassifierRules->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else - nStatus = UpdateClassifierPHSRule(uiClsId, - psClassifierRules, - psaClassifiertable, - psPhsRule, - u8AssociatedPHSI); - - return nStatus; -} - -static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, - IN struct bcm_phs_classifier_entry *pstClassifierEntry, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI) -{ - struct bcm_phs_rule *pstAddPhsRule = NULL; - UINT nPhsRuleIndex = 0; - bool bPHSRuleOrphaned = false; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - psPhsRule->u8RefCnt = 0; - - /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry */ - bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable, - pstClassifierEntry->pstPhsRule); - - /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in - * Classifier table for this SF */ - nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI, - eActiveClassifierRuleContext, - &pstAddPhsRule); - if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nAdding New PHSRuleEntry For Classifier"); - - if (psPhsRule->u8PHSI == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, "\nError PHSI is Zero\n"); - return ERR_PHS_INVALID_PHS_RULE; - } - - /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for - * uiClsId */ - if (false == bPHSRuleOrphaned) { - - pstClassifierEntry->pstPhsRule = - kmalloc(sizeof(struct bcm_phs_rule), - GFP_KERNEL); - if (NULL == pstClassifierEntry->pstPhsRule) - return ERR_PHSRULE_MEMALLOC_FAIL; - } - memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, - sizeof(struct bcm_phs_rule)); - } else { - /* Step 2.b PHS Rule Exists Tie uiClsId with the existing - * PHS Rule */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, - DBG_LVL_ALL, - "\nTying Classifier to Existing PHS Rule"); - if (bPHSRuleOrphaned) { - kfree(pstClassifierEntry->pstPhsRule); - pstClassifierEntry->pstPhsRule = NULL; - } - pstClassifierEntry->pstPhsRule = pstAddPhsRule; - } - - pstClassifierEntry->bUsed = TRUE; - pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI; - pstClassifierEntry->uiClassifierRuleId = uiClsId; - pstClassifierEntry->pstPhsRule->u8RefCnt++; - pstClassifierEntry->bUnclassifiedPHSRule = - pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule; - - return PHS_SUCCESS; -} - -static bool DerefPhsRule(IN B_UINT16 uiClsId, - struct bcm_phs_classifier_table *psaClassifiertable, - struct bcm_phs_rule *pstPhsRule) -{ - if (pstPhsRule == NULL) - return false; - - if (pstPhsRule->u8RefCnt) - pstPhsRule->u8RefCnt--; - - return (0 == pstPhsRule->u8RefCnt); -} - -static void dbg_print_st_cls_entry(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry, - struct bcm_phs_classifier_entry *st_cls_entry) -{ - int k; - - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", st_serv_flow_entry->uiVcid); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", st_cls_entry->uiClassifierRuleId); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", st_cls_entry->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n"); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", st_cls_entry->pstPhsRule->u8PHSI); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", st_cls_entry->pstPhsRule->u8PHSFLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : "); - - for (k = 0 ; k < st_cls_entry->pstPhsRule->u8PHSFLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSF[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", st_cls_entry->pstPhsRule->u8PHSMLength); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :"); - - for (k = 0; k < st_cls_entry->pstPhsRule->u8PHSMLength; k++) - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSM[k]); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", st_cls_entry->pstPhsRule->u8PHSS); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", st_cls_entry->pstPhsRule->u8PHSV); - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n"); -} - -static void phsrules_per_sf_dbg_print(struct bcm_mini_adapter *ad, - struct bcm_phs_entry *st_serv_flow_entry) -{ - int j, l; - struct bcm_phs_classifier_entry st_cls_entry; - - for (j = 0; j < MAX_PHSRULE_PER_SF; j++) { - - for (l = 0; l < 2; l++) { - - if (l == 0) { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stActivePhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Active PHS Rule :\n"); - } else { - st_cls_entry = st_serv_flow_entry->pstClassifierTable->stOldPhsRulesList[j]; - if (st_cls_entry.bUsed) - BCM_DEBUG_PRINT(ad, - DBG_TYPE_OTHERS, - DUMP_INFO, - (DBG_LVL_ALL | DBG_NO_FUNC_PRINT), - "\n Old PHS Rule :\n"); - } - - if (st_cls_entry.bUsed) { - dbg_print_st_cls_entry(ad, - st_serv_flow_entry, - &st_cls_entry); - } - } - } -} - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension) -{ - int i; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, - "\n Dumping PHS Rules :\n"); - - for (i = 0; i < MAX_SERVICEFLOWS; i++) { - - struct bcm_phs_entry stServFlowEntry = - pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i]; - - if (!stServFlowEntry.bUsed) - continue; - - phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry); - } -} - -/* - * Procedure: phs_decompress - * - * Description: This routine restores the static fields within the packet. - * - * Arguments: - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed - * header is copied. - * decomp_phs_rules - ptr to PHS rule. - * header_size - ptr to field which holds the phss or - * phsf_length. - * - * Returns: - * size - The number of bytes of dynamic fields present with in the - * incoming packet header. - * 0 - If PHS rule is NULL.If PHSI is 0 indicateing packet as - * uncompressed. - */ -static int phs_decompress(unsigned char *in_buf, - unsigned char *out_buf, - struct bcm_phs_rule *decomp_phs_rules, - UINT *header_size) -{ - int phss, size = 0; - struct bcm_phs_rule *tmp_memb; - int bit, i = 0; - unsigned char *phsf, *phsm; - int in_buf_len = *header_size - 1; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - in_buf++; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, - "====>\n"); - *header_size = 0; - - if (decomp_phs_rules == NULL) - return 0; - - tmp_memb = decomp_phs_rules; - /* - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL, - * "\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); - * header_size = tmp_memb->u8PHSFLength; - */ - phss = tmp_memb->u8PHSS; - phsf = tmp_memb->u8PHSF; - phsm = tmp_memb->u8PHSM; - - if (phss > MAX_PHS_LENGTHS) - phss = MAX_PHS_LENGTHS; - - /* - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL, - * "\nDECOMP: - * In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); - */ - while ((phss > 0) && (size < in_buf_len)) { - bit = ((*phsm << i) & SUPPRESS); - - if (bit == SUPPRESS) { - *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d phsf %d output %d", - phss, *phsf, *out_buf); - } else { - *out_buf = *in_buf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, - DBG_LVL_ALL, - "\nDECOMP:In phss %d input %d output %d", - phss, *in_buf, *out_buf); - in_buf++; - size++; - } - out_buf++; - phsf++; - phss--; - i++; - *header_size = *header_size + 1; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - - return size; -} - -/* - * Procedure: phs_compress - * - * Description: This routine suppresses the static fields within the packet. - * Before that it will verify the fields to be suppressed with the corresponding - * fields in the phsf. For verification it checks the phsv field of PHS rule. - * If set and verification succeeds it suppresses the field.If any one static - * field is found different none of the static fields are suppressed then the - * packet is sent as uncompressed packet with phsi=0. - * - * Arguments: - * phs_rule - ptr to PHS rule. - * in_buf - ptr to incoming packet buffer. - * out_buf - ptr to output buffer where the suppressed header is - * copied. - * header_size - ptr to field which holds the phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e - * dynamic fields - * 0 - If PHS rule is NULL.If PHSV field is not set. If the - * verification fails. - */ -static int phs_compress(struct bcm_phs_rule *phs_rule, - unsigned char *in_buf, - unsigned char *out_buf, - UINT *header_size, - UINT *new_header_size) -{ - unsigned char *old_addr = out_buf; - int suppress = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (phs_rule == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nphs_compress(): phs_rule null!"); - *out_buf = ZERO_PHSI; - return STATUS_PHS_NOCOMPRESSION; - } - - if (phs_rule->u8PHSS <= *new_header_size) - *header_size = phs_rule->u8PHSS; - else - *header_size = *new_header_size; - - /* To copy PHSI */ - out_buf++; - suppress = verify_suppress_phsf(in_buf, out_buf, phs_rule->u8PHSF, - phs_rule->u8PHSM, phs_rule->u8PHSS, - phs_rule->u8PHSV, new_header_size); - - if (suppress == STATUS_PHS_COMPRESSED) { - *old_addr = (unsigned char)phs_rule->u8PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress phsi %d", - phs_rule->u8PHSI); - } else { - *old_addr = ZERO_PHSI; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In phs_compress PHSV Verification failed"); - } - - return suppress; -} - -/* - * Procedure: verify_suppress_phsf - * - * Description: This routine verifies the fields of the packet and if all the - * static fields are equal it adds the phsi of that PHS rule.If any static - * field differs it woun't suppress any field. - * - * Arguments: - * rules_set - ptr to classifier_rules. - * in_buffer - ptr to incoming packet buffer. - * out_buffer - ptr to output buffer where the suppressed header is copied. - * phsf - ptr to phsf. - * phsm - ptr to phsm. - * phss - variable holding phss. - * - * Returns: - * size - The number of bytes copied into the output buffer i.e dynamic - * fields. - * 0 - Packet has failed the verification. - */ -static int verify_suppress_phsf(unsigned char *in_buffer, - unsigned char *out_buffer, - unsigned char *phsf, - unsigned char *phsm, - unsigned int phss, - unsigned int phsv, - UINT *new_header_size) -{ - unsigned int size = 0; - int bit, i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm); - - if (phss > (*new_header_size)) - phss = *new_header_size; - - while (phss > 0) { - bit = ((*phsm << i) & SUPPRESS); - if (bit == SUPPRESS) { - if (*in_buffer != *phsf) { - if (phsv == VERIFY) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In verify_phsf failed for field %d buf %d phsf %d", - phss, - *in_buffer, - *phsf); - return STATUS_PHS_NOCOMPRESSION; - } - } else - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In verify_phsf success for field %d buf %d phsf %d", - phss, - *in_buffer, - *phsf); - } else { - *out_buffer = *in_buffer; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - PHS_SEND, - DBG_LVL_ALL, - "\nCOMP:In copying_header input %d out %d", - *in_buffer, - *out_buffer); - out_buffer++; - size++; - } - - in_buffer++; - phsf++; - phss--; - i++; - - if (i > MAX_NO_BIT) { - i = 0; - phsm++; - } - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, - "\nCOMP:In verify_phsf success"); - *new_header_size = size; - return STATUS_PHS_COMPRESSED; -} diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h deleted file mode 100644 index d84d60ba48f9..000000000000 --- a/drivers/staging/bcm/PHSModule.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef BCM_MINIPORT_PHSMODULE_H -#define BCM_MINIPORT_PHSMODULE_H - -int PHSTransmit(struct bcm_mini_adapter *Adapter, - struct sk_buff **pPacket, - USHORT Vcid, - B_UINT16 uiClassifierRuleID, - bool bHeaderSuppressionEnabled, - PUINT PacketLen, - UCHAR bEthCSSupport); - -int PHSReceive(struct bcm_mini_adapter *Adapter, - USHORT usVcid, - struct sk_buff *packet, - UINT *punPacketLen, - UCHAR *pucEthernetHdr, - UINT - ); - - -void DumpDataPacketHeader(PUCHAR pPkt); - -void DumpFullPacket(UCHAR *pBuf, UINT nPktLen); - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension); - - -int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, - struct bcm_mini_adapter *Adapter); - -int PhsCleanup(struct bcm_phs_extension *pPHSDeviceExt); - -/* Utility Functions */ -ULONG PhsUpdateClassifierRule(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - struct bcm_phs_rule *psPhsRule, - B_UINT8 u8AssociatedPHSI); - -ULONG PhsDeletePHSRule(void *pvContext, B_UINT16 uiVcid, B_UINT8 u8PHSI); - -ULONG PhsDeleteClassifierRule(void *pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId); - -ULONG PhsDeleteSFRules(void *pvContext, B_UINT16 uiVcid); - - -bool ValidatePHSRule(struct bcm_phs_rule *psPhsRule); - -UINT GetServiceFlowEntry(struct bcm_phs_table *psServiceFlowTable, - B_UINT16 uiVcid, - struct bcm_phs_entry **ppstServiceFlowEntry); - - -void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension); - - -#endif diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h deleted file mode 100644 index 9818128d9320..000000000000 --- a/drivers/staging/bcm/Protocol.h +++ /dev/null @@ -1,128 +0,0 @@ -/************************************ -* Protocol.h -*************************************/ -#ifndef __PROTOCOL_H__ -#define __PROTOCOL_H__ - -#define IPV4 4 -#define IPV6 6 - -struct ArpHeader { - struct arphdr arp; - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -}; - -struct bcm_transport_header { - union { - struct udphdr uhdr; - struct tcphdr thdr; - }; -} __packed; - -enum bcm_ip_frame_type { - eNonIPPacket, - eIPv4Packet, - eIPv6Packet -}; - -enum bcm_eth_frame_type { - eEthUnsupportedFrame, - eEth802LLCFrame, - eEth802LLCSNAPFrame, - eEth802QVLANFrame, - eEthOtherFrame -}; - -struct bcm_eth_packet_info { - enum bcm_ip_frame_type eNwpktIPFrameType; - enum bcm_eth_frame_type eNwpktEthFrameType; - unsigned short usEtherType; - unsigned char ucDSAP; -}; - -struct bcm_eth_q_frame { - struct bcm_eth_header EThHdr; - unsigned short UserPriority:3; - unsigned short CFI:1; - unsigned short VLANID:12; - unsigned short EthType; -} __packed; - -struct bcm_eth_llc_frame { - struct bcm_eth_header EThHdr; - unsigned char DSAP; - unsigned char SSAP; - unsigned char Control; -} __packed; - -struct bcm_eth_llc_snap_frame { - struct bcm_eth_header EThHdr; - unsigned char DSAP; - unsigned char SSAP; - unsigned char Control; - unsigned char OUI[3]; - unsigned short usEtherType; -} __packed; - -struct bcm_ethernet2_frame { - struct bcm_eth_header EThHdr; -} __packed; - -#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) -#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd) -#define ETHERNET_FRAMETYPE_802QVLAN ntohs(0x8100) - -/* Per SF CS Specification Encodings */ -enum bcm_spec_encoding { - eCSSpecUnspecified = 0, - eCSPacketIPV4, - eCSPacketIPV6, - eCS802_3PacketEthernet, - eCS802_1QPacketVLAN, - eCSPacketIPV4Over802_3Ethernet, - eCSPacketIPV6Over802_3Ethernet, - eCSPacketIPV4Over802_1QVLAN, - eCSPacketIPV6Over802_1QVLAN, - eCSPacketUnsupported -}; - -#define IP6_HEADER_LEN 40 -#define IP_VERSION(byte) (((byte&0xF0)>>4)) - -#define MAC_ADDRESS_SIZE 6 -#define ETH_AND_IP_HEADER_LEN (14 + 20) -#define L4_SRC_PORT_LEN 2 -#define L4_DEST_PORT_LEN 2 -#define CTRL_PKT_LEN (8 + ETH_AND_IP_HEADER_LEN) - -#define ETH_ARP_FRAME 0x806 -#define ETH_IPV4_FRAME 0x800 -#define ETH_IPV6_FRAME 0x86DD -#define UDP 0x11 -#define TCP 0x06 - -#define ARP_OP_REQUEST 0x01 -#define ARP_OP_REPLY 0x02 -#define ARP_PKT_SIZE 60 - -/* This is the format for the TCP packet header */ -struct bcm_tcp_header { - unsigned short usSrcPort; - unsigned short usDestPort; - unsigned long ulSeqNumber; - unsigned long ulAckNumber; - unsigned char HeaderLength; - unsigned char ucFlags; - unsigned short usWindowsSize; - unsigned short usChkSum; - unsigned short usUrgetPtr; -}; - -#define TCP_HEADER_LEN sizeof(struct bcm_tcp_header) -#define TCP_ACK 0x10 /* Bit 4 in tcpflags field. */ -#define GET_TCP_HEADER_LEN(byte) ((byte&0xF0)>>4) - -#endif /* __PROTOCOL_H__ */ diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h deleted file mode 100644 index 1ddc8b2539f6..000000000000 --- a/drivers/staging/bcm/Prototypes.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef _PROTOTYPES_H_ -#define _PROTOTYPES_H_ - -VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); - -VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); - -VOID IdleModeResponse(struct bcm_mini_adapter *Adapter, PUINT puiBuffer); - -int control_packet_handler(struct bcm_mini_adapter *Adapter); - -VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex); - -VOID flush_all_queues(struct bcm_mini_adapter *Adapter); - -int register_control_device_interface(struct bcm_mini_adapter *ps_adapter); - -void unregister_control_device_interface(struct bcm_mini_adapter *Adapter); - -INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter,/**ucIPSourceAddressLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength); - ucLoopIndex++) { - src_addr = &pstClassifierRule->stSrcIpAddress; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", - (UINT)src_addr->ulIpv4Mask[ucLoopIndex], - (UINT)ulSrcIP, - (UINT)src_addr->ulIpv6Addr[ucLoopIndex]); - - if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) == - (src_addr->ulIpv4Addr[ucLoopIndex] & - src_addr->ulIpv4Mask[ucLoopIndex])) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Ip Address Not Matched"); - return false; -} - - -/******************************************************************* -* Function - MatchDestIpAddress() -* -* Description - Checks whether the Destination IP address from the packet -* matches with that of Queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ulDestIP : Destination IP address from the packet. -* -* Returns - TRUE(If address matches) else FAIL . -*********************************************************************/ -static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress; - - ulDestIP = ntohl(ulDestIP); - if (0 == pstClassifierRule->ucIPDestinationAddressLength) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Ip Address 0x%x 0x%x 0x%x ", - (UINT)ulDestIP, - (UINT)dest_addr->ulIpv4Mask[ucLoopIndex], - (UINT)dest_addr->ulIpv4Addr[ucLoopIndex]); - - for (ucLoopIndex = 0; - ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength); - ucLoopIndex++) { - if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) == - (dest_addr->ulIpv4Addr[ucLoopIndex] & - dest_addr->ulIpv4Mask[ucLoopIndex])) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Ip Address Not Matched"); - return false; -} - - -/************************************************************************ -* Function - MatchTos() -* -* Description - Checks the TOS from the packet matches with that of queue. -* -* Parameters - pstClassifierRule : Pointer to the packet info structure. -* - ucTypeOfService: TOS from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -**************************************************************************/ -static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, - UCHAR ucTypeOfService) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (3 != pstClassifierRule->ucIPTypeOfServiceLength) - return TRUE; - - if (((pstClassifierRule->ucTosMask & ucTypeOfService) <= - pstClassifierRule->ucTosHigh) && - ((pstClassifierRule->ucTosMask & ucTypeOfService) >= - pstClassifierRule->ucTosLow)) - return TRUE; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Type Of Service Not Matched"); - return false; -} - - -/*************************************************************************** -* Function - MatchProtocol() -* -* Description - Checks the protocol from the packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ucProtocol : Protocol from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -****************************************************************************/ -bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, - UCHAR ucProtocol) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (0 == pstClassifierRule->ucProtocolLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucProtocolLength; - ucLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol:0x%X Classification Protocol:0x%X", - ucProtocol, - pstClassifierRule->ucProtocol[ucLoopIndex]); - if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol Not Matched"); - return false; -} - - -/*********************************************************************** -* Function - MatchSrcPort() -* -* Description - Checks, Source port from the packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ushSrcPort : Source port from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -***************************************************************************/ -bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, - USHORT ushSrcPort) -{ - UCHAR ucLoopIndex = 0; - - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - - if (0 == pstClassifierRule->ucSrcPortRangeLength) - return TRUE; - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength; - ucLoopIndex++) { - if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] && - ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex]) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Port: %x Not Matched ", - ushSrcPort); - return false; -} - - -/*********************************************************************** -* Function - MatchDestPort() -* -* Description - Checks, Destination port from packet matches with that of queue. -* -* Parameters - pstClassifierRule: Pointer to the packet info structure. -* - ushDestPort : Destination port from the packet. -* -* Returns - TRUE(If address matches) else FAIL. -***************************************************************************/ -bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, - USHORT ushDestPort) -{ - UCHAR ucLoopIndex = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (0 == pstClassifierRule->ucDestPortRangeLength) - return TRUE; - - for (ucLoopIndex = 0; - ucLoopIndex < pstClassifierRule->ucDestPortRangeLength; - ucLoopIndex++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Matching Port:0x%X 0x%X 0x%X", - ushDestPort, - pstClassifierRule->usDestPortRangeLo[ucLoopIndex], - pstClassifierRule->usDestPortRangeHi[ucLoopIndex]); - - if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] && - ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex]) - return TRUE; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Dest Port: %x Not Matched", - ushDestPort); - return false; -} -/** - * @ingroup tx_functions - * Compares IPV4 Ip address and port number - * @return Queue Index. -*/ -static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, - struct iphdr *iphd, - struct bcm_classifier_rule *pstClassifierRule) -{ - struct bcm_transport_header *xprt_hdr = NULL; - bool bClassificationSucceed = false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "========>"); - - xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr)); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Trying to see Direction = %d %d", - pstClassifierRule->ucDirection, - pstClassifierRule->usVCID_Value); - - /* Checking classifier validity */ - if (!pstClassifierRule->bUsed || - pstClassifierRule->ucDirection == DOWNLINK_DIR) - goto out; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "is IPv6 check!"); - if (pstClassifierRule->bIpv6Protocol) - goto out; - - /* Checking IP header parameter */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Trying to match Source IP Address"); - if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Source IP Address Matched"); - - if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination IP Address Matched"); - - if (!MatchTos(pstClassifierRule, iphd->tos)) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "TOS Match failed\n"); - goto out; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "TOS Matched"); - - if (!MatchProtocol(pstClassifierRule, iphd->protocol)) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Protocol Matched"); - - /* - * if protocol is not TCP or UDP then no - * need of comparing source port and destination port - */ - if (iphd->protocol != TCP && iphd->protocol != UDP) { - bClassificationSucceed = TRUE; - goto out; - } - /* Checking Transport Layer Header field if present */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Source Port %04x", - (iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source); - - if (!MatchSrcPort(pstClassifierRule, - ntohs((iphd->protocol == UDP) ? - xprt_hdr->uhdr.source : xprt_hdr->thdr.source))) - goto out; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Src Port Matched"); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Destination Port %04x", - (iphd->protocol == UDP) ? xprt_hdr->uhdr.dest : - xprt_hdr->thdr.dest); - - if (!MatchDestPort(pstClassifierRule, - ntohs((iphd->protocol == UDP) ? - xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest))) - goto out; - bClassificationSucceed = TRUE; - -out: - if (TRUE == bClassificationSucceed) { - INT iMatchedSFQueueIndex = 0; - - iMatchedSFQueueIndex = - SearchSfid(Adapter, pstClassifierRule->ulSFID); - if (iMatchedSFQueueIndex >= NO_OF_QUEUES) - bClassificationSucceed = false; - else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) - bClassificationSucceed = false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "IpVersion4 <=========="); - - return bClassificationSucceed; -} - -VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter) -{ - UINT iIndex = 0; - - for (iIndex = 0; iIndex < HiPriority; iIndex++) { - if (!Adapter->PackInfo[iIndex].bValid) - continue; - - PruneQueue(Adapter, iIndex); - } -} - - -/** - * @ingroup tx_functions - * This function checks if the max queue size for a queue - * is less than number of bytes in the queue. If so - - * drops packets from the Head till the number of bytes is - * less than or equal to max queue size for the queue. - */ -static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex) -{ - struct sk_buff *PacketToDrop = NULL; - struct net_device_stats *netstats; - struct bcm_packet_info *curr_pack_info = &Adapter->PackInfo[iIndex]; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "=====> Index %d", - iIndex); - - if (iIndex == HiPriority) - return; - - if (!Adapter || (iIndex < 0) || (iIndex > HiPriority)) - return; - - /* To Store the netdevice statistic */ - netstats = &Adapter->dev->stats; - - spin_lock_bh(&curr_pack_info->SFQueueLock); - - while (1) { -/* while((UINT)curr_pack_info->uiCurrentPacketsOnHost > - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */ - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x", - curr_pack_info->uiCurrentBytesOnHost, - curr_pack_info->uiMaxBucketSize); - - PacketToDrop = curr_pack_info->FirstTxQueue; - - if (PacketToDrop == NULL) - break; - if ((curr_pack_info->uiCurrentPacketsOnHost < - SF_MAX_ALLOWED_PACKETS_TO_BACKUP) && - ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb) + - SKB_CB_LATENCY_OFFSET))/HZ) <= - curr_pack_info->uiMaxLatency)) - break; - - if (PacketToDrop) { - if (netif_msg_tx_err(Adapter)) - pr_info(PFX "%s: tx queue %d overlimit\n", - Adapter->dev->name, iIndex); - - netstats->tx_dropped++; - - DEQUEUEPACKET(curr_pack_info->FirstTxQueue, - curr_pack_info->LastTxQueue); - /* update current bytes and packets count */ - curr_pack_info->uiCurrentBytesOnHost -= - PacketToDrop->len; - curr_pack_info->uiCurrentPacketsOnHost--; - /* update dropped bytes and packets counts */ - curr_pack_info->uiDroppedCountBytes += PacketToDrop->len; - curr_pack_info->uiDroppedCountPackets++; - dev_kfree_skb(PacketToDrop); - - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "Dropped Bytes:%x Dropped Packets:%x", - curr_pack_info->uiDroppedCountBytes, - curr_pack_info->uiDroppedCountPackets); - - atomic_dec(&Adapter->TotalPacketCount); - } - - spin_unlock_bh(&curr_pack_info->SFQueueLock); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "TotalPacketCount:%x", - atomic_read(&Adapter->TotalPacketCount)); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - PRUNE_QUEUE, - DBG_LVL_ALL, - "<====="); -} - -VOID flush_all_queues(struct bcm_mini_adapter *Adapter) -{ - INT iQIndex; - UINT uiTotalPacketLength; - struct sk_buff *PacketToDrop = NULL; - struct bcm_packet_info *curr_packet_info; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "=====>"); - - /* down(&Adapter->data_packet_queue_lock); */ - for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) { - struct net_device_stats *netstats = &Adapter->dev->stats; - - curr_packet_info = &Adapter->PackInfo[iQIndex]; - - spin_lock_bh(&curr_packet_info->SFQueueLock); - while (curr_packet_info->FirstTxQueue) { - PacketToDrop = curr_packet_info->FirstTxQueue; - if (PacketToDrop) { - uiTotalPacketLength = PacketToDrop->len; - netstats->tx_dropped++; - } else - uiTotalPacketLength = 0; - - DEQUEUEPACKET(curr_packet_info->FirstTxQueue, - curr_packet_info->LastTxQueue); - - /* Free the skb */ - dev_kfree_skb(PacketToDrop); - - /* update current bytes and packets count */ - curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength; - curr_packet_info->uiCurrentPacketsOnHost--; - - /* update dropped bytes and packets counts */ - curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength; - curr_packet_info->uiDroppedCountPackets++; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "Dropped Bytes:%x Dropped Packets:%x", - curr_packet_info->uiDroppedCountBytes, - curr_packet_info->uiDroppedCountPackets); - atomic_dec(&Adapter->TotalPacketCount); - } - spin_unlock_bh(&curr_packet_info->SFQueueLock); - } - /* up(&Adapter->data_packet_queue_lock); */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_OTHERS, - DUMP_INFO, - DBG_LVL_ALL, - "<====="); -} - -USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb) -{ - INT uiLoopIndex = 0; - struct bcm_classifier_rule *pstClassifierRule = NULL; - struct bcm_eth_packet_info stEthCsPktInfo; - PVOID pvEThPayload = NULL; - struct iphdr *pIpHeader = NULL; - INT uiSfIndex = 0; - USHORT usIndex = Adapter->usBestEffortQueueIndex; - bool bFragmentedPkt = false, bClassificationSucceed = false; - USHORT usCurrFragment = 0; - - struct bcm_tcp_header *pTcpHeader; - UCHAR IpHeaderLength; - UCHAR TcpHeaderLength; - - pvEThPayload = skb->data; - *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0; - EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo); - - switch (stEthCsPktInfo.eNwpktEthFrameType) { - case eEth802LLCFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802LLCFrame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame); - break; - case eEth802LLCSNAPFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802LLC SNAP Frame\n"); - pIpHeader = pvEThPayload + - sizeof(struct bcm_eth_llc_snap_frame); - break; - case eEth802QVLANFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : 802.1Q VLANFrame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame); - break; - case eEthOtherFrame: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : ETH Other Frame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame); - break; - default: - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : Unrecognized ETH Frame\n"); - pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame); - break; - } - - if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) { - usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET); - if ((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment) - bFragmentedPkt = TRUE; - - if (bFragmentedPkt) { - /* Fragmented Packet. Get Frag Classifier Entry. */ - pstClassifierRule = GetFragIPClsEntry(Adapter, - pIpHeader->id, - pIpHeader->saddr); - if (pstClassifierRule) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "It is next Fragmented pkt"); - bClassificationSucceed = TRUE; - } - if (!(ntohs(pIpHeader->frag_off) & IP_MF)) { - /* Fragmented Last packet . Remove Frag Classifier Entry */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "This is the last fragmented Pkt"); - DelFragIPClsEntry(Adapter, - pIpHeader->id, - pIpHeader->saddr); - } - } - } - - for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) { - if (bClassificationSucceed) - break; - /* - * Iterate through all classifiers which are already in order of priority - * to classify the packet until match found - */ - if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) { - bClassificationSucceed = false; - continue; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Adapter->PackInfo[%d].bvalid=True\n", - uiLoopIndex); - - if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) { - bClassificationSucceed = false; /* cannot be processed for classification. */ - continue; /* it is a down link connection */ - } - - pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex]; - - uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); - if (uiSfIndex >= NO_OF_QUEUES) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Queue Not Valid. SearchSfid for this classifier Failed\n"); - continue; - } - - if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) { - - if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n"); - bClassificationSucceed = false; - continue; - } - - - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n", - pstClassifierRule->uiClassifierRuleIndex, - Adapter->PackInfo[uiSfIndex].ulSFID); - bClassificationSucceed = EThCSClassifyPkt(Adapter, - skb, - &stEthCsPktInfo, - pstClassifierRule, - Adapter->PackInfo[uiSfIndex].bEthCSSupport); - - if (!bClassificationSucceed) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ClassifyPacket : Ethernet CS Classification Failed\n"); - continue; - } - } else { /* No ETH Supported on this SF */ - if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n"); - bClassificationSucceed = false; - continue; - } - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Proceeding to IP CS Clasification"); - - if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) { - - if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - " ClassifyPacket : Packet is Not an IP Packet\n"); - bClassificationSucceed = false; - continue; - } - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "Dump IP Header :\n"); - DumpFullPacket((PUCHAR)pIpHeader, 20); - - if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) - bClassificationSucceed = IpVersion4(Adapter, - pIpHeader, - pstClassifierRule); - else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet) - bClassificationSucceed = IpVersion6(Adapter, - pIpHeader, - pstClassifierRule); - } - } - - if (bClassificationSucceed == TRUE) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "CF id : %d, SF ID is =%lu", - pstClassifierRule->uiClassifierRuleIndex, - pstClassifierRule->ulSFID); - - /* Store The matched Classifier in SKB */ - *((UINT32 *)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = - pstClassifierRule->uiClassifierRuleIndex; - if ((TCP == pIpHeader->protocol) && !bFragmentedPkt && - (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= - skb->len)) { - IpHeaderLength = pIpHeader->ihl; - pTcpHeader = - (struct bcm_tcp_header *)(((PUCHAR)pIpHeader) + - (IpHeaderLength*4)); - TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength); - - if ((pTcpHeader->ucFlags & TCP_ACK) && - (ntohs(pIpHeader->tot_len) == - (IpHeaderLength*4)+(TcpHeaderLength*4))) - *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = - TCP_ACK; - } - - usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "index is =%d", - usIndex); - - /* - * If this is the first fragment of a Fragmented pkt, - * add this CF. Only This CF should be used for all other - * fragment of this Pkt. - */ - if (bFragmentedPkt && (usCurrFragment == 0)) { - /* - * First Fragment of Fragmented Packet. - * Create Frag CLS Entry - */ - struct bcm_fragmented_packet_info stFragPktInfo; - - stFragPktInfo.bUsed = TRUE; - stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr; - stFragPktInfo.usIpIdentification = pIpHeader->id; - stFragPktInfo.pstMatchedClassifierEntry = - pstClassifierRule; - stFragPktInfo.bOutOfOrderFragment = false; - AddFragIPClsEntry(Adapter, &stFragPktInfo); - } - - - } - - return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX; -} - -static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule, - PUCHAR Mac) -{ - UINT i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (pstClassifierRule->ucEthCSSrcMACLen == 0) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s\n", __func__); - for (i = 0; i < MAC_ADDRESS_SIZE; i++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", - i, - Mac[i], - pstClassifierRule->au8EThCSSrcMAC[i], - pstClassifierRule->au8EThCSSrcMACMask[i]); - if ((pstClassifierRule->au8EThCSSrcMAC[i] & - pstClassifierRule->au8EThCSSrcMACMask[i]) != - (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i])) - return false; - } - return TRUE; -} - -static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule, - PUCHAR Mac) -{ - UINT i = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if (pstClassifierRule->ucEthCSDestMACLen == 0) - return TRUE; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s\n", - __func__); - for (i = 0; i < MAC_ADDRESS_SIZE; i++) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", - i, - Mac[i], - pstClassifierRule->au8EThCSDestMAC[i], - pstClassifierRule->au8EThCSDestMACMask[i]); - if ((pstClassifierRule->au8EThCSDestMAC[i] & - pstClassifierRule->au8EThCSDestMACMask[i]) != - (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i])) - return false; - } - return TRUE; -} - -static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - if ((pstClassifierRule->ucEtherTypeLen == 0) || - (pstClassifierRule->au8EthCSEtherType[0] == 0)) - return TRUE; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s SrcEtherType:%x CLS EtherType[0]:%x\n", - __func__, - pstEthCsPktInfo->usEtherType, - pstClassifierRule->au8EthCSEtherType[0]); - if (pstClassifierRule->au8EthCSEtherType[0] == 1) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s CLS EtherType[1]:%x EtherType[2]:%x\n", - __func__, - pstClassifierRule->au8EthCSEtherType[1], - pstClassifierRule->au8EthCSEtherType[2]); - - if (memcmp(&pstEthCsPktInfo->usEtherType, - &pstClassifierRule->au8EthCSEtherType[1], - 2) == 0) - return TRUE; - else - return false; - } - - if (pstClassifierRule->au8EthCSEtherType[0] == 2) { - if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType) - return false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s EthCS DSAP:%x EtherType[2]:%x\n", - __func__, - pstEthCsPktInfo->ucDSAP, - pstClassifierRule->au8EthCSEtherType[2]); - if (pstEthCsPktInfo->ucDSAP == - pstClassifierRule->au8EthCSEtherType[2]) - return TRUE; - return false; - - } - - return false; - -} - -static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - bool bClassificationSucceed = false; - USHORT usVLANID; - B_UINT8 uPriority = 0; - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s CLS UserPrio:%x CLS VLANID:%x\n", - __func__, - ntohs(*((USHORT *)pstClassifierRule->usUserPriority)), - pstClassifierRule->usVLANID); - - /* - * In case FW didn't receive the TLV, - * the priority field should be ignored - */ - if (pstClassifierRule->usValidityBitMap & - (1<eNwpktEthFrameType != eEth802QVLANFrame) - return false; - - uPriority = (ntohs(*(USHORT *)(skb->data + - sizeof(struct bcm_eth_header))) & - 0xF000) >> 13; - - if ((uPriority >= pstClassifierRule->usUserPriority[0]) && - (uPriority <= - pstClassifierRule->usUserPriority[1])) - bClassificationSucceed = TRUE; - - if (!bClassificationSucceed) - return false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 D User Priority Rule Matched\n"); - - bClassificationSucceed = false; - - if (pstClassifierRule->usValidityBitMap & - (1<eNwpktEthFrameType != eEth802QVLANFrame) - return false; - - usVLANID = ntohs(*(USHORT *)(skb->data + - sizeof(struct bcm_eth_header))) & 0xFFF; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "%s Pkt VLANID %x Priority: %d\n", - __func__, - usVLANID, - uPriority); - - if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4)) - bClassificationSucceed = TRUE; - - if (!bClassificationSucceed) - return false; - } - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 Q VLAN ID Rule Matched\n"); - - return TRUE; -} - - -static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, - struct sk_buff *skb, - struct bcm_eth_packet_info *pstEthCsPktInfo, - struct bcm_classifier_rule *pstClassifierRule, - B_UINT8 EthCSCupport) -{ - bool bClassificationSucceed = false; - - bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule, - ((struct bcm_eth_header *)(skb->data))->au8SourceAddress); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS SrcMAC Matched\n"); - - bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule, - ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS DestMAC Matched\n"); - - /* classify on ETHType/802.2SAP TLV */ - bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule, - skb, - pstEthCsPktInfo); - if (!bClassificationSucceed) - return false; - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS EthType/802.2SAP Matched\n"); - - /* classify on 802.1VLAN Header Parameters */ - bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule, - skb, - pstEthCsPktInfo); - if (!bClassificationSucceed) - return false; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "ETH CS 802.1 VLAN Rules Matched\n"); - - return bClassificationSucceed; -} - -static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, - PVOID pvEthPayload, - struct bcm_eth_packet_info *pstEthCsPktInfo) -{ - USHORT u16Etype = ntohs( - ((struct bcm_eth_header *)pvEthPayload)->u16Etype); - - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCSGetPktInfo : Eth Hdr Type : %X\n", - u16Etype); - if (u16Etype > 0x5dc) { - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCSGetPktInfo : ETH2 Frame\n"); - /* ETH2 Frame */ - if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) { - /* 802.1Q VLAN Header */ - pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame; - u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType; - /* ((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority */ - } else { - pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame; - u16Etype = ntohs(u16Etype); - } - } else { - /* 802.2 LLC */ - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "802.2 LLC Frame\n"); - pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame; - pstEthCsPktInfo->ucDSAP = - ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP; - if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) { - /* SNAP Frame */ - pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame; - u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType; - } - } - if (u16Etype == ETHERNET_FRAMETYPE_IPV4) - pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet; - else if (u16Etype == ETHERNET_FRAMETYPE_IPV6) - pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet; - else - pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket; - - pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype; - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->eNwpktIPFrameType : %x\n", - pstEthCsPktInfo->eNwpktIPFrameType); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->eNwpktEthFrameType : %x\n", - pstEthCsPktInfo->eNwpktEthFrameType); - BCM_DEBUG_PRINT(Adapter, - DBG_TYPE_TX, - IPV4_DBG, - DBG_LVL_ALL, - "EthCsPktInfo->usEtherType : %x\n", - pstEthCsPktInfo->usEtherType); -} - diff --git a/drivers/staging/bcm/Queue.h b/drivers/staging/bcm/Queue.h deleted file mode 100644 index 460c0aee67f6..000000000000 --- a/drivers/staging/bcm/Queue.h +++ /dev/null @@ -1,29 +0,0 @@ -/************************************* -* Queue.h -**************************************/ -#ifndef __QUEUE_H__ -#define __QUEUE_H__ - - - -#define ENQUEUEPACKET(_Head, _Tail, _Packet) \ -do { \ - if (!_Head) { \ - _Head = _Packet; \ - } \ - else { \ - (_Tail)->next = _Packet; \ - } \ - (_Packet)->next = NULL; \ - _Tail = _Packet; \ -} while (0) -#define DEQUEUEPACKET(Head, Tail) \ -do { \ - if (Head) { \ - if (!Head->next) { \ - Tail = NULL; \ - } \ - Head = Head->next; \ - } \ -} while (0) -#endif /* __QUEUE_H__ */ diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO deleted file mode 100644 index 8467f45d08a6..000000000000 --- a/drivers/staging/bcm/TODO +++ /dev/null @@ -1,26 +0,0 @@ -This driver is barely functional in its current state. - -Kevin McKinney(klmckinney1@gmail.com) and Matthias Beyer(mail@beyermatthias.de) -are currently maintaining/cleaning up this driver. Please copy us on all -patches. More maintainers are aways welcomed. - -BIG: - - existing API is (/dev/tarang) should be replaced - Is it possible to use same API as Intel Wimax stack and - have same user level components. - - Qos and queue model is non-standard and inflexible. - Use existing TC Qos? - -TODO: - - support more than one board - eliminate global variables - - remove developer debug BCM_DEBUG() macros - add a limited number of messages through netif_msg() - - fix non-standard kernel style - - checkpatch warnings - - use request firmware - - fix use of file I/O to load config with better API - - merge some files together? - - cleanup/eliminate debug messages - - - diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c deleted file mode 100644 index 622a482e9826..000000000000 --- a/drivers/staging/bcm/Transmit.c +++ /dev/null @@ -1,271 +0,0 @@ -/** - * @file Transmit.c - * @defgroup tx_functions Transmission - * @section Queueing - * @dot - * digraph transmit1 { - * node[shape=box] - * edge[weight=5;color=red] - * - * bcm_transmit->GetPacketQueueIndex[label="IP Packet"] - * GetPacketQueueIndex->IpVersion4[label="IPV4"] - * GetPacketQueueIndex->IpVersion6[label="IPV6"] - * } - * - * @enddot - * - * @section De-Queueing - * @dot - * digraph transmit2 { - * node[shape=box] - * edge[weight=5;color=red] - * interrupt_service_thread->transmit_packets - * tx_pkt_hdler->transmit_packets - * transmit_packets->CheckAndSendPacketFromIndex - * transmit_packets->UpdateTokenCount - * CheckAndSendPacketFromIndex->PruneQueue - * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow - * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] - * SendControlPacket->bcm_cmd53 - * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] - * SendPacketFromQueue->SetupNextSend->bcm_cmd53 - * } - * @enddot - */ - -#include "headers.h" - -/** - * @ingroup ctrl_pkt_functions - * This function dispatches control packet to the h/w interface - * @return zero(success) or -ve value(failure) - */ -int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) -{ - struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); - if (!pControlPacket || !Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Got NULL Control Packet or Adapter"); - return STATUS_FAILURE; - } - if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < - ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); - return STATUS_FAILURE; - } - - /* Update the netdevice statistics */ - /* Dump Packet */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader Status: %x", PLeader->Status); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader VCID: %x", PLeader->Vcid); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "Leader Length: %x", PLeader->PLength); - if (Adapter->device_removed) - return 0; - - if (netif_msg_pktdata(Adapter)) - print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, - 16, 1, pControlPacket, - PLeader->PLength + LEADER_SIZE, 0); - - Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - pControlPacket, - (PLeader->PLength + LEADER_SIZE)); - - atomic_dec(&Adapter->CurrNumFreeTxDesc); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, - "<========="); - return STATUS_SUCCESS; -} - -/** - * @ingroup tx_functions - * This function despatches the IP packets with the given vcid - * to the target via the host h/w interface. - * @return zero(success) or -ve value(failure) - */ -int SetupNextSend(struct bcm_mini_adapter *Adapter, - struct sk_buff *Packet, USHORT Vcid) -{ - int status = 0; - bool bHeaderSupressionEnabled = false; - B_UINT16 uiClassifierRuleID; - u16 QueueIndex = skb_get_queue_mapping(Packet); - struct bcm_packet_info *curr_packet_info = - &Adapter->PackInfo[QueueIndex]; - struct bcm_leader Leader = {0}; - - if (Packet->len > MAX_DEVICE_DESC_SIZE) { - status = STATUS_FAILURE; - goto errExit; - } - - /* Get the Classifier Rule ID */ - uiClassifierRuleID = *((UINT32 *) (Packet->cb) + - SKB_CB_CLASSIFICATION_OFFSET); - - bHeaderSupressionEnabled = curr_packet_info->bHeaderSuppressionEnabled & - Adapter->bPHSEnabled; - - if (Adapter->device_removed) { - status = STATUS_FAILURE; - goto errExit; - } - - status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, - bHeaderSupressionEnabled, - (UINT *)&Packet->len, - curr_packet_info->bEthCSSupport); - - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "PHS Transmit failed..\n"); - goto errExit; - } - - Leader.Vcid = Vcid; - - if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET)) - Leader.Status = LEADER_STATUS_TCP_ACK; - else - Leader.Status = LEADER_STATUS; - - if (curr_packet_info->bEthCSSupport) { - Leader.PLength = Packet->len; - if (skb_headroom(Packet) < LEADER_SIZE) { - status = skb_cow(Packet, LEADER_SIZE); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, - DBG_LVL_ALL, - "bcm_transmit : Failed To Increase headRoom\n"); - goto errExit; - } - } - skb_push(Packet, LEADER_SIZE); - memcpy(Packet->data, &Leader, LEADER_SIZE); - } else { - Leader.PLength = Packet->len - ETH_HLEN; - memcpy((struct bcm_leader *)skb_pull(Packet, - (ETH_HLEN - LEADER_SIZE)), - &Leader, - LEADER_SIZE); - } - - status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, - Packet->data, - (Leader.PLength + LEADER_SIZE)); - if (status) { - ++Adapter->dev->stats.tx_errors; - if (netif_msg_tx_err(Adapter)) - pr_info(PFX "%s: transmit error %d\n", - Adapter->dev->name, - status); - } else { - struct net_device_stats *netstats = &Adapter->dev->stats; - - curr_packet_info->uiTotalTxBytes += Leader.PLength; - - netstats->tx_bytes += Leader.PLength; - ++netstats->tx_packets; - - curr_packet_info->uiCurrentTokenCount -= Leader.PLength << 3; - curr_packet_info->uiSentBytes += (Packet->len); - curr_packet_info->uiSentPackets++; - curr_packet_info->NumOfPacketsSent++; - - atomic_dec(&curr_packet_info->uiPerSFTxResourceCount); - curr_packet_info->uiThisPeriodSentBytes += Leader.PLength; - } - - atomic_dec(&Adapter->CurrNumFreeTxDesc); - -errExit: - dev_kfree_skb(Packet); - return status; -} - -static int tx_pending(struct bcm_mini_adapter *Adapter) -{ - return (atomic_read(&Adapter->TxPktAvail) - && MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) - || Adapter->device_removed || (1 == Adapter->downloadDDR); -} - -/** - * @ingroup tx_functions - * Transmit thread - */ -int tx_pkt_handler(struct bcm_mini_adapter *Adapter) -{ - int status = 0; - - while (!kthread_should_stop()) { - /* FIXME - the timeout looks like workaround - * for racey usage of TxPktAvail - */ - if (Adapter->LinkUpStatus) - wait_event_timeout(Adapter->tx_packet_wait_queue, - tx_pending(Adapter), - msecs_to_jiffies(10)); - else - wait_event_interruptible(Adapter->tx_packet_wait_queue, - tx_pending(Adapter)); - - if (Adapter->device_removed) - break; - - if (Adapter->downloadDDR == 1) { - Adapter->downloadDDR += 1; - status = download_ddr_settings(Adapter); - if (status) - pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); - continue; - } - - /* Check end point for halt/stall. */ - if (Adapter->bEndPointHalted == TRUE) { - Bcm_clear_halt_of_endpoints(Adapter); - Adapter->bEndPointHalted = false; - StartInterruptUrb((struct bcm_interface_adapter *) - (Adapter->pvInterfaceAdapter)); - } - - if (Adapter->LinkUpStatus && !Adapter->IdleMode) { - if (atomic_read(&Adapter->TotalPacketCount)) - update_per_sf_desc_cnts(Adapter); - } - - if (atomic_read(&Adapter->CurrNumFreeTxDesc) && - Adapter->LinkStatus == SYNC_UP_REQUEST && - !Adapter->bSyncUpRequestSent) { - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, - DBG_LVL_ALL, "Calling LinkMessage"); - LinkMessage(Adapter); - } - - if ((Adapter->IdleMode || Adapter->bShutStatus) && - atomic_read(&Adapter->TotalPacketCount)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, - TX_PACKETS, DBG_LVL_ALL, - "Device in Low Power mode...waking up"); - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - } - - transmit_packets(Adapter); - atomic_set(&Adapter->TxPktAvail, 0); - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, - "Exiting the tx thread..\n"); - Adapter->transmit_packet_thread = NULL; - return 0; -} diff --git a/drivers/staging/bcm/Typedefs.h b/drivers/staging/bcm/Typedefs.h deleted file mode 100644 index 90b3b25dd606..000000000000 --- a/drivers/staging/bcm/Typedefs.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************** -* Typedefs.h -****************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ -#define STATUS_SUCCESS 0 -#define STATUS_FAILURE -1 - - -#define TRUE 1 - - -typedef char CHAR; -typedef int INT; -typedef short SHORT; -typedef long LONG; -typedef void VOID; - -typedef unsigned char UCHAR; -typedef unsigned char B_UINT8; -typedef unsigned short USHORT; -typedef unsigned short B_UINT16; -typedef unsigned int UINT; -typedef unsigned int B_UINT32; -typedef unsigned long ULONG; -typedef unsigned long DWORD; - -typedef char *PCHAR; -typedef short *PSHORT; -typedef int *PINT; -typedef long *PLONG; -typedef void *PVOID; - -typedef unsigned char *PUCHAR; -typedef unsigned short *PUSHORT; -typedef unsigned int *PUINT; -typedef unsigned long *PULONG; -typedef unsigned long long ULONG64; -typedef unsigned long long LARGE_INTEGER; -typedef unsigned int UINT32; -#ifndef NULL -#define NULL 0 -#endif - - -#endif /* __TYPEDEFS_H__ */ - diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h deleted file mode 100644 index 8683c2d4276e..000000000000 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ /dev/null @@ -1,311 +0,0 @@ -#ifndef CNTRL_SIGNALING_INTERFACE_ -#define CNTRL_SIGNALING_INTERFACE_ - -#define DSA_REQ 11 -#define DSA_RSP 12 -#define DSA_ACK 13 -#define DSC_REQ 14 -#define DSC_RSP 15 -#define DSC_ACK 16 -#define DSD_REQ 17 -#define DSD_RSP 18 -#define DSD_ACK 19 -#define MAX_CLASSIFIERS_IN_SF 4 - -#define MAX_STRING_LEN 20 -#define MAX_PHS_LENGTHS 255 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MAX_NUM_ACTIVE_BS 10 -#define AUTH_TOKEN_LENGTH 10 -#define NUM_HARQ_CHANNELS 16 /* Changed from 10 to 16 to accommodate all HARQ channels */ -#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 /* Changed the size to 1 byte since we dnt use it */ -#define VENDOR_SPECIF_QOS_PARAM 1 -#define VENDOR_PHS_PARAM_LENGTH 10 -#define MBS_CONTENTS_ID_LENGTH 10 -#define GLOBAL_SF_CLASSNAME_LENGTH 6 - -#define TYPE_OF_SERVICE_LENGTH 3 -#define IP_MASKED_SRC_ADDRESS_LENGTH 32 -#define IP_MASKED_DEST_ADDRESS_LENGTH 32 -#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4 -#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4 -#define ETHERNET_DEST_MAC_ADDR_LENGTH 12 -#define ETHERNET_SRC_MAC_ADDR_LENGTH 12 -#define NUM_ETHERTYPE_BYTES 3 -#define NUM_IPV6_FLOWLABLE_BYTES 3 - -struct bcm_packet_class_rules { - /* 16bit UserPriority Of The Service Flow */ - u16 u16UserPriority; - /* 16bit VLANID Of The Service Flow */ - u16 u16VLANID; - /* 16bit Packet Classification RuleIndex Of The Service Flow */ - u16 u16PacketClassificationRuleIndex; - /* 8bit Classifier Rule Priority Of The Service Flow */ - u8 u8ClassifierRulePriority; - /* Length of IP TypeOfService field */ - u8 u8IPTypeOfServiceLength; - /* 3bytes IP TypeOfService */ - u8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; - /* Protocol used in classification of Service Flow */ - u8 u8Protocol; - /* Length of IP Masked Source Address */ - u8 u8IPMaskedSourceAddressLength; - /* IP Masked Source Address used in classification for the Service Flow */ - u8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; - /* Length of IP Destination Address */ - u8 u8IPDestinationAddressLength; - /* IP Destination Address used in classification for the Service Flow */ - u8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; - /* Length of Protocol Source Port Range */ - u8 u8ProtocolSourcePortRangeLength; - /* Protocol Source Port Range used in the Service Flow */ - u8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; - /* Length of Protocol Dest Port Range */ - u8 u8ProtocolDestPortRangeLength; - /* Protocol Dest Port Range used in the Service Flow */ - u8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; - /* Length of Ethernet Destination MAC Address */ - u8 u8EthernetDestMacAddressLength; - /* Ethernet Destination MAC Address used in classification of the Service Flow */ - u8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; - /* Length of Ethernet Source MAC Address */ - u8 u8EthernetSourceMACAddressLength; - /* Ethernet Source MAC Address used in classification of the Service Flow */ - u8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; - /* Length of Ethertype */ - u8 u8EthertypeLength; - /* 3bytes Ethertype Of The Service Flow */ - u8 u8Ethertype[NUM_ETHERTYPE_BYTES]; - /* 8bit Associated PHSI Of The Service Flow */ - u8 u8AssociatedPHSI; - /* Length of Vendor Specific Classifier Param length Of The Service Flow */ - u8 u8VendorSpecificClassifierParamLength; - /* Vendor Specific Classifier Param Of The Service Flow */ - u8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; - /* Length Of IPv6 Flow Lable of the Service Flow */ - u8 u8IPv6FlowLableLength; - /* IPv6 Flow Lable Of The Service Flow */ - u8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; - /* Action associated with the classifier rule */ - u8 u8ClassifierActionRule; - u16 u16ValidityBitMap; -}; - -struct bcm_phs_rules { - /* 8bit PHS Index Of The Service Flow */ - u8 u8PHSI; - /* PHSF Length Of The Service Flow */ - u8 u8PHSFLength; - /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */ - u8 u8PHSF[MAX_PHS_LENGTHS]; - /* PHSM Length Of The Service Flow */ - u8 u8PHSMLength; - /* PHS Mask for the SF */ - u8 u8PHSM[MAX_PHS_LENGTHS]; - /* 8bit Total number of bytes to be suppressed for the Service Flow */ - u8 u8PHSS; - /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ - u8 u8PHSV; - /* Vendor Specific PHS param Length Of The Service Flow */ - u8 u8VendorSpecificPHSParamsLength; - /* Vendor Specific PHS param Of The Service Flow */ - u8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; - u8 u8Padding[2]; -}; - -struct bcm_convergence_types { - /* 8bit Phs Classfier Action Of The Service Flow */ - u8 u8ClassfierDSCAction; - /* 8bit Phs DSC Action Of The Service Flow */ - u8 u8PhsDSCAction; - /* 16bit Padding */ - u8 u8Padding[2]; - /* Packet classification rules structure */ - struct bcm_packet_class_rules cCPacketClassificationRule; - /* Payload header suppression rules structure */ - struct bcm_phs_rules cPhsRule; -}; - -struct bcm_connect_mgr_params { - /* 32bitSFID Of The Service Flow */ - u32 u32SFID; - /* 32bit Maximum Sustained Traffic Rate of the Service Flow */ - u32 u32MaxSustainedTrafficRate; - /* 32bit Maximum Traffic Burst allowed for the Service Flow */ - u32 u32MaxTrafficBurst; - /* 32bit Minimum Reserved Traffic Rate of the Service Flow */ - u32 u32MinReservedTrafficRate; - /* 32bit Tolerated Jitter of the Service Flow */ - u32 u32ToleratedJitter; - /* 32bit Maximum Latency of the Service Flow */ - u32 u32MaximumLatency; - /* 16bitCID Of The Service Flow */ - u16 u16CID; - /* 16bit SAID on which the service flow being set up shall be mapped */ - u16 u16TargetSAID; - /* 16bit ARQ window size negotiated */ - u16 u16ARQWindowSize; - /* 16bit Total Tx delay incl sending, receiving & processing delays */ - u16 u16ARQRetryTxTimeOut; - /* 16bit Total Rx delay incl sending, receiving & processing delays */ - u16 u16ARQRetryRxTimeOut; - /* 16bit ARQ block lifetime */ - u16 u16ARQBlockLifeTime; - /* 16bit ARQ Sync loss timeout */ - u16 u16ARQSyncLossTimeOut; - /* 16bit ARQ Purge timeout */ - u16 u16ARQRxPurgeTimeOut; - /* TODO::Remove this once we move to a new CORR2 driver - * brief Size of an ARQ block - */ - u16 u16ARQBlockSize; - /* #endif */ - /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */ - u16 u16SDUInterArrivalTime; - /* 16bit Specifies the time base for rate measurement */ - u16 u16TimeBase; - /* 16bit Interval b/w Successive Grant oppurtunities */ - u16 u16UnsolicitedGrantInterval; - /* 16bit Interval b/w Successive Polling grant oppurtunities */ - u16 u16UnsolicitedPollingInterval; - /* internal var to get the overhead */ - u16 u16MacOverhead; - /* MBS contents Identifier */ - u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; - /* MBS contents Identifier length */ - u8 u8MBSContentsIDLength; - /* ServiceClassName Length Of The Service Flow */ - u8 u8ServiceClassNameLength; - /* 32bytes ServiceClassName Of The Service Flow */ - u8 u8ServiceClassName[32]; - /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */ - u8 u8MBSService; - /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */ - u8 u8QosParamSet; - /* 8bit Traffic Priority Of the Service Flow */ - u8 u8TrafficPriority; - /* 8bit Uplink Grant Scheduling Type of The Service Flow */ - u8 u8ServiceFlowSchedulingType; - /* 8bit Request transmission Policy of the Service Flow */ - u8 u8RequesttransmissionPolicy; - /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ - u8 u8FixedLengthVSVariableLengthSDUIndicator; - /* 8bit Length of the SDU for a fixed length SDU service flow */ - u8 u8SDUSize; - /* 8bit Indicates whether or not ARQ is requested for this connection */ - u8 u8ARQEnable; - /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */ - u8 u8ARQDeliverInOrder; - /* 8bit Receiver ARQ ACK processing time */ - u8 u8RxARQAckProcessingTime; - /* 8bit Convergence Sublayer Specification Of The Service Flow */ - u8 u8CSSpecification; - /* 8 bit Type of data delivery service */ - u8 u8TypeOfDataDeliveryService; - /* 8bit Specifies whether a service flow may generate Paging */ - u8 u8PagingPreference; - /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ - u8 u8MBSZoneIdentifierassignment; - /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */ - u8 u8TrafficIndicationPreference; - /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ - u8 u8GlobalServicesClassNameLength; - /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ - u8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; - /* 8bit Indicates whether or not SN feedback is enabled for the conn */ - u8 u8SNFeedbackEnabled; - /* Indicates the size of the Fragment Sequence Number for the connection */ - u8 u8FSNSize; - /* 8bit Number of CIDs in active BS list */ - u8 u8CIDAllocation4activeBSsLength; - /* CIDs of BS in the active list */ - u8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; - /* Specifies if PDU extended subheader should be applied on every PDU on this conn */ - u8 u8PDUSNExtendedSubheader4HarqReordering; - /* 8bit Specifies whether the connection uses HARQ or not */ - u8 u8HARQServiceFlows; - /* Specifies the length of Authorization token */ - u8 u8AuthTokenLength; - /* Specifies the Authorization token */ - u8 u8AuthToken[AUTH_TOKEN_LENGTH]; - /* specifes Number of HARQ channels used to carry data length */ - u8 u8HarqChannelMappingLength; - /* specifes HARQ channels used to carry data */ - u8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; - /* 8bit Length of Vendor Specific QoS Params */ - u8 u8VendorSpecificQoSParamLength; - /* 1byte Vendor Specific QoS Param Of The Service Flow */ - u8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; - /* indicates total classifiers in the SF */ - u8 u8TotalClassifiers; /* < Total number of valid classifiers */ - u8 bValid; /* < Validity flag */ - u8 u8Padding; /* < Padding byte */ - /* - * Structure for Convergence SubLayer Types with a maximum of 4 classifiers - */ - struct bcm_convergence_types cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; -}; - -struct bcm_add_request { - u8 u8Type; /* < Type */ - u8 eConnectionDir; /* < Connection direction */ - /* brief 16 bit TID */ - u16 u16TID; /* < 16bit TID */ - /* brief 16bitCID */ - u16 u16CID; /* < 16bit CID */ - /* brief 16bitVCID */ - u16 u16VCID; /* < 16bit VCID */ - struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */ -}; - -struct bcm_add_indication { - u8 u8Type; /* < Type */ - u8 eConnectionDir; /* < Connection Direction */ - /* brief 16 bit TID */ - u16 u16TID; /* < TID */ - /* brief 16bitCID */ - u16 u16CID; /* < 16bitCID */ - /* brief 16bitVCID */ - u16 u16VCID; /* < 16bitVCID */ - struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */ - struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */ - struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */ - u8 u8CC; /* -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Typedefs.h" -#include "Macros.h" -#include "HostMIBSInterface.h" -#include "cntrl_SignalingInterface.h" -#include "PHSDefines.h" -#include "led_control.h" -#include "Ioctl.h" -#include "nvm.h" -#include "target_params.h" -#include "Adapter.h" -#include "CmHost.h" -#include "DDRInit.h" -#include "Debug.h" -#include "IPv6ProtocolHdr.h" -#include "PHSModule.h" -#include "Protocol.h" -#include "Prototypes.h" -#include "Queue.h" -#include "vendorspecificextn.h" - -#include "InterfaceMacros.h" -#include "InterfaceAdapter.h" -#include "InterfaceIsr.h" -#include "InterfaceMisc.h" -#include "InterfaceRx.h" -#include "InterfaceTx.h" -#include "InterfaceIdleMode.h" -#include "InterfaceInit.h" - -#define DRV_NAME "beceem" -#define DEV_NAME "tarang" -#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" -#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" -#define DRV_VERSION "5.2.45" -#define PFX DRV_NAME " " - -extern struct class *bcm_class; - -#endif diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c deleted file mode 100644 index f9b08a5d8ce8..000000000000 --- a/drivers/staging/bcm/hostmibs.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * File Name: hostmibs.c - * - * Author: Beceem Communications Pvt. Ltd - * - * Abstract: This file contains the routines to copy the statistics used by - * the driver to the Host MIBS structure and giving the same to Application. - */ - -#include "headers.h" - -INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, - struct bcm_host_stats_mibs *pstHostMibs) -{ - struct bcm_phs_entry *pstServiceFlowEntry = NULL; - struct bcm_phs_rule *pstPhsRule = NULL; - struct bcm_phs_classifier_table *pstClassifierTable = NULL; - struct bcm_phs_classifier_entry *pstClassifierRule = NULL; - struct bcm_phs_extension *pDeviceExtension = &Adapter->stBCMPhsContext; - struct bcm_mibs_host_info *host_info; - UINT nClassifierIndex = 0; - UINT nPhsTableIndex = 0; - UINT nSfIndex = 0; - UINT uiIndex = 0; - - if (pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, HOST_MIBS, - DBG_LVL_ALL, "Invalid Device Extension\n"); - return STATUS_FAILURE; - } - - /* Copy the classifier Table */ - for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; - nClassifierIndex++) { - if (Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE) - memcpy(&pstHostMibs->astClassifierTable[nClassifierIndex], - &Adapter->astClassifierTable[nClassifierIndex], - sizeof(struct bcm_mibs_classifier_rule)); - } - - /* Copy the SF Table */ - for (nSfIndex = 0; nSfIndex < NO_OF_QUEUES; nSfIndex++) { - if (Adapter->PackInfo[nSfIndex].bValid) { - memcpy(&pstHostMibs->astSFtable[nSfIndex], - &Adapter->PackInfo[nSfIndex], - sizeof(struct bcm_mibs_table)); - } else { - /* If index in not valid, - * don't process this for the PHS table. - * Go For the next entry. - */ - continue; - } - - /* Retrieve the SFID Entry Index for requested Service Flow */ - if (PHS_INVALID_TABLE_INDEX == - GetServiceFlowEntry(pDeviceExtension-> - pstServiceFlowPhsRulesTable, - Adapter->PackInfo[nSfIndex]. - usVCID_Value, &pstServiceFlowEntry)) - - continue; - - pstClassifierTable = pstServiceFlowEntry->pstClassifierTable; - - for (uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++) { - pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[uiIndex]; - - if (pstClassifierRule->bUsed) { - pstPhsRule = pstClassifierRule->pstPhsRule; - - pstHostMibs->astPhsRulesTable[nPhsTableIndex]. - ulSFID = Adapter->PackInfo[nSfIndex].ulSFID; - - memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI, - &pstPhsRule->u8PHSI, - sizeof(struct bcm_phs_rule)); - nPhsTableIndex++; - - } - - } - - } - - /* Copy other Host Statistics parameters */ - host_info = &pstHostMibs->stHostInfo; - host_info->GoodTransmits = Adapter->dev->stats.tx_packets; - host_info->GoodReceives = Adapter->dev->stats.rx_packets; - host_info->CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc); - host_info->BEBucketSize = Adapter->BEBucketSize; - host_info->rtPSBucketSize = Adapter->rtPSBucketSize; - host_info->TimerActive = Adapter->TimerActive; - host_info->u32TotalDSD = Adapter->u32TotalDSD; - - memcpy(host_info->aTxPktSizeHist, Adapter->aTxPktSizeHist, - sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES); - memcpy(host_info->aRxPktSizeHist, Adapter->aRxPktSizeHist, - sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES); - - return STATUS_SUCCESS; -} - -VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs, - struct bcm_tarang_data *pTarang) -{ - memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs), - &(pTarang->stDroppedAppCntrlMsgs), - sizeof(struct bcm_mibs_dropped_cntrl_msg)); -} - -VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, - struct bcm_connect_mgr_params *psfLocalSet, - UINT uiSearchRuleIndex) -{ - struct bcm_mibs_parameters *t = - &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable; - - t->wmanIfSfid = psfLocalSet->u32SFID; - t->wmanIfCmnCpsMaxSustainedRate = - psfLocalSet->u32MaxSustainedTrafficRate; - t->wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst; - t->wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate; - t->wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter; - t->wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency; - t->wmanIfCmnCpsFixedVsVariableSduInd = - psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator; - t->wmanIfCmnCpsFixedVsVariableSduInd = - ntohl(t->wmanIfCmnCpsFixedVsVariableSduInd); - t->wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize; - t->wmanIfCmnCpsSduSize = ntohl(t->wmanIfCmnCpsSduSize); - t->wmanIfCmnCpsSfSchedulingType = - psfLocalSet->u8ServiceFlowSchedulingType; - t->wmanIfCmnCpsSfSchedulingType = - ntohl(t->wmanIfCmnCpsSfSchedulingType); - t->wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable; - t->wmanIfCmnCpsArqEnable = ntohl(t->wmanIfCmnCpsArqEnable); - t->wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize); - t->wmanIfCmnCpsArqWindowSize = ntohl(t->wmanIfCmnCpsArqWindowSize); - t->wmanIfCmnCpsArqBlockLifetime = - ntohs(psfLocalSet->u16ARQBlockLifeTime); - t->wmanIfCmnCpsArqBlockLifetime = - ntohl(t->wmanIfCmnCpsArqBlockLifetime); - t->wmanIfCmnCpsArqSyncLossTimeout = - ntohs(psfLocalSet->u16ARQSyncLossTimeOut); - t->wmanIfCmnCpsArqSyncLossTimeout = - ntohl(t->wmanIfCmnCpsArqSyncLossTimeout); - t->wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder; - t->wmanIfCmnCpsArqDeliverInOrder = - ntohl(t->wmanIfCmnCpsArqDeliverInOrder); - t->wmanIfCmnCpsArqRxPurgeTimeout = - ntohs(psfLocalSet->u16ARQRxPurgeTimeOut); - t->wmanIfCmnCpsArqRxPurgeTimeout = - ntohl(t->wmanIfCmnCpsArqRxPurgeTimeout); - t->wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize); - t->wmanIfCmnCpsArqBlockSize = ntohl(t->wmanIfCmnCpsArqBlockSize); - t->wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy; - t->wmanIfCmnCpsReqTxPolicy = ntohl(t->wmanIfCmnCpsReqTxPolicy); - t->wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification; - t->wmanIfCmnSfCsSpecification = ntohl(t->wmanIfCmnSfCsSpecification); - t->wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID); - t->wmanIfCmnCpsTargetSaid = ntohl(t->wmanIfCmnCpsTargetSaid); - -} diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c deleted file mode 100644 index 181f17ff0a24..000000000000 --- a/drivers/staging/bcm/led_control.c +++ /dev/null @@ -1,951 +0,0 @@ -#include "headers.h" - -#define STATUS_IMAGE_CHECKSUM_MISMATCH -199 -#define EVENT_SIGNALED 1 - -static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size) -{ - B_UINT16 u16CheckSum = 0; - - while (u32Size--) { - u16CheckSum += (B_UINT8)~(*pu8Buffer); - pu8Buffer++; - } - return u16CheckSum; -} - -bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios) -{ - INT Status; - - Status = (Adapter->gpioBitMap & gpios) ^ gpios; - if (Status) - return false; - else - return TRUE; -} - -static INT LED_Blink(struct bcm_mini_adapter *Adapter, - UINT GPIO_Num, - UCHAR uiLedIndex, - ULONG timeout, - INT num_of_time, - enum bcm_led_events currdriverstate) -{ - int Status = STATUS_SUCCESS; - bool bInfinite = false; - - /* Check if num_of_time is -ve. If yes, blink led in infinite loop */ - if (num_of_time < 0) { - bInfinite = TRUE; - num_of_time = 1; - } - while (num_of_time) { - if (currdriverstate == Adapter->DriverState) - TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex); - - /* Wait for timeout after setting on the LED */ - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState || - kthread_should_stop(), - msecs_to_jiffies(timeout)); - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = EVENT_SIGNALED; - break; - } - if (Status) { - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = EVENT_SIGNALED; - break; - } - - TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex); - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState || - kthread_should_stop(), - msecs_to_jiffies(timeout)); - if (bInfinite == false) - num_of_time--; - } - return Status; -} - -static INT ScaleRateofTransfer(ULONG rate) -{ - if (rate <= 3) - return rate; - else if ((rate > 3) && (rate <= 100)) - return 5; - else if ((rate > 100) && (rate <= 200)) - return 6; - else if ((rate > 200) && (rate <= 300)) - return 7; - else if ((rate > 300) && (rate <= 400)) - return 8; - else if ((rate > 400) && (rate <= 500)) - return 9; - else if ((rate > 500) && (rate <= 600)) - return 10; - return MAX_NUM_OF_BLINKS; -} - -static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad, - INT *time, - INT *time_tx, - INT *time_rx, - UCHAR GPIO_Num_tx, - UCHAR uiTxLedIndex, - UCHAR GPIO_Num_rx, - UCHAR uiRxLedIndex, - enum bcm_led_events currdriverstate, - ulong *timeout) -{ - /* - * Assign minimum number of blinks of - * either Tx or Rx. - */ - *time = (*time_tx > *time_rx ? *time_rx : *time_tx); - - if (*time > 0) { - /* Blink both Tx and Rx LEDs */ - if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, - *time, currdriverstate) == EVENT_SIGNALED) || - (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout, - *time, currdriverstate) == EVENT_SIGNALED)) - return EVENT_SIGNALED; - } - - if (*time == *time_tx) { - /* Blink pending rate of Rx */ - if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout, - *time_rx - *time, - currdriverstate) == EVENT_SIGNALED) - return EVENT_SIGNALED; - - *time = *time_rx; - } else { - /* Blink pending rate of Tx */ - if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout, - *time_tx - *time, - currdriverstate) == EVENT_SIGNALED) - return EVENT_SIGNALED; - - *time = *time_tx; - } - - return 0; -} - -static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, - UCHAR GPIO_Num_tx, - UCHAR uiTxLedIndex, - UCHAR GPIO_Num_rx, - UCHAR uiRxLedIndex, - enum bcm_led_events currdriverstate) -{ - /* Initial values of TX and RX packets */ - ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0; - /* values of TX and RX packets after 1 sec */ - ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0; - /* Rate of transfer of Tx and Rx in 1 sec */ - ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0; - int Status = STATUS_SUCCESS; - INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0; - UINT remDelay = 0; - /* UINT GPIO_num = DISABLE_GPIO_NUM; */ - ulong timeout = 0; - - /* Read initial value of packets sent/received */ - Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets; - Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets; - - /* Scale the rate of transfer to no of blinks. */ - num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx); - num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx); - - while ((Adapter->device_removed == false)) { - timeout = 50; - - if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter, - &num_of_time, - &num_of_time_tx, - &num_of_time_rx, - GPIO_Num_tx, - uiTxLedIndex, - GPIO_Num_rx, - uiRxLedIndex, - currdriverstate, - &timeout)) - return EVENT_SIGNALED; - - - /* - * If Tx/Rx rate is less than maximum blinks per second, - * wait till delay completes to 1 second - */ - remDelay = MAX_NUM_OF_BLINKS - num_of_time; - if (remDelay > 0) { - timeout = 100 * remDelay; - Status = wait_event_interruptible_timeout( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState - || kthread_should_stop(), - msecs_to_jiffies(timeout)); - - if (kthread_should_stop()) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, - LED_DUMP_INFO, DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - return EVENT_SIGNALED; - } - if (Status) - return EVENT_SIGNALED; - } - - /* Turn off both Tx and Rx LEDs before next second */ - TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex); - TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex); - - /* - * Read the Tx & Rx packets transmission after 1 second and - * calculate rate of transfer - */ - Final_num_of_packts_tx = Adapter->dev->stats.tx_packets; - Final_num_of_packts_rx = Adapter->dev->stats.rx_packets; - - rate_of_transfer_tx = Final_num_of_packts_tx - - Initial_num_of_packts_tx; - rate_of_transfer_rx = Final_num_of_packts_rx - - Initial_num_of_packts_rx; - - /* Read initial value of packets sent/received */ - Initial_num_of_packts_tx = Final_num_of_packts_tx; - Initial_num_of_packts_rx = Final_num_of_packts_rx; - - /* Scale the rate of transfer to no of blinks. */ - num_of_time_tx = - ScaleRateofTransfer((ULONG)rate_of_transfer_tx); - num_of_time_rx = - ScaleRateofTransfer((ULONG)rate_of_transfer_rx); - - } - return Status; -} - -/* - * ----------------------------------------------------------------------------- - * Procedure: ValidateDSDParamsChecksum - * - * Description: Reads DSD Params and validates checkusm. - * - * Arguments: - * Adapter - Pointer to Adapter structure. - * ulParamOffset - Start offset of the DSD parameter to be read and - * validated. - * usParamLen - Length of the DSD Parameter. - * - * Returns: - * - * ----------------------------------------------------------------------------- - */ -static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, - ULONG ulParamOffset, - USHORT usParamLen) -{ - INT Status = STATUS_SUCCESS; - PUCHAR puBuffer = NULL; - USHORT usChksmOrg = 0; - USHORT usChecksumCalculated = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X", - ulParamOffset, usParamLen); - - puBuffer = kmalloc(usParamLen, GFP_KERNEL); - if (!puBuffer) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum Allocation failed"); - return -ENOMEM; - - } - - /* Read the DSD data from the parameter offset. */ - if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer, - ulParamOffset, usParamLen)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - - /* Calculate the checksum of the data read from the DSD parameter. */ - usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: usCheckSumCalculated = 0x%x\n", - usChecksumCalculated); - - /* - * End of the DSD parameter will have a TWO bytes checksum stored in it. - * Read it and compare with the calculated Checksum. - */ - if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg, - ulParamOffset+usParamLen, 2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - usChksmOrg = ntohs(usChksmOrg); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: usChksmOrg = 0x%x", usChksmOrg); - - /* - * Compare the checksum calculated with the checksum read - * from DSD section - */ - if (usChecksumCalculated ^ usChksmOrg) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: ValidateDSDParamsChecksum: Checksums don't match"); - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - goto exit; - } - -exit: - kfree(puBuffer); - return Status; -} - - -/* - * ----------------------------------------------------------------------------- - * Procedure: ValidateHWParmStructure - * - * Description: Validates HW Parameters. - * - * Arguments: - * Adapter - Pointer to Adapter structure. - * ulHwParamOffset - Start offset of the HW parameter Section to be read - * and validated. - * - * Returns: - * - * ----------------------------------------------------------------------------- - */ -static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, - ULONG ulHwParamOffset) -{ - - INT Status = STATUS_SUCCESS; - USHORT HwParamLen = 0; - /* - * Add DSD start offset to the hwParamOffset to get - * the actual address. - */ - ulHwParamOffset += DSD_START_OFFSET; - - /* Read the Length of HW_PARAM structure */ - BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2); - HwParamLen = ntohs(HwParamLen); - if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize) - return STATUS_IMAGE_CHECKSUM_MISMATCH; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread:HwParamLen = 0x%x", HwParamLen); - Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset, - HwParamLen); - return Status; -} /* ValidateHWParmStructure() */ - -static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter, - UCHAR GPIO_Array[]) -{ - int Status = STATUS_SUCCESS; - - ULONG dwReadValue = 0; - USHORT usHwParamData = 0; - USHORT usEEPROMVersion = 0; - UCHAR ucIndex = 0; - UCHAR ucGPIOInfo[32] = {0}; - - BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion, - EEPROM_VERSION_OFFSET, 2); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "usEEPROMVersion: Minor:0x%X Major:0x%x", - usEEPROMVersion & 0xFF, - ((usEEPROMVersion >> 8) & 0xFF)); - - - if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) { - BeceemNVMRead(Adapter, (PUINT)&usHwParamData, - EEPROM_HW_PARAM_POINTER_ADDRESS, 2); - usHwParamData = ntohs(usHwParamData); - dwReadValue = usHwParamData; - } else { - /* - * Validate Compatibility section and then read HW param - * if compatibility section is valid. - */ - Status = ValidateDSDParamsChecksum(Adapter, - DSD_START_OFFSET, - COMPATIBILITY_SECTION_LENGTH_MAP5); - - if (Status != STATUS_SUCCESS) - return Status; - - BeceemNVMRead(Adapter, (PUINT)&dwReadValue, - EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4); - dwReadValue = ntohl(dwReadValue); - } - - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: Start address of HW_PARAM structure = 0x%lx", - dwReadValue); - - /* - * Validate if the address read out is within the DSD. - * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit. - * lower limit should be above DSD_START_OFFSET and - * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET) - */ - if (dwReadValue < DSD_START_OFFSET || - dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET)) - return STATUS_IMAGE_CHECKSUM_MISMATCH; - - Status = ValidateHWParmStructure(Adapter, dwReadValue); - if (Status) - return Status; - - /* - * Add DSD_START_OFFSET to the offset read from the EEPROM. - * This will give the actual start HW Parameters start address. - * To read GPIO section, add GPIO offset further. - */ - - dwReadValue += DSD_START_OFFSET; - /* = start address of hw param section. */ - dwReadValue += GPIO_SECTION_START_OFFSET; - /* = GPIO start offset within HW Param section. */ - - /* - * Read the GPIO values for 32 GPIOs from EEPROM and map the function - * number to GPIO pin number to GPIO_Array - */ - BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32); - for (ucIndex = 0; ucIndex < 32; ucIndex++) { - - switch (ucGPIOInfo[ucIndex]) { - case RED_LED: - GPIO_Array[RED_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case BLUE_LED: - GPIO_Array[BLUE_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case YELLOW_LED: - GPIO_Array[YELLOW_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - case GREEN_LED: - GPIO_Array[GREEN_LED] = ucIndex; - Adapter->gpioBitMap |= (1 << ucIndex); - break; - default: - break; - } - - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "GPIO's bit map correspond to LED :0x%X", - Adapter->gpioBitMap); - return Status; -} - - -static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter, - bool *bEnableThread) -{ - int Status = STATUS_SUCCESS; - /* Array to store GPIO numbers from EEPROM */ - UCHAR GPIO_Array[NUM_OF_LEDS+1]; - UINT uiIndex = 0; - UINT uiNum_of_LED_Type = 0; - PUCHAR puCFGData = NULL; - UCHAR bData = 0; - struct bcm_led_state_info *curr_led_state; - - memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1); - - if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "Target Params not Avail.\n"); - return -ENOENT; - } - - /* Populate GPIO_Array with GPIO numbers for LED functions */ - /* Read the GPIO numbers from EEPROM */ - Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array); - if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) { - *bEnableThread = false; - return STATUS_SUCCESS; - } else if (Status) { - *bEnableThread = false; - return Status; - } - - /* - * CONFIG file read successfully. Deallocate the memory of - * uiFileNameBufferSize - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, - "LED Thread: Config file read successfully\n"); - puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1; - - /* - * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which - * will have the information of LED type, LED on state for different - * driver state and LED blink state. - */ - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - bData = *puCFGData; - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - /* - * Check Bit 8 for polarity. If it is set, - * polarity is reverse polarity - */ - if (bData & 0x80) { - curr_led_state->BitPolarity = 0; - /* unset the bit 8 */ - bData = bData & 0x7f; - } - - curr_led_state->LED_Type = bData; - if (bData <= NUM_OF_LEDS) - curr_led_state->GPIO_Num = GPIO_Array[bData]; - else - curr_led_state->GPIO_Num = DISABLE_GPIO_NUM; - - puCFGData++; - bData = *puCFGData; - curr_led_state->LED_On_State = bData; - puCFGData++; - bData = *puCFGData; - curr_led_state->LED_Blink_State = bData; - puCFGData++; - } - - /* - * Check if all the LED settings are disabled. If it is disabled, - * dont launch the LED control thread. - */ - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) || - (curr_led_state->LED_Type == 0x7f) || - (curr_led_state->LED_Type == 0)) - uiNum_of_LED_Type++; - } - if (uiNum_of_LED_Type >= NUM_OF_LEDS) - *bEnableThread = false; - - return Status; -} - -/* - * ----------------------------------------------------------------------------- - * Procedure: LedGpioInit - * - * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode - * and make the initial state to be OFF. - * - * Arguments: - * Adapter - Pointer to MINI_ADAPTER structure. - * - * Returns: VOID - * - * ----------------------------------------------------------------------------- - */ -static VOID LedGpioInit(struct bcm_mini_adapter *Adapter) -{ - UINT uiResetValue = 0; - UINT uiIndex = 0; - struct bcm_led_state_info *curr_led_state; - - /* Set all LED GPIO Mode to output mode */ - if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, - sizeof(uiResetValue)) < 0) - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "LED Thread: RDM Failed\n"); - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex]; - - if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM) - uiResetValue |= (1 << curr_led_state->GPIO_Num); - - TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex); - - } - if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, - sizeof(uiResetValue)) < 0) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "LED Thread: WRM Failed\n"); - - Adapter->LEDInfo.bIdle_led_off = false; -} - -static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, - UCHAR *GPIO_num_tx, - UCHAR *GPIO_num_rx, - UCHAR *uiLedTxIndex, - UCHAR *uiLedRxIndex, - enum bcm_led_events currdriverstate) -{ - UINT uiIndex = 0; - struct bcm_led_state_info *led_state_info; - - *GPIO_num_tx = DISABLE_GPIO_NUM; - *GPIO_num_rx = DISABLE_GPIO_NUM; - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - led_state_info = &Adapter->LEDInfo.LEDState[uiIndex]; - - if (((currdriverstate == NORMAL_OPERATION) || - (currdriverstate == IDLEMODE_EXIT) || - (currdriverstate == FW_DOWNLOAD)) && - (led_state_info->LED_Blink_State & currdriverstate) && - (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { - if (*GPIO_num_tx == DISABLE_GPIO_NUM) { - *GPIO_num_tx = led_state_info->GPIO_Num; - *uiLedTxIndex = uiIndex; - } else { - *GPIO_num_rx = led_state_info->GPIO_Num; - *uiLedRxIndex = uiIndex; - } - } else { - if ((led_state_info->LED_On_State & currdriverstate) && - (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) { - *GPIO_num_tx = led_state_info->GPIO_Num; - *uiLedTxIndex = uiIndex; - } - } - } - return STATUS_SUCCESS; -} - -static void handle_adapter_driver_state(struct bcm_mini_adapter *ad, - enum bcm_led_events currdriverstate, - UCHAR GPIO_num, - UCHAR dummyGPIONum, - UCHAR uiLedIndex, - UCHAR dummyIndex, - ulong timeout, - UINT uiResetValue, - UINT uiIndex) -{ - switch (ad->DriverState) { - case DRIVER_INIT: - currdriverstate = DRIVER_INIT; - /* ad->DriverState; */ - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, - currdriverstate); - - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - - break; - case FW_DOWNLOAD: - /* - * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, - * LED_DUMP_INFO, DBG_LVL_ALL, - * "LED Thread: FW_DN_DONE called\n"); - */ - currdriverstate = FW_DOWNLOAD; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, - currdriverstate); - - if (GPIO_num != DISABLE_GPIO_NUM) { - timeout = 50; - LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout, - -1, currdriverstate); - } - break; - case FW_DOWNLOAD_DONE: - currdriverstate = FW_DOWNLOAD_DONE; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyIndex, currdriverstate); - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - break; - - case SHUTDOWN_EXIT: - /* - * no break, continue to NO_NETWORK_ENTRY - * state as well. - */ - case NO_NETWORK_ENTRY: - currdriverstate = NO_NETWORK_ENTRY; - BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum, - &uiLedIndex, &dummyGPIONum, currdriverstate); - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex); - break; - case NORMAL_OPERATION: - { - UCHAR GPIO_num_tx = DISABLE_GPIO_NUM; - UCHAR GPIO_num_rx = DISABLE_GPIO_NUM; - UCHAR uiLEDTx = 0; - UCHAR uiLEDRx = 0; - - currdriverstate = NORMAL_OPERATION; - ad->LEDInfo.bIdle_led_off = false; - - BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx, - &uiLEDTx, &uiLEDRx, currdriverstate); - if ((GPIO_num_tx == DISABLE_GPIO_NUM) && - (GPIO_num_rx == DISABLE_GPIO_NUM)) { - GPIO_num = DISABLE_GPIO_NUM; - } else { - /* - * If single LED is selected, use same - * for both Tx and Rx - */ - if (GPIO_num_tx == DISABLE_GPIO_NUM) { - GPIO_num_tx = GPIO_num_rx; - uiLEDTx = uiLEDRx; - } else if (GPIO_num_rx == DISABLE_GPIO_NUM) { - GPIO_num_rx = GPIO_num_tx; - uiLEDRx = uiLEDTx; - } - /* - * Blink the LED in proportionate - * to Tx and Rx transmissions. - */ - LED_Proportional_Blink(ad, - GPIO_num_tx, uiLEDTx, - GPIO_num_rx, uiLEDRx, - currdriverstate); - } - } - break; - case LOWPOWER_MODE_ENTER: - currdriverstate = LOWPOWER_MODE_ENTER; - if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == - ad->ulPowerSaveMode) { - /* Turn OFF all the LED */ - uiResetValue = 0; - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - - } - /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */ - ad->LEDInfo.bLedInitDone = false; - ad->LEDInfo.bIdle_led_off = TRUE; - wake_up(&ad->LEDInfo.idleModeSyncEvent); - GPIO_num = DISABLE_GPIO_NUM; - break; - case IDLEMODE_CONTINUE: - currdriverstate = IDLEMODE_CONTINUE; - GPIO_num = DISABLE_GPIO_NUM; - break; - case IDLEMODE_EXIT: - break; - case DRIVER_HALT: - currdriverstate = DRIVER_HALT; - GPIO_num = DISABLE_GPIO_NUM; - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != - DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - /* ad->DriverState = DRIVER_INIT; */ - break; - case LED_THREAD_INACTIVE: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "InActivating LED thread..."); - currdriverstate = LED_THREAD_INACTIVE; - ad->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_INACTIVELY; - ad->LEDInfo.bLedInitDone = false; - /* disable ALL LED */ - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) { - if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != - DISABLE_GPIO_NUM) - TURN_OFF_LED(ad, - (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num), - uiIndex); - } - break; - case LED_THREAD_ACTIVE: - BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, "Activating LED thread again..."); - if (ad->LinkUpStatus == false) - ad->DriverState = NO_NETWORK_ENTRY; - else - ad->DriverState = NORMAL_OPERATION; - - ad->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_ACTIVELY; - break; - /* return; */ - default: - break; - } -} - -static VOID LEDControlThread(struct bcm_mini_adapter *Adapter) -{ - UINT uiIndex = 0; - UCHAR GPIO_num = 0; - UCHAR uiLedIndex = 0; - UINT uiResetValue = 0; - enum bcm_led_events currdriverstate = 0; - ulong timeout = 0; - - INT Status = 0; - - UCHAR dummyGPIONum = 0; - UCHAR dummyIndex = 0; - - /* currdriverstate = Adapter->DriverState; */ - Adapter->LEDInfo.bIdleMode_tx_from_host = false; - - /* - * Wait till event is triggered - * - * wait_event(Adapter->LEDInfo.notify_led_event, - * currdriverstate!= Adapter->DriverState); - */ - - GPIO_num = DISABLE_GPIO_NUM; - - while (TRUE) { - /* Wait till event is triggered */ - if ((GPIO_num == DISABLE_GPIO_NUM) - || - ((currdriverstate != FW_DOWNLOAD) && - (currdriverstate != NORMAL_OPERATION) && - (currdriverstate != LOWPOWER_MODE_ENTER)) - || - (currdriverstate == LED_THREAD_INACTIVE)) - Status = wait_event_interruptible( - Adapter->LEDInfo.notify_led_event, - currdriverstate != Adapter->DriverState - || kthread_should_stop()); - - if (kthread_should_stop() || Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); - return; /* STATUS_FAILURE; */ - } - - if (GPIO_num != DISABLE_GPIO_NUM) - TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex); - - if (Adapter->LEDInfo.bLedInitDone == false) { - LedGpioInit(Adapter); - Adapter->LEDInfo.bLedInitDone = TRUE; - } - - handle_adapter_driver_state(Adapter, - currdriverstate, - GPIO_num, - dummyGPIONum, - uiLedIndex, - dummyIndex, - timeout, - uiResetValue, - uiIndex - ); - } - Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED; -} - -int InitLedSettings(struct bcm_mini_adapter *Adapter) -{ - int Status = STATUS_SUCCESS; - bool bEnableThread = TRUE; - UCHAR uiIndex = 0; - - /* - * Initially set BitPolarity to normal polarity. The bit 8 of LED type - * is used to change the polarity of the LED. - */ - - for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) - Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1; - - /* - * Read the LED settings of CONFIG file and map it - * to GPIO numbers in EEPROM - */ - Status = ReadConfigFileStructure(Adapter, &bEnableThread); - if (STATUS_SUCCESS != Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "LED Thread: FAILED in ReadConfigFileStructure\n"); - return Status; - } - - if (Adapter->LEDInfo.led_thread_running) { - if (bEnableThread) { - ; - } else { - Adapter->DriverState = DRIVER_HALT; - wake_up(&Adapter->LEDInfo.notify_led_event); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - } - - } else if (bEnableThread) { - /* Create secondary thread to handle the LEDs */ - init_waitqueue_head(&Adapter->LEDInfo.notify_led_event); - init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_RUNNING_ACTIVELY; - Adapter->LEDInfo.bIdle_led_off = false; - Adapter->LEDInfo.led_cntrl_threadid = - kthread_run((int (*)(void *)) LEDControlThread, - Adapter, "led_control_thread"); - if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, - DBG_LVL_ALL, - "Not able to spawn Kernel Thread\n"); - Adapter->LEDInfo.led_thread_running = - BCM_LED_THREAD_DISABLED; - return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid); - } - } - return Status; -} diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h deleted file mode 100644 index 1b24bf4658af..000000000000 --- a/drivers/staging/bcm/led_control.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _LED_CONTROL_H -#define _LED_CONTROL_H - -#define NUM_OF_LEDS 4 -#define DSD_START_OFFSET 0x0200 -#define EEPROM_VERSION_OFFSET 0x020E -#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218 -#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220 -#define GPIO_SECTION_START_OFFSET 0x03 -#define COMPATIBILITY_SECTION_LENGTH 42 -#define COMPATIBILITY_SECTION_LENGTH_MAP5 84 -#define EEPROM_MAP5_MAJORVERSION 5 -#define EEPROM_MAP5_MINORVERSION 0 -#define MAX_NUM_OF_BLINKS 10 -#define NUM_OF_GPIO_PINS 16 -#define DISABLE_GPIO_NUM 0xFF -#define EVENT_SIGNALED 1 -#define MAX_FILE_NAME_BUFFER_SIZE 100 - -#define TURN_ON_LED(ad, GPIO, index) do { \ - unsigned int gpio_val = GPIO; \ - (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \ - } while (0) - -#define TURN_OFF_LED(ad, GPIO, index) do { \ - unsigned int gpio_val = GPIO; \ - (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \ - wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \ - } while (0) - -enum bcm_led_colors { - RED_LED = 1, - BLUE_LED = 2, - YELLOW_LED = 3, - GREEN_LED = 4 -}; - -enum bcm_led_events { - SHUTDOWN_EXIT = 0x00, - DRIVER_INIT = 0x1, - FW_DOWNLOAD = 0x2, - FW_DOWNLOAD_DONE = 0x4, - NO_NETWORK_ENTRY = 0x8, - NORMAL_OPERATION = 0x10, - LOWPOWER_MODE_ENTER = 0x20, - IDLEMODE_CONTINUE = 0x40, - IDLEMODE_EXIT = 0x80, - LED_THREAD_INACTIVE = 0x100, /* Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. */ - LED_THREAD_ACTIVE = 0x200, /* Makes the LED Thread Active back. */ - DRIVER_HALT = 0xff -}; /* Enumerated values of different driver states */ - -/* - * Structure which stores the information of different LED types - * and corresponding LED state information of driver states - */ -struct bcm_led_state_info { - unsigned char LED_Type; /* specify GPIO number - use 0xFF if not used */ - unsigned char LED_On_State; /* Bits set or reset for different states */ - unsigned char LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */ - unsigned char GPIO_Num; - unsigned char BitPolarity; /* To represent whether H/W is normal polarity or reverse polarity */ -}; - -struct bcm_led_info { - struct bcm_led_state_info LEDState[NUM_OF_LEDS]; - bool bIdleMode_tx_from_host; /* Variable to notify whether driver came out from idlemode due to Host or target */ - bool bIdle_led_off; - wait_queue_head_t notify_led_event; - wait_queue_head_t idleModeSyncEvent; - struct task_struct *led_cntrl_threadid; - int led_thread_running; - bool bLedInitDone; -}; - -/* LED Thread state. */ -#define BCM_LED_THREAD_DISABLED 0 /* LED Thread is not running. */ -#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 /* LED thread is running. */ -#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 /* LED thread has been put on hold */ - -#endif diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c deleted file mode 100644 index ce09473fbb1f..000000000000 --- a/drivers/staging/bcm/nvm.c +++ /dev/null @@ -1,4661 +0,0 @@ -#include "headers.h" - -#define DWORD unsigned int - -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, - unsigned int offset); -static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); -static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); -static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, - unsigned int FlashSectorSizeSig, - unsigned int FlashSectorSize); - -static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); -static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter); -static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter); - -static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); - -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset); -static int IsSectionWritable(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val Section); -static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val section); - -static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val dsd); -static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val dsd); -static int ReadISOPriority(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val iso); -static int ReadISOSignature(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val iso); - -static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); -static int CorruptISOSig(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val eFlash2xSectionVal); -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, - PUCHAR pBuff, - unsigned int uiSectAlignAddr); -static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, - PUINT pBuff, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffset, - unsigned int uiNumBytes); -static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter); -static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter); - -static int BeceemFlashBulkRead( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes); - -static int BeceemFlashBulkWrite( - struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify); - -static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); - -static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData); - -/* Procedure: ReadEEPROMStatusRegister - * - * Description: Reads the standard EEPROM Status Register. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * Returns: - * OSAL_STATUS_CODE - */ -static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) -{ - UCHAR uiData = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - unsigned int value = 0; - unsigned int value1 = 0; - - /* Read the EEPROM status register */ - value = EEPROM_READ_STATUS_REGISTER; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - while (dwRetries != 0) { - value = 0; - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting...."); - break; - } - - /* Wait for Avail bit to be set. */ - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { - /* Clear the Avail/Full bits - which ever is set. */ - value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - uiData = (UCHAR)value; - - break; - } - - dwRetries--; - if (dwRetries == 0) { - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x3004 = %x 0x3008 = %x, retries = %d failed.\n", value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return uiData; - } - if (!(dwRetries%RETRIES_PER_DELAY)) - udelay(1000); - uiStatus = 0; - } - return uiData; -} /* ReadEEPROMStatusRegister */ - -/* - * Procedure: ReadBeceemEEPROMBulk - * - * Description: This routine reads 16Byte data from EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * dwAddress - EEPROM Offset to read the data from. - * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY. - * - * Returns: - * OSAL_STATUS_CODE: - */ - -static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, - DWORD dwAddress, - DWORD *pdwData, - DWORD dwNumWords) -{ - DWORD dwIndex = 0; - DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - unsigned int value = 0; - unsigned int value1 = 0; - UCHAR *pvalue; - - /* Flush the read and cmd queue. */ - value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH); - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Clear the Avail/Full bits. */ - value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ); - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - while (dwRetries != 0) { - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop..."); - return -ENODEV; - } - - /* If we are reading 16 bytes we want to be sure that the queue - * is full before we read. In the other cases we are ok if the - * queue has data available - */ - if (dwNumWords == 4) { - if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) { - /* Clear the Avail/Full bits - which ever is set. */ - value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - break; - } - } else if (dwNumWords == 1) { - if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) { - /* We just got Avail and we have to read 32bits so we - * need this sleep for Cardbus kind of devices. - */ - if (Adapter->chip_id == 0xBECE0210) - udelay(800); - - /* Clear the Avail/Full bits - which ever is set. */ - value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - break; - } - } - - uiStatus = 0; - - dwRetries--; - if (dwRetries == 0) { - value = 0; - value1 = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", - dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - - if (!(dwRetries%RETRIES_PER_DELAY)) - udelay(1000); - } - - for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) { - /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */ - pvalue = (PUCHAR)(pdwData + dwIndex); - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[0] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[1] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[2] = value; - - value = 0; - rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); - - pvalue[3] = value; - } - - return STATUS_SUCCESS; -} /* ReadBeceemEEPROMBulk() */ - -/* - * Procedure: ReadBeceemEEPROM - * - * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page - * reads to do this operation. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - EEPROM Offset to read the data from. - * pBuffer - Pointer to word where data needs to be stored in. - * - * Returns: - * OSAL_STATUS_CODE: - */ - -int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, - DWORD uiOffset, - DWORD *pBuffer) -{ - unsigned int uiData[8] = {0}; - unsigned int uiByteOffset = 0; - unsigned int uiTempOffset = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> "); - - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiByteOffset = uiOffset - uiTempOffset; - - ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); - - /* A word can overlap at most over 2 pages. In that case we read the - * next page too. - */ - if (uiByteOffset > 12) - ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); - - memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4); - - return STATUS_SUCCESS; -} /* ReadBeceemEEPROM() */ - -int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) -{ - int Status; - unsigned char puMacAddr[6]; - - Status = BeceemNVMRead(Adapter, - (PUINT)&puMacAddr[0], - INIT_PARAMS_1_MACADDRESS_ADDRESS, - MAC_ADDRESS_SIZE); - - if (Status == STATUS_SUCCESS) - memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - - return Status; -} - -/* - * Procedure: BeceemEEPROMBulkRead - * - * Description: Reads the EEPROM and returns the Data. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from EEPROM - * uiOffset - Offset of EEPROM from where data should be read - * uiNumBytes - Number of bytes to be read from the EEPROM. - * - * Returns: - * OSAL_STATUS_SUCCESS - if EEPROM read is successful. - * - if failed. - */ - -int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiData[4] = {0}; - /* unsigned int uiAddress = 0; */ - unsigned int uiBytesRemaining = uiNumBytes; - unsigned int uiIndex = 0; - unsigned int uiTempOffset = 0; - unsigned int uiExtraBytes = 0; - unsigned int uiFailureRetries = 0; - PUCHAR pcBuff = (PUCHAR)pBuffer; - - if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) { - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiExtraBytes = uiOffset - uiTempOffset; - ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); - if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) { - memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes); - uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); - uiIndex += (MAX_RW_SIZE - uiExtraBytes); - uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } else { - memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining); - uiIndex += uiBytesRemaining; - uiOffset += uiBytesRemaining; - uiBytesRemaining = 0; - } - } - - while (uiBytesRemaining && uiFailureRetries != 128) { - if (Adapter->device_removed) - return -1; - - if (uiBytesRemaining >= MAX_RW_SIZE) { - /* For the requests more than or equal to 16 bytes, use bulk - * read function to make the access faster. - * We read 4 Dwords of data - */ - if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) { - memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE); - uiOffset += MAX_RW_SIZE; - uiBytesRemaining -= MAX_RW_SIZE; - uiIndex += MAX_RW_SIZE; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } else if (uiBytesRemaining >= 4) { - if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { - memcpy(pcBuff + uiIndex, &uiData[0], 4); - uiOffset += 4; - uiBytesRemaining -= 4; - uiIndex += 4; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } else { - /* Handle the reads less than 4 bytes... */ - PUCHAR pCharBuff = (PUCHAR)pBuffer; - - pCharBuff += uiIndex; - if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { - memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */ - uiBytesRemaining = 0; - } else { - uiFailureRetries++; - mdelay(3); /* sleep for a while before retry... */ - } - } - } - - return 0; -} - -/* - * Procedure: BeceemFlashBulkRead - * - * Description: Reads the FLASH and returns the Data. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from FLASH - * uiOffset - Offset of FLASH from where data should be read - * uiNumBytes - Number of bytes to be read from the FLASH. - * - * Returns: - * OSAL_STATUS_SUCCESS - if FLASH read is successful. - * - if failed. - */ - -static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiIndex = 0; - unsigned int uiBytesToRead = uiNumBytes; - int Status = 0; - unsigned int uiPartOffset = 0; - int bytes; - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed"); - return -ENODEV; - } - - /* Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - return Status; - #endif - - Adapter->SelectedChip = RESET_CHIP_SELECT; - - if (uiOffset % MAX_RW_SIZE) { - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE); - uiBytesToRead = MIN(uiNumBytes, uiBytesToRead); - - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); - if (bytes < 0) { - Status = bytes; - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; - } - - uiIndex += uiBytesToRead; - uiOffset += uiBytesToRead; - uiNumBytes -= uiBytesToRead; - } - - while (uiNumBytes) { - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE); - - bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); - if (bytes < 0) { - Status = bytes; - break; - } - - uiIndex += uiBytesToRead; - uiOffset += uiBytesToRead; - uiNumBytes -= uiBytesToRead; - } - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: BcmGetFlashSize - * - * Description: Finds the size of FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - size of the FLASH Storage. - * - */ - -static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter) -{ - if (IsFlash2x(Adapter)) - return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); - else - return 32 * 1024; -} - -/* - * Procedure: BcmGetEEPROMSize - * - * Description: Finds the size of EEPROM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - size of the EEPROM Storage. - * - */ - -static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiData = 0; - unsigned int uiIndex = 0; - - /* - * if EEPROM is present and already Calibrated,it will have - * 'BECM' string at 0th offset. - * To find the EEPROM size read the possible boundaries of the - * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will - * result in wrap around. So when we get the End of the EEPROM we will - * get 'BECM' string which is indeed at offset 0. - */ - BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); - if (uiData == BECM) { - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); - if (uiData == BECM) - return uiIndex * 1024; - } - } else { - /* - * EEPROM may not be present or not programmed - */ - uiData = 0xBABEFACE; - if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) { - uiData = 0; - for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4); - if (uiData == 0xBABEFACE) - return uiIndex * 1024; - } - } - } - return 0; -} - -/* - * Procedure: FlashSectorErase - * - * Description: Finds the sector size of the FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * addr - sector start address - * numOfSectors - number of sectors to be erased. - * - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int FlashSectorErase(struct bcm_mini_adapter *Adapter, - unsigned int addr, - unsigned int numOfSectors) -{ - unsigned int iIndex = 0, iRetries = 0; - unsigned int uiStatus = 0; - unsigned int value; - int bytes; - - for (iIndex = 0; iIndex < numOfSectors; iIndex++) { - value = 0x06000000; - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - value = (0xd8000000 | (addr & 0xFFFFFF)); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - iRetries = 0; - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries++; - /* After every try lets make the CPU free for 10 ms. generally time taken by the - * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms - * won't hamper performance in any case. - */ - mdelay(10); - } while ((uiStatus & 0x1) && (iRetries < 400)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n"); - return STATUS_FAILURE; - } - - addr += Adapter->uiSectorSize; - } - return 0; -} -/* - * Procedure: flashByteWrite - * - * Description: Performs Byte by Byte write to flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashByteWrite(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - unsigned int value; - ULONG ulData = *(PUCHAR)pData; - int bytes; - /* - * need not write 0xFF because write requires an erase and erase will - * make whole sector 0xFF. - */ - - if (0xFF == ulData) - return STATUS_SUCCESS; - - /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); - return STATUS_FAILURE; - } - value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - /* __udelay(950); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries--; - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: flashWrite - * - * Description: Performs write to flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashWrite(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - /* unsigned int uiStatus = 0; - * int iRetries = 0; - * unsigned int uiReadBack = 0; - */ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - unsigned int value; - unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - int bytes; - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - return 0; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); - return STATUS_FAILURE; - } - - /* __udelay(950); */ - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - - iRetries--; - /* this will ensure that in there will be no changes in the current path. - * currently one rdm/wrm takes 125 us. - * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay) - * Hence current implementation cycle will intoduce no delay in current path - */ - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/*----------------------------------------------------------------------------- - * Procedure: flashByteWriteStatus - * - * Description: Performs byte by byte write to flash with write done status check - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of the Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ -static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - ULONG ulData = *(PUCHAR)pData; - unsigned int value; - int bytes; - - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - - if (0xFF == ulData) - return STATUS_SUCCESS; - - /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ - - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails"); - return STATUS_SUCCESS; - } - if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails"); - return STATUS_FAILURE; - } - value = (0x02000000 | (uiOffset & 0xFFFFFF)); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - /* msleep(1); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - - iRetries--; - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} -/* - * Procedure: flashWriteStatus - * - * Description: Performs write to flash with write done status check - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. - * pData - Address of the Data to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int flashWriteStatus(struct bcm_mini_adapter *Adapter, - unsigned int uiOffset, - PVOID pData) -{ - unsigned int uiStatus = 0; - int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */ - /* unsigned int uiReadBack = 0; */ - unsigned int value; - unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; - int bytes; - - /* - * need not write 0xFFFFFFFF because write requires an erase and erase will - * make whole sector 0xFFFFFFFF. - */ - if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) - return 0; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - - if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails..."); - return STATUS_FAILURE; - } - /* __udelay(1); */ - - do { - value = (FLASH_CMD_STATUS_REG_READ << 24); - if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails"); - return STATUS_FAILURE; - } - /* __udelay(1); */ - bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)); - if (bytes < 0) { - uiStatus = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails"); - return uiStatus; - } - iRetries--; - /* this will ensure that in there will be no changes in the current path. - * currently one rdm/wrm takes 125 us. - * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay) - * Hence current implementation cycle will intoduce no delay in current path - */ - if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) - udelay(1000); - - } while ((uiStatus & 0x1) && (iRetries > 0)); - - if (uiStatus & 0x1) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times."); - return STATUS_FAILURE; - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: BcmRestoreBlockProtectStatus - * - * Description: Restores the original block protection status. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * ulWriteStatus -Original status - * Returns: - * - * - */ - -static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) -{ - unsigned int value; - - value = (FLASH_CMD_WRITE_ENABLE << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); -} - -/* - * Procedure: BcmFlashUnProtectBlock - * - * Description: UnProtects appropriate blocks for writing. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned. - * Returns: - * ULONG - Status value before UnProtect. - * - */ - -static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength) -{ - ULONG ulStatus = 0; - ULONG ulWriteStatus = 0; - unsigned int value; - - uiOffset = uiOffset&0x000FFFFF; - /* - * Implemented only for 1MB Flash parts. - */ - if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) { - /* - * Get Current BP status. - */ - value = (FLASH_CMD_STATUS_REG_READ << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(10); - /* - * Read status will be WWXXYYZZ. We have to take only WW. - */ - rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); - ulStatus >>= 24; - ulWriteStatus = ulStatus; - /* - * Bits [5-2] give current block level protection status. - * Bit5: BP3 - DONT CARE - * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4 - * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS - */ - - if (ulStatus) { - if ((uiOffset+uiLength) <= 0x80000) { - /* - * Offset comes in lower half of 1MB. Protect the upper half. - * Clear BP1 and BP0 and set BP2. - */ - ulWriteStatus |= (0x4<<2); - ulWriteStatus &= ~(0x3<<2); - } else if ((uiOffset + uiLength) <= 0xC0000) { - /* - * Offset comes below Upper 1/4. Upper 1/4 can be protected. - * Clear BP2 and set BP1 and BP0. - */ - ulWriteStatus |= (0x3<<2); - ulWriteStatus &= ~(0x1<<4); - } else if ((uiOffset + uiLength) <= 0xE0000) { - /* - * Offset comes below Upper 1/8. Upper 1/8 can be protected. - * Clear BP2 and BP0 and set BP1 - */ - ulWriteStatus |= (0x1<<3); - ulWriteStatus &= ~(0x5<<2); - } else if ((uiOffset + uiLength) <= 0xF0000) { - /* - * Offset comes below Upper 1/16. Only upper 1/16 can be protected. - * Set BP0 and Clear BP2,BP1. - */ - ulWriteStatus |= (0x1<<2); - ulWriteStatus &= ~(0x3<<3); - } else { - /* - * Unblock all. - * Clear BP2,BP1 and BP0. - */ - ulWriteStatus &= ~(0x7<<2); - } - - value = (FLASH_CMD_WRITE_ENABLE << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); - value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - udelay(20); - } - } - return ulStatus; -} - -static int bulk_read_complete_sector(struct bcm_mini_adapter *ad, - UCHAR read_bk[], - PCHAR tmpbuff, - unsigned int offset, - unsigned int partoff) -{ - unsigned int i; - int j; - int bulk_read_stat; - FP_FLASH_WRITE_STATUS writef = - ad->fpFlashWriteWithStatusCheck; - - for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) { - bulk_read_stat = BeceemFlashBulkRead(ad, - (PUINT)read_bk, - offset + i, - MAX_RW_SIZE); - - if (bulk_read_stat != STATUS_SUCCESS) - continue; - - if (ad->ulFlashWriteSize == 1) { - for (j = 0; j < 16; j++) { - if ((read_bk[j] != tmpbuff[i + j]) && - (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) { - return STATUS_FAILURE; - } - } - } else { - if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) && - (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) { - return STATUS_FAILURE; - } - } - } - - return STATUS_SUCCESS; -} - -/* - * Procedure: BeceemFlashBulkWrite - * - * Description: Performs write to the flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - unsigned int uiIndex = 0; - unsigned int uiOffsetFromSectStart = 0; - unsigned int uiSectAlignAddr = 0; - unsigned int uiCurrSectOffsetAddr = 0; - unsigned int uiSectBoundary = 0; - unsigned int uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - int Status = STATUS_SUCCESS; - unsigned int uiTemp = 0; - unsigned int index = 0; - unsigned int uiPartOffset = 0; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - return Status; - #endif - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - /* Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - - pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (!pTempBuff) - goto BeceemFlashBulkWrite_EXIT; - /* - * check if the data to be written is overlapped across sectors - */ - if (uiOffset+uiNumBytes < uiSectBoundary) { - uiNumSectTobeRead = 1; - } else { - /* Number of sectors = Last sector start address/First sector start address */ - uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; - if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - uiNumSectTobeRead++; - } - /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is - * for DSD calibration, allow it without checking of sector permission - */ - - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) { - index = 0; - uiTemp = uiNumSectTobeRead; - while (uiTemp) { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); - Status = SECTOR_IS_NOT_WRITABLE; - goto BeceemFlashBulkWrite_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1; - } - } - Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) { - /* do_gettimeofday(&tv1); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000)); - */ - uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - BcmDoChipSelect(Adapter, uiSectAlignAddr); - - if (0 != BeceemFlashBulkRead(Adapter, - (PUINT)pTempBuff, - uiOffsetFromSectStart, - Adapter->uiSectorSize)) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - - /* do_gettimeofday(&tr); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - */ - ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - - if (uiNumSectTobeRead > 1) { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); - } - - if (IsFlash2x(Adapter)) - SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - - FlashSectorErase(Adapter, uiPartOffset, 1); - /* do_gettimeofday(&te); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000)); - */ - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if (Adapter->device_removed) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - - if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) { - Status = -1; - goto BeceemFlashBulkWrite_EXIT; - } - } - - /* do_gettimeofday(&tw); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); - */ - - if (STATUS_FAILURE == bulk_read_complete_sector(Adapter, - ucReadBk, - pTempBuff, - uiOffsetFromSectStart, - uiPartOffset)) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWrite_EXIT; - } - - /* do_gettimeofday(&twv); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000)); - */ - if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - ulStatus = 0; - } - - uiCurrSectOffsetAddr = 0; - uiSectAlignAddr = uiSectBoundary; - uiSectBoundary += Adapter->uiSectorSize; - uiOffsetFromSectStart += Adapter->uiSectorSize; - uiNumSectTobeRead--; - } - /* do_gettimeofday(&tv2); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000)); - * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000)); - * - * Cleanup. - */ -BeceemFlashBulkWrite_EXIT: - if (ulStatus) - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - - kfree(pTempBuff); - - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: BeceemFlashBulkWriteStatus - * - * Description: Writes to Flash. Checks the SPI status after each write. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - PCHAR pTempBuff = NULL; - PUCHAR pcBuffer = (PUCHAR)pBuffer; - unsigned int uiIndex = 0; - unsigned int uiOffsetFromSectStart = 0; - unsigned int uiSectAlignAddr = 0; - unsigned int uiCurrSectOffsetAddr = 0; - unsigned int uiSectBoundary = 0; - unsigned int uiNumSectTobeRead = 0; - UCHAR ucReadBk[16] = {0}; - ULONG ulStatus = 0; - unsigned int Status = STATUS_SUCCESS; - unsigned int uiTemp = 0; - unsigned int index = 0; - unsigned int uiPartOffset = 0; - - uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); - - /* uiOffset += Adapter->ulFlashCalStart; - * Adding flash Base address - * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); - */ - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); - uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - - pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); - if (!pTempBuff) - goto BeceemFlashBulkWriteStatus_EXIT; - - /* - * check if the data to be written is overlapped across sectors - */ - if (uiOffset+uiNumBytes < uiSectBoundary) { - uiNumSectTobeRead = 1; - } else { - /* Number of sectors = Last sector start address/First sector start address */ - uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize; - if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize) - uiNumSectTobeRead++; - } - - if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) { - index = 0; - uiTemp = uiNumSectTobeRead; - while (uiTemp) { - if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable", - (uiOffsetFromSectStart + index * Adapter->uiSectorSize)); - Status = SECTOR_IS_NOT_WRITABLE; - goto BeceemFlashBulkWriteStatus_EXIT; - } - uiTemp = uiTemp - 1; - index = index + 1; - } - } - - Adapter->SelectedChip = RESET_CHIP_SELECT; - while (uiNumSectTobeRead) { - uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - BcmDoChipSelect(Adapter, uiSectAlignAddr); - if (0 != BeceemFlashBulkRead(Adapter, - (PUINT)pTempBuff, - uiOffsetFromSectStart, - Adapter->uiSectorSize)) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - - ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize); - - if (uiNumSectTobeRead > 1) { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr))); - uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)); - } else { - memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes); - } - - if (IsFlash2x(Adapter)) - SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); - - FlashSectorErase(Adapter, uiPartOffset, 1); - - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { - if (Adapter->device_removed) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - } - } - - if (bVerify) { - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { - if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { - if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWriteStatus_EXIT; - } - } - } - } - - if (ulStatus) { - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - ulStatus = 0; - } - - uiCurrSectOffsetAddr = 0; - uiSectAlignAddr = uiSectBoundary; - uiSectBoundary += Adapter->uiSectorSize; - uiOffsetFromSectStart += Adapter->uiSectorSize; - uiNumSectTobeRead--; - } -/* - * Cleanup. - */ -BeceemFlashBulkWriteStatus_EXIT: - if (ulStatus) - BcmRestoreBlockProtectStatus(Adapter, ulStatus); - - kfree(pTempBuff); - Adapter->SelectedChip = RESET_CHIP_SELECT; - return Status; -} - -/* - * Procedure: PropagateCalParamsFromFlashToMemory - * - * Description: Dumps the calibration section of EEPROM to DDR. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * Returns: - * OSAL_STATUS_CODE - * - */ - -int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) -{ - PCHAR pBuff, pPtr; - unsigned int uiEepromSize = 0; - unsigned int uiBytesToCopy = 0; - /* unsigned int uiIndex = 0; */ - unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; - unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - unsigned int value; - int Status = 0; - - /* - * Write the signature first. This will ensure firmware does not access EEPROM. - */ - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - - if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) - return -1; - - uiEepromSize = ntohl(uiEepromSize); - uiEepromSize >>= 16; - - /* - * subtract the auto init section size - */ - uiEepromSize -= EEPROM_CALPARAM_START; - - if (uiEepromSize > 1024 * 1024) - return -1; - - pBuff = kmalloc(uiEepromSize, GFP_KERNEL); - if (pBuff == NULL) - return -ENOMEM; - - if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { - kfree(pBuff); - return -1; - } - - pPtr = pBuff; - - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - - while (uiBytesToCopy) { - Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status); - break; - } - - pPtr += uiBytesToCopy; - uiEepromSize -= uiBytesToCopy; - uiMemoryLoc += uiBytesToCopy; - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - } - - kfree(pBuff); - return Status; -} - -/* - * Procedure: BeceemEEPROMReadBackandVerify - * - * Description: Read back the data written and verifies. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the flash where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - unsigned int uiRdbk = 0; - unsigned int uiIndex = 0; - unsigned int uiData = 0; - unsigned int auiData[4] = {0}; - - while (uiNumBytes) { - if (Adapter->device_removed) - return -1; - - if (uiNumBytes >= MAX_RW_SIZE) { - /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */ - BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - - if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { - /* re-write */ - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false); - mdelay(3); - BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); - - if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) - return -1; - } - uiOffset += MAX_RW_SIZE; - uiNumBytes -= MAX_RW_SIZE; - uiIndex += 4; - } else if (uiNumBytes >= 4) { - BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); - if (uiData != pBuffer[uiIndex]) { - /* re-write */ - BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false); - mdelay(3); - BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); - if (uiData != pBuffer[uiIndex]) - return -1; - } - uiOffset += 4; - uiNumBytes -= 4; - uiIndex++; - } else { - /* Handle the reads less than 4 bytes... */ - uiData = 0; - memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes); - BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); - - if (memcmp(&uiData, &uiRdbk, uiNumBytes)) - return -1; - - uiNumBytes = 0; - } - } - - return 0; -} - -static VOID BcmSwapWord(unsigned int *ptr1) -{ - unsigned int tempval = (unsigned int)*ptr1; - char *ptr2 = (char *)&tempval; - char *ptr = (char *)ptr1; - - ptr[0] = ptr2[3]; - ptr[1] = ptr2[2]; - ptr[2] = ptr2[1]; - ptr[3] = ptr2[0]; -} - -/* - * Procedure: BeceemEEPROMWritePage - * - * Description: Performs page write (16bytes) to the EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiData - Data to be written. - * uiOffset - Offset of the EEPROM where data needs to be written to. - * Returns: - * OSAL_STATUS_CODE - * - */ - -static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset) -{ - unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - unsigned int uiStatus = 0; - UCHAR uiEpromStatus = 0; - unsigned int value = 0; - - /* Flush the Write/Read/Cmd queues. */ - value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH); - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Clear the Empty/Avail/Full bits. After this it has been confirmed - * that the bit was cleared by reading back the register. See NOTE below. - * We also clear the Read queues as we do a EEPROM status register read - * later. - */ - value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - /* Enable write */ - value = EEPROM_WRITE_ENABLE; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - /* We can write back to back 8bits * 16 into the queue and as we have - * checked for the queue to be empty we can write in a burst. - */ - - value = uiData[0]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[1]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[2]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - value = uiData[3]; - BcmSwapWord(&value); - wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); - - /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG - * shows that we see 7 for the EEPROM data write. Which means that - * queue got full, also space is available as well as the queue is empty. - * This may happen in sequence. - */ - value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset; - wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); - - /* Ideally we should loop here without tries and eventually succeed. - * What we are checking if the previous write has completed, and this - * may take time. We should wait till the Empty bit is set. - */ - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { - uiRetries--; - if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - - if (!(uiRetries%RETRIES_PER_DELAY)) - udelay(1000); - - uiStatus = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop...."); - return -ENODEV; - } - } - - if (uiRetries != 0) { - /* Clear the ones that are set - either, Empty/Full/Avail bits */ - value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL)); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - } - - /* Here we should check if the EEPROM status register is correct before - * proceeding. Bit 0 in the EEPROM Status register should be 0 before - * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy - * with the previous write. Note also that issuing this read finally - * means the previous write to the EEPROM has completed. - */ - uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; - uiEpromStatus = 0; - while (uiRetries != 0) { - uiEpromStatus = ReadEEPROMStatusRegister(Adapter); - if (Adapter->device_removed == TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); - return -ENODEV; - } - if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries)); - return STATUS_SUCCESS; - } - uiRetries--; - if (uiRetries == 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); - return STATUS_FAILURE; - } - uiEpromStatus = 0; - if (!(uiRetries%RETRIES_PER_DELAY)) - udelay(1000); - } - - return STATUS_SUCCESS; -} /* BeceemEEPROMWritePage */ - -/* - * Procedure: BeceemEEPROMBulkWrite - * - * Description: Performs write to the EEPROM - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Data to be written. - * uiOffset - Offset of the EEPROM where data needs to be written to. - * uiNumBytes - Number of bytes to be written. - * bVerify - read verify flag. - * Returns: - * OSAL_STATUS_CODE - * - */ - -int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, - PUCHAR pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - unsigned int uiBytesToCopy = uiNumBytes; - /* unsigned int uiRdbk = 0; */ - unsigned int uiData[4] = {0}; - unsigned int uiIndex = 0; - unsigned int uiTempOffset = 0; - unsigned int uiExtraBytes = 0; - /* PUINT puiBuffer = (PUINT)pBuffer; - * int value; - */ - - if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { - uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); - uiExtraBytes = uiOffset - uiTempOffset; - - BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE); - - if (uiBytesToCopy >= (16 - uiExtraBytes)) { - memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) - return STATUS_FAILURE; - - uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); - uiIndex += (MAX_RW_SIZE - uiExtraBytes); - uiOffset += (MAX_RW_SIZE - uiExtraBytes); - } else { - memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) - return STATUS_FAILURE; - - uiIndex += uiBytesToCopy; - uiOffset += uiBytesToCopy; - uiBytesToCopy = 0; - } - } - - while (uiBytesToCopy) { - if (Adapter->device_removed) - return -1; - - if (uiBytesToCopy >= MAX_RW_SIZE) { - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset)) - return STATUS_FAILURE; - - uiIndex += MAX_RW_SIZE; - uiOffset += MAX_RW_SIZE; - uiBytesToCopy -= MAX_RW_SIZE; - } else { - /* - * To program non 16byte aligned data, read 16byte and then update. - */ - BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16); - memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy); - - if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset)) - return STATUS_FAILURE; - - uiBytesToCopy = 0; - } - } - - return 0; -} - -/* - * Procedure: BeceemNVMRead - * - * Description: Reads n number of bytes from NVM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer to store the data read from NVM - * uiOffset - Offset of NVM from where data should be read - * uiNumBytes - Number of bytes to be read from the NVM. - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM read is successful. - * - if failed. - */ - -int BeceemNVMRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - int Status = 0; - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int uiTemp = 0, value; - #endif - - if (Adapter->eNVMType == NVM_FLASH) { - if (Adapter->bFlashRawRead == false) { - if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) - return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes); - - uiOffset = uiOffset + Adapter->ulFlashCalStart; - } - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Status = BeceemFlashBulkRead(Adapter, - pBuffer, - uiOffset, - uiNumBytes); - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - #endif - } else if (Adapter->eNVMType == NVM_EEPROM) { - Status = BeceemEEPROMBulkRead(Adapter, - pBuffer, - uiOffset, - uiNumBytes); - } else { - Status = -1; - } - - return Status; -} - -/* - * Procedure: BeceemNVMWrite - * - * Description: Writes n number of bytes to NVM. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pBuffer - Buffer contains the data to be written. - * uiOffset - Offset of NVM where data to be written to. - * uiNumBytes - Number of bytes to be written.. - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM write is successful. - * - if failed. - */ - -int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - unsigned int uiOffset, - unsigned int uiNumBytes, - bool bVerify) -{ - int Status = 0; - unsigned int uiTemp = 0; - unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - unsigned int uiIndex = 0; - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int value; - #endif - - unsigned int uiFlashOffset = 0; - - if (Adapter->eNVMType == NVM_FLASH) { - if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) - Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify); - else { - uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - if (Adapter->bStatusWrite == TRUE) - Status = BeceemFlashBulkWriteStatus(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes , - bVerify); - else - - Status = BeceemFlashBulkWrite(Adapter, - pBuffer, - uiFlashOffset, - uiNumBytes, - bVerify); - #endif - } - - if (uiOffset >= EEPROM_CALPARAM_START) { - uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); - while (uiNumBytes) { - if (uiNumBytes > BUFFER_4K) { - wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K); - uiNumBytes -= BUFFER_4K; - uiIndex += BUFFER_4K; - } else { - wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes); - uiNumBytes = 0; - break; - } - } - } else { - if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { - ULONG ulBytesTobeSkipped = 0; - PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */ - - uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); - ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); - uiOffset += (EEPROM_CALPARAM_START - uiOffset); - while (uiNumBytes) { - if (uiNumBytes > BUFFER_4K) { - wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K); - uiNumBytes -= BUFFER_4K; - uiIndex += BUFFER_4K; - } else { - wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes); - uiNumBytes = 0; - break; - } - } - } - } - /* restore the values. */ - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - } else if (Adapter->eNVMType == NVM_EEPROM) { - Status = BeceemEEPROMBulkWrite(Adapter, - (PUCHAR)pBuffer, - uiOffset, - uiNumBytes, - bVerify); - if (bVerify) - Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes); - } else { - Status = -1; - } - return Status; -} - -/* - * Procedure: BcmUpdateSectorSize - * - * Description: Updates the sector size to FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * uiSectorSize - sector size - * - * Returns: - * OSAL_STATUS_SUCCESS - if NVM write is successful. - * - if failed. - */ - -int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize) -{ - int Status = -1; - struct bcm_flash_cs_info sFlashCsInfo = {0}; - unsigned int uiTemp = 0; - unsigned int uiSectorSig = 0; - unsigned int uiCurrentSectorSize = 0; - unsigned int value; - - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - /* - * Before updating the sector size in the reserved area, check if already present. - */ - BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo)); - uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); - uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); - - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { - if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) { - if (uiSectorSize == uiCurrentSectorSize) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash"); - Status = STATUS_SUCCESS; - goto Restore; - } - } - } - - if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) { - sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); - sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); - - Status = BeceemFlashBulkWrite(Adapter, - (PUINT)&sFlashCsInfo, - Adapter->ulFlashControlSectionStart, - sizeof(sFlashCsInfo), - TRUE); - } - -Restore: - /* restore the values. */ - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - - return Status; -} - -/* - * Procedure: BcmGetFlashSectorSize - * - * Description: Finds the sector size of the FLASH. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * unsigned int - sector size. - * - */ - -static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize) -{ - unsigned int uiSectorSize = 0; - unsigned int uiSectorSig = 0; - - if (Adapter->bSectorSizeOverride && - (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) { - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } else { - uiSectorSig = FlashSectorSizeSig; - - if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { - uiSectorSize = FlashSectorSize; - /* - * If the sector size stored in the FLASH makes sense then use it. - */ - if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { - Adapter->uiSectorSize = uiSectorSize; - } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { - /* No valid size in FLASH, check if Config file has it. */ - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - } else { - /* Init to Default, if none of the above works. */ - Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; - } - } else { - if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && - Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) - Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; - else - Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; - } - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize); - - return Adapter->uiSectorSize; -} - -/* - * Procedure: BcmInitEEPROMQueues - * - * Description: Initialization of EEPROM queues. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * - */ - -static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) -{ - unsigned int value = 0; - /* CHIP Bug : Clear the Avail bits on the Read queue. The default - * value on this register is supposed to be 0x00001102. - * But we get 0x00001122. - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n"); - value = EEPROM_READ_DATA_AVAIL; - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - - /* Flush the all the EEPROM queues. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); - value = EEPROM_ALL_QUEUE_FLUSH; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - value = 0; - wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); - - /* Read the EEPROM Status Register. Just to see, no real purpose. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter)); - - return STATUS_SUCCESS; -} /* BcmInitEEPROMQueues() */ - -/* - * Procedure: BcmInitNVM - * - * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * - */ - -int BcmInitNVM(struct bcm_mini_adapter *ps_adapter) -{ - BcmValidateNvmType(ps_adapter); - BcmInitEEPROMQueues(ps_adapter); - - if (ps_adapter->eNVMType == NVM_AUTODETECT) { - ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); - if (ps_adapter->eNVMType == NVM_UNKNOWN) - BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); - } else if (ps_adapter->eNVMType == NVM_FLASH) { - BcmGetFlashCSInfo(ps_adapter); - } - - BcmGetNvmSize(ps_adapter); - - return STATUS_SUCCESS; -} - -/* BcmGetNvmSize : set the EEPROM or flash size in Adapter. - * - * Input Parameter: - * Adapter data structure - * Return Value : - * 0. means success; - */ - -static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->eNVMType == NVM_EEPROM) - Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); - else if (Adapter->eNVMType == NVM_FLASH) - Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); - - return 0; -} - -/* - * Procedure: BcmValidateNvm - * - * Description: Validates the NVM Type option selected against the device - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * - */ - -static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) -{ - /* - * if forcing the FLASH through CFG file, we should ensure device really has a FLASH. - * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. - * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. - */ - - if (Adapter->eNVMType == NVM_FLASH && - Adapter->chip_id < 0xBECE3300) - Adapter->eNVMType = NVM_AUTODETECT; -} - -/* - * Procedure: BcmReadFlashRDID - * - * Description: Reads ID from Serial Flash - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * Flash ID - */ - -static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) -{ - ULONG ulRDID = 0; - unsigned int value; - - /* - * Read ID Instruction. - */ - value = (FLASH_CMD_READ_ID << 24); - wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); - - /* Delay */ - udelay(10); - - /* - * Read SPI READQ REG. The output will be WWXXYYZZ. - * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. - */ - rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); - - return ulRDID >> 8; -} - -int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) -{ - if (!psAdapter) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); - return -EINVAL; - } - psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL); - if (psAdapter->psFlashCSInfo == NULL) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); - return -ENOMEM; - } - - psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL); - if (!psAdapter->psFlash2xCSInfo) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); - kfree(psAdapter->psFlashCSInfo); - return -ENOMEM; - } - - psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL); - if (!psAdapter->psFlash2xVendorInfo) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); - kfree(psAdapter->psFlashCSInfo); - kfree(psAdapter->psFlash2xCSInfo); - return -ENOMEM; - } - - return STATUS_SUCCESS; -} - -int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) -{ - if (!psAdapter) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); - return -EINVAL; - } - kfree(psAdapter->psFlashCSInfo); - kfree(psAdapter->psFlash2xCSInfo); - kfree(psAdapter->psFlash2xVendorInfo); - return STATUS_SUCCESS; -} - -static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) -{ - unsigned int Index = 0; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); - - for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, - (psFlash2xCSInfo->SectorAccessBitMap[Index])); - - return STATUS_SUCCESS; -} - -static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo) -{ - unsigned int Index = 0; - - psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); - psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); - /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */ - psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); - psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); - psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); - psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware); - psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage); - psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart); - psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd); - psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart); - psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd); - psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData); - psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout); - psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature); - psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig); - psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize); - psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize); - psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize); - psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr); - psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize); - psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig); - psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout); - psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start); - psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End); - psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start); - psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End); - psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start); - psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End); - psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start); - psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End); - psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start); - psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End); - psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start); - psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End); - psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader); - psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End); - psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End); - psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End); - psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); - - for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) - psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); - - return STATUS_SUCCESS; -} - -static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo) -{ - /* unsigned int Index = 0; */ - psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); - psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); - psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); - /* won't convert according to old assumption */ - psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion); - psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); - psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); - psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware); - psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); - psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); - psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); - psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); - psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); - psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); - psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); - psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); - psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); - psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); - psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); - psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); - psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); - psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); - psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); - psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); - psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); - - return STATUS_SUCCESS; -} - -static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) -{ - return (Adapter->uiVendorExtnFlag && - (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && - (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS)); -} - -static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) -{ - B_UINT32 i = 0; - unsigned int uiSizeSection = 0; - - Adapter->uiVendorExtnFlag = false; - - for (i = 0; i < TOTAL_SECTIONS; i++) - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS; - - if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) - return; - - i = 0; - while (i < TOTAL_SECTIONS) { - if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) { - i++; - continue; - } - - Adapter->uiVendorExtnFlag = TRUE; - uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - - Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); - - switch (i) { - case DSD0: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; - break; - - case DSD1: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; - break; - - case DSD2: - if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && - (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; - break; - case VSA0: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; - break; - - case VSA1: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; - break; - case VSA2: - if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; - else - Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; - break; - - default: - break; - } - i++; - } -} - -/* - * Procedure: BcmGetFlashCSInfo - * - * Description: Reads control structure and gets Cal section addresses. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * - */ - -static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) -{ - /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */ - - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int value; - #endif - - unsigned int uiFlashLayoutMajorVersion; - - Adapter->uiFlashLayoutMinorVersion = 0; - Adapter->uiFlashLayoutMajorVersion = 0; - Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; - - Adapter->uiFlashBaseAdd = 0; - Adapter->ulFlashCalStart = 0; - memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info)); - memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info)); - - if (!Adapter->bDDRInitDone) { - value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); - } - - /* Reading first 8 Bytes to get the Flash Layout - * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) - */ - BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8); - - Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); - - if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { - uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); - Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); - } else { - Adapter->uiFlashLayoutMinorVersion = 0; - uiFlashLayoutMajorVersion = 0; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); - - if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) { - BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info)); - ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); - Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); - - if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; - - if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && - (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) { - Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } else { - Adapter->ulFlashWriteSize = MAX_RW_SIZE; - Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; - } - - BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), - (Adapter->psFlashCSInfo->FlashSectorSize)); - Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; - } else { - if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL, - Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n"); - return STATUS_FAILURE; - } - - ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); - BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter); - if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && - (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && - (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && - (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) { - Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; - Adapter->fpFlashWrite = flashByteWrite; - Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; - } else { - Adapter->ulFlashWriteSize = MAX_RW_SIZE; - Adapter->fpFlashWrite = flashWrite; - Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; - } - - BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig, - Adapter->psFlash2xCSInfo->FlashSectorSize); - - UpdateVendorInfo(Adapter); - - BcmGetActiveDSD(Adapter); - BcmGetActiveISO(Adapter); - Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF; - Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; - } - /* - * Concerns: what if CS sector size does not match with this sector size ??? - * what is the indication of AccessBitMap in CS in flash 2.x ???? - */ - Adapter->ulFlashID = BcmReadFlashRDID(Adapter); - Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; - - return STATUS_SUCCESS; -} - -/* - * Procedure: BcmGetNvmType - * - * Description: Finds the type of NVM used. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * - * Returns: - * NVM_TYPE - * - */ - -static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiData = 0; - - BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); - if (uiData == BECM) - return NVM_EEPROM; - - /* - * Read control struct and get cal addresses before accessing the flash - */ - BcmGetFlashCSInfo(Adapter); - - BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); - if (uiData == BECM) - return NVM_FLASH; - - /* - * even if there is no valid signature on EEPROM/FLASH find out if they really exist. - * if exist select it. - */ - if (BcmGetEEPROMSize(Adapter)) - return NVM_EEPROM; - - /* TBD for Flash. */ - return NVM_UNKNOWN; -} - -/* - * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given - * @Adapter : Drivers Private Data structure - * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val - * - * Return value:- - * On success it return the start offset of the provided section val - * On Failure -returns STATUS_FAILURE - */ - -int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) -{ - /* - * Considering all the section for which end offset can be calculated or directly given - * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section - * endoffset can't be calculated or given in CS Structure. - */ - - int SectStartOffset = 0; - - SectStartOffset = INVALID_OFFSET; - - if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal)) - return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; - - switch (eFlashSectionVal) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); - break; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) - SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectStartOffset = INVALID_OFFSET; - } - - return SectStartOffset; -} - -/* - * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given - * @Adapter : Drivers Private Data structure - * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val - * - * Return value:- - * On success it return the end offset of the provided section val - * On Failure -returns STATUS_FAILURE - */ - -static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - int SectEndOffset = 0; - - SectEndOffset = INVALID_OFFSET; - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; - - switch (eFlash2xSectionVal) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + - (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); - break; - case CONTROL_SECTION: - /* Not Clear So Putting failure. confirm and fix it. */ - SectEndOffset = STATUS_FAILURE; - break; - case ISO_IMAGE1_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); - break; - case ISO_IMAGE1_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); - break; - case ISO_IMAGE2_PART2: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); - break; - case ISO_IMAGE2_PART3: - if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) - SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); - break; - default: - SectEndOffset = INVALID_OFFSET; - } - - return SectEndOffset; -} - -/* - * BcmFlash2xBulkRead:- Read API for Flash Map 2.x . - * @Adapter :Driver Private Data Structure - * @pBuffer : Buffer where data has to be put after reading - * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val - * @uiOffsetWithinSectionVal :- Offset with in provided section - * @uiNumBytes : Number of Bytes for Read - * - * Return value:- - * return true on success and STATUS_FAILURE on fail. - */ - -int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffsetWithinSectionVal, - unsigned int uiNumBytes) -{ - int Status = STATUS_SUCCESS; - int SectionStartOffset = 0; - unsigned int uiAbsoluteOffset = 0; - unsigned int uiTemp = 0, value = 0; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); - return -EINVAL; - } - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); - return -ENODEV; - } - - /* NO_SECTION_VAL means absolute offset is given. */ - if (eFlash2xSectionVal == NO_SECTION_VAL) - SectionStartOffset = 0; - else - SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - - if (SectionStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal); - return -EINVAL; - } - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); - - /* calculating the absolute offset from FLASH; */ - uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes); - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); - return Status; - } - - return Status; -} - -/* - * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. - * @Adapter :Driver Private Data Structure - * @pBuffer : Buffer From where data has to taken for writing - * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val - * @uiOffsetWithinSectionVal :- Offset with in provided section - * @uiNumBytes : Number of Bytes for Write - * - * Return value:- - * return true on success and STATUS_FAILURE on fail. - * - */ - -int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, - PUINT pBuffer, - enum bcm_flash2x_section_val eFlash2xSectVal, - unsigned int uiOffset, - unsigned int uiNumBytes, - unsigned int bVerify) -{ - int Status = STATUS_SUCCESS; - unsigned int FlashSectValStartOffset = 0; - unsigned int uiTemp = 0, value = 0; - - if (!Adapter) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); - return -EINVAL; - } - - if (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); - return -ENODEV; - } - - /* NO_SECTION_VAL means absolute offset is given. */ - if (eFlash2xSectVal == NO_SECTION_VAL) - FlashSectValStartOffset = 0; - else - FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); - - if (FlashSectValStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal); - return -EINVAL; - } - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal)) - return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); - - /* calculating the absolute offset from FLASH; */ - uiOffset = uiOffset + FlashSectValStartOffset; - - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify); - - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); - return Status; - } - - return Status; -} - -/* - * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR - * @Adapter :-Drivers private Data Structure - * - * Return Value:- - * Return STATUS_SUCESS if get success in setting the right DSD else negative error code - * - */ - -static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) -{ - enum bcm_flash2x_section_val uiHighestPriDSD = 0; - - uiHighestPriDSD = getHighestPriDSD(Adapter); - Adapter->eActiveDSD = uiHighestPriDSD; - - if (DSD0 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; - if (DSD1 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - if (DSD2 == uiHighestPriDSD) - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - if (Adapter->eActiveDSD) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); - if (Adapter->eActiveDSD == 0) { - /* if No DSD gets Active, Make Active the DSD with WR permission */ - if (IsSectionWritable(Adapter, DSD2)) { - Adapter->eActiveDSD = DSD2; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; - } else if (IsSectionWritable(Adapter, DSD1)) { - Adapter->eActiveDSD = DSD1; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; - } else if (IsSectionWritable(Adapter, DSD0)) { - Adapter->eActiveDSD = DSD0; - Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; - } - } - - return STATUS_SUCCESS; -} - -/* - * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue - * @Adapter : Driver private Data Structure - * - * Return Value:- - * Sucsess:- STATUS_SUCESS - * Failure- : negative erro code - * - */ - -static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter) -{ - int HighestPriISO = 0; - - HighestPriISO = getHighestPriISO(Adapter); - - Adapter->eActiveISO = HighestPriISO; - if (Adapter->eActiveISO == ISO_IMAGE2) - Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); - else if (Adapter->eActiveISO == ISO_IMAGE1) - Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); - - if (Adapter->eActiveISO) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO); - - return STATUS_SUCCESS; -} - -/* - * IsOffsetWritable :- it will tell the access permission of the sector having passed offset - * @Adapter : Drivers Private Data Structure - * @uiOffset : Offset provided in the Flash - * - * Return Value:- - * Success:-TRUE , offset is writable - * Failure:-false, offset is RO - * - */ - -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset) -{ - unsigned int uiSectorNum = 0; - unsigned int uiWordOfSectorPermission = 0; - unsigned int uiBitofSectorePermission = 0; - B_UINT32 permissionBits = 0; - - uiSectorNum = uiOffset/Adapter->uiSectorSize; - - /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */ - uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16]; - - /* calculating the bit index inside the word for this sector */ - uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16); - - /* Setting Access permission */ - permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission); - permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; - if (permissionBits == SECTOR_READWRITE_PERMISSION) - return TRUE; - else - return false; -} - -static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap) -{ - struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); - - return STATUS_SUCCESS; -} - -/* - * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash - * 8bit has been assigned to every section. - * bit[0] :Section present or not - * bit[1] :section is valid or not - * bit[2] : Secton is read only or has write permission too. - * bit[3] : Active Section - - * bit[7...4] = Reserved . - * - * @Adapter:-Driver private Data Structure - * - * Return value:- - * Success:- STATUS_SUCESS - * Failure:- negative error code - */ - -int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap) -{ - struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo; - enum bcm_flash2x_section_val uiHighestPriDSD = 0; - enum bcm_flash2x_section_val uiHighestPriISO = 0; - bool SetActiveDSDDone = false; - bool SetActiveISODone = false; - - /* For 1.x map all the section except DSD0 will be shown as not present - * This part will be used by calibration tool to detect the number of DSD present in Flash. - */ - if (IsFlash2x(Adapter) == false) { - psFlash2xBitMap->ISO_IMAGE2 = 0; - psFlash2xBitMap->ISO_IMAGE1 = 0; - psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */ - psFlash2xBitMap->DSD1 = 0; - psFlash2xBitMap->DSD2 = 0; - psFlash2xBitMap->VSA0 = 0; - psFlash2xBitMap->VSA1 = 0; - psFlash2xBitMap->VSA2 = 0; - psFlash2xBitMap->CONTROL_SECTION = 0; - psFlash2xBitMap->SCSI = 0; - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved1 = 0; - psFlash2xBitMap->Reserved2 = 0; - - return STATUS_SUCCESS; - } - - uiHighestPriDSD = getHighestPriDSD(Adapter); - uiHighestPriISO = getHighestPriISO(Adapter); - - /* - * IS0 IMAGE 2 - */ - if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; - - if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, ISO_IMAGE2) == false) - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; - - if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) { - psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT; - SetActiveISODone = TRUE; - } - } - - /* - * IS0 IMAGE 1 - */ - if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; - - if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, ISO_IMAGE1) == false) - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; - - if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) { - psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT; - SetActiveISODone = TRUE; - } - } - - /* - * DSD2 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, DSD2) == false) { - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) { - psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * DSD 1 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, DSD1) == false) { - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) { - psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * For DSD 0 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; - - if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER) - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; - - /* Setting Access permission */ - if (IsSectionWritable(Adapter, DSD0) == false) { - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; - } else { - /* Means section is writable */ - if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) { - psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; - SetActiveDSDDone = TRUE; - } - } - } - - /* - * VSA 0 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; - - /* Calculation for extrating the Access permission */ - if (IsSectionWritable(Adapter, VSA0) == false) - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT; - } - - /* - * VSA 1 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, VSA1) == false) - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT; - } - - /* - * VSA 2 - */ - if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, VSA2) == false) - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT; - } - - /* - * SCSI Section - */ - if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, SCSI) == false) - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT; - } - - /* - * Control Section - */ - if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { - /* Setting the 0th Bit representing the Section is present or not. */ - psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); - - /* Setting the Access Bit. Map is not defined hece setting it always valid */ - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; - - /* Checking For Access permission */ - if (IsSectionWritable(Adapter, CONTROL_SECTION) == false) - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; - - /* By Default section is Active */ - psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT; - } - - /* - * For Reserved Sections - */ - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved0 = 0; - psFlash2xBitMap->Reserved0 = 0; - BcmDumpFlash2xSectionBitMap(psFlash2xBitMap); - - return STATUS_SUCCESS; -} - -/* - * BcmSetActiveSection :- Set Active section is used to make priority field highest over other - * section of same type. - * - * @Adapater :- Bcm Driver Private Data Structure - * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest. - * - * Return Value:- Make the priorit highest else return erorr code - * - */ - -int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal) -{ - unsigned int SectImagePriority = 0; - int Status = STATUS_SUCCESS; - - /* struct bcm_dsd_header sDSD = {0}; - * struct bcm_iso_header sISO = {0}; - */ - int HighestPriDSD = 0; - int HighestPriISO = 0; - - Status = IsSectionWritable(Adapter, eFlash2xSectVal); - if (Status != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal); - return STATUS_FAILURE; - } - - Adapter->bHeaderChangeAllowed = TRUE; - switch (eFlash2xSectVal) { - case ISO_IMAGE1: - case ISO_IMAGE2: - if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) { - HighestPriISO = getHighestPriISO(Adapter); - - if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; - - if ((SectImagePriority == 0) && IsSectionWritable(Adapter, HighestPriISO)) { - /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. - * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO - * by user - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriISO, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; - break; - } - - HighestPriISO = getHighestPriISO(Adapter); - - if (HighestPriISO == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = 2; - } - - SectImagePriority = htonl(SectImagePriority); - - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE; - break; - } - break; - case DSD0: - case DSD1: - case DSD2: - if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) { - HighestPriDSD = getHighestPriDSD(Adapter); - if (HighestPriDSD == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; - if (SectImagePriority == 0) { - /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. - * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD - * by user - */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); - SectImagePriority = htonl(0x1); - - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - - if (HighestPriDSD == eFlash2xSectVal) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = htonl(0x2); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - HighestPriDSD, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - break; - } - - HighestPriDSD = getHighestPriDSD(Adapter); - if (HighestPriDSD == eFlash2xSectVal) { - Status = STATUS_SUCCESS; - break; - } - - SectImagePriority = 3; - } - SectImagePriority = htonl(SectImagePriority); - Status = BcmFlash2xBulkWrite(Adapter, - &SectImagePriority, - eFlash2xSectVal, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - SIGNATURE_SIZE, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); - Status = STATUS_FAILURE; - break; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); - Status = STATUS_FAILURE; - break; - } - break; - case VSA0: - case VSA1: - case VSA2: - /* Has to be decided */ - break; - default: - Status = STATUS_FAILURE; - break; - } - - Adapter->bHeaderChangeAllowed = false; - return Status; -} - -/* - * BcmCopyISO - Used only for copying the ISO section - * @Adapater :- Bcm Driver Private Data Structure - * @sCopySectStrut :- Section copy structure - * - * Return value:- SUCCESS if copies successfully else negative error code - * - */ - -int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut) -{ - PCHAR Buff = NULL; - enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0; - unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; - unsigned int uiTotalDataToCopy = 0; - bool IsThisHeaderSector = false; - unsigned int sigOffset = 0; - unsigned int ISOLength = 0; - unsigned int Status = STATUS_SUCCESS; - unsigned int SigBuff[MAX_RW_SIZE]; - unsigned int i = 0; - - if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - return STATUS_FAILURE; - } - - Status = BcmFlash2xBulkRead(Adapter, &ISOLength, - sCopySectStrut.SrcSection, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize), - 4); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); - return Status; - } - - ISOLength = htonl(ISOLength); - if (ISOLength % Adapter->uiSectorSize) - ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize); - - sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); - - Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); - - if (!Buff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); - return -ENOMEM; - } - - if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) { - eISOReadPart = ISO_IMAGE1; - eISOWritePart = ISO_IMAGE2; - uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0; - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = ISOLength; - - CorruptISOSig(Adapter, ISO_IMAGE2); - while (uiTotalDataToCopy) { - if (uiTotalDataToCopy == Adapter->uiSectorSize) { - /* Setting for write of first sector. First sector is assumed to be written in last */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); - eISOReadPart = ISO_IMAGE1; - uiReadOffsetWithinPart = 0; - eISOWritePart = ISO_IMAGE2; - uiWriteOffsetWithinPart = 0; - IsThisHeaderSector = TRUE; - } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - - if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOReadPart = ISO_IMAGE1_PART2; - uiReadOffsetWithinPart = 0; - } - - if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOReadPart = ISO_IMAGE1_PART3; - uiReadOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOWritePart = ISO_IMAGE2_PART2; - uiWriteOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOWritePart = ISO_IMAGE2_PART3; - uiWriteOffsetWithinPart = 0; - } - } - - Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); - break; - } - - if (IsThisHeaderSector == TRUE) { - /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ - memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); - - for (i = 0; i < MAX_RW_SIZE; i++) - *(Buff + sigOffset + i) = 0xFF; - } - Adapter->bHeaderChangeAllowed = TRUE; - Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); - break; - } - - Adapter->bHeaderChangeAllowed = false; - if (IsThisHeaderSector == TRUE) { - WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - IsThisHeaderSector = false; - } - /* subtracting the written Data */ - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; - } - } - - if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) { - eISOReadPart = ISO_IMAGE2; - eISOWritePart = ISO_IMAGE1; - uiReadOffsetWithinPart = 0; - uiWriteOffsetWithinPart = 0; - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - - (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); - - if (uiTotalDataToCopy < ISOLength) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); - Status = STATUS_FAILURE; - goto out; - } - - uiTotalDataToCopy = ISOLength; - - CorruptISOSig(Adapter, ISO_IMAGE1); - - while (uiTotalDataToCopy) { - if (uiTotalDataToCopy == Adapter->uiSectorSize) { - /* Setting for write of first sector. First sector is assumed to be written in last */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); - eISOReadPart = ISO_IMAGE2; - uiReadOffsetWithinPart = 0; - eISOWritePart = ISO_IMAGE1; - uiWriteOffsetWithinPart = 0; - IsThisHeaderSector = TRUE; - } else { - uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; - uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; - - if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { - eISOReadPart = ISO_IMAGE2_PART2; - uiReadOffsetWithinPart = 0; - } - - if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { - eISOReadPart = ISO_IMAGE2_PART3; - uiReadOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { - eISOWritePart = ISO_IMAGE1_PART2; - uiWriteOffsetWithinPart = 0; - } - - if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { - eISOWritePart = ISO_IMAGE1_PART3; - uiWriteOffsetWithinPart = 0; - } - } - - Status = BcmFlash2xBulkRead(Adapter, - (PUINT)Buff, - eISOReadPart, - uiReadOffsetWithinPart, - Adapter->uiSectorSize); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); - break; - } - - if (IsThisHeaderSector == TRUE) { - /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ - memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); - - for (i = 0; i < MAX_RW_SIZE; i++) - *(Buff + sigOffset + i) = 0xFF; - } - Adapter->bHeaderChangeAllowed = TRUE; - Status = BcmFlash2xBulkWrite(Adapter, - (PUINT)Buff, - eISOWritePart, - uiWriteOffsetWithinPart, - Adapter->uiSectorSize, - TRUE); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); - break; - } - - Adapter->bHeaderChangeAllowed = false; - if (IsThisHeaderSector == TRUE) { - WriteToFlashWithoutSectorErase(Adapter, - SigBuff, - eISOWritePart, - sigOffset, - MAX_RW_SIZE); - - IsThisHeaderSector = false; - } - - /* subtracting the written Data */ - uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; - } - } -out: - kfree(Buff); - - return Status; -} - -/* - * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. - * It will corrupt the sig, if Section is writable, by making first bytes as zero. - * @Adapater :- Bcm Driver Private Data Structure - * @eFlash2xSectionVal :- Flash section val which has header - * - * Return Value :- - * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS - * Failure :-Return negative error code - */ - -int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - int Status = STATUS_SUCCESS; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); - - if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) { - Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); - } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) { - Status = CorruptISOSig(Adapter, eFlash2xSectionVal); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal); - return STATUS_SUCCESS; - } - return Status; -} - -/* - *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has - * header and Write Permission. - * @Adapater :- Bcm Driver Private Data Structure - * @eFlashSectionVal :- Flash section val which has header - * - * Return Value :- - * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS - * Failure :-Return negative error code - */ - -int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) -{ - unsigned int uiSignature = 0; - unsigned int uiOffset = 0; - - /* struct bcm_dsd_header dsdHeader = {0}; */ - if (Adapter->bSigCorrupted == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); - return STATUS_SUCCESS; - } - - if (Adapter->bAllDSDWriteAllow == false) { - if (IsSectionWritable(Adapter, eFlashSectionVal) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature"); - return SECTOR_IS_NOT_WRITABLE; - } - } - - if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) { - uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER); - uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader; - - uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber); - - if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig"); - return STATUS_FAILURE; - } - } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { - uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); - /* uiOffset = 0; */ - uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); - if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); - return STATUS_FAILURE; - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); - return STATUS_FAILURE; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature"); - - Adapter->bHeaderChangeAllowed = TRUE; - Adapter->bSigCorrupted = false; - BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE); - Adapter->bHeaderChangeAllowed = false; - - return STATUS_SUCCESS; -} - -/* - * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. - * if requested Bytes goes beyond the Requested section, it reports error. - * @Adapater :- Bcm Driver Private Data Structure - * @psFlash2xReadWrite :-Flash2x Read/write structure pointer - * - * Return values:-Return TRUE is request is valid else false. - */ - -int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite) -{ - unsigned int uiNumOfBytes = 0; - unsigned int uiSectStartOffset = 0; - unsigned int uiSectEndOffset = 0; - - uiNumOfBytes = psFlash2xReadWrite->numOfBytes; - - if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section); - return false; - } - uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section); - if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) { - if (psFlash2xReadWrite->Section == ISO_IMAGE1) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3); - } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) { - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) + - BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) - - BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); - } - - /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset - * it should be added in startoffset. so that check done in last of this function can be valued. - */ - uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); - } else - uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); - - /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */ - if (psFlash2xReadWrite->offset > uiSectEndOffset) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } - if (uiNumOfBytes > uiSectEndOffset) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } - /* Checking the boundary condition */ - if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) - return TRUE; - else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); - return false; - } -} - -/* - * IsFlash2x :- check for Flash 2.x - * Adapater :- Bcm Driver Private Data Structure - * - * Return value:- - * return TRUE if flah2.x of hgher version else return false. - */ - -int IsFlash2x(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) - return TRUE; - else - return false; -} - -/* - * GetFlashBaseAddr :- Calculate the Flash Base address - * @Adapater :- Bcm Driver Private Data Structure - * - * Return Value:- - * Success :- Base Address of the Flash - */ - -static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) -{ - unsigned int uiBaseAddr = 0; - - if (Adapter->bDDRInitDone) { - /* - * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - * In case of Raw Read... use the default value - */ - if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - uiBaseAddr = Adapter->uiFlashBaseAdd; - else - uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; - } else { - /* - * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr - * In case of Raw Read... use the default value - */ - if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) && - !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) - uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - else - uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; - } - - return uiBaseAddr; -} - -/* - * BcmCopySection :- This API is used to copy the One section in another. Both section should - * be contiuous and of same size. Hence this Will not be applicabe to copy ISO. - * - * @Adapater :- Bcm Driver Private Data Structure - * @SrcSection :- Source section From where data has to be copied - * @DstSection :- Destination section to which data has to be copied - * @offset :- Offset from/to where data has to be copied from one section to another. - * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset. - * in case of numofBytes equal zero complete section will be copied. - * Return Values- - * Success : Return STATUS_SUCCESS - * Faillure :- return negative error code - */ - -int BcmCopySection(struct bcm_mini_adapter *Adapter, - enum bcm_flash2x_section_val SrcSection, - enum bcm_flash2x_section_val DstSection, - unsigned int offset, - unsigned int numOfBytes) -{ - unsigned int BuffSize = 0; - unsigned int BytesToBeCopied = 0; - PUCHAR pBuff = NULL; - int Status = STATUS_SUCCESS; - - if (SrcSection == DstSection) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); - return -EINVAL; - } - - if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection"); - return -EINVAL; - } - - if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection"); - return -EINVAL; - } - - /* if offset zero means have to copy complete secton */ - if (numOfBytes == 0) { - numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) - - BcmGetSectionValStartOffset(Adapter, SrcSection); - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes); - } - - if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection) - - BcmGetSectionValStartOffset(Adapter, SrcSection)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n", - offset, numOfBytes); - return -EINVAL; - } - - if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection) - - BcmGetSectionValStartOffset(Adapter, DstSection)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", - offset, numOfBytes); - return -EINVAL; - } - - if (numOfBytes > Adapter->uiSectorSize) - BuffSize = Adapter->uiSectorSize; - else - BuffSize = numOfBytes; - - pBuff = kzalloc(BuffSize, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); - return -ENOMEM; - } - - BytesToBeCopied = Adapter->uiSectorSize; - if (offset % Adapter->uiSectorSize) - BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize); - if (BytesToBeCopied > numOfBytes) - BytesToBeCopied = numOfBytes; - - Adapter->bHeaderChangeAllowed = TRUE; - - do { - Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied); - break; - } - Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied); - break; - } - offset = offset + BytesToBeCopied; - numOfBytes = numOfBytes - BytesToBeCopied; - if (numOfBytes) { - if (numOfBytes > Adapter->uiSectorSize) - BytesToBeCopied = Adapter->uiSectorSize; - else - BytesToBeCopied = numOfBytes; - } - } while (numOfBytes > 0); - - kfree(pBuff); - Adapter->bHeaderChangeAllowed = false; - - return Status; -} - -/* - * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write - * @Adapater :- Bcm Driver Private Data Structure - * @pBuff :- Data buffer that has to be written in sector having the header map. - * @uiOffset :- Flash offset that has to be written. - * - * Return value :- - * Success :- On success return STATUS_SUCCESS - * Faillure :- Return negative error code - */ - -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset) -{ - unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0; - bool bHasHeader = false; - PUCHAR pTempBuff = NULL; - unsigned int uiSectAlignAddr = 0; - unsigned int sig = 0; - - /* making the offset sector aligned */ - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - - if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || - (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { - /* offset from the sector boundary having the header map */ - offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; - HeaderSizeToProtect = sizeof(struct bcm_dsd_header); - bHasHeader = TRUE; - } - - if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) || - uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) { - offsetToProtect = 0; - HeaderSizeToProtect = sizeof(struct bcm_iso_header); - bHasHeader = TRUE; - } - /* If Header is present overwrite passed buffer with this */ - if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) { - pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL); - if (!pTempBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); - return -ENOMEM; - } - /* Read header */ - BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect); - /* Replace Buffer content with Header */ - memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect); - - kfree(pTempBuff); - } - if (bHasHeader && Adapter->bSigCorrupted) { - sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))); - sig = ntohl(sig); - if ((sig & 0xFF000000) != CORRUPTED_PATTERN) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore"); - Adapter->bSigCorrupted = false; - return STATUS_SUCCESS; - } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig); - *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only"); - Adapter->bSigCorrupted = false; - } - - return STATUS_SUCCESS; -} - -/* - * BcmDoChipSelect : This will selcet the appropriate chip for writing. - * @Adapater :- Bcm Driver Private Data Structure - * - * OutPut:- - * Select the Appropriate chip and retrn status Success - */ -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset) -{ - unsigned int FlashConfig = 0; - int ChipNum = 0; - unsigned int GPIOConfig = 0; - unsigned int PartNum = 0; - - ChipNum = offset / FLASH_PART_SIZE; - - /* - * Chip Select mapping to enable flash0. - * To select flash 0, we have to OR with (0<<12). - * ORing 0 will have no impact so not doing that part. - * In future if Chip select value changes from 0 to non zero, - * That needs be taken care with backward comaptibility. No worries for now. - */ - - /* - * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured - * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) - * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from - * power down modes (Idle mode/shutdown mode), the values in the register will be different. - */ - - if (Adapter->SelectedChip == ChipNum) - return STATUS_SUCCESS; - - /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */ - Adapter->SelectedChip = ChipNum; - - /* bit[13..12] will select the appropriate chip */ - rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); - rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - { - switch (ChipNum) { - case 0: - PartNum = 0; - break; - case 1: - PartNum = 3; - GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); - break; - case 2: - PartNum = 1; - GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); - break; - case 3: - PartNum = 2; - GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); - break; - } - } - /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, - * nothing to do... can return immediately. - * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. - * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. - * These values are not written by host other than during CHIP_SELECT. - */ - if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) - return STATUS_SUCCESS; - - /* clearing the bit[13..12] */ - FlashConfig &= 0xFFFFCFFF; - FlashConfig = (FlashConfig | (PartNum<psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber), - SIGNATURE_SIZE); - - uiDSDsig = ntohl(uiDSDsig); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig); - - return uiDSDsig; -} - -static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd) -{ - /* unsigned int priOffsetInMap = 0 ; */ - unsigned int uiDSDPri = STATUS_FAILURE; - /* struct bcm_dsd_header dsdHeader = {0}; - * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; - */ - if (IsSectionWritable(Adapter, dsd)) { - if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) { - BcmFlash2xBulkRead(Adapter, - &uiDSDPri, - dsd, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), - 4); - - uiDSDPri = ntohl(uiDSDPri); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri); - } - } - - return uiDSDPri; -} - -static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter) -{ - int DSDHighestPri = STATUS_FAILURE; - int DsdPri = 0; - enum bcm_flash2x_section_val HighestPriDSD = 0; - - if (IsSectionWritable(Adapter, DSD2)) { - DSDHighestPri = ReadDSDPriority(Adapter, DSD2); - HighestPriDSD = DSD2; - } - - if (IsSectionWritable(Adapter, DSD1)) { - DsdPri = ReadDSDPriority(Adapter, DSD1); - if (DSDHighestPri < DsdPri) { - DSDHighestPri = DsdPri; - HighestPriDSD = DSD1; - } - } - - if (IsSectionWritable(Adapter, DSD0)) { - DsdPri = ReadDSDPriority(Adapter, DSD0); - if (DSDHighestPri < DsdPri) { - DSDHighestPri = DsdPri; - HighestPriDSD = DSD0; - } - } - if (HighestPriDSD) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); - - return HighestPriDSD; -} - -static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) -{ - unsigned int uiISOsig = 0; - /* unsigned int sigoffsetInMap = 0; - * struct bcm_iso_header ISOHeader = {0}; - * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; - */ - if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs"); - return STATUS_FAILURE; - } - BcmFlash2xBulkRead(Adapter, - &uiISOsig, - iso, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber), - SIGNATURE_SIZE); - - uiISOsig = ntohl(uiISOsig); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig); - - return uiISOsig; -} - -static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) -{ - unsigned int ISOPri = STATUS_FAILURE; - - if (IsSectionWritable(Adapter, iso)) { - if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { - BcmFlash2xBulkRead(Adapter, - &ISOPri, - iso, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), - 4); - - ISOPri = ntohl(ISOPri); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri); - } - } - - return ISOPri; -} - -static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter) -{ - int ISOHighestPri = STATUS_FAILURE; - int ISOPri = 0; - enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL; - - if (IsSectionWritable(Adapter, ISO_IMAGE2)) { - ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2); - HighestPriISO = ISO_IMAGE2; - } - - if (IsSectionWritable(Adapter, ISO_IMAGE1)) { - ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1); - if (ISOHighestPri < ISOPri) { - ISOHighestPri = ISOPri; - HighestPriISO = ISO_IMAGE1; - } - } - if (HighestPriISO) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri); - - return HighestPriISO; -} - -static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, - PUINT pBuff, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffset, - unsigned int uiNumBytes) -{ - #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) - unsigned int uiTemp = 0, value = 0; - unsigned int i = 0; - unsigned int uiPartOffset = 0; - #endif - unsigned int uiStartOffset = 0; - /* Adding section start address */ - int Status = STATUS_SUCCESS; - PUCHAR pcBuff = (PUCHAR)pBuff; - - if (uiNumBytes % Adapter->ulFlashWriteSize) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); - return STATUS_FAILURE; - } - - uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); - - if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) - return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); - - uiOffset = uiOffset + uiStartOffset; - - #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) - Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes); - #else - rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - value = 0; - wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); - - Adapter->SelectedChip = RESET_CHIP_SELECT; - BcmDoChipSelect(Adapter, uiOffset); - uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); - - for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) { - if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) - Status = flashByteWrite(Adapter, uiPartOffset, pcBuff); - else - Status = flashWrite(Adapter, uiPartOffset, pcBuff); - - if (Status != STATUS_SUCCESS) - break; - - pcBuff = pcBuff + Adapter->ulFlashWriteSize; - uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; - } - wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); - Adapter->SelectedChip = RESET_CHIP_SELECT; - #endif - - return Status; -} - -bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) -{ - bool SectionPresent = false; - - switch (section) { - case ISO_IMAGE1: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectionPresent = TRUE; - break; - case ISO_IMAGE2: - if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && - (IsNonCDLessDevice(Adapter) == false)) - SectionPresent = TRUE; - break; - case DSD0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case DSD2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA0: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA1: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case VSA2: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case SCSI: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - case CONTROL_SECTION: - if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) - SectionPresent = TRUE; - break; - default: - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); - SectionPresent = false; - } - - return SectionPresent; -} - -static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section) -{ - int offset = STATUS_FAILURE; - int Status = false; - - if (IsSectionExistInFlash(Adapter, Section) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section); - return false; - } - - offset = BcmGetSectionValStartOffset(Adapter, Section); - if (offset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section); - return false; - } - - if (IsSectionExistInVendorInfo(Adapter, Section)) - return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); - - Status = IsOffsetWritable(Adapter, offset); - return Status; -} - -static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - PUCHAR pBuff = NULL; - unsigned int sig = 0; - unsigned int uiOffset = 0; - unsigned int BlockStatus = 0; - unsigned int uiSectAlignAddr = 0; - - Adapter->bSigCorrupted = false; - if (Adapter->bAllDSDWriteAllow == false) { - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); - return SECTOR_IS_NOT_WRITABLE; - } - } - - pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); - return -ENOMEM; - } - - uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); - uiOffset -= MAX_RW_SIZE; - - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); - - sig = *((PUINT)(pBuff + 12)); - sig = ntohl(sig); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); - /* Now corrupting the sig by corrupting 4th last Byte. */ - *(pBuff + 12) = 0; - - if (sig == DSD_IMAGE_MAGIC_NUMBER) { - Adapter->bSigCorrupted = TRUE; - if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) { - uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); - BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); - - WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal, - (uiOffset + 12), BYTE_WRITE_SUPPORT); - if (BlockStatus) { - BcmRestoreBlockProtectStatus(Adapter, BlockStatus); - BlockStatus = 0; - } - } else { - WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, - uiOffset, MAX_RW_SIZE); - } - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); - kfree(pBuff); - - return STATUS_FAILURE; - } - - kfree(pBuff); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); - - return STATUS_SUCCESS; -} - -static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) -{ - PUCHAR pBuff = NULL; - unsigned int sig = 0; - unsigned int uiOffset = 0; - - Adapter->bSigCorrupted = false; - - if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); - return SECTOR_IS_NOT_WRITABLE; - } - - pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); - if (!pBuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); - return -ENOMEM; - } - - uiOffset = 0; - - BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); - - sig = *((PUINT)pBuff); - sig = ntohl(sig); - - /* corrupt signature */ - *pBuff = 0; - - if (sig == ISO_IMAGE_MAGIC_NUMBER) { - Adapter->bSigCorrupted = TRUE; - WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, - uiOffset, Adapter->ulFlashWriteSize); - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); - kfree(pBuff); - - return STATUS_FAILURE; - } - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); - BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); - - kfree(pBuff); - return STATUS_SUCCESS; -} - -bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter) -{ - if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) - return TRUE; - else - return false; -} diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h deleted file mode 100644 index e765cca5d966..000000000000 --- a/drivers/staging/bcm/nvm.h +++ /dev/null @@ -1,286 +0,0 @@ -/*************************************************************************************** - * - * Copyright (c) Beceem Communications Inc. - * - * Module Name: - * NVM.h - * - * Abstract: - * This file has the prototypes,preprocessors and definitions various NVM libraries. - * - * - * Revision History: - * Who When What - * -------- -------- ---------------------------------------------- - * Name Date Created/reviewed/modified - * - * Notes: - * - ****************************************************************************************/ - -#ifndef _NVM_H_ -#define _NVM_H_ - -struct bcm_flash_cs_info { - u32 MagicNumber; - /* let the magic number be 0xBECE-F1A5 - F1A5 for "flas-h" */ - u32 FlashLayoutVersion; - u32 ISOImageVersion; - u32 SCSIFirmwareVersion; - u32 OffsetFromZeroForPart1ISOImage; - u32 OffsetFromZeroForScsiFirmware; - u32 SizeOfScsiFirmware; - u32 OffsetFromZeroForPart2ISOImage; - u32 OffsetFromZeroForCalibrationStart; - u32 OffsetFromZeroForCalibrationEnd; - u32 OffsetFromZeroForVSAStart; - u32 OffsetFromZeroForVSAEnd; - u32 OffsetFromZeroForControlSectionStart; - u32 OffsetFromZeroForControlSectionData; - u32 CDLessInactivityTimeout; - u32 NewImageSignature; - u32 FlashSectorSizeSig; - u32 FlashSectorSize; - u32 FlashWriteSupportSize; - u32 TotalFlashSize; - u32 FlashBaseAddr; - u32 FlashPartMaxSize; - u32 IsCDLessDeviceBootSig; - /* MSC Timeout after reset to switch from MSC to NW Mode */ - u32 MassStorageTimeout; -}; - -#define FLASH2X_TOTAL_SIZE (64 * 1024 * 1024) -#define DEFAULT_SECTOR_SIZE (64 * 1024) - -struct bcm_flash2x_cs_info { - /* magic number as 0xBECE-F1A5 - F1A5 for "flas-h" */ - u32 MagicNumber; - u32 FlashLayoutVersion; - u32 ISOImageVersion; - u32 SCSIFirmwareVersion; - u32 OffsetFromZeroForPart1ISOImage; - u32 OffsetFromZeroForScsiFirmware; - u32 SizeOfScsiFirmware; - u32 OffsetFromZeroForPart2ISOImage; - u32 OffsetFromZeroForDSDStart; - u32 OffsetFromZeroForDSDEnd; - u32 OffsetFromZeroForVSAStart; - u32 OffsetFromZeroForVSAEnd; - u32 OffsetFromZeroForControlSectionStart; - u32 OffsetFromZeroForControlSectionData; - /* NO Data Activity timeout to switch from MSC to NW Mode */ - u32 CDLessInactivityTimeout; - u32 NewImageSignature; - u32 FlashSectorSizeSig; - u32 FlashSectorSize; - u32 FlashWriteSupportSize; - u32 TotalFlashSize; - u32 FlashBaseAddr; - u32 FlashPartMaxSize; - u32 IsCDLessDeviceBootSig; - /* MSC Timeout after reset to switch from MSC to NW Mode */ - u32 MassStorageTimeout; - /* Flash Map 2.0 Field */ - u32 OffsetISOImage1Part1Start; - u32 OffsetISOImage1Part1End; - u32 OffsetISOImage1Part2Start; - u32 OffsetISOImage1Part2End; - u32 OffsetISOImage1Part3Start; - u32 OffsetISOImage1Part3End; - u32 OffsetISOImage2Part1Start; - u32 OffsetISOImage2Part1End; - u32 OffsetISOImage2Part2Start; - u32 OffsetISOImage2Part2End; - u32 OffsetISOImage2Part3Start; - u32 OffsetISOImage2Part3End; - /* DSD Header offset from start of DSD */ - u32 OffsetFromDSDStartForDSDHeader; - u32 OffsetFromZeroForDSD1Start; - u32 OffsetFromZeroForDSD1End; - u32 OffsetFromZeroForDSD2Start; - u32 OffsetFromZeroForDSD2End; - u32 OffsetFromZeroForVSA1Start; - u32 OffsetFromZeroForVSA1End; - u32 OffsetFromZeroForVSA2Start; - u32 OffsetFromZeroForVSA2End; - /* - * ACCESS_BITS_PER_SECTOR 2 - * ACCESS_RW 0 - * ACCESS_RO 1 - * ACCESS_RESVD 2 - * ACCESS_RESVD 3 - */ - u32 SectorAccessBitMap[FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)]; - /* All expansions to the control data structure should add here */ -}; - -struct bcm_vendor_section_info { - u32 OffsetFromZeroForSectionStart; - u32 OffsetFromZeroForSectionEnd; - u32 AccessFlags; - u32 Reserved[16]; -}; - -struct bcm_flash2x_vendor_info { - struct bcm_vendor_section_info VendorSection[TOTAL_SECTIONS]; - u32 Reserved[16]; -}; - -struct bcm_dsd_header { - u32 DSDImageSize; - u32 DSDImageCRC; - u32 DSDImagePriority; - /* We should not consider right now. Reading reserve is worthless. */ - u32 Reserved[252]; /* Resvd for DSD Header */ - u32 DSDImageMagicNumber; -}; - -struct bcm_iso_header { - u32 ISOImageMagicNumber; - u32 ISOImageSize; - u32 ISOImageCRC; - u32 ISOImagePriority; - /* We should not consider right now. Reading reserve is worthless. */ - u32 Reserved[60]; /* Resvd for ISO Header extension */ -}; - -#define EEPROM_BEGIN_CIS (0) -#define EEPROM_BEGIN_NON_CIS (0x200) -#define EEPROM_END (0x2000) -#define INIT_PARAMS_SIGNATURE (0x95a7a597) -#define MAX_INIT_PARAMS_LENGTH (2048) -#define MAC_ADDRESS_OFFSET 0x200 - -#define INIT_PARAMS_1_SIGNATURE_ADDRESS EEPROM_BEGIN_NON_CIS -#define INIT_PARAMS_1_DATA_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+16) -#define INIT_PARAMS_1_MACADDRESS_ADDRESS (MAC_ADDRESS_OFFSET) -#define INIT_PARAMS_1_LENGTH_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+4) - -#define INIT_PARAMS_2_SIGNATURE_ADDRESS (EEPROM_BEGIN_NON_CIS + 2048 + 16) -#define INIT_PARAMS_2_DATA_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 16) -#define INIT_PARAMS_2_MACADDRESS_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 8) -#define INIT_PARAMS_2_LENGTH_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS + 4) - -#define EEPROM_SPI_DEV_CONFIG_REG 0x0F003000 -#define EEPROM_SPI_Q_STATUS1_REG 0x0F003004 -#define EEPROM_SPI_Q_STATUS1_MASK_REG 0x0F00300C - -#define EEPROM_SPI_Q_STATUS_REG 0x0F003008 -#define EEPROM_CMDQ_SPI_REG 0x0F003018 -#define EEPROM_WRITE_DATAQ_REG 0x0F00301C -#define EEPROM_READ_DATAQ_REG 0x0F003020 -#define SPI_FLUSH_REG 0x0F00304C - -#define EEPROM_WRITE_ENABLE 0x06000000 -#define EEPROM_READ_STATUS_REGISTER 0x05000000 -#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 -#define EEPROM_WRITE_QUEUE_EMPTY 0x00001000 -#define EEPROM_WRITE_QUEUE_AVAIL 0x00002000 -#define EEPROM_WRITE_QUEUE_FULL 0x00004000 -#define EEPROM_16_BYTE_PAGE_READ 0xFB000000 -#define EEPROM_4_BYTE_PAGE_READ 0x3B000000 - -#define EEPROM_CMD_QUEUE_FLUSH 0x00000001 -#define EEPROM_WRITE_QUEUE_FLUSH 0x00000002 -#define EEPROM_READ_QUEUE_FLUSH 0x00000004 -#define EEPROM_ETH_QUEUE_FLUSH 0x00000008 -#define EEPROM_ALL_QUEUE_FLUSH 0x0000000f -#define EEPROM_READ_ENABLE 0x06000000 -#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000 -#define EEPROM_READ_DATA_FULL 0x00000010 -#define EEPROM_READ_DATA_AVAIL 0x00000020 -#define EEPROM_READ_QUEUE_EMPTY 0x00000002 -#define EEPROM_CMD_QUEUE_EMPTY 0x00000100 -#define EEPROM_CMD_QUEUE_AVAIL 0x00000200 -#define EEPROM_CMD_QUEUE_FULL 0x00000400 - -/* Most EEPROM status register bit 0 indicates if the EEPROM is busy - * with a write if set 1. See the details of the EEPROM Status Register - * in the EEPROM data sheet. - */ -#define EEPROM_STATUS_REG_WRITE_BUSY 0x00000001 - -/* We will have 1 mSec for every RETRIES_PER_DELAY count and have a max attempts of MAX_EEPROM_RETRIES - * This will give us 80 mSec minimum of delay = 80mSecs - */ -#define MAX_EEPROM_RETRIES 80 -#define RETRIES_PER_DELAY 64 -#define MAX_RW_SIZE 0x10 -#define MAX_READ_SIZE 0x10 -#define MAX_SECTOR_SIZE (512 * 1024) -#define MIN_SECTOR_SIZE (1024) -#define FLASH_SECTOR_SIZE_OFFSET 0xEFFFC -#define FLASH_SECTOR_SIZE_SIG_OFFSET 0xEFFF8 -#define FLASH_SECTOR_SIZE_SIG 0xCAFEBABE -#define FLASH_CS_INFO_START_ADDR 0xFF0000 -#define FLASH_CONTROL_STRUCT_SIGNATURE 0xBECEF1A5 -#define SCSI_FIRMWARE_MAJOR_VERSION 0x1 -#define SCSI_FIRMWARE_MINOR_VERSION 0x5 -#define BYTE_WRITE_SUPPORT 0x1 -#define FLASH_AUTO_INIT_BASE_ADDR 0xF00000 -#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000 -#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000 -#define FLASH_CONTIGIOUS_START_ADDR_BCS350 0x08000000 -#define FLASH_CONTIGIOUS_END_ADDR_BCS350 0x08FFFFFF -#define FLASH_SIZE_ADDR 0xFFFFEC -#define FLASH_SPI_CMDQ_REG 0xAF003040 -#define FLASH_SPI_WRITEQ_REG 0xAF003044 -#define FLASH_SPI_READQ_REG 0xAF003048 -#define FLASH_CONFIG_REG 0xAF003050 -#define FLASH_GPIO_CONFIG_REG 0xAF000030 -#define FLASH_CMD_WRITE_ENABLE 0x06 -#define FLASH_CMD_READ_ENABLE 0x03 -#define FLASH_CMD_RESET_WRITE_ENABLE 0x04 -#define FLASH_CMD_STATUS_REG_READ 0x05 -#define FLASH_CMD_STATUS_REG_WRITE 0x01 -#define FLASH_CMD_READ_ID 0x9F -#define PAD_SELECT_REGISTER 0xAF000410 -#define FLASH_PART_SST25VF080B 0xBF258E -#define EEPROM_CAL_DATA_INTERNAL_LOC 0xbFB00008 -#define EEPROM_CALPARAM_START 0x200 -#define EEPROM_SIZE_OFFSET 524 - -/* As Read/Write time vaires from 1.5 to 3.0 ms. - * so After Ignoring the rdm/wrm time(that is dependent on many factor like interface etc.), - * here time calculated meets the worst case delay, 3.0 ms - */ -#define MAX_FLASH_RETRIES 4 -#define FLASH_PER_RETRIES_DELAY 16 -#define EEPROM_MAX_CAL_AREA_SIZE 0xF0000 -#define BECM ntohl(0x4245434d) -#define FLASH_2X_MAJOR_NUMBER 0x2 -#define DSD_IMAGE_MAGIC_NUMBER 0xBECE0D5D -#define ISO_IMAGE_MAGIC_NUMBER 0xBECE0150 -#define NON_CDLESS_DEVICE_BOOT_SIG 0xBECEB007 - -#define MINOR_VERSION(x) ((x >> 16) & 0xFFFF) -#define MAJOR_VERSION(x) (x & 0xFFFF) - -#define CORRUPTED_PATTERN 0x0 -#define UNINIT_PTR_IN_CS 0xBBBBDDDD -#define VENDOR_PTR_IN_CS 0xAAAACCCC -#define FLASH2X_SECTION_PRESENT (1 << 0) -#define FLASH2X_SECTION_VALID (1 << 1) -#define FLASH2X_SECTION_RO (1 << 2) -#define FLASH2X_SECTION_ACT (1 << 3) -#define SECTOR_IS_NOT_WRITABLE STATUS_FAILURE -#define INVALID_OFFSET STATUS_FAILURE -#define INVALID_SECTION STATUS_FAILURE -#define SECTOR_1K 1024 -#define SECTOR_64K (64 * SECTOR_1K) -#define SECTOR_128K (2 * SECTOR_64K) -#define SECTOR_256k (2 * SECTOR_128K) -#define SECTOR_512K (2 * SECTOR_256k) -#define FLASH_PART_SIZE (16 * 1024 * 1024) -#define RESET_CHIP_SELECT -1 -#define CHIP_SELECT_BIT12 12 -#define SECTOR_READWRITE_PERMISSION 0 -#define SECTOR_READONLY 1 -#define SIGNATURE_SIZE 4 -#define DEFAULT_BUFF_SIZE 0x10000 - -#define FIELD_OFFSET_IN_HEADER(HeaderPointer, Field) ((u8 *)&((HeaderPointer)(NULL))->Field - (u8 *)(NULL)) - -#endif - diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c deleted file mode 100644 index ca0b17991512..000000000000 --- a/drivers/staging/bcm/sort.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "headers.h" -#include - -/* - * File Name: sort.c - * - * Author: Beceem Communications Pvt. Ltd - * - * Abstract: This file contains the routines sorting the classification rules. - * - * Copyright (c) 2007 Beceem Communications Pvt. Ltd - */ - -static int compare_packet_info(void const *a, void const *b) -{ - struct bcm_packet_info const *pa = a; - struct bcm_packet_info const *pb = b; - - if (!pa->bValid || !pb->bValid) - return 0; - - return pa->u8TrafficPriority - pb->u8TrafficPriority; -} - -VOID SortPackInfo(struct bcm_mini_adapter *Adapter) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "<======="); - - sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(struct bcm_packet_info), - compare_packet_info, NULL); -} - -static int compare_classifiers(void const *a, void const *b) -{ - struct bcm_classifier_rule const *pa = a; - struct bcm_classifier_rule const *pb = b; - - if (!pa->bUsed || !pb->bUsed) - return 0; - - return pa->u8ClassifierRulePriority - pb->u8ClassifierRulePriority; -} - -VOID SortClassifiers(struct bcm_mini_adapter *Adapter) -{ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, - DBG_LVL_ALL, "<======="); - - sort(Adapter->astClassifierTable, MAX_CLASSIFIERS, - sizeof(struct bcm_classifier_rule), compare_classifiers, NULL); -} diff --git a/drivers/staging/bcm/target_params.h b/drivers/staging/bcm/target_params.h deleted file mode 100644 index dc45f9ab854d..000000000000 --- a/drivers/staging/bcm/target_params.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef TARGET_PARAMS_H -#define TARGET_PARAMS_H - -struct bcm_target_params { - u32 m_u32CfgVersion; - u32 m_u32CenterFrequency; - u32 m_u32BandAScan; - u32 m_u32BandBScan; - u32 m_u32BandCScan; - u32 m_u32ErtpsOptions; - u32 m_u32PHSEnable; - u32 m_u32HoEnable; - u32 m_u32HoReserved1; - u32 m_u32HoReserved2; - u32 m_u32MimoEnable; - u32 m_u32SecurityEnable; - u32 m_u32PowerSavingModesEnable; /* bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable */ - /* PowerSaving Mode Options: - * bit 0 = 1: CPE mode - to keep pcmcia if alive; - * bit 1 = 1: CINR reporting in Idlemode Msg - * bit 2 = 1: Default PSC Enable in sleepmode - */ - u32 m_u32PowerSavingModeOptions; - u32 m_u32ArqEnable; - /* From Version #3, the HARQ section renamed as general */ - u32 m_u32HarqEnable; - u32 m_u32EEPROMFlag; - /* BINARY TYPE - 4th MSByte: Interface Type - 3rd MSByte: Vendor Type - 2nd MSByte - * Unused - LSByte - */ - u32 m_u32Customize; - u32 m_u32ConfigBW; /* In Hz */ - u32 m_u32ShutDownInitThresholdTimer; - u32 m_u32RadioParameter; - u32 m_u32PhyParameter1; - u32 m_u32PhyParameter2; - u32 m_u32PhyParameter3; - u32 m_u32TestOptions; /* in eval mode only; lower 16bits = basic cid for testing; then bit 16 is test cqich,bit 17 test init rang; bit 18 test periodic rang and bit 19 is test harq ack/nack */ - u32 m_u32MaxMACDataperDLFrame; - u32 m_u32MaxMACDataperULFrame; - u32 m_u32Corr2MacFlags; - u32 HostDrvrConfig1; - u32 HostDrvrConfig2; - u32 HostDrvrConfig3; - u32 HostDrvrConfig4; - u32 HostDrvrConfig5; - u32 HostDrvrConfig6; - u32 m_u32SegmentedPUSCenable; - /* removed SHUT down related 'unused' params from here to sync 4.x and 5.x CFG files.. - * BAMC Related Parameters - * Bit 0-15 Band AMC signaling configuration: Bit 1 = 1 – Enable Band AMC signaling. - * bit 16-31 Band AMC Data configuration: Bit 16 = 1 – Band AMC 2x3 support. - */ - u32 m_u32BandAMCEnable; -}; - -#endif diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c deleted file mode 100644 index 1d9bef6e4273..000000000000 --- a/drivers/staging/bcm/vendorspecificextn.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "headers.h" -/* - * Procedure: vendorextnGetSectionInfo - * - * Description: Finds the type of NVM used. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * pNVMType - ptr to NVM type. - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - */ -INT vendorextnGetSectionInfo(PVOID pContext, - struct bcm_flash2x_vendor_info *pVendorInfo) -{ - return STATUS_FAILURE; -} - -/* - * Procedure: vendorextnInit - * - * Description: Initializing the vendor extension NVM interface - * - * Arguments: - * Adapter - Pointer to MINI Adapter Structure - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - * - */ -INT vendorextnInit(struct bcm_mini_adapter *Adapter) -{ - return STATUS_SUCCESS; -} - -/* - * Procedure: vendorextnExit - * - * Description: Free the resource associated with vendor extension NVM interface - * - * Arguments: - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - * - * - */ -INT vendorextnExit(struct bcm_mini_adapter *Adapter) -{ - return STATUS_SUCCESS; -} - -/* - * Procedure: vendorextnIoctl - * - * Description: execute the vendor extension specific ioctl - * - * Arguments: - * Adapter -Beceem private Adapter Structure - * cmd -vendor extension specific Ioctl commad - * arg -input parameter sent by vendor - * - * Returns: - * CONTINUE_COMMON_PATH in case it is not meant to be processed - * by vendor ioctls - * STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value - */ - -INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg) -{ - return CONTINUE_COMMON_PATH; -} - - - -/* - * Procedure: vendorextnReadSection - * - * Description: Reads from a section of NVM - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Read the data from Vendor Area to this buffer - * SectionVal - Value of type of Section - * Offset - Read from the Offset of the Vendor Section. - * numOfBytes - Read numOfBytes from the Vendor section to Buffer - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ - -INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) -{ - return STATUS_FAILURE; -} - - - -/* - * Procedure: vendorextnWriteSection - * - * Description: Write to a Section of NVM - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Write the data provided in the buffer - * SectionVal - Value of type of Section - * Offset - Writes to the Offset of the Vendor Section. - * numOfBytes - Write num Bytes after reading from pBuffer. - * bVerify - the Buffer Written should be verified. - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ -INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, - UINT numOfBytes, bool bVerify) -{ - return STATUS_FAILURE; -} - - - -/* - * Procedure: vendorextnWriteSectionWithoutErase - * - * Description: Write to a Section of NVM without erasing the sector - * - * Arguments: - * pContext - ptr to Adapter object instance - * pBuffer - Write the data provided in the buffer - * SectionVal - Value of type of Section - * Offset - Writes to the Offset of the Vendor Section. - * numOfBytes - Write num Bytes after reading from pBuffer. - * - * Returns: - * STATUS_SUCCESS/STATUS_FAILURE - */ -INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, - enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) -{ - return STATUS_FAILURE; -} diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h deleted file mode 100644 index ff57f0570451..000000000000 --- a/drivers/staging/bcm/vendorspecificextn.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef __VENDOR_EXTN_NVM_H__ -#define __VENDOR_EXTN_NVM_H__ - -#define CONTINUE_COMMON_PATH 0xFFFF - -INT vendorextnGetSectionInfo(PVOID pContext, struct bcm_flash2x_vendor_info *pVendorInfo); -INT vendorextnExit(struct bcm_mini_adapter *Adapter); -INT vendorextnInit(struct bcm_mini_adapter *Adapter); -INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg); -INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes); -INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes, bool bVerify); -INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes); - -#endif /* */ -- GitLab From 777783e0abae3cab7555bb182776f9ffaa35631a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Oct 2014 14:40:38 +0200 Subject: [PATCH 0524/9457] staging: android: binder: move to the "real" part of the kernel The Android binder code has been "stable" for many years now. No matter what comes in the future, we are going to have to support this API, so might as well move it to the "real" part of the kernel as there's no real work that needs to be done to the existing code. Signed-off-by: Greg Kroah-Hartman --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/android/Kconfig | 37 +++++++++++++++++++ drivers/android/Makefile | 3 ++ drivers/{staging => }/android/binder.c | 0 drivers/{staging => }/android/binder.h | 2 +- drivers/{staging => }/android/binder_trace.h | 0 drivers/staging/android/Kconfig | 30 --------------- drivers/staging/android/Makefile | 1 - include/uapi/linux/Kbuild | 1 + include/uapi/linux/android/Kbuild | 2 + .../uapi/linux/android}/binder.h | 0 12 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 drivers/android/Kconfig create mode 100644 drivers/android/Makefile rename drivers/{staging => }/android/binder.c (100%) rename drivers/{staging => }/android/binder.h (95%) rename drivers/{staging => }/android/binder_trace.h (100%) create mode 100644 include/uapi/linux/android/Kbuild rename {drivers/staging/android/uapi => include/uapi/linux/android}/binder.h (100%) diff --git a/drivers/Kconfig b/drivers/Kconfig index 1a693d3f9d51..569ff7886dc3 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -182,4 +182,6 @@ source "drivers/ras/Kconfig" source "drivers/thunderbolt/Kconfig" +source "drivers/android/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index ebee55537a05..60d19820a4d4 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -161,3 +161,4 @@ obj-$(CONFIG_POWERCAP) += powercap/ obj-$(CONFIG_MCB) += mcb/ obj-$(CONFIG_RAS) += ras/ obj-$(CONFIG_THUNDERBOLT) += thunderbolt/ +obj-$(CONFIG_ANDROID) += android/ diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig new file mode 100644 index 000000000000..bdfc6c6f4f5a --- /dev/null +++ b/drivers/android/Kconfig @@ -0,0 +1,37 @@ +menu "Android" + +config ANDROID + bool "Android Drivers" + ---help--- + Enable support for various drivers needed on the Android platform + +if ANDROID + +config ANDROID_BINDER_IPC + bool "Android Binder IPC Driver" + depends on MMU + default n + ---help--- + Binder is used in Android for both communication between processes, + and remote method invocation. + + This means one Android process can call a method/routine in another + Android process, using Binder to identify, invoke and pass arguments + between said processes. + +config ANDROID_BINDER_IPC_32BIT + bool + depends on !64BIT && ANDROID_BINDER_IPC + default y + ---help--- + The Binder API has been changed to support both 32 and 64bit + applications in a mixed environment. + + Enable this to support an old 32-bit Android user-space (v4.4 and + earlier). + + Note that enabling this will break newer Android user-space. + +endif # if ANDROID + +endmenu diff --git a/drivers/android/Makefile b/drivers/android/Makefile new file mode 100644 index 000000000000..3b7e4b072c58 --- /dev/null +++ b/drivers/android/Makefile @@ -0,0 +1,3 @@ +ccflags-y += -I$(src) # needed for trace events + +obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o diff --git a/drivers/staging/android/binder.c b/drivers/android/binder.c similarity index 100% rename from drivers/staging/android/binder.c rename to drivers/android/binder.c diff --git a/drivers/staging/android/binder.h b/drivers/android/binder.h similarity index 95% rename from drivers/staging/android/binder.h rename to drivers/android/binder.h index eb0834656dfe..5dc6a66b0665 100644 --- a/drivers/staging/android/binder.h +++ b/drivers/android/binder.h @@ -24,7 +24,7 @@ #define BINDER_IPC_32BIT 1 #endif -#include "uapi/binder.h" +#include #endif /* _LINUX_BINDER_H */ diff --git a/drivers/staging/android/binder_trace.h b/drivers/android/binder_trace.h similarity index 100% rename from drivers/staging/android/binder_trace.h rename to drivers/android/binder_trace.h diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 7a0e28852965..7e012f37792b 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -1,37 +1,7 @@ menu "Android" -config ANDROID - bool "Android Drivers" - ---help--- - Enable support for various drivers needed on the Android platform - if ANDROID -config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - depends on MMU - default n - ---help--- - Binder is used in Android for both communication between processes, - and remote method invocation. - - This means one Android process can call a method/routine in another - Android process, using Binder to identify, invoke and pass arguments - between said processes. - -config ANDROID_BINDER_IPC_32BIT - bool - depends on !64BIT && ANDROID_BINDER_IPC - default y - ---help--- - The Binder API has been changed to support both 32 and 64bit - applications in a mixed environment. - - Enable this to support an old 32-bit Android user-space (v4.4 and - earlier). - - Note that enabling this will break newer Android user-space. - config ASHMEM bool "Enable the Anonymous Shared Memory Subsystem" default n diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 517ad5ffa429..479b2b86f8c8 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -2,7 +2,6 @@ ccflags-y += -I$(src) # needed for trace events obj-y += ion/ -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 6cad97485bad..5f17fa7bc153 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -1,4 +1,5 @@ # UAPI Header export list +header-y += android/ header-y += byteorder/ header-y += can/ header-y += caif/ diff --git a/include/uapi/linux/android/Kbuild b/include/uapi/linux/android/Kbuild new file mode 100644 index 000000000000..ca011eec252a --- /dev/null +++ b/include/uapi/linux/android/Kbuild @@ -0,0 +1,2 @@ +# UAPI Header export list +header-y += binder.h diff --git a/drivers/staging/android/uapi/binder.h b/include/uapi/linux/android/binder.h similarity index 100% rename from drivers/staging/android/uapi/binder.h rename to include/uapi/linux/android/binder.h -- GitLab From bc2d62a01b336983b8abd1cb2337f305352f29ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Oct 2014 15:22:30 +0200 Subject: [PATCH 0525/9457] android: uapi: binder.h add types.h to .h file to pass the checker scripts, and provide a proper uapi .h file. Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/android/binder.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h index dba4cef3a8d3..41420e341e75 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -20,6 +20,7 @@ #ifndef _UAPI_LINUX_BINDER_H #define _UAPI_LINUX_BINDER_H +#include #include #define B_PACK_CHARS(c1, c2, c3, c4) \ -- GitLab From 9246a4a98a01bafc017118bb2512d394d040fcbe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Oct 2014 15:26:51 +0200 Subject: [PATCH 0526/9457] android: binder: remove binder.h binder.h isn't needed to just include a uapi file and set a single define, so move it into binder.c to save a few lines of code. Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 6 +++++- drivers/android/binder.h | 30 ------------------------------ 2 files changed, 5 insertions(+), 31 deletions(-) delete mode 100644 drivers/android/binder.h diff --git a/drivers/android/binder.c b/drivers/android/binder.c index c69c40d69d5c..8c43521d3f11 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -38,7 +38,11 @@ #include #include -#include "binder.h" +#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT +#define BINDER_IPC_32BIT 1 +#endif + +#include #include "binder_trace.h" static DEFINE_MUTEX(binder_main_lock); diff --git a/drivers/android/binder.h b/drivers/android/binder.h deleted file mode 100644 index 5dc6a66b0665..000000000000 --- a/drivers/android/binder.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_BINDER_H -#define _LINUX_BINDER_H - -#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT -#define BINDER_IPC_32BIT 1 -#endif - -#include - -#endif /* _LINUX_BINDER_H */ - -- GitLab From 6ffb16475c99b59a5db1a127f1b82084840c0779 Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Tue, 30 Sep 2014 22:22:47 -0500 Subject: [PATCH 0527/9457] staging: skein: Whitespace cleanup Pretties up multiline #defines and many other whitespace issues Signed-off-by: Eric Rost Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_block.c | 585 +++++++++++++++------------- 1 file changed, 315 insertions(+), 270 deletions(-) diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 616364faf92e..71c14f58efdc 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -26,15 +26,18 @@ #define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ #endif -#define BLK_BITS (WCNT*64) /* some useful definitions for code here */ +#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ #define KW_TWK_BASE (0) #define KW_KEY_BASE (3) #define ks (kw + KW_KEY_BASE) #define ts (kw + KW_TWK_BASE) #ifdef SKEIN_DEBUG -#define debug_save_tweak(ctx) { \ - ctx->h.tweak[0] = ts[0]; ctx->h.tweak[1] = ts[1]; } +#define debug_save_tweak(ctx) \ +{ \ + ctx->h.tweak[0] = ts[0]; \ + ctx->h.tweak[1] = ts[1]; \ +} #else #define debug_save_tweak(ctx) #endif @@ -43,15 +46,15 @@ #if !(SKEIN_USE_ASM & 256) void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, size_t blk_cnt, size_t byte_cnt_add) - { /* do it in C */ +{ /* do it in C */ enum { WCNT = SKEIN_256_STATE_WORDS }; #undef RCNT -#define RCNT (SKEIN_256_ROUNDS_TOTAL/8) +#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10) +#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) #else #define SKEIN_UNROLL_256 (0) #endif @@ -96,7 +99,8 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, debug_save_tweak(ctx); skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - X0 = w[0] + ks[0]; /* do the first full key injection */ + /* do the first full key injection */ + X0 = w[0] + ks[0]; X1 = w[1] + ks[1] + ts[0]; X2 = w[2] + ks[2] + ts[1]; X3 = w[3] + ks[3]; @@ -109,29 +113,34 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, /* run the rounds */ -#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ +#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ } while (0) #if SKEIN_UNROLL_256 == 0 #define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ -do { \ - ROUND256(p0, p1, p2, p3, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ +do { \ + ROUND256(p0, p1, p2, p3, ROT, r_num); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ } while (0) -#define I256(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[((R)+1) % 5]; \ - X1 += ks[((R)+2) % 5] + ts[((R)+1) % 3]; \ - X2 += ks[((R)+3) % 5] + ts[((R)+2) % 3]; \ - X3 += ks[((R)+4) % 5] + (R)+1; \ +#define I256(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 5]; \ + X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ + X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ + X3 += ks[((R) + 4) % 5] + (R) + 1; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) -#else /* looping version */ +#else +/* looping version */ #define R256(p0, p1, p2, p3, ROT, r_num) \ do { \ ROUND256(p0, p1, p2, p3, ROT, r_num); \ @@ -141,85 +150,85 @@ do { \ #define I256(R) \ do { \ /* inject the key schedule value */ \ - X0 += ks[r+(R)+0]; \ - X1 += ks[r+(R)+1] + ts[r+(R)+0]; \ - X2 += ks[r+(R)+2] + ts[r+(R)+1]; \ - X3 += ks[r+(R)+3] + r+(R); \ - /* rotate key schedule */ \ - ks[r + (R) + 4] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1] + ts[r + (R) + 0]; \ + X2 += ks[r + (R) + 2] + ts[r + (R) + 1]; \ + X3 += ks[r + (R) + 3] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 4] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_256) #endif { -#define R256_8_ROUNDS(R) \ -do { \ +#define R256_8_ROUNDS(R) \ +do { \ R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ - I256(2 * (R)); \ + I256(2 * (R)); \ R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ - I256(2 * (R) + 1); \ + I256(2 * (R) + 1); \ } while (0) R256_8_ROUNDS(0); -#define R256_UNROLL_R(NN) \ - ((SKEIN_UNROLL_256 == 0 && \ - SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_256 > (NN))) +#define R256_UNROLL_R(NN) \ + ((SKEIN_UNROLL_256 == 0 && \ + SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_256 > (NN))) - #if R256_UNROLL_R(1) +#if R256_UNROLL_R(1) R256_8_ROUNDS(1); - #endif - #if R256_UNROLL_R(2) +#endif +#if R256_UNROLL_R(2) R256_8_ROUNDS(2); - #endif - #if R256_UNROLL_R(3) +#endif +#if R256_UNROLL_R(3) R256_8_ROUNDS(3); - #endif - #if R256_UNROLL_R(4) +#endif +#if R256_UNROLL_R(4) R256_8_ROUNDS(4); - #endif - #if R256_UNROLL_R(5) +#endif +#if R256_UNROLL_R(5) R256_8_ROUNDS(5); - #endif - #if R256_UNROLL_R(6) +#endif +#if R256_UNROLL_R(6) R256_8_ROUNDS(6); - #endif - #if R256_UNROLL_R(7) +#endif +#if R256_UNROLL_R(7) R256_8_ROUNDS(7); - #endif - #if R256_UNROLL_R(8) +#endif +#if R256_UNROLL_R(8) R256_8_ROUNDS(8); - #endif - #if R256_UNROLL_R(9) +#endif +#if R256_UNROLL_R(9) R256_8_ROUNDS(9); - #endif - #if R256_UNROLL_R(10) +#endif +#if R256_UNROLL_R(10) R256_8_ROUNDS(10); - #endif - #if R256_UNROLL_R(11) +#endif +#if R256_UNROLL_R(11) R256_8_ROUNDS(11); - #endif - #if R256_UNROLL_R(12) +#endif +#if R256_UNROLL_R(12) R256_8_ROUNDS(12); - #endif - #if R256_UNROLL_R(13) +#endif +#if R256_UNROLL_R(13) R256_8_ROUNDS(13); - #endif - #if R256_UNROLL_R(14) +#endif +#if R256_UNROLL_R(14) R256_8_ROUNDS(14); - #endif - #if (SKEIN_UNROLL_256 > 14) +#endif +#if (SKEIN_UNROLL_256 > 14) #error "need more unrolling in skein_256_process_block" - #endif +#endif } /* do the final "feedforward" xor, update context chaining */ ctx->x[0] = X0 ^ w[0]; @@ -312,7 +321,8 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, debug_save_tweak(ctx); skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - X0 = w[0] + ks[0]; /* do the first full key injection */ + /* do the first full key injection */ + X0 = w[0] + ks[0]; X1 = w[1] + ks[1]; X2 = w[2] + ks[2]; X3 = w[3] + ks[3]; @@ -327,62 +337,70 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, X_ptr); /* run the rounds */ #define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ - X##p4 += X##p5; X##p5 = rotl_64(X##p5, ROT##_2); X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); X##p7 ^= X##p6; \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ } while (0) #if SKEIN_UNROLL_512 == 0 #define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ } while (0) -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 9]; \ - X1 += ks[((R) + 2) % 9]; \ - X2 += ks[((R) + 3) % 9]; \ - X3 += ks[((R) + 4) % 9]; \ - X4 += ks[((R) + 5) % 9]; \ - X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ - X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ - X7 += ks[((R) + 8) % 9] + (R) + 1; \ +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 9]; \ + X1 += ks[((R) + 2) % 9]; \ + X2 += ks[((R) + 3) % 9]; \ + X3 += ks[((R) + 4) % 9]; \ + X4 += ks[((R) + 5) % 9]; \ + X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ + X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ + X7 += ks[((R) + 8) % 9] + (R) + 1; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) + #else /* looping version */ -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ } while (0) -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1]; \ - X2 += ks[r + (R) + 2]; \ - X3 += ks[r + (R) + 3]; \ - X4 += ks[r + (R) + 4]; \ - X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ - X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ - X7 += ks[r + (R) + 7] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 8] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1]; \ + X2 += ks[r + (R) + 2]; \ + X3 += ks[r + (R) + 3]; \ + X4 += ks[r + (R) + 4]; \ + X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ + X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ + X7 += ks[r + (R) + 7] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 8] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_512) #endif /* end of looped code definitions */ { -#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ -do { \ +#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ +do { \ R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ @@ -392,61 +410,61 @@ do { \ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ - I512(2 * (R) + 1); /* and key injection */ \ + I512(2 * (R) + 1); /* and key injection */ \ } while (0) R512_8_ROUNDS(0); -#define R512_UNROLL_R(NN) \ - ((SKEIN_UNROLL_512 == 0 && \ - SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_512 > (NN))) +#define R512_UNROLL_R(NN) \ + ((SKEIN_UNROLL_512 == 0 && \ + SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_512 > (NN))) - #if R512_UNROLL_R(1) +#if R512_UNROLL_R(1) R512_8_ROUNDS(1); - #endif - #if R512_UNROLL_R(2) +#endif +#if R512_UNROLL_R(2) R512_8_ROUNDS(2); - #endif - #if R512_UNROLL_R(3) +#endif +#if R512_UNROLL_R(3) R512_8_ROUNDS(3); - #endif - #if R512_UNROLL_R(4) +#endif +#if R512_UNROLL_R(4) R512_8_ROUNDS(4); - #endif - #if R512_UNROLL_R(5) +#endif +#if R512_UNROLL_R(5) R512_8_ROUNDS(5); - #endif - #if R512_UNROLL_R(6) +#endif +#if R512_UNROLL_R(6) R512_8_ROUNDS(6); - #endif - #if R512_UNROLL_R(7) +#endif +#if R512_UNROLL_R(7) R512_8_ROUNDS(7); - #endif - #if R512_UNROLL_R(8) +#endif +#if R512_UNROLL_R(8) R512_8_ROUNDS(8); - #endif - #if R512_UNROLL_R(9) +#endif +#if R512_UNROLL_R(9) R512_8_ROUNDS(9); - #endif - #if R512_UNROLL_R(10) +#endif +#if R512_UNROLL_R(10) R512_8_ROUNDS(10); - #endif - #if R512_UNROLL_R(11) +#endif +#if R512_UNROLL_R(11) R512_8_ROUNDS(11); - #endif - #if R512_UNROLL_R(12) +#endif +#if R512_UNROLL_R(12) R512_8_ROUNDS(12); - #endif - #if R512_UNROLL_R(13) +#endif +#if R512_UNROLL_R(13) R512_8_ROUNDS(13); - #endif - #if R512_UNROLL_R(14) +#endif +#if R512_UNROLL_R(14) R512_8_ROUNDS(14); - #endif - #if (SKEIN_UNROLL_512 > 14) +#endif +#if (SKEIN_UNROLL_512 > 14) #error "need more unrolling in skein_512_process_block" - #endif +#endif } /* do the final "feedforward" xor, update context chaining */ @@ -513,11 +531,21 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, #ifdef SKEIN_DEBUG const u64 *X_ptr[16]; /* use for debugging (help cc put Xn in regs) */ - X_ptr[0] = &X00; X_ptr[1] = &X01; X_ptr[2] = &X02; - X_ptr[3] = &X03; X_ptr[4] = &X04; X_ptr[5] = &X05; - X_ptr[6] = &X06; X_ptr[7] = &X07; X_ptr[8] = &X08; - X_ptr[9] = &X09; X_ptr[10] = &X10; X_ptr[11] = &X11; - X_ptr[12] = &X12; X_ptr[13] = &X13; X_ptr[14] = &X14; + X_ptr[0] = &X00; + X_ptr[1] = &X01; + X_ptr[2] = &X02; + X_ptr[3] = &X03; + X_ptr[4] = &X04; + X_ptr[5] = &X05; + X_ptr[6] = &X06; + X_ptr[7] = &X07; + X_ptr[8] = &X08; + X_ptr[9] = &X09; + X_ptr[10] = &X10; + X_ptr[11] = &X11; + X_ptr[12] = &X12; + X_ptr[13] = &X13; + X_ptr[14] = &X14; X_ptr[15] = &X15; #endif @@ -548,192 +576,209 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, ks[13] = ctx->x[13]; ks[14] = ctx->x[14]; ks[15] = ctx->x[15]; - ks[16] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ - ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ - ks[8] ^ ks[9] ^ ks[10] ^ ks[11] ^ + ks[16] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ + ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ + ks[8] ^ ks[9] ^ ks[10] ^ ks[11] ^ ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY; - ts[2] = ts[0] ^ ts[1]; + ts[2] = ts[0] ^ ts[1]; /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - X00 = w[0] + ks[0]; /* do the first full key injection */ - X01 = w[1] + ks[1]; - X02 = w[2] + ks[2]; - X03 = w[3] + ks[3]; - X04 = w[4] + ks[4]; - X05 = w[5] + ks[5]; - X06 = w[6] + ks[6]; - X07 = w[7] + ks[7]; - X08 = w[8] + ks[8]; - X09 = w[9] + ks[9]; - X10 = w[10] + ks[10]; - X11 = w[11] + ks[11]; - X12 = w[12] + ks[12]; - X13 = w[13] + ks[13] + ts[0]; - X14 = w[14] + ks[14] + ts[1]; - X15 = w[15] + ks[15]; + /* do the first full key injection */ + X00 = w[0] + ks[0]; + X01 = w[1] + ks[1]; + X02 = w[2] + ks[2]; + X03 = w[3] + ks[3]; + X04 = w[4] + ks[4]; + X05 = w[5] + ks[5]; + X06 = w[6] + ks[6]; + X07 = w[7] + ks[7]; + X08 = w[8] + ks[8]; + X09 = w[9] + ks[9]; + X10 = w[10] + ks[10]; + X11 = w[11] + ks[11]; + X12 = w[12] + ks[12]; + X13 = w[13] + ks[13] + ts[0]; + X14 = w[14] + ks[14] + ts[1]; + X15 = w[15] + ks[15]; skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, X_ptr); #define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, r_num) \ -do { \ - X##p0 += X##p1; X##p1 = rotl_64(X##p1, ROT##_0); X##p1 ^= X##p0; \ - X##p2 += X##p3; X##p3 = rotl_64(X##p3, ROT##_1); X##p3 ^= X##p2; \ - X##p4 += X##p5; X##p5 = rotl_64(X##p5, ROT##_2); X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); X##p7 ^= X##p6; \ - X##p8 += X##p9; X##p9 = rotl_64(X##p9, ROT##_4); X##p9 ^= X##p8; \ - X##pA += X##pB; X##pB = rotl_64(X##pB, ROT##_5); X##pB ^= X##pA; \ - X##pC += X##pD; X##pD = rotl_64(X##pD, ROT##_6); X##pD ^= X##pC; \ - X##pE += X##pF; X##pF = rotl_64(X##pF, ROT##_7); X##pF ^= X##pE; \ + pF, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + X##p8 += X##p9; \ + X##p9 = rotl_64(X##p9, ROT##_4); \ + X##p9 ^= X##p8; \ + X##pA += X##pB; \ + X##pB = rotl_64(X##pB, ROT##_5); \ + X##pB ^= X##pA; \ + X##pC += X##pD; \ + X##pD = rotl_64(X##pD, ROT##_6); \ + X##pD ^= X##pC; \ + X##pE += X##pF; \ + X##pF = rotl_64(X##pF, ROT##_7); \ + X##pF ^= X##pE; \ } while (0) #if SKEIN_UNROLL_1024 == 0 #define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ + ROT, rn) \ +do { \ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ + pF, ROT, rn); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ } while (0) -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[((R) + 1) % 17]; \ - X01 += ks[((R) + 2) % 17]; \ - X02 += ks[((R) + 3) % 17]; \ - X03 += ks[((R) + 4) % 17]; \ - X04 += ks[((R) + 5) % 17]; \ - X05 += ks[((R) + 6) % 17]; \ - X06 += ks[((R) + 7) % 17]; \ - X07 += ks[((R) + 8) % 17]; \ - X08 += ks[((R) + 9) % 17]; \ - X09 += ks[((R) + 10) % 17]; \ - X10 += ks[((R) + 11) % 17]; \ - X11 += ks[((R) + 12) % 17]; \ - X12 += ks[((R) + 13) % 17]; \ - X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ - X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ - X15 += ks[((R) + 16) % 17] + (R) + 1; \ +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[((R) + 1) % 17]; \ + X01 += ks[((R) + 2) % 17]; \ + X02 += ks[((R) + 3) % 17]; \ + X03 += ks[((R) + 4) % 17]; \ + X04 += ks[((R) + 5) % 17]; \ + X05 += ks[((R) + 6) % 17]; \ + X06 += ks[((R) + 7) % 17]; \ + X07 += ks[((R) + 8) % 17]; \ + X08 += ks[((R) + 9) % 17]; \ + X09 += ks[((R) + 10) % 17]; \ + X10 += ks[((R) + 11) % 17]; \ + X11 += ks[((R) + 12) % 17]; \ + X12 += ks[((R) + 13) % 17]; \ + X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ + X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ + X15 += ks[((R) + 16) % 17] + (R) + 1; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #else /* looping version */ #define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ + ROT, rn) \ +do { \ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ + pF, ROT, rn); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ } while (0) -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[r + (R) + 0]; \ - X01 += ks[r + (R) + 1]; \ - X02 += ks[r + (R) + 2]; \ - X03 += ks[r + (R) + 3]; \ - X04 += ks[r + (R) + 4]; \ - X05 += ks[r + (R) + 5]; \ - X06 += ks[r + (R) + 6]; \ - X07 += ks[r + (R) + 7]; \ - X08 += ks[r + (R) + 8]; \ - X09 += ks[r + (R) + 9]; \ - X10 += ks[r + (R) + 10]; \ - X11 += ks[r + (R) + 11]; \ - X12 += ks[r + (R) + 12]; \ - X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ - X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ - X15 += ks[r + (R) + 15] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 16] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[r + (R) + 0]; \ + X01 += ks[r + (R) + 1]; \ + X02 += ks[r + (R) + 2]; \ + X03 += ks[r + (R) + 3]; \ + X04 += ks[r + (R) + 4]; \ + X05 += ks[r + (R) + 5]; \ + X06 += ks[r + (R) + 6]; \ + X07 += ks[r + (R) + 7]; \ + X08 += ks[r + (R) + 8]; \ + X09 += ks[r + (R) + 9]; \ + X10 += ks[r + (R) + 10]; \ + X11 += ks[r + (R) + 11]; \ + X12 += ks[r + (R) + 12]; \ + X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ + X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ + X15 += ks[r + (R) + 15] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 16] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ skein_show_r_ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) for (r = 1; r <= 2 * RCNT; r += 2 * SKEIN_UNROLL_1024) #endif { -#define R1024_8_ROUNDS(R) \ -do { \ +#define R1024_8_ROUNDS(R) \ +do { \ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_0, 8*(R) + 1); \ + R1024_0, 8*(R) + 1); \ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_1, 8*(R) + 2); \ + R1024_1, 8*(R) + 2); \ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_2, 8*(R) + 3); \ + R1024_2, 8*(R) + 3); \ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_3, 8*(R) + 4); \ - I1024(2*(R)); \ + R1024_3, 8*(R) + 4); \ + I1024(2*(R)); \ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_4, 8*(R) + 5); \ + R1024_4, 8*(R) + 5); \ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_5, 8*(R) + 6); \ + R1024_5, 8*(R) + 6); \ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_6, 8*(R) + 7); \ + R1024_6, 8*(R) + 7); \ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_7, 8*(R) + 8); \ - I1024(2*(R)+1); \ + R1024_7, 8*(R) + 8); \ + I1024(2*(R)+1); \ } while (0) R1024_8_ROUNDS(0); -#define R1024_UNROLL_R(NN) \ - ((SKEIN_UNROLL_1024 == 0 && \ - SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_1024 > (NN))) +#define R1024_UNROLL_R(NN) \ + ((SKEIN_UNROLL_1024 == 0 && \ + SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_1024 > (NN))) - #if R1024_UNROLL_R(1) +#if R1024_UNROLL_R(1) R1024_8_ROUNDS(1); - #endif - #if R1024_UNROLL_R(2) +#endif +#if R1024_UNROLL_R(2) R1024_8_ROUNDS(2); - #endif - #if R1024_UNROLL_R(3) +#endif +#if R1024_UNROLL_R(3) R1024_8_ROUNDS(3); - #endif - #if R1024_UNROLL_R(4) +#endif +#if R1024_UNROLL_R(4) R1024_8_ROUNDS(4); - #endif - #if R1024_UNROLL_R(5) +#endif +#if R1024_UNROLL_R(5) R1024_8_ROUNDS(5); - #endif - #if R1024_UNROLL_R(6) +#endif +#if R1024_UNROLL_R(6) R1024_8_ROUNDS(6); - #endif - #if R1024_UNROLL_R(7) +#endif +#if R1024_UNROLL_R(7) R1024_8_ROUNDS(7); - #endif - #if R1024_UNROLL_R(8) +#endif +#if R1024_UNROLL_R(8) R1024_8_ROUNDS(8); - #endif - #if R1024_UNROLL_R(9) +#endif +#if R1024_UNROLL_R(9) R1024_8_ROUNDS(9); - #endif - #if R1024_UNROLL_R(10) +#endif +#if R1024_UNROLL_R(10) R1024_8_ROUNDS(10); - #endif - #if R1024_UNROLL_R(11) +#endif +#if R1024_UNROLL_R(11) R1024_8_ROUNDS(11); - #endif - #if R1024_UNROLL_R(12) +#endif +#if R1024_UNROLL_R(12) R1024_8_ROUNDS(12); - #endif - #if R1024_UNROLL_R(13) +#endif +#if R1024_UNROLL_R(13) R1024_8_ROUNDS(13); - #endif - #if R1024_UNROLL_R(14) +#endif +#if R1024_UNROLL_R(14) R1024_8_ROUNDS(14); - #endif +#endif #if (SKEIN_UNROLL_1024 > 14) #error "need more unrolling in Skein_1024_Process_Block" - #endif + #endif } /* do the final "feedforward" xor, update context chaining */ -- GitLab From 468d958d2478c5dca4eb08c34cdb5c2a1436ad79 Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Tue, 30 Sep 2014 22:23:23 -0500 Subject: [PATCH 0528/9457] staging: skein: File Reorg Reorganizes file to remove #defines from middle of functions. Also removes #if'd loop declarations and adds ternary if driven loops. Signed-off-by: Eric Rost Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_block.c | 680 ++++++++++++++-------------- 1 file changed, 351 insertions(+), 329 deletions(-) diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 71c14f58efdc..88bc718ae5b6 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -42,17 +42,9 @@ #define debug_save_tweak(ctx) #endif -/***************************** SKEIN_256 ******************************/ #if !(SKEIN_USE_ASM & 256) -void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, - size_t blk_cnt, size_t byte_cnt_add) -{ /* do it in C */ - enum { - WCNT = SKEIN_256_STATE_WORDS - }; #undef RCNT #define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) - #ifdef SKEIN_LOOP /* configure how much to unroll the loop */ #define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) #else @@ -63,56 +55,7 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, #if (RCNT % SKEIN_UNROLL_256) #error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ #endif - size_t r; - u64 kw[WCNT+4+RCNT*2]; /* key schedule: chaining vars + tweak + "rot"*/ -#else - u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ -#endif - u64 X0, X1, X2, X3; /* local copy of context vars, for speed */ - u64 w[WCNT]; /* local copy of input block */ -#ifdef SKEIN_DEBUG - const u64 *X_ptr[4]; /* use for debugging (help cc put Xn in regs) */ - - X_ptr[0] = &X0; X_ptr[1] = &X1; X_ptr[2] = &X2; X_ptr[3] = &X3; #endif - skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ - ts[0] = ctx->h.tweak[0]; - ts[1] = ctx->h.tweak[1]; - do { - /* - * this implementation only supports 2**64 input bytes - * (no carry out here) - */ - ts[0] += byte_cnt_add; /* update processed length */ - - /* precompute the key schedule for this block */ - ks[0] = ctx->x[0]; - ks[1] = ctx->x[1]; - ks[2] = ctx->x[2]; - ks[3] = ctx->x[3]; - ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY; - - ts[2] = ts[0] ^ ts[1]; - - /* get input block in little-endian format */ - skein_get64_lsb_first(w, blk_ptr, WCNT); - debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); - - /* do the first full key injection */ - X0 = w[0] + ks[0]; - X1 = w[1] + ks[1] + ts[0]; - X2 = w[2] + ks[2] + ts[1]; - X3 = w[3] + ks[3]; - - /* show starting state values */ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - x_ptr); - - blk_ptr += SKEIN_256_BLOCK_BYTES; - - /* run the rounds */ - #define ROUND256(p0, p1, p2, p3, ROT, r_num) \ do { \ X##p0 += X##p1; \ @@ -159,10 +102,7 @@ do { \ ts[r + (R) + 2] = ts[r + (R) - 1]; \ skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) - - for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_256) #endif - { #define R256_8_ROUNDS(R) \ do { \ R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ @@ -177,57 +117,362 @@ do { \ I256(2 * (R) + 1); \ } while (0) - R256_8_ROUNDS(0); +#define R256_UNROLL_R(NN) \ + ((SKEIN_UNROLL_256 == 0 && \ + SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_256 > (NN))) + +#if (SKEIN_UNROLL_256 > 14) +#error "need more unrolling in skein_256_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 512) +#undef RCNT +#define RCNT (SKEIN_512_ROUNDS_TOTAL/8) + +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) +#else +#define SKEIN_UNROLL_512 (0) +#endif + +#if SKEIN_UNROLL_512 +#if (RCNT % SKEIN_UNROLL_512) +#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ +#endif +#endif +#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ +} while (0) + +#if SKEIN_UNROLL_512 == 0 +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ +} while (0) + +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 9]; \ + X1 += ks[((R) + 2) % 9]; \ + X2 += ks[((R) + 3) % 9]; \ + X3 += ks[((R) + 4) % 9]; \ + X4 += ks[((R) + 5) % 9]; \ + X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ + X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ + X7 += ks[((R) + 8) % 9] + (R) + 1; \ + skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ +} while (0) + +#else /* looping version */ +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ +do { \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ +} while (0) + +#define I512(R) \ +do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1]; \ + X2 += ks[r + (R) + 2]; \ + X3 += ks[r + (R) + 3]; \ + X4 += ks[r + (R) + 4]; \ + X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ + X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ + X7 += ks[r + (R) + 7] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 8] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ +} while (0) +#endif /* end of looped code definitions */ +#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ +do { \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ + I512(2 * (R)); \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ + I512(2 * (R) + 1); /* and key injection */ \ +} while (0) +#define R512_UNROLL_R(NN) \ + ((SKEIN_UNROLL_512 == 0 && \ + SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_512 > (NN))) + +#if (SKEIN_UNROLL_512 > 14) +#error "need more unrolling in skein_512_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 1024) +#undef RCNT +#define RCNT (SKEIN_1024_ROUNDS_TOTAL/8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) +#else +#define SKEIN_UNROLL_1024 (0) +#endif + +#if (SKEIN_UNROLL_1024 != 0) +#if (RCNT % SKEIN_UNROLL_1024) +#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ +#endif +#endif +#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, r_num) \ +do { \ + X##p0 += X##p1; \ + X##p1 = rotl_64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rotl_64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rotl_64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rotl_64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + X##p8 += X##p9; \ + X##p9 = rotl_64(X##p9, ROT##_4); \ + X##p9 ^= X##p8; \ + X##pA += X##pB; \ + X##pB = rotl_64(X##pB, ROT##_5); \ + X##pB ^= X##pA; \ + X##pC += X##pD; \ + X##pD = rotl_64(X##pD, ROT##_6); \ + X##pD ^= X##pC; \ + X##pE += X##pF; \ + X##pF = rotl_64(X##pF, ROT##_7); \ + X##pF ^= X##pE; \ +} while (0) + +#if SKEIN_UNROLL_1024 == 0 +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ +do { \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ +} while (0) + +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[((R) + 1) % 17]; \ + X01 += ks[((R) + 2) % 17]; \ + X02 += ks[((R) + 3) % 17]; \ + X03 += ks[((R) + 4) % 17]; \ + X04 += ks[((R) + 5) % 17]; \ + X05 += ks[((R) + 6) % 17]; \ + X06 += ks[((R) + 7) % 17]; \ + X07 += ks[((R) + 8) % 17]; \ + X08 += ks[((R) + 9) % 17]; \ + X09 += ks[((R) + 10) % 17]; \ + X10 += ks[((R) + 11) % 17]; \ + X11 += ks[((R) + 12) % 17]; \ + X12 += ks[((R) + 13) % 17]; \ + X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ + X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ + X15 += ks[((R) + 16) % 17] + (R) + 1; \ + skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ +} while (0) +#else /* looping version */ +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ +do { \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn); \ + skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ +} while (0) + +#define I1024(R) \ +do { \ + /* inject the key schedule value */ \ + X00 += ks[r + (R) + 0]; \ + X01 += ks[r + (R) + 1]; \ + X02 += ks[r + (R) + 2]; \ + X03 += ks[r + (R) + 3]; \ + X04 += ks[r + (R) + 4]; \ + X05 += ks[r + (R) + 5]; \ + X06 += ks[r + (R) + 6]; \ + X07 += ks[r + (R) + 7]; \ + X08 += ks[r + (R) + 8]; \ + X09 += ks[r + (R) + 9]; \ + X10 += ks[r + (R) + 10]; \ + X11 += ks[r + (R) + 11]; \ + X12 += ks[r + (R) + 12]; \ + X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ + X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ + X15 += ks[r + (R) + 15] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 16] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + skein_show_r_ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ +} while (0) + +#endif +#define R1024_8_ROUNDS(R) \ +do { \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ + R1024_0, 8*(R) + 1); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ + R1024_1, 8*(R) + 2); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ + R1024_2, 8*(R) + 3); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ + R1024_3, 8*(R) + 4); \ + I1024(2*(R)); \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ + R1024_4, 8*(R) + 5); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ + R1024_5, 8*(R) + 6); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ + R1024_6, 8*(R) + 7); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ + R1024_7, 8*(R) + 8); \ + I1024(2*(R)+1); \ +} while (0) + +#define R1024_UNROLL_R(NN) \ + ((SKEIN_UNROLL_1024 == 0 && \ + SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ + (SKEIN_UNROLL_1024 > (NN))) + +#if (SKEIN_UNROLL_1024 > 14) +#error "need more unrolling in Skein_1024_Process_Block" +#endif +#endif + +/***************************** SKEIN_256 ******************************/ +#if !(SKEIN_USE_ASM & 256) +void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, + size_t blk_cnt, size_t byte_cnt_add) +{ /* do it in C */ + enum { + WCNT = SKEIN_256_STATE_WORDS + }; + size_t r; +#if SKEIN_UNROLL_256 + /* key schedule: chaining vars + tweak + "rot"*/ + u64 kw[WCNT+4+RCNT*2]; +#else + /* key schedule words : chaining vars + tweak */ + u64 kw[WCNT+4]; +#endif + u64 X0, X1, X2, X3; /* local copy of context vars, for speed */ + u64 w[WCNT]; /* local copy of input block */ +#ifdef SKEIN_DEBUG + const u64 *X_ptr[4]; /* use for debugging (help cc put Xn in regs) */ + + X_ptr[0] = &X0; + X_ptr[1] = &X1; + X_ptr[2] = &X2; + X_ptr[3] = &X3; +#endif + skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ + ts[0] = ctx->h.tweak[0]; + ts[1] = ctx->h.tweak[1]; + do { + /* + * this implementation only supports 2**64 input bytes + * (no carry out here) + */ + ts[0] += byte_cnt_add; /* update processed length */ + + /* precompute the key schedule for this block */ + ks[0] = ctx->x[0]; + ks[1] = ctx->x[1]; + ks[2] = ctx->x[2]; + ks[3] = ctx->x[3]; + ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY; + + ts[2] = ts[0] ^ ts[1]; + + /* get input block in little-endian format */ + skein_get64_lsb_first(w, blk_ptr, WCNT); + debug_save_tweak(ctx); + skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); + + /* do the first full key injection */ + X0 = w[0] + ks[0]; + X1 = w[1] + ks[1] + ts[0]; + X2 = w[2] + ks[2] + ts[1]; + X3 = w[3] + ks[3]; -#define R256_UNROLL_R(NN) \ - ((SKEIN_UNROLL_256 == 0 && \ - SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_256 > (NN))) + /* show starting state values */ + skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, + x_ptr); + + blk_ptr += SKEIN_256_BLOCK_BYTES; + /* run the rounds */ + for (r = 1; + r < (SKEIN_UNROLL_256 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_256 ? 2 * SKEIN_UNROLL_256 : 1)) { + R256_8_ROUNDS(0); #if R256_UNROLL_R(1) - R256_8_ROUNDS(1); + R256_8_ROUNDS(1); #endif #if R256_UNROLL_R(2) - R256_8_ROUNDS(2); + R256_8_ROUNDS(2); #endif #if R256_UNROLL_R(3) - R256_8_ROUNDS(3); + R256_8_ROUNDS(3); #endif #if R256_UNROLL_R(4) - R256_8_ROUNDS(4); + R256_8_ROUNDS(4); #endif #if R256_UNROLL_R(5) - R256_8_ROUNDS(5); + R256_8_ROUNDS(5); #endif #if R256_UNROLL_R(6) - R256_8_ROUNDS(6); + R256_8_ROUNDS(6); #endif #if R256_UNROLL_R(7) - R256_8_ROUNDS(7); + R256_8_ROUNDS(7); #endif #if R256_UNROLL_R(8) - R256_8_ROUNDS(8); + R256_8_ROUNDS(8); #endif #if R256_UNROLL_R(9) - R256_8_ROUNDS(9); + R256_8_ROUNDS(9); #endif #if R256_UNROLL_R(10) - R256_8_ROUNDS(10); + R256_8_ROUNDS(10); #endif #if R256_UNROLL_R(11) - R256_8_ROUNDS(11); + R256_8_ROUNDS(11); #endif #if R256_UNROLL_R(12) - R256_8_ROUNDS(12); + R256_8_ROUNDS(12); #endif #if R256_UNROLL_R(13) - R256_8_ROUNDS(13); + R256_8_ROUNDS(13); #endif #if R256_UNROLL_R(14) - R256_8_ROUNDS(14); -#endif -#if (SKEIN_UNROLL_256 > 14) -#error "need more unrolling in skein_256_process_block" + R256_8_ROUNDS(14); #endif } /* do the final "feedforward" xor, update context chaining */ @@ -265,20 +510,8 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, enum { WCNT = SKEIN_512_STATE_WORDS }; -#undef RCNT -#define RCNT (SKEIN_512_ROUNDS_TOTAL/8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10) -#else -#define SKEIN_UNROLL_512 (0) -#endif - -#if SKEIN_UNROLL_512 -#if (RCNT % SKEIN_UNROLL_512) -#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ -#endif size_t r; +#if SKEIN_UNROLL_512 u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot"*/ #else u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ @@ -288,8 +521,14 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, #ifdef SKEIN_DEBUG const u64 *X_ptr[8]; /* use for debugging (help cc put Xn in regs) */ - X_ptr[0] = &X0; X_ptr[1] = &X1; X_ptr[2] = &X2; X_ptr[3] = &X3; - X_ptr[4] = &X4; X_ptr[5] = &X5; X_ptr[6] = &X6; X_ptr[7] = &X7; + X_ptr[0] = &X0; + X_ptr[1] = &X1; + X_ptr[2] = &X2; + X_ptr[3] = &X3; + X_ptr[4] = &X4; + X_ptr[5] = &X5; + X_ptr[6] = &X6; + X_ptr[7] = &X7; #endif skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ @@ -322,104 +561,26 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); /* do the first full key injection */ - X0 = w[0] + ks[0]; - X1 = w[1] + ks[1]; - X2 = w[2] + ks[2]; - X3 = w[3] + ks[3]; - X4 = w[4] + ks[4]; - X5 = w[5] + ks[5] + ts[0]; - X6 = w[6] + ks[6] + ts[1]; - X7 = w[7] + ks[7]; + X0 = w[0] + ks[0]; + X1 = w[1] + ks[1]; + X2 = w[2] + ks[2]; + X3 = w[3] + ks[3]; + X4 = w[4] + ks[4]; + X5 = w[5] + ks[5] + ts[0]; + X6 = w[6] + ks[6] + ts[1]; + X7 = w[7] + ks[7]; blk_ptr += SKEIN_512_BLOCK_BYTES; skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, X_ptr); /* run the rounds */ -#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - X##p0 += X##p1; \ - X##p1 = rotl_64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rotl_64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rotl_64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; X##p7 = rotl_64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ -} while (0) - -#if SKEIN_UNROLL_512 == 0 -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ -} while (0) - -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 9]; \ - X1 += ks[((R) + 2) % 9]; \ - X2 += ks[((R) + 3) % 9]; \ - X3 += ks[((R) + 4) % 9]; \ - X4 += ks[((R) + 5) % 9]; \ - X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ - X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ - X7 += ks[((R) + 8) % 9] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - -#else /* looping version */ -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ -do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ -} while (0) - -#define I512(R) \ -do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1]; \ - X2 += ks[r + (R) + 2]; \ - X3 += ks[r + (R) + 3]; \ - X4 += ks[r + (R) + 4]; \ - X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ - X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ - X7 += ks[r + (R) + 7] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 8] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - - for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_512) -#endif /* end of looped code definitions */ - { -#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ -do { \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ - I512(2 * (R)); \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ - I512(2 * (R) + 1); /* and key injection */ \ -} while (0) + for (r = 1; + r < (SKEIN_UNROLL_512 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_512 ? 2 * SKEIN_UNROLL_512 : 1)) { R512_8_ROUNDS(0); -#define R512_UNROLL_R(NN) \ - ((SKEIN_UNROLL_512 == 0 && \ - SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_512 > (NN))) - #if R512_UNROLL_R(1) R512_8_ROUNDS(1); #endif @@ -461,9 +622,6 @@ do { \ #endif #if R512_UNROLL_R(14) R512_8_ROUNDS(14); -#endif -#if (SKEIN_UNROLL_512 > 14) -#error "need more unrolling in skein_512_process_block" #endif } @@ -505,20 +663,8 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, enum { WCNT = SKEIN_1024_STATE_WORDS }; -#undef RCNT -#define RCNT (SKEIN_1024_ROUNDS_TOTAL/8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10) -#else -#define SKEIN_UNROLL_1024 (0) -#endif - -#if (SKEIN_UNROLL_1024 != 0) -#if (RCNT % SKEIN_UNROLL_1024) -#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ -#endif size_t r; +#if (SKEIN_UNROLL_1024 != 0) u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot" */ #else u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */ @@ -609,131 +755,10 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, X_ptr); -#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, r_num) \ -do { \ - X##p0 += X##p1; \ - X##p1 = rotl_64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rotl_64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rotl_64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; \ - X##p7 = rotl_64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ - X##p8 += X##p9; \ - X##p9 = rotl_64(X##p9, ROT##_4); \ - X##p9 ^= X##p8; \ - X##pA += X##pB; \ - X##pB = rotl_64(X##pB, ROT##_5); \ - X##pB ^= X##pA; \ - X##pC += X##pD; \ - X##pD = rotl_64(X##pD, ROT##_6); \ - X##pD ^= X##pC; \ - X##pE += X##pF; \ - X##pF = rotl_64(X##pF, ROT##_7); \ - X##pF ^= X##pE; \ -} while (0) - -#if SKEIN_UNROLL_1024 == 0 -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ -} while (0) - -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[((R) + 1) % 17]; \ - X01 += ks[((R) + 2) % 17]; \ - X02 += ks[((R) + 3) % 17]; \ - X03 += ks[((R) + 4) % 17]; \ - X04 += ks[((R) + 5) % 17]; \ - X05 += ks[((R) + 6) % 17]; \ - X06 += ks[((R) + 7) % 17]; \ - X07 += ks[((R) + 8) % 17]; \ - X08 += ks[((R) + 9) % 17]; \ - X09 += ks[((R) + 10) % 17]; \ - X10 += ks[((R) + 11) % 17]; \ - X11 += ks[((R) + 12) % 17]; \ - X12 += ks[((R) + 13) % 17]; \ - X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ - X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ - X15 += ks[((R) + 16) % 17] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) -#else /* looping version */ -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ -do { \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ -} while (0) - -#define I1024(R) \ -do { \ - /* inject the key schedule value */ \ - X00 += ks[r + (R) + 0]; \ - X01 += ks[r + (R) + 1]; \ - X02 += ks[r + (R) + 2]; \ - X03 += ks[r + (R) + 3]; \ - X04 += ks[r + (R) + 4]; \ - X05 += ks[r + (R) + 5]; \ - X06 += ks[r + (R) + 6]; \ - X07 += ks[r + (R) + 7]; \ - X08 += ks[r + (R) + 8]; \ - X09 += ks[r + (R) + 9]; \ - X10 += ks[r + (R) + 10]; \ - X11 += ks[r + (R) + 11]; \ - X12 += ks[r + (R) + 12]; \ - X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ - X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ - X15 += ks[r + (R) + 15] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 16] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ -} while (0) - - for (r = 1; r <= 2 * RCNT; r += 2 * SKEIN_UNROLL_1024) -#endif - { -#define R1024_8_ROUNDS(R) \ -do { \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_0, 8*(R) + 1); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_1, 8*(R) + 2); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_2, 8*(R) + 3); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_3, 8*(R) + 4); \ - I1024(2*(R)); \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \ - R1024_4, 8*(R) + 5); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \ - R1024_5, 8*(R) + 6); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \ - R1024_6, 8*(R) + 7); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \ - R1024_7, 8*(R) + 8); \ - I1024(2*(R)+1); \ -} while (0) - + for (r = 1; + r < (SKEIN_UNROLL_1024 ? 2 * RCNT : 2); + r += (SKEIN_UNROLL_1024 ? 2 * SKEIN_UNROLL_1024 : 1)) { R1024_8_ROUNDS(0); - -#define R1024_UNROLL_R(NN) \ - ((SKEIN_UNROLL_1024 == 0 && \ - SKEIN_1024_ROUNDS_TOTAL/8 > (NN)) || \ - (SKEIN_UNROLL_1024 > (NN))) - #if R1024_UNROLL_R(1) R1024_8_ROUNDS(1); #endif @@ -776,9 +801,6 @@ do { \ #if R1024_UNROLL_R(14) R1024_8_ROUNDS(14); #endif -#if (SKEIN_UNROLL_1024 > 14) -#error "need more unrolling in Skein_1024_Process_Block" - #endif } /* do the final "feedforward" xor, update context chaining */ -- GitLab From 68d41f23ce8d049d05bdd96889d3a2504e7f21f0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 29 Sep 2014 17:21:56 +0200 Subject: [PATCH 0529/9457] pinctrl: nomadik: force-convert to generic mux bindings This converts the Nomadik pin controller and all associated device trees to use the standard, generic mux bindings for pin controllers. There are no such device trees deployed in the wild so this is safe to do to set a good example. Signed-off-by: Linus Walleij --- arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi | 28 +++---- .../arm/boot/dts/ste-href-family-pinctrl.dtsi | 80 +++++++++---------- arch/arm/boot/dts/ste-hrefprev60.dtsi | 12 +-- arch/arm/boot/dts/ste-hrefv60plus.dtsi | 4 +- arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 20 ++--- arch/arm/boot/dts/ste-snowball.dts | 12 +-- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 16 ++-- 7 files changed, 88 insertions(+), 84 deletions(-) diff --git a/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi index e0799966bc25..08a7365cb929 100644 --- a/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi +++ b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi @@ -16,8 +16,8 @@ uart0 { uart0_default_mux: uart0_mux { default_mux { - ste,function = "u0"; - ste,pins = "u0_a_1"; + function = "u0"; + groups = "u0_a_1"; }; }; @@ -49,8 +49,8 @@ uart2 { uart2_default_mode: uart2_default { default_mux { - ste,function = "u2"; - ste,pins = "u2txrx_a_1"; + function = "u2"; + groups = "u2txrx_a_1"; }; default_cfg1 { @@ -80,8 +80,8 @@ i2c0 { i2c0_default_mux: i2c_mux { default_mux { - ste,function = "i2c0"; - ste,pins = "i2c0_a_1"; + function = "i2c0"; + groups = "i2c0_a_1"; }; }; @@ -103,8 +103,8 @@ i2c1 { i2c1_default_mux: i2c_mux { default_mux { - ste,function = "i2c1"; - ste,pins = "i2c1_b_2"; + function = "i2c1"; + groups = "i2c1_b_2"; }; }; @@ -126,8 +126,8 @@ i2c2 { i2c2_default_mux: i2c_mux { default_mux { - ste,function = "i2c2"; - ste,pins = "i2c2_b_2"; + function = "i2c2"; + groups = "i2c2_b_2"; }; }; @@ -149,8 +149,8 @@ i2c4 { i2c4_default_mux: i2c_mux { default_mux { - ste,function = "i2c4"; - ste,pins = "i2c4_b_2"; + function = "i2c4"; + groups = "i2c4_b_2"; }; }; @@ -172,8 +172,8 @@ i2c5 { i2c5_default_mux: i2c_mux { default_mux { - ste,function = "i2c5"; - ste,pins = "i2c5_c_2"; + function = "i2c5"; + groups = "i2c5_c_2"; }; }; diff --git a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi index addfcc7c2750..61aa87138927 100644 --- a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi +++ b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi @@ -18,8 +18,8 @@ uart0 { uart0_default_mode: uart0_default { default_mux { - ste,function = "u0"; - ste,pins = "u0_a_1"; + function = "u0"; + groups = "u0_a_1"; }; default_cfg1 { ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ @@ -53,8 +53,8 @@ uart1 { uart1_default_mode: uart1_default { default_mux { - ste,function = "u1"; - ste,pins = "u1rxtx_a_1"; + function = "u1"; + groups = "u1rxtx_a_1"; }; default_cfg1 { ste,pins = "GPIO4_AH6"; /* RXD */ @@ -83,8 +83,8 @@ uart2 { uart2_default_mode: uart2_default { default_mux { - ste,function = "u2"; - ste,pins = "u2rxtx_c_1"; + function = "u2"; + groups = "u2rxtx_c_1"; }; default_cfg1 { ste,pins = "GPIO29_W2"; /* RXD */ @@ -114,8 +114,8 @@ i2c0 { i2c0_default_mode: i2c_default { default_mux { - ste,function = "i2c0"; - ste,pins = "i2c0_a_1"; + function = "i2c0"; + groups = "i2c0_a_1"; }; default_cfg1 { ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ @@ -134,8 +134,8 @@ i2c1 { i2c1_default_mode: i2c_default { default_mux { - ste,function = "i2c1"; - ste,pins = "i2c1_b_2"; + function = "i2c1"; + groups = "i2c1_b_2"; }; default_cfg1 { ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ @@ -154,8 +154,8 @@ i2c2 { i2c2_default_mode: i2c_default { default_mux { - ste,function = "i2c2"; - ste,pins = "i2c2_b_2"; + function = "i2c2"; + groups = "i2c2_b_2"; }; default_cfg1 { ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ @@ -174,8 +174,8 @@ i2c3 { i2c3_default_mode: i2c_default { default_mux { - ste,function = "i2c3"; - ste,pins = "i2c3_c_2"; + function = "i2c3"; + groups = "i2c3_c_2"; }; default_cfg1 { ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ @@ -198,8 +198,8 @@ i2c4 { i2c4_default_mode: i2c_default { default_mux { - ste,function = "i2c4"; - ste,pins = "i2c4_b_1"; + function = "i2c4"; + groups = "i2c4_b_1"; }; default_cfg1 { ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ @@ -219,8 +219,8 @@ spi2 { spi2_default_mode: spi_default { default_mux { - ste,function = "spi2"; - ste,pins = "spi2_oc1_2"; + function = "spi2"; + groups = "spi2_oc1_2"; }; default_cfg1 { ste,pins = "GPIO216_AG12"; /* FRM */ @@ -281,8 +281,8 @@ /* This is the external SD card slot, 4 bits wide */ sdi0_default_mode: sdi0_default { default_mux { - ste,function = "mc0"; - ste,pins = "mc0_a_1"; + function = "mc0"; + groups = "mc0_a_1"; }; default_cfg1 { ste,pins = @@ -339,8 +339,8 @@ /* This is the WLAN SDIO 4 bits wide */ sdi1_default_mode: sdi1_default { default_mux { - ste,function = "mc1"; - ste,pins = "mc1_a_1"; + function = "mc1"; + groups = "mc1_a_1"; }; default_cfg1 { ste,pins = "GPIO208_AH16"; /* CLK */ @@ -383,8 +383,8 @@ /* This is the eMMC 8 bits wide, usually PoP eMMC */ sdi2_default_mode: sdi2_default { default_mux { - ste,function = "mc2"; - ste,pins = "mc2_a_1"; + function = "mc2"; + groups = "mc2_a_1"; }; default_cfg1 { ste,pins = "GPIO128_A5"; /* CLK */ @@ -439,8 +439,8 @@ /* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */ sdi4_default_mode: sdi4_default { default_mux { - ste,function = "mc4"; - ste,pins = "mc4_a_1"; + function = "mc4"; + groups = "mc4_a_1"; }; default_cfg1 { ste,pins = "GPIO203_AE23"; /* CLK */ @@ -494,8 +494,8 @@ msp0 { msp0_default_mode: msp0_default { default_msp0_mux { - ste,function = "msp0"; - ste,pins = "msp0txrx_a_1", "msp0tfstck_a_1"; + function = "msp0"; + groups = "msp0txrx_a_1", "msp0tfstck_a_1"; }; default_msp0_cfg { ste,pins = @@ -511,8 +511,8 @@ msp1 { msp1_default_mode: msp1_default { default_mux { - ste,function = "msp1"; - ste,pins = "msp1txrx_a_1", "msp1_a_1"; + function = "msp1"; + groups = "msp1txrx_a_1", "msp1_a_1"; }; default_cfg1 { ste,pins = "GPIO33_AF2"; @@ -533,8 +533,8 @@ msp2_default_mode: msp2_default { /* MSP2 usually used for HDMI audio */ default_mux { - ste,function = "msp2"; - ste,pins = "msp2_a_1"; + function = "msp2"; + groups = "msp2_a_1"; }; default_cfg1 { ste,pins = @@ -554,8 +554,8 @@ musb { musb_default_mode: musb_default { default_mux { - ste,function = "usb"; - ste,pins = "usb_a_1"; + function = "usb"; + groups = "usb_a_1"; }; default_cfg1 { ste,pins = @@ -609,8 +609,8 @@ lcd_default_mode: lcd_default { default_mux { /* Mux in VSI0 and all the data lines */ - ste,function = "lcd"; - ste,pins = + function = "lcd"; + groups = "lcdvsi0_a_1", /* VSI0 for LCD */ "lcd_d0_d7_a_1", /* Data lines */ "lcd_d8_d11_a_1", /* TV-out */ @@ -636,8 +636,8 @@ /* SKE keys on position 2 in an 8x8 matrix */ ske_kpa2_default_mode: ske_kpa2_default { default_mux { - ste,function = "kp"; - ste,pins = "kp_a_2"; + function = "kp"; + groups = "kp_a_2"; }; default_cfg1 { ste,pins = @@ -696,8 +696,8 @@ */ ske_kpaoc1_default_mode: ske_kpaoc1_default { default_mux { - ste,function = "kp"; - ste,pins = "kp_a_1", "kp_oc1_1"; + function = "kp"; + groups = "kp_a_1", "kp_oc1_1"; }; default_cfg1 { ste,pins = diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi index abc762e24fcb..5d8b7f8ced1b 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dtsi +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -79,8 +79,8 @@ ssp0 { ssp0_hrefprev60_mode: ssp0_hrefprev60_default { hrefprev60_mux { - ste,function = "ssp0"; - ste,pins = "ssp0_a_1"; + function = "ssp0"; + groups = "ssp0_a_1"; }; hrefprev60_cfg1 { ste,pins = "GPIO145_C13"; /* RXD */ @@ -93,8 +93,8 @@ /* This additional pin needed on early MOP500 and HREFs previous to v60 */ sdi0_default_mode: sdi0_default { hrefprev60_mux { - ste,function = "mc0"; - ste,pins = "mc0dat31dir_a_1"; + function = "mc0"; + groups = "mc0dat31dir_a_1"; }; hrefprev60_cfg1 { ste,pins = "GPIO21_AB3"; /* DAT31DIR */ @@ -114,8 +114,8 @@ ipgpio { ipgpio_hrefprev60_mode: ipgpio_hrefprev60 { hrefprev60_mux { - ste,function = "ipgpio"; - ste,pins = "ipgpio0_c_1", "ipgpio1_c_1"; + function = "ipgpio"; + groups = "ipgpio0_c_1", "ipgpio1_c_1"; }; hrefprev60_cfg1 { ste,pins = "GPIO6_AF6", "GPIO7_AG5"; diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi index bcc1f0c37f49..2b4104ef07de 100644 --- a/arch/arm/boot/dts/ste-hrefv60plus.dtsi +++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi @@ -64,8 +64,8 @@ */ ipgpio_hrefv60_mode: ipgpio_hrefv60 { hrefv60_mux { - ste,function = "ipgpio"; - ste,pins = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1"; + function = "ipgpio"; + groups = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1"; }; hrefv60_cfg1 { ste,pins = "GPIO6_AF6", "GPIO7_AG5"; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index dbcf521b017f..7cedb5aba9a9 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -100,24 +100,24 @@ uart0 { uart0_default_mux: uart0_mux { u0_default_mux { - ste,function = "u0"; - ste,pins = "u0_a_1"; + function = "u0"; + groups = "u0_a_1"; }; }; }; uart1 { uart1_default_mux: uart1_mux { u1_default_mux { - ste,function = "u1"; - ste,pins = "u1_a_1"; + function = "u1"; + groups = "u1_a_1"; }; }; }; mmcsd { mmcsd_default_mux: mmcsd_mux { mmcsd_default_mux { - ste,function = "mmcsd"; - ste,pins = "mmcsd_a_1"; + function = "mmcsd"; + groups = "mmcsd_a_1"; }; }; mmcsd_default_mode: mmcsd_default { @@ -144,8 +144,8 @@ i2c0 { i2c0_default_mux: i2c0_mux { i2c0_default_mux { - ste,function = "i2c0"; - ste,pins = "i2c0_a_1"; + function = "i2c0"; + groups = "i2c0_a_1"; }; }; i2c0_default_mode: i2c0_default { @@ -158,8 +158,8 @@ i2c1 { i2c1_default_mux: i2c1_mux { i2c1_default_mux { - ste,function = "i2c1"; - ste,pins = "i2c1_a_1"; + function = "i2c1"; + groups = "i2c1_a_1"; }; }; i2c1_default_mode: i2c1_default { diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index 3e97a669f15e..d43f8b19e7dd 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -404,8 +404,8 @@ */ eth_snowball_mode: eth_snowball { snowball_mux { - ste,function = "sm"; - ste,pins = "sm_b_1"; + function = "sm"; + groups = "sm_b_1"; }; /* LAN IRQ pin */ snowball_cfg1 { @@ -423,8 +423,8 @@ sdi0 { sdi0_default_mode: sdi0_default { snowball_mux { - ste,function = "mc0"; - ste,pins = "mc0dat31dir_a_1"; + function = "mc0"; + groups = "mc0dat31dir_a_1"; }; snowball_cfg1 { ste,pins = "GPIO21_AB3"; /* DAT31DIR */ @@ -436,8 +436,8 @@ ssp0 { ssp0_snowball_mode: ssp0_snowball_default { snowball_mux { - ste,function = "ssp0"; - ste,pins = "ssp0_a_1"; + function = "ssp0"; + groups = "ssp0_a_1"; }; snowball_cfg1 { ste,pins = "GPIO144_B13"; /* FRM */ diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 746db6acf648..dec72f2e6a2b 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1520,12 +1520,13 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, unsigned long configs = 0; bool has_config = 0; struct property *prop; - const char *group, *gpio_name; struct device_node *np_config; - ret = of_property_read_string(np, "ste,function", &function); + ret = of_property_read_string(np, "function", &function); if (ret >= 0) { - ret = of_property_count_strings(np, "ste,pins"); + const char *group; + + ret = of_property_count_strings(np, "groups"); if (ret < 0) goto exit; @@ -1535,7 +1536,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, group) { + of_property_for_each_string(np, "groups", prop, group) { ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps, group, function); if (ret < 0) @@ -1548,6 +1549,9 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (np_config) has_config |= nmk_pinctrl_dt_get_config(np_config, &configs); if (has_config) { + const char *gpio_name; + const char *pin; + ret = of_property_count_strings(np, "ste,pins"); if (ret < 0) goto exit; @@ -1557,8 +1561,8 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, group) { - gpio_name = nmk_find_pin_name(pctldev, group); + of_property_for_each_string(np, "ste,pins", prop, pin) { + gpio_name = nmk_find_pin_name(pctldev, pin); ret = nmk_dt_add_map_configs(map, reserved_maps, num_maps, -- GitLab From 51d39936acba666774b596829277db3e13e5e970 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 12:10:11 +0200 Subject: [PATCH 0530/9457] pinctrl: abx500: force-convert to generic mux bindings This converts the ABx500 pin controller and all associated device trees to use the standard, generic mux bindings for pin controllers. There are no such device trees deployed in the wild so this is safe to do to set a good example. Signed-off-by: Linus Walleij --- arch/arm/boot/dts/ste-href-ab8500.dtsi | 108 +++++++++++------------ arch/arm/boot/dts/ste-href-ab8505.dtsi | 60 ++++++------- drivers/pinctrl/nomadik/pinctrl-abx500.c | 16 ++-- 3 files changed, 94 insertions(+), 90 deletions(-) diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi index 30f8601da323..8be3c471d097 100644 --- a/arch/arm/boot/dts/ste-href-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi @@ -47,8 +47,8 @@ gpio2 { gpio2_default_mode: gpio2_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio2_a_1"; + function = "gpio"; + groups = "gpio2_a_1"; }; default_cfg { ste,pins = "GPIO2_T9"; @@ -60,8 +60,8 @@ gpio4 { gpio4_default_mode: gpio4_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio4_a_1"; + function = "gpio"; + groups = "gpio4_a_1"; }; default_cfg { ste,pins = "GPIO4_W2"; @@ -73,8 +73,8 @@ gpio10 { gpio10_default_mode: gpio10_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio10_d_1"; + function = "gpio"; + groups = "gpio10_d_1"; }; default_cfg { ste,pins = "GPIO10_U17"; @@ -86,8 +86,8 @@ gpio11 { gpio11_default_mode: gpio11_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio11_d_1"; + function = "gpio"; + groups = "gpio11_d_1"; }; default_cfg { ste,pins = "GPIO11_AA18"; @@ -99,8 +99,8 @@ gpio12 { gpio12_default_mode: gpio12_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio12_d_1"; + function = "gpio"; + groups = "gpio12_d_1"; }; default_cfg { ste,pins = "GPIO12_U16"; @@ -112,8 +112,8 @@ gpio13 { gpio13_default_mode: gpio13_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio13_d_1"; + function = "gpio"; + groups = "gpio13_d_1"; }; default_cfg { ste,pins = "GPIO13_W17"; @@ -125,8 +125,8 @@ gpio16 { gpio16_default_mode: gpio16_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio16_a_1"; + function = "gpio"; + groups = "gpio16_a_1"; }; default_cfg { ste,pins = "GPIO16_F15"; @@ -138,8 +138,8 @@ gpio24 { gpio24_default_mode: gpio24_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio24_a_1"; + function = "gpio"; + groups = "gpio24_a_1"; }; default_cfg { ste,pins = "GPIO24_T14"; @@ -151,8 +151,8 @@ gpio25 { gpio25_default_mode: gpio25_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio25_a_1"; + function = "gpio"; + groups = "gpio25_a_1"; }; default_cfg { ste,pins = "GPIO25_R16"; @@ -164,8 +164,8 @@ gpio36 { gpio36_default_mode: gpio36_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio36_a_1"; + function = "gpio"; + groups = "gpio36_a_1"; }; default_cfg { ste,pins = "GPIO36_A17"; @@ -177,8 +177,8 @@ gpio37 { gpio37_default_mode: gpio37_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio37_a_1"; + function = "gpio"; + groups = "gpio37_a_1"; }; default_cfg { ste,pins = "GPIO37_E15"; @@ -190,8 +190,8 @@ gpio38 { gpio38_default_mode: gpio38_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio38_a_1"; + function = "gpio"; + groups = "gpio38_a_1"; }; default_cfg { ste,pins = "GPIO38_C17"; @@ -203,8 +203,8 @@ gpio39 { gpio39_default_mode: gpio39_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio39_a_1"; + function = "gpio"; + groups = "gpio39_a_1"; }; default_cfg { ste,pins = "GPIO39_E16"; @@ -216,8 +216,8 @@ gpio42 { gpio42_default_mode: gpio42_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio42_a_1"; + function = "gpio"; + groups = "gpio42_a_1"; }; default_cfg { ste,pins = "GPIO42_U2"; @@ -232,8 +232,8 @@ gpio26 { gpio26_default_mode: gpio26_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio26_d_1"; + function = "gpio"; + groups = "gpio26_d_1"; }; default_cfg { ste,pins = "GPIO26_M16"; @@ -244,8 +244,8 @@ gpio35 { gpio35_default_mode: gpio35_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio35_d_1"; + function = "gpio"; + groups = "gpio35_d_1"; }; default_cfg { ste,pins = "GPIO35_W15"; @@ -260,8 +260,8 @@ ycbcr { ycbcr_default_mode: ycbcr_default { default_mux { - ste,function = "ycbcr"; - ste,pins = "ycbcr0123_d_1"; + function = "ycbcr"; + groups = "ycbcr0123_d_1"; }; default_cfg { ste,pins = "GPIO6_Y18", @@ -277,8 +277,8 @@ pwm { pwm_default_mode: pwm_default { default_mux { - ste,function = "pwmout"; - ste,pins = "pwmout1_d_1", "pwmout2_d_1"; + function = "pwmout"; + groups = "pwmout1_d_1", "pwmout2_d_1"; }; default_cfg { ste,pins = "GPIO14_F14", @@ -292,8 +292,8 @@ adi1 { adi1_default_mode: adi1_default { default_mux { - ste,function = "adi1"; - ste,pins = "adi1_d_1"; + function = "adi1"; + groups = "adi1_d_1"; }; default_cfg { ste,pins = "GPIO17_P5", @@ -309,8 +309,8 @@ usbuicc { usbuicc_default_mode: usbuicc_default { default_mux { - ste,function = "usbuicc"; - ste,pins = "usbuicc_d_1"; + function = "usbuicc"; + groups = "usbuicc_d_1"; }; default_cfg { ste,pins = "GPIO21_H19", @@ -325,8 +325,8 @@ dmic { dmic_default_mode: dmic_default { default_mux { - ste,function = "dmic"; - ste,pins = "dmic12_d_1", + function = "dmic"; + groups = "dmic12_d_1", "dmic34_d_1", "dmic56_d_1"; }; @@ -345,8 +345,8 @@ extcpena { extcpena_default_mode: extcpena_default { default_mux { - ste,function = "extcpena"; - ste,pins = "extcpena_d_1"; + function = "extcpena"; + groups = "extcpena_d_1"; }; default_cfg { ste,pins = "GPIO34_R17"; @@ -359,8 +359,8 @@ modsclsda { modsclsda_default_mode: modsclsda_default { default_mux { - ste,function = "modsclsda"; - ste,pins = "modsclsda_d_1"; + function = "modsclsda"; + groups = "modsclsda_d_1"; }; default_cfg { ste,pins = "GPIO40_T19", @@ -376,8 +376,8 @@ sysclkreq2 { sysclkreq2_default_mode: sysclkreq2_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq2_d_1"; + function = "sysclkreq"; + groups = "sysclkreq2_d_1"; }; default_cfg { ste,pins = "GPIO1_T10"; @@ -387,8 +387,8 @@ }; sysclkreq2_sleep_mode: sysclkreq2_sleep { default_mux { - ste,function = "gpio"; - ste,pins = "gpio1_a_1"; + function = "gpio"; + groups = "gpio1_a_1"; }; default_cfg { ste,pins = "GPIO1_T10"; @@ -400,8 +400,8 @@ sysclkreq4 { sysclkreq4_default_mode: sysclkreq4_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq4_d_1"; + function = "sysclkreq"; + groups = "sysclkreq4_d_1"; }; default_cfg { ste,pins = "GPIO3_U9"; @@ -411,8 +411,8 @@ }; sysclkreq4_sleep_mode: sysclkreq4_sleep { default_mux { - ste,function = "gpio"; - ste,pins = "gpio3_a_1"; + function = "gpio"; + groups = "gpio3_a_1"; }; default_cfg { ste,pins = "GPIO3_U9"; diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi index 6006d62086a2..112053c7aa51 100644 --- a/arch/arm/boot/dts/ste-href-ab8505.dtsi +++ b/arch/arm/boot/dts/ste-href-ab8505.dtsi @@ -35,8 +35,8 @@ gpio2 { gpio2_default_mode: gpio2_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio2_a_1"; + function = "gpio"; + groups = "gpio2_a_1"; }; default_cfg { ste,pins = "GPIO2_R5"; @@ -48,8 +48,8 @@ gpio10 { gpio10_default_mode: gpio10_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio10_d_1"; + function = "gpio"; + groups = "gpio10_d_1"; }; default_cfg { ste,pins = "GPIO10_B16"; @@ -61,8 +61,8 @@ gpio11 { gpio11_default_mode: gpio11_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio11_d_1"; + function = "gpio"; + groups = "gpio11_d_1"; }; default_cfg { ste,pins = "GPIO11_B17"; @@ -74,8 +74,8 @@ gpio13 { gpio13_default_mode: gpio13_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio13_d_1"; + function = "gpio"; + groups = "gpio13_d_1"; }; default_cfg { ste,pins = "GPIO13_D17"; @@ -87,8 +87,8 @@ gpio34 { gpio34_default_mode: gpio34_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio34_a_1"; + function = "gpio"; + groups = "gpio34_a_1"; }; default_cfg { ste,pins = "GPIO34_H14"; @@ -100,8 +100,8 @@ gpio50 { gpio50_default_mode: gpio50_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio50_d_1"; + function = "gpio"; + groups = "gpio50_d_1"; }; default_cfg { ste,pins = "GPIO50_L4"; @@ -114,8 +114,8 @@ pwm { pwm_default_mode: pwm_default { default_mux { - ste,function = "pwmout"; - ste,pins = "pwmout1_d_1"; + function = "pwmout"; + groups = "pwmout1_d_1"; }; default_cfg { ste,pins = "GPIO14_C16"; @@ -128,8 +128,8 @@ adi2 { adi2_default_mode: adi2_default { default_mux { - ste,function = "adi2"; - ste,pins = "adi2_d_1"; + function = "adi2"; + groups = "adi2_d_1"; }; default_cfg { ste,pins = "GPIO17_P2", @@ -145,8 +145,8 @@ modsclsda { modsclsda_default_mode: modsclsda_default { default_mux { - ste,function = "modsclsda"; - ste,pins = "modsclsda_d_1"; + function = "modsclsda"; + groups = "modsclsda_d_1"; }; default_cfg { ste,pins = "GPIO40_J15", @@ -159,8 +159,8 @@ resethw { resethw_default_mode: resethw_default { default_mux { - ste,function = "resethw"; - ste,pins = "resethw_d_1"; + function = "resethw"; + groups = "resethw_d_1"; }; default_cfg { ste,pins = "GPIO52_D16"; @@ -172,8 +172,8 @@ service { service_default_mode: service_default { default_mux { - ste,function = "service"; - ste,pins = "service_d_1"; + function = "service"; + groups = "service_d_1"; }; default_cfg { ste,pins = "GPIO53_D15"; @@ -188,8 +188,8 @@ sysclkreq2 { sysclkreq2_default_mode: sysclkreq2_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq2_d_1"; + function = "sysclkreq"; + groups = "sysclkreq2_d_1"; }; default_cfg { ste,pins = "GPIO1_N4"; @@ -199,8 +199,8 @@ }; sysclkreq2_sleep_mode: sysclkreq2_sleep { default_mux { - ste,function = "gpio"; - ste,pins = "gpio1_a_1"; + function = "gpio"; + groups = "gpio1_a_1"; }; default_cfg { ste,pins = "GPIO1_N4"; @@ -212,8 +212,8 @@ sysclkreq4 { sysclkreq4_default_mode: sysclkreq4_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq4_d_1"; + function = "sysclkreq"; + groups = "sysclkreq4_d_1"; }; default_cfg { ste,pins = "GPIO3_P5"; @@ -223,8 +223,8 @@ }; sysclkreq4_sleep_mode: sysclkreq4_sleep { default_mux { - ste,function = "gpio"; - ste,pins = "gpio3_a_1"; + function = "gpio"; + groups = "gpio3_a_1"; }; default_cfg { ste,pins = "GPIO3_P5"; diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 228972827132..d0c0454dce0d 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -893,12 +893,13 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, unsigned int nconfigs = 0; bool has_config = 0; struct property *prop; - const char *group, *gpio_name; struct device_node *np_config; - ret = of_property_read_string(np, "ste,function", &function); + ret = of_property_read_string(np, "function", &function); if (ret >= 0) { - ret = of_property_count_strings(np, "ste,pins"); + const char *group; + + ret = of_property_count_strings(np, "groups"); if (ret < 0) goto exit; @@ -907,7 +908,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, group) { + of_property_for_each_string(np, "groups", prop, group) { ret = abx500_dt_add_map_mux(map, reserved_maps, num_maps, group, function); if (ret < 0) @@ -927,6 +928,9 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, has_config |= nconfigs; } if (has_config) { + const char *gpio_name; + const char *pin; + ret = of_property_count_strings(np, "ste,pins"); if (ret < 0) goto exit; @@ -937,8 +941,8 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, group) { - gpio_name = abx500_find_pin_name(pctldev, group); + of_property_for_each_string(np, "ste,pins", prop, pin) { + gpio_name = abx500_find_pin_name(pctldev, pin); ret = abx500_dt_add_map_configs(map, reserved_maps, num_maps, gpio_name, configs, 1); -- GitLab From 1637d480f873ca305f7f090e3b3bc92430b5892f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 12:16:25 +0200 Subject: [PATCH 0531/9457] pinctrl: nomadik: force-convert to generic config bindings This converts the Nomadik pin controller and all associated device trees to use the standard, generic config bindings for pin controllers. There are no such device trees deployed in the wild so this is safe to do to set a good example. Signed-off-by: Linus Walleij --- arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi | 36 ++--- .../arm/boot/dts/ste-href-family-pinctrl.dtsi | 150 +++++++++--------- arch/arm/boot/dts/ste-href-stuib.dtsi | 4 +- arch/arm/boot/dts/ste-href-tvk1281618.dtsi | 12 +- arch/arm/boot/dts/ste-hrefprev60.dtsi | 8 +- arch/arm/boot/dts/ste-hrefv60plus.dtsi | 38 ++--- arch/arm/boot/dts/ste-nomadik-s8815.dts | 8 +- arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 12 +- arch/arm/boot/dts/ste-snowball.dts | 24 +-- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 +- 10 files changed, 148 insertions(+), 148 deletions(-) diff --git a/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi index 08a7365cb929..52dba2e39c71 100644 --- a/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi +++ b/arch/arm/boot/dts/ste-ccu8540-pinctrl.dtsi @@ -23,24 +23,24 @@ uart0_default_mode: uart0_default { default_cfg1 { - ste,pins = "GPIO0", "GPIO2"; + pins = "GPIO0", "GPIO2"; ste,config = <&in_pu>; }; default_cfg2 { - ste,pins = "GPIO1", "GPIO3"; + pins = "GPIO1", "GPIO3"; ste,config = <&out_hi>; }; }; uart0_sleep_mode: uart0_sleep { sleep_cfg1 { - ste,pins = "GPIO0", "GPIO2"; + pins = "GPIO0", "GPIO2"; ste,config = <&slpm_in_pu>; }; sleep_cfg2 { - ste,pins = "GPIO1", "GPIO3"; + pins = "GPIO1", "GPIO3"; ste,config = <&slpm_out_hi>; }; }; @@ -54,24 +54,24 @@ }; default_cfg1 { - ste,pins = "GPIO120"; + pins = "GPIO120"; ste,config = <&in_pu>; }; default_cfg2 { - ste,pins = "GPIO121"; + pins = "GPIO121"; ste,config = <&out_hi>; }; }; uart2_sleep_mode: uart2_sleep { sleep_cfg1 { - ste,pins = "GPIO120"; + pins = "GPIO120"; ste,config = <&slpm_in_pu>; }; sleep_cfg2 { - ste,pins = "GPIO121"; + pins = "GPIO121"; ste,config = <&slpm_out_hi>; }; }; @@ -87,14 +87,14 @@ i2c0_default_mode: i2c_default { default_cfg1 { - ste,pins = "GPIO147", "GPIO148"; + pins = "GPIO147", "GPIO148"; ste,config = <&in_pu>; }; }; i2c0_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO147", "GPIO148"; + pins = "GPIO147", "GPIO148"; ste,config = <&slpm_in_pu>; }; }; @@ -110,14 +110,14 @@ i2c1_default_mode: i2c_default { default_cfg1 { - ste,pins = "GPIO16", "GPIO17"; + pins = "GPIO16", "GPIO17"; ste,config = <&in_pu>; }; }; i2c1_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO16", "GPIO17"; + pins = "GPIO16", "GPIO17"; ste,config = <&slpm_in_pu>; }; }; @@ -133,14 +133,14 @@ i2c2_default_mode: i2c_default { default_cfg1 { - ste,pins = "GPIO10", "GPIO11"; + pins = "GPIO10", "GPIO11"; ste,config = <&in_pu>; }; }; i2c2_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO11", "GPIO11"; + pins = "GPIO11", "GPIO11"; ste,config = <&slpm_in_pu>; }; }; @@ -156,14 +156,14 @@ i2c4_default_mode: i2c_default { default_cfg1 { - ste,pins = "GPIO122", "GPIO123"; + pins = "GPIO122", "GPIO123"; ste,config = <&in_pu>; }; }; i2c4_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO122", "GPIO123"; + pins = "GPIO122", "GPIO123"; ste,config = <&slpm_in_pu>; }; }; @@ -179,14 +179,14 @@ i2c5_default_mode: i2c_default { default_cfg1 { - ste,pins = "GPIO118", "GPIO119"; + pins = "GPIO118", "GPIO119"; ste,config = <&in_pu>; }; }; i2c5_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO118", "GPIO119"; + pins = "GPIO118", "GPIO119"; ste,config = <&slpm_in_pu>; }; }; diff --git a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi index 61aa87138927..5c5cea232743 100644 --- a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi +++ b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi @@ -22,29 +22,29 @@ groups = "u0_a_1"; }; default_cfg1 { - ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ + pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ ste,config = <&in_pu>; }; default_cfg2 { - ste,pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */ + pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */ ste,config = <&out_hi>; }; }; uart0_sleep_mode: uart0_sleep { sleep_cfg1 { - ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ + pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ ste,config = <&slpm_in_wkup_pdis>; }; sleep_cfg2 { - ste,pins = "GPIO1_AJ3"; /* RTS */ + pins = "GPIO1_AJ3"; /* RTS */ ste,config = <&slpm_out_hi_wkup_pdis>; }; sleep_cfg3 { - ste,pins = "GPIO3_AH3"; /* TXD */ + pins = "GPIO3_AH3"; /* TXD */ ste,config = <&slpm_out_wkup_pdis>; }; }; @@ -57,24 +57,24 @@ groups = "u1rxtx_a_1"; }; default_cfg1 { - ste,pins = "GPIO4_AH6"; /* RXD */ + pins = "GPIO4_AH6"; /* RXD */ ste,config = <&in_pu>; }; default_cfg2 { - ste,pins = "GPIO5_AG6"; /* TXD */ + pins = "GPIO5_AG6"; /* TXD */ ste,config = <&out_hi>; }; }; uart1_sleep_mode: uart1_sleep { sleep_cfg1 { - ste,pins = "GPIO4_AH6"; /* RXD */ + pins = "GPIO4_AH6"; /* RXD */ ste,config = <&slpm_in_wkup_pdis>; }; sleep_cfg2 { - ste,pins = "GPIO5_AG6"; /* TXD */ + pins = "GPIO5_AG6"; /* TXD */ ste,config = <&slpm_out_wkup_pdis>; }; }; @@ -87,24 +87,24 @@ groups = "u2rxtx_c_1"; }; default_cfg1 { - ste,pins = "GPIO29_W2"; /* RXD */ + pins = "GPIO29_W2"; /* RXD */ ste,config = <&in_pu>; }; default_cfg2 { - ste,pins = "GPIO30_W3"; /* TXD */ + pins = "GPIO30_W3"; /* TXD */ ste,config = <&out_hi>; }; }; uart2_sleep_mode: uart2_sleep { sleep_cfg1 { - ste,pins = "GPIO29_W2"; /* RXD */ + pins = "GPIO29_W2"; /* RXD */ ste,config = <&in_wkup_pdis>; }; sleep_cfg2 { - ste,pins = "GPIO30_W3"; /* TXD */ + pins = "GPIO30_W3"; /* TXD */ ste,config = <&out_wkup_pdis>; }; }; @@ -118,14 +118,14 @@ groups = "i2c0_a_1"; }; default_cfg1 { - ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ + pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ ste,config = <&in_pu>; }; }; i2c0_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ + pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -138,14 +138,14 @@ groups = "i2c1_b_2"; }; default_cfg1 { - ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ + pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ ste,config = <&in_pu>; }; }; i2c1_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ + pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -158,14 +158,14 @@ groups = "i2c2_b_2"; }; default_cfg1 { - ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ + pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ ste,config = <&in_pu>; }; }; i2c2_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ + pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -178,14 +178,14 @@ groups = "i2c3_c_2"; }; default_cfg1 { - ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ + pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ ste,config = <&in_pu>; }; }; i2c3_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ + pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -202,14 +202,14 @@ groups = "i2c4_b_1"; }; default_cfg1 { - ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ + pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ ste,config = <&in_pu>; }; }; i2c4_sleep_mode: i2c_sleep { sleep_cfg1 { - ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ + pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -223,15 +223,15 @@ groups = "spi2_oc1_2"; }; default_cfg1 { - ste,pins = "GPIO216_AG12"; /* FRM */ + pins = "GPIO216_AG12"; /* FRM */ ste,config = <&gpio_out_hi>; }; default_cfg2 { - ste,pins = "GPIO218_AH11"; /* RXD */ + pins = "GPIO218_AH11"; /* RXD */ ste,config = <&in_pd>; }; default_cfg3 { - ste,pins = + pins = "GPIO215_AH13", /* TXD */ "GPIO217_AH12"; /* CLK */ ste,config = <&out_lo>; @@ -245,32 +245,32 @@ * as we do not state any muxing. */ idle_cfg1 { - ste,pins = "GPIO218_AH11"; /* RXD */ + pins = "GPIO218_AH11"; /* RXD */ ste,config = <&slpm_in_pdis>; }; idle_cfg2 { - ste,pins = "GPIO215_AH13"; /* TXD */ + pins = "GPIO215_AH13"; /* TXD */ ste,config = <&slpm_out_lo_pdis>; }; idle_cfg3 { - ste,pins = "GPIO217_AH12"; /* CLK */ + pins = "GPIO217_AH12"; /* CLK */ ste,config = <&slpm_pdis>; }; }; spi2_sleep_mode: spi_sleep { sleep_cfg1 { - ste,pins = + pins = "GPIO216_AG12", /* FRM */ "GPIO218_AH11"; /* RXD */ ste,config = <&slpm_in_wkup_pdis>; }; sleep_cfg2 { - ste,pins = "GPIO215_AH13"; /* TXD */ + pins = "GPIO215_AH13"; /* TXD */ ste,config = <&slpm_out_lo_wkup_pdis>; }; sleep_cfg3 { - ste,pins = "GPIO217_AH12"; /* CLK */ + pins = "GPIO217_AH12"; /* CLK */ ste,config = <&slpm_wkup_pdis>; }; }; @@ -285,22 +285,22 @@ groups = "mc0_a_1"; }; default_cfg1 { - ste,pins = + pins = "GPIO18_AC2", /* CMDDIR */ "GPIO19_AC1", /* DAT0DIR */ "GPIO20_AB4"; /* DAT2DIR */ ste,config = <&out_hi>; }; default_cfg2 { - ste,pins = "GPIO22_AA3"; /* FBCLK */ + pins = "GPIO22_AA3"; /* FBCLK */ ste,config = <&in_nopull>; }; default_cfg3 { - ste,pins = "GPIO23_AA4"; /* CLK */ + pins = "GPIO23_AA4"; /* CLK */ ste,config = <&out_lo>; }; default_cfg4 { - ste,pins = + pins = "GPIO24_AB2", /* CMD */ "GPIO25_Y4", /* DAT0 */ "GPIO26_Y2", /* DAT1 */ @@ -312,14 +312,14 @@ sdi0_sleep_mode: sdi0_sleep { sleep_cfg1 { - ste,pins = + pins = "GPIO18_AC2", /* CMDDIR */ "GPIO19_AC1", /* DAT0DIR */ "GPIO20_AB4"; /* DAT2DIR */ ste,config = <&slpm_out_hi_wkup_pdis>; }; sleep_cfg2 { - ste,pins = + pins = "GPIO22_AA3", /* FBCLK */ "GPIO24_AB2", /* CMD */ "GPIO25_Y4", /* DAT0 */ @@ -329,7 +329,7 @@ ste,config = <&slpm_in_wkup_pdis>; }; sleep_cfg3 { - ste,pins = "GPIO23_AA4"; /* CLK */ + pins = "GPIO23_AA4"; /* CLK */ ste,config = <&slpm_out_lo_wkup_pdis>; }; }; @@ -343,15 +343,15 @@ groups = "mc1_a_1"; }; default_cfg1 { - ste,pins = "GPIO208_AH16"; /* CLK */ + pins = "GPIO208_AH16"; /* CLK */ ste,config = <&out_lo>; }; default_cfg2 { - ste,pins = "GPIO209_AG15"; /* FBCLK */ + pins = "GPIO209_AG15"; /* FBCLK */ ste,config = <&in_nopull>; }; default_cfg3 { - ste,pins = + pins = "GPIO210_AJ15", /* CMD */ "GPIO211_AG14", /* DAT0 */ "GPIO212_AF13", /* DAT1 */ @@ -363,11 +363,11 @@ sdi1_sleep_mode: sdi1_sleep { sleep_cfg1 { - ste,pins = "GPIO208_AH16"; /* CLK */ + pins = "GPIO208_AH16"; /* CLK */ ste,config = <&slpm_out_lo_wkup_pdis>; }; sleep_cfg2 { - ste,pins = + pins = "GPIO209_AG15", /* FBCLK */ "GPIO210_AJ15", /* CMD */ "GPIO211_AG14", /* DAT0 */ @@ -387,15 +387,15 @@ groups = "mc2_a_1"; }; default_cfg1 { - ste,pins = "GPIO128_A5"; /* CLK */ + pins = "GPIO128_A5"; /* CLK */ ste,config = <&out_lo>; }; default_cfg2 { - ste,pins = "GPIO130_C8"; /* FBCLK */ + pins = "GPIO130_C8"; /* FBCLK */ ste,config = <&in_nopull>; }; default_cfg3 { - ste,pins = + pins = "GPIO129_B4", /* CMD */ "GPIO131_A12", /* DAT0 */ "GPIO132_C10", /* DAT1 */ @@ -411,17 +411,17 @@ sdi2_sleep_mode: sdi2_sleep { sleep_cfg1 { - ste,pins = "GPIO128_A5"; /* CLK */ + pins = "GPIO128_A5"; /* CLK */ ste,config = <&out_lo_wkup_pdis>; }; sleep_cfg2 { - ste,pins = + pins = "GPIO130_C8", /* FBCLK */ "GPIO129_B4"; /* CMD */ ste,config = <&in_wkup_pdis_en>; }; sleep_cfg3 { - ste,pins = + pins = "GPIO131_A12", /* DAT0 */ "GPIO132_C10", /* DAT1 */ "GPIO133_B10", /* DAT2 */ @@ -443,15 +443,15 @@ groups = "mc4_a_1"; }; default_cfg1 { - ste,pins = "GPIO203_AE23"; /* CLK */ + pins = "GPIO203_AE23"; /* CLK */ ste,config = <&out_lo>; }; default_cfg2 { - ste,pins = "GPIO202_AF25"; /* FBCLK */ + pins = "GPIO202_AF25"; /* FBCLK */ ste,config = <&in_nopull>; }; default_cfg3 { - ste,pins = + pins = "GPIO201_AF24", /* CMD */ "GPIO200_AH26", /* DAT0 */ "GPIO199_AH23", /* DAT1 */ @@ -467,11 +467,11 @@ sdi4_sleep_mode: sdi4_sleep { sleep_cfg1 { - ste,pins = "GPIO203_AE23"; /* CLK */ + pins = "GPIO203_AE23"; /* CLK */ ste,config = <&out_lo_wkup_pdis>; }; sleep_cfg2 { - ste,pins = + pins = "GPIO202_AF25", /* FBCLK */ "GPIO201_AF24", /* CMD */ "GPIO200_AH26", /* DAT0 */ @@ -498,7 +498,7 @@ groups = "msp0txrx_a_1", "msp0tfstck_a_1"; }; default_msp0_cfg { - ste,pins = + pins = "GPIO12_AC4", /* TXD */ "GPIO15_AC3", /* RXD */ "GPIO13_AF3", /* TFS */ @@ -515,11 +515,11 @@ groups = "msp1txrx_a_1", "msp1_a_1"; }; default_cfg1 { - ste,pins = "GPIO33_AF2"; + pins = "GPIO33_AF2"; ste,config = <&out_lo>; }; default_cfg2 { - ste,pins = + pins = "GPIO34_AE1", "GPIO35_AE2", "GPIO36_AG2"; @@ -537,14 +537,14 @@ groups = "msp2_a_1"; }; default_cfg1 { - ste,pins = + pins = "GPIO193_AH27", /* TXD */ "GPIO194_AF27", /* TCK */ "GPIO195_AG28"; /* TFS */ ste,config = <&in_pd>; }; default_cfg2 { - ste,pins = "GPIO196_AG26"; /* RXD */ + pins = "GPIO196_AG26"; /* RXD */ ste,config = <&out_lo>; }; }; @@ -558,7 +558,7 @@ groups = "usb_a_1"; }; default_cfg1 { - ste,pins = + pins = "GPIO256_AF28", /* NXT */ "GPIO258_AD29", /* XCLK */ "GPIO259_AC29", /* DIR */ @@ -573,25 +573,25 @@ ste,config = <&in_nopull>; }; default_cfg2 { - ste,pins = "GPIO257_AE29"; /* STP */ + pins = "GPIO257_AE29"; /* STP */ ste,config = <&out_hi>; }; }; musb_sleep_mode: musb_sleep { sleep_cfg1 { - ste,pins = + pins = "GPIO256_AF28", /* NXT */ "GPIO258_AD29", /* XCLK */ "GPIO259_AC29"; /* DIR */ ste,config = <&slpm_wkup_pdis_en>; }; sleep_cfg2 { - ste,pins = "GPIO257_AE29"; /* STP */ + pins = "GPIO257_AE29"; /* STP */ ste,config = <&slpm_out_hi_wkup_pdis>; }; sleep_cfg3 { - ste,pins = + pins = "GPIO260_AD28", /* DAT7 */ "GPIO261_AD26", /* DAT6 */ "GPIO262_AE26", /* DAT5 */ @@ -618,7 +618,7 @@ "lcdvsi1_a_1"; /* VSI1 for HDMI */ }; default_cfg1 { - ste,pins = + pins = "GPIO68_E1", /* VSI0 */ "GPIO69_E2"; /* VSI1 */ ste,config = <&in_pu>; @@ -626,7 +626,7 @@ }; lcd_sleep_mode: lcd_sleep { sleep_cfg1 { - ste,pins = "GPIO69_E2"; /* VSI1 */ + pins = "GPIO69_E2"; /* VSI1 */ ste,config = <&slpm_in_wkup_pdis>; }; }; @@ -640,7 +640,7 @@ groups = "kp_a_2"; }; default_cfg1 { - ste,pins = + pins = "GPIO153_B17", /* I7 */ "GPIO154_C16", /* I6 */ "GPIO155_C19", /* I5 */ @@ -652,7 +652,7 @@ ste,config = <&in_pd>; }; default_cfg2 { - ste,pins = + pins = "GPIO157_A18", /* O7 */ "GPIO158_C18", /* O6 */ "GPIO159_B19", /* O5 */ @@ -666,7 +666,7 @@ }; ske_kpa2_sleep_mode: ske_kpa2_sleep { sleep_cfg1 { - ste,pins = + pins = "GPIO153_B17", /* I7 */ "GPIO154_C16", /* I6 */ "GPIO155_C19", /* I5 */ @@ -678,7 +678,7 @@ ste,config = <&slpm_in_pu_wkup_pdis_en>; }; sleep_cfg2 { - ste,pins = + pins = "GPIO157_A18", /* O7 */ "GPIO158_C18", /* O6 */ "GPIO159_B19", /* O5 */ @@ -700,7 +700,7 @@ groups = "kp_a_1", "kp_oc1_1"; }; default_cfg1 { - ste,pins = + pins = "GPIO91_B6", /* KP_O0 */ "GPIO90_A3", /* KP_O1 */ "GPIO87_B3", /* KP_O2 */ @@ -710,7 +710,7 @@ ste,config = <&out_lo>; }; default_cfg2 { - ste,pins = + pins = "GPIO93_B7", /* KP_I0 */ "GPIO92_D6", /* KP_I1 */ "GPIO89_E6", /* KP_I2 */ @@ -729,13 +729,13 @@ * These are plain GPIO pins used by WLAN */ default_cfg1 { - ste,pins = + pins = "GPIO226_AF8", /* WLAN_PMU_EN */ "GPIO85_D5"; /* WLAN_ENA */ ste,config = <&gpio_out_lo>; }; default_cfg2 { - ste,pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */ + pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */ ste,config = <&gpio_in_pu>; }; }; diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi index 84d7c5d883f2..7d4f8184c522 100644 --- a/arch/arm/boot/dts/ste-href-stuib.dtsi +++ b/arch/arm/boot/dts/ste-href-stuib.dtsi @@ -103,7 +103,7 @@ prox { prox_stuib_mode: prox_stuib { stuib_cfg { - ste,pins = "GPIO217_AH12"; + pins = "GPIO217_AH12"; ste,config = <&gpio_in_pu>; }; }; @@ -111,7 +111,7 @@ hall { hall_stuib_mode: stuib_tvk { stuib_cfg { - ste,pins = "GPIO145_C13"; + pins = "GPIO145_C13"; ste,config = <&gpio_in_pu>; }; }; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi index 18b65d1b14f2..062c6aae3afa 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi @@ -130,7 +130,7 @@ tc35893 { tc35893_tvk_mode: tc35893_tvk { tvk_cfg { - ste,pins = "GPIO218_AH11"; + pins = "GPIO218_AH11"; ste,config = <&gpio_in_pu>; }; }; @@ -138,7 +138,7 @@ prox { prox_tvk_mode: prox_tvk { tvk_cfg { - ste,pins = "GPIO217_AH12"; + pins = "GPIO217_AH12"; ste,config = <&gpio_in_pu>; }; }; @@ -146,7 +146,7 @@ hall { hall_tvk_mode: hall_tvk { tvk_cfg { - ste,pins = "GPIO145_C13"; + pins = "GPIO145_C13"; ste,config = <&gpio_in_pu>; }; }; @@ -155,7 +155,7 @@ accel_tvk_mode: accel_tvk { /* Accelerometer interrupt lines 1 & 2 */ tvk_cfg { - ste,pins = "GPIO82_C1", "GPIO83_D3"; + pins = "GPIO82_C1", "GPIO83_D3"; ste,config = <&gpio_in_pu>; }; }; @@ -164,11 +164,11 @@ magneto_tvk_mode: magneto_tvk { /* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */ tvk_cfg1 { - ste,pins = "GPIO31_V3"; + pins = "GPIO31_V3"; ste,config = <&gpio_in_pu>; }; tvk_cfg2 { - ste,pins = "GPIO32_V2"; + pins = "GPIO32_V2"; ste,config = <&gpio_in_pd>; }; }; diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi index 5d8b7f8ced1b..7f3975b58d16 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dtsi +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -83,7 +83,7 @@ groups = "ssp0_a_1"; }; hrefprev60_cfg1 { - ste,pins = "GPIO145_C13"; /* RXD */ + pins = "GPIO145_C13"; /* RXD */ ste,config = <&in_pd>; }; @@ -97,7 +97,7 @@ groups = "mc0dat31dir_a_1"; }; hrefprev60_cfg1 { - ste,pins = "GPIO21_AB3"; /* DAT31DIR */ + pins = "GPIO21_AB3"; /* DAT31DIR */ ste,config = <&out_hi>; }; @@ -106,7 +106,7 @@ tc35892 { tc35892_hrefprev60_mode: tc35892_hrefprev60 { hrefprev60_cfg { - ste,pins = "GPIO217_AH12"; + pins = "GPIO217_AH12"; ste,config = <&gpio_in_pu>; }; }; @@ -118,7 +118,7 @@ groups = "ipgpio0_c_1", "ipgpio1_c_1"; }; hrefprev60_cfg1 { - ste,pins = "GPIO6_AF6", "GPIO7_AG5"; + pins = "GPIO6_AF6", "GPIO7_AG5"; ste,config = <&in_pu>; }; }; diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi index 2b4104ef07de..a4bc9e77d640 100644 --- a/arch/arm/boot/dts/ste-hrefv60plus.dtsi +++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi @@ -49,7 +49,7 @@ /* SD card detect GPIO pin, extend default state */ sdi0_default_mode: sdi0_default { default_hrefv60_cfg1 { - ste,pins = "GPIO95_E8"; + pins = "GPIO95_E8"; ste,config = <&gpio_in_pu>; }; }; @@ -68,15 +68,15 @@ groups = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1"; }; hrefv60_cfg1 { - ste,pins = "GPIO6_AF6", "GPIO7_AG5"; + pins = "GPIO6_AF6", "GPIO7_AG5"; ste,config = <&in_pu>; }; hrefv60_cfg2 { - ste,pins = "GPIO21_AB3"; + pins = "GPIO21_AB3"; ste,config = <&gpio_out_lo>; }; hrefv60_cfg3 { - ste,pins = "GPIO64_F3"; + pins = "GPIO64_F3"; ste,config = <&out_lo>; }; }; @@ -89,7 +89,7 @@ */ etm_hrefv60_mode: etm_hrefv60 { hrefv60_cfg1 { - ste,pins = + pins = "GPIO70_G5", "GPIO71_G4", "GPIO72_H4", @@ -103,11 +103,11 @@ nahj_hrefv60_mode: nahj_hrefv60 { /* NAHJ CTRL on GPIO76 to low, CTRL_INV on GPIO216 to high */ hrefv60_cfg1 { - ste,pins = "GPIO76_J2"; + pins = "GPIO76_J2"; ste,config = <&gpio_out_lo>; }; hrefv60_cfg2 { - ste,pins = "GPIO216_AG12"; + pins = "GPIO216_AG12"; ste,config = <&gpio_out_hi>; }; }; @@ -116,13 +116,13 @@ nfc_hrefv60_mode: nfc_hrefv60 { /* NFC ENA and RESET to low, pulldown IRQ line */ hrefv60_cfg1 { - ste,pins = + pins = "GPIO77_H1", /* NFC_ENA */ "GPIO142_C11"; /* NFC_RESET */ ste,config = <&gpio_out_lo>; }; hrefv60_cfg2 { - ste,pins = "GPIO144_B13"; /* NFC_IRQ */ + pins = "GPIO144_B13"; /* NFC_IRQ */ ste,config = <&gpio_in_pd>; }; }; @@ -130,11 +130,11 @@ force { force_hrefv60_mode: force_hrefv60 { hrefv60_cfg1 { - ste,pins = "GPIO91_B6"; /* FORCE_SENSING_INT */ + pins = "GPIO91_B6"; /* FORCE_SENSING_INT */ ste,config = <&gpio_in_pu>; }; hrefv60_cfg2 { - ste,pins = + pins = "GPIO92_D6", /* FORCE_SENSING_RST */ "GPIO97_D9"; /* FORCE_SENSING_WU */ ste,config = <&gpio_out_lo>; @@ -144,7 +144,7 @@ dipro { dipro_hrefv60_mode: dipro_hrefv60 { hrefv60_cfg1 { - ste,pins = "GPIO139_C9"; /* DIPRO_INT */ + pins = "GPIO139_C9"; /* DIPRO_INT */ ste,config = <&gpio_in_pu>; }; }; @@ -153,7 +153,7 @@ vaudio_hf_hrefv60_mode: vaudio_hf_hrefv60 { /* Audio Amplifier HF enable GPIO */ hrefv60_cfg1 { - ste,pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */ + pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */ ste,config = <&gpio_out_hi>; }; }; @@ -165,7 +165,7 @@ * pull low to reset state */ hrefv60_cfg1 { - ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */ + pins = "GPIO171_D23"; /* GBF_ENA_RESET */ ste,config = <&gpio_out_lo>; }; }; @@ -174,7 +174,7 @@ hdtv_hrefv60_mode: hdtv_hrefv60 { /* MSP : HDTV INTERFACE GPIO line */ hrefv60_cfg1 { - ste,pins = "GPIO192_AJ27"; + pins = "GPIO192_AJ27"; ste,config = <&gpio_in_pd>; }; }; @@ -187,11 +187,11 @@ * reset signals low. */ hrefv60_cfg1 { - ste,pins = "GPIO143_D12", "GPIO146_D13"; + pins = "GPIO143_D12", "GPIO146_D13"; ste,config = <&gpio_out_lo>; }; hrefv60_cfg2 { - ste,pins = "GPIO67_G2"; + pins = "GPIO67_G2"; ste,config = <&gpio_in_pu>; }; }; @@ -204,11 +204,11 @@ * Drive DISP1 reset high (not reset), driver DISP2 reset low (reset) */ hrefv60_cfg1 { - ste,pins ="GPIO65_F1"; + pins ="GPIO65_F1"; ste,config = <&gpio_out_hi>; }; hrefv60_cfg2 { - ste,pins ="GPIO66_G3"; + pins ="GPIO66_G3"; ste,config = <&gpio_out_lo>; }; }; diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts index 90d8b6c7a205..cc81ae7450a9 100644 --- a/arch/arm/boot/dts/ste-nomadik-s8815.dts +++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts @@ -37,12 +37,12 @@ cd_default_mode: cd_default { cd_default_cfg1 { /* CD input GPIO */ - ste,pins = "GPIO111_H21"; + pins = "GPIO111_H21"; ste,input = <0>; }; cd_default_cfg2 { /* CD GPIO biasing */ - ste,pins = "GPIO112_J21"; + pins = "GPIO112_J21"; ste,output = <0>; }; }; @@ -50,7 +50,7 @@ user-led { user_led_default_mode: user_led_default { user_led_default_cfg { - ste,pins = "GPIO2_C5"; + pins = "GPIO2_C5"; ste,output = <1>; }; }; @@ -58,7 +58,7 @@ user-button { user_button_default_mode: user_button_default { user_button_default_cfg { - ste,pins = "GPIO3_A4"; + pins = "GPIO3_A4"; ste,input = <0>; }; }; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 7cedb5aba9a9..c8b4a93180f8 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -123,18 +123,18 @@ mmcsd_default_mode: mmcsd_default { mmcsd_default_cfg1 { /* MCCLK */ - ste,pins = "GPIO8_B10"; + pins = "GPIO8_B10"; ste,output = <0>; }; mmcsd_default_cfg2 { /* MCCMDDIR, MCDAT0DIR, MCDAT31DIR */ - ste,pins = "GPIO10_C11", "GPIO15_A12", + pins = "GPIO10_C11", "GPIO15_A12", "GPIO16_C13"; ste,output = <1>; }; mmcsd_default_cfg3 { /* MCCMD, MCDAT3-0, MCMSFBCLK */ - ste,pins = "GPIO9_A10", "GPIO11_B11", + pins = "GPIO9_A10", "GPIO11_B11", "GPIO12_A11", "GPIO13_C12", "GPIO14_B12", "GPIO24_C15"; ste,input = <1>; @@ -150,7 +150,7 @@ }; i2c0_default_mode: i2c0_default { i2c0_default_cfg { - ste,pins = "GPIO62_D3", "GPIO63_D2"; + pins = "GPIO62_D3", "GPIO63_D2"; ste,input = <0>; }; }; @@ -164,7 +164,7 @@ }; i2c1_default_mode: i2c1_default { i2c1_default_cfg { - ste,pins = "GPIO53_L4", "GPIO54_L3"; + pins = "GPIO53_L4", "GPIO54_L3"; ste,input = <0>; }; }; @@ -172,7 +172,7 @@ i2c2 { i2c2_default_mode: i2c2_default { i2c2_default_cfg { - ste,pins = "GPIO73_C21", "GPIO74_C20"; + pins = "GPIO73_C21", "GPIO74_C20"; ste,input = <0>; }; }; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index d43f8b19e7dd..206826a855c0 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -409,12 +409,12 @@ }; /* LAN IRQ pin */ snowball_cfg1 { - ste,pins = "GPIO140_B11"; + pins = "GPIO140_B11"; ste,config = <&in_nopull>; }; /* LAN reset pin */ snowball_cfg2 { - ste,pins = "GPIO141_C12"; + pins = "GPIO141_C12"; ste,config = <&gpio_out_hi>; }; @@ -427,7 +427,7 @@ groups = "mc0dat31dir_a_1"; }; snowball_cfg1 { - ste,pins = "GPIO21_AB3"; /* DAT31DIR */ + pins = "GPIO21_AB3"; /* DAT31DIR */ ste,config = <&out_hi>; }; @@ -440,15 +440,15 @@ groups = "ssp0_a_1"; }; snowball_cfg1 { - ste,pins = "GPIO144_B13"; /* FRM */ + pins = "GPIO144_B13"; /* FRM */ ste,config = <&gpio_out_hi>; }; snowball_cfg2 { - ste,pins = "GPIO145_C13"; /* RXD */ + pins = "GPIO145_C13"; /* RXD */ ste,config = <&in_pd>; }; snowball_cfg3 { - ste,pins = + pins = "GPIO146_D13", /* TXD */ "GPIO143_D12"; /* CLK */ ste,config = <&out_lo>; @@ -459,7 +459,7 @@ gpio_led { gpioled_snowball_mode: gpioled_default { snowball_cfg1 { - ste,pins = "GPIO142_C11"; + pins = "GPIO142_C11"; ste,config = <&gpio_out_hi>; }; @@ -469,7 +469,7 @@ accel_snowball_mode: accel_snowball { /* Accelerometer lines */ snowball_cfg1 { - ste,pins = + pins = "GPIO163_C20", /* ACCEL_IRQ1 */ "GPIO164_B21"; /* ACCEL_IRQ2 */ ste,config = <&gpio_in_pu>; @@ -479,7 +479,7 @@ magnetometer { magneto_snowball_mode: magneto_snowball { snowball_cfg1 { - ste,pins = "GPIO165_C21"; /* MAG_DRDY */ + pins = "GPIO165_C21"; /* MAG_DRDY */ ste,config = <&gpio_in_pu>; }; }; @@ -491,7 +491,7 @@ * pull low to reset state */ snowball_cfg1 { - ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */ + pins = "GPIO171_D23"; /* GBF_ENA_RESET */ ste,config = <&gpio_out_lo>; }; }; @@ -503,13 +503,13 @@ * These are plain GPIO pins used by WLAN */ snowball_cfg1 { - ste,pins = + pins = "GPIO161_D21", /* WLAN_PMU_EN */ "GPIO215_AH13"; /* WLAN_ENA */ ste,config = <&gpio_out_lo>; }; snowball_cfg2 { - ste,pins = "GPIO216_AG12"; /* WLAN_IRQ */ + pins = "GPIO216_AG12"; /* WLAN_IRQ */ ste,config = <&gpio_in_pu>; }; }; diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index dec72f2e6a2b..ad99ba886e50 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1552,7 +1552,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, const char *gpio_name; const char *pin; - ret = of_property_count_strings(np, "ste,pins"); + ret = of_property_count_strings(np, "pins"); if (ret < 0) goto exit; ret = pinctrl_utils_reserve_map(pctldev, map, @@ -1561,7 +1561,7 @@ static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, pin) { + of_property_for_each_string(np, "pins", prop, pin) { gpio_name = nmk_find_pin_name(pctldev, pin); ret = nmk_dt_add_map_configs(map, reserved_maps, -- GitLab From 0564f7d946efc2948999cc26cc0831fdf81c895e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 12:19:40 +0200 Subject: [PATCH 0532/9457] pinctrl: abx500: force-convert to generic config bindings This converts the ABx500 pin controller and all associated device trees to use the standard, generic config bindings for pin controllers. There are no such device trees deployed in the wild so this is safe to do to set a good example. Signed-off-by: Linus Walleij --- arch/arm/boot/dts/ste-href-ab8500.dtsi | 54 ++++++++++++------------ arch/arm/boot/dts/ste-href-ab8505.dtsi | 30 ++++++------- drivers/pinctrl/nomadik/pinctrl-abx500.c | 4 +- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi index 8be3c471d097..9b69bce9297d 100644 --- a/arch/arm/boot/dts/ste-href-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi @@ -51,7 +51,7 @@ groups = "gpio2_a_1"; }; default_cfg { - ste,pins = "GPIO2_T9"; + pins = "GPIO2_T9"; input-enable; bias-pull-down; }; @@ -64,7 +64,7 @@ groups = "gpio4_a_1"; }; default_cfg { - ste,pins = "GPIO4_W2"; + pins = "GPIO4_W2"; input-enable; bias-pull-down; }; @@ -77,7 +77,7 @@ groups = "gpio10_d_1"; }; default_cfg { - ste,pins = "GPIO10_U17"; + pins = "GPIO10_U17"; input-enable; bias-pull-down; }; @@ -90,7 +90,7 @@ groups = "gpio11_d_1"; }; default_cfg { - ste,pins = "GPIO11_AA18"; + pins = "GPIO11_AA18"; input-enable; bias-pull-down; }; @@ -103,7 +103,7 @@ groups = "gpio12_d_1"; }; default_cfg { - ste,pins = "GPIO12_U16"; + pins = "GPIO12_U16"; input-enable; bias-pull-down; }; @@ -116,7 +116,7 @@ groups = "gpio13_d_1"; }; default_cfg { - ste,pins = "GPIO13_W17"; + pins = "GPIO13_W17"; input-enable; bias-pull-down; }; @@ -129,7 +129,7 @@ groups = "gpio16_a_1"; }; default_cfg { - ste,pins = "GPIO16_F15"; + pins = "GPIO16_F15"; input-enable; bias-pull-down; }; @@ -142,7 +142,7 @@ groups = "gpio24_a_1"; }; default_cfg { - ste,pins = "GPIO24_T14"; + pins = "GPIO24_T14"; input-enable; bias-pull-down; }; @@ -155,7 +155,7 @@ groups = "gpio25_a_1"; }; default_cfg { - ste,pins = "GPIO25_R16"; + pins = "GPIO25_R16"; input-enable; bias-pull-down; }; @@ -168,7 +168,7 @@ groups = "gpio36_a_1"; }; default_cfg { - ste,pins = "GPIO36_A17"; + pins = "GPIO36_A17"; input-enable; bias-pull-down; }; @@ -181,7 +181,7 @@ groups = "gpio37_a_1"; }; default_cfg { - ste,pins = "GPIO37_E15"; + pins = "GPIO37_E15"; input-enable; bias-pull-down; }; @@ -194,7 +194,7 @@ groups = "gpio38_a_1"; }; default_cfg { - ste,pins = "GPIO38_C17"; + pins = "GPIO38_C17"; input-enable; bias-pull-down; }; @@ -207,7 +207,7 @@ groups = "gpio39_a_1"; }; default_cfg { - ste,pins = "GPIO39_E16"; + pins = "GPIO39_E16"; input-enable; bias-pull-down; }; @@ -220,7 +220,7 @@ groups = "gpio42_a_1"; }; default_cfg { - ste,pins = "GPIO42_U2"; + pins = "GPIO42_U2"; input-enable; bias-pull-down; }; @@ -236,7 +236,7 @@ groups = "gpio26_d_1"; }; default_cfg { - ste,pins = "GPIO26_M16"; + pins = "GPIO26_M16"; output-low; }; }; @@ -248,7 +248,7 @@ groups = "gpio35_d_1"; }; default_cfg { - ste,pins = "GPIO35_W15"; + pins = "GPIO35_W15"; output-low; }; }; @@ -264,7 +264,7 @@ groups = "ycbcr0123_d_1"; }; default_cfg { - ste,pins = "GPIO6_Y18", + pins = "GPIO6_Y18", "GPIO7_AA20", "GPIO8_W18", "GPIO9_AA19"; @@ -281,7 +281,7 @@ groups = "pwmout1_d_1", "pwmout2_d_1"; }; default_cfg { - ste,pins = "GPIO14_F14", + pins = "GPIO14_F14", "GPIO15_B17"; input-enable; bias-pull-down; @@ -296,7 +296,7 @@ groups = "adi1_d_1"; }; default_cfg { - ste,pins = "GPIO17_P5", + pins = "GPIO17_P5", "GPIO18_R5", "GPIO19_U5", "GPIO20_T5"; @@ -313,7 +313,7 @@ groups = "usbuicc_d_1"; }; default_cfg { - ste,pins = "GPIO21_H19", + pins = "GPIO21_H19", "GPIO22_G20", "GPIO23_G19"; input-enable; @@ -331,7 +331,7 @@ "dmic56_d_1"; }; default_cfg { - ste,pins = "GPIO27_J6", + pins = "GPIO27_J6", "GPIO28_K6", "GPIO29_G6", "GPIO30_H6", @@ -349,7 +349,7 @@ groups = "extcpena_d_1"; }; default_cfg { - ste,pins = "GPIO34_R17"; + pins = "GPIO34_R17"; input-enable; bias-pull-down; }; @@ -363,7 +363,7 @@ groups = "modsclsda_d_1"; }; default_cfg { - ste,pins = "GPIO40_T19", + pins = "GPIO40_T19", "GPIO41_U19"; input-enable; bias-pull-down; @@ -380,7 +380,7 @@ groups = "sysclkreq2_d_1"; }; default_cfg { - ste,pins = "GPIO1_T10"; + pins = "GPIO1_T10"; input-enable; bias-disable; }; @@ -391,7 +391,7 @@ groups = "gpio1_a_1"; }; default_cfg { - ste,pins = "GPIO1_T10"; + pins = "GPIO1_T10"; input-enable; bias-pull-down; }; @@ -404,7 +404,7 @@ groups = "sysclkreq4_d_1"; }; default_cfg { - ste,pins = "GPIO3_U9"; + pins = "GPIO3_U9"; input-enable; bias-disable; }; @@ -415,7 +415,7 @@ groups = "gpio3_a_1"; }; default_cfg { - ste,pins = "GPIO3_U9"; + pins = "GPIO3_U9"; input-enable; bias-pull-down; }; diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi index 112053c7aa51..ccf37a9df050 100644 --- a/arch/arm/boot/dts/ste-href-ab8505.dtsi +++ b/arch/arm/boot/dts/ste-href-ab8505.dtsi @@ -39,7 +39,7 @@ groups = "gpio2_a_1"; }; default_cfg { - ste,pins = "GPIO2_R5"; + pins = "GPIO2_R5"; input-enable; bias-pull-down; }; @@ -52,7 +52,7 @@ groups = "gpio10_d_1"; }; default_cfg { - ste,pins = "GPIO10_B16"; + pins = "GPIO10_B16"; input-enable; bias-pull-down; }; @@ -65,7 +65,7 @@ groups = "gpio11_d_1"; }; default_cfg { - ste,pins = "GPIO11_B17"; + pins = "GPIO11_B17"; input-enable; bias-pull-down; }; @@ -78,7 +78,7 @@ groups = "gpio13_d_1"; }; default_cfg { - ste,pins = "GPIO13_D17"; + pins = "GPIO13_D17"; input-enable; bias-disable; }; @@ -91,7 +91,7 @@ groups = "gpio34_a_1"; }; default_cfg { - ste,pins = "GPIO34_H14"; + pins = "GPIO34_H14"; input-enable; bias-pull-down; }; @@ -104,7 +104,7 @@ groups = "gpio50_d_1"; }; default_cfg { - ste,pins = "GPIO50_L4"; + pins = "GPIO50_L4"; input-enable; bias-disable; }; @@ -118,7 +118,7 @@ groups = "pwmout1_d_1"; }; default_cfg { - ste,pins = "GPIO14_C16"; + pins = "GPIO14_C16"; input-enable; bias-pull-down; }; @@ -132,7 +132,7 @@ groups = "adi2_d_1"; }; default_cfg { - ste,pins = "GPIO17_P2", + pins = "GPIO17_P2", "GPIO18_N3", "GPIO19_T1", "GPIO20_P3"; @@ -149,7 +149,7 @@ groups = "modsclsda_d_1"; }; default_cfg { - ste,pins = "GPIO40_J15", + pins = "GPIO40_J15", "GPIO41_J14"; input-enable; bias-pull-down; @@ -163,7 +163,7 @@ groups = "resethw_d_1"; }; default_cfg { - ste,pins = "GPIO52_D16"; + pins = "GPIO52_D16"; input-enable; bias-pull-down; }; @@ -176,7 +176,7 @@ groups = "service_d_1"; }; default_cfg { - ste,pins = "GPIO53_D15"; + pins = "GPIO53_D15"; input-enable; bias-pull-down; }; @@ -192,7 +192,7 @@ groups = "sysclkreq2_d_1"; }; default_cfg { - ste,pins = "GPIO1_N4"; + pins = "GPIO1_N4"; input-enable; bias-disable; }; @@ -203,7 +203,7 @@ groups = "gpio1_a_1"; }; default_cfg { - ste,pins = "GPIO1_N4"; + pins = "GPIO1_N4"; input-enable; bias-pull-down; }; @@ -216,7 +216,7 @@ groups = "sysclkreq4_d_1"; }; default_cfg { - ste,pins = "GPIO3_P5"; + pins = "GPIO3_P5"; input-enable; bias-disable; }; @@ -227,7 +227,7 @@ groups = "gpio3_a_1"; }; default_cfg { - ste,pins = "GPIO3_P5"; + pins = "GPIO3_P5"; input-enable; bias-pull-down; }; diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index d0c0454dce0d..7130cd668c96 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -931,7 +931,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, const char *gpio_name; const char *pin; - ret = of_property_count_strings(np, "ste,pins"); + ret = of_property_count_strings(np, "pins"); if (ret < 0) goto exit; @@ -941,7 +941,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_string(np, "ste,pins", prop, pin) { + of_property_for_each_string(np, "pins", prop, pin) { gpio_name = abx500_find_pin_name(pctldev, pin); ret = abx500_dt_add_map_configs(map, reserved_maps, -- GitLab From eea11b0baa63ed871e16ca4513db56341e4c3598 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 12:23:15 +0200 Subject: [PATCH 0533/9457] pinctrl: abx500: retire phandle config mechanism The abx500 pin control driver supported a method of fetching the generic config from a phandle to a separate node using the "ste,config" as a phandle. This is not used in any device trees and not documented in the bindings, so drop this support. Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-abx500.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 7130cd668c96..acd17a21a159 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -891,9 +891,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, const char *function = NULL; unsigned long *configs; unsigned int nconfigs = 0; - bool has_config = 0; struct property *prop; - struct device_node *np_config; ret = of_property_read_string(np, "function", &function); if (ret >= 0) { @@ -917,17 +915,7 @@ static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev, } ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs); - if (nconfigs) - has_config = 1; - np_config = of_parse_phandle(np, "ste,config", 0); - if (np_config) { - ret = pinconf_generic_parse_dt_config(np_config, &configs, - &nconfigs); - if (ret) - goto exit; - has_config |= nconfigs; - } - if (has_config) { + if (nconfigs) { const char *gpio_name; const char *pin; -- GitLab From 4944d2cac6de0aec02032bdda45668c932bb6732 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 12:29:19 +0200 Subject: [PATCH 0534/9457] pinctrl: abx500: update device tree bindings After force converting the ABx500 bindings in the driver and device tree sources, also update the binding documentation to state that we are now using standard bindings. Signed-off-by: Linus Walleij --- .../bindings/pinctrl/ste,abx500.txt | 184 +++++++----------- 1 file changed, 75 insertions(+), 109 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt b/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt index e3865e136067..87697420439e 100644 --- a/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt +++ b/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt @@ -8,42 +8,8 @@ Please refer to pinctrl-bindings.txt in this directory for details of the common pinctrl bindings used by client devices, including the meaning of the phrase "pin configuration node". -ST Ericsson's pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those pin(s)/group(s), and various pin configuration -parameters, such as input, output, pull up, pull down... - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Required subnode-properties: -- ste,pins : An array of strings. Each string contains the name of a pin or - group. - -Optional subnode-properties: -- ste,function: A string containing the name of the function to mux to the - pin or group. - -- generic pin configuration option to use. Example : - - default_cfg { - ste,pins = "GPIO1"; - bias-disable; - }; - -- ste,config: Handle of pin configuration node containing the generic - pinconfig options to use, as described in pinctrl-bindings.txt in - this directory. Example : - - pcfg_bias_disable: pcfg_bias_disable { - bias-disable; - }; - - default_cfg { - ste,pins = "GPIO1"; - ste.config = <&pcfg_bias_disable>; - }; +ST Ericsson's pin configuration nodes use the generic pin multiplexing +and pin configuration bindings, see pinctrl-bindings.txt Example board file extract: @@ -54,11 +20,11 @@ Example board file extract: sysclkreq2 { sysclkreq2_default_mode: sysclkreq2_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq2_d_1"; + function = "sysclkreq"; + groups = "sysclkreq2_d_1"; }; default_cfg { - ste,pins = "GPIO1"; + pins = "GPIO1"; bias-disable; }; }; @@ -66,11 +32,11 @@ Example board file extract: sysclkreq3 { sysclkreq3_default_mode: sysclkreq3_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq3_d_1"; + function = "sysclkreq"; + groups = "sysclkreq3_d_1"; }; default_cfg { - ste,pins = "GPIO2"; + pins = "GPIO2"; output-low; }; }; @@ -78,11 +44,11 @@ Example board file extract: gpio3 { gpio3_default_mode: gpio3_default { default_mux { - ste,function = "gpio"; - ste,pins = "gpio3_a_1"; + function = "gpio"; + groups = "gpio3_a_1"; }; default_cfg { - ste,pins = "GPIO3"; + pins = "GPIO3"; output-low; }; }; @@ -90,11 +56,11 @@ Example board file extract: sysclkreq6 { sysclkreq6_default_mode: sysclkreq6_default { default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq6_d_1"; + function = "sysclkreq"; + groups = "sysclkreq6_d_1"; }; default_cfg { - ste,pins = "GPIO4"; + pins = "GPIO4"; bias-disable; }; }; @@ -102,11 +68,11 @@ Example board file extract: pwmout1 { pwmout1_default_mode: pwmout1_default { default_mux { - ste,function = "pwmout"; - ste,pins = "pwmout1_d_1"; + function = "pwmout"; + groups = "pwmout1_d_1"; }; default_cfg { - ste,pins = "GPIO14"; + pins = "GPIO14"; output-low; }; }; @@ -114,11 +80,11 @@ Example board file extract: pwmout2 { pwmout2_default_mode: pwmout2_default { pwmout2_default_mux { - ste,function = "pwmout"; - ste,pins = "pwmout2_d_1"; + function = "pwmout"; + groups = "pwmout2_d_1"; }; pwmout2_default_cfg { - ste,pins = "GPIO15"; + pins = "GPIO15"; output-low; }; }; @@ -126,11 +92,11 @@ Example board file extract: pwmout3 { pwmout3_default_mode: pwmout3_default { pwmout3_default_mux { - ste,function = "pwmout"; - ste,pins = "pwmout3_d_1"; + function = "pwmout"; + groups = "pwmout3_d_1"; }; pwmout3_default_cfg { - ste,pins = "GPIO16"; + pins = "GPIO16"; output-low; }; }; @@ -139,15 +105,15 @@ Example board file extract: adi1_default_mode: adi1_default { adi1_default_mux { - ste,function = "adi1"; - ste,pins = "adi1_d_1"; + function = "adi1"; + groups = "adi1_d_1"; }; adi1_default_cfg1 { - ste,pins = "GPIO17","GPIO19","GPIO20"; + pins = "GPIO17","GPIO19","GPIO20"; bias-disable; }; adi1_default_cfg2 { - ste,pins = "GPIO18"; + pins = "GPIO18"; output-low; }; }; @@ -155,15 +121,15 @@ Example board file extract: dmic12 { dmic12_default_mode: dmic12_default { dmic12_default_mux { - ste,function = "dmic"; - ste,pins = "dmic12_d_1"; + function = "dmic"; + groups = "dmic12_d_1"; }; dmic12_default_cfg1 { - ste,pins = "GPIO27"; + pins = "GPIO27"; output-low; }; dmic12_default_cfg2 { - ste,pins = "GPIO28"; + pins = "GPIO28"; bias-disable; }; }; @@ -171,15 +137,15 @@ Example board file extract: dmic34 { dmic34_default_mode: dmic34_default { dmic34_default_mux { - ste,function = "dmic"; - ste,pins = "dmic34_d_1"; + function = "dmic"; + groups = "dmic34_d_1"; }; dmic34_default_cfg1 { - ste,pins = "GPIO29"; + pins = "GPIO29"; output-low; }; dmic34_default_cfg2 { - ste,pins = "GPIO30"; + pins = "GPIO30"; bias-disable;{ }; @@ -188,15 +154,15 @@ Example board file extract: dmic56 { dmic56_default_mode: dmic56_default { dmic56_default_mux { - ste,function = "dmic"; - ste,pins = "dmic56_d_1"; + function = "dmic"; + groups = "dmic56_d_1"; }; dmic56_default_cfg1 { - ste,pins = "GPIO31"; + pins = "GPIO31"; output-low; }; dmic56_default_cfg2 { - ste,pins = "GPIO32"; + pins = "GPIO32"; bias-disable; }; }; @@ -204,11 +170,11 @@ Example board file extract: sysclkreq5 { sysclkreq5_default_mode: sysclkreq5_default { sysclkreq5_default_mux { - ste,function = "sysclkreq"; - ste,pins = "sysclkreq5_d_1"; + function = "sysclkreq"; + groups = "sysclkreq5_d_1"; }; sysclkreq5_default_cfg { - ste,pins = "GPIO42"; + pins = "GPIO42"; output-low; }; }; @@ -216,11 +182,11 @@ Example board file extract: batremn { batremn_default_mode: batremn_default { batremn_default_mux { - ste,function = "batremn"; - ste,pins = "batremn_d_1"; + function = "batremn"; + groups = "batremn_d_1"; }; batremn_default_cfg { - ste,pins = "GPIO43"; + pins = "GPIO43"; bias-disable; }; }; @@ -228,11 +194,11 @@ Example board file extract: service { service_default_mode: service_default { service_default_mux { - ste,function = "service"; - ste,pins = "service_d_1"; + function = "service"; + groups = "service_d_1"; }; service_default_cfg { - ste,pins = "GPIO44"; + pins = "GPIO44"; bias-disable; }; }; @@ -240,13 +206,13 @@ Example board file extract: pwrctrl0 { pwrctrl0_default_mux: pwrctrl0_mux { pwrctrl0_default_mux { - ste,function = "pwrctrl"; - ste,pins = "pwrctrl0_d_1"; + function = "pwrctrl"; + groups = "pwrctrl0_d_1"; }; }; pwrctrl0_default_mode: pwrctrl0_default { pwrctrl0_default_cfg { - ste,pins = "GPIO45"; + pins = "GPIO45"; bias-disable; }; }; @@ -254,13 +220,13 @@ Example board file extract: pwrctrl1 { pwrctrl1_default_mux: pwrctrl1_mux { pwrctrl1_default_mux { - ste,function = "pwrctrl"; - ste,pins = "pwrctrl1_d_1"; + function = "pwrctrl"; + groups = "pwrctrl1_d_1"; }; }; pwrctrl1_default_mode: pwrctrl1_default { pwrctrl1_default_cfg { - ste,pins = "GPIO46"; + pins = "GPIO46"; bias-disable; }; }; @@ -268,11 +234,11 @@ Example board file extract: pwmextvibra1 { pwmextvibra1_default_mode: pwmextvibra1_default { pwmextvibra1_default_mux { - ste,function = "pwmextvibra"; - ste,pins = "pwmextvibra1_d_1"; + function = "pwmextvibra"; + groups = "pwmextvibra1_d_1"; }; pwmextvibra1_default_cfg { - ste,pins = "GPIO47"; + pins = "GPIO47"; bias-disable; }; }; @@ -280,11 +246,11 @@ Example board file extract: pwmextvibra2 { pwmextvibra2_default_mode: pwmextvibra2_default { pwmextvibra2_default_mux { - ste,function = "pwmextvibra"; - ste,pins = "pwmextvibra2_d_1"; + function = "pwmextvibra"; + groups = "pwmextvibra2_d_1"; }; pwmextvibra1_default_cfg { - ste,pins = "GPIO48"; + pins = "GPIO48"; bias-disable; }; }; @@ -292,11 +258,11 @@ Example board file extract: gpio51 { gpio51_default_mode: gpio51_default { gpio51_default_mux { - ste,function = "gpio"; - ste,pins = "gpio51_a_1"; + function = "gpio"; + groups = "gpio51_a_1"; }; gpio51_default_cfg { - ste,pins = "GPIO51"; + pins = "GPIO51"; output-low; }; }; @@ -304,11 +270,11 @@ Example board file extract: gpio52 { gpio52_default_mode: gpio52_default { gpio52_default_mux { - ste,function = "gpio"; - ste,pins = "gpio52_a_1"; + function = "gpio"; + groups = "gpio52_a_1"; }; gpio52_default_cfg { - ste,pins = "GPIO52"; + pins = "GPIO52"; bias-pull-down; }; }; @@ -316,11 +282,11 @@ Example board file extract: gpio53 { gpio53_default_mode: gpio53_default { gpio53_default_mux { - ste,function = "gpio"; - ste,pins = "gpio53_a_1"; + function = "gpio"; + groups = "gpio53_a_1"; }; gpio53_default_cfg { - ste,pins = "GPIO53"; + pins = "GPIO53"; bias-pull-down; }; }; @@ -328,11 +294,11 @@ Example board file extract: gpio54 { gpio54_default_mode: gpio54_default { gpio54_default_mux { - ste,function = "gpio"; - ste,pins = "gpio54_a_1"; + function = "gpio"; + groups = "gpio54_a_1"; }; gpio54_default_cfg { - ste,pins = "GPIO54"; + pins = "GPIO54"; output-low; }; }; @@ -340,11 +306,11 @@ Example board file extract: pdmclkdat { pdmclkdat_default_mode: pdmclkdat_default { pdmclkdat_default_mux { - ste,function = "pdm"; - ste,pins = "pdmclkdat_d_1"; + function = "pdm"; + groups = "pdmclkdat_d_1"; }; pdmclkdat_default_cfg { - ste,pins = "GPIO55", "GPIO56"; + pins = "GPIO55", "GPIO56"; bias-disable; }; }; -- GitLab From 71ca917a60738731b0609abea8f3e320e43cb0a1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Sep 2014 13:12:28 +0200 Subject: [PATCH 0535/9457] pinctrl: abx500: mark pin config as generic This is generic pin configuration, so add .is_generic. Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-abx500.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index acd17a21a159..e1087c75e4f4 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -1104,6 +1104,7 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, static const struct pinconf_ops abx500_pinconf_ops = { .pin_config_get = abx500_pin_config_get, .pin_config_set = abx500_pin_config_set, + .is_generic = true, }; static struct pinctrl_desc abx500_pinctrl_desc = { -- GitLab From dc603c650afdc3182df0694b4a5a0454674af18f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 18 Oct 2014 14:57:53 +0200 Subject: [PATCH 0536/9457] pinctrl: nomadik: amend MMC/SD pins There is a missing MMC/SD pin for MCDATDIR2 which is routed as alt B, add it to the MMC/SD pin group and functions. Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c index ed39dcafd4f8..2cd71470f270 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c @@ -291,6 +291,7 @@ static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5, static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10, STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12, STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 }; +static const unsigned mmcsd_b_1_pins[] = { STN8815_PIN_D15 }; static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1, STN8815_PIN_F3, STN8815_PIN_F2 }; static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 }; @@ -305,6 +306,7 @@ static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 }; static const struct nmk_pingroup nmk_stn8815_groups[] = { STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A), STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A), + STN8815_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B), STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A), STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A), STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), @@ -317,7 +319,7 @@ static const struct nmk_pingroup nmk_stn8815_groups[] = { static const char * const a##_groups[] = { b }; STN8815_FUNC_GROUPS(u0, "u0_a_1"); -STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1"); +STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1", "mmcsd_b_1"); STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1"); STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1"); STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1"); -- GitLab From de7d6c3eebbe6da47c07f048ca689e10f194b842 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Wed, 8 Oct 2014 01:55:16 -0700 Subject: [PATCH 0537/9457] clk: rockchip: fix parent for spdif_8ch_frac on rk3288 The parent should be spdif_8ch_pre not spdif_8ch_src, which doesn't exist and looks to be a typo. The TRM also confirms this. Signed-off-by: Sonny Rao Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 23278291da44..e41ae1f4cd29 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -325,7 +325,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 7, GFLAGS), - COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0, + COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0, RK3288_CLKSEL_CON(41), 0, RK3288_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, -- GitLab From 61e309f322f264917e5dcbd7ea773df1db53629a Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 6 Oct 2014 10:15:27 -0700 Subject: [PATCH 0538/9457] clk: rockchip: Add CLK_SET_RATE_PARENT to aclk_cpu_pre We'd like to be able to call clk_set_rate() on aclk_cpu (a gate) at bootup. In order for this to have any effect we need its parent (aclk_cpu_pre) to percolate the rate change to _its_ parent (aclk_cpu_src). Add CLK_SET_RATE_PARENT to make this happen. Signed-off-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index e41ae1f4cd29..4670bd8335a1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -279,7 +279,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 11, GFLAGS), COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), - DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, + DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, RK3288_CLKGATE_CON(0), 3, GFLAGS), -- GitLab From cd9b4609a5621021f6c10ac09e1ddaabc677a814 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 9 Oct 2014 21:50:29 -0700 Subject: [PATCH 0539/9457] clk: rockchip: add 400MHz and 500MHz for rk3288 clock rate This patch add 400MHz and 500MHz to clock rate table for rk3288. Signed-off-by: Kever Yang Reviewed-by: Doug Anderson Tested-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 4670bd8335a1..c3706431ed10 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -86,8 +86,10 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE( 594000000, 2, 198, 4), RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 504000000, 1, 84, 4), + RK3066_PLL_RATE( 500000000, 3, 125, 2), RK3066_PLL_RATE( 456000000, 1, 76, 4), RK3066_PLL_RATE( 408000000, 1, 68, 4), + RK3066_PLL_RATE( 400000000, 3, 100, 2), RK3066_PLL_RATE( 384000000, 2, 128, 4), RK3066_PLL_RATE( 360000000, 1, 60, 4), RK3066_PLL_RATE( 312000000, 1, 52, 4), -- GitLab From ae11601b80b984859deda1f2d430a23bfabd3bea Mon Sep 17 00:00:00 2001 From: Ramesh Babu Date: Wed, 15 Oct 2014 12:34:59 +0530 Subject: [PATCH 0540/9457] ASoC: core: Call mute for cpu dais as well We call mute for codec dai only, we should call this for cpu dai as well to allow cpu dais (FEs) in DSPs to be muted/unmuted on shutdown/startup Signed-off-by: Ramesh Babu Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 002311afdeaa..1cd027a97106 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -654,6 +654,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) codec_dai->rate = 0; } + snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream); + if (cpu_dai->driver->ops->shutdown) cpu_dai->driver->ops->shutdown(substream, cpu_dai); @@ -772,6 +774,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) for (i = 0; i < rtd->num_codecs; i++) snd_soc_dai_digital_mute(rtd->codec_dais[i], 0, substream->stream); + snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream); out: mutex_unlock(&rtd->pcm_mutex); -- GitLab From fd587e320041d42eb21d12bb62da9e8ac08fd6c2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Oct 2014 23:14:23 +0800 Subject: [PATCH 0541/9457] ASoC: cs4265: Remove unused *dev field from struct cs4265_private Signed-off-by: Axel Lin Acked-by: Paul Handrigan Signed-off-by: Mark Brown --- sound/soc/codecs/cs4265.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 4fdd47d700e3..ce6086835ebd 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -32,7 +32,6 @@ #include "cs4265.h" struct cs4265_private { - struct device *dev; struct regmap *regmap; struct gpio_desc *reset_gpio; u8 format; @@ -598,7 +597,6 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client, GFP_KERNEL); if (cs4265 == NULL) return -ENOMEM; - cs4265->dev = &i2c_client->dev; cs4265->regmap = devm_regmap_init_i2c(i2c_client, &cs4265_regmap); if (IS_ERR(cs4265->regmap)) { -- GitLab From c973b8a7dc50ace86393f209b19aa7fd0bfaf66b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Oct 2014 23:09:47 +0800 Subject: [PATCH 0542/9457] ASoC: cs4271: Split SPI and I2C code into different modules Currently the cs4271 driver depends on SND_SOC_I2C_AND_SPI. So the driver cannot be built as built-in if CONFIG_I2C=m. Split SPI and I2C code into different modules to avoid this issue. Signed-off-by: Axel Lin Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/cirrus/Kconfig | 3 +- sound/soc/codecs/Kconfig | 18 +++- sound/soc/codecs/Makefile | 4 + sound/soc/codecs/cs4271-i2c.c | 62 ++++++++++++++ sound/soc/codecs/cs4271-spi.c | 55 ++++++++++++ sound/soc/codecs/cs4271.c | 155 ++++------------------------------ sound/soc/codecs/cs4271.h | 11 +++ 7 files changed, 167 insertions(+), 141 deletions(-) create mode 100644 sound/soc/codecs/cs4271-i2c.c create mode 100644 sound/soc/codecs/cs4271-spi.c create mode 100644 sound/soc/codecs/cs4271.h diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 5477c5475923..7b7fbcd49e5e 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig @@ -36,7 +36,8 @@ config SND_EP93XX_SOC_EDB93XX tristate "SoC Audio support for Cirrus Logic EDB93xx boards" depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A) select SND_EP93XX_SOC_I2S - select SND_SOC_CS4271 + select SND_SOC_CS4271_I2C if I2C + select SND_SOC_CS4271_SPI if SPI_MASTER help Say Y or M here if you want to add support for I2S audio on the Cirrus Logic EDB93xx boards. diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..765062551027 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -50,7 +50,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_CS42L73 if I2C select SND_SOC_CS4265 if I2C select SND_SOC_CS4270 if I2C - select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI + select SND_SOC_CS4271_I2C if I2C + select SND_SOC_CS4271_SPI if SPI_MASTER select SND_SOC_CS42XX8_I2C if I2C select SND_SOC_CX20442 if TTY select SND_SOC_DA7210 if I2C @@ -370,8 +371,19 @@ config SND_SOC_CS4270_VD33_ERRATA depends on SND_SOC_CS4270 config SND_SOC_CS4271 - tristate "Cirrus Logic CS4271 CODEC" - depends on SND_SOC_I2C_AND_SPI + tristate + +config SND_SOC_CS4271_I2C + tristate "Cirrus Logic CS4271 CODEC (I2C)" + depends on I2C + select SND_SOC_CS4271 + select REGMAP_I2C + +config SND_SOC_CS4271_SPI + tristate "Cirrus Logic CS4271 CODEC (SPI)" + depends on SPI_MASTER + select SND_SOC_CS4271 + select REGMAP_SPI config SND_SOC_CS42XX8 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 5dce451661e4..ac7ec31f8cbe 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -41,6 +41,8 @@ snd-soc-cs42l73-objs := cs42l73.o snd-soc-cs4265-objs := cs4265.o snd-soc-cs4270-objs := cs4270.o snd-soc-cs4271-objs := cs4271.o +snd-soc-cs4271-i2c-objs := cs4271-i2c.o +snd-soc-cs4271-spi-objs := cs4271-spi.o snd-soc-cs42xx8-objs := cs42xx8.o snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o snd-soc-cx20442-objs := cx20442.o @@ -217,6 +219,8 @@ obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o obj-$(CONFIG_SND_SOC_CS4265) += snd-soc-cs4265.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o +obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o +obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o diff --git a/sound/soc/codecs/cs4271-i2c.c b/sound/soc/codecs/cs4271-i2c.c new file mode 100644 index 000000000000..b264da030340 --- /dev/null +++ b/sound/soc/codecs/cs4271-i2c.c @@ -0,0 +1,62 @@ +/* + * CS4271 I2C audio driver + * + * Copyright (c) 2010 Alexander Sverdlin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include "cs4271.h" + +static int cs4271_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap_config config; + + config = cs4271_regmap_config; + config.reg_bits = 8; + config.val_bits = 8; + + return cs4271_probe(&client->dev, + devm_regmap_init_i2c(client, &config)); +} + +static int cs4271_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id cs4271_i2c_id[] = { + { "cs4271", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); + +static struct i2c_driver cs4271_i2c_driver = { + .driver = { + .name = "cs4271", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(cs4271_dt_ids), + }, + .probe = cs4271_i2c_probe, + .remove = cs4271_i2c_remove, + .id_table = cs4271_i2c_id, +}; +module_i2c_driver(cs4271_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS4271 I2C Driver"); +MODULE_AUTHOR("Alexander Sverdlin "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs4271-spi.c b/sound/soc/codecs/cs4271-spi.c new file mode 100644 index 000000000000..acd49d86e706 --- /dev/null +++ b/sound/soc/codecs/cs4271-spi.c @@ -0,0 +1,55 @@ +/* + * CS4271 SPI audio driver + * + * Copyright (c) 2010 Alexander Sverdlin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include "cs4271.h" + +static int cs4271_spi_probe(struct spi_device *spi) +{ + struct regmap_config config; + + config = cs4271_regmap_config; + config.reg_bits = 16; + config.val_bits = 8; + config.read_flag_mask = 0x21; + config.write_flag_mask = 0x20; + + return cs4271_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); +} + +static int cs4271_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + return 0; +} + +static struct spi_driver cs4271_spi_driver = { + .driver = { + .name = "cs4271", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(cs4271_dt_ids), + }, + .probe = cs4271_spi_probe, + .remove = cs4271_spi_remove, +}; +module_spi_driver(cs4271_spi_driver); + +MODULE_DESCRIPTION("ASoC CS4271 SPI Driver"); +MODULE_AUTHOR("Alexander Sverdlin "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 93cec52f4733..79a4efcb894c 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include #include @@ -32,6 +30,7 @@ #include #include #include +#include "cs4271.h" #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ @@ -527,14 +526,15 @@ static int cs4271_soc_resume(struct snd_soc_codec *codec) #endif /* CONFIG_PM */ #ifdef CONFIG_OF -static const struct of_device_id cs4271_dt_ids[] = { +const struct of_device_id cs4271_dt_ids[] = { { .compatible = "cirrus,cs4271", }, { } }; MODULE_DEVICE_TABLE(of, cs4271_dt_ids); +EXPORT_SYMBOL_GPL(cs4271_dt_ids); #endif -static int cs4271_probe(struct snd_soc_codec *codec) +static int cs4271_codec_probe(struct snd_soc_codec *codec) { struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; @@ -587,7 +587,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) return 0; } -static int cs4271_remove(struct snd_soc_codec *codec) +static int cs4271_codec_remove(struct snd_soc_codec *codec) { struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); @@ -599,8 +599,8 @@ static int cs4271_remove(struct snd_soc_codec *codec) }; static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { - .probe = cs4271_probe, - .remove = cs4271_remove, + .probe = cs4271_codec_probe, + .remove = cs4271_codec_remove, .suspend = cs4271_soc_suspend, .resume = cs4271_soc_resume, @@ -642,14 +642,8 @@ static int cs4271_common_probe(struct device *dev, return 0; } -#if defined(CONFIG_SPI_MASTER) - -static const struct regmap_config cs4271_spi_regmap = { - .reg_bits = 16, - .val_bits = 8, +const struct regmap_config cs4271_regmap_config = { .max_register = CS4271_LASTREG, - .read_flag_mask = 0x21, - .write_flag_mask = 0x20, .reg_defaults = cs4271_reg_defaults, .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), @@ -657,140 +651,27 @@ static const struct regmap_config cs4271_spi_regmap = { .volatile_reg = cs4271_volatile_reg, }; +EXPORT_SYMBOL_GPL(cs4271_regmap_config); -static int cs4271_spi_probe(struct spi_device *spi) +int cs4271_probe(struct device *dev, struct regmap *regmap) { struct cs4271_private *cs4271; int ret; - ret = cs4271_common_probe(&spi->dev, &cs4271); - if (ret < 0) - return ret; - - spi_set_drvdata(spi, cs4271); - cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); - if (IS_ERR(cs4271->regmap)) - return PTR_ERR(cs4271->regmap); - - return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, - &cs4271_dai, 1); -} - -static int cs4271_spi_remove(struct spi_device *spi) -{ - snd_soc_unregister_codec(&spi->dev); - return 0; -} - -static struct spi_driver cs4271_spi_driver = { - .driver = { - .name = "cs4271", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(cs4271_dt_ids), - }, - .probe = cs4271_spi_probe, - .remove = cs4271_spi_remove, -}; -#endif /* defined(CONFIG_SPI_MASTER) */ - -#if IS_ENABLED(CONFIG_I2C) -static const struct i2c_device_id cs4271_i2c_id[] = { - {"cs4271", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); -static const struct regmap_config cs4271_i2c_regmap = { - .reg_bits = 8, - .val_bits = 8, - .max_register = CS4271_LASTREG, - - .reg_defaults = cs4271_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), - .cache_type = REGCACHE_RBTREE, - - .volatile_reg = cs4271_volatile_reg, -}; - -static int cs4271_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct cs4271_private *cs4271; - int ret; - - ret = cs4271_common_probe(&client->dev, &cs4271); + ret = cs4271_common_probe(dev, &cs4271); if (ret < 0) return ret; - i2c_set_clientdata(client, cs4271); - cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); - if (IS_ERR(cs4271->regmap)) - return PTR_ERR(cs4271->regmap); + dev_set_drvdata(dev, cs4271); + cs4271->regmap = regmap; - return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, - &cs4271_dai, 1); -} - -static int cs4271_i2c_remove(struct i2c_client *client) -{ - snd_soc_unregister_codec(&client->dev); - return 0; -} - -static struct i2c_driver cs4271_i2c_driver = { - .driver = { - .name = "cs4271", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(cs4271_dt_ids), - }, - .id_table = cs4271_i2c_id, - .probe = cs4271_i2c_probe, - .remove = cs4271_i2c_remove, -}; -#endif /* IS_ENABLED(CONFIG_I2C) */ - -/* - * We only register our serial bus driver here without - * assignment to particular chip. So if any of the below - * fails, there is some problem with I2C or SPI subsystem. - * In most cases this module will be compiled with support - * of only one serial bus. - */ -static int __init cs4271_modinit(void) -{ - int ret; - -#if IS_ENABLED(CONFIG_I2C) - ret = i2c_add_driver(&cs4271_i2c_driver); - if (ret) { - pr_err("Failed to register CS4271 I2C driver: %d\n", ret); - return ret; - } -#endif - -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&cs4271_spi_driver); - if (ret) { - pr_err("Failed to register CS4271 SPI driver: %d\n", ret); - return ret; - } -#endif - - return 0; -} -module_init(cs4271_modinit); - -static void __exit cs4271_modexit(void) -{ -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&cs4271_spi_driver); -#endif - -#if IS_ENABLED(CONFIG_I2C) - i2c_del_driver(&cs4271_i2c_driver); -#endif + return snd_soc_register_codec(dev, &soc_codec_dev_cs4271, &cs4271_dai, + 1); } -module_exit(cs4271_modexit); +EXPORT_SYMBOL_GPL(cs4271_probe); MODULE_AUTHOR("Alexander Sverdlin "); MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver"); diff --git a/sound/soc/codecs/cs4271.h b/sound/soc/codecs/cs4271.h new file mode 100644 index 000000000000..9adad8eefdc9 --- /dev/null +++ b/sound/soc/codecs/cs4271.h @@ -0,0 +1,11 @@ +#ifndef _CS4271_PRIV_H +#define _CS4271_PRIV_H + +#include + +extern const struct of_device_id cs4271_dt_ids[]; +extern const struct regmap_config cs4271_regmap_config; + +int cs4271_probe(struct device *dev, struct regmap *regmap); + +#endif -- GitLab From 051c77e552bf1c80adf3fb2fa5e145ca7c9b0f08 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 15:13:24 -0300 Subject: [PATCH 0543/9457] ASoC: fsl: imx-wm8962: Delete unneeded test before of_node_put of_node_put() supports NULL as its argument, so the initial test is not necessary. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/imx-wm8962.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 3a3d17ce6ba4..48179ffe1543 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c @@ -281,10 +281,8 @@ static int imx_wm8962_probe(struct platform_device *pdev) clk_fail: clk_disable_unprepare(data->codec_clk); fail: - if (ssi_np) - of_node_put(ssi_np); - if (codec_np) - of_node_put(codec_np); + of_node_put(ssi_np); + of_node_put(codec_np); return ret; } -- GitLab From 7e3bc3c1c9017867b88593ecb4c0c1ae9da16fb2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 15:13:25 -0300 Subject: [PATCH 0544/9457] ASoC: fsl: imx-sgtl5000: Delete unneeded test before of_node_put of_node_put() supports NULL as its argument, so the initial test is not necessary. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/imx-sgtl5000.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 1cb22dd034eb..1dab963a59f7 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -175,10 +175,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) fail: if (data && !IS_ERR(data->codec_clk)) clk_put(data->codec_clk); - if (ssi_np) - of_node_put(ssi_np); - if (codec_np) - of_node_put(codec_np); + of_node_put(ssi_np); + of_node_put(codec_np); return ret; } -- GitLab From aa4ac9201676ddd35aa56ae74bdf8e07454f04fc Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 15:29:56 -0300 Subject: [PATCH 0545/9457] ASoC: fsl: imx-spdif: Delete unneeded test before of_node_put of_node_put() supports NULL as its argument, so the initial test is not necessary. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/imx-spdif.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c index e1dc40143600..0c9068ebe1e7 100644 --- a/sound/soc/fsl/imx-spdif.c +++ b/sound/soc/fsl/imx-spdif.c @@ -74,8 +74,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); end: - if (spdif_np) - of_node_put(spdif_np); + of_node_put(spdif_np); return ret; } -- GitLab From 89dea487646831d47b0c56723a7c43c62b094c48 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 15:29:57 -0300 Subject: [PATCH 0546/9457] ASoC: fsl: eukrea-tlv320: Delete unneeded test before of_node_put of_node_put() supports NULL as its argument, so the initial test is not necessary. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/eukrea-tlv320.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index eb093d5b85c4..dd931fa5a813 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -217,8 +217,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) err: if (ret) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); - if (np) - of_node_put(ssi_np); + of_node_put(ssi_np); return ret; } -- GitLab From 077661b6ed24e530dabc9db3ab3ae48fbaf19679 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 7 Oct 2014 20:56:29 +0200 Subject: [PATCH 0547/9457] ASoC: eukrea-tlv320: Fix of_node_put() call with uninitialized object The of_node_put() call in eukrea_tlv320_probe() may take an uninitialized pointer, as compiler spotted out: sound/soc/fsl/eukrea-tlv320.c:221:14: warning: 'ssi_np' may be used uninitialized in this function [-Wuninitialized] This patch adds the proper NULL initializations as a fix. (codec_np is also NULL initialized just for consistency.) Fixes: 66f232908de2 ('ASoC: eukrea-tlv320: Add DT support') Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown --- sound/soc/fsl/eukrea-tlv320.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index dd931fa5a813..b175b0145a42 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -105,7 +105,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) int ret; int int_port = 0, ext_port; struct device_node *np = pdev->dev.of_node; - struct device_node *ssi_np, *codec_np; + struct device_node *ssi_np = NULL, *codec_np = NULL; eukrea_tlv320.dev = &pdev->dev; if (np) { -- GitLab From 73a2cd9193ae50d4cc7c447f8929e13010b589be Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:04 -0700 Subject: [PATCH 0548/9457] ASoC: fsl_esai: Add indentation for binding doc to increase readability This patch simply adds indentations for DT binding doc to increase readability without changing any contents. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,esai.txt | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt index 52f5b6bf3e8e..d3b6b5f48010 100644 --- a/Documentation/devicetree/bindings/sound/fsl,esai.txt +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt @@ -7,37 +7,39 @@ other DSPs. It has up to six transmitters and four receivers. Required properties: - - compatible : Compatible list, must contain "fsl,imx35-esai" or - "fsl,vf610-esai" + - compatible : Compatible list, must contain "fsl,imx35-esai" or + "fsl,vf610-esai" - - reg : Offset and length of the register set for the device. + - reg : Offset and length of the register set for the device. - - interrupts : Contains the spdif interrupt. + - interrupts : Contains the spdif interrupt. - - dmas : Generic dma devicetree binding as described in - Documentation/devicetree/bindings/dma/dma.txt. + - dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. - - dma-names : Two dmas have to be defined, "tx" and "rx". + - dma-names : Two dmas have to be defined, "tx" and "rx". - - clocks: Contains an entry for each entry in clock-names. + - clocks : Contains an entry for each entry in clock-names. - - clock-names : Includes the following entries: - "core" The core clock used to access registers - "extal" The esai baud clock for esai controller used to derive - HCK, SCK and FS. - "fsys" The system clock derived from ahb clock used to derive - HCK, SCK and FS. + - clock-names : Includes the following entries: + "core" The core clock used to access registers + "extal" The esai baud clock for esai controller used to + derive HCK, SCK and FS. + "fsys" The system clock derived from ahb clock used to + derive HCK, SCK and FS. - - fsl,fifo-depth: The number of elements in the transmit and receive FIFOs. - This number is the maximum allowed value for TFCR[TFWM] or RFCR[RFWM]. + - fsl,fifo-depth : The number of elements in the transmit and receive + FIFOs. This number is the maximum allowed value for + TFCR[TFWM] or RFCR[RFWM]. - fsl,esai-synchronous: This is a boolean property. If present, indicating - that ESAI would work in the synchronous mode, which means all the settings - for Receiving would be duplicated from Transmition related registers. + that ESAI would work in the synchronous mode, which + means all the settings for Receiving would be + duplicated from Transmition related registers. - - big-endian : If this property is absent, the native endian mode will - be in use as default, or the big endian mode will be in use for all the - device registers. + - big-endian : If this property is absent, the native endian mode + will be in use as default, or the big endian mode + will be in use for all the device registers. Example: -- GitLab From 9c4c1045343836b848c3dd546277c955d145d20a Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:05 -0700 Subject: [PATCH 0549/9457] ASoC: fsl_spdif: Add indentation for binding doc to increase readability This patch simply adds indentations for DT binding doc to increase readability without changing any contents. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,spdif.txt | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt index 3e9e82c8eab3..b5ee32ee3706 100644 --- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt +++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt @@ -6,32 +6,31 @@ a fibre cable. Required properties: - - compatible : Compatible list, must contain "fsl,imx35-spdif". + - compatible : Compatible list, must contain "fsl,imx35-spdif". - - reg : Offset and length of the register set for the device. + - reg : Offset and length of the register set for the device. - - interrupts : Contains the spdif interrupt. + - interrupts : Contains the spdif interrupt. - - dmas : Generic dma devicetree binding as described in - Documentation/devicetree/bindings/dma/dma.txt. + - dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. - - dma-names : Two dmas have to be defined, "tx" and "rx". + - dma-names : Two dmas have to be defined, "tx" and "rx". - - clocks : Contains an entry for each entry in clock-names. + - clocks : Contains an entry for each entry in clock-names. - - clock-names : Includes the following entries: - "core" The core clock of spdif controller - "rxtx<0-7>" Clock source list for tx and rx clock. - This clock list should be identical to - the source list connecting to the spdif - clock mux in "SPDIF Transceiver Clock - Diagram" of SoC reference manual. It - can also be referred to TxClk_Source - bit of register SPDIF_STC. + - clock-names : Includes the following entries: + "core" The core clock of spdif controller. + "rxtx<0-7>" Clock source list for tx and rx clock. + This clock list should be identical to the source + list connecting to the spdif clock mux in "SPDIF + Transceiver Clock Diagram" of SoC reference manual. + It can also be referred to TxClk_Source bit of + register SPDIF_STC. - - big-endian : If this property is absent, the native endian mode will - be in use as default, or the big endian mode will be in use for all the - device registers. + - big-endian : If this property is absent, the native endian mode + will be in use as default, or the big endian mode + will be in use for all the device registers. Example: -- GitLab From 0b9938b264d1a76458cf06aab6de7b9cec68efca Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:06 -0700 Subject: [PATCH 0550/9457] ASoC: fsl_sai: Add indentation for binding doc to increase readability This patch refines the DT binding doc for more readability by adding extra blank lines and indentations. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl-sai.txt | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 4956b14d4b06..044e5d76e2dd 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -5,32 +5,48 @@ which provides a synchronous audio interface that supports fullduplex serial interfaces with frame synchronization such as I2S, AC97, TDM, and codec/DSP interfaces. - Required properties: -- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". -- reg: Offset and length of the register set for the device. -- clocks: Must contain an entry for each entry in clock-names. -- clock-names : Must include the "bus" for register access and "mclk1" "mclk2" - "mclk3" for bit clock and frame clock providing. -- dmas : Generic dma devicetree binding as described in - Documentation/devicetree/bindings/dma/dma.txt. -- dma-names : Two dmas have to be defined, "tx" and "rx". -- pinctrl-names: Must contain a "default" entry. -- pinctrl-NNN: One property must exist for each entry in pinctrl-names. - See ../pinctrl/pinctrl-bindings.txt for details of the property values. -- big-endian: Boolean property, required if all the FTM_PWM registers - are big-endian rather than little-endian. -- lsb-first: Configures whether the LSB or the MSB is transmitted first for - the fifo data. If this property is absent, the MSB is transmitted first as - default, or the LSB is transmitted first. -- fsl,sai-synchronous-rx: This is a boolean property. If present, indicating - that SAI will work in the synchronous mode (sync Tx with Rx) which means - both the transimitter and receiver will send and receive data by following - receiver's bit clocks and frame sync clocks. -- fsl,sai-asynchronous: This is a boolean property. If present, indicating - that SAI will work in the asynchronous mode, which means both transimitter - and receiver will send and receive data by following their own bit clocks - and frame sync clocks separately. + + - compatible : Compatible list, contains "fsl,vf610-sai" or + "fsl,imx6sx-sai". + + - reg : Offset and length of the register set for the device. + + - clocks : Must contain an entry for each entry in clock-names. + + - clock-names : Must include the "bus" for register access and + "mclk1", "mclk2", "mclk3" for bit clock and frame + clock providing. + - dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. + + - dma-names : Two dmas have to be defined, "tx" and "rx". + + - pinctrl-names : Must contain a "default" entry. + + - pinctrl-NNN : One property must exist for each entry in + pinctrl-names. See ../pinctrl/pinctrl-bindings.txt + for details of the property values. + + - big-endian : Boolean property, required if all the FTM_PWM + registers are big-endian rather than little-endian. + + - lsb-first : Configures whether the LSB or the MSB is transmitted + first for the fifo data. If this property is absent, + the MSB is transmitted first as default, or the LSB + is transmitted first. + + - fsl,sai-synchronous-rx: This is a boolean property. If present, indicating + that SAI will work in the synchronous mode (sync Tx + with Rx) which means both the transimitter and the + receiver will send and receive data by following + receiver's bit clocks and frame sync clocks. + + - fsl,sai-asynchronous: This is a boolean property. If present, indicating + that SAI will work in the asynchronous mode, which + means both transimitter and receiver will send and + receive data by following their own bit clocks and + frame sync clocks separately. Note: - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the -- GitLab From d29ae41edde680c00f9f74d448b7d59c91ca0474 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:07 -0700 Subject: [PATCH 0551/9457] ASoC: eukrea-tlv320: Add indentation for binding doc to increase readability This patch refines the DT binding doc for more readability by adding extra blank lines and indentations. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/eukrea-tlv320.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt b/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt index 0d7985c864af..6dfa88c4dc1e 100644 --- a/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt +++ b/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt @@ -1,11 +1,16 @@ Audio complex for Eukrea boards with tlv320aic23 codec. Required properties: -- compatible : "eukrea,asoc-tlv320" -- eukrea,model : The user-visible name of this sound complex. -- ssi-controller : The phandle of the SSI controller. -- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX). -- fsl,mux-ext-port : The external port of the i.MX audio muxer. + + - compatible : "eukrea,asoc-tlv320" + + - eukrea,model : The user-visible name of this sound complex. + + - ssi-controller : The phandle of the SSI controller. + + - fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX). + + - fsl,mux-ext-port : The external port of the i.MX audio muxer. Note: The AUDMUX port numbering should start at 1, which is consistent with hardware manual. -- GitLab From 5463c709ddeeacc73ae6844fd8aebc0a217b98d4 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:08 -0700 Subject: [PATCH 0552/9457] ASoC: imx-audmux: Add indentation for binding doc to increase readability This patch refines the DT binding doc for more readability by adding extra blank lines and indentations. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/imx-audmux.txt | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt index f88a00e54c63..b30a737e209e 100644 --- a/Documentation/devicetree/bindings/sound/imx-audmux.txt +++ b/Documentation/devicetree/bindings/sound/imx-audmux.txt @@ -1,18 +1,24 @@ Freescale Digital Audio Mux (AUDMUX) device Required properties: -- compatible : "fsl,imx21-audmux" for AUDMUX version firstly used on i.MX21, - or "fsl,imx31-audmux" for the version firstly used on i.MX31. -- reg : Should contain AUDMUX registers location and length + + - compatible : "fsl,imx21-audmux" for AUDMUX version firstly used + on i.MX21, or "fsl,imx31-audmux" for the version + firstly used on i.MX31. + + - reg : Should contain AUDMUX registers location and length. An initial configuration can be setup using child nodes. Required properties of optional child nodes: -- fsl,audmux-port : Integer of the audmux port that is configured by this - child node. -- fsl,port-config : List of configuration options for the specific port. For - imx31-audmux and above, it is a list of tuples . For - imx21-audmux it is a list of pcr values. + + - fsl,audmux-port : Integer of the audmux port that is configured by this + child node. + + - fsl,port-config : List of configuration options for the specific port. + For imx31-audmux and above, it is a list of tuples + . For imx21-audmux it is a list of pcr + values. Example: -- GitLab From afa1fde676592b9c40e893f4f652f2c842e31683 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:09 -0700 Subject: [PATCH 0553/9457] ASoC: imx-sgtl5000: Add indentation for binding doc to increase readability This patch refines the DT binding doc for more readability by adding extra blank lines and indentations. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../bindings/sound/imx-audio-sgtl5000.txt | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt index e4acdd891e49..2f89db88fd57 100644 --- a/Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt @@ -1,33 +1,40 @@ Freescale i.MX audio complex with SGTL5000 codec Required properties: -- compatible : "fsl,imx-audio-sgtl5000" -- model : The user-visible name of this sound complex -- ssi-controller : The phandle of the i.MX SSI controller -- audio-codec : The phandle of the SGTL5000 audio codec -- audio-routing : A list of the connections between audio components. - Each entry is a pair of strings, the first being the connection's sink, - the second being the connection's source. Valid names could be power - supplies, SGTL5000 pins, and the jacks on the board: - - Power supplies: - * Mic Bias - - SGTL5000 pins: - * MIC_IN - * LINE_IN - * HP_OUT - * LINE_OUT - - Board connectors: - * Mic Jack - * Line In Jack - * Headphone Jack - * Line Out Jack - * Ext Spk - -- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) -- mux-ext-port : The external port of the i.MX audio muxer + + - compatible : "fsl,imx-audio-sgtl5000" + + - model : The user-visible name of this sound complex + + - ssi-controller : The phandle of the i.MX SSI controller + + - audio-codec : The phandle of the SGTL5000 audio codec + + - audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's + source. Valid names could be power supplies, SGTL5000 + pins, and the jacks on the board: + + Power supplies: + * Mic Bias + + SGTL5000 pins: + * MIC_IN + * LINE_IN + * HP_OUT + * LINE_OUT + + Board connectors: + * Mic Jack + * Line In Jack + * Headphone Jack + * Line Out Jack + * Ext Spk + + - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) + + - mux-ext-port : The external port of the i.MX audio muxer Note: The AUDMUX port numbering should start at 1, which is consistent with hardware manual. -- GitLab From 6219b082b3099668c32be99bd31216379fc3d97a Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:10 -0700 Subject: [PATCH 0554/9457] ASoC: imx-spdif: Add indentation for binding doc to increase readability This patch simply adds indentations for DT binding doc to increase readability without changing any contents. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../bindings/sound/imx-audio-spdif.txt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt index 7d13479f9c3c..da84a442ccea 100644 --- a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt +++ b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt @@ -2,23 +2,25 @@ Freescale i.MX audio complex with S/PDIF transceiver Required properties: - - compatible : "fsl,imx-audio-spdif" + - compatible : "fsl,imx-audio-spdif" - - model : The user-visible name of this sound complex + - model : The user-visible name of this sound complex - - spdif-controller : The phandle of the i.MX S/PDIF controller + - spdif-controller : The phandle of the i.MX S/PDIF controller Optional properties: - - spdif-out : This is a boolean property. If present, the transmitting - function of S/PDIF will be enabled, indicating there's a physical - S/PDIF out connector/jack on the board or it's connecting to some - other IP block, such as an HDMI encoder/display-controller. + - spdif-out : This is a boolean property. If present, the + transmitting function of S/PDIF will be enabled, + indicating there's a physical S/PDIF out connector + or jack on the board or it's connecting to some + other IP block, such as an HDMI encoder or + display-controller. - - spdif-in : This is a boolean property. If present, the receiving - function of S/PDIF will be enabled, indicating there's a physical - S/PDIF in connector/jack on the board. + - spdif-in : This is a boolean property. If present, the receiving + function of S/PDIF will be enabled, indicating there + is a physical S/PDIF in connector/jack on the board. * Note: At least one of these two properties should be set in the DT binding. -- GitLab From 6a6dec83e5abbc5003dac234970b51afa142defd Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 7 Oct 2014 12:29:11 -0700 Subject: [PATCH 0555/9457] ASoC: imx-wm8962: Add indentation for binding doc to increase readability This patch simply adds indentations for DT binding doc to increase readability without changing any contents. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../bindings/sound/imx-audio-wm8962.txt | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt index f49450a87890..acea71bee34f 100644 --- a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt +++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt @@ -1,25 +1,32 @@ Freescale i.MX audio complex with WM8962 codec Required properties: -- compatible : "fsl,imx-audio-wm8962" -- model : The user-visible name of this sound complex -- ssi-controller : The phandle of the i.MX SSI controller -- audio-codec : The phandle of the WM8962 audio codec -- audio-routing : A list of the connections between audio components. - Each entry is a pair of strings, the first being the connection's sink, - the second being the connection's source. Valid names could be power - supplies, WM8962 pins, and the jacks on the board: - - Power supplies: - * Mic Bias - - Board connectors: - * Mic Jack - * Headphone Jack - * Ext Spk - -- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) -- mux-ext-port : The external port of the i.MX audio muxer + + - compatible : "fsl,imx-audio-wm8962" + + - model : The user-visible name of this sound complex + + - ssi-controller : The phandle of the i.MX SSI controller + + - audio-codec : The phandle of the WM8962 audio codec + + - audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's + source. Valid names could be power supplies, WM8962 + pins, and the jacks on the board: + + Power supplies: + * Mic Bias + + Board connectors: + * Mic Jack + * Headphone Jack + * Ext Spk + + - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) + + - mux-ext-port : The external port of the i.MX audio muxer Note: The AUDMUX port numbering should start at 1, which is consistent with hardware manual. -- GitLab From 74d813cf37c210e94d155b0c19598fe269b8f78c Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 14 Oct 2014 20:29:26 +0300 Subject: [PATCH 0556/9457] ASoC: hdmi: Mark the maximum significant bits to HDMI codec HDMI audio can not have more than 24 bits even if on i2s bus there would be 32 bit samples. Mark this by adding .sig_bits = 24 to playback stream definition. Signed-off-by: Jyri Sarha Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 1087fd5f9917..2a52b9050371 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -47,6 +47,7 @@ static struct snd_soc_dai_driver hdmi_codec_dai = { SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + .sig_bits = 24, }, .capture = { .stream_name = "Capture", -- GitLab From 69434097916bc52a4d6d495a0d719eb02e0cff9e Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 14 Oct 2014 20:29:27 +0300 Subject: [PATCH 0557/9457] ASoC: hdmi: HDMI codec doesn't benefit from pmdown delay Adds .ignore_pmdown_time = true to codec driver struct. HDMI codec is currently a dummy codec and doesn't benefit from pmdown delay. Even if in the future the codec would controll HDMI encoder, it would still be a digital to digital interface that should have no need for pmdown delay. Signed-off-by: Jyri Sarha Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 2a52b9050371..1391ad50f95d 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -76,6 +76,7 @@ static struct snd_soc_codec_driver hdmi_codec = { .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), .dapm_routes = hdmi_routes, .num_dapm_routes = ARRAY_SIZE(hdmi_routes), + .ignore_pmdown_time = true, }; static int hdmi_codec_probe(struct platform_device *pdev) -- GitLab From 4fa805738e497c6f5bad53fcdc76b9759bc9dc80 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 15 Oct 2014 20:12:56 +0530 Subject: [PATCH 0558/9457] ASoC: Intel: mrfld: add the gain controls The DSP has various gain modules in the path, add these as ALSA gain controls Signed-off-by: Vinod Koul Signed-off-by: Subhransu S. Prusty Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 2 +- sound/soc/intel/sst-atom-controls.c | 202 +++++++++++++++++++++++++++- sound/soc/intel/sst-atom-controls.h | 121 +++++++++++++++++ 3 files changed, 322 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index f5b4a9c79cdf..726f7d891a7a 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -1,6 +1,6 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" - depends on INTEL_SCU_IPC + depends on INTEL_SCU_IPC || COMPILE_TEST select SND_SOC_SN95031 select SND_SST_MFLD_PLATFORM help diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index 7104a34181a9..a00d506af179 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -162,6 +162,190 @@ static int sst_algo_control_set(struct snd_kcontrol *kcontrol, return ret; } +static int sst_gain_ctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = mc->stereo ? 2 : 1; + uinfo->value.integer.min = mc->min; + uinfo->value.integer.max = mc->max; + + return 0; +} + +/** + * sst_send_gain_cmd - send the gain algorithm IPC to the FW + * @gv: the stored value of gain (also contains rampduration) + * @mute: flag that indicates whether this was called from the + * digital_mute callback or directly. If called from the + * digital_mute callback, module will be muted/unmuted based on this + * flag. The flag is always 0 if called directly. + * + * Called with sst_data.lock held + * + * The user-set gain value is sent only if the user-controllable 'mute' control + * is OFF (indicated by gv->mute). Otherwise, the mute value (MIN value) is + * sent. + */ +static int sst_send_gain_cmd(struct sst_data *drv, struct sst_gain_value *gv, + u16 task_id, u16 loc_id, u16 module_id, int mute) +{ + struct sst_cmd_set_gain_dual cmd; + + dev_dbg(&drv->pdev->dev, "Enter\n"); + + cmd.header.command_id = MMX_SET_GAIN; + SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); + cmd.gain_cell_num = 1; + + if (mute || gv->mute) { + cmd.cell_gains[0].cell_gain_left = SST_GAIN_MIN_VALUE; + cmd.cell_gains[0].cell_gain_right = SST_GAIN_MIN_VALUE; + } else { + cmd.cell_gains[0].cell_gain_left = gv->l_gain; + cmd.cell_gains[0].cell_gain_right = gv->r_gain; + } + + SST_FILL_DESTINATION(2, cmd.cell_gains[0].dest, + loc_id, module_id); + cmd.cell_gains[0].gain_time_constant = gv->ramp_duration; + + cmd.header.length = sizeof(struct sst_cmd_set_gain_dual) + - sizeof(struct sst_dsp_header); + + /* we are with lock held, so call the unlocked api to send */ + return sst_fill_and_send_cmd_unlocked(drv, SST_IPC_IA_SET_PARAMS, + SST_FLAG_BLOCKED, task_id, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); +} + +static int sst_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; + struct sst_gain_value *gv = mc->gain_val; + + switch (mc->type) { + case SST_GAIN_TLV: + ucontrol->value.integer.value[0] = gv->l_gain; + ucontrol->value.integer.value[1] = gv->r_gain; + break; + + case SST_GAIN_MUTE: + ucontrol->value.integer.value[0] = gv->mute ? 1 : 0; + break; + + case SST_GAIN_RAMP_DURATION: + ucontrol->value.integer.value[0] = gv->ramp_duration; + break; + + default: + dev_err(component->dev, "Invalid Input- gain type:%d\n", + mc->type); + return -EINVAL; + }; + + return 0; +} + +static int sst_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int ret = 0; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct sst_data *drv = snd_soc_component_get_drvdata(cmpnt); + struct sst_gain_mixer_control *mc = (void *)kcontrol->private_value; + struct sst_gain_value *gv = mc->gain_val; + + mutex_lock(&drv->lock); + + switch (mc->type) { + case SST_GAIN_TLV: + gv->l_gain = ucontrol->value.integer.value[0]; + gv->r_gain = ucontrol->value.integer.value[1]; + dev_dbg(cmpnt->dev, "%s: Volume %d, %d\n", + mc->pname, gv->l_gain, gv->r_gain); + break; + + case SST_GAIN_MUTE: + gv->mute = !!ucontrol->value.integer.value[0]; + dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute); + break; + + case SST_GAIN_RAMP_DURATION: + gv->ramp_duration = ucontrol->value.integer.value[0]; + dev_dbg(cmpnt->dev, "%s: Ramp Delay%d\n", + mc->pname, gv->ramp_duration); + break; + + default: + mutex_unlock(&drv->lock); + dev_err(cmpnt->dev, "Invalid Input- gain type:%d\n", + mc->type); + return -EINVAL; + }; + + if (mc->w && mc->w->power) + ret = sst_send_gain_cmd(drv, gv, mc->task_id, + mc->pipe_id | mc->instance_id, mc->module_id, 0); + mutex_unlock(&drv->lock); + + return ret; +} + +static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10, 10, 0); + +/* Gain helper with min/max set */ +#define SST_GAIN(name, path_id, task_id, instance, gain_var) \ + SST_GAIN_KCONTROLS(name, "Gain", SST_GAIN_MIN_VALUE, SST_GAIN_MAX_VALUE, \ + SST_GAIN_TC_MIN, SST_GAIN_TC_MAX, \ + sst_gain_get, sst_gain_put, \ + SST_MODULE_ID_GAIN_CELL, path_id, instance, task_id, \ + sst_gain_tlv_common, gain_var) + +#define SST_VOLUME(name, path_id, task_id, instance, gain_var) \ + SST_GAIN_KCONTROLS(name, "Volume", SST_GAIN_MIN_VALUE, SST_GAIN_MAX_VALUE, \ + SST_GAIN_TC_MIN, SST_GAIN_TC_MAX, \ + sst_gain_get, sst_gain_put, \ + SST_MODULE_ID_VOLUME, path_id, instance, task_id, \ + sst_gain_tlv_common, gain_var) + +static struct sst_gain_value sst_gains[]; + +static const struct snd_kcontrol_new sst_gain_controls[] = { + SST_GAIN("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[0]), + SST_GAIN("media1_in", SST_PATH_INDEX_MEDIA1_IN, SST_TASK_MMX, 0, &sst_gains[1]), + SST_GAIN("media2_in", SST_PATH_INDEX_MEDIA2_IN, SST_TASK_MMX, 0, &sst_gains[2]), + SST_GAIN("media3_in", SST_PATH_INDEX_MEDIA3_IN, SST_TASK_MMX, 0, &sst_gains[3]), + + SST_GAIN("pcm0_in", SST_PATH_INDEX_PCM0_IN, SST_TASK_SBA, 0, &sst_gains[4]), + SST_GAIN("pcm1_in", SST_PATH_INDEX_PCM1_IN, SST_TASK_SBA, 0, &sst_gains[5]), + SST_GAIN("pcm1_out", SST_PATH_INDEX_PCM1_OUT, SST_TASK_SBA, 0, &sst_gains[6]), + SST_GAIN("pcm2_out", SST_PATH_INDEX_PCM2_OUT, SST_TASK_SBA, 0, &sst_gains[7]), + + SST_GAIN("codec_in0", SST_PATH_INDEX_CODEC_IN0, SST_TASK_SBA, 0, &sst_gains[8]), + SST_GAIN("codec_in1", SST_PATH_INDEX_CODEC_IN1, SST_TASK_SBA, 0, &sst_gains[9]), + SST_GAIN("codec_out0", SST_PATH_INDEX_CODEC_OUT0, SST_TASK_SBA, 0, &sst_gains[10]), + SST_GAIN("codec_out1", SST_PATH_INDEX_CODEC_OUT1, SST_TASK_SBA, 0, &sst_gains[11]), + SST_GAIN("media_loop1_out", SST_PATH_INDEX_MEDIA_LOOP1_OUT, SST_TASK_SBA, 0, &sst_gains[12]), + SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), + SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), + SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), +}; + +#define SST_GAIN_NUM_CONTROLS 3 +/* the SST_GAIN macro above will create three alsa controls for each + * instance invoked, gain, mute and ramp duration, which use the same gain + * cell sst_gain to keep track of data + * To calculate number of gain cell instances we need to device by 3 in + * below caulcation for gain cell memory. + * This gets rid of static number and issues while adding new controls + */ +static struct sst_gain_value sst_gains[ARRAY_SIZE(sst_gain_controls)/SST_GAIN_NUM_CONTROLS]; + static const struct snd_kcontrol_new sst_algo_controls[] = { SST_ALGO_KCONTROL_BYTES("media_loop1_out", "fir", 272, SST_MODULE_ID_FIR_24, SST_PATH_INDEX_MEDIA_LOOP1_OUT, 0, SST_TASK_SBA, SBA_VB_SET_FIR), @@ -200,19 +384,33 @@ static int sst_algo_control_init(struct device *dev) int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) { - int ret = 0; + int i, ret = 0; struct sst_data *drv = snd_soc_platform_get_drvdata(platform); + unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3; drv->byte_stream = devm_kzalloc(platform->dev, SST_MAX_BIN_BYTES, GFP_KERNEL); if (!drv->byte_stream) return -ENOMEM; - /*Initialize algo control params*/ + for (i = 0; i < gains; i++) { + sst_gains[i].mute = SST_GAIN_MUTE_DEFAULT; + sst_gains[i].l_gain = SST_GAIN_VOLUME_DEFAULT; + sst_gains[i].r_gain = SST_GAIN_VOLUME_DEFAULT; + sst_gains[i].ramp_duration = SST_GAIN_RAMP_DURATION_DEFAULT; + } + + ret = snd_soc_add_platform_controls(platform, sst_gain_controls, + ARRAY_SIZE(sst_gain_controls)); + if (ret) + return ret; + + /* Initialize algo control params */ ret = sst_algo_control_init(platform->dev); if (ret) return ret; ret = snd_soc_add_platform_controls(platform, sst_algo_controls, ARRAY_SIZE(sst_algo_controls)); + return ret; } diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h index a73e894b175c..e530002cd763 100644 --- a/sound/soc/intel/sst-atom-controls.h +++ b/sound/soc/intel/sst-atom-controls.h @@ -23,6 +23,9 @@ #ifndef __SST_ATOM_CONTROLS_H__ #define __SST_ATOM_CONTROLS_H__ +#include +#include + enum { MERR_DPCM_AUDIO = 0, MERR_DPCM_COMPR, @@ -360,16 +363,134 @@ struct sst_dsp_header { struct sst_cmd_generic { struct sst_dsp_header header; } __packed; + +struct gain_cell { + struct sst_destination_id dest; + s16 cell_gain_left; + s16 cell_gain_right; + u16 gain_time_constant; +} __packed; + +#define NUM_GAIN_CELLS 1 +struct sst_cmd_set_gain_dual { + struct sst_dsp_header header; + u16 gain_cell_num; + struct gain_cell cell_gains[NUM_GAIN_CELLS]; +} __packed; struct sst_cmd_set_params { struct sst_destination_id dst; u16 command_id; char params[0]; } __packed; + +/**** widget defines *****/ + +struct sst_ids { + u16 location_id; + u16 module_id; + u8 task_id; + u8 format; + u8 reg; + const char *parent_wname; + struct snd_soc_dapm_widget *parent_w; + struct list_head algo_list; + struct list_head gain_list; + const struct sst_pcm_format *pcm_fmt; +}; +enum sst_gain_kcontrol_type { + SST_GAIN_TLV, + SST_GAIN_MUTE, + SST_GAIN_RAMP_DURATION, +}; + +struct sst_gain_mixer_control { + bool stereo; + enum sst_gain_kcontrol_type type; + struct sst_gain_value *gain_val; + int max; + int min; + u16 instance_id; + u16 module_id; + u16 pipe_id; + u16 task_id; + char pname[44]; + struct snd_soc_dapm_widget *w; +}; + +struct sst_gain_value { + u16 ramp_duration; + s16 l_gain; + s16 r_gain; + bool mute; +}; +#define SST_GAIN_VOLUME_DEFAULT (-1440) +#define SST_GAIN_RAMP_DURATION_DEFAULT 5 /* timeconstant */ +#define SST_GAIN_MUTE_DEFAULT true + +#define SST_GAIN_KCONTROL_TLV(xname, xhandler_get, xhandler_put, \ + xmod, xpipe, xinstance, xtask, tlv_array, xgain_val, \ + xmin, xmax, xpname) \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .tlv.p = (tlv_array), \ + .info = sst_gain_ctl_info,\ + .get = xhandler_get, .put = xhandler_put, \ + .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ + { .stereo = true, .max = xmax, .min = xmin, .type = SST_GAIN_TLV, \ + .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ + .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} + +#define SST_GAIN_KCONTROL_INT(xname, xhandler_get, xhandler_put, \ + xmod, xpipe, xinstance, xtask, xtype, xgain_val, \ + xmin, xmax, xpname) \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = sst_gain_ctl_info, \ + .get = xhandler_get, .put = xhandler_put, \ + .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ + { .stereo = false, .max = xmax, .min = xmin, .type = xtype, \ + .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ + .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} + +#define SST_GAIN_KCONTROL_BOOL(xname, xhandler_get, xhandler_put,\ + xmod, xpipe, xinstance, xtask, xgain_val, xpname) \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_bool_ext, \ + .get = xhandler_get, .put = xhandler_put, \ + .private_value = (unsigned long)&(struct sst_gain_mixer_control) \ + { .stereo = false, .type = SST_GAIN_MUTE, \ + .module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\ + .instance_id = xinstance, .gain_val = xgain_val, .pname = xpname} #define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \ xpname " " xmname " " #xinstance " " xtype #define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \ xpname " " xmname " " #xinstance " " xtype " " xsubmodule + +/* + * 3 Controls for each Gain module + * e.g. - pcm0_in Gain 0 Volume + * - pcm0_in Gain 0 Ramp Delay + * - pcm0_in Gain 0 Switch + */ +#define SST_GAIN_KCONTROLS(xpname, xmname, xmin_gain, xmax_gain, xmin_tc, xmax_tc, \ + xhandler_get, xhandler_put, \ + xmod, xpipe, xinstance, xtask, tlv_array, xgain_val) \ + { SST_GAIN_KCONTROL_INT(SST_CONTROL_NAME(xpname, xmname, xinstance, "Ramp Delay"), \ + xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, SST_GAIN_RAMP_DURATION, \ + xgain_val, xmin_tc, xmax_tc, xpname) }, \ + { SST_GAIN_KCONTROL_BOOL(SST_CONTROL_NAME(xpname, xmname, xinstance, "Switch"), \ + xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, \ + xgain_val, xpname) } ,\ + { SST_GAIN_KCONTROL_TLV(SST_CONTROL_NAME(xpname, xmname, xinstance, "Volume"), \ + xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, tlv_array, \ + xgain_val, xmin_gain, xmax_gain, xpname) } + +#define SST_GAIN_TC_MIN 5 +#define SST_GAIN_TC_MAX 5000 +#define SST_GAIN_MIN_VALUE -1440 /* in 0.1 DB units */ +#define SST_GAIN_MAX_VALUE 360 + enum sst_algo_kcontrol_type { SST_ALGO_PARAMS, SST_ALGO_BYPASS, -- GitLab From 24c8d14192cc63661ca049b423d7baaa0bbafeb3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 15 Oct 2014 20:12:57 +0530 Subject: [PATCH 0559/9457] ASoC: Intel: mrfld: add DSP core controls This patch adds core controls like interleavers, SSP BEs, and also logic of sending pipeline and module commands to the DSP. Signed-off-by: Vinod Koul Signed-off-by: Subhransu S. Prusty Signed-off-by: Mark Brown --- sound/soc/intel/sst-atom-controls.c | 754 ++++++++++++++++++++++++++++ sound/soc/intel/sst-atom-controls.h | 307 +++++++++++ 2 files changed, 1061 insertions(+) diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index a00d506af179..9239eff26749 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -15,6 +15,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * + * In the dpcm driver modelling when a particular FE/BE/Mixer/Pipe is active + * we forward the settings and parameters, rest we keep the values in + * driver and forward when DAPM enables them * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -81,6 +84,183 @@ static int sst_fill_and_send_cmd(struct sst_data *drv, return ret; } +/** + * tx map value is a bitfield where each bit represents a FW channel + * + * 3 2 1 0 # 0 = codec0, 1 = codec1 + * RLRLRLRL # 3, 4 = reserved + * + * e.g. slot 0 rx map = 00001100b -> data from slot 0 goes into codec_in1 L,R + */ +static u8 sst_ssp_tx_map[SST_MAX_TDM_SLOTS] = { + 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, /* default rx map */ +}; + +/** + * rx map value is a bitfield where each bit represents a slot + * + * 76543210 # 0 = slot 0, 1 = slot 1 + * + * e.g. codec1_0 tx map = 00000101b -> data from codec_out1_0 goes into slot 0, 2 + */ +static u8 sst_ssp_rx_map[SST_MAX_TDM_SLOTS] = { + 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, /* default tx map */ +}; + +/** + * NOTE: this is invoked with lock held + */ +static int sst_send_slot_map(struct sst_data *drv) +{ + struct sst_param_sba_ssp_slot_map cmd; + + SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); + cmd.header.command_id = SBA_SET_SSP_SLOT_MAP; + cmd.header.length = sizeof(struct sst_param_sba_ssp_slot_map) + - sizeof(struct sst_dsp_header); + + cmd.param_id = SBA_SET_SSP_SLOT_MAP; + cmd.param_len = sizeof(cmd.rx_slot_map) + sizeof(cmd.tx_slot_map) + + sizeof(cmd.ssp_index); + cmd.ssp_index = SSP_CODEC; + + memcpy(cmd.rx_slot_map, &sst_ssp_tx_map[0], sizeof(cmd.rx_slot_map)); + memcpy(cmd.tx_slot_map, &sst_ssp_rx_map[0], sizeof(cmd.tx_slot_map)); + + return sst_fill_and_send_cmd_unlocked(drv, SST_IPC_IA_SET_PARAMS, + SST_FLAG_BLOCKED, SST_TASK_SBA, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); +} + +int sst_slot_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct sst_enum *e = (struct sst_enum *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = e->max; + + if (uinfo->value.enumerated.item > e->max - 1) + uinfo->value.enumerated.item = e->max - 1; + strcpy(uinfo->value.enumerated.name, + e->texts[uinfo->value.enumerated.item]); + + return 0; +} + +/** + * sst_slot_get - get the status of the interleaver/deinterleaver control + * + * Searches the map where the control status is stored, and gets the + * channel/slot which is currently set for this enumerated control. Since it is + * an enumerated control, there is only one possible value. + */ +static int sst_slot_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sst_enum *e = (void *)kcontrol->private_value; + struct snd_soc_component *c = snd_kcontrol_chip(kcontrol); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + unsigned int ctl_no = e->reg; + unsigned int is_tx = e->tx; + unsigned int val, mux; + u8 *map = is_tx ? sst_ssp_rx_map : sst_ssp_tx_map; + + mutex_lock(&drv->lock); + val = 1 << ctl_no; + /* search which slot/channel has this bit set - there should be only one */ + for (mux = e->max; mux > 0; mux--) + if (map[mux - 1] & val) + break; + + ucontrol->value.enumerated.item[0] = mux; + mutex_unlock(&drv->lock); + + dev_dbg(c->dev, "%s - %s map = %#x\n", + is_tx ? "tx channel" : "rx slot", + e->texts[mux], mux ? map[mux - 1] : -1); + return 0; +} + +/* sst_check_and_send_slot_map - helper for checking power state and sending + * slot map cmd + * + * called with lock held + */ +static int sst_check_and_send_slot_map(struct sst_data *drv, struct snd_kcontrol *kcontrol) +{ + struct sst_enum *e = (void *)kcontrol->private_value; + int ret = 0; + + if (e->w && e->w->power) + ret = sst_send_slot_map(drv); + else + dev_err(&drv->pdev->dev, "Slot control: %s doesn't have DAPM widget!!!\n", + kcontrol->id.name); + return ret; +} + +/** + * sst_slot_put - set the status of interleaver/deinterleaver control + * + * (de)interleaver controls are defined in opposite sense to be user-friendly + * + * Instead of the enum value being the value written to the register, it is the + * register address; and the kcontrol number (register num) is the value written + * to the register. This is so that there can be only one value for each + * slot/channel since there is only one control for each slot/channel. + * + * This means that whenever an enum is set, we need to clear the bit + * for that kcontrol_no for all the interleaver OR deinterleaver registers + */ +static int sst_slot_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + struct sst_enum *e = (void *)kcontrol->private_value; + int i, ret = 0; + unsigned int ctl_no = e->reg; + unsigned int is_tx = e->tx; + unsigned int slot_channel_no; + unsigned int val, mux; + u8 *map; + + map = is_tx ? sst_ssp_rx_map : sst_ssp_tx_map; + + val = 1 << ctl_no; + mux = ucontrol->value.enumerated.item[0]; + if (mux > e->max - 1) + return -EINVAL; + + mutex_lock(&drv->lock); + /* first clear all registers of this bit */ + for (i = 0; i < e->max; i++) + map[i] &= ~val; + + if (mux == 0) { + /* kctl set to 'none' and we reset the bits so send IPC */ + ret = sst_check_and_send_slot_map(drv, kcontrol); + + mutex_unlock(&drv->lock); + return ret; + } + + /* offset by one to take "None" into account */ + slot_channel_no = mux - 1; + map[slot_channel_no] |= val; + + dev_dbg(c->dev, "%s %s map = %#x\n", + is_tx ? "tx channel" : "rx slot", + e->texts[mux], map[slot_channel_no]); + + ret = sst_check_and_send_slot_map(drv, kcontrol); + + mutex_unlock(&drv->lock); + return ret; +} + static int sst_send_algo_cmd(struct sst_data *drv, struct sst_algo_control *bc) { @@ -104,6 +284,34 @@ static int sst_send_algo_cmd(struct sst_data *drv, return ret; } +/** + * sst_find_and_send_pipe_algo - send all the algo parameters for a pipe + * + * The algos which are in each pipeline are sent to the firmware one by one + * + * Called with lock held + */ +static int sst_find_and_send_pipe_algo(struct sst_data *drv, + const char *pipe, struct sst_ids *ids) +{ + int ret = 0; + struct sst_algo_control *bc; + struct sst_module *algo = NULL; + + dev_dbg(&drv->pdev->dev, "Enter: widget=%s\n", pipe); + + list_for_each_entry(algo, &ids->algo_list, node) { + bc = (void *)algo->kctl->private_value; + + dev_dbg(&drv->pdev->dev, "Found algo control name=%s pipe=%s\n", + algo->kctl->id.name, pipe); + ret = sst_send_algo_cmd(drv, bc); + if (ret) + return ret; + } + return ret; +} + static int sst_algo_bytes_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -296,8 +504,317 @@ static int sst_gain_put(struct snd_kcontrol *kcontrol, return ret; } +static int sst_set_pipe_gain(struct sst_ids *ids, + struct sst_data *drv, int mute); + +static int sst_send_pipe_module_params(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol) +{ + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + struct sst_ids *ids = w->priv; + + mutex_lock(&drv->lock); + sst_find_and_send_pipe_algo(drv, w->name, ids); + sst_set_pipe_gain(ids, drv, 0); + mutex_unlock(&drv->lock); + + return 0; +} + +static int sst_generic_modules_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) + return sst_send_pipe_module_params(w, k); + return 0; +} + static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10, 10, 0); +/* Look up table to convert MIXER SW bit regs to SWM inputs */ +static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { + [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, + [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, + [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, + [SST_IP_LOOP1] = SST_SWM_IN_MEDIA_LOOP1, + [SST_IP_LOOP2] = SST_SWM_IN_MEDIA_LOOP2, + [SST_IP_PCM0] = SST_SWM_IN_PCM0, + [SST_IP_PCM1] = SST_SWM_IN_PCM1, + [SST_IP_MEDIA0] = SST_SWM_IN_MEDIA0, + [SST_IP_MEDIA1] = SST_SWM_IN_MEDIA1, + [SST_IP_MEDIA2] = SST_SWM_IN_MEDIA2, + [SST_IP_MEDIA3] = SST_SWM_IN_MEDIA3, +}; + +/** + * called with lock held + */ +static int sst_set_pipe_gain(struct sst_ids *ids, + struct sst_data *drv, int mute) +{ + int ret = 0; + struct sst_gain_mixer_control *mc; + struct sst_gain_value *gv; + struct sst_module *gain = NULL; + + list_for_each_entry(gain, &ids->gain_list, node) { + struct snd_kcontrol *kctl = gain->kctl; + + dev_dbg(&drv->pdev->dev, "control name=%s\n", kctl->id.name); + mc = (void *)kctl->private_value; + gv = mc->gain_val; + + ret = sst_send_gain_cmd(drv, gv, mc->task_id, + mc->pipe_id | mc->instance_id, mc->module_id, mute); + if (ret) + return ret; + } + return ret; +} + +/* + * sst_handle_vb_timer - Start/Stop the DSP scheduler + * + * The DSP expects first cmd to be SBA_VB_START, so at first startup send + * that. + * DSP expects last cmd to be SBA_VB_IDLE, so at last shutdown send that. + * + * Do refcount internally so that we send command only at first start + * and last end. Since SST driver does its own ref count, invoke sst's + * power ops always! + */ +int sst_handle_vb_timer(struct snd_soc_dai *dai, bool enable) +{ + int ret = 0; + struct sst_cmd_generic cmd; + struct sst_data *drv = snd_soc_dai_get_drvdata(dai); + static int timer_usage; + + if (enable) + cmd.header.command_id = SBA_VB_START; + else + cmd.header.command_id = SBA_IDLE; + dev_dbg(dai->dev, "enable=%u, usage=%d\n", enable, timer_usage); + + SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); + cmd.header.length = 0; + + if (enable) { + ret = sst->ops->power(sst->dev, true); + if (ret < 0) + return ret; + } + + mutex_lock(&drv->lock); + if (enable) + timer_usage++; + else + timer_usage--; + + /* + * Send the command only if this call is the first enable or last + * disable + */ + if ((enable && (timer_usage == 1)) || + (!enable && (timer_usage == 0))) { + ret = sst_fill_and_send_cmd_unlocked(drv, SST_IPC_IA_CMD, + SST_FLAG_BLOCKED, SST_TASK_SBA, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); + if (ret && enable) { + timer_usage--; + enable = false; + } + } + mutex_unlock(&drv->lock); + + if (!enable) + sst->ops->power(sst->dev, false); + return ret; +} + +/** + * sst_ssp_config - contains SSP configuration for media UC + */ +static const struct sst_ssp_config sst_ssp_configs = { + .ssp_id = SSP_CODEC, + .bits_per_slot = 24, + .slots = 4, + .ssp_mode = SSP_MODE_MASTER, + .pcm_mode = SSP_PCM_MODE_NETWORK, + .duplex = SSP_DUPLEX, + .ssp_protocol = SSP_MODE_PCM, + .fs_width = 1, + .fs_frequency = SSP_FS_48_KHZ, + .active_slot_map = 0xF, + .start_delay = 0, +}; + +int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) +{ + struct sst_cmd_sba_hw_set_ssp cmd; + struct sst_data *drv = snd_soc_dai_get_drvdata(dai); + const struct sst_ssp_config *config; + + dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); + + SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); + cmd.header.command_id = SBA_HW_SET_SSP; + cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) + - sizeof(struct sst_dsp_header); + + config = &sst_ssp_configs; + dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); + + if (enable) + cmd.switch_state = SST_SWITCH_ON; + else + cmd.switch_state = SST_SWITCH_OFF; + + cmd.selection = config->ssp_id; + cmd.nb_bits_per_slots = config->bits_per_slot; + cmd.nb_slots = config->slots; + cmd.mode = config->ssp_mode | (config->pcm_mode << 1); + cmd.duplex = config->duplex; + cmd.active_tx_slot_map = config->active_slot_map; + cmd.active_rx_slot_map = config->active_slot_map; + cmd.frame_sync_frequency = config->fs_frequency; + cmd.frame_sync_polarity = SSP_FS_ACTIVE_HIGH; + cmd.data_polarity = 1; + cmd.frame_sync_width = config->fs_width; + cmd.ssp_protocol = config->ssp_protocol; + cmd.start_delay = config->start_delay; + cmd.reserved1 = cmd.reserved2 = 0xFF; + + return sst_fill_and_send_cmd(drv, SST_IPC_IA_CMD, SST_FLAG_BLOCKED, + SST_TASK_SBA, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); +} + +static int sst_set_be_modules(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + + dev_dbg(c->dev, "Enter: widget=%s\n", w->name); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = sst_send_slot_map(drv); + if (ret) + return ret; + ret = sst_send_pipe_module_params(w, k); + } + return ret; +} + +static int sst_set_media_path(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + struct sst_cmd_set_media_path cmd; + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + struct sst_ids *ids = w->priv; + + dev_dbg(c->dev, "widget=%s\n", w->name); + dev_dbg(c->dev, "task=%u, location=%#x\n", + ids->task_id, ids->location_id); + + if (SND_SOC_DAPM_EVENT_ON(event)) + cmd.switch_state = SST_PATH_ON; + else + cmd.switch_state = SST_PATH_OFF; + + SST_FILL_DESTINATION(2, cmd.header.dst, + ids->location_id, SST_DEFAULT_MODULE_ID); + + /* MMX_SET_MEDIA_PATH == SBA_SET_MEDIA_PATH */ + cmd.header.command_id = MMX_SET_MEDIA_PATH; + cmd.header.length = sizeof(struct sst_cmd_set_media_path) + - sizeof(struct sst_dsp_header); + + ret = sst_fill_and_send_cmd(drv, SST_IPC_IA_CMD, SST_FLAG_BLOCKED, + ids->task_id, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); + if (ret) + return ret; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = sst_send_pipe_module_params(w, k); + return ret; +} + +static int sst_set_media_loop(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + struct sst_cmd_sba_set_media_loop_map cmd; + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct sst_data *drv = snd_soc_component_get_drvdata(c); + struct sst_ids *ids = w->priv; + + dev_dbg(c->dev, "Enter:widget=%s\n", w->name); + if (SND_SOC_DAPM_EVENT_ON(event)) + cmd.switch_state = SST_SWITCH_ON; + else + cmd.switch_state = SST_SWITCH_OFF; + + SST_FILL_DESTINATION(2, cmd.header.dst, + ids->location_id, SST_DEFAULT_MODULE_ID); + + cmd.header.command_id = SBA_SET_MEDIA_LOOP_MAP; + cmd.header.length = sizeof(struct sst_cmd_sba_set_media_loop_map) + - sizeof(struct sst_dsp_header); + cmd.param.part.cfg.rate = 2; /* 48khz */ + + cmd.param.part.cfg.format = ids->format; /* stereo/Mono */ + cmd.param.part.cfg.s_length = 1; /* 24bit left justified */ + cmd.map = 0; /* Algo sequence: Gain - DRP - FIR - IIR */ + + ret = sst_fill_and_send_cmd(drv, SST_IPC_IA_CMD, SST_FLAG_BLOCKED, + SST_TASK_SBA, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); + if (ret) + return ret; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = sst_send_pipe_module_params(w, k); + return ret; +} + +static const char * const slot_names[] = { + "none", + "slot 0", "slot 1", "slot 2", "slot 3", + "slot 4", "slot 5", "slot 6", "slot 7", /* not supported by FW */ +}; + +static const char * const channel_names[] = { + "none", + "codec_out0_0", "codec_out0_1", "codec_out1_0", "codec_out1_1", + "codec_out2_0", "codec_out2_1", "codec_out3_0", "codec_out3_1", /* not supported by FW */ +}; + +#define SST_INTERLEAVER(xpname, slot_name, slotno) \ + SST_SSP_SLOT_CTL(xpname, "tx interleaver", slot_name, slotno, true, \ + channel_names, sst_slot_get, sst_slot_put) + +#define SST_DEINTERLEAVER(xpname, channel_name, channel_no) \ + SST_SSP_SLOT_CTL(xpname, "rx deinterleaver", channel_name, channel_no, false, \ + slot_names, sst_slot_get, sst_slot_put) + +static const struct snd_kcontrol_new sst_slot_controls[] = { + SST_INTERLEAVER("codec_out", "slot 0", 0), + SST_INTERLEAVER("codec_out", "slot 1", 1), + SST_INTERLEAVER("codec_out", "slot 2", 2), + SST_INTERLEAVER("codec_out", "slot 3", 3), + SST_DEINTERLEAVER("codec_in", "codec_in0_0", 0), + SST_DEINTERLEAVER("codec_in", "codec_in0_1", 1), + SST_DEINTERLEAVER("codec_in", "codec_in1_0", 2), + SST_DEINTERLEAVER("codec_in", "codec_in1_1", 3), +}; + /* Gain helper with min/max set */ #define SST_GAIN(name, path_id, task_id, instance, gain_var) \ SST_GAIN_KCONTROLS(name, "Gain", SST_GAIN_MIN_VALUE, SST_GAIN_MAX_VALUE, \ @@ -382,6 +899,234 @@ static int sst_algo_control_init(struct device *dev) return 0; } +static bool is_sst_dapm_widget(struct snd_soc_dapm_widget *w) +{ + switch (w->id) { + case snd_soc_dapm_pga: + case snd_soc_dapm_aif_in: + case snd_soc_dapm_aif_out: + case snd_soc_dapm_input: + case snd_soc_dapm_output: + case snd_soc_dapm_mixer: + return true; + default: + return false; + } +} + +/** + * sst_send_pipe_gains - send gains for the front-end DAIs + * + * The gains in the pipes connected to the front-ends are muted/unmuted + * automatically via the digital_mute() DAPM callback. This function sends the + * gains for the front-end pipes. + */ +int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute) +{ + struct sst_data *drv = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dapm_widget *w; + struct snd_soc_dapm_path *p = NULL; + + dev_dbg(dai->dev, "enter, dai-name=%s dir=%d\n", dai->name, stream); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + dev_dbg(dai->dev, "Stream name=%s\n", + dai->playback_widget->name); + w = dai->playback_widget; + list_for_each_entry(p, &w->sinks, list_source) { + if (p->connected && !p->connected(w, p->sink)) + continue; + + if (p->connect && p->sink->power && + is_sst_dapm_widget(p->sink)) { + struct sst_ids *ids = p->sink->priv; + + dev_dbg(dai->dev, "send gains for widget=%s\n", + p->sink->name); + mutex_lock(&drv->lock); + sst_set_pipe_gain(ids, drv, mute); + mutex_unlock(&drv->lock); + } + } + } else { + dev_dbg(dai->dev, "Stream name=%s\n", + dai->capture_widget->name); + w = dai->capture_widget; + list_for_each_entry(p, &w->sources, list_sink) { + if (p->connected && !p->connected(w, p->sink)) + continue; + + if (p->connect && p->source->power && + is_sst_dapm_widget(p->source)) { + struct sst_ids *ids = p->source->priv; + + dev_dbg(dai->dev, "send gain for widget=%s\n", + p->source->name); + mutex_lock(&drv->lock); + sst_set_pipe_gain(ids, drv, mute); + mutex_unlock(&drv->lock); + } + } + } + return 0; +} + +/** + * sst_fill_module_list - populate the list of modules/gains for a pipe + * + * + * Fills the widget pointer in the kcontrol private data, and also fills the + * kcontrol pointer in the widget private data. + * + * Widget pointer is used to send the algo/gain in the .put() handler if the + * widget is powerd on. + * + * Kcontrol pointer is used to send the algo/gain in the widget power ON/OFF + * event handler. Each widget (pipe) has multiple algos stored in the algo_list. + */ +static int sst_fill_module_list(struct snd_kcontrol *kctl, + struct snd_soc_dapm_widget *w, int type) +{ + struct sst_module *module = NULL; + struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); + struct sst_ids *ids = w->priv; + int ret = 0; + + module = devm_kzalloc(c->dev, sizeof(*module), GFP_KERNEL); + if (!module) + return -ENOMEM; + + if (type == SST_MODULE_GAIN) { + struct sst_gain_mixer_control *mc = (void *)kctl->private_value; + + mc->w = w; + module->kctl = kctl; + list_add_tail(&module->node, &ids->gain_list); + } else if (type == SST_MODULE_ALGO) { + struct sst_algo_control *bc = (void *)kctl->private_value; + + bc->w = w; + module->kctl = kctl; + list_add_tail(&module->node, &ids->algo_list); + } else { + dev_err(c->dev, "invoked for unknown type %d module %s", + type, kctl->id.name); + ret = -EINVAL; + } + + return ret; +} + +/** + * sst_fill_widget_module_info - fill list of gains/algos for the pipe + * @widget: pipe modelled as a DAPM widget + * + * Fill the list of gains/algos for the widget by looking at all the card + * controls and comparing the name of the widget with the first part of control + * name. First part of control name contains the pipe name (widget name). + */ +static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w, + struct snd_soc_platform *platform) +{ + struct snd_kcontrol *kctl; + int index, ret = 0; + struct snd_card *card = platform->component.card->snd_card; + char *idx; + + down_read(&card->controls_rwsem); + + list_for_each_entry(kctl, &card->controls, list) { + idx = strstr(kctl->id.name, " "); + if (idx == NULL) + continue; + index = strlen(kctl->id.name) - strlen(idx); + + if (strstr(kctl->id.name, "Volume") && + !strncmp(kctl->id.name, w->name, index)) + ret = sst_fill_module_list(kctl, w, SST_MODULE_GAIN); + + else if (strstr(kctl->id.name, "params") && + !strncmp(kctl->id.name, w->name, index)) + ret = sst_fill_module_list(kctl, w, SST_MODULE_ALGO); + + else if (strstr(kctl->id.name, "Switch") && + !strncmp(kctl->id.name, w->name, index) && + strstr(kctl->id.name, "Gain")) { + struct sst_gain_mixer_control *mc = + (void *)kctl->private_value; + + mc->w = w; + + } else if (strstr(kctl->id.name, "interleaver") && + !strncmp(kctl->id.name, w->name, index)) { + struct sst_enum *e = (void *)kctl->private_value; + + e->w = w; + + } else if (strstr(kctl->id.name, "deinterleaver") && + !strncmp(kctl->id.name, w->name, index)) { + + struct sst_enum *e = (void *)kctl->private_value; + + e->w = w; + } + + if (ret < 0) { + up_read(&card->controls_rwsem); + return ret; + } + } + + up_read(&card->controls_rwsem); + return 0; +} + +/** + * sst_fill_linked_widgets - fill the parent pointer for the linked widget + */ +static void sst_fill_linked_widgets(struct snd_soc_platform *platform, + struct sst_ids *ids) +{ + struct snd_soc_dapm_widget *w; + unsigned int len = strlen(ids->parent_wname); + + list_for_each_entry(w, &platform->component.card->widgets, list) { + if (!strncmp(ids->parent_wname, w->name, len)) { + ids->parent_w = w; + break; + } + } +} + +/** + * sst_map_modules_to_pipe - fill algo/gains list for all pipes + */ +static int sst_map_modules_to_pipe(struct snd_soc_platform *platform) +{ + struct snd_soc_dapm_widget *w; + int ret = 0; + + list_for_each_entry(w, &platform->component.card->widgets, list) { + if (platform && is_sst_dapm_widget(w) && (w->priv)) { + struct sst_ids *ids = w->priv; + + dev_dbg(platform->dev, "widget type=%d name=%s\n", + w->id, w->name); + INIT_LIST_HEAD(&ids->algo_list); + INIT_LIST_HEAD(&ids->gain_list); + ret = sst_fill_widget_module_info(w, platform); + + if (ret < 0) + return ret; + + /* fill linked widgets */ + if (ids->parent_wname != NULL) + sst_fill_linked_widgets(platform, ids); + } + } + return 0; +} + int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) { int i, ret = 0; @@ -411,6 +1156,15 @@ int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) return ret; ret = snd_soc_add_platform_controls(platform, sst_algo_controls, ARRAY_SIZE(sst_algo_controls)); + if (ret) + return ret; + + ret = snd_soc_add_platform_controls(platform, sst_slot_controls, + ARRAY_SIZE(sst_slot_controls)); + if (ret) + return ret; + + ret = sst_map_modules_to_pipe(platform); return ret; } diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h index e530002cd763..dfebfdd5eb2a 100644 --- a/sound/soc/intel/sst-atom-controls.h +++ b/sound/soc/intel/sst-atom-controls.h @@ -364,6 +364,38 @@ struct sst_cmd_generic { struct sst_dsp_header header; } __packed; +struct swm_input_ids { + struct sst_destination_id input_id; +} __packed; + +struct sst_cmd_set_swm { + struct sst_dsp_header header; + struct sst_destination_id output_id; + u16 switch_state; + u16 nb_inputs; + struct swm_input_ids input[SST_CMD_SWM_MAX_INPUTS]; +} __packed; + +struct sst_cmd_set_media_path { + struct sst_dsp_header header; + u16 switch_state; +} __packed; + +struct pcm_cfg { + u8 s_length:2; + u8 rate:3; + u8 format:3; +} __packed; + +struct sst_cmd_set_speech_path { + struct sst_dsp_header header; + u16 switch_state; + struct { + u16 rsvd:8; + struct pcm_cfg cfg; + } config; +} __packed; + struct gain_cell { struct sst_destination_id dest; s16 cell_gain_left; @@ -383,8 +415,162 @@ struct sst_cmd_set_params { char params[0]; } __packed; + +struct sst_cmd_sba_vb_start { + struct sst_dsp_header header; +} __packed; + +union sba_media_loop_params { + struct { + u16 rsvd:8; + struct pcm_cfg cfg; + } part; + u16 full; +} __packed; + +struct sst_cmd_sba_set_media_loop_map { + struct sst_dsp_header header; + u16 switch_state; + union sba_media_loop_params param; + u16 map; +} __packed; + +struct sst_cmd_tone_stop { + struct sst_dsp_header header; + u16 switch_state; +} __packed; + +enum sst_ssp_mode { + SSP_MODE_MASTER = 0, + SSP_MODE_SLAVE = 1, +}; + +enum sst_ssp_pcm_mode { + SSP_PCM_MODE_NORMAL = 0, + SSP_PCM_MODE_NETWORK = 1, +}; + +enum sst_ssp_duplex { + SSP_DUPLEX = 0, + SSP_RX = 1, + SSP_TX = 2, +}; + +enum sst_ssp_fs_frequency { + SSP_FS_8_KHZ = 0, + SSP_FS_16_KHZ = 1, + SSP_FS_44_1_KHZ = 2, + SSP_FS_48_KHZ = 3, +}; + +enum sst_ssp_fs_polarity { + SSP_FS_ACTIVE_LOW = 0, + SSP_FS_ACTIVE_HIGH = 1, +}; + +enum sst_ssp_protocol { + SSP_MODE_PCM = 0, + SSP_MODE_I2S = 1, +}; + +enum sst_ssp_port_id { + SSP_MODEM = 0, + SSP_BT = 1, + SSP_FM = 2, + SSP_CODEC = 3, +}; + +struct sst_cmd_sba_hw_set_ssp { + struct sst_dsp_header header; + u16 selection; /* 0:SSP0(def), 1:SSP1, 2:SSP2 */ + + u16 switch_state; + + u16 nb_bits_per_slots:6; /* 0-32 bits, 24 (def) */ + u16 nb_slots:4; /* 0-8: slots per frame */ + u16 mode:3; /* 0:Master, 1: Slave */ + u16 duplex:3; + + u16 active_tx_slot_map:8; /* Bit map, 0:off, 1:on */ + u16 reserved1:8; + + u16 active_rx_slot_map:8; /* Bit map 0: Off, 1:On */ + u16 reserved2:8; + + u16 frame_sync_frequency; + + u16 frame_sync_polarity:8; + u16 data_polarity:8; + + u16 frame_sync_width; /* 1 to N clocks */ + u16 ssp_protocol:8; + u16 start_delay:8; /* Start delay in terms of clock ticks */ +} __packed; + +#define SST_MAX_TDM_SLOTS 8 + +struct sst_param_sba_ssp_slot_map { + struct sst_dsp_header header; + + u16 param_id; + u16 param_len; + u16 ssp_index; + + u8 rx_slot_map[SST_MAX_TDM_SLOTS]; + u8 tx_slot_map[SST_MAX_TDM_SLOTS]; +} __packed; + +enum { + SST_PROBE_EXTRACTOR = 0, + SST_PROBE_INJECTOR = 1, +}; + /**** widget defines *****/ +#define SST_MODULE_GAIN 1 +#define SST_MODULE_ALGO 2 + +#define SST_FMT_MONO 0 +#define SST_FMT_STEREO 3 + +/* physical SSP numbers */ +enum { + SST_SSP0 = 0, + SST_SSP1, + SST_SSP2, + SST_SSP_LAST = SST_SSP2, +}; + +#define SST_NUM_SSPS (SST_SSP_LAST + 1) /* physical SSPs */ +#define SST_MAX_SSP_MUX 2 /* single SSP muxed between pipes */ +#define SST_MAX_SSP_DOMAINS 2 /* domains present in each pipe */ + +struct sst_module { + struct snd_kcontrol *kctl; + struct list_head node; +}; + +struct sst_ssp_config { + u8 ssp_id; + u8 bits_per_slot; + u8 slots; + u8 ssp_mode; + u8 pcm_mode; + u8 duplex; + u8 ssp_protocol; + u8 fs_frequency; + u8 active_slot_map; + u8 start_delay; + u16 fs_width; +}; + +struct sst_ssp_cfg { + const u8 ssp_number; + const int *mux_shift; + const int (*domain_shift)[SST_MAX_SSP_MUX]; + const struct sst_ssp_config (*ssp_config)[SST_MAX_SSP_MUX][SST_MAX_SSP_DOMAINS]; +}; + struct sst_ids { u16 location_id; u16 module_id; @@ -397,6 +583,102 @@ struct sst_ids { struct list_head gain_list; const struct sst_pcm_format *pcm_fmt; }; + + +#define SST_AIF_IN(wname, wevent) \ +{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = NULL, \ + .reg = SND_SOC_NOPM, .shift = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ + .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ +} + +#define SST_AIF_OUT(wname, wevent) \ +{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = NULL, \ + .reg = SND_SOC_NOPM, .shift = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ + .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ +} + +#define SST_INPUT(wname, wevent) \ +{ .id = snd_soc_dapm_input, .name = wname, .sname = NULL, \ + .reg = SND_SOC_NOPM, .shift = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ + .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ +} + +#define SST_OUTPUT(wname, wevent) \ +{ .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \ + .reg = SND_SOC_NOPM, .shift = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ + .priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \ +} + +#define SST_DAPM_OUTPUT(wname, wloc_id, wtask_id, wformat, wevent) \ +{ .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \ + .reg = SND_SOC_NOPM, .shift = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ + .priv = (void *)&(struct sst_ids) { .location_id = wloc_id, .task_id = wtask_id,\ + .pcm_fmt = wformat, } \ +} + +#define SST_PATH(wname, wtask, wloc_id, wevent, wflags) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ + .kcontrol_news = NULL, .num_kcontrols = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = wflags, \ + .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, } \ +} + +#define SST_LINKED_PATH(wname, wtask, wloc_id, linked_wname, wevent, wflags) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ + .kcontrol_news = NULL, .num_kcontrols = 0, \ + .on_val = 1, .off_val = 0, \ + .event = wevent, .event_flags = wflags, \ + .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ + .parent_wname = linked_wname} \ +} + +#define SST_PATH_MEDIA_LOOP(wname, wtask, wloc_id, wformat, wevent, wflags) \ +{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ + .kcontrol_news = NULL, .num_kcontrols = 0, \ + .event = wevent, .event_flags = wflags, \ + .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ + .format = wformat,} \ +} + +/* output is triggered before input */ +#define SST_PATH_INPUT(name, task_id, loc_id, event) \ + SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) + +#define SST_PATH_LINKED_INPUT(name, task_id, loc_id, linked_wname, event) \ + SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \ + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) + +#define SST_PATH_OUTPUT(name, task_id, loc_id, event) \ + SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) + +#define SST_PATH_LINKED_OUTPUT(name, task_id, loc_id, linked_wname, event) \ + SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \ + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) + +#define SST_PATH_MEDIA_LOOP_OUTPUT(name, task_id, loc_id, format, event) \ + SST_PATH_MEDIA_LOOP(name, task_id, loc_id, format, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD) + + +#define SST_SWM_MIXER(wname, wreg, wtask, wloc_id, wcontrols, wevent) \ +{ .id = snd_soc_dapm_mixer, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \ + .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols),\ + .event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD | \ + SND_SOC_DAPM_POST_REG, \ + .priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \ + .reg = wreg } \ +} + enum sst_gain_kcontrol_type { SST_GAIN_TLV, SST_GAIN_MUTE, @@ -560,4 +842,29 @@ struct sst_enum { struct snd_soc_dapm_widget *w; }; +/* only 4 slots/channels supported atm */ +#define SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts) \ + (struct sst_enum){ .reg = s_ch_no, .tx = is_tx, .max = 4+1, .texts = xtexts, } + +#define SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name) \ + xpname " " xmname " " s_ch_name + +#define SST_SSP_SLOT_CTL(xpname, xmname, s_ch_name, s_ch_no, is_tx, xtexts, xget, xput) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name), \ + .info = sst_slot_enum_info, \ + .get = xget, .put = xput, \ + .private_value = (unsigned long)&SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts), \ +} + +#define SST_MUX_CTL_NAME(xpname, xinstance) \ + xpname " " #xinstance + +#define SST_SSP_MUX_ENUM(xreg, xshift, xtexts) \ + (struct soc_enum) SOC_ENUM_DOUBLE(xreg, xshift, xshift, ARRAY_SIZE(xtexts), xtexts) + +#define SST_SSP_MUX_CTL(xpname, xinstance, xreg, xshift, xtexts) \ + SOC_DAPM_ENUM(SST_MUX_CTL_NAME(xpname, xinstance), \ + SST_SSP_MUX_ENUM(xreg, xshift, xtexts)) + #endif -- GitLab From e4f5ccd050e5c366ee1301b5b318bdc2780ce94a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 15 Oct 2014 20:12:58 +0530 Subject: [PATCH 0560/9457] ASoC: Intel: mrfld: add the DSP DAPM widgets This patch adds all DAPM widgets and the event handlers for DSP except the mixers. Signed-off-by: Vinod Koul Signed-off-by: Subhransu S. Prusty Signed-off-by: Mark Brown --- sound/soc/intel/sst-atom-controls.c | 226 ++++++++++++++++++++++++++++ sound/soc/intel/sst-mfld-platform.h | 4 + 2 files changed, 230 insertions(+) diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index 9239eff26749..9aa09dbc5ff0 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -547,6 +547,41 @@ static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { [SST_IP_MEDIA3] = SST_SWM_IN_MEDIA3, }; +/** + * fill_swm_input - fill in the SWM input ids given the register + * + * The register value is a bit-field inicated which mixer inputs are ON. Use the + * lookup table to get the input-id and fill it in the structure. + */ +static int fill_swm_input(struct snd_soc_component *cmpnt, + struct swm_input_ids *swm_input, unsigned int reg) +{ + uint i, is_set, nb_inputs = 0; + u16 input_loc_id; + + dev_dbg(cmpnt->dev, "reg: %#x\n", reg); + for (i = 0; i < SST_SWM_INPUT_COUNT; i++) { + is_set = reg & BIT(i); + if (!is_set) + continue; + + input_loc_id = swm_mixer_input_ids[i]; + SST_FILL_DESTINATION(2, swm_input->input_id, + input_loc_id, SST_DEFAULT_MODULE_ID); + nb_inputs++; + swm_input++; + dev_dbg(cmpnt->dev, "input id: %#x, nb_inputs: %d\n", + input_loc_id, nb_inputs); + + if (nb_inputs == SST_CMD_SWM_MAX_INPUTS) { + dev_warn(cmpnt->dev, "SET_SWM cmd max inputs reached"); + break; + } + } + return nb_inputs; +} + + /** * called with lock held */ @@ -573,6 +608,112 @@ static int sst_set_pipe_gain(struct sst_ids *ids, return ret; } +static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct sst_cmd_set_swm cmd; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct sst_data *drv = snd_soc_component_get_drvdata(cmpnt); + struct sst_ids *ids = w->priv; + bool set_mixer = false; + struct soc_mixer_control *mc; + int val = 0; + int i = 0; + + dev_dbg(cmpnt->dev, "widget = %s\n", w->name); + /* + * Identify which mixer input is on and send the bitmap of the + * inputs as an IPC to the DSP. + */ + for (i = 0; i < w->num_kcontrols; i++) { + if (dapm_kcontrol_get_value(w->kcontrols[i])) { + mc = (struct soc_mixer_control *)(w->kcontrols[i])->private_value; + val |= 1 << mc->shift; + } + } + dev_dbg(cmpnt->dev, "val = %#x\n", val); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + case SND_SOC_DAPM_POST_PMD: + set_mixer = true; + break; + case SND_SOC_DAPM_POST_REG: + if (w->power) + set_mixer = true; + break; + default: + set_mixer = false; + } + + if (set_mixer == false) + return 0; + + if (SND_SOC_DAPM_EVENT_ON(event) || + event == SND_SOC_DAPM_POST_REG) + cmd.switch_state = SST_SWM_ON; + else + cmd.switch_state = SST_SWM_OFF; + + SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); + /* MMX_SET_SWM == SBA_SET_SWM */ + cmd.header.command_id = SBA_SET_SWM; + + SST_FILL_DESTINATION(2, cmd.output_id, + ids->location_id, SST_DEFAULT_MODULE_ID); + cmd.nb_inputs = fill_swm_input(cmpnt, &cmd.input[0], val); + cmd.header.length = offsetof(struct sst_cmd_set_swm, input) + - sizeof(struct sst_dsp_header) + + (cmd.nb_inputs * sizeof(cmd.input[0])); + + return sst_fill_and_send_cmd(drv, SST_IPC_IA_CMD, SST_FLAG_BLOCKED, + ids->task_id, 0, &cmd, + sizeof(cmd.header) + cmd.header.length); +} + +/* SBA mixers - 16 inputs */ +#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ + static const struct snd_kcontrol_new kctl_name[] = { \ + SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ + SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ + SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ + SOC_DAPM_SINGLE("media_loop1_in Switch", SND_SOC_NOPM, SST_IP_LOOP1, 1, 0), \ + SOC_DAPM_SINGLE("media_loop2_in Switch", SND_SOC_NOPM, SST_IP_LOOP2, 1, 0), \ + SOC_DAPM_SINGLE("pcm0_in Switch", SND_SOC_NOPM, SST_IP_PCM0, 1, 0), \ + SOC_DAPM_SINGLE("pcm1_in Switch", SND_SOC_NOPM, SST_IP_PCM1, 1, 0), \ + } + +#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ + { mix_name, "codec_in0 Switch", "codec_in0" }, \ + { mix_name, "codec_in1 Switch", "codec_in1" }, \ + { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ + { mix_name, "media_loop1_in Switch", "media_loop1_in" }, \ + { mix_name, "media_loop2_in Switch", "media_loop2_in" }, \ + { mix_name, "pcm0_in Switch", "pcm0_in" }, \ + { mix_name, "pcm1_in Switch", "pcm1_in" } + +#define SST_MMX_DECLARE_MIX_CONTROLS(kctl_name) \ + static const struct snd_kcontrol_new kctl_name[] = { \ + SOC_DAPM_SINGLE("media0_in Switch", SND_SOC_NOPM, SST_IP_MEDIA0, 1, 0), \ + SOC_DAPM_SINGLE("media1_in Switch", SND_SOC_NOPM, SST_IP_MEDIA1, 1, 0), \ + SOC_DAPM_SINGLE("media2_in Switch", SND_SOC_NOPM, SST_IP_MEDIA2, 1, 0), \ + SOC_DAPM_SINGLE("media3_in Switch", SND_SOC_NOPM, SST_IP_MEDIA3, 1, 0), \ + } + +SST_MMX_DECLARE_MIX_CONTROLS(sst_mix_media0_controls); +SST_MMX_DECLARE_MIX_CONTROLS(sst_mix_media1_controls); + +/* 18 SBA mixers */ +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_pcm0_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_pcm1_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_pcm2_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_sprot_l0_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l1_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); +SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); + /* * sst_handle_vb_timer - Start/Stop the DSP scheduler * @@ -784,6 +925,83 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w, return ret; } +static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { + SST_AIF_IN("codec_in0", sst_set_be_modules), + SST_AIF_IN("codec_in1", sst_set_be_modules), + SST_AIF_OUT("codec_out0", sst_set_be_modules), + SST_AIF_OUT("codec_out1", sst_set_be_modules), + + /* Media Paths */ + /* MediaX IN paths are set via ALLOC, so no SET_MEDIA_PATH command */ + SST_PATH_INPUT("media0_in", SST_TASK_MMX, SST_SWM_IN_MEDIA0, sst_generic_modules_event), + SST_PATH_INPUT("media1_in", SST_TASK_MMX, SST_SWM_IN_MEDIA1, NULL), + SST_PATH_INPUT("media2_in", SST_TASK_MMX, SST_SWM_IN_MEDIA2, sst_set_media_path), + SST_PATH_INPUT("media3_in", SST_TASK_MMX, SST_SWM_IN_MEDIA3, NULL), + SST_PATH_OUTPUT("media0_out", SST_TASK_MMX, SST_SWM_OUT_MEDIA0, sst_set_media_path), + SST_PATH_OUTPUT("media1_out", SST_TASK_MMX, SST_SWM_OUT_MEDIA1, sst_set_media_path), + + /* SBA PCM Paths */ + SST_PATH_INPUT("pcm0_in", SST_TASK_SBA, SST_SWM_IN_PCM0, sst_set_media_path), + SST_PATH_INPUT("pcm1_in", SST_TASK_SBA, SST_SWM_IN_PCM1, sst_set_media_path), + SST_PATH_OUTPUT("pcm0_out", SST_TASK_SBA, SST_SWM_OUT_PCM0, sst_set_media_path), + SST_PATH_OUTPUT("pcm1_out", SST_TASK_SBA, SST_SWM_OUT_PCM1, sst_set_media_path), + SST_PATH_OUTPUT("pcm2_out", SST_TASK_SBA, SST_SWM_OUT_PCM2, sst_set_media_path), + + /* SBA Loops */ + SST_PATH_INPUT("sprot_loop_in", SST_TASK_SBA, SST_SWM_IN_SPROT_LOOP, NULL), + SST_PATH_INPUT("media_loop1_in", SST_TASK_SBA, SST_SWM_IN_MEDIA_LOOP1, NULL), + SST_PATH_INPUT("media_loop2_in", SST_TASK_SBA, SST_SWM_IN_MEDIA_LOOP2, NULL), + SST_PATH_MEDIA_LOOP_OUTPUT("sprot_loop_out", SST_TASK_SBA, SST_SWM_OUT_SPROT_LOOP, SST_FMT_MONO, sst_set_media_loop), + SST_PATH_MEDIA_LOOP_OUTPUT("media_loop1_out", SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP1, SST_FMT_MONO, sst_set_media_loop), + SST_PATH_MEDIA_LOOP_OUTPUT("media_loop2_out", SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2, SST_FMT_STEREO, sst_set_media_loop), + + /* Media Mixers */ +}; + +static const struct snd_soc_dapm_route intercon[] = { + {"media0_in", NULL, "Compress Playback"}, + {"media1_in", NULL, "Headset Playback"}, + {"media2_in", NULL, "pcm0_out"}, + + {"media0_out mix 0", "media0_in Switch", "media0_in"}, + {"media0_out mix 0", "media1_in Switch", "media1_in"}, + {"media0_out mix 0", "media2_in Switch", "media2_in"}, + {"media0_out mix 0", "media3_in Switch", "media3_in"}, + {"media1_out mix 0", "media0_in Switch", "media0_in"}, + {"media1_out mix 0", "media1_in Switch", "media1_in"}, + {"media1_out mix 0", "media2_in Switch", "media2_in"}, + {"media1_out mix 0", "media3_in Switch", "media3_in"}, + + {"media0_out", NULL, "media0_out mix 0"}, + {"media1_out", NULL, "media1_out mix 0"}, + {"pcm0_in", NULL, "media0_out"}, + {"pcm1_in", NULL, "media1_out"}, + + {"Headset Capture", NULL, "pcm1_out"}, + {"Headset Capture", NULL, "pcm2_out"}, + {"pcm0_out", NULL, "pcm0_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("pcm0_out mix 0"), + {"pcm1_out", NULL, "pcm1_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("pcm1_out mix 0"), + {"pcm2_out", NULL, "pcm2_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("pcm2_out mix 0"), + + {"media_loop1_in", NULL, "media_loop1_out"}, + {"media_loop1_out", NULL, "media_loop1_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("media_loop1_out mix 0"), + {"media_loop2_in", NULL, "media_loop2_out"}, + {"media_loop2_out", NULL, "media_loop2_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("media_loop2_out mix 0"), + {"sprot_loop_in", NULL, "sprot_loop_out"}, + {"sprot_loop_out", NULL, "sprot_loop_out mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("sprot_loop_out mix 0"), + + {"codec_out0", NULL, "codec_out0 mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), + {"codec_out1", NULL, "codec_out1 mix 0"}, + SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), + +}; static const char * const slot_names[] = { "none", "slot 0", "slot 1", "slot 2", "slot 3", @@ -1130,6 +1348,8 @@ static int sst_map_modules_to_pipe(struct snd_soc_platform *platform) int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) { int i, ret = 0; + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(&platform->component); struct sst_data *drv = snd_soc_platform_get_drvdata(platform); unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3; @@ -1138,6 +1358,12 @@ int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) if (!drv->byte_stream) return -ENOMEM; + snd_soc_dapm_new_controls(dapm, sst_dapm_widgets, + ARRAY_SIZE(sst_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, + ARRAY_SIZE(intercon)); + snd_soc_dapm_new_widgets(dapm->card); + for (i = 0; i < gains; i++) { sst_gains[i].mute = SST_GAIN_MUTE_DEFAULT; sst_gains[i].l_gain = SST_GAIN_VOLUME_DEFAULT; diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index 19f83ec51613..d41d1c36031a 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -153,6 +153,10 @@ struct sst_device { struct sst_data; int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform); +int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute); +int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable); +int sst_handle_vb_timer(struct snd_soc_dai *dai, bool enable); + void sst_set_stream_status(struct sst_runtime_stream *stream, int state); int sst_fill_stream_params(void *substream, const struct sst_data *ctx, struct snd_sst_params *str_params, bool is_compress); -- GitLab From c82351da2e9f2b14d5664e41b021ec1fd948b932 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 15 Oct 2014 20:12:59 +0530 Subject: [PATCH 0561/9457] ASoC: Intel: mfld-pcm: add FE and BE ops Now that we have added code for managing DSP pipelines we need to add the code for DSPs FrontEnd and Backend dai. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform-pcm.c | 153 +++++++++++++++++++----- 1 file changed, 125 insertions(+), 28 deletions(-) diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index aa9b600dfc9b..e7cf18d1d421 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -101,35 +101,11 @@ static struct sst_dev_stream_map dpcm_strm_map[] = { {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0}, }; -/* MFLD - MSIC */ -static struct snd_soc_dai_driver sst_platform_dai[] = { +static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream) { - .name = "Headset-cpu-dai", - .id = 0, - .playback = { - .channels_min = SST_STEREO, - .channels_max = SST_STEREO, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S24_LE, - }, - .capture = { - .channels_min = 1, - .channels_max = 5, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S24_LE, - }, -}, -{ - .name = "Compress-cpu-dai", - .compress_dai = 1, - .playback = { - .channels_min = SST_STEREO, - .channels_max = SST_STEREO, - .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, -}, -}; + + return sst_send_pipe_gains(dai, stream, mute); +} /* helper functions */ void sst_set_stream_status(struct sst_runtime_stream *stream, @@ -451,12 +427,133 @@ static int sst_media_hw_free(struct snd_pcm_substream *substream, return snd_pcm_lib_free_pages(substream); } +static int sst_enable_ssp(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int ret = 0; + + if (!dai->active) { + ret = sst_handle_vb_timer(dai, true); + if (ret) + return ret; + ret = send_ssp_cmd(dai, dai->name, 1); + } + return ret; +} + +static void sst_disable_ssp(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + if (!dai->active) { + send_ssp_cmd(dai, dai->name, 0); + sst_handle_vb_timer(dai, false); + } +} + static struct snd_soc_dai_ops sst_media_dai_ops = { .startup = sst_media_open, .shutdown = sst_media_close, .prepare = sst_media_prepare, .hw_params = sst_media_hw_params, .hw_free = sst_media_hw_free, + .mute_stream = sst_media_digital_mute, +}; + +static struct snd_soc_dai_ops sst_compr_dai_ops = { + .mute_stream = sst_media_digital_mute, +}; + +static struct snd_soc_dai_ops sst_be_dai_ops = { + .startup = sst_enable_ssp, + .shutdown = sst_disable_ssp, +}; + +static struct snd_soc_dai_driver sst_platform_dai[] = { +{ + .name = "media-cpu-dai", + .ops = &sst_media_dai_ops, + .playback = { + .stream_name = "Headset Playback", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "Headset Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, +{ + .name = "compress-cpu-dai", + .compress_dai = 1, + .ops = &sst_compr_dai_ops, + .playback = { + .stream_name = "Compress Playback", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, +/* BE CPU Dais */ +{ + .name = "ssp0-port", + .ops = &sst_be_dai_ops, + .playback = { + .stream_name = "ssp0 Tx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "ssp0 Rx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, +{ + .name = "ssp1-port", + .ops = &sst_be_dai_ops, + .playback = { + .stream_name = "ssp1 Tx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "ssp1 Rx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, +{ + .name = "ssp2-port", + .ops = &sst_be_dai_ops, + .playback = { + .stream_name = "ssp2 Tx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "ssp2 Rx", + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}, }; static int sst_platform_open(struct snd_pcm_substream *substream) -- GitLab From f2b3a93973ca7cda6e6365c0a8ff7c4438778a6f Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 15 Oct 2014 20:13:00 +0530 Subject: [PATCH 0562/9457] ASoC: Intel: mrfld: add the DSP mixers Signed-off-by: Vinod Koul Signed-off-by: Subhransu S. Prusty Signed-off-by: Mark Brown --- sound/soc/intel/sst-atom-controls.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index 9aa09dbc5ff0..dcdeb28a49fe 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -956,6 +956,32 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { SST_PATH_MEDIA_LOOP_OUTPUT("media_loop2_out", SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2, SST_FMT_STEREO, sst_set_media_loop), /* Media Mixers */ + SST_SWM_MIXER("media0_out mix 0", SND_SOC_NOPM, SST_TASK_MMX, SST_SWM_OUT_MEDIA0, + sst_mix_media0_controls, sst_swm_mixer_event), + SST_SWM_MIXER("media1_out mix 0", SND_SOC_NOPM, SST_TASK_MMX, SST_SWM_OUT_MEDIA1, + sst_mix_media1_controls, sst_swm_mixer_event), + + /* SBA PCM mixers */ + SST_SWM_MIXER("pcm0_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_PCM0, + sst_mix_pcm0_controls, sst_swm_mixer_event), + SST_SWM_MIXER("pcm1_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_PCM1, + sst_mix_pcm1_controls, sst_swm_mixer_event), + SST_SWM_MIXER("pcm2_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_PCM2, + sst_mix_pcm2_controls, sst_swm_mixer_event), + + /* SBA Loop mixers */ + SST_SWM_MIXER("sprot_loop_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_SPROT_LOOP, + sst_mix_sprot_l0_controls, sst_swm_mixer_event), + SST_SWM_MIXER("media_loop1_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP1, + sst_mix_media_l1_controls, sst_swm_mixer_event), + SST_SWM_MIXER("media_loop2_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MEDIA_LOOP2, + sst_mix_media_l2_controls, sst_swm_mixer_event), + + /* SBA Backend mixers */ + SST_SWM_MIXER("codec_out0 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC0, + sst_mix_codec0_controls, sst_swm_mixer_event), + SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, + sst_mix_codec1_controls, sst_swm_mixer_event), }; static const struct snd_soc_dapm_route intercon[] = { -- GitLab From 5914ccf47bb0954210d64a92396632442c4f2a80 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 13:54:29 +0530 Subject: [PATCH 0563/9457] ASoC: intel: turn off COMPILE_TEST for medfield Since medfield machine uses SCU_IPC which is not availble for all archs, so compile test fails on these Reported-by: kbuild test robot Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 726f7d891a7a..f5b4a9c79cdf 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -1,6 +1,6 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" - depends on INTEL_SCU_IPC || COMPILE_TEST + depends on INTEL_SCU_IPC select SND_SOC_SN95031 select SND_SST_MFLD_PLATFORM help -- GitLab From f07e51c51e44a6e4e6d003f3bccbbf8a1b2cda0d Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 16 Oct 2014 15:29:15 +0100 Subject: [PATCH 0564/9457] ASoC: Intel: Add TDM support to HSW/BDW SSP port Add TDM support to SSP port via DSP IPC SetDeviceFormat message. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 4 ++++ sound/soc/intel/sst-haswell-ipc.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index b6291516dbbf..92d625ab6415 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1630,6 +1630,10 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, config.clock_frequency = mclk; config.mode = mode; config.clock_divider = clock_divider; + if (mode == SST_HSW_DEVICE_TDM_CLOCK_MASTER) + config.channels = 4; + else + config.channels = 2; trace_hsw_device_config_req(&config); diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index 2ac194a6d04b..063dd6b669bf 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h @@ -84,6 +84,7 @@ enum sst_hsw_device_mclk { enum sst_hsw_device_mode { SST_HSW_DEVICE_CLOCK_SLAVE = 0, SST_HSW_DEVICE_CLOCK_MASTER = 1, + SST_HSW_DEVICE_TDM_CLOCK_MASTER = 2, }; /* DX Power State */ @@ -295,7 +296,8 @@ struct sst_hsw_ipc_device_config_req { u32 clock_frequency; u32 mode; u16 clock_divider; - u16 reserved; + u8 channels; + u8 reserved; } __attribute__((packed)); /* Audio Data formats */ -- GitLab From 48dc326f6ba71ba0ee5b1bbfc128a6577ba98608 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 16 Oct 2014 15:29:16 +0100 Subject: [PATCH 0565/9457] ASoC: Intel: Add 4 channel support to DSP. DSP can now support 4 channels in certain use cases. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 4 ---- sound/soc/intel/sst-haswell-pcm.c | 8 +------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 92d625ab6415..4799768c43cd 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1256,10 +1256,6 @@ int sst_hsw_stream_set_channels(struct sst_hsw *hsw, return -EINVAL; } - /* stereo is only supported atm */ - if (channels != 2) - return -EINVAL; - stream->request.format.ch_num = channels; return 0; } diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 33fc5c3abf55..32a33b9e36c4 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -421,13 +421,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, return ret; } - /* we only support stereo atm */ channels = params_channels(params); - if (channels != 2) { - dev_err(rtd->dev, "error: invalid channels %d\n", channels); - return -EINVAL; - } - map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO); sst_hsw_stream_set_map_config(hsw, pcm_data->stream, map, SST_HSW_CHANNEL_CONFIG_STEREO); @@ -743,7 +737,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { .capture = { .stream_name = "Analog Capture", .channels_min = 2, - .channels_max = 2, + .channels_max = 4, .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, -- GitLab From 8046249d3ef18a1093fbee9ab8eb16c05c13edc7 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 16 Oct 2014 15:29:17 +0100 Subject: [PATCH 0566/9457] ASoC: Intel: Make HSW/BDW pointer debug verbose Improve the debug SNR by making the positional pointer debug more verbose. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 32a33b9e36c4..32a6470ae38a 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -552,7 +552,7 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data) pos = frames_to_bytes(runtime, (runtime->control->appl_ptr % runtime->buffer_size)); - dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); + dev_vdbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); /* let alsa know we have play a period */ snd_pcm_period_elapsed(substream); @@ -574,7 +574,7 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream) offset = bytes_to_frames(runtime, position); ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); - dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", + dev_vdbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", position, ppos); return offset; } -- GitLab From 3750a8f7d1df5e6442e0fc537d1d37b1b48d3712 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Fri, 17 Oct 2014 00:14:19 +0800 Subject: [PATCH 0567/9457] ASoC: Intel: mrfld: fix semicolon.cocci warnings sound/soc/intel/sst-atom-controls.c:249:2-3: Unneeded semicolon sound/soc/intel/sst-atom-controls.c:289:2-3: Unneeded semicolon Removes unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Signed-off-by: Fengguang Wu Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-atom-controls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index dcdeb28a49fe..309a8f31428b 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -454,7 +454,7 @@ static int sst_gain_get(struct snd_kcontrol *kcontrol, dev_err(component->dev, "Invalid Input- gain type:%d\n", mc->type); return -EINVAL; - }; + } return 0; } @@ -494,7 +494,7 @@ static int sst_gain_put(struct snd_kcontrol *kcontrol, dev_err(cmpnt->dev, "Invalid Input- gain type:%d\n", mc->type); return -EINVAL; - }; + } if (mc->w && mc->w->power) ret = sst_send_gain_cmd(drv, gv, mc->task_id, -- GitLab From 163d2089d226ab184469f53561f1a63f151757c3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:13 +0530 Subject: [PATCH 0568/9457] ASoC: Intel: mrfld - add the dsp sst driver The SST driver is the missing piece in our driver stack not upstreamed, so push it now :) This driver currently supports PCI device on Merrifield. Future updates will bring support for ACPI device as well as future update to PCI devices as well In subsequent patches support is added for DSP loading using memcpy, pcm operations and compressed ops. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- arch/x86/include/asm/platform_sst_audio.h | 34 ++ sound/soc/intel/sst/sst.c | 434 +++++++++++++++++ sound/soc/intel/sst/sst.h | 539 ++++++++++++++++++++++ 3 files changed, 1007 insertions(+) create mode 100644 sound/soc/intel/sst/sst.c create mode 100644 sound/soc/intel/sst/sst.h diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h index 0a4e140315b6..268a96aec77c 100644 --- a/arch/x86/include/asm/platform_sst_audio.h +++ b/arch/x86/include/asm/platform_sst_audio.h @@ -16,6 +16,9 @@ #include +#define MAX_NUM_STREAMS_MRFLD 25 +#define MAX_NUM_STREAMS MAX_NUM_STREAMS_MRFLD + enum sst_audio_task_id_mrfld { SST_TASK_ID_NONE = 0, SST_TASK_ID_SBA = 1, @@ -73,6 +76,37 @@ struct sst_platform_data { unsigned int strm_map_size; }; +struct sst_info { + u32 iram_start; + u32 iram_end; + bool iram_use; + u32 dram_start; + u32 dram_end; + bool dram_use; + u32 imr_start; + u32 imr_end; + bool imr_use; + u32 mailbox_start; + bool use_elf; + bool lpe_viewpt_rqd; + unsigned int max_streams; + u32 dma_max_len; + u8 num_probes; +}; + +struct sst_lib_dnld_info { + unsigned int mod_base; + unsigned int mod_end; + unsigned int mod_table_offset; + unsigned int mod_table_size; + bool mod_ddr_dnld; +}; + +struct sst_platform_info { + const struct sst_info *probe_data; + const struct sst_ipc_info *ipc_info; + const struct sst_lib_dnld_info *lib_info; +}; int add_sst_platform_device(void); #endif diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c new file mode 100644 index 000000000000..d88cdd97f747 --- /dev/null +++ b/sound/soc/intel/sst/sst.c @@ -0,0 +1,434 @@ +/* + * sst.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + +MODULE_AUTHOR("Vinod Koul "); +MODULE_AUTHOR("Harsha Priya "); +MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine Driver"); +MODULE_LICENSE("GPL v2"); + +static inline bool sst_is_process_reply(u32 msg_id) +{ + return ((msg_id & PROCESS_MSG) ? true : false); +} + +static inline bool sst_validate_mailbox_size(unsigned int size) +{ + return ((size <= SST_MAILBOX_SIZE) ? true : false); +} + +static irqreturn_t intel_sst_interrupt_mrfld(int irq, void *context) +{ + union interrupt_reg_mrfld isr; + union ipc_header_mrfld header; + union sst_imr_reg_mrfld imr; + struct ipc_post *msg = NULL; + unsigned int size = 0; + struct intel_sst_drv *drv = (struct intel_sst_drv *) context; + irqreturn_t retval = IRQ_HANDLED; + + /* Interrupt arrived, check src */ + isr.full = sst_shim_read64(drv->shim, SST_ISRX); + + if (isr.part.done_interrupt) { + /* Clear done bit */ + spin_lock(&drv->ipc_spin_lock); + header.full = sst_shim_read64(drv->shim, + drv->ipc_reg.ipcx); + header.p.header_high.part.done = 0; + sst_shim_write64(drv->shim, drv->ipc_reg.ipcx, header.full); + + /* write 1 to clear status register */; + isr.part.done_interrupt = 1; + sst_shim_write64(drv->shim, SST_ISRX, isr.full); + spin_unlock(&drv->ipc_spin_lock); + + /* we can send more messages to DSP so trigger work */ + queue_work(drv->post_msg_wq, &drv->ipc_post_msg_wq); + retval = IRQ_HANDLED; + } + + if (isr.part.busy_interrupt) { + /* message from dsp so copy that */ + spin_lock(&drv->ipc_spin_lock); + imr.full = sst_shim_read64(drv->shim, SST_IMRX); + imr.part.busy_interrupt = 1; + sst_shim_write64(drv->shim, SST_IMRX, imr.full); + spin_unlock(&drv->ipc_spin_lock); + header.full = sst_shim_read64(drv->shim, drv->ipc_reg.ipcd); + + if (sst_create_ipc_msg(&msg, header.p.header_high.part.large)) { + drv->ops->clear_interrupt(drv); + return IRQ_HANDLED; + } + + if (header.p.header_high.part.large) { + size = header.p.header_low_payload; + if (sst_validate_mailbox_size(size)) { + memcpy_fromio(msg->mailbox_data, + drv->mailbox + drv->mailbox_recv_offset, size); + } else { + dev_err(drv->dev, + "Mailbox not copied, payload size is: %u\n", size); + header.p.header_low_payload = 0; + } + } + + msg->mrfld_header = header; + msg->is_process_reply = + sst_is_process_reply(header.p.header_high.part.msg_id); + spin_lock(&drv->rx_msg_lock); + list_add_tail(&msg->node, &drv->rx_list); + spin_unlock(&drv->rx_msg_lock); + drv->ops->clear_interrupt(drv); + retval = IRQ_WAKE_THREAD; + } + return retval; +} + +static irqreturn_t intel_sst_irq_thread_mrfld(int irq, void *context) +{ + struct intel_sst_drv *drv = (struct intel_sst_drv *) context; + struct ipc_post *__msg, *msg = NULL; + unsigned long irq_flags; + + spin_lock_irqsave(&drv->rx_msg_lock, irq_flags); + if (list_empty(&drv->rx_list)) { + spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); + return IRQ_HANDLED; + } + + list_for_each_entry_safe(msg, __msg, &drv->rx_list, node) { + list_del(&msg->node); + spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); + if (msg->is_process_reply) + drv->ops->process_message(msg); + else + drv->ops->process_reply(drv, msg); + + if (msg->is_large) + kfree(msg->mailbox_data); + kfree(msg); + spin_lock_irqsave(&drv->rx_msg_lock, irq_flags); + } + spin_unlock_irqrestore(&drv->rx_msg_lock, irq_flags); + return IRQ_HANDLED; +} + +static struct intel_sst_ops mrfld_ops = { + .interrupt = intel_sst_interrupt_mrfld, + .irq_thread = intel_sst_irq_thread_mrfld, + .clear_interrupt = intel_sst_clear_intr_mrfld, + .start = sst_start_mrfld, + .reset = intel_sst_reset_dsp_mrfld, + .post_message = sst_post_message_mrfld, + .process_reply = sst_process_reply_mrfld, + .alloc_stream = sst_alloc_stream_mrfld, + .post_download = sst_post_download_mrfld, +}; + +int sst_driver_ops(struct intel_sst_drv *sst) +{ + + switch (sst->pci_id) { + case SST_MRFLD_PCI_ID: + sst->tstamp = SST_TIME_STAMP_MRFLD; + sst->ops = &mrfld_ops; + return 0; + + default: + dev_err(sst->dev, + "SST Driver capablities missing for pci_id: %x", sst->pci_id); + return -EINVAL; + }; +} + +void sst_process_pending_msg(struct work_struct *work) +{ + struct intel_sst_drv *ctx = container_of(work, + struct intel_sst_drv, ipc_post_msg_wq); + + ctx->ops->post_message(ctx, NULL, false); +} + +/* +* intel_sst_probe - PCI probe function +* +* @pci: PCI device structure +* @pci_id: PCI device ID structure +* +*/ +static int intel_sst_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + int i, ret = 0; + struct intel_sst_drv *sst_drv_ctx; + struct intel_sst_ops *ops; + struct sst_platform_info *sst_pdata = pci->dev.platform_data; + int ddr_base; + + dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); + sst_drv_ctx = devm_kzalloc(&pci->dev, sizeof(*sst_drv_ctx), GFP_KERNEL); + if (!sst_drv_ctx) + return -ENOMEM; + + sst_drv_ctx->dev = &pci->dev; + sst_drv_ctx->pci_id = pci->device; + if (!sst_pdata) + return -EINVAL; + + sst_drv_ctx->pdata = sst_pdata; + if (!sst_drv_ctx->pdata->probe_data) + return -EINVAL; + + memcpy(&sst_drv_ctx->info, sst_drv_ctx->pdata->probe_data, + sizeof(sst_drv_ctx->info)); + + if (0 != sst_driver_ops(sst_drv_ctx)) + return -EINVAL; + + ops = sst_drv_ctx->ops; + mutex_init(&sst_drv_ctx->sst_lock); + + /* pvt_id 0 reserved for async messages */ + sst_drv_ctx->pvt_id = 1; + sst_drv_ctx->stream_cnt = 0; + sst_drv_ctx->fw_in_mem = NULL; + + /* we use memcpy, so set to 0 */ + sst_drv_ctx->use_dma = 0; + sst_drv_ctx->use_lli = 0; + + INIT_LIST_HEAD(&sst_drv_ctx->memcpy_list); + INIT_LIST_HEAD(&sst_drv_ctx->ipc_dispatch_list); + INIT_LIST_HEAD(&sst_drv_ctx->block_list); + INIT_LIST_HEAD(&sst_drv_ctx->rx_list); + + sst_drv_ctx->post_msg_wq = + create_singlethread_workqueue("sst_post_msg_wq"); + if (!sst_drv_ctx->post_msg_wq) { + ret = -EINVAL; + goto do_free_drv_ctx; + } + INIT_WORK(&sst_drv_ctx->ipc_post_msg_wq, sst_process_pending_msg); + init_waitqueue_head(&sst_drv_ctx->wait_queue); + + spin_lock_init(&sst_drv_ctx->ipc_spin_lock); + spin_lock_init(&sst_drv_ctx->block_lock); + spin_lock_init(&sst_drv_ctx->rx_msg_lock); + + dev_info(sst_drv_ctx->dev, "Got drv data max stream %d\n", + sst_drv_ctx->info.max_streams); + for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) { + struct stream_info *stream = &sst_drv_ctx->streams[i]; + + memset(stream, 0, sizeof(*stream)); + stream->pipe_id = PIPE_RSVD; + mutex_init(&stream->lock); + } + + /* Init the device */ + ret = pcim_enable_device(pci); + if (ret) { + dev_err(sst_drv_ctx->dev, + "device can't be enabled. Returned err: %d\n", ret); + goto do_free_mem; + } + sst_drv_ctx->pci = pci_dev_get(pci); + ret = pci_request_regions(pci, SST_DRV_NAME); + if (ret) + goto do_free_mem; + + /* map registers */ + /* DDR base */ + if (sst_drv_ctx->pci_id == SST_MRFLD_PCI_ID) { + sst_drv_ctx->ddr_base = pci_resource_start(pci, 0); + /* check that the relocated IMR base matches with FW Binary */ + ddr_base = relocate_imr_addr_mrfld(sst_drv_ctx->ddr_base); + if (!sst_drv_ctx->pdata->lib_info) { + dev_err(sst_drv_ctx->dev, "lib_info pointer NULL\n"); + ret = -EINVAL; + goto do_release_regions; + } + if (ddr_base != sst_drv_ctx->pdata->lib_info->mod_base) { + dev_err(sst_drv_ctx->dev, + "FW LSP DDR BASE does not match with IFWI\n"); + ret = -EINVAL; + goto do_release_regions; + } + sst_drv_ctx->ddr_end = pci_resource_end(pci, 0); + + sst_drv_ctx->ddr = pcim_iomap(pci, 0, + pci_resource_len(pci, 0)); + if (!sst_drv_ctx->ddr) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(sst_drv_ctx->dev, "sst: DDR Ptr %p\n", sst_drv_ctx->ddr); + } else { + sst_drv_ctx->ddr = NULL; + } + + /* SHIM */ + sst_drv_ctx->shim_phy_add = pci_resource_start(pci, 1); + sst_drv_ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); + if (!sst_drv_ctx->shim) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(sst_drv_ctx->dev, "SST Shim Ptr %p\n", sst_drv_ctx->shim); + + /* Shared SRAM */ + sst_drv_ctx->mailbox_add = pci_resource_start(pci, 2); + sst_drv_ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); + if (!sst_drv_ctx->mailbox) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(sst_drv_ctx->dev, "SRAM Ptr %p\n", sst_drv_ctx->mailbox); + + /* IRAM */ + sst_drv_ctx->iram_end = pci_resource_end(pci, 3); + sst_drv_ctx->iram_base = pci_resource_start(pci, 3); + sst_drv_ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); + if (!sst_drv_ctx->iram) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(sst_drv_ctx->dev, "IRAM Ptr %p\n", sst_drv_ctx->iram); + + /* DRAM */ + sst_drv_ctx->dram_end = pci_resource_end(pci, 4); + sst_drv_ctx->dram_base = pci_resource_start(pci, 4); + sst_drv_ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); + if (!sst_drv_ctx->dram) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(sst_drv_ctx->dev, "DRAM Ptr %p\n", sst_drv_ctx->dram); + + + sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); + sst_drv_ctx->irq_num = pci->irq; + /* Register the ISR */ + ret = devm_request_threaded_irq(&pci->dev, pci->irq, + sst_drv_ctx->ops->interrupt, + sst_drv_ctx->ops->irq_thread, 0, SST_DRV_NAME, + sst_drv_ctx); + if (ret) + goto do_release_regions; + dev_dbg(sst_drv_ctx->dev, "Registered IRQ 0x%x\n", pci->irq); + + /* default intr are unmasked so set this as masked */ + if (sst_drv_ctx->pci_id == SST_MRFLD_PCI_ID) + sst_shim_write64(sst_drv_ctx->shim, SST_IMRX, 0xFFFF0038); + + pci_set_drvdata(pci, sst_drv_ctx); + pm_runtime_set_autosuspend_delay(sst_drv_ctx->dev, SST_SUSPEND_DELAY); + pm_runtime_use_autosuspend(sst_drv_ctx->dev); + pm_runtime_allow(sst_drv_ctx->dev); + pm_runtime_put_noidle(sst_drv_ctx->dev); + sst_register(sst_drv_ctx->dev); + sst_drv_ctx->qos = devm_kzalloc(&pci->dev, + sizeof(struct pm_qos_request), GFP_KERNEL); + if (!sst_drv_ctx->qos) { + ret = -ENOMEM; + goto do_release_regions; + } + pm_qos_add_request(sst_drv_ctx->qos, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + + return ret; + +do_release_regions: + pci_release_regions(pci); +do_free_mem: + destroy_workqueue(sst_drv_ctx->post_msg_wq); +do_free_drv_ctx: + dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); + return ret; +} + +/** +* intel_sst_remove - PCI remove function +* +* @pci: PCI device structure +* +* This function is called by OS when a device is unloaded +* This frees the interrupt etc +*/ +static void intel_sst_remove(struct pci_dev *pci) +{ + struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); + + pm_runtime_get_noresume(sst_drv_ctx->dev); + pm_runtime_forbid(sst_drv_ctx->dev); + sst_unregister(sst_drv_ctx->dev); + pci_dev_put(sst_drv_ctx->pci); + sst_set_fw_state_locked(sst_drv_ctx, SST_SHUTDOWN); + + flush_scheduled_work(); + destroy_workqueue(sst_drv_ctx->post_msg_wq); + pm_qos_remove_request(sst_drv_ctx->qos); + kfree(sst_drv_ctx->fw_sg_list.src); + kfree(sst_drv_ctx->fw_sg_list.dst); + sst_drv_ctx->fw_sg_list.list_len = 0; + kfree(sst_drv_ctx->fw_in_mem); + sst_drv_ctx->fw_in_mem = NULL; + sst_memcpy_free_resources(sst_drv_ctx); + sst_drv_ctx = NULL; + pci_release_regions(pci); + pci_set_drvdata(pci, NULL); +} + +/* PCI Routines */ +static struct pci_device_id intel_sst_ids[] = { + { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, + { 0, } +}; + +static struct pci_driver sst_driver = { + .name = SST_DRV_NAME, + .id_table = intel_sst_ids, + .probe = intel_sst_probe, + .remove = intel_sst_remove, +}; + +module_pci_driver(sst_driver); diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h new file mode 100644 index 000000000000..bfcf51ad3f5a --- /dev/null +++ b/sound/soc/intel/sst/sst.h @@ -0,0 +1,539 @@ +/* + * sst.h - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corporation + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Common private declarations for SST + */ +#ifndef __SST_H__ +#define __SST_H__ + +#include + +/* driver names */ +#define SST_DRV_NAME "intel_sst_driver" +#define SST_MRFLD_PCI_ID 0x119A + +#define SST_SUSPEND_DELAY 2000 +#define FW_CONTEXT_MEM (64*1024) +#define SST_ICCM_BOUNDARY 4 +#define SST_CONFIG_SSP_SIGN 0x7ffe8001 + +#define MRFLD_FW_VIRTUAL_BASE 0xC0000000 +#define MRFLD_FW_DDR_BASE_OFFSET 0x0 +#define MRFLD_FW_FEATURE_BASE_OFFSET 0x4 +#define MRFLD_FW_BSS_RESET_BIT 0 + +enum sst_states { + SST_FW_LOADING = 1, + SST_FW_RUNNING, + SST_RESET, + SST_SHUTDOWN, +}; + +enum sst_algo_ops { + SST_SET_ALGO = 0, + SST_GET_ALGO = 1, +}; + +#define SST_BLOCK_TIMEOUT 1000 + +#define FW_SIGNATURE_SIZE 4 + +/* stream states */ +enum sst_stream_states { + STREAM_UN_INIT = 0, /* Freed/Not used stream */ + STREAM_RUNNING = 1, /* Running */ + STREAM_PAUSED = 2, /* Paused stream */ + STREAM_DECODE = 3, /* stream is in decoding only state */ + STREAM_INIT = 4, /* stream init, waiting for data */ + STREAM_RESET = 5, /* force reset on recovery */ +}; + +enum sst_ram_type { + SST_IRAM = 1, + SST_DRAM = 2, + SST_DDR = 5, + SST_CUSTOM_INFO = 7, /* consists of FW binary information */ +}; + +/* SST shim registers to structure mapping */ +union interrupt_reg { + struct { + u64 done_interrupt:1; + u64 busy_interrupt:1; + u64 rsvd:62; + } part; + u64 full; +}; + +union sst_pisr_reg { + struct { + u32 pssp0:1; + u32 pssp1:1; + u32 rsvd0:3; + u32 dmac:1; + u32 rsvd1:26; + } part; + u32 full; +}; + +union sst_pimr_reg { + struct { + u32 ssp0:1; + u32 ssp1:1; + u32 rsvd0:3; + u32 dmac:1; + u32 rsvd1:10; + u32 ssp0_sc:1; + u32 ssp1_sc:1; + u32 rsvd2:3; + u32 dmac_sc:1; + u32 rsvd3:10; + } part; + u32 full; +}; + +union config_status_reg_mrfld { + struct { + u64 lpe_reset:1; + u64 lpe_reset_vector:1; + u64 runstall:1; + u64 pwaitmode:1; + u64 clk_sel:3; + u64 rsvd2:1; + u64 sst_clk:3; + u64 xt_snoop:1; + u64 rsvd3:4; + u64 clk_sel1:6; + u64 clk_enable:3; + u64 rsvd4:6; + u64 slim0baseclk:1; + u64 rsvd:32; + } part; + u64 full; +}; + +union interrupt_reg_mrfld { + struct { + u64 done_interrupt:1; + u64 busy_interrupt:1; + u64 rsvd:62; + } part; + u64 full; +}; + +union sst_imr_reg_mrfld { + struct { + u64 done_interrupt:1; + u64 busy_interrupt:1; + u64 rsvd:62; + } part; + u64 full; +}; + +/** + * struct sst_block - This structure is used to block a user/fw data call to another + * fw/user call + * + * @condition: condition for blocking check + * @ret_code: ret code when block is released + * @data: data ptr + * @size: size of data + * @on: block condition + * @msg_id: msg_id = msgid in mfld/ctp, mrfld = NULL + * @drv_id: str_id in mfld/ctp, = drv_id in mrfld + * @node: list head node + */ +struct sst_block { + bool condition; + int ret_code; + void *data; + u32 size; + bool on; + u32 msg_id; + u32 drv_id; + struct list_head node; +}; + +/** + * struct stream_info - structure that holds the stream information + * + * @status : stream current state + * @prev : stream prev state + * @ops : stream operation pb/cp/drm... + * @bufs: stream buffer list + * @lock : stream mutex for protecting state + * @pcm_substream : PCM substream + * @period_elapsed : PCM period elapsed callback + * @sfreq : stream sampling freq + * @str_type : stream type + * @cumm_bytes : cummulative bytes decoded + * @str_type : stream type + * @src : stream source + */ +struct stream_info { + unsigned int status; + unsigned int prev; + unsigned int ops; + struct mutex lock; + + void *pcm_substream; + void (*period_elapsed)(void *pcm_substream); + + unsigned int sfreq; + u32 cumm_bytes; + + void *compr_cb_param; + void (*compr_cb)(void *compr_cb_param); + + void *drain_cb_param; + void (*drain_notify)(void *drain_cb_param); + + unsigned int num_ch; + unsigned int pipe_id; + unsigned int str_id; + unsigned int task_id; +}; + +#define SST_FW_SIGN "$SST" +#define SST_FW_LIB_SIGN "$LIB" + +/** + * struct sst_fw_header - FW file headers + * + * @signature : FW signature + * @file_size: size of fw image + * @modules : # of modules + * @file_format : version of header format + * @reserved : reserved fields + */ +struct sst_fw_header { + unsigned char signature[FW_SIGNATURE_SIZE]; + u32 file_size; + u32 modules; + u32 file_format; + u32 reserved[4]; +}; + +/** + * struct fw_module_header - module header in FW + * + * @signature: module signature + * @mod_size: size of module + * @blocks: block count + * @type: block type + * @entry_point: module netry point + */ +struct fw_module_header { + unsigned char signature[FW_SIGNATURE_SIZE]; + u32 mod_size; + u32 blocks; + u32 type; + u32 entry_point; +}; + +/** + * struct fw_block_info - block header for FW + * + * @type: block ram type I/D + * @size: size of block + * @ram_offset: offset in ram + */ +struct fw_block_info { + enum sst_ram_type type; + u32 size; + u32 ram_offset; + u32 rsvd; +}; + +struct sst_runtime_param { + struct snd_sst_runtime_params param; +}; + +struct sst_sg_list { + struct scatterlist *src; + struct scatterlist *dst; + int list_len; + unsigned int sg_idx; +}; + +struct sst_memcpy_list { + struct list_head memcpylist; + void *dstn; + const void *src; + u32 size; + bool is_io; +}; + +/*Firmware Module Information*/ +enum sst_lib_dwnld_status { + SST_LIB_NOT_FOUND = 0, + SST_LIB_FOUND, + SST_LIB_DOWNLOADED, +}; + +struct sst_module_info { + const char *name; /*Library name*/ + u32 id; /*Module ID*/ + u32 entry_pt; /*Module entry point*/ + u8 status; /*module status*/ + u8 rsvd1; + u16 rsvd2; +}; + +/* + * Structure for managing the Library Region(1.5MB) + * in DDR in Merrifield + */ +struct sst_mem_mgr { + phys_addr_t current_base; + int avail; + unsigned int count; +}; + +struct sst_ipc_reg { + int ipcx; + int ipcd; +}; + +struct sst_shim_regs64 { + u64 csr; + u64 pisr; + u64 pimr; + u64 isrx; + u64 isrd; + u64 imrx; + u64 imrd; + u64 ipcx; + u64 ipcd; + u64 isrsc; + u64 isrlpesc; + u64 imrsc; + u64 imrlpesc; + u64 ipcsc; + u64 ipclpesc; + u64 clkctl; + u64 csr2; +}; + +/** + * struct intel_sst_drv - driver ops + * + * @sst_state : current sst device state + * @pci_id : PCI device id loaded + * @shim : SST shim pointer + * @mailbox : SST mailbox pointer + * @iram : SST IRAM pointer + * @dram : SST DRAM pointer + * @pdata : SST info passed as a part of pci platform data + * @shim_phy_add : SST shim phy addr + * @shim_regs64: Struct to save shim registers + * @ipc_dispatch_list : ipc messages dispatched + * @rx_list : to copy the process_reply/process_msg from DSP + * @ipc_post_msg_wq : wq to post IPC messages context + * @mad_ops : MAD driver operations registered + * @mad_wq : MAD driver wq + * @post_msg_wq : wq to post IPC messages + * @streams : sst stream contexts + * @list_lock : sst driver list lock (deprecated) + * @ipc_spin_lock : spin lock to handle audio shim access and ipc queue + * @block_lock : spin lock to add block to block_list and assign pvt_id + * @rx_msg_lock : spin lock to handle the rx messages from the DSP + * @scard_ops : sst card ops + * @pci : sst pci device struture + * @dev : pointer to current device struct + * @sst_lock : sst device lock + * @pvt_id : sst private id + * @stream_cnt : total sst active stream count + * @pb_streams : total active pb streams + * @cp_streams : total active cp streams + * @audio_start : audio status + * @qos : PM Qos struct + * firmware_name : Firmware / Library name + */ +struct intel_sst_drv { + int sst_state; + int irq_num; + unsigned int pci_id; + void __iomem *ddr; + void __iomem *shim; + void __iomem *mailbox; + void __iomem *iram; + void __iomem *dram; + unsigned int mailbox_add; + unsigned int iram_base; + unsigned int dram_base; + unsigned int shim_phy_add; + unsigned int iram_end; + unsigned int dram_end; + unsigned int ddr_end; + unsigned int ddr_base; + unsigned int mailbox_recv_offset; + struct sst_shim_regs64 *shim_regs64; + struct list_head block_list; + struct list_head ipc_dispatch_list; + struct sst_platform_info *pdata; + struct list_head rx_list; + struct work_struct ipc_post_msg_wq; + wait_queue_head_t wait_queue; + struct workqueue_struct *post_msg_wq; + unsigned int tstamp; + /* str_id 0 is not used */ + struct stream_info streams[MAX_NUM_STREAMS+1]; + spinlock_t ipc_spin_lock; + spinlock_t block_lock; + spinlock_t rx_msg_lock; + struct pci_dev *pci; + struct device *dev; + volatile long unsigned pvt_id; + struct mutex sst_lock; + unsigned int stream_cnt; + unsigned int csr_value; + void *fw_in_mem; + struct sst_sg_list fw_sg_list, library_list; + struct intel_sst_ops *ops; + struct sst_info info; + struct pm_qos_request *qos; + unsigned int use_dma; + unsigned int use_lli; + atomic_t fw_clear_context; + bool lib_dwnld_reqd; + struct list_head memcpy_list; + struct sst_ipc_reg ipc_reg; + struct sst_mem_mgr lib_mem_mgr; + /* + * Holder for firmware name. Due to async call it needs to be + * persistent till worker thread gets called + */ + char firmware_name[20]; +}; + +/* misc definitions */ +#define FW_DWNL_ID 0x01 + +struct intel_sst_ops { + irqreturn_t (*interrupt)(int, void *); + irqreturn_t (*irq_thread)(int, void *); + void (*clear_interrupt)(struct intel_sst_drv *ctx); + int (*start)(struct intel_sst_drv *ctx); + int (*reset)(struct intel_sst_drv *ctx); + void (*process_reply)(struct intel_sst_drv *ctx, struct ipc_post *msg); + int (*post_message)(struct intel_sst_drv *ctx, + struct ipc_post *msg, bool sync); + void (*process_message)(struct ipc_post *msg); + void (*set_bypass)(bool set); + int (*save_dsp_context)(struct intel_sst_drv *sst); + void (*restore_dsp_context)(void); + int (*alloc_stream)(struct intel_sst_drv *ctx, void *params); + void (*post_download)(struct intel_sst_drv *sst); +}; + +int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int id); +int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int id); +int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int id); +int sst_free_stream(struct intel_sst_drv *sst_drv_ctx, int id); +int sst_start_stream(struct intel_sst_drv *sst_drv_ctx, int str_id); +int sst_send_byte_stream_mrfld(struct intel_sst_drv *ctx, + struct snd_sst_bytes_v2 *sbytes); +int sst_set_stream_param(int str_id, struct snd_sst_params *str_param); +int sst_set_metadata(int str_id, char *params); +int sst_get_stream(struct intel_sst_drv *sst_drv_ctx, + struct snd_sst_params *str_param); +int sst_get_stream_allocated(struct intel_sst_drv *ctx, + struct snd_sst_params *str_param, + struct snd_sst_lib_download **lib_dnld); +int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx, + int str_id, bool partial_drain); +int sst_post_message_mrfld(struct intel_sst_drv *ctx, + struct ipc_post *msg, bool sync); +void sst_process_reply_mrfld(struct intel_sst_drv *ctx, struct ipc_post *msg); +int sst_start_mrfld(struct intel_sst_drv *ctx); +int intel_sst_reset_dsp_mrfld(struct intel_sst_drv *ctx); +void intel_sst_clear_intr_mrfld(struct intel_sst_drv *ctx); + +int sst_load_fw(struct intel_sst_drv *ctx); +int sst_load_library(struct snd_sst_lib_download *lib, u8 ops); +void sst_post_download_mrfld(struct intel_sst_drv *ctx); +int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx); +void sst_memcpy_free_resources(struct intel_sst_drv *ctx); + +int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx, + struct sst_block *block); +int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx, + struct sst_block *block); +int sst_create_ipc_msg(struct ipc_post **arg, bool large); +int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id); +void sst_clean_stream(struct stream_info *stream); +int intel_sst_register_compress(struct intel_sst_drv *sst); +int intel_sst_remove_compress(struct intel_sst_drv *sst); +void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id); +int sst_send_sync_msg(int ipc, int str_id); +int sst_get_num_channel(struct snd_sst_params *str_param); +int sst_get_sfreq(struct snd_sst_params *str_param); +int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params); +void sst_restore_fw_context(void); +struct sst_block *sst_create_block(struct intel_sst_drv *ctx, + u32 msg_id, u32 drv_id); +int sst_create_block_and_ipc_msg(struct ipc_post **arg, bool large, + struct intel_sst_drv *sst_drv_ctx, struct sst_block **block, + u32 msg_id, u32 drv_id); +int sst_free_block(struct intel_sst_drv *ctx, struct sst_block *freed); +int sst_wake_up_block(struct intel_sst_drv *ctx, int result, + u32 drv_id, u32 ipc, void *data, u32 size); +int sst_request_firmware_async(struct intel_sst_drv *ctx); +int sst_driver_ops(struct intel_sst_drv *sst); +struct sst_platform_info *sst_get_acpi_driver_data(const char *hid); +void sst_firmware_load_cb(const struct firmware *fw, void *context); +int sst_prepare_and_post_msg(struct intel_sst_drv *sst, + int task_id, int ipc_msg, int cmd_id, int pipe_id, + size_t mbox_data_len, const void *mbox_data, void **data, + bool large, bool fill_dsp, bool sync, bool response); + +void sst_save_shim64(struct intel_sst_drv *ctx, void __iomem *shim, + struct sst_shim_regs64 *shim_regs); +void sst_process_pending_msg(struct work_struct *work); +int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx); +void sst_init_stream(struct stream_info *stream, + int codec, int sst_id, int ops, u8 slot); +int sst_validate_strid(struct intel_sst_drv *sst_drv_ctx, int str_id); +struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx, + int str_id); +int get_stream_id_mrfld(struct intel_sst_drv *sst_drv_ctx, + u32 pipe_id); +u32 relocate_imr_addr_mrfld(u32 base_addr); +void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst, + struct ipc_post *msg); +int sst_pm_runtime_put(struct intel_sst_drv *sst_drv); +int sst_shim_write(void __iomem *addr, int offset, int value); +u32 sst_shim_read(void __iomem *addr, int offset); +u64 sst_reg_read64(void __iomem *addr, int offset); +int sst_shim_write64(void __iomem *addr, int offset, u64 value); +u64 sst_shim_read64(void __iomem *addr, int offset); +void sst_set_fw_state_locked( + struct intel_sst_drv *sst_drv_ctx, int sst_state); +void sst_fill_header_mrfld(union ipc_header_mrfld *header, + int msg, int task_id, int large, int drv_id); +void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg, + int pipe_id, int len); + +int sst_register(struct device *); +int sst_unregister(struct device *); + +#endif -- GitLab From 9012c9544eeac485b2193fea721233907f0847fa Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:14 +0530 Subject: [PATCH 0569/9457] ASoC: Intel: mrfld - Add DSP load and management This patch contains all dsp controlling functions like firmware download, setting/resetting dsp cores, etc. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_loader.c | 461 +++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 sound/soc/intel/sst/sst_loader.c diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c new file mode 100644 index 000000000000..b6d27c14455a --- /dev/null +++ b/sound/soc/intel/sst/sst_loader.c @@ -0,0 +1,461 @@ +/* + * sst_dsp.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This file contains all dsp controlling functions like firmware download, + * setting/resetting dsp cores, etc + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + +static void memcpy32_toio(void __iomem *dst, const void *src, int count) +{ + int i; + const u32 *src_32 = src; + u32 *dst_32 = dst; + + for (i = 0; i < count/sizeof(u32); i++) + writel(*src_32++, dst_32++); +} + +/** + * intel_sst_reset_dsp_mrfld - Resetting SST DSP + * + * This resets DSP in case of MRFLD platfroms + */ +int intel_sst_reset_dsp_mrfld(struct intel_sst_drv *sst_drv_ctx) +{ + union config_status_reg_mrfld csr; + + dev_dbg(sst_drv_ctx->dev, "sst: Resetting the DSP in mrfld\n"); + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + + dev_dbg(sst_drv_ctx->dev, "value:0x%llx\n", csr.full); + + csr.full |= 0x7; + sst_shim_write64(sst_drv_ctx->shim, SST_CSR, csr.full); + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + + dev_dbg(sst_drv_ctx->dev, "value:0x%llx\n", csr.full); + + csr.full &= ~(0x1); + sst_shim_write64(sst_drv_ctx->shim, SST_CSR, csr.full); + + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + dev_dbg(sst_drv_ctx->dev, "value:0x%llx\n", csr.full); + return 0; +} + +/** + * sst_start_merrifield - Start the SST DSP processor + * + * This starts the DSP in MERRIFIELD platfroms + */ +int sst_start_mrfld(struct intel_sst_drv *sst_drv_ctx) +{ + union config_status_reg_mrfld csr; + + dev_dbg(sst_drv_ctx->dev, "sst: Starting the DSP in mrfld LALALALA\n"); + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + dev_dbg(sst_drv_ctx->dev, "value:0x%llx\n", csr.full); + + csr.full |= 0x7; + sst_shim_write64(sst_drv_ctx->shim, SST_CSR, csr.full); + + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + dev_dbg(sst_drv_ctx->dev, "value:0x%llx\n", csr.full); + + csr.part.xt_snoop = 1; + csr.full &= ~(0x5); + sst_shim_write64(sst_drv_ctx->shim, SST_CSR, csr.full); + + csr.full = sst_shim_read64(sst_drv_ctx->shim, SST_CSR); + dev_dbg(sst_drv_ctx->dev, "sst: Starting the DSP_merrifield:%llx\n", + csr.full); + return 0; +} + +static int sst_validate_fw_image(struct intel_sst_drv *ctx, unsigned long size, + struct fw_module_header **module, u32 *num_modules) +{ + struct sst_fw_header *header; + const void *sst_fw_in_mem = ctx->fw_in_mem; + + dev_dbg(ctx->dev, "Enter\n"); + + /* Read the header information from the data pointer */ + header = (struct sst_fw_header *)sst_fw_in_mem; + dev_dbg(ctx->dev, + "header sign=%s size=%x modules=%x fmt=%x size=%zx\n", + header->signature, header->file_size, header->modules, + header->file_format, sizeof(*header)); + + /* verify FW */ + if ((strncmp(header->signature, SST_FW_SIGN, 4) != 0) || + (size != header->file_size + sizeof(*header))) { + /* Invalid FW signature */ + dev_err(ctx->dev, "InvalidFW sign/filesize mismatch\n"); + return -EINVAL; + } + *num_modules = header->modules; + *module = (void *)sst_fw_in_mem + sizeof(*header); + + return 0; +} + +/* + * sst_fill_memcpy_list - Fill the memcpy list + * + * @memcpy_list: List to be filled + * @destn: Destination addr to be filled in the list + * @src: Source addr to be filled in the list + * @size: Size to be filled in the list + * + * Adds the node to the list after required fields + * are populated in the node + */ +static int sst_fill_memcpy_list(struct list_head *memcpy_list, + void *destn, const void *src, u32 size, bool is_io) +{ + struct sst_memcpy_list *listnode; + + listnode = kzalloc(sizeof(*listnode), GFP_KERNEL); + if (listnode == NULL) + return -ENOMEM; + listnode->dstn = destn; + listnode->src = src; + listnode->size = size; + listnode->is_io = is_io; + list_add_tail(&listnode->memcpylist, memcpy_list); + + return 0; +} + +/** + * sst_parse_module_memcpy - Parse audio FW modules and populate the memcpy list + * + * @sst_drv_ctx : driver context + * @module : FW module header + * @memcpy_list : Pointer to the list to be populated + * Create the memcpy list as the number of block to be copied + * returns error or 0 if module sizes are proper + */ +static int sst_parse_module_memcpy(struct intel_sst_drv *sst_drv_ctx, + struct fw_module_header *module, struct list_head *memcpy_list) +{ + struct fw_block_info *block; + u32 count; + int ret_val = 0; + void __iomem *ram_iomem; + + dev_dbg(sst_drv_ctx->dev, "module sign %s size %x blocks %x type %x\n", + module->signature, module->mod_size, + module->blocks, module->type); + dev_dbg(sst_drv_ctx->dev, "module entrypoint 0x%x\n", module->entry_point); + + block = (void *)module + sizeof(*module); + + for (count = 0; count < module->blocks; count++) { + if (block->size <= 0) { + dev_err(sst_drv_ctx->dev, "block size invalid\n"); + return -EINVAL; + } + switch (block->type) { + case SST_IRAM: + ram_iomem = sst_drv_ctx->iram; + break; + case SST_DRAM: + ram_iomem = sst_drv_ctx->dram; + break; + case SST_DDR: + ram_iomem = sst_drv_ctx->ddr; + break; + case SST_CUSTOM_INFO: + block = (void *)block + sizeof(*block) + block->size; + continue; + default: + dev_err(sst_drv_ctx->dev, "wrong ram type0x%x in block0x%x\n", + block->type, count); + return -EINVAL; + } + + ret_val = sst_fill_memcpy_list(memcpy_list, + ram_iomem + block->ram_offset, + (void *)block + sizeof(*block), block->size, 1); + if (ret_val) + return ret_val; + + block = (void *)block + sizeof(*block) + block->size; + } + return 0; +} + +/** + * sst_parse_fw_memcpy - parse the firmware image & populate the list for memcpy + * + * @ctx : pointer to drv context + * @size : size of the firmware + * @fw_list : pointer to list_head to be populated + * This function parses the FW image and saves the parsed image in the list + * for memcpy + */ +static int sst_parse_fw_memcpy(struct intel_sst_drv *ctx, unsigned long size, + struct list_head *fw_list) +{ + struct fw_module_header *module; + u32 count, num_modules; + int ret_val; + + ret_val = sst_validate_fw_image(ctx, size, &module, &num_modules); + if (ret_val) + return ret_val; + + for (count = 0; count < num_modules; count++) { + ret_val = sst_parse_module_memcpy(ctx, module, fw_list); + if (ret_val) + return ret_val; + module = (void *)module + sizeof(*module) + module->mod_size; + } + + return 0; +} + +/** + * sst_do_memcpy - function initiates the memcpy + * + * @memcpy_list: Pter to memcpy list on which the memcpy needs to be initiated + * + * Triggers the memcpy + */ +static void sst_do_memcpy(struct list_head *memcpy_list) +{ + struct sst_memcpy_list *listnode; + + list_for_each_entry(listnode, memcpy_list, memcpylist) { + if (listnode->is_io == true) + memcpy32_toio((void __iomem *)listnode->dstn, + listnode->src, listnode->size); + else + memcpy(listnode->dstn, listnode->src, listnode->size); + } +} + +void sst_memcpy_free_resources(struct intel_sst_drv *sst_drv_ctx) +{ + struct sst_memcpy_list *listnode, *tmplistnode; + + /* Free the list */ + if (!list_empty(&sst_drv_ctx->memcpy_list)) { + list_for_each_entry_safe(listnode, tmplistnode, + &sst_drv_ctx->memcpy_list, memcpylist) { + list_del(&listnode->memcpylist); + kfree(listnode); + } + } +} + +static int sst_cache_and_parse_fw(struct intel_sst_drv *sst, + const struct firmware *fw) +{ + int retval = 0; + + sst->fw_in_mem = kzalloc(fw->size, GFP_KERNEL); + if (!sst->fw_in_mem) { + retval = -ENOMEM; + goto end_release; + } + dev_dbg(sst->dev, "copied fw to %p", sst->fw_in_mem); + dev_dbg(sst->dev, "phys: %lx", (unsigned long)virt_to_phys(sst->fw_in_mem)); + memcpy(sst->fw_in_mem, fw->data, fw->size); + retval = sst_parse_fw_memcpy(sst, fw->size, &sst->memcpy_list); + if (retval) { + dev_err(sst->dev, "Failed to parse fw\n"); + kfree(sst->fw_in_mem); + sst->fw_in_mem = NULL; + } + +end_release: + release_firmware(fw); + return retval; + +} + +void sst_firmware_load_cb(const struct firmware *fw, void *context) +{ + struct intel_sst_drv *ctx = context; + + dev_dbg(ctx->dev, "Enter\n"); + + if (fw == NULL) { + dev_err(ctx->dev, "request fw failed\n"); + return; + } + + mutex_lock(&ctx->sst_lock); + + if (ctx->sst_state != SST_RESET || + ctx->fw_in_mem != NULL) { + if (fw != NULL) + release_firmware(fw); + mutex_unlock(&ctx->sst_lock); + return; + } + + dev_dbg(ctx->dev, "Request Fw completed\n"); + sst_cache_and_parse_fw(ctx, fw); + mutex_unlock(&ctx->sst_lock); +} + +/* + * sst_request_fw - requests audio fw from kernel and saves a copy + * + * This function requests the SST FW from the kernel, parses it and + * saves a copy in the driver context + */ +static int sst_request_fw(struct intel_sst_drv *sst) +{ + int retval = 0; + char name[20]; + const struct firmware *fw; + + dev_dbg(sst->dev, "Requesting FW %s now...\n", name); + + retval = request_firmware(&fw, name, sst->dev); + if (fw == NULL) { + dev_err(sst->dev, "fw is returning as null\n"); + return -EINVAL; + } + if (retval) { + dev_err(sst->dev, "request fw failed %d\n", retval); + return retval; + } + mutex_lock(&sst->sst_lock); + retval = sst_cache_and_parse_fw(sst, fw); + mutex_unlock(&sst->sst_lock); + + return retval; +} + +/* + * Writing the DDR physical base to DCCM offset + * so that FW can use it to setup TLB + */ +static void sst_dccm_config_write(void __iomem *dram_base, + unsigned int ddr_base) +{ + void __iomem *addr; + u32 bss_reset = 0; + + addr = (void __iomem *)(dram_base + MRFLD_FW_DDR_BASE_OFFSET); + memcpy32_toio(addr, (void *)&ddr_base, sizeof(u32)); + bss_reset |= (1 << MRFLD_FW_BSS_RESET_BIT); + addr = (void __iomem *)(dram_base + MRFLD_FW_FEATURE_BASE_OFFSET); + memcpy32_toio(addr, &bss_reset, sizeof(u32)); + +} + +void sst_post_download_mrfld(struct intel_sst_drv *ctx) +{ + sst_dccm_config_write(ctx->dram, ctx->ddr_base); + dev_dbg(ctx->dev, "config written to DCCM\n"); +} + +/** + * sst_load_fw - function to load FW into DSP + * Transfers the FW to DSP using dma/memcpy + */ +int sst_load_fw(struct intel_sst_drv *sst_drv_ctx) +{ + int ret_val = 0; + struct sst_block *block; + + dev_dbg(sst_drv_ctx->dev, "sst_load_fw\n"); + + if (sst_drv_ctx->sst_state != SST_RESET || + sst_drv_ctx->sst_state == SST_SHUTDOWN) + return -EAGAIN; + + if (!sst_drv_ctx->fw_in_mem) { + dev_dbg(sst_drv_ctx->dev, "sst: FW not in memory retry to download\n"); + ret_val = sst_request_fw(sst_drv_ctx); + if (ret_val) + return ret_val; + } + + BUG_ON(!sst_drv_ctx->fw_in_mem); + block = sst_create_block(sst_drv_ctx, 0, FW_DWNL_ID); + if (block == NULL) + return -ENOMEM; + + /* Prevent C-states beyond C6 */ + pm_qos_update_request(sst_drv_ctx->qos, 0); + + sst_drv_ctx->sst_state = SST_FW_LOADING; + + ret_val = sst_drv_ctx->ops->reset(sst_drv_ctx); + if (ret_val) + goto restore; + + sst_do_memcpy(&sst_drv_ctx->memcpy_list); + + /* Write the DRAM/DCCM config before enabling FW */ + if (sst_drv_ctx->ops->post_download) + sst_drv_ctx->ops->post_download(sst_drv_ctx); + + /* bring sst out of reset */ + ret_val = sst_drv_ctx->ops->start(sst_drv_ctx); + if (ret_val) + goto restore; + + ret_val = sst_wait_timeout(sst_drv_ctx, block); + if (ret_val) { + dev_err(sst_drv_ctx->dev, "fw download failed %d\n" , ret_val); + /* FW download failed due to timeout */ + ret_val = -EBUSY; + + } + + +restore: + /* Re-enable Deeper C-states beyond C6 */ + pm_qos_update_request(sst_drv_ctx->qos, PM_QOS_DEFAULT_VALUE); + sst_free_block(sst_drv_ctx, block); + dev_dbg(sst_drv_ctx->dev, "fw load successful!!!\n"); + + if (sst_drv_ctx->ops->restore_dsp_context) + sst_drv_ctx->ops->restore_dsp_context(); + sst_drv_ctx->sst_state = SST_FW_RUNNING; + return ret_val; +} + -- GitLab From cc547054d3122646cb9be5d4fc80699bf3e281d8 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:15 +0530 Subject: [PATCH 0570/9457] ASoC: Intel: sst - add pcm ops handling This patch adds low level IPC handling for pcm stream operations Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_drv_interface.c | 403 ++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 sound/soc/intel/sst/sst_drv_interface.c diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c new file mode 100644 index 000000000000..aadb0dbaa01c --- /dev/null +++ b/sound/soc/intel/sst/sst_drv_interface.c @@ -0,0 +1,403 @@ +/* + * sst_drv_interface.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + + + +#define NUM_CODEC 2 +#define MIN_FRAGMENT 2 +#define MAX_FRAGMENT 4 +#define MIN_FRAGMENT_SIZE (50 * 1024) +#define MAX_FRAGMENT_SIZE (1024 * 1024) +#define SST_GET_BYTES_PER_SAMPLE(pcm_wd_sz) (((pcm_wd_sz + 15) >> 4) << 1) + +int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id) +{ + struct stream_info *stream; + int ret = 0; + + stream = get_stream_info(ctx, str_id); + if (stream) { + /* str_id is valid, so stream is alloacted */ + ret = sst_free_stream(ctx, str_id); + if (ret) + sst_clean_stream(&ctx->streams[str_id]); + return ret; + } + return ret; +} + +int sst_get_stream_allocated(struct intel_sst_drv *ctx, + struct snd_sst_params *str_param, + struct snd_sst_lib_download **lib_dnld) +{ + int retval; + + retval = ctx->ops->alloc_stream(ctx, str_param); + if (retval > 0) + dev_dbg(ctx->dev, "Stream allocated %d\n", retval); + return retval; + +} + +/* + * sst_get_sfreq - this function returns the frequency of the stream + * + * @str_param : stream params + */ +int sst_get_sfreq(struct snd_sst_params *str_param) +{ + switch (str_param->codec) { + case SST_CODEC_TYPE_PCM: + return str_param->sparams.uc.pcm_params.sfreq; + case SST_CODEC_TYPE_AAC: + return str_param->sparams.uc.aac_params.externalsr; + case SST_CODEC_TYPE_MP3: + return 0; + default: + return -EINVAL; + } +} + +/* + * sst_get_sfreq - this function returns the frequency of the stream + * + * @str_param : stream params + */ +int sst_get_num_channel(struct snd_sst_params *str_param) +{ + switch (str_param->codec) { + case SST_CODEC_TYPE_PCM: + return str_param->sparams.uc.pcm_params.num_chan; + case SST_CODEC_TYPE_MP3: + return str_param->sparams.uc.mp3_params.num_chan; + case SST_CODEC_TYPE_AAC: + return str_param->sparams.uc.aac_params.num_chan; + default: + return -EINVAL; + } +} + +/* + * sst_get_stream - this function prepares for stream allocation + * + * @str_param : stream param + */ +int sst_get_stream(struct intel_sst_drv *ctx, + struct snd_sst_params *str_param) +{ + int retval; + struct stream_info *str_info; + + /* stream is not allocated, we are allocating */ + retval = ctx->ops->alloc_stream(ctx, str_param); + if (retval <= 0) { + return -EIO; + } + /* store sampling freq */ + str_info = &ctx->streams[retval]; + str_info->sfreq = sst_get_sfreq(str_param); + + return retval; +} + +static int sst_power_control(struct device *dev, bool state) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + dev_dbg(ctx->dev, "state:%d", state); + if (state == true) + return pm_runtime_get_sync(dev); + else + return sst_pm_runtime_put(ctx); +} + +/* + * sst_open_pcm_stream - Open PCM interface + * + * @str_param: parameters of pcm stream + * + * This function is called by MID sound card driver to open + * a new pcm interface + */ +static int sst_open_pcm_stream(struct device *dev, + struct snd_sst_params *str_param) +{ + int retval; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + if (!str_param) + return -EINVAL; + + retval = pm_runtime_get_sync(ctx->dev); + if (retval < 0) + return retval; + retval = sst_get_stream(ctx, str_param); + if (retval > 0) { + ctx->stream_cnt++; + } else { + dev_err(ctx->dev, "sst_get_stream returned err %d\n", retval); + sst_pm_runtime_put(ctx); + } + + return retval; +} + +/* + * sst_close_pcm_stream - Close PCM interface + * + * @str_id: stream id to be closed + * + * This function is called by MID sound card driver to close + * an existing pcm interface + */ +static int sst_close_pcm_stream(struct device *dev, unsigned int str_id) +{ + struct stream_info *stream; + int retval = 0; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + stream = get_stream_info(ctx, str_id); + if (!stream) { + dev_err(ctx->dev, "stream info is NULL for str %d!!!\n", str_id); + return -EINVAL; + } + + if (stream->status == STREAM_RESET) { + /* silently fail here as we have cleaned the stream earlier */ + dev_dbg(ctx->dev, "stream in reset state...\n"); + + retval = 0; + goto put; + } + + retval = free_stream_context(ctx, str_id); +put: + stream->pcm_substream = NULL; + stream->status = STREAM_UN_INIT; + stream->period_elapsed = NULL; + ctx->stream_cnt--; + + sst_pm_runtime_put(ctx); + + dev_dbg(ctx->dev, "Exit\n"); + return 0; +} + +static inline int sst_calc_tstamp(struct intel_sst_drv *ctx, + struct pcm_stream_info *info, + struct snd_pcm_substream *substream, + struct snd_sst_tstamp *fw_tstamp) +{ + size_t delay_bytes, delay_frames; + size_t buffer_sz; + u32 pointer_bytes, pointer_samples; + + dev_dbg(ctx->dev, "mrfld ring_buffer_counter %llu in bytes\n", + fw_tstamp->ring_buffer_counter); + dev_dbg(ctx->dev, "mrfld hardware_counter %llu in bytes\n", + fw_tstamp->hardware_counter); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + delay_bytes = (size_t) (fw_tstamp->ring_buffer_counter - + fw_tstamp->hardware_counter); + else + delay_bytes = (size_t) (fw_tstamp->hardware_counter - + fw_tstamp->ring_buffer_counter); + delay_frames = bytes_to_frames(substream->runtime, delay_bytes); + buffer_sz = snd_pcm_lib_buffer_bytes(substream); + div_u64_rem(fw_tstamp->ring_buffer_counter, buffer_sz, &pointer_bytes); + pointer_samples = bytes_to_samples(substream->runtime, pointer_bytes); + + dev_dbg(ctx->dev, "pcm delay %zu in bytes\n", delay_bytes); + + info->buffer_ptr = pointer_samples / substream->runtime->channels; + + info->pcm_delay = delay_frames / substream->runtime->channels; + dev_dbg(ctx->dev, "buffer ptr %llu pcm_delay rep: %llu\n", + info->buffer_ptr, info->pcm_delay); + return 0; +} + +static int sst_read_timestamp(struct device *dev, struct pcm_stream_info *info) +{ + struct stream_info *stream; + struct snd_pcm_substream *substream; + struct snd_sst_tstamp fw_tstamp; + unsigned int str_id; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + str_id = info->str_id; + stream = get_stream_info(ctx, str_id); + if (!stream) + return -EINVAL; + + if (!stream->pcm_substream) + return -EINVAL; + substream = stream->pcm_substream; + + memcpy_fromio(&fw_tstamp, + ((void *)(ctx->mailbox + ctx->tstamp) + + (str_id * sizeof(fw_tstamp))), + sizeof(fw_tstamp)); + return sst_calc_tstamp(ctx, info, substream, &fw_tstamp); +} + +static int sst_stream_start(struct device *dev, int str_id) +{ + struct stream_info *str_info; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + if (ctx->sst_state != SST_FW_RUNNING) + return 0; + str_info = get_stream_info(ctx, str_id); + if (!str_info) + return -EINVAL; + str_info->prev = str_info->status; + str_info->status = STREAM_RUNNING; + sst_start_stream(ctx, str_id); + + return 0; +} + +static int sst_stream_drop(struct device *dev, int str_id) +{ + struct stream_info *str_info; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + if (ctx->sst_state != SST_FW_RUNNING) + return 0; + + str_info = get_stream_info(ctx, str_id); + if (!str_info) + return -EINVAL; + str_info->prev = STREAM_UN_INIT; + str_info->status = STREAM_INIT; + return sst_drop_stream(ctx, str_id); +} + +static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) +{ + int str_id = 0; + struct stream_info *stream; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + str_id = str_info->str_id; + + if (ctx->sst_state != SST_FW_RUNNING) + return 0; + + stream = get_stream_info(ctx, str_id); + if (!stream) + return -EINVAL; + + dev_dbg(ctx->dev, "setting the period ptrs\n"); + stream->pcm_substream = str_info->arg; + stream->period_elapsed = str_info->period_elapsed; + stream->sfreq = str_info->sfreq; + stream->prev = stream->status; + stream->status = STREAM_INIT; + dev_dbg(ctx->dev, + "pcm_substream %p, period_elapsed %p, sfreq %d, status %d\n", + stream->pcm_substream, stream->period_elapsed, + stream->sfreq, stream->status); + + return 0; +} + +/* + * sst_set_byte_stream - Set generic params + * + * @cmd: control cmd to be set + * @arg: command argument + * + * This function is called by MID sound card driver to configure + * SST runtime params. + */ +static int sst_send_byte_stream(struct device *dev, + struct snd_sst_bytes_v2 *bytes) +{ + int ret_val = 0; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + if (NULL == bytes) + return -EINVAL; + ret_val = pm_runtime_get_sync(ctx->dev); + if (ret_val < 0) + return ret_val; + + ret_val = sst_send_byte_stream_mrfld(ctx, bytes); + sst_pm_runtime_put(ctx); + + return ret_val; +} + +static struct sst_ops pcm_ops = { + .open = sst_open_pcm_stream, + .stream_init = sst_stream_init, + .stream_start = sst_stream_start, + .stream_drop = sst_stream_drop, + .stream_read_tstamp = sst_read_timestamp, + .send_byte_stream = sst_send_byte_stream, + .close = sst_close_pcm_stream, + .power = sst_power_control, +}; + +static struct sst_device sst_dsp_device = { + .name = "Intel(R) SST LPE", + .dev = NULL, + .ops = &pcm_ops, +}; + +/* + * sst_register - function to register DSP + * + * This functions registers DSP with the platform driver + */ +int sst_register(struct device *dev) +{ + int ret_val; + + sst_dsp_device.dev = dev; + ret_val = sst_register_dsp(&sst_dsp_device); + if (ret_val) + dev_err(dev, "Unable to register DSP with platform driver\n"); + + return ret_val; +} + +int sst_unregister(struct device *dev) +{ + return sst_unregister_dsp(&sst_dsp_device); +} -- GitLab From ea12aa4acd703b507a20354b7af378b1497369e4 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:16 +0530 Subject: [PATCH 0571/9457] ASoC: Intel: sst: Add IPC handling This patch adds APIs to post IPCs and process reply messages. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_ipc.c | 358 ++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 sound/soc/intel/sst/sst_ipc.c diff --git a/sound/soc/intel/sst/sst_ipc.c b/sound/soc/intel/sst/sst_ipc.c new file mode 100644 index 000000000000..41a2b41b232b --- /dev/null +++ b/sound/soc/intel/sst/sst_ipc.c @@ -0,0 +1,358 @@ +/* + * sst_ipc.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corporation + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + +struct sst_block *sst_create_block(struct intel_sst_drv *ctx, + u32 msg_id, u32 drv_id) +{ + struct sst_block *msg = NULL; + + dev_dbg(ctx->dev, "Enter\n"); + msg = kzalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return NULL; + msg->condition = false; + msg->on = true; + msg->msg_id = msg_id; + msg->drv_id = drv_id; + spin_lock_bh(&ctx->block_lock); + list_add_tail(&msg->node, &ctx->block_list); + spin_unlock_bh(&ctx->block_lock); + + return msg; +} + +int sst_wake_up_block(struct intel_sst_drv *ctx, int result, + u32 drv_id, u32 ipc, void *data, u32 size) +{ + struct sst_block *block = NULL; + + dev_dbg(ctx->dev, "Enter\n"); + + spin_lock_bh(&ctx->block_lock); + list_for_each_entry(block, &ctx->block_list, node) { + dev_dbg(ctx->dev, "Block ipc %d, drv_id %d\n", block->msg_id, + block->drv_id); + if (block->msg_id == ipc && block->drv_id == drv_id) { + dev_dbg(ctx->dev, "free up the block\n"); + block->ret_code = result; + block->data = data; + block->size = size; + block->condition = true; + spin_unlock_bh(&ctx->block_lock); + wake_up(&ctx->wait_queue); + return 0; + } + } + spin_unlock_bh(&ctx->block_lock); + dev_dbg(ctx->dev, + "Block not found or a response received for a short msg for ipc %d, drv_id %d\n", + ipc, drv_id); + return -EINVAL; +} + +int sst_free_block(struct intel_sst_drv *ctx, struct sst_block *freed) +{ + struct sst_block *block = NULL, *__block; + + dev_dbg(ctx->dev, "Enter\n"); + spin_lock_bh(&ctx->block_lock); + list_for_each_entry_safe(block, __block, &ctx->block_list, node) { + if (block == freed) { + pr_debug("pvt_id freed --> %d\n", freed->drv_id); + /* toggle the index position of pvt_id */ + list_del(&freed->node); + spin_unlock_bh(&ctx->block_lock); + kfree(freed->data); + freed->data = NULL; + kfree(freed); + return 0; + } + } + spin_unlock_bh(&ctx->block_lock); + dev_err(ctx->dev, "block is already freed!!!\n"); + return -EINVAL; +} + +int sst_post_message_mrfld(struct intel_sst_drv *sst_drv_ctx, + struct ipc_post *ipc_msg, bool sync) +{ + struct ipc_post *msg = ipc_msg; + union ipc_header_mrfld header; + unsigned int loop_count = 0; + int retval = 0; + unsigned long irq_flags; + + dev_dbg(sst_drv_ctx->dev, "Enter: sync: %d\n", sync); + spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); + header.full = sst_shim_read64(sst_drv_ctx->shim, SST_IPCX); + if (sync) { + while (header.p.header_high.part.busy) { + if (loop_count > 25) { + dev_err(sst_drv_ctx->dev, + "sst: Busy wait failed, cant send this msg\n"); + retval = -EBUSY; + goto out; + } + cpu_relax(); + loop_count++; + header.full = sst_shim_read64(sst_drv_ctx->shim, SST_IPCX); + } + } else { + if (list_empty(&sst_drv_ctx->ipc_dispatch_list)) { + /* queue is empty, nothing to send */ + spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); + dev_dbg(sst_drv_ctx->dev, + "Empty msg queue... NO Action\n"); + return 0; + } + + if (header.p.header_high.part.busy) { + spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); + dev_dbg(sst_drv_ctx->dev, "Busy not free... post later\n"); + return 0; + } + + /* copy msg from list */ + msg = list_entry(sst_drv_ctx->ipc_dispatch_list.next, + struct ipc_post, node); + list_del(&msg->node); + } + dev_dbg(sst_drv_ctx->dev, "sst: Post message: header = %x\n", + msg->mrfld_header.p.header_high.full); + dev_dbg(sst_drv_ctx->dev, "sst: size = 0x%x\n", + msg->mrfld_header.p.header_low_payload); + + if (msg->mrfld_header.p.header_high.part.large) + memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND, + msg->mailbox_data, + msg->mrfld_header.p.header_low_payload); + + sst_shim_write64(sst_drv_ctx->shim, SST_IPCX, msg->mrfld_header.full); + +out: + spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); + kfree(msg->mailbox_data); + kfree(msg); + return retval; +} + +void intel_sst_clear_intr_mrfld(struct intel_sst_drv *sst_drv_ctx) +{ + union interrupt_reg_mrfld isr; + union interrupt_reg_mrfld imr; + union ipc_header_mrfld clear_ipc; + unsigned long irq_flags; + + spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags); + imr.full = sst_shim_read64(sst_drv_ctx->shim, SST_IMRX); + isr.full = sst_shim_read64(sst_drv_ctx->shim, SST_ISRX); + + /* write 1 to clear*/ + isr.part.busy_interrupt = 1; + sst_shim_write64(sst_drv_ctx->shim, SST_ISRX, isr.full); + + /* Set IA done bit */ + clear_ipc.full = sst_shim_read64(sst_drv_ctx->shim, SST_IPCD); + + clear_ipc.p.header_high.part.busy = 0; + clear_ipc.p.header_high.part.done = 1; + clear_ipc.p.header_low_payload = IPC_ACK_SUCCESS; + sst_shim_write64(sst_drv_ctx->shim, SST_IPCD, clear_ipc.full); + /* un mask busy interrupt */ + imr.part.busy_interrupt = 0; + sst_shim_write64(sst_drv_ctx->shim, SST_IMRX, imr.full); + spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags); +} + + +/* + * process_fw_init - process the FW init msg + * + * @msg: IPC message mailbox data from FW + * + * This function processes the FW init msg from FW + * marks FW state and prints debug info of loaded FW + */ +static void process_fw_init(struct intel_sst_drv *sst_drv_ctx, + void *msg) +{ + struct ipc_header_fw_init *init = + (struct ipc_header_fw_init *)msg; + int retval = 0; + + dev_dbg(sst_drv_ctx->dev, "*** FW Init msg came***\n"); + if (init->result) { + sst_drv_ctx->sst_state = SST_RESET; + dev_err(sst_drv_ctx->dev, "FW Init failed, Error %x\n", + init->result); + retval = init->result; + goto ret; + } + +ret: + sst_wake_up_block(sst_drv_ctx, retval, FW_DWNL_ID, 0 , NULL, 0); +} + +static void process_fw_async_msg(struct intel_sst_drv *sst_drv_ctx, + struct ipc_post *msg) +{ + u32 msg_id; + int str_id; + u32 data_size, i; + void *data_offset; + struct stream_info *stream; + union ipc_header_high msg_high; + u32 msg_low, pipe_id; + + msg_high = msg->mrfld_header.p.header_high; + msg_low = msg->mrfld_header.p.header_low_payload; + msg_id = ((struct ipc_dsp_hdr *)msg->mailbox_data)->cmd_id; + data_offset = (msg->mailbox_data + sizeof(struct ipc_dsp_hdr)); + data_size = msg_low - (sizeof(struct ipc_dsp_hdr)); + + switch (msg_id) { + case IPC_SST_PERIOD_ELAPSED_MRFLD: + pipe_id = ((struct ipc_dsp_hdr *)msg->mailbox_data)->pipe_id; + str_id = get_stream_id_mrfld(sst_drv_ctx, pipe_id); + if (str_id > 0) { + dev_dbg(sst_drv_ctx->dev, + "Period elapsed rcvd for pipe id 0x%x\n", + pipe_id); + stream = &sst_drv_ctx->streams[str_id]; + if (stream->period_elapsed) + stream->period_elapsed(stream->pcm_substream); + if (stream->compr_cb) + stream->compr_cb(stream->compr_cb_param); + } + break; + + case IPC_IA_DRAIN_STREAM_MRFLD: + pipe_id = ((struct ipc_dsp_hdr *)msg->mailbox_data)->pipe_id; + str_id = get_stream_id_mrfld(sst_drv_ctx, pipe_id); + if (str_id > 0) { + stream = &sst_drv_ctx->streams[str_id]; + if (stream->drain_notify) + stream->drain_notify(stream->drain_cb_param); + } + break; + + case IPC_IA_FW_ASYNC_ERR_MRFLD: + dev_err(sst_drv_ctx->dev, "FW sent async error msg:\n"); + for (i = 0; i < (data_size/4); i++) + print_hex_dump(KERN_DEBUG, NULL, DUMP_PREFIX_NONE, + 16, 4, data_offset, data_size, false); + break; + + case IPC_IA_FW_INIT_CMPLT_MRFLD: + process_fw_init(sst_drv_ctx, data_offset); + break; + + case IPC_IA_BUF_UNDER_RUN_MRFLD: + pipe_id = ((struct ipc_dsp_hdr *)msg->mailbox_data)->pipe_id; + str_id = get_stream_id_mrfld(sst_drv_ctx, pipe_id); + if (str_id > 0) + dev_err(sst_drv_ctx->dev, + "Buffer under-run for pipe:%#x str_id:%d\n", + pipe_id, str_id); + break; + + default: + dev_err(sst_drv_ctx->dev, + "Unrecognized async msg from FW msg_id %#x\n", msg_id); + } +} + +void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx, + struct ipc_post *msg) +{ + unsigned int drv_id; + void *data; + union ipc_header_high msg_high; + u32 msg_low; + struct ipc_dsp_hdr *dsp_hdr; + unsigned int cmd_id; + + msg_high = msg->mrfld_header.p.header_high; + msg_low = msg->mrfld_header.p.header_low_payload; + + dev_dbg(sst_drv_ctx->dev, "IPC process message header %x payload %x\n", + msg->mrfld_header.p.header_high.full, + msg->mrfld_header.p.header_low_payload); + + drv_id = msg_high.part.drv_id; + + /* Check for async messages first */ + if (drv_id == SST_ASYNC_DRV_ID) { + /*FW sent async large message*/ + process_fw_async_msg(sst_drv_ctx, msg); + return; + } + + /* FW sent short error response for an IPC */ + if (msg_high.part.result && drv_id && !msg_high.part.large) { + /* 32-bit FW error code in msg_low */ + dev_err(sst_drv_ctx->dev, "FW sent error response 0x%x", msg_low); + sst_wake_up_block(sst_drv_ctx, msg_high.part.result, + msg_high.part.drv_id, + msg_high.part.msg_id, NULL, 0); + return; + } + + /* + * Process all valid responses + * if it is a large message, the payload contains the size to + * copy from mailbox + **/ + if (msg_high.part.large) { + data = kzalloc(msg_low, GFP_KERNEL); + if (!data) + return; + memcpy(data, (void *) msg->mailbox_data, msg_low); + /* Copy command id so that we can use to put sst to reset */ + dsp_hdr = (struct ipc_dsp_hdr *)data; + cmd_id = dsp_hdr->cmd_id; + dev_dbg(sst_drv_ctx->dev, "cmd_id %d\n", dsp_hdr->cmd_id); + if (sst_wake_up_block(sst_drv_ctx, msg_high.part.result, + msg_high.part.drv_id, + msg_high.part.msg_id, data, msg_low)) + kfree(data); + } else { + sst_wake_up_block(sst_drv_ctx, msg_high.part.result, + msg_high.part.drv_id, + msg_high.part.msg_id, NULL, 0); + } + +} -- GitLab From 3d9ff34622badd65543430a784f7af9838c5c3fc Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:17 +0530 Subject: [PATCH 0572/9457] ASoC: Intel: sst: add stream operations This patch adds pcm and compressed stream control operations. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_stream.c | 437 +++++++++++++++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 sound/soc/intel/sst/sst_stream.c diff --git a/sound/soc/intel/sst/sst_stream.c b/sound/soc/intel/sst/sst_stream.c new file mode 100644 index 000000000000..dae2a41997aa --- /dev/null +++ b/sound/soc/intel/sst/sst_stream.c @@ -0,0 +1,437 @@ +/* + * sst_stream.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + +int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params) +{ + struct snd_sst_alloc_mrfld alloc_param; + struct snd_sst_params *str_params; + struct snd_sst_tstamp fw_tstamp; + struct stream_info *str_info; + struct snd_sst_alloc_response *response; + unsigned int str_id, pipe_id, task_id; + int i, num_ch, ret = 0; + void *data = NULL; + + dev_dbg(sst_drv_ctx->dev, "Enter\n"); + BUG_ON(!params); + + str_params = (struct snd_sst_params *)params; + memset(&alloc_param, 0, sizeof(alloc_param)); + alloc_param.operation = str_params->ops; + alloc_param.codec_type = str_params->codec; + alloc_param.sg_count = str_params->aparams.sg_count; + alloc_param.ring_buf_info[0].addr = + str_params->aparams.ring_buf_info[0].addr; + alloc_param.ring_buf_info[0].size = + str_params->aparams.ring_buf_info[0].size; + alloc_param.frag_size = str_params->aparams.frag_size; + + memcpy(&alloc_param.codec_params, &str_params->sparams, + sizeof(struct snd_sst_stream_params)); + + /* + * fill channel map params for multichannel support. + * Ideally channel map should be received from upper layers + * for multichannel support. + * Currently hardcoding as per FW reqm. + */ + num_ch = sst_get_num_channel(str_params); + for (i = 0; i < 8; i++) { + if (i < num_ch) + alloc_param.codec_params.uc.pcm_params.channel_map[i] = i; + else + alloc_param.codec_params.uc.pcm_params.channel_map[i] = 0xFF; + } + + str_id = str_params->stream_id; + str_info = get_stream_info(sst_drv_ctx, str_id); + if (str_info == NULL) { + dev_err(sst_drv_ctx->dev, "get stream info returned null\n"); + return -EINVAL; + } + + pipe_id = str_params->device_type; + task_id = str_params->task; + sst_drv_ctx->streams[str_id].pipe_id = pipe_id; + sst_drv_ctx->streams[str_id].task_id = task_id; + sst_drv_ctx->streams[str_id].num_ch = num_ch; + + if (sst_drv_ctx->info.lpe_viewpt_rqd) + alloc_param.ts = sst_drv_ctx->info.mailbox_start + + sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp)); + else + alloc_param.ts = sst_drv_ctx->mailbox_add + + sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp)); + + dev_dbg(sst_drv_ctx->dev, "alloc tstamp location = 0x%x\n", + alloc_param.ts); + dev_dbg(sst_drv_ctx->dev, "assigned pipe id 0x%x to task %d\n", + pipe_id, task_id); + + /* allocate device type context */ + sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type, + str_id, alloc_param.operation, 0); + + dev_info(sst_drv_ctx->dev, "Alloc for str %d pipe %#x\n", + str_id, pipe_id); + ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD, + IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param), + &alloc_param, data, true, true, false, true); + + if (ret < 0) { + dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret); + /* alloc failed, so reset the state to uninit */ + str_info->status = STREAM_UN_INIT; + str_id = ret; + } else if (data) { + response = (struct snd_sst_alloc_response *)data; + ret = response->str_type.result; + if (!ret) + goto out; + dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret); + if (ret == SST_ERR_STREAM_IN_USE) { + dev_err(sst_drv_ctx->dev, + "FW not in clean state, send free for:%d\n", str_id); + sst_free_stream(sst_drv_ctx, str_id); + } + str_id = -ret; + } +out: + kfree(data); + return str_id; +} + +/** +* sst_start_stream - Send msg for a starting stream +* @str_id: stream ID +* +* This function is called by any function which wants to start +* a stream. +*/ +int sst_start_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + int retval = 0; + struct stream_info *str_info; + u16 data = 0; + + dev_dbg(sst_drv_ctx->dev, "sst_start_stream for %d\n", str_id); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + if (str_info->status != STREAM_RUNNING) + return -EBADRQC; + + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, + IPC_CMD, IPC_IA_START_STREAM_MRFLD, str_info->pipe_id, + sizeof(u16), &data, NULL, true, true, true, false); + + return retval; +} + +int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, + struct snd_sst_bytes_v2 *bytes) +{ struct ipc_post *msg = NULL; + u32 length; + int pvt_id, ret = 0; + struct sst_block *block = NULL; + + dev_dbg(sst_drv_ctx->dev, + "type:%u ipc_msg:%u block:%u task_id:%u pipe: %#x length:%#x\n", + bytes->type, bytes->ipc_msg, bytes->block, bytes->task_id, + bytes->pipe_id, bytes->len); + + if (sst_create_ipc_msg(&msg, true)) + return -ENOMEM; + + pvt_id = sst_assign_pvt_id(sst_drv_ctx); + sst_fill_header_mrfld(&msg->mrfld_header, bytes->ipc_msg, + bytes->task_id, 1, pvt_id); + msg->mrfld_header.p.header_high.part.res_rqd = bytes->block; + length = bytes->len; + msg->mrfld_header.p.header_low_payload = length; + dev_dbg(sst_drv_ctx->dev, "length is %d\n", length); + memcpy(msg->mailbox_data, &bytes->bytes, bytes->len); + if (bytes->block) { + block = sst_create_block(sst_drv_ctx, bytes->ipc_msg, pvt_id); + if (block == NULL) { + kfree(msg); + ret = -ENOMEM; + goto out; + } + } + + sst_add_to_dispatch_list_and_post(sst_drv_ctx, msg); + dev_dbg(sst_drv_ctx->dev, "msg->mrfld_header.p.header_low_payload:%d", + msg->mrfld_header.p.header_low_payload); + + if (bytes->block) { + ret = sst_wait_timeout(sst_drv_ctx, block); + if (ret) { + dev_err(sst_drv_ctx->dev, "fw returned err %d\n", ret); + sst_free_block(sst_drv_ctx, block); + goto out; + } + } + if (bytes->type == SND_SST_BYTES_GET) { + /* + * copy the reply and send back + * we need to update only sz and payload + */ + if (bytes->block) { + unsigned char *r = block->data; + + dev_dbg(sst_drv_ctx->dev, "read back %d bytes", + bytes->len); + memcpy(bytes->bytes, r, bytes->len); + } + } + if (bytes->block) + sst_free_block(sst_drv_ctx, block); +out: + test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id); + return 0; +} + +/* + * sst_pause_stream - Send msg for a pausing stream + * @str_id: stream ID + * + * This function is called by any function which wants to pause + * an already running stream. + */ +int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + int retval = 0; + struct stream_info *str_info; + + dev_dbg(sst_drv_ctx->dev, "SST DBG:sst_pause_stream for %d\n", str_id); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + if (str_info->status == STREAM_PAUSED) + return 0; + if (str_info->status == STREAM_RUNNING || + str_info->status == STREAM_INIT) { + if (str_info->prev == STREAM_UN_INIT) + return -EBADRQC; + + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD, + IPC_IA_PAUSE_STREAM_MRFLD, str_info->pipe_id, + 0, NULL, NULL, true, true, false, true); + + if (retval == 0) { + str_info->prev = str_info->status; + str_info->status = STREAM_PAUSED; + } else if (retval == SST_ERR_INVALID_STREAM_ID) { + retval = -EINVAL; + mutex_lock(&sst_drv_ctx->sst_lock); + sst_clean_stream(str_info); + mutex_unlock(&sst_drv_ctx->sst_lock); + } + } else { + retval = -EBADRQC; + dev_dbg(sst_drv_ctx->dev, "SST DBG:BADRQC for stream\n "); + } + + return retval; +} + +/** + * sst_resume_stream - Send msg for resuming stream + * @str_id: stream ID + * + * This function is called by any function which wants to resume + * an already paused stream. + */ +int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + int retval = 0; + struct stream_info *str_info; + + dev_dbg(sst_drv_ctx->dev, "SST DBG:sst_resume_stream for %d\n", str_id); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + if (str_info->status == STREAM_RUNNING) + return 0; + if (str_info->status == STREAM_PAUSED) { + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, + IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD, + str_info->pipe_id, 0, NULL, NULL, + true, true, false, true); + + if (!retval) { + if (str_info->prev == STREAM_RUNNING) + str_info->status = STREAM_RUNNING; + else + str_info->status = STREAM_INIT; + str_info->prev = STREAM_PAUSED; + } else if (retval == -SST_ERR_INVALID_STREAM_ID) { + retval = -EINVAL; + mutex_lock(&sst_drv_ctx->sst_lock); + sst_clean_stream(str_info); + mutex_unlock(&sst_drv_ctx->sst_lock); + } + } else { + retval = -EBADRQC; + dev_err(sst_drv_ctx->dev, "SST ERR: BADQRC for stream\n"); + } + + return retval; +} + + +/** + * sst_drop_stream - Send msg for stopping stream + * @str_id: stream ID + * + * This function is called by any function which wants to stop + * a stream. + */ +int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + int retval = 0; + struct stream_info *str_info; + + dev_dbg(sst_drv_ctx->dev, "SST DBG:sst_drop_stream for %d\n", str_id); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + + if (str_info->status != STREAM_UN_INIT) { + str_info->prev = STREAM_UN_INIT; + str_info->status = STREAM_INIT; + str_info->cumm_bytes = 0; + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, + IPC_CMD, IPC_IA_DROP_STREAM_MRFLD, + str_info->pipe_id, 0, NULL, NULL, + true, true, true, false); + } else { + retval = -EBADRQC; + dev_dbg(sst_drv_ctx->dev, "BADQRC for stream, state %x\n", + str_info->status); + } + return retval; +} + +/** +* sst_drain_stream - Send msg for draining stream +* @str_id: stream ID +* +* This function is called by any function which wants to drain +* a stream. +*/ +int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx, + int str_id, bool partial_drain) +{ + int retval = 0; + struct stream_info *str_info; + + dev_dbg(sst_drv_ctx->dev, "SST DBG:sst_drain_stream for %d\n", str_id); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + if (str_info->status != STREAM_RUNNING && + str_info->status != STREAM_INIT && + str_info->status != STREAM_PAUSED) { + dev_err(sst_drv_ctx->dev, "SST ERR: BADQRC for stream = %d\n", + str_info->status); + return -EBADRQC; + } + + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD, + IPC_IA_DRAIN_STREAM_MRFLD, str_info->pipe_id, + sizeof(u8), &partial_drain, NULL, true, true, false, false); + /* + * with new non blocked drain implementation in core we dont need to + * wait for respsonse, and need to only invoke callback for drain + * complete + */ + + return retval; +} + +/** + * sst_free_stream - Frees a stream + * @str_id: stream ID + * + * This function is called by any function which wants to free + * a stream. + */ +int sst_free_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + int retval = 0; + struct stream_info *str_info; + struct intel_sst_ops *ops; + + dev_dbg(sst_drv_ctx->dev, "SST DBG:sst_free_stream for %d\n", str_id); + + mutex_lock(&sst_drv_ctx->sst_lock); + if (sst_drv_ctx->sst_state == SST_RESET) { + mutex_unlock(&sst_drv_ctx->sst_lock); + return -ENODEV; + } + mutex_unlock(&sst_drv_ctx->sst_lock); + str_info = get_stream_info(sst_drv_ctx, str_id); + if (!str_info) + return -EINVAL; + ops = sst_drv_ctx->ops; + + mutex_lock(&str_info->lock); + if (str_info->status != STREAM_UN_INIT) { + str_info->prev = str_info->status; + str_info->status = STREAM_UN_INIT; + mutex_unlock(&str_info->lock); + + dev_info(sst_drv_ctx->dev, "Free for str %d pipe %#x\n", + str_id, str_info->pipe_id); + retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD, + IPC_IA_FREE_STREAM_MRFLD, str_info->pipe_id, 0, + NULL, NULL, true, true, false, true); + + dev_dbg(sst_drv_ctx->dev, "sst: wait for free returned %d\n", + retval); + mutex_lock(&sst_drv_ctx->sst_lock); + sst_clean_stream(str_info); + mutex_unlock(&sst_drv_ctx->sst_lock); + dev_dbg(sst_drv_ctx->dev, "SST DBG:Stream freed\n"); + } else { + mutex_unlock(&str_info->lock); + retval = -EBADRQC; + dev_dbg(sst_drv_ctx->dev, "SST DBG:BADQRC for stream\n"); + } + + return retval; +} -- GitLab From 60dc8dbacb001b6400624ee72990b85d6d44bce6 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:18 +0530 Subject: [PATCH 0573/9457] ASoC: Intel: sst: Add some helper functions This patch adds helper functions like wait, creating ipc headers, shim wrappers. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_pvt.c | 446 ++++++++++++++++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 sound/soc/intel/sst/sst_pvt.c diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/sst/sst_pvt.c new file mode 100644 index 000000000000..9e5f69b6b395 --- /dev/null +++ b/sound/soc/intel/sst/sst_pvt.c @@ -0,0 +1,446 @@ +/* + * sst_pvt.c - Intel SST Driver for audio engine + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul + * Harsha Priya + * Dharageswari R + * KP Jeeja + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "sst.h" +#include "../sst-dsp.h" + +int sst_shim_write(void __iomem *addr, int offset, int value) +{ + writel(value, addr + offset); + return 0; +} + +u32 sst_shim_read(void __iomem *addr, int offset) +{ + return readl(addr + offset); +} + +u64 sst_reg_read64(void __iomem *addr, int offset) +{ + u64 val = 0; + + memcpy_fromio(&val, addr + offset, sizeof(val)); + + return val; +} + +int sst_shim_write64(void __iomem *addr, int offset, u64 value) +{ + memcpy_toio(addr + offset, &value, sizeof(value)); + return 0; +} + +u64 sst_shim_read64(void __iomem *addr, int offset) +{ + u64 val = 0; + + memcpy_fromio(&val, addr + offset, sizeof(val)); + return val; +} + +void sst_set_fw_state_locked( + struct intel_sst_drv *sst_drv_ctx, int sst_state) +{ + mutex_lock(&sst_drv_ctx->sst_lock); + sst_drv_ctx->sst_state = sst_state; + mutex_unlock(&sst_drv_ctx->sst_lock); +} + +/* + * sst_wait_interruptible - wait on event + * + * @sst_drv_ctx: Driver context + * @block: Driver block to wait on + * + * This function waits without a timeout (and is interruptable) for a + * given block event + */ +int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx, + struct sst_block *block) +{ + int retval = 0; + + if (!wait_event_interruptible(sst_drv_ctx->wait_queue, + block->condition)) { + /* event wake */ + if (block->ret_code < 0) { + dev_err(sst_drv_ctx->dev, + "stream failed %d\n", block->ret_code); + retval = -EBUSY; + } else { + dev_dbg(sst_drv_ctx->dev, "event up\n"); + retval = 0; + } + } else { + dev_err(sst_drv_ctx->dev, "signal interrupted\n"); + retval = -EINTR; + } + return retval; + +} + +unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr) +{ + unsigned long long val = 0; + + switch (sst->pci_id) { + case SST_MRFLD_PCI_ID: + val = sst_shim_read64(sst->shim, addr); + break; + } + return val; +} + +void write_shim_data(struct intel_sst_drv *sst, int addr, + unsigned long long data) +{ + switch (sst->pci_id) { + case SST_MRFLD_PCI_ID: + sst_shim_write64(sst->shim, addr, (u64) data); + break; + } +} + +/* + * sst_wait_timeout - wait on event for timeout + * + * @sst_drv_ctx: Driver context + * @block: Driver block to wait on + * + * This function waits with a timeout value (and is not interruptible) on a + * given block event + */ +int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx, struct sst_block *block) +{ + int retval = 0; + + /* + * NOTE: + * Observed that FW processes the alloc msg and replies even + * before the alloc thread has finished execution + */ + dev_dbg(sst_drv_ctx->dev, + "waiting for condition %x ipc %d drv_id %d\n", + block->condition, block->msg_id, block->drv_id); + if (wait_event_timeout(sst_drv_ctx->wait_queue, + block->condition, + msecs_to_jiffies(SST_BLOCK_TIMEOUT))) { + /* event wake */ + dev_dbg(sst_drv_ctx->dev, "Event wake %x\n", + block->condition); + dev_dbg(sst_drv_ctx->dev, "message ret: %d\n", + block->ret_code); + retval = -block->ret_code; + } else { + block->on = false; + dev_err(sst_drv_ctx->dev, + "Wait timed-out condition:%#x, msg_id:%#x fw_state %#x\n", + block->condition, block->msg_id, sst_drv_ctx->sst_state); + sst_drv_ctx->sst_state = SST_RESET; + + retval = -EBUSY; + } + return retval; +} + +/* + * sst_create_ipc_msg - create a IPC message + * + * @arg: ipc message + * @large: large or short message + * + * this function allocates structures to send a large or short + * message to the firmware + */ +int sst_create_ipc_msg(struct ipc_post **arg, bool large) +{ + struct ipc_post *msg; + + msg = kzalloc(sizeof(struct ipc_post), GFP_ATOMIC); + if (!msg) + return -ENOMEM; + if (large) { + msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_ATOMIC); + if (!msg->mailbox_data) { + kfree(msg); + return -ENOMEM; + } + } else { + msg->mailbox_data = NULL; + } + msg->is_large = large; + *arg = msg; + return 0; +} + +/* + * sst_create_block_and_ipc_msg - Creates IPC message and sst block + * @arg: passed to sst_create_ipc_message API + * @large: large or short message + * @sst_drv_ctx: sst driver context + * @block: return block allocated + * @msg_id: IPC + * @drv_id: stream id or private id + */ +int sst_create_block_and_ipc_msg(struct ipc_post **arg, bool large, + struct intel_sst_drv *sst_drv_ctx, struct sst_block **block, + u32 msg_id, u32 drv_id) +{ + int retval = 0; + + retval = sst_create_ipc_msg(arg, large); + if (retval) + return retval; + *block = sst_create_block(sst_drv_ctx, msg_id, drv_id); + if (*block == NULL) { + kfree(*arg); + return -ENOMEM; + } + return retval; +} + +/* + * sst_clean_stream - clean the stream context + * + * @stream: stream structure + * + * this function resets the stream contexts + * should be called in free + */ +void sst_clean_stream(struct stream_info *stream) +{ + stream->status = STREAM_UN_INIT; + stream->prev = STREAM_UN_INIT; + mutex_lock(&stream->lock); + stream->cumm_bytes = 0; + mutex_unlock(&stream->lock); +} + +int sst_prepare_and_post_msg(struct intel_sst_drv *sst, + int task_id, int ipc_msg, int cmd_id, int pipe_id, + size_t mbox_data_len, const void *mbox_data, void **data, + bool large, bool fill_dsp, bool sync, bool response) +{ + struct ipc_post *msg = NULL; + struct ipc_dsp_hdr dsp_hdr; + struct sst_block *block; + int ret = 0, pvt_id; + + pvt_id = sst_assign_pvt_id(sst); + if (pvt_id < 0) + return pvt_id; + + if (response) + ret = sst_create_block_and_ipc_msg( + &msg, large, sst, &block, ipc_msg, pvt_id); + else + ret = sst_create_ipc_msg(&msg, large); + + if (ret < 0) { + test_and_clear_bit(pvt_id, &sst->pvt_id); + return -ENOMEM; + } + + dev_dbg(sst->dev, "pvt_id = %d, pipe id = %d, task = %d ipc_msg: %d\n", + pvt_id, pipe_id, task_id, ipc_msg); + sst_fill_header_mrfld(&msg->mrfld_header, ipc_msg, + task_id, large, pvt_id); + msg->mrfld_header.p.header_low_payload = sizeof(dsp_hdr) + mbox_data_len; + msg->mrfld_header.p.header_high.part.res_rqd = !sync; + dev_dbg(sst->dev, "header:%x\n", + msg->mrfld_header.p.header_high.full); + dev_dbg(sst->dev, "response rqd: %x", + msg->mrfld_header.p.header_high.part.res_rqd); + dev_dbg(sst->dev, "msg->mrfld_header.p.header_low_payload:%d", + msg->mrfld_header.p.header_low_payload); + if (fill_dsp) { + sst_fill_header_dsp(&dsp_hdr, cmd_id, pipe_id, mbox_data_len); + memcpy(msg->mailbox_data, &dsp_hdr, sizeof(dsp_hdr)); + if (mbox_data_len) { + memcpy(msg->mailbox_data + sizeof(dsp_hdr), + mbox_data, mbox_data_len); + } + } + + if (sync) + sst->ops->post_message(sst, msg, true); + else + sst_add_to_dispatch_list_and_post(sst, msg); + + if (response) { + ret = sst_wait_timeout(sst, block); + if (ret < 0) { + goto out; + } else if(block->data) { + if (!data) + goto out; + *data = kzalloc(block->size, GFP_KERNEL); + if (!(*data)) { + ret = -ENOMEM; + goto out; + } else + memcpy(data, (void *) block->data, block->size); + } + } +out: + if (response) + sst_free_block(sst, block); + test_and_clear_bit(pvt_id, &sst->pvt_id); + return ret; +} + +int sst_pm_runtime_put(struct intel_sst_drv *sst_drv) +{ + int ret; + + pm_runtime_mark_last_busy(sst_drv->dev); + ret = pm_runtime_put_autosuspend(sst_drv->dev); + if (ret < 0) + return ret; + return 0; +} + +void sst_fill_header_mrfld(union ipc_header_mrfld *header, + int msg, int task_id, int large, int drv_id) +{ + header->full = 0; + header->p.header_high.part.msg_id = msg; + header->p.header_high.part.task_id = task_id; + header->p.header_high.part.large = large; + header->p.header_high.part.drv_id = drv_id; + header->p.header_high.part.done = 0; + header->p.header_high.part.busy = 1; + header->p.header_high.part.res_rqd = 1; +} + +void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg, + int pipe_id, int len) +{ + dsp->cmd_id = msg; + dsp->mod_index_id = 0xff; + dsp->pipe_id = pipe_id; + dsp->length = len; + dsp->mod_id = 0; +} + +#define SST_MAX_BLOCKS 15 +/* + * sst_assign_pvt_id - assign a pvt id for stream + * + * @sst_drv_ctx : driver context + * + * this function assigns a private id for calls that dont have stream + * context yet, should be called with lock held + * uses bits for the id, and finds first free bits and assigns that + */ +int sst_assign_pvt_id(struct intel_sst_drv *drv) +{ + int local; + + spin_lock(&drv->block_lock); + /* find first zero index from lsb */ + local = ffz(drv->pvt_id); + dev_dbg(drv->dev, "pvt_id assigned --> %d\n", local); + if (local >= SST_MAX_BLOCKS){ + spin_unlock(&drv->block_lock); + dev_err(drv->dev, "PVT _ID error: no free id blocks "); + return -EINVAL; + } + /* toggle the index */ + change_bit(local, &drv->pvt_id); + spin_unlock(&drv->block_lock); + return local; +} + +void sst_init_stream(struct stream_info *stream, + int codec, int sst_id, int ops, u8 slot) +{ + stream->status = STREAM_INIT; + stream->prev = STREAM_UN_INIT; + stream->ops = ops; +} + +int sst_validate_strid( + struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + if (str_id <= 0 || str_id > sst_drv_ctx->info.max_streams) { + dev_err(sst_drv_ctx->dev, + "SST ERR: invalid stream id : %d, max %d\n", + str_id, sst_drv_ctx->info.max_streams); + return -EINVAL; + } + + return 0; +} + +struct stream_info *get_stream_info( + struct intel_sst_drv *sst_drv_ctx, int str_id) +{ + if (sst_validate_strid(sst_drv_ctx, str_id)) + return NULL; + return &sst_drv_ctx->streams[str_id]; +} + +int get_stream_id_mrfld(struct intel_sst_drv *sst_drv_ctx, + u32 pipe_id) +{ + int i; + + for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) + if (pipe_id == sst_drv_ctx->streams[i].pipe_id) + return i; + + dev_dbg(sst_drv_ctx->dev, "no such pipe_id(%u)", pipe_id); + return -1; +} + +u32 relocate_imr_addr_mrfld(u32 base_addr) +{ + /* Get the difference from 512MB aligned base addr */ + /* relocate the base */ + base_addr = MRFLD_FW_VIRTUAL_BASE + (base_addr % (512 * 1024 * 1024)); + return base_addr; +} + +void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst, + struct ipc_post *msg) +{ + unsigned long irq_flags; + + spin_lock_irqsave(&sst->ipc_spin_lock, irq_flags); + list_add_tail(&msg->node, &sst->ipc_dispatch_list); + spin_unlock_irqrestore(&sst->ipc_spin_lock, irq_flags); + sst->ops->post_message(sst, NULL, false); +} -- GitLab From 0fbc7d7320202489383f520ecd1758b15a00e17c Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 16 Oct 2014 20:00:19 +0530 Subject: [PATCH 0574/9457] ASoC: Intel: sst: Add makefile and kconfig changes Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 4 ++++ sound/soc/intel/Makefile | 3 +++ sound/soc/intel/sst/Makefile | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 sound/soc/intel/sst/Makefile diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index f5b4a9c79cdf..c719438fa3d7 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -3,6 +3,7 @@ config SND_MFLD_MACHINE depends on INTEL_SCU_IPC select SND_SOC_SN95031 select SND_SST_MFLD_PLATFORM + select SND_SST_IPC help This adds support for ASoC machine driver for Intel(R) MID Medfield platform used as alsa device in audio substem in Intel(R) MID devices @@ -12,6 +13,9 @@ config SND_MFLD_MACHINE config SND_SST_MFLD_PLATFORM tristate +config SND_SST_IPC + tristate + config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index f841786dad15..9ab43be75311 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -31,3 +31,6 @@ obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o + +# DSP driver +obj-$(CONFIG_SND_SST_IPC) += sst/ diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/sst/Makefile new file mode 100644 index 000000000000..4d0e79b1f8ce --- /dev/null +++ b/sound/soc/intel/sst/Makefile @@ -0,0 +1,3 @@ +snd-intel-sst-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o + +obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst.o -- GitLab From 282a331fe25c74c23800bb7da1bb62c9e54fd738 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Thu, 16 Oct 2014 18:22:01 -0700 Subject: [PATCH 0575/9457] ASoC: Intel: Add new dependency for Broadwell machine I2C support for the RT286 codec is provided through the Designware I2C platform adapter in this machine. Thus, the adapter driver must be present. Signed-off-by: Ricardo Neri Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index c719438fa3d7..774fab988509 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -65,7 +65,8 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH config SND_SOC_INTEL_BROADWELL_MACH tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" - depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC + depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\ + I2C_DESIGNWARE_PLATFORM select SND_SOC_INTEL_HASWELL select SND_COMPRESS_OFFLOAD select SND_SOC_RT286 -- GitLab From 161aa49ef1b99891b82d3599885eb8d5cbf0ebfc Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Thu, 16 Oct 2014 18:22:02 -0700 Subject: [PATCH 0576/9457] ASoC: Intel: Add new dependency for Haswell machine I2C support for the RT5640 codec is provided through the Designware I2C platform adapter in this machine. Thus, the driver must be present. Signed-off-by: Ricardo Neri Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 774fab988509..2a3af880868b 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -36,7 +36,8 @@ config SND_SOC_INTEL_BAYTRAIL config SND_SOC_INTEL_HASWELL_MACH tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" - depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C + depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\ + I2C_DESIGNWARE_PLATFORM select SND_SOC_INTEL_HASWELL select SND_SOC_RT5640 help -- GitLab From cd6e82b814ca73c474b1a2fa48a54b251da44655 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Tue, 7 Oct 2014 10:25:37 +0800 Subject: [PATCH 0577/9457] ASoC: rt5645: Add the workqueue of the jack detect function for the debouncing Add the workqueue of the jack detect function for the debouncing. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 15 ++++++++++++++- sound/soc/codecs/rt5645.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 3fb83bf09768..57ba74292259 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2166,11 +2166,20 @@ int rt5645_set_jack_detect(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(rt5645_set_jack_detect); +static void rt5645_jack_detect_work(struct work_struct *work) +{ + struct rt5645_priv *rt5645 = + container_of(work, struct rt5645_priv, jack_detect_work.work); + + rt5645_jack_detect(rt5645->codec, rt5645->jack); +} + static irqreturn_t rt5645_irq(int irq, void *data) { struct rt5645_priv *rt5645 = data; - rt5645_jack_detect(rt5645->codec, rt5645->jack); + queue_delayed_work(system_power_efficient_wq, + &rt5645->jack_detect_work, msecs_to_jiffies(250)); return IRQ_HANDLED; } @@ -2436,6 +2445,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, dev_err(&i2c->dev, "Fail gpio_direction hp_det_gpio\n"); } + INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); + return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, rt5645_dai, ARRAY_SIZE(rt5645_dai)); } @@ -2447,6 +2458,8 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) if (i2c->irq) free_irq(i2c->irq, rt5645); + cancel_delayed_work_sync(&rt5645->jack_detect_work); + if (gpio_is_valid(rt5645->pdata.hp_det_gpio)) gpio_free(rt5645->pdata.hp_det_gpio); diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 50c62c5668ea..5ec2520614d2 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2168,6 +2168,7 @@ struct rt5645_priv { struct regmap *regmap; struct i2c_client *i2c; struct snd_soc_jack *jack; + struct delayed_work jack_detect_work; int sysclk; int sysclk_src; -- GitLab From 80fff6bf65dcae62255bdb592603dfc247c8cacf Mon Sep 17 00:00:00 2001 From: Ben Zhang Date: Fri, 3 Oct 2014 14:37:24 -0700 Subject: [PATCH 0578/9457] ASoC: rt5677: Include gpio driver header The header file is needed because struct gpio_chip is placed in struct rt5677_priv. Signed-off-by: Ben Zhang Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index d4eb6d5e6746..99fd023e3290 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -13,6 +13,7 @@ #define __RT5677_H__ #include +#include /* Info */ #define RT5677_RESET 0x00 -- GitLab From 40eb90a18e93fbd4fd0e6892b31241356c3c8e43 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Fri, 10 Oct 2014 20:46:36 -0700 Subject: [PATCH 0579/9457] ASoC: rt5677: Add option to configure gpio as floating/pullup/pulldown gpio_config is array of 6 elements that allows to set GPIO as floating, pullup, pulldown. Sponsored: Google ChromeOS Signed-off-by: Anatol Pomozov Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/rt5677.txt | 7 ++++ include/sound/rt5677.h | 3 ++ sound/soc/codecs/rt5677.c | 39 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt b/Documentation/devicetree/bindings/sound/rt5677.txt index 0701b834fc73..f82f0e906cd9 100644 --- a/Documentation/devicetree/bindings/sound/rt5677.txt +++ b/Documentation/devicetree/bindings/sound/rt5677.txt @@ -27,6 +27,12 @@ Optional properties: Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential, rather than single-ended. +- realtek,gpio-config + Array of six 8bit elements that configures GPIO. + 0 - floating (reset value) + 1 - pull down + 2 - pull up + Pins on the device (for linking into audio routes): * IN1P @@ -56,4 +62,5 @@ rt5677 { realtek,pow-ldo2-gpio = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,in1-differential = "true"; + realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */ }; diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h index 082670e3a353..a56b429a1dbc 100644 --- a/include/sound/rt5677.h +++ b/include/sound/rt5677.h @@ -27,6 +27,9 @@ struct rt5677_platform_data { bool lout3_diff; /* DMIC2 clock source selection */ enum rt5677_dmic2_clk dmic2_clk_pin; + + /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ + u8 gpio_config[6]; }; #endif diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 16aa4d99a713..a454df39b7a5 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -3309,6 +3309,38 @@ static int rt5677_gpio_direction_in(struct gpio_chip *chip, unsigned offset) return 0; } +/** Configures the gpio as + * 0 - floating + * 1 - pull down + * 2 - pull up + */ +static void rt5677_gpio_config(struct rt5677_priv *rt5677, unsigned offset, + int value) +{ + int shift; + + switch (offset) { + case RT5677_GPIO1 ... RT5677_GPIO2: + shift = 2 * (1 - offset); + regmap_update_bits(rt5677->regmap, + RT5677_PR_BASE + RT5677_DIG_IN_PIN_ST_CTRL2, + 0x3 << shift, + (value & 0x3) << shift); + break; + + case RT5677_GPIO3 ... RT5677_GPIO6: + shift = 2 * (9 - offset); + regmap_update_bits(rt5677->regmap, + RT5677_PR_BASE + RT5677_DIG_IN_PIN_ST_CTRL3, + 0x3 << shift, + (value & 0x3) << shift); + break; + + default: + break; + } +} + static struct gpio_chip rt5677_template_chip = { .label = "rt5677", .owner = THIS_MODULE, @@ -3353,6 +3385,7 @@ static void rt5677_free_gpio(struct i2c_client *i2c) static int rt5677_probe(struct snd_soc_codec *codec) { struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + int i; rt5677->codec = codec; @@ -3371,6 +3404,9 @@ static int rt5677_probe(struct snd_soc_codec *codec) regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020); regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00); + for (i = 0; i < RT5677_GPIO_NUM; i++) + rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); + return 0; } @@ -3590,6 +3626,9 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) (rt5677->pow_ldo2 != -ENOENT)) return rt5677->pow_ldo2; + of_property_read_u8_array(np, "realtek,gpio-config", + rt5677->pdata.gpio_config, RT5677_GPIO_NUM); + return 0; } -- GitLab From af48f1d08a5474184da9aaf8b77f4a2848b1875e Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Mon, 6 Oct 2014 16:30:51 +0800 Subject: [PATCH 0580/9457] ASoC: rt5677: Support DSP function for VAD application The ALC5677 has a programmable DSP, and there is a SPI that is dadicated for DSP firmware loading. Therefore, the patch includes a SPI driver for writing the DSP firmware. The VAD(Voice Activaty Detection) has be implemented and use the DSP to recognize the key phase. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/Makefile | 2 +- sound/soc/codecs/rt5677-spi.c | 128 +++++++++++++++ sound/soc/codecs/rt5677-spi.h | 21 +++ sound/soc/codecs/rt5677.c | 288 +++++++++++++++++++++++++++++++++- sound/soc/codecs/rt5677.h | 6 + 5 files changed, 440 insertions(+), 5 deletions(-) create mode 100644 sound/soc/codecs/rt5677-spi.c create mode 100644 sound/soc/codecs/rt5677-spi.h diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 5dce451661e4..4435f9f18ce8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -79,7 +79,7 @@ snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o snd-soc-rt5651-objs := rt5651.o snd-soc-rt5670-objs := rt5670.o -snd-soc-rt5677-objs := rt5677.o +snd-soc-rt5677-objs := rt5677.o rt5677-spi.o snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c new file mode 100644 index 000000000000..11c38f3a9b72 --- /dev/null +++ b/sound/soc/codecs/rt5677-spi.c @@ -0,0 +1,128 @@ +/* + * rt5677-spi.c -- RT5677 ALSA SoC audio codec driver + * + * Copyright 2013 Realtek Semiconductor Corp. + * Author: Oder Chiou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rt5677-spi.h" + +static struct spi_device *g_spi; + +/** + * rt5677_spi_write - Write data to SPI. + * @txbuf: Data Buffer for writing. + * @len: Data length. + * + * + * Returns true for success. + */ +int rt5677_spi_write(u8 *txbuf, size_t len) +{ + int status; + + status = spi_write(g_spi, txbuf, len); + + if (status) + dev_err(&g_spi->dev, "rt5677_spi_write error %d\n", status); + + return status; +} + +/** + * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address. + * @addr: Start address. + * @txbuf: Data Buffer for writng. + * @len: Data length, it must be a multiple of 8. + * + * + * Returns true for success. + */ +int rt5677_spi_burst_write(u32 addr, const struct firmware *fw) +{ + u8 spi_cmd = RT5677_SPI_CMD_BURST_WRITE; + u8 *write_buf; + unsigned int i, end, offset = 0; + + write_buf = kmalloc(RT5677_SPI_BUF_LEN + 6, GFP_KERNEL); + + if (write_buf == NULL) + return -ENOMEM; + + while (offset < fw->size) { + if (offset + RT5677_SPI_BUF_LEN <= fw->size) + end = RT5677_SPI_BUF_LEN; + else + end = fw->size % RT5677_SPI_BUF_LEN; + + write_buf[0] = spi_cmd; + write_buf[1] = ((addr + offset) & 0xff000000) >> 24; + write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16; + write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8; + write_buf[4] = ((addr + offset) & 0x000000ff) >> 0; + + for (i = 0; i < end; i += 8) { + write_buf[i + 12] = fw->data[offset + i + 0]; + write_buf[i + 11] = fw->data[offset + i + 1]; + write_buf[i + 10] = fw->data[offset + i + 2]; + write_buf[i + 9] = fw->data[offset + i + 3]; + write_buf[i + 8] = fw->data[offset + i + 4]; + write_buf[i + 7] = fw->data[offset + i + 5]; + write_buf[i + 6] = fw->data[offset + i + 6]; + write_buf[i + 5] = fw->data[offset + i + 7]; + } + + write_buf[end + 5] = spi_cmd; + + rt5677_spi_write(write_buf, end + 6); + + offset += RT5677_SPI_BUF_LEN; + } + + kfree(write_buf); + + return 0; +} + +static int rt5677_spi_probe(struct spi_device *spi) +{ + g_spi = spi; + return 0; +} + +static struct spi_driver rt5677_spi_driver = { + .driver = { + .name = "rt5677", + .owner = THIS_MODULE, + }, + .probe = rt5677_spi_probe, +}; +module_spi_driver(rt5677_spi_driver); + +MODULE_DESCRIPTION("ASoC RT5677 SPI driver"); +MODULE_AUTHOR("Oder Chiou "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rt5677-spi.h b/sound/soc/codecs/rt5677-spi.h new file mode 100644 index 000000000000..7528bfd0b596 --- /dev/null +++ b/sound/soc/codecs/rt5677-spi.h @@ -0,0 +1,21 @@ +/* + * rt5677-spi.h -- RT5677 ALSA SoC audio codec driver + * + * Copyright 2013 Realtek Semiconductor Corp. + * Author: Oder Chiou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __RT5671_SPI_H__ +#define __RT5671_SPI_H__ + +#define RT5677_SPI_BUF_LEN 240 +#define RT5677_SPI_CMD_BURST_WRITE 0x05 + +int rt5677_spi_write(u8 *txbuf, size_t len); +int rt5677_spi_burst_write(u32 addr, const struct firmware *fw); + +#endif /* __RT5677_SPI_H__ */ diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index a454df39b7a5..e6e54fa648aa 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include "rl6231.h" #include "rt5677.h" +#include "rt5677-spi.h" #define RT5677_DEVICE_ID 0x6327 @@ -537,6 +539,243 @@ static bool rt5677_readable_register(struct device *dev, unsigned int reg) } } +/** + * rt5677_dsp_mode_i2c_write_addr - Write value to address on DSP mode. + * @codec: SoC audio codec device. + * @addr: Address index. + * @value: Address data. + * + * + * Returns 0 for success or negative error code. + */ +static int rt5677_dsp_mode_i2c_write_addr(struct snd_soc_codec *codec, + unsigned int addr, unsigned int value, unsigned int opcode) +{ + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + int ret; + + mutex_lock(&rt5677->dsp_cmd_lock); + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16); + if (ret < 0) { + dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB, + addr & 0xffff); + if (ret < 0) { + dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB, + value >> 16); + if (ret < 0) { + dev_err(codec->dev, "Failed to set data msb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB, + value & 0xffff); + if (ret < 0) { + dev_err(codec->dev, "Failed to set data lsb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE, opcode); + if (ret < 0) { + dev_err(codec->dev, "Failed to set op code value: %d\n", ret); + goto err; + } + +err: + mutex_unlock(&rt5677->dsp_cmd_lock); + + return ret; +} + +/** + * rt5677_dsp_mode_i2c_read_addr - Read value from address on DSP mode. + * @codec: SoC audio codec device. + * @addr: Address index. + * @value: Address data. + * + * Returns 0 for success or negative error code. + */ +static int rt5677_dsp_mode_i2c_read_addr( + struct snd_soc_codec *codec, unsigned int addr, unsigned int *value) +{ + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + int ret; + unsigned int msb, lsb; + + mutex_lock(&rt5677->dsp_cmd_lock); + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16); + if (ret < 0) { + dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB, + addr & 0xffff); + if (ret < 0) { + dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret); + goto err; + } + + ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE , 0x0002); + if (ret < 0) { + dev_err(codec->dev, "Failed to set op code value: %d\n", ret); + goto err; + } + + regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB, &msb); + regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB, &lsb); + *value = (msb << 16) | lsb; + +err: + mutex_unlock(&rt5677->dsp_cmd_lock); + + return ret; +} + +/** + * rt5677_dsp_mode_i2c_write - Write register on DSP mode. + * @codec: SoC audio codec device. + * @reg: Register index. + * @value: Register data. + * + * + * Returns 0 for success or negative error code. + */ +static int rt5677_dsp_mode_i2c_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + return rt5677_dsp_mode_i2c_write_addr(codec, 0x18020000 + reg * 2, + value, 0x0001); +} + +/** + * rt5677_dsp_mode_i2c_read - Read register on DSP mode. + * @codec: SoC audio codec device. + * @reg: Register index. + * + * + * Returns Register value. + */ +static unsigned int rt5677_dsp_mode_i2c_read( + struct snd_soc_codec *codec, unsigned int reg) +{ + unsigned int value = 0; + + rt5677_dsp_mode_i2c_read_addr(codec, 0x18020000 + reg * 2, &value); + + return value; +} + +/** + * rt5677_dsp_mode_i2c_update_bits - update register on DSP mode. + * @codec: audio codec + * @reg: register index. + * @mask: register mask + * @value: new value + * + * + * Returns 1 for change, 0 for no change, or negative error code. + */ +static int rt5677_dsp_mode_i2c_update_bits(struct snd_soc_codec *codec, + unsigned int reg, unsigned int mask, unsigned int value) +{ + unsigned int old, new; + int change, ret; + + ret = rt5677_dsp_mode_i2c_read(codec, reg); + if (ret < 0) { + dev_err(codec->dev, "Failed to read reg: %d\n", ret); + goto err; + } + + old = ret; + new = (old & ~mask) | (value & mask); + change = old != new; + if (change) { + ret = rt5677_dsp_mode_i2c_write(codec, reg, new); + if (ret < 0) { + dev_err(codec->dev, + "Failed to write reg: %d\n", ret); + goto err; + } + } + return change; + +err: + return ret; +} + +static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) +{ + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + static bool activity; + int ret; + + if (on && !activity) { + activity = true; + + regcache_cache_only(rt5677->regmap, false); + regcache_cache_bypass(rt5677->regmap, true); + + regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x1); + regmap_update_bits(rt5677->regmap, + RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0f00); + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, + RT5677_LDO1_SEL_MASK, 0x0); + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, + RT5677_PWR_LDO1, RT5677_PWR_LDO1); + regmap_write(rt5677->regmap, RT5677_GLB_CLK2, 0x0080); + regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff); + regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07ff); + + ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1, + codec->dev); + if (ret == 0) { + rt5677_spi_burst_write(0x50000000, rt5677->fw1); + release_firmware(rt5677->fw1); + } + + ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2, + codec->dev); + if (ret == 0) { + rt5677_spi_burst_write(0x60000000, rt5677->fw2); + release_firmware(rt5677->fw2); + } + + rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1, + 0x0); + + regcache_cache_bypass(rt5677->regmap, false); + regcache_cache_only(rt5677->regmap, true); + } else if (!on && activity) { + activity = false; + + regcache_cache_only(rt5677->regmap, false); + regcache_cache_bypass(rt5677->regmap, true); + + rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1, + 0x1); + rt5677_dsp_mode_i2c_write(codec, RT5677_PWR_DSP1, 0x0001); + + regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); + + regcache_cache_bypass(rt5677->regmap, false); + regcache_mark_dirty(rt5677->regmap); + regcache_sync(rt5677->regmap); + } + + return 0; +} + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); @@ -556,6 +795,31 @@ static unsigned int bst_tlv[] = { 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), }; +static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = rt5677->dsp_vad_en; + + return 0; +} + +static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + + rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0]; + + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) + rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en); + + return 0; +} + static const struct snd_kcontrol_new rt5677_snd_controls[] = { /* OUTPUT Control */ SOC_SINGLE("OUT1 Playback Switch", RT5677_LOUT1, @@ -627,6 +891,9 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = { SOC_DOUBLE_TLV("Mono ADC Boost Volume", RT5677_ADC_BST_CTRL2, RT5677_MONO_ADC_L_BST_SFT, RT5677_MONO_ADC_R_BST_SFT, 3, 0, adc_bst_tlv), + + SOC_SINGLE_EXT("DSP VAD Switch", SND_SOC_NOPM, 0, 1, 0, + rt5677_dsp_vad_get, rt5677_dsp_vad_put), }; /** @@ -3181,6 +3448,8 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + rt5677_set_dsp_vad(codec, false); + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, 0x0055); @@ -3214,6 +3483,9 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec, regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); regmap_update_bits(rt5677->regmap, RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); + + if (rt5677->dsp_vad_en) + rt5677_set_dsp_vad(codec, true); break; default: @@ -3407,6 +3679,8 @@ static int rt5677_probe(struct snd_soc_codec *codec) for (i = 0; i < RT5677_GPIO_NUM; i++) rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); + mutex_init(&rt5677->dsp_cmd_lock); + return 0; } @@ -3426,8 +3700,11 @@ static int rt5677_suspend(struct snd_soc_codec *codec) { struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); - regcache_cache_only(rt5677->regmap, true); - regcache_mark_dirty(rt5677->regmap); + if (!rt5677->dsp_vad_en) { + regcache_cache_only(rt5677->regmap, true); + regcache_mark_dirty(rt5677->regmap); + } + if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 0); @@ -3442,8 +3719,11 @@ static int rt5677_resume(struct snd_soc_codec *codec) gpio_set_value_cansleep(rt5677->pow_ldo2, 1); msleep(10); } - regcache_cache_only(rt5677->regmap, false); - regcache_sync(rt5677->regmap); + + if (!rt5677->dsp_vad_en) { + regcache_cache_only(rt5677->regmap, false); + regcache_sync(rt5677->regmap); + } return 0; } diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 99fd023e3290..20efa4a4c82c 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -1507,6 +1507,9 @@ #define RT5677_GPIO5_FUNC_GPIO (0x0 << 9) #define RT5677_GPIO5_FUNC_DMIC (0x1 << 9) +#define RT5677_FIRMWARE1 "rt5677_dsp_fw1.bin" +#define RT5677_FIRMWARE2 "rt5677_dsp_fw2.bin" + /* System Clock Source */ enum { RT5677_SCLK_S_MCLK, @@ -1546,6 +1549,8 @@ struct rt5677_priv { struct snd_soc_codec *codec; struct rt5677_platform_data pdata; struct regmap *regmap; + const struct firmware *fw1, *fw2; + struct mutex dsp_cmd_lock; int sysclk; int sysclk_src; @@ -1559,6 +1564,7 @@ struct rt5677_priv { #ifdef CONFIG_GPIOLIB struct gpio_chip gpio_chip; #endif + bool dsp_vad_en; }; #endif /* __RT5677_H__ */ -- GitLab From 8a4bd60af4cbdfbdaab6dec6ab86471733197a4f Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Wed, 15 Oct 2014 13:55:32 -0700 Subject: [PATCH 0581/9457] ASoC: rt5677: Print more information if setting DAI clock failed Signed-off-by: Anatol Pomozov Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index e6e54fa648aa..caada9192f0f 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -3104,7 +3104,8 @@ static int rt5677_hw_params(struct snd_pcm_substream *substream, rt5677->lrck[dai->id] = params_rate(params); pre_div = rl6231_get_clk_info(rt5677->sysclk, rt5677->lrck[dai->id]); if (pre_div < 0) { - dev_err(codec->dev, "Unsupported clock setting\n"); + dev_err(codec->dev, "Unsupported clock setting: sysclk=%dHz lrck=%dHz\n", + rt5677->sysclk, rt5677->lrck[dai->id]); return -EINVAL; } frame_size = snd_soc_params_to_frame_size(params); -- GitLab From 45b6e1d300b034678c42369aad3b27d37854d1fb Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Thu, 16 Oct 2014 09:40:58 -0700 Subject: [PATCH 0582/9457] ASoC: rt5677: fix build when kernel compiled without GPIOLIB support Signed-off-by: Anatol Pomozov Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index caada9192f0f..d17d079fdcf3 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -3646,6 +3646,11 @@ static void rt5677_free_gpio(struct i2c_client *i2c) gpiochip_remove(&rt5677->gpio_chip); } #else +static void rt5677_gpio_config(struct rt5677_priv *rt5677, unsigned offset, + int value) +{ +} + static void rt5677_init_gpio(struct i2c_client *i2c) { } -- GitLab From ac884fc47b7750b1e7eaf04f0236610c84ceee54 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Fri, 17 Oct 2014 11:56:42 -0700 Subject: [PATCH 0583/9457] ASoC: rt5677: add build dependency to spi Since 9cb715a9d4c the codec has a hardcoded dependency to spi. Add this dependency to Kconfig. It fixes buildbot compilation failure: sound/built-in.o: In function `spi_write': >> rt5677-spi.c:(.text+0x8265f): undefined reference to `spi_sync' sound/built-in.o: In function `rt5677_spi_driver_init': >> rt5677-spi.c:(.init.text+0x17db): undefined reference to `spi_register_driver' Signed-off-by: Anatol Pomozov Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..2c7482ec25e8 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -85,7 +85,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_RT5645 if I2C select SND_SOC_RT5651 if I2C select SND_SOC_RT5670 if I2C - select SND_SOC_RT5677 if I2C + select SND_SOC_RT5677 if I2C && SPI_MASTER select SND_SOC_SGTL5000 if I2C select SND_SOC_SI476X if MFD_SI476X_CORE select SND_SOC_SIRF_AUDIO_CODEC -- GitLab From 7f6d75d77683c8f9c18836a2fea2a1e76efc3a9a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 10:50:56 -0300 Subject: [PATCH 0584/9457] ASoC: sgtl5000: Cleanup the comments Fix grammar and typos. Besides that, also fix the comment about the range of SYS_MCLK, which is from 8 to 27 MHz. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 6bb77d76561b..10160e7a9277 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -530,16 +530,16 @@ static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai, /* * set clock according to i2s frame clock, - * sgtl5000 provide 2 clock sources. - * 1. sys_mclk. sample freq can only configure to + * sgtl5000 provides 2 clock sources: + * 1. sys_mclk: sample freq can only be configured to * 1/256, 1/384, 1/512 of sys_mclk. - * 2. pll. can derive any audio clocks. + * 2. pll: can derive any audio clocks. * * clock setting rules: - * 1. in slave mode, only sys_mclk can use. - * 2. as constraint by sys_mclk, sample freq should - * set to 32k, 44.1k and above. - * 3. using sys_mclk prefer to pll to save power. + * 1. in slave mode, only sys_mclk can be used + * 2. as constraint by sys_mclk, sample freq should be set to 32 kHz, 44.1 kHz + * and above. + * 3. usage of sys_mclk is preferred over pll to save power. */ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) { @@ -549,8 +549,8 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) /* * sample freq should be divided by frame clock, - * if frame clock lower than 44.1khz, sample feq should set to - * 32khz or 44.1khz. + * if frame clock is lower than 44.1 kHz, sample freq should be set to + * 32 kHz or 44.1 kHz. */ switch (frame_rate) { case 8000: @@ -603,7 +603,8 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) /* * calculate the divider of mclk/sample_freq, - * factor of freq =96k can only be 256, since mclk in range (12m,27m) + * factor of freq = 96 kHz can only be 256, since mclk is in the range + * of 8 MHz - 27 MHz */ switch (sgtl5000->sysclk / sys_fs) { case 256: @@ -619,7 +620,7 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate) SGTL5000_MCLK_FREQ_SHIFT; break; default: - /* if mclk not satisify the divider, use pll */ + /* if mclk does not satisfy the divider, use pll */ if (sgtl5000->master) { clk_ctl |= SGTL5000_MCLK_FREQ_PLL << SGTL5000_MCLK_FREQ_SHIFT; @@ -795,7 +796,7 @@ static int ldo_regulator_enable(struct regulator_dev *dev) SGTL5000_LINEREG_D_POWERUP, SGTL5000_LINEREG_D_POWERUP); - /* when internal ldo enabled, simple digital power can be disabled */ + /* when internal ldo is enabled, simple digital power can be disabled */ snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, SGTL5000_LINREG_SIMPLE_POWERUP, 0); @@ -1079,7 +1080,7 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg) /* * sgtl5000 has 3 internal power supplies: * 1. VAG, normally set to vdda/2 - * 2. chargepump, set to different value + * 2. charge pump, set to different value * according to voltage of vdda and vddio * 3. line out VAG, normally set to vddio/2 * -- GitLab From bd0593f5f6add279257334b4a76aecd3ee8d31dc Mon Sep 17 00:00:00 2001 From: Jean-Michel Hautbois Date: Tue, 14 Oct 2014 08:43:11 +0200 Subject: [PATCH 0585/9457] ASoC: sgtl5000: Add MicBias resistor support in DT Some systems may require a different resistor than the default one (4K). This adds a property in sgtl5000 codec. It keeps the default of 4K when nothing is specified so it does not break existing code. Signed-off-by: Jean-Michel Hautbois Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/sgtl5000.txt | 8 +++ sound/soc/codecs/sgtl5000.c | 55 +++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt index 955df60a118c..d6ec92707d81 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -7,10 +7,18 @@ Required properties: - clocks : the clock provider of SYS_MCLK +- micbias-resistor-k-ohms : the bias resistor to be used in kOmhs + The resistor can take values of 2k, 4k or 8k. + If set to 0 it will be off. + If this node is not mentioned or if the value is unknown, then + micbias resistor is set to 4K. + + Example: codec: sgtl5000@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; clocks = <&clks 150>; + sgtl5000-micbias-resistor = <1>; }; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 10160e7a9277..c417b4ad0492 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,13 @@ struct ldo_regulator { bool enabled; }; +enum sgtl5000_micbias_resistor { + SGTL5000_MICBIAS_OFF = 0, + SGTL5000_MICBIAS_2K = 2, + SGTL5000_MICBIAS_4K = 4, + SGTL5000_MICBIAS_8K = 8, +}; + /* sgtl5000 private structure in codec */ struct sgtl5000_priv { int sysclk; /* sysclk rate */ @@ -131,6 +139,7 @@ struct sgtl5000_priv { struct regmap *regmap; struct clk *mclk; int revision; + u8 micbias_resistor; }; /* @@ -145,12 +154,14 @@ struct sgtl5000_priv { static int mic_bias_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(w->codec); + switch (event) { case SND_SOC_DAPM_POST_PMU: - /* change mic bias resistor to 4Kohm */ + /* change mic bias resistor */ snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, - SGTL5000_BIAS_R_MASK, - SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT); + SGTL5000_BIAS_R_MASK, + sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); break; case SND_SOC_DAPM_PRE_PMD: @@ -1327,7 +1338,9 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN); - snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 2); + snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, + SGTL5000_BIAS_R_MASK, + sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); /* * disable DAP @@ -1419,6 +1432,8 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, struct sgtl5000_priv *sgtl5000; int ret, reg, rev; unsigned int mclk; + struct device_node *np = client->dev.of_node; + u32 value; sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), GFP_KERNEL); @@ -1471,6 +1486,38 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev); sgtl5000->revision = rev; + if (np) { + if (!of_property_read_u32(np, + "micbias-resistor-k-ohms", &value)) { + switch (value) { + case SGTL5000_MICBIAS_OFF: + sgtl5000->micbias_resistor = 0; + break; + case SGTL5000_MICBIAS_2K: + sgtl5000->micbias_resistor = 1; + break; + case SGTL5000_MICBIAS_4K: + sgtl5000->micbias_resistor = 2; + break; + case SGTL5000_MICBIAS_8K: + sgtl5000->micbias_resistor = 3; + break; + default: + sgtl5000->micbias_resistor = 2; + dev_err(&client->dev, + "Unsuitable MicBias resistor\n"); + } + } else { + /* default is 4Kohms */ + sgtl5000->micbias_resistor = 2; + } + dev_err(&client->dev, + "Unsuitable MicBias resistor\n"); + } + } else { + } + } + i2c_set_clientdata(client, sgtl5000); /* Ensure sgtl5000 will start with sane register values */ -- GitLab From 8735779774b8bbe14456c9e6ba4525eefc67a228 Mon Sep 17 00:00:00 2001 From: Jean-Michel Hautbois Date: Tue, 14 Oct 2014 08:43:12 +0200 Subject: [PATCH 0586/9457] ASoC: sgtl5000: Add MicBias voltage support Some systems may require to specify a bias different than default (1.25V). This adds a property in sgtl5000 codec. The property is specified in milli-volts so that it is coherent with datasheet. Signed-off-by: Jean-Michel Hautbois Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/sgtl5000.txt | 7 ++++++- sound/soc/codecs/sgtl5000.c | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt index d6ec92707d81..1aab40339617 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -13,6 +13,10 @@ Required properties: If this node is not mentioned or if the value is unknown, then micbias resistor is set to 4K. +- micbias-voltage-m-volts : the bias voltage to be used in mVolts + The voltage can take values from 1.25V to 3V by 250mV steps + If this node is not mentionned or the value is unknown, then + the value is set to 1.25V. Example: @@ -20,5 +24,6 @@ codec: sgtl5000@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; clocks = <&clks 150>; - sgtl5000-micbias-resistor = <1>; + micbias-resistor-k-ohms = <2>; + micbias-voltage-m-volts = <2250>; }; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index c417b4ad0492..59336f6aba80 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -140,6 +140,7 @@ struct sgtl5000_priv { struct clk *mclk; int revision; u8 micbias_resistor; + u8 micbias_voltage; }; /* @@ -1342,6 +1343,9 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) SGTL5000_BIAS_R_MASK, sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); + snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, + SGTL5000_BIAS_R_MASK, + sgtl5000->micbias_voltage << SGTL5000_BIAS_R_SHIFT); /* * disable DAP * TODO: @@ -1511,10 +1515,19 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, /* default is 4Kohms */ sgtl5000->micbias_resistor = 2; } + if (!of_property_read_u32(np, + "micbias-voltage-m-volts", &value)) { + /* 1250mV => 0 */ + /* steps of 250mV */ + if ((value >= 1250) && (value <= 3000)) + sgtl5000->micbias_voltage = (value / 250) - 5; + else { + sgtl5000->micbias_voltage = 0; dev_err(&client->dev, "Unsuitable MicBias resistor\n"); } } else { + sgtl5000->micbias_voltage = 0; } } -- GitLab From 84d4cbe9a60a1fdd35b4dd69951f31c518b467d8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 15:29:58 -0300 Subject: [PATCH 0587/9457] ASoC: simple-card: Delete unneeded test before of_node_put of_node_put() supports NULL as its argument, so the initial test is not necessary. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index d1b7293c133e..4f192ee3cb16 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -368,12 +368,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, dai_link->cpu_dai_name = NULL; dai_link_of_err: - if (np) - of_node_put(np); - if (bitclkmaster) - of_node_put(bitclkmaster); - if (framemaster) - of_node_put(framemaster); + of_node_put(np); + of_node_put(bitclkmaster); + of_node_put(framemaster); return ret; } @@ -464,11 +461,9 @@ static int asoc_simple_card_unref(struct platform_device *pdev) num_links < card->num_links; num_links++, dai_link++) { np = (struct device_node *) dai_link->cpu_of_node; - if (np) - of_node_put(np); + of_node_put(np); np = (struct device_node *) dai_link->codec_of_node; - if (np) - of_node_put(np); + of_node_put(np); } return 0; } -- GitLab From 5398ad6897ec666a416b1d7428f0e8a51adf4254 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sat, 11 Oct 2014 21:10:35 +0530 Subject: [PATCH 0588/9457] spi/atmel: use dmaengine_terminate_all() API The drivers should use dmaengine_terminate_all() API instead of accessing the device_control which will be deprecated soon Signed-off-by: Vinod Koul Acked-by: Nicolas Ferre Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 113c83f44b5c..649dcb5a603c 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -482,11 +482,9 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) static void atmel_spi_stop_dma(struct atmel_spi *as) { if (as->dma.chan_rx) - as->dma.chan_rx->device->device_control(as->dma.chan_rx, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(as->dma.chan_rx); if (as->dma.chan_tx) - as->dma.chan_tx->device->device_control(as->dma.chan_tx, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(as->dma.chan_tx); } static void atmel_spi_release_dma(struct atmel_spi *as) -- GitLab From ce0c4caf256cb828e0465d3cd363ec145e446e21 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Thu, 16 Oct 2014 17:23:10 +0800 Subject: [PATCH 0589/9457] spi/atmel: add support for runtime PM Drivers should put the device into low power states proactively whenever the device is not in use. Thus implement support for runtime PM and use the autosuspend feature to make sure that we can still perform well in case we see lots of SPI traffic within short period of time. Signed-off-by: Wenyou Yang Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 68 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 649dcb5a603c..bc9d96902837 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -26,6 +26,7 @@ #include #include #include +#include /* SPI register offsets */ #define SPI_CR 0x0000 @@ -191,6 +192,8 @@ #define SPI_DMA_TIMEOUT (msecs_to_jiffies(1000)) +#define AUTOSUSPEND_TIMEOUT 2000 + struct atmel_spi_dma { struct dma_chan *chan_rx; struct dma_chan *chan_tx; @@ -1313,6 +1316,7 @@ static int atmel_spi_probe(struct platform_device *pdev) master->setup = atmel_spi_setup; master->transfer_one_message = atmel_spi_transfer_one_message; master->cleanup = atmel_spi_cleanup; + master->auto_runtime_pm = true; platform_set_drvdata(pdev, master); as = spi_master_get_devdata(master); @@ -1385,6 +1389,11 @@ static int atmel_spi_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n", (unsigned long)regs->start, irq); + pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = devm_spi_register_master(&pdev->dev, master); if (ret) goto out_free_dma; @@ -1392,6 +1401,9 @@ static int atmel_spi_probe(struct platform_device *pdev) return 0; out_free_dma: + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + if (as->use_dma) atmel_spi_release_dma(as); @@ -1413,6 +1425,8 @@ 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); + pm_runtime_get_sync(&pdev->dev); + /* reset the hardware and block queue progress */ spin_lock_irq(&as->lock); if (as->use_dma) { @@ -1430,9 +1444,13 @@ static int atmel_spi_remove(struct platform_device *pdev) clk_disable_unprepare(as->clk); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return 0; } +#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP static int atmel_spi_suspend(struct device *dev) { @@ -1447,9 +1465,10 @@ static int atmel_spi_suspend(struct device *dev) return ret; } - clk_disable_unprepare(as->clk); - - pinctrl_pm_select_sleep_state(dev); + if (!pm_runtime_suspended(dev)) { + clk_disable_unprepare(as->clk); + pinctrl_pm_select_sleep_state(dev); + } return 0; } @@ -1460,9 +1479,12 @@ static int atmel_spi_resume(struct device *dev) struct atmel_spi *as = spi_master_get_devdata(master); int ret; - pinctrl_pm_select_default_state(dev); - - clk_prepare_enable(as->clk); + if (!pm_runtime_suspended(dev)) { + pinctrl_pm_select_default_state(dev); + ret = clk_prepare_enable(as->clk); + if (ret) + return ret; + } /* Start the queue running */ ret = spi_master_resume(master); @@ -1471,9 +1493,41 @@ static int atmel_spi_resume(struct device *dev) return ret; } +#endif -static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume); +#ifdef CONFIG_PM_RUNTIME +static int atmel_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct atmel_spi *as = spi_master_get_devdata(master); + clk_disable_unprepare(as->clk); + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int atmel_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct atmel_spi *as = spi_master_get_devdata(master); + int ret; + + pinctrl_pm_select_default_state(dev); + + ret = clk_prepare_enable(as->clk); + if (ret) + return ret; + + return 0; +} +#endif + +static const struct dev_pm_ops atmel_spi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(atmel_spi_suspend, atmel_spi_resume) + SET_RUNTIME_PM_OPS(atmel_spi_runtime_suspend, + atmel_spi_runtime_resume, NULL) +}; #define ATMEL_SPI_PM_OPS (&atmel_spi_pm_ops) #else #define ATMEL_SPI_PM_OPS NULL -- GitLab From d0de6ff6b92665c10a93795e9d041a61f64431af Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Fri, 17 Oct 2014 00:18:56 +0800 Subject: [PATCH 0590/9457] spi/atmel: fix simple_return.cocci warnings drivers/spi/spi-atmel.c:1518:1-4: WARNING: end returns can be simpified and declaration on line 1514 can be dropped Simplify a trivial if-return sequence. Possibly combine with a preceding function call. Generated by: scripts/coccinelle/misc/simple_return.cocci Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index bc9d96902837..3f500142f13c 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1511,15 +1511,10 @@ static int atmel_spi_runtime_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct atmel_spi *as = spi_master_get_devdata(master); - int ret; pinctrl_pm_select_default_state(dev); - ret = clk_prepare_enable(as->clk); - if (ret) - return ret; - - return 0; + return clk_prepare_enable(as->clk); } #endif -- GitLab From 409851c38c742e56747b1911a5091e22b6c8514f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 9 Oct 2014 11:27:45 +0800 Subject: [PATCH 0591/9457] spi: fsl-dspi: remove useless code for dspi driver. Since we are using regmap framework's internal locks, so the lock_arg for dspi_regmap_config is redundant here. This patch just remove it, and then the dspi_regmap_config could be const type. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-dspi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 448216025ce8..12dc99546394 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -438,7 +438,7 @@ static int dspi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume); -static struct regmap_config dspi_regmap_config = { +static const struct regmap_config dspi_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, @@ -492,7 +492,6 @@ static int dspi_probe(struct platform_device *pdev) goto out_master_put; } - dspi_regmap_config.lock_arg = dspi; dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, &dspi_regmap_config); if (IS_ERR(dspi->regmap)) { -- GitLab From 03ad6a8c93b6df2d65c305b5b5f9474068b45bfb Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 16 Oct 2014 15:33:45 +0200 Subject: [PATCH 0592/9457] ALSA: hda - Fix "PCM" name being used on one DAC when there are two DACs In the scenario where there is one "Line Out", one "Speaker" and one "Headphone", and there are only two DACs, two outputs will share a DAC. Currently any mixer on such a DAC will get the "PCM" name, which is misleading. Instead use "Headphone+LO" or "Speaker+LO" to better specify what the volume actually controls. [fixed missing slave string additions by tiwai] Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 64220c08bd98..dc13cce70932 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1038,6 +1038,19 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch, break; *index = ch; return "Headphone"; + case AUTO_PIN_LINE_OUT: + /* This deals with the case where we have two DACs and + * one LO, one HP and one Speaker */ + if (!ch && cfg->speaker_outs && cfg->hp_outs) { + bool hp_lo_shared = !path_has_mixer(codec, spec->hp_paths[0], ctl_type); + bool spk_lo_shared = !path_has_mixer(codec, spec->speaker_paths[0], ctl_type); + if (hp_lo_shared && spk_lo_shared) + return spec->vmaster_mute.hook ? "PCM" : "Master"; + if (hp_lo_shared) + return "Headphone+LO"; + if (spk_lo_shared) + return "Speaker+LO"; + } } /* for a single channel output, we don't have to name the channel */ @@ -4524,7 +4537,7 @@ static const char * const slave_pfxs[] = { "CLFE", "Bass Speaker", "PCM", "Speaker Front", "Speaker Surround", "Speaker CLFE", "Speaker Side", "Headphone Front", "Headphone Surround", "Headphone CLFE", - "Headphone Side", + "Headphone Side", "Headphone+LO", "Speaker+LO", NULL, }; -- GitLab From 3abb4f4d0e7aaad0d12004b5057f4486a688752b Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 16 Oct 2014 15:33:46 +0200 Subject: [PATCH 0593/9457] ALSA: hda - Use "Line Out" name instead of "PCM" when there are other outputs In case there are speakers or headphones as well, anything that only covers the line out should not be labelled "PCM". Let's name it "Line Out" instead for clarity. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index dc13cce70932..06d721085e72 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1055,7 +1055,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch, /* for a single channel output, we don't have to name the channel */ if (cfg->line_outs == 1 && !spec->multi_ios) - return "PCM"; + return "Line Out"; if (ch >= ARRAY_SIZE(channel_name)) { snd_BUG(); -- GitLab From 8f06f5d392b3fbd58a5d7e00b047b6ee08c6d9b0 Mon Sep 17 00:00:00 2001 From: Jianqun Date: Mon, 20 Oct 2014 17:55:03 +0800 Subject: [PATCH 0594/9457] clk: rockchip: rk3288: removing the CLK_SET_RATE_PARENT from i2s_clkout Removing the CLK_SET_RATE_PARENT from i2s_clkout, to limit i2s0_clkout to select between its two parent without being able influence the core i2s clock. Tested on rk3288 board, suggested by Heiko. Signed-off-by: Jianqun Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index c3706431ed10..d417bceac9e4 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -307,7 +307,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(4), 2, GFLAGS), MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT, + COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, 0, RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, RK3288_CLKGATE_CON(4), 0, GFLAGS), GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, -- GitLab From 89c107a88de955eee2e1ca0c8d9f10524f5f68cc Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 16 Oct 2014 15:46:36 -0700 Subject: [PATCH 0595/9457] clk: rockchip: add npll to source of sclk_gpu The possible sources for the rk3288-gpu-clock also include the npll, making it the same list of sources as for uart0. This patch make a common source for uart0 pll src and sclk_gpu, so that gpu can get its clock from npll. Signed-off-by: Kever Yang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index d417bceac9e4..4cef77b5006d 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -175,14 +175,14 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; -PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" }; +PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; +PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; -PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" }; PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; @@ -442,7 +442,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 8, GFLAGS), - COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 7, GFLAGS), @@ -519,7 +519,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(5), 6, GFLAGS), - COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0, + COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(1), 8, GFLAGS), COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0, -- GitLab From 8e648204194cb51df8562d1e2a64b7dc6b0aead3 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Oct 2014 14:38:09 +0200 Subject: [PATCH 0596/9457] ALSA: Update control names documentation This document was not really up-to-date. Add recent additions to this standard - based on what the HDA driver currently does, which is some kind of a de facto standard. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ControlNames.txt | 32 +++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Documentation/sound/alsa/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt index fea65bb6269e..79a6127863ca 100644 --- a/Documentation/sound/alsa/ControlNames.txt +++ b/Documentation/sound/alsa/ControlNames.txt @@ -1,6 +1,6 @@ This document describes standard names of mixer controls. -Syntax: SOURCE [DIRECTION] FUNCTION +Syntax: [LOCATION] SOURCE [CHANNEL] [DIRECTION] FUNCTION DIRECTION: (both directions) @@ -14,12 +14,29 @@ FUNCTION: Volume Route (route control, hardware specific) +CHANNEL: + (channel independent, or applies to all channels) + Front + Surround (rear left/right in 4.0/5.1 surround) + CLFE + Center + LFE + Side (side left/right for 7.1 surround) + +LOCATION: (physical location of source) + Front + Rear + Dock (docking station) + Internal + SOURCE: Master Master Mono Hardware Master Speaker (internal speaker) + Bass Speaker (internal LFE speaker) Headphone + Line Out Beep (beep generator) Phone Phone Input @@ -27,14 +44,14 @@ SOURCE: Synth FM Mic - Line + Headset Mic (mic part of combined headset jack - 4-pin headphone + mic) + Headphone Mic (mic part of either/or - 3-pin headphone or mic) + Line (input only, use "Line Out" for output) CD Video Zoom Video Aux PCM - PCM Front - PCM Rear PCM Pan Loopback Analog Loopback (D/A -> A/D loopback) @@ -47,8 +64,13 @@ SOURCE: Music I2S IEC958 + HDMI + SPDIF (output only) + SPDIF In + Digital In + HDMI/DP (either HDMI or DisplayPort) -Exceptions: +Exceptions (deprecated): [Digital] Capture Source [Digital] Capture Switch (aka input gain switch) [Digital] Capture Volume (aka input gain volume) -- GitLab From d155fc759abd0a0d0289a63ad8bb51057538f1e3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:02 +0200 Subject: [PATCH 0597/9457] ARM: common: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/common/sa1111.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index e57d7e5bf96a..cd5914cfa175 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1057,7 +1057,6 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", - .owner = THIS_MODULE, }, }; -- GitLab From 7246c72de2ba99c1eafd4131f353c8ab4dca5191 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:02 +0200 Subject: [PATCH 0598/9457] ARM: mach-davinci: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-davinci/cpuidle.c | 1 - arch/arm/mach-davinci/pm.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index f1ac1c94ac0f..6b8dbd2089de 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -92,7 +92,6 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) static struct platform_driver davinci_cpuidle_driver = { .driver = { .name = "cpuidle-davinci", - .owner = THIS_MODULE, }, }; diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index a508fe587af7..07e23ba61f3a 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -148,7 +148,6 @@ static int __exit davinci_pm_remove(struct platform_device *pdev) static struct platform_driver davinci_pm_driver = { .driver = { .name = "pm-davinci", - .owner = THIS_MODULE, }, .remove = __exit_p(davinci_pm_remove), }; -- GitLab From f2633f8a53e3e7cbc488e87a9473c040ea3e76ff Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:03 +0200 Subject: [PATCH 0599/9457] ARM: mach-imx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-imx/mmdc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 7a9686ad994c..a3dedc309bbc 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -59,7 +59,6 @@ static struct of_device_id imx_mmdc_dt_ids[] = { static struct platform_driver imx_mmdc_driver = { .driver = { .name = "imx-mmdc", - .owner = THIS_MODULE, .of_match_table = imx_mmdc_dt_ids, }, .probe = imx_mmdc_probe, -- GitLab From a46ca32ca0ea801fb835794bb069e9449060bbae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:03 +0200 Subject: [PATCH 0600/9457] ARM: mach-msm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-msm/clock-pcom.c | 1 - arch/arm/mach-msm/smd.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c index 9a80449518e6..f5b69d736ee5 100644 --- a/arch/arm/mach-msm/clock-pcom.c +++ b/arch/arm/mach-msm/clock-pcom.c @@ -169,7 +169,6 @@ static struct platform_driver msm_clock_pcom_driver = { .probe = msm_clock_pcom_probe, .driver = { .name = "msm-clock-pcom", - .owner = THIS_MODULE, }, }; module_platform_driver(msm_clock_pcom_driver); diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index b1588a1ea2f8..7550f5a08956 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -1019,7 +1019,6 @@ static struct platform_driver msm_smd_driver = { .probe = msm_smd_probe, .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From ceb8ef2e20fe452f55d9fee0e8c8f2dfcec73db5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:04 +0200 Subject: [PATCH 0601/9457] ARM: mach-omap2: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-omap2/gpmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5fa3755261ce..c02e581f7cfc 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1760,7 +1760,6 @@ static struct platform_driver gpmc_driver = { .remove = gpmc_remove, .driver = { .name = DEVICE_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpmc_dt_ids), .pm = &gpmc_pm_ops, }, -- GitLab From ea18faf9f6173bcb74bd4079dc0356be82d6d8ec Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:05 +0200 Subject: [PATCH 0602/9457] ARM: mach-prima2: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-prima2/pm.c | 1 - arch/arm/mach-prima2/rstc.c | 1 - arch/arm/mach-prima2/rtciobrg.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c index 96e9bc102117..d99d08eeb966 100644 --- a/arch/arm/mach-prima2/pm.c +++ b/arch/arm/mach-prima2/pm.c @@ -135,7 +135,6 @@ static struct platform_driver sirfsoc_memc_driver = { .probe = sirfsoc_memc_probe, .driver = { .name = "sirfsoc-memc", - .owner = THIS_MODULE, .of_match_table = memc_ids, }, }; diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index 3dffcb2d714e..e1f1f86f6a95 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c @@ -114,7 +114,6 @@ static struct platform_driver sirfsoc_rstc_driver = { .probe = sirfsoc_rstc_probe, .driver = { .name = "sirfsoc_rstc", - .owner = THIS_MODULE, .of_match_table = rstc_ids, }, }; diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c index a17c88b74fa1..70a0b475062b 100644 --- a/arch/arm/mach-prima2/rtciobrg.c +++ b/arch/arm/mach-prima2/rtciobrg.c @@ -123,7 +123,6 @@ static struct platform_driver sirfsoc_rtciobrg_driver = { .probe = sirfsoc_rtciobrg_probe, .driver = { .name = "sirfsoc-rtciobrg", - .owner = THIS_MODULE, .of_match_table = rtciobrg_ids, }, }; -- GitLab From a961f40ee16c5c1cae338e0734d054a98f24d7b7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:05 +0200 Subject: [PATCH 0603/9457] ARM: mach-pxa: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-pxa/pxa3xx-ulpi.c | 1 - arch/arm/mach-pxa/tosa-bt.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index e329ccefd364..4ced61afc7f5 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -379,7 +379,6 @@ static int pxa3xx_u2d_remove(struct platform_device *pdev) static struct platform_driver pxa3xx_u2d_ulpi_driver = { .driver = { .name = "pxa3xx-u2d", - .owner = THIS_MODULE, }, .probe = pxa3xx_u2d_probe, .remove = pxa3xx_u2d_remove, diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index fc3646c2c694..685deff861d2 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -129,7 +129,6 @@ static struct platform_driver tosa_bt_driver = { .driver = { .name = "tosa-bt", - .owner = THIS_MODULE, }, }; -- GitLab From fb33e224768876b0b58b9e3e18f3d28ac49c8c57 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:06 +0200 Subject: [PATCH 0604/9457] ARM: mach-s3c24xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-s3c24xx/mach-osiris-dvs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c index 33afb9190091..ce2db235dbaf 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c +++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c @@ -171,7 +171,6 @@ static struct platform_driver osiris_dvs_driver = { .remove = osiris_dvs_remove, .driver = { .name = "osiris-dvs", - .owner = THIS_MODULE, .pm = &osiris_dvs_pm, }, }; -- GitLab From 666672065a5a277f9d975327e0631afa9f892d1a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:06 +0200 Subject: [PATCH 0605/9457] ARM: mach-sa1100: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-sa1100/neponset.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 400f80332046..169262e3040d 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -423,7 +423,6 @@ static struct platform_driver neponset_device_driver = { .remove = neponset_remove, .driver = { .name = "neponset", - .owner = THIS_MODULE, .pm = PM_OPS, }, }; -- GitLab From 67cfdbc4dcac4a9105adbdb5926facd2a4d304f9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:06 +0200 Subject: [PATCH 0606/9457] ARM: mach-u300: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/mach-u300/regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c index 0493a845b6bc..595b574c2c50 100644 --- a/arch/arm/mach-u300/regulator.c +++ b/arch/arm/mach-u300/regulator.c @@ -116,7 +116,6 @@ static const struct of_device_id s365_board_match[] = { static struct platform_driver s365_board_driver = { .driver = { .name = "s365-board", - .owner = THIS_MODULE, .of_match_table = s365_board_match, }, }; -- GitLab From 848ceb1b85e306a8634ea6ed6ec752598554f5b1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:07 +0200 Subject: [PATCH 0607/9457] ARM: plat-pxa: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/plat-pxa/ssp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 1f5ee17a10e8..ad9529cc4203 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c @@ -268,7 +268,6 @@ static struct platform_driver pxa_ssp_driver = { .probe = pxa_ssp_probe, .remove = pxa_ssp_remove, .driver = { - .owner = THIS_MODULE, .name = "pxa2xx-ssp", .of_match_table = of_match_ptr(pxa_ssp_of_ids), }, -- GitLab From 5e641f9f5b6f1d3f5ab20fd7949a8bb5329030f4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:07 +0200 Subject: [PATCH 0608/9457] ARM: plat-samsung: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/arm/plat-samsung/adc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 468352633101..e2be70df06c6 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -505,7 +505,6 @@ static struct platform_driver s3c_adc_driver = { .id_table = s3c_adc_driver_ids, .driver = { .name = "s3c-adc", - .owner = THIS_MODULE, .pm = &adc_pm_ops, }, .probe = s3c_adc_probe, -- GitLab From 5ffc6d13e141632f9f26e47823d00ac5ae4947a8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:08 +0200 Subject: [PATCH 0609/9457] mips: lantiq: xway: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/mips/lantiq/xway/dcdc.c | 1 - arch/mips/lantiq/xway/dma.c | 1 - arch/mips/lantiq/xway/gptu.c | 1 - arch/mips/lantiq/xway/xrx200_phy_fw.c | 1 - 4 files changed, 4 deletions(-) diff --git a/arch/mips/lantiq/xway/dcdc.c b/arch/mips/lantiq/xway/dcdc.c index 7688ac0f06d0..ae8e930f5283 100644 --- a/arch/mips/lantiq/xway/dcdc.c +++ b/arch/mips/lantiq/xway/dcdc.c @@ -46,7 +46,6 @@ static struct platform_driver dcdc_driver = { .probe = dcdc_probe, .driver = { .name = "dcdc-xrx200", - .owner = THIS_MODULE, .of_match_table = dcdc_match, }, }; diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 78a91fa41944..34a116e840d8 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -261,7 +261,6 @@ static struct platform_driver dma_driver = { .probe = ltq_dma_init, .driver = { .name = "dma-xway", - .owner = THIS_MODULE, .of_match_table = dma_match, }, }; diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c index 850821df924c..f1492b2db017 100644 --- a/arch/mips/lantiq/xway/gptu.c +++ b/arch/mips/lantiq/xway/gptu.c @@ -193,7 +193,6 @@ static struct platform_driver dma_driver = { .probe = gptu_probe, .driver = { .name = "gptu-xway", - .owner = THIS_MODULE, .of_match_table = gptu_match, }, }; diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index d4d9d31f152e..e4ed004015c4 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c @@ -85,7 +85,6 @@ static struct platform_driver xway_phy_driver = { .probe = xway_phy_fw_probe, .driver = { .name = "phy-xrx200", - .owner = THIS_MODULE, .of_match_table = xway_phy_match, }, }; -- GitLab From b9acbf99f1e3a76e5a6ea185009d9c7e30c6a9c1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:08 +0200 Subject: [PATCH 0610/9457] mips: mti-sead3: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/mips/mti-sead3/leds-sead3.c | 1 - arch/mips/mti-sead3/sead3-i2c-drv.c | 1 - arch/mips/mti-sead3/sead3-pic32-i2c-drv.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/mips/mti-sead3/leds-sead3.c b/arch/mips/mti-sead3/leds-sead3.c index 0a168c948b01..3abe47b316aa 100644 --- a/arch/mips/mti-sead3/leds-sead3.c +++ b/arch/mips/mti-sead3/leds-sead3.c @@ -70,7 +70,6 @@ static struct platform_driver sead3_led_driver = { .remove = sead3_led_remove, .driver = { .name = DRVNAME, - .owner = THIS_MODULE, }, }; diff --git a/arch/mips/mti-sead3/sead3-i2c-drv.c b/arch/mips/mti-sead3/sead3-i2c-drv.c index 1f787a6a7878..2bebf0974e39 100644 --- a/arch/mips/mti-sead3/sead3-i2c-drv.c +++ b/arch/mips/mti-sead3/sead3-i2c-drv.c @@ -380,7 +380,6 @@ static int sead3_i2c_platform_resume(struct platform_device *pdev) static struct platform_driver sead3_i2c_platform_driver = { .driver = { .name = "sead3-i2c", - .owner = THIS_MODULE, }, .probe = sead3_i2c_platform_probe, .remove = sead3_i2c_platform_remove, diff --git a/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c index 80fe194cfa53..c388844f4ddb 100644 --- a/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c +++ b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c @@ -393,7 +393,6 @@ i2c_platform_resume(struct platform_device *pdev) static struct platform_driver i2c_platform_driver = { .driver = { .name = "i2c_pic32", - .owner = THIS_MODULE, }, .probe = i2c_platform_probe, .remove = i2c_platform_remove, -- GitLab From ec4848815c83d4b8b83440bf6bf571d9b6b5e0d6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:08 +0200 Subject: [PATCH 0611/9457] mips: pci: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/mips/pci/pci-alchemy.c | 1 - arch/mips/pci/pci-ar71xx.c | 1 - arch/mips/pci/pci-ar724x.c | 1 - arch/mips/pci/pci-lantiq.c | 1 - arch/mips/pci/pci-rt3883.c | 1 - 5 files changed, 5 deletions(-) diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index c19600a03460..28952637a862 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -505,7 +505,6 @@ static struct platform_driver alchemy_pcictl_driver = { .probe = alchemy_pci_probe, .driver = { .name = "alchemy-pci", - .owner = THIS_MODULE, }, }; diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index d471a26dd5f8..2882f6a0f919 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -416,7 +416,6 @@ static struct platform_driver ar71xx_pci_driver = { .probe = ar71xx_pci_probe, .driver = { .name = "ar71xx-pci", - .owner = THIS_MODULE, }, }; diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 785b2659b519..204c8525c4bb 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -423,7 +423,6 @@ static struct platform_driver ar724x_pci_driver = { .probe = ar724x_pci_probe, .driver = { .name = "ar724x-pci", - .owner = THIS_MODULE, }, }; diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index 37fe8e7887e2..ca94c008c754 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c @@ -247,7 +247,6 @@ static struct platform_driver ltq_pci_driver = { .probe = ltq_pci_probe, .driver = { .name = "pci-xway", - .owner = THIS_MODULE, .of_match_table = ltq_pci_match, }, }; diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 72919aeef42b..b0ba9a9e74d6 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -598,7 +598,6 @@ static struct platform_driver rt3883_pci_driver = { .probe = rt3883_pci_probe, .driver = { .name = "rt3883-pci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rt3883_pci_ids), }, }; -- GitLab From 59613d88e7dd7769d4ac161b7f0540aeed6f3534 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:09 +0200 Subject: [PATCH 0612/9457] mips: ralink: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/mips/ralink/timer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index 5bb29b3790ff..82c72a15bf75 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -173,7 +173,6 @@ static struct platform_driver rt_timer_driver = { .remove = rt_timer_remove, .driver = { .name = "rt-timer", - .owner = THIS_MODULE, .of_match_table = rt_timer_match }, }; -- GitLab From 2320c471aa8703d079debe2e68a5dd59dca0a5fc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:09 +0200 Subject: [PATCH 0613/9457] mips: txx9: rbtx4939: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/mips/txx9/rbtx4939/setup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 2da5f25f98bc..37030409745c 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -245,7 +245,6 @@ static int __init rbtx4939_led_probe(struct platform_device *pdev) static struct platform_driver rbtx4939_led_driver = { .driver = { .name = "rbtx4939-led", - .owner = THIS_MODULE, }, }; -- GitLab From 21d9625180e953853257ffaec38f52200d8489f0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:10 +0200 Subject: [PATCH 0614/9457] powerpc: kernel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/kernel/of_platform.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index f87bc1b4bdda..2f35a72642c6 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -110,7 +110,6 @@ static struct platform_driver of_pci_phb_driver = { .probe = of_pci_phb_probe, .driver = { .name = "of-pci", - .owner = THIS_MODULE, .of_match_table = of_pci_phb_ids, }, }; -- GitLab From ef0e201fc1def82d49f0cc9d6ee4362a200645f5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:10 +0200 Subject: [PATCH 0615/9457] powerpc: platforms: 52xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 1 - arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 692998244d2c..c949ca055712 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -782,7 +782,6 @@ static const struct of_device_id mpc52xx_gpt_match[] = { static struct platform_driver mpc52xx_gpt_driver = { .driver = { .name = "mpc52xx-gpt", - .owner = THIS_MODULE, .of_match_table = mpc52xx_gpt_match, }, .probe = mpc52xx_gpt_probe, diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index f8f0081759fb..251dcb90ef34 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -572,7 +572,6 @@ static const struct of_device_id mpc52xx_lpbfifo_match[] = { static struct platform_driver mpc52xx_lpbfifo_driver = { .driver = { .name = "mpc52xx-lpbfifo", - .owner = THIS_MODULE, .of_match_table = mpc52xx_lpbfifo_match, }, .probe = mpc52xx_lpbfifo_probe, -- GitLab From dc31c3b5685640a57ff6fe20b0bf222f37a50c0b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:11 +0200 Subject: [PATCH 0616/9457] powerpc: platforms: 82xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/82xx/ep8248e.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 3d0c3a01143d..a0cb8bd41958 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -169,7 +169,6 @@ static const struct of_device_id ep8248e_mdio_match[] = { static struct platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", - .owner = THIS_MODULE, .of_match_table = ep8248e_mdio_match, }, .probe = ep8248e_mdio_probe, -- GitLab From bedb9eb1e82e584a95ce0b6ed305e67eded1369e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:11 +0200 Subject: [PATCH 0617/9457] powerpc: platforms: 83xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/83xx/suspend.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index eeb80e25214d..c9adbfb65006 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -435,7 +435,6 @@ static const struct of_device_id pmc_match[] = { static struct platform_driver pmc_driver = { .driver = { .name = "mpc83xx-pmc", - .owner = THIS_MODULE, .of_match_table = pmc_match, }, .probe = pmc_probe, -- GitLab From 4a0b0cee81478b07966412514577dd30dec05d1d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:11 +0200 Subject: [PATCH 0618/9457] powerpc: platforms: 85xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/85xx/sgy_cts1000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 8162b0412117..26bacf0ed146 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -161,7 +161,6 @@ MODULE_DEVICE_TABLE(of, gpio_halt_match); static struct platform_driver gpio_halt_driver = { .driver = { .name = "gpio-halt", - .owner = THIS_MODULE, .of_match_table = gpio_halt_match, }, .probe = gpio_halt_probe, -- GitLab From 463fbd6eb11183d62cbeff75fc8abed29208ac74 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:12 +0200 Subject: [PATCH 0619/9457] powerpc: platforms: cell: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/cell/axon_msi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 862b32702d29..89115d33a846 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -437,7 +437,6 @@ static struct platform_driver axon_msi_driver = { .shutdown = axon_msi_shutdown, .driver = { .name = "axon-msi", - .owner = THIS_MODULE, .of_match_table = axon_msi_device_id, }, }; -- GitLab From 0b06ab798c6abaf6b36d98c176cdadb0cc90e0fa Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:12 +0200 Subject: [PATCH 0620/9457] powerpc: platforms: pasemi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/platforms/pasemi/gpio_mdio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index ada33358950d..ae3f47b25b18 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -305,7 +305,6 @@ static struct platform_driver gpio_mdio_driver = .remove = gpio_mdio_remove, .driver = { .name = "gpio-mdio-bitbang", - .owner = THIS_MODULE, .of_match_table = gpio_mdio_match, }, }; -- GitLab From 4ad7fb261d033e085ea1f3e90bfb1ce47c26a901 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:13 +0200 Subject: [PATCH 0621/9457] powerpc: sysdev: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/sysdev/axonram.c | 1 - arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 1 - arch/powerpc/sysdev/fsl_msi.c | 1 - arch/powerpc/sysdev/fsl_pmc.c | 1 - arch/powerpc/sysdev/fsl_rio.c | 1 - arch/powerpc/sysdev/mpic_msgr.c | 1 - arch/powerpc/sysdev/pmi.c | 1 - arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 1 - arch/powerpc/sysdev/ppc4xx_msi.c | 1 - 9 files changed, 9 deletions(-) diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index ad56edc39919..f532c92bf99d 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -326,7 +326,6 @@ static struct platform_driver axon_ram_driver = { .remove = axon_ram_remove, .driver = { .name = AXON_RAM_MODULE_NAME, - .owner = THIS_MODULE, .of_match_table = axon_ram_device_id, }, }; diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c index 90545ad1626e..861cebf9c292 100644 --- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c @@ -210,7 +210,6 @@ static const struct of_device_id mpc85xx_l2ctlr_of_match[] = { static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = { .driver = { .name = "fsl-l2ctlr", - .owner = THIS_MODULE, .of_match_table = mpc85xx_l2ctlr_of_match, }, .probe = mpc85xx_l2ctlr_of_probe, diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index de40b48b460e..e596444fb024 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -578,7 +578,6 @@ static const struct of_device_id fsl_of_msi_ids[] = { static struct platform_driver fsl_of_msi_driver = { .driver = { .name = "fsl-msi", - .owner = THIS_MODULE, .of_match_table = fsl_of_msi_ids, }, .probe = fsl_of_msi_probe, diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 8cf4aa0e3a25..1d6fd7c59fe9 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -80,7 +80,6 @@ static const struct of_device_id pmc_ids[] = { static struct platform_driver pmc_driver = { .driver = { .name = "fsl-pmc", - .owner = THIS_MODULE, .of_match_table = pmc_ids, }, .probe = pmc_probe, diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index c04b718307c8..39d32480f0eb 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -673,7 +673,6 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { static struct platform_driver fsl_of_rio_rpn_driver = { .driver = { .name = "fsl-of-rio", - .owner = THIS_MODULE, .of_match_table = fsl_of_rio_rpn_ids, }, .probe = fsl_of_rio_rpn_probe, diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 7bdf3cc741e4..3f165d972a0e 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -270,7 +270,6 @@ static const struct of_device_id mpic_msgr_ids[] = { static struct platform_driver mpic_msgr_driver = { .driver = { .name = "mpic-msgr", - .owner = THIS_MODULE, .of_match_table = mpic_msgr_ids, }, .probe = mpic_msgr_probe, diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 13e67d93a7c1..8a0b77a3ec0c 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -210,7 +210,6 @@ static struct platform_driver pmi_of_platform_driver = { .remove = pmi_of_remove, .driver = { .name = "pmi", - .owner = THIS_MODULE, .of_match_table = pmi_match, }, }; diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c index a6a4dbda9078..f51fcebb559e 100644 --- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c @@ -197,7 +197,6 @@ static struct platform_driver hsta_msi_driver = { .probe = hsta_msi_probe, .driver = { .name = "hsta-msi", - .owner = THIS_MODULE, .of_match_table = hsta_msi_ids, }, }; diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 22b5200636e7..96eaaa026849 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c @@ -270,7 +270,6 @@ static struct platform_driver ppc4xx_msi_driver = { .remove = ppc4xx_of_msi_remove, .driver = { .name = "ppc4xx-msi", - .owner = THIS_MODULE, .of_match_table = ppc4xx_msi_ids, }, -- GitLab From e70db68276bd303b9b00eb0fdfaff0b348e5551a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:13 +0200 Subject: [PATCH 0622/9457] powerpc: sysdev: qe_lib: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/powerpc/sysdev/qe_lib/qe.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 238a07b97f2c..a06f83ee63a5 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -693,7 +693,6 @@ static const struct of_device_id qe_ids[] = { static struct platform_driver qe_driver = { .driver = { .name = "fsl-qe", - .owner = THIS_MODULE, .of_match_table = qe_ids, }, .probe = qe_probe, -- GitLab From f8977af9cd970d168f577a1f752ceb991a624fe1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:13 +0200 Subject: [PATCH 0623/9457] s390: appldata: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/s390/appldata/appldata_base.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 47c8630c93cd..15c94246b600 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -511,7 +511,6 @@ static const struct dev_pm_ops appldata_pm_ops = { static struct platform_driver appldata_pdrv = { .driver = { .name = "appldata", - .owner = THIS_MODULE, .pm = &appldata_pm_ops, }, }; -- GitLab From 1d5f672ea10fbe613b5ace0ebe61126845ae9e41 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:14 +0200 Subject: [PATCH 0624/9457] sparc: include: asm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/sparc/include/asm/parport.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index c55291e5b83e..f005ccac91cc 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -238,7 +238,6 @@ static const struct of_device_id ecpp_match[] = { static struct platform_driver ecpp_driver = { .driver = { .name = "ecpp", - .owner = THIS_MODULE, .of_match_table = ecpp_match, }, .probe = ecpp_probe, -- GitLab From de720242625c57b406cc178672ad2f281f36130e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:15 +0200 Subject: [PATCH 0625/9457] sparc: kernel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/sparc/kernel/apc.c | 1 - arch/sparc/kernel/auxio_64.c | 1 - arch/sparc/kernel/central.c | 2 -- arch/sparc/kernel/chmc.c | 1 - arch/sparc/kernel/leon_pci_grpci1.c | 1 - arch/sparc/kernel/leon_pci_grpci2.c | 1 - arch/sparc/kernel/pci_fire.c | 1 - arch/sparc/kernel/pci_psycho.c | 1 - arch/sparc/kernel/pci_sabre.c | 1 - arch/sparc/kernel/pci_schizo.c | 1 - arch/sparc/kernel/pci_sun4v.c | 1 - arch/sparc/kernel/pmc.c | 1 - arch/sparc/kernel/power.c | 1 - arch/sparc/kernel/time_32.c | 1 - arch/sparc/kernel/time_64.c | 3 --- 15 files changed, 18 deletions(-) diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index eefda32b595e..742f6c4436bf 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -178,7 +178,6 @@ MODULE_DEVICE_TABLE(of, apc_match); static struct platform_driver apc_driver = { .driver = { .name = "apc", - .owner = THIS_MODULE, .of_match_table = apc_match, }, .probe = apc_probe, diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 86e55778e4af..086435c17981 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -135,7 +135,6 @@ static struct platform_driver auxio_driver = { .probe = auxio_probe, .driver = { .name = "auxio", - .owner = THIS_MODULE, .of_match_table = auxio_match, }, }; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 052b5a44318f..4696958299e9 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -152,7 +152,6 @@ static struct platform_driver clock_board_driver = { .probe = clock_board_probe, .driver = { .name = "clock_board", - .owner = THIS_MODULE, .of_match_table = clock_board_match, }, }; @@ -257,7 +256,6 @@ static struct platform_driver fhc_driver = { .probe = fhc_probe, .driver = { .name = "fhc", - .owner = THIS_MODULE, .of_match_table = fhc_match, }, }; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index dbb210d74e21..0de4bcb8261f 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -810,7 +810,6 @@ MODULE_DEVICE_TABLE(of, us3mc_match); static struct platform_driver us3mc_driver = { .driver = { .name = "us3mc", - .owner = THIS_MODULE, .of_match_table = us3mc_match, }, .probe = us3mc_probe, diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index c8bf26edfa7c..3382f7b3eeef 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c @@ -708,7 +708,6 @@ static struct of_device_id grpci1_of_match[] = { static struct platform_driver grpci1_of_driver = { .driver = { .name = "grpci1", - .owner = THIS_MODULE, .of_match_table = grpci1_of_match, }, .probe = grpci1_of_probe, diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index e433a4d69fe0..94e392bdee7d 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -900,7 +900,6 @@ static struct of_device_id grpci2_of_match[] = { static struct platform_driver grpci2_of_driver = { .driver = { .name = "grpci2", - .owner = THIS_MODULE, .of_match_table = grpci2_of_match, }, .probe = grpci2_of_probe, diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index e60fc6a67e9b..11a1f0d289d2 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -508,7 +508,6 @@ static const struct of_device_id fire_match[] = { static struct platform_driver fire_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = fire_match, }, .probe = fire_probe, diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index c647634ead2b..7dce27b3c761 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -604,7 +604,6 @@ static const struct of_device_id psycho_match[] = { static struct platform_driver psycho_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = psycho_match, }, .probe = psycho_probe, diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 6f00d27e8dac..00a616ffa35b 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -600,7 +600,6 @@ static const struct of_device_id sabre_match[] = { static struct platform_driver sabre_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = sabre_match, }, .probe = sabre_probe, diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 8f76f23dac38..432b3d63fd14 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1495,7 +1495,6 @@ static const struct of_device_id schizo_match[] = { static struct platform_driver schizo_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = schizo_match, }, .probe = schizo_probe, diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 49d33b178793..47ddbd496a1e 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1010,7 +1010,6 @@ static const struct of_device_id pci_sun4v_match[] = { static struct platform_driver pci_sun4v_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = pci_sun4v_match, }, .probe = pci_sun4v_probe, diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 8b7297faca79..97d123107ecb 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -82,7 +82,6 @@ MODULE_DEVICE_TABLE(of, pmc_match); static struct platform_driver pmc_driver = { .driver = { .name = "pmc", - .owner = THIS_MODULE, .of_match_table = pmc_match, }, .probe = pmc_probe, diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 4cb23c41553f..1836cb965ff8 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -63,7 +63,6 @@ static struct platform_driver power_driver = { .probe = power_probe, .driver = { .name = "power", - .owner = THIS_MODULE, .of_match_table = power_match, }, }; diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 5923d1e4e7c9..2f80d23a0a44 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -322,7 +322,6 @@ static struct platform_driver clock_driver = { .probe = clock_probe, .driver = { .name = "rtc", - .owner = THIS_MODULE, .of_match_table = clock_match, }, }; diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 59da0c3ea788..edbbeb157d46 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -466,7 +466,6 @@ static struct platform_driver rtc_driver = { .probe = rtc_probe, .driver = { .name = "rtc", - .owner = THIS_MODULE, .of_match_table = rtc_match, }, }; @@ -499,7 +498,6 @@ static struct platform_driver bq4802_driver = { .probe = bq4802_probe, .driver = { .name = "bq4802", - .owner = THIS_MODULE, .of_match_table = bq4802_match, }, }; @@ -563,7 +561,6 @@ static struct platform_driver mostek_driver = { .probe = mostek_probe, .driver = { .name = "mostek", - .owner = THIS_MODULE, .of_match_table = mostek_match, }, }; -- GitLab From fe242ccbc0ba730e20091ebd7037730cc81112e1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:15 +0200 Subject: [PATCH 0626/9457] x86: platform: iris: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/x86/platform/iris/iris.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/platform/iris/iris.c b/arch/x86/platform/iris/iris.c index 4d171e8640ef..735ba21efe91 100644 --- a/arch/x86/platform/iris/iris.c +++ b/arch/x86/platform/iris/iris.c @@ -86,7 +86,6 @@ static int iris_remove(struct platform_device *pdev) static struct platform_driver iris_driver = { .driver = { .name = "iris", - .owner = THIS_MODULE, }, .probe = iris_probe, .remove = iris_remove, -- GitLab From b28af12d113ba8f301650f7487df32d439a8f741 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:16 +0200 Subject: [PATCH 0627/9457] x86: platform: olpc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- arch/x86/platform/olpc/olpc-xo1-pm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c index a9acde72d4ed..c5350fd27d70 100644 --- a/arch/x86/platform/olpc/olpc-xo1-pm.c +++ b/arch/x86/platform/olpc/olpc-xo1-pm.c @@ -170,7 +170,6 @@ static int xo1_pm_remove(struct platform_device *pdev) static struct platform_driver cs5535_pms_driver = { .driver = { .name = "cs5535-pms", - .owner = THIS_MODULE, }, .probe = xo1_pm_probe, .remove = xo1_pm_remove, @@ -179,7 +178,6 @@ static struct platform_driver cs5535_pms_driver = { static struct platform_driver cs5535_acpi_driver = { .driver = { .name = "olpc-xo1-pm-acpi", - .owner = THIS_MODULE, }, .probe = xo1_pm_probe, .remove = xo1_pm_remove, -- GitLab From e61bf8d05a2868963277746f2a8a36094bbfd331 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:16 +0200 Subject: [PATCH 0628/9457] acpi: apei: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/acpi/apei/ghes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fc5f780bb61d..868ea63c94c7 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1101,7 +1101,6 @@ static int ghes_remove(struct platform_device *ghes_dev) static struct platform_driver ghes_platform_driver = { .driver = { .name = "GHES", - .owner = THIS_MODULE, }, .probe = ghes_probe, .remove = ghes_remove, -- GitLab From 7ab6c54b5dc15732bf14c29bb21263efa49704bd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:16 +0200 Subject: [PATCH 0629/9457] amba: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/amba/tegra-ahb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index d8961ef4d2e7..c6dc3548e5d1 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -277,7 +277,6 @@ static struct platform_driver tegra_ahb_driver = { .probe = tegra_ahb_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra_ahb_of_match, .pm = &tegra_ahb_pm, }, -- GitLab From 65c662ab63d2055d883bc97386aa779cbbb81f93 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:17 +0200 Subject: [PATCH 0630/9457] ata: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/ata/ahci_da850.c | 1 - drivers/ata/ahci_imx.c | 1 - drivers/ata/ahci_mvebu.c | 1 - drivers/ata/ahci_platform.c | 1 - drivers/ata/ahci_st.c | 1 - drivers/ata/ahci_sunxi.c | 1 - drivers/ata/ahci_xgene.c | 1 - drivers/ata/pata_arasan_cf.c | 1 - drivers/ata/pata_at32.c | 1 - drivers/ata/pata_at91.c | 1 - drivers/ata/pata_bf54x.c | 1 - drivers/ata/pata_ep93xx.c | 1 - drivers/ata/pata_imx.c | 1 - drivers/ata/pata_ixp4xx_cf.c | 1 - drivers/ata/pata_mpc52xx.c | 1 - drivers/ata/pata_octeon_cf.c | 1 - drivers/ata/pata_of_platform.c | 1 - drivers/ata/pata_palmld.c | 1 - drivers/ata/pata_platform.c | 1 - drivers/ata/pata_pxa.c | 1 - drivers/ata/pata_rb532_cf.c | 1 - drivers/ata/pata_samsung_cf.c | 1 - drivers/ata/sata_dwc_460ex.c | 1 - drivers/ata/sata_fsl.c | 1 - drivers/ata/sata_highbank.c | 1 - drivers/ata/sata_mv.c | 1 - drivers/ata/sata_rcar.c | 1 - 27 files changed, 27 deletions(-) diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index ad1e71ec10cf..ce8a7a6d6c7f 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -103,7 +103,6 @@ static struct platform_driver ahci_da850_driver = { .remove = ata_platform_remove_one, .driver = { .name = "ahci_da850", - .owner = THIS_MODULE, .pm = &ahci_da850_pm_ops, }, }; diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index f3970b4ed889..35d51c59a370 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -679,7 +679,6 @@ static struct platform_driver imx_ahci_driver = { .remove = ata_platform_remove_one, .driver = { .name = "ahci-imx", - .owner = THIS_MODULE, .of_match_table = imx_ahci_of_match, .pm = &ahci_imx_pm_ops, }, diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 68672d2692ee..64bb08432b69 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -115,7 +115,6 @@ static struct platform_driver ahci_mvebu_driver = { .remove = ata_platform_remove_one, .driver = { .name = "ahci-mvebu", - .owner = THIS_MODULE, .of_match_table = ahci_mvebu_of_match, }, }; diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 06f1d59fa678..18d539837045 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -76,7 +76,6 @@ static struct platform_driver ahci_driver = { .remove = ata_platform_remove_one, .driver = { .name = "ahci", - .owner = THIS_MODULE, .of_match_table = ahci_of_match, .pm = &ahci_pm_ops, }, diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index 835d6eea84fd..2f9e8317cc16 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c @@ -230,7 +230,6 @@ MODULE_DEVICE_TABLE(of, st_ahci_match); static struct platform_driver st_ahci_driver = { .driver = { .name = "st_ahci", - .owner = THIS_MODULE, .pm = &st_ahci_pm_ops, .of_match_table = of_match_ptr(st_ahci_match), }, diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index e44d675a30ec..afe5581e9b1f 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -238,7 +238,6 @@ static struct platform_driver ahci_sunxi_driver = { .remove = ata_platform_remove_one, .driver = { .name = "ahci-sunxi", - .owner = THIS_MODULE, .of_match_table = ahci_sunxi_of_match, .pm = &ahci_sunxi_pm_ops, }, diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 0f8538f238b6..feeb8f1e2fe8 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -544,7 +544,6 @@ static struct platform_driver xgene_ahci_driver = { .remove = ata_platform_remove_one, .driver = { .name = "xgene-ahci", - .owner = THIS_MODULE, .of_match_table = xgene_ahci_of_match, }, }; diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 38216b991474..a9b0c820f2eb 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -961,7 +961,6 @@ static struct platform_driver arasan_cf_driver = { .remove = arasan_cf_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &arasan_cf_pm_ops, .of_match_table = of_match_ptr(arasan_cf_id_table), }, diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index d59d5239405f..9aeb7a6dd4d4 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -389,7 +389,6 @@ static struct platform_driver pata_at32_driver = { .remove = __exit_p(pata_at32_remove), .driver = { .name = "at32_ide", - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 8a66f23af4c4..9e85937d36a9 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -444,7 +444,6 @@ static struct platform_driver pata_at91_driver = { .remove = pata_at91_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 03f2f2bc83bd..dd7410019d15 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1657,7 +1657,6 @@ static struct platform_driver bfin_atapi_driver = { .resume = bfin_atapi_resume, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index 4d37c5415fc7..bd6b089c67a3 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -1021,7 +1021,6 @@ static int ep93xx_pata_remove(struct platform_device *pdev) static struct platform_driver ep93xx_pata_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ep93xx_pata_probe, .remove = ep93xx_pata_remove, diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index 989ff5ac69ec..139d20778b29 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c @@ -240,7 +240,6 @@ static struct platform_driver pata_imx_driver = { .driver = { .name = DRV_NAME, .of_match_table = imx_pata_dt_ids, - .owner = THIS_MODULE, .pm = &pata_imx_pm_ops, }, }; diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index ddf470c2341d..abda44183512 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -193,7 +193,6 @@ static int ixp4xx_pata_probe(struct platform_device *pdev) static struct platform_driver ixp4xx_pata_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ixp4xx_pata_probe, .remove = ata_platform_remove_one, diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index ccd1c83a05cc..252ba27fa63b 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -863,7 +863,6 @@ static struct platform_driver mpc52xx_ata_of_platform_driver = { #endif .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = mpc52xx_ata_of_match, }, }; diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 2a97d3a531ec..80a80548ad0a 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -1059,7 +1059,6 @@ static struct platform_driver octeon_cf_driver = { .probe = octeon_cf_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = octeon_cf_match, .shutdown = octeon_cf_shutdown }, diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 64965398914a..dcc408abe171 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -75,7 +75,6 @@ MODULE_DEVICE_TABLE(of, pata_of_platform_match); static struct platform_driver pata_of_platform_driver = { .driver = { .name = "pata_of_platform", - .owner = THIS_MODULE, .of_match_table = pata_of_platform_match, }, .probe = pata_of_platform_probe, diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index df2bb7504fc8..8c0d7d736b7a 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c @@ -124,7 +124,6 @@ static int palmld_pata_remove(struct platform_device *dev) static struct platform_driver palmld_pata_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = palmld_pata_probe, .remove = palmld_pata_remove, diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index f8cff3e247c5..1eedfe46d7c8 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -224,7 +224,6 @@ static struct platform_driver pata_platform_driver = { .remove = ata_platform_remove_one, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 73259bfda1e3..c36b3e6531d8 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -385,7 +385,6 @@ static struct platform_driver pxa_ata_driver = { .remove = pxa_ata_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 3c5eb8fa6bd1..6d08446b877c 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -193,7 +193,6 @@ static struct platform_driver rb532_pata_platform_driver = { .remove = rb532_pata_driver_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 1a24a5dc3940..fa44eb2872db 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -656,7 +656,6 @@ static struct platform_driver pata_s3c_driver = { .id_table = pata_s3c_driver_ids, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, #ifdef CONFIG_PM_SLEEP .pm = &pata_s3c_pm_ops, #endif diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 0bb2cabd2197..c7ddef89e7b0 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1807,7 +1807,6 @@ MODULE_DEVICE_TABLE(of, sata_dwc_match); static struct platform_driver sata_dwc_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = sata_dwc_match, }, .probe = sata_dwc_probe, diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 07bc7e4dbd04..42174158d10f 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1624,7 +1624,6 @@ MODULE_DEVICE_TABLE(of, fsl_sata_match); static struct platform_driver fsl_sata_driver = { .driver = { .name = "fsl-sata", - .owner = THIS_MODULE, .of_match_table = fsl_sata_match, }, .probe = sata_fsl_probe, diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index ce2b99a1ed70..24e311fe2c1c 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -634,7 +634,6 @@ static struct platform_driver ahci_highbank_driver = { .remove = ata_platform_remove_one, .driver = { .name = "highbank-ahci", - .owner = THIS_MODULE, .of_match_table = ahci_of_match, .pm = &ahci_highbank_pm_ops, }, diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 391cfda1e83f..f9a0e34eb111 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4280,7 +4280,6 @@ static struct platform_driver mv_platform_driver = { .resume = mv_platform_resume, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mv_sata_dt_ids), }, }; diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 61eb6d77dac7..ad7725245d39 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -989,7 +989,6 @@ static struct platform_driver sata_rcar_driver = { .id_table = sata_rcar_id_table, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = sata_rcar_match, #ifdef CONFIG_PM_SLEEP .pm = &sata_rcar_pm_ops, -- GitLab From a9add3339b9ebf0930bd6fb698c5b51e42f48de2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:18 +0200 Subject: [PATCH 0631/9457] atm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/atm/fore200e.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index d4725fc0395d..d5d9eafbbfcf 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2687,7 +2687,6 @@ MODULE_DEVICE_TABLE(of, fore200e_sba_match); static struct platform_driver fore200e_sba_driver = { .driver = { .name = "fore_200e", - .owner = THIS_MODULE, .of_match_table = fore200e_sba_match, }, .probe = fore200e_sba_probe, -- GitLab From 8294adb90b4645812ef5f720d5661315b80bd9c7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:18 +0200 Subject: [PATCH 0632/9457] block: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/block/amiflop.c | 1 - drivers/block/mg_disk.c | 1 - drivers/block/swim.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 758da2287d9a..5fd50a284168 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1864,7 +1864,6 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev) static struct platform_driver amiga_floppy_driver = { .driver = { .name = "amiga-floppy", - .owner = THIS_MODULE, }, }; diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index e352cac707e8..145ce2aa2e78 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -1082,7 +1082,6 @@ static struct platform_driver mg_disk_driver = { .remove = mg_remove, .driver = { .name = MG_DEV_NAME, - .owner = THIS_MODULE, .pm = &mg_pm, } }; diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 6b44bbe528b7..b5afd495d482 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -971,7 +971,6 @@ static struct platform_driver swim_driver = { .remove = swim_remove, .driver = { .name = CARDNAME, - .owner = THIS_MODULE, }, }; -- GitLab From bacc3ea94f9a79e7f3711ace506272a019838fbd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:19 +0200 Subject: [PATCH 0633/9457] bluetooth: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/bluetooth/btwilink.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index f038dba19e36..55c135b7757a 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c @@ -349,7 +349,6 @@ static struct platform_driver btwilink_driver = { .remove = bt_ti_remove, .driver = { .name = "btwilink", - .owner = THIS_MODULE, }, }; -- GitLab From 571b8c6adb1b48046ee2dc5e67ed161a4b5c33cf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:19 +0200 Subject: [PATCH 0634/9457] bus: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/bus/brcmstb_gisb.c | 1 - drivers/bus/imx-weim.c | 1 - drivers/bus/omap-ocp2scp.c | 1 - drivers/bus/omap_l3_noc.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index f2cd6a2d40b4..5b15cd2cbd8e 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -276,7 +276,6 @@ static struct platform_driver brcmstb_gisb_arb_driver = { .probe = brcmstb_gisb_arb_probe, .driver = { .name = "brcm-gisb-arb", - .owner = THIS_MODULE, .of_match_table = brcmstb_gisb_arb_of_match, }, }; diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index 75c9681f8021..0958b6981773 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c @@ -206,7 +206,6 @@ static int __init weim_probe(struct platform_device *pdev) static struct platform_driver weim_driver = { .driver = { .name = "imx-weim", - .owner = THIS_MODULE, .of_match_table = weim_id_table, }, }; diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c index 5511f9814ddd..723ec06ad2c8 100644 --- a/drivers/bus/omap-ocp2scp.c +++ b/drivers/bus/omap-ocp2scp.c @@ -77,7 +77,6 @@ static struct platform_driver omap_ocp2scp_driver = { .remove = omap_ocp2scp_remove, .driver = { .name = "omap-ocp2scp", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(omap_ocp2scp_id_table), }, }; diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c index 531ae591783b..1ff1863415c5 100644 --- a/drivers/bus/omap_l3_noc.c +++ b/drivers/bus/omap_l3_noc.c @@ -300,7 +300,6 @@ static struct platform_driver omap_l3_driver = { .probe = omap_l3_probe, .driver = { .name = "omap_l3_noc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(l3_noc_match), }, }; -- GitLab From 06861ab52b4c355d65c8a72aa3817261158cc409 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:19 +0200 Subject: [PATCH 0635/9457] char: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/char/sonypi.c | 1 - drivers/char/tb0219.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 7cc1fe2241fd..e496daefe9e0 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1482,7 +1482,6 @@ static void sonypi_shutdown(struct platform_device *dev) static struct platform_driver sonypi_driver = { .driver = { .name = "sonypi", - .owner = THIS_MODULE, .pm = SONYPI_PM, }, .probe = sonypi_probe, diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 47b9fdfcf083..480a777db577 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -337,7 +337,6 @@ static struct platform_driver tb0219_device_driver = { .remove = tb0219_remove, .driver = { .name = "TB0219", - .owner = THIS_MODULE, }, }; -- GitLab From eff54802fe981a378555aebd86af0d11e83899ff Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:20 +0200 Subject: [PATCH 0636/9457] char: hw_random: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/char/hw_random/atmel-rng.c | 1 - drivers/char/hw_random/bcm2835-rng.c | 1 - drivers/char/hw_random/bcm63xx-rng.c | 1 - drivers/char/hw_random/exynos-rng.c | 1 - drivers/char/hw_random/msm-rng.c | 1 - drivers/char/hw_random/mxc-rnga.c | 1 - drivers/char/hw_random/n2-drv.c | 1 - drivers/char/hw_random/octeon-rng.c | 1 - drivers/char/hw_random/omap-rng.c | 1 - drivers/char/hw_random/omap3-rom-rng.c | 1 - drivers/char/hw_random/pasemi-rng.c | 1 - drivers/char/hw_random/ppc4xx-rng.c | 1 - drivers/char/hw_random/timeriomem-rng.c | 1 - drivers/char/hw_random/tx4939-rng.c | 1 - 14 files changed, 14 deletions(-) diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 851bc7e20ad2..25a4de21feac 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -128,7 +128,6 @@ static struct platform_driver atmel_trng_driver = { .remove = atmel_trng_remove, .driver = { .name = "atmel-trng", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &atmel_trng_pm_ops, #endif /* CONFIG_PM */ diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c index e900961cdd2e..7192ec25f667 100644 --- a/drivers/char/hw_random/bcm2835-rng.c +++ b/drivers/char/hw_random/bcm2835-rng.c @@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match); static struct platform_driver bcm2835_rng_driver = { .driver = { .name = "bcm2835-rng", - .owner = THIS_MODULE, .of_match_table = bcm2835_rng_of_match, }, .probe = bcm2835_rng_probe, diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index 36581ea562cb..ba6a65ac023b 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -162,7 +162,6 @@ static struct platform_driver bcm63xx_rng_driver = { .remove = bcm63xx_rng_remove, .driver = { .name = "bcm63xx-rng", - .owner = THIS_MODULE, }, }; diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c index 9f8277cc44b4..beaa157bf43e 100644 --- a/drivers/char/hw_random/exynos-rng.c +++ b/drivers/char/hw_random/exynos-rng.c @@ -169,7 +169,6 @@ static UNIVERSAL_DEV_PM_OPS(exynos_rng_pm_ops, exynos_rng_runtime_suspend, static struct platform_driver exynos_rng_driver = { .driver = { .name = "exynos-rng", - .owner = THIS_MODULE, .pm = &exynos_rng_pm_ops, }, .probe = exynos_rng_probe, diff --git a/drivers/char/hw_random/msm-rng.c b/drivers/char/hw_random/msm-rng.c index 148521e51dc6..cea1c703d62f 100644 --- a/drivers/char/hw_random/msm-rng.c +++ b/drivers/char/hw_random/msm-rng.c @@ -185,7 +185,6 @@ static struct platform_driver msm_rng_driver = { .remove = msm_rng_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(msm_rng_of_match), } }; diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 6a86b6f56af2..6cbb72ec6013 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c @@ -206,7 +206,6 @@ static int __exit mxc_rnga_remove(struct platform_device *pdev) static struct platform_driver mxc_rnga_driver = { .driver = { .name = "mxc_rnga", - .owner = THIS_MODULE, }, .remove = __exit_p(mxc_rnga_remove), }; diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 292a5889f675..843d6f6aee7a 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -750,7 +750,6 @@ MODULE_DEVICE_TABLE(of, n2rng_match); static struct platform_driver n2rng_driver = { .driver = { .name = "n2rng", - .owner = THIS_MODULE, .of_match_table = n2rng_match, }, .probe = n2rng_probe, diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c index b5cc3420c659..be1c3f607398 100644 --- a/drivers/char/hw_random/octeon-rng.c +++ b/drivers/char/hw_random/octeon-rng.c @@ -117,7 +117,6 @@ static int __exit octeon_rng_remove(struct platform_device *pdev) static struct platform_driver octeon_rng_driver = { .driver = { .name = "octeon_rng", - .owner = THIS_MODULE, }, .probe = octeon_rng_probe, .remove = __exit_p(octeon_rng_remove), diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index f66ea258382f..d14dcf788f17 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -456,7 +456,6 @@ static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); static struct platform_driver omap_rng_driver = { .driver = { .name = "omap_rng", - .owner = THIS_MODULE, .pm = OMAP_RNG_PM, .of_match_table = of_match_ptr(omap_rng_of_match), }, diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index 6f2eaffed623..a405cdcd8dd2 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -126,7 +126,6 @@ static int omap3_rom_rng_remove(struct platform_device *pdev) static struct platform_driver omap3_rom_rng_driver = { .driver = { .name = "omap3-rom-rng", - .owner = THIS_MODULE, }, .probe = omap3_rom_rng_probe, .remove = omap3_rom_rng_remove, diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index c0347d1dded0..3eb7bdd7f93b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -142,7 +142,6 @@ static struct of_device_id rng_match[] = { static struct platform_driver rng_driver = { .driver = { .name = "pasemi-rng", - .owner = THIS_MODULE, .of_match_table = rng_match, }, .probe = rng_probe, diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c index 521f76b0934b..c85d31a5f9e3 100644 --- a/drivers/char/hw_random/ppc4xx-rng.c +++ b/drivers/char/hw_random/ppc4xx-rng.c @@ -133,7 +133,6 @@ static struct of_device_id ppc4xx_rng_match[] = { static struct platform_driver ppc4xx_rng_driver = { .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, .of_match_table = ppc4xx_rng_match, }, .probe = ppc4xx_rng_probe, diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index b6ab9ac3f34d..cf37db263ecd 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c @@ -200,7 +200,6 @@ MODULE_DEVICE_TABLE(of, timeriomem_rng_match); static struct platform_driver timeriomem_rng_driver = { .driver = { .name = "timeriomem_rng", - .owner = THIS_MODULE, .of_match_table = timeriomem_rng_match, }, .probe = timeriomem_rng_probe, diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 09c5fbea2b93..a7b694913416 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c @@ -158,7 +158,6 @@ static int __exit tx4939_rng_remove(struct platform_device *dev) static struct platform_driver tx4939_rng_driver = { .driver = { .name = "tx4939-rng", - .owner = THIS_MODULE, }, .remove = tx4939_rng_remove, }; -- GitLab From 394b3d078dfe0e7fbd4507cb2382de6736f70cb2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:20 +0200 Subject: [PATCH 0637/9457] char: ipmi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/char/ipmi/ipmi_si_intf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5c4e1f625bbb..84eb2db85534 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2751,7 +2751,6 @@ static struct of_device_id ipmi_match[] = static struct platform_driver ipmi_driver = { .driver = { .name = DEVICE_NAME, - .owner = THIS_MODULE, .of_match_table = ipmi_match, }, .probe = ipmi_probe, -- GitLab From 05e6cc68afbe445382ab201b2b29ff0fcddec0be Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:21 +0200 Subject: [PATCH 0638/9457] char: tpm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/char/tpm/tpm_atmel.c | 1 - drivers/char/tpm/tpm_nsc.c | 1 - drivers/char/tpm/tpm_tis.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 6069d13ae4ac..435c8b9dd2f8 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -152,7 +152,6 @@ static SIMPLE_DEV_PM_OPS(tpm_atml_pm, tpm_pm_suspend, tpm_pm_resume); static struct platform_driver atml_drv = { .driver = { .name = "tpm_atmel", - .owner = THIS_MODULE, .pm = &tpm_atml_pm, }, }; diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 3179ec9cffdc..4d0a17ea8cde 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -258,7 +258,6 @@ static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); static struct platform_driver nsc_drv = { .driver = { .name = "tpm_nsc", - .owner = THIS_MODULE, .pm = &tpm_nsc_pm, }, }; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 2c46734b266d..6f1985496112 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -837,7 +837,6 @@ MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); static struct platform_driver tis_drv = { .driver = { .name = "tpm_tis", - .owner = THIS_MODULE, .pm = &tpm_tis_pm, }, }; -- GitLab From 71379accaff8bcf33985f75adeabcbd21b4f1462 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:21 +0200 Subject: [PATCH 0639/9457] char: xillybus: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/char/xillybus/xillybus_of.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/char/xillybus/xillybus_of.c b/drivers/char/xillybus/xillybus_of.c index 1ca0c7a4f1be..2002a3a28146 100644 --- a/drivers/char/xillybus/xillybus_of.c +++ b/drivers/char/xillybus/xillybus_of.c @@ -179,7 +179,6 @@ static struct platform_driver xillybus_platform_driver = { .remove = xilly_drv_remove, .driver = { .name = xillyname, - .owner = THIS_MODULE, .of_match_table = xillybus_of_match, }, }; -- GitLab From a4ae8f3b0f7ac6ab33d28b36da39a4c2601ce886 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:22 +0200 Subject: [PATCH 0640/9457] clk: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/clk/clk-axm5516.c | 1 - drivers/clk/clk-ppc-corenet.c | 1 - drivers/clk/clk-s2mps11.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c index d2f1e119b450..0f6368ceec4c 100644 --- a/drivers/clk/clk-axm5516.c +++ b/drivers/clk/clk-axm5516.c @@ -593,7 +593,6 @@ static struct platform_driver axmclk_driver = { .remove = axmclk_remove, .driver = { .name = "clk-axm5516", - .owner = THIS_MODULE, .of_match_table = axmclk_match_table, }, }; diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index 8e58edfeeb37..b6e6c85507a5 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -294,7 +294,6 @@ static const struct of_device_id ppc_clk_ids[] __initconst = { static struct platform_driver ppc_corenet_clk_driver __initdata = { .driver = { .name = "ppc_corenet_clock", - .owner = THIS_MODULE, .of_match_table = ppc_clk_ids, }, .probe = ppc_corenet_clk_probe, diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index b7797fb12e12..b1fb9a137688 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -288,7 +288,6 @@ MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); static struct platform_driver s2mps11_clk_driver = { .driver = { .name = "s2mps11-clk", - .owner = THIS_MODULE, }, .probe = s2mps11_clk_probe, .remove = s2mps11_clk_remove, -- GitLab From 1f46c71d6e820cbd82a19790185680cc2ca31b98 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:22 +0200 Subject: [PATCH 0641/9457] clk: qcom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/clk/qcom/gcc-apq8084.c | 1 - drivers/clk/qcom/gcc-ipq806x.c | 1 - drivers/clk/qcom/gcc-msm8660.c | 1 - drivers/clk/qcom/gcc-msm8960.c | 1 - drivers/clk/qcom/gcc-msm8974.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c index ee52eb1c838a..e3ef90264214 100644 --- a/drivers/clk/qcom/gcc-apq8084.c +++ b/drivers/clk/qcom/gcc-apq8084.c @@ -3589,7 +3589,6 @@ static struct platform_driver gcc_apq8084_driver = { .remove = gcc_apq8084_remove, .driver = { .name = "gcc-apq8084", - .owner = THIS_MODULE, .of_match_table = gcc_apq8084_match_table, }, }; diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index 5cd62a709ac7..afed5eb0691e 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -2431,7 +2431,6 @@ static struct platform_driver gcc_ipq806x_driver = { .remove = gcc_ipq806x_remove, .driver = { .name = "gcc-ipq806x", - .owner = THIS_MODULE, .of_match_table = gcc_ipq806x_match_table, }, }; diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index 0c4b727ae429..f366e68f7316 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c @@ -2744,7 +2744,6 @@ static struct platform_driver gcc_msm8660_driver = { .remove = gcc_msm8660_remove, .driver = { .name = "gcc-msm8660", - .owner = THIS_MODULE, .of_match_table = gcc_msm8660_match_table, }, }; diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 007534f7a2d7..b0b562b9ce0e 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -3519,7 +3519,6 @@ static struct platform_driver gcc_msm8960_driver = { .remove = gcc_msm8960_remove, .driver = { .name = "gcc-msm8960", - .owner = THIS_MODULE, .of_match_table = gcc_msm8960_match_table, }, }; diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 7af7c18d2144..a6937fe78d8a 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -2737,7 +2737,6 @@ static struct platform_driver gcc_msm8974_driver = { .remove = gcc_msm8974_remove, .driver = { .name = "gcc-msm8974", - .owner = THIS_MODULE, .of_match_table = gcc_msm8974_match_table, }, }; -- GitLab From c8da4a0ec6bad4b54a5e2aeda7878605c6e9d6b7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:22 +0200 Subject: [PATCH 0642/9457] clk: samsung: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/clk/samsung/clk-exynos-audss.c | 1 - drivers/clk/samsung/clk-s5pv210-audss.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 13eae14c2cc2..acce708ace18 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -223,7 +223,6 @@ static int exynos_audss_clk_remove(struct platform_device *pdev) static struct platform_driver exynos_audss_clk_driver = { .driver = { .name = "exynos-audss-clk", - .owner = THIS_MODULE, .of_match_table = exynos_audss_clk_of_match, }, .probe = exynos_audss_clk_probe, diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index a8053b4aca56..de4455b75e8a 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -216,7 +216,6 @@ static const struct of_device_id s5pv210_audss_clk_of_match[] = { static struct platform_driver s5pv210_audss_clk_driver = { .driver = { .name = "s5pv210-audss-clk", - .owner = THIS_MODULE, .of_match_table = s5pv210_audss_clk_of_match, }, .probe = s5pv210_audss_clk_probe, -- GitLab From 661ff5be95903a37e7a61e8157b197689a6f755a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:23 +0200 Subject: [PATCH 0643/9457] clk: ux500: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/clk/ux500/abx500-clk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index e7bd62cf60b3..3e5e05101302 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c @@ -121,7 +121,6 @@ static int abx500_clk_probe(struct platform_device *pdev) static struct platform_driver abx500_clk_driver = { .driver = { .name = "abx500-clk", - .owner = THIS_MODULE, }, .probe = abx500_clk_probe, }; -- GitLab From e030f980b3ed2d9f3a3e37f3e6941494c7c0c471 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:23 +0200 Subject: [PATCH 0644/9457] clk: x86: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/clk/x86/clk-lpt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 812f83f8b0c6..f827083defc4 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -42,7 +42,6 @@ static int lpt_clk_probe(struct platform_device *pdev) static struct platform_driver lpt_clk_driver = { .driver = { .name = "clk-lpt", - .owner = THIS_MODULE, }, .probe = lpt_clk_probe, }; -- GitLab From 30f51f248c1d0987733353b64adae26b23165908 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:24 +0200 Subject: [PATCH 0645/9457] cpufreq: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/cpufreq/arm_big_little_dt.c | 1 - drivers/cpufreq/cpufreq-dt.c | 1 - drivers/cpufreq/davinci-cpufreq.c | 1 - drivers/cpufreq/dbx500-cpufreq.c | 1 - drivers/cpufreq/exynos-cpufreq.c | 1 - drivers/cpufreq/exynos5440-cpufreq.c | 1 - drivers/cpufreq/imx6q-cpufreq.c | 1 - drivers/cpufreq/integrator-cpufreq.c | 1 - drivers/cpufreq/kirkwood-cpufreq.c | 1 - drivers/cpufreq/loongson2_cpufreq.c | 1 - drivers/cpufreq/omap-cpufreq.c | 1 - drivers/cpufreq/s5pv210-cpufreq.c | 1 - drivers/cpufreq/spear-cpufreq.c | 1 - drivers/cpufreq/vexpress-spc-cpufreq.c | 1 - 14 files changed, 14 deletions(-) diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 4550f6976768..efa8efae50d1 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -105,7 +105,6 @@ static int generic_bL_remove(struct platform_device *pdev) static struct platform_driver generic_bL_platdrv = { .driver = { .name = "arm-bL-cpufreq-dt", - .owner = THIS_MODULE, }, .probe = generic_bL_probe, .remove = generic_bL_remove, diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 6bbb8b913446..941836731116 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -351,7 +351,6 @@ static int dt_cpufreq_remove(struct platform_device *pdev) static struct platform_driver dt_cpufreq_platdrv = { .driver = { .name = "cpufreq-dt", - .owner = THIS_MODULE, }, .probe = dt_cpufreq_probe, .remove = dt_cpufreq_remove, diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 28a16dc6e02e..7e336d20c184 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -169,7 +169,6 @@ static int __exit davinci_cpufreq_remove(struct platform_device *pdev) static struct platform_driver davinci_cpufreq_driver = { .driver = { .name = "cpufreq-davinci", - .owner = THIS_MODULE, }, .remove = __exit_p(davinci_cpufreq_remove), }; diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 4bebc1b5db48..5c3ec1dd4921 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c @@ -69,7 +69,6 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev) static struct platform_driver dbx500_cpufreq_plat_driver = { .driver = { .name = "cpufreq-ux500", - .owner = THIS_MODULE, }, .probe = dbx500_cpufreq_probe, }; diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 1e0ec57bf6e3..f99a0b0b7c06 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -211,7 +211,6 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) static struct platform_driver exynos_cpufreq_platdrv = { .driver = { .name = "exynos-cpufreq", - .owner = THIS_MODULE, }, .probe = exynos_cpufreq_probe, }; diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index f33f25b483ca..3e7a03620f37 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -439,7 +439,6 @@ static int exynos_cpufreq_remove(struct platform_device *pdev) static struct platform_driver exynos_cpufreq_platdrv = { .driver = { .name = "exynos5440-cpufreq", - .owner = THIS_MODULE, .of_match_table = exynos_cpufreq_match, }, .probe = exynos_cpufreq_probe, diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index c2d30765bf3d..b2d0bc137f34 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -348,7 +348,6 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev) static struct platform_driver imx6q_cpufreq_platdrv = { .driver = { .name = "imx6q-cpufreq", - .owner = THIS_MODULE, }, .probe = imx6q_cpufreq_probe, .remove = imx6q_cpufreq_remove, diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index 6bd69adc3c5e..129e266f7621 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c @@ -226,7 +226,6 @@ static const struct of_device_id integrator_cpufreq_match[] = { static struct platform_driver integrator_cpufreq_driver = { .driver = { .name = "integrator-cpufreq", - .owner = THIS_MODULE, .of_match_table = integrator_cpufreq_match, }, .remove = __exit_p(integrator_cpufreq_remove), diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index 7906d4acfe40..be42f103db60 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -183,7 +183,6 @@ static struct platform_driver kirkwood_cpufreq_platform_driver = { .remove = kirkwood_cpufreq_remove, .driver = { .name = "kirkwood-cpufreq", - .owner = THIS_MODULE, }, }; diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index 9fa177206032..fc897babab55 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c @@ -130,7 +130,6 @@ MODULE_DEVICE_TABLE(platform, platform_device_ids); static struct platform_driver platform_driver = { .driver = { .name = "loongson2_cpufreq", - .owner = THIS_MODULE, }, .id_table = platform_device_ids, }; diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 5f69c9aa703c..e3866e0d5bf8 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -195,7 +195,6 @@ static int omap_cpufreq_remove(struct platform_device *pdev) static struct platform_driver omap_cpufreq_platdrv = { .driver = { .name = "omap-cpufreq", - .owner = THIS_MODULE, }, .probe = omap_cpufreq_probe, .remove = omap_cpufreq_remove, diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 567caa6313ff..b0dac7d6ba31 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -656,7 +656,6 @@ static int s5pv210_cpufreq_probe(struct platform_device *pdev) static struct platform_driver s5pv210_cpufreq_platdrv = { .driver = { .name = "s5pv210-cpufreq", - .owner = THIS_MODULE, }, .probe = s5pv210_cpufreq_probe, }; diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 38678396636d..4894924a3ca2 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -236,7 +236,6 @@ static int spear_cpufreq_probe(struct platform_device *pdev) static struct platform_driver spear_cpufreq_platdrv = { .driver = { .name = "spear-cpufreq", - .owner = THIS_MODULE, }, .probe = spear_cpufreq_probe, }; diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c index 7f7c9c01b44e..433e93fd4900 100644 --- a/drivers/cpufreq/vexpress-spc-cpufreq.c +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c @@ -60,7 +60,6 @@ static int ve_spc_cpufreq_remove(struct platform_device *pdev) static struct platform_driver ve_spc_cpufreq_platdrv = { .driver = { .name = "vexpress-spc-cpufreq", - .owner = THIS_MODULE, }, .probe = ve_spc_cpufreq_probe, .remove = ve_spc_cpufreq_remove, -- GitLab From c6ec883212a9f7a341c16dc141e41c40b2b2c238 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:24 +0200 Subject: [PATCH 0646/9457] cpuidle: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/cpuidle/cpuidle-at91.c | 1 - drivers/cpuidle/cpuidle-calxeda.c | 1 - drivers/cpuidle/cpuidle-clps711x.c | 1 - drivers/cpuidle/cpuidle-exynos.c | 1 - drivers/cpuidle/cpuidle-kirkwood.c | 1 - drivers/cpuidle/cpuidle-mvebu-v7.c | 3 --- drivers/cpuidle/cpuidle-ux500.c | 1 - drivers/cpuidle/cpuidle-zynq.c | 1 - 8 files changed, 10 deletions(-) diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c index a0774370c6bc..f63a7d41f4f3 100644 --- a/drivers/cpuidle/cpuidle-at91.c +++ b/drivers/cpuidle/cpuidle-at91.c @@ -61,7 +61,6 @@ static int at91_cpuidle_probe(struct platform_device *dev) static struct platform_driver at91_cpuidle_driver = { .driver = { .name = "cpuidle-at91", - .owner = THIS_MODULE, }, .probe = at91_cpuidle_probe, }; diff --git a/drivers/cpuidle/cpuidle-calxeda.c b/drivers/cpuidle/cpuidle-calxeda.c index 6e51114057d0..11b0466e4a97 100644 --- a/drivers/cpuidle/cpuidle-calxeda.c +++ b/drivers/cpuidle/cpuidle-calxeda.c @@ -73,7 +73,6 @@ static int calxeda_cpuidle_probe(struct platform_device *pdev) static struct platform_driver calxeda_cpuidle_plat_driver = { .driver = { .name = "cpuidle-calxeda", - .owner = THIS_MODULE, }, .probe = calxeda_cpuidle_probe, }; diff --git a/drivers/cpuidle/cpuidle-clps711x.c b/drivers/cpuidle/cpuidle-clps711x.c index 5243811daa6e..18a7f7380508 100644 --- a/drivers/cpuidle/cpuidle-clps711x.c +++ b/drivers/cpuidle/cpuidle-clps711x.c @@ -54,7 +54,6 @@ static int __init clps711x_cpuidle_probe(struct platform_device *pdev) static struct platform_driver clps711x_cpuidle_driver = { .driver = { .name = CLPS711X_CPUIDLE_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver_probe(clps711x_cpuidle_driver, clps711x_cpuidle_probe); diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c index ba9b34b579f3..1b64cc97a6a8 100644 --- a/drivers/cpuidle/cpuidle-exynos.c +++ b/drivers/cpuidle/cpuidle-exynos.c @@ -75,7 +75,6 @@ static struct platform_driver exynos_cpuidle_driver = { .probe = exynos_cpuidle_probe, .driver = { .name = "exynos_cpuidle", - .owner = THIS_MODULE, }, }; diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c index 41ba843251b8..10984b4be6df 100644 --- a/drivers/cpuidle/cpuidle-kirkwood.c +++ b/drivers/cpuidle/cpuidle-kirkwood.c @@ -78,7 +78,6 @@ static struct platform_driver kirkwood_cpuidle_driver = { .remove = kirkwood_cpuidle_remove, .driver = { .name = "kirkwood_cpuidle", - .owner = THIS_MODULE, }, }; diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c index 45371bb16214..58fa4e9d7049 100644 --- a/drivers/cpuidle/cpuidle-mvebu-v7.c +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c @@ -118,7 +118,6 @@ static int mvebu_v7_cpuidle_probe(struct platform_device *pdev) static struct platform_driver armadaxp_cpuidle_plat_driver = { .driver = { .name = "cpuidle-armada-xp", - .owner = THIS_MODULE, }, .probe = mvebu_v7_cpuidle_probe, }; @@ -128,7 +127,6 @@ module_platform_driver(armadaxp_cpuidle_plat_driver); static struct platform_driver armada370_cpuidle_plat_driver = { .driver = { .name = "cpuidle-armada-370", - .owner = THIS_MODULE, }, .probe = mvebu_v7_cpuidle_probe, }; @@ -138,7 +136,6 @@ module_platform_driver(armada370_cpuidle_plat_driver); static struct platform_driver armada38x_cpuidle_plat_driver = { .driver = { .name = "cpuidle-armada-38x", - .owner = THIS_MODULE, }, .probe = mvebu_v7_cpuidle_probe, }; diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c index 5e35804b1a95..56fb729dac64 100644 --- a/drivers/cpuidle/cpuidle-ux500.c +++ b/drivers/cpuidle/cpuidle-ux500.c @@ -123,7 +123,6 @@ static int dbx500_cpuidle_probe(struct platform_device *pdev) static struct platform_driver dbx500_cpuidle_plat_driver = { .driver = { .name = "cpuidle-dbx500", - .owner = THIS_MODULE, }, .probe = dbx500_cpuidle_probe, }; diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c index c61b8b2a7c77..8396a57790a5 100644 --- a/drivers/cpuidle/cpuidle-zynq.c +++ b/drivers/cpuidle/cpuidle-zynq.c @@ -72,7 +72,6 @@ static int zynq_cpuidle_probe(struct platform_device *pdev) static struct platform_driver zynq_cpuidle_driver = { .driver = { .name = "cpuidle-zynq", - .owner = THIS_MODULE, }, .probe = zynq_cpuidle_probe, }; -- GitLab From 5573bc03c63e4be7de501a91cca2acc5a44ec4dd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:25 +0200 Subject: [PATCH 0647/9457] crypto: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/atmel-aes.c | 1 - drivers/crypto/atmel-sha.c | 1 - drivers/crypto/atmel-tdes.c | 1 - drivers/crypto/bfin_crc.c | 1 - drivers/crypto/mv_cesa.c | 1 - drivers/crypto/mxs-dcp.c | 1 - drivers/crypto/n2_core.c | 2 -- drivers/crypto/omap-aes.c | 1 - drivers/crypto/omap-des.c | 1 - drivers/crypto/omap-sham.c | 1 - drivers/crypto/s5p-sss.c | 1 - drivers/crypto/sahara.c | 1 - drivers/crypto/talitos.c | 1 - 13 files changed, 14 deletions(-) diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index a083474991ab..53d1c330f8a8 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c @@ -1473,7 +1473,6 @@ static struct platform_driver atmel_aes_driver = { .remove = atmel_aes_remove, .driver = { .name = "atmel_aes", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_aes_dt_ids), }, }; diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 9a4f69eaa5e0..d94f07c78e19 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -1529,7 +1529,6 @@ static struct platform_driver atmel_sha_driver = { .remove = atmel_sha_remove, .driver = { .name = "atmel_sha", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_sha_dt_ids), }, }; diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index d3a9041938ea..5e7c896cde30 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c @@ -1524,7 +1524,6 @@ static struct platform_driver atmel_tdes_driver = { .remove = atmel_tdes_remove, .driver = { .name = "atmel_tdes", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_tdes_dt_ids), }, }; diff --git a/drivers/crypto/bfin_crc.c b/drivers/crypto/bfin_crc.c index b099e33cb073..ef5b58ad49ad 100644 --- a/drivers/crypto/bfin_crc.c +++ b/drivers/crypto/bfin_crc.c @@ -724,7 +724,6 @@ static struct platform_driver bfin_crypto_crc_driver = { .resume = bfin_crypto_crc_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 032c72c1f953..f91f15ddee92 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -1180,7 +1180,6 @@ static struct platform_driver marvell_crypto = { .probe = mv_probe, .remove = mv_remove, .driver = { - .owner = THIS_MODULE, .name = "mv_crypto", .of_match_table = mv_cesa_of_match_table, }, diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c index b5f7e6db24d4..829d6394fb33 100644 --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -1090,7 +1090,6 @@ static struct platform_driver mxs_dcp_driver = { .remove = mxs_dcp_remove, .driver = { .name = "mxs-dcp", - .owner = THIS_MODULE, .of_match_table = mxs_dcp_dt_ids, }, }; diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index f8e3207fecb1..afd136b45f49 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -2210,7 +2210,6 @@ MODULE_DEVICE_TABLE(of, n2_crypto_match); static struct platform_driver n2_crypto_driver = { .driver = { .name = "n2cp", - .owner = THIS_MODULE, .of_match_table = n2_crypto_match, }, .probe = n2_crypto_probe, @@ -2238,7 +2237,6 @@ MODULE_DEVICE_TABLE(of, n2_mau_match); static struct platform_driver n2_mau_driver = { .driver = { .name = "ncp", - .owner = THIS_MODULE, .of_match_table = n2_mau_match, }, .probe = n2_mau_probe, diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index cb98fa54573d..f79dd410dede 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -1314,7 +1314,6 @@ static struct platform_driver omap_aes_driver = { .remove = omap_aes_remove, .driver = { .name = "omap-aes", - .owner = THIS_MODULE, .pm = &omap_aes_pm_ops, .of_match_table = omap_aes_of_match, }, diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c index b8bc84be8741..e350f5be4d2e 100644 --- a/drivers/crypto/omap-des.c +++ b/drivers/crypto/omap-des.c @@ -1222,7 +1222,6 @@ static struct platform_driver omap_des_driver = { .remove = omap_des_remove, .driver = { .name = "omap-des", - .owner = THIS_MODULE, .pm = &omap_des_pm_ops, .of_match_table = of_match_ptr(omap_des_of_match), }, diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 24ef48965e45..3c76696ee578 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -2029,7 +2029,6 @@ static struct platform_driver omap_sham_driver = { .remove = omap_sham_remove, .driver = { .name = "omap-sham", - .owner = THIS_MODULE, .pm = &omap_sham_pm_ops, .of_match_table = omap_sham_of_match, }, diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index 4197ad9a711b..f214a8755827 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -745,7 +745,6 @@ static struct platform_driver s5p_aes_crypto = { .probe = s5p_aes_probe, .remove = s5p_aes_remove, .driver = { - .owner = THIS_MODULE, .name = "s5p-secss", .of_match_table = s5p_sss_dt_match, }, diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c index 164e1ec624e3..8e10a48239b2 100644 --- a/drivers/crypto/sahara.c +++ b/drivers/crypto/sahara.c @@ -1045,7 +1045,6 @@ static struct platform_driver sahara_driver = { .remove = sahara_remove, .driver = { .name = SAHARA_NAME, - .owner = THIS_MODULE, .of_match_table = sahara_dt_ids, }, .id_table = sahara_platform_ids, diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 624b8be0c365..067ec2193d71 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2811,7 +2811,6 @@ MODULE_DEVICE_TABLE(of, talitos_match); static struct platform_driver talitos_driver = { .driver = { .name = "talitos", - .owner = THIS_MODULE, .of_match_table = talitos_match, }, .probe = talitos_probe, -- GitLab From 1a8cdf6e3a8e1acdb5bb7ffa498d1cea0fb5007d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:25 +0200 Subject: [PATCH 0648/9457] crypto: amcc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/amcc/crypto4xx_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index e4c6c58fbb03..d02b77150070 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1288,7 +1288,6 @@ static const struct of_device_id crypto4xx_match[] = { static struct platform_driver crypto4xx_driver = { .driver = { .name = "crypto4xx", - .owner = THIS_MODULE, .of_match_table = crypto4xx_match, }, .probe = crypto4xx_probe, -- GitLab From 7464d31b3caa76b7478702ae0f9986155ba8f52a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:25 +0200 Subject: [PATCH 0649/9457] crypto: caam: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/caam/ctrl.c | 1 - drivers/crypto/caam/jr.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 31000c8c4a90..70f1e6f37336 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -720,7 +720,6 @@ MODULE_DEVICE_TABLE(of, caam_match); static struct platform_driver caam_driver = { .driver = { .name = "caam", - .owner = THIS_MODULE, .of_match_table = caam_match, }, .probe = caam_probe, diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 4d18e27ffa9e..bae20d86e0ad 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -514,7 +514,6 @@ MODULE_DEVICE_TABLE(of, caam_jr_match); static struct platform_driver caam_jr_driver = { .driver = { .name = "caam_jr", - .owner = THIS_MODULE, .of_match_table = caam_jr_match, }, .probe = caam_jr_probe, -- GitLab From 28f01363f82472d56f05608d4bfa4fba1f1fe79b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:26 +0200 Subject: [PATCH 0650/9457] crypto: ccp: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/ccp/ccp-platform.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c index b0a2806908f1..8c50bad25f7e 100644 --- a/drivers/crypto/ccp/ccp-platform.c +++ b/drivers/crypto/ccp/ccp-platform.c @@ -208,7 +208,6 @@ static const struct of_device_id ccp_platform_ids[] = { static struct platform_driver ccp_platform_driver = { .driver = { .name = "AMD Cryptographic Coprocessor", - .owner = THIS_MODULE, .of_match_table = ccp_platform_ids, }, .probe = ccp_platform_probe, -- GitLab From 3b1b4f540d0dd5c8fe777bf02b9f87ffae100b15 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:26 +0200 Subject: [PATCH 0651/9457] crypto: qce: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/qce/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index 33ae3545dc48..718b32a3112e 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -273,7 +273,6 @@ static struct platform_driver qce_crypto_driver = { .probe = qce_crypto_probe, .remove = qce_crypto_remove, .driver = { - .owner = THIS_MODULE, .name = KBUILD_MODNAME, .of_match_table = qce_crypto_of_match, }, -- GitLab From b0d1c793d0ef9cdf748576af6195f507970c15c1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:27 +0200 Subject: [PATCH 0652/9457] crypto: ux500: cryp: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/ux500/cryp/cryp_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 92105f3dc8e0..0fff20435e62 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c @@ -1781,7 +1781,6 @@ static struct platform_driver cryp_driver = { .remove = ux500_cryp_remove, .shutdown = ux500_cryp_shutdown, .driver = { - .owner = THIS_MODULE, .name = "cryp1", .of_match_table = ux500_cryp_match, .pm = &ux500_cryp_pm, -- GitLab From 0c1af19bcf1679358432c86d58ec8ae888549067 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:27 +0200 Subject: [PATCH 0653/9457] crypto: ux500: hash: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/crypto/ux500/hash/hash_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 1c73f4fbc252..1f5876427455 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1962,7 +1962,6 @@ static struct platform_driver hash_driver = { .remove = ux500_hash_remove, .shutdown = ux500_hash_shutdown, .driver = { - .owner = THIS_MODULE, .name = "hash1", .of_match_table = ux500_hash_match, .pm = &ux500_hash_pm, -- GitLab From c4456c1701d64ba1870ecafb33ec7f6de9dc5952 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:27 +0200 Subject: [PATCH 0654/9457] devfreq: exynos: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/devfreq/exynos/exynos4_bus.c | 1 - drivers/devfreq/exynos/exynos5_bus.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index d9b08d3b6830..da9509205169 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c @@ -1034,7 +1034,6 @@ static struct platform_driver exynos4_busfreq_driver = { .id_table = exynos4_busfreq_id, .driver = { .name = "exynos4-busfreq", - .owner = THIS_MODULE, .pm = &exynos4_busfreq_pm_ops, }, }; diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index 6cd0392e2798..297ea30d4159 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c @@ -393,7 +393,6 @@ static struct platform_driver exynos5_busfreq_int_driver = { .remove = exynos5_busfreq_int_remove, .driver = { .name = "exynos5-bus-int", - .owner = THIS_MODULE, .pm = &exynos5_busfreq_int_pm_ops, }, }; -- GitLab From 55f04d7f59ddd48422cccba2cb1329d62401b2df Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:28 +0200 Subject: [PATCH 0655/9457] dma: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/dma/bcm2835-dma.c | 1 - drivers/dma/cppi41.c | 1 - drivers/dma/dma-jz4740.c | 1 - drivers/dma/edma.c | 1 - drivers/dma/fsl-edma.c | 1 - drivers/dma/fsldma.c | 1 - drivers/dma/imx-dma.c | 1 - drivers/dma/iop-adma.c | 1 - drivers/dma/k3dma.c | 1 - drivers/dma/mmp_pdma.c | 1 - drivers/dma/mmp_tdma.c | 1 - drivers/dma/moxart-dma.c | 1 - drivers/dma/mpc512x_dma.c | 1 - drivers/dma/mv_xor.c | 1 - drivers/dma/nbpfaxi.c | 1 - drivers/dma/omap-dma.c | 1 - drivers/dma/qcom_bam_dma.c | 1 - drivers/dma/s3c24xx-dma.c | 1 - drivers/dma/sa11x0-dma.c | 1 - drivers/dma/sirf-dma.c | 1 - drivers/dma/ste_dma40.c | 1 - drivers/dma/tegra20-apb-dma.c | 1 - drivers/dma/timb_dma.c | 1 - 23 files changed, 23 deletions(-) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 68007974961a..815dbdfdb195 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -694,7 +694,6 @@ static struct platform_driver bcm2835_dma_driver = { .remove = bcm2835_dma_remove, .driver = { .name = "bcm2835-dma", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(bcm2835_dma_of_match), }, }; diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index a58eec3b2cad..cf7633f6d474 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -1088,7 +1088,6 @@ static struct platform_driver cpp41_dma_driver = { .remove = cppi41_dma_remove, .driver = { .name = "cppi41-dma-engine", - .owner = THIS_MODULE, .pm = &cppi41_pm_ops, .of_match_table = of_match_ptr(cppi41_dma_ids), }, diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index ae2ab14e64b3..8605ed10c96a 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c @@ -608,7 +608,6 @@ static struct platform_driver jz4740_dma_driver = { .remove = jz4740_dma_remove, .driver = { .name = "jz4740-dma", - .owner = THIS_MODULE, }, }; module_platform_driver(jz4740_dma_driver); diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 123f578d6dd3..fd455979cc9f 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -1092,7 +1092,6 @@ static struct platform_driver edma_driver = { .remove = edma_remove, .driver = { .name = "edma-dma-engine", - .owner = THIS_MODULE, }, }; diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 3c5711d5fe97..a38e5d24db0d 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -963,7 +963,6 @@ MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); static struct platform_driver fsl_edma_driver = { .driver = { .name = "fsl-edma", - .owner = THIS_MODULE, .of_match_table = fsl_edma_dt_ids, }, .probe = fsl_edma_probe, diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 994bcb2c6b92..de3da031ff18 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1540,7 +1540,6 @@ static const struct of_device_id fsldma_of_ids[] = { static struct platform_driver fsldma_of_driver = { .driver = { .name = "fsl-elo-dma", - .owner = THIS_MODULE, .of_match_table = fsldma_of_ids, #ifdef CONFIG_PM .pm = &fsldma_pm_ops, diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 9d2c9e7374dc..10bbc0a675b0 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -1236,7 +1236,6 @@ static int imxdma_remove(struct platform_device *pdev) static struct platform_driver imxdma_driver = { .driver = { .name = "imx-dma", - .owner = THIS_MODULE, .of_match_table = imx_dma_of_dev_id, }, .id_table = imx_dma_devtype, diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index c56137bc3868..263d9f6a207e 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -1557,7 +1557,6 @@ static struct platform_driver iop_adma_driver = { .probe = iop_adma_probe, .remove = iop_adma_remove, .driver = { - .owner = THIS_MODULE, .name = "iop-adma", }, }; diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index a1f911aaf220..9349021cb74c 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -822,7 +822,6 @@ static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume); static struct platform_driver k3_pdma_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &k3_dma_pmops, .of_match_table = k3_pdma_dt_ids, }, diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index a1a4db5721b8..8b8952f35e6c 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -1098,7 +1098,6 @@ static const struct platform_device_id mmp_pdma_id_table[] = { static struct platform_driver mmp_pdma_driver = { .driver = { .name = "mmp-pdma", - .owner = THIS_MODULE, .of_match_table = mmp_pdma_dt_ids, }, .id_table = mmp_pdma_id_table, diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index c6bd015b7165..bfb46957c3dc 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -703,7 +703,6 @@ static const struct platform_device_id mmp_tdma_id_table[] = { static struct platform_driver mmp_tdma_driver = { .driver = { .name = "mmp-tdma", - .owner = THIS_MODULE, .of_match_table = mmp_tdma_dt_ids, }, .id_table = mmp_tdma_id_table, diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index 3258e484e4f6..53032bac06e0 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -677,7 +677,6 @@ static struct platform_driver moxart_driver = { .remove = moxart_remove, .driver = { .name = "moxart-dma-engine", - .owner = THIS_MODULE, .of_match_table = moxart_dma_match, }, }; diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 881db2bcb48b..586d52c86477 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -1090,7 +1090,6 @@ static struct platform_driver mpc_dma_driver = { .remove = mpc_dma_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = mpc_dma_match, }, }; diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a63837ca1410..d7ac558c2c1c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1269,7 +1269,6 @@ static struct platform_driver mv_xor_driver = { .probe = mv_xor_probe, .remove = mv_xor_remove, .driver = { - .owner = THIS_MODULE, .name = MV_XOR_NAME, .of_match_table = of_match_ptr(mv_xor_dt_ids), }, diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 5aeada56a442..a7a36835a233 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1500,7 +1500,6 @@ static const struct dev_pm_ops nbpf_pm_ops = { static struct platform_driver nbpf_driver = { .driver = { - .owner = THIS_MODULE, .name = "dma-nbpf", .of_match_table = nbpf_match, .pm = &nbpf_pm_ops, diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index bbea8243f9e8..7ff73a249502 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -1233,7 +1233,6 @@ static struct platform_driver omap_dma_driver = { .remove = omap_dma_remove, .driver = { .name = "omap-dma-engine", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(omap_dma_match), }, }; diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index 7a4bbb0f80a5..9d7b5542397c 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c @@ -1115,7 +1115,6 @@ static struct platform_driver bam_dma_driver = { .remove = bam_dma_remove, .driver = { .name = "bam-dma-engine", - .owner = THIS_MODULE, .of_match_table = bam_of_match, }, }; diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c index 7416572d1e40..6941a77521c3 100644 --- a/drivers/dma/s3c24xx-dma.c +++ b/drivers/dma/s3c24xx-dma.c @@ -1402,7 +1402,6 @@ static int s3c24xx_dma_remove(struct platform_device *pdev) static struct platform_driver s3c24xx_dma_driver = { .driver = { .name = "s3c24xx-dma", - .owner = THIS_MODULE, }, .id_table = s3c24xx_dma_driver_ids, .probe = s3c24xx_dma_probe, diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index 4b0ef043729a..94f2be30412e 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -1064,7 +1064,6 @@ static const struct dev_pm_ops sa11x0_dma_pm_ops = { static struct platform_driver sa11x0_dma_driver = { .driver = { .name = "sa11x0-dma", - .owner = THIS_MODULE, .pm = &sa11x0_dma_pm_ops, }, .probe = sa11x0_dma_probe, diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index aac03ab10c54..981880ffe276 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -933,7 +933,6 @@ static struct platform_driver sirfsoc_dma_driver = { .remove = sirfsoc_dma_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &sirfsoc_dma_pm_ops, .of_match_table = sirfsoc_dma_match, }, diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 5fe59335e247..7de218c3ed91 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3749,7 +3749,6 @@ static const struct of_device_id d40_match[] = { static struct platform_driver d40_driver = { .driver = { - .owner = THIS_MODULE, .name = D40_NAME, .pm = &dma40_pm_ops, .of_match_table = d40_match, diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 16efa603ff65..a6c0b3f68393 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1597,7 +1597,6 @@ static const struct dev_pm_ops tegra_dma_dev_pm_ops = { static struct platform_driver tegra_dmac_driver = { .driver = { .name = "tegra-apbdma", - .owner = THIS_MODULE, .pm = &tegra_dma_dev_pm_ops, .of_match_table = tegra_dma_of_match, }, diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 4506a7b4f972..2407ccf1a64b 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -783,7 +783,6 @@ static int td_remove(struct platform_device *pdev) static struct platform_driver td_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = td_probe, .remove = td_remove, -- GitLab From d45acddd85964a3c58666d93911bc6cdfac3b999 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:28 +0200 Subject: [PATCH 0656/9457] dma: bestcomm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/dma/bestcomm/bestcomm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index a8c2e2994d2e..fa378d88f6c8 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -495,7 +495,6 @@ static struct platform_driver mpc52xx_bcom_of_platform_driver = { .remove = mpc52xx_bcom_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mpc52xx_bcom_of_match, }, }; -- GitLab From 496b2da10ea0ad0690e83cd58e8663b8bd76c76f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:29 +0200 Subject: [PATCH 0657/9457] dma: ipu: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/dma/ipu/ipu_idmac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index bbf62927bd72..c2b017ad139d 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1783,7 +1783,6 @@ static int ipu_remove(struct platform_device *pdev) static struct platform_driver ipu_platform_driver = { .driver = { .name = "ipu-core", - .owner = THIS_MODULE, }, .remove = ipu_remove, }; -- GitLab From 278559f695df0cd34f43fbeb81f11528ca064d93 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:29 +0200 Subject: [PATCH 0658/9457] dma: ppc4xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/dma/ppc4xx/adma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index ce7a8d7564ba..fa764a39cd36 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4579,7 +4579,6 @@ static struct platform_driver ppc440spe_adma_driver = { .remove = ppc440spe_adma_remove, .driver = { .name = "PPC440SP(E)-ADMA", - .owner = THIS_MODULE, .of_match_table = ppc440spe_adma_of_match, }, }; -- GitLab From 696f26e740b3278b842386a0ead3833b7b4da7d8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:29 +0200 Subject: [PATCH 0659/9457] dma: sh: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/dma/sh/rcar-audmapp.c | 1 - drivers/dma/sh/rcar-hpbdma.c | 1 - drivers/dma/sh/shdma-of.c | 1 - drivers/dma/sh/shdmac.c | 1 - drivers/dma/sh/sudmac.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/dma/sh/rcar-audmapp.c b/drivers/dma/sh/rcar-audmapp.c index 80fd2aeb4870..02979d5199d0 100644 --- a/drivers/dma/sh/rcar-audmapp.c +++ b/drivers/dma/sh/rcar-audmapp.c @@ -367,7 +367,6 @@ static struct platform_driver audmapp_driver = { .probe = audmapp_probe, .remove = audmapp_remove, .driver = { - .owner = THIS_MODULE, .name = "rcar-audmapp-engine", .of_match_table = audmapp_of_match, }, diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c index b212d9471ab5..fe83320d7b57 100644 --- a/drivers/dma/sh/rcar-hpbdma.c +++ b/drivers/dma/sh/rcar-hpbdma.c @@ -655,7 +655,6 @@ static struct platform_driver hpb_dmae_driver = { .remove = hpb_dmae_remove, .shutdown = hpb_dmae_shutdown, .driver = { - .owner = THIS_MODULE, .name = "hpb-dma-engine", }, }; diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c index b4ff9d3e56d1..f999f9b0d314 100644 --- a/drivers/dma/sh/shdma-of.c +++ b/drivers/dma/sh/shdma-of.c @@ -66,7 +66,6 @@ MODULE_DEVICE_TABLE(of, sh_dmae_of_match); static struct platform_driver shdma_of = { .driver = { - .owner = THIS_MODULE, .name = "shdma-of", .of_match_table = shdma_of_match, }, diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index 58eb85770eba..1b1d252f938e 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -925,7 +925,6 @@ static int sh_dmae_remove(struct platform_device *pdev) static struct platform_driver sh_dmae_driver = { .driver = { - .owner = THIS_MODULE, .pm = &sh_dmae_pm, .name = SH_DMAE_DRV_NAME, .of_match_table = sh_dmae_of_match, diff --git a/drivers/dma/sh/sudmac.c b/drivers/dma/sh/sudmac.c index 3ce103909896..2d7a480aa749 100644 --- a/drivers/dma/sh/sudmac.c +++ b/drivers/dma/sh/sudmac.c @@ -411,7 +411,6 @@ static int sudmac_remove(struct platform_device *pdev) static struct platform_driver sudmac_driver = { .driver = { - .owner = THIS_MODULE, .name = SUDMAC_DRV_NAME, }, .probe = sudmac_probe, -- GitLab From b7382f8349c60f364802d8ad124699ef4428e635 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:30 +0200 Subject: [PATCH 0660/9457] edac: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/edac/cell_edac.c | 1 - drivers/edac/mpc85xx_edac.c | 2 -- drivers/edac/ppc4xx_edac.c | 1 - drivers/edac/tile_edac.c | 1 - 4 files changed, 5 deletions(-) diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index a12c8552f6a6..a9259b069dcd 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c @@ -245,7 +245,6 @@ static int cell_edac_remove(struct platform_device *pdev) static struct platform_driver cell_edac_driver = { .driver = { .name = "cbe-mic", - .owner = THIS_MODULE, }, .probe = cell_edac_probe, .remove = cell_edac_remove, diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 7d3742edbaa2..ffb1a9a15ccd 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -715,7 +715,6 @@ static struct platform_driver mpc85xx_l2_err_driver = { .remove = mpc85xx_l2_err_remove, .driver = { .name = "mpc85xx_l2_err", - .owner = THIS_MODULE, .of_match_table = mpc85xx_l2_err_of_match, }, }; @@ -1215,7 +1214,6 @@ static struct platform_driver mpc85xx_mc_err_driver = { .remove = mpc85xx_mc_err_remove, .driver = { .name = "mpc85xx_mc_err", - .owner = THIS_MODULE, .of_match_table = mpc85xx_mc_err_of_match, }, }; diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 0f04d5ead521..6ffd475b3d4a 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -204,7 +204,6 @@ static struct platform_driver ppc4xx_edac_driver = { .probe = ppc4xx_edac_probe, .remove = ppc4xx_edac_remove, .driver = { - .owner = THIS_MODULE, .name = PPC4XX_EDAC_MODULE_NAME, .of_match_table = ppc4xx_edac_match, }, diff --git a/drivers/edac/tile_edac.c b/drivers/edac/tile_edac.c index 578f915ee195..71381642ce2a 100644 --- a/drivers/edac/tile_edac.c +++ b/drivers/edac/tile_edac.c @@ -199,7 +199,6 @@ static int tile_edac_mc_remove(struct platform_device *pdev) static struct platform_driver tile_edac_mc_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = tile_edac_mc_probe, .remove = tile_edac_mc_remove, -- GitLab From 08147bb19a37c8cb2b8149310cf2fa7865c7535e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:30 +0200 Subject: [PATCH 0661/9457] extcon: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/extcon/extcon-adc-jack.c | 1 - drivers/extcon/extcon-arizona.c | 1 - drivers/extcon/extcon-gpio.c | 1 - drivers/extcon/extcon-max14577.c | 1 - drivers/extcon/extcon-max77693.c | 1 - drivers/extcon/extcon-max8997.c | 1 - drivers/extcon/extcon-palmas.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c index d860229e4de1..5d7ab577fba9 100644 --- a/drivers/extcon/extcon-adc-jack.c +++ b/drivers/extcon/extcon-adc-jack.c @@ -182,7 +182,6 @@ static struct platform_driver adc_jack_driver = { .remove = adc_jack_remove, .driver = { .name = "adc-jack", - .owner = THIS_MODULE, }, }; diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index ba51588cc000..63f01c42aed4 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1469,7 +1469,6 @@ static int arizona_extcon_remove(struct platform_device *pdev) static struct platform_driver arizona_extcon_driver = { .driver = { .name = "arizona-extcon", - .owner = THIS_MODULE, }, .probe = arizona_extcon_probe, .remove = arizona_extcon_remove, diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 72f19a37fd01..7af33fc433cd 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -181,7 +181,6 @@ static struct platform_driver gpio_extcon_driver = { .remove = gpio_extcon_remove, .driver = { .name = "extcon-gpio", - .owner = THIS_MODULE, .pm = &gpio_extcon_pm_ops, }, }; diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index 7309743d0da1..dfc2fd370eb3 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c @@ -807,7 +807,6 @@ MODULE_DEVICE_TABLE(platform, max14577_muic_id); static struct platform_driver max14577_muic_driver = { .driver = { .name = "max14577-muic", - .owner = THIS_MODULE, }, .probe = max14577_muic_probe, .remove = max14577_muic_remove, diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 490e27475bac..5bf5c5e66f16 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1301,7 +1301,6 @@ static int max77693_muic_remove(struct platform_device *pdev) static struct platform_driver max77693_muic_driver = { .driver = { .name = DEV_NAME, - .owner = THIS_MODULE, }, .probe = max77693_muic_probe, .remove = max77693_muic_remove, diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 75e501c98005..fc1678fa95c4 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -792,7 +792,6 @@ static int max8997_muic_remove(struct platform_device *pdev) static struct platform_driver max8997_muic_driver = { .driver = { .name = DEV_NAME, - .owner = THIS_MODULE, }, .probe = max8997_muic_probe, .remove = max8997_muic_remove, diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c index 230e1220ce48..11c6757b6c40 100644 --- a/drivers/extcon/extcon-palmas.c +++ b/drivers/extcon/extcon-palmas.c @@ -291,7 +291,6 @@ static struct platform_driver palmas_usb_driver = { .driver = { .name = "palmas-usb", .of_match_table = of_palmas_match_tbl, - .owner = THIS_MODULE, .pm = &palmas_pm_ops, }, }; -- GitLab From e94d68450e2f45b8d227cc1987121d1460841a1e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:31 +0200 Subject: [PATCH 0662/9457] firmware: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/firmware/dcdbas.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 7160c43c59fc..829eec8959f2 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -578,7 +578,6 @@ static int dcdbas_remove(struct platform_device *dev) static struct platform_driver dcdbas_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = dcdbas_probe, .remove = dcdbas_remove, -- GitLab From 4a3a950ee9cc76188f5be9088bc765889f7a61c5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:31 +0200 Subject: [PATCH 0663/9457] gpio: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpio/gpio-adp5520.c | 1 - drivers/gpio/gpio-bcm-kona.c | 1 - drivers/gpio/gpio-clps711x.c | 1 - drivers/gpio/gpio-crystalcove.c | 1 - drivers/gpio/gpio-cs5535.c | 1 - drivers/gpio/gpio-da9052.c | 1 - drivers/gpio/gpio-da9055.c | 1 - drivers/gpio/gpio-davinci.c | 1 - drivers/gpio/gpio-dwapb.c | 1 - drivers/gpio/gpio-em.c | 1 - drivers/gpio/gpio-ep93xx.c | 1 - drivers/gpio/gpio-f7188x.c | 1 - drivers/gpio/gpio-ge.c | 1 - drivers/gpio/gpio-grgpio.c | 1 - drivers/gpio/gpio-ich.c | 1 - drivers/gpio/gpio-iop.c | 1 - drivers/gpio/gpio-janz-ttl.c | 1 - drivers/gpio/gpio-kempld.c | 1 - drivers/gpio/gpio-lp3943.c | 1 - drivers/gpio/gpio-lpc32xx.c | 1 - drivers/gpio/gpio-lynxpoint.c | 1 - drivers/gpio/gpio-mm-lantiq.c | 1 - drivers/gpio/gpio-moxart.c | 1 - drivers/gpio/gpio-mpc5200.c | 2 -- drivers/gpio/gpio-msic.c | 1 - drivers/gpio/gpio-msm-v1.c | 1 - drivers/gpio/gpio-msm-v2.c | 1 - drivers/gpio/gpio-mvebu.c | 1 - drivers/gpio/gpio-mxc.c | 1 - drivers/gpio/gpio-mxs.c | 1 - drivers/gpio/gpio-octeon.c | 1 - drivers/gpio/gpio-rc5t583.c | 1 - drivers/gpio/gpio-sch.c | 1 - drivers/gpio/gpio-spear-spics.c | 1 - drivers/gpio/gpio-sta2x11.c | 1 - drivers/gpio/gpio-stp-xway.c | 1 - drivers/gpio/gpio-syscon.c | 1 - drivers/gpio/gpio-tb10x.c | 1 - drivers/gpio/gpio-tegra.c | 1 - drivers/gpio/gpio-timberdale.c | 1 - drivers/gpio/gpio-tps65912.c | 1 - drivers/gpio/gpio-ts5500.c | 1 - drivers/gpio/gpio-twl4030.c | 1 - drivers/gpio/gpio-twl6040.c | 1 - drivers/gpio/gpio-tz1090-pdc.c | 1 - drivers/gpio/gpio-tz1090.c | 1 - drivers/gpio/gpio-vr41xx.c | 1 - drivers/gpio/gpio-vx855.c | 1 - drivers/gpio/gpio-xgene.c | 1 - drivers/gpio/gpio-xtensa.c | 1 - drivers/gpio/gpio-zevio.c | 1 - 51 files changed, 52 deletions(-) diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index b08bd169e568..caff711ca5a9 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c @@ -177,7 +177,6 @@ static int adp5520_gpio_remove(struct platform_device *pdev) static struct platform_driver adp5520_gpio_driver = { .driver = { .name = "adp5520-gpio", - .owner = THIS_MODULE, }, .probe = adp5520_gpio_probe, .remove = adp5520_gpio_remove, diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index de0801e9767a..9fc05581cbd6 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -668,7 +668,6 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) static struct platform_driver bcm_kona_gpio_driver = { .driver = { .name = "bcm-kona-gpio", - .owner = THIS_MODULE, .of_match_table = bcm_kona_gpio_of_match, }, .probe = bcm_kona_gpio_probe, diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index e1e861239e95..b6908f1ff1ab 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -87,7 +87,6 @@ MODULE_DEVICE_TABLE(of, clps711x_gpio_ids); static struct platform_driver clps711x_gpio_driver = { .driver = { .name = "clps711x-gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(clps711x_gpio_ids), }, .probe = clps711x_gpio_probe, diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index bbfe7f508502..55d4803d71b0 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -379,7 +379,6 @@ static struct platform_driver crystalcove_gpio_driver = { .remove = crystalcove_gpio_remove, .driver = { .name = "crystal_cove_gpio", - .owner = THIS_MODULE, }, }; diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 668127fe90ef..feb4cecfcb01 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -372,7 +372,6 @@ static int cs5535_gpio_remove(struct platform_device *pdev) static struct platform_driver cs5535_gpio_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = cs5535_gpio_probe, .remove = cs5535_gpio_remove, diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index c5bccd4dec96..389a4d2a4926 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c @@ -246,7 +246,6 @@ static struct platform_driver da9052_gpio_driver = { .remove = da9052_gpio_remove, .driver = { .name = "da9052-gpio", - .owner = THIS_MODULE, }, }; diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c index 9167c4331081..b8d757036887 100644 --- a/drivers/gpio/gpio-da9055.c +++ b/drivers/gpio/gpio-da9055.c @@ -183,7 +183,6 @@ static struct platform_driver da9055_gpio_driver = { .remove = da9055_gpio_remove, .driver = { .name = "da9055-gpio", - .owner = THIS_MODULE, }, }; diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 9f0682534e2f..ab06a92faac6 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -619,7 +619,6 @@ static struct platform_driver davinci_gpio_driver = { .probe = davinci_gpio_probe, .driver = { .name = "davinci_gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(davinci_gpio_ids), }, }; diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index b43cd84b61f1..165cce593e64 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -703,7 +703,6 @@ static SIMPLE_DEV_PM_OPS(dwapb_gpio_pm_ops, dwapb_gpio_suspend, static struct platform_driver dwapb_gpio_driver = { .driver = { .name = "gpio-dwapb", - .owner = THIS_MODULE, .pm = &dwapb_gpio_pm_ops, .of_match_table = of_match_ptr(dwapb_of_match), }, diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index fe49ec3cdb7d..0c6c4d138c3d 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -428,7 +428,6 @@ static struct platform_driver em_gio_device_driver = { .driver = { .name = "em_gio", .of_match_table = em_gio_dt_ids, - .owner = THIS_MODULE, } }; diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index dcc2bb4074ef..45684f36ddb1 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -374,7 +374,6 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) static struct platform_driver ep93xx_gpio_driver = { .driver = { .name = "gpio-ep93xx", - .owner = THIS_MODULE, }, .probe = ep93xx_gpio_probe, }; diff --git a/drivers/gpio/gpio-f7188x.c b/drivers/gpio/gpio-f7188x.c index fd3202f968ff..1be291ac6319 100644 --- a/drivers/gpio/gpio-f7188x.c +++ b/drivers/gpio/gpio-f7188x.c @@ -417,7 +417,6 @@ f7188x_gpio_device_add(const struct f7188x_sio *sio) static struct platform_driver f7188x_gpio_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = f7188x_gpio_probe, diff --git a/drivers/gpio/gpio-ge.c b/drivers/gpio/gpio-ge.c index 1237a73c3c91..aea5c2a53cc0 100644 --- a/drivers/gpio/gpio-ge.c +++ b/drivers/gpio/gpio-ge.c @@ -120,7 +120,6 @@ static int __init gef_gpio_probe(struct platform_device *pdev) static struct platform_driver gef_gpio_driver = { .driver = { .name = "gef-gpio", - .owner = THIS_MODULE, .of_match_table = gef_gpio_ids, }, }; diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 66ad3df9d9cf..c1c017cdf6e4 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -490,7 +490,6 @@ MODULE_DEVICE_TABLE(of, grgpio_match); static struct platform_driver grgpio_driver = { .driver = { .name = "grgpio", - .owner = THIS_MODULE, .of_match_table = grgpio_match, }, .probe = grgpio_probe, diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index 3784e81e7762..7818cd1453ae 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -526,7 +526,6 @@ static int ichx_gpio_remove(struct platform_device *pdev) static struct platform_driver ichx_gpio_driver = { .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, .probe = ichx_gpio_probe, diff --git a/drivers/gpio/gpio-iop.c b/drivers/gpio/gpio-iop.c index 0a5e9d3f308c..2ed0237a8baf 100644 --- a/drivers/gpio/gpio-iop.c +++ b/drivers/gpio/gpio-iop.c @@ -120,7 +120,6 @@ static int iop3xx_gpio_probe(struct platform_device *pdev) static struct platform_driver iop3xx_gpio_driver = { .driver = { .name = "gpio-iop", - .owner = THIS_MODULE, }, .probe = iop3xx_gpio_probe, }; diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 29ffe22ad97a..3a1664335f5e 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -203,7 +203,6 @@ static int ttl_remove(struct platform_device *pdev) static struct platform_driver ttl_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ttl_probe, .remove = ttl_remove, diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index fd150adeebf9..443518f63f15 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -206,7 +206,6 @@ static int kempld_gpio_remove(struct platform_device *pdev) static struct platform_driver kempld_gpio_driver = { .driver = { .name = "kempld-gpio", - .owner = THIS_MODULE, }, .probe = kempld_gpio_probe, .remove = kempld_gpio_remove, diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c index 6bbdad805b78..cfc5b12b43ad 100644 --- a/drivers/gpio/gpio-lp3943.c +++ b/drivers/gpio/gpio-lp3943.c @@ -231,7 +231,6 @@ static struct platform_driver lp3943_gpio_driver = { .remove = lp3943_gpio_remove, .driver = { .name = "lp3943-gpio", - .owner = THIS_MODULE, .of_match_table = lp3943_gpio_of_match, }, }; diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index b9b9799b368b..47e2dde63734 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -569,7 +569,6 @@ static const struct of_device_id lpc32xx_gpio_of_match[] = { static struct platform_driver lpc32xx_gpio_driver = { .driver = { .name = "lpc32xx-gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(lpc32xx_gpio_of_match), }, .probe = lpc32xx_gpio_probe, diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index fa945ec9ccff..127c755b38dc 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -450,7 +450,6 @@ static struct platform_driver lp_gpio_driver = { .remove = lp_gpio_remove, .driver = { .name = "lp_gpio", - .owner = THIS_MODULE, .pm = &lp_gpio_pm_ops, .acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match), }, diff --git a/drivers/gpio/gpio-mm-lantiq.c b/drivers/gpio/gpio-mm-lantiq.c index 2983dfbd0668..f228b1ce0ce0 100644 --- a/drivers/gpio/gpio-mm-lantiq.c +++ b/drivers/gpio/gpio-mm-lantiq.c @@ -145,7 +145,6 @@ static struct platform_driver ltq_mm_driver = { .probe = ltq_mm_probe, .driver = { .name = "gpio-mm-ltq", - .owner = THIS_MODULE, .of_match_table = ltq_mm_match, }, }; diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c index 4661e181be04..31e2551ed903 100644 --- a/drivers/gpio/gpio-moxart.c +++ b/drivers/gpio/gpio-moxart.c @@ -142,7 +142,6 @@ static const struct of_device_id moxart_gpio_match[] = { static struct platform_driver moxart_gpio_driver = { .driver = { .name = "moxart-gpio", - .owner = THIS_MODULE, .of_match_table = moxart_gpio_match, }, .probe = moxart_gpio_probe, diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c index 42647f26c9e0..8ce6c9510035 100644 --- a/drivers/gpio/gpio-mpc5200.c +++ b/drivers/gpio/gpio-mpc5200.c @@ -192,7 +192,6 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { static struct platform_driver mpc52xx_wkup_gpiochip_driver = { .driver = { .name = "mpc5200-gpio-wkup", - .owner = THIS_MODULE, .of_match_table = mpc52xx_wkup_gpiochip_match, }, .probe = mpc52xx_wkup_gpiochip_probe, @@ -347,7 +346,6 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { static struct platform_driver mpc52xx_simple_gpiochip_driver = { .driver = { .name = "mpc5200-gpio", - .owner = THIS_MODULE, .of_match_table = mpc52xx_simple_gpiochip_match, }, .probe = mpc52xx_simple_gpiochip_probe, diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index 8f70ded82a2b..01acf0a8cdb1 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c @@ -321,7 +321,6 @@ static int platform_msic_gpio_probe(struct platform_device *pdev) static struct platform_driver platform_msic_gpio_driver = { .driver = { .name = "msic_gpio", - .owner = THIS_MODULE, }, .probe = platform_msic_gpio_probe, }; diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index 73b73969d361..09e895d018b7 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c @@ -701,7 +701,6 @@ MODULE_DEVICE_TABLE(platform, gpio_msm_v1_device_ids); static struct platform_driver gpio_msm_v1_driver = { .driver = { .name = "gpio-msm-v1", - .owner = THIS_MODULE, }, .probe = gpio_msm_v1_probe, .id_table = gpio_msm_v1_device_ids, diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c index 94f57670df9a..52ff18229fdc 100644 --- a/drivers/gpio/gpio-msm-v2.c +++ b/drivers/gpio/gpio-msm-v2.c @@ -450,7 +450,6 @@ static struct platform_driver msm_gpio_driver = { .remove = msm_gpio_remove, .driver = { .name = "msmgpio", - .owner = THIS_MODULE, .of_match_table = msm_gpio_of_match, }, }; diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 418e38650363..e06d7932b498 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -731,7 +731,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) static struct platform_driver mvebu_gpio_driver = { .driver = { .name = "mvebu-gpio", - .owner = THIS_MODULE, .of_match_table = mvebu_gpio_of_match, }, .probe = mvebu_gpio_probe, diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index f4e54a92e04a..9f7446a7ac64 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -496,7 +496,6 @@ static int mxc_gpio_probe(struct platform_device *pdev) static struct platform_driver mxc_gpio_driver = { .driver = { .name = "gpio-mxc", - .owner = THIS_MODULE, .of_match_table = mxc_gpio_dt_ids, }, .probe = mxc_gpio_probe, diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index 8ffdd7d2bade..89143e2d3f5d 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c @@ -338,7 +338,6 @@ static int mxs_gpio_probe(struct platform_device *pdev) static struct platform_driver mxs_gpio_driver = { .driver = { .name = "gpio-mxs", - .owner = THIS_MODULE, .of_match_table = mxs_gpio_dt_ids, }, .probe = mxs_gpio_probe, diff --git a/drivers/gpio/gpio-octeon.c b/drivers/gpio/gpio-octeon.c index 5c5770c99c80..62ae251d4490 100644 --- a/drivers/gpio/gpio-octeon.c +++ b/drivers/gpio/gpio-octeon.c @@ -144,7 +144,6 @@ MODULE_DEVICE_TABLE(of, octeon_gpio_match); static struct platform_driver octeon_gpio_driver = { .driver = { .name = "octeon_gpio", - .owner = THIS_MODULE, .of_match_table = octeon_gpio_match, }, .probe = octeon_gpio_probe, diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 769233d2da6d..6eabf239676b 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -155,7 +155,6 @@ static int rc5t583_gpio_remove(struct platform_device *pdev) static struct platform_driver rc5t583_gpio_driver = { .driver = { .name = "rc5t583-gpio", - .owner = THIS_MODULE, }, .probe = rc5t583_gpio_probe, .remove = rc5t583_gpio_remove, diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 41e91d70301e..8266045a5d45 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -319,7 +319,6 @@ static int sch_gpio_remove(struct platform_device *pdev) static struct platform_driver sch_gpio_driver = { .driver = { .name = "sch_gpio", - .owner = THIS_MODULE, }, .probe = sch_gpio_probe, .remove = sch_gpio_remove, diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c index 353263c85d26..64c8aa4f52b8 100644 --- a/drivers/gpio/gpio-spear-spics.c +++ b/drivers/gpio/gpio-spear-spics.c @@ -191,7 +191,6 @@ MODULE_DEVICE_TABLE(of, spics_gpio_of_match); static struct platform_driver spics_gpio_driver = { .probe = spics_gpio_probe, .driver = { - .owner = THIS_MODULE, .name = "spear-spics-gpio", .of_match_table = spics_gpio_of_match, }, diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 68e3fcb1acea..18579ac65b2b 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c @@ -429,7 +429,6 @@ static int gsta_probe(struct platform_device *dev) static struct platform_driver sta2x11_gpio_platform_driver = { .driver = { .name = "sta2x11-gpio", - .owner = THIS_MODULE, }, .probe = gsta_probe, }; diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 7e359b7cce1b..6b9321e8669a 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c @@ -287,7 +287,6 @@ static struct platform_driver xway_stp_driver = { .probe = xway_stp_probe, .driver = { .name = "gpio-stp-xway", - .owner = THIS_MODULE, .of_match_table = xway_stp_match, }, }; diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index e82fde4b6898..257e2989215c 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c @@ -253,7 +253,6 @@ static int syscon_gpio_remove(struct platform_device *pdev) static struct platform_driver syscon_gpio_driver = { .driver = { .name = "gpio-syscon", - .owner = THIS_MODULE, .of_match_table = syscon_gpio_ids, }, .probe = syscon_gpio_probe, diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c index 9e615be8032c..a2bde95f64c7 100644 --- a/drivers/gpio/gpio-tb10x.c +++ b/drivers/gpio/gpio-tb10x.c @@ -316,7 +316,6 @@ static struct platform_driver tb10x_gpio_driver = { .driver = { .name = "tb10x-gpio", .of_match_table = tb10x_gpio_dt_ids, - .owner = THIS_MODULE, } }; diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 4e8fb8261a87..a223ac51749c 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -528,7 +528,6 @@ static int tegra_gpio_probe(struct platform_device *pdev) static struct platform_driver tegra_gpio_driver = { .driver = { .name = "tegra-gpio", - .owner = THIS_MODULE, .pm = &tegra_gpio_pm_ops, .of_match_table = tegra_gpio_of_match, }, diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index a685a3cbbc81..e8f97e03c9bb 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -330,7 +330,6 @@ static int timbgpio_remove(struct platform_device *pdev) static struct platform_driver timbgpio_platform_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = timbgpio_probe, .remove = timbgpio_remove, diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 22052d84c63b..472fb5b8779f 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -124,7 +124,6 @@ static int tps65912_gpio_remove(struct platform_device *pdev) static struct platform_driver tps65912_gpio_driver = { .driver = { .name = "tps65912-gpio", - .owner = THIS_MODULE, }, .probe = tps65912_gpio_probe, .remove = tps65912_gpio_remove, diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c index de18591ff11e..92fbabd82879 100644 --- a/drivers/gpio/gpio-ts5500.c +++ b/drivers/gpio/gpio-ts5500.c @@ -452,7 +452,6 @@ MODULE_DEVICE_TABLE(platform, ts5500_dio_ids); static struct platform_driver ts5500_dio_driver = { .driver = { .name = "ts5500-dio", - .owner = THIS_MODULE, }, .probe = ts5500_dio_probe, .remove = ts5500_dio_remove, diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index 118828b3736f..9e1dbb9877c1 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -605,7 +605,6 @@ MODULE_ALIAS("platform:twl4030_gpio"); static struct platform_driver gpio_twl4030_driver = { .driver = { .name = "twl4030_gpio", - .owner = THIS_MODULE, .of_match_table = twl_gpio_match, }, .probe = gpio_twl4030_probe, diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index f28e04b88aa9..c946e7eef3ee 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -121,7 +121,6 @@ MODULE_ALIAS("platform:twl6040-gpo"); static struct platform_driver gpo_twl6040_driver = { .driver = { .name = "twl6040-gpo", - .owner = THIS_MODULE, }, .probe = gpo_twl6040_probe, .remove = gpo_twl6040_remove, diff --git a/drivers/gpio/gpio-tz1090-pdc.c b/drivers/gpio/gpio-tz1090-pdc.c index f512da299b3d..d7536226b847 100644 --- a/drivers/gpio/gpio-tz1090-pdc.c +++ b/drivers/gpio/gpio-tz1090-pdc.c @@ -230,7 +230,6 @@ static struct of_device_id tz1090_pdc_gpio_of_match[] = { static struct platform_driver tz1090_pdc_gpio_driver = { .driver = { .name = "tz1090-pdc-gpio", - .owner = THIS_MODULE, .of_match_table = tz1090_pdc_gpio_of_match, }, .probe = tz1090_pdc_gpio_probe, diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c index 5246a60eff6d..9e901773a9d5 100644 --- a/drivers/gpio/gpio-tz1090.c +++ b/drivers/gpio/gpio-tz1090.c @@ -593,7 +593,6 @@ static struct of_device_id tz1090_gpio_of_match[] = { static struct platform_driver tz1090_gpio_driver = { .driver = { .name = "tz1090-gpio", - .owner = THIS_MODULE, .of_match_table = tz1090_gpio_of_match, }, .probe = tz1090_gpio_probe, diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index dbf28fa03f67..b2d05f3a8c9e 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -591,7 +591,6 @@ static struct platform_driver giu_device_driver = { .remove = giu_remove, .driver = { .name = "GIU", - .owner = THIS_MODULE, }, }; diff --git a/drivers/gpio/gpio-vx855.c b/drivers/gpio/gpio-vx855.c index 85971d4e23c1..9d21d2fcc327 100644 --- a/drivers/gpio/gpio-vx855.c +++ b/drivers/gpio/gpio-vx855.c @@ -306,7 +306,6 @@ static int vx855gpio_remove(struct platform_device *pdev) static struct platform_driver vx855gpio_driver = { .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, }, .probe = vx855gpio_probe, .remove = vx855gpio_remove, diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c index 7d489221dc1f..18a8182d4fec 100644 --- a/drivers/gpio/gpio-xgene.c +++ b/drivers/gpio/gpio-xgene.c @@ -229,7 +229,6 @@ MODULE_DEVICE_TABLE(of, xgene_gpio_of_match); static struct platform_driver xgene_gpio_driver = { .driver = { .name = "xgene-gpio", - .owner = THIS_MODULE, .of_match_table = xgene_gpio_of_match, .pm = XGENE_GPIO_PM_OPS, }, diff --git a/drivers/gpio/gpio-xtensa.c b/drivers/gpio/gpio-xtensa.c index 7081304d6797..93ec95df67a3 100644 --- a/drivers/gpio/gpio-xtensa.c +++ b/drivers/gpio/gpio-xtensa.c @@ -157,7 +157,6 @@ static int xtensa_gpio_probe(struct platform_device *pdev) static struct platform_driver xtensa_gpio_driver = { .driver = { .name = "xtensa-gpio", - .owner = THIS_MODULE, }, .probe = xtensa_gpio_probe, }; diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 54e54e4cc6c4..f769cd53f4e4 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -212,7 +212,6 @@ MODULE_DEVICE_TABLE(of, zevio_gpio_of_match); static struct platform_driver zevio_gpio_driver = { .driver = { .name = "gpio-zevio", - .owner = THIS_MODULE, .of_match_table = zevio_gpio_of_match, }, .probe = zevio_gpio_probe, -- GitLab From 85a4389974c6fe08bdb1346d28efec0eea911f70 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:32 +0200 Subject: [PATCH 0664/9457] gpu: drm: armada: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/armada/armada_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index f672e6ad8afa..ff0f94588600 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -485,7 +485,6 @@ static struct platform_driver armada_drm_platform_driver = { .remove = armada_drm_remove, .driver = { .name = "armada-drm", - .owner = THIS_MODULE, }, .id_table = armada_drm_platform_ids, }; -- GitLab From 3097735b381b5271dd9cd36dd361473391506f2c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:32 +0200 Subject: [PATCH 0665/9457] gpu: drm: exynos: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 443a2069858a..9ee00c95639b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -724,7 +724,6 @@ static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, .driver = { - .owner = THIS_MODULE, .name = "exynos-drm", .pm = &exynos_drm_pm_ops, }, -- GitLab From 6a4d005e64d034dbd9f3ce551aeb1f89d0f65c7c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:33 +0200 Subject: [PATCH 0666/9457] gpu: drm: msm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/msm/msm_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b67ef5985125..42e1c48eef28 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -987,7 +987,6 @@ static struct platform_driver msm_platform_driver = { .probe = msm_pdev_probe, .remove = msm_pdev_remove, .driver = { - .owner = THIS_MODULE, .name = "msm", .of_match_table = dt_match, .pm = &msm_pm_ops, -- GitLab From a58a3b9b045d2ab295622ea8b1989907bbc8b736 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:33 +0200 Subject: [PATCH 0667/9457] gpu: drm: omapdrm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/omapdrm/omap_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 862ba03c236c..8241ed9b353c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -718,7 +718,6 @@ static const struct dev_pm_ops omapdrm_pm_ops = { static struct platform_driver pdev = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &omapdrm_pm_ops, #endif -- GitLab From b24347c714421fa55d4fe8b08cdd10cacbd5c80c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:33 +0200 Subject: [PATCH 0668/9457] gpu: drm: panel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/panel/panel-simple.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 23de22f8c820..12bc8a0ab1cf 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -708,7 +708,6 @@ static void panel_simple_platform_shutdown(struct platform_device *pdev) static struct platform_driver panel_simple_platform_driver = { .driver = { .name = "panel-simple", - .owner = THIS_MODULE, .of_match_table = platform_of_match, }, .probe = panel_simple_platform_probe, -- GitLab From 8749393d361fa003a6b09152972043f6d6cd2b74 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:34 +0200 Subject: [PATCH 0669/9457] gpu: drm: rcar-du: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index d212efa6a495..e419aade2209 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -330,7 +330,6 @@ static struct platform_driver rcar_du_platform_driver = { .probe = rcar_du_probe, .remove = rcar_du_remove, .driver = { - .owner = THIS_MODULE, .name = "rcar-du", .pm = &rcar_du_pm_ops, .of_match_table = rcar_du_of_table, -- GitLab From 1b53d63ab719f582a218f579be4d0a26309923a2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:34 +0200 Subject: [PATCH 0670/9457] gpu: drm: shmobile: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index e62cbde81e50..666321de7b99 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -348,7 +348,6 @@ static struct platform_driver shmob_drm_platform_driver = { .probe = shmob_drm_probe, .remove = shmob_drm_remove, .driver = { - .owner = THIS_MODULE, .name = "shmob-drm", .pm = &shmob_drm_pm_ops, }, -- GitLab From 31bc02b1929307887b38b8b60902ba4d4686f1ed Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:35 +0200 Subject: [PATCH 0671/9457] gpu: drm: sti: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/sti/sti_compositor.c | 1 - drivers/gpu/drm/sti/sti_drm_drv.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c index 390d93e9a06c..9e31dfe154ed 100644 --- a/drivers/gpu/drm/sti/sti_compositor.c +++ b/drivers/gpu/drm/sti/sti_compositor.c @@ -267,7 +267,6 @@ static int sti_compositor_remove(struct platform_device *pdev) static struct platform_driver sti_compositor_driver = { .driver = { .name = "sti-compositor", - .owner = THIS_MODULE, .of_match_table = compositor_of_match, }, .probe = sti_compositor_probe, diff --git a/drivers/gpu/drm/sti/sti_drm_drv.c b/drivers/gpu/drm/sti/sti_drm_drv.c index 223d93c3a05d..8e64220e8796 100644 --- a/drivers/gpu/drm/sti/sti_drm_drv.c +++ b/drivers/gpu/drm/sti/sti_drm_drv.c @@ -184,7 +184,6 @@ static struct platform_driver sti_drm_master_driver = { .probe = sti_drm_master_probe, .remove = sti_drm_master_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME "__master", }, }; @@ -228,7 +227,6 @@ static struct platform_driver sti_drm_platform_driver = { .probe = sti_drm_platform_probe, .remove = sti_drm_platform_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = sti_drm_dt_ids, }, -- GitLab From 154f0d679d5a5085f3c245d01e0a678481020ecb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:35 +0200 Subject: [PATCH 0672/9457] gpu: drm: tilcdc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 79a34cbd29f5..f8546824d177 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -645,7 +645,6 @@ static struct platform_driver tilcdc_platform_driver = { .probe = tilcdc_pdev_probe, .remove = tilcdc_pdev_remove, .driver = { - .owner = THIS_MODULE, .name = "tilcdc", .pm = &tilcdc_pm_ops, .of_match_table = tilcdc_of_match, -- GitLab From 53b72c17873ad3500c19c71dd3074a57604880eb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:35 +0200 Subject: [PATCH 0673/9457] hsi: controllers: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/hsi/controllers/omap_ssi.c | 1 - drivers/hsi/controllers/omap_ssi_port.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/hsi/controllers/omap_ssi.c b/drivers/hsi/controllers/omap_ssi.c index bf0eace4cb67..8cd03e5c1db6 100644 --- a/drivers/hsi/controllers/omap_ssi.c +++ b/drivers/hsi/controllers/omap_ssi.c @@ -610,7 +610,6 @@ static struct platform_driver ssi_pdriver = { .remove = __exit_p(ssi_remove), .driver = { .name = "omap_ssi", - .owner = THIS_MODULE, .pm = DEV_PM_OPS, .of_match_table = omap_ssi_of_match, }, diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 4c0b5820581e..c65455af050e 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -1385,7 +1385,6 @@ static struct platform_driver ssi_port_pdriver = { .remove = __exit_p(ssi_port_remove), .driver = { .name = "omap_ssi_port", - .owner = THIS_MODULE, .of_match_table = omap_ssi_port_of_match, .pm = DEV_PM_OPS, }, -- GitLab From 2a1ed077189a38bccf39cb00d8dca96d20a49463 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:36 +0200 Subject: [PATCH 0674/9457] hwmon: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/hwmon/abituguru.c | 1 - drivers/hwmon/abituguru3.c | 1 - drivers/hwmon/abx500.c | 1 - drivers/hwmon/applesmc.c | 1 - drivers/hwmon/coretemp.c | 1 - drivers/hwmon/da9052-hwmon.c | 1 - drivers/hwmon/da9055-hwmon.c | 1 - drivers/hwmon/dme1737.c | 1 - drivers/hwmon/f71805f.c | 1 - drivers/hwmon/f71882fg.c | 1 - drivers/hwmon/i5k_amb.c | 1 - drivers/hwmon/ibmpowernv.c | 1 - drivers/hwmon/iio_hwmon.c | 1 - drivers/hwmon/it87.c | 1 - drivers/hwmon/jz4740-hwmon.c | 1 - drivers/hwmon/lm78.c | 1 - drivers/hwmon/max197.c | 1 - drivers/hwmon/mc13783-adc.c | 1 - drivers/hwmon/menf21bmc_hwmon.c | 1 - drivers/hwmon/nct6683.c | 1 - drivers/hwmon/nct6775.c | 1 - drivers/hwmon/ntc_thermistor.c | 1 - drivers/hwmon/pc87360.c | 1 - drivers/hwmon/pc87427.c | 1 - drivers/hwmon/s3c-hwmon.c | 1 - drivers/hwmon/sch5627.c | 1 - drivers/hwmon/sch5636.c | 1 - drivers/hwmon/sht15.c | 1 - drivers/hwmon/sis5595.c | 1 - drivers/hwmon/smsc47b397.c | 1 - drivers/hwmon/smsc47m1.c | 1 - drivers/hwmon/twl4030-madc-hwmon.c | 1 - drivers/hwmon/ultra45_env.c | 1 - drivers/hwmon/vexpress.c | 1 - drivers/hwmon/via-cputemp.c | 1 - drivers/hwmon/via686a.c | 1 - drivers/hwmon/vt1211.c | 1 - drivers/hwmon/vt8231.c | 1 - drivers/hwmon/w83627ehf.c | 1 - drivers/hwmon/w83627hf.c | 1 - drivers/hwmon/w83781d.c | 1 - drivers/hwmon/wm831x-hwmon.c | 1 - drivers/hwmon/wm8350-hwmon.c | 1 - 43 files changed, 43 deletions(-) diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 9c8a6bab8228..7a09c1615aa9 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1547,7 +1547,6 @@ static SIMPLE_DEV_PM_OPS(abituguru_pm, abituguru_suspend, abituguru_resume); static struct platform_driver abituguru_driver = { .driver = { - .owner = THIS_MODULE, .name = ABIT_UGURU_NAME, .pm = ABIT_UGURU_PM, }, diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 4ae74aa8cdc1..3d2a4ae92d1e 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -1167,7 +1167,6 @@ static SIMPLE_DEV_PM_OPS(abituguru3_pm, abituguru3_suspend, abituguru3_resume); static struct platform_driver abituguru3_driver = { .driver = { - .owner = THIS_MODULE, .name = ABIT_UGURU3_NAME, .pm = ABIT_UGURU3_PM }, diff --git a/drivers/hwmon/abx500.c b/drivers/hwmon/abx500.c index 769fe20ec938..13875968c844 100644 --- a/drivers/hwmon/abx500.c +++ b/drivers/hwmon/abx500.c @@ -474,7 +474,6 @@ static const struct of_device_id abx500_temp_match[] = { static struct platform_driver abx500_temp_driver = { .driver = { - .owner = THIS_MODULE, .name = "abx500-temp", .of_match_table = of_match_ptr(abx500_temp_match), }, diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 3288f13d2d87..0af63da6b603 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -676,7 +676,6 @@ static struct platform_driver applesmc_driver = { .probe = applesmc_probe, .driver = { .name = "applesmc", - .owner = THIS_MODULE, .pm = &applesmc_pm_ops, }, }; diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index d76f0b70c6e0..5b7fec824f10 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -596,7 +596,6 @@ static int coretemp_remove(struct platform_device *pdev) static struct platform_driver coretemp_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = coretemp_probe, diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c index 692b3f34d88c..c9832bfacfe5 100644 --- a/drivers/hwmon/da9052-hwmon.c +++ b/drivers/hwmon/da9052-hwmon.c @@ -282,7 +282,6 @@ static struct platform_driver da9052_hwmon_driver = { .probe = da9052_hwmon_probe, .driver = { .name = "da9052-hwmon", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c index 9916a3fb4bb9..f6e159cabe23 100644 --- a/drivers/hwmon/da9055-hwmon.c +++ b/drivers/hwmon/da9055-hwmon.c @@ -286,7 +286,6 @@ static struct platform_driver da9055_hwmon_driver = { .probe = da9055_hwmon_probe, .driver = { .name = "da9055-hwmon", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index bea0a344fab5..8763c4a8280c 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -2732,7 +2732,6 @@ static int dme1737_isa_remove(struct platform_device *pdev) static struct platform_driver dme1737_isa_driver = { .driver = { - .owner = THIS_MODULE, .name = "dme1737", }, .probe = dme1737_isa_probe, diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 9e57b77ecd34..facd05cda26d 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -1503,7 +1503,6 @@ static int f71805f_remove(struct platform_device *pdev) static struct platform_driver f71805f_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = f71805f_probe, diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 03d8592810bf..2e5c6f46e442 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -369,7 +369,6 @@ static int f71882fg_remove(struct platform_device *pdev); static struct platform_driver f71882fg_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = f71882fg_probe, diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 6c0080a3b902..6b3d1972cef7 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -581,7 +581,6 @@ static int i5k_amb_remove(struct platform_device *pdev) static struct platform_driver i5k_amb_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = i5k_amb_probe, diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index d2bf2c97ae70..58ea44ec6c77 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c @@ -311,7 +311,6 @@ static int __init ibmpowernv_probe(struct platform_device *pdev) static struct platform_driver ibmpowernv_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, }; diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index 14c82daab019..214a51c55ad2 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c @@ -172,7 +172,6 @@ MODULE_DEVICE_TABLE(of, iio_hwmon_of_match); static struct platform_driver __refdata iio_hwmon_driver = { .driver = { .name = "iio_hwmon", - .owner = THIS_MODULE, .of_match_table = iio_hwmon_of_match, }, .probe = iio_hwmon_probe, diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a327fd3402a7..409116c52cc5 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -498,7 +498,6 @@ static void it87_init_device(struct platform_device *pdev); static struct platform_driver it87_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = it87_probe, diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index 7488e36809c8..df9b3447f2a8 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c @@ -172,7 +172,6 @@ static struct platform_driver jz4740_hwmon_driver = { .remove = jz4740_hwmon_remove, .driver = { .name = "jz4740-hwmon", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 759661c7d480..539efe4ad991 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -836,7 +836,6 @@ static int lm78_isa_probe(struct platform_device *pdev) static struct platform_driver lm78_isa_driver = { .driver = { - .owner = THIS_MODULE, .name = "lm78", }, .probe = lm78_isa_probe, diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c index 82128ad79a91..cb0dcfda958c 100644 --- a/drivers/hwmon/max197.c +++ b/drivers/hwmon/max197.c @@ -334,7 +334,6 @@ MODULE_DEVICE_TABLE(platform, max197_device_ids); static struct platform_driver max197_driver = { .driver = { .name = "max197", - .owner = THIS_MODULE, }, .probe = max197_probe, .remove = max197_remove, diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index ae00e60d856c..0c02f40eb0c1 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c @@ -267,7 +267,6 @@ MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable); static struct platform_driver mc13783_adc_driver = { .remove = mc13783_adc_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, }, .id_table = mc13783_adc_idtable, diff --git a/drivers/hwmon/menf21bmc_hwmon.c b/drivers/hwmon/menf21bmc_hwmon.c index c92229d321c9..722d08198b53 100644 --- a/drivers/hwmon/menf21bmc_hwmon.c +++ b/drivers/hwmon/menf21bmc_hwmon.c @@ -218,7 +218,6 @@ static struct platform_driver menf21bmc_hwmon = { .probe = menf21bmc_hwmon_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c index 7710f4694ba1..f3830db02d46 100644 --- a/drivers/hwmon/nct6683.c +++ b/drivers/hwmon/nct6683.c @@ -1282,7 +1282,6 @@ static const struct dev_pm_ops nct6683_dev_pm_ops = { static struct platform_driver nct6683_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, .pm = NCT6683_DEV_PM_OPS, }, diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 504cbddbdd90..7c0ea7252ef4 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -4039,7 +4039,6 @@ static const struct dev_pm_ops nct6775_dev_pm_ops = { static struct platform_driver nct6775_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, .pm = NCT6775_DEV_PM_OPS, }, diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 4ff89b2482e4..fd9a945fe8db 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -609,7 +609,6 @@ static int ntc_thermistor_remove(struct platform_device *pdev) static struct platform_driver ntc_thermistor_driver = { .driver = { .name = "ntc-thermistor", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ntc_match), }, .probe = ntc_thermistor_probe, diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 145f674c1d87..d50fbf93a737 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -244,7 +244,6 @@ static struct pc87360_data *pc87360_update_device(struct device *dev); static struct platform_driver pc87360_driver = { .driver = { - .owner = THIS_MODULE, .name = "pc87360", }, .probe = pc87360_probe, diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 9e4684e747ea..cb9fdd37bd0d 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -1153,7 +1153,6 @@ static int pc87427_remove(struct platform_device *pdev) static struct platform_driver pc87427_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = pc87427_probe, diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index 0674c13bbd4b..0c4710d35d16 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c @@ -378,7 +378,6 @@ static int s3c_hwmon_remove(struct platform_device *dev) static struct platform_driver s3c_hwmon_driver = { .driver = { .name = "s3c-hwmon", - .owner = THIS_MODULE, }, .probe = s3c_hwmon_probe, .remove = s3c_hwmon_remove, diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c index 0cc99fd83e8e..19f85c0da270 100644 --- a/drivers/hwmon/sch5627.c +++ b/drivers/hwmon/sch5627.c @@ -591,7 +591,6 @@ static int sch5627_probe(struct platform_device *pdev) static struct platform_driver sch5627_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = sch5627_probe, diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c index 547b5c952eff..131a2815dbda 100644 --- a/drivers/hwmon/sch5636.c +++ b/drivers/hwmon/sch5636.c @@ -521,7 +521,6 @@ static int sch5636_probe(struct platform_device *pdev) static struct platform_driver sch5636_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = sch5636_probe, diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 97cd45a8432c..d4f0935daaa1 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -1087,7 +1087,6 @@ MODULE_DEVICE_TABLE(platform, sht15_device_ids); static struct platform_driver sht15_driver = { .driver = { .name = "sht15", - .owner = THIS_MODULE, }, .probe = sht15_probe, .remove = sht15_remove, diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index bf1d7893d51c..45a028fb8851 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -215,7 +215,6 @@ static void sis5595_init_device(struct sis5595_data *data); static struct platform_driver sis5595_driver = { .driver = { - .owner = THIS_MODULE, .name = "sis5595", }, .probe = sis5595_probe, diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 221f0931bf1c..6bd200756560 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -219,7 +219,6 @@ static int smsc47b397_probe(struct platform_device *pdev); static struct platform_driver smsc47b397_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = smsc47b397_probe, diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index d7485659acc5..5d323186d2c1 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -849,7 +849,6 @@ static int __exit smsc47m1_remove(struct platform_device *pdev) static struct platform_driver smsc47m1_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .remove = __exit_p(smsc47m1_remove), diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 9a0e2b8e8b94..b5caf7fdb487 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -107,7 +107,6 @@ static struct platform_driver twl4030_madc_hwmon_driver = { .probe = twl4030_madc_hwmon_probe, .driver = { .name = "twl4030_madc_hwmon", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 7d4658636064..f2816c7c918f 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -314,7 +314,6 @@ MODULE_DEVICE_TABLE(of, env_match); static struct platform_driver env_driver = { .driver = { .name = "ultra45_env", - .owner = THIS_MODULE, .of_match_table = env_match, }, .probe = env_probe, diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c index c53619086f33..cf1848b8fb32 100644 --- a/drivers/hwmon/vexpress.c +++ b/drivers/hwmon/vexpress.c @@ -247,7 +247,6 @@ static struct platform_driver vexpress_hwmon_driver = { .probe = vexpress_hwmon_probe, .driver = { .name = DRVNAME, - .owner = THIS_MODULE, .of_match_table = vexpress_hwmon_of_match, }, }; diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 8df43c51de2c..ac91c07e3f90 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -205,7 +205,6 @@ static int via_cputemp_remove(struct platform_device *pdev) static struct platform_driver via_cputemp_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = via_cputemp_probe, diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index babd732b4e18..40dd93c8f9f4 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -670,7 +670,6 @@ static const struct attribute_group via686a_group = { static struct platform_driver via686a_driver = { .driver = { - .owner = THIS_MODULE, .name = "via686a", }, .probe = via686a_probe, diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 3ea57c3504e2..3a6bfa51cb94 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -1233,7 +1233,6 @@ static int vt1211_remove(struct platform_device *pdev) static struct platform_driver vt1211_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = vt1211_probe, diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index b3babe3326fb..cb69a8c2ed5b 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -759,7 +759,6 @@ static const struct attribute_group vt8231_group = { static struct platform_driver vt8231_driver = { .driver = { - .owner = THIS_MODULE, .name = "vt8231", }, .probe = vt8231_probe, diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index f0ab61db7a0d..b10353b31806 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -2705,7 +2705,6 @@ static const struct dev_pm_ops w83627ehf_dev_pm_ops = { static struct platform_driver w83627ehf_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, .pm = W83627EHF_DEV_PM_OPS, }, diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 2f55973a8c4c..721295b9a051 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -474,7 +474,6 @@ static const struct dev_pm_ops w83627hf_dev_pm_ops = { static struct platform_driver w83627hf_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, .pm = W83627HF_DEV_PM_OPS, }, diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 84911616d8c0..54848fdd181e 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1839,7 +1839,6 @@ w83781d_isa_remove(struct platform_device *pdev) static struct platform_driver w83781d_isa_driver = { .driver = { - .owner = THIS_MODULE, .name = "w83781d", }, .probe = w83781d_isa_probe, diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index 3e6a3195cd11..a16cce72e4e2 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c @@ -154,7 +154,6 @@ static struct platform_driver wm831x_hwmon_driver = { .probe = wm831x_hwmon_probe, .driver = { .name = "wm831x-hwmon", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c index 90e3d918e597..31af438ffa88 100644 --- a/drivers/hwmon/wm8350-hwmon.c +++ b/drivers/hwmon/wm8350-hwmon.c @@ -93,7 +93,6 @@ static struct platform_driver wm8350_hwmon_driver = { .probe = wm8350_hwmon_probe, .driver = { .name = "wm8350-hwmon", - .owner = THIS_MODULE, }, }; -- GitLab From a7629c70d0ffd5ea12e681f0dd168d03ff3b60ec Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:37 +0200 Subject: [PATCH 0675/9457] hwspinlock: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/hwspinlock/omap_hwspinlock.c | 1 - drivers/hwspinlock/u8500_hsem.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index c1e2cd4d85fe..47a275c6ece1 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -179,7 +179,6 @@ static struct platform_driver omap_hwspinlock_driver = { .remove = omap_hwspinlock_remove, .driver = { .name = "omap_hwspinlock", - .owner = THIS_MODULE, }, }; diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 401c33bcdb45..e93eabbd660f 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -175,7 +175,6 @@ static struct platform_driver u8500_hsem_driver = { .remove = u8500_hsem_remove, .driver = { .name = "u8500_hsem", - .owner = THIS_MODULE, }, }; -- GitLab From 1ecc4335eba1a264ed8ac5b180a2ffde8113f3db Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:37 +0200 Subject: [PATCH 0676/9457] i2c: busses: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 1 - drivers/i2c/busses/i2c-au1550.c | 1 - drivers/i2c/busses/i2c-bcm-kona.c | 1 - drivers/i2c/busses/i2c-bcm2835.c | 1 - drivers/i2c/busses/i2c-bfin-twi.c | 1 - drivers/i2c/busses/i2c-cadence.c | 1 - drivers/i2c/busses/i2c-cbus-gpio.c | 1 - drivers/i2c/busses/i2c-cpm.c | 1 - drivers/i2c/busses/i2c-davinci.c | 1 - drivers/i2c/busses/i2c-designware-platdrv.c | 1 - drivers/i2c/busses/i2c-efm32.c | 1 - drivers/i2c/busses/i2c-exynos5.c | 1 - drivers/i2c/busses/i2c-gpio.c | 1 - drivers/i2c/busses/i2c-highlander.c | 1 - drivers/i2c/busses/i2c-ibm_iic.c | 1 - drivers/i2c/busses/i2c-imx.c | 1 - drivers/i2c/busses/i2c-iop3xx.c | 1 - drivers/i2c/busses/i2c-isch.c | 1 - drivers/i2c/busses/i2c-kempld.c | 1 - drivers/i2c/busses/i2c-mpc.c | 1 - drivers/i2c/busses/i2c-mv64xxx.c | 1 - drivers/i2c/busses/i2c-mxs.c | 1 - drivers/i2c/busses/i2c-ocores.c | 1 - drivers/i2c/busses/i2c-octeon.c | 1 - drivers/i2c/busses/i2c-omap.c | 1 - drivers/i2c/busses/i2c-parport-light.c | 1 - drivers/i2c/busses/i2c-pca-platform.c | 1 - drivers/i2c/busses/i2c-pmcmsp.c | 1 - drivers/i2c/busses/i2c-pnx.c | 1 - drivers/i2c/busses/i2c-puv3.c | 1 - drivers/i2c/busses/i2c-pxa.c | 1 - drivers/i2c/busses/i2c-qup.c | 1 - drivers/i2c/busses/i2c-rcar.c | 1 - drivers/i2c/busses/i2c-riic.c | 1 - drivers/i2c/busses/i2c-rk3x.c | 1 - drivers/i2c/busses/i2c-s3c2410.c | 1 - drivers/i2c/busses/i2c-sh7760.c | 1 - drivers/i2c/busses/i2c-sh_mobile.c | 1 - drivers/i2c/busses/i2c-simtec.c | 1 - drivers/i2c/busses/i2c-sirf.c | 1 - drivers/i2c/busses/i2c-st.c | 1 - drivers/i2c/busses/i2c-stu300.c | 1 - drivers/i2c/busses/i2c-sun6i-p2wi.c | 1 - drivers/i2c/busses/i2c-tegra.c | 1 - drivers/i2c/busses/i2c-versatile.c | 1 - drivers/i2c/busses/i2c-wmt.c | 1 - drivers/i2c/busses/i2c-xiic.c | 1 - drivers/i2c/busses/i2c-xlr.c | 1 - drivers/i2c/busses/scx200_acb.c | 1 - 49 files changed, 49 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 917d54588d95..b39e0e84ee50 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -851,7 +851,6 @@ static struct platform_driver at91_twi_driver = { .id_table = at91_twi_devtypes, .driver = { .name = "at91_i2c", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_twi_dt_ids), .pm = at91_twi_pm_ops, }, diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 8762458ca7da..74faf6317bce 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -417,7 +417,6 @@ static const struct dev_pm_ops i2c_au1550_pmops = { static struct platform_driver au1xpsc_smbus_driver = { .driver = { .name = "au1xpsc_smbus", - .owner = THIS_MODULE, .pm = AU1XPSC_SMBUS_PMOPS, }, .probe = i2c_au1550_probe, diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c index 18a74a6751a9..2c9d9b1c8e64 100644 --- a/drivers/i2c/busses/i2c-bcm-kona.c +++ b/drivers/i2c/busses/i2c-bcm-kona.c @@ -895,7 +895,6 @@ MODULE_DEVICE_TABLE(of, bcm_kona_i2c_of_match); static struct platform_driver bcm_kona_i2c_driver = { .driver = { .name = "bcm-kona-i2c", - .owner = THIS_MODULE, .of_match_table = bcm_kona_i2c_of_match, }, .probe = bcm_kona_i2c_probe, diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 4b8ecd0b3661..5d6feb937b9d 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -313,7 +313,6 @@ static struct platform_driver bcm2835_i2c_driver = { .remove = bcm2835_i2c_remove, .driver = { .name = "i2c-bcm2835", - .owner = THIS_MODULE, .of_match_table = bcm2835_i2c_of_match, }, }; diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 067c1615e968..af162b4c7a6d 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -717,7 +717,6 @@ static struct platform_driver i2c_bfin_twi_driver = { .remove = i2c_bfin_twi_remove, .driver = { .name = "i2c-bfin-twi", - .owner = THIS_MODULE, .pm = I2C_BFIN_TWI_PM_OPS, }, }; diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 63f3f03ecc9b..04d0a7e449ef 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -890,7 +890,6 @@ MODULE_DEVICE_TABLE(of, cdns_i2c_of_match); static struct platform_driver cdns_i2c_drv = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = cdns_i2c_of_match, .pm = &cdns_i2c_dev_pm_ops, }, diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c index bdf040fd8675..b4f91e48948a 100644 --- a/drivers/i2c/busses/i2c-cbus-gpio.c +++ b/drivers/i2c/busses/i2c-cbus-gpio.c @@ -287,7 +287,6 @@ static struct platform_driver cbus_i2c_driver = { .probe = cbus_i2c_probe, .remove = cbus_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = "i2c-cbus-gpio", .of_match_table = of_match_ptr(i2c_cbus_dt_ids), }, diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f3b89a4698b6..a08069c71555 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -720,7 +720,6 @@ static struct platform_driver cpm_i2c_driver = { .remove = cpm_i2c_remove, .driver = { .name = "fsl-i2c-cpm", - .owner = THIS_MODULE, .of_match_table = cpm_i2c_match, }, }; diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 4d9614719128..dcf671b736b7 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -793,7 +793,6 @@ static struct platform_driver davinci_i2c_driver = { .remove = davinci_i2c_remove, .driver = { .name = "i2c_davinci", - .owner = THIS_MODULE, .pm = davinci_i2c_pm_ops, .of_match_table = davinci_i2c_of_match, }, diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index a7431150acf7..cb0667ce1d40 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -331,7 +331,6 @@ static struct platform_driver dw_i2c_driver = { .remove = dw_i2c_remove, .driver = { .name = "i2c_designware", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(dw_i2c_of_match), .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match), .pm = &dw_i2c_dev_pm_ops, diff --git a/drivers/i2c/busses/i2c-efm32.c b/drivers/i2c/busses/i2c-efm32.c index 10b8323b08d4..8eff62738877 100644 --- a/drivers/i2c/busses/i2c-efm32.c +++ b/drivers/i2c/busses/i2c-efm32.c @@ -473,7 +473,6 @@ static struct platform_driver efm32_i2c_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = efm32_i2c_dt_ids, }, }; diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index 81e6263cd7da..9306a5c3092e 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -861,7 +861,6 @@ static struct platform_driver exynos5_i2c_driver = { .probe = exynos5_i2c_probe, .remove = exynos5_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = "exynos5-hsi2c", .pm = &exynos5_i2c_dev_pm_ops, .of_match_table = exynos5_i2c_match, diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 933f1e453e41..34cfc0ebdcb9 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -260,7 +260,6 @@ MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); static struct platform_driver i2c_gpio_driver = { .driver = { .name = "i2c-gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_gpio_dt_ids), }, .probe = i2c_gpio_probe, diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index 512fcfabc18e..56dc69e7349f 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -456,7 +456,6 @@ static int highlander_i2c_remove(struct platform_device *pdev) static struct platform_driver highlander_i2c_driver = { .driver = { .name = "i2c-highlander", - .owner = THIS_MODULE, }, .probe = highlander_i2c_probe, diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 274312c96b12..722f839cfa3c 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -802,7 +802,6 @@ static const struct of_device_id ibm_iic_match[] = { static struct platform_driver ibm_iic_driver = { .driver = { .name = "ibm-iic", - .owner = THIS_MODULE, .of_match_table = ibm_iic_match, }, .probe = iic_probe, diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index c48e46af670a..3c881913784b 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -777,7 +777,6 @@ static struct platform_driver i2c_imx_driver = { .remove = i2c_imx_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = i2c_imx_dt_ids, }, .id_table = imx_i2c_devtype, diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 3d16c2f60a5e..72d6161cf77c 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -516,7 +516,6 @@ static struct platform_driver iop3xx_i2c_driver = { .probe = iop3xx_i2c_probe, .remove = iop3xx_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = "IOP3xx-I2C", }, }; diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index cf99dbf21fd1..efd8ed6f7f32 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -313,7 +313,6 @@ static int smbus_sch_remove(struct platform_device *pdev) static struct platform_driver smbus_sch_driver = { .driver = { .name = "isch_smbus", - .owner = THIS_MODULE, }, .probe = smbus_sch_probe, .remove = smbus_sch_remove, diff --git a/drivers/i2c/busses/i2c-kempld.c b/drivers/i2c/busses/i2c-kempld.c index af8f65fb1c05..25993d2e64bf 100644 --- a/drivers/i2c/busses/i2c-kempld.c +++ b/drivers/i2c/busses/i2c-kempld.c @@ -394,7 +394,6 @@ static int kempld_i2c_resume(struct platform_device *pdev) static struct platform_driver kempld_i2c_driver = { .driver = { .name = "kempld-i2c", - .owner = THIS_MODULE, }, .probe = kempld_i2c_probe, .remove = kempld_i2c_remove, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 0edf630b099a..795d25ed0f92 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -813,7 +813,6 @@ static struct platform_driver mpc_i2c_driver = { .probe = fsl_i2c_probe, .remove = fsl_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = mpc_i2c_of_match, .pm = MPC_I2C_PM_OPS, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 2f64273d3f2b..373f6d4e4080 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -925,7 +925,6 @@ static struct platform_driver mv64xxx_i2c_driver = { .probe = mv64xxx_i2c_probe, .remove = mv64xxx_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = MV64XXX_I2C_CTLR_NAME, .of_match_table = mv64xxx_i2c_of_match_table, }, diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 07e1be6f8992..a13aeade5d3c 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -893,7 +893,6 @@ static int mxs_i2c_remove(struct platform_device *pdev) static struct platform_driver mxs_i2c_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mxs_i2c_dt_ids, }, .probe = mxs_i2c_probe, diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 2a4fe0b7cfb7..7249b5b1e5d0 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -480,7 +480,6 @@ static struct platform_driver ocores_i2c_driver = { .probe = ocores_i2c_probe, .remove = ocores_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = "ocores-i2c", .of_match_table = ocores_i2c_match, .pm = OCORES_I2C_PM, diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 81042b08a947..6e75e016bffc 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c @@ -623,7 +623,6 @@ static struct platform_driver octeon_i2c_driver = { .probe = octeon_i2c_probe, .remove = octeon_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = octeon_i2c_match, }, diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0dffb0e62c3b..d20c6bc64c70 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1338,7 +1338,6 @@ static struct platform_driver omap_i2c_driver = { .remove = omap_i2c_remove, .driver = { .name = "omap_i2c", - .owner = THIS_MODULE, .pm = OMAP_I2C_PM_OPS, .of_match_table = of_match_ptr(omap_i2c_of_match), }, diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index 62f55fe624cb..96da36f69f06 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c @@ -187,7 +187,6 @@ static int i2c_parport_remove(struct platform_device *pdev) static struct platform_driver i2c_parport_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = i2c_parport_probe, diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 845f12598e79..6336f02ec566 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -280,7 +280,6 @@ static struct platform_driver i2c_pca_pf_driver = { .remove = i2c_pca_pf_remove, .driver = { .name = "i2c-pca-platform", - .owner = THIS_MODULE, }, }; diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 8564768fee32..702d05b7daf3 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -628,7 +628,6 @@ static struct platform_driver pmcmsptwi_driver = { .remove = pmcmsptwi_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index dc7ff829ad78..e814a36d9b78 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -751,7 +751,6 @@ MODULE_DEVICE_TABLE(of, i2c_pnx_of_match); static struct platform_driver i2c_pnx_driver = { .driver = { .name = "pnx-i2c", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_pnx_of_match), .pm = PNX_I2C_PM, }, diff --git a/drivers/i2c/busses/i2c-puv3.c b/drivers/i2c/busses/i2c-puv3.c index c83fc3ccdd2b..82b6f02544da 100644 --- a/drivers/i2c/busses/i2c-puv3.c +++ b/drivers/i2c/busses/i2c-puv3.c @@ -270,7 +270,6 @@ static struct platform_driver puv3_i2c_driver = { .remove = puv3_i2c_remove, .driver = { .name = "PKUnity-v3-I2C", - .owner = THIS_MODULE, .pm = PUV3_I2C_PM, } }; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index be671f7a0e06..495589a78e6c 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1328,7 +1328,6 @@ static struct platform_driver i2c_pxa_driver = { .remove = i2c_pxa_remove, .driver = { .name = "pxa2xx-i2c", - .owner = THIS_MODULE, .pm = I2C_PXA_DEV_PM_OPS, .of_match_table = i2c_pxa_dt_ids, }, diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 092d89bd3224..4dad23bdffbe 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -764,7 +764,6 @@ static struct platform_driver qup_i2c_driver = { .remove = qup_i2c_remove, .driver = { .name = "i2c_qup", - .owner = THIS_MODULE, .pm = &qup_i2c_qup_pm_ops, .of_match_table = qup_i2c_dt_match, }, diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d826e82dd997..a9494eec1ee2 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -620,7 +620,6 @@ MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table); static struct platform_driver rcar_i2c_driver = { .driver = { .name = "i2c-rcar", - .owner = THIS_MODULE, .of_match_table = rcar_i2c_dt_ids, }, .probe = rcar_i2c_probe, diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index af3b3d032a9f..d7e3af671543 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -414,7 +414,6 @@ static struct platform_driver riic_i2c_driver = { .remove = riic_i2c_remove, .driver = { .name = "i2c-riic", - .owner = THIS_MODULE, .of_match_table = riic_i2c_dt_ids, }, }; diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index f486d0eac4d0..045edd74394a 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -753,7 +753,6 @@ static struct platform_driver rk3x_i2c_driver = { .probe = rk3x_i2c_probe, .remove = rk3x_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = "rk3x-i2c", .of_match_table = rk3x_i2c_match, }, diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index e3b0337faeb7..fd4fd0c4ef21 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1305,7 +1305,6 @@ static struct platform_driver s3c24xx_i2c_driver = { .remove = s3c24xx_i2c_remove, .id_table = s3c24xx_driver_ids, .driver = { - .owner = THIS_MODULE, .name = "s3c-i2c", .pm = S3C24XX_DEV_PM_OPS, .of_match_table = of_match_ptr(s3c24xx_i2c_match), diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index d76f3d9737ec..24968384b401 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -552,7 +552,6 @@ static int sh7760_i2c_remove(struct platform_device *pdev) static struct platform_driver sh7760_i2c_drv = { .driver = { .name = SH7760_I2C_DEVNAME, - .owner = THIS_MODULE, }, .probe = sh7760_i2c_probe, .remove = sh7760_i2c_remove, diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 8b5e79cb4468..12b9a69c0285 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -798,7 +798,6 @@ static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = { static struct platform_driver sh_mobile_i2c_driver = { .driver = { .name = "i2c-sh_mobile", - .owner = THIS_MODULE, .pm = &sh_mobile_i2c_dev_pm_ops, .of_match_table = sh_mobile_i2c_dt_ids, }, diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 964e5c6f84ab..e766de8d34e3 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -158,7 +158,6 @@ static int simtec_i2c_remove(struct platform_device *dev) static struct platform_driver simtec_i2c_driver = { .driver = { .name = "simtec-i2c", - .owner = THIS_MODULE, }, .probe = simtec_i2c_probe, .remove = simtec_i2c_remove, diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c index b1336d5f0531..1092d4eeeb54 100644 --- a/drivers/i2c/busses/i2c-sirf.c +++ b/drivers/i2c/busses/i2c-sirf.c @@ -451,7 +451,6 @@ MODULE_DEVICE_TABLE(of, sirfsoc_i2c_of_match); static struct platform_driver i2c_sirfsoc_driver = { .driver = { .name = "sirfsoc_i2c", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &i2c_sirfsoc_pm_ops, #endif diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index 2e4eccd6599a..88057fad9dfe 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -863,7 +863,6 @@ MODULE_DEVICE_TABLE(of, st_i2c_match); static struct platform_driver st_i2c_driver = { .driver = { .name = "st-i2c", - .owner = THIS_MODULE, .of_match_table = st_i2c_match, .pm = ST_I2C_PM, }, diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 6a44f37798c8..4885da9e9298 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -981,7 +981,6 @@ static const struct of_device_id stu300_dt_match[] = { static struct platform_driver stu300_i2c_driver = { .driver = { .name = NAME, - .owner = THIS_MODULE, .pm = STU300_I2C_PM, .of_match_table = stu300_dt_match, }, diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c index 4d75d4759709..7668e2e9b8fd 100644 --- a/drivers/i2c/busses/i2c-sun6i-p2wi.c +++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c @@ -332,7 +332,6 @@ static struct platform_driver p2wi_driver = { .probe = p2wi_probe, .remove = p2wi_remove, .driver = { - .owner = THIS_MODULE, .name = "i2c-sunxi-p2wi", .of_match_table = p2wi_of_match_table, }, diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index efba1ebe16ba..28b87e683503 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -893,7 +893,6 @@ static struct platform_driver tegra_i2c_driver = { .remove = tegra_i2c_remove, .driver = { .name = "tegra-i2c", - .owner = THIS_MODULE, .of_match_table = tegra_i2c_of_match, .pm = TEGRA_I2C_PM, }, diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c index 6bb3a89a440f..240637f01d11 100644 --- a/drivers/i2c/busses/i2c-versatile.c +++ b/drivers/i2c/busses/i2c-versatile.c @@ -138,7 +138,6 @@ static struct platform_driver i2c_versatile_driver = { .remove = i2c_versatile_remove, .driver = { .name = "versatile-i2c", - .owner = THIS_MODULE, .of_match_table = i2c_versatile_match, }, }; diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index f80a38c2072c..82ea34925489 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -462,7 +462,6 @@ static struct platform_driver wmt_i2c_driver = { .remove = wmt_i2c_remove, .driver = { .name = "wmt-i2c", - .owner = THIS_MODULE, .of_match_table = wmt_i2c_dt_ids, }, }; diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index ade9223912d3..e60e67a5fac6 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -771,7 +771,6 @@ static struct platform_driver xiic_i2c_driver = { .probe = xiic_i2c_probe, .remove = xiic_i2c_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = of_match_ptr(xiic_of_match), }, diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 17f7352eca6b..8b36bcfd952d 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -263,7 +263,6 @@ static struct platform_driver xlr_i2c_driver = { .remove = xlr_i2c_remove, .driver = { .name = "xlr-i2cbus", - .owner = THIS_MODULE, }, }; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index ff3f5747e43b..77dacfef072e 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -548,7 +548,6 @@ static int scx200_remove(struct platform_device *pdev) static struct platform_driver scx200_pci_driver = { .driver = { .name = "cs5535-smb", - .owner = THIS_MODULE, }, .probe = scx200_probe, .remove = scx200_remove, -- GitLab From 37e5dc1c277c4efa8d1093171ab77fd3585fca3d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:38 +0200 Subject: [PATCH 0677/9457] i2c: muxes: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 1 - drivers/i2c/muxes/i2c-mux-gpio.c | 1 - drivers/i2c/muxes/i2c-mux-pinctrl.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c index 69afffa8f427..5cf1b60b69e2 100644 --- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -235,7 +235,6 @@ static struct platform_driver i2c_arbitrator_driver = { .probe = i2c_arbitrator_probe, .remove = i2c_arbitrator_remove, .driver = { - .owner = THIS_MODULE, .name = "i2c-arb-gpio-challenge", .of_match_table = i2c_arbitrator_of_match, }, diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index d8989c823f50..f5798eb4076b 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -280,7 +280,6 @@ static struct platform_driver i2c_mux_gpio_driver = { .probe = i2c_mux_gpio_probe, .remove = i2c_mux_gpio_remove, .driver = { - .owner = THIS_MODULE, .name = "i2c-mux-gpio", .of_match_table = i2c_mux_gpio_of_match, }, diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 4ff0ef3e07a6..b48378c4b40d 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -264,7 +264,6 @@ MODULE_DEVICE_TABLE(of, i2c_mux_pinctrl_of_match); static struct platform_driver i2c_mux_pinctrl_driver = { .driver = { .name = "i2c-mux-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_mux_pinctrl_of_match), }, .probe = i2c_mux_pinctrl_probe, -- GitLab From 35316c9ffd6abf7a217f56fb269e71e87c96b599 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:38 +0200 Subject: [PATCH 0678/9457] ide: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/ide/au1xxx-ide.c | 1 - drivers/ide/gayle.c | 1 - drivers/ide/ide_platform.c | 1 - drivers/ide/palm_bk3710.c | 1 - drivers/ide/tx4938ide.c | 1 - drivers/ide/tx4939ide.c | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 07ea58084068..4d181a918d72 100644 --- a/drivers/ide/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c @@ -586,7 +586,6 @@ static int au_ide_remove(struct platform_device *dev) static struct platform_driver au1200_ide_driver = { .driver = { .name = "au1200-ide", - .owner = THIS_MODULE, }, .probe = au_ide_probe, .remove = au_ide_remove, diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 97a2f9dc75d8..901e6ebfeb96 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -179,7 +179,6 @@ static struct platform_driver amiga_gayle_ide_driver = { .remove = __exit_p(amiga_gayle_ide_remove), .driver = { .name = "amiga-gayle-ide", - .owner = THIS_MODULE, }, }; diff --git a/drivers/ide/ide_platform.c b/drivers/ide/ide_platform.c index d48de6de503e..2b43be3bca0a 100644 --- a/drivers/ide/ide_platform.c +++ b/drivers/ide/ide_platform.c @@ -125,7 +125,6 @@ static int plat_ide_remove(struct platform_device *pdev) static struct platform_driver platform_ide_driver = { .driver = { .name = "pata_platform", - .owner = THIS_MODULE, }, .probe = plat_ide_probe, .remove = plat_ide_remove, diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c index ba20d18c0373..8012e43bf8f6 100644 --- a/drivers/ide/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c @@ -386,7 +386,6 @@ MODULE_ALIAS("platform:palm_bk3710"); static struct platform_driver platform_bk_driver = { .driver = { .name = "palm_bk3710", - .owner = THIS_MODULE, }, }; diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 68edd4f58a28..40a3f55b08dd 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c @@ -198,7 +198,6 @@ static int __exit tx4938ide_remove(struct platform_device *pdev) static struct platform_driver tx4938ide_driver = { .driver = { .name = "tx4938ide", - .owner = THIS_MODULE, }, .remove = __exit_p(tx4938ide_remove), }; diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 4ecdee5eca83..67d4a7d4acc8 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c @@ -618,7 +618,6 @@ static int tx4939ide_resume(struct platform_device *dev) static struct platform_driver tx4939ide_driver = { .driver = { .name = MODNAME, - .owner = THIS_MODULE, }, .remove = __exit_p(tx4939ide_remove), .resume = tx4939ide_resume, -- GitLab From 770ca15c0369b9237bf143e3f9c1f5a406cb45b4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:39 +0200 Subject: [PATCH 0679/9457] iio: adc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/iio/adc/rockchip_saradc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index e074a0b03f28..63a9797775cb 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -307,7 +307,6 @@ static struct platform_driver rockchip_saradc_driver = { .remove = rockchip_saradc_remove, .driver = { .name = "rockchip-saradc", - .owner = THIS_MODULE, .of_match_table = rockchip_saradc_match, .pm = &rockchip_saradc_pm_ops, }, -- GitLab From 1d05726c315c146b2ac0c5e94f01fde0c2b73dc1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:39 +0200 Subject: [PATCH 0680/9457] input: keyboard: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/input/keyboard/adp5520-keys.c | 1 - drivers/input/keyboard/amikbd.c | 1 - drivers/input/keyboard/bf54x-keys.c | 1 - drivers/input/keyboard/clps711x-keypad.c | 1 - drivers/input/keyboard/davinci_keyscan.c | 1 - drivers/input/keyboard/ep93xx_keypad.c | 1 - drivers/input/keyboard/goldfish_events.c | 1 - drivers/input/keyboard/gpio_keys.c | 1 - drivers/input/keyboard/gpio_keys_polled.c | 1 - drivers/input/keyboard/imx_keypad.c | 1 - drivers/input/keyboard/jornada680_kbd.c | 1 - drivers/input/keyboard/jornada720_kbd.c | 1 - drivers/input/keyboard/lpc32xx-keys.c | 1 - drivers/input/keyboard/matrix_keypad.c | 1 - drivers/input/keyboard/nomadik-ske-keypad.c | 1 - drivers/input/keyboard/nspire-keypad.c | 1 - drivers/input/keyboard/omap-keypad.c | 1 - drivers/input/keyboard/omap4-keypad.c | 1 - drivers/input/keyboard/pmic8xxx-keypad.c | 1 - drivers/input/keyboard/pxa27x_keypad.c | 1 - drivers/input/keyboard/pxa930_rotary.c | 1 - drivers/input/keyboard/samsung-keypad.c | 1 - drivers/input/keyboard/spear-keyboard.c | 1 - drivers/input/keyboard/tc3589x-keypad.c | 1 - drivers/input/keyboard/tegra-kbc.c | 1 - drivers/input/keyboard/twl4030_keypad.c | 1 - drivers/input/keyboard/w90p910_keypad.c | 1 - 27 files changed, 27 deletions(-) diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index 7f4a8b58efc1..db1004dad108 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -184,7 +184,6 @@ static int adp5520_keys_remove(struct platform_device *pdev) static struct platform_driver adp5520_keys_driver = { .driver = { .name = "adp5520-keys", - .owner = THIS_MODULE, }, .probe = adp5520_keys_probe, .remove = adp5520_keys_remove, diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 096d6067ae1f..d3b8c58fcfdb 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -255,7 +255,6 @@ static struct platform_driver amikbd_driver = { .remove = __exit_p(amikbd_remove), .driver = { .name = "amiga-keyboard", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index e6d46c5994d7..81b07dddae86 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -385,7 +385,6 @@ static int bfin_kpad_resume(struct platform_device *pdev) static struct platform_driver bfin_kpad_device_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = bfin_kpad_probe, .remove = bfin_kpad_remove, diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 552b65c6e6b0..27ef29f8fe6a 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -194,7 +194,6 @@ MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match); static struct platform_driver clps711x_keypad_driver = { .driver = { .name = "clps711x-keypad", - .owner = THIS_MODULE, .of_match_table = clps711x_keypad_of_match, }, .probe = clps711x_keypad_probe, diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 1559dc1cf951..f363d1d2907a 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -322,7 +322,6 @@ static int davinci_ks_remove(struct platform_device *pdev) static struct platform_driver davinci_ks_driver = { .driver = { .name = "davinci_keyscan", - .owner = THIS_MODULE, }, .remove = davinci_ks_remove, }; diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index e59876212b8c..f77b295e0123 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -373,7 +373,6 @@ static int ep93xx_keypad_remove(struct platform_device *pdev) static struct platform_driver ep93xx_keypad_driver = { .driver = { .name = "ep93xx-keypad", - .owner = THIS_MODULE, .pm = &ep93xx_keypad_pm_ops, }, .probe = ep93xx_keypad_probe, diff --git a/drivers/input/keyboard/goldfish_events.c b/drivers/input/keyboard/goldfish_events.c index 69e854763370..907e4e278fce 100644 --- a/drivers/input/keyboard/goldfish_events.c +++ b/drivers/input/keyboard/goldfish_events.c @@ -181,7 +181,6 @@ static int events_probe(struct platform_device *pdev) static struct platform_driver events_driver = { .probe = events_probe, .driver = { - .owner = THIS_MODULE, .name = "goldfish_events", }, }; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 8c98e97f8e41..8f3a24e15402 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -835,7 +835,6 @@ static struct platform_driver gpio_keys_device_driver = { .remove = gpio_keys_remove, .driver = { .name = "gpio-keys", - .owner = THIS_MODULE, .pm = &gpio_keys_pm_ops, .of_match_table = of_match_ptr(gpio_keys_of_match), } diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 432d36395f35..10f0098f3c77 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -307,7 +307,6 @@ static struct platform_driver gpio_keys_polled_driver = { .probe = gpio_keys_polled_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_keys_polled_of_match), }, }; diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 20a99c368d16..e53f232eda0e 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -580,7 +580,6 @@ static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); static struct platform_driver imx_keypad_driver = { .driver = { .name = "imx-keypad", - .owner = THIS_MODULE, .pm = &imx_kbd_pm_ops, .of_match_table = of_match_ptr(imx_keypad_of_match), }, diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 0ba4428da24a..80c81278ad2c 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -237,7 +237,6 @@ static int jornada680kbd_probe(struct platform_device *pdev) static struct platform_driver jornada680kbd_driver = { .driver = { .name = "jornada680_kbd", - .owner = THIS_MODULE, }, .probe = jornada680kbd_probe, }; diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index cd729d485e98..421d9c55b0e8 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c @@ -167,7 +167,6 @@ MODULE_ALIAS("platform:jornada720_kbd"); static struct platform_driver jornada720_kbd_driver = { .driver = { .name = "jornada720_kbd", - .owner = THIS_MODULE, }, .probe = jornada720_kbd_probe, .remove = jornada720_kbd_remove, diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 8b1b01361ec6..8c079371c2e7 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -381,7 +381,6 @@ static struct platform_driver lpc32xx_kscan_driver = { .remove = lpc32xx_kscan_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &lpc32xx_kscan_pm_ops, .of_match_table = lpc32xx_kscan_match, } diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index e651fa692afe..b370a59cb759 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -565,7 +565,6 @@ static struct platform_driver matrix_keypad_driver = { .remove = matrix_keypad_remove, .driver = { .name = "matrix-keypad", - .owner = THIS_MODULE, .pm = &matrix_keypad_pm_ops, .of_match_table = of_match_ptr(matrix_keypad_dt_match), }, diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 63332e2f8628..c7d5b1666fc3 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -425,7 +425,6 @@ static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, static struct platform_driver ske_keypad_driver = { .driver = { .name = "nmk-ske-keypad", - .owner = THIS_MODULE, .pm = &ske_keypad_dev_pm_ops, }, .remove = ske_keypad_remove, diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index b31064981e96..7abfd34eb87e 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c @@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(of, nspire_keypad_dt_match); static struct platform_driver nspire_keypad_driver = { .driver = { .name = "nspire-keypad", - .owner = THIS_MODULE, .of_match_table = nspire_keypad_dt_match, }, .probe = nspire_keypad_probe, diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index b1acc9852eb7..7502e46165fa 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -383,7 +383,6 @@ static struct platform_driver omap_kp_driver = { .resume = omap_kp_resume, .driver = { .name = "omap-keypad", - .owner = THIS_MODULE, }, }; module_platform_driver(omap_kp_driver); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 024b7bdffe5b..b052afec9a11 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -460,7 +460,6 @@ static struct platform_driver omap4_keypad_driver = { .remove = omap4_keypad_remove, .driver = { .name = "omap4-keypad", - .owner = THIS_MODULE, .pm = &omap4_keypad_pm_ops, .of_match_table = omap_keypad_dt_match, }, diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 80c6b0ef3fc8..32580afecc26 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -687,7 +687,6 @@ static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .driver = { .name = "pm8xxx-keypad", - .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, .of_match_table = pm8xxx_match_table, }, diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index a15063bea700..6ab3e7c96329 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -881,7 +881,6 @@ static struct platform_driver pxa27x_keypad_driver = { .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), - .owner = THIS_MODULE, .pm = &pxa27x_keypad_pm_ops, }, }; diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 374ca0246c8f..1cf5211fddaa 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c @@ -189,7 +189,6 @@ static int pxa930_rotary_remove(struct platform_device *pdev) static struct platform_driver pxa930_rotary_driver = { .driver = { .name = "pxa930-rotary", - .owner = THIS_MODULE, }, .probe = pxa930_rotary_probe, .remove = pxa930_rotary_remove, diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 5e80fbf7b5ed..43ebd9c174bc 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -602,7 +602,6 @@ static struct platform_driver samsung_keypad_driver = { .remove = samsung_keypad_remove, .driver = { .name = "samsung-keypad", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(samsung_keypad_dt_match), .pm = &samsung_keypad_pm_ops, }, diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 258af10e5811..f42a543db043 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -385,7 +385,6 @@ static struct platform_driver spear_kbd_driver = { .remove = spear_kbd_remove, .driver = { .name = "keyboard", - .owner = THIS_MODULE, .pm = &spear_kbd_pm_ops, .of_match_table = of_match_ptr(spear_kbd_id_table), }, diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index ad7abae69078..8ff612d160b0 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -505,7 +505,6 @@ static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, static struct platform_driver tc3589x_keypad_driver = { .driver = { .name = "tc3589x-keypad", - .owner = THIS_MODULE, .pm = &tc3589x_keypad_dev_pm_ops, }, .probe = tc3589x_keypad_probe, diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 9757a58bc897..f97c73bd14f8 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -822,7 +822,6 @@ static struct platform_driver tegra_kbc_driver = { .probe = tegra_kbc_probe, .driver = { .name = "tegra-kbc", - .owner = THIS_MODULE, .pm = &tegra_kbc_pm_ops, .of_match_table = tegra_kbc_of_match, }, diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index c5a11700a1bf..bbcccd67247d 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -459,7 +459,6 @@ static struct platform_driver twl4030_kp_driver = { .probe = twl4030_kp_probe, .driver = { .name = "twl4030_keypad", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl4030_keypad_dt_match_table), }, }; diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index e8b9d94daae7..a1ff69c53102 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c @@ -258,7 +258,6 @@ static struct platform_driver w90p910_keypad_driver = { .remove = w90p910_keypad_remove, .driver = { .name = "nuc900-kpi", - .owner = THIS_MODULE, }, }; module_platform_driver(w90p910_keypad_driver); -- GitLab From 776bd315a7721574d7d687dd9abf200735d12a2a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:40 +0200 Subject: [PATCH 0681/9457] input: misc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/input/misc/88pm80x_onkey.c | 1 - drivers/input/misc/88pm860x_onkey.c | 1 - drivers/input/misc/ab8500-ponkey.c | 1 - drivers/input/misc/arizona-haptics.c | 1 - drivers/input/misc/bfin_rotary.c | 1 - drivers/input/misc/cobalt_btns.c | 1 - drivers/input/misc/da9052_onkey.c | 1 - drivers/input/misc/da9055_onkey.c | 1 - drivers/input/misc/dm355evm_keys.c | 1 - drivers/input/misc/gpio-beeper.c | 1 - drivers/input/misc/gpio_tilt_polled.c | 1 - drivers/input/misc/ideapad_slidebar.c | 1 - drivers/input/misc/ixp4xx-beeper.c | 1 - drivers/input/misc/m68kspkr.c | 1 - drivers/input/misc/max77693-haptic.c | 1 - drivers/input/misc/max8925_onkey.c | 1 - drivers/input/misc/max8997_haptic.c | 1 - drivers/input/misc/mc13783-pwrbutton.c | 1 - drivers/input/misc/palmas-pwrbutton.c | 1 - drivers/input/misc/pcap_keys.c | 1 - drivers/input/misc/pcspkr.c | 1 - drivers/input/misc/pm8xxx-vibrator.c | 1 - drivers/input/misc/pmic8xxx-pwrkey.c | 1 - drivers/input/misc/pwm-beeper.c | 1 - drivers/input/misc/rb532_button.c | 1 - drivers/input/misc/retu-pwrbutton.c | 1 - drivers/input/misc/rotary_encoder.c | 1 - drivers/input/misc/sgi_btns.c | 1 - drivers/input/misc/sirfsoc-onkey.c | 1 - drivers/input/misc/soc_button_array.c | 1 - drivers/input/misc/sparcspkr.c | 2 -- drivers/input/misc/twl4030-pwrbutton.c | 1 - drivers/input/misc/twl4030-vibra.c | 1 - drivers/input/misc/twl6040-vibra.c | 1 - drivers/input/misc/wistron_btns.c | 1 - drivers/input/misc/wm831x-on.c | 1 - 36 files changed, 37 deletions(-) diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c index ee43e5b7c881..cf9908f1e5d5 100644 --- a/drivers/input/misc/88pm80x_onkey.c +++ b/drivers/input/misc/88pm80x_onkey.c @@ -153,7 +153,6 @@ static int pm80x_onkey_remove(struct platform_device *pdev) static struct platform_driver pm80x_onkey_driver = { .driver = { .name = "88pm80x-onkey", - .owner = THIS_MODULE, .pm = &pm80x_onkey_pm_ops, }, .probe = pm80x_onkey_probe, diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index 220ce0fa15d9..cfdca6e99779 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c @@ -138,7 +138,6 @@ static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey static struct platform_driver pm860x_onkey_driver = { .driver = { .name = "88pm860x-onkey", - .owner = THIS_MODULE, .pm = &pm860x_onkey_pm_ops, }, .probe = pm860x_onkey_probe, diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 95ef7dd6442d..1f7e15ca5fbe 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -123,7 +123,6 @@ static const struct of_device_id ab8500_ponkey_match[] = { static struct platform_driver ab8500_ponkey_driver = { .driver = { .name = "ab8500-poweron-key", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ab8500_ponkey_match), }, .probe = ab8500_ponkey_probe, diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index ef2e281b0a43..4dbbed74c9e4 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c @@ -225,7 +225,6 @@ static struct platform_driver arizona_haptics_driver = { .remove = arizona_haptics_remove, .driver = { .name = "arizona-haptics", - .owner = THIS_MODULE, }, }; module_platform_driver(arizona_haptics_driver); diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index e69d9bcb37e1..3f4351579372 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -256,7 +256,6 @@ static struct platform_driver bfin_rotary_device_driver = { .remove = bfin_rotary_remove, .driver = { .name = "bfin-rotary", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &bfin_rotary_pm_ops, #endif diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 3e11510ff82d..fbe72afc9347 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -157,7 +157,6 @@ static struct platform_driver cobalt_buttons_driver = { .remove = cobalt_buttons_remove, .driver = { .name = "Cobalt buttons", - .owner = THIS_MODULE, }, }; module_platform_driver(cobalt_buttons_driver); diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c index 184c8f21ab59..266e07fdc182 100644 --- a/drivers/input/misc/da9052_onkey.c +++ b/drivers/input/misc/da9052_onkey.c @@ -149,7 +149,6 @@ static struct platform_driver da9052_onkey_driver = { .remove = da9052_onkey_remove, .driver = { .name = "da9052-onkey", - .owner = THIS_MODULE, }, }; module_platform_driver(da9052_onkey_driver); diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c index 4765799fef74..3251a9693f45 100644 --- a/drivers/input/misc/da9055_onkey.c +++ b/drivers/input/misc/da9055_onkey.c @@ -157,7 +157,6 @@ static struct platform_driver da9055_onkey_driver = { .remove = da9055_onkey_remove, .driver = { .name = "da9055-onkey", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 0eba94f581df..b6b7bd4e5462 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -263,7 +263,6 @@ static struct platform_driver dm355evm_keys_driver = { .probe = dm355evm_keys_probe, .remove = dm355evm_keys_remove, .driver = { - .owner = THIS_MODULE, .name = "dm355evm_keys", }, }; diff --git a/drivers/input/misc/gpio-beeper.c b/drivers/input/misc/gpio-beeper.c index 8886af63eae3..4817c5f0c3e4 100644 --- a/drivers/input/misc/gpio-beeper.c +++ b/drivers/input/misc/gpio-beeper.c @@ -112,7 +112,6 @@ MODULE_DEVICE_TABLE(of, gpio_beeper_of_match); static struct platform_driver gpio_beeper_platform_driver = { .driver = { .name = BEEPER_MODNAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_beeper_of_match), }, .probe = gpio_beeper_probe, diff --git a/drivers/input/misc/gpio_tilt_polled.c b/drivers/input/misc/gpio_tilt_polled.c index 1a81d9115226..f103b99d1852 100644 --- a/drivers/input/misc/gpio_tilt_polled.c +++ b/drivers/input/misc/gpio_tilt_polled.c @@ -199,7 +199,6 @@ static struct platform_driver gpio_tilt_polled_driver = { .remove = gpio_tilt_polled_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/misc/ideapad_slidebar.c b/drivers/input/misc/ideapad_slidebar.c index edfd6239f131..b0acb878d1cf 100644 --- a/drivers/input/misc/ideapad_slidebar.c +++ b/drivers/input/misc/ideapad_slidebar.c @@ -272,7 +272,6 @@ static int ideapad_remove(struct platform_device *pdev) static struct platform_driver slidebar_drv = { .driver = { .name = "ideapad_slidebar", - .owner = THIS_MODULE, }, .remove = ideapad_remove, }; diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index ed8e5e8449d3..1fe149f3def2 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -168,7 +168,6 @@ static void ixp4xx_spkr_shutdown(struct platform_device *dev) static struct platform_driver ixp4xx_spkr_platform_driver = { .driver = { .name = "ixp4xx-beeper", - .owner = THIS_MODULE, }, .probe = ixp4xx_spkr_probe, .remove = ixp4xx_spkr_remove, diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index def21dc84522..312d63623038 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c @@ -100,7 +100,6 @@ static void m68kspkr_shutdown(struct platform_device *dev) static struct platform_driver m68kspkr_platform_driver = { .driver = { .name = "m68kspkr", - .owner = THIS_MODULE, }, .probe = m68kspkr_probe, .remove = m68kspkr_remove, diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 7b1fde93799e..bdc403041139 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -344,7 +344,6 @@ static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops, static struct platform_driver max77693_haptic_driver = { .driver = { .name = "max77693-haptic", - .owner = THIS_MODULE, .pm = &max77693_haptic_pm_ops, }, .probe = max77693_haptic_probe, diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 3809618e6a5d..297e2a9169d5 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c @@ -168,7 +168,6 @@ static SIMPLE_DEV_PM_OPS(max8925_onkey_pm_ops, max8925_onkey_suspend, max8925_on static struct platform_driver max8925_onkey_driver = { .driver = { .name = "max8925-onkey", - .owner = THIS_MODULE, .pm = &max8925_onkey_pm_ops, }, .probe = max8925_onkey_probe, diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index a363ebbd9cc0..5b3154edf822 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -401,7 +401,6 @@ MODULE_DEVICE_TABLE(i2c, max8997_haptic_id); static struct platform_driver max8997_haptic_driver = { .driver = { .name = "max8997-haptic", - .owner = THIS_MODULE, .pm = &max8997_haptic_pm_ops, }, .probe = max8997_haptic_probe, diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c index 0df6e8d8bd03..afdf8ef25ee8 100644 --- a/drivers/input/misc/mc13783-pwrbutton.c +++ b/drivers/input/misc/mc13783-pwrbutton.c @@ -258,7 +258,6 @@ static struct platform_driver mc13783_pwrbutton_driver = { .remove = mc13783_pwrbutton_remove, .driver = { .name = "mc13783-pwrbutton", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c index f505ac3a8d87..066c5ab632c8 100644 --- a/drivers/input/misc/palmas-pwrbutton.c +++ b/drivers/input/misc/palmas-pwrbutton.c @@ -319,7 +319,6 @@ static struct platform_driver palmas_pwron_driver = { .remove = palmas_pwron_remove, .driver = { .name = "palmas_pwrbutton", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_palmas_pwr_match), .pm = &palmas_pwron_pm, }, diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index cd230365166e..3b81daf67726 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c @@ -121,7 +121,6 @@ static struct platform_driver pcap_keys_device_driver = { .remove = pcap_keys_remove, .driver = { .name = "pcap-keys", - .owner = THIS_MODULE, } }; module_platform_driver(pcap_keys_device_driver); diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 674a2cfc3c0e..72b1fc3ab910 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -125,7 +125,6 @@ static const struct dev_pm_ops pcspkr_pm_ops = { static struct platform_driver pcspkr_platform_driver = { .driver = { .name = "pcspkr", - .owner = THIS_MODULE, .pm = &pcspkr_pm_ops, }, .probe = pcspkr_probe, diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index 6a915ba31bba..e9c77a95717e 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -224,7 +224,6 @@ static struct platform_driver pm8xxx_vib_driver = { .probe = pm8xxx_vib_probe, .driver = { .name = "pm8xxx-vib", - .owner = THIS_MODULE, .pm = &pm8xxx_vib_pm_ops, .of_match_table = pm8xxx_vib_id_table, }, diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index c91e3d33aea9..cb799177cbd5 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -195,7 +195,6 @@ static struct platform_driver pmic8xxx_pwrkey_driver = { .remove = pmic8xxx_pwrkey_remove, .driver = { .name = "pm8xxx-pwrkey", - .owner = THIS_MODULE, .pm = &pm8xxx_pwr_key_pm_ops, .of_match_table = pm8xxx_pwr_key_id_table, }, diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 8ef288e7c971..294aa48bad50 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -187,7 +187,6 @@ static struct platform_driver pwm_beeper_driver = { .remove = pwm_beeper_remove, .driver = { .name = "pwm-beeper", - .owner = THIS_MODULE, .pm = PWM_BEEPER_PM_OPS, .of_match_table = of_match_ptr(pwm_beeper_match), }, diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c index 83fff38b86b3..e956e81cd4e6 100644 --- a/drivers/input/misc/rb532_button.c +++ b/drivers/input/misc/rb532_button.c @@ -96,7 +96,6 @@ static struct platform_driver rb532_button_driver = { .remove = rb532_button_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(rb532_button_driver); diff --git a/drivers/input/misc/retu-pwrbutton.c b/drivers/input/misc/retu-pwrbutton.c index 4bff1aa9b0db..0c8ac60e2639 100644 --- a/drivers/input/misc/retu-pwrbutton.c +++ b/drivers/input/misc/retu-pwrbutton.c @@ -85,7 +85,6 @@ static struct platform_driver retu_pwrbutton_driver = { .remove = retu_pwrbutton_remove, .driver = { .name = "retu-pwrbutton", - .owner = THIS_MODULE, }, }; module_platform_driver(retu_pwrbutton_driver); diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 93558a1c7f70..f27f81ee84ed 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -325,7 +325,6 @@ static struct platform_driver rotary_encoder_driver = { .remove = rotary_encoder_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rotary_encoder_of_match), } }; diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index f10474937a64..7bbe79d89f5c 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -157,7 +157,6 @@ static struct platform_driver sgi_buttons_driver = { .remove = sgi_buttons_remove, .driver = { .name = "sgibtns", - .owner = THIS_MODULE, }, }; module_platform_driver(sgi_buttons_driver); diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index fed5102e1802..4faf9f8d1240 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -205,7 +205,6 @@ static struct platform_driver sirfsoc_pwrc_driver = { .remove = sirfsoc_pwrc_remove, .driver = { .name = "sirfsoc-pwrc", - .owner = THIS_MODULE, .pm = &sirfsoc_pwrc_pm_ops, .of_match_table = sirfsoc_pwrc_of_match, } diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 735604753568..e9e4d6a6741e 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -214,7 +214,6 @@ static struct platform_driver soc_button_driver = { .remove = soc_button_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .acpi_match_table = ACPI_PTR(soc_button_acpi_match), }, }; diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 179ff1cd6f6b..54116e544c96 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -257,7 +257,6 @@ static const struct of_device_id bbc_beep_match[] = { static struct platform_driver bbc_beep_driver = { .driver = { .name = "bbcbeep", - .owner = THIS_MODULE, .of_match_table = bbc_beep_match, }, .probe = bbc_beep_probe, @@ -337,7 +336,6 @@ static const struct of_device_id grover_beep_match[] = { static struct platform_driver grover_beep_driver = { .driver = { .name = "groverbeep", - .owner = THIS_MODULE, .of_match_table = grover_beep_match, }, .probe = grover_beep_probe, diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index fb3b63b2f85c..380580e77f9f 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -101,7 +101,6 @@ static struct platform_driver twl4030_pwrbutton_driver = { .probe = twl4030_pwrbutton_probe, .driver = { .name = "twl4030_pwrbutton", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl4030_pwrbutton_dt_match_table), }, }; diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 960ef2a70910..ccd6dd18f8f6 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -253,7 +253,6 @@ static struct platform_driver twl4030_vibra_driver = { .probe = twl4030_vibra_probe, .driver = { .name = "twl4030-vibra", - .owner = THIS_MODULE, .pm = &twl4030_vibra_pm_ops, }, }; diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 6d26eecc278c..96e0e0c0ccb1 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -388,7 +388,6 @@ static struct platform_driver twl6040_vibra_driver = { .probe = twl6040_vibra_probe, .driver = { .name = "twl6040-vibra", - .owner = THIS_MODULE, .pm = &twl6040_vibra_pm_ops, }, }; diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 7b7add5061a5..e25f87ba19f6 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -1347,7 +1347,6 @@ static const struct dev_pm_ops wistron_pm_ops = { static struct platform_driver wistron_driver = { .driver = { .name = "wistron-bios", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &wistron_pm_ops, #endif diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index 173b6dcca0da..59d4f7bcb4a3 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c @@ -138,7 +138,6 @@ static struct platform_driver wm831x_on_driver = { .remove = wm831x_on_remove, .driver = { .name = "wm831x-on", - .owner = THIS_MODULE, }, }; module_platform_driver(wm831x_on_driver); -- GitLab From 128562fb2ad542ab66f293fa2fec92e0ea3e531c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:40 +0200 Subject: [PATCH 0682/9457] input: mouse: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/input/mouse/amimouse.c | 1 - drivers/input/mouse/gpio_mouse.c | 1 - drivers/input/mouse/navpoint.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 62ec52b2e347..a7fd8f22ba56 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -141,7 +141,6 @@ static struct platform_driver amimouse_driver = { .remove = __exit_p(amimouse_remove), .driver = { .name = "amiga-mouse", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 8c7d94200bdb..ced07391304b 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c @@ -171,7 +171,6 @@ static struct platform_driver gpio_mouse_device_driver = { .remove = gpio_mouse_remove, .driver = { .name = "gpio_mouse", - .owner = THIS_MODULE, } }; module_platform_driver(gpio_mouse_device_driver); diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c index 1ccc88af1f0b..2a0360f5b5f7 100644 --- a/drivers/input/mouse/navpoint.c +++ b/drivers/input/mouse/navpoint.c @@ -355,7 +355,6 @@ static struct platform_driver navpoint_driver = { .remove = navpoint_remove, .driver = { .name = "navpoint", - .owner = THIS_MODULE, .pm = &navpoint_pm_ops, }, }; -- GitLab From 947a0687d19f7bc589183f1f0e2ca46e59cf8310 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:41 +0200 Subject: [PATCH 0683/9457] input: serio: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/input/serio/altera_ps2.c | 1 - drivers/input/serio/apbps2.c | 1 - drivers/input/serio/arc_ps2.c | 1 - drivers/input/serio/at32psif.c | 1 - drivers/input/serio/ct82c710.c | 1 - drivers/input/serio/i8042-sparcio.h | 1 - drivers/input/serio/i8042.c | 1 - drivers/input/serio/maceps2.c | 1 - drivers/input/serio/olpc_apsp.c | 1 - drivers/input/serio/q40kbd.c | 1 - drivers/input/serio/rpckbd.c | 1 - drivers/input/serio/xilinx_ps2.c | 1 - 12 files changed, 12 deletions(-) diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index cce69d6b9587..e8420ddd57f2 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -189,7 +189,6 @@ static struct platform_driver altera_ps2_driver = { .remove = altera_ps2_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(altera_ps2_match), }, }; diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index 98be824544a5..45d4e08ca4f8 100644 --- a/drivers/input/serio/apbps2.c +++ b/drivers/input/serio/apbps2.c @@ -214,7 +214,6 @@ MODULE_DEVICE_TABLE(of, apbps2_of_match); static struct platform_driver apbps2_of_driver = { .driver = { .name = "grlib-apbps2", - .owner = THIS_MODULE, .of_match_table = apbps2_of_match, }, .probe = apbps2_of_probe, diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c index 8024a6d7fccb..99e57a418753 100644 --- a/drivers/input/serio/arc_ps2.c +++ b/drivers/input/serio/arc_ps2.c @@ -266,7 +266,6 @@ MODULE_DEVICE_TABLE(of, arc_ps2_match); static struct platform_driver arc_ps2_driver = { .driver = { .name = "arc_ps2", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(arc_ps2_match), }, .probe = arc_ps2_probe, diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 3290b287ac4b..2e4ff5bac754 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -352,7 +352,6 @@ static struct platform_driver psif_driver = { .remove = __exit_p(psif_remove), .driver = { .name = "atmel_psif", - .owner = THIS_MODULE, .pm = &psif_pm_ops, }, }; diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index cfe549d4eaa5..9c54c43c9749 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -209,7 +209,6 @@ static int ct82c710_remove(struct platform_device *dev) static struct platform_driver ct82c710_driver = { .driver = { .name = "ct82c710", - .owner = THIS_MODULE, }, .probe = ct82c710_probe, .remove = ct82c710_remove, diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 93cb7912703c..afcd1c1a05b2 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(of, sparc_i8042_match); static struct platform_driver sparc_i8042_driver = { .driver = { .name = "i8042", - .owner = THIS_MODULE, .of_match_table = sparc_i8042_match, }, .probe = sparc_i8042_probe, diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 9a97c2b10926..10c6852250c6 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1463,7 +1463,6 @@ static int i8042_remove(struct platform_device *dev) static struct platform_driver i8042_driver = { .driver = { .name = "i8042", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &i8042_pm_ops, #endif diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index bc85e1cc66d8..e365c5f4cbc9 100644 --- a/drivers/input/serio/maceps2.c +++ b/drivers/input/serio/maceps2.c @@ -162,7 +162,6 @@ static int maceps2_remove(struct platform_device *dev) static struct platform_driver maceps2_driver = { .driver = { .name = "maceps2", - .owner = THIS_MODULE, }, .probe = maceps2_probe, .remove = maceps2_remove, diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c index d906f3ebc8c8..8e9a4209fcad 100644 --- a/drivers/input/serio/olpc_apsp.c +++ b/drivers/input/serio/olpc_apsp.c @@ -273,7 +273,6 @@ static struct platform_driver olpc_apsp_driver = { .remove = olpc_apsp_remove, .driver = { .name = "olpc-apsp", - .owner = THIS_MODULE, .of_match_table = olpc_apsp_dt_ids, }, }; diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 594256c38554..5a9d521510bf 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -186,7 +186,6 @@ static int q40kbd_remove(struct platform_device *pdev) static struct platform_driver q40kbd_driver = { .driver = { .name = "q40kbd", - .owner = THIS_MODULE, }, .remove = q40kbd_remove, }; diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index e462e7791bb8..8cf964736902 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -168,7 +168,6 @@ static struct platform_driver rpckbd_driver = { .remove = rpckbd_remove, .driver = { .name = "kart", - .owner = THIS_MODULE, }, }; module_platform_driver(rpckbd_driver); diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index e6cf52ebad87..5223cbf94262 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -363,7 +363,6 @@ MODULE_DEVICE_TABLE(of, xps2_of_match); static struct platform_driver xps2_of_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = xps2_of_match, }, .probe = xps2_of_probe, -- GitLab From 7b8f16c2d1a81b29035379b471226ea09817a29c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:41 +0200 Subject: [PATCH 0684/9457] input: touchscreen: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/input/touchscreen/88pm860x-ts.c | 1 - drivers/input/touchscreen/atmel-wm97xx.c | 1 - drivers/input/touchscreen/da9034-ts.c | 1 - drivers/input/touchscreen/da9052_tsi.c | 1 - drivers/input/touchscreen/intel-mid-touch.c | 1 - drivers/input/touchscreen/jornada720_ts.c | 1 - drivers/input/touchscreen/lpc32xx_ts.c | 1 - drivers/input/touchscreen/mc13783_ts.c | 1 - drivers/input/touchscreen/pcap_ts.c | 1 - drivers/input/touchscreen/s3c2410_ts.c | 1 - drivers/input/touchscreen/stmpe-ts.c | 1 - drivers/input/touchscreen/sun4i-ts.c | 1 - drivers/input/touchscreen/ti_am335x_tsc.c | 1 - drivers/input/touchscreen/tps6507x-ts.c | 1 - drivers/input/touchscreen/ucb1400_ts.c | 1 - drivers/input/touchscreen/w90p910_ts.c | 1 - drivers/input/touchscreen/wm831x-ts.c | 1 - 17 files changed, 17 deletions(-) diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 0d4a9fad4a78..251ff2aa0633 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -292,7 +292,6 @@ static int pm860x_touch_probe(struct platform_device *pdev) static struct platform_driver pm860x_touch_driver = { .driver = { .name = "88pm860x-touch", - .owner = THIS_MODULE, }, .probe = pm860x_touch_probe, }; diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index 279c0e42b8a7..7ec0421c0dd8 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c @@ -425,7 +425,6 @@ static struct platform_driver atmel_wm97xx_driver = { .remove = __exit_p(atmel_wm97xx_remove), .driver = { .name = "wm97xx-touch", - .owner = THIS_MODULE, .pm = &atmel_wm97xx_pm_ops, }, }; diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index cf6f4b31db4d..8264822dc4b9 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c @@ -357,7 +357,6 @@ static int da9034_touch_probe(struct platform_device *pdev) static struct platform_driver da9034_touch_driver = { .driver = { .name = "da9034-touch", - .owner = THIS_MODULE, }, .probe = da9034_touch_probe, }; diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c index ab64d58c3ac0..5a013bb7bcad 100644 --- a/drivers/input/touchscreen/da9052_tsi.c +++ b/drivers/input/touchscreen/da9052_tsi.c @@ -337,7 +337,6 @@ static struct platform_driver da9052_tsi_driver = { .remove = da9052_ts_remove, .driver = { .name = "da9052-tsi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index c38ca4a7e386..b4f0725a1c3d 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c @@ -644,7 +644,6 @@ static int mrstouch_probe(struct platform_device *pdev) static struct platform_driver mrstouch_driver = { .driver = { .name = "pmic_touch", - .owner = THIS_MODULE, }, .probe = mrstouch_probe, }; diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index 651ec71a5c68..ea3b6a5b83e6 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -148,7 +148,6 @@ static struct platform_driver jornada720_ts_driver = { .probe = jornada720_ts_probe, .driver = { .name = "jornada_ts", - .owner = THIS_MODULE, }, }; module_platform_driver(jornada720_ts_driver); diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index bb47d3442a35..24d704cd9f88 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c @@ -396,7 +396,6 @@ static struct platform_driver lpc32xx_ts_driver = { .remove = lpc32xx_ts_remove, .driver = { .name = MOD_NAME, - .owner = THIS_MODULE, .pm = LPC32XX_TS_PM_OPS, .of_match_table = of_match_ptr(lpc32xx_tsc_of_match), }, diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index d6f099c47f84..913e25a994b4 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c @@ -243,7 +243,6 @@ static int mc13783_ts_remove(struct platform_device *pdev) static struct platform_driver mc13783_ts_driver = { .remove = mc13783_ts_remove, .driver = { - .owner = THIS_MODULE, .name = MC13783_TS_NAME, }, }; diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index cff2376817e5..23a354a392ae 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -247,7 +247,6 @@ static struct platform_driver pcap_ts_driver = { .remove = pcap_ts_remove, .driver = { .name = "pcap-ts", - .owner = THIS_MODULE, .pm = PCAP_TS_PM_OPS, }, }; diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 5a69ded9b53c..bdfa27dc097b 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -422,7 +422,6 @@ MODULE_DEVICE_TABLE(platform, s3cts_driver_ids); static struct platform_driver s3c_ts_driver = { .driver = { .name = "samsung-ts", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &s3c_ts_pmops, #endif diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 42ce31afa259..2d5ff86b343f 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c @@ -384,7 +384,6 @@ static int stmpe_ts_remove(struct platform_device *pdev) static struct platform_driver stmpe_ts_driver = { .driver = { .name = STMPE_TS_NAME, - .owner = THIS_MODULE, }, .probe = stmpe_input_probe, .remove = stmpe_ts_remove, diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c index 2ba826024954..28a06749ae42 100644 --- a/drivers/input/touchscreen/sun4i-ts.c +++ b/drivers/input/touchscreen/sun4i-ts.c @@ -324,7 +324,6 @@ MODULE_DEVICE_TABLE(of, sun4i_ts_of_match); static struct platform_driver sun4i_ts_driver = { .driver = { - .owner = THIS_MODULE, .name = "sun4i-ts", .of_match_table = of_match_ptr(sun4i_ts_of_match), }, diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 2ce649520fe0..004f1346a957 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -518,7 +518,6 @@ static struct platform_driver ti_tsc_driver = { .remove = titsc_remove, .driver = { .name = "TI-am335x-tsc", - .owner = THIS_MODULE, .pm = TITSC_PM_OPS, .of_match_table = ti_tsc_dt_ids, }, diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index 94cde2cb1491..4ffd829d1990 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -314,7 +314,6 @@ static int tps6507x_ts_remove(struct platform_device *pdev) static struct platform_driver tps6507x_ts_driver = { .driver = { .name = "tps6507x-ts", - .owner = THIS_MODULE, }, .probe = tps6507x_ts_probe, .remove = tps6507x_ts_remove, diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index b46c55cd1bbb..0eca00da584b 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -444,7 +444,6 @@ static struct platform_driver ucb1400_ts_driver = { .remove = ucb1400_ts_remove, .driver = { .name = "ucb1400_ts", - .owner = THIS_MODULE, .pm = &ucb1400_ts_pm_ops, }, }; diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 003d0c3b5d08..da6004e97753 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c @@ -326,7 +326,6 @@ static struct platform_driver w90x900ts_driver = { .remove = w90x900ts_remove, .driver = { .name = "nuc900-ts", - .owner = THIS_MODULE, }, }; module_platform_driver(w90x900ts_driver); diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index 1b953a066b2c..1db0a1410929 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c @@ -392,7 +392,6 @@ static int wm831x_ts_remove(struct platform_device *pdev) static struct platform_driver wm831x_ts_driver = { .driver = { .name = "wm831x-touch", - .owner = THIS_MODULE, }, .probe = wm831x_ts_probe, .remove = wm831x_ts_remove, -- GitLab From 98b773cf7b6b0d1c2e809702c5c05cf59eaefda8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:42 +0200 Subject: [PATCH 0685/9457] iommu: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/iommu/arm-smmu.c | 1 - drivers/iommu/exynos-iommu.c | 1 - drivers/iommu/fsl_pamu.c | 1 - drivers/iommu/ipmmu-vmsa.c | 1 - drivers/iommu/shmobile-ipmmu.c | 1 - drivers/iommu/tegra-gart.c | 1 - drivers/iommu/tegra-smmu.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 60558f794922..480951484376 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -2062,7 +2062,6 @@ static int arm_smmu_device_remove(struct platform_device *pdev) static struct platform_driver arm_smmu_driver = { .driver = { - .owner = THIS_MODULE, .name = "arm-smmu", .of_match_table = of_match_ptr(arm_smmu_of_match), }, diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 74233186f6f7..e940f5077126 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -684,7 +684,6 @@ static const struct of_device_id sysmmu_of_match[] __initconst = { static struct platform_driver exynos_sysmmu_driver __refdata = { .probe = exynos_sysmmu_probe, .driver = { - .owner = THIS_MODULE, .name = "exynos-sysmmu", .of_match_table = sysmmu_of_match, } diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index 2b6ce9387af1..80ac68d884c5 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -1227,7 +1227,6 @@ static const struct of_device_id fsl_of_pamu_ids[] = { static struct platform_driver fsl_of_pamu_driver = { .driver = { .name = "fsl-of-pamu", - .owner = THIS_MODULE, }, .probe = fsl_pamu_probe, }; diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 7dab5cbcc775..33c9d5327e70 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1221,7 +1221,6 @@ static int ipmmu_remove(struct platform_device *pdev) static struct platform_driver ipmmu_driver = { .driver = { - .owner = THIS_MODULE, .name = "ipmmu-vmsa", }, .probe = ipmmu_probe, diff --git a/drivers/iommu/shmobile-ipmmu.c b/drivers/iommu/shmobile-ipmmu.c index bd97adecb1fd..951651a9746b 100644 --- a/drivers/iommu/shmobile-ipmmu.c +++ b/drivers/iommu/shmobile-ipmmu.c @@ -118,7 +118,6 @@ static int ipmmu_probe(struct platform_device *pdev) static struct platform_driver ipmmu_driver = { .probe = ipmmu_probe, .driver = { - .owner = THIS_MODULE, .name = "ipmmu", }, }; diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index a6d76abf2c06..f722a0c466cf 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c @@ -425,7 +425,6 @@ static struct platform_driver tegra_gart_driver = { .probe = tegra_gart_probe, .remove = tegra_gart_remove, .driver = { - .owner = THIS_MODULE, .name = "tegra-gart", .pm = &tegra_gart_pm_ops, .of_match_table = tegra_gart_of_match, diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 3afdf43f732a..6157946ae73d 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -1269,7 +1269,6 @@ static struct platform_driver tegra_smmu_driver = { .probe = tegra_smmu_probe, .remove = tegra_smmu_remove, .driver = { - .owner = THIS_MODULE, .name = "tegra-smmu", .pm = &tegra_smmu_pm_ops, .of_match_table = tegra_smmu_of_match, -- GitLab From b79d4b7717b1355f3215278dc5942f42afb00a1b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:42 +0200 Subject: [PATCH 0686/9457] irqchip: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/irqchip/irq-keystone.c | 1 - drivers/irqchip/irq-renesas-intc-irqpin.c | 1 - drivers/irqchip/irq-renesas-irqc.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 608abf9c9283..78e8b3ce5252 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -218,7 +218,6 @@ static struct platform_driver keystone_irq_device_driver = { .remove = keystone_irq_remove, .driver = { .name = "keystone_irq", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(keystone_irq_dt_ids), } }; diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 542e850f4946..078cac5e2d08 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -562,7 +562,6 @@ static struct platform_driver intc_irqpin_device_driver = { .driver = { .name = "renesas_intc_irqpin", .of_match_table = intc_irqpin_dt_ids, - .owner = THIS_MODULE, } }; diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 8777065012a5..384e6ed61d7c 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -281,7 +281,6 @@ static struct platform_driver irqc_device_driver = { .driver = { .name = "renesas_irqc", .of_match_table = irqc_dt_ids, - .owner = THIS_MODULE, } }; -- GitLab From 81902d5f658f5c8c0fbdff7c598fe24d4d521c05 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:43 +0200 Subject: [PATCH 0687/9457] leds: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/leds/leds-88pm860x.c | 1 - drivers/leds/leds-adp5520.c | 1 - drivers/leds/leds-asic3.c | 1 - drivers/leds/leds-clevo-mail.c | 1 - drivers/leds/leds-cobalt-qube.c | 1 - drivers/leds/leds-cobalt-raq.c | 1 - drivers/leds/leds-da903x.c | 1 - drivers/leds/leds-da9052.c | 1 - drivers/leds/leds-gpio.c | 1 - drivers/leds/leds-hp6xx.c | 1 - drivers/leds/leds-lm3533.c | 1 - drivers/leds/leds-lp8788.c | 1 - drivers/leds/leds-lt3593.c | 1 - drivers/leds/leds-max8997.c | 1 - drivers/leds/leds-mc13783.c | 1 - drivers/leds/leds-menf21bmc.c | 1 - drivers/leds/leds-net48xx.c | 1 - drivers/leds/leds-netxbig.c | 1 - drivers/leds/leds-ns2.c | 1 - drivers/leds/leds-ot200.c | 1 - drivers/leds/leds-pwm.c | 1 - drivers/leds/leds-rb532.c | 1 - drivers/leds/leds-regulator.c | 1 - drivers/leds/leds-s3c24xx.c | 1 - drivers/leds/leds-sunfire.c | 2 -- drivers/leds/leds-wm831x-status.c | 1 - drivers/leds/leds-wm8350.c | 1 - drivers/leds/leds-wrap.c | 1 - 28 files changed, 29 deletions(-) diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index c2def5551ce1..1497a09166d6 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -237,7 +237,6 @@ static int pm860x_led_remove(struct platform_device *pdev) static struct platform_driver pm860x_led_driver = { .driver = { .name = "88pm860x-led", - .owner = THIS_MODULE, }, .probe = pm860x_led_probe, .remove = pm860x_led_remove, diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c index 5036d7b4f82e..07e66cae32d3 100644 --- a/drivers/leds/leds-adp5520.c +++ b/drivers/leds/leds-adp5520.c @@ -201,7 +201,6 @@ static int adp5520_led_remove(struct platform_device *pdev) static struct platform_driver adp5520_led_driver = { .driver = { .name = "adp5520-led", - .owner = THIS_MODULE, }, .probe = adp5520_led_probe, .remove = adp5520_led_remove, diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c index 70c74a7f0dfe..1b71eac639f0 100644 --- a/drivers/leds/leds-asic3.c +++ b/drivers/leds/leds-asic3.c @@ -168,7 +168,6 @@ static struct platform_driver asic3_led_driver = { .remove = asic3_led_remove, .driver = { .name = "leds-asic3", - .owner = THIS_MODULE, .pm = &asic3_led_pm_ops, }, }; diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index f58a354428e3..0f9ed1ea0e89 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c @@ -168,7 +168,6 @@ static struct platform_driver clevo_mail_led_driver = { .remove = clevo_mail_led_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index 910339d86edf..d97522080491 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c @@ -76,7 +76,6 @@ static struct platform_driver cobalt_qube_led_driver = { .remove = cobalt_qube_led_remove, .driver = { .name = "cobalt-qube-leds", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c index 001088b31373..06dbe18a2065 100644 --- a/drivers/leds/leds-cobalt-raq.c +++ b/drivers/leds/leds-cobalt-raq.c @@ -124,7 +124,6 @@ static struct platform_driver cobalt_raq_led_driver = { .remove = cobalt_raq_led_remove, .driver = { .name = "cobalt-raq-leds", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c index 54b8b5216b8b..952ba96e5b38 100644 --- a/drivers/leds/leds-da903x.c +++ b/drivers/leds/leds-da903x.c @@ -144,7 +144,6 @@ static int da903x_led_remove(struct platform_device *pdev) static struct platform_driver da903x_led_driver = { .driver = { .name = "da903x-led", - .owner = THIS_MODULE, }, .probe = da903x_led_probe, .remove = da903x_led_remove, diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c index e4da1f460ac5..28291b6acc8e 100644 --- a/drivers/leds/leds-da9052.c +++ b/drivers/leds/leds-da9052.c @@ -199,7 +199,6 @@ static int da9052_led_remove(struct platform_device *pdev) static struct platform_driver da9052_led_driver = { .driver = { .name = "da9052-leds", - .owner = THIS_MODULE, }, .probe = da9052_led_probe, .remove = da9052_led_remove, diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 57ff20fecf57..eda0c87dd9e4 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -289,7 +289,6 @@ static struct platform_driver gpio_led_driver = { .remove = gpio_led_remove, .driver = { .name = "leds-gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_gpio_leds_match), }, }; diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index d61a98896c71..0b84c0113126 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c @@ -83,7 +83,6 @@ static struct platform_driver hp6xxled_driver = { .remove = hp6xxled_remove, .driver = { .name = "hp6xx-led", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c index cbf61a40137d..6e2e02035dd7 100644 --- a/drivers/leds/leds-lm3533.c +++ b/drivers/leds/leds-lm3533.c @@ -766,7 +766,6 @@ static void lm3533_led_shutdown(struct platform_device *pdev) static struct platform_driver lm3533_led_driver = { .driver = { .name = "lm3533-leds", - .owner = THIS_MODULE, }, .probe = lm3533_led_probe, .remove = lm3533_led_remove, diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c index 7c2cb384e7ae..3409f03c1fa8 100644 --- a/drivers/leds/leds-lp8788.c +++ b/drivers/leds/leds-lp8788.c @@ -183,7 +183,6 @@ static struct platform_driver lp8788_led_driver = { .remove = lp8788_led_remove, .driver = { .name = LP8788_DEV_KEYLED, - .owner = THIS_MODULE, }, }; module_platform_driver(lp8788_led_driver); diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index 059f5b1f3553..9f41124765cc 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c @@ -184,7 +184,6 @@ static struct platform_driver lt3593_led_driver = { .remove = lt3593_led_remove, .driver = { .name = "leds-lt3593", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c index 607bc2755aba..c592aa5662bb 100644 --- a/drivers/leds/leds-max8997.c +++ b/drivers/leds/leds-max8997.c @@ -303,7 +303,6 @@ static int max8997_led_remove(struct platform_device *pdev) static struct platform_driver max8997_led_driver = { .driver = { .name = "max8997-led", - .owner = THIS_MODULE, }, .probe = max8997_led_probe, .remove = max8997_led_remove, diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c index f1db88e25138..85c3714e1b5a 100644 --- a/drivers/leds/leds-mc13783.c +++ b/drivers/leds/leds-mc13783.c @@ -325,7 +325,6 @@ MODULE_DEVICE_TABLE(platform, mc13xxx_led_id_table); static struct platform_driver mc13xxx_led_driver = { .driver = { .name = "mc13xxx-led", - .owner = THIS_MODULE, }, .remove = mc13xxx_led_remove, .id_table = mc13xxx_led_id_table, diff --git a/drivers/leds/leds-menf21bmc.c b/drivers/leds/leds-menf21bmc.c index 89dd57769e3b..4b9eea815b1a 100644 --- a/drivers/leds/leds-menf21bmc.c +++ b/drivers/leds/leds-menf21bmc.c @@ -119,7 +119,6 @@ static struct platform_driver menf21bmc_led = { .remove = menf21bmc_led_remove, .driver = { .name = "menf21bmc_led", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c index 27d06c528246..ec3a2e8adcae 100644 --- a/drivers/leds/leds-net48xx.c +++ b/drivers/leds/leds-net48xx.c @@ -53,7 +53,6 @@ static struct platform_driver net48xx_led_driver = { .remove = net48xx_led_remove, .driver = { .name = DRVNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 64fde485dcaa..26515c27ea8c 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -404,7 +404,6 @@ static struct platform_driver netxbig_led_driver = { .remove = netxbig_led_remove, .driver = { .name = "leds-netxbig", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 231993d1fe21..1fd6adbb43b7 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c @@ -380,7 +380,6 @@ static struct platform_driver ns2_led_driver = { .remove = ns2_led_remove, .driver = { .name = "leds-ns2", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_ns2_leds_match), }, }; diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c index c9d906098466..39870de20a26 100644 --- a/drivers/leds/leds-ot200.c +++ b/drivers/leds/leds-ot200.c @@ -158,7 +158,6 @@ static struct platform_driver ot200_led_driver = { .remove = ot200_led_remove, .driver = { .name = "leds-ot200", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index d672bb4480f6..f668500a2157 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -232,7 +232,6 @@ static struct platform_driver led_pwm_driver = { .remove = led_pwm_remove, .driver = { .name = "leds_pwm", - .owner = THIS_MODULE, .of_match_table = of_pwm_leds_match, }, }; diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c index 2e746d257b02..fcd1215b64a2 100644 --- a/drivers/leds/leds-rb532.c +++ b/drivers/leds/leds-rb532.c @@ -53,7 +53,6 @@ static struct platform_driver rb532_led_driver = { .remove = rb532_led_remove, .driver = { .name = "rb532-led", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c index 358430db6e66..fa1126f12063 100644 --- a/drivers/leds/leds-regulator.c +++ b/drivers/leds/leds-regulator.c @@ -221,7 +221,6 @@ static int regulator_led_remove(struct platform_device *pdev) static struct platform_driver regulator_led_driver = { .driver = { .name = "leds-regulator", - .owner = THIS_MODULE, }, .probe = regulator_led_probe, .remove = regulator_led_remove, diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c index 785eb53a87fc..83641a7b299a 100644 --- a/drivers/leds/leds-s3c24xx.c +++ b/drivers/leds/leds-s3c24xx.c @@ -116,7 +116,6 @@ static struct platform_driver s3c24xx_led_driver = { .remove = s3c24xx_led_remove, .driver = { .name = "s3c24xx_led", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c index 0b8cc4a021a6..c2553c54f2cf 100644 --- a/drivers/leds/leds-sunfire.c +++ b/drivers/leds/leds-sunfire.c @@ -223,7 +223,6 @@ static struct platform_driver sunfire_clockboard_led_driver = { .remove = sunfire_led_generic_remove, .driver = { .name = "sunfire-clockboard-leds", - .owner = THIS_MODULE, }, }; @@ -232,7 +231,6 @@ static struct platform_driver sunfire_fhc_led_driver = { .remove = sunfire_led_generic_remove, .driver = { .name = "sunfire-fhc-leds", - .owner = THIS_MODULE, }, }; diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c index 1b71e0701002..56027ef7c7e8 100644 --- a/drivers/leds/leds-wm831x-status.c +++ b/drivers/leds/leds-wm831x-status.c @@ -312,7 +312,6 @@ static int wm831x_status_remove(struct platform_device *pdev) static struct platform_driver wm831x_status_driver = { .driver = { .name = "wm831x-status", - .owner = THIS_MODULE, }, .probe = wm831x_status_probe, .remove = wm831x_status_remove, diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index 4133ffe29015..0d121835673f 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c @@ -272,7 +272,6 @@ static int wm8350_led_remove(struct platform_device *pdev) static struct platform_driver wm8350_led_driver = { .driver = { .name = "wm8350-led", - .owner = THIS_MODULE, }, .probe = wm8350_led_probe, .remove = wm8350_led_remove, diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c index b358cc05eff5..1ba3defdd460 100644 --- a/drivers/leds/leds-wrap.c +++ b/drivers/leds/leds-wrap.c @@ -111,7 +111,6 @@ static struct platform_driver wrap_led_driver = { .remove = wrap_led_remove, .driver = { .name = DRVNAME, - .owner = THIS_MODULE, }, }; -- GitLab From ff3ad09b0dbc0d30764c7d46fecf99958781a921 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:43 +0200 Subject: [PATCH 0688/9457] macintosh: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/macintosh/smu.c | 1 - drivers/macintosh/therm_pm72.c | 1 - drivers/macintosh/therm_windtunnel.c | 1 - drivers/macintosh/windfarm_pm81.c | 1 - drivers/macintosh/windfarm_pm91.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 4eab93aa570b..10ae69bcbbd2 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -667,7 +667,6 @@ static struct platform_driver smu_of_platform_driver = { .driver = { .name = "smu", - .owner = THIS_MODULE, .of_match_table = smu_platform_match, }, .probe = smu_platform_probe, diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 97cfc5ac9fd0..7ed92582d2cf 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2243,7 +2243,6 @@ static struct platform_driver fcu_of_platform_driver = { .driver = { .name = "temperature", - .owner = THIS_MODULE, .of_match_table = fcu_match, }, .probe = fcu_of_probe, diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 3b4a157714b1..109dcaa15934 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -463,7 +463,6 @@ static const struct of_device_id therm_of_match[] = {{ static struct platform_driver therm_of_driver = { .driver = { .name = "temperature", - .owner = THIS_MODULE, .of_match_table = therm_of_match, }, .probe = therm_of_probe, diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index 2a5e1b15b1d2..93faf298a3c5 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -770,7 +770,6 @@ static struct platform_driver wf_smu_driver = { .remove = wf_smu_remove, .driver = { .name = "windfarm", - .owner = THIS_MODULE, }, }; diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index a8ac66cd3b13..81fdf40c5b82 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -699,7 +699,6 @@ static struct platform_driver wf_smu_driver = { .remove = wf_smu_remove, .driver = { .name = "windfarm", - .owner = THIS_MODULE, }, }; -- GitLab From aaa8a418ec5a2bdb4b0e51bcd7775f81db3a3dd8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:43 +0200 Subject: [PATCH 0689/9457] mailbox: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mailbox/omap-mailbox.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index bcc7ee129276..42978c4b63fc 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -814,7 +814,6 @@ static struct platform_driver omap_mbox_driver = { .remove = omap_mbox_remove, .driver = { .name = "omap-mailbox", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(omap_mailbox_of_match), }, }; -- GitLab From 1847265fe4ffb0ee6d3caf1461c8556db53163ef Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:44 +0200 Subject: [PATCH 0690/9457] media: platform: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/fsl-viu.c | 1 - drivers/media/platform/m2m-deinterlace.c | 1 - drivers/media/platform/mem2mem_testdev.c | 1 - drivers/media/platform/mx2_emmaprp.c | 1 - drivers/media/platform/sh_veu.c | 1 - drivers/media/platform/sh_vou.c | 1 - drivers/media/platform/timblogiw.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index d5dc198502ef..e3e6024d62c3 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1680,7 +1680,6 @@ static struct platform_driver viu_of_platform_driver = { #endif .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = mpc512x_viu_of_match, }, }; diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index d36c507a0ba2..b70c1aecca37 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -1101,7 +1101,6 @@ static struct platform_driver deinterlace_pdrv = { .remove = deinterlace_remove, .driver = { .name = MEM2MEM_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(deinterlace_pdrv); diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c index c1b03cfd6ded..b8c9677a7c70 100644 --- a/drivers/media/platform/mem2mem_testdev.c +++ b/drivers/media/platform/mem2mem_testdev.c @@ -1060,7 +1060,6 @@ static struct platform_driver m2mtest_pdrv = { .remove = m2mtest_remove, .driver = { .name = MEM2MEM_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 4971ff21f82b..b4791f9f44ed 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -1010,7 +1010,6 @@ static struct platform_driver emmaprp_pdrv = { .remove = emmaprp_remove, .driver = { .name = MEM2MEM_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(emmaprp_pdrv); diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index be3b3bc71a0f..aaa1f6f25a29 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c @@ -1235,7 +1235,6 @@ static struct platform_driver __refdata sh_veu_pdrv = { .remove = sh_veu_remove, .driver = { .name = "sh_veu", - .owner = THIS_MODULE, }, }; diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index e5f1d4c14f2c..b36da10e3f6d 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -1449,7 +1449,6 @@ static struct platform_driver __refdata sh_vou = { .remove = sh_vou_remove, .driver = { .name = "sh-vou", - .owner = THIS_MODULE, }, }; diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c index 3cb2f3564873..5820e45b3a9f 100644 --- a/drivers/media/platform/timblogiw.c +++ b/drivers/media/platform/timblogiw.c @@ -857,7 +857,6 @@ static int timblogiw_remove(struct platform_device *pdev) static struct platform_driver timblogiw_platform_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = timblogiw_probe, .remove = timblogiw_remove, -- GitLab From 5d04d12ed241df74ee03c366afc1e1508043ac95 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:44 +0200 Subject: [PATCH 0691/9457] media: platform: blackfin: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/blackfin/bfin_capture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 9b5daa65841c..8c1dca2f7728 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -1130,7 +1130,6 @@ static int bcap_remove(struct platform_device *pdev) static struct platform_driver bcap_driver = { .driver = { .name = CAPTURE_DRV_NAME, - .owner = THIS_MODULE, }, .probe = bcap_probe, .remove = bcap_remove, -- GitLab From e0eee332d218d3dab0701568a01851df6208eb0a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:45 +0200 Subject: [PATCH 0692/9457] media: platform: coda: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/coda/coda-common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index ced47609f5ef..5faf7b6b502a 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2038,7 +2038,6 @@ static struct platform_driver coda_driver = { .remove = coda_remove, .driver = { .name = CODA_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(coda_dt_ids), .pm = &coda_pm_ops, }, -- GitLab From efd285ea42682f3bbf21a5631ab127214b1fdf85 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:45 +0200 Subject: [PATCH 0693/9457] media: platform: davinci: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/davinci/dm355_ccdc.c | 1 - drivers/media/platform/davinci/dm644x_ccdc.c | 1 - drivers/media/platform/davinci/isif.c | 1 - drivers/media/platform/davinci/vpbe.c | 1 - drivers/media/platform/davinci/vpbe_display.c | 1 - drivers/media/platform/davinci/vpbe_osd.c | 1 - drivers/media/platform/davinci/vpbe_venc.c | 1 - drivers/media/platform/davinci/vpfe_capture.c | 1 - drivers/media/platform/davinci/vpif.c | 1 - drivers/media/platform/davinci/vpif_capture.c | 1 - drivers/media/platform/davinci/vpif_display.c | 1 - drivers/media/platform/davinci/vpss.c | 1 - 12 files changed, 12 deletions(-) diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 3f44deb5b7a7..c90b9a4f0c24 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -1030,7 +1030,6 @@ static int dm355_ccdc_remove(struct platform_device *pdev) static struct platform_driver dm355_ccdc_driver = { .driver = { .name = "dm355_ccdc", - .owner = THIS_MODULE, }, .remove = dm355_ccdc_remove, .probe = dm355_ccdc_probe, diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 62a0ebb01056..ffbefdff6b5e 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -1029,7 +1029,6 @@ static const struct dev_pm_ops dm644x_ccdc_pm_ops = { static struct platform_driver dm644x_ccdc_driver = { .driver = { .name = "dm644x_ccdc", - .owner = THIS_MODULE, .pm = &dm644x_ccdc_pm_ops, }, .remove = dm644x_ccdc_remove, diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index 3332cca632e5..99faea2e84c6 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -1134,7 +1134,6 @@ static int isif_remove(struct platform_device *pdev) static struct platform_driver isif_driver = { .driver = { .name = "isif", - .owner = THIS_MODULE, }, .remove = isif_remove, .probe = isif_probe, diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 33b9660b7f77..338cf6ba76dc 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -863,7 +863,6 @@ static int vpbe_remove(struct platform_device *device) static struct platform_driver vpbe_driver = { .driver = { .name = "vpbe_controller", - .owner = THIS_MODULE, }, .probe = vpbe_probe, .remove = vpbe_remove, diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 73496d953ba0..c39b83c2475f 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1843,7 +1843,6 @@ static int vpbe_display_remove(struct platform_device *pdev) static struct platform_driver vpbe_display_driver = { .driver = { .name = VPBE_DISPLAY_DRIVER, - .owner = THIS_MODULE, .bus = &platform_bus_type, }, .probe = vpbe_display_probe, diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c index d053c2669c1f..7d96a4b13b32 100644 --- a/drivers/media/platform/davinci/vpbe_osd.c +++ b/drivers/media/platform/davinci/vpbe_osd.c @@ -1585,7 +1585,6 @@ static struct platform_driver osd_driver = { .remove = osd_remove, .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, }, .id_table = vpbe_osd_devtype }; diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 14a023a75d2d..36ed1466b290 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -687,7 +687,6 @@ static struct platform_driver venc_driver = { .remove = venc_remove, .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, }, .id_table = vpbe_venc_devtype }; diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index de55f47a77db..953b5c23c897 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -2031,7 +2031,6 @@ static const struct dev_pm_ops vpfe_dev_pm_ops = { static struct platform_driver vpfe_driver = { .driver = { .name = CAPTURE_DRV_NAME, - .owner = THIS_MODULE, .pm = &vpfe_dev_pm_ops, }, .probe = vpfe_probe, diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c index 3dad5bd7fe0a..0380cf2e5775 100644 --- a/drivers/media/platform/davinci/vpif.c +++ b/drivers/media/platform/davinci/vpif.c @@ -467,7 +467,6 @@ static const struct dev_pm_ops vpif_pm = { static struct platform_driver vpif_driver = { .driver = { .name = "vpif", - .owner = THIS_MODULE, .pm = vpif_pm_ops, }, .remove = vpif_remove, diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 3ccb26ff43c8..07f7452b5b72 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1656,7 +1656,6 @@ static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); static __refdata struct platform_driver vpif_driver = { .driver = { .name = VPIF_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &vpif_pm_ops, }, .probe = vpif_probe, diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 8d6ced56253c..839c24de1fd8 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1459,7 +1459,6 @@ static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); static __refdata struct platform_driver vpif_driver = { .driver = { .name = VPIF_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &vpif_pm_ops, }, .probe = vpif_probe, diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index 31120b4a4a33..fce86f17dffc 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c @@ -504,7 +504,6 @@ static const struct dev_pm_ops vpss_pm_ops = { static struct platform_driver vpss_driver = { .driver = { .name = "vpss", - .owner = THIS_MODULE, .pm = &vpss_pm_ops, }, .remove = vpss_remove, -- GitLab From 73239ad1ab1236ef8d521e88088ec541e5df8862 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:46 +0200 Subject: [PATCH 0694/9457] media: platform: exynos4-is: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/exynos4-is/fimc-core.c | 1 - drivers/media/platform/exynos4-is/fimc-is-i2c.c | 1 - drivers/media/platform/exynos4-is/fimc-is.c | 1 - drivers/media/platform/exynos4-is/fimc-lite.c | 1 - drivers/media/platform/exynos4-is/media-dev.c | 1 - drivers/media/platform/exynos4-is/mipi-csis.c | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index b70fd996d794..cae23f457d16 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -1292,7 +1292,6 @@ static struct platform_driver fimc_driver = { .driver = { .of_match_table = fimc_of_match, .name = FIMC_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &fimc_pm_ops, } }; diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c index 371cad4fcce9..25e635c9a0f4 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c +++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c @@ -133,7 +133,6 @@ static struct platform_driver fimc_is_i2c_driver = { .driver = { .of_match_table = fimc_is_i2c_of_match, .name = "fimc-isp-i2c", - .owner = THIS_MODULE, .pm = &fimc_is_i2c_pm_ops, } }; diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 22162b2567da..94c6b47d9717 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -962,7 +962,6 @@ static struct platform_driver fimc_is_driver = { .driver = { .of_match_table = fimc_is_of_match, .name = FIMC_IS_DRV_NAME, - .owner = THIS_MODULE, .pm = &fimc_is_pm_ops, } }; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index a97d2352f1d7..65a58cd432a3 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1720,7 +1720,6 @@ static struct platform_driver fimc_lite_driver = { .driver = { .of_match_table = flite_of_match, .name = FIMC_LITE_DRV_NAME, - .owner = THIS_MODULE, .pm = &fimc_lite_pm_ops, } }; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 54c49d5e7690..f315ef946cd4 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1469,7 +1469,6 @@ static struct platform_driver fimc_md_driver = { .driver = { .of_match_table = of_match_ptr(fimc_md_of_match), .name = "s5p-fimc-md", - .owner = THIS_MODULE, } }; diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index db6fd14d1936..53a7415f17fb 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -1041,7 +1041,6 @@ static struct platform_driver s5pcsis_driver = { .driver = { .of_match_table = s5pcsis_of_match, .name = CSIS_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &s5pcsis_pm_ops, }, }; -- GitLab From ae6ec6abcfe4141157227e8a063ea898e858fb2c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:46 +0200 Subject: [PATCH 0695/9457] media: platform: exynos-gsc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/exynos-gsc/gsc-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index b4c9f1d08968..2640e9412998 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1253,7 +1253,6 @@ static struct platform_driver gsc_driver = { .id_table = gsc_driver_ids, .driver = { .name = GSC_MODULE_NAME, - .owner = THIS_MODULE, .pm = &gsc_pm_ops, .of_match_table = exynos_gsc_match, } -- GitLab From ea1251b7349b10fe178a9de4b7acee0caf076a95 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:46 +0200 Subject: [PATCH 0696/9457] media: platform: marvell-ccic: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/marvell-ccic/mmp-driver.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 054507f16734..0ed9b3adfcdf 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -512,7 +512,6 @@ static struct platform_driver mmpcam_driver = { #endif .driver = { .name = "mmp-camera", - .owner = THIS_MODULE } }; -- GitLab From 054d0dbab398143603f5f7ed78f8ce304b9590aa Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:47 +0200 Subject: [PATCH 0697/9457] media: platform: omap3isp: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/omap3isp/isp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 72265e58ca60..51c2129bdcc6 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2380,7 +2380,6 @@ static struct platform_driver omap3isp_driver = { .remove = isp_remove, .id_table = omap3isp_id_table, .driver = { - .owner = THIS_MODULE, .name = "omap3isp", .pm = &omap3isp_pm_ops, }, -- GitLab From 30355dd734c8f427ad2e89d6f0fc5ab074db6fac Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:47 +0200 Subject: [PATCH 0698/9457] media: platform: s3c-camif: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/s3c-camif/camif-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index b38574702fe9..e7163cad81cb 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -652,7 +652,6 @@ static struct platform_driver s3c_camif_driver = { .id_table = s3c_camif_driver_ids, .driver = { .name = S3C_CAMIF_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &s3c_camif_pm_ops, } }; -- GitLab From 831de321bfcadc9bed1cf4fab1365d9c3e110de2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:48 +0200 Subject: [PATCH 0699/9457] media: platform: s5p-g2d: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/s5p-g2d/g2d.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index d79e214ce8ce..ac98821082a2 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -812,7 +812,6 @@ static struct platform_driver g2d_pdrv = { .id_table = g2d_driver_ids, .driver = { .name = G2D_NAME, - .owner = THIS_MODULE, .of_match_table = exynos_g2d_match, }, }; -- GitLab From 5c208acf182325fdb73988792f15820f6ca2b973 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:48 +0200 Subject: [PATCH 0700/9457] media: platform: s5p-jpeg: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index e525a7c8d885..65e4afe64244 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2764,7 +2764,6 @@ static struct platform_driver s5p_jpeg_driver = { .remove = s5p_jpeg_remove, .driver = { .of_match_table = of_match_ptr(samsung_jpeg_match), - .owner = THIS_MODULE, .name = S5P_JPEG_M2M_NAME, .pm = &s5p_jpeg_pm_ops, }, -- GitLab From f38a46ca1432b5e219ba628f797b6998d59f1fa6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:48 +0200 Subject: [PATCH 0701/9457] media: platform: s5p-mfc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 165bc86c5962..96fe33f0a045 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1505,7 +1505,6 @@ static struct platform_driver s5p_mfc_driver = { .id_table = mfc_driver_ids, .driver = { .name = S5P_MFC_NAME, - .owner = THIS_MODULE, .pm = &s5p_mfc_pm_ops, .of_match_table = exynos_mfc_match, }, -- GitLab From 6fe0f3da2f58f03a97e87fcc929cc24c71624154 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:49 +0200 Subject: [PATCH 0702/9457] media: platform: s5p-tv: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/s5p-tv/hdmi_drv.c | 1 - drivers/media/platform/s5p-tv/mixer_drv.c | 1 - drivers/media/platform/s5p-tv/sdo_drv.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c index 37c8bd694c5f..2b959ae4e62f 100644 --- a/drivers/media/platform/s5p-tv/hdmi_drv.c +++ b/drivers/media/platform/s5p-tv/hdmi_drv.c @@ -1046,7 +1046,6 @@ static struct platform_driver hdmi_driver __refdata = { .id_table = hdmi_driver_types, .driver = { .name = "s5p-hdmi", - .owner = THIS_MODULE, .pm = &hdmi_pm_ops, } }; diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c index bc08b5f28e44..2a9501d7e7c8 100644 --- a/drivers/media/platform/s5p-tv/mixer_drv.c +++ b/drivers/media/platform/s5p-tv/mixer_drv.c @@ -487,7 +487,6 @@ static struct platform_driver mxr_driver __refdata = { .remove = mxr_remove, .driver = { .name = MXR_DRIVER_NAME, - .owner = THIS_MODULE, .pm = &mxr_pm_ops, } }; diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c index 72cf892dd008..0dfe51a9ca06 100644 --- a/drivers/media/platform/s5p-tv/sdo_drv.c +++ b/drivers/media/platform/s5p-tv/sdo_drv.c @@ -482,7 +482,6 @@ static struct platform_driver sdo_driver __refdata = { .remove = sdo_remove, .driver = { .name = "s5p-sdo", - .owner = THIS_MODULE, .pm = &sdo_pm_ops, } }; -- GitLab From 01945a4e01615033faf0da0b6608858346ea0b57 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:49 +0200 Subject: [PATCH 0703/9457] media: platform: soc_camera: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/soc_camera/atmel-isi.c | 1 - drivers/media/platform/soc_camera/mx3_camera.c | 1 - drivers/media/platform/soc_camera/rcar_vin.c | 1 - drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 1 - drivers/media/platform/soc_camera/sh_mobile_csi2.c | 1 - drivers/media/platform/soc_camera/soc_camera.c | 1 - drivers/media/platform/soc_camera/soc_camera_platform.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c5291b001057..19b27d88caeb 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1068,7 +1068,6 @@ static struct platform_driver atmel_isi_driver = { .remove = atmel_isi_remove, .driver = { .name = "atmel_isi", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_isi_of_match), }, }; diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 7696a873510d..db65e5778094 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -1253,7 +1253,6 @@ static int mx3_camera_remove(struct platform_device *pdev) static struct platform_driver mx3_camera_driver = { .driver = { .name = MX3_CAM_DRV_NAME, - .owner = THIS_MODULE, }, .probe = mx3_camera_probe, .remove = mx3_camera_remove, diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 20defcb8b31b..fa592a69a878 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1543,7 +1543,6 @@ static struct platform_driver rcar_vin_driver = { .remove = rcar_vin_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rcar_vin_of_table), }, .id_table = rcar_vin_id_table, diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 20ad4a571d37..412b74dd2cdd 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -2009,7 +2009,6 @@ MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match); static struct platform_driver sh_mobile_ceu_driver = { .driver = { .name = "sh_mobile_ceu", - .owner = THIS_MODULE, .pm = &sh_mobile_ceu_dev_pm_ops, .of_match_table = sh_mobile_ceu_of_match, }, diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c index 05dd21a35d63..f4a81ba09081 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c @@ -391,7 +391,6 @@ static struct platform_driver __refdata sh_csi2_pdrv = { .probe = sh_csi2_probe, .driver = { .name = "sh-mobile-csi2", - .owner = THIS_MODULE, }, }; diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 8e61b976da19..4843df0095a9 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -2236,7 +2236,6 @@ static struct platform_driver __refdata soc_camera_pdrv = { .remove = soc_camera_pdrv_remove, .driver = { .name = "soc-camera-pdrv", - .owner = THIS_MODULE, }, }; diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index ceaddfb85e49..22bd8290c097 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -180,7 +180,6 @@ static int soc_camera_platform_remove(struct platform_device *pdev) static struct platform_driver soc_camera_platform_driver = { .driver = { .name = "soc_camera_platform", - .owner = THIS_MODULE, }, .probe = soc_camera_platform_probe, .remove = soc_camera_platform_remove, -- GitLab From e2f64141596c4fd0c21928987fba61d8c38d1a81 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:50 +0200 Subject: [PATCH 0704/9457] media: platform: ti-vpe: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/ti-vpe/vpe.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 9a081c291159..d628d1a7cf9e 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2376,7 +2376,6 @@ static struct platform_driver vpe_pdrv = { .remove = vpe_remove, .driver = { .name = VPE_MODULE_NAME, - .owner = THIS_MODULE, .of_match_table = vpe_of_match, }, }; -- GitLab From 377b19756c67b6754fbbd4ff00efadf2b67eff28 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:50 +0200 Subject: [PATCH 0705/9457] media: platform: vsp1: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/platform/vsp1/vsp1_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 3e6601b5b4de..5eb16e87d53f 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -562,7 +562,6 @@ static struct platform_driver vsp1_platform_driver = { .probe = vsp1_probe, .remove = vsp1_remove, .driver = { - .owner = THIS_MODULE, .name = "vsp1", .pm = &vsp1_pm_ops, .of_match_table = vsp1_of_match, -- GitLab From da2dc6fff5b63b94a45d75b77b1a441d1b55a4bf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:51 +0200 Subject: [PATCH 0706/9457] media: radio: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/radio/radio-si476x.c | 1 - drivers/media/radio/radio-timb.c | 1 - drivers/media/radio/radio-wl1273.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c index 633022b45f33..dccf58691650 100644 --- a/drivers/media/radio/radio-si476x.c +++ b/drivers/media/radio/radio-si476x.c @@ -1575,7 +1575,6 @@ MODULE_ALIAS("platform:si476x-radio"); static struct platform_driver si476x_radio_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = si476x_radio_probe, .remove = si476x_radio_remove, diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index b9285e6584af..e6b55edc8f8d 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c @@ -174,7 +174,6 @@ static int timbradio_remove(struct platform_device *pdev) static struct platform_driver timbradio_platform_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = timbradio_probe, .remove = timbradio_remove, diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index 9cf6731fb816..fd2281c4a784 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -2148,7 +2148,6 @@ static struct platform_driver wl1273_fm_radio_driver = { .remove = wl1273_fm_radio_remove, .driver = { .name = "wl1273_fm_radio", - .owner = THIS_MODULE, }, }; -- GitLab From b2e385395ec010792aa550458fba510d762988f1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:51 +0200 Subject: [PATCH 0707/9457] media: radio: si4713: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/radio/si4713/radio-platform-si4713.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c index a47502a330f0..71881a22d664 100644 --- a/drivers/media/radio/si4713/radio-platform-si4713.c +++ b/drivers/media/radio/si4713/radio-platform-si4713.c @@ -236,7 +236,6 @@ static int radio_si4713_pdriver_remove(struct platform_device *pdev) static struct platform_driver radio_si4713_pdriver = { .driver = { .name = "radio-si4713", - .owner = THIS_MODULE, }, .probe = radio_si4713_pdriver_probe, .remove = radio_si4713_pdriver_remove, -- GitLab From d07f1c56cfde5389784975415bc2031b3c405a54 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:51 +0200 Subject: [PATCH 0708/9457] media: rc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/rc/gpio-ir-recv.c | 1 - drivers/media/rc/sunxi-cir.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 59853085bc88..229853d68451 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -240,7 +240,6 @@ static struct platform_driver gpio_ir_recv_driver = { .remove = gpio_ir_recv_remove, .driver = { .name = GPIO_IR_DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_ir_recv_of_match), #ifdef CONFIG_PM .pm = &gpio_ir_recv_pm_ops, diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index bcee8e1a4e9e..340f7f51eed4 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -306,7 +306,6 @@ static struct platform_driver sunxi_ir_driver = { .remove = sunxi_ir_remove, .driver = { .name = SUNXI_IR_DEV, - .owner = THIS_MODULE, .of_match_table = sunxi_ir_match, }, }; -- GitLab From 04626474b8d74731aff1ecd7137be6d070f28ba6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:52 +0200 Subject: [PATCH 0709/9457] media: rc: img-ir: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/media/rc/img-ir/img-ir-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c index a0cac2f09109..77c78de4f5bf 100644 --- a/drivers/media/rc/img-ir/img-ir-core.c +++ b/drivers/media/rc/img-ir/img-ir-core.c @@ -166,7 +166,6 @@ MODULE_DEVICE_TABLE(of, img_ir_match); static struct platform_driver img_ir_driver = { .driver = { .name = "img-ir", - .owner = THIS_MODULE, .of_match_table = img_ir_match, .pm = &img_ir_pmops, }, -- GitLab From 0f0d7e7b022b2d3b03a613048954dffb4af9a9b8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:52 +0200 Subject: [PATCH 0710/9457] memory: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/memory/atmel-sdramc.c | 1 - drivers/memory/fsl-corenet-cf.c | 1 - drivers/memory/mvebu-devbus.c | 1 - drivers/memory/tegra20-mc.c | 1 - drivers/memory/tegra30-mc.c | 1 - drivers/memory/ti-aemif.c | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c index fed04e8efe75..a3ebc8a87479 100644 --- a/drivers/memory/atmel-sdramc.c +++ b/drivers/memory/atmel-sdramc.c @@ -82,7 +82,6 @@ static struct platform_driver atmel_ramc_driver = { .probe = atmel_ramc_probe, .driver = { .name = "atmel-ramc", - .owner = THIS_MODULE, .of_match_table = atmel_ramc_of_match, }, }; diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c index c9443fc136db..fc7ab5a3561e 100644 --- a/drivers/memory/fsl-corenet-cf.c +++ b/drivers/memory/fsl-corenet-cf.c @@ -237,7 +237,6 @@ static int ccf_remove(struct platform_device *pdev) static struct platform_driver ccf_driver = { .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = ccf_matches, }, .probe = ccf_probe, diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index ff7138fd66d1..24852812fd44 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -346,7 +346,6 @@ static struct platform_driver mvebu_devbus_driver = { .probe = mvebu_devbus_probe, .driver = { .name = "mvebu-devbus", - .owner = THIS_MODULE, .of_match_table = mvebu_devbus_of_match, }, }; diff --git a/drivers/memory/tegra20-mc.c b/drivers/memory/tegra20-mc.c index 7cd82b874abd..cc309a05289a 100644 --- a/drivers/memory/tegra20-mc.c +++ b/drivers/memory/tegra20-mc.c @@ -243,7 +243,6 @@ static struct platform_driver tegra20_mc_driver = { .probe = tegra20_mc_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra20_mc_of_match, }, }; diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c index ef7934535fd1..b3d59f88c278 100644 --- a/drivers/memory/tegra30-mc.c +++ b/drivers/memory/tegra30-mc.c @@ -365,7 +365,6 @@ static struct platform_driver tegra30_mc_driver = { .probe = tegra30_mc_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra30_mc_of_match, .pm = &tegra30_mc_pm, }, diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c index d3df7602f406..ca7d97a9a9ba 100644 --- a/drivers/memory/ti-aemif.c +++ b/drivers/memory/ti-aemif.c @@ -413,7 +413,6 @@ static struct platform_driver aemif_driver = { .remove = aemif_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(aemif_of_match), }, }; -- GitLab From 1a22cd17483e4e574b7c1d624be48b47404aea2d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:53 +0200 Subject: [PATCH 0711/9457] memstick: host: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/memstick/host/rtsx_pci_ms.c | 1 - drivers/memstick/host/rtsx_usb_ms.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c index c880ba685754..818fa94354ae 100644 --- a/drivers/memstick/host/rtsx_pci_ms.c +++ b/drivers/memstick/host/rtsx_pci_ms.c @@ -645,7 +645,6 @@ static struct platform_driver rtsx_pci_ms_driver = { .suspend = rtsx_pci_ms_suspend, .resume = rtsx_pci_ms_resume, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME_RTSX_PCI_MS, }, }; diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index a7282b7d4de8..1105db2355d2 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c @@ -827,7 +827,6 @@ static struct platform_driver rtsx_usb_ms_driver = { .remove = rtsx_usb_ms_drv_remove, .id_table = rtsx_usb_ms_ids, .driver = { - .owner = THIS_MODULE, .name = "rtsx_usb_ms", .pm = &rtsx_usb_ms_pm_ops, }, -- GitLab From 78a835416ad6d5b0d67f264d592906fade309ea2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:53 +0200 Subject: [PATCH 0712/9457] mfd: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mfd/ab3100-otp.c | 1 - drivers/mfd/ab8500-core.c | 1 - drivers/mfd/ab8500-debugfs.c | 1 - drivers/mfd/ab8500-gpadc.c | 1 - drivers/mfd/ab8500-sysctrl.c | 1 - drivers/mfd/davinci_voicecodec.c | 1 - drivers/mfd/db8500-prcmu.c | 1 - drivers/mfd/intel_msic.c | 1 - drivers/mfd/jz4740-adc.c | 1 - drivers/mfd/kempld-core.c | 1 - drivers/mfd/mcp-sa11x0.c | 1 - drivers/mfd/omap-usb-host.c | 1 - drivers/mfd/omap-usb-tll.c | 1 - drivers/mfd/pm8921-core.c | 1 - drivers/mfd/sm501.c | 1 - drivers/mfd/ssbi.c | 1 - drivers/mfd/sta2x11-mfd.c | 4 ---- drivers/mfd/sun6i-prcm.c | 1 - drivers/mfd/syscon.c | 1 - drivers/mfd/t7l66xb.c | 1 - drivers/mfd/tc6393xb.c | 1 - drivers/mfd/ti_am335x_tscadc.c | 1 - drivers/mfd/tps65911-comparator.c | 1 - drivers/mfd/twl4030-audio.c | 1 - drivers/mfd/twl4030-power.c | 1 - 25 files changed, 28 deletions(-) diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index c9af16cc7310..f391c5fee1b0 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -239,7 +239,6 @@ static int __exit ab3100_otp_remove(struct platform_device *pdev) static struct platform_driver ab3100_otp_driver = { .driver = { .name = "ab3100-otp", - .owner = THIS_MODULE, }, .remove = __exit_p(ab3100_otp_remove), }; diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index bde2fc072410..c80a2925f8e5 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1848,7 +1848,6 @@ static const struct platform_device_id ab8500_id[] = { static struct platform_driver ab8500_core_driver = { .driver = { .name = "ab8500-core", - .owner = THIS_MODULE, }, .probe = ab8500_probe, .remove = ab8500_remove, diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index b2c7e3b1edfa..9a8e185f11df 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -3263,7 +3263,6 @@ static int ab8500_debug_remove(struct platform_device *plf) static struct platform_driver ab8500_debug_driver = { .driver = { .name = "ab8500-debug", - .owner = THIS_MODULE, }, .probe = ab8500_debug_probe, .remove = ab8500_debug_remove diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 36000f920981..ee9198e12739 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -1044,7 +1044,6 @@ static struct platform_driver ab8500_gpadc_driver = { .remove = ab8500_gpadc_remove, .driver = { .name = "ab8500-gpadc", - .owner = THIS_MODULE, .pm = &ab8500_gpadc_pm_ops, }, }; diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 8e0dae59844d..fe7e3b133834 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -237,7 +237,6 @@ static int ab8500_sysctrl_remove(struct platform_device *pdev) static struct platform_driver ab8500_sysctrl_driver = { .driver = { .name = "ab8500-sysctrl", - .owner = THIS_MODULE, }, .probe = ab8500_sysctrl_probe, .remove = ab8500_sysctrl_remove, diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 013ba8159dcd..c835e85539b2 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -143,7 +143,6 @@ static int davinci_vc_remove(struct platform_device *pdev) static struct platform_driver davinci_vc_driver = { .driver = { .name = "davinci_voicecodec", - .owner = THIS_MODULE, }, .remove = davinci_vc_remove, }; diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 193cf168ba84..7700e17b3718 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -3230,7 +3230,6 @@ static const struct of_device_id db8500_prcmu_match[] = { static struct platform_driver db8500_prcmu_driver = { .driver = { .name = "db8500-prcmu", - .owner = THIS_MODULE, .of_match_table = db8500_prcmu_match, }, .probe = db8500_prcmu_probe, diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 443e7cddff28..25d486c543cb 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c @@ -447,7 +447,6 @@ static struct platform_driver intel_msic_driver = { .remove = intel_msic_remove, .driver = { .name = "intel_msic", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 7a51c0d0d4f1..b31c54e4ecb2 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c @@ -324,7 +324,6 @@ static struct platform_driver jz4740_adc_driver = { .remove = jz4740_adc_remove, .driver = { .name = "jz4740-adc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index bd2696136eee..f38ec424872e 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -494,7 +494,6 @@ static int kempld_remove(struct platform_device *pdev) static struct platform_driver kempld_driver = { .driver = { .name = "kempld", - .owner = THIS_MODULE, }, .probe = kempld_probe, .remove = kempld_remove, diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 29d76986b40b..1fc458128405 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -299,7 +299,6 @@ static struct platform_driver mcp_sa11x0_driver = { .remove = mcp_sa11x0_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &mcp_sa11x0_pm_ops, }, }; diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 83dab2f0a50e..04cd54dd507c 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -882,7 +882,6 @@ MODULE_DEVICE_TABLE(of, usbhs_omap_dt_ids); static struct platform_driver usbhs_omap_driver = { .driver = { .name = (char *)usbhs_driver_name, - .owner = THIS_MODULE, .pm = &usbhsomap_dev_pm_ops, .of_match_table = usbhs_omap_dt_ids, }, diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 532eacab6b46..b7b3e8ee64f2 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c @@ -319,7 +319,6 @@ MODULE_DEVICE_TABLE(of, usbtll_omap_dt_ids); static struct platform_driver usbtll_omap_driver = { .driver = { .name = (char *)usbtll_driver_name, - .owner = THIS_MODULE, .of_match_table = usbtll_omap_dt_ids, }, .probe = usbtll_omap_probe, diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index 39904f77c049..5a92646a2ccb 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c @@ -374,7 +374,6 @@ static struct platform_driver pm8921_driver = { .remove = pm8921_remove, .driver = { .name = "pm8921-core", - .owner = THIS_MODULE, .of_match_table = pm8921_id_table, }, }; diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 6ce6e6200359..91077efc8050 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1723,7 +1723,6 @@ static const struct of_device_id of_sm501_match_tbl[] = { static struct platform_driver sm501_plat_driver = { .driver = { .name = "sm501", - .owner = THIS_MODULE, .of_match_table = of_sm501_match_tbl, }, .probe = sm501_plat_probe, diff --git a/drivers/mfd/ssbi.c b/drivers/mfd/ssbi.c index b78942ed4c67..27986f641f7d 100644 --- a/drivers/mfd/ssbi.c +++ b/drivers/mfd/ssbi.c @@ -327,7 +327,6 @@ static struct platform_driver ssbi_driver = { .probe = ssbi_probe, .driver = { .name = "ssbi", - .owner = THIS_MODULE, .of_match_table = ssbi_match_table, }, }; diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index 5b72db07d9de..b3e5c6f45105 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -368,7 +368,6 @@ static int sta2x11_scr_probe(struct platform_device *dev) static struct platform_driver sta2x11_sctl_platform_driver = { .driver = { .name = STA2X11_MFD_SCTL_NAME, - .owner = THIS_MODULE, }, .probe = sta2x11_sctl_probe, }; @@ -382,7 +381,6 @@ static int __init sta2x11_sctl_init(void) static struct platform_driver sta2x11_platform_driver = { .driver = { .name = STA2X11_MFD_APBREG_NAME, - .owner = THIS_MODULE, }, .probe = sta2x11_apbreg_probe, }; @@ -396,7 +394,6 @@ static int __init sta2x11_apbreg_init(void) static struct platform_driver sta2x11_apb_soc_regs_platform_driver = { .driver = { .name = STA2X11_MFD_APB_SOC_REGS_NAME, - .owner = THIS_MODULE, }, .probe = sta2x11_apb_soc_regs_probe, }; @@ -410,7 +407,6 @@ static int __init sta2x11_apb_soc_regs_init(void) static struct platform_driver sta2x11_scr_platform_driver = { .driver = { .name = STA2X11_MFD_SCR_NAME, - .owner = THIS_MODULE, }, .probe = sta2x11_scr_probe, }; diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c index 283ab8d197e4..2f2e9f062571 100644 --- a/drivers/mfd/sun6i-prcm.c +++ b/drivers/mfd/sun6i-prcm.c @@ -152,7 +152,6 @@ static int sun6i_prcm_probe(struct platform_device *pdev) static struct platform_driver sun6i_prcm_driver = { .driver = { .name = "sun6i-prcm", - .owner = THIS_MODULE, .of_match_table = sun6i_prcm_dt_ids, }, .probe = sun6i_prcm_probe, diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index ca15878ce5c0..e85c052b302c 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -166,7 +166,6 @@ static const struct platform_device_id syscon_ids[] = { static struct platform_driver syscon_driver = { .driver = { .name = "syscon", - .owner = THIS_MODULE, .of_match_table = of_syscon_match, }, .probe = syscon_probe, diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 9e04a7485981..3bb12e791982 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -431,7 +431,6 @@ static int t7l66xb_remove(struct platform_device *dev) static struct platform_driver t7l66xb_platform_driver = { .driver = { .name = "t7l66xb", - .owner = THIS_MODULE, }, .suspend = t7l66xb_suspend, .resume = t7l66xb_resume, diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 4fac16bcd732..aaf852242d76 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -831,7 +831,6 @@ static struct platform_driver tc6393xb_driver = { .driver = { .name = "tc6393xb", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index d877e777cce6..467c80e1c4ae 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c @@ -368,7 +368,6 @@ MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids); static struct platform_driver ti_tscadc_driver = { .driver = { .name = "ti_am3359-tscadc", - .owner = THIS_MODULE, .pm = TSCADC_PM_OPS, .of_match_table = ti_tscadc_dt_ids, }, diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c index c0816ebd9d7e..c0789f81a1c5 100644 --- a/drivers/mfd/tps65911-comparator.c +++ b/drivers/mfd/tps65911-comparator.c @@ -166,7 +166,6 @@ static int tps65911_comparator_remove(struct platform_device *pdev) static struct platform_driver tps65911_comparator_driver = { .driver = { .name = "tps65911-comparator", - .owner = THIS_MODULE, }, .probe = tps65911_comparator_probe, .remove = tps65911_comparator_remove, diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 07fe542e6fc0..0a1606480023 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c @@ -283,7 +283,6 @@ MODULE_DEVICE_TABLE(of, twl4030_audio_of_match); static struct platform_driver twl4030_audio_driver = { .driver = { - .owner = THIS_MODULE, .name = "twl4030-audio", .of_match_table = twl4030_audio_of_match, }, diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index cf92a6d1c532..fdea0cb75320 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -878,7 +878,6 @@ static int twl4030_power_remove(struct platform_device *pdev) static struct platform_driver twl4030_power_driver = { .driver = { .name = "twl4030_power", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl4030_power_of_match), }, .probe = twl4030_power_probe, -- GitLab From 9bcde613eaa6b5bc2e2030b4ee40ffb9662327a6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:54 +0200 Subject: [PATCH 0713/9457] misc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/misc/arm-charlcd.c | 1 - drivers/misc/atmel-ssc.c | 1 - drivers/misc/cs5535-mfgpt.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c index c72e96b523ed..c65b5ea5d5ef 100644 --- a/drivers/misc/arm-charlcd.c +++ b/drivers/misc/arm-charlcd.c @@ -375,7 +375,6 @@ static const struct of_device_id charlcd_match[] = { static struct platform_driver charlcd_driver = { .driver = { .name = DRIVERNAME, - .owner = THIS_MODULE, .pm = &charlcd_pm_ops, .of_match_table = of_match_ptr(charlcd_match), }, diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 60843a275abd..5305ac8dfb3e 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -220,7 +220,6 @@ static int ssc_remove(struct platform_device *pdev) static struct platform_driver ssc_driver = { .driver = { .name = "ssc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_ssc_dt_ids), }, .id_table = atmel_ssc_devtypes, diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index effd8c6b2b94..347f08f2fd48 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -365,7 +365,6 @@ static int cs5535_mfgpt_probe(struct platform_device *pdev) static struct platform_driver cs5535_mfgpt_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = cs5535_mfgpt_probe, }; -- GitLab From 98dc3b5edf2c194101fbea7631fc8e1852eadf03 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:54 +0200 Subject: [PATCH 0714/9457] misc: carma: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/misc/carma/carma-fpga-program.c | 1 - drivers/misc/carma/carma-fpga.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index 339b252fcedd..6fa52f71f51c 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c @@ -1091,7 +1091,6 @@ static struct platform_driver fpga_of_driver = { .driver = { .name = drv_name, .of_match_table = fpga_of_match, - .owner = THIS_MODULE, }, }; diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 55e913b7eb11..cdf2d7b902bb 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -1433,7 +1433,6 @@ static struct platform_driver data_of_driver = { .driver = { .name = drv_name, .of_match_table = data_of_match, - .owner = THIS_MODULE, }, }; -- GitLab From 16640616518e10ae56060ed6110638e7f220ae98 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:55 +0200 Subject: [PATCH 0715/9457] misc: eeprom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/misc/eeprom/sunxi_sid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/eeprom/sunxi_sid.c b/drivers/misc/eeprom/sunxi_sid.c index 3f2b625b2032..8385177ff32b 100644 --- a/drivers/misc/eeprom/sunxi_sid.c +++ b/drivers/misc/eeprom/sunxi_sid.c @@ -146,7 +146,6 @@ static struct platform_driver sunxi_sid_driver = { .remove = sunxi_sid_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = sunxi_sid_of_match, }, }; -- GitLab From c190476bd43bee2ce822d7a8f6aecd7dd3c9b0b2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:55 +0200 Subject: [PATCH 0716/9457] misc: mic: card: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/misc/mic/card/mic_x100.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c index 9d57545d64f6..e98e537d68e3 100644 --- a/drivers/misc/mic/card/mic_x100.c +++ b/drivers/misc/mic/card/mic_x100.c @@ -255,7 +255,6 @@ static struct platform_driver __refdata mic_platform_driver = { .shutdown = mic_platform_shutdown, .driver = { .name = mic_driver_name, - .owner = THIS_MODULE, }, }; -- GitLab From 17149e4c863c9696f3ee6fa27954f3087acdefd3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:56 +0200 Subject: [PATCH 0717/9457] misc: ti-st: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/misc/ti-st/st_kim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 21c2337bad68..e4b7ee4f57b8 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -858,7 +858,6 @@ static struct platform_driver kim_platform_driver = { .resume = kim_resume, .driver = { .name = "kim", - .owner = THIS_MODULE, }, }; -- GitLab From bb0d20e79490aad989e6c85fedf46781b8d1e3ba Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:56 +0200 Subject: [PATCH 0718/9457] mmc: host: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mmc/host/au1xmmc.c | 1 - drivers/mmc/host/davinci_mmc.c | 1 - drivers/mmc/host/sdhci-acpi.c | 1 - drivers/mmc/host/tmio_mmc.c | 1 - drivers/mmc/host/usdhi6rol0.c | 1 - drivers/mmc/host/wbsd.c | 1 - drivers/mmc/host/wmt-sdmmc.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 725f6a6fd89b..ed77fbfa4774 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -1206,7 +1206,6 @@ static struct platform_driver au1xmmc_driver = { .resume = au1xmmc_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 5d4c5e0fba2f..1625f908dc70 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1466,7 +1466,6 @@ static const struct dev_pm_ops davinci_mmcsd_pm = { static struct platform_driver davinci_mmcsd_driver = { .driver = { .name = "davinci_mmc", - .owner = THIS_MODULE, .pm = davinci_mmcsd_pm_ops, .of_match_table = davinci_mmc_dt_ids, }, diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 9cccc0e89b04..4e064c8cec97 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -449,7 +449,6 @@ static const struct dev_pm_ops sdhci_acpi_pm_ops = { static struct platform_driver sdhci_acpi_driver = { .driver = { .name = "sdhci-acpi", - .owner = THIS_MODULE, .acpi_match_table = sdhci_acpi_ids, .pm = &sdhci_acpi_pm_ops, }, diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 659028ddb8b1..bcf3c94c415f 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -143,7 +143,6 @@ static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { static struct platform_driver tmio_mmc_driver = { .driver = { .name = "tmio-mmc", - .owner = THIS_MODULE, .pm = &tmio_mmc_dev_pm_ops, }, .probe = tmio_mmc_probe, diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index f0a39eb049af..54b082b1804a 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -1834,7 +1834,6 @@ static struct platform_driver usdhi6_driver = { .remove = usdhi6_remove, .driver = { .name = "usdhi6rol0", - .owner = THIS_MODULE, .of_match_table = usdhi6_of_match, }, }; diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 9a6dfb0c4ecc..ca183ea767b3 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1914,7 +1914,6 @@ static struct platform_driver wbsd_driver = { .resume = wbsd_platform_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index 54181b4f6e9e..dd2e1aa95ba3 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -991,7 +991,6 @@ static struct platform_driver wmt_mci_driver = { .remove = wmt_mci_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = wmt_mci_pm_ops, .of_match_table = wmt_mci_dt_ids, }, -- GitLab From c37c1e160546eca3f0612bf9a541667af4f5d71b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:57 +0200 Subject: [PATCH 0719/9457] mtd: devices: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/devices/bcm47xxsflash.c | 1 - drivers/mtd/devices/docg3.c | 1 - drivers/mtd/devices/spear_smi.c | 1 - drivers/mtd/devices/st_spi_fsm.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c index 77de29bc02ba..3d008a9410be 100644 --- a/drivers/mtd/devices/bcm47xxsflash.c +++ b/drivers/mtd/devices/bcm47xxsflash.c @@ -329,7 +329,6 @@ static struct platform_driver bcma_sflash_driver = { .remove = bcm47xxsflash_bcma_remove, .driver = { .name = "bcma_sflash", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 21cc4b66feaa..72346048532d 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -2129,7 +2129,6 @@ static int __exit docg3_release(struct platform_device *pdev) static struct platform_driver g3_driver = { .driver = { .name = "docg3", - .owner = THIS_MODULE, }, .suspend = docg3_suspend, .resume = docg3_resume, diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index c4176b0f382d..508bab3bd0c4 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -1079,7 +1079,6 @@ static struct platform_driver spear_smi_driver = { .driver = { .name = "smi", .bus = &platform_bus_type, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spear_smi_id_table), .pm = &spear_smi_pm_ops, }, diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index d252514d3e98..54ffe5223e64 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2069,7 +2069,6 @@ static struct platform_driver stfsm_driver = { .remove = stfsm_remove, .driver = { .name = "st-spi-fsm", - .owner = THIS_MODULE, .of_match_table = stfsm_match, }, }; -- GitLab From fe5e48259137661a7e07c97a931b4f6aba52ed1e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:57 +0200 Subject: [PATCH 0720/9457] mtd: maps: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/maps/ixp4xx.c | 1 - drivers/mtd/maps/lantiq-flash.c | 1 - drivers/mtd/maps/physmap.c | 1 - drivers/mtd/maps/physmap_of.c | 1 - drivers/mtd/maps/plat-ram.c | 1 - drivers/mtd/maps/pxa2xx-flash.c | 1 - drivers/mtd/maps/rbtx4939-flash.c | 1 - drivers/mtd/maps/sa1100-flash.c | 1 - drivers/mtd/maps/sun_uflash.c | 1 - 9 files changed, 9 deletions(-) diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 6a589f1e2880..b4430741024e 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c @@ -250,7 +250,6 @@ static struct platform_driver ixp4xx_flash_driver = { .remove = ixp4xx_flash_remove, .driver = { .name = "IXP4XX-Flash", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index 7aa682cd4d7e..33d26f5bee54 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c @@ -205,7 +205,6 @@ static struct platform_driver ltq_mtd_driver = { .remove = ltq_mtd_remove, .driver = { .name = "ltq-nor", - .owner = THIS_MODULE, .of_match_table = ltq_mtd_match, }, }; diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index f73cd461257c..4305fd607015 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -217,7 +217,6 @@ static struct platform_driver physmap_flash_driver = { .shutdown = physmap_flash_shutdown, .driver = { .name = "physmap-flash", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index c1d21cb501ca..991d0cb871f0 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -354,7 +354,6 @@ MODULE_DEVICE_TABLE(of, of_flash_match); static struct platform_driver of_flash_driver = { .driver = { .name = "of-flash", - .owner = THIS_MODULE, .of_match_table = of_flash_match, }, .probe = of_flash_probe, diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index d597e89f2692..4b65c08d15f6 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -251,7 +251,6 @@ static struct platform_driver platram_driver = { .remove = platram_remove, .driver = { .name = "mtd-ram", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index cb4d92eea9fe..12fa75df5008 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -131,7 +131,6 @@ static void pxa2xx_flash_shutdown(struct platform_device *dev) static struct platform_driver pxa2xx_flash_driver = { .driver = { .name = "pxa2xx-flash", - .owner = THIS_MODULE, }, .probe = pxa2xx_flash_probe, .remove = pxa2xx_flash_remove, diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c index a84fdfb10518..5a7551aa2d89 100644 --- a/drivers/mtd/maps/rbtx4939-flash.c +++ b/drivers/mtd/maps/rbtx4939-flash.c @@ -127,7 +127,6 @@ static struct platform_driver rbtx4939_flash_driver = { .shutdown = rbtx4939_flash_shutdown, .driver = { .name = "rbtx4939-flash", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 8fc06bf111c4..ea697202935a 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -289,7 +289,6 @@ static struct platform_driver sa1100_mtd_driver = { .remove = __exit_p(sa1100_mtd_remove), .driver = { .name = "sa1100-mtd", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index b6f1aac3510c..d459aca07881 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -150,7 +150,6 @@ MODULE_DEVICE_TABLE(of, uflash_match); static struct platform_driver uflash_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = uflash_match, }, .probe = uflash_probe, -- GitLab From 5cfb36ebf4780ee9a9694f6f43ecaf3fc4a13409 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:58 +0200 Subject: [PATCH 0721/9457] mtd: nand: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/nand/ams-delta.c | 1 - drivers/mtd/nand/atmel_nand.c | 2 -- drivers/mtd/nand/au1550nd.c | 1 - drivers/mtd/nand/bf5xx_nand.c | 1 - drivers/mtd/nand/davinci_nand.c | 1 - drivers/mtd/nand/denali_dt.c | 1 - drivers/mtd/nand/docg4.c | 1 - drivers/mtd/nand/fsl_elbc_nand.c | 1 - drivers/mtd/nand/fsl_ifc_nand.c | 1 - drivers/mtd/nand/fsl_upm.c | 1 - drivers/mtd/nand/fsmc_nand.c | 1 - drivers/mtd/nand/gpio.c | 1 - drivers/mtd/nand/jz4740_nand.c | 1 - drivers/mtd/nand/lpc32xx_mlc.c | 1 - drivers/mtd/nand/lpc32xx_slc.c | 1 - drivers/mtd/nand/mpc5121_nfc.c | 1 - drivers/mtd/nand/mxc_nand.c | 1 - drivers/mtd/nand/ndfc.c | 1 - drivers/mtd/nand/nuc900_nand.c | 1 - drivers/mtd/nand/omap2.c | 1 - drivers/mtd/nand/omap_elm.c | 1 - drivers/mtd/nand/orion_nand.c | 1 - drivers/mtd/nand/pasemi_nand.c | 1 - drivers/mtd/nand/plat_nand.c | 1 - drivers/mtd/nand/s3c2410.c | 1 - drivers/mtd/nand/sh_flctl.c | 1 - drivers/mtd/nand/sharpsl.c | 1 - drivers/mtd/nand/socrates_nand.c | 1 - drivers/mtd/nand/txx9ndfmc.c | 1 - 29 files changed, 30 deletions(-) diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 4936e9e0002f..f1d555cfb332 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -290,7 +290,6 @@ static struct platform_driver ams_delta_nand_driver = { .remove = ams_delta_cleanup, .driver = { .name = "ams-delta-nand", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 19d1e9d17bf9..84c38f3c65b0 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -2312,7 +2312,6 @@ MODULE_DEVICE_TABLE(of, atmel_nand_nfc_match); static struct platform_driver atmel_nand_nfc_driver = { .driver = { .name = "atmel_nand_nfc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_nand_nfc_match), }, .probe = atmel_nand_nfc_probe, @@ -2324,7 +2323,6 @@ static struct platform_driver atmel_nand_driver = { .remove = atmel_nand_remove, .driver = { .name = "atmel_nand", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_nand_dt_ids), }, }; diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 77d6c17b38c2..c0c3be180012 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -503,7 +503,6 @@ static int au1550nd_remove(struct platform_device *pdev) static struct platform_driver au1550nd_driver = { .driver = { .name = "au1550-nand", - .owner = THIS_MODULE, }, .probe = au1550nd_probe, .remove = au1550nd_remove, diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 871c4f712654..4d8d4ba4b9c1 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c @@ -836,7 +836,6 @@ static struct platform_driver bf5xx_nand_driver = { .remove = bf5xx_nand_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index b922c8efcf40..feb6d18de78d 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -870,7 +870,6 @@ static struct platform_driver nand_davinci_driver = { .remove = nand_davinci_remove, .driver = { .name = "davinci_nand", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(davinci_nand_of_match), }, }; diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index 35cb17f57800..0cb1e8d9fbfc 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c @@ -120,7 +120,6 @@ static struct platform_driver denali_dt_driver = { .remove = denali_dt_remove, .driver = { .name = "denali-nand-dt", - .owner = THIS_MODULE, .of_match_table = denali_nand_dt_ids, }, }; diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index ce24637e14f1..e5d7bcaafa7d 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -1380,7 +1380,6 @@ static int __exit cleanup_docg4(struct platform_device *pdev) static struct platform_driver docg4_driver = { .driver = { .name = "docg4", - .owner = THIS_MODULE, }, .suspend = docg4_suspend, .resume = docg4_resume, diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 545a5c002f09..04b22fd3732d 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -950,7 +950,6 @@ static const struct of_device_id fsl_elbc_nand_match[] = { static struct platform_driver fsl_elbc_nand_driver = { .driver = { .name = "fsl,elbc-fcm-nand", - .owner = THIS_MODULE, .of_match_table = fsl_elbc_nand_match, }, .probe = fsl_elbc_nand_probe, diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 2338124dd05f..b9ef7a6bba42 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -1167,7 +1167,6 @@ static const struct of_device_id fsl_ifc_nand_match[] = { static struct platform_driver fsl_ifc_nand_driver = { .driver = { .name = "fsl,ifc-nand", - .owner = THIS_MODULE, .of_match_table = fsl_ifc_nand_match, }, .probe = fsl_ifc_nand_probe, diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 4d203e84e8ca..72755d7ec25d 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -347,7 +347,6 @@ MODULE_DEVICE_TABLE(of, of_fun_match); static struct platform_driver of_fun_driver = { .driver = { .name = "fsl,upm-nand", - .owner = THIS_MODULE, .of_match_table = of_fun_match, }, .probe = fun_probe, diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 7a915870d9d6..edfaa21b1817 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -1224,7 +1224,6 @@ MODULE_DEVICE_TABLE(of, fsmc_nand_id_table); static struct platform_driver fsmc_nand_driver = { .remove = fsmc_nand_remove, .driver = { - .owner = THIS_MODULE, .name = "fsmc-nand", .of_match_table = of_match_ptr(fsmc_nand_id_table), .pm = &fsmc_nand_pm_ops, diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 117ce333fdd4..918283999a4b 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -308,7 +308,6 @@ static struct platform_driver gpio_nand_driver = { .remove = gpio_nand_remove, .driver = { .name = "gpio-nand", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_nand_id_table), }, }; diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index a2c804de156b..1633ec9c5108 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -577,7 +577,6 @@ static struct platform_driver jz_nand_driver = { .remove = jz_nand_remove, .driver = { .name = "jz4740-nand", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 7335346dc126..79c3b7801e1f 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -878,7 +878,6 @@ static struct platform_driver lpc32xx_nand_driver = { .suspend = lpc32xx_nand_suspend, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = lpc32xx_nand_match, }, }; diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 8caef28e0756..abfec13868e5 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c @@ -999,7 +999,6 @@ static struct platform_driver lpc32xx_nand_driver = { .suspend = lpc32xx_nand_suspend, .driver = { .name = LPC32XX_MODNAME, - .owner = THIS_MODULE, .of_match_table = lpc32xx_nand_match, }, }; diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index e78841a2dcc3..1f12e5bfbced 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -847,7 +847,6 @@ static struct platform_driver mpc5121_nfc_driver = { .remove = mpc5121_nfc_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = mpc5121_nfc_match, }, }; diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index dba262bf766f..e1d56beeca79 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1600,7 +1600,6 @@ static int mxcnd_remove(struct platform_device *pdev) static struct platform_driver mxcnd_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mxcnd_dt_ids), }, .id_table = mxcnd_devtype, diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 253a644da76a..3187c6b92d9a 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -277,7 +277,6 @@ MODULE_DEVICE_TABLE(of, ndfc_match); static struct platform_driver ndfc_driver = { .driver = { .name = "ndfc", - .owner = THIS_MODULE, .of_match_table = ndfc_match, }, .probe = ndfc_probe, diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index e8a5fffd6ab2..e58c644dd220 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -300,7 +300,6 @@ static struct platform_driver nuc900_nand_driver = { .remove = nuc900_nand_remove, .driver = { .name = "nuc900-fmi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 3b357e920a0c..6d74b56dd9f6 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -2095,7 +2095,6 @@ static struct platform_driver omap_nand_driver = { .remove = omap_nand_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c index b4f61c7fc161..f73fbeaaeb7a 100644 --- a/drivers/mtd/nand/omap_elm.c +++ b/drivers/mtd/nand/omap_elm.c @@ -563,7 +563,6 @@ MODULE_DEVICE_TABLE(of, elm_of_match); static struct platform_driver elm_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(elm_of_match), .pm = &elm_pm_ops, }, diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 471b4df3a5ac..c53e36956bff 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -224,7 +224,6 @@ static struct platform_driver orion_nand_driver = { .remove = orion_nand_remove, .driver = { .name = "orion_nand", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(orion_nand_of_match_table), }, }; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 2c98f9da7471..66c345b42097 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -223,7 +223,6 @@ static struct platform_driver pasemi_nand_driver = { .driver = { .name = driver_name, - .owner = THIS_MODULE, .of_match_table = pasemi_nand_match, }, .probe = pasemi_nand_probe, diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 0b068a5c0bff..4535c263fae5 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -138,7 +138,6 @@ static struct platform_driver plat_nand_driver = { .remove = plat_nand_remove, .driver = { .name = "gen_nand", - .owner = THIS_MODULE, .of_match_table = plat_nand_match, }, }; diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 6b97bf17ce5d..35aef5edb588 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -1135,7 +1135,6 @@ static struct platform_driver s3c24xx_nand_driver = { .id_table = s3c24xx_driver_ids, .driver = { .name = "s3c24xx-nand", - .owner = THIS_MODULE, }, }; diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 0ed7c603298f..a21c378f096a 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -1190,7 +1190,6 @@ static struct platform_driver flctl_driver = { .remove = flctl_remove, .driver = { .name = "sh_flctl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_flctl_match), }, }; diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index e81059b58382..842c47a451a0 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -220,7 +220,6 @@ static int sharpsl_nand_remove(struct platform_device *pdev) static struct platform_driver sharpsl_nand_driver = { .driver = { .name = "sharpsl-nand", - .owner = THIS_MODULE, }, .probe = sharpsl_nand_probe, .remove = sharpsl_nand_remove, diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index fe8058a45054..d71062273f55 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -240,7 +240,6 @@ MODULE_DEVICE_TABLE(of, socrates_nand_match); static struct platform_driver socrates_nand_driver = { .driver = { .name = "socrates_nand", - .owner = THIS_MODULE, .of_match_table = socrates_nand_match, }, .probe = socrates_nand_probe, diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index c1622a5ba814..9c0bc45e28a9 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -417,7 +417,6 @@ static struct platform_driver txx9ndfmc_driver = { .resume = txx9ndfmc_resume, .driver = { .name = "txx9ndfmc", - .owner = THIS_MODULE, }, }; -- GitLab From 50e23b45999a54a0c9f2865a738559d95c8ecd62 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:58 +0200 Subject: [PATCH 0722/9457] mtd: nand: bcm47xxnflash: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/nand/bcm47xxnflash/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index 107445911315..461577cfb5bc 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c @@ -73,7 +73,6 @@ static struct platform_driver bcm47xxnflash_driver = { .remove = bcm47xxnflash_remove, .driver = { .name = "bcma_nflash", - .owner = THIS_MODULE, }, }; -- GitLab From 5c1a77c7fd816c9e9c4c08132876fcb757732649 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:59 +0200 Subject: [PATCH 0723/9457] mtd: onenand: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/onenand/generic.c | 1 - drivers/mtd/onenand/omap2.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 093c29ac1a13..32a216d31141 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -106,7 +106,6 @@ static int generic_onenand_remove(struct platform_device *pdev) static struct platform_driver generic_onenand_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = generic_onenand_probe, .remove = generic_onenand_remove, diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index d945473c3882..646ddd6db1b4 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -804,7 +804,6 @@ static struct platform_driver omap2_onenand_driver = { .shutdown = omap2_onenand_shutdown, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From c084b7bbd35cb21d2e5a6f3ec75b6dc19331eb2f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:59 +0200 Subject: [PATCH 0724/9457] mtd: spi-nor: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/mtd/spi-nor/fsl-quadspi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2888d5..b60b211594fc 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -996,7 +996,6 @@ static struct platform_driver fsl_qspi_driver = { .driver = { .name = "fsl-quadspi", .bus = &platform_bus_type, - .owner = THIS_MODULE, .of_match_table = fsl_qspi_dt_ids, }, .probe = fsl_qspi_probe, -- GitLab From 0e9063242671dcbc9ca1a10ff5a0cd2dc078397e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:20:59 +0200 Subject: [PATCH 0725/9457] net: can: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/at91_can.c | 1 - drivers/net/can/bfin_can.c | 1 - drivers/net/can/flexcan.c | 1 - drivers/net/can/grcan.c | 1 - drivers/net/can/janz-ican3.c | 1 - drivers/net/can/rcar_can.c | 1 - drivers/net/can/ti_hecc.c | 1 - drivers/net/can/xilinx_can.c | 1 - 8 files changed, 8 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 05e1aa090add..d0c2463b573f 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1428,7 +1428,6 @@ static struct platform_driver at91_can_driver = { .remove = at91_can_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91_can_dt_ids), }, .id_table = at91_can_id_table, diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 543ecceb33e9..417d50998e31 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -680,7 +680,6 @@ static struct platform_driver bfin_can_driver = { .resume = bfin_can_resume, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 60f86bd0434a..f1221b27abd3 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1367,7 +1367,6 @@ static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); static struct platform_driver flexcan_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &flexcan_pm_ops, .of_match_table = flexcan_of_match, }, diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 3fd9fd942c6e..fed1bbd0b0d2 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1738,7 +1738,6 @@ MODULE_DEVICE_TABLE(of, grcan_match); static struct platform_driver grcan_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = grcan_match, }, .probe = grcan_probe, diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 2382c04dc780..1b118394907f 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1910,7 +1910,6 @@ static int ican3_remove(struct platform_device *pdev) static struct platform_driver ican3_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ican3_probe, .remove = ican3_remove, diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index 1abe133d1594..05d57f7bf020 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -906,7 +906,6 @@ MODULE_DEVICE_TABLE(of, rcar_can_of_table); static struct platform_driver rcar_can_driver = { .driver = { .name = RCAR_CAN_DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rcar_can_of_table), .pm = &rcar_can_pm_ops, }, diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 258b9c4856ec..9a07eafe554b 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -1039,7 +1039,6 @@ static int ti_hecc_resume(struct platform_device *pdev) static struct platform_driver ti_hecc_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ti_hecc_probe, .remove = ti_hecc_remove, diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 5e8b5609c067..72fe96fc8fef 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -1194,7 +1194,6 @@ static struct platform_driver xcan_driver = { .probe = xcan_probe, .remove = xcan_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .pm = &xcan_dev_pm_ops, .of_match_table = xcan_of_match, -- GitLab From 8e58ed1ce23ad66dc4f30a7532bce0bcb80e27a2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:00 +0200 Subject: [PATCH 0726/9457] net: can: cc770: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/cc770/cc770_isa.c | 1 - drivers/net/can/cc770/cc770_platform.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c index 87a47c0cfd49..e0d15711e9ac 100644 --- a/drivers/net/can/cc770/cc770_isa.c +++ b/drivers/net/can/cc770/cc770_isa.c @@ -318,7 +318,6 @@ static struct platform_driver cc770_isa_driver = { .remove = cc770_isa_remove, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c index ad76734b3ecc..b1e8851d3cc4 100644 --- a/drivers/net/can/cc770/cc770_platform.c +++ b/drivers/net/can/cc770/cc770_platform.c @@ -264,7 +264,6 @@ MODULE_DEVICE_TABLE(of, cc770_platform_table); static struct platform_driver cc770_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = cc770_platform_table, }, .probe = cc770_platform_probe, -- GitLab From 3865fe261941a21eceac220d837c58a2a957c2f3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:00 +0200 Subject: [PATCH 0727/9457] net: can: c_can: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/c_can/c_can_platform.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index fb279d6ae484..d06f45dc0f59 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -392,7 +392,6 @@ static int c_can_resume(struct platform_device *pdev) static struct platform_driver c_can_plat_driver = { .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = c_can_of_table, }, .probe = c_can_plat_probe, -- GitLab From 0a6e54be42d2e61425188b84068aa74234ba1bbc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:01 +0200 Subject: [PATCH 0728/9457] net: can: mscan: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/mscan/mpc5xxx_can.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 44725296f72a..ad024e60ba8c 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -441,7 +441,6 @@ MODULE_DEVICE_TABLE(of, mpc5xxx_can_table); static struct platform_driver mpc5xxx_can_driver = { .driver = { .name = "mpc5xxx_can", - .owner = THIS_MODULE, .of_match_table = mpc5xxx_can_table, }, .probe = mpc5xxx_can_probe, -- GitLab From ac52841ce7af1c09957922254da035d5607a9b93 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:01 +0200 Subject: [PATCH 0729/9457] net: can: sja1000: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/sja1000/sja1000_isa.c | 1 - drivers/net/can/sja1000/sja1000_platform.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c index 014695d7e6a3..e97e6d35b300 100644 --- a/drivers/net/can/sja1000/sja1000_isa.c +++ b/drivers/net/can/sja1000/sja1000_isa.c @@ -259,7 +259,6 @@ static struct platform_driver sja1000_isa_driver = { .remove = sja1000_isa_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 95a844a7ee7b..93115250eaf5 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -253,7 +253,6 @@ static struct platform_driver sp_driver = { .remove = sp_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = sp_of_table, }, }; -- GitLab From 0dc5a27a175b9b90fb8a84846f915d3a9f50dae9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:01 +0200 Subject: [PATCH 0730/9457] net: can: softing: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/can/softing/softing_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index bacd236ce306..2bf98d862302 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -856,7 +856,6 @@ static int softing_pdev_probe(struct platform_device *pdev) static struct platform_driver softing_driver = { .driver = { .name = "softing", - .owner = THIS_MODULE, }, .probe = softing_pdev_probe, .remove = softing_pdev_remove, -- GitLab From 224cd4b44cbc14d73b13144d15d514d870d3ebfd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:02 +0200 Subject: [PATCH 0731/9457] net: ethernet: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/ethoc.c | 1 - drivers/net/ethernet/lantiq_etop.c | 1 - drivers/net/ethernet/netx-eth.c | 1 - drivers/net/ethernet/s6gmac.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 0bc6c102f3ac..f88cfaa359e7 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -1312,7 +1312,6 @@ static struct platform_driver ethoc_driver = { .resume = ethoc_resume, .driver = { .name = "ethoc", - .owner = THIS_MODULE, .of_match_table = ethoc_match, }, }; diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 2dad4d5047ba..581928c068f2 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -789,7 +789,6 @@ static struct platform_driver ltq_mii_driver = { .remove = ltq_etop_remove, .driver = { .name = "ltq_etop", - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 8176c8a1cc6a..9fbc30264237 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -457,7 +457,6 @@ static struct platform_driver netx_eth_driver = { .resume = netx_eth_drv_resume, .driver = { .name = CARDNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index 1f4449ad8900..f537cbea20e5 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c @@ -1048,7 +1048,6 @@ static struct platform_driver s6gmac_driver = { .remove = s6gmac_remove, .driver = { .name = "s6gmac", - .owner = THIS_MODULE, }, }; -- GitLab From 078d665616ece61c2bfb55a67d2ea758888f8bae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:02 +0200 Subject: [PATCH 0732/9457] net: ethernet: 8390: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/8390/ax88796.c | 1 - drivers/net/ethernet/8390/mcf8390.c | 1 - drivers/net/ethernet/8390/ne.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 1d162ccb4733..0443654f0339 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -1000,7 +1000,6 @@ static int ax_resume(struct platform_device *pdev) static struct platform_driver axdrv = { .driver = { .name = "ax88796", - .owner = THIS_MODULE, }, .probe = ax_probe, .remove = ax_remove, diff --git a/drivers/net/ethernet/8390/mcf8390.c b/drivers/net/ethernet/8390/mcf8390.c index 38fcdcf7c4c7..e1c055574a11 100644 --- a/drivers/net/ethernet/8390/mcf8390.c +++ b/drivers/net/ethernet/8390/mcf8390.c @@ -467,7 +467,6 @@ static int mcf8390_remove(struct platform_device *pdev) static struct platform_driver mcf8390_drv = { .driver = { .name = "mcf8390", - .owner = THIS_MODULE, }, .probe = mcf8390_probe, .remove = mcf8390_remove, diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index de566fb6e0f7..c063b410a163 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c @@ -920,7 +920,6 @@ static struct platform_driver ne_driver = { .resume = ne_drv_resume, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From 5a21758d26e027b03efde2c4fbabdd3ae17fa6d1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:03 +0200 Subject: [PATCH 0733/9457] net: ethernet: adi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/adi/bfin_mac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index 8ed4d3408ef6..ec20611e9de2 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -1901,7 +1901,6 @@ static struct platform_driver bfin_mii_bus_driver = { .remove = bfin_mii_bus_remove, .driver = { .name = "bfin_mii_bus", - .owner = THIS_MODULE, }, }; @@ -1912,7 +1911,6 @@ static struct platform_driver bfin_mac_driver = { .suspend = bfin_mac_suspend, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, }; -- GitLab From 07646c937958d986a973d5bf647af23013e3e4ef Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:03 +0200 Subject: [PATCH 0734/9457] net: ethernet: aeroflex: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/aeroflex/greth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 3005155e412b..2b8bfeeee9cf 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1603,7 +1603,6 @@ MODULE_DEVICE_TABLE(of, greth_of_match); static struct platform_driver greth_of_driver = { .driver = { .name = "grlib-greth", - .owner = THIS_MODULE, .of_match_table = greth_of_match, }, .probe = greth_of_probe, -- GitLab From 0c026c179e83c6229b6744c2373d5c41e3bf606c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:04 +0200 Subject: [PATCH 0735/9457] net: ethernet: altera: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/altera/altera_tse_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index 4efc4355d345..3498760dc22a 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -1587,7 +1587,6 @@ static struct platform_driver altera_tse_driver = { .resume = NULL, .driver = { .name = ALTERA_TSE_RESOURCE_NAME, - .owner = THIS_MODULE, .of_match_table = altera_tse_ids, }, }; -- GitLab From 884df0a3143b67b0f309656a3a47365d9bf77b94 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:04 +0200 Subject: [PATCH 0736/9457] net: ethernet: amd: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/amd/au1000_eth.c | 1 - drivers/net/ethernet/amd/sunlance.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 6c323f4f457b..cb367cc59e0b 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -1461,7 +1461,6 @@ static struct platform_driver au1000_eth_driver = { .remove = au1000_remove, .driver = { .name = "au1000-eth", - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 5e4273b7aa27..7847638bdd22 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -1524,7 +1524,6 @@ MODULE_DEVICE_TABLE(of, sunlance_sbus_match); static struct platform_driver sunlance_sbus_driver = { .driver = { .name = "sunlance", - .owner = THIS_MODULE, .of_match_table = sunlance_sbus_match, }, .probe = sunlance_sbus_probe, -- GitLab From 69ddb8a2c8032cfdcaa47007e7c5a86c51402708 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:04 +0200 Subject: [PATCH 0737/9457] net: ethernet: apple: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/apple/macmace.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index 58a200df4c35..6e66127e6abf 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -768,7 +768,6 @@ static struct platform_driver mac_mace_driver = { .remove = mac_mace_device_remove, .driver = { .name = mac_mace_string, - .owner = THIS_MODULE, }, }; -- GitLab From 3a2f66b5447ec65cc00924d1bce75162209dc299 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:05 +0200 Subject: [PATCH 0738/9457] net: ethernet: broadcom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/broadcom/bcmsysport.c | 1 - drivers/net/ethernet/broadcom/sb1250-mac.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 9ae36979bdee..a06d2df53152 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1954,7 +1954,6 @@ static struct platform_driver bcm_sysport_driver = { .remove = bcm_sysport_remove, .driver = { .name = "brcm-systemport", - .owner = THIS_MODULE, .of_match_table = bcm_sysport_of_match, .pm = &bcm_sysport_pm_ops, }, diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index b61c14ed9b8d..ac27e24264a5 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -2664,7 +2664,6 @@ static struct platform_driver sbmac_driver = { .remove = __exit_p(sbmac_remove), .driver = { .name = sbmac_string, - .owner = THIS_MODULE, }, }; -- GitLab From 63ad0215e1ad288910e4dcc957fd07ee99864866 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:05 +0200 Subject: [PATCH 0739/9457] net: ethernet: broadcom: genet: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index fdc9ec09e453..aafbefe9f78f 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2735,7 +2735,6 @@ static struct platform_driver bcmgenet_driver = { .remove = bcmgenet_remove, .driver = { .name = "bcmgenet", - .owner = THIS_MODULE, .of_match_table = bcmgenet_match, .pm = &bcmgenet_pm_ops, }, -- GitLab From fe6a12d1b2bc6aec1ae2d624a517cd7295733fba Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:06 +0200 Subject: [PATCH 0740/9457] net: ethernet: cadence: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/cadence/at91_ether.c | 1 - drivers/net/ethernet/cadence/macb.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 4a24b9a6ad75..55eb7f2af2b4 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -469,7 +469,6 @@ static struct platform_driver at91ether_driver = { .resume = at91ether_resume, .driver = { .name = "at91_ether", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91ether_dt_ids), }, }; diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 4d9fc0509af6..41113e51c704 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -2321,7 +2321,6 @@ static struct platform_driver macb_driver = { .remove = __exit_p(macb_remove), .driver = { .name = "macb", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(macb_dt_ids), .pm = &macb_pm_ops, }, -- GitLab From bfe68b1423afc27cbc41733799ab170b6a876fa8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:06 +0200 Subject: [PATCH 0741/9457] net: ethernet: cirrus: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/cirrus/cs89x0.c | 1 - drivers/net/ethernet/cirrus/ep93xx_eth.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 9823a0ea7937..b2427928eb11 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1897,7 +1897,6 @@ static int cs89x0_platform_remove(struct platform_device *pdev) static struct platform_driver cs89x0_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .remove = cs89x0_platform_remove, }; diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c index 2be2a99c5ea3..3a12c096ea1c 100644 --- a/drivers/net/ethernet/cirrus/ep93xx_eth.c +++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c @@ -881,7 +881,6 @@ static struct platform_driver ep93xx_eth_driver = { .remove = ep93xx_eth_remove, .driver = { .name = "ep93xx-eth", - .owner = THIS_MODULE, }, }; -- GitLab From 46c68a571703f18b41c28d7305486d9c763cba9b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:06 +0200 Subject: [PATCH 0742/9457] net: ethernet: davicom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/davicom/dm9000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index f3ba840cbf7b..ef0bb58750e6 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1749,7 +1749,6 @@ MODULE_DEVICE_TABLE(of, dm9000_of_matches); static struct platform_driver dm9000_driver = { .driver = { .name = "dm9000", - .owner = THIS_MODULE, .pm = &dm9000_drv_pm_ops, .of_match_table = of_match_ptr(dm9000_of_matches), }, -- GitLab From d6cc5c262205e1295b7d7f04f11957b206fec636 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:07 +0200 Subject: [PATCH 0743/9457] net: ethernet: faraday: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/faraday/ftgmac100.c | 1 - drivers/net/ethernet/faraday/ftmac100.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index c77fa4a69844..6d0c5d5eea6d 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1335,7 +1335,6 @@ static struct platform_driver ftgmac100_driver = { .remove = __exit_p(ftgmac100_remove), .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c index 4ff1adc6bfca..dce5f7b7f772 100644 --- a/drivers/net/ethernet/faraday/ftmac100.c +++ b/drivers/net/ethernet/faraday/ftmac100.c @@ -1177,7 +1177,6 @@ static struct platform_driver ftmac100_driver = { .remove = __exit_p(ftmac100_remove), .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From a057351e1e333c4753384be880518efee363e664 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:07 +0200 Subject: [PATCH 0744/9457] net: ethernet: freescale: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/freescale/fec_main.c | 1 - drivers/net/ethernet/freescale/fec_mpc52xx.c | 1 - drivers/net/ethernet/freescale/fsl_pq_mdio.c | 1 - drivers/net/ethernet/freescale/gianfar.c | 1 - drivers/net/ethernet/freescale/gianfar_ptp.c | 1 - drivers/net/ethernet/freescale/ucc_geth.c | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 81b96cf87574..ac6481015959 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3395,7 +3395,6 @@ static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume); static struct platform_driver fec_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &fec_pm_ops, .of_match_table = fec_dt_ids, }, diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c index ff55fbb20a75..f495796248db 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c @@ -1069,7 +1069,6 @@ MODULE_DEVICE_TABLE(of, mpc52xx_fec_match); static struct platform_driver mpc52xx_fec_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mpc52xx_fec_match, }, .probe = mpc52xx_fec_probe, diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 964c6bf37710..d1a91e344e6b 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -488,7 +488,6 @@ static int fsl_pq_mdio_remove(struct platform_device *pdev) static struct platform_driver fsl_pq_mdio_driver = { .driver = { .name = "fsl-pq_mdio", - .owner = THIS_MODULE, .of_match_table = fsl_pq_mdio_match, }, .probe = fsl_pq_mdio_probe, diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4fdf0aa16978..610a4a87e86c 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -3472,7 +3472,6 @@ MODULE_DEVICE_TABLE(of, gfar_match); static struct platform_driver gfar_driver = { .driver = { .name = "fsl-gianfar", - .owner = THIS_MODULE, .pm = GFAR_PM_OPS, .of_match_table = gfar_match, }, diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index bb568006f37d..16826341a4c9 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -563,7 +563,6 @@ static struct platform_driver gianfar_ptp_driver = { .driver = { .name = "gianfar_ptp", .of_match_table = match_table, - .owner = THIS_MODULE, }, .probe = gianfar_ptp_probe, .remove = gianfar_ptp_remove, diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 3cf0478b3728..357e8b576905 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -3943,7 +3943,6 @@ MODULE_DEVICE_TABLE(of, ucc_geth_match); static struct platform_driver ucc_geth_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = ucc_geth_match, }, .probe = ucc_geth_probe, -- GitLab From bfd5f04ffa9d3d87c73e4332080668d63746f609 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:08 +0200 Subject: [PATCH 0745/9457] net: ethernet: freescale: fs_enet: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 1 - drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c | 1 - drivers/net/ethernet/freescale/fs_enet/mii-fec.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index c92c3b7876ca..9e2bcb807923 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -1087,7 +1087,6 @@ MODULE_DEVICE_TABLE(of, fs_enet_match); static struct platform_driver fs_enet_driver = { .driver = { - .owner = THIS_MODULE, .name = "fs_enet", .of_match_table = fs_enet_match, }, diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 3d3fde66c2cc..1d5617d2d8bd 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -224,7 +224,6 @@ MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); static struct platform_driver fs_enet_bb_mdio_driver = { .driver = { .name = "fsl-bb-mdio", - .owner = THIS_MODULE, .of_match_table = fs_enet_mdio_bb_match, }, .probe = fs_enet_mdio_probe, diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index ebf5d6429a8d..1648e3582500 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -225,7 +225,6 @@ MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match); static struct platform_driver fs_enet_fec_mdio_driver = { .driver = { .name = "fsl-fec-mdio", - .owner = THIS_MODULE, .of_match_table = fs_enet_mdio_fec_match, }, .probe = fs_enet_mdio_probe, -- GitLab From 3f8e0b5fdda42cc1e17e141b6bff2d335b839b75 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:08 +0200 Subject: [PATCH 0746/9457] net: ethernet: i825xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/i825xx/sni_82596.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/i825xx/sni_82596.c b/drivers/net/ethernet/i825xx/sni_82596.c index 372fa8d1fda1..2af7f77345fb 100644 --- a/drivers/net/ethernet/i825xx/sni_82596.c +++ b/drivers/net/ethernet/i825xx/sni_82596.c @@ -165,7 +165,6 @@ static struct platform_driver sni_82596_driver = { .remove = sni_82596_driver_remove, .driver = { .name = sni_82596_string, - .owner = THIS_MODULE, }, }; -- GitLab From 379f023d273caf5e48e155581850e4ef24f52011 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:08 +0200 Subject: [PATCH 0747/9457] net: ethernet: ibm: emac: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/ibm/emac/core.c | 1 - drivers/net/ethernet/ibm/emac/mal.c | 1 - drivers/net/ethernet/ibm/emac/rgmii.c | 1 - drivers/net/ethernet/ibm/emac/tah.c | 1 - drivers/net/ethernet/ibm/emac/zmii.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 87bd953cc2ee..61ae5cbd1270 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -3009,7 +3009,6 @@ MODULE_DEVICE_TABLE(of, emac_match); static struct platform_driver emac_driver = { .driver = { .name = "emac", - .owner = THIS_MODULE, .of_match_table = emac_match, }, .probe = emac_probe, diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index 63eb959a28aa..dddaab11a4c7 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -776,7 +776,6 @@ static struct of_device_id mal_platform_match[] = static struct platform_driver mal_of_driver = { .driver = { .name = "mcmal", - .owner = THIS_MODULE, .of_match_table = mal_platform_match, }, .probe = mal_probe, diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index a01182cce965..457088fc5b06 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -319,7 +319,6 @@ static struct of_device_id rgmii_match[] = static struct platform_driver rgmii_driver = { .driver = { .name = "emac-rgmii", - .owner = THIS_MODULE, .of_match_table = rgmii_match, }, .probe = rgmii_probe, diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index 9f24769ed826..cb18e7f917c6 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -163,7 +163,6 @@ static struct of_device_id tah_match[] = static struct platform_driver tah_driver = { .driver = { .name = "emac-tah", - .owner = THIS_MODULE, .of_match_table = tah_match, }, .probe = tah_probe, diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index 9ca67a38c062..36409ccb75ea 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -310,7 +310,6 @@ static struct of_device_id zmii_match[] = static struct platform_driver zmii_driver = { .driver = { .name = "emac-zmii", - .owner = THIS_MODULE, .of_match_table = zmii_match, }, .probe = zmii_probe, -- GitLab From 7a53834e6e79b98d71dab49b53e0f66608a67d55 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:09 +0200 Subject: [PATCH 0748/9457] net: ethernet: marvell: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/marvell/mv643xx_eth.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index b151a949f352..513276489d3f 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -2837,7 +2837,6 @@ static struct platform_driver mv643xx_eth_shared_driver = { .remove = mv643xx_eth_shared_remove, .driver = { .name = MV643XX_ETH_SHARED_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mv643xx_eth_shared_ids), }, }; @@ -3186,7 +3185,6 @@ static struct platform_driver mv643xx_eth_driver = { .shutdown = mv643xx_eth_shutdown, .driver = { .name = MV643XX_ETH_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From f1535688c2de69512521c61c498d265d7405241f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:09 +0200 Subject: [PATCH 0749/9457] net: ethernet: micrel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/micrel/ks8695net.c | 1 - drivers/net/ethernet/micrel/ks8842.c | 1 - drivers/net/ethernet/micrel/ks8851_mll.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index 6c7c78baedca..a8522d8af95d 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -1612,7 +1612,6 @@ ks8695_drv_remove(struct platform_device *pdev) static struct platform_driver ks8695_driver = { .driver = { .name = MODULENAME, - .owner = THIS_MODULE, }, .probe = ks8695_probe, .remove = ks8695_drv_remove, diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c index 0c33b92a5a81..f78909a00f15 100644 --- a/drivers/net/ethernet/micrel/ks8842.c +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -1255,7 +1255,6 @@ static int ks8842_remove(struct platform_device *pdev) static struct platform_driver ks8842_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ks8842_probe, .remove = ks8842_remove, diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 0eb47649191b..2fc5cd56c0a8 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1679,7 +1679,6 @@ static int ks8851_remove(struct platform_device *pdev) static struct platform_driver ks8851_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ks8851_ml_dt_ids), }, .probe = ks8851_probe, -- GitLab From 8fc5fb43efb051297e579083c2f331e3e4a75f86 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:10 +0200 Subject: [PATCH 0750/9457] net: ethernet: moxa: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/moxa/moxart_ether.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index bde1b70f473b..6c72e74fef3e 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -559,7 +559,6 @@ static struct platform_driver moxart_mac_driver = { .remove = moxart_remove, .driver = { .name = "moxart-ethernet", - .owner = THIS_MODULE, .of_match_table = moxart_mac_match, }, }; -- GitLab From b9deaa2a54d3b8bd229e428f0cd294ca2bcc6625 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:10 +0200 Subject: [PATCH 0751/9457] net: ethernet: natsemi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/natsemi/jazzsonic.c | 1 - drivers/net/ethernet/natsemi/macsonic.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c index a5512a97cc4d..acf3f11e38cc 100644 --- a/drivers/net/ethernet/natsemi/jazzsonic.c +++ b/drivers/net/ethernet/natsemi/jazzsonic.c @@ -287,7 +287,6 @@ static struct platform_driver jazz_sonic_driver = { .remove = jazz_sonic_device_remove, .driver = { .name = jazz_sonic_string, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index 9e4ddbba7036..5b2dcb03c29e 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -634,7 +634,6 @@ static struct platform_driver mac_sonic_driver = { .remove = mac_sonic_device_remove, .driver = { .name = mac_sonic_string, - .owner = THIS_MODULE, }, }; -- GitLab From e590dead91f12b56da7c5711429482acef8697f1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:10 +0200 Subject: [PATCH 0752/9457] net: ethernet: nuvoton: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/nuvoton/w90p910_ether.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c index 379b7fbded78..afa445842f3e 100644 --- a/drivers/net/ethernet/nuvoton/w90p910_ether.c +++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c @@ -1081,7 +1081,6 @@ static struct platform_driver w90p910_ether_driver = { .remove = w90p910_ether_remove, .driver = { .name = "nuc900-emc", - .owner = THIS_MODULE, }, }; -- GitLab From fb5b11f6ce8016ffe3d1eaadb387d01f7fefc297 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:11 +0200 Subject: [PATCH 0753/9457] net: ethernet: octeon: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/octeon/octeon_mgmt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c index a42293092ea4..d36599f47af5 100644 --- a/drivers/net/ethernet/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/octeon/octeon_mgmt.c @@ -1568,7 +1568,6 @@ MODULE_DEVICE_TABLE(of, octeon_mgmt_match); static struct platform_driver octeon_mgmt_driver = { .driver = { .name = "octeon_mgmt", - .owner = THIS_MODULE, .of_match_table = octeon_mgmt_match, }, .probe = octeon_mgmt_probe, -- GitLab From 6afa02fbf992620edbf6b1ef87d879cf45056094 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:11 +0200 Subject: [PATCH 0754/9457] net: ethernet: samsung: sxgbe: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index b147d469a799..b37db0b0da72 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c @@ -236,7 +236,6 @@ static struct platform_driver sxgbe_platform_driver = { .remove = sxgbe_platform_remove, .driver = { .name = SXGBE_RESOURCE_NAME, - .owner = THIS_MODULE, .pm = &sxgbe_platform_pm_ops, .of_match_table = of_match_ptr(sxgbe_dt_ids), }, -- GitLab From bd8eabfa0ae52c172b75bd6c53f41e5d82a12547 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:12 +0200 Subject: [PATCH 0755/9457] net: ethernet: seeq: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/seeq/sgiseeq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index 69e4fd21adb4..ca7336605748 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -826,7 +826,6 @@ static struct platform_driver sgiseeq_driver = { .remove = __exit_p(sgiseeq_remove), .driver = { .name = "sgiseeq", - .owner = THIS_MODULE, } }; -- GitLab From 5a8078bebd3805d1150642c67440cc510e686f52 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:12 +0200 Subject: [PATCH 0756/9457] net: ethernet: sgi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/sgi/meth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/sgi/meth.c b/drivers/net/ethernet/sgi/meth.c index 5564a5fa3385..5eac523b4b0c 100644 --- a/drivers/net/ethernet/sgi/meth.c +++ b/drivers/net/ethernet/sgi/meth.c @@ -870,7 +870,6 @@ static struct platform_driver meth_driver = { .remove = __exit_p(meth_remove), .driver = { .name = "meth", - .owner = THIS_MODULE, } }; -- GitLab From 6577f97d476f5ca5cfc38219d9dce881579ae1b5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:12 +0200 Subject: [PATCH 0757/9457] net: ethernet: smsc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/smsc/smc911x.c | 1 - drivers/net/ethernet/smsc/smc91x.c | 1 - drivers/net/ethernet/smsc/smsc911x.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index e88df9c7f1c0..bd64eb982e52 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -2173,7 +2173,6 @@ static struct platform_driver smc911x_driver = { .resume = smc911x_drv_resume, .driver = { .name = CARDNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 5e94d00b96b3..a2649c81a393 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -2410,7 +2410,6 @@ static struct platform_driver smc_driver = { .remove = smc_drv_remove, .driver = { .name = CARDNAME, - .owner = THIS_MODULE, .pm = &smc_drv_pm_ops, .of_match_table = of_match_ptr(smc91x_match), }, diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index affb29da353e..a255be08e34f 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2610,7 +2610,6 @@ static struct platform_driver smsc911x_driver = { .remove = smsc911x_drv_remove, .driver = { .name = SMSC_CHIPNAME, - .owner = THIS_MODULE, .pm = SMSC911X_PM_OPS, .of_match_table = of_match_ptr(smsc911x_dt_ids), }, -- GitLab From 3a6e44c57a75f6a73614b1be9c953654864adaaa Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:13 +0200 Subject: [PATCH 0758/9457] net: ethernet: sun: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/sun/niu.c | 1 - drivers/net/ethernet/sun/sunbmac.c | 1 - drivers/net/ethernet/sun/sunhme.c | 1 - drivers/net/ethernet/sun/sunqe.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 904fd1ab5f6e..a2a1d32742a6 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -10185,7 +10185,6 @@ MODULE_DEVICE_TABLE(of, niu_match); static struct platform_driver niu_of_driver = { .driver = { .name = "niu", - .owner = THIS_MODULE, .of_match_table = niu_match, }, .probe = niu_of_probe, diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c index 206c1063815a..aa4f9d2d8fa9 100644 --- a/drivers/net/ethernet/sun/sunbmac.c +++ b/drivers/net/ethernet/sun/sunbmac.c @@ -1273,7 +1273,6 @@ MODULE_DEVICE_TABLE(of, bigmac_sbus_match); static struct platform_driver bigmac_sbus_driver = { .driver = { .name = "sunbmac", - .owner = THIS_MODULE, .of_match_table = bigmac_sbus_match, }, .probe = bigmac_sbus_probe, diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 72c8525d5457..4396c570beb4 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -3271,7 +3271,6 @@ MODULE_DEVICE_TABLE(of, hme_sbus_match); static struct platform_driver hme_sbus_driver = { .driver = { .name = "hme", - .owner = THIS_MODULE, .of_match_table = hme_sbus_match, }, .probe = hme_sbus_probe, diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 5695ae2411de..9b825780b3be 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -963,7 +963,6 @@ MODULE_DEVICE_TABLE(of, qec_sbus_match); static struct platform_driver qec_sbus_driver = { .driver = { .name = "qec", - .owner = THIS_MODULE, .of_match_table = qec_sbus_match, }, .probe = qec_sbus_probe, -- GitLab From 671ebaf7259fd590346a560ac43acc49933dabf6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:13 +0200 Subject: [PATCH 0759/9457] net: ethernet: tundra: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/tundra/tsi108_eth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 47eeb3abf7f7..520cf50a3d5a 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -161,7 +161,6 @@ static struct platform_driver tsi_eth_driver = { .remove = tsi108_ether_remove, .driver = { .name = "tsi-ethernet", - .owner = THIS_MODULE, }, }; -- GitLab From 5e0b25165749a32616f30fbf5870507d5d765b89 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:14 +0200 Subject: [PATCH 0760/9457] net: ethernet: via: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/via/via-rhine.c | 1 - drivers/net/ethernet/via/via-velocity.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 68c5260cc322..a191afc23b56 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -2508,7 +2508,6 @@ static struct platform_driver rhine_driver_platform = { .remove = rhine_remove_one_platform, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = rhine_of_tbl, .pm = RHINE_PM_OPS, } diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index a43e8492b1ce..282f83a63b67 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -3281,7 +3281,6 @@ static struct platform_driver velocity_platform_driver = { .remove = velocity_platform_remove, .driver = { .name = "via-velocity", - .owner = THIS_MODULE, .of_match_table = velocity_of_ids, .pm = &velocity_pm_ops, }, -- GitLab From bd0e5d5a7eae99fc2abff756e4ad19825bf41c03 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:14 +0200 Subject: [PATCH 0761/9457] net: ethernet: wiznet: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ethernet/wiznet/w5100.c | 1 - drivers/net/ethernet/wiznet/w5300.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index 0f56b1c0e082..13c5c9844da7 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -790,7 +790,6 @@ static SIMPLE_DEV_PM_OPS(w5100_pm_ops, w5100_suspend, w5100_resume); static struct platform_driver w5100_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &w5100_pm_ops, }, .probe = w5100_probe, diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c index f961f14a0473..b9b2f7547c43 100644 --- a/drivers/net/ethernet/wiznet/w5300.c +++ b/drivers/net/ethernet/wiznet/w5300.c @@ -702,7 +702,6 @@ static SIMPLE_DEV_PM_OPS(w5300_pm_ops, w5300_suspend, w5300_resume); static struct platform_driver w5300_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &w5300_pm_ops, }, .probe = w5300_probe, -- GitLab From bb1f1107858c1cb3cbb870852f54a0169cb2c360 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:14 +0200 Subject: [PATCH 0762/9457] net: ieee802154: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/ieee802154/fakehard.c | 1 - drivers/net/ieee802154/fakelb.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 9ce854f43917..3db412b4465e 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -405,7 +405,6 @@ static struct platform_driver ieee802154fake_driver = { .remove = ieee802154fake_remove, .driver = { .name = "ieee802154hardmac", - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 27d83207d24c..c1397cddd1b8 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -272,7 +272,6 @@ static struct platform_driver ieee802154fake_driver = { .remove = fakelb_remove, .driver = { .name = "ieee802154fakelb", - .owner = THIS_MODULE, }, }; -- GitLab From 3f00302fbaf4a561d89a0c030fab6151b0f233ca Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:15 +0200 Subject: [PATCH 0763/9457] net: irda: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/irda/ali-ircc.c | 1 - drivers/net/irda/au1k_ir.c | 1 - drivers/net/irda/pxaficp_ir.c | 1 - drivers/net/irda/sa1100_ir.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index befa45f809c3..9673670b8773 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -61,7 +61,6 @@ static struct platform_driver ali_ircc_driver = { .resume = ali_ircc_resume, .driver = { .name = ALI_IRCC_DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index aab2cf72d025..e151205281e2 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -989,7 +989,6 @@ static int au1k_irda_remove(struct platform_device *pdev) static struct platform_driver au1k_irda_driver = { .driver = { .name = "au1000-irda", - .owner = THIS_MODULE, }, .probe = au1k_irda_probe, .remove = au1k_irda_remove, diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 3eeaaf800494..100454662e4b 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -966,7 +966,6 @@ static int pxa_irda_remove(struct platform_device *_dev) static struct platform_driver pxa_ir_driver = { .driver = { .name = "pxa2xx-ir", - .owner = THIS_MODULE, }, .probe = pxa_irda_probe, .remove = pxa_irda_remove, diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 42fde9ed23e1..7b17fa2114e1 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -1114,7 +1114,6 @@ static struct platform_driver sa1100ir_driver = { .resume = sa1100_irda_resume, .driver = { .name = "sa11x0-ir", - .owner = THIS_MODULE, }, }; -- GitLab From 9aec7aeced5ae5a22a0702794b061d34723d79e1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:15 +0200 Subject: [PATCH 0764/9457] net: phy: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/phy/mdio-bcm-unimac.c | 1 - drivers/net/phy/mdio-gpio.c | 1 - drivers/net/phy/mdio-mux-gpio.c | 1 - drivers/net/phy/mdio-mux-mmioreg.c | 1 - drivers/net/phy/mdio-octeon.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/net/phy/mdio-bcm-unimac.c b/drivers/net/phy/mdio-bcm-unimac.c index 5b643e588e8f..6deac6d32f57 100644 --- a/drivers/net/phy/mdio-bcm-unimac.c +++ b/drivers/net/phy/mdio-bcm-unimac.c @@ -199,7 +199,6 @@ static struct of_device_id unimac_mdio_ids[] = { static struct platform_driver unimac_mdio_driver = { .driver = { .name = "unimac-mdio", - .owner = THIS_MODULE, .of_match_table = unimac_mdio_ids, }, .probe = unimac_mdio_probe, diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 5f1a2250018f..0a0578a592b8 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -259,7 +259,6 @@ static struct platform_driver mdio_gpio_driver = { .remove = mdio_gpio_remove, .driver = { .name = "mdio-gpio", - .owner = THIS_MODULE, .of_match_table = mdio_gpio_of_match, }, }; diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c index 096695163491..6d5073839f7b 100644 --- a/drivers/net/phy/mdio-mux-gpio.c +++ b/drivers/net/phy/mdio-mux-gpio.c @@ -125,7 +125,6 @@ MODULE_DEVICE_TABLE(of, mdio_mux_gpio_match); static struct platform_driver mdio_mux_gpio_driver = { .driver = { .name = "mdio-mux-gpio", - .owner = THIS_MODULE, .of_match_table = mdio_mux_gpio_match, }, .probe = mdio_mux_gpio_probe, diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c index 1656785ff339..0aa985c74014 100644 --- a/drivers/net/phy/mdio-mux-mmioreg.c +++ b/drivers/net/phy/mdio-mux-mmioreg.c @@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, mdio_mux_mmioreg_match); static struct platform_driver mdio_mux_mmioreg_driver = { .driver = { .name = "mdio-mux-mmioreg", - .owner = THIS_MODULE, .of_match_table = mdio_mux_mmioreg_match, }, .probe = mdio_mux_mmioreg_probe, diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index a51ed92fbada..c81052486edc 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -263,7 +263,6 @@ MODULE_DEVICE_TABLE(of, octeon_mdiobus_match); static struct platform_driver octeon_mdiobus_driver = { .driver = { .name = "mdio-octeon", - .owner = THIS_MODULE, .of_match_table = octeon_mdiobus_match, }, .probe = octeon_mdiobus_probe, -- GitLab From 77cb54db5c2eba4f37d54d385a6a1553ba32e050 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:16 +0200 Subject: [PATCH 0765/9457] net: wireless: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/mac80211_hwsim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index babbdc1ce741..1510a3b7b5eb 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -395,7 +395,6 @@ static int hwsim_radio_idx; static struct platform_driver mac80211_hwsim_driver = { .driver = { .name = "mac80211_hwsim", - .owner = THIS_MODULE, }, }; -- GitLab From d250fe6665d64c5eba3f337b1d83ee79d68ac461 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:16 +0200 Subject: [PATCH 0766/9457] net: wireless: ath: ath9k: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/ath/ath9k/ahb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 4173838f4684..e000c4c27881 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -175,7 +175,6 @@ static struct platform_driver ath_ahb_driver = { .remove = ath_ahb_remove, .driver = { .name = "ath9k", - .owner = THIS_MODULE, }, .id_table = ath9k_platform_id_table, }; -- GitLab From 0b07a15404ccc7a915e1909bf773b73370ba9eae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:17 +0200 Subject: [PATCH 0767/9457] net: wireless: ath: wcn36xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/ath/wcn36xx/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index b71d2b33532d..30c9dca38c58 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1075,7 +1075,6 @@ static struct platform_driver wcn36xx_driver = { .remove = wcn36xx_remove, .driver = { .name = "wcn36xx", - .owner = THIS_MODULE, }, .id_table = wcn36xx_platform_id_table, }; -- GitLab From e8460665ed5081b9f93349fe05ad3529f887c3d5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:17 +0200 Subject: [PATCH 0768/9457] net: wireless: brcm80211: brcmfmac: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 8dbd5dbb78fd..602034306076 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1204,7 +1204,6 @@ static struct platform_driver brcmf_sdio_pd = { .remove = brcmf_sdio_pd_remove, .driver = { .name = BRCMFMAC_SDIO_PDATA_NAME, - .owner = THIS_MODULE, } }; -- GitLab From f853e9b3f16691b6ccb6d90aa67b56a852b49749 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:18 +0200 Subject: [PATCH 0769/9457] net: wireless: rt2x00: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/rt2x00/rt2800soc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800soc.c b/drivers/net/wireless/rt2x00/rt2800soc.c index f6d1bf5be006..aaa7aa4cad9d 100644 --- a/drivers/net/wireless/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/rt2x00/rt2800soc.c @@ -244,7 +244,6 @@ static int rt2800soc_probe(struct platform_device *pdev) static struct platform_driver rt2800soc_driver = { .driver = { .name = "rt2800_wmac", - .owner = THIS_MODULE, .mod_name = KBUILD_MODNAME, }, .probe = rt2800soc_probe, -- GitLab From 0db942e9c0b314ac7a205f42121f704c7ef092cf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:18 +0200 Subject: [PATCH 0770/9457] net: wireless: ti: wl12xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/ti/wl12xx/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 0bccf123831e..d6d0d6d9c7a8 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1900,7 +1900,6 @@ static struct platform_driver wl12xx_driver = { .id_table = wl12xx_id_table, .driver = { .name = "wl12xx_driver", - .owner = THIS_MODULE, } }; -- GitLab From 65cfd80354a6217afe13ad304e9f5615226463bf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:19 +0200 Subject: [PATCH 0771/9457] net: wireless: ti: wl18xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/net/wireless/ti/wl18xx/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 7af1936719eb..8e562610bf16 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -1968,7 +1968,6 @@ static struct platform_driver wl18xx_driver = { .id_table = wl18xx_id_table, .driver = { .name = "wl18xx_driver", - .owner = THIS_MODULE, } }; -- GitLab From 47fc34ffd9c24cf100927da659309a12acbe0d3d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:19 +0200 Subject: [PATCH 0772/9457] nfc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/nfc/nfcwilink.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index 683671a71c7e..ce2e2cf54fbc 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -566,7 +566,6 @@ static struct platform_driver nfcwilink_driver = { .remove = nfcwilink_remove, .driver = { .name = "nfcwilink", - .owner = THIS_MODULE, }, }; -- GitLab From 2422f7e4d1138a740f228bd4983815bf3b3254e4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:20 +0200 Subject: [PATCH 0773/9457] parport: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/parport/parport_amiga.c | 1 - drivers/parport/parport_ax88796.c | 1 - drivers/parport/parport_pc.c | 1 - drivers/parport/parport_sunbpp.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c index 26ecdea84fb5..9c68f2aec4ff 100644 --- a/drivers/parport/parport_amiga.c +++ b/drivers/parport/parport_amiga.c @@ -239,7 +239,6 @@ static struct platform_driver amiga_parallel_driver = { .remove = __exit_p(amiga_parallel_remove), .driver = { .name = "amiga-parallel", - .owner = THIS_MODULE, }, }; diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c index 7c5d86696eed..8f8c9f3aa691 100644 --- a/drivers/parport/parport_ax88796.c +++ b/drivers/parport/parport_ax88796.c @@ -412,7 +412,6 @@ MODULE_ALIAS("platform:ax88796-pp"); static struct platform_driver axdrv = { .driver = { .name = "ax88796-pp", - .owner = THIS_MODULE, }, .probe = parport_ax88796_probe, .remove = parport_ax88796_remove, diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index f721299eb1ba..7ae20b7a56bc 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -3011,7 +3011,6 @@ static int parport_pc_platform_probe(struct platform_device *pdev) static struct platform_driver parport_pc_platform_driver = { .driver = { - .owner = THIS_MODULE, .name = "parport_pc", }, .probe = parport_pc_platform_probe, diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index dffd6d0bd15b..01cf1c1a841a 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -362,7 +362,6 @@ MODULE_DEVICE_TABLE(of, bpp_match); static struct platform_driver bpp_sbus_driver = { .driver = { .name = "bpp", - .owner = THIS_MODULE, .of_match_table = bpp_match, }, .probe = bpp_probe, -- GitLab From e27a5130ab647aec2a70b800a690736d5b258007 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:20 +0200 Subject: [PATCH 0774/9457] pci: host: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pci/host/pci-dra7xx.c | 1 - drivers/pci/host/pci-exynos.c | 1 - drivers/pci/host/pci-host-generic.c | 1 - drivers/pci/host/pci-imx6.c | 1 - drivers/pci/host/pci-keystone.c | 1 - drivers/pci/host/pci-mvebu.c | 1 - drivers/pci/host/pci-rcar-gen2.c | 1 - drivers/pci/host/pci-tegra.c | 1 - drivers/pci/host/pci-xgene.c | 1 - drivers/pci/host/pcie-rcar.c | 1 - drivers/pci/host/pcie-spear13xx.c | 1 - drivers/pci/host/pcie-xilinx.c | 1 - 12 files changed, 12 deletions(-) diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 52b34fee07fd..b7da6cf78070 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -446,7 +446,6 @@ static struct platform_driver dra7xx_pcie_driver = { .remove = __exit_p(dra7xx_pcie_remove), .driver = { .name = "dra7-pcie", - .owner = THIS_MODULE, .of_match_table = of_dra7xx_pcie_match, }, }; diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index c5d0ca384502..a95b20dbc3aa 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -649,7 +649,6 @@ static struct platform_driver exynos_pcie_driver = { .remove = __exit_p(exynos_pcie_remove), .driver = { .name = "exynos-pcie", - .owner = THIS_MODULE, .of_match_table = exynos_pcie_of_match, }, }; diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 3d2076f59911..f0577bd9483a 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c @@ -376,7 +376,6 @@ static int gen_pci_probe(struct platform_device *pdev) static struct platform_driver gen_pci_driver = { .driver = { .name = "pci-host-generic", - .owner = THIS_MODULE, .of_match_table = gen_pci_of_match, }, .probe = gen_pci_probe, diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 233fe8a88264..8855fef88e52 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -636,7 +636,6 @@ MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); static struct platform_driver imx6_pcie_driver = { .driver = { .name = "imx6q-pcie", - .owner = THIS_MODULE, .of_match_table = imx6_pcie_of_match, }, .shutdown = imx6_pcie_shutdown, diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 1b893bc8b842..8a2707885735 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c @@ -403,7 +403,6 @@ static struct platform_driver ks_pcie_driver __refdata = { .remove = __exit_p(ks_pcie_remove), .driver = { .name = "keystone-pcie", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ks_pcie_of_match), }, }; diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index b1315e197ffb..753cbf0f5b5e 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -1082,7 +1082,6 @@ MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); static struct platform_driver mvebu_pcie_driver = { .driver = { - .owner = THIS_MODULE, .name = "mvebu-pcie", .of_match_table = mvebu_pcie_of_match_table, /* driver unloading/unbinding currently not supported */ diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index 3ef854f5a5b5..d9c042febb1a 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c @@ -412,7 +412,6 @@ MODULE_DEVICE_TABLE(of, rcar_pci_of_match); static struct platform_driver rcar_pci_driver = { .driver = { .name = "pci-rcar-gen2", - .owner = THIS_MODULE, .suppress_bind_attrs = true, .of_match_table = rcar_pci_of_match, }, diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 3d43874319be..393cdb03ae59 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -2122,7 +2122,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) static struct platform_driver tegra_pcie_driver = { .driver = { .name = "tegra-pcie", - .owner = THIS_MODULE, .of_match_table = tegra_pcie_of_match, .suppress_bind_attrs = true, }, diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index 9ecabfa8c634..2439fe57d70c 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c @@ -647,7 +647,6 @@ static const struct of_device_id xgene_pcie_match_table[] = { static struct platform_driver xgene_pcie_driver = { .driver = { .name = "xgene-pcie", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(xgene_pcie_match_table), }, .probe = xgene_pcie_probe_bridge, diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 61158e03ab5f..9b356c32b192 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -988,7 +988,6 @@ static int rcar_pcie_probe(struct platform_device *pdev) static struct platform_driver rcar_pcie_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = rcar_pcie_of_match, .suppress_bind_attrs = true, }, diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 85f594e1708f..6826e0031381 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -375,7 +375,6 @@ static struct platform_driver spear13xx_pcie_driver __initdata = { .probe = spear13xx_pcie_probe, .driver = { .name = "spear-pcie", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spear13xx_pcie_of_match), }, }; diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index ccc496b33a97..56979ac36be2 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -956,7 +956,6 @@ static struct of_device_id xilinx_pcie_of_match[] = { static struct platform_driver xilinx_pcie_driver = { .driver = { .name = "xilinx-pcie", - .owner = THIS_MODULE, .of_match_table = xilinx_pcie_of_match, .suppress_bind_attrs = true, }, -- GitLab From 735fc3ec3434dd71c3846766a857812571c79925 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:21 +0200 Subject: [PATCH 0775/9457] pcmcia: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pcmcia/at91_cf.c | 1 - drivers/pcmcia/bfin_cf_pcmcia.c | 1 - drivers/pcmcia/db1xxx_ss.c | 1 - drivers/pcmcia/electra_cf.c | 1 - drivers/pcmcia/i82365.c | 1 - drivers/pcmcia/m32r_cfc.c | 1 - drivers/pcmcia/m32r_pcc.c | 1 - drivers/pcmcia/omap_cf.c | 1 - drivers/pcmcia/pxa2xx_base.c | 1 - drivers/pcmcia/pxa2xx_viper.c | 1 - drivers/pcmcia/sa1100_generic.c | 1 - drivers/pcmcia/tcic.c | 1 - drivers/pcmcia/vrc4171_card.c | 1 - drivers/pcmcia/xxs1500_ss.c | 1 - 14 files changed, 14 deletions(-) diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index de24232c5191..bfb799c7b343 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -401,7 +401,6 @@ static int at91_cf_resume(struct platform_device *pdev) static struct platform_driver at91_cf_driver = { .driver = { .name = "at91_cf", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91_cf_dt_ids), }, .probe = at91_cf_probe, diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 971991bab975..bba1dcbb8075 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -304,7 +304,6 @@ static int bfin_cf_remove(struct platform_device *pdev) static struct platform_driver bfin_cf_driver = { .driver = { .name = driver_name, - .owner = THIS_MODULE, }, .probe = bfin_cf_probe, .remove = bfin_cf_remove, diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index a31e69ea99f3..4c2fa05b4589 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -574,7 +574,6 @@ static int db1x_pcmcia_socket_remove(struct platform_device *pdev) static struct platform_driver db1x_pcmcia_socket_driver = { .driver = { .name = "db1xxx_pcmcia", - .owner = THIS_MODULE, }, .probe = db1x_pcmcia_socket_probe, .remove = db1x_pcmcia_socket_remove, diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 5ea64d0f61ab..7f9950d324df 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -360,7 +360,6 @@ MODULE_DEVICE_TABLE(of, electra_cf_match); static struct platform_driver electra_cf_driver = { .driver = { .name = driver_name, - .owner = THIS_MODULE, .of_match_table = electra_cf_match, }, .probe = electra_cf_probe, diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index e6f3d17dd2b4..a2c138719bac 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1233,7 +1233,6 @@ static struct pccard_operations pcic_operations = { static struct platform_driver i82365_driver = { .driver = { .name = "i82365", - .owner = THIS_MODULE, }, }; diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index a26f38c6402a..0075bd7162ed 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -687,7 +687,6 @@ static struct pccard_operations pcc_operations = { static struct platform_driver pcc_driver = { .driver = { .name = "cfc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 296514155cd5..a77e571b08b8 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -664,7 +664,6 @@ static struct pccard_operations pcc_operations = { static struct platform_driver pcc_driver = { .driver = { .name = "pcc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 25c4b1993b3d..8170102d1e93 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -334,7 +334,6 @@ static int __exit omap_cf_remove(struct platform_device *pdev) static struct platform_driver omap_cf_driver = { .driver = { .name = (char *) driver_name, - .owner = THIS_MODULE, }, .remove = __exit_p(omap_cf_remove), }; diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index cfec9dd18ff5..984a8ff559d8 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -368,7 +368,6 @@ static struct platform_driver pxa2xx_pcmcia_driver = { .remove = pxa2xx_drv_pcmcia_remove, .driver = { .name = "pxa2xx-pcmcia", - .owner = THIS_MODULE, .pm = &pxa2xx_drv_pcmcia_pm_ops, }, }; diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index a76f495953ab..7ac6647d286e 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c @@ -172,7 +172,6 @@ static struct platform_driver viper_pcmcia_driver = { .remove = viper_pcmcia_remove, .driver = { .name = "arcom-pcmcia", - .owner = THIS_MODULE, }, .id_table = viper_pcmcia_id_table, }; diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index ff8a027a4afb..42861cc70158 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -100,7 +100,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) static struct platform_driver sa11x0_pcmcia_driver = { .driver = { .name = "sa11x0-pcmcia", - .owner = THIS_MODULE, }, .probe = sa11x0_drv_pcmcia_probe, .remove = sa11x0_drv_pcmcia_remove, diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index cbe15fc37411..1ee63e5f0550 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -349,7 +349,6 @@ static int __init get_tcic_id(void) static struct platform_driver tcic_driver = { .driver = { .name = "tcic-pcmcia", - .owner = THIS_MODULE, }, }; diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index d98a08612492..21973d55a055 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -709,7 +709,6 @@ __setup("vrc4171_card=", vrc4171_card_setup); static struct platform_driver vrc4171_card_driver = { .driver = { .name = vrc4171_card_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index 95f5b270ad44..4c04360f378b 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -314,7 +314,6 @@ static int xxs1500_pcmcia_remove(struct platform_device *pdev) static struct platform_driver xxs1500_pcmcia_socket_driver = { .driver = { .name = "xxs1500_pcmcia", - .owner = THIS_MODULE, }, .probe = xxs1500_pcmcia_probe, .remove = xxs1500_pcmcia_remove, -- GitLab From 5c759d73b0228901d0e05e5f02402fb35f5d2263 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:21 +0200 Subject: [PATCH 0776/9457] pinctrl: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/pinctrl-as3722.c | 1 - drivers/pinctrl/pinctrl-at91.c | 2 -- drivers/pinctrl/pinctrl-baytrail.c | 1 - drivers/pinctrl/pinctrl-bcm281xx.c | 1 - drivers/pinctrl/pinctrl-bcm2835.c | 1 - drivers/pinctrl/pinctrl-falcon.c | 1 - drivers/pinctrl/pinctrl-palmas.c | 1 - drivers/pinctrl/pinctrl-rockchip.c | 1 - drivers/pinctrl/pinctrl-single.c | 1 - drivers/pinctrl/pinctrl-st.c | 1 - drivers/pinctrl/pinctrl-tb10x.c | 1 - drivers/pinctrl/pinctrl-tegra114.c | 1 - drivers/pinctrl/pinctrl-tegra124.c | 1 - drivers/pinctrl/pinctrl-tegra20.c | 1 - drivers/pinctrl/pinctrl-tegra30.c | 1 - drivers/pinctrl/pinctrl-tz1090-pdc.c | 1 - drivers/pinctrl/pinctrl-tz1090.c | 1 - drivers/pinctrl/pinctrl-u300.c | 1 - drivers/pinctrl/pinctrl-xway.c | 1 - 19 files changed, 20 deletions(-) diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c index 1f790a4b83fe..169b1bfa00c8 100644 --- a/drivers/pinctrl/pinctrl-as3722.c +++ b/drivers/pinctrl/pinctrl-as3722.c @@ -634,7 +634,6 @@ MODULE_DEVICE_TABLE(of, as3722_pinctrl_of_match); static struct platform_driver as3722_pinctrl_driver = { .driver = { .name = "as3722-pinctrl", - .owner = THIS_MODULE, .of_match_table = as3722_pinctrl_of_match, }, .probe = as3722_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 354a81d40925..654b36517f96 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1832,7 +1832,6 @@ static int at91_gpio_probe(struct platform_device *pdev) static struct platform_driver at91_gpio_driver = { .driver = { .name = "gpio-at91", - .owner = THIS_MODULE, .of_match_table = at91_gpio_of_match, }, .probe = at91_gpio_probe, @@ -1841,7 +1840,6 @@ static struct platform_driver at91_gpio_driver = { static struct platform_driver at91_pinctrl_driver = { .driver = { .name = "pinctrl-at91", - .owner = THIS_MODULE, .of_match_table = at91_pinctrl_of_match, }, .probe = at91_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index e12e5b07f6d7..e0d3ca2fab8f 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -602,7 +602,6 @@ static struct platform_driver byt_gpio_driver = { .remove = byt_gpio_remove, .driver = { .name = "byt_gpio", - .owner = THIS_MODULE, .pm = &byt_gpio_pm_ops, .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), }, diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c index a26e0c2ba33e..1db69857de09 100644 --- a/drivers/pinctrl/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/pinctrl-bcm281xx.c @@ -1448,7 +1448,6 @@ static struct of_device_id bcm281xx_pinctrl_of_match[] = { static struct platform_driver bcm281xx_pinctrl_driver = { .driver = { .name = "bcm281xx-pinctrl", - .owner = THIS_MODULE, .of_match_table = bcm281xx_pinctrl_of_match, }, }; diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index eabba02f71f9..9aa8a3f10b10 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c @@ -1062,7 +1062,6 @@ static struct platform_driver bcm2835_pinctrl_driver = { .remove = bcm2835_pinctrl_remove, .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, .of_match_table = bcm2835_pinctrl_match, }, }; diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c index 2e62689b5e9f..1d21dc226920 100644 --- a/drivers/pinctrl/pinctrl-falcon.c +++ b/drivers/pinctrl/pinctrl-falcon.c @@ -500,7 +500,6 @@ static struct platform_driver pinctrl_falcon_driver = { .probe = pinctrl_falcon_probe, .driver = { .name = "pinctrl-falcon", - .owner = THIS_MODULE, .of_match_table = falcon_match, }, }; diff --git a/drivers/pinctrl/pinctrl-palmas.c b/drivers/pinctrl/pinctrl-palmas.c index e3079d3d19fe..26461e30f0ae 100644 --- a/drivers/pinctrl/pinctrl-palmas.c +++ b/drivers/pinctrl/pinctrl-palmas.c @@ -1062,7 +1062,6 @@ static int palmas_pinctrl_remove(struct platform_device *pdev) static struct platform_driver palmas_pinctrl_driver = { .driver = { .name = "palmas-pinctrl", - .owner = THIS_MODULE, .of_match_table = palmas_pinctrl_of_match, }, .probe = palmas_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 016f4578e494..71d5835d864b 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1982,7 +1982,6 @@ static struct platform_driver rockchip_pinctrl_driver = { .probe = rockchip_pinctrl_probe, .driver = { .name = "rockchip-pinctrl", - .owner = THIS_MODULE, .of_match_table = rockchip_pinctrl_dt_match, }, }; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index fb94b772ad62..69e84427f913 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -2016,7 +2016,6 @@ static struct platform_driver pcs_driver = { .probe = pcs_probe, .remove = pcs_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = pcs_of_match, }, diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 4b1792aad3d8..a23e8729a473 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1689,7 +1689,6 @@ static int st_pctl_probe(struct platform_device *pdev) static struct platform_driver st_pctl_driver = { .driver = { .name = "st-pinctrl", - .owner = THIS_MODULE, .of_match_table = st_pctl_of_match, }, .probe = st_pctl_probe, diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 3b9bfcf717ac..6474bbd936f7 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -847,7 +847,6 @@ static struct platform_driver tb10x_pinctrl_pdrv = { .driver = { .name = "tb10x_pinctrl", .of_match_table = of_match_ptr(tb10x_pinctrl_dt_ids), - .owner = THIS_MODULE } }; diff --git a/drivers/pinctrl/pinctrl-tegra114.c b/drivers/pinctrl/pinctrl-tegra114.c index a3db85b0b75f..52e4ec6386b4 100644 --- a/drivers/pinctrl/pinctrl-tegra114.c +++ b/drivers/pinctrl/pinctrl-tegra114.c @@ -1859,7 +1859,6 @@ MODULE_DEVICE_TABLE(of, tegra114_pinctrl_of_match); static struct platform_driver tegra114_pinctrl_driver = { .driver = { .name = "tegra114-pinctrl", - .owner = THIS_MODULE, .of_match_table = tegra114_pinctrl_of_match, }, .probe = tegra114_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-tegra124.c b/drivers/pinctrl/pinctrl-tegra124.c index 2f9b75c14967..2b20906c5356 100644 --- a/drivers/pinctrl/pinctrl-tegra124.c +++ b/drivers/pinctrl/pinctrl-tegra124.c @@ -2072,7 +2072,6 @@ MODULE_DEVICE_TABLE(of, tegra124_pinctrl_of_match); static struct platform_driver tegra124_pinctrl_driver = { .driver = { .name = "tegra124-pinctrl", - .owner = THIS_MODULE, .of_match_table = tegra124_pinctrl_of_match, }, .probe = tegra124_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c index c9805d2e71b0..d3a5722e4acb 100644 --- a/drivers/pinctrl/pinctrl-tegra20.c +++ b/drivers/pinctrl/pinctrl-tegra20.c @@ -2236,7 +2236,6 @@ static const struct of_device_id tegra20_pinctrl_of_match[] = { static struct platform_driver tegra20_pinctrl_driver = { .driver = { .name = "tegra20-pinctrl", - .owner = THIS_MODULE, .of_match_table = tegra20_pinctrl_of_match, }, .probe = tegra20_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index e7b72e916558..f6edc2ff5494 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -2493,7 +2493,6 @@ MODULE_DEVICE_TABLE(of, tegra30_pinctrl_of_match); static struct platform_driver tegra30_pinctrl_driver = { .driver = { .name = "tegra30-pinctrl", - .owner = THIS_MODULE, .of_match_table = tegra30_pinctrl_of_match, }, .probe = tegra30_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-tz1090-pdc.c b/drivers/pinctrl/pinctrl-tz1090-pdc.c index 3bb6a3b78864..146e48a9b839 100644 --- a/drivers/pinctrl/pinctrl-tz1090-pdc.c +++ b/drivers/pinctrl/pinctrl-tz1090-pdc.c @@ -977,7 +977,6 @@ static struct of_device_id tz1090_pdc_pinctrl_of_match[] = { static struct platform_driver tz1090_pdc_pinctrl_driver = { .driver = { .name = "tz1090-pdc-pinctrl", - .owner = THIS_MODULE, .of_match_table = tz1090_pdc_pinctrl_of_match, }, .probe = tz1090_pdc_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c index 48d36413b99f..df8cb1e5b7b4 100644 --- a/drivers/pinctrl/pinctrl-tz1090.c +++ b/drivers/pinctrl/pinctrl-tz1090.c @@ -1992,7 +1992,6 @@ static struct of_device_id tz1090_pinctrl_of_match[] = { static struct platform_driver tz1090_pinctrl_driver = { .driver = { .name = "tz1090-pinctrl", - .owner = THIS_MODULE, .of_match_table = tz1090_pinctrl_of_match, }, .probe = tz1090_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index e9c7113d81f2..f931e65aba3a 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -1098,7 +1098,6 @@ static const struct of_device_id u300_pinctrl_match[] = { static struct platform_driver u300_pmx_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = u300_pinctrl_match, }, .probe = u300_pmx_probe, diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index 37040ab42890..c5cef59f5965 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -840,7 +840,6 @@ static struct platform_driver pinmux_xway_driver = { .probe = pinmux_xway_probe, .driver = { .name = "pinctrl-xway", - .owner = THIS_MODULE, .of_match_table = xway_match, }, }; -- GitLab From 4c992fe5c1fdb699b37172b79bc0a5f0f2825332 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:21 +0200 Subject: [PATCH 0777/9457] pinctrl: berlin: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/berlin/berlin-bg2.c | 1 - drivers/pinctrl/berlin/berlin-bg2cd.c | 1 - drivers/pinctrl/berlin/berlin-bg2q.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/pinctrl/berlin/berlin-bg2.c b/drivers/pinctrl/berlin/berlin-bg2.c index dcd4f6a4fc50..b71a6fffef1b 100644 --- a/drivers/pinctrl/berlin/berlin-bg2.c +++ b/drivers/pinctrl/berlin/berlin-bg2.c @@ -263,7 +263,6 @@ static struct platform_driver berlin2_pinctrl_driver = { .probe = berlin2_pinctrl_probe, .driver = { .name = "berlin-bg2-pinctrl", - .owner = THIS_MODULE, .of_match_table = berlin2_pinctrl_match, }, }; diff --git a/drivers/pinctrl/berlin/berlin-bg2cd.c b/drivers/pinctrl/berlin/berlin-bg2cd.c index 89d585ef7da7..19ac5a22c947 100644 --- a/drivers/pinctrl/berlin/berlin-bg2cd.c +++ b/drivers/pinctrl/berlin/berlin-bg2cd.c @@ -206,7 +206,6 @@ static struct platform_driver berlin2cd_pinctrl_driver = { .probe = berlin2cd_pinctrl_probe, .driver = { .name = "berlin-bg2cd-pinctrl", - .owner = THIS_MODULE, .of_match_table = berlin2cd_pinctrl_match, }, }; diff --git a/drivers/pinctrl/berlin/berlin-bg2q.c b/drivers/pinctrl/berlin/berlin-bg2q.c index 9fcf9836045c..bd9662e57ad3 100644 --- a/drivers/pinctrl/berlin/berlin-bg2q.c +++ b/drivers/pinctrl/berlin/berlin-bg2q.c @@ -425,7 +425,6 @@ static struct platform_driver berlin2q_pinctrl_driver = { .probe = berlin2q_pinctrl_probe, .driver = { .name = "berlin-bg2q-pinctrl", - .owner = THIS_MODULE, .of_match_table = berlin2q_pinctrl_match, }, }; -- GitLab From c61b301d3b1a9b2f40b2c3f03e78821c1d68b511 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:22 +0200 Subject: [PATCH 0778/9457] pinctrl: freescale: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/freescale/pinctrl-imx1.c | 1 - drivers/pinctrl/freescale/pinctrl-imx21.c | 1 - drivers/pinctrl/freescale/pinctrl-imx23.c | 1 - drivers/pinctrl/freescale/pinctrl-imx25.c | 1 - drivers/pinctrl/freescale/pinctrl-imx27.c | 1 - drivers/pinctrl/freescale/pinctrl-imx28.c | 1 - drivers/pinctrl/freescale/pinctrl-imx35.c | 1 - drivers/pinctrl/freescale/pinctrl-imx50.c | 1 - drivers/pinctrl/freescale/pinctrl-imx51.c | 1 - drivers/pinctrl/freescale/pinctrl-imx53.c | 1 - drivers/pinctrl/freescale/pinctrl-imx6dl.c | 1 - drivers/pinctrl/freescale/pinctrl-imx6q.c | 1 - drivers/pinctrl/freescale/pinctrl-imx6sl.c | 1 - drivers/pinctrl/freescale/pinctrl-imx6sx.c | 1 - drivers/pinctrl/freescale/pinctrl-vf610.c | 1 - 15 files changed, 15 deletions(-) diff --git a/drivers/pinctrl/freescale/pinctrl-imx1.c b/drivers/pinctrl/freescale/pinctrl-imx1.c index 533a6e519648..d3bacb7d6d37 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1.c @@ -267,7 +267,6 @@ MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match); static struct platform_driver imx1_pinctrl_driver = { .driver = { .name = "imx1-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx1_pinctrl_of_match, }, .remove = imx1_pinctrl_core_remove, diff --git a/drivers/pinctrl/freescale/pinctrl-imx21.c b/drivers/pinctrl/freescale/pinctrl-imx21.c index 1b3b2311b033..9d9aca3dbd7e 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx21.c +++ b/drivers/pinctrl/freescale/pinctrl-imx21.c @@ -330,7 +330,6 @@ MODULE_DEVICE_TABLE(of, imx21_pinctrl_of_match); static struct platform_driver imx21_pinctrl_driver = { .driver = { .name = "imx21-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx21_pinctrl_of_match, }, .remove = imx1_pinctrl_core_remove, diff --git a/drivers/pinctrl/freescale/pinctrl-imx23.c b/drivers/pinctrl/freescale/pinctrl-imx23.c index df79096becb0..955cbf4f094f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx23.c +++ b/drivers/pinctrl/freescale/pinctrl-imx23.c @@ -281,7 +281,6 @@ MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match); static struct platform_driver imx23_pinctrl_driver = { .driver = { .name = "imx23-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx23_pinctrl_of_match, }, .probe = imx23_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx25.c b/drivers/pinctrl/freescale/pinctrl-imx25.c index 550e6d77ac2b..8d1013a040c9 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx25.c +++ b/drivers/pinctrl/freescale/pinctrl-imx25.c @@ -328,7 +328,6 @@ static int imx25_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx25_pinctrl_driver = { .driver = { .name = "imx25-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(imx25_pinctrl_of_match), }, .probe = imx25_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx27.c b/drivers/pinctrl/freescale/pinctrl-imx27.c index 945eccadea74..a461d5881f37 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx27.c +++ b/drivers/pinctrl/freescale/pinctrl-imx27.c @@ -402,7 +402,6 @@ static int imx27_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx27_pinctrl_driver = { .driver = { .name = "imx27-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(imx27_pinctrl_of_match), }, .probe = imx27_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx28.c b/drivers/pinctrl/freescale/pinctrl-imx28.c index 3bd45da21229..5082efec4f72 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx28.c +++ b/drivers/pinctrl/freescale/pinctrl-imx28.c @@ -397,7 +397,6 @@ MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match); static struct platform_driver imx28_pinctrl_driver = { .driver = { .name = "imx28-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx28_pinctrl_of_match, }, .probe = imx28_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx35.c b/drivers/pinctrl/freescale/pinctrl-imx35.c index 6bfbcd0112c1..9109c10c5dab 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx35.c +++ b/drivers/pinctrl/freescale/pinctrl-imx35.c @@ -1018,7 +1018,6 @@ static int imx35_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx35_pinctrl_driver = { .driver = { .name = "imx35-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx35_pinctrl_of_match, }, .probe = imx35_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx50.c b/drivers/pinctrl/freescale/pinctrl-imx50.c index e8bd604ab147..51b31df96273 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx50.c +++ b/drivers/pinctrl/freescale/pinctrl-imx50.c @@ -404,7 +404,6 @@ static int imx50_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx50_pinctrl_driver = { .driver = { .name = "imx50-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(imx50_pinctrl_of_match), }, .probe = imx50_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx51.c b/drivers/pinctrl/freescale/pinctrl-imx51.c index b818051db7c9..8dec494aa2c6 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx51.c +++ b/drivers/pinctrl/freescale/pinctrl-imx51.c @@ -781,7 +781,6 @@ static int imx51_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx51_pinctrl_driver = { .driver = { .name = "imx51-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx51_pinctrl_of_match, }, .probe = imx51_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx53.c b/drivers/pinctrl/freescale/pinctrl-imx53.c index 1884d53cf750..7344d340013c 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx53.c +++ b/drivers/pinctrl/freescale/pinctrl-imx53.c @@ -467,7 +467,6 @@ static int imx53_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx53_pinctrl_driver = { .driver = { .name = "imx53-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx53_pinctrl_of_match, }, .probe = imx53_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx6dl.c b/drivers/pinctrl/freescale/pinctrl-imx6dl.c index 656c4b08cc2e..6805c678c3b2 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6dl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6dl.c @@ -473,7 +473,6 @@ static int imx6dl_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6dl_pinctrl_driver = { .driver = { .name = "imx6dl-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx6dl_pinctrl_of_match, }, .probe = imx6dl_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx6q.c b/drivers/pinctrl/freescale/pinctrl-imx6q.c index 59bb5b4ec0f6..4d1fcb861ac1 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6q.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6q.c @@ -479,7 +479,6 @@ static int imx6q_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6q_pinctrl_driver = { .driver = { .name = "imx6q-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx6q_pinctrl_of_match, }, .probe = imx6q_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sl.c b/drivers/pinctrl/freescale/pinctrl-imx6sl.c index e0924bd7b98c..83fa5f19ae89 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sl.c @@ -380,7 +380,6 @@ static int imx6sl_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6sl_pinctrl_driver = { .driver = { .name = "imx6sl-pinctrl", - .owner = THIS_MODULE, .of_match_table = imx6sl_pinctrl_of_match, }, .probe = imx6sl_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sx.c b/drivers/pinctrl/freescale/pinctrl-imx6sx.c index 840344c8580d..0d78fe690818 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sx.c @@ -383,7 +383,6 @@ static int imx6sx_pinctrl_probe(struct platform_device *pdev) static struct platform_driver imx6sx_pinctrl_driver = { .driver = { .name = "imx6sx-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(imx6sx_pinctrl_of_match), }, .probe = imx6sx_pinctrl_probe, diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c index b788e1578954..fc86276892fd 100644 --- a/drivers/pinctrl/freescale/pinctrl-vf610.c +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c @@ -315,7 +315,6 @@ static int vf610_pinctrl_probe(struct platform_device *pdev) static struct platform_driver vf610_pinctrl_driver = { .driver = { .name = "vf610-pinctrl", - .owner = THIS_MODULE, .of_match_table = vf610_pinctrl_of_match, }, .probe = vf610_pinctrl_probe, -- GitLab From 1d57fb12e612d65c1e7463d1d193869d3d9edbb1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:22 +0200 Subject: [PATCH 0779/9457] pinctrl: mvebu: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/mvebu/pinctrl-armada-370.c | 1 - drivers/pinctrl/mvebu/pinctrl-armada-375.c | 1 - drivers/pinctrl/mvebu/pinctrl-armada-38x.c | 1 - drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 1 - drivers/pinctrl/mvebu/pinctrl-dove.c | 1 - drivers/pinctrl/mvebu/pinctrl-kirkwood.c | 1 - drivers/pinctrl/mvebu/pinctrl-orion.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index 670e5b01c678..c4f51d0cd2cc 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c @@ -425,7 +425,6 @@ static int armada_370_pinctrl_remove(struct platform_device *pdev) static struct platform_driver armada_370_pinctrl_driver = { .driver = { .name = "armada-370-pinctrl", - .owner = THIS_MODULE, .of_match_table = armada_370_pinctrl_of_match, }, .probe = armada_370_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-375.c b/drivers/pinctrl/mvebu/pinctrl-armada-375.c index db078fe7ace6..cd7c8f51f7d9 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-375.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-375.c @@ -445,7 +445,6 @@ static int armada_375_pinctrl_remove(struct platform_device *pdev) static struct platform_driver armada_375_pinctrl_driver = { .driver = { .name = "armada-375-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(armada_375_pinctrl_of_match), }, .probe = armada_375_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c index 1049f82fb62f..224c6cff6aa2 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c @@ -448,7 +448,6 @@ static int armada_38x_pinctrl_remove(struct platform_device *pdev) static struct platform_driver armada_38x_pinctrl_driver = { .driver = { .name = "armada-38x-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(armada_38x_pinctrl_of_match), }, .probe = armada_38x_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index de311129f7a0..fc3376147c18 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -472,7 +472,6 @@ static int armada_xp_pinctrl_remove(struct platform_device *pdev) static struct platform_driver armada_xp_pinctrl_driver = { .driver = { .name = "armada-xp-pinctrl", - .owner = THIS_MODULE, .of_match_table = armada_xp_pinctrl_of_match, }, .probe = armada_xp_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index 3b022178a566..89a52e15f0ae 100644 --- a/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -851,7 +851,6 @@ static int dove_pinctrl_remove(struct platform_device *pdev) static struct platform_driver dove_pinctrl_driver = { .driver = { .name = "dove-pinctrl", - .owner = THIS_MODULE, .of_match_table = dove_pinctrl_of_match, }, .probe = dove_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c index 0d0211a1a0b0..dbc673cf7131 100644 --- a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c @@ -489,7 +489,6 @@ static int kirkwood_pinctrl_remove(struct platform_device *pdev) static struct platform_driver kirkwood_pinctrl_driver = { .driver = { .name = "kirkwood-pinctrl", - .owner = THIS_MODULE, .of_match_table = kirkwood_pinctrl_of_match, }, .probe = kirkwood_pinctrl_probe, diff --git a/drivers/pinctrl/mvebu/pinctrl-orion.c b/drivers/pinctrl/mvebu/pinctrl-orion.c index dda1e7254e15..3a632efb56bb 100644 --- a/drivers/pinctrl/mvebu/pinctrl-orion.c +++ b/drivers/pinctrl/mvebu/pinctrl-orion.c @@ -247,7 +247,6 @@ static int orion_pinctrl_remove(struct platform_device *pdev) static struct platform_driver orion_pinctrl_driver = { .driver = { .name = "orion-pinctrl", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(orion_pinctrl_of_match), }, .probe = orion_pinctrl_probe, -- GitLab From 87b5067322b2b1ecde970e88694867a776443ff7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:23 +0200 Subject: [PATCH 0780/9457] pinctrl: nomadik: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/nomadik/pinctrl-abx500.c | 1 - drivers/pinctrl/nomadik/pinctrl-nomadik.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 228972827132..37af8fb15c71 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -1285,7 +1285,6 @@ static int abx500_gpio_remove(struct platform_device *pdev) static struct platform_driver abx500_gpio_driver = { .driver = { .name = "abx500-gpio", - .owner = THIS_MODULE, .of_match_table = abx500_gpio_match, }, .probe = abx500_gpio_probe, diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 746db6acf648..97a7724dcdf8 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -2047,7 +2047,6 @@ static const struct of_device_id nmk_gpio_match[] = { static struct platform_driver nmk_gpio_driver = { .driver = { - .owner = THIS_MODULE, .name = "gpio", .of_match_table = nmk_gpio_match, }, @@ -2060,7 +2059,6 @@ static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops, static struct platform_driver nmk_pinctrl_driver = { .driver = { - .owner = THIS_MODULE, .name = "pinctrl-nomadik", .of_match_table = nmk_pinctrl_match, .pm = &nmk_pinctrl_pm_ops, -- GitLab From bdac6d4a08a4d93b9de6beabf653b8b45300e8ce Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:23 +0200 Subject: [PATCH 0781/9457] pinctrl: qcom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/qcom/pinctrl-apq8064.c | 1 - drivers/pinctrl/qcom/pinctrl-apq8084.c | 1 - drivers/pinctrl/qcom/pinctrl-ipq8064.c | 1 - drivers/pinctrl/qcom/pinctrl-msm8960.c | 1 - drivers/pinctrl/qcom/pinctrl-msm8x74.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c index c832d7d6b912..cd96699b1929 100644 --- a/drivers/pinctrl/qcom/pinctrl-apq8064.c +++ b/drivers/pinctrl/qcom/pinctrl-apq8064.c @@ -612,7 +612,6 @@ static const struct of_device_id apq8064_pinctrl_of_match[] = { static struct platform_driver apq8064_pinctrl_driver = { .driver = { .name = "apq8064-pinctrl", - .owner = THIS_MODULE, .of_match_table = apq8064_pinctrl_of_match, }, .probe = apq8064_pinctrl_probe, diff --git a/drivers/pinctrl/qcom/pinctrl-apq8084.c b/drivers/pinctrl/qcom/pinctrl-apq8084.c index 138cbf6134a5..d07e8df43b90 100644 --- a/drivers/pinctrl/qcom/pinctrl-apq8084.c +++ b/drivers/pinctrl/qcom/pinctrl-apq8084.c @@ -1221,7 +1221,6 @@ static const struct of_device_id apq8084_pinctrl_of_match[] = { static struct platform_driver apq8084_pinctrl_driver = { .driver = { .name = "apq8084-pinctrl", - .owner = THIS_MODULE, .of_match_table = apq8084_pinctrl_of_match, }, .probe = apq8084_pinctrl_probe, diff --git a/drivers/pinctrl/qcom/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c index 81f49a9b4dbe..bcb29c02f4b0 100644 --- a/drivers/pinctrl/qcom/pinctrl-ipq8064.c +++ b/drivers/pinctrl/qcom/pinctrl-ipq8064.c @@ -645,7 +645,6 @@ static const struct of_device_id ipq8064_pinctrl_of_match[] = { static struct platform_driver ipq8064_pinctrl_driver = { .driver = { .name = "ipq8064-pinctrl", - .owner = THIS_MODULE, .of_match_table = ipq8064_pinctrl_of_match, }, .probe = ipq8064_pinctrl_probe, diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c index 2ab21ce5575a..ed23e367fe89 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8960.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c @@ -1259,7 +1259,6 @@ static const struct of_device_id msm8960_pinctrl_of_match[] = { static struct platform_driver msm8960_pinctrl_driver = { .driver = { .name = "msm8960-pinctrl", - .owner = THIS_MODULE, .of_match_table = msm8960_pinctrl_of_match, }, .probe = msm8960_pinctrl_probe, diff --git a/drivers/pinctrl/qcom/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c index 3c858384d041..46fe6ad5f97e 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8x74.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c @@ -1043,7 +1043,6 @@ static const struct of_device_id msm8x74_pinctrl_of_match[] = { static struct platform_driver msm8x74_pinctrl_driver = { .driver = { .name = "msm8x74-pinctrl", - .owner = THIS_MODULE, .of_match_table = msm8x74_pinctrl_of_match, }, .probe = msm8x74_pinctrl_probe, -- GitLab From 2604b832b577115122d0da9ccd6dd3baef1136e6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:24 +0200 Subject: [PATCH 0782/9457] pinctrl: samsung: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/samsung/pinctrl-exynos5440.c | 1 - drivers/pinctrl/samsung/pinctrl-samsung.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c index 88acfc0efd54..86192be3b679 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos5440.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c @@ -1036,7 +1036,6 @@ static struct platform_driver exynos5440_pinctrl_driver = { .probe = exynos5440_pinctrl_probe, .driver = { .name = "exynos5440-pinctrl", - .owner = THIS_MODULE, .of_match_table = exynos5440_pinctrl_dt_match, }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 2d37c8f49f3c..2fd05e2c2ce6 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1249,7 +1249,6 @@ static struct platform_driver samsung_pinctrl_driver = { .probe = samsung_pinctrl_probe, .driver = { .name = "samsung-pinctrl", - .owner = THIS_MODULE, .of_match_table = samsung_pinctrl_dt_match, }, }; -- GitLab From 569c65c08a7ed67019683950409a6c10243711f5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:24 +0200 Subject: [PATCH 0783/9457] pinctrl: sh-pfc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/sh-pfc/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 6572c233f73d..66dc62d2156c 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -650,7 +650,6 @@ static struct platform_driver sh_pfc_driver = { .id_table = sh_pfc_id_table, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(sh_pfc_of_table), }, }; -- GitLab From 66d0f85f1003ae0eafd5e225bc06c71f5366418e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:24 +0200 Subject: [PATCH 0784/9457] pinctrl: sirf: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/sirf/pinctrl-sirf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index 4c831fdfcc2f..4871647c7f85 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c @@ -406,7 +406,6 @@ static const struct dev_pm_ops sirfsoc_pinmux_pm_ops = { static struct platform_driver sirfsoc_pinmux_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = pinmux_ids, #ifdef CONFIG_PM_SLEEP .pm = &sirfsoc_pinmux_pm_ops, -- GitLab From 5a9a1e8437c865b29f0807ce861a224a95d3121e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:25 +0200 Subject: [PATCH 0785/9457] pinctrl: spear: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/spear/pinctrl-plgpio.c | 1 - drivers/pinctrl/spear/pinctrl-spear1310.c | 1 - drivers/pinctrl/spear/pinctrl-spear1340.c | 1 - drivers/pinctrl/spear/pinctrl-spear300.c | 1 - drivers/pinctrl/spear/pinctrl-spear310.c | 1 - drivers/pinctrl/spear/pinctrl-spear320.c | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index bddb79105d67..59a6b6bcfae4 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -710,7 +710,6 @@ MODULE_DEVICE_TABLE(of, plgpio_of_match); static struct platform_driver plgpio_driver = { .probe = plgpio_probe, .driver = { - .owner = THIS_MODULE, .name = "spear-plgpio", .pm = &plgpio_dev_pm_ops, .of_match_table = plgpio_of_match, diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index 6d57d43ab640..a7bdc537efa7 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2712,7 +2712,6 @@ static int spear1310_pinctrl_remove(struct platform_device *pdev) static struct platform_driver spear1310_pinctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spear1310_pinctrl_of_match, }, .probe = spear1310_pinctrl_probe, diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index d243e43e7f6d..f43ec85a0328 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2028,7 +2028,6 @@ static int spear1340_pinctrl_remove(struct platform_device *pdev) static struct platform_driver spear1340_pinctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spear1340_pinctrl_of_match, }, .probe = spear1340_pinctrl_probe, diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 9db83e9ee18c..da8990a8eeef 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -685,7 +685,6 @@ static int spear300_pinctrl_remove(struct platform_device *pdev) static struct platform_driver spear300_pinctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spear300_pinctrl_of_match, }, .probe = spear300_pinctrl_probe, diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index db775a414b7a..31ede51e819b 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -408,7 +408,6 @@ static int spear310_pinctrl_remove(struct platform_device *pdev) static struct platform_driver spear310_pinctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spear310_pinctrl_of_match, }, .probe = spear310_pinctrl_probe, diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index 80fbd68e17bc..506e40b641e0 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -3449,7 +3449,6 @@ static int spear320_pinctrl_remove(struct platform_device *pdev) static struct platform_driver spear320_pinctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spear320_pinctrl_of_match, }, .probe = spear320_pinctrl_probe, -- GitLab From 75bb55b8014e06737f49d5abd837f006a5ac965b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:25 +0200 Subject: [PATCH 0786/9457] pinctrl: sunxi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c | 1 - drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c | 1 - 8 files changed, 8 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c index 86b608bedca6..24c5d88f943f 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c @@ -1029,7 +1029,6 @@ static struct platform_driver sun4i_a10_pinctrl_driver = { .probe = sun4i_a10_pinctrl_probe, .driver = { .name = "sun4i-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun4i_a10_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c index 2fa7430cabaf..45a351affa59 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c @@ -680,7 +680,6 @@ static struct platform_driver sun5i_a10s_pinctrl_driver = { .probe = sun5i_a10s_pinctrl_probe, .driver = { .name = "sun5i-a10s-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun5i_a10s_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c index e47c33dbae3a..4bd23471412c 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c @@ -398,7 +398,6 @@ static struct platform_driver sun5i_a13_pinctrl_driver = { .probe = sun5i_a13_pinctrl_probe, .driver = { .name = "sun5i-a13-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun5i_a13_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c index 9a2517b65113..02174fa57997 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c @@ -130,7 +130,6 @@ static struct platform_driver sun6i_a31_r_pinctrl_driver = { .probe = sun6i_a31_r_pinctrl_probe, .driver = { .name = "sun6i-a31-r-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun6i_a31_r_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c index a2b4b85c5ad5..f42858eaca28 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c @@ -927,7 +927,6 @@ static struct platform_driver sun6i_a31_pinctrl_driver = { .probe = sun6i_a31_pinctrl_probe, .driver = { .name = "sun6i-a31-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun6i_a31_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c index dac99e02bfdb..6af6cc8547b0 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c @@ -1055,7 +1055,6 @@ static struct platform_driver sun7i_a20_pinctrl_driver = { .probe = sun7i_a20_pinctrl_probe, .driver = { .name = "sun7i-a20-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun7i_a20_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c index 90f3b3a7c51e..327e03ff7c4d 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c @@ -129,7 +129,6 @@ static struct platform_driver sun8i_a23_r_pinctrl_driver = { .probe = sun8i_a23_r_pinctrl_probe, .driver = { .name = "sun8i-a23-r-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun8i_a23_r_pinctrl_match, }, }; diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c index ac71e8c5901b..62695c9a92c2 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c @@ -581,7 +581,6 @@ static struct platform_driver sun8i_a23_pinctrl_driver = { .probe = sun8i_a23_pinctrl_probe, .driver = { .name = "sun8i-a23-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun8i_a23_pinctrl_match, }, }; -- GitLab From e129b04ece0d0486ce7179b394d4c95ced347f93 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:26 +0200 Subject: [PATCH 0787/9457] pinctrl: vt8500: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pinctrl/vt8500/pinctrl-vt8500.c | 1 - drivers/pinctrl/vt8500/pinctrl-wm8505.c | 1 - drivers/pinctrl/vt8500/pinctrl-wm8650.c | 1 - drivers/pinctrl/vt8500/pinctrl-wm8750.c | 1 - drivers/pinctrl/vt8500/pinctrl-wm8850.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/pinctrl/vt8500/pinctrl-vt8500.c b/drivers/pinctrl/vt8500/pinctrl-vt8500.c index f2fe9f85cfa6..cf8bbc946ff7 100644 --- a/drivers/pinctrl/vt8500/pinctrl-vt8500.c +++ b/drivers/pinctrl/vt8500/pinctrl-vt8500.c @@ -488,7 +488,6 @@ static struct platform_driver wmt_pinctrl_driver = { .remove = vt8500_pinctrl_remove, .driver = { .name = "pinctrl-vt8500", - .owner = THIS_MODULE, .of_match_table = wmt_pinctrl_of_match, }, }; diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8505.c b/drivers/pinctrl/vt8500/pinctrl-wm8505.c index 483ba732694e..3f9c32dcb3d0 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8505.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8505.c @@ -519,7 +519,6 @@ static struct platform_driver wmt_pinctrl_driver = { .remove = wm8505_pinctrl_remove, .driver = { .name = "pinctrl-wm8505", - .owner = THIS_MODULE, .of_match_table = wmt_pinctrl_of_match, }, }; diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8650.c b/drivers/pinctrl/vt8500/pinctrl-wm8650.c index 7de57f063153..4e80f98c2ba7 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8650.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8650.c @@ -357,7 +357,6 @@ static struct platform_driver wmt_pinctrl_driver = { .remove = wm8650_pinctrl_remove, .driver = { .name = "pinctrl-wm8650", - .owner = THIS_MODULE, .of_match_table = wmt_pinctrl_of_match, }, }; diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8750.c b/drivers/pinctrl/vt8500/pinctrl-wm8750.c index de43262398db..47b52a7cacac 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8750.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8750.c @@ -396,7 +396,6 @@ static struct platform_driver wmt_pinctrl_driver = { .remove = wm8750_pinctrl_remove, .driver = { .name = "pinctrl-wm8750", - .owner = THIS_MODULE, .of_match_table = wmt_pinctrl_of_match, }, }; diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8850.c b/drivers/pinctrl/vt8500/pinctrl-wm8850.c index ecadce9c91d5..8bbb38c931f6 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8850.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8850.c @@ -375,7 +375,6 @@ static struct platform_driver wmt_pinctrl_driver = { .remove = wm8850_pinctrl_remove, .driver = { .name = "pinctrl-wm8850", - .owner = THIS_MODULE, .of_match_table = wmt_pinctrl_of_match, }, }; -- GitLab From 38c53fa8f0b2bdf4e534a24bd224e4480d8d9dc4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:26 +0200 Subject: [PATCH 0788/9457] platform: chrome: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/platform/chrome/chromeos_laptop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index d866db80b4fd..b84fdd6b629b 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -571,7 +571,6 @@ static struct platform_device *cros_platform_device; static struct platform_driver cros_platform_driver = { .driver = { .name = "chromeos_laptop", - .owner = THIS_MODULE, }, .probe = chromeos_laptop_probe, }; -- GitLab From 3493f4144bfd2f11923670b45a8290c8c6499c92 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:27 +0200 Subject: [PATCH 0789/9457] platform: x86: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/platform/x86/acer-wmi.c | 1 - drivers/platform/x86/acerhdf.c | 1 - drivers/platform/x86/alienware-wmi.c | 1 - drivers/platform/x86/amilo-rfkill.c | 1 - drivers/platform/x86/asus-laptop.c | 1 - drivers/platform/x86/compal-laptop.c | 1 - drivers/platform/x86/dell-laptop.c | 1 - drivers/platform/x86/eeepc-laptop.c | 1 - drivers/platform/x86/fujitsu-laptop.c | 1 - drivers/platform/x86/hdaps.c | 1 - drivers/platform/x86/hp-wmi.c | 1 - drivers/platform/x86/ideapad-laptop.c | 1 - drivers/platform/x86/intel_mid_powerbtn.c | 1 - drivers/platform/x86/intel_mid_thermal.c | 1 - drivers/platform/x86/intel_oaktrail.c | 1 - drivers/platform/x86/intel_pmic_gpio.c | 1 - drivers/platform/x86/msi-laptop.c | 1 - drivers/platform/x86/samsung-q10.c | 1 - drivers/platform/x86/sony-laptop.c | 1 - drivers/platform/x86/tc1100-wmi.c | 1 - drivers/platform/x86/thinkpad_acpi.c | 2 -- drivers/platform/x86/xo1-rfkill.c | 1 - 22 files changed, 23 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 96a0b75c52c9..5b3bca5470e3 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -2106,7 +2106,6 @@ static void acer_platform_shutdown(struct platform_device *device) static struct platform_driver acer_platform_driver = { .driver = { .name = "acer-wmi", - .owner = THIS_MODULE, .pm = &acer_pm, }, .probe = acer_platform_probe, diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index f94467c05225..aaf37c5f12f9 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -533,7 +533,6 @@ static const struct dev_pm_ops acerhdf_pm_ops = { static struct platform_driver acerhdf_driver = { .driver = { .name = "acerhdf", - .owner = THIS_MODULE, .pm = &acerhdf_pm_ops, }, .probe = acerhdf_probe, diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index c5af23b64438..1e1e59423889 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -157,7 +157,6 @@ static struct platform_zone *zone_data; static struct platform_driver platform_driver = { .driver = { .name = "alienware-wmi", - .owner = THIS_MODULE, } }; diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c index da36b5e824d4..0157625cb918 100644 --- a/drivers/platform/x86/amilo-rfkill.c +++ b/drivers/platform/x86/amilo-rfkill.c @@ -138,7 +138,6 @@ static int amilo_rfkill_remove(struct platform_device *device) static struct platform_driver amilo_rfkill_driver = { .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, .probe = amilo_rfkill_probe, .remove = amilo_rfkill_remove, diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 7f4dc6f51f8a..05647f1a427e 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1699,7 +1699,6 @@ static void asus_platform_exit(struct asus_laptop *asus) static struct platform_driver platform_driver = { .driver = { .name = ASUS_LAPTOP_FILE, - .owner = THIS_MODULE, }, }; diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 26bfd7bb5c13..15c0fab2bfa1 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -710,7 +710,6 @@ static int compal_remove(struct platform_device *); static struct platform_driver compal_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = compal_probe, .remove = compal_remove, diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 233d2ee598a6..f6a28d7161f5 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -84,7 +84,6 @@ static struct calling_interface_token *da_tokens; static struct platform_driver platform_driver = { .driver = { .name = "dell-laptop", - .owner = THIS_MODULE, } }; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index db79902c4a8e..5a54d35a61de 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -961,7 +961,6 @@ static const struct dev_pm_ops eeepc_pm_ops = { static struct platform_driver platform_driver = { .driver = { .name = EEEPC_LAPTOP_FILE, - .owner = THIS_MODULE, .pm = &eeepc_pm_ops, } }; diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 2655d4a988f3..be55bd78b503 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -559,7 +559,6 @@ static struct attribute_group fujitsupf_attribute_group = { static struct platform_driver fujitsupf_driver = { .driver = { .name = "fujitsu-laptop", - .owner = THIS_MODULE, } }; diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index 777c7e3dda51..458e6c948c11 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c @@ -318,7 +318,6 @@ static struct platform_driver hdaps_driver = { .probe = hdaps_probe, .driver = { .name = "hdaps", - .owner = THIS_MODULE, .pm = &hdaps_pm, }, }; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 4c559640dcba..0ab2b377a778 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -1006,7 +1006,6 @@ static const struct dev_pm_ops hp_wmi_pm_ops = { static struct platform_driver hp_wmi_driver = { .driver = { .name = "hp-wmi", - .owner = THIS_MODULE, .pm = &hp_wmi_pm_ops, }, .remove = __exit_p(hp_wmi_bios_remove), diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 02152de135b5..60499bc1fded 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -959,7 +959,6 @@ static struct platform_driver ideapad_acpi_driver = { .remove = ideapad_acpi_remove, .driver = { .name = "ideapad_acpi", - .owner = THIS_MODULE, .pm = &ideapad_pm, .acpi_match_table = ACPI_PTR(ideapad_device_ids), }, diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 8d6775266d66..22606d6b2af3 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -133,7 +133,6 @@ static int mfld_pb_remove(struct platform_device *pdev) static struct platform_driver mfld_pb_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = mfld_pb_probe, .remove = mfld_pb_remove, diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index ab7860a21a22..0944e834af8d 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -555,7 +555,6 @@ static const struct platform_device_id therm_id_table[] = { static struct platform_driver mid_thermal_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &mid_thermal_pm, }, .probe = mid_thermal_probe, diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index 4bc960416785..0afaaef5711f 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c @@ -288,7 +288,6 @@ static int oaktrail_remove(struct platform_device *pdev) static struct platform_driver oaktrail_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = oaktrail_probe, .remove = oaktrail_remove, diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 04fed00b88e9..709f0afdafa8 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -314,7 +314,6 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev) static struct platform_driver platform_pmic_gpio_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = platform_pmic_gpio_probe, }; diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 62f8030b9e77..a3f06cb1063f 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -573,7 +573,6 @@ static struct attribute_group msipf_old_attribute_group = { static struct platform_driver msipf_driver = { .driver = { .name = "msi-laptop-pf", - .owner = THIS_MODULE, .pm = &msi_laptop_pm, }, }; diff --git a/drivers/platform/x86/samsung-q10.c b/drivers/platform/x86/samsung-q10.c index 28d12bda3ac1..e6aac725a0af 100644 --- a/drivers/platform/x86/samsung-q10.c +++ b/drivers/platform/x86/samsung-q10.c @@ -82,7 +82,6 @@ static int samsungq10_remove(struct platform_device *pdev) static struct platform_driver samsungq10_driver = { .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, .probe = samsungq10_probe, .remove = samsungq10_remove, diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 26ad9ff12ac5..a1a0fd72e9bf 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -581,7 +581,6 @@ static atomic_t sony_pf_users = ATOMIC_INIT(0); static struct platform_driver sony_pf_driver = { .driver = { .name = "sony-laptop", - .owner = THIS_MODULE, } }; static struct platform_device *sony_pf_device; diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 6a6ea28a7e51..e36542564131 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -234,7 +234,6 @@ static const struct dev_pm_ops tc1100_pm_ops = { static struct platform_driver tc1100_driver = { .driver = { .name = "tc1100-wmi", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &tc1100_pm_ops, #endif diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index cf0f89364d44..6414cfe5d848 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -972,7 +972,6 @@ static void tpacpi_shutdown_handler(struct platform_device *pdev) static struct platform_driver tpacpi_pdriver = { .driver = { .name = TPACPI_DRVR_NAME, - .owner = THIS_MODULE, .pm = &tpacpi_pm, }, .shutdown = tpacpi_shutdown_handler, @@ -981,7 +980,6 @@ static struct platform_driver tpacpi_pdriver = { static struct platform_driver tpacpi_hwmon_pdriver = { .driver = { .name = TPACPI_HWMON_DRVR_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/platform/x86/xo1-rfkill.c b/drivers/platform/x86/xo1-rfkill.c index 4bd17248dfc6..e46fa9cebc7d 100644 --- a/drivers/platform/x86/xo1-rfkill.c +++ b/drivers/platform/x86/xo1-rfkill.c @@ -71,7 +71,6 @@ static int xo1_rfkill_remove(struct platform_device *pdev) static struct platform_driver xo1_rfkill_driver = { .driver = { .name = "xo1-rfkill", - .owner = THIS_MODULE, }, .probe = xo1_rfkill_probe, .remove = xo1_rfkill_remove, -- GitLab From 816c44c369019fd7a7ca460a120dc1dc0dca389e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:27 +0200 Subject: [PATCH 0790/9457] power: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/power/88pm860x_battery.c | 1 - drivers/power/88pm860x_charger.c | 1 - drivers/power/ab8500_btemp.c | 1 - drivers/power/ab8500_charger.c | 1 - drivers/power/ab8500_fg.c | 1 - drivers/power/abx500_chargalg.c | 1 - drivers/power/bq27x00_battery.c | 1 - drivers/power/charger-manager.c | 1 - drivers/power/da9030_battery.c | 1 - drivers/power/da9052-battery.c | 1 - drivers/power/generic-adc-battery.c | 1 - drivers/power/gpio-charger.c | 1 - drivers/power/intel_mid_battery.c | 1 - drivers/power/jz4740-battery.c | 1 - drivers/power/lp8788-charger.c | 1 - drivers/power/max14577_charger.c | 1 - drivers/power/max8903_charger.c | 1 - drivers/power/max8997_charger.c | 1 - drivers/power/max8998_charger.c | 1 - drivers/power/olpc_battery.c | 1 - drivers/power/rx51_battery.c | 1 - drivers/power/tps65090-charger.c | 1 - drivers/power/twl4030_charger.c | 1 - drivers/power/wm97xx_battery.c | 1 - 24 files changed, 24 deletions(-) diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c index dfcda3a49403..bd3c997f4fee 100644 --- a/drivers/power/88pm860x_battery.c +++ b/drivers/power/88pm860x_battery.c @@ -1023,7 +1023,6 @@ static SIMPLE_DEV_PM_OPS(pm860x_battery_pm_ops, static struct platform_driver pm860x_battery_driver = { .driver = { .name = "88pm860x-battery", - .owner = THIS_MODULE, .pm = &pm860x_battery_pm_ops, }, .probe = pm860x_battery_probe, diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c index de029bbc1cc1..650930e4fa79 100644 --- a/drivers/power/88pm860x_charger.c +++ b/drivers/power/88pm860x_charger.c @@ -732,7 +732,6 @@ static int pm860x_charger_remove(struct platform_device *pdev) static struct platform_driver pm860x_charger_driver = { .driver = { .name = "88pm860x-charger", - .owner = THIS_MODULE, }, .probe = pm860x_charger_probe, .remove = pm860x_charger_remove, diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index 7f9a4547dccd..4ebf7b0819f7 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -1195,7 +1195,6 @@ static struct platform_driver ab8500_btemp_driver = { .resume = ab8500_btemp_resume, .driver = { .name = "ab8500-btemp", - .owner = THIS_MODULE, .of_match_table = ab8500_btemp_match, }, }; diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index 19110aa613a1..8c8d170ff0f8 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -3733,7 +3733,6 @@ static struct platform_driver ab8500_charger_driver = { .resume = ab8500_charger_resume, .driver = { .name = "ab8500-charger", - .owner = THIS_MODULE, .of_match_table = ab8500_charger_match, }, }; diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 217da4b2ca86..a71834793b19 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -3280,7 +3280,6 @@ static struct platform_driver ab8500_fg_driver = { .resume = ab8500_fg_resume, .driver = { .name = "ab8500-fg", - .owner = THIS_MODULE, .of_match_table = ab8500_fg_match, }, }; diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 6d2723664a01..ab54b8dea670 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -2156,7 +2156,6 @@ static struct platform_driver abx500_chargalg_driver = { .resume = abx500_chargalg_resume, .driver = { .name = "ab8500-chargalg", - .owner = THIS_MODULE, .of_match_table = ab8500_chargalg_match, }, }; diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index e3bacfe3bcd0..a78ac201828e 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -1014,7 +1014,6 @@ static struct platform_driver bq27000_battery_driver = { .remove = bq27000_battery_remove, .driver = { .name = "bq27000-battery", - .owner = THIS_MODULE, }, }; diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 7098a1ce2d3c..3d3c12f1d6e1 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -2028,7 +2028,6 @@ static const struct dev_pm_ops charger_manager_pm = { static struct platform_driver charger_manager_driver = { .driver = { .name = "charger-manager", - .owner = THIS_MODULE, .pm = &charger_manager_pm, .of_match_table = charger_manager_match, }, diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c index ae6c41835ee6..78cd5d66144b 100644 --- a/drivers/power/da9030_battery.c +++ b/drivers/power/da9030_battery.c @@ -579,7 +579,6 @@ static int da9030_battery_remove(struct platform_device *dev) static struct platform_driver da903x_battery_driver = { .driver = { .name = "da903x-battery", - .owner = THIS_MODULE, }, .probe = da9030_battery_probe, .remove = da9030_battery_remove, diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c index f8f4c0f7c17d..d17250f745c2 100644 --- a/drivers/power/da9052-battery.c +++ b/drivers/power/da9052-battery.c @@ -656,7 +656,6 @@ static struct platform_driver da9052_bat_driver = { .remove = da9052_bat_remove, .driver = { .name = "da9052-bat", - .owner = THIS_MODULE, }, }; module_platform_driver(da9052_bat_driver); diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index 59a1421f9288..d72733e4f93a 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c @@ -414,7 +414,6 @@ static const struct dev_pm_ops gab_pm_ops = { static struct platform_driver gab_driver = { .driver = { .name = "generic-adc-battery", - .owner = THIS_MODULE, .pm = GAB_PM_OPS }, .probe = gab_probe, diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 7536933d0ab9..3ee889fe0021 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -194,7 +194,6 @@ static struct platform_driver gpio_charger_driver = { .remove = gpio_charger_remove, .driver = { .name = "gpio-charger", - .owner = THIS_MODULE, .pm = &gpio_charger_pm_ops, }, }; diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index 4520811168ad..de3f39e6fa8e 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c @@ -773,7 +773,6 @@ static int platform_pmic_battery_remove(struct platform_device *pdev) static struct platform_driver platform_pmic_battery_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = platform_pmic_battery_probe, .remove = platform_pmic_battery_remove, diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index 6c8931d4ad62..9cd391d61819 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -406,7 +406,6 @@ static struct platform_driver jz_battery_driver = { .remove = jz_battery_remove, .driver = { .name = "jz4740-battery", - .owner = THIS_MODULE, .pm = JZ_BATTERY_PM_OPS, }, }; diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c index ed49b50b220b..21fc233c7d61 100644 --- a/drivers/power/lp8788-charger.c +++ b/drivers/power/lp8788-charger.c @@ -740,7 +740,6 @@ static struct platform_driver lp8788_charger_driver = { .remove = lp8788_charger_remove, .driver = { .name = LP8788_DEV_CHARGER, - .owner = THIS_MODULE, }, }; module_platform_driver(lp8788_charger_driver); diff --git a/drivers/power/max14577_charger.c b/drivers/power/max14577_charger.c index 0a2bc7277026..ef4103ee6021 100644 --- a/drivers/power/max14577_charger.c +++ b/drivers/power/max14577_charger.c @@ -599,7 +599,6 @@ MODULE_DEVICE_TABLE(platform, max14577_charger_id); static struct platform_driver max14577_charger_driver = { .driver = { - .owner = THIS_MODULE, .name = "max14577-charger", }, .probe = max14577_charger_probe, diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c index 08f0d7909b6b..99e3cdcd3e11 100644 --- a/drivers/power/max8903_charger.c +++ b/drivers/power/max8903_charger.c @@ -368,7 +368,6 @@ static struct platform_driver max8903_driver = { .remove = max8903_remove, .driver = { .name = "max8903-charger", - .owner = THIS_MODULE, }, }; diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c index 4bdedfed936d..aefa0c9a3007 100644 --- a/drivers/power/max8997_charger.c +++ b/drivers/power/max8997_charger.c @@ -181,7 +181,6 @@ static const struct platform_device_id max8997_battery_id[] = { static struct platform_driver max8997_battery_driver = { .driver = { .name = "max8997-battery", - .owner = THIS_MODULE, }, .probe = max8997_battery_probe, .remove = max8997_battery_remove, diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c index 5017470c2fc9..08694c7a9f38 100644 --- a/drivers/power/max8998_charger.c +++ b/drivers/power/max8998_charger.c @@ -195,7 +195,6 @@ static const struct platform_device_id max8998_battery_id[] = { static struct platform_driver max8998_battery_driver = { .driver = { .name = "max8998-battery", - .owner = THIS_MODULE, }, .probe = max8998_battery_probe, .remove = max8998_battery_remove, diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 1ec810ada5ed..ad9cde705de1 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -677,7 +677,6 @@ MODULE_DEVICE_TABLE(of, olpc_battery_ids); static struct platform_driver olpc_battery_driver = { .driver = { .name = "olpc-battery", - .owner = THIS_MODULE, .of_match_table = olpc_battery_ids, }, .probe = olpc_battery_probe, diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index d5a2acfb8821..a01aacb32f59 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c @@ -281,7 +281,6 @@ static struct platform_driver rx51_battery_driver = { .remove = rx51_battery_remove, .driver = { .name = "rx51-battery", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(n900_battery_of_match), }, }; diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index 3e8ba97c8169..0f4e5971dff5 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c @@ -353,7 +353,6 @@ static struct platform_driver tps65090_charger_driver = { .driver = { .name = "tps65090-charger", .of_match_table = of_tps65090_charger_match, - .owner = THIS_MODULE, }, .probe = tps65090_charger_probe, .remove = tps65090_charger_remove, diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index 2598c588006e..d35b83e635b5 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -716,7 +716,6 @@ MODULE_DEVICE_TABLE(of, twl_bci_of_match); static struct platform_driver twl4030_bci_driver = { .driver = { .name = "twl4030_bci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl_bci_of_match), }, .remove = __exit_p(twl4030_bci_remove), diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 58f7348e6c22..a8e6203673ad 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -281,7 +281,6 @@ static int wm97xx_bat_remove(struct platform_device *dev) static struct platform_driver wm97xx_bat_driver = { .driver = { .name = "wm97xx-battery", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &wm97xx_bat_pm_ops, #endif -- GitLab From 5938ee2bb2e45bfd601896677eb5db3e21339689 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:28 +0200 Subject: [PATCH 0791/9457] power: reset: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/power/reset/as3722-poweroff.c | 1 - drivers/power/reset/brcmstb-reboot.c | 1 - drivers/power/reset/gpio-poweroff.c | 1 - drivers/power/reset/gpio-restart.c | 1 - drivers/power/reset/keystone-reset.c | 1 - drivers/power/reset/ltc2952-poweroff.c | 1 - drivers/power/reset/qnap-poweroff.c | 1 - drivers/power/reset/restart-poweroff.c | 1 - 8 files changed, 8 deletions(-) diff --git a/drivers/power/reset/as3722-poweroff.c b/drivers/power/reset/as3722-poweroff.c index 684971199bd3..60d0295fffb1 100644 --- a/drivers/power/reset/as3722-poweroff.c +++ b/drivers/power/reset/as3722-poweroff.c @@ -82,7 +82,6 @@ static int as3722_poweroff_remove(struct platform_device *pdev) static struct platform_driver as3722_poweroff_driver = { .driver = { .name = "as3722-power-off", - .owner = THIS_MODULE, }, .probe = as3722_poweroff_probe, .remove = as3722_poweroff_remove, diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c index 3f236924742a..c523ea7a90ee 100644 --- a/drivers/power/reset/brcmstb-reboot.c +++ b/drivers/power/reset/brcmstb-reboot.c @@ -107,7 +107,6 @@ static struct platform_driver brcmstb_reboot_driver = { .probe = brcmstb_reboot_probe, .driver = { .name = "brcmstb-reboot", - .owner = THIS_MODULE, .of_match_table = of_match, }, }; diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c index ce849bc9b269..e5332f1db8a7 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c @@ -99,7 +99,6 @@ static struct platform_driver gpio_poweroff_driver = { .remove = gpio_poweroff_remove, .driver = { .name = "poweroff-gpio", - .owner = THIS_MODULE, .of_match_table = of_gpio_poweroff_match, }, }; diff --git a/drivers/power/reset/gpio-restart.c b/drivers/power/reset/gpio-restart.c index a76829b3f1cd..edb327efee8b 100644 --- a/drivers/power/reset/gpio-restart.c +++ b/drivers/power/reset/gpio-restart.c @@ -137,7 +137,6 @@ static struct platform_driver gpio_restart_driver = { .remove = gpio_restart_remove, .driver = { .name = "restart-gpio", - .owner = THIS_MODULE, .of_match_table = of_gpio_restart_match, }, }; diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c index 408a18fd91cb..86bc100818b2 100644 --- a/drivers/power/reset/keystone-reset.c +++ b/drivers/power/reset/keystone-reset.c @@ -153,7 +153,6 @@ static int rsctrl_probe(struct platform_device *pdev) static struct platform_driver rsctrl_driver = { .probe = rsctrl_probe, .driver = { - .owner = THIS_MODULE, .name = KBUILD_MODNAME, .of_match_table = rsctrl_of_match, }, diff --git a/drivers/power/reset/ltc2952-poweroff.c b/drivers/power/reset/ltc2952-poweroff.c index 116a1cef8f7b..34f38a3dc3ff 100644 --- a/drivers/power/reset/ltc2952-poweroff.c +++ b/drivers/power/reset/ltc2952-poweroff.c @@ -342,7 +342,6 @@ static struct platform_driver ltc2952_poweroff_driver = { .remove = ltc2952_poweroff_remove, .driver = { .name = "ltc2952-poweroff", - .owner = THIS_MODULE, .of_match_table = of_ltc2952_poweroff_match, }, .suspend = ltc2952_poweroff_suspend, diff --git a/drivers/power/reset/qnap-poweroff.c b/drivers/power/reset/qnap-poweroff.c index a75db7f8a92f..2789a61cec68 100644 --- a/drivers/power/reset/qnap-poweroff.c +++ b/drivers/power/reset/qnap-poweroff.c @@ -129,7 +129,6 @@ static struct platform_driver qnap_power_off_driver = { .probe = qnap_power_off_probe, .remove = qnap_power_off_remove, .driver = { - .owner = THIS_MODULE, .name = "qnap_power_off", .of_match_table = of_match_ptr(qnap_power_off_of_match_table), }, diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c index edd707ee7281..f46f2c2e4648 100644 --- a/drivers/power/reset/restart-poweroff.c +++ b/drivers/power/reset/restart-poweroff.c @@ -55,7 +55,6 @@ static struct platform_driver restart_poweroff_driver = { .remove = restart_poweroff_remove, .driver = { .name = "poweroff-restart", - .owner = THIS_MODULE, .of_match_table = of_restart_poweroff_match, }, }; -- GitLab From da2612af00d8216ba365866f9d52f04ea2ad7773 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:28 +0200 Subject: [PATCH 0792/9457] pps: clients: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pps/clients/pps-gpio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c index f41bacfdc3dc..333ad7d5b45b 100644 --- a/drivers/pps/clients/pps-gpio.c +++ b/drivers/pps/clients/pps-gpio.c @@ -200,7 +200,6 @@ static struct platform_driver pps_gpio_driver = { .remove = pps_gpio_remove, .driver = { .name = PPS_GPIO_NAME, - .owner = THIS_MODULE, .of_match_table = pps_gpio_dt_ids, }, }; -- GitLab From f05fae14a10ca0c07f176e680ef9ff9d348e7153 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:28 +0200 Subject: [PATCH 0793/9457] pwm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/pwm/pwm-ab8500.c | 1 - drivers/pwm/pwm-atmel-tcb.c | 1 - drivers/pwm/pwm-bfin.c | 1 - drivers/pwm/pwm-clps711x.c | 1 - drivers/pwm/pwm-imx.c | 1 - drivers/pwm/pwm-jz4740.c | 1 - drivers/pwm/pwm-lp3943.c | 1 - drivers/pwm/pwm-lpc32xx.c | 1 - drivers/pwm/pwm-mxs.c | 1 - drivers/pwm/pwm-puv3.c | 1 - drivers/pwm/pwm-pxa.c | 1 - drivers/pwm/pwm-renesas-tpu.c | 1 - drivers/pwm/pwm-samsung.c | 1 - drivers/pwm/pwm-spear.c | 1 - drivers/pwm/pwm-tegra.c | 1 - drivers/pwm/pwm-tiecap.c | 1 - drivers/pwm/pwm-tiehrpwm.c | 1 - drivers/pwm/pwm-tipwmss.c | 1 - drivers/pwm/pwm-vt8500.c | 1 - 19 files changed, 19 deletions(-) diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index 4c07a8420b37..f39399273426 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c @@ -131,7 +131,6 @@ static int ab8500_pwm_remove(struct platform_device *pdev) static struct platform_driver ab8500_pwm_driver = { .driver = { .name = "ab8500-pwm", - .owner = THIS_MODULE, }, .probe = ab8500_pwm_probe, .remove = ab8500_pwm_remove, diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index d56e5b717431..d14e0677c92d 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -436,7 +436,6 @@ MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids); static struct platform_driver atmel_tcb_pwm_driver = { .driver = { .name = "atmel-tcb-pwm", - .owner = THIS_MODULE, .of_match_table = atmel_tcb_pwm_dt_ids, }, .probe = atmel_tcb_pwm_probe, diff --git a/drivers/pwm/pwm-bfin.c b/drivers/pwm/pwm-bfin.c index 9985d830e554..7631ef194de7 100644 --- a/drivers/pwm/pwm-bfin.c +++ b/drivers/pwm/pwm-bfin.c @@ -149,7 +149,6 @@ static int bfin_pwm_remove(struct platform_device *pdev) static struct platform_driver bfin_pwm_driver = { .driver = { .name = "bfin-pwm", - .owner = THIS_MODULE, }, .probe = bfin_pwm_probe, .remove = bfin_pwm_remove, diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c index fafb6a0111b0..a80c10803636 100644 --- a/drivers/pwm/pwm-clps711x.c +++ b/drivers/pwm/pwm-clps711x.c @@ -163,7 +163,6 @@ MODULE_DEVICE_TABLE(of, clps711x_pwm_dt_ids); static struct platform_driver clps711x_pwm_driver = { .driver = { .name = "clps711x-pwm", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(clps711x_pwm_dt_ids), }, .probe = clps711x_pwm_probe, diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 5449d9150d40..11af7b4403f8 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -295,7 +295,6 @@ static int imx_pwm_remove(struct platform_device *pdev) static struct platform_driver imx_pwm_driver = { .driver = { .name = "imx-pwm", - .owner = THIS_MODULE, .of_match_table = imx_pwm_dt_ids, }, .probe = imx_pwm_probe, diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c index 9c46209e1d02..76d13150283f 100644 --- a/drivers/pwm/pwm-jz4740.c +++ b/drivers/pwm/pwm-jz4740.c @@ -194,7 +194,6 @@ static int jz4740_pwm_remove(struct platform_device *pdev) static struct platform_driver jz4740_pwm_driver = { .driver = { .name = "jz4740-pwm", - .owner = THIS_MODULE, }, .probe = jz4740_pwm_probe, .remove = jz4740_pwm_remove, diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 2c39b0e50fa4..872ea76a4f19 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c @@ -305,7 +305,6 @@ static struct platform_driver lp3943_pwm_driver = { .remove = lp3943_pwm_remove, .driver = { .name = "lp3943-pwm", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(lp3943_pwm_of_match), }, }; diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index 9dc0f9d42bfa..9fde60ce8e7b 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -168,7 +168,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_pwm_dt_ids); static struct platform_driver lpc32xx_pwm_driver = { .driver = { .name = "lpc32xx-pwm", - .owner = THIS_MODULE, .of_match_table = lpc32xx_pwm_dt_ids, }, .probe = lpc32xx_pwm_probe, diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c index 4f1bb4e0a426..f75ecb09d97d 100644 --- a/drivers/pwm/pwm-mxs.c +++ b/drivers/pwm/pwm-mxs.c @@ -189,7 +189,6 @@ MODULE_DEVICE_TABLE(of, mxs_pwm_dt_ids); static struct platform_driver mxs_pwm_driver = { .driver = { .name = "mxs-pwm", - .owner = THIS_MODULE, .of_match_table = mxs_pwm_dt_ids, }, .probe = mxs_pwm_probe, diff --git a/drivers/pwm/pwm-puv3.c b/drivers/pwm/pwm-puv3.c index a9a28083f245..ed6007b27585 100644 --- a/drivers/pwm/pwm-puv3.c +++ b/drivers/pwm/pwm-puv3.c @@ -146,7 +146,6 @@ static int pwm_remove(struct platform_device *pdev) static struct platform_driver puv3_pwm_driver = { .driver = { .name = "PKUnity-v3-PWM", - .owner = THIS_MODULE, }, .probe = pwm_probe, .remove = pwm_remove, diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index 0b312ec420b6..cb2f7024cf68 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -225,7 +225,6 @@ static int pwm_remove(struct platform_device *pdev) static struct platform_driver pwm_driver = { .driver = { .name = "pxa25x-pwm", - .owner = THIS_MODULE, .of_match_table = pwm_of_match, }, .probe = pwm_probe, diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 3b71b42e89d5..ee63f9e9d0fb 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -468,7 +468,6 @@ static struct platform_driver tpu_driver = { .remove = tpu_remove, .driver = { .name = "renesas-tpu-pwm", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(tpu_of_table), } }; diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index ba6b650cf8dc..3e9b5835a4af 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -601,7 +601,6 @@ static SIMPLE_DEV_PM_OPS(pwm_samsung_pm_ops, pwm_samsung_suspend, static struct platform_driver pwm_samsung_driver = { .driver = { .name = "samsung-pwm", - .owner = THIS_MODULE, .pm = &pwm_samsung_pm_ops, .of_match_table = of_match_ptr(samsung_pwm_matches), }, diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index 6fd93e6a4122..6c6b44fd3f43 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -252,7 +252,6 @@ MODULE_DEVICE_TABLE(of, spear_pwm_of_match); static struct platform_driver spear_pwm_driver = { .driver = { .name = "spear-pwm", - .owner = THIS_MODULE, .of_match_table = spear_pwm_of_match, }, .probe = spear_pwm_probe, diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 61d86b9498ca..5b97cae5423a 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -237,7 +237,6 @@ MODULE_DEVICE_TABLE(of, tegra_pwm_of_match); static struct platform_driver tegra_pwm_driver = { .driver = { .name = "tegra-pwm", - .owner = THIS_MODULE, .of_match_table = tegra_pwm_of_match, }, .probe = tegra_pwm_probe, diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 74efbe7f20c3..e557befdf4e6 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -331,7 +331,6 @@ static SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume); static struct platform_driver ecap_pwm_driver = { .driver = { .name = "ecap", - .owner = THIS_MODULE, .of_match_table = ecap_of_match, .pm = &ecap_pwm_pm_ops, }, diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index cb75133085a8..694b3cf7694b 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -599,7 +599,6 @@ static SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend, static struct platform_driver ehrpwm_pwm_driver = { .driver = { .name = "ehrpwm", - .owner = THIS_MODULE, .of_match_table = ehrpwm_of_match, .pm = &ehrpwm_pwm_pm_ops, }, diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c index 67481dc6da3f..5cf65a15d021 100644 --- a/drivers/pwm/pwm-tipwmss.c +++ b/drivers/pwm/pwm-tipwmss.c @@ -119,7 +119,6 @@ static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume); static struct platform_driver pwmss_driver = { .driver = { .name = "pwmss", - .owner = THIS_MODULE, .pm = &pwmss_pm_ops, .of_match_table = pwmss_of_match, }, diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 652e6b5b859b..cdb58fd4619d 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -266,7 +266,6 @@ static struct platform_driver vt8500_pwm_driver = { .remove = vt8500_pwm_remove, .driver = { .name = "vt8500-pwm", - .owner = THIS_MODULE, .of_match_table = vt8500_pwm_dt_ids, }, }; -- GitLab From 6c794b2654555d6af7572e3a8f13b2b39126df0c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:29 +0200 Subject: [PATCH 0794/9457] regulator: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/regulator/88pm800.c | 1 - drivers/regulator/88pm8607.c | 1 - drivers/regulator/aat2870-regulator.c | 1 - drivers/regulator/ab3100.c | 1 - drivers/regulator/ab8500-ext.c | 1 - drivers/regulator/ab8500.c | 1 - drivers/regulator/anatop-regulator.c | 1 - drivers/regulator/arizona-ldo1.c | 1 - drivers/regulator/arizona-micsupp.c | 1 - drivers/regulator/as3711-regulator.c | 1 - drivers/regulator/as3722-regulator.c | 1 - drivers/regulator/axp20x-regulator.c | 1 - drivers/regulator/bcm590xx-regulator.c | 1 - drivers/regulator/da903x.c | 1 - drivers/regulator/da9052-regulator.c | 1 - drivers/regulator/da9055-regulator.c | 1 - drivers/regulator/da9063-regulator.c | 1 - drivers/regulator/db8500-prcmu.c | 1 - drivers/regulator/dummy.c | 1 - drivers/regulator/fixed.c | 1 - drivers/regulator/gpio-regulator.c | 1 - drivers/regulator/hi6421-regulator.c | 1 - drivers/regulator/lp8788-buck.c | 1 - drivers/regulator/lp8788-ldo.c | 2 -- drivers/regulator/max14577.c | 1 - drivers/regulator/max77686.c | 1 - drivers/regulator/max77693.c | 1 - drivers/regulator/max77802.c | 1 - drivers/regulator/max8907-regulator.c | 1 - drivers/regulator/max8925-regulator.c | 1 - drivers/regulator/max8997.c | 1 - drivers/regulator/max8998.c | 1 - drivers/regulator/mc13783-regulator.c | 1 - drivers/regulator/mc13892-regulator.c | 1 - drivers/regulator/palmas-regulator.c | 1 - drivers/regulator/pbias-regulator.c | 1 - drivers/regulator/pcap-regulator.c | 1 - drivers/regulator/pwm-regulator.c | 1 - drivers/regulator/qcom_rpm-regulator.c | 1 - drivers/regulator/rc5t583-regulator.c | 1 - drivers/regulator/rk808-regulator.c | 1 - drivers/regulator/s2mpa01.c | 1 - drivers/regulator/s2mps11.c | 1 - drivers/regulator/s5m8767.c | 1 - drivers/regulator/stw481x-vmmc.c | 1 - drivers/regulator/ti-abb-regulator.c | 1 - drivers/regulator/tps6105x-regulator.c | 1 - drivers/regulator/tps6507x-regulator.c | 1 - drivers/regulator/tps65090-regulator.c | 1 - drivers/regulator/tps65218-regulator.c | 1 - drivers/regulator/tps6586x-regulator.c | 1 - drivers/regulator/tps65910-regulator.c | 1 - drivers/regulator/tps65912-regulator.c | 1 - drivers/regulator/tps80031-regulator.c | 1 - drivers/regulator/twl-regulator.c | 1 - drivers/regulator/vexpress.c | 1 - drivers/regulator/virtual.c | 1 - drivers/regulator/wm831x-dcdc.c | 4 ---- drivers/regulator/wm831x-isink.c | 1 - drivers/regulator/wm831x-ldo.c | 3 --- drivers/regulator/wm8994-regulator.c | 1 - 61 files changed, 67 deletions(-) diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index 4e6c8c611905..832932bdc977 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -362,7 +362,6 @@ static int pm800_regulator_remove(struct platform_device *pdev) static struct platform_driver pm800_regulator_driver = { .driver = { .name = "88pm80x-regulator", - .owner = THIS_MODULE, }, .probe = pm800_regulator_probe, .remove = pm800_regulator_remove, diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 6d77dcd7dcf6..e04b333cc108 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -418,7 +418,6 @@ MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids); static struct platform_driver pm8607_regulator_driver = { .driver = { .name = "88pm860x-regulator", - .owner = THIS_MODULE, }, .probe = pm8607_regulator_probe, .id_table = pm8607_regulator_driver_ids, diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index c873ee0082cf..9dfabda8f478 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -191,7 +191,6 @@ static int aat2870_regulator_probe(struct platform_device *pdev) static struct platform_driver aat2870_regulator_driver = { .driver = { .name = "aat2870-regulator", - .owner = THIS_MODULE, }, .probe = aat2870_regulator_probe, }; diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index e10febe9ec34..de2644490f0d 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -721,7 +721,6 @@ static int ab3100_regulators_probe(struct platform_device *pdev) static struct platform_driver ab3100_regulators_driver = { .driver = { .name = "ab3100-regulators", - .owner = THIS_MODULE, }, .probe = ab3100_regulators_probe, .remove = ab3100_regulators_remove, diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 29c0faaf8eba..84c1ee39ddae 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c @@ -433,7 +433,6 @@ static struct platform_driver ab8500_ext_regulator_driver = { .probe = ab8500_ext_regulator_probe, .driver = { .name = "ab8500-ext-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 1fda14e12ea8..0f97514e3474 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -3075,7 +3075,6 @@ static struct platform_driver ab8500_regulator_driver = { .probe = ab8500_regulator_probe, .driver = { .name = "ab8500-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 4f730af70e7c..1d4d8e572786 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -308,7 +308,6 @@ static const struct of_device_id of_anatop_regulator_match_tbl[] = { static struct platform_driver anatop_regulator_driver = { .driver = { .name = "anatop_regulator", - .owner = THIS_MODULE, .of_match_table = of_anatop_regulator_match_tbl, }, .probe = anatop_regulator_probe, diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4c9db589f6c1..9b0e96919578 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -296,7 +296,6 @@ static struct platform_driver arizona_ldo1_driver = { .probe = arizona_ldo1_probe, .driver = { .name = "arizona-ldo1", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index ce9aca5f8ee7..9857c9f2f621 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -300,7 +300,6 @@ static struct platform_driver arizona_micsupp_driver = { .probe = arizona_micsupp_probe, .driver = { .name = "arizona-micsupp", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index 8459b0b648cd..c0e93b1332f7 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -267,7 +267,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) static struct platform_driver as3711_regulator_driver = { .driver = { .name = "as3711-regulator", - .owner = THIS_MODULE, }, .probe = as3711_regulator_probe, }; diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index b68f05f38537..8b046eec6ae0 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -916,7 +916,6 @@ MODULE_DEVICE_TABLE(of, of_as3722_regulator_match); static struct platform_driver as3722_regulator_driver = { .driver = { .name = "as3722-regulator", - .owner = THIS_MODULE, .of_match_table = of_as3722_regulator_match, }, .probe = as3722_regulator_probe, diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 2e1010a34ddc..f23d7e1f2ee7 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -275,7 +275,6 @@ static struct platform_driver axp20x_regulator_driver = { .probe = axp20x_regulator_probe, .driver = { .name = "axp20x-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index fe6ac69549a6..628430bdc312 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -453,7 +453,6 @@ static int bcm590xx_probe(struct platform_device *pdev) static struct platform_driver bcm590xx_regulator_driver = { .driver = { .name = "bcm590xx-vregs", - .owner = THIS_MODULE, }, .probe = bcm590xx_probe, }; diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index b431ae357fcd..affa1b191314 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -475,7 +475,6 @@ static int da903x_regulator_probe(struct platform_device *pdev) static struct platform_driver da903x_regulator_driver = { .driver = { .name = "da903x-regulator", - .owner = THIS_MODULE, }, .probe = da903x_regulator_probe, }; diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 00033625a09c..8f42ae741774 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -463,7 +463,6 @@ static struct platform_driver da9052_regulator_driver = { .probe = da9052_regulator_probe, .driver = { .name = "da9052-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 9516317e1a9f..cafdafbffcaf 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -665,7 +665,6 @@ static struct platform_driver da9055_regulator_driver = { .probe = da9055_regulator_probe, .driver = { .name = "da9055-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 7c9461d13313..82e6cd39942d 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -896,7 +896,6 @@ static int da9063_regulator_remove(struct platform_device *pdev) static struct platform_driver da9063_regulator_driver = { .driver = { .name = DA9063_DRVNAME_REGULATORS, - .owner = THIS_MODULE, }, .probe = da9063_regulator_probe, .remove = da9063_regulator_remove, diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 617c1adca816..7cec535cf0bc 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -534,7 +534,6 @@ static int db8500_regulator_remove(struct platform_device *pdev) static struct platform_driver db8500_regulator_driver = { .driver = { .name = "db8500-prcmu-regulators", - .owner = THIS_MODULE, }, .probe = db8500_regulator_probe, .remove = db8500_regulator_remove, diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index 2436db9e2ca3..933b529ac27f 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -63,7 +63,6 @@ static struct platform_driver dummy_regulator_driver = { .probe = dummy_regulator_probe, .driver = { .name = "reg-dummy", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 354105eff1f8..47e9043a3a4f 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -207,7 +207,6 @@ static struct platform_driver regulator_fixed_voltage_driver = { .probe = reg_fixed_voltage_probe, .driver = { .name = "reg-fixed-voltage", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(fixed_of_match), }, }; diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 989b23b377c0..17fa02554c3d 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -388,7 +388,6 @@ static struct platform_driver gpio_regulator_driver = { .remove = gpio_regulator_remove, .driver = { .name = "gpio-regulator", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(regulator_gpio_of_match), }, }; diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 156d0d1a55f1..42dc5fb8c899 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -623,7 +623,6 @@ static int hi6421_regulator_probe(struct platform_device *pdev) static struct platform_driver hi6421_regulator_driver = { .driver = { .name = "hi6421-regulator", - .owner = THIS_MODULE, }, .probe = hi6421_regulator_probe, }; diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index 948afc249e29..a97bed90d39b 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -533,7 +533,6 @@ static struct platform_driver lp8788_buck_driver = { .probe = lp8788_buck_probe, .driver = { .name = LP8788_DEV_BUCK, - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index b9a29a29933f..9f22d079c8cc 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -561,7 +561,6 @@ static struct platform_driver lp8788_dldo_driver = { .probe = lp8788_dldo_probe, .driver = { .name = LP8788_DEV_DLDO, - .owner = THIS_MODULE, }, }; @@ -611,7 +610,6 @@ static struct platform_driver lp8788_aldo_driver = { .probe = lp8788_aldo_probe, .driver = { .name = LP8788_DEV_ALDO, - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index 0ff5a20ac958..bf9a44c5fdd2 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c @@ -371,7 +371,6 @@ MODULE_DEVICE_TABLE(platform, max14577_regulator_id); static struct platform_driver max14577_regulator_driver = { .driver = { - .owner = THIS_MODULE, .name = "max14577-regulator", }, .probe = max14577_regulator_probe, diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index ef1af2debbd2..a95689631bf8 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c @@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(platform, max77686_pmic_id); static struct platform_driver max77686_pmic_driver = { .driver = { .name = "max77686-pmic", - .owner = THIS_MODULE, }, .probe = max77686_pmic_probe, .id_table = max77686_pmic_id, diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index c67ff05fc1dd..b0024e90e533 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c @@ -267,7 +267,6 @@ MODULE_DEVICE_TABLE(platform, max77693_pmic_id); static struct platform_driver max77693_pmic_driver = { .driver = { .name = "max77693-pmic", - .owner = THIS_MODULE, }, .probe = max77693_pmic_probe, .id_table = max77693_pmic_id, diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c index d89792b084e9..e873da75f351 100644 --- a/drivers/regulator/max77802.c +++ b/drivers/regulator/max77802.c @@ -573,7 +573,6 @@ MODULE_DEVICE_TABLE(platform, max77802_pmic_id); static struct platform_driver max77802_pmic_driver = { .driver = { .name = "max77802-pmic", - .owner = THIS_MODULE, }, .probe = max77802_pmic_probe, .id_table = max77802_pmic_id, diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 3426be89c9f6..5e941db5ccaf 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -366,7 +366,6 @@ static int max8907_regulator_probe(struct platform_device *pdev) static struct platform_driver max8907_regulator_driver = { .driver = { .name = "max8907-regulator", - .owner = THIS_MODULE, }, .probe = max8907_regulator_probe, }; diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 7770777befc4..c802f0239dc7 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -324,7 +324,6 @@ static int max8925_regulator_probe(struct platform_device *pdev) static struct platform_driver max8925_regulator_driver = { .driver = { .name = "max8925-regulator", - .owner = THIS_MODULE, }, .probe = max8925_regulator_probe, }; diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 9c31e215a521..0767ae4f1280 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1218,7 +1218,6 @@ MODULE_DEVICE_TABLE(platform, max8997_pmic_id); static struct platform_driver max8997_pmic_driver = { .driver = { .name = "max8997-pmic", - .owner = THIS_MODULE, }, .probe = max8997_pmic_probe, .id_table = max8997_pmic_id, diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 961091b46557..9978d616125f 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -894,7 +894,6 @@ MODULE_DEVICE_TABLE(platform, max8998_pmic_id); static struct platform_driver max8998_pmic_driver = { .driver = { .name = "max8998-pmic", - .owner = THIS_MODULE, }, .probe = max8998_pmic_probe, .id_table = max8998_pmic_id, diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 7f4a67edf780..fe4c7d677f9c 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -459,7 +459,6 @@ static int mc13783_regulator_probe(struct platform_device *pdev) static struct platform_driver mc13783_regulator_driver = { .driver = { .name = "mc13783-regulator", - .owner = THIS_MODULE, }, .probe = mc13783_regulator_probe, }; diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index 793b662a1967..0d17c9206816 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -633,7 +633,6 @@ static int mc13892_regulator_probe(struct platform_device *pdev) static struct platform_driver mc13892_regulator_driver = { .driver = { .name = "mc13892-regulator", - .owner = THIS_MODULE, }, .probe = mc13892_regulator_probe, }; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 1878e5b567ef..9205f433573c 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -1610,7 +1610,6 @@ static struct platform_driver palmas_driver = { .driver = { .name = "palmas-pmic", .of_match_table = of_palmas_match_tbl, - .owner = THIS_MODULE, }, .probe = palmas_regulators_probe, }; diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index 6d02d68dfb46..bd2b75c0d1d1 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -185,7 +185,6 @@ static struct platform_driver pbias_regulator_driver = { .probe = pbias_regulator_probe, .driver = { .name = "pbias-regulator", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pbias_of_match), }, }; diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 3727b7d0e9ac..9b16e6158f15 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -259,7 +259,6 @@ static int pcap_regulator_probe(struct platform_device *pdev) static struct platform_driver pcap_regulator_driver = { .driver = { .name = "pcap-regulator", - .owner = THIS_MODULE, }, .probe = pcap_regulator_probe, }; diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index d3f55eaea058..914b88ba370a 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -183,7 +183,6 @@ MODULE_DEVICE_TABLE(of, pwm_of_match); static struct platform_driver pwm_regulator_driver = { .driver = { .name = "pwm-regulator", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pwm_of_match), }, .probe = pwm_regulator_probe, diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index b55cd5b50ebe..b8692546a7f3 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -777,7 +777,6 @@ static struct platform_driver rpm_reg_driver = { .probe = rpm_reg_probe, .driver = { .name = "qcom_rpm_reg", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rpm_of_match), }, }; diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 4c414ae109ae..d2e67c512195 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -179,7 +179,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) static struct platform_driver rc5t583_regulator_driver = { .driver = { .name = "rc5t583-regulator", - .owner = THIS_MODULE, }, .probe = rc5t583_regulator_probe, }; diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index e305416d7697..1ef296c41b2d 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -368,7 +368,6 @@ static struct platform_driver rk808_regulator_driver = { .probe = rk808_regulator_probe, .driver = { .name = "rk808-regulator", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 4acefa6b462e..5f4b7d3380d6 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -405,7 +405,6 @@ MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id); static struct platform_driver s2mpa01_pmic_driver = { .driver = { .name = "s2mpa01-pmic", - .owner = THIS_MODULE, }, .probe = s2mpa01_pmic_probe, .id_table = s2mpa01_pmic_id, diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index adab82d5279f..5248d36927ff 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -936,7 +936,6 @@ MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); static struct platform_driver s2mps11_pmic_driver = { .driver = { .name = "s2mps11-pmic", - .owner = THIS_MODULE, }, .probe = s2mps11_pmic_probe, .id_table = s2mps11_pmic_id, diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 0ab5cbeeb797..684bd9ff9e02 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -986,7 +986,6 @@ MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id); static struct platform_driver s5m8767_pmic_driver = { .driver = { .name = "s5m8767-pmic", - .owner = THIS_MODULE, }, .probe = s5m8767_pmic_probe, .id_table = s5m8767_pmic_id, diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c index a7e152696a02..0cc35b1ccdab 100644 --- a/drivers/regulator/stw481x-vmmc.c +++ b/drivers/regulator/stw481x-vmmc.c @@ -94,7 +94,6 @@ static const struct of_device_id stw481x_vmmc_match[] = { static struct platform_driver stw481x_vmmc_regulator_driver = { .driver = { .name = "stw481x-vmmc-regulator", - .owner = THIS_MODULE, .of_match_table = stw481x_vmmc_match, }, .probe = stw481x_vmmc_regulator_probe, diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index a2dabb575b97..340faf329fbb 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -891,7 +891,6 @@ static struct platform_driver ti_abb_driver = { .probe = ti_abb_probe, .driver = { .name = "ti_abb", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ti_abb_of_match), }, }; diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index c1e33a3d397b..3510b3e7330a 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -163,7 +163,6 @@ static int tps6105x_regulator_probe(struct platform_device *pdev) static struct platform_driver tps6105x_regulator_driver = { .driver = { .name = "tps6105x-regulator", - .owner = THIS_MODULE, }, .probe = tps6105x_regulator_probe, }; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 98e66ce26723..dad0bac09ecf 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -519,7 +519,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) static struct platform_driver tps6507x_pmic_driver = { .driver = { .name = "tps6507x-pmic", - .owner = THIS_MODULE, }, .probe = tps6507x_pmic_probe, }; diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index d5df1e9ad1da..5e1a67ade71f 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -507,7 +507,6 @@ static int tps65090_regulator_probe(struct platform_device *pdev) static struct platform_driver tps65090_regulator_driver = { .driver = { .name = "tps65090-pmic", - .owner = THIS_MODULE, }, .probe = tps65090_regulator_probe, }; diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index f0a40281b9c1..e2b97ac6a9fa 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -255,7 +255,6 @@ static int tps65218_regulator_probe(struct platform_device *pdev) static struct platform_driver tps65218_regulator_driver = { .driver = { .name = "tps65218-pmic", - .owner = THIS_MODULE, .of_match_table = tps65218_of_match, }, .probe = tps65218_regulator_probe, diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index ccbb9f150b4e..2852de05d64d 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -522,7 +522,6 @@ static int tps6586x_regulator_probe(struct platform_device *pdev) static struct platform_driver tps6586x_regulator_driver = { .driver = { .name = "tps6586x-regulator", - .owner = THIS_MODULE, }, .probe = tps6586x_regulator_probe, }; diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 18fc991175bc..e2cffe01b807 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1245,7 +1245,6 @@ static void tps65910_shutdown(struct platform_device *pdev) static struct platform_driver tps65910_driver = { .driver = { .name = "tps65910-pmic", - .owner = THIS_MODULE, }, .probe = tps65910_probe, .shutdown = tps65910_shutdown, diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 9cafaa0f9455..9503d5481a52 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -519,7 +519,6 @@ static int tps65912_probe(struct platform_device *pdev) static struct platform_driver tps65912_driver = { .driver = { .name = "tps65912-pmic", - .owner = THIS_MODULE, }, .probe = tps65912_probe, }; diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index 26aa6d9c308f..d4cc60ad18ae 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -746,7 +746,6 @@ static int tps80031_regulator_probe(struct platform_device *pdev) static struct platform_driver tps80031_regulator_driver = { .driver = { .name = "tps80031-pmic", - .owner = THIS_MODULE, }, .probe = tps80031_regulator_probe, }; diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 0b4f8660fdb4..00c49e7cb345 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1220,7 +1220,6 @@ static struct platform_driver twlreg_driver = { */ .driver = { .name = "twl_reg", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl_of_match), }, }; diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 02e7267ccf92..6ab78bdbe138 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c @@ -107,7 +107,6 @@ static struct platform_driver vexpress_regulator_driver = { .probe = vexpress_regulator_probe, .driver = { .name = DRVNAME, - .owner = THIS_MODULE, .of_match_table = vexpress_regulator_of_match, }, }; diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index 6ff95b045984..a6f1c7a9914f 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -338,7 +338,6 @@ static struct platform_driver regulator_virtual_consumer_driver = { .remove = regulator_virtual_remove, .driver = { .name = "reg-virt-consumer", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 0d88a82ab2a2..0d7e164a5e76 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -562,7 +562,6 @@ static struct platform_driver wm831x_buckv_driver = { .probe = wm831x_buckv_probe, .driver = { .name = "wm831x-buckv", - .owner = THIS_MODULE, }, }; @@ -689,7 +688,6 @@ static struct platform_driver wm831x_buckp_driver = { .probe = wm831x_buckp_probe, .driver = { .name = "wm831x-buckp", - .owner = THIS_MODULE, }, }; @@ -804,7 +802,6 @@ static struct platform_driver wm831x_boostp_driver = { .probe = wm831x_boostp_probe, .driver = { .name = "wm831x-boostp", - .owner = THIS_MODULE, }, }; @@ -880,7 +877,6 @@ static struct platform_driver wm831x_epe_driver = { .probe = wm831x_epe_probe, .driver = { .name = "wm831x-epe", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 72e385e76a9d..1e88391a1628 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -224,7 +224,6 @@ static struct platform_driver wm831x_isink_driver = { .probe = wm831x_isink_probe, .driver = { .name = "wm831x-isink", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index eca0eeb78acd..7ae2dc82f636 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -307,7 +307,6 @@ static struct platform_driver wm831x_gp_ldo_driver = { .probe = wm831x_gp_ldo_probe, .driver = { .name = "wm831x-ldo", - .owner = THIS_MODULE, }, }; @@ -516,7 +515,6 @@ static struct platform_driver wm831x_aldo_driver = { .probe = wm831x_aldo_probe, .driver = { .name = "wm831x-aldo", - .owner = THIS_MODULE, }, }; @@ -650,7 +648,6 @@ static struct platform_driver wm831x_alive_ldo_driver = { .probe = wm831x_alive_ldo_probe, .driver = { .name = "wm831x-alive-ldo", - .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index c24346db8a71..fdfd37aefaf6 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -185,7 +185,6 @@ static struct platform_driver wm8994_ldo_driver = { .probe = wm8994_ldo_probe, .driver = { .name = "wm8994-ldo", - .owner = THIS_MODULE, }, }; -- GitLab From 51aa31b49fa0be1062c44eb74f242dfc4ae7c496 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:29 +0200 Subject: [PATCH 0795/9457] remoteproc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/remoteproc/da8xx_remoteproc.c | 1 - drivers/remoteproc/omap_remoteproc.c | 1 - drivers/remoteproc/ste_modem_rproc.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/remoteproc/da8xx_remoteproc.c b/drivers/remoteproc/da8xx_remoteproc.c index 3841b9813109..89fd057e5f1d 100644 --- a/drivers/remoteproc/da8xx_remoteproc.c +++ b/drivers/remoteproc/da8xx_remoteproc.c @@ -300,7 +300,6 @@ static struct platform_driver da8xx_rproc_driver = { .remove = da8xx_rproc_remove, .driver = { .name = "davinci-rproc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 51689721ea7a..a0128cd13ef8 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -228,7 +228,6 @@ static struct platform_driver omap_rproc_driver = { .remove = omap_rproc_remove, .driver = { .name = "omap-rproc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c index c4ac9104dd8e..16b7b7bd805b 100644 --- a/drivers/remoteproc/ste_modem_rproc.c +++ b/drivers/remoteproc/ste_modem_rproc.c @@ -331,7 +331,6 @@ static int sproc_probe(struct platform_device *pdev) static struct platform_driver sproc_driver = { .driver = { .name = SPROC_MODEM_NAME, - .owner = THIS_MODULE, }, .probe = sproc_probe, .remove = sproc_drv_remove, -- GitLab From 569d5e911b36102ed3398537d90a4e0cf11b852f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:30 +0200 Subject: [PATCH 0796/9457] reset: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/reset/reset-socfpga.c | 1 - drivers/reset/reset-sunxi.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index 79c32ca84ef1..9181bea64d7a 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -135,7 +135,6 @@ static struct platform_driver socfpga_reset_driver = { .remove = socfpga_reset_remove, .driver = { .name = "socfpga-reset", - .owner = THIS_MODULE, .of_match_table = socfpga_reset_dt_ids, }, }; diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index a94e7a7820b4..eebc52cb6984 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -179,7 +179,6 @@ static struct platform_driver sunxi_reset_driver = { .remove = sunxi_reset_remove, .driver = { .name = "sunxi-reset", - .owner = THIS_MODULE, .of_match_table = sunxi_reset_dt_ids, }, }; -- GitLab From d373860d70c6d32f52ea1cb8e6633478dfb2180d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:30 +0200 Subject: [PATCH 0797/9457] reset: sti: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/reset/sti/reset-stih415.c | 1 - drivers/reset/sti/reset-stih416.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/reset/sti/reset-stih415.c b/drivers/reset/sti/reset-stih415.c index c93fd260447e..8dad603d863c 100644 --- a/drivers/reset/sti/reset-stih415.c +++ b/drivers/reset/sti/reset-stih415.c @@ -101,7 +101,6 @@ static struct platform_driver stih415_reset_driver = { .probe = syscfg_reset_probe, .driver = { .name = "reset-stih415", - .owner = THIS_MODULE, .of_match_table = stih415_reset_match, }, }; diff --git a/drivers/reset/sti/reset-stih416.c b/drivers/reset/sti/reset-stih416.c index 5fc987076a90..79aed70a26c0 100644 --- a/drivers/reset/sti/reset-stih416.c +++ b/drivers/reset/sti/reset-stih416.c @@ -132,7 +132,6 @@ static struct platform_driver stih416_reset_driver = { .probe = syscfg_reset_probe, .driver = { .name = "reset-stih416", - .owner = THIS_MODULE, .of_match_table = stih416_reset_match, }, }; -- GitLab From 0929ae376ef32591a5f13870a703efc2901bfab9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:31 +0200 Subject: [PATCH 0798/9457] rtc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/rtc/rtc-88pm80x.c | 1 - drivers/rtc/rtc-88pm860x.c | 1 - drivers/rtc/rtc-ab3100.c | 1 - drivers/rtc/rtc-ab8500.c | 1 - drivers/rtc/rtc-at32ap700x.c | 1 - drivers/rtc/rtc-at91rm9200.c | 1 - drivers/rtc/rtc-at91sam9.c | 1 - drivers/rtc/rtc-au1xxx.c | 1 - drivers/rtc/rtc-bfin.c | 1 - drivers/rtc/rtc-bq4802.c | 1 - drivers/rtc/rtc-coh901331.c | 1 - drivers/rtc/rtc-da9052.c | 1 - drivers/rtc/rtc-da9055.c | 1 - drivers/rtc/rtc-da9063.c | 1 - drivers/rtc/rtc-davinci.c | 1 - drivers/rtc/rtc-dm355evm.c | 1 - drivers/rtc/rtc-ds1216.c | 1 - drivers/rtc/rtc-ds1286.c | 1 - drivers/rtc/rtc-ds1302.c | 1 - drivers/rtc/rtc-ds1511.c | 1 - drivers/rtc/rtc-ds1553.c | 1 - drivers/rtc/rtc-ds1742.c | 1 - drivers/rtc/rtc-ds2404.c | 1 - drivers/rtc/rtc-efi.c | 1 - drivers/rtc/rtc-ep93xx.c | 1 - drivers/rtc/rtc-generic.c | 1 - drivers/rtc/rtc-hid-sensor-time.c | 1 - drivers/rtc/rtc-imxdi.c | 1 - drivers/rtc/rtc-jz4740.c | 1 - drivers/rtc/rtc-lp8788.c | 1 - drivers/rtc/rtc-lpc32xx.c | 1 - drivers/rtc/rtc-ls1x.c | 1 - drivers/rtc/rtc-m48t35.c | 1 - drivers/rtc/rtc-m48t59.c | 1 - drivers/rtc/rtc-m48t86.c | 1 - drivers/rtc/rtc-max77686.c | 1 - drivers/rtc/rtc-max77802.c | 1 - drivers/rtc/rtc-max8907.c | 1 - drivers/rtc/rtc-max8925.c | 1 - drivers/rtc/rtc-max8997.c | 1 - drivers/rtc/rtc-max8998.c | 1 - drivers/rtc/rtc-mc13xxx.c | 1 - drivers/rtc/rtc-moxart.c | 1 - drivers/rtc/rtc-mpc5121.c | 1 - drivers/rtc/rtc-msm6242.c | 1 - drivers/rtc/rtc-mv.c | 1 - drivers/rtc/rtc-mxc.c | 1 - drivers/rtc/rtc-nuc900.c | 1 - drivers/rtc/rtc-omap.c | 1 - drivers/rtc/rtc-palmas.c | 1 - drivers/rtc/rtc-pcap.c | 1 - drivers/rtc/rtc-pm8xxx.c | 1 - drivers/rtc/rtc-ps3.c | 1 - drivers/rtc/rtc-puv3.c | 1 - drivers/rtc/rtc-rc5t583.c | 1 - drivers/rtc/rtc-rp5c01.c | 1 - drivers/rtc/rtc-rs5c313.c | 1 - drivers/rtc/rtc-s3c.c | 1 - drivers/rtc/rtc-s5m.c | 1 - drivers/rtc/rtc-sh.c | 1 - drivers/rtc/rtc-sirfsoc.c | 1 - drivers/rtc/rtc-snvs.c | 1 - drivers/rtc/rtc-starfire.c | 1 - drivers/rtc/rtc-stk17ta8.c | 1 - drivers/rtc/rtc-stmp3xxx.c | 1 - drivers/rtc/rtc-sun4v.c | 1 - drivers/rtc/rtc-sunxi.c | 1 - drivers/rtc/rtc-tegra.c | 1 - drivers/rtc/rtc-test.c | 1 - drivers/rtc/rtc-tile.c | 1 - drivers/rtc/rtc-tps6586x.c | 1 - drivers/rtc/rtc-tps65910.c | 1 - drivers/rtc/rtc-tps80031.c | 1 - drivers/rtc/rtc-twl.c | 1 - drivers/rtc/rtc-tx4939.c | 1 - drivers/rtc/rtc-v3020.c | 1 - drivers/rtc/rtc-vr41xx.c | 1 - drivers/rtc/rtc-vt8500.c | 1 - drivers/rtc/rtc-xgene.c | 1 - 79 files changed, 79 deletions(-) diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index 0916089c7c3e..7df0579d9852 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -352,7 +352,6 @@ static int pm80x_rtc_remove(struct platform_device *pdev) static struct platform_driver pm80x_rtc_driver = { .driver = { .name = "88pm80x-rtc", - .owner = THIS_MODULE, .pm = &pm80x_rtc_pm_ops, }, .probe = pm80x_rtc_probe, diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 0c6add1a38dc..19e53b3b8e00 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -448,7 +448,6 @@ static SIMPLE_DEV_PM_OPS(pm860x_rtc_pm_ops, pm860x_rtc_suspend, pm860x_rtc_resum static struct platform_driver pm860x_rtc_driver = { .driver = { .name = "88pm860x-rtc", - .owner = THIS_MODULE, .pm = &pm860x_rtc_pm_ops, }, .probe = pm860x_rtc_probe, diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index ff435343ba9f..1d0340fdb820 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -243,7 +243,6 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) static struct platform_driver ab3100_rtc_driver = { .driver = { .name = "ab3100-rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 727e2f5d14d9..43c09ad5112b 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -517,7 +517,6 @@ static int ab8500_rtc_remove(struct platform_device *pdev) static struct platform_driver ab8500_rtc_driver = { .driver = { .name = "ab8500-rtc", - .owner = THIS_MODULE, }, .probe = ab8500_rtc_probe, .remove = ab8500_rtc_remove, diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index aee3387fb099..d618d6c7ef93 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -277,7 +277,6 @@ static struct platform_driver at32_rtc_driver = { .remove = __exit_p(at32_rtc_remove), .driver = { .name = "at32ap700x_rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 44fe83ee9bee..70a5d94cc766 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -491,7 +491,6 @@ static struct platform_driver at91_rtc_driver = { .shutdown = at91_rtc_shutdown, .driver = { .name = "at91_rtc", - .owner = THIS_MODULE, .pm = &at91_rtc_pm_ops, .of_match_table = of_match_ptr(at91_rtc_dt_ids), }, diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 596374304532..dcf211b941a5 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -446,7 +446,6 @@ static struct platform_driver at91_rtc_driver = { .shutdown = at91_rtc_shutdown, .driver = { .name = "rtc-at91sam9", - .owner = THIS_MODULE, .pm = &at91_rtc_pm_ops, }, }; diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index fd25e2374d4e..84d6e026784d 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -117,7 +117,6 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) static struct platform_driver au1xrtc_driver = { .driver = { .name = "rtc-au1xxx", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index fe4bdb06a55a..3d44b11721ea 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -434,7 +434,6 @@ static SIMPLE_DEV_PM_OPS(bfin_rtc_pm_ops, bfin_rtc_suspend, bfin_rtc_resume); static struct platform_driver bfin_rtc_driver = { .driver = { .name = "rtc-bfin", - .owner = THIS_MODULE, .pm = &bfin_rtc_pm_ops, }, .probe = bfin_rtc_probe, diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index fc0ff87aa5df..bd170cb3361c 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c @@ -192,7 +192,6 @@ MODULE_ALIAS("platform:rtc-bq4802"); static struct platform_driver bq4802_driver = { .driver = { .name = "rtc-bq4802", - .owner = THIS_MODULE, }, .probe = bq4802_probe, }; diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 869cae273799..56343b2fbc68 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -267,7 +267,6 @@ static const struct of_device_id coh901331_dt_match[] = { static struct platform_driver coh901331_driver = { .driver = { .name = "rtc-coh901331", - .owner = THIS_MODULE, .pm = &coh901331_pm_ops, .of_match_table = coh901331_dt_match, }, diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index e5c9486cf452..613c43b7e9ae 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -265,7 +265,6 @@ static struct platform_driver da9052_rtc_driver = { .probe = da9052_rtc_probe, .driver = { .name = "da9052-rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c index a825491331c8..7ec0872d5e3b 100644 --- a/drivers/rtc/rtc-da9055.c +++ b/drivers/rtc/rtc-da9055.c @@ -391,7 +391,6 @@ static struct platform_driver da9055_rtc_driver = { .probe = da9055_rtc_probe, .driver = { .name = "da9055-rtc", - .owner = THIS_MODULE, .pm = &da9055_rtc_pm_ops, }, }; diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 731ed1a97f59..7ffc5707f8b9 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -341,7 +341,6 @@ static struct platform_driver da9063_rtc_driver = { .probe = da9063_rtc_probe, .driver = { .name = DA9063_DRVNAME_RTC, - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index c0a3b59f65a2..c84f46168a52 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -550,7 +550,6 @@ static struct platform_driver davinci_rtc_driver = { .remove = __exit_p(davinci_rtc_remove), .driver = { .name = "rtc_davinci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c index 1aca08394c47..94067f8eeb10 100644 --- a/drivers/rtc/rtc-dm355evm.c +++ b/drivers/rtc/rtc-dm355evm.c @@ -146,7 +146,6 @@ static int dm355evm_rtc_probe(struct platform_device *pdev) static struct platform_driver rtc_dm355evm_driver = { .probe = dm355evm_rtc_probe, .driver = { - .owner = THIS_MODULE, .name = "rtc-dm355evm", }, }; diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 9c04fd2bc209..d16f550897b8 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -170,7 +170,6 @@ static int __init ds1216_rtc_probe(struct platform_device *pdev) static struct platform_driver ds1216_rtc_platform_driver = { .driver = { .name = "rtc-ds1216", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 50e109b78252..2fe537f4e2bd 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -356,7 +356,6 @@ static int ds1286_probe(struct platform_device *pdev) static struct platform_driver ds1286_platform_driver = { .driver = { .name = "rtc-ds1286", - .owner = THIS_MODULE, }, .probe = ds1286_probe, }; diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 07e8d79b4a09..6bef7a5233c4 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -244,7 +244,6 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) static struct platform_driver ds1302_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index b13d1399b81a..7415c2b4d6e8 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -561,7 +561,6 @@ static struct platform_driver ds1511_rtc_driver = { .remove = ds1511_rtc_remove, .driver = { .name = "ds1511", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index ab56893aac73..a24e091bcb41 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -351,7 +351,6 @@ static struct platform_driver ds1553_rtc_driver = { .remove = ds1553_rtc_remove, .driver = { .name = "rtc-ds1553", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 9822715db8ba..0f8d8ace1515 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -230,7 +230,6 @@ static struct platform_driver ds1742_rtc_driver = { .remove = ds1742_rtc_remove, .driver = { .name = "rtc-ds1742", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ds1742_rtc_of_match), }, }; diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index fc209dc4e245..7885edd3d507 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c @@ -274,7 +274,6 @@ static struct platform_driver rtc_device_driver = { .remove = rtc_remove, .driver = { .name = "ds2404", - .owner = THIS_MODULE, }, }; module_platform_driver(rtc_device_driver); diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c384fec6d173..3d5b8168268e 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -226,7 +226,6 @@ static int __init efi_rtc_probe(struct platform_device *dev) static struct platform_driver efi_rtc_driver = { .driver = { .name = "rtc-efi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 5e4f5dc40ba5..de325d68c7e4 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -174,7 +174,6 @@ static int ep93xx_rtc_remove(struct platform_device *pdev) static struct platform_driver ep93xx_rtc_driver = { .driver = { .name = "ep93xx-rtc", - .owner = THIS_MODULE, }, .probe = ep93xx_rtc_probe, .remove = ep93xx_rtc_remove, diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c index 9b6725ebbfb2..e782ebd719b2 100644 --- a/drivers/rtc/rtc-generic.c +++ b/drivers/rtc/rtc-generic.c @@ -51,7 +51,6 @@ static int __init generic_rtc_probe(struct platform_device *dev) static struct platform_driver generic_rtc_driver = { .driver = { .name = "rtc-generic", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index 965a9da70867..ae7c2ba440cf 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -331,7 +331,6 @@ static struct platform_driver hid_time_platform_driver = { .id_table = hid_time_ids, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, .probe = hid_time_probe, .remove = hid_time_remove, diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index cd741c77e085..42f5570f42f8 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -499,7 +499,6 @@ MODULE_DEVICE_TABLE(of, dryice_dt_ids); static struct platform_driver dryice_rtc_driver = { .driver = { .name = "imxdi_rtc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(dryice_dt_ids), }, .remove = __exit_p(dryice_rtc_remove), diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 08f5160fb6d4..b2bcfc0bf2e5 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -299,7 +299,6 @@ static struct platform_driver jz4740_rtc_driver = { .probe = jz4740_rtc_probe, .driver = { .name = "jz4740-rtc", - .owner = THIS_MODULE, .pm = JZ4740_RTC_PM_OPS, }, }; diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c index 4ff6c73253b3..e20e7bd822e0 100644 --- a/drivers/rtc/rtc-lp8788.c +++ b/drivers/rtc/rtc-lp8788.c @@ -316,7 +316,6 @@ static struct platform_driver lp8788_rtc_driver = { .probe = lp8788_rtc_probe, .driver = { .name = LP8788_DEV_RTC, - .owner = THIS_MODULE, }, }; module_platform_driver(lp8788_rtc_driver); diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index f130c08c98f8..f923f7324788 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -379,7 +379,6 @@ static struct platform_driver lpc32xx_rtc_driver = { .remove = lpc32xx_rtc_remove, .driver = { .name = RTC_NAME, - .owner = THIS_MODULE, .pm = LPC32XX_RTC_PM_OPS, .of_match_table = of_match_ptr(lpc32xx_rtc_match), }, diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c index 682ecb094839..8445e564094a 100644 --- a/drivers/rtc/rtc-ls1x.c +++ b/drivers/rtc/rtc-ls1x.c @@ -188,7 +188,6 @@ static int ls1x_rtc_probe(struct platform_device *pdev) static struct platform_driver ls1x_rtc_driver = { .driver = { .name = "ls1x-rtc", - .owner = THIS_MODULE, }, .probe = ls1x_rtc_probe, }; diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index 411adb3f86a1..c62b51217ecf 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -181,7 +181,6 @@ static int m48t35_probe(struct platform_device *pdev) static struct platform_driver m48t35_platform_driver = { .driver = { .name = "rtc-m48t35", - .owner = THIS_MODULE, }, .probe = m48t35_probe, }; diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 11880c1e9dac..90abb5bd589c 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -504,7 +504,6 @@ MODULE_ALIAS("platform:rtc-m48t59"); static struct platform_driver m48t59_rtc_driver = { .driver = { .name = "rtc-m48t59", - .owner = THIS_MODULE, }, .probe = m48t59_rtc_probe, .remove = m48t59_rtc_remove, diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 32f64c942621..a17b7a3ceece 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -169,7 +169,6 @@ static int m48t86_rtc_probe(struct platform_device *dev) static struct platform_driver m48t86_rtc_platform_driver = { .driver = { .name = "rtc-m48t86", - .owner = THIS_MODULE, }, .probe = m48t86_rtc_probe, }; diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index cf73e969c8cc..9d71328e59b9 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -513,7 +513,6 @@ static const struct platform_device_id rtc_id[] = { static struct platform_driver max77686_rtc_driver = { .driver = { .name = "max77686-rtc", - .owner = THIS_MODULE, .pm = &max77686_rtc_pm_ops, }, .probe = max77686_rtc_probe, diff --git a/drivers/rtc/rtc-max77802.c b/drivers/rtc/rtc-max77802.c index 566471335b33..7f8adf8d6feb 100644 --- a/drivers/rtc/rtc-max77802.c +++ b/drivers/rtc/rtc-max77802.c @@ -488,7 +488,6 @@ static const struct platform_device_id rtc_id[] = { static struct platform_driver max77802_rtc_driver = { .driver = { .name = "max77802-rtc", - .owner = THIS_MODULE, .pm = &max77802_rtc_pm_ops, }, .probe = max77802_rtc_probe, diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c index 3032178bd9e6..19c29b72598d 100644 --- a/drivers/rtc/rtc-max8907.c +++ b/drivers/rtc/rtc-max8907.c @@ -215,7 +215,6 @@ static int max8907_rtc_probe(struct platform_device *pdev) static struct platform_driver max8907_rtc_driver = { .driver = { .name = "max8907-rtc", - .owner = THIS_MODULE, }, .probe = max8907_rtc_probe, }; diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 951d1a78e190..16d129a0bb3b 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -314,7 +314,6 @@ static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops, max8925_rtc_suspend, max8925_rtc_re static struct platform_driver max8925_rtc_driver = { .driver = { .name = "max8925-rtc", - .owner = THIS_MODULE, .pm = &max8925_rtc_pm_ops, }, .probe = max8925_rtc_probe, diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index 0777c01b58e0..67fbe559d535 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c @@ -523,7 +523,6 @@ static const struct platform_device_id rtc_id[] = { static struct platform_driver max8997_rtc_driver = { .driver = { .name = "max8997-rtc", - .owner = THIS_MODULE, }, .probe = max8997_rtc_probe, .shutdown = max8997_rtc_shutdown, diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index f098ad8382de..5726ef7bd56e 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -313,7 +313,6 @@ static const struct platform_device_id max8998_rtc_id[] = { static struct platform_driver max8998_rtc_driver = { .driver = { .name = "max8998-rtc", - .owner = THIS_MODULE, }, .probe = max8998_rtc_probe, .id_table = max8998_rtc_id, diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 0765606a2d14..5bce904b7ee6 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -370,7 +370,6 @@ static struct platform_driver mc13xxx_rtc_driver = { .remove = mc13xxx_rtc_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c index c31846238871..73759c9a4527 100644 --- a/drivers/rtc/rtc-moxart.c +++ b/drivers/rtc/rtc-moxart.c @@ -317,7 +317,6 @@ static struct platform_driver moxart_rtc_driver = { .probe = moxart_rtc_probe, .driver = { .name = "moxart-rtc", - .owner = THIS_MODULE, .of_match_table = moxart_rtc_match, }, }; diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 3b965ad6f4d5..1767e18d5bd4 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -411,7 +411,6 @@ static const struct of_device_id mpc5121_rtc_match[] = { static struct platform_driver mpc5121_rtc_driver = { .driver = { .name = "mpc5121-rtc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mpc5121_rtc_match), }, .probe = mpc5121_rtc_probe, diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index 426cb5189daa..9bf877bdf836 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -225,7 +225,6 @@ static int __init msm6242_rtc_probe(struct platform_device *pdev) static struct platform_driver msm6242_rtc_driver = { .driver = { .name = "rtc-msm6242", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 6aaec2fc7c0d..423762241042 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -329,7 +329,6 @@ static struct platform_driver mv_rtc_driver = { .remove = __exit_p(mv_rtc_remove), .driver = { .name = "rtc-mv", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rtc_mv_of_match_table), }, }; diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 419874fefa4b..3c3f8d10ab43 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -489,7 +489,6 @@ static struct platform_driver mxc_rtc_driver = { .driver = { .name = "mxc_rtc", .pm = &mxc_rtc_pm_ops, - .owner = THIS_MODULE, }, .id_table = imx_rtc_devtype, .probe = mxc_rtc_probe, diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index a53da0958e95..09fc1c19f0df 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -262,7 +262,6 @@ static int __init nuc900_rtc_probe(struct platform_device *pdev) static struct platform_driver nuc900_rtc_driver = { .driver = { .name = "nuc900-rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 21142e6574a9..ae444a8bd602 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -569,7 +569,6 @@ static struct platform_driver omap_rtc_driver = { .shutdown = omap_rtc_shutdown, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &omap_rtc_pm_ops, .of_match_table = omap_rtc_of_match, }, diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c index 4dfe2d793fa3..3b01d567496d 100644 --- a/drivers/rtc/rtc-palmas.c +++ b/drivers/rtc/rtc-palmas.c @@ -363,7 +363,6 @@ static struct platform_driver palmas_rtc_driver = { .probe = palmas_rtc_probe, .remove = palmas_rtc_remove, .driver = { - .owner = THIS_MODULE, .name = "palmas-rtc", .pm = &palmas_rtc_pm_ops, .of_match_table = of_match_ptr(of_palmas_rtc_match), diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index 40b5c630bc7d..c4433240d8a9 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -184,7 +184,6 @@ static struct platform_driver pcap_rtc_driver = { .remove = __exit_p(pcap_rtc_remove), .driver = { .name = "pcap-rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 197699f358c7..26a5351c0a3d 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -485,7 +485,6 @@ static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, .driver = { .name = "rtc-pm8xxx", - .owner = THIS_MODULE, .pm = &pm8xxx_rtc_pm_ops, .of_match_table = pm8xxx_id_table, }, diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c index 554ada5e9b76..6a8f5d758eac 100644 --- a/drivers/rtc/rtc-ps3.c +++ b/drivers/rtc/rtc-ps3.c @@ -74,7 +74,6 @@ static int __init ps3_rtc_probe(struct platform_device *dev) static struct platform_driver ps3_rtc_driver = { .driver = { .name = "rtc-ps3", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index 1cff2a21db67..c0a6e638c672 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -328,7 +328,6 @@ static struct platform_driver puv3_rtc_driver = { .remove = puv3_rtc_remove, .driver = { .name = "PKUnity-v3-RTC", - .owner = THIS_MODULE, .pm = &puv3_rtc_pm_ops, } }; diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index e53e9b1c69b3..f28d57788951 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c @@ -310,7 +310,6 @@ static struct platform_driver rc5t583_rtc_driver = { .probe = rc5t583_rtc_probe, .remove = rc5t583_rtc_remove, .driver = { - .owner = THIS_MODULE, .name = "rtc-rc5t583", .pm = &rc5t583_rtc_pm_ops, }, diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 89d073679267..b548551f385c 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -273,7 +273,6 @@ static int __exit rp5c01_rtc_remove(struct platform_device *dev) static struct platform_driver rp5c01_rtc_driver = { .driver = { .name = "rtc-rp5c01", - .owner = THIS_MODULE, }, .remove = __exit_p(rp5c01_rtc_remove), }; diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index 68f7856422f1..5f48167c802a 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c @@ -381,7 +381,6 @@ static int rs5c313_rtc_probe(struct platform_device *pdev) static struct platform_driver rs5c313_rtc_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = rs5c313_rtc_probe, }; diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a6b1252c9941..c44e5f2767b4 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -894,7 +894,6 @@ static struct platform_driver s3c_rtc_driver = { .remove = s3c_rtc_remove, .driver = { .name = "s3c-rtc", - .owner = THIS_MODULE, .pm = &s3c_rtc_pm_ops, .of_match_table = of_match_ptr(s3c_rtc_dt_match), }, diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 8754c33361e8..b5e7c4670205 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -837,7 +837,6 @@ static const struct platform_device_id s5m_rtc_id[] = { static struct platform_driver s5m_rtc_driver = { .driver = { .name = "s5m-rtc", - .owner = THIS_MODULE, .pm = &s5m_rtc_pm_ops, }, .probe = s5m_rtc_probe, diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index d0d2b047658b..2b81dd4baf17 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -782,7 +782,6 @@ static SIMPLE_DEV_PM_OPS(sh_rtc_pm_ops, sh_rtc_suspend, sh_rtc_resume); static struct platform_driver sh_rtc_platform_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &sh_rtc_pm_ops, }, .remove = __exit_p(sh_rtc_remove), diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 76e38007ba90..52db89e25959 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -408,7 +408,6 @@ static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops, static struct platform_driver sirfsoc_rtc_driver = { .driver = { .name = "sirfsoc-rtc", - .owner = THIS_MODULE, .pm = &sirfsoc_rtc_pm_ops, .of_match_table = sirfsoc_rtc_of_match, }, diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index fa384fe28988..f04c378b781a 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -327,7 +327,6 @@ MODULE_DEVICE_TABLE(of, snvs_dt_ids); static struct platform_driver snvs_rtc_driver = { .driver = { .name = "snvs_rtc", - .owner = THIS_MODULE, .pm = &snvs_rtc_pm_ops, .of_match_table = snvs_dt_ids, }, diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c index f7d8a6db8078..83a057a03060 100644 --- a/drivers/rtc/rtc-starfire.c +++ b/drivers/rtc/rtc-starfire.c @@ -54,7 +54,6 @@ static int __init starfire_rtc_probe(struct platform_device *pdev) static struct platform_driver starfire_rtc_driver = { .driver = { .name = "rtc-starfire", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 35ed49ea1f81..0e93b714ee41 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -358,7 +358,6 @@ static struct platform_driver stk17ta8_rtc_driver = { .remove = stk17ta8_rtc_remove, .driver = { .name = "stk17ta8", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index ea96492357b0..2939cdcb2688 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -341,7 +341,6 @@ static struct platform_driver stmp3xxx_rtcdrv = { .remove = stmp3xxx_rtc_remove, .driver = { .name = "stmp3xxx-rtc", - .owner = THIS_MODULE, .pm = &stmp3xxx_rtc_pm_ops, .of_match_table = rtc_dt_ids, }, diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c index bc97ff91341d..7c696c12f28f 100644 --- a/drivers/rtc/rtc-sun4v.c +++ b/drivers/rtc/rtc-sun4v.c @@ -95,7 +95,6 @@ static int __init sun4v_rtc_probe(struct platform_device *pdev) static struct platform_driver sun4v_rtc_driver = { .driver = { .name = "rtc-sun4v", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index b6f21f73d508..6e678fa4dfaf 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c @@ -511,7 +511,6 @@ static struct platform_driver sunxi_rtc_driver = { .remove = sunxi_rtc_remove, .driver = { .name = "sunxi-rtc", - .owner = THIS_MODULE, .of_match_table = sunxi_rtc_dt_ids, }, }; diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 76af92ad5a8a..d948277057d8 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -420,7 +420,6 @@ static struct platform_driver tegra_rtc_driver = { .shutdown = tegra_rtc_shutdown, .driver = { .name = "tegra_rtc", - .owner = THIS_MODULE, .of_match_table = tegra_rtc_dt_match, .pm = &tegra_rtc_pm_ops, }, diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 6599c20bc454..8f86fa91de1a 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -129,7 +129,6 @@ static struct platform_driver test_driver = { .remove = test_remove, .driver = { .name = "rtc-test", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c index ff9632eb79f2..0b60867d8390 100644 --- a/drivers/rtc/rtc-tile.c +++ b/drivers/rtc/rtc-tile.c @@ -94,7 +94,6 @@ static int tile_rtc_probe(struct platform_device *dev) static struct platform_driver tile_rtc_platform_driver = { .driver = { .name = "rtc-tile", - .owner = THIS_MODULE, }, .probe = tile_rtc_probe, }; diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 426901cef14f..3b6ce80a769c 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -337,7 +337,6 @@ static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_rtc_suspend, static struct platform_driver tps6586x_rtc_driver = { .driver = { .name = "tps6586x-rtc", - .owner = THIS_MODULE, .pm = &tps6586x_pm_ops, }, .probe = tps6586x_rtc_probe, diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 2583349fbde5..f42aa2b2dcba 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -326,7 +326,6 @@ static struct platform_driver tps65910_rtc_driver = { .probe = tps65910_rtc_probe, .remove = tps65910_rtc_remove, .driver = { - .owner = THIS_MODULE, .name = "tps65910-rtc", .pm = &tps65910_rtc_pm_ops, }, diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c index 3e400dce2d06..27e254cde715 100644 --- a/drivers/rtc/rtc-tps80031.c +++ b/drivers/rtc/rtc-tps80031.c @@ -324,7 +324,6 @@ static SIMPLE_DEV_PM_OPS(tps80031_pm_ops, tps80031_rtc_suspend, static struct platform_driver tps80031_rtc_driver = { .driver = { .name = "tps80031-rtc", - .owner = THIS_MODULE, .pm = &tps80031_pm_ops, }, .probe = tps80031_rtc_probe, diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 1915464e4cd6..5baea3f54926 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -608,7 +608,6 @@ static struct platform_driver twl4030rtc_driver = { .remove = twl_rtc_remove, .shutdown = twl_rtc_shutdown, .driver = { - .owner = THIS_MODULE, .name = "twl_rtc", .pm = &twl_rtc_pm_ops, .of_match_table = of_match_ptr(twl_rtc_of_match), diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 2e678c681b13..cb7f94ede516 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -287,7 +287,6 @@ static struct platform_driver tx4939_rtc_driver = { .remove = __exit_p(tx4939_rtc_remove), .driver = { .name = "tx4939rtc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 25222cdccdc6..bfbfa7ed7bbf 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c @@ -382,7 +382,6 @@ static struct platform_driver rtc_device_driver = { .remove = rtc_remove, .driver = { .name = "v3020", - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 88c9c92e89fd..f64c282275b3 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -375,7 +375,6 @@ static struct platform_driver rtc_platform_driver = { .probe = rtc_probe, .driver = { .name = rtc_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 051da968da6d..a58b6d17e6f0 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -277,7 +277,6 @@ static struct platform_driver vt8500_rtc_driver = { .remove = vt8500_rtc_remove, .driver = { .name = "vt8500-rtc", - .owner = THIS_MODULE, .of_match_table = wmt_dt_ids, }, }; diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index 14129cc85bdb..65b432a096fe 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c @@ -264,7 +264,6 @@ static struct platform_driver xgene_rtc_driver = { .probe = xgene_rtc_probe, .remove = xgene_rtc_remove, .driver = { - .owner = THIS_MODULE, .name = "xgene-rtc", .pm = &xgene_rtc_pm_ops, .of_match_table = of_match_ptr(xgene_rtc_of_match), -- GitLab From 1cd5ad7eefbcec1f1eba5d4be80385ce1a827f21 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:31 +0200 Subject: [PATCH 0799/9457] s390: block: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/s390/block/dcssblk.c | 1 - drivers/s390/block/xpram.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 0f471750327e..b550c8c8d010 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -1003,7 +1003,6 @@ static const struct dev_pm_ops dcssblk_pm_ops = { static struct platform_driver dcssblk_pdrv = { .driver = { .name = "dcssblk", - .owner = THIS_MODULE, .pm = &dcssblk_pm_ops, }, }; diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 9e0de9c9a6fc..7d4e9397ac31 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -417,7 +417,6 @@ static const struct dev_pm_ops xpram_pm_ops = { static struct platform_driver xpram_pdrv = { .driver = { .name = XPRAM_NAME, - .owner = THIS_MODULE, .pm = &xpram_pm_ops, }, }; -- GitLab From f3326ec8a426c73a26dfcd374a463ea2b0f66b52 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:32 +0200 Subject: [PATCH 0800/9457] s390: char: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/s390/char/monwriter.c | 1 - drivers/s390/char/sclp.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 668b32b0dc1d..9b5d1138b2e2 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -334,7 +334,6 @@ static const struct dev_pm_ops monwriter_pm_ops = { static struct platform_driver monwriter_pdrv = { .driver = { .name = "monwriter", - .owner = THIS_MODULE, .pm = &monwriter_pm_ops, }, }; diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index c316051d9bda..41ba56d2e752 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -1167,7 +1167,6 @@ static const struct attribute_group *sclp_drv_attr_groups[] = { static struct platform_driver sclp_pdrv = { .driver = { .name = "sclp", - .owner = THIS_MODULE, .pm = &sclp_pm_ops, .groups = sclp_drv_attr_groups, }, -- GitLab From 7cafb31ca4e85fa4c522cecf917e86e258cfbcaa Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:32 +0200 Subject: [PATCH 0801/9457] sbus: char: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/sbus/char/bbc_i2c.c | 1 - drivers/sbus/char/display7seg.c | 1 - drivers/sbus/char/envctrl.c | 1 - drivers/sbus/char/flash.c | 1 - drivers/sbus/char/uctrl.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 812b5f0361b6..129967ad345d 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -413,7 +413,6 @@ MODULE_DEVICE_TABLE(of, bbc_i2c_match); static struct platform_driver bbc_i2c_driver = { .driver = { .name = "bbc_i2c", - .owner = THIS_MODULE, .of_match_table = bbc_i2c_match, }, .probe = bbc_i2c_probe, diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 2b0ce7c350ee..33fbe8249fd5 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -263,7 +263,6 @@ MODULE_DEVICE_TABLE(of, d7s_match); static struct platform_driver d7s_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = d7s_match, }, .probe = d7s_probe, diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index af15a2fdab5e..e244cf3d9ec8 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1130,7 +1130,6 @@ MODULE_DEVICE_TABLE(of, envctrl_match); static struct platform_driver envctrl_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = envctrl_match, }, .probe = envctrl_probe, diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 25c738e9ef19..206ef4232adf 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -207,7 +207,6 @@ MODULE_DEVICE_TABLE(of, flash_match); static struct platform_driver flash_driver = { .driver = { .name = "flash", - .owner = THIS_MODULE, .of_match_table = flash_match, }, .probe = flash_probe, diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index b7acafc85099..57696fc0b482 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -425,7 +425,6 @@ MODULE_DEVICE_TABLE(of, uctrl_match); static struct platform_driver uctrl_driver = { .driver = { .name = "uctrl", - .owner = THIS_MODULE, .of_match_table = uctrl_match, }, .probe = uctrl_probe, -- GitLab From b36069c833d9440774d5daab143ec15ea026f34a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:33 +0200 Subject: [PATCH 0802/9457] scsi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/scsi/a3000.c | 1 - drivers/scsi/a4000t.c | 1 - drivers/scsi/bvme6000_scsi.c | 1 - drivers/scsi/jazz_esp.c | 1 - drivers/scsi/mac_esp.c | 1 - drivers/scsi/mvme16x_scsi.c | 1 - drivers/scsi/qlogicpti.c | 1 - drivers/scsi/sgiwd93.c | 1 - drivers/scsi/sni_53c710.c | 1 - drivers/scsi/sun3x_esp.c | 1 - drivers/scsi/sun_esp.c | 1 - 11 files changed, 11 deletions(-) diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index dd5b64726ddc..e6375b4de79e 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -276,7 +276,6 @@ static struct platform_driver amiga_a3000_scsi_driver = { .remove = __exit_p(amiga_a3000_scsi_remove), .driver = { .name = "amiga-a3000-scsi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index f5a2ab41543b..66c573093901 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -112,7 +112,6 @@ static struct platform_driver amiga_a4000t_scsi_driver = { .remove = __exit_p(amiga_a4000t_scsi_remove), .driver = { .name = "amiga-a4000t-scsi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index 1e3f96adf9da..0f846ae2f918 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c @@ -105,7 +105,6 @@ bvme6000_device_remove(struct platform_device *dev) static struct platform_driver bvme6000_scsi_driver = { .driver = { .name = "bvme6000-scsi", - .owner = THIS_MODULE, }, .probe = bvme6000_probe, .remove = bvme6000_device_remove, diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 69efbf12b299..9aaa74e349cc 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -226,7 +226,6 @@ static struct platform_driver esp_jazz_driver = { .remove = esp_jazz_remove, .driver = { .name = "jazz_esp", - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index 994fc5caf036..14c0334f41e4 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -617,7 +617,6 @@ static struct platform_driver esp_mac_driver = { .remove = esp_mac_remove, .driver = { .name = DRV_MODULE_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index 8fbb97a8bfd3..050c8c39d7ed 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c @@ -126,7 +126,6 @@ static int mvme16x_device_remove(struct platform_device *dev) static struct platform_driver mvme16x_scsi_driver = { .driver = { .name = "mvme16x-scsi", - .owner = THIS_MODULE, }, .probe = mvme16x_probe, .remove = mvme16x_device_remove, diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 740ae495aa77..fe122700cad8 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1455,7 +1455,6 @@ MODULE_DEVICE_TABLE(of, qpti_match); static struct platform_driver qpti_sbus_driver = { .driver = { .name = "qpti", - .owner = THIS_MODULE, .of_match_table = qpti_match, }, .probe = qpti_sbus_probe, diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index a464d959f66e..6d215e2fb46d 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -315,7 +315,6 @@ static struct platform_driver sgiwd93_driver = { .remove = sgiwd93_remove, .driver = { .name = "sgiwd93", - .owner = THIS_MODULE, } }; diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index 52d54e7425db..76278072147e 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -137,7 +137,6 @@ static struct platform_driver snirm710_driver = { .remove = snirm710_driver_remove, .driver = { .name = "snirm_53c710", - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 534eb96fc3a7..e26e81de7c45 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -295,7 +295,6 @@ static struct platform_driver esp_sun3x_driver = { .remove = esp_sun3x_remove, .driver = { .name = "sun3x_esp", - .owner = THIS_MODULE, }, }; diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index f2e68459f7ea..7b6d4c2087d7 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -633,7 +633,6 @@ MODULE_DEVICE_TABLE(of, esp_match); static struct platform_driver esp_sbus_driver = { .driver = { .name = "esp", - .owner = THIS_MODULE, .of_match_table = esp_match, }, .probe = esp_sbus_probe, -- GitLab From 37b6fea57b4fcc03689368b7aab1a897f6e9e6b7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:34 +0200 Subject: [PATCH 0803/9457] scsi: ufs: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/scsi/ufs/ufshcd-pltfrm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 8adf067ff019..af613a6375dc 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -398,7 +398,6 @@ static struct platform_driver ufshcd_pltfrm_driver = { .shutdown = ufshcd_pltfrm_shutdown, .driver = { .name = "ufshcd", - .owner = THIS_MODULE, .pm = &ufshcd_dev_pm_ops, .of_match_table = ufs_of_match, }, -- GitLab From ea84768e9a96f1add072456bce103ce347ec87ed Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:34 +0200 Subject: [PATCH 0804/9457] soc: qcom: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/soc/qcom/qcom_gsbi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index 7e1f120f2b32..729425ddfd3e 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -91,7 +91,6 @@ MODULE_DEVICE_TABLE(of, gsbi_dt_match); static struct platform_driver gsbi_driver = { .driver = { .name = "gsbi", - .owner = THIS_MODULE, .of_match_table = gsbi_dt_match, }, .probe = gsbi_probe, -- GitLab From 1135dc17bf15c61a40ecb8a3af5528af9bb877c4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:35 +0200 Subject: [PATCH 0805/9457] soc: tegra: fuse: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/soc/tegra/fuse/fuse-tegra20.c | 1 - drivers/soc/tegra/fuse/fuse-tegra30.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c index 7cb63ab6aac2..5eff6f097f98 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra20.c +++ b/drivers/soc/tegra/fuse/fuse-tegra20.c @@ -158,7 +158,6 @@ static struct platform_driver tegra20_fuse_driver = { .probe = tegra20_fuse_probe, .driver = { .name = "tegra20_fuse", - .owner = THIS_MODULE, .of_match_table = tegra20_fuse_of_match, } }; diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 5999cf34ab70..8646fa920d8d 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -130,7 +130,6 @@ static struct platform_driver tegra30_fuse_driver = { .probe = tegra30_fuse_probe, .driver = { .name = "tegra_fuse", - .owner = THIS_MODULE, .of_match_table = tegra30_fuse_of_match, } }; -- GitLab From 72c6293340bb2fea5ced8fdecc7d765fd6828731 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:35 +0200 Subject: [PATCH 0806/9457] soc: ti: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/soc/ti/knav_dma.c | 1 - drivers/soc/ti/knav_qmss_queue.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 17264275f32b..bc1b80ec6afe 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -803,7 +803,6 @@ static struct platform_driver knav_dma_driver = { .remove = knav_dma_remove, .driver = { .name = "keystone-navigator-dma", - .owner = THIS_MODULE, .of_match_table = of_match, }, }; diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 0a2c8634c48b..5fc9c55abbfd 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -1804,7 +1804,6 @@ static struct platform_driver keystone_qmss_driver = { .remove = knav_queue_remove, .driver = { .name = "keystone-navigator-qmss", - .owner = THIS_MODULE, .of_match_table = keystone_qmss_of_match, }, }; -- GitLab From 14ac00e033c57983032993d3b7b3f70b16a9fdbd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:36 +0200 Subject: [PATCH 0807/9457] spi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/spi/spi-adi-v3.c | 1 - drivers/spi/spi-altera.c | 1 - drivers/spi/spi-ath79.c | 1 - drivers/spi/spi-atmel.c | 1 - drivers/spi/spi-au1550.c | 1 - drivers/spi/spi-bcm2835.c | 1 - drivers/spi/spi-bcm63xx-hsspi.c | 1 - drivers/spi/spi-bcm63xx.c | 1 - drivers/spi/spi-bfin-sport.c | 1 - drivers/spi/spi-bfin5xx.c | 1 - drivers/spi/spi-clps711x.c | 1 - drivers/spi/spi-davinci.c | 1 - drivers/spi/spi-dw-mmio.c | 1 - drivers/spi/spi-efm32.c | 1 - drivers/spi/spi-ep93xx.c | 1 - drivers/spi/spi-falcon.c | 1 - drivers/spi/spi-fsl-espi.c | 1 - drivers/spi/spi-fsl-spi.c | 2 -- drivers/spi/spi-gpio.c | 1 - drivers/spi/spi-imx.c | 1 - drivers/spi/spi-mpc512x-psc.c | 1 - drivers/spi/spi-mpc52xx-psc.c | 1 - drivers/spi/spi-mpc52xx.c | 1 - drivers/spi/spi-mxs.c | 1 - drivers/spi/spi-nuc900.c | 1 - drivers/spi/spi-oc-tiny.c | 1 - drivers/spi/spi-octeon.c | 1 - drivers/spi/spi-omap-100k.c | 1 - drivers/spi/spi-omap-uwire.c | 1 - drivers/spi/spi-omap2-mcspi.c | 1 - drivers/spi/spi-orion.c | 1 - drivers/spi/spi-ppc4xx.c | 1 - drivers/spi/spi-pxa2xx.c | 1 - drivers/spi/spi-qup.c | 1 - drivers/spi/spi-rockchip.c | 1 - drivers/spi/spi-rspi.c | 1 - drivers/spi/spi-s3c24xx.c | 1 - drivers/spi/spi-s3c64xx.c | 1 - drivers/spi/spi-sh-hspi.c | 1 - drivers/spi/spi-sh-msiof.c | 1 - drivers/spi/spi-sh-sci.c | 1 - drivers/spi/spi-sh.c | 1 - drivers/spi/spi-sirf.c | 1 - drivers/spi/spi-sun4i.c | 1 - drivers/spi/spi-sun6i.c | 1 - drivers/spi/spi-tegra114.c | 1 - drivers/spi/spi-tegra20-sflash.c | 1 - drivers/spi/spi-tegra20-slink.c | 1 - drivers/spi/spi-ti-qspi.c | 1 - drivers/spi/spi-topcliff-pch.c | 1 - drivers/spi/spi-txx9.c | 1 - drivers/spi/spi-xtensa-xtfpga.c | 1 - 52 files changed, 53 deletions(-) diff --git a/drivers/spi/spi-adi-v3.c b/drivers/spi/spi-adi-v3.c index 19ea8fb78cc7..a16b25dcd1e6 100644 --- a/drivers/spi/spi-adi-v3.c +++ b/drivers/spi/spi-adi-v3.c @@ -972,7 +972,6 @@ MODULE_ALIAS("platform:adi-spi3"); static struct platform_driver adi_spi_driver = { .driver = { .name = "adi-spi3", - .owner = THIS_MODULE, .pm = &adi_spi_pm_ops, }, .remove = adi_spi_remove, diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 5b5709a5c957..b95010e72452 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c @@ -282,7 +282,6 @@ static struct platform_driver altera_spi_driver = { .remove = altera_spi_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = NULL, .of_match_table = of_match_ptr(altera_spi_match), }, diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 058db0fe8dc7..b02eb4ac0218 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -307,7 +307,6 @@ static struct platform_driver ath79_spi_driver = { .shutdown = ath79_spi_shutdown, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(ath79_spi_driver); diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 113c83f44b5c..5b8a84e81734 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1493,7 +1493,6 @@ MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids); static struct platform_driver atmel_spi_driver = { .driver = { .name = "atmel_spi", - .owner = THIS_MODULE, .pm = ATMEL_SPI_PM_OPS, .of_match_table = of_match_ptr(atmel_spi_dt_ids), }, diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index f40b34cdf2fc..326f47973684 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -965,7 +965,6 @@ static struct platform_driver au1550_spi_drv = { .remove = au1550_spi_remove, .driver = { .name = "au1550-spi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 69167456ec1e..98aab457b24d 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -395,7 +395,6 @@ MODULE_DEVICE_TABLE(of, bcm2835_spi_match); static struct platform_driver bcm2835_spi_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = bcm2835_spi_match, }, .probe = bcm2835_spi_probe, diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 86f5a98aa7a2..f5ca6dc3a157 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -459,7 +459,6 @@ static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, static struct platform_driver bcm63xx_hsspi_driver = { .driver = { .name = "bcm63xx-hsspi", - .owner = THIS_MODULE, .pm = &bcm63xx_hsspi_pm_ops, }, .probe = bcm63xx_hsspi_probe, diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 8510400e7867..c20530982e26 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -469,7 +469,6 @@ static const struct dev_pm_ops bcm63xx_spi_pm_ops = { static struct platform_driver bcm63xx_spi_driver = { .driver = { .name = "bcm63xx-spi", - .owner = THIS_MODULE, .pm = &bcm63xx_spi_pm_ops, }, .probe = bcm63xx_spi_probe, diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index f515c5e9db57..a78693189f45 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -921,7 +921,6 @@ static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend, static struct platform_driver bfin_sport_spi_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = BFIN_SPORT_SPI_PM_OPS, }, .probe = bfin_sport_spi_probe, diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index ebf720b88a2a..37079937d2f7 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -1455,7 +1455,6 @@ MODULE_ALIAS("platform:bfin-spi"); static struct platform_driver bfin_spi_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = BFIN_SPI_PM_OPS, }, .probe = bfin_spi_probe, diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 181cf2262006..8c30de0315e7 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -203,7 +203,6 @@ static int spi_clps711x_probe(struct platform_device *pdev) static struct platform_driver clps711x_spi_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = spi_clps711x_probe, }; diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 63700ab7bd9f..b3707badb1e5 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -1119,7 +1119,6 @@ static int davinci_spi_remove(struct platform_device *pdev) static struct platform_driver davinci_spi_driver = { .driver = { .name = "spi_davinci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(davinci_spi_of_match), }, .probe = davinci_spi_probe, diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 21ce0e36fa00..eb03e1215195 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -135,7 +135,6 @@ static struct platform_driver dw_spi_mmio_driver = { .remove = dw_spi_mmio_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = dw_spi_mmio_of_match, }, }; diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index 6caeb1cac0f3..065fe8744989 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -494,7 +494,6 @@ static struct platform_driver efm32_spi_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = efm32_spi_dt_ids, }, }; diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index bf9728773247..bb00be8d1851 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -964,7 +964,6 @@ static int ep93xx_spi_remove(struct platform_device *pdev) static struct platform_driver ep93xx_spi_driver = { .driver = { .name = "ep93xx-spi", - .owner = THIS_MODULE, }, .probe = ep93xx_spi_probe, .remove = ep93xx_spi_remove, diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index f73b3004d6d3..912b9037e9cf 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -441,7 +441,6 @@ static struct platform_driver falcon_sflash_driver = { .probe = falcon_sflash_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = falcon_sflash_match, } }; diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index a7f94b6a9e70..cff2ebd97463 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -827,7 +827,6 @@ MODULE_DEVICE_TABLE(of, of_fsl_espi_match); static struct platform_driver fsl_espi_driver = { .driver = { .name = "fsl_espi", - .owner = THIS_MODULE, .of_match_table = of_fsl_espi_match, .pm = &espi_pm, }, diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index ed792880c9d6..048f4577e5aa 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -882,7 +882,6 @@ static int of_fsl_spi_remove(struct platform_device *ofdev) static struct platform_driver of_fsl_spi_driver = { .driver = { .name = "fsl_spi", - .owner = THIS_MODULE, .of_match_table = of_fsl_spi_match, }, .probe = of_fsl_spi_probe, @@ -929,7 +928,6 @@ static struct platform_driver mpc8xxx_spi_driver = { .remove = plat_mpc8xxx_spi_remove, .driver = { .name = "mpc8xxx_spi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 9f595535cf27..4a00b7c15b05 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -524,7 +524,6 @@ MODULE_ALIAS("platform:" DRIVER_NAME); static struct platform_driver spi_gpio_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spi_gpio_dt_ids), }, .probe = spi_gpio_probe, diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 3637847b5370..961b97d43b43 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1231,7 +1231,6 @@ static int spi_imx_remove(struct platform_device *pdev) static struct platform_driver spi_imx_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spi_imx_dt_ids, }, .id_table = spi_imx_devtype, diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 577d23a12763..ecae0d4e2945 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -600,7 +600,6 @@ static struct platform_driver mpc512x_psc_spi_of_driver = { .remove = mpc512x_psc_spi_of_remove, .driver = { .name = "mpc512x-psc-spi", - .owner = THIS_MODULE, .of_match_table = mpc512x_psc_spi_of_match, }, }; diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index de532aa11d34..72d11ebefb28 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c @@ -508,7 +508,6 @@ static struct platform_driver mpc52xx_psc_spi_of_driver = { .remove = mpc52xx_psc_spi_of_remove, .driver = { .name = "mpc52xx-psc-spi", - .owner = THIS_MODULE, .of_match_table = mpc52xx_psc_spi_of_match, }, }; diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index b07db4b62d80..c36002110c30 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -543,7 +543,6 @@ MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); static struct platform_driver mpc52xx_spi_of_driver = { .driver = { .name = "mpc52xx-spi", - .owner = THIS_MODULE, .of_match_table = mpc52xx_spi_match, }, .probe = mpc52xx_spi_probe, diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 51460878af04..11de3191f819 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -572,7 +572,6 @@ static struct platform_driver mxs_spi_driver = { .remove = mxs_spi_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mxs_spi_dt_ids, }, }; diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 73e91d5a43df..f51a058e7678 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -423,7 +423,6 @@ static struct platform_driver nuc900_spi_driver = { .remove = nuc900_spi_remove, .driver = { .name = "nuc900-spi", - .owner = THIS_MODULE, }, }; module_platform_driver(nuc900_spi_driver); diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 8998d11c7238..76656a77ec12 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -351,7 +351,6 @@ static struct platform_driver tiny_spi_driver = { .remove = tiny_spi_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = NULL, .of_match_table = of_match_ptr(tiny_spi_match), }, diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index c5e2f718eebd..b283d537d16a 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, octeon_spi_match); static struct platform_driver octeon_spi_driver = { .driver = { .name = "spi-octeon", - .owner = THIS_MODULE, .of_match_table = octeon_spi_match, }, .probe = octeon_spi_probe, diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index fb522765ce5a..79399ae9c84c 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -453,7 +453,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev) static struct platform_driver omap1_spi100k_driver = { .driver = { .name = "omap1_spi100k", - .owner = THIS_MODULE, }, .probe = omap1_spi100k_probe, }; diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 8bca90a19dd1..daf1ada5cd11 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -527,7 +527,6 @@ MODULE_ALIAS("platform:omap_uwire"); static struct platform_driver uwire_driver = { .driver = { .name = "omap_uwire", - .owner = THIS_MODULE, }, .probe = uwire_probe, .remove = uwire_remove, diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 352eed7463ac..3bc3cbabbbc0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1521,7 +1521,6 @@ static const struct dev_pm_ops omap2_mcspi_pm_ops = { static struct platform_driver omap2_mcspi_driver = { .driver = { .name = "omap2_mcspi", - .owner = THIS_MODULE, .pm = &omap2_mcspi_pm_ops, .of_match_table = omap_mcspi_of_match, }, diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 835cdda6f4f5..f6d2188cef84 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -551,7 +551,6 @@ static const struct dev_pm_ops orion_spi_pm_ops = { static struct platform_driver orion_spi_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &orion_spi_pm_ops, .of_match_table = of_match_ptr(orion_spi_of_match_table), }, diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 80b8408ac3e3..54fb984a3e17 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -575,7 +575,6 @@ static struct platform_driver spi_ppc4xx_of_driver = { .remove = spi_ppc4xx_of_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = spi_ppc4xx_of_match, }, }; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index d8a105f76837..00850f83aeba 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1331,7 +1331,6 @@ static const struct dev_pm_ops pxa2xx_spi_pm_ops = { static struct platform_driver driver = { .driver = { .name = "pxa2xx-spi", - .owner = THIS_MODULE, .pm = &pxa2xx_spi_pm_ops, .acpi_match_table = ACPI_PTR(pxa2xx_spi_acpi_match), }, diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 9f83d2950748..390ed712eeed 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -756,7 +756,6 @@ static const struct dev_pm_ops spi_qup_dev_pm_ops = { static struct platform_driver spi_qup_driver = { .driver = { .name = "spi_qup", - .owner = THIS_MODULE, .pm = &spi_qup_dev_pm_ops, .of_match_table = spi_qup_dt_match, }, diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index f96ea8a38d64..7d90c9963093 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -822,7 +822,6 @@ MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match); static struct platform_driver rockchip_spi_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &rockchip_spi_pm, .of_match_table = of_match_ptr(rockchip_spi_dt_match), }, diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 54bb0faec155..2071f788c6fb 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1211,7 +1211,6 @@ static struct platform_driver rspi_driver = { .id_table = spi_driver_ids, .driver = { .name = "renesas_spi", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rspi_of_match), }, }; diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index e713737d784f..f747ca269986 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -663,7 +663,6 @@ static struct platform_driver s3c24xx_spi_driver = { .remove = s3c24xx_spi_remove, .driver = { .name = "s3c2410-spi", - .owner = THIS_MODULE, .pm = S3C24XX_SPI_PMOPS, }, }; diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 480133ee1eb3..4392b44c7889 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1381,7 +1381,6 @@ MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match); static struct platform_driver s3c64xx_spi_driver = { .driver = { .name = "s3c64xx-spi", - .owner = THIS_MODULE, .pm = &s3c64xx_spi_pm, .of_match_table = of_match_ptr(s3c64xx_spi_dt_match), }, diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 94b5faed21e2..fc29233d0650 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -315,7 +315,6 @@ static struct platform_driver hspi_driver = { .remove = hspi_remove, .driver = { .name = "sh-hspi", - .owner = THIS_MODULE, .of_match_table = hspi_of_match, }, }; diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 3f365402fcc0..239be7cbe5a8 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -1235,7 +1235,6 @@ static struct platform_driver sh_msiof_spi_drv = { .id_table = spi_driver_ids, .driver = { .name = "spi_sh_msiof", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(sh_msiof_match), }, }; diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index b83dd733684c..a9beeeed812c 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c @@ -187,7 +187,6 @@ static struct platform_driver sh_sci_spi_drv = { .remove = sh_sci_spi_remove, .driver = { .name = "spi_sh_sci", - .owner = THIS_MODULE, }, }; module_platform_driver(sh_sci_spi_drv); diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c index 8e171a76049f..1cfc906dd174 100644 --- a/drivers/spi/spi-sh.c +++ b/drivers/spi/spi-sh.c @@ -532,7 +532,6 @@ static struct platform_driver spi_sh_driver = { .remove = spi_sh_remove, .driver = { .name = "sh_spi", - .owner = THIS_MODULE, }, }; module_platform_driver(spi_sh_driver); diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 39e2c0a55a28..515184cfba4e 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -820,7 +820,6 @@ MODULE_DEVICE_TABLE(of, spi_sirfsoc_of_match); static struct platform_driver spi_sirfsoc_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &spi_sirfsoc_pm_ops, .of_match_table = spi_sirfsoc_of_match, }, diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index 85204c93f3d3..fbb0a4d74e91 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -464,7 +464,6 @@ static struct platform_driver sun4i_spi_driver = { .remove = sun4i_spi_remove, .driver = { .name = "sun4i-spi", - .owner = THIS_MODULE, .of_match_table = sun4i_spi_match, .pm = &sun4i_spi_pm_ops, }, diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index bd24093f4038..ac48f59705a8 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -470,7 +470,6 @@ static struct platform_driver sun6i_spi_driver = { .remove = sun6i_spi_remove, .driver = { .name = "sun6i-spi", - .owner = THIS_MODULE, .of_match_table = sun6i_spi_match, .pm = &sun6i_spi_pm_ops, }, diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 795bcbc0131b..73779cecc3bb 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -1223,7 +1223,6 @@ static const struct dev_pm_ops tegra_spi_pm_ops = { static struct platform_driver tegra_spi_driver = { .driver = { .name = "spi-tegra114", - .owner = THIS_MODULE, .pm = &tegra_spi_pm_ops, .of_match_table = tegra_spi_of_match, }, diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index cd66fe7b78a9..b6558bb6f9df 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -608,7 +608,6 @@ static const struct dev_pm_ops slink_pm_ops = { static struct platform_driver tegra_sflash_driver = { .driver = { .name = "spi-tegra-sflash", - .owner = THIS_MODULE, .pm = &slink_pm_ops, .of_match_table = tegra_sflash_of_match, }, diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 0b9e32e9f493..85c91f58b42f 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -1224,7 +1224,6 @@ static const struct dev_pm_ops slink_pm_ops = { static struct platform_driver tegra_slink_driver = { .driver = { .name = "spi-tegra-slink", - .owner = THIS_MODULE, .pm = &slink_pm_ops, .of_match_table = tegra_slink_of_match, }, diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 6c211d1910b0..6146c4cd6583 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -567,7 +567,6 @@ static struct platform_driver ti_qspi_driver = { .remove = ti_qspi_remove, .driver = { .name = "ti-qspi", - .owner = THIS_MODULE, .pm = &ti_qspi_pm_ops, .of_match_table = ti_qspi_match, } diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 0a87ec39f619..be692ad50442 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1561,7 +1561,6 @@ static int pch_spi_pd_resume(struct platform_device *pd_dev) static struct platform_driver pch_spi_pd_driver = { .driver = { .name = "pch-spi", - .owner = THIS_MODULE, }, .probe = pch_spi_pd_probe, .remove = pch_spi_pd_remove, diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 2501a8373e89..0da7c67f5db4 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -426,7 +426,6 @@ static struct platform_driver txx9spi_driver = { .remove = txx9spi_remove, .driver = { .name = "spi_txx9", - .owner = THIS_MODULE, }, }; diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c index 0dc5df5233a9..2e32ea2f194f 100644 --- a/drivers/spi/spi-xtensa-xtfpga.c +++ b/drivers/spi/spi-xtensa-xtfpga.c @@ -160,7 +160,6 @@ static struct platform_driver xtfpga_spi_driver = { .remove = xtfpga_spi_remove, .driver = { .name = XTFPGA_SPI_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(xtfpga_spi_of_match), }, }; -- GitLab From f271fbddfa3634fda9ea2baff047e128c9a18bf2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:36 +0200 Subject: [PATCH 0808/9457] spmi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/spmi/spmi-pmic-arb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 246e03a18c94..20559ab3466d 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -768,7 +768,6 @@ static struct platform_driver spmi_pmic_arb_driver = { .remove = spmi_pmic_arb_remove, .driver = { .name = "spmi_pmic_arb", - .owner = THIS_MODULE, .of_match_table = spmi_pmic_arb_match_table, }, }; -- GitLab From 2fe10a7ba9e9a59c29b07da5ac71de3dc5e80c9e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:36 +0200 Subject: [PATCH 0809/9457] staging: android: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/android/timed_gpio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 8fa4758517c0..c71ed64931ba 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -157,7 +157,6 @@ static struct platform_driver timed_gpio_driver = { .remove = timed_gpio_remove, .driver = { .name = TIMED_GPIO_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From 9feba53fb1f05806f85dffe404c4d3743c51a81a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:37 +0200 Subject: [PATCH 0810/9457] staging: emxx_udc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/emxx_udc/emxx_udc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 1ae0013fb118..ed8d86c98f65 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -3491,7 +3491,6 @@ static struct platform_driver udc_driver = { .suspend = nbu2ss_drv_suspend, .resume = nbu2ss_drv_resume, .driver = { - .owner = THIS_MODULE, .name = driver_name, }, }; -- GitLab From 5508ef724de8410af9317895b58d76fcd6f56953 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:37 +0200 Subject: [PATCH 0811/9457] staging: iio: adc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/iio/adc/ad7606_par.c | 1 - drivers/staging/iio/adc/lpc32xx_adc.c | 1 - drivers/staging/iio/adc/mxs-lradc.c | 1 - drivers/staging/iio/adc/spear_adc.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c index 7511839ba94e..9e24b4d4455f 100644 --- a/drivers/staging/iio/adc/ad7606_par.c +++ b/drivers/staging/iio/adc/ad7606_par.c @@ -141,7 +141,6 @@ static struct platform_driver ad7606_driver = { .id_table = ad7606_driver_ids, .driver = { .name = "ad7606", - .owner = THIS_MODULE, .pm = AD7606_PAR_PM_OPS, }, }; diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index a876ce755351..4708e9a41633 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -204,7 +204,6 @@ static struct platform_driver lpc32xx_adc_driver = { .probe = lpc32xx_adc_probe, .driver = { .name = MOD_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(lpc32xx_adc_match), }, }; diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 32a19264a170..61a16c2726ea 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1664,7 +1664,6 @@ static int mxs_lradc_remove(struct platform_device *pdev) static struct platform_driver mxs_lradc_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mxs_lradc_dt_ids, }, .probe = mxs_lradc_probe, diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index c5492ba50751..750697832b96 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -389,7 +389,6 @@ static struct platform_driver spear_adc_driver = { .remove = spear_adc_remove, .driver = { .name = SPEAR_ADC_MOD_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spear_adc_dt_ids), }, }; -- GitLab From c85d13ed2b64ecbe9ff0806097012a892a433cf5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:38 +0200 Subject: [PATCH 0812/9457] staging: iio: trigger: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 1 - drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index a21b7c514776..2af8d677d4ed 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -279,7 +279,6 @@ static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev) static struct platform_driver iio_bfin_tmr_trigger_driver = { .driver = { .name = "iio_bfin_tmr_trigger", - .owner = THIS_MODULE, }, .probe = iio_bfin_tmr_trigger_probe, .remove = iio_bfin_tmr_trigger_remove, diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 8f0a2ffa7150..82c2e6d3f5a7 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -206,7 +206,6 @@ static struct platform_driver iio_trig_periodic_rtc_driver = { .remove = iio_trig_periodic_rtc_remove, .driver = { .name = "iio_prtc_trigger", - .owner = THIS_MODULE, }, }; -- GitLab From 76dab93696b7e75305236dddf51b6dc5d6e574d5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:38 +0200 Subject: [PATCH 0813/9457] staging: imx-drm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/imx-drm/imx-drm-core.c | 1 - drivers/staging/imx-drm/imx-hdmi.c | 1 - drivers/staging/imx-drm/imx-ldb.c | 1 - drivers/staging/imx-drm/imx-tve.c | 1 - drivers/staging/imx-drm/parallel-display.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 9cb222e2996f..ad6173500bfc 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -691,7 +691,6 @@ static struct platform_driver imx_drm_pdrv = { .probe = imx_drm_platform_probe, .remove = imx_drm_platform_remove, .driver = { - .owner = THIS_MODULE, .name = "imx-drm", .pm = &imx_drm_pm_ops, .of_match_table = imx_drm_dt_ids, diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index aaec6b2cdf56..ddc53e039530 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1754,7 +1754,6 @@ static struct platform_driver imx_hdmi_driver = { .remove = imx_hdmi_platform_remove, .driver = { .name = "imx-hdmi", - .owner = THIS_MODULE, .of_match_table = imx_hdmi_dt_ids, }, }; diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 4662e00b456a..2638dc1671d0 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -604,7 +604,6 @@ static struct platform_driver imx_ldb_driver = { .driver = { .of_match_table = imx_ldb_dt_ids, .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 42c651be6c20..64b54d7f996c 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -724,7 +724,6 @@ static struct platform_driver imx_tve_driver = { .driver = { .of_match_table = imx_tve_dt_ids, .name = "imx-tve", - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 015a454b87e1..8a76a5c1c34b 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -284,7 +284,6 @@ static struct platform_driver imx_pd_driver = { .driver = { .of_match_table = imx_pd_dt_ids, .name = "imx-parallel-display", - .owner = THIS_MODULE, }, }; -- GitLab From 95f87b928376690a23137944239d8d9121c6abae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:38 +0200 Subject: [PATCH 0814/9457] staging: media: davinci_vpfe: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index a862b28092e4..291bf11e09a1 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -707,7 +707,6 @@ static int vpfe_remove(struct platform_device *pdev) static struct platform_driver vpfe_driver = { .driver = { .name = CAPTURE_DRV_NAME, - .owner = THIS_MODULE, }, .probe = vpfe_probe, .remove = vpfe_remove, -- GitLab From 305f3de8d1c5902c6c7b9617dc75d8647ce60b19 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:39 +0200 Subject: [PATCH 0815/9457] staging: media: lirc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/media/lirc/lirc_parallel.c | 1 - drivers/staging/media/lirc/lirc_serial.c | 1 - drivers/staging/media/lirc/lirc_sir.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c index 5156c2181016..19c5c21babf5 100644 --- a/drivers/staging/media/lirc/lirc_parallel.c +++ b/drivers/staging/media/lirc/lirc_parallel.c @@ -605,7 +605,6 @@ static struct platform_driver lirc_parallel_driver = { .resume = lirc_parallel_resume, .driver = { .name = LIRC_DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 181b92bfe25d..eb4ccb8d2a93 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -1060,7 +1060,6 @@ static struct platform_driver lirc_serial_driver = { .resume = lirc_serial_resume, .driver = { .name = "lirc_serial", - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 2ee55eaf2a53..e961b5218215 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -931,7 +931,6 @@ static struct platform_driver lirc_sir_driver = { .remove = lirc_sir_remove, .driver = { .name = "lirc_sir", - .owner = THIS_MODULE, }, }; -- GitLab From 8c5bd8111b45e6ef32ee1e8ead5700a426e2771b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:39 +0200 Subject: [PATCH 0816/9457] staging: media: omap24xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/media/omap24xx/omap24xxcam.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/omap24xx/omap24xxcam.c b/drivers/staging/media/omap24xx/omap24xxcam.c index d590b3e8b70c..5a60addc9767 100644 --- a/drivers/staging/media/omap24xx/omap24xxcam.c +++ b/drivers/staging/media/omap24xx/omap24xxcam.c @@ -1864,7 +1864,6 @@ static struct platform_driver omap24xxcam_driver = { #endif .driver = { .name = CAM_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From b096ba95349e1fe8f695b48e5000056275048ec8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:40 +0200 Subject: [PATCH 0817/9457] staging: media: omap4iss: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/media/omap4iss/iss.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index d548371db65a..96b14b326e09 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1476,7 +1476,6 @@ static struct platform_driver iss_driver = { .remove = iss_remove, .id_table = omap4iss_id_table, .driver = { - .owner = THIS_MODULE, .name = "omap4iss", }, }; -- GitLab From 848a17ca5b6c3294c3f14d04198507ff5c8c7b04 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:40 +0200 Subject: [PATCH 0818/9457] staging: netlogic: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/netlogic/xlr_net.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index ad19ba9df3c7..5ecb3e6a5bb3 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c @@ -1133,7 +1133,6 @@ static struct platform_driver xlr_net_driver = { .remove = xlr_net_remove, .driver = { .name = "xlr-net", - .owner = THIS_MODULE, }, }; -- GitLab From d5dbc0245a7da65b95fc14f99ccfc5f1fad078f0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:41 +0200 Subject: [PATCH 0819/9457] staging: nvec: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/nvec/nvec.c | 1 - drivers/staging/nvec/nvec_kbd.c | 1 - drivers/staging/nvec/nvec_paz00.c | 1 - drivers/staging/nvec/nvec_power.c | 1 - drivers/staging/nvec/nvec_ps2.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index a93208adbfcf..093535c6217b 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -973,7 +973,6 @@ static struct platform_driver nvec_device_driver = { .remove = tegra_nvec_remove, .driver = { .name = "nvec", - .owner = THIS_MODULE, .pm = &nvec_pm_ops, .of_match_table = nvidia_nvec_of_match, } diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index c17a1c3eb3ca..e881e6b26a4c 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -181,7 +181,6 @@ static struct platform_driver nvec_kbd_driver = { .remove = nvec_kbd_remove, .driver = { .name = "nvec-kbd", - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/nvec/nvec_paz00.c b/drivers/staging/nvec/nvec_paz00.c index e2e675a6e95a..f0cea0e43c96 100644 --- a/drivers/staging/nvec/nvec_paz00.c +++ b/drivers/staging/nvec/nvec_paz00.c @@ -87,7 +87,6 @@ static struct platform_driver nvec_paz00_driver = { .remove = nvec_paz00_remove, .driver = { .name = "nvec-paz00", - .owner = THIS_MODULE, }, }; diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 6446e151866f..6a1459d4f8fb 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -432,7 +432,6 @@ static struct platform_driver nvec_power_driver = { .remove = nvec_power_remove, .driver = { .name = "nvec-power", - .owner = THIS_MODULE, } }; diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index f56f1db15bad..4fd63c239454 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -177,7 +177,6 @@ static struct platform_driver nvec_mouse_driver = { .remove = nvec_mouse_remove, .driver = { .name = "nvec-mouse", - .owner = THIS_MODULE, .pm = &nvec_mouse_pm_ops, }, }; -- GitLab From a4652e8e34cd5e07ad34230c17b1b310ec1bcd71 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:41 +0200 Subject: [PATCH 0820/9457] staging: octeon: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/octeon/ethernet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 8f9e3fb4871d..af24294d9466 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -877,7 +877,6 @@ static struct platform_driver cvm_oct_driver = { .probe = cvm_oct_probe, .remove = cvm_oct_remove, .driver = { - .owner = THIS_MODULE, .name = KBUILD_MODNAME, .of_match_table = cvm_oct_match, }, -- GitLab From a4d9e08f81eb5bd8a6c253de775cc0171a4556cd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:41 +0200 Subject: [PATCH 0821/9457] staging: octeon-usb: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/octeon-usb/octeon-hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 5f9db4cbb381..2f8eaf768bf3 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -3882,7 +3882,6 @@ static struct of_device_id octeon_usb_match[] = { static struct platform_driver octeon_usb_driver = { .driver = { .name = "OcteonUSB", - .owner = THIS_MODULE, .of_match_table = octeon_usb_match, }, .probe = octeon_usb_probe, -- GitLab From 3d622e2c587540d5e7d037f9ced6a3d73e4880a7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:42 +0200 Subject: [PATCH 0822/9457] staging: ozwpan: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/staging/ozwpan/ozhcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index e88045228607..347b8b1ffa29 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -224,7 +224,6 @@ static struct platform_driver g_oz_plat_drv = { .resume = oz_plat_resume, .driver = { .name = OZ_PLAT_DEV_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From bbc379834091670d540cae8d7d1e2240b68bb0e8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:42 +0200 Subject: [PATCH 0823/9457] thermal: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/thermal/armada_thermal.c | 1 - drivers/thermal/db8500_cpufreq_cooling.c | 1 - drivers/thermal/db8500_thermal.c | 1 - drivers/thermal/dove_thermal.c | 1 - drivers/thermal/imx_thermal.c | 1 - drivers/thermal/kirkwood_thermal.c | 1 - drivers/thermal/spear_thermal.c | 1 - 7 files changed, 7 deletions(-) diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 9d1420acb391..eaaf59c98ba2 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -329,7 +329,6 @@ static struct platform_driver armada_thermal_driver = { .remove = armada_thermal_exit, .driver = { .name = "armada_thermal", - .owner = THIS_MODULE, .of_match_table = armada_thermal_id_table, }, }; diff --git a/drivers/thermal/db8500_cpufreq_cooling.c b/drivers/thermal/db8500_cpufreq_cooling.c index 786d19263ab0..000d53e934a0 100644 --- a/drivers/thermal/db8500_cpufreq_cooling.c +++ b/drivers/thermal/db8500_cpufreq_cooling.c @@ -78,7 +78,6 @@ static const struct of_device_id db8500_cpufreq_cooling_match[] = { static struct platform_driver db8500_cpufreq_cooling_driver = { .driver = { - .owner = THIS_MODULE, .name = "db8500-cpufreq-cooling", .of_match_table = of_match_ptr(db8500_cpufreq_cooling_match), }, diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c index 1e3b3bf9f993..20adfbe27df1 100644 --- a/drivers/thermal/db8500_thermal.c +++ b/drivers/thermal/db8500_thermal.c @@ -517,7 +517,6 @@ static const struct of_device_id db8500_thermal_match[] = { static struct platform_driver db8500_thermal_driver = { .driver = { - .owner = THIS_MODULE, .name = "db8500-thermal", .of_match_table = of_match_ptr(db8500_thermal_match), }, diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c index 828f5e345c30..09f6e304c274 100644 --- a/drivers/thermal/dove_thermal.c +++ b/drivers/thermal/dove_thermal.c @@ -184,7 +184,6 @@ static struct platform_driver dove_thermal_driver = { .remove = dove_thermal_exit, .driver = { .name = "dove_thermal", - .owner = THIS_MODULE, .of_match_table = dove_thermal_id_table, }, }; diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 2c516f2eebed..9f34fdd51250 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -559,7 +559,6 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match); static struct platform_driver imx_thermal = { .driver = { .name = "imx_thermal", - .owner = THIS_MODULE, .pm = &imx_thermal_pm_ops, .of_match_table = of_imx_thermal_match, }, diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c index 3b034a0dfc94..11041fe63dc2 100644 --- a/drivers/thermal/kirkwood_thermal.c +++ b/drivers/thermal/kirkwood_thermal.c @@ -114,7 +114,6 @@ static struct platform_driver kirkwood_thermal_driver = { .remove = kirkwood_thermal_exit, .driver = { .name = "kirkwood_thermal", - .owner = THIS_MODULE, .of_match_table = kirkwood_thermal_id_table, }, }; diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c index 1e2193fc3241..bddb71744a6c 100644 --- a/drivers/thermal/spear_thermal.c +++ b/drivers/thermal/spear_thermal.c @@ -186,7 +186,6 @@ static struct platform_driver spear_thermal_driver = { .remove = spear_thermal_exit, .driver = { .name = "spear_thermal", - .owner = THIS_MODULE, .pm = &spear_thermal_pm_ops, .of_match_table = spear_thermal_id_table, }, -- GitLab From 32d3c299c567b3114152a5ca777a2c91523f4d8c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:43 +0200 Subject: [PATCH 0824/9457] thermal: samsung: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/thermal/samsung/exynos_tmu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index acbff14da3a4..79c3d95e6513 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -806,7 +806,6 @@ static SIMPLE_DEV_PM_OPS(exynos_tmu_pm, static struct platform_driver exynos_tmu_driver = { .driver = { .name = "exynos-tmu", - .owner = THIS_MODULE, .pm = EXYNOS_TMU_PM, .of_match_table = exynos_tmu_match, }, -- GitLab From 4b6d6c6785b33dabeee69cab1c04954e584ab84c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:43 +0200 Subject: [PATCH 0825/9457] thermal: st: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/thermal/st/st_thermal_memmap.c | 1 - drivers/thermal/st/st_thermal_syscfg.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/thermal/st/st_thermal_memmap.c b/drivers/thermal/st/st_thermal_memmap.c index 39896ce2ee00..067bfcdb91d6 100644 --- a/drivers/thermal/st/st_thermal_memmap.c +++ b/drivers/thermal/st/st_thermal_memmap.c @@ -194,7 +194,6 @@ int st_mmap_remove(struct platform_device *pdev) static struct platform_driver st_mmap_thermal_driver = { .driver = { .name = "st_thermal_mmap", - .owner = THIS_MODULE, .pm = &st_thermal_pm_ops, .of_match_table = st_mmap_thermal_of_match, }, diff --git a/drivers/thermal/st/st_thermal_syscfg.c b/drivers/thermal/st/st_thermal_syscfg.c index 888b58e64090..26d36a242bb8 100644 --- a/drivers/thermal/st/st_thermal_syscfg.c +++ b/drivers/thermal/st/st_thermal_syscfg.c @@ -165,7 +165,6 @@ int st_syscfg_remove(struct platform_device *pdev) static struct platform_driver st_syscfg_thermal_driver = { .driver = { .name = "st_syscfg_thermal", - .owner = THIS_MODULE, .pm = &st_thermal_pm_ops, .of_match_table = st_syscfg_thermal_of_match, }, -- GitLab From c910367fed9fc73368d0deb7898c5ceef31e5d8f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:44 +0200 Subject: [PATCH 0826/9457] tty: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/tty/amiserial.c | 1 - drivers/tty/ehv_bytechan.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 979e7c3ea2cb..d9f85f95eb2a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1802,7 +1802,6 @@ static struct platform_driver amiga_serial_driver = { .remove = __exit_p(amiga_serial_remove), .driver = { .name = "amiga-serial", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4f485e88f60c..ffe08e1d7187 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -740,7 +740,6 @@ static const struct of_device_id ehv_bc_tty_of_ids[] = { static struct platform_driver ehv_bc_tty_driver = { .driver = { - .owner = THIS_MODULE, .name = "ehv-bc", .of_match_table = ehv_bc_tty_of_ids, }, -- GitLab From 3aa5fed2564fd7a18f6f6ab4fd1a50538ebb70e9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:44 +0200 Subject: [PATCH 0827/9457] tty: hvc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/tty/hvc/hvc_opal.c | 1 - drivers/tty/hvc/hvc_tile.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index a2cc5f834c63..071551bf3e9a 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -262,7 +262,6 @@ static struct platform_driver hvc_opal_driver = { .remove = hvc_opal_remove, .driver = { .name = hvc_opal_name, - .owner = THIS_MODULE, .of_match_table = hvc_opal_match, } }; diff --git a/drivers/tty/hvc/hvc_tile.c b/drivers/tty/hvc/hvc_tile.c index df374860037c..3f6cd3102db5 100644 --- a/drivers/tty/hvc/hvc_tile.c +++ b/drivers/tty/hvc/hvc_tile.c @@ -178,7 +178,6 @@ static struct platform_driver hvc_tile_driver = { .shutdown = hvc_tile_shutdown, .driver = { .name = "hvc-tile", - .owner = THIS_MODULE, } }; #endif -- GitLab From 9144b3cded04a05d4b4e18dc9dcfb5b8ada3f2fc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:45 +0200 Subject: [PATCH 0828/9457] tty: serial: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/tty/serial/altera_jtaguart.c | 1 - drivers/tty/serial/altera_uart.c | 1 - drivers/tty/serial/apbuart.c | 1 - drivers/tty/serial/ar933x_uart.c | 1 - drivers/tty/serial/arc_uart.c | 1 - drivers/tty/serial/atmel_serial.c | 1 - drivers/tty/serial/bcm63xx_uart.c | 1 - drivers/tty/serial/bfin_uart.c | 1 - drivers/tty/serial/clps711x.c | 1 - drivers/tty/serial/efm32-uart.c | 1 - drivers/tty/serial/fsl_lpuart.c | 1 - drivers/tty/serial/imx.c | 1 - drivers/tty/serial/lantiq.c | 1 - drivers/tty/serial/lpc32xx_hs.c | 1 - drivers/tty/serial/mcf.c | 1 - drivers/tty/serial/meson_uart.c | 1 - drivers/tty/serial/mpc52xx_uart.c | 1 - drivers/tty/serial/mpsc.c | 1 - drivers/tty/serial/msm_serial.c | 1 - drivers/tty/serial/msm_serial_hs.c | 1 - drivers/tty/serial/mxs-auart.c | 1 - drivers/tty/serial/netx-serial.c | 1 - drivers/tty/serial/of_serial.c | 1 - drivers/tty/serial/pmac_zilog.c | 1 - drivers/tty/serial/pnx8xxx_uart.c | 1 - drivers/tty/serial/pxa.c | 1 - drivers/tty/serial/sa1100.c | 1 - drivers/tty/serial/samsung.c | 1 - drivers/tty/serial/sccnxp.c | 1 - drivers/tty/serial/serial_txx9.c | 1 - drivers/tty/serial/sh-sci.c | 1 - drivers/tty/serial/sirfsoc_uart.c | 1 - drivers/tty/serial/st-asc.c | 1 - drivers/tty/serial/sunhv.c | 1 - drivers/tty/serial/sunsab.c | 1 - drivers/tty/serial/sunsu.c | 1 - drivers/tty/serial/sunzilog.c | 1 - drivers/tty/serial/timbuart.c | 1 - drivers/tty/serial/ucc_uart.c | 1 - drivers/tty/serial/vr41xx_siu.c | 1 - drivers/tty/serial/vt8500_serial.c | 1 - 41 files changed, 41 deletions(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 932e01995c0a..192d0435bb86 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -475,7 +475,6 @@ static struct platform_driver altera_jtaguart_platform_driver = { .remove = altera_jtaguart_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(altera_jtaguart_match), }, }; diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 1cb2cdb1bc42..eb15a50623cb 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -623,7 +623,6 @@ static struct platform_driver altera_uart_platform_driver = { .remove = altera_uart_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(altera_uart_match), }, }; diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index a34a0cec1685..4f0f95e358e8 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -585,7 +585,6 @@ static struct of_device_id apbuart_match[] = { static struct platform_driver grlib_apbuart_of_driver = { .probe = apbuart_probe, .driver = { - .owner = THIS_MODULE, .name = "grlib-apbuart", .of_match_table = apbuart_match, }, diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 0be1c45efd65..5d8ec7fe0d98 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -734,7 +734,6 @@ static struct platform_driver ar933x_uart_platform_driver = { .remove = ar933x_uart_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ar933x_uart_of_ids), }, }; diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index a59d1d77e750..03ebe401fff7 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -653,7 +653,6 @@ static struct platform_driver arc_platform_driver = { .remove = arc_serial_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = arc_uart_dt_ids, }, }; diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index edde3eca055d..9075c6622af5 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2660,7 +2660,6 @@ static struct platform_driver atmel_serial_driver = { .resume = atmel_serial_resume, .driver = { .name = "atmel_usart", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_serial_dt_ids), }, }; diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 231519022b73..ded5620ea513 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -874,7 +874,6 @@ static struct platform_driver bcm_uart_platform_driver = { .probe = bcm_uart_probe, .remove = bcm_uart_remove, .driver = { - .owner = THIS_MODULE, .name = "bcm63xx_uart", .of_match_table = bcm63xx_of_match, }, diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 7da9911e95f0..165564dff0c8 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -1386,7 +1386,6 @@ static struct platform_driver bfin_serial_driver = { .resume = bfin_serial_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index acfe31773643..54626f99d49e 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -542,7 +542,6 @@ MODULE_DEVICE_TABLE(of, clps711x_uart_dt_ids); static struct platform_driver clps711x_uart_platform = { .driver = { .name = "clps711x-uart", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(clps711x_uart_dt_ids), }, .probe = uart_clps711x_probe, diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 55d9c00112cc..195acc868763 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c @@ -814,7 +814,6 @@ static struct platform_driver efm32_uart_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = efm32_uart_dt_ids, }, }; diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 6dd53af546a3..fd503c35defb 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1876,7 +1876,6 @@ static struct platform_driver lpuart_driver = { .remove = lpuart_remove, .driver = { .name = "fsl-lpuart", - .owner = THIS_MODULE, .of_match_table = lpuart_dt_ids, .pm = &lpuart_pm_ops, }, diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 8f62a3cec23e..f2b81bdd4f02 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1952,7 +1952,6 @@ static struct platform_driver serial_imx_driver = { .id_table = imx_uart_devtype, .driver = { .name = "imx-uart", - .owner = THIS_MODULE, .of_match_table = imx_uart_dt_ids, }, }; diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 4675fe198d31..6c10a9089f3b 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -743,7 +743,6 @@ MODULE_DEVICE_TABLE(of, ltq_asc_match); static struct platform_driver lqasc_driver = { .driver = { .name = DRVNAME, - .owner = THIS_MODULE, .of_match_table = ltq_asc_match, }, }; diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 6f0f89282847..e92d7ebe9e77 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -768,7 +768,6 @@ static struct platform_driver serial_hs_lpc32xx_driver = { .resume = serial_hs_lpc32xx_resume, .driver = { .name = MODNAME, - .owner = THIS_MODULE, .of_match_table = serial_hs_lpc32xx_dt_ids, }, }; diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index bc896dc7d2ed..89ac4e457ca5 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -693,7 +693,6 @@ static struct platform_driver mcf_platform_driver = { .remove = mcf_remove, .driver = { .name = "mcfuart", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 15c749753317..67c036702629 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -599,7 +599,6 @@ static struct platform_driver meson_uart_platform_driver = { .probe = meson_uart_probe, .remove = meson_uart_remove, .driver = { - .owner = THIS_MODULE, .name = "meson_uart", .of_match_table = meson_uart_dt_match, }, diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index a5f4e3648b15..3308ef243dc3 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1889,7 +1889,6 @@ static struct platform_driver mpc52xx_uart_of_driver = { #endif .driver = { .name = "mpc52xx-psc-uart", - .owner = THIS_MODULE, .of_match_table = mpc52xx_uart_of_match, }, }; diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index ae49856ef6c7..5f864287b508 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c @@ -2111,7 +2111,6 @@ static struct platform_driver mpsc_driver = { .remove = mpsc_drv_remove, .driver = { .name = MPSC_CTLR_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 4b6c78331a64..353725a51efb 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1114,7 +1114,6 @@ static struct platform_driver msm_platform_driver = { .probe = msm_serial_probe, .driver = { .name = "msm_serial", - .owner = THIS_MODULE, .of_match_table = msm_match_table, }, }; diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 48e94961a9e5..8abe8ea65658 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -1838,7 +1838,6 @@ static struct platform_driver msm_serial_hs_platform_driver = { .remove = msm_hs_remove, .driver = { .name = "msm_serial_hs", - .owner = THIS_MODULE, .pm = &msm_hs_dev_pm_ops, }, }; diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 10c29334fe2f..b55892106a2e 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -1123,7 +1123,6 @@ static struct platform_driver mxs_auart_driver = { .remove = mxs_auart_remove, .driver = { .name = "mxs-auart", - .owner = THIS_MODULE, .of_match_table = mxs_auart_dt_ids, }, }; diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index 7a6745601d4e..207a0a032ed1 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c @@ -710,7 +710,6 @@ static struct platform_driver serial_netx_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 8bc2563335ae..1f65e727c0ea 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -295,7 +295,6 @@ static struct of_device_id of_platform_serial_table[] = { static struct platform_driver of_platform_serial_driver = { .driver = { .name = "of_serial", - .owner = THIS_MODULE, .of_match_table = of_platform_serial_table, .pm = &of_serial_pm_ops, }, diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index abbfedb84901..f03c23543ead 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1874,7 +1874,6 @@ static struct platform_driver pmz_driver = { .remove = __exit_p(pmz_detach), .driver = { .name = "scc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 2ba24a45c97f..928cc113c773 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c @@ -813,7 +813,6 @@ static int pnx8xxx_serial_remove(struct platform_device *pdev) static struct platform_driver pnx8xxx_serial_driver = { .driver = { .name = "pnx8xxx-uart", - .owner = THIS_MODULE, }, .probe = pnx8xxx_serial_probe, .remove = pnx8xxx_serial_remove, diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 21b7d8b86493..a3cd61d6a727 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -930,7 +930,6 @@ static struct platform_driver serial_pxa_driver = { .driver = { .name = "pxa2xx-uart", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &serial_pxa_pm_ops, #endif diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 753d4525b367..63989802caf2 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -883,7 +883,6 @@ static struct platform_driver sa11x0_serial_driver = { .resume = sa1100_serial_resume, .driver = { .name = "sa11x0-uart", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index c78f43a481ce..7961bf411432 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1848,7 +1848,6 @@ static struct platform_driver samsung_serial_driver = { .id_table = s3c24xx_serial_driver_ids, .driver = { .name = "samsung-uart", - .owner = THIS_MODULE, .pm = SERIAL_SAMSUNG_PM_OPS, .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), }, diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 75850f70b479..fcf803ffad19 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -1012,7 +1012,6 @@ static int sccnxp_remove(struct platform_device *pdev) static struct platform_driver sccnxp_uart_driver = { .driver = { .name = SCCNXP_NAME, - .owner = THIS_MODULE, }, .probe = sccnxp_probe, .remove = sccnxp_remove, diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index af115645c51f..f80312eed4fd 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -1165,7 +1165,6 @@ static struct platform_driver serial_txx9_plat_driver = { #endif .driver = { .name = "serial_txx9", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index eb17c7124e72..c0125df41c2d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2638,7 +2638,6 @@ static struct platform_driver sci_driver = { .remove = sci_remove, .driver = { .name = "sh-sci", - .owner = THIS_MODULE, .pm = &sci_dev_pm_ops, .of_match_table = of_match_ptr(of_sci_match), }, diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 4102192687ee..775a6e369e46 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -1477,7 +1477,6 @@ static struct platform_driver sirfsoc_uart_driver = { .remove = sirfsoc_uart_remove, .driver = { .name = SIRFUART_PORT_NAME, - .owner = THIS_MODULE, .of_match_table = sirfsoc_uart_ids, .pm = &sirfsoc_uart_pm_ops, }, diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index a3165842ca29..712b03a076b8 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -895,7 +895,6 @@ static struct platform_driver asc_serial_driver = { .driver = { .name = DRIVER_NAME, .pm = &asc_serial_pm_ops, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(asc_match), }, }; diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 25d43ce8b318..534754440fa8 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -626,7 +626,6 @@ MODULE_DEVICE_TABLE(of, hv_match); static struct platform_driver hv_driver = { .driver = { .name = "hv", - .owner = THIS_MODULE, .of_match_table = hv_match, }, .probe = hv_probe, diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b339fe4811cd..82a07a4fbf3b 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1092,7 +1092,6 @@ MODULE_DEVICE_TABLE(of, sab_match); static struct platform_driver sab_driver = { .driver = { .name = "sab", - .owner = THIS_MODULE, .of_match_table = sab_match, }, .probe = sab_probe, diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 5326ae195e5f..526331c146ef 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -1537,7 +1537,6 @@ MODULE_DEVICE_TABLE(of, su_match); static struct platform_driver su_driver = { .driver = { .name = "su", - .owner = THIS_MODULE, .of_match_table = su_match, }, .probe = su_probe, diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 02df3940b95e..370546e085d3 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1533,7 +1533,6 @@ MODULE_DEVICE_TABLE(of, zs_match); static struct platform_driver zs_driver = { .driver = { .name = "zs", - .owner = THIS_MODULE, .of_match_table = zs_match, }, .probe = zs_probe, diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 0d11d5032b93..03e746378f1e 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -501,7 +501,6 @@ static int timbuart_remove(struct platform_device *dev) static struct platform_driver timbuart_platform_driver = { .driver = { .name = "timb-uart", - .owner = THIS_MODULE, }, .probe = timbuart_probe, .remove = timbuart_remove, diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index c107a0f0e72f..14d10fcfd210 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1485,7 +1485,6 @@ MODULE_DEVICE_TABLE(of, ucc_uart_match); static struct platform_driver ucc_uart_of_driver = { .driver = { .name = "ucc_uart", - .owner = THIS_MODULE, .of_match_table = ucc_uart_match, }, .probe = ucc_uart_probe, diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index d7f9d622cdcb..485de53c5d75 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c @@ -954,7 +954,6 @@ static struct platform_driver siu_device_driver = { .resume = siu_resume, .driver = { .name = "SIU", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index b2bc9e8ba048..4079ec56f5f9 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -745,7 +745,6 @@ static struct platform_driver vt8500_platform_driver = { .remove = vt8500_serial_remove, .driver = { .name = "vt8500_serial", - .owner = THIS_MODULE, .of_match_table = wmt_dt_ids, }, }; -- GitLab From 4e4b79d608978c3c2fb65c3eb02e65cd10d55648 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:45 +0200 Subject: [PATCH 0829/9457] tty: serial: 8250: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/tty/serial/8250/8250_core.c | 1 - drivers/tty/serial/8250/8250_dw.c | 1 - drivers/tty/serial/8250/8250_em.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index ca5cfdc1459a..27483d3fcfa0 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -3488,7 +3488,6 @@ static struct platform_driver serial8250_isa_driver = { .resume = serial8250_resume, .driver = { .name = "serial8250", - .owner = THIS_MODULE, }, }; diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index beea6ca73ee5..2f7a055d63b5 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -543,7 +543,6 @@ MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); static struct platform_driver dw8250_platform_driver = { .driver = { .name = "dw-apb-uart", - .owner = THIS_MODULE, .pm = &dw8250_pm_ops, .of_match_table = dw8250_of_match, .acpi_match_table = ACPI_PTR(dw8250_acpi_match), diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index 56c87232b6a0..3f0858d72411 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c @@ -161,7 +161,6 @@ static struct platform_driver serial8250_em_platform_driver = { .driver = { .name = "serial8250-em", .of_match_table = serial8250_em_dt_ids, - .owner = THIS_MODULE, }, .probe = serial8250_em_probe, .remove = serial8250_em_remove, -- GitLab From 2c15043e2283ca5ea42675fd8bb3f506766fefa6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:46 +0200 Subject: [PATCH 0830/9457] tty: serial: cpm_uart: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 533852eb8778..5a59f8db3b80 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1438,7 +1438,6 @@ static struct of_device_id cpm_uart_match[] = { static struct platform_driver cpm_uart_driver = { .driver = { .name = "cpm_uart", - .owner = THIS_MODULE, .of_match_table = cpm_uart_match, }, .probe = cpm_uart_probe, -- GitLab From 7021949a3150561ce9273158afafc067213e37ea Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:46 +0200 Subject: [PATCH 0831/9457] uio: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/uio/uio_dmem_genirq.c | 1 - drivers/uio/uio_pdrv_genirq.c | 1 - drivers/uio/uio_pruss.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 8d0bba469566..915facbf552e 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -343,7 +343,6 @@ static struct platform_driver uio_dmem_genirq = { .remove = uio_dmem_genirq_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &uio_dmem_genirq_dev_pm_ops, .of_match_table = of_match_ptr(uio_of_genirq_match), }, diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 76669313e9a7..f598ecddc8a7 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -266,7 +266,6 @@ static struct platform_driver uio_pdrv_genirq = { .remove = uio_pdrv_genirq_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &uio_pdrv_genirq_dev_pm_ops, .of_match_table = of_match_ptr(uio_of_genirq_match), }, diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index c28d6e2e3df2..818735bb8c3a 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -231,7 +231,6 @@ static struct platform_driver pruss_driver = { .remove = pruss_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From 52830d773ec305f84fa72194b5f1d177bda889d9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:46 +0200 Subject: [PATCH 0832/9457] usb: c67x00: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/c67x00/c67x00-drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 8db3380c3329..5796c8820514 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -221,7 +221,6 @@ static struct platform_driver c67x00_driver = { .probe = c67x00_drv_probe, .remove = c67x00_drv_remove, .driver = { - .owner = THIS_MODULE, .name = "c67x00", }, }; -- GitLab From 5bc879a6a2710557961f0965e8fee383ce16ad3c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:47 +0200 Subject: [PATCH 0833/9457] usb: chipidea: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/chipidea/ci_hdrc_imx.c | 1 - drivers/usb/chipidea/ci_hdrc_zevio.c | 1 - drivers/usb/chipidea/core.c | 1 - drivers/usb/chipidea/usbmisc_imx.c | 1 - 4 files changed, 4 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index a7ab0f15926e..e913792e4df5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -215,7 +215,6 @@ static struct platform_driver ci_hdrc_imx_driver = { .remove = ci_hdrc_imx_remove, .driver = { .name = "imx_usb", - .owner = THIS_MODULE, .of_match_table = ci_hdrc_imx_dt_ids, }, }; diff --git a/drivers/usb/chipidea/ci_hdrc_zevio.c b/drivers/usb/chipidea/ci_hdrc_zevio.c index 3bf6489ef5ec..d976fc1db73a 100644 --- a/drivers/usb/chipidea/ci_hdrc_zevio.c +++ b/drivers/usb/chipidea/ci_hdrc_zevio.c @@ -61,7 +61,6 @@ static struct platform_driver ci_hdrc_zevio_driver = { .remove = ci_hdrc_zevio_remove, .driver = { .name = "zevio_usb", - .owner = THIS_MODULE, .of_match_table = ci_hdrc_zevio_dt_ids, }, }; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3df5005c554d..b7e788446ed6 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -752,7 +752,6 @@ static struct platform_driver ci_hdrc_driver = { .remove = ci_hdrc_remove, .driver = { .name = "ci_hdrc", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 926c997ef310..7776ec676014 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -372,7 +372,6 @@ static struct platform_driver usbmisc_imx_driver = { .remove = usbmisc_imx_remove, .driver = { .name = "usbmisc_imx", - .owner = THIS_MODULE, .of_match_table = usbmisc_imx_dt_ids, }, }; -- GitLab From 7c3e90537b7489a46c4be57ca3f8e2293020e843 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:47 +0200 Subject: [PATCH 0834/9457] usb: dwc2: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/dwc2/gadget.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 7b5856fadd93..6c658219706b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3684,7 +3684,6 @@ MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids); static struct platform_driver s3c_hsotg_driver = { .driver = { .name = "s3c-hsotg", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(s3c_hsotg_of_ids), }, .probe = s3c_hsotg_probe, -- GitLab From e55a0137167f5ec61c2e91d05b38a7e7bf513095 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:48 +0200 Subject: [PATCH 0835/9457] usb: gadget: legacy: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/gadget/legacy/hid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 778613eb37af..3090aa2aa977 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -231,7 +231,6 @@ static __refdata struct usb_composite_driver hidg_driver = { static struct platform_driver hidg_plat_driver = { .remove = hidg_plat_driver_remove, .driver = { - .owner = THIS_MODULE, .name = "hidg", }, }; -- GitLab From 6d3f5f2d895b668ecade4a87d39c9c233b094b8d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:48 +0200 Subject: [PATCH 0836/9457] usb: gadget: udc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/gadget/udc/at91_udc.c | 1 - drivers/usb/gadget/udc/atmel_usba_udc.c | 1 - drivers/usb/gadget/udc/bcm63xx_udc.c | 1 - drivers/usb/gadget/udc/dummy_hcd.c | 2 -- drivers/usb/gadget/udc/fotg210-udc.c | 1 - drivers/usb/gadget/udc/fsl_qe_udc.c | 1 - drivers/usb/gadget/udc/fsl_udc_core.c | 1 - drivers/usb/gadget/udc/fusb300_udc.c | 1 - drivers/usb/gadget/udc/gr_udc.c | 1 - drivers/usb/gadget/udc/lpc32xx_udc.c | 1 - drivers/usb/gadget/udc/m66592-udc.c | 1 - drivers/usb/gadget/udc/mv_u3d_core.c | 1 - drivers/usb/gadget/udc/mv_udc_core.c | 1 - drivers/usb/gadget/udc/net2272.c | 1 - drivers/usb/gadget/udc/omap_udc.c | 1 - drivers/usb/gadget/udc/pxa25x_udc.c | 1 - drivers/usb/gadget/udc/pxa27x_udc.c | 1 - drivers/usb/gadget/udc/s3c-hsudc.c | 1 - drivers/usb/gadget/udc/s3c2410_udc.c | 1 - 19 files changed, 20 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 9968f5331fe4..41f91b4922eb 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1972,7 +1972,6 @@ static struct platform_driver at91_udc_driver = { .resume = at91udc_resume, .driver = { .name = (char *) driver_name, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91_udc_dt_ids), }, }; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 1529926e20a0..4721989ce641 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -2120,7 +2120,6 @@ static struct platform_driver udc_driver = { .remove = __exit_p(usba_udc_remove), .driver = { .name = "atmel_usba_udc", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_udc_dt_ids), }, }; diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 2235b8808700..55ed4a937ec5 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2425,7 +2425,6 @@ static struct platform_driver bcm63xx_udc_driver = { .remove = bcm63xx_udc_remove, .driver = { .name = DRV_MODULE_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(bcm63xx_udc_driver); diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 81dc5959e36b..bd3fc0ed0f30 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -1042,7 +1042,6 @@ static struct platform_driver dummy_udc_driver = { .resume = dummy_udc_resume, .driver = { .name = (char *) gadget_name, - .owner = THIS_MODULE, }, }; @@ -2612,7 +2611,6 @@ static struct platform_driver dummy_hcd_driver = { .resume = dummy_hcd_resume, .driver = { .name = (char *) driver_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index 1d315921bf34..9aaf485ceac6 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c @@ -1203,7 +1203,6 @@ static int fotg210_udc_probe(struct platform_device *pdev) static struct platform_driver fotg210_driver = { .driver = { .name = (char *)udc_name, - .owner = THIS_MODULE, }, .probe = fotg210_udc_probe, .remove = fotg210_udc_remove, diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index dd18ea38e391..fd71ee712abd 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2709,7 +2709,6 @@ MODULE_DEVICE_TABLE(of, qe_udc_match); static struct platform_driver udc_driver = { .driver = { .name = driver_name, - .owner = THIS_MODULE, .of_match_table = qe_udc_match, }, .probe = qe_udc_probe, diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index c3620791a315..8e71c9ce3f9f 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2669,7 +2669,6 @@ static struct platform_driver udc_driver = { .resume = fsl_udc_resume, .driver = { .name = driver_name, - .owner = THIS_MODULE, /* udc suspend/resume called from OTG driver */ .suspend = fsl_udc_otg_suspend, .resume = fsl_udc_otg_resume, diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 8286df72add4..f2d2f55be851 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1496,7 +1496,6 @@ static struct platform_driver fusb300_driver = { .remove = __exit_p(fusb300_remove), .driver = { .name = (char *) udc_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 1b3048a6a2a3..6902b04684e8 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -2262,7 +2262,6 @@ MODULE_DEVICE_TABLE(of, gr_match); static struct platform_driver gr_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = gr_match, }, .probe = gr_probe, diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index feab0bac8fdc..28a35da3797f 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3410,7 +3410,6 @@ static struct platform_driver lpc32xx_udc_driver = { .resume = lpc32xx_udc_resume, .driver = { .name = (char *) driver_name, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(lpc32xx_udc_of_match), }, }; diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 898565687a8c..36e1f7558dc9 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1699,7 +1699,6 @@ static struct platform_driver m66592_driver = { .remove = __exit_p(m66592_remove), .driver = { .name = (char *) udc_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 046a1f808b0d..0e48fc2ef7f6 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -2053,7 +2053,6 @@ static struct platform_driver mv_u3d_driver = { .remove = mv_u3d_remove, .shutdown = mv_u3d_shutdown, .driver = { - .owner = THIS_MODULE, .name = "mv-u3d", .pm = &mv_u3d_pm_ops, }, diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 3c5db80ae325..ffed7671cda7 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -2403,7 +2403,6 @@ static struct platform_driver udc_driver = { .remove = mv_udc_remove, .shutdown = mv_udc_shutdown, .driver = { - .owner = THIS_MODULE, .name = "mv-udc", #ifdef CONFIG_PM .pm = &mv_udc_pm_ops, diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 84d7162a8022..c12c29d770de 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -2674,7 +2674,6 @@ static struct platform_driver net2272_plat_driver = { .remove = net2272_plat_remove, .driver = { .name = driver_name, - .owner = THIS_MODULE, }, /* FIXME .suspend, .resume */ }; diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index dcdfea46003b..81a9aa3a3b2f 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -3026,7 +3026,6 @@ static struct platform_driver udc_driver = { .suspend = omap_udc_suspend, .resume = omap_udc_resume, .driver = { - .owner = THIS_MODULE, .name = (char *) driver_name, }, }; diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 42f7eeb8ff6f..42274f82e233 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -2271,7 +2271,6 @@ static struct platform_driver udc_driver = { .suspend = pxa25x_udc_suspend, .resume = pxa25x_udc_resume, .driver = { - .owner = THIS_MODULE, .name = "pxa25x-udc", }, }; diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 4868369eeec6..61bceedf515d 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2614,7 +2614,6 @@ MODULE_ALIAS("platform:pxa27x-udc"); static struct platform_driver udc_driver = { .driver = { .name = "pxa27x-udc", - .owner = THIS_MODULE, }, .probe = pxa_udc_probe, .remove = pxa_udc_remove, diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index dfbf55797360..712e569bcbd9 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1354,7 +1354,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) static struct platform_driver s3c_hsudc_driver = { .driver = { - .owner = THIS_MODULE, .name = "s3c-hsudc", }, .probe = s3c_hsudc_probe, diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index ff423d15beff..306734608ed9 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -1997,7 +1997,6 @@ MODULE_DEVICE_TABLE(platform, s3c_udc_ids); static struct platform_driver udc_driver_24x0 = { .driver = { .name = "s3c24x0-usbgadget", - .owner = THIS_MODULE, }, .probe = s3c2410_udc_probe, .remove = s3c2410_udc_remove, -- GitLab From 566e0269e58cb95aa759c3f11c831536ae3858d2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:49 +0200 Subject: [PATCH 0837/9457] usb: host: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/host/ehci-exynos.c | 1 - drivers/usb/host/ehci-orion.c | 1 - drivers/usb/host/ehci-platform.c | 1 - drivers/usb/host/ehci-w90x900.c | 1 - drivers/usb/host/fhci-hcd.c | 1 - drivers/usb/host/fsl-mph-dr-of.c | 1 - drivers/usb/host/isp116x-hcd.c | 1 - drivers/usb/host/isp1362-hcd.c | 1 - drivers/usb/host/isp1760-if.c | 1 - drivers/usb/host/ohci-at91.c | 1 - drivers/usb/host/ohci-exynos.c | 1 - drivers/usb/host/ohci-nxp.c | 1 - drivers/usb/host/ohci-omap.c | 1 - drivers/usb/host/ohci-platform.c | 1 - drivers/usb/host/ohci-pxa27x.c | 1 - drivers/usb/host/ohci-s3c2410.c | 1 - drivers/usb/host/ohci-spear.c | 1 - drivers/usb/host/r8a66597-hcd.c | 1 - drivers/usb/host/u132-hcd.c | 1 - 19 files changed, 19 deletions(-) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 7189f2e32ac2..e1b4f58283ad 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -323,7 +323,6 @@ static struct platform_driver exynos_ehci_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "exynos-ehci", - .owner = THIS_MODULE, .pm = &exynos_ehci_pm_ops, .of_match_table = of_match_ptr(exynos_ehci_match), } diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 22e15cab8ea5..ebd203ac3fad 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -321,7 +321,6 @@ static struct platform_driver ehci_orion_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "orion-ehci", - .owner = THIS_MODULE, .of_match_table = ehci_orion_dt_ids, }, }; diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 2f5b9ce3e042..bc6455c8b77a 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -379,7 +379,6 @@ static struct platform_driver ehci_platform_driver = { .remove = ehci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { - .owner = THIS_MODULE, .name = "ehci-platform", .pm = &ehci_platform_pm_ops, .of_match_table = vt8500_ehci_ids, diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index a9303aff125e..eb7a5a83fa3d 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -126,7 +126,6 @@ static struct platform_driver ehci_hcd_w90x900_driver = { .remove = ehci_w90x900_remove, .driver = { .name = "w90x900-ehci", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index a1a1ef521436..c6cebb96fd21 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -821,7 +821,6 @@ MODULE_DEVICE_TABLE(of, of_fhci_match); static struct platform_driver of_fhci_driver = { .driver = { .name = "fsl,usb-fhci", - .owner = THIS_MODULE, .of_match_table = of_fhci_match, }, .probe = of_fhci_probe, diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9162d1b6c0a3..7e325e90d7d9 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -326,7 +326,6 @@ static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { static struct platform_driver fsl_usb2_mph_dr_driver = { .driver = { .name = "fsl-usb2-mph-dr", - .owner = THIS_MODULE, .of_match_table = fsl_usb2_mph_dr_of_match, }, .probe = fsl_usb2_mph_dr_of_probe, diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 240e792c81a7..31c9c4d0fa0b 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1707,7 +1707,6 @@ static struct platform_driver isp116x_driver = { .resume = isp116x_resume, .driver = { .name = hcd_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 4bb37982855e..75e5876f9d7c 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2778,7 +2778,6 @@ static struct platform_driver isp1362_driver = { .resume = isp1362_resume, .driver = { .name = hcd_name, - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index df931e9ba5b5..09254a43bc01 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -161,7 +161,6 @@ MODULE_DEVICE_TABLE(of, of_isp1760_match); static struct platform_driver isp1760_of_driver = { .driver = { .name = "nxp-isp1760", - .owner = THIS_MODULE, .of_match_table = of_isp1760_match, }, .probe = of_isp1760_probe, diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e49eb4f90f5d..1a4ea93e620d 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -664,7 +664,6 @@ static struct platform_driver ohci_hcd_at91_driver = { .resume = ohci_hcd_at91_drv_resume, .driver = { .name = "at91_ohci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91_ohci_dt_ids), }, }; diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index d28b6583ba02..4589e3abba83 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -292,7 +292,6 @@ static struct platform_driver exynos_ohci_driver = { .shutdown = exynos_ohci_shutdown, .driver = { .name = "exynos-ohci", - .owner = THIS_MODULE, .pm = &exynos_ohci_pm_ops, .of_match_table = of_match_ptr(exynos_ohci_match), } diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index ba180ed0f81c..d9f0481d7258 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -322,7 +322,6 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match); static struct platform_driver ohci_hcd_nxp_driver = { .driver = { .name = "usb-ohci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ohci_hcd_nxp_match), }, .probe = ohci_hcd_nxp_probe, diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 0231606d47c2..989a90156f17 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -481,7 +481,6 @@ static struct platform_driver ohci_hcd_omap_driver = { .resume = ohci_omap_resume, #endif .driver = { - .owner = THIS_MODULE, .name = "ohci", }, }; diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4369299064c7..b348483ca174 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -364,7 +364,6 @@ static struct platform_driver ohci_platform_driver = { .remove = ohci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { - .owner = THIS_MODULE, .name = "ohci-platform", .pm = &ohci_platform_pm_ops, .of_match_table = ohci_platform_ids, diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e68f3d02cd1a..c069856ed39e 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -610,7 +610,6 @@ static struct platform_driver ohci_hcd_pxa27x_driver = { .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "pxa27x-ohci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pxa_ohci_dt_ids), #ifdef CONFIG_PM .pm = &ohci_hcd_pxa27x_pm_ops, diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 3d753a9d3141..095113ea1fcb 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -462,7 +462,6 @@ static struct platform_driver ohci_hcd_s3c2410_driver = { .remove = ohci_hcd_s3c2410_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { - .owner = THIS_MODULE, .name = "s3c2410-ohci", .pm = &ohci_hcd_s3c2410_pm_ops, }, diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 8d5876692e7c..062e173d8848 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -176,7 +176,6 @@ static struct platform_driver spear_ohci_hcd_driver = { .resume = spear_ohci_hcd_drv_resume, #endif .driver = { - .owner = THIS_MODULE, .name = "spear-ohci", .of_match_table = spear_ohci_id_table, }, diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 110b4b9ebeaa..c4bcfaedeec9 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2535,7 +2535,6 @@ static struct platform_driver r8a66597_driver = { .remove = r8a66597_remove, .driver = { .name = hcd_name, - .owner = THIS_MODULE, .pm = R8A66597_DEV_PM_OPS, }, }; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index c0671750671f..5972c0513182 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3219,7 +3219,6 @@ static struct platform_driver u132_platform_driver = { .resume = u132_resume, .driver = { .name = hcd_name, - .owner = THIS_MODULE, }, }; static int __init u132_hcd_init(void) -- GitLab From 45c74c06550b939c4e57c8f8c72e066256356c35 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:49 +0200 Subject: [PATCH 0838/9457] usb: misc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/misc/usb3503.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index ae7e1206ca54..20b4c30ef7b8 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -405,7 +405,6 @@ static struct platform_driver usb3503_platform_driver = { .driver = { .name = USB3503_I2C_NAME, .of_match_table = of_match_ptr(usb3503_of_match), - .owner = THIS_MODULE, }, .probe = usb3503_platform_probe, }; -- GitLab From 59a9e07b0b1eca239e060a8111e09e4057453192 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:50 +0200 Subject: [PATCH 0839/9457] usb: musb: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/musb/musb_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b841ee0bff06..4d81bb9d11db 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2362,7 +2362,6 @@ static struct platform_driver musb_driver = { .driver = { .name = (char *)musb_driver_name, .bus = &platform_bus_type, - .owner = THIS_MODULE, .pm = MUSB_DEV_PM_OPS, }, .probe = musb_probe, -- GitLab From a25f10c27c1cbdd5dafaa9018136aaba2fd53bcf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:50 +0200 Subject: [PATCH 0840/9457] usb: phy: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/phy/phy-ab8500-usb.c | 1 - drivers/usb/phy/phy-am335x-control.c | 1 - drivers/usb/phy/phy-am335x.c | 1 - drivers/usb/phy/phy-generic.c | 1 - drivers/usb/phy/phy-gpio-vbus-usb.c | 1 - drivers/usb/phy/phy-isp1301-omap.c | 1 - drivers/usb/phy/phy-keystone.c | 1 - drivers/usb/phy/phy-mv-usb.c | 1 - drivers/usb/phy/phy-mxs-usb.c | 1 - drivers/usb/phy/phy-omap-otg.c | 1 - drivers/usb/phy/phy-tahvo.c | 1 - drivers/usb/phy/phy-tegra-usb.c | 1 - drivers/usb/phy/phy-twl6030-usb.c | 1 - 13 files changed, 13 deletions(-) diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 11ab2c45e462..579ef4e9cc41 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -1505,7 +1505,6 @@ static struct platform_driver ab8500_usb_driver = { .id_table = ab8500_usb_devtype, .driver = { .name = "abx5x0-usb", - .owner = THIS_MODULE, }, }; diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 35b6083b7999..460b515cc5cf 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -175,7 +175,6 @@ static struct platform_driver am335x_control_driver = { .probe = am335x_control_usb_probe, .driver = { .name = "am335x-control-usb", - .owner = THIS_MODULE, .of_match_table = omap_control_usb_id_table, }, }; diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index b70e05537180..90b67a4ca221 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -137,7 +137,6 @@ static struct platform_driver am335x_phy_driver = { .remove = am335x_phy_remove, .driver = { .name = "am335x-phy-driver", - .owner = THIS_MODULE, .pm = &am335x_pm_ops, .of_match_table = am335x_phy_ids, }, diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 7594e5069ae5..1bb4d3adc9c7 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -286,7 +286,6 @@ static struct platform_driver usb_phy_generic_driver = { .remove = usb_phy_generic_remove, .driver = { .name = "usb_phy_generic", - .owner = THIS_MODULE, .of_match_table = nop_xceiv_dt_ids, }, }; diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index f4b14bd97e14..b5c368a9175f 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -380,7 +380,6 @@ MODULE_ALIAS("platform:gpio-vbus"); static struct platform_driver gpio_vbus_driver = { .driver = { .name = "gpio-vbus", - .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &gpio_vbus_dev_pm_ops, #endif diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 8eea56d3ded6..397b17134487 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -878,7 +878,6 @@ static struct platform_driver omap_otg_driver = { .probe = otg_probe, .remove = otg_remove, .driver = { - .owner = THIS_MODULE, .name = "omap_otg", }, }; diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index f4d722de912b..e0556f7832b5 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c @@ -123,7 +123,6 @@ static struct platform_driver keystone_usbphy_driver = { .remove = keystone_usbphy_remove, .driver = { .name = "keystone-usbphy", - .owner = THIS_MODULE, .of_match_table = keystone_usbphy_ids, }, }; diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 7d80c54f0ac6..2162f7a37f76 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -896,7 +896,6 @@ static struct platform_driver mv_otg_driver = { .probe = mv_otg_probe, .remove = mv_otg_remove, .driver = { - .owner = THIS_MODULE, .name = driver_name, }, #ifdef CONFIG_PM diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 0e0c41587a08..9aef6ca162fe 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -491,7 +491,6 @@ static struct platform_driver mxs_phy_driver = { .remove = mxs_phy_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = mxs_phy_dt_ids, .pm = &mxs_phy_pm, }, diff --git a/drivers/usb/phy/phy-omap-otg.c b/drivers/usb/phy/phy-omap-otg.c index 11598cdb3189..56ee7603034b 100644 --- a/drivers/usb/phy/phy-omap-otg.c +++ b/drivers/usb/phy/phy-omap-otg.c @@ -158,7 +158,6 @@ static struct platform_driver omap_otg_driver = { .probe = omap_otg_probe, .remove = omap_otg_remove, .driver = { - .owner = THIS_MODULE, .name = "omap_otg", }, }; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index cc61ee44b911..6a6777d2f57d 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -446,7 +446,6 @@ static struct platform_driver tahvo_usb_driver = { .remove = tahvo_usb_remove, .driver = { .name = "tahvo-usb", - .owner = THIS_MODULE, }, }; module_platform_driver(tahvo_usb_driver); diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 886f1807a67b..af9c9ec9b2a6 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -1086,7 +1086,6 @@ static struct platform_driver tegra_usb_phy_driver = { .remove = tegra_usb_phy_remove, .driver = { .name = "tegra-phy", - .owner = THIS_MODULE, .of_match_table = tegra_usb_phy_id_table, }, }; diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 44ea082e40dc..12741856a75c 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -430,7 +430,6 @@ static struct platform_driver twl6030_usb_driver = { .remove = twl6030_usb_remove, .driver = { .name = "twl6030_usb", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl6030_usb_id_table), }, }; -- GitLab From 0ca4ac7fb3a9b4c15d195778affc040415af90b4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:51 +0200 Subject: [PATCH 0841/9457] usb: usbip: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/usb/usbip/vhci_hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c02374b6049c..933143bccb7c 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1110,7 +1110,6 @@ static struct platform_driver vhci_driver = { .resume = vhci_hcd_resume, .driver = { .name = driver_name, - .owner = THIS_MODULE, }, }; -- GitLab From 6a732becfd2fe1525718de8eb5c17314265a15f2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:51 +0200 Subject: [PATCH 0842/9457] video: fbdev: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/amifb.c | 1 - drivers/video/fbdev/atmel_lcdfb.c | 1 - drivers/video/fbdev/au1100fb.c | 1 - drivers/video/fbdev/au1200fb.c | 1 - drivers/video/fbdev/auo_k1900fb.c | 1 - drivers/video/fbdev/auo_k1901fb.c | 1 - drivers/video/fbdev/bf537-lq035.c | 1 - drivers/video/fbdev/bf54x-lq043fb.c | 1 - drivers/video/fbdev/bfin-t350mcqb-fb.c | 1 - drivers/video/fbdev/broadsheetfb.c | 1 - drivers/video/fbdev/bw2.c | 1 - drivers/video/fbdev/cg14.c | 1 - drivers/video/fbdev/cg3.c | 1 - drivers/video/fbdev/cg6.c | 1 - drivers/video/fbdev/clps711x-fb.c | 1 - drivers/video/fbdev/clps711xfb.c | 1 - drivers/video/fbdev/cobalt_lcdfb.c | 1 - drivers/video/fbdev/da8xx-fb.c | 1 - drivers/video/fbdev/efifb.c | 1 - drivers/video/fbdev/ep93xx-fb.c | 1 - drivers/video/fbdev/ffb.c | 1 - drivers/video/fbdev/fsl-diu-fb.c | 1 - drivers/video/fbdev/grvga.c | 1 - drivers/video/fbdev/hecubafb.c | 1 - drivers/video/fbdev/hitfb.c | 1 - drivers/video/fbdev/imxfb.c | 1 - drivers/video/fbdev/leo.c | 1 - drivers/video/fbdev/metronomefb.c | 1 - drivers/video/fbdev/mx3fb.c | 1 - drivers/video/fbdev/nuc900fb.c | 1 - drivers/video/fbdev/p9100.c | 1 - drivers/video/fbdev/platinumfb.c | 1 - drivers/video/fbdev/pxa168fb.c | 1 - drivers/video/fbdev/pxa3xx-gcu.c | 1 - drivers/video/fbdev/pxafb.c | 1 - drivers/video/fbdev/s3c-fb.c | 1 - drivers/video/fbdev/s3c2410fb.c | 2 -- drivers/video/fbdev/sa1100fb.c | 1 - drivers/video/fbdev/sh7760fb.c | 1 - drivers/video/fbdev/sh_mobile_lcdcfb.c | 1 - drivers/video/fbdev/sh_mobile_meram.c | 1 - drivers/video/fbdev/simplefb.c | 1 - drivers/video/fbdev/sm501fb.c | 1 - drivers/video/fbdev/sunxvr1000.c | 1 - drivers/video/fbdev/tcx.c | 1 - drivers/video/fbdev/vesafb.c | 1 - drivers/video/fbdev/vt8500lcdfb.c | 1 - drivers/video/fbdev/wm8505fb.c | 1 - drivers/video/fbdev/wmt_ge_rops.c | 1 - drivers/video/fbdev/xilinxfb.c | 1 - 50 files changed, 51 deletions(-) diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c index 518f790ef88a..35f7900a0573 100644 --- a/drivers/video/fbdev/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -3782,7 +3782,6 @@ static struct platform_driver amifb_driver = { .remove = __exit_p(amifb_remove), .driver = { .name = "amiga-video", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 3bf403150a2d..98abb23f1066 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -1466,7 +1466,6 @@ static struct platform_driver atmel_lcdfb_driver = { .id_table = atmel_lcdfb_devtypes, .driver = { .name = "atmel_lcdfb", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_lcdfb_dt_ids), }, }; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 0676746ec68c..59560189b24a 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -638,7 +638,6 @@ int au1100fb_drv_resume(struct platform_device *dev) static struct platform_driver au1100fb_driver = { .driver = { .name = "au1100-lcd", - .owner = THIS_MODULE, }, .probe = au1100fb_drv_probe, .remove = au1100fb_drv_remove, diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 18600d4e1b3f..f9507b1894df 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1841,7 +1841,6 @@ static const struct dev_pm_ops au1200fb_pmops = { static struct platform_driver au1200fb_driver = { .driver = { .name = "au1200-lcd", - .owner = THIS_MODULE, .pm = AU1200FB_PMOPS, }, .probe = au1200fb_drv_probe, diff --git a/drivers/video/fbdev/auo_k1900fb.c b/drivers/video/fbdev/auo_k1900fb.c index f5b668e77af3..7637c60eae3d 100644 --- a/drivers/video/fbdev/auo_k1900fb.c +++ b/drivers/video/fbdev/auo_k1900fb.c @@ -193,7 +193,6 @@ static struct platform_driver auok1900fb_driver = { .probe = auok1900fb_probe, .remove = auok1900fb_remove, .driver = { - .owner = THIS_MODULE, .name = "auo_k1900fb", .pm = &auok190x_pm, }, diff --git a/drivers/video/fbdev/auo_k1901fb.c b/drivers/video/fbdev/auo_k1901fb.c index 12b9adcb75c5..681fe61957b6 100644 --- a/drivers/video/fbdev/auo_k1901fb.c +++ b/drivers/video/fbdev/auo_k1901fb.c @@ -246,7 +246,6 @@ static struct platform_driver auok1901fb_driver = { .probe = auok1901fb_probe, .remove = auok1901fb_remove, .driver = { - .owner = THIS_MODULE, .name = "auo_k1901fb", .pm = &auok190x_pm, }, diff --git a/drivers/video/fbdev/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c index a82d2578d976..7db3052b471d 100644 --- a/drivers/video/fbdev/bf537-lq035.c +++ b/drivers/video/fbdev/bf537-lq035.c @@ -894,7 +894,6 @@ static struct platform_driver bfin_lq035_driver = { .resume = bfin_lq035_resume, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c index adbef542c998..8f1f97c75619 100644 --- a/drivers/video/fbdev/bf54x-lq043fb.c +++ b/drivers/video/fbdev/bf54x-lq043fb.c @@ -756,7 +756,6 @@ static struct platform_driver bfin_bf54x_driver = { .resume = bfin_bf54x_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(bfin_bf54x_driver); diff --git a/drivers/video/fbdev/bfin-t350mcqb-fb.c b/drivers/video/fbdev/bfin-t350mcqb-fb.c index b5cf1307a3d9..e5ee4d9677f7 100644 --- a/drivers/video/fbdev/bfin-t350mcqb-fb.c +++ b/drivers/video/fbdev/bfin-t350mcqb-fb.c @@ -661,7 +661,6 @@ static struct platform_driver bfin_t350mcqb_driver = { .resume = bfin_t350mcqb_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; module_platform_driver(bfin_t350mcqb_driver); diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 8556264b16b7..1c29bd19e3d5 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -1212,7 +1212,6 @@ static struct platform_driver broadsheetfb_driver = { .probe = broadsheetfb_probe, .remove = broadsheetfb_remove, .driver = { - .owner = THIS_MODULE, .name = "broadsheetfb", }, }; diff --git a/drivers/video/fbdev/bw2.c b/drivers/video/fbdev/bw2.c index bc123d6947a4..8c5b281f0b29 100644 --- a/drivers/video/fbdev/bw2.c +++ b/drivers/video/fbdev/bw2.c @@ -377,7 +377,6 @@ MODULE_DEVICE_TABLE(of, bw2_match); static struct platform_driver bw2_driver = { .driver = { .name = "bw2", - .owner = THIS_MODULE, .of_match_table = bw2_match, }, .probe = bw2_probe, diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c index c79745b136bb..43e915eaf606 100644 --- a/drivers/video/fbdev/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -597,7 +597,6 @@ MODULE_DEVICE_TABLE(of, cg14_match); static struct platform_driver cg14_driver = { .driver = { .name = "cg14", - .owner = THIS_MODULE, .of_match_table = cg14_match, }, .probe = cg14_probe, diff --git a/drivers/video/fbdev/cg3.c b/drivers/video/fbdev/cg3.c index 64a89d5747ed..716391f22e75 100644 --- a/drivers/video/fbdev/cg3.c +++ b/drivers/video/fbdev/cg3.c @@ -463,7 +463,6 @@ MODULE_DEVICE_TABLE(of, cg3_match); static struct platform_driver cg3_driver = { .driver = { .name = "cg3", - .owner = THIS_MODULE, .of_match_table = cg3_match, }, .probe = cg3_probe, diff --git a/drivers/video/fbdev/cg6.c b/drivers/video/fbdev/cg6.c index 70781fea092a..bdf901ed5291 100644 --- a/drivers/video/fbdev/cg6.c +++ b/drivers/video/fbdev/cg6.c @@ -856,7 +856,6 @@ MODULE_DEVICE_TABLE(of, cg6_match); static struct platform_driver cg6_driver = { .driver = { .name = "cg6", - .owner = THIS_MODULE, .of_match_table = cg6_match, }, .probe = cg6_probe, diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c index 49a7bb4ef02f..649b32f78c08 100644 --- a/drivers/video/fbdev/clps711x-fb.c +++ b/drivers/video/fbdev/clps711x-fb.c @@ -384,7 +384,6 @@ MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids); static struct platform_driver clps711x_fb_driver = { .driver = { .name = CLPS711X_FB_NAME, - .owner = THIS_MODULE, .of_match_table = clps711x_fb_dt_ids, }, .probe = clps711x_fb_probe, diff --git a/drivers/video/fbdev/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c index f00980607b8f..7693aea8fb23 100644 --- a/drivers/video/fbdev/clps711xfb.c +++ b/drivers/video/fbdev/clps711xfb.c @@ -303,7 +303,6 @@ static int clps711x_fb_remove(struct platform_device *pdev) static struct platform_driver clps711x_fb_driver = { .driver = { .name = "video-clps711x", - .owner = THIS_MODULE, }, .probe = clps711x_fb_probe, .remove = clps711x_fb_remove, diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index d5533f4db1cf..07675d6f323e 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -391,7 +391,6 @@ static struct platform_driver cobalt_lcdfb_driver = { .remove = cobalt_lcdfb_remove, .driver = { .name = "cobalt-lcd", - .owner = THIS_MODULE, }, }; module_platform_driver(cobalt_lcdfb_driver); diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index 10c876c95772..0081725c6b5b 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -1659,7 +1659,6 @@ static struct platform_driver da8xx_fb_driver = { .remove = fb_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .pm = &fb_pm_ops, }, }; diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 982f6abe6faf..4bfff349b1fb 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -311,7 +311,6 @@ static int efifb_remove(struct platform_device *pdev) static struct platform_driver efifb_driver = { .driver = { .name = "efi-framebuffer", - .owner = THIS_MODULE, }, .probe = efifb_probe, .remove = efifb_remove, diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index 35a0f533f1a2..7ec251cc9c03 100644 --- a/drivers/video/fbdev/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -622,7 +622,6 @@ static struct platform_driver ep93xxfb_driver = { .remove = ep93xxfb_remove, .driver = { .name = "ep93xx-fb", - .owner = THIS_MODULE, }, }; module_platform_driver(ep93xxfb_driver); diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c index 4c4ffa61ae26..dda31e0a45af 100644 --- a/drivers/video/fbdev/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -1052,7 +1052,6 @@ MODULE_DEVICE_TABLE(of, ffb_match); static struct platform_driver ffb_driver = { .driver = { .name = "ffb", - .owner = THIS_MODULE, .of_match_table = ffb_match, }, .probe = ffb_probe, diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c index e8758b9c3bcc..7fa2e6f9e322 100644 --- a/drivers/video/fbdev/fsl-diu-fb.c +++ b/drivers/video/fbdev/fsl-diu-fb.c @@ -1881,7 +1881,6 @@ MODULE_DEVICE_TABLE(of, fsl_diu_match); static struct platform_driver fsl_diu_driver = { .driver = { .name = "fsl-diu-fb", - .owner = THIS_MODULE, .of_match_table = fsl_diu_match, }, .probe = fsl_diu_probe, diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c index 2db5bb1a33e8..b471f92969b1 100644 --- a/drivers/video/fbdev/grvga.c +++ b/drivers/video/fbdev/grvga.c @@ -549,7 +549,6 @@ MODULE_DEVICE_TABLE(of, svgactrl_of_match); static struct platform_driver grvga_driver = { .driver = { .name = "grlib-svgactrl", - .owner = THIS_MODULE, .of_match_table = svgactrl_of_match, }, .probe = grvga_probe, diff --git a/drivers/video/fbdev/hecubafb.c b/drivers/video/fbdev/hecubafb.c index f64120ec9192..e4031ef39491 100644 --- a/drivers/video/fbdev/hecubafb.c +++ b/drivers/video/fbdev/hecubafb.c @@ -300,7 +300,6 @@ static struct platform_driver hecubafb_driver = { .probe = hecubafb_probe, .remove = hecubafb_remove, .driver = { - .owner = THIS_MODULE, .name = "hecubafb", }, }; diff --git a/drivers/video/fbdev/hitfb.c b/drivers/video/fbdev/hitfb.c index a648d5186c6e..9d68dc9ee7bf 100644 --- a/drivers/video/fbdev/hitfb.c +++ b/drivers/video/fbdev/hitfb.c @@ -464,7 +464,6 @@ static struct platform_driver hitfb_driver = { .remove = hitfb_remove, .driver = { .name = "hitfb", - .owner = THIS_MODULE, .pm = &hitfb_dev_pm_ops, }, }; diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index f6e621684953..3b6a3c8c36e2 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -1061,7 +1061,6 @@ static struct platform_driver imxfb_driver = { .driver = { .name = DRIVER_NAME, .of_match_table = imxfb_of_dev_id, - .owner = THIS_MODULE, .pm = &imxfb_pm_ops, }, .probe = imxfb_probe, diff --git a/drivers/video/fbdev/leo.c b/drivers/video/fbdev/leo.c index 2c7f7d479fe2..62e59dc90ee6 100644 --- a/drivers/video/fbdev/leo.c +++ b/drivers/video/fbdev/leo.c @@ -662,7 +662,6 @@ MODULE_DEVICE_TABLE(of, leo_match); static struct platform_driver leo_driver = { .driver = { .name = "leo", - .owner = THIS_MODULE, .of_match_table = leo_match, }, .probe = leo_probe, diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c index 195cc2db4c2c..ad04a01e2761 100644 --- a/drivers/video/fbdev/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -766,7 +766,6 @@ static struct platform_driver metronomefb_driver = { .probe = metronomefb_probe, .remove = metronomefb_remove, .driver = { - .owner = THIS_MODULE, .name = "metronomefb", }, }; diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c index 23ec781e9a61..9c3f5f53cbd1 100644 --- a/drivers/video/fbdev/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -1646,7 +1646,6 @@ static int mx3fb_remove(struct platform_device *dev) static struct platform_driver mx3fb_driver = { .driver = { .name = MX3FB_NAME, - .owner = THIS_MODULE, }, .probe = mx3fb_probe, .remove = mx3fb_remove, diff --git a/drivers/video/fbdev/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c index 478f9808dee4..389fa2cbb713 100644 --- a/drivers/video/fbdev/nuc900fb.c +++ b/drivers/video/fbdev/nuc900fb.c @@ -755,7 +755,6 @@ static struct platform_driver nuc900fb_driver = { .resume = nuc900fb_resume, .driver = { .name = "nuc900-lcd", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/p9100.c b/drivers/video/fbdev/p9100.c index 367cea8f43f3..1f6ee76af878 100644 --- a/drivers/video/fbdev/p9100.c +++ b/drivers/video/fbdev/p9100.c @@ -353,7 +353,6 @@ MODULE_DEVICE_TABLE(of, p9100_match); static struct platform_driver p9100_driver = { .driver = { .name = "p9100", - .owner = THIS_MODULE, .of_match_table = p9100_match, }, .probe = p9100_probe, diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c index 4c9299576827..518d1fd38a81 100644 --- a/drivers/video/fbdev/platinumfb.c +++ b/drivers/video/fbdev/platinumfb.c @@ -679,7 +679,6 @@ static struct platform_driver platinum_driver = { .driver = { .name = "platinumfb", - .owner = THIS_MODULE, .of_match_table = platinumfb_match, }, .probe = platinumfb_probe, diff --git a/drivers/video/fbdev/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c index c95b9e46d48f..e209b039f553 100644 --- a/drivers/video/fbdev/pxa168fb.c +++ b/drivers/video/fbdev/pxa168fb.c @@ -823,7 +823,6 @@ static int pxa168fb_remove(struct platform_device *pdev) static struct platform_driver pxa168fb_driver = { .driver = { .name = "pxa168-fb", - .owner = THIS_MODULE, }, .probe = pxa168fb_probe, .remove = pxa168fb_remove, diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c index 4df3657fe221..86bd457d039d 100644 --- a/drivers/video/fbdev/pxa3xx-gcu.c +++ b/drivers/video/fbdev/pxa3xx-gcu.c @@ -707,7 +707,6 @@ static struct platform_driver pxa3xx_gcu_driver = { .probe = pxa3xx_gcu_probe, .remove = pxa3xx_gcu_remove, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index a5acca88fa63..da2431eda2fd 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -2304,7 +2304,6 @@ static struct platform_driver pxafb_driver = { .probe = pxafb_probe, .remove = pxafb_remove, .driver = { - .owner = THIS_MODULE, .name = "pxa2xx-fb", #ifdef CONFIG_PM .pm = &pxafb_pm_ops, diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c index b33abb0a433d..a623a4d0c94f 100644 --- a/drivers/video/fbdev/s3c-fb.c +++ b/drivers/video/fbdev/s3c-fb.c @@ -1971,7 +1971,6 @@ static struct platform_driver s3c_fb_driver = { .id_table = s3c_fb_driver_ids, .driver = { .name = "s3c-fb", - .owner = THIS_MODULE, .pm = &s3cfb_pm_ops, }, }; diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index e350eb57f11d..d6704add1601 100644 --- a/drivers/video/fbdev/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c @@ -1104,7 +1104,6 @@ static struct platform_driver s3c2410fb_driver = { .resume = s3c2410fb_resume, .driver = { .name = "s3c2410-lcd", - .owner = THIS_MODULE, }, }; @@ -1115,7 +1114,6 @@ static struct platform_driver s3c2412fb_driver = { .resume = s3c2410fb_resume, .driver = { .name = "s3c2412-lcd", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 9690216d38ff..4900b37d2240 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -1288,7 +1288,6 @@ static struct platform_driver sa1100fb_driver = { .resume = sa1100fb_resume, .driver = { .name = "sa11x0-fb", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c index 1265b25f9f99..96de91d76623 100644 --- a/drivers/video/fbdev/sh7760fb.c +++ b/drivers/video/fbdev/sh7760fb.c @@ -578,7 +578,6 @@ static int sh7760fb_remove(struct platform_device *dev) static struct platform_driver sh7760_lcdc_driver = { .driver = { .name = "sh7760-lcdc", - .owner = THIS_MODULE, }, .probe = sh7760fb_probe, .remove = sh7760fb_remove, diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 2bcc84ac18c7..ba03c8e65ddb 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -2849,7 +2849,6 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) static struct platform_driver sh_mobile_lcdc_driver = { .driver = { .name = "sh_mobile_lcdc_fb", - .owner = THIS_MODULE, .pm = &sh_mobile_lcdc_dev_pm_ops, }, .probe = sh_mobile_lcdc_probe, diff --git a/drivers/video/fbdev/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c index a297de5cc859..1d56108dee9c 100644 --- a/drivers/video/fbdev/sh_mobile_meram.c +++ b/drivers/video/fbdev/sh_mobile_meram.c @@ -745,7 +745,6 @@ static int sh_mobile_meram_remove(struct platform_device *pdev) static struct platform_driver sh_mobile_meram_driver = { .driver = { .name = "sh_mobile_meram", - .owner = THIS_MODULE, .pm = &sh_mobile_meram_dev_pm_ops, }, .probe = sh_mobile_meram_probe, diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 210f3a02121a..76756c80cad6 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -267,7 +267,6 @@ MODULE_DEVICE_TABLE(of, simplefb_of_match); static struct platform_driver simplefb_driver = { .driver = { .name = "simple-framebuffer", - .owner = THIS_MODULE, .of_match_table = simplefb_of_match, }, .probe = simplefb_probe, diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index 9e74e8fbe074..0f8fb9925e11 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -2224,7 +2224,6 @@ static struct platform_driver sm501fb_driver = { .resume = sm501fb_resume, .driver = { .name = "sm501-fb", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c index 58241b47a96d..08879bdfad35 100644 --- a/drivers/video/fbdev/sunxvr1000.c +++ b/drivers/video/fbdev/sunxvr1000.c @@ -202,7 +202,6 @@ static struct platform_driver gfb_driver = { .remove = gfb_remove, .driver = { .name = "gfb", - .owner = THIS_MODULE, .of_match_table = gfb_match, }, }; diff --git a/drivers/video/fbdev/tcx.c b/drivers/video/fbdev/tcx.c index 7fb2d696fac7..54ad08854c94 100644 --- a/drivers/video/fbdev/tcx.c +++ b/drivers/video/fbdev/tcx.c @@ -512,7 +512,6 @@ MODULE_DEVICE_TABLE(of, tcx_match); static struct platform_driver tcx_driver = { .driver = { .name = "tcx", - .owner = THIS_MODULE, .of_match_table = tcx_match, }, .probe = tcx_probe, diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index 6170e7f58640..d79a0ac49fc7 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -512,7 +512,6 @@ static int vesafb_remove(struct platform_device *pdev) static struct platform_driver vesafb_driver = { .driver = { .name = "vesa-framebuffer", - .owner = THIS_MODULE, }, .probe = vesafb_probe, .remove = vesafb_remove, diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index a1134c3f6c11..ffaf29eeaaba 100644 --- a/drivers/video/fbdev/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -486,7 +486,6 @@ static struct platform_driver vt8500lcd_driver = { .probe = vt8500lcd_probe, .remove = vt8500lcd_remove, .driver = { - .owner = THIS_MODULE, .name = "vt8500-lcd", .of_match_table = of_match_ptr(via_dt_ids), }, diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c index d2fafbbcd7f8..e925619da39b 100644 --- a/drivers/video/fbdev/wm8505fb.c +++ b/drivers/video/fbdev/wm8505fb.c @@ -407,7 +407,6 @@ static struct platform_driver wm8505fb_driver = { .probe = wm8505fb_probe, .remove = wm8505fb_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = wmt_dt_ids, }, diff --git a/drivers/video/fbdev/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c index 9df6fe78a44b..89d23844c1db 100644 --- a/drivers/video/fbdev/wmt_ge_rops.c +++ b/drivers/video/fbdev/wmt_ge_rops.c @@ -167,7 +167,6 @@ static struct platform_driver wmt_ge_rops_driver = { .probe = wmt_ge_rops_probe, .remove = wmt_ge_rops_remove, .driver = { - .owner = THIS_MODULE, .name = "wmt_ge_rops", .of_match_table = wmt_dt_ids, }, diff --git a/drivers/video/fbdev/xilinxfb.c b/drivers/video/fbdev/xilinxfb.c index 553cff2f3f4c..17dc119c7a98 100644 --- a/drivers/video/fbdev/xilinxfb.c +++ b/drivers/video/fbdev/xilinxfb.c @@ -497,7 +497,6 @@ static struct platform_driver xilinxfb_of_driver = { .remove = xilinxfb_of_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = xilinxfb_of_match, }, }; -- GitLab From e7ddb0fe0f650b866a26a0ff216a1b5f3ad58f6d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:52 +0200 Subject: [PATCH 0843/9457] video: fbdev: exynos: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/exynos/exynos_mipi_dsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c index cee9602f9a7b..cc702df8605a 100644 --- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c @@ -562,7 +562,6 @@ static struct platform_driver exynos_mipi_dsi_driver = { .remove = exynos_mipi_dsi_remove, .driver = { .name = "exynos-mipi-dsim", - .owner = THIS_MODULE, .pm = &exynos_mipi_dsi_pm_ops, }, }; -- GitLab From 089cdbe631d9cfb4b8dcb14fb5e6611da9c50438 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:52 +0200 Subject: [PATCH 0844/9457] video: fbdev: mb862xx: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/mb862xx/mb862xxfbdrv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index 0cd4c3318511..9b8bebdf8f86 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -835,7 +835,6 @@ static struct of_device_id of_platform_mb862xx_tbl[] = { static struct platform_driver of_platform_mb862xxfb_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_platform_mb862xx_tbl, }, .probe = of_platform_mb862xx_probe, -- GitLab From 204ec8d34fbf049bec2bafdbf525f3d943705731 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:53 +0200 Subject: [PATCH 0845/9457] video: fbdev: mmp: fb: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/mmp/fb/mmpfb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c index 910fcc6ecece..92279e02dd94 100644 --- a/drivers/video/fbdev/mmp/fb/mmpfb.c +++ b/drivers/video/fbdev/mmp/fb/mmpfb.c @@ -673,7 +673,6 @@ static int mmpfb_probe(struct platform_device *pdev) static struct platform_driver mmpfb_driver = { .driver = { .name = "mmp-fb", - .owner = THIS_MODULE, }, .probe = mmpfb_probe, }; -- GitLab From dcb7b311646f0b95c8a950a0be842fe5e195b904 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:53 +0200 Subject: [PATCH 0846/9457] video: fbdev: mmp: hw: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/mmp/hw/mmp_ctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c index 8621a9f2bdcc..117383634de9 100644 --- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c +++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c @@ -572,7 +572,6 @@ static int mmphw_probe(struct platform_device *pdev) static struct platform_driver mmphw_driver = { .driver = { .name = "mmp-disp", - .owner = THIS_MODULE, }, .probe = mmphw_probe, }; -- GitLab From 6355721ca99ba9bed213aaae892e70c54f41cb57 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:54 +0200 Subject: [PATCH 0847/9457] video: fbdev: omap: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/omap/lcd_ams_delta.c | 1 - drivers/video/fbdev/omap/lcd_h3.c | 1 - drivers/video/fbdev/omap/lcd_htcherald.c | 1 - drivers/video/fbdev/omap/lcd_inn1510.c | 1 - drivers/video/fbdev/omap/lcd_inn1610.c | 1 - drivers/video/fbdev/omap/lcd_osk.c | 1 - drivers/video/fbdev/omap/lcd_palmte.c | 1 - drivers/video/fbdev/omap/lcd_palmtt.c | 1 - drivers/video/fbdev/omap/lcd_palmz71.c | 1 - drivers/video/fbdev/omap/omapfb_main.c | 1 - 10 files changed, 10 deletions(-) diff --git a/drivers/video/fbdev/omap/lcd_ams_delta.c b/drivers/video/fbdev/omap/lcd_ams_delta.c index 4a5f2cd3d3bf..f912a207b394 100644 --- a/drivers/video/fbdev/omap/lcd_ams_delta.c +++ b/drivers/video/fbdev/omap/lcd_ams_delta.c @@ -218,7 +218,6 @@ static struct platform_driver ams_delta_panel_driver = { .resume = ams_delta_panel_resume, .driver = { .name = "lcd_ams_delta", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c index 49bdeca81e50..a0729d0200d0 100644 --- a/drivers/video/fbdev/omap/lcd_h3.c +++ b/drivers/video/fbdev/omap/lcd_h3.c @@ -120,7 +120,6 @@ static struct platform_driver h3_panel_driver = { .resume = h3_panel_resume, .driver = { .name = "lcd_h3", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c index 20f477851d54..8b4dfa058258 100644 --- a/drivers/video/fbdev/omap/lcd_htcherald.c +++ b/drivers/video/fbdev/omap/lcd_htcherald.c @@ -111,7 +111,6 @@ static struct platform_driver htcherald_panel_driver = { .resume = htcherald_panel_resume, .driver = { .name = "lcd_htcherald", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c index 2ee423279e35..49907fab36ac 100644 --- a/drivers/video/fbdev/omap/lcd_inn1510.c +++ b/drivers/video/fbdev/omap/lcd_inn1510.c @@ -106,7 +106,6 @@ static struct platform_driver innovator1510_panel_driver = { .resume = innovator1510_panel_resume, .driver = { .name = "lcd_inn1510", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c index e3d3d135aa48..8b42894eeb77 100644 --- a/drivers/video/fbdev/omap/lcd_inn1610.c +++ b/drivers/video/fbdev/omap/lcd_inn1610.c @@ -127,7 +127,6 @@ static struct platform_driver innovator1610_panel_driver = { .resume = innovator1610_panel_resume, .driver = { .name = "lcd_inn1610", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c index 7fbe04bce0ed..c3ddebf934b2 100644 --- a/drivers/video/fbdev/omap/lcd_osk.c +++ b/drivers/video/fbdev/omap/lcd_osk.c @@ -126,7 +126,6 @@ static struct platform_driver osk_panel_driver = { .resume = osk_panel_resume, .driver = { .name = "lcd_osk", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_palmte.c b/drivers/video/fbdev/omap/lcd_palmte.c index ff4fb624b904..2713fed286f7 100644 --- a/drivers/video/fbdev/omap/lcd_palmte.c +++ b/drivers/video/fbdev/omap/lcd_palmte.c @@ -103,7 +103,6 @@ static struct platform_driver palmte_panel_driver = { .resume = palmte_panel_resume, .driver = { .name = "lcd_palmte", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c index aaf3c8ba1243..3d0ea04ec248 100644 --- a/drivers/video/fbdev/omap/lcd_palmtt.c +++ b/drivers/video/fbdev/omap/lcd_palmtt.c @@ -109,7 +109,6 @@ static struct platform_driver palmtt_panel_driver = { .resume = palmtt_panel_resume, .driver = { .name = "lcd_palmtt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c index 3b7d8aa1cf34..a20db4f7ea99 100644 --- a/drivers/video/fbdev/omap/lcd_palmz71.c +++ b/drivers/video/fbdev/omap/lcd_palmz71.c @@ -105,7 +105,6 @@ static struct platform_driver palmz71_panel_driver = { .resume = palmz71_panel_resume, .driver = { .name = "lcd_palmz71", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c index d8d028d98711..1fb3ea3c98a1 100644 --- a/drivers/video/fbdev/omap/omapfb_main.c +++ b/drivers/video/fbdev/omap/omapfb_main.c @@ -1869,7 +1869,6 @@ static struct platform_driver omapfb_driver = { .resume = omapfb_resume, .driver = { .name = MODULE_NAME, - .owner = THIS_MODULE, }, }; -- GitLab From fb04e18e55772361509634bf7b74f248ce827247 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:54 +0200 Subject: [PATCH 0848/9457] video: fbdev: omap2: displays-new: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c | 1 - drivers/video/fbdev/omap2/displays-new/connector-dvi.c | 1 - drivers/video/fbdev/omap2/displays-new/connector-hdmi.c | 1 - drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c | 1 - drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c | 1 - drivers/video/fbdev/omap2/displays-new/panel-dpi.c | 1 - drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c | 1 - drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c | 1 - 8 files changed, 8 deletions(-) diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c index 5ee3b5505f7f..5fb8aca1792c 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c @@ -306,7 +306,6 @@ static struct platform_driver tvc_connector_driver = { .remove = __exit_p(tvc_remove), .driver = { .name = "connector-analog-tv", - .owner = THIS_MODULE, .of_match_table = tvc_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c index 74de2bc50c4f..bb211c84d27f 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c @@ -389,7 +389,6 @@ static struct platform_driver dvi_connector_driver = { .remove = __exit_p(dvic_remove), .driver = { .name = "connector-dvi", - .owner = THIS_MODULE, .of_match_table = dvic_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c index 131c6e260898..daac64888e29 100644 --- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c @@ -435,7 +435,6 @@ static struct platform_driver hdmi_connector_driver = { .remove = __exit_p(hdmic_remove), .driver = { .name = "connector-hdmi", - .owner = THIS_MODULE, .of_match_table = hdmic_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c index b4e9a42a79e6..207b782df268 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c @@ -296,7 +296,6 @@ static struct platform_driver tfp410_driver = { .remove = __exit_p(tfp410_remove), .driver = { .name = "tfp410", - .owner = THIS_MODULE, .of_match_table = tfp410_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c index c891d8f84cb2..d89cfda4a0bc 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c @@ -459,7 +459,6 @@ static struct platform_driver tpd_driver = { .remove = __exit_p(tpd_remove), .driver = { .name = "tpd12s015", - .owner = THIS_MODULE, .of_match_table = tpd_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c index 3636b61dc9b4..9d557456d14c 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c @@ -325,7 +325,6 @@ static struct platform_driver panel_dpi_driver = { .remove = __exit_p(panel_dpi_remove), .driver = { .name = "panel-dpi", - .owner = THIS_MODULE, .of_match_table = panel_dpi_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c index d6f14e8717e8..28f1bd34846c 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c @@ -1376,7 +1376,6 @@ static struct platform_driver dsicm_driver = { .remove = __exit_p(dsicm_remove), .driver = { .name = "panel-dsi-cm", - .owner = THIS_MODULE, .of_match_table = dsicm_of_match, }, }; diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c index f1f72ce50a17..9357f4087b63 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c @@ -408,7 +408,6 @@ static struct platform_driver sharp_ls_driver = { .remove = __exit_p(sharp_ls_remove), .driver = { .name = "panel-sharp-ls037v7dw01", - .owner = THIS_MODULE, .of_match_table = sharp_ls_of_match, }, }; -- GitLab From f1782b478bbd7368f0dfaca12e39f9e31e7aa67e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:54 +0200 Subject: [PATCH 0849/9457] video: fbdev: omap2: dss: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/omap2/dss/core.c | 1 - drivers/video/fbdev/omap2/dss/dispc.c | 1 - drivers/video/fbdev/omap2/dss/dpi.c | 1 - drivers/video/fbdev/omap2/dss/dsi.c | 1 - drivers/video/fbdev/omap2/dss/dss.c | 1 - drivers/video/fbdev/omap2/dss/hdmi4.c | 1 - drivers/video/fbdev/omap2/dss/hdmi5.c | 1 - drivers/video/fbdev/omap2/dss/rfbi.c | 1 - drivers/video/fbdev/omap2/dss/sdi.c | 1 - drivers/video/fbdev/omap2/dss/venc.c | 1 - 10 files changed, 10 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c index 6b74f73fb524..d5d92124e019 100644 --- a/drivers/video/fbdev/omap2/dss/core.c +++ b/drivers/video/fbdev/omap2/dss/core.c @@ -244,7 +244,6 @@ static struct platform_driver omap_dss_driver = { .shutdown = omap_dss_shutdown, .driver = { .name = "omapdss", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index be053aa80880..f5ebc2bc1e3a 100644 --- a/drivers/video/fbdev/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -3840,7 +3840,6 @@ static struct platform_driver omap_dispchw_driver = { .remove = __exit_p(omap_dispchw_remove), .driver = { .name = "omapdss_dispc", - .owner = THIS_MODULE, .pm = &dispc_pm_ops, .of_match_table = dispc_of_match, }, diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index 9368972d6962..4a44a9059e7f 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -719,7 +719,6 @@ static struct platform_driver omap_dpi_driver = { .remove = __exit_p(omap_dpi_remove), .driver = { .name = "omapdss_dpi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index b6f6ae1d4664..ef45ffb7e210 100644 --- a/drivers/video/fbdev/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c @@ -5751,7 +5751,6 @@ static struct platform_driver omap_dsihw_driver = { .remove = __exit_p(omap_dsihw_remove), .driver = { .name = "omapdss_dsi", - .owner = THIS_MODULE, .pm = &dsi_pm_ops, .of_match_table = dsi_of_match, }, diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 6daeb7ed44c6..6bae84f4953b 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -963,7 +963,6 @@ static struct platform_driver omap_dsshw_driver = { .remove = __exit_p(omap_dsshw_remove), .driver = { .name = "omapdss_dss", - .owner = THIS_MODULE, .pm = &dss_pm_ops, .of_match_table = dss_of_match, }, diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 6a8550cf43e5..3d2708c6c85f 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -778,7 +778,6 @@ static struct platform_driver omapdss_hdmihw_driver = { .remove = __exit_p(omapdss_hdmihw_remove), .driver = { .name = "omapdss_hdmi", - .owner = THIS_MODULE, .pm = &hdmi_pm_ops, .of_match_table = hdmi_of_match, }, diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index 32d02ec34d23..e03a8b4f9a61 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -803,7 +803,6 @@ static struct platform_driver omapdss_hdmihw_driver = { .remove = __exit_p(omapdss_hdmihw_remove), .driver = { .name = "omapdss_hdmi5", - .owner = THIS_MODULE, .pm = &hdmi_pm_ops, .of_match_table = hdmi_of_match, }, diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c index c8a81a2b879c..0726b1c1dfe6 100644 --- a/drivers/video/fbdev/omap2/dss/rfbi.c +++ b/drivers/video/fbdev/omap2/dss/rfbi.c @@ -1042,7 +1042,6 @@ static struct platform_driver omap_rfbihw_driver = { .remove = __exit_p(omap_rfbihw_remove), .driver = { .name = "omapdss_rfbi", - .owner = THIS_MODULE, .pm = &rfbi_pm_ops, }, }; diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index 911dcc9173a6..d65063c62456 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -376,7 +376,6 @@ static struct platform_driver omap_sdi_driver = { .remove = __exit_p(omap_sdi_remove), .driver = { .name = "omapdss_sdi", - .owner = THIS_MODULE, }, }; diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c index 21d81113962b..de1d716134c6 100644 --- a/drivers/video/fbdev/omap2/dss/venc.c +++ b/drivers/video/fbdev/omap2/dss/venc.c @@ -963,7 +963,6 @@ static struct platform_driver omap_venchw_driver = { .remove = __exit_p(omap_venchw_remove), .driver = { .name = "omapdss_venc", - .owner = THIS_MODULE, .pm = &venc_pm_ops, .of_match_table = venc_of_match, }, -- GitLab From 3dd15a12486c6435b1d04b78ccf0b348880d0bfb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:55 +0200 Subject: [PATCH 0850/9457] video: fbdev: omap2: omapfb: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index 15872433e0c6..b11b0e4f1c00 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -2639,7 +2639,6 @@ static struct platform_driver omapfb_driver = { .remove = __exit_p(omapfb_remove), .driver = { .name = "omapfb", - .owner = THIS_MODULE, }, }; -- GitLab From 257d6e5a3bc7866703748b4ca07dd67f3c1e35ba Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:55 +0200 Subject: [PATCH 0851/9457] virtio: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/virtio/virtio_mmio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index ef9a1650bb80..5b0917670f89 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -639,7 +639,6 @@ static struct platform_driver virtio_mmio_driver = { .remove = virtio_mmio_remove, .driver = { .name = "virtio-mmio", - .owner = THIS_MODULE, .of_match_table = virtio_mmio_match, }, }; -- GitLab From ce882ad3c93fc076457ce9b97c19735b52b88c45 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:56 +0200 Subject: [PATCH 0852/9457] w1: masters: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/w1/masters/mxc_w1.c | 1 - drivers/w1/masters/w1-gpio.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index da3d0f0ad63c..53bf2c860ad3 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -175,7 +175,6 @@ MODULE_DEVICE_TABLE(of, mxc_w1_dt_ids); static struct platform_driver mxc_w1_driver = { .driver = { .name = "mxc_w1", - .owner = THIS_MODULE, .of_match_table = mxc_w1_dt_ids, }, .probe = mxc_w1_probe, diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index 1d111e56c8c8..b99a932ad901 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -228,7 +228,6 @@ static int w1_gpio_resume(struct platform_device *pdev) static struct platform_driver w1_gpio_driver = { .driver = { .name = "w1-gpio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(w1_gpio_dt_ids), }, .probe = w1_gpio_probe, -- GitLab From fa21a580dea456c03fcf69203dcd0195df3f7dee Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:56 +0200 Subject: [PATCH 0853/9457] watchdog: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/watchdog/acquirewdt.c | 1 - drivers/watchdog/advantechwdt.c | 1 - drivers/watchdog/ar7_wdt.c | 1 - drivers/watchdog/at32ap700x_wdt.c | 1 - drivers/watchdog/at91rm9200_wdt.c | 1 - drivers/watchdog/at91sam9_wdt.c | 1 - drivers/watchdog/ath79_wdt.c | 1 - drivers/watchdog/bcm2835_wdt.c | 1 - drivers/watchdog/bcm47xx_wdt.c | 1 - drivers/watchdog/bcm63xx_wdt.c | 1 - drivers/watchdog/bcm_kona_wdt.c | 1 - drivers/watchdog/bfin_wdt.c | 1 - drivers/watchdog/coh901327_wdt.c | 1 - drivers/watchdog/cpwd.c | 1 - drivers/watchdog/davinci_wdt.c | 1 - drivers/watchdog/dw_wdt.c | 1 - drivers/watchdog/ep93xx_wdt.c | 1 - drivers/watchdog/gef_wdt.c | 1 - drivers/watchdog/geodewdt.c | 1 - drivers/watchdog/gpio_wdt.c | 1 - drivers/watchdog/iTCO_wdt.c | 1 - drivers/watchdog/ib700wdt.c | 1 - drivers/watchdog/ie6xx_wdt.c | 1 - drivers/watchdog/imx2_wdt.c | 1 - drivers/watchdog/intel-mid_wdt.c | 1 - drivers/watchdog/jz4740_wdt.c | 1 - drivers/watchdog/kempld_wdt.c | 1 - drivers/watchdog/ks8695_wdt.c | 1 - drivers/watchdog/lantiq_wdt.c | 1 - drivers/watchdog/max63xx_wdt.c | 1 - drivers/watchdog/menf21bmc_wdt.c | 1 - drivers/watchdog/moxart_wdt.c | 1 - drivers/watchdog/mpc8xxx_wdt.c | 1 - drivers/watchdog/mv64x60_wdt.c | 1 - drivers/watchdog/nuc900_wdt.c | 1 - drivers/watchdog/nv_tco.c | 1 - drivers/watchdog/of_xilinx_wdt.c | 1 - drivers/watchdog/omap_wdt.c | 1 - drivers/watchdog/orion_wdt.c | 1 - drivers/watchdog/pnx4008_wdt.c | 1 - drivers/watchdog/rdc321x_wdt.c | 1 - drivers/watchdog/riowd.c | 1 - drivers/watchdog/rt2880_wdt.c | 1 - drivers/watchdog/s3c2410_wdt.c | 1 - drivers/watchdog/sch311x_wdt.c | 1 - drivers/watchdog/shwdt.c | 1 - drivers/watchdog/sirfsoc_wdt.c | 1 - drivers/watchdog/sp5100_tco.c | 1 - drivers/watchdog/sunxi_wdt.c | 1 - drivers/watchdog/tegra_wdt.c | 1 - drivers/watchdog/ts72xx_wdt.c | 1 - drivers/watchdog/twl4030_wdt.c | 1 - drivers/watchdog/txx9wdt.c | 1 - drivers/watchdog/ux500_wdt.c | 1 - drivers/watchdog/xen_wdt.c | 1 - 55 files changed, 55 deletions(-) diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 5614416f1032..d6210d946082 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -294,7 +294,6 @@ static struct platform_driver acquirewdt_driver = { .remove = acq_remove, .shutdown = acq_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 7796db7fa6e1..7d7db0c5a64e 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c @@ -302,7 +302,6 @@ static struct platform_driver advwdt_driver = { .remove = advwdt_remove, .shutdown = advwdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index ae6c287a49cb..6d5ae251e309 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c @@ -324,7 +324,6 @@ static struct platform_driver ar7_wdt_driver = { .remove = ar7_wdt_remove, .shutdown = ar7_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = "ar7_wdt", }, }; diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index 25b5c67d3af9..81ba8920f127 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c @@ -422,7 +422,6 @@ static struct platform_driver at32_wdt_driver = { .resume = at32_wdt_resume, .driver = { .name = "at32_wdt", - .owner = THIS_MODULE, }, .shutdown = at32_wdt_shutdown, }; diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index dee6cc21d270..d244112d5b6f 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -268,7 +268,6 @@ static struct platform_driver at91wdt_driver = { .resume = at91wdt_resume, .driver = { .name = "at91_wdt", - .owner = THIS_MODULE, .of_match_table = at91_wdt_dt_ids, }, }; diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 489729b26298..6df940528fd2 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -393,7 +393,6 @@ static struct platform_driver at91wdt_driver = { .remove = __exit_p(at91wdt_remove), .driver = { .name = "at91_wdt", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91_wdt_dt_ids), }, }; diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index 41ac4660fb89..835d310081e1 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c @@ -326,7 +326,6 @@ static struct platform_driver ath79_wdt_driver = { .shutdown = ath97_wdt_shutdown, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ath79_wdt_match), }, }; diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index 8df450c090a9..2b5a9bbf80b7 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -167,7 +167,6 @@ static struct platform_driver bcm2835_wdt_driver = { .shutdown = bcm2835_wdt_shutdown, .driver = { .name = "bcm2835-wdt", - .owner = THIS_MODULE, .of_match_table = bcm2835_wdt_of_match, }, }; diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index b61fcc535979..9816485f6825 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c @@ -242,7 +242,6 @@ static int bcm47xx_wdt_remove(struct platform_device *pdev) static struct platform_driver bcm47xx_wdt_driver = { .driver = { - .owner = THIS_MODULE, .name = "bcm47xx-wdt", }, .probe = bcm47xx_wdt_probe, diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 5a8e879a430a..ab26fd90729e 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -304,7 +304,6 @@ static struct platform_driver bcm63xx_wdt_driver = { .remove = bcm63xx_wdt_remove, .shutdown = bcm63xx_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = "bcm63xx-wdt", } }; diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index 9c248099f4a2..4e37db3539a4 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -352,7 +352,6 @@ MODULE_DEVICE_TABLE(of, bcm_kona_wdt_of_match); static struct platform_driver bcm_kona_wdt_driver = { .driver = { .name = BCM_KONA_WDT_NAME, - .owner = THIS_MODULE, .of_match_table = bcm_kona_wdt_of_match, }, .probe = bcm_kona_wdt_probe, diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index a3b6a5b30f9f..aa4d2e8a8ef9 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c @@ -407,7 +407,6 @@ static struct platform_driver bfin_wdt_driver = { .resume = bfin_wdt_resume, .driver = { .name = WATCHDOG_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 4bd070f524e5..ce12f437f195 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c @@ -448,7 +448,6 @@ static const struct of_device_id coh901327_dt_match[] = { static struct platform_driver coh901327_driver = { .driver = { - .owner = THIS_MODULE, .name = "coh901327_wdog", .of_match_table = coh901327_dt_match, }, diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index e55ed702209f..02007689e9ca 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -679,7 +679,6 @@ MODULE_DEVICE_TABLE(of, cpwd_match); static struct platform_driver cpwd_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = cpwd_match, }, .probe = cpwd_probe, diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index d09ad2254b57..cfdf8a408aea 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE(of, davinci_wdt_of_match); static struct platform_driver platform_wdt_driver = { .driver = { .name = "davinci-wdt", - .owner = THIS_MODULE, .of_match_table = davinci_wdt_of_match, }, .probe = davinci_wdt_probe, diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 9f210299de24..5693c5e21b10 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -348,7 +348,6 @@ static struct platform_driver dw_wdt_driver = { .remove = dw_wdt_drv_remove, .driver = { .name = "dw_wdt", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(dw_wdt_of_match), .pm = &dw_wdt_pm_ops, }, diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index 5f54e1e5819a..7a2cc7191c58 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c @@ -156,7 +156,6 @@ static int ep93xx_wdt_remove(struct platform_device *pdev) static struct platform_driver ep93xx_wdt_driver = { .driver = { - .owner = THIS_MODULE, .name = "ep93xx-wdt", }, .probe = ep93xx_wdt_probe, diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 25beb30878d7..cc1bdfc2ff71 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -307,7 +307,6 @@ static const struct of_device_id gef_wdt_ids[] = { static struct platform_driver gef_wdt_driver = { .driver = { .name = "gef_wdt", - .owner = THIS_MODULE, .of_match_table = gef_wdt_ids, }, .probe = gef_wdt_probe, diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 4c43e3fa8bd2..88e01238f01b 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -258,7 +258,6 @@ static struct platform_driver geodewdt_driver = { .remove = geodewdt_remove, .shutdown = geodewdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 220a9e07cfd5..bbdb19b45332 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c @@ -241,7 +241,6 @@ MODULE_DEVICE_TABLE(of, gpio_wdt_dt_ids); static struct platform_driver gpio_wdt_driver = { .driver = { .name = "gpio-wdt", - .owner = THIS_MODULE, .of_match_table = gpio_wdt_dt_ids, }, .probe = gpio_wdt_probe, diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 0ba1b7c99760..05ee0bf88ce9 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -576,7 +576,6 @@ static struct platform_driver iTCO_wdt_driver = { .remove = iTCO_wdt_remove, .shutdown = iTCO_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 4247c498ee78..f2e4e1eeb8dd 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c @@ -339,7 +339,6 @@ static struct platform_driver ibwdt_driver = { .remove = ibwdt_remove, .shutdown = ibwdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c index 07f88f54e5c0..9bc39ae51624 100644 --- a/drivers/watchdog/ie6xx_wdt.c +++ b/drivers/watchdog/ie6xx_wdt.c @@ -313,7 +313,6 @@ static struct platform_driver ie6xx_wdt_driver = { .remove = ie6xx_wdt_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 68c3d379ffa8..92a5c279c2ea 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -306,7 +306,6 @@ static struct platform_driver imx2_wdt_driver = { .shutdown = imx2_wdt_shutdown, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = imx2_wdt_dt_ids, }, }; diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c index ca66e8e74635..84f6701c391f 100644 --- a/drivers/watchdog/intel-mid_wdt.c +++ b/drivers/watchdog/intel-mid_wdt.c @@ -172,7 +172,6 @@ static struct platform_driver mid_wdt_driver = { .probe = mid_wdt_probe, .remove = mid_wdt_remove, .driver = { - .owner = THIS_MODULE, .name = "intel_mid_wdt", }, }; diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 91e45ca589e6..18e41afa4da3 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c @@ -211,7 +211,6 @@ static struct platform_driver jz4740_wdt_driver = { .remove = jz4740_wdt_remove, .driver = { .name = "jz4740-wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c index d9c1a1601926..5bf931ce1353 100644 --- a/drivers/watchdog/kempld_wdt.c +++ b/drivers/watchdog/kempld_wdt.c @@ -563,7 +563,6 @@ static int kempld_wdt_resume(struct platform_device *pdev) static struct platform_driver kempld_wdt_driver = { .driver = { .name = "kempld-wdt", - .owner = THIS_MODULE, }, .probe = kempld_wdt_probe, .remove = kempld_wdt_remove, diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index 40ca5594a336..b7ea39b455c8 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c @@ -296,7 +296,6 @@ static struct platform_driver ks8695wdt_driver = { .resume = ks8695wdt_resume, .driver = { .name = "ks8695_wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index 021e84eb88eb..582f2fa1b8d9 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c @@ -232,7 +232,6 @@ static struct platform_driver ltq_wdt_driver = { .remove = ltq_wdt_remove, .driver = { .name = "wdt", - .owner = THIS_MODULE, .of_match_table = ltq_wdt_match, }, }; diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index 0e9cc6f5a919..08da3114accb 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c @@ -231,7 +231,6 @@ static struct platform_driver max63xx_wdt_driver = { .id_table = max63xx_id_table, .driver = { .name = "max63xx_wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c index 2042874d5ce3..59f0913c7341 100644 --- a/drivers/watchdog/menf21bmc_wdt.c +++ b/drivers/watchdog/menf21bmc_wdt.c @@ -187,7 +187,6 @@ static void menf21bmc_wdt_shutdown(struct platform_device *pdev) static struct platform_driver menf21bmc_wdt = { .driver = { - .owner = THIS_MODULE, .name = DEVNAME, }, .probe = menf21bmc_wdt_probe, diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c index a64405b82596..2789da2c0515 100644 --- a/drivers/watchdog/moxart_wdt.c +++ b/drivers/watchdog/moxart_wdt.c @@ -174,7 +174,6 @@ static struct platform_driver moxart_wdt_driver = { .remove = moxart_wdt_remove, .driver = { .name = "moxart-watchdog", - .owner = THIS_MODULE, .of_match_table = moxart_watchdog_match, }, }; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 7831955cd9e1..689381a24887 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -249,7 +249,6 @@ static struct platform_driver mpc8xxx_wdt_driver = { .remove = mpc8xxx_wdt_remove, .driver = { .name = "mpc8xxx_wdt", - .owner = THIS_MODULE, .of_match_table = mpc8xxx_wdt_match, }, }; diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index f9fa58409396..315275d7bab6 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c @@ -300,7 +300,6 @@ static struct platform_driver mv64x60_wdt_driver = { .probe = mv64x60_wdt_probe, .remove = mv64x60_wdt_remove, .driver = { - .owner = THIS_MODULE, .name = MV64x60_WDT_NAME, }, }; diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c index 7135803ca1a3..d5bed78c4d9f 100644 --- a/drivers/watchdog/nuc900_wdt.c +++ b/drivers/watchdog/nuc900_wdt.c @@ -297,7 +297,6 @@ static struct platform_driver nuc900wdt_driver = { .remove = nuc900wdt_remove, .driver = { .name = "nuc900-wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index 0b9ec61e1313..c028454be66c 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c @@ -471,7 +471,6 @@ static struct platform_driver nv_tco_driver = { .remove = nv_tco_remove, .shutdown = nv_tco_shutdown, .driver = { - .owner = THIS_MODULE, .name = TCO_MODULE_NAME, }, }; diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 1e6e28df5d7b..b2e1b4cbbdc1 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -236,7 +236,6 @@ static struct platform_driver xwdt_driver = { .probe = xwdt_probe, .remove = xwdt_remove, .driver = { - .owner = THIS_MODULE, .name = WATCHDOG_NAME, .of_match_table = xwdt_of_match, }, diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 3691b157516a..9f2709db61ca 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -353,7 +353,6 @@ static struct platform_driver omap_wdt_driver = { .suspend = omap_wdt_suspend, .resume = omap_wdt_resume, .driver = { - .owner = THIS_MODULE, .name = "omap_wdt", .of_match_table = omap_wdt_of_match, }, diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 00d0741228fc..469031e528e1 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -593,7 +593,6 @@ static struct platform_driver orion_wdt_driver = { .remove = orion_wdt_remove, .shutdown = orion_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = "orion_wdt", .of_match_table = orion_wdt_of_match_table, }, diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 15fb316e9437..55e220150103 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -207,7 +207,6 @@ MODULE_DEVICE_TABLE(of, pnx4008_wdt_match); static struct platform_driver platform_wdt_driver = { .driver = { .name = "pnx4008-watchdog", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pnx4008_wdt_match), }, .probe = pnx4008_wdt_probe, diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 29cf4dcbc59c..47a8f1b1087d 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -287,7 +287,6 @@ static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, .remove = rdc321x_wdt_remove, .driver = { - .owner = THIS_MODULE, .name = "rdc321x-wdt", }, }; diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index cfed0fe264dc..aba53424605e 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -237,7 +237,6 @@ MODULE_DEVICE_TABLE(of, riowd_match); static struct platform_driver riowd_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = riowd_match, }, .probe = riowd_probe, diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c index d92c2d5859ce..11aad5b7aafe 100644 --- a/drivers/watchdog/rt2880_wdt.c +++ b/drivers/watchdog/rt2880_wdt.c @@ -194,7 +194,6 @@ static struct platform_driver rt288x_wdt_driver = { .shutdown = rt288x_wdt_shutdown, .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .of_match_table = rt288x_wdt_match, }, }; diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 7c6ccd071baf..c411196e9b00 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -694,7 +694,6 @@ static struct platform_driver s3c2410wdt_driver = { .shutdown = s3c2410wdt_shutdown, .id_table = s3c2410_wdt_ids, .driver = { - .owner = THIS_MODULE, .name = "s3c2410-wdt", .pm = &s3c2410wdt_pm_ops, .of_match_table = of_match_ptr(s3c2410_wdt_match), diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index b96127ea3de1..43d0cbb7ba0b 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -453,7 +453,6 @@ static struct platform_driver sch311x_wdt_driver = { .remove = sch311x_wdt_remove, .shutdown = sch311x_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index fa89bb30d004..567458b137a6 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -303,7 +303,6 @@ static void sh_wdt_shutdown(struct platform_device *pdev) static struct platform_driver sh_wdt_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = sh_wdt_probe, diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c index 702d07870808..42fa5c0c518a 100644 --- a/drivers/watchdog/sirfsoc_wdt.c +++ b/drivers/watchdog/sirfsoc_wdt.c @@ -210,7 +210,6 @@ MODULE_DEVICE_TABLE(of, sirfsoc_wdt_of_match); static struct platform_driver sirfsoc_wdt_driver = { .driver = { .name = "sirfsoc-wdt", - .owner = THIS_MODULE, .pm = &sirfsoc_wdt_pm_ops, .of_match_table = sirfsoc_wdt_of_match, }, diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index 5cca9cddb87d..eb8044ef0ea0 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c @@ -538,7 +538,6 @@ static struct platform_driver sp5100_tco_driver = { .remove = sp5100_tco_remove, .shutdown = sp5100_tco_shutdown, .driver = { - .owner = THIS_MODULE, .name = TCO_MODULE_NAME, }, }; diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 480bb557f353..93d3ee71c9c7 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -253,7 +253,6 @@ static struct platform_driver sunxi_wdt_driver = { .remove = sunxi_wdt_remove, .shutdown = sunxi_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = sunxi_wdt_dt_ids, }, diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c index 750e2a26cb12..30451ea46902 100644 --- a/drivers/watchdog/tegra_wdt.c +++ b/drivers/watchdog/tegra_wdt.c @@ -289,7 +289,6 @@ static struct platform_driver tegra_wdt_driver = { .probe = tegra_wdt_probe, .remove = tegra_wdt_remove, .driver = { - .owner = THIS_MODULE, .name = "tegra-wdt", .pm = &tegra_wdt_pm_ops, .of_match_table = tegra_wdt_of_match, diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index afa9d6ef353a..d5bc870229e0 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c @@ -440,7 +440,6 @@ static struct platform_driver ts72xx_wdt_driver = { .remove = ts72xx_wdt_remove, .driver = { .name = "ts72xx-wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index 2d4535dc2676..12c15903d098 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c @@ -140,7 +140,6 @@ static struct platform_driver twl4030_wdt_driver = { .suspend = twl4030_wdt_suspend, .resume = twl4030_wdt_resume, .driver = { - .owner = THIS_MODULE, .name = "twl4030_wdt", .of_match_table = twl_wdt_of_match, }, diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 6a447e321dd0..7f615933d31a 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c @@ -167,7 +167,6 @@ static struct platform_driver txx9wdt_driver = { .shutdown = txx9wdt_shutdown, .driver = { .name = "txx9wdt", - .owner = THIS_MODULE, }, }; diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c index 5aed9d7ad47e..9de09ab00838 100644 --- a/drivers/watchdog/ux500_wdt.c +++ b/drivers/watchdog/ux500_wdt.c @@ -156,7 +156,6 @@ static struct platform_driver ux500_wdt_driver = { .suspend = ux500_wdt_suspend, .resume = ux500_wdt_resume, .driver = { - .owner = THIS_MODULE, .name = "ux500_wdt", }, }; diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c index 7a42dffd39e5..cf0e650c2015 100644 --- a/drivers/watchdog/xen_wdt.c +++ b/drivers/watchdog/xen_wdt.c @@ -320,7 +320,6 @@ static struct platform_driver xen_wdt_driver = { .suspend = xen_wdt_suspend, .resume = xen_wdt_resume, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, }, }; -- GitLab From 467817edc57ff0b1e3a1d3d97b534296a956fb82 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:57 +0200 Subject: [PATCH 0854/9457] zorro: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- drivers/zorro/zorro.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 707c1a5a0317..d295d9878dff 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -222,7 +222,6 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) static struct platform_driver amiga_zorro_driver = { .driver = { .name = "amiga-zorro", - .owner = THIS_MODULE, }, }; -- GitLab From 75c43e049398d7822c356da611eab0b30a1249e1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:57 +0200 Subject: [PATCH 0855/9457] pstore: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- fs/pstore/ram.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 3b5744306ed8..da1fed65e7db 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -545,7 +545,6 @@ static struct platform_driver ramoops_driver = { .remove = __exit_p(ramoops_remove), .driver = { .name = "ramoops", - .owner = THIS_MODULE, }, }; -- GitLab From 0dd115381375408110d7848cfbc5b5d0fafc1d44 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:58 +0200 Subject: [PATCH 0856/9457] net: dsa: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- net/dsa/dsa.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 22f34cf4cb27..29a8e972931a 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -744,7 +744,6 @@ static struct platform_driver dsa_driver = { .shutdown = dsa_shutdown, .driver = { .name = "dsa", - .owner = THIS_MODULE, .of_match_table = dsa_of_match_table, .pm = &dsa_pm_ops, }, -- GitLab From 140bbc4af034aca57641eedcc82d35cc36947674 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:58 +0200 Subject: [PATCH 0857/9457] net: rfkill: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- net/rfkill/rfkill-gpio.c | 1 - net/rfkill/rfkill-regulator.c | 1 - 2 files changed, 2 deletions(-) diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 0f62326c0f5e..fd33aa4ec249 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c @@ -171,7 +171,6 @@ static struct platform_driver rfkill_gpio_driver = { .remove = rfkill_gpio_remove, .driver = { .name = "rfkill_gpio", - .owner = THIS_MODULE, .acpi_match_table = ACPI_PTR(rfkill_acpi_match), }, }; diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c index cf5b145902e5..50cd26a48e87 100644 --- a/net/rfkill/rfkill-regulator.c +++ b/net/rfkill/rfkill-regulator.c @@ -142,7 +142,6 @@ static struct platform_driver rfkill_regulator_driver = { .remove = rfkill_regulator_remove, .driver = { .name = "rfkill-regulator", - .owner = THIS_MODULE, }, }; -- GitLab From 6851da1f744dcc6c9c1945a6aab4575c7cf240cb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:59 +0200 Subject: [PATCH 0858/9457] ALSA: arm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/arm/pxa2xx-ac97.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 3a10df6688ee..38590b322c54 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -241,7 +241,6 @@ static struct platform_driver pxa2xx_ac97_driver = { .remove = pxa2xx_ac97_remove, .driver = { .name = "pxa2xx-ac97", - .owner = THIS_MODULE, #ifdef CONFIG_PM_SLEEP .pm = &pxa2xx_ac97_pm_ops, #endif -- GitLab From 16573a98e1a665f8c52f0b2705d4b74ced8173dd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:59 +0200 Subject: [PATCH 0859/9457] ALSA: atmel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/atmel/abdac.c | 1 - sound/atmel/ac97c.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index 31061e3521d4..0672e716d296 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c @@ -588,7 +588,6 @@ static struct platform_driver atmel_abdac_driver = { .remove = atmel_abdac_remove, .driver = { .name = "atmel_abdac", - .owner = THIS_MODULE, .pm = ATMEL_ABDAC_PM_OPS, }, }; diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index b59427d5a697..dcbf3371e24f 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -1203,7 +1203,6 @@ static struct platform_driver atmel_ac97c_driver = { .remove = atmel_ac97c_remove, .driver = { .name = "atmel_ac97c", - .owner = THIS_MODULE, .pm = ATMEL_AC97C_PM_OPS, }, }; -- GitLab From 5d5638afa0cb252442e1746a36550b46a9ebe6ee Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:21:59 +0200 Subject: [PATCH 0860/9457] ALSA: drivers: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/drivers/aloop.c | 1 - sound/drivers/dummy.c | 1 - sound/drivers/ml403-ac97cr.c | 1 - sound/drivers/mtpav.c | 1 - sound/drivers/mts64.c | 1 - sound/drivers/portman2x4.c | 1 - sound/drivers/serial-u16550.c | 1 - sound/drivers/virmidi.c | 1 - 8 files changed, 8 deletions(-) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 2a16c86a60b3..7ea53399404d 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -1220,7 +1220,6 @@ static struct platform_driver loopback_driver = { .remove = loopback_remove, .driver = { .name = SND_LOOPBACK_DRIVER, - .owner = THIS_MODULE, .pm = LOOPBACK_PM_OPS, }, }; diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index fab90bd2bd51..5d0dfb787cec 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -1162,7 +1162,6 @@ static struct platform_driver snd_dummy_driver = { .remove = snd_dummy_remove, .driver = { .name = SND_DUMMY_DRIVER, - .owner = THIS_MODULE, .pm = SND_DUMMY_PM_OPS, }, }; diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index 33ed76530d0b..bcca825a1c8d 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -1335,7 +1335,6 @@ static struct platform_driver snd_ml403_ac97cr_driver = { .remove = snd_ml403_ac97cr_remove, .driver = { .name = SND_ML403_AC97CR_DRIVER, - .owner = THIS_MODULE, }, }; diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 4b66c7f22af7..15769447688f 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c @@ -759,7 +759,6 @@ static struct platform_driver snd_mtpav_driver = { .remove = snd_mtpav_remove, .driver = { .name = SND_MTPAV_DRIVER, - .owner = THIS_MODULE, }, }; diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index f5fd448dbc57..8991d834e3dd 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -1040,7 +1040,6 @@ static struct platform_driver snd_mts64_driver = { .remove = snd_mts64_remove, .driver = { .name = PLATFORM_DRIVER, - .owner = THIS_MODULE, } }; diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index 78ccfa455527..464385a480e4 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c @@ -829,7 +829,6 @@ static struct platform_driver snd_portman_driver = { .remove = snd_portman_remove, .driver = { .name = PLATFORM_DRIVER, - .owner = THIS_MODULE, } }; diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 9ad4414fa25c..13a34e3c6382 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -994,7 +994,6 @@ static struct platform_driver snd_serial_driver = { .remove = snd_serial_remove, .driver = { .name = SND_SERIAL_DRIVER, - .owner = THIS_MODULE, }, }; diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index b178724295f3..abace3ce24da 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c @@ -140,7 +140,6 @@ static struct platform_driver snd_virmidi_driver = { .remove = snd_virmidi_remove, .driver = { .name = SND_VIRMIDI_DRIVER, - .owner = THIS_MODULE, }, }; -- GitLab From d9b97db07ae38943236773e54b3f19f1a3d9a07f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:00 +0200 Subject: [PATCH 0861/9457] ALSA: drivers: mpu401: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/drivers/mpu401/mpu401.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 83014b83a44e..fed7e7e2177b 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -140,7 +140,6 @@ static struct platform_driver snd_mpu401_driver = { .remove = snd_mpu401_remove, .driver = { .name = SND_MPU401_DRIVER, - .owner = THIS_MODULE, }, }; -- GitLab From cb4fe8ae6688e25f760f345b8b9e757955fdb963 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:00 +0200 Subject: [PATCH 0862/9457] ALSA: drivers: pcsp: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/drivers/pcsp/pcsp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 36808cdab06f..2adc7548ffca 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c @@ -221,7 +221,6 @@ static void pcsp_shutdown(struct platform_device *dev) static struct platform_driver pcsp_platform_driver = { .driver = { .name = "pcspkr", - .owner = THIS_MODULE, .pm = PCSP_PM_OPS, }, .probe = pcsp_probe, -- GitLab From 0d3d8be84aa6d2da80257a847c0db4520654cfb3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:01 +0200 Subject: [PATCH 0863/9457] ALSA: mips: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/mips/hal2.c | 1 - sound/mips/sgio2audio.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 23441b9e6148..ede449f0b50d 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -929,7 +929,6 @@ static struct platform_driver hal2_driver = { .remove = hal2_remove, .driver = { .name = "sgihal2", - .owner = THIS_MODULE, } }; diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 04bb06c03ec8..0f146a9fca49 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -970,7 +970,6 @@ static struct platform_driver sgio2audio_driver = { .remove = snd_sgio2audio_remove, .driver = { .name = "sgio2audio", - .owner = THIS_MODULE, } }; -- GitLab From 04edde9789a150aa73ee49c8f10926e83910e3bd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:01 +0200 Subject: [PATCH 0864/9457] OSS: dmasound: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/oss/dmasound/dmasound_paula.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c index c2d45a5848bc..3f653618614d 100644 --- a/sound/oss/dmasound/dmasound_paula.c +++ b/sound/oss/dmasound/dmasound_paula.c @@ -729,7 +729,6 @@ static struct platform_driver amiga_audio_driver = { .remove = __exit_p(amiga_audio_remove), .driver = { .name = "amiga-audio", - .owner = THIS_MODULE, }, }; -- GitLab From 85be0fa4600b89961da1201ada5337f266a561f3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:02 +0200 Subject: [PATCH 0865/9457] ALSA: ppc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/ppc/powermac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index 350a7c8f86dd..33c6be9fb388 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c @@ -168,7 +168,6 @@ static struct platform_driver snd_pmac_driver = { .remove = snd_pmac_remove, .driver = { .name = SND_PMAC_DRIVER, - .owner = THIS_MODULE, .pm = SND_PMAC_PM_OPS, }, }; -- GitLab From 9717b20ee4b9aeea748f0624f0895490510c2553 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:02 +0200 Subject: [PATCH 0866/9457] ALSA: sh: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/sh/aica.c | 1 - sound/sh/sh_dac_audio.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 47849eaf266d..f44dda610ed2 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -652,7 +652,6 @@ static struct platform_driver snd_aica_driver = { .remove = snd_aica_remove, .driver = { .name = SND_AICA_DRIVER, - .owner = THIS_MODULE, }, }; diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index d1fb74dabbd1..abf9c0cab1e2 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -436,7 +436,6 @@ static struct platform_driver sh_dac_driver = { .remove = snd_sh_dac_remove, .driver = { .name = "dac_audio", - .owner = THIS_MODULE, }, }; -- GitLab From ab31135e6ed873011b40e6f547831757a275d15b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:02 +0200 Subject: [PATCH 0867/9457] ASoC: : drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/soc-core.c | 1 - sound/soc/soc-utils.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..0a476b650708 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1941,7 +1941,6 @@ EXPORT_SYMBOL_GPL(snd_soc_pm_ops); static struct platform_driver soc_driver = { .driver = { .name = "soc-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = soc_probe, diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 7f22ca35a413..362c69ac1d6c 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -154,7 +154,6 @@ static int snd_soc_dummy_remove(struct platform_device *pdev) static struct platform_driver soc_dummy_driver = { .driver = { .name = "snd-soc-dummy", - .owner = THIS_MODULE, }, .probe = snd_soc_dummy_probe, .remove = snd_soc_dummy_remove, -- GitLab From 7af23bd9f39228cd128a61f4700d915f31bac973 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:03 +0200 Subject: [PATCH 0868/9457] ASoC: adi: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/adi/axi-i2s.c | 1 - sound/soc/adi/axi-spdif.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 6058c1fd5070..7752860f7230 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c @@ -263,7 +263,6 @@ MODULE_DEVICE_TABLE(of, axi_i2s_of_match); static struct platform_driver axi_i2s_driver = { .driver = { .name = "axi-i2s", - .owner = THIS_MODULE, .of_match_table = axi_i2s_of_match, }, .probe = axi_i2s_probe, diff --git a/sound/soc/adi/axi-spdif.c b/sound/soc/adi/axi-spdif.c index 198e3a4640f6..d7259d412892 100644 --- a/sound/soc/adi/axi-spdif.c +++ b/sound/soc/adi/axi-spdif.c @@ -258,7 +258,6 @@ MODULE_DEVICE_TABLE(of, axi_spdif_of_match); static struct platform_driver axi_spdif_driver = { .driver = { .name = "axi-spdif", - .owner = THIS_MODULE, .of_match_table = axi_spdif_of_match, }, .probe = axi_spdif_probe, -- GitLab From c9845a84be87e04e0d360c1e4bc48a0e953b1eb2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:03 +0200 Subject: [PATCH 0869/9457] ASoC: atmel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/atmel/atmel_wm8904.c | 1 - sound/soc/atmel/sam9g20_wm8731.c | 1 - sound/soc/atmel/sam9x5_wm8731.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c index 4052268ce462..aa354e1c6ff7 100644 --- a/sound/soc/atmel/atmel_wm8904.c +++ b/sound/soc/atmel/atmel_wm8904.c @@ -181,7 +181,6 @@ static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = { static struct platform_driver atmel_asoc_wm8904_driver = { .driver = { .name = "atmel-wm8904-audio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids), }, .probe = atmel_asoc_wm8904_probe, diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index bb1149126c54..66b66d0e7514 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -309,7 +309,6 @@ MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids); static struct platform_driver at91sam9g20ek_audio_driver = { .driver = { .name = "at91sam9g20ek-audio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids), }, .probe = at91sam9g20ek_audio_probe, diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c index 3188036a18f0..ccdf547f4d8c 100644 --- a/sound/soc/atmel/sam9x5_wm8731.c +++ b/sound/soc/atmel/sam9x5_wm8731.c @@ -192,7 +192,6 @@ MODULE_DEVICE_TABLE(of, sam9x5_wm8731_of_match); static struct platform_driver sam9x5_wm8731_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(sam9x5_wm8731_of_match), }, .probe = sam9x5_wm8731_driver_probe, -- GitLab From 68db31fc045041a56c9bdbe2e2365eb255b8ec91 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:04 +0200 Subject: [PATCH 0870/9457] ASoC: au1x: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/au1x/ac97c.c | 1 - sound/soc/au1x/db1000.c | 1 - sound/soc/au1x/db1200.c | 1 - sound/soc/au1x/dbdma2.c | 1 - sound/soc/au1x/dma.c | 1 - sound/soc/au1x/i2sc.c | 1 - sound/soc/au1x/psc-ac97.c | 1 - sound/soc/au1x/psc-i2s.c | 1 - 8 files changed, 8 deletions(-) diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index c8a2de103c5f..e989f1a7a768 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -334,7 +334,6 @@ static const struct dev_pm_ops au1xpscac97_pmops = { static struct platform_driver au1xac97c_driver = { .driver = { .name = "alchemy-ac97c", - .owner = THIS_MODULE, .pm = AU1XPSCAC97_PMOPS, }, .probe = au1xac97c_drvprobe, diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c index 376d976bcc2d..452f404abfd2 100644 --- a/sound/soc/au1x/db1000.c +++ b/sound/soc/au1x/db1000.c @@ -51,7 +51,6 @@ static int db1000_audio_remove(struct platform_device *pdev) static struct platform_driver db1000_audio_driver = { .driver = { .name = "db1000-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = db1000_audio_probe, diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index decba87a074c..a747ac0b399f 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -200,7 +200,6 @@ static int db1200_audio_remove(struct platform_device *pdev) static struct platform_driver db1200_audio_driver = { .driver = { .name = "db1200-ac97", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .id_table = db1200_pids, diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 17a24d804734..b06b8d8128c6 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -363,7 +363,6 @@ static int au1xpsc_pcm_drvremove(struct platform_device *pdev) static struct platform_driver au1xpsc_pcm_driver = { .driver = { .name = "au1xpsc-pcm", - .owner = THIS_MODULE, }, .probe = au1xpsc_pcm_drvprobe, .remove = au1xpsc_pcm_drvremove, diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index e920b60bf6c2..6ffaaff469c7 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -331,7 +331,6 @@ static int alchemy_pcm_drvremove(struct platform_device *pdev) static struct platform_driver alchemy_pcmdma_driver = { .driver = { .name = "alchemy-pcm-dma", - .owner = THIS_MODULE, }, .probe = alchemy_pcm_drvprobe, .remove = alchemy_pcm_drvremove, diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index b3f37f6edbcb..450c842c776c 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -310,7 +310,6 @@ static const struct dev_pm_ops au1xi2sc_pmops = { static struct platform_driver au1xi2s_driver = { .driver = { .name = "alchemy-i2sc", - .owner = THIS_MODULE, .pm = AU1XI2SC_PMOPS, }, .probe = au1xi2s_drvprobe, diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 84f31e1f9d24..f3bd1b80e3a1 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -490,7 +490,6 @@ static struct dev_pm_ops au1xpscac97_pmops = { static struct platform_driver au1xpsc_ac97_driver = { .driver = { .name = "au1xpsc_ac97", - .owner = THIS_MODULE, .pm = AU1XPSCAC97_PMOPS, }, .probe = au1xpsc_ac97_drvprobe, diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 814beffc56f2..e742ef668496 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -419,7 +419,6 @@ static struct dev_pm_ops au1xpsci2s_pmops = { static struct platform_driver au1xpsc_i2s_driver = { .driver = { .name = "au1xpsc_i2s", - .owner = THIS_MODULE, .pm = AU1XPSCI2S_PMOPS, }, .probe = au1xpsc_i2s_drvprobe, -- GitLab From ea3bccab077b1cdc41d0aec3183d7260a999777e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:04 +0200 Subject: [PATCH 0871/9457] ASoC: bcm: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/bcm/bcm2835-i2s.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index 2685fe4f8427..03fa1cbf8ec1 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -866,7 +866,6 @@ static struct platform_driver bcm2835_i2s_driver = { .probe = bcm2835_i2s_probe, .driver = { .name = "bcm2835-i2s", - .owner = THIS_MODULE, .of_match_table = bcm2835_i2s_of_match, }, }; -- GitLab From 3316fd2554b717904e979eb13cd3cdd95a66f0c5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:05 +0200 Subject: [PATCH 0872/9457] ASoC: blackfin: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/blackfin/bf5xx-ac97-pcm.c | 1 - sound/soc/blackfin/bf5xx-ac97.c | 1 - sound/soc/blackfin/bf5xx-ad1836.c | 1 - sound/soc/blackfin/bf5xx-i2s-pcm.c | 1 - sound/soc/blackfin/bf5xx-i2s.c | 1 - sound/soc/blackfin/bf6xx-i2s.c | 1 - sound/soc/blackfin/bfin-eval-adau1373.c | 1 - sound/soc/blackfin/bfin-eval-adau1701.c | 1 - sound/soc/blackfin/bfin-eval-adau1x61.c | 1 - sound/soc/blackfin/bfin-eval-adau1x81.c | 1 - sound/soc/blackfin/bfin-eval-adav80x.c | 1 - 11 files changed, 11 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index cdb8ee75ded9..238913e030e0 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -462,7 +462,6 @@ static int bf5xx_soc_platform_remove(struct platform_device *pdev) static struct platform_driver bf5xx_pcm_driver = { .driver = { .name = "bfin-ac97-pcm-audio", - .owner = THIS_MODULE, }, .probe = bf5xx_soc_platform_probe, diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index e82eb373a731..a47c08ece082 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -375,7 +375,6 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev) static struct platform_driver asoc_bfin_ac97_driver = { .driver = { .name = "bfin-ac97", - .owner = THIS_MODULE, }, .probe = asoc_bfin_ac97_probe, diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 8fcfc4ec3a51..5bf1501e5e3c 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -104,7 +104,6 @@ static int bf5xx_ad1836_driver_remove(struct platform_device *pdev) static struct platform_driver bf5xx_ad1836_driver = { .driver = { .name = "bfin-snd-ad1836", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bf5xx_ad1836_driver_probe, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index bcf591373a7a..d95477afcc67 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -354,7 +354,6 @@ static int bfin_i2s_soc_platform_remove(struct platform_device *pdev) static struct platform_driver bfin_i2s_pcm_driver = { .driver = { .name = "bfin-i2s-pcm-audio", - .owner = THIS_MODULE, }, .probe = bfin_i2s_soc_platform_probe, diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 39d774839b3e..b69aeef6418e 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -379,7 +379,6 @@ static struct platform_driver bfin_i2s_driver = { .remove = bf5xx_i2s_remove, .driver = { .name = "bfin-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index 5810a0603f2f..bd3b4d464145 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -229,7 +229,6 @@ static struct platform_driver bfin_i2s_driver = { .remove = bfin_i2s_remove, .driver = { .name = "bfin-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c index 4ef9683bcad8..523baf5820d7 100644 --- a/sound/soc/blackfin/bfin-eval-adau1373.c +++ b/sound/soc/blackfin/bfin-eval-adau1373.c @@ -169,7 +169,6 @@ static int bfin_eval_adau1373_remove(struct platform_device *pdev) static struct platform_driver bfin_eval_adau1373_driver = { .driver = { .name = "bfin-eval-adau1373", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1373_probe, diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c index 3b55081a96c0..f9e926dfd4ef 100644 --- a/sound/soc/blackfin/bfin-eval-adau1701.c +++ b/sound/soc/blackfin/bfin-eval-adau1701.c @@ -109,7 +109,6 @@ static int bfin_eval_adau1701_remove(struct platform_device *pdev) static struct platform_driver bfin_eval_adau1701_driver = { .driver = { .name = "bfin-eval-adau1701", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1701_probe, diff --git a/sound/soc/blackfin/bfin-eval-adau1x61.c b/sound/soc/blackfin/bfin-eval-adau1x61.c index 3011906f9d3b..4229f76daec9 100644 --- a/sound/soc/blackfin/bfin-eval-adau1x61.c +++ b/sound/soc/blackfin/bfin-eval-adau1x61.c @@ -129,7 +129,6 @@ static int bfin_eval_adau1x61_probe(struct platform_device *pdev) static struct platform_driver bfin_eval_adau1x61_driver = { .driver = { .name = "bfin-eval-adau1x61", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1x61_probe, diff --git a/sound/soc/blackfin/bfin-eval-adau1x81.c b/sound/soc/blackfin/bfin-eval-adau1x81.c index 5c380f6aed1a..3e01cbe53fc7 100644 --- a/sound/soc/blackfin/bfin-eval-adau1x81.c +++ b/sound/soc/blackfin/bfin-eval-adau1x81.c @@ -117,7 +117,6 @@ static int bfin_eval_adau1x81_probe(struct platform_device *pdev) static struct platform_driver bfin_eval_adau1x81_driver = { .driver = { .name = "bfin-eval-adau1x81", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adau1x81_probe, diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c index 3b1b61a44815..27eee66afdb2 100644 --- a/sound/soc/blackfin/bfin-eval-adav80x.c +++ b/sound/soc/blackfin/bfin-eval-adav80x.c @@ -141,7 +141,6 @@ MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids); static struct platform_driver bfin_eval_adav80x_driver = { .driver = { .name = "bfin-eval-adav80x", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bfin_eval_adav80x_probe, -- GitLab From d0052ec305893d6eb25ac31c1ca8cc895c5b108a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:05 +0200 Subject: [PATCH 0873/9457] ASoC: cirrus: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/cirrus/edb93xx.c | 1 - sound/soc/cirrus/ep93xx-ac97.c | 1 - sound/soc/cirrus/ep93xx-i2s.c | 1 - sound/soc/cirrus/simone.c | 1 - sound/soc/cirrus/snappercl15.c | 1 - 5 files changed, 5 deletions(-) diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 4f900efc437c..85962657aabe 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -113,7 +113,6 @@ static int edb93xx_remove(struct platform_device *pdev) static struct platform_driver edb93xx_driver = { .driver = { .name = "edb93xx-audio", - .owner = THIS_MODULE, }, .probe = edb93xx_probe, .remove = edb93xx_remove, diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index f30dadf85b99..4e382a3dd38b 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -439,7 +439,6 @@ static struct platform_driver ep93xx_ac97_driver = { .remove = ep93xx_ac97_remove, .driver = { .name = "ep93xx-ac97", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 943145f9d1b6..934f8aefdd90 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -451,7 +451,6 @@ static struct platform_driver ep93xx_i2s_driver = { .remove = ep93xx_i2s_remove, .driver = { .name = "ep93xx-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index 822a19a89e74..1ec661834e5a 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -74,7 +74,6 @@ static int simone_remove(struct platform_device *pdev) static struct platform_driver simone_driver = { .driver = { .name = "simone-audio", - .owner = THIS_MODULE, }, .probe = simone_probe, .remove = simone_remove, diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 5b68b106cfc2..98089df08df6 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -123,7 +123,6 @@ static int snappercl15_remove(struct platform_device *pdev) static struct platform_driver snappercl15_driver = { .driver = { .name = "snappercl15-audio", - .owner = THIS_MODULE, }, .probe = snappercl15_probe, .remove = snappercl15_remove, -- GitLab From c756e83d1aa18310043042402566fdefa6e9d58b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:07 +0200 Subject: [PATCH 0874/9457] ASoC: codecs: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/codecs/88pm860x-codec.c | 1 - sound/soc/codecs/ab8500-codec.c | 1 - sound/soc/codecs/ac97.c | 1 - sound/soc/codecs/ad1980.c | 1 - sound/soc/codecs/ad73311.c | 1 - sound/soc/codecs/ads117x.c | 1 - sound/soc/codecs/ak4554.c | 1 - sound/soc/codecs/ak5386.c | 1 - sound/soc/codecs/bt-sco.c | 1 - sound/soc/codecs/cq93vc.c | 1 - sound/soc/codecs/cx20442.c | 1 - sound/soc/codecs/dmic.c | 1 - sound/soc/codecs/hdmi.c | 1 - sound/soc/codecs/jz4740.c | 1 - sound/soc/codecs/mc13783.c | 1 - sound/soc/codecs/pcm3008.c | 1 - sound/soc/codecs/si476x.c | 1 - sound/soc/codecs/sirf-audio-codec.c | 1 - sound/soc/codecs/sn95031.c | 1 - sound/soc/codecs/spdif_receiver.c | 1 - sound/soc/codecs/spdif_transmitter.c | 1 - sound/soc/codecs/stac9766.c | 1 - sound/soc/codecs/twl4030.c | 1 - sound/soc/codecs/twl6040.c | 1 - sound/soc/codecs/uda134x.c | 1 - sound/soc/codecs/wl1273.c | 1 - sound/soc/codecs/wm5102.c | 1 - sound/soc/codecs/wm5110.c | 1 - sound/soc/codecs/wm8350.c | 1 - sound/soc/codecs/wm8400.c | 1 - sound/soc/codecs/wm8727.c | 1 - sound/soc/codecs/wm8782.c | 1 - sound/soc/codecs/wm8994.c | 1 - sound/soc/codecs/wm8997.c | 1 - sound/soc/codecs/wm9705.c | 1 - sound/soc/codecs/wm9712.c | 1 - sound/soc/codecs/wm9713.c | 1 - 37 files changed, 37 deletions(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index e88a6b67f781..a2bf27f4baab 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1423,7 +1423,6 @@ static int pm860x_codec_remove(struct platform_device *pdev) static struct platform_driver pm860x_codec_driver = { .driver = { .name = "88pm860x-codec", - .owner = THIS_MODULE, }, .probe = pm860x_codec_probe, .remove = pm860x_codec_remove, diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index fd43827bb856..d2931dabfaf7 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2609,7 +2609,6 @@ static int ab8500_codec_driver_remove(struct platform_device *pdev) static struct platform_driver ab8500_codec_platform_driver = { .driver = { .name = "ab8500-codec", - .owner = THIS_MODULE, }, .probe = ab8500_codec_driver_probe, .remove = ab8500_codec_driver_remove, diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index bd9b1839c8b0..74a92369e06e 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -134,7 +134,6 @@ static int ac97_remove(struct platform_device *pdev) static struct platform_driver ac97_codec_driver = { .driver = { .name = "ac97-codec", - .owner = THIS_MODULE, }, .probe = ac97_probe, diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 304d3003339a..c0a9f2292bf3 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -312,7 +312,6 @@ static int ad1980_remove(struct platform_device *pdev) static struct platform_driver ad1980_codec_driver = { .driver = { .name = "ad1980", - .owner = THIS_MODULE, }, .probe = ad1980_probe, diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index 5fac8adbc136..a9400aef60b5 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -76,7 +76,6 @@ static int ad73311_remove(struct platform_device *pdev) static struct platform_driver ad73311_codec_driver = { .driver = { .name = "ad73311", - .owner = THIS_MODULE, }, .probe = ad73311_probe, diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 8f388edff586..1222282e93c3 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -78,7 +78,6 @@ static int ads117x_remove(struct platform_device *pdev) static struct platform_driver ads117x_codec_driver = { .driver = { .name = "ads117x-codec", - .owner = THIS_MODULE, }, .probe = ads117x_probe, diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 79e9555766c0..16ce9f9fefa1 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -93,7 +93,6 @@ MODULE_DEVICE_TABLE(of, ak4554_of_match); static struct platform_driver ak4554_driver = { .driver = { .name = "ak4554-adc-dac", - .owner = THIS_MODULE, .of_match_table = ak4554_of_match, }, .probe = ak4554_soc_probe, diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index 8107a1cac876..afa95360826d 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -205,7 +205,6 @@ static struct platform_driver ak5386_driver = { .remove = ak5386_remove, .driver = { .name = "ak5386", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ak5386_dt_ids), }, }; diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index c4cf0699e77f..5075bf0a7276 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c @@ -77,7 +77,6 @@ MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids); static struct platform_driver bt_sco_driver = { .driver = { .name = "bt-sco", - .owner = THIS_MODULE, }, .probe = bt_sco_probe, .remove = bt_sco_remove, diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 537327c7f7f1..5e92e0dc1e28 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -184,7 +184,6 @@ static int cq93vc_platform_remove(struct platform_device *pdev) static struct platform_driver cq93vc_codec_driver = { .driver = { .name = "cq93vc-codec", - .owner = THIS_MODULE, }, .probe = cq93vc_platform_probe, diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 8f95b0300f1a..0b10979513c4 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -429,7 +429,6 @@ static int __exit cx20442_platform_remove(struct platform_device *pdev) static struct platform_driver cx20442_platform_driver = { .driver = { .name = "cx20442-codec", - .owner = THIS_MODULE, }, .probe = cx20442_platform_probe, .remove = __exit_p(cx20442_platform_remove), diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index b2090b2a5e2d..fde53251c047 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -74,7 +74,6 @@ MODULE_ALIAS("platform:dmic-codec"); static struct platform_driver dmic_driver = { .driver = { .name = "dmic-codec", - .owner = THIS_MODULE, }, .probe = dmic_dev_probe, .remove = dmic_dev_remove, diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 1087fd5f9917..73d07b4c5588 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -92,7 +92,6 @@ static int hdmi_codec_remove(struct platform_device *pdev) static struct platform_driver hdmi_codec_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(hdmi_audio_codec_ids), }, diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index df7c01cf7072..933f4476d76c 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -364,7 +364,6 @@ static struct platform_driver jz4740_codec_driver = { .remove = jz4740_codec_remove, .driver = { .name = "jz4740-codec", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 71f775aad7c7..c1e441c2c8af 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -802,7 +802,6 @@ static int mc13783_codec_remove(struct platform_device *pdev) static struct platform_driver mc13783_codec_driver = { .driver = { .name = "mc13783-codec", - .owner = THIS_MODULE, }, .remove = mc13783_codec_remove, }; diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index b6618c4a7597..7e73fa4b3183 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -162,7 +162,6 @@ static struct platform_driver pcm3008_codec_driver = { .remove = pcm3008_codec_remove, .driver = { .name = "pcm3008-codec", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index cdf882fa7716..3e72964280c6 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -261,7 +261,6 @@ MODULE_ALIAS("platform:si476x-codec"); static struct platform_driver si476x_platform_driver = { .driver = { .name = "si476x-codec", - .owner = THIS_MODULE, }, .probe = si476x_platform_probe, .remove = si476x_platform_remove, diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 06ba4923fd5a..45de6b1718e1 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -565,7 +565,6 @@ static const struct dev_pm_ops sirf_audio_codec_pm_ops = { static struct platform_driver sirf_audio_codec_driver = { .driver = { .name = "sirf-audio-codec", - .owner = THIS_MODULE, .of_match_table = sirf_audio_codec_of_match, .pm = &sirf_audio_codec_pm_ops, }, diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index cf8fa40662f0..e879e5e0489e 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -916,7 +916,6 @@ static int sn95031_device_remove(struct platform_device *pdev) static struct platform_driver sn95031_codec_driver = { .driver = { .name = "sn95031", - .owner = THIS_MODULE, }, .probe = sn95031_device_probe, .remove = sn95031_device_remove, diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index e3501f40c7b3..3ec41ccbf4e2 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c @@ -80,7 +80,6 @@ static struct platform_driver spdif_dir_driver = { .remove = spdif_dir_remove, .driver = { .name = "spdif-dir", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spdif_dir_dt_ids), }, }; diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index e0df537dd4b7..ef634a9ad673 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c @@ -80,7 +80,6 @@ static struct platform_driver spdif_dit_driver = { .remove = spdif_dit_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(spdif_dit_dt_ids), }, }; diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 53b810d23fea..c24958c02cd7 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -396,7 +396,6 @@ static int stac9766_remove(struct platform_device *pdev) static struct platform_driver stac9766_codec_driver = { .driver = { .name = "stac9766-codec", - .owner = THIS_MODULE, }, .probe = stac9766_probe, diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index b6b0cb399599..7443b196be07 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2220,7 +2220,6 @@ static struct platform_driver twl4030_codec_driver = { .remove = twl4030_codec_remove, .driver = { .name = "twl4030-codec", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 0f6067f04e29..38bdc7eb3bb5 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1198,7 +1198,6 @@ static int twl6040_codec_remove(struct platform_device *pdev) static struct platform_driver twl6040_codec_driver = { .driver = { .name = "twl6040-codec", - .owner = THIS_MODULE, }, .probe = twl6040_codec_probe, .remove = twl6040_codec_remove, diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 32b2f78aa62c..a2a02e84bdf0 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -633,7 +633,6 @@ static int uda134x_codec_remove(struct platform_device *pdev) static struct platform_driver uda134x_codec_driver = { .driver = { .name = "uda134x-codec", - .owner = THIS_MODULE, }, .probe = uda134x_codec_probe, .remove = uda134x_codec_remove, diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index f3d4e88d0b7b..facb3d899c64 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -515,7 +515,6 @@ MODULE_ALIAS("platform:wl1273-codec"); static struct platform_driver wl1273_platform_driver = { .driver = { .name = "wl1273-codec", - .owner = THIS_MODULE, }, .probe = wl1273_platform_probe, .remove = wl1273_platform_remove, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index f60234962527..8ac9ae6c5a6c 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1958,7 +1958,6 @@ static int wm5102_remove(struct platform_device *pdev) static struct platform_driver wm5102_codec_driver = { .driver = { .name = "wm5102-codec", - .owner = THIS_MODULE, }, .probe = wm5102_probe, .remove = wm5102_remove, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2f2ec26d831c..4456b38a3ef5 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1738,7 +1738,6 @@ static int wm5110_remove(struct platform_device *pdev) static struct platform_driver wm5110_codec_driver = { .driver = { .name = "wm5110-codec", - .owner = THIS_MODULE, }, .probe = wm5110_probe, .remove = wm5110_remove, diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 628ec774cf22..fe29f17852ad 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1641,7 +1641,6 @@ static int wm8350_remove(struct platform_device *pdev) static struct platform_driver wm8350_codec_driver = { .driver = { .name = "wm8350-codec", - .owner = THIS_MODULE, }, .probe = wm8350_probe, .remove = wm8350_remove, diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 72471bef2e9a..50d2ff18aecf 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1397,7 +1397,6 @@ static int wm8400_remove(struct platform_device *pdev) static struct platform_driver wm8400_codec_driver = { .driver = { .name = "wm8400-codec", - .owner = THIS_MODULE, }, .probe = wm8400_probe, .remove = wm8400_remove, diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 7b1a6d5c11c6..bb25a75f92a2 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -75,7 +75,6 @@ static int wm8727_remove(struct platform_device *pdev) static struct platform_driver wm8727_codec_driver = { .driver = { .name = "wm8727", - .owner = THIS_MODULE, }, .probe = wm8727_probe, diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index 8092495605ce..fb55fd845d27 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -72,7 +72,6 @@ static int wm8782_remove(struct platform_device *pdev) static struct platform_driver wm8782_codec_driver = { .driver = { .name = "wm8782", - .owner = THIS_MODULE, }, .probe = wm8782_probe, .remove = wm8782_remove, diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1fcb9f3f3097..fc831caf5909 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4508,7 +4508,6 @@ static const struct dev_pm_ops wm8994_pm_ops = { static struct platform_driver wm8994_codec_driver = { .driver = { .name = "wm8994-codec", - .owner = THIS_MODULE, .pm = &wm8994_pm_ops, }, .probe = wm8994_probe, diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index ab33fe596519..7e8bfe27566b 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1165,7 +1165,6 @@ static int wm8997_remove(struct platform_device *pdev) static struct platform_driver wm8997_codec_driver = { .driver = { .name = "wm8997-codec", - .owner = THIS_MODULE, }, .probe = wm8997_probe, .remove = wm8997_remove, diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index c0b7f45dfa37..f74b3d2b23a5 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -395,7 +395,6 @@ static int wm9705_remove(struct platform_device *pdev) static struct platform_driver wm9705_codec_driver = { .driver = { .name = "wm9705-codec", - .owner = THIS_MODULE, }, .probe = wm9705_probe, diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c5eb746087b4..c078c15536fc 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -700,7 +700,6 @@ static int wm9712_remove(struct platform_device *pdev) static struct platform_driver wm9712_codec_driver = { .driver = { .name = "wm9712-codec", - .owner = THIS_MODULE, }, .probe = wm9712_probe, diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index bddee30a4bc7..fa2a235b2da3 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1269,7 +1269,6 @@ static int wm9713_remove(struct platform_device *pdev) static struct platform_driver wm9713_codec_driver = { .driver = { .name = "wm9713-codec", - .owner = THIS_MODULE, }, .probe = wm9713_probe, -- GitLab From a17b87a5b0ce32c3c4982bc80e9e153168e80e39 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:07 +0200 Subject: [PATCH 0875/9457] ASoC: davinci: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/davinci/davinci-evm.c | 1 - sound/soc/davinci/davinci-i2s.c | 1 - sound/soc/davinci/davinci-mcasp.c | 1 - sound/soc/davinci/davinci-vcif.c | 1 - 4 files changed, 4 deletions(-) diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index a50010e2891f..158cb3d1db70 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -445,7 +445,6 @@ static struct platform_driver davinci_evm_driver = { .remove = davinci_evm_remove, .driver = { .name = "davinci_evm", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = of_match_ptr(davinci_evm_dt_ids), }, diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 7682af31d6e6..15fb28fc8e1b 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -770,7 +770,6 @@ static struct platform_driver davinci_mcbsp_driver = { .remove = davinci_i2s_remove, .driver = { .name = "davinci-mcbsp", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 0eed9b1b24e1..9efc110e51e6 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1391,7 +1391,6 @@ static struct platform_driver davinci_mcasp_driver = { .remove = davinci_mcasp_remove, .driver = { .name = "davinci-mcasp", - .owner = THIS_MODULE, .of_match_table = mcasp_dt_ids, }, }; diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 77aef05588c3..5bee04279ebe 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -267,7 +267,6 @@ static struct platform_driver davinci_vcif_driver = { .remove = davinci_vcif_remove, .driver = { .name = "davinci-vcif", - .owner = THIS_MODULE, }, }; -- GitLab From 27cbfa122acb489bd7aec42867a3c65264c62a41 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:07 +0200 Subject: [PATCH 0876/9457] ASoC: dwc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/dwc/designware_i2s.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index e961388e6e9c..103b34e58ffa 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -449,7 +449,6 @@ static struct platform_driver dw_i2s_driver = { .remove = dw_i2s_remove, .driver = { .name = "designware-i2s", - .owner = THIS_MODULE, }, }; -- GitLab From 8cb636b1a181cc2c644ce5a03b4efa464c2c6348 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:08 +0200 Subject: [PATCH 0877/9457] ASoC: fsl: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/fsl/eukrea-tlv320.c | 1 - sound/soc/fsl/fsl_dma.c | 1 - sound/soc/fsl/fsl_esai.c | 1 - sound/soc/fsl/fsl_sai.c | 1 - sound/soc/fsl/fsl_spdif.c | 1 - sound/soc/fsl/fsl_ssi.c | 1 - sound/soc/fsl/imx-audmux.c | 1 - sound/soc/fsl/imx-mc13783.c | 1 - sound/soc/fsl/imx-sgtl5000.c | 1 - sound/soc/fsl/imx-spdif.c | 1 - sound/soc/fsl/imx-ssi.c | 1 - sound/soc/fsl/imx-wm8962.c | 1 - sound/soc/fsl/mpc5200_psc_ac97.c | 1 - sound/soc/fsl/mpc5200_psc_i2s.c | 1 - sound/soc/fsl/mpc8610_hpcd.c | 1 - sound/soc/fsl/mx27vis-aic32x4.c | 1 - sound/soc/fsl/p1022_ds.c | 1 - sound/soc/fsl/p1022_rdk.c | 1 - sound/soc/fsl/pcm030-audio-fabric.c | 1 - 19 files changed, 19 deletions(-) diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index eb093d5b85c4..daf1181fb1cb 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -239,7 +239,6 @@ MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids); static struct platform_driver eukrea_tlv320_driver = { .driver = { .name = "eukrea_tlv320", - .owner = THIS_MODULE, .of_match_table = imx_tlv320_dt_ids, }, .probe = eukrea_tlv320_probe, diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index a609aafc994d..986089f45805 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -971,7 +971,6 @@ MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids); static struct platform_driver fsl_soc_dma_driver = { .driver = { .name = "fsl-pcm-audio", - .owner = THIS_MODULE, .of_match_table = fsl_soc_dma_ids, }, .probe = fsl_soc_dma_probe, diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 8bcdfda09d7a..0bc78bd02a25 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -855,7 +855,6 @@ static struct platform_driver fsl_esai_driver = { .probe = fsl_esai_probe, .driver = { .name = "fsl-esai-dai", - .owner = THIS_MODULE, .of_match_table = fsl_esai_dt_ids, }, }; diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 7eeb1dd8ce27..032d2d33619c 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -678,7 +678,6 @@ static struct platform_driver fsl_sai_driver = { .probe = fsl_sai_probe, .driver = { .name = "fsl-sai", - .owner = THIS_MODULE, .of_match_table = fsl_sai_ids, }, }; diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 9b791621294c..af0429421fc8 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1283,7 +1283,6 @@ MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); static struct platform_driver fsl_spdif_driver = { .driver = { .name = "fsl-spdif-dai", - .owner = THIS_MODULE, .of_match_table = fsl_spdif_dt_ids, }, .probe = fsl_spdif_probe, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e6955170dc42..ab05262deaf8 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1489,7 +1489,6 @@ static int fsl_ssi_remove(struct platform_device *pdev) static struct platform_driver fsl_ssi_driver = { .driver = { .name = "fsl-ssi-dai", - .owner = THIS_MODULE, .of_match_table = fsl_ssi_ids, }, .probe = fsl_ssi_probe, diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index 46f9beb6b273..d9050d946ae7 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -356,7 +356,6 @@ static struct platform_driver imx_audmux_driver = { .id_table = imx_audmux_ids, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = imx_audmux_dt_ids, } }; diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index a2fd7321b5a9..6bf5bce01a92 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c @@ -159,7 +159,6 @@ static int imx_mc13783_remove(struct platform_device *pdev) static struct platform_driver imx_mc13783_audio_driver = { .driver = { .name = "imx_mc13783", - .owner = THIS_MODULE, }, .probe = imx_mc13783_probe, .remove = imx_mc13783_remove diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 1cb22dd034eb..413a771b8bbd 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -202,7 +202,6 @@ MODULE_DEVICE_TABLE(of, imx_sgtl5000_dt_ids); static struct platform_driver imx_sgtl5000_driver = { .driver = { .name = "imx-sgtl5000", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = imx_sgtl5000_dt_ids, }, diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c index e1dc40143600..9d0bb6bf1b7b 100644 --- a/sound/soc/fsl/imx-spdif.c +++ b/sound/soc/fsl/imx-spdif.c @@ -89,7 +89,6 @@ MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids); static struct platform_driver imx_spdif_driver = { .driver = { .name = "imx-spdif", - .owner = THIS_MODULE, .of_match_table = imx_spdif_dt_ids, }, .probe = imx_spdif_audio_probe, diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index ab2fdd76b693..44313e47e254 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -647,7 +647,6 @@ static struct platform_driver imx_ssi_driver = { .driver = { .name = "imx-ssi", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 3a3d17ce6ba4..2cebcb1641ba 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c @@ -309,7 +309,6 @@ MODULE_DEVICE_TABLE(of, imx_wm8962_dt_ids); static struct platform_driver imx_wm8962_driver = { .driver = { .name = "imx-wm8962", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = imx_wm8962_dt_ids, }, diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 24eafa2cfbf4..9c1a2c09b8c7 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -340,7 +340,6 @@ static struct platform_driver psc_ac97_driver = { .remove = psc_ac97_of_remove, .driver = { .name = "mpc5200-psc-ac97", - .owner = THIS_MODULE, .of_match_table = psc_ac97_match, }, }; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 5d07e8a74a21..51fb0c00fe73 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -229,7 +229,6 @@ static struct platform_driver psc_i2s_driver = { .remove = psc_i2s_of_remove, .driver = { .name = "mpc5200-psc-i2s", - .owner = THIS_MODULE, .of_match_table = psc_i2s_match, }, }; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index fa756d05b2f7..9621b9140df6 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -389,7 +389,6 @@ static struct platform_driver mpc8610_hpcd_driver = { * in lowercase letters. */ .name = "snd-soc-mpc8610hpcd", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c index f4c3bda5e69e..b1ced7b8d80c 100644 --- a/sound/soc/fsl/mx27vis-aic32x4.c +++ b/sound/soc/fsl/mx27vis-aic32x4.c @@ -229,7 +229,6 @@ static int mx27vis_aic32x4_remove(struct platform_device *pdev) static struct platform_driver mx27vis_aic32x4_audio_driver = { .driver = { .name = "mx27vis", - .owner = THIS_MODULE, }, .probe = mx27vis_aic32x4_probe, .remove = mx27vis_aic32x4_remove, diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index f75c3cf0e6de..71c1a7dc3aeb 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -398,7 +398,6 @@ static struct platform_driver p1022_ds_driver = { * in lowercase letters. */ .name = "snd-soc-p1022ds", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c index 9d89bb028621..ee29048424be 100644 --- a/sound/soc/fsl/p1022_rdk.c +++ b/sound/soc/fsl/p1022_rdk.c @@ -348,7 +348,6 @@ static struct platform_driver p1022_rdk_driver = { * in lowercase letters. */ .name = "snd-soc-p1022rdk", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 3665f612819d..c44459d24c50 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -124,7 +124,6 @@ static struct platform_driver pcm030_fabric_driver = { .remove = pcm030_fabric_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = pcm030_audio_match, }, }; -- GitLab From ffd35fa74f8ce5db0a980ae5b1d16cb4afe034d6 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:08 +0200 Subject: [PATCH 0878/9457] ASoC: generic: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/generic/simple-card.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index d1b7293c133e..df77772e9dff 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -590,7 +590,6 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match); static struct platform_driver asoc_simple_card = { .driver = { .name = "asoc-simple-card", - .owner = THIS_MODULE, .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, -- GitLab From 3c1af8802e459b2d1159dd9665b9ae14a1f15a5c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:09 +0200 Subject: [PATCH 0879/9457] ASoC: intel: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/intel/broadwell.c | 1 - sound/soc/intel/byt-max98090.c | 1 - sound/soc/intel/byt-rt5640.c | 1 - sound/soc/intel/haswell.c | 1 - sound/soc/intel/mfld_machine.c | 1 - sound/soc/intel/sst-acpi.c | 1 - sound/soc/intel/sst-baytrail-pcm.c | 1 - sound/soc/intel/sst-haswell-pcm.c | 1 - sound/soc/intel/sst-mfld-platform-pcm.c | 1 - 9 files changed, 9 deletions(-) diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c index 0e550f14028f..8db22982f259 100644 --- a/sound/soc/intel/broadwell.c +++ b/sound/soc/intel/broadwell.c @@ -238,7 +238,6 @@ static struct platform_driver broadwell_audio = { .remove = broadwell_audio_remove, .driver = { .name = "broadwell-audio", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/byt-max98090.c index d52681e7225e..9832afe7d22c 100644 --- a/sound/soc/intel/byt-max98090.c +++ b/sound/soc/intel/byt-max98090.c @@ -181,7 +181,6 @@ static struct platform_driver byt_max98090_driver = { .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c index e03abdf21c1b..0cba7830c5e9 100644 --- a/sound/soc/intel/byt-rt5640.c +++ b/sound/soc/intel/byt-rt5640.c @@ -224,7 +224,6 @@ static struct platform_driver byt_rt5640_audio = { .probe = byt_rt5640_probe, .driver = { .name = "byt-rt5640", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/haswell.c index 3981982674ac..9de3f8c4ddc6 100644 --- a/sound/soc/intel/haswell.c +++ b/sound/soc/intel/haswell.c @@ -209,7 +209,6 @@ static struct platform_driver haswell_audio = { .probe = haswell_audio_probe, .driver = { .name = "haswell-audio", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c index 031d78783fc8..90b7a57713a0 100644 --- a/sound/soc/intel/mfld_machine.c +++ b/sound/soc/intel/mfld_machine.c @@ -420,7 +420,6 @@ static int snd_mfld_mc_probe(struct platform_device *pdev) static struct platform_driver snd_mfld_mc_driver = { .driver = { - .owner = THIS_MODULE, .name = "msic_audio", }, .probe = snd_mfld_mc_probe, diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c index 03d0a166b635..b3d84560fbb5 100644 --- a/sound/soc/intel/sst-acpi.c +++ b/sound/soc/intel/sst-acpi.c @@ -275,7 +275,6 @@ static struct platform_driver sst_acpi_driver = { .remove = sst_acpi_remove, .driver = { .name = "sst-acpi", - .owner = THIS_MODULE, .acpi_match_table = ACPI_PTR(sst_acpi_match), }, }; diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index eab1c7d85187..3bb6288d8b4d 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c @@ -497,7 +497,6 @@ static int sst_byt_pcm_dev_remove(struct platform_device *pdev) static struct platform_driver sst_byt_pcm_driver = { .driver = { .name = "baytrail-pcm-audio", - .owner = THIS_MODULE, .pm = SST_BYT_PM_OPS, }, diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 33fc5c3abf55..467dac3b1075 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -901,7 +901,6 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev) static struct platform_driver hsw_pcm_driver = { .driver = { .name = "haswell-pcm-audio", - .owner = THIS_MODULE, }, .probe = hsw_pcm_dev_probe, diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index aa9b600dfc9b..a31536b8dcca 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -639,7 +639,6 @@ static int sst_platform_remove(struct platform_device *pdev) static struct platform_driver sst_platform_driver = { .driver = { .name = "sst-mfld-platform", - .owner = THIS_MODULE, }, .probe = sst_platform_probe, .remove = sst_platform_remove, -- GitLab From 20d7e389f218b5f7a3d54e5705c0f0e6cb13f80d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:09 +0200 Subject: [PATCH 0880/9457] ASoC: jz4740: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/jz4740/jz4740-i2s.c | 1 - sound/soc/jz4740/qi_lb60.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 3f9c3a9ae36f..d3d45c6f064f 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -455,7 +455,6 @@ static struct platform_driver jz4740_i2s_driver = { .probe = jz4740_i2s_dev_probe, .driver = { .name = "jz4740-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 5cb91f9e8626..084691784bf9 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -107,7 +107,6 @@ static int qi_lb60_probe(struct platform_device *pdev) static struct platform_driver qi_lb60_driver = { .driver = { .name = "qi-lb60-audio", - .owner = THIS_MODULE, }, .probe = qi_lb60_probe, }; -- GitLab From b4c1456f86af6a73b2d716ad21cd6fdfad784bf0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:10 +0200 Subject: [PATCH 0881/9457] ASoC: kirkwood: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/kirkwood/armada-370-db.c | 1 - sound/soc/kirkwood/kirkwood-i2s.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c index c44333849259..de7563bdc5c2 100644 --- a/sound/soc/kirkwood/armada-370-db.c +++ b/sound/soc/kirkwood/armada-370-db.c @@ -134,7 +134,6 @@ static const struct of_device_id a370db_dt_ids[] = { static struct platform_driver a370db_driver = { .driver = { .name = "a370db-audio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(a370db_dt_ids), }, .probe = a370db_probe, diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 0704cd6d2314..def7d8260c4e 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -657,7 +657,6 @@ static struct platform_driver kirkwood_i2s_driver = { .remove = kirkwood_i2s_dev_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mvebu_audio_of_match), }, }; -- GitLab From 38b089d78b3084fa100315e5f167d8019e446eae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:10 +0200 Subject: [PATCH 0882/9457] ASoC: mxs: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/mxs/mxs-saif.c | 1 - sound/soc/mxs/mxs-sgtl5000.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 231d7e7b0711..eade2742a937 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -815,7 +815,6 @@ static struct platform_driver mxs_saif_driver = { .driver = { .name = "mxs-saif", - .owner = THIS_MODULE, .of_match_table = mxs_saif_dt_ids, }, }; diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 61822cc53bd3..7515cd434e21 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -194,7 +194,6 @@ MODULE_DEVICE_TABLE(of, mxs_sgtl5000_dt_ids); static struct platform_driver mxs_sgtl5000_audio_driver = { .driver = { .name = "mxs-sgtl5000", - .owner = THIS_MODULE, .of_match_table = mxs_sgtl5000_dt_ids, }, .probe = mxs_sgtl5000_probe, -- GitLab From 9a600224a39aebb2c6b50514c5a4237032b8b653 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:11 +0200 Subject: [PATCH 0883/9457] ASoC: nuc900: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/nuc900/nuc900-ac97.c | 1 - sound/soc/nuc900/nuc900-pcm.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index f2f67942b229..291ee12d2bb9 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -385,7 +385,6 @@ static int nuc900_ac97_drvremove(struct platform_device *pdev) static struct platform_driver nuc900_ac97_driver = { .driver = { .name = "nuc900-ac97", - .owner = THIS_MODULE, }, .probe = nuc900_ac97_drvprobe, .remove = nuc900_ac97_drvremove, diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index f434ed79d1b6..b779a3d9b5dd 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -347,7 +347,6 @@ static int nuc900_soc_platform_remove(struct platform_device *pdev) static struct platform_driver nuc900_pcm_driver = { .driver = { .name = "nuc900-pcm-audio", - .owner = THIS_MODULE, }, .probe = nuc900_soc_platform_probe, -- GitLab From d34135b4c0ef4508f514ba43e02b226e4ba9236b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:11 +0200 Subject: [PATCH 0884/9457] ASoC: omap: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/omap/ams-delta.c | 1 - sound/soc/omap/omap-abe-twl6040.c | 1 - sound/soc/omap/omap-dmic.c | 1 - sound/soc/omap/omap-hdmi-card.c | 1 - sound/soc/omap/omap-hdmi.c | 1 - sound/soc/omap/omap-mcbsp.c | 1 - sound/soc/omap/omap-mcpdm.c | 1 - sound/soc/omap/omap-twl4030.c | 1 - sound/soc/omap/rx51.c | 1 - 9 files changed, 9 deletions(-) diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 8c9cc64a9dfb..4c6afb75eea6 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -599,7 +599,6 @@ static int ams_delta_remove(struct platform_device *pdev) static struct platform_driver ams_delta_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = ams_delta_probe, .remove = ams_delta_remove, diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index cec836ed0c01..b9c65f1ad5a8 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -354,7 +354,6 @@ MODULE_DEVICE_TABLE(of, omap_abe_of_match); static struct platform_driver omap_abe_driver = { .driver = { .name = "omap-abe-twl6040", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = omap_abe_of_match, }, diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 0f34e28a3d55..09db2aec12a3 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -509,7 +509,6 @@ MODULE_DEVICE_TABLE(of, omap_dmic_of_match); static struct platform_driver asoc_dmic_driver = { .driver = { .name = "omap-dmic", - .owner = THIS_MODULE, .of_match_table = omap_dmic_of_match, }, .probe = asoc_dmic_probe, diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c index f649fe84b629..788d5dfd388f 100644 --- a/sound/soc/omap/omap-hdmi-card.c +++ b/sound/soc/omap/omap-hdmi-card.c @@ -73,7 +73,6 @@ static int omap_hdmi_remove(struct platform_device *pdev) static struct platform_driver omap_hdmi_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = omap_hdmi_probe, .remove = omap_hdmi_remove, diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index eb9c39299f81..3abe80a68be2 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -349,7 +349,6 @@ static int omap_hdmi_remove(struct platform_device *pdev) static struct platform_driver hdmi_dai_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = omap_hdmi_probe, .remove = omap_hdmi_remove, diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index bd3ef2a88be0..8b79cafab1e2 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -831,7 +831,6 @@ static int asoc_mcbsp_remove(struct platform_device *pdev) static struct platform_driver asoc_mcbsp_driver = { .driver = { .name = "omap-mcbsp", - .owner = THIS_MODULE, .of_match_table = omap_mcbsp_of_match, }, diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index f0e2ebeab02b..b837265ac3e9 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -512,7 +512,6 @@ MODULE_DEVICE_TABLE(of, omap_mcpdm_of_match); static struct platform_driver asoc_mcpdm_driver = { .driver = { .name = "omap-mcpdm", - .owner = THIS_MODULE, .of_match_table = omap_mcpdm_of_match, }, diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index 4336d1831485..5e551c762b7a 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -375,7 +375,6 @@ MODULE_DEVICE_TABLE(of, omap_twl4030_of_match); static struct platform_driver omap_twl4030_driver = { .driver = { .name = "omap-twl4030", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = omap_twl4030_of_match, }, diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index b10ae8074461..04896d6252a2 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -519,7 +519,6 @@ MODULE_DEVICE_TABLE(of, rx51_audio_of_match); static struct platform_driver rx51_soc_driver = { .driver = { .name = "rx51-audio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rx51_audio_of_match), }, .probe = rx51_soc_probe, -- GitLab From 08d30ecc67ee1ef222ee1b92b342b9ce51d29a39 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:11 +0200 Subject: [PATCH 0885/9457] ASoC: pxa: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/pxa/brownstone.c | 1 - sound/soc/pxa/corgi.c | 1 - sound/soc/pxa/e740_wm9705.c | 1 - sound/soc/pxa/e750_wm9705.c | 1 - sound/soc/pxa/e800_wm9712.c | 1 - sound/soc/pxa/hx4700.c | 1 - sound/soc/pxa/imote2.c | 1 - sound/soc/pxa/mioa701_wm9713.c | 1 - sound/soc/pxa/mmp-pcm.c | 1 - sound/soc/pxa/mmp-sspa.c | 1 - sound/soc/pxa/palm27x.c | 1 - sound/soc/pxa/poodle.c | 1 - sound/soc/pxa/pxa-ssp.c | 1 - sound/soc/pxa/pxa2xx-ac97.c | 1 - sound/soc/pxa/pxa2xx-i2s.c | 1 - sound/soc/pxa/pxa2xx-pcm.c | 1 - sound/soc/pxa/tosa.c | 1 - sound/soc/pxa/ttc-dkb.c | 1 - 18 files changed, 18 deletions(-) diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c index c8dd53f9c35d..79936e3e80e7 100644 --- a/sound/soc/pxa/brownstone.c +++ b/sound/soc/pxa/brownstone.c @@ -155,7 +155,6 @@ static int brownstone_remove(struct platform_device *pdev) static struct platform_driver mmp_driver = { .driver = { .name = "brownstone-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = brownstone_probe, diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 5a88136aa800..b7cd0a71fd70 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -327,7 +327,6 @@ static int corgi_remove(struct platform_device *pdev) static struct platform_driver corgi_driver = { .driver = { .name = "corgi-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = corgi_probe, diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index c29fedab2f49..7c691aae8af2 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -177,7 +177,6 @@ static int e740_remove(struct platform_device *pdev) static struct platform_driver e740_driver = { .driver = { .name = "e740-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = e740_probe, diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index ee36aba88063..30544b65b5a8 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -159,7 +159,6 @@ static int e750_remove(struct platform_device *pdev) static struct platform_driver e750_driver = { .driver = { .name = "e750-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = e750_probe, diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 24c2078ce70b..45d4bd46fff6 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -140,7 +140,6 @@ static int e800_remove(struct platform_device *pdev) static struct platform_driver e800_driver = { .driver = { .name = "e800-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = e800_probe, diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index 05559a725bec..ce26551052a3 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -226,7 +226,6 @@ static int hx4700_audio_remove(struct platform_device *pdev) static struct platform_driver hx4700_audio_driver = { .driver = { .name = "hx4700-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = hx4700_audio_probe, diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c index fd2f4eda1fd3..29fabbfd21f1 100644 --- a/sound/soc/pxa/imote2.c +++ b/sound/soc/pxa/imote2.c @@ -90,7 +90,6 @@ static int imote2_remove(struct platform_device *pdev) static struct platform_driver imote2_driver = { .driver = { .name = "imote2-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = imote2_probe, diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 595eee341e90..0d746cc880c1 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -205,7 +205,6 @@ static struct platform_driver mioa701_wm9713_driver = { .remove = mioa701_wm9713_remove, .driver = { .name = "mioa701-wm9713", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 64e8b949a1a3..1eb45dcfb8e8 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -244,7 +244,6 @@ static int mmp_pcm_remove(struct platform_device *pdev) static struct platform_driver mmp_pcm_driver = { .driver = { .name = "mmp-pcm-audio", - .owner = THIS_MODULE, }, .probe = mmp_pcm_probe, diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 5bf5f1f7cac5..eca60c29791a 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -472,7 +472,6 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev) static struct platform_driver asoc_mmp_sspa_driver = { .driver = { .name = "mmp-sspa-dai", - .owner = THIS_MODULE, }, .probe = asoc_mmp_sspa_probe, .remove = asoc_mmp_sspa_remove, diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 17f9521ff6ea..1eebca2f0a97 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -172,7 +172,6 @@ static struct platform_driver palm27x_wm9712_driver = { .remove = palm27x_asoc_remove, .driver = { .name = "palm27x-asoc", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, }; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 21f340065318..0fce8c420e96 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -296,7 +296,6 @@ static int poodle_remove(struct platform_device *pdev) static struct platform_driver poodle_driver = { .driver = { .name = "poodle-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = poodle_probe, diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a8e097433074..020b79a23f92 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -826,7 +826,6 @@ static int asoc_ssp_remove(struct platform_device *pdev) static struct platform_driver asoc_ssp_driver = { .driver = { .name = "pxa-ssp-dai", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(pxa_ssp_of_ids), }, diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index ae956e3f4b9d..9455314e1281 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -261,7 +261,6 @@ static struct platform_driver pxa2xx_ac97_driver = { .remove = pxa2xx_ac97_dev_remove, .driver = { .name = "pxa2xx-ac97", - .owner = THIS_MODULE, #ifdef CONFIG_PM_SLEEP .pm = &pxa2xx_ac97_pm_ops, #endif diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index c0d648d3339f..e68290c15328 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -383,7 +383,6 @@ static struct platform_driver pxa2xx_i2s_driver = { .driver = { .name = "pxa2xx-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 42f2f0175981..a51c9da66614 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -143,7 +143,6 @@ static const struct of_device_id snd_soc_pxa_audio_match[] = { static struct platform_driver pxa_pcm_driver = { .driver = { .name = "pxa-pcm-audio", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(snd_soc_pxa_audio_match), }, diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 4a956d1cb269..cb49284e853a 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -265,7 +265,6 @@ static int tosa_remove(struct platform_device *pdev) static struct platform_driver tosa_driver = { .driver = { .name = "tosa-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = tosa_probe, diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index 9d7c5b7e9539..e3d7257ad09c 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c @@ -155,7 +155,6 @@ static int ttc_dkb_remove(struct platform_device *pdev) static struct platform_driver ttc_dkb_driver = { .driver = { .name = "ttc-dkb-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = ttc_dkb_probe, -- GitLab From d20114fd74f728fea26aa213a5e5fc436f2d3e57 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:12 +0200 Subject: [PATCH 0886/9457] ASoC: rockchip: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/rockchip/rockchip_i2s.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index f373e37f8305..5f63cbfeb879 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -526,7 +526,6 @@ static struct platform_driver rockchip_i2s_driver = { .remove = rockchip_i2s_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rockchip_i2s_match), .pm = &rockchip_i2s_pm_ops, }, -- GitLab From bc46ec16a579a5ba2b93f4e87390a466586556ce Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:12 +0200 Subject: [PATCH 0887/9457] ASoC: s6000: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/s6000/s6000-i2s.c | 1 - sound/soc/s6000/s6000-pcm.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 1c8d01166e5b..58c67642ed35 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -606,7 +606,6 @@ static struct platform_driver s6000_i2s_driver = { .remove = s6000_i2s_remove, .driver = { .name = "s6000-i2s", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index fb8461e1b1f6..370fbb44033b 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -507,7 +507,6 @@ static int s6000_soc_platform_remove(struct platform_device *pdev) static struct platform_driver s6000_pcm_driver = { .driver = { .name = "s6000-pcm-audio", - .owner = THIS_MODULE, }, .probe = s6000_soc_platform_probe, -- GitLab From ac204d2290e5a76ecff5b597beb19f98680ef095 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:13 +0200 Subject: [PATCH 0888/9457] ASoC: samsung: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/samsung/ac97.c | 1 - sound/soc/samsung/bells.c | 1 - sound/soc/samsung/i2s.c | 1 - sound/soc/samsung/idma.c | 1 - sound/soc/samsung/littlemill.c | 1 - sound/soc/samsung/lowland.c | 1 - sound/soc/samsung/odroidx2_max98090.c | 1 - sound/soc/samsung/pcm.c | 1 - sound/soc/samsung/s3c2412-i2s.c | 1 - sound/soc/samsung/s3c24xx-i2s.c | 1 - sound/soc/samsung/s3c24xx_simtec_hermes.c | 1 - sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c | 1 - sound/soc/samsung/s3c24xx_uda134x.c | 1 - sound/soc/samsung/smdk_wm8580pcm.c | 1 - sound/soc/samsung/smdk_wm8994.c | 1 - sound/soc/samsung/smdk_wm8994pcm.c | 1 - sound/soc/samsung/snow.c | 1 - sound/soc/samsung/spdif.c | 1 - sound/soc/samsung/speyside.c | 1 - sound/soc/samsung/tobermory.c | 1 - 20 files changed, 20 deletions(-) diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index e1615113fd84..cb9dd57814ed 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -442,7 +442,6 @@ static struct platform_driver s3c_ac97_driver = { .remove = s3c_ac97_remove, .driver = { .name = "samsung-ac97", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 5b21207cf551..e5f05e62fa3c 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -445,7 +445,6 @@ static int bells_probe(struct platform_device *pdev) static struct platform_driver bells_driver = { .driver = { .name = "bells", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = bells_probe, diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 9d513473b300..2e7097429bee 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1366,7 +1366,6 @@ static struct platform_driver samsung_i2s_driver = { .id_table = samsung_i2s_driver_ids, .driver = { .name = "samsung-i2s", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(exynos_i2s_match), .pm = &samsung_i2s_pm, }, diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 0e8dd985fcb3..4ed29ffc1c54 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -418,7 +418,6 @@ static int asoc_idma_platform_probe(struct platform_device *pdev) static struct platform_driver asoc_idma_driver = { .driver = { .name = "samsung-idma", - .owner = THIS_MODULE, }, .probe = asoc_idma_platform_probe, diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index 840787e63cb1..141519c21e21 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -315,7 +315,6 @@ static int littlemill_probe(struct platform_device *pdev) static struct platform_driver littlemill_driver = { .driver = { .name = "littlemill", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = littlemill_probe, diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index bd5f0d643a86..243dea7ba38f 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -198,7 +198,6 @@ static int lowland_probe(struct platform_device *pdev) static struct platform_driver lowland_driver = { .driver = { .name = "lowland", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = lowland_probe, diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index 3c8f60423e82..1d3c3af5886e 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c @@ -162,7 +162,6 @@ static int odroidx2_audio_remove(struct platform_device *pdev) static struct platform_driver odroidx2_audio_driver = { .driver = { .name = "odroidx2-audio", - .owner = THIS_MODULE, .of_match_table = odroidx2_audio_of_match, .pm = &snd_soc_pm_ops, }, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index bac034b15a27..b320a9d3fbf8 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -626,7 +626,6 @@ static struct platform_driver s3c_pcm_driver = { .remove = s3c_pcm_dev_remove, .driver = { .name = "samsung-pcm", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 27b339c6580e..2b766d212ce0 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -180,7 +180,6 @@ static struct platform_driver s3c2412_iis_driver = { .probe = s3c2412_iis_dev_probe, .driver = { .name = "s3c2412-iis", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index e87d9a2053b8..326d3c3804e3 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -485,7 +485,6 @@ static struct platform_driver s3c24xx_iis_driver = { .probe = s3c24xx_iis_dev_probe, .driver = { .name = "s3c24xx-iis", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index 2d30b7b6818a..7ac924c595bf 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c @@ -99,7 +99,6 @@ static int simtec_audio_hermes_probe(struct platform_device *pd) static struct platform_driver simtec_audio_hermes_platdrv = { .driver = { - .owner = THIS_MODULE, .name = "s3c24xx-simtec-hermes-snd", .pm = simtec_audio_pm, }, diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index 83f6c7d49cd6..b4ed2fc1a65c 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c @@ -87,7 +87,6 @@ static int simtec_audio_tlv320aic23_probe(struct platform_device *pd) static struct platform_driver simtec_audio_tlv320aic23_driver = { .driver = { - .owner = THIS_MODULE, .name = "s3c24xx-simtec-tlv320aic23", .pm = simtec_audio_pm, }, diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 1b7b52b0af97..9c6f7db56f60 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -340,7 +340,6 @@ static struct platform_driver s3c24xx_uda134x_driver = { .remove = s3c24xx_uda134x_remove, .driver = { .name = "s3c24xx_uda134x", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 63d079303561..05c609c62de9 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c @@ -173,7 +173,6 @@ static int snd_smdk_probe(struct platform_device *pdev) static struct platform_driver snd_smdk_driver = { .driver = { - .owner = THIS_MODULE, .name = "samsung-smdk-pcm", }, .probe = snd_smdk_probe, diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index 3d6272a8cad2..d38595fbdab7 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -191,7 +191,6 @@ static int smdk_audio_probe(struct platform_device *pdev) static struct platform_driver smdk_audio_driver = { .driver = { .name = "smdk-audio-wm8994", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(samsung_wm8994_of_match), .pm = &snd_soc_pm_ops, }, diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index b6c09979be1f..c470e8eed6e1 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c @@ -143,7 +143,6 @@ static int snd_smdk_probe(struct platform_device *pdev) static struct platform_driver snd_smdk_driver = { .driver = { - .owner = THIS_MODULE, .name = "samsung-smdk-pcm", }, .probe = snd_smdk_probe, diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c index 0acf5d0eed53..61e8efd9f779 100644 --- a/sound/soc/samsung/snow.c +++ b/sound/soc/samsung/snow.c @@ -114,7 +114,6 @@ static const struct of_device_id snow_of_match[] = { static struct platform_driver snow_driver = { .driver = { .name = "snow-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = snow_of_match, }, diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index d7d2e208f486..36dbc0e96004 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -477,7 +477,6 @@ static struct platform_driver samsung_spdif_driver = { .remove = spdif_remove, .driver = { .name = "samsung-spdif", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index a05482651aae..5ec7c52282f2 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -340,7 +340,6 @@ static int speyside_probe(struct platform_device *pdev) static struct platform_driver speyside_driver = { .driver = { .name = "speyside", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = speyside_probe, diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 6a2b9f14d624..9c80506527c4 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -234,7 +234,6 @@ static int tobermory_probe(struct platform_device *pdev) static struct platform_driver tobermory_driver = { .driver = { .name = "tobermory", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, .probe = tobermory_probe, -- GitLab From f20068009adf34dcc2b10b3f134502205aa9f04e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:13 +0200 Subject: [PATCH 0889/9457] ASoC: sh: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/sh/dma-sh7760.c | 1 - sound/soc/sh/hac.c | 1 - sound/soc/sh/siu_dai.c | 1 - sound/soc/sh/ssi.c | 1 - 4 files changed, 4 deletions(-) diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index c85f8eb66c97..a5b2c4ea90d9 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -345,7 +345,6 @@ static int sh7760_soc_platform_remove(struct platform_device *pdev) static struct platform_driver sh7760_pcm_driver = { .driver = { .name = "sh7760-pcm-audio", - .owner = THIS_MODULE, }, .probe = sh7760_soc_platform_probe, diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 0af2e4dfd139..0e0115cf2959 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -333,7 +333,6 @@ static int hac_soc_platform_remove(struct platform_device *pdev) static struct platform_driver hac_pcm_driver = { .driver = { .name = "hac-pcm-audio", - .owner = THIS_MODULE, }, .probe = hac_soc_platform_probe, diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index d55babee14f8..abb0d956231c 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -845,7 +845,6 @@ static int siu_remove(struct platform_device *pdev) static struct platform_driver siu_driver = { .driver = { - .owner = THIS_MODULE, .name = "siu-pcm-audio", }, .probe = siu_probe, diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index e889405ebd38..ab13146e4f82 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -398,7 +398,6 @@ static int sh4_soc_dai_remove(struct platform_device *pdev) static struct platform_driver sh4_ssi_driver = { .driver = { .name = "sh4-ssi-dai", - .owner = THIS_MODULE, }, .probe = sh4_soc_dai_probe, -- GitLab From 33db744abe957baa8440b7065644c1becde28dc3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:14 +0200 Subject: [PATCH 0890/9457] ASoC: sirf: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/sirf/sirf-audio-port.c | 1 - sound/soc/sirf/sirf-audio.c | 1 - sound/soc/sirf/sirf-usp.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c index b4afa31b2bc1..3f2cce03275c 100644 --- a/sound/soc/sirf/sirf-audio-port.c +++ b/sound/soc/sirf/sirf-audio-port.c @@ -74,7 +74,6 @@ MODULE_DEVICE_TABLE(of, sirf_audio_port_of_match); static struct platform_driver sirf_audio_port_driver = { .driver = { .name = "sirf-audio-port", - .owner = THIS_MODULE, .of_match_table = sirf_audio_port_of_match, }, .probe = sirf_audio_port_probe, diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c index ecef51021653..94ea152e0362 100644 --- a/sound/soc/sirf/sirf-audio.c +++ b/sound/soc/sirf/sirf-audio.c @@ -143,7 +143,6 @@ MODULE_DEVICE_TABLE(of, sirf_audio_of_match); static struct platform_driver sirf_audio_driver = { .driver = { .name = "sirf-audio-card", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = sirf_audio_of_match, }, diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c index 186dc7f33a55..45fc06c0e0e5 100644 --- a/sound/soc/sirf/sirf-usp.c +++ b/sound/soc/sirf/sirf-usp.c @@ -422,7 +422,6 @@ static const struct dev_pm_ops sirf_usp_pcm_pm_ops = { static struct platform_driver sirf_usp_pcm_driver = { .driver = { .name = "sirf-usp-pcm", - .owner = THIS_MODULE, .of_match_table = sirf_usp_pcm_of_match, .pm = &sirf_usp_pcm_pm_ops, }, -- GitLab From 0d0a995aa8711adeaee2c4d00178e51efa3c8479 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:14 +0200 Subject: [PATCH 0891/9457] ASoC: spear: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/spear/spdif_in.c | 1 - sound/soc/spear/spdif_out.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 4ab442a63d7e..a4028601da01 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -274,7 +274,6 @@ static struct platform_driver spdif_in_driver = { .probe = spdif_in_probe, .driver = { .name = "spdif-in", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 19cca043e6e4..0a72d52d533e 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -354,7 +354,6 @@ static struct platform_driver spdif_out_driver = { .probe = spdif_out_probe, .driver = { .name = "spdif-out", - .owner = THIS_MODULE, .pm = SPDIF_OUT_DEV_PM_OPS, }, }; -- GitLab From 89032b176b8200257de2f21ee57ddaef8a212e8c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:15 +0200 Subject: [PATCH 0892/9457] ASoC: tegra: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/tegra/tegra20_ac97.c | 1 - sound/soc/tegra/tegra20_das.c | 1 - sound/soc/tegra/tegra20_i2s.c | 1 - sound/soc/tegra/tegra20_spdif.c | 1 - sound/soc/tegra/tegra30_ahub.c | 1 - sound/soc/tegra/tegra30_i2s.c | 1 - sound/soc/tegra/tegra_alc5632.c | 1 - sound/soc/tegra/tegra_max98090.c | 1 - sound/soc/tegra/tegra_rt5640.c | 1 - sound/soc/tegra/tegra_wm8753.c | 1 - sound/soc/tegra/tegra_wm8903.c | 1 - sound/soc/tegra/tegra_wm9712.c | 1 - sound/soc/tegra/trimslice.c | 1 - 13 files changed, 13 deletions(-) diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 3b0fa12dbff7..e3dd2615eb69 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -438,7 +438,6 @@ static const struct of_device_id tegra20_ac97_of_match[] = { static struct platform_driver tegra20_ac97_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra20_ac97_of_match, }, .probe = tegra20_ac97_platform_probe, diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index a634f13b3ffc..f52600b4f3fd 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -233,7 +233,6 @@ static struct platform_driver tegra20_das_driver = { .remove = tegra20_das_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra20_das_of_match, }, }; diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 79a9932ffe6e..05f1c6ee99e3 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -464,7 +464,6 @@ static const struct dev_pm_ops tegra20_i2s_pm_ops = { static struct platform_driver tegra20_i2s_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra20_i2s_of_match, .pm = &tegra20_i2s_pm_ops, }, diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index a0ce92400faf..9141477a528d 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -387,7 +387,6 @@ static const struct dev_pm_ops tegra20_spdif_pm_ops = { static struct platform_driver tegra20_spdif_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &tegra20_spdif_pm_ops, }, .probe = tegra20_spdif_platform_probe, diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 0db68f49f4d9..bc94e5d8e79a 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -723,7 +723,6 @@ static struct platform_driver tegra30_ahub_driver = { .remove = tegra30_ahub_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra30_ahub_of_match, .pm = &tegra30_ahub_pm_ops, }, diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index f146c41dd3ec..fe36375ba89c 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -585,7 +585,6 @@ static const struct dev_pm_ops tegra30_i2s_pm_ops = { static struct platform_driver tegra30_i2s_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = tegra30_i2s_of_match, .pm = &tegra30_i2s_pm_ops, }, diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index a83aff09dce2..769aca2fc5f5 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -250,7 +250,6 @@ static const struct of_device_id tegra_alc5632_of_match[] = { static struct platform_driver tegra_alc5632_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_alc5632_of_match, }, diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index 01921d7e73fa..af3fb997b752 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -308,7 +308,6 @@ static const struct of_device_id tegra_max98090_of_match[] = { static struct platform_driver tegra_max98090_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_max98090_of_match, }, diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index a6898831fb9f..c0c15a94bab1 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -251,7 +251,6 @@ static const struct of_device_id tegra_rt5640_of_match[] = { static struct platform_driver tegra_rt5640_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_rt5640_of_match, }, diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 769e28f6642e..f0cd01dbfc38 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -204,7 +204,6 @@ static const struct of_device_id tegra_wm8753_of_match[] = { static struct platform_driver tegra_wm8753_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_wm8753_of_match, }, diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 86e05e938585..e52420dae2b4 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -386,7 +386,6 @@ static const struct of_device_id tegra_wm8903_of_match[] = { static struct platform_driver tegra_wm8903_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_wm8903_of_match, }, diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index de087ee3458a..2868b4839bc0 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -167,7 +167,6 @@ static const struct of_device_id tegra_wm9712_of_match[] = { static struct platform_driver tegra_wm9712_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = tegra_wm9712_of_match, }, diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 589d2d9b553a..2cea203c4f5f 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -193,7 +193,6 @@ MODULE_DEVICE_TABLE(of, trimslice_of_match); static struct platform_driver tegra_snd_trimslice_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .of_match_table = trimslice_of_match, }, .probe = tegra_snd_trimslice_probe, -- GitLab From 1cfc291a30c29082992d69dc203c5213f90d57ed Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:15 +0200 Subject: [PATCH 0893/9457] ASoC: txx9: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/txx9/txx9aclc-ac97.c | 1 - sound/soc/txx9/txx9aclc-generic.c | 1 - sound/soc/txx9/txx9aclc.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 9edd68db9f48..57e4d99b3cd8 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -224,7 +224,6 @@ static struct platform_driver txx9aclc_ac97_driver = { .remove = txx9aclc_ac97_dev_remove, .driver = { .name = "txx9aclc-ac97", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index b056a1431ed4..d0b1e7759968 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c @@ -66,7 +66,6 @@ static struct platform_driver txx9aclc_generic_driver = { .remove = __exit_p(txx9aclc_generic_remove), .driver = { .name = "txx9aclc-generic", - .owner = THIS_MODULE, }, }; diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index cd71fd889d8b..45684206118e 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -429,7 +429,6 @@ static int txx9aclc_soc_platform_remove(struct platform_device *pdev) static struct platform_driver txx9aclc_pcm_driver = { .driver = { .name = "txx9aclc-pcm-audio", - .owner = THIS_MODULE, }, .probe = txx9aclc_soc_platform_probe, -- GitLab From c9e2faeb20f8c9e1e8cf789fa9860f2a491e5a2e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:15 +0200 Subject: [PATCH 0894/9457] ASoC: ux500: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/soc/ux500/mop500.c | 1 - sound/soc/ux500/ux500_msp_dai.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index b3b66aa98dce..2ba0d42b108f 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -159,7 +159,6 @@ static const struct of_device_id snd_soc_mop500_match[] = { static struct platform_driver snd_soc_mop500_driver = { .driver = { - .owner = THIS_MODULE, .name = "snd-soc-mop500", .of_match_table = snd_soc_mop500_match, }, diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 5f4807b2c007..978f2d7316b0 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -856,7 +856,6 @@ static const struct of_device_id ux500_msp_i2s_match[] = { static struct platform_driver msp_i2s_driver = { .driver = { .name = "ux500-msp-i2s", - .owner = THIS_MODULE, .of_match_table = ux500_msp_i2s_match, }, .probe = ux500_msp_drv_probe, -- GitLab From 79cd1762933153237731585f0901eec368e54bae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Oct 2014 16:22:16 +0200 Subject: [PATCH 0895/9457] ALSA: sparc: drop owner assignment from platform_drivers A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang --- sound/sparc/amd7930.c | 1 - sound/sparc/cs4231.c | 1 - sound/sparc/dbri.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 4a85e1433472..86280d63b76d 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1067,7 +1067,6 @@ static const struct of_device_id amd7930_match[] = { static struct platform_driver amd7930_sbus_driver = { .driver = { .name = "audio", - .owner = THIS_MODULE, .of_match_table = amd7930_match, }, .probe = amd7930_sbus_probe, diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 4e91bcaa3664..a3fcb592318b 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2119,7 +2119,6 @@ MODULE_DEVICE_TABLE(of, cs4231_match); static struct platform_driver cs4231_driver = { .driver = { .name = "audio", - .owner = THIS_MODULE, .of_match_table = cs4231_match, }, .probe = cs4231_probe, diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index b2c3d0d5dca3..0190cb6332f2 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2686,7 +2686,6 @@ MODULE_DEVICE_TABLE(of, dbri_match); static struct platform_driver dbri_sbus_driver = { .driver = { .name = "dbri", - .owner = THIS_MODULE, .of_match_table = dbri_match, }, .probe = dbri_probe, -- GitLab From 89c771e5a62b856f4705f189892c489190edaec1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 10 Oct 2014 20:52:40 +0300 Subject: [PATCH 0896/9457] cfg80211: Convert del_station() callback to use a param struct This makes it easier to add new parameters for the del_station calls without having to modify all drivers that use this. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 4 +-- drivers/net/wireless/ath/wil6210/cfg80211.c | 5 ++-- .../wireless/brcm80211/brcmfmac/wl_cfg80211.c | 8 +++--- drivers/net/wireless/mwifiex/cfg80211.c | 9 ++++--- .../staging/rtl8723au/os_dep/ioctl_cfg80211.c | 4 ++- include/net/cfg80211.h | 15 +++++++++-- net/mac80211/cfg.c | 6 ++--- net/wireless/nl80211.c | 8 +++--- net/wireless/rdev-ops.h | 7 +++--- net/wireless/trace.h | 25 ++++++++++++++++--- 10 files changed, 64 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index ba60e37213eb..7a5337877a0c 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2976,11 +2976,11 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); - const u8 *addr = mac ? mac : bcast_addr; + const u8 *addr = params->mac ? params->mac : bcast_addr; return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index d9f4b30dd343..8fdfa3222a6e 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -792,12 +792,13 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, } static int wil_cfg80211_del_station(struct wiphy *wiphy, - struct net_device *dev, const u8 *mac) + struct net_device *dev, + struct station_del_parameters *params) { struct wil6210_priv *wil = wiphy_to_wil(wiphy); mutex_lock(&wil->mutex); - wil6210_disconnect(wil, mac); + wil6210_disconnect(wil, params->mac); mutex_unlock(&wil->mutex); return 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28fa25b509db..1a2e062d3bfd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3998,24 +3998,24 @@ brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, - const u8 *mac) + struct station_del_parameters *params) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_scb_val_le scbval; struct brcmf_if *ifp = netdev_priv(ndev); s32 err; - if (!mac) + if (!params->mac) return -EFAULT; - brcmf_dbg(TRACE, "Enter %pM\n", mac); + brcmf_dbg(TRACE, "Enter %pM\n", params->mac); if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; if (!check_vif_up(ifp->vif)) return -EIO; - memcpy(&scbval.ea, mac, ETH_ALEN); + memcpy(&scbval.ea, params->mac, ETH_ALEN); scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scbval)); diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 0dd672954ad1..71e29c7055de 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1239,7 +1239,7 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy, */ static int mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_sta_node *sta_node; @@ -1248,7 +1248,7 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, if (list_empty(&priv->sta_list) || !priv->bss_started) return 0; - if (!mac || is_broadcast_ether_addr(mac)) { + if (!params->mac || is_broadcast_ether_addr(params->mac)) { wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__); list_for_each_entry(sta_node, &priv->sta_list, list) { if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH, @@ -1258,9 +1258,10 @@ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, mwifiex_uap_del_sta_data(priv, sta_node); } } else { - wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac); + wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, + params->mac); spin_lock_irqsave(&priv->sta_list_spinlock, flags); - sta_node = mwifiex_get_sta_entry(priv, mac); + sta_node = mwifiex_get_sta_entry(priv, params->mac); spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); if (sta_node) { if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH, diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index bd6953af0a03..3d26955da724 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -2856,8 +2856,10 @@ static int cfg80211_rtw_add_station(struct wiphy *wiphy, } static int cfg80211_rtw_del_station(struct wiphy *wiphy, - struct net_device *ndev, const u8 *mac) + struct net_device *ndev, + struct station_del_parameters *params) { + const u8 *mac = params->mac; int ret = 0; struct list_head *phead, *plist, *ptmp; u8 updated = 0; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3f3aaa06adb5..ebb69f671979 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -798,6 +798,17 @@ struct station_parameters { bool opmode_notif_used; }; +/** + * struct station_del_parameters - station deletion parameters + * + * Used to delete a station entry (or all stations). + * + * @mac: MAC address of the station to remove or NULL to remove all stations + */ +struct station_del_parameters { + const u8 *mac; +}; + /** * enum cfg80211_station_type - the type of station being modified * @CFG80211_STA_AP_CLIENT: client of an AP interface @@ -2132,7 +2143,7 @@ struct cfg80211_qos_map { * @stop_ap: Stop being an AP, including stopping beaconing. * * @add_station: Add a new station. - * @del_station: Remove a station; @mac may be NULL to remove all stations. + * @del_station: Remove a station * @change_station: Modify a given station. Note that flags changes are not much * validated in cfg80211, in particular the auth/assoc/authorized flags * might come to the driver in invalid combinations -- make sure to check @@ -2378,7 +2389,7 @@ struct cfg80211_ops { const u8 *mac, struct station_parameters *params); int (*del_station)(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac); + struct station_del_parameters *params); int (*change_station)(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4bb2d34b2dd7..a1498416ad55 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1225,14 +1225,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac) + struct station_del_parameters *params) { struct ieee80211_sub_if_data *sdata; sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (mac) - return sta_info_destroy_addr_bss(sdata, mac); + if (params->mac) + return sta_info_destroy_addr_bss(sdata, params->mac); sta_info_flush(sdata); return 0; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d527aa0706c1..40cf7b937926 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4398,10 +4398,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; - u8 *mac_addr = NULL; + struct station_del_parameters params; + + memset(¶ms, 0, sizeof(params)); if (info->attrs[NL80211_ATTR_MAC]) - mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]); if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && @@ -4412,7 +4414,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_station) return -EOPNOTSUPP; - return rdev_del_station(rdev, dev, mac_addr); + return rdev_del_station(rdev, dev, ¶ms); } static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c09e697bcb15..71b1db3cc645 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -178,11 +178,12 @@ static inline int rdev_add_station(struct cfg80211_registered_device *rdev, } static inline int rdev_del_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac) + struct net_device *dev, + struct station_del_parameters *params) { int ret; - trace_rdev_del_station(&rdev->wiphy, dev, mac); - ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); + trace_rdev_del_station(&rdev->wiphy, dev, params); + ret = rdev->ops->del_station(&rdev->wiphy, dev, params); trace_rdev_return_int(&rdev->wiphy, ret); return ret; } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 8e4f8f04332d..b1339400631d 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -680,9 +680,28 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) ); -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) +DECLARE_EVENT_CLASS(station_del, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct station_del_parameters *params), + TP_ARGS(wiphy, netdev, params), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(sta_mac) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(sta_mac, params->mac); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) +); + +DEFINE_EVENT(station_del, rdev_del_station, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + struct station_del_parameters *params), + TP_ARGS(wiphy, netdev, params) ); DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, -- GitLab From 988568669d171774b96e59fe35ef575df7f8cffd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 20 Oct 2014 13:20:45 +0300 Subject: [PATCH 0897/9457] cfg80211: Specify frame and reason code for NL80211_CMD_DEL_STATION The optional NL80211_ATTR_MGMT_SUBTYPE and NL80211_ATTR_REASON_CODE attributes can now be included in NL80211_CMD_DEL_STATION to indicate to the driver which frame (Deauthentication/Disassociation) and reason code in that frame should be used to indicate removal to the specific station. This is used by drivers that implement AP SME and generate those frames internally. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 5 +++++ include/uapi/linux/nl80211.h | 6 +++++- net/wireless/nl80211.c | 21 +++++++++++++++++++++ net/wireless/trace.h | 10 ++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ebb69f671979..ed896c0b5b8b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -804,9 +804,14 @@ struct station_parameters { * Used to delete a station entry (or all stations). * * @mac: MAC address of the station to remove or NULL to remove all stations + * @subtype: Management frame subtype to use for indicating removal + * (10 = Disassociation, 12 = Deauthentication) + * @reason_code: Reason code for the Disassociation/Deauthentication frame */ struct station_del_parameters { const u8 *mac; + u8 subtype; + u16 reason_code; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 846071b0cde9..b553c48404d3 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -227,7 +227,11 @@ * the interface identified by %NL80211_ATTR_IFINDEX. * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC * or, if no MAC address given, all stations, on the interface identified - * by %NL80211_ATTR_IFINDEX. + * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and + * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type + * of disconnection indication should be sent to the station + * (Deauthentication or Disassociation frame and reason code for that + * frame). * * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to * destination %NL80211_ATTR_MAC on the interface identified by diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 40cf7b937926..0c0f2045e1f8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4414,6 +4414,27 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_station) return -EOPNOTSUPP; + if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) { + params.subtype = + nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]); + if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 && + params.subtype != IEEE80211_STYPE_DEAUTH >> 4) + return -EINVAL; + } else { + /* Default to Deauthentication frame */ + params.subtype = IEEE80211_STYPE_DEAUTH >> 4; + } + + if (info->attrs[NL80211_ATTR_REASON_CODE]) { + params.reason_code = + nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); + if (params.reason_code == 0) + return -EINVAL; /* 0 is reserved */ + } else { + /* Default to reason code 2 */ + params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID; + } + return rdev_del_station(rdev, dev, ¶ms); } diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b1339400631d..cdb2c2ef1ae1 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -688,14 +688,20 @@ DECLARE_EVENT_CLASS(station_del, WIPHY_ENTRY NETDEV_ENTRY MAC_ENTRY(sta_mac) + __field(u8, subtype) + __field(u16, reason_code) ), TP_fast_assign( WIPHY_ASSIGN; NETDEV_ASSIGN; MAC_ASSIGN(sta_mac, params->mac); + __entry->subtype = params->subtype; + __entry->reason_code = params->reason_code; ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT + ", subtype: %u, reason_code: %u", + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), + __entry->subtype, __entry->reason_code) ); DEFINE_EVENT(station_del, rdev_del_station, -- GitLab From be93709cb13a1947fec3493267d04cd87baf497e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:06:04 +0200 Subject: [PATCH 0898/9457] ALSA: doc: Recommend the use of snd_ctl_elem_info() Instead of the open code for the info call back of enum elements, recommend the use of snd_ctl_elem_info(), which will reduce lots of codes. Signed-off-by: Takashi Iwai --- .../DocBook/writing-an-alsa-driver.tmpl | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index 784793df81ed..84ef6a90131c 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl @@ -3657,6 +3657,29 @@ struct _snd_pcm_runtime { + + The above callback can be simplified with a helper function, + snd_ctl_enum_info. The final code + looks like below. + (You can pass ARRAY_SIZE(texts) instead of 4 in the third + argument; it's a matter of taste.) + + + + + + + + Some common info callbacks are available for your convenience: snd_ctl_boolean_mono_info() and -- GitLab From 915f389d9c52c5a2d6946ffc252d68bfd6c5dfee Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Mon, 20 Oct 2014 11:59:43 -0400 Subject: [PATCH 0899/9457] audit: add Paul Moore to the MAINTAINERS entry After a long stint maintaining the audit tree, Eric asked me to step in and handle the day-to-day management of the audit tree. We should also update the linux-audit mailing list entry to better reflect current usage. Signed-off-by: Paul Moore Acked-by: Eric Paris --- MAINTAINERS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c2066f4c3286..86c24fd147d1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1689,10 +1689,11 @@ S: Supported F: drivers/scsi/esas2r AUDIT SUBSYSTEM +M: Paul Moore M: Eric Paris -L: linux-audit@redhat.com (subscribers-only) +L: linux-audit@redhat.com (moderated for non-subscribers) W: http://people.redhat.com/sgrubb/audit/ -T: git git://git.infradead.org/users/eparis/audit.git +T: git git://git.infradead.org/users/pcmoore/audit S: Maintained F: include/linux/audit.h F: include/uapi/linux/audit.h -- GitLab From df803e1389716bcdf11932fff47d7f1fc198bc8a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:07:21 +0200 Subject: [PATCH 0900/9457] ALSA: control: Warn if too long string is passed to snd_ctl_enum_info() This allows us to catch the bugs in drivers easily. Signed-off-by: Takashi Iwai --- sound/core/control.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/core/control.c b/sound/core/control.c index b9611344ff9e..f95df84437e1 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1747,6 +1747,9 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, info->value.enumerated.items = items; if (info->value.enumerated.item >= items) info->value.enumerated.item = items - 1; + WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), + "ALSA: too long item name '%s'\n", + names[info->value.enumerated.item]); strlcpy(info->value.enumerated.name, names[info->value.enumerated.item], sizeof(info->value.enumerated.name)); -- GitLab From a7e6fb99150ebb2852ebd0e7bad9ce37cc9a79dd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:08:50 +0200 Subject: [PATCH 0901/9457] ALSA: control: Allow to pass items zero to snd_ctl_enum_info() Although this is weird, some drivers want to allow empty control elements intentionally, e.g. the number of items may change depending on the firmware status. Let the function simply returning in such a case. Signed-off-by: Takashi Iwai --- sound/core/control.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/control.c b/sound/core/control.c index f95df84437e1..5c35bbaf881e 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1745,6 +1745,8 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; info->count = channels; info->value.enumerated.items = items; + if (!items) + return 0; if (info->value.enumerated.item >= items) info->value.enumerated.item = items - 1; WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), -- GitLab From b08cc24e0a24f8d67ba7d66dab43c40ed25a3f5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Oct 2014 21:36:04 +0200 Subject: [PATCH 0902/9457] mac80211: fix change flags variable signedness This showed up as a sparse warning (with higher verbosity) and is certainly correct - the change flags should be unsigned. It's not that important since high flag numbers aren't used and bitwise operations would still work. Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a1498416ad55..acebf2c5bb0c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3108,7 +3108,8 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel_switch ch_switch; struct ieee80211_chanctx_conf *conf; struct ieee80211_chanctx *chanctx; - int err, changed = 0; + u32 changed = 0; + int err; sdata_assert_lock(sdata); lockdep_assert_held(&local->mtx); -- GitLab From d4d141cae804a430054f4138fa177229114f203a Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:45:59 +0200 Subject: [PATCH 0903/9457] mac80211: minstrel_ht: Increase the range of handled rate indexes Since 5935839ad735 ("mac80211: improve minstrel_ht rate sorting by throughput & probability"), the rate indexes are manipulated via u8's and hence allow for a maximum of 256 mcs_group entries in minstrel_mcs_groups. ATM, minstrel_ht advertizes support up to 3HTSS@40MHz, consuming: 8(MCS_GROUP_RATES) * (3(SS)*2(GI)*2(BW)+1(CCK)), i.e. 104 entries. Support for 3VHTSS@80MHz will require: 10(MCS_GROUP_RATES) * (3(SS)*2(GI)*2(BW)+1(CCK)) + 10(MCS_GROUP_RATES) * (3(SS)*2(GI)*3(BW)), i.e. 130 + 180 entries. This change moves from u8s to u16s where necessary. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 16 ++++++++-------- net/mac80211/rc80211_minstrel_ht.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 17ef54a7a492..ccec718c29f9 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -240,8 +240,8 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) * MCS groups, CCK rates do not provide aggregation and are therefore at last. */ static void -minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, - u8 *tp_list) +minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index, + u16 *tp_list) { int cur_group, cur_idx, cur_thr, cur_prob; int tmp_group, tmp_idx, tmp_thr, tmp_prob; @@ -278,7 +278,7 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, * Find and set the topmost probability rate per sta and per group */ static void -minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) +minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index) { struct minstrel_mcs_group_data *mg; struct minstrel_rate_stats *mr; @@ -321,8 +321,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) */ static void minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, - u8 tmp_mcs_tp_rate[MAX_THR_RATES], - u8 tmp_cck_tp_rate[MAX_THR_RATES]) + u16 tmp_mcs_tp_rate[MAX_THR_RATES], + u16 tmp_cck_tp_rate[MAX_THR_RATES]) { unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; int i; @@ -386,8 +386,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) struct minstrel_mcs_group_data *mg; struct minstrel_rate_stats *mr; int group, i, j; - u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; - u8 tmp_cck_tp_rate[MAX_THR_RATES], index; + u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; if (mi->ampdu_packets > 0) { mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, @@ -517,7 +517,7 @@ minstrel_next_sample_idx(struct minstrel_ht_sta *mi) } static void -minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) +minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) { int group, orig_group; diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index 01570e0e014b..8b54e894b197 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -34,8 +34,8 @@ struct minstrel_mcs_group_data { u8 supported; /* sorted rate set within a MCS group*/ - u8 max_group_tp_rate[MAX_THR_RATES]; - u8 max_group_prob_rate; + u16 max_group_tp_rate[MAX_THR_RATES]; + u16 max_group_prob_rate; /* MCS rate statistics */ struct minstrel_rate_stats rates[MCS_GROUP_RATES]; @@ -52,8 +52,8 @@ struct minstrel_ht_sta { unsigned int avg_ampdu_len; /* overall sorted rate set */ - u8 max_tp_rate[MAX_THR_RATES]; - u8 max_prob_rate; + u16 max_tp_rate[MAX_THR_RATES]; + u16 max_prob_rate; /* time of last status update */ unsigned long stats_update; -- GitLab From 8a0ee4fe1951af252b1ac7b5c6af4083bafc4c7e Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:46:00 +0200 Subject: [PATCH 0904/9457] mac80211: minstrel_ht: macros adjustments for future VHT_GROUPs No functional change. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 51 +++++++++++----------- net/mac80211/rc80211_minstrel_ht.h | 15 +++++-- net/mac80211/rc80211_minstrel_ht_debugfs.c | 10 ++--- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index ccec718c29f9..a48eb76440c6 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -34,12 +34,16 @@ /* Transmit duration for the raw data part of an average sized packet */ #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) +#define BW_20 0 +#define BW_40 1 + /* * Define group sort order: HT40 -> SGI -> #streams */ #define GROUP_IDX(_streams, _sgi, _ht40) \ + MINSTREL_HT_GROUP_0 + \ MINSTREL_MAX_STREAMS * 2 * _ht40 + \ - MINSTREL_MAX_STREAMS * _sgi + \ + MINSTREL_MAX_STREAMS * _sgi + \ _streams - 1 /* MCS rate information for an MCS group */ @@ -76,13 +80,13 @@ CCK_ACK_DURATION(55, _short), \ CCK_ACK_DURATION(110, _short) -#define CCK_GROUP \ - [MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS] = { \ - .streams = 0, \ - .duration = { \ - CCK_DURATION_LIST(false), \ - CCK_DURATION_LIST(true) \ - } \ +#define CCK_GROUP \ + [MINSTREL_CCK_GROUP] = { \ + .streams = 0, \ + .duration = { \ + CCK_DURATION_LIST(false), \ + CCK_DURATION_LIST(true) \ + } \ } /* @@ -91,38 +95,36 @@ * use. * * Sortorder has to be fixed for GROUP_IDX macro to be applicable: - * HT40 -> SGI -> #streams + * BW -> SGI -> #streams */ const struct mcs_group minstrel_mcs_groups[] = { - MCS_GROUP(1, 0, 0), - MCS_GROUP(2, 0, 0), + MCS_GROUP(1, 0, BW_20), + MCS_GROUP(2, 0, BW_20), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, 0), + MCS_GROUP(3, 0, BW_20), #endif - MCS_GROUP(1, 1, 0), - MCS_GROUP(2, 1, 0), + MCS_GROUP(1, 1, BW_20), + MCS_GROUP(2, 1, BW_20), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, 0), + MCS_GROUP(3, 1, BW_20), #endif - MCS_GROUP(1, 0, 1), - MCS_GROUP(2, 0, 1), + MCS_GROUP(1, 0, BW_40), + MCS_GROUP(2, 0, BW_40), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 0, 1), + MCS_GROUP(3, 0, BW_40), #endif - MCS_GROUP(1, 1, 1), - MCS_GROUP(2, 1, 1), + MCS_GROUP(1, 1, BW_40), + MCS_GROUP(2, 1, BW_40), #if MINSTREL_MAX_STREAMS >= 3 - MCS_GROUP(3, 1, 1), + MCS_GROUP(3, 1, BW_40), #endif - /* must be last */ CCK_GROUP }; -#define MINSTREL_CCK_GROUP (ARRAY_SIZE(minstrel_mcs_groups) - 1) static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; @@ -971,8 +973,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, if (!sta->ht_cap.ht_supported) goto use_legacy; - BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != - MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); msp->is_ht = true; memset(mi, 0, sizeof(*mi)); diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index 8b54e894b197..e747ac668afe 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -13,8 +13,17 @@ * The number of streams can be changed to 2 to reduce code * size and memory footprint. */ -#define MINSTREL_MAX_STREAMS 3 -#define MINSTREL_STREAM_GROUPS 4 +#define MINSTREL_MAX_STREAMS 3 +#define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ + +#define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_HT_STREAM_GROUPS) +#define MINSTREL_CCK_GROUPS_NB 1 +#define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ + MINSTREL_CCK_GROUPS_NB) + +#define MINSTREL_HT_GROUP_0 0 +#define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) #define MCS_GROUP_RATES 8 @@ -80,7 +89,7 @@ struct minstrel_ht_sta { u8 cck_supported_short; /* MCS rate group info and statistics */ - struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; + struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; }; struct minstrel_ht_sta_priv { diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index d537bec93754..d2f53b867660 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -18,7 +18,6 @@ static char * minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) { - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; const struct mcs_group *mg; unsigned int j, tp, prob, eprob; char htmode = '2'; @@ -41,7 +40,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (!(mi->groups[i].supported & BIT(j))) continue; - if (i == max_mcs) + if (i == MINSTREL_CCK_GROUP) p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); else p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); @@ -52,7 +51,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; - if (i == max_mcs) { + if (i == MINSTREL_CCK_GROUP) { int r = bitrates[j % 4]; p += sprintf(p, " %2u.%1uM", r / 10, r % 10); } else { @@ -85,7 +84,6 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_debugfs_info *ms; unsigned int i; - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; char *p; int ret; @@ -106,8 +104,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) "ret *ok(*cum) ok( cum)\n"); - p = minstrel_ht_stats_dump(mi, max_mcs, p); - for (i = 0; i < max_mcs; i++) + p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); + for (i = 0; i < MINSTREL_CCK_GROUP; i++) p = minstrel_ht_stats_dump(mi, i, p); p += sprintf(p, "\nTotal packet count:: ideal %d " -- GitLab From 3ec373c421b6efc41b84b20265b4381beb1d7908 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Mon, 20 Oct 2014 15:46:01 +0200 Subject: [PATCH 0905/9457] mac80211: minstrel_ht: include type (cck/ht) in rates flag ATM, we grep cck rates idx with idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP. Matching neither-cck-non-ht rates could be done by replacing '==' with '>', however it would be less versatile or explicit. This will allow to match VHT rates with IEEE80211_TX_RC_VHT_MCS. Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index a48eb76440c6..e760d3d71fe1 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -51,6 +51,7 @@ [GROUP_IDX(_streams, _sgi, _ht40)] = { \ .streams = _streams, \ .flags = \ + IEEE80211_TX_RC_MCS | \ (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ .duration = { \ @@ -83,6 +84,7 @@ #define CCK_GROUP \ [MINSTREL_CCK_GROUP] = { \ .streams = 0, \ + .flags = 0, \ .duration = { \ CCK_DURATION_LIST(false), \ CCK_DURATION_LIST(true) \ @@ -716,7 +718,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; struct minstrel_rate_stats *mr; u8 idx; - u16 flags; + u16 flags = group->flags; mr = minstrel_get_ratestats(mi, index); if (!mr->retry_updated) @@ -732,13 +734,10 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; } - if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { + if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; - flags = 0; - } else { + else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; - flags = IEEE80211_TX_RC_MCS | group->flags; - } if (offset > 0) { ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; @@ -918,13 +917,12 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); rate->idx = mp->cck_rates[idx]; - rate->flags = 0; - return; + } else { + rate->idx = sample_idx % MCS_GROUP_RATES + + (sample_group->streams - 1) * 8; } - rate->idx = sample_idx % MCS_GROUP_RATES + - (sample_group->streams - 1) * 8; - rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; + rate->flags = sample_group->flags; } static void @@ -1006,14 +1004,16 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, mi->tx_flags |= IEEE80211_TX_CTL_LDPC; for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + mi->groups[i].supported = 0; if (i == MINSTREL_CCK_GROUP) { minstrel_ht_update_cck(mp, mi, sband, sta); continue; } - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) continue; } else { @@ -1022,7 +1022,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, } } - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH && + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH && sta->bandwidth < IEEE80211_STA_RX_BW_40) continue; -- GitLab From 04eeb606a8383b306f4bc6991da8231b5f3924b0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:10:39 +0200 Subject: [PATCH 0906/9457] ALSA: aoa: Use snd_ctl_elem_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/aoa/codecs/onyx.c | 8 +------- sound/aoa/codecs/tas.c | 10 ++-------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 401107b85d30..23c371ecfb6b 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -243,13 +243,7 @@ static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol, { static const char * const texts[] = { "Line-In", "Microphone" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol, diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index cf3c6303b7e3..364c7c4416e8 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -478,15 +478,9 @@ static struct snd_kcontrol_new drc_switch_control = { static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "Line-In", "Microphone" }; + static const char * const texts[] = { "Line-In", "Microphone" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol, -- GitLab From 6d416f594bf9a290406d267e2627c5286f51ea59 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:11:28 +0200 Subject: [PATCH 0907/9457] ALSA: mts64: Use snd_ctl_elem_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/drivers/mts64.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index f5fd448dbc57..0388fbbd2c06 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -604,21 +604,11 @@ static struct snd_kcontrol_new mts64_ctl_smpte_time_frames = { static int snd_mts64_ctl_smpte_fps_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { - static char *texts[5] = { "24", - "25", - "29.97", - "30D", - "30" }; + static const char * const texts[5] = { + "24", "25", "29.97", "30D", "30" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } static int snd_mts64_ctl_smpte_fps_get(struct snd_kcontrol *kctl, -- GitLab From 7f471fd40742a5d87d887375430bf40331cbbcf6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:11:58 +0200 Subject: [PATCH 0908/9457] ALSA: vx: Use snd_ctl_elem_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/drivers/vx/vx_mixer.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index 3b6823fc0606..be9477e30739 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c @@ -471,30 +471,18 @@ static struct snd_kcontrol_new vx_control_output_level = { */ static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts_mic[3] = { + static const char * const texts_mic[3] = { "Digital", "Line", "Mic" }; - static char *texts_vx2[2] = { + static const char * const texts_vx2[2] = { "Digital", "Analog" }; struct vx_core *chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - if (chip->type >= VX_TYPE_VXPOCKET) { - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, - texts_mic[uinfo->value.enumerated.item]); - } else { - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - texts_vx2[uinfo->value.enumerated.item]); - } - return 0; + if (chip->type >= VX_TYPE_VXPOCKET) + return snd_ctl_enum_info(uinfo, 1, 3, texts_mic); + else + return snd_ctl_enum_info(uinfo, 1, 2, texts_vx2); } static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -539,18 +527,11 @@ static struct snd_kcontrol_new vx_control_audio_src = { */ static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { + static const char * const texts[3] = { "Auto", "Internal", "External" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From e7ced4137d859c576130ce7605e5fdd13221793d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Oct 2014 08:26:10 +0200 Subject: [PATCH 0909/9457] ALSA: bebob: More constify text arrays Signed-off-by: Takashi Iwai --- sound/firewire/bebob/bebob.h | 4 ++-- sound/firewire/bebob/bebob_focusrite.c | 10 +++++----- sound/firewire/bebob/bebob_maudio.c | 18 +++++++++--------- sound/firewire/bebob/bebob_terratec.c | 4 ++-- sound/firewire/bebob/bebob_yamaha.c | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index e13eef99c27a..dfbcd233178c 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h @@ -52,7 +52,7 @@ extern const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES]; #define SND_BEBOB_CLOCK_INTERNAL "Internal" struct snd_bebob_clock_spec { unsigned int num; - char *const *labels; + const char *const *labels; int (*get)(struct snd_bebob *bebob, unsigned int *id); }; struct snd_bebob_rate_spec { @@ -61,7 +61,7 @@ struct snd_bebob_rate_spec { }; struct snd_bebob_meter_spec { unsigned int num; - char *const *labels; + const char *const *labels; int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size); }; struct snd_bebob_spec { diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c index 45a0eed6d5b1..a45a86952a41 100644 --- a/sound/firewire/bebob/bebob_focusrite.c +++ b/sound/firewire/bebob/bebob_focusrite.c @@ -101,11 +101,11 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) &data, sizeof(__be32), 0); } -static char *const saffirepro_26_clk_src_labels[] = { +static const char *const saffirepro_26_clk_src_labels[] = { SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" }; -static char *const saffirepro_10_clk_src_labels[] = { +static const char *const saffirepro_10_clk_src_labels[] = { SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" }; static int @@ -161,7 +161,7 @@ saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) } struct snd_bebob_spec saffire_le_spec; -static char *const saffire_both_clk_src_labels[] = { +static const char *const saffire_both_clk_src_labels[] = { SND_BEBOB_CLOCK_INTERNAL, "S/PDIF" }; static int @@ -176,12 +176,12 @@ saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) return err; }; -static char *const saffire_le_meter_labels[] = { +static const char *const saffire_le_meter_labels[] = { ANA_IN, ANA_IN, DIG_IN, ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, STM_IN, STM_IN }; -static char *const saffire_meter_labels[] = { +static const char *const saffire_meter_labels[] = { ANA_IN, ANA_IN, STM_IN, STM_IN, STM_IN, STM_IN, STM_IN, }; diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index 70faa3a32526..34cba8037b36 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c @@ -340,7 +340,7 @@ static int special_set_rate(struct snd_bebob *bebob, unsigned int rate) } /* Clock source control for special firmware */ -static char *const special_clk_labels[] = { +static const char *const special_clk_labels[] = { SND_BEBOB_CLOCK_INTERNAL " with Digital Mute", "Digital", "Word Clock", SND_BEBOB_CLOCK_INTERNAL}; static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) @@ -438,7 +438,7 @@ static struct snd_kcontrol_new special_sync_ctl = { }; /* Digital input interface control for special firmware */ -static char *const special_dig_in_iface_labels[] = { +static const char *const special_dig_in_iface_labels[] = { "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical" }; static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, @@ -539,7 +539,7 @@ static struct snd_kcontrol_new special_dig_in_iface_ctl = { }; /* Digital output interface control for special firmware */ -static char *const special_dig_out_iface_labels[] = { +static const char *const special_dig_out_iface_labels[] = { "S/PDIF Optical and Coaxial", "ADAT Optical" }; static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, @@ -631,7 +631,7 @@ static int add_special_controls(struct snd_bebob *bebob) } /* Hardware metering for special firmware */ -static char *const special_meter_labels[] = { +static const char *const special_meter_labels[] = { ANA_IN, ANA_IN, ANA_IN, ANA_IN, SPDIF_IN, ADAT_IN, ADAT_IN, ADAT_IN, ADAT_IN, @@ -671,30 +671,30 @@ special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size) } /* last 4 bytes are omitted because it's clock info. */ -static char *const fw410_meter_labels[] = { +static const char *const fw410_meter_labels[] = { ANA_IN, DIG_IN, ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, DIG_OUT, HP_OUT }; -static char *const audiophile_meter_labels[] = { +static const char *const audiophile_meter_labels[] = { ANA_IN, DIG_IN, ANA_OUT, ANA_OUT, DIG_OUT, HP_OUT, AUX_OUT, }; -static char *const solo_meter_labels[] = { +static const char *const solo_meter_labels[] = { ANA_IN, DIG_IN, STRM_IN, STRM_IN, ANA_OUT, DIG_OUT }; /* no clock info */ -static char *const ozonic_meter_labels[] = { +static const char *const ozonic_meter_labels[] = { ANA_IN, ANA_IN, STRM_IN, STRM_IN, ANA_OUT, ANA_OUT }; /* TODO: need testers. these positions are based on authour's assumption */ -static char *const nrv10_meter_labels[] = { +static const char *const nrv10_meter_labels[] = { ANA_IN, ANA_IN, ANA_IN, ANA_IN, DIG_IN, ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index 0e4c0bfc463b..83b677224f1f 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c @@ -8,7 +8,7 @@ #include "./bebob.h" -static char *const phase88_rack_clk_src_labels[] = { +static const char *const phase88_rack_clk_src_labels[] = { SND_BEBOB_CLOCK_INTERNAL, "Digital In", "Word Clock" }; static int @@ -29,7 +29,7 @@ phase88_rack_clk_src_get(struct snd_bebob *bebob, unsigned int *id) return err; } -static char *const phase24_series_clk_src_labels[] = { +static const char *const phase24_series_clk_src_labels[] = { SND_BEBOB_CLOCK_INTERNAL, "Digital In" }; static int diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha.c index 9b7e798180ff..ef1fe3823a9c 100644 --- a/sound/firewire/bebob/bebob_yamaha.c +++ b/sound/firewire/bebob/bebob_yamaha.c @@ -28,7 +28,7 @@ * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. */ -static char *const clk_src_labels[] = {SND_BEBOB_CLOCK_INTERNAL, "SPDIF"}; +static const char *const clk_src_labels[] = {SND_BEBOB_CLOCK_INTERNAL, "SPDIF"}; static int clk_src_get(struct snd_bebob *bebob, unsigned int *id) { -- GitLab From 41be5164ea09c92d551e8007d2543418e40f847a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:12:26 +0200 Subject: [PATCH 0910/9457] ALSA: bebob: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/firewire/bebob/bebob_maudio.c | 41 ++++++----------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index 34cba8037b36..a422aaa3bb0c 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c @@ -352,17 +352,8 @@ static int special_clk_get(struct snd_bebob *bebob, unsigned int *id) static int special_clk_ctl_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *einf) { - einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - einf->count = 1; - einf->value.enumerated.items = ARRAY_SIZE(special_clk_labels); - - if (einf->value.enumerated.item >= einf->value.enumerated.items) - einf->value.enumerated.item = einf->value.enumerated.items - 1; - - strcpy(einf->value.enumerated.name, - special_clk_labels[einf->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(einf, 1, ARRAY_SIZE(special_clk_labels), + special_clk_labels); } static int special_clk_ctl_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uval) @@ -444,17 +435,9 @@ static const char *const special_dig_in_iface_labels[] = { static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *einf) { - einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - einf->count = 1; - einf->value.enumerated.items = ARRAY_SIZE(special_dig_in_iface_labels); - - if (einf->value.enumerated.item >= einf->value.enumerated.items) - einf->value.enumerated.item = einf->value.enumerated.items - 1; - - strcpy(einf->value.enumerated.name, - special_dig_in_iface_labels[einf->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(einf, 1, + ARRAY_SIZE(special_dig_in_iface_labels), + special_dig_in_iface_labels); } static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uval) @@ -545,17 +528,9 @@ static const char *const special_dig_out_iface_labels[] = { static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *einf) { - einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - einf->count = 1; - einf->value.enumerated.items = ARRAY_SIZE(special_dig_out_iface_labels); - - if (einf->value.enumerated.item >= einf->value.enumerated.items) - einf->value.enumerated.item = einf->value.enumerated.items - 1; - - strcpy(einf->value.enumerated.name, - special_dig_out_iface_labels[einf->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(einf, 1, + ARRAY_SIZE(special_dig_out_iface_labels), + special_dig_out_iface_labels); } static int special_dig_out_iface_ctl_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uval) -- GitLab From 609e478b40aceaa07d14f1bada02a3874bac2c45 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:13:01 +0200 Subject: [PATCH 0911/9457] ALSA: ak4xxx-adda: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/i2c/other/ak4xxx-adda.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index f3735e64791c..67dbfde837ab 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c @@ -465,17 +465,10 @@ static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { + static const char * const texts[4] = { "44.1kHz", "Off", "48kHz", "32kHz", }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= 4) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, @@ -570,22 +563,13 @@ static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol, { struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int mixer_ch = AK_GET_SHIFT(kcontrol->private_value); - const char **input_names; - unsigned int num_names, idx; + unsigned int num_names; num_names = ak4xxx_capture_num_inputs(ak, mixer_ch); if (!num_names) return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = num_names; - idx = uinfo->value.enumerated.item; - if (idx >= num_names) - return -EINVAL; - input_names = ak->adc_info[mixer_ch].input_names; - strlcpy(uinfo->value.enumerated.name, input_names[idx], - sizeof(uinfo->value.enumerated.name)); - return 0; + return snd_ctl_enum_info(uinfo, 1, num_names, + ak->adc_info[mixer_ch].input_names); } static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol, -- GitLab From 1da0c47779840d038583ea6fa4e3497939d6ea21 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:13:39 +0200 Subject: [PATCH 0912/9457] ALSA: ad1816a: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/isa/ad1816a/ad1816a_lib.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index f0fd98e695e3..01a07986f4a3 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -731,18 +731,12 @@ int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[8] = { + static const char * const texts[8] = { "Line", "Mix", "CD", "Synth", "Video", "Mic", "Phone", }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 7; - if (uinfo->value.enumerated.item > 6) - uinfo->value.enumerated.item = 6; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 2, 7, texts); } static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 69b0c762cfd4c5e86a5b1fc0074889881b859c4a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:14:07 +0200 Subject: [PATCH 0913/9457] ALSA: es1688: Use snd_ctl_enum_info() ... and reduce the open codes. Also correct the array size and add missing const. Signed-off-by: Takashi Iwai --- sound/isa/es1688/es1688_lib.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index b3b4f15e45ba..de810e484bdf 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -762,18 +762,12 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[9] = { + static const char * const texts[8] = { "Mic", "Mic Master", "CD", "AOUT", "Mic1", "Mix", "Line", "Master" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 8, texts); } static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 4e28350a8c54a8b873b610311eb384a619c4045b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:14:24 +0200 Subject: [PATCH 0914/9457] ALSA: es18xx: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/isa/es18xx.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 6faaac60161a..63e7323e218f 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -964,44 +964,28 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream) static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts5Source[5] = { + static const char * const texts5Source[5] = { "Mic", "CD", "Line", "Master", "Mix" }; - static char *texts8Source[8] = { + static const char * const texts8Source[8] = { "Mic", "Mic Master", "CD", "AOUT", "Mic1", "Mix", "Line", "Master" }; struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; switch (chip->version) { case 0x1868: case 0x1878: - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts5Source[uinfo->value.enumerated.item]); - break; + return snd_ctl_enum_info(uinfo, 1, 4, texts5Source); case 0x1887: case 0x1888: - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]); - break; + return snd_ctl_enum_info(uinfo, 1, 5, texts5Source); case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */ case 0x1879: - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]); - break; + return snd_ctl_enum_info(uinfo, 1, 8, texts8Source); default: return -EINVAL; } - return 0; } static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 8edd2d120b6821d6eba9fedd0b17b7a47fbe9181 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:14:41 +0200 Subject: [PATCH 0915/9457] ALSA: msnd: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/isa/msnd/msnd_pinnacle_mixer.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c index 031dc69b7470..17e49a071af4 100644 --- a/sound/isa/msnd/msnd_pinnacle_mixer.c +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c @@ -55,20 +55,13 @@ static int snd_msndmix_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { + static const char * const texts[3] = { "Analog", "MASS", "SPDIF", }; struct snd_msnd *chip = snd_kcontrol_chip(kcontrol); unsigned items = test_bit(F_HAVEDIGITAL, &chip->flags) ? 3 : 2; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = items; - if (uinfo->value.enumerated.item >= items) - uinfo->value.enumerated.item = items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, items, texts); } static int snd_msndmix_get_mux(struct snd_kcontrol *kcontrol, -- GitLab From 6b9e1288a506b4d10c48a67058532c52c5c46240 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:14:51 +0200 Subject: [PATCH 0916/9457] ALSA: sb16: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/isa/sb/sb16_main.c | 10 ++-------- sound/isa/sb/sb_mixer.c | 31 ++++++------------------------- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 0bbcd4714d28..72b10f4f3e70 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -702,17 +702,11 @@ static int snd_sb16_get_dma_mode(struct snd_sb *chip) static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { + static const char * const texts[3] = { "Auto", "Playback", "Capture" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 1ff78ec9f0ac..e403334a19ad 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c @@ -182,17 +182,11 @@ static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[5] = { + static const char * const texts[5] = { "CD", "Mic", "Line", "Synth", "Master" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -275,18 +269,11 @@ static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[3] = { + static const char * const texts[3] = { "L chan only", "R chan only", "L ch/2 + R ch/2" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol, @@ -335,17 +322,11 @@ static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol, static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[3] = { + static const char * const texts[3] = { "Mic", "CD", "Line" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } -- GitLab From 0773efa53260a57d6e3bc38469c216635700537e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:15:06 +0200 Subject: [PATCH 0917/9457] ALSA: wss: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/isa/wss/wss_lib.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 360b08b03e1d..347bb1bda110 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1993,25 +1993,20 @@ EXPORT_SYMBOL(snd_wss_timer); static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { + static const char * const texts[4] = { "Line", "Aux", "Mic", "Mix" }; - static char *opl3sa_texts[4] = { + static const char * const opl3sa_texts[4] = { "Line", "CD", "Mic", "Mix" }; - static char *gusmax_texts[4] = { + static const char * const gusmax_texts[4] = { "Line", "Synth", "Mic", "Mix" }; - char **ptexts = texts; + const char * const *ptexts = texts; struct snd_wss *chip = snd_kcontrol_chip(kcontrol); if (snd_BUG_ON(!chip->card)) return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; if (!strcmp(chip->card->driver, "GUS MAX")) ptexts = gusmax_texts; switch (chip->hardware) { @@ -2023,8 +2018,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol, ptexts = opl3sa_texts; break; } - strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 2, 4, ptexts); } static int snd_wss_get_mux(struct snd_kcontrol *kcontrol, -- GitLab From 2a2085ab198439c8f08be2f6b9b5cbc9e93877b7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:15:16 +0200 Subject: [PATCH 0918/9457] ALSA: mips: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/mips/sgio2audio.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 04bb06c03ec8..33b08fcc27a9 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -201,17 +201,10 @@ static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol, static int sgio2audio_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[3] = { + static const char * const texts[3] = { "Cam Mic", "Mic", "Line" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= 3) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int sgio2audio_source_get(struct snd_kcontrol *kcontrol, -- GitLab From 3c6a73cc6b6ccd9188b3405c744365c0874b9274 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:15:26 +0200 Subject: [PATCH 0919/9457] ALSA: parisc: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/parisc/harmony.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 4b20be79c1dd..29604a239c44 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -776,15 +776,9 @@ static int snd_harmony_captureroute_info(struct snd_kcontrol *kc, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "Line", "Mic" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + static const char * const texts[2] = { "Line", "Mic" }; + + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int -- GitLab From 3b7a00dc9e4277d6fcad68dd1db35f77264ede5f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:15:36 +0200 Subject: [PATCH 0920/9457] ALSA: ac97: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_codec.c | 10 +- sound/pci/ac97/ac97_patch.c | 176 +++++++++++------------------------- 2 files changed, 53 insertions(+), 133 deletions(-) diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 14ad54b7928c..5ee2f17c287c 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -463,14 +463,8 @@ static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, { struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = e->shift_l == e->shift_r ? 1 : 2; - uinfo->value.enumerated.items = e->mask; - - if (uinfo->value.enumerated.item > e->mask - 1) - uinfo->value.enumerated.item = e->mask - 1; - strcpy(uinfo->value.enumerated.name, e->texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, + e->mask, e->texts); } static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 991762215417..50f420d69a8a 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -81,22 +81,11 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi /* * shared line-in/mic controls */ -static int ac97_enum_text_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo, - const char **texts, unsigned int nums) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = nums; - if (uinfo->value.enumerated.item > nums - 1) - uinfo->value.enumerated.item = nums - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[] = { "Shared", "Independent" }; - return ac97_enum_text_info(kcontrol, uinfo, texts, 2); + static const char * const texts[] = { "Shared", "Independent" }; + + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -123,9 +112,9 @@ static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[] = { "2ch", "4ch", "6ch", "8ch" }; - return ac97_enum_text_info(kcontrol, uinfo, texts, - kcontrol->private_value); + static const char * const texts[] = { "2ch", "4ch", "6ch", "8ch" }; + + return snd_ctl_enum_info(uinfo, 1, kcontrol->private_value, texts); } static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -240,17 +229,11 @@ static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97) static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { + static const char * const texts[3] = { "Standard", "Small", "Smaller" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, @@ -293,15 +276,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker = static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "AC-Link", "A/D Converter" }; + static const char * const texts[2] = { "AC-Link", "A/D Converter" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, @@ -401,15 +378,9 @@ static int patch_yamaha_ymf743(struct snd_ac97 *ac97) There is also a bit to mute S/PDIF output in a vendor-specific register. */ static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" }; + static const char * const texts[3] = { "Disabled", "Pin 43", "Pin 48" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1103,16 +1074,11 @@ static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[5] = { "Input/Disabled", "Front Output", + static const char * const texts[5] = { + "Input/Disabled", "Front Output", "Rear Output", "Center/LFE Output", "Mixer Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1147,16 +1113,11 @@ static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, stru static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack", + static const char * const texts[7] = { + "Mic2 Jack", "Mic1 Jack", "Line In Jack", "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 7; - if (uinfo->value.enumerated.item > 6) - uinfo->value.enumerated.item = 6; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 7, texts); } static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1181,15 +1142,11 @@ static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struc static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { "None", "Front Jack", "Rear Jack" }; + static const char * const texts[3] = { + "None", "Front Jack", "Rear Jack" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1804,15 +1761,9 @@ static int patch_ad1886(struct snd_ac97 * ac97) static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "AC-Link", "A/D Converter" }; + static const char * const texts[2] = { "AC-Link", "A/D Converter" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1994,15 +1945,9 @@ static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"}; + static const char * const texts[3] = {"Off", "6 -> 4", "6 -> 2"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2153,16 +2098,11 @@ static int patch_ad1980(struct snd_ac97 * ac97) static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"}; + static const char * const texts[4] = { + "High-Z", "3.7 V", "2.25 V", "0 V" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol, @@ -2756,20 +2696,18 @@ static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = { static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" }; - static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" }; + static const char * const texts_655[3] = { + "PCM", "Analog In", "IEC958 In" + }; + static const char * const texts_658[4] = { + "PCM", "Analog1 In", "Analog2 In", "IEC958 In" + }; struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ac97->spec.dev_flags ? 4 : 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - ac97->spec.dev_flags ? - texts_658[uinfo->value.enumerated.item] : - texts_655[uinfo->value.enumerated.item]); - return 0; + if (ac97->spec.dev_flags) + return snd_ctl_enum_info(uinfo, 1, 4, texts_658); + else + return snd_ctl_enum_info(uinfo, 1, 3, texts_655); } static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3055,15 +2993,9 @@ static int patch_cm9738(struct snd_ac97 * ac97) static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "Analog", "Digital" }; + static const char * const texts[] = { "Analog", "Digital" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3235,15 +3167,9 @@ static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = { static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" }; + static const char * const texts[] = { "AC-Link", "ADC", "SPDIF-In" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -3552,11 +3478,12 @@ static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, * is SM51EN *AND* it's Bit14, not Bit15 so the table is very * counter-intuitive */ - static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", + static const char * const texts[] = {"LineIn Mic1", "LineIn Mic1 Mic3", "Surr LFE/C Mic3", "LineIn LFE/C Mic3", "LineIn Mic2", "LineIn Mic2 Mic1", "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; - return ac97_enum_text_info(kcontrol, uinfo, texts, 8); + + return snd_ctl_enum_info(uinfo, 1, 8, texts); } static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, @@ -3720,9 +3647,8 @@ static struct vt1618_uaj_item vt1618_uaj[3] = { static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - return ac97_enum_text_info(kcontrol, uinfo, - vt1618_uaj[kcontrol->private_value].items, - 4); + return snd_ctl_enum_info(uinfo, 1, 4, + vt1618_uaj[kcontrol->private_value].items); } /* All of the vt1618 Universal Audio Jack twiddlers are on @@ -3767,9 +3693,9 @@ static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol, static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *txt_aux[] = {"Aux In", "Back Surr Out"}; + static const char * const txt_aux[] = {"Aux In", "Back Surr Out"}; - return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2); + return snd_ctl_enum_info(uinfo, 1, 2, txt_aux); } static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol, -- GitLab From 1bc10bb68d348078af0eb8b64292ec542dcd7634 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Oct 2014 08:51:45 +0200 Subject: [PATCH 0921/9457] ALSA: ac97: Constify more text arrays Signed-off-by: Takashi Iwai --- sound/pci/ac97/ac97_patch.c | 22 ++++++++++++++-------- sound/pci/ac97/ac97_patch.h | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 50f420d69a8a..ceaac1c41906 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -33,7 +33,8 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, const char *name); static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, - const unsigned int *tlv, const char **slaves); + const unsigned int *tlv, + const char * const *slaves); /* * Chip specific initialization @@ -3196,7 +3197,9 @@ static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); } -static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" }; +static const char * const cm9761_dac_clock[] = { + "AC-Link", "SPDIF-In", "Both" +}; static const struct ac97_enum cm9761_dac_clock_enum = AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); @@ -3310,7 +3313,9 @@ static int patch_cm9761(struct snd_ac97 *ac97) #define AC97_CM9780_MULTI_CHAN 0x66 #define AC97_CM9780_SPDIF 0x6c -static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" }; +static const char * const cm9780_ch_select[] = { + "Front", "Side", "Center/LFE", "Rear" +}; static const struct ac97_enum cm9780_ch_select_enum = AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); static const struct snd_kcontrol_new cm9780_controls[] = { @@ -3356,7 +3361,7 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), }; -static const char *slave_vols_vt1616[] = { +static const char * const slave_vols_vt1616[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -3364,7 +3369,7 @@ static const char *slave_vols_vt1616[] = { NULL }; -static const char *slave_sws_vt1616[] = { +static const char * const slave_sws_vt1616[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -3385,10 +3390,11 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, /* create a virtual master control and add slaves */ static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, - const unsigned int *tlv, const char **slaves) + const unsigned int *tlv, + const char * const *slaves) { struct snd_kcontrol *kctl; - const char **s; + const char * const *s; int err; kctl = snd_ctl_make_virtual_master(name, tlv); @@ -3612,7 +3618,7 @@ static int patch_vt1617a(struct snd_ac97 * ac97) struct vt1618_uaj_item { unsigned short mask; unsigned short shift; - const char *items[4]; + const char * const items[4]; }; /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */ diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 47bf8dfe8276..d1ce151fe722 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -49,7 +49,7 @@ struct ac97_enum { unsigned char shift_l; unsigned char shift_r; unsigned short mask; - const char **texts; + const char * const *texts; }; #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ -- GitLab From 30d0ae425ab1c9bb0003c3798de78fbf30ddebdc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:15:50 +0200 Subject: [PATCH 0922/9457] ALSA: asihpi: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 46 +++++---------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 5017176bfaa1..ac66b3228a34 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -1625,18 +1625,7 @@ static const char * const asihpi_aesebu_format_names[] = { static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - asihpi_aesebu_format_names[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names); } static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, @@ -1863,22 +1852,7 @@ static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol, if (num_bands < 0) return num_bands; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = num_bands; - - if (num_bands > 0) { - if (uinfo->value.enumerated.item >= - uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - asihpi_tuner_band_names[ - tuner_bands[uinfo->value.enumerated.item]]); - - } - return 0; + return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names); } static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol, @@ -2253,7 +2227,7 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, u32 h_control = kcontrol->private_value; u16 mode; int i; - u16 mode_map[6]; + const char *mapped_names[6]; int valid_modes = 0; /* HPI channel mode values can be from 1 to 6 @@ -2262,24 +2236,14 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) if (!hpi_channel_mode_query_mode( h_control, i, &mode)) { - mode_map[valid_modes] = mode; + mapped_names[valid_modes] = mode_names[mode]; valid_modes++; } if (!valid_modes) return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = valid_modes; - - if (uinfo->value.enumerated.item >= valid_modes) - uinfo->value.enumerated.item = valid_modes - 1; - - strcpy(uinfo->value.enumerated.name, - mode_names[mode_map[uinfo->value.enumerated.item]]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names); } static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol, -- GitLab From 4d765e48c5edb2090b82e97680b2d1ddf6d18c31 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:16:01 +0200 Subject: [PATCH 0923/9457] ALSA: aw2: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/pci/aw2/aw2-alsa.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 3878cf5de9a4..e1cf01949fda 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -725,19 +725,10 @@ static int snd_aw2_new_pcm(struct aw2 *chip) static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { + static const char * const texts[2] = { "Analog", "Digital" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) { - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - } - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, -- GitLab From 9b311a0ad9ec0df9f010bcadd19193b1cee593f6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:16:13 +0200 Subject: [PATCH 0924/9457] ALSA: azt3328: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5a69e26cb2fb..fdbb9c05c77b 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1034,11 +1034,6 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, const char * const *p = NULL; snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1; - uinfo->value.enumerated.items = reg.enum_c; - if (uinfo->value.enumerated.item > reg.enum_c - 1U) - uinfo->value.enumerated.item = reg.enum_c - 1U; if (reg.reg == IDX_MIXER_ADVCTL2) { switch(reg.lchan_shift) { case 8: /* modem out sel */ @@ -1051,12 +1046,12 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, p = texts4; break; } - } else - if (reg.reg == IDX_MIXER_REC_SELECT) + } else if (reg.reg == IDX_MIXER_REC_SELECT) p = texts3; - strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, + (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1, + reg.enum_c, p); } static int -- GitLab From de95eae25a2744ba5f9bd3c862bb43a1b177ad58 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:16:26 +0200 Subject: [PATCH 0925/9457] ALSA: ca0106: Use snd_ctl_enum_info() ... and reduce the open codes. Also correct the array size and add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/ca0106/ca0106_mixer.c | 40 +++++++-------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 27de0de90018..68c0eb0a2807 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -185,17 +185,11 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol, static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[6] = { + static const char * const texts[6] = { "IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 6; - if (uinfo->value.enumerated.item > 5) - uinfo->value.enumerated.item = 5; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 6, texts); } static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol, @@ -228,17 +222,11 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol, static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[6] = { + static const char * const texts[4] = { "Phone", "Mic", "Line in", "Aux" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol, @@ -273,29 +261,17 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol, static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "Side out", "Line in" }; + static const char * const texts[2] = { "Side out", "Line in" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "Line in", "Mic in" }; + static const char * const texts[2] = { "Line in", "Mic in" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol, -- GitLab From c69a4f3046ee5a28ab09a1786a73d04bd6177445 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:16:38 +0200 Subject: [PATCH 0926/9457] ALSA: echoaudio: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/echoaudio/echoaudio.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 631aaa4046ad..d82321ff549b 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -1416,21 +1416,14 @@ static struct snd_kcontrol_new snd_echo_vmixer = { static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *names[4] = { + static const char * const names[4] = { "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", "S/PDIF Cdrom" }; struct echoaudio *chip; chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = chip->num_digital_modes; - uinfo->count = 1; - if (uinfo->value.enumerated.item >= chip->num_digital_modes) - uinfo->value.enumerated.item = chip->num_digital_modes - 1; - strcpy(uinfo->value.enumerated.name, names[ - chip->digital_mode_list[uinfo->value.enumerated.item]]); - return 0; + return snd_ctl_enum_info(uinfo, 1, chip->num_digital_modes, names); } static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, @@ -1509,16 +1502,9 @@ static struct snd_kcontrol_new snd_echo_digital_mode_switch = { static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *names[2] = {"Consumer", "Professional"}; + static const char * const names[2] = {"Consumer", "Professional"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = 2; - uinfo->count = 1; - if (uinfo->value.enumerated.item) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - names[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, names); } static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, @@ -1566,21 +1552,14 @@ static struct snd_kcontrol_new snd_echo_spdif_mode_switch = { static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *names[8] = { + static const char * const names[8] = { "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", "ESync96", "MTC" }; struct echoaudio *chip; chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = chip->num_clock_sources; - uinfo->count = 1; - if (uinfo->value.enumerated.item >= chip->num_clock_sources) - uinfo->value.enumerated.item = chip->num_clock_sources - 1; - strcpy(uinfo->value.enumerated.name, names[ - chip->clock_source_list[uinfo->value.enumerated.item]]); - return 0; + return snd_ctl_enum_info(uinfo, 1, chip->num_clock_sources, names); } static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, -- GitLab From e07db352ca679a8b915008195aeee5c790bee545 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 13 Oct 2014 09:40:47 +0300 Subject: [PATCH 0927/9457] ath10k: add back enum ath10k_bus Commit 3a0861fffd223 ("ath10k: remove ath10k_bus") removed enum ath10k_bus because it was not used for anything at the time. But now it's needed for for retrieving the right calibration data file so add it back. Only new addition is ath10k_bus_str(). Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 2 ++ drivers/net/wireless/ath/ath10k/core.h | 16 ++++++++++++++++ drivers/net/wireless/ath/ath10k/pci.c | 1 + 3 files changed, 19 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 37e31665628c..76f0db0654bb 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1084,6 +1084,7 @@ void ath10k_core_unregister(struct ath10k *ar) EXPORT_SYMBOL(ath10k_core_unregister); struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, + enum ath10k_bus bus, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; @@ -1100,6 +1101,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, ar->dev = dev; ar->hif.ops = hif_ops; + ar->hif.bus = bus; init_completion(&ar->scan.started); init_completion(&ar->scan.completed); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 1ac2f1466758..770b0bcc3e69 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -63,6 +63,20 @@ struct ath10k; +enum ath10k_bus { + ATH10K_BUS_PCI, +}; + +static inline const char *ath10k_bus_str(enum ath10k_bus bus) +{ + switch (bus) { + case ATH10K_BUS_PCI: + return "pci"; + } + + return "unknown"; +} + struct ath10k_skb_cb { dma_addr_t paddr; u8 vdev_id; @@ -423,6 +437,7 @@ struct ath10k { bool p2p; struct { + enum ath10k_bus bus; const struct ath10k_hif_ops *ops; } hif; @@ -577,6 +592,7 @@ struct ath10k { }; struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, + enum ath10k_bus bus, const struct ath10k_hif_ops *hif_ops); void ath10k_core_destroy(struct ath10k *ar); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 730bb18c3f45..86f734e74103 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2435,6 +2435,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, u32 chip_id; ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, + ATH10K_BUS_PCI, &ath10k_pci_hif_ops); if (!ar) { dev_err(&pdev->dev, "failed to allocate core\n"); -- GitLab From 830915597747013b18143d298922f7ea227d3769 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 13 Oct 2014 09:40:53 +0300 Subject: [PATCH 0928/9457] ath10k: refactor ath10k_init_download_firmware() This is preparation for being able to download calibration data from a file. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 76f0db0654bb..d0b67a7512cf 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -225,6 +225,12 @@ static int ath10k_download_and_run_otp(struct ath10k *ar) u32 result, address = ar->hw_params.patch_load_addr; int ret; + ret = ath10k_download_board_data(ar); + if (ret) { + ath10k_err(ar, "failed to download board data: %d\n", ret); + return ret; + } + /* OTP is optional */ if (!ar->otp_data || !ar->otp_len) { @@ -589,29 +595,16 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) return 0; } -static int ath10k_init_download_firmware(struct ath10k *ar, - enum ath10k_firmware_mode mode) +static int ath10k_download_cal_data(struct ath10k *ar) { int ret; - ret = ath10k_download_board_data(ar); - if (ret) { - ath10k_err(ar, "failed to download board data: %d\n", ret); - return ret; - } - ret = ath10k_download_and_run_otp(ar); if (ret) { ath10k_err(ar, "failed to run otp: %d\n", ret); return ret; } - ret = ath10k_download_fw(ar, mode); - if (ret) { - ath10k_err(ar, "failed to download firmware: %d\n", ret); - return ret; - } - return ret; } @@ -729,7 +722,11 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) goto err; } - status = ath10k_init_download_firmware(ar, mode); + status = ath10k_download_cal_data(ar); + if (status) + goto err; + + status = ath10k_download_fw(ar, mode); if (status) goto err; -- GitLab From 1541c66d3bb78c8a388025b074c75658c790b72f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:16:48 +0200 Subject: [PATCH 0929/9457] ALSA: emu10k1: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emumixer.c | 58 ++++++++---------------------------- sound/pci/emu10k1/p16v.c | 20 +++---------- 2 files changed, 17 insertions(+), 61 deletions(-) diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index c5ae2a24d8a5..1de33025669a 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -83,7 +83,7 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, * Items labels in enum mixer controls assigning source data to * each destination */ -static char *emu1010_src_texts[] = { +static const char * const emu1010_src_texts[] = { "Silence", "Dock Mic A", "Dock Mic B", @@ -141,7 +141,7 @@ static char *emu1010_src_texts[] = { /* 1616(m) cardbus */ -static char *emu1616_src_texts[] = { +static const char * const emu1616_src_texts[] = { "Silence", "Dock Mic A", "Dock Mic B", @@ -393,23 +393,11 @@ static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - char **items; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) { - uinfo->value.enumerated.items = 49; - items = emu1616_src_texts; - } else { - uinfo->value.enumerated.items = 53; - items = emu1010_src_texts; - } - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - items[uinfo->value.enumerated.item]); - return 0; + if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1616) + return snd_ctl_enum_info(uinfo, 1, 49, emu1616_src_texts); + else + return snd_ctl_enum_info(uinfo, 1, 53, emu1010_src_texts); } static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, @@ -699,19 +687,11 @@ static struct snd_kcontrol_new snd_emu1010_dac_pads[] = { static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { + static const char * const texts[4] = { "44100", "48000", "SPDIF", "ADAT" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; - - + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, @@ -830,21 +810,15 @@ static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { #if 0 - static char *texts[4] = { + static const char * const texts[4] = { "Unknown1", "Unknown2", "Mic", "Line" }; #endif - static char *texts[2] = { + static const char * const texts[2] = { "Mic", "Line" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol, @@ -997,15 +971,9 @@ static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] = { #if 0 static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"44100", "48000", "96000"}; + static const char * const texts[] = {"44100", "48000", "96000"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index a4fe7f0c9458..7ef3898a7806 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -757,18 +757,12 @@ static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol, static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[8] = { + static const char * const texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 8, texts); } static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol, @@ -805,15 +799,9 @@ static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol, static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { "0", "1", "2", "3", }; + static const char * const texts[4] = { "0", "1", "2", "3", }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol, -- GitLab From 6b6b295e8053dd5a005aaa089b5bed4b4a65c632 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:17:08 +0200 Subject: [PATCH 0930/9457] ALSA: es1938: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/pci/es1938.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 639962443ccc..0fc46eb4e251 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1045,18 +1045,12 @@ static int snd_es1938_new_pcm(struct es1938 *chip, int device) static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[8] = { + static const char * const texts[8] = { "Mic", "Mic Master", "CD", "AOUT", "Mic1", "Mix", "Line", "Master" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 8, texts); } static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol, -- GitLab From ca776a28ae10bb06807f23e807f0f459dab78318 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:17:17 +0200 Subject: [PATCH 0931/9457] ALSA: fm801: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c5038303a126..d167afffce5f 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -958,17 +958,11 @@ static int snd_fm801_put_double(struct snd_kcontrol *kcontrol, static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[5] = { + static const char * const texts[5] = { "AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item > 4) - uinfo->value.enumerated.item = 4; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol, -- GitLab From 3ff72219320f616489bf0d98ddac12899da4a9ce Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:17:28 +0200 Subject: [PATCH 0932/9457] ALSA: hda: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 15e0089492f7..259fbeaa37bd 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2927,16 +2927,8 @@ static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol, static const char * const texts[] = { "On", "Off", "Follow Master" }; - unsigned int index; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - index = uinfo->value.enumerated.item; - if (index >= 3) - index = 2; - strcpy(uinfo->value.enumerated.name, texts[index]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol, @@ -5195,14 +5187,7 @@ int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol, texts = texts_default; } - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = num_items; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info); -- GitLab From c4fa251f6f3ed00d59d0d8ee63bf346e6dd6b664 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:18:33 +0200 Subject: [PATCH 0933/9457] ALSA: ice1712: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/ice1712/ews.c | 16 ++-------------- sound/pci/ice1712/ice1712.c | 27 ++++----------------------- 2 files changed, 6 insertions(+), 37 deletions(-) diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 817a1bc50a60..5cb587cf360e 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -580,13 +580,7 @@ static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct s static const char * const texts[2] = { "+4dBu", "-10dBV", }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= 2) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -903,13 +897,7 @@ static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, st static const char * const texts[4] = { "Internal", "Front Input", "Rear Input", "Wave Table" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= 4) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 206ed2cbcef9..48a0c330da24 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -1839,13 +1839,7 @@ static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, "96000", /* 12: 7 */ "IEC958 Input", /* 13: -- */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 14; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 14, texts); } static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, @@ -1930,13 +1924,7 @@ static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcon "96000", /* 12: 7 */ /* "IEC958 Input", 13: -- */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 13; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 13, texts); } static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol, @@ -2057,15 +2045,8 @@ static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, "IEC958 In L", "IEC958 In R", /* 9-10 */ "Digital Mixer", /* 11 - optional */ }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = - snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + int num_items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol, -- GitLab From 597da2e4dfa04c8ee66b09fce931ab6825bc3e75 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:18:50 +0200 Subject: [PATCH 0934/9457] ALSA: ice1724: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/ice1712/aureon.c | 46 ++++++-------------------------- sound/pci/ice1712/ice1724.c | 8 +----- sound/pci/ice1712/maya44.c | 20 ++------------ sound/pci/ice1712/phase.c | 12 +-------- sound/pci/ice1712/pontis.c | 8 +----- sound/pci/ice1712/prodigy192.c | 18 ++----------- sound/pci/ice1712/prodigy_hifi.c | 11 ++------ sound/pci/ice1712/quartet.c | 27 +++---------------- sound/pci/ice1712/se.c | 9 +------ 9 files changed, 22 insertions(+), 137 deletions(-) diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 3b3cf4ac9060..c9411dfff5a4 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -205,13 +205,7 @@ static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, static const char * const texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol, @@ -1106,20 +1100,10 @@ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in }; struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]); - } else { - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - } - return 0; + if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) + return snd_ctl_enum_info(uinfo, 2, 8, universe_texts); + else + return snd_ctl_enum_info(uinfo, 2, 5, texts); } static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1167,16 +1151,10 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ "CD", "Coax" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) - strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]); + return snd_ctl_enum_info(uinfo, 1, 2, prodigy_texts); else - strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, aureon_texts); } static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1392,15 +1370,7 @@ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_ { static const char * const texts[2] = { "128x", "64x" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 08cb08ac85e6..f633e3bb4c43 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2049,13 +2049,7 @@ static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol, "IEC958 In L", "IEC958 In R", /* 3-4 */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } static inline int analog_route_shift(int idx) diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 63aa39f06f02..7de25c4807fd 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c @@ -359,15 +359,7 @@ static int maya_rec_src_info(struct snd_kcontrol *kcontrol, { static const char * const texts[] = { "Line", "Mic" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } static int maya_rec_src_get(struct snd_kcontrol *kcontrol, @@ -411,15 +403,7 @@ static int maya_pb_route_info(struct snd_kcontrol *kcontrol, "Input 1", "Input 2", "Input 3", "Input 4" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } static int maya_pb_route_shift(int idx) diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 0011e04f36a2..e9ca89c9174b 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -723,17 +723,7 @@ static int phase28_oversampling_info(struct snd_kcontrol *k, { static const char * const texts[2] = { "128x", "64x" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 5555eb4b2400..5101f40f6fbd 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -417,13 +417,7 @@ static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_inf "Optical", /* RXP1 */ "CD", /* RXP2 */ }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index f3b491aa3e22..1eb151aaa965 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -284,15 +284,7 @@ static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, { static const char * const texts[2] = { "Line In", "Mic" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } @@ -563,13 +555,7 @@ static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, { static const char * const texts[2] = { "Toslink", "Coax" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 2261d1e49150..2697402b5195 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -537,7 +537,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char* texts[32] = { + static const char * const texts[32] = { "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2, WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3, WM_AIN1 "+" WM_AIN2 "+" WM_AIN3, @@ -560,14 +560,7 @@ static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5 }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 32; - if (uinfo->value.enumerated.item > 31) - uinfo->value.enumerated.item = 31; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 32, texts); } static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index 2c2df4b74e01..d4caf9d05922 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -46,7 +46,7 @@ struct qtet_kcontrol_private { unsigned int bit; void (*set_register)(struct snd_ice1712 *ice, unsigned int val); unsigned int (*get_register)(struct snd_ice1712 *ice); - unsigned char * const texts[2]; + const char * const texts[2]; }; enum { @@ -554,17 +554,7 @@ static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol, { static const char * const texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(texts); - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol, @@ -706,17 +696,8 @@ static int qtet_enum_info(struct snd_kcontrol *kcontrol, { struct qtet_kcontrol_private private = qtet_privates[kcontrol->private_value]; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ARRAY_SIZE(private.texts); - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - private.texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(private.texts), + private.texts); } static int qtet_sw_get(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c index ffd894bb4507..1c5d5b22c7a0 100644 --- a/sound/pci/ice1712/se.c +++ b/sound/pci/ice1712/se.c @@ -452,14 +452,7 @@ static int se200pci_cont_enum_info(struct snd_kcontrol *kc, c = se200pci_get_enum_count(n); if (!c) return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = c; - if (uinfo->value.enumerated.item >= c) - uinfo->value.enumerated.item = c - 1; - strcpy(uinfo->value.enumerated.name, - se200pci_cont[n].member[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, c, se200pci_cont[n].member); } static int se200pci_cont_volume_get(struct snd_kcontrol *kc, -- GitLab From a58227ef69a74e624b06a4ff193d13e6f1a4b298 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 13 Oct 2014 09:40:59 +0300 Subject: [PATCH 0935/9457] ath10k: retrieve calibration data from file A frequent request have been to be able to provide calibration data from a file as some of the AP devices store the calibration data on an MTD partition. This patchset adds support for that and also makes it easier to add Device Tree support later on. The calibration data is found by using the id string provided by dev_name() using this format: cal--.bin With PCI the id string contains bus, slot and func values. For example for a PCI device in bus 2 slot 0, ath10k will try to retrieve a calibration data from a file: /lib/firmware/ath10k/cal-pci-0000:02:00.0.bin The calibration data sequence is: 1. Check with request_firmware() if there's a calibration file ("cal--.bin") on the filesystem for this device. If yes, use that. If not, goto 2 2. Check if otp.bin is able to successfully load the calibration data from OTP. If yes, use that. If not, goto 3. 4. Print an error message that no calibration data found and stop driver initialization for this device. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 86 ++++++++++++++++++++++--- drivers/net/wireless/ath/ath10k/core.h | 20 ++++++ drivers/net/wireless/ath/ath10k/debug.c | 5 +- drivers/net/wireless/ath/ath10k/hw.h | 4 +- 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index d0b67a7512cf..5c23d00f7d60 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -138,7 +138,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, return fw; } -static int ath10k_push_board_ext_data(struct ath10k *ar) +static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data, + size_t data_len) { u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; @@ -159,14 +160,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) if (board_ext_data_addr == 0) return 0; - if (ar->board_len != (board_data_size + board_ext_data_size)) { + if (data_len != (board_data_size + board_ext_data_size)) { ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n", - ar->board_len, board_data_size, board_ext_data_size); + data_len, board_data_size, board_ext_data_size); return -EINVAL; } ret = ath10k_bmi_write_memory(ar, board_ext_data_addr, - ar->board_data + board_data_size, + data + board_data_size, board_ext_data_size); if (ret) { ath10k_err(ar, "could not write board ext data (%d)\n", ret); @@ -184,13 +185,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) return 0; } -static int ath10k_download_board_data(struct ath10k *ar) +static int ath10k_download_board_data(struct ath10k *ar, const void *data, + size_t data_len) { u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 address; int ret; - ret = ath10k_push_board_ext_data(ar); + ret = ath10k_push_board_ext_data(ar, data, data_len); if (ret) { ath10k_err(ar, "could not push board ext data (%d)\n", ret); goto exit; @@ -202,9 +204,9 @@ static int ath10k_download_board_data(struct ath10k *ar) goto exit; } - ret = ath10k_bmi_write_memory(ar, address, ar->board_data, + ret = ath10k_bmi_write_memory(ar, address, data, min_t(u32, board_data_size, - ar->board_len)); + data_len)); if (ret) { ath10k_err(ar, "could not write board data (%d)\n", ret); goto exit; @@ -220,12 +222,34 @@ static int ath10k_download_board_data(struct ath10k *ar) return ret; } +static int ath10k_download_cal_file(struct ath10k *ar) +{ + int ret; + + if (!ar->cal_file) + return -ENOENT; + + if (IS_ERR(ar->cal_file)) + return PTR_ERR(ar->cal_file); + + ret = ath10k_download_board_data(ar, ar->cal_file->data, + ar->cal_file->size); + if (ret) { + ath10k_err(ar, "failed to download cal_file data: %d\n", ret); + return ret; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n"); + + return 0; +} + static int ath10k_download_and_run_otp(struct ath10k *ar) { u32 result, address = ar->hw_params.patch_load_addr; int ret; - ret = ath10k_download_board_data(ar); + ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len); if (ret) { ath10k_err(ar, "failed to download board data: %d\n", ret); return ret; @@ -314,6 +338,9 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar) if (ar->firmware && !IS_ERR(ar->firmware)) release_firmware(ar->firmware); + if (ar->cal_file && !IS_ERR(ar->cal_file)) + release_firmware(ar->cal_file); + ar->board = NULL; ar->board_data = NULL; ar->board_len = 0; @@ -325,6 +352,27 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar) ar->firmware = NULL; ar->firmware_data = NULL; ar->firmware_len = 0; + + ar->cal_file = NULL; +} + +static int ath10k_fetch_cal_file(struct ath10k *ar) +{ + char filename[100]; + + /* cal--.bin */ + scnprintf(filename, sizeof(filename), "cal-%s-%s.bin", + ath10k_bus_str(ar->hif.bus), dev_name(ar->dev)); + + ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename); + if (IS_ERR(ar->cal_file)) + /* calibration file is optional, don't print any warnings */ + return PTR_ERR(ar->cal_file); + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n", + ATH10K_FW_DIR, filename); + + return 0; } static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) @@ -568,6 +616,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) { int ret; + /* calibration file is optional, don't check for any errors */ + ath10k_fetch_cal_file(ar); + ar->fw_api = 3; ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); @@ -599,13 +650,28 @@ static int ath10k_download_cal_data(struct ath10k *ar) { int ret; + ret = ath10k_download_cal_file(ar); + if (ret == 0) { + ar->cal_mode = ATH10K_CAL_MODE_FILE; + goto done; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, + "boot did not find a calibration file, try OTP next: %d\n", + ret); + ret = ath10k_download_and_run_otp(ar); if (ret) { ath10k_err(ar, "failed to run otp: %d\n", ret); return ret; } - return ret; + ar->cal_mode = ATH10K_CAL_MODE_OTP; + +done: + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n", + ath10k_cal_mode_str(ar->cal_mode)); + return 0; } static int ath10k_init_uart(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 770b0bcc3e69..2c286e73dbf7 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -387,6 +387,23 @@ enum ath10k_dev_flags { ATH10K_FLAG_CORE_REGISTERED, }; +enum ath10k_cal_mode { + ATH10K_CAL_MODE_FILE, + ATH10K_CAL_MODE_OTP, +}; + +static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) +{ + switch (mode) { + case ATH10K_CAL_MODE_FILE: + return "file"; + case ATH10K_CAL_MODE_OTP: + return "otp"; + } + + return "unknown"; +} + enum ath10k_scan_state { ATH10K_SCAN_IDLE, ATH10K_SCAN_STARTING, @@ -473,7 +490,10 @@ struct ath10k { const void *firmware_data; size_t firmware_len; + const struct firmware *cal_file; + int fw_api; + enum ath10k_cal_mode cal_mode; struct { struct completion started; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 0d94febbb360..9147dd36dcdd 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -124,7 +124,7 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { - ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d\n", + ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n", ar->hw_params.name, ar->target_version, ar->chip_id, @@ -135,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar) ar->fw_version_major, ar->fw_version_minor, ar->fw_version_release, - ar->fw_version_build); + ar->fw_version_build, + ath10k_cal_mode_str(ar->cal_mode)); ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", config_enabled(CONFIG_ATH10K_DEBUG), config_enabled(CONFIG_ATH10K_DEBUGFS), diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 5dd6551801d5..ef09fe8cb4b2 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -20,13 +20,15 @@ #include "targaddrs.h" +#define ATH10K_FW_DIR "ath10k" + /* QCA988X 1.0 definitions (unsupported) */ #define QCA988X_HW_1_0_CHIP_ID_REV 0x0 /* QCA988X 2.0 definitions */ #define QCA988X_HW_2_0_VERSION 0x4100016c #define QCA988X_HW_2_0_CHIP_ID_REV 0x2 -#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" +#define QCA988X_HW_2_0_FW_DIR ATH10K_FW_DIR "/QCA988X/hw2.0" #define QCA988X_HW_2_0_FW_FILE "firmware.bin" #define QCA988X_HW_2_0_OTP_FILE "otp.bin" #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" -- GitLab From f861237c80a07449abd351c04a6ba397418dc0ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:21:58 +0200 Subject: [PATCH 0936/9457] ALSA: korg1212: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/korg1212/korg1212.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 9fe549b2efdf..59d21c9401d2 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -444,9 +444,9 @@ static char *stateName[] = { "Invalid" }; -static char *clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" }; +static const char * const clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" }; -static char *clockSourceName[] = { +static const char * const clockSourceName[] = { "ADAT at 44.1 kHz", "ADAT at 48 kHz", "S/PDIF at 44.1 kHz", @@ -455,7 +455,7 @@ static char *clockSourceName[] = { "local clock at 48 kHz" }; -static char *channelName[] = { +static const char * const channelName[] = { "ADAT-1", "ADAT-2", "ADAT-3", @@ -1844,14 +1844,9 @@ static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol, static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1; - uinfo->value.enumerated.items = kAudioChannels; - if (uinfo->value.enumerated.item > kAudioChannels-1) { - uinfo->value.enumerated.item = kAudioChannels-1; - } - strcpy(uinfo->value.enumerated.name, channelName[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, + (kcontrol->private_value >= 8) ? 2 : 1, + kAudioChannels, channelName); } static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol, @@ -1961,14 +1956,7 @@ static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol, static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) { - uinfo->value.enumerated.item = 2; - } - strcpy(uinfo->value.enumerated.name, clockSourceTypeName[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, clockSourceTypeName); } static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol, -- GitLab From 08455ace3cafd9b0b5c35db3d89c4388f6d3a6fe Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:00 +0200 Subject: [PATCH 0937/9457] ALSA: pcxhr: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr_mixer.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 95c9571780d8..63136c4f3f3d 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -660,14 +660,7 @@ static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, if (chip->mgr->board_has_mic) i = 5; /* Mic and MicroMix available */ } - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = i; - if (uinfo->value.enumerated.item > (i-1)) - uinfo->value.enumerated.item = i-1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, i, texts); } static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol, @@ -756,14 +749,7 @@ static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol, texts = textsPCXHR; snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1)); } - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = clock_items; - if (uinfo->value.enumerated.item >= clock_items) - uinfo->value.enumerated.item = clock_items-1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, clock_items, texts); } static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol, -- GitLab From 11c6ef7c8d439ef2bc3c95e5a4dcea449ab1f90f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:12 +0200 Subject: [PATCH 0938/9457] ALSA: rme32: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/rme32.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 4afd3cab775b..6c60dcd2e5a1 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -1608,30 +1608,24 @@ snd_rme32_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct rme32 *rme32 = snd_kcontrol_chip(kcontrol); - static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" }; + static const char * const texts[4] = { + "Optical", "Coaxial", "Internal", "XLR" + }; + int num_items; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; switch (rme32->pci->device) { case PCI_DEVICE_ID_RME_DIGI32: case PCI_DEVICE_ID_RME_DIGI32_8: - uinfo->value.enumerated.items = 3; + num_items = 3; break; case PCI_DEVICE_ID_RME_DIGI32_PRO: - uinfo->value.enumerated.items = 4; + num_items = 4; break; default: snd_BUG(); - break; - } - if (uinfo->value.enumerated.item > - uinfo->value.enumerated.items - 1) { - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; + return -EINVAL; } - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } static int snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol, @@ -1695,20 +1689,12 @@ static int snd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { "AutoSync", + static const char * const texts[4] = { "AutoSync", "Internal 32.0kHz", "Internal 44.1kHz", "Internal 48.0kHz" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) { - uinfo->value.enumerated.item = 3; - } - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol, -- GitLab From 9c30d46a0fb3b294faf1226025071d6e802a8c36 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:23 +0200 Subject: [PATCH 0939/9457] ALSA: rme96: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/rme96.c | 62 ++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 5a395c87c6fc..2f1a85185a16 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -1884,39 +1884,38 @@ snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele static int snd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" }; + static const char * const _texts[5] = { + "Optical", "Coaxial", "Internal", "XLR", "Analog" + }; struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] }; + const char *texts[5] = { + _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] + }; + int num_items; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; switch (rme96->pci->device) { case PCI_DEVICE_ID_RME_DIGI96: case PCI_DEVICE_ID_RME_DIGI96_8: - uinfo->value.enumerated.items = 3; + num_items = 3; break; case PCI_DEVICE_ID_RME_DIGI96_8_PRO: - uinfo->value.enumerated.items = 4; + num_items = 4; break; case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { /* PST */ - uinfo->value.enumerated.items = 4; + num_items = 4; texts[3] = _texts[4]; /* Analog instead of XLR */ } else { /* PAD */ - uinfo->value.enumerated.items = 5; + num_items = 5; } break; default: snd_BUG(); - break; - } - if (uinfo->value.enumerated.item > uinfo->value.enumerated.items - 1) { - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + return -EINVAL; } - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } static int snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2002,16 +2001,9 @@ snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el static int snd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { "AutoSync", "Internal", "Word" }; + static const char * const texts[3] = { "AutoSync", "Internal", "Word" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) { - uinfo->value.enumerated.item = 2; - } - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2041,16 +2033,11 @@ snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el static int snd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" }; + static const char * const texts[4] = { + "0 dB", "-6 dB", "-12 dB", "-18 dB" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) { - uinfo->value.enumerated.item = 3; - } - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2081,16 +2068,9 @@ snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ static int snd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" }; + static const char * const texts[4] = { "1+2", "3+4", "5+6", "7+8" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) { - uinfo->value.enumerated.item = 3; - } - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 8d678da9f0afbb951778369510c09b99de608c24 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:34 +0200 Subject: [PATCH 0940/9457] ALSA: hdsp: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 175 +++++++++++++-------------------------- 1 file changed, 57 insertions(+), 118 deletions(-) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 7646ba1664eb..2eb8baf7b828 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -1680,16 +1680,13 @@ static int hdsp_set_spdif_input(struct hdsp *hdsp, int in) static int snd_hdsp_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"}; + static const char * const texts[4] = { + "Optical", "Coaxial", "Internal", "AES" + }; struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3); - if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2)) - uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2); - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 4 : 3, + texts); } static int snd_hdsp_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1786,16 +1783,14 @@ static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol, static int snd_hdsp_info_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; + static const char * const texts[] = { + "32000", "44100", "48000", "64000", "88200", "96000", + "None", "128000", "176400", "192000" + }; struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, + texts); } static int snd_hdsp_get_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1872,14 +1867,13 @@ static int snd_hdsp_get_system_sample_rate(struct snd_kcontrol *kcontrol, struct static int snd_hdsp_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7 ; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char * const texts[] = { + "32000", "44100", "48000", "64000", "88200", "96000", + "None", "128000", "176400", "192000" + }; + + return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, + texts); } static int snd_hdsp_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1940,15 +1934,9 @@ static int hdsp_system_clock_mode(struct hdsp *hdsp) static int snd_hdsp_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"Master", "Slave" }; + static const char * const texts[] = {"Master", "Slave" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_hdsp_get_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2049,19 +2037,16 @@ static int hdsp_set_clock_source(struct hdsp *hdsp, int mode) static int snd_hdsp_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" }; + static const char * const texts[] = { + "AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", + "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", + "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", + "Internal 192.0 KHz" + }; struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - if (hdsp->io_type == H9632) - uinfo->value.enumerated.items = 10; - else - uinfo->value.enumerated.items = 7; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, (hdsp->io_type == H9632) ? 10 : 7, + texts); } static int snd_hdsp_get_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2165,15 +2150,9 @@ static int hdsp_set_da_gain(struct hdsp *hdsp, int mode) static int snd_hdsp_info_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"}; + static const char * const texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_hdsp_get_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2250,15 +2229,9 @@ static int hdsp_set_ad_gain(struct hdsp *hdsp, int mode) static int snd_hdsp_info_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"}; + static const char * const texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_hdsp_get_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2335,15 +2308,9 @@ static int hdsp_set_phone_gain(struct hdsp *hdsp, int mode) static int snd_hdsp_info_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"0 dB", "-6 dB", "-12 dB"}; + static const char * const texts[] = {"0 dB", "-6 dB", "-12 dB"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_hdsp_get_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2439,31 +2406,28 @@ static int hdsp_set_pref_sync_ref(struct hdsp *hdsp, int pref) static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" }; + static const char * const texts[] = { + "Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" + }; struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; + int num_items; switch (hdsp->io_type) { case Digiface: case H9652: - uinfo->value.enumerated.items = 6; + num_items = 6; break; case Multiface: - uinfo->value.enumerated.items = 4; + num_items = 4; break; case H9632: - uinfo->value.enumerated.items = 3; + num_items = 3; break; default: return -EINVAL; } - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, num_items, texts); } static int snd_hdsp_get_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2543,15 +2507,11 @@ static int hdsp_autosync_ref(struct hdsp *hdsp) static int snd_hdsp_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" }; + static const char * const texts[] = { + "Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 7; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 7, texts); } static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2738,14 +2698,9 @@ static int snd_hdsp_put_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem static int snd_hdsp_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"No Lock", "Lock", "Sync" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char * const texts[] = {"No Lock", "Lock", "Sync" }; + + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int hdsp_wc_sync_check(struct hdsp *hdsp) @@ -3101,15 +3056,11 @@ static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ct static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"}; + static const char * const texts[] = { + "Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 5, texts); } @@ -3234,15 +3185,9 @@ static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"On", "Off"}; + static const char * const texts[] = {"On", "Off"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } @@ -3291,15 +3236,9 @@ static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = {"On", "Off"}; + static const char * const texts[] = {"On", "Off"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { -- GitLab From c69a637b4df37fc5a011a89e422636ea393af5b0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:41 +0200 Subject: [PATCH 0941/9457] ALSA: hdspm: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 52d86af3ef2d..7f7277bfb66a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2645,18 +2645,7 @@ static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 9; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts_freq[uinfo->value.enumerated.item+1]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, 9, texts_freq + 1); } static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol, -- GitLab From 7298ece7a26753b073a9ce5f979a4942d3904d44 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:19:53 +0200 Subject: [PATCH 0942/9457] ALSA: rme9652: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/pci/rme9652/rme9652.c | 58 ++++++++++++------------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index fa9a2a8dce5a..6521521853b8 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -920,15 +920,9 @@ static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal) static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = {"ADAT1", "Internal"}; + static const char * const texts[2] = {"ADAT1", "Internal"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -991,15 +985,9 @@ static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in) static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = {"ADAT1", "Coaxial", "Internal"}; + static const char * const texts[3] = {"ADAT1", "Coaxial", "Internal"}; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1140,15 +1128,11 @@ static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode) static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = {"AutoSync", "Master", "Word Clock"}; + static const char * const texts[3] = { + "AutoSync", "Master", "Word Clock" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 3, texts); } static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1231,16 +1215,14 @@ static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref) static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"}; + static const char * const texts[4] = { + "IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In" + }; struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, + rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3, + texts); } static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1392,15 +1374,11 @@ static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = {"No Lock", "Lock", "No Lock Sync", "Lock Sync"}; + static const char * const texts[4] = { + "No Lock", "Lock", "No Lock Sync", "Lock Sync" + }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 4, texts); } static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 3e4bc5b78e5516585941c7888287ed50a5090bf4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:20:07 +0200 Subject: [PATCH 0943/9457] ALSA: sonicvibes: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/pci/sonicvibes.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 5b0d317cc9a6..313a7328bf9c 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -918,17 +918,11 @@ static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device, static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[7] = { + static const char * const texts[7] = { "CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 7; - if (uinfo->value.enumerated.item >= 7) - uinfo->value.enumerated.item = 6; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 2, 7, texts); } static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -- GitLab From 9883ab91e3ba5229bfe2d6e7f6ff497a2d03d4d2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:20:18 +0200 Subject: [PATCH 0944/9457] ALSA: via82xx: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/pci/via82xx.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index ecedf4dbfa2a..e088467fb736 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1610,16 +1610,10 @@ static int snd_via8233_capture_source_info(struct snd_kcontrol *kcontrol, /* formerly they were "Line" and "Mic", but it looks like that they * have nothing to do with the actual physical connections... */ - static char *texts[2] = { + static const char * const texts[2] = { "Input1", "Input2" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= 2) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_via8233_capture_source_get(struct snd_kcontrol *kcontrol, -- GitLab From 9502272163ace71d77d809937216fd669c02364b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:20:28 +0200 Subject: [PATCH 0945/9457] ALSA: ppc: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/ppc/tumbler.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index b9ffc17a4799..24c8766a925d 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -795,16 +795,11 @@ static int snapper_set_capture_source(struct pmac_tumbler *mix) static int snapper_info_capture_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { + static const char * const texts[2] = { "Line", "Mic" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snapper_get_capture_source(struct snd_kcontrol *kcontrol, -- GitLab From 5fe0b0e3ea1c8cb704677ef7e85345bb683f9182 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:21:15 +0200 Subject: [PATCH 0946/9457] ALSA: sparc: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to the text array. Signed-off-by: Takashi Iwai --- sound/sparc/cs4231.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 4e91bcaa3664..06606f9bbf78 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1285,19 +1285,11 @@ static int snd_cs4231_timer(struct snd_card *card) static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[4] = { + static const char * const texts[4] = { "Line", "CD", "Mic", "Mix" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 2; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 2, 4, texts); } static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, -- GitLab From c8dd33fc80cd344d28a1f6a7e1f0af1cf7a2ffd1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:21:27 +0200 Subject: [PATCH 0947/9457] ALSA: 6fire: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/usb/6fire/control.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index 184e3987ac24..54656eed6e2e 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c @@ -25,8 +25,8 @@ #include "comm.h" #include "chip.h" -static char *opt_coax_texts[2] = { "Optical", "Coax" }; -static char *line_phono_texts[2] = { "Line", "Phono" }; +static const char * const opt_coax_texts[2] = { "Optical", "Coax" }; +static const char * const line_phono_texts[2] = { "Line", "Phono" }; /* * data that needs to be sent to device. sets up card internal stuff. @@ -327,14 +327,7 @@ static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - line_phono_texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, line_phono_texts); } static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol, @@ -361,14 +354,7 @@ static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol, static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - opt_coax_texts[uinfo->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, opt_coax_texts); } static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol, -- GitLab From 7bbd03e0143b562ff7d96f7e71c016104020b550 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2014 18:21:42 +0200 Subject: [PATCH 0948/9457] ALSA: usb-audio: Use snd_ctl_enum_info() ... and reduce the open codes. Also add missing const to text arrays. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f119a41ed9a9..3980bf554c83 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -437,19 +437,9 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[2] = {"1/2", - "3/4" - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); + static const char * const texts[2] = {"1/2", "3/4"}; - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, @@ -735,25 +725,12 @@ struct snd_ftu_eff_switch_priv_val { static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char *texts[8] = {"Room 1", - "Room 2", - "Room 3", - "Hall 1", - "Hall 2", - "Plate", - "Delay", - "Echo" + static const char *const texts[8] = { + "Room 1", "Room 2", "Room 3", "Hall 1", + "Hall 2", "Plate", "Delay", "Echo" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, -- GitLab From 590922a824cd9c16b3f43c59e4defd411a3be5dc Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 21 Oct 2014 10:10:29 +0300 Subject: [PATCH 0949/9457] ath10k: clean up assoc code There's no need to pass bss_conf explicitly as it is accessible via vif pointer. This requires slight changes in function prototypes. While at it clean up listen interval workaround/command. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 94 +++++++++++++-------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b2bd80c4f72c..39c4029d9219 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1060,51 +1060,45 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) /* Station management */ /**********************/ +static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar, + struct ieee80211_vif *vif) +{ + /* Some firmware revisions have unstable STA powersave when listen + * interval is set too high (e.g. 5). The symptoms are firmware doesn't + * generate NullFunc frames properly even if buffered frames have been + * indicated in Beacon TIM. Firmware would seldom wake up to pull + * buffered frames. Often pinging the device from AP would simply fail. + * + * As a workaround set it to 1. + */ + if (vif->type == NL80211_IFTYPE_STATION) + return 1; + + return ar->hw->conf.listen_interval; +} + static void ath10k_peer_assoc_h_basic(struct ath10k *ar, - struct ath10k_vif *arvif, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_bss_conf *bss_conf, struct wmi_peer_assoc_complete_arg *arg) { + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + lockdep_assert_held(&ar->conf_mutex); ether_addr_copy(arg->addr, sta->addr); arg->vdev_id = arvif->vdev_id; arg->peer_aid = sta->aid; arg->peer_flags |= WMI_PEER_AUTH; - - if (arvif->vdev_type == WMI_VDEV_TYPE_STA) - /* - * Seems FW have problems with Power Save in STA - * mode when we setup this parameter to high (eg. 5). - * Often we see that FW don't send NULL (with clean P flags) - * frame even there is info about buffered frames in beacons. - * Sometimes we have to wait more than 10 seconds before FW - * will wakeup. Often sending one ping from AP to our device - * just fail (more than 50%). - * - * Seems setting this FW parameter to 1 couse FW - * will check every beacon and will wakup immediately - * after detection buffered data. - */ - arg->peer_listen_intval = 1; - else - arg->peer_listen_intval = ar->hw->conf.listen_interval; - + arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif); arg->peer_num_spatial_streams = 1; - - /* - * The assoc capabilities are available only in managed mode. - */ - if (arvif->vdev_type == WMI_VDEV_TYPE_STA && bss_conf) - arg->peer_caps = bss_conf->assoc_capability; + arg->peer_caps = vif->bss_conf.assoc_capability; } static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, - struct ath10k_vif *arvif, + struct ieee80211_vif *vif, struct wmi_peer_assoc_complete_arg *arg) { - struct ieee80211_vif *vif = arvif->vif; struct ieee80211_bss_conf *info = &vif->bss_conf; struct cfg80211_bss *bss; const u8 *rsnie = NULL; @@ -1361,11 +1355,12 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, } static void ath10k_peer_assoc_h_qos(struct ath10k *ar, - struct ath10k_vif *arvif, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_bss_conf *bss_conf, struct wmi_peer_assoc_complete_arg *arg) { + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + switch (arvif->vdev_type) { case WMI_VDEV_TYPE_AP: if (sta->wme) @@ -1377,7 +1372,7 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, } break; case WMI_VDEV_TYPE_STA: - if (bss_conf->qos) + if (vif->bss_conf.qos) arg->peer_flags |= WMI_PEER_QOS; break; default: @@ -1386,7 +1381,7 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, } static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, - struct ath10k_vif *arvif, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct wmi_peer_assoc_complete_arg *arg) { @@ -1437,22 +1432,21 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, } static int ath10k_peer_assoc_prepare(struct ath10k *ar, - struct ath10k_vif *arvif, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_bss_conf *bss_conf, struct wmi_peer_assoc_complete_arg *arg) { lockdep_assert_held(&ar->conf_mutex); memset(arg, 0, sizeof(*arg)); - ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, arg); - ath10k_peer_assoc_h_crypto(ar, arvif, arg); + ath10k_peer_assoc_h_basic(ar, vif, sta, arg); + ath10k_peer_assoc_h_crypto(ar, vif, arg); ath10k_peer_assoc_h_rates(ar, sta, arg); ath10k_peer_assoc_h_ht(ar, sta, arg); ath10k_peer_assoc_h_vht(ar, sta, arg); - ath10k_peer_assoc_h_qos(ar, arvif, sta, bss_conf, arg); - ath10k_peer_assoc_h_phymode(ar, arvif, sta, arg); + ath10k_peer_assoc_h_qos(ar, vif, sta, arg); + ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); return 0; } @@ -1512,8 +1506,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, * before calling ath10k_setup_peer_smps() which might sleep. */ ht_cap = ap_sta->ht_cap; - ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, - bss_conf, &peer_arg); + ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); if (ret) { ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n", bss_conf->bssid, arvif->vdev_id, ret); @@ -1596,15 +1589,18 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, arvif->is_up = false; } -static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, - struct ieee80211_sta *sta, bool reassoc) +static int ath10k_station_assoc(struct ath10k *ar, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + bool reassoc) { + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); struct wmi_peer_assoc_complete_arg peer_arg; int ret = 0; lockdep_assert_held(&ar->conf_mutex); - ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg); + ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg); if (ret) { ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n", sta->addr, arvif->vdev_id, ret); @@ -1653,9 +1649,11 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, return ret; } -static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif, +static int ath10k_station_disassoc(struct ath10k *ar, + struct ieee80211_vif *vif, struct ieee80211_sta *sta) { + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); int ret = 0; lockdep_assert_held(&ar->conf_mutex); @@ -3497,7 +3495,7 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", sta->addr); - err = ath10k_station_assoc(ar, arvif, sta, true); + err = ath10k_station_assoc(ar, arvif->vif, sta, true); if (err) ath10k_warn(ar, "failed to reassociate station: %pM\n", sta->addr); @@ -3583,7 +3581,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n", sta->addr); - ret = ath10k_station_assoc(ar, arvif, sta, false); + ret = ath10k_station_assoc(ar, vif, sta, false); if (ret) ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n", sta->addr, arvif->vdev_id, ret); @@ -3597,7 +3595,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n", sta->addr); - ret = ath10k_station_disassoc(ar, arvif, sta); + ret = ath10k_station_disassoc(ar, vif, sta); if (ret) ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n", sta->addr, arvif->vdev_id, ret); -- GitLab From b1ecde36adb0c488dd048aa267602803b65ccc9b Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 21 Oct 2014 10:10:29 +0300 Subject: [PATCH 0950/9457] ath10k: skip some commands on reassoc It doesn't make much sense to reconfigure peer completely upon reassociation. This will make it easier to have a more uniform association code across different modes. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 52 +++++++++++++++------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 39c4029d9219..d7a2d6f9a0a4 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1615,35 +1615,41 @@ static int ath10k_station_assoc(struct ath10k *ar, return ret; } - ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap); - if (ret) { - ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n", - arvif->vdev_id, ret); - return ret; - } - - if (!sta->wme && !reassoc) { - arvif->num_legacy_stations++; - ret = ath10k_recalc_rtscts_prot(arvif); + /* Re-assoc is run only to update supported rates for given station. It + * doesn't make much sense to reconfigure the peer completely. + */ + if (!reassoc) { + ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, + &sta->ht_cap); if (ret) { - ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", + ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n", arvif->vdev_id, ret); return ret; } - } - ret = ath10k_install_peer_wep_keys(arvif, sta->addr); - if (ret) { - ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", - arvif->vdev_id, ret); - return ret; - } + ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); + if (ret) { + ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n", + sta->addr, arvif->vdev_id, ret); + return ret; + } - ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); - if (ret) { - ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n", - sta->addr, arvif->vdev_id, ret); - return ret; + if (!sta->wme) { + arvif->num_legacy_stations++; + ret = ath10k_recalc_rtscts_prot(arvif); + if (ret) { + ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", + arvif->vdev_id, ret); + return ret; + } + } + + ret = ath10k_install_peer_wep_keys(arvif, sta->addr); + if (ret) { + ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", + arvif->vdev_id, ret); + return ret; + } } return ret; -- GitLab From 077efc8c42e8c35870946fc8d2452b70e9a13fba Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 21 Oct 2014 10:10:29 +0300 Subject: [PATCH 0951/9457] ath10k: clean up sta auth/assoc code The code can be symmetrical so make it so. This makes it easier to understand and work with. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 121 +++++++++----------------- 1 file changed, 42 insertions(+), 79 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index d7a2d6f9a0a4..78726a9bb7f1 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1492,6 +1492,9 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, lockdep_assert_held(&ar->conf_mutex); + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n", + arvif->vdev_id, arvif->bssid, arvif->aid); + rcu_read_lock(); ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); @@ -1534,6 +1537,8 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, "mac vdev %d up (associated) bssid %pM aid %d\n", arvif->vdev_id, bss_conf->bssid, bss_conf->aid); + WARN_ON(arvif->is_up); + arvif->aid = bss_conf->aid; ether_addr_copy(arvif->bssid, bss_conf->bssid); @@ -1547,9 +1552,6 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, arvif->is_up = true; } -/* - * FIXME: flush TIDs - */ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1559,33 +1561,15 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, lockdep_assert_held(&ar->conf_mutex); - /* - * For some reason, calling VDEV-DOWN before VDEV-STOP - * makes the FW to send frames via HTT after disassociation. - * No idea why this happens, even though VDEV-DOWN is supposed - * to be analogous to link down, so just stop the VDEV. - */ - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n", - arvif->vdev_id); - - /* FIXME: check return value */ - ret = ath10k_vdev_stop(arvif); - - /* - * If we don't call VDEV-DOWN after VDEV-STOP FW will remain active and - * report beacons from previously associated network through HTT. - * This in turn would spam mac80211 WARN_ON if we bring down all - * interfaces as it expects there is no rx when no interface is - * running. - */ - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id); + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n", + arvif->vdev_id, arvif->bssid); - /* FIXME: why don't we print error if wmi call fails? */ ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); + if (ret) + ath10k_warn(ar, "faield to down vdev %i: %d\n", + arvif->vdev_id, ret); arvif->def_wep_key_idx = 0; - - arvif->is_started = false; arvif->is_up = false; } @@ -3116,54 +3100,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, arvif->u.ap.hidden_ssid = info->hidden_ssid; } - /* - * Firmware manages AP self-peer internally so make sure to not create - * it in driver. Otherwise AP self-peer deletion may timeout later. - */ - if (changed & BSS_CHANGED_BSSID && - vif->type != NL80211_IFTYPE_AP) { - if (!is_zero_ether_addr(info->bssid)) { - if (vif->type == NL80211_IFTYPE_STATION) { - ath10k_dbg(ar, ATH10K_DBG_MAC, - "mac vdev %d create peer %pM\n", - arvif->vdev_id, info->bssid); - - ret = ath10k_peer_create(ar, arvif->vdev_id, - info->bssid); - if (ret) - ath10k_warn(ar, "failed to add peer %pM for vdev %d when changing bssid: %i\n", - info->bssid, arvif->vdev_id, - ret); - /* - * this is never erased as we it for crypto key - * clearing; this is FW requirement - */ - ether_addr_copy(arvif->bssid, info->bssid); - - ath10k_dbg(ar, ATH10K_DBG_MAC, - "mac vdev %d start %pM\n", - arvif->vdev_id, info->bssid); - - ret = ath10k_vdev_start(arvif); - if (ret) { - ath10k_warn(ar, "failed to start vdev %i: %d\n", - arvif->vdev_id, ret); - goto exit; - } - - arvif->is_started = true; - } - - /* - * Mac80211 does not keep IBSS bssid when leaving IBSS, - * so driver need to store it. It is needed when leaving - * IBSS in order to remove BSSID peer. - */ - if (vif->type == NL80211_IFTYPE_ADHOC) - memcpy(arvif->bssid, info->bssid, - ETH_ALEN); - } - } + if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) + ether_addr_copy(arvif->bssid, info->bssid); if (changed & BSS_CHANGED_BEACON_ENABLED) ath10k_control_beaconing(arvif, info); @@ -3225,10 +3163,11 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, ath10k_monitor_stop(ar); ath10k_bss_assoc(hw, vif, info); ath10k_monitor_recalc(ar); + } else { + ath10k_bss_disassoc(hw, vif); } } -exit: mutex_unlock(&ar->conf_mutex); } @@ -3537,8 +3476,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); if (old_state == IEEE80211_STA_NOTEXIST && - new_state == IEEE80211_STA_NONE && - vif->type != NL80211_IFTYPE_STATION) { + new_state == IEEE80211_STA_NONE) { /* * New station addition. */ @@ -3562,6 +3500,21 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, if (ret) ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n", sta->addr, arvif->vdev_id, ret); + + if (vif->type == NL80211_IFTYPE_STATION) { + WARN_ON(arvif->is_started); + + ret = ath10k_vdev_start(arvif); + if (ret) { + ath10k_warn(ar, "failed to start vdev %i: %d\n", + arvif->vdev_id, ret); + WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id, + sta->addr)); + goto exit; + } + + arvif->is_started = true; + } } else if ((old_state == IEEE80211_STA_NONE && new_state == IEEE80211_STA_NOTEXIST)) { /* @@ -3570,13 +3523,23 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d peer delete %pM (sta gone)\n", arvif->vdev_id, sta->addr); + + if (vif->type == NL80211_IFTYPE_STATION) { + WARN_ON(!arvif->is_started); + + ret = ath10k_vdev_stop(arvif); + if (ret) + ath10k_warn(ar, "failed to stop vdev %i: %d\n", + arvif->vdev_id, ret); + + arvif->is_started = false; + } + ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); if (ret) ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", sta->addr, arvif->vdev_id, ret); - if (vif->type == NL80211_IFTYPE_STATION) - ath10k_bss_disassoc(hw, vif); } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || -- GitLab From 21040bf9cb02eb688cb7f1ddaa568713d9ec3c2e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 21 Oct 2014 10:10:30 +0300 Subject: [PATCH 0952/9457] ath10k: simplify computation of mgmt rx band Using global channel won't work with chanctx. Try to determine the channel from the information provided in the wmi event itself alone. This should be sufficient. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 829fccfebbff..ae746cece211 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1114,7 +1114,6 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) struct wmi_mgmt_rx_event_v2 *ev_v2; struct wmi_mgmt_rx_hdr_v1 *ev_hdr; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_channel *ch; struct ieee80211_hdr *hdr; u32 rx_status; u32 channel; @@ -1167,25 +1166,26 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) if (rx_status & WMI_RX_STATUS_ERR_MIC) status->flag |= RX_FLAG_MMIC_ERROR; - /* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to + /* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is set to * MODE_11B. This means phy_mode is not a reliable source for the band - * of mgmt rx. */ - - ch = ar->scan_channel; - if (!ch) - ch = ar->rx_channel; - - if (ch) { - status->band = ch->band; - - if (phy_mode == MODE_11B && - status->band == IEEE80211_BAND_5GHZ) - ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); + * of mgmt rx. + */ + if (channel >= 1 && channel <= 14) { + status->band = IEEE80211_BAND_2GHZ; + } else if (channel >= 36 && channel <= 165) { + status->band = IEEE80211_BAND_5GHZ; } else { - ath10k_warn(ar, "using (unreliable) phy_mode to extract band for mgmt rx\n"); - status->band = phy_mode_to_band(phy_mode); + /* Shouldn't happen unless list of advertised channels to + * mac80211 has been changed. + */ + WARN_ON_ONCE(1); + dev_kfree_skb(skb); + return 0; } + if (phy_mode == MODE_11B && status->band == IEEE80211_BAND_5GHZ) + ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); + status->freq = ieee80211_channel_to_frequency(channel, status->band); status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; status->rate_idx = get_rate_idx(rate, status->band); -- GitLab From 7d9d5587c2e385b7a6c86547618e8adb87171e42 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 21 Oct 2014 10:40:15 +0300 Subject: [PATCH 0953/9457] ath10k: use bss_info as txpower source This simply changes the source for txpower setup. It does not make ath10k use different txpower values for different vifs. This will make it easier to implement chanctx in ath10k in the future. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/mac.c | 94 ++++++++++++++++++++------ 2 files changed, 75 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 2c286e73dbf7..1e3fd1013b70 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -287,6 +287,7 @@ struct ath10k_vif { u8 force_sgi; bool use_cts_prot; int num_legacy_stations; + int txpower; }; struct ath10k_vif_iter { diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 78726a9bb7f1..caaa3690af69 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2676,12 +2676,68 @@ static void ath10k_config_chan(struct ath10k *ar) ath10k_monitor_recalc(ar); } +static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower) +{ + int ret; + u32 param; + + lockdep_assert_held(&ar->conf_mutex); + + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower); + + param = ar->wmi.pdev_param->txpower_limit2g; + ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2); + if (ret) { + ath10k_warn(ar, "failed to set 2g txpower %d: %d\n", + txpower, ret); + return ret; + } + + param = ar->wmi.pdev_param->txpower_limit5g; + ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2); + if (ret) { + ath10k_warn(ar, "failed to set 5g txpower %d: %d\n", + txpower, ret); + return ret; + } + + return 0; +} + +static int ath10k_mac_txpower_recalc(struct ath10k *ar) +{ + struct ath10k_vif *arvif; + int ret, txpower = -1; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) { + WARN_ON(arvif->txpower < 0); + + if (txpower == -1) + txpower = arvif->txpower; + else + txpower = min(txpower, arvif->txpower); + } + + if (WARN_ON(txpower == -1)) + return -EINVAL; + + ret = ath10k_mac_txpower_setup(ar, txpower); + if (ret) { + ath10k_warn(ar, "failed to setup tx power %d: %d\n", + txpower, ret); + return ret; + } + + return 0; +} + static int ath10k_config(struct ieee80211_hw *hw, u32 changed) { struct ath10k *ar = hw->priv; struct ieee80211_conf *conf = &hw->conf; int ret = 0; - u32 param; mutex_lock(&ar->conf_mutex); @@ -2705,25 +2761,6 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) } } - if (changed & IEEE80211_CONF_CHANGE_POWER) { - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac config power %d\n", - hw->conf.power_level); - - param = ar->wmi.pdev_param->txpower_limit2g; - ret = ath10k_wmi_pdev_set_param(ar, param, - hw->conf.power_level * 2); - if (ret) - ath10k_warn(ar, "failed to set 2g txpower %d: %d\n", - hw->conf.power_level, ret); - - param = ar->wmi.pdev_param->txpower_limit5g; - ret = ath10k_wmi_pdev_set_param(ar, param, - hw->conf.power_level * 2); - if (ret) - ath10k_warn(ar, "failed to set 5g txpower %d: %d\n", - hw->conf.power_level, ret); - } - if (changed & IEEE80211_CONF_CHANGE_PS) ath10k_config_ps(ar); @@ -2932,6 +2969,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, goto err_peer_delete; } + arvif->txpower = vif->bss_conf.txpower; + ret = ath10k_mac_txpower_recalc(ar); + if (ret) { + ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); + goto err_peer_delete; + } + mutex_unlock(&ar->conf_mutex); return 0; @@ -3168,6 +3212,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, } } + if (changed & BSS_CHANGED_TXPOWER) { + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n", + arvif->vdev_id, info->txpower); + + arvif->txpower = info->txpower; + ret = ath10k_mac_txpower_recalc(ar); + if (ret) + ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); + } + mutex_unlock(&ar->conf_mutex); } -- GitLab From 2e53727658f1cfd23d4bc4a91967b7d9170d0a74 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Tue, 30 Sep 2014 11:39:17 +0530 Subject: [PATCH 0954/9457] pinctrl: st: Fix Sparse error This change fixes below sparse error, drivers/pinctrl/pinctrl-st.c:1515:31: error: incompatible types for operation (>) drivers/pinctrl/pinctrl-st.c:1515:31: left side has type void [noderef] *irqmux_base drivers/pinctrl/pinctrl-st.c:1515:31: right side has type int Cc: Maxime Coquelin Cc: Patrice Chotard CC: Linus Walleij Cc: Srinivas Kandagatla Signed-off-by: Pramod Gurav Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 4b1792aad3d8..caeeb1c65b0f 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1512,7 +1512,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info, gpio_irq, st_gpio_irq_handler); } - if (info->irqmux_base > 0 || gpio_irq > 0) { + if (info->irqmux_base || gpio_irq > 0) { err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip, 0, handle_simple_irq, IRQ_TYPE_LEVEL_LOW); -- GitLab From af0a33e26c1f16a52fb2511400387a7eab9fe4d6 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 3 Oct 2014 11:31:57 +0400 Subject: [PATCH 0955/9457] GPIO: Add driver for 74xx-ICs with MMIO access This patch adds driver to support GPIO functionality for 74xx-compatible ICs with MMIO access. Compatible models include: 1 bit: 741G125 (Input), 741G74 (Output) 2 bits: 742G125 (Input), 7474 (Output) 4 bits: 74125 (Input), 74175 (Output) 6 bits: 74365 (Input), 74174 (Output) 8 bits: 74244 (Input), 74273 (Output) 16 bits: 741624 (Input), 7416374 (Output) Signed-off-by: Alexander Shiyan Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 14 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-74xx-mmio.c | 170 ++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 drivers/gpio/gpio-74xx-mmio.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0959ca9b6b27..cd3313436b3a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -112,6 +112,20 @@ config GPIO_MAX730X comment "Memory mapped GPIO drivers:" +config GPIO_74XX_MMIO + tristate "GPIO driver for 74xx-ICs with MMIO access" + depends on OF_GPIO + select GPIO_GENERIC + help + Say yes here to support GPIO functionality for 74xx-compatible ICs + with MMIO access. Compatible models include: + 1 bit: 741G125 (Input), 741G74 (Output) + 2 bits: 742G125 (Input), 7474 (Output) + 4 bits: 74125 (Input), 74175 (Output) + 6 bits: 74365 (Input), 74174 (Output) + 8 bits: 74244 (Input), 74273 (Output) + 16 bits: 741624 (Input), 7416374 (Output) + config GPIO_CLPS711X tristate "CLPS711X GPIO support" depends on ARCH_CLPS711X || COMPILE_TEST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index e5d346cf3b6e..4486bbd2dad7 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o +obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o diff --git a/drivers/gpio/gpio-74xx-mmio.c b/drivers/gpio/gpio-74xx-mmio.c new file mode 100644 index 000000000000..0763655cca6c --- /dev/null +++ b/drivers/gpio/gpio-74xx-mmio.c @@ -0,0 +1,170 @@ +/* + * 74xx MMIO GPIO driver + * + * Copyright (C) 2014 Alexander Shiyan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#define MMIO_74XX_DIR_IN (0 << 8) +#define MMIO_74XX_DIR_OUT (1 << 8) +#define MMIO_74XX_BIT_CNT(x) ((x) & 0xff) + +struct mmio_74xx_gpio_priv { + struct bgpio_chip bgc; + unsigned flags; +}; + +static const struct of_device_id mmio_74xx_gpio_ids[] = { + { + .compatible = "ti,741g125", + .data = (const void *)(MMIO_74XX_DIR_IN | 1), + }, + { + .compatible = "ti,742g125", + .data = (const void *)(MMIO_74XX_DIR_IN | 2), + }, + { + .compatible = "ti,74125", + .data = (const void *)(MMIO_74XX_DIR_IN | 4), + }, + { + .compatible = "ti,74365", + .data = (const void *)(MMIO_74XX_DIR_IN | 6), + }, + { + .compatible = "ti,74244", + .data = (const void *)(MMIO_74XX_DIR_IN | 8), + }, + { + .compatible = "ti,741624", + .data = (const void *)(MMIO_74XX_DIR_IN | 16), + }, + { + .compatible = "ti,741g74", + .data = (const void *)(MMIO_74XX_DIR_OUT | 1), + }, + { + .compatible = "ti,7474", + .data = (const void *)(MMIO_74XX_DIR_OUT | 2), + }, + { + .compatible = "ti,74175", + .data = (const void *)(MMIO_74XX_DIR_OUT | 4), + }, + { + .compatible = "ti,74174", + .data = (const void *)(MMIO_74XX_DIR_OUT | 6), + }, + { + .compatible = "ti,74273", + .data = (const void *)(MMIO_74XX_DIR_OUT | 8), + }, + { + .compatible = "ti,7416374", + .data = (const void *)(MMIO_74XX_DIR_OUT | 16), + }, + { } +}; +MODULE_DEVICE_TABLE(of, mmio_74xx_gpio_ids); + +static inline struct mmio_74xx_gpio_priv *to_74xx_gpio(struct gpio_chip *gc) +{ + struct bgpio_chip *bgc = to_bgpio_chip(gc); + + return container_of(bgc, struct mmio_74xx_gpio_priv, bgc); +} + +static int mmio_74xx_get_direction(struct gpio_chip *gc, unsigned offset) +{ + struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc); + + return (priv->flags & MMIO_74XX_DIR_OUT) ? GPIOF_DIR_OUT : GPIOF_DIR_IN; +} + +static int mmio_74xx_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc); + + return (priv->flags & MMIO_74XX_DIR_OUT) ? -ENOTSUPP : 0; +} + +static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc); + + if (priv->flags & MMIO_74XX_DIR_OUT) { + gc->set(gc, gpio, val); + return 0; + } + + return -ENOTSUPP; +} + +static int mmio_74xx_gpio_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(mmio_74xx_gpio_ids, &pdev->dev); + struct mmio_74xx_gpio_priv *priv; + struct resource *res; + void __iomem *dat; + int err; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dat = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dat)) + return PTR_ERR(dat); + + priv->flags = (unsigned)of_id->data; + + err = bgpio_init(&priv->bgc, &pdev->dev, + DIV_ROUND_UP(MMIO_74XX_BIT_CNT(priv->flags), 8), + dat, NULL, NULL, NULL, NULL, 0); + if (err) + return err; + + priv->bgc.gc.direction_input = mmio_74xx_dir_in; + priv->bgc.gc.direction_output = mmio_74xx_dir_out; + priv->bgc.gc.get_direction = mmio_74xx_get_direction; + priv->bgc.gc.ngpio = MMIO_74XX_BIT_CNT(priv->flags); + priv->bgc.gc.owner = THIS_MODULE; + + platform_set_drvdata(pdev, priv); + + return gpiochip_add(&priv->bgc.gc); +} + +static int mmio_74xx_gpio_remove(struct platform_device *pdev) +{ + struct mmio_74xx_gpio_priv *priv = platform_get_drvdata(pdev); + + return bgpio_remove(&priv->bgc); +} + +static struct platform_driver mmio_74xx_gpio_driver = { + .driver = { + .name = "74xx-mmio-gpio", + .of_match_table = mmio_74xx_gpio_ids, + }, + .probe = mmio_74xx_gpio_probe, + .remove = mmio_74xx_gpio_remove, +}; +module_platform_driver(mmio_74xx_gpio_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alexander Shiyan "); +MODULE_DESCRIPTION("74xx MMIO GPIO driver"); -- GitLab From 4515b76d9b158ae89db094fe0fb277eaac88be25 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 3 Oct 2014 11:32:15 +0400 Subject: [PATCH 0956/9457] GPIO: 74xx-mmio: Add DT bindings documentation This patch adds DT binding documentation for the 74xx-mmio GPIO driver. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- .../bindings/gpio/gpio-74xx-mmio.txt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-74xx-mmio.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-74xx-mmio.txt b/Documentation/devicetree/bindings/gpio/gpio-74xx-mmio.txt new file mode 100644 index 000000000000..7bb1a9d60133 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-74xx-mmio.txt @@ -0,0 +1,30 @@ +* 74XX MMIO GPIO driver + +Required properties: +- compatible: Should contain one of the following: + "ti,741g125": for 741G125 (1-bit Input), + "ti,741g174": for 741G74 (1-bit Output), + "ti,742g125": for 742G125 (2-bit Input), + "ti,7474" : for 7474 (2-bit Output), + "ti,74125" : for 74125 (4-bit Input), + "ti,74175" : for 74175 (4-bit Output), + "ti,74365" : for 74365 (6-bit Input), + "ti,74174" : for 74174 (6-bit Output), + "ti,74244" : for 74244 (8-bit Input), + "ti,74273" : for 74273 (8-bit Output), + "ti,741624" : for 741624 (16-bit Input), + "ti,7416374": for 7416374 (16-bit Output). +- reg: Physical base address and length where IC resides. +- gpio-controller: Marks the device node as a gpio controller. +- #gpio-cells: Should be two. The first cell is the pin number and + the second cell is used to specify the GPIO polarity: + 0 = Active High, + 1 = Active Low. + +Example: + ctrl: gpio@30008004 { + compatible = "ti,74174"; + reg = <0x30008004 0x1>; + gpio-controller; + #gpio-cells = <2>; + }; -- GitLab From 3eebd61322835565bbcb1745bf9bd44e86ff80ca Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Wed, 1 Oct 2014 16:16:33 +0530 Subject: [PATCH 0957/9457] gpio: cs5535: Switch to using managed resources with devm_ This change switches to devm_request_region to request region and hence simplifies the module unload and does away with release_region in remove function. Cc: linux-gpio@vger.kernel.org Signed-off-by: Pramod Gurav Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-cs5535.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-cs5535.c b/drivers/gpio/gpio-cs5535.c index 668127fe90ef..71484eeb4ac2 100644 --- a/drivers/gpio/gpio-cs5535.c +++ b/drivers/gpio/gpio-cs5535.c @@ -322,7 +322,8 @@ static int cs5535_gpio_probe(struct platform_device *pdev) goto done; } - if (!request_region(res->start, resource_size(res), pdev->name)) { + if (!devm_request_region(&pdev->dev, res->start, resource_size(res), + pdev->name)) { dev_err(&pdev->dev, "can't request region\n"); goto done; } @@ -348,24 +349,18 @@ static int cs5535_gpio_probe(struct platform_device *pdev) /* finally, register with the generic GPIO API */ err = gpiochip_add(&cs5535_gpio_chip.chip); if (err) - goto release_region; + goto done; return 0; -release_region: - release_region(res->start, resource_size(res)); done: return err; } static int cs5535_gpio_remove(struct platform_device *pdev) { - struct resource *r; - gpiochip_remove(&cs5535_gpio_chip.chip); - r = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(r->start, resource_size(r)); return 0; } -- GitLab From 32197aab0425dbecc38462a91bc5c8acf70b2036 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 20 Oct 2014 23:53:13 +0900 Subject: [PATCH 0958/9457] gpu:drm: Fix typo in Documentation/DocBook/drm.xml This patch fix spelling typos found in drm.xml. It is because the file is generated from comments in source codes, I have to fix the typos within source files. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 2 +- drivers/gpu/drm/drm_irq.c | 4 ++-- drivers/gpu/drm/drm_modes.c | 2 +- drivers/gpu/drm/drm_prime.c | 4 ++-- drivers/gpu/drm/i915/i915_cmd_parser.c | 4 ++-- drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 2 +- include/drm/drm_dp_mst_helper.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e79c8d3700d8..7f94989e6fc9 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3611,7 +3611,7 @@ static struct drm_property *property_create_range(struct drm_device *dev, * object with drm_object_attach_property. The returned property object must be * freed with drm_property_destroy. * - * Userspace is allowed to set any interger value in the (min, max) range + * Userspace is allowed to set any integer value in the (min, max) range * inclusive. * * Returns: diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 5ef03c216a27..3e6b582f60dd 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off); * * This functions restores the vblank interrupt state captured with * drm_vblank_off() again. Note that calls to drm_vblank_on() and - * drm_vblank_off() can be unbalanced and so can also be unconditionaly called + * drm_vblank_off() can be unbalanced and so can also be unconditionally called * in driver load code to reflect the current hardware state of the crtc. * * This is the legacy version of drm_crtc_vblank_on(). @@ -1237,7 +1237,7 @@ EXPORT_SYMBOL(drm_vblank_on); * * This functions restores the vblank interrupt state captured with * drm_vblank_off() again. Note that calls to drm_vblank_on() and - * drm_vblank_off() can be unbalanced and so can also be unconditionaly called + * drm_vblank_off() can be unbalanced and so can also be unconditionally called * in driver load code to reflect the current hardware state of the crtc. * * This is the native kms version of drm_vblank_on(). diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index d1b7d2006529..6d8b941c8200 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -914,7 +914,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); * * This function is a helper which can be used to validate modes against size * limitations of the DRM device/connector. If a mode is too big its status - * memeber is updated with the appropriate validation failure code. The list + * member is updated with the appropriate validation failure code. The list * itself is not changed. */ void drm_mode_validate_size(struct drm_device *dev, diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 78ca30808422..6872eca6555e 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -328,7 +328,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { */ /** - * drm_gem_prime_export - helper library implemention of the export callback + * drm_gem_prime_export - helper library implementation of the export callback * @dev: drm_device to export from * @obj: GEM object to export * @flags: flags like DRM_CLOEXEC @@ -483,7 +483,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); /** - * drm_gem_prime_import - helper library implemention of the import callback + * drm_gem_prime_import - helper library implementation of the import callback * @dev: drm_device to import into * @dma_buf: dma-buf object to import * diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index c45856bcc8b9..5506242ee766 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -73,7 +73,7 @@ * those commands required by the parser. This generally works because command * opcode ranges have standard command length encodings. So for commands that * the parser does not need to check, it can easily skip them. This is - * implementated via a per-ring length decoding vfunc. + * implemented via a per-ring length decoding vfunc. * * Unfortunately, there are a number of commands that do not follow the standard * length encoding for their opcode range, primarily amongst the MI_* commands. @@ -836,7 +836,7 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj) * @ring: the ring in question * * Only certain platforms require software batch buffer command parsing, and - * only when enabled via module paramter. + * only when enabled via module parameter. * * Return: true if the ring requires software command parsing */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b65bdfc23ccb..65821bad3f6a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -664,7 +664,7 @@ enum punit_power_well { * need to be accessed during AUX communication, * * Generally the common lane corresponds to the pipe and - * the spline (PCS/TX) correponds to the port. + * the spline (PCS/TX) corresponds to the port. * * For dual channel PHY (VLV/CHV): * diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bd1b28d99920..b7b9a097c213 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1639,7 +1639,7 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) * the creation is a deferred call: it's better to make sure first that we need to use * a given ring with the context. * - * Return: non-zero on eror. + * Return: non-zero on error. */ int intel_lr_context_deferred_create(struct intel_context *ctx, struct intel_engine_cs *ring) diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 9b446ada2532..3ecfcc143bdd 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -28,7 +28,7 @@ struct drm_dp_mst_branch; /** - * struct drm_dp_vcpi - Virtual Channel Payload Identifer + * struct drm_dp_vcpi - Virtual Channel Payload Identifier * @vcpi: Virtual channel ID. * @pbn: Payload Bandwidth Number for this channel * @aligned_pbn: PBN aligned with slot size -- GitLab From c9d09bbec45fdeb26eed4cec6394bc6fae01ec0d Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 05:31:48 +0400 Subject: [PATCH 0959/9457] xtensa: nommu: move init_mmu stub to nommu_context.h mmu_context.h is not used in nommu configuration, nommu_context.h is used instead. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/mmu_context.h | 4 ---- arch/xtensa/include/asm/nommu_context.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h index d33c71a8c9ec..04c8ebdc4517 100644 --- a/arch/xtensa/include/asm/mmu_context.h +++ b/arch/xtensa/include/asm/mmu_context.h @@ -50,11 +50,7 @@ DECLARE_PER_CPU(unsigned long, asid_cache); #define ASID_MASK ((1 << XCHAL_MMU_ASID_BITS) - 1) #define ASID_INSERT(x) (0x03020001 | (((x) & ASID_MASK) << 8)) -#ifdef CONFIG_MMU void init_mmu(void); -#else -static inline void init_mmu(void) { } -#endif static inline void set_rasid_register (unsigned long val) { diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h index 3407cf7989b7..22984fd1d846 100644 --- a/arch/xtensa/include/asm/nommu_context.h +++ b/arch/xtensa/include/asm/nommu_context.h @@ -1,3 +1,7 @@ +static inline void init_mmu(void) +{ +} + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } -- GitLab From 4d5ea702467438bc7af59b053c13e900022d9387 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 06:32:07 +0400 Subject: [PATCH 0960/9457] xtensa: nommu: provide __invalidate_dcache_page_alias stub Signed-off-by: Max Filippov --- arch/xtensa/include/asm/cacheflush.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index e72aaca7a77f..01438e97edc6 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -67,6 +67,8 @@ extern void __invalidate_dcache_page_alias(unsigned long, unsigned long); #else static inline void __flush_invalidate_dcache_page_alias(unsigned long virt, unsigned long phys) { } +static inline void __invalidate_dcache_page_alias(unsigned long virt, + unsigned long phys) { } #endif #if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE) extern void __invalidate_icache_page_alias(unsigned long, unsigned long); -- GitLab From 972c55bf70c04b3deeecec022c8ca64136350655 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 06:32:47 +0400 Subject: [PATCH 0961/9457] xtensa: nommu: provide _PAGE_CHG_MASK definition Signed-off-by: Max Filippov --- arch/xtensa/include/asm/pgtable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 0383aed59121..872bf0194e6d 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -178,6 +178,7 @@ #else /* no mmu */ +# define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) # define PAGE_NONE __pgprot(0) # define PAGE_SHARED __pgprot(0) # define PAGE_COPY __pgprot(0) -- GitLab From f6891ddbc78dc819281d4fef158c0993e5ca7809 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 06:44:41 +0400 Subject: [PATCH 0962/9457] xtensa: nommu: provide MAP_UNINITIALIZED definition Add MAP_UNINITIALIZED to xtensa version of mman.h to keep mm/nommu.c happy. Signed-off-by: Max Filippov --- arch/xtensa/include/uapi/asm/mman.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/xtensa/include/uapi/asm/mman.h b/arch/xtensa/include/uapi/asm/mman.h index 00eed6786d7e..201aec0e0446 100644 --- a/arch/xtensa/include/uapi/asm/mman.h +++ b/arch/xtensa/include/uapi/asm/mman.h @@ -55,6 +55,12 @@ #define MAP_NONBLOCK 0x20000 /* do not block on IO */ #define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x80000 /* create a huge page mapping */ +#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED +# define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could be + * uninitialized */ +#else +# define MAP_UNINITIALIZED 0x0 /* Don't support this flag */ +#endif /* * Flags for msync -- GitLab From d10fa7cf3dc0b38995a691c3f4e9f90acaaa05f2 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 07:21:48 +0400 Subject: [PATCH 0963/9457] xtensa: nommu: don't provide arch_get_unmapped_area Nommu unconditionally provides arch_get_unmapped_area that always returns -ENOMEM. Signed-off-by: Max Filippov --- arch/xtensa/kernel/syscall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 5d3f7a119ed1..83cf49685373 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -57,6 +57,7 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, return sys_fadvise64_64(fd, offset, len, advice); } +#ifdef CONFIG_MMU unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { @@ -93,3 +94,4 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, addr = COLOUR_ALIGN(addr, pgoff); } } +#endif -- GitLab From b6cee17b7d5999ae5f9ea51643dc6ea6c3e4efd4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Sep 2014 09:54:42 +0400 Subject: [PATCH 0964/9457] xtensa: nommu: don't build most of the cache flushing code Most cache flushing code is only relevant for MMU. Don't build it for nommu configuration. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/cacheflush.h | 5 +++-- arch/xtensa/include/asm/page.h | 2 +- arch/xtensa/mm/Makefile | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 01438e97edc6..5f67ace97b32 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -86,7 +86,8 @@ static inline void __invalidate_icache_page_alias(unsigned long virt, * (see also Documentation/cachetlb.txt) */ -#if (DCACHE_WAY_SIZE > PAGE_SIZE) || defined(CONFIG_SMP) +#if defined(CONFIG_MMU) && \ + ((DCACHE_WAY_SIZE > PAGE_SIZE) || defined(CONFIG_SMP)) #ifdef CONFIG_SMP void flush_cache_all(void); @@ -152,7 +153,7 @@ void local_flush_cache_page(struct vm_area_struct *vma, #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -#if (DCACHE_WAY_SIZE > PAGE_SIZE) +#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) extern void copy_to_user_page(struct vm_area_struct*, struct page*, unsigned long, void*, const void*, unsigned long); diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index abe24c6f8b2f..619a51bb0163 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -145,7 +145,7 @@ extern void copy_page(void *to, void *from); * some extra work */ -#if DCACHE_WAY_SIZE > PAGE_SIZE +#if defined(CONFIG_MMU) && DCACHE_WAY_SIZE > PAGE_SIZE extern void clear_page_alias(void *vaddr, unsigned long paddr); extern void copy_page_alias(void *to, void *from, unsigned long to_paddr, unsigned long from_paddr); diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index f54f78e24d7b..e601e2fbe8e6 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile @@ -2,6 +2,6 @@ # Makefile for the Linux/Xtensa-specific parts of the memory manager. # -obj-y := init.o cache.o misc.o -obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o +obj-y := init.o misc.o +obj-$(CONFIG_MMU) += cache.o fault.o mmu.o tlb.o obj-$(CONFIG_HIGHMEM) += highmem.o -- GitLab From be603092ccc09f2d5ecf64cdf3c702b332a5dde3 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 2 Oct 2014 20:52:56 +0400 Subject: [PATCH 0965/9457] xtensa: nommu: add MMU dependency to DEBUG_TLB_SANITY TLB sanity checking code depends on full MMU presence and may not be built in noMMU confgiuration. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index af7da74d535f..53ae08eef86d 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug @@ -4,7 +4,7 @@ source "lib/Kconfig.debug" config DEBUG_TLB_SANITY bool "Debug TLB sanity" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && MMU help Enable this to turn on TLB sanity check on each entry to userspace. This check can spot missing TLB invalidation/wrong PTE permissions/ -- GitLab From ccd0ef38be3b9e0cc6efff407c53c43f648d598b Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 2 Oct 2014 22:03:27 +0400 Subject: [PATCH 0966/9457] xtensa: nommu: fix Image.elf reset code and ld script Don't hardcode kernel entry address as 0x3000 or 0xd0003000, use LOAD_MEMORY_ADDRESS macro. Don't compile MMU remapping code and don't try to link it when building noMMU configuration. Signed-off-by: Max Filippov --- arch/xtensa/boot/boot-elf/boot.lds.S | 2 ++ arch/xtensa/boot/boot-elf/bootstrap.S | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S index 932b58ef33d4..958b33af96b7 100644 --- a/arch/xtensa/boot/boot-elf/boot.lds.S +++ b/arch/xtensa/boot/boot-elf/boot.lds.S @@ -41,6 +41,7 @@ SECTIONS __bss_end = .; } +#ifdef CONFIG_MMU /* * This is a remapped copy of the Reset Vector Code. * It keeps gdb in sync with the PC after switching @@ -51,4 +52,5 @@ SECTIONS { *(.ResetVector.remapped_text) } +#endif } diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S index 1388a499753b..9341a5750694 100644 --- a/arch/xtensa/boot/boot-elf/bootstrap.S +++ b/arch/xtensa/boot/boot-elf/bootstrap.S @@ -20,6 +20,7 @@ #include #include #include +#include #include .section .ResetVector.text, "ax" @@ -34,12 +35,7 @@ _ResetVector: .align 4 RomInitAddr: -#if defined(CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) && \ - XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY - .word 0x00003000 -#else - .word 0xd0003000 -#endif + .word LOAD_MEMORY_ADDRESS RomBootParam: .word _bootparam _bootparam: @@ -79,6 +75,7 @@ reset: movi a4, 0 jx a0 +#ifdef CONFIG_MMU .align 4 .section .ResetVector.remapped_text, "x" @@ -102,3 +99,4 @@ _RemappedSetupMMU: #endif .end no-absolute-literals +#endif -- GitLab From 72bb305fdcb7b6ee14a283016e32f6bf4c864b44 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 3 Oct 2014 00:57:31 +0400 Subject: [PATCH 0967/9457] xtensa: nommu: fix load address definitions Change KERNELOFFSET, LOAD_MEMORY_ADDRESS and VIRTUAL_MEMORY_ADDRESS to be relative to the start of physical memory in noMMU configuration, as there's no uniform memory remapping to KSEG starting at 0xd0000000. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/vectors.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h index f74ddfbb92ef..a46c53f36113 100644 --- a/arch/xtensa/include/asm/vectors.h +++ b/arch/xtensa/include/asm/vectors.h @@ -19,6 +19,7 @@ #define _XTENSA_VECTORS_H #include +#include #define XCHAL_KIO_CACHED_VADDR 0xe0000000 #define XCHAL_KIO_BYPASS_VADDR 0xf0000000 @@ -51,13 +52,13 @@ /* MMU Not being used - Virtual == Physical */ /* VECBASE */ - #define VIRTUAL_MEMORY_ADDRESS 0x00002000 + #define VIRTUAL_MEMORY_ADDRESS (PLATFORM_DEFAULT_MEM_START + 0x2000) /* Location of the start of the kernel text, _start */ - #define KERNELOFFSET 0x00003000 + #define KERNELOFFSET (PLATFORM_DEFAULT_MEM_START + 0x3000) /* Loaded just above possibly live vectors */ - #define LOAD_MEMORY_ADDRESS 0x00003000 + #define LOAD_MEMORY_ADDRESS (PLATFORM_DEFAULT_MEM_START + 0x3000) #endif /* CONFIG_MMU */ -- GitLab From a4f9846da76c854dcd13a5ac00826b599ad09745 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 3 Oct 2014 19:04:59 +0400 Subject: [PATCH 0968/9457] xtensa: nommu: fix uImage load address Use the same offset from the default physical memory start address as in LOAD_MEMORY_ADDRESS definition. Signed-off-by: Max Filippov --- arch/xtensa/boot/boot-uboot/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile index 545759819ef9..403fcf23405c 100644 --- a/arch/xtensa/boot/boot-uboot/Makefile +++ b/arch/xtensa/boot/boot-uboot/Makefile @@ -4,11 +4,15 @@ # for more details. # +ifdef CONFIG_MMU ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX UIMAGE_LOADADDR = 0x00003000 else UIMAGE_LOADADDR = 0xd0003000 endif +else +UIMAGE_LOADADDR = $(shell printf "0x%x" $$(( ${CONFIG_DEFAULT_MEM_START} + 0x3000 )) ) +endif UIMAGE_COMPRESSION = gzip $(obj)/../uImage: vmlinux.bin.gz FORCE -- GitLab From 53490121e9ffa3e6314137af016cde8ac83c9bb4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 4 Oct 2014 05:12:27 +0400 Subject: [PATCH 0969/9457] xtensa: move vecbase SR initialization to _startup Instead of initializing vecbase in initialize_mmu macro, which may be expanded either in Image.elf reset vector hadler or in the kernel head.S, both times only when CONFIG_MMU is enabled, do this initialization once in _startup function. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/initialize_mmu.h | 3 --- arch/xtensa/kernel/head.S | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h index 600781edc8a3..cdac5584ec0c 100644 --- a/arch/xtensa/include/asm/initialize_mmu.h +++ b/arch/xtensa/include/asm/initialize_mmu.h @@ -141,9 +141,6 @@ jx a4 1: - movi a2, VECBASE_RESET_VADDR - wsr a2, vecbase - /* Step 5: remove temporary mapping. */ idtlb a7 iitlb a7 diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index aeeb3cc8a410..15a461e2a0ed 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -112,6 +112,11 @@ ENTRY(_startup) movi a0, 0 +#if XCHAL_HAVE_VECBASE + movi a2, VECBASE_RESET_VADDR + wsr a2, vecbase +#endif + /* Clear debugging registers. */ #if XCHAL_HAVE_DEBUG -- GitLab From 2eabc1800d1ef7a850672aedcc266a831572af63 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 4 Oct 2014 18:50:53 +0400 Subject: [PATCH 0970/9457] xtensa: nommu: set up cache and atomctl in initialize_mmu initialize_mmu sets up atomctl SR which is needed for s32c1i to function correctly even in noMMU configurations. It's also a good place to set up caching attributes of physical memory. Allow enabling INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX in noMMU configurations for setting up atomctl and cache attributes. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 1 - arch/xtensa/include/asm/initialize_mmu.h | 37 +++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 81f57e8c8f1b..cb44f6f95968 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -191,7 +191,6 @@ config HOTPLUG_CPU config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX bool "Initialize Xtensa MMU inside the Linux kernel code" - depends on MMU default y help Earlier version initialized the MMU in the exception vector diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h index cdac5584ec0c..e256f2270ec9 100644 --- a/arch/xtensa/include/asm/initialize_mmu.h +++ b/arch/xtensa/include/asm/initialize_mmu.h @@ -26,8 +26,16 @@ #include #include +#if XCHAL_HAVE_PTP_MMU #define CA_BYPASS (_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC) #define CA_WRITEBACK (_PAGE_CA_WB | _PAGE_HW_WRITE | _PAGE_HW_EXEC) +#else +#define CA_WRITEBACK (0x4) +#endif + +#ifndef XCHAL_SPANNING_WAY +#define XCHAL_SPANNING_WAY 0 +#endif #ifdef __ASSEMBLY__ @@ -75,7 +83,7 @@ /* Step 1: invalidate mapping at 0x40000000..0x5FFFFFFF. */ - movi a2, 0x40000006 + movi a2, 0x40000000 | XCHAL_SPANNING_WAY idtlb a2 iitlb a2 isync @@ -153,6 +161,33 @@ #endif /* defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY */ +#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS + /* Enable data and instruction cache in the DEFAULT_MEMORY region + * if the processor has DTLB and ITLB. + */ + + movi a5, PLATFORM_DEFAULT_MEM_START | XCHAL_SPANNING_WAY + movi a6, ~_PAGE_ATTRIB_MASK + movi a7, CA_WRITEBACK + movi a8, 0x20000000 + movi a9, PLATFORM_DEFAULT_MEM_SIZE + j 2f +1: + sub a9, a9, a8 +2: + rdtlb1 a3, a5 + ritlb1 a4, a5 + and a3, a3, a6 + and a4, a4, a6 + or a3, a3, a7 + or a4, a4, a7 + wdtlb a3, a5 + witlb a4, a5 + add a5, a5, a8 + bltu a8, a9, 1b + +#endif + .endm #endif /*__ASSEMBLY__*/ -- GitLab From 566fb58ed422537715023d1f19b705247a640b11 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 4 Oct 2014 03:46:34 +0400 Subject: [PATCH 0971/9457] xtensa: nommu: reserve memory below PLATFORM_DEFAULT_MEM_START Memory accounting code can't handle pages below PLATFORM_DEFAULT_MEM_START. Reserve those pages if they exist. When PLATFORM_DEFAULT_MEM_START is zero reserve one page at address 0 to make sure that successfull memory allocations don't return NULL. Signed-off-by: Max Filippov --- arch/xtensa/mm/init.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 77ed20209ca5..5a084fa5b608 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -239,6 +239,17 @@ void __init bootmem_init(void) unsigned long bootmap_start, bootmap_size; int i; + /* Reserve all memory below PLATFORM_DEFAULT_MEM_START, as memory + * accounting doesn't work for pages below that address. + * + * If PLATFORM_DEFAULT_MEM_START is zero reserve page at address 0: + * successfull allocations should never return NULL. + */ + if (PLATFORM_DEFAULT_MEM_START) + mem_reserve(0, PLATFORM_DEFAULT_MEM_START, 0); + else + mem_reserve(0, 1, 0); + sysmem_dump(); max_low_pfn = max_pfn = 0; min_low_pfn = ~0; -- GitLab From 5a0b1d78bfc5ca4079ea03abb0ecc0d61d676e41 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 4 Oct 2014 03:50:33 +0400 Subject: [PATCH 0972/9457] xtensa: nommu: clean up memory map dump noMMU configuration doesn't use special area for vmalloc allocations, don't print it in the memory map. PAGE_OFFSET is fixed to 0 in noMMU, use min_low_pfn and max_low_pfn for lowmem range display. Make all XCHAL_KSEG_* constants unsigned long for consistency with other addresses. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/page.h | 10 +++++----- arch/xtensa/mm/init.c | 8 +++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 619a51bb0163..ad38500471fa 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -20,10 +20,10 @@ * Fixed TLB translations in the processor. */ -#define XCHAL_KSEG_CACHED_VADDR 0xd0000000 -#define XCHAL_KSEG_BYPASS_VADDR 0xd8000000 -#define XCHAL_KSEG_PADDR 0x00000000 -#define XCHAL_KSEG_SIZE 0x08000000 +#define XCHAL_KSEG_CACHED_VADDR __XTENSA_UL_CONST(0xd0000000) +#define XCHAL_KSEG_BYPASS_VADDR __XTENSA_UL_CONST(0xd8000000) +#define XCHAL_KSEG_PADDR __XTENSA_UL_CONST(0x00000000) +#define XCHAL_KSEG_SIZE __XTENSA_UL_CONST(0x08000000) /* * PAGE_SHIFT determines the page size @@ -37,7 +37,7 @@ #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR #define MAX_MEM_PFN XCHAL_KSEG_SIZE #else -#define PAGE_OFFSET 0 +#define PAGE_OFFSET __XTENSA_UL_CONST(0) #define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) #endif diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 5a084fa5b608..9a9a5935bd36 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -343,18 +343,24 @@ void __init mem_init(void) " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n" " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" #endif +#ifdef CONFIG_MMU " vmalloc : 0x%08x - 0x%08x (%5u MB)\n" - " lowmem : 0x%08x - 0x%08lx (%5lu MB)\n", +#endif + " lowmem : 0x%08lx - 0x%08lx (%5lu MB)\n", #ifdef CONFIG_HIGHMEM PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, (LAST_PKMAP*PAGE_SIZE) >> 10, FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10, #endif +#ifdef CONFIG_MMU VMALLOC_START, VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, PAGE_OFFSET, PAGE_OFFSET + (max_low_pfn - min_low_pfn) * PAGE_SIZE, +#else + min_low_pfn * PAGE_SIZE, max_low_pfn * PAGE_SIZE, +#endif ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20); } -- GitLab From 3932b9ca55b0be314a36d3e84faff3e823c081f5 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 4 Oct 2014 04:45:39 +0400 Subject: [PATCH 0973/9457] xtensa: make PLATFORM_DEFAULT_MEM parameters configurable This allows using xtfpga platform with both MMU and noMMU cores. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 36 +++++++++++++++++++ .../xtfpga/include/platform/hardware.h | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index cb44f6f95968..f860dbe28b5e 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -319,6 +319,7 @@ config XTENSA_PLATFORM_S6105 config XTENSA_PLATFORM_XTFPGA bool "XTFPGA" select ETHOC if ETHERNET + select PLATFORM_WANT_DEFAULT_MEM select SERIAL_CONSOLE select XTENSA_CALIBRATE_CCOUNT help @@ -405,6 +406,41 @@ source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" +config PLATFORM_WANT_DEFAULT_MEM + def_bool n + +config DEFAULT_MEM_START + hex "Physical address of the default memory area start" + depends on PLATFORM_WANT_DEFAULT_MEM + default 0x00000000 if MMU + default 0x40000000 if !MMU + help + This is a fallback start address of the default memory area, it is + used when no physical memory size is passed through DTB or through + boot parameter from bootloader. + + In noMMU configuration the following parameters are derived from it: + - kernel load address; + - kernel entry point address; + - relocatable vectors base address; + - uBoot load address; + - TASK_SIZE. + + If unsure, leave the default value here. + +config DEFAULT_MEM_SIZE + hex "Maximal size of the default memory area" + depends on PLATFORM_WANT_DEFAULT_MEM + default 0x04000000 + help + This is a fallback size of the default memory area, it is used when + no physical memory size is passed through DTB or through boot + parameter from bootloader. + + It's also used for TASK_SIZE calculation in noMMU configuration. + + If unsure, leave the default value here. + endmenu menu "Executable file formats" diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h index aeb316b7ff88..6edd20bb4565 100644 --- a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h @@ -17,8 +17,8 @@ /* Memory configuration. */ -#define PLATFORM_DEFAULT_MEM_START 0x00000000 -#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 +#define PLATFORM_DEFAULT_MEM_START CONFIG_DEFAULT_MEM_START +#define PLATFORM_DEFAULT_MEM_SIZE CONFIG_DEFAULT_MEM_SIZE /* Interrupt configuration. */ -- GitLab From 4006e565e1500db40b8546dcc6011737bc5d986c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Sun, 19 Oct 2014 00:46:25 +0200 Subject: [PATCH 0974/9457] xtensa: remove s6000 variant and s6105 platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Stretch s6000 family support has been merged into mainline 5 years ago. There appear to be no users of this code since nobody complained that there is a merge error preventing compilation. Apart from the s6105 IP camera reference design there are no s6000 devices known to ever have run Linux and as the chips are out of production there probably never will be. The successor s7000 no longer uses an Xtensa core for the OS. Let's remove the code until someone is found who actually needs it. Signed-off-by: Daniel Glöckner Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 13 - arch/xtensa/Makefile | 1 - arch/xtensa/configs/iss_defconfig | 2 - arch/xtensa/configs/s6105_defconfig | 615 ------------------ arch/xtensa/platforms/s6105/Makefile | 3 - arch/xtensa/platforms/s6105/device.c | 161 ----- .../platforms/s6105/include/platform/gpio.h | 27 - .../s6105/include/platform/hardware.h | 11 - .../platforms/s6105/include/platform/serial.h | 8 - arch/xtensa/platforms/s6105/setup.c | 73 --- arch/xtensa/variants/s6000/Makefile | 4 - arch/xtensa/variants/s6000/delay.c | 25 - arch/xtensa/variants/s6000/dmac.c | 173 ----- arch/xtensa/variants/s6000/gpio.c | 230 ------- .../variants/s6000/include/variant/core.h | 431 ------------ .../variants/s6000/include/variant/dmac.h | 387 ----------- .../variants/s6000/include/variant/gpio.h | 6 - .../variants/s6000/include/variant/hardware.h | 259 -------- .../variants/s6000/include/variant/irq.h | 8 - .../variants/s6000/include/variant/tie-asm.h | 304 --------- .../variants/s6000/include/variant/tie.h | 191 ------ arch/xtensa/variants/s6000/irq.c | 74 --- 22 files changed, 3006 deletions(-) delete mode 100644 arch/xtensa/configs/s6105_defconfig delete mode 100644 arch/xtensa/platforms/s6105/Makefile delete mode 100644 arch/xtensa/platforms/s6105/device.c delete mode 100644 arch/xtensa/platforms/s6105/include/platform/gpio.h delete mode 100644 arch/xtensa/platforms/s6105/include/platform/hardware.h delete mode 100644 arch/xtensa/platforms/s6105/include/platform/serial.h delete mode 100644 arch/xtensa/platforms/s6105/setup.c delete mode 100644 arch/xtensa/variants/s6000/Makefile delete mode 100644 arch/xtensa/variants/s6000/delay.c delete mode 100644 arch/xtensa/variants/s6000/dmac.c delete mode 100644 arch/xtensa/variants/s6000/gpio.c delete mode 100644 arch/xtensa/variants/s6000/include/variant/core.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/dmac.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/gpio.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/hardware.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/irq.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/tie-asm.h delete mode 100644 arch/xtensa/variants/s6000/include/variant/tie.h delete mode 100644 arch/xtensa/variants/s6000/irq.c diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index f860dbe28b5e..8cdbc4cc830c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -98,12 +98,6 @@ config XTENSA_VARIANT_DC233C help This variant refers to Tensilica's Diamond 233L Standard core Rev.C (LE). -config XTENSA_VARIANT_S6000 - bool "s6000 - Stretch software configurable processor" - select VARIANT_IRQ_SWITCH - select ARCH_REQUIRE_GPIOLIB - select XTENSA_CALIBRATE_CCOUNT - config XTENSA_VARIANT_CUSTOM bool "Custom Xtensa processor configuration" select MAY_HAVE_SMP @@ -126,7 +120,6 @@ config XTENSA_VARIANT_NAME default "dc232b" if XTENSA_VARIANT_DC232B default "dc233c" if XTENSA_VARIANT_DC233C default "fsf" if XTENSA_VARIANT_FSF - default "s6000" if XTENSA_VARIANT_S6000 default XTENSA_VARIANT_CUSTOM_NAME if XTENSA_VARIANT_CUSTOM config XTENSA_VARIANT_MMU @@ -310,12 +303,6 @@ config XTENSA_PLATFORM_XT2000 XT2000 is the name of Tensilica's feature-rich emulation platform. This hardware is capable of running a full Linux distribution. -config XTENSA_PLATFORM_S6105 - bool "S6105" - select HAVE_IDE - select SERIAL_CONSOLE - select NO_IOPORT_MAP - config XTENSA_PLATFORM_XTFPGA bool "XTFPGA" select ETHOC if ETHERNET diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 472533064b46..f9e6a068aafd 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -35,7 +35,6 @@ endif platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss -platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga PLATFORM = $(platform-y) diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index b966baf82cae..6a7593b6784d 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig @@ -143,7 +143,6 @@ CONFIG_MMU=y # CONFIG_XTENSA_VARIANT_FSF=y # CONFIG_XTENSA_VARIANT_DC232B is not set -# CONFIG_XTENSA_VARIANT_S6000 is not set # CONFIG_XTENSA_UNALIGNED_USER is not set # CONFIG_PREEMPT is not set CONFIG_XTENSA_CALIBRATE_CCOUNT=y @@ -161,7 +160,6 @@ CONFIG_XTENSA_ISS_NETWORK=y # CONFIG_XTENSA_PLATFORM_ISS=y # CONFIG_XTENSA_PLATFORM_XT2000 is not set -# CONFIG_XTENSA_PLATFORM_S6105 is not set # CONFIG_GENERIC_CALIBRATE_DELAY is not set CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,38400 eth0=tuntap,,tap0 ip=192.168.168.5:192.168.168.1 root=nfs nfsroot=192.168.168.1:/opt/montavista/pro/devkit/xtensa/linux_be/target" diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig deleted file mode 100644 index 9471265b8ca6..000000000000 --- a/arch/xtensa/configs/s6105_defconfig +++ /dev/null @@ -1,615 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc7-s6 -# Tue Mar 10 11:09:26 2009 -# -# CONFIG_FRAME_POINTER is not set -CONFIG_ZONE_DMA=y -CONFIG_XTENSA=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_NO_IOPORT_MAP=y -CONFIG_HZ=100 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -# CONFIG_CLASSIC_RCU is not set -# CONFIG_TREE_RCU is not set -CONFIG_PREEMPT_RCU=y -# CONFIG_RCU_TRACE is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=16 -# CONFIG_GROUP_SCHED is not set -# CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EXPERT=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -# CONFIG_MODULES is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_FREEZER is not set -# CONFIG_MMU is not set -CONFIG_VARIANT_IRQ_SWITCH=y - -# -# Processor type and features -# -# CONFIG_XTENSA_VARIANT_FSF is not set -# CONFIG_XTENSA_VARIANT_DC232B is not set -CONFIG_XTENSA_VARIANT_S6000=y -# CONFIG_XTENSA_UNALIGNED_USER is not set -CONFIG_PREEMPT=y -# CONFIG_HIGHMEM is not set -CONFIG_XTENSA_CALIBRATE_CCOUNT=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_XTENSA_ISS_NETWORK is not set - -# -# Bus options -# -# CONFIG_PCI is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# Platform options -# -# CONFIG_XTENSA_PLATFORM_ISS is not set -# CONFIG_XTENSA_PLATFORM_XT2000 is not set -CONFIG_XTENSA_PLATFORM_S6105=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7" -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_VIRT_TO_BUS=y - -# -# Executable file formats -# -CONFIG_KCORE_ELF=y -CONFIG_BINFMT_FLAT=y -# CONFIG_BINFMT_ZFLAT is not set -# CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_HAVE_AOUT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_NET=y - -# -# Networking options -# -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -CONFIG_SMSC_PHY=y -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_NET_ETHERNET is not set -CONFIG_NETDEV_1000=y -CONFIG_S6GMAC=y -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_DEVKMEM is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO expanders: -# - -# -# I2C GPIO expanders: -# - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -# CONFIG_RTC_INTF_SYSFS is not set -# CONFIG_RTC_INTF_PROC is not set -# CONFIG_RTC_INTF_DEV is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -CONFIG_RTC_DRV_M41T80=y -# CONFIG_RTC_DRV_M41T80_WDT is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -# CONFIG_MISC_FILESYSTEMS is not set -# CONFIG_NETWORK_FILESYSTEMS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_PRINTK_TIME=y -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -CONFIG_DEBUG_NOMMU_REGIONS=y -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set - -# -# Tracers -# -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_SAMPLES is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC32 is not set -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_DMA=y diff --git a/arch/xtensa/platforms/s6105/Makefile b/arch/xtensa/platforms/s6105/Makefile deleted file mode 100644 index 0be6194bcb72..000000000000 --- a/arch/xtensa/platforms/s6105/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# Makefile for the Stretch S6105 eval board - -obj-y := setup.o device.o diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c deleted file mode 100644 index 4f4fc971042f..000000000000 --- a/arch/xtensa/platforms/s6105/device.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * s6105 platform devices - * - * Copyright (c) 2009 emlix GmbH - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define GPIO3_INTNUM 3 -#define UART_INTNUM 4 -#define GMAC_INTNUM 5 - -static const signed char gpio3_irq_mappings[] = { - S6_INTC_GPIO(3), - -1 -}; - -static const signed char uart_irq_mappings[] = { - S6_INTC_UART(0), - S6_INTC_UART(1), - -1, -}; - -static const signed char gmac_irq_mappings[] = { - S6_INTC_GMAC_STAT, - S6_INTC_GMAC_ERR, - S6_INTC_DMA_HOSTTERMCNT(0), - S6_INTC_DMA_HOSTTERMCNT(1), - -1 -}; - -const signed char *platform_irq_mappings[NR_IRQS] = { - [GPIO3_INTNUM] = gpio3_irq_mappings, - [UART_INTNUM] = uart_irq_mappings, - [GMAC_INTNUM] = gmac_irq_mappings, -}; - -static struct plat_serial8250_port serial_platform_data[] = { - { - .membase = (void *)S6_REG_UART + 0x0000, - .mapbase = S6_REG_UART + 0x0000, - .irq = UART_INTNUM, - .uartclk = S6_SCLK, - .regshift = 2, - .iotype = SERIAL_IO_MEM, - .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST, - }, - { - .membase = (void *)S6_REG_UART + 0x1000, - .mapbase = S6_REG_UART + 0x1000, - .irq = UART_INTNUM, - .uartclk = S6_SCLK, - .regshift = 2, - .iotype = SERIAL_IO_MEM, - .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST, - }, - { }, -}; - -static struct resource s6_gmac_resource[] = { - { - .name = "mem", - .start = (resource_size_t)S6_REG_GMAC, - .end = (resource_size_t)S6_REG_GMAC + 0x10000 - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "dma", - .start = (resource_size_t) - DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX), - .end = (resource_size_t) - DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1, - .flags = IORESOURCE_DMA, - }, - { - .name = "dma", - .start = (resource_size_t) - DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX), - .end = (resource_size_t) - DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1, - .flags = IORESOURCE_DMA, - }, - { - .name = "io", - .start = (resource_size_t)S6_MEM_GMAC, - .end = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1, - .flags = IORESOURCE_IO, - }, - { - .name = "irq", - .start = (resource_size_t)GMAC_INTNUM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "irq", - .start = (resource_size_t)PHY_POLL, - .flags = IORESOURCE_IRQ, - }, -}; - -static int __init prepare_phy_irq(int pin) -{ - int irq; - if (gpio_request(pin, "s6gmac_phy") < 0) - goto fail; - if (gpio_direction_input(pin) < 0) - goto free; - irq = gpio_to_irq(pin); - if (irq < 0) - goto free; - if (irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0) - goto free; - return irq; -free: - gpio_free(pin); -fail: - return PHY_POLL; -} - -static struct platform_device platform_devices[] = { - { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, - }, - { - .name = "s6gmac", - .id = 0, - .resource = s6_gmac_resource, - .num_resources = ARRAY_SIZE(s6_gmac_resource), - }, - { - I2C_BOARD_INFO("m41t62", S6I2C_ADDR_M41T62), - }, -}; - -static int __init device_init(void) -{ - int i; - - s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ); - - for (i = 0; i < ARRAY_SIZE(platform_devices); i++) - platform_device_register(&platform_devices[i]); - return 0; -} -arch_initcall_sync(device_init); diff --git a/arch/xtensa/platforms/s6105/include/platform/gpio.h b/arch/xtensa/platforms/s6105/include/platform/gpio.h deleted file mode 100644 index fa11aa4b61e9..000000000000 --- a/arch/xtensa/platforms/s6105/include/platform/gpio.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __ASM_XTENSA_S6105_GPIO_H -#define __ASM_XTENSA_S6105_GPIO_H - -#define GPIO_BP_TEMP_ALARM 0 -#define GPIO_PB_RESET_IN 1 -#define GPIO_EXP_IRQ 2 -#define GPIO_TRIGGER_IRQ 3 -#define GPIO_RTC_IRQ 4 -#define GPIO_PHY_IRQ 5 -#define GPIO_IMAGER_RESET 6 -#define GPIO_SD_IRQ 7 -#define GPIO_MINI_BOOT_INH 8 -#define GPIO_BOARD_RESET 9 -#define GPIO_EXP_PRESENT 10 -#define GPIO_LED1_NGREEN 12 -#define GPIO_LED1_RED 13 -#define GPIO_LED0_NGREEN 14 -#define GPIO_LED0_NRED 15 -#define GPIO_SPI_CS0 16 -#define GPIO_SPI_CS1 17 -#define GPIO_SPI_CS3 19 -#define GPIO_SPI_CS4 20 -#define GPIO_SD_WP 21 -#define GPIO_BP_RESET 22 -#define GPIO_ALARM_OUT 23 - -#endif /* __ASM_XTENSA_S6105_GPIO_H */ diff --git a/arch/xtensa/platforms/s6105/include/platform/hardware.h b/arch/xtensa/platforms/s6105/include/platform/hardware.h deleted file mode 100644 index d628efac7089..000000000000 --- a/arch/xtensa/platforms/s6105/include/platform/hardware.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __XTENSA_S6105_HARDWARE_H -#define __XTENSA_S6105_HARDWARE_H - -#define PLATFORM_DEFAULT_MEM_START 0x40000000 -#define PLATFORM_DEFAULT_MEM_SIZE 0x08000000 - -#define MAX_DMA_ADDRESS 0 - -#define KERNELOFFSET (PLATFORM_DEFAULT_MEM_START + 0x1000) - -#endif /* __XTENSA_S6105_HARDWARE_H */ diff --git a/arch/xtensa/platforms/s6105/include/platform/serial.h b/arch/xtensa/platforms/s6105/include/platform/serial.h deleted file mode 100644 index c8a771e5981b..000000000000 --- a/arch/xtensa/platforms/s6105/include/platform/serial.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_XTENSA_S6105_SERIAL_H -#define __ASM_XTENSA_S6105_SERIAL_H - -#include - -#define BASE_BAUD (S6_SCLK / 16) - -#endif /* __ASM_XTENSA_S6105_SERIAL_H */ diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c deleted file mode 100644 index 86ce730f7913..000000000000 --- a/arch/xtensa/platforms/s6105/setup.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * s6105 control routines - * - * Copyright (c) 2009 emlix GmbH - */ -#include -#include -#include - -#include - -#include -#include - -#include - -void platform_halt(void) -{ - local_irq_disable(); - while (1) - ; -} - -void platform_power_off(void) -{ - platform_halt(); -} - -void platform_restart(void) -{ - platform_halt(); -} - -void __init platform_setup(char **cmdline) -{ - unsigned long reg; - - reg = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); - reg &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC | - S6_GREG1_PLLSEL_GMII_MASK << S6_GREG1_PLLSEL_GMII); - reg |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC | - S6_GREG1_PLLSEL_GMII_125MHZ << S6_GREG1_PLLSEL_GMII; - writel(reg, S6_REG_GREG1 + S6_GREG1_PLLSEL); - - reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE); - reg &= ~(1 << S6_GREG1_BLOCK_SB); - reg &= ~(1 << S6_GREG1_BLOCK_GMAC); - writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE); - - reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA); - reg |= 1 << S6_GREG1_BLOCK_SB; - reg |= 1 << S6_GREG1_BLOCK_GMAC; - writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA); - - printk(KERN_NOTICE "S6105 on Stretch S6000 - " - "Copyright (C) 2009 emlix GmbH \n"); -} - -void __init platform_init(bp_tag_t *first) -{ - s6_gpio_init(0); - gpio_request(GPIO_LED1_NGREEN, "led1_green"); - gpio_request(GPIO_LED1_RED, "led1_red"); - gpio_direction_output(GPIO_LED1_NGREEN, 1); -} - -void platform_heartbeat(void) -{ - static unsigned int c; - - if (!(++c & 0x4F)) - gpio_direction_output(GPIO_LED1_RED, !(c & 0x10)); -} diff --git a/arch/xtensa/variants/s6000/Makefile b/arch/xtensa/variants/s6000/Makefile deleted file mode 100644 index 3e7ef0a0c498..000000000000 --- a/arch/xtensa/variants/s6000/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# s6000 Makefile - -obj-y += irq.o gpio.o dmac.o -obj-$(CONFIG_XTENSA_CALIBRATE_CCOUNT) += delay.o diff --git a/arch/xtensa/variants/s6000/delay.c b/arch/xtensa/variants/s6000/delay.c deleted file mode 100644 index 39154563ee17..000000000000 --- a/arch/xtensa/variants/s6000/delay.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -#define LOOPS 10 -void platform_calibrate_ccount(void) -{ - u32 uninitialized_var(a); - u32 uninitialized_var(u); - u32 b; - u32 tstamp = S6_REG_GREG1 + S6_GREG1_GLOBAL_TIMER; - int i = LOOPS+1; - do { - u32 t = u; - asm volatile( - "1: l32i %0, %2, 0 ;" - " beq %0, %1, 1b ;" - : "=&a"(u) : "a"(t), "a"(tstamp)); - b = get_ccount(); - if (i == LOOPS) - a = b; - } while (--i >= 0); - b -= a; - ccount_freq = b * (100000UL / LOOPS); -} diff --git a/arch/xtensa/variants/s6000/dmac.c b/arch/xtensa/variants/s6000/dmac.c deleted file mode 100644 index 340f5bb0b5ef..000000000000 --- a/arch/xtensa/variants/s6000/dmac.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Authors: Oskar Schirmer - * Daniel Gloeckner - * (c) 2008 emlix GmbH http://www.emlix.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* DMA engine lookup */ - -struct s6dmac_ctrl s6dmac_ctrl[S6_DMAC_NB]; - - -/* DMA control, per engine */ - -void s6dmac_put_fifo_cache(u32 dmac, int chan, u32 src, u32 dst, u32 size) -{ - if (xtensa_need_flush_dma_source(src)) { - u32 base = src; - u32 span = size; - u32 chunk = readl(DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); - if (chunk && (size > chunk)) { - s32 skip = - readl(DMA_CHNL(dmac, chan) + S6_DMA_SRCSKIP); - u32 gaps = (size+chunk-1)/chunk - 1; - if (skip >= 0) { - span += gaps * skip; - } else if (-skip > chunk) { - s32 decr = gaps * (chunk + skip); - base += decr; - span = chunk - decr; - } else { - span = max(span + gaps * skip, - (chunk + skip) * gaps - skip); - } - } - flush_dcache_unaligned(base, span); - } - if (xtensa_need_invalidate_dma_destination(dst)) { - u32 base = dst; - u32 span = size; - u32 chunk = readl(DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); - if (chunk && (size > chunk)) { - s32 skip = - readl(DMA_CHNL(dmac, chan) + S6_DMA_DSTSKIP); - u32 gaps = (size+chunk-1)/chunk - 1; - if (skip >= 0) { - span += gaps * skip; - } else if (-skip > chunk) { - s32 decr = gaps * (chunk + skip); - base += decr; - span = chunk - decr; - } else { - span = max(span + gaps * skip, - (chunk + skip) * gaps - skip); - } - } - invalidate_dcache_unaligned(base, span); - } - s6dmac_put_fifo(dmac, chan, src, dst, size); -} - -void s6dmac_disable_error_irqs(u32 dmac, u32 mask) -{ - unsigned long flags; - spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; - spin_lock_irqsave(spinl, flags); - _s6dmac_disable_error_irqs(dmac, mask); - spin_unlock_irqrestore(spinl, flags); -} - -u32 s6dmac_int_sources(u32 dmac, u32 channel) -{ - u32 mask, ret, tmp; - mask = 1 << channel; - - tmp = readl(dmac + S6_DMA_TERMCNTIRQSTAT); - tmp &= mask; - writel(tmp, dmac + S6_DMA_TERMCNTIRQCLR); - ret = tmp >> channel; - - tmp = readl(dmac + S6_DMA_PENDCNTIRQSTAT); - tmp &= mask; - writel(tmp, dmac + S6_DMA_PENDCNTIRQCLR); - ret |= (tmp >> channel) << 1; - - tmp = readl(dmac + S6_DMA_LOWWMRKIRQSTAT); - tmp &= mask; - writel(tmp, dmac + S6_DMA_LOWWMRKIRQCLR); - ret |= (tmp >> channel) << 2; - - tmp = readl(dmac + S6_DMA_INTRAW0); - tmp &= (mask << S6_DMA_INT0_OVER) | (mask << S6_DMA_INT0_UNDER); - writel(tmp, dmac + S6_DMA_INTCLEAR0); - - if (tmp & (mask << S6_DMA_INT0_UNDER)) - ret |= 1 << 3; - if (tmp & (mask << S6_DMA_INT0_OVER)) - ret |= 1 << 4; - - tmp = readl(dmac + S6_DMA_MASTERERRINFO); - mask <<= S6_DMA_INT1_CHANNEL; - if (((tmp >> S6_DMA_MASTERERR_CHAN(0)) & S6_DMA_MASTERERR_CHAN_MASK) - == channel) - mask |= 1 << S6_DMA_INT1_MASTER; - if (((tmp >> S6_DMA_MASTERERR_CHAN(1)) & S6_DMA_MASTERERR_CHAN_MASK) - == channel) - mask |= 1 << (S6_DMA_INT1_MASTER + 1); - if (((tmp >> S6_DMA_MASTERERR_CHAN(2)) & S6_DMA_MASTERERR_CHAN_MASK) - == channel) - mask |= 1 << (S6_DMA_INT1_MASTER + 2); - - tmp = readl(dmac + S6_DMA_INTRAW1) & mask; - writel(tmp, dmac + S6_DMA_INTCLEAR1); - ret |= ((tmp >> channel) & 1) << 5; - ret |= ((tmp >> S6_DMA_INT1_MASTER) & S6_DMA_INT1_MASTER_MASK) << 6; - - return ret; -} - -void s6dmac_release_chan(u32 dmac, int chan) -{ - if (chan >= 0) - s6dmac_disable_chan(dmac, chan); -} - - -/* global init */ - -static inline void __init dmac_init(u32 dmac, u8 chan_nb) -{ - s6dmac_ctrl[S6_DMAC_INDEX(dmac)].dmac = dmac; - spin_lock_init(&s6dmac_ctrl[S6_DMAC_INDEX(dmac)].lock); - s6dmac_ctrl[S6_DMAC_INDEX(dmac)].chan_nb = chan_nb; - writel(S6_DMA_INT1_MASTER_MASK << S6_DMA_INT1_MASTER, - dmac + S6_DMA_INTCLEAR1); -} - -static inline void __init dmac_master(u32 dmac, - u32 m0start, u32 m0end, u32 m1start, u32 m1end) -{ - writel(m0start, dmac + S6_DMA_MASTER0START); - writel(m0end - 1, dmac + S6_DMA_MASTER0END); - writel(m1start, dmac + S6_DMA_MASTER1START); - writel(m1end - 1, dmac + S6_DMA_MASTER1END); -} - -static void __init s6_dmac_init(void) -{ - dmac_init(S6_REG_LMSDMA, S6_LMSDMA_NB); - dmac_master(S6_REG_LMSDMA, - S6_MEM_DDR, S6_MEM_PCIE_APER, S6_MEM_EFI, S6_MEM_GMAC); - dmac_init(S6_REG_NIDMA, S6_NIDMA_NB); - dmac_init(S6_REG_DPDMA, S6_DPDMA_NB); - dmac_master(S6_REG_DPDMA, - S6_MEM_DDR, S6_MEM_PCIE_APER, S6_REG_DP, S6_REG_DPDMA); - dmac_init(S6_REG_HIFDMA, S6_HIFDMA_NB); - dmac_master(S6_REG_HIFDMA, - S6_MEM_GMAC, S6_MEM_PCIE_CFG, S6_MEM_PCIE_APER, S6_MEM_AUX); -} - -arch_initcall(s6_dmac_init); diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c deleted file mode 100644 index da9e85c13b08..000000000000 --- a/arch/xtensa/variants/s6000/gpio.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * s6000 gpio driver - * - * Copyright (c) 2009 emlix GmbH - * Authors: Oskar Schirmer - * Johannes Weiner - * Daniel Gloeckner - */ -#include -#include -#include -#include -#include -#include -#include - -#include - -#define IRQ_BASE XTENSA_NR_IRQS - -#define S6_GPIO_DATA 0x000 -#define S6_GPIO_IS 0x404 -#define S6_GPIO_IBE 0x408 -#define S6_GPIO_IEV 0x40C -#define S6_GPIO_IE 0x410 -#define S6_GPIO_RIS 0x414 -#define S6_GPIO_MIS 0x418 -#define S6_GPIO_IC 0x41C -#define S6_GPIO_AFSEL 0x420 -#define S6_GPIO_DIR 0x800 -#define S6_GPIO_BANK(nr) ((nr) * 0x1000) -#define S6_GPIO_MASK(nr) (4 << (nr)) -#define S6_GPIO_OFFSET(nr) \ - (S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7)) - -static int direction_input(struct gpio_chip *chip, unsigned int off) -{ - writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off)); - return 0; -} - -static int get(struct gpio_chip *chip, unsigned int off) -{ - return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off)); -} - -static int direction_output(struct gpio_chip *chip, unsigned int off, int val) -{ - unsigned rel = S6_GPIO_OFFSET(off); - writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel); - writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel); - return 0; -} - -static void set(struct gpio_chip *chip, unsigned int off, int val) -{ - writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off)); -} - -static int to_irq(struct gpio_chip *chip, unsigned offset) -{ - if (offset < 8) - return offset + IRQ_BASE; - return -EINVAL; -} - -static struct gpio_chip gpiochip = { - .owner = THIS_MODULE, - .direction_input = direction_input, - .get = get, - .direction_output = direction_output, - .set = set, - .to_irq = to_irq, - .base = 0, - .ngpio = 24, - .can_sleep = 0, /* no blocking io needed */ - .exported = 0, /* no exporting to userspace */ -}; - -int s6_gpio_init(u32 afsel) -{ - writeb(afsel, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL); - writeb(afsel >> 8, S6_REG_GPIO + S6_GPIO_BANK(1) + S6_GPIO_AFSEL); - writeb(afsel >> 16, S6_REG_GPIO + S6_GPIO_BANK(2) + S6_GPIO_AFSEL); - return gpiochip_add(&gpiochip); -} - -static void ack(struct irq_data *d) -{ - writeb(1 << (d->irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC); -} - -static void mask(struct irq_data *d) -{ - u8 r = readb(S6_REG_GPIO + S6_GPIO_IE); - r &= ~(1 << (d->irq - IRQ_BASE)); - writeb(r, S6_REG_GPIO + S6_GPIO_IE); -} - -static void unmask(struct irq_data *d) -{ - u8 m = readb(S6_REG_GPIO + S6_GPIO_IE); - m |= 1 << (d->irq - IRQ_BASE); - writeb(m, S6_REG_GPIO + S6_GPIO_IE); -} - -static int set_type(struct irq_data *d, unsigned int type) -{ - const u8 m = 1 << (d->irq - IRQ_BASE); - irq_flow_handler_t handler; - u8 reg; - - if (type == IRQ_TYPE_PROBE) { - if ((readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL) & m) - || (readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE) & m) - || readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_DIR - + S6_GPIO_MASK(irq - IRQ_BASE))) - return 0; - type = IRQ_TYPE_EDGE_BOTH; - } - - reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); - if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { - reg |= m; - handler = handle_level_irq; - } else { - reg &= ~m; - handler = handle_edge_irq; - } - writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); - __irq_set_handler_locked(irq, handler); - - reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); - if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) - reg |= m; - else - reg &= ~m; - writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); - - reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE); - if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) - reg |= m; - else - reg &= ~m; - writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE); - return 0; -} - -static struct irq_chip gpioirqs = { - .name = "GPIO", - .irq_ack = ack, - .irq_mask = mask, - .irq_unmask = unmask, - .irq_set_type = set_type, -}; - -static u8 demux_masks[4]; - -static void demux_irqs(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - u8 *mask = irq_desc_get_handler_data(desc); - u8 pending; - int cirq; - - chip->irq_mask(&desc->irq_data); - chip->irq_ack(&desc->irq_data); - pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; - cirq = IRQ_BASE - 1; - while (pending) { - int n = ffs(pending); - cirq += n; - pending >>= n; - generic_handle_irq(cirq); - } - chip->irq_unmask(&desc->irq_data); -} - -extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; - -void __init variant_init_irq(void) -{ - int irq, n; - writeb(0, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE); - for (irq = n = 0; irq < XTENSA_NR_IRQS; irq++) { - const signed char *mapping = platform_irq_mappings[irq]; - int alone = 1; - u8 mask; - if (!mapping) - continue; - for(mask = 0; *mapping != -1; mapping++) - switch (*mapping) { - case S6_INTC_GPIO(0): - mask |= 1 << 0; - break; - case S6_INTC_GPIO(1): - mask |= 1 << 1; - break; - case S6_INTC_GPIO(2): - mask |= 1 << 2; - break; - case S6_INTC_GPIO(3): - mask |= 0x1f << 3; - break; - default: - alone = 0; - } - if (mask) { - int cirq, i; - if (!alone) { - printk(KERN_ERR "chained irq chips can't share" - " parent irq %i\n", irq); - continue; - } - demux_masks[n] = mask; - cirq = IRQ_BASE - 1; - do { - i = ffs(mask); - cirq += i; - mask >>= i; - irq_set_chip(cirq, &gpioirqs); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); - } while (mask); - irq_set_handler_data(irq, demux_masks + n); - irq_set_chained_handler(irq, demux_irqs); - if (++n == ARRAY_SIZE(demux_masks)) - break; - } - } -} diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h deleted file mode 100644 index af007953027e..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/core.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Xtensa processor core configuration information. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 1999-2008 Tensilica Inc. - */ - -#ifndef _XTENSA_CORE_CONFIGURATION_H -#define _XTENSA_CORE_CONFIGURATION_H - - -/**************************************************************************** - Parameters Useful for Any Code, USER or PRIVILEGED - ****************************************************************************/ - -/* - * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is - * configured, and a value of 0 otherwise. These macros are always defined. - */ - - -/*---------------------------------------------------------------------- - ISA - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ -#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ -#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */ -#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */ -#define XCHAL_MAX_INSTRUCTION_SIZE 8 /* max instr bytes (3..8) */ -#define XCHAL_HAVE_DEBUG 1 /* debug option */ -#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ -#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ -#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ -#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ -#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ -#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ -#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ -#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ -#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */ -#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */ -#define XCHAL_HAVE_L32R 1 /* L32R instruction */ -#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ -#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ -#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ -#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ -#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ -#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ -#define XCHAL_HAVE_ABS 1 /* ABS instruction */ -/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ -/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ -#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */ -#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */ -#define XCHAL_HAVE_SPECULATION 0 /* speculation */ -#define XCHAL_HAVE_FULL_RESET 0 /* all regs/state reset */ -#define XCHAL_NUM_CONTEXTS 1 /* */ -#define XCHAL_NUM_MISC_REGS 4 /* num of scratch regs (0..4) */ -#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ -#define XCHAL_HAVE_PRID 0 /* processor ID register */ -#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */ -#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */ -#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ -#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */ -#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ -#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ -#define XCHAL_HAVE_FP 1 /* floating point pkg */ -#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ -#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ -#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ - - -/*---------------------------------------------------------------------- - MISC - ----------------------------------------------------------------------*/ - -#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */ -#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */ -#define XCHAL_DATA_WIDTH 16 /* data width in bytes */ -/* In T1050, applies to selected core load and store instructions (see ISA): */ -#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ -#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ - -#define XCHAL_SW_VERSION 701001 /* sw version of this header */ - -#define XCHAL_CORE_ID "stretch_bali" /* alphanum core name - (CoreID) set in the Xtensa - Processor Generator */ - -#define XCHAL_BUILD_UNIQUE_ID 0x000104B9 /* 22-bit sw build ID */ - -/* - * These definitions describe the hardware targeted by this software. - */ -#define XCHAL_HW_CONFIGID0 0xC2F3F9FE /* ConfigID hi 32 bits*/ -#define XCHAL_HW_CONFIGID1 0x054104B9 /* ConfigID lo 32 bits*/ -#define XCHAL_HW_VERSION_NAME "LX1.0.2" /* full version name */ -#define XCHAL_HW_VERSION_MAJOR 2100 /* major ver# of targeted hw */ -#define XCHAL_HW_VERSION_MINOR 2 /* minor ver# of targeted hw */ -#define XCHAL_HW_VERSION 210002 /* major*100+minor */ -#define XCHAL_HW_REL_LX1 1 -#define XCHAL_HW_REL_LX1_0 1 -#define XCHAL_HW_REL_LX1_0_2 1 -#define XCHAL_HW_CONFIGID_RELIABLE 1 -/* If software targets a *range* of hardware versions, these are the bounds: */ -#define XCHAL_HW_MIN_VERSION_MAJOR 2100 /* major v of earliest tgt hw */ -#define XCHAL_HW_MIN_VERSION_MINOR 2 /* minor v of earliest tgt hw */ -#define XCHAL_HW_MIN_VERSION 210002 /* earliest targeted hw */ -#define XCHAL_HW_MAX_VERSION_MAJOR 2100 /* major v of latest tgt hw */ -#define XCHAL_HW_MAX_VERSION_MINOR 2 /* minor v of latest tgt hw */ -#define XCHAL_HW_MAX_VERSION 210002 /* latest targeted hw */ - - -/*---------------------------------------------------------------------- - CACHE - ----------------------------------------------------------------------*/ - -#define XCHAL_ICACHE_LINESIZE 16 /* I-cache line size in bytes */ -#define XCHAL_DCACHE_LINESIZE 16 /* D-cache line size in bytes */ -#define XCHAL_ICACHE_LINEWIDTH 4 /* log2(I line size in bytes) */ -#define XCHAL_DCACHE_LINEWIDTH 4 /* log2(D line size in bytes) */ - -#define XCHAL_ICACHE_SIZE 32768 /* I-cache size in bytes or 0 */ -#define XCHAL_DCACHE_SIZE 32768 /* D-cache size in bytes or 0 */ - -#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ - - - - -/**************************************************************************** - Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code - ****************************************************************************/ - - -#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY - -/*---------------------------------------------------------------------- - CACHE - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ - -/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ - -/* Number of cache sets in log2(lines per way): */ -#define XCHAL_ICACHE_SETWIDTH 9 -#define XCHAL_DCACHE_SETWIDTH 10 - -/* Cache set associativity (number of ways): */ -#define XCHAL_ICACHE_WAYS 4 -#define XCHAL_DCACHE_WAYS 2 - -/* Cache features: */ -#define XCHAL_ICACHE_LINE_LOCKABLE 1 -#define XCHAL_DCACHE_LINE_LOCKABLE 0 -#define XCHAL_ICACHE_ECC_PARITY 0 -#define XCHAL_DCACHE_ECC_PARITY 0 - -/* Number of encoded cache attr bits (see for decoded bits): */ -#define XCHAL_CA_BITS 4 - - -/*---------------------------------------------------------------------- - INTERNAL I/D RAM/ROMs and XLMI - ----------------------------------------------------------------------*/ - -#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ -#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */ -#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ -#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */ -#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ -#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */ - -/* Data RAM 0: */ -#define XCHAL_DATARAM0_VADDR 0x3FFF0000 -#define XCHAL_DATARAM0_PADDR 0x3FFF0000 -#define XCHAL_DATARAM0_SIZE 65536 -#define XCHAL_DATARAM0_ECC_PARITY 0 - -/* XLMI Port 0: */ -#define XCHAL_XLMI0_VADDR 0x37F80000 -#define XCHAL_XLMI0_PADDR 0x37F80000 -#define XCHAL_XLMI0_SIZE 262144 -#define XCHAL_XLMI0_ECC_PARITY 0 - - -/*---------------------------------------------------------------------- - INTERRUPTS and TIMERS - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ -#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ -#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ -#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ -#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */ -#define XCHAL_NUM_INTERRUPTS 27 /* number of interrupts */ -#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ -#define XCHAL_NUM_EXTINTERRUPTS 20 /* num of external interrupts */ -#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels - (not including level zero) */ -#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */ - /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ - -/* Masks of interrupts at each interrupt level: */ -#define XCHAL_INTLEVEL1_MASK 0x01F07FFF -#define XCHAL_INTLEVEL2_MASK 0x02018000 -#define XCHAL_INTLEVEL3_MASK 0x04060000 -#define XCHAL_INTLEVEL4_MASK 0x00000000 -#define XCHAL_INTLEVEL5_MASK 0x00080000 -#define XCHAL_INTLEVEL6_MASK 0x00000000 -#define XCHAL_INTLEVEL7_MASK 0x00000000 - -/* Masks of interrupts at each range 1..n of interrupt levels: */ -#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x01F07FFF -#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x03F1FFFF -#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x07F7FFFF -#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x07F7FFFF -#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x07FFFFFF -#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x07FFFFFF -#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x07FFFFFF - -/* Level of each interrupt: */ -#define XCHAL_INT0_LEVEL 1 -#define XCHAL_INT1_LEVEL 1 -#define XCHAL_INT2_LEVEL 1 -#define XCHAL_INT3_LEVEL 1 -#define XCHAL_INT4_LEVEL 1 -#define XCHAL_INT5_LEVEL 1 -#define XCHAL_INT6_LEVEL 1 -#define XCHAL_INT7_LEVEL 1 -#define XCHAL_INT8_LEVEL 1 -#define XCHAL_INT9_LEVEL 1 -#define XCHAL_INT10_LEVEL 1 -#define XCHAL_INT11_LEVEL 1 -#define XCHAL_INT12_LEVEL 1 -#define XCHAL_INT13_LEVEL 1 -#define XCHAL_INT14_LEVEL 1 -#define XCHAL_INT15_LEVEL 2 -#define XCHAL_INT16_LEVEL 2 -#define XCHAL_INT17_LEVEL 3 -#define XCHAL_INT18_LEVEL 3 -#define XCHAL_INT19_LEVEL 5 -#define XCHAL_INT20_LEVEL 1 -#define XCHAL_INT21_LEVEL 1 -#define XCHAL_INT22_LEVEL 1 -#define XCHAL_INT23_LEVEL 1 -#define XCHAL_INT24_LEVEL 1 -#define XCHAL_INT25_LEVEL 2 -#define XCHAL_INT26_LEVEL 3 -#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */ -#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ -#define XCHAL_NMILEVEL 5 /* NMI "level" (for use with - EXCSAVE/EPS/EPC_n, RFI n) */ - -/* Type of each interrupt: */ -#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT14_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT19_TYPE XTHAL_INTTYPE_NMI -#define XCHAL_INT20_TYPE XTHAL_INTTYPE_SOFTWARE -#define XCHAL_INT21_TYPE XTHAL_INTTYPE_SOFTWARE -#define XCHAL_INT22_TYPE XTHAL_INTTYPE_SOFTWARE -#define XCHAL_INT23_TYPE XTHAL_INTTYPE_SOFTWARE -#define XCHAL_INT24_TYPE XTHAL_INTTYPE_TIMER -#define XCHAL_INT25_TYPE XTHAL_INTTYPE_TIMER -#define XCHAL_INT26_TYPE XTHAL_INTTYPE_TIMER - -/* Masks of interrupts for each type of interrupt: */ -#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xF8000000 -#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00F00000 -#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000 -#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0007FFFF -#define XCHAL_INTTYPE_MASK_TIMER 0x07000000 -#define XCHAL_INTTYPE_MASK_NMI 0x00080000 -#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 - -/* Interrupt numbers assigned to specific interrupt sources: */ -#define XCHAL_TIMER0_INTERRUPT 24 /* CCOMPARE0 */ -#define XCHAL_TIMER1_INTERRUPT 25 /* CCOMPARE1 */ -#define XCHAL_TIMER2_INTERRUPT 26 /* CCOMPARE2 */ -#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED -#define XCHAL_NMI_INTERRUPT 19 /* non-maskable interrupt */ - -/* Interrupt numbers for levels at which only one interrupt is configured: */ -#define XCHAL_INTLEVEL5_NUM 19 -/* (There are many interrupts each at level(s) 1, 2, 3.) */ - - -/* - * External interrupt vectors/levels. - * These macros describe how Xtensa processor interrupt numbers - * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) - * map to external BInterrupt pins, for those interrupts - * configured as external (level-triggered, edge-triggered, or NMI). - * See the Xtensa processor databook for more details. - */ - -/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ -#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ -#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ -#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ -#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ -#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ -#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ -#define XCHAL_EXTINT6_NUM 6 /* (intlevel 1) */ -#define XCHAL_EXTINT7_NUM 7 /* (intlevel 1) */ -#define XCHAL_EXTINT8_NUM 8 /* (intlevel 1) */ -#define XCHAL_EXTINT9_NUM 9 /* (intlevel 1) */ -#define XCHAL_EXTINT10_NUM 10 /* (intlevel 1) */ -#define XCHAL_EXTINT11_NUM 11 /* (intlevel 1) */ -#define XCHAL_EXTINT12_NUM 12 /* (intlevel 1) */ -#define XCHAL_EXTINT13_NUM 13 /* (intlevel 1) */ -#define XCHAL_EXTINT14_NUM 14 /* (intlevel 1) */ -#define XCHAL_EXTINT15_NUM 15 /* (intlevel 2) */ -#define XCHAL_EXTINT16_NUM 16 /* (intlevel 2) */ -#define XCHAL_EXTINT17_NUM 17 /* (intlevel 3) */ -#define XCHAL_EXTINT18_NUM 18 /* (intlevel 3) */ -#define XCHAL_EXTINT19_NUM 19 /* (intlevel 5) */ - - -/*---------------------------------------------------------------------- - EXCEPTIONS and VECTORS - ----------------------------------------------------------------------*/ - -#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture - number: 1 == XEA1 (old) - 2 == XEA2 (new) - 0 == XEAX (extern) */ -#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ -#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ -#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ -#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ -#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ -#define XCHAL_HAVE_VECTOR_SELECT 0 /* relocatable vectors */ -#define XCHAL_HAVE_VECBASE 0 /* relocatable vectors */ - -#define XCHAL_RESET_VECOFS 0x00000000 -#define XCHAL_RESET_VECTOR_VADDR 0x3FFE03D0 -#define XCHAL_RESET_VECTOR_PADDR 0x3FFE03D0 -#define XCHAL_USER_VECOFS 0x00000000 -#define XCHAL_USER_VECTOR_VADDR 0x40000220 -#define XCHAL_USER_VECTOR_PADDR 0x40000220 -#define XCHAL_KERNEL_VECOFS 0x00000000 -#define XCHAL_KERNEL_VECTOR_VADDR 0x40000200 -#define XCHAL_KERNEL_VECTOR_PADDR 0x40000200 -#define XCHAL_DOUBLEEXC_VECOFS 0x00000000 -#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x400002A0 -#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x400002A0 -#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 -#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 -#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 -#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 -#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 -#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 -#define XCHAL_WINDOW_VECTORS_VADDR 0x40000000 -#define XCHAL_WINDOW_VECTORS_PADDR 0x40000000 -#define XCHAL_INTLEVEL2_VECOFS 0x00000000 -#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x40000240 -#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x40000240 -#define XCHAL_INTLEVEL3_VECOFS 0x00000000 -#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x40000260 -#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x40000260 -#define XCHAL_INTLEVEL4_VECOFS 0x00000000 -#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x40000390 -#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x40000390 -#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL4_VECOFS -#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR -#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR -#define XCHAL_NMI_VECOFS 0x00000000 -#define XCHAL_NMI_VECTOR_VADDR 0x400003B0 -#define XCHAL_NMI_VECTOR_PADDR 0x400003B0 -#define XCHAL_INTLEVEL5_VECOFS XCHAL_NMI_VECOFS -#define XCHAL_INTLEVEL5_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR -#define XCHAL_INTLEVEL5_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR - - -/*---------------------------------------------------------------------- - DEBUG - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ -#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ -#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ -#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */ - - -/*---------------------------------------------------------------------- - MMU - ----------------------------------------------------------------------*/ - -/* See core-matmap.h header file for more details. */ - -#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ -#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ -#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */ -#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ -#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */ -#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ -#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table - [autorefill] and protection) - usable for an MMU-based OS */ -/* If none of the above last 4 are set, it's a custom TLB configuration. */ - -#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */ -#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */ -#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */ - -#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ - - -#endif /* _XTENSA_CORE_CONFIGURATION_H */ - diff --git a/arch/xtensa/variants/s6000/include/variant/dmac.h b/arch/xtensa/variants/s6000/include/variant/dmac.h deleted file mode 100644 index 3f88d9fc6897..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/dmac.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * include/asm-xtensa/variant-s6000/dmac.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Tensilica Inc. - * Copyright (C) 2008 Emlix GmbH - * Authors: Fabian Godehardt - * Oskar Schirmer - * Daniel Gloeckner - */ - -#ifndef __ASM_XTENSA_S6000_DMAC_H -#define __ASM_XTENSA_S6000_DMAC_H -#include -#include - -/* DMA global */ - -#define S6_DMA_INTSTAT0 0x000 -#define S6_DMA_INTSTAT1 0x004 -#define S6_DMA_INTENABLE0 0x008 -#define S6_DMA_INTENABLE1 0x00C -#define S6_DMA_INTRAW0 0x010 -#define S6_DMA_INTRAW1 0x014 -#define S6_DMA_INTCLEAR0 0x018 -#define S6_DMA_INTCLEAR1 0x01C -#define S6_DMA_INTSET0 0x020 -#define S6_DMA_INTSET1 0x024 -#define S6_DMA_INT0_UNDER 0 -#define S6_DMA_INT0_OVER 16 -#define S6_DMA_INT1_CHANNEL 0 -#define S6_DMA_INT1_MASTER 16 -#define S6_DMA_INT1_MASTER_MASK 7 -#define S6_DMA_TERMCNTIRQSTAT 0x028 -#define S6_DMA_TERMCNTIRQCLR 0x02C -#define S6_DMA_TERMCNTIRQSET 0x030 -#define S6_DMA_PENDCNTIRQSTAT 0x034 -#define S6_DMA_PENDCNTIRQCLR 0x038 -#define S6_DMA_PENDCNTIRQSET 0x03C -#define S6_DMA_LOWWMRKIRQSTAT 0x040 -#define S6_DMA_LOWWMRKIRQCLR 0x044 -#define S6_DMA_LOWWMRKIRQSET 0x048 -#define S6_DMA_MASTERERRINFO 0x04C -#define S6_DMA_MASTERERR_CHAN(n) (4*(n)) -#define S6_DMA_MASTERERR_CHAN_MASK 0xF -#define S6_DMA_DESCRFIFO0 0x050 -#define S6_DMA_DESCRFIFO1 0x054 -#define S6_DMA_DESCRFIFO2 0x058 -#define S6_DMA_DESCRFIFO2_AUTODISABLE 24 -#define S6_DMA_DESCRFIFO3 0x05C -#define S6_DMA_MASTER0START 0x060 -#define S6_DMA_MASTER0END 0x064 -#define S6_DMA_MASTER1START 0x068 -#define S6_DMA_MASTER1END 0x06C -#define S6_DMA_NEXTFREE 0x070 -#define S6_DMA_NEXTFREE_CHAN 0 -#define S6_DMA_NEXTFREE_CHAN_MASK 0x1F -#define S6_DMA_NEXTFREE_ENA 16 -#define S6_DMA_NEXTFREE_ENA_MASK ((1 << 16) - 1) -#define S6_DMA_DPORTCTRLGRP(p) ((p) * 4 + 0x074) -#define S6_DMA_DPORTCTRLGRP_FRAMEREP 0 -#define S6_DMA_DPORTCTRLGRP_NRCHANS 1 -#define S6_DMA_DPORTCTRLGRP_NRCHANS_1 0 -#define S6_DMA_DPORTCTRLGRP_NRCHANS_3 1 -#define S6_DMA_DPORTCTRLGRP_NRCHANS_4 2 -#define S6_DMA_DPORTCTRLGRP_NRCHANS_2 3 -#define S6_DMA_DPORTCTRLGRP_ENA 31 - - -/* DMA per channel */ - -#define DMA_CHNL(dmac, n) ((dmac) + 0x1000 + (n) * 0x100) -#define DMA_INDEX_CHNL(addr) (((addr) >> 8) & 0xF) -#define DMA_MASK_DMAC(addr) ((addr) & 0xFFFF0000) -#define S6_DMA_CHNCTRL 0x000 -#define S6_DMA_CHNCTRL_ENABLE 0 -#define S6_DMA_CHNCTRL_PAUSE 1 -#define S6_DMA_CHNCTRL_PRIO 2 -#define S6_DMA_CHNCTRL_PRIO_MASK 3 -#define S6_DMA_CHNCTRL_PERIPHXFER 4 -#define S6_DMA_CHNCTRL_PERIPHENA 5 -#define S6_DMA_CHNCTRL_SRCINC 6 -#define S6_DMA_CHNCTRL_DSTINC 7 -#define S6_DMA_CHNCTRL_BURSTLOG 8 -#define S6_DMA_CHNCTRL_BURSTLOG_MASK 7 -#define S6_DMA_CHNCTRL_DESCFIFODEPTH 12 -#define S6_DMA_CHNCTRL_DESCFIFODEPTH_MASK 0x1F -#define S6_DMA_CHNCTRL_DESCFIFOFULL 17 -#define S6_DMA_CHNCTRL_BWCONSEL 18 -#define S6_DMA_CHNCTRL_BWCONENA 19 -#define S6_DMA_CHNCTRL_PENDGCNTSTAT 20 -#define S6_DMA_CHNCTRL_PENDGCNTSTAT_MASK 0x3F -#define S6_DMA_CHNCTRL_LOWWMARK 26 -#define S6_DMA_CHNCTRL_LOWWMARK_MASK 0xF -#define S6_DMA_CHNCTRL_TSTAMP 30 -#define S6_DMA_TERMCNTNB 0x004 -#define S6_DMA_TERMCNTNB_MASK 0xFFFF -#define S6_DMA_TERMCNTTMO 0x008 -#define S6_DMA_TERMCNTSTAT 0x00C -#define S6_DMA_TERMCNTSTAT_MASK 0xFF -#define S6_DMA_CMONCHUNK 0x010 -#define S6_DMA_SRCSKIP 0x014 -#define S6_DMA_DSTSKIP 0x018 -#define S6_DMA_CUR_SRC 0x024 -#define S6_DMA_CUR_DST 0x028 -#define S6_DMA_TIMESTAMP 0x030 - -/* DMA channel lists */ - -#define S6_DPDMA_CHAN(stream, channel) (4 * (stream) + (channel)) -#define S6_DPDMA_NB 16 - -#define S6_HIFDMA_GMACTX 0 -#define S6_HIFDMA_GMACRX 1 -#define S6_HIFDMA_I2S0 2 -#define S6_HIFDMA_I2S1 3 -#define S6_HIFDMA_EGIB 4 -#define S6_HIFDMA_PCITX 5 -#define S6_HIFDMA_PCIRX 6 -#define S6_HIFDMA_NB 7 - -#define S6_NIDMA_NB 4 - -#define S6_LMSDMA_NB 12 - -/* controller access */ - -#define S6_DMAC_NB 4 -#define S6_DMAC_INDEX(dmac) (((unsigned)(dmac) >> 18) % S6_DMAC_NB) - -struct s6dmac_ctrl { - u32 dmac; - spinlock_t lock; - u8 chan_nb; -}; - -extern struct s6dmac_ctrl s6dmac_ctrl[S6_DMAC_NB]; - - -/* DMA control, per channel */ - -static inline int s6dmac_fifo_full(u32 dmac, int chan) -{ - return (readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) - & (1 << S6_DMA_CHNCTRL_DESCFIFOFULL)) && 1; -} - -static inline int s6dmac_termcnt_irq(u32 dmac, int chan) -{ - u32 m = 1 << chan; - int r = (readl(dmac + S6_DMA_TERMCNTIRQSTAT) & m) && 1; - if (r) - writel(m, dmac + S6_DMA_TERMCNTIRQCLR); - return r; -} - -static inline int s6dmac_pendcnt_irq(u32 dmac, int chan) -{ - u32 m = 1 << chan; - int r = (readl(dmac + S6_DMA_PENDCNTIRQSTAT) & m) && 1; - if (r) - writel(m, dmac + S6_DMA_PENDCNTIRQCLR); - return r; -} - -static inline int s6dmac_lowwmark_irq(u32 dmac, int chan) -{ - int r = (readl(dmac + S6_DMA_LOWWMRKIRQSTAT) & (1 << chan)) ? 1 : 0; - if (r) - writel(1 << chan, dmac + S6_DMA_LOWWMRKIRQCLR); - return r; -} - -static inline u32 s6dmac_pending_count(u32 dmac, int chan) -{ - return (readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) - >> S6_DMA_CHNCTRL_PENDGCNTSTAT) - & S6_DMA_CHNCTRL_PENDGCNTSTAT_MASK; -} - -static inline void s6dmac_set_terminal_count(u32 dmac, int chan, u32 n) -{ - n &= S6_DMA_TERMCNTNB_MASK; - n |= readl(DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB) - & ~S6_DMA_TERMCNTNB_MASK; - writel(n, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB); -} - -static inline u32 s6dmac_get_terminal_count(u32 dmac, int chan) -{ - return (readl(DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB)) - & S6_DMA_TERMCNTNB_MASK; -} - -static inline u32 s6dmac_timestamp(u32 dmac, int chan) -{ - return readl(DMA_CHNL(dmac, chan) + S6_DMA_TIMESTAMP); -} - -static inline u32 s6dmac_cur_src(u32 dmac, int chan) -{ - return readl(DMA_CHNL(dmac, chan) + S6_DMA_CUR_SRC); -} - -static inline u32 s6dmac_cur_dst(u32 dmac, int chan) -{ - return readl(DMA_CHNL(dmac, chan) + S6_DMA_CUR_DST); -} - -static inline void s6dmac_disable_chan(u32 dmac, int chan) -{ - u32 ctrl; - writel(readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) - & ~(1 << S6_DMA_CHNCTRL_ENABLE), - DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); - do - ctrl = readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); - while (ctrl & (1 << S6_DMA_CHNCTRL_ENABLE)); -} - -static inline void s6dmac_set_stride_skip(u32 dmac, int chan, - int comchunk, /* 0: disable scatter/gather */ - int srcskip, int dstskip) -{ - writel(comchunk, DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); - writel(srcskip, DMA_CHNL(dmac, chan) + S6_DMA_SRCSKIP); - writel(dstskip, DMA_CHNL(dmac, chan) + S6_DMA_DSTSKIP); -} - -static inline void s6dmac_enable_chan(u32 dmac, int chan, - int prio, /* 0 (highest) .. 3 (lowest) */ - int periphxfer, /* <0: disable p.req.line, 0..1: mode */ - int srcinc, int dstinc, /* 0: dont increment src/dst address */ - int comchunk, /* 0: disable scatter/gather */ - int srcskip, int dstskip, - int burstsize, /* 4 for I2S, 7 for everything else */ - int bandwidthconserve, /* <0: disable, 0..1: select */ - int lowwmark, /* 0..15 */ - int timestamp, /* 0: disable timestamp */ - int enable) /* 0: disable for now */ -{ - writel(1, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB); - writel(0, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTTMO); - writel(lowwmark << S6_DMA_CHNCTRL_LOWWMARK, - DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); - s6dmac_set_stride_skip(dmac, chan, comchunk, srcskip, dstskip); - writel(((enable ? 1 : 0) << S6_DMA_CHNCTRL_ENABLE) | - (prio << S6_DMA_CHNCTRL_PRIO) | - (((periphxfer > 0) ? 1 : 0) << S6_DMA_CHNCTRL_PERIPHXFER) | - (((periphxfer < 0) ? 0 : 1) << S6_DMA_CHNCTRL_PERIPHENA) | - ((srcinc ? 1 : 0) << S6_DMA_CHNCTRL_SRCINC) | - ((dstinc ? 1 : 0) << S6_DMA_CHNCTRL_DSTINC) | - (burstsize << S6_DMA_CHNCTRL_BURSTLOG) | - (((bandwidthconserve > 0) ? 1 : 0) << S6_DMA_CHNCTRL_BWCONSEL) | - (((bandwidthconserve < 0) ? 0 : 1) << S6_DMA_CHNCTRL_BWCONENA) | - (lowwmark << S6_DMA_CHNCTRL_LOWWMARK) | - ((timestamp ? 1 : 0) << S6_DMA_CHNCTRL_TSTAMP), - DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); -} - - -/* DMA control, per engine */ - -static inline unsigned _dmac_addr_index(u32 dmac) -{ - unsigned i = S6_DMAC_INDEX(dmac); - if (s6dmac_ctrl[i].dmac != dmac) - BUG(); - return i; -} - -static inline void _s6dmac_disable_error_irqs(u32 dmac, u32 mask) -{ - writel(mask, dmac + S6_DMA_TERMCNTIRQCLR); - writel(mask, dmac + S6_DMA_PENDCNTIRQCLR); - writel(mask, dmac + S6_DMA_LOWWMRKIRQCLR); - writel(readl(dmac + S6_DMA_INTENABLE0) - & ~((mask << S6_DMA_INT0_UNDER) | (mask << S6_DMA_INT0_OVER)), - dmac + S6_DMA_INTENABLE0); - writel(readl(dmac + S6_DMA_INTENABLE1) & ~(mask << S6_DMA_INT1_CHANNEL), - dmac + S6_DMA_INTENABLE1); - writel((mask << S6_DMA_INT0_UNDER) | (mask << S6_DMA_INT0_OVER), - dmac + S6_DMA_INTCLEAR0); - writel(mask << S6_DMA_INT1_CHANNEL, dmac + S6_DMA_INTCLEAR1); -} - -/* - * request channel from specified engine - * with chan<0, accept any channel - * further parameters see s6dmac_enable_chan - * returns < 0 upon error, channel nb otherwise - */ -static inline int s6dmac_request_chan(u32 dmac, int chan, - int prio, - int periphxfer, - int srcinc, int dstinc, - int comchunk, - int srcskip, int dstskip, - int burstsize, - int bandwidthconserve, - int lowwmark, - int timestamp, - int enable) -{ - int r = chan; - unsigned long flags; - spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; - spin_lock_irqsave(spinl, flags); - if (r < 0) { - r = (readl(dmac + S6_DMA_NEXTFREE) >> S6_DMA_NEXTFREE_CHAN) - & S6_DMA_NEXTFREE_CHAN_MASK; - } - if (r >= s6dmac_ctrl[_dmac_addr_index(dmac)].chan_nb) { - if (chan < 0) - r = -EBUSY; - else - r = -ENXIO; - } else if (((readl(dmac + S6_DMA_NEXTFREE) >> S6_DMA_NEXTFREE_ENA) - >> r) & 1) { - r = -EBUSY; - } else { - s6dmac_enable_chan(dmac, r, prio, periphxfer, - srcinc, dstinc, comchunk, srcskip, dstskip, burstsize, - bandwidthconserve, lowwmark, timestamp, enable); - } - spin_unlock_irqrestore(spinl, flags); - return r; -} - -static inline void s6dmac_put_fifo(u32 dmac, int chan, - u32 src, u32 dst, u32 size) -{ - unsigned long flags; - spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; - spin_lock_irqsave(spinl, flags); - writel(src, dmac + S6_DMA_DESCRFIFO0); - writel(dst, dmac + S6_DMA_DESCRFIFO1); - writel(size, dmac + S6_DMA_DESCRFIFO2); - writel(chan, dmac + S6_DMA_DESCRFIFO3); - spin_unlock_irqrestore(spinl, flags); -} - -static inline u32 s6dmac_channel_enabled(u32 dmac, int chan) -{ - return readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) & - (1 << S6_DMA_CHNCTRL_ENABLE); -} - -/* - * group 1-4 data port channels - * with port=0..3, nrch=1-4 channels, - * frrep=0/1 (dis- or enable frame repeat) - */ -static inline void s6dmac_dp_setup_group(u32 dmac, int port, - int nrch, int frrep) -{ - static const u8 mask[4] = {0, 3, 1, 2}; - BUG_ON(dmac != S6_REG_DPDMA); - if ((port < 0) || (port > 3) || (nrch < 1) || (nrch > 4)) - return; - writel((mask[nrch - 1] << S6_DMA_DPORTCTRLGRP_NRCHANS) - | ((frrep ? 1 : 0) << S6_DMA_DPORTCTRLGRP_FRAMEREP), - dmac + S6_DMA_DPORTCTRLGRP(port)); -} - -static inline void s6dmac_dp_switch_group(u32 dmac, int port, int enable) -{ - u32 tmp; - BUG_ON(dmac != S6_REG_DPDMA); - tmp = readl(dmac + S6_DMA_DPORTCTRLGRP(port)); - if (enable) - tmp |= (1 << S6_DMA_DPORTCTRLGRP_ENA); - else - tmp &= ~(1 << S6_DMA_DPORTCTRLGRP_ENA); - writel(tmp, dmac + S6_DMA_DPORTCTRLGRP(port)); -} - -extern void s6dmac_put_fifo_cache(u32 dmac, int chan, - u32 src, u32 dst, u32 size); -extern void s6dmac_disable_error_irqs(u32 dmac, u32 mask); -extern u32 s6dmac_int_sources(u32 dmac, u32 channel); -extern void s6dmac_release_chan(u32 dmac, int chan); - -#endif /* __ASM_XTENSA_S6000_DMAC_H */ diff --git a/arch/xtensa/variants/s6000/include/variant/gpio.h b/arch/xtensa/variants/s6000/include/variant/gpio.h deleted file mode 100644 index 8484ab0df461..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _XTENSA_VARIANT_S6000_GPIO_H -#define _XTENSA_VARIANT_S6000_GPIO_H - -extern int s6_gpio_init(u32 afsel); - -#endif /* _XTENSA_VARIANT_S6000_GPIO_H */ diff --git a/arch/xtensa/variants/s6000/include/variant/hardware.h b/arch/xtensa/variants/s6000/include/variant/hardware.h deleted file mode 100644 index 5d9ba098d84a..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/hardware.h +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef __XTENSA_S6000_HARDWARE_H -#define __XTENSA_S6000_HARDWARE_H - -#define S6_SCLK 1843200 - -#define S6_MEM_REG 0x20000000 -#define S6_MEM_EFI 0x33F00000 -#define S6_MEM_PCIE_DATARAM1 0x34000000 -#define S6_MEM_XLMI 0x37F80000 -#define S6_MEM_PIF_DATARAM1 0x37FFC000 -#define S6_MEM_GMAC 0x38000000 -#define S6_MEM_I2S 0x3A000000 -#define S6_MEM_EGIB 0x3C000000 -#define S6_MEM_PCIE_CFG 0x3E000000 -#define S6_MEM_PIF_DATARAM 0x3FFE0000 -#define S6_MEM_XLMI_DATARAM 0x3FFF0000 -#define S6_MEM_DDR 0x40000000 -#define S6_MEM_PCIE_APER 0xC0000000 -#define S6_MEM_AUX 0xF0000000 - -/* Device addresses */ - -#define S6_REG_SCB S6_MEM_REG -#define S6_REG_NB (S6_REG_SCB + 0x10000) -#define S6_REG_LMSDMA (S6_REG_SCB + 0x20000) -#define S6_REG_NI (S6_REG_SCB + 0x30000) -#define S6_REG_NIDMA (S6_REG_SCB + 0x40000) -#define S6_REG_NS (S6_REG_SCB + 0x50000) -#define S6_REG_DDR (S6_REG_SCB + 0x60000) -#define S6_REG_GREG1 (S6_REG_SCB + 0x70000) -#define S6_REG_DP (S6_REG_SCB + 0x80000) -#define S6_REG_DPDMA (S6_REG_SCB + 0x90000) -#define S6_REG_EGIB (S6_REG_SCB + 0xA0000) -#define S6_REG_PCIE (S6_REG_SCB + 0xB0000) -#define S6_REG_I2S (S6_REG_SCB + 0xC0000) -#define S6_REG_GMAC (S6_REG_SCB + 0xD0000) -#define S6_REG_HIFDMA (S6_REG_SCB + 0xE0000) -#define S6_REG_GREG2 (S6_REG_SCB + 0xF0000) - -#define S6_REG_APB S6_REG_SCB -#define S6_REG_UART (S6_REG_APB + 0x0000) -#define S6_REG_INTC (S6_REG_APB + 0x2000) -#define S6_REG_SPI (S6_REG_APB + 0x3000) -#define S6_REG_I2C (S6_REG_APB + 0x4000) -#define S6_REG_GPIO (S6_REG_APB + 0x8000) - -/* Global register block */ - -#define S6_GREG1_PLL_LOCKCLEAR 0x000 -#define S6_GREG1_PLL_LOCK_SYS 0 -#define S6_GREG1_PLL_LOCK_IO 1 -#define S6_GREG1_PLL_LOCK_AIM 2 -#define S6_GREG1_PLL_LOCK_DP0 3 -#define S6_GREG1_PLL_LOCK_DP2 4 -#define S6_GREG1_PLL_LOCK_DDR 5 -#define S6_GREG1_PLL_LOCKSTAT 0x004 -#define S6_GREG1_PLL_LOCKSTAT_CURLOCK 0 -#define S6_GREG1_PLL_LOCKSTAT_EVERUNLCK 8 -#define S6_GREG1_PLLSEL 0x010 -#define S6_GREG1_PLLSEL_AIM 0 -#define S6_GREG1_PLLSEL_AIM_DDR2 0 -#define S6_GREG1_PLLSEL_AIM_300MHZ 1 -#define S6_GREG1_PLLSEL_AIM_240MHZ 2 -#define S6_GREG1_PLLSEL_AIM_200MHZ 3 -#define S6_GREG1_PLLSEL_AIM_150MHZ 4 -#define S6_GREG1_PLLSEL_AIM_120MHZ 5 -#define S6_GREG1_PLLSEL_AIM_40MHZ 6 -#define S6_GREG1_PLLSEL_AIM_PLLAIMREF 7 -#define S6_GREG1_PLLSEL_AIM_MASK 7 -#define S6_GREG1_PLLSEL_DDR 8 -#define S6_GREG1_PLLSEL_DDR_HS 0 -#define S6_GREG1_PLLSEL_DDR_333MHZ 1 -#define S6_GREG1_PLLSEL_DDR_250MHZ 2 -#define S6_GREG1_PLLSEL_DDR_200MHZ 3 -#define S6_GREG1_PLLSEL_DDR_167MHZ 4 -#define S6_GREG1_PLLSEL_DDR_100MHZ 5 -#define S6_GREG1_PLLSEL_DDR_33MHZ 6 -#define S6_GREG1_PLLSEL_DDR_PLLIOREF 7 -#define S6_GREG1_PLLSEL_DDR_MASK 7 -#define S6_GREG1_PLLSEL_GMAC 16 -#define S6_GREG1_PLLSEL_GMAC_125MHZ 0 -#define S6_GREG1_PLLSEL_GMAC_25MHZ 1 -#define S6_GREG1_PLLSEL_GMAC_2500KHZ 2 -#define S6_GREG1_PLLSEL_GMAC_EXTERN 3 -#define S6_GREG1_PLLSEL_GMAC_MASK 3 -#define S6_GREG1_PLLSEL_GMII 18 -#define S6_GREG1_PLLSEL_GMII_111MHZ 0 -#define S6_GREG1_PLLSEL_GMII_IOREF 1 -#define S6_GREG1_PLLSEL_GMII_NONE 2 -#define S6_GREG1_PLLSEL_GMII_125MHZ 3 -#define S6_GREG1_PLLSEL_GMII_MASK 3 -#define S6_GREG1_SYSUNLOCKCNT 0x020 -#define S6_GREG1_IOUNLOCKCNT 0x024 -#define S6_GREG1_AIMUNLOCKCNT 0x028 -#define S6_GREG1_DP0UNLOCKCNT 0x02C -#define S6_GREG1_DP2UNLOCKCNT 0x030 -#define S6_GREG1_DDRUNLOCKCNT 0x034 -#define S6_GREG1_CLKBAL0 0x040 -#define S6_GREG1_CLKBAL0_LSGB 0 -#define S6_GREG1_CLKBAL0_LSPX 8 -#define S6_GREG1_CLKBAL0_MEMDO 16 -#define S6_GREG1_CLKBAL0_HSXT1 24 -#define S6_GREG1_CLKBAL1 0x044 -#define S6_GREG1_CLKBAL1_HSISEF 0 -#define S6_GREG1_CLKBAL1_HSNI 8 -#define S6_GREG1_CLKBAL1_HSNS 16 -#define S6_GREG1_CLKBAL1_HSISEFCFG 24 -#define S6_GREG1_CLKBAL2 0x048 -#define S6_GREG1_CLKBAL2_LSNB 0 -#define S6_GREG1_CLKBAL2_LSSB 8 -#define S6_GREG1_CLKBAL2_LSREST 24 -#define S6_GREG1_CLKBAL3 0x04C -#define S6_GREG1_CLKBAL3_ISEFXAD 0 -#define S6_GREG1_CLKBAL3_ISEFLMS 8 -#define S6_GREG1_CLKBAL3_ISEFISEF 16 -#define S6_GREG1_CLKBAL3_DDRDD 24 -#define S6_GREG1_CLKBAL4 0x050 -#define S6_GREG1_CLKBAL4_DDRDP 0 -#define S6_GREG1_CLKBAL4_DDRDO 8 -#define S6_GREG1_CLKBAL4_DDRNB 16 -#define S6_GREG1_CLKBAL4_DDRLMS 24 -#define S6_GREG1_BLOCKENA 0x100 -#define S6_GREG1_BLOCK_DDR 0 -#define S6_GREG1_BLOCK_DP 1 -#define S6_GREG1_BLOCK_NSNI 2 -#define S6_GREG1_BLOCK_PCIE 3 -#define S6_GREG1_BLOCK_GMAC 4 -#define S6_GREG1_BLOCK_I2S 5 -#define S6_GREG1_BLOCK_EGIB 6 -#define S6_GREG1_BLOCK_SB 7 -#define S6_GREG1_BLOCK_XT1 8 -#define S6_GREG1_CLKGATE 0x104 -#define S6_GREG1_BGATE_AIMNORTH 9 -#define S6_GREG1_BGATE_AIMEAST 10 -#define S6_GREG1_BGATE_AIMWEST 11 -#define S6_GREG1_BGATE_AIMSOUTH 12 -#define S6_GREG1_CHIPRES 0x108 -#define S6_GREG1_CHIPRES_SOFTRES 0 -#define S6_GREG1_CHIPRES_LOSTLOCK 1 -#define S6_GREG1_RESETCAUSE 0x10C -#define S6_GREG1_RESETCAUSE_RESETN 0 -#define S6_GREG1_RESETCAUSE_GLOBAL 1 -#define S6_GREG1_RESETCAUSE_WDOGTIMER 2 -#define S6_GREG1_RESETCAUSE_SWCHIP 3 -#define S6_GREG1_RESETCAUSE_PLLSYSLOSS 4 -#define S6_GREG1_RESETCAUSE_PCIE 5 -#define S6_GREG1_RESETCAUSE_CREATEDGLOB 6 -#define S6_GREG1_REFCLOCKCNT 0x110 -#define S6_GREG1_RESETTIMER 0x114 -#define S6_GREG1_NMITIMER 0x118 -#define S6_GREG1_GLOBAL_TIMER 0x11C -#define S6_GREG1_TIMER0 0x180 -#define S6_GREG1_TIMER1 0x184 -#define S6_GREG1_UARTCLOCKSEL 0x204 -#define S6_GREG1_CHIPVERSPACKG 0x208 -#define S6_GREG1_CHIPVERSPACKG_CHIPVID 0 -#define S6_GREG1_CHIPVERSPACKG_PACKSEL 8 -#define S6_GREG1_ONDIETERMCTRL 0x20C -#define S6_GREG1_ONDIETERMCTRL_WEST 0 -#define S6_GREG1_ONDIETERMCTRL_NORTH 2 -#define S6_GREG1_ONDIETERMCTRL_EAST 4 -#define S6_GREG1_ONDIETERMCTRL_SOUTH 6 -#define S6_GREG1_ONDIETERMCTRL_NONE 0 -#define S6_GREG1_ONDIETERMCTRL_75OHM 2 -#define S6_GREG1_ONDIETERMCTRL_MASK 3 -#define S6_GREG1_BOOT_CFG0 0x210 -#define S6_GREG1_BOOT_CFG0_AIMSTRONG 1 -#define S6_GREG1_BOOT_CFG0_MINIBOOTDL 2 -#define S6_GREG1_BOOT_CFG0_OCDGPIO8SET 5 -#define S6_GREG1_BOOT_CFG0_OCDGPIOENA 6 -#define S6_GREG1_BOOT_CFG0_DOWNSTREAM 7 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV 8 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_300MHZ 1 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_240MHZ 2 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_200MHZ 3 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_150MHZ 4 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_120MHZ 5 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_40MHZ 6 -#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_MASK 7 -#define S6_GREG1_BOOT_CFG0_BALHSLMS 12 -#define S6_GREG1_BOOT_CFG0_BALHSNB 18 -#define S6_GREG1_BOOT_CFG0_BALHSXAD 24 -#define S6_GREG1_BOOT_CFG1 0x214 -#define S6_GREG1_BOOT_CFG1_PCIE1LANE 1 -#define S6_GREG1_BOOT_CFG1_MPLLPRESCALE 2 -#define S6_GREG1_BOOT_CFG1_MPLLNCY 4 -#define S6_GREG1_BOOT_CFG1_MPLLNCY5 9 -#define S6_GREG1_BOOT_CFG1_BALHSREST 14 -#define S6_GREG1_BOOT_CFG1_BALHSPSMEMS 20 -#define S6_GREG1_BOOT_CFG1_BALLSGI 26 -#define S6_GREG1_BOOT_CFG2 0x218 -#define S6_GREG1_BOOT_CFG2_PEID 0 -#define S6_GREG1_BOOT_CFG3 0x21C -#define S6_GREG1_DRAMBUSYHOLDOF 0x220 -#define S6_GREG1_DRAMBUSYHOLDOF_XT0 0 -#define S6_GREG1_DRAMBUSYHOLDOF_XT1 4 -#define S6_GREG1_DRAMBUSYHOLDOF_XT_MASK 7 -#define S6_GREG1_PCIEBAR1SIZE 0x224 -#define S6_GREG1_PCIEBAR2SIZE 0x228 -#define S6_GREG1_PCIEVENDOR 0x22C -#define S6_GREG1_PCIEDEVICE 0x230 -#define S6_GREG1_PCIEREV 0x234 -#define S6_GREG1_PCIECLASS 0x238 -#define S6_GREG1_XT1DCACHEMISS 0x240 -#define S6_GREG1_XT1ICACHEMISS 0x244 -#define S6_GREG1_HWSEMAPHORE(n) (0x400 + 4 * (n)) -#define S6_GREG1_HWSEMAPHORE_NB 16 - -/* peripheral interrupt numbers */ - -#define S6_INTC_GPIO(n) (n) /* 0..3 */ -#define S6_INTC_I2C 4 -#define S6_INTC_SPI 5 -#define S6_INTC_NB_ERR 6 -#define S6_INTC_DMA_LMSERR 7 -#define S6_INTC_DMA_LMSLOWWMRK(n) (8 + (n)) /* 0..11 */ -#define S6_INTC_DMA_LMSPENDCNT(n) (20 + (n)) /* 0..11 */ -#define S6_INTC_DMA HOSTLOWWMRK(n) (32 + (n)) /* 0..6 */ -#define S6_INTC_DMA_HOSTPENDCNT(n) (39 + (n)) /* 0..6 */ -#define S6_INTC_DMA_HOSTERR 46 -#define S6_INTC_UART(n) (47 + (n)) /* 0..1 */ -#define S6_INTC_XAD 49 -#define S6_INTC_NI_ERR 50 -#define S6_INTC_NI_INFIFOFULL 51 -#define S6_INTC_DMA_NIERR 52 -#define S6_INTC_DMA_NILOWWMRK(n) (53 + (n)) /* 0..3 */ -#define S6_INTC_DMA_NIPENDCNT(n) (57 + (n)) /* 0..3 */ -#define S6_INTC_DDR 61 -#define S6_INTC_NS_ERR 62 -#define S6_INTC_EFI_CFGERR 63 -#define S6_INTC_EFI_ISEFTEST 64 -#define S6_INTC_EFI_WRITEERR 65 -#define S6_INTC_NMI_TIMER 66 -#define S6_INTC_PLLLOCK_SYS 67 -#define S6_INTC_PLLLOCK_IO 68 -#define S6_INTC_PLLLOCK_AIM 69 -#define S6_INTC_PLLLOCK_DP0 70 -#define S6_INTC_PLLLOCK_DP2 71 -#define S6_INTC_I2S_ERR 72 -#define S6_INTC_GMAC_STAT 73 -#define S6_INTC_GMAC_ERR 74 -#define S6_INTC_GIB_ERR 75 -#define S6_INTC_PCIE_ERR 76 -#define S6_INTC_PCIE_MSI(n) (77 + (n)) /* 0..3 */ -#define S6_INTC_PCIE_INTA 81 -#define S6_INTC_PCIE_INTB 82 -#define S6_INTC_PCIE_INTC 83 -#define S6_INTC_PCIE_INTD 84 -#define S6_INTC_SW(n) (85 + (n)) /* 0..9 */ -#define S6_INTC_SW_ENABLE(n) (85 + 256 + (n)) -#define S6_INTC_DMA_DP_ERR 95 -#define S6_INTC_DMA_DPLOWWMRK(n) (96 + (n)) /* 0..3 */ -#define S6_INTC_DMA_DPPENDCNT(n) (100 + (n)) /* 0..3 */ -#define S6_INTC_DMA_DPTERMCNT(n) (104 + (n)) /* 0..3 */ -#define S6_INTC_TIMER0 108 -#define S6_INTC_TIMER1 109 -#define S6_INTC_DMA_HOSTTERMCNT(n) (110 + (n)) /* 0..6 */ - -#endif /* __XTENSA_S6000_HARDWARE_H */ diff --git a/arch/xtensa/variants/s6000/include/variant/irq.h b/arch/xtensa/variants/s6000/include/variant/irq.h deleted file mode 100644 index 39ca751a6255..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/irq.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _XTENSA_S6000_IRQ_H -#define _XTENSA_S6000_IRQ_H - -#define VARIANT_NR_IRQS 8 /* GPIO interrupts */ - -extern void variant_irq_enable(unsigned int irq); - -#endif /* __XTENSA_S6000_IRQ_H */ diff --git a/arch/xtensa/variants/s6000/include/variant/tie-asm.h b/arch/xtensa/variants/s6000/include/variant/tie-asm.h deleted file mode 100644 index f02d0a3a2e20..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/tie-asm.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * This header file contains assembly-language definitions (assembly - * macros, etc.) for this specific Xtensa processor's TIE extensions - * and options. It is customized to this Xtensa processor configuration. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999-2008 Tensilica Inc. - */ - -#ifndef _XTENSA_CORE_TIE_ASM_H -#define _XTENSA_CORE_TIE_ASM_H - -/* Selection parameter values for save-area save/restore macros: */ -/* Option vs. TIE: */ -#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ -#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ -/* Whether used automatically by compiler: */ -#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ -#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ -/* ABI handling across function calls: */ -#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ -#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ -#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ -/* Misc */ -#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ - - - -/* Macro to save all non-coprocessor (extra) custom TIE and optional state - * (not including zero-overhead loop registers). - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) - */ - .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 1024-4, 4, 4 - rsr \at1, BR // boolean option - s32i \at1, \ptr, .Lxchal_ofs_ + 0 - .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 - .endif - .endm // xchal_ncp_store - -/* Macro to save all non-coprocessor (extra) custom TIE and optional state - * (not including zero-overhead loop registers). - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) - */ - .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 1024-4, 4, 4 - l32i \at1, \ptr, .Lxchal_ofs_ + 0 - wsr \at1, BR // boolean option - .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 - .endif - .endm // xchal_ncp_load - - - -#define XCHAL_NCP_NUM_ATMPS 1 - - - -/* Macro to save the state of TIE coprocessor FPU. - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed) - */ -#define xchal_cp_FPU_store xchal_cp0_store -/* #define xchal_cp_FPU_store_a2 xchal_cp0_store a2 a3 a4 a5 a6 */ - .macro xchal_cp0_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 0, 1, 16 - rur232 \at1 // FCR - s32i \at1, \ptr, 0 - rur233 \at1 // FSR - s32i \at1, \ptr, 4 - SSI f0, \ptr, 8 - SSI f1, \ptr, 12 - SSI f2, \ptr, 16 - SSI f3, \ptr, 20 - SSI f4, \ptr, 24 - SSI f5, \ptr, 28 - SSI f6, \ptr, 32 - SSI f7, \ptr, 36 - SSI f8, \ptr, 40 - SSI f9, \ptr, 44 - SSI f10, \ptr, 48 - SSI f11, \ptr, 52 - SSI f12, \ptr, 56 - SSI f13, \ptr, 60 - SSI f14, \ptr, 64 - SSI f15, \ptr, 68 - .set .Lxchal_ofs_, .Lxchal_ofs_ + 72 - .endif - .endm // xchal_cp0_store - -/* Macro to restore the state of TIE coprocessor FPU. - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed) - */ -#define xchal_cp_FPU_load xchal_cp0_load -/* #define xchal_cp_FPU_load_a2 xchal_cp0_load a2 a3 a4 a5 a6 */ - .macro xchal_cp0_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 0, 1, 16 - l32i \at1, \ptr, 0 - wur232 \at1 // FCR - l32i \at1, \ptr, 4 - wur233 \at1 // FSR - LSI f0, \ptr, 8 - LSI f1, \ptr, 12 - LSI f2, \ptr, 16 - LSI f3, \ptr, 20 - LSI f4, \ptr, 24 - LSI f5, \ptr, 28 - LSI f6, \ptr, 32 - LSI f7, \ptr, 36 - LSI f8, \ptr, 40 - LSI f9, \ptr, 44 - LSI f10, \ptr, 48 - LSI f11, \ptr, 52 - LSI f12, \ptr, 56 - LSI f13, \ptr, 60 - LSI f14, \ptr, 64 - LSI f15, \ptr, 68 - .set .Lxchal_ofs_, .Lxchal_ofs_ + 72 - .endif - .endm // xchal_cp0_load - -#define XCHAL_CP0_NUM_ATMPS 1 - -/* Macro to save the state of TIE coprocessor XAD. - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed) - */ -#define xchal_cp_XAD_store xchal_cp6_store -/* #define xchal_cp_XAD_store_a2 xchal_cp6_store a2 a3 a4 a5 a6 */ - .macro xchal_cp6_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 0, 1, 16 - rur0 \at1 // LDCBHI - s32i \at1, \ptr, 0 - rur1 \at1 // LDCBLO - s32i \at1, \ptr, 4 - rur2 \at1 // STCBHI - s32i \at1, \ptr, 8 - rur3 \at1 // STCBLO - s32i \at1, \ptr, 12 - rur8 \at1 // LDBRBASE - s32i \at1, \ptr, 16 - rur9 \at1 // LDBROFF - s32i \at1, \ptr, 20 - rur10 \at1 // LDBRINC - s32i \at1, \ptr, 24 - rur11 \at1 // STBRBASE - s32i \at1, \ptr, 28 - rur12 \at1 // STBROFF - s32i \at1, \ptr, 32 - rur13 \at1 // STBRINC - s32i \at1, \ptr, 36 - rur24 \at1 // SCRATCH0 - s32i \at1, \ptr, 40 - rur25 \at1 // SCRATCH1 - s32i \at1, \ptr, 44 - rur26 \at1 // SCRATCH2 - s32i \at1, \ptr, 48 - rur27 \at1 // SCRATCH3 - s32i \at1, \ptr, 52 - WRAS128I wra0, \ptr, 64 - WRAS128I wra1, \ptr, 80 - WRAS128I wra2, \ptr, 96 - WRAS128I wra3, \ptr, 112 - WRAS128I wra4, \ptr, 128 - WRAS128I wra5, \ptr, 144 - WRAS128I wra6, \ptr, 160 - WRAS128I wra7, \ptr, 176 - WRAS128I wra8, \ptr, 192 - WRAS128I wra9, \ptr, 208 - WRAS128I wra10, \ptr, 224 - WRAS128I wra11, \ptr, 240 - WRAS128I wra12, \ptr, 256 - WRAS128I wra13, \ptr, 272 - WRAS128I wra14, \ptr, 288 - WRAS128I wra15, \ptr, 304 - WRBS128I wrb0, \ptr, 320 - WRBS128I wrb1, \ptr, 336 - WRBS128I wrb2, \ptr, 352 - WRBS128I wrb3, \ptr, 368 - WRBS128I wrb4, \ptr, 384 - WRBS128I wrb5, \ptr, 400 - WRBS128I wrb6, \ptr, 416 - WRBS128I wrb7, \ptr, 432 - WRBS128I wrb8, \ptr, 448 - WRBS128I wrb9, \ptr, 464 - WRBS128I wrb10, \ptr, 480 - WRBS128I wrb11, \ptr, 496 - WRBS128I wrb12, \ptr, 512 - WRBS128I wrb13, \ptr, 528 - WRBS128I wrb14, \ptr, 544 - WRBS128I wrb15, \ptr, 560 - .set .Lxchal_ofs_, .Lxchal_ofs_ + 576 - .endif - .endm // xchal_cp6_store - -/* Macro to restore the state of TIE coprocessor XAD. - * Save area ptr (clobbered): ptr (16 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed) - */ -#define xchal_cp_XAD_load xchal_cp6_load -/* #define xchal_cp_XAD_load_a2 xchal_cp6_load a2 a3 a4 a5 a6 */ - .macro xchal_cp6_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select - xchal_sa_align \ptr, 0, 0, 1, 16 - l32i \at1, \ptr, 0 - wur0 \at1 // LDCBHI - l32i \at1, \ptr, 4 - wur1 \at1 // LDCBLO - l32i \at1, \ptr, 8 - wur2 \at1 // STCBHI - l32i \at1, \ptr, 12 - wur3 \at1 // STCBLO - l32i \at1, \ptr, 16 - wur8 \at1 // LDBRBASE - l32i \at1, \ptr, 20 - wur9 \at1 // LDBROFF - l32i \at1, \ptr, 24 - wur10 \at1 // LDBRINC - l32i \at1, \ptr, 28 - wur11 \at1 // STBRBASE - l32i \at1, \ptr, 32 - wur12 \at1 // STBROFF - l32i \at1, \ptr, 36 - wur13 \at1 // STBRINC - l32i \at1, \ptr, 40 - wur24 \at1 // SCRATCH0 - l32i \at1, \ptr, 44 - wur25 \at1 // SCRATCH1 - l32i \at1, \ptr, 48 - wur26 \at1 // SCRATCH2 - l32i \at1, \ptr, 52 - wur27 \at1 // SCRATCH3 - WRBL128I wrb0, \ptr, 320 - WRBL128I wrb1, \ptr, 336 - WRBL128I wrb2, \ptr, 352 - WRBL128I wrb3, \ptr, 368 - WRBL128I wrb4, \ptr, 384 - WRBL128I wrb5, \ptr, 400 - WRBL128I wrb6, \ptr, 416 - WRBL128I wrb7, \ptr, 432 - WRBL128I wrb8, \ptr, 448 - WRBL128I wrb9, \ptr, 464 - WRBL128I wrb10, \ptr, 480 - WRBL128I wrb11, \ptr, 496 - WRBL128I wrb12, \ptr, 512 - WRBL128I wrb13, \ptr, 528 - WRBL128I wrb14, \ptr, 544 - WRBL128I wrb15, \ptr, 560 - WRAL128I wra0, \ptr, 64 - WRAL128I wra1, \ptr, 80 - WRAL128I wra2, \ptr, 96 - WRAL128I wra3, \ptr, 112 - WRAL128I wra4, \ptr, 128 - WRAL128I wra5, \ptr, 144 - WRAL128I wra6, \ptr, 160 - WRAL128I wra7, \ptr, 176 - WRAL128I wra8, \ptr, 192 - WRAL128I wra9, \ptr, 208 - WRAL128I wra10, \ptr, 224 - WRAL128I wra11, \ptr, 240 - WRAL128I wra12, \ptr, 256 - WRAL128I wra13, \ptr, 272 - WRAL128I wra14, \ptr, 288 - WRAL128I wra15, \ptr, 304 - .set .Lxchal_ofs_, .Lxchal_ofs_ + 576 - .endif - .endm // xchal_cp6_load - -#define XCHAL_CP6_NUM_ATMPS 1 -#define XCHAL_SA_NUM_ATMPS 1 - - /* Empty macros for unconfigured coprocessors: */ - .macro xchal_cp1_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp1_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm - -#endif /*_XTENSA_CORE_TIE_ASM_H*/ - diff --git a/arch/xtensa/variants/s6000/include/variant/tie.h b/arch/xtensa/variants/s6000/include/variant/tie.h deleted file mode 100644 index be7ea843d5df..000000000000 --- a/arch/xtensa/variants/s6000/include/variant/tie.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * This header file describes this specific Xtensa processor's TIE extensions - * that extend basic Xtensa core functionality. It is customized to this - * Xtensa processor configuration. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999-2008 Tensilica Inc. - */ - -#ifndef _XTENSA_CORE_TIE_H -#define _XTENSA_CORE_TIE_H - -#define XCHAL_CP_NUM 2 /* number of coprocessors */ -#define XCHAL_CP_MAX 7 /* max CP ID + 1 (0 if none) */ -#define XCHAL_CP_MASK 0x41 /* bitmask of all CPs by ID */ -#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ - -/* Basic parameters of each coprocessor: */ -#define XCHAL_CP0_NAME "FPU" -#define XCHAL_CP0_IDENT FPU -#define XCHAL_CP0_SA_SIZE 72 /* size of state save area */ -#define XCHAL_CP0_SA_ALIGN 4 /* min alignment of save area */ -#define XCHAL_CP_ID_FPU 0 /* coprocessor ID (0..7) */ -#define XCHAL_CP6_NAME "XAD" -#define XCHAL_CP6_IDENT XAD -#define XCHAL_CP6_SA_SIZE 576 /* size of state save area */ -#define XCHAL_CP6_SA_ALIGN 16 /* min alignment of save area */ -#define XCHAL_CP_ID_XAD 6 /* coprocessor ID (0..7) */ - -/* Filler info for unassigned coprocessors, to simplify arrays etc: */ -#define XCHAL_CP1_SA_SIZE 0 -#define XCHAL_CP1_SA_ALIGN 1 -#define XCHAL_CP2_SA_SIZE 0 -#define XCHAL_CP2_SA_ALIGN 1 -#define XCHAL_CP3_SA_SIZE 0 -#define XCHAL_CP3_SA_ALIGN 1 -#define XCHAL_CP4_SA_SIZE 0 -#define XCHAL_CP4_SA_ALIGN 1 -#define XCHAL_CP5_SA_SIZE 0 -#define XCHAL_CP5_SA_ALIGN 1 -#define XCHAL_CP7_SA_SIZE 0 -#define XCHAL_CP7_SA_ALIGN 1 - -/* Save area for non-coprocessor optional and custom (TIE) state: */ -#define XCHAL_NCP_SA_SIZE 4 -#define XCHAL_NCP_SA_ALIGN 4 - -/* Total save area for optional and custom state (NCP + CPn): */ -#define XCHAL_TOTAL_SA_SIZE 672 /* with 16-byte align padding */ -#define XCHAL_TOTAL_SA_ALIGN 16 /* actual minimum alignment */ - -/* - * Detailed contents of save areas. - * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) - * before expanding the XCHAL_xxx_SA_LIST() macros. - * - * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, - * dbnum,base,regnum,bitsz,gapsz,reset,x...) - * - * s = passed from XCHAL_*_LIST(s), eg. to select how to expand - * ccused = set if used by compiler without special options or code - * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) - * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) - * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) - * name = lowercase reg name (no quotes) - * galign = group byte alignment (power of 2) (galign >= align) - * align = register byte alignment (power of 2) - * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) - * (not including any pad bytes required to galign this or next reg) - * dbnum = unique target number f/debug (see ) - * base = reg shortname w/o index (or sr=special, ur=TIE user reg) - * regnum = reg index in regfile, or special/TIE-user reg number - * bitsz = number of significant bits (regfile width, or ur/sr mask bits) - * gapsz = intervening bits, if bitsz bits not stored contiguously - * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) - * reset = register reset value (or 0 if undefined at reset) - * x = reserved for future use (0 until then) - * - * To filter out certain registers, e.g. to expand only the non-global - * registers used by the compiler, you can do something like this: - * - * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) - * #define SELCC0(p...) - * #define SELCC1(abikind,p...) SELAK##abikind(p) - * #define SELAK0(p...) REG(p) - * #define SELAK1(p...) REG(p) - * #define SELAK2(p...) - * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ - * ...what you want to expand... - */ - -#define XCHAL_NCP_SA_NUM 1 -#define XCHAL_NCP_SA_LIST(s) \ - XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0) - -#define XCHAL_CP0_SA_NUM 18 -#define XCHAL_CP0_SA_LIST(s) \ - XCHAL_SA_REG(s,0,0,1,0, fcr, 4, 4, 4,0x03E8, ur,232, 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, fsr, 4, 4, 4,0x03E9, ur,233, 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f0, 4, 4, 4,0x0030, f,0 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f1, 4, 4, 4,0x0031, f,1 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f2, 4, 4, 4,0x0032, f,2 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f3, 4, 4, 4,0x0033, f,3 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f4, 4, 4, 4,0x0034, f,4 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f5, 4, 4, 4,0x0035, f,5 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f6, 4, 4, 4,0x0036, f,6 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f7, 4, 4, 4,0x0037, f,7 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f8, 4, 4, 4,0x0038, f,8 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f9, 4, 4, 4,0x0039, f,9 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f10, 4, 4, 4,0x003A, f,10 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f11, 4, 4, 4,0x003B, f,11 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f12, 4, 4, 4,0x003C, f,12 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f13, 4, 4, 4,0x003D, f,13 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f14, 4, 4, 4,0x003E, f,14 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, f15, 4, 4, 4,0x003F, f,15 , 32,0,0,0) - -#define XCHAL_CP1_SA_NUM 0 -#define XCHAL_CP1_SA_LIST(s) /* empty */ - -#define XCHAL_CP2_SA_NUM 0 -#define XCHAL_CP2_SA_LIST(s) /* empty */ - -#define XCHAL_CP3_SA_NUM 0 -#define XCHAL_CP3_SA_LIST(s) /* empty */ - -#define XCHAL_CP4_SA_NUM 0 -#define XCHAL_CP4_SA_LIST(s) /* empty */ - -#define XCHAL_CP5_SA_NUM 0 -#define XCHAL_CP5_SA_LIST(s) /* empty */ - -#define XCHAL_CP6_SA_NUM 46 -#define XCHAL_CP6_SA_LIST(s) \ - XCHAL_SA_REG(s,0,0,1,0, ldcbhi,16, 4, 4,0x0300, ur,0 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, ldcblo, 4, 4, 4,0x0301, ur,1 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, stcbhi, 4, 4, 4,0x0302, ur,2 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, stcblo, 4, 4, 4,0x0303, ur,3 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, ldbrbase, 4, 4, 4,0x0308, ur,8 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, ldbroff, 4, 4, 4,0x0309, ur,9 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, ldbrinc, 4, 4, 4,0x030A, ur,10 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, stbrbase, 4, 4, 4,0x030B, ur,11 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, stbroff, 4, 4, 4,0x030C, ur,12 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, stbrinc, 4, 4, 4,0x030D, ur,13 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, scratch0, 4, 4, 4,0x0318, ur,24 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, scratch1, 4, 4, 4,0x0319, ur,25 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, scratch2, 4, 4, 4,0x031A, ur,26 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,1,0, scratch3, 4, 4, 4,0x031B, ur,27 , 32,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra0,16,16,16,0x1010, wra,0 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra1,16,16,16,0x1011, wra,1 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra2,16,16,16,0x1012, wra,2 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra3,16,16,16,0x1013, wra,3 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra4,16,16,16,0x1014, wra,4 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra5,16,16,16,0x1015, wra,5 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra6,16,16,16,0x1016, wra,6 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra7,16,16,16,0x1017, wra,7 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra8,16,16,16,0x1018, wra,8 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra9,16,16,16,0x1019, wra,9 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra10,16,16,16,0x101A, wra,10 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra11,16,16,16,0x101B, wra,11 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra12,16,16,16,0x101C, wra,12 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra13,16,16,16,0x101D, wra,13 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra14,16,16,16,0x101E, wra,14 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wra15,16,16,16,0x101F, wra,15 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb0,16,16,16,0x1020, wrb,0 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb1,16,16,16,0x1021, wrb,1 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb2,16,16,16,0x1022, wrb,2 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb3,16,16,16,0x1023, wrb,3 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb4,16,16,16,0x1024, wrb,4 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb5,16,16,16,0x1025, wrb,5 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb6,16,16,16,0x1026, wrb,6 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb7,16,16,16,0x1027, wrb,7 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb8,16,16,16,0x1028, wrb,8 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb9,16,16,16,0x1029, wrb,9 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb10,16,16,16,0x102A, wrb,10 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb11,16,16,16,0x102B, wrb,11 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb12,16,16,16,0x102C, wrb,12 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb13,16,16,16,0x102D, wrb,13 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb14,16,16,16,0x102E, wrb,14 ,128,0,0,0) \ - XCHAL_SA_REG(s,0,0,2,0, wrb15,16,16,16,0x102F, wrb,15 ,128,0,0,0) - -#define XCHAL_CP7_SA_NUM 0 -#define XCHAL_CP7_SA_LIST(s) /* empty */ - -/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ -#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8 - -#endif /*_XTENSA_CORE_TIE_H*/ - diff --git a/arch/xtensa/variants/s6000/irq.c b/arch/xtensa/variants/s6000/irq.c deleted file mode 100644 index 81a241e79075..000000000000 --- a/arch/xtensa/variants/s6000/irq.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * s6000 irq crossbar - * - * Copyright (c) 2009 emlix GmbH - * Authors: Johannes Weiner - * Oskar Schirmer - */ -#include -#include -#include - -/* S6_REG_INTC */ -#define INTC_STATUS 0x000 -#define INTC_RAW 0x010 -#define INTC_STATUS_AG 0x100 -#define INTC_CFG(n) (0x200 + 4 * (n)) - -/* - * The s6000 has a crossbar that multiplexes interrupt output lines - * from the peripherals to input lines on the xtensa core. - * - * We leave the mapping decisions to the platform as it depends on the - * actually connected peripherals which distribution makes sense. - */ -extern const signed char *platform_irq_mappings[NR_IRQS]; - -static unsigned long scp_to_intc_enable[] = { -#define TO_INTC_ENABLE(n) (((n) << 1) + 1) - TO_INTC_ENABLE(0), - TO_INTC_ENABLE(1), - TO_INTC_ENABLE(2), - TO_INTC_ENABLE(3), - TO_INTC_ENABLE(4), - TO_INTC_ENABLE(5), - TO_INTC_ENABLE(6), - TO_INTC_ENABLE(7), - TO_INTC_ENABLE(8), - TO_INTC_ENABLE(9), - TO_INTC_ENABLE(10), - TO_INTC_ENABLE(11), - TO_INTC_ENABLE(12), - -1, - -1, - TO_INTC_ENABLE(13), - -1, - TO_INTC_ENABLE(14), - -1, - TO_INTC_ENABLE(15), -#undef TO_INTC_ENABLE -}; - -static void irq_set(unsigned int irq, int enable) -{ - unsigned long en; - const signed char *m = platform_irq_mappings[irq]; - - if (!m) - return; - en = enable ? scp_to_intc_enable[irq] : 0; - while (*m >= 0) { - writel(en, S6_REG_INTC + INTC_CFG(*m)); - m++; - } -} - -void variant_irq_enable(unsigned int irq) -{ - irq_set(irq, 1); -} - -void variant_irq_disable(unsigned int irq) -{ - irq_set(irq, 0); -} -- GitLab From 9208247d74bc52dcaf370ba3cee29b5e8775464b Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Tue, 21 Oct 2014 10:38:38 +0200 Subject: [PATCH 0975/9457] mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz When the new CONFIG_MAC80211_RC_MINSTREL_VHT is not set (default 'N'), there is no behavioral change including in sampling and MCS_GROUP_RATES remains 8. Otherwise MCS_GROUP_RATES is 10, and a module parameter *vht_only* (default 'true'), restricts the rates selection to VHT when VHT is supported. Regarding the debugfs stats buffer: It is explicitly increased from 8k to 32k to fit every rates incl. when both HT and VHT rates are enabled, as for the format, before: type rate tpt eprob *prob ret *ok(*cum) ok( cum) HT20/LGI ABCDP MCS0 0.0 0.0 0.0 1 0( 0) 0( 0) after: type rate tpt eprob *prob ret *ok(*cum) ok( cum) HT20/LGI ABCDP MCS0 0.0 0.0 0.0 1 0( 0) 0( 0) VHT40/LGI MCS5/2 0.0 0.0 0.0 0 0( 0) 0( 0) Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/Kconfig | 7 + net/mac80211/rc80211_minstrel_ht.c | 216 +++++++++++++++++++-- net/mac80211/rc80211_minstrel_ht.h | 17 +- net/mac80211/rc80211_minstrel_ht_debugfs.c | 23 ++- 4 files changed, 241 insertions(+), 22 deletions(-) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index aeb6a483b3bc..67cf8125d75d 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -33,6 +33,13 @@ config MAC80211_RC_MINSTREL_HT ---help--- This option enables the 'minstrel_ht' TX rate control algorithm +config MAC80211_RC_MINSTREL_VHT + bool "Minstrel 802.11ac support" if EXPERT + depends on MAC80211_RC_MINSTREL_HT + default n + ---help--- + This option enables VHT in the 'minstrel_ht' TX rate control algorithm + choice prompt "Default rate control algorithm" depends on MAC80211_HAS_RC diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index e760d3d71fe1..46666818719b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "rate.h" @@ -36,6 +37,7 @@ #define BW_20 0 #define BW_40 1 +#define BW_80 2 /* * Define group sort order: HT40 -> SGI -> #streams @@ -66,6 +68,47 @@ } \ } +#define VHT_GROUP_IDX(_streams, _sgi, _bw) \ + (MINSTREL_VHT_GROUP_0 + \ + MINSTREL_MAX_STREAMS * 2 * (_bw) + \ + MINSTREL_MAX_STREAMS * (_sgi) + \ + (_streams) - 1) + +#define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +#define VHT_GROUP(_streams, _sgi, _bw) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ + (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH : \ + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 117, 54, 26)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 234, 108, 52)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 351, 162, 78)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 468, 216, 104)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 702, 324, 156)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 936, 432, 208)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1053, 486, 234)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1170, 540, 260)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1404, 648, 312)), \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1560, 720, 346)) \ + } \ +} + #define CCK_DURATION(_bitrate, _short, _len) \ (1000 * (10 /* SIFS */ + \ (_short ? 72 + 24 : 144 + 48) + \ @@ -91,6 +134,13 @@ } \ } +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +static bool minstrel_vht_only = true; +module_param(minstrel_vht_only, bool, 0644); +MODULE_PARM_DESC(minstrel_vht_only, + "Use only VHT rates when VHT is supported by sta."); +#endif + /* * To enable sufficiently targeted rate sampling, MCS rates are divided into * groups, based on the number of streams and flags (HT40, SGI) that they @@ -124,15 +174,91 @@ const struct mcs_group minstrel_mcs_groups[] = { MCS_GROUP(3, 1, BW_40), #endif - CCK_GROUP -}; + CCK_GROUP, + +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_20), +#endif + + VHT_GROUP(1, 1, BW_20), + VHT_GROUP(2, 1, BW_20), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_20), +#endif + VHT_GROUP(1, 0, BW_40), + VHT_GROUP(2, 0, BW_40), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_40), +#endif + + VHT_GROUP(1, 1, BW_40), + VHT_GROUP(2, 1, BW_40), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_40), +#endif + + VHT_GROUP(1, 0, BW_80), + VHT_GROUP(2, 0, BW_80), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 0, BW_80), +#endif + + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), +#if MINSTREL_MAX_STREAMS >= 3 + VHT_GROUP(3, 1, BW_80), +#endif +#endif +}; static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; static void minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); +/* + * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer) + * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1 + * + * Returns the valid mcs map for struct minstrel_mcs_group_data.supported + */ +static u16 +minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map) +{ + u16 mask = 0; + + if (bw == BW_20) { + if (nss != 3 && nss != 6) + mask = BIT(9); + } else if (bw == BW_80) { + if (nss == 3 || nss == 7) + mask = BIT(6); + else if (nss == 6) + mask = BIT(9); + } else { + WARN_ON(bw != BW_40); + } + + switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) { + case IEEE80211_VHT_MCS_SUPPORT_0_7: + mask |= 0x300; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_8: + mask |= 0x200; + break; + case IEEE80211_VHT_MCS_SUPPORT_0_9: + break; + default: + mask = 0x3ff; + } + + return 0x3ff & ~mask; +} + /* * Look up an MCS group index based on mac80211 rate information */ @@ -144,6 +270,15 @@ minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); } +static int +minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate) +{ + return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate), + !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), + !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + + 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)); +} + static struct minstrel_rate_stats * minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, struct ieee80211_tx_rate *rate) @@ -153,6 +288,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (rate->flags & IEEE80211_TX_RC_MCS) { group = minstrel_ht_get_group_idx(rate); idx = rate->idx % 8; + } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + group = minstrel_vht_get_group_idx(rate); + idx = ieee80211_rate_get_vht_mcs(rate); } else { group = MINSTREL_CCK_GROUP; @@ -489,7 +627,8 @@ minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rat if (!rate->count) return false; - if (rate->flags & IEEE80211_TX_RC_MCS) + if (rate->flags & IEEE80211_TX_RC_MCS || + rate->flags & IEEE80211_TX_RC_VHT_MCS) return true; return rate->idx == mp->cck_rates[0] || @@ -736,6 +875,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; + else if (flags & IEEE80211_TX_RC_VHT_MCS) + idx = ((group->streams - 1) << 4) | + ((index % MCS_GROUP_RATES) & 0xF); else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; @@ -917,6 +1059,9 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); rate->idx = mp->cck_rates[idx]; + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); } else { rate->idx = sample_idx % MCS_GROUP_RATES + (sample_group->streams - 1) * 8; @@ -962,6 +1107,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, struct minstrel_ht_sta *mi = &msp->ht; struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; u16 sta_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + int use_vht; int n_supported = 0; int ack_dur; int stbc; @@ -973,6 +1120,13 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + if (vht_cap->vht_supported) + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); + else +#endif + use_vht = 0; + msp->is_ht = true; memset(mi, 0, sizeof(*mi)); @@ -996,15 +1150,19 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, } mi->sample_tries = 4; - stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> - IEEE80211_HT_CAP_RX_STBC_SHIFT; - mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { + stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; + mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; - if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) - mi->tx_flags |= IEEE80211_TX_CTL_LDPC; + if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) + mi->tx_flags |= IEEE80211_TX_CTL_LDPC; + } for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; mi->groups[i].supported = 0; if (i == MINSTREL_CCK_GROUP) { @@ -1026,13 +1184,47 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, sta->bandwidth < IEEE80211_STA_RX_BW_40) continue; + nss = minstrel_mcs_groups[i].streams; + /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ - if (sta->smps_mode == IEEE80211_SMPS_STATIC && - minstrel_mcs_groups[i].streams > 1) + if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) + continue; + + /* HT rate */ + if (gflags & IEEE80211_TX_RC_MCS) { +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT + if (minstrel_vht_only) + continue; +#endif + mi->groups[i].supported = mcs->rx_mask[nss - 1]; + if (mi->groups[i].supported) + n_supported++; + continue; + } + + /* VHT rate */ + if (!vht_cap->vht_supported || + WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) || + WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH)) continue; - mi->groups[i].supported = - mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; + if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) { + if (sta->bandwidth < IEEE80211_STA_RX_BW_80 || + ((gflags & IEEE80211_TX_RC_SHORT_GI) && + !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { + continue; + } + } + + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) + bw = BW_40; + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) + bw = BW_80; + else + bw = BW_20; + + mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss, + vht_cap->vht_mcs.tx_mcs_map); if (mi->groups[i].supported) n_supported++; diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index e747ac668afe..f2217d6aa0c2 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -15,17 +15,30 @@ */ #define MINSTREL_MAX_STREAMS 3 #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +#define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ +#else +#define MINSTREL_VHT_STREAM_GROUPS 0 +#endif #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ MINSTREL_HT_STREAM_GROUPS) +#define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_VHT_STREAM_GROUPS) #define MINSTREL_CCK_GROUPS_NB 1 #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ + MINSTREL_VHT_GROUPS_NB + \ MINSTREL_CCK_GROUPS_NB) #define MINSTREL_HT_GROUP_0 0 #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) +#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) -#define MCS_GROUP_RATES 8 +#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT +#define MCS_GROUP_RATES 10 +#else +#define MCS_GROUP_RATES 8 +#endif struct mcs_group { u32 flags; @@ -40,7 +53,7 @@ struct minstrel_mcs_group_data { u8 column; /* bitfield of supported MCS rates of this group */ - u8 supported; + u16 supported; /* sorted rate set within a MCS group*/ u16 max_group_tp_rate[MAX_THR_RATES]; diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index d2f53b867660..52bb6ef55b19 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -29,6 +29,8 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) mg = &minstrel_mcs_groups[i]; if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) htmode = '4'; + else if (mg->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + htmode = '8'; if (mg->flags & IEEE80211_TX_RC_SHORT_GI) gimode = 'S'; @@ -41,9 +43,11 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) continue; if (i == MINSTREL_CCK_GROUP) - p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); + p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); + else if (i >= MINSTREL_VHT_GROUP_0) + p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode); else - p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); + p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; @@ -53,9 +57,11 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (i == MINSTREL_CCK_GROUP) { int r = bitrates[j % 4]; - p += sprintf(p, " %2u.%1uM", r / 10, r % 10); + p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); + } else if (i >= MINSTREL_VHT_GROUP_0) { + p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); } else { - p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); + p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); } tp = mr->cur_tp / 10; @@ -94,19 +100,20 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) return ret; } - ms = kmalloc(8192, GFP_KERNEL); + ms = kmalloc(32768, GFP_KERNEL); if (!ms) return -ENOMEM; file->private_data = ms; p = ms->buf; - p += sprintf(p, "type rate tpt eprob *prob " + p += sprintf(p, " type rate tpt eprob *prob " "ret *ok(*cum) ok( cum)\n"); - p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); for (i = 0; i < MINSTREL_CCK_GROUP; i++) p = minstrel_ht_stats_dump(mi, i, p); + for (i++; i < ARRAY_SIZE(mi->groups); i++) + p = minstrel_ht_stats_dump(mi, i, p); p += sprintf(p, "\nTotal packet count:: ideal %d " "lookaround %d\n", @@ -117,7 +124,7 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); ms->len = p - ms->buf; - WARN_ON(ms->len + sizeof(*ms) > 8192); + WARN_ON(ms->len + sizeof(*ms) > 32768); return nonseekable_open(inode, file); } -- GitLab From cf6814f2b5014ed5bbdef764a42e4abaa09b3a2e Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 21 Oct 2014 16:28:47 +0530 Subject: [PATCH 0976/9457] ALSA: ctxfi: remove unused variable As of now the pointer to struct dai is not being used anywhere in the function. So it is safe to remove the variable. If we are ever doing anything with the container_of(daio, struct dai, daio), then at that time we can again add the variable. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 454659074390..632e843fa95e 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1145,7 +1145,6 @@ static int atc_release_resources(struct ct_atc *atc) int i; struct daio_mgr *daio_mgr = NULL; struct dao *dao = NULL; - struct dai *dai = NULL; struct daio *daio = NULL; struct sum_mgr *sum_mgr = NULL; struct src_mgr *src_mgr = NULL; @@ -1172,9 +1171,6 @@ static int atc_release_resources(struct ct_atc *atc) dao = container_of(daio, struct dao, daio); dao->ops->clear_left_input(dao); dao->ops->clear_right_input(dao); - } else { - dai = container_of(daio, struct dai, daio); - /* some thing to do for dai ... */ } daio_mgr->put_daio(daio_mgr, daio); } -- GitLab From 5c6761adc77c131ef1601016f9ebbad0a9ae6d1a Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 21 Oct 2014 18:20:12 +0200 Subject: [PATCH 0977/9457] mac80211: remove unnecessary null test before debugfs_remove() The debugfs_remove() function can safely take NULL parameters so the additionally null test isn't required, and there's no other reason to have it here, so remove it. Signed-off-by: Fabian Frederick [rewrite commit message, re-introduce blank line after assert] Signed-off-by: Johannes Berg --- net/mac80211/debugfs_key.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 1521cabad3d6..5523b94c7c90 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -300,10 +300,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&sdata->local->key_mtx); - if (sdata->debugfs.default_unicast_key) { - debugfs_remove(sdata->debugfs.default_unicast_key); - sdata->debugfs.default_unicast_key = NULL; - } + debugfs_remove(sdata->debugfs.default_unicast_key); + sdata->debugfs.default_unicast_key = NULL; if (sdata->default_unicast_key) { key = key_mtx_dereference(sdata->local, @@ -314,10 +312,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) sdata->vif.debugfs_dir, buf); } - if (sdata->debugfs.default_multicast_key) { - debugfs_remove(sdata->debugfs.default_multicast_key); - sdata->debugfs.default_multicast_key = NULL; - } + debugfs_remove(sdata->debugfs.default_multicast_key); + sdata->debugfs.default_multicast_key = NULL; if (sdata->default_multicast_key) { key = key_mtx_dereference(sdata->local, -- GitLab From e94f8cb32d47b157b2af1906eb965290e89ee3fe Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 20 Oct 2014 22:10:26 +0800 Subject: [PATCH 0978/9457] clk: sunxi: make factors clock mux mask configurable Some of the factors-style clocks on the A80 have different widths for the mux values in the registers. Add a .muxmask field to clk_factors_config to make it configurable. Passing a bitmask instead of a width parameter will allow reuse in case we support table-based muxes in the future. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 2 +- drivers/clk/sunxi/clk-factors.h | 3 +-- drivers/clk/sunxi/clk-mod0.c | 1 + drivers/clk/sunxi/clk-sun8i-mbus.c | 1 + drivers/clk/sunxi/clk-sunxi.c | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index f83ba097126c..5521e866fa5e 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -224,7 +224,7 @@ struct clk * __init sunxi_factors_register(struct device_node *node, /* set up gate properties */ mux->reg = reg; mux->shift = data->mux; - mux->mask = SUNXI_FACTORS_MUX_MASK; + mux->mask = data->muxmask; mux->lock = factors->lock; mux_hw = &mux->hw; } diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 9913840018d3..912238fde132 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -7,8 +7,6 @@ #define SUNXI_FACTORS_NOT_APPLICABLE (0) -#define SUNXI_FACTORS_MUX_MASK 0x3 - struct clk_factors_config { u8 nshift; u8 nwidth; @@ -24,6 +22,7 @@ struct clk_factors_config { struct factors_data { int enable; int mux; + int muxmask; struct clk_factors_config *table; void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); const char *name; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 4a563850ee6e..da0524eaee94 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -70,6 +70,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = { static const struct factors_data sun4i_a10_mod0_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun4i_a10_mod0_config, .getter = sun4i_a10_get_mod0_factors, }; diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 8e49b44cee41..ef49786eefd3 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -60,6 +60,7 @@ static struct clk_factors_config sun8i_a23_mbus_config = { static const struct factors_data sun8i_a23_mbus_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun8i_a23_mbus_config, .getter = sun8i_a23_get_mbus_factors, }; diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d5dc951264ca..636b8d772d4a 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -514,6 +514,7 @@ static const struct factors_data sun4i_apb1_data __initconst = { static const struct factors_data sun7i_a20_out_data __initconst = { .enable = 31, .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun7i_a20_out_config, .getter = sun7i_a20_get_out_factors, }; -- GitLab From 3b2bd70f03c75d37de791b65d574a31d1e2507b0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 20 Oct 2014 22:10:27 +0800 Subject: [PATCH 0979/9457] clk: sunxi: Add support for A80 basic bus clocks The A80 SoC has 12 PLL clocks, 3 AHB clocks, 2 APB clocks, and a new "GT" bus, which I assume is some kind of data bus connecting the processor cores, memory and various busses. Also there is a bus clock for a ARM CCI400 module. As far as I can tell, the GT bus and CCI400 bus clock must be protected. This patch adds driver support for peripheral related PLLs and bus clocks on the A80. The GT and CCI400 clocks are added as well as these 2 along with the PLLs they are clocked from must not be disabled. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- .../devicetree/bindings/clock/sunxi.txt | 5 + drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk-sun9i-core.c | 271 ++++++++++++++++++ 3 files changed, 277 insertions(+) create mode 100644 drivers/clk/sunxi/clk-sun9i-core.c diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index ed116df9c3e7..7f1c486691e0 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -10,14 +10,17 @@ Required properties: "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 + "allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80 "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31 + "allwinner,sun9i-a80-gt-clk" - for the GT bus clock on A80 "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock "allwinner,sun4i-a10-axi-clk" - for the AXI clock "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates "allwinner,sun4i-a10-ahb-clk" - for the AHB clock + "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s @@ -29,6 +32,7 @@ Required properties: "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 + "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s @@ -36,6 +40,7 @@ Required properties: "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock + "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing "allwinner,sun4i-a10-apb1-gates-clk" - for the APB1 gates on A10 "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 7ddc2b553846..a66953c0f430 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -7,6 +7,7 @@ obj-y += clk-a10-hosc.o obj-y += clk-a20-gmac.o obj-y += clk-mod0.o obj-y += clk-sun8i-mbus.o +obj-y += clk-sun9i-core.o obj-$(CONFIG_MFD_SUN6I_PRCM) += \ clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c new file mode 100644 index 000000000000..3cb9036d91bb --- /dev/null +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -0,0 +1,271 @@ +/* + * Copyright 2014 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "clk-factors.h" + + +/** + * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1 + * PLL4 rate is calculated as follows + * rate = (parent_rate * n >> p) / (m + 1); + * parent_rate is always 24Mhz + * + * p and m are named div1 and div2 in Allwinner's SDK + */ + +static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + int div; + + /* Normalize value to a 6M multiple */ + div = DIV_ROUND_UP(*freq, 6000000); + + /* divs above 256 cannot be odd */ + if (div > 256) + div = round_up(div, 2); + + /* divs above 512 must be a multiple of 4 */ + if (div > 512) + div = round_up(div, 4); + + *freq = 6000000 * div; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + /* p will be 1 for divs under 512 */ + if (div < 512) + *p = 1; + else + *p = 0; + + /* m will be 1 if div is odd */ + if (div & 1) + *m = 1; + else + *m = 0; + + /* calculate a suitable n based on m and p */ + *n = div / (*p + 1) / (*m + 1); +} + +static struct clk_factors_config sun9i_a80_pll4_config = { + .mshift = 18, + .mwidth = 1, + .nshift = 8, + .nwidth = 8, + .pshift = 16, + .pwidth = 1, +}; + +static const struct factors_data sun9i_a80_pll4_data __initconst = { + .enable = 31, + .table = &sun9i_a80_pll4_config, + .getter = sun9i_a80_get_pll4_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_pll4_lock); + +static void __init sun9i_a80_pll4_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_pll4_data, &sun9i_a80_pll4_lock); +} +CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_setup); + + +/** + * sun9i_a80_get_gt_factors() - calculates m factor for GT + * GT rate is calculated as follows + * rate = parent_rate / (m + 1); + */ + +static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 div; + + if (parent_rate < *freq) + *freq = parent_rate; + + div = DIV_ROUND_UP(parent_rate, *freq); + + /* maximum divider is 4 */ + if (div > 4) + div = 4; + + *freq = parent_rate / div; + + /* we were called to round the frequency, we can now return */ + if (!m) + return; + + *m = div; +} + +static struct clk_factors_config sun9i_a80_gt_config = { + .mshift = 0, + .mwidth = 2, +}; + +static const struct factors_data sun9i_a80_gt_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), + .table = &sun9i_a80_gt_config, + .getter = sun9i_a80_get_gt_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_gt_lock); + +static void __init sun9i_a80_gt_setup(struct device_node *node) +{ + struct clk *gt = sunxi_factors_register(node, &sun9i_a80_gt_data, + &sun9i_a80_gt_lock); + + /* The GT bus clock needs to be always enabled */ + __clk_get(gt); + clk_prepare_enable(gt); +} +CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); + + +/** + * sun9i_a80_get_ahb_factors() - calculates p factor for AHB0/1/2 + * AHB rate is calculated as follows + * rate = parent_rate >> p; + */ + +static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 _p; + + if (parent_rate < *freq) + *freq = parent_rate; + + _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + + /* maximum p is 3 */ + if (_p > 3) + _p = 3; + + *freq = parent_rate >> _p; + + /* we were called to round the frequency, we can now return */ + if (!p) + return; + + *p = _p; +} + +static struct clk_factors_config sun9i_a80_ahb_config = { + .pshift = 0, + .pwidth = 2, +}; + +static const struct factors_data sun9i_a80_ahb_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), + .table = &sun9i_a80_ahb_config, + .getter = sun9i_a80_get_ahb_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_ahb_lock); + +static void __init sun9i_a80_ahb_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_ahb_data, &sun9i_a80_ahb_lock); +} +CLK_OF_DECLARE(sun9i_a80_ahb, "allwinner,sun9i-a80-ahb-clk", sun9i_a80_ahb_setup); + + +static const struct factors_data sun9i_a80_apb0_data __initconst = { + .mux = 24, + .muxmask = BIT(0), + .table = &sun9i_a80_ahb_config, + .getter = sun9i_a80_get_ahb_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_apb0_lock); + +static void __init sun9i_a80_apb0_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_apb0_data, &sun9i_a80_apb0_lock); +} +CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_setup); + + +/** + * sun9i_a80_get_apb1_factors() - calculates m, p factors for APB1 + * APB1 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ + +static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u32 div; + u8 calcm, calcp; + + if (parent_rate < *freq) + *freq = parent_rate; + + div = DIV_ROUND_UP(parent_rate, *freq); + + /* Highest possible divider is 256 (p = 3, m = 31) */ + if (div > 256) + div = 256; + + calcp = order_base_2(div); + calcm = (parent_rate >> calcp) - 1; + *freq = (parent_rate >> calcp) / (calcm + 1); + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + *m = calcm; + *p = calcp; +} + +static struct clk_factors_config sun9i_a80_apb1_config = { + .mshift = 0, + .mwidth = 5, + .pshift = 16, + .pwidth = 2, +}; + +static const struct factors_data sun9i_a80_apb1_data __initconst = { + .mux = 24, + .muxmask = BIT(0), + .table = &sun9i_a80_apb1_config, + .getter = sun9i_a80_get_apb1_factors, +}; + +static DEFINE_SPINLOCK(sun9i_a80_apb1_lock); + +static void __init sun9i_a80_apb1_setup(struct device_node *node) +{ + sunxi_factors_register(node, &sun9i_a80_apb1_data, &sun9i_a80_apb1_lock); +} +CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-clk", sun9i_a80_apb1_setup); -- GitLab From 0b0f08028e4e2d69edbe4bb073af26cd17505a04 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 20 Oct 2014 22:10:28 +0800 Subject: [PATCH 0980/9457] clk: sunxi: Add support for bus clock gates on Allwinner A80 SoC This adds the gate clocks for AHB/APB busses on the A80 SoC. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- .../devicetree/bindings/clock/sunxi.txt | 5 +++ drivers/clk/sunxi/clk-sunxi.c | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 7f1c486691e0..0455cb9caa97 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -29,6 +29,9 @@ Required properties: "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23 + "allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80 + "allwinner,sun9i-a80-ahb1-gates-clk" - for the AHB1 gates on A80 + "allwinner,sun9i-a80-ahb2-gates-clk" - for the AHB2 gates on A80 "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 @@ -39,6 +42,7 @@ Required properties: "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 + "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing @@ -48,6 +52,7 @@ Required properties: "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31 "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 "allwinner,sun8i-a23-apb1-gates-clk" - for the APB1 gates on A23 + "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 636b8d772d4a..20f47c68a946 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -758,6 +758,18 @@ static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = { .mask = {0x25386742, 0x2505111}, }; +static const struct gates_data sun9i_a80_ahb0_gates_data __initconst = { + .mask = {0xF5F12B}, +}; + +static const struct gates_data sun9i_a80_ahb1_gates_data __initconst = { + .mask = {0x1E20003}, +}; + +static const struct gates_data sun9i_a80_ahb2_gates_data __initconst = { + .mask = {0x9B7}, +}; + static const struct gates_data sun4i_apb0_gates_data __initconst = { .mask = {0x4EF}, }; @@ -774,6 +786,10 @@ static const struct gates_data sun7i_a20_apb0_gates_data __initconst = { .mask = { 0x4ff }, }; +static const struct gates_data sun9i_a80_apb0_gates_data __initconst = { + .mask = {0xEB822}, +}; + static const struct gates_data sun4i_apb1_gates_data __initconst = { .mask = {0xFF00F7}, }; @@ -802,6 +818,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = { .mask = { 0xff80ff }, }; +static const struct gates_data sun9i_a80_apb1_gates_data __initconst = { + .mask = {0x3F001F}, +}; + static const struct gates_data sun8i_a23_apb2_gates_data __initconst = { .mask = {0x1F0007}, }; @@ -1103,16 +1123,21 @@ static const struct of_device_id clk_gates_match[] __initconst = { {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb0-gates-clk", .data = &sun9i_a80_ahb0_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb1-gates-clk", .data = &sun9i_a80_ahb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-ahb2-gates-clk", .data = &sun9i_a80_ahb2_gates_data,}, {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, + {.compatible = "allwinner,sun9i-a80-apb0-gates-clk", .data = &sun9i_a80_apb0_gates_data,}, {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,}, + {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,}, {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, @@ -1201,3 +1226,9 @@ static void __init sun6i_init_clocks(struct device_node *node) } CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); + +static void __init sun9i_init_clocks(struct device_node *node) +{ + sunxi_init_clocks(NULL, 0); +} +CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); -- GitLab From 34b48db66e08ca1c1bc07cf305d672ac940268dc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 6 Sep 2014 16:08:05 -0700 Subject: [PATCH 0981/9457] block: remove artifical max_hw_sectors cap Set max_sectors to the value the drivers provides as hardware limit by default. Linux had proper I/O throttling for a long time and doesn't rely on a artifically small maximum I/O size anymore. By not limiting the I/O size by default we remove an annoying tuning step required for most Linux installation. Note that both the user, and if absolutely required the driver can still impose a limit for FS requests below max_hw_sectors_kb. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-settings.c | 4 +--- drivers/block/aoe/aoeblk.c | 2 +- include/linux/blkdev.h | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/block/blk-settings.c b/block/blk-settings.c index aa02247d227e..6ed2cbe5e8c9 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -257,9 +257,7 @@ void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_ __func__, max_hw_sectors); } - limits->max_hw_sectors = max_hw_sectors; - limits->max_sectors = min_t(unsigned int, max_hw_sectors, - BLK_DEF_MAX_SECTORS); + limits->max_sectors = limits->max_hw_sectors = max_hw_sectors; } EXPORT_SYMBOL(blk_limits_max_hw_sectors); diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index dd73e1ff1759..46c282fff104 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -395,7 +395,7 @@ aoeblk_gdalloc(void *vp) WARN_ON(d->flags & DEVFL_TKILL); WARN_ON(d->gd); WARN_ON(d->flags & DEVFL_UP); - blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS); + blk_queue_max_hw_sectors(q, 1024); q->backing_dev_info.name = "aoe"; q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE; d->bufpool = mp; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0207a78a8d82..74d14dba6fb7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1186,7 +1186,6 @@ extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); enum blk_default_limits { BLK_MAX_SEGMENTS = 128, BLK_SAFE_MAX_SECTORS = 255, - BLK_DEF_MAX_SECTORS = 1024, BLK_MAX_SEGMENT_SIZE = 65536, BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, }; -- GitLab From 469cda294dac1c4128e9adcb0a94636bc0cb280e Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Tue, 21 Oct 2014 17:33:29 +0200 Subject: [PATCH 0982/9457] ASoC: tegra: Read and use the GPIO flags of the headphone detect The headphone detect was hardcoded to low-active, use the flags from DT to allow high-active as well. Signed-off-by: Alban Bedel Acked-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_rt5640.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index a6898831fb9f..4ebe3871e610 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -44,6 +44,7 @@ struct tegra_rt5640 { struct tegra_asoc_utils_data util_data; int gpio_hp_det; + enum of_gpio_flags gpio_hp_det_flags; }; static int tegra_rt5640_asoc_hw_params(struct snd_pcm_substream *substream, @@ -119,6 +120,8 @@ static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd) if (gpio_is_valid(machine->gpio_hp_det)) { tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det; + tegra_rt5640_hp_jack_gpio.invert = + !!(machine->gpio_hp_det_flags & OF_GPIO_ACTIVE_LOW); snd_soc_jack_add_gpios(&tegra_rt5640_hp_jack, 1, &tegra_rt5640_hp_jack_gpio); @@ -180,7 +183,8 @@ static int tegra_rt5640_probe(struct platform_device *pdev) platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); - machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); + machine->gpio_hp_det = of_get_named_gpio_flags( + np, "nvidia,hp-det-gpios", 0, &machine->gpio_hp_det_flags); if (machine->gpio_hp_det == -EPROBE_DEFER) return -EPROBE_DEFER; -- GitLab From 98ad73c995ed4886c36a1fcfcda53fbff484f666 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 21 Oct 2014 17:01:15 +0200 Subject: [PATCH 0983/9457] ASoC: dapm: Remove redundant cast Both path->name and e->texts[i] have type const char*, so the cast is slightly confusing and certainly unnecessary. Signed-off-by: Rasmus Villemoes Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c61cb9cedbcd..39f992bc2b6a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -496,7 +496,7 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); - path->name = (char*)e->texts[i]; + path->name = e->texts[i]; if (i == item) path->connect = 1; else -- GitLab From c1ee8f3fdff2b5763fe13be0a50a7ab3df015f5b Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Tue, 21 Oct 2014 11:43:34 +0800 Subject: [PATCH 0984/9457] spi/atmel: improve the system suspend/resume functions implementation To make it cleaner, the system suspend/resume directly call the runtime suspend/resume functions and remove the wapper of CONFIG_PM_RUNTIME, CONFIG_PM_SLEEP. Signed-off-by: Wenyou Yang Acked-by: Kevin Hilman Acked-by: Nicolas Ferre Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 61 ++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 3f500142f13c..6ed18934dffe 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1451,11 +1451,30 @@ static int atmel_spi_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP +static int atmel_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct atmel_spi *as = spi_master_get_devdata(master); + + clk_disable_unprepare(as->clk); + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int atmel_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct atmel_spi *as = spi_master_get_devdata(master); + + pinctrl_pm_select_default_state(dev); + + return clk_prepare_enable(as->clk); +} + static int atmel_spi_suspend(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_master *master = dev_get_drvdata(dev); int ret; /* Stop the queue running */ @@ -1465,23 +1484,19 @@ static int atmel_spi_suspend(struct device *dev) return ret; } - if (!pm_runtime_suspended(dev)) { - clk_disable_unprepare(as->clk); - pinctrl_pm_select_sleep_state(dev); - } + if (!pm_runtime_suspended(dev)) + atmel_spi_runtime_suspend(dev); return 0; } static int atmel_spi_resume(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); + struct spi_master *master = dev_get_drvdata(dev); int ret; if (!pm_runtime_suspended(dev)) { - pinctrl_pm_select_default_state(dev); - ret = clk_prepare_enable(as->clk); + ret = atmel_spi_runtime_resume(dev); if (ret) return ret; } @@ -1493,30 +1508,6 @@ static int atmel_spi_resume(struct device *dev) return ret; } -#endif - -#ifdef CONFIG_PM_RUNTIME -static int atmel_spi_runtime_suspend(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); - - clk_disable_unprepare(as->clk); - pinctrl_pm_select_sleep_state(dev); - - return 0; -} - -static int atmel_spi_runtime_resume(struct device *dev) -{ - struct spi_master *master = dev_get_drvdata(dev); - struct atmel_spi *as = spi_master_get_devdata(master); - - pinctrl_pm_select_default_state(dev); - - return clk_prepare_enable(as->clk); -} -#endif static const struct dev_pm_ops atmel_spi_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(atmel_spi_suspend, atmel_spi_resume) -- GitLab From b3baaa47cc49fab3ecffbbaee660ce003d17d1f7 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 20 Oct 2014 20:54:30 +0530 Subject: [PATCH 0985/9457] ASoC: intel: use __iowrite32_copy for 32 bit copy The driver was using own method to do 32bit copy, turns out we have a kernel API so use that instead Tested-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_loader.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c index b6d27c14455a..00f60c1e9fda 100644 --- a/sound/soc/intel/sst/sst_loader.c +++ b/sound/soc/intel/sst/sst_loader.c @@ -39,14 +39,12 @@ #include "sst.h" #include "../sst-dsp.h" -static void memcpy32_toio(void __iomem *dst, const void *src, int count) +static inline void memcpy32_toio(void __iomem *dst, const void *src, int count) { - int i; - const u32 *src_32 = src; - u32 *dst_32 = dst; - - for (i = 0; i < count/sizeof(u32); i++) - writel(*src_32++, dst_32++); + /* __iowrite32_copy uses 32-bit count values so divide by 4 for + * right count in words + */ + __iowrite32_copy(dst, src, count/4); } /** -- GitLab From 790b4075b3a6845543d02ab29c81dc450e7b6794 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 20 Oct 2014 20:54:31 +0530 Subject: [PATCH 0986/9457] ASoC: intel: log an error on double free the stream context should be freed only once on stream cleanup. If we ever hit a chance that stream context is getting double freed, though not an cause of panic as memory allocator can deal with this, we should still log this to help in finding issues and debugging Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_drv_interface.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c index aadb0dbaa01c..3a5e92096b82 100644 --- a/sound/soc/intel/sst/sst_drv_interface.c +++ b/sound/soc/intel/sst/sst_drv_interface.c @@ -55,6 +55,8 @@ int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id) if (ret) sst_clean_stream(&ctx->streams[str_id]); return ret; + } else { + dev_err(ctx->dev, "we tried to free stream context %d which was freed!!!\n", str_id); } return ret; } -- GitLab From dee2ce696ea8b37a26eef9f2a3fcc64df7179d98 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 20 Oct 2014 20:54:32 +0530 Subject: [PATCH 0987/9457] ASoC: intel: fix the kernldoc comment copypaste error on function sst_get_num_channel caused the comment to be wrong, so fix it here Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_drv_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c index 3a5e92096b82..183b1eb95c0e 100644 --- a/sound/soc/intel/sst/sst_drv_interface.c +++ b/sound/soc/intel/sst/sst_drv_interface.c @@ -94,7 +94,7 @@ int sst_get_sfreq(struct snd_sst_params *str_param) } /* - * sst_get_sfreq - this function returns the frequency of the stream + * sst_get_num_channel - get number of channels for the stream * * @str_param : stream params */ -- GitLab From 33c1256f1ce30a94f4b590bb30baf787e17f64aa Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 20 Oct 2014 20:54:33 +0530 Subject: [PATCH 0988/9457] ASoC: intel: explain why block not found isn't error always The IPC blocking can be error when we don't find block or a short message, explain that by adding a comment about this scenario Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_ipc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sound/soc/intel/sst/sst_ipc.c b/sound/soc/intel/sst/sst_ipc.c index 41a2b41b232b..2126f5bb2813 100644 --- a/sound/soc/intel/sst/sst_ipc.c +++ b/sound/soc/intel/sst/sst_ipc.c @@ -54,6 +54,21 @@ struct sst_block *sst_create_block(struct intel_sst_drv *ctx, return msg; } +/* + * while handling the interrupts, we need to check for message status and + * then if we are blocking for a message + * + * here we are unblocking the blocked ones, this is based on id we have + * passed and search that for block threads. + * We will not find block in two cases + * a) when its small message and block in not there, so silently ignore + * them + * b) when we are actually not able to find the block (bug perhaps) + * + * Since we have bit of small messages we can spam kernel log with err + * print on above so need to keep as debug prints which should be enabled + * via dynamic debug while debugging IPC issues + */ int sst_wake_up_block(struct intel_sst_drv *ctx, int result, u32 drv_id, u32 ipc, void *data, u32 size) { -- GitLab From 7f26680170e322730c7c7553f5625fb04de4f5b8 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 20 Oct 2014 20:54:34 +0530 Subject: [PATCH 0989/9457] ASoC: intel: use __iowrite32_copy for 32 bit copy The sst-firmware was also using own method to do 32bit copy, turns out we have a kernel API so use that instead [For BYT] Tested-by: Jarkko Nikula Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 3bb43dac892d..cf3d19997126 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -32,13 +32,10 @@ static void block_module_remove(struct sst_module *module); -static void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) +static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) { - u32 i; - - /* copy one 32 bit word at a time as 64 bit access is not supported */ - for (i = 0; i < bytes; i += 4) - memcpy_toio(dest + i, src + i, 4); + /* __iowrite32_copy use 32bit size values so divide by 4 */ + __iowrite32_copy((void *)dest, src, bytes/4); } /* create new generic firmware object */ -- GitLab From 8c98d2554f715260efb3e779a9cfe045c4af8aa0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Sep 2014 16:08:27 -0700 Subject: [PATCH 0990/9457] docg3: Fix miuse of seq_printf return value seq_printf doesn't return a useful value, so remove these misuses. Signed-off-by: Joe Perches Signed-off-by: Brian Norris --- drivers/mtd/devices/docg3.c | 112 +++++++++++++++++------------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 21cc4b66feaa..68ff83cc6660 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1655,22 +1655,21 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; u8 fctrl; mutex_lock(&docg3->cascade->lock); fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, - "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", - fctrl, - fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", - fctrl & DOC_CTRL_CE ? "active" : "inactive", - fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", - fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", - fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); - return pos; + seq_printf(s, "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", + fctrl, + fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", + fctrl & DOC_CTRL_CE ? "active" : "inactive", + fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", + fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", + fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); + + return 0; } DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show); @@ -1678,58 +1677,56 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0, pctrl, mode; + int pctrl, mode; mutex_lock(&docg3->cascade->lock); pctrl = doc_register_readb(docg3, DOC_ASICMODE); mode = pctrl & 0x03; mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, - "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", - pctrl, - pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, - pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, - pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, - pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, - pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, - mode >> 1, mode & 0x1); + seq_printf(s, + "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", + pctrl, + pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, + pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, + pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, + pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, + pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, + mode >> 1, mode & 0x1); switch (mode) { case DOC_ASICMODE_RESET: - pos += seq_puts(s, "reset"); + seq_puts(s, "reset"); break; case DOC_ASICMODE_NORMAL: - pos += seq_puts(s, "normal"); + seq_puts(s, "normal"); break; case DOC_ASICMODE_POWERDOWN: - pos += seq_puts(s, "powerdown"); + seq_puts(s, "powerdown"); break; } - pos += seq_puts(s, ")\n"); - return pos; + seq_puts(s, ")\n"); + return 0; } DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); static int dbg_device_id_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; int id; mutex_lock(&docg3->cascade->lock); id = doc_register_readb(docg3, DOC_DEVICESELECT); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, "DeviceId = %d\n", id); - return pos; + seq_printf(s, "DeviceId = %d\n", id); + return 0; } DEBUGFS_RO_ATTR(device_id, dbg_device_id_show); static int dbg_protection_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0; int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; mutex_lock(&docg3->cascade->lock); @@ -1742,45 +1739,40 @@ static int dbg_protection_show(struct seq_file *s, void *p) dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); mutex_unlock(&docg3->cascade->lock); - pos += seq_printf(s, "Protection = 0x%02x (", - protect); + seq_printf(s, "Protection = 0x%02x (", protect); if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) - pos += seq_puts(s, "FOUNDRY_OTP_LOCK,"); + seq_puts(s, "FOUNDRY_OTP_LOCK,"); if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) - pos += seq_puts(s, "CUSTOMER_OTP_LOCK,"); + seq_puts(s, "CUSTOMER_OTP_LOCK,"); if (protect & DOC_PROTECT_LOCK_INPUT) - pos += seq_puts(s, "LOCK_INPUT,"); + seq_puts(s, "LOCK_INPUT,"); if (protect & DOC_PROTECT_STICKY_LOCK) - pos += seq_puts(s, "STICKY_LOCK,"); + seq_puts(s, "STICKY_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ENABLED) - pos += seq_puts(s, "PROTECTION ON,"); + seq_puts(s, "PROTECTION ON,"); if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) - pos += seq_puts(s, "IPL_DOWNLOAD_LOCK,"); + seq_puts(s, "IPL_DOWNLOAD_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ERROR) - pos += seq_puts(s, "PROTECT_ERR,"); + seq_puts(s, "PROTECT_ERR,"); else - pos += seq_puts(s, "NO_PROTECT_ERR"); - pos += seq_puts(s, ")\n"); - - pos += seq_printf(s, "DPS0 = 0x%02x : " - "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " - "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", - dps0, dps0_low, dps0_high, - !!(dps0 & DOC_DPS_OTP_PROTECTED), - !!(dps0 & DOC_DPS_READ_PROTECTED), - !!(dps0 & DOC_DPS_WRITE_PROTECTED), - !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), - !!(dps0 & DOC_DPS_KEY_OK)); - pos += seq_printf(s, "DPS1 = 0x%02x : " - "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " - "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", - dps1, dps1_low, dps1_high, - !!(dps1 & DOC_DPS_OTP_PROTECTED), - !!(dps1 & DOC_DPS_READ_PROTECTED), - !!(dps1 & DOC_DPS_WRITE_PROTECTED), - !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), - !!(dps1 & DOC_DPS_KEY_OK)); - return pos; + seq_puts(s, "NO_PROTECT_ERR"); + seq_puts(s, ")\n"); + + seq_printf(s, "DPS0 = 0x%02x : Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", + dps0, dps0_low, dps0_high, + !!(dps0 & DOC_DPS_OTP_PROTECTED), + !!(dps0 & DOC_DPS_READ_PROTECTED), + !!(dps0 & DOC_DPS_WRITE_PROTECTED), + !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), + !!(dps0 & DOC_DPS_KEY_OK)); + seq_printf(s, "DPS1 = 0x%02x : Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", + dps1, dps1_low, dps1_high, + !!(dps1 & DOC_DPS_OTP_PROTECTED), + !!(dps1 & DOC_DPS_READ_PROTECTED), + !!(dps1 & DOC_DPS_WRITE_PROTECTED), + !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), + !!(dps1 & DOC_DPS_KEY_OK)); + return 0; } DEBUGFS_RO_ATTR(protection, dbg_protection_show); -- GitLab From e66fcf722a74786c500957608f3230e843960b42 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 30 Sep 2014 03:15:04 +0100 Subject: [PATCH 0991/9457] spi-nor: Remove spi_nor::read_id operation There is currently no useful way to override the default implementation of this operation. The returned struct spi_device_id must have a pointer to struct flash_info in its private data, but this structure is defined inside spi-nor. Signed-off-by: Ben Hutchings Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 4 +--- include/linux/mtd/spi-nor.h | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index c51ee52386a7..a98c134e51b6 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -904,8 +904,6 @@ static int spi_nor_check(struct spi_nor *nor) return -EINVAL; } - if (!nor->read_id) - nor->read_id = spi_nor_read_id; if (!nor->wait_till_ready) nor->wait_till_ready = spi_nor_wait_till_ready; @@ -935,7 +933,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) if (info->jedec_id) { const struct spi_device_id *jid; - jid = nor->read_id(nor); + jid = spi_nor_read_id(nor); if (IS_ERR(jid)) { return PTR_ERR(jid); } else if (jid != id) { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 046a0a2e4c4e..2f27713b3ae1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -139,8 +139,6 @@ enum spi_nor_ops { * @write_xfer: [OPTIONAL] the writefundamental primitive * @read_reg: [DRIVER-SPECIFIC] read out the register * @write_reg: [DRIVER-SPECIFIC] write data to the register - * @read_id: [REPLACEABLE] read out the ID data, and find - * the proper spi_device_id * @wait_till_ready: [REPLACEABLE] wait till the NOR becomes ready * @read: [DRIVER-SPECIFIC] read data from the SPI NOR * @write: [DRIVER-SPECIFIC] write data to the SPI NOR @@ -172,7 +170,6 @@ struct spi_nor { int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len, int write_enable); - const struct spi_device_id *(*read_id)(struct spi_nor *nor); int (*wait_till_ready)(struct spi_nor *nor); int (*read)(struct spi_nor *nor, loff_t from, -- GitLab From 94cb4ee0f75383327fbeeb91909b342dae3771a5 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Thu, 2 Oct 2014 14:16:12 +0200 Subject: [PATCH 0992/9457] mtd: nand: omap: Do not use global variables Since the commit 97a288ba2cfa ("ARM: omap2+: gpmc-nand: Use dynamic platform_device_alloc()") gpmc-nand driver supports multiple NAND flash devices connected to the single controller. Remove global variable to make the code thread-safe. Signed-off-by: Rostislav Lisovy Acked-by: Roger Quadros Signed-off-by: Brian Norris --- drivers/mtd/nand/omap2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 3b357e920a0c..b0f89d87de89 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -144,9 +144,6 @@ static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, 0xac, 0x6b, 0xff, 0x99, 0x7b}; static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; -/* oob info generated runtime depending on ecc algorithm and layout selected */ -static struct nand_ecclayout omap_oobinfo; - struct omap_nand_info { struct nand_hw_control controller; struct omap_nand_platform_data *pdata; @@ -168,6 +165,8 @@ struct omap_nand_info { u_char *buf; int buf_len; struct gpmc_nand_regs reg; + /* generated at runtime depending on ECC algorithm and layout selected */ + struct nand_ecclayout oobinfo; /* fields specific for BCHx_HW ECC scheme */ struct device *elm_dev; struct device_node *of_node; @@ -1840,7 +1839,7 @@ static int omap_nand_probe(struct platform_device *pdev) } /* populate MTD interface based on ECC scheme */ - ecclayout = &omap_oobinfo; + ecclayout = &info->oobinfo; switch (info->ecc_opt) { case OMAP_ECC_HAM1_CODE_SW: nand_chip->ecc.mode = NAND_ECC_SOFT; -- GitLab From a59459f29fb7942a2d5d9f209c8b6b8da6c0540f Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 27 Sep 2014 21:34:29 +0200 Subject: [PATCH 0993/9457] mtd: docg3: add device-tree support Add device-tree support. This is straightforward as docg3 only uses the standard IOMEM resources. Signed-off-by: Robert Jarzmik Cc: devicetree@vger.kernel.org Cc: Mark Rutland Signed-off-by: Brian Norris --- drivers/mtd/devices/docg3.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 68ff83cc6660..abd94668a05d 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -2118,10 +2119,17 @@ static int __exit docg3_release(struct platform_device *pdev) return 0; } +static struct of_device_id docg3_dt_ids[] = { + { .compatible = "m-systems,diskonchip-g3" }, + {} +}; +MODULE_DEVICE_TABLE(of, docg3_dt_ids); + static struct platform_driver g3_driver = { .driver = { .name = "docg3", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(docg3_dt_ids), }, .suspend = docg3_suspend, .resume = docg3_resume, -- GitLab From 9c350066a709f7ee3d1219e9888252daf547af99 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 27 Sep 2014 21:34:30 +0200 Subject: [PATCH 0994/9457] mtd: docg3: add device-tree documentation Add documentation for the sandisk docg3 chip. Signed-off-by: Robert Jarzmik Cc: devicetree@vger.kernel.org Cc: Mark Rutland Signed-off-by: Brian Norris --- .../devicetree/bindings/mtd/diskonchip.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/diskonchip.txt diff --git a/Documentation/devicetree/bindings/mtd/diskonchip.txt b/Documentation/devicetree/bindings/mtd/diskonchip.txt new file mode 100644 index 000000000000..3e13bfdbea5b --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/diskonchip.txt @@ -0,0 +1,15 @@ +M-Systems and Sandisk DiskOnChip devices + +M-System DiskOnChip G3 +====================== +The Sandisk (formerly M-Systems) docg3 is a nand device of 64M to 256MB. + +Required properties: + - compatible: should be "m-systems,diskonchip-g3" + - reg: register base and size + +Example: + docg3: flash@0 { + compatible = "m-systems,diskonchip-g3"; + reg = <0x0 0x2000>; + }; -- GitLab From a72fe6b2ce7fd39d1df4cb4bb0330348824c6025 Mon Sep 17 00:00:00 2001 From: Aaron Sierra Date: Tue, 23 Sep 2014 14:07:24 -0500 Subject: [PATCH 0995/9457] mtd: bfin-async-flash: Remove unused variable Avoid the following compile warning: drivers/mtd/maps/bfin-async-flash.c: In function 'bfin_flash_probe': drivers/mtd/maps/bfin-async-flash.c:129: warning: unused variable 'ret' Signed-off-by: Aaron Sierra Signed-off-by: Brian Norris --- drivers/mtd/maps/bfin-async-flash.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 6ea51e549045..41730feeace8 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -126,7 +126,6 @@ static const char * const part_probe_types[] = { static int bfin_flash_probe(struct platform_device *pdev) { - int ret; struct physmap_flash_data *pdata = dev_get_platdata(&pdev->dev); struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- GitLab From 7f4028b29658a3ad63e83352af6ce2dae4fe7cdf Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sun, 28 Sep 2014 21:26:32 +0200 Subject: [PATCH 0996/9457] jffs2: fix sparse warning: unexpected unlock fs/jffs2/summary.c:846:5: warning: context imbalance in 'jffs2_sum_write_sumnode' - unexpected unlock Suggested-by: Brian Norris Suggested-by: Josh Triplett Signed-off-by: Fabian Frederick Reviewed-by: Josh Triplett Signed-off-by: Brian Norris --- fs/jffs2/summary.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index c522d098bb4f..bc5385471a6e 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -844,6 +844,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock /* Write out summary information - called from jffs2_do_reserve_space */ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) + __must_hold(&c->erase_completion_block) { int datasize, infosize, padsize; struct jffs2_eraseblock *jeb; -- GitLab From 59af5c7acde3d5cbbf8fadbc81a352a892cbc34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 2 Oct 2014 11:48:46 +0200 Subject: [PATCH 0997/9457] mtd: bcm47xxpart: alloc memory for more partitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for some new Netgear devices (e.g. R6250). Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- drivers/mtd/bcm47xxpart.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 8057f52a45b7..f2db4d7d6c36 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -15,8 +15,12 @@ #include #include -/* 10 parts were found on sflash on Netgear WNDR4500 */ -#define BCM47XXPART_MAX_PARTS 12 +/* + * NAND flash on Netgear R6250 was verified to contain 15 partitions. + * This will result in allocating too big array for some old devices, but the + * memory will be freed soon anyway (see mtd_device_parse_register). + */ +#define BCM47XXPART_MAX_PARTS 20 /* * Amount of bytes we read when analyzing each block of flash memory. -- GitLab From a0fa0b66ac1ce73ff791df977b07410a6f4cd337 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Thu, 16 Oct 2014 06:58:35 +0200 Subject: [PATCH 0998/9457] mtd: orion_nand: fix error code path in probe This replaces kzalloc() and ioremap() calls by devm_ functions in the probe() routine, which automatically release the corresponding resources when probe() fails or when the device is removed. This simplifies simplifies the error management code, and brings the below improvements or changes: A. Fixing a bug reported by "make coccicheck": If "board = devm_kzalloc()" fails, the probe() function jumps incorrectly to label "no_res" and therefore returns without running iounmap(). B. Requesting the memory region Using devm_ioremap_resource() makes the probe() function request the corresponding memory region before running ioremap(), as it is supposed to do. C. Standardizing the error codes: The use of devm_ioremap_resource() changes the return value: * -ENOMEM instead of -EIO in case of ioremap() failure, * -EINVAL instead of -ENODEV in case of platform_get_resource() failure. Signed-off-by: Michael Opdenacker Reviewed-by: Jingoo Han Acked-by: Andrew Lunn Signed-off-by: Brian Norris --- drivers/mtd/nand/orion_nand.c | 39 ++++++++++------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 471b4df3a5ac..0b49d5d34c50 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -85,33 +85,24 @@ static int __init orion_nand_probe(struct platform_device *pdev) int ret = 0; u32 val = 0; - nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); - if (!nc) { - ret = -ENOMEM; - goto no_res; - } + nc = devm_kzalloc(&pdev->dev, + sizeof(struct nand_chip) + sizeof(struct mtd_info), + GFP_KERNEL); + if (!nc) + return -ENOMEM; mtd = (struct mtd_info *)(nc + 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto no_res; - } + io_base = devm_ioremap_resource(&pdev->dev, res); - io_base = ioremap(res->start, resource_size(res)); - if (!io_base) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -EIO; - goto no_res; - } + if (IS_ERR(io_base)) + return PTR_ERR(io_base); if (pdev->dev.of_node) { board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data), GFP_KERNEL); - if (!board) { - ret = -ENOMEM; - goto no_res; - } + if (!board) + return -ENOMEM; if (!of_property_read_u32(pdev->dev.of_node, "cle", &val)) board->cle = (u8)val; else @@ -185,9 +176,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) clk_disable_unprepare(clk); clk_put(clk); } - iounmap(io_base); -no_res: - kfree(nc); return ret; } @@ -195,15 +183,10 @@ static int __init orion_nand_probe(struct platform_device *pdev) static int orion_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); - struct nand_chip *nc = mtd->priv; struct clk *clk; nand_release(mtd); - iounmap(nc->IO_ADDR_W); - - kfree(nc); - clk = clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { clk_disable_unprepare(clk); -- GitLab From b26171e392c7d3952b6eeb6da62a861c5317e438 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 17 Oct 2014 15:31:08 -0300 Subject: [PATCH 0999/9457] mtd: fsl-quadspi: Propagate the error from of_modalias_node() The 'map_failed' label will return 'ret', so we need to assign the error code to 'ret', otherwise the probe function will return success. Signed-off-by: Fabio Estevam Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/fsl-quadspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index d5269a26c839..94e73553abb3 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -905,7 +905,8 @@ static int fsl_qspi_probe(struct platform_device *pdev) nor->prepare = fsl_qspi_prep; nor->unprepare = fsl_qspi_unprep; - if (of_modalias_node(np, modalias, sizeof(modalias)) < 0) + ret = of_modalias_node(np, modalias, sizeof(modalias)); + if (ret < 0) goto map_failed; ret = of_property_read_u32(np, "spi-max-frequency", -- GitLab From 77adc085aee0c96dc3536403b197707316c7c241 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 17 Oct 2014 17:14:01 -0300 Subject: [PATCH 1000/9457] mtd: fsl-quadspi: Let the clocks error path be clearer When clk_prepare_enable(q->clk) fails it is clearer to disable the previous acquired clock (q->clk_en) in the error path rather than doing it locally. So disable q->clk_en in the error path only. Signed-off-by: Fabio Estevam Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/fsl-quadspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 94e73553abb3..b6aab38c4a97 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -849,9 +849,8 @@ static int fsl_qspi_probe(struct platform_device *pdev) ret = clk_prepare_enable(q->clk); if (ret) { - clk_disable_unprepare(q->clk_en); dev_err(dev, "can not enable the qspi clock\n"); - goto map_failed; + goto clk_failed; } /* find the irq */ @@ -965,6 +964,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) irq_failed: clk_disable_unprepare(q->clk); +clk_failed: clk_disable_unprepare(q->clk_en); map_failed: dev_err(dev, "Freescale QuadSPI probe failed\n"); -- GitLab From 209f5527b7ef06948d79f9dea636764db296db08 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Wed, 8 Oct 2014 11:37:20 -0500 Subject: [PATCH 1001/9457] drm/crtc: Fix two typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: ioclt -> ioctl in comment wrong variable name in debug message Signed-off-by: Chuck Ebbert Reviewed-by: Ville Syrjälä [danvet: Frob manually generated patch to make it apply.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 7f94989e6fc9..4be01899f29d 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2943,7 +2943,7 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format); * @file_priv: drm file for the ioctl call * * Add a new FB to the specified CRTC, given a user request. This is the - * original addfb ioclt which only supported RGB formats. + * original addfb ioctl which only supported RGB formats. * * Called by the user via ioctl. * @@ -3080,7 +3080,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) num_planes = drm_format_num_planes(r->pixel_format); if (r->width == 0 || r->width % hsub) { - DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height); + DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); return -EINVAL; } -- GitLab From 228f2cb32f0dbeef0b88dc97ea66a3c31b03de99 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Wed, 8 Oct 2014 11:40:34 -0500 Subject: [PATCH 1002/9457] drm/crtc: Remove duplicated ioctl code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make drm_mode_add_fb() call drm_mode_add_fb2() after converting its args to the new internal format, instead of duplicating code. Also picks up a lot more error checking, which the legacy modes should pass after being converted to the new format. Signed-off-by: Chuck Ebbert Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4be01899f29d..b4a6f08d0045 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2955,11 +2955,9 @@ int drm_mode_addfb(struct drm_device *dev, { struct drm_mode_fb_cmd *or = data; struct drm_mode_fb_cmd2 r = {}; - struct drm_mode_config *config = &dev->mode_config; - struct drm_framebuffer *fb; - int ret = 0; + int ret; - /* Use new struct with format internally */ + /* convert to new format and call new ioctl */ r.fb_id = or->fb_id; r.width = or->width; r.height = or->height; @@ -2967,26 +2965,11 @@ int drm_mode_addfb(struct drm_device *dev, r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); r.handles[0] = or->handle; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if ((config->min_width > r.width) || (r.width > config->max_width)) - return -EINVAL; - - if ((config->min_height > r.height) || (r.height > config->max_height)) - return -EINVAL; - - fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); - if (IS_ERR(fb)) { - DRM_DEBUG_KMS("could not create framebuffer\n"); - return PTR_ERR(fb); - } + ret = drm_mode_addfb2(dev, &r, file_priv); + if (ret) + return ret; - mutex_lock(&file_priv->fbs_lock); - or->fb_id = fb->base.id; - list_add(&fb->filp_head, &file_priv->fbs); - DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); - mutex_unlock(&file_priv->fbs_lock); + or->fb_id = r.fb_id; return ret; } -- GitLab From 723e73acd16d2ea08cdbd8b449b7bc69389b94d4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Oct 2014 09:25:06 +0200 Subject: [PATCH 1003/9457] cfg80211: make WMM TSPEC support flag an nl80211 feature flag During the review of the corresponding wpa_supplicant patches we noticed that the only way for it to detect that this functionality is supported currently is to check for the command support. This can be misleading though, as the command was also designed to, in the future, support pure 802.11 TSPECs. Expose the WMM-TSPEC feature flag to nl80211 so later we can also expose an 802.11-TSPEC feature flag (if needed) to differentiate the two cases. Note: this change isn't needed in 3.18 as there's no driver there yet that supports the functionality at all. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 6 +----- include/uapi/linux/nl80211.h | 5 +++++ net/wireless/nl80211.c | 14 ++++++-------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ed896c0b5b8b..77aa805d7e7c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2646,13 +2646,9 @@ struct cfg80211_ops { * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in * beaconing mode (AP, IBSS, Mesh, ...). - * @WIPHY_FLAG_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM - * TSPEC sessions (TID aka TSID 0-7) with the NL80211_CMD_ADD_TX_TS - * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it - * needs to be able to handle Block-Ack agreements and other things. */ enum wiphy_flags { - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION = BIT(0), + /* use hole at 0 */ /* use hole at 1 */ /* use hole at 2 */ WIPHY_FLAG_NETNS_OK = BIT(3), diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index b553c48404d3..be1d5def304d 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4052,6 +4052,10 @@ enum nl80211_ap_sme_features { * multiplexing powersave, ie. can turn off all but one chain * and then wake the rest up as required after, for example, * rts/cts handshake. + * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM + * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS + * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it + * needs to be able to handle Block-Ack agreements and other things. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4080,6 +4084,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, NL80211_FEATURE_STATIC_SMPS = 1 << 24, NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d05fe6d6481d..d98d4ea27819 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1514,8 +1514,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) CMD(channel_switch, CHANNEL_SWITCH); CMD(set_qos_map, SET_QOS_MAP); - if (rdev->wiphy.flags & - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) + if (rdev->wiphy.features & + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION) CMD(add_tx_ts, ADD_TX_TS); } /* add into the if now */ @@ -9557,7 +9557,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) u16 admitted_time = 0; int err; - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) + if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)) return -EOPNOTSUPP; if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || @@ -9573,12 +9573,10 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* WMM uses TIDs 0-7 even for TSPEC */ - if (tsid < IEEE80211_FIRST_TSPEC_TSID) { - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) - return -EINVAL; - } else { + if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { /* TODO: handle 802.11 TSPEC/admission control - * need more attributes for that (e.g. BA session requirement) + * need more attributes for that (e.g. BA session requirement); + * change the WMM adminssion test above to allow both then */ return -EINVAL; } -- GitLab From f409079bb678600be0201cd03afb4731f0480b4e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 8 Oct 2014 14:37:47 +0200 Subject: [PATCH 1004/9457] mac80211: sanity check CW_min/CW_max towards driver There's no reason to ever set invalid CW_min/CW_max to the drivers, we should catch it in higher layers. However, the consequences of setting it wrong can be quite severe, so double-check at a low level and error out for invalid data. Signed-off-by: Johannes Berg --- net/mac80211/driver-ops.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 1bbb0790264f..3df28e0fa045 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -631,6 +631,12 @@ static inline int drv_conf_tx(struct ieee80211_local *local, if (!check_sdata_in_driver(sdata)) return -EIO; + if (WARN_ONCE(params->cw_min == 0 || + params->cw_min > params->cw_max, + "%s: invalid CW_min/CW_max: %d/%d\n", + sdata->name, params->cw_min, params->cw_max)) + return -EINVAL; + trace_drv_conf_tx(local, sdata, ac, params); if (local->ops->conf_tx) ret = local->ops->conf_tx(&local->hw, &sdata->vif, -- GitLab From 02219b3abca59fca81711bfe7ee78df7abad97ce Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 7 Oct 2014 10:38:50 +0300 Subject: [PATCH 1005/9457] mac80211: add WMM admission control support Use the currently existing APIs between mac80211 and the low level driver to implement WMM admission control. The low level driver needs to report the media time used by each transmitted packet in ieee80211_tx_status. Based on that information, mac80211 will modify the QoS parameters of the admission controlled Access Category when the limit is reached. Once the original QoS parameters can be restored, mac80211 will do so. One issue with this approach is that management frames will also erroneously be downgraded, but the upside is that the implementation is simple. In the future, it can be extended to driver- or device-based implementations that are better. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +- net/mac80211/agg-tx.c | 5 -- net/mac80211/cfg.c | 73 +++++++++++++++++++ net/mac80211/ieee80211_i.h | 38 +++++++++- net/mac80211/mlme.c | 142 +++++++++++++++++++++++++++++++++++-- net/mac80211/status.c | 3 +- net/mac80211/wme.c | 29 +++++--- net/mac80211/wme.h | 2 - 8 files changed, 272 insertions(+), 23 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9bb2fc73aeaa..9dc5e7606322 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -739,7 +739,8 @@ struct ieee80211_tx_info { u8 ampdu_ack_len; u8 ampdu_len; u8 antenna; - void *status_driver_data[21 / sizeof(void *)]; + u16 tx_time; + void *status_driver_data[19 / sizeof(void *)]; } status; struct { struct ieee80211_tx_rate driver_rates[ diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index d6986f3aa5c4..9242c60048cf 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -149,11 +149,6 @@ void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); } -static inline int ieee80211_ac_from_tid(int tid) -{ - return ieee802_1d_to_ac[tid & 7]; -} - /* * When multiple aggregation sessions on multiple stations * are being created/destroyed simultaneously, we need to diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 64deb9aa0f81..d6b01ad2f7d7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -20,6 +20,7 @@ #include "cfg.h" #include "rate.h" #include "mesh.h" +#include "wme.h" static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, const char *name, @@ -3585,6 +3586,76 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy, return ret; } +static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev, + u8 tsid, const u8 *peer, u8 up, + u16 admitted_time) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + int ac = ieee802_1d_to_ac[up]; + + if (sdata->vif.type != NL80211_IFTYPE_STATION) + return -EOPNOTSUPP; + + if (!(sdata->wmm_acm & BIT(up))) + return -EINVAL; + + if (ifmgd->tx_tspec[ac].admitted_time) + return -EBUSY; + + if (admitted_time) { + ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time; + ifmgd->tx_tspec[ac].tsid = tsid; + ifmgd->tx_tspec[ac].up = up; + } + + return 0; +} + +static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev, + u8 tsid, const u8 *peer) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_local *local = wiphy_priv(wiphy); + int ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + + /* skip unused entries */ + if (!tx_tspec->admitted_time) + continue; + + if (tx_tspec->tsid != tsid) + continue; + + /* due to this new packets will be reassigned to non-ACM ACs */ + tx_tspec->up = -1; + + /* Make sure that all packets have been sent to avoid to + * restore the QoS params on packets that are still on the + * queues. + */ + synchronize_net(); + ieee80211_flush_queues(local, sdata); + + /* restore the normal QoS parameters + * (unconditionally to avoid races) + */ + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; + tx_tspec->downgraded = false; + ieee80211_sta_handle_tspec_ac_params(sdata); + + /* finally clear all the data */ + memset(tx_tspec, 0, sizeof(*tx_tspec)); + + return 0; + } + + return -ENOENT; +} + const struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -3663,4 +3734,6 @@ const struct cfg80211_ops mac80211_config_ops = { .channel_switch = ieee80211_channel_switch, .set_qos_map = ieee80211_set_qos_map, .set_ap_chanwidth = ieee80211_set_ap_chanwidth, + .add_tx_ts = ieee80211_add_tx_ts, + .del_tx_ts = ieee80211_del_tx_ts, }; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 78d6121eb372..60063be057d0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -399,6 +399,24 @@ struct ieee80211_mgd_assoc_data { u8 ie[]; }; +struct ieee80211_sta_tx_tspec { + /* timestamp of the first packet in the time slice */ + unsigned long time_slice_start; + + u32 admitted_time; /* in usecs, unlike over the air */ + u8 tsid; + s8 up; /* signed to be able to invalidate with -1 during teardown */ + + /* consumed TX time in microseconds in the time slice */ + u32 consumed_tx_time; + enum { + TX_TSPEC_ACTION_NONE = 0, + TX_TSPEC_ACTION_DOWNGRADE, + TX_TSPEC_ACTION_STOP_DOWNGRADE, + } action; + bool downgraded; +}; + struct ieee80211_if_managed { struct timer_list timer; struct timer_list conn_mon_timer; @@ -509,6 +527,16 @@ struct ieee80211_if_managed { u8 tdls_peer[ETH_ALEN] __aligned(2); struct delayed_work tdls_peer_del_work; + + /* WMM-AC TSPEC support */ + struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; + /* Use a separate work struct so that we can do something here + * while the sdata->work is flushing the queues, for example. + * otherwise, in scenarios where we hardly get any traffic out + * on the BE queue, but there's a lot of VO traffic, we might + * get stuck in a downgraded situation and flush takes forever. + */ + struct delayed_work tx_tspec_wk; }; struct ieee80211_if_ibss { @@ -1459,6 +1487,7 @@ void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, __le16 fc, bool acked); void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); +void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); @@ -1763,6 +1792,13 @@ static inline bool ieee80211_rx_reorder_ready(struct sk_buff_head *frames) return true; } +extern const int ieee802_1d_to_ac[8]; + +static inline int ieee80211_ac_from_tid(int tid) +{ + return ieee802_1d_to_ac[tid & 7]; +} + void ieee80211_dynamic_ps_enable_work(struct work_struct *work); void ieee80211_dynamic_ps_disable_work(struct work_struct *work); void ieee80211_dynamic_ps_timer(unsigned long data); @@ -1772,7 +1808,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr); void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr, bool ack); + struct ieee80211_hdr *hdr, bool ack, u16 tx_time); void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, unsigned long queues, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fb6561509caf..4d9b4d165ce8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1606,6 +1606,95 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work) mutex_unlock(&sdata->local->mtx); } +static bool +__ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + bool ret; + int ac; + + if (local->hw.queues < IEEE80211_NUM_ACS) + return false; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + int non_acm_ac; + unsigned long now = jiffies; + + if (tx_tspec->action == TX_TSPEC_ACTION_NONE && + tx_tspec->admitted_time && + time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->consumed_tx_time = 0; + tx_tspec->time_slice_start = now; + + if (tx_tspec->downgraded) + tx_tspec->action = + TX_TSPEC_ACTION_STOP_DOWNGRADE; + } + + switch (tx_tspec->action) { + case TX_TSPEC_ACTION_STOP_DOWNGRADE: + /* take the original parameters */ + if (drv_conf_tx(local, sdata, ac, &sdata->tx_conf[ac])) + sdata_err(sdata, + "failed to set TX queue parameters for queue %d\n", + ac); + tx_tspec->action = TX_TSPEC_ACTION_NONE; + tx_tspec->downgraded = false; + ret = true; + break; + case TX_TSPEC_ACTION_DOWNGRADE: + if (time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->action = TX_TSPEC_ACTION_NONE; + ret = true; + break; + } + /* downgrade next lower non-ACM AC */ + for (non_acm_ac = ac + 1; + non_acm_ac < IEEE80211_NUM_ACS; + non_acm_ac++) + if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac))) + break; + /* The loop will result in using BK even if it requires + * admission control, such configuration makes no sense + * and we have to transmit somehow - the AC selection + * does the same thing. + */ + if (drv_conf_tx(local, sdata, ac, + &sdata->tx_conf[non_acm_ac])) + sdata_err(sdata, + "failed to set TX queue parameters for queue %d\n", + ac); + tx_tspec->action = TX_TSPEC_ACTION_NONE; + ret = true; + schedule_delayed_work(&ifmgd->tx_tspec_wk, + tx_tspec->time_slice_start + HZ - now + 1); + break; + case TX_TSPEC_ACTION_NONE: + /* nothing now */ + break; + } + } + + return ret; +} + +void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) +{ + if (__ieee80211_sta_handle_tspec_ac_params(sdata)) + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); +} + +static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work) +{ + struct ieee80211_sub_if_data *sdata; + + sdata = container_of(work, struct ieee80211_sub_if_data, + u.mgd.tx_tspec_wk.work); + ieee80211_sta_handle_tspec_ac_params(sdata); +} + /* MLME */ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, @@ -1690,12 +1779,14 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, params.uapsd = uapsd; mlme_dbg(sdata, - "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n", queue, aci, acm, params.aifs, params.cw_min, params.cw_max, - params.txop, params.uapsd); + params.txop, params.uapsd, + ifmgd->tx_tspec[queue].downgraded); sdata->tx_conf[queue] = params; - if (drv_conf_tx(local, sdata, queue, ¶ms)) + if (!ifmgd->tx_tspec[queue].downgraded && + drv_conf_tx(local, sdata, queue, ¶ms)) sdata_err(sdata, "failed to set TX queue parameters for queue %d\n", queue); @@ -1958,6 +2049,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, } mutex_unlock(&local->mtx); + /* existing TX TSPEC sessions no longer exist */ + memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec)); + cancel_delayed_work_sync(&ifmgd->tx_tspec_wk); + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; } @@ -2010,9 +2105,46 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) mutex_unlock(&local->mtx); } +static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr, + u16 tx_time) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; + int ac = ieee80211_ac_from_tid(tid); + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; + unsigned long now = jiffies; + + if (likely(!tx_tspec->admitted_time)) + return; + + if (time_after(now, tx_tspec->time_slice_start + HZ)) { + tx_tspec->consumed_tx_time = 0; + tx_tspec->time_slice_start = now; + + if (tx_tspec->downgraded) { + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); + } + } + + if (tx_tspec->downgraded) + return; + + tx_tspec->consumed_tx_time += tx_time; + + if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) { + tx_tspec->downgraded = true; + tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE; + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); + } +} + void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, - struct ieee80211_hdr *hdr, bool ack) + struct ieee80211_hdr *hdr, bool ack, u16 tx_time) { + ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time); + if (!ieee80211_is_data(hdr->frame_control)) return; @@ -3834,6 +3966,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) (unsigned long) sdata); setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, (unsigned long) sdata); + INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk, + ieee80211_sta_handle_tspec_ac_params_wk); ifmgd->flags = 0; ifmgd->powersave = sdata->wdev.ps; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 89290e33dafe..9612d89fad56 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -704,7 +704,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) - ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); + ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, + acked, info->status.tx_time); if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { if (info->flags & IEEE80211_TX_STAT_ACK) { diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 3b873989992c..d3c5672d775f 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -54,10 +54,18 @@ static int wme_downgrade_ac(struct sk_buff *skb) } static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb) + struct sta_info *sta, struct sk_buff *skb) { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + /* in case we are a client verify acm is not set for this ac */ - while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { + while (sdata->wmm_acm & BIT(skb->priority)) { + int ac = ieee802_1d_to_ac[skb->priority]; + + if (ifmgd->tx_tspec[ac].admitted_time && + skb->priority == ifmgd->tx_tspec[ac].up) + return ac; + if (wme_downgrade_ac(skb)) { /* * This should not really happen. The AP has marked all @@ -96,7 +104,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, p = ieee80211_get_qos_ctl(hdr); skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; - return ieee80211_downgrade_queue(sdata, skb); + return ieee80211_downgrade_queue(sdata, NULL, skb); } /* Indicate which queue to use. */ @@ -108,6 +116,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, const u8 *ra = NULL; bool qos = false; struct mac80211_qos_map *qos_map; + u16 ret; if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { skb->priority = 0; /* required for correct WPA/11i MIC */ @@ -148,27 +157,29 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, if (sta) qos = sta->sta.wme; } - rcu_read_unlock(); if (!qos) { skb->priority = 0; /* required for correct WPA/11i MIC */ - return IEEE80211_AC_BE; + ret = IEEE80211_AC_BE; + goto out; } if (skb->protocol == sdata->control_port_protocol) { skb->priority = 7; - return ieee80211_downgrade_queue(sdata, skb); + goto downgrade; } /* use the data classifier to determine what 802.1d tag the * data frame has */ - rcu_read_lock(); qos_map = rcu_dereference(sdata->qos_map); skb->priority = cfg80211_classify8021d(skb, qos_map ? &qos_map->qos_map : NULL); - rcu_read_unlock(); - return ieee80211_downgrade_queue(sdata, skb); + downgrade: + ret = ieee80211_downgrade_queue(sdata, sta, skb); + out: + rcu_read_unlock(); + return ret; } /** diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index 7fea4bb8acbc..80151edc5195 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h @@ -13,8 +13,6 @@ #include #include "ieee80211_i.h" -extern const int ieee802_1d_to_ac[8]; - u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_hdr *hdr); -- GitLab From b85b8d92c1d720a5b2229aa1bad9bd77f09b8ec5 Mon Sep 17 00:00:00 2001 From: Rob Ward Date: Tue, 21 Oct 2014 20:01:09 +0100 Subject: [PATCH 1006/9457] mtd: phram: fix asm/io.h include usage Modify phram to include rather than Signed-off-by: Rob Ward Signed-off-by: Brian Norris --- drivers/mtd/devices/phram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index effd9a4ef7ee..8b66e52ca3cc 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -17,7 +17,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include +#include #include #include #include -- GitLab From a1ff7d64c5361c15bac653708a679de13506d283 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 22 Sep 2014 00:33:13 +0200 Subject: [PATCH 1007/9457] mtd: bcm47xxpart: only register partitions if the trx header was filled Sometimes the trx offsets are 0, in that case there is no partition and we should not try to add one. Signed-off-by: Hauke Mehrtens [Brian: rewrapped] Signed-off-by: Brian Norris --- drivers/mtd/bcm47xxpart.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index f2db4d7d6c36..cc13ea5ce4d5 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -172,18 +172,26 @@ static int bcm47xxpart_parse(struct mtd_info *master, i++; } - bcm47xxpart_add_part(&parts[curr_part++], "linux", - offset + trx->offset[i], 0); - i++; + if (trx->offset[i]) { + bcm47xxpart_add_part(&parts[curr_part++], + "linux", + offset + trx->offset[i], + 0); + i++; + } /* * Pure rootfs size is known and can be calculated as: * trx->length - trx->offset[i]. We don't fill it as * we want to have jffs2 (overlay) in the same mtd. */ - bcm47xxpart_add_part(&parts[curr_part++], "rootfs", - offset + trx->offset[i], 0); - i++; + if (trx->offset[i]) { + bcm47xxpart_add_part(&parts[curr_part++], + "rootfs", + offset + trx->offset[i], + 0); + i++; + } last_trx_part = curr_part - 1; -- GitLab From 5f9f975b7984ffec0a25f55e58246aebf68794f4 Mon Sep 17 00:00:00 2001 From: Mark Knibbs Date: Sat, 4 Oct 2014 12:19:59 +0100 Subject: [PATCH 1008/9457] USB: serial: keyspan_pda: fix Entrega company name spelling Entrega is misspelled as Entregra or Entrgra, so fix that. Signed-off-by: Mark Knibbs Signed-off-by: Johan Hovold --- Documentation/usb/usb-serial.txt | 2 +- drivers/usb/serial/Kconfig | 4 ++-- drivers/usb/serial/keyspan_pda.c | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt index 5bd7926185e8..947fa62bccf2 100644 --- a/Documentation/usb/usb-serial.txt +++ b/Documentation/usb/usb-serial.txt @@ -145,7 +145,7 @@ Keyspan PDA Serial Adapter Single port DB-9 serial adapter, pushed as a PDA adapter for iMacs (mostly sold in Macintosh catalogs, comes in a translucent white/green dongle). Fairly simple device. Firmware is homebrew. - This driver also works for the Xircom/Entrgra single port serial adapter. + This driver also works for the Xircom/Entrega single port serial adapter. Current status: Things that work: diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index a69f7cd9d0bf..d185613bbd7d 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -606,10 +606,10 @@ config USB_SERIAL_CYBERJACK If unsure, say N. config USB_SERIAL_XIRCOM - tristate "USB Xircom / Entregra Single Port Serial Driver" + tristate "USB Xircom / Entrega Single Port Serial Driver" select USB_EZUSB_FX2 help - Say Y here if you want to use a Xircom or Entregra single port USB to + Say Y here if you want to use a Xircom or Entrega single port USB to serial converter device. This driver makes use of firmware developed from scratch by Brian Warner. diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 742d827f876c..dd97d8b572c3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -1,5 +1,5 @@ /* - * USB Keyspan PDA / Xircom / Entregra Converter driver + * USB Keyspan PDA / Xircom / Entrega Converter driver * * Copyright (C) 1999 - 2001 Greg Kroah-Hartman * Copyright (C) 1999, 2000 Brian Warner @@ -58,11 +58,11 @@ struct keyspan_pda_private { #define KEYSPAN_PDA_FAKE_ID 0x0103 #define KEYSPAN_PDA_ID 0x0104 /* no clue */ -/* For Xircom PGSDB9 and older Entregra version of the same device */ +/* For Xircom PGSDB9 and older Entrega version of the same device */ #define XIRCOM_VENDOR_ID 0x085a #define XIRCOM_FAKE_ID 0x8027 -#define ENTREGRA_VENDOR_ID 0x1645 -#define ENTREGRA_FAKE_ID 0x8093 +#define ENTREGA_VENDOR_ID 0x1645 +#define ENTREGA_FAKE_ID 0x8093 static const struct usb_device_id id_table_combined[] = { #ifdef KEYSPAN @@ -70,7 +70,7 @@ static const struct usb_device_id id_table_combined[] = { #endif #ifdef XIRCOM { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, - { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, + { USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) }, #endif { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, { } /* Terminating entry */ @@ -93,7 +93,7 @@ static const struct usb_device_id id_table_fake[] = { #ifdef XIRCOM static const struct usb_device_id id_table_fake_xircom[] = { { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, - { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, + { USB_DEVICE(ENTREGA_VENDOR_ID, ENTREGA_FAKE_ID) }, { } }; #endif @@ -667,7 +667,7 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial) #endif #ifdef XIRCOM else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || - (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) + (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGA_VENDOR_ID)) fw_name = "keyspan_pda/xircom_pgs.fw"; #endif else { @@ -744,7 +744,7 @@ static struct usb_serial_driver xircom_pgs_fake_device = { .owner = THIS_MODULE, .name = "xircom_no_firm", }, - .description = "Xircom / Entregra PGS - (prerenumeration)", + .description = "Xircom / Entrega PGS - (prerenumeration)", .id_table = id_table_fake_xircom, .num_ports = 1, .attach = keyspan_pda_fake_startup, -- GitLab From 4619194a49bfbbb03d20d4ca45c3eb1dc8297d9d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Oct 2014 13:43:29 +0200 Subject: [PATCH 1009/9457] mac80211: don't remove tainted keys after not programming When a key is tainted during resume, it is no longer programmed into the device; however, it's uploaded flag may (will) be set. Clear the flag when not programming it because it's tainted to avoid attempting to remove it again later. Signed-off-by: Johannes Berg --- net/mac80211/key.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 4712150dc210..434a91ad12c8 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -94,8 +94,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) might_sleep(); - if (key->flags & KEY_FLAG_TAINTED) + if (key->flags & KEY_FLAG_TAINTED) { + /* If we get here, it's during resume and the key is + * tainted so shouldn't be used/programmed any more. + * However, its flags may still indicate that it was + * programmed into the device (since we're in resume) + * so clear that flag now to avoid trying to remove + * it again later. + */ + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; return -EINVAL; + } if (!key->local->ops->set_key) goto out_unsupported; -- GitLab From afdb5cce979b7d3100d58bdce70c8be6093a8915 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 21 Oct 2014 23:11:00 +0200 Subject: [PATCH 1010/9457] HID: input: Map unknown consumer page codes to KEY_UNKNOWN Currently unknown consumer page codes are ignored, which means that they cannot later be mapped from userspace using udev / hwdb. Map them to KEY_UNKNOWN, so that userspace can remap them for keyboards which make up their own consumer page codes. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2df7fddbd119..7ea582be9c9a 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -862,7 +862,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; case 0x28c: map_key_clear(KEY_SEND); break; - default: goto ignore; + default: map_key_clear(KEY_UNKNOWN); } break; -- GitLab From c37de55efa1ccf018c27b876560725ff5e9f5701 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 22 Oct 2014 12:01:13 +0200 Subject: [PATCH 1011/9457] ALSA: pcm: Remove arch-dependent mmap kludges Since we have consistently dma_mmap_coherent() for all architectures, the current ifdef and arch-specific codes in pcm core can be cleaned up gracefully. Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 815396d8427f..aa6754da7929 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -35,9 +35,6 @@ #include #include #include -#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) -#include -#endif /* * Compatibility @@ -3251,20 +3248,6 @@ static inline struct page * snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs) { void *vaddr = substream->runtime->dma_area + ofs; -#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) - if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) - return virt_to_page(CAC_ADDR(vaddr)); -#endif -#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE) - if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) { - dma_addr_t addr = substream->runtime->dma_addr + ofs; - addr -= get_dma_offset(substream->dma_buffer.dev.dev); - /* assume dma_handle set via pfn_to_phys() in - * mm/dma-noncoherent.c - */ - return pfn_to_page(addr >> PAGE_SHIFT); - } -#endif return virt_to_page(vaddr); } @@ -3309,13 +3292,6 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { .fault = snd_pcm_mmap_data_fault, }; -#ifndef ARCH_HAS_DMA_MMAP_COHERENT -/* This should be defined / handled globally! */ -#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -#define ARCH_HAS_DMA_MMAP_COHERENT -#endif -#endif - /* * mmap the DMA buffer on RAM */ @@ -3331,7 +3307,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, area->vm_end - area->vm_start, area->vm_page_prot); } #endif /* CONFIG_GENERIC_ALLOCATOR */ -#ifdef ARCH_HAS_DMA_MMAP_COHERENT if (!substream->ops->page && substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) return dma_mmap_coherent(substream->dma_buffer.dev.dev, @@ -3339,11 +3314,6 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, substream->runtime->dma_area, substream->runtime->dma_addr, area->vm_end - area->vm_start); -#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) - if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV && - !plat_device_is_coherent(substream->dma_buffer.dev.dev)) - area->vm_page_prot = pgprot_noncached(area->vm_page_prot); -#endif /* ARCH_HAS_DMA_MMAP_COHERENT */ /* mmap with fault handler */ area->vm_ops = &snd_pcm_vm_ops_data_fault; return 0; -- GitLab From 78cb4d995b932d9014342ddc81ce0a5cc434ed98 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Oct 2014 12:14:56 +0200 Subject: [PATCH 1012/9457] ASoC: core: Use snd_ctl_enum_info() ... and reduce the open codes. Signed-off-by: Takashi Iwai Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..96ecdc30eb60 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2348,16 +2348,8 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, { struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = e->shift_l == e->shift_r ? 1 : 2; - uinfo->value.enumerated.items = e->items; - - if (uinfo->value.enumerated.item >= e->items) - uinfo->value.enumerated.item = e->items - 1; - strlcpy(uinfo->value.enumerated.name, - e->texts[uinfo->value.enumerated.item], - sizeof(uinfo->value.enumerated.name)); - return 0; + return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, + e->items, e->texts); } EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); -- GitLab From 63825f3a879ea2be569471643bb6aac73d9261f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 22 Oct 2014 12:04:46 +0200 Subject: [PATCH 1013/9457] ALSA: pcm: Disable mmap for known broken archs Some architectures like PARISC is known not to support mmap properly with the DMA buffer, where dma_mmap_coherent() returns -EINVAL unconditionally. From the API POV, we should rather drop the mmap support there and expose it before the user-space tries to call mmap. The patch contains again ugly ifdef's, unfortunately, as there is no global flag indicating this. Once when such macro is defined, we can get rid of this instead. Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index aa6754da7929..dc9a1355a4ab 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -192,6 +192,21 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream, return err; } +static bool hw_support_mmap(struct snd_pcm_substream *substream) +{ + if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP)) + return false; + /* check architectures that return -EINVAL from dma_mmap_coherent() */ + /* FIXME: this should be some global flag */ +#if defined(CONFIG_C6X) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) ||\ + defined(CONFIG_PARISC) || defined(CONFIG_XTENSA) + if (!substream->ops->mmap && + substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) + return false; +#endif + return true; +} + #undef RULES_DEBUG #ifdef RULES_DEBUG @@ -369,8 +384,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, } hw = &substream->runtime->hw; - if (!params->info) + if (!params->info) { params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; + if (!hw_support_mmap(substream)) + params->info &= ~(SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID); + } if (!params->fifo_size) { m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); @@ -2069,7 +2088,7 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; - if (hw->info & SNDRV_PCM_INFO_MMAP) { + if (hw_support_mmap(substream)) { if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) -- GitLab From 9313484238ca49fe5c7513dfcb36aaddcea8c298 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:28 +0200 Subject: [PATCH 1014/9457] ASoC: ak4535: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ak4535.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 30e297890fec..eced46d7d6cb 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -373,36 +373,19 @@ static struct snd_soc_dai_driver ak4535_dai = { .ops = &ak4535_dai_ops, }; -static int ak4535_suspend(struct snd_soc_codec *codec) -{ - ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int ak4535_resume(struct snd_soc_codec *codec) { snd_soc_cache_sync(codec); - ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } static int ak4535_probe(struct snd_soc_codec *codec) { - /* power on device */ - ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_codec_controls(codec, ak4535_snd_controls, ARRAY_SIZE(ak4535_snd_controls)); return 0; } -/* power down chip */ -static int ak4535_remove(struct snd_soc_codec *codec) -{ - ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static const struct regmap_config ak4535_regmap = { .reg_bits = 8, .val_bits = 8, @@ -417,10 +400,10 @@ static const struct regmap_config ak4535_regmap = { static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .probe = ak4535_probe, - .remove = ak4535_remove, - .suspend = ak4535_suspend, .resume = ak4535_resume, .set_bias_level = ak4535_set_bias_level, + .suspend_bias_off = true, + .dapm_widgets = ak4535_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), .dapm_routes = ak4535_audio_map, -- GitLab From 4caab4194a99e58c08c70e7df846b9bda948f353 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:29 +0200 Subject: [PATCH 1015/9457] ASoC: ak4535: Use table based setup for controls Makes the code slightly shorter and cleaner. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ak4535.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index eced46d7d6cb..9130d916f2f4 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -379,13 +379,6 @@ static int ak4535_resume(struct snd_soc_codec *codec) return 0; } -static int ak4535_probe(struct snd_soc_codec *codec) -{ - snd_soc_add_codec_controls(codec, ak4535_snd_controls, - ARRAY_SIZE(ak4535_snd_controls)); - return 0; -} - static const struct regmap_config ak4535_regmap = { .reg_bits = 8, .val_bits = 8, @@ -399,11 +392,12 @@ static const struct regmap_config ak4535_regmap = { }; static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { - .probe = ak4535_probe, .resume = ak4535_resume, .set_bias_level = ak4535_set_bias_level, .suspend_bias_off = true, + .controls = ak4535_snd_controls, + .num_controls = ARRAY_SIZE(ak4535_snd_controls), .dapm_widgets = ak4535_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), .dapm_routes = ak4535_audio_map, -- GitLab From 0b0171e3ad22b5a3be01bbafddede4ebea1769bd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:30 +0200 Subject: [PATCH 1016/9457] ASoC: ak4641: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ak4641.c | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 7afe8f482088..70861c7b1631 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -505,39 +505,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { }, }; -static int ak4641_suspend(struct snd_soc_codec *codec) -{ - ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int ak4641_resume(struct snd_soc_codec *codec) -{ - ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -static int ak4641_probe(struct snd_soc_codec *codec) -{ - /* power on device */ - ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int ak4641_remove(struct snd_soc_codec *codec) -{ - ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - - static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { - .probe = ak4641_probe, - .remove = ak4641_remove, - .suspend = ak4641_suspend, - .resume = ak4641_resume, .controls = ak4641_snd_controls, .num_controls = ARRAY_SIZE(ak4641_snd_controls), .dapm_widgets = ak4641_dapm_widgets, @@ -545,6 +513,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { .dapm_routes = ak4641_audio_map, .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), .set_bias_level = ak4641_set_bias_level, + .suspend_bias_off = true, }; static const struct regmap_config ak4641_regmap = { -- GitLab From 61ce9ee3aad2fc7a505a420957e8205c4050db69 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:31 +0200 Subject: [PATCH 1017/9457] ASoC: ak4642: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ak4642.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 041712592e29..dde8b49c19ad 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -491,23 +491,7 @@ static int ak4642_resume(struct snd_soc_codec *codec) return 0; } - -static int ak4642_probe(struct snd_soc_codec *codec) -{ - ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int ak4642_remove(struct snd_soc_codec *codec) -{ - ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { - .probe = ak4642_probe, - .remove = ak4642_remove, .resume = ak4642_resume, .set_bias_level = ak4642_set_bias_level, .controls = ak4642_snd_controls, -- GitLab From e48d73c697b77b798a82e86c937fc41e597a1471 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:32 +0200 Subject: [PATCH 1018/9457] ASoC: ak4671: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ak4671.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 998fa0c5a0b9..686cacb0e835 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -611,20 +611,7 @@ static struct snd_soc_dai_driver ak4671_dai = { .ops = &ak4671_dai_ops, }; -static int ak4671_probe(struct snd_soc_codec *codec) -{ - return ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -} - -static int ak4671_remove(struct snd_soc_codec *codec) -{ - ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { - .probe = ak4671_probe, - .remove = ak4671_remove, .set_bias_level = ak4671_set_bias_level, .controls = ak4671_snd_controls, .num_controls = ARRAY_SIZE(ak4671_snd_controls), -- GitLab From a613cc4063a315efe36f233006f424e958ef4e67 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:33 +0200 Subject: [PATCH 1019/9457] ASoC: max98088: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 2cd3e5427441..bb892b3178dc 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1887,25 +1887,6 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec) max98088_handle_eq_pdata(codec); } -#ifdef CONFIG_PM -static int max98088_suspend(struct snd_soc_codec *codec) -{ - max98088_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int max98088_resume(struct snd_soc_codec *codec) -{ - max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define max98088_suspend NULL -#define max98088_resume NULL -#endif - static int max98088_probe(struct snd_soc_codec *codec) { struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); @@ -1946,9 +1927,6 @@ static int max98088_probe(struct snd_soc_codec *codec) snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV); - /* initialize registers cache to hardware default */ - max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00); snd_soc_write(codec, M98088_REG_22_MIX_DAC, @@ -1974,7 +1952,6 @@ static int max98088_remove(struct snd_soc_codec *codec) { struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); - max98088_set_bias_level(codec, SND_SOC_BIAS_OFF); kfree(max98088->eq_texts); return 0; @@ -1983,9 +1960,9 @@ static int max98088_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_max98088 = { .probe = max98088_probe, .remove = max98088_remove, - .suspend = max98088_suspend, - .resume = max98088_resume, .set_bias_level = max98088_set_bias_level, + .suspend_bias_off = true, + .controls = max98088_snd_controls, .num_controls = ARRAY_SIZE(max98088_snd_controls), .dapm_widgets = max98088_dapm_widgets, -- GitLab From a8669f60321c8cb08af76438727b6460d1b591b6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:34 +0200 Subject: [PATCH 1020/9457] ASoC: max98095: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98095.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 0ee6797d5083..42103cafeb24 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2317,9 +2317,6 @@ static int max98095_probe(struct snd_soc_codec *codec) snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV); - /* initialize registers cache to hardware default */ - max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_write(codec, M98095_048_MIX_DAC_LR, M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR); @@ -2359,8 +2356,6 @@ static int max98095_remove(struct snd_soc_codec *codec) struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct i2c_client *client = to_i2c_client(codec->dev); - max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); - if (max98095->headphone_jack || max98095->mic_jack) max98095_jack_detect_disable(codec); -- GitLab From 46804120c59b1374f8beb2b8636ffe6b0a7c16c8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:35 +0200 Subject: [PATCH 1021/9457] ASoC: max9850: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max9850.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 4fdf5aaa236f..10f8e47ce2c2 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -291,25 +291,6 @@ static struct snd_soc_dai_driver max9850_dai = { .ops = &max9850_dai_ops, }; -#ifdef CONFIG_PM -static int max9850_suspend(struct snd_soc_codec *codec) -{ - max9850_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int max9850_resume(struct snd_soc_codec *codec) -{ - max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define max9850_suspend NULL -#define max9850_resume NULL -#endif - static int max9850_probe(struct snd_soc_codec *codec) { /* enable zero-detect */ @@ -324,9 +305,8 @@ static int max9850_probe(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_max9850 = { .probe = max9850_probe, - .suspend = max9850_suspend, - .resume = max9850_resume, .set_bias_level = max9850_set_bias_level, + .suspend_bias_off = true, .controls = max9850_controls, .num_controls = ARRAY_SIZE(max9850_controls), -- GitLab From 815b776cf5983ab69d548146fb979adac5dec4de Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:36 +0200 Subject: [PATCH 1022/9457] ASoC: sta32x: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sta32x.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 48740855566d..7e18200dd6a9 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -833,23 +833,6 @@ static struct snd_soc_dai_driver sta32x_dai = { .ops = &sta32x_dai_ops, }; -#ifdef CONFIG_PM -static int sta32x_suspend(struct snd_soc_codec *codec) -{ - sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int sta32x_resume(struct snd_soc_codec *codec) -{ - sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define sta32x_suspend NULL -#define sta32x_resume NULL -#endif - static int sta32x_probe(struct snd_soc_codec *codec) { struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); @@ -936,7 +919,6 @@ static int sta32x_remove(struct snd_soc_codec *codec) struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); sta32x_watchdog_stop(sta32x); - sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); return 0; @@ -955,9 +937,8 @@ static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg) static const struct snd_soc_codec_driver sta32x_codec = { .probe = sta32x_probe, .remove = sta32x_remove, - .suspend = sta32x_suspend, - .resume = sta32x_resume, .set_bias_level = sta32x_set_bias_level, + .suspend_bias_off = true, .controls = sta32x_snd_controls, .num_controls = ARRAY_SIZE(sta32x_snd_controls), .dapm_widgets = sta32x_dapm_widgets, -- GitLab From 2062c1ff3596e1ae8aafe8082460d03d9a420282 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:37 +0200 Subject: [PATCH 1023/9457] ASoC: sta350: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sta350.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index cc97dd52aa9c..bda2ee18769e 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -912,23 +912,6 @@ static struct snd_soc_dai_driver sta350_dai = { .ops = &sta350_dai_ops, }; -#ifdef CONFIG_PM -static int sta350_suspend(struct snd_soc_codec *codec) -{ - sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int sta350_resume(struct snd_soc_codec *codec) -{ - sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define sta350_suspend NULL -#define sta350_resume NULL -#endif - static int sta350_probe(struct snd_soc_codec *codec) { struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); @@ -1065,7 +1048,6 @@ static int sta350_remove(struct snd_soc_codec *codec) { struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); - sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); return 0; @@ -1074,9 +1056,8 @@ static int sta350_remove(struct snd_soc_codec *codec) static const struct snd_soc_codec_driver sta350_codec = { .probe = sta350_probe, .remove = sta350_remove, - .suspend = sta350_suspend, - .resume = sta350_resume, .set_bias_level = sta350_set_bias_level, + .suspend_bias_off = true, .controls = sta350_snd_controls, .num_controls = ARRAY_SIZE(sta350_snd_controls), .dapm_widgets = sta350_dapm_widgets, -- GitLab From cfbb77ce368b8d4181e06f8982a440702567eb98 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:38 +0200 Subject: [PATCH 1024/9457] ASoC: sta529: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sta529.c | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 89c748dd3d6e..b0f436d10125 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -319,41 +319,10 @@ static struct snd_soc_dai_driver sta529_dai = { .ops = &sta529_dai_ops, }; -static int sta529_probe(struct snd_soc_codec *codec) -{ - sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -/* power down chip */ -static int sta529_remove(struct snd_soc_codec *codec) -{ - sta529_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int sta529_suspend(struct snd_soc_codec *codec) -{ - sta529_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int sta529_resume(struct snd_soc_codec *codec) -{ - sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - static const struct snd_soc_codec_driver sta529_codec_driver = { - .probe = sta529_probe, - .remove = sta529_remove, .set_bias_level = sta529_set_bias_level, - .suspend = sta529_suspend, - .resume = sta529_resume, + .suspend_bias_off = true, + .controls = sta529_snd_controls, .num_controls = ARRAY_SIZE(sta529_snd_controls), }; -- GitLab From 4c07a43d9691ab1f264337d683dc8655b1edca46 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 10:56:39 +0200 Subject: [PATCH 1025/9457] ASoC: stac9766: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/stac9766.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 53b810d23fea..9878534ccd16 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -254,12 +254,6 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) return 0; } -static int stac9766_codec_suspend(struct snd_soc_codec *codec) -{ - stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int stac9766_codec_resume(struct snd_soc_codec *codec) { u16 id, reset; @@ -278,7 +272,6 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec) reset++; goto reset; } - stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -349,8 +342,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) goto codec_err; } - stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls, ARRAY_SIZE(stac9766_snd_ac97_controls)); @@ -371,9 +362,9 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { .write = stac9766_ac97_write, .read = stac9766_ac97_read, .set_bias_level = stac9766_set_bias_level, + .suspend_bias_off = true, .probe = stac9766_codec_probe, .remove = stac9766_codec_remove, - .suspend = stac9766_codec_suspend, .resume = stac9766_codec_resume, .reg_cache_size = ARRAY_SIZE(stac9766_reg), .reg_word_size = sizeof(u16), -- GitLab From 15f6b09a00a6d12b594c439fb3a7e2d113a05592 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 19 Oct 2014 09:07:35 +0200 Subject: [PATCH 1026/9457] ASoC: soc-compress: consolidate two identical branches The actions taken in both branches are identical, so we can simplify the code. Spotted by Coverity. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/soc-compress.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index cecfab3cc948..590a82f01d0b 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -258,10 +258,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); - else - dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; @@ -456,11 +453,7 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, if (ret < 0) goto out; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); - else - dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); - + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; out: -- GitLab From 5e3363ad1b7b2e1f197a3f56b01e21cb155ad454 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 16 Oct 2014 11:24:26 -0700 Subject: [PATCH 1027/9457] ASoC: rt5677: add GPIO IRQ support This allows to enable Mic Jack detection feature Signed-off-by: Oder Chiou Modified-by: Anatol Pomozov Signed-off-by: Anatol Pomozov Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/rt5677.txt | 10 ++ include/sound/rt5677.h | 7 + sound/soc/codecs/rt5677.c | 134 ++++++++++++++++++ sound/soc/codecs/rt5677.h | 49 +++++++ 4 files changed, 200 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt b/Documentation/devicetree/bindings/sound/rt5677.txt index f82f0e906cd9..740ff771aa8b 100644 --- a/Documentation/devicetree/bindings/sound/rt5677.txt +++ b/Documentation/devicetree/bindings/sound/rt5677.txt @@ -33,6 +33,15 @@ Optional properties: 1 - pull down 2 - pull up +- realtek,jd1-gpio + Configures GPIO Mic Jack detection 1. + Select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively. + +- realtek,jd2-gpio +- realtek,jd3-gpio + Configures GPIO Mic Jack detection 2 and 3. + Select 0 ~ 3 as OFF, GPIO4, GPIO5 and GPIO6 respectively. + Pins on the device (for linking into audio routes): * IN1P @@ -63,4 +72,5 @@ rt5677 { <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,in1-differential = "true"; realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */ + realtek,jd2-gpio = <3>; /* Enables Jack detection for GPIO6 */ }; diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h index a56b429a1dbc..d9eb7d861cd0 100644 --- a/include/sound/rt5677.h +++ b/include/sound/rt5677.h @@ -30,6 +30,13 @@ struct rt5677_platform_data { /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ u8 gpio_config[6]; + + /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ + unsigned int jd1_gpio; + /* jd2 and jd3 can select 0 ~ 3 as + OFF, GPIO4, GPIO5 and GPIO6 respectively */ + unsigned int jd2_gpio; + unsigned int jd3_gpio; }; #endif diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index d17d079fdcf3..6c73dfd22a0c 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -3614,6 +3614,46 @@ static void rt5677_gpio_config(struct rt5677_priv *rt5677, unsigned offset, } } +static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct rt5677_priv *rt5677 = gpio_to_rt5677(chip); + struct regmap_irq_chip_data *data = rt5677->irq_data; + int irq; + + if (offset >= RT5677_GPIO1 && offset <= RT5677_GPIO3) { + if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || + (rt5677->pdata.jd1_gpio == 2 && + offset == RT5677_GPIO2) || + (rt5677->pdata.jd1_gpio == 3 && + offset == RT5677_GPIO3)) { + irq = RT5677_IRQ_JD1; + } else { + return -ENXIO; + } + } + + if (offset >= RT5677_GPIO4 && offset <= RT5677_GPIO6) { + if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || + (rt5677->pdata.jd2_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd2_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD2; + } else if ((rt5677->pdata.jd3_gpio == 1 && + offset == RT5677_GPIO4) || + (rt5677->pdata.jd3_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd3_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD3; + } else { + return -ENXIO; + } + } + + return regmap_irq_get_virq(data, irq); +} + static struct gpio_chip rt5677_template_chip = { .label = "rt5677", .owner = THIS_MODULE, @@ -3621,6 +3661,7 @@ static struct gpio_chip rt5677_template_chip = { .set = rt5677_gpio_set, .direction_input = rt5677_gpio_direction_in, .get = rt5677_gpio_get, + .to_irq = rt5677_to_irq, .can_sleep = 1, }; @@ -3685,6 +3726,31 @@ static int rt5677_probe(struct snd_soc_codec *codec) for (i = 0; i < RT5677_GPIO_NUM; i++) rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); + if (rt5677->irq_data) { + regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, 0x8000, + 0x8000); + regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x0018, + 0x0008); + + if (rt5677->pdata.jd1_gpio) + regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, + RT5677_SEL_GPIO_JD1_MASK, + rt5677->pdata.jd1_gpio << + RT5677_SEL_GPIO_JD1_SFT); + + if (rt5677->pdata.jd2_gpio) + regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, + RT5677_SEL_GPIO_JD2_MASK, + rt5677->pdata.jd2_gpio << + RT5677_SEL_GPIO_JD2_SFT); + + if (rt5677->pdata.jd3_gpio) + regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, + RT5677_SEL_GPIO_JD3_MASK, + rt5677->pdata.jd3_gpio << + RT5677_SEL_GPIO_JD3_SFT); + } + mutex_init(&rt5677->dsp_cmd_lock); return 0; @@ -3915,9 +3981,74 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) of_property_read_u8_array(np, "realtek,gpio-config", rt5677->pdata.gpio_config, RT5677_GPIO_NUM); + of_property_read_u32(np, "realtek,jd1-gpio", &rt5677->pdata.jd1_gpio); + of_property_read_u32(np, "realtek,jd2-gpio", &rt5677->pdata.jd2_gpio); + of_property_read_u32(np, "realtek,jd3-gpio", &rt5677->pdata.jd3_gpio); + return 0; } +static struct regmap_irq rt5677_irqs[] = { + [RT5677_IRQ_JD1] = { + .reg_offset = 0, + .mask = RT5677_EN_IRQ_GPIO_JD1, + }, + [RT5677_IRQ_JD2] = { + .reg_offset = 0, + .mask = RT5677_EN_IRQ_GPIO_JD2, + }, + [RT5677_IRQ_JD3] = { + .reg_offset = 0, + .mask = RT5677_EN_IRQ_GPIO_JD3, + }, +}; + +static struct regmap_irq_chip rt5677_irq_chip = { + .name = "rt5677", + .irqs = rt5677_irqs, + .num_irqs = ARRAY_SIZE(rt5677_irqs), + + .num_regs = 1, + .status_base = RT5677_IRQ_CTRL1, + .mask_base = RT5677_IRQ_CTRL1, + .mask_invert = 1, +}; + +int rt5677_irq_init(struct i2c_client *i2c) +{ + int ret; + struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); + + if (!rt5677->pdata.jd1_gpio && + !rt5677->pdata.jd2_gpio && + !rt5677->pdata.jd3_gpio) + return 0; + + if (!i2c->irq) { + dev_err(&i2c->dev, "No interrupt specified\n"); + return -EINVAL; + } + + ret = regmap_add_irq_chip(rt5677->regmap, i2c->irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0, + &rt5677_irq_chip, &rt5677->irq_data); + + if (ret != 0) { + dev_err(&i2c->dev, "Failed to register IRQ chip: %d\n", ret); + return ret; + } + + return 0; +} + +void rt5677_irq_exit(struct i2c_client *i2c) +{ + struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); + + if (rt5677->irq_data) + regmap_del_irq_chip(i2c->irq, rt5677->irq_data); +} + static int rt5677_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -4015,6 +4146,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, } rt5677_init_gpio(i2c); + rt5677_irq_init(i2c); return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677, rt5677_dai, ARRAY_SIZE(rt5677_dai)); @@ -4022,6 +4154,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, static int rt5677_i2c_remove(struct i2c_client *i2c) { + rt5677_irq_exit(i2c); + snd_soc_unregister_codec(&i2c->dev); rt5677_free_gpio(i2c); diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 20efa4a4c82c..d2c743c255a1 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -1368,6 +1368,48 @@ #define RT5677_SEL_SRC_IB01 (0x1 << 0) #define RT5677_SEL_SRC_IB01_SFT 0 +/* Jack Detect Control 1 (0xb5) */ +#define RT5677_SEL_GPIO_JD1_MASK (0x3 << 14) +#define RT5677_SEL_GPIO_JD1_SFT 14 +#define RT5677_SEL_GPIO_JD2_MASK (0x3 << 12) +#define RT5677_SEL_GPIO_JD2_SFT 12 +#define RT5677_SEL_GPIO_JD3_MASK (0x3 << 10) +#define RT5677_SEL_GPIO_JD3_SFT 10 + +/* IRQ Control 1 (0xbd) */ +#define RT5677_STA_GPIO_JD1 (0x1 << 15) +#define RT5677_STA_GPIO_JD1_SFT 15 +#define RT5677_EN_IRQ_GPIO_JD1 (0x1 << 14) +#define RT5677_EN_IRQ_GPIO_JD1_SFT 14 +#define RT5677_EN_GPIO_JD1_STICKY (0x1 << 13) +#define RT5677_EN_GPIO_JD1_STICKY_SFT 13 +#define RT5677_INV_GPIO_JD1 (0x1 << 12) +#define RT5677_INV_GPIO_JD1_SFT 12 +#define RT5677_STA_GPIO_JD2 (0x1 << 11) +#define RT5677_STA_GPIO_JD2_SFT 11 +#define RT5677_EN_IRQ_GPIO_JD2 (0x1 << 10) +#define RT5677_EN_IRQ_GPIO_JD2_SFT 10 +#define RT5677_EN_GPIO_JD2_STICKY (0x1 << 9) +#define RT5677_EN_GPIO_JD2_STICKY_SFT 9 +#define RT5677_INV_GPIO_JD2 (0x1 << 8) +#define RT5677_INV_GPIO_JD2_SFT 8 +#define RT5677_STA_MICBIAS1_OVCD (0x1 << 7) +#define RT5677_STA_MICBIAS1_OVCD_SFT 7 +#define RT5677_EN_IRQ_MICBIAS1_OVCD (0x1 << 6) +#define RT5677_EN_IRQ_MICBIAS1_OVCD_SFT 6 +#define RT5677_EN_MICBIAS1_OVCD_STICKY (0x1 << 5) +#define RT5677_EN_MICBIAS1_OVCD_STICKY_SFT 5 +#define RT5677_INV_MICBIAS1_OVCD (0x1 << 4) +#define RT5677_INV_MICBIAS1_OVCD_SFT 4 +#define RT5677_STA_GPIO_JD3 (0x1 << 3) +#define RT5677_STA_GPIO_JD3_SFT 3 +#define RT5677_EN_IRQ_GPIO_JD3 (0x1 << 2) +#define RT5677_EN_IRQ_GPIO_JD3_SFT 2 +#define RT5677_EN_GPIO_JD3_STICKY (0x1 << 1) +#define RT5677_EN_GPIO_JD3_STICKY_SFT 1 +#define RT5677_INV_GPIO_JD3 (0x1 << 0) +#define RT5677_INV_GPIO_JD3_SFT 0 + /* GPIO status (0xbf) */ #define RT5677_GPIO6_STATUS_MASK (0x1 << 5) #define RT5677_GPIO6_STATUS_SFT 5 @@ -1545,6 +1587,12 @@ enum { RT5677_GPIO_NUM, }; +enum { + RT5677_IRQ_JD1, + RT5677_IRQ_JD2, + RT5677_IRQ_JD3, +}; + struct rt5677_priv { struct snd_soc_codec *codec; struct rt5677_platform_data pdata; @@ -1565,6 +1613,7 @@ struct rt5677_priv { struct gpio_chip gpio_chip; #endif bool dsp_vad_en; + struct regmap_irq_chip_data *irq_data; }; #endif /* __RT5677_H__ */ -- GitLab From cdc4508b4d1c609e3b0e4f23697edbee0d23b86e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 19:36:33 +0200 Subject: [PATCH 1028/9457] ASoC: dapm: Reduce number of checked paths in dapm_widget_in_card_paths() Each widget has a list of all the paths that it is connected to. There is no need to iterate over all paths when we are only interested in the paths of a specific widget. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 65 ++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 39f992bc2b6a..2c4bfdbae88f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3788,35 +3788,54 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, } EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); +/** + * dapm_is_external_path() - Checks if a path is a external path + * @card: The card the path belongs to + * @path: The path to check + * + * Returns true if the path is either between two different DAPM contexts or + * between two external pins of the same DAPM context. Otherwise returns + * false. + */ +static bool dapm_is_external_path(struct snd_soc_card *card, + struct snd_soc_dapm_path *path) +{ + dev_dbg(card->dev, + "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n", + path->source->name, path->source->id, path->source->dapm, + path->sink->name, path->sink->id, path->sink->dapm); + + /* Connection between two different DAPM contexts */ + if (path->source->dapm != path->sink->dapm) + return true; + + /* Loopback connection from external pin to external pin */ + if (path->sink->id == snd_soc_dapm_input) { + switch (path->source->id) { + case snd_soc_dapm_output: + case snd_soc_dapm_micbias: + return true; + default: + break; + } + } + + return false; +} + static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card, struct snd_soc_dapm_widget *w) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &card->paths, list) { - if ((p->source == w) || (p->sink == w)) { - dev_dbg(card->dev, - "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n", - p->source->name, p->source->id, p->source->dapm, - p->sink->name, p->sink->id, p->sink->dapm); + list_for_each_entry(p, &w->sources, list_sink) { + if (dapm_is_external_path(card, p)) + return true; + } - /* Connected to something other than the codec */ - if (p->source->dapm != p->sink->dapm) - return true; - /* - * Loopback connection from codec external pin to - * codec external pin - */ - if (p->sink->id == snd_soc_dapm_input) { - switch (p->source->id) { - case snd_soc_dapm_output: - case snd_soc_dapm_micbias: - return true; - default: - break; - } - } - } + list_for_each_entry(p, &w->sinks, list_source) { + if (dapm_is_external_path(card, p)) + return true; } return false; -- GitLab From 7ddd4cd5c31ccaf32febe52462f9fdc915893212 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 19:36:34 +0200 Subject: [PATCH 1029/9457] ASoC: dapm: Remove always true path source/sink checks A path has always a valid source and a valid sink otherwise we wouldn't add it in the first place. Hence all tests that check if sink/source is non NULL always evaluate to true and can be removed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2c4bfdbae88f..28269f219e16 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -909,7 +909,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, trace_snd_soc_dapm_output_path(widget, path); - if (path->sink && path->connect) { + if (path->connect) { path->walked = 1; path->walking = 1; @@ -1017,7 +1017,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, trace_snd_soc_dapm_input_path(widget, path); - if (path->source && path->connect) { + if (path->connect) { path->walked = 1; path->walking = 1; @@ -1219,9 +1219,6 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) !path->connected(path->source, path->sink)) continue; - if (!path->sink) - continue; - if (dapm_widget_power_check(path->sink)) return 1; } @@ -1636,12 +1633,9 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, /* If we changed our power state perhaps our neigbours changed * also. */ - list_for_each_entry(path, &w->sources, list_sink) { - if (path->source) { - dapm_widget_set_peer_power(path->source, power, - path->connect); - } - } + list_for_each_entry(path, &w->sources, list_sink) + dapm_widget_set_peer_power(path->source, power, path->connect); + switch (w->id) { case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: @@ -1650,12 +1644,9 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, /* Supplies can't affect their outputs, only their inputs */ break; default: - list_for_each_entry(path, &w->sinks, list_source) { - if (path->sink) { - dapm_widget_set_peer_power(path->sink, power, - path->connect); - } - } + list_for_each_entry(path, &w->sinks, list_source) + dapm_widget_set_peer_power(path->sink, power, + path->connect); break; } -- GitLab From cdef2ad3ae64cc1ab2daeff26335e0dde988eed7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 19:36:38 +0200 Subject: [PATCH 1030/9457] ASoC: dapm: Remove special DAI widget power check functions dapm_adc_check_power() checks if the widget is active, if yes it only checks whether there are any connected input paths. Otherwise it calls dapm_generic_check_power() which will check for both connected input and output paths. But the function that checks for connected output paths will return true if the widget is a active sink. Which means the generic power check function will work just fine and there is no need for a special power check function. The same applies for dapm_dac_check_power(), but with input and output paths reversed. This patch removes both dapm_adc_check_power() and dapm_dac_check_power() and replace their usage with dapm_generic_check_power(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 28269f219e16..219d73c27a8c 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1169,38 +1169,6 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) return out != 0 && in != 0; } -/* Check to see if an ADC has power */ -static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) -{ - int in; - - DAPM_UPDATE_STAT(w, power_checks); - - if (w->active) { - in = is_connected_input_ep(w, NULL); - dapm_clear_walk_input(w->dapm, &w->sources); - return in != 0; - } else { - return dapm_generic_check_power(w); - } -} - -/* Check to see if a DAC has power */ -static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) -{ - int out; - - DAPM_UPDATE_STAT(w, power_checks); - - if (w->active) { - out = is_connected_output_ep(w, NULL); - dapm_clear_walk_output(w->dapm, &w->sinks); - return out != 0; - } else { - return dapm_generic_check_power(w); - } -} - /* Check to see if a power supply is needed */ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) { @@ -3086,12 +3054,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_mux: w->power_check = dapm_generic_check_power; break; - case snd_soc_dapm_dai_out: - w->power_check = dapm_adc_check_power; - break; - case snd_soc_dapm_dai_in: - w->power_check = dapm_dac_check_power; - break; case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: case snd_soc_dapm_dac: @@ -3106,6 +3068,8 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_mic: case snd_soc_dapm_line: case snd_soc_dapm_dai_link: + case snd_soc_dapm_dai_out: + case snd_soc_dapm_dai_in: w->power_check = dapm_generic_check_power; break; case snd_soc_dapm_supply: -- GitLab From 130897ac5ac03adb4604d27497c378c64c7b22dd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 20 Oct 2014 19:36:39 +0200 Subject: [PATCH 1031/9457] ASoC: dapm: Remove path 'walked' flag The 'walked' flag was used to avoid walking paths that have already been walked. But since we started caching the number of inputs and outputs of a path we never actually get into a situation where we try to walk a path that has the 'walked' flag set. There are two cases in which we can end up walking a path multiple times within a single run of is_connected_output_ep() or is_connected_input_ep(). 1) If a path splits up and rejoins later: .--> C ---v A -> B E --> F '--> D ---^ When walking from A to F we'll end up at E twice, once via C and once via D. But since we do a depth first search we'll fully discover the path and initialize the number of outputs/inputs of the widget the first time we get there. The second time we get there we'll use the cached value and not bother to check any of the paths again. So we'll never see a path where 'walked' is set in this case. 2) If there is a circle: A --> B <-- C <-.--> F '--> D ---' When walking from A to F we'll end up twice at B. But since there is a circle the 'walking' flag will still be set on B once we get there the second time. This means we won't look at any of it's outgoing paths. So in this case we won't ever see a path where 'walked' is set either. So it is safe to remove the flag. This on one hand means we remove some always true checks from one of the hottest paths of the DAPM algorithm and on the other hand means we do not have to do the tedious clearing of the flag after checking the number inputs or outputs of a widget. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 1 - sound/soc/soc-dapm.c | 49 ++-------------------------------------- 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 3a4d7da67b8d..ebb93f29e4f3 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -508,7 +508,6 @@ struct snd_soc_dapm_path { /* status */ u32 connect:1; /* source and sink widgets are connected */ - u32 walked:1; /* path has been walked */ u32 walking:1; /* path is in the process of being walked */ u32 weak:1; /* path ignored for power management */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 219d73c27a8c..f03e0cfc65be 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -754,34 +754,6 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) return 0; } -/* reset 'walked' bit for each dapm path */ -static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm, - struct list_head *sink) -{ - struct snd_soc_dapm_path *p; - - list_for_each_entry(p, sink, list_source) { - if (p->walked) { - p->walked = 0; - dapm_clear_walk_output(dapm, &p->sink->sinks); - } - } -} - -static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm, - struct list_head *source) -{ - struct snd_soc_dapm_path *p; - - list_for_each_entry(p, source, list_sink) { - if (p->walked) { - p->walked = 0; - dapm_clear_walk_input(dapm, &p->source->sources); - } - } -} - - /* We implement power down on suspend by checking the power state of * the ALSA card - when we are suspending the ALSA state for the card * is set to D3. @@ -904,13 +876,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, if (path->walking) return 1; - if (path->walked) - continue; - trace_snd_soc_dapm_output_path(widget, path); if (path->connect) { - path->walked = 1; path->walking = 1; /* do we need to add this widget to the list ? */ @@ -1012,13 +980,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, if (path->walking) return 1; - if (path->walked) - continue; - trace_snd_soc_dapm_input_path(widget, path); if (path->connect) { - path->walked = 1; path->walking = 1; /* do we need to add this widget to the list ? */ @@ -1066,15 +1030,10 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); dapm_reset(card); - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (stream == SNDRV_PCM_STREAM_PLAYBACK) paths = is_connected_output_ep(dai->playback_widget, list); - dapm_clear_walk_output(&card->dapm, - &dai->playback_widget->sinks); - } else { + else paths = is_connected_input_ep(dai->capture_widget, list); - dapm_clear_walk_input(&card->dapm, - &dai->capture_widget->sources); - } trace_snd_soc_dapm_connected(paths, stream); mutex_unlock(&card->dapm_mutex); @@ -1163,9 +1122,7 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) DAPM_UPDATE_STAT(w, power_checks); in = is_connected_input_ep(w, NULL); - dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk_output(w->dapm, &w->sinks); return out != 0 && in != 0; } @@ -1823,9 +1780,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file, return -ENOMEM; in = is_connected_input_ep(w, NULL); - dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk_output(w->dapm, &w->sinks); ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", w->name, w->power ? "On" : "Off", -- GitLab From 2d27deb40db74c751c991e96ca91d675f966a0c5 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 22 Oct 2014 20:04:08 +0800 Subject: [PATCH 1032/9457] ASoC: rt5677: rt5677_irq_init() can be static sound/soc/codecs/rt5677.c:4017:5: sparse: symbol 'rt5677_irq_init' was not declared. Should it be static? sound/soc/codecs/rt5677.c:4044:6: sparse: symbol 'rt5677_irq_exit' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 6c73dfd22a0c..413bccbff19e 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -4014,7 +4014,7 @@ static struct regmap_irq_chip rt5677_irq_chip = { .mask_invert = 1, }; -int rt5677_irq_init(struct i2c_client *i2c) +static int rt5677_irq_init(struct i2c_client *i2c) { int ret; struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); @@ -4041,7 +4041,7 @@ int rt5677_irq_init(struct i2c_client *i2c) return 0; } -void rt5677_irq_exit(struct i2c_client *i2c) +static void rt5677_irq_exit(struct i2c_client *i2c) { struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); -- GitLab From d4efafcc040dcc91b09fd393756e4ee4ad7bf9f2 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 22 Oct 2014 10:17:38 -0700 Subject: [PATCH 1033/9457] mtd: docg3: fix 'defined but not used' warning With CONFIG_OF=n, we can see the following warning: drivers/mtd/devices/docg3.c:2122:28: warning: 'docg3_dt_ids' defined but not used [-Wunused-variable] static struct of_device_id docg3_dt_ids[] = { Signed-off-by: Brian Norris Cc: Robert Jarzmik --- drivers/mtd/devices/docg3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index abd94668a05d..0d9d3ee68b61 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -2119,11 +2119,13 @@ static int __exit docg3_release(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF static struct of_device_id docg3_dt_ids[] = { { .compatible = "m-systems,diskonchip-g3" }, {} }; MODULE_DEVICE_TABLE(of, docg3_dt_ids); +#endif static struct platform_driver g3_driver = { .driver = { -- GitLab From 254af0a3c7fe1959b0a865660f2f2004e023ddc3 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Wed, 8 Oct 2014 11:14:10 -0700 Subject: [PATCH 1034/9457] Input: mpr121 - switch to using managed resources This change switches the driver to use devm_* managed resources APIs to request the resources in probe to simplify probe error path and module unloading and does away with remove function. Signed-off-by: Pramod Gurav Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mpr121_touchkey.c | 42 +++++++----------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 009c82256e89..3aa2ec45bcab 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -214,13 +214,14 @@ static int mpr_touchkey_probe(struct i2c_client *client, return -EINVAL; } - mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!mpr121 || !input_dev) { - dev_err(&client->dev, "Failed to allocate memory\n"); - error = -ENOMEM; - goto err_free_mem; - } + mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), + GFP_KERNEL); + if (!mpr121) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&client->dev); + if (!input_dev) + return -ENOMEM; mpr121->client = client; mpr121->input_dev = input_dev; @@ -243,43 +244,25 @@ static int mpr_touchkey_probe(struct i2c_client *client, error = mpr121_phys_init(pdata, mpr121, client); if (error) { dev_err(&client->dev, "Failed to init register\n"); - goto err_free_mem; + return error; } - error = request_threaded_irq(client->irq, NULL, + error = devm_request_threaded_irq(&client->dev, client->irq, NULL, mpr_touchkey_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->dev.driver->name, mpr121); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); - goto err_free_mem; + return error; } error = input_register_device(input_dev); if (error) - goto err_free_irq; + return error; i2c_set_clientdata(client, mpr121); device_init_wakeup(&client->dev, pdata->wakeup); - return 0; - -err_free_irq: - free_irq(client->irq, mpr121); -err_free_mem: - input_free_device(input_dev); - kfree(mpr121); - return error; -} - -static int mpr_touchkey_remove(struct i2c_client *client) -{ - struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); - - free_irq(client->irq, mpr121); - input_unregister_device(mpr121->input_dev); - kfree(mpr121); - return 0; } @@ -327,7 +310,6 @@ static struct i2c_driver mpr_touchkey_driver = { }, .id_table = mpr121_id, .probe = mpr_touchkey_probe, - .remove = mpr_touchkey_remove, }; module_i2c_driver(mpr_touchkey_driver); -- GitLab From 38c3807252085f97e1359400c8bf1312da3168c6 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Wed, 8 Oct 2014 11:19:43 -0700 Subject: [PATCH 1035/9457] Input: pxa27x_keypad - switch to using managed resources This change switches ithe driver to use devm_* APIs to allocate resources. This helps to simplify failure path in probe function and module unloading and does away with remove function. Signed-off-by: Pramod Gurav Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pxa27x_keypad.c | 84 ++++++-------------------- 1 file changed, 20 insertions(+), 64 deletions(-) diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index a15063bea700..e08fc0ae913d 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -741,37 +741,27 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) return -ENXIO; } - keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!keypad || !input_dev) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - error = -ENOMEM; - goto failed_free; - } + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), + GFP_KERNEL); + if (!keypad) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) + return -ENOMEM; keypad->pdata = pdata; keypad->input_dev = input_dev; keypad->irq = irq; - res = request_mem_region(res->start, resource_size(res), pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto failed_free; - } - - keypad->mmio_base = ioremap(res->start, resource_size(res)); - if (keypad->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - error = -ENXIO; - goto failed_free_mem; - } + keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(keypad->mmio_base)) + return PTR_ERR(keypad->mmio_base); - keypad->clk = clk_get(&pdev->dev, NULL); + keypad->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); - error = PTR_ERR(keypad->clk); - goto failed_free_io; + return PTR_ERR(keypad->clk); } input_dev->name = pdev->name; @@ -802,7 +792,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) } if (error) { dev_err(&pdev->dev, "failed to build keycode\n"); - goto failed_put_clk; + return error; } keypad->row_shift = get_count_order(pdata->matrix_key_cols); @@ -812,61 +802,26 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) input_dev->evbit[0] |= BIT_MASK(EV_REL); } - error = request_irq(irq, pxa27x_keypad_irq_handler, 0, - pdev->name, keypad); + error = devm_request_irq(&pdev->dev, irq, pxa27x_keypad_irq_handler, + 0, pdev->name, keypad); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); - goto failed_put_clk; + return error; } /* Register the input device */ error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto failed_free_irq; + return error; } platform_set_drvdata(pdev, keypad); device_init_wakeup(&pdev->dev, 1); return 0; - -failed_free_irq: - free_irq(irq, keypad); -failed_put_clk: - clk_put(keypad->clk); -failed_free_io: - iounmap(keypad->mmio_base); -failed_free_mem: - release_mem_region(res->start, resource_size(res)); -failed_free: - input_free_device(input_dev); - kfree(keypad); - return error; } -static int pxa27x_keypad_remove(struct platform_device *pdev) -{ - struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); - struct resource *res; - - free_irq(keypad->irq, keypad); - clk_put(keypad->clk); - - input_unregister_device(keypad->input_dev); - iounmap(keypad->mmio_base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(keypad); - - return 0; -} - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa27x-keypad"); - #ifdef CONFIG_OF static const struct of_device_id pxa27x_keypad_dt_match[] = { { .compatible = "marvell,pxa27x-keypad" }, @@ -877,7 +832,6 @@ MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match); static struct platform_driver pxa27x_keypad_driver = { .probe = pxa27x_keypad_probe, - .remove = pxa27x_keypad_remove, .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), @@ -889,3 +843,5 @@ module_platform_driver(pxa27x_keypad_driver); MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); MODULE_LICENSE("GPL"); +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:pxa27x-keypad"); -- GitLab From dae7aa8d849615134a11704cbd37fb45a22bd316 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Wed, 8 Oct 2014 11:26:29 -0700 Subject: [PATCH 1036/9457] Input: lpc32xx-keys - switch to using managed resources This change switches to using devm_* managed resources APIs to request the resources in probe to simplify probe error path and module unloading. Signed-off-by: Pramod Gurav Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/lpc32xx-keys.c | 92 ++++++--------------------- 1 file changed, 20 insertions(+), 72 deletions(-) diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 8b1b01361ec6..9e9786d576cb 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -66,7 +66,6 @@ struct lpc32xx_kscan_drv { struct input_dev *input; struct clk *clk; - struct resource *iores; void __iomem *kscan_base; unsigned int irq; @@ -188,32 +187,27 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) return -EINVAL; } - kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); - if (!kscandat) { - dev_err(&pdev->dev, "failed to allocate memory\n"); + kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat), + GFP_KERNEL); + if (!kscandat) return -ENOMEM; - } error = lpc32xx_parse_dt(&pdev->dev, kscandat); if (error) { dev_err(&pdev->dev, "failed to parse device tree\n"); - goto err_free_mem; + return error; } keymap_size = sizeof(kscandat->keymap[0]) * (kscandat->matrix_sz << kscandat->row_shift); - kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); - if (!kscandat->keymap) { - dev_err(&pdev->dev, "could not allocate memory for keymap\n"); - error = -ENOMEM; - goto err_free_mem; - } + kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL); + if (!kscandat->keymap) + return -ENOMEM; - kscandat->input = input = input_allocate_device(); + kscandat->input = input = devm_input_allocate_device(&pdev->dev); if (!input) { dev_err(&pdev->dev, "failed to allocate input device\n"); - error = -ENOMEM; - goto err_free_keymap; + return -ENOMEM; } /* Setup key input */ @@ -234,39 +228,26 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) kscandat->keymap, kscandat->input); if (error) { dev_err(&pdev->dev, "failed to build keymap\n"); - goto err_free_input; + return error; } input_set_drvdata(kscandat->input, kscandat); - kscandat->iores = request_mem_region(res->start, resource_size(res), - pdev->name); - if (!kscandat->iores) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto err_free_input; - } - - kscandat->kscan_base = ioremap(kscandat->iores->start, - resource_size(kscandat->iores)); - if (!kscandat->kscan_base) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - error = -EBUSY; - goto err_release_memregion; - } + kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(kscandat->kscan_base)) + return PTR_ERR(kscandat->kscan_base); /* Get the key scanner clock */ - kscandat->clk = clk_get(&pdev->dev, NULL); + kscandat->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(kscandat->clk)) { dev_err(&pdev->dev, "failed to get clock\n"); - error = PTR_ERR(kscandat->clk); - goto err_unmap; + return PTR_ERR(kscandat->clk); } /* Configure the key scanner */ error = clk_prepare_enable(kscandat->clk); if (error) - goto err_clk_put; + return error; writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); @@ -277,52 +258,20 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); clk_disable_unprepare(kscandat->clk); - error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); + error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0, + pdev->name, kscandat); if (error) { dev_err(&pdev->dev, "failed to request irq\n"); - goto err_clk_put; + return error; } error = input_register_device(kscandat->input); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err_free_irq; + return error; } platform_set_drvdata(pdev, kscandat); - return 0; - -err_free_irq: - free_irq(irq, kscandat); -err_clk_put: - clk_put(kscandat->clk); -err_unmap: - iounmap(kscandat->kscan_base); -err_release_memregion: - release_mem_region(kscandat->iores->start, - resource_size(kscandat->iores)); -err_free_input: - input_free_device(kscandat->input); -err_free_keymap: - kfree(kscandat->keymap); -err_free_mem: - kfree(kscandat); - - return error; -} - -static int lpc32xx_kscan_remove(struct platform_device *pdev) -{ - struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); - - free_irq(platform_get_irq(pdev, 0), kscandat); - clk_put(kscandat->clk); - iounmap(kscandat->kscan_base); - release_mem_region(kscandat->iores->start, - resource_size(kscandat->iores)); - input_unregister_device(kscandat->input); - kfree(kscandat->keymap); - kfree(kscandat); return 0; } @@ -378,7 +327,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); static struct platform_driver lpc32xx_kscan_driver = { .probe = lpc32xx_kscan_probe, - .remove = lpc32xx_kscan_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, -- GitLab From 8552befa3086589876032d5e1ce5797ae2bb684b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 2 Oct 2014 22:25:22 -0300 Subject: [PATCH 1037/9457] iio: adc: vf610: Propagate the real error when platform_get_irq() fails There is no need to pass a 'fake' return value when platform_get_irq() fails. Propagate the real error instead. While at it, only consider negative numbers returned by platform_get_irq() as error. Signed-off-by: Fabio Estevam Signed-off-by: Jonathan Cameron --- drivers/iio/adc/vf610_adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index d47fff003b78..8ec353c01d98 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -593,9 +593,9 @@ static int vf610_adc_probe(struct platform_device *pdev) return PTR_ERR(info->regs); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(&pdev->dev, "no irq resource?\n"); - return -EINVAL; + return irq; } ret = devm_request_irq(info->dev, irq, -- GitLab From c22e15f352066e8ee4d662f4a721c2fd10590f81 Mon Sep 17 00:00:00 2001 From: Vlad Dogaru Date: Mon, 13 Oct 2014 14:53:00 +0100 Subject: [PATCH 1038/9457] iio: add ABI documentation for scaled pressure Signed-off-by: Vlad Dogaru Reviewed-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 1ac9ac20f530..5a7fc666b07e 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -200,6 +200,13 @@ Description: Raw pressure measurement from channel Y. Units after application of scale and offset are kilopascal. +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_input +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_input +KernelVersion: 3.8 +Contact: linux-iio@vger.kernel.org +Description: + Scaled pressure measurement from channel Y, in kilopascal. + What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_raw KernelVersion: 3.14 Contact: linux-iio@vger.kernel.org -- GitLab From d5c94568cc1d11dffee349468ae996e420381453 Mon Sep 17 00:00:00 2001 From: Vlad Dogaru Date: Tue, 21 Oct 2014 11:09:58 +0300 Subject: [PATCH 1039/9457] iio: add bmp280 pressure and temperature driver Minimal implementation, can read temperature and data using direct mode. Datasheet available at Signed-off-by: Vlad Dogaru Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/Kconfig | 11 + drivers/iio/pressure/Makefile | 1 + drivers/iio/pressure/bmp280.c | 455 ++++++++++++++++++++++++++++++++++ 3 files changed, 467 insertions(+) create mode 100644 drivers/iio/pressure/bmp280.c diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 15afbc919521..a3be53792072 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -5,6 +5,17 @@ menu "Pressure sensors" +config BMP280 + tristate "Bosch Sensortec BMP280 pressure sensor driver" + depends on I2C + select REGMAP_I2C + help + Say yes here to build support for Bosch Sensortec BMP280 + pressure and temperature sensor. + + To compile this driver as a module, choose M here: the module + will be called bmp280. + config HID_SENSOR_PRESS depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index 90a37e85cf21..88011f2ae00e 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -3,6 +3,7 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_BMP280) += bmp280.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_MPL115) += mpl115.o obj-$(CONFIG_MPL3115) += mpl3115.o diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c new file mode 100644 index 000000000000..fb91cb35b331 --- /dev/null +++ b/drivers/iio/pressure/bmp280.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2014 Intel Corporation + * + * Driver for Bosch Sensortec BMP280 digital pressure sensor. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#define pr_fmt(fmt) "bmp280: " fmt + +#include +#include +#include +#include +#include +#include + +#define BMP280_REG_TEMP_XLSB 0xFC +#define BMP280_REG_TEMP_LSB 0xFB +#define BMP280_REG_TEMP_MSB 0xFA +#define BMP280_REG_PRESS_XLSB 0xF9 +#define BMP280_REG_PRESS_LSB 0xF8 +#define BMP280_REG_PRESS_MSB 0xF7 + +#define BMP280_REG_CONFIG 0xF5 +#define BMP280_REG_CTRL_MEAS 0xF4 +#define BMP280_REG_STATUS 0xF3 +#define BMP280_REG_RESET 0xE0 +#define BMP280_REG_ID 0xD0 + +#define BMP280_REG_COMP_TEMP_START 0x88 +#define BMP280_COMP_TEMP_REG_COUNT 6 + +#define BMP280_REG_COMP_PRESS_START 0x8E +#define BMP280_COMP_PRESS_REG_COUNT 18 + +#define BMP280_FILTER_MASK (BIT(4) | BIT(3) | BIT(2)) +#define BMP280_FILTER_OFF 0 +#define BMP280_FILTER_2X BIT(2) +#define BMP280_FILTER_4X BIT(3) +#define BMP280_FILTER_8X (BIT(3) | BIT(2)) +#define BMP280_FILTER_16X BIT(4) + +#define BMP280_OSRS_TEMP_MASK (BIT(7) | BIT(6) | BIT(5)) +#define BMP280_OSRS_TEMP_SKIP 0 +#define BMP280_OSRS_TEMP_1X BIT(5) +#define BMP280_OSRS_TEMP_2X BIT(6) +#define BMP280_OSRS_TEMP_4X (BIT(6) | BIT(5)) +#define BMP280_OSRS_TEMP_8X BIT(7) +#define BMP280_OSRS_TEMP_16X (BIT(7) | BIT(5)) + +#define BMP280_OSRS_PRESS_MASK (BIT(4) | BIT(3) | BIT(2)) +#define BMP280_OSRS_PRESS_SKIP 0 +#define BMP280_OSRS_PRESS_1X BIT(2) +#define BMP280_OSRS_PRESS_2X BIT(3) +#define BMP280_OSRS_PRESS_4X (BIT(3) | BIT(2)) +#define BMP280_OSRS_PRESS_8X BIT(4) +#define BMP280_OSRS_PRESS_16X (BIT(4) | BIT(2)) + +#define BMP280_MODE_MASK (BIT(1) | BIT(0)) +#define BMP280_MODE_SLEEP 0 +#define BMP280_MODE_FORCED BIT(0) +#define BMP280_MODE_NORMAL (BIT(1) | BIT(0)) + +#define BMP280_CHIP_ID 0x58 +#define BMP280_SOFT_RESET_VAL 0xB6 + +struct bmp280_data { + struct i2c_client *client; + struct mutex lock; + struct regmap *regmap; + + /* + * Carryover value from temperature conversion, used in pressure + * calculation. + */ + s32 t_fine; +}; + +/* Compensation parameters. */ +struct bmp280_comp_temp { + u16 dig_t1; + s16 dig_t2, dig_t3; +}; + +struct bmp280_comp_press { + u16 dig_p1; + s16 dig_p2, dig_p3, dig_p4, dig_p5, dig_p6, dig_p7, dig_p8, dig_p9; +}; + +static const struct iio_chan_spec bmp280_channels[] = { + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, +}; + +static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP280_REG_CONFIG: + case BMP280_REG_CTRL_MEAS: + case BMP280_REG_RESET: + return true; + default: + return false; + }; +} + +static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BMP280_REG_TEMP_XLSB: + case BMP280_REG_TEMP_LSB: + case BMP280_REG_TEMP_MSB: + case BMP280_REG_PRESS_XLSB: + case BMP280_REG_PRESS_LSB: + case BMP280_REG_PRESS_MSB: + case BMP280_REG_STATUS: + return true; + default: + return false; + } +} + +static const struct regmap_config bmp280_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = BMP280_REG_TEMP_XLSB, + .cache_type = REGCACHE_RBTREE, + + .writeable_reg = bmp280_is_writeable_reg, + .volatile_reg = bmp280_is_volatile_reg, +}; + +static int bmp280_read_compensation_temp(struct bmp280_data *data, + struct bmp280_comp_temp *comp) +{ + int ret; + __le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2]; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START, + buf, BMP280_COMP_TEMP_REG_COUNT); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to read temperature calibration parameters\n"); + return ret; + } + + comp->dig_t1 = (u16) le16_to_cpu(buf[0]); + comp->dig_t2 = (s16) le16_to_cpu(buf[1]); + comp->dig_t3 = (s16) le16_to_cpu(buf[2]); + + return 0; +} + +static int bmp280_read_compensation_press(struct bmp280_data *data, + struct bmp280_comp_press *comp) +{ + int ret; + __le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2]; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START, + buf, BMP280_COMP_PRESS_REG_COUNT); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to read pressure calibration parameters\n"); + return ret; + } + + comp->dig_p1 = (s16) le16_to_cpu(buf[0]); + comp->dig_p2 = (u16) le16_to_cpu(buf[1]); + comp->dig_p3 = (u16) le16_to_cpu(buf[2]); + comp->dig_p4 = (u16) le16_to_cpu(buf[3]); + comp->dig_p5 = (u16) le16_to_cpu(buf[4]); + comp->dig_p6 = (u16) le16_to_cpu(buf[5]); + comp->dig_p7 = (u16) le16_to_cpu(buf[6]); + comp->dig_p8 = (u16) le16_to_cpu(buf[7]); + comp->dig_p9 = (u16) le16_to_cpu(buf[8]); + + return 0; +} + +/* + * Returns temperature in DegC, resolution is 0.01 DegC. Output value of + * "5123" equals 51.23 DegC. t_fine carries fine temperature as global + * value. + * + * Taken from datasheet, Section 3.11.3, "Compensation formula". + */ +static s32 bmp280_compensate_temp(struct bmp280_data *data, + struct bmp280_comp_temp *comp, + s32 adc_temp) +{ + s32 var1, var2, t; + + var1 = (((adc_temp >> 3) - ((s32) comp->dig_t1 << 1)) * + ((s32) comp->dig_t2)) >> 11; + var2 = (((((adc_temp >> 4) - ((s32) comp->dig_t1)) * + ((adc_temp >> 4) - ((s32) comp->dig_t1))) >> 12) * + ((s32) comp->dig_t3)) >> 14; + + data->t_fine = var1 + var2; + t = (data->t_fine * 5 + 128) >> 8; + + return t; +} + +/* + * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 + * integer bits and 8 fractional bits). Output value of "24674867" + * represents 24674867/256 = 96386.2 Pa = 963.862 hPa + * + * Taken from datasheet, Section 3.11.3, "Compensation formula". + */ +static u32 bmp280_compensate_press(struct bmp280_data *data, + struct bmp280_comp_press *comp, + s32 adc_press) +{ + s64 var1, var2, p; + + var1 = ((s64) data->t_fine) - 128000; + var2 = var1 * var1 * (s64) comp->dig_p6; + var2 = var2 + ((var1 * (s64) comp->dig_p5) << 17); + var2 = var2 + (((s64) comp->dig_p4) << 35); + var1 = ((var1 * var1 * (s64) comp->dig_p3) >> 8) + + ((var1 * (s64) comp->dig_p2) << 12); + var1 = (((((s64) 1) << 47) + var1)) * ((s64) comp->dig_p1) >> 33; + + if (var1 == 0) + return 0; + + p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125; + do_div(p, var1); + var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25; + var2 = (((s64) comp->dig_p8) * p) >> 19; + p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4); + + return (u32) p; +} + +static int bmp280_read_temp(struct bmp280_data *data, + int *val) +{ + int ret; + __be32 tmp = 0; + s32 adc_temp, comp_temp; + struct bmp280_comp_temp comp; + + ret = bmp280_read_compensation_temp(data, &comp); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB, + (u8 *) &tmp, 3); + if (ret < 0) { + dev_err(&data->client->dev, "failed to read temperature\n"); + return ret; + } + + adc_temp = be32_to_cpu(tmp) >> 12; + comp_temp = bmp280_compensate_temp(data, &comp, adc_temp); + + /* + * val might be NULL if we're called by the read_press routine, + * who only cares about the carry over t_fine value. + */ + if (val) { + *val = comp_temp * 10; + return IIO_VAL_INT; + } + + return 0; +} + +static int bmp280_read_press(struct bmp280_data *data, + int *val, int *val2) +{ + int ret; + __be32 tmp = 0; + s32 adc_press; + u32 comp_press; + struct bmp280_comp_press comp; + + ret = bmp280_read_compensation_press(data, &comp); + if (ret < 0) + return ret; + + /* Read and compensate temperature so we get a reading of t_fine. */ + ret = bmp280_read_temp(data, NULL); + if (ret < 0) + return ret; + + ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB, + (u8 *) &tmp, 3); + if (ret < 0) { + dev_err(&data->client->dev, "failed to read pressure\n"); + return ret; + } + + adc_press = be32_to_cpu(tmp) >> 12; + comp_press = bmp280_compensate_press(data, &comp, adc_press); + + *val = comp_press / 256000; + *val2 = comp_press * 1000000 / 256000; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int bmp280_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + struct bmp280_data *data = iio_priv(indio_dev); + + mutex_lock(&data->lock); + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_PRESSURE: + ret = bmp280_read_press(data, val, val2); + break; + case IIO_TEMP: + ret = bmp280_read_temp(data, val); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static const struct iio_info bmp280_info = { + .driver_module = THIS_MODULE, + .read_raw = &bmp280_read_raw, +}; + +static int bmp280_chip_init(struct bmp280_data *data) +{ + int ret; + + ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS, + BMP280_OSRS_TEMP_MASK | + BMP280_OSRS_PRESS_MASK | + BMP280_MODE_MASK, + BMP280_OSRS_TEMP_2X | + BMP280_OSRS_PRESS_16X | + BMP280_MODE_NORMAL); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to write config register\n"); + return ret; + } + + ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG, + BMP280_FILTER_MASK, + BMP280_FILTER_4X); + if (ret < 0) { + dev_err(&data->client->dev, + "failed to write config register\n"); + return ret; + } + + return ret; +} + +static int bmp280_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct iio_dev *indio_dev; + struct bmp280_data *data; + unsigned int chip_id; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + i2c_set_clientdata(client, indio_dev); + data = iio_priv(indio_dev); + mutex_init(&data->lock); + data->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->channels = bmp280_channels; + indio_dev->num_channels = ARRAY_SIZE(bmp280_channels); + indio_dev->info = &bmp280_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + data->regmap = devm_regmap_init_i2c(client, &bmp280_regmap_config); + if (IS_ERR(data->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(data->regmap); + } + + ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id); + if (ret < 0) + return ret; + if (chip_id != BMP280_CHIP_ID) { + dev_err(&client->dev, "bad chip id. expected %x got %x\n", + BMP280_CHIP_ID, chip_id); + return -EINVAL; + } + + ret = bmp280_chip_init(data); + if (ret < 0) + return ret; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct acpi_device_id bmp280_acpi_match[] = { + {"BMP0280", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match); + +static const struct i2c_device_id bmp280_id[] = { + {"bmp280", 0}, + { }, +}; +MODULE_DEVICE_TABLE(i2c, bmp280_id); + +static struct i2c_driver bmp280_driver = { + .driver = { + .name = "bmp280", + .acpi_match_table = ACPI_PTR(bmp280_acpi_match), + }, + .probe = bmp280_probe, + .id_table = bmp280_id, +}; +module_i2c_driver(bmp280_driver); + +MODULE_AUTHOR("Vlad Dogaru "); +MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP280 pressure and temperature sensor"); +MODULE_LICENSE("GPL v2"); -- GitLab From ace0eb1e91a75b84b1be3d610b79509a5bd94df1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:13:46 -0700 Subject: [PATCH 1040/9457] ASoC: rsnd: tidyup debug information when read/write b8c637864a6904a9ba8e0df556d5bdf9f26b2c54 (ASoC: rsnd: use regmap_mmio instead of original regmap bus) added regmap_mmio support on Renesas R-Car sound driver. Then, debug information of register read/write indicates regmap index, not register address. This is a little bit confusable information. This patch tidyup debug message, and added regmap debug hint on comment area. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/gen.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index f95e7ab135e8..61dee68ffc0d 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -8,6 +8,17 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +/* + * #define DEBUG + * + * you can also add below in + * ${LINUX}/drivers/base/regmap/regmap.c + * for regmap debug + * + * #define LOG_DEVICE "xxxx.rcar_sound" + */ + #include "rsnd.h" struct rsnd_gen { @@ -67,9 +78,10 @@ u32 rsnd_read(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return 0; - regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); + dev_dbg(dev, "r %s(%d) - %4d : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); - dev_dbg(dev, "r %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, val); + regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); return val; } @@ -84,9 +96,10 @@ void rsnd_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); + dev_dbg(dev, "w %s(%d) - %4d : %08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); - dev_dbg(dev, "w %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, data); + regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); } void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, @@ -98,11 +111,11 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; + dev_dbg(dev, "b %s(%d) - %4d : %08x/%08x\n", + rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); + regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), mask, data); - - dev_dbg(dev, "b %s - 0x%04d : %08x/%08x\n", - rsnd_mod_name(mod), reg, data, mask); } #define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ -- GitLab From 9960ce97432bdb1defc76ed80ac19e37e8778bc6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:13:56 -0700 Subject: [PATCH 1041/9457] ASoC: rsnd: tidyup RSND_DVC_VOLUME_NUM to RSND_DVC_CHANNELS RSND_DVC_VOLUME_NUM means DVC channel number. This patch tidyups this un-understandable naming Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 3f443930c2b1..b5f95ad4c123 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -12,7 +12,7 @@ #define RSND_DVC_NAME_SIZE 16 #define RSND_DVC_VOLUME_MAX 100 -#define RSND_DVC_VOLUME_NUM 2 +#define RSND_DVC_CHANNELS 2 #define DVC_NAME "dvc" @@ -20,8 +20,8 @@ struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - u8 volume[RSND_DVC_VOLUME_NUM]; - u8 mute[RSND_DVC_VOLUME_NUM]; + u8 volume[RSND_DVC_CHANNELS]; + u8 mute[RSND_DVC_CHANNELS]; }; #define rsnd_mod_to_dvc(_mod) \ @@ -37,11 +37,11 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); u32 max = (0x00800000 - 1); - u32 vol[RSND_DVC_VOLUME_NUM]; + u32 vol[RSND_DVC_CHANNELS]; u32 mute = 0; int i; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { + for (i = 0; i < RSND_DVC_CHANNELS; i++) { vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; mute |= (!!dvc->mute[i]) << i; } @@ -150,7 +150,7 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); u8 *val = (u8 *)kctrl->private_value; - uinfo->count = RSND_DVC_VOLUME_NUM; + uinfo->count = RSND_DVC_CHANNELS; uinfo->value.integer.min = 0; if (val == dvc->volume) { @@ -170,7 +170,7 @@ static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, u8 *val = (u8 *)kctrl->private_value; int i; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) + for (i = 0; i < RSND_DVC_CHANNELS; i++) ucontrol->value.integer.value[i] = val[i]; return 0; @@ -183,7 +183,7 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, u8 *val = (u8 *)kctrl->private_value; int i, change = 0; - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { + for (i = 0; i < RSND_DVC_CHANNELS; i++) { change |= (ucontrol->value.integer.value[i] != val[i]); val[i] = ucontrol->value.integer.value[i]; } -- GitLab From 92b9a6991b2e3a4ccf5ffc956730d36835d53a79 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 21 Oct 2014 18:14:14 -0700 Subject: [PATCH 1042/9457] ASoC: rsnd: add struct rsnd_dvc_cfg and control DVC settings DVC can control Digital Volume / Mute / Volume Ramp etc, and these uses different max value. Current driver is using fixed max value for each settings. This patch adds new struct rsnd_dvc_cfg, and control these. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 51 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index b5f95ad4c123..deaf0faaed81 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -11,17 +11,21 @@ #include "rsnd.h" #define RSND_DVC_NAME_SIZE 16 -#define RSND_DVC_VOLUME_MAX 100 #define RSND_DVC_CHANNELS 2 #define DVC_NAME "dvc" +struct rsnd_dvc_cfg { + unsigned int max; + u32 val[RSND_DVC_CHANNELS]; +}; + struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - u8 volume[RSND_DVC_CHANNELS]; - u8 mute[RSND_DVC_CHANNELS]; + struct rsnd_dvc_cfg volume; + struct rsnd_dvc_cfg mute; }; #define rsnd_mod_to_dvc(_mod) \ @@ -36,18 +40,15 @@ struct rsnd_dvc { static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); - u32 max = (0x00800000 - 1); - u32 vol[RSND_DVC_CHANNELS]; u32 mute = 0; int i; for (i = 0; i < RSND_DVC_CHANNELS; i++) { - vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; - mute |= (!!dvc->mute[i]) << i; + mute |= (!!dvc->mute.val[i]) << i; } - rsnd_mod_write(mod, DVC_VOL0R, vol[0]); - rsnd_mod_write(mod, DVC_VOL1R, vol[1]); + rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); + rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); rsnd_mod_write(mod, DVC_ZCMCR, mute); } @@ -146,20 +147,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; uinfo->count = RSND_DVC_CHANNELS; uinfo->value.integer.min = 0; + uinfo->value.integer.max = cfg->max; - if (val == dvc->volume) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; - } else { + if (cfg->max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->value.integer.max = 1; - } + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; return 0; } @@ -167,11 +164,11 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i; for (i = 0; i < RSND_DVC_CHANNELS; i++) - ucontrol->value.integer.value[i] = val[i]; + ucontrol->value.integer.value[i] = cfg->val[i]; return 0; } @@ -180,12 +177,12 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - u8 *val = (u8 *)kctrl->private_value; + struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i, change = 0; for (i = 0; i < RSND_DVC_CHANNELS; i++) { - change |= (ucontrol->value.integer.value[i] != val[i]); - val[i] = ucontrol->value.integer.value[i]; + change |= (ucontrol->value.integer.value[i] != cfg->val[i]); + cfg->val[i] = ucontrol->value.integer.value[i]; } if (change) @@ -198,7 +195,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd, const unsigned char *name, - u8 *private) + struct rsnd_dvc_cfg *private) { struct snd_card *card = rtd->card->snd_card; struct snd_kcontrol *kctrl; @@ -232,18 +229,20 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int ret; /* Volume */ + dvc->volume.max = 0x00800000 - 1; ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Playback Volume" : "DVC In Capture Volume", - dvc->volume); + &dvc->volume); if (ret < 0) return ret; /* Mute */ + dvc->mute.max = 1; ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Mute Switch" : "DVC In Mute Switch", - dvc->mute); + &dvc->mute); if (ret < 0) return ret; -- GitLab From 0a9858689017544743708b332c6b7a54df10b6fe Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Wed, 22 Oct 2014 15:30:40 +0200 Subject: [PATCH 1043/9457] staging: vt6655: wcmd.c: fix print priority warning This patch fixes the following warning generated by checkpatch.pl for the file wcmd.c WARNING: printk() should include KERN_ facility level printk was replaced by netdev_err since providing printk with the facility level KERN_ERR generated the printing priority warning. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wcmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 985e1b99362d..7302196eda03 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -665,7 +665,8 @@ vCommandTimer( add_timer(&pDevice->sTimerTxData); } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { - printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); + netdev_err(pDevice->dev, + "WLAN_ASSOCIATE_WAIT:Association Fail???\n"); } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! pDevice->byLinkWaitCount++; pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); -- GitLab From 36beff6e20740e055c11ec87d9f41ea54a842db5 Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Wed, 22 Oct 2014 17:24:03 +0530 Subject: [PATCH 1044/9457] Staging: dgnc: Remove unused sniff code The output written by dgnc_sniff_nowait_nolock() is never used anywhere since commit 35cf90459312f ("staging: dgnc: removes proc code") deleted the code that used to copy it to user space. dgnc_sniff_nowait_nolock() uses 'timeval' to create header timestamps for the data dump. 32-bit systems using 'struct timeval' will break in the year 2038, This patch removes dgnc_sniff_nowait_nolock() and all ch_sniff_* members of struct channel_t defined in "dgnc_driver.h". It also removes their usage from the driver files and hence y2038 issue is also resolved. Signed-off-by: Somya Anand Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 4 - drivers/staging/dgnc/dgnc_driver.h | 14 ---- drivers/staging/dgnc/dgnc_neo.c | 3 - drivers/staging/dgnc/dgnc_tty.c | 127 ----------------------------- drivers/staging/dgnc/dgnc_tty.h | 2 - 5 files changed, 150 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index c1c4bb9b0354..360fe258946d 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -918,8 +918,6 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE | UART_LSR_FE); ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART READ", - ch->ch_rqueue + head, 1); qleft--; @@ -1086,8 +1084,6 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_tun.un_flags |= (UN_EMPTY); } writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART WRITE", - ch->ch_wqueue + ch->ch_w_tail, 1); ch->ch_w_tail++; ch->ch_w_tail &= WQUEUEMASK; ch->ch_txcount++; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index d5de3e2f2945..695c3c6d3233 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -123,8 +123,6 @@ #define _POSIX_VDISABLE '\0' #endif -#define SNIFF_MAX 65536 /* Sniff buffer size (2^n) */ -#define SNIFF_MASK (SNIFF_MAX - 1) /* Sniff wrap mask */ /* * All the possible states the driver can be while being loaded. @@ -331,13 +329,6 @@ struct un_t { #define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */ #define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */ -/* - * Definitions for ch_sniff_flags - */ -#define SNIFF_OPEN 0x1 -#define SNIFF_WAIT_DATA 0x2 -#define SNIFF_WAIT_SPACE 0x4 - /* Our Read/Error/Write queue sizes */ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ @@ -431,11 +422,6 @@ struct channel_t { struct proc_dir_entry *proc_entry_pointer; struct dgnc_proc_entry *dgnc_channel_table; - uint ch_sniff_in; - uint ch_sniff_out; - char *ch_sniff_buf; /* Sniff buffer for proc */ - ulong ch_sniff_flags; /* Channel flags */ - wait_queue_head_t ch_sniff_wait; }; /* diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 27a525ead878..cc6136418071 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1217,7 +1217,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) /* Copy data from uart to the queue */ memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n); - dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, n); /* * Since RX_FIFO_DATA_ERROR was 0, we are guarenteed @@ -1303,7 +1302,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); ch->ch_equeue[head] = (unsigned char) linestatus; - dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, 1); /* Ditch any remaining linestatus value. */ linestatus = 0; @@ -1556,7 +1554,6 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) } memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); - dgnc_sniff_nowait_nolock(ch, "UART WRITE", ch->ch_wqueue + tail, s); /* Add and flip queue if needed */ tail = (tail + s) & WQUEUEMASK; diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index b0fcbe7bdfe4..8384e3d770f1 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -49,7 +49,6 @@ #include /* For udelay */ #include /* For copy_from_user/copy_to_user */ #include - #include "dgnc_driver.h" #include "dgnc_tty.h" #include "dgnc_types.h" @@ -374,7 +373,6 @@ int dgnc_tty_init(struct dgnc_board *brd) init_waitqueue_head(&ch->ch_flags_wait); init_waitqueue_head(&ch->ch_tun.un_flags_wait); init_waitqueue_head(&ch->ch_pun.un_flags_wait); - init_waitqueue_head(&ch->ch_sniff_wait); { struct device *classp; @@ -449,127 +447,6 @@ void dgnc_tty_uninit(struct dgnc_board *brd) #define TMPBUFLEN (1024) -/* - * dgnc_sniff - Dump data out to the "sniff" buffer if the - * proc sniff file is opened... - */ -void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int len) -{ - struct timeval tv; - int n; - int r; - int nbuf; - int i; - int tmpbuflen; - char *tmpbuf; - char *p; - int too_much_data; - - tmpbuf = kzalloc(TMPBUFLEN, GFP_ATOMIC); - if (!tmpbuf) - return; - p = tmpbuf; - - /* Leave if sniff not open */ - if (!(ch->ch_sniff_flags & SNIFF_OPEN)) - goto exit; - - do_gettimeofday(&tv); - - /* Create our header for data dump */ - p += sprintf(p, "<%ld %ld><%s><", tv.tv_sec, tv.tv_usec, text); - tmpbuflen = p - tmpbuf; - - do { - too_much_data = 0; - - for (i = 0; i < len && tmpbuflen < (TMPBUFLEN - 4); i++) { - p += sprintf(p, "%02x ", *buf); - buf++; - tmpbuflen = p - tmpbuf; - } - - if (tmpbuflen < (TMPBUFLEN - 4)) { - if (i > 0) - p += sprintf(p - 1, "%s\n", ">"); - else - p += sprintf(p, "%s\n", ">"); - } else { - too_much_data = 1; - len -= i; - } - - nbuf = strlen(tmpbuf); - p = tmpbuf; - - /* - * Loop while data remains. - */ - while (nbuf > 0 && ch->ch_sniff_buf) { - /* - * Determine the amount of available space left in the - * buffer. If there's none, wait until some appears. - */ - n = (ch->ch_sniff_out - ch->ch_sniff_in - 1) & SNIFF_MASK; - - /* - * If there is no space left to write to in our sniff buffer, - * we have no choice but to drop the data. - * We *cannot* sleep here waiting for space, because this - * function was probably called by the interrupt/timer routines! - */ - if (n == 0) - goto exit; - - /* - * Copy as much data as will fit. - */ - - if (n > nbuf) - n = nbuf; - - r = SNIFF_MAX - ch->ch_sniff_in; - - if (r <= n) { - memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, r); - - n -= r; - ch->ch_sniff_in = 0; - p += r; - nbuf -= r; - } - - memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, n); - - ch->ch_sniff_in += n; - p += n; - nbuf -= n; - - /* - * Wakeup any thread waiting for data - */ - if (ch->ch_sniff_flags & SNIFF_WAIT_DATA) { - ch->ch_sniff_flags &= ~SNIFF_WAIT_DATA; - wake_up_interruptible(&ch->ch_sniff_wait); - } - } - - /* - * If the user sent us too much data to push into our tmpbuf, - * we need to keep looping around on all the data. - */ - if (too_much_data) { - p = tmpbuf; - tmpbuflen = 0; - } - - } while (too_much_data); - -exit: - kfree(tmpbuf); -} - - /*======================================================================= * * dgnc_wmove - Write data to transmit queue. @@ -784,8 +661,6 @@ void dgnc_input(struct channel_t *ch) tty_insert_flip_string(tp->port, ch->ch_rqueue + tail, s); } - dgnc_sniff_nowait_nolock(ch, "USER READ", ch->ch_rqueue + tail, s); - tail += s; n -= s; /* Flip queue if needed */ @@ -1981,7 +1856,6 @@ static int dgnc_tty_write(struct tty_struct *tty, if (n >= remain) { n -= remain; memcpy(ch->ch_wqueue + head, buf, remain); - dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain); head = 0; buf += remain; } @@ -1992,7 +1866,6 @@ static int dgnc_tty_write(struct tty_struct *tty, */ remain = n; memcpy(ch->ch_wqueue + head, buf, remain); - dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain); head += remain; } diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 58eef257c2ec..3975f0407143 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -37,6 +37,4 @@ void dgnc_carrier(struct channel_t *ch); void dgnc_wakeup_writes(struct channel_t *ch); void dgnc_check_queue_flow_control(struct channel_t *ch); -void dgnc_sniff_nowait_nolock(struct channel_t *ch, unsigned char *text, unsigned char *buf, int nbuf); - #endif -- GitLab From 0a6e2170dfcd2b17ae32ad91993edf2b77014137 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Wed, 22 Oct 2014 16:50:17 +0300 Subject: [PATCH 1045/9457] staging: iio: iio_event_monitor: Add support for missing IIO modifiers This patch adds the missing IIO modifiers in event_is_known function and iio_modifier_names vector. Additionally, it removes duplicate name entries of IIO_MOD_LIGHT_BOTH and IIO_MOD_LIGHT_IR in iio_modifier_names. Signed-off-by: Roberta Dobrescu Reviewed-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- .../iio/Documentation/iio_event_monitor.c | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 569d6f8face5..940ed2399e73 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -69,16 +69,29 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_X] = "x", [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", + [IIO_MOD_X_AND_Y] = "x&y", + [IIO_MOD_X_AND_Z] = "x&z", + [IIO_MOD_Y_AND_Z] = "y&z", + [IIO_MOD_X_AND_Y_AND_Z] = "x&y&z", + [IIO_MOD_X_OR_Y] = "x|y", + [IIO_MOD_X_OR_Z] = "x|z", + [IIO_MOD_Y_OR_Z] = "y|z", + [IIO_MOD_X_OR_Y_OR_Z] = "x|y|z", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", - [IIO_MOD_LIGHT_BOTH] = "both", - [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_LIGHT_CLEAR] = "clear", [IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_BLUE] = "blue", + [IIO_MOD_QUATERNION] = "quaternion", + [IIO_MOD_TEMP_AMBIENT] = "ambient", + [IIO_MOD_TEMP_OBJECT] = "object", + [IIO_MOD_NORTH_MAGN] = "from_north_magnetic", + [IIO_MOD_NORTH_TRUE] = "from_north_true", + [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp", + [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp", }; static bool event_is_known(struct iio_event_data *event) @@ -118,6 +131,14 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_X: case IIO_MOD_Y: case IIO_MOD_Z: + case IIO_MOD_X_AND_Y: + case IIO_MOD_X_AND_Z: + case IIO_MOD_Y_AND_Z: + case IIO_MOD_X_AND_Y_AND_Z: + case IIO_MOD_X_OR_Y: + case IIO_MOD_X_OR_Z: + case IIO_MOD_Y_OR_Z: + case IIO_MOD_X_OR_Y_OR_Z: case IIO_MOD_LIGHT_BOTH: case IIO_MOD_LIGHT_IR: case IIO_MOD_ROOT_SUM_SQUARED_X_Y: @@ -126,6 +147,13 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_LIGHT_RED: case IIO_MOD_LIGHT_GREEN: case IIO_MOD_LIGHT_BLUE: + case IIO_MOD_QUATERNION: + case IIO_MOD_TEMP_AMBIENT: + case IIO_MOD_TEMP_OBJECT: + case IIO_MOD_NORTH_MAGN: + case IIO_MOD_NORTH_TRUE: + case IIO_MOD_NORTH_MAGN_TILT_COMP: + case IIO_MOD_NORTH_TRUE_TILT_COMP: break; default: return false; -- GitLab From 0951252522bfdb71f35bc4ea99c0739bb883c4ca Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 20 Oct 2014 10:40:22 +0530 Subject: [PATCH 1046/9457] Staging: lustre: lnet: Make functions static This patch makes functions proc_lnet_routes, proc_lnet_routers, proc_lnet_peers and proc_lnet_nis static in file router_proc.c as they are used only in this file. This problem is detected by sparse. Signed-off-by: Vaishali Thakkar Reviewed-by: Josh Triplett Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/router_proc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 6e8f7e2bbcfc..d9645f6bce49 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -164,8 +164,8 @@ static int proc_lnet_stats(struct ctl_table *table, int write, __proc_lnet_stats); } -int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_routes(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { const int tmpsiz = 256; char *tmpstr; @@ -290,8 +290,8 @@ int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer, return rc; } -int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_routers(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { int rc = 0; char *tmpstr; @@ -425,8 +425,8 @@ int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer, return rc; } -int proc_lnet_peers(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_peers(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { const int tmpsiz = 256; struct lnet_peer_table *ptable; @@ -657,8 +657,8 @@ static int proc_lnet_buffers(struct ctl_table *table, int write, __proc_lnet_buffers); } -int proc_lnet_nis(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +static int proc_lnet_nis(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { int tmpsiz = 128 * LNET_CPT_NUMBER; int rc = 0; -- GitLab From 38d676da615ac1a0b37572ac31ac8c7573f7dcfd Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 20 Oct 2014 13:58:35 +0530 Subject: [PATCH 1047/9457] Staging: lustre: Remove typedef ldlm_ns_hash_def_t The linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedef for ldlm_ns_hash_def_t. Also, the name of the struct is changed to drop the _t, to make the name look less typedef-like. This is done using Coccinelle. Semantic patch used to detect this case is as follows: @tn1@ type td; @@ typedef struct { ... } td; @script:python tf@ td << tn1.td; tdres; @@ coccinelle.tdres = td; @@ type tn1.td; identifier tf.tdres; @@ -typedef struct + tdres { ... } -td ; @@ type tn1.td; identifier tf.tdres; @@ -td + struct tdres Signed-off-by: Vaishali Thakkar Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index a785b7a7d1b3..8b20a838b7f2 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -501,7 +501,7 @@ cfs_hash_ops_t ldlm_ns_fid_hash_ops = { .hs_put = ldlm_res_hop_put }; -typedef struct { +struct ldlm_ns_hash_def { ldlm_ns_type_t nsd_type; /** hash bucket bits */ unsigned nsd_bkt_bits; @@ -509,9 +509,9 @@ typedef struct { unsigned nsd_all_bits; /** hash operations */ cfs_hash_ops_t *nsd_hops; -} ldlm_ns_hash_def_t; +}; -ldlm_ns_hash_def_t ldlm_ns_hash_defs[] = { +struct ldlm_ns_hash_def ldlm_ns_hash_defs[] = { { .nsd_type = LDLM_NS_TYPE_MDC, .nsd_bkt_bits = 11, @@ -563,7 +563,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, { struct ldlm_namespace *ns = NULL; struct ldlm_ns_bucket *nsb; - ldlm_ns_hash_def_t *nsd; + struct ldlm_ns_hash_def *nsd; struct cfs_hash_bd bd; int idx; int rc; -- GitLab From abb368abf76059e07967808ef5da9f32d2b760ae Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Mon, 20 Oct 2014 19:52:03 +0800 Subject: [PATCH 1048/9457] staging: lustre: lustre: obdecho: expand the GOTO macro in echo_client.c The GOTO macro is not standard in Linux. The following Coccinelle semantic patch was used to expand the GOTO macro. @@ identifier lbl; identifier rc; constant c; @@ - GOTO(lbl,\(rc\|c\)); + goto lbl; @@ identifier lbl; expression rc; @@ - GOTO(lbl,rc); + rc; + goto lbl; Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/obdecho/echo_client.c | 137 +++++++++++------- 1 file changed, 84 insertions(+), 53 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 98e4290919d0..a6ad87557512 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -698,14 +698,16 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, int cleanup = 0; OBD_ALLOC_PTR(ed); - if (ed == NULL) - GOTO(out, rc = -ENOMEM); + if (ed == NULL) { + rc = -ENOMEM; + goto out; + } cleanup = 1; cd = &ed->ed_cl; rc = cl_device_init(cd, t); if (rc) - GOTO(out, rc); + goto out; cd->cd_lu_dev.ld_ops = &echo_device_lu_ops; cd->cd_ops = &echo_device_cl_ops; @@ -719,24 +721,26 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, if (tgt == NULL) { CERROR("Can not find tgt device %s\n", lustre_cfg_string(cfg, 1)); - GOTO(out, rc = -ENODEV); + rc = -ENODEV; + goto out; } next = tgt->obd_lu_dev; if (!strcmp(tgt->obd_type->typ_name, LUSTRE_MDT_NAME)) { CERROR("echo MDT client must be run on server\n"); - GOTO(out, rc = -EOPNOTSUPP); + rc = -EOPNOTSUPP; + goto out; } rc = echo_site_init(env, ed); if (rc) - GOTO(out, rc); + goto out; cleanup = 3; rc = echo_client_setup(env, obd, cfg); if (rc) - GOTO(out, rc); + goto out; ed->ed_ec = &obd->u.echo_client; cleanup = 4; @@ -749,15 +753,17 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env, tgt_type_name = tgt->obd_type->typ_name; if (next != NULL) { LASSERT(next != NULL); - if (next->ld_site != NULL) - GOTO(out, rc = -EBUSY); + if (next->ld_site != NULL) { + rc = -EBUSY; + goto out; + } next->ld_site = &ed->ed_site->cs_lu; rc = next->ld_type->ldt_ops->ldto_device_init(env, next, next->ld_type->ldt_name, NULL); if (rc) - GOTO(out, rc); + goto out; /* Tricky case, I have to determine the obd type since * CLIO uses the different parameters to initialize @@ -968,15 +974,19 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d, fid = &info->eti_fid; rc = ostid_to_fid(fid, &lsm->lsm_oi, 0); - if (rc != 0) - GOTO(out, eco = ERR_PTR(rc)); + if (rc != 0) { + eco = ERR_PTR(rc); + goto out; + } /* In the function below, .hs_keycmp resolves to * lu_obj_hop_keycmp() */ /* coverity[overrun-buffer-val] */ obj = cl_object_find(env, echo_dev2cl(d), fid, &conf->eoc_cl); - if (IS_ERR(obj)) - GOTO(out, eco = (void *)obj); + if (IS_ERR(obj)) { + eco = (void *)obj; + goto out; + } eco = cl2echo_obj(obj); if (eco->eo_deleted) { @@ -1076,7 +1086,7 @@ static int cl_echo_enqueue(struct echo_object *eco, u64 start, u64 end, io->ci_ignore_layout = 1; result = cl_io_init(env, io, CIT_MISC, echo_obj2cl(eco)); if (result < 0) - GOTO(out, result); + goto out; LASSERT(result == 0); result = cl_echo_enqueue0(env, eco, start, end, mode, cookie, 0); @@ -1182,7 +1192,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, io->ci_ignore_layout = 1; rc = cl_io_init(env, io, CIT_MISC, obj); if (rc < 0) - GOTO(out, rc); + goto out; LASSERT(rc == 0); @@ -1191,7 +1201,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, rw == READ ? LCK_PR : LCK_PW, &lh.cookie, CEF_NEVER); if (rc < 0) - GOTO(error_lock, rc); + goto error_lock; for (i = 0; i < npages; i++) { LASSERT(pages[i]); @@ -1318,7 +1328,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = echo_alloc_memmd(ed, &lsm); if (rc < 0) { CERROR("Cannot allocate md: rc = %d\n", rc); - GOTO(failed, rc); + goto failed; } if (ulsm != NULL) { @@ -1326,7 +1336,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = echo_copyin_lsm (ed, lsm, ulsm, ulsm_nob); if (rc != 0) - GOTO(failed, rc); + goto failed; if (lsm->lsm_stripe_count == 0) lsm->lsm_stripe_count = ec->ec_nstripes; @@ -1363,7 +1373,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, rc = obd_create(env, ec->ec_exp, oa, &lsm, oti); if (rc != 0) { CERROR("Cannot create objects: rc = %d\n", rc); - GOTO(failed, rc); + goto failed; } created = 1; } @@ -1373,8 +1383,10 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed, oa->o_valid |= OBD_MD_FLID; eco = cl_echo_object_find(ed, &lsm); - if (IS_ERR(eco)) - GOTO(failed, rc = PTR_ERR(eco)); + if (IS_ERR(eco)) { + rc = PTR_ERR(eco); + goto failed; + } cl_echo_object_put(eco); CDEBUG(D_INFO, "oa oid "DOSTID"\n", POSTID(&oa->o_oi)); @@ -1642,8 +1654,10 @@ static int echo_client_prep_commit(const struct lu_env *env, OBD_ALLOC(lnb, npages * sizeof(struct niobuf_local)); OBD_ALLOC(rnb, npages * sizeof(struct niobuf_remote)); - if (lnb == NULL || rnb == NULL) - GOTO(out, ret = -ENOMEM); + if (lnb == NULL || rnb == NULL) { + ret = -ENOMEM; + goto out; + } if (rw == OBD_BRW_WRITE && async) brw_flags |= OBD_BRW_ASYNC; @@ -1671,7 +1685,7 @@ static int echo_client_prep_commit(const struct lu_env *env, ret = obd_preprw(env, rw, exp, oa, 1, &ioo, rnb, &lpages, lnb, oti, NULL); if (ret != 0) - GOTO(out, ret); + goto out; LASSERT(lpages == npages); for (i = 0; i < lpages; i++) { @@ -1704,7 +1718,7 @@ static int echo_client_prep_commit(const struct lu_env *env, ret = obd_commitrw(env, rw, exp, oa, 1, &ioo, rnb, npages, lnb, oti, ret); if (ret != 0) - GOTO(out, ret); + goto out; /* Reset oti otherwise it would confuse ldiskfs. */ memset(oti, 0, sizeof(*oti)); @@ -1862,21 +1876,27 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, return -ENOMEM; rc = lu_env_init(env, LCT_DT_THREAD); - if (rc) - GOTO(out, rc = -ENOMEM); + if (rc) { + rc = -ENOMEM; + goto out; + } switch (cmd) { case OBD_IOC_CREATE: /* may create echo object */ - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_create_object(env, ed, 1, oa, data->ioc_pbuf1, data->ioc_plen1, &dummy_oti); - GOTO(out, rc); + goto out; case OBD_IOC_DESTROY: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_get_object(&eco, ed, oa); if (rc == 0) { @@ -1886,7 +1906,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, eco->eo_deleted = 1; echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_GETATTR: rc = echo_get_object(&eco, ed, oa); @@ -1897,11 +1917,13 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, rc = obd_getattr(env, ec->ec_exp, &oinfo); echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_SETATTR: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_get_object(&eco, ed, oa); if (rc == 0) { @@ -1912,17 +1934,19 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, rc = obd_setattr(env, ec->ec_exp, &oinfo, NULL); echo_put_object(eco); } - GOTO(out, rc); + goto out; case OBD_IOC_BRW_WRITE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rw = OBD_BRW_WRITE; /* fall through */ case OBD_IOC_BRW_READ: rc = echo_client_brw_ioctl(env, rw, exp, data, &dummy_oti); - GOTO(out, rc); + goto out; case ECHO_IOC_GET_STRIPE: rc = echo_get_object(&eco, ed, oa); @@ -1931,11 +1955,13 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data->ioc_plen1); echo_put_object(eco); } - GOTO(out, rc); + goto out; case ECHO_IOC_SET_STRIPE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } if (data->ioc_pbuf1 == NULL) { /* unset */ rc = echo_get_object(&eco, ed, oa); @@ -1948,25 +1974,28 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data->ioc_pbuf1, data->ioc_plen1, &dummy_oti); } - GOTO (out, rc); + goto out; case ECHO_IOC_ENQUEUE: - if (!capable(CFS_CAP_SYS_ADMIN)) - GOTO (out, rc = -EPERM); + if (!capable(CFS_CAP_SYS_ADMIN)) { + rc = -EPERM; + goto out; + } rc = echo_client_enqueue(exp, oa, data->ioc_conn1, /* lock mode */ data->ioc_offset, data->ioc_count);/*extent*/ - GOTO (out, rc); + goto out; case ECHO_IOC_CANCEL: rc = echo_client_cancel(exp, oa); - GOTO (out, rc); + goto out; default: CERROR ("echo_ioctl(): unrecognised ioctl %#x\n", cmd); - GOTO (out, rc = -ENOTTY); + rc = -ENOTTY; + goto out; } out: @@ -2084,11 +2113,13 @@ static int echo_client_disconnect(struct obd_export *exp) { int rc; - if (exp == NULL) - GOTO(out, rc = -EINVAL); + if (exp == NULL) { + rc = -EINVAL; + goto out; + } rc = class_disconnect(exp); - GOTO(out, rc); + goto out; out: return rc; } -- GitLab From 57303e76c2251abf7d67f1afde30f861a93a49ff Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Tue, 21 Oct 2014 22:13:21 -0700 Subject: [PATCH 1049/9457] staging: lustre: Fix checkpatch.pl spacing-related errors This patch fixes misc. spacing errors reported by checkpatch.pl for lustre/llite/file.c Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index f1f75c7edee0..a5acc98a1c99 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -247,7 +247,7 @@ int ll_md_real_close(struct inode *inode, fmode_t fmode) return 0; } - och=*och_p; + och = *och_p; *och_p = NULL; mutex_unlock(&lli->lli_och_mutex); @@ -297,7 +297,8 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode, __u64 flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK; struct lustre_handle lockh; struct inode *inode = file->f_dentry->d_inode; - ldlm_policy_data_t policy = {.l_inodebits={MDS_INODELOCK_OPEN}}; + ldlm_policy_data_t policy = { + .l_inodebits = {MDS_INODELOCK_OPEN} }; mutex_lock(&lli->lli_och_mutex); if (fd->fd_omode & FMODE_WRITE) { @@ -2866,7 +2867,7 @@ ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, struct lustre_handle *lockh, __u64 flags, ldlm_mode_t mode) { - ldlm_policy_data_t policy = { .l_inodebits = {bits}}; + ldlm_policy_data_t policy = { .l_inodebits = {bits} }; struct lu_fid *fid; ldlm_mode_t rc; -- GitLab From 0fa3b9d3542a76f192e4789352e5f8fafe8bc655 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 22 Oct 2014 11:29:26 -0700 Subject: [PATCH 1050/9457] staging: lustre: llite: Use kcalloc not kzalloc with mult This patch fixes the following checkpatch.pl warnings: WARNING: Prefer kcalloc over kzalloc with multiply 166: FILE: drivers/staging/lustre/lustre/llite/dir.c:166: page_pool = kzalloc(sizeof(page) * max_pages, GFP_NOFS); 796: FILE: drivers/staging/lustre/lustre/llite/lloop.c:796: loop_dev = kzalloc(max_loop * sizeof(*loop_dev), GFP_KERNEL); 800: FILE: drivers/staging/lustre/lustre/llite/lloop.c:800: disks = kzalloc(max_loop * sizeof(*disks), GFP_KERNEL); Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/llite/lloop.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 9e8bfdcfe5a4..a07e0fe06207 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -163,7 +163,7 @@ static int ll_dir_filler(void *_hash, struct page *page0) LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES); - page_pool = kzalloc(sizeof(page) * max_pages, GFP_NOFS); + page_pool = kcalloc(max_pages, sizeof(page), GFP_NOFS); if (page_pool) { page_pool[0] = page0; } else { diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index 264e5ec3fed6..e0f39fec2787 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -793,11 +793,11 @@ static int __init lloop_init(void) if (ll_iocontrol_magic == NULL) goto out_mem1; - loop_dev = kzalloc(max_loop * sizeof(*loop_dev), GFP_KERNEL); + loop_dev = kcalloc(max_loop, sizeof(*loop_dev), GFP_KERNEL); if (!loop_dev) goto out_mem1; - disks = kzalloc(max_loop * sizeof(*disks), GFP_KERNEL); + disks = kcalloc(max_loop, sizeof(*disks), GFP_KERNEL); if (!disks) goto out_mem2; -- GitLab From 588bf52aa3a81c8f7171925c2e0e5bb79e4db4ee Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 22 Oct 2014 12:16:04 -0700 Subject: [PATCH 1051/9457] Staging: lustre: llite: Remove C99 '//' comments This patch fixes the following checkpatch.pl errors: ERROR: do not use C99 // comments 538: FILE: drivers/staging/lustre/lustre/llite/rw26.c:538: // .orig_aops.readpages = ll_readpages, 816: FILE: drivers/staging/lustre/lustre/llite/lproc_llite.c:816: //{ "mntpt_path", ll_rd_path, 0, 0 }, 826: FILE: drivers/staging/lustre/lustre/llite/lproc_llite.c:826: //{ "filegroups", lprocfs_rd_filegroups, 0, 0 }, Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/lproc_llite.c | 4 ++-- drivers/staging/lustre/lustre/llite/rw26.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 3b3df9f03422..f175c59dc166 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -813,7 +813,7 @@ LPROC_SEQ_FOPS(ll_xattr_cache); static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "uuid", &ll_sb_uuid_fops, NULL, 0 }, - //{ "mntpt_path", ll_rd_path, 0, 0 }, + /* { "mntpt_path", ll_rd_path, 0, 0 }, */ { "fstype", &ll_fstype_fops, NULL, 0 }, { "site", &ll_site_stats_fops, NULL, 0 }, { "blocksize", &ll_blksize_fops, NULL, 0 }, @@ -823,7 +823,7 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "filestotal", &ll_filestotal_fops, NULL, 0 }, { "filesfree", &ll_filesfree_fops, NULL, 0 }, { "client_type", &ll_client_type_fops, NULL, 0 }, - //{ "filegroups", lprocfs_rd_filegroups, 0, 0 }, + /* { "filegroups", lprocfs_rd_filegroups, 0, 0 }, */ { "max_read_ahead_mb", &ll_max_readahead_mb_fops, NULL }, { "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops, NULL }, diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index eac2131e6b85..14441b4df9b5 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -535,7 +535,7 @@ const struct address_space_operations ll_aops = { #else const struct address_space_operations_ext ll_aops = { .orig_aops.readpage = ll_readpage, -// .orig_aops.readpages = ll_readpages, +/* .orig_aops.readpages = ll_readpages, */ .orig_aops.direct_IO = ll_direct_IO_26, .orig_aops.writepage = ll_writepage, .orig_aops.writepages = ll_writepages, -- GitLab From 907cd2485b828deea069b100b6852ea0e54829da Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 22 Oct 2014 12:28:49 -0700 Subject: [PATCH 1052/9457] Staging: lustre: llite: Use () around long macro This patch fixes the following checkpatch.pl error: "Macros with complex values should be enclosed in parentheses." Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/rw26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c index 14441b4df9b5..2f21304046aa 100644 --- a/drivers/staging/lustre/lustre/llite/rw26.c +++ b/drivers/staging/lustre/lustre/llite/rw26.c @@ -183,7 +183,7 @@ static int ll_set_page_dirty(struct page *vmpage) return __set_page_dirty_nobuffers(vmpage); } -#define MAX_DIRECTIO_SIZE 2*1024*1024*1024UL +#define MAX_DIRECTIO_SIZE (2*1024*1024*1024UL) static inline int ll_get_user_pages(int rw, unsigned long user_addr, size_t size, struct page ***pages, -- GitLab From 464289d876ba6774972ecb277dad4b104e565fbe Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 22 Oct 2014 13:21:40 -0700 Subject: [PATCH 1053/9457] Staging: lustre: libcfs: Fix switch-case indent This patch fixes the following checkpatch error:j ERROR: switch and case should be at the same indent 105: FILE: drivers/staging/lustre/lustre/libcfs/fail.c:105: Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/fail.c | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c index e73ca3df9734..92444b0fe2a3 100644 --- a/drivers/staging/lustre/lustre/libcfs/fail.c +++ b/drivers/staging/lustre/lustre/libcfs/fail.c @@ -103,18 +103,18 @@ int __cfs_fail_check_set(__u32 id, __u32 value, int set) } switch (set) { - case CFS_FAIL_LOC_NOSET: - case CFS_FAIL_LOC_VALUE: - break; - case CFS_FAIL_LOC_ORSET: - cfs_fail_loc |= value & ~(CFS_FAILED | CFS_FAIL_ONCE); - break; - case CFS_FAIL_LOC_RESET: - cfs_fail_loc = value; - break; - default: - LASSERTF(0, "called with bad set %u\n", set); - break; + case CFS_FAIL_LOC_NOSET: + case CFS_FAIL_LOC_VALUE: + break; + case CFS_FAIL_LOC_ORSET: + cfs_fail_loc |= value & ~(CFS_FAILED | CFS_FAIL_ONCE); + break; + case CFS_FAIL_LOC_RESET: + cfs_fail_loc = value; + break; + default: + LASSERTF(0, "called with bad set %u\n", set); + break; } return 1; -- GitLab From 2a80f844158b9b5327a159dc9c0fa6b676d2bd9d Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 22 Oct 2014 13:39:11 -0700 Subject: [PATCH 1054/9457] Staging: lustre: llite: Declare ptr args correctly This patch fixes the following checkpatch errors: ERROR: "foo * bar" should be "foo *bar" 951: FILE: drivers/staging/lustre/lustre/llite/namei.c:951: static void ll_get_child_fid(struct inode * dir, struct qstr *name, 1193: FILE: drivers/staging/lustre/lustre/llite/namei.c:1193: static int ll_unlink(struct inode * dir, struct dentry *dentry) Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/namei.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 7a68c1e027e0..2971a26370be 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -948,7 +948,7 @@ static int ll_mkdir_generic(struct inode *dir, struct qstr *name, /* Try to find the child dentry by its name. If found, put the result fid into @fid. */ -static void ll_get_child_fid(struct inode * dir, struct qstr *name, +static void ll_get_child_fid(struct inode *dir, struct qstr *name, struct lu_fid *fid) { struct dentry *parent, *child; @@ -1190,7 +1190,7 @@ static int ll_mknod(struct inode *dir, struct dentry *dchild, ll_umode_t mode, old_encode_dev(rdev), dchild); } -static int ll_unlink(struct inode * dir, struct dentry *dentry) +static int ll_unlink(struct inode *dir, struct dentry *dentry) { return ll_unlink_generic(dir, NULL, dentry, &dentry->d_name); } -- GitLab From c8cb5f2c780a6003fcf76eb3ac1675fbb090ecd8 Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Mon, 20 Oct 2014 14:04:55 +0800 Subject: [PATCH 1055/9457] staging: rtl8188eu: core: fixed msleep < 20ms can sleep for up to 20ms warning in rtw_efuse.c This patch fixes following checkpatch.pl warning: WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 7006088d1ad0..e037c43c2837 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -250,7 +250,7 @@ static void efuse_read_phymap_from_txpktbuf( while (!(reg_0x143 = usb_read8(adapter, REG_TXPKTBUF_DBG)) && (passing_time = rtw_get_passing_time_ms(start)) < 1000) { DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, usb_read8(adapter, 0x106)); - msleep(1); + usleep_range(1000, 2000); } lo32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_L); -- GitLab From b312fb06b50b2aed3e75527fa74bc475dfb57cd6 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 21 Oct 2014 09:48:01 +0530 Subject: [PATCH 1056/9457] staging: rtl8188eu: os_dep: Remove useless cast on kzalloc Casting rhe return value which is a void pointer is redundant. The conversion from void pointer to any other pointer type is guaranteed by the C programming language, as mentioned in Documentation/CodingStyle, Chap 14. Removed the cast on kzalloc return value. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/osdep_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index 8af4a8d24cce..abcb3a8589ef 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -51,7 +51,7 @@ void *rtw_malloc2d(int h, int w, int size) { int j; - void **a = (void **)kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL); + void **a = kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL); if (a == NULL) { pr_info("%s: alloc memory fail!\n", __func__); return NULL; -- GitLab From 705515cdcdf972ad9df4d1a9874d0e94a3cad517 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 21 Oct 2014 09:48:20 +0530 Subject: [PATCH 1057/9457] staging: rtl8188eu: os_dep: Replaced kzalloc and memcpy with kmemdup Replaced calls to kzalloc followed by memcpy with a single call to kmemdup. Patch found using coccicheck. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index d598fec4abbf..d8605be07a71 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -512,14 +512,12 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie } if (ielen) { - buf = kzalloc(ielen, GFP_KERNEL); + buf = kmemdup(pie, ielen, GFP_KERNEL); if (buf == NULL) { ret = -ENOMEM; goto exit; } - memcpy(buf, pie, ielen); - /* dump */ { int i; -- GitLab From 93164c03ae7144bc4d9593a962a9169e9675dc3f Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 20 Oct 2014 10:24:49 +0530 Subject: [PATCH 1058/9457] staging: ft1000: Remove parentheses from return arguments The sematic patch used for this is: // @@ identifier i; constant c; @@ return - ( \(i\|-i\|i(...)\|c\) - ) ; // Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 0f347ab0d300..5899c4eca41f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -365,7 +365,7 @@ static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) /* DEBUG("ft1000_poll_dev called\n"); */ if (ft1000_flarion_cnt == 0) { DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); + return -EBADF; } /* Search for matching file object */ @@ -379,7 +379,7 @@ static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) /* Could not find application info block */ if (i == MAX_NUM_APP) { DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - return (-EACCES); + return -EACCES; } if (list_empty(&dev->app_info[i].app_sqlist) == 0) { @@ -433,7 +433,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, if (ft1000_flarion_cnt == 0) { DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); + return -EBADF; } /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ @@ -541,15 +541,15 @@ static long ft1000_ioctl(struct file *file, unsigned int command, if (ft1000_flarion_cnt == 0) { - return (-EBADF); + return -EBADF; } if (ft1000dev->DrvMsgPend) { - return (-ENOTTY); + return -ENOTTY; } if (ft1000dev->fProvComplete == 0) { - return (-EACCES); + return -EACCES; } ft1000dev->fAppMsgPend = 1; @@ -678,7 +678,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ if (ft1000_flarion_cnt == 0) { - return (-EBADF); + return -EBADF; } /* Search for matching file object */ @@ -762,7 +762,7 @@ static int ft1000_release(struct inode *inode, struct file *file) if (ft1000_flarion_cnt == 0) { ft1000dev->appcnt--; - return (-EBADF); + return -EBADF; } /* Search for matching file object */ -- GitLab From 817c66c4f50d7b0abb3e33117777d8890ac70040 Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Mon, 20 Oct 2014 19:13:56 +0800 Subject: [PATCH 1059/9457] staging: ft1000: ft1000-pcmcia: removed unused variable in ft1000_hw.c Variable whose value is initialized but never used is unnecessary. The following Coccinelle semantic patch removed the unused variable. @e@ identifier i; position p; type T; @@ extern T i@p; @@ type T; identifier i; constant C; position p != e.p; @@ - T i@p; <+... when != i - i = C; ...+> Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 9574775ba3b5..a9bcb9e1af78 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -1270,7 +1270,6 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) u16 nxtph; u16 total_len; int i = 0; - int cnt; unsigned long flags; doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL); @@ -1336,7 +1335,6 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) total_len); if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { total_len += nxtph; - cnt = 0; /* * ft1000_read_reg will return a value that needs to be byteswap * in order to get DSP_QID_OFFSET. -- GitLab From 17fbab1ee9a3e5d2a070450a0c76a3434278bc96 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 22 Oct 2014 11:23:57 +0530 Subject: [PATCH 1060/9457] staging: android: Assign bool to true high is a bool type variable. bool variable should be assigned true, false not 1 or 0. This patch assigns high to true, replacing 1. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion_page_pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 5864f3dfcbc6..4b88f11e52d3 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -120,7 +120,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, bool high; if (current_is_kswapd()) - high = 1; + high = true; else high = !!(gfp_mask & __GFP_HIGHMEM); -- GitLab From 2c1bfc3be0fc525d95ff5983bf8ea3f2aff24d1b Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Mon, 20 Oct 2014 16:58:10 +0530 Subject: [PATCH 1061/9457] staging: media: lirc: Delete unused function tv2int The function tv2int is used to convert timeval to int. 32-bit systems using 'struct timeval' will break in the year 2038, so we have to replace that code with more appropriate types. This patch changes the lirc_imon.c file of media: lirc driver. tv2int function is static and not used anywhere in this file too, so it is removed. I also build tested it. Signed-off-by: Tapasweni Pathak Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_imon.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 7aca44f28c5a..e4cfbe34e56d 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -572,29 +572,6 @@ static void submit_data(struct imon_context *context) wake_up(&context->driver->rbuf->wait_poll); } -static inline int tv2int(const struct timeval *a, const struct timeval *b) -{ - int usecs = 0; - int sec = 0; - - if (b->tv_usec > a->tv_usec) { - usecs = 1000000; - sec--; - } - - usecs += a->tv_usec - b->tv_usec; - - sec += a->tv_sec - b->tv_sec; - sec *= 1000; - usecs /= 1000; - sec += usecs; - - if (sec < 0) - sec = 1000; - - return sec; -} - /** * Process the incoming packet */ -- GitLab From a5a89d7a84fa3198e2e39b29325a65c211a0397c Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 21 Oct 2014 09:48:58 +0530 Subject: [PATCH 1062/9457] staging: emxx_udc: Remove null check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 1ae0013fb118..77e4aee74fa1 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2722,8 +2722,7 @@ static void nbu2ss_ep_free_request( if (_req != NULL) { req = container_of(_req, struct nbu2ss_req, req); - if (req != NULL) - kfree(req); + kfree(req); } } -- GitLab From 029bf13814d46d66aecd18c20f0e0c278696c5dc Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Wed, 22 Oct 2014 11:35:21 +0530 Subject: [PATCH 1063/9457] staging: rtl8723au: Remove unnecessary else if Removed the unnecessary else if condition as it has only one comment inside it and do not have an FIXME or TODO comment near to it too. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index c567df6c6321..2f01714bc9e2 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -850,7 +850,6 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, u8 key_index, dot11PrivacyAlgrthm; } } - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */ } } -- GitLab From 8d02c02253457a1facf077d8d67aa350ac317878 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Tue, 21 Oct 2014 09:50:03 +0530 Subject: [PATCH 1064/9457] staging: unisys: visorutil: Remove null check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorutil/procobjecttree.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorutil/procobjecttree.c b/drivers/staging/unisys/visorutil/procobjecttree.c index c476036f7382..195772d22c9e 100644 --- a/drivers/staging/unisys/visorutil/procobjecttree.c +++ b/drivers/staging/unisys/visorutil/procobjecttree.c @@ -320,19 +320,18 @@ void visor_proc_DestroyObject(MYPROCOBJECT *obj) kfree(obj->procDirProperties); obj->procDirProperties = NULL; } - if (obj->procDirPropertyContexts != NULL) { - kfree(obj->procDirPropertyContexts); - obj->procDirPropertyContexts = NULL; - } + + kfree(obj->procDirPropertyContexts); + obj->procDirPropertyContexts = NULL; + if (obj->procDir != NULL) { if (obj->name != NULL) remove_proc_entry(obj->name, type->procDir); obj->procDir = NULL; } - if (obj->name != NULL) { - kfree(obj->name); - obj->name = NULL; - } + + kfree(obj->name); + obj->name = NULL; kfree(obj); } EXPORT_SYMBOL_GPL(visor_proc_DestroyObject); -- GitLab From 1002a240ed72f0535f01ca88e0341ccf7c4e0b54 Mon Sep 17 00:00:00 2001 From: Aybuke Ozdemir Date: Tue, 21 Oct 2014 01:39:34 +0300 Subject: [PATCH 1065/9457] staging: media: omap24xx: Use min_t instead of min MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch focuses on fixing the following warning generated by checkpatch.pl for the file tcm825x.c: WARNİNG: min() should probably be min_t(u32, tgt_xclk, TCM825X_XCLK_MAX) The changes were applied using the following coccinelle rule: @@ expression e1, e2; typedef u32; @@ -tgt_xclk = min(e1, (u32)e2); +tgt_xclk = min_t(u32, e1, e2); Signed-off-by: Aybuke Ozdemir Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/omap24xx/tcm825x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/omap24xx/tcm825x.c b/drivers/staging/media/omap24xx/tcm825x.c index 9d9ecf1fc4ae..6a1f47995a17 100644 --- a/drivers/staging/media/omap24xx/tcm825x.c +++ b/drivers/staging/media/omap24xx/tcm825x.c @@ -751,7 +751,7 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) (2457 * tgt_fps) / MAX_FPS; tgt_xclk *= 10000; - tgt_xclk = min(tgt_xclk, (u32)TCM825X_XCLK_MAX); + tgt_xclk = min_t(u32, tgt_xclk, TCM825X_XCLK_MAX); tgt_xclk = max(tgt_xclk, (u32)TCM825X_XCLK_MIN); p->u.bt656.clock_curr = tgt_xclk; -- GitLab From cb6c1ee3057ebb717fd4439711b3cb5354d5085f Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Tue, 21 Oct 2014 02:47:29 +0300 Subject: [PATCH 1066/9457] staging: wlan-ng: Fix restricted __be16 degrades to integer skb->protocol variable type is __be16 and in if condition it is comparing with ETH_P_80211_RAW constant variable which is not __be16 type. Using be16_to_cpu() function, value of skb->protocol converted native processor format. This bug was found by sparse. Signed-off-by: Ebru Akagunduz Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 2dd9bf8a6e18..a9c1e0bafa62 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -358,7 +358,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, * and return success . * TODO: we need a saner way to handle this */ - if (skb->protocol != ETH_P_80211_RAW) { + if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) { netif_start_queue(wlandev->netdev); netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n"); netdev->stats.tx_dropped++; @@ -369,7 +369,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, } /* Check for raw transmits */ - if (skb->protocol == ETH_P_80211_RAW) { + if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) { if (!capable(CAP_NET_ADMIN)) { result = 1; goto failed; -- GitLab From b0ef3ed48eb8c1982c9d8b8063d856c83d116764 Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Mon, 20 Oct 2014 15:01:08 +0800 Subject: [PATCH 1067/9457] staging: rts5208: fix case of bitwise operator on zero in ms.c If a variable has value 0, then there is no point in combining it with other things with |, as for any x, 0 | x is just x. The following semantic patch finds this problem. @@ expression x,e,e1; statement S; @@ if (x == 0) { <... when != x = e1 when != while(...) S when != for(...;...;...) S ( * x |= e | * x | e ) ...> } Signed-off-by: Jiayi Ye Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/ms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 228e48339b9e..b4612fb615f6 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -2599,9 +2599,9 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, if (count > sector_cnt) { if (mode_2k) - ms_card->seq_mode |= MODE_2K_SEQ; + ms_card->seq_mode = MODE_2K_SEQ; else - ms_card->seq_mode |= MODE_512_SEQ; + ms_card->seq_mode = MODE_512_SEQ; } } else { count = sector_cnt; -- GitLab From e45708976aea3a3c3aa959e3cc2b703fefbd758a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Oct 2014 11:16:36 +0200 Subject: [PATCH 1068/9457] drm/dp-helper: Move the legacy helpers to gma500 Except for gma500 all drivers are converted to the new style helpers, which have much better abstraction of the underlying hw protocols and already much more helper functions (including the entire mst library) on top of them. Since no one seems to work on converting gma500 let's just move the code away so that new drivers don't end up accidentally using this. Cc: Patrik Jakobsson Reviewed-by: Patrik Jakobsson Reviewed-by: Alan Cox [danvet: Add __deprecated as requested by Alan. Also add a short FIXME comment and drop the EXPORT_SYMBOL which is no longer needed.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_dp_helper.c | 192 ------------------------- drivers/gpu/drm/gma500/cdv_intel_dp.c | 195 ++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 20 --- 3 files changed, 195 insertions(+), 212 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 08e33b8b13a4..c088bad7e72f 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -39,198 +39,6 @@ * blocks, ... */ -/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ -static int -i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, - uint8_t write_byte, uint8_t *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - ret = (*algo_data->aux_ch)(adapter, mode, - write_byte, read_byte); - return ret; -} - -/* - * I2C over AUX CH - */ - -/* - * Send the address. If the I2C link is running, this 'restarts' - * the connection with the new address, this is used for doing - * a write followed by a read (as needed for DDC) - */ -static int -i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_START; - int ret; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - algo_data->address = address; - algo_data->running = true; - ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - return ret; -} - -/* - * Stop the I2C transaction. This closes out the link, sending - * a bare address packet with the MOT bit turned off - */ -static void -i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_STOP; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - if (algo_data->running) { - (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - algo_data->running = false; - } -} - -/* - * Write a single byte to the current I2C address, the - * the I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); - return ret; -} - -/* - * Read a single byte from the current I2C address, the - * I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); - return ret; -} - -static int -i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - int ret = 0; - bool reading = false; - int m; - int b; - - for (m = 0; m < num; m++) { - u16 len = msgs[m].len; - u8 *buf = msgs[m].buf; - reading = (msgs[m].flags & I2C_M_RD) != 0; - ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); - if (ret < 0) - break; - if (reading) { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); - if (ret < 0) - break; - } - } else { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); - if (ret < 0) - break; - } - } - if (ret < 0) - break; - } - if (ret >= 0) - ret = num; - i2c_algo_dp_aux_stop(adapter, reading); - DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret); - return ret; -} - -static u32 -i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | - I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm i2c_dp_aux_algo = { - .master_xfer = i2c_algo_dp_aux_xfer, - .functionality = i2c_algo_dp_aux_functionality, -}; - -static void -i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) -{ - (void) i2c_algo_dp_aux_address(adapter, 0, false); - (void) i2c_algo_dp_aux_stop(adapter, false); -} - -static int -i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) -{ - adapter->algo = &i2c_dp_aux_algo; - adapter->retries = 3; - i2c_dp_aux_reset_bus(adapter); - return 0; -} - -/** - * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper - * @adapter: i2c adapter to register - * - * This registers an i2c adapter that uses dp aux channel as it's underlaying - * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure - * and store it in the algo_data member of the @adapter argument. This will be - * used by the i2c over dp aux algorithm to drive the hardware. - * - * RETURNS: - * 0 on success, -ERRNO on failure. - * - * IMPORTANT: - * This interface is deprecated, please switch to the new dp aux helpers and - * drm_dp_aux_register(). - */ -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter) -{ - int error; - - error = i2c_dp_aux_prepare_bus(adapter); - if (error) - return error; - error = i2c_add_adapter(adapter); - return error; -} -EXPORT_SYMBOL(i2c_dp_aux_add_bus); - /* Helpers for DP link training */ static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r) { diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 9f158eab517a..0fafb8e2483a 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -37,6 +37,201 @@ #include "gma_display.h" #include +/** + * struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp + * aux algorithm + * @running: set by the algo indicating whether an i2c is ongoing or whether + * the i2c bus is quiescent + * @address: i2c target address for the currently ongoing transfer + * @aux_ch: driver callback to transfer a single byte of the i2c payload + */ +struct i2c_algo_dp_aux_data { + bool running; + u16 address; + int (*aux_ch) (struct i2c_adapter *adapter, + int mode, uint8_t write_byte, + uint8_t *read_byte); +}; + +/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ +static int +i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, + uint8_t write_byte, uint8_t *read_byte) +{ + struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; + int ret; + + ret = (*algo_data->aux_ch)(adapter, mode, + write_byte, read_byte); + return ret; +} + +/* + * I2C over AUX CH + */ + +/* + * Send the address. If the I2C link is running, this 'restarts' + * the connection with the new address, this is used for doing + * a write followed by a read (as needed for DDC) + */ +static int +i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) +{ + struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; + int mode = MODE_I2C_START; + int ret; + + if (reading) + mode |= MODE_I2C_READ; + else + mode |= MODE_I2C_WRITE; + algo_data->address = address; + algo_data->running = true; + ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); + return ret; +} + +/* + * Stop the I2C transaction. This closes out the link, sending + * a bare address packet with the MOT bit turned off + */ +static void +i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) +{ + struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; + int mode = MODE_I2C_STOP; + + if (reading) + mode |= MODE_I2C_READ; + else + mode |= MODE_I2C_WRITE; + if (algo_data->running) { + (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); + algo_data->running = false; + } +} + +/* + * Write a single byte to the current I2C address, the + * the I2C link must be running or this returns -EIO + */ +static int +i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) +{ + struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; + int ret; + + if (!algo_data->running) + return -EIO; + + ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); + return ret; +} + +/* + * Read a single byte from the current I2C address, the + * I2C link must be running or this returns -EIO + */ +static int +i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) +{ + struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; + int ret; + + if (!algo_data->running) + return -EIO; + + ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); + return ret; +} + +static int +i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, + int num) +{ + int ret = 0; + bool reading = false; + int m; + int b; + + for (m = 0; m < num; m++) { + u16 len = msgs[m].len; + u8 *buf = msgs[m].buf; + reading = (msgs[m].flags & I2C_M_RD) != 0; + ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); + if (ret < 0) + break; + if (reading) { + for (b = 0; b < len; b++) { + ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); + if (ret < 0) + break; + } + } else { + for (b = 0; b < len; b++) { + ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); + if (ret < 0) + break; + } + } + if (ret < 0) + break; + } + if (ret >= 0) + ret = num; + i2c_algo_dp_aux_stop(adapter, reading); + DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret); + return ret; +} + +static u32 +i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | + I2C_FUNC_SMBUS_BLOCK_PROC_CALL | + I2C_FUNC_10BIT_ADDR; +} + +static const struct i2c_algorithm i2c_dp_aux_algo = { + .master_xfer = i2c_algo_dp_aux_xfer, + .functionality = i2c_algo_dp_aux_functionality, +}; + +static void +i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) +{ + (void) i2c_algo_dp_aux_address(adapter, 0, false); + (void) i2c_algo_dp_aux_stop(adapter, false); +} + +static int +i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) +{ + adapter->algo = &i2c_dp_aux_algo; + adapter->retries = 3; + i2c_dp_aux_reset_bus(adapter); + return 0; +} + +/* + * FIXME: This is the old dp aux helper, gma500 is the last driver that needs to + * be ported over to the new helper code in drm_dp_helper.c like i915 or radeon. + */ +static int __deprecated +i2c_dp_aux_add_bus(struct i2c_adapter *adapter) +{ + int error; + + error = i2c_dp_aux_prepare_bus(adapter); + if (error) + return error; + error = i2c_add_adapter(adapter); + return error; +} + #define _wait_for(COND, MS, W) ({ \ unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ int ret__ = 0; \ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 9305c718d789..afebb08eee3a 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -404,26 +404,6 @@ #define MODE_I2C_READ 4 #define MODE_I2C_STOP 8 -/** - * struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp - * aux algorithm - * @running: set by the algo indicating whether an i2c is ongoing or whether - * the i2c bus is quiescent - * @address: i2c target address for the currently ongoing transfer - * @aux_ch: driver callback to transfer a single byte of the i2c payload - */ -struct i2c_algo_dp_aux_data { - bool running; - u16 address; - int (*aux_ch) (struct i2c_adapter *adapter, - int mode, uint8_t write_byte, - uint8_t *read_byte); -}; - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter); - - #define DP_LINK_STATUS_SIZE 6 bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count); -- GitLab From b00358a5632bdfc5048fdee04b548ebf8ca1c79c Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 23 Oct 2014 08:41:44 +0900 Subject: [PATCH 1069/9457] nandsim: add id_bytes module parameter nandsim can simulate NAND Flash which returns the ID bytes specified by first_id_byte, ..., fourth_id_byte module parameters. In order to simulate NAND flash which returns more than four ID bytes, this adds id_bytes module parameter which is specified by the array of byte like this: # modprobe nandsim id_bytes=0x98,0xdc,0x90,0x26,0x76,0x15,0x01,0x08 bch=1 This doesn't add fifth_id_byte, ..., seventh_id_byte module parameters, because they are redundant. But the existing first_id_byte, ..., fourth_id_byte module parameters are preserved and add "(obsolete)" to the description. Cc: Artem Bityutskiy Cc: David Woodhouse Cc: Brian Norris Cc: linux-mtd@lists.infradead.org Signed-off-by: Akinobu Mita Signed-off-by: Brian Norris --- drivers/mtd/nand/nandsim.c | 42 ++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 7dc1dd28d896..ab5bbf567439 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -87,10 +87,6 @@ #define CONFIG_NANDSIM_MAX_PARTS 32 #endif -static uint first_id_byte = CONFIG_NANDSIM_FIRST_ID_BYTE; -static uint second_id_byte = CONFIG_NANDSIM_SECOND_ID_BYTE; -static uint third_id_byte = CONFIG_NANDSIM_THIRD_ID_BYTE; -static uint fourth_id_byte = CONFIG_NANDSIM_FOURTH_ID_BYTE; static uint access_delay = CONFIG_NANDSIM_ACCESS_DELAY; static uint programm_delay = CONFIG_NANDSIM_PROGRAMM_DELAY; static uint erase_delay = CONFIG_NANDSIM_ERASE_DELAY; @@ -111,11 +107,19 @@ static unsigned int overridesize = 0; static char *cache_file = NULL; static unsigned int bbt; static unsigned int bch; +static u_char id_bytes[8] = { + [0] = CONFIG_NANDSIM_FIRST_ID_BYTE, + [1] = CONFIG_NANDSIM_SECOND_ID_BYTE, + [2] = CONFIG_NANDSIM_THIRD_ID_BYTE, + [3] = CONFIG_NANDSIM_FOURTH_ID_BYTE, + [4 ... 7] = 0xFF, +}; -module_param(first_id_byte, uint, 0400); -module_param(second_id_byte, uint, 0400); -module_param(third_id_byte, uint, 0400); -module_param(fourth_id_byte, uint, 0400); +module_param_array(id_bytes, byte, NULL, 0400); +module_param_named(first_id_byte, id_bytes[0], byte, 0400); +module_param_named(second_id_byte, id_bytes[1], byte, 0400); +module_param_named(third_id_byte, id_bytes[2], byte, 0400); +module_param_named(fourth_id_byte, id_bytes[3], byte, 0400); module_param(access_delay, uint, 0400); module_param(programm_delay, uint, 0400); module_param(erase_delay, uint, 0400); @@ -136,10 +140,11 @@ module_param(cache_file, charp, 0400); module_param(bbt, uint, 0400); module_param(bch, uint, 0400); -MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)"); -MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)"); -MODULE_PARM_DESC(third_id_byte, "The third byte returned by NAND Flash 'read ID' command"); -MODULE_PARM_DESC(fourth_id_byte, "The fourth byte returned by NAND Flash 'read ID' command"); +MODULE_PARM_DESC(id_bytes, "The ID bytes returned by NAND Flash 'read ID' command"); +MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID) (obsolete)"); +MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID) (obsolete)"); +MODULE_PARM_DESC(third_id_byte, "The third byte returned by NAND Flash 'read ID' command (obsolete)"); +MODULE_PARM_DESC(fourth_id_byte, "The fourth byte returned by NAND Flash 'read ID' command (obsolete)"); MODULE_PARM_DESC(access_delay, "Initial page access delay (microseconds)"); MODULE_PARM_DESC(programm_delay, "Page programm delay (microseconds"); MODULE_PARM_DESC(erase_delay, "Sector erase delay (milliseconds)"); @@ -304,7 +309,7 @@ struct nandsim { unsigned int nbparts; uint busw; /* flash chip bus width (8 or 16) */ - u_char ids[4]; /* chip's ID bytes */ + u_char ids[8]; /* chip's ID bytes */ uint32_t options; /* chip's characteristic bits */ uint32_t state; /* current chip state */ uint32_t nxstate; /* next expected state */ @@ -2279,17 +2284,18 @@ static int __init ns_init_module(void) * Perform minimum nandsim structure initialization to handle * the initial ID read command correctly */ - if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) + if (id_bytes[6] != 0xFF || id_bytes[7] != 0xFF) + nand->geom.idbytes = 8; + else if (id_bytes[4] != 0xFF || id_bytes[5] != 0xFF) + nand->geom.idbytes = 6; + else if (id_bytes[2] != 0xFF || id_bytes[3] != 0xFF) nand->geom.idbytes = 4; else nand->geom.idbytes = 2; nand->regs.status = NS_STATUS_OK(nand); nand->nxstate = STATE_UNKNOWN; nand->options |= OPT_PAGE512; /* temporary value */ - nand->ids[0] = first_id_byte; - nand->ids[1] = second_id_byte; - nand->ids[2] = third_id_byte; - nand->ids[3] = fourth_id_byte; + memcpy(nand->ids, id_bytes, sizeof(nand->ids)); if (bus_width == 16) { nand->busw = 16; chip->options |= NAND_BUSWIDTH_16; -- GitLab From 5a1cbdb0fb6748a52a33f4ccd5d49486d7479fbb Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 23 Oct 2014 09:06:28 +0900 Subject: [PATCH 1070/9457] gpu: drm: Fix warning caused by a parameter description in drm_crtc.c This patch fix following error while "make xmldocs" Warning(.//drivers/gpu/drm/drm_crtc.c:778): Excess function parameter 'mode' description in 'drm_connector_get_cmdline_mode' Signed-off-by: Masanari Iida Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b4a6f08d0045..4081d7ab8407 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -766,7 +766,6 @@ static void drm_mode_remove(struct drm_connector *connector, /** * drm_connector_get_cmdline_mode - reads the user's cmdline mode * @connector: connector to quwery - * @mode: returned mode * * The kernel supports per-connector configration of its consoles through * use of the video= parameter. This function parses that option and -- GitLab From 00d647b081b5ef2193fd15910fbd103f483a5d15 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 23 Oct 2014 17:15:18 +0900 Subject: [PATCH 1071/9457] ASoC: jack: update calls to gpiod_get*() Add the new flags argument to calls of (devm_)gpiod_get*() and remove any direction setting code afterwards. Currently both forms (with or without the flags argument) are valid thanks to transitional macros in . These macros will be removed once all consumers are updated and the flags argument will become compulsary. Signed-off-by: Alexandre Courbot Signed-off-by: Mark Brown --- sound/soc/soc-jack.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index ab47fea997a3..f921d0098518 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -309,7 +309,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, /* GPIO descriptor */ gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev, gpios[i].name, - gpios[i].idx); + gpios[i].idx, GPIOD_IN); if (IS_ERR(gpios[i].desc)) { ret = PTR_ERR(gpios[i].desc); dev_err(gpios[i].gpiod_dev, @@ -327,17 +327,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, goto undo; } - ret = gpio_request(gpios[i].gpio, gpios[i].name); + ret = gpio_request_one(gpios[i].gpio, GPIOF_IN, + gpios[i].name); if (ret) goto undo; gpios[i].desc = gpio_to_desc(gpios[i].gpio); } - ret = gpiod_direction_input(gpios[i].desc); - if (ret) - goto err; - INIT_DELAYED_WORK(&gpios[i].work, gpio_work); gpios[i].jack = jack; -- GitLab From e29bee098ea1cc9b8537628f3c1cdf60ead83514 Mon Sep 17 00:00:00 2001 From: Ben Zhang Date: Mon, 20 Oct 2014 20:30:13 -0700 Subject: [PATCH 1072/9457] ASoC: rt5677: fix rt5677 spi driver build Create a separate module for rt5677 spi driver. Without this patch, the build fails due to multiple defs of 'init_module' and 'cleanup_module'. module_spi_driver() defines its own module, so it can't be part of the rt5677 module. Signed-off-by: Ben Zhang Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 ++++ sound/soc/codecs/Makefile | 4 +++- sound/soc/codecs/rt5677-spi.c | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 2c7482ec25e8..6f21a766723c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -504,6 +504,10 @@ config SND_SOC_RT5670 config SND_SOC_RT5677 tristate +config SND_SOC_RT5677_SPI + tristate + default SND_SOC_RT5677 + #Freescale sgtl5000 codec config SND_SOC_SGTL5000 tristate "Freescale SGTL5000 CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4435f9f18ce8..3e57edc1f510 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -79,7 +79,8 @@ snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o snd-soc-rt5651-objs := rt5651.o snd-soc-rt5670-objs := rt5670.o -snd-soc-rt5677-objs := rt5677.o rt5677-spi.o +snd-soc-rt5677-objs := rt5677.o +snd-soc-rt5677-spi-objs := rt5677-spi.o snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o @@ -256,6 +257,7 @@ obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o +obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c index 11c38f3a9b72..ef6348cb9157 100644 --- a/sound/soc/codecs/rt5677-spi.c +++ b/sound/soc/codecs/rt5677-spi.c @@ -52,6 +52,7 @@ int rt5677_spi_write(u8 *txbuf, size_t len) return status; } +EXPORT_SYMBOL_GPL(rt5677_spi_write); /** * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address. @@ -107,6 +108,7 @@ int rt5677_spi_burst_write(u32 addr, const struct firmware *fw) return 0; } +EXPORT_SYMBOL_GPL(rt5677_spi_burst_write); static int rt5677_spi_probe(struct spi_device *spi) { -- GitLab From 2088ecba93f68252464b95375d80a12fe723ba5e Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:19 -0500 Subject: [PATCH 1073/9457] iommu/omap: Remove refcount field from omap_iommu object The refcount field in omap_iommu object is primarily used to check if an IOMMU device has already been enabled, but this is already implicit in the omap_iommu_attach_dev() which ensures that only a single device can attach to an IOMMU. This field is redundant, and so has been cleaned up. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 15 +++------------ drivers/iommu/omap-iommu.h | 1 - 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 36278870e84a..ea04e4d30bbf 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -819,8 +819,9 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) u32 *iopgd, *iopte; struct omap_iommu *obj = data; struct iommu_domain *domain = obj->domain; + struct omap_iommu_domain *omap_domain = domain->priv; - if (!obj->refcount) + if (!omap_domain->iommu_dev) return IRQ_NONE; errs = iommu_report_fault(obj, &da); @@ -880,13 +881,6 @@ static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd) spin_lock(&obj->iommu_lock); - /* an iommu device can only be attached once */ - if (++obj->refcount > 1) { - dev_err(dev, "%s: already attached!\n", obj->name); - err = -EBUSY; - goto err_enable; - } - obj->iopgd = iopgd; err = iommu_enable(obj); if (err) @@ -899,7 +893,6 @@ static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd) return obj; err_enable: - obj->refcount--; spin_unlock(&obj->iommu_lock); return ERR_PTR(err); } @@ -915,9 +908,7 @@ static void omap_iommu_detach(struct omap_iommu *obj) spin_lock(&obj->iommu_lock); - if (--obj->refcount == 0) - iommu_disable(obj); - + iommu_disable(obj); obj->iopgd = NULL; spin_unlock(&obj->iommu_lock); diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 4f1b68c08c15..5c1400024e35 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -33,7 +33,6 @@ struct omap_iommu { void *isr_priv; struct iommu_domain *domain; - unsigned int refcount; spinlock_t iommu_lock; /* global for this whole object */ /* -- GitLab From 4cfcf2ab01617401236b84c3539a59099592c7f3 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:20 -0500 Subject: [PATCH 1074/9457] iommu/omap: Remove unused isr_priv field from omap_iommu The isr_priv field is a left-over from before the IOMMU API adaptation, this was used to store the callback data. This is no longer relevant, so remove it. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 5c1400024e35..18a0f3a138d9 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -30,7 +30,6 @@ struct omap_iommu { const char *name; void __iomem *regbase; struct device *dev; - void *isr_priv; struct iommu_domain *domain; spinlock_t iommu_lock; /* global for this whole object */ -- GitLab From 52dad776fcb644f9ccfc1986c965bd9438e59b21 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:21 -0500 Subject: [PATCH 1075/9457] iommu/omap: Remove duplicate declarations The omap_iommu_save_ctx() and omap_iommu_restore_ctx() declarations are defined in include/linux/omap-iommu.h and do not belong in the internal drivers/iommu/omap-iommu.h header, so remove them. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 18a0f3a138d9..4fc51c8e24b1 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -197,9 +197,6 @@ extern void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern int omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); -extern void omap_iommu_save_ctx(struct device *dev); -extern void omap_iommu_restore_ctx(struct device *dev); - extern int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *)); -- GitLab From 533b40cccd2fbe8cf6ba361cab7e99f626be45bf Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:22 -0500 Subject: [PATCH 1076/9457] iommu/omap: Remove conditional definition of dev_to_omap_iommu() The dev_to_omap_iommu() is local to the OMAP IOMMU modules, and need not be defined conditionally. The CONFIG_IOMMU_API dependency check was added in the past to fix a compilation issue back when the header resided in the arch/arm layers, and is no longer needed. While at this, fix the header against double inclusion as well. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 4fc51c8e24b1..d7c51327cd25 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -10,6 +10,9 @@ * published by the Free Software Foundation. */ +#ifndef _OMAP_IOMMU_H +#define _OMAP_IOMMU_H + #if defined(CONFIG_ARCH_OMAP1) #error "iommu for this processor not implemented yet" #endif @@ -92,7 +95,6 @@ struct iommu_functions { ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len); }; -#ifdef CONFIG_IOMMU_API /** * dev_to_omap_iommu() - retrieves an omap iommu object from a user device * @dev: iommu client device @@ -103,7 +105,6 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) return arch_data->iommu_dev; } -#endif /* * MMU Register offsets @@ -220,3 +221,5 @@ static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs) { __raw_writel(val, obj->regbase + offs); } + +#endif /* _OMAP_IOMMU_H */ -- GitLab From 2b313dd13a1690b9c4e2a968feea890838b77b81 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:23 -0500 Subject: [PATCH 1077/9457] iommu/omap: Remove ver debugfs entry The debugfs entry 'ver' to read the OMAP IOMMU version is not much useful for developers, so it has been removed. The same can be deduced from the register dump, provided by the debugfs entry 'regs', REVISION register. This also allows us to remove the omap_iommu_arch_revision() which is currently returning a fixed value. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 531658d17333..0fb92aa42c19 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -30,17 +30,6 @@ static DEFINE_MUTEX(iommu_debug_lock); static struct dentry *iommu_debug_root; -static ssize_t debug_read_ver(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - u32 ver = omap_iommu_arch_version(); - char buf[MAXCOLUMN], *p = buf; - - p += sprintf(p, "H/W version: %d.%d\n", (ver >> 4) & 0xf , ver & 0xf); - - return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); -} - static ssize_t debug_read_regs(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -228,7 +217,6 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, .llseek = generic_file_llseek, \ }; -DEBUG_FOPS_RO(ver); DEBUG_FOPS_RO(regs); DEBUG_FOPS_RO(tlb); DEBUG_FOPS(pagetable); @@ -273,7 +261,6 @@ static int iommu_debug_register(struct device *dev, void *data) if (!d) goto nomem; - DEBUG_ADD_FILE_RO(ver); DEBUG_ADD_FILE_RO(regs); DEBUG_ADD_FILE_RO(tlb); DEBUG_ADD_FILE(pagetable); -- GitLab From 3acb04ca5ea4e03c5718a87b713b2fd6f7f52b51 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:24 -0500 Subject: [PATCH 1078/9457] iommu/omap: Remove omap_iommu_arch_version() and version field The function omap_iommu_arch_version() is not used anymore, and is not required either, so remove it. The .version field in struct iommu_functions that this function uses is also removed, as it is not really an ops to retrieve a version and there won't be any usage for this field either. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 9 --------- drivers/iommu/omap-iommu.h | 4 ---- drivers/iommu/omap-iommu2.c | 2 -- 3 files changed, 15 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index ea04e4d30bbf..f9efa6ba99f5 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -138,15 +138,6 @@ void omap_iommu_restore_ctx(struct device *dev) } EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); -/** - * omap_iommu_arch_version - Return running iommu arch version - **/ -u32 omap_iommu_arch_version(void) -{ - return arch_iommu->version; -} -EXPORT_SYMBOL_GPL(omap_iommu_arch_version); - static int iommu_enable(struct omap_iommu *obj) { int err; diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index d7c51327cd25..45fe67d641e2 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -70,8 +70,6 @@ struct cr_regs { /* architecture specific functions */ struct iommu_functions { - unsigned long version; - int (*enable)(struct omap_iommu *obj); void (*disable)(struct omap_iommu *obj); void (*set_twl)(struct omap_iommu *obj, bool on); @@ -191,8 +189,6 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) /* * global functions */ -extern u32 omap_iommu_arch_version(void); - extern void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern int diff --git a/drivers/iommu/omap-iommu2.c b/drivers/iommu/omap-iommu2.c index 5e1ea3b0bf16..2f6a9f76c6ee 100644 --- a/drivers/iommu/omap-iommu2.c +++ b/drivers/iommu/omap-iommu2.c @@ -297,8 +297,6 @@ static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) } static const struct iommu_functions omap2_iommu_ops = { - .version = IOMMU_ARCH_VERSION, - .enable = omap2_iommu_enable, .disable = omap2_iommu_disable, .set_twl = omap2_iommu_set_twl, -- GitLab From c2372aafbc4ff59bb6a6bda7ed73364d7f7c53bb Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:25 -0500 Subject: [PATCH 1079/9457] iommu/omap: Remove bogus version check in context save/restore The omap2_iommu_save_ctx() and omap2_iommu_restore_ctx() performs a sanity version check against a fixed value that is correct only for OMAP2/OMAP3 IOMMUs. This fixed check does not scale for all OMAP2+ IOMMUs and is not absolutely required, so it has been removed. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu2.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/iommu/omap-iommu2.c b/drivers/iommu/omap-iommu2.c index 2f6a9f76c6ee..372141b2267d 100644 --- a/drivers/iommu/omap-iommu2.c +++ b/drivers/iommu/omap-iommu2.c @@ -26,8 +26,6 @@ /* * omap2 architecture specific register bit definitions */ -#define IOMMU_ARCH_VERSION 0x00000011 - /* IRQSTATUS & IRQENABLE */ #define MMU_IRQ_MULTIHITFAULT (1 << 4) #define MMU_IRQ_TABLEWALKFAULT (1 << 3) @@ -268,8 +266,6 @@ static void omap2_iommu_save_ctx(struct omap_iommu *obj) p[i] = iommu_read_reg(obj, i * sizeof(u32)); dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); } - - BUG_ON(p[0] != IOMMU_ARCH_VERSION); } static void omap2_iommu_restore_ctx(struct omap_iommu *obj) @@ -281,8 +277,6 @@ static void omap2_iommu_restore_ctx(struct omap_iommu *obj) iommu_write_reg(obj, p[i], i * sizeof(u32)); dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); } - - BUG_ON(p[0] != IOMMU_ARCH_VERSION); } static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) -- GitLab From 124262a2eecc4c3e6e96e083e50ce4909b2d69d9 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:26 -0500 Subject: [PATCH 1080/9457] iommu/omap: Simplify omap2_iommu_fault_isr() The function omap2_iommu_fault_isr() does an unnecessary recomputation of the return value. The logic relies on setting the same bit fields as the MMU fault error status bits, so simplify this function and remove the unneeded macros. These macros were originally exported to notify MMU faults to users prior to the IOMMU framework adaptation, but are now redundant. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu2.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/iommu/omap-iommu2.c b/drivers/iommu/omap-iommu2.c index 372141b2267d..ce2fff37aa61 100644 --- a/drivers/iommu/omap-iommu2.c +++ b/drivers/iommu/omap-iommu2.c @@ -53,13 +53,6 @@ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) -/* IOMMU errors */ -#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) -#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) -#define OMAP_IOMMU_ERR_EMU_MISS (1 << 2) -#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3) -#define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4) - static void __iommu_set_twl(struct omap_iommu *obj, bool on) { u32 l = iommu_read_reg(obj, MMU_CNTL); @@ -122,7 +115,6 @@ static void omap2_iommu_set_twl(struct omap_iommu *obj, bool on) static u32 omap2_iommu_fault_isr(struct omap_iommu *obj, u32 *ra) { u32 stat, da; - u32 errs = 0; stat = iommu_read_reg(obj, MMU_IRQSTATUS); stat &= MMU_IRQ_MASK; @@ -134,19 +126,9 @@ static u32 omap2_iommu_fault_isr(struct omap_iommu *obj, u32 *ra) da = iommu_read_reg(obj, MMU_FAULT_AD); *ra = da; - if (stat & MMU_IRQ_TLBMISS) - errs |= OMAP_IOMMU_ERR_TLB_MISS; - if (stat & MMU_IRQ_TRANSLATIONFAULT) - errs |= OMAP_IOMMU_ERR_TRANS_FAULT; - if (stat & MMU_IRQ_EMUMISS) - errs |= OMAP_IOMMU_ERR_EMU_MISS; - if (stat & MMU_IRQ_TABLEWALKFAULT) - errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT; - if (stat & MMU_IRQ_MULTIHITFAULT) - errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT; iommu_write_reg(obj, stat, MMU_IRQSTATUS); - return errs; + return stat; } static void omap2_tlb_read_cr(struct omap_iommu *obj, struct cr_regs *cr) -- GitLab From bd4396f09a4a9e77423e92ec9448217ab46f6edf Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:27 -0500 Subject: [PATCH 1081/9457] iommu/omap: Consolidate OMAP IOMMU modules The OMAP IOMMU driver was originally designed as modules, and split into a core module and a thin arch-specific module through the OMAP arch-specific struct iommu_functions, to scale for both OMAP1 and OMAP2+ IOMMU variants. The driver can only be built for OMAP2+ platforms currently, and also can only be built-in after the adaptation to generic IOMMU API. The OMAP1 variant was never added and will most probably be never added (the code for the only potential user, its parent, DSP processor has already been cleaned up). So, consolidate the OMAP2 specific omap-iommu2 module into the core OMAP IOMMU driver - this eliminates the arch-specific ops structure and simplifies the driver into a single module that only implements the generic IOMMU API's iommu_ops. The following are the main changes: - omap-iommu2 module is completely eliminated, with the common definitions moved to the internal omap-iommu.h, and the ops implementations moved into omap-iommu.c - OMAP arch-specific struct iommu_functions is also eliminated, with the ops implementations directly absorbed into the calling functions - iotlb_alloc_cr() is no longer inlined and defined only when PREFETCH_IOTLB is defined - iotlb_dump_cr() is similarly defined only when CONFIG_OMAP_IOMMU_DEBUG is defined - Elimination of the OMAP IOMMU exported functions to register the arch ops, omap_install_iommu_arch() & omap_uninstall_iommu_arch() - Any stale comments about OMAP1 are also cleaned up Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/Makefile | 1 - drivers/iommu/omap-iommu.c | 263 +++++++++++++++++++++--------- drivers/iommu/omap-iommu.h | 61 ++++--- drivers/iommu/omap-iommu2.c | 311 ------------------------------------ 4 files changed, 217 insertions(+), 419 deletions(-) delete mode 100644 drivers/iommu/omap-iommu2.c diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 16edef74b8ee..18fa446a4ffa 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o -obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index f9efa6ba99f5..91262fa2a351 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -76,44 +76,9 @@ struct iotlb_lock { short vict; }; -/* accommodate the difference between omap1 and omap2/3 */ -static const struct iommu_functions *arch_iommu; - static struct platform_driver omap_iommu_driver; static struct kmem_cache *iopte_cachep; -/** - * omap_install_iommu_arch - Install archtecure specific iommu functions - * @ops: a pointer to architecture specific iommu functions - * - * There are several kind of iommu algorithm(tlb, pagetable) among - * omap series. This interface installs such an iommu algorighm. - **/ -int omap_install_iommu_arch(const struct iommu_functions *ops) -{ - if (arch_iommu) - return -EBUSY; - - arch_iommu = ops; - return 0; -} -EXPORT_SYMBOL_GPL(omap_install_iommu_arch); - -/** - * omap_uninstall_iommu_arch - Uninstall archtecure specific iommu functions - * @ops: a pointer to architecture specific iommu functions - * - * This interface uninstalls the iommu algorighm installed previously. - **/ -void omap_uninstall_iommu_arch(const struct iommu_functions *ops) -{ - if (arch_iommu != ops) - pr_err("%s: not your arch\n", __func__); - - arch_iommu = NULL; -} -EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch); - /** * omap_iommu_save_ctx - Save registers for pm off-mode support * @dev: client device @@ -121,8 +86,13 @@ EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch); void omap_iommu_save_ctx(struct device *dev) { struct omap_iommu *obj = dev_to_omap_iommu(dev); + u32 *p = obj->ctx; + int i; - arch_iommu->save_ctx(obj); + for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { + p[i] = iommu_read_reg(obj, i * sizeof(u32)); + dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); + } } EXPORT_SYMBOL_GPL(omap_iommu_save_ctx); @@ -133,20 +103,75 @@ EXPORT_SYMBOL_GPL(omap_iommu_save_ctx); void omap_iommu_restore_ctx(struct device *dev) { struct omap_iommu *obj = dev_to_omap_iommu(dev); + u32 *p = obj->ctx; + int i; - arch_iommu->restore_ctx(obj); + for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { + iommu_write_reg(obj, p[i], i * sizeof(u32)); + dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); + } } EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); +static void __iommu_set_twl(struct omap_iommu *obj, bool on) +{ + u32 l = iommu_read_reg(obj, MMU_CNTL); + + if (on) + iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); + else + iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); + + l &= ~MMU_CNTL_MASK; + if (on) + l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); + else + l |= (MMU_CNTL_MMU_EN); + + iommu_write_reg(obj, l, MMU_CNTL); +} + +static int omap2_iommu_enable(struct omap_iommu *obj) +{ + u32 l, pa; + + if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K)) + return -EINVAL; + + pa = virt_to_phys(obj->iopgd); + if (!IS_ALIGNED(pa, SZ_16K)) + return -EINVAL; + + l = iommu_read_reg(obj, MMU_REVISION); + dev_info(obj->dev, "%s: version %d.%d\n", obj->name, + (l >> 4) & 0xf, l & 0xf); + + iommu_write_reg(obj, pa, MMU_TTB); + + if (obj->has_bus_err_back) + iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG); + + __iommu_set_twl(obj, true); + + return 0; +} + +static void omap2_iommu_disable(struct omap_iommu *obj) +{ + u32 l = iommu_read_reg(obj, MMU_CNTL); + + l &= ~MMU_CNTL_MASK; + iommu_write_reg(obj, l, MMU_CNTL); + + dev_dbg(obj->dev, "%s is shutting down\n", obj->name); +} + static int iommu_enable(struct omap_iommu *obj) { int err; struct platform_device *pdev = to_platform_device(obj->dev); struct iommu_platform_data *pdata = pdev->dev.platform_data; - if (!arch_iommu) - return -ENODEV; - if (pdata && pdata->deassert_reset) { err = pdata->deassert_reset(pdev, pdata->reset_name); if (err) { @@ -157,7 +182,7 @@ static int iommu_enable(struct omap_iommu *obj) pm_runtime_get_sync(obj->dev); - err = arch_iommu->enable(obj); + err = omap2_iommu_enable(obj); return err; } @@ -167,7 +192,7 @@ static void iommu_disable(struct omap_iommu *obj) struct platform_device *pdev = to_platform_device(obj->dev); struct iommu_platform_data *pdata = pdev->dev.platform_data; - arch_iommu->disable(obj); + omap2_iommu_disable(obj); pm_runtime_put_sync(obj->dev); @@ -182,7 +207,13 @@ void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) { BUG_ON(!cr || !e); - arch_iommu->cr_to_e(cr, e); + e->da = cr->cam & MMU_CAM_VATAG_MASK; + e->pa = cr->ram & MMU_RAM_PADDR_MASK; + e->valid = cr->cam & MMU_CAM_V; + e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK; + e->endian = cr->ram & MMU_RAM_ENDIAN_MASK; + e->elsz = cr->ram & MMU_RAM_ELSZ_MASK; + e->mixed = cr->ram & MMU_RAM_MIXED; } EXPORT_SYMBOL_GPL(omap_iotlb_cr_to_e); @@ -191,31 +222,46 @@ static inline int iotlb_cr_valid(struct cr_regs *cr) if (!cr) return -EINVAL; - return arch_iommu->cr_valid(cr); -} - -static inline struct cr_regs *iotlb_alloc_cr(struct omap_iommu *obj, - struct iotlb_entry *e) -{ - if (!e) - return NULL; - - return arch_iommu->alloc_cr(obj, e); + return cr->cam & MMU_CAM_V; } static u32 iotlb_cr_to_virt(struct cr_regs *cr) { - return arch_iommu->cr_to_virt(cr); + u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; + u32 mask = get_cam_va_mask(cr->cam & page_size); + + return cr->cam & mask; } static u32 get_iopte_attr(struct iotlb_entry *e) { - return arch_iommu->get_pte_attr(e); + u32 attr; + + attr = e->mixed << 5; + attr |= e->endian; + attr |= e->elsz >> 3; + attr <<= (((e->pgsz == MMU_CAM_PGSZ_4K) || + (e->pgsz == MMU_CAM_PGSZ_64K)) ? 0 : 6); + return attr; } static u32 iommu_report_fault(struct omap_iommu *obj, u32 *da) { - return arch_iommu->fault_isr(obj, da); + u32 status, fault_addr; + + status = iommu_read_reg(obj, MMU_IRQSTATUS); + status &= MMU_IRQ_MASK; + if (!status) { + *da = 0; + return 0; + } + + fault_addr = iommu_read_reg(obj, MMU_FAULT_AD); + *da = fault_addr; + + iommu_write_reg(obj, status, MMU_IRQSTATUS); + + return status; } static void iotlb_lock_get(struct omap_iommu *obj, struct iotlb_lock *l) @@ -241,31 +287,19 @@ static void iotlb_lock_set(struct omap_iommu *obj, struct iotlb_lock *l) static void iotlb_read_cr(struct omap_iommu *obj, struct cr_regs *cr) { - arch_iommu->tlb_read_cr(obj, cr); + cr->cam = iommu_read_reg(obj, MMU_READ_CAM); + cr->ram = iommu_read_reg(obj, MMU_READ_RAM); } static void iotlb_load_cr(struct omap_iommu *obj, struct cr_regs *cr) { - arch_iommu->tlb_load_cr(obj, cr); + iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM); + iommu_write_reg(obj, cr->ram, MMU_RAM); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); iommu_write_reg(obj, 1, MMU_LD_TLB); } -/** - * iotlb_dump_cr - Dump an iommu tlb entry into buf - * @obj: target iommu - * @cr: contents of cam and ram register - * @buf: output buffer - **/ -static inline ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, - char *buf) -{ - BUG_ON(!cr || !buf); - - return arch_iommu->dump_cr(obj, cr, buf); -} - /* only used in iotlb iteration for-loop */ static struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n) { @@ -280,12 +314,36 @@ static struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n) return cr; } +#ifdef PREFETCH_IOTLB +static struct cr_regs *iotlb_alloc_cr(struct omap_iommu *obj, + struct iotlb_entry *e) +{ + struct cr_regs *cr; + + if (!e) + return NULL; + + if (e->da & ~(get_cam_va_mask(e->pgsz))) { + dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__, + e->da); + return ERR_PTR(-EINVAL); + } + + cr = kmalloc(sizeof(*cr), GFP_KERNEL); + if (!cr) + return ERR_PTR(-ENOMEM); + + cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; + cr->ram = e->pa | e->endian | e->elsz | e->mixed; + + return cr; +} + /** * load_iotlb_entry - Set an iommu tlb entry * @obj: target iommu * @e: an iommu tlb entry info **/ -#ifdef PREFETCH_IOTLB static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e) { int err = 0; @@ -416,6 +474,44 @@ static void flush_iotlb_all(struct omap_iommu *obj) #if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) +#define pr_reg(name) \ + do { \ + ssize_t bytes; \ + const char *str = "%20s: %08x\n"; \ + const int maxcol = 32; \ + bytes = snprintf(p, maxcol, str, __stringify(name), \ + iommu_read_reg(obj, MMU_##name)); \ + p += bytes; \ + len -= bytes; \ + if (len < maxcol) \ + goto out; \ + } while (0) + +static ssize_t +omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len) +{ + char *p = buf; + + pr_reg(REVISION); + pr_reg(IRQSTATUS); + pr_reg(IRQENABLE); + pr_reg(WALKING_ST); + pr_reg(CNTL); + pr_reg(FAULT_AD); + pr_reg(TTB); + pr_reg(LOCK); + pr_reg(LD_TLB); + pr_reg(CAM); + pr_reg(RAM); + pr_reg(GFLUSH); + pr_reg(FLUSH_ENTRY); + pr_reg(READ_CAM); + pr_reg(READ_RAM); + pr_reg(EMU_FAULT_AD); +out: + return p - buf; +} + ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes) { if (!obj || !buf) @@ -423,7 +519,7 @@ ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes) pm_runtime_get_sync(obj->dev); - bytes = arch_iommu->dump_ctx(obj, buf, bytes); + bytes = omap2_iommu_dump_ctx(obj, buf, bytes); pm_runtime_put_sync(obj->dev); @@ -454,6 +550,24 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) return p - crs; } +/** + * iotlb_dump_cr - Dump an iommu tlb entry into buf + * @obj: target iommu + * @cr: contents of cam and ram register + * @buf: output buffer + **/ +static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, + char *buf) +{ + char *p = buf; + + /* FIXME: Need more detail analysis of cam/ram */ + p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, + (cr->cam & MMU_CAM_P) ? 1 : 0); + + return p - buf; +} + /** * omap_dump_tlb_entries - dump cr arrays to given buffer * @obj: target iommu @@ -1008,7 +1122,6 @@ static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, int pgsz) e->da = da; e->pa = pa; e->valid = MMU_CAM_V; - /* FIXME: add OMAP1 support */ e->pgsz = pgsz; e->endian = MMU_RAM_ENDIAN_LITTLE; e->elsz = MMU_RAM_ELSZ_8; diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 45fe67d641e2..0516e0ed77d7 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -13,10 +13,6 @@ #ifndef _OMAP_IOMMU_H #define _OMAP_IOMMU_H -#if defined(CONFIG_ARCH_OMAP1) -#error "iommu for this processor not implemented yet" -#endif - struct iotlb_entry { u32 da; u32 pa; @@ -68,31 +64,6 @@ struct cr_regs { }; }; -/* architecture specific functions */ -struct iommu_functions { - int (*enable)(struct omap_iommu *obj); - void (*disable)(struct omap_iommu *obj); - void (*set_twl)(struct omap_iommu *obj, bool on); - u32 (*fault_isr)(struct omap_iommu *obj, u32 *ra); - - void (*tlb_read_cr)(struct omap_iommu *obj, struct cr_regs *cr); - void (*tlb_load_cr)(struct omap_iommu *obj, struct cr_regs *cr); - - struct cr_regs *(*alloc_cr)(struct omap_iommu *obj, - struct iotlb_entry *e); - int (*cr_valid)(struct cr_regs *cr); - u32 (*cr_to_virt)(struct cr_regs *cr); - void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e); - ssize_t (*dump_cr)(struct omap_iommu *obj, struct cr_regs *cr, - char *buf); - - u32 (*get_pte_attr)(struct iotlb_entry *e); - - void (*save_ctx)(struct omap_iommu *obj); - void (*restore_ctx)(struct omap_iommu *obj); - ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len); -}; - /** * dev_to_omap_iommu() - retrieves an omap iommu object from a user device * @dev: iommu client device @@ -130,6 +101,28 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) /* * MMU Register bit definitions */ +/* IRQSTATUS & IRQENABLE */ +#define MMU_IRQ_MULTIHITFAULT (1 << 4) +#define MMU_IRQ_TABLEWALKFAULT (1 << 3) +#define MMU_IRQ_EMUMISS (1 << 2) +#define MMU_IRQ_TRANSLATIONFAULT (1 << 1) +#define MMU_IRQ_TLBMISS (1 << 0) + +#define __MMU_IRQ_FAULT \ + (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) +#define MMU_IRQ_MASK \ + (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) +#define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) +#define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) + +/* MMU_CNTL */ +#define MMU_CNTL_SHIFT 1 +#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT) +#define MMU_CNTL_EML_TLB (1 << 3) +#define MMU_CNTL_TWL_EN (1 << 2) +#define MMU_CNTL_MMU_EN (1 << 1) + +/* CAM */ #define MMU_CAM_VATAG_SHIFT 12 #define MMU_CAM_VATAG_MASK \ ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT) @@ -141,6 +134,7 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) #define MMU_CAM_PGSZ_4K (2 << 0) #define MMU_CAM_PGSZ_16M (3 << 0) +/* RAM */ #define MMU_RAM_PADDR_SHIFT 12 #define MMU_RAM_PADDR_MASK \ ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT) @@ -162,6 +156,12 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) #define MMU_GP_REG_BUS_ERR_BACK_EN 0x1 +#define get_cam_va_mask(pgsz) \ + (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \ + ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \ + ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ + ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) + /* * utilities for super page(16MB, 1MB, 64KB and 4KB) */ @@ -197,9 +197,6 @@ omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); extern int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *)); -extern int omap_install_iommu_arch(const struct iommu_functions *ops); -extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops); - extern ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); extern size_t diff --git a/drivers/iommu/omap-iommu2.c b/drivers/iommu/omap-iommu2.c deleted file mode 100644 index ce2fff37aa61..000000000000 --- a/drivers/iommu/omap-iommu2.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * omap iommu: omap2/3 architecture specific functions - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Written by Hiroshi DOYU , - * Paul Mundt and Toshihiro Kobayashi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "omap-iommu.h" - -/* - * omap2 architecture specific register bit definitions - */ -/* IRQSTATUS & IRQENABLE */ -#define MMU_IRQ_MULTIHITFAULT (1 << 4) -#define MMU_IRQ_TABLEWALKFAULT (1 << 3) -#define MMU_IRQ_EMUMISS (1 << 2) -#define MMU_IRQ_TRANSLATIONFAULT (1 << 1) -#define MMU_IRQ_TLBMISS (1 << 0) - -#define __MMU_IRQ_FAULT \ - (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) -#define MMU_IRQ_MASK \ - (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) -#define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) -#define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) - -/* MMU_CNTL */ -#define MMU_CNTL_SHIFT 1 -#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT) -#define MMU_CNTL_EML_TLB (1 << 3) -#define MMU_CNTL_TWL_EN (1 << 2) -#define MMU_CNTL_MMU_EN (1 << 1) - -#define get_cam_va_mask(pgsz) \ - (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \ - ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \ - ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ - ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) - -static void __iommu_set_twl(struct omap_iommu *obj, bool on) -{ - u32 l = iommu_read_reg(obj, MMU_CNTL); - - if (on) - iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); - else - iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); - - l &= ~MMU_CNTL_MASK; - if (on) - l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); - else - l |= (MMU_CNTL_MMU_EN); - - iommu_write_reg(obj, l, MMU_CNTL); -} - - -static int omap2_iommu_enable(struct omap_iommu *obj) -{ - u32 l, pa; - - if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K)) - return -EINVAL; - - pa = virt_to_phys(obj->iopgd); - if (!IS_ALIGNED(pa, SZ_16K)) - return -EINVAL; - - l = iommu_read_reg(obj, MMU_REVISION); - dev_info(obj->dev, "%s: version %d.%d\n", obj->name, - (l >> 4) & 0xf, l & 0xf); - - iommu_write_reg(obj, pa, MMU_TTB); - - if (obj->has_bus_err_back) - iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG); - - __iommu_set_twl(obj, true); - - return 0; -} - -static void omap2_iommu_disable(struct omap_iommu *obj) -{ - u32 l = iommu_read_reg(obj, MMU_CNTL); - - l &= ~MMU_CNTL_MASK; - iommu_write_reg(obj, l, MMU_CNTL); - - dev_dbg(obj->dev, "%s is shutting down\n", obj->name); -} - -static void omap2_iommu_set_twl(struct omap_iommu *obj, bool on) -{ - __iommu_set_twl(obj, false); -} - -static u32 omap2_iommu_fault_isr(struct omap_iommu *obj, u32 *ra) -{ - u32 stat, da; - - stat = iommu_read_reg(obj, MMU_IRQSTATUS); - stat &= MMU_IRQ_MASK; - if (!stat) { - *ra = 0; - return 0; - } - - da = iommu_read_reg(obj, MMU_FAULT_AD); - *ra = da; - - iommu_write_reg(obj, stat, MMU_IRQSTATUS); - - return stat; -} - -static void omap2_tlb_read_cr(struct omap_iommu *obj, struct cr_regs *cr) -{ - cr->cam = iommu_read_reg(obj, MMU_READ_CAM); - cr->ram = iommu_read_reg(obj, MMU_READ_RAM); -} - -static void omap2_tlb_load_cr(struct omap_iommu *obj, struct cr_regs *cr) -{ - iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM); - iommu_write_reg(obj, cr->ram, MMU_RAM); -} - -static u32 omap2_cr_to_virt(struct cr_regs *cr) -{ - u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; - u32 mask = get_cam_va_mask(cr->cam & page_size); - - return cr->cam & mask; -} - -static struct cr_regs *omap2_alloc_cr(struct omap_iommu *obj, - struct iotlb_entry *e) -{ - struct cr_regs *cr; - - if (e->da & ~(get_cam_va_mask(e->pgsz))) { - dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__, - e->da); - return ERR_PTR(-EINVAL); - } - - cr = kmalloc(sizeof(*cr), GFP_KERNEL); - if (!cr) - return ERR_PTR(-ENOMEM); - - cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; - cr->ram = e->pa | e->endian | e->elsz | e->mixed; - - return cr; -} - -static inline int omap2_cr_valid(struct cr_regs *cr) -{ - return cr->cam & MMU_CAM_V; -} - -static u32 omap2_get_pte_attr(struct iotlb_entry *e) -{ - u32 attr; - - attr = e->mixed << 5; - attr |= e->endian; - attr |= e->elsz >> 3; - attr <<= (((e->pgsz == MMU_CAM_PGSZ_4K) || - (e->pgsz == MMU_CAM_PGSZ_64K)) ? 0 : 6); - return attr; -} - -static ssize_t -omap2_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, char *buf) -{ - char *p = buf; - - /* FIXME: Need more detail analysis of cam/ram */ - p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, - (cr->cam & MMU_CAM_P) ? 1 : 0); - - return p - buf; -} - -#define pr_reg(name) \ - do { \ - ssize_t bytes; \ - const char *str = "%20s: %08x\n"; \ - const int maxcol = 32; \ - bytes = snprintf(p, maxcol, str, __stringify(name), \ - iommu_read_reg(obj, MMU_##name)); \ - p += bytes; \ - len -= bytes; \ - if (len < maxcol) \ - goto out; \ - } while (0) - -static ssize_t -omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len) -{ - char *p = buf; - - pr_reg(REVISION); - pr_reg(IRQSTATUS); - pr_reg(IRQENABLE); - pr_reg(WALKING_ST); - pr_reg(CNTL); - pr_reg(FAULT_AD); - pr_reg(TTB); - pr_reg(LOCK); - pr_reg(LD_TLB); - pr_reg(CAM); - pr_reg(RAM); - pr_reg(GFLUSH); - pr_reg(FLUSH_ENTRY); - pr_reg(READ_CAM); - pr_reg(READ_RAM); - pr_reg(EMU_FAULT_AD); -out: - return p - buf; -} - -static void omap2_iommu_save_ctx(struct omap_iommu *obj) -{ - int i; - u32 *p = obj->ctx; - - for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { - p[i] = iommu_read_reg(obj, i * sizeof(u32)); - dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); - } -} - -static void omap2_iommu_restore_ctx(struct omap_iommu *obj) -{ - int i; - u32 *p = obj->ctx; - - for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) { - iommu_write_reg(obj, p[i], i * sizeof(u32)); - dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]); - } -} - -static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) -{ - e->da = cr->cam & MMU_CAM_VATAG_MASK; - e->pa = cr->ram & MMU_RAM_PADDR_MASK; - e->valid = cr->cam & MMU_CAM_V; - e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK; - e->endian = cr->ram & MMU_RAM_ENDIAN_MASK; - e->elsz = cr->ram & MMU_RAM_ELSZ_MASK; - e->mixed = cr->ram & MMU_RAM_MIXED; -} - -static const struct iommu_functions omap2_iommu_ops = { - .enable = omap2_iommu_enable, - .disable = omap2_iommu_disable, - .set_twl = omap2_iommu_set_twl, - .fault_isr = omap2_iommu_fault_isr, - - .tlb_read_cr = omap2_tlb_read_cr, - .tlb_load_cr = omap2_tlb_load_cr, - - .cr_to_e = omap2_cr_to_e, - .cr_to_virt = omap2_cr_to_virt, - .alloc_cr = omap2_alloc_cr, - .cr_valid = omap2_cr_valid, - .dump_cr = omap2_dump_cr, - - .get_pte_attr = omap2_get_pte_attr, - - .save_ctx = omap2_iommu_save_ctx, - .restore_ctx = omap2_iommu_restore_ctx, - .dump_ctx = omap2_iommu_dump_ctx, -}; - -static int __init omap2_iommu_init(void) -{ - return omap_install_iommu_arch(&omap2_iommu_ops); -} -module_init(omap2_iommu_init); - -static void __exit omap2_iommu_exit(void) -{ - omap_uninstall_iommu_arch(&omap2_iommu_ops); -} -module_exit(omap2_iommu_exit); - -MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi"); -MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions"); -MODULE_LICENSE("GPL v2"); -- GitLab From 68570a744631ab4f2d378c9d7ef794e66e623a81 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:28 -0500 Subject: [PATCH 1082/9457] iommu/omap: Fix the permissions on nr_tlb_entries The permissions on the debugfs entry "nr_tlb_entries" should have been octal, not decimal, so fix it. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 0fb92aa42c19..a520438182db 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -256,7 +256,7 @@ static int iommu_debug_register(struct device *dev, void *data) goto nomem; parent = d; - d = debugfs_create_u8("nr_tlb_entries", 400, parent, + d = debugfs_create_u8("nr_tlb_entries", 0400, parent, (u8 *)&obj->nr_tlb_entries); if (!d) goto nomem; -- GitLab From 3ca5db072c770c950a816c46ef2330d9e0ced8a7 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:29 -0500 Subject: [PATCH 1083/9457] iommu/omap: Make pagetable debugfs entry read-only Remove the writeability on the 'pagetable' debugfs entry, so that the mapping/unmapping into an OMAP IOMMU is only limited to actual client devices/drivers at kernel-level. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 48 ++------------------------------ 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index a520438182db..28de657e38c0 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -24,8 +24,6 @@ #include "omap-iopgtable.h" #include "omap-iommu.h" -#define MAXCOLUMN 100 /* for short messages */ - static DEFINE_MUTEX(iommu_debug_lock); static struct dentry *iommu_debug_root; @@ -82,39 +80,6 @@ static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, return bytes; } -static ssize_t debug_write_pagetable(struct file *file, - const char __user *userbuf, size_t count, loff_t *ppos) -{ - struct iotlb_entry e; - struct cr_regs cr; - int err; - struct device *dev = file->private_data; - struct omap_iommu *obj = dev_to_omap_iommu(dev); - char buf[MAXCOLUMN], *p = buf; - - count = min(count, sizeof(buf)); - - mutex_lock(&iommu_debug_lock); - if (copy_from_user(p, userbuf, count)) { - mutex_unlock(&iommu_debug_lock); - return -EFAULT; - } - - sscanf(p, "%x %x", &cr.cam, &cr.ram); - if (!cr.cam || !cr.ram) { - mutex_unlock(&iommu_debug_lock); - return -EINVAL; - } - - omap_iotlb_cr_to_e(&cr, &e); - err = omap_iopgtable_store_entry(obj, &e); - if (err) - dev_err(obj->dev, "%s: fail to store cr\n", __func__); - - mutex_unlock(&iommu_debug_lock); - return count; -} - #define dump_ioptable_entry_one(lv, da, val) \ ({ \ int __err = 0; \ @@ -202,14 +167,6 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, return bytes; } -#define DEBUG_FOPS(name) \ - static const struct file_operations debug_##name##_fops = { \ - .open = simple_open, \ - .read = debug_read_##name, \ - .write = debug_write_##name, \ - .llseek = generic_file_llseek, \ - }; - #define DEBUG_FOPS_RO(name) \ static const struct file_operations debug_##name##_fops = { \ .open = simple_open, \ @@ -219,7 +176,7 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, DEBUG_FOPS_RO(regs); DEBUG_FOPS_RO(tlb); -DEBUG_FOPS(pagetable); +DEBUG_FOPS_RO(pagetable); #define __DEBUG_ADD_FILE(attr, mode) \ { \ @@ -230,7 +187,6 @@ DEBUG_FOPS(pagetable); return -ENOMEM; \ } -#define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 0600) #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400) static int iommu_debug_register(struct device *dev, void *data) @@ -263,7 +219,7 @@ static int iommu_debug_register(struct device *dev, void *data) DEBUG_ADD_FILE_RO(regs); DEBUG_ADD_FILE_RO(tlb); - DEBUG_ADD_FILE(pagetable); + DEBUG_ADD_FILE_RO(pagetable); return 0; -- GitLab From 61c753526dc3ef91a0601e0bf2bdeeb6c415e747 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:30 -0500 Subject: [PATCH 1084/9457] iommu/omap: Integrate omap-iommu-debug into omap-iommu The debugfs support for OMAP IOMMU is currently implemented as a module, warranting certain OMAP-specific IOMMU API to be exported. The OMAP IOMMU, when enabled, can only be built-in into the kernel, so integrate the OMAP IOMMU debug module into the OMAP IOMMU driver. This helps in eliminating the need to export most of the current OMAP IOMMU API. The following are the main changes: - The debugfs directory and entry creation logic is reversed, the calls are invoked by the OMAP IOMMU driver now. - The current iffy circular logic of adding IOMMU archdata to the IOMMU devices itself to get a pointer to the omap_iommu object in the debugfs support code is replaced by directly using the omap_iommu structure while creating the debugfs entries. - The debugfs root directory is renamed from the generic name "iommu" to a specific name "omap_iommu". - Unneeded headers have also been cleaned up while at this. - There will no longer be a omap-iommu-debug.ko module after this patch. - The OMAP_IOMMU_DEBUG Kconfig option is converted to boolean only, the OMAP IOMMU debugfs support is built alongside the OMAP IOMMU driver only when this option is enabled. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 12 ++-- drivers/iommu/omap-iommu-debug.c | 100 +++++++++---------------------- drivers/iommu/omap-iommu.c | 11 +++- drivers/iommu/omap-iommu.h | 15 +++++ 4 files changed, 58 insertions(+), 80 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index dd5112265cc9..1d54996b6a70 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -144,13 +144,13 @@ config OMAP_IOMMU select IOMMU_API config OMAP_IOMMU_DEBUG - tristate "Export OMAP IOMMU internals in DebugFS" - depends on OMAP_IOMMU && DEBUG_FS - help - Select this to see extensive information about - the internal state of OMAP IOMMU in debugfs. + bool "Export OMAP IOMMU internals in DebugFS" + depends on OMAP_IOMMU && DEBUG_FS + ---help--- + Select this to see extensive information about + the internal state of OMAP IOMMU in debugfs. - Say N unless you know you need this. + Say N unless you know you need this. config TEGRA_IOMMU_GART bool "Tegra GART IOMMU Support" diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 28de657e38c0..4813d3a71a00 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -10,15 +10,11 @@ * published by the Free Software Foundation. */ -#include #include -#include #include #include #include -#include #include -#include #include #include "omap-iopgtable.h" @@ -31,8 +27,7 @@ static struct dentry *iommu_debug_root; static ssize_t debug_read_regs(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - struct device *dev = file->private_data; - struct omap_iommu *obj = dev_to_omap_iommu(dev); + struct omap_iommu *obj = file->private_data; char *p, *buf; ssize_t bytes; @@ -55,8 +50,7 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf, static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - struct device *dev = file->private_data; - struct omap_iommu *obj = dev_to_omap_iommu(dev); + struct omap_iommu *obj = file->private_data; char *p, *buf; ssize_t bytes, rest; @@ -141,8 +135,7 @@ static ssize_t dump_ioptable(struct omap_iommu *obj, char *buf, ssize_t len) static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - struct device *dev = file->private_data; - struct omap_iommu *obj = dev_to_omap_iommu(dev); + struct omap_iommu *obj = file->private_data; char *p, *buf; size_t bytes; @@ -181,93 +174,56 @@ DEBUG_FOPS_RO(pagetable); #define __DEBUG_ADD_FILE(attr, mode) \ { \ struct dentry *dent; \ - dent = debugfs_create_file(#attr, mode, parent, \ - dev, &debug_##attr##_fops); \ + dent = debugfs_create_file(#attr, mode, obj->debug_dir, \ + obj, &debug_##attr##_fops); \ if (!dent) \ - return -ENOMEM; \ + goto err; \ } #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400) -static int iommu_debug_register(struct device *dev, void *data) +void omap_iommu_debugfs_add(struct omap_iommu *obj) { - struct platform_device *pdev = to_platform_device(dev); - struct omap_iommu *obj = platform_get_drvdata(pdev); - struct omap_iommu_arch_data *arch_data; - struct dentry *d, *parent; - - if (!obj || !obj->dev) - return -EINVAL; - - arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL); - if (!arch_data) - return -ENOMEM; - - arch_data->iommu_dev = obj; + struct dentry *d; - dev->archdata.iommu = arch_data; + if (!iommu_debug_root) + return; - d = debugfs_create_dir(obj->name, iommu_debug_root); - if (!d) - goto nomem; - parent = d; + obj->debug_dir = debugfs_create_dir(obj->name, iommu_debug_root); + if (!obj->debug_dir) + return; - d = debugfs_create_u8("nr_tlb_entries", 0400, parent, + d = debugfs_create_u8("nr_tlb_entries", 0400, obj->debug_dir, (u8 *)&obj->nr_tlb_entries); if (!d) - goto nomem; + return; DEBUG_ADD_FILE_RO(regs); DEBUG_ADD_FILE_RO(tlb); DEBUG_ADD_FILE_RO(pagetable); - return 0; + return; -nomem: - kfree(arch_data); - return -ENOMEM; +err: + debugfs_remove_recursive(obj->debug_dir); } -static int iommu_debug_unregister(struct device *dev, void *data) +void omap_iommu_debugfs_remove(struct omap_iommu *obj) { - if (!dev->archdata.iommu) - return 0; - - kfree(dev->archdata.iommu); - - dev->archdata.iommu = NULL; + if (!obj->debug_dir) + return; - return 0; + debugfs_remove_recursive(obj->debug_dir); } -static int __init iommu_debug_init(void) +void __init omap_iommu_debugfs_init(void) { - struct dentry *d; - int err; - - d = debugfs_create_dir("iommu", NULL); - if (!d) - return -ENOMEM; - iommu_debug_root = d; - - err = omap_foreach_iommu_device(d, iommu_debug_register); - if (err) - goto err_out; - return 0; - -err_out: - debugfs_remove_recursive(iommu_debug_root); - return err; + iommu_debug_root = debugfs_create_dir("omap_iommu", NULL); + if (!iommu_debug_root) + pr_err("can't create debugfs dir\n"); } -module_init(iommu_debug_init) -static void __exit iommu_debugfs_exit(void) +void __exit omap_iommu_debugfs_exit(void) { - debugfs_remove_recursive(iommu_debug_root); - omap_foreach_iommu_device(NULL, iommu_debug_unregister); + debugfs_remove(iommu_debug_root); } -module_exit(iommu_debugfs_exit) - -MODULE_DESCRIPTION("omap iommu: debugfs interface"); -MODULE_AUTHOR("Hiroshi DOYU "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 91262fa2a351..b92b6fc33690 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -472,7 +472,7 @@ static void flush_iotlb_all(struct omap_iommu *obj) pm_runtime_put_sync(obj->dev); } -#if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) +#ifdef CONFIG_OMAP_IOMMU_DEBUG #define pr_reg(name) \ do { \ @@ -602,7 +602,7 @@ int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *)) } EXPORT_SYMBOL_GPL(omap_foreach_iommu_device); -#endif /* CONFIG_OMAP_IOMMU_DEBUG_MODULE */ +#endif /* CONFIG_OMAP_IOMMU_DEBUG */ /* * H/W pagetable operations @@ -1077,6 +1077,8 @@ static int omap_iommu_probe(struct platform_device *pdev) pm_runtime_irq_safe(obj->dev); pm_runtime_enable(obj->dev); + omap_iommu_debugfs_add(obj); + dev_info(&pdev->dev, "%s registered\n", obj->name); return 0; } @@ -1086,6 +1088,7 @@ static int omap_iommu_remove(struct platform_device *pdev) struct omap_iommu *obj = platform_get_drvdata(pdev); iopgtable_clear_entry_all(obj); + omap_iommu_debugfs_remove(obj); pm_runtime_disable(obj->dev); @@ -1403,6 +1406,8 @@ static int __init omap_iommu_init(void) bus_set_iommu(&platform_bus_type, &omap_iommu_ops); + omap_iommu_debugfs_init(); + return platform_driver_register(&omap_iommu_driver); } /* must be ready before omap3isp is probed */ @@ -1413,6 +1418,8 @@ static void __exit omap_iommu_exit(void) kmem_cache_destroy(iopte_cachep); platform_driver_unregister(&omap_iommu_driver); + + omap_iommu_debugfs_exit(); } module_exit(omap_iommu_exit); diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 0516e0ed77d7..478377924e8f 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -30,6 +30,7 @@ struct omap_iommu { void __iomem *regbase; struct device *dev; struct iommu_domain *domain; + struct dentry *debug_dir; spinlock_t iommu_lock; /* global for this whole object */ @@ -197,11 +198,25 @@ omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); extern int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *)); +#ifdef CONFIG_OMAP_IOMMU_DEBUG extern ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); extern size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); +void omap_iommu_debugfs_init(void); +void omap_iommu_debugfs_exit(void); + +void omap_iommu_debugfs_add(struct omap_iommu *obj); +void omap_iommu_debugfs_remove(struct omap_iommu *obj); +#else +static inline void omap_iommu_debugfs_init(void) { } +static inline void omap_iommu_debugfs_exit(void) { } + +static inline void omap_iommu_debugfs_add(struct omap_iommu *obj) { } +static inline void omap_iommu_debugfs_remove(struct omap_iommu *obj) { } +#endif + /* * register accessors */ -- GitLab From c55caec124512d8192ff21eb3c08df55c94f2db3 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:31 -0500 Subject: [PATCH 1085/9457] iommu/omap: Remove couple of unused exported functions The exported functions omap_foreach_iommu_device() and omap_iotlb_cr_to_e() have been deleted, as they are no longer needed. The function omap_foreach_iommu_device() is not required after the consolidation of the OMAP IOMMU debug module, and the function omap_iotlb_cr_to_e() is not required after making the debugfs entry 'pagetable' read-only. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 21 --------------------- drivers/iommu/omap-iommu.h | 5 ----- 2 files changed, 26 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index b92b6fc33690..91711126cb25 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -203,20 +203,6 @@ static void iommu_disable(struct omap_iommu *obj) /* * TLB operations */ -void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e) -{ - BUG_ON(!cr || !e); - - e->da = cr->cam & MMU_CAM_VATAG_MASK; - e->pa = cr->ram & MMU_RAM_PADDR_MASK; - e->valid = cr->cam & MMU_CAM_V; - e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK; - e->endian = cr->ram & MMU_RAM_ENDIAN_MASK; - e->elsz = cr->ram & MMU_RAM_ELSZ_MASK; - e->mixed = cr->ram & MMU_RAM_MIXED; -} -EXPORT_SYMBOL_GPL(omap_iotlb_cr_to_e); - static inline int iotlb_cr_valid(struct cr_regs *cr) { if (!cr) @@ -595,13 +581,6 @@ size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t bytes) } EXPORT_SYMBOL_GPL(omap_dump_tlb_entries); -int omap_foreach_iommu_device(void *data, int (*fn)(struct device *, void *)) -{ - return driver_for_each_device(&omap_iommu_driver.driver, - NULL, data, fn); -} -EXPORT_SYMBOL_GPL(omap_foreach_iommu_device); - #endif /* CONFIG_OMAP_IOMMU_DEBUG */ /* diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 478377924e8f..b18ceccd4845 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -190,14 +190,9 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) /* * global functions */ -extern void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); - extern int omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); -extern int omap_foreach_iommu_device(void *data, - int (*fn)(struct device *, void *)); - #ifdef CONFIG_OMAP_IOMMU_DEBUG extern ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); -- GitLab From 4899a5636d535ba573a7e52b5ad7be1f886d40a3 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:32 -0500 Subject: [PATCH 1086/9457] iommu/omap: Do not export unneeded functions The following functions were exported previously for usage by the OMAP IOMMU debug module: omap_iommu_dump_ctx() omap_dump_tlb_entries() omap_iopgtable_store_entry() These functions need not be exported anymore as the OMAP IOMMU debugfs code is integrated with the OMAP IOMMU driver, and there won't be external users for these functions. So, remove the EXPORT_SYMBOL_GPL on these. The omap_iopgtable_store_entry() is also made internal only, after making the 'pagetable' debugfs entry read-only. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 6 ++---- drivers/iommu/omap-iommu.h | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 91711126cb25..3dcaef068382 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -511,7 +511,6 @@ ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes) return bytes; } -EXPORT_SYMBOL_GPL(omap_iommu_dump_ctx); static int __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) @@ -579,7 +578,6 @@ size_t omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t bytes) return p - buf; } -EXPORT_SYMBOL_GPL(omap_dump_tlb_entries); #endif /* CONFIG_OMAP_IOMMU_DEBUG */ @@ -764,7 +762,8 @@ iopgtable_store_entry_core(struct omap_iommu *obj, struct iotlb_entry *e) * @obj: target iommu * @e: an iommu tlb entry info **/ -int omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e) +static int +omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e) { int err; @@ -774,7 +773,6 @@ int omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e) prefetch_iotlb_entry(obj, e); return err; } -EXPORT_SYMBOL_GPL(omap_iopgtable_store_entry); /** * iopgtable_lookup_entry - Lookup an iommu pte entry diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index b18ceccd4845..d736630df3c8 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -190,9 +190,6 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev) /* * global functions */ -extern int -omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); - #ifdef CONFIG_OMAP_IOMMU_DEBUG extern ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); -- GitLab From f24d9ad3fafd7c4ee47ec75947657d768873b6e4 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:33 -0500 Subject: [PATCH 1087/9457] iommu/omap: Reset the domain field upon detaching The .domain field in omap_iommu struct is set properly when the OMAP IOMMU device is attached to, but is never reset properly on detach. Reset this properly so that the OMAP IOMMU debugfs logic can depend on this field before allowing the debugfs operations. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 3dcaef068382..2ba321921f81 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1206,6 +1206,7 @@ static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain, omap_domain->iommu_dev = arch_data->iommu_dev = NULL; omap_domain->dev = NULL; + oiommu->domain = NULL; } static void omap_iommu_detach_dev(struct iommu_domain *domain, -- GitLab From c5cf5c5377fbd0a1ff2a09ad1f0c7e261aabc567 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:34 -0500 Subject: [PATCH 1088/9457] iommu/omap: Fix bus error on debugfs access of unattached IOMMU Any debugfs access on an OMAP IOMMU that is not enabled (done during attach) results in a bus error due to access of registers without the clock or the reset enabled for the respective IOMMU. So, add a check to make sure the IOMMU is enabled/attached by a client device. This gracefully prints a "Operation not permitted" trace when the corresponding IOMMU is not enabled. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 4813d3a71a00..41b09a1d78ea 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -24,6 +24,11 @@ static DEFINE_MUTEX(iommu_debug_lock); static struct dentry *iommu_debug_root; +static inline bool is_omap_iommu_detached(struct omap_iommu *obj) +{ + return !obj->domain; +} + static ssize_t debug_read_regs(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -31,6 +36,9 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf, char *p, *buf; ssize_t bytes; + if (is_omap_iommu_detached(obj)) + return -EPERM; + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -54,6 +62,9 @@ static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, char *p, *buf; ssize_t bytes, rest; + if (is_omap_iommu_detached(obj)) + return -EPERM; + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -139,6 +150,9 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, char *p, *buf; size_t bytes; + if (is_omap_iommu_detached(obj)) + return -EPERM; + buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; -- GitLab From 9c83e9f384f5d1513e42935af43c13a601aad842 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Wed, 22 Oct 2014 17:22:35 -0500 Subject: [PATCH 1089/9457] iommu/omap: Switch pagetable debugfs entry to use seq_file The debugfs entry 'pagetable' that shows the page table entry (PTE) data currently outputs only data that can be fit into a page. Switch the entry to use the seq_file interface so that it can show all the valid page table entries. The patch also corrected the output for L2 entries, and prints the proper L2 PTE instead of the previous L1 page descriptor pointer. Signed-off-by: Suman Anna Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 81 +++++++++++--------------------- 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 41b09a1d78ea..f3d20a2039d2 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -85,95 +85,70 @@ static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, return bytes; } -#define dump_ioptable_entry_one(lv, da, val) \ - ({ \ - int __err = 0; \ - ssize_t bytes; \ - const int maxcol = 22; \ - const char *str = "%d: %08x %08x\n"; \ - bytes = snprintf(p, maxcol, str, lv, da, val); \ - p += bytes; \ - len -= bytes; \ - if (len < maxcol) \ - __err = -ENOMEM; \ - __err; \ - }) - -static ssize_t dump_ioptable(struct omap_iommu *obj, char *buf, ssize_t len) +static void dump_ioptable(struct seq_file *s) { - int i; - u32 *iopgd; - char *p = buf; + int i, j; + u32 da; + u32 *iopgd, *iopte; + struct omap_iommu *obj = s->private; spin_lock(&obj->page_table_lock); iopgd = iopgd_offset(obj, 0); for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) { - int j, err; - u32 *iopte; - u32 da; - if (!*iopgd) continue; if (!(*iopgd & IOPGD_TABLE)) { da = i << IOPGD_SHIFT; - - err = dump_ioptable_entry_one(1, da, *iopgd); - if (err) - goto out; + seq_printf(s, "1: 0x%08x 0x%08x\n", da, *iopgd); continue; } iopte = iopte_offset(iopgd, 0); - for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) { if (!*iopte) continue; da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT); - err = dump_ioptable_entry_one(2, da, *iopgd); - if (err) - goto out; + seq_printf(s, "2: 0x%08x 0x%08x\n", da, *iopte); } } -out: - spin_unlock(&obj->page_table_lock); - return p - buf; + spin_unlock(&obj->page_table_lock); } -static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) +static int debug_read_pagetable(struct seq_file *s, void *data) { - struct omap_iommu *obj = file->private_data; - char *p, *buf; - size_t bytes; + struct omap_iommu *obj = s->private; if (is_omap_iommu_detached(obj)) return -EPERM; - buf = (char *)__get_free_page(GFP_KERNEL); - if (!buf) - return -ENOMEM; - p = buf; - - p += sprintf(p, "L: %8s %8s\n", "da:", "pa:"); - p += sprintf(p, "-----------------------------------------\n"); - mutex_lock(&iommu_debug_lock); - bytes = PAGE_SIZE - (p - buf); - p += dump_ioptable(obj, p, bytes); - - bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); + seq_printf(s, "L: %8s %8s\n", "da:", "pte:"); + seq_puts(s, "--------------------------\n"); + dump_ioptable(s); mutex_unlock(&iommu_debug_lock); - free_page((unsigned long)buf); - return bytes; + return 0; } +#define DEBUG_SEQ_FOPS_RO(name) \ + static int debug_open_##name(struct inode *inode, struct file *file) \ + { \ + return single_open(file, debug_read_##name, inode->i_private); \ + } \ + \ + static const struct file_operations debug_##name##_fops = { \ + .open = debug_open_##name, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + } + #define DEBUG_FOPS_RO(name) \ static const struct file_operations debug_##name##_fops = { \ .open = simple_open, \ @@ -183,7 +158,7 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, DEBUG_FOPS_RO(regs); DEBUG_FOPS_RO(tlb); -DEBUG_FOPS_RO(pagetable); +DEBUG_SEQ_FOPS_RO(pagetable); #define __DEBUG_ADD_FILE(attr, mode) \ { \ -- GitLab From c72acf69e2c0d884023296d0cceb16f3e75c09d9 Mon Sep 17 00:00:00 2001 From: SF Markus Elfring Date: Wed, 22 Oct 2014 20:00:17 +0200 Subject: [PATCH 1090/9457] iommu/msm: Deletion of unnecessary checks before clk_disable() A semantic patch approach was proposed with the subject "[PATCH with Coccinelle?] Deletion of unnecessary checks before specific function calls" on 2014-03-05. https://lkml.org/lkml/2014/3/5/344 http://article.gmane.org/gmane.comp.version-control.coccinelle/3513/ This patch pattern application was repeated with the help of the software "Coccinelle 1.0.0-rc22" on the source files for Linux 3.17.1. An extract of the automatically generated update suggestions is shown here. It was determined that the affected source code places call functions which perform input parameter validation already. It is therefore not needed that a similar safety check is repeated at the call site. Signed-off-by: Markus Elfring Signed-off-by: Joerg Roedel --- drivers/iommu/msm_iommu.c | 3 +-- drivers/iommu/msm_iommu_dev.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 6e3dcc289d59..3e4d888bef2b 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -73,8 +73,7 @@ static int __enable_clocks(struct msm_iommu_drvdata *drvdata) static void __disable_clocks(struct msm_iommu_drvdata *drvdata) { - if (drvdata->clk) - clk_disable(drvdata->clk); + clk_disable(drvdata->clk); clk_disable(drvdata->pclk); } diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c index 61def7cb5263..9574d217227c 100644 --- a/drivers/iommu/msm_iommu_dev.c +++ b/drivers/iommu/msm_iommu_dev.c @@ -224,8 +224,7 @@ static int msm_iommu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, drvdata); - if (iommu_clk) - clk_disable(iommu_clk); + clk_disable(iommu_clk); clk_disable(iommu_pclk); @@ -323,8 +322,7 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev) SET_NSCFG(drvdata->base, mid, 3); } - if (drvdata->clk) - clk_disable(drvdata->clk); + clk_disable(drvdata->clk); clk_disable(drvdata->pclk); dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num); -- GitLab From 332b122d39c9cbff8b799007a825d94b2e7c12f2 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Tue, 7 Oct 2014 15:51:55 -0500 Subject: [PATCH 1091/9457] eCryptfs: Force RO mount when encrypted view is enabled The ecryptfs_encrypted_view mount option greatly changes the functionality of an eCryptfs mount. Instead of encrypting and decrypting lower files, it provides a unified view of the encrypted files in the lower filesystem. The presence of the ecryptfs_encrypted_view mount option is intended to force a read-only mount and modifying files is not supported when the feature is in use. See the following commit for more information: e77a56d [PATCH] eCryptfs: Encrypted passthrough This patch forces the mount to be read-only when the ecryptfs_encrypted_view mount option is specified by setting the MS_RDONLY flag on the superblock. Additionally, this patch removes some broken logic in ecryptfs_open() that attempted to prevent modifications of files when the encrypted view feature was in use. The check in ecryptfs_open() was not sufficient to prevent file modifications using system calls that do not operate on a file descriptor. Signed-off-by: Tyler Hicks Reported-by: Priya Bansal Cc: stable@vger.kernel.org # v2.6.21+: e77a56d [PATCH] eCryptfs: Encrypted passthrough --- fs/ecryptfs/file.c | 12 ------------ fs/ecryptfs/main.c | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index f5bce9096555..54742f9a67a8 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -190,23 +190,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file) { int rc = 0; struct ecryptfs_crypt_stat *crypt_stat = NULL; - struct ecryptfs_mount_crypt_stat *mount_crypt_stat; struct dentry *ecryptfs_dentry = file->f_path.dentry; /* Private value of ecryptfs_dentry allocated in * ecryptfs_lookup() */ struct ecryptfs_file_info *file_info; - mount_crypt_stat = &ecryptfs_superblock_to_private( - ecryptfs_dentry->d_sb)->mount_crypt_stat; - if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) - && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR) - || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC) - || (file->f_flags & O_APPEND))) { - printk(KERN_WARNING "Mount has encrypted view enabled; " - "files may only be read\n"); - rc = -EPERM; - goto out; - } /* Released in ecryptfs_release or end of function if failure */ file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); ecryptfs_set_file_private(file, file_info); diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 1b119d3bf924..34eb8433d93f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -493,6 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags { struct super_block *s; struct ecryptfs_sb_info *sbi; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; struct ecryptfs_dentry_info *root_info; const char *err = "Getting sb failed"; struct inode *inode; @@ -511,6 +512,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags err = "Error parsing options"; goto out; } + mount_crypt_stat = &sbi->mount_crypt_stat; s = sget(fs_type, NULL, set_anon_super, flags, NULL); if (IS_ERR(s)) { @@ -557,11 +559,19 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags /** * Set the POSIX ACL flag based on whether they're enabled in the lower - * mount. Force a read-only eCryptfs mount if the lower mount is ro. - * Allow a ro eCryptfs mount even when the lower mount is rw. + * mount. */ s->s_flags = flags & ~MS_POSIXACL; - s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); + s->s_flags |= path.dentry->d_sb->s_flags & MS_POSIXACL; + + /** + * Force a read-only eCryptfs mount when: + * 1) The lower mount is ro + * 2) The ecryptfs_encrypted_view mount option is specified + */ + if (path.dentry->d_sb->s_flags & MS_RDONLY || + mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) + s->s_flags |= MS_RDONLY; s->s_maxbytes = path.dentry->d_sb->s_maxbytes; s->s_blocksize = path.dentry->d_sb->s_blocksize; -- GitLab From a428249da9f9ef169d09d1a637d19a27991122da Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 20 Oct 2014 14:14:37 +0200 Subject: [PATCH 1092/9457] ath10k: re-disable interrupts after target init If MSI isn't configured device ROM program expects legacy interrupts to be enabled before it can fully boot. Don't forget to disable legacy interrupts after that. While at it re-use the legacy irq enabling helper instead of calling ath10k_pci_write32(). Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 86f734e74103..9d700d1530d2 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2279,14 +2279,13 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) if (ar_pci->num_msi_intrs == 0) /* Fix potential race by repeating CORE_BASE writes */ - ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + - PCIE_INTR_ENABLE_ADDRESS, - PCIE_INTR_FIRMWARE_MASK | - PCIE_INTR_CE_MASK_ALL); + ath10k_pci_enable_legacy_irq(ar); mdelay(10); } while (time_before(jiffies, timeout)); + ath10k_pci_disable_and_clear_legacy_irq(ar); + if (val == 0xffffffff) { ath10k_err(ar, "failed to read device register, device is gone\n"); return -EIO; -- GitLab From 7c0f0e3c9797e5a08d15da68812f24eadaf9e82b Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 20 Oct 2014 14:14:38 +0200 Subject: [PATCH 1093/9457] ath10k: mask/unmask msi fw irq This was the final missing bit to making sure the device doesn't assert interrupts to host. This should fix possible race when target crashes during driver teardown. This also removes an early warm reset workaround during pci probing. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/hw.h | 1 + drivers/net/wireless/ath/ath10k/pci.c | 53 ++++++++++++++++----------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index ef09fe8cb4b2..392c2501d0a1 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -291,6 +291,7 @@ struct ath10k_pktlog_hdr { #define SI_RX_DATA1_OFFSET 0x00000014 #define CORE_CTRL_CPU_INTR_MASK 0x00002000 +#define CORE_CTRL_PCIE_REG_31_MASK 0x00000800 #define CORE_CTRL_ADDRESS 0x0000 #define PCIE_INTR_ENABLE_ADDRESS 0x0008 #define PCIE_INTR_CAUSE_ADDRESS 0x000c diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 9d700d1530d2..243099d62ee9 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1143,14 +1143,37 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, &dl_is_polled); } -static void ath10k_pci_irq_disable(struct ath10k *ar) +static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - int i; + u32 val; + + val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS); + val &= ~CORE_CTRL_PCIE_REG_31_MASK; + + ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val); +} + +static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar) +{ + u32 val; + + val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS); + val |= CORE_CTRL_PCIE_REG_31_MASK; + + ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val); +} +static void ath10k_pci_irq_disable(struct ath10k *ar) +{ ath10k_ce_disable_interrupts(ar); ath10k_pci_disable_and_clear_legacy_irq(ar); - /* FIXME: How to mask all MSI interrupts? */ + ath10k_pci_irq_msi_fw_mask(ar); +} + +static void ath10k_pci_irq_sync(struct ath10k *ar) +{ + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + int i; for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) synchronize_irq(ar_pci->pdev->irq + i); @@ -1160,7 +1183,7 @@ static void ath10k_pci_irq_enable(struct ath10k *ar) { ath10k_ce_enable_interrupts(ar); ath10k_pci_enable_legacy_irq(ar); - /* FIXME: How to unmask all MSI interrupts? */ + ath10k_pci_irq_msi_fw_unmask(ar); } static int ath10k_pci_hif_start(struct ath10k *ar) @@ -1288,6 +1311,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) ath10k_pci_warm_reset(ar); ath10k_pci_irq_disable(ar); + ath10k_pci_irq_sync(ar); ath10k_pci_flush(ar); } @@ -2285,6 +2309,7 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) } while (time_before(jiffies, timeout)); ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_irq_msi_fw_mask(ar); if (val == 0xffffffff) { ath10k_err(ar, "failed to read device register, device is gone\n"); @@ -2478,20 +2503,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, } ath10k_pci_ce_deinit(ar); - - ret = ath10k_ce_disable_interrupts(ar); - if (ret) { - ath10k_err(ar, "failed to disable copy engine interrupts: %d\n", - ret); - goto err_free_ce; - } - - /* Workaround: There's no known way to mask all possible interrupts via - * device CSR. The only way to make sure device doesn't assert - * interrupts is to reset it. Interrupts are then disabled on host - * after handlers are registered. - */ - ath10k_pci_warm_reset(ar); + ath10k_pci_irq_disable(ar); ret = ath10k_pci_init_irq(ar); if (ret) { @@ -2509,9 +2521,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_deinit_irq; } - /* This shouldn't race as the device has been reset above. */ - ath10k_pci_irq_disable(ar); - ret = ath10k_core_register(ar, chip_id); if (ret) { ath10k_err(ar, "failed to register driver core: %d\n", ret); -- GitLab From 84cbf3a7592879810f80cece6c7f736f099ab163 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 20 Oct 2014 14:14:39 +0200 Subject: [PATCH 1094/9457] ath10k: split ce pipe init/alloc further Calling init to reinit ce pipe state would also re-set all static structure links and setting (which don't change over driver lifecycle). Make it so alloc links structures and initializes static data and init part to setup state variables and clear stuff. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 56 +++++++++++----------- drivers/net/wireless/ath/ath10k/ce.h | 8 ++-- drivers/net/wireless/ath/ath10k/pci.c | 67 +++++++++++++-------------- 3 files changed, 62 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 4745ef2a6f01..9b89ac133946 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -1023,37 +1023,10 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, * initialized by software/firmware. */ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, - const struct ce_attr *attr, - void (*send_cb)(struct ath10k_ce_pipe *), - void (*recv_cb)(struct ath10k_ce_pipe *)) + const struct ce_attr *attr) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; - /* - * Make sure there's enough CE ringbuffer entries for HTT TX to avoid - * additional TX locking checks. - * - * For the lack of a better place do the check here. - */ - BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC > - (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); - BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > - (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); - - spin_lock_bh(&ar_pci->ce_lock); - ce_state->ar = ar; - ce_state->id = ce_id; - ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); - ce_state->attr_flags = attr->flags; - ce_state->src_sz_max = attr->src_sz_max; - if (attr->src_nentries) - ce_state->send_cb = send_cb; - if (attr->dest_nentries) - ce_state->recv_cb = recv_cb; - spin_unlock_bh(&ar_pci->ce_lock); - if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, attr); if (ret) { @@ -1101,12 +1074,37 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) } int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, - const struct ce_attr *attr) + const struct ce_attr *attr, + void (*send_cb)(struct ath10k_ce_pipe *), + void (*recv_cb)(struct ath10k_ce_pipe *)) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; + /* + * Make sure there's enough CE ringbuffer entries for HTT TX to avoid + * additional TX locking checks. + * + * For the lack of a better place do the check here. + */ + BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC > + (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); + BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > + (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); + + ce_state->ar = ar; + ce_state->id = ce_id; + ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); + ce_state->attr_flags = attr->flags; + ce_state->src_sz_max = attr->src_sz_max; + + if (attr->src_nentries) + ce_state->send_cb = send_cb; + + if (attr->dest_nentries) + ce_state->recv_cb = recv_cb; + if (attr->src_nentries) { ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); if (IS_ERR(ce_state->src_ring)) { diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 608262ab964e..617a151e8ce4 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -201,12 +201,12 @@ int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, /*==================CE Engine Initialization=======================*/ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, - const struct ce_attr *attr, - void (*send_cb)(struct ath10k_ce_pipe *), - void (*recv_cb)(struct ath10k_ce_pipe *)); + const struct ce_attr *attr); void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, - const struct ce_attr *attr); + const struct ce_attr *attr, + void (*send_cb)(struct ath10k_ce_pipe *), + void (*recv_cb)(struct ath10k_ce_pipe *)); void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); /*==================CE Engine Shutdown=======================*/ diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 243099d62ee9..4a4740b4bdc0 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1615,23 +1615,40 @@ static int ath10k_pci_init_config(struct ath10k *ar) return 0; } -static int ath10k_pci_alloc_ce(struct ath10k *ar) +static int ath10k_pci_alloc_pipes(struct ath10k *ar) { + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + struct ath10k_pci_pipe *pipe; int i, ret; for (i = 0; i < CE_COUNT; i++) { - ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]); + pipe = &ar_pci->pipe_info[i]; + pipe->ce_hdl = &ar_pci->ce_states[i]; + pipe->pipe_num = i; + pipe->hif_ce_state = ar; + + ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i], + ath10k_pci_ce_send_done, + ath10k_pci_ce_recv_data); if (ret) { ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n", i, ret); return ret; } + + /* Last CE is Diagnostic Window */ + if (i == CE_COUNT - 1) { + ar_pci->ce_diag = pipe->ce_hdl; + continue; + } + + pipe->buf_sz = (size_t)(host_ce_config_wlan[i].src_sz_max); } return 0; } -static void ath10k_pci_free_ce(struct ath10k *ar) +static void ath10k_pci_free_pipes(struct ath10k *ar) { int i; @@ -1639,39 +1656,17 @@ static void ath10k_pci_free_ce(struct ath10k *ar) ath10k_ce_free_pipe(ar, i); } -static int ath10k_pci_ce_init(struct ath10k *ar) +static int ath10k_pci_init_pipes(struct ath10k *ar) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info; - const struct ce_attr *attr; - int pipe_num, ret; + int i, ret; - for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { - pipe_info = &ar_pci->pipe_info[pipe_num]; - pipe_info->ce_hdl = &ar_pci->ce_states[pipe_num]; - pipe_info->pipe_num = pipe_num; - pipe_info->hif_ce_state = ar; - attr = &host_ce_config_wlan[pipe_num]; - - ret = ath10k_ce_init_pipe(ar, pipe_num, attr, - ath10k_pci_ce_send_done, - ath10k_pci_ce_recv_data); + for (i = 0; i < CE_COUNT; i++) { + ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]); if (ret) { ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n", - pipe_num, ret); + i, ret); return ret; } - - if (pipe_num == CE_COUNT - 1) { - /* - * Reserve the ultimate CE for - * diagnostic Window support - */ - ar_pci->ce_diag = pipe_info->ce_hdl; - continue; - } - - pipe_info->buf_sz = (size_t)(attr->src_sz_max); } return 0; @@ -1825,7 +1820,7 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) goto err; } - ret = ath10k_pci_ce_init(ar); + ret = ath10k_pci_init_pipes(ar); if (ret) { ath10k_err(ar, "failed to initialize CE: %d\n", ret); goto err; @@ -2495,7 +2490,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_sleep; } - ret = ath10k_pci_alloc_ce(ar); + ret = ath10k_pci_alloc_pipes(ar); if (ret) { ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", ret); @@ -2508,7 +2503,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ret = ath10k_pci_init_irq(ar); if (ret) { ath10k_err(ar, "failed to init irqs: %d\n", ret); - goto err_free_ce; + goto err_free_pipes; } ath10k_info(ar, "pci irq %s interrupts %d irq_mode %d reset_mode %d\n", @@ -2536,8 +2531,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev, err_deinit_irq: ath10k_pci_deinit_irq(ar); -err_free_ce: - ath10k_pci_free_ce(ar); +err_free_pipes: + ath10k_pci_free_pipes(ar); err_sleep: ath10k_pci_sleep(ar); @@ -2571,7 +2566,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) ath10k_pci_kill_tasklet(ar); ath10k_pci_deinit_irq(ar); ath10k_pci_ce_deinit(ar); - ath10k_pci_free_ce(ar); + ath10k_pci_free_pipes(ar); ath10k_pci_sleep(ar); ath10k_pci_release(ar); ath10k_core_destroy(ar); -- GitLab From 70b3e89aaf421ad642c4ab0fb196e1c19ea838c5 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 22 Oct 2014 13:58:49 +0900 Subject: [PATCH 1095/9457] PCI: exynos: Add exynos prefix to add_pcie_port()/pcie_init() The add_pcie_port() and pcie_init() functions are Exynos-specific. Add exynos prefix to avoid collision in global name space. Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pci-exynos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index c5d0ca384502..902d7cd3e760 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -509,8 +509,8 @@ static struct pcie_host_ops exynos_pcie_host_ops = { .host_init = exynos_pcie_host_init, }; -static int __init add_pcie_port(struct pcie_port *pp, - struct platform_device *pdev) +static int __init exynos_add_pcie_port(struct pcie_port *pp, + struct platform_device *pdev) { int ret; @@ -615,7 +615,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev) goto fail_bus_clk; } - ret = add_pcie_port(pp, pdev); + ret = exynos_add_pcie_port(pp, pdev); if (ret < 0) goto fail_bus_clk; @@ -656,11 +656,11 @@ static struct platform_driver exynos_pcie_driver = { /* Exynos PCIe driver does not allow module unload */ -static int __init pcie_init(void) +static int __init exynos_pcie_init(void) { return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe); } -subsys_initcall(pcie_init); +subsys_initcall(exynos_pcie_init); MODULE_AUTHOR("Jingoo Han "); MODULE_DESCRIPTION("Samsung PCIe host controller driver"); -- GitLab From 5ba8368b7a78514d823cd7caaba7f6c2fdef8f97 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Oct 2014 11:10:16 +0900 Subject: [PATCH 1096/9457] PCI: keystone: Make ks_dw_pcie_msi_domain_ops static Make ks_dw_pcie_msi_domain_ops static because it is used only in this file. Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Murali Karicheri Acked-by: Santosh Shilimkar --- drivers/pci/host/pci-keystone-dw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index 34086ce88e8e..4a97cd14e6fb 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c @@ -201,7 +201,7 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, return 0; } -const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = { +static const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = { .map = ks_dw_pcie_msi_map, }; -- GitLab From 3c70637f7569de3ebf05e2961c05e05ed80e22df Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Oct 2014 11:11:47 +0900 Subject: [PATCH 1097/9457] PCI: rcar: Make rcar_pci static Make rcar_pci static because it is used only in this file. Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Simon Horman --- drivers/pci/host/pcie-rcar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 61158e03ab5f..0df9b2941221 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c @@ -389,7 +389,7 @@ static void rcar_pcie_add_bus(struct pci_bus *bus) } } -struct hw_pci rcar_pci = { +static struct hw_pci rcar_pci = { .setup = rcar_pcie_setup, .map_irq = of_irq_parse_and_map_pci, .ops = &rcar_pcie_ops, -- GitLab From e77a7b4f01b4c7b02c1c15b5d5b4ce4bd147b043 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 6 Oct 2014 16:42:52 -0700 Subject: [PATCH 1098/9457] nfsd: fix inclusive vfs_fsync_range() end The vfs_fsync_range() call during write processing got the end of the range off by one. The range is inclusive, not exclusive. The error has nfsd sync more data than requested -- it's correct but unnecessary overhead. The call during commit processing is correct so I copied that pattern in write processing. Maybe a helper would be nice but I kept it trivial. This is untested. I found it while reviewing code for something else entirely. Signed-off-by: Zach Brown Signed-off-by: J. Bruce Fields --- fs/nfsd/vfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 989129e2d6ea..d16076bd9a7a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -938,6 +938,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, int stable = *stablep; int use_wgather; loff_t pos = offset; + loff_t end = LLONG_MAX; unsigned int pflags = current->flags; if (rqstp->rq_local) @@ -969,10 +970,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, fsnotify_modify(file); if (stable) { - if (use_wgather) + if (use_wgather) { host_err = wait_for_concurrent_writes(file); - else - host_err = vfs_fsync_range(file, offset, offset+*cnt, 0); + } else { + if (*cnt) + end = offset + *cnt - 1; + host_err = vfs_fsync_range(file, offset, end, 0); + } } out_nfserr: -- GitLab From ed38c0699848508672793bbdcca98ee89aa6c71e Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 19 Sep 2014 17:21:35 -0400 Subject: [PATCH 1099/9457] RPC: remove unneeded checks from xdr_truncate_encode() Thanks to Andrea Arcangeli for pointing out these checks are obviously unnecessary given the preceding calculations. Reported-by: Andrea Arcangeli Signed-off-by: J. Bruce Fields --- net/sunrpc/xdr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 290af97bf6f9..bcece520c4db 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -617,7 +617,7 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) fraglen = min_t(int, buf->len - len, tail->iov_len); tail->iov_len -= fraglen; buf->len -= fraglen; - if (tail->iov_len && buf->len == len) { + if (tail->iov_len) { xdr->p = tail->iov_base + tail->iov_len; /* xdr->end, xdr->iov should be set already */ return; @@ -631,7 +631,7 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) old = new + fraglen; xdr->page_ptr -= (old >> PAGE_SHIFT) - (new >> PAGE_SHIFT); - if (buf->page_len && buf->len == len) { + if (buf->page_len) { xdr->p = page_address(*xdr->page_ptr); xdr->end = (void *)xdr->p + PAGE_SIZE; xdr->p = (void *)xdr->p + (new % PAGE_SIZE); -- GitLab From 280caac078d3db075247915f6d2f72315232ed16 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 1 Oct 2014 11:36:31 -0400 Subject: [PATCH 1100/9457] rpc: change comments to assertions Reported-by: Andrea Arcangeli Signed-off-by: J. Bruce Fields --- net/sunrpc/xdr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index bcece520c4db..1cb61242e55e 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -619,7 +619,8 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) buf->len -= fraglen; if (tail->iov_len) { xdr->p = tail->iov_base + tail->iov_len; - /* xdr->end, xdr->iov should be set already */ + WARN_ON_ONCE(!xdr->end); + WARN_ON_ONCE(!xdr->iov); return; } WARN_ON_ONCE(fraglen); @@ -635,7 +636,7 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) xdr->p = page_address(*xdr->page_ptr); xdr->end = (void *)xdr->p + PAGE_SIZE; xdr->p = (void *)xdr->p + (new % PAGE_SIZE); - /* xdr->iov should already be NULL */ + WARN_ON_ONCE(xdr->iov); return; } if (fraglen) { -- GitLab From b0d2e42cce8fbf12998a24abf62a26c895dd2fd2 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 22 Aug 2014 15:10:59 -0400 Subject: [PATCH 1101/9457] NFSD: Always initialize cl_cb_addr A client may not want to use the back channel on a transport it sent CREATE_SESSION on, in which case it clears SESSION4_BACK_CHAN. However, cl_cb_addr should be populated anyway, to be used if the client binds other connections to this session. If cl_cb_addr is not initialized, rpc_create() fails when the server attempts to set up a back channel on such secondary transports. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e9c3afe4b5d3..1afd7d4420bd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1440,7 +1440,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru list_add(&new->se_perclnt, &clp->cl_sessions); spin_unlock(&clp->cl_lock); - if (cses->flags & SESSION4_BACK_CHAN) { + { struct sockaddr *sa = svc_addr(rqstp); /* * This is a little silly; with sessions there's no real -- GitLab From ccc6398ea5d58fdedc6caccba0216ab30739773b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 16 Oct 2014 08:49:37 -0400 Subject: [PATCH 1102/9457] nfsd: clean up comments over nfs4_file definition They're a bit outdated wrt to some recent changes. Signed-off-by: Jeff Layton Reviewed-by: Christoph Hellwig Signed-off-by: J. Bruce Fields --- fs/nfsd/state.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 2712042a66b1..8e85e07efce6 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -463,15 +463,19 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so) /* * nfs4_file: a file opened by some number of (open) nfs4_stateowners. * - * These objects are global. nfsd only keeps one instance of a nfs4_file per - * inode (though it may keep multiple file descriptors open per inode). These - * are tracked in the file_hashtbl which is protected by the state_lock - * spinlock. + * These objects are global. nfsd keeps one instance of a nfs4_file per + * filehandle (though it may keep multiple file descriptors for each). Each + * inode can have multiple filehandles associated with it, so there is + * (potentially) a many to one relationship between this struct and struct + * inode. + * + * These are hashed by filehandle in the file_hashtbl, which is protected by + * the global state_lock spinlock. */ struct nfs4_file { atomic_t fi_ref; spinlock_t fi_lock; - struct hlist_node fi_hash; /* hash by "struct inode *" */ + struct hlist_node fi_hash; /* hash on fi_fhandle */ struct list_head fi_stateids; struct list_head fi_delegations; /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ -- GitLab From 8ec7886b1cd59c6e76a6d8fa413f9d338cfedc96 Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Wed, 22 Oct 2014 18:20:37 +0200 Subject: [PATCH 1103/9457] mac80211: minstrel_ht: use group flags instead of index to display rates When displaying a rate through debugfs minstrel_ht guesses its flags comparing group indexes. Since 3ec373c421b6 ("mac80211: minstrel_ht: include type (cck/ht) in rates flag"), the rate flags of interest are present in the mcs_group-s, so use it. While improving the code, this also fixes a smatch false positive "error: testing array offset 'i' after use" in minstrel_ht_stats_dump. This warning only triggers after 9208247d74bc ("mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz") with CONFIG_MAC80211_RC_MINSTREL_VHT unset because then MINSTREL_VHT_GROUP_0 is above MINSTREL_GROUPS_NB and smatch only barks when the "testing array offset" seems to prevent possible out of bonds accesses (which does not happen here since i < ARRAY_SIZE(mi->groups)). Signed-off-by: Karl Beldan Cc: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht_debugfs.c | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 52bb6ef55b19..20c676b8e5b6 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c @@ -22,16 +22,19 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) unsigned int j, tp, prob, eprob; char htmode = '2'; char gimode = 'L'; + u32 gflags; if (!mi->groups[i].supported) return p; mg = &minstrel_mcs_groups[i]; - if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + gflags = mg->flags; + + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) htmode = '4'; - else if (mg->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) htmode = '8'; - if (mg->flags & IEEE80211_TX_RC_SHORT_GI) + if (gflags & IEEE80211_TX_RC_SHORT_GI) gimode = 'S'; for (j = 0; j < MCS_GROUP_RATES; j++) { @@ -42,12 +45,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) if (!(mi->groups[i].supported & BIT(j))) continue; - if (i == MINSTREL_CCK_GROUP) - p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); - else if (i >= MINSTREL_VHT_GROUP_0) + if (gflags & IEEE80211_TX_RC_MCS) + p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); + else if (gflags & IEEE80211_TX_RC_VHT_MCS) p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode); else - p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); + p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; @@ -55,13 +58,14 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; - if (i == MINSTREL_CCK_GROUP) { - int r = bitrates[j % 4]; - p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); - } else if (i >= MINSTREL_VHT_GROUP_0) { + if (gflags & IEEE80211_TX_RC_MCS) { + p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); + } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); } else { - p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); + int r = bitrates[j % 4]; + + p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); } tp = mr->cur_tp / 10; -- GitLab From a7f3a768289858f03f5c1866639c8b476c1b8ebc Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Wed, 22 Oct 2014 15:22:49 +0300 Subject: [PATCH 1104/9457] mac80211: export IE splitting function Export ieee80211_ie_split function, so it can be reused by drivers which need to insert additional elements. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 28 ++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 2 -- net/mac80211/util.c | 26 +------------------------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9dc5e7606322..96d224357c8c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4906,4 +4906,32 @@ void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf); void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer, enum nl80211_tdls_operation oper, u16 reason_code, gfp_t gfp); + +/** + * ieee80211_ie_split - split an IE buffer according to ordering + * + * @ies: the IE buffer + * @ielen: the length of the IE buffer + * @ids: an array with element IDs that are allowed before + * the split + * @n_ids: the size of the element ID array + * @offset: offset where to start splitting in the buffer + * + * This function splits an IE buffer by updating the @offset + * variable to point to the location where the buffer should be + * split. + * + * It assumes that the given IE buffer is well-formed, this + * has to be guaranteed by the caller! + * + * It also assumes that the IEs in the buffer are ordered + * correctly, if not the result of using this function will not + * be ordered correctly either, i.e. it does no reordering. + * + * The function returns the offset where the next part of the + * buffer starts, which may be @ielen if the entire (remainder) + * of the buffer should be used. + */ +size_t ieee80211_ie_split(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, size_t offset); #endif /* MAC80211_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 60063be057d0..146a818e52b5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1874,8 +1874,6 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); -size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u16 cap); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c76c9d7294ae..9247a960ea59 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2052,31 +2052,6 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } -/** - * ieee80211_ie_split - split an IE buffer according to ordering - * - * @ies: the IE buffer - * @ielen: the length of the IE buffer - * @ids: an array with element IDs that are allowed before - * the split - * @n_ids: the size of the element ID array - * @offset: offset where to start splitting in the buffer - * - * This function splits an IE buffer by updating the @offset - * variable to point to the location where the buffer should be - * split. - * - * It assumes that the given IE buffer is well-formed, this - * has to be guaranteed by the caller! - * - * It also assumes that the IEs in the buffer are ordered - * correctly, if not the result of using this function will not - * be ordered correctly either, i.e. it does no reordering. - * - * The function returns the offset where the next part of the - * buffer starts, which may be @ielen if the entire (remainder) - * of the buffer should be used. - */ size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset) { @@ -2087,6 +2062,7 @@ size_t ieee80211_ie_split(const u8 *ies, size_t ielen, return pos; } +EXPORT_SYMBOL(ieee80211_ie_split); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) { -- GitLab From 452218d9fd22505ed790e95b460b0f40cebb95a0 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:33:45 +0300 Subject: [PATCH 1105/9457] mac80211: fix network header breakage during encryption When an IV is generated, only the MAC header is moved back. The network header location remains the same relative to the skb head, as the new IV is using headroom space that was reserved in advance. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/wep.c | 2 -- net/mac80211/wpa.c | 5 ----- 2 files changed, 7 deletions(-) diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9181fb6d6437..a4220e92f0cc 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -111,8 +111,6 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) return newhdr + hdrlen; - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_WEP_IV_LEN); ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); return newhdr + hdrlen; } diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 983527a4c1ab..12398fde02e8 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -209,8 +209,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_TKIP_IV_LEN); pos += hdrlen; /* the HW only needs room for the IV, but not the actual IV */ @@ -434,8 +432,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + - IEEE80211_CCMP_HDR_LEN); /* the HW only needs room for the IV, but not the actual IV */ if (info->control.hw_key && @@ -575,7 +571,6 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, pos = skb_push(skb, cs->hdr_len); memmove(pos, pos + cs->hdr_len, hdrlen); - skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len); return TX_CONTINUE; } -- GitLab From 8b94148cfec4c40f4c55308fdcd816bbfe2b4016 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:32:48 +0300 Subject: [PATCH 1106/9457] mac80211: expose TDLS-initiator value to low level driver Some drivers need to know which station is the TDLS link initiator. Expose this value via the mac80211 ieee80211_sta structure. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 3 +++ net/mac80211/tdls.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 96d224357c8c..99dd3ce7484e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1427,6 +1427,8 @@ struct ieee80211_sta_rates { * @smps_mode: current SMPS mode (off, static or dynamic) * @rates: rate control selection table * @tdls: indicates whether the STA is a TDLS peer + * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only + * valid if the STA is a TDLS peer in the first place. */ struct ieee80211_sta { u32 supp_rates[IEEE80211_NUM_BANDS]; @@ -1442,6 +1444,7 @@ struct ieee80211_sta { enum ieee80211_smps_mode smps_mode; struct ieee80211_sta_rates __rcu *rates; bool tdls; + bool tdls_initiator; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 4ea25dec0698..b4f368e2cb3b 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -562,8 +562,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, /* infer the initiator if we can, to support old userspace */ switch (action_code) { case WLAN_TDLS_SETUP_REQUEST: - if (sta) + if (sta) { set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); + sta->sta.tdls_initiator = false; + } /* fall-through */ case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_DISCOVERY_REQUEST: @@ -575,8 +577,10 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, * Make the last packet sent take effect for the initiator * value. */ - if (sta) + if (sta) { clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); + sta->sta.tdls_initiator = true; + } /* fall-through */ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: initiator = false; -- GitLab From 2bad7748b332d7218377287248eb66c25de033b2 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:32:16 +0300 Subject: [PATCH 1107/9457] mac80211: add stations in order to the station list During reconfig the station list is traversed in order and station are added back to the driver. Make sure the stations are added to the driver in the same order they were added to mac80211. This has a real side effect - some drivers (iwlwifi) require TDLS stations to be added only after the AP station for the same network. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index de494df3bab8..2cd48cefcbdc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -501,7 +501,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) /* make the station visible */ sta_info_hash_add(local, sta); - list_add_rcu(&sta->list, &local->sta_list); + list_add_tail_rcu(&sta->list, &local->sta_list); /* notify driver */ err = sta_info_insert_drv_state(local, sdata, sta); -- GitLab From 0fc1e0495fd6e261e75acdbe66b53e769e5ffb81 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 22 Oct 2014 12:30:59 +0300 Subject: [PATCH 1108/9457] mac80211: expose API allowing station iteration Allow drivers to iterate all stations currently uploaded to them. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/net/mac80211.h | 16 ++++++++++++++++ net/mac80211/util.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 99dd3ce7484e..2b7426a90ff0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4192,6 +4192,22 @@ void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw, struct ieee80211_vif *vif), void *data); +/** + * ieee80211_iterate_stations_atomic - iterate stations + * + * This function iterates over all stations associated with a given + * hardware that are currently uploaded to the driver and calls the callback + * function for them. + * This function requires the iterator callback function to be atomic, + * + * @hw: the hardware struct of which the interfaces should be iterated over + * @iterator: the iterator function to call, cannot sleep + * @data: first argument of the iterator function + */ +void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data); /** * ieee80211_queue_work - add work onto the mac80211 workqueue * diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9247a960ea59..666aa1306c45 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -693,6 +693,34 @@ void ieee80211_iterate_active_interfaces_rtnl( } EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); +static void __iterate_stations(struct ieee80211_local *local, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data) +{ + struct sta_info *sta; + + list_for_each_entry_rcu(sta, &local->sta_list, list) { + if (!sta->uploaded) + continue; + + iterator(data, &sta->sta); + } +} + +void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data) +{ + struct ieee80211_local *local = hw_to_local(hw); + + rcu_read_lock(); + __iterate_stations(local, iterator, data); + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); + struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); -- GitLab From 7e2453fee88f8c326a2df9fcee1f05767d8a709a Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Sat, 13 Sep 2014 07:40:41 +0000 Subject: [PATCH 1109/9457] i40e: mask phy events Tell the firmware what kind of link related events the driver is interested in. In this case, just link up/down and qualified module events are the ones the driver really cares about. Change-ID: If132c812c340c8e1927c2caf6d55185296b66201 Signed-off-by: Jesse Brandeburg Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 27 +++++++++++++++++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 18 +++++++++++++ .../net/ethernet/intel/i40e/i40e_prototype.h | 2 ++ 3 files changed, 47 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 30056b25d94e..c23e3772de58 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1419,6 +1419,33 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse) return status; } +/** + * i40e_aq_set_phy_int_mask + * @hw: pointer to the hw struct + * @mask: interrupt mask to be set + * @cmd_details: pointer to command details structure or NULL + * + * Set link interrupt mask. + **/ +i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, + u16 mask, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + struct i40e_aqc_set_phy_int_mask *cmd = + (struct i40e_aqc_set_phy_int_mask *)&desc.params.raw; + i40e_status status; + + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_set_phy_int_mask); + + cmd->event_mask = cpu_to_le16(mask); + + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); + + return status; +} + /** * i40e_aq_add_vsi * @hw: pointer to the hw struct diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ed5f1c15fb0f..8cb64690a6c2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6038,6 +6038,15 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) if (ret) goto end_core_reset; + /* driver is only interested in link up/down and module qualification + * reports from firmware + */ + ret = i40e_aq_set_phy_int_mask(&pf->hw, + I40E_AQ_EVENT_LINK_UPDOWN | + I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL); + if (ret) + dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", ret); + /* Rebuild the VSIs and VEBs that existed before reset. * They are still in our local switch element arrays, so only * need to rebuild the switch model in the HW. @@ -9158,6 +9167,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } + /* driver is only interested in link up/down and module qualification + * reports from firmware + */ + err = i40e_aq_set_phy_int_mask(&pf->hw, + I40E_AQ_EVENT_LINK_UPDOWN | + I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL); + if (err) + dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", err); + /* The main driver is (mostly) up and happy. We need to set this state * before setting up the misc vector or we get a race and the vector * ends up disabled forever. diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 0988b5c1fe87..246c27869a63 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -84,6 +84,8 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures, bool atomic_reset); +i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask, + struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw, struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw, -- GitLab From 1e701e09d898834ee808cd3af7c4ff46348d4f61 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Sat, 13 Sep 2014 07:40:42 +0000 Subject: [PATCH 1110/9457] i40e: enable LSE poke and simplify link state The driver can do a simpler job of managing link state by simply using the admin queue receive event for link events as a doorbell that tells the driver to update link state. Additionally, add a workaround will help make sure the link state in the hardware is consistent with the link state the driver is reporting by refreshing the link state every service task interval. Change-ID: Ib95b5b7b8cc016e97d8009f6363c9f9eed301444 Signed-off-by: Jesse Brandeburg Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 39 +++++++++------------ 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 8cb64690a6c2..d40fc3b9c46e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5354,10 +5354,14 @@ static void i40e_link_event(struct i40e_pf *pf) { bool new_link, old_link; - new_link = (pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP); + /* set this to force the get_link_status call to refresh state */ + pf->hw.phy.get_link_info = true; + old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP); + new_link = i40e_get_link_status(&pf->hw); - if (new_link == old_link) + if (new_link == old_link && + new_link == netif_carrier_ok(pf->vsi[pf->lan_vsi]->netdev)) return; if (!test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state)) i40e_print_link_message(pf->vsi[pf->lan_vsi], new_link); @@ -5525,33 +5529,20 @@ static void i40e_handle_link_event(struct i40e_pf *pf, memcpy(&pf->hw.phy.link_info_old, hw_link_info, sizeof(pf->hw.phy.link_info_old)); + /* Do a new status request to re-enable LSE reporting + * and load new status information into the hw struct + * This completely ignores any state information + * in the ARQ event info, instead choosing to always + * issue the AQ update link status command. + */ + i40e_link_event(pf); + /* check for unqualified module, if link is down */ if ((status->link_info & I40E_AQ_MEDIA_AVAILABLE) && (!(status->an_info & I40E_AQ_QUALIFIED_MODULE)) && (!(status->link_info & I40E_AQ_LINK_UP))) dev_err(&pf->pdev->dev, "The driver failed to link because an unqualified module was detected.\n"); - - /* update link status */ - hw_link_info->phy_type = (enum i40e_aq_phy_type)status->phy_type; - hw_link_info->link_speed = (enum i40e_aq_link_speed)status->link_speed; - hw_link_info->link_info = status->link_info; - hw_link_info->an_info = status->an_info; - hw_link_info->ext_info = status->ext_info; - hw_link_info->lse_enable = - le16_to_cpu(status->command_flags) & - I40E_AQ_LSE_ENABLE; - - /* process the event */ - i40e_link_event(pf); - - /* Do a new status request to re-enable LSE reporting - * and load new status information into the hw struct, - * then see if the status changed while processing the - * initial event. - */ - i40e_update_link_info(&pf->hw, true); - i40e_link_event(pf); } /** @@ -6314,6 +6305,8 @@ static void i40e_service_task(struct work_struct *work) #endif i40e_clean_adminq_subtask(pf); + i40e_link_event(pf); + i40e_service_event_complete(pf); /* If the tasks have taken longer than one timer cycle or there -- GitLab From 8c570dcc8cbabd7bf1a8eb7eb7cc16a1a37b6c0f Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Sat, 13 Sep 2014 07:40:43 +0000 Subject: [PATCH 1111/9457] i40e/i40evf: Fix whitespace indentation This is one small step in making the indentation more consistent. If we truly want to align values, then use tabs rather than spaces. Change-ID: I12368bc77a52f296d1843fdcb67201a7d7cd4749 Signed-off-by: Jeff Kirsher Tested-by: Jim Young --- .../net/ethernet/intel/i40e/i40e_adminq_cmd.h | 2139 ++++++++--------- .../ethernet/intel/i40evf/i40e_adminq_cmd.h | 2136 ++++++++-------- 2 files changed, 2133 insertions(+), 2142 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index 15f289f2917f..a65bc4398971 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -33,8 +33,8 @@ * This file needs to comply with the Linux Kernel coding style. */ -#define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0002 +#define I40E_FW_API_VERSION_MAJOR 0x0001 +#define I40E_FW_API_VERSION_MINOR 0x0002 struct i40e_aq_desc { __le16 flags; @@ -66,216 +66,216 @@ struct i40e_aq_desc { */ /* command flags and offsets*/ -#define I40E_AQ_FLAG_DD_SHIFT 0 -#define I40E_AQ_FLAG_CMP_SHIFT 1 -#define I40E_AQ_FLAG_ERR_SHIFT 2 -#define I40E_AQ_FLAG_VFE_SHIFT 3 -#define I40E_AQ_FLAG_LB_SHIFT 9 -#define I40E_AQ_FLAG_RD_SHIFT 10 -#define I40E_AQ_FLAG_VFC_SHIFT 11 -#define I40E_AQ_FLAG_BUF_SHIFT 12 -#define I40E_AQ_FLAG_SI_SHIFT 13 -#define I40E_AQ_FLAG_EI_SHIFT 14 -#define I40E_AQ_FLAG_FE_SHIFT 15 - -#define I40E_AQ_FLAG_DD (1 << I40E_AQ_FLAG_DD_SHIFT) /* 0x1 */ -#define I40E_AQ_FLAG_CMP (1 << I40E_AQ_FLAG_CMP_SHIFT) /* 0x2 */ -#define I40E_AQ_FLAG_ERR (1 << I40E_AQ_FLAG_ERR_SHIFT) /* 0x4 */ -#define I40E_AQ_FLAG_VFE (1 << I40E_AQ_FLAG_VFE_SHIFT) /* 0x8 */ -#define I40E_AQ_FLAG_LB (1 << I40E_AQ_FLAG_LB_SHIFT) /* 0x200 */ -#define I40E_AQ_FLAG_RD (1 << I40E_AQ_FLAG_RD_SHIFT) /* 0x400 */ -#define I40E_AQ_FLAG_VFC (1 << I40E_AQ_FLAG_VFC_SHIFT) /* 0x800 */ -#define I40E_AQ_FLAG_BUF (1 << I40E_AQ_FLAG_BUF_SHIFT) /* 0x1000 */ -#define I40E_AQ_FLAG_SI (1 << I40E_AQ_FLAG_SI_SHIFT) /* 0x2000 */ -#define I40E_AQ_FLAG_EI (1 << I40E_AQ_FLAG_EI_SHIFT) /* 0x4000 */ -#define I40E_AQ_FLAG_FE (1 << I40E_AQ_FLAG_FE_SHIFT) /* 0x8000 */ +#define I40E_AQ_FLAG_DD_SHIFT 0 +#define I40E_AQ_FLAG_CMP_SHIFT 1 +#define I40E_AQ_FLAG_ERR_SHIFT 2 +#define I40E_AQ_FLAG_VFE_SHIFT 3 +#define I40E_AQ_FLAG_LB_SHIFT 9 +#define I40E_AQ_FLAG_RD_SHIFT 10 +#define I40E_AQ_FLAG_VFC_SHIFT 11 +#define I40E_AQ_FLAG_BUF_SHIFT 12 +#define I40E_AQ_FLAG_SI_SHIFT 13 +#define I40E_AQ_FLAG_EI_SHIFT 14 +#define I40E_AQ_FLAG_FE_SHIFT 15 + +#define I40E_AQ_FLAG_DD (1 << I40E_AQ_FLAG_DD_SHIFT) /* 0x1 */ +#define I40E_AQ_FLAG_CMP (1 << I40E_AQ_FLAG_CMP_SHIFT) /* 0x2 */ +#define I40E_AQ_FLAG_ERR (1 << I40E_AQ_FLAG_ERR_SHIFT) /* 0x4 */ +#define I40E_AQ_FLAG_VFE (1 << I40E_AQ_FLAG_VFE_SHIFT) /* 0x8 */ +#define I40E_AQ_FLAG_LB (1 << I40E_AQ_FLAG_LB_SHIFT) /* 0x200 */ +#define I40E_AQ_FLAG_RD (1 << I40E_AQ_FLAG_RD_SHIFT) /* 0x400 */ +#define I40E_AQ_FLAG_VFC (1 << I40E_AQ_FLAG_VFC_SHIFT) /* 0x800 */ +#define I40E_AQ_FLAG_BUF (1 << I40E_AQ_FLAG_BUF_SHIFT) /* 0x1000 */ +#define I40E_AQ_FLAG_SI (1 << I40E_AQ_FLAG_SI_SHIFT) /* 0x2000 */ +#define I40E_AQ_FLAG_EI (1 << I40E_AQ_FLAG_EI_SHIFT) /* 0x4000 */ +#define I40E_AQ_FLAG_FE (1 << I40E_AQ_FLAG_FE_SHIFT) /* 0x8000 */ /* error codes */ enum i40e_admin_queue_err { - I40E_AQ_RC_OK = 0, /* success */ - I40E_AQ_RC_EPERM = 1, /* Operation not permitted */ - I40E_AQ_RC_ENOENT = 2, /* No such element */ - I40E_AQ_RC_ESRCH = 3, /* Bad opcode */ - I40E_AQ_RC_EINTR = 4, /* operation interrupted */ - I40E_AQ_RC_EIO = 5, /* I/O error */ - I40E_AQ_RC_ENXIO = 6, /* No such resource */ - I40E_AQ_RC_E2BIG = 7, /* Arg too long */ - I40E_AQ_RC_EAGAIN = 8, /* Try again */ - I40E_AQ_RC_ENOMEM = 9, /* Out of memory */ - I40E_AQ_RC_EACCES = 10, /* Permission denied */ - I40E_AQ_RC_EFAULT = 11, /* Bad address */ - I40E_AQ_RC_EBUSY = 12, /* Device or resource busy */ - I40E_AQ_RC_EEXIST = 13, /* object already exists */ - I40E_AQ_RC_EINVAL = 14, /* Invalid argument */ - I40E_AQ_RC_ENOTTY = 15, /* Not a typewriter */ - I40E_AQ_RC_ENOSPC = 16, /* No space left or alloc failure */ - I40E_AQ_RC_ENOSYS = 17, /* Function not implemented */ - I40E_AQ_RC_ERANGE = 18, /* Parameter out of range */ - I40E_AQ_RC_EFLUSHED = 19, /* Cmd flushed because of prev cmd error */ - I40E_AQ_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */ - I40E_AQ_RC_EMODE = 21, /* Op not allowed in current dev mode */ - I40E_AQ_RC_EFBIG = 22, /* File too large */ + I40E_AQ_RC_OK = 0, /* success */ + I40E_AQ_RC_EPERM = 1, /* Operation not permitted */ + I40E_AQ_RC_ENOENT = 2, /* No such element */ + I40E_AQ_RC_ESRCH = 3, /* Bad opcode */ + I40E_AQ_RC_EINTR = 4, /* operation interrupted */ + I40E_AQ_RC_EIO = 5, /* I/O error */ + I40E_AQ_RC_ENXIO = 6, /* No such resource */ + I40E_AQ_RC_E2BIG = 7, /* Arg too long */ + I40E_AQ_RC_EAGAIN = 8, /* Try again */ + I40E_AQ_RC_ENOMEM = 9, /* Out of memory */ + I40E_AQ_RC_EACCES = 10, /* Permission denied */ + I40E_AQ_RC_EFAULT = 11, /* Bad address */ + I40E_AQ_RC_EBUSY = 12, /* Device or resource busy */ + I40E_AQ_RC_EEXIST = 13, /* object already exists */ + I40E_AQ_RC_EINVAL = 14, /* Invalid argument */ + I40E_AQ_RC_ENOTTY = 15, /* Not a typewriter */ + I40E_AQ_RC_ENOSPC = 16, /* No space left or alloc failure */ + I40E_AQ_RC_ENOSYS = 17, /* Function not implemented */ + I40E_AQ_RC_ERANGE = 18, /* Parameter out of range */ + I40E_AQ_RC_EFLUSHED = 19, /* Cmd flushed due to prev cmd error */ + I40E_AQ_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */ + I40E_AQ_RC_EMODE = 21, /* Op not allowed in current dev mode */ + I40E_AQ_RC_EFBIG = 22, /* File too large */ }; /* Admin Queue command opcodes */ enum i40e_admin_queue_opc { /* aq commands */ - i40e_aqc_opc_get_version = 0x0001, - i40e_aqc_opc_driver_version = 0x0002, - i40e_aqc_opc_queue_shutdown = 0x0003, - i40e_aqc_opc_set_pf_context = 0x0004, + i40e_aqc_opc_get_version = 0x0001, + i40e_aqc_opc_driver_version = 0x0002, + i40e_aqc_opc_queue_shutdown = 0x0003, + i40e_aqc_opc_set_pf_context = 0x0004, /* resource ownership */ - i40e_aqc_opc_request_resource = 0x0008, - i40e_aqc_opc_release_resource = 0x0009, + i40e_aqc_opc_request_resource = 0x0008, + i40e_aqc_opc_release_resource = 0x0009, - i40e_aqc_opc_list_func_capabilities = 0x000A, - i40e_aqc_opc_list_dev_capabilities = 0x000B, + i40e_aqc_opc_list_func_capabilities = 0x000A, + i40e_aqc_opc_list_dev_capabilities = 0x000B, - i40e_aqc_opc_set_cppm_configuration = 0x0103, - i40e_aqc_opc_set_arp_proxy_entry = 0x0104, - i40e_aqc_opc_set_ns_proxy_entry = 0x0105, + i40e_aqc_opc_set_cppm_configuration = 0x0103, + i40e_aqc_opc_set_arp_proxy_entry = 0x0104, + i40e_aqc_opc_set_ns_proxy_entry = 0x0105, /* LAA */ - i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */ - i40e_aqc_opc_mac_address_read = 0x0107, - i40e_aqc_opc_mac_address_write = 0x0108, + i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */ + i40e_aqc_opc_mac_address_read = 0x0107, + i40e_aqc_opc_mac_address_write = 0x0108, /* PXE */ - i40e_aqc_opc_clear_pxe_mode = 0x0110, + i40e_aqc_opc_clear_pxe_mode = 0x0110, /* internal switch commands */ - i40e_aqc_opc_get_switch_config = 0x0200, - i40e_aqc_opc_add_statistics = 0x0201, - i40e_aqc_opc_remove_statistics = 0x0202, - i40e_aqc_opc_set_port_parameters = 0x0203, - i40e_aqc_opc_get_switch_resource_alloc = 0x0204, - - i40e_aqc_opc_add_vsi = 0x0210, - i40e_aqc_opc_update_vsi_parameters = 0x0211, - i40e_aqc_opc_get_vsi_parameters = 0x0212, - - i40e_aqc_opc_add_pv = 0x0220, - i40e_aqc_opc_update_pv_parameters = 0x0221, - i40e_aqc_opc_get_pv_parameters = 0x0222, - - i40e_aqc_opc_add_veb = 0x0230, - i40e_aqc_opc_update_veb_parameters = 0x0231, - i40e_aqc_opc_get_veb_parameters = 0x0232, - - i40e_aqc_opc_delete_element = 0x0243, - - i40e_aqc_opc_add_macvlan = 0x0250, - i40e_aqc_opc_remove_macvlan = 0x0251, - i40e_aqc_opc_add_vlan = 0x0252, - i40e_aqc_opc_remove_vlan = 0x0253, - i40e_aqc_opc_set_vsi_promiscuous_modes = 0x0254, - i40e_aqc_opc_add_tag = 0x0255, - i40e_aqc_opc_remove_tag = 0x0256, - i40e_aqc_opc_add_multicast_etag = 0x0257, - i40e_aqc_opc_remove_multicast_etag = 0x0258, - i40e_aqc_opc_update_tag = 0x0259, - i40e_aqc_opc_add_control_packet_filter = 0x025A, - i40e_aqc_opc_remove_control_packet_filter = 0x025B, - i40e_aqc_opc_add_cloud_filters = 0x025C, - i40e_aqc_opc_remove_cloud_filters = 0x025D, - - i40e_aqc_opc_add_mirror_rule = 0x0260, - i40e_aqc_opc_delete_mirror_rule = 0x0261, + i40e_aqc_opc_get_switch_config = 0x0200, + i40e_aqc_opc_add_statistics = 0x0201, + i40e_aqc_opc_remove_statistics = 0x0202, + i40e_aqc_opc_set_port_parameters = 0x0203, + i40e_aqc_opc_get_switch_resource_alloc = 0x0204, + + i40e_aqc_opc_add_vsi = 0x0210, + i40e_aqc_opc_update_vsi_parameters = 0x0211, + i40e_aqc_opc_get_vsi_parameters = 0x0212, + + i40e_aqc_opc_add_pv = 0x0220, + i40e_aqc_opc_update_pv_parameters = 0x0221, + i40e_aqc_opc_get_pv_parameters = 0x0222, + + i40e_aqc_opc_add_veb = 0x0230, + i40e_aqc_opc_update_veb_parameters = 0x0231, + i40e_aqc_opc_get_veb_parameters = 0x0232, + + i40e_aqc_opc_delete_element = 0x0243, + + i40e_aqc_opc_add_macvlan = 0x0250, + i40e_aqc_opc_remove_macvlan = 0x0251, + i40e_aqc_opc_add_vlan = 0x0252, + i40e_aqc_opc_remove_vlan = 0x0253, + i40e_aqc_opc_set_vsi_promiscuous_modes = 0x0254, + i40e_aqc_opc_add_tag = 0x0255, + i40e_aqc_opc_remove_tag = 0x0256, + i40e_aqc_opc_add_multicast_etag = 0x0257, + i40e_aqc_opc_remove_multicast_etag = 0x0258, + i40e_aqc_opc_update_tag = 0x0259, + i40e_aqc_opc_add_control_packet_filter = 0x025A, + i40e_aqc_opc_remove_control_packet_filter = 0x025B, + i40e_aqc_opc_add_cloud_filters = 0x025C, + i40e_aqc_opc_remove_cloud_filters = 0x025D, + + i40e_aqc_opc_add_mirror_rule = 0x0260, + i40e_aqc_opc_delete_mirror_rule = 0x0261, /* DCB commands */ - i40e_aqc_opc_dcb_ignore_pfc = 0x0301, - i40e_aqc_opc_dcb_updated = 0x0302, + i40e_aqc_opc_dcb_ignore_pfc = 0x0301, + i40e_aqc_opc_dcb_updated = 0x0302, /* TX scheduler */ - i40e_aqc_opc_configure_vsi_bw_limit = 0x0400, - i40e_aqc_opc_configure_vsi_ets_sla_bw_limit = 0x0406, - i40e_aqc_opc_configure_vsi_tc_bw = 0x0407, - i40e_aqc_opc_query_vsi_bw_config = 0x0408, - i40e_aqc_opc_query_vsi_ets_sla_config = 0x040A, - i40e_aqc_opc_configure_switching_comp_bw_limit = 0x0410, - - i40e_aqc_opc_enable_switching_comp_ets = 0x0413, - i40e_aqc_opc_modify_switching_comp_ets = 0x0414, - i40e_aqc_opc_disable_switching_comp_ets = 0x0415, - i40e_aqc_opc_configure_switching_comp_ets_bw_limit = 0x0416, - i40e_aqc_opc_configure_switching_comp_bw_config = 0x0417, - i40e_aqc_opc_query_switching_comp_ets_config = 0x0418, - i40e_aqc_opc_query_port_ets_config = 0x0419, - i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, - i40e_aqc_opc_suspend_port_tx = 0x041B, - i40e_aqc_opc_resume_port_tx = 0x041C, - i40e_aqc_opc_configure_partition_bw = 0x041D, + i40e_aqc_opc_configure_vsi_bw_limit = 0x0400, + i40e_aqc_opc_configure_vsi_ets_sla_bw_limit = 0x0406, + i40e_aqc_opc_configure_vsi_tc_bw = 0x0407, + i40e_aqc_opc_query_vsi_bw_config = 0x0408, + i40e_aqc_opc_query_vsi_ets_sla_config = 0x040A, + i40e_aqc_opc_configure_switching_comp_bw_limit = 0x0410, + + i40e_aqc_opc_enable_switching_comp_ets = 0x0413, + i40e_aqc_opc_modify_switching_comp_ets = 0x0414, + i40e_aqc_opc_disable_switching_comp_ets = 0x0415, + i40e_aqc_opc_configure_switching_comp_ets_bw_limit = 0x0416, + i40e_aqc_opc_configure_switching_comp_bw_config = 0x0417, + i40e_aqc_opc_query_switching_comp_ets_config = 0x0418, + i40e_aqc_opc_query_port_ets_config = 0x0419, + i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, + i40e_aqc_opc_suspend_port_tx = 0x041B, + i40e_aqc_opc_resume_port_tx = 0x041C, + i40e_aqc_opc_configure_partition_bw = 0x041D, /* hmc */ - i40e_aqc_opc_query_hmc_resource_profile = 0x0500, - i40e_aqc_opc_set_hmc_resource_profile = 0x0501, + i40e_aqc_opc_query_hmc_resource_profile = 0x0500, + i40e_aqc_opc_set_hmc_resource_profile = 0x0501, /* phy commands*/ - i40e_aqc_opc_get_phy_abilities = 0x0600, - i40e_aqc_opc_set_phy_config = 0x0601, - i40e_aqc_opc_set_mac_config = 0x0603, - i40e_aqc_opc_set_link_restart_an = 0x0605, - i40e_aqc_opc_get_link_status = 0x0607, - i40e_aqc_opc_set_phy_int_mask = 0x0613, - i40e_aqc_opc_get_local_advt_reg = 0x0614, - i40e_aqc_opc_set_local_advt_reg = 0x0615, - i40e_aqc_opc_get_partner_advt = 0x0616, - i40e_aqc_opc_set_lb_modes = 0x0618, - i40e_aqc_opc_get_phy_wol_caps = 0x0621, - i40e_aqc_opc_set_phy_debug = 0x0622, - i40e_aqc_opc_upload_ext_phy_fm = 0x0625, + i40e_aqc_opc_get_phy_abilities = 0x0600, + i40e_aqc_opc_set_phy_config = 0x0601, + i40e_aqc_opc_set_mac_config = 0x0603, + i40e_aqc_opc_set_link_restart_an = 0x0605, + i40e_aqc_opc_get_link_status = 0x0607, + i40e_aqc_opc_set_phy_int_mask = 0x0613, + i40e_aqc_opc_get_local_advt_reg = 0x0614, + i40e_aqc_opc_set_local_advt_reg = 0x0615, + i40e_aqc_opc_get_partner_advt = 0x0616, + i40e_aqc_opc_set_lb_modes = 0x0618, + i40e_aqc_opc_get_phy_wol_caps = 0x0621, + i40e_aqc_opc_set_phy_debug = 0x0622, + i40e_aqc_opc_upload_ext_phy_fm = 0x0625, /* NVM commands */ - i40e_aqc_opc_nvm_read = 0x0701, - i40e_aqc_opc_nvm_erase = 0x0702, - i40e_aqc_opc_nvm_update = 0x0703, - i40e_aqc_opc_nvm_config_read = 0x0704, - i40e_aqc_opc_nvm_config_write = 0x0705, + i40e_aqc_opc_nvm_read = 0x0701, + i40e_aqc_opc_nvm_erase = 0x0702, + i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_config_read = 0x0704, + i40e_aqc_opc_nvm_config_write = 0x0705, /* virtualization commands */ - i40e_aqc_opc_send_msg_to_pf = 0x0801, - i40e_aqc_opc_send_msg_to_vf = 0x0802, - i40e_aqc_opc_send_msg_to_peer = 0x0803, + i40e_aqc_opc_send_msg_to_pf = 0x0801, + i40e_aqc_opc_send_msg_to_vf = 0x0802, + i40e_aqc_opc_send_msg_to_peer = 0x0803, /* alternate structure */ - i40e_aqc_opc_alternate_write = 0x0900, - i40e_aqc_opc_alternate_write_indirect = 0x0901, - i40e_aqc_opc_alternate_read = 0x0902, - i40e_aqc_opc_alternate_read_indirect = 0x0903, - i40e_aqc_opc_alternate_write_done = 0x0904, - i40e_aqc_opc_alternate_set_mode = 0x0905, - i40e_aqc_opc_alternate_clear_port = 0x0906, + i40e_aqc_opc_alternate_write = 0x0900, + i40e_aqc_opc_alternate_write_indirect = 0x0901, + i40e_aqc_opc_alternate_read = 0x0902, + i40e_aqc_opc_alternate_read_indirect = 0x0903, + i40e_aqc_opc_alternate_write_done = 0x0904, + i40e_aqc_opc_alternate_set_mode = 0x0905, + i40e_aqc_opc_alternate_clear_port = 0x0906, /* LLDP commands */ - i40e_aqc_opc_lldp_get_mib = 0x0A00, - i40e_aqc_opc_lldp_update_mib = 0x0A01, - i40e_aqc_opc_lldp_add_tlv = 0x0A02, - i40e_aqc_opc_lldp_update_tlv = 0x0A03, - i40e_aqc_opc_lldp_delete_tlv = 0x0A04, - i40e_aqc_opc_lldp_stop = 0x0A05, - i40e_aqc_opc_lldp_start = 0x0A06, + i40e_aqc_opc_lldp_get_mib = 0x0A00, + i40e_aqc_opc_lldp_update_mib = 0x0A01, + i40e_aqc_opc_lldp_add_tlv = 0x0A02, + i40e_aqc_opc_lldp_update_tlv = 0x0A03, + i40e_aqc_opc_lldp_delete_tlv = 0x0A04, + i40e_aqc_opc_lldp_stop = 0x0A05, + i40e_aqc_opc_lldp_start = 0x0A06, /* Tunnel commands */ - i40e_aqc_opc_add_udp_tunnel = 0x0B00, - i40e_aqc_opc_del_udp_tunnel = 0x0B01, - i40e_aqc_opc_tunnel_key_structure = 0x0B10, + i40e_aqc_opc_add_udp_tunnel = 0x0B00, + i40e_aqc_opc_del_udp_tunnel = 0x0B01, + i40e_aqc_opc_tunnel_key_structure = 0x0B10, /* Async Events */ - i40e_aqc_opc_event_lan_overflow = 0x1001, + i40e_aqc_opc_event_lan_overflow = 0x1001, /* OEM commands */ - i40e_aqc_opc_oem_parameter_change = 0xFE00, - i40e_aqc_opc_oem_device_status_change = 0xFE01, + i40e_aqc_opc_oem_parameter_change = 0xFE00, + i40e_aqc_opc_oem_device_status_change = 0xFE01, /* debug commands */ - i40e_aqc_opc_debug_get_deviceid = 0xFF00, - i40e_aqc_opc_debug_set_mode = 0xFF01, - i40e_aqc_opc_debug_read_reg = 0xFF03, - i40e_aqc_opc_debug_write_reg = 0xFF04, - i40e_aqc_opc_debug_modify_reg = 0xFF07, - i40e_aqc_opc_debug_dump_internals = 0xFF08, - i40e_aqc_opc_debug_modify_internals = 0xFF09, + i40e_aqc_opc_debug_get_deviceid = 0xFF00, + i40e_aqc_opc_debug_set_mode = 0xFF01, + i40e_aqc_opc_debug_read_reg = 0xFF03, + i40e_aqc_opc_debug_write_reg = 0xFF04, + i40e_aqc_opc_debug_modify_reg = 0xFF07, + i40e_aqc_opc_debug_dump_internals = 0xFF08, + i40e_aqc_opc_debug_modify_internals = 0xFF09, }; /* command structures and indirect data structures */ @@ -302,7 +302,7 @@ enum i40e_admin_queue_opc { /* This macro is used extensively to ensure that command structures are 16 * bytes in length as they have to map to the raw array of that size. */ -#define I40E_CHECK_CMD_LENGTH(X) I40E_CHECK_STRUCT_LEN(16, X) +#define I40E_CHECK_CMD_LENGTH(X) I40E_CHECK_STRUCT_LEN(16, X) /* internal (0x00XX) commands */ @@ -320,22 +320,22 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_version); /* Send driver version (indirect 0x0002) */ struct i40e_aqc_driver_version { - u8 driver_major_ver; - u8 driver_minor_ver; - u8 driver_build_ver; - u8 driver_subbuild_ver; - u8 reserved[4]; - __le32 address_high; - __le32 address_low; + u8 driver_major_ver; + u8 driver_minor_ver; + u8 driver_build_ver; + u8 driver_subbuild_ver; + u8 reserved[4]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_driver_version); /* Queue Shutdown (direct 0x0003) */ struct i40e_aqc_queue_shutdown { - __le32 driver_unloading; -#define I40E_AQ_DRIVER_UNLOADING 0x1 - u8 reserved[12]; + __le32 driver_unloading; +#define I40E_AQ_DRIVER_UNLOADING 0x1 + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_queue_shutdown); @@ -351,19 +351,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_pf_context); /* Request resource ownership (direct 0x0008) * Release resource ownership (direct 0x0009) */ -#define I40E_AQ_RESOURCE_NVM 1 -#define I40E_AQ_RESOURCE_SDP 2 -#define I40E_AQ_RESOURCE_ACCESS_READ 1 -#define I40E_AQ_RESOURCE_ACCESS_WRITE 2 -#define I40E_AQ_RESOURCE_NVM_READ_TIMEOUT 3000 -#define I40E_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000 +#define I40E_AQ_RESOURCE_NVM 1 +#define I40E_AQ_RESOURCE_SDP 2 +#define I40E_AQ_RESOURCE_ACCESS_READ 1 +#define I40E_AQ_RESOURCE_ACCESS_WRITE 2 +#define I40E_AQ_RESOURCE_NVM_READ_TIMEOUT 3000 +#define I40E_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000 struct i40e_aqc_request_resource { - __le16 resource_id; - __le16 access_type; - __le32 timeout; - __le32 resource_number; - u8 reserved[4]; + __le16 resource_id; + __le16 access_type; + __le32 timeout; + __le32 resource_number; + u8 reserved[4]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_request_resource); @@ -373,7 +373,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_request_resource); */ struct i40e_aqc_list_capabilites { u8 command_flags; -#define I40E_AQ_LIST_CAP_PF_INDEX_EN 1 +#define I40E_AQ_LIST_CAP_PF_INDEX_EN 1 u8 pf_index; u8 reserved[2]; __le32 count; @@ -384,123 +384,123 @@ struct i40e_aqc_list_capabilites { I40E_CHECK_CMD_LENGTH(i40e_aqc_list_capabilites); struct i40e_aqc_list_capabilities_element_resp { - __le16 id; - u8 major_rev; - u8 minor_rev; - __le32 number; - __le32 logical_id; - __le32 phys_id; - u8 reserved[16]; + __le16 id; + u8 major_rev; + u8 minor_rev; + __le32 number; + __le32 logical_id; + __le32 phys_id; + u8 reserved[16]; }; /* list of caps */ -#define I40E_AQ_CAP_ID_SWITCH_MODE 0x0001 -#define I40E_AQ_CAP_ID_MNG_MODE 0x0002 -#define I40E_AQ_CAP_ID_NPAR_ACTIVE 0x0003 -#define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004 -#define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005 -#define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006 -#define I40E_AQ_CAP_ID_SRIOV 0x0012 -#define I40E_AQ_CAP_ID_VF 0x0013 -#define I40E_AQ_CAP_ID_VMDQ 0x0014 -#define I40E_AQ_CAP_ID_8021QBG 0x0015 -#define I40E_AQ_CAP_ID_8021QBR 0x0016 -#define I40E_AQ_CAP_ID_VSI 0x0017 -#define I40E_AQ_CAP_ID_DCB 0x0018 -#define I40E_AQ_CAP_ID_FCOE 0x0021 -#define I40E_AQ_CAP_ID_RSS 0x0040 -#define I40E_AQ_CAP_ID_RXQ 0x0041 -#define I40E_AQ_CAP_ID_TXQ 0x0042 -#define I40E_AQ_CAP_ID_MSIX 0x0043 -#define I40E_AQ_CAP_ID_VF_MSIX 0x0044 -#define I40E_AQ_CAP_ID_FLOW_DIRECTOR 0x0045 -#define I40E_AQ_CAP_ID_1588 0x0046 -#define I40E_AQ_CAP_ID_IWARP 0x0051 -#define I40E_AQ_CAP_ID_LED 0x0061 -#define I40E_AQ_CAP_ID_SDP 0x0062 -#define I40E_AQ_CAP_ID_MDIO 0x0063 -#define I40E_AQ_CAP_ID_FLEX10 0x00F1 -#define I40E_AQ_CAP_ID_CEM 0x00F2 +#define I40E_AQ_CAP_ID_SWITCH_MODE 0x0001 +#define I40E_AQ_CAP_ID_MNG_MODE 0x0002 +#define I40E_AQ_CAP_ID_NPAR_ACTIVE 0x0003 +#define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004 +#define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005 +#define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006 +#define I40E_AQ_CAP_ID_SRIOV 0x0012 +#define I40E_AQ_CAP_ID_VF 0x0013 +#define I40E_AQ_CAP_ID_VMDQ 0x0014 +#define I40E_AQ_CAP_ID_8021QBG 0x0015 +#define I40E_AQ_CAP_ID_8021QBR 0x0016 +#define I40E_AQ_CAP_ID_VSI 0x0017 +#define I40E_AQ_CAP_ID_DCB 0x0018 +#define I40E_AQ_CAP_ID_FCOE 0x0021 +#define I40E_AQ_CAP_ID_RSS 0x0040 +#define I40E_AQ_CAP_ID_RXQ 0x0041 +#define I40E_AQ_CAP_ID_TXQ 0x0042 +#define I40E_AQ_CAP_ID_MSIX 0x0043 +#define I40E_AQ_CAP_ID_VF_MSIX 0x0044 +#define I40E_AQ_CAP_ID_FLOW_DIRECTOR 0x0045 +#define I40E_AQ_CAP_ID_1588 0x0046 +#define I40E_AQ_CAP_ID_IWARP 0x0051 +#define I40E_AQ_CAP_ID_LED 0x0061 +#define I40E_AQ_CAP_ID_SDP 0x0062 +#define I40E_AQ_CAP_ID_MDIO 0x0063 +#define I40E_AQ_CAP_ID_FLEX10 0x00F1 +#define I40E_AQ_CAP_ID_CEM 0x00F2 /* Set CPPM Configuration (direct 0x0103) */ struct i40e_aqc_cppm_configuration { - __le16 command_flags; -#define I40E_AQ_CPPM_EN_LTRC 0x0800 -#define I40E_AQ_CPPM_EN_DMCTH 0x1000 -#define I40E_AQ_CPPM_EN_DMCTLX 0x2000 -#define I40E_AQ_CPPM_EN_HPTC 0x4000 -#define I40E_AQ_CPPM_EN_DMARC 0x8000 - __le16 ttlx; - __le32 dmacr; - __le16 dmcth; - u8 hptc; - u8 reserved; - __le32 pfltrc; + __le16 command_flags; +#define I40E_AQ_CPPM_EN_LTRC 0x0800 +#define I40E_AQ_CPPM_EN_DMCTH 0x1000 +#define I40E_AQ_CPPM_EN_DMCTLX 0x2000 +#define I40E_AQ_CPPM_EN_HPTC 0x4000 +#define I40E_AQ_CPPM_EN_DMARC 0x8000 + __le16 ttlx; + __le32 dmacr; + __le16 dmcth; + u8 hptc; + u8 reserved; + __le32 pfltrc; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration); /* Set ARP Proxy command / response (indirect 0x0104) */ struct i40e_aqc_arp_proxy_data { - __le16 command_flags; -#define I40E_AQ_ARP_INIT_IPV4 0x0008 -#define I40E_AQ_ARP_UNSUP_CTL 0x0010 -#define I40E_AQ_ARP_ENA 0x0020 -#define I40E_AQ_ARP_ADD_IPV4 0x0040 -#define I40E_AQ_ARP_DEL_IPV4 0x0080 - __le16 table_id; - __le32 pfpm_proxyfc; - __le32 ip_addr; - u8 mac_addr[6]; + __le16 command_flags; +#define I40E_AQ_ARP_INIT_IPV4 0x0008 +#define I40E_AQ_ARP_UNSUP_CTL 0x0010 +#define I40E_AQ_ARP_ENA 0x0020 +#define I40E_AQ_ARP_ADD_IPV4 0x0040 +#define I40E_AQ_ARP_DEL_IPV4 0x0080 + __le16 table_id; + __le32 pfpm_proxyfc; + __le32 ip_addr; + u8 mac_addr[6]; }; /* Set NS Proxy Table Entry Command (indirect 0x0105) */ struct i40e_aqc_ns_proxy_data { - __le16 table_idx_mac_addr_0; - __le16 table_idx_mac_addr_1; - __le16 table_idx_ipv6_0; - __le16 table_idx_ipv6_1; - __le16 control; -#define I40E_AQ_NS_PROXY_ADD_0 0x0100 -#define I40E_AQ_NS_PROXY_DEL_0 0x0200 -#define I40E_AQ_NS_PROXY_ADD_1 0x0400 -#define I40E_AQ_NS_PROXY_DEL_1 0x0800 -#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 -#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 -#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 -#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 -#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 -#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 -#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 - u8 mac_addr_0[6]; - u8 mac_addr_1[6]; - u8 local_mac_addr[6]; - u8 ipv6_addr_0[16]; /* Warning! spec specifies BE byte order */ - u8 ipv6_addr_1[16]; + __le16 table_idx_mac_addr_0; + __le16 table_idx_mac_addr_1; + __le16 table_idx_ipv6_0; + __le16 table_idx_ipv6_1; + __le16 control; +#define I40E_AQ_NS_PROXY_ADD_0 0x0100 +#define I40E_AQ_NS_PROXY_DEL_0 0x0200 +#define I40E_AQ_NS_PROXY_ADD_1 0x0400 +#define I40E_AQ_NS_PROXY_DEL_1 0x0800 +#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 +#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 +#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 +#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 +#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 +#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 +#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 + u8 mac_addr_0[6]; + u8 mac_addr_1[6]; + u8 local_mac_addr[6]; + u8 ipv6_addr_0[16]; /* Warning! spec specifies BE byte order */ + u8 ipv6_addr_1[16]; }; /* Manage LAA Command (0x0106) - obsolete */ struct i40e_aqc_mng_laa { __le16 command_flags; -#define I40E_AQ_LAA_FLAG_WR 0x8000 - u8 reserved[2]; - __le32 sal; - __le16 sah; - u8 reserved2[6]; +#define I40E_AQ_LAA_FLAG_WR 0x8000 + u8 reserved[2]; + __le32 sal; + __le16 sah; + u8 reserved2[6]; }; /* Manage MAC Address Read Command (indirect 0x0107) */ struct i40e_aqc_mac_address_read { __le16 command_flags; -#define I40E_AQC_LAN_ADDR_VALID 0x10 -#define I40E_AQC_SAN_ADDR_VALID 0x20 -#define I40E_AQC_PORT_ADDR_VALID 0x40 -#define I40E_AQC_WOL_ADDR_VALID 0x80 -#define I40E_AQC_ADDR_VALID_MASK 0xf0 - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; +#define I40E_AQC_LAN_ADDR_VALID 0x10 +#define I40E_AQC_SAN_ADDR_VALID 0x20 +#define I40E_AQC_PORT_ADDR_VALID 0x40 +#define I40E_AQC_WOL_ADDR_VALID 0x80 +#define I40E_AQC_ADDR_VALID_MASK 0xf0 + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_read); @@ -516,14 +516,14 @@ I40E_CHECK_STRUCT_LEN(24, i40e_aqc_mac_address_read_data); /* Manage MAC Address Write Command (0x0108) */ struct i40e_aqc_mac_address_write { - __le16 command_flags; -#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000 -#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000 -#define I40E_AQC_WRITE_TYPE_PORT 0x8000 -#define I40E_AQC_WRITE_TYPE_MASK 0xc000 - __le16 mac_sah; - __le32 mac_sal; - u8 reserved[8]; + __le16 command_flags; +#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000 +#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000 +#define I40E_AQC_WRITE_TYPE_PORT 0x8000 +#define I40E_AQC_WRITE_TYPE_MASK 0xc000 + __le16 mac_sah; + __le32 mac_sal; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_write); @@ -544,10 +544,10 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe); * command */ struct i40e_aqc_switch_seid { - __le16 seid; - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; + __le16 seid; + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_switch_seid); @@ -556,34 +556,34 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_switch_seid); * uses i40e_aqc_switch_seid for the descriptor */ struct i40e_aqc_get_switch_config_header_resp { - __le16 num_reported; - __le16 num_total; - u8 reserved[12]; + __le16 num_reported; + __le16 num_total; + u8 reserved[12]; }; struct i40e_aqc_switch_config_element_resp { - u8 element_type; -#define I40E_AQ_SW_ELEM_TYPE_MAC 1 -#define I40E_AQ_SW_ELEM_TYPE_PF 2 -#define I40E_AQ_SW_ELEM_TYPE_VF 3 -#define I40E_AQ_SW_ELEM_TYPE_EMP 4 -#define I40E_AQ_SW_ELEM_TYPE_BMC 5 -#define I40E_AQ_SW_ELEM_TYPE_PV 16 -#define I40E_AQ_SW_ELEM_TYPE_VEB 17 -#define I40E_AQ_SW_ELEM_TYPE_PA 18 -#define I40E_AQ_SW_ELEM_TYPE_VSI 19 - u8 revision; -#define I40E_AQ_SW_ELEM_REV_1 1 - __le16 seid; - __le16 uplink_seid; - __le16 downlink_seid; - u8 reserved[3]; - u8 connection_type; -#define I40E_AQ_CONN_TYPE_REGULAR 0x1 -#define I40E_AQ_CONN_TYPE_DEFAULT 0x2 -#define I40E_AQ_CONN_TYPE_CASCADED 0x3 - __le16 scheduler_id; - __le16 element_info; + u8 element_type; +#define I40E_AQ_SW_ELEM_TYPE_MAC 1 +#define I40E_AQ_SW_ELEM_TYPE_PF 2 +#define I40E_AQ_SW_ELEM_TYPE_VF 3 +#define I40E_AQ_SW_ELEM_TYPE_EMP 4 +#define I40E_AQ_SW_ELEM_TYPE_BMC 5 +#define I40E_AQ_SW_ELEM_TYPE_PV 16 +#define I40E_AQ_SW_ELEM_TYPE_VEB 17 +#define I40E_AQ_SW_ELEM_TYPE_PA 18 +#define I40E_AQ_SW_ELEM_TYPE_VSI 19 + u8 revision; +#define I40E_AQ_SW_ELEM_REV_1 1 + __le16 seid; + __le16 uplink_seid; + __le16 downlink_seid; + u8 reserved[3]; + u8 connection_type; +#define I40E_AQ_CONN_TYPE_REGULAR 0x1 +#define I40E_AQ_CONN_TYPE_DEFAULT 0x2 +#define I40E_AQ_CONN_TYPE_CASCADED 0x3 + __le16 scheduler_id; + __le16 element_info; }; /* Get Switch Configuration (indirect 0x0200) @@ -591,73 +591,73 @@ struct i40e_aqc_switch_config_element_resp { * the first in the array is the header, remainder are elements */ struct i40e_aqc_get_switch_config_resp { - struct i40e_aqc_get_switch_config_header_resp header; - struct i40e_aqc_switch_config_element_resp element[1]; + struct i40e_aqc_get_switch_config_header_resp header; + struct i40e_aqc_switch_config_element_resp element[1]; }; /* Add Statistics (direct 0x0201) * Remove Statistics (direct 0x0202) */ struct i40e_aqc_add_remove_statistics { - __le16 seid; - __le16 vlan; - __le16 stat_index; - u8 reserved[10]; + __le16 seid; + __le16 vlan; + __le16 stat_index; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_statistics); /* Set Port Parameters command (direct 0x0203) */ struct i40e_aqc_set_port_parameters { - __le16 command_flags; -#define I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1 -#define I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */ -#define I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4 - __le16 bad_frame_vsi; - __le16 default_seid; /* reserved for command */ - u8 reserved[10]; + __le16 command_flags; +#define I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1 +#define I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */ +#define I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4 + __le16 bad_frame_vsi; + __le16 default_seid; /* reserved for command */ + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_port_parameters); /* Get Switch Resource Allocation (indirect 0x0204) */ struct i40e_aqc_get_switch_resource_alloc { - u8 num_entries; /* reserved for command */ - u8 reserved[7]; - __le32 addr_high; - __le32 addr_low; + u8 num_entries; /* reserved for command */ + u8 reserved[7]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_switch_resource_alloc); /* expect an array of these structs in the response buffer */ struct i40e_aqc_switch_resource_alloc_element_resp { - u8 resource_type; -#define I40E_AQ_RESOURCE_TYPE_VEB 0x0 -#define I40E_AQ_RESOURCE_TYPE_VSI 0x1 -#define I40E_AQ_RESOURCE_TYPE_MACADDR 0x2 -#define I40E_AQ_RESOURCE_TYPE_STAG 0x3 -#define I40E_AQ_RESOURCE_TYPE_ETAG 0x4 -#define I40E_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5 -#define I40E_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6 -#define I40E_AQ_RESOURCE_TYPE_VLAN 0x7 -#define I40E_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8 -#define I40E_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9 -#define I40E_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA -#define I40E_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB -#define I40E_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC -#define I40E_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD -#define I40E_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF -#define I40E_AQ_RESOURCE_TYPE_IP_FILTERS 0x10 -#define I40E_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11 -#define I40E_AQ_RESOURCE_TYPE_VN2_KEYS 0x12 -#define I40E_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13 - u8 reserved1; - __le16 guaranteed; - __le16 total; - __le16 used; - __le16 total_unalloced; - u8 reserved2[6]; + u8 resource_type; +#define I40E_AQ_RESOURCE_TYPE_VEB 0x0 +#define I40E_AQ_RESOURCE_TYPE_VSI 0x1 +#define I40E_AQ_RESOURCE_TYPE_MACADDR 0x2 +#define I40E_AQ_RESOURCE_TYPE_STAG 0x3 +#define I40E_AQ_RESOURCE_TYPE_ETAG 0x4 +#define I40E_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5 +#define I40E_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6 +#define I40E_AQ_RESOURCE_TYPE_VLAN 0x7 +#define I40E_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8 +#define I40E_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9 +#define I40E_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA +#define I40E_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB +#define I40E_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC +#define I40E_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD +#define I40E_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF +#define I40E_AQ_RESOURCE_TYPE_IP_FILTERS 0x10 +#define I40E_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11 +#define I40E_AQ_RESOURCE_TYPE_VN2_KEYS 0x12 +#define I40E_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13 + u8 reserved1; + __le16 guaranteed; + __le16 total; + __le16 used; + __le16 total_unalloced; + u8 reserved2[6]; }; /* Add VSI (indirect 0x0210) @@ -671,24 +671,24 @@ struct i40e_aqc_switch_resource_alloc_element_resp { * uses the same completion and data structure as Add VSI */ struct i40e_aqc_add_get_update_vsi { - __le16 uplink_seid; - u8 connection_type; -#define I40E_AQ_VSI_CONN_TYPE_NORMAL 0x1 -#define I40E_AQ_VSI_CONN_TYPE_DEFAULT 0x2 -#define I40E_AQ_VSI_CONN_TYPE_CASCADED 0x3 - u8 reserved1; - u8 vf_id; - u8 reserved2; - __le16 vsi_flags; -#define I40E_AQ_VSI_TYPE_SHIFT 0x0 -#define I40E_AQ_VSI_TYPE_MASK (0x3 << I40E_AQ_VSI_TYPE_SHIFT) -#define I40E_AQ_VSI_TYPE_VF 0x0 -#define I40E_AQ_VSI_TYPE_VMDQ2 0x1 -#define I40E_AQ_VSI_TYPE_PF 0x2 -#define I40E_AQ_VSI_TYPE_EMP_MNG 0x3 -#define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4 - __le32 addr_high; - __le32 addr_low; + __le16 uplink_seid; + u8 connection_type; +#define I40E_AQ_VSI_CONN_TYPE_NORMAL 0x1 +#define I40E_AQ_VSI_CONN_TYPE_DEFAULT 0x2 +#define I40E_AQ_VSI_CONN_TYPE_CASCADED 0x3 + u8 reserved1; + u8 vf_id; + u8 reserved2; + __le16 vsi_flags; +#define I40E_AQ_VSI_TYPE_SHIFT 0x0 +#define I40E_AQ_VSI_TYPE_MASK (0x3 << I40E_AQ_VSI_TYPE_SHIFT) +#define I40E_AQ_VSI_TYPE_VF 0x0 +#define I40E_AQ_VSI_TYPE_VMDQ2 0x1 +#define I40E_AQ_VSI_TYPE_PF 0x2 +#define I40E_AQ_VSI_TYPE_EMP_MNG 0x3 +#define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4 + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_get_update_vsi); @@ -706,121 +706,121 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_get_update_vsi_completion); struct i40e_aqc_vsi_properties_data { /* first 96 byte are written by SW */ - __le16 valid_sections; -#define I40E_AQ_VSI_PROP_SWITCH_VALID 0x0001 -#define I40E_AQ_VSI_PROP_SECURITY_VALID 0x0002 -#define I40E_AQ_VSI_PROP_VLAN_VALID 0x0004 -#define I40E_AQ_VSI_PROP_CAS_PV_VALID 0x0008 -#define I40E_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010 -#define I40E_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020 -#define I40E_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040 -#define I40E_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080 -#define I40E_AQ_VSI_PROP_OUTER_UP_VALID 0x0100 -#define I40E_AQ_VSI_PROP_SCHED_VALID 0x0200 + __le16 valid_sections; +#define I40E_AQ_VSI_PROP_SWITCH_VALID 0x0001 +#define I40E_AQ_VSI_PROP_SECURITY_VALID 0x0002 +#define I40E_AQ_VSI_PROP_VLAN_VALID 0x0004 +#define I40E_AQ_VSI_PROP_CAS_PV_VALID 0x0008 +#define I40E_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010 +#define I40E_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020 +#define I40E_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040 +#define I40E_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080 +#define I40E_AQ_VSI_PROP_OUTER_UP_VALID 0x0100 +#define I40E_AQ_VSI_PROP_SCHED_VALID 0x0200 /* switch section */ - __le16 switch_id; /* 12bit id combined with flags below */ -#define I40E_AQ_VSI_SW_ID_SHIFT 0x0000 -#define I40E_AQ_VSI_SW_ID_MASK (0xFFF << I40E_AQ_VSI_SW_ID_SHIFT) -#define I40E_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000 -#define I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000 -#define I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000 - u8 sw_reserved[2]; + __le16 switch_id; /* 12bit id combined with flags below */ +#define I40E_AQ_VSI_SW_ID_SHIFT 0x0000 +#define I40E_AQ_VSI_SW_ID_MASK (0xFFF << I40E_AQ_VSI_SW_ID_SHIFT) +#define I40E_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000 +#define I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000 +#define I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000 + u8 sw_reserved[2]; /* security section */ - u8 sec_flags; -#define I40E_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01 -#define I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02 -#define I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04 - u8 sec_reserved; + u8 sec_flags; +#define I40E_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01 +#define I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02 +#define I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04 + u8 sec_reserved; /* VLAN section */ - __le16 pvid; /* VLANS include priority bits */ - __le16 fcoe_pvid; - u8 port_vlan_flags; -#define I40E_AQ_VSI_PVLAN_MODE_SHIFT 0x00 -#define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \ - I40E_AQ_VSI_PVLAN_MODE_SHIFT) -#define I40E_AQ_VSI_PVLAN_MODE_TAGGED 0x01 -#define I40E_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02 -#define I40E_AQ_VSI_PVLAN_MODE_ALL 0x03 -#define I40E_AQ_VSI_PVLAN_INSERT_PVID 0x04 -#define I40E_AQ_VSI_PVLAN_EMOD_SHIFT 0x03 -#define I40E_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \ - I40E_AQ_VSI_PVLAN_EMOD_SHIFT) -#define I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0 -#define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08 -#define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10 -#define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18 - u8 pvlan_reserved[3]; + __le16 pvid; /* VLANS include priority bits */ + __le16 fcoe_pvid; + u8 port_vlan_flags; +#define I40E_AQ_VSI_PVLAN_MODE_SHIFT 0x00 +#define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \ + I40E_AQ_VSI_PVLAN_MODE_SHIFT) +#define I40E_AQ_VSI_PVLAN_MODE_TAGGED 0x01 +#define I40E_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02 +#define I40E_AQ_VSI_PVLAN_MODE_ALL 0x03 +#define I40E_AQ_VSI_PVLAN_INSERT_PVID 0x04 +#define I40E_AQ_VSI_PVLAN_EMOD_SHIFT 0x03 +#define I40E_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \ + I40E_AQ_VSI_PVLAN_EMOD_SHIFT) +#define I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0 +#define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08 +#define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10 +#define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18 + u8 pvlan_reserved[3]; /* ingress egress up sections */ - __le32 ingress_table; /* bitmap, 3 bits per up */ -#define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0 -#define I40E_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP0_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP1_SHIFT 3 -#define I40E_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP1_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP2_SHIFT 6 -#define I40E_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP2_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP3_SHIFT 9 -#define I40E_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP3_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP4_SHIFT 12 -#define I40E_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP4_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP5_SHIFT 15 -#define I40E_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP5_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP6_SHIFT 18 -#define I40E_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP6_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP7_SHIFT 21 -#define I40E_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP7_SHIFT) - __le32 egress_table; /* same defines as for ingress table */ + __le32 ingress_table; /* bitmap, 3 bits per up */ +#define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0 +#define I40E_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP0_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP1_SHIFT 3 +#define I40E_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP1_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP2_SHIFT 6 +#define I40E_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP2_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP3_SHIFT 9 +#define I40E_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP3_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP4_SHIFT 12 +#define I40E_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP4_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP5_SHIFT 15 +#define I40E_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP5_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP6_SHIFT 18 +#define I40E_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP6_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP7_SHIFT 21 +#define I40E_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP7_SHIFT) + __le32 egress_table; /* same defines as for ingress table */ /* cascaded PV section */ - __le16 cas_pv_tag; - u8 cas_pv_flags; -#define I40E_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00 -#define I40E_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \ - I40E_AQ_VSI_CAS_PV_TAGX_SHIFT) -#define I40E_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00 -#define I40E_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01 -#define I40E_AQ_VSI_CAS_PV_TAGX_COPY 0x02 -#define I40E_AQ_VSI_CAS_PV_INSERT_TAG 0x10 -#define I40E_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20 -#define I40E_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40 - u8 cas_pv_reserved; + __le16 cas_pv_tag; + u8 cas_pv_flags; +#define I40E_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00 +#define I40E_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \ + I40E_AQ_VSI_CAS_PV_TAGX_SHIFT) +#define I40E_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00 +#define I40E_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01 +#define I40E_AQ_VSI_CAS_PV_TAGX_COPY 0x02 +#define I40E_AQ_VSI_CAS_PV_INSERT_TAG 0x10 +#define I40E_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20 +#define I40E_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40 + u8 cas_pv_reserved; /* queue mapping section */ - __le16 mapping_flags; -#define I40E_AQ_VSI_QUE_MAP_CONTIG 0x0 -#define I40E_AQ_VSI_QUE_MAP_NONCONTIG 0x1 - __le16 queue_mapping[16]; -#define I40E_AQ_VSI_QUEUE_SHIFT 0x0 -#define I40E_AQ_VSI_QUEUE_MASK (0x7FF << I40E_AQ_VSI_QUEUE_SHIFT) - __le16 tc_mapping[8]; -#define I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT 0 -#define I40E_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \ - I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) -#define I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT 9 -#define I40E_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \ - I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT) + __le16 mapping_flags; +#define I40E_AQ_VSI_QUE_MAP_CONTIG 0x0 +#define I40E_AQ_VSI_QUE_MAP_NONCONTIG 0x1 + __le16 queue_mapping[16]; +#define I40E_AQ_VSI_QUEUE_SHIFT 0x0 +#define I40E_AQ_VSI_QUEUE_MASK (0x7FF << I40E_AQ_VSI_QUEUE_SHIFT) + __le16 tc_mapping[8]; +#define I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT 0 +#define I40E_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \ + I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) +#define I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT 9 +#define I40E_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \ + I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT) /* queueing option section */ - u8 queueing_opt_flags; -#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10 -#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20 - u8 queueing_opt_reserved[3]; + u8 queueing_opt_flags; +#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10 +#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20 + u8 queueing_opt_reserved[3]; /* scheduler section */ - u8 up_enable_bits; - u8 sched_reserved; + u8 up_enable_bits; + u8 sched_reserved; /* outer up section */ - __le32 outer_up_table; /* same structure and defines as ingress table */ - u8 cmd_reserved[8]; + __le32 outer_up_table; /* same structure and defines as ingress tbl */ + u8 cmd_reserved[8]; /* last 32 bytes are written by FW */ - __le16 qs_handle[8]; + __le16 qs_handle[8]; #define I40E_AQ_VSI_QS_HANDLE_INVALID 0xFFFF - __le16 stat_counter_idx; - __le16 sched_id; - u8 resp_reserved[12]; + __le16 stat_counter_idx; + __le16 sched_id; + u8 resp_reserved[12]; }; I40E_CHECK_STRUCT_LEN(128, i40e_aqc_vsi_properties_data); @@ -830,26 +830,26 @@ I40E_CHECK_STRUCT_LEN(128, i40e_aqc_vsi_properties_data); * (IS_CTRL_PORT only works on add PV) */ struct i40e_aqc_add_update_pv { - __le16 command_flags; -#define I40E_AQC_PV_FLAG_PV_TYPE 0x1 -#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2 -#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4 -#define I40E_AQC_PV_FLAG_IS_CTRL_PORT 0x8 - __le16 uplink_seid; - __le16 connected_seid; - u8 reserved[10]; + __le16 command_flags; +#define I40E_AQC_PV_FLAG_PV_TYPE 0x1 +#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2 +#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4 +#define I40E_AQC_PV_FLAG_IS_CTRL_PORT 0x8 + __le16 uplink_seid; + __le16 connected_seid; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv); struct i40e_aqc_add_update_pv_completion { /* reserved for update; for add also encodes error if rc == ENOSPC */ - __le16 pv_seid; -#define I40E_AQC_PV_ERR_FLAG_NO_PV 0x1 -#define I40E_AQC_PV_ERR_FLAG_NO_SCHED 0x2 -#define I40E_AQC_PV_ERR_FLAG_NO_COUNTER 0x4 -#define I40E_AQC_PV_ERR_FLAG_NO_ENTRY 0x8 - u8 reserved[14]; + __le16 pv_seid; +#define I40E_AQC_PV_ERR_FLAG_NO_PV 0x1 +#define I40E_AQC_PV_ERR_FLAG_NO_SCHED 0x2 +#define I40E_AQC_PV_ERR_FLAG_NO_COUNTER 0x4 +#define I40E_AQC_PV_ERR_FLAG_NO_ENTRY 0x8 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv_completion); @@ -859,48 +859,48 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv_completion); */ struct i40e_aqc_get_pv_params_completion { - __le16 seid; - __le16 default_stag; - __le16 pv_flags; /* same flags as add_pv */ -#define I40E_AQC_GET_PV_PV_TYPE 0x1 -#define I40E_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2 -#define I40E_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4 - u8 reserved[8]; - __le16 default_port_seid; + __le16 seid; + __le16 default_stag; + __le16 pv_flags; /* same flags as add_pv */ +#define I40E_AQC_GET_PV_PV_TYPE 0x1 +#define I40E_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2 +#define I40E_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4 + u8 reserved[8]; + __le16 default_port_seid; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_pv_params_completion); /* Add VEB (direct 0x0230) */ struct i40e_aqc_add_veb { - __le16 uplink_seid; - __le16 downlink_seid; - __le16 veb_flags; -#define I40E_AQC_ADD_VEB_FLOATING 0x1 -#define I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT 1 -#define I40E_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \ + __le16 uplink_seid; + __le16 downlink_seid; + __le16 veb_flags; +#define I40E_AQC_ADD_VEB_FLOATING 0x1 +#define I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT 1 +#define I40E_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \ I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT) -#define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2 -#define I40E_AQC_ADD_VEB_PORT_TYPE_DATA 0x4 -#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 - u8 enable_tcs; - u8 reserved[9]; +#define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2 +#define I40E_AQC_ADD_VEB_PORT_TYPE_DATA 0x4 +#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 + u8 enable_tcs; + u8 reserved[9]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb); struct i40e_aqc_add_veb_completion { - u8 reserved[6]; - __le16 switch_seid; + u8 reserved[6]; + __le16 switch_seid; /* also encodes error if rc == ENOSPC; codes are the same as add_pv */ - __le16 veb_seid; -#define I40E_AQC_VEB_ERR_FLAG_NO_VEB 0x1 -#define I40E_AQC_VEB_ERR_FLAG_NO_SCHED 0x2 -#define I40E_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4 -#define I40E_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8 - __le16 statistic_index; - __le16 vebs_used; - __le16 vebs_free; + __le16 veb_seid; +#define I40E_AQC_VEB_ERR_FLAG_NO_VEB 0x1 +#define I40E_AQC_VEB_ERR_FLAG_NO_SCHED 0x2 +#define I40E_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4 +#define I40E_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8 + __le16 statistic_index; + __le16 vebs_used; + __le16 vebs_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb_completion); @@ -909,13 +909,13 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb_completion); * uses i40e_aqc_switch_seid for the descriptor */ struct i40e_aqc_get_veb_parameters_completion { - __le16 seid; - __le16 switch_id; - __le16 veb_flags; /* only the first/last flags from 0x0230 is valid */ - __le16 statistic_index; - __le16 vebs_used; - __le16 vebs_free; - u8 reserved[4]; + __le16 seid; + __le16 switch_id; + __le16 veb_flags; /* only the first/last flags from 0x0230 is valid */ + __le16 statistic_index; + __le16 vebs_used; + __le16 vebs_free; + u8 reserved[4]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_veb_parameters_completion); @@ -928,37 +928,37 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_veb_parameters_completion); /* used for the command for most vlan commands */ struct i40e_aqc_macvlan { - __le16 num_addresses; - __le16 seid[3]; -#define I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 num_addresses; + __le16 seid[3]; +#define I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT) -#define I40E_AQC_MACVLAN_CMD_SEID_VALID 0x8000 - __le32 addr_high; - __le32 addr_low; +#define I40E_AQC_MACVLAN_CMD_SEID_VALID 0x8000 + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_macvlan); /* indirect data for command and response */ struct i40e_aqc_add_macvlan_element_data { - u8 mac_addr[6]; - __le16 vlan_tag; - __le16 flags; -#define I40E_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001 -#define I40E_AQC_MACVLAN_ADD_HASH_MATCH 0x0002 -#define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004 -#define I40E_AQC_MACVLAN_ADD_TO_QUEUE 0x0008 - __le16 queue_number; -#define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT 0 -#define I40E_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \ + u8 mac_addr[6]; + __le16 vlan_tag; + __le16 flags; +#define I40E_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001 +#define I40E_AQC_MACVLAN_ADD_HASH_MATCH 0x0002 +#define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004 +#define I40E_AQC_MACVLAN_ADD_TO_QUEUE 0x0008 + __le16 queue_number; +#define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT 0 +#define I40E_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \ I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT) /* response section */ - u8 match_method; -#define I40E_AQC_MM_PERFECT_MATCH 0x01 -#define I40E_AQC_MM_HASH_MATCH 0x02 -#define I40E_AQC_MM_ERR_NO_RES 0xFF - u8 reserved1[3]; + u8 match_method; +#define I40E_AQC_MM_PERFECT_MATCH 0x01 +#define I40E_AQC_MM_HASH_MATCH 0x02 +#define I40E_AQC_MM_ERR_NO_RES 0xFF + u8 reserved1[3]; }; struct i40e_aqc_add_remove_macvlan_completion { @@ -978,19 +978,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_macvlan_completion); */ struct i40e_aqc_remove_macvlan_element_data { - u8 mac_addr[6]; - __le16 vlan_tag; - u8 flags; -#define I40E_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01 -#define I40E_AQC_MACVLAN_DEL_HASH_MATCH 0x02 -#define I40E_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08 -#define I40E_AQC_MACVLAN_DEL_ALL_VSIS 0x10 - u8 reserved[3]; + u8 mac_addr[6]; + __le16 vlan_tag; + u8 flags; +#define I40E_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01 +#define I40E_AQC_MACVLAN_DEL_HASH_MATCH 0x02 +#define I40E_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08 +#define I40E_AQC_MACVLAN_DEL_ALL_VSIS 0x10 + u8 reserved[3]; /* reply section */ - u8 error_code; -#define I40E_AQC_REMOVE_MACVLAN_SUCCESS 0x0 -#define I40E_AQC_REMOVE_MACVLAN_FAIL 0xFF - u8 reply_reserved[3]; + u8 error_code; +#define I40E_AQC_REMOVE_MACVLAN_SUCCESS 0x0 +#define I40E_AQC_REMOVE_MACVLAN_FAIL 0xFF + u8 reply_reserved[3]; }; /* Add VLAN (indirect 0x0252) @@ -998,59 +998,58 @@ struct i40e_aqc_remove_macvlan_element_data { * use the generic i40e_aqc_macvlan for the command */ struct i40e_aqc_add_remove_vlan_element_data { - __le16 vlan_tag; - u8 vlan_flags; + __le16 vlan_tag; + u8 vlan_flags; /* flags for add VLAN */ -#define I40E_AQC_ADD_VLAN_LOCAL 0x1 -#define I40E_AQC_ADD_PVLAN_TYPE_SHIFT 1 -#define I40E_AQC_ADD_PVLAN_TYPE_MASK (0x3 << \ - I40E_AQC_ADD_PVLAN_TYPE_SHIFT) -#define I40E_AQC_ADD_PVLAN_TYPE_REGULAR 0x0 -#define I40E_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2 -#define I40E_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4 -#define I40E_AQC_VLAN_PTYPE_SHIFT 3 -#define I40E_AQC_VLAN_PTYPE_MASK (0x3 << I40E_AQC_VLAN_PTYPE_SHIFT) -#define I40E_AQC_VLAN_PTYPE_REGULAR_VSI 0x0 -#define I40E_AQC_VLAN_PTYPE_PROMISC_VSI 0x8 -#define I40E_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10 -#define I40E_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18 +#define I40E_AQC_ADD_VLAN_LOCAL 0x1 +#define I40E_AQC_ADD_PVLAN_TYPE_SHIFT 1 +#define I40E_AQC_ADD_PVLAN_TYPE_MASK (0x3 << I40E_AQC_ADD_PVLAN_TYPE_SHIFT) +#define I40E_AQC_ADD_PVLAN_TYPE_REGULAR 0x0 +#define I40E_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2 +#define I40E_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4 +#define I40E_AQC_VLAN_PTYPE_SHIFT 3 +#define I40E_AQC_VLAN_PTYPE_MASK (0x3 << I40E_AQC_VLAN_PTYPE_SHIFT) +#define I40E_AQC_VLAN_PTYPE_REGULAR_VSI 0x0 +#define I40E_AQC_VLAN_PTYPE_PROMISC_VSI 0x8 +#define I40E_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10 +#define I40E_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18 /* flags for remove VLAN */ -#define I40E_AQC_REMOVE_VLAN_ALL 0x1 - u8 reserved; - u8 result; +#define I40E_AQC_REMOVE_VLAN_ALL 0x1 + u8 reserved; + u8 result; /* flags for add VLAN */ -#define I40E_AQC_ADD_VLAN_SUCCESS 0x0 -#define I40E_AQC_ADD_VLAN_FAIL_REQUEST 0xFE -#define I40E_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF +#define I40E_AQC_ADD_VLAN_SUCCESS 0x0 +#define I40E_AQC_ADD_VLAN_FAIL_REQUEST 0xFE +#define I40E_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF /* flags for remove VLAN */ -#define I40E_AQC_REMOVE_VLAN_SUCCESS 0x0 -#define I40E_AQC_REMOVE_VLAN_FAIL 0xFF - u8 reserved1[3]; +#define I40E_AQC_REMOVE_VLAN_SUCCESS 0x0 +#define I40E_AQC_REMOVE_VLAN_FAIL 0xFF + u8 reserved1[3]; }; struct i40e_aqc_add_remove_vlan_completion { - u8 reserved[4]; - __le16 vlans_used; - __le16 vlans_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[4]; + __le16 vlans_used; + __le16 vlans_free; + __le32 addr_high; + __le32 addr_low; }; /* Set VSI Promiscuous Modes (direct 0x0254) */ struct i40e_aqc_set_vsi_promiscuous_modes { - __le16 promiscuous_flags; - __le16 valid_flags; + __le16 promiscuous_flags; + __le16 valid_flags; /* flags used for both fields above */ -#define I40E_AQC_SET_VSI_PROMISC_UNICAST 0x01 -#define I40E_AQC_SET_VSI_PROMISC_MULTICAST 0x02 -#define I40E_AQC_SET_VSI_PROMISC_BROADCAST 0x04 -#define I40E_AQC_SET_VSI_DEFAULT 0x08 -#define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10 - __le16 seid; -#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF - __le16 vlan_tag; -#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000 - u8 reserved[8]; +#define I40E_AQC_SET_VSI_PROMISC_UNICAST 0x01 +#define I40E_AQC_SET_VSI_PROMISC_MULTICAST 0x02 +#define I40E_AQC_SET_VSI_PROMISC_BROADCAST 0x04 +#define I40E_AQC_SET_VSI_DEFAULT 0x08 +#define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10 + __le16 seid; +#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF + __le16 vlan_tag; +#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000 + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_vsi_promiscuous_modes); @@ -1059,23 +1058,23 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_vsi_promiscuous_modes); * Uses generic i40e_aqc_add_remove_tag_completion for completion */ struct i40e_aqc_add_tag { - __le16 flags; -#define I40E_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001 - __le16 seid; -#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 flags; +#define I40E_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001 + __le16 seid; +#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT) - __le16 tag; - __le16 queue_number; - u8 reserved[8]; + __le16 tag; + __le16 queue_number; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_tag); struct i40e_aqc_add_remove_tag_completion { - u8 reserved[12]; - __le16 tags_used; - __le16 tags_free; + u8 reserved[12]; + __le16 tags_used; + __le16 tags_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_tag_completion); @@ -1084,12 +1083,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_tag_completion); * Uses generic i40e_aqc_add_remove_tag_completion for completion */ struct i40e_aqc_remove_tag { - __le16 seid; -#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 seid; +#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT) - __le16 tag; - u8 reserved[12]; + __le16 tag; + u8 reserved[12]; }; /* Add multicast E-Tag (direct 0x0257) @@ -1097,22 +1096,22 @@ struct i40e_aqc_remove_tag { * and no external data */ struct i40e_aqc_add_remove_mcast_etag { - __le16 pv_seid; - __le16 etag; - u8 num_unicast_etags; - u8 reserved[3]; - __le32 addr_high; /* address of array of 2-byte s-tags */ - __le32 addr_low; + __le16 pv_seid; + __le16 etag; + u8 num_unicast_etags; + u8 reserved[3]; + __le32 addr_high; /* address of array of 2-byte s-tags */ + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_mcast_etag); struct i40e_aqc_add_remove_mcast_etag_completion { - u8 reserved[4]; - __le16 mcast_etags_used; - __le16 mcast_etags_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[4]; + __le16 mcast_etags_used; + __le16 mcast_etags_free; + __le32 addr_high; + __le32 addr_low; }; @@ -1120,21 +1119,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_mcast_etag_completion); /* Update S/E-Tag (direct 0x0259) */ struct i40e_aqc_update_tag { - __le16 seid; -#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 seid; +#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT) - __le16 old_tag; - __le16 new_tag; - u8 reserved[10]; + __le16 old_tag; + __le16 new_tag; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag); struct i40e_aqc_update_tag_completion { - u8 reserved[12]; - __le16 tags_used; - __le16 tags_free; + u8 reserved[12]; + __le16 tags_used; + __le16 tags_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag_completion); @@ -1145,30 +1144,30 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag_completion); * and the generic direct completion structure */ struct i40e_aqc_add_remove_control_packet_filter { - u8 mac[6]; - __le16 etype; - __le16 flags; -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000 - __le16 seid; -#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \ + u8 mac[6]; + __le16 etype; + __le16 flags; +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000 + __le16 seid; +#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT) - __le16 queue; - u8 reserved[2]; + __le16 queue; + u8 reserved[2]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter); struct i40e_aqc_add_remove_control_packet_filter_completion { - __le16 mac_etype_used; - __le16 etype_used; - __le16 mac_etype_free; - __le16 etype_free; - u8 reserved[8]; + __le16 mac_etype_used; + __le16 etype_used; + __le16 mac_etype_free; + __le16 etype_free; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter_completion); @@ -1179,23 +1178,23 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter_completion); * and the generic indirect completion structure */ struct i40e_aqc_add_remove_cloud_filters { - u8 num_filters; - u8 reserved; - __le16 seid; -#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \ + u8 num_filters; + u8 reserved; + __le16 seid; +#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT) - u8 reserved2[4]; - __le32 addr_high; - __le32 addr_low; + u8 reserved2[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_cloud_filters); struct i40e_aqc_add_remove_cloud_filters_element_data { - u8 outer_mac[6]; - u8 inner_mac[6]; - __le16 inner_vlan; + u8 outer_mac[6]; + u8 inner_mac[6]; + __le16 inner_vlan; union { struct { u8 reserved[12]; @@ -1205,49 +1204,49 @@ struct i40e_aqc_add_remove_cloud_filters_element_data { u8 data[16]; } v6; } ipaddr; - __le16 flags; -#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \ + __le16 flags; +#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \ I40E_AQC_ADD_CLOUD_FILTER_SHIFT) /* 0x0000 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001 +#define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001 /* 0x0002 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004 /* 0x0005 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006 /* 0x0007 reserved */ /* 0x0008 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_OMAC 0x0009 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A -#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B -#define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C - -#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080 -#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6 -#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0 -#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0 -#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100 - -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN 0 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3 - - __le32 tenant_id; - u8 reserved[4]; - __le16 queue_number; -#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x3F << \ - I40E_AQC_ADD_CLOUD_QUEUE_SHIFT) - u8 reserved2[14]; +#define I40E_AQC_ADD_CLOUD_FILTER_OMAC 0x0009 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A +#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B +#define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C + +#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080 +#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6 +#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0 +#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0 +#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100 + +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN 0 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3 + + __le32 tenant_id; + u8 reserved[4]; + __le16 queue_number; +#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x3F << \ + I40E_AQC_ADD_CLOUD_QUEUE_SHIFT) + u8 reserved2[14]; /* response section */ - u8 allocation_result; -#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0 -#define I40E_AQC_ADD_CLOUD_FILTER_FAIL 0xFF - u8 response_reserved[7]; + u8 allocation_result; +#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0 +#define I40E_AQC_ADD_CLOUD_FILTER_FAIL 0xFF + u8 response_reserved[7]; }; struct i40e_aqc_remove_cloud_filters_completion { @@ -1269,14 +1268,14 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_cloud_filters_completion); struct i40e_aqc_add_delete_mirror_rule { __le16 seid; __le16 rule_type; -#define I40E_AQC_MIRROR_RULE_TYPE_SHIFT 0 -#define I40E_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \ +#define I40E_AQC_MIRROR_RULE_TYPE_SHIFT 0 +#define I40E_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \ I40E_AQC_MIRROR_RULE_TYPE_SHIFT) -#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1 -#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2 -#define I40E_AQC_MIRROR_RULE_TYPE_VLAN 3 -#define I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4 -#define I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5 +#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1 +#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2 +#define I40E_AQC_MIRROR_RULE_TYPE_VLAN 3 +#define I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4 +#define I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5 __le16 num_entries; __le16 destination; /* VSI for add, rule id for delete */ __le32 addr_high; /* address of array of 2-byte VSI or VLAN ids */ @@ -1286,12 +1285,12 @@ struct i40e_aqc_add_delete_mirror_rule { I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule); struct i40e_aqc_add_delete_mirror_rule_completion { - u8 reserved[2]; - __le16 rule_id; /* only used on add */ - __le16 mirror_rules_used; - __le16 mirror_rules_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[2]; + __le16 rule_id; /* only used on add */ + __le16 mirror_rules_used; + __le16 mirror_rules_free; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); @@ -1302,11 +1301,11 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); * the command and response use the same descriptor structure */ struct i40e_aqc_pfc_ignore { - u8 tc_bitmap; - u8 command_flags; /* unused on response */ -#define I40E_AQC_PFC_IGNORE_SET 0x80 -#define I40E_AQC_PFC_IGNORE_CLEAR 0x0 - u8 reserved[14]; + u8 tc_bitmap; + u8 command_flags; /* unused on response */ +#define I40E_AQC_PFC_IGNORE_SET 0x80 +#define I40E_AQC_PFC_IGNORE_CLEAR 0x0 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_pfc_ignore); @@ -1321,10 +1320,10 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_pfc_ignore); * this generic struct to pass the SEID in param0 */ struct i40e_aqc_tx_sched_ind { - __le16 vsi_seid; - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; + __le16 vsi_seid; + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_tx_sched_ind); @@ -1336,12 +1335,12 @@ struct i40e_aqc_qs_handles_resp { /* Configure VSI BW limits (direct 0x0400) */ struct i40e_aqc_configure_vsi_bw_limit { - __le16 vsi_seid; - u8 reserved[2]; - __le16 credit; - u8 reserved1[2]; - u8 max_credit; /* 0-3, limit = 2^max */ - u8 reserved2[7]; + __le16 vsi_seid; + u8 reserved[2]; + __le16 credit; + u8 reserved1[2]; + u8 max_credit; /* 0-3, limit = 2^max */ + u8 reserved2[7]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_vsi_bw_limit); @@ -1350,58 +1349,58 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_vsi_bw_limit); * responds with i40e_aqc_qs_handles_resp */ struct i40e_aqc_configure_vsi_ets_sla_bw_data { - u8 tc_valid_bits; - u8 reserved[15]; - __le16 tc_bw_credits[8]; /* FW writesback QS handles here */ + u8 tc_valid_bits; + u8 reserved[15]; + __le16 tc_bw_credits[8]; /* FW writesback QS handles here */ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved1[28]; + __le16 tc_bw_max[2]; + u8 reserved1[28]; }; /* Configure VSI Bandwidth Allocation per Traffic Type (indirect 0x0407) * responds with i40e_aqc_qs_handles_resp */ struct i40e_aqc_configure_vsi_tc_bw_data { - u8 tc_valid_bits; - u8 reserved[3]; - u8 tc_bw_credits[8]; - u8 reserved1[4]; - __le16 qs_handles[8]; + u8 tc_valid_bits; + u8 reserved[3]; + u8 tc_bw_credits[8]; + u8 reserved1[4]; + __le16 qs_handles[8]; }; /* Query vsi bw configuration (indirect 0x0408) */ struct i40e_aqc_query_vsi_bw_config_resp { - u8 tc_valid_bits; - u8 tc_suspended_bits; - u8 reserved[14]; - __le16 qs_handles[8]; - u8 reserved1[4]; - __le16 port_bw_limit; - u8 reserved2[2]; - u8 max_bw; /* 0-3, limit = 2^max */ - u8 reserved3[23]; + u8 tc_valid_bits; + u8 tc_suspended_bits; + u8 reserved[14]; + __le16 qs_handles[8]; + u8 reserved1[4]; + __le16 port_bw_limit; + u8 reserved2[2]; + u8 max_bw; /* 0-3, limit = 2^max */ + u8 reserved3[23]; }; /* Query VSI Bandwidth Allocation per Traffic Type (indirect 0x040A) */ struct i40e_aqc_query_vsi_ets_sla_config_resp { - u8 tc_valid_bits; - u8 reserved[3]; - u8 share_credits[8]; - __le16 credits[8]; + u8 tc_valid_bits; + u8 reserved[3]; + u8 share_credits[8]; + __le16 credits[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; + __le16 tc_bw_max[2]; }; /* Configure Switching Component Bandwidth Limit (direct 0x0410) */ struct i40e_aqc_configure_switching_comp_bw_limit { - __le16 seid; - u8 reserved[2]; - __le16 credit; - u8 reserved1[2]; - u8 max_bw; /* 0-3, limit = 2^max */ - u8 reserved2[7]; + __le16 seid; + u8 reserved[2]; + __le16 credit; + u8 reserved1[2]; + u8 max_bw; /* 0-3, limit = 2^max */ + u8 reserved2[7]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); @@ -1411,75 +1410,75 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); * Disable Physical Port ETS (indirect 0x0415) */ struct i40e_aqc_configure_switching_comp_ets_data { - u8 reserved[4]; - u8 tc_valid_bits; - u8 seepage; -#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 - u8 tc_strict_priority_flags; - u8 reserved1[17]; - u8 tc_bw_share_credits[8]; - u8 reserved2[96]; + u8 reserved[4]; + u8 tc_valid_bits; + u8 seepage; +#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 + u8 tc_strict_priority_flags; + u8 reserved1[17]; + u8 tc_bw_share_credits[8]; + u8 reserved2[96]; }; /* Configure Switching Component Bandwidth Limits per Tc (indirect 0x0416) */ struct i40e_aqc_configure_switching_comp_ets_bw_limit_data { - u8 tc_valid_bits; - u8 reserved[15]; - __le16 tc_bw_credit[8]; + u8 tc_valid_bits; + u8 reserved[15]; + __le16 tc_bw_credit[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved1[28]; + __le16 tc_bw_max[2]; + u8 reserved1[28]; }; /* Configure Switching Component Bandwidth Allocation per Tc * (indirect 0x0417) */ struct i40e_aqc_configure_switching_comp_bw_config_data { - u8 tc_valid_bits; - u8 reserved[2]; - u8 absolute_credits; /* bool */ - u8 tc_bw_share_credits[8]; - u8 reserved1[20]; + u8 tc_valid_bits; + u8 reserved[2]; + u8 absolute_credits; /* bool */ + u8 tc_bw_share_credits[8]; + u8 reserved1[20]; }; /* Query Switching Component Configuration (indirect 0x0418) */ struct i40e_aqc_query_switching_comp_ets_config_resp { - u8 tc_valid_bits; - u8 reserved[35]; - __le16 port_bw_limit; - u8 reserved1[2]; - u8 tc_bw_max; /* 0-3, limit = 2^max */ - u8 reserved2[23]; + u8 tc_valid_bits; + u8 reserved[35]; + __le16 port_bw_limit; + u8 reserved1[2]; + u8 tc_bw_max; /* 0-3, limit = 2^max */ + u8 reserved2[23]; }; /* Query PhysicalPort ETS Configuration (indirect 0x0419) */ struct i40e_aqc_query_port_ets_config_resp { - u8 reserved[4]; - u8 tc_valid_bits; - u8 reserved1; - u8 tc_strict_priority_bits; - u8 reserved2; - u8 tc_bw_share_credits[8]; - __le16 tc_bw_limits[8]; + u8 reserved[4]; + u8 tc_valid_bits; + u8 reserved1; + u8 tc_strict_priority_bits; + u8 reserved2; + u8 tc_bw_share_credits[8]; + __le16 tc_bw_limits[8]; /* 4 bits per tc 0-7, 4th bit reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved3[32]; + __le16 tc_bw_max[2]; + u8 reserved3[32]; }; /* Query Switching Component Bandwidth Allocation per Traffic Type * (indirect 0x041A) */ struct i40e_aqc_query_switching_comp_bw_config_resp { - u8 tc_valid_bits; - u8 reserved[2]; - u8 absolute_credits_enable; /* bool */ - u8 tc_bw_share_credits[8]; - __le16 tc_bw_limits[8]; + u8 tc_valid_bits; + u8 reserved[2]; + u8 absolute_credits_enable; /* bool */ + u8 tc_bw_share_credits[8]; + __le16 tc_bw_limits[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; + __le16 tc_bw_max[2]; }; /* Suspend/resume port TX traffic @@ -1490,37 +1489,37 @@ struct i40e_aqc_query_switching_comp_bw_config_resp { * (indirect 0x041D) */ struct i40e_aqc_configure_partition_bw_data { - __le16 pf_valid_bits; - u8 min_bw[16]; /* guaranteed bandwidth */ - u8 max_bw[16]; /* bandwidth limit */ + __le16 pf_valid_bits; + u8 min_bw[16]; /* guaranteed bandwidth */ + u8 max_bw[16]; /* bandwidth limit */ }; /* Get and set the active HMC resource profile and status. * (direct 0x0500) and (direct 0x0501) */ struct i40e_aq_get_set_hmc_resource_profile { - u8 pm_profile; - u8 pe_vf_enabled; - u8 reserved[14]; + u8 pm_profile; + u8 pe_vf_enabled; + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_get_set_hmc_resource_profile); enum i40e_aq_hmc_profile { /* I40E_HMC_PROFILE_NO_CHANGE = 0, reserved */ - I40E_HMC_PROFILE_DEFAULT = 1, - I40E_HMC_PROFILE_FAVOR_VF = 2, - I40E_HMC_PROFILE_EQUAL = 3, + I40E_HMC_PROFILE_DEFAULT = 1, + I40E_HMC_PROFILE_FAVOR_VF = 2, + I40E_HMC_PROFILE_EQUAL = 3, }; -#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_PM_MASK 0xF -#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_COUNT_MASK 0x3F +#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_PM_MASK 0xF +#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_COUNT_MASK 0x3F /* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */ /* set in param0 for get phy abilities to report qualified modules */ -#define I40E_AQ_PHY_REPORT_QUALIFIED_MODULES 0x0001 -#define I40E_AQ_PHY_REPORT_INITIAL_VALUES 0x0002 +#define I40E_AQ_PHY_REPORT_QUALIFIED_MODULES 0x0001 +#define I40E_AQ_PHY_REPORT_INITIAL_VALUES 0x0002 enum i40e_aq_phy_type { I40E_PHY_TYPE_SGMII = 0x0, @@ -1578,147 +1577,147 @@ struct i40e_aqc_module_desc { }; struct i40e_aq_get_phy_abilities_resp { - __le32 phy_type; /* bitmap using the above enum for offsets */ - u8 link_speed; /* bitmap using the above enum bit patterns */ - u8 abilities; -#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 -#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 -#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 -#define I40E_AQ_PHY_LINK_ENABLED 0x08 -#define I40E_AQ_PHY_AN_ENABLED 0x10 -#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 - __le16 eee_capability; -#define I40E_AQ_EEE_100BASE_TX 0x0002 -#define I40E_AQ_EEE_1000BASE_T 0x0004 -#define I40E_AQ_EEE_10GBASE_T 0x0008 -#define I40E_AQ_EEE_1000BASE_KX 0x0010 -#define I40E_AQ_EEE_10GBASE_KX4 0x0020 -#define I40E_AQ_EEE_10GBASE_KR 0x0040 - __le32 eeer_val; - u8 d3_lpan; -#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01 - u8 reserved[3]; - u8 phy_id[4]; - u8 module_type[3]; - u8 qualified_module_count; -#define I40E_AQ_PHY_MAX_QMS 16 - struct i40e_aqc_module_desc qualified_module[I40E_AQ_PHY_MAX_QMS]; + __le32 phy_type; /* bitmap using the above enum for offsets */ + u8 link_speed; /* bitmap using the above enum bit patterns */ + u8 abilities; +#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 +#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 +#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 +#define I40E_AQ_PHY_LINK_ENABLED 0x08 +#define I40E_AQ_PHY_AN_ENABLED 0x10 +#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 + __le16 eee_capability; +#define I40E_AQ_EEE_100BASE_TX 0x0002 +#define I40E_AQ_EEE_1000BASE_T 0x0004 +#define I40E_AQ_EEE_10GBASE_T 0x0008 +#define I40E_AQ_EEE_1000BASE_KX 0x0010 +#define I40E_AQ_EEE_10GBASE_KX4 0x0020 +#define I40E_AQ_EEE_10GBASE_KR 0x0040 + __le32 eeer_val; + u8 d3_lpan; +#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01 + u8 reserved[3]; + u8 phy_id[4]; + u8 module_type[3]; + u8 qualified_module_count; +#define I40E_AQ_PHY_MAX_QMS 16 + struct i40e_aqc_module_desc qualified_module[I40E_AQ_PHY_MAX_QMS]; }; /* Set PHY Config (direct 0x0601) */ struct i40e_aq_set_phy_config { /* same bits as above in all */ - __le32 phy_type; - u8 link_speed; - u8 abilities; + __le32 phy_type; + u8 link_speed; + u8 abilities; /* bits 0-2 use the values from get_phy_abilities_resp */ #define I40E_AQ_PHY_ENABLE_LINK 0x08 #define I40E_AQ_PHY_ENABLE_AN 0x10 #define I40E_AQ_PHY_ENABLE_ATOMIC_LINK 0x20 - __le16 eee_capability; - __le32 eeer; - u8 low_power_ctrl; - u8 reserved[3]; + __le16 eee_capability; + __le32 eeer; + u8 low_power_ctrl; + u8 reserved[3]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config); /* Set MAC Config command data structure (direct 0x0603) */ struct i40e_aq_set_mac_config { - __le16 max_frame_size; - u8 params; -#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 -#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 -#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 -#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 -#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 -#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 - u8 tx_timer_priority; /* bitmap */ - __le16 tx_timer_value; - __le16 fc_refresh_threshold; - u8 reserved[8]; + __le16 max_frame_size; + u8 params; +#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 +#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 +#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 +#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 +#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 +#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 + u8 tx_timer_priority; /* bitmap */ + __le16 tx_timer_value; + __le16 fc_refresh_threshold; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_set_mac_config); /* Restart Auto-Negotiation (direct 0x605) */ struct i40e_aqc_set_link_restart_an { - u8 command; -#define I40E_AQ_PHY_RESTART_AN 0x02 -#define I40E_AQ_PHY_LINK_ENABLE 0x04 - u8 reserved[15]; + u8 command; +#define I40E_AQ_PHY_RESTART_AN 0x02 +#define I40E_AQ_PHY_LINK_ENABLE 0x04 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_link_restart_an); /* Get Link Status cmd & response data structure (direct 0x0607) */ struct i40e_aqc_get_link_status { - __le16 command_flags; /* only field set on command */ -#define I40E_AQ_LSE_MASK 0x3 -#define I40E_AQ_LSE_NOP 0x0 -#define I40E_AQ_LSE_DISABLE 0x2 -#define I40E_AQ_LSE_ENABLE 0x3 + __le16 command_flags; /* only field set on command */ +#define I40E_AQ_LSE_MASK 0x3 +#define I40E_AQ_LSE_NOP 0x0 +#define I40E_AQ_LSE_DISABLE 0x2 +#define I40E_AQ_LSE_ENABLE 0x3 /* only response uses this flag */ -#define I40E_AQ_LSE_IS_ENABLED 0x1 - u8 phy_type; /* i40e_aq_phy_type */ - u8 link_speed; /* i40e_aq_link_speed */ - u8 link_info; -#define I40E_AQ_LINK_UP 0x01 -#define I40E_AQ_LINK_FAULT 0x02 -#define I40E_AQ_LINK_FAULT_TX 0x04 -#define I40E_AQ_LINK_FAULT_RX 0x08 -#define I40E_AQ_LINK_FAULT_REMOTE 0x10 -#define I40E_AQ_MEDIA_AVAILABLE 0x40 -#define I40E_AQ_SIGNAL_DETECT 0x80 - u8 an_info; -#define I40E_AQ_AN_COMPLETED 0x01 -#define I40E_AQ_LP_AN_ABILITY 0x02 -#define I40E_AQ_PD_FAULT 0x04 -#define I40E_AQ_FEC_EN 0x08 -#define I40E_AQ_PHY_LOW_POWER 0x10 -#define I40E_AQ_LINK_PAUSE_TX 0x20 -#define I40E_AQ_LINK_PAUSE_RX 0x40 -#define I40E_AQ_QUALIFIED_MODULE 0x80 - u8 ext_info; -#define I40E_AQ_LINK_PHY_TEMP_ALARM 0x01 -#define I40E_AQ_LINK_XCESSIVE_ERRORS 0x02 -#define I40E_AQ_LINK_TX_SHIFT 0x02 -#define I40E_AQ_LINK_TX_MASK (0x03 << I40E_AQ_LINK_TX_SHIFT) -#define I40E_AQ_LINK_TX_ACTIVE 0x00 -#define I40E_AQ_LINK_TX_DRAINED 0x01 -#define I40E_AQ_LINK_TX_FLUSHED 0x03 -#define I40E_AQ_LINK_FORCED_40G 0x10 - u8 loopback; /* use defines from i40e_aqc_set_lb_mode */ - __le16 max_frame_size; - u8 config; -#define I40E_AQ_CONFIG_CRC_ENA 0x04 -#define I40E_AQ_CONFIG_PACING_MASK 0x78 - u8 reserved[5]; +#define I40E_AQ_LSE_IS_ENABLED 0x1 + u8 phy_type; /* i40e_aq_phy_type */ + u8 link_speed; /* i40e_aq_link_speed */ + u8 link_info; +#define I40E_AQ_LINK_UP 0x01 +#define I40E_AQ_LINK_FAULT 0x02 +#define I40E_AQ_LINK_FAULT_TX 0x04 +#define I40E_AQ_LINK_FAULT_RX 0x08 +#define I40E_AQ_LINK_FAULT_REMOTE 0x10 +#define I40E_AQ_MEDIA_AVAILABLE 0x40 +#define I40E_AQ_SIGNAL_DETECT 0x80 + u8 an_info; +#define I40E_AQ_AN_COMPLETED 0x01 +#define I40E_AQ_LP_AN_ABILITY 0x02 +#define I40E_AQ_PD_FAULT 0x04 +#define I40E_AQ_FEC_EN 0x08 +#define I40E_AQ_PHY_LOW_POWER 0x10 +#define I40E_AQ_LINK_PAUSE_TX 0x20 +#define I40E_AQ_LINK_PAUSE_RX 0x40 +#define I40E_AQ_QUALIFIED_MODULE 0x80 + u8 ext_info; +#define I40E_AQ_LINK_PHY_TEMP_ALARM 0x01 +#define I40E_AQ_LINK_XCESSIVE_ERRORS 0x02 +#define I40E_AQ_LINK_TX_SHIFT 0x02 +#define I40E_AQ_LINK_TX_MASK (0x03 << I40E_AQ_LINK_TX_SHIFT) +#define I40E_AQ_LINK_TX_ACTIVE 0x00 +#define I40E_AQ_LINK_TX_DRAINED 0x01 +#define I40E_AQ_LINK_TX_FLUSHED 0x03 +#define I40E_AQ_LINK_FORCED_40G 0x10 + u8 loopback; /* use defines from i40e_aqc_set_lb_mode */ + __le16 max_frame_size; + u8 config; +#define I40E_AQ_CONFIG_CRC_ENA 0x04 +#define I40E_AQ_CONFIG_PACING_MASK 0x78 + u8 reserved[5]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status); /* Set event mask command (direct 0x613) */ struct i40e_aqc_set_phy_int_mask { - u8 reserved[8]; - __le16 event_mask; -#define I40E_AQ_EVENT_LINK_UPDOWN 0x0002 -#define I40E_AQ_EVENT_MEDIA_NA 0x0004 -#define I40E_AQ_EVENT_LINK_FAULT 0x0008 -#define I40E_AQ_EVENT_PHY_TEMP_ALARM 0x0010 -#define I40E_AQ_EVENT_EXCESSIVE_ERRORS 0x0020 -#define I40E_AQ_EVENT_SIGNAL_DETECT 0x0040 -#define I40E_AQ_EVENT_AN_COMPLETED 0x0080 -#define I40E_AQ_EVENT_MODULE_QUAL_FAIL 0x0100 -#define I40E_AQ_EVENT_PORT_TX_SUSPENDED 0x0200 - u8 reserved1[6]; + u8 reserved[8]; + __le16 event_mask; +#define I40E_AQ_EVENT_LINK_UPDOWN 0x0002 +#define I40E_AQ_EVENT_MEDIA_NA 0x0004 +#define I40E_AQ_EVENT_LINK_FAULT 0x0008 +#define I40E_AQ_EVENT_PHY_TEMP_ALARM 0x0010 +#define I40E_AQ_EVENT_EXCESSIVE_ERRORS 0x0020 +#define I40E_AQ_EVENT_SIGNAL_DETECT 0x0040 +#define I40E_AQ_EVENT_AN_COMPLETED 0x0080 +#define I40E_AQ_EVENT_MODULE_QUAL_FAIL 0x0100 +#define I40E_AQ_EVENT_PORT_TX_SUSPENDED 0x0200 + u8 reserved1[6]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_int_mask); @@ -1728,27 +1727,27 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_int_mask); * Get Link Partner AN advt register (direct 0x0616) */ struct i40e_aqc_an_advt_reg { - __le32 local_an_reg0; - __le16 local_an_reg1; - u8 reserved[10]; + __le32 local_an_reg0; + __le16 local_an_reg1; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_an_advt_reg); /* Set Loopback mode (0x0618) */ struct i40e_aqc_set_lb_mode { - __le16 lb_mode; -#define I40E_AQ_LB_PHY_LOCAL 0x01 -#define I40E_AQ_LB_PHY_REMOTE 0x02 -#define I40E_AQ_LB_MAC_LOCAL 0x04 - u8 reserved[14]; + __le16 lb_mode; +#define I40E_AQ_LB_PHY_LOCAL 0x01 +#define I40E_AQ_LB_PHY_REMOTE 0x02 +#define I40E_AQ_LB_MAC_LOCAL 0x04 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_lb_mode); /* Set PHY Debug command (0x0622) */ struct i40e_aqc_set_phy_debug { - u8 command_flags; + u8 command_flags; #define I40E_AQ_PHY_DEBUG_RESET_INTERNAL 0x02 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT 2 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_MASK (0x03 << \ @@ -1757,15 +1756,15 @@ struct i40e_aqc_set_phy_debug { #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_HARD 0x01 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SOFT 0x02 #define I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW 0x10 - u8 reserved[15]; + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_debug); enum i40e_aq_phy_reg_type { - I40E_AQC_PHY_REG_INTERNAL = 0x1, - I40E_AQC_PHY_REG_EXERNAL_BASET = 0x2, - I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3 + I40E_AQC_PHY_REG_INTERNAL = 0x1, + I40E_AQC_PHY_REG_EXERNAL_BASET = 0x2, + I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3 }; /* NVM Read command (indirect 0x0701) @@ -1773,40 +1772,40 @@ enum i40e_aq_phy_reg_type { * NVM Update commands (indirect 0x0703) */ struct i40e_aqc_nvm_update { - u8 command_flags; -#define I40E_AQ_NVM_LAST_CMD 0x01 -#define I40E_AQ_NVM_FLASH_ONLY 0x80 - u8 module_pointer; - __le16 length; - __le32 offset; - __le32 addr_high; - __le32 addr_low; + u8 command_flags; +#define I40E_AQ_NVM_LAST_CMD 0x01 +#define I40E_AQ_NVM_FLASH_ONLY 0x80 + u8 module_pointer; + __le16 length; + __le32 offset; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_update); /* NVM Config Read (indirect 0x0704) */ struct i40e_aqc_nvm_config_read { - __le16 cmd_flags; + __le16 cmd_flags; #define ANVM_SINGLE_OR_MULTIPLE_FEATURES_MASK 1 #define ANVM_READ_SINGLE_FEATURE 0 #define ANVM_READ_MULTIPLE_FEATURES 1 - __le16 element_count; - __le16 element_id; /* Feature/field ID */ - u8 reserved[2]; - __le32 address_high; - __le32 address_low; + __le16 element_count; + __le16 element_id; /* Feature/field ID */ + u8 reserved[2]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_read); /* NVM Config Write (indirect 0x0705) */ struct i40e_aqc_nvm_config_write { - __le16 cmd_flags; - __le16 element_count; - u8 reserved[4]; - __le32 address_high; - __le32 address_low; + __le16 cmd_flags; + __le16 element_count; + u8 reserved[4]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_write); @@ -1831,10 +1830,10 @@ struct i40e_aqc_nvm_config_data_immediate_field { * Send to Peer PF command (indirect 0x0803) */ struct i40e_aqc_pf_vf_message { - __le32 id; - u8 reserved[4]; - __le32 addr_high; - __le32 addr_low; + __le32 id; + u8 reserved[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_pf_vf_message); @@ -1870,22 +1869,22 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_ind_write); * uses i40e_aq_desc */ struct i40e_aqc_alternate_write_done { - __le16 cmd_flags; + __le16 cmd_flags; #define I40E_AQ_ALTERNATE_MODE_BIOS_MASK 1 #define I40E_AQ_ALTERNATE_MODE_BIOS_LEGACY 0 #define I40E_AQ_ALTERNATE_MODE_BIOS_UEFI 1 #define I40E_AQ_ALTERNATE_RESET_NEEDED 2 - u8 reserved[14]; + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_write_done); /* Set OEM mode (direct 0x0905) */ struct i40e_aqc_alternate_set_mode { - __le32 mode; + __le32 mode; #define I40E_AQ_ALTERNATE_MODE_NONE 0 #define I40E_AQ_ALTERNATE_MODE_OEM 1 - u8 reserved[12]; + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_set_mode); @@ -1896,33 +1895,33 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_set_mode); /* Lan Queue Overflow Event (direct, 0x1001) */ struct i40e_aqc_lan_overflow { - __le32 prtdcb_rupto; - __le32 otx_ctl; - u8 reserved[8]; + __le32 prtdcb_rupto; + __le32 otx_ctl; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lan_overflow); /* Get LLDP MIB (indirect 0x0A00) */ struct i40e_aqc_lldp_get_mib { - u8 type; - u8 reserved1; -#define I40E_AQ_LLDP_MIB_TYPE_MASK 0x3 -#define I40E_AQ_LLDP_MIB_LOCAL 0x0 -#define I40E_AQ_LLDP_MIB_REMOTE 0x1 -#define I40E_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2 -#define I40E_AQ_LLDP_BRIDGE_TYPE_MASK 0xC -#define I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2 -#define I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0 -#define I40E_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1 -#define I40E_AQ_LLDP_TX_SHIFT 0x4 -#define I40E_AQ_LLDP_TX_MASK (0x03 << I40E_AQ_LLDP_TX_SHIFT) + u8 type; + u8 reserved1; +#define I40E_AQ_LLDP_MIB_TYPE_MASK 0x3 +#define I40E_AQ_LLDP_MIB_LOCAL 0x0 +#define I40E_AQ_LLDP_MIB_REMOTE 0x1 +#define I40E_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2 +#define I40E_AQ_LLDP_BRIDGE_TYPE_MASK 0xC +#define I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2 +#define I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0 +#define I40E_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1 +#define I40E_AQ_LLDP_TX_SHIFT 0x4 +#define I40E_AQ_LLDP_TX_MASK (0x03 << I40E_AQ_LLDP_TX_SHIFT) /* TX pause flags use I40E_AQ_LINK_TX_* above */ - __le16 local_len; - __le16 remote_len; - u8 reserved2[2]; - __le32 addr_high; - __le32 addr_low; + __le16 local_len; + __le16 remote_len; + u8 reserved2[2]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_get_mib); @@ -1931,12 +1930,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_get_mib); * also used for the event (with type in the command field) */ struct i40e_aqc_lldp_update_mib { - u8 command; -#define I40E_AQ_LLDP_MIB_UPDATE_ENABLE 0x0 -#define I40E_AQ_LLDP_MIB_UPDATE_DISABLE 0x1 - u8 reserved[7]; - __le32 addr_high; - __le32 addr_low; + u8 command; +#define I40E_AQ_LLDP_MIB_UPDATE_ENABLE 0x0 +#define I40E_AQ_LLDP_MIB_UPDATE_DISABLE 0x1 + u8 reserved[7]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_mib); @@ -1945,35 +1944,35 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_mib); * Delete LLDP TLV (indirect 0x0A04) */ struct i40e_aqc_lldp_add_tlv { - u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ - u8 reserved1[1]; - __le16 len; - u8 reserved2[4]; - __le32 addr_high; - __le32 addr_low; + u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ + u8 reserved1[1]; + __le16 len; + u8 reserved2[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_add_tlv); /* Update LLDP TLV (indirect 0x0A03) */ struct i40e_aqc_lldp_update_tlv { - u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ - u8 reserved; - __le16 old_len; - __le16 new_offset; - __le16 new_len; - __le32 addr_high; - __le32 addr_low; + u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ + u8 reserved; + __le16 old_len; + __le16 new_offset; + __le16 new_len; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv); /* Stop LLDP (direct 0x0A05) */ struct i40e_aqc_lldp_stop { - u8 command; -#define I40E_AQ_LLDP_AGENT_STOP 0x0 -#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 - u8 reserved[15]; + u8 command; +#define I40E_AQ_LLDP_AGENT_STOP 0x0 +#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); @@ -1981,9 +1980,9 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); /* Start LLDP (direct 0x0A06) */ struct i40e_aqc_lldp_start { - u8 command; -#define I40E_AQ_LLDP_AGENT_START 0x1 - u8 reserved[15]; + u8 command; +#define I40E_AQ_LLDP_AGENT_START 0x1 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); @@ -1994,44 +1993,44 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); /* Add Udp Tunnel command and completion (direct 0x0B00) */ struct i40e_aqc_add_udp_tunnel { - __le16 udp_port; - u8 reserved0[3]; - u8 protocol_type; + __le16 udp_port; + u8 reserved0[3]; + u8 protocol_type; #define I40E_AQC_TUNNEL_TYPE_VXLAN 0x00 #define I40E_AQC_TUNNEL_TYPE_NGE 0x01 #define I40E_AQC_TUNNEL_TYPE_TEREDO 0x10 - u8 reserved1[10]; + u8 reserved1[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel); struct i40e_aqc_add_udp_tunnel_completion { - __le16 udp_port; - u8 filter_entry_index; - u8 multiple_pfs; -#define I40E_AQC_SINGLE_PF 0x0 -#define I40E_AQC_MULTIPLE_PFS 0x1 - u8 total_filters; - u8 reserved[11]; + __le16 udp_port; + u8 filter_entry_index; + u8 multiple_pfs; +#define I40E_AQC_SINGLE_PF 0x0 +#define I40E_AQC_MULTIPLE_PFS 0x1 + u8 total_filters; + u8 reserved[11]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel_completion); /* remove UDP Tunnel command (0x0B01) */ struct i40e_aqc_remove_udp_tunnel { - u8 reserved[2]; - u8 index; /* 0 to 15 */ - u8 reserved2[13]; + u8 reserved[2]; + u8 index; /* 0 to 15 */ + u8 reserved2[13]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel); struct i40e_aqc_del_udp_tunnel_completion { - __le16 udp_port; - u8 index; /* 0 to 15 */ - u8 multiple_pfs; - u8 total_filters_used; - u8 reserved1[11]; + __le16 udp_port; + u8 index; /* 0 to 15 */ + u8 multiple_pfs; + u8 total_filters_used; + u8 reserved1[11]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion); @@ -2044,11 +2043,11 @@ struct i40e_aqc_tunnel_key_structure { u8 key1_len; /* 0 to 15 */ u8 key2_len; /* 0 to 15 */ u8 flags; -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01 +#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01 /* response flags */ -#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01 -#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02 -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03 +#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01 +#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02 +#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03 u8 network_key_index; #define I40E_AQC_NETWORK_KEY_INDEX_VXLAN 0x0 #define I40E_AQC_NETWORK_KEY_INDEX_NGE 0x1 @@ -2061,21 +2060,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure); /* OEM mode commands (direct 0xFE0x) */ struct i40e_aqc_oem_param_change { - __le32 param_type; -#define I40E_AQ_OEM_PARAM_TYPE_PF_CTL 0 -#define I40E_AQ_OEM_PARAM_TYPE_BW_CTL 1 -#define I40E_AQ_OEM_PARAM_MAC 2 - __le32 param_value1; - u8 param_value2[8]; + __le32 param_type; +#define I40E_AQ_OEM_PARAM_TYPE_PF_CTL 0 +#define I40E_AQ_OEM_PARAM_TYPE_BW_CTL 1 +#define I40E_AQ_OEM_PARAM_MAC 2 + __le32 param_value1; + u8 param_value2[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_param_change); struct i40e_aqc_oem_state_change { - __le32 state; -#define I40E_AQ_OEM_STATE_LINK_DOWN 0x0 -#define I40E_AQ_OEM_STATE_LINK_UP 0x1 - u8 reserved[12]; + __le32 state; +#define I40E_AQ_OEM_STATE_LINK_DOWN 0x0 +#define I40E_AQ_OEM_STATE_LINK_UP 0x1 + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_state_change); @@ -2087,18 +2086,18 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_state_change); /* set test more (0xFF01, internal) */ struct i40e_acq_set_test_mode { - u8 mode; -#define I40E_AQ_TEST_PARTIAL 0 -#define I40E_AQ_TEST_FULL 1 -#define I40E_AQ_TEST_NVM 2 - u8 reserved[3]; - u8 command; -#define I40E_AQ_TEST_OPEN 0 -#define I40E_AQ_TEST_CLOSE 1 -#define I40E_AQ_TEST_INC 2 - u8 reserved2[3]; - __le32 address_high; - __le32 address_low; + u8 mode; +#define I40E_AQ_TEST_PARTIAL 0 +#define I40E_AQ_TEST_FULL 1 +#define I40E_AQ_TEST_NVM 2 + u8 reserved[3]; + u8 command; +#define I40E_AQ_TEST_OPEN 0 +#define I40E_AQ_TEST_CLOSE 1 +#define I40E_AQ_TEST_INC 2 + u8 reserved2[3]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_acq_set_test_mode); @@ -2151,21 +2150,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg); #define I40E_AQ_CLUSTER_ID_ALTRAM 11 struct i40e_aqc_debug_dump_internals { - u8 cluster_id; - u8 table_id; - __le16 data_size; - __le32 idx; - __le32 address_high; - __le32 address_low; + u8 cluster_id; + u8 table_id; + __le16 data_size; + __le32 idx; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_dump_internals); struct i40e_aqc_debug_modify_internals { - u8 cluster_id; - u8 cluster_specific_params[7]; - __le32 address_high; - __le32 address_low; + u8 cluster_id; + u8 cluster_specific_params[7]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h index e656ea7a7920..ff1b16370da9 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h @@ -33,8 +33,8 @@ * This file needs to comply with the Linux Kernel coding style. */ -#define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0002 +#define I40E_FW_API_VERSION_MAJOR 0x0001 +#define I40E_FW_API_VERSION_MINOR 0x0002 #define I40E_FW_API_VERSION_A0_MINOR 0x0000 struct i40e_aq_desc { @@ -67,216 +67,216 @@ struct i40e_aq_desc { */ /* command flags and offsets*/ -#define I40E_AQ_FLAG_DD_SHIFT 0 -#define I40E_AQ_FLAG_CMP_SHIFT 1 -#define I40E_AQ_FLAG_ERR_SHIFT 2 -#define I40E_AQ_FLAG_VFE_SHIFT 3 -#define I40E_AQ_FLAG_LB_SHIFT 9 -#define I40E_AQ_FLAG_RD_SHIFT 10 -#define I40E_AQ_FLAG_VFC_SHIFT 11 -#define I40E_AQ_FLAG_BUF_SHIFT 12 -#define I40E_AQ_FLAG_SI_SHIFT 13 -#define I40E_AQ_FLAG_EI_SHIFT 14 -#define I40E_AQ_FLAG_FE_SHIFT 15 - -#define I40E_AQ_FLAG_DD (1 << I40E_AQ_FLAG_DD_SHIFT) /* 0x1 */ -#define I40E_AQ_FLAG_CMP (1 << I40E_AQ_FLAG_CMP_SHIFT) /* 0x2 */ -#define I40E_AQ_FLAG_ERR (1 << I40E_AQ_FLAG_ERR_SHIFT) /* 0x4 */ -#define I40E_AQ_FLAG_VFE (1 << I40E_AQ_FLAG_VFE_SHIFT) /* 0x8 */ -#define I40E_AQ_FLAG_LB (1 << I40E_AQ_FLAG_LB_SHIFT) /* 0x200 */ -#define I40E_AQ_FLAG_RD (1 << I40E_AQ_FLAG_RD_SHIFT) /* 0x400 */ -#define I40E_AQ_FLAG_VFC (1 << I40E_AQ_FLAG_VFC_SHIFT) /* 0x800 */ -#define I40E_AQ_FLAG_BUF (1 << I40E_AQ_FLAG_BUF_SHIFT) /* 0x1000 */ -#define I40E_AQ_FLAG_SI (1 << I40E_AQ_FLAG_SI_SHIFT) /* 0x2000 */ -#define I40E_AQ_FLAG_EI (1 << I40E_AQ_FLAG_EI_SHIFT) /* 0x4000 */ -#define I40E_AQ_FLAG_FE (1 << I40E_AQ_FLAG_FE_SHIFT) /* 0x8000 */ +#define I40E_AQ_FLAG_DD_SHIFT 0 +#define I40E_AQ_FLAG_CMP_SHIFT 1 +#define I40E_AQ_FLAG_ERR_SHIFT 2 +#define I40E_AQ_FLAG_VFE_SHIFT 3 +#define I40E_AQ_FLAG_LB_SHIFT 9 +#define I40E_AQ_FLAG_RD_SHIFT 10 +#define I40E_AQ_FLAG_VFC_SHIFT 11 +#define I40E_AQ_FLAG_BUF_SHIFT 12 +#define I40E_AQ_FLAG_SI_SHIFT 13 +#define I40E_AQ_FLAG_EI_SHIFT 14 +#define I40E_AQ_FLAG_FE_SHIFT 15 + +#define I40E_AQ_FLAG_DD (1 << I40E_AQ_FLAG_DD_SHIFT) /* 0x1 */ +#define I40E_AQ_FLAG_CMP (1 << I40E_AQ_FLAG_CMP_SHIFT) /* 0x2 */ +#define I40E_AQ_FLAG_ERR (1 << I40E_AQ_FLAG_ERR_SHIFT) /* 0x4 */ +#define I40E_AQ_FLAG_VFE (1 << I40E_AQ_FLAG_VFE_SHIFT) /* 0x8 */ +#define I40E_AQ_FLAG_LB (1 << I40E_AQ_FLAG_LB_SHIFT) /* 0x200 */ +#define I40E_AQ_FLAG_RD (1 << I40E_AQ_FLAG_RD_SHIFT) /* 0x400 */ +#define I40E_AQ_FLAG_VFC (1 << I40E_AQ_FLAG_VFC_SHIFT) /* 0x800 */ +#define I40E_AQ_FLAG_BUF (1 << I40E_AQ_FLAG_BUF_SHIFT) /* 0x1000 */ +#define I40E_AQ_FLAG_SI (1 << I40E_AQ_FLAG_SI_SHIFT) /* 0x2000 */ +#define I40E_AQ_FLAG_EI (1 << I40E_AQ_FLAG_EI_SHIFT) /* 0x4000 */ +#define I40E_AQ_FLAG_FE (1 << I40E_AQ_FLAG_FE_SHIFT) /* 0x8000 */ /* error codes */ enum i40e_admin_queue_err { - I40E_AQ_RC_OK = 0, /* success */ - I40E_AQ_RC_EPERM = 1, /* Operation not permitted */ - I40E_AQ_RC_ENOENT = 2, /* No such element */ - I40E_AQ_RC_ESRCH = 3, /* Bad opcode */ - I40E_AQ_RC_EINTR = 4, /* operation interrupted */ - I40E_AQ_RC_EIO = 5, /* I/O error */ - I40E_AQ_RC_ENXIO = 6, /* No such resource */ - I40E_AQ_RC_E2BIG = 7, /* Arg too long */ - I40E_AQ_RC_EAGAIN = 8, /* Try again */ - I40E_AQ_RC_ENOMEM = 9, /* Out of memory */ - I40E_AQ_RC_EACCES = 10, /* Permission denied */ - I40E_AQ_RC_EFAULT = 11, /* Bad address */ - I40E_AQ_RC_EBUSY = 12, /* Device or resource busy */ - I40E_AQ_RC_EEXIST = 13, /* object already exists */ - I40E_AQ_RC_EINVAL = 14, /* Invalid argument */ - I40E_AQ_RC_ENOTTY = 15, /* Not a typewriter */ - I40E_AQ_RC_ENOSPC = 16, /* No space left or alloc failure */ - I40E_AQ_RC_ENOSYS = 17, /* Function not implemented */ - I40E_AQ_RC_ERANGE = 18, /* Parameter out of range */ - I40E_AQ_RC_EFLUSHED = 19, /* Cmd flushed because of prev cmd error */ - I40E_AQ_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */ - I40E_AQ_RC_EMODE = 21, /* Op not allowed in current dev mode */ - I40E_AQ_RC_EFBIG = 22, /* File too large */ + I40E_AQ_RC_OK = 0, /* success */ + I40E_AQ_RC_EPERM = 1, /* Operation not permitted */ + I40E_AQ_RC_ENOENT = 2, /* No such element */ + I40E_AQ_RC_ESRCH = 3, /* Bad opcode */ + I40E_AQ_RC_EINTR = 4, /* operation interrupted */ + I40E_AQ_RC_EIO = 5, /* I/O error */ + I40E_AQ_RC_ENXIO = 6, /* No such resource */ + I40E_AQ_RC_E2BIG = 7, /* Arg too long */ + I40E_AQ_RC_EAGAIN = 8, /* Try again */ + I40E_AQ_RC_ENOMEM = 9, /* Out of memory */ + I40E_AQ_RC_EACCES = 10, /* Permission denied */ + I40E_AQ_RC_EFAULT = 11, /* Bad address */ + I40E_AQ_RC_EBUSY = 12, /* Device or resource busy */ + I40E_AQ_RC_EEXIST = 13, /* object already exists */ + I40E_AQ_RC_EINVAL = 14, /* Invalid argument */ + I40E_AQ_RC_ENOTTY = 15, /* Not a typewriter */ + I40E_AQ_RC_ENOSPC = 16, /* No space left or alloc failure */ + I40E_AQ_RC_ENOSYS = 17, /* Function not implemented */ + I40E_AQ_RC_ERANGE = 18, /* Parameter out of range */ + I40E_AQ_RC_EFLUSHED = 19, /* Cmd flushed due to prev cmd error */ + I40E_AQ_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */ + I40E_AQ_RC_EMODE = 21, /* Op not allowed in current dev mode */ + I40E_AQ_RC_EFBIG = 22, /* File too large */ }; /* Admin Queue command opcodes */ enum i40e_admin_queue_opc { /* aq commands */ - i40e_aqc_opc_get_version = 0x0001, - i40e_aqc_opc_driver_version = 0x0002, - i40e_aqc_opc_queue_shutdown = 0x0003, - i40e_aqc_opc_set_pf_context = 0x0004, + i40e_aqc_opc_get_version = 0x0001, + i40e_aqc_opc_driver_version = 0x0002, + i40e_aqc_opc_queue_shutdown = 0x0003, + i40e_aqc_opc_set_pf_context = 0x0004, /* resource ownership */ - i40e_aqc_opc_request_resource = 0x0008, - i40e_aqc_opc_release_resource = 0x0009, + i40e_aqc_opc_request_resource = 0x0008, + i40e_aqc_opc_release_resource = 0x0009, - i40e_aqc_opc_list_func_capabilities = 0x000A, - i40e_aqc_opc_list_dev_capabilities = 0x000B, + i40e_aqc_opc_list_func_capabilities = 0x000A, + i40e_aqc_opc_list_dev_capabilities = 0x000B, - i40e_aqc_opc_set_cppm_configuration = 0x0103, - i40e_aqc_opc_set_arp_proxy_entry = 0x0104, - i40e_aqc_opc_set_ns_proxy_entry = 0x0105, + i40e_aqc_opc_set_cppm_configuration = 0x0103, + i40e_aqc_opc_set_arp_proxy_entry = 0x0104, + i40e_aqc_opc_set_ns_proxy_entry = 0x0105, /* LAA */ - i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */ - i40e_aqc_opc_mac_address_read = 0x0107, - i40e_aqc_opc_mac_address_write = 0x0108, + i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */ + i40e_aqc_opc_mac_address_read = 0x0107, + i40e_aqc_opc_mac_address_write = 0x0108, /* PXE */ - i40e_aqc_opc_clear_pxe_mode = 0x0110, + i40e_aqc_opc_clear_pxe_mode = 0x0110, /* internal switch commands */ - i40e_aqc_opc_get_switch_config = 0x0200, - i40e_aqc_opc_add_statistics = 0x0201, - i40e_aqc_opc_remove_statistics = 0x0202, - i40e_aqc_opc_set_port_parameters = 0x0203, - i40e_aqc_opc_get_switch_resource_alloc = 0x0204, - - i40e_aqc_opc_add_vsi = 0x0210, - i40e_aqc_opc_update_vsi_parameters = 0x0211, - i40e_aqc_opc_get_vsi_parameters = 0x0212, - - i40e_aqc_opc_add_pv = 0x0220, - i40e_aqc_opc_update_pv_parameters = 0x0221, - i40e_aqc_opc_get_pv_parameters = 0x0222, - - i40e_aqc_opc_add_veb = 0x0230, - i40e_aqc_opc_update_veb_parameters = 0x0231, - i40e_aqc_opc_get_veb_parameters = 0x0232, - - i40e_aqc_opc_delete_element = 0x0243, - - i40e_aqc_opc_add_macvlan = 0x0250, - i40e_aqc_opc_remove_macvlan = 0x0251, - i40e_aqc_opc_add_vlan = 0x0252, - i40e_aqc_opc_remove_vlan = 0x0253, - i40e_aqc_opc_set_vsi_promiscuous_modes = 0x0254, - i40e_aqc_opc_add_tag = 0x0255, - i40e_aqc_opc_remove_tag = 0x0256, - i40e_aqc_opc_add_multicast_etag = 0x0257, - i40e_aqc_opc_remove_multicast_etag = 0x0258, - i40e_aqc_opc_update_tag = 0x0259, - i40e_aqc_opc_add_control_packet_filter = 0x025A, - i40e_aqc_opc_remove_control_packet_filter = 0x025B, - i40e_aqc_opc_add_cloud_filters = 0x025C, - i40e_aqc_opc_remove_cloud_filters = 0x025D, - - i40e_aqc_opc_add_mirror_rule = 0x0260, - i40e_aqc_opc_delete_mirror_rule = 0x0261, + i40e_aqc_opc_get_switch_config = 0x0200, + i40e_aqc_opc_add_statistics = 0x0201, + i40e_aqc_opc_remove_statistics = 0x0202, + i40e_aqc_opc_set_port_parameters = 0x0203, + i40e_aqc_opc_get_switch_resource_alloc = 0x0204, + + i40e_aqc_opc_add_vsi = 0x0210, + i40e_aqc_opc_update_vsi_parameters = 0x0211, + i40e_aqc_opc_get_vsi_parameters = 0x0212, + + i40e_aqc_opc_add_pv = 0x0220, + i40e_aqc_opc_update_pv_parameters = 0x0221, + i40e_aqc_opc_get_pv_parameters = 0x0222, + + i40e_aqc_opc_add_veb = 0x0230, + i40e_aqc_opc_update_veb_parameters = 0x0231, + i40e_aqc_opc_get_veb_parameters = 0x0232, + + i40e_aqc_opc_delete_element = 0x0243, + + i40e_aqc_opc_add_macvlan = 0x0250, + i40e_aqc_opc_remove_macvlan = 0x0251, + i40e_aqc_opc_add_vlan = 0x0252, + i40e_aqc_opc_remove_vlan = 0x0253, + i40e_aqc_opc_set_vsi_promiscuous_modes = 0x0254, + i40e_aqc_opc_add_tag = 0x0255, + i40e_aqc_opc_remove_tag = 0x0256, + i40e_aqc_opc_add_multicast_etag = 0x0257, + i40e_aqc_opc_remove_multicast_etag = 0x0258, + i40e_aqc_opc_update_tag = 0x0259, + i40e_aqc_opc_add_control_packet_filter = 0x025A, + i40e_aqc_opc_remove_control_packet_filter = 0x025B, + i40e_aqc_opc_add_cloud_filters = 0x025C, + i40e_aqc_opc_remove_cloud_filters = 0x025D, + + i40e_aqc_opc_add_mirror_rule = 0x0260, + i40e_aqc_opc_delete_mirror_rule = 0x0261, /* DCB commands */ - i40e_aqc_opc_dcb_ignore_pfc = 0x0301, - i40e_aqc_opc_dcb_updated = 0x0302, + i40e_aqc_opc_dcb_ignore_pfc = 0x0301, + i40e_aqc_opc_dcb_updated = 0x0302, /* TX scheduler */ - i40e_aqc_opc_configure_vsi_bw_limit = 0x0400, - i40e_aqc_opc_configure_vsi_ets_sla_bw_limit = 0x0406, - i40e_aqc_opc_configure_vsi_tc_bw = 0x0407, - i40e_aqc_opc_query_vsi_bw_config = 0x0408, - i40e_aqc_opc_query_vsi_ets_sla_config = 0x040A, - i40e_aqc_opc_configure_switching_comp_bw_limit = 0x0410, - - i40e_aqc_opc_enable_switching_comp_ets = 0x0413, - i40e_aqc_opc_modify_switching_comp_ets = 0x0414, - i40e_aqc_opc_disable_switching_comp_ets = 0x0415, - i40e_aqc_opc_configure_switching_comp_ets_bw_limit = 0x0416, - i40e_aqc_opc_configure_switching_comp_bw_config = 0x0417, - i40e_aqc_opc_query_switching_comp_ets_config = 0x0418, - i40e_aqc_opc_query_port_ets_config = 0x0419, - i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, - i40e_aqc_opc_suspend_port_tx = 0x041B, - i40e_aqc_opc_resume_port_tx = 0x041C, - i40e_aqc_opc_configure_partition_bw = 0x041D, + i40e_aqc_opc_configure_vsi_bw_limit = 0x0400, + i40e_aqc_opc_configure_vsi_ets_sla_bw_limit = 0x0406, + i40e_aqc_opc_configure_vsi_tc_bw = 0x0407, + i40e_aqc_opc_query_vsi_bw_config = 0x0408, + i40e_aqc_opc_query_vsi_ets_sla_config = 0x040A, + i40e_aqc_opc_configure_switching_comp_bw_limit = 0x0410, + + i40e_aqc_opc_enable_switching_comp_ets = 0x0413, + i40e_aqc_opc_modify_switching_comp_ets = 0x0414, + i40e_aqc_opc_disable_switching_comp_ets = 0x0415, + i40e_aqc_opc_configure_switching_comp_ets_bw_limit = 0x0416, + i40e_aqc_opc_configure_switching_comp_bw_config = 0x0417, + i40e_aqc_opc_query_switching_comp_ets_config = 0x0418, + i40e_aqc_opc_query_port_ets_config = 0x0419, + i40e_aqc_opc_query_switching_comp_bw_config = 0x041A, + i40e_aqc_opc_suspend_port_tx = 0x041B, + i40e_aqc_opc_resume_port_tx = 0x041C, + i40e_aqc_opc_configure_partition_bw = 0x041D, /* hmc */ - i40e_aqc_opc_query_hmc_resource_profile = 0x0500, - i40e_aqc_opc_set_hmc_resource_profile = 0x0501, + i40e_aqc_opc_query_hmc_resource_profile = 0x0500, + i40e_aqc_opc_set_hmc_resource_profile = 0x0501, /* phy commands*/ - i40e_aqc_opc_get_phy_abilities = 0x0600, - i40e_aqc_opc_set_phy_config = 0x0601, - i40e_aqc_opc_set_mac_config = 0x0603, - i40e_aqc_opc_set_link_restart_an = 0x0605, - i40e_aqc_opc_get_link_status = 0x0607, - i40e_aqc_opc_set_phy_int_mask = 0x0613, - i40e_aqc_opc_get_local_advt_reg = 0x0614, - i40e_aqc_opc_set_local_advt_reg = 0x0615, - i40e_aqc_opc_get_partner_advt = 0x0616, - i40e_aqc_opc_set_lb_modes = 0x0618, - i40e_aqc_opc_get_phy_wol_caps = 0x0621, - i40e_aqc_opc_set_phy_debug = 0x0622, - i40e_aqc_opc_upload_ext_phy_fm = 0x0625, + i40e_aqc_opc_get_phy_abilities = 0x0600, + i40e_aqc_opc_set_phy_config = 0x0601, + i40e_aqc_opc_set_mac_config = 0x0603, + i40e_aqc_opc_set_link_restart_an = 0x0605, + i40e_aqc_opc_get_link_status = 0x0607, + i40e_aqc_opc_set_phy_int_mask = 0x0613, + i40e_aqc_opc_get_local_advt_reg = 0x0614, + i40e_aqc_opc_set_local_advt_reg = 0x0615, + i40e_aqc_opc_get_partner_advt = 0x0616, + i40e_aqc_opc_set_lb_modes = 0x0618, + i40e_aqc_opc_get_phy_wol_caps = 0x0621, + i40e_aqc_opc_set_phy_debug = 0x0622, + i40e_aqc_opc_upload_ext_phy_fm = 0x0625, /* NVM commands */ - i40e_aqc_opc_nvm_read = 0x0701, - i40e_aqc_opc_nvm_erase = 0x0702, - i40e_aqc_opc_nvm_update = 0x0703, - i40e_aqc_opc_nvm_config_read = 0x0704, - i40e_aqc_opc_nvm_config_write = 0x0705, + i40e_aqc_opc_nvm_read = 0x0701, + i40e_aqc_opc_nvm_erase = 0x0702, + i40e_aqc_opc_nvm_update = 0x0703, + i40e_aqc_opc_nvm_config_read = 0x0704, + i40e_aqc_opc_nvm_config_write = 0x0705, /* virtualization commands */ - i40e_aqc_opc_send_msg_to_pf = 0x0801, - i40e_aqc_opc_send_msg_to_vf = 0x0802, - i40e_aqc_opc_send_msg_to_peer = 0x0803, + i40e_aqc_opc_send_msg_to_pf = 0x0801, + i40e_aqc_opc_send_msg_to_vf = 0x0802, + i40e_aqc_opc_send_msg_to_peer = 0x0803, /* alternate structure */ - i40e_aqc_opc_alternate_write = 0x0900, - i40e_aqc_opc_alternate_write_indirect = 0x0901, - i40e_aqc_opc_alternate_read = 0x0902, - i40e_aqc_opc_alternate_read_indirect = 0x0903, - i40e_aqc_opc_alternate_write_done = 0x0904, - i40e_aqc_opc_alternate_set_mode = 0x0905, - i40e_aqc_opc_alternate_clear_port = 0x0906, + i40e_aqc_opc_alternate_write = 0x0900, + i40e_aqc_opc_alternate_write_indirect = 0x0901, + i40e_aqc_opc_alternate_read = 0x0902, + i40e_aqc_opc_alternate_read_indirect = 0x0903, + i40e_aqc_opc_alternate_write_done = 0x0904, + i40e_aqc_opc_alternate_set_mode = 0x0905, + i40e_aqc_opc_alternate_clear_port = 0x0906, /* LLDP commands */ - i40e_aqc_opc_lldp_get_mib = 0x0A00, - i40e_aqc_opc_lldp_update_mib = 0x0A01, - i40e_aqc_opc_lldp_add_tlv = 0x0A02, - i40e_aqc_opc_lldp_update_tlv = 0x0A03, - i40e_aqc_opc_lldp_delete_tlv = 0x0A04, - i40e_aqc_opc_lldp_stop = 0x0A05, - i40e_aqc_opc_lldp_start = 0x0A06, + i40e_aqc_opc_lldp_get_mib = 0x0A00, + i40e_aqc_opc_lldp_update_mib = 0x0A01, + i40e_aqc_opc_lldp_add_tlv = 0x0A02, + i40e_aqc_opc_lldp_update_tlv = 0x0A03, + i40e_aqc_opc_lldp_delete_tlv = 0x0A04, + i40e_aqc_opc_lldp_stop = 0x0A05, + i40e_aqc_opc_lldp_start = 0x0A06, /* Tunnel commands */ - i40e_aqc_opc_add_udp_tunnel = 0x0B00, - i40e_aqc_opc_del_udp_tunnel = 0x0B01, - i40e_aqc_opc_tunnel_key_structure = 0x0B10, + i40e_aqc_opc_add_udp_tunnel = 0x0B00, + i40e_aqc_opc_del_udp_tunnel = 0x0B01, + i40e_aqc_opc_tunnel_key_structure = 0x0B10, /* Async Events */ - i40e_aqc_opc_event_lan_overflow = 0x1001, + i40e_aqc_opc_event_lan_overflow = 0x1001, /* OEM commands */ - i40e_aqc_opc_oem_parameter_change = 0xFE00, - i40e_aqc_opc_oem_device_status_change = 0xFE01, + i40e_aqc_opc_oem_parameter_change = 0xFE00, + i40e_aqc_opc_oem_device_status_change = 0xFE01, /* debug commands */ - i40e_aqc_opc_debug_get_deviceid = 0xFF00, - i40e_aqc_opc_debug_set_mode = 0xFF01, - i40e_aqc_opc_debug_read_reg = 0xFF03, - i40e_aqc_opc_debug_write_reg = 0xFF04, - i40e_aqc_opc_debug_modify_reg = 0xFF07, - i40e_aqc_opc_debug_dump_internals = 0xFF08, - i40e_aqc_opc_debug_modify_internals = 0xFF09, + i40e_aqc_opc_debug_get_deviceid = 0xFF00, + i40e_aqc_opc_debug_set_mode = 0xFF01, + i40e_aqc_opc_debug_read_reg = 0xFF03, + i40e_aqc_opc_debug_write_reg = 0xFF04, + i40e_aqc_opc_debug_modify_reg = 0xFF07, + i40e_aqc_opc_debug_dump_internals = 0xFF08, + i40e_aqc_opc_debug_modify_internals = 0xFF09, }; /* command structures and indirect data structures */ @@ -303,7 +303,7 @@ enum i40e_admin_queue_opc { /* This macro is used extensively to ensure that command structures are 16 * bytes in length as they have to map to the raw array of that size. */ -#define I40E_CHECK_CMD_LENGTH(X) I40E_CHECK_STRUCT_LEN(16, X) +#define I40E_CHECK_CMD_LENGTH(X) I40E_CHECK_STRUCT_LEN(16, X) /* internal (0x00XX) commands */ @@ -321,22 +321,22 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_version); /* Send driver version (indirect 0x0002) */ struct i40e_aqc_driver_version { - u8 driver_major_ver; - u8 driver_minor_ver; - u8 driver_build_ver; - u8 driver_subbuild_ver; - u8 reserved[4]; - __le32 address_high; - __le32 address_low; + u8 driver_major_ver; + u8 driver_minor_ver; + u8 driver_build_ver; + u8 driver_subbuild_ver; + u8 reserved[4]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_driver_version); /* Queue Shutdown (direct 0x0003) */ struct i40e_aqc_queue_shutdown { - __le32 driver_unloading; -#define I40E_AQ_DRIVER_UNLOADING 0x1 - u8 reserved[12]; + __le32 driver_unloading; +#define I40E_AQ_DRIVER_UNLOADING 0x1 + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_queue_shutdown); @@ -352,19 +352,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_pf_context); /* Request resource ownership (direct 0x0008) * Release resource ownership (direct 0x0009) */ -#define I40E_AQ_RESOURCE_NVM 1 -#define I40E_AQ_RESOURCE_SDP 2 -#define I40E_AQ_RESOURCE_ACCESS_READ 1 -#define I40E_AQ_RESOURCE_ACCESS_WRITE 2 -#define I40E_AQ_RESOURCE_NVM_READ_TIMEOUT 3000 -#define I40E_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000 +#define I40E_AQ_RESOURCE_NVM 1 +#define I40E_AQ_RESOURCE_SDP 2 +#define I40E_AQ_RESOURCE_ACCESS_READ 1 +#define I40E_AQ_RESOURCE_ACCESS_WRITE 2 +#define I40E_AQ_RESOURCE_NVM_READ_TIMEOUT 3000 +#define I40E_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000 struct i40e_aqc_request_resource { - __le16 resource_id; - __le16 access_type; - __le32 timeout; - __le32 resource_number; - u8 reserved[4]; + __le16 resource_id; + __le16 access_type; + __le32 timeout; + __le32 resource_number; + u8 reserved[4]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_request_resource); @@ -374,7 +374,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_request_resource); */ struct i40e_aqc_list_capabilites { u8 command_flags; -#define I40E_AQ_LIST_CAP_PF_INDEX_EN 1 +#define I40E_AQ_LIST_CAP_PF_INDEX_EN 1 u8 pf_index; u8 reserved[2]; __le32 count; @@ -385,123 +385,123 @@ struct i40e_aqc_list_capabilites { I40E_CHECK_CMD_LENGTH(i40e_aqc_list_capabilites); struct i40e_aqc_list_capabilities_element_resp { - __le16 id; - u8 major_rev; - u8 minor_rev; - __le32 number; - __le32 logical_id; - __le32 phys_id; - u8 reserved[16]; + __le16 id; + u8 major_rev; + u8 minor_rev; + __le32 number; + __le32 logical_id; + __le32 phys_id; + u8 reserved[16]; }; /* list of caps */ -#define I40E_AQ_CAP_ID_SWITCH_MODE 0x0001 -#define I40E_AQ_CAP_ID_MNG_MODE 0x0002 -#define I40E_AQ_CAP_ID_NPAR_ACTIVE 0x0003 -#define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004 -#define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005 -#define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006 -#define I40E_AQ_CAP_ID_SRIOV 0x0012 -#define I40E_AQ_CAP_ID_VF 0x0013 -#define I40E_AQ_CAP_ID_VMDQ 0x0014 -#define I40E_AQ_CAP_ID_8021QBG 0x0015 -#define I40E_AQ_CAP_ID_8021QBR 0x0016 -#define I40E_AQ_CAP_ID_VSI 0x0017 -#define I40E_AQ_CAP_ID_DCB 0x0018 -#define I40E_AQ_CAP_ID_FCOE 0x0021 -#define I40E_AQ_CAP_ID_RSS 0x0040 -#define I40E_AQ_CAP_ID_RXQ 0x0041 -#define I40E_AQ_CAP_ID_TXQ 0x0042 -#define I40E_AQ_CAP_ID_MSIX 0x0043 -#define I40E_AQ_CAP_ID_VF_MSIX 0x0044 -#define I40E_AQ_CAP_ID_FLOW_DIRECTOR 0x0045 -#define I40E_AQ_CAP_ID_1588 0x0046 -#define I40E_AQ_CAP_ID_IWARP 0x0051 -#define I40E_AQ_CAP_ID_LED 0x0061 -#define I40E_AQ_CAP_ID_SDP 0x0062 -#define I40E_AQ_CAP_ID_MDIO 0x0063 -#define I40E_AQ_CAP_ID_FLEX10 0x00F1 -#define I40E_AQ_CAP_ID_CEM 0x00F2 +#define I40E_AQ_CAP_ID_SWITCH_MODE 0x0001 +#define I40E_AQ_CAP_ID_MNG_MODE 0x0002 +#define I40E_AQ_CAP_ID_NPAR_ACTIVE 0x0003 +#define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004 +#define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005 +#define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006 +#define I40E_AQ_CAP_ID_SRIOV 0x0012 +#define I40E_AQ_CAP_ID_VF 0x0013 +#define I40E_AQ_CAP_ID_VMDQ 0x0014 +#define I40E_AQ_CAP_ID_8021QBG 0x0015 +#define I40E_AQ_CAP_ID_8021QBR 0x0016 +#define I40E_AQ_CAP_ID_VSI 0x0017 +#define I40E_AQ_CAP_ID_DCB 0x0018 +#define I40E_AQ_CAP_ID_FCOE 0x0021 +#define I40E_AQ_CAP_ID_RSS 0x0040 +#define I40E_AQ_CAP_ID_RXQ 0x0041 +#define I40E_AQ_CAP_ID_TXQ 0x0042 +#define I40E_AQ_CAP_ID_MSIX 0x0043 +#define I40E_AQ_CAP_ID_VF_MSIX 0x0044 +#define I40E_AQ_CAP_ID_FLOW_DIRECTOR 0x0045 +#define I40E_AQ_CAP_ID_1588 0x0046 +#define I40E_AQ_CAP_ID_IWARP 0x0051 +#define I40E_AQ_CAP_ID_LED 0x0061 +#define I40E_AQ_CAP_ID_SDP 0x0062 +#define I40E_AQ_CAP_ID_MDIO 0x0063 +#define I40E_AQ_CAP_ID_FLEX10 0x00F1 +#define I40E_AQ_CAP_ID_CEM 0x00F2 /* Set CPPM Configuration (direct 0x0103) */ struct i40e_aqc_cppm_configuration { - __le16 command_flags; -#define I40E_AQ_CPPM_EN_LTRC 0x0800 -#define I40E_AQ_CPPM_EN_DMCTH 0x1000 -#define I40E_AQ_CPPM_EN_DMCTLX 0x2000 -#define I40E_AQ_CPPM_EN_HPTC 0x4000 -#define I40E_AQ_CPPM_EN_DMARC 0x8000 - __le16 ttlx; - __le32 dmacr; - __le16 dmcth; - u8 hptc; - u8 reserved; - __le32 pfltrc; + __le16 command_flags; +#define I40E_AQ_CPPM_EN_LTRC 0x0800 +#define I40E_AQ_CPPM_EN_DMCTH 0x1000 +#define I40E_AQ_CPPM_EN_DMCTLX 0x2000 +#define I40E_AQ_CPPM_EN_HPTC 0x4000 +#define I40E_AQ_CPPM_EN_DMARC 0x8000 + __le16 ttlx; + __le32 dmacr; + __le16 dmcth; + u8 hptc; + u8 reserved; + __le32 pfltrc; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration); /* Set ARP Proxy command / response (indirect 0x0104) */ struct i40e_aqc_arp_proxy_data { - __le16 command_flags; -#define I40E_AQ_ARP_INIT_IPV4 0x0008 -#define I40E_AQ_ARP_UNSUP_CTL 0x0010 -#define I40E_AQ_ARP_ENA 0x0020 -#define I40E_AQ_ARP_ADD_IPV4 0x0040 -#define I40E_AQ_ARP_DEL_IPV4 0x0080 - __le16 table_id; - __le32 pfpm_proxyfc; - __le32 ip_addr; - u8 mac_addr[6]; + __le16 command_flags; +#define I40E_AQ_ARP_INIT_IPV4 0x0008 +#define I40E_AQ_ARP_UNSUP_CTL 0x0010 +#define I40E_AQ_ARP_ENA 0x0020 +#define I40E_AQ_ARP_ADD_IPV4 0x0040 +#define I40E_AQ_ARP_DEL_IPV4 0x0080 + __le16 table_id; + __le32 pfpm_proxyfc; + __le32 ip_addr; + u8 mac_addr[6]; }; /* Set NS Proxy Table Entry Command (indirect 0x0105) */ struct i40e_aqc_ns_proxy_data { - __le16 table_idx_mac_addr_0; - __le16 table_idx_mac_addr_1; - __le16 table_idx_ipv6_0; - __le16 table_idx_ipv6_1; - __le16 control; -#define I40E_AQ_NS_PROXY_ADD_0 0x0100 -#define I40E_AQ_NS_PROXY_DEL_0 0x0200 -#define I40E_AQ_NS_PROXY_ADD_1 0x0400 -#define I40E_AQ_NS_PROXY_DEL_1 0x0800 -#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 -#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 -#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 -#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 -#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 -#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 -#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 - u8 mac_addr_0[6]; - u8 mac_addr_1[6]; - u8 local_mac_addr[6]; - u8 ipv6_addr_0[16]; /* Warning! spec specifies BE byte order */ - u8 ipv6_addr_1[16]; + __le16 table_idx_mac_addr_0; + __le16 table_idx_mac_addr_1; + __le16 table_idx_ipv6_0; + __le16 table_idx_ipv6_1; + __le16 control; +#define I40E_AQ_NS_PROXY_ADD_0 0x0100 +#define I40E_AQ_NS_PROXY_DEL_0 0x0200 +#define I40E_AQ_NS_PROXY_ADD_1 0x0400 +#define I40E_AQ_NS_PROXY_DEL_1 0x0800 +#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 +#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 +#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 +#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 +#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 +#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 +#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 + u8 mac_addr_0[6]; + u8 mac_addr_1[6]; + u8 local_mac_addr[6]; + u8 ipv6_addr_0[16]; /* Warning! spec specifies BE byte order */ + u8 ipv6_addr_1[16]; }; /* Manage LAA Command (0x0106) - obsolete */ struct i40e_aqc_mng_laa { __le16 command_flags; -#define I40E_AQ_LAA_FLAG_WR 0x8000 - u8 reserved[2]; - __le32 sal; - __le16 sah; - u8 reserved2[6]; +#define I40E_AQ_LAA_FLAG_WR 0x8000 + u8 reserved[2]; + __le32 sal; + __le16 sah; + u8 reserved2[6]; }; /* Manage MAC Address Read Command (indirect 0x0107) */ struct i40e_aqc_mac_address_read { __le16 command_flags; -#define I40E_AQC_LAN_ADDR_VALID 0x10 -#define I40E_AQC_SAN_ADDR_VALID 0x20 -#define I40E_AQC_PORT_ADDR_VALID 0x40 -#define I40E_AQC_WOL_ADDR_VALID 0x80 -#define I40E_AQC_ADDR_VALID_MASK 0xf0 - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; +#define I40E_AQC_LAN_ADDR_VALID 0x10 +#define I40E_AQC_SAN_ADDR_VALID 0x20 +#define I40E_AQC_PORT_ADDR_VALID 0x40 +#define I40E_AQC_WOL_ADDR_VALID 0x80 +#define I40E_AQC_ADDR_VALID_MASK 0xf0 + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_read); @@ -517,14 +517,14 @@ I40E_CHECK_STRUCT_LEN(24, i40e_aqc_mac_address_read_data); /* Manage MAC Address Write Command (0x0108) */ struct i40e_aqc_mac_address_write { - __le16 command_flags; -#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000 -#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000 -#define I40E_AQC_WRITE_TYPE_PORT 0x8000 -#define I40E_AQC_WRITE_TYPE_MASK 0xc000 - __le16 mac_sah; - __le32 mac_sal; - u8 reserved[8]; + __le16 command_flags; +#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000 +#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000 +#define I40E_AQC_WRITE_TYPE_PORT 0x8000 +#define I40E_AQC_WRITE_TYPE_MASK 0xc000 + __le16 mac_sah; + __le32 mac_sal; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_write); @@ -545,10 +545,10 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe); * command */ struct i40e_aqc_switch_seid { - __le16 seid; - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; + __le16 seid; + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_switch_seid); @@ -557,34 +557,34 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_switch_seid); * uses i40e_aqc_switch_seid for the descriptor */ struct i40e_aqc_get_switch_config_header_resp { - __le16 num_reported; - __le16 num_total; - u8 reserved[12]; + __le16 num_reported; + __le16 num_total; + u8 reserved[12]; }; struct i40e_aqc_switch_config_element_resp { - u8 element_type; -#define I40E_AQ_SW_ELEM_TYPE_MAC 1 -#define I40E_AQ_SW_ELEM_TYPE_PF 2 -#define I40E_AQ_SW_ELEM_TYPE_VF 3 -#define I40E_AQ_SW_ELEM_TYPE_EMP 4 -#define I40E_AQ_SW_ELEM_TYPE_BMC 5 -#define I40E_AQ_SW_ELEM_TYPE_PV 16 -#define I40E_AQ_SW_ELEM_TYPE_VEB 17 -#define I40E_AQ_SW_ELEM_TYPE_PA 18 -#define I40E_AQ_SW_ELEM_TYPE_VSI 19 - u8 revision; -#define I40E_AQ_SW_ELEM_REV_1 1 - __le16 seid; - __le16 uplink_seid; - __le16 downlink_seid; - u8 reserved[3]; - u8 connection_type; -#define I40E_AQ_CONN_TYPE_REGULAR 0x1 -#define I40E_AQ_CONN_TYPE_DEFAULT 0x2 -#define I40E_AQ_CONN_TYPE_CASCADED 0x3 - __le16 scheduler_id; - __le16 element_info; + u8 element_type; +#define I40E_AQ_SW_ELEM_TYPE_MAC 1 +#define I40E_AQ_SW_ELEM_TYPE_PF 2 +#define I40E_AQ_SW_ELEM_TYPE_VF 3 +#define I40E_AQ_SW_ELEM_TYPE_EMP 4 +#define I40E_AQ_SW_ELEM_TYPE_BMC 5 +#define I40E_AQ_SW_ELEM_TYPE_PV 16 +#define I40E_AQ_SW_ELEM_TYPE_VEB 17 +#define I40E_AQ_SW_ELEM_TYPE_PA 18 +#define I40E_AQ_SW_ELEM_TYPE_VSI 19 + u8 revision; +#define I40E_AQ_SW_ELEM_REV_1 1 + __le16 seid; + __le16 uplink_seid; + __le16 downlink_seid; + u8 reserved[3]; + u8 connection_type; +#define I40E_AQ_CONN_TYPE_REGULAR 0x1 +#define I40E_AQ_CONN_TYPE_DEFAULT 0x2 +#define I40E_AQ_CONN_TYPE_CASCADED 0x3 + __le16 scheduler_id; + __le16 element_info; }; /* Get Switch Configuration (indirect 0x0200) @@ -592,73 +592,73 @@ struct i40e_aqc_switch_config_element_resp { * the first in the array is the header, remainder are elements */ struct i40e_aqc_get_switch_config_resp { - struct i40e_aqc_get_switch_config_header_resp header; - struct i40e_aqc_switch_config_element_resp element[1]; + struct i40e_aqc_get_switch_config_header_resp header; + struct i40e_aqc_switch_config_element_resp element[1]; }; /* Add Statistics (direct 0x0201) * Remove Statistics (direct 0x0202) */ struct i40e_aqc_add_remove_statistics { - __le16 seid; - __le16 vlan; - __le16 stat_index; - u8 reserved[10]; + __le16 seid; + __le16 vlan; + __le16 stat_index; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_statistics); /* Set Port Parameters command (direct 0x0203) */ struct i40e_aqc_set_port_parameters { - __le16 command_flags; -#define I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1 -#define I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */ -#define I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4 - __le16 bad_frame_vsi; - __le16 default_seid; /* reserved for command */ - u8 reserved[10]; + __le16 command_flags; +#define I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1 +#define I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */ +#define I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4 + __le16 bad_frame_vsi; + __le16 default_seid; /* reserved for command */ + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_port_parameters); /* Get Switch Resource Allocation (indirect 0x0204) */ struct i40e_aqc_get_switch_resource_alloc { - u8 num_entries; /* reserved for command */ - u8 reserved[7]; - __le32 addr_high; - __le32 addr_low; + u8 num_entries; /* reserved for command */ + u8 reserved[7]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_switch_resource_alloc); /* expect an array of these structs in the response buffer */ struct i40e_aqc_switch_resource_alloc_element_resp { - u8 resource_type; -#define I40E_AQ_RESOURCE_TYPE_VEB 0x0 -#define I40E_AQ_RESOURCE_TYPE_VSI 0x1 -#define I40E_AQ_RESOURCE_TYPE_MACADDR 0x2 -#define I40E_AQ_RESOURCE_TYPE_STAG 0x3 -#define I40E_AQ_RESOURCE_TYPE_ETAG 0x4 -#define I40E_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5 -#define I40E_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6 -#define I40E_AQ_RESOURCE_TYPE_VLAN 0x7 -#define I40E_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8 -#define I40E_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9 -#define I40E_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA -#define I40E_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB -#define I40E_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC -#define I40E_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD -#define I40E_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF -#define I40E_AQ_RESOURCE_TYPE_IP_FILTERS 0x10 -#define I40E_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11 -#define I40E_AQ_RESOURCE_TYPE_VN2_KEYS 0x12 -#define I40E_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13 - u8 reserved1; - __le16 guaranteed; - __le16 total; - __le16 used; - __le16 total_unalloced; - u8 reserved2[6]; + u8 resource_type; +#define I40E_AQ_RESOURCE_TYPE_VEB 0x0 +#define I40E_AQ_RESOURCE_TYPE_VSI 0x1 +#define I40E_AQ_RESOURCE_TYPE_MACADDR 0x2 +#define I40E_AQ_RESOURCE_TYPE_STAG 0x3 +#define I40E_AQ_RESOURCE_TYPE_ETAG 0x4 +#define I40E_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5 +#define I40E_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6 +#define I40E_AQ_RESOURCE_TYPE_VLAN 0x7 +#define I40E_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8 +#define I40E_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9 +#define I40E_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA +#define I40E_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB +#define I40E_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC +#define I40E_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD +#define I40E_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF +#define I40E_AQ_RESOURCE_TYPE_IP_FILTERS 0x10 +#define I40E_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11 +#define I40E_AQ_RESOURCE_TYPE_VN2_KEYS 0x12 +#define I40E_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13 + u8 reserved1; + __le16 guaranteed; + __le16 total; + __le16 used; + __le16 total_unalloced; + u8 reserved2[6]; }; /* Add VSI (indirect 0x0210) @@ -672,24 +672,24 @@ struct i40e_aqc_switch_resource_alloc_element_resp { * uses the same completion and data structure as Add VSI */ struct i40e_aqc_add_get_update_vsi { - __le16 uplink_seid; - u8 connection_type; -#define I40E_AQ_VSI_CONN_TYPE_NORMAL 0x1 -#define I40E_AQ_VSI_CONN_TYPE_DEFAULT 0x2 -#define I40E_AQ_VSI_CONN_TYPE_CASCADED 0x3 - u8 reserved1; - u8 vf_id; - u8 reserved2; - __le16 vsi_flags; -#define I40E_AQ_VSI_TYPE_SHIFT 0x0 -#define I40E_AQ_VSI_TYPE_MASK (0x3 << I40E_AQ_VSI_TYPE_SHIFT) -#define I40E_AQ_VSI_TYPE_VF 0x0 -#define I40E_AQ_VSI_TYPE_VMDQ2 0x1 -#define I40E_AQ_VSI_TYPE_PF 0x2 -#define I40E_AQ_VSI_TYPE_EMP_MNG 0x3 -#define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4 - __le32 addr_high; - __le32 addr_low; + __le16 uplink_seid; + u8 connection_type; +#define I40E_AQ_VSI_CONN_TYPE_NORMAL 0x1 +#define I40E_AQ_VSI_CONN_TYPE_DEFAULT 0x2 +#define I40E_AQ_VSI_CONN_TYPE_CASCADED 0x3 + u8 reserved1; + u8 vf_id; + u8 reserved2; + __le16 vsi_flags; +#define I40E_AQ_VSI_TYPE_SHIFT 0x0 +#define I40E_AQ_VSI_TYPE_MASK (0x3 << I40E_AQ_VSI_TYPE_SHIFT) +#define I40E_AQ_VSI_TYPE_VF 0x0 +#define I40E_AQ_VSI_TYPE_VMDQ2 0x1 +#define I40E_AQ_VSI_TYPE_PF 0x2 +#define I40E_AQ_VSI_TYPE_EMP_MNG 0x3 +#define I40E_AQ_VSI_FLAG_CASCADED_PV 0x4 + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_get_update_vsi); @@ -707,121 +707,121 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_get_update_vsi_completion); struct i40e_aqc_vsi_properties_data { /* first 96 byte are written by SW */ - __le16 valid_sections; -#define I40E_AQ_VSI_PROP_SWITCH_VALID 0x0001 -#define I40E_AQ_VSI_PROP_SECURITY_VALID 0x0002 -#define I40E_AQ_VSI_PROP_VLAN_VALID 0x0004 -#define I40E_AQ_VSI_PROP_CAS_PV_VALID 0x0008 -#define I40E_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010 -#define I40E_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020 -#define I40E_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040 -#define I40E_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080 -#define I40E_AQ_VSI_PROP_OUTER_UP_VALID 0x0100 -#define I40E_AQ_VSI_PROP_SCHED_VALID 0x0200 + __le16 valid_sections; +#define I40E_AQ_VSI_PROP_SWITCH_VALID 0x0001 +#define I40E_AQ_VSI_PROP_SECURITY_VALID 0x0002 +#define I40E_AQ_VSI_PROP_VLAN_VALID 0x0004 +#define I40E_AQ_VSI_PROP_CAS_PV_VALID 0x0008 +#define I40E_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010 +#define I40E_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020 +#define I40E_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040 +#define I40E_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080 +#define I40E_AQ_VSI_PROP_OUTER_UP_VALID 0x0100 +#define I40E_AQ_VSI_PROP_SCHED_VALID 0x0200 /* switch section */ - __le16 switch_id; /* 12bit id combined with flags below */ -#define I40E_AQ_VSI_SW_ID_SHIFT 0x0000 -#define I40E_AQ_VSI_SW_ID_MASK (0xFFF << I40E_AQ_VSI_SW_ID_SHIFT) -#define I40E_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000 -#define I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000 -#define I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000 - u8 sw_reserved[2]; + __le16 switch_id; /* 12bit id combined with flags below */ +#define I40E_AQ_VSI_SW_ID_SHIFT 0x0000 +#define I40E_AQ_VSI_SW_ID_MASK (0xFFF << I40E_AQ_VSI_SW_ID_SHIFT) +#define I40E_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000 +#define I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000 +#define I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000 + u8 sw_reserved[2]; /* security section */ - u8 sec_flags; -#define I40E_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01 -#define I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02 -#define I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04 - u8 sec_reserved; + u8 sec_flags; +#define I40E_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01 +#define I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02 +#define I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04 + u8 sec_reserved; /* VLAN section */ - __le16 pvid; /* VLANS include priority bits */ - __le16 fcoe_pvid; - u8 port_vlan_flags; -#define I40E_AQ_VSI_PVLAN_MODE_SHIFT 0x00 -#define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \ - I40E_AQ_VSI_PVLAN_MODE_SHIFT) -#define I40E_AQ_VSI_PVLAN_MODE_TAGGED 0x01 -#define I40E_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02 -#define I40E_AQ_VSI_PVLAN_MODE_ALL 0x03 -#define I40E_AQ_VSI_PVLAN_INSERT_PVID 0x04 -#define I40E_AQ_VSI_PVLAN_EMOD_SHIFT 0x03 -#define I40E_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \ - I40E_AQ_VSI_PVLAN_EMOD_SHIFT) -#define I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0 -#define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08 -#define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10 -#define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18 - u8 pvlan_reserved[3]; + __le16 pvid; /* VLANS include priority bits */ + __le16 fcoe_pvid; + u8 port_vlan_flags; +#define I40E_AQ_VSI_PVLAN_MODE_SHIFT 0x00 +#define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \ + I40E_AQ_VSI_PVLAN_MODE_SHIFT) +#define I40E_AQ_VSI_PVLAN_MODE_TAGGED 0x01 +#define I40E_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02 +#define I40E_AQ_VSI_PVLAN_MODE_ALL 0x03 +#define I40E_AQ_VSI_PVLAN_INSERT_PVID 0x04 +#define I40E_AQ_VSI_PVLAN_EMOD_SHIFT 0x03 +#define I40E_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \ + I40E_AQ_VSI_PVLAN_EMOD_SHIFT) +#define I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0 +#define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08 +#define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10 +#define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18 + u8 pvlan_reserved[3]; /* ingress egress up sections */ - __le32 ingress_table; /* bitmap, 3 bits per up */ -#define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0 -#define I40E_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP0_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP1_SHIFT 3 -#define I40E_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP1_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP2_SHIFT 6 -#define I40E_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP2_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP3_SHIFT 9 -#define I40E_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP3_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP4_SHIFT 12 -#define I40E_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP4_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP5_SHIFT 15 -#define I40E_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP5_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP6_SHIFT 18 -#define I40E_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP6_SHIFT) -#define I40E_AQ_VSI_UP_TABLE_UP7_SHIFT 21 -#define I40E_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \ - I40E_AQ_VSI_UP_TABLE_UP7_SHIFT) - __le32 egress_table; /* same defines as for ingress table */ + __le32 ingress_table; /* bitmap, 3 bits per up */ +#define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0 +#define I40E_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP0_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP1_SHIFT 3 +#define I40E_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP1_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP2_SHIFT 6 +#define I40E_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP2_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP3_SHIFT 9 +#define I40E_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP3_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP4_SHIFT 12 +#define I40E_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP4_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP5_SHIFT 15 +#define I40E_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP5_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP6_SHIFT 18 +#define I40E_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP6_SHIFT) +#define I40E_AQ_VSI_UP_TABLE_UP7_SHIFT 21 +#define I40E_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \ + I40E_AQ_VSI_UP_TABLE_UP7_SHIFT) + __le32 egress_table; /* same defines as for ingress table */ /* cascaded PV section */ - __le16 cas_pv_tag; - u8 cas_pv_flags; -#define I40E_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00 -#define I40E_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \ - I40E_AQ_VSI_CAS_PV_TAGX_SHIFT) -#define I40E_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00 -#define I40E_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01 -#define I40E_AQ_VSI_CAS_PV_TAGX_COPY 0x02 -#define I40E_AQ_VSI_CAS_PV_INSERT_TAG 0x10 -#define I40E_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20 -#define I40E_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40 - u8 cas_pv_reserved; + __le16 cas_pv_tag; + u8 cas_pv_flags; +#define I40E_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00 +#define I40E_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \ + I40E_AQ_VSI_CAS_PV_TAGX_SHIFT) +#define I40E_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00 +#define I40E_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01 +#define I40E_AQ_VSI_CAS_PV_TAGX_COPY 0x02 +#define I40E_AQ_VSI_CAS_PV_INSERT_TAG 0x10 +#define I40E_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20 +#define I40E_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40 + u8 cas_pv_reserved; /* queue mapping section */ - __le16 mapping_flags; -#define I40E_AQ_VSI_QUE_MAP_CONTIG 0x0 -#define I40E_AQ_VSI_QUE_MAP_NONCONTIG 0x1 - __le16 queue_mapping[16]; -#define I40E_AQ_VSI_QUEUE_SHIFT 0x0 -#define I40E_AQ_VSI_QUEUE_MASK (0x7FF << I40E_AQ_VSI_QUEUE_SHIFT) - __le16 tc_mapping[8]; -#define I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT 0 -#define I40E_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \ - I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) -#define I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT 9 -#define I40E_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \ - I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT) + __le16 mapping_flags; +#define I40E_AQ_VSI_QUE_MAP_CONTIG 0x0 +#define I40E_AQ_VSI_QUE_MAP_NONCONTIG 0x1 + __le16 queue_mapping[16]; +#define I40E_AQ_VSI_QUEUE_SHIFT 0x0 +#define I40E_AQ_VSI_QUEUE_MASK (0x7FF << I40E_AQ_VSI_QUEUE_SHIFT) + __le16 tc_mapping[8]; +#define I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT 0 +#define I40E_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \ + I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) +#define I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT 9 +#define I40E_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \ + I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT) /* queueing option section */ - u8 queueing_opt_flags; -#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10 -#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20 - u8 queueing_opt_reserved[3]; + u8 queueing_opt_flags; +#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10 +#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20 + u8 queueing_opt_reserved[3]; /* scheduler section */ - u8 up_enable_bits; - u8 sched_reserved; + u8 up_enable_bits; + u8 sched_reserved; /* outer up section */ - __le32 outer_up_table; /* same structure and defines as ingress table */ - u8 cmd_reserved[8]; + __le32 outer_up_table; /* same structure and defines as ingress tbl */ + u8 cmd_reserved[8]; /* last 32 bytes are written by FW */ - __le16 qs_handle[8]; + __le16 qs_handle[8]; #define I40E_AQ_VSI_QS_HANDLE_INVALID 0xFFFF - __le16 stat_counter_idx; - __le16 sched_id; - u8 resp_reserved[12]; + __le16 stat_counter_idx; + __le16 sched_id; + u8 resp_reserved[12]; }; I40E_CHECK_STRUCT_LEN(128, i40e_aqc_vsi_properties_data); @@ -831,26 +831,26 @@ I40E_CHECK_STRUCT_LEN(128, i40e_aqc_vsi_properties_data); * (IS_CTRL_PORT only works on add PV) */ struct i40e_aqc_add_update_pv { - __le16 command_flags; -#define I40E_AQC_PV_FLAG_PV_TYPE 0x1 -#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2 -#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4 -#define I40E_AQC_PV_FLAG_IS_CTRL_PORT 0x8 - __le16 uplink_seid; - __le16 connected_seid; - u8 reserved[10]; + __le16 command_flags; +#define I40E_AQC_PV_FLAG_PV_TYPE 0x1 +#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2 +#define I40E_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4 +#define I40E_AQC_PV_FLAG_IS_CTRL_PORT 0x8 + __le16 uplink_seid; + __le16 connected_seid; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv); struct i40e_aqc_add_update_pv_completion { /* reserved for update; for add also encodes error if rc == ENOSPC */ - __le16 pv_seid; -#define I40E_AQC_PV_ERR_FLAG_NO_PV 0x1 -#define I40E_AQC_PV_ERR_FLAG_NO_SCHED 0x2 -#define I40E_AQC_PV_ERR_FLAG_NO_COUNTER 0x4 -#define I40E_AQC_PV_ERR_FLAG_NO_ENTRY 0x8 - u8 reserved[14]; + __le16 pv_seid; +#define I40E_AQC_PV_ERR_FLAG_NO_PV 0x1 +#define I40E_AQC_PV_ERR_FLAG_NO_SCHED 0x2 +#define I40E_AQC_PV_ERR_FLAG_NO_COUNTER 0x4 +#define I40E_AQC_PV_ERR_FLAG_NO_ENTRY 0x8 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv_completion); @@ -860,48 +860,48 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_update_pv_completion); */ struct i40e_aqc_get_pv_params_completion { - __le16 seid; - __le16 default_stag; - __le16 pv_flags; /* same flags as add_pv */ -#define I40E_AQC_GET_PV_PV_TYPE 0x1 -#define I40E_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2 -#define I40E_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4 - u8 reserved[8]; - __le16 default_port_seid; + __le16 seid; + __le16 default_stag; + __le16 pv_flags; /* same flags as add_pv */ +#define I40E_AQC_GET_PV_PV_TYPE 0x1 +#define I40E_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2 +#define I40E_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4 + u8 reserved[8]; + __le16 default_port_seid; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_pv_params_completion); /* Add VEB (direct 0x0230) */ struct i40e_aqc_add_veb { - __le16 uplink_seid; - __le16 downlink_seid; - __le16 veb_flags; -#define I40E_AQC_ADD_VEB_FLOATING 0x1 -#define I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT 1 -#define I40E_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \ + __le16 uplink_seid; + __le16 downlink_seid; + __le16 veb_flags; +#define I40E_AQC_ADD_VEB_FLOATING 0x1 +#define I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT 1 +#define I40E_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \ I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT) -#define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2 -#define I40E_AQC_ADD_VEB_PORT_TYPE_DATA 0x4 -#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 - u8 enable_tcs; - u8 reserved[9]; +#define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2 +#define I40E_AQC_ADD_VEB_PORT_TYPE_DATA 0x4 +#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 + u8 enable_tcs; + u8 reserved[9]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb); struct i40e_aqc_add_veb_completion { - u8 reserved[6]; - __le16 switch_seid; + u8 reserved[6]; + __le16 switch_seid; /* also encodes error if rc == ENOSPC; codes are the same as add_pv */ - __le16 veb_seid; -#define I40E_AQC_VEB_ERR_FLAG_NO_VEB 0x1 -#define I40E_AQC_VEB_ERR_FLAG_NO_SCHED 0x2 -#define I40E_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4 -#define I40E_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8 - __le16 statistic_index; - __le16 vebs_used; - __le16 vebs_free; + __le16 veb_seid; +#define I40E_AQC_VEB_ERR_FLAG_NO_VEB 0x1 +#define I40E_AQC_VEB_ERR_FLAG_NO_SCHED 0x2 +#define I40E_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4 +#define I40E_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8 + __le16 statistic_index; + __le16 vebs_used; + __le16 vebs_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb_completion); @@ -910,13 +910,13 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_veb_completion); * uses i40e_aqc_switch_seid for the descriptor */ struct i40e_aqc_get_veb_parameters_completion { - __le16 seid; - __le16 switch_id; - __le16 veb_flags; /* only the first/last flags from 0x0230 is valid */ - __le16 statistic_index; - __le16 vebs_used; - __le16 vebs_free; - u8 reserved[4]; + __le16 seid; + __le16 switch_id; + __le16 veb_flags; /* only the first/last flags from 0x0230 is valid */ + __le16 statistic_index; + __le16 vebs_used; + __le16 vebs_free; + u8 reserved[4]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_veb_parameters_completion); @@ -929,37 +929,37 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_get_veb_parameters_completion); /* used for the command for most vlan commands */ struct i40e_aqc_macvlan { - __le16 num_addresses; - __le16 seid[3]; -#define I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 num_addresses; + __le16 seid[3]; +#define I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT) -#define I40E_AQC_MACVLAN_CMD_SEID_VALID 0x8000 - __le32 addr_high; - __le32 addr_low; +#define I40E_AQC_MACVLAN_CMD_SEID_VALID 0x8000 + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_macvlan); /* indirect data for command and response */ struct i40e_aqc_add_macvlan_element_data { - u8 mac_addr[6]; - __le16 vlan_tag; - __le16 flags; -#define I40E_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001 -#define I40E_AQC_MACVLAN_ADD_HASH_MATCH 0x0002 -#define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004 -#define I40E_AQC_MACVLAN_ADD_TO_QUEUE 0x0008 - __le16 queue_number; -#define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT 0 -#define I40E_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \ + u8 mac_addr[6]; + __le16 vlan_tag; + __le16 flags; +#define I40E_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001 +#define I40E_AQC_MACVLAN_ADD_HASH_MATCH 0x0002 +#define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004 +#define I40E_AQC_MACVLAN_ADD_TO_QUEUE 0x0008 + __le16 queue_number; +#define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT 0 +#define I40E_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \ I40E_AQC_MACVLAN_CMD_SEID_NUM_SHIFT) /* response section */ - u8 match_method; -#define I40E_AQC_MM_PERFECT_MATCH 0x01 -#define I40E_AQC_MM_HASH_MATCH 0x02 -#define I40E_AQC_MM_ERR_NO_RES 0xFF - u8 reserved1[3]; + u8 match_method; +#define I40E_AQC_MM_PERFECT_MATCH 0x01 +#define I40E_AQC_MM_HASH_MATCH 0x02 +#define I40E_AQC_MM_ERR_NO_RES 0xFF + u8 reserved1[3]; }; struct i40e_aqc_add_remove_macvlan_completion { @@ -979,19 +979,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_macvlan_completion); */ struct i40e_aqc_remove_macvlan_element_data { - u8 mac_addr[6]; - __le16 vlan_tag; - u8 flags; -#define I40E_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01 -#define I40E_AQC_MACVLAN_DEL_HASH_MATCH 0x02 -#define I40E_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08 -#define I40E_AQC_MACVLAN_DEL_ALL_VSIS 0x10 - u8 reserved[3]; + u8 mac_addr[6]; + __le16 vlan_tag; + u8 flags; +#define I40E_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01 +#define I40E_AQC_MACVLAN_DEL_HASH_MATCH 0x02 +#define I40E_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08 +#define I40E_AQC_MACVLAN_DEL_ALL_VSIS 0x10 + u8 reserved[3]; /* reply section */ - u8 error_code; -#define I40E_AQC_REMOVE_MACVLAN_SUCCESS 0x0 -#define I40E_AQC_REMOVE_MACVLAN_FAIL 0xFF - u8 reply_reserved[3]; + u8 error_code; +#define I40E_AQC_REMOVE_MACVLAN_SUCCESS 0x0 +#define I40E_AQC_REMOVE_MACVLAN_FAIL 0xFF + u8 reply_reserved[3]; }; /* Add VLAN (indirect 0x0252) @@ -999,59 +999,58 @@ struct i40e_aqc_remove_macvlan_element_data { * use the generic i40e_aqc_macvlan for the command */ struct i40e_aqc_add_remove_vlan_element_data { - __le16 vlan_tag; - u8 vlan_flags; + __le16 vlan_tag; + u8 vlan_flags; /* flags for add VLAN */ -#define I40E_AQC_ADD_VLAN_LOCAL 0x1 -#define I40E_AQC_ADD_PVLAN_TYPE_SHIFT 1 -#define I40E_AQC_ADD_PVLAN_TYPE_MASK (0x3 << \ - I40E_AQC_ADD_PVLAN_TYPE_SHIFT) -#define I40E_AQC_ADD_PVLAN_TYPE_REGULAR 0x0 -#define I40E_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2 -#define I40E_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4 -#define I40E_AQC_VLAN_PTYPE_SHIFT 3 -#define I40E_AQC_VLAN_PTYPE_MASK (0x3 << I40E_AQC_VLAN_PTYPE_SHIFT) -#define I40E_AQC_VLAN_PTYPE_REGULAR_VSI 0x0 -#define I40E_AQC_VLAN_PTYPE_PROMISC_VSI 0x8 -#define I40E_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10 -#define I40E_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18 +#define I40E_AQC_ADD_VLAN_LOCAL 0x1 +#define I40E_AQC_ADD_PVLAN_TYPE_SHIFT 1 +#define I40E_AQC_ADD_PVLAN_TYPE_MASK (0x3 << I40E_AQC_ADD_PVLAN_TYPE_SHIFT) +#define I40E_AQC_ADD_PVLAN_TYPE_REGULAR 0x0 +#define I40E_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2 +#define I40E_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4 +#define I40E_AQC_VLAN_PTYPE_SHIFT 3 +#define I40E_AQC_VLAN_PTYPE_MASK (0x3 << I40E_AQC_VLAN_PTYPE_SHIFT) +#define I40E_AQC_VLAN_PTYPE_REGULAR_VSI 0x0 +#define I40E_AQC_VLAN_PTYPE_PROMISC_VSI 0x8 +#define I40E_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10 +#define I40E_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18 /* flags for remove VLAN */ -#define I40E_AQC_REMOVE_VLAN_ALL 0x1 - u8 reserved; - u8 result; +#define I40E_AQC_REMOVE_VLAN_ALL 0x1 + u8 reserved; + u8 result; /* flags for add VLAN */ -#define I40E_AQC_ADD_VLAN_SUCCESS 0x0 -#define I40E_AQC_ADD_VLAN_FAIL_REQUEST 0xFE -#define I40E_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF +#define I40E_AQC_ADD_VLAN_SUCCESS 0x0 +#define I40E_AQC_ADD_VLAN_FAIL_REQUEST 0xFE +#define I40E_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF /* flags for remove VLAN */ -#define I40E_AQC_REMOVE_VLAN_SUCCESS 0x0 -#define I40E_AQC_REMOVE_VLAN_FAIL 0xFF - u8 reserved1[3]; +#define I40E_AQC_REMOVE_VLAN_SUCCESS 0x0 +#define I40E_AQC_REMOVE_VLAN_FAIL 0xFF + u8 reserved1[3]; }; struct i40e_aqc_add_remove_vlan_completion { - u8 reserved[4]; - __le16 vlans_used; - __le16 vlans_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[4]; + __le16 vlans_used; + __le16 vlans_free; + __le32 addr_high; + __le32 addr_low; }; /* Set VSI Promiscuous Modes (direct 0x0254) */ struct i40e_aqc_set_vsi_promiscuous_modes { - __le16 promiscuous_flags; - __le16 valid_flags; + __le16 promiscuous_flags; + __le16 valid_flags; /* flags used for both fields above */ -#define I40E_AQC_SET_VSI_PROMISC_UNICAST 0x01 -#define I40E_AQC_SET_VSI_PROMISC_MULTICAST 0x02 -#define I40E_AQC_SET_VSI_PROMISC_BROADCAST 0x04 -#define I40E_AQC_SET_VSI_DEFAULT 0x08 -#define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10 - __le16 seid; -#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF - __le16 vlan_tag; -#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000 - u8 reserved[8]; +#define I40E_AQC_SET_VSI_PROMISC_UNICAST 0x01 +#define I40E_AQC_SET_VSI_PROMISC_MULTICAST 0x02 +#define I40E_AQC_SET_VSI_PROMISC_BROADCAST 0x04 +#define I40E_AQC_SET_VSI_DEFAULT 0x08 +#define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10 + __le16 seid; +#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF + __le16 vlan_tag; +#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000 + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_vsi_promiscuous_modes); @@ -1060,23 +1059,23 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_vsi_promiscuous_modes); * Uses generic i40e_aqc_add_remove_tag_completion for completion */ struct i40e_aqc_add_tag { - __le16 flags; -#define I40E_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001 - __le16 seid; -#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 flags; +#define I40E_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001 + __le16 seid; +#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT) - __le16 tag; - __le16 queue_number; - u8 reserved[8]; + __le16 tag; + __le16 queue_number; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_tag); struct i40e_aqc_add_remove_tag_completion { - u8 reserved[12]; - __le16 tags_used; - __le16 tags_free; + u8 reserved[12]; + __le16 tags_used; + __le16 tags_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_tag_completion); @@ -1085,12 +1084,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_tag_completion); * Uses generic i40e_aqc_add_remove_tag_completion for completion */ struct i40e_aqc_remove_tag { - __le16 seid; -#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 seid; +#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT) - __le16 tag; - u8 reserved[12]; + __le16 tag; + u8 reserved[12]; }; /* Add multicast E-Tag (direct 0x0257) @@ -1098,22 +1097,22 @@ struct i40e_aqc_remove_tag { * and no external data */ struct i40e_aqc_add_remove_mcast_etag { - __le16 pv_seid; - __le16 etag; - u8 num_unicast_etags; - u8 reserved[3]; - __le32 addr_high; /* address of array of 2-byte s-tags */ - __le32 addr_low; + __le16 pv_seid; + __le16 etag; + u8 num_unicast_etags; + u8 reserved[3]; + __le32 addr_high; /* address of array of 2-byte s-tags */ + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_mcast_etag); struct i40e_aqc_add_remove_mcast_etag_completion { - u8 reserved[4]; - __le16 mcast_etags_used; - __le16 mcast_etags_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[4]; + __le16 mcast_etags_used; + __le16 mcast_etags_free; + __le32 addr_high; + __le32 addr_low; }; @@ -1121,21 +1120,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_mcast_etag_completion); /* Update S/E-Tag (direct 0x0259) */ struct i40e_aqc_update_tag { - __le16 seid; -#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ + __le16 seid; +#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT) - __le16 old_tag; - __le16 new_tag; - u8 reserved[10]; + __le16 old_tag; + __le16 new_tag; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag); struct i40e_aqc_update_tag_completion { - u8 reserved[12]; - __le16 tags_used; - __le16 tags_free; + u8 reserved[12]; + __le16 tags_used; + __le16 tags_free; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag_completion); @@ -1146,30 +1145,30 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_update_tag_completion); * and the generic direct completion structure */ struct i40e_aqc_add_remove_control_packet_filter { - u8 mac[6]; - __le16 etype; - __le16 flags; -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008 -#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000 - __le16 seid; -#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \ + u8 mac[6]; + __le16 etype; + __le16 flags; +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008 +#define I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000 + __le16 seid; +#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT) - __le16 queue; - u8 reserved[2]; + __le16 queue; + u8 reserved[2]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter); struct i40e_aqc_add_remove_control_packet_filter_completion { - __le16 mac_etype_used; - __le16 etype_used; - __le16 mac_etype_free; - __le16 etype_free; - u8 reserved[8]; + __le16 mac_etype_used; + __le16 etype_used; + __le16 mac_etype_free; + __le16 etype_free; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter_completion); @@ -1180,23 +1179,23 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_control_packet_filter_completion); * and the generic indirect completion structure */ struct i40e_aqc_add_remove_cloud_filters { - u8 num_filters; - u8 reserved; - __le16 seid; -#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \ + u8 num_filters; + u8 reserved; + __le16 seid; +#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \ I40E_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT) - u8 reserved2[4]; - __le32 addr_high; - __le32 addr_low; + u8 reserved2[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_remove_cloud_filters); struct i40e_aqc_add_remove_cloud_filters_element_data { - u8 outer_mac[6]; - u8 inner_mac[6]; - __le16 inner_vlan; + u8 outer_mac[6]; + u8 inner_mac[6]; + __le16 inner_vlan; union { struct { u8 reserved[12]; @@ -1206,52 +1205,49 @@ struct i40e_aqc_add_remove_cloud_filters_element_data { u8 data[16]; } v6; } ipaddr; - __le16 flags; -#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \ + __le16 flags; +#define I40E_AQC_ADD_CLOUD_FILTER_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \ I40E_AQC_ADD_CLOUD_FILTER_SHIFT) -#define I40E_AQC_ADD_CLOUD_FILTER_OIP_GRE 0x0002 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_GRE 0x0004 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_VNL 0x0007 /* 0x0000 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001 +#define I40E_AQC_ADD_CLOUD_FILTER_OIP 0x0001 /* 0x0002 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004 /* 0x0005 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006 /* 0x0007 reserved */ /* 0x0008 reserved */ -#define I40E_AQC_ADD_CLOUD_FILTER_OMAC 0x0009 -#define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A -#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B -#define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C - -#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080 -#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6 -#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0 -#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0 -#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100 - -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN 0 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2 -#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3 - - __le32 tenant_id; - u8 reserved[4]; - __le16 queue_number; -#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0 -#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x3F << \ - I40E_AQC_ADD_CLOUD_QUEUE_SHIFT) - u8 reserved2[14]; +#define I40E_AQC_ADD_CLOUD_FILTER_OMAC 0x0009 +#define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A +#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B +#define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C + +#define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080 +#define I40E_AQC_ADD_CLOUD_VNK_SHIFT 6 +#define I40E_AQC_ADD_CLOUD_VNK_MASK 0x00C0 +#define I40E_AQC_ADD_CLOUD_FLAGS_IPV4 0 +#define I40E_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100 + +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN 0 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2 +#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3 + + __le32 tenant_id; + u8 reserved[4]; + __le16 queue_number; +#define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0 +#define I40E_AQC_ADD_CLOUD_QUEUE_MASK (0x3F << \ + I40E_AQC_ADD_CLOUD_QUEUE_SHIFT) + u8 reserved2[14]; /* response section */ - u8 allocation_result; -#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0 -#define I40E_AQC_ADD_CLOUD_FILTER_FAIL 0xFF - u8 response_reserved[7]; + u8 allocation_result; +#define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0 +#define I40E_AQC_ADD_CLOUD_FILTER_FAIL 0xFF + u8 response_reserved[7]; }; struct i40e_aqc_remove_cloud_filters_completion { @@ -1273,14 +1269,14 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_cloud_filters_completion); struct i40e_aqc_add_delete_mirror_rule { __le16 seid; __le16 rule_type; -#define I40E_AQC_MIRROR_RULE_TYPE_SHIFT 0 -#define I40E_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \ +#define I40E_AQC_MIRROR_RULE_TYPE_SHIFT 0 +#define I40E_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \ I40E_AQC_MIRROR_RULE_TYPE_SHIFT) -#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1 -#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2 -#define I40E_AQC_MIRROR_RULE_TYPE_VLAN 3 -#define I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4 -#define I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5 +#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1 +#define I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2 +#define I40E_AQC_MIRROR_RULE_TYPE_VLAN 3 +#define I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4 +#define I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5 __le16 num_entries; __le16 destination; /* VSI for add, rule id for delete */ __le32 addr_high; /* address of array of 2-byte VSI or VLAN ids */ @@ -1290,12 +1286,12 @@ struct i40e_aqc_add_delete_mirror_rule { I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule); struct i40e_aqc_add_delete_mirror_rule_completion { - u8 reserved[2]; - __le16 rule_id; /* only used on add */ - __le16 mirror_rules_used; - __le16 mirror_rules_free; - __le32 addr_high; - __le32 addr_low; + u8 reserved[2]; + __le16 rule_id; /* only used on add */ + __le16 mirror_rules_used; + __le16 mirror_rules_free; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); @@ -1306,11 +1302,11 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion); * the command and response use the same descriptor structure */ struct i40e_aqc_pfc_ignore { - u8 tc_bitmap; - u8 command_flags; /* unused on response */ -#define I40E_AQC_PFC_IGNORE_SET 0x80 -#define I40E_AQC_PFC_IGNORE_CLEAR 0x0 - u8 reserved[14]; + u8 tc_bitmap; + u8 command_flags; /* unused on response */ +#define I40E_AQC_PFC_IGNORE_SET 0x80 +#define I40E_AQC_PFC_IGNORE_CLEAR 0x0 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_pfc_ignore); @@ -1325,10 +1321,10 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_pfc_ignore); * this generic struct to pass the SEID in param0 */ struct i40e_aqc_tx_sched_ind { - __le16 vsi_seid; - u8 reserved[6]; - __le32 addr_high; - __le32 addr_low; + __le16 vsi_seid; + u8 reserved[6]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_tx_sched_ind); @@ -1340,12 +1336,12 @@ struct i40e_aqc_qs_handles_resp { /* Configure VSI BW limits (direct 0x0400) */ struct i40e_aqc_configure_vsi_bw_limit { - __le16 vsi_seid; - u8 reserved[2]; - __le16 credit; - u8 reserved1[2]; - u8 max_credit; /* 0-3, limit = 2^max */ - u8 reserved2[7]; + __le16 vsi_seid; + u8 reserved[2]; + __le16 credit; + u8 reserved1[2]; + u8 max_credit; /* 0-3, limit = 2^max */ + u8 reserved2[7]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_vsi_bw_limit); @@ -1354,58 +1350,58 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_vsi_bw_limit); * responds with i40e_aqc_qs_handles_resp */ struct i40e_aqc_configure_vsi_ets_sla_bw_data { - u8 tc_valid_bits; - u8 reserved[15]; - __le16 tc_bw_credits[8]; /* FW writesback QS handles here */ + u8 tc_valid_bits; + u8 reserved[15]; + __le16 tc_bw_credits[8]; /* FW writesback QS handles here */ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved1[28]; + __le16 tc_bw_max[2]; + u8 reserved1[28]; }; /* Configure VSI Bandwidth Allocation per Traffic Type (indirect 0x0407) * responds with i40e_aqc_qs_handles_resp */ struct i40e_aqc_configure_vsi_tc_bw_data { - u8 tc_valid_bits; - u8 reserved[3]; - u8 tc_bw_credits[8]; - u8 reserved1[4]; - __le16 qs_handles[8]; + u8 tc_valid_bits; + u8 reserved[3]; + u8 tc_bw_credits[8]; + u8 reserved1[4]; + __le16 qs_handles[8]; }; /* Query vsi bw configuration (indirect 0x0408) */ struct i40e_aqc_query_vsi_bw_config_resp { - u8 tc_valid_bits; - u8 tc_suspended_bits; - u8 reserved[14]; - __le16 qs_handles[8]; - u8 reserved1[4]; - __le16 port_bw_limit; - u8 reserved2[2]; - u8 max_bw; /* 0-3, limit = 2^max */ - u8 reserved3[23]; + u8 tc_valid_bits; + u8 tc_suspended_bits; + u8 reserved[14]; + __le16 qs_handles[8]; + u8 reserved1[4]; + __le16 port_bw_limit; + u8 reserved2[2]; + u8 max_bw; /* 0-3, limit = 2^max */ + u8 reserved3[23]; }; /* Query VSI Bandwidth Allocation per Traffic Type (indirect 0x040A) */ struct i40e_aqc_query_vsi_ets_sla_config_resp { - u8 tc_valid_bits; - u8 reserved[3]; - u8 share_credits[8]; - __le16 credits[8]; + u8 tc_valid_bits; + u8 reserved[3]; + u8 share_credits[8]; + __le16 credits[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; + __le16 tc_bw_max[2]; }; /* Configure Switching Component Bandwidth Limit (direct 0x0410) */ struct i40e_aqc_configure_switching_comp_bw_limit { - __le16 seid; - u8 reserved[2]; - __le16 credit; - u8 reserved1[2]; - u8 max_bw; /* 0-3, limit = 2^max */ - u8 reserved2[7]; + __le16 seid; + u8 reserved[2]; + __le16 credit; + u8 reserved1[2]; + u8 max_bw; /* 0-3, limit = 2^max */ + u8 reserved2[7]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); @@ -1415,75 +1411,75 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_configure_switching_comp_bw_limit); * Disable Physical Port ETS (indirect 0x0415) */ struct i40e_aqc_configure_switching_comp_ets_data { - u8 reserved[4]; - u8 tc_valid_bits; - u8 seepage; -#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 - u8 tc_strict_priority_flags; - u8 reserved1[17]; - u8 tc_bw_share_credits[8]; - u8 reserved2[96]; + u8 reserved[4]; + u8 tc_valid_bits; + u8 seepage; +#define I40E_AQ_ETS_SEEPAGE_EN_MASK 0x1 + u8 tc_strict_priority_flags; + u8 reserved1[17]; + u8 tc_bw_share_credits[8]; + u8 reserved2[96]; }; /* Configure Switching Component Bandwidth Limits per Tc (indirect 0x0416) */ struct i40e_aqc_configure_switching_comp_ets_bw_limit_data { - u8 tc_valid_bits; - u8 reserved[15]; - __le16 tc_bw_credit[8]; + u8 tc_valid_bits; + u8 reserved[15]; + __le16 tc_bw_credit[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved1[28]; + __le16 tc_bw_max[2]; + u8 reserved1[28]; }; /* Configure Switching Component Bandwidth Allocation per Tc * (indirect 0x0417) */ struct i40e_aqc_configure_switching_comp_bw_config_data { - u8 tc_valid_bits; - u8 reserved[2]; - u8 absolute_credits; /* bool */ - u8 tc_bw_share_credits[8]; - u8 reserved1[20]; + u8 tc_valid_bits; + u8 reserved[2]; + u8 absolute_credits; /* bool */ + u8 tc_bw_share_credits[8]; + u8 reserved1[20]; }; /* Query Switching Component Configuration (indirect 0x0418) */ struct i40e_aqc_query_switching_comp_ets_config_resp { - u8 tc_valid_bits; - u8 reserved[35]; - __le16 port_bw_limit; - u8 reserved1[2]; - u8 tc_bw_max; /* 0-3, limit = 2^max */ - u8 reserved2[23]; + u8 tc_valid_bits; + u8 reserved[35]; + __le16 port_bw_limit; + u8 reserved1[2]; + u8 tc_bw_max; /* 0-3, limit = 2^max */ + u8 reserved2[23]; }; /* Query PhysicalPort ETS Configuration (indirect 0x0419) */ struct i40e_aqc_query_port_ets_config_resp { - u8 reserved[4]; - u8 tc_valid_bits; - u8 reserved1; - u8 tc_strict_priority_bits; - u8 reserved2; - u8 tc_bw_share_credits[8]; - __le16 tc_bw_limits[8]; + u8 reserved[4]; + u8 tc_valid_bits; + u8 reserved1; + u8 tc_strict_priority_bits; + u8 reserved2; + u8 tc_bw_share_credits[8]; + __le16 tc_bw_limits[8]; /* 4 bits per tc 0-7, 4th bit reserved, limit = 2^max */ - __le16 tc_bw_max[2]; - u8 reserved3[32]; + __le16 tc_bw_max[2]; + u8 reserved3[32]; }; /* Query Switching Component Bandwidth Allocation per Traffic Type * (indirect 0x041A) */ struct i40e_aqc_query_switching_comp_bw_config_resp { - u8 tc_valid_bits; - u8 reserved[2]; - u8 absolute_credits_enable; /* bool */ - u8 tc_bw_share_credits[8]; - __le16 tc_bw_limits[8]; + u8 tc_valid_bits; + u8 reserved[2]; + u8 absolute_credits_enable; /* bool */ + u8 tc_bw_share_credits[8]; + __le16 tc_bw_limits[8]; /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */ - __le16 tc_bw_max[2]; + __le16 tc_bw_max[2]; }; /* Suspend/resume port TX traffic @@ -1494,37 +1490,37 @@ struct i40e_aqc_query_switching_comp_bw_config_resp { * (indirect 0x041D) */ struct i40e_aqc_configure_partition_bw_data { - __le16 pf_valid_bits; - u8 min_bw[16]; /* guaranteed bandwidth */ - u8 max_bw[16]; /* bandwidth limit */ + __le16 pf_valid_bits; + u8 min_bw[16]; /* guaranteed bandwidth */ + u8 max_bw[16]; /* bandwidth limit */ }; /* Get and set the active HMC resource profile and status. * (direct 0x0500) and (direct 0x0501) */ struct i40e_aq_get_set_hmc_resource_profile { - u8 pm_profile; - u8 pe_vf_enabled; - u8 reserved[14]; + u8 pm_profile; + u8 pe_vf_enabled; + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_get_set_hmc_resource_profile); enum i40e_aq_hmc_profile { /* I40E_HMC_PROFILE_NO_CHANGE = 0, reserved */ - I40E_HMC_PROFILE_DEFAULT = 1, - I40E_HMC_PROFILE_FAVOR_VF = 2, - I40E_HMC_PROFILE_EQUAL = 3, + I40E_HMC_PROFILE_DEFAULT = 1, + I40E_HMC_PROFILE_FAVOR_VF = 2, + I40E_HMC_PROFILE_EQUAL = 3, }; -#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_PM_MASK 0xF -#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_COUNT_MASK 0x3F +#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_PM_MASK 0xF +#define I40E_AQ_GET_HMC_RESOURCE_PROFILE_COUNT_MASK 0x3F /* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */ /* set in param0 for get phy abilities to report qualified modules */ -#define I40E_AQ_PHY_REPORT_QUALIFIED_MODULES 0x0001 -#define I40E_AQ_PHY_REPORT_INITIAL_VALUES 0x0002 +#define I40E_AQ_PHY_REPORT_QUALIFIED_MODULES 0x0001 +#define I40E_AQ_PHY_REPORT_INITIAL_VALUES 0x0002 enum i40e_aq_phy_type { I40E_PHY_TYPE_SGMII = 0x0, @@ -1582,147 +1578,147 @@ struct i40e_aqc_module_desc { }; struct i40e_aq_get_phy_abilities_resp { - __le32 phy_type; /* bitmap using the above enum for offsets */ - u8 link_speed; /* bitmap using the above enum bit patterns */ - u8 abilities; -#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 -#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 -#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 -#define I40E_AQ_PHY_LINK_ENABLED 0x08 -#define I40E_AQ_PHY_AN_ENABLED 0x10 -#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 - __le16 eee_capability; -#define I40E_AQ_EEE_100BASE_TX 0x0002 -#define I40E_AQ_EEE_1000BASE_T 0x0004 -#define I40E_AQ_EEE_10GBASE_T 0x0008 -#define I40E_AQ_EEE_1000BASE_KX 0x0010 -#define I40E_AQ_EEE_10GBASE_KX4 0x0020 -#define I40E_AQ_EEE_10GBASE_KR 0x0040 - __le32 eeer_val; - u8 d3_lpan; -#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01 - u8 reserved[3]; - u8 phy_id[4]; - u8 module_type[3]; - u8 qualified_module_count; -#define I40E_AQ_PHY_MAX_QMS 16 - struct i40e_aqc_module_desc qualified_module[I40E_AQ_PHY_MAX_QMS]; + __le32 phy_type; /* bitmap using the above enum for offsets */ + u8 link_speed; /* bitmap using the above enum bit patterns */ + u8 abilities; +#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01 +#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02 +#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04 +#define I40E_AQ_PHY_LINK_ENABLED 0x08 +#define I40E_AQ_PHY_AN_ENABLED 0x10 +#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20 + __le16 eee_capability; +#define I40E_AQ_EEE_100BASE_TX 0x0002 +#define I40E_AQ_EEE_1000BASE_T 0x0004 +#define I40E_AQ_EEE_10GBASE_T 0x0008 +#define I40E_AQ_EEE_1000BASE_KX 0x0010 +#define I40E_AQ_EEE_10GBASE_KX4 0x0020 +#define I40E_AQ_EEE_10GBASE_KR 0x0040 + __le32 eeer_val; + u8 d3_lpan; +#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01 + u8 reserved[3]; + u8 phy_id[4]; + u8 module_type[3]; + u8 qualified_module_count; +#define I40E_AQ_PHY_MAX_QMS 16 + struct i40e_aqc_module_desc qualified_module[I40E_AQ_PHY_MAX_QMS]; }; /* Set PHY Config (direct 0x0601) */ struct i40e_aq_set_phy_config { /* same bits as above in all */ - __le32 phy_type; - u8 link_speed; - u8 abilities; + __le32 phy_type; + u8 link_speed; + u8 abilities; /* bits 0-2 use the values from get_phy_abilities_resp */ #define I40E_AQ_PHY_ENABLE_LINK 0x08 #define I40E_AQ_PHY_ENABLE_AN 0x10 #define I40E_AQ_PHY_ENABLE_ATOMIC_LINK 0x20 - __le16 eee_capability; - __le32 eeer; - u8 low_power_ctrl; - u8 reserved[3]; + __le16 eee_capability; + __le32 eeer; + u8 low_power_ctrl; + u8 reserved[3]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config); /* Set MAC Config command data structure (direct 0x0603) */ struct i40e_aq_set_mac_config { - __le16 max_frame_size; - u8 params; -#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 -#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 -#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 -#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 -#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 -#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 - u8 tx_timer_priority; /* bitmap */ - __le16 tx_timer_value; - __le16 fc_refresh_threshold; - u8 reserved[8]; + __le16 max_frame_size; + u8 params; +#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 +#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 +#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 +#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 +#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 +#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 + u8 tx_timer_priority; /* bitmap */ + __le16 tx_timer_value; + __le16 fc_refresh_threshold; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aq_set_mac_config); /* Restart Auto-Negotiation (direct 0x605) */ struct i40e_aqc_set_link_restart_an { - u8 command; -#define I40E_AQ_PHY_RESTART_AN 0x02 -#define I40E_AQ_PHY_LINK_ENABLE 0x04 - u8 reserved[15]; + u8 command; +#define I40E_AQ_PHY_RESTART_AN 0x02 +#define I40E_AQ_PHY_LINK_ENABLE 0x04 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_link_restart_an); /* Get Link Status cmd & response data structure (direct 0x0607) */ struct i40e_aqc_get_link_status { - __le16 command_flags; /* only field set on command */ -#define I40E_AQ_LSE_MASK 0x3 -#define I40E_AQ_LSE_NOP 0x0 -#define I40E_AQ_LSE_DISABLE 0x2 -#define I40E_AQ_LSE_ENABLE 0x3 + __le16 command_flags; /* only field set on command */ +#define I40E_AQ_LSE_MASK 0x3 +#define I40E_AQ_LSE_NOP 0x0 +#define I40E_AQ_LSE_DISABLE 0x2 +#define I40E_AQ_LSE_ENABLE 0x3 /* only response uses this flag */ -#define I40E_AQ_LSE_IS_ENABLED 0x1 - u8 phy_type; /* i40e_aq_phy_type */ - u8 link_speed; /* i40e_aq_link_speed */ - u8 link_info; -#define I40E_AQ_LINK_UP 0x01 -#define I40E_AQ_LINK_FAULT 0x02 -#define I40E_AQ_LINK_FAULT_TX 0x04 -#define I40E_AQ_LINK_FAULT_RX 0x08 -#define I40E_AQ_LINK_FAULT_REMOTE 0x10 -#define I40E_AQ_MEDIA_AVAILABLE 0x40 -#define I40E_AQ_SIGNAL_DETECT 0x80 - u8 an_info; -#define I40E_AQ_AN_COMPLETED 0x01 -#define I40E_AQ_LP_AN_ABILITY 0x02 -#define I40E_AQ_PD_FAULT 0x04 -#define I40E_AQ_FEC_EN 0x08 -#define I40E_AQ_PHY_LOW_POWER 0x10 -#define I40E_AQ_LINK_PAUSE_TX 0x20 -#define I40E_AQ_LINK_PAUSE_RX 0x40 -#define I40E_AQ_QUALIFIED_MODULE 0x80 - u8 ext_info; -#define I40E_AQ_LINK_PHY_TEMP_ALARM 0x01 -#define I40E_AQ_LINK_XCESSIVE_ERRORS 0x02 -#define I40E_AQ_LINK_TX_SHIFT 0x02 -#define I40E_AQ_LINK_TX_MASK (0x03 << I40E_AQ_LINK_TX_SHIFT) -#define I40E_AQ_LINK_TX_ACTIVE 0x00 -#define I40E_AQ_LINK_TX_DRAINED 0x01 -#define I40E_AQ_LINK_TX_FLUSHED 0x03 -#define I40E_AQ_LINK_FORCED_40G 0x10 - u8 loopback; /* use defines from i40e_aqc_set_lb_mode */ - __le16 max_frame_size; - u8 config; -#define I40E_AQ_CONFIG_CRC_ENA 0x04 -#define I40E_AQ_CONFIG_PACING_MASK 0x78 - u8 reserved[5]; +#define I40E_AQ_LSE_IS_ENABLED 0x1 + u8 phy_type; /* i40e_aq_phy_type */ + u8 link_speed; /* i40e_aq_link_speed */ + u8 link_info; +#define I40E_AQ_LINK_UP 0x01 +#define I40E_AQ_LINK_FAULT 0x02 +#define I40E_AQ_LINK_FAULT_TX 0x04 +#define I40E_AQ_LINK_FAULT_RX 0x08 +#define I40E_AQ_LINK_FAULT_REMOTE 0x10 +#define I40E_AQ_MEDIA_AVAILABLE 0x40 +#define I40E_AQ_SIGNAL_DETECT 0x80 + u8 an_info; +#define I40E_AQ_AN_COMPLETED 0x01 +#define I40E_AQ_LP_AN_ABILITY 0x02 +#define I40E_AQ_PD_FAULT 0x04 +#define I40E_AQ_FEC_EN 0x08 +#define I40E_AQ_PHY_LOW_POWER 0x10 +#define I40E_AQ_LINK_PAUSE_TX 0x20 +#define I40E_AQ_LINK_PAUSE_RX 0x40 +#define I40E_AQ_QUALIFIED_MODULE 0x80 + u8 ext_info; +#define I40E_AQ_LINK_PHY_TEMP_ALARM 0x01 +#define I40E_AQ_LINK_XCESSIVE_ERRORS 0x02 +#define I40E_AQ_LINK_TX_SHIFT 0x02 +#define I40E_AQ_LINK_TX_MASK (0x03 << I40E_AQ_LINK_TX_SHIFT) +#define I40E_AQ_LINK_TX_ACTIVE 0x00 +#define I40E_AQ_LINK_TX_DRAINED 0x01 +#define I40E_AQ_LINK_TX_FLUSHED 0x03 +#define I40E_AQ_LINK_FORCED_40G 0x10 + u8 loopback; /* use defines from i40e_aqc_set_lb_mode */ + __le16 max_frame_size; + u8 config; +#define I40E_AQ_CONFIG_CRC_ENA 0x04 +#define I40E_AQ_CONFIG_PACING_MASK 0x78 + u8 reserved[5]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status); /* Set event mask command (direct 0x613) */ struct i40e_aqc_set_phy_int_mask { - u8 reserved[8]; - __le16 event_mask; -#define I40E_AQ_EVENT_LINK_UPDOWN 0x0002 -#define I40E_AQ_EVENT_MEDIA_NA 0x0004 -#define I40E_AQ_EVENT_LINK_FAULT 0x0008 -#define I40E_AQ_EVENT_PHY_TEMP_ALARM 0x0010 -#define I40E_AQ_EVENT_EXCESSIVE_ERRORS 0x0020 -#define I40E_AQ_EVENT_SIGNAL_DETECT 0x0040 -#define I40E_AQ_EVENT_AN_COMPLETED 0x0080 -#define I40E_AQ_EVENT_MODULE_QUAL_FAIL 0x0100 -#define I40E_AQ_EVENT_PORT_TX_SUSPENDED 0x0200 - u8 reserved1[6]; + u8 reserved[8]; + __le16 event_mask; +#define I40E_AQ_EVENT_LINK_UPDOWN 0x0002 +#define I40E_AQ_EVENT_MEDIA_NA 0x0004 +#define I40E_AQ_EVENT_LINK_FAULT 0x0008 +#define I40E_AQ_EVENT_PHY_TEMP_ALARM 0x0010 +#define I40E_AQ_EVENT_EXCESSIVE_ERRORS 0x0020 +#define I40E_AQ_EVENT_SIGNAL_DETECT 0x0040 +#define I40E_AQ_EVENT_AN_COMPLETED 0x0080 +#define I40E_AQ_EVENT_MODULE_QUAL_FAIL 0x0100 +#define I40E_AQ_EVENT_PORT_TX_SUSPENDED 0x0200 + u8 reserved1[6]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_int_mask); @@ -1732,27 +1728,27 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_int_mask); * Get Link Partner AN advt register (direct 0x0616) */ struct i40e_aqc_an_advt_reg { - __le32 local_an_reg0; - __le16 local_an_reg1; - u8 reserved[10]; + __le32 local_an_reg0; + __le16 local_an_reg1; + u8 reserved[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_an_advt_reg); /* Set Loopback mode (0x0618) */ struct i40e_aqc_set_lb_mode { - __le16 lb_mode; -#define I40E_AQ_LB_PHY_LOCAL 0x01 -#define I40E_AQ_LB_PHY_REMOTE 0x02 -#define I40E_AQ_LB_MAC_LOCAL 0x04 - u8 reserved[14]; + __le16 lb_mode; +#define I40E_AQ_LB_PHY_LOCAL 0x01 +#define I40E_AQ_LB_PHY_REMOTE 0x02 +#define I40E_AQ_LB_MAC_LOCAL 0x04 + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_lb_mode); /* Set PHY Debug command (0x0622) */ struct i40e_aqc_set_phy_debug { - u8 command_flags; + u8 command_flags; #define I40E_AQ_PHY_DEBUG_RESET_INTERNAL 0x02 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT 2 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_MASK (0x03 << \ @@ -1761,15 +1757,15 @@ struct i40e_aqc_set_phy_debug { #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_HARD 0x01 #define I40E_AQ_PHY_DEBUG_RESET_EXTERNAL_SOFT 0x02 #define I40E_AQ_PHY_DEBUG_DISABLE_LINK_FW 0x10 - u8 reserved[15]; + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_set_phy_debug); enum i40e_aq_phy_reg_type { - I40E_AQC_PHY_REG_INTERNAL = 0x1, - I40E_AQC_PHY_REG_EXERNAL_BASET = 0x2, - I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3 + I40E_AQC_PHY_REG_INTERNAL = 0x1, + I40E_AQC_PHY_REG_EXERNAL_BASET = 0x2, + I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3 }; /* NVM Read command (indirect 0x0701) @@ -1777,40 +1773,40 @@ enum i40e_aq_phy_reg_type { * NVM Update commands (indirect 0x0703) */ struct i40e_aqc_nvm_update { - u8 command_flags; -#define I40E_AQ_NVM_LAST_CMD 0x01 -#define I40E_AQ_NVM_FLASH_ONLY 0x80 - u8 module_pointer; - __le16 length; - __le32 offset; - __le32 addr_high; - __le32 addr_low; + u8 command_flags; +#define I40E_AQ_NVM_LAST_CMD 0x01 +#define I40E_AQ_NVM_FLASH_ONLY 0x80 + u8 module_pointer; + __le16 length; + __le32 offset; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_update); /* NVM Config Read (indirect 0x0704) */ struct i40e_aqc_nvm_config_read { - __le16 cmd_flags; + __le16 cmd_flags; #define ANVM_SINGLE_OR_MULTIPLE_FEATURES_MASK 1 #define ANVM_READ_SINGLE_FEATURE 0 #define ANVM_READ_MULTIPLE_FEATURES 1 - __le16 element_count; - __le16 element_id; /* Feature/field ID */ - u8 reserved[2]; - __le32 address_high; - __le32 address_low; + __le16 element_count; + __le16 element_id; /* Feature/field ID */ + u8 reserved[2]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_read); /* NVM Config Write (indirect 0x0705) */ struct i40e_aqc_nvm_config_write { - __le16 cmd_flags; - __le16 element_count; - u8 reserved[4]; - __le32 address_high; - __le32 address_low; + __le16 cmd_flags; + __le16 element_count; + u8 reserved[4]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_config_write); @@ -1835,10 +1831,10 @@ struct i40e_aqc_nvm_config_data_immediate_field { * Send to Peer PF command (indirect 0x0803) */ struct i40e_aqc_pf_vf_message { - __le32 id; - u8 reserved[4]; - __le32 addr_high; - __le32 addr_low; + __le32 id; + u8 reserved[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_pf_vf_message); @@ -1874,22 +1870,22 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_ind_write); * uses i40e_aq_desc */ struct i40e_aqc_alternate_write_done { - __le16 cmd_flags; + __le16 cmd_flags; #define I40E_AQ_ALTERNATE_MODE_BIOS_MASK 1 #define I40E_AQ_ALTERNATE_MODE_BIOS_LEGACY 0 #define I40E_AQ_ALTERNATE_MODE_BIOS_UEFI 1 #define I40E_AQ_ALTERNATE_RESET_NEEDED 2 - u8 reserved[14]; + u8 reserved[14]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_write_done); /* Set OEM mode (direct 0x0905) */ struct i40e_aqc_alternate_set_mode { - __le32 mode; + __le32 mode; #define I40E_AQ_ALTERNATE_MODE_NONE 0 #define I40E_AQ_ALTERNATE_MODE_OEM 1 - u8 reserved[12]; + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_set_mode); @@ -1900,33 +1896,33 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_alternate_set_mode); /* Lan Queue Overflow Event (direct, 0x1001) */ struct i40e_aqc_lan_overflow { - __le32 prtdcb_rupto; - __le32 otx_ctl; - u8 reserved[8]; + __le32 prtdcb_rupto; + __le32 otx_ctl; + u8 reserved[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lan_overflow); /* Get LLDP MIB (indirect 0x0A00) */ struct i40e_aqc_lldp_get_mib { - u8 type; - u8 reserved1; -#define I40E_AQ_LLDP_MIB_TYPE_MASK 0x3 -#define I40E_AQ_LLDP_MIB_LOCAL 0x0 -#define I40E_AQ_LLDP_MIB_REMOTE 0x1 -#define I40E_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2 -#define I40E_AQ_LLDP_BRIDGE_TYPE_MASK 0xC -#define I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2 -#define I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0 -#define I40E_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1 -#define I40E_AQ_LLDP_TX_SHIFT 0x4 -#define I40E_AQ_LLDP_TX_MASK (0x03 << I40E_AQ_LLDP_TX_SHIFT) + u8 type; + u8 reserved1; +#define I40E_AQ_LLDP_MIB_TYPE_MASK 0x3 +#define I40E_AQ_LLDP_MIB_LOCAL 0x0 +#define I40E_AQ_LLDP_MIB_REMOTE 0x1 +#define I40E_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2 +#define I40E_AQ_LLDP_BRIDGE_TYPE_MASK 0xC +#define I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2 +#define I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0 +#define I40E_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1 +#define I40E_AQ_LLDP_TX_SHIFT 0x4 +#define I40E_AQ_LLDP_TX_MASK (0x03 << I40E_AQ_LLDP_TX_SHIFT) /* TX pause flags use I40E_AQ_LINK_TX_* above */ - __le16 local_len; - __le16 remote_len; - u8 reserved2[2]; - __le32 addr_high; - __le32 addr_low; + __le16 local_len; + __le16 remote_len; + u8 reserved2[2]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_get_mib); @@ -1935,12 +1931,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_get_mib); * also used for the event (with type in the command field) */ struct i40e_aqc_lldp_update_mib { - u8 command; -#define I40E_AQ_LLDP_MIB_UPDATE_ENABLE 0x0 -#define I40E_AQ_LLDP_MIB_UPDATE_DISABLE 0x1 - u8 reserved[7]; - __le32 addr_high; - __le32 addr_low; + u8 command; +#define I40E_AQ_LLDP_MIB_UPDATE_ENABLE 0x0 +#define I40E_AQ_LLDP_MIB_UPDATE_DISABLE 0x1 + u8 reserved[7]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_mib); @@ -1949,35 +1945,35 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_mib); * Delete LLDP TLV (indirect 0x0A04) */ struct i40e_aqc_lldp_add_tlv { - u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ - u8 reserved1[1]; - __le16 len; - u8 reserved2[4]; - __le32 addr_high; - __le32 addr_low; + u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ + u8 reserved1[1]; + __le16 len; + u8 reserved2[4]; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_add_tlv); /* Update LLDP TLV (indirect 0x0A03) */ struct i40e_aqc_lldp_update_tlv { - u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ - u8 reserved; - __le16 old_len; - __le16 new_offset; - __le16 new_len; - __le32 addr_high; - __le32 addr_low; + u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */ + u8 reserved; + __le16 old_len; + __le16 new_offset; + __le16 new_len; + __le32 addr_high; + __le32 addr_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv); /* Stop LLDP (direct 0x0A05) */ struct i40e_aqc_lldp_stop { - u8 command; -#define I40E_AQ_LLDP_AGENT_STOP 0x0 -#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 - u8 reserved[15]; + u8 command; +#define I40E_AQ_LLDP_AGENT_STOP 0x0 +#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); @@ -1985,9 +1981,9 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); /* Start LLDP (direct 0x0A06) */ struct i40e_aqc_lldp_start { - u8 command; -#define I40E_AQ_LLDP_AGENT_START 0x1 - u8 reserved[15]; + u8 command; +#define I40E_AQ_LLDP_AGENT_START 0x1 + u8 reserved[15]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); @@ -1998,13 +1994,13 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); /* Add Udp Tunnel command and completion (direct 0x0B00) */ struct i40e_aqc_add_udp_tunnel { - __le16 udp_port; - u8 reserved0[3]; - u8 protocol_type; + __le16 udp_port; + u8 reserved0[3]; + u8 protocol_type; #define I40E_AQC_TUNNEL_TYPE_VXLAN 0x00 #define I40E_AQC_TUNNEL_TYPE_NGE 0x01 #define I40E_AQC_TUNNEL_TYPE_TEREDO 0x10 - u8 reserved1[10]; + u8 reserved1[10]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel); @@ -2013,8 +2009,8 @@ struct i40e_aqc_add_udp_tunnel_completion { __le16 udp_port; u8 filter_entry_index; u8 multiple_pfs; -#define I40E_AQC_SINGLE_PF 0x0 -#define I40E_AQC_MULTIPLE_PFS 0x1 +#define I40E_AQC_SINGLE_PF 0x0 +#define I40E_AQC_MULTIPLE_PFS 0x1 u8 total_filters; u8 reserved[11]; }; @@ -2023,23 +2019,19 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel_completion); /* remove UDP Tunnel command (0x0B01) */ struct i40e_aqc_remove_udp_tunnel { - u8 reserved[2]; - u8 index; /* 0 to 15 */ - u8 pf_filters; - u8 total_filters; - u8 reserved2[11]; + u8 reserved[2]; + u8 index; /* 0 to 15 */ + u8 reserved2[13]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel); struct i40e_aqc_del_udp_tunnel_completion { - __le16 udp_port; - u8 index; /* 0 to 15 */ - u8 multiple_pfs; - u8 total_filters_used; - u8 reserved; - u8 tunnels_free; - u8 reserved1[9]; + __le16 udp_port; + u8 index; /* 0 to 15 */ + u8 multiple_pfs; + u8 total_filters_used; + u8 reserved1[11]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion); @@ -2068,11 +2060,11 @@ struct i40e_aqc_tunnel_key_structure { u8 key1_len; /* 0 to 15 */ u8 key2_len; /* 0 to 15 */ u8 flags; -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01 +#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01 /* response flags */ -#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01 -#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02 -#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03 +#define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01 +#define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02 +#define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03 u8 network_key_index; #define I40E_AQC_NETWORK_KEY_INDEX_VXLAN 0x0 #define I40E_AQC_NETWORK_KEY_INDEX_NGE 0x1 @@ -2085,21 +2077,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure); /* OEM mode commands (direct 0xFE0x) */ struct i40e_aqc_oem_param_change { - __le32 param_type; -#define I40E_AQ_OEM_PARAM_TYPE_PF_CTL 0 -#define I40E_AQ_OEM_PARAM_TYPE_BW_CTL 1 -#define I40E_AQ_OEM_PARAM_MAC 2 - __le32 param_value1; - u8 param_value2[8]; + __le32 param_type; +#define I40E_AQ_OEM_PARAM_TYPE_PF_CTL 0 +#define I40E_AQ_OEM_PARAM_TYPE_BW_CTL 1 +#define I40E_AQ_OEM_PARAM_MAC 2 + __le32 param_value1; + u8 param_value2[8]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_param_change); struct i40e_aqc_oem_state_change { - __le32 state; -#define I40E_AQ_OEM_STATE_LINK_DOWN 0x0 -#define I40E_AQ_OEM_STATE_LINK_UP 0x1 - u8 reserved[12]; + __le32 state; +#define I40E_AQ_OEM_STATE_LINK_DOWN 0x0 +#define I40E_AQ_OEM_STATE_LINK_UP 0x1 + u8 reserved[12]; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_state_change); @@ -2111,18 +2103,18 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_oem_state_change); /* set test more (0xFF01, internal) */ struct i40e_acq_set_test_mode { - u8 mode; -#define I40E_AQ_TEST_PARTIAL 0 -#define I40E_AQ_TEST_FULL 1 -#define I40E_AQ_TEST_NVM 2 - u8 reserved[3]; - u8 command; -#define I40E_AQ_TEST_OPEN 0 -#define I40E_AQ_TEST_CLOSE 1 -#define I40E_AQ_TEST_INC 2 - u8 reserved2[3]; - __le32 address_high; - __le32 address_low; + u8 mode; +#define I40E_AQ_TEST_PARTIAL 0 +#define I40E_AQ_TEST_FULL 1 +#define I40E_AQ_TEST_NVM 2 + u8 reserved[3]; + u8 command; +#define I40E_AQ_TEST_OPEN 0 +#define I40E_AQ_TEST_CLOSE 1 +#define I40E_AQ_TEST_INC 2 + u8 reserved2[3]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_acq_set_test_mode); @@ -2175,21 +2167,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg); #define I40E_AQ_CLUSTER_ID_ALTRAM 11 struct i40e_aqc_debug_dump_internals { - u8 cluster_id; - u8 table_id; - __le16 data_size; - __le32 idx; - __le32 address_high; - __le32 address_low; + u8 cluster_id; + u8 table_id; + __le16 data_size; + __le32 idx; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_dump_internals); struct i40e_aqc_debug_modify_internals { - u8 cluster_id; - u8 cluster_specific_params[7]; - __le32 address_high; - __le32 address_low; + u8 cluster_id; + u8 cluster_specific_params[7]; + __le32 address_high; + __le32 address_low; }; I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_internals); -- GitLab From f98a20068dfcc16d1292d3e4d0d690e123da1538 Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Sat, 13 Sep 2014 07:40:44 +0000 Subject: [PATCH 1112/9457] i40e/i40evf: Use usleep_range() instead of udelay() As per the Documentation/timers/timers-howto.txt it is preferred to use usleep_range() instead of udelay() if the delay value is > 10us in non-atomic contexts. So, replacing all the instances of udelay() with 10 or greater than 10 micro seconds delay in the driver and using usleep_range() instead. Change-ID: Iaa2ab499a4c26f6005e5d86cc421407ef9de16c7 Reported-by: Fengguang Wu Signed-off-by: Neerav Parikh Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +++--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2 +- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d40fc3b9c46e..f7464e87d521 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3440,7 +3440,7 @@ static int i40e_pf_txq_wait(struct i40e_pf *pf, int pf_q, bool enable) if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) break; - udelay(10); + usleep_range(10, 20); } if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT) return -ETIMEDOUT; @@ -3466,7 +3466,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) /* warn the TX unit of coming changes */ i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); if (!enable) - udelay(10); + usleep_range(10, 20); for (j = 0; j < 50; j++) { tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); @@ -3526,7 +3526,7 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, bool enable) if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK)) break; - udelay(10); + usleep_range(10, 20); } if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT) return -ETIMEDOUT; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 4eeed267e4b7..fff3c276736b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -674,7 +674,7 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) * that the requested op was completed * successfully */ - udelay(10); + usleep_range(10, 20); reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id)); if (reg & I40E_VPGEN_VFRSTAT_VFRD_MASK) { rsd = true; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index c51bc7a33bc5..dabe6a4220c6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1494,7 +1494,7 @@ static void i40evf_reset_task(struct work_struct *work) while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section)) - udelay(500); + usleep_range(500, 1000); if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) { dev_info(&adapter->pdev->dev, "Requesting reset from PF\n"); @@ -1980,7 +1980,7 @@ static int i40evf_check_reset_complete(struct i40e_hw *hw) if ((rstat == I40E_VFR_VFACTIVE) || (rstat == I40E_VFR_COMPLETED)) return 0; - udelay(10); + usleep_range(10, 20); } return -EBUSY; } -- GitLab From cafa2ee6fbb1bbc2fecdeef990858d56646fc1bd Mon Sep 17 00:00:00 2001 From: Anjali Singhai Jain Date: Sat, 13 Sep 2014 07:40:45 +0000 Subject: [PATCH 1113/9457] i40e: Fix a bug where Rx would stop after some time Move the setting of flow control because this should be done at a pf level not a vsi level. Also add a sleep and restart an to fix a bug where Rx would stop after some stress. Change-ID: I9a93d8c2ff27c39339eb00bc4ec1225e43900be0 Signed-off-by: Anjali Singhai Jain Signed-off-by: Jesse Brandeburg Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f7464e87d521..ff6d94d4d1e0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4479,12 +4479,8 @@ static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup) static int i40e_up_complete(struct i40e_vsi *vsi) { struct i40e_pf *pf = vsi->back; - u8 set_fc_aq_fail = 0; int err; - /* force flow control off */ - i40e_set_fc(&pf->hw, &set_fc_aq_fail, true); - if (pf->flags & I40E_FLAG_MSIX_ENABLED) i40e_vsi_configure_msix(vsi); else @@ -5958,6 +5954,7 @@ static void i40e_send_version(struct i40e_pf *pf) static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) { struct i40e_hw *hw = &pf->hw; + u8 set_fc_aq_fail = 0; i40e_status ret; u32 v; @@ -6038,6 +6035,11 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) if (ret) dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", ret); + /* make sure our flow control settings are restored */ + ret = i40e_set_fc(&pf->hw, &set_fc_aq_fail, true); + if (ret) + dev_info(&pf->pdev->dev, "set fc fail, aq_err %d\n", ret); + /* Rebuild the VSIs and VEBs that existed before reset. * They are still in our local switch element arrays, so only * need to rebuild the switch model in the HW. @@ -6092,6 +6094,13 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit) } } + msleep(75); + ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL); + if (ret) { + dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n", + pf->hw.aq.asq_last_status); + } + /* reinit the misc interrupt */ if (pf->flags & I40E_FLAG_MSIX_ENABLED) ret = i40e_setup_misc_vector(pf); @@ -9169,6 +9178,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", err); + msleep(75); + err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL); + if (err) { + dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n", + pf->hw.aq.asq_last_status); + } + /* The main driver is (mostly) up and happy. We need to set this state * before setting up the misc vector or we get a race and the vector * ends up disabled forever. -- GitLab From a34a6711f8fc0198439b27aa3f35eedd9fc61222 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Sat, 13 Sep 2014 07:40:46 +0000 Subject: [PATCH 1114/9457] i40e: process link events when setting up switch Add code to handle link events when updating the PF switch. This allows link information to be properly provided to VFs in all cases. Change-ID: If314c95f3d39259ef4c40a4a3b823381e28fb24f Signed-off-by: Mitch Williams Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ff6d94d4d1e0..1fbbe113e8f4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8726,6 +8726,14 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) i40e_update_link_info(&pf->hw, true); i40e_link_event(pf); + /* Initialize user-specific link properties */ + pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info & + I40E_AQ_AN_COMPLETED) ? true : false); + + /* fill in link information and enable LSE reporting */ + i40e_update_link_info(&pf->hw, true); + i40e_link_event(pf); + /* Initialize user-specific link properties */ pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info & I40E_AQ_AN_COMPLETED) ? true : false); -- GitLab From 5960d33f918c65dfee033421b2e04c37ce046b3d Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Sat, 13 Sep 2014 07:40:47 +0000 Subject: [PATCH 1115/9457] i40e: Add 10GBaseT support Add driver support for 10GBaseT device. Change-ID: I4be6ed847ac0bddd220b9878a95c523b32038174 Signed-off-by: Catherine Sullivan Signed-off-by: Shannon Nelson Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 1 + .../net/ethernet/intel/i40e/i40e_ethtool.c | 33 ++++++++++++++++--- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 +++ drivers/net/ethernet/intel/i40e/i40e_type.h | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index c23e3772de58..c49416cfe616 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -50,6 +50,7 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_QSFP_A: case I40E_DEV_ID_QSFP_B: case I40E_DEV_ID_QSFP_C: + case I40E_DEV_ID_10G_BASE_T: hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_VF: diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 1dda467ae1ac..12adc08c54dc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -264,6 +264,14 @@ static int i40e_get_settings(struct net_device *netdev, ecmd->supported = SUPPORTED_10000baseKR_Full; ecmd->advertising = ADVERTISED_10000baseKR_Full; break; + case I40E_DEV_ID_10G_BASE_T: + ecmd->supported = SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_100baseT_Full; + ecmd->advertising = ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | + ADVERTISED_100baseT_Full; + break; default: /* all the rest are 10G/1G */ ecmd->supported = SUPPORTED_10000baseT_Full | @@ -322,9 +330,13 @@ static int i40e_get_settings(struct net_device *netdev, case I40E_PHY_TYPE_10GBASE_CR1: case I40E_PHY_TYPE_10GBASE_T: ecmd->supported = SUPPORTED_Autoneg | - SUPPORTED_10000baseT_Full; + SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_100baseT_Full; ecmd->advertising = ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full; + ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | + ADVERTISED_100baseT_Full; break; case I40E_PHY_TYPE_XAUI: case I40E_PHY_TYPE_XFI: @@ -335,14 +347,22 @@ static int i40e_get_settings(struct net_device *netdev, case I40E_PHY_TYPE_1000BASE_KX: case I40E_PHY_TYPE_1000BASE_T: ecmd->supported = SUPPORTED_Autoneg | - SUPPORTED_1000baseT_Full; + SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_100baseT_Full; ecmd->advertising = ADVERTISED_Autoneg | - ADVERTISED_1000baseT_Full; + ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | + ADVERTISED_100baseT_Full; break; case I40E_PHY_TYPE_100BASE_TX: ecmd->supported = SUPPORTED_Autoneg | + SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full; ecmd->advertising = ADVERTISED_Autoneg | + ADVERTISED_10000baseT_Full | + ADVERTISED_1000baseT_Full | ADVERTISED_100baseT_Full; break; case I40E_PHY_TYPE_SGMII: @@ -426,6 +446,9 @@ static int i40e_get_settings(struct net_device *netdev, case I40E_LINK_SPEED_1GB: ethtool_cmd_speed_set(ecmd, SPEED_1000); break; + case I40E_LINK_SPEED_100MB: + ethtool_cmd_speed_set(ecmd, SPEED_100); + break; default: break; } @@ -528,7 +551,7 @@ static int i40e_set_settings(struct net_device *netdev, } /* If autoneg is currently enabled */ if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) { - config.abilities = abilities.abilities | + config.abilities = abilities.abilities & ~I40E_AQ_PHY_ENABLE_AN; change = true; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 1fbbe113e8f4..9d36d10df868 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -74,6 +74,7 @@ static const struct pci_device_id i40e_pci_tbl[] = { {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_A), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_B), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_C), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T), 0}, /* required last entry */ {0, } }; @@ -4449,6 +4450,9 @@ static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup) case I40E_LINK_SPEED_1GB: strlcpy(speed, "1000 Mbps", SPEED_SIZE); break; + case I40E_LINK_SPEED_100MB: + strncpy(speed, "100 Mbps", SPEED_SIZE); + break; default: break; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index ce04d9093db6..3a237c3d0dcb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -43,6 +43,7 @@ #define I40E_DEV_ID_QSFP_A 0x1583 #define I40E_DEV_ID_QSFP_B 0x1584 #define I40E_DEV_ID_QSFP_C 0x1585 +#define I40E_DEV_ID_10G_BASE_T 0x1586 #define I40E_DEV_ID_VF 0x154C #define I40E_DEV_ID_VF_HV 0x1571 -- GitLab From bf00b376d329bbabd885dcaebe67f1119faf3ad4 Mon Sep 17 00:00:00 2001 From: Akeem G Abodunrin Date: Fri, 17 Oct 2014 03:14:39 +0000 Subject: [PATCH 1116/9457] i40e: Moving variable declaration out of the loops Move the three variables out of the loop, so it only declares once. Change-ID: I436913777c7da3c16dc0031b59e3ffa61de74718 Signed-off-by: Akeem G Abodunrin Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9d36d10df868..b0c10e0f8a9f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -813,7 +813,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) struct i40e_eth_stats *oes; struct i40e_eth_stats *es; /* device's eth stats */ u32 tx_restart, tx_busy; + struct i40e_ring *p; u32 rx_page, rx_buf; + u64 bytes, packets; + unsigned int start; u64 rx_p, rx_b; u64 tx_p, tx_b; u16 q; @@ -837,10 +840,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) rx_buf = 0; rcu_read_lock(); for (q = 0; q < vsi->num_queue_pairs; q++) { - struct i40e_ring *p; - u64 bytes, packets; - unsigned int start; - /* locate Tx ring */ p = ACCESS_ONCE(vsi->tx_rings[q]); -- GitLab From e8720db1fbf0529e9f5ac3756f23828ce817f5ab Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Sat, 13 Sep 2014 07:40:48 +0000 Subject: [PATCH 1117/9457] i40e: Bump version Bump i40e version to 1.0.21. Signed-off-by: Catherine Sullivan Tested-By: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b0c10e0f8a9f..da3f3a704b08 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -39,7 +39,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 1 #define DRV_VERSION_MINOR 0 -#define DRV_VERSION_BUILD 11 +#define DRV_VERSION_BUILD 21 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN -- GitLab From 105970f6087ae240b00deaff85773ed9bf381145 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 20 Oct 2014 18:15:50 +0900 Subject: [PATCH 1118/9457] net: Remove trailing whitespace in tcp.h icmp.c syncookies.c Remove trailing whitespace in tcp.h icmp.c syncookies.c Signed-off-by: Kenjiro Nakayama Signed-off-by: David S. Miller --- include/net/tcp.h | 12 ++++++------ net/ipv6/icmp.c | 1 - net/ipv6/syncookies.c | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 4062b4f0d121..c73fc145ee45 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -55,9 +55,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define MAX_TCP_HEADER (128 + MAX_HEADER) #define MAX_TCP_OPTION_SPACE 40 -/* +/* * Never offer a window over 32767 without using window scaling. Some - * poor stacks do signed 16bit maths! + * poor stacks do signed 16bit maths! */ #define MAX_TCP_WINDOW 32767U @@ -167,7 +167,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); /* * TCP option */ - + #define TCPOPT_NOP 1 /* Padding */ #define TCPOPT_EOL 0 /* End of options */ #define TCPOPT_MSS 2 /* Segment size negotiating */ @@ -1104,16 +1104,16 @@ static inline int tcp_win_from_space(int space) space - (space>>sysctl_tcp_adv_win_scale); } -/* Note: caller must be prepared to deal with negative returns */ +/* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { return tcp_win_from_space(sk->sk_rcvbuf - atomic_read(&sk->sk_rmem_alloc)); -} +} static inline int tcp_full_space(const struct sock *sk) { - return tcp_win_from_space(sk->sk_rcvbuf); + return tcp_win_from_space(sk->sk_rcvbuf); } static inline void tcp_openreq_init(struct request_sock *req, diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 97ae70077a4f..62c1037d9e83 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -1009,4 +1009,3 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net) return table; } #endif - diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 2f25cb6347ca..0e26e795b703 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -269,4 +269,3 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) reqsk_free(req); return NULL; } - -- GitLab From a3c00e46efdb4009369971c97203ea67f7630fe4 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 20 Oct 2014 13:42:43 -0700 Subject: [PATCH 1119/9457] ipv6: Remove BACKTRACK macro It is the prep work to reduce the number of calls to fib6_lookup(). The BACKTRACK macro could be hard-to-read and error-prone due to its side effects (mainly goto). This patch is to: 1. Replace BACKTRACK macro with a function (fib6_backtrack) with the following return values: * If it is backtrack-able, returns next fn for retry. * If it reaches the root, returns NULL. 2. The caller needs to decide if a backtrack is needed (by testing rt == net->ipv6.ip6_null_entry). 3. Rename the goto labels in ip6_pol_route() to make the next few patches easier to read. Cc: David Miller Cc: Hannes Frederic Sowa Signed-off-by: Martin KaFai Lau Signed-off-by: David S. Miller --- net/ipv6/route.c | 70 +++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a318dd89b6d9..f1ab2f4f4529 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -772,23 +772,22 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, } #endif -#define BACKTRACK(__net, saddr) \ -do { \ - if (rt == __net->ipv6.ip6_null_entry) { \ - struct fib6_node *pn; \ - while (1) { \ - if (fn->fn_flags & RTN_TL_ROOT) \ - goto out; \ - pn = fn->parent; \ - if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \ - fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \ - else \ - fn = pn; \ - if (fn->fn_flags & RTN_RTINFO) \ - goto restart; \ - } \ - } \ -} while (0) +static struct fib6_node* fib6_backtrack(struct fib6_node *fn, + struct in6_addr *saddr) +{ + struct fib6_node *pn; + while (1) { + if (fn->fn_flags & RTN_TL_ROOT) + return NULL; + pn = fn->parent; + if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) + fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); + else + fn = pn; + if (fn->fn_flags & RTN_RTINFO) + return fn; + } +} static struct rt6_info *ip6_pol_route_lookup(struct net *net, struct fib6_table *table, @@ -804,8 +803,11 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, flags); - BACKTRACK(net, &fl6->saddr); -out: + if (rt == net->ipv6.ip6_null_entry) { + fn = fib6_backtrack(fn, &fl6->saddr); + if (fn) + goto restart; + } dst_use(&rt->dst, jiffies); read_unlock_bh(&table->tb6_lock); return rt; @@ -924,19 +926,25 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, strict |= flags & RT6_LOOKUP_F_IFACE; -relookup: +redo_fib6_lookup_lock: read_lock_bh(&table->tb6_lock); -restart_2: +redo_fib6_lookup: fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); -restart: +redo_rt6_select: rt = rt6_select(fn, oif, strict | reachable); if (rt->rt6i_nsiblings) rt = rt6_multipath_select(rt, fl6, oif, strict | reachable); - BACKTRACK(net, &fl6->saddr); - if (rt == net->ipv6.ip6_null_entry || - rt->rt6i_flags & RTF_CACHE) + if (rt == net->ipv6.ip6_null_entry) { + fn = fib6_backtrack(fn, &fl6->saddr); + if (fn) + goto redo_rt6_select; + else + goto out; + } + + if (rt->rt6i_flags & RTF_CACHE) goto out; dst_hold(&rt->dst); @@ -967,12 +975,12 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, * released someone could insert this route. Relookup. */ ip6_rt_put(rt); - goto relookup; + goto redo_fib6_lookup_lock; out: if (reachable) { reachable = 0; - goto restart_2; + goto redo_fib6_lookup; } dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); @@ -1235,10 +1243,12 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, rt = net->ipv6.ip6_null_entry; else if (rt->dst.error) { rt = net->ipv6.ip6_null_entry; - goto out; + } else if (rt == net->ipv6.ip6_null_entry) { + fn = fib6_backtrack(fn, &fl6->saddr); + if (fn) + goto restart; } - BACKTRACK(net, &fl6->saddr); -out: + dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); -- GitLab From 94c77bb41d871deb848e5011aacb5d7c24358ddd Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 20 Oct 2014 13:42:44 -0700 Subject: [PATCH 1120/9457] ipv6: Avoid redoing fib6_lookup() for RTF_CACHE hit case When there is a RTF_CACHE hit, no need to redo fib6_lookup() with reachable=0. Cc: David Miller Cc: Hannes Frederic Sowa Signed-off-by: Martin KaFai Lau Signed-off-by: David S. Miller --- net/ipv6/route.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f1ab2f4f4529..98c523f4a3c3 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -944,12 +944,12 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, goto out; } - if (rt->rt6i_flags & RTF_CACHE) - goto out; - dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); + if (rt->rt6i_flags & RTF_CACHE) + goto out2; + if (!(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_GATEWAY))) nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); else if (!(rt->dst.flags & DST_HOST)) -- GitLab From 367efcb932c1cfc134d5b1fd9db8665ae5e6a251 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 20 Oct 2014 13:42:45 -0700 Subject: [PATCH 1121/9457] ipv6: Avoid redoing fib6_lookup() with reachable = 0 by saving fn This patch save the fn before doing rt6_backtrack. Hence, without redo-ing the fib6_lookup(), saved_fn can be used to redo rt6_select() with RT6_LOOKUP_F_REACHABLE off. Some minor changes I think make sense to review as a single patch: * Remove the 'out:' goto label. * Remove the 'reachable' variable. Only use the 'strict' variable instead. After this patch, "failing ip6_ins_rt()" should be the only case that requires a redo of fib6_lookup(). Cc: David Miller Cc: Hannes Frederic Sowa Signed-off-by: Martin KaFai Lau Signed-off-by: David S. Miller --- net/ipv6/route.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 98c523f4a3c3..c91083156edb 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -917,31 +917,40 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, struct flowi6 *fl6, int flags) { - struct fib6_node *fn; + struct fib6_node *fn, *saved_fn; struct rt6_info *rt, *nrt; int strict = 0; int attempts = 3; int err; - int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; strict |= flags & RT6_LOOKUP_F_IFACE; + if (net->ipv6.devconf_all->forwarding == 0) + strict |= RT6_LOOKUP_F_REACHABLE; redo_fib6_lookup_lock: read_lock_bh(&table->tb6_lock); -redo_fib6_lookup: fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); + saved_fn = fn; redo_rt6_select: - rt = rt6_select(fn, oif, strict | reachable); + rt = rt6_select(fn, oif, strict); if (rt->rt6i_nsiblings) - rt = rt6_multipath_select(rt, fl6, oif, strict | reachable); + rt = rt6_multipath_select(rt, fl6, oif, strict); if (rt == net->ipv6.ip6_null_entry) { fn = fib6_backtrack(fn, &fl6->saddr); if (fn) goto redo_rt6_select; - else - goto out; + else if (strict & RT6_LOOKUP_F_REACHABLE) { + /* also consider unreachable route */ + strict &= ~RT6_LOOKUP_F_REACHABLE; + fn = saved_fn; + goto redo_rt6_select; + } else { + dst_hold(&rt->dst); + read_unlock_bh(&table->tb6_lock); + goto out2; + } } dst_hold(&rt->dst); @@ -977,13 +986,6 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, ip6_rt_put(rt); goto redo_fib6_lookup_lock; -out: - if (reachable) { - reachable = 0; - goto redo_fib6_lookup; - } - dst_hold(&rt->dst); - read_unlock_bh(&table->tb6_lock); out2: rt->dst.lastuse = jiffies; rt->dst.__use++; -- GitLab From 16704b129bc1e497862e88253da20b13a1b94b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Barr=C3=A9?= Date: Tue, 21 Oct 2014 15:26:15 +0200 Subject: [PATCH 1122/9457] Removed unused function sctp_addr_is_valid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sctp_addr_is_valid() only appeared in its definition. Acked-by: Neil Horman Signed-off-by: Sébastien Barré Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 4ff3f67be62c..806e3b5b3351 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1116,7 +1116,6 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, sctp_scope_t sctp_scope(const union sctp_addr *); int sctp_in_scope(struct net *net, const union sctp_addr *addr, const sctp_scope_t scope); int sctp_is_any(struct sock *sk, const union sctp_addr *addr); -int sctp_addr_is_valid(const union sctp_addr *addr); int sctp_is_ep_boundall(struct sock *sk); -- GitLab From 00fd5d94c219839925959d73e266702f08ba283a Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 21 Oct 2014 16:51:43 +0200 Subject: [PATCH 1123/9457] net: typhoon: Remove redundant casts Both image_data and typhoon_fw->data are const u8*, so the cast to u8* is unnecessary and confusing. Signed-off-by: Rasmus Villemoes Acked-by: David Dillow Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/typhoon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index 48775b88bac7..dede43f4ce09 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -1285,7 +1285,7 @@ typhoon_request_firmware(struct typhoon *tp) return err; } - image_data = (u8 *) typhoon_fw->data; + image_data = typhoon_fw->data; remaining = typhoon_fw->size; if (remaining < sizeof(struct typhoon_file_header)) goto invalid_fw; @@ -1343,7 +1343,7 @@ typhoon_download_firmware(struct typhoon *tp) int i; int err; - image_data = (u8 *) typhoon_fw->data; + image_data = typhoon_fw->data; fHdr = (struct typhoon_file_header *) image_data; /* Cannot just map the firmware image using pci_map_single() as -- GitLab From 7f30b7420b4c8ca4ae71167b6856c82972b6e193 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 21 Oct 2014 19:53:11 +0200 Subject: [PATCH 1124/9457] cirrus/mac89x0: Remove superfluous interrupt disable/restore As of commit e4dc601bf99ccd1c ("m68k: Disable/restore interrupts in hwreg_present()/hwreg_write()"), this is no longer needed. Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/cirrus/mac89x0.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/cirrus/mac89x0.c b/drivers/net/ethernet/cirrus/mac89x0.c index e285f384b096..07719676c305 100644 --- a/drivers/net/ethernet/cirrus/mac89x0.c +++ b/drivers/net/ethernet/cirrus/mac89x0.c @@ -216,14 +216,10 @@ struct net_device * __init mac89x0_probe(int unit) ioaddr = (unsigned long) nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE); { - unsigned long flags; int card_present; - local_irq_save(flags); - card_present = (hwreg_present((void*) ioaddr+4) && - hwreg_present((void*) ioaddr + DATA_PORT)); - local_irq_restore(flags); - + card_present = (hwreg_present((void *)ioaddr + 4) && + hwreg_present((void *)ioaddr + DATA_PORT)); if (!card_present) goto out; } -- GitLab From d4c3363e84ba03f4f8c434145d352f44c2b2443b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 21 Oct 2014 19:53:57 +0200 Subject: [PATCH 1125/9457] natsemi/macsonic: Remove superfluous interrupt disable/restore As of commit e4dc601bf99ccd1c ("m68k: Disable/restore interrupts in hwreg_present()/hwreg_write()"), this is no longer needed. Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/natsemi/macsonic.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index 9e4ddbba7036..66c2d50d5b8d 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -326,13 +326,9 @@ static int mac_onboard_sonic_probe(struct net_device *dev) macintosh_config->ident == MAC_MODEL_P588 || macintosh_config->ident == MAC_MODEL_P575 || macintosh_config->ident == MAC_MODEL_C610) { - unsigned long flags; int card_present; - local_irq_save(flags); card_present = hwreg_present((void*)ONBOARD_SONIC_REGISTERS); - local_irq_restore(flags); - if (!card_present) { printk("none.\n"); return -ENODEV; -- GitLab From 2155c3f82327bddd092bd704ebaff79c0a2dfb9c Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:22:58 -0700 Subject: [PATCH 1126/9457] mac80211-hwsim: add ethtool stats support This gives a view into packet activity at the virtual radio level. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 75 ++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6ffe07323e6e..4e92a5b9324d 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -450,6 +450,14 @@ struct mac80211_hwsim_data { s64 bcn_delta; /* absolute beacon transmission time. Used to cover up "tx" delay. */ u64 abs_bcn_ts; + + /* Stats */ + u64 tx_pkts; + u64 rx_pkts; + u64 tx_bytes; + u64 rx_bytes; + u64 tx_dropped; + u64 tx_failed; }; @@ -865,8 +873,10 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, /* If the queue contains MAX_QUEUE skb's drop some */ if (skb_queue_len(&data->pending) >= MAX_QUEUE) { /* Droping until WARN_QUEUE level */ - while (skb_queue_len(&data->pending) >= WARN_QUEUE) + while (skb_queue_len(&data->pending) >= WARN_QUEUE) { ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); + data->tx_dropped++; + } } skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -921,11 +931,14 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, /* Enqueue the packet */ skb_queue_tail(&data->pending, my_skb); + data->tx_pkts++; + data->tx_bytes += my_skb->len; return; nla_put_failure: printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); ieee80211_free_txskb(hw, my_skb); + data->tx_failed++; } static bool hwsim_chans_compat(struct ieee80211_channel *c1, @@ -1071,6 +1084,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, rx_status.mactime = now + data2->tsf_offset; memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); + data2->rx_pkts++; + data2->rx_bytes += nskb->len; ieee80211_rx_irqsafe(data2->hw, nskb); } spin_unlock(&hwsim_radio_lock); @@ -1138,6 +1153,8 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); /* NO wmediumd detected, perfect medium simulation */ + data->tx_pkts++; + data->tx_bytes += skb->len; ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel); if (ack && skb->len >= 16) { @@ -1921,6 +1938,57 @@ static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw, hwsim_check_chanctx_magic(ctx); } +static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = { + "tx_pkts_nic", + "tx_bytes_nic", + "rx_pkts_nic", + "rx_bytes_nic", + "d_tx_dropped", + "d_tx_failed", + "d_ps_mode", + "d_group", + "d_tx_power", +}; + +#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats) + +static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset == ETH_SS_STATS) + memcpy(data, *mac80211_hwsim_gstrings_stats, + sizeof(mac80211_hwsim_gstrings_stats)); +} + +static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset) +{ + if (sset == ETH_SS_STATS) + return MAC80211_HWSIM_SSTATS_LEN; + return 0; +} + +static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct mac80211_hwsim_data *ar = hw->priv; + int i = 0; + + data[i++] = ar->tx_pkts; + data[i++] = ar->tx_bytes; + data[i++] = ar->rx_pkts; + data[i++] = ar->rx_bytes; + data[i++] = ar->tx_dropped; + data[i++] = ar->tx_failed; + data[i++] = ar->ps; + data[i++] = ar->group; + data[i++] = ar->power_level; + + WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN); +} + static const struct ieee80211_ops mac80211_hwsim_ops = { .tx = mac80211_hwsim_tx, .start = mac80211_hwsim_start, @@ -1944,6 +2012,9 @@ static const struct ieee80211_ops mac80211_hwsim_ops = { .flush = mac80211_hwsim_flush, .get_tsf = mac80211_hwsim_get_tsf, .set_tsf = mac80211_hwsim_set_tsf, + .get_et_sset_count = mac80211_hwsim_get_et_sset_count, + .get_et_stats = mac80211_hwsim_get_et_stats, + .get_et_strings = mac80211_hwsim_get_et_strings, }; static struct ieee80211_ops mac80211_hwsim_mchan_ops; @@ -2394,6 +2465,8 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + data2->rx_pkts++; + data2->rx_bytes += skb->len; ieee80211_rx_irqsafe(data2->hw, skb); return 0; -- GitLab From 8cdd9e1c37dd888894922b8209d5fc8055cfde52 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:22:59 -0700 Subject: [PATCH 1127/9457] mac80211-hwsim: support destroying radio by name It is not always convenient to have to know the device-id, so allow deleting by name as well. Signed-off-by: Ben Greear [use wiphy_name() instead of dev_name()] Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 21 ++++++++++++++++----- drivers/net/wireless/mac80211_hwsim.h | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4e92a5b9324d..e9f7c1ec50a4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2544,16 +2544,27 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) { struct mac80211_hwsim_data *data; - int idx; + s64 idx = -1; + const char *hwname = NULL; - if (!info->attrs[HWSIM_ATTR_RADIO_ID]) + if (info->attrs[HWSIM_ATTR_RADIO_ID]) + idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); + else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) + hwname = (void *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); + else return -EINVAL; - idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); spin_lock_bh(&hwsim_radio_lock); list_for_each_entry(data, &hwsim_radios, list) { - if (data->idx != idx) - continue; + if (idx >= 0) { + if (data->idx != idx) + continue; + } else { + if (hwname && + strcmp(hwname, wiphy_name(data->hw->wiphy))) + continue; + } + list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); mac80211_hwsim_destroy_radio(data); diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index b96d8670a703..98c69984878d 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -113,6 +113,7 @@ enum { * single channel is supported * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO * command to force radio removal when process that created the radio dies + * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 * @__HWSIM_ATTR_MAX: enum limit */ @@ -135,6 +136,7 @@ enum { HWSIM_ATTR_SUPPORT_P2P_DEVICE, HWSIM_ATTR_USE_CHANCTX, HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, + HWSIM_ATTR_RADIO_NAME, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) -- GitLab From 49d776ffb50f2e428aafb6a6576e58e80f1e886c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 24 Oct 2014 12:36:23 +0200 Subject: [PATCH 1128/9457] ALSA: pcm: Avoid mmap warnings on x86 On x86, using dma_mmap_coherent() for the pages allocated via dma_alloc_coherent() results in a warning like: aplay:32536 map pfn RAM range req uncached-minus for [mem 0x21d500000-0x21d51ffff], got write-back Until the issue is addressed in the core side, take back to the old good way in PCM code only for x86. Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index dc9a1355a4ab..03e1e920ab13 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3326,6 +3326,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, area->vm_end - area->vm_start, area->vm_page_prot); } #endif /* CONFIG_GENERIC_ALLOCATOR */ +#ifndef CONFIG_X86 /* for avoiding warnings arch/x86/mm/pat.c */ if (!substream->ops->page && substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) return dma_mmap_coherent(substream->dma_buffer.dev.dev, @@ -3333,6 +3334,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, substream->runtime->dma_area, substream->runtime->dma_addr, area->vm_end - area->vm_start); +#endif /* CONFIG_X86 */ /* mmap with fault handler */ area->vm_ops = &snd_pcm_vm_ops_data_fault; return 0; -- GitLab From 7f2691a19627a8d7723909b6e82468fd4437e445 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 16 Oct 2014 21:47:58 +0200 Subject: [PATCH 1129/9457] gpio: vf610: add gpiolib/IRQ chip driver for Vybrid Add a gpiolib and IRQ chip driver for Vybrid ARM SoC using the Vybrid's GPIO and PORT module. The driver is instanced once per each GPIO/PORT module pair and handles 32 GPIO's. Signed-off-by: Stefan Agner Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-vf610.c | 295 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 drivers/gpio/gpio-vf610.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index cd3313436b3a..690ad0b20414 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -347,6 +347,13 @@ config GPIO_TZ1090_PDC help Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs. +config GPIO_VF610 + def_bool y + depends on ARCH_MXC && SOC_VF610 + select GPIOLIB_IRQCHIP + help + Say yes here to support Vybrid vf610 GPIOs. + config GPIO_XGENE bool "APM X-Gene GPIO controller support" depends on ARM64 && OF_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4486bbd2dad7..aaea751fa845 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -96,6 +96,7 @@ obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o obj-$(CONFIG_GPIO_TZ1090) += gpio-tz1090.o obj-$(CONFIG_GPIO_TZ1090_PDC) += gpio-tz1090-pdc.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o +obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c new file mode 100644 index 000000000000..4ee4cee832ec --- /dev/null +++ b/drivers/gpio/gpio-vf610.c @@ -0,0 +1,295 @@ +/* + * vf610 GPIO support through PORT and GPIO module + * + * Copyright (c) 2014 Toradex AG. + * + * Author: Stefan Agner . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VF610_GPIO_PER_PORT 32 + +struct vf610_gpio_port { + struct gpio_chip gc; + void __iomem *base; + void __iomem *gpio_base; + u8 irqc[VF610_GPIO_PER_PORT]; + int irq; +}; + +#define GPIO_PDOR 0x00 +#define GPIO_PSOR 0x04 +#define GPIO_PCOR 0x08 +#define GPIO_PTOR 0x0c +#define GPIO_PDIR 0x10 + +#define PORT_PCR(n) ((n) * 0x4) +#define PORT_PCR_IRQC_OFFSET 16 + +#define PORT_ISFR 0xa0 +#define PORT_DFER 0xc0 +#define PORT_DFCR 0xc4 +#define PORT_DFWR 0xc8 + +#define PORT_INT_OFF 0x0 +#define PORT_INT_LOGIC_ZERO 0x8 +#define PORT_INT_RISING_EDGE 0x9 +#define PORT_INT_FALLING_EDGE 0xa +#define PORT_INT_EITHER_EDGE 0xb +#define PORT_INT_LOGIC_ONE 0xc + +static const struct of_device_id vf610_gpio_dt_ids[] = { + { .compatible = "fsl,vf610-gpio" }, + { /* sentinel */ } +}; + +static inline void vf610_gpio_writel(u32 val, void __iomem *reg) +{ + writel_relaxed(val, reg); +} + +static inline u32 vf610_gpio_readl(void __iomem *reg) +{ + return readl_relaxed(reg); +} + +static int vf610_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + return pinctrl_request_gpio(chip->base + offset); +} + +static void vf610_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + pinctrl_free_gpio(chip->base + offset); +} + +static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct vf610_gpio_port *port = + container_of(gc, struct vf610_gpio_port, gc); + + return !!(vf610_gpio_readl(port->gpio_base + GPIO_PDIR) & BIT(gpio)); +} + +static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct vf610_gpio_port *port = + container_of(gc, struct vf610_gpio_port, gc); + unsigned long mask = BIT(gpio); + + if (val) + vf610_gpio_writel(mask, port->gpio_base + GPIO_PSOR); + else + vf610_gpio_writel(mask, port->gpio_base + GPIO_PCOR); +} + +static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + return pinctrl_gpio_direction_input(chip->base + gpio); +} + +static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, + int value) +{ + vf610_gpio_set(chip, gpio, value); + + return pinctrl_gpio_direction_output(chip->base + gpio); +} + +static void vf610_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + struct vf610_gpio_port *port = irq_get_handler_data(irq); + struct irq_chip *chip = irq_desc_get_chip(desc); + int pin; + unsigned long irq_isfr; + + chained_irq_enter(chip, desc); + + irq_isfr = vf610_gpio_readl(port->base + PORT_ISFR); + + for_each_set_bit(pin, &irq_isfr, VF610_GPIO_PER_PORT) { + vf610_gpio_writel(BIT(pin), port->base + PORT_ISFR); + + generic_handle_irq(irq_find_mapping(port->gc.irqdomain, pin)); + } + + chained_irq_exit(chip, desc); +} + +static void vf610_gpio_irq_ack(struct irq_data *d) +{ + struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d); + int gpio = d->hwirq; + + vf610_gpio_writel(BIT(gpio), port->base + PORT_ISFR); +} + +static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type) +{ + struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d); + u8 irqc; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + irqc = PORT_INT_RISING_EDGE; + break; + case IRQ_TYPE_EDGE_FALLING: + irqc = PORT_INT_FALLING_EDGE; + break; + case IRQ_TYPE_EDGE_BOTH: + irqc = PORT_INT_EITHER_EDGE; + break; + case IRQ_TYPE_LEVEL_LOW: + irqc = PORT_INT_LOGIC_ZERO; + break; + case IRQ_TYPE_LEVEL_HIGH: + irqc = PORT_INT_LOGIC_ONE; + break; + default: + return -EINVAL; + } + + port->irqc[d->hwirq] = irqc; + + return 0; +} + +static void vf610_gpio_irq_mask(struct irq_data *d) +{ + struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d); + void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); + + vf610_gpio_writel(0, pcr_base); +} + +static void vf610_gpio_irq_unmask(struct irq_data *d) +{ + struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d); + void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); + + vf610_gpio_writel(port->irqc[d->hwirq] << PORT_PCR_IRQC_OFFSET, + pcr_base); +} + +static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable) +{ + struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d); + + if (enable) + enable_irq_wake(port->irq); + else + disable_irq_wake(port->irq); + + return 0; +} + +static struct irq_chip vf610_gpio_irq_chip = { + .name = "gpio-vf610", + .irq_ack = vf610_gpio_irq_ack, + .irq_mask = vf610_gpio_irq_mask, + .irq_unmask = vf610_gpio_irq_unmask, + .irq_set_type = vf610_gpio_irq_set_type, + .irq_set_wake = vf610_gpio_irq_set_wake, +}; + +static int vf610_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct vf610_gpio_port *port; + struct resource *iores; + struct gpio_chip *gc; + int ret; + + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + port->base = devm_ioremap_resource(dev, iores); + if (IS_ERR(port->base)) + return PTR_ERR(port->base); + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 1); + port->gpio_base = devm_ioremap_resource(dev, iores); + if (IS_ERR(port->gpio_base)) + return PTR_ERR(port->gpio_base); + + port->irq = platform_get_irq(pdev, 0); + if (port->irq < 0) + return port->irq; + + gc = &port->gc; + gc->of_node = np; + gc->dev = dev; + gc->label = "vf610-gpio", + gc->ngpio = VF610_GPIO_PER_PORT, + gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; + + gc->request = vf610_gpio_request, + gc->free = vf610_gpio_free, + gc->direction_input = vf610_gpio_direction_input, + gc->get = vf610_gpio_get, + gc->direction_output = vf610_gpio_direction_output, + gc->set = vf610_gpio_set, + + ret = gpiochip_add(gc); + if (ret < 0) + return ret; + + /* Clear the interrupt status register for all GPIO's */ + vf610_gpio_writel(~0, port->base + PORT_ISFR); + + ret = gpiochip_irqchip_add(gc, &vf610_gpio_irq_chip, 0, + handle_simple_irq, IRQ_TYPE_NONE); + if (ret) { + dev_err(dev, "failed to add irqchip\n"); + gpiochip_remove(gc); + return ret; + } + gpiochip_set_chained_irqchip(gc, &vf610_gpio_irq_chip, port->irq, + vf610_gpio_irq_handler); + + return 0; +} + +static struct platform_driver vf610_gpio_driver = { + .driver = { + .name = "gpio-vf610", + .owner = THIS_MODULE, + .of_match_table = vf610_gpio_dt_ids, + }, + .probe = vf610_gpio_probe, +}; + +static int __init gpio_vf610_init(void) +{ + return platform_driver_register(&vf610_gpio_driver); +} +device_initcall(gpio_vf610_init); + +MODULE_AUTHOR("Stefan Agner "); +MODULE_DESCRIPTION("Freescale VF610 GPIO"); +MODULE_LICENSE("GPL v2"); -- GitLab From 580b9676e53af8f037002c16bafc7037319bbbce Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 16 Oct 2014 21:48:00 +0200 Subject: [PATCH 1130/9457] Documentation: dts: add bindings for Vybrid GPIO/PORT module The Vybrid SoC device tree (vf610.dtsi) used this bindings since its initial commit in May 2013. However, a proper gpiolib driver was missing so far. With the addition of the gpiolib driver, the bindings proved to be useful and complete, hence a good time to add the documentation. Signed-off-by: Stefan Agner Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio-vf610.txt | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-vf610.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt new file mode 100644 index 000000000000..436cc99c6598 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt @@ -0,0 +1,55 @@ +* Freescale VF610 PORT/GPIO module + +The Freescale PORT/GPIO modules are two adjacent modules providing GPIO +functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of +each, and each PORT module has its own interrupt. + +Required properties for GPIO node: +- compatible : Should be "fsl,-gpio", currently "fsl,vf610-gpio" +- reg : The first reg tuple represents the PORT module, the second tuple + the GPIO module. +- interrupts : Should be the port interrupt shared by all 32 pins. +- gpio-controller : Marks the device node as a gpio controller. +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify the gpio polarity: + 0 = active high + 1 = active low +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells : Should be 2. The first cell is the GPIO number. + The second cell bits[3:0] is used to specify trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. + +Note: Each GPIO port should have an alias correctly numbered in "aliases" +node. + +Examples: + +aliases { + gpio0 = &gpio1; + gpio1 = &gpio2; +}; + +gpio1: gpio@40049000 { + compatible = "fsl,vf610-gpio"; + reg = <0x40049000 0x1000 0x400ff000 0x40>; + interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 0 32>; +}; + +gpio2: gpio@4004a000 { + compatible = "fsl,vf610-gpio"; + reg = <0x4004a000 0x1000 0x400ff040 0x40>; + interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 32 32>; +}; -- GitLab From f6b946ef78eb08727615f00b88032b9dd1038b96 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:22 +0300 Subject: [PATCH 1131/9457] ath10k: don't drop control and null func Rx HTT_RX_IND_MPDU_STATUS_MGMT_CTRL was pretty greedy and because of that ath10k ended up dropping Control Frames as well as Null Func frames. Reported-by: Okhwan Lee Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index fbb3175d4d6e..63c69d8d8ead 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1200,8 +1200,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, } /* Skip mgmt frames while we handle this in WMI */ - if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL || - attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { + if (attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); return false; } -- GitLab From 10ac1ce879eb36c108699d90ce2ebd95a8239d54 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:22 +0300 Subject: [PATCH 1132/9457] ath10k: remove unused variable The rx descriptor variable was no longer used in the rx handler. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 63c69d8d8ead..61ff2ac8496e 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1230,7 +1230,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct ath10k *ar = htt->ar; struct ieee80211_rx_status *rx_status = &htt->rx_status; struct htt_rx_indication_mpdu_range *mpdu_ranges; - struct htt_rx_desc *rxd; enum htt_rx_mpdu_status status; struct ieee80211_hdr *hdr; int num_mpdu_ranges; @@ -1301,10 +1300,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, continue; } - rxd = container_of((void *)msdu_head->data, - struct htt_rx_desc, - msdu_payload); - if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, status, channel_set, -- GitLab From 890d3b2a61323baedee314015351c7f15ced0c71 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:22 +0300 Subject: [PATCH 1133/9457] ath10k: use ieee80211 defines for crypto param lengths Use the globally defined ieee80211 values instead of re-defining them in the driver again. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 34 ++++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 61ff2ac8496e..ca466cedfb3e 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -588,41 +588,47 @@ static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar, enum htt_rx_mpdu_encrypt_type type) { switch (type) { + case HTT_RX_MPDU_ENCRYPT_NONE: + return 0; case HTT_RX_MPDU_ENCRYPT_WEP40: case HTT_RX_MPDU_ENCRYPT_WEP104: - return 4; + return IEEE80211_WEP_IV_LEN; case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC: - case HTT_RX_MPDU_ENCRYPT_WEP128: /* not tested */ case HTT_RX_MPDU_ENCRYPT_TKIP_WPA: - case HTT_RX_MPDU_ENCRYPT_WAPI: /* not tested */ + return IEEE80211_TKIP_IV_LEN; case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: - return 8; - case HTT_RX_MPDU_ENCRYPT_NONE: - return 0; + return IEEE80211_CCMP_HDR_LEN; + case HTT_RX_MPDU_ENCRYPT_WEP128: + case HTT_RX_MPDU_ENCRYPT_WAPI: + break; } - ath10k_warn(ar, "unknown encryption type %d\n", type); + ath10k_warn(ar, "unsupported encryption type %d\n", type); return 0; } +#define MICHAEL_MIC_LEN 8 + static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar, enum htt_rx_mpdu_encrypt_type type) { switch (type) { case HTT_RX_MPDU_ENCRYPT_NONE: + return 0; case HTT_RX_MPDU_ENCRYPT_WEP40: case HTT_RX_MPDU_ENCRYPT_WEP104: - case HTT_RX_MPDU_ENCRYPT_WEP128: - case HTT_RX_MPDU_ENCRYPT_WAPI: - return 0; + return IEEE80211_WEP_ICV_LEN; case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC: case HTT_RX_MPDU_ENCRYPT_TKIP_WPA: - return 4; + return IEEE80211_TKIP_ICV_LEN; case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: - return 8; + return IEEE80211_CCMP_MIC_LEN; + case HTT_RX_MPDU_ENCRYPT_WEP128: + case HTT_RX_MPDU_ENCRYPT_WAPI: + break; } - ath10k_warn(ar, "unknown encryption type %d\n", type); + ath10k_warn(ar, "unsupported encryption type %d\n", type); return 0; } @@ -1427,7 +1433,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, /* last fragment of TKIP frags has MIC */ if (!ieee80211_has_morefrags(hdr->frame_control) && enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) - trim += 8; + trim += MICHAEL_MIC_LEN; if (trim > msdu_head->len) { ath10k_warn(ar, "htt rx fragment: trailer longer than the frame itself? drop\n"); -- GitLab From 5f69caf793e996d4a84ba3ae38cc0e38c83d4470 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:23 +0300 Subject: [PATCH 1134/9457] ath10k: fix rx buffer tracing Tracing function was called before buffers were unmapped from DMA. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index ca466cedfb3e..a7d29c8718c3 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -291,9 +291,6 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) htt->rx_ring.sw_rd_idx.msdu_payld = idx; htt->rx_ring.fill_cnt--; - trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + - skb_tailroom(msdu)); - return msdu; } @@ -339,6 +336,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ", msdu->data, msdu->len + skb_tailroom(msdu)); + trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + + skb_tailroom(msdu)); rx_desc = (struct htt_rx_desc *)msdu->data; @@ -438,6 +437,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx chained: ", next->data, next->len + skb_tailroom(next)); + trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + + skb_tailroom(msdu)); skb_trim(next, 0); skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE)); -- GitLab From 4de028064fc4c70a72ac0efb0530bbe1923c2ce9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:23 +0300 Subject: [PATCH 1135/9457] ath10k: deduplicate htt rx dma unmapping Treat non-chained and chained popping the same way. Also this makes netbuf pop fully symmetrical to (re)filling. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 30 +++++++----------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index a7d29c8718c3..41a280387cf4 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -291,6 +291,15 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) htt->rx_ring.sw_rd_idx.msdu_payld = idx; htt->rx_ring.fill_cnt--; + dma_unmap_single(htt->ar->dev, + ATH10K_SKB_CB(msdu)->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ", + msdu->data, msdu->len + skb_tailroom(msdu)); + trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + + skb_tailroom(msdu)); + return msdu; } @@ -329,16 +338,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, while (msdu) { int last_msdu, msdu_len_invalid, msdu_chained; - dma_unmap_single(htt->ar->dev, - ATH10K_SKB_CB(msdu)->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ", - msdu->data, msdu->len + skb_tailroom(msdu)); - trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + - skb_tailroom(msdu)); - rx_desc = (struct htt_rx_desc *)msdu->data; /* FIXME: we must report msdu payload since this is what caller @@ -429,17 +428,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, while (msdu_chained--) { struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); - dma_unmap_single(htt->ar->dev, - ATH10K_SKB_CB(next)->paddr, - next->len + skb_tailroom(next), - DMA_FROM_DEVICE); - - ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, - "htt rx chained: ", next->data, - next->len + skb_tailroom(next)); - trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + - skb_tailroom(msdu)); - skb_trim(next, 0); skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE)); msdu_len -= next->len; -- GitLab From 34440df03d638cf31ca915a25537e1addecd7ddc Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:23 +0300 Subject: [PATCH 1136/9457] ath10k: don't drop frames aggressively There's little point in dropping, e.g. frames with FCS error early in ath10k. This simplifies amsdu_allowed() and gets rid of htt_rx_mpdu_status usage finally. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 41a280387cf4..7fa4d872f05c 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1171,7 +1171,6 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head) static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, struct sk_buff *head, - enum htt_rx_mpdu_status status, bool channel_set, u32 attention) { @@ -1200,16 +1199,6 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, return false; } - if (status != HTT_RX_IND_MPDU_STATUS_OK && - status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && - status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && - !htt->ar->monitor_started) { - ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt rx ignoring frame w/ status %d\n", - status); - return false; - } - if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx CAC running\n"); @@ -1225,7 +1214,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct ath10k *ar = htt->ar; struct ieee80211_rx_status *rx_status = &htt->rx_status; struct htt_rx_indication_mpdu_range *mpdu_ranges; - enum htt_rx_mpdu_status status; struct ieee80211_hdr *hdr; int num_mpdu_ranges; u32 attention; @@ -1273,8 +1261,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, num_mpdu_ranges)); for (i = 0; i < num_mpdu_ranges; i++) { - status = mpdu_ranges[i].mpdu_range_status; - for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { struct sk_buff *msdu_head, *msdu_tail; @@ -1296,7 +1282,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, } if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, - status, channel_set, attention)) { ath10k_htt_rx_free_msdu_chain(msdu_head); -- GitLab From b30595aea39d6946c1d17c3f278fb8d2fbe2a4cf Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:24 +0300 Subject: [PATCH 1137/9457] ath10k: add extra sanity check when popping amsdu The netbuf pop can return NULL. Make sure to check for that. It shouldn't happen but better safe than sorry. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 7fa4d872f05c..25bd286391d9 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -428,6 +428,15 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, while (msdu_chained--) { struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); + if (!next) { + ath10k_warn(ar, "failed to pop chained msdu\n"); + ath10k_htt_rx_free_msdu_chain(*head_msdu); + *head_msdu = NULL; + msdu = NULL; + htt->rx_confused = true; + break; + } + skb_trim(next, 0); skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE)); msdu_len -= next->len; -- GitLab From 686687c9afb43d396b32689f4dd29d1e87cebdf8 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:24 +0300 Subject: [PATCH 1138/9457] ath10k: don't forget to replenish after fragmented Rx In theory it was possible to drain entire HTT Rx ring via fragmented Rx leading to Rx lockup. In practice non-data traffic would always trigger replenishment via the regular Rx handler. For correctness sake make sure to replenish the ring on fragmented Rx. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 25bd286391d9..70e8090f9fac 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1355,6 +1355,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, &attention); spin_unlock_bh(&htt->rx_ring.lock); + tasklet_schedule(&htt->rx_replenish_task); + ath10k_dbg(ar, ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); if (ret) { -- GitLab From 51fc7d74ce4a1d92623e592eff14403872fb26bd Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:24 +0300 Subject: [PATCH 1139/9457] ath10k: clear htt->rx_confused on load Once driver entered the rx_confused state it would refuse to rx even after firmware is restarted. Make sure to clear it so that rx works after, e.g. hw restart or after all interfaces are stopped. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 70e8090f9fac..4fc4dbd2aaab 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -497,6 +497,8 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) size_t size; struct timer_list *timer = &htt->rx_ring.refill_retry_timer; + htt->rx_confused = false; + htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); if (!is_power_of_2(htt->rx_ring.size)) { ath10k_warn(ar, "htt rx ring size is not power of 2\n"); -- GitLab From b04e204fcae5a2c1e99e94f7e80f1e75fa95b938 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:27 +0300 Subject: [PATCH 1140/9457] ath10k: remove tsf argument from rx_desc tracing Fundamentally this was wrong. Tsf is only valid in last MPDU of a PPDU. This means tsf value was wrong most of the time during heavy traffic. Also I don't see much point in exposing a redundant (and broken) tsf value. Userspace can already read it from the dumped rx descriptor buffer. Cc: Rajkumar Manoharan Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 +--- drivers/net/wireless/ath/ath10k/trace.h | 9 +++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 4fc4dbd2aaab..a691fdf2fbae 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -325,7 +325,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, int msdu_len, msdu_chaining = 0; struct sk_buff *msdu, *next; struct htt_rx_desc *rx_desc; - u32 tsf; lockdep_assert_held(&htt->rx_ring.lock); @@ -449,8 +448,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & RX_MSDU_END_INFO0_LAST_MSDU; - tsf = __le32_to_cpu(rx_desc->ppdu_end.tsf_timestamp); - trace_ath10k_htt_rx_desc(ar, tsf, &rx_desc->attention, + trace_ath10k_htt_rx_desc(ar, &rx_desc->attention, sizeof(*rx_desc) - sizeof(u32)); if (last_msdu) { msdu->next = NULL; diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 9d34e7f6c455..2409cb54a32b 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -282,14 +282,13 @@ TRACE_EVENT(ath10k_htt_pktlog, ); TRACE_EVENT(ath10k_htt_rx_desc, - TP_PROTO(struct ath10k *ar, u32 tsf, void *rxdesc, u16 len), + TP_PROTO(struct ath10k *ar, void *rxdesc, u16 len), - TP_ARGS(ar, tsf, rxdesc, len), + TP_ARGS(ar, rxdesc, len), TP_STRUCT__entry( __string(device, dev_name(ar->dev)) __string(driver, dev_driver_string(ar->dev)) - __field(u32, tsf) __field(u16, len) __dynamic_array(u8, rxdesc, len) ), @@ -297,16 +296,14 @@ TRACE_EVENT(ath10k_htt_rx_desc, TP_fast_assign( __assign_str(device, dev_name(ar->dev)); __assign_str(driver, dev_driver_string(ar->dev)); - __entry->tsf = tsf; __entry->len = len; memcpy(__get_dynamic_array(rxdesc), rxdesc, len); ), TP_printk( - "%s %s %u len %hu", + "%s %s len %hu", __get_str(driver), __get_str(device), - __entry->tsf, __entry->len ) ); -- GitLab From a5d85f609de71c0d92c358cf96a91f00b3d8d657 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:28 +0300 Subject: [PATCH 1141/9457] ath10k: re-use trace class Instead of defining a completely new tracepoint use an existing tracepoint class. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/trace.h | 32 ++++--------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 2409cb54a32b..b9a2ba6bf6c0 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -281,33 +281,6 @@ TRACE_EVENT(ath10k_htt_pktlog, ) ); -TRACE_EVENT(ath10k_htt_rx_desc, - TP_PROTO(struct ath10k *ar, void *rxdesc, u16 len), - - TP_ARGS(ar, rxdesc, len), - - TP_STRUCT__entry( - __string(device, dev_name(ar->dev)) - __string(driver, dev_driver_string(ar->dev)) - __field(u16, len) - __dynamic_array(u8, rxdesc, len) - ), - - TP_fast_assign( - __assign_str(device, dev_name(ar->dev)); - __assign_str(driver, dev_driver_string(ar->dev)); - __entry->len = len; - memcpy(__get_dynamic_array(rxdesc), rxdesc, len); - ), - - TP_printk( - "%s %s len %hu", - __get_str(driver), - __get_str(device), - __entry->len - ) -); - TRACE_EVENT(ath10k_htt_tx, TP_PROTO(struct ath10k *ar, u16 msdu_id, u16 msdu_len, u8 vdev_id, u8 tid), @@ -414,6 +387,11 @@ DEFINE_EVENT(ath10k_data_event, ath10k_wmi_bcn_tx, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len) ); + +DEFINE_EVENT(ath10k_data_event, ath10k_htt_rx_desc, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + TP_ARGS(ar, data, len) +); #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ -- GitLab From fa1d4df84131afffc0e7aa02cea29ae76eb789a2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 23 Oct 2014 17:04:28 +0300 Subject: [PATCH 1142/9457] ath10k: add SURVEY_INFO_IN_USE for current channel on survey When user space requests survey info, it is useful to know which of the survey data refers to the channel that is currently actively being used. One of the use cases is getting the current channel noise for status output. Without this flag you would have to look up the channel separately and then compare it against the frequency in the survey output in user space. Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index caaa3690af69..1927adb0ef72 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4040,6 +4040,9 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx, survey->channel = &sband->channels[idx]; + if (ar->rx_channel == survey->channel) + survey->filled |= SURVEY_INFO_IN_USE; + exit: mutex_unlock(&ar->conf_mutex); return ret; -- GitLab From 56a0dee77ee3650e2e54a979f7392eec7a492f28 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 23 Oct 2014 17:04:29 +0300 Subject: [PATCH 1143/9457] ath10k: call correct function for frag threshold Rts threshold was being configured instead of fragmentation threshold. Keep in mind available firmware binaries don't seem to support fragmentation anyway so this doesn't fix fragmentation threshold per se. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1927adb0ef72..4f150ef84ea3 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3872,7 +3872,7 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n", arvif->vdev_id, value); - ret = ath10k_mac_set_rts(arvif, value); + ret = ath10k_mac_set_frag(arvif, value); if (ret) { ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n", arvif->vdev_id, ret); -- GitLab From cacc6c837b799b058d59d2af02c11140640cc1d2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Oct 2014 11:18:51 +0200 Subject: [PATCH 1144/9457] Revert "drm/i915: Enable full PPGTT on gen7" This reverts commit 8c50f10d73b50139dcfe48bc22f2c8c7822c1983. It's not yet solid and Dave objected to pulling the tree in its current state. Cc: Michel Thierry Cc: Dave Airlie Cc: Chris Wilson References: http://mid.mail-archive.com/CAPM=9ty2r1MLE=wzC-_vNSUzXVqAyXiGgocpSV9qOp0gzpK3xA@mail.gmail.com References: http://lists.freedesktop.org/archives/intel-gfx/2014-October/053926.html Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 273dad964e1b..8ddc834f722f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -67,7 +67,7 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) return 0; } - return has_full_ppgtt ? 2 : has_aliasing_ppgtt ? 1 : 0; + return has_aliasing_ppgtt ? 1 : 0; } -- GitLab From 47339cd9ff07376df1639260ecc088adf1856bfe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:46 +0200 Subject: [PATCH 1145/9457] drm/i915: Extract intel_fifo_underrun.c Prep work for some nice documentation. Requires that we export the display irq enable/disable functions on ilk/ibx. But we already export them for vlv/i915. So not more inconsistency. v2: Rebase on top of skl stage 1. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/i915_irq.c | 297 +------------------- drivers/gpu/drm/i915/intel_drv.h | 8 +- drivers/gpu/drm/i915/intel_fifo_underrun.c | 311 +++++++++++++++++++++ 5 files changed, 334 insertions(+), 294 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_fifo_underrun.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 3a6bce047f6f..75fd7de9bf4b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -45,6 +45,7 @@ i915-y += intel_renderstate_gen6.o \ # modesetting core code i915-y += intel_bios.o \ intel_display.o \ + intel_fifo_underrun.o \ intel_frontbuffer.o \ intel_modes.o \ intel_overlay.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9962da202456..26724c54bd80 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2312,6 +2312,17 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv); void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv); +void +ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask); +void +ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask); +void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + uint32_t interrupt_mask, + uint32_t enabled_irq_mask); +#define ibx_enable_display_interrupt(dev_priv, bits) \ + ibx_display_interrupt_update((dev_priv), (bits), (bits)) +#define ibx_disable_display_interrupt(dev_priv, bits) \ + ibx_display_interrupt_update((dev_priv), (bits), 0) /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f17bbf3ac136..536efa277b01 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -139,7 +139,7 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ } while (0) /* For display hotplug interrupt */ -static void +void ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(&dev_priv->irq_lock); @@ -154,7 +154,7 @@ ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) } } -static void +void ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(&dev_priv->irq_lock); @@ -238,24 +238,6 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) snb_update_pm_irq(dev_priv, mask, 0); } -static bool ivb_can_enable_err_int(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *crtc; - enum pipe pipe; - - assert_spin_locked(&dev_priv->irq_lock); - - for_each_pipe(dev_priv, pipe) { - crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); - - if (crtc->cpu_fifo_underrun_disabled) - return false; - } - - return true; -} - /** * bdw_update_pm_irq - update GT interrupt 2 * @dev_priv: driver private @@ -296,130 +278,15 @@ void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) bdw_update_pm_irq(dev_priv, mask, 0); } -static bool cpt_can_enable_serr_int(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - enum pipe pipe; - struct intel_crtc *crtc; - - assert_spin_locked(&dev_priv->irq_lock); - - for_each_pipe(dev_priv, pipe) { - crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); - - if (crtc->pch_fifo_underrun_disabled) - return false; - } - - return true; -} - -void i9xx_check_fifo_underruns(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *crtc; - - spin_lock_irq(&dev_priv->irq_lock); - - for_each_intel_crtc(dev, crtc) { - u32 reg = PIPESTAT(crtc->pipe); - u32 pipestat; - - if (crtc->cpu_fifo_underrun_disabled) - continue; - - pipestat = I915_READ(reg) & 0xffff0000; - if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) - continue; - - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); - POSTING_READ(reg); - - DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); - } - - spin_unlock_irq(&dev_priv->irq_lock); -} - -static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, - bool enable, bool old) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 reg = PIPESTAT(pipe); - u32 pipestat = I915_READ(reg) & 0xffff0000; - - assert_spin_locked(&dev_priv->irq_lock); - - if (enable) { - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); - POSTING_READ(reg); - } else { - if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS) - DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); - } -} - -static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : - DE_PIPEB_FIFO_UNDERRUN; - - if (enable) - ironlake_enable_display_irq(dev_priv, bit); - else - ironlake_disable_display_irq(dev_priv, bit); -} - -static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, - bool enable, bool old) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - if (enable) { - I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); - - if (!ivb_can_enable_err_int(dev)) - return; - - ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); - } else { - ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); - - if (old && - I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { - DRM_ERROR("uncleared fifo underrun on pipe %c\n", - pipe_name(pipe)); - } - } -} - -static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - assert_spin_locked(&dev_priv->irq_lock); - - if (enable) - dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_FIFO_UNDERRUN; - else - dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_FIFO_UNDERRUN; - I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); - POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); -} - /** * ibx_display_interrupt_update - update SDEIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, - uint32_t interrupt_mask, - uint32_t enabled_irq_mask) +void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + uint32_t interrupt_mask, + uint32_t enabled_irq_mask) { uint32_t sdeimr = I915_READ(SDEIMR); sdeimr &= ~interrupt_mask; @@ -433,160 +300,6 @@ static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, I915_WRITE(SDEIMR, sdeimr); POSTING_READ(SDEIMR); } -#define ibx_enable_display_interrupt(dev_priv, bits) \ - ibx_display_interrupt_update((dev_priv), (bits), (bits)) -#define ibx_disable_display_interrupt(dev_priv, bits) \ - ibx_display_interrupt_update((dev_priv), (bits), 0) - -static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, - enum transcoder pch_transcoder, - bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t bit = (pch_transcoder == TRANSCODER_A) ? - SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; - - if (enable) - ibx_enable_display_interrupt(dev_priv, bit); - else - ibx_disable_display_interrupt(dev_priv, bit); -} - -static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, - enum transcoder pch_transcoder, - bool enable, bool old) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (enable) { - I915_WRITE(SERR_INT, - SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); - - if (!cpt_can_enable_serr_int(dev)) - return; - - ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); - } else { - ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); - - if (old && I915_READ(SERR_INT) & - SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { - DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", - transcoder_name(pch_transcoder)); - } - } -} - -/** - * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages - * @dev: drm device - * @pipe: pipe - * @enable: true if we want to report FIFO underrun errors, false otherwise - * - * This function makes us disable or enable CPU fifo underruns for a specific - * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun - * reporting for one pipe may also disable all the other CPU error interruts for - * the other pipes, due to the fact that there's just one interrupt mask/enable - * bit for all the pipes. - * - * Returns the previous state of underrun reporting. - */ -static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - bool old; - - assert_spin_locked(&dev_priv->irq_lock); - - old = !intel_crtc->cpu_fifo_underrun_disabled; - intel_crtc->cpu_fifo_underrun_disabled = !enable; - - if (HAS_GMCH_DISPLAY(dev)) - i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (IS_GEN5(dev) || IS_GEN6(dev)) - ironlake_set_fifo_underrun_reporting(dev, pipe, enable); - else if (IS_GEN7(dev)) - ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old); - else if (IS_GEN8(dev) || IS_GEN9(dev)) - broadwell_set_fifo_underrun_reporting(dev, pipe, enable); - - return old; -} - -bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, - enum pipe pipe, bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long flags; - bool ret; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - ret = __intel_set_cpu_fifo_underrun_reporting(dev, pipe, enable); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return ret; -} - -static bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, - enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - return !intel_crtc->cpu_fifo_underrun_disabled; -} - -/** - * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages - * @dev: drm device - * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) - * @enable: true if we want to report FIFO underrun errors, false otherwise - * - * This function makes us disable or enable PCH fifo underruns for a specific - * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO - * underrun reporting for one transcoder may also disable all the other PCH - * error interruts for the other transcoders, due to the fact that there's just - * one interrupt mask/enable bit for all the transcoders. - * - * Returns the previous state of underrun reporting. - */ -bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, - enum transcoder pch_transcoder, - bool enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long flags; - bool old; - - /* - * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT - * has only one pch transcoder A that all pipes can use. To avoid racy - * pch transcoder -> pipe lookups from interrupt code simply store the - * underrun statistics in crtc A. Since we never expose this anywhere - * nor use it outside of the fifo underrun code here using the "wrong" - * crtc on LPT won't cause issues. - */ - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - - old = !intel_crtc->pch_fifo_underrun_disabled; - intel_crtc->pch_fifo_underrun_disabled = !enable; - - if (HAS_PCH_IBX(dev)) - ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); - else - cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable, old); - - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - return old; -} - static void __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 94993d23e547..321701da12ec 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -755,12 +755,17 @@ static inline unsigned int intel_num_planes(struct intel_crtc *crtc) return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1; } -/* i915_irq.c */ +/* intel_fifo_underrun.c */ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable); bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, enum transcoder pch_transcoder, bool enable); +void i9xx_check_fifo_underruns(struct drm_device *dev); +bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, + enum pipe pipe); + +/* i915_irq.c */ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); @@ -779,7 +784,6 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) } int intel_get_crtc_scanline(struct intel_crtc *crtc); -void i9xx_check_fifo_underruns(struct drm_device *dev); void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv); /* intel_crt.c */ diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c new file mode 100644 index 000000000000..8e79d2ba787d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -0,0 +1,311 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Daniel Vetter + * + */ + +#include "i915_drv.h" +#include "intel_drv.h" + +static bool ivb_can_enable_err_int(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc; + enum pipe pipe; + + assert_spin_locked(&dev_priv->irq_lock); + + for_each_pipe(dev_priv, pipe) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + + if (crtc->cpu_fifo_underrun_disabled) + return false; + } + + return true; +} + +static bool cpt_can_enable_serr_int(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe; + struct intel_crtc *crtc; + + assert_spin_locked(&dev_priv->irq_lock); + + for_each_pipe(dev_priv, pipe) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + + if (crtc->pch_fifo_underrun_disabled) + return false; + } + + return true; +} + +void i9xx_check_fifo_underruns(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc; + + spin_lock_irq(&dev_priv->irq_lock); + + for_each_intel_crtc(dev, crtc) { + u32 reg = PIPESTAT(crtc->pipe); + u32 pipestat; + + if (crtc->cpu_fifo_underrun_disabled) + continue; + + pipestat = I915_READ(reg) & 0xffff0000; + if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) + continue; + + I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); + POSTING_READ(reg); + + DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); + } + + spin_unlock_irq(&dev_priv->irq_lock); +} + +static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, + bool enable, bool old) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 reg = PIPESTAT(pipe); + u32 pipestat = I915_READ(reg) & 0xffff0000; + + assert_spin_locked(&dev_priv->irq_lock); + + if (enable) { + I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); + POSTING_READ(reg); + } else { + if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS) + DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); + } +} + +static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : + DE_PIPEB_FIFO_UNDERRUN; + + if (enable) + ironlake_enable_display_irq(dev_priv, bit); + else + ironlake_disable_display_irq(dev_priv, bit); +} + +static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, + bool enable, bool old) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + if (enable) { + I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); + + if (!ivb_can_enable_err_int(dev)) + return; + + ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); + } else { + ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); + + if (old && + I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { + DRM_ERROR("uncleared fifo underrun on pipe %c\n", + pipe_name(pipe)); + } + } +} + +static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + assert_spin_locked(&dev_priv->irq_lock); + + if (enable) + dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_FIFO_UNDERRUN; + else + dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_FIFO_UNDERRUN; + I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); + POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); +} + +static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, + enum transcoder pch_transcoder, + bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t bit = (pch_transcoder == TRANSCODER_A) ? + SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; + + if (enable) + ibx_enable_display_interrupt(dev_priv, bit); + else + ibx_disable_display_interrupt(dev_priv, bit); +} + +static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, + enum transcoder pch_transcoder, + bool enable, bool old) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (enable) { + I915_WRITE(SERR_INT, + SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); + + if (!cpt_can_enable_serr_int(dev)) + return; + + ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); + } else { + ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); + + if (old && I915_READ(SERR_INT) & + SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { + DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", + transcoder_name(pch_transcoder)); + } + } +} + +/** + * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages + * @dev: drm device + * @pipe: pipe + * @enable: true if we want to report FIFO underrun errors, false otherwise + * + * This function makes us disable or enable CPU fifo underruns for a specific + * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun + * reporting for one pipe may also disable all the other CPU error interruts for + * the other pipes, due to the fact that there's just one interrupt mask/enable + * bit for all the pipes. + * + * Returns the previous state of underrun reporting. + */ +static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + bool old; + + assert_spin_locked(&dev_priv->irq_lock); + + old = !intel_crtc->cpu_fifo_underrun_disabled; + intel_crtc->cpu_fifo_underrun_disabled = !enable; + + if (HAS_GMCH_DISPLAY(dev)) + i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); + else if (IS_GEN5(dev) || IS_GEN6(dev)) + ironlake_set_fifo_underrun_reporting(dev, pipe, enable); + else if (IS_GEN7(dev)) + ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old); + else if (IS_GEN8(dev) || IS_GEN9(dev)) + broadwell_set_fifo_underrun_reporting(dev, pipe, enable); + + return old; +} + +bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, + enum pipe pipe, bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + bool ret; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + ret = __intel_set_cpu_fifo_underrun_reporting(dev, pipe, enable); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + + return ret; +} + +bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, + enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + return !intel_crtc->cpu_fifo_underrun_disabled; +} + +/** + * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages + * @dev: drm device + * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) + * @enable: true if we want to report FIFO underrun errors, false otherwise + * + * This function makes us disable or enable PCH fifo underruns for a specific + * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO + * underrun reporting for one transcoder may also disable all the other PCH + * error interruts for the other transcoders, due to the fact that there's just + * one interrupt mask/enable bit for all the transcoders. + * + * Returns the previous state of underrun reporting. + */ +bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + enum transcoder pch_transcoder, + bool enable) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + unsigned long flags; + bool old; + + /* + * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT + * has only one pch transcoder A that all pipes can use. To avoid racy + * pch transcoder -> pipe lookups from interrupt code simply store the + * underrun statistics in crtc A. Since we never expose this anywhere + * nor use it outside of the fifo underrun code here using the "wrong" + * crtc on LPT won't cause issues. + */ + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + + old = !intel_crtc->pch_fifo_underrun_disabled; + intel_crtc->pch_fifo_underrun_disabled = !enable; + + if (HAS_PCH_IBX(dev)) + ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); + else + cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable, old); + + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + return old; +} -- GitLab From a72e4c9f9a11d44458a12928cc776921ae43a616 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:47 +0200 Subject: [PATCH 1146/9457] drm/i915: Use dev_priv in public intel_fifo_underrun.c functions It's the new rule! Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 35 ++++++++++++++-------- drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++---------- drivers/gpu/drm/i915/intel_drv.h | 8 ++--- drivers/gpu/drm/i915/intel_fifo_underrun.c | 25 ++++++++-------- 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 536efa277b01..3ee8c4756adb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1750,7 +1750,7 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) * handle. */ mask = 0; - if (__cpu_fifo_underrun_reporting_enabled(dev, pipe)) + if (__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe)) mask |= PIPE_FIFO_UNDERRUN_STATUS; switch (pipe) { @@ -1797,7 +1797,8 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) i9xx_pipe_crc_irq_handler(dev, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, + false)) DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); } @@ -1965,12 +1966,14 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) - if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, + if (intel_set_pch_fifo_underrun_reporting(dev_priv, + TRANSCODER_A, false)) DRM_ERROR("PCH transcoder A FIFO underrun\n"); if (pch_iir & SDE_TRANSB_FIFO_UNDER) - if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, + if (intel_set_pch_fifo_underrun_reporting(dev_priv, + TRANSCODER_B, false)) DRM_ERROR("PCH transcoder B FIFO underrun\n"); } @@ -1986,7 +1989,7 @@ static void ivb_err_int_handler(struct drm_device *dev) for_each_pipe(dev_priv, pipe) { if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) { - if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, + if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) DRM_ERROR("Pipe %c FIFO underrun\n", pipe_name(pipe)); @@ -2012,17 +2015,17 @@ static void cpt_serr_int_handler(struct drm_device *dev) DRM_ERROR("PCH poison interrupt\n"); if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, + if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, false)) DRM_ERROR("PCH transcoder A FIFO underrun\n"); if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, + if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_B, false)) DRM_ERROR("PCH transcoder B FIFO underrun\n"); if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_C, + if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_C, false)) DRM_ERROR("PCH transcoder C FIFO underrun\n"); @@ -2090,7 +2093,9 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) intel_check_page_flip(dev, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) - if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) + if (intel_set_cpu_fifo_underrun_reporting(dev_priv, + pipe, + false)) DRM_ERROR("Pipe %c FIFO underrun\n", pipe_name(pipe)); @@ -2312,7 +2317,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) hsw_pipe_crc_irq_handler(dev, pipe); if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) { - if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, + if (intel_set_cpu_fifo_underrun_reporting(dev_priv, + pipe, false)) DRM_ERROR("Pipe %c FIFO underrun\n", pipe_name(pipe)); @@ -3834,7 +3840,8 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) i9xx_pipe_crc_irq_handler(dev, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) + intel_set_cpu_fifo_underrun_reporting(dev_priv, + pipe, false)) DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); } @@ -4028,7 +4035,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) i9xx_pipe_crc_irq_handler(dev, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) + intel_set_cpu_fifo_underrun_reporting(dev_priv, + pipe, false)) DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); } @@ -4256,7 +4264,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) i9xx_pipe_crc_irq_handler(dev, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) + intel_set_cpu_fifo_underrun_reporting(dev_priv, + pipe, false)) DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1fc05ffc4695..ee8156cf6f61 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4163,8 +4163,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) intel_crtc->active = true; - intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); - intel_set_pch_fifo_underrun_reporting(dev, pipe, true); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); for_each_encoder_on_crtc(dev, crtc, encoder) if (encoder->pre_enable) @@ -4278,13 +4278,14 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_crtc->active = true; - intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); for_each_encoder_on_crtc(dev, crtc, encoder) if (encoder->pre_enable) encoder->pre_enable(encoder); if (intel_crtc->config.has_pch_encoder) { - intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, + true); dev_priv->display.fdi_link_train(crtc); } @@ -4360,7 +4361,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) encoder->disable(encoder); if (intel_crtc->config.has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev, pipe, false); + intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false); intel_disable_pipe(intel_crtc); @@ -4374,7 +4375,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) ironlake_fdi_disable(crtc); ironlake_disable_pch_transcoder(dev_priv, pipe); - intel_set_pch_fifo_underrun_reporting(dev, pipe, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); if (HAS_PCH_CPT(dev)) { /* disable TRANS_DP_CTL */ @@ -4427,7 +4428,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) } if (intel_crtc->config.has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); + intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, + false); intel_disable_pipe(intel_crtc); if (intel_crtc->config.dp_encoder_is_mst) @@ -4441,7 +4443,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) if (intel_crtc->config.has_pch_encoder) { lpt_disable_pch_transcoder(dev_priv); - intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, + true); intel_ddi_fdi_disable(crtc); } @@ -4818,6 +4821,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev) static void valleyview_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -4846,7 +4850,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_crtc->active = true; - intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); for_each_encoder_on_crtc(dev, crtc, encoder) if (encoder->pre_pll_enable) @@ -4879,7 +4883,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_crtc_enable_planes(crtc); /* Underruns don't raise interrupts, so check manually. */ - i9xx_check_fifo_underruns(dev); + i9xx_check_fifo_underruns(dev_priv); } static void i9xx_set_pll_dividers(struct intel_crtc *crtc) @@ -4894,6 +4898,7 @@ static void i9xx_set_pll_dividers(struct intel_crtc *crtc) static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -4915,7 +4920,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_crtc->active = true; if (!IS_GEN2(dev)) - intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); for_each_encoder_on_crtc(dev, crtc, encoder) if (encoder->pre_enable) @@ -4946,10 +4951,10 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) * but leave the pipe running. */ if (IS_GEN2(dev)) - intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); /* Underruns don't raise interrupts, so check manually. */ - i9xx_check_fifo_underruns(dev); + i9xx_check_fifo_underruns(dev_priv); } static void i9xx_pfit_disable(struct intel_crtc *crtc) @@ -4985,7 +4990,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) * but leave the pipe running. */ if (IS_GEN2(dev)) - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); /* * Vblank time updates from the shadow to live plane control register @@ -5031,7 +5036,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) } if (!IS_GEN2(dev)) - intel_set_cpu_fifo_underrun_reporting(dev, pipe, false); + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); intel_crtc->active = false; intel_update_watermarks(crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 321701da12ec..ede96065235d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -756,13 +756,13 @@ static inline unsigned int intel_num_planes(struct intel_crtc *crtc) } /* intel_fifo_underrun.c */ -bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, +bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable); -bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, +bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum transcoder pch_transcoder, bool enable); -void i9xx_check_fifo_underruns(struct drm_device *dev); -bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, +void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv); +bool __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, enum pipe pipe); /* i915_irq.c */ diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 8e79d2ba787d..0604a112a4ad 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -64,14 +64,13 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) return true; } -void i9xx_check_fifo_underruns(struct drm_device *dev) +void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *crtc; spin_lock_irq(&dev_priv->irq_lock); - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(dev_priv->dev, crtc) { u32 reg = PIPESTAT(crtc->pipe); u32 pipestat; @@ -239,24 +238,23 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, return old; } -bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, +bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; unsigned long flags; bool ret; spin_lock_irqsave(&dev_priv->irq_lock, flags); - ret = __intel_set_cpu_fifo_underrun_reporting(dev, pipe, enable); + ret = __intel_set_cpu_fifo_underrun_reporting(dev_priv->dev, pipe, + enable); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return ret; } -bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, +bool __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -277,11 +275,10 @@ bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, * * Returns the previous state of underrun reporting. */ -bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, +bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum transcoder pch_transcoder, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); unsigned long flags; @@ -301,10 +298,12 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, old = !intel_crtc->pch_fifo_underrun_disabled; intel_crtc->pch_fifo_underrun_disabled = !enable; - if (HAS_PCH_IBX(dev)) - ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); + if (HAS_PCH_IBX(dev_priv->dev)) + ibx_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder, + enable); else - cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable, old); + cpt_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder, + enable, old); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return old; -- GitLab From 1f7247c01c9d1bdc7b0e239a8f2e256972b9189b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:48 +0200 Subject: [PATCH 1147/9457] drm/i915: Add wrappers to handle fifo underrun interrupts Way too much copypasta all over. And this also clarifies a bit what's going on since it separates the "do we have an underrun irq" from the "should we report the underrun" check. v2: Fix excessively long lines. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 72 +++++++--------------- drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_fifo_underrun.c | 17 +++++ 3 files changed, 42 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3ee8c4756adb..1db9fb567359 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1796,10 +1796,8 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev, pipe); - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, - false)) - DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) @@ -1966,16 +1964,10 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) - if (intel_set_pch_fifo_underrun_reporting(dev_priv, - TRANSCODER_A, - false)) - DRM_ERROR("PCH transcoder A FIFO underrun\n"); + intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A); if (pch_iir & SDE_TRANSB_FIFO_UNDER) - if (intel_set_pch_fifo_underrun_reporting(dev_priv, - TRANSCODER_B, - false)) - DRM_ERROR("PCH transcoder B FIFO underrun\n"); + intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B); } static void ivb_err_int_handler(struct drm_device *dev) @@ -1988,12 +1980,8 @@ static void ivb_err_int_handler(struct drm_device *dev) DRM_ERROR("Poison interrupt\n"); for_each_pipe(dev_priv, pipe) { - if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) { - if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, - false)) - DRM_ERROR("Pipe %c FIFO underrun\n", - pipe_name(pipe)); - } + if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) { if (IS_IVYBRIDGE(dev)) @@ -2015,19 +2003,13 @@ static void cpt_serr_int_handler(struct drm_device *dev) DRM_ERROR("PCH poison interrupt\n"); if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, - false)) - DRM_ERROR("PCH transcoder A FIFO underrun\n"); + intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A); if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_B, - false)) - DRM_ERROR("PCH transcoder B FIFO underrun\n"); + intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B); if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) - if (intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_C, - false)) - DRM_ERROR("PCH transcoder C FIFO underrun\n"); + intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_C); I915_WRITE(SERR_INT, serr_int); } @@ -2093,11 +2075,7 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) intel_check_page_flip(dev, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) - if (intel_set_cpu_fifo_underrun_reporting(dev_priv, - pipe, - false)) - DRM_ERROR("Pipe %c FIFO underrun\n", - pipe_name(pipe)); + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); if (de_iir & DE_PIPE_CRC_DONE(pipe)) i9xx_pipe_crc_irq_handler(dev, pipe); @@ -2316,13 +2294,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) hsw_pipe_crc_irq_handler(dev, pipe); - if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) { - if (intel_set_cpu_fifo_underrun_reporting(dev_priv, - pipe, - false)) - DRM_ERROR("Pipe %c FIFO underrun\n", - pipe_name(pipe)); - } + if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) + intel_cpu_fifo_underrun_irq_handler(dev_priv, + pipe); if (IS_GEN9(dev)) @@ -3839,10 +3813,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev, pipe); - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev_priv, - pipe, false)) - DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, + pipe); } iir = new_iir; @@ -4034,10 +4007,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev, pipe); - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev_priv, - pipe, false)) - DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, + pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) @@ -4263,10 +4235,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) i9xx_pipe_crc_irq_handler(dev, pipe); - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && - intel_set_cpu_fifo_underrun_reporting(dev_priv, - pipe, false)) - DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); + if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); } if (blc_event || (iir & I915_ASLE_INTERRUPT)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ede96065235d..4ffbe4e5f822 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -761,6 +761,10 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum transcoder pch_transcoder, bool enable); +void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, + enum pipe pipe); +void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, + enum transcoder pch_transcoder); void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv); bool __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, enum pipe pipe); diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 0604a112a4ad..5d66b933a097 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -308,3 +308,20 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, spin_unlock_irqrestore(&dev_priv->irq_lock, flags); return old; } + +void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) + DRM_ERROR("CPU pipe %c FIFO underrun\n", + pipe_name(pipe)); +} + +void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, + enum transcoder pch_transcoder) +{ + if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, + false)) + DRM_ERROR("PCH transcoder %c FIFO underrun\n", + transcoder_name(pch_transcoder)); +} -- GitLab From 0f239f4cb1dbbe259b7a29fed1e2ff8a50591319 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:49 +0200 Subject: [PATCH 1148/9457] drm/i915: Filter gmch fifo underruns in the shared handler This simplifies the code in the vlv irq handler. Also this now means that we correctly filter underruns on gen2-4. And as the real upshot I need to document one less function for the fifo underrun code. v2: Shorten one long line. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 6 +++--- drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_fifo_underrun.c | 10 ++++++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1db9fb567359..a2b013d97fb6 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1749,9 +1749,9 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) * we need to be careful that we only handle what we want to * handle. */ - mask = 0; - if (__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe)) - mask |= PIPE_FIFO_UNDERRUN_STATUS; + + /* fifo underruns are filterered in the underrun handler. */ + mask = PIPE_FIFO_UNDERRUN_STATUS; switch (pipe) { case PIPE_A: diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4ffbe4e5f822..5ab813c6091e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -766,8 +766,6 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum transcoder pch_transcoder); void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv); -bool __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe); /* i915_irq.c */ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 5d66b933a097..8622ab107590 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -252,8 +252,9 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, return ret; } -bool __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe) +static bool +__cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, + enum pipe pipe) { struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -312,6 +313,11 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { + /* GMCH can't disable fifo underruns, filter them. */ + if (HAS_GMCH_DISPLAY(dev_priv->dev) && + !__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe)) + return; + if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) DRM_ERROR("CPU pipe %c FIFO underrun\n", pipe_name(pipe)); -- GitLab From ef07388e8832394f92f124e4069014d5b33cb39e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 30 Sep 2014 10:56:50 +0200 Subject: [PATCH 1149/9457] drm/i915: kerneldoc for intel_fifo_underrun.c v2: Fix spelling fail. Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 5 ++ drivers/gpu/drm/i915/intel_fifo_underrun.c | 82 +++++++++++++++++----- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d7cfc98be159..f6a9d7b21380 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3829,6 +3829,11 @@ int num_ioctls; !Idrivers/gpu/drm/i915/intel_frontbuffer.c !Fdrivers/gpu/drm/i915/intel_drv.h intel_frontbuffer_flip !Fdrivers/gpu/drm/i915/i915_gem.c i915_gem_track_fb + + + Display FIFO Underrun Reporting +!Pdrivers/gpu/drm/i915/intel_fifo_underrun.c fifo underrun handling +!Idrivers/gpu/drm/i915/intel_fifo_underrun.c Plane Configuration diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 8622ab107590..77af512d2d35 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -28,6 +28,26 @@ #include "i915_drv.h" #include "intel_drv.h" +/** + * DOC: fifo underrun handling + * + * The i915 driver checks for display fifo underruns using the interrupt signals + * provided by the hardware. This is enabled by default and fairly useful to + * debug display issues, especially watermark settings. + * + * If an underrun is detected this is logged into dmesg. To avoid flooding logs + * and occupying the cpu underrun interrupts are disabled after the first + * occurrence until the next modeset on a given pipe. + * + * Note that underrun detection on gmch platforms is a bit more ugly since there + * is no interrupt (despite that the signalling bit is in the PIPESTAT pipe + * interrupt register). Also on some other platforms underrun interrupts are + * shared, which means that if we detect an underrun we need to disable underrun + * reporting on all pipes. + * + * The code also supports underrun detection on the PCH transcoder. + */ + static bool ivb_can_enable_err_int(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -64,6 +84,14 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) return true; } +/** + * i9xx_check_fifo_underruns - check for fifo underruns + * @dev_priv: i915 device instance + * + * This function checks for fifo underruns on GMCH platforms. This needs to be + * done manually on modeset to make sure that we catch all underruns since they + * do not generate an interrupt by themselves on these platforms. + */ void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv) { struct intel_crtc *crtc; @@ -199,20 +227,6 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, } } -/** - * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages - * @dev: drm device - * @pipe: pipe - * @enable: true if we want to report FIFO underrun errors, false otherwise - * - * This function makes us disable or enable CPU fifo underruns for a specific - * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun - * reporting for one pipe may also disable all the other CPU error interruts for - * the other pipes, due to the fact that there's just one interrupt mask/enable - * bit for all the pipes. - * - * Returns the previous state of underrun reporting. - */ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { @@ -238,6 +252,22 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, return old; } +/** + * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state + * @dev_priv: i915 device instance + * @pipe: (CPU) pipe to set state for + * @enable: whether underruns should be reported or not + * + * This function sets the fifo underrun state for @pipe. It is used in the + * modeset code to avoid false positives since on many platforms underruns are + * expected when disabling or enabling the pipe. + * + * Notice that on some platforms disabling underrun reports for one pipe + * disables for all due to shared interrupts. Actual reporting is still per-pipe + * though. + * + * Returns the previous state of underrun reporting. + */ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) { @@ -263,10 +293,10 @@ __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, } /** - * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages - * @dev: drm device + * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state + * @dev_priv: i915 device instance * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) - * @enable: true if we want to report FIFO underrun errors, false otherwise + * @enable: whether underruns should be reported or not * * This function makes us disable or enable PCH fifo underruns for a specific * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO @@ -310,6 +340,15 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, return old; } +/** + * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt + * @dev_priv: i915 device instance + * @pipe: (CPU) pipe to set state for + * + * This handles a CPU fifo underrun interrupt, generating an underrun warning + * into dmesg if underrun reporting is enabled and then disables the underrun + * interrupt to avoid an irq storm. + */ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -323,6 +362,15 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, pipe_name(pipe)); } +/** + * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt + * @dev_priv: i915 device instance + * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) + * + * This handles a PCH fifo underrun interrupt, generating an underrun warning + * into dmesg if underrun reporting is enabled and then disables the underrun + * interrupt to avoid an irq storm. + */ void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, enum transcoder pch_transcoder) { -- GitLab From bcef6d5aa5746e6d3955f2dbc8e00d58d2c8adbd Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:13 +0100 Subject: [PATCH 1150/9457] drm/i915: Use IS_HSW_ULT() in a HSW specific code path No need to add the BDW pci ULT/ULX checks inside a if (IS_HASWELL(dev)) code path. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bd7978cb094f..02cee518c113 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -463,7 +463,7 @@ void intel_detect_pch(struct drm_device *dev) dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint PCH\n"); WARN_ON(!IS_HASWELL(dev)); - WARN_ON(IS_ULT(dev)); + WARN_ON(IS_HSW_ULT(dev)); } else if (IS_BROADWELL(dev)) { dev_priv->pch_type = PCH_LPT; dev_priv->pch_id = @@ -474,7 +474,7 @@ void intel_detect_pch(struct drm_device *dev) dev_priv->pch_type = PCH_LPT; DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); WARN_ON(!IS_HASWELL(dev)); - WARN_ON(!IS_ULT(dev)); + WARN_ON(!IS_HSW_ULT(dev)); } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); -- GitLab From dbf7786efabec4d1256cc0c049d1f7d7cccfd8bf Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:14 +0100 Subject: [PATCH 1151/9457] drm/i915: Use IS_HSW_ULT() in HAS_IPS() HAS_IPS() has a '|| IS_BROADWELL()', no need to check for IS_BDW_ULT(). Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 26724c54bd80..b3e4c2c50eb5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2178,7 +2178,7 @@ struct drm_i915_cmd_table { #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) #define HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) -#define HAS_IPS(dev) (IS_ULT(dev) || IS_BROADWELL(dev)) +#define HAS_IPS(dev) (IS_HSW_ULT(dev) || IS_BROADWELL(dev)) #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) -- GitLab From cf404ce4b1de77017208e73c91cd6f09524678b7 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:15 +0100 Subject: [PATCH 1152/9457] drm/i915: Spell out IS_HSW/BDW_ULT() in intel_crt_present() The quality of being a ULT or ULX package doesn't tell anything across generations and so a global IS_ULT() macro doesn't make much sense, esp. as we're adding new products. So, spell out which ULT/ULX SKUs we are talking about here, namely HSW and BDW. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee8156cf6f61..1fff5b20f2a0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12162,7 +12162,7 @@ static bool intel_crt_present(struct drm_device *dev) if (INTEL_INFO(dev)->gen >= 9) return false; - if (IS_ULT(dev)) + if (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) return false; if (IS_CHERRYVIEW(dev)) -- GitLab From 95626e7caac4f0dbe285c59d9702b9f55af497eb Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:16 +0100 Subject: [PATCH 1153/9457] drm/i915: Use IS_HSW_ULT() in HSW CDCLK clock read-out hsw_get_cdclk_freq() is really just HSW, so we can use IS_HSW_ULT() instead of IS_ULT() there. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a151de7d13cd..cb5367c6f95a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1291,7 +1291,7 @@ static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv) return 450000; else if (freq == LCPLL_CLK_FREQ_450) return 450000; - else if (IS_ULT(dev)) + else if (IS_HSW_ULT(dev)) return 337500; else return 540000; -- GitLab From fa4dca2cce89ce8dc95f6dde58b3791feadc4283 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:17 +0100 Subject: [PATCH 1154/9457] drm/i915/skl: Don't check for ULT/ULX when detecting the PCH IS_ULT() wasn't taking into account SKL so we had a warn with SPT-LP. We don't realy need those checks here, and as we don't need to introduce IS_SKL_ULT/ULX() at the moment, let's just drop them. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 02cee518c113..a05a1d083e95 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -479,12 +479,10 @@ void intel_detect_pch(struct drm_device *dev) dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); WARN_ON(!IS_SKYLAKE(dev)); - WARN_ON(IS_ULT(dev)); } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { dev_priv->pch_type = PCH_SPT; DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); WARN_ON(!IS_SKYLAKE(dev)); - WARN_ON(!IS_ULT(dev)); } else continue; -- GitLab From d68a08af3d112064b35c5d6eaa582379c5057fa8 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 1 Oct 2014 20:04:18 +0100 Subject: [PATCH 1155/9457] drm/i915: Remove IS_ULT() As stated in the few previous commits, IS_ULT/ULX() is better per-platform as it has different consequences depending on the platform. We now can get rid of it. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b3e4c2c50eb5..1e476b5d9106 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2107,7 +2107,6 @@ struct drm_i915_cmd_table { (INTEL_DEVID(dev) & 0x00F0) == 0x0020) #define IS_HSW_ULT(dev) (IS_HASWELL(dev) && \ (INTEL_DEVID(dev) & 0xFF00) == 0x0A00) -#define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) #define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \ (INTEL_DEVID(dev) & 0x00F0) == 0x0020) /* ULX machines are also considered ULT. */ -- GitLab From ccc759dc2a0214fd8b65ed4ebe78050874a67f94 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 24 Sep 2014 14:20:22 -0300 Subject: [PATCH 1156/9457] drm/i915: Merge of visible and !visible paths for primary planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold intel_pipe_set_base() in the update primary plane path merging pieces of code that are common to both paths. Basically the the pin/unpin procedures are the same for both paths and some checks can also be shared (some of the were moved to the check() stage) v2: take Ville's comments: - remove unnecessary plane check - move mutex lock to inside the conditional - make the pin fail message a debug one - add a fixme for the fastboot hack - call intel_frontbuffer_flip() after FBC update v3: take more Ville's comments: - fold update code under if (intel_crtc->active), and do the visible/!visible split inside. - check ret inside the same conditional we assign it v4: don't use intel_enable_primary_hw_plane(), the primary_enabled check inside will break page flips v5: take more Ville's comments: - set primary_enabled to true and add BDW hack - unify if (old_fb) and if (old_fb != fb) v6: take more Ville's comments: - make was_primary bool and fix its check - add the BDW vblank wait comment Suggested-by: Ville Syrjälä Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 147 +++++++++++++++++---------- 1 file changed, 92 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1fff5b20f2a0..0760b60fd3bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11671,12 +11671,23 @@ intel_check_primary_plane(struct drm_plane *plane, struct drm_rect *dest = &state->dst; struct drm_rect *src = &state->src; const struct drm_rect *clip = &state->clip; + int ret; - return drm_plane_helper_check_update(plane, crtc, fb, + ret = drm_plane_helper_check_update(plane, crtc, fb, src, dest, clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, true, &state->visible); + if (ret) + return ret; + + /* no fb bound */ + if (state->visible && !fb) { + DRM_ERROR("No FB bound\n"); + return -EINVAL; + } + + return 0; } static int @@ -11688,6 +11699,8 @@ intel_commit_primary_plane(struct drm_plane *plane, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *old_fb = plane->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); struct intel_plane *intel_plane = to_intel_plane(plane); @@ -11696,76 +11709,100 @@ intel_commit_primary_plane(struct drm_plane *plane, intel_crtc_wait_for_pending_flips(crtc); - /* - * If clipping results in a non-visible primary plane, we'll disable - * the primary plane. Note that this is a bit different than what - * happens if userspace explicitly disables the plane by passing fb=0 - * because plane->fb still gets set and pinned. - */ - if (!state->visible) { + if (intel_crtc_has_pending_flip(crtc)) { + DRM_ERROR("pipe is still busy with an old pageflip\n"); + return -EBUSY; + } + + if (plane->fb != fb) { mutex_lock(&dev->struct_mutex); + ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); + if (ret == 0) + i915_gem_track_fb(old_obj, obj, + INTEL_FRONTBUFFER_PRIMARY(pipe)); + mutex_unlock(&dev->struct_mutex); + if (ret != 0) { + DRM_DEBUG_KMS("pin & fence failed\n"); + return ret; + } + } + + crtc->primary->fb = fb; + crtc->x = src->x1; + crtc->y = src->y1; + + intel_plane->crtc_x = state->orig_dst.x1; + intel_plane->crtc_y = state->orig_dst.y1; + intel_plane->crtc_w = drm_rect_width(&state->orig_dst); + intel_plane->crtc_h = drm_rect_height(&state->orig_dst); + intel_plane->src_x = state->orig_src.x1; + intel_plane->src_y = state->orig_src.y1; + intel_plane->src_w = drm_rect_width(&state->orig_src); + intel_plane->src_h = drm_rect_height(&state->orig_src); + intel_plane->obj = obj; + if (intel_crtc->active) { /* - * Try to pin the new fb first so that we can bail out if we - * fail. + * FBC does not work on some platforms for rotated + * planes, so disable it when rotation is not 0 and + * update it when rotation is set back to 0. + * + * FIXME: This is redundant with the fbc update done in + * the primary plane enable function except that that + * one is done too late. We eventually need to unify + * this. */ - if (plane->fb != fb) { - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } + if (intel_crtc->primary_enabled && + INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && + dev_priv->fbc.plane == intel_crtc->plane && + intel_plane->rotation != BIT(DRM_ROTATE_0)) { + intel_disable_fbc(dev); } - i915_gem_track_fb(old_obj, obj, - INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe)); - - if (intel_crtc->primary_enabled) - intel_disable_primary_hw_plane(plane, crtc); + if (state->visible) { + bool was_enabled = intel_crtc->primary_enabled; + /* FIXME: kill this fastboot hack */ + intel_update_pipe_size(intel_crtc); - if (plane->fb != fb) - if (plane->fb) - intel_unpin_fb_obj(old_obj); + intel_crtc->primary_enabled = true; - mutex_unlock(&dev->struct_mutex); + dev_priv->display.update_primary_plane(crtc, plane->fb, + crtc->x, crtc->y); - } else { - if (intel_crtc && intel_crtc->active && - intel_crtc->primary_enabled) { /* - * FBC does not work on some platforms for rotated - * planes, so disable it when rotation is not 0 and - * update it when rotation is set back to 0. - * - * FIXME: This is redundant with the fbc update done in - * the primary plane enable function except that that - * one is done too late. We eventually need to unify - * this. + * BDW signals flip done immediately if the plane + * is disabled, even if the plane enable is already + * armed to occur at the next vblank :( */ - if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && - dev_priv->fbc.plane == intel_crtc->plane && - intel_plane->rotation != BIT(DRM_ROTATE_0)) { - intel_disable_fbc(dev); - } + if (IS_BROADWELL(dev) && !was_enabled) + intel_wait_for_vblank(dev, intel_crtc->pipe); + } else { + /* + * If clipping results in a non-visible primary plane, + * we'll disable the primary plane. Note that this is + * a bit different than what happens if userspace + * explicitly disables the plane by passing fb=0 + * because plane->fb still gets set and pinned. + */ + intel_disable_primary_hw_plane(plane, crtc); } - ret = intel_pipe_set_base(crtc, src->x1, src->y1, fb); - if (ret) - return ret; - if (!intel_crtc->primary_enabled) - intel_enable_primary_hw_plane(plane, crtc); + intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_PRIMARY(pipe)); + + mutex_lock(&dev->struct_mutex); + intel_update_fbc(dev); + mutex_unlock(&dev->struct_mutex); } - intel_plane->crtc_x = state->orig_dst.x1; - intel_plane->crtc_y = state->orig_dst.y1; - intel_plane->crtc_w = drm_rect_width(&state->orig_dst); - intel_plane->crtc_h = drm_rect_height(&state->orig_dst); - intel_plane->src_x = state->orig_src.x1; - intel_plane->src_y = state->orig_src.y1; - intel_plane->src_w = drm_rect_width(&state->orig_src); - intel_plane->src_h = drm_rect_height(&state->orig_src); - intel_plane->obj = obj; + if (old_fb && old_fb != fb) { + if (intel_crtc->active) + intel_wait_for_vblank(dev, intel_crtc->pipe); + + mutex_lock(&dev->struct_mutex); + intel_unpin_fb_obj(old_obj); + mutex_unlock(&dev->struct_mutex); + } return 0; } -- GitLab From 5ee446383901791dc2917227de5a94ddcfadd761 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 24 Sep 2014 14:20:23 -0300 Subject: [PATCH 1157/9457] drm/i915: remove leftover from pre-universal planes days MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that universal planes are in place we don't need this plane unref on failures. Suggested-by: Ville Syrjälä Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0760b60fd3bf..8b85aa6aff64 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8455,13 +8455,6 @@ static bool cursor_size_ok(struct drm_device *dev, return true; } -/* - * intel_crtc_cursor_set_obj - Set cursor to specified GEM object - * - * Note that the object's reference will be consumed if the update fails. If - * the update succeeds, the reference of the old object (if any) will be - * consumed. - */ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, struct drm_i915_gem_object *obj, uint32_t width, uint32_t height) @@ -8491,8 +8484,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, stride = roundup_pow_of_two(width) * 4; if (obj->base.size < stride * height) { DRM_DEBUG_KMS("buffer is too small\n"); - ret = -ENOMEM; - goto fail; + return -ENOMEM; } /* we only need to pin inside GTT if cursor is non-phy */ @@ -8581,8 +8573,6 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, i915_gem_object_unpin_from_display_plane(obj); fail_locked: mutex_unlock(&dev->struct_mutex); -fail: - drm_gem_object_unreference_unlocked(&obj->base); return ret; } -- GitLab From 757f9a3e5b8a812af0c213099a5b31cb423f4d3c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 24 Sep 2014 14:20:24 -0300 Subject: [PATCH 1158/9457] drm/i915: move check of intel_crtc_cursor_set_obj() out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move check inside intel_crtc_cursor_set_obj() to intel_check_cursor_plane(), we only use it there so move them out to make the merge of intel_crtc_cursor_set_obj() into intel_check_cursor_plane() easier. This is another step toward the atomic modesetting support and unification of plane operations such pin/unpin of fb objects on i915. v2: take Ville's comment: move crtc_{w,h} assignment a bit down in the code v3: take Ville's comment: kept only the restructuring changes, the rest of the code was moved to a separated patch since it is a bug fix (we weren't checking sizes when the fb was the same) Signed-off-by: Gustavo Padovan [danvet: Fixup commit message mixup.] Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++++--------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b85aa6aff64..81f5656b2343 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8463,7 +8463,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; - unsigned old_width, stride; + unsigned old_width; uint32_t addr; int ret; @@ -8475,29 +8475,11 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, goto finish; } - /* Check for which cursor types we support */ - if (!cursor_size_ok(dev, width, height)) { - DRM_DEBUG("Cursor dimension not supported\n"); - return -EINVAL; - } - - stride = roundup_pow_of_two(width) * 4; - if (obj->base.size < stride * height) { - DRM_DEBUG_KMS("buffer is too small\n"); - return -ENOMEM; - } - /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!INTEL_INFO(dev)->cursor_needs_physical) { unsigned alignment; - if (obj->tiling_mode) { - DRM_DEBUG_KMS("cursor cannot be tiled\n"); - ret = -EINVAL; - goto fail_locked; - } - /* * Global gtt pte registers are special registers which actually * forward writes to a chunk of system memory. Which means that @@ -11918,16 +11900,55 @@ intel_check_cursor_plane(struct drm_plane *plane, struct intel_plane_state *state) { struct drm_crtc *crtc = state->crtc; + struct drm_device *dev = crtc->dev; struct drm_framebuffer *fb = state->fb; struct drm_rect *dest = &state->dst; struct drm_rect *src = &state->src; const struct drm_rect *clip = &state->clip; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + int crtc_w, crtc_h; + unsigned stride; + int ret; - return drm_plane_helper_check_update(plane, crtc, fb, + ret = drm_plane_helper_check_update(plane, crtc, fb, src, dest, clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, true, true, &state->visible); + if (ret) + return ret; + + + /* if we want to turn off the cursor ignore width and height */ + if (!obj) + return 0; + + if (fb == crtc->cursor->fb) + return 0; + + /* Check for which cursor types we support */ + crtc_w = drm_rect_width(&state->orig_dst); + crtc_h = drm_rect_height(&state->orig_dst); + if (!cursor_size_ok(dev, crtc_w, crtc_h)) { + DRM_DEBUG("Cursor dimension not supported\n"); + return -EINVAL; + } + + stride = roundup_pow_of_two(crtc_w) * 4; + if (obj->base.size < stride * crtc_h) { + DRM_DEBUG_KMS("buffer is too small\n"); + return -ENOMEM; + } + + /* we only need to pin inside GTT if cursor is non-phy */ + mutex_lock(&dev->struct_mutex); + if (!INTEL_INFO(dev)->cursor_needs_physical && obj->tiling_mode) { + DRM_DEBUG_KMS("cursor cannot be tiled\n"); + ret = -EINVAL; + } + mutex_unlock(&dev->struct_mutex); + + return ret; } static int -- GitLab From e391ea882b1a04fb3f559287ac694652a3cd9da9 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Wed, 24 Sep 2014 14:20:25 -0300 Subject: [PATCH 1159/9457] drm/i915: Fix not checking cursor and object sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even if the fb is the same we should still check if the sizes are valid to be set. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 81f5656b2343..f150765faf3f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11923,9 +11923,6 @@ intel_check_cursor_plane(struct drm_plane *plane, if (!obj) return 0; - if (fb == crtc->cursor->fb) - return 0; - /* Check for which cursor types we support */ crtc_w = drm_rect_width(&state->orig_dst); crtc_h = drm_rect_height(&state->orig_dst); @@ -11940,6 +11937,9 @@ intel_check_cursor_plane(struct drm_plane *plane, return -ENOMEM; } + if (fb == crtc->cursor->fb) + return 0; + /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!INTEL_INFO(dev)->cursor_needs_physical && obj->tiling_mode) { -- GitLab From 58abf1daae8264e5adc90733dcabeb48a8245439 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 7 Oct 2014 07:06:50 -0700 Subject: [PATCH 1160/9457] drm/i915: Do not export RC6p and RC6pp if they don't exist Avoid to expose RC6 and RC6pp to the platforms that doesn't support it. So powertop can be changed to show RC6p and RC6pp only on the platforms they are available. v2: Simplify by merging RC6p and RC6pp groups and respect the spec that mentions deep and deepest RC6 on SNB and IVB although they keep disabled by default. v3: Remove unecessary space. v4: RC6p and RC6pp is only for SNB and IVB; unify debug msg and use has_rc6p() on sanitize options instead of is gen 6 and ivb. v5: yet another fix on has_rc6p macro. final is_gen6 or is_ivb! To make sure we are excluding hsw and baytrail. References: https://bugs.freedesktop.org/show_bug.cgi?id=84524 Cc: Josh Triplett Cc: Paulo Zanoni Cc: Daniel Vetter Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_sysfs.c | 22 +++++++++++++++++++--- drivers/gpu/drm/i915/intel_pm.c | 15 ++++++++++----- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1e476b5d9106..ac6232bc1341 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2184,6 +2184,8 @@ struct drm_i915_cmd_table { #define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev)) #define HAS_RUNTIME_PM(dev) (IS_GEN6(dev) || IS_HASWELL(dev) || \ IS_BROADWELL(dev) || IS_VALLEYVIEW(dev)) +#define HAS_RC6(dev) (INTEL_INFO(dev)->gen >= 6) +#define HAS_RC6p(dev) (INTEL_INFO(dev)->gen == 6 || IS_IVYBRIDGE(dev)) #define INTEL_PCH_DEVICE_ID_MASK 0xff00 #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 503847f18fdd..4a5af695307e 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -139,8 +139,6 @@ static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL); static struct attribute *rc6_attrs[] = { &dev_attr_rc6_enable.attr, &dev_attr_rc6_residency_ms.attr, - &dev_attr_rc6p_residency_ms.attr, - &dev_attr_rc6pp_residency_ms.attr, NULL }; @@ -148,6 +146,17 @@ static struct attribute_group rc6_attr_group = { .name = power_group_name, .attrs = rc6_attrs }; + +static struct attribute *rc6p_attrs[] = { + &dev_attr_rc6p_residency_ms.attr, + &dev_attr_rc6pp_residency_ms.attr, + NULL +}; + +static struct attribute_group rc6p_attr_group = { + .name = power_group_name, + .attrs = rc6p_attrs +}; #endif static int l3_access_valid(struct drm_device *dev, loff_t offset) @@ -595,12 +604,18 @@ void i915_setup_sysfs(struct drm_device *dev) int ret; #ifdef CONFIG_PM - if (INTEL_INFO(dev)->gen >= 6) { + if (HAS_RC6(dev)) { ret = sysfs_merge_group(&dev->primary->kdev->kobj, &rc6_attr_group); if (ret) DRM_ERROR("RC6 residency sysfs setup failed\n"); } + if (HAS_RC6p(dev)) { + ret = sysfs_merge_group(&dev->primary->kdev->kobj, + &rc6p_attr_group); + if (ret) + DRM_ERROR("RC6p residency sysfs setup failed\n"); + } #endif if (HAS_L3_DPF(dev)) { ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs); @@ -640,5 +655,6 @@ void i915_teardown_sysfs(struct drm_device *dev) device_remove_bin_file(dev->primary->kdev, &dpf_attrs); #ifdef CONFIG_PM sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group); + sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6p_attr_group); #endif } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a14be5d56c6b..daa99e7e805b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3629,10 +3629,15 @@ static void intel_print_rc6_info(struct drm_device *dev, u32 mode) else mode = 0; } - DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", - (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off", - (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off", - (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off"); + if (HAS_RC6p(dev)) + DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s RC6p %s RC6pp %s\n", + (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off", + (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off", + (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off"); + + else + DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s\n", + (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); } static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) @@ -3649,7 +3654,7 @@ static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) if (enable_rc6 >= 0) { int mask; - if (INTEL_INFO(dev)->gen == 6 || IS_IVYBRIDGE(dev)) + if (HAS_RC6p(dev)) mask = INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE | INTEL_RC6pp_ENABLE; else -- GitLab From 43dc52c3b43af65084d6399c4f4b723fa2374971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 7 Oct 2014 17:41:20 +0300 Subject: [PATCH 1161/9457] drm/i915: Add missing '\n' to cdclk debug message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f150765faf3f..d6fc469d60a6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4618,7 +4618,7 @@ static void vlv_update_cdclk(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; dev_priv->vlv_cdclk_freq = dev_priv->display.get_display_clock_speed(dev); - DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz", + DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz\n", dev_priv->vlv_cdclk_freq); /* -- GitLab From 005445c5fb3a96026d6bd9580339ea8580eb6c6d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Oct 2014 11:25:16 +0100 Subject: [PATCH 1162/9457] drm/i915: Report the current number of bytes freed during oom The shrinker reports the number of pages freed, but we try to log the number of bytes - which leads to some nonsense values being reportedly freed during oom. Reported-by: Maarten Lankhorst Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2719c25588cb..dd25a546fb8e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5259,7 +5259,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) struct drm_device *dev = dev_priv->dev; struct drm_i915_gem_object *obj; unsigned long timeout = msecs_to_jiffies(5000) + 1; - unsigned long pinned, bound, unbound, freed; + unsigned long pinned, bound, unbound, freed_pages; bool was_interruptible; bool unlock; @@ -5276,7 +5276,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) was_interruptible = dev_priv->mm.interruptible; dev_priv->mm.interruptible = false; - freed = i915_gem_shrink_all(dev_priv); + freed_pages = i915_gem_shrink_all(dev_priv); dev_priv->mm.interruptible = was_interruptible; @@ -5308,13 +5308,13 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) mutex_unlock(&dev->struct_mutex); pr_info("Purging GPU memory, %lu bytes freed, %lu bytes still pinned.\n", - freed, pinned); + freed_pages << PAGE_SHIFT, pinned); if (unbound || bound) pr_err("%lu and %lu bytes still available in the " "bound and unbound GPU page lists.\n", bound, unbound); - *(unsigned long *)ptr += freed; + *(unsigned long *)ptr += freed_pages; return NOTIFY_DONE; } -- GitLab From bb9059d3a034d56f57e037d7866afeef18876283 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Oct 2014 11:25:17 +0100 Subject: [PATCH 1163/9457] drm/i915: Suppress no action noise from oom shrinker If we are not able to free anything (the shrinker leaves nothing on the global object lists), do not log anything. This is useful when other subsystems are being stress-tested for their oom behaviour and i915.ko is shouting into the logs about doing nothing. Reported-by: Dave Jones Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index dd25a546fb8e..e9c783d55612 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5307,8 +5307,9 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) if (unlock) mutex_unlock(&dev->struct_mutex); - pr_info("Purging GPU memory, %lu bytes freed, %lu bytes still pinned.\n", - freed_pages << PAGE_SHIFT, pinned); + if (freed_pages || unbound || bound) + pr_info("Purging GPU memory, %lu bytes freed, %lu bytes still pinned.\n", + freed_pages << PAGE_SHIFT, pinned); if (unbound || bound) pr_err("%lu and %lu bytes still available in the " "bound and unbound GPU page lists.\n", -- GitLab From 1447dde094c1ebe90289949b4735f8d6ed2f2c08 Mon Sep 17 00:00:00 2001 From: Sonika Jindal Date: Sat, 4 Oct 2014 10:53:31 +0100 Subject: [PATCH 1164/9457] drm/i915/skl: Add 180 degree HW rotation support Add support for 180 degree rotation for primary and sprite planes Signed-off-by: Sonika Jindal Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_display.c | 2 ++ drivers/gpu/drm/i915/intel_sprite.c | 3 +++ 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a56d9a7e7e0e..6db369a91ee9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4579,6 +4579,9 @@ enum punit_power_well { #define PLANE_CTL_ALPHA_DISABLE ( 0 << 4) #define PLANE_CTL_ALPHA_SW_PREMULTIPLY ( 2 << 4) #define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) +#define PLANE_CTL_ROTATE_MASK 0x3 +#define PLANE_CTL_ROTATE_0 0x0 +#define PLANE_CTL_ROTATE_180 0x2 #define _PLANE_STRIDE_1_A 0x70188 #define _PLANE_STRIDE_2_A 0x70288 #define _PLANE_STRIDE_3_A 0x70388 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d6fc469d60a6..6e6f1505592a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2694,6 +2694,8 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, } plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; + if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) + plane_ctl |= PLANE_CTL_ROTATE_180; I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 750b634d45ec..2c060addea29 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -162,6 +162,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK; plane_ctl &= ~PLANE_CTL_TILED_MASK; plane_ctl &= ~PLANE_CTL_ALPHA_MASK; + plane_ctl &= ~PLANE_CTL_ROTATE_MASK; /* Trickle feed has to be enabled */ plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE; @@ -217,6 +218,8 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, default: BUG(); } + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) + plane_ctl |= PLANE_CTL_ROTATE_180; plane_ctl |= PLANE_CTL_ENABLE; plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; -- GitLab From f2fbc690aee054d3e29044d66518335fe03069ca Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 24 Aug 2014 19:35:31 +0100 Subject: [PATCH 1165/9457] drm/i915: Convert a couple more INTEL_INFO-esque macros to be pointer agnostic Just a couple more macros that assume that they were being passed a struct drm_device when they want a struct drm_i915_private. Use our magic macro to ease transitioning over to using drm_i915_privates Signed-off-by: Chris Wilson Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ac6232bc1341..1d6f29806337 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2140,7 +2140,7 @@ struct drm_i915_cmd_table { #define HAS_VEBOX(dev) (INTEL_INFO(dev)->ring_mask & VEBOX_RING) #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define HAS_WT(dev) ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && \ - to_i915(dev)->ellc_size) + __I915__(dev)->ellc_size) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) @@ -2196,7 +2196,7 @@ struct drm_i915_cmd_table { #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 -#define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type) +#define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) -- GitLab From 101b376d358e2f724db5e0ac4d207079b16c4754 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 9 Oct 2014 07:11:47 -0700 Subject: [PATCH 1166/9457] drm/i915/bdw: Remove BDW preproduction W/As until C stepping. Let's clean this a bit v2: Rebase after other Mika's patch that removed some BDW production workarounds. v3: Removed stepping info. Reviewed-by: Mika Kuoppala Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 10 ---------- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 ++--- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index daa99e7e805b..23d331884944 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5654,16 +5654,6 @@ static void broadwell_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* FIXME(BDW): Check all the w/a, some might only apply to - * pre-production hw. */ - - - I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE)); - - I915_WRITE(_3D_CHICKEN3, - _MASKED_BIT_ENABLE(_3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2))); - - /* WaSwitchSolVfFArbitrationPriority:bdw */ I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7c0c28c65cb4..5ebe46a05a05 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -712,13 +712,12 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) return ret; /* WaDisablePartialInstShootdown:bdw */ - /* WaDisableThreadStallDopClockGating:bdw */ - /* FIXME: Unclear whether we really need this on production bdw. */ + /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN, _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | STALL_DOP_GATING_DISABLE)); - /* WaDisableDopClockGating:bdw May not be needed for production */ + /* WaDisableDopClockGating:bdw */ intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); -- GitLab From 343673818098b80e5adca6a93d4e112d907cd293 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 16 Oct 2014 12:28:18 +0200 Subject: [PATCH 1167/9457] drm/i915: Document that mmap forwarding is discouraged Too many new drm driver writers seem to look at i915 for inspiration. But we have two ways to do mmap, so discourage readers from the old, ugly version. In a new driver we'd just expose two mmap offsets per object, one for the gtt map and the other for the cpu map. v2: Make it clear that i915 does cpu mmaps this way for past cluelessness^W^W historical reasons. Asked for by Jani. Cc: "Cheng, Yao" Cc: David Herrmann Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e9c783d55612..895f9881f0aa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1466,6 +1466,16 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, * * While the mapping holds a reference on the contents of the object, it doesn't * imply a ref on the object itself. + * + * IMPORTANT: + * + * DRM driver writers who look a this function as an example for how to do GEM + * mmap support, please don't implement mmap support like here. The modern way + * to implement DRM mmap support is with an mmap offset ioctl (like + * i915_gem_mmap_gtt) and then using the mmap syscall on the DRM fd directly. + * That way debug tooling like valgrind will understand what's going on, hiding + * the mmap call in a driver private ioctl will break that. The i915 driver only + * does cpu mmaps this way because we didn't know better. */ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, -- GitLab From 6e2cc0963a962aad91184eaabcf67a106e80e815 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 20 Oct 2014 13:46:42 +0300 Subject: [PATCH 1168/9457] drm/i915: Replace some loop through encoders with intel_pipe_has_type() In the ironlake mode set code, there was two instances of a loop through encoders to find out if one of them has INTEL_OUTPUT_LVDS type. Simplify the code by deleting some lines and use intel_pipe_has_type() instead. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6e6f1505592a..79d9944fba5c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7110,18 +7110,11 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_encoder *intel_encoder; int refclk; const intel_limit_t *limit; bool ret, is_lvds = false; - for_each_encoder_on_crtc(dev, crtc, intel_encoder) { - switch (intel_encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - } - } + is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS); refclk = ironlake_get_refclk(crtc); @@ -7261,23 +7254,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int num_connectors = 0; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; bool ok, has_reduced_clock = false; bool is_lvds = false; - struct intel_encoder *encoder; struct intel_shared_dpll *pll; - for_each_encoder_on_crtc(dev, crtc, encoder) { - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - } - - num_connectors++; - } + is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS); WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); -- GitLab From a919ff14e606a7a2aca62259500158413c733fe8 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 20 Oct 2014 13:46:43 +0300 Subject: [PATCH 1169/9457] drm/i915: Make *_find_best_dpll() take an intel_crtc insted of drm_crtc For consistency, since that's the rule followed for internal functions. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1d6f29806337..3a8d0cba1a53 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -460,7 +460,7 @@ struct drm_i915_display_funcs { * Returns true on success, false on failure. */ bool (*find_dpll)(const struct intel_limit *limit, - struct drm_crtc *crtc, + struct intel_crtc *crtc, int target, int refclk, struct dpll *match_clock, struct dpll *best_clock); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 79d9944fba5c..eed389404707 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -576,15 +576,15 @@ static bool intel_PLL_is_valid(struct drm_device *dev, } static bool -i9xx_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; intel_clock_t clock; int err = target; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -637,15 +637,15 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, } static bool -pnv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; intel_clock_t clock; int err = target; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -696,11 +696,11 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, } static bool -g4x_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; intel_clock_t clock; int max_n; bool found; @@ -708,7 +708,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, int err_most = (target >> 8) + (target >> 9); found = false; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { if (intel_is_dual_link_lvds(dev)) clock.p2 = limit->p2.p2_fast; else @@ -753,11 +753,11 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, } static bool -vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; intel_clock_t clock; unsigned int bestppm = 1000000; /* min update 19.2 MHz */ @@ -810,11 +810,11 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, } static bool -chv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, +chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int target, int refclk, intel_clock_t *match_clock, intel_clock_t *best_clock) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; intel_clock_t clock; uint64_t m2; int found = false; @@ -6284,7 +6284,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ok = dev_priv->display.find_dpll(limit, crtc, + ok = dev_priv->display.find_dpll(limit, intel_crtc, intel_crtc->config.port_clock, refclk, NULL, &clock); if (!ok) { @@ -6300,7 +6300,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * we will disable the LVDS downclock feature. */ has_reduced_clock = - dev_priv->display.find_dpll(limit, crtc, + dev_priv->display.find_dpll(limit, intel_crtc, dev_priv->lvds_downclock, refclk, &clock, &reduced_clock); @@ -7110,6 +7110,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int refclk; const intel_limit_t *limit; bool ret, is_lvds = false; @@ -7124,8 +7125,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ret = dev_priv->display.find_dpll(limit, crtc, - to_intel_crtc(crtc)->config.port_clock, + ret = dev_priv->display.find_dpll(limit, intel_crtc, + intel_crtc->config.port_clock, refclk, NULL, clock); if (!ret) return false; @@ -7138,7 +7139,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, * downclock feature. */ *has_reduced_clock = - dev_priv->display.find_dpll(limit, crtc, + dev_priv->display.find_dpll(limit, intel_crtc, dev_priv->lvds_downclock, refclk, clock, reduced_clock); -- GitLab From c7653199c01a2499ea134ead0fe03f2451c28518 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 20 Oct 2014 13:46:44 +0300 Subject: [PATCH 1170/9457] drm/i915: Make *_crtc_mode_set() take an intel_crtc insted of drm_crtc For consistency, since that's the rule followed for internal functions. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 95 +++++++++++++--------------- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3a8d0cba1a53..9f3d68903caa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -476,7 +476,7 @@ struct drm_i915_display_funcs { struct intel_crtc_config *); void (*get_plane_config)(struct intel_crtc *, struct intel_plane_config *); - int (*crtc_mode_set)(struct drm_crtc *crtc, + int (*crtc_mode_set)(struct intel_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb); void (*crtc_enable)(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eed389404707..b9f0f38bd482 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6244,13 +6244,12 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) POSTING_READ(PIPECONF(intel_crtc->pipe)); } -static int i9xx_crtc_mode_set(struct drm_crtc *crtc, +static int i9xx_crtc_mode_set(struct intel_crtc *crtc, int x, int y, struct drm_framebuffer *fb) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; bool ok, has_reduced_clock = false; @@ -6258,7 +6257,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, struct intel_encoder *encoder; const intel_limit_t *limit; - for_each_encoder_on_crtc(dev, crtc, encoder) { + for_each_encoder_on_crtc(dev, &crtc->base, encoder) { switch (encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; @@ -6274,8 +6273,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (is_dsi) return 0; - if (!intel_crtc->config.clock_set) { - refclk = i9xx_get_refclk(crtc, num_connectors); + if (!crtc->config.clock_set) { + refclk = i9xx_get_refclk(&crtc->base, num_connectors); /* * Returns a set of divisors for the desired target clock with @@ -6283,9 +6282,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + * 2) / p1 / p2. */ - limit = intel_limit(crtc, refclk); - ok = dev_priv->display.find_dpll(limit, intel_crtc, - intel_crtc->config.port_clock, + limit = intel_limit(&crtc->base, refclk); + ok = dev_priv->display.find_dpll(limit, crtc, + crtc->config.port_clock, refclk, NULL, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); @@ -6300,29 +6299,29 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * we will disable the LVDS downclock feature. */ has_reduced_clock = - dev_priv->display.find_dpll(limit, intel_crtc, + dev_priv->display.find_dpll(limit, crtc, dev_priv->lvds_downclock, refclk, &clock, &reduced_clock); } /* Compat-code for transition, will disappear. */ - intel_crtc->config.dpll.n = clock.n; - intel_crtc->config.dpll.m1 = clock.m1; - intel_crtc->config.dpll.m2 = clock.m2; - intel_crtc->config.dpll.p1 = clock.p1; - intel_crtc->config.dpll.p2 = clock.p2; + crtc->config.dpll.n = clock.n; + crtc->config.dpll.m1 = clock.m1; + crtc->config.dpll.m2 = clock.m2; + crtc->config.dpll.p1 = clock.p1; + crtc->config.dpll.p2 = clock.p2; } if (IS_GEN2(dev)) { - i8xx_update_pll(intel_crtc, + i8xx_update_pll(crtc, has_reduced_clock ? &reduced_clock : NULL, num_connectors); } else if (IS_CHERRYVIEW(dev)) { - chv_update_pll(intel_crtc); + chv_update_pll(crtc); } else if (IS_VALLEYVIEW(dev)) { - vlv_update_pll(intel_crtc); + vlv_update_pll(crtc); } else { - i9xx_update_pll(intel_crtc, + i9xx_update_pll(crtc, has_reduced_clock ? &reduced_clock : NULL, num_connectors); } @@ -7249,68 +7248,67 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, return dpll | DPLL_VCO_ENABLE; } -static int ironlake_crtc_mode_set(struct drm_crtc *crtc, +static int ironlake_crtc_mode_set(struct intel_crtc *crtc, int x, int y, struct drm_framebuffer *fb) { - struct drm_device *dev = crtc->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_device *dev = crtc->base.dev; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0; bool ok, has_reduced_clock = false; bool is_lvds = false; struct intel_shared_dpll *pll; - is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS); + is_lvds = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS); WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); - ok = ironlake_compute_clocks(crtc, &clock, + ok = ironlake_compute_clocks(&crtc->base, &clock, &has_reduced_clock, &reduced_clock); - if (!ok && !intel_crtc->config.clock_set) { + if (!ok && !crtc->config.clock_set) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; } /* Compat-code for transition, will disappear. */ - if (!intel_crtc->config.clock_set) { - intel_crtc->config.dpll.n = clock.n; - intel_crtc->config.dpll.m1 = clock.m1; - intel_crtc->config.dpll.m2 = clock.m2; - intel_crtc->config.dpll.p1 = clock.p1; - intel_crtc->config.dpll.p2 = clock.p2; + if (!crtc->config.clock_set) { + crtc->config.dpll.n = clock.n; + crtc->config.dpll.m1 = clock.m1; + crtc->config.dpll.m2 = clock.m2; + crtc->config.dpll.p1 = clock.p1; + crtc->config.dpll.p2 = clock.p2; } /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ - if (intel_crtc->config.has_pch_encoder) { - fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); + if (crtc->config.has_pch_encoder) { + fp = i9xx_dpll_compute_fp(&crtc->config.dpll); if (has_reduced_clock) fp2 = i9xx_dpll_compute_fp(&reduced_clock); - dpll = ironlake_compute_dpll(intel_crtc, + dpll = ironlake_compute_dpll(crtc, &fp, &reduced_clock, has_reduced_clock ? &fp2 : NULL); - intel_crtc->config.dpll_hw_state.dpll = dpll; - intel_crtc->config.dpll_hw_state.fp0 = fp; + crtc->config.dpll_hw_state.dpll = dpll; + crtc->config.dpll_hw_state.fp0 = fp; if (has_reduced_clock) - intel_crtc->config.dpll_hw_state.fp1 = fp2; + crtc->config.dpll_hw_state.fp1 = fp2; else - intel_crtc->config.dpll_hw_state.fp1 = fp; + crtc->config.dpll_hw_state.fp1 = fp; - pll = intel_get_shared_dpll(intel_crtc); + pll = intel_get_shared_dpll(crtc); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", - pipe_name(intel_crtc->pipe)); + pipe_name(crtc->pipe)); return -EINVAL; } } else - intel_put_shared_dpll(intel_crtc); + intel_put_shared_dpll(crtc); if (is_lvds && has_reduced_clock && i915.powersave) - intel_crtc->lowfreq_avail = true; + crtc->lowfreq_avail = true; else - intel_crtc->lowfreq_avail = false; + crtc->lowfreq_avail = false; return 0; } @@ -7804,16 +7802,14 @@ static void haswell_modeset_global_resources(struct drm_device *dev) modeset_update_crtc_power_domains(dev); } -static int haswell_crtc_mode_set(struct drm_crtc *crtc, +static int haswell_crtc_mode_set(struct intel_crtc *crtc, int x, int y, struct drm_framebuffer *fb) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - if (!intel_ddi_pll_select(intel_crtc)) + if (!intel_ddi_pll_select(crtc)) return -EINVAL; - intel_crtc->lowfreq_avail = false; + crtc->lowfreq_avail = false; return 0; } @@ -11004,8 +11000,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, crtc->x = x; crtc->y = y; - ret = dev_priv->display.crtc_mode_set(&intel_crtc->base, - x, y, fb); + ret = dev_priv->display.crtc_mode_set(intel_crtc, x, y, fb); if (ret) goto done; } -- GitLab From 409ee761fdc3b39e34ffccea375e7f0f13fce9cc Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 20 Oct 2014 13:46:45 +0300 Subject: [PATCH 1171/9457] drm/i915: Make intel_pipe_has_type() and some callers take intel_crtc For consistency, since that's the rule followed for internal functions. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 106 ++++++++++++++------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b9f0f38bd482..103972c131b6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -406,22 +406,22 @@ static void vlv_clock(int refclk, intel_clock_t *clock) /** * Returns whether any output on the specified pipe is of the specified type */ -static bool intel_pipe_has_type(struct drm_crtc *crtc, int type) +static bool intel_pipe_has_type(struct intel_crtc *crtc, int type) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; struct intel_encoder *encoder; - for_each_encoder_on_crtc(dev, crtc, encoder) + for_each_encoder_on_crtc(dev, &crtc->base, encoder) if (encoder->type == type) return true; return false; } -static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, +static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc, int refclk) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { @@ -442,9 +442,9 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, return limit; } -static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) +static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { @@ -463,9 +463,9 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) return limit; } -static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) +static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; const intel_limit_t *limit; if (HAS_PCH_SPLIT(dev)) @@ -584,7 +584,7 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, intel_clock_t clock; int err = target; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -645,7 +645,7 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, intel_clock_t clock; int err = target; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -708,7 +708,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int err_most = (target >> 8) + (target >> 9); found = false; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_is_dual_link_lvds(dev)) clock.p2 = limit->p2.p2_fast; else @@ -1567,7 +1567,7 @@ static int intel_num_dvo_pipes(struct drm_device *dev) for_each_intel_crtc(dev, crtc) count += crtc->active && - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO); + intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO); return count; } @@ -1646,7 +1646,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc) /* Disable DVO 2x clock on both PLLs if necessary */ if (IS_I830(dev) && - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO) && + intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) && intel_num_dvo_pipes(dev) == 1) { I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE); @@ -1884,7 +1884,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, val &= ~TRANS_INTERLACE_MASK; if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) if (HAS_PCH_IBX(dev_priv->dev) && - intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) + intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) val |= TRANS_LEGACY_INTERLACED_ILK; else val |= TRANS_INTERLACED; @@ -2007,7 +2007,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc) * need the check. */ if (!HAS_PCH_SPLIT(dev_priv->dev)) - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DSI)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI)) assert_dsi_pll_enabled(dev_priv); else assert_pll_enabled(dev_priv, pipe); @@ -2846,8 +2846,8 @@ static void intel_update_pipe_size(struct intel_crtc *crtc) ((adjusted_mode->crtc_hdisplay - 1) << 16) | (adjusted_mode->crtc_vdisplay - 1)); if (!crtc->config.pch_pfit.enabled && - (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))) { + (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { I915_WRITE(PF_CTL(crtc->pipe), 0); I915_WRITE(PF_WIN_POS(crtc->pipe), 0); I915_WRITE(PF_WIN_SZ(crtc->pipe), 0); @@ -3755,8 +3755,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { + (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_EDP))) { u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5; reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); @@ -4033,7 +4033,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) return; if (!HAS_PCH_SPLIT(dev_priv->dev)) { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI)) + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI)) assert_dsi_pll_enabled(dev_priv); else assert_pll_enabled(dev_priv, pipe); @@ -4834,7 +4834,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->active) return; - is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); + is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI); if (!is_dsi) { if (IS_CHERRYVIEW(dev)) @@ -5028,7 +5028,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (encoder->post_disable) encoder->post_disable(encoder); - if (!intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI)) { + if (!intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI)) { if (IS_CHERRYVIEW(dev)) chv_disable_pll(dev_priv, pipe); else if (IS_VALLEYVIEW(dev)) @@ -5411,7 +5411,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, * - LVDS dual channel mode * - Double wide pipe */ - if ((intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + if ((intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && intel_is_dual_link_lvds(dev)) || pipe_config->double_wide) pipe_config->pipe_src_w &= ~1; @@ -5599,9 +5599,9 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); } -static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) +static int i9xx_get_refclk(struct intel_crtc *crtc, int num_connectors) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int refclk; @@ -5649,7 +5649,7 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, crtc->config.dpll_hw_state.fp0 = fp; crtc->lowfreq_avail = false; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && reduced_clock && i915.powersave) { crtc->config.dpll_hw_state.fp1 = fp2; crtc->lowfreq_avail = true; @@ -5818,16 +5818,16 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) /* Set HBR and RBR LPF coefficients */ if (crtc->config.port_clock == 162000 || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) + intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x009f0003); else vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x00d0000f); - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { /* Use SSC source */ if (pipe == PIPE_A) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe), @@ -5847,8 +5847,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe)); coreclk = (coreclk & 0x0000ff00) | 0x01c00000; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) coreclk |= 0x01000000; vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk); @@ -5918,7 +5918,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc) (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT)); /* Loop filter */ - refclk = i9xx_get_refclk(&crtc->base, 0); + refclk = i9xx_get_refclk(crtc, 0); loopfilter = 5 << DPIO_CHV_PROP_COEFF_SHIFT | 2 << DPIO_CHV_GAIN_CTRL_SHIFT; if (refclk == 100000) @@ -5950,12 +5950,12 @@ static void i9xx_update_pll(struct intel_crtc *crtc, i9xx_update_pll_dividers(crtc, reduced_clock); - is_sdvo = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_SDVO) || - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI); + is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) dpll |= DPLLB_MODE_LVDS; else dpll |= DPLLB_MODE_DAC_SERIAL; @@ -5968,7 +5968,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc, if (is_sdvo) dpll |= DPLL_SDVO_HIGH_SPEED; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ @@ -5998,7 +5998,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc, if (crtc->config.sdvo_tv_clock) dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else @@ -6027,7 +6027,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc, dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; } else { if (clock->p1 == 2) @@ -6038,10 +6038,10 @@ static void i8xx_update_pll(struct intel_crtc *crtc, dpll |= PLL_P2_DIVIDE_BY_4; } - if (!IS_I830(dev) && intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO)) + if (!IS_I830(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; - if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else @@ -6072,7 +6072,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) crtc_vtotal -= 1; crtc_vblank_end -= 1; - if (intel_pipe_has_type(&intel_crtc->base, INTEL_OUTPUT_SDVO)) + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2; else vsyncshift = adjusted_mode->crtc_hsync_start - @@ -6230,7 +6230,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { if (INTEL_INFO(dev)->gen < 4 || - intel_pipe_has_type(&intel_crtc->base, INTEL_OUTPUT_SDVO)) + intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; else pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT; @@ -6274,7 +6274,7 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, return 0; if (!crtc->config.clock_set) { - refclk = i9xx_get_refclk(&crtc->base, num_connectors); + refclk = i9xx_get_refclk(crtc, num_connectors); /* * Returns a set of divisors for the desired target clock with @@ -6282,7 +6282,7 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + * 2) / p1 / p2. */ - limit = intel_limit(&crtc->base, refclk); + limit = intel_limit(crtc, refclk); ok = dev_priv->display.find_dpll(limit, crtc, crtc->config.port_clock, refclk, NULL, &clock); @@ -7114,7 +7114,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, const intel_limit_t *limit; bool ret, is_lvds = false; - is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS); + is_lvds = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_LVDS); refclk = ironlake_get_refclk(crtc); @@ -7123,7 +7123,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, * refclk, or FALSE. The returned values represent the clock equation: * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ - limit = intel_limit(crtc, refclk); + limit = intel_limit(intel_crtc, refclk); ret = dev_priv->display.find_dpll(limit, intel_crtc, intel_crtc->config.port_clock, refclk, NULL, clock); @@ -7259,7 +7259,7 @@ static int ironlake_crtc_mode_set(struct intel_crtc *crtc, bool is_lvds = false; struct intel_shared_dpll *pll; - is_lvds = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS); + is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS); WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); @@ -8049,6 +8049,7 @@ static void haswell_write_eld(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint8_t *eld = connector->eld; uint32_t eldv; uint32_t i; @@ -8089,7 +8090,7 @@ static void haswell_write_eld(struct drm_connector *connector, eldv = AUDIO_ELD_VALID_A << (pipe * 4); - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ @@ -8132,6 +8133,7 @@ static void ironlake_write_eld(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint8_t *eld = connector->eld; uint32_t eldv; uint32_t i; @@ -8185,7 +8187,7 @@ static void ironlake_write_eld(struct drm_connector *connector, eldv = IBX_ELD_VALIDB << ((i - 1) * 4); } - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ @@ -10880,7 +10882,7 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset = vtotal - 1; } else if (HAS_DDI(dev) && - intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) { + intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { crtc->scanline_offset = 2; } else crtc->scanline_offset = 1; -- GitLab From 0b14cbd2f58199a024acbe2994bb27533c97d756 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 10 Sep 2014 18:16:55 +0300 Subject: [PATCH 1172/9457] drm/i915: remove dead code from legacy suspend handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The legacy DRM suspend logic (effective in UMS) doesn't handle any S4 thaw events so we don't need to care about it either. Only S3 suspend and S4 freeze events are handled. Leave an assert behind to be sure. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a05a1d083e95..f7bc3e980d8e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -640,9 +640,9 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) return -ENODEV; } - if (state.event == PM_EVENT_PRETHAW) - return 0; - + if (WARN_ON_ONCE(state.event != PM_EVENT_SUSPEND && + state.event != PM_EVENT_FREEZE)) + return -EINVAL; if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; -- GitLab From 8eff426233e61332686acea22a4199288047ec64 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Oct 2014 14:40:37 +0300 Subject: [PATCH 1173/9457] drm/i915: remove redundant #ifdef CONFIG_COMPAT The whole file is only built with CONFIG_COMPAT=y. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_ioc32.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c index 2e0613e26251..176de6322e4d 100644 --- a/drivers/gpu/drm/i915/i915_ioc32.c +++ b/drivers/gpu/drm/i915/i915_ioc32.c @@ -189,7 +189,6 @@ static drm_ioctl_compat_t *i915_compat_ioctls[] = { [DRM_I915_ALLOC] = compat_i915_alloc }; -#ifdef CONFIG_COMPAT /** * Called whenever a 32-bit process running under a 64-bit kernel * performs an ioctl on /dev/dri/card. @@ -218,4 +217,3 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return ret; } -#endif -- GitLab From 7225342ab501befdb64bcec76ded41f5897c0855 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 7 Oct 2014 17:21:26 +0300 Subject: [PATCH 1174/9457] drm/i915: Build workaround list in ring initialization If we build the workaround list in ring initialization and decouple it from the actual writing of values, we gain the ability to decide where and how we want to apply the values. The advantage of this will become more clear when we need to initialize workarounds on older gens where it is not possible to write all the registers through ring LRIs. v2: rebase on newest bdw workarounds Cc: Arun Siluvery Cc: Damien Lespiau Signed-off-by: Mika Kuoppala Reviewed-by: Arun Siluvery [danvet: Resolve tiny conflict in comments and ocd alignments a bit.] [danvet2: Remove bogus force_wake_get call spotted by Paulo and QA.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 18 +-- drivers/gpu/drm/i915/i915_drv.h | 28 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 184 +++++++++++++----------- 3 files changed, 128 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index da4036d0bab9..62c111b1f0d8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2655,18 +2655,18 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - seq_printf(m, "Workarounds applied: %d\n", dev_priv->num_wa_regs); - for (i = 0; i < dev_priv->num_wa_regs; ++i) { + seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count); + for (i = 0; i < dev_priv->workarounds.count; ++i) { u32 addr, mask; - addr = dev_priv->intel_wa_regs[i].addr; - mask = dev_priv->intel_wa_regs[i].mask; - dev_priv->intel_wa_regs[i].value = I915_READ(addr) | mask; - if (dev_priv->intel_wa_regs[i].addr) + addr = dev_priv->workarounds.reg[i].addr; + mask = dev_priv->workarounds.reg[i].mask; + dev_priv->workarounds.reg[i].value = I915_READ(addr) | mask; + if (dev_priv->workarounds.reg[i].addr) seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n", - dev_priv->intel_wa_regs[i].addr, - dev_priv->intel_wa_regs[i].value, - dev_priv->intel_wa_regs[i].mask); + dev_priv->workarounds.reg[i].addr, + dev_priv->workarounds.reg[i].value, + dev_priv->workarounds.reg[i].mask); } intel_runtime_pm_put(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9f3d68903caa..d1905b38fc95 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1448,6 +1448,20 @@ struct i915_frontbuffer_tracking { unsigned flip_bits; }; +struct i915_wa_reg { + u32 addr; + u32 value; + /* bitmask representing WA bits */ + u32 mask; +}; + +#define I915_MAX_WA_REGS 16 + +struct i915_workarounds { + struct i915_wa_reg reg[I915_MAX_WA_REGS]; + u32 count; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1590,19 +1604,7 @@ struct drm_i915_private { struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; - /* - * workarounds are currently applied at different places and - * changes are being done to consolidate them so exact count is - * not clear at this point, use a max value for now. - */ -#define I915_MAX_WA_REGS 16 - struct { - u32 addr; - u32 value; - /* bitmask representing WA bits */ - u32 mask; - } intel_wa_regs[I915_MAX_WA_REGS]; - u32 num_wa_regs; + struct i915_workarounds workarounds; /* Reclocking support */ bool render_reclock_avail; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5ebe46a05a05..5f935d4dfb6a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -665,79 +665,107 @@ intel_init_pipe_control(struct intel_engine_cs *ring) return ret; } -static inline void intel_ring_emit_wa(struct intel_engine_cs *ring, - u32 addr, u32 value) +static int intel_ring_workarounds_emit(struct intel_engine_cs *ring) { + int ret, i; struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_workarounds *w = &dev_priv->workarounds; - if (WARN_ON(dev_priv->num_wa_regs >= I915_MAX_WA_REGS)) - return; + if (WARN_ON(w->count == 0)) + return 0; - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, addr); - intel_ring_emit(ring, value); + ring->gpu_caches_dirty = true; + ret = intel_ring_flush_all_caches(ring); + if (ret) + return ret; - dev_priv->intel_wa_regs[dev_priv->num_wa_regs].addr = addr; - dev_priv->intel_wa_regs[dev_priv->num_wa_regs].mask = value & 0xFFFF; - /* value is updated with the status of remaining bits of this - * register when it is read from debugfs file - */ - dev_priv->intel_wa_regs[dev_priv->num_wa_regs].value = value; - dev_priv->num_wa_regs++; + ret = intel_ring_begin(ring, w->count * 3); + if (ret) + return ret; + + for (i = 0; i < w->count; i++) { + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, w->reg[i].addr); + intel_ring_emit(ring, w->reg[i].value); + } + + intel_ring_advance(ring); + + ring->gpu_caches_dirty = true; + ret = intel_ring_flush_all_caches(ring); + if (ret) + return ret; + + DRM_DEBUG_DRIVER("Number of Workarounds emitted: %d\n", w->count); - return; + return 0; +} + +static int wa_add(struct drm_i915_private *dev_priv, + const u32 addr, const u32 val, const u32 mask) +{ + const u32 idx = dev_priv->workarounds.count; + + if (WARN_ON(idx >= I915_MAX_WA_REGS)) + return -ENOSPC; + + dev_priv->workarounds.reg[idx].addr = addr; + dev_priv->workarounds.reg[idx].value = val; + dev_priv->workarounds.reg[idx].mask = mask; + + dev_priv->workarounds.count++; + + return 0; } +#define WA_REG(addr, val, mask) { \ + const int r = wa_add(dev_priv, (addr), (val), (mask)); \ + if (r) \ + return r; \ + } + +#define WA_SET_BIT_MASKED(addr, mask) \ + WA_REG(addr, _MASKED_BIT_ENABLE(mask), (mask) & 0xffff) + +#define WA_CLR_BIT_MASKED(addr, mask) \ + WA_REG(addr, _MASKED_BIT_DISABLE(mask), (mask) & 0xffff) + +#define WA_SET_BIT(addr, mask) WA_REG(addr, I915_READ(addr) | (mask), mask) +#define WA_CLR_BIT(addr, mask) WA_REG(addr, I915_READ(addr) & ~(mask), mask) + +#define WA_WRITE(addr, val) WA_REG(addr, val, 0xffffffff) + static int bdw_init_workarounds(struct intel_engine_cs *ring) { - int ret; struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - /* - * workarounds applied in this fn are part of register state context, - * they need to be re-initialized followed by gpu reset, suspend/resume, - * module reload. - */ - dev_priv->num_wa_regs = 0; - memset(dev_priv->intel_wa_regs, 0, sizeof(dev_priv->intel_wa_regs)); - - /* - * update the number of dwords required based on the - * actual number of workarounds applied - */ - ret = intel_ring_begin(ring, 18); - if (ret) - return ret; - /* WaDisablePartialInstShootdown:bdw */ /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ - intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN, - _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE - | STALL_DOP_GATING_DISABLE)); + WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | + STALL_DOP_GATING_DISABLE); /* WaDisableDopClockGating:bdw */ - intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, + DOP_CLOCK_GATING_DISABLE); - intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3, - _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); + WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, + GEN8_SAMPLER_POWER_BYPASS_DIS); /* Use Force Non-Coherent whenever executing a 3D context. This is a * workaround for for a possible hang in the unlikely event a TLB * invalidation occurs during a PSD flush. */ /* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */ - intel_ring_emit_wa(ring, HDC_CHICKEN0, - _MASKED_BIT_ENABLE(HDC_FORCE_NON_COHERENT | - (IS_BDW_GT3(dev) ? - HDC_FENCE_DEST_SLM_DISABLE : 0) - )); + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FORCE_NON_COHERENT | + (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); /* Wa4x4STCOptimizationDisable:bdw */ - intel_ring_emit_wa(ring, CACHE_MODE_1, - _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); + WA_SET_BIT_MASKED(CACHE_MODE_1, + GEN8_4x4_STC_OPTIMIZATION_DISABLE); /* * BSpec recommends 8x4 when MSAA is used, @@ -747,52 +775,50 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) * disable bit, which we don't touch here, but it's good * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). */ - intel_ring_emit_wa(ring, GEN7_GT_MODE, - GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); - - intel_ring_advance(ring); - - DRM_DEBUG_DRIVER("Number of Workarounds applied: %d\n", - dev_priv->num_wa_regs); + WA_SET_BIT_MASKED(GEN7_GT_MODE, + GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); return 0; } static int chv_init_workarounds(struct intel_engine_cs *ring) { - int ret; struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - /* - * workarounds applied in this fn are part of register state context, - * they need to be re-initialized followed by gpu reset, suspend/resume, - * module reload. - */ - dev_priv->num_wa_regs = 0; - memset(dev_priv->intel_wa_regs, 0, sizeof(dev_priv->intel_wa_regs)); - - ret = intel_ring_begin(ring, 12); - if (ret) - return ret; - /* WaDisablePartialInstShootdown:chv */ - intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN, - _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE)); + WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); /* WaDisableThreadStallDopClockGating:chv */ - intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN, - _MASKED_BIT_ENABLE(STALL_DOP_GATING_DISABLE)); + WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, + STALL_DOP_GATING_DISABLE); /* WaDisableDopClockGating:chv (pre-production hw) */ - intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, + DOP_CLOCK_GATING_DISABLE); /* WaDisableSamplerPowerBypass:chv (pre-production hw) */ - intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3, - _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); + WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, + GEN8_SAMPLER_POWER_BYPASS_DIS); - intel_ring_advance(ring); + return 0; +} + +static int init_workarounds_ring(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(ring->id != RCS); + + dev_priv->workarounds.count = 0; + + if (IS_BROADWELL(dev)) + return bdw_init_workarounds(ring); + + if (IS_CHERRYVIEW(dev)) + return chv_init_workarounds(ring); return 0; } @@ -852,7 +878,7 @@ static int init_render_ring(struct intel_engine_cs *ring) if (HAS_L3_DPF(dev)) I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev)); - return ret; + return init_workarounds_ring(ring); } static void render_ring_cleanup(struct intel_engine_cs *ring) @@ -2298,10 +2324,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) dev_priv->semaphore_obj = obj; } } - if (IS_CHERRYVIEW(dev)) - ring->init_context = chv_init_workarounds; - else - ring->init_context = bdw_init_workarounds; + + ring->init_context = intel_ring_workarounds_emit; ring->add_request = gen6_add_request; ring->flush = gen8_render_ring_flush; ring->irq_get = gen8_ring_get_irq; -- GitLab From 2fa60f6d515b509b05f6a96afc83ac9629d6401b Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 7 Oct 2014 17:21:27 +0300 Subject: [PATCH 1175/9457] drm/i915: Check workaround status on dfs read time As the workaround list has the value as initialization time constant, we can do the simple checking on the go without negleting igt. Signed-off-by: Mika Kuoppala Reviewed-by: Arun Siluvery Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 62c111b1f0d8..6f8c9d780632 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2657,16 +2657,16 @@ static int i915_wa_registers(struct seq_file *m, void *unused) seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count); for (i = 0; i < dev_priv->workarounds.count; ++i) { - u32 addr, mask; + u32 addr, mask, value, read; + bool ok; addr = dev_priv->workarounds.reg[i].addr; mask = dev_priv->workarounds.reg[i].mask; - dev_priv->workarounds.reg[i].value = I915_READ(addr) | mask; - if (dev_priv->workarounds.reg[i].addr) - seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n", - dev_priv->workarounds.reg[i].addr, - dev_priv->workarounds.reg[i].value, - dev_priv->workarounds.reg[i].mask); + value = dev_priv->workarounds.reg[i].value; + read = I915_READ(addr); + ok = (value & mask) == (read & mask); + seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, status: %s\n", + addr, value, mask, read, ok ? "OK" : "FAIL"); } intel_runtime_pm_put(dev_priv); -- GitLab From 163f53a2611c98a9f8e25cbda30ce8ce268b92de Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 10 Sep 2014 18:16:54 +0300 Subject: [PATCH 1176/9457] drm/i915: vlv: fix gunit HW state corruption during S4 suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During S4 freeze we don't call intel_suspend_complete(), which would save the gunit HW state, but during S4 thaw/restore events we call intel_resume_prepare() which restores it, thus ending up in a corrupted HW state. Fix this by calling intel_suspend_complete() from the corresponding freeze_late event handler. The issue was introduced in commit 016970beb05da6285c2f3ed2bee1c676cb75972e Author: Sagar Kamble Date: Wed Aug 13 23:07:06 2014 +0530 CC: Sagar Kamble Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f7bc3e980d8e..ffd672ef245c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1011,6 +1011,15 @@ static int i915_pm_freeze(struct device *dev) return i915_drm_freeze(drm_dev); } +static int i915_pm_freeze_late(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct drm_i915_private *dev_priv = drm_dev->dev_private; + + return intel_suspend_complete(dev_priv); +} + static int i915_pm_thaw_early(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -1595,6 +1604,7 @@ static const struct dev_pm_ops i915_pm_ops = { .resume_early = i915_pm_resume_early, .resume = i915_pm_resume, .freeze = i915_pm_freeze, + .freeze_late = i915_pm_freeze_late, .thaw_early = i915_pm_thaw_early, .thaw = i915_pm_thaw, .poweroff = i915_pm_poweroff, -- GitLab From d9ceb8163339134bd3ffb9fb87a0db4698283e32 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 9 Oct 2014 12:57:43 -0700 Subject: [PATCH 1177/9457] drm/i915: preserve swizzle settings if necessary v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some machines (like MBAs) might use a tiled framebuffer but not enable display swizzling at boot time. We want to preserve that configuration if possible to prevent a boot time mode set. On IVB+ it shouldn't affect performance anyway since the memory controller does internal swizzling anyway. For most other configs we'll be able to enable swizzling at boot time, since the initial framebuffer won't be tiled, thus we won't see any corruption when we enable it. v2: preserve swizzling if BIOS had it set (Daniel) v3: preserve swizzling only if we inherited a tiled framebuffer (Daniel) check display swizzle setting in detect_bit_6_swizzle (Daniel) use gen6 as cutoff point (Daniel) v4: fixup swizzle preserve again, had wrong init order (Daniel) Reported-by: Kristian Høgsberg Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem_tiling.c | 41 ++++++++++++++++---------- drivers/gpu/drm/i915/intel_display.c | 4 +++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d1905b38fc95..3212d62c3c64 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1541,6 +1541,8 @@ struct drm_i915_private { struct intel_opregion opregion; struct intel_vbt_data vbt; + bool preserve_bios_swizzle; + /* overlay */ struct intel_overlay *overlay; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 2cefb597df6d..d1e7a3e088aa 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -102,22 +102,33 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else if (INTEL_INFO(dev)->gen >= 6) { - uint32_t dimm_c0, dimm_c1; - dimm_c0 = I915_READ(MAD_DIMM_C0); - dimm_c1 = I915_READ(MAD_DIMM_C1); - dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; - dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; - /* Enable swizzling when the channels are populated with - * identically sized dimms. We don't need to check the 3rd - * channel because no cpu with gpu attached ships in that - * configuration. Also, swizzling only makes sense for 2 - * channels anyway. */ - if (dimm_c0 == dimm_c1) { - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; + if (dev_priv->preserve_bios_swizzle) { + if (I915_READ(DISP_ARB_CTL) & + DISP_TILE_SURFACE_SWIZZLING) { + swizzle_x = I915_BIT_6_SWIZZLE_9_10; + swizzle_y = I915_BIT_6_SWIZZLE_9; + } else { + swizzle_x = I915_BIT_6_SWIZZLE_NONE; + swizzle_y = I915_BIT_6_SWIZZLE_NONE; + } } else { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; + uint32_t dimm_c0, dimm_c1; + dimm_c0 = I915_READ(MAD_DIMM_C0); + dimm_c1 = I915_READ(MAD_DIMM_C1); + dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; + dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; + /* Enable swizzling when the channels are populated + * with identically sized dimms. We don't need to check + * the 3rd channel because no cpu with gpu attached + * ships in that configuration. Also, swizzling only + * makes sense for 2 channels anyway. */ + if (dimm_c0 == dimm_c1) { + swizzle_x = I915_BIT_6_SWIZZLE_9_10; + swizzle_y = I915_BIT_6_SWIZZLE_9; + } else { + swizzle_x = I915_BIT_6_SWIZZLE_NONE; + swizzle_y = I915_BIT_6_SWIZZLE_NONE; + } } } else if (IS_GEN5(dev)) { /* On Ironlake whatever DRAM config, GPU always do diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 103972c131b6..fb9a43480680 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2359,6 +2359,7 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc, struct intel_plane_config *plane_config) { struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *c; struct intel_crtc *i; struct drm_i915_gem_object *obj; @@ -2390,6 +2391,9 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc, continue; if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) { + if (obj->tiling_mode != I915_TILING_NONE) + dev_priv->preserve_bios_swizzle = true; + drm_framebuffer_reference(c->primary->fb); intel_crtc->base.primary->fb = c->primary->fb; obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); -- GitLab From e6b2627c6a8b25afc85649b54987b4bea27875b1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 Oct 2014 17:53:33 +0300 Subject: [PATCH 1178/9457] drm/i915: spt does not have pch backlight override bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPT is always in the PCH override mode, and the bit MBZ. Only set override on LPT. v2: check for PCH version (Ville) Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e3def5ad4a77..e18b3f49074c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -775,8 +775,9 @@ static void bdw_enable_backlight(struct intel_connector *connector) if (panel->backlight.active_low_pwm) pch_ctl1 |= BLM_PCH_POLARITY; - /* BDW always uses the pch pwm controls. */ - pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; + /* After LPT, override is the default. */ + if (HAS_PCH_LPT(dev_priv)) + pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); POSTING_READ(BLC_PWM_PCH_CTL1); -- GitLab From 2ebfaf5f10c6f00d4232f741c82c421eca8ae784 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 15 Oct 2014 14:15:04 -0300 Subject: [PATCH 1179/9457] drm/i915: call drm_vblank_cleanup() earlier at unload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In its current place, it just segfaults while trying to access the CRTC structures: [ 9132.421681] Call Trace: [ 9132.421707] [] i915_get_crtc_scanoutpos+0x1e8/0x220 [i915] [ 9132.421727] [] drm_calc_vbltimestamp_from_scanoutpos+0x94/0x330 [drm] [ 9132.421744] [] ?vblank_disable_and_save+0x40/0x1e0 [drm] [ 9132.421769] [] i915_get_vblank_timestamp+0x68/0xb0 [i915] [ 9132.421786] [] drm_get_last_vbltimestamp+0x44/0x80 [drm] [ 9132.421801] [] vblank_disable_and_save+0x1a6/0x1e0 [drm] [ 9132.421817] [] drm_vblank_cleanup+0x61/0xa0 [drm] [ 9132.421849] [] i915_driver_unload+0xde/0x290 [i915] [ 9132.421867] [] drm_dev_unregister+0x24/0xb0 [drm] [ 9132.421884] [] drm_put_dev+0x1e/0x70 [drm] [ 9132.421901] [] i915_pci_remove+0x10/0x20 [i915] [ 9132.421910] [] pci_device_remove+0x36/0xb0 [ 9132.421920] [] __device_release_driver+0x7a/0xf0 [ 9132.421928] [] driver_detach+0xb8/0xc0 [ 9132.421936] [] bus_remove_driver+0x4a/0xb0 [ 9132.421944] [] driver_unregister+0x27/0x50 [ 9132.421953] [] pci_unregister_driver+0x25/0x70 [ 9132.421971] [] drm_pci_exit+0x78/0xa0 [drm] [ 9132.422000] [] i915_exit+0x20/0x94e [i915] [ 9132.422009] [] SyS_delete_module+0x13c/0x1f0 [ 9132.422019] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 9132.422028] [] system_call_fastpath+0x16/0x1b This means it has to be before intel_modeset_cleanup, which cleans the CRTC structures. But if we move it to before intel_fbdev_fini(), we get WARNs because intel_fbdev_fini() still tries to use the vblanks, so the only acceptable point for drm_vblank_cleanup() seems to be this place. Related commit: commit cbb47d179fb345c579cd8cd884693903fceed26a Author: Chris Wilson Date: Mon Sep 23 17:33:20 2013 -0300 drm/i915: Add some missing steps to i915_driver_load error path Testsuite: igt/drv_module_reload Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77511 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83484 Signed-off-by: Paulo Zanoni Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 85d14e169409..1b398070b230 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1853,8 +1853,12 @@ int i915_driver_unload(struct drm_device *dev) acpi_video_unregister(); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) intel_fbdev_fini(dev); + + drm_vblank_cleanup(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_modeset_cleanup(dev); /* @@ -1895,8 +1899,6 @@ int i915_driver_unload(struct drm_device *dev) i915_free_hws(dev); } - drm_vblank_cleanup(dev); - intel_teardown_gmbus(dev); intel_teardown_mchbar(dev); -- GitLab From 8c740dcea254a1472df2c0ac5ac585412a2507ec Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 17 Oct 2014 18:42:03 -0300 Subject: [PATCH 1180/9457] drm/i915: disable IPS while getting the pipe CRCs. For some yet-undiscovered reason, when IPS gets enabled, the pipe CRC changes. Since hsw_enable_ips() doesn't really guarantees to enable IPS (it depends on package C-states), we can't really predict if IPS is enabled or disabled while running our CRC tests, so let's just completely disable IPS while pipe CRCs are being used. If we find a way to make IPS not change the pipe CRC result, we may want to fix IPS and then revert this patch. While this doesn't happen, let's merge this patch, so every IGT test relying on the CRCs can work on pipe A. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=72864 Testcase: igt/kms_cursor_crc (and others) Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6f8c9d780632..1e7a7c68deb7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3255,6 +3255,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; + struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, + pipe)); u32 val = 0; /* shut up gcc */ int ret; @@ -3290,6 +3292,14 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, if (!pipe_crc->entries) return -ENOMEM; + /* + * When IPS gets enabled, the pipe CRC changes. Since IPS gets + * enabled and disabled dynamically based on package C states, + * user space can't make reliable use of the CRCs, so let's just + * completely disable it. + */ + hsw_disable_ips(crtc); + spin_lock_irq(&pipe_crc->lock); pipe_crc->head = 0; pipe_crc->tail = 0; @@ -3328,6 +3338,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, vlv_undo_pipe_scramble_reset(dev, pipe); else if (IS_HASWELL(dev) && pipe == PIPE_A) hsw_undo_trans_edp_pipe_A_crc_wa(dev); + + hsw_enable_ips(crtc); } return 0; -- GitLab From 0039a4b357477bd8bcd495e4160974c71657b3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 20:52:30 +0300 Subject: [PATCH 1181/9457] drm/i915: Don't claim that we're resetting PCH ADPA register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_crt_reset() resets the ADPA register on all gen5+ platforms. However the debug message claims it's touching the PCH ADPA register which is clearly not what it does on VLV. Drop the PCH part from the debug message. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index dacaad5f4e34..a9af9a4866db 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -775,7 +775,7 @@ static void intel_crt_reset(struct drm_connector *connector) I915_WRITE(crt->adpa_reg, adpa); POSTING_READ(crt->adpa_reg); - DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); + DRM_DEBUG_KMS("crt adpa set to 0x%x\n", adpa); crt->force_hotplug_required = 1; } -- GitLab From 142d2eca356af6744c7e4bb577c3dfaadee486fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 20:52:32 +0300 Subject: [PATCH 1182/9457] drm/i915: Fix chv PCS DW11 register defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I managed to fumble the per spline PCS DW11 register defines in: commit 570e2a747bc06cd8620662c5125ec2dc964c511b Author: Ville Syrjälä Date: Mon Aug 18 14:42:46 2014 +0300 drm/i915: Clear TX FIFO reset master override bits on chv Fortunately the bit in DW0 that was cleared due to this didn't have any effect as long as the bit we meant to clear was already zero. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula [danvet: Fix commit ref as pointed out by Jani.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6db369a91ee9..46cfbc7466ef 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -883,8 +883,8 @@ enum punit_power_well { #define _VLV_PCS23_DW11_CH0 0x042c #define _VLV_PCS01_DW11_CH1 0x262c #define _VLV_PCS23_DW11_CH1 0x282c -#define VLV_PCS01_DW11(ch) _PORT(ch, _VLV_PCS01_DW0_CH0, _VLV_PCS01_DW0_CH1) -#define VLV_PCS23_DW11(ch) _PORT(ch, _VLV_PCS23_DW0_CH0, _VLV_PCS23_DW0_CH1) +#define VLV_PCS01_DW11(ch) _PORT(ch, _VLV_PCS01_DW11_CH0, _VLV_PCS01_DW11_CH1) +#define VLV_PCS23_DW11(ch) _PORT(ch, _VLV_PCS23_DW11_CH0, _VLV_PCS23_DW11_CH1) #define _VLV_PCS_DW12_CH0 0x8230 #define _VLV_PCS_DW12_CH1 0x8430 -- GitLab From fc0412ec0ff5aa7eef694ccde47606caa7c089e0 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Thu, 16 Oct 2014 16:13:38 +0100 Subject: [PATCH 1183/9457] drm/i915: add runtime PM get/put call in i915_execlists Otherwise we will get WARNs when we read context status registers and the machine is suspended. Testcase: igt/pm_rpm/debugfs-read Signed-off-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1e7a7c68deb7..e60d5c2f4a35 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1848,6 +1848,8 @@ static int i915_execlists(struct seq_file *m, void *data) if (ret) return ret; + intel_runtime_pm_get(dev_priv); + for_each_ring(ring, dev_priv, ring_id) { struct intel_ctx_submit_request *head_req = NULL; int count = 0; @@ -1899,6 +1901,7 @@ static int i915_execlists(struct seq_file *m, void *data) seq_putc(m, '\n'); } + intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); return 0; -- GitLab From f7f3d48ac858e4d2f0c71f8479d4ea022a35dd9c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Oct 2014 11:06:44 +0200 Subject: [PATCH 1184/9457] drm/i915: Fold in intel_mst_port_dp_detect The indirection here seems to serve no purpose. Probably leftovers from earlier revisions. Spotted while trying to review some mst patches. Cc: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp_mst.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index d9a7a7865f66..b03fa9026a9c 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -278,7 +278,7 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) } static enum drm_connector_status -intel_mst_port_dp_detect(struct drm_connector *connector) +intel_dp_mst_detect(struct drm_connector *connector, bool force) { struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; @@ -286,14 +286,6 @@ intel_mst_port_dp_detect(struct drm_connector *connector) return drm_dp_mst_detect_port(&intel_dp->mst_mgr, intel_connector->port); } -static enum drm_connector_status -intel_dp_mst_detect(struct drm_connector *connector, bool force) -{ - enum drm_connector_status status; - status = intel_mst_port_dp_detect(connector); - return status; -} - static int intel_dp_mst_set_property(struct drm_connector *connector, struct drm_property *property, -- GitLab From 5e56ba45053ab5d7a77b60924e7a15cbbb11dcad Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 17 Oct 2014 08:05:08 -0700 Subject: [PATCH 1185/9457] drm/i915/chv: Use 16 and 32 for low and high drain latency precision. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current chv spec teels we can only use either 16 or 32 bits as precision. Although in the past VLV went from 16/32 to 32/64 and spec might not be updated, these precision values brings stability and fixes some issues Wayne was facing. Cc: Wayne Boyer Cc: Ville Syrjälä Signed-off-by: Rodrigo Vivi Tested-by: Wayne Boyer Reviewed-by: Ville Syrjälä [danvet: Sprinkle const as requested by Ville.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 13 ++++++----- drivers/gpu/drm/i915/intel_pm.c | 40 ++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 46cfbc7466ef..1e6f7fb15672 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4054,17 +4054,18 @@ enum punit_power_well { #define DSPFW_PLANEA_WM1_HI_MASK (1<<0) /* drain latency register values*/ +#define DRAIN_LATENCY_PRECISION_16 16 #define DRAIN_LATENCY_PRECISION_32 32 #define DRAIN_LATENCY_PRECISION_64 64 #define VLV_DDL(pipe) (VLV_DISPLAY_BASE + 0x70050 + 4 * (pipe)) -#define DDL_CURSOR_PRECISION_64 (1<<31) -#define DDL_CURSOR_PRECISION_32 (0<<31) +#define DDL_CURSOR_PRECISION_HIGH (1<<31) +#define DDL_CURSOR_PRECISION_LOW (0<<31) #define DDL_CURSOR_SHIFT 24 -#define DDL_SPRITE_PRECISION_64(sprite) (1<<(15+8*(sprite))) -#define DDL_SPRITE_PRECISION_32(sprite) (0<<(15+8*(sprite))) +#define DDL_SPRITE_PRECISION_HIGH(sprite) (1<<(15+8*(sprite))) +#define DDL_SPRITE_PRECISION_LOW(sprite) (0<<(15+8*(sprite))) #define DDL_SPRITE_SHIFT(sprite) (8+8*(sprite)) -#define DDL_PLANE_PRECISION_64 (1<<7) -#define DDL_PLANE_PRECISION_32 (0<<7) +#define DDL_PLANE_PRECISION_HIGH (1<<7) +#define DDL_PLANE_PRECISION_LOW (0<<7) #define DDL_PLANE_SHIFT 0 #define DRAIN_LATENCY_MASK 0x7f diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 23d331884944..7a69eba533c7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1345,6 +1345,7 @@ static bool vlv_compute_drain_latency(struct drm_crtc *crtc, int *prec_mult, int *drain_latency) { + struct drm_device *dev = crtc->dev; int entries; int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; @@ -1355,8 +1356,12 @@ static bool vlv_compute_drain_latency(struct drm_crtc *crtc, return false; entries = DIV_ROUND_UP(clock, 1000) * pixel_size; - *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : - DRAIN_LATENCY_PRECISION_32; + if (IS_CHERRYVIEW(dev)) + *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_32 : + DRAIN_LATENCY_PRECISION_16; + else + *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : + DRAIN_LATENCY_PRECISION_32; *drain_latency = (64 * (*prec_mult) * 4) / entries; if (*drain_latency > DRAIN_LATENCY_MASK) @@ -1375,15 +1380,18 @@ static bool vlv_compute_drain_latency(struct drm_crtc *crtc, static void vlv_update_drain_latency(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pixel_size; int drain_latency; enum pipe pipe = intel_crtc->pipe; int plane_prec, prec_mult, plane_dl; + const int high_precision = IS_CHERRYVIEW(dev) ? + DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_64; - plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_64 | - DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_64 | + plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_HIGH | + DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_HIGH | (DRAIN_LATENCY_MASK << DDL_CURSOR_SHIFT)); if (!intel_crtc_active(crtc)) { @@ -1394,9 +1402,9 @@ static void vlv_update_drain_latency(struct drm_crtc *crtc) /* Primary plane Drain Latency */ pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ if (vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { - plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? - DDL_PLANE_PRECISION_64 : - DDL_PLANE_PRECISION_32; + plane_prec = (prec_mult == high_precision) ? + DDL_PLANE_PRECISION_HIGH : + DDL_PLANE_PRECISION_LOW; plane_dl |= plane_prec | drain_latency; } @@ -1408,9 +1416,9 @@ static void vlv_update_drain_latency(struct drm_crtc *crtc) /* Program cursor DL only if it is enabled */ if (intel_crtc->cursor_base && vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { - plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? - DDL_CURSOR_PRECISION_64 : - DDL_CURSOR_PRECISION_32; + plane_prec = (prec_mult == high_precision) ? + DDL_CURSOR_PRECISION_HIGH : + DDL_CURSOR_PRECISION_LOW; plane_dl |= plane_prec | (drain_latency << DDL_CURSOR_SHIFT); } @@ -1578,15 +1586,17 @@ static void valleyview_update_sprite_wm(struct drm_plane *plane, int plane_prec; int sprite_dl; int prec_mult; + const int high_precision = IS_CHERRYVIEW(dev) ? + DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_64; - sprite_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_SPRITE_PRECISION_64(sprite) | + sprite_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_SPRITE_PRECISION_HIGH(sprite) | (DRAIN_LATENCY_MASK << DDL_SPRITE_SHIFT(sprite))); if (enabled && vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { - plane_prec = (prec_mult == DRAIN_LATENCY_PRECISION_64) ? - DDL_SPRITE_PRECISION_64(sprite) : - DDL_SPRITE_PRECISION_32(sprite); + plane_prec = (prec_mult == high_precision) ? + DDL_SPRITE_PRECISION_HIGH(sprite) : + DDL_SPRITE_PRECISION_LOW(sprite); sprite_dl |= plane_prec | (drain_latency << DDL_SPRITE_SHIFT(sprite)); } -- GitLab From 6d729bff304f3b81062e21cd333a639fda4244b3 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 7 Oct 2014 16:11:11 -0300 Subject: [PATCH 1186/9457] drm/i915: only run hsw_power_well_post_enable when really needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only run it after we actually enable the power well. When we're booting the machine there are cases where we run hsw_power_well_post_enable without really needing, and even though this is not causing any real bugs, it is unneeded and causes confusion to people debugging interrupts. Signed-off-by: Paulo Zanoni Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 36749b91d28e..39c33e0a753c 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -221,9 +221,9 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED), 20)) DRM_ERROR("Timeout enabling power well\n"); + hsw_power_well_post_enable(dev_priv); } - hsw_power_well_post_enable(dev_priv); } else { if (enable_requested) { I915_WRITE(HSW_PWR_WELL_DRIVER, 0); -- GitLab From 43d942a780efe72b426d30dc112f5eb2fc7eec3a Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Thu, 23 Oct 2014 15:28:24 +0800 Subject: [PATCH 1187/9457] drm/i915: use macros to assign mmio access functions This is beautification prep work since vgt will add even more special cases. With these macros it's much easier to see what's going on really. Signed-off-by: Yu Zhang [danvet: #undef the temporary macros after the function again. And write a commit message.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 78 +++++++++++------------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0b0f4f85c4f2..964805ce4d2c 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -823,6 +823,22 @@ __gen4_write(64) #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER +#define ASSIGN_WRITE_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_writeb = x##_write8; \ + dev_priv->uncore.funcs.mmio_writew = x##_write16; \ + dev_priv->uncore.funcs.mmio_writel = x##_write32; \ + dev_priv->uncore.funcs.mmio_writeq = x##_write64; \ +} while (0) + +#define ASSIGN_READ_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_readb = x##_read8; \ + dev_priv->uncore.funcs.mmio_readw = x##_read16; \ + dev_priv->uncore.funcs.mmio_readl = x##_read32; \ + dev_priv->uncore.funcs.mmio_readq = x##_read64; \ +} while (0) + void intel_uncore_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -879,76 +895,42 @@ void intel_uncore_init(struct drm_device *dev) switch (INTEL_INFO(dev)->gen) { default: if (IS_CHERRYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_writeb = chv_write8; - dev_priv->uncore.funcs.mmio_writew = chv_write16; - dev_priv->uncore.funcs.mmio_writel = chv_write32; - dev_priv->uncore.funcs.mmio_writeq = chv_write64; - dev_priv->uncore.funcs.mmio_readb = chv_read8; - dev_priv->uncore.funcs.mmio_readw = chv_read16; - dev_priv->uncore.funcs.mmio_readl = chv_read32; - dev_priv->uncore.funcs.mmio_readq = chv_read64; + ASSIGN_WRITE_MMIO_VFUNCS(chv); + ASSIGN_READ_MMIO_VFUNCS(chv); } else { - dev_priv->uncore.funcs.mmio_writeb = gen8_write8; - dev_priv->uncore.funcs.mmio_writew = gen8_write16; - dev_priv->uncore.funcs.mmio_writel = gen8_write32; - dev_priv->uncore.funcs.mmio_writeq = gen8_write64; - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + ASSIGN_WRITE_MMIO_VFUNCS(gen8); + ASSIGN_READ_MMIO_VFUNCS(gen6); } break; case 7: case 6: if (IS_HASWELL(dev)) { - dev_priv->uncore.funcs.mmio_writeb = hsw_write8; - dev_priv->uncore.funcs.mmio_writew = hsw_write16; - dev_priv->uncore.funcs.mmio_writel = hsw_write32; - dev_priv->uncore.funcs.mmio_writeq = hsw_write64; + ASSIGN_WRITE_MMIO_VFUNCS(hsw); } else { - dev_priv->uncore.funcs.mmio_writeb = gen6_write8; - dev_priv->uncore.funcs.mmio_writew = gen6_write16; - dev_priv->uncore.funcs.mmio_writel = gen6_write32; - dev_priv->uncore.funcs.mmio_writeq = gen6_write64; + ASSIGN_WRITE_MMIO_VFUNCS(gen6); } if (IS_VALLEYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_readb = vlv_read8; - dev_priv->uncore.funcs.mmio_readw = vlv_read16; - dev_priv->uncore.funcs.mmio_readl = vlv_read32; - dev_priv->uncore.funcs.mmio_readq = vlv_read64; + ASSIGN_READ_MMIO_VFUNCS(vlv); } else { - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + ASSIGN_READ_MMIO_VFUNCS(gen6); } break; case 5: - dev_priv->uncore.funcs.mmio_writeb = gen5_write8; - dev_priv->uncore.funcs.mmio_writew = gen5_write16; - dev_priv->uncore.funcs.mmio_writel = gen5_write32; - dev_priv->uncore.funcs.mmio_writeq = gen5_write64; - dev_priv->uncore.funcs.mmio_readb = gen5_read8; - dev_priv->uncore.funcs.mmio_readw = gen5_read16; - dev_priv->uncore.funcs.mmio_readl = gen5_read32; - dev_priv->uncore.funcs.mmio_readq = gen5_read64; + ASSIGN_WRITE_MMIO_VFUNCS(gen5); + ASSIGN_READ_MMIO_VFUNCS(gen5); break; case 4: case 3: case 2: - dev_priv->uncore.funcs.mmio_writeb = gen4_write8; - dev_priv->uncore.funcs.mmio_writew = gen4_write16; - dev_priv->uncore.funcs.mmio_writel = gen4_write32; - dev_priv->uncore.funcs.mmio_writeq = gen4_write64; - dev_priv->uncore.funcs.mmio_readb = gen4_read8; - dev_priv->uncore.funcs.mmio_readw = gen4_read16; - dev_priv->uncore.funcs.mmio_readl = gen4_read32; - dev_priv->uncore.funcs.mmio_readq = gen4_read64; + ASSIGN_WRITE_MMIO_VFUNCS(gen4); + ASSIGN_READ_MMIO_VFUNCS(gen4); break; } } +#undef ASSIGN_WRITE_MMIO_VFUNCS +#undef ASSIGN_READ_MMIO_VFUNCS void intel_uncore_fini(struct drm_device *dev) { -- GitLab From 11b5d5112c51f8cf4ac51f9f063bb76992a5ebe7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 29 Sep 2014 15:31:26 +0200 Subject: [PATCH 1188/9457] drm/i915: Correctly reject invalid flags for wait_ioctl Not having checks for this isn't good. I've checked igt and libdrm and they all already clear flags properly. So we're lucky and should be able to sneak this ABI clarification in. Testcase: igt/gem_wait/invalid-flags Signed-off-by: Daniel Vetter Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85280 Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 895f9881f0aa..827edb589883 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2810,6 +2810,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) u32 seqno = 0; int ret = 0; + if (args->flags != 0) + return -EINVAL; + ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; -- GitLab From 4398ad454a976d69a30fd76aee21fc82b9489054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 23 Oct 2014 07:41:34 -0700 Subject: [PATCH 1189/9457] drm/i915: Add rotation support for cursor plane (v5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cursor plane also supports 180 degree rotation. Add a new "cursor-rotation" property on the crtc which controls this. Unlike sprites, the cursor has a fixed size, so if you have a small cursor image with the rest of the bo filled by transparent pixels, simply flipping the rotation property will cause the visible part of the cursor to shift. This is something to keep in mind when using cursor rotation. v2: Fix gen4/vlv by offsetting the base address appropriately v3: Removing cursor-rotation property and using rotation property on cursor plane. v4: Changing the author name back to Ville. v5 (by Matt Roper): Slight tweaking to apply against latest di-nightly codebase. Cc: Sagar Kamble Signed-off-by: Ville Syrjälä Signed-off-by: Sonika Jindal Reviewed-by: Matt Roper Tested-by (IVB): Matt Roper Signed-off-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1e6f7fb15672..ea84e1ec5e5f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4208,6 +4208,7 @@ enum punit_power_well { #define MCURSOR_PIPE_A 0x00 #define MCURSOR_PIPE_B (1 << 28) #define MCURSOR_GAMMA_ENABLE (1 << 26) +#define CURSOR_ROTATE_180 (1<<15) #define CURSOR_TRICKLE_FEED_DISABLE (1 << 14) #define _CURABASE 0x70084 #define _CURAPOS 0x70088 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fb9a43480680..1d2fa7f4523e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8343,6 +8343,9 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) cntl |= CURSOR_PIPE_CSC_ENABLE; } + if (to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180)) + cntl |= CURSOR_ROTATE_180; + if (intel_crtc->cursor_cntl != cntl) { I915_WRITE(CURCNTR(pipe), cntl); POSTING_READ(CURCNTR(pipe)); @@ -8400,6 +8403,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, I915_WRITE(CURPOS(pipe), pos); + /* ILK+ do this automagically */ + if (HAS_GMCH_DISPLAY(dev) && + to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180)) { + base += (intel_crtc->cursor_height * + intel_crtc->cursor_width - 1) * 4; + } + if (IS_845G(dev) || IS_I865G(dev)) i845_update_cursor(crtc, base); else @@ -12010,6 +12020,7 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = { .update_plane = intel_cursor_plane_update, .disable_plane = intel_cursor_plane_disable, .destroy = intel_plane_destroy, + .set_property = intel_plane_set_property, }; static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, @@ -12025,12 +12036,26 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, cursor->max_downscale = 1; cursor->pipe = pipe; cursor->plane = pipe; + cursor->rotation = BIT(DRM_ROTATE_0); drm_universal_plane_init(dev, &cursor->base, 0, &intel_cursor_plane_funcs, intel_cursor_formats, ARRAY_SIZE(intel_cursor_formats), DRM_PLANE_TYPE_CURSOR); + + if (INTEL_INFO(dev)->gen >= 4) { + if (!dev->mode_config.rotation_property) + dev->mode_config.rotation_property = + drm_mode_create_rotation_property(dev, + BIT(DRM_ROTATE_0) | + BIT(DRM_ROTATE_180)); + if (dev->mode_config.rotation_property) + drm_object_attach_property(&cursor->base.base, + dev->mode_config.rotation_property, + cursor->rotation); + } + return &cursor->base; } -- GitLab From 22a916aaa187946e8df724ab7838a0c13b45a9f4 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Wed, 22 Oct 2014 18:59:52 +0100 Subject: [PATCH 1190/9457] drm/i915: Emit even number of dwords when emitting LRIs The number of DWords should be even when doing ring emits as command sequences require QWord alignment. There was some discussion about the maximum length of the MI_LRI command. Quoting Mika "I did some test with bdw: "The maximum is 128 writes, resulting the 8 bit length field of the command being 0xff, thus following the spec. The 128'th write went through. "Perhaps the max command length is then less in older gens? "Perhaps WARN_ON(x > 128) in MI_LOAD_REGISTER_IMM would be in place but one needs minor tweak to command parser a bit also then. #define I915_MAX_WA_REGS 16 keeps us safe for now atleast." Ville commented that on pre-gen6 the length field seems to be restricted to 0x3f though. So for all cases we should be ok. v2: user LRI variant that can write multiple regs in one go (Damien). We can simply insert one NOP at the end instead of one per register write. Cc: Mika Kuoppala Signed-off-by: Arun Siluvery Reviewed-by: Damien Lespiau [danvet: Add a summary of the MI_LRI length discussion.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5f935d4dfb6a..603148e6dbc3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -680,15 +680,16 @@ static int intel_ring_workarounds_emit(struct intel_engine_cs *ring) if (ret) return ret; - ret = intel_ring_begin(ring, w->count * 3); + ret = intel_ring_begin(ring, (w->count * 2 + 2)); if (ret) return ret; + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(w->count)); for (i = 0; i < w->count; i++) { - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); intel_ring_emit(ring, w->reg[i].addr); intel_ring_emit(ring, w->reg[i].value); } + intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); -- GitLab From c3c09c9522f806bd12d0c85dfdb8d2b8578d0da1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:15 +0300 Subject: [PATCH 1191/9457] drm/i915: factor out i915_drm_suspend_late MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed by an upcoming patch fixing the switcheroo/legacy suspend paths. No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ffd672ef245c..753d44a10f12 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -630,6 +630,25 @@ static int i915_drm_freeze(struct drm_device *dev) return 0; } +static int i915_drm_suspend_late(struct drm_device *drm_dev) +{ + struct drm_i915_private *dev_priv = drm_dev->dev_private; + int ret; + + ret = intel_suspend_complete(dev_priv); + + if (ret) { + DRM_ERROR("Suspend complete failed: %d\n", ret); + + return ret; + } + + pci_disable_device(drm_dev->pdev); + pci_set_power_state(drm_dev->pdev, PCI_D3hot); + + return 0; +} + int i915_suspend(struct drm_device *dev, pm_message_t state) { int error; @@ -955,8 +974,6 @@ static int i915_pm_suspend_late(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct drm_i915_private *dev_priv = drm_dev->dev_private; - int ret; /* * We have a suspedn ordering issue with the snd-hda driver also @@ -970,16 +987,7 @@ static int i915_pm_suspend_late(struct device *dev) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - ret = intel_suspend_complete(dev_priv); - - if (ret) - DRM_ERROR("Suspend complete failed: %d\n", ret); - else { - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - } - - return ret; + return i915_drm_suspend_late(drm_dev); } static int i915_pm_resume_early(struct device *dev) -- GitLab From f2888fabfbbccc0acb4d21713b91d557edc1e64f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:16 +0300 Subject: [PATCH 1192/9457] drm/i915: unify legacy S3 suspend and S4 freeze handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i915_suspend() is called from the DRM legacy S3 suspend/S4 freeze paths and the switcheroo suspend path. For switcheroo we only ever need to perform a full suspend (PM_EVENT_SUSPEND) and for the DRM legacy path we can handle the S4 freeze (PM_EVENT_FREEZE) the same way as S3 suspend. The only difference atm between suspend and freeze is that during freeze we don't disable the PCI device, but there is no reason why we can't do so. So unify the two cases to reduce complexity. Note that for the DRM legacy case the thaw event is not handled, so we disable the display before creating the hibernation image and it won't get re-enabled until reboot. We could fix this leaving the display enabled for the image creation/writing (if we care enough about UMS), but this can be done as a follow-up. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 753d44a10f12..56c75706055c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -670,11 +670,9 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) if (error) return error; - if (state.event == PM_EVENT_SUSPEND) { - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); - } + /* Shut down the device */ + pci_disable_device(dev->pdev); + pci_set_power_state(dev->pdev, PCI_D3hot); return 0; } -- GitLab From 50a0072f3829d36767f3359649d224f18f7987f7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:17 +0300 Subject: [PATCH 1193/9457] drm/i915: propagate error from legacy resume handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 56c75706055c..524c3dfed380 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -810,10 +810,13 @@ int i915_resume(struct drm_device *dev) static int i915_resume_legacy(struct drm_device *dev) { - i915_resume_early(dev); - i915_resume(dev); + int ret; - return 0; + ret = i915_resume_early(dev); + if (ret) + return ret; + + return i915_resume(dev); } /** -- GitLab From 5a17514ed924201f1465e4a2f5209bdb192d8dff Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:18 +0300 Subject: [PATCH 1194/9457] drm/i915: vlv: fix switcheroo/legacy suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During switcheroo/legacy suspend we don't call the suspend_late handler but when resuming afterwards we call resume_early. This happened to work so far, since suspend_late only disabled the PCI device. This changed in commit 016970beb05da6285c2f3ed2bee1c676cb75972e Author: Sagar Kamble Date: Wed Aug 13 23:07:06 2014 +0530 drm/i915: Sharing platform specific sequence between runtime and system susp after which we also saved/restored the VLV Gunit HW state in suspend_late/resume_early. So now since we don't save the state during suspend a following resume will restore a corrupted state. Fix this by calling the suspend_late handler during both switcheroo and legacy suspend. CC: Sagar Kamble Signed-off-by: Imre Deak Reviewed-by: Sagar Kamble Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 524c3dfed380..203bd820d5f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -670,11 +670,7 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) if (error) return error; - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); - - return 0; + return i915_drm_suspend_late(dev); } static int i915_drm_thaw_early(struct drm_device *dev) @@ -790,7 +786,7 @@ static int i915_resume_early(struct drm_device *dev) return i915_drm_thaw_early(dev); } -int i915_resume(struct drm_device *dev) +static int i915_drm_resume(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -816,7 +812,12 @@ static int i915_resume_legacy(struct drm_device *dev) if (ret) return ret; - return i915_resume(dev); + return i915_drm_resume(dev); +} + +int i915_resume(struct drm_device *dev) +{ + return i915_resume_legacy(dev); } /** @@ -1004,7 +1005,7 @@ static int i915_pm_resume(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - return i915_resume(drm_dev); + return i915_drm_resume(drm_dev); } static int i915_pm_freeze(struct device *dev) -- GitLab From 097dd83763bfe8e8643957c0b90819742fb01cd9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:19 +0300 Subject: [PATCH 1195/9457] drm/i915: fix S4 suspend while switcheroo state is off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the device is suspended already through the switcheroo interface we shouldn't suspend it again or resume it after suspend. We have the corresponding check for S3 suspend already, add it for all the other S3 and S4 handlers. Also move the check from i915_resume_early() to i915_resume_legacy(), so that it's done in the high level handler for all PM events. v2: - fix the resume path too, we don't need to special case there DRM_SWITCH_POWER_OFF with the device being enabled (in which case we'd have to disable the device), since that never happens (Ville) Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 203bd820d5f7..69936322f87d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -766,9 +766,6 @@ static int i915_drm_thaw(struct drm_device *dev) static int i915_resume_early(struct drm_device *dev) { - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - /* * We have a resume ordering issue with the snd-hda driver also * requiring our device to be power up. Due to the lack of a @@ -808,6 +805,9 @@ static int i915_resume_legacy(struct drm_device *dev) { int ret; + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + ret = i915_resume_early(dev); if (ret) return ret; @@ -997,6 +997,9 @@ static int i915_pm_resume_early(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_resume_early(drm_dev); } @@ -1005,6 +1008,9 @@ static int i915_pm_resume(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_drm_resume(drm_dev); } @@ -1018,6 +1024,9 @@ static int i915_pm_freeze(struct device *dev) return -ENODEV; } + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_drm_freeze(drm_dev); } @@ -1027,6 +1036,9 @@ static int i915_pm_freeze_late(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); struct drm_i915_private *dev_priv = drm_dev->dev_private; + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return intel_suspend_complete(dev_priv); } @@ -1035,6 +1047,9 @@ static int i915_pm_thaw_early(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_drm_thaw_early(drm_dev); } @@ -1043,6 +1058,9 @@ static int i915_pm_thaw(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_drm_thaw(drm_dev); } @@ -1051,6 +1069,9 @@ static int i915_pm_poweroff(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + return i915_drm_freeze(drm_dev); } -- GitLab From f4a12ead50580c17c3641ac1a453e68b5a5195dd Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:20 +0300 Subject: [PATCH 1196/9457] drm/i915: remove unused restore_gtt_mappings optimization during suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The logic to skip restoring GTT mappings was added to speed up suspend/resume, but not on old GENs where not restoring them caused problems. The check for old GENs is based on the existence of OpRegion, but this doesn't work since opregion is initialized only after the check. So we end up always restoring the mappings. On my BYT - which has OpRegion - skipping restoring the mappings during suspend doesn't work, I get a GPU hang after resume. Also the logic of when to allow the optimization during S4 is reversed: we should allow it during S4 thaw but not during S4 restore, but atm we have it the other way around in the code. Since correctness wins over optimal code and since the optimization wasn't used anyway I decided not to try to fix it at this point, but just remove it. This allows us to unify the S3 and S4 handlers in the following patches. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 69936322f87d..9c934bec3ef1 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -689,12 +689,11 @@ static int i915_drm_thaw_early(struct drm_device *dev) return ret; } -static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) +static int __i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (drm_core_check_feature(dev, DRIVER_MODESET) && - restore_gtt_mappings) { + if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); i915_gem_restore_gtt_mappings(dev); mutex_unlock(&dev->struct_mutex); @@ -761,7 +760,7 @@ static int i915_drm_thaw(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) i915_check_and_clear_faults(dev); - return __i915_drm_thaw(dev, true); + return __i915_drm_thaw(dev); } static int i915_resume_early(struct drm_device *dev) @@ -785,15 +784,9 @@ static int i915_resume_early(struct drm_device *dev) static int i915_drm_resume(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; int ret; - /* - * Platforms with opregion should have sane BIOS, older ones (gen3 and - * earlier) need to restore the GTT mappings since the BIOS might clear - * all our scratch PTEs. - */ - ret = __i915_drm_thaw(dev, !dev_priv->opregion.header); + ret = __i915_drm_thaw(dev); if (ret) return ret; -- GitLab From ed49388384b19ed37567053de7b4087ba990813e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:21 +0300 Subject: [PATCH 1197/9457] drm/i915: check for GT faults in all resume handlers and driver load time Checking for GT faults is not specific in any way to S4 thaw, so do it also during S3 resume, S4 restore and driver load time. This allows us to unify the Sx handlers in an upcoming patch. v2: - move the check to intel_uncore_early_sanitize(), so we check at driver load time too (Chris) Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 3 --- drivers/gpu/drm/i915/intel_uncore.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9c934bec3ef1..d0f721fb25ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -757,9 +757,6 @@ static int __i915_drm_thaw(struct drm_device *dev) static int i915_drm_thaw(struct drm_device *dev) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) - i915_check_and_clear_faults(dev); - return __i915_drm_thaw(dev); } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 964805ce4d2c..94276419c13f 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -360,7 +360,8 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } -void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) +static void __intel_uncore_early_sanitize(struct drm_device *dev, + bool restore_forcewake) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -386,6 +387,12 @@ void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) intel_uncore_forcewake_reset(dev, restore_forcewake); } +void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) +{ + __intel_uncore_early_sanitize(dev, restore_forcewake); + i915_check_and_clear_faults(dev); +} + void intel_uncore_sanitize(struct drm_device *dev) { /* BIOS often leaves RC6 enabled, but disable it for hw init */ @@ -846,7 +853,7 @@ void intel_uncore_init(struct drm_device *dev) setup_timer(&dev_priv->uncore.force_wake_timer, gen6_force_wake_timer, (unsigned long)dev_priv); - intel_uncore_early_sanitize(dev, false); + __intel_uncore_early_sanitize(dev, false); if (IS_VALLEYVIEW(dev)) { dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; @@ -928,6 +935,8 @@ void intel_uncore_init(struct drm_device *dev) ASSIGN_READ_MMIO_VFUNCS(gen4); break; } + + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS #undef ASSIGN_READ_MMIO_VFUNCS -- GitLab From ee6f280e7895c838d90e8ef19ba737c8003ae85d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:22 +0300 Subject: [PATCH 1198/9457] drm/i915: enable output polling during S4 thaw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid processing hotplug events we disable connector polling for the duration of S3 suspend. We also disable it for S4 freeze, and keep it disabled after S4 thaw. This won't prevent though hotplug processing, since we re-enable interrupts anyway. There is also no need to prevent it at that time, since we reinitialize everything during thaw, so the device is in a consistent state. So to simplify things enable polling during thaw, which will allow us to handle S4 thaw the same way as S3 resume in an upcoming patch. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d0f721fb25ad..4524c615f0a7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -752,6 +752,8 @@ static int __i915_drm_thaw(struct drm_device *dev) intel_opregion_notify_adapter(dev, PCI_D0); + drm_kms_helper_poll_enable(dev); + return 0; } @@ -781,14 +783,7 @@ static int i915_resume_early(struct drm_device *dev) static int i915_drm_resume(struct drm_device *dev) { - int ret; - - ret = __i915_drm_thaw(dev); - if (ret) - return ret; - - drm_kms_helper_poll_enable(dev); - return 0; + return __i915_drm_thaw(dev); } static int i915_resume_legacy(struct drm_device *dev) -- GitLab From f2476ae65e6159b41168bc41c630e9fbb1d72dde Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:23 +0300 Subject: [PATCH 1199/9457] drm/i915: disable/re-enable PCI device around S4 freeze/thaw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already disable everything during S4 freeze, except the PCI device itself. There is no reason why we couldn't disable that too and doing so allows us to unify these handlers in the next patch with the corresponding S3 suspend/resume handlers. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4524c615f0a7..be4cb1d4f3e9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1019,12 +1019,11 @@ static int i915_pm_freeze_late(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct drm_i915_private *dev_priv = drm_dev->dev_private; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - return intel_suspend_complete(dev_priv); + return i915_drm_suspend_late(drm_dev); } static int i915_pm_thaw_early(struct device *dev) @@ -1035,7 +1034,7 @@ static int i915_pm_thaw_early(struct device *dev) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - return i915_drm_thaw_early(drm_dev); + return i915_resume_early(drm_dev); } static int i915_pm_thaw(struct device *dev) -- GitLab From 36d61e6751d16fa80a4355b9708ff24ab7536f89 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:24 +0300 Subject: [PATCH 1200/9457] drm/i915: unify S3 and S4 suspend/resume handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The S3 and S4 events are now handled the same way internally, there is no need to keep separate wrapper functions around them. Simply reuse the suspend/resume versions everywhere. No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 104 ++++++-------------------------- 1 file changed, 17 insertions(+), 87 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index be4cb1d4f3e9..2190d0f61018 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -673,22 +673,6 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) return i915_drm_suspend_late(dev); } -static int i915_drm_thaw_early(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - ret = intel_resume_prepare(dev_priv, false); - if (ret) - DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); - - intel_uncore_early_sanitize(dev, true); - intel_uncore_sanitize(dev); - intel_power_domains_init_hw(dev_priv); - - return ret; -} - static int __i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -757,13 +741,11 @@ static int __i915_drm_thaw(struct drm_device *dev) return 0; } -static int i915_drm_thaw(struct drm_device *dev) -{ - return __i915_drm_thaw(dev); -} - static int i915_resume_early(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + /* * We have a resume ordering issue with the snd-hda driver also * requiring our device to be power up. Due to the lack of a @@ -778,7 +760,15 @@ static int i915_resume_early(struct drm_device *dev) pci_set_master(dev->pdev); - return i915_drm_thaw_early(dev); + ret = intel_resume_prepare(dev_priv, false); + if (ret) + DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); + + intel_uncore_early_sanitize(dev, true); + intel_uncore_sanitize(dev); + intel_power_domains_init_hw(dev_priv); + + return ret; } static int i915_drm_resume(struct drm_device *dev) @@ -999,66 +989,6 @@ static int i915_pm_resume(struct device *dev) return i915_drm_resume(drm_dev); } -static int i915_pm_freeze(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (!drm_dev || !drm_dev->dev_private) { - dev_err(dev, "DRM not initialized, aborting suspend.\n"); - return -ENODEV; - } - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - return i915_drm_freeze(drm_dev); -} - -static int i915_pm_freeze_late(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - return i915_drm_suspend_late(drm_dev); -} - -static int i915_pm_thaw_early(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - return i915_resume_early(drm_dev); -} - -static int i915_pm_thaw(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - return i915_drm_thaw(drm_dev); -} - -static int i915_pm_poweroff(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - return i915_drm_freeze(drm_dev); -} - static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); @@ -1618,11 +1548,11 @@ static const struct dev_pm_ops i915_pm_ops = { .suspend_late = i915_pm_suspend_late, .resume_early = i915_pm_resume_early, .resume = i915_pm_resume, - .freeze = i915_pm_freeze, - .freeze_late = i915_pm_freeze_late, - .thaw_early = i915_pm_thaw_early, - .thaw = i915_pm_thaw, - .poweroff = i915_pm_poweroff, + .freeze = i915_pm_suspend, + .freeze_late = i915_pm_suspend_late, + .thaw_early = i915_pm_resume_early, + .thaw = i915_pm_resume, + .poweroff = i915_pm_suspend, .restore_early = i915_pm_resume_early, .restore = i915_pm_resume, .runtime_suspend = intel_runtime_suspend, -- GitLab From 5e365c391aeffe8b53d6952c28a68bd5fc856390 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:25 +0300 Subject: [PATCH 1201/9457] drm/i915: sanitize suspend/resume helper function names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By now the S4 freeze/thaw and S3 suspend/resume events are handled the same way, so we can rename the freeze/thaw internal helpers to suspend/resume accordingly to make clearer what the helpers do. Also rename i915_resume_early to i915_drm_resume_early aligning it with the rest of the helper names. No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2190d0f61018..8b2b34cc6552 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -554,7 +554,7 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv); static int intel_resume_prepare(struct drm_i915_private *dev_priv, bool rpm_resume); -static int i915_drm_freeze(struct drm_device *dev) +static int i915_drm_suspend(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc; @@ -666,14 +666,14 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - error = i915_drm_freeze(dev); + error = i915_drm_suspend(dev); if (error) return error; return i915_drm_suspend_late(dev); } -static int __i915_drm_thaw(struct drm_device *dev) +static int i915_drm_resume(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -741,7 +741,7 @@ static int __i915_drm_thaw(struct drm_device *dev) return 0; } -static int i915_resume_early(struct drm_device *dev) +static int i915_drm_resume_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -771,11 +771,6 @@ static int i915_resume_early(struct drm_device *dev) return ret; } -static int i915_drm_resume(struct drm_device *dev) -{ - return __i915_drm_thaw(dev); -} - static int i915_resume_legacy(struct drm_device *dev) { int ret; @@ -783,7 +778,7 @@ static int i915_resume_legacy(struct drm_device *dev) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - ret = i915_resume_early(dev); + ret = i915_drm_resume_early(dev); if (ret) return ret; @@ -944,7 +939,7 @@ static int i915_pm_suspend(struct device *dev) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - return i915_drm_freeze(drm_dev); + return i915_drm_suspend(drm_dev); } static int i915_pm_suspend_late(struct device *dev) @@ -975,7 +970,7 @@ static int i915_pm_resume_early(struct device *dev) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - return i915_resume_early(drm_dev); + return i915_drm_resume_early(drm_dev); } static int i915_pm_resume(struct device *dev) -- GitLab From da2bc1b9db3351addd293e5b82757efe1f77ed1d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:26 +0300 Subject: [PATCH 1202/9457] drm/i915: add poweroff_late handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The suspend_late handler saves some registers and powers off the device, so it doesn't have a big overhead. Calling it at S4 poweroff_late time makes the power off handling identical to the S3 suspend and S4 freeze handling, so do this for consistency. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8b2b34cc6552..808f6591317a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1548,6 +1548,7 @@ static const struct dev_pm_ops i915_pm_ops = { .thaw_early = i915_pm_resume_early, .thaw = i915_pm_resume, .poweroff = i915_pm_suspend, + .poweroff_late = i915_pm_suspend_late, .restore_early = i915_pm_resume_early, .restore = i915_pm_resume, .runtime_suspend = intel_runtime_suspend, -- GitLab From fc49b3da0e1f20484ac069982e2dcbf1a53f60af Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:27 +0300 Subject: [PATCH 1203/9457] drm/i915: unify switcheroo and legacy suspend/resume handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By now we handle switcheroo and legacy suspend/resume the same way, so no need to keep separate functions for them. No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 11 +++-------- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1b398070b230..9a7353302b3f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1275,12 +1275,12 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; /* i915 resume handler doesn't set to D0 */ pci_set_power_state(dev->pdev, PCI_D0); - i915_resume(dev); + i915_resume_legacy(dev); dev->switch_power_state = DRM_SWITCH_POWER_ON; } else { pr_err("switched off\n"); dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - i915_suspend(dev, pmm); + i915_suspend_legacy(dev, pmm); dev->switch_power_state = DRM_SWITCH_POWER_OFF; } } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 808f6591317a..bce58d395b28 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -649,7 +649,7 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev) return 0; } -int i915_suspend(struct drm_device *dev, pm_message_t state) +int i915_suspend_legacy(struct drm_device *dev, pm_message_t state) { int error; @@ -771,7 +771,7 @@ static int i915_drm_resume_early(struct drm_device *dev) return ret; } -static int i915_resume_legacy(struct drm_device *dev) +int i915_resume_legacy(struct drm_device *dev) { int ret; @@ -785,11 +785,6 @@ static int i915_resume_legacy(struct drm_device *dev) return i915_drm_resume(dev); } -int i915_resume(struct drm_device *dev) -{ - return i915_resume_legacy(dev); -} - /** * i915_reset - reset chip after a hang * @dev: drm device to reset @@ -1592,7 +1587,7 @@ static struct drm_driver driver = { .set_busid = drm_pci_set_busid, /* Used in place of i915_pm_ops for non-DRIVER_MODESET */ - .suspend = i915_suspend, + .suspend = i915_suspend_legacy, .resume = i915_resume_legacy, .device_is_agp = i915_driver_device_is_agp, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3212d62c3c64..059330c7027a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2221,8 +2221,8 @@ struct drm_i915_cmd_table { extern const struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; -extern int i915_suspend(struct drm_device *dev, pm_message_t state); -extern int i915_resume(struct drm_device *dev); +extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state); +extern int i915_resume_legacy(struct drm_device *dev); extern int i915_master_create(struct drm_device *dev, struct drm_master *master); extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); -- GitLab From 5545dbbfb3bb7a5ab5ced991e08d1c312326e843 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Oct 2014 19:23:28 +0300 Subject: [PATCH 1204/9457] drm/i915: add comments on what stage a given PM handler is called MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will hopefully make it easier to navigate the code without the need to consult the full PM documentation. v2: - add a comment that the freeze handler is also called after rebooting - add a comment that the thaw handler is also called to recover from errors (Ville) - add the PM event names (PMSG_THAW etc.) for reference (Ville) - add comments that s0ix can be handled both via system and runtime suspend (Ville) Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bce58d395b28..035ec94ca3c7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1534,10 +1534,30 @@ static int intel_resume_prepare(struct drm_i915_private *dev_priv, } static const struct dev_pm_ops i915_pm_ops = { + /* + * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND, + * PMSG_RESUME] + */ .suspend = i915_pm_suspend, .suspend_late = i915_pm_suspend_late, .resume_early = i915_pm_resume_early, .resume = i915_pm_resume, + + /* + * S4 event handlers + * @freeze, @freeze_late : called (1) before creating the + * hibernation image [PMSG_FREEZE] and + * (2) after rebooting, before restoring + * the image [PMSG_QUIESCE] + * @thaw, @thaw_early : called (1) after creating the hibernation + * image, before writing it [PMSG_THAW] + * and (2) after failing to create or + * restore the image [PMSG_RECOVER] + * @poweroff, @poweroff_late: called after writing the hibernation + * image, before rebooting [PMSG_HIBERNATE] + * @restore, @restore_early : called after rebooting and restoring the + * hibernation image [PMSG_RESTORE] + */ .freeze = i915_pm_suspend, .freeze_late = i915_pm_suspend_late, .thaw_early = i915_pm_resume_early, @@ -1546,6 +1566,8 @@ static const struct dev_pm_ops i915_pm_ops = { .poweroff_late = i915_pm_suspend_late, .restore_early = i915_pm_resume_early, .restore = i915_pm_resume, + + /* S0ix (via runtime suspend) event handlers */ .runtime_suspend = intel_runtime_suspend, .runtime_resume = intel_runtime_resume, }; -- GitLab From 3eebaec630c2413a5e67bb7f49f0c6a53069a399 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 24 Oct 2014 16:45:21 +0200 Subject: [PATCH 1205/9457] drm/i915: Update DRIVER_DATE to 20141024 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 059330c7027a..583c97debeb7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -55,7 +55,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20141003" +#define DRIVER_DATE "20141024" enum pipe { INVALID_PIPE = -1, -- GitLab From 3e8cffd431464365c9787cea741b755bc64c4b8e Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 7 Oct 2014 00:37:54 +0900 Subject: [PATCH 1206/9457] crypto: testmgr - Remove unnecessary KERN_INFO from testmgr.c This patch remove unncessary KERN_INFO from pr_info within testmgr.c Signed-off-by: Masanari Iida Acked-by: David S. Miller Signed-off-by: Herbert Xu --- crypto/testmgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 29a0cbdd0d19..037368d34586 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -3708,8 +3708,7 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) panic("%s: %s alg self test failed in fips mode!\n", driver, alg); if (fips_enabled && !rc) - pr_info(KERN_INFO "alg: self-tests for %s (%s) passed\n", - driver, alg); + pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); return rc; -- GitLab From 41a84982a1d728165554be3e2be845f2caf83b55 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 14 Oct 2014 21:50:13 +0200 Subject: [PATCH 1207/9457] crypto: drbg - use crypto_inc The DRBG internal buffer addition function is replaced with crypto_inc when a buffer is to be incremented by one. The function drbg_add_buf is moved to the CONFIG_CRYPTO_DRBG_HASH ifdef area as it is now only needed for the Hash DRBG. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 79 +++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index 54cfd4820abc..8c0a742b60f6 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -283,38 +283,6 @@ static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf) conversion->conv = cpu_to_be32(val); } - -/* - * Increment buffer - * - * @dst buffer to increment - * @add value to add - */ -static inline void drbg_add_buf(unsigned char *dst, size_t dstlen, - const unsigned char *add, size_t addlen) -{ - /* implied: dstlen > addlen */ - unsigned char *dstptr; - const unsigned char *addptr; - unsigned int remainder = 0; - size_t len = addlen; - - dstptr = dst + (dstlen-1); - addptr = add + (addlen-1); - while (len) { - remainder += *dstptr + *addptr; - *dstptr = remainder & 0xff; - remainder >>= 8; - len--; dstptr--; addptr--; - } - len = dstlen - addlen; - while (len && remainder > 0) { - remainder = *dstptr + 1; - *dstptr = remainder & 0xff; - remainder >>= 8; - len--; dstptr--; - } -} #endif /* defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR) */ /****************************************************************** @@ -554,7 +522,6 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ unsigned int len = 0; struct drbg_string cipherin; - unsigned char prefix = DRBG_PREFIX1; memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); if (3 > reseed) @@ -574,7 +541,7 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, */ while (len < (drbg_statelen(drbg))) { /* 10.2.1.2 step 2.1 */ - drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); + crypto_inc(drbg->V, drbg_blocklen(drbg)); /* * 10.2.1.2 step 2.2 */ ret = drbg_kcapi_sym(drbg, drbg->C, temp + len, &cipherin); @@ -617,7 +584,6 @@ static int drbg_ctr_generate(struct drbg_state *drbg, int len = 0; int ret = 0; struct drbg_string data; - unsigned char prefix = DRBG_PREFIX1; memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); @@ -629,7 +595,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, } /* 10.2.1.5.2 step 4.1 */ - drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); + crypto_inc(drbg->V, drbg_blocklen(drbg)); drbg_string_fill(&data, drbg->V, drbg_blocklen(drbg)); while (len < buflen) { int outlen = 0; @@ -643,7 +609,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, drbg_blocklen(drbg) : (buflen - len); if (!drbg_fips_continuous_test(drbg, drbg->scratchpad)) { /* 10.2.1.5.2 step 6 */ - drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); + crypto_inc(drbg->V, drbg_blocklen(drbg)); continue; } /* 10.2.1.5.2 step 4.3 */ @@ -651,7 +617,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, len += outlen; /* 10.2.1.5.2 step 6 */ if (len < buflen) - drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); + crypto_inc(drbg->V, drbg_blocklen(drbg)); } /* 10.2.1.5.2 step 6 */ @@ -796,6 +762,38 @@ static struct drbg_state_ops drbg_hmac_ops = { #ifdef CONFIG_CRYPTO_DRBG_HASH #define CRYPTO_DRBG_HASH_STRING "HASH " +/* + * Increment buffer + * + * @dst buffer to increment + * @add value to add + */ +static inline void drbg_add_buf(unsigned char *dst, size_t dstlen, + const unsigned char *add, size_t addlen) +{ + /* implied: dstlen > addlen */ + unsigned char *dstptr; + const unsigned char *addptr; + unsigned int remainder = 0; + size_t len = addlen; + + dstptr = dst + (dstlen-1); + addptr = add + (addlen-1); + while (len) { + remainder += *dstptr + *addptr; + *dstptr = remainder & 0xff; + remainder >>= 8; + len--; dstptr--; addptr--; + } + len = dstlen - addlen; + while (len && remainder > 0) { + remainder = *dstptr + 1; + *dstptr = remainder & 0xff; + remainder >>= 8; + len--; dstptr--; + } +} + /* * scratchpad usage: as drbg_hash_update and drbg_hash_df are used * interlinked, the scratchpad is used as follows: @@ -942,7 +940,6 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg); struct drbg_string data; LIST_HEAD(datalist); - unsigned char prefix = DRBG_PREFIX1; memset(src, 0, drbg_statelen(drbg)); memset(dst, 0, drbg_blocklen(drbg)); @@ -963,7 +960,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, outlen = (drbg_blocklen(drbg) < (buflen - len)) ? drbg_blocklen(drbg) : (buflen - len); if (!drbg_fips_continuous_test(drbg, dst)) { - drbg_add_buf(src, drbg_statelen(drbg), &prefix, 1); + crypto_inc(src, drbg_statelen(drbg)); continue; } /* 10.1.1.4 step hashgen 4.2 */ @@ -971,7 +968,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg, len += outlen; /* 10.1.1.4 hashgen step 4.3 */ if (len < buflen) - drbg_add_buf(src, drbg_statelen(drbg), &prefix, 1); + crypto_inc(src, drbg_statelen(drbg)); } out: -- GitLab From 8c4cef464b90b1638ff01a922d6a34095cc09c0c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 15 Oct 2014 11:33:15 -0700 Subject: [PATCH 1208/9457] crypto: qat - fix bad unlock balance The mutex table_lock is unlocked in two functions without first being locked. Fix the functions to properly protect the accel_table with the table_lock. Also, fix a spelling error in one of the function's header comment. Signed-off-by: Bruce Allan Signed-off-by: Herbert Xu --- drivers/crypto/qat/qat_common/adf_dev_mgr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/qat/qat_common/adf_dev_mgr.c index ae71555c0868..4a0a829d4500 100644 --- a/drivers/crypto/qat/qat_common/adf_dev_mgr.c +++ b/drivers/crypto/qat/qat_common/adf_dev_mgr.c @@ -129,12 +129,13 @@ struct adf_accel_dev *adf_devmgr_get_first(void) * Function returns acceleration device associated with the given pci device. * To be used by QAT device specific drivers. * - * Return: pinter to accel_dev or NULL if not found. + * Return: pointer to accel_dev or NULL if not found. */ struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev) { struct list_head *itr; + mutex_lock(&table_lock); list_for_each(itr, &accel_table) { struct adf_accel_dev *ptr = list_entry(itr, struct adf_accel_dev, list); @@ -144,6 +145,7 @@ struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev) return ptr; } } + mutex_unlock(&table_lock); return NULL; } EXPORT_SYMBOL_GPL(adf_devmgr_pci_to_accel_dev); @@ -152,6 +154,7 @@ struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id) { struct list_head *itr; + mutex_lock(&table_lock); list_for_each(itr, &accel_table) { struct adf_accel_dev *ptr = list_entry(itr, struct adf_accel_dev, list); @@ -161,6 +164,7 @@ struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id) return ptr; } } + mutex_unlock(&table_lock); return NULL; } -- GitLab From fdb4c0ad3e6c35a51544bb7e5553c10433e50b85 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 15 Oct 2014 11:33:21 -0700 Subject: [PATCH 1209/9457] crypto: qat - cleanup coccicheck warning - NULL check before freeing functions Analyzing with coccinelle MODE=report... Please check for false positives in the output before submitting a patch. When using "patch" mode, carefully review the patch before submitting it. drivers/crypto/qat/qat_dh895xcc/adf_isr.c:191:3-8: WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values. drivers/crypto/qat/qat_dh895xcc/adf_isr.c:208:3-8: WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values. Signed-off-by: Bruce Allan Signed-off-by: Herbert Xu --- drivers/crypto/qat/qat_dh895xcc/adf_isr.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c index 67ec61e51185..c9212b919b2c 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c +++ b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c @@ -186,10 +186,8 @@ static int adf_isr_alloc_msix_entry_table(struct adf_accel_dev *accel_dev) accel_dev->accel_pci_dev.msix_entries.names = names; return 0; err: - for (i = 0; i < msix_num_entries; i++) { - if (*(names + i)) - kfree(*(names + i)); - } + for (i = 0; i < msix_num_entries; i++) + kfree(*(names + i)); kfree(entries); kfree(names); return -ENOMEM; @@ -203,10 +201,8 @@ static void adf_isr_free_msix_entry_table(struct adf_accel_dev *accel_dev) int i; kfree(accel_dev->accel_pci_dev.msix_entries.entries); - for (i = 0; i < msix_num_entries; i++) { - if (*(names + i)) - kfree(*(names + i)); - } + for (i = 0; i < msix_num_entries; i++) + kfree(*(names + i)); kfree(names); } -- GitLab From 242b1598e6db92e11c2fe7ab7e724936167f0a6f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 15 Oct 2014 11:33:27 -0700 Subject: [PATCH 1210/9457] crypto: qat - cleanup unnecessary break checkpatch warning WARNING:UNNECESSARY_BREAK: break is not useful after a goto or return #472: FILE: drivers/crypto/qat/qat_common/qat_algs.c:472: + goto bad_key; + break; Signed-off-by: Bruce Allan Signed-off-by: Herbert Xu --- drivers/crypto/qat/qat_common/qat_algs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index f2e2f158cfbe..25a409ca2d2a 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -466,7 +466,6 @@ static int qat_alg_init_sessions(struct qat_alg_session_ctx *ctx, break; default: goto bad_key; - break; } if (qat_alg_init_enc_session(ctx, alg, &keys)) -- GitLab From 77ddaba02bb83c4628b4fc1cf36b9ac81b9a7609 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 21 Oct 2014 23:09:56 +0000 Subject: [PATCH 1211/9457] crypto: qat - misspelling typo - "reseting" should be "resetting" Signed-off-by: Bruce Allan Signed-off-by: Herbert Xu --- drivers/crypto/qat/qat_common/adf_aer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c index c29d4c3926bf..10ce4a2854ab 100644 --- a/drivers/crypto/qat/qat_common/adf_aer.c +++ b/drivers/crypto/qat/qat_common/adf_aer.c @@ -90,7 +90,7 @@ static void adf_dev_restore(struct adf_accel_dev *accel_dev) uint16_t ppdstat = 0, bridge_ctl = 0; int pending = 0; - pr_info("QAT: Reseting device qat_dev%d\n", accel_dev->accel_id); + pr_info("QAT: Resetting device qat_dev%d\n", accel_dev->accel_id); pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat); pending = ppdstat & PCI_EXP_DEVSTA_TRPND; if (pending) { -- GitLab From 61daf055ea42342dea1f7006833bc7cde20eeb34 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Thu, 16 Oct 2014 23:17:23 +0200 Subject: [PATCH 1212/9457] hwrng: core - Changed from using strncat to strlcat The buf is used to hold the list of hwrng devices registered. The old code ensures we don't walk off the end of buf as we fill it, but it's unnecessarily complicated and thus difficult to maintain. Simplify it by using strlcat. Signed-off-by: Rickard Strandqvist Reviewed-by: Jason Cooper Signed-off-by: Herbert Xu --- drivers/char/hw_random/core.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index aa30a25c8d49..1500cfd799a7 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -281,7 +281,6 @@ static ssize_t hwrng_attr_available_show(struct device *dev, char *buf) { int err; - ssize_t ret = 0; struct hwrng *rng; err = mutex_lock_interruptible(&rng_mutex); @@ -289,16 +288,13 @@ static ssize_t hwrng_attr_available_show(struct device *dev, return -ERESTARTSYS; buf[0] = '\0'; list_for_each_entry(rng, &rng_list, list) { - strncat(buf, rng->name, PAGE_SIZE - ret - 1); - ret += strlen(rng->name); - strncat(buf, " ", PAGE_SIZE - ret - 1); - ret++; + strlcat(buf, rng->name, PAGE_SIZE); + strlcat(buf, " ", PAGE_SIZE); } - strncat(buf, "\n", PAGE_SIZE - ret - 1); - ret++; + strlcat(buf, "\n", PAGE_SIZE); mutex_unlock(&rng_mutex); - return ret; + return strlen(buf); } static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, -- GitLab From 3ef8d945d0dafd272e77c01099bc4975c5297a5a Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 23 Oct 2014 16:11:23 +0300 Subject: [PATCH 1213/9457] crypto: caam - add support for gcm(aes) Add support for AES working in Galois Counter Mode. There is a limitation related to IV size, similar to the one present in SW implementation (crypto/gcm.c): The only IV size allowed is 12 bytes. It will be padded by HW to the right with 0x0000_0001 (up to 16 bytes - AES block size), according to the GCM specification. Signed-off-by: Tudor Ambarus Signed-off-by: Horia Geanta Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 342 ++++++++++++++++++++++++++++++++-- 1 file changed, 331 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index a80ea853701d..66e35efcedfa 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -74,6 +74,10 @@ #define DESC_AEAD_NULL_ENC_LEN (DESC_AEAD_NULL_BASE + 14 * CAAM_CMD_SZ) #define DESC_AEAD_NULL_DEC_LEN (DESC_AEAD_NULL_BASE + 17 * CAAM_CMD_SZ) +#define DESC_GCM_BASE (3 * CAAM_CMD_SZ) +#define DESC_GCM_ENC_LEN (DESC_GCM_BASE + 23 * CAAM_CMD_SZ) +#define DESC_GCM_DEC_LEN (DESC_GCM_BASE + 19 * CAAM_CMD_SZ) + #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ 20 * CAAM_CMD_SZ) @@ -630,6 +634,236 @@ static int aead_setauthsize(struct crypto_aead *authenc, return 0; } +static int gcm_set_sh_desc(struct crypto_aead *aead) +{ + struct aead_tfm *tfm = &aead->base.crt_aead; + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + bool keys_fit_inline = false; + u32 *key_jump_cmd, *zero_payload_jump_cmd, + *zero_assoc_jump_cmd1, *zero_assoc_jump_cmd2; + u32 *desc; + + if (!ctx->enckeylen || !ctx->authsize) + return 0; + + /* + * AES GCM encrypt shared descriptor + * Job Descriptor and Shared Descriptor + * must fit into the 64-word Descriptor h/w Buffer + */ + if (DESC_GCM_ENC_LEN + DESC_JOB_IO_LEN + + ctx->enckeylen <= CAAM_DESC_BYTES_MAX) + keys_fit_inline = true; + + desc = ctx->sh_desc_enc; + + init_sh_desc(desc, HDR_SHARE_SERIAL); + + /* skip key loading if they are loaded due to sharing */ + key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | + JUMP_COND_SHRD | JUMP_COND_SELF); + if (keys_fit_inline) + append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, + ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); + else + append_key(desc, ctx->key_dma, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + set_jump_tgt_here(desc, key_jump_cmd); + + /* class 1 operation */ + append_operation(desc, ctx->class1_alg_type | + OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); + + /* cryptlen = seqoutlen - authsize */ + append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); + + /* assoclen + cryptlen = seqinlen - ivsize */ + append_math_sub_imm_u32(desc, REG2, SEQINLEN, IMM, tfm->ivsize); + + /* assoclen = (assoclen + cryptlen) - cryptlen */ + append_math_sub(desc, REG1, REG2, REG3, CAAM_CMD_SZ); + + /* if cryptlen is ZERO jump to zero-payload commands */ + append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); + zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + /* read IV */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1); + + /* if assoclen is ZERO, skip reading the assoc data */ + append_math_add(desc, VARSEQINLEN, ZERO, REG1, CAAM_CMD_SZ); + zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + + /* read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + set_jump_tgt_here(desc, zero_assoc_jump_cmd1); + + append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); + + /* write encrypted data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); + + /* read payload data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); + + /* jump the zero-payload commands */ + append_jump(desc, JUMP_TEST_ALL | 7); + + /* zero-payload commands */ + set_jump_tgt_here(desc, zero_payload_jump_cmd); + + /* if assoclen is ZERO, jump to IV reading - is the only input data */ + append_math_add(desc, VARSEQINLEN, ZERO, REG1, CAAM_CMD_SZ); + zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + /* read IV */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1); + + /* read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1); + + /* jump to ICV writing */ + append_jump(desc, JUMP_TEST_ALL | 2); + + /* read IV - is the only input data */ + set_jump_tgt_here(desc, zero_assoc_jump_cmd2); + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | + FIFOLD_TYPE_LAST1); + + /* write ICV */ + append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB | + LDST_SRCDST_BYTE_CONTEXT); + + ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "gcm enc shdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + /* + * Job Descriptor and Shared Descriptors + * must all fit into the 64-word Descriptor h/w Buffer + */ + keys_fit_inline = false; + if (DESC_GCM_DEC_LEN + DESC_JOB_IO_LEN + + ctx->enckeylen <= CAAM_DESC_BYTES_MAX) + keys_fit_inline = true; + + desc = ctx->sh_desc_dec; + + init_sh_desc(desc, HDR_SHARE_SERIAL); + + /* skip key loading if they are loaded due to sharing */ + key_jump_cmd = append_jump(desc, JUMP_JSL | + JUMP_TEST_ALL | JUMP_COND_SHRD | + JUMP_COND_SELF); + if (keys_fit_inline) + append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, + ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); + else + append_key(desc, ctx->key_dma, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + set_jump_tgt_here(desc, key_jump_cmd); + + /* class 1 operation */ + append_operation(desc, ctx->class1_alg_type | + OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON); + + /* assoclen + cryptlen = seqinlen - ivsize - icvsize */ + append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, + ctx->authsize + tfm->ivsize); + + /* assoclen = (assoclen + cryptlen) - cryptlen */ + append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ); + append_math_sub(desc, REG1, REG3, REG2, CAAM_CMD_SZ); + + /* read IV */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1); + + /* jump to zero-payload command if cryptlen is zero */ + append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ); + zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + + append_math_add(desc, VARSEQINLEN, ZERO, REG1, CAAM_CMD_SZ); + /* if asoclen is ZERO, skip reading assoc data */ + zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + /* read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + set_jump_tgt_here(desc, zero_assoc_jump_cmd1); + + append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ); + + /* store encrypted data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); + + /* read payload data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1); + + /* jump the zero-payload commands */ + append_jump(desc, JUMP_TEST_ALL | 4); + + /* zero-payload command */ + set_jump_tgt_here(desc, zero_payload_jump_cmd); + + /* if assoclen is ZERO, jump to ICV reading */ + append_math_add(desc, VARSEQINLEN, ZERO, REG1, CAAM_CMD_SZ); + zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL | + JUMP_COND_MATH_Z); + /* read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + set_jump_tgt_here(desc, zero_assoc_jump_cmd2); + + /* read ICV */ + append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1); + + ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "gcm dec shdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + return 0; +} + +static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize) +{ + struct caam_ctx *ctx = crypto_aead_ctx(authenc); + + ctx->authsize = authsize; + gcm_set_sh_desc(authenc); + + return 0; +} + static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen) { @@ -703,6 +937,36 @@ static int aead_setkey(struct crypto_aead *aead, return -EINVAL; } +static int gcm_setkey(struct crypto_aead *aead, + const u8 *key, unsigned int keylen) +{ + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + int ret = 0; + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + + memcpy(ctx->key, key, keylen); + ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->key_dma)) { + dev_err(jrdev, "unable to map key i/o memory\n"); + return -ENOMEM; + } + ctx->enckeylen = keylen; + + ret = gcm_set_sh_desc(aead); + if (ret) { + dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen, + DMA_TO_DEVICE); + } + + return ret; +} + static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, const u8 *key, unsigned int keylen) { @@ -1088,6 +1352,7 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, u32 out_options = 0, in_options; dma_addr_t dst_dma, src_dma; int len, sec4_sg_index = 0; + bool is_gcm = false; #ifdef DEBUG debug("assoclen %d cryptlen %d authsize %d\n", @@ -1106,11 +1371,19 @@ static void init_aead_job(u32 *sh_desc, dma_addr_t ptr, desc_bytes(sh_desc), 1); #endif + if (((ctx->class1_alg_type & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_AES) && + ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_GCM)) + is_gcm = true; + len = desc_len(sh_desc); init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); if (all_contig) { - src_dma = sg_dma_address(req->assoc); + if (is_gcm) + src_dma = edesc->iv_dma; + else + src_dma = sg_dma_address(req->assoc); in_options = 0; } else { src_dma = edesc->sec4_sg_dma; @@ -1292,6 +1565,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, int ivsize = crypto_aead_ivsize(aead); int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; unsigned int authsize = ctx->authsize; + bool is_gcm = false; assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); @@ -1326,15 +1600,31 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, return ERR_PTR(-ENOMEM); } - /* Check if data are contiguous */ - if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen != - iv_dma || src_nents || iv_dma + ivsize != - sg_dma_address(req->src)) { - all_contig = false; + if (((ctx->class1_alg_type & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_AES) && + ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_GCM)) + is_gcm = true; + + /* + * Check if data are contiguous. + * GCM expected input sequence: IV, AAD, text + * All other - expected input sequence: AAD, IV, text + */ + if (is_gcm) + all_contig = (!assoc_nents && + iv_dma + ivsize == sg_dma_address(req->assoc) && + !src_nents && sg_dma_address(req->assoc) + + req->assoclen == sg_dma_address(req->src)); + else + all_contig = (!assoc_nents && sg_dma_address(req->assoc) + + req->assoclen == iv_dma && !src_nents && + iv_dma + ivsize == sg_dma_address(req->src)); + if (!all_contig) { assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; sec4_sg_len = assoc_nents + 1 + src_nents; } + sec4_sg_len += dst_nents; sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); @@ -1361,14 +1651,26 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, sec4_sg_index = 0; if (!all_contig) { - sg_to_sec4_sg(req->assoc, - (assoc_nents ? : 1), - edesc->sec4_sg + - sec4_sg_index, 0); - sec4_sg_index += assoc_nents ? : 1; + if (!is_gcm) { + sg_to_sec4_sg(req->assoc, + (assoc_nents ? : 1), + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += assoc_nents ? : 1; + } + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); sec4_sg_index += 1; + + if (is_gcm) { + sg_to_sec4_sg(req->assoc, + (assoc_nents ? : 1), + edesc->sec4_sg + + sec4_sg_index, 0); + sec4_sg_index += assoc_nents ? : 1; + } + sg_to_sec4_sg_last(req->src, (src_nents ? : 1), edesc->sec4_sg + @@ -2309,6 +2611,24 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, }, + /* Galois Counter Mode */ + { + .name = "gcm(aes)", + .driver_name = "gcm-aes-caam", + .blocksize = 1, + .type = CRYPTO_ALG_TYPE_AEAD, + .template_aead = { + .setkey = gcm_setkey, + .setauthsize = gcm_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = NULL, + .geniv = "", + .ivsize = 12, + .maxauthsize = AES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + }, /* ablkcipher descriptor */ { .name = "cbc(aes)", -- GitLab From bac68f2c9a43e60a70e27c0c75aaca7128b6271d Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 23 Oct 2014 16:14:03 +0300 Subject: [PATCH 1214/9457] crypto: caam - add support for rfc4106(gcm(aes)) Add Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM) as an IPsec Encapsulating Security Payload (ESP) mechanism to provide confidentiality and data origin authentication. Signed-off-by: Tudor Ambarus Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 429 ++++++++++++++++++++++++++++++++-- 1 file changed, 414 insertions(+), 15 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 66e35efcedfa..c17154c32031 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -78,6 +78,11 @@ #define DESC_GCM_ENC_LEN (DESC_GCM_BASE + 23 * CAAM_CMD_SZ) #define DESC_GCM_DEC_LEN (DESC_GCM_BASE + 19 * CAAM_CMD_SZ) +#define DESC_RFC4106_BASE (3 * CAAM_CMD_SZ) +#define DESC_RFC4106_ENC_LEN (DESC_RFC4106_BASE + 15 * CAAM_CMD_SZ) +#define DESC_RFC4106_DEC_LEN (DESC_RFC4106_BASE + 14 * CAAM_CMD_SZ) +#define DESC_RFC4106_GIVENC_LEN (DESC_RFC4106_BASE + 21 * CAAM_CMD_SZ) + #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ 20 * CAAM_CMD_SZ) @@ -864,6 +869,287 @@ static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize) return 0; } +static int rfc4106_set_sh_desc(struct crypto_aead *aead) +{ + struct aead_tfm *tfm = &aead->base.crt_aead; + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + bool keys_fit_inline = false; + u32 *key_jump_cmd, *move_cmd, *write_iv_cmd; + u32 *desc; + u32 geniv; + + if (!ctx->enckeylen || !ctx->authsize) + return 0; + + /* + * RFC4106 encrypt shared descriptor + * Job Descriptor and Shared Descriptor + * must fit into the 64-word Descriptor h/w Buffer + */ + if (DESC_RFC4106_ENC_LEN + DESC_JOB_IO_LEN + + ctx->enckeylen <= CAAM_DESC_BYTES_MAX) + keys_fit_inline = true; + + desc = ctx->sh_desc_enc; + + init_sh_desc(desc, HDR_SHARE_SERIAL); + + /* Skip key loading if it is loaded due to sharing */ + key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | + JUMP_COND_SHRD); + if (keys_fit_inline) + append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, + ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); + else + append_key(desc, ctx->key_dma, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + set_jump_tgt_here(desc, key_jump_cmd); + + /* Class 1 operation */ + append_operation(desc, ctx->class1_alg_type | + OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); + + /* cryptlen = seqoutlen - authsize */ + append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); + append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); + + /* assoclen + cryptlen = seqinlen - ivsize */ + append_math_sub_imm_u32(desc, REG2, SEQINLEN, IMM, tfm->ivsize); + + /* assoclen = (assoclen + cryptlen) - cryptlen */ + append_math_sub(desc, VARSEQINLEN, REG2, REG3, CAAM_CMD_SZ); + + /* Read Salt */ + append_fifo_load_as_imm(desc, (void *)(ctx->key + ctx->enckeylen), + 4, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV); + /* Read AES-GCM-ESP IV */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1); + + /* Read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + + /* Will read cryptlen bytes */ + append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); + + /* Write encrypted data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); + + /* Read payload data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); + + /* Write ICV */ + append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB | + LDST_SRCDST_BYTE_CONTEXT); + + ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "rfc4106 enc shdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + /* + * Job Descriptor and Shared Descriptors + * must all fit into the 64-word Descriptor h/w Buffer + */ + keys_fit_inline = false; + if (DESC_RFC4106_DEC_LEN + DESC_JOB_IO_LEN + + ctx->enckeylen <= CAAM_DESC_BYTES_MAX) + keys_fit_inline = true; + + desc = ctx->sh_desc_dec; + + init_sh_desc(desc, HDR_SHARE_SERIAL); + + /* Skip key loading if it is loaded due to sharing */ + key_jump_cmd = append_jump(desc, JUMP_JSL | + JUMP_TEST_ALL | JUMP_COND_SHRD); + if (keys_fit_inline) + append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, + ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); + else + append_key(desc, ctx->key_dma, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + set_jump_tgt_here(desc, key_jump_cmd); + + /* Class 1 operation */ + append_operation(desc, ctx->class1_alg_type | + OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON); + + /* assoclen + cryptlen = seqinlen - ivsize - icvsize */ + append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, + ctx->authsize + tfm->ivsize); + + /* assoclen = (assoclen + cryptlen) - cryptlen */ + append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ); + append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ); + + /* Will write cryptlen bytes */ + append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ); + + /* Read Salt */ + append_fifo_load_as_imm(desc, (void *)(ctx->key + ctx->enckeylen), + 4, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV); + /* Read AES-GCM-ESP IV */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1); + + /* Read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + + /* Will read cryptlen bytes */ + append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ); + + /* Store payload data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); + + /* Read encrypted data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1); + + /* Read ICV */ + append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 | + FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1); + + ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "rfc4106 dec shdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + /* + * Job Descriptor and Shared Descriptors + * must all fit into the 64-word Descriptor h/w Buffer + */ + keys_fit_inline = false; + if (DESC_RFC4106_GIVENC_LEN + DESC_JOB_IO_LEN + + ctx->split_key_pad_len + ctx->enckeylen <= + CAAM_DESC_BYTES_MAX) + keys_fit_inline = true; + + /* rfc4106_givencrypt shared descriptor */ + desc = ctx->sh_desc_givenc; + + init_sh_desc(desc, HDR_SHARE_SERIAL); + + /* Skip key loading if it is loaded due to sharing */ + key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | + JUMP_COND_SHRD); + if (keys_fit_inline) + append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen, + ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); + else + append_key(desc, ctx->key_dma, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + set_jump_tgt_here(desc, key_jump_cmd); + + /* Generate IV */ + geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO | + NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 | + NFIFOENTRY_PTYPE_RND | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT); + append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB | + LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM); + append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); + move_cmd = append_move(desc, MOVE_SRC_INFIFO | MOVE_DEST_DESCBUF | + (tfm->ivsize << MOVE_LEN_SHIFT)); + append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); + + /* Copy generated IV to OFIFO */ + write_iv_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_OUTFIFO | + (tfm->ivsize << MOVE_LEN_SHIFT)); + + /* Class 1 operation */ + append_operation(desc, ctx->class1_alg_type | + OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); + + /* ivsize + cryptlen = seqoutlen - authsize */ + append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize); + + /* assoclen = seqinlen - (ivsize + cryptlen) */ + append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ); + + /* Will write ivsize + cryptlen */ + append_math_add(desc, VARSEQOUTLEN, REG3, REG0, CAAM_CMD_SZ); + + /* Read Salt and generated IV */ + append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV | + FIFOLD_TYPE_FLUSH1 | IMMEDIATE | 12); + /* Append Salt */ + append_data(desc, (void *)(ctx->key + ctx->enckeylen), 4); + set_move_tgt_here(desc, move_cmd); + set_move_tgt_here(desc, write_iv_cmd); + /* Blank commands. Will be overwritten by generated IV. */ + append_cmd(desc, 0x00000000); + append_cmd(desc, 0x00000000); + /* End of blank commands */ + + /* No need to reload iv */ + append_seq_fifo_load(desc, tfm->ivsize, FIFOLD_CLASS_SKIP); + + /* Read assoc data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1); + + /* Will read cryptlen */ + append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); + + /* Store generated IV and encrypted data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF); + + /* Read payload data */ + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1); + + /* Write ICV */ + append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB | + LDST_SRCDST_BYTE_CONTEXT); + + ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc, + desc_bytes(desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, + "rfc4106 givenc shdesc@"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, + desc_bytes(desc), 1); +#endif + + return 0; +} + +static int rfc4106_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) +{ + struct caam_ctx *ctx = crypto_aead_ctx(authenc); + + ctx->authsize = authsize; + rfc4106_set_sh_desc(authenc); + + return 0; +} + static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen) { @@ -967,6 +1253,45 @@ static int gcm_setkey(struct crypto_aead *aead, return ret; } +static int rfc4106_setkey(struct crypto_aead *aead, + const u8 *key, unsigned int keylen) +{ + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + int ret = 0; + + if (keylen < 4) + return -EINVAL; + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + + memcpy(ctx->key, key, keylen); + + /* + * The last four bytes of the key material are used as the salt value + * in the nonce. Update the AES key length. + */ + ctx->enckeylen = keylen - 4; + + ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->key_dma)) { + dev_err(jrdev, "unable to map key i/o memory\n"); + return -ENOMEM; + } + + ret = rfc4106_set_sh_desc(aead); + if (ret) { + dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen, + DMA_TO_DEVICE); + } + + return ret; +} + static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, const u8 *key, unsigned int keylen) { @@ -1437,6 +1762,7 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, u32 out_options = 0, in_options; dma_addr_t dst_dma, src_dma; int len, sec4_sg_index = 0; + bool is_gcm = false; #ifdef DEBUG debug("assoclen %d cryptlen %d authsize %d\n", @@ -1454,11 +1780,19 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, desc_bytes(sh_desc), 1); #endif + if (((ctx->class1_alg_type & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_AES) && + ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_GCM)) + is_gcm = true; + len = desc_len(sh_desc); init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE); if (contig & GIV_SRC_CONTIG) { - src_dma = sg_dma_address(req->assoc); + if (is_gcm) + src_dma = edesc->iv_dma; + else + src_dma = sg_dma_address(req->assoc); in_options = 0; } else { src_dma = edesc->sec4_sg_dma; @@ -1473,7 +1807,8 @@ static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr, } else { if (likely(req->src == req->dst)) { dst_dma = src_dma + sizeof(struct sec4_sg_entry) * - edesc->assoc_nents; + (edesc->assoc_nents + + (is_gcm ? 1 + edesc->src_nents : 0)); out_options = LDST_SGF; } else { dst_dma = edesc->sec4_sg_dma + @@ -1792,6 +2127,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request int ivsize = crypto_aead_ivsize(aead); bool assoc_chained = false, src_chained = false, dst_chained = false; int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; + bool is_gcm = false; assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); src_nents = sg_count(req->src, req->cryptlen, &src_chained); @@ -1818,16 +2154,33 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request return ERR_PTR(-ENOMEM); } - /* Check if data are contiguous */ - if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen != - iv_dma || src_nents || iv_dma + ivsize != sg_dma_address(req->src)) - contig &= ~GIV_SRC_CONTIG; + if (((ctx->class1_alg_type & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_AES) && + ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_GCM)) + is_gcm = true; + + /* + * Check if data are contiguous. + * GCM expected input sequence: IV, AAD, text + * All other - expected input sequence: AAD, IV, text + */ + + if (is_gcm) { + if (assoc_nents || iv_dma + ivsize != + sg_dma_address(req->assoc) || src_nents || + sg_dma_address(req->assoc) + req->assoclen != + sg_dma_address(req->src)) + contig &= ~GIV_SRC_CONTIG; + } else { + if (assoc_nents || + sg_dma_address(req->assoc) + req->assoclen != iv_dma || + src_nents || iv_dma + ivsize != sg_dma_address(req->src)) + contig &= ~GIV_SRC_CONTIG; + } + if (dst_nents || iv_dma + ivsize != sg_dma_address(req->dst)) contig &= ~GIV_DST_CONTIG; - if (unlikely(req->src != req->dst)) { - dst_nents = dst_nents ? : 1; - sec4_sg_len += 1; - } + if (!(contig & GIV_SRC_CONTIG)) { assoc_nents = assoc_nents ? : 1; src_nents = src_nents ? : 1; @@ -1835,7 +2188,18 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request if (likely(req->src == req->dst)) contig &= ~GIV_DST_CONTIG; } - sec4_sg_len += dst_nents; + + /* + * Add new sg entries for GCM output sequence. + * Expected output sequence: IV, encrypted text. + */ + if (is_gcm && req->src == req->dst && !(contig & GIV_DST_CONTIG)) + sec4_sg_len += 1 + src_nents; + + if (unlikely(req->src != req->dst)) { + dst_nents = dst_nents ? : 1; + sec4_sg_len += 1 + dst_nents; + } sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); @@ -1861,18 +2225,36 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request sec4_sg_index = 0; if (!(contig & GIV_SRC_CONTIG)) { - sg_to_sec4_sg(req->assoc, assoc_nents, - edesc->sec4_sg + - sec4_sg_index, 0); - sec4_sg_index += assoc_nents; + if (!is_gcm) { + sg_to_sec4_sg(req->assoc, assoc_nents, + edesc->sec4_sg + sec4_sg_index, 0); + sec4_sg_index += assoc_nents; + } + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); sec4_sg_index += 1; + + if (is_gcm) { + sg_to_sec4_sg(req->assoc, assoc_nents, + edesc->sec4_sg + sec4_sg_index, 0); + sec4_sg_index += assoc_nents; + } + sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg + sec4_sg_index, 0); sec4_sg_index += src_nents; } + + if (is_gcm && req->src == req->dst && !(contig & GIV_DST_CONTIG)) { + dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, + iv_dma, ivsize, 0); + sec4_sg_index += 1; + sg_to_sec4_sg_last(req->src, src_nents, + edesc->sec4_sg + sec4_sg_index, 0); + } + if (unlikely(req->src != req->dst && !(contig & GIV_DST_CONTIG))) { dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index, iv_dma, ivsize, 0); @@ -2611,6 +2993,23 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, }, + { + .name = "rfc4106(gcm(aes))", + .driver_name = "rfc4106-gcm-aes-caam", + .blocksize = 1, + .type = CRYPTO_ALG_TYPE_AEAD, + .template_aead = { + .setkey = rfc4106_setkey, + .setauthsize = rfc4106_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = 8, + .maxauthsize = AES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + }, /* Galois Counter Mode */ { .name = "gcm(aes)", -- GitLab From 6b358aedced8180830727258718c3916bef3e249 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 22 Oct 2014 20:26:44 +0200 Subject: [PATCH 1215/9457] phy: marvell: Add support for 88E3016 FastEthernet PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marvell 88E3016 is a FastEthernet PHY that also can be found in Marvell Berlin SoCs as integrated PHY. Tested-by: Antoine Ténart Reviewed-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 46 +++++++++++++++++++++++++++++++++++++ include/linux/marvell_phy.h | 1 + 2 files changed, 47 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index bd37e45c89c0..d2b2f2f795d5 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -118,6 +118,9 @@ #define MII_M1116R_CONTROL_REG_MAC 21 +#define MII_88E3016_PHY_SPEC_CTRL 0x10 +#define MII_88E3016_DISABLE_SCRAMBLER 0x0200 +#define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 MODULE_DESCRIPTION("Marvell PHY driver"); MODULE_AUTHOR("Andy Fleming"); @@ -434,6 +437,25 @@ static int m88e1116r_config_init(struct phy_device *phydev) return 0; } +static int m88e3016_config_init(struct phy_device *phydev) +{ + int reg; + + /* Enable Scrambler and Auto-Crossover */ + reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL); + if (reg < 0) + return reg; + + reg &= ~MII_88E3016_DISABLE_SCRAMBLER; + reg |= MII_88E3016_AUTO_MDIX_CROSSOVER; + + reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg); + if (reg < 0) + return reg; + + return 0; +} + static int m88e1111_config_init(struct phy_device *phydev) { int err; @@ -770,6 +792,12 @@ static int marvell_read_status(struct phy_device *phydev) return 0; } +static int marvell_aneg_done(struct phy_device *phydev) +{ + int retval = phy_read(phydev, MII_M1011_PHY_STATUS); + return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); +} + static int m88e1121_did_interrupt(struct phy_device *phydev) { int imask; @@ -1050,6 +1078,23 @@ static struct phy_driver marvell_drivers[] = { .suspend = &genphy_suspend, .driver = { .owner = THIS_MODULE }, }, + { + .phy_id = MARVELL_PHY_ID_88E3016, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E3016", + .features = PHY_BASIC_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg = &genphy_config_aneg, + .config_init = &m88e3016_config_init, + .aneg_done = &marvell_aneg_done, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .did_interrupt = &m88e1121_did_interrupt, + .resume = &genphy_resume, + .suspend = &genphy_suspend, + .driver = { .owner = THIS_MODULE }, + }, }; static int __init marvell_init(void) @@ -1079,6 +1124,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = { { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, { } }; diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h index 8e9a029e093d..e6982ac3200d 100644 --- a/include/linux/marvell_phy.h +++ b/include/linux/marvell_phy.h @@ -16,6 +16,7 @@ #define MARVELL_PHY_ID_88E1318S 0x01410e90 #define MARVELL_PHY_ID_88E1116R 0x01410e40 #define MARVELL_PHY_ID_88E1510 0x01410dd0 +#define MARVELL_PHY_ID_88E3016 0x01410e60 /* struct phy_device dev_flags definitions */ #define MARVELL_PHY_M1145_FLAGS_RESISTANCE 0x00000001 -- GitLab From e7de17abeda24d8acc316b2e07bd969d03099eea Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 22 Oct 2014 20:26:45 +0200 Subject: [PATCH 1216/9457] net: pxa168_eth: Provide phy_interface mode on platform_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PXA168 Ethernet IP support MII and RMII connection to its PHY. Currently, pxa168 platform_data does not provide a way to pass that and there is one user of pxa168 platform_data (mach-mmp/gplug). Given the pinctrl settings of gplug it uses RMII, so add and pass a corresponding phy_interface_t. Tested-by: Antoine Ténart Reviewed-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- arch/arm/mach-mmp/gplugd.c | 2 ++ include/linux/pxa168_eth.h | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index d81b2475e67e..3b5794cd0357 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -158,6 +159,7 @@ struct pxa168_eth_platform_data gplugd_eth_platform_data = { .port_number = 0, .phy_addr = 0, .speed = 0, /* Autonagotiation */ + .intf = PHY_INTERFACE_MODE_RMII, .init = gplugd_eth_init, }; diff --git a/include/linux/pxa168_eth.h b/include/linux/pxa168_eth.h index 18d75e795606..37c381120bc8 100644 --- a/include/linux/pxa168_eth.h +++ b/include/linux/pxa168_eth.h @@ -13,6 +13,7 @@ struct pxa168_eth_platform_data { */ int speed; /* 0, SPEED_10, SPEED_100 */ int duplex; /* DUPLEX_HALF or DUPLEX_FULL */ + phy_interface_t intf; /* * Override default RX/TX queue sizes if nonzero. -- GitLab From 9d8ea73d3ebdf4ab8f1d2e447452fb0b504e3873 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 22 Oct 2014 20:26:46 +0200 Subject: [PATCH 1217/9457] net: pxa168_eth: Prepare proper libphy handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current libphy handling in pxa168_eth lacks proper phy_connect. Prepare to fix this by first moving phy properties from platform_data to private driver data. Tested-by: Antoine Ténart Reviewed-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/pxa168_eth.c | 38 ++++++++++++++--------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index c3b209cd0660..3918887e09c5 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -197,6 +197,9 @@ struct tx_desc { struct pxa168_eth_private { int port_num; /* User Ethernet port number */ int phy_addr; + int phy_speed; + int phy_duplex; + phy_interface_t phy_intf; int rx_resource_err; /* Rx ring resource error flag */ @@ -1394,19 +1397,17 @@ static void phy_init(struct pxa168_eth_private *pep) { struct phy_device *phy = pep->phy; - phy_attach(pep->dev, dev_name(&phy->dev), PHY_INTERFACE_MODE_MII); + phy_attach(pep->dev, dev_name(&phy->dev), pep->phy_intf); - if (pep->pd && pep->pd->speed != 0) { + phy->speed = pep->phy_speed; + phy->duplex = pep->phy_duplex; + phy->autoneg = AUTONEG_ENABLE; + phy->supported &= PHY_BASIC_FEATURES; + phy->advertising = phy->supported | ADVERTISED_Autoneg; + + if (pep->phy_speed != 0) { phy->autoneg = AUTONEG_DISABLE; phy->advertising = 0; - phy->speed = pep->pd->speed; - phy->duplex = pep->pd->duplex; - } else { - phy->autoneg = AUTONEG_ENABLE; - phy->speed = 0; - phy->duplex = 0; - phy->supported &= PHY_BASIC_FEATURES; - phy->advertising = phy->supported | ADVERTISED_Autoneg; } phy_start_aneg(phy); @@ -1416,9 +1417,6 @@ static int ethernet_phy_setup(struct net_device *dev) { struct pxa168_eth_private *pep = netdev_priv(dev); - if (pep->pd && pep->pd->init) - pep->pd->init(); - pep->phy = phy_scan(pep, pep->phy_addr & 0x1f); if (pep->phy != NULL) phy_init(pep); @@ -1552,13 +1550,23 @@ static int pxa168_eth_probe(struct platform_device *pdev) pep->port_num = pep->pd->port_number; pep->phy_addr = pep->pd->phy_addr; + pep->phy_speed = pep->pd->speed; + pep->phy_duplex = pep->pd->duplex; + pep->phy_intf = pep->pd->intf; + + if (pep->pd->init) + pep->pd->init(); } else if (pdev->dev.of_node) { of_property_read_u32(pdev->dev.of_node, "port-id", &pep->port_num); np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); - if (np) - of_property_read_u32(np, "reg", &pep->phy_addr); + if (!np) { + dev_err(&pdev->dev, "missing phy-handle\n"); + return -EINVAL; + } + of_property_read_u32(np, "reg", &pep->phy_addr); + pep->phy_intf = of_get_phy_mode(pdev->dev.of_node); } /* Hardware supports only 3 ports */ -- GitLab From 1a14913289a9d0eafbb29971229c24fbdc4c1496 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 22 Oct 2014 20:26:47 +0200 Subject: [PATCH 1218/9457] net: pxa168_eth: Remove HW auto-negotiaion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marvell Ethernet IP supports PHY negotiation driven by HW. This fundamentally clashes with libphy (software) driven negotiation and also cannot cope with quirky PHYs. Therefore, always disable any HW negotiation features and properly use libphy's phy_device. Tested-by: Antoine Ténart Reviewed-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/pxa168_eth.c | 100 ++++++++++++++++++---- 1 file changed, 85 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 3918887e09c5..ca60fa24d2ed 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -106,6 +106,7 @@ #define SDMA_CMD_ERD (1 << 7) /* Bit definitions of the Port Config Reg */ +#define PCR_DUPLEX_FULL (1 << 15) #define PCR_HS (1 << 12) #define PCR_EN (1 << 7) #define PCR_PM (1 << 0) @@ -113,11 +114,17 @@ /* Bit definitions of the Port Config Extend Reg */ #define PCXR_2BSM (1 << 28) #define PCXR_DSCP_EN (1 << 21) +#define PCXR_RMII_EN (1 << 20) +#define PCXR_AN_SPEED_DIS (1 << 19) +#define PCXR_SPEED_100 (1 << 18) #define PCXR_MFL_1518 (0 << 14) #define PCXR_MFL_1536 (1 << 14) #define PCXR_MFL_2048 (2 << 14) #define PCXR_MFL_64K (3 << 14) +#define PCXR_FLOWCTL_DIS (1 << 12) #define PCXR_FLP (1 << 11) +#define PCXR_AN_FLOWCTL_DIS (1 << 10) +#define PCXR_AN_DUPLEX_DIS (1 << 9) #define PCXR_PRIO_TX_OFF 3 #define PCXR_TX_HIGH_PRI (7 << PCXR_PRIO_TX_OFF) @@ -272,6 +279,7 @@ enum hash_table_entry { static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd); static int pxa168_init_hw(struct pxa168_eth_private *pep); +static int pxa168_init_phy(struct net_device *dev); static void eth_port_reset(struct net_device *dev); static void eth_port_start(struct net_device *dev); static int pxa168_eth_open(struct net_device *dev); @@ -658,14 +666,7 @@ static void eth_port_start(struct net_device *dev) struct pxa168_eth_private *pep = netdev_priv(dev); int tx_curr_desc, rx_curr_desc; - /* Perform PHY reset, if there is a PHY. */ - if (pep->phy != NULL) { - struct ethtool_cmd cmd; - - pxa168_get_settings(pep->dev, &cmd); - phy_init_hw(pep->phy); - pxa168_set_settings(pep->dev, &cmd); - } + phy_start(pep->phy); /* Assignment of Tx CTRP of given queue */ tx_curr_desc = pep->tx_curr_desc_q; @@ -720,6 +721,8 @@ static void eth_port_reset(struct net_device *dev) val = rdl(pep, PORT_CONFIG); val &= ~PCR_EN; wrl(pep, PORT_CONFIG, val); + + phy_stop(pep->phy); } /* @@ -981,8 +984,11 @@ static int set_port_config_ext(struct pxa168_eth_private *pep) skb_size = PCXR_MFL_64K; /* Extended Port Configuration */ - wrl(pep, - PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte prefix aligns IP hdr */ + wrl(pep, PORT_CONFIG_EXT, + PCXR_AN_SPEED_DIS | /* Disable HW AN */ + PCXR_AN_DUPLEX_DIS | + PCXR_AN_FLOWCTL_DIS | + PCXR_2BSM | /* Two byte prefix aligns IP hdr */ PCXR_DSCP_EN | /* Enable DSCP in IP */ skb_size | PCXR_FLP | /* do not force link pass */ PCXR_TX_HIGH_PRI); /* Transmit - high priority queue */ @@ -990,6 +996,69 @@ static int set_port_config_ext(struct pxa168_eth_private *pep) return 0; } +static void pxa168_eth_adjust_link(struct net_device *dev) +{ + struct pxa168_eth_private *pep = netdev_priv(dev); + struct phy_device *phy = pep->phy; + u32 cfg, cfg_o = rdl(pep, PORT_CONFIG); + u32 cfgext, cfgext_o = rdl(pep, PORT_CONFIG_EXT); + + cfg = cfg_o & ~PCR_DUPLEX_FULL; + cfgext = cfgext_o & ~(PCXR_SPEED_100 | PCXR_FLOWCTL_DIS | PCXR_RMII_EN); + + if (phy->interface == PHY_INTERFACE_MODE_RMII) + cfgext |= PCXR_RMII_EN; + if (phy->speed == SPEED_100) + cfgext |= PCXR_SPEED_100; + if (phy->duplex) + cfg |= PCR_DUPLEX_FULL; + if (!phy->pause) + cfgext |= PCXR_FLOWCTL_DIS; + + /* Bail out if there has nothing changed */ + if (cfg == cfg_o && cfgext == cfgext_o) + return; + + wrl(pep, PORT_CONFIG, cfg); + wrl(pep, PORT_CONFIG_EXT, cfgext); + + phy_print_status(phy); +} + +static int pxa168_init_phy(struct net_device *dev) +{ + struct pxa168_eth_private *pep = netdev_priv(dev); + struct ethtool_cmd cmd; + int err; + + if (pep->phy) + return 0; + + pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); + if (!pep->phy) + return -ENODEV; + + err = phy_connect_direct(dev, pep->phy, pxa168_eth_adjust_link, + pep->phy_intf); + if (err) + return err; + + err = pxa168_get_settings(dev, &cmd); + if (err) + return err; + + cmd.phy_address = pep->phy_addr; + cmd.speed = pep->phy_speed; + cmd.duplex = pep->phy_duplex; + cmd.advertising = PHY_BASIC_FEATURES; + cmd.autoneg = AUTONEG_ENABLE; + + if (cmd.speed != 0) + cmd.autoneg = AUTONEG_DISABLE; + + return pxa168_set_settings(dev, &cmd); +} + static int pxa168_init_hw(struct pxa168_eth_private *pep) { int err = 0; @@ -1136,6 +1205,10 @@ static int pxa168_eth_open(struct net_device *dev) struct pxa168_eth_private *pep = netdev_priv(dev); int err; + err = pxa168_init_phy(dev); + if (err) + return err; + err = request_irq(dev->irq, pxa168_eth_int_handler, 0, dev->name, dev); if (err) { dev_err(&dev->dev, "can't assign irq\n"); @@ -1596,9 +1669,6 @@ static int pxa168_eth_probe(struct platform_device *pdev) goto err_free_mdio; pxa168_init_hw(pep); - err = ethernet_phy_setup(dev); - if (err) - goto err_mdiobus; SET_NETDEV_DEV(dev, &pdev->dev); err = register_netdev(dev); if (err) @@ -1629,13 +1699,13 @@ static int pxa168_eth_remove(struct platform_device *pdev) pep->htpr, pep->htpr_dma); pep->htpr = NULL; } + if (pep->phy) + phy_disconnect(pep->phy); if (pep->clk) { clk_disable(pep->clk); clk_put(pep->clk); pep->clk = NULL; } - if (pep->phy != NULL) - phy_detach(pep->phy); iounmap(pep->base); pep->base = NULL; -- GitLab From 9ff32fe1b9c5e125557766ea1723a7c42779f5a6 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 22 Oct 2014 20:26:48 +0200 Subject: [PATCH 1219/9457] net: pxa168_eth: Remove in-driver PHY mangling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With properly using libphy PHYs now, remove the in-driver PHY mangling. Tested-by: Antoine Ténart Reviewed-by: Florian Fainelli Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/pxa168_eth.c | 126 ---------------------- 1 file changed, 126 deletions(-) diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index ca60fa24d2ed..bee4c369f0fe 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -177,7 +177,6 @@ #define LINK_UP (1 << 3) /* Bit definitions for work to be done */ -#define WORK_LINK (1 << 0) #define WORK_TX_DONE (1 << 1) /* @@ -284,7 +283,6 @@ static void eth_port_reset(struct net_device *dev); static void eth_port_start(struct net_device *dev); static int pxa168_eth_open(struct net_device *dev); static int pxa168_eth_stop(struct net_device *dev); -static int ethernet_phy_setup(struct net_device *dev); static inline u32 rdl(struct pxa168_eth_private *pep, int offset) { @@ -316,26 +314,6 @@ static void abort_dma(struct pxa168_eth_private *pep) netdev_err(pep->dev, "%s : DMA Stuck\n", __func__); } -static int ethernet_phy_get(struct pxa168_eth_private *pep) -{ - unsigned int reg_data; - - reg_data = rdl(pep, PHY_ADDRESS); - - return (reg_data >> (5 * pep->port_num)) & 0x1f; -} - -static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr) -{ - u32 reg_data; - int addr_shift = 5 * pep->port_num; - - reg_data = rdl(pep, PHY_ADDRESS); - reg_data &= ~(0x1f << addr_shift); - reg_data |= (phy_addr & 0x1f) << addr_shift; - wrl(pep, PHY_ADDRESS, reg_data); -} - static void rxq_refill(struct net_device *dev) { struct pxa168_eth_private *pep = netdev_priv(dev); @@ -890,43 +868,9 @@ static int pxa168_eth_collect_events(struct pxa168_eth_private *pep, } if (icr & ICR_RXBUF) ret = 1; - if (icr & ICR_MII_CH) { - pep->work_todo |= WORK_LINK; - ret = 1; - } return ret; } -static void handle_link_event(struct pxa168_eth_private *pep) -{ - struct net_device *dev = pep->dev; - u32 port_status; - int speed; - int duplex; - int fc; - - port_status = rdl(pep, PORT_STATUS); - if (!(port_status & LINK_UP)) { - if (netif_carrier_ok(dev)) { - netdev_info(dev, "link down\n"); - netif_carrier_off(dev); - txq_reclaim(dev, 1); - } - return; - } - if (port_status & PORT_SPEED_100) - speed = 100; - else - speed = 10; - - duplex = (port_status & FULL_DUPLEX) ? 1 : 0; - fc = (port_status & FLOW_CONTROL_DISABLED) ? 0 : 1; - netdev_info(dev, "link up, %d Mb/s, %s duplex, flow control %sabled\n", - speed, duplex ? "full" : "half", fc ? "en" : "dis"); - if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); -} - static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; @@ -1307,10 +1251,6 @@ static int pxa168_rx_poll(struct napi_struct *napi, int budget) struct net_device *dev = pep->dev; int work_done = 0; - if (unlikely(pep->work_todo & WORK_LINK)) { - pep->work_todo &= ~(WORK_LINK); - handle_link_event(pep); - } /* * We call txq_reclaim every time since in NAPI interupts are disabled * and due to this we miss the TX_DONE interrupt,which is not updated in @@ -1433,72 +1373,6 @@ static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, return -EOPNOTSUPP; } -static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr) -{ - struct mii_bus *bus = pep->smi_bus; - struct phy_device *phydev; - int start; - int num; - int i; - - if (phy_addr == PXA168_ETH_PHY_ADDR_DEFAULT) { - /* Scan entire range */ - start = ethernet_phy_get(pep); - num = 32; - } else { - /* Use phy addr specific to platform */ - start = phy_addr & 0x1f; - num = 1; - } - phydev = NULL; - for (i = 0; i < num; i++) { - int addr = (start + i) & 0x1f; - if (bus->phy_map[addr] == NULL) - mdiobus_scan(bus, addr); - - if (phydev == NULL) { - phydev = bus->phy_map[addr]; - if (phydev != NULL) - ethernet_phy_set_addr(pep, addr); - } - } - - return phydev; -} - -static void phy_init(struct pxa168_eth_private *pep) -{ - struct phy_device *phy = pep->phy; - - phy_attach(pep->dev, dev_name(&phy->dev), pep->phy_intf); - - phy->speed = pep->phy_speed; - phy->duplex = pep->phy_duplex; - phy->autoneg = AUTONEG_ENABLE; - phy->supported &= PHY_BASIC_FEATURES; - phy->advertising = phy->supported | ADVERTISED_Autoneg; - - if (pep->phy_speed != 0) { - phy->autoneg = AUTONEG_DISABLE; - phy->advertising = 0; - } - - phy_start_aneg(phy); -} - -static int ethernet_phy_setup(struct net_device *dev) -{ - struct pxa168_eth_private *pep = netdev_priv(dev); - - pep->phy = phy_scan(pep, pep->phy_addr & 0x1f); - if (pep->phy != NULL) - phy_init(pep); - - update_hash_table_mac_address(pep, NULL, dev->dev_addr); - - return 0; -} - static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct pxa168_eth_private *pep = netdev_priv(dev); -- GitLab From 75da1469f923970627843d68482b6da6ed6f38f9 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 22 Oct 2014 21:01:41 +0200 Subject: [PATCH 1220/9457] lapb: move EXPORT_SYMBOL after functions. See Documentation/CodingStyle Chapter 6 Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/lapb/lapb_iface.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index 3cdaa046c1bc..fc60d9d738b5 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -73,6 +73,7 @@ static void __lapb_remove_cb(struct lapb_cb *lapb) lapb_put(lapb); } } +EXPORT_SYMBOL(lapb_register); /* * Add a socket to the bound sockets list. @@ -195,6 +196,7 @@ int lapb_unregister(struct net_device *dev) write_unlock_bh(&lapb_list_lock); return rc; } +EXPORT_SYMBOL(lapb_unregister); int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms) { @@ -227,6 +229,7 @@ int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms) out: return rc; } +EXPORT_SYMBOL(lapb_getparms); int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) { @@ -262,6 +265,7 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) out: return rc; } +EXPORT_SYMBOL(lapb_setparms); int lapb_connect_request(struct net_device *dev) { @@ -290,6 +294,7 @@ int lapb_connect_request(struct net_device *dev) out: return rc; } +EXPORT_SYMBOL(lapb_connect_request); int lapb_disconnect_request(struct net_device *dev) { @@ -334,6 +339,7 @@ int lapb_disconnect_request(struct net_device *dev) out: return rc; } +EXPORT_SYMBOL(lapb_disconnect_request); int lapb_data_request(struct net_device *dev, struct sk_buff *skb) { @@ -355,6 +361,7 @@ int lapb_data_request(struct net_device *dev, struct sk_buff *skb) out: return rc; } +EXPORT_SYMBOL(lapb_data_request); int lapb_data_received(struct net_device *dev, struct sk_buff *skb) { @@ -369,6 +376,7 @@ int lapb_data_received(struct net_device *dev, struct sk_buff *skb) return rc; } +EXPORT_SYMBOL(lapb_data_received); void lapb_connect_confirmation(struct lapb_cb *lapb, int reason) { @@ -415,15 +423,6 @@ int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *skb) return used; } -EXPORT_SYMBOL(lapb_register); -EXPORT_SYMBOL(lapb_unregister); -EXPORT_SYMBOL(lapb_getparms); -EXPORT_SYMBOL(lapb_setparms); -EXPORT_SYMBOL(lapb_connect_request); -EXPORT_SYMBOL(lapb_disconnect_request); -EXPORT_SYMBOL(lapb_data_request); -EXPORT_SYMBOL(lapb_data_received); - static int __init lapb_init(void) { return 0; -- GitLab From 74bca138e1351a0da5ce9c2936bbccdd0d4e2225 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 22 Oct 2014 21:06:26 +0200 Subject: [PATCH 1221/9457] net: llc: include linux/errno.h instead of asm/errno.h Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/llc/llc_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 25c31c0a3fdb..6daf391b3e84 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include -- GitLab From 6696777c6506fa52b2a0282121195843ed855be6 Mon Sep 17 00:00:00 2001 From: Duson Lin Date: Fri, 3 Oct 2014 13:24:27 -0700 Subject: [PATCH 1222/9457] Input: add driver for Elan I2C/SMbus touchpad This driver supports Elan I2C/SMbus touchpads found in some laptops and also in many Chromebooks. Signed-off-by: Duson Lin Reviewed-by: Benson Leung Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/elan_i2c.txt | 34 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/input/mouse/Kconfig | 30 + drivers/input/mouse/Makefile | 5 + drivers/input/mouse/elan_i2c.h | 86 ++ drivers/input/mouse/elan_i2c_core.c | 1137 +++++++++++++++++ drivers/input/mouse/elan_i2c_i2c.c | 611 +++++++++ drivers/input/mouse/elan_i2c_smbus.c | 514 ++++++++ 8 files changed, 2418 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/elan_i2c.txt create mode 100644 drivers/input/mouse/elan_i2c.h create mode 100644 drivers/input/mouse/elan_i2c_core.c create mode 100644 drivers/input/mouse/elan_i2c_i2c.c create mode 100644 drivers/input/mouse/elan_i2c_smbus.c diff --git a/Documentation/devicetree/bindings/input/elan_i2c.txt b/Documentation/devicetree/bindings/input/elan_i2c.txt new file mode 100644 index 000000000000..ee3242c4ba67 --- /dev/null +++ b/Documentation/devicetree/bindings/input/elan_i2c.txt @@ -0,0 +1,34 @@ +Elantech I2C Touchpad + +Required properties: +- compatible: must be "elan,ekth3000". +- reg: I2C address of the chip. +- interrupt-parent: a phandle for the interrupt controller (see interrupt + binding[0]). +- interrupts: interrupt to which the chip is connected (see interrupt + binding[0]). + +Optional properties: +- wakeup-source: touchpad can be used as a wakeup source. +- pinctrl-names: should be "default" (see pinctrl binding [1]). +- pinctrl-0: a phandle pointing to the pin settings for the device (see + pinctrl binding [1]). +- vcc-supply: a phandle for the regulator supplying 3.3V power. + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt + +Example: + &i2c1 { + /* ... */ + + touchpad@15 { + compatible = "elan,ekth3000"; + reg = <0x15>; + interrupt-parent = <&gpio4>; + interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>; + wakeup-source; + }; + + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ac7269f90764..e6469ec7a90e 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -42,6 +42,7 @@ dlink D-Link Corporation dmo Data Modul AG ebv EBV Elektronik edt Emerging Display Technologies +elan Elan Microelectronic Corp. emmicro EM Microelectronic epcos EPCOS AG epfl Ecole Polytechnique Fédérale de Lausanne diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 366fc7ad5eb6..d8b46b0f2dbe 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -215,6 +215,36 @@ config MOUSE_CYAPA To compile this driver as a module, choose M here: the module will be called cyapa. +config MOUSE_ELAN_I2C + tristate "ELAN I2C Touchpad support" + depends on I2C + help + This driver adds support for Elan I2C/SMbus Trackpads. + + Say Y here if you have a ELAN I2C/SMbus Touchpad. + + To compile this driver as a module, choose M here: the module will be + called elan_i2c. + +config MOUSE_ELAN_I2C_I2C + bool "Enable I2C support" + depends on MOUSE_ELAN_I2C + default y + help + Say Y here if Elan Touchpad in your system is connected to + a standard I2C controller. + + If unsure, say Y. + +config MOUSE_ELAN_I2C_SMBUS + bool "Enable SMbus support" + depends on MOUSE_ELAN_I2C + help + Say Y here if Elan Touchpad in your system is connected to + a SMbus adapter. + + If unsure, say Y. + config MOUSE_INPORT tristate "InPort/MS/ATIXL busmouse" depends on ISA diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index dda507f8b3a2..560003dcac37 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o +obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o obj-$(CONFIG_MOUSE_INPORT) += inport.o obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o @@ -34,3 +35,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o + +elan_i2c-objs := elan_i2c_core.o +elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C) += elan_i2c_i2c.o +elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_SMBUS) += elan_i2c_smbus.o diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h new file mode 100644 index 000000000000..2e838626205f --- /dev/null +++ b/drivers/input/mouse/elan_i2c.h @@ -0,0 +1,86 @@ +/* + * Elan I2C/SMBus Touchpad driver + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: 林政維 (Duson Lin) + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#ifndef _ELAN_I2C_H +#define _ELAN_i2C_H + +#include + +#define ETP_ENABLE_ABS 0x0001 +#define ETP_ENABLE_CALIBRATE 0x0002 +#define ETP_DISABLE_CALIBRATE 0x0000 +#define ETP_DISABLE_POWER 0x0001 + +/* IAP Firmware handling */ +#define ETP_FW_NAME "elan_i2c.bin" +#define ETP_IAP_START_ADDR 0x0083 +#define ETP_FW_IAP_PAGE_ERR (1 << 5) +#define ETP_FW_IAP_INTF_ERR (1 << 4) +#define ETP_FW_PAGE_SIZE 64 +#define ETP_FW_PAGE_COUNT 768 +#define ETP_FW_SIZE (ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT) + +struct i2c_client; +struct completion; + +enum tp_mode { + IAP_MODE = 1, + MAIN_MODE +}; + +struct elan_transport_ops { + int (*initialize)(struct i2c_client *client); + int (*sleep_control)(struct i2c_client *, bool sleep); + int (*power_control)(struct i2c_client *, bool enable); + int (*set_mode)(struct i2c_client *client, u8 mode); + + int (*calibrate)(struct i2c_client *client); + int (*calibrate_result)(struct i2c_client *client, u8 *val); + + int (*get_baseline_data)(struct i2c_client *client, + bool max_baseliune, u8 *value); + + int (*get_version)(struct i2c_client *client, bool iap, u8 *version); + int (*get_sm_version)(struct i2c_client *client, u8 *version); + int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); + int (*get_product_id)(struct i2c_client *client, u8 *id); + + int (*get_max)(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y); + int (*get_resolution)(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y); + int (*get_num_traces)(struct i2c_client *client, + unsigned int *x_tracenum, + unsigned int *y_tracenum); + + int (*iap_get_mode)(struct i2c_client *client, enum tp_mode *mode); + int (*iap_reset)(struct i2c_client *client); + + int (*prepare_fw_update)(struct i2c_client *client); + int (*write_fw_block)(struct i2c_client *client, + const u8 *page, u16 checksum, int idx); + int (*finish_fw_update)(struct i2c_client *client, + struct completion *reset_done); + + int (*get_report)(struct i2c_client *client, u8 *report); +}; + +extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; + +#endif /* _ELAN_I2C_H */ diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c new file mode 100644 index 000000000000..0cb2be48d537 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_core.c @@ -0,0 +1,1137 @@ +/* + * Elan I2C/SMBus Touchpad driver + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: 林政維 (Duson Lin) + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "elan_i2c.h" + +#define DRIVER_NAME "elan_i2c" +#define ELAN_DRIVER_VERSION "1.5.5" +#define ETP_PRESSURE_OFFSET 25 +#define ETP_MAX_PRESSURE 255 +#define ETP_FWIDTH_REDUCE 90 +#define ETP_FINGER_WIDTH 15 +#define ETP_RETRY_COUNT 3 + +#define ETP_MAX_FINGERS 5 +#define ETP_FINGER_DATA_LEN 5 +#define ETP_REPORT_ID 0x5D +#define ETP_REPORT_ID_OFFSET 2 +#define ETP_TOUCH_INFO_OFFSET 3 +#define ETP_FINGER_DATA_OFFSET 4 +#define ETP_MAX_REPORT_LEN 34 + +/* The main device structure */ +struct elan_tp_data { + struct i2c_client *client; + struct input_dev *input; + struct regulator *vcc; + + const struct elan_transport_ops *ops; + + /* for fw update */ + struct completion fw_completion; + bool in_fw_update; + + struct mutex sysfs_mutex; + + unsigned int max_x; + unsigned int max_y; + unsigned int width_x; + unsigned int width_y; + unsigned int x_res; + unsigned int y_res; + + u8 product_id; + u8 fw_version; + u8 sm_version; + u8 iap_version; + u16 fw_checksum; + + u8 mode; + + bool irq_wake; + + u8 min_baseline; + u8 max_baseline; + bool baseline_ready; +}; + +static int elan_enable_power(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + error = regulator_enable(data->vcc); + if (error) { + dev_err(&data->client->dev, + "Failed to enable regulator: %d\n", error); + return error; + } + + do { + error = data->ops->power_control(data->client, true); + if (error >= 0) + return 0; + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_disable_power(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->power_control(data->client, false); + if (!error) { + error = regulator_disable(data->vcc); + if (error) { + dev_err(&data->client->dev, + "Failed to disable regulator: %d\n", + error); + /* Attempt to power the chip back up */ + data->ops->power_control(data->client, true); + break; + } + + return 0; + } + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_sleep(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->sleep_control(data->client, true); + if (!error) + return 0; + + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int __elan_initialize(struct elan_tp_data *data) +{ + struct i2c_client *client = data->client; + int error; + + error = data->ops->initialize(client); + if (error) { + dev_err(&client->dev, "device initialize failed: %d\n", error); + return error; + } + + data->mode |= ETP_ENABLE_ABS; + error = data->ops->set_mode(client, data->mode); + if (error) { + dev_err(&client->dev, + "failed to switch to absolute mode: %d\n", error); + return error; + } + + error = data->ops->sleep_control(client, false); + if (error) { + dev_err(&client->dev, + "failed to wake device up: %d\n", error); + return error; + } + + return 0; +} + +static int elan_initialize(struct elan_tp_data *data) +{ + int repeat = ETP_RETRY_COUNT; + int error; + + do { + error = __elan_initialize(data); + if (!error) + return 0; + + repeat--; + msleep(30); + } while (--repeat > 0); + + return error; +} + +static int elan_query_device_info(struct elan_tp_data *data) +{ + int error; + + error = data->ops->get_product_id(data->client, &data->product_id); + if (error) + return error; + + error = data->ops->get_version(data->client, false, &data->fw_version); + if (error) + return error; + + error = data->ops->get_checksum(data->client, false, + &data->fw_checksum); + if (error) + return error; + + error = data->ops->get_sm_version(data->client, &data->sm_version); + if (error) + return error; + + error = data->ops->get_version(data->client, true, &data->iap_version); + if (error) + return error; + + return 0; +} + +static unsigned int elan_convert_resolution(u8 val) +{ + /* + * (value from firmware) * 10 + 790 = dpi + * + * We also have to convert dpi to dots/mm (*10/254 to avoid floating + * point). + */ + + return ((int)(char)val * 10 + 790) * 10 / 254; +} + +static int elan_query_device_parameters(struct elan_tp_data *data) +{ + unsigned int x_traces, y_traces; + u8 hw_x_res, hw_y_res; + int error; + + error = data->ops->get_max(data->client, &data->max_x, &data->max_y); + if (error) + return error; + + error = data->ops->get_num_traces(data->client, &x_traces, &y_traces); + if (error) + return error; + + data->width_x = data->max_x / x_traces; + data->width_y = data->max_y / y_traces; + + error = data->ops->get_resolution(data->client, &hw_x_res, &hw_y_res); + if (error) + return error; + + data->x_res = elan_convert_resolution(hw_x_res); + data->y_res = elan_convert_resolution(hw_y_res); + + return 0; +} + +/* + ********************************************************** + * IAP firmware updater related routines + ********************************************************** + */ +static int elan_write_fw_block(struct elan_tp_data *data, + const u8 *page, u16 checksum, int idx) +{ + int retry = ETP_RETRY_COUNT; + int error; + + do { + error = data->ops->write_fw_block(data->client, + page, checksum, idx); + if (!error) + return 0; + + dev_dbg(&data->client->dev, + "IAP retrying page %d (error: %d)\n", idx, error); + } while (--retry > 0); + + return error; +} + +static int __elan_update_firmware(struct elan_tp_data *data, + const struct firmware *fw) +{ + struct i2c_client *client = data->client; + struct device *dev = &client->dev; + int i, j; + int error; + u16 iap_start_addr; + u16 boot_page_count; + u16 sw_checksum = 0, fw_checksum = 0; + + error = data->ops->prepare_fw_update(client); + if (error) + return error; + + iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); + + boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; + for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) { + u16 checksum = 0; + const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; + + for (j = 0; j < ETP_FW_PAGE_SIZE; j += 2) + checksum += ((page[j + 1] << 8) | page[j]); + + error = elan_write_fw_block(data, page, checksum, i); + if (error) { + dev_err(dev, "write page %d fail: %d\n", i, error); + return error; + } + + sw_checksum += checksum; + } + + /* Wait WDT reset and power on reset */ + msleep(600); + + error = data->ops->finish_fw_update(client, &data->fw_completion); + if (error) + return error; + + error = data->ops->get_checksum(client, true, &fw_checksum); + if (error) + return error; + + if (sw_checksum != fw_checksum) { + dev_err(dev, "checksum diff sw=[%04X], fw=[%04X]\n", + sw_checksum, fw_checksum); + return -EIO; + } + + return 0; +} + +static int elan_update_firmware(struct elan_tp_data *data, + const struct firmware *fw) +{ + struct i2c_client *client = data->client; + int retval; + + dev_dbg(&client->dev, "Starting firmware update....\n"); + + disable_irq(client->irq); + data->in_fw_update = true; + + retval = __elan_update_firmware(data, fw); + if (retval) { + dev_err(&client->dev, "firmware update failed: %d\n", retval); + data->ops->iap_reset(client); + } else { + /* Reinitialize TP after fw is updated */ + elan_initialize(data); + elan_query_device_info(data); + } + + data->in_fw_update = false; + enable_irq(client->irq); + + return retval; +} + +/* + ******************************************************************* + * SYSFS attributes + ******************************************************************* + */ +static ssize_t elan_sysfs_read_fw_checksum(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "0x%04x\n", data->fw_checksum); +} + +static ssize_t elan_sysfs_read_product_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->product_id); +} + +static ssize_t elan_sysfs_read_fw_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->fw_version); +} + +static ssize_t elan_sysfs_read_sm_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->sm_version); +} + +static ssize_t elan_sysfs_read_iap_ver(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%d.0\n", data->iap_version); +} + +static ssize_t elan_sysfs_update_fw(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + const struct firmware *fw; + int error; + + error = request_firmware(&fw, ETP_FW_NAME, dev); + if (error) { + dev_err(dev, "cannot load firmware %s: %d\n", + ETP_FW_NAME, error); + return error; + } + + /* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */ + if (fw->size != ETP_FW_SIZE) { + dev_err(dev, "invalid firmware size = %zu, expected %d.\n", + fw->size, ETP_FW_SIZE); + error = -EBADF; + goto out_release_fw; + } + + error = mutex_lock_interruptible(&data->sysfs_mutex); + if (error) + goto out_release_fw; + + error = elan_update_firmware(data, fw); + + mutex_unlock(&data->sysfs_mutex); + +out_release_fw: + release_firmware(fw); + return error ?: count; +} + +static ssize_t calibrate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int tries = 20; + int retval; + int error; + u8 val[3]; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + disable_irq(client->irq); + + data->mode |= ETP_ENABLE_CALIBRATE; + retval = data->ops->set_mode(client, data->mode); + if (retval) { + dev_err(dev, "failed to enable calibration mode: %d\n", + retval); + goto out; + } + + retval = data->ops->calibrate(client); + if (retval) { + dev_err(dev, "failed to start calibration: %d\n", + retval); + goto out_disable_calibrate; + } + + val[0] = 0xff; + do { + /* Wait 250ms before checking if calibration has completed. */ + msleep(250); + + retval = data->ops->calibrate_result(client, val); + if (retval) + dev_err(dev, "failed to check calibration result: %d\n", + retval); + else if (val[0] == 0) + break; /* calibration done */ + + } while (--tries); + + if (tries == 0) { + dev_err(dev, "failed to calibrate. Timeout.\n"); + retval = -ETIMEDOUT; + } + +out_disable_calibrate: + data->mode &= ~ETP_ENABLE_CALIBRATE; + error = data->ops->set_mode(data->client, data->mode); + if (error) { + dev_err(dev, "failed to disable calibration mode: %d\n", + error); + if (!retval) + retval = error; + } +out: + enable_irq(client->irq); + mutex_unlock(&data->sysfs_mutex); + return retval ?: count; +} + +static ssize_t elan_sysfs_read_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + enum tp_mode mode; + + error = mutex_lock_interruptible(&data->sysfs_mutex); + if (error) + return error; + + error = data->ops->iap_get_mode(data->client, &mode); + + mutex_unlock(&data->sysfs_mutex); + + if (error) + return error; + + return sprintf(buf, "%d\n", (int)mode); +} + +static DEVICE_ATTR(product_id, S_IRUGO, elan_sysfs_read_product_id, NULL); +static DEVICE_ATTR(firmware_version, S_IRUGO, elan_sysfs_read_fw_ver, NULL); +static DEVICE_ATTR(sample_version, S_IRUGO, elan_sysfs_read_sm_ver, NULL); +static DEVICE_ATTR(iap_version, S_IRUGO, elan_sysfs_read_iap_ver, NULL); +static DEVICE_ATTR(fw_checksum, S_IRUGO, elan_sysfs_read_fw_checksum, NULL); +static DEVICE_ATTR(mode, S_IRUGO, elan_sysfs_read_mode, NULL); +static DEVICE_ATTR(update_fw, S_IWUSR, NULL, elan_sysfs_update_fw); + +static DEVICE_ATTR_WO(calibrate); + +static struct attribute *elan_sysfs_entries[] = { + &dev_attr_product_id.attr, + &dev_attr_firmware_version.attr, + &dev_attr_sample_version.attr, + &dev_attr_iap_version.attr, + &dev_attr_fw_checksum.attr, + &dev_attr_calibrate.attr, + &dev_attr_mode.attr, + &dev_attr_update_fw.attr, + NULL, +}; + +static const struct attribute_group elan_sysfs_group = { + .attrs = elan_sysfs_entries, +}; + +static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + disable_irq(client->irq); + + data->baseline_ready = false; + + data->mode |= ETP_ENABLE_CALIBRATE; + retval = data->ops->set_mode(data->client, data->mode); + if (retval) { + dev_err(dev, "Failed to enable calibration mode to get baseline: %d\n", + retval); + goto out; + } + + msleep(250); + + retval = data->ops->get_baseline_data(data->client, true, + &data->max_baseline); + if (retval) { + dev_err(dev, "Failed to read max baseline form device: %d\n", + retval); + goto out_disable_calibrate; + } + + retval = data->ops->get_baseline_data(data->client, false, + &data->min_baseline); + if (retval) { + dev_err(dev, "Failed to read min baseline form device: %d\n", + retval); + goto out_disable_calibrate; + } + + data->baseline_ready = true; + +out_disable_calibrate: + data->mode &= ~ETP_ENABLE_CALIBRATE; + error = data->ops->set_mode(data->client, data->mode); + if (error) { + dev_err(dev, "Failed to disable calibration mode after acquiring baseline: %d\n", + error); + if (!retval) + retval = error; + } +out: + enable_irq(client->irq); + mutex_unlock(&data->sysfs_mutex); + return retval ?: count; +} + +static ssize_t min_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + if (!data->baseline_ready) { + retval = -ENODATA; + goto out; + } + + retval = snprintf(buf, PAGE_SIZE, "%d", data->min_baseline); + +out: + mutex_unlock(&data->sysfs_mutex); + return retval; +} + +static ssize_t max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int retval; + + retval = mutex_lock_interruptible(&data->sysfs_mutex); + if (retval) + return retval; + + if (!data->baseline_ready) { + retval = -ENODATA; + goto out; + } + + retval = snprintf(buf, PAGE_SIZE, "%d", data->max_baseline); + +out: + mutex_unlock(&data->sysfs_mutex); + return retval; +} + + +static DEVICE_ATTR_WO(acquire); +static DEVICE_ATTR_RO(min); +static DEVICE_ATTR_RO(max); + +static struct attribute *elan_baseline_sysfs_entries[] = { + &dev_attr_acquire.attr, + &dev_attr_min.attr, + &dev_attr_max.attr, + NULL, +}; + +static const struct attribute_group elan_baseline_sysfs_group = { + .name = "baseline", + .attrs = elan_baseline_sysfs_entries, +}; + +static const struct attribute_group *elan_sysfs_groups[] = { + &elan_sysfs_group, + &elan_baseline_sysfs_group, + NULL +}; + +/* + ****************************************************************** + * Elan isr functions + ****************************************************************** + */ +static void elan_report_contact(struct elan_tp_data *data, + int contact_num, bool contact_valid, + u8 *finger_data) +{ + struct input_dev *input = data->input; + unsigned int pos_x, pos_y; + unsigned int pressure, mk_x, mk_y; + unsigned int area_x, area_y, major, minor, new_pressure; + + + if (contact_valid) { + pos_x = ((finger_data[0] & 0xf0) << 4) | + finger_data[1]; + pos_y = ((finger_data[0] & 0x0f) << 8) | + finger_data[2]; + mk_x = (finger_data[3] & 0x0f); + mk_y = (finger_data[3] >> 4); + pressure = finger_data[4]; + + if (pos_x > data->max_x || pos_y > data->max_y) { + dev_dbg(input->dev.parent, + "[%d] x=%d y=%d over max (%d, %d)", + contact_num, pos_x, pos_y, + data->max_x, data->max_y); + return; + } + + /* + * To avoid treating large finger as palm, let's reduce the + * width x and y per trace. + */ + area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); + area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); + + major = max(area_x, area_y); + minor = min(area_x, area_y); + + new_pressure = pressure + ETP_PRESSURE_OFFSET; + if (new_pressure > ETP_MAX_PRESSURE) + new_pressure = ETP_MAX_PRESSURE; + + input_mt_slot(input, contact_num); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_POSITION_X, pos_x); + input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); + input_report_abs(input, ABS_MT_PRESSURE, new_pressure); + input_report_abs(input, ABS_TOOL_WIDTH, mk_x); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); + input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); + } else { + input_mt_slot(input, contact_num); + input_mt_report_slot_state(input, MT_TOOL_FINGER, false); + } +} + +static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) +{ + struct input_dev *input = data->input; + u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET]; + int i; + u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET]; + bool contact_valid; + + for (i = 0; i < ETP_MAX_FINGERS; i++) { + contact_valid = tp_info & (1U << (3 + i)); + elan_report_contact(data, i, contact_valid, finger_data); + + if (contact_valid) + finger_data += ETP_FINGER_DATA_LEN; + } + + input_report_key(input, BTN_LEFT, tp_info & 0x01); + input_mt_report_pointer_emulation(input, true); + input_sync(input); +} + +static irqreturn_t elan_isr(int irq, void *dev_id) +{ + struct elan_tp_data *data = dev_id; + struct device *dev = &data->client->dev; + int error; + u8 report[ETP_MAX_REPORT_LEN]; + + /* + * When device is connected to i2c bus, when all IAP page writes + * complete, the driver will receive interrupt and must read + * 0000 to confirm that IAP is finished. + */ + if (data->in_fw_update) { + complete(&data->fw_completion); + goto out; + } + + error = data->ops->get_report(data->client, report); + if (error) + goto out; + + if (report[ETP_REPORT_ID_OFFSET] != ETP_REPORT_ID) + dev_err(dev, "invalid report id data (%x)\n", + report[ETP_REPORT_ID_OFFSET]); + else + elan_report_absolute(data, report); + +out: + return IRQ_HANDLED; +} + +/* + ****************************************************************** + * Elan initialization functions + ****************************************************************** + */ +static int elan_setup_input_device(struct elan_tp_data *data) +{ + struct device *dev = &data->client->dev; + struct input_dev *input; + unsigned int max_width = max(data->width_x, data->width_y); + unsigned int min_width = min(data->width_x, data->width_y); + int error; + + input = devm_input_allocate_device(dev); + if (!input) + return -ENOMEM; + + input->name = "Elan Touchpad"; + input->id.bustype = BUS_I2C; + input_set_drvdata(input, data); + + error = input_mt_init_slots(input, ETP_MAX_FINGERS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(dev, "failed to initialize MT slots: %d\n", error); + return error; + } + + __set_bit(EV_ABS, input->evbit); + __set_bit(INPUT_PROP_POINTER, input->propbit); + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + __set_bit(BTN_LEFT, input->keybit); + + /* Set up ST parameters */ + input_set_abs_params(input, ABS_X, 0, data->max_x, 0, 0); + input_set_abs_params(input, ABS_Y, 0, data->max_y, 0, 0); + input_abs_set_res(input, ABS_X, data->x_res); + input_abs_set_res(input, ABS_Y, data->y_res); + input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); + input_set_abs_params(input, ABS_TOOL_WIDTH, 0, ETP_FINGER_WIDTH, 0, 0); + + /* And MT parameters */ + input_set_abs_params(input, ABS_MT_POSITION_X, 0, data->max_x, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, data->max_y, 0, 0); + input_abs_set_res(input, ABS_MT_POSITION_X, data->x_res); + input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res); + input_set_abs_params(input, ABS_MT_PRESSURE, 0, + ETP_MAX_PRESSURE, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, + ETP_FINGER_WIDTH * max_width, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, + ETP_FINGER_WIDTH * min_width, 0, 0); + + data->input = input; + + return 0; +} + +static void elan_disable_regulator(void *_data) +{ + struct elan_tp_data *data = _data; + + regulator_disable(data->vcc); +} + +static void elan_remove_sysfs_groups(void *_data) +{ + struct elan_tp_data *data = _data; + + sysfs_remove_groups(&data->client->dev.kobj, elan_sysfs_groups); +} + +static int elan_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + const struct elan_transport_ops *transport_ops; + struct device *dev = &client->dev; + struct elan_tp_data *data; + unsigned long irqflags; + int error; + + if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_I2C) && + i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + transport_ops = &elan_i2c_ops; + } else if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) && + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) { + transport_ops = &elan_smbus_ops; + } else { + dev_err(dev, "not a supported I2C/SMBus adapter\n"); + return -EIO; + } + + data = devm_kzalloc(&client->dev, sizeof(struct elan_tp_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + + data->ops = transport_ops; + data->client = client; + init_completion(&data->fw_completion); + mutex_init(&data->sysfs_mutex); + + data->vcc = devm_regulator_get(&client->dev, "vcc"); + if (IS_ERR(data->vcc)) { + error = PTR_ERR(data->vcc); + if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get 'vcc' regulator: %d\n", + error); + return error; + } + + error = regulator_enable(data->vcc); + if (error) { + dev_err(&client->dev, + "Failed to enable regulator: %d\n", error); + return error; + } + + error = devm_add_action(&client->dev, + elan_disable_regulator, data); + if (error) { + regulator_disable(data->vcc); + dev_err(&client->dev, + "Failed to add disable regulator action: %d\n", + error); + return error; + } + + /* Initialize the touchpad. */ + error = elan_initialize(data); + if (error) + return error; + + error = elan_query_device_info(data); + if (error) + return error; + + error = elan_query_device_parameters(data); + if (error) + return error; + + dev_dbg(&client->dev, + "Elan Touchpad Information:\n" + " Module product ID: 0x%04x\n" + " Firmware Version: 0x%04x\n" + " Sample Version: 0x%04x\n" + " IAP Version: 0x%04x\n" + " Max ABS X,Y: %d,%d\n" + " Width X,Y: %d,%d\n" + " Resolution X,Y: %d,%d (dots/mm)\n", + data->product_id, + data->fw_version, + data->sm_version, + data->iap_version, + data->max_x, data->max_y, + data->width_x, data->width_y, + data->x_res, data->y_res); + + /* Set up input device properties based on queried parameters. */ + error = elan_setup_input_device(data); + if (error) + return error; + + /* + * Systems using device tree should set up interrupt via DTS, + * the rest will use the default falling edge interrupts. + */ + irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, elan_isr, + irqflags | IRQF_ONESHOT, + client->name, data); + if (error) { + dev_err(&client->dev, "cannot register irq=%d\n", client->irq); + return error; + } + + error = sysfs_create_groups(&client->dev.kobj, elan_sysfs_groups); + if (error) { + dev_err(&client->dev, "failed to create sysfs attributes: %d\n", + error); + return error; + } + + error = devm_add_action(&client->dev, + elan_remove_sysfs_groups, data); + if (error) { + elan_remove_sysfs_groups(data); + dev_err(&client->dev, + "Failed to add sysfs cleanup action: %d\n", + error); + return error; + } + + error = input_register_device(data->input); + if (error) { + dev_err(&client->dev, "failed to register input device: %d\n", + error); + return error; + } + + /* + * Systems using device tree should set up wakeup via DTS, + * the rest will configure device as wakeup source by default. + */ + if (!client->dev.of_node) + device_init_wakeup(&client->dev, true); + + return 0; +} + +static int __maybe_unused elan_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int ret; + + /* + * We are taking the mutex to make sure sysfs operations are + * complete before we attempt to bring the device into low[er] + * power mode. + */ + ret = mutex_lock_interruptible(&data->sysfs_mutex); + if (ret) + return ret; + + disable_irq(client->irq); + + if (device_may_wakeup(dev)) { + ret = elan_sleep(data); + /* Enable wake from IRQ */ + data->irq_wake = (enable_irq_wake(client->irq) == 0); + } else { + ret = elan_disable_power(data); + } + + mutex_unlock(&data->sysfs_mutex); + return ret; +} + +static int __maybe_unused elan_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct elan_tp_data *data = i2c_get_clientdata(client); + int error; + + if (device_may_wakeup(dev) && data->irq_wake) { + disable_irq_wake(client->irq); + data->irq_wake = false; + } + + error = elan_enable_power(data); + if (error) + dev_err(dev, "power up when resuming failed: %d\n", error); + + error = elan_initialize(data); + if (error) + dev_err(dev, "initialize when resuming failed: %d\n", error); + + enable_irq(data->client->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); + +static const struct i2c_device_id elan_id[] = { + { DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, elan_id); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN0000", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, elan_acpi_id); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id elan_of_match[] = { + { .compatible = "elan,ekth3000" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, elan_of_match); +#endif + +static struct i2c_driver elan_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .pm = &elan_pm_ops, + .acpi_match_table = ACPI_PTR(elan_acpi_id), + .of_match_table = of_match_ptr(elan_of_match), + }, + .probe = elan_probe, + .id_table = elan_id, +}; + +module_i2c_driver(elan_driver); + +MODULE_AUTHOR("Duson Lin "); +MODULE_DESCRIPTION("Elan I2C/SMBus Touchpad driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ELAN_DRIVER_VERSION); diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c new file mode 100644 index 000000000000..97d4937fc244 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -0,0 +1,611 @@ +/* + * Elan I2C/SMBus Touchpad driver - I2C interface + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: 林政維 (Duson Lin) + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "elan_i2c.h" + +/* Elan i2c commands */ +#define ETP_I2C_RESET 0x0100 +#define ETP_I2C_WAKE_UP 0x0800 +#define ETP_I2C_SLEEP 0x0801 +#define ETP_I2C_DESC_CMD 0x0001 +#define ETP_I2C_REPORT_DESC_CMD 0x0002 +#define ETP_I2C_STAND_CMD 0x0005 +#define ETP_I2C_UNIQUEID_CMD 0x0101 +#define ETP_I2C_FW_VERSION_CMD 0x0102 +#define ETP_I2C_SM_VERSION_CMD 0x0103 +#define ETP_I2C_XY_TRACENUM_CMD 0x0105 +#define ETP_I2C_MAX_X_AXIS_CMD 0x0106 +#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 +#define ETP_I2C_RESOLUTION_CMD 0x0108 +#define ETP_I2C_IAP_VERSION_CMD 0x0110 +#define ETP_I2C_SET_CMD 0x0300 +#define ETP_I2C_POWER_CMD 0x0307 +#define ETP_I2C_FW_CHECKSUM_CMD 0x030F +#define ETP_I2C_IAP_CTRL_CMD 0x0310 +#define ETP_I2C_IAP_CMD 0x0311 +#define ETP_I2C_IAP_RESET_CMD 0x0314 +#define ETP_I2C_IAP_CHECKSUM_CMD 0x0315 +#define ETP_I2C_CALIBRATE_CMD 0x0316 +#define ETP_I2C_MAX_BASELINE_CMD 0x0317 +#define ETP_I2C_MIN_BASELINE_CMD 0x0318 + +#define ETP_I2C_REPORT_LEN 34 +#define ETP_I2C_DESC_LENGTH 30 +#define ETP_I2C_REPORT_DESC_LENGTH 158 +#define ETP_I2C_INF_LENGTH 2 +#define ETP_I2C_IAP_PASSWORD 0x1EA5 +#define ETP_I2C_IAP_RESET 0xF0F0 +#define ETP_I2C_MAIN_MODE_ON (1 << 9) +#define ETP_I2C_IAP_REG_L 0x01 +#define ETP_I2C_IAP_REG_H 0x06 + +static int elan_i2c_read_block(struct i2c_client *client, + u16 reg, u8 *val, u16 len) +{ + __le16 buf[] = { + cpu_to_le16(reg), + }; + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = client->flags & I2C_M_TEN, + .len = sizeof(buf), + .buf = (u8 *)buf, + }, + { + .addr = client->addr, + .flags = (client->flags & I2C_M_TEN) | I2C_M_RD, + .len = len, + .buf = val, + } + }; + int ret; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + return ret == ARRAY_SIZE(msgs) ? 0 : (ret < 0 ? ret : -EIO); +} + +static int elan_i2c_read_cmd(struct i2c_client *client, u16 reg, u8 *val) +{ + int retval; + + retval = elan_i2c_read_block(client, reg, val, ETP_I2C_INF_LENGTH); + if (retval < 0) { + dev_err(&client->dev, "reading cmd (0x%04x) fail.\n", reg); + return retval; + } + + return 0; +} + +static int elan_i2c_write_cmd(struct i2c_client *client, u16 reg, u16 cmd) +{ + __le16 buf[] = { + cpu_to_le16(reg), + cpu_to_le16(cmd), + }; + struct i2c_msg msg = { + .addr = client->addr, + .flags = client->flags & I2C_M_TEN, + .len = sizeof(buf), + .buf = (u8 *)buf, + }; + int ret; + + ret = i2c_transfer(client->adapter, &msg, 1); + return ret == 1 ? 0 : (ret < 0 ? ret : -EIO); +} + +static int elan_i2c_initialize(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int error; + u8 val[256]; + + error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); + if (error) { + dev_err(dev, "device reset failed: %d\n", error); + return error; + } + + /* Wait for the device to reset */ + msleep(100); + + /* get reset acknowledgement 0000 */ + error = i2c_master_recv(client, val, ETP_I2C_INF_LENGTH); + if (error < 0) { + dev_err(dev, "failed to read reset response: %d\n", error); + return error; + } + + error = elan_i2c_read_block(client, ETP_I2C_DESC_CMD, + val, ETP_I2C_DESC_LENGTH); + if (error) { + dev_err(dev, "cannot get device descriptor: %d\n", error); + return error; + } + + error = elan_i2c_read_block(client, ETP_I2C_REPORT_DESC_CMD, + val, ETP_I2C_REPORT_DESC_LENGTH); + if (error) { + dev_err(dev, "fetching report descriptor failed.: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_sleep_control(struct i2c_client *client, bool sleep) +{ + return elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, + sleep ? ETP_I2C_SLEEP : ETP_I2C_WAKE_UP); +} + +static int elan_i2c_power_control(struct i2c_client *client, bool enable) +{ + u8 val[2]; + u16 reg; + int error; + + error = elan_i2c_read_cmd(client, ETP_I2C_POWER_CMD, val); + if (error) { + dev_err(&client->dev, + "failed to read current power state: %d\n", + error); + return error; + } + + reg = le16_to_cpup((__le16 *)val); + if (enable) + reg &= ~ETP_DISABLE_POWER; + else + reg |= ETP_DISABLE_POWER; + + error = elan_i2c_write_cmd(client, ETP_I2C_POWER_CMD, reg); + if (error) { + dev_err(&client->dev, + "failed to write current power state: %d\n", + error); + return error; + } + + return 0; +} + +static int elan_i2c_set_mode(struct i2c_client *client, u8 mode) +{ + return elan_i2c_write_cmd(client, ETP_I2C_SET_CMD, mode); +} + + +static int elan_i2c_calibrate(struct i2c_client *client) +{ + return elan_i2c_write_cmd(client, ETP_I2C_CALIBRATE_CMD, 1); +} + +static int elan_i2c_calibrate_result(struct i2c_client *client, u8 *val) +{ + return elan_i2c_read_block(client, ETP_I2C_CALIBRATE_CMD, val, 1); +} + +static int elan_i2c_get_baseline_data(struct i2c_client *client, + bool max_baseline, u8 *value) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + max_baseline ? ETP_I2C_MAX_BASELINE_CMD : + ETP_I2C_MIN_BASELINE_CMD, + val); + if (error) + return error; + + *value = le16_to_cpup((__le16 *)val); + + return 0; +} + +static int elan_i2c_get_version(struct i2c_client *client, + bool iap, u8 *version) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + iap ? ETP_I2C_IAP_VERSION_CMD : + ETP_I2C_FW_VERSION_CMD, + val); + if (error) { + dev_err(&client->dev, "failed to get %s version: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *version = val[0]; + return 0; +} + +static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_SM_VERSION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get SM version: %d\n", error); + return error; + } + + *version = val[0]; + return 0; +} + +static int elan_i2c_get_product_id(struct i2c_client *client, u8 *id) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_UNIQUEID_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get product ID: %d\n", error); + return error; + } + + *id = val[0]; + return 0; +} + +static int elan_i2c_get_checksum(struct i2c_client *client, + bool iap, u16 *csum) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, + iap ? ETP_I2C_IAP_CHECKSUM_CMD : + ETP_I2C_FW_CHECKSUM_CMD, + val); + if (error) { + dev_err(&client->dev, "failed to get %s checksum: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *csum = le16_to_cpup((__le16 *)val); + return 0; +} + +static int elan_i2c_get_max(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_MAX_X_AXIS_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get X dimension: %d\n", error); + return error; + } + + *max_x = le16_to_cpup((__le16 *)val) & 0x0fff; + + error = elan_i2c_read_cmd(client, ETP_I2C_MAX_Y_AXIS_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get Y dimension: %d\n", error); + return error; + } + + *max_y = le16_to_cpup((__le16 *)val) & 0x0fff; + + return 0; +} + +static int elan_i2c_get_resolution(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_RESOLUTION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get resolution: %d\n", error); + return error; + } + + *hw_res_x = val[0]; + *hw_res_y = val[1]; + + return 0; +} + +static int elan_i2c_get_num_traces(struct i2c_client *client, + unsigned int *x_traces, + unsigned int *y_traces) +{ + int error; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_XY_TRACENUM_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get trace info: %d\n", error); + return error; + } + + *x_traces = val[0] - 1; + *y_traces = val[1] - 1; + + return 0; +} + +static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) +{ + int error; + u16 constant; + u8 val[3]; + + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); + if (error) { + dev_err(&client->dev, + "failed to read iap control register: %d\n", + error); + return error; + } + + constant = le16_to_cpup((__le16 *)val); + dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); + + *mode = (constant & ETP_I2C_MAIN_MODE_ON) ? MAIN_MODE : IAP_MODE; + + return 0; +} + +static int elan_i2c_iap_reset(struct i2c_client *client) +{ + int error; + + error = elan_i2c_write_cmd(client, ETP_I2C_IAP_RESET_CMD, + ETP_I2C_IAP_RESET); + if (error) { + dev_err(&client->dev, "cannot reset IC: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_set_flash_key(struct i2c_client *client) +{ + int error; + + error = elan_i2c_write_cmd(client, ETP_I2C_IAP_CMD, + ETP_I2C_IAP_PASSWORD); + if (error) { + dev_err(&client->dev, "cannot set flash key: %d\n", error); + return error; + } + + return 0; +} + +static int elan_i2c_prepare_fw_update(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int error; + enum tp_mode mode; + u8 val[3]; + u16 password; + + /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ + error = elan_i2c_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == IAP_MODE) { + /* Reset IC */ + error = elan_i2c_iap_reset(client); + if (error) + return error; + + msleep(30); + } + + /* Set flash key*/ + error = elan_i2c_set_flash_key(client); + if (error) + return error; + + /* Wait for F/W IAP initialization */ + msleep(mode == MAIN_MODE ? 100 : 30); + + /* Check if we are in IAP mode or not */ + error = elan_i2c_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == MAIN_MODE) { + dev_err(dev, "wrong mode: %d\n", mode); + return -EIO; + } + + /* Set flash key again */ + error = elan_i2c_set_flash_key(client); + if (error) + return error; + + /* Wait for F/W IAP initialization */ + msleep(30); + + /* read back to check we actually enabled successfully. */ + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CMD, val); + if (error) { + dev_err(dev, "cannot read iap password: %d\n", + error); + return error; + } + + password = le16_to_cpup((__le16 *)val); + if (password != ETP_I2C_IAP_PASSWORD) { + dev_err(dev, "wrong iap password: 0x%X\n", password); + return -EIO; + } + + return 0; +} + +static int elan_i2c_write_fw_block(struct i2c_client *client, + const u8 *page, u16 checksum, int idx) +{ + struct device *dev = &client->dev; + u8 page_store[ETP_FW_PAGE_SIZE + 4]; + u8 val[3]; + u16 result; + int ret, error; + + page_store[0] = ETP_I2C_IAP_REG_L; + page_store[1] = ETP_I2C_IAP_REG_H; + memcpy(&page_store[2], page, ETP_FW_PAGE_SIZE); + /* recode checksum at last two bytes */ + put_unaligned_le16(checksum, &page_store[ETP_FW_PAGE_SIZE + 2]); + + ret = i2c_master_send(client, page_store, sizeof(page_store)); + if (ret != sizeof(page_store)) { + error = ret < 0 ? ret : -EIO; + dev_err(dev, "Failed to write page %d: %d\n", idx, error); + return error; + } + + /* Wait for F/W to update one page ROM data. */ + msleep(20); + + error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); + if (error) { + dev_err(dev, "Failed to read IAP write result: %d\n", error); + return error; + } + + result = le16_to_cpup((__le16 *)val); + if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { + dev_err(dev, "IAP reports failed write: %04hx\n", + result); + return -EIO; + } + + return 0; +} + +static int elan_i2c_finish_fw_update(struct i2c_client *client, + struct completion *completion) +{ + struct device *dev = &client->dev; + long ret; + int error; + int len; + u8 buffer[ETP_I2C_INF_LENGTH]; + + reinit_completion(completion); + enable_irq(client->irq); + + error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); + if (!error) + ret = wait_for_completion_interruptible_timeout(completion, + msecs_to_jiffies(300)); + disable_irq(client->irq); + + if (error) { + dev_err(dev, "device reset failed: %d\n", error); + return error; + } else if (ret == 0) { + dev_err(dev, "timeout waiting for device reset\n"); + return -ETIMEDOUT; + } else if (ret < 0) { + error = ret; + dev_err(dev, "error waiting for device reset: %d\n", error); + return error; + } + + len = i2c_master_recv(client, buffer, ETP_I2C_INF_LENGTH); + if (len != ETP_I2C_INF_LENGTH) { + error = len < 0 ? len : -EIO; + dev_err(dev, "failed to read INT signal: %d (%d)\n", + error, len); + return error; + } + + return 0; +} + +static int elan_i2c_get_report(struct i2c_client *client, u8 *report) +{ + int len; + + len = i2c_master_recv(client, report, ETP_I2C_REPORT_LEN); + if (len < 0) { + dev_err(&client->dev, "failed to read report data: %d\n", len); + return len; + } + + if (len != ETP_I2C_REPORT_LEN) { + dev_err(&client->dev, + "wrong report length (%d vs %d expected)\n", + len, ETP_I2C_REPORT_LEN); + return -EIO; + } + + return 0; +} + +const struct elan_transport_ops elan_i2c_ops = { + .initialize = elan_i2c_initialize, + .sleep_control = elan_i2c_sleep_control, + .power_control = elan_i2c_power_control, + .set_mode = elan_i2c_set_mode, + + .calibrate = elan_i2c_calibrate, + .calibrate_result = elan_i2c_calibrate_result, + + .get_baseline_data = elan_i2c_get_baseline_data, + + .get_version = elan_i2c_get_version, + .get_sm_version = elan_i2c_get_sm_version, + .get_product_id = elan_i2c_get_product_id, + .get_checksum = elan_i2c_get_checksum, + + .get_max = elan_i2c_get_max, + .get_resolution = elan_i2c_get_resolution, + .get_num_traces = elan_i2c_get_num_traces, + + .iap_get_mode = elan_i2c_iap_get_mode, + .iap_reset = elan_i2c_iap_reset, + + .prepare_fw_update = elan_i2c_prepare_fw_update, + .write_fw_block = elan_i2c_write_fw_block, + .finish_fw_update = elan_i2c_finish_fw_update, + + .get_report = elan_i2c_get_report, +}; diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c new file mode 100644 index 000000000000..359bf8583d54 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_smbus.c @@ -0,0 +1,514 @@ +/* + * Elan I2C/SMBus Touchpad driver - SMBus interface + * + * Copyright (c) 2013 ELAN Microelectronics Corp. + * + * Author: 林政維 (Duson Lin) + * Version: 1.5.5 + * + * Based on cyapa driver: + * copyright (c) 2011-2012 Cypress Semiconductor, Inc. + * copyright (c) 2011-2012 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include +#include +#include +#include + +#include "elan_i2c.h" + +/* Elan SMbus commands */ +#define ETP_SMBUS_IAP_CMD 0x00 +#define ETP_SMBUS_ENABLE_TP 0x20 +#define ETP_SMBUS_SLEEP_CMD 0x21 +#define ETP_SMBUS_IAP_PASSWORD_WRITE 0x29 +#define ETP_SMBUS_IAP_PASSWORD_READ 0x80 +#define ETP_SMBUS_WRITE_FW_BLOCK 0x2A +#define ETP_SMBUS_IAP_RESET_CMD 0x2B +#define ETP_SMBUS_RANGE_CMD 0xA0 +#define ETP_SMBUS_FW_VERSION_CMD 0xA1 +#define ETP_SMBUS_XY_TRACENUM_CMD 0xA2 +#define ETP_SMBUS_SM_VERSION_CMD 0xA3 +#define ETP_SMBUS_UNIQUEID_CMD 0xA3 +#define ETP_SMBUS_RESOLUTION_CMD 0xA4 +#define ETP_SMBUS_HELLOPACKET_CMD 0xA7 +#define ETP_SMBUS_PACKET_QUERY 0xA8 +#define ETP_SMBUS_IAP_VERSION_CMD 0xAC +#define ETP_SMBUS_IAP_CTRL_CMD 0xAD +#define ETP_SMBUS_IAP_CHECKSUM_CMD 0xAE +#define ETP_SMBUS_FW_CHECKSUM_CMD 0xAF +#define ETP_SMBUS_MAX_BASELINE_CMD 0xC3 +#define ETP_SMBUS_MIN_BASELINE_CMD 0xC4 +#define ETP_SMBUS_CALIBRATE_QUERY 0xC5 + +#define ETP_SMBUS_REPORT_LEN 32 +#define ETP_SMBUS_REPORT_OFFSET 2 +#define ETP_SMBUS_HELLOPACKET_LEN 5 +#define ETP_SMBUS_IAP_PASSWORD 0x1234 +#define ETP_SMBUS_IAP_MODE_ON (1 << 6) + +static int elan_smbus_initialize(struct i2c_client *client) +{ + u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; + u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; + int len, error; + + /* Get hello packet */ + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_HELLOPACKET_CMD, values); + if (len != ETP_SMBUS_HELLOPACKET_LEN) { + dev_err(&client->dev, "hello packet length fail: %d\n", len); + error = len < 0 ? len : -EIO; + return error; + } + + /* compare hello packet */ + if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) { + dev_err(&client->dev, "hello packet fail [%*px]\n", + ETP_SMBUS_HELLOPACKET_LEN, values); + return -ENXIO; + } + + /* enable tp */ + error = i2c_smbus_write_byte(client, ETP_SMBUS_ENABLE_TP); + if (error) { + dev_err(&client->dev, "failed to enable touchpad: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_set_mode(struct i2c_client *client, u8 mode) +{ + u8 cmd[4] = { 0x00, 0x07, 0x00, mode }; + + return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); +} + +static int elan_smbus_sleep_control(struct i2c_client *client, bool sleep) +{ + if (sleep) + return i2c_smbus_write_byte(client, ETP_SMBUS_SLEEP_CMD); + else + return 0; /* XXX should we send ETP_SMBUS_ENABLE_TP here? */ +} + +static int elan_smbus_power_control(struct i2c_client *client, bool enable) +{ + return 0; /* A no-op */ +} + +static int elan_smbus_calibrate(struct i2c_client *client) +{ + u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 }; + + return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); +} + +static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) +{ + int error; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_CALIBRATE_QUERY, val); + if (error < 0) + return error; + + return 0; +} + +static int elan_smbus_get_baseline_data(struct i2c_client *client, + bool max_baseline, u8 *value) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + max_baseline ? + ETP_SMBUS_MAX_BASELINE_CMD : + ETP_SMBUS_MIN_BASELINE_CMD, + val); + if (error < 0) + return error; + + *value = be16_to_cpup((__be16 *)val); + + return 0; +} + +static int elan_smbus_get_version(struct i2c_client *client, + bool iap, u8 *version) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_IAP_VERSION_CMD : + ETP_SMBUS_FW_VERSION_CMD, + val); + if (error < 0) { + dev_err(&client->dev, "failed to get %s version: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *version = val[2]; + return 0; +} + +static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *version) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_SM_VERSION_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to get SM version: %d\n", error); + return error; + } + + *version = val[0]; /* XXX Why 0 and not 2 as in IAP/FW versions? */ + return 0; +} + +static int elan_smbus_get_product_id(struct i2c_client *client, u8 *id) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_UNIQUEID_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to get product ID: %d\n", error); + return error; + } + + *id = val[1]; + return 0; +} + +static int elan_smbus_get_checksum(struct i2c_client *client, + bool iap, u16 *csum) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + iap ? ETP_SMBUS_FW_CHECKSUM_CMD : + ETP_SMBUS_IAP_CHECKSUM_CMD, + val); + if (error < 0) { + dev_err(&client->dev, "failed to get %s checksum: %d\n", + iap ? "IAP" : "FW", error); + return error; + } + + *csum = be16_to_cpup((__be16 *)val); + return 0; +} + +static int elan_smbus_get_max(struct i2c_client *client, + unsigned int *max_x, unsigned int *max_y) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get dimensions: %d\n", error); + return error; + } + + *max_x = (0x0f & val[0]) << 8 | val[1]; + *max_y = (0xf0 & val[0]) << 4 | val[2]; + + return 0; +} + +static int elan_smbus_get_resolution(struct i2c_client *client, + u8 *hw_res_x, u8 *hw_res_y) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_RESOLUTION_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get resolution: %d\n", error); + return error; + } + + *hw_res_x = val[1] & 0x0F; + *hw_res_y = (val[1] & 0xF0) >> 4; + + return 0; +} + +static int elan_smbus_get_num_traces(struct i2c_client *client, + unsigned int *x_traces, + unsigned int *y_traces) +{ + int error; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_XY_TRACENUM_CMD, val); + if (error) { + dev_err(&client->dev, "failed to get trace info: %d\n", error); + return error; + } + + *x_traces = val[1] - 1; + *y_traces = val[2] - 1; + + return 0; +} + +static int elan_smbus_iap_get_mode(struct i2c_client *client, + enum tp_mode *mode) +{ + int error; + u16 constant; + u8 val[3]; + + error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); + if (error < 0) { + dev_err(&client->dev, "failed to read iap ctrol register: %d\n", + error); + return error; + } + + constant = be16_to_cpup((__be16 *)val); + dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); + + *mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE; + + return 0; +} + +static int elan_smbus_iap_reset(struct i2c_client *client) +{ + int error; + + error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD); + if (error) { + dev_err(&client->dev, "cannot reset IC: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_set_flash_key(struct i2c_client *client) +{ + int error; + u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A }; + + error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); + if (error) { + dev_err(&client->dev, "cannot set flash key: %d\n", error); + return error; + } + + return 0; +} + +static int elan_smbus_prepare_fw_update(struct i2c_client *client) +{ + struct device *dev = &client->dev; + int len; + int error; + enum tp_mode mode; + u8 val[3]; + u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; + u16 password; + + /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ + error = elan_smbus_iap_get_mode(client, &mode); + if (error) + return error; + + if (mode == MAIN_MODE) { + + /* set flash key */ + error = elan_smbus_set_flash_key(client); + if (error) + return error; + + /* write iap password */ + if (i2c_smbus_write_byte(client, + ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) { + dev_err(dev, "cannot write iap password\n"); + return -EIO; + } + + error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, + sizeof(cmd), cmd); + if (error) { + dev_err(dev, "failed to write iap password: %d\n", + error); + return error; + } + + /* + * Read back password to make sure we enabled flash + * successfully. + */ + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_IAP_PASSWORD_READ, + val); + if (len < sizeof(u16)) { + error = len < 0 ? len : -EIO; + dev_err(dev, "failed to read iap password: %d\n", + error); + return error; + } + + password = be16_to_cpup((__be16 *)val); + if (password != ETP_SMBUS_IAP_PASSWORD) { + dev_err(dev, "wrong iap password = 0x%X\n", password); + return -EIO; + } + + /* Wait 30ms for MAIN_MODE change to IAP_MODE */ + msleep(30); + } + + error = elan_smbus_set_flash_key(client); + if (error) + return error; + + /* Reset IC */ + error = elan_smbus_iap_reset(client); + if (error) + return error; + + return 0; +} + + +static int elan_smbus_write_fw_block(struct i2c_client *client, + const u8 *page, u16 checksum, int idx) +{ + struct device *dev = &client->dev; + int error; + u16 result; + u8 val[3]; + + /* + * Due to the limitation of smbus protocol limiting + * transfer to 32 bytes at a time, we must split block + * in 2 transfers. + */ + error = i2c_smbus_write_block_data(client, + ETP_SMBUS_WRITE_FW_BLOCK, + ETP_FW_PAGE_SIZE / 2, + page); + if (error) { + dev_err(dev, "Failed to write page %d (part %d): %d\n", + idx, 1, error); + return error; + } + + error = i2c_smbus_write_block_data(client, + ETP_SMBUS_WRITE_FW_BLOCK, + ETP_FW_PAGE_SIZE / 2, + page + ETP_FW_PAGE_SIZE / 2); + if (error) { + dev_err(dev, "Failed to write page %d (part %d): %d\n", + idx, 2, error); + return error; + } + + + /* Wait for F/W to update one page ROM data. */ + usleep_range(8000, 10000); + + error = i2c_smbus_read_block_data(client, + ETP_SMBUS_IAP_CTRL_CMD, val); + if (error < 0) { + dev_err(dev, "Failed to read IAP write result: %d\n", + error); + return error; + } + + result = be16_to_cpup((__be16 *)val); + if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { + dev_err(dev, "IAP reports failed write: %04hx\n", + result); + return -EIO; + } + + return 0; +} + +static int elan_smbus_get_report(struct i2c_client *client, u8 *report) +{ + int len; + + len = i2c_smbus_read_block_data(client, + ETP_SMBUS_PACKET_QUERY, + &report[ETP_SMBUS_REPORT_OFFSET]); + if (len < 0) { + dev_err(&client->dev, "failed to read report data: %d\n", len); + return len; + } + + if (len != ETP_SMBUS_REPORT_LEN) { + dev_err(&client->dev, + "wrong report length (%d vs %d expected)\n", + len, ETP_SMBUS_REPORT_LEN); + return -EIO; + } + + return 0; +} + +static int elan_smbus_finish_fw_update(struct i2c_client *client, + struct completion *fw_completion) +{ + /* No special handling unlike I2C transport */ + return 0; +} + +const struct elan_transport_ops elan_smbus_ops = { + .initialize = elan_smbus_initialize, + .sleep_control = elan_smbus_sleep_control, + .power_control = elan_smbus_power_control, + .set_mode = elan_smbus_set_mode, + + .calibrate = elan_smbus_calibrate, + .calibrate_result = elan_smbus_calibrate_result, + + .get_baseline_data = elan_smbus_get_baseline_data, + + .get_version = elan_smbus_get_version, + .get_sm_version = elan_smbus_get_sm_version, + .get_product_id = elan_smbus_get_product_id, + .get_checksum = elan_smbus_get_checksum, + + .get_max = elan_smbus_get_max, + .get_resolution = elan_smbus_get_resolution, + .get_num_traces = elan_smbus_get_num_traces, + + .iap_get_mode = elan_smbus_iap_get_mode, + .iap_reset = elan_smbus_iap_reset, + + .prepare_fw_update = elan_smbus_prepare_fw_update, + .write_fw_block = elan_smbus_write_fw_block, + .finish_fw_update = elan_smbus_finish_fw_update, + + .get_report = elan_smbus_get_report, +}; -- GitLab From ee4c148e8a6a749f821170976489a8ea1802fdbb Mon Sep 17 00:00:00 2001 From: Julien Catalano Date: Sun, 5 Oct 2014 20:23:11 +0200 Subject: [PATCH 1223/9457] trivial: net/mac802154: Fix Kconfig typo Signed-off-by: Julien Catalano Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac802154/Kconfig b/net/mac802154/Kconfig index 1818a99b3081..aa462b480a39 100644 --- a/net/mac802154/Kconfig +++ b/net/mac802154/Kconfig @@ -16,5 +16,5 @@ config MAC802154 been tested yet! If you plan to use HardMAC IEEE 802.15.4 devices, you can - say N here. Alternatievly you can say M to compile it as + say N here. Alternatively you can say M to compile it as module. -- GitLab From 39f6eb19cf85b08b8a926294750f5e79c50a6a7b Mon Sep 17 00:00:00 2001 From: Simon Vincent Date: Sun, 5 Oct 2014 20:23:12 +0200 Subject: [PATCH 1224/9457] ieee802154: 6lowpan: Drop PACKET_OTHERHOST skbs in 6lowpan There is no point processing pkts which are PACKET_OTHERHOST in 6lowpan as they are discarded as soon as they reach the ipv6 layer. Therefore we should drop them in the 6lowpan layer. Signed-off-by: Simon Vincent Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 44136297b673..56252ee157c9 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -515,6 +515,9 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, if (!netif_running(dev)) goto drop_skb; + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop_skb; + if (dev->type != ARPHRD_IEEE802154) goto drop_skb; -- GitLab From cd97a713acbc1b63feb67ba137c3b827fa4f2308 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:50 +0200 Subject: [PATCH 1225/9457] ieee802154: 6lowpan: fix byteorder for frag tag This patch fix byteorder issues with fragment tag of generation 802.15.4 6LoWPAN fragment header. net/ieee802154/6lowpan_rtnl.c:278:54: warning restricted __be16 degrades to integer net/ieee802154/6lowpan_rtnl.c:278:18: warning: incorrect type in assignment (different base types) net/ieee802154/6lowpan_rtnl.c:278:18: expected restricted __be16 [usertype] frag_tag net/ieee802154/6lowpan_rtnl.c:278:18: got unsigned short Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 56252ee157c9..2d547ea190e8 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -63,7 +63,7 @@ static LIST_HEAD(lowpan_devices); struct lowpan_dev_info { struct net_device *real_dev; /* real WPAN device ptr */ struct mutex dev_list_mtx; /* mutex for list ops */ - __be16 fragment_tag; + u16 fragment_tag; }; struct lowpan_dev_record { @@ -275,7 +275,8 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, dgram_size = lowpan_uncompress_size(skb, &dgram_offset) - skb->mac_len; - frag_tag = lowpan_dev_info(dev)->fragment_tag++; + frag_tag = htons(lowpan_dev_info(dev)->fragment_tag); + lowpan_dev_info(dev)->fragment_tag++; frag_hdr[0] = LOWPAN_DISPATCH_FRAG1 | ((dgram_size >> 8) & 0x07); frag_hdr[1] = dgram_size & 0xff; @@ -294,7 +295,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, frag_len + skb_network_header_len(skb)); if (rc) { pr_debug("%s unable to send FRAG1 packet (tag: %d)", - __func__, frag_tag); + __func__, ntohs(frag_tag)); goto err; } @@ -315,7 +316,7 @@ lowpan_xmit_fragmented(struct sk_buff *skb, struct net_device *dev, frag_len); if (rc) { pr_debug("%s unable to send a FRAGN packet. (tag: %d, offset: %d)\n", - __func__, frag_tag, skb_offset); + __func__, ntohs(frag_tag), skb_offset); goto err; } } while (skb_unprocessed > frag_cap); -- GitLab From f870b8c6314c85712ff1e82765a902d895b73f21 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:51 +0200 Subject: [PATCH 1226/9457] ieee802154: reassembly: fix tag byteorder This patch fix byte order handling in reassembly code of 802.15.4 6LoWPAN fragmentation handling. net/ieee802154/reassembly.c:58:43: warning: restricted __be16 degrades to integer Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/ieee802154/reassembly.c | 8 +++++--- net/ieee802154/reassembly.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c index 7cfcd6885225..9d980ed3ffe2 100644 --- a/net/ieee802154/reassembly.c +++ b/net/ieee802154/reassembly.c @@ -33,7 +33,7 @@ static const char lowpan_frags_cache_name[] = "lowpan-frags"; struct lowpan_frag_info { - __be16 d_tag; + u16 d_tag; u16 d_size; u8 d_offset; }; @@ -48,7 +48,7 @@ static struct inet_frags lowpan_frags; static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev, struct net_device *dev); -static unsigned int lowpan_hash_frag(__be16 tag, u16 d_size, +static unsigned int lowpan_hash_frag(u16 tag, u16 d_size, const struct ieee802154_addr *saddr, const struct ieee802154_addr *daddr) { @@ -330,11 +330,13 @@ static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type, { bool fail; u8 pattern = 0, low = 0; + __be16 d_tag = 0; fail = lowpan_fetch_skb(skb, &pattern, 1); fail |= lowpan_fetch_skb(skb, &low, 1); frag_info->d_size = (pattern & 7) << 8 | low; - fail |= lowpan_fetch_skb(skb, &frag_info->d_tag, 2); + fail |= lowpan_fetch_skb(skb, &d_tag, 2); + frag_info->d_tag = ntohs(d_tag); if (frag_type == LOWPAN_DISPATCH_FRAGN) { fail |= lowpan_fetch_skb(skb, &frag_info->d_offset, 1); diff --git a/net/ieee802154/reassembly.h b/net/ieee802154/reassembly.h index 74e4a7c98191..836b16fa001f 100644 --- a/net/ieee802154/reassembly.h +++ b/net/ieee802154/reassembly.h @@ -4,7 +4,7 @@ #include struct lowpan_create_arg { - __be16 tag; + u16 tag; u16 d_size; const struct ieee802154_addr *src; const struct ieee802154_addr *dst; @@ -15,7 +15,7 @@ struct lowpan_create_arg { struct lowpan_frag_queue { struct inet_frag_queue q; - __be16 tag; + u16 tag; u16 d_size; struct ieee802154_addr saddr; struct ieee802154_addr daddr; -- GitLab From c0bffc7ddc1383d20efa5c1a36b81e2df48cf65c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 6 Oct 2014 11:00:52 +0200 Subject: [PATCH 1227/9457] ieee802154: 6lowpan: fix sign of errno return val This patch fix ERR_PTR(-rc) to ERR_PTR(rc). The variable rc is already a negative errno value. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 2d547ea190e8..c7e07b8a8f9f 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -233,7 +233,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size, &master_hdr->source, size); if (rc < 0) { kfree_skb(frag); - return ERR_PTR(-rc); + return ERR_PTR(rc); } } else { frag = ERR_PTR(-ENOMEM); -- GitLab From 4b552bc9edfdc947862af225a0e2521edb5d37a0 Mon Sep 17 00:00:00 2001 From: Anantha Krishnan Date: Mon, 6 Oct 2014 16:31:49 +0530 Subject: [PATCH 1228/9457] Bluetooth: Add support for Acer [0489:e078] Add support for the QCA6174 chip. T: Bus=06 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e078 Rev=00.01 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb Signed-off-by: Anantha Krishnan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index d85ced27ebd5..25c874da5f2b 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -79,6 +79,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0489, 0xe057) }, { USB_DEVICE(0x0489, 0xe056) }, { USB_DEVICE(0x0489, 0xe05f) }, + { USB_DEVICE(0x0489, 0xe078) }, { USB_DEVICE(0x04c5, 0x1330) }, { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, @@ -130,6 +131,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index edfc17bfcd44..03ce301fca92 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -156,6 +156,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, -- GitLab From db9e0ee805901c4a7284fde1f12a8033f24d2e07 Mon Sep 17 00:00:00 2001 From: Simon Vincent Date: Mon, 6 Oct 2014 10:39:45 +0100 Subject: [PATCH 1229/9457] ieee802154: mrf24j40: Add support for MRF24J40MC The MRF24J40MC module has an external amplifier which should be enabled. The TX power has to be lowered to meet FCC regs. Signed-off-by: Simon Vincent Acked-by: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/mrf24j40.c | 32 +++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 07e0b887c350..b1e73bc6e398 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -43,6 +43,8 @@ #define REG_TXSTBL 0x2E /* TX Stabilization */ #define REG_INTSTAT 0x31 /* Interrupt Status */ #define REG_INTCON 0x32 /* Interrupt Control */ +#define REG_GPIO 0x33 /* GPIO */ +#define REG_TRISGPIO 0x34 /* GPIO direction */ #define REG_RFCTL 0x36 /* RF Control Mode Register */ #define REG_BBREG1 0x39 /* Baseband Registers */ #define REG_BBREG2 0x3A /* */ @@ -63,6 +65,7 @@ #define REG_SLPCON1 0x220 #define REG_WAKETIMEL 0x222 /* Wake-up Time Match Value Low */ #define REG_WAKETIMEH 0x223 /* Wake-up Time Match Value High */ +#define REG_TESTMODE 0x22F /* Test mode */ #define REG_RX_FIFO 0x300 /* Receive FIFO */ /* Device configuration: Only channels 11-26 on page 0 are supported. */ @@ -75,6 +78,8 @@ #define RX_FIFO_SIZE 144 /* From datasheet */ #define SET_CHANNEL_DELAY_US 192 /* From datasheet */ +enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC }; + /* Device Private Data */ struct mrf24j40 { struct spi_device *spi; @@ -691,6 +696,28 @@ static int mrf24j40_hw_init(struct mrf24j40 *devrec) if (ret) goto err_ret; + if (spi_get_device_id(devrec->spi)->driver_data == MRF24J40MC) { + /* Enable external amplifier. + * From MRF24J40MC datasheet section 1.3: Operation. + */ + read_long_reg(devrec, REG_TESTMODE, &val); + val |= 0x7; /* Configure GPIO 0-2 to control amplifier */ + write_long_reg(devrec, REG_TESTMODE, val); + + read_short_reg(devrec, REG_TRISGPIO, &val); + val |= 0x8; /* Set GPIO3 as output. */ + write_short_reg(devrec, REG_TRISGPIO, val); + + read_short_reg(devrec, REG_GPIO, &val); + val |= 0x8; /* Set GPIO3 HIGH to enable U5 voltage regulator */ + write_short_reg(devrec, REG_GPIO, val); + + /* Reduce TX pwr to meet FCC requirements. + * From MRF24J40MC datasheet section 3.1.1 + */ + write_long_reg(devrec, REG_RFCON3, 0x28); + } + return 0; err_ret: @@ -779,8 +806,9 @@ static int mrf24j40_remove(struct spi_device *spi) } static const struct spi_device_id mrf24j40_ids[] = { - { "mrf24j40", 0 }, - { "mrf24j40ma", 0 }, + { "mrf24j40", MRF24J40 }, + { "mrf24j40ma", MRF24J40MA }, + { "mrf24j40mc", MRF24J40MC }, { }, }; MODULE_DEVICE_TABLE(spi, mrf24j40_ids); -- GitLab From 464f029915de6379c8fcd18d5dd49e5b3d1a2cc5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:25 +0200 Subject: [PATCH 1230/9457] at86rf230: fix errno on tx timeout handling The rc variable is zero if we get a timeout. Instead of pass the rc variable to the async error handling function which try to recover the phy, we use a static -ETIMEDOUT errno. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index c9d2a752abd7..6857038111a0 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -995,7 +995,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) rc = wait_for_completion_interruptible_timeout(&lp->tx_complete, msecs_to_jiffies(lp->data->t_tx_timeout)); if (!rc) { - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_error(lp, ctx, -ETIMEDOUT); return -ETIMEDOUT; } -- GitLab From d06c21990fbbca644a31a3c851c22a8d1f5d0e66 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:26 +0200 Subject: [PATCH 1231/9457] at86rf230: add missing error handling This patch adds an async error handling function if sync state change runs into a timeout. The async error handling function tries to recover the phy state machine into a valid state. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 6857038111a0..44d2f1de31e0 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -690,8 +690,10 @@ at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state) rc = wait_for_completion_timeout(&lp->state_complete, msecs_to_jiffies(100)); - if (!rc) + if (!rc) { + at86rf230_async_error(lp, &lp->state, -ETIMEDOUT); return -ETIMEDOUT; + } return 0; } -- GitLab From 850f43acb1869edf2a8b355330819412066d6fa2 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:27 +0200 Subject: [PATCH 1232/9457] at86rf230: correct aret lifs and sifs handling This patch adds lifs/sifs handling only if max_frame_retries is above zero. The at86rf2xx datasheets says nothing about phy lifs/sifs handling. I asked the atmel support and they said lifs/sifs is done by phy when max_frame_retries is above zero. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 44d2f1de31e0..2a25324d3a64 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -89,6 +89,7 @@ struct at86rf230_local { struct at86rf230_state_change irq; bool tx_aret; + s8 max_frame_retries; bool is_tx; /* spinlock for is_tx protection */ spinlock_t lock; @@ -1001,6 +1002,9 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) return -ETIMEDOUT; } + if (lp->max_frame_retries > 0) + return 0; + /* Interfame spacing time, which is phy depend. * TODO * Move this handling in MAC 802.15.4 layer. @@ -1230,6 +1234,7 @@ at86rf230_set_frame_retries(struct ieee802154_dev *dev, s8 retries) return -EINVAL; lp->tx_aret = retries >= 0; + lp->max_frame_retries = retries; if (retries >= 0) rc = at86rf230_write_subreg(lp, SR_MAX_FRAME_RETRIES, retries); -- GitLab From 7ad38b8fbfeeaeddc3d89ba47f8de0ccbbcb1b67 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:28 +0200 Subject: [PATCH 1233/9457] at86rf230: correct at86rf2xx lifs timings Symbol rate is 16 us. Lifs is 40 symbols. 16 * 40 = 640 us. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 2a25324d3a64..b26135fd0a2d 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1267,7 +1267,7 @@ static struct at86rf2xx_chip_data at86rf233_data = { .t_frame = 4096, .t_p_ack = 545, .t_sifs = 192, - .t_lifs = 480, + .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel, @@ -1283,7 +1283,7 @@ static struct at86rf2xx_chip_data at86rf231_data = { .t_frame = 4096, .t_p_ack = 545, .t_sifs = 192, - .t_lifs = 480, + .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel, @@ -1299,7 +1299,7 @@ static struct at86rf2xx_chip_data at86rf212_data = { .t_frame = 4096, .t_p_ack = 545, .t_sifs = 192, - .t_lifs = 480, + .t_lifs = 640, .t_tx_timeout = 2000, .rssi_base_val = -100, .set_channel = at86rf212_set_channel, -- GitLab From 90566363b5f5e7660a2cfd9b8e70ccf51a1dbc44 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:29 +0200 Subject: [PATCH 1234/9457] at86rf230: squash unnecessary dereferencing This patch removes dereferencing irq number over spi struct. Instead we doing it directly over isr paramater. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b26135fd0a2d..09503fbd9953 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -904,7 +904,7 @@ static irqreturn_t at86rf230_isr(int irq, void *data) u8 *buf = ctx->buf; int rc; - disable_irq_nosync(lp->spi->irq); + disable_irq_nosync(irq); buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG; ctx->trx.len = 2; -- GitLab From e93102112c1659bd3b5991adc213816c792b9fbd Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:30 +0200 Subject: [PATCH 1235/9457] at86rf230: add missing enable_irq This patch adds a missing enable_irq when spi_async in isr failed. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 09503fbd9953..8754f158abbf 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -911,6 +911,7 @@ static irqreturn_t at86rf230_isr(int irq, void *data) ctx->msg.complete = at86rf230_irq_status; rc = spi_async(lp->spi, &ctx->msg); if (rc) { + enable_irq(irq); at86rf230_async_error(lp, ctx, rc); return IRQ_NONE; } -- GitLab From 35e92a8e1b9058a5f7da271a7a60264a4888f4b9 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:31 +0200 Subject: [PATCH 1236/9457] at86rf230: fix race condition When the driver waits for a tx completion currently the driver direct enables the irq. When we switching to RX_AACK_ON some steps afterwards the driver could receive a new frame and request resources which are already in use, for example irq state change resource. To be sure there are no new interrupts when we switching to RX_AACK_ON, we enable the irq when state change to RX_AACK_ON was completed. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 8754f158abbf..5dbec64eb786 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -705,6 +705,7 @@ at86rf230_tx_complete(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; + enable_irq(lp->spi->irq); complete(&lp->tx_complete); } @@ -860,7 +861,6 @@ at86rf230_irq_trx_end(struct at86rf230_local *lp) if (lp->is_tx) { lp->is_tx = 0; spin_unlock(&lp->lock); - enable_irq(lp->spi->irq); if (lp->tx_aret) return at86rf230_async_state_change(lp, &lp->irq, -- GitLab From 97fed795e70d97fb89ebd8c3efc30b33aa4ac1fa Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:32 +0200 Subject: [PATCH 1237/9457] at86rf230: fix enable_irq handling on async spi Sometimes the async state function is call in an context where the spi irq is diabled. This patch fix the handling to enable the irq when spi_async failed in the async state change calling chain. We do this by a context parameter irq_enable and evaluate this parameter when spi_async failed instead of returning spi_async errno. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 157 ++++++++++++++--------------- 1 file changed, 77 insertions(+), 80 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 5dbec64eb786..7a1a8e39b130 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -74,6 +74,8 @@ struct at86rf230_state_change { void (*complete)(void *context); u8 from_state; u8 to_state; + + bool irq_enable; }; struct at86rf230_local { @@ -292,10 +294,11 @@ struct at86rf230_local { #define AT86RF2XX_NUMREGS 0x3F -static int +static void at86rf230_async_state_change(struct at86rf230_local *lp, struct at86rf230_state_change *ctx, - const u8 state, void (*complete)(void *context)); + const u8 state, void (*complete)(void *context), + const bool irq_enable); static inline int __at86rf230_write(struct at86rf230_local *lp, @@ -452,7 +455,7 @@ at86rf230_async_error_recover(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL); + at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL, false); } static void @@ -462,21 +465,31 @@ at86rf230_async_error(struct at86rf230_local *lp, dev_err(&lp->spi->dev, "spi_async error %d\n", rc); at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, - at86rf230_async_error_recover); + at86rf230_async_error_recover, false); } /* Generic function to get some register value in async mode */ -static int +static void at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg, struct at86rf230_state_change *ctx, - void (*complete)(void *context)) + void (*complete)(void *context), + const bool irq_enable) { + int rc; + u8 *tx_buf = ctx->buf; tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG; ctx->trx.len = 2; ctx->msg.complete = complete; - return spi_async(lp->spi, &ctx->msg); + ctx->irq_enable = irq_enable; + rc = spi_async(lp->spi, &ctx->msg); + if (rc) { + if (irq_enable) + enable_irq(lp->spi->irq); + + at86rf230_async_error(lp, ctx, rc); + } } static void @@ -513,7 +526,8 @@ at86rf230_async_state_assert(void *context) if (ctx->to_state == STATE_TX_ON) { at86rf230_async_state_change(lp, ctx, STATE_FORCE_TX_ON, - ctx->complete); + ctx->complete, + ctx->irq_enable); return; } } @@ -536,7 +550,6 @@ at86rf230_async_state_delay(void *context) struct at86rf230_local *lp = ctx->lp; struct at86rf2xx_chip_data *c = lp->data; bool force = false; - int rc; /* The force state changes are will show as normal states in the * state status subregister. We change the to_state to the @@ -605,10 +618,9 @@ at86rf230_async_state_delay(void *context) udelay(1); change: - rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, - at86rf230_async_state_assert); - if (rc) - dev_err(&lp->spi->dev, "spi_async error %d\n", rc); + at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, + at86rf230_async_state_assert, + ctx->irq_enable); } static void @@ -623,10 +635,9 @@ at86rf230_async_state_change_start(void *context) /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */ if (trx_state == STATE_TRANSITION_IN_PROGRESS) { udelay(1); - rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, - at86rf230_async_state_change_start); - if (rc) - dev_err(&lp->spi->dev, "spi_async error %d\n", rc); + at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, + at86rf230_async_state_change_start, + ctx->irq_enable); return; } @@ -648,20 +659,28 @@ at86rf230_async_state_change_start(void *context) ctx->trx.len = 2; ctx->msg.complete = at86rf230_async_state_delay; rc = spi_async(lp->spi, &ctx->msg); - if (rc) + if (rc) { + if (ctx->irq_enable) + enable_irq(lp->spi->irq); + + at86rf230_async_error(lp, &lp->state, rc); dev_err(&lp->spi->dev, "spi_async error %d\n", rc); + } } -static int +static void at86rf230_async_state_change(struct at86rf230_local *lp, struct at86rf230_state_change *ctx, - const u8 state, void (*complete)(void *context)) + const u8 state, void (*complete)(void *context), + const bool irq_enable) { /* Initialization for the state change context */ ctx->to_state = state; ctx->complete = complete; - return at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, - at86rf230_async_state_change_start); + ctx->irq_enable = irq_enable; + at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, + at86rf230_async_state_change_start, + irq_enable); } static void @@ -682,12 +701,9 @@ at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state) { int rc; - rc = at86rf230_async_state_change(lp, &lp->state, state, - at86rf230_sync_state_change_complete); - if (rc) { - at86rf230_async_error(lp, &lp->state, rc); - return rc; - } + at86rf230_async_state_change(lp, &lp->state, state, + at86rf230_sync_state_change_complete, + false); rc = wait_for_completion_timeout(&lp->state_complete, msecs_to_jiffies(100)); @@ -714,12 +730,9 @@ at86rf230_tx_on(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - int rc; - rc = at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON, - at86rf230_tx_complete); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON, + at86rf230_tx_complete, true); } static void @@ -727,12 +740,9 @@ at86rf230_tx_trac_error(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - int rc; - rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, - at86rf230_tx_on); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_state_change(lp, ctx, STATE_TX_ON, + at86rf230_tx_on, true); } static void @@ -742,17 +752,14 @@ at86rf230_tx_trac_check(void *context) struct at86rf230_local *lp = ctx->lp; const u8 *buf = ctx->buf; const u8 trac = (buf[1] & 0xe0) >> 5; - int rc; /* If trac status is different than zero we need to do a state change * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver * state to TX_ON. */ if (trac) { - rc = at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, - at86rf230_tx_trac_error); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF, + at86rf230_tx_trac_error, true); return; } @@ -765,12 +772,9 @@ at86rf230_tx_trac_status(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - int rc; - rc = at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, - at86rf230_tx_trac_check); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx, + at86rf230_tx_trac_check, true); } static void @@ -823,15 +827,21 @@ at86rf230_rx_read_frame_complete(void *context) at86rf230_rx(lp, buf + 2, len); } -static int +static void at86rf230_rx_read_frame(struct at86rf230_local *lp) { + int rc; + u8 *buf = lp->irq.buf; buf[0] = CMD_FB; lp->irq.trx.len = AT86RF2XX_MAX_BUF; lp->irq.msg.complete = at86rf230_rx_read_frame_complete; - return spi_async(lp->spi, &lp->irq.msg); + rc = spi_async(lp->spi, &lp->irq.msg); + if (rc) { + enable_irq(lp->spi->irq); + at86rf230_async_error(lp, &lp->irq, rc); + } } static void @@ -839,7 +849,6 @@ at86rf230_rx_trac_check(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - int rc; /* Possible check on trac status here. This could be useful to make * some stats why receive is failed. Not used at the moment, but it's @@ -847,14 +856,10 @@ at86rf230_rx_trac_check(void *context) * The programming guide say do it so. */ - rc = at86rf230_rx_read_frame(lp); - if (rc) { - enable_irq(lp->spi->irq); - at86rf230_async_error(lp, ctx, rc); - } + at86rf230_rx_read_frame(lp); } -static int +static void at86rf230_irq_trx_end(struct at86rf230_local *lp) { spin_lock(&lp->lock); @@ -863,17 +868,19 @@ at86rf230_irq_trx_end(struct at86rf230_local *lp) spin_unlock(&lp->lock); if (lp->tx_aret) - return at86rf230_async_state_change(lp, &lp->irq, - STATE_FORCE_TX_ON, - at86rf230_tx_trac_status); + at86rf230_async_state_change(lp, &lp->irq, + STATE_FORCE_TX_ON, + at86rf230_tx_trac_status, + true); else - return at86rf230_async_state_change(lp, &lp->irq, - STATE_RX_AACK_ON, - at86rf230_tx_complete); + at86rf230_async_state_change(lp, &lp->irq, + STATE_RX_AACK_ON, + at86rf230_tx_complete, + true); } else { spin_unlock(&lp->lock); - return at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq, - at86rf230_rx_trac_check); + at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq, + at86rf230_rx_trac_check, true); } } @@ -884,12 +891,9 @@ at86rf230_irq_status(void *context) struct at86rf230_local *lp = ctx->lp; const u8 *buf = lp->irq.buf; const u8 irq = buf[1]; - int rc; if (irq & IRQ_TRX_END) { - rc = at86rf230_irq_trx_end(lp); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_irq_trx_end(lp); } else { enable_irq(lp->spi->irq); dev_err(&lp->spi->dev, "not supported irq %02x received\n", @@ -964,12 +968,9 @@ at86rf230_xmit_tx_on(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - int rc; - rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, - at86rf230_write_frame); - if (rc) - at86rf230_async_error(lp, ctx, rc); + at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON, + at86rf230_write_frame, false); } static int @@ -990,12 +991,8 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) if (lp->tx_aret) tx_complete = at86rf230_xmit_tx_on; - rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON, - tx_complete); - if (rc) { - at86rf230_async_error(lp, ctx, rc); - return rc; - } + at86rf230_async_state_change(lp, ctx, STATE_TX_ON, tx_complete, false); + rc = wait_for_completion_interruptible_timeout(&lp->tx_complete, msecs_to_jiffies(lp->data->t_tx_timeout)); if (!rc) { -- GitLab From 866665f29382b4f189a51a649661ede9e35e9ace Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 7 Oct 2014 10:38:33 +0200 Subject: [PATCH 1238/9457] at86rf230: remove unnecessary print of async error The async error function will already printout the errno over dev_err. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 7a1a8e39b130..6ebd665892d8 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -664,7 +664,6 @@ at86rf230_async_state_change_start(void *context) enable_irq(lp->spi->irq); at86rf230_async_error(lp, &lp->state, rc); - dev_err(&lp->spi->dev, "spi_async error %d\n", rc); } } -- GitLab From 48ec92fa4f16c0f71e95c31490c03b6c9e0e793b Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:10 +0000 Subject: [PATCH 1239/9457] Bluetooth: Refactor arguments of mgmt_device_connected The values of a lot of the mgmt_device_connected() parameters come straight from a hci_conn object. We can simplify the function by passing the full hci_conn pointer to it. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 5 ++--- net/bluetooth/hci_event.c | 14 ++++---------- net/bluetooth/l2cap_core.c | 4 +--- net/bluetooth/mgmt.c | 13 ++++++------- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 37ff1aef0845..f1407fe0fc5b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1310,9 +1310,8 @@ int mgmt_update_adv_data(struct hci_dev *hdev); void mgmt_discoverable_timeout(struct hci_dev *hdev); void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent); -void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class); +void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, + u32 flags, u8 *name, u8 name_len); void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason, bool mgmt_connected); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 8b0a2a6de419..6ee7de26cbb6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1577,8 +1577,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, struct inquiry_entry *e; if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, - name_len, conn->dev_class); + mgmt_device_connected(hdev, conn, 0, name, name_len); if (discov->state == DISCOVERY_STOPPED) return; @@ -2536,9 +2535,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + mgmt_device_connected(hdev, conn, 0, NULL, 0); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -3434,9 +3431,7 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, - conn->dev_class); + mgmt_device_connected(hdev, conn, 0, NULL, 0); if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; @@ -4214,8 +4209,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) } if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) - mgmt_device_connected(hdev, &conn->dst, conn->type, - conn->dst_type, 0, NULL, 0, NULL); + mgmt_device_connected(hdev, conn, 0, NULL, 0); conn->sec_level = BT_SECURITY_LOW; conn->handle = __le16_to_cpu(ev->handle); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b6f9777e057d..2ff5591bee97 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3873,9 +3873,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn, hci_dev_lock(hdev); if (test_bit(HCI_MGMT, &hdev->dev_flags) && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) - mgmt_device_connected(hdev, &hcon->dst, hcon->type, - hcon->dst_type, 0, NULL, 0, - hcon->dev_class); + mgmt_device_connected(hdev, hcon, 0, NULL, 0); hci_dev_unlock(hdev); l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index efb71b022ab6..fc275dca94f8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6171,16 +6171,15 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, return eir_len; } -void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, - u8 addr_type, u32 flags, u8 *name, u8 name_len, - u8 *dev_class) +void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, + u32 flags, u8 *name, u8 name_len) { char buf[512]; struct mgmt_ev_device_connected *ev = (void *) buf; u16 eir_len = 0; - bacpy(&ev->addr.bdaddr, bdaddr); - ev->addr.type = link_to_bdaddr(link_type, addr_type); + bacpy(&ev->addr.bdaddr, &conn->dst); + ev->addr.type = link_to_bdaddr(conn->type, conn->dst_type); ev->flags = __cpu_to_le32(flags); @@ -6188,9 +6187,9 @@ void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, name_len); - if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) + if (conn->dev_class && memcmp(conn->dev_class, "\0\0\0", 3) != 0) eir_len = eir_append_data(ev->eir, eir_len, - EIR_CLASS_OF_DEV, dev_class, 3); + EIR_CLASS_OF_DEV, conn->dev_class, 3); ev->eir_len = cpu_to_le16(eir_len); -- GitLab From fd45ada9105635a69cbaa2d142d502d402eef6fe Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:11 +0000 Subject: [PATCH 1240/9457] Bluetooth: Include ADV_IND report in Device Connected event There are scenarios when autoconnecting to a device after the reception of an ADV_IND report (action 0x02), in which userland might want to examine the report's contents. For instance, the Service Data might have changed and it would be useful to know ahead of time before starting any GATT procedures. Also, the ADV_IND may contain Manufacturer Specific data which would be lost if not propagated to userland. In fact, this patch results from the need to rebond with a device lacking persistent storage which notifies about losing its LTK in ADV_IND reports. This patch appends the ADV_IND report which triggered the autoconnection to the EIR Data in the Device Connected event. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_event.c | 32 ++++++++++++++++++++++---------- net/bluetooth/mgmt.c | 24 ++++++++++++++++++------ 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index f1407fe0fc5b..07ddeed62419 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -398,6 +398,8 @@ struct hci_conn { __u16 le_conn_interval; __u16 le_conn_latency; __u16 le_supv_timeout; + __u8 le_adv_data[HCI_MAX_AD_LENGTH]; + __u8 le_adv_data_len; __s8 rssi; __s8 tx_power; __s8 max_tx_power; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6ee7de26cbb6..96291530606d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4263,25 +4263,26 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, } /* This function requires the caller holds hdev->lock */ -static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, - u8 addr_type, u8 adv_type) +static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, + bdaddr_t *addr, + u8 addr_type, u8 adv_type) { struct hci_conn *conn; struct hci_conn_params *params; /* If the event is not connectable don't proceed further */ if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) - return; + return NULL; /* Ignore if the device is blocked */ if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) - return; + return NULL; /* Most controller will fail if we try to create new connections * while we have an existing one in slave role. */ if (hdev->conn_hash.le_num_slave > 0) - return; + return NULL; /* If we're not connectable only connect devices that we have in * our pend_le_conns list. @@ -4289,7 +4290,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type); if (!params) - return; + return NULL; switch (params->auto_connect) { case HCI_AUTO_CONN_DIRECT: @@ -4298,7 +4299,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, * incoming connections from slave devices. */ if (adv_type != LE_ADV_DIRECT_IND) - return; + return NULL; break; case HCI_AUTO_CONN_ALWAYS: /* Devices advertising with ADV_IND or ADV_DIRECT_IND @@ -4309,7 +4310,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, */ break; default: - return; + return NULL; } conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, @@ -4322,7 +4323,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, * count consistent once the connection is established. */ params->conn = hci_conn_get(conn); - return; + return conn; } switch (PTR_ERR(conn)) { @@ -4335,7 +4336,10 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, break; default: BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); + return NULL; } + + return NULL; } static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, @@ -4343,6 +4347,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, { struct discovery_state *d = &hdev->discovery; struct smp_irk *irk; + struct hci_conn *conn; bool match; u32 flags; @@ -4354,7 +4359,14 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, } /* Check if we have been requested to connect to this device */ - check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); + conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); + if (conn && type == LE_ADV_IND) { + /* Store report for later inclusion by + * mgmt_device_connected + */ + memcpy(conn->le_adv_data, data, len); + conn->le_adv_data_len = len; + } /* Passive scanning shouldn't trigger any device found events, * except for devices marked as CONN_REPORT for which we do send diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index fc275dca94f8..10caab587cca 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6183,13 +6183,25 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, ev->flags = __cpu_to_le32(flags); - if (name_len > 0) - eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, - name, name_len); + /* We must ensure that the EIR Data fields are ordered and + * unique. Keep it simple for now and avoid the problem by not + * adding any BR/EDR data to the LE adv. + */ + if (conn->le_adv_data_len > 0) { + memcpy(&ev->eir[eir_len], + conn->le_adv_data, conn->le_adv_data_len); + eir_len = conn->le_adv_data_len; + } else { + if (name_len > 0) + eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, + name, name_len); - if (conn->dev_class && memcmp(conn->dev_class, "\0\0\0", 3) != 0) - eir_len = eir_append_data(ev->eir, eir_len, - EIR_CLASS_OF_DEV, conn->dev_class, 3); + if (conn->dev_class && + memcmp(conn->dev_class, "\0\0\0", 3) != 0) + eir_len = eir_append_data(ev->eir, eir_len, + EIR_CLASS_OF_DEV, + conn->dev_class, 3); + } ev->eir_len = cpu_to_le16(eir_len); -- GitLab From ddbea5cff7d5e2a9727f72c948e92b676a061fc5 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Tue, 7 Oct 2014 08:44:12 +0000 Subject: [PATCH 1241/9457] Bluetooth: Remove redundant check on hci_conn's device class NULL-checking conn->dev_class is pointless since the variable is defined as an array, i.e. it will always be non-NULL. Signed-off-by: Alfonso Acosta Signed-off-by: Johan Hedberg --- net/bluetooth/mgmt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 10caab587cca..3fd88b06ed5a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6196,8 +6196,7 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name, name_len); - if (conn->dev_class && - memcmp(conn->dev_class, "\0\0\0", 3) != 0) + if (memcmp(conn->dev_class, "\0\0\0", 3) != 0) eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, conn->dev_class, 3); -- GitLab From 1ae2605e55c6ef640238fb2e03d044119acd9a37 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 13 Oct 2014 10:33:06 +0200 Subject: [PATCH 1242/9457] ieee802154: 6lowpan: improve packet registration This patch improves the packet registration handling. Instead of registration with module init we have a open count variable and registration the lowpan packet handler when it's needed. The open count variable should be protected by RTNL. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index c7e07b8a8f9f..da78fae5b301 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -58,6 +58,7 @@ #include "reassembly.h" static LIST_HEAD(lowpan_devices); +static int lowpan_open_count; /* private device info */ struct lowpan_dev_info { @@ -571,11 +572,17 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, return NET_RX_DROP; } +static struct packet_type lowpan_packet_type = { + .type = htons(ETH_P_IEEE802154), + .func = lowpan_rcv, +}; + static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct net_device *real_dev; struct lowpan_dev_record *entry; + int ret; pr_debug("adding new link\n"); @@ -610,9 +617,14 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, list_add_tail(&entry->list, &lowpan_devices); mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); - register_netdevice(dev); + ret = register_netdevice(dev); + if (ret >= 0) { + if (!lowpan_open_count) + dev_add_pack(&lowpan_packet_type); + lowpan_open_count++; + } - return 0; + return ret; } static void lowpan_dellink(struct net_device *dev, struct list_head *head) @@ -623,6 +635,10 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) ASSERT_RTNL(); + lowpan_open_count--; + if (!lowpan_open_count) + dev_remove_pack(&lowpan_packet_type); + mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { if (entry->ldev == dev) { @@ -685,11 +701,6 @@ static struct notifier_block lowpan_dev_notifier = { .notifier_call = lowpan_device_event, }; -static struct packet_type lowpan_packet_type = { - .type = htons(ETH_P_IEEE802154), - .func = lowpan_rcv, -}; - static int __init lowpan_init_module(void) { int err = 0; @@ -702,8 +713,6 @@ static int __init lowpan_init_module(void) if (err < 0) goto out_frag; - dev_add_pack(&lowpan_packet_type); - err = register_netdevice_notifier(&lowpan_dev_notifier); if (err < 0) goto out_pack; @@ -711,7 +720,6 @@ static int __init lowpan_init_module(void) return 0; out_pack: - dev_remove_pack(&lowpan_packet_type); lowpan_netlink_fini(); out_frag: lowpan_net_frag_exit(); @@ -723,8 +731,6 @@ static void __exit lowpan_cleanup_module(void) { lowpan_netlink_fini(); - dev_remove_pack(&lowpan_packet_type); - lowpan_net_frag_exit(); unregister_netdevice_notifier(&lowpan_dev_notifier); -- GitLab From c37a8106de1b8d286fe577599ccc9bbb0efdd7ad Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 13 Oct 2014 10:33:07 +0200 Subject: [PATCH 1243/9457] ieee802154: 6lowpan: add RTNL assertion This patch ensure that the rtnl lock is hold while newlink callback. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index da78fae5b301..0c1a49b51e57 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -584,6 +584,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, struct lowpan_dev_record *entry; int ret; + ASSERT_RTNL(); + pr_debug("adding new link\n"); if (!tb[IFLA_LINK]) -- GitLab From 89cbb0638e9b7ba6fab02558f47a29f144df1a19 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Sat, 11 Oct 2014 21:44:47 +0000 Subject: [PATCH 1244/9457] Bluetooth: Defer connection-parameter removal when unpairing Systematically removing the LE connection parameters and autoconnect action is inconvenient for rebonding without disconnecting from userland (i.e. unpairing followed by repairing without disconnecting). The parameters will be lost after unparing and userland needs to take care of book-keeping them and re-adding them. This patch allows userland to forget about parameter management when rebonding without disconnecting. It defers clearing the connection parameters when unparing without disconnecting, giving a chance of keeping the parameters if a repairing happens before the connection is closed. Signed-off-by: Alfonso Acosta Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 3 ++ net/bluetooth/mgmt.c | 51 ++++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 07ddeed62419..b8685a77a15e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -555,6 +555,7 @@ enum { HCI_CONN_STK_ENCRYPT, HCI_CONN_AUTH_INITIATOR, HCI_CONN_DROP, + HCI_CONN_PARAM_REMOVAL_PEND, }; static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b9517bd17190..11aac06d53ce 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -544,6 +544,9 @@ int hci_conn_del(struct hci_conn *conn) hci_conn_del_sysfs(conn); + if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags)) + hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type); + hci_dev_put(hdev); hci_conn_put(conn); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3fd88b06ed5a..9c4daf715cf8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2725,10 +2725,40 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, } if (cp->addr.type == BDADDR_BREDR) { + /* If disconnection is requested, then look up the + * connection. If the remote device is connected, it + * will be later used to terminate the link. + * + * Setting it to NULL explicitly will cause no + * termination of the link. + */ + if (cp->disconnect) + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, + &cp->addr.bdaddr); + else + conn = NULL; + err = hci_remove_link_key(hdev, &cp->addr.bdaddr); } else { u8 addr_type; + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, + &cp->addr.bdaddr); + if (conn) { + /* Defer clearing up the connection parameters + * until closing to give a chance of keeping + * them if a repairing happens. + */ + set_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); + + /* If disconnection is not requested, then + * clear the connection variable so that the + * link is not terminated. + */ + if (!cp->disconnect) + conn = NULL; + } + if (cp->addr.type == BDADDR_LE_PUBLIC) addr_type = ADDR_LE_DEV_PUBLIC; else @@ -2736,8 +2766,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type); - hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type); - err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type); } @@ -2747,17 +2775,9 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, goto unlock; } - if (cp->disconnect) { - if (cp->addr.type == BDADDR_BREDR) - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, - &cp->addr.bdaddr); - else - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, - &cp->addr.bdaddr); - } else { - conn = NULL; - } - + /* If the connection variable is set, then termination of the + * link is requested. + */ if (!conn) { err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, &rp, sizeof(rp)); @@ -3062,6 +3082,11 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) hci_conn_put(conn); mgmt_pending_remove(cmd); + + /* The device is paired so there is no need to remove + * its connection parameters anymore. + */ + clear_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags); } void mgmt_smp_complete(struct hci_conn *conn, bool complete) -- GitLab From ec511545ef791577ed9dd055e3b2d6d926b85daf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 13 Oct 2014 11:43:53 +0200 Subject: [PATCH 1245/9457] Bluetooth: Fix RFCOMM NSC response rfcomm_send_nsc expects CR to be either 0 or 1 since it is later passed to __mcc_type macro and shitfed. Unfortunatelly CR extracted from received frame type was not sanitized and shifted value was passed resulting in bogus response. Note: shifted value was also passed to other functions but was used only in if satements so this bug appears only for NSC case. The CR bit in the value octet shall be set to the same value as the CR bit in the type field octet of the not supported command frame but the CR bit for NCS response should be set to 0 since it is always a response. This was affecting TC_RFC_BV_25_C PTS qualification test. Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/rfcomm/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index af73bc3acb40..d0bbc737f162 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -78,7 +78,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); #define __get_type(b) ((b & 0xef)) #define __test_ea(b) ((b & 0x01)) -#define __test_cr(b) ((b & 0x02)) +#define __test_cr(b) (!!(b & 0x02)) #define __test_pf(b) ((b & 0x10)) #define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) @@ -904,7 +904,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) hdr->len = __len8(sizeof(*mcc) + 1); mcc = (void *) ptr; ptr += sizeof(*mcc); - mcc->type = __mcc_type(cr, RFCOMM_NSC); + mcc->type = __mcc_type(0, RFCOMM_NSC); mcc->len = __len8(1); /* Type that we didn't like */ -- GitLab From 15346a9c2875cae8e84c13196a2fc7428d9358d4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 13 Oct 2014 11:43:54 +0200 Subject: [PATCH 1246/9457] Bluetooth: Improve RFCOMM __test_pf macro robustness Value returned by this macro might be used as bit value so it should return either 0 or 1 to avoid possible bugs (similar to NSC bug) when shifting it. Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/rfcomm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index d0bbc737f162..bce9c3d39324 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -79,7 +79,7 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); #define __test_ea(b) ((b & 0x01)) #define __test_cr(b) (!!(b & 0x02)) -#define __test_pf(b) ((b & 0x10)) +#define __test_pf(b) (!!(b & 0x10)) #define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) #define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) -- GitLab From 4456c50d23d44352f4174a9a0cb75313d3150907 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Thu, 16 Oct 2014 10:21:55 +0800 Subject: [PATCH 1247/9457] Bluetooth: 6lowpan: remove unnecessary codes in give_skb_to_upper netif_rx() only returns NET_RX_DROP and NET_RX_SUCCESS, not returns negative value Signed-off-by: Li RongQing Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index c2e0d14433df..9b5c89b18718 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -249,19 +249,12 @@ static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *skb_cp; - int ret; skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) return -ENOMEM; - ret = netif_rx(skb_cp); - if (ret < 0) { - BT_DBG("receive skb %d", ret); - return NET_RX_DROP; - } - - return ret; + return netif_rx(skb_cp); } static int process_data(struct sk_buff *skb, struct net_device *netdev, -- GitLab From 11e3ff7072789ad4585870cbdde1be10c45f1cc4 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Mon, 13 Oct 2014 11:00:56 +0100 Subject: [PATCH 1248/9457] 6lowpan: Use skb_cow in IPHC decompression. Currently there are potentially 2 skb_copy_expand calls in IPHC decompression. This patch replaces this with one call to skb_cow which will check to see if there is enough headroom first to ensure it's only done if necessary and will handle alignment issues for cache. As skb_cow uses pskb_expand_head we ensure the skb isn't shared from bluetooth and ieee802.15.4 code that use the IPHC decompression. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/6lowpan/iphc.c | 47 ++++++++++++++++++----------------------- net/bluetooth/6lowpan.c | 4 ++++ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 142eef55c9e2..747b3ccfc4f8 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -174,30 +174,22 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb, static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, struct net_device *dev, skb_delivery_cb deliver_skb) { - struct sk_buff *new; int stat; - new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), - GFP_ATOMIC); - kfree_skb(skb); - - if (!new) - return -ENOMEM; - - skb_push(new, sizeof(struct ipv6hdr)); - skb_reset_network_header(new); - skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr)); + skb_push(skb, sizeof(struct ipv6hdr)); + skb_reset_network_header(skb); + skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr)); - new->protocol = htons(ETH_P_IPV6); - new->pkt_type = PACKET_HOST; - new->dev = dev; + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + skb->dev = dev; raw_dump_table(__func__, "raw skb data dump before receiving", - new->data, new->len); + skb->data, skb->len); - stat = deliver_skb(new, dev); + stat = deliver_skb(skb, dev); - kfree_skb(new); + consume_skb(skb); return stat; } @@ -460,7 +452,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, /* UDP data uncompression */ if (iphc0 & LOWPAN_IPHC_NH_C) { struct udphdr uh; - struct sk_buff *new; + const int needed = sizeof(struct udphdr) + sizeof(hdr); if (uncompress_udp_header(skb, &uh)) goto drop; @@ -468,14 +460,11 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, /* replace the compressed UDP head by the uncompressed UDP * header */ - new = skb_copy_expand(skb, sizeof(struct udphdr), - skb_tailroom(skb), GFP_ATOMIC); - kfree_skb(skb); - - if (!new) - return -ENOMEM; - - skb = new; + err = skb_cow(skb, needed); + if (unlikely(err)) { + kfree_skb(skb); + return err; + } skb_push(skb, sizeof(struct udphdr)); skb_reset_transport_header(skb); @@ -485,6 +474,12 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, (u8 *)&uh, sizeof(uh)); hdr.nexthdr = UIP_PROTO_UDP; + } else { + err = skb_cow(skb, sizeof(hdr)); + if (unlikely(err)) { + kfree_skb(skb); + return err; + } } hdr.payload_len = htons(skb->len); diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 9b5c89b18718..6c5c2eff45bd 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -309,6 +309,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (dev->type != ARPHRD_6LOWPAN) goto drop; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto drop; + /* check that it's our buffer */ if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { /* Copy the packet so that the IPv6 header is -- GitLab From ee93053d569b8b56e09a278fc9c41b7adf070a96 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Mon, 13 Oct 2014 19:24:45 +0100 Subject: [PATCH 1249/9457] Bluetooth: Fix missing channel unlock in l2cap_le_credits In the error case where credits is greater than max_credits there is a missing l2cap_chan_unlock before returning. Signed-off-by: Martin Townsend Tested-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2ff5591bee97..d46c5127f6c3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5492,6 +5492,7 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn, if (credits > max_credits) { BT_ERR("LE credits overflow"); l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_chan_unlock(chan); /* Return 0 so that we don't trigger an unnecessary * command reject packet. -- GitLab From b3020f0a35fc431f7acf3fba9a5b7376d79932e5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:07 +0200 Subject: [PATCH 1250/9457] ieee802154: mac802154: remove FSF address This patch removes the FSF address in files which belongs to ieee802154 and mac802154. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 ---- drivers/net/ieee802154/fakelb.c | 4 ---- drivers/net/ieee802154/mrf24j40.c | 4 ---- include/linux/nl802154.h | 4 ---- include/net/af_ieee802154.h | 4 ---- include/net/ieee802154.h | 4 ---- include/net/ieee802154_netdev.h | 4 ---- include/net/mac802154.h | 3 --- include/net/nl802154.h | 4 ---- include/net/wpan-phy.h | 4 ---- net/ieee802154/af802154.h | 4 ---- net/ieee802154/af_ieee802154.c | 4 ---- net/ieee802154/dgram.c | 4 ---- net/ieee802154/ieee802154.h | 4 ---- net/ieee802154/netlink.c | 4 ---- net/ieee802154/nl-mac.c | 4 ---- net/ieee802154/nl-phy.c | 4 ---- net/ieee802154/nl_policy.c | 4 ---- net/ieee802154/raw.c | 4 ---- net/ieee802154/wpan-class.c | 4 ---- net/mac802154/ieee802154_dev.c | 4 ---- net/mac802154/mac802154.h | 4 ---- net/mac802154/mac_cmd.c | 4 ---- net/mac802154/mib.c | 4 ---- net/mac802154/monitor.c | 4 ---- net/mac802154/rx.c | 4 ---- net/mac802154/tx.c | 4 ---- net/mac802154/wpan.c | 4 ---- 28 files changed, 111 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 6ebd665892d8..b8b1e40feeb8 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Alexander Smirnov diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 27d83207d24c..e4b1b1f66bd2 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index b1e73bc6e398..ba9a3960d26d 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -13,10 +13,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 20163b9a0eae..167342c2ce6b 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef NL802154_H diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h index 085940f7eeec..7d38e2ffd256 100644 --- a/include/net/af_ieee802154.h +++ b/include/net/af_ieee802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h index 0aa7122e8f15..4db4e320b2f5 100644 --- a/include/net/ieee802154.h +++ b/include/net/ieee802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 3b53c8e405e4..f87420689d70 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 2e67cdd19cdc..f95b98ec50a8 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -12,9 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef NET_MAC802154_H #define NET_MAC802154_H diff --git a/include/net/nl802154.h b/include/net/nl802154.h index b23548e04098..b5cdea29d9d9 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef IEEE802154_NL_H diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 10ab0fc6d4f7..65a05f19eb68 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov */ diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h index 8330a09bfc95..343b63e6f953 100644 --- a/net/ieee802154/af802154.h +++ b/net/ieee802154/af802154.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index 29e0de63001b..26da1e179737 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Maxim Gorbachyov diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index ef2ad8aaef13..71e99a0994e1 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h index 5d352f86979e..42ae63a345ab 100644 --- a/net/ieee802154/ieee802154.h +++ b/net/ieee802154/ieee802154.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #ifndef IEEE_802154_LOCAL_H #define IEEE_802154_LOCAL_H diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 9222966f5e6d..6c3c2595a201 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index c6bfe22bfa5e..78a1529e8bb2 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 972baf83411a..e943e20bcf09 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c index 3a703ab88348..35c432668454 100644 --- a/net/ieee802154/nl_policy.c +++ b/net/ieee802154/nl_policy.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 9d1f64806f02..3ffcf4a9de01 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 4955e0fe5883..9a2dfab5648d 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index b36b2b996578..6af6a2427aaf 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -14,10 +14,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h index 762a6f849c6b..e3503c1bc04e 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/mac802154.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index bf809131eef7..85f70edbe8dd 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Sergey Lapin * Dmitry Eremin-Solenikov diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 868a040fd422..d7e5df872be7 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index a68230e2b25f..81249bb7c935 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index a14cf9ede171..e99d9394d13a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Pavel Smolenskiy * Maxim Gorbachyov diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fdf4c0e67259..95ea412395c7 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 4ab86a57dca5..b11a98d824e0 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * * Written by: * Dmitry Eremin-Solenikov * Sergey Lapin -- GitLab From 139f14adab08223fda55759cb93b9b80ba4bfee7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:08 +0200 Subject: [PATCH 1251/9457] ieee802154: ieee802154_dev: fix align typo This patch fix a typo and fix align instead allign. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index 6af6a2427aaf..086d4a91ae45 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -263,7 +263,7 @@ ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) * +-----------------------+ * * Due to ieee802154 layer isn't aware of driver and MAC structures, - * so lets allign them here. + * so lets align them here. */ priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; -- GitLab From 57205c14ca9147c1907556f77998cf82624d9fd6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:09 +0200 Subject: [PATCH 1252/9457] mac802154: fix typo IEEE802515 to IEEE802154 This patch fixs a typo in address filter defines from IEEE802515 to IEEE802154. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 8 ++++---- drivers/net/ieee802154/cc2520.c | 8 ++++---- drivers/net/ieee802154/mrf24j40.c | 8 ++++---- include/net/mac802154.h | 8 ++++---- net/mac802154/mib.c | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b8b1e40feeb8..83a635f17367 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1097,7 +1097,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, { struct at86rf230_local *lp = dev->priv; - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); dev_vdbg(&lp->spi->dev, @@ -1106,7 +1106,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_SHORT_ADDR_1, addr >> 8); } - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 pan = le16_to_cpu(filt->pan_id); dev_vdbg(&lp->spi->dev, @@ -1115,7 +1115,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_PAN_ID_1, pan >> 8); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { u8 i, addr[8]; memcpy(addr, &filt->ieee_addr, 8); @@ -1125,7 +1125,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, __at86rf230_write(lp, RG_IEEE_ADDR_0 + i, addr[i]); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&lp->spi->dev, "at86rf230_set_hw_addr_filt called for panc change\n"); if (filt->pan_coord) diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 8a5ac7ab2300..571f280204b6 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -593,7 +593,7 @@ cc2520_filter(struct ieee802154_dev *dev, { struct cc2520_private *priv = dev->priv; - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); dev_vdbg(&priv->spi->dev, @@ -602,7 +602,7 @@ cc2520_filter(struct ieee802154_dev *dev, sizeof(panid), (u8 *)&panid); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for IEEE addr\n"); cc2520_write_ram(priv, CC2520RAM_IEEEADDR, @@ -610,7 +610,7 @@ cc2520_filter(struct ieee802154_dev *dev, (u8 *)&filt->ieee_addr); } - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); dev_vdbg(&priv->spi->dev, @@ -619,7 +619,7 @@ cc2520_filter(struct ieee802154_dev *dev, sizeof(addr), (u8 *)&addr); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for panc change\n"); if (filt->pan_coord) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index ba9a3960d26d..0006b9ad5127 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -462,7 +462,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, dev_dbg(printdev(devrec), "filter\n"); - if (changed & IEEE802515_AFILT_SADDR_CHANGED) { + if (changed & IEEE802154_AFILT_SADDR_CHANGED) { /* Short Addr */ u8 addrh, addrl; @@ -475,7 +475,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, "Set short addr to %04hx\n", filt->short_addr); } - if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { + if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { /* Device Address */ u8 i, addr[8]; @@ -491,7 +491,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, #endif } - if (changed & IEEE802515_AFILT_PANID_CHANGED) { + if (changed & IEEE802154_AFILT_PANID_CHANGED) { /* PAN ID */ u8 panidl, panidh; @@ -503,7 +503,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id); } - if (changed & IEEE802515_AFILT_PANC_CHANGED) { + if (changed & IEEE802154_AFILT_PANC_CHANGED) { /* Pan Coordinator */ u8 val; int ret; diff --git a/include/net/mac802154.h b/include/net/mac802154.h index f95b98ec50a8..70351de3a72c 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -32,13 +32,13 @@ */ /* indicates that the Short Address changed */ -#define IEEE802515_AFILT_SADDR_CHANGED 0x00000001 +#define IEEE802154_AFILT_SADDR_CHANGED 0x00000001 /* indicates that the IEEE Address changed */ -#define IEEE802515_AFILT_IEEEADDR_CHANGED 0x00000002 +#define IEEE802154_AFILT_IEEEADDR_CHANGED 0x00000002 /* indicates that the PAN ID changed */ -#define IEEE802515_AFILT_PANID_CHANGED 0x00000004 +#define IEEE802154_AFILT_PANID_CHANGED 0x00000004 /* indicates that PAN Coordinator status changed */ -#define IEEE802515_AFILT_PANC_CHANGED 0x00000008 +#define IEEE802154_AFILT_PANC_CHANGED 0x00000008 struct ieee802154_hw_addr_filt { __le16 pan_id; /* Each independent PAN selects a unique diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index d7e5df872be7..3ee604292238 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -89,7 +89,7 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) if ((priv->hw->ops->set_hw_addr_filt) && (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { priv->hw->hw.hw_filt.short_addr = priv->short_addr; - set_hw_addr_filt(dev, IEEE802515_AFILT_SADDR_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } @@ -117,7 +117,7 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev) if (mac->ops->set_hw_addr_filt && mac->hw.hw_filt.ieee_addr != priv->extended_addr) { mac->hw.hw_filt.ieee_addr = priv->extended_addr; - set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } @@ -148,7 +148,7 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) if ((priv->hw->ops->set_hw_addr_filt) && (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { priv->hw->hw.hw_filt.pan_id = priv->pan_id; - set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); + set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } -- GitLab From 4896167d9761ede678c36999eea0450c355991d4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:10 +0200 Subject: [PATCH 1253/9457] ieee802154: wpan-phy: change to __aligned(size) This patch fix a checkpatch warning that __aligned(size) is preferred over __attribute__((aligned(size))). Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/wpan-phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 65a05f19eb68..fa827c923391 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -65,7 +65,7 @@ struct wpan_phy { u8 retries); int (*set_frame_retries)(struct wpan_phy *phy, s8 retries); - char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); + char priv[0] __aligned(NETDEV_ALIGN); }; #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) -- GitLab From e72740d057fea18be17587ff84ecebf09b30ca7d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:11 +0200 Subject: [PATCH 1254/9457] ieee802154: wpan-phy: use blank line after function This patch adds a blank line after function declaration. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/wpan-phy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index fa827c923391..1e9795f116ba 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -75,6 +75,7 @@ static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) { phy->dev.parent = dev; } + int wpan_phy_register(struct wpan_phy *phy); void wpan_phy_unregister(struct wpan_phy *phy); void wpan_phy_free(struct wpan_phy *phy); -- GitLab From ed1da148178d90bc21d96f35cfa62f969362495f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 05:25:12 +0200 Subject: [PATCH 1255/9457] ieee802154: wpan-class: fix trailing semicolon This patch removes an unnecessary tailing semicolon after macro define. Otherwise we get a trailing semicolon while using this macro. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/wpan-class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 9a2dfab5648d..e4c6fb31a360 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -33,7 +33,7 @@ static ssize_t name ## _show(struct device *dev, \ mutex_unlock(&phy->pib_lock); \ return ret; \ } \ -static DEVICE_ATTR_RO(name); +static DEVICE_ATTR_RO(name) #define MASTER_SHOW(field, format_string) \ MASTER_SHOW_COMPLEX(field, format_string, phy->field) -- GitLab From 46ee98a206c1fa6fc394791fb6188a47820a80b5 Mon Sep 17 00:00:00 2001 From: Vlad Dogaru Date: Thu, 23 Oct 2014 15:52:00 +0100 Subject: [PATCH 1256/9457] bmp280: use correct routine for division The proper way to divide two signed 64-bit values is to use div64_s64. Signed-off-by: Vlad Dogaru Reported-by: kbuild test robot Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c index fb91cb35b331..ce29ff91bce7 100644 --- a/drivers/iio/pressure/bmp280.c +++ b/drivers/iio/pressure/bmp280.c @@ -239,7 +239,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data, return 0; p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125; - do_div(p, var1); + p = div64_s64(p, var1); var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((s64) comp->dig_p8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4); -- GitLab From 4d5ce6bb11abee638052d8682263008fea57e068 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Thu, 23 Oct 2014 12:44:00 +0100 Subject: [PATCH 1257/9457] iio: Add ABI documentation for offset and scaled humidity This patch adds ABI documentation entries for in_humidityrelative_offset and in_humidityrelative_scale, since there is at least one user for these, Si7005 humidity and temperature sensor driver. Signed-off-by: Roberta Dobrescu Reviewed-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 5a7fc666b07e..d9dd70f591ab 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -238,6 +238,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset +What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_offset KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -273,6 +274,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_magnetic_tilt_comp_sca What: /sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale +What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_scale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: -- GitLab From ed56330df215b014c45940cceb97590d283b865f Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Fri, 24 Oct 2014 22:41:00 +0100 Subject: [PATCH 1258/9457] iio: Add ABI documentation for RGBC intensity hardware gain factor This patch adds documentation for RGBC in_intensity_*_hardwaregain. There is at least one user for these, ADJD-S311-CR999 digital color sensor driver. Signed-off-by: Roberta Dobrescu Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index d9dd70f591ab..ea7e7abbbdf4 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -337,6 +337,10 @@ Description: are listed in this attribute. What /sys/bus/iio/devices/iio:deviceX/out_voltageY_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_hardwaregain +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_clear_hardwaregain KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: -- GitLab From a9bef750135cc261bfceff6840a30a3f357df8da Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Wed, 22 Oct 2014 16:50:17 +0300 Subject: [PATCH 1259/9457] staging: iio: iio_event_monitor: Add support for missing IIO modifiers This patch adds the missing IIO modifiers in event_is_known function and iio_modifier_names vector. Additionally, it removes duplicate name entries of IIO_MOD_LIGHT_BOTH and IIO_MOD_LIGHT_IR in iio_modifier_names. Signed-off-by: Roberta Dobrescu Reviewed-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- .../iio/Documentation/iio_event_monitor.c | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 569d6f8face5..940ed2399e73 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -69,16 +69,29 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_X] = "x", [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", + [IIO_MOD_X_AND_Y] = "x&y", + [IIO_MOD_X_AND_Z] = "x&z", + [IIO_MOD_Y_AND_Z] = "y&z", + [IIO_MOD_X_AND_Y_AND_Z] = "x&y&z", + [IIO_MOD_X_OR_Y] = "x|y", + [IIO_MOD_X_OR_Z] = "x|z", + [IIO_MOD_Y_OR_Z] = "y|z", + [IIO_MOD_X_OR_Y_OR_Z] = "x|y|z", [IIO_MOD_LIGHT_BOTH] = "both", [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)", [IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2", - [IIO_MOD_LIGHT_BOTH] = "both", - [IIO_MOD_LIGHT_IR] = "ir", [IIO_MOD_LIGHT_CLEAR] = "clear", [IIO_MOD_LIGHT_RED] = "red", [IIO_MOD_LIGHT_GREEN] = "green", [IIO_MOD_LIGHT_BLUE] = "blue", + [IIO_MOD_QUATERNION] = "quaternion", + [IIO_MOD_TEMP_AMBIENT] = "ambient", + [IIO_MOD_TEMP_OBJECT] = "object", + [IIO_MOD_NORTH_MAGN] = "from_north_magnetic", + [IIO_MOD_NORTH_TRUE] = "from_north_true", + [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp", + [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp", }; static bool event_is_known(struct iio_event_data *event) @@ -118,6 +131,14 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_X: case IIO_MOD_Y: case IIO_MOD_Z: + case IIO_MOD_X_AND_Y: + case IIO_MOD_X_AND_Z: + case IIO_MOD_Y_AND_Z: + case IIO_MOD_X_AND_Y_AND_Z: + case IIO_MOD_X_OR_Y: + case IIO_MOD_X_OR_Z: + case IIO_MOD_Y_OR_Z: + case IIO_MOD_X_OR_Y_OR_Z: case IIO_MOD_LIGHT_BOTH: case IIO_MOD_LIGHT_IR: case IIO_MOD_ROOT_SUM_SQUARED_X_Y: @@ -126,6 +147,13 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_LIGHT_RED: case IIO_MOD_LIGHT_GREEN: case IIO_MOD_LIGHT_BLUE: + case IIO_MOD_QUATERNION: + case IIO_MOD_TEMP_AMBIENT: + case IIO_MOD_TEMP_OBJECT: + case IIO_MOD_NORTH_MAGN: + case IIO_MOD_NORTH_TRUE: + case IIO_MOD_NORTH_MAGN_TILT_COMP: + case IIO_MOD_NORTH_TRUE_TILT_COMP: break; default: return false; -- GitLab From acd8256723f286b7217801fbed24503f8565b91e Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 22 Oct 2014 18:29:43 +0300 Subject: [PATCH 1260/9457] iio: inkern: Add of_xlate function to struct iio_info When #iio-cells is greater than '0', the driver could provide a custom of_xlate function that reads the *args* and returns the appropriate index in registered IIO channels array. Add simple translation function, suitable for the most 1:1 mapped channels in IIO chips, and use it when driver did not provide custom implementation. Signed-off-by: Ivan T. Ivanov Reviewed-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 33 ++++++++++++++++++++++++++++----- include/linux/iio/iio.h | 8 ++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index c7497009d60a..0cc505d98686 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -100,6 +100,28 @@ static int iio_dev_node_match(struct device *dev, void *data) return dev->of_node == data && dev->type == &iio_device_type; } +/** + * __of_iio_simple_xlate - translate iiospec to the IIO channel index + * @indio_dev: pointer to the iio_dev structure + * @iiospec: IIO specifier as found in the device tree + * + * This is simple translation function, suitable for the most 1:1 mapped + * channels in IIO chips. This function performs only one sanity check: + * whether IIO index is less than num_channels (that is specified in the + * iio_dev). + */ +static int __of_iio_simple_xlate(struct iio_dev *indio_dev, + const struct of_phandle_args *iiospec) +{ + if (!iiospec->args_count) + return 0; + + if (iiospec->args[0] >= indio_dev->num_channels) + return -EINVAL; + + return iiospec->args[0]; +} + static int __of_iio_channel_get(struct iio_channel *channel, struct device_node *np, int index) { @@ -122,18 +144,19 @@ static int __of_iio_channel_get(struct iio_channel *channel, indio_dev = dev_to_iio_dev(idev); channel->indio_dev = indio_dev; - index = iiospec.args_count ? iiospec.args[0] : 0; - if (index >= indio_dev->num_channels) { - err = -EINVAL; + if (indio_dev->info->of_xlate) + index = indio_dev->info->of_xlate(indio_dev, &iiospec); + else + index = __of_iio_simple_xlate(indio_dev, &iiospec); + if (index < 0) goto err_put; - } channel->channel = &indio_dev->channels[index]; return 0; err_put: iio_device_put(indio_dev); - return err; + return index; } static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 15dc6bc2bdd2..3642ce7ef512 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -13,6 +13,7 @@ #include #include #include +#include /* IIO TODO LIST */ /* * Provide means of adjusting timer accuracy. @@ -326,6 +327,11 @@ struct iio_dev; * @update_scan_mode: function to configure device and scan buffer when * channels have changed * @debugfs_reg_access: function to read or write register value of device + * @of_xlate: function pointer to obtain channel specifier index. + * When #iio-cells is greater than '0', the driver could + * provide a custom of_xlate function that reads the + * *args* and returns the appropriate index in registered + * IIO channels array. **/ struct iio_info { struct module *driver_module; @@ -385,6 +391,8 @@ struct iio_info { int (*debugfs_reg_access)(struct iio_dev *indio_dev, unsigned reg, unsigned writeval, unsigned *readval); + int (*of_xlate)(struct iio_dev *indio_dev, + const struct of_phandle_args *iiospec); }; /** -- GitLab From 4f639edef73c15ddb1534e39f4bd6234ee04e4f8 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 25 Oct 2014 10:48:58 +0200 Subject: [PATCH 1261/9457] Bluetooth: fix shadow warning in hci_disconnect() use clkoff_cp for hci_cp_read_clock_offset instead of cp (already defined above). Suggested-by: Marcel Holtmann Signed-off-by: Fabian Frederick Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_conn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 11aac06d53ce..6a3225bf7bac 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -141,10 +141,11 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason) */ if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { struct hci_dev *hdev = conn->hdev; - struct hci_cp_read_clock_offset cp; + struct hci_cp_read_clock_offset clkoff_cp; - cp.handle = cpu_to_le16(conn->handle); - hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(cp), &cp); + clkoff_cp.handle = cpu_to_le16(conn->handle); + hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(clkoff_cp), + &clkoff_cp); } conn->state = BT_DISCONN; -- GitLab From e491eaf3c0b02b5325535a2de3e4fa15a3093190 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:37 +0200 Subject: [PATCH 1262/9457] Bluetooth: Pass only crypto context to SMP crypto functions In order to make unit testing possible we need to make the SMP crypto functions only take the crypto context instead of the full SMP context (the latter would require having hci_dev, hci_conn, l2cap_chan, l2cap_conn, etc around). The drawback is that we no-longer get the involved hdev in the debug logs, but this is really the only way to make simple unit tests for the code. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index f09b6b65cf6b..fea3782989f4 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -191,16 +191,13 @@ int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa) return 0; } -static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], - u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra, - u8 res[16]) +static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16], + u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, + bdaddr_t *ra, u8 res[16]) { - struct hci_dev *hdev = smp->conn->hcon->hdev; u8 p1[16], p2[16]; int err; - BT_DBG("%s", hdev->name); - memset(p1, 0, 16); /* p1 = pres || preq || _rat || _iat */ @@ -218,7 +215,7 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); /* res = e(k, res) */ - err = smp_e(smp->tfm_aes, k, res); + err = smp_e(tfm_aes, k, res); if (err) { BT_ERR("Encrypt data error"); return err; @@ -228,26 +225,23 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); /* res = e(k, res) */ - err = smp_e(smp->tfm_aes, k, res); + err = smp_e(tfm_aes, k, res); if (err) BT_ERR("Encrypt data error"); return err; } -static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], - u8 _r[16]) +static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16], + u8 r2[16], u8 _r[16]) { - struct hci_dev *hdev = smp->conn->hcon->hdev; int err; - BT_DBG("%s", hdev->name); - /* Just least significant octets from r1 and r2 are considered */ memcpy(_r, r2, 8); memcpy(_r + 8, r1, 8); - err = smp_e(smp->tfm_aes, k, _r); + err = smp_e(tfm_aes, k, _r); if (err) BT_ERR("Encrypt data error"); @@ -547,7 +541,7 @@ static u8 smp_confirm(struct smp_chan *smp) BT_DBG("conn %p", conn); - ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp, + ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp, conn->hcon->init_addr_type, &conn->hcon->init_addr, conn->hcon->resp_addr_type, &conn->hcon->resp_addr, cp.confirm_val); @@ -578,7 +572,7 @@ static u8 smp_random(struct smp_chan *smp) BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); - ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp, + ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp, hcon->init_addr_type, &hcon->init_addr, hcon->resp_addr_type, &hcon->resp_addr, confirm); if (ret) @@ -594,7 +588,7 @@ static u8 smp_random(struct smp_chan *smp) __le64 rand = 0; __le16 ediv = 0; - smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk); + smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); @@ -613,7 +607,7 @@ static u8 smp_random(struct smp_chan *smp) smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), smp->prnd); - smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk); + smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk); memset(stk + smp->enc_key_size, 0, SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); -- GitLab From 4cd3362da899a59955146851dd860198b0aaaa75 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:38 +0200 Subject: [PATCH 1263/9457] Bluetooth: Add skeleton for SMP self-tests This patch adds a basic skeleton for SMP self-tests. The tests are put behind a new configuration option since running them will slow down the boot process. For now there are no actual tests defined but those will come in a subsequent patch. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/Kconfig | 6 ++++++ net/bluetooth/smp.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 600fb29288f4..2675b4106b00 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -45,6 +45,12 @@ config BT_6LOWPAN help IPv6 compression over Bluetooth Low Energy. +config BT_SELFTEST + bool "Run self-tests on boot" + depends on BT && DEBUG_KERNEL + help + Run self-tests during boot. Currently limited to SMP. + source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/bnep/Kconfig" diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fea3782989f4..9821dc938e2c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1743,3 +1743,36 @@ void smp_unregister(struct hci_dev *hdev) hdev->smp_data = NULL; l2cap_chan_put(chan); } + +#ifdef CONFIG_BT_SELFTEST + +static int __init run_selftests(struct crypto_blkcipher *tfm_aes) +{ + return 0; +} + +static int __init test_smp(void) +{ + struct crypto_blkcipher *tfm_aes; + int err; + + tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm_aes)) { + BT_ERR("Unable to create ECB crypto context"); + return PTR_ERR(tfm_aes); + } + + err = run_selftests(tfm_aes); + if (err < 0) + BT_ERR("Self tests failed"); + else + BT_INFO("Self-tests passed"); + + crypto_free_blkcipher(tfm_aes); + + return err; +} + +module_init(test_smp); + +#endif /* CONFIG_BT_SELFTEST */ -- GitLab From c6992e9ef2a17e9738b7bb8a03a7fe581a8f9977 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 25 Oct 2014 21:15:39 +0200 Subject: [PATCH 1264/9457] Bluetooth: Add self-tests for SMP crypto functions This patch adds self-tests for the c1 and s1 crypto functions used for SMP pairing. The data used is the sample data from the core specification. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 9821dc938e2c..983d1e0793f6 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1746,8 +1746,95 @@ void smp_unregister(struct hci_dev *hdev) #ifdef CONFIG_BT_SELFTEST +static int __init test_ah(struct crypto_blkcipher *tfm_aes) +{ + u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, + 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; + u8 r[3] = { 0x94, 0x81, 0x70 }; + u8 exp[3] = { 0xaa, 0xfb, 0x0d }; + u8 res[3]; + int err; + + err = smp_ah(tfm_aes, irk, r, res); + if (err) + return err; + + if (memcmp(res, exp, 3) != 0) + return -EINVAL; + + return 0; +} + +static int __init test_c1(struct crypto_blkcipher *tfm_aes) +{ + u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 r[16] = { 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, + 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; + u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; + u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; + u8 _iat = 0x01; + u8 _rat = 0x00; + bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; + bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; + u8 exp[16] = { 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, + 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; + u8 res[16]; + int err; + + err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); + if (err) + return err; + + if (memcmp(res, exp, 16) != 0) + return -EINVAL; + + return 0; +} + +static int __init test_s1(struct crypto_blkcipher *tfm_aes) +{ + u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 r1[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; + u8 r2[16] = { 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; + u8 exp[16] = { 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, + 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; + u8 res[16]; + int err; + + err = smp_s1(tfm_aes, k, r1, r2, res); + if (err) + return err; + + if (memcmp(res, exp, 16) != 0) + return -EINVAL; + + return 0; +} + static int __init run_selftests(struct crypto_blkcipher *tfm_aes) { + int err; + + err = test_ah(tfm_aes); + if (err) { + BT_ERR("smp_ah test failed"); + return err; + } + + err = test_c1(tfm_aes); + if (err) { + BT_ERR("smp_c1 test failed"); + return err; + } + + err = test_s1(tfm_aes); + if (err) { + BT_ERR("smp_s1 test failed"); + return err; + } + return 0; } -- GitLab From 62eb01f5c2d735e8aeab6bc95e5832cb59397527 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:40:59 +0200 Subject: [PATCH 1265/9457] mac802154: move ieee802154_dev.c to main.c The ieee802154_dev functionality contains various function for allocation and registration of an ieee802154_dev. This is equal to the net/mac80211/main.c file. This patch rename the ieee802154_dev.c to main.c to have the same behaviour. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/{ieee802154_dev.c => main.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename net/mac802154/{ieee802154_dev.c => main.c} (100%) diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 9723d6f3f3e5..1ecbc47d4276 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o -mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o \ +mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ monitor.o wpan.o llsec.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/main.c similarity index 100% rename from net/mac802154/ieee802154_dev.c rename to net/mac802154/main.c -- GitLab From 0f1556bc2b152fc5d2a6b929c579748ec90c55d0 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:00 +0200 Subject: [PATCH 1266/9457] mac802154: move mac802154.h to ieee802154_i.h This patch moves the mac802154.h internal header to ieee802154_i.h like the wireless stack ieee80211_i.h file. This avoids confusing with the not internal header include/net/mac802154.h header. Additional we get the same naming conversion like mac80211 for this file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/{mac802154.h => ieee802154_i.h} | 6 +++--- net/mac802154/llsec.c | 2 +- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 2 +- net/mac802154/mib.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- net/mac802154/wpan.c | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) rename net/mac802154/{mac802154.h => ieee802154_i.h} (98%) diff --git a/net/mac802154/mac802154.h b/net/mac802154/ieee802154_i.h similarity index 98% rename from net/mac802154/mac802154.h rename to net/mac802154/ieee802154_i.h index e3503c1bc04e..970b621fc50b 100644 --- a/net/mac802154/mac802154.h +++ b/net/mac802154/ieee802154_i.h @@ -16,8 +16,8 @@ * Dmitry Eremin-Solenikov * Alexander Smirnov */ -#ifndef MAC802154_H -#define MAC802154_H +#ifndef __IEEE802154_I_H +#define __IEEE802154_I_H #include #include @@ -165,4 +165,4 @@ void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t); void mac802154_unlock_table(struct net_device *dev); -#endif /* MAC802154_H */ +#endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index 457058142098..26f876128ae0 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -20,7 +20,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" #include "llsec.h" static void llsec_key_put(struct mac802154_llsec_key *key); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 85f70edbe8dd..7c4b05ba2fe1 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -27,7 +27,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static int mac802154_mlme_start_req(struct net_device *dev, struct ieee802154_addr *addr, diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 086d4a91ae45..d11e42ae10d6 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -27,7 +27,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" int mac802154_slave_open(struct net_device *dev) { diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 3ee604292238..91cd3b260243 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -23,7 +23,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" struct phy_chan_notify_work { struct work_struct work; diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 81249bb7c935..2647a9e002ea 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -28,7 +28,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index e99d9394d13a..bc6cffd51f94 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -26,7 +26,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" /* The IEEE 802.15.4 standard defines 4 MAC packet types: * - beacon frame diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 95ea412395c7..ef11cc6fa323 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -25,7 +25,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index b11a98d824e0..5adcbd87a4f5 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -29,7 +29,7 @@ #include #include -#include "mac802154.h" +#include "ieee802154_i.h" static int mac802154_wpan_update_llsec(struct net_device *dev) { -- GitLab From 15859a5e141c4914c7c4d9dc9b2d54fa948fbd42 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:01 +0200 Subject: [PATCH 1267/9457] mac802154: move wpan.c to iface.c The wpan.c file contains the interface handling functions now. It's similar like the mac80211 iface.c file. This patch renames this file to iface.c to have similar naming convention in mac802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/{wpan.c => iface.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename net/mac802154/{wpan.c => iface.c} (100%) diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 1ecbc47d4276..203f42d511af 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o wpan.o llsec.o + monitor.o iface.o llsec.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/wpan.c b/net/mac802154/iface.c similarity index 100% rename from net/mac802154/wpan.c rename to net/mac802154/iface.c -- GitLab From 5ad60d36993596f7b3b958500f9c66c5338cd855 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:02 +0200 Subject: [PATCH 1268/9457] ieee802154: move wpan-phy.h to cfg802154.h The wpan-phy header contains the wpan_phy struct information. Later this header will be have similar function like cfg80211 header. The cfg80211 header contains the wiphy struct which is identically the wpan_phy struct inside 802.15.4 subsystem. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakehard.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/{wpan-phy.h => cfg802154.h} | 7 ++++--- net/ieee802154/nl-mac.c | 2 +- net/ieee802154/nl-phy.c | 2 +- net/ieee802154/wpan-class.c | 2 +- net/mac802154/iface.c | 2 +- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 2 +- net/mac802154/mib.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 2 +- 15 files changed, 18 insertions(+), 17 deletions(-) rename include/net/{wpan-phy.h => cfg802154.h} (97%) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 83a635f17367..795ac116602c 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -32,7 +32,7 @@ #include #include -#include +#include struct at86rf230_local; /* at86rf2xx chip depend data. diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 571f280204b6..f1770cf892ed 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #define SPI_COMMAND_BUFFER 3 diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 9ce854f43917..1460bf520498 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include struct fakehard_priv { struct wpan_phy *phy; diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index e4b1b1f66bd2..e6e2993b7ec6 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include static int numlbs = 1; diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 0006b9ad5127..bea7349db6ad 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/net/wpan-phy.h b/include/net/cfg802154.h similarity index 97% rename from include/net/wpan-phy.h rename to include/net/cfg802154.h index 1e9795f116ba..5c674673ef20 100644 --- a/include/net/wpan-phy.h +++ b/include/net/cfg802154.h @@ -14,8 +14,8 @@ * Dmitry Eremin-Solenikov */ -#ifndef WPAN_PHY_H -#define WPAN_PHY_H +#ifndef __NET_CFG802154_H +#define __NET_CFG802154_H #include #include @@ -99,4 +99,5 @@ static inline const char *wpan_phy_name(struct wpan_phy *phy) { return dev_name(&phy->dev); } -#endif + +#endif /* __NET_CFG802154_H */ diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index 78a1529e8bb2..a9c8e3e98387 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "ieee802154.h" diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index e943e20bcf09..0afe760ff512 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include /* for rtnl_{un,}lock */ diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index e4c6fb31a360..760b7d752190 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include "ieee802154.h" diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 5adcbd87a4f5..5a604074555b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 7c4b05ba2fe1..f118ea06d344 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/net/mac802154/main.c b/net/mac802154/main.c index d11e42ae10d6..9798c741739c 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 91cd3b260243..7c9467216199 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include "ieee802154_i.h" diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 2647a9e002ea..ca1dedd9b229 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index ef11cc6fa323..8f537bf731ca 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include "ieee802154_i.h" -- GitLab From 86d52cd96414f05c4053fb264a85309772c6ae26 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:03 +0200 Subject: [PATCH 1269/9457] ieee802154: move wpan-class.c to core.c Like the wireless core.c file this file contains function for phy allocation and freeing. Move this file to core.c to get similar behaviour. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/Makefile | 2 +- net/ieee802154/{wpan-class.c => core.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename net/ieee802154/{wpan-class.c => core.c} (100%) diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index 3914b1ed4274..e58c4cbb3639 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o -ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o \ +ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ header_ops.o af_802154-y := af_ieee802154.o raw.o dgram.o diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/core.c similarity index 100% rename from net/ieee802154/wpan-class.c rename to net/ieee802154/core.c -- GitLab From 4ca24aca55fe1e2a61f3ffaac9015d9c45204729 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:04 +0200 Subject: [PATCH 1270/9457] ieee802154: move ieee802154 header This patch moves the ieee802154 header into include/linux instead include/net. Similar like wireless which have the ieee80211 header inside of include/linux. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakehard.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/{net => linux}/ieee802154.h | 8 +++----- include/net/ieee802154_netdev.h | 2 +- net/ieee802154/6lowpan_rtnl.c | 2 +- net/ieee802154/dgram.c | 2 +- net/ieee802154/header_ops.c | 3 ++- net/ieee802154/nl-mac.c | 2 +- net/mac802154/iface.c | 2 +- net/mac802154/llsec.c | 2 +- net/mac802154/mac_cmd.c | 2 +- net/mac802154/monitor.c | 2 +- 14 files changed, 17 insertions(+), 18 deletions(-) rename include/{net => linux}/ieee802154.h (98%) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 795ac116602c..a433d20587e1 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -29,8 +29,8 @@ #include #include #include +#include -#include #include #include diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index f1770cf892ed..32b3c8862b4f 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -21,10 +21,10 @@ #include #include #include +#include #include #include -#include #define SPI_COMMAND_BUFFER 3 #define HIGH 1 diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 1460bf520498..8be05ade0ceb 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -25,10 +25,10 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index bea7349db6ad..56a69599ac31 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include /* MRF24J40 Short Address Registers */ #define REG_RXMCR 0x00 /* Receive MAC control */ diff --git a/include/net/ieee802154.h b/include/linux/ieee802154.h similarity index 98% rename from include/net/ieee802154.h rename to include/linux/ieee802154.h index 4db4e320b2f5..2dfab2db103a 100644 --- a/include/net/ieee802154.h +++ b/include/linux/ieee802154.h @@ -20,8 +20,8 @@ * Alexander Smirnov */ -#ifndef NET_IEEE802154_H -#define NET_IEEE802154_H +#ifndef LINUX_IEEE802154_H +#define LINUX_IEEE802154_H #define IEEE802154_MTU 127 @@ -186,6 +186,4 @@ enum { }; -#endif - - +#endif /* LINUX_IEEE802154_H */ diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index f87420689d70..5e62d758eea5 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -23,10 +23,10 @@ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H -#include #include #include #include +#include struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 0c1a49b51e57..1779a08d110a 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -49,8 +49,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 71e99a0994e1..3d58befef467 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -23,9 +23,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index c09294e39ca6..a051b6993177 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -14,8 +14,9 @@ * Phoebe Buckheister */ +#include + #include -#include #include static int diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index a9c8e3e98387..fb6866d1dd39 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 5a604074555b..03eedc3b23ef 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -20,13 +20,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index 26f876128ae0..fa0d5237c2e0 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include "ieee802154_i.h" diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index f118ea06d344..ad09d54bc690 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -20,8 +20,8 @@ #include #include +#include -#include #include #include #include diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index ca1dedd9b229..ca82c72a635c 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -21,8 +21,8 @@ #include #include #include +#include -#include #include #include #include -- GitLab From 580947d395c3827af805573c5fafa87dc01b13bb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 09:41:05 +0200 Subject: [PATCH 1271/9457] MAINTAINERS: add missing headers in 802.15.4 This patch adds a lot of include headers which are missing by the current IEEE 802.15.4 subsystem. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 43898b1a8a2d..15867a680422 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4689,6 +4689,13 @@ S: Maintained F: net/ieee802154/ F: net/mac802154/ F: drivers/net/ieee802154/ +F: include/linux/nl802154.h +F: include/linux/ieee802154.h +F: include/net/nl802154.h +F: include/net/mac802154.h +F: include/net/af_ieee802154.h +F: include/net/cfg802154.h +F: include/net/ieee802154_netdev.h F: Documentation/networking/ieee802154.txt IGUANAWORKS USB IR TRANSCEIVER -- GitLab From 36426484fcaca2153616d6f3496b389a5b11bd9f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:33 +0200 Subject: [PATCH 1272/9457] ieee802154: remove fakehard driver This patch removes the not functional fakehard driver. We don't support HardMAC 802.15.4 drivers right now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/Kconfig | 10 - drivers/net/ieee802154/Makefile | 1 - drivers/net/ieee802154/fakehard.c | 427 ------------------------------ 3 files changed, 438 deletions(-) delete mode 100644 drivers/net/ieee802154/fakehard.c diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig index 391a916622a9..1a3c3e57aa0b 100644 --- a/drivers/net/ieee802154/Kconfig +++ b/drivers/net/ieee802154/Kconfig @@ -10,16 +10,6 @@ menuconfig IEEE802154_DRIVERS If you say N, all options in this submenu will be skipped and disabled. -config IEEE802154_FAKEHARD - tristate "Fake LR-WPAN driver with several interconnected devices" - depends on IEEE802154_DRIVERS - ---help--- - Say Y here to enable the fake driver that serves as an example - of HardMAC device driver. - - This driver can also be built as a module. To do so say M here. - The module will be called 'fakehard'. - config IEEE802154_FAKELB depends on IEEE802154_DRIVERS && MAC802154 tristate "IEEE 802.15.4 loopback driver" diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile index 655cb95e6e24..d77fa4d77e27 100644 --- a/drivers/net/ieee802154/Makefile +++ b/drivers/net/ieee802154/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c deleted file mode 100644 index 8be05ade0ceb..000000000000 --- a/drivers/net/ieee802154/fakehard.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Sample driver for HardMAC IEEE 802.15.4 devices - * - * Copyright (C) 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct fakehard_priv { - struct wpan_phy *phy; -}; - -static struct wpan_phy *fake_to_phy(const struct net_device *dev) -{ - struct fakehard_priv *priv = netdev_priv(dev); - return priv->phy; -} - -/** - * fake_get_phy - Return a phy corresponding to this device. - * @dev: The network device for which to return the wan-phy object - * - * This function returns a wpan-phy object corresponding to the passed - * network device. Reference counter for wpan-phy object is incremented, - * so when the wpan-phy isn't necessary, you should drop the reference - * via @wpan_phy_put() call. - */ -static struct wpan_phy *fake_get_phy(const struct net_device *dev) -{ - struct wpan_phy *phy = fake_to_phy(dev); - return to_phy(get_device(&phy->dev)); -} - -/** - * fake_get_pan_id - Retrieve the PAN ID of the device. - * @dev: The network device to retrieve the PAN of. - * - * Return the ID of the PAN from the PIB. - */ -static __le16 fake_get_pan_id(const struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return cpu_to_le16(0xeba1); -} - -/** - * fake_get_short_addr - Retrieve the short address of the device. - * @dev: The network device to retrieve the short address of. - * - * Returns the IEEE 802.15.4 short-form address cached for this - * device. If the device has not yet had a short address assigned - * then this should return 0xFFFF to indicate a lack of association. - */ -static __le16 fake_get_short_addr(const struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return cpu_to_le16(0x1); -} - -/** - * fake_get_dsn - Retrieve the DSN of the device. - * @dev: The network device to retrieve the DSN for. - * - * Returns the IEEE 802.15.4 DSN for the network device. - * The DSN is the sequence number which will be added to each - * packet or MAC command frame by the MAC during transmission. - * - * DSN means 'Data Sequence Number'. - * - * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006 - * document. - */ -static u8 fake_get_dsn(const struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x00; /* DSN are implemented in HW, so return just 0 */ -} - -/** - * fake_assoc_req - Make an association request to the HW. - * @dev: The network device which we are associating to a network. - * @addr: The coordinator with which we wish to associate. - * @channel: The channel on which to associate. - * @cap: The capability information field to use in the association. - * - * Start an association with a coordinator. The coordinator's address - * and PAN ID can be found in @addr. - * - * Note: This is in section 7.3.1 and 7.5.3.1 of the IEEE - * 802.15.4-2006 document. - */ -static int fake_assoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap) -{ - struct wpan_phy *phy = fake_to_phy(dev); - - mutex_lock(&phy->pib_lock); - phy->current_channel = channel; - phy->current_page = page; - mutex_unlock(&phy->pib_lock); - - /* We simply emulate it here */ - return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), - IEEE802154_SUCCESS); -} - -/** - * fake_assoc_resp - Send an association response to a device. - * @dev: The network device on which to send the response. - * @addr: The address of the device to respond to. - * @short_addr: The assigned short address for the device (if any). - * @status: The result of the association request. - * - * Queue the association response of the coordinator to another - * device's attempt to associate with the network which we - * coordinate. This is then added to the indirect-send queue to be - * transmitted to the end device when it polls for data. - * - * Note: This is in section 7.3.2 and 7.5.3.1 of the IEEE - * 802.15.4-2006 document. - */ -static int fake_assoc_resp(struct net_device *dev, - struct ieee802154_addr *addr, __le16 short_addr, u8 status) -{ - return 0; -} - -/** - * fake_disassoc_req - Disassociate a device from a network. - * @dev: The network device on which we're disassociating a device. - * @addr: The device to disassociate from the network. - * @reason: The reason to give to the device for being disassociated. - * - * This sends a disassociation notification to the device being - * disassociated from the network. - * - * Note: This is in section 7.5.3.2 of the IEEE 802.15.4-2006 - * document, with the reason described in 7.3.3.2. - */ -static int fake_disassoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason) -{ - return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS); -} - -/** - * fake_start_req - Start an IEEE 802.15.4 PAN. - * @dev: The network device on which to start the PAN. - * @addr: The coordinator address to use when starting the PAN. - * @channel: The channel on which to start the PAN. - * @bcn_ord: Beacon order. - * @sf_ord: Superframe order. - * @pan_coord: Whether or not we are the PAN coordinator or just - * requesting a realignment perhaps? - * @blx: Battery Life Extension feature bitfield. - * @coord_realign: Something to realign something else. - * - * If pan_coord is non-zero then this starts a network with the - * provided parameters, otherwise it attempts a coordinator - * realignment of the stated network instead. - * - * Note: This is in section 7.5.2.3 of the IEEE 802.15.4-2006 - * document, with 7.3.8 describing coordinator realignment. - */ -static int fake_start_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 channel, u8 page, - u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, - u8 coord_realign) -{ - struct wpan_phy *phy = fake_to_phy(dev); - - mutex_lock(&phy->pib_lock); - phy->current_channel = channel; - phy->current_page = page; - mutex_unlock(&phy->pib_lock); - - /* We don't emulate beacons here at all, so START should fail */ - ieee802154_nl_start_confirm(dev, IEEE802154_INVALID_PARAMETER); - return 0; -} - -/** - * fake_scan_req - Start a channel scan. - * @dev: The network device on which to perform a channel scan. - * @type: The type of scan to perform. - * @channels: The channel bitmask to scan. - * @duration: How long to spend on each channel. - * - * This starts either a passive (energy) scan or an active (PAN) scan - * on the channels indicated in the @channels bitmask. The duration of - * the scan is measured in terms of superframe duration. Specifically, - * the scan will spend aBaseSuperFrameDuration * ((2^n) + 1) on each - * channel. - * - * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document. - */ -static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, - u8 page, u8 duration) -{ - u8 edl[27] = {}; - return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, - channels, page, - type == IEEE802154_MAC_SCAN_ED ? edl : NULL); -} - -static struct ieee802154_mlme_ops fake_mlme = { - .assoc_req = fake_assoc_req, - .assoc_resp = fake_assoc_resp, - .disassoc_req = fake_disassoc_req, - .start_req = fake_start_req, - .scan_req = fake_scan_req, - - .get_phy = fake_get_phy, - - .get_pan_id = fake_get_pan_id, - .get_short_addr = fake_get_short_addr, - .get_dsn = fake_get_dsn, -}; - -static int ieee802154_fake_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int ieee802154_fake_close(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - /* FIXME: do hardware work here ... */ - - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - - -static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr, - int cmd) -{ - struct sockaddr_ieee802154 *sa = - (struct sockaddr_ieee802154 *)&ifr->ifr_addr; - u16 pan_id, short_addr; - - switch (cmd) { - case SIOCGIFADDR: - /* FIXME: fixed here, get from device IRL */ - pan_id = le16_to_cpu(fake_get_pan_id(dev)); - short_addr = le16_to_cpu(fake_get_short_addr(dev)); - if (pan_id == IEEE802154_PANID_BROADCAST || - short_addr == IEEE802154_ADDR_BROADCAST) - return -EADDRNOTAVAIL; - - sa->family = AF_IEEE802154; - sa->addr.addr_type = IEEE802154_ADDR_SHORT; - sa->addr.pan_id = pan_id; - sa->addr.short_addr = short_addr; - return 0; - } - return -ENOIOCTLCMD; -} - -static int ieee802154_fake_mac_addr(struct net_device *dev, void *p) -{ - return -EBUSY; /* HW address is built into the device */ -} - -static const struct net_device_ops fake_ops = { - .ndo_open = ieee802154_fake_open, - .ndo_stop = ieee802154_fake_close, - .ndo_start_xmit = ieee802154_fake_xmit, - .ndo_do_ioctl = ieee802154_fake_ioctl, - .ndo_set_mac_address = ieee802154_fake_mac_addr, -}; - -static void ieee802154_fake_destruct(struct net_device *dev) -{ - struct wpan_phy *phy = fake_to_phy(dev); - - wpan_phy_unregister(phy); - free_netdev(dev); - wpan_phy_free(phy); -} - -static void ieee802154_fake_setup(struct net_device *dev) -{ - dev->addr_len = IEEE802154_ADDR_LEN; - memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); - dev->features = NETIF_F_HW_CSUM; - dev->needed_tailroom = 2; /* FCS */ - dev->mtu = 127; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; - dev->destructor = ieee802154_fake_destruct; -} - - -static int ieee802154fake_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct fakehard_priv *priv; - struct wpan_phy *phy = wpan_phy_alloc(0); - int err; - - if (!phy) - return -ENOMEM; - - dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", - NET_NAME_UNKNOWN, ieee802154_fake_setup); - if (!dev) { - wpan_phy_free(phy); - return -ENOMEM; - } - - memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", - dev->addr_len); - - /* - * For now we'd like to emulate 2.4 GHz-only device, - * both O-QPSK and CSS - */ - /* 2.4 GHz O-QPSK 802.15.4-2003 */ - phy->channels_supported[0] |= 0x7FFF800; - /* 2.4 GHz CSS 802.15.4a-2007 */ - phy->channels_supported[3] |= 0x3fff; - - phy->transmit_power = 0xbf; - - dev->netdev_ops = &fake_ops; - dev->ml_priv = &fake_mlme; - - priv = netdev_priv(dev); - priv->phy = phy; - - wpan_phy_set_dev(phy, &pdev->dev); - SET_NETDEV_DEV(dev, &phy->dev); - - platform_set_drvdata(pdev, dev); - - err = wpan_phy_register(phy); - if (err) - goto out; - - err = register_netdev(dev); - if (err < 0) - goto out; - - dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); - return 0; - -out: - unregister_netdev(dev); - return err; -} - -static int ieee802154fake_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - return 0; -} - -static struct platform_device *ieee802154fake_dev; - -static struct platform_driver ieee802154fake_driver = { - .probe = ieee802154fake_probe, - .remove = ieee802154fake_remove, - .driver = { - .name = "ieee802154hardmac", - .owner = THIS_MODULE, - }, -}; - -static __init int fake_init(void) -{ - ieee802154fake_dev = platform_device_register_simple( - "ieee802154hardmac", -1, NULL, 0); - return platform_driver_register(&ieee802154fake_driver); -} - -static __exit void fake_exit(void) -{ - platform_driver_unregister(&ieee802154fake_driver); - platform_device_unregister(ieee802154fake_dev); -} - -module_init(fake_init); -module_exit(fake_exit); -MODULE_LICENSE("GPL"); -- GitLab From 5a50439775853a8d565115edb63a5ab4bb780479 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:34 +0200 Subject: [PATCH 1273/9457] ieee802154: rename ieee802154_dev to ieee802154_hw The identical struct of the wireless stack implementation is named ieee80211_hw. This is useful to name the variable hw instead of get confusing with netdev dev variable. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 90 +++++++++++++++--------------- drivers/net/ieee802154/cc2520.c | 50 ++++++++--------- drivers/net/ieee802154/fakelb.c | 78 +++++++++++++------------- drivers/net/ieee802154/mrf24j40.c | 48 ++++++++-------- include/net/mac802154.h | 44 +++++++-------- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 34 +++++------ net/mac802154/rx.c | 12 ++-- 8 files changed, 179 insertions(+), 179 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index a433d20587e1..b0d68d7061c1 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -77,7 +77,7 @@ struct at86rf230_state_change { struct at86rf230_local { struct spi_device *spi; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct at86rf2xx_chip_data *data; struct regmap *regmap; @@ -808,7 +808,7 @@ at86rf230_rx(struct at86rf230_local *lp, /* We do not put CRC into the frame */ skb_trim(skb, len - 2); - ieee802154_rx_irqsafe(lp->dev, skb, lqi); + ieee802154_rx_irqsafe(lp->hw, skb, lqi); } static void @@ -969,9 +969,9 @@ at86rf230_xmit_tx_on(void *context) } static int -at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; struct at86rf230_state_change *ctx = &lp->tx; void (*tx_complete)(void *context) = at86rf230_write_frame; @@ -1012,7 +1012,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) } static int -at86rf230_ed(struct ieee802154_dev *dev, u8 *level) +at86rf230_ed(struct ieee802154_hw *hw, u8 *level) { might_sleep(); BUG_ON(!level); @@ -1021,15 +1021,15 @@ at86rf230_ed(struct ieee802154_dev *dev, u8 *level) } static int -at86rf230_start(struct ieee802154_dev *dev) +at86rf230_start(struct ieee802154_hw *hw) { - return at86rf230_sync_state_change(dev->priv, STATE_RX_AACK_ON); + return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); } static void -at86rf230_stop(struct ieee802154_dev *dev) +at86rf230_stop(struct ieee802154_hw *hw) { - at86rf230_sync_state_change(dev->priv, STATE_FORCE_TRX_OFF); + at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); } static int @@ -1064,15 +1064,15 @@ at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel) } static int -at86rf230_channel(struct ieee802154_dev *dev, int page, int channel) +at86rf230_channel(struct ieee802154_hw *hw, int page, int channel) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc; might_sleep(); if (page < 0 || page > 31 || - !(lp->dev->phy->channels_supported[page] & BIT(channel))) { + !(lp->hw->phy->channels_supported[page] & BIT(channel))) { WARN_ON(1); return -EINVAL; } @@ -1084,18 +1084,18 @@ at86rf230_channel(struct ieee802154_dev *dev, int page, int channel) /* Wait for PLL */ usleep_range(lp->data->t_channel_switch, lp->data->t_channel_switch + 10); - dev->phy->current_channel = channel; - dev->phy->current_page = page; + hw->phy->current_channel = channel; + hw->phy->current_page = page; return 0; } static int -at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, +at86rf230_set_hw_addr_filt(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); @@ -1138,9 +1138,9 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev, } static int -at86rf230_set_txpower(struct ieee802154_dev *dev, int db) +at86rf230_set_txpower(struct ieee802154_hw *hw, int db) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; /* typical maximum output is 5dBm with RG_PHY_TX_PWR 0x60, lower five * bits decrease power in 1dB steps. 0x60 represents extra PA gain of @@ -1157,17 +1157,17 @@ at86rf230_set_txpower(struct ieee802154_dev *dev, int db) } static int -at86rf230_set_lbt(struct ieee802154_dev *dev, bool on) +at86rf230_set_lbt(struct ieee802154_hw *hw, bool on) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; return at86rf230_write_subreg(lp, SR_CSMA_LBT_MODE, on); } static int -at86rf230_set_cca_mode(struct ieee802154_dev *dev, u8 mode) +at86rf230_set_cca_mode(struct ieee802154_hw *hw, u8 mode) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; return at86rf230_write_subreg(lp, SR_CCA_MODE, mode); } @@ -1185,9 +1185,9 @@ at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level) } static int -at86rf230_set_cca_ed_level(struct ieee802154_dev *dev, s32 level) +at86rf230_set_cca_ed_level(struct ieee802154_hw *hw, s32 level) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; if (level < lp->data->rssi_base_val || level > 30) return -EINVAL; @@ -1197,10 +1197,10 @@ at86rf230_set_cca_ed_level(struct ieee802154_dev *dev, s32 level) } static int -at86rf230_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be, +at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc; if (min_be > max_be || max_be > 8 || retries > 5) @@ -1218,9 +1218,9 @@ at86rf230_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be, } static int -at86rf230_set_frame_retries(struct ieee802154_dev *dev, s8 retries) +at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) { - struct at86rf230_local *lp = dev->priv; + struct at86rf230_local *lp = hw->priv; int rc = 0; if (retries < -1 || retries > 15) @@ -1409,8 +1409,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) return -EINVAL; } - lp->dev->extra_tx_headroom = 0; - lp->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | + lp->hw->extra_tx_headroom = 0; + lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA; switch (part) { @@ -1421,15 +1421,15 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 3: chip = "at86rf231"; lp->data = &at86rf231_data; - lp->dev->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->channels_supported[0] = 0x7FFF800; break; case 7: chip = "at86rf212"; if (version == 1) { lp->data = &at86rf212_data; - lp->dev->flags |= IEEE802154_HW_LBT; - lp->dev->phy->channels_supported[0] = 0x00007FF; - lp->dev->phy->channels_supported[2] = 0x00007FF; + lp->hw->flags |= IEEE802154_HW_LBT; + lp->hw->phy->channels_supported[0] = 0x00007FF; + lp->hw->phy->channels_supported[2] = 0x00007FF; } else { rc = -ENOTSUPP; } @@ -1437,7 +1437,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) case 11: chip = "at86rf233"; lp->data = &at86rf233_data; - lp->dev->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->channels_supported[0] = 0x7FFF800; break; default: chip = "unkown"; @@ -1478,7 +1478,7 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) static int at86rf230_probe(struct spi_device *spi) { struct at86rf230_platform_data *pdata; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct at86rf230_local *lp; unsigned int status; int rc, irq_type; @@ -1517,14 +1517,14 @@ static int at86rf230_probe(struct spi_device *spi) usleep_range(120, 240); } - dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops); - if (!dev) + hw = ieee802154_alloc_hw(sizeof(*lp), &at86rf230_ops); + if (!hw) return -ENOMEM; - lp = dev->priv; - lp->dev = dev; + lp = hw->priv; + lp->hw = hw; lp->spi = spi; - dev->parent = &spi->dev; + hw->parent = &spi->dev; lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); if (IS_ERR(lp->regmap)) { @@ -1564,14 +1564,14 @@ static int at86rf230_probe(struct spi_device *spi) if (rc) goto free_dev; - rc = ieee802154_register_device(lp->dev); + rc = ieee802154_register_hw(lp->hw); if (rc) goto free_dev; return rc; free_dev: - ieee802154_free_device(lp->dev); + ieee802154_free_hw(lp->hw); return rc; } @@ -1582,8 +1582,8 @@ static int at86rf230_remove(struct spi_device *spi) /* mask all at86rf230 irq's */ at86rf230_write_subreg(lp, SR_IRQ_MASK, 0); - ieee802154_unregister_device(lp->dev); - ieee802154_free_device(lp->dev); + ieee802154_unregister_hw(lp->hw); + ieee802154_free_hw(lp->hw); dev_dbg(&spi->dev, "unregistered at86rf230\n"); return 0; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 32b3c8862b4f..b827e04d481b 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -193,7 +193,7 @@ /* Driver private information */ struct cc2520_private { struct spi_device *spi; /* SPI device structure */ - struct ieee802154_dev *dev; /* IEEE-802.15.4 device */ + struct ieee802154_hw *hw; /* IEEE-802.15.4 device */ u8 *buf; /* SPI TX/Rx data buffer */ struct mutex buffer_mutex; /* SPI buffer mutex */ bool is_tx; /* Flag for sync b/w Tx and Rx */ @@ -453,20 +453,20 @@ cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi) return status; } -static int cc2520_start(struct ieee802154_dev *dev) +static int cc2520_start(struct ieee802154_hw *hw) { - return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON); + return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON); } -static void cc2520_stop(struct ieee802154_dev *dev) +static void cc2520_stop(struct ieee802154_hw *hw) { - cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF); + cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF); } static int -cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb) +cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; unsigned long flags; int rc; u8 status = 0; @@ -536,7 +536,7 @@ static int cc2520_rx(struct cc2520_private *priv) skb_trim(skb, skb->len - 2); - ieee802154_rx_irqsafe(priv->dev, skb, lqi); + ieee802154_rx_irqsafe(priv->hw, skb, lqi); dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi); @@ -544,9 +544,9 @@ static int cc2520_rx(struct cc2520_private *priv) } static int -cc2520_ed(struct ieee802154_dev *dev, u8 *level) +cc2520_ed(struct ieee802154_hw *hw, u8 *level) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; u8 status = 0xff; u8 rssi; int ret; @@ -569,9 +569,9 @@ cc2520_ed(struct ieee802154_dev *dev, u8 *level) } static int -cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) +cc2520_set_channel(struct ieee802154_hw *hw, int page, int channel) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; int ret; might_sleep(); @@ -588,10 +588,10 @@ cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) } static int -cc2520_filter(struct ieee802154_dev *dev, +cc2520_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct cc2520_private *priv = dev->priv; + struct cc2520_private *priv = hw->priv; if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); @@ -645,27 +645,27 @@ static int cc2520_register(struct cc2520_private *priv) { int ret = -ENOMEM; - priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops); - if (!priv->dev) + priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops); + if (!priv->hw) goto err_ret; - priv->dev->priv = priv; - priv->dev->parent = &priv->spi->dev; - priv->dev->extra_tx_headroom = 0; + priv->hw->priv = priv; + priv->hw->parent = &priv->spi->dev; + priv->hw->extra_tx_headroom = 0; /* We do support only 2.4 Ghz */ - priv->dev->phy->channels_supported[0] = 0x7FFF800; - priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; + priv->hw->phy->channels_supported[0] = 0x7FFF800; + priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; dev_vdbg(&priv->spi->dev, "registered cc2520\n"); - ret = ieee802154_register_device(priv->dev); + ret = ieee802154_register_hw(priv->hw); if (ret) goto err_free_device; return 0; err_free_device: - ieee802154_free_device(priv->dev); + ieee802154_free_hw(priv->hw); err_ret: return ret; } @@ -1002,8 +1002,8 @@ static int cc2520_remove(struct spi_device *spi) mutex_destroy(&priv->buffer_mutex); flush_work(&priv->fifop_irqwork); - ieee802154_unregister_device(priv->dev); - ieee802154_free_device(priv->dev); + ieee802154_unregister_hw(priv->hw); + ieee802154_free_hw(priv->hw); return 0; } diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index e6e2993b7ec6..51e3c589d2e4 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -30,7 +30,7 @@ static int numlbs = 1; struct fakelb_dev_priv { - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct list_head list; struct fakelb_priv *fake; @@ -45,7 +45,7 @@ struct fakelb_priv { }; static int -fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) +fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level) { might_sleep(); BUG_ON(!level); @@ -55,13 +55,13 @@ fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) } static int -fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) +fakelb_hw_channel(struct ieee802154_hw *hw, int page, int channel) { pr_debug("set channel to %d\n", channel); might_sleep(); - dev->phy->current_page = page; - dev->phy->current_channel = channel; + hw->phy->current_page = page; + hw->phy->current_channel = channel; return 0; } @@ -74,15 +74,15 @@ fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) spin_lock(&priv->lock); if (priv->working) { newskb = pskb_copy(skb, GFP_ATOMIC); - ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); + ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc); } spin_unlock(&priv->lock); } static int -fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) +fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct fakelb_dev_priv *priv = dev->priv; + struct fakelb_dev_priv *priv = hw->priv; struct fakelb_priv *fake = priv->fake; might_sleep(); @@ -95,8 +95,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) struct fakelb_dev_priv *dp; list_for_each_entry(dp, &priv->fake->list, list) { if (dp != priv && - (dp->dev->phy->current_channel == - priv->dev->phy->current_channel)) + (dp->hw->phy->current_channel == + priv->hw->phy->current_channel)) fakelb_hw_deliver(dp, skb); } } @@ -106,8 +106,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) } static int -fakelb_hw_start(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; +fakelb_hw_start(struct ieee802154_hw *hw) { + struct fakelb_dev_priv *priv = hw->priv; int ret = 0; spin_lock(&priv->lock); @@ -121,8 +121,8 @@ fakelb_hw_start(struct ieee802154_dev *dev) { } static void -fakelb_hw_stop(struct ieee802154_dev *dev) { - struct fakelb_dev_priv *priv = dev->priv; +fakelb_hw_stop(struct ieee802154_hw *hw) { + struct fakelb_dev_priv *priv = hw->priv; spin_lock(&priv->lock); priv->working = 0; @@ -146,54 +146,54 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) { struct fakelb_dev_priv *priv; int err; - struct ieee802154_dev *ieee; + struct ieee802154_hw *hw; - ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); - if (!ieee) + hw = ieee802154_alloc_hw(sizeof(*priv), &fakelb_ops); + if (!hw) return -ENOMEM; - priv = ieee->priv; - priv->dev = ieee; + priv = hw->priv; + priv->hw = hw; /* 868 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 1; + hw->phy->channels_supported[0] |= 1; /* 915 MHz BPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7fe; + hw->phy->channels_supported[0] |= 0x7fe; /* 2.4 GHz O-QPSK 802.15.4-2003 */ - ieee->phy->channels_supported[0] |= 0x7FFF800; + hw->phy->channels_supported[0] |= 0x7FFF800; /* 868 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 1; + hw->phy->channels_supported[1] |= 1; /* 915 MHz ASK 802.15.4-2006 */ - ieee->phy->channels_supported[1] |= 0x7fe; + hw->phy->channels_supported[1] |= 0x7fe; /* 868 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 1; + hw->phy->channels_supported[2] |= 1; /* 915 MHz O-QPSK 802.15.4-2006 */ - ieee->phy->channels_supported[2] |= 0x7fe; + hw->phy->channels_supported[2] |= 0x7fe; /* 2.4 GHz CSS 802.15.4a-2007 */ - ieee->phy->channels_supported[3] |= 0x3fff; + hw->phy->channels_supported[3] |= 0x3fff; /* UWB Sub-gigahertz 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 1; + hw->phy->channels_supported[4] |= 1; /* UWB Low band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0x1e; + hw->phy->channels_supported[4] |= 0x1e; /* UWB High band 802.15.4a-2007 */ - ieee->phy->channels_supported[4] |= 0xffe0; + hw->phy->channels_supported[4] |= 0xffe0; /* 750 MHz O-QPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf; + hw->phy->channels_supported[5] |= 0xf; /* 750 MHz MPSK 802.15.4c-2009 */ - ieee->phy->channels_supported[5] |= 0xf0; + hw->phy->channels_supported[5] |= 0xf0; /* 950 MHz BPSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ff; + hw->phy->channels_supported[6] |= 0x3ff; /* 950 MHz GFSK 802.15.4d-2009 */ - ieee->phy->channels_supported[6] |= 0x3ffc00; + hw->phy->channels_supported[6] |= 0x3ffc00; INIT_LIST_HEAD(&priv->list); priv->fake = fake; spin_lock_init(&priv->lock); - ieee->parent = dev; + hw->parent = dev; - err = ieee802154_register_device(ieee); + err = ieee802154_register_hw(hw); if (err) goto err_reg; @@ -204,7 +204,7 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) return 0; err_reg: - ieee802154_free_device(priv->dev); + ieee802154_free_hw(priv->hw); return err; } @@ -214,8 +214,8 @@ static void fakelb_del(struct fakelb_dev_priv *priv) list_del(&priv->list); write_unlock_bh(&priv->fake->lock); - ieee802154_unregister_device(priv->dev); - ieee802154_free_device(priv->dev); + ieee802154_unregister_hw(priv->hw); + ieee802154_free_hw(priv->hw); } static int fakelb_probe(struct platform_device *pdev) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 56a69599ac31..2e267c5c44da 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -79,7 +79,7 @@ enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC }; /* Device Private Data */ struct mrf24j40 { struct spi_device *spi; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; struct mutex buffer_mutex; /* only used to protect buf */ struct completion tx_complete; @@ -332,9 +332,9 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec, return ret; } -static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) +static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret = 0; @@ -383,7 +383,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) return ret; } -static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) +static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level) { /* TODO: */ pr_warn("mrf24j40: ed not implemented\n"); @@ -391,9 +391,9 @@ static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) return 0; } -static int mrf24j40_start(struct ieee802154_dev *dev) +static int mrf24j40_start(struct ieee802154_hw *hw) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -408,9 +408,9 @@ static int mrf24j40_start(struct ieee802154_dev *dev) return 0; } -static void mrf24j40_stop(struct ieee802154_dev *dev) +static void mrf24j40_stop(struct ieee802154_hw *hw) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -423,10 +423,10 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) write_short_reg(devrec, REG_INTCON, val); } -static int mrf24j40_set_channel(struct ieee802154_dev *dev, +static int mrf24j40_set_channel(struct ieee802154_hw *hw, int page, int channel) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; u8 val; int ret; @@ -454,11 +454,11 @@ static int mrf24j40_set_channel(struct ieee802154_dev *dev, return 0; } -static int mrf24j40_filter(struct ieee802154_dev *dev, +static int mrf24j40_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { - struct mrf24j40 *devrec = dev->priv; + struct mrf24j40 *devrec = hw->priv; dev_dbg(printdev(devrec), "filter\n"); @@ -564,7 +564,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040, * also from a workqueue). I think irqsafe is not necessary here. * Can someone confirm? */ - ieee802154_rx_irqsafe(devrec->dev, skb, lqi); + ieee802154_rx_irqsafe(devrec->hw, skb, lqi); dev_dbg(printdev(devrec), "RX Handled\n"); @@ -745,17 +745,17 @@ static int mrf24j40_probe(struct spi_device *spi) /* Register with the 802154 subsystem */ - devrec->dev = ieee802154_alloc_device(0, &mrf24j40_ops); - if (!devrec->dev) + devrec->hw = ieee802154_alloc_hw(0, &mrf24j40_ops); + if (!devrec->hw) goto err_ret; - devrec->dev->priv = devrec; - devrec->dev->parent = &devrec->spi->dev; - devrec->dev->phy->channels_supported[0] = CHANNEL_MASK; - devrec->dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; + devrec->hw->priv = devrec; + devrec->hw->parent = &devrec->spi->dev; + devrec->hw->phy->channels_supported[0] = CHANNEL_MASK; + devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; dev_dbg(printdev(devrec), "registered mrf24j40\n"); - ret = ieee802154_register_device(devrec->dev); + ret = ieee802154_register_hw(devrec->hw); if (ret) goto err_register_device; @@ -780,9 +780,9 @@ static int mrf24j40_probe(struct spi_device *spi) err_irq: err_hw_init: - ieee802154_unregister_device(devrec->dev); + ieee802154_unregister_hw(devrec->hw); err_register_device: - ieee802154_free_device(devrec->dev); + ieee802154_free_hw(devrec->hw); err_ret: return ret; } @@ -793,8 +793,8 @@ static int mrf24j40_remove(struct spi_device *spi) dev_dbg(printdev(devrec), "remove\n"); - ieee802154_unregister_device(devrec->dev); - ieee802154_free_device(devrec->dev); + ieee802154_unregister_hw(devrec->hw); + ieee802154_free_hw(devrec->hw); /* TODO: Will ieee802154_free_device() wait until ->xmit() is * complete? */ diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 70351de3a72c..eb0e1cb9ca98 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -52,7 +52,7 @@ struct ieee802154_hw_addr_filt { u8 pan_coord; }; -struct ieee802154_dev { +struct ieee802154_hw { /* filled by the driver */ int extra_tx_headroom; u32 flags; @@ -159,37 +159,37 @@ struct ieee802154_dev { */ struct ieee802154_ops { struct module *owner; - int (*start)(struct ieee802154_dev *dev); - void (*stop)(struct ieee802154_dev *dev); - int (*xmit)(struct ieee802154_dev *dev, + int (*start)(struct ieee802154_hw *hw); + void (*stop)(struct ieee802154_hw *hw); + int (*xmit)(struct ieee802154_hw *hw, struct sk_buff *skb); - int (*ed)(struct ieee802154_dev *dev, u8 *level); - int (*set_channel)(struct ieee802154_dev *dev, + int (*ed)(struct ieee802154_hw *hw, u8 *level); + int (*set_channel)(struct ieee802154_hw *hw, int page, int channel); - int (*set_hw_addr_filt)(struct ieee802154_dev *dev, - struct ieee802154_hw_addr_filt *filt, + int (*set_hw_addr_filt)(struct ieee802154_hw *hw, + struct ieee802154_hw_addr_filt *filt, unsigned long changed); - int (*ieee_addr)(struct ieee802154_dev *dev, __le64 addr); - int (*set_txpower)(struct ieee802154_dev *dev, int db); - int (*set_lbt)(struct ieee802154_dev *dev, bool on); - int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode); - int (*set_cca_ed_level)(struct ieee802154_dev *dev, + int (*ieee_addr)(struct ieee802154_hw *hw, __le64 addr); + int (*set_txpower)(struct ieee802154_hw *hw, int db); + int (*set_lbt)(struct ieee802154_hw *hw, bool on); + int (*set_cca_mode)(struct ieee802154_hw *hw, u8 mode); + int (*set_cca_ed_level)(struct ieee802154_hw *hw, s32 level); - int (*set_csma_params)(struct ieee802154_dev *dev, + int (*set_csma_params)(struct ieee802154_hw *hw, u8 min_be, u8 max_be, u8 retries); - int (*set_frame_retries)(struct ieee802154_dev *dev, + int (*set_frame_retries)(struct ieee802154_hw *hw, s8 retries); }; -/* Basic interface to register ieee802154 device */ -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops); -void ieee802154_free_device(struct ieee802154_dev *dev); -int ieee802154_register_device(struct ieee802154_dev *dev); -void ieee802154_unregister_device(struct ieee802154_dev *dev); +/* Basic interface to register ieee802154 hwice */ +struct ieee802154_hw * +ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops); +void ieee802154_free_hw(struct ieee802154_hw *hw); +int ieee802154_register_hw(struct ieee802154_hw *hw); +void ieee802154_unregister_hw(struct ieee802154_hw *hw); -void ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, +void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 970b621fc50b..0cb98e87645a 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -27,7 +27,7 @@ /* mac802154 device private data */ struct mac802154_priv { - struct ieee802154_dev hw; + struct ieee802154_hw hw; struct ieee802154_ops *ops; /* ieee802154 phy */ diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9798c741739c..b0bcc063e9af 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -235,8 +235,8 @@ static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) return priv->ops->set_frame_retries(&priv->hw, retries); } -struct ieee802154_dev * -ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) +struct ieee802154_hw * +ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { struct wpan_phy *phy; struct mac802154_priv *priv; @@ -285,9 +285,9 @@ ieee802154_alloc_device(size_t priv_data_len, struct ieee802154_ops *ops) return &priv->hw; } -EXPORT_SYMBOL(ieee802154_alloc_device); +EXPORT_SYMBOL(ieee802154_alloc_hw); -void ieee802154_free_device(struct ieee802154_dev *hw) +void ieee802154_free_hw(struct ieee802154_hw *hw) { struct mac802154_priv *priv = mac802154_to_priv(hw); @@ -297,49 +297,49 @@ void ieee802154_free_device(struct ieee802154_dev *hw) wpan_phy_free(priv->phy); } -EXPORT_SYMBOL(ieee802154_free_device); +EXPORT_SYMBOL(ieee802154_free_hw); -int ieee802154_register_device(struct ieee802154_dev *dev) +int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); int rc = -ENOSYS; - if (dev->flags & IEEE802154_HW_TXPOWER) { + if (hw->flags & IEEE802154_HW_TXPOWER) { if (!priv->ops->set_txpower) goto out; priv->phy->set_txpower = mac802154_set_txpower; } - if (dev->flags & IEEE802154_HW_LBT) { + if (hw->flags & IEEE802154_HW_LBT) { if (!priv->ops->set_lbt) goto out; priv->phy->set_lbt = mac802154_set_lbt; } - if (dev->flags & IEEE802154_HW_CCA_MODE) { + if (hw->flags & IEEE802154_HW_CCA_MODE) { if (!priv->ops->set_cca_mode) goto out; priv->phy->set_cca_mode = mac802154_set_cca_mode; } - if (dev->flags & IEEE802154_HW_CCA_ED_LEVEL) { + if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { if (!priv->ops->set_cca_ed_level) goto out; priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; } - if (dev->flags & IEEE802154_HW_CSMA_PARAMS) { + if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { if (!priv->ops->set_csma_params) goto out; priv->phy->set_csma_params = mac802154_set_csma_params; } - if (dev->flags & IEEE802154_HW_FRAME_RETRIES) { + if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { if (!priv->ops->set_frame_retries) goto out; @@ -377,11 +377,11 @@ int ieee802154_register_device(struct ieee802154_dev *dev) out: return rc; } -EXPORT_SYMBOL(ieee802154_register_device); +EXPORT_SYMBOL(ieee802154_register_hw); -void ieee802154_unregister_device(struct ieee802154_dev *dev) +void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); struct mac802154_sub_if_data *sdata, *next; flush_workqueue(priv->dev_workqueue); @@ -405,7 +405,7 @@ void ieee802154_unregister_device(struct ieee802154_dev *dev) wpan_phy_unregister(priv->phy); } -EXPORT_SYMBOL(ieee802154_unregister_device); +EXPORT_SYMBOL(ieee802154_unregister_hw); MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); MODULE_LICENSE("GPL v2"); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index bc6cffd51f94..62b5c7dfe7f3 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -42,12 +42,12 @@ struct rx_work { struct sk_buff *skb; struct work_struct work; - struct ieee802154_dev *dev; + struct ieee802154_hw *hw; u8 lqi; }; static void -mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) +mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { struct mac802154_priv *priv = mac802154_to_priv(hw); @@ -83,14 +83,14 @@ static void mac802154_rx_worker(struct work_struct *work) { struct rx_work *rw = container_of(work, struct rx_work, work); - mac802154_subif_rx(rw->dev, rw->skb, rw->lqi); + mac802154_subif_rx(rw->hw, rw->skb, rw->lqi); kfree(rw); } void -ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) +ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(dev); + struct mac802154_priv *priv = mac802154_to_priv(hw); struct rx_work *work; if (!skb) @@ -102,7 +102,7 @@ ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) INIT_WORK(&work->work, mac802154_rx_worker); work->skb = skb; - work->dev = dev; + work->hw = hw; work->lqi = lqi; queue_work(priv->dev_workqueue, &work->work); -- GitLab From a5e1ec538f54c4cb8ec9ce30867cfbab57225280 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:35 +0200 Subject: [PATCH 1274/9457] mac802154: rename mac802154_priv to ieee802154_local This patch rename the mac802154_priv to ieee802154_local. The mac802154_priv structure is like ieee80211_local and so we name it ieee802154_local. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 12 +-- net/mac802154/iface.c | 4 +- net/mac802154/main.c | 172 +++++++++++++++++------------------ net/mac802154/mib.c | 21 ++--- net/mac802154/monitor.c | 4 +- net/mac802154/rx.c | 12 +-- net/mac802154/tx.c | 36 ++++---- 7 files changed, 130 insertions(+), 131 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 0cb98e87645a..eb55cd2d0b34 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -26,7 +26,7 @@ #include "llsec.h" /* mac802154 device private data */ -struct mac802154_priv { +struct ieee802154_local { struct ieee802154_hw hw; struct ieee802154_ops *ops; @@ -69,7 +69,7 @@ struct mac802154_priv { struct mac802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ - struct mac802154_priv *hw; + struct ieee802154_local *hw; struct net_device *dev; int type; @@ -99,7 +99,7 @@ struct mac802154_sub_if_data { struct mac802154_llsec sec; }; -#define mac802154_to_priv(_hw) container_of(_hw, struct mac802154_priv, hw) +#define mac802154_to_priv(_hw) container_of(_hw, struct ieee802154_local, hw) #define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ @@ -109,13 +109,13 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb); +void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, +netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan); /* MIB callbacks */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 03eedc3b23ef..10f1ee27a616 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -565,7 +565,7 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, return 0; } -void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) +void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) { int ret; struct mac802154_sub_if_data *sdata; @@ -579,7 +579,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) } rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { + list_for_each_entry_rcu(sdata, &local->slaves, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index b0bcc063e9af..387d4cf94853 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -33,7 +33,7 @@ int mac802154_slave_open(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); struct mac802154_sub_if_data *subif; - struct mac802154_priv *ipriv = priv->hw; + struct ieee802154_local *local = priv->hw; int res = 0; ASSERT_RTNL(); @@ -54,17 +54,17 @@ int mac802154_slave_open(struct net_device *dev) priv->running = true; mutex_unlock(&priv->hw->slaves_mtx); - if (ipriv->open_count++ == 0) { - res = ipriv->ops->start(&ipriv->hw); + if (local->open_count++ == 0) { + res = local->ops->start(&local->hw); WARN_ON(res); if (res) goto err; } - if (ipriv->ops->ieee_addr) { + if (local->ops->ieee_addr) { __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); - res = ipriv->ops->ieee_addr(&ipriv->hw, addr); + res = local->ops->ieee_addr(&local->hw, addr); WARN_ON(res); if (res) goto err; @@ -82,7 +82,7 @@ int mac802154_slave_open(struct net_device *dev) int mac802154_slave_close(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *ipriv = priv->hw; + struct ieee802154_local *local = priv->hw; ASSERT_RTNL(); @@ -92,8 +92,8 @@ int mac802154_slave_close(struct net_device *dev) priv->running = false; mutex_unlock(&priv->hw->slaves_mtx); - if (!--ipriv->open_count) - ipriv->ops->stop(&ipriv->hw); + if (!--local->open_count) + local->ops->stop(&local->hw); return 0; } @@ -102,34 +102,34 @@ static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { struct mac802154_sub_if_data *priv; - struct mac802154_priv *ipriv; + struct ieee802154_local *local; int err; - ipriv = wpan_phy_priv(phy); + local = wpan_phy_priv(phy); priv = netdev_priv(dev); priv->dev = dev; - priv->hw = ipriv; + priv->hw = local; - dev->needed_headroom = ipriv->hw.extra_tx_headroom; + dev->needed_headroom = local->hw.extra_tx_headroom; - SET_NETDEV_DEV(dev, &ipriv->phy->dev); + SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&ipriv->slaves_mtx); - if (!ipriv->running) { - mutex_unlock(&ipriv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + if (!local->running) { + mutex_unlock(&local->slaves_mtx); return -ENODEV; } - mutex_unlock(&ipriv->slaves_mtx); + mutex_unlock(&local->slaves_mtx); err = register_netdev(dev); if (err < 0) return err; rtnl_lock(); - mutex_lock(&ipriv->slaves_mtx); - list_add_tail_rcu(&priv->list, &ipriv->slaves); - mutex_unlock(&ipriv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + list_add_tail_rcu(&priv->list, &local->slaves); + mutex_unlock(&local->slaves_mtx); rtnl_unlock(); return 0; @@ -194,52 +194,52 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) static int mac802154_set_txpower(struct wpan_phy *phy, int db) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_txpower(&priv->hw, db); + return local->ops->set_txpower(&local->hw, db); } static int mac802154_set_lbt(struct wpan_phy *phy, bool on) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_lbt(&priv->hw, on); + return local->ops->set_lbt(&local->hw, on); } static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_cca_mode(&priv->hw, mode); + return local->ops->set_cca_mode(&local->hw, mode); } static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_cca_ed_level(&priv->hw, level); + return local->ops->set_cca_ed_level(&local->hw, level); } static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, u8 max_be, u8 retries) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries); + return local->ops->set_csma_params(&local->hw, min_be, max_be, retries); } static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) { - struct mac802154_priv *priv = wpan_phy_priv(phy); + struct ieee802154_local *local = wpan_phy_priv(phy); - return priv->ops->set_frame_retries(&priv->hw, retries); + return local->ops->set_frame_retries(&local->hw, retries); } struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { struct wpan_phy *phy; - struct mac802154_priv *priv; + struct ieee802154_local *local; size_t priv_size; if (!ops || !ops->xmit || !ops->ed || !ops->start || @@ -249,24 +249,24 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) } /* Ensure 32-byte alignment of our private data and hw private data. - * We use the wpan_phy priv data for both our mac802154_priv and for + * We use the wpan_phy priv data for both our ieee802154_local and for * the driver's private data * * in memory it'll be like this: * - * +-----------------------+ - * | struct wpan_phy | - * +-----------------------+ - * | struct mac802154_priv | - * +-----------------------+ - * | driver's private data | - * +-----------------------+ + * +-------------------------+ + * | struct wpan_phy | + * +-------------------------+ + * | struct ieee802154_local | + * +-------------------------+ + * | driver's private data | + * +-------------------------+ * * Due to ieee802154 layer isn't aware of driver and MAC structures, * so lets align them here. */ - priv_size = ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_data_len; + priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; phy = wpan_phy_alloc(priv_size); if (!phy) { @@ -274,106 +274,106 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) return NULL; } - priv = wpan_phy_priv(phy); - priv->phy = phy; - priv->hw.phy = priv->phy; - priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN); - priv->ops = ops; + local = wpan_phy_priv(phy); + local->phy = phy; + local->hw.phy = local->phy; + local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); + local->ops = ops; - INIT_LIST_HEAD(&priv->slaves); - mutex_init(&priv->slaves_mtx); + INIT_LIST_HEAD(&local->slaves); + mutex_init(&local->slaves_mtx); - return &priv->hw; + return &local->hw; } EXPORT_SYMBOL(ieee802154_alloc_hw); void ieee802154_free_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); - BUG_ON(!list_empty(&priv->slaves)); + BUG_ON(!list_empty(&local->slaves)); - mutex_destroy(&priv->slaves_mtx); + mutex_destroy(&local->slaves_mtx); - wpan_phy_free(priv->phy); + wpan_phy_free(local->phy); } EXPORT_SYMBOL(ieee802154_free_hw); int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); int rc = -ENOSYS; if (hw->flags & IEEE802154_HW_TXPOWER) { - if (!priv->ops->set_txpower) + if (!local->ops->set_txpower) goto out; - priv->phy->set_txpower = mac802154_set_txpower; + local->phy->set_txpower = mac802154_set_txpower; } if (hw->flags & IEEE802154_HW_LBT) { - if (!priv->ops->set_lbt) + if (!local->ops->set_lbt) goto out; - priv->phy->set_lbt = mac802154_set_lbt; + local->phy->set_lbt = mac802154_set_lbt; } if (hw->flags & IEEE802154_HW_CCA_MODE) { - if (!priv->ops->set_cca_mode) + if (!local->ops->set_cca_mode) goto out; - priv->phy->set_cca_mode = mac802154_set_cca_mode; + local->phy->set_cca_mode = mac802154_set_cca_mode; } if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { - if (!priv->ops->set_cca_ed_level) + if (!local->ops->set_cca_ed_level) goto out; - priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level; + local->phy->set_cca_ed_level = mac802154_set_cca_ed_level; } if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { - if (!priv->ops->set_csma_params) + if (!local->ops->set_csma_params) goto out; - priv->phy->set_csma_params = mac802154_set_csma_params; + local->phy->set_csma_params = mac802154_set_csma_params; } if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { - if (!priv->ops->set_frame_retries) + if (!local->ops->set_frame_retries) goto out; - priv->phy->set_frame_retries = mac802154_set_frame_retries; + local->phy->set_frame_retries = mac802154_set_frame_retries; } - priv->dev_workqueue = - create_singlethread_workqueue(wpan_phy_name(priv->phy)); - if (!priv->dev_workqueue) { + local->dev_workqueue = + create_singlethread_workqueue(wpan_phy_name(local->phy)); + if (!local->dev_workqueue) { rc = -ENOMEM; goto out; } - wpan_phy_set_dev(priv->phy, priv->hw.parent); + wpan_phy_set_dev(local->phy, local->hw.parent); - priv->phy->add_iface = mac802154_add_iface; - priv->phy->del_iface = mac802154_del_iface; + local->phy->add_iface = mac802154_add_iface; + local->phy->del_iface = mac802154_del_iface; - rc = wpan_phy_register(priv->phy); + rc = wpan_phy_register(local->phy); if (rc < 0) goto out_wq; rtnl_lock(); - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_RUN; - mutex_unlock(&priv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + local->running = MAC802154_DEVICE_RUN; + mutex_unlock(&local->slaves_mtx); rtnl_unlock(); return 0; out_wq: - destroy_workqueue(priv->dev_workqueue); + destroy_workqueue(local->dev_workqueue); out: return rc; } @@ -381,19 +381,19 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); struct mac802154_sub_if_data *sdata, *next; - flush_workqueue(priv->dev_workqueue); - destroy_workqueue(priv->dev_workqueue); + flush_workqueue(local->dev_workqueue); + destroy_workqueue(local->dev_workqueue); rtnl_lock(); - mutex_lock(&priv->slaves_mtx); - priv->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&priv->slaves_mtx); + mutex_lock(&local->slaves_mtx); + local->running = MAC802154_DEVICE_STOPPED; + mutex_unlock(&local->slaves_mtx); - list_for_each_entry_safe(sdata, next, &priv->slaves, list) { + list_for_each_entry_safe(sdata, next, &local->slaves, list) { mutex_lock(&sdata->hw->slaves_mtx); list_del(&sdata->list); mutex_unlock(&sdata->hw->slaves_mtx); @@ -403,7 +403,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_unlock(); - wpan_phy_unregister(priv->phy); + wpan_phy_unregister(local->phy); } EXPORT_SYMBOL(ieee802154_unregister_hw); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 7c9467216199..5d9592a128db 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -36,7 +36,7 @@ struct hw_addr_filt_notify_work { unsigned long changed; }; -static struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) +static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); @@ -49,12 +49,11 @@ static void hw_addr_notify(struct work_struct *work) { struct hw_addr_filt_notify_work *nw = container_of(work, struct hw_addr_filt_notify_work, work); - struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); int res; - res = hw->ops->set_hw_addr_filt(&hw->hw, - &hw->hw.hw_filt, - nw->changed); + res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt, + nw->changed); if (res) pr_debug("failed changed mask %lx\n", nw->changed); @@ -110,13 +109,13 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_priv *mac = priv->hw; + struct ieee802154_local *local = priv->hw; priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); - if (mac->ops->set_hw_addr_filt && - mac->hw.hw_filt.ieee_addr != priv->extended_addr) { - mac->hw.hw_filt.ieee_addr = priv->extended_addr; + if (local->ops->set_hw_addr_filt && + local->hw.hw_filt.ieee_addr != priv->extended_addr) { + local->hw.hw_filt.ieee_addr = priv->extended_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } @@ -165,12 +164,12 @@ static void phy_chan_notify(struct work_struct *work) { struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); - struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); + struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); int res; mutex_lock(&priv->hw->phy->pib_lock); - res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan); + res = local->ops->set_channel(&local->hw, priv->page, priv->chan); if (res) { pr_debug("set_channel failed\n"); } else { diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index ca82c72a635c..a107fd2f2312 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -57,7 +57,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, } -void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct mac802154_sub_if_data *sdata; @@ -65,7 +65,7 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb) u8 *data; rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) { + list_for_each_entry_rcu(sdata, &local->slaves, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 62b5c7dfe7f3..dc01817a92c5 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -49,13 +49,13 @@ struct rx_work { static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc; if (skb->len < 2) { @@ -70,8 +70,8 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) skb_trim(skb, skb->len - 2); /* CRC */ } - mac802154_monitors_rx(priv, skb); - mac802154_wpans_rx(priv, skb); + mac802154_monitors_rx(local, skb); + mac802154_wpans_rx(local, skb); return; @@ -90,7 +90,7 @@ static void mac802154_rx_worker(struct work_struct *work) void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct mac802154_priv *priv = mac802154_to_priv(hw); + struct ieee802154_local *local = mac802154_to_priv(hw); struct rx_work *work; if (!skb) @@ -105,6 +105,6 @@ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) work->hw = hw; work->lqi = lqi; - queue_work(priv->dev_workqueue, &work->work); + queue_work(local->dev_workqueue, &work->work); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8f537bf731ca..d4c92bd3ad32 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -33,7 +33,7 @@ struct xmit_work { struct sk_buff *skb; struct work_struct work; - struct mac802154_priv *priv; + struct ieee802154_local *local; u8 chan; u8 page; }; @@ -44,10 +44,10 @@ static void mac802154_xmit_worker(struct work_struct *work) struct mac802154_sub_if_data *sdata; int res; - mutex_lock(&xw->priv->phy->pib_lock); - if (xw->priv->phy->current_channel != xw->chan || - xw->priv->phy->current_page != xw->page) { - res = xw->priv->ops->set_channel(&xw->priv->hw, + mutex_lock(&xw->local->phy->pib_lock); + if (xw->local->phy->current_channel != xw->chan || + xw->local->phy->current_page != xw->page) { + res = xw->local->ops->set_channel(&xw->local->hw, xw->page, xw->chan); if (res) { @@ -55,20 +55,20 @@ static void mac802154_xmit_worker(struct work_struct *work) goto out; } - xw->priv->phy->current_channel = xw->chan; - xw->priv->phy->current_page = xw->page; + xw->local->phy->current_channel = xw->chan; + xw->local->phy->current_page = xw->page; } - res = xw->priv->ops->xmit(&xw->priv->hw, xw->skb); + res = xw->local->ops->xmit(&xw->local->hw, xw->skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&xw->priv->phy->pib_lock); + mutex_unlock(&xw->local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->priv->slaves, list) + list_for_each_entry_rcu(sdata, &xw->local->slaves, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); @@ -77,20 +77,20 @@ static void mac802154_xmit_worker(struct work_struct *work) kfree(xw); } -netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, +netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; struct mac802154_sub_if_data *sdata; - if (!(priv->phy->channels_supported[page] & (1 << chan))) { + if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); goto err_tx; } - mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); + mac802154_monitors_rx(mac802154_to_priv(&local->hw), skb); - if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data = skb_put(skb, 2); @@ -98,7 +98,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, data[1] = crc >> 8; } - if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) + if (skb_cow_head(skb, local->hw.extra_tx_headroom)) goto err_tx; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -109,17 +109,17 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &priv->slaves, list) + list_for_each_entry_rcu(sdata, &local->slaves, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); INIT_WORK(&work->work, mac802154_xmit_worker); work->skb = skb; - work->priv = priv; + work->local = local; work->page = page; work->chan = chan; - queue_work(priv->dev_workqueue, &work->work); + queue_work(local->dev_workqueue, &work->work); return NETDEV_TX_OK; -- GitLab From 036562f9c4d942f2fbc77ae3215309bde340546f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:36 +0200 Subject: [PATCH 1275/9457] mac802154: rename mac802154_sub_if_data Like wireless this structure should named ieee802154_sub_if_data and not mac802154_sub_if_data. This patch renames the struct and variables to sdata instead priv sometimes. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 137 ++++++++++++------------- net/mac802154/mac_cmd.c | 4 +- net/mac802154/main.c | 54 +++++----- net/mac802154/mib.c | 192 +++++++++++++++++------------------ net/mac802154/monitor.c | 22 ++-- net/mac802154/tx.c | 4 +- 7 files changed, 208 insertions(+), 207 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index eb55cd2d0b34..daaca371110f 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -66,7 +66,7 @@ struct ieee802154_local { * Each ieee802154 device/transceiver may have several slaves and able * to be associated with several networks at the same time. */ -struct mac802154_sub_if_data { +struct ieee802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ struct ieee802154_local *hw; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 10f1ee27a616..d3eb8a445a81 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -33,7 +33,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); int rc = 0; @@ -41,10 +41,10 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) struct ieee802154_llsec_params params; int changed = 0; - params.pan_id = priv->pan_id; + params.pan_id = sdata->pan_id; changed |= IEEE802154_LLSEC_PARAM_PAN_ID; - params.hwaddr = priv->extended_addr; + params.hwaddr = sdata->extended_addr; changed |= IEEE802154_LLSEC_PARAM_HWADDR; rc = ops->llsec->set_params(dev, ¶ms, changed); @@ -56,20 +56,20 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) static int mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct sockaddr_ieee802154 *sa = (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; - spin_lock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); switch (cmd) { case SIOCGIFADDR: { u16 pan_id, short_addr; - pan_id = le16_to_cpu(priv->pan_id); - short_addr = le16_to_cpu(priv->short_addr); + pan_id = le16_to_cpu(sdata->pan_id); + short_addr = le16_to_cpu(sdata->short_addr); if (pan_id == IEEE802154_PANID_BROADCAST || short_addr == IEEE802154_ADDR_BROADCAST) { err = -EADDRNOTAVAIL; @@ -96,14 +96,14 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; } - priv->pan_id = cpu_to_le16(sa->addr.pan_id); - priv->short_addr = cpu_to_le16(sa->addr.short_addr); + sdata->pan_id = cpu_to_le16(sa->addr.pan_id); + sdata->short_addr = cpu_to_le16(sa->addr.short_addr); err = mac802154_wpan_update_llsec(dev); break; } - spin_unlock_bh(&priv->mib_lock); + spin_unlock_bh(&sdata->mib_lock); return err; } @@ -123,11 +123,11 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) int mac802154_set_mac_params(struct net_device *dev, const struct ieee802154_mac_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&priv->hw->slaves_mtx); - priv->mac_params = *params; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->mac_params = *params; + mutex_unlock(&sdata->hw->slaves_mtx); return 0; } @@ -135,18 +135,18 @@ int mac802154_set_mac_params(struct net_device *dev, void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_mac_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&priv->hw->slaves_mtx); - *params = priv->mac_params; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + *params = sdata->mac_params; + mutex_unlock(&sdata->hw->slaves_mtx); } static int mac802154_wpan_open(struct net_device *dev) { int rc; - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct wpan_phy *phy = priv->hw->phy; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct wpan_phy *phy = sdata->hw->phy; rc = mac802154_slave_open(dev); if (rc < 0) @@ -155,40 +155,40 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); if (phy->set_txpower) { - rc = phy->set_txpower(phy, priv->mac_params.transmit_power); + rc = phy->set_txpower(phy, sdata->mac_params.transmit_power); if (rc < 0) goto out; } if (phy->set_lbt) { - rc = phy->set_lbt(phy, priv->mac_params.lbt); + rc = phy->set_lbt(phy, sdata->mac_params.lbt); if (rc < 0) goto out; } if (phy->set_cca_mode) { - rc = phy->set_cca_mode(phy, priv->mac_params.cca_mode); + rc = phy->set_cca_mode(phy, sdata->mac_params.cca_mode); if (rc < 0) goto out; } if (phy->set_cca_ed_level) { - rc = phy->set_cca_ed_level(phy, priv->mac_params.cca_ed_level); + rc = phy->set_cca_ed_level(phy, sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } if (phy->set_csma_params) { - rc = phy->set_csma_params(phy, priv->mac_params.min_be, - priv->mac_params.max_be, - priv->mac_params.csma_retries); + rc = phy->set_csma_params(phy, sdata->mac_params.min_be, + sdata->mac_params.max_be, + sdata->mac_params.csma_retries); if (rc < 0) goto out; } if (phy->set_frame_retries) { rc = phy->set_frame_retries(phy, - priv->mac_params.frame_retries); + sdata->mac_params.frame_retries); if (rc < 0) goto out; } @@ -201,14 +201,14 @@ static int mac802154_wpan_open(struct net_device *dev) return rc; } -static int mac802154_set_header_security(struct mac802154_sub_if_data *priv, +static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata, struct ieee802154_hdr *hdr, const struct ieee802154_mac_cb *cb) { struct ieee802154_llsec_params params; u8 level; - mac802154_llsec_get_params(&priv->sec, ¶ms); + mac802154_llsec_get_params(&sdata->sec, ¶ms); if (!params.enabled && cb->secen_override && cb->secen) return -EINVAL; @@ -241,7 +241,7 @@ static int mac802154_header_create(struct sk_buff *skb, unsigned len) { struct ieee802154_hdr hdr; - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; @@ -254,25 +254,25 @@ static int mac802154_header_create(struct sk_buff *skb, hdr.fc.ack_request = cb->ackreq; hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); - if (mac802154_set_header_security(priv, &hdr, cb) < 0) + if (mac802154_set_header_security(sdata, &hdr, cb) < 0) return -EINVAL; if (!saddr) { - spin_lock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); - if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || - priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || - priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { + if (sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || + sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || + sdata->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { hdr.source.mode = IEEE802154_ADDR_LONG; - hdr.source.extended_addr = priv->extended_addr; + hdr.source.extended_addr = sdata->extended_addr; } else { hdr.source.mode = IEEE802154_ADDR_SHORT; - hdr.source.short_addr = priv->short_addr; + hdr.source.short_addr = sdata->short_addr; } - hdr.source.pan_id = priv->pan_id; + hdr.source.pan_id = sdata->pan_id; - spin_unlock_bh(&priv->mib_lock); + spin_unlock_bh(&sdata->mib_lock); } else { hdr.source = *(const struct ieee802154_addr *)saddr; } @@ -310,16 +310,16 @@ mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) static netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; u8 chan, page; int rc; - priv = netdev_priv(dev); + sdata = netdev_priv(dev); - spin_lock_bh(&priv->mib_lock); - chan = priv->chan; - page = priv->page; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + chan = sdata->chan; + page = sdata->page; + spin_unlock_bh(&sdata->mib_lock); if (chan == MAC802154_CHAN_NONE || page >= WPAN_NUM_PAGES || @@ -328,7 +328,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - rc = mac802154_llsec_encrypt(&priv->sec, skb); + rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { pr_warn("encryption failed: %i\n", rc); kfree_skb(skb); @@ -339,7 +339,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(priv->hw, skb, page, chan); + return mac802154_tx(sdata->hw, skb, page, chan); } static struct header_ops mac802154_header_ops = { @@ -357,16 +357,16 @@ static const struct net_device_ops mac802154_wpan_ops = { static void mac802154_wpan_free(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mac802154_llsec_destroy(&priv->sec); + mac802154_llsec_destroy(&sdata->sec); free_netdev(dev); } void mac802154_wpan_setup(struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; dev->addr_len = IEEE802154_ADDR_LEN; memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); @@ -384,28 +384,29 @@ void mac802154_wpan_setup(struct net_device *dev) dev->netdev_ops = &mac802154_wpan_ops; dev->ml_priv = &mac802154_mlme_wpan; - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_WPAN; + sdata = netdev_priv(dev); + sdata->type = IEEE802154_DEV_WPAN; - priv->chan = MAC802154_CHAN_NONE; - priv->page = 0; + sdata->chan = MAC802154_CHAN_NONE; + sdata->page = 0; - spin_lock_init(&priv->mib_lock); - mutex_init(&priv->sec_mtx); + spin_lock_init(&sdata->mib_lock); + mutex_init(&sdata->sec_mtx); - get_random_bytes(&priv->bsn, 1); - get_random_bytes(&priv->dsn, 1); + get_random_bytes(&sdata->bsn, 1); + get_random_bytes(&sdata->dsn, 1); /* defaults per 802.15.4-2011 */ - priv->mac_params.min_be = 3; - priv->mac_params.max_be = 5; - priv->mac_params.csma_retries = 4; - priv->mac_params.frame_retries = -1; /* for compatibility, actual default is 3 */ + sdata->mac_params.min_be = 3; + sdata->mac_params.max_be = 5; + sdata->mac_params.csma_retries = 4; + /* for compatibility, actual default is 3 */ + sdata->mac_params.frame_retries = -1; - priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); - priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); + sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); - mac802154_llsec_init(&priv->sec); + mac802154_llsec_init(&sdata->sec); } static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) @@ -414,7 +415,7 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) } static int -mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, +mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, const struct ieee802154_hdr *hdr) { __le16 span, sshort; @@ -568,7 +569,7 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) { int ret; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; struct ieee802154_hdr hdr; ret = mac802154_parse_frame_start(skb, &hdr); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index ad09d54bc690..bccaefbe0ba2 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -75,11 +75,11 @@ static int mac802154_mlme_start_req(struct net_device *dev, static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return to_phy(get_device(&priv->hw->phy->dev)); + return to_phy(get_device(&sdata->hw->phy->dev)); } static struct ieee802154_llsec_ops mac802154_llsec_ops = { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 387d4cf94853..6f630d4990fa 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -31,28 +31,28 @@ int mac802154_slave_open(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct mac802154_sub_if_data *subif; - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *subif; + struct ieee802154_local *local = sdata->hw; int res = 0; ASSERT_RTNL(); - if (priv->type == IEEE802154_DEV_WPAN) { - mutex_lock(&priv->hw->slaves_mtx); - list_for_each_entry(subif, &priv->hw->slaves, list) { - if (subif != priv && subif->type == priv->type && + if (sdata->type == IEEE802154_DEV_WPAN) { + mutex_lock(&sdata->hw->slaves_mtx); + list_for_each_entry(subif, &sdata->hw->slaves, list) { + if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&priv->hw->slaves_mtx); + mutex_unlock(&sdata->hw->slaves_mtx); return -EBUSY; } } - mutex_unlock(&priv->hw->slaves_mtx); + mutex_unlock(&sdata->hw->slaves_mtx); } - mutex_lock(&priv->hw->slaves_mtx); - priv->running = true; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->running = true; + mutex_unlock(&sdata->hw->slaves_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -74,23 +74,23 @@ int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: - priv->hw->open_count--; + sdata->hw->open_count--; return res; } int mac802154_slave_close(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_local *local = sdata->hw; ASSERT_RTNL(); netif_stop_queue(dev); - mutex_lock(&priv->hw->slaves_mtx); - priv->running = false; - mutex_unlock(&priv->hw->slaves_mtx); + mutex_lock(&sdata->hw->slaves_mtx); + sdata->running = false; + mutex_unlock(&sdata->hw->slaves_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -101,15 +101,15 @@ int mac802154_slave_close(struct net_device *dev) static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; struct ieee802154_local *local; int err; local = wpan_phy_priv(phy); - priv = netdev_priv(dev); - priv->dev = dev; - priv->hw = local; + sdata = netdev_priv(dev); + sdata->dev = dev; + sdata->hw = local; dev->needed_headroom = local->hw.extra_tx_headroom; @@ -128,7 +128,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) rtnl_lock(); mutex_lock(&local->slaves_mtx); - list_add_tail_rcu(&priv->list, &local->slaves); + list_add_tail_rcu(&sdata->list, &local->slaves); mutex_unlock(&local->slaves_mtx); rtnl_unlock(); @@ -138,7 +138,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) static void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) { - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; ASSERT_RTNL(); @@ -162,12 +162,12 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) switch (type) { case IEEE802154_DEV_MONITOR: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), name, NET_NAME_UNKNOWN, mac802154_monitor_setup); break; case IEEE802154_DEV_WPAN: - dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), + dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), name, NET_NAME_UNKNOWN, mac802154_wpan_setup); break; @@ -382,7 +382,7 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = mac802154_to_priv(hw); - struct mac802154_sub_if_data *sdata, *next; + struct ieee802154_sub_if_data *sdata, *next; flush_workqueue(local->dev_workqueue); destroy_workqueue(local->dev_workqueue); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 5d9592a128db..ef05b3bd9a63 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -38,11 +38,11 @@ struct hw_addr_filt_notify_work { static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return priv->hw; + return sdata->hw; } static void hw_addr_notify(struct work_struct *work) @@ -62,7 +62,7 @@ static void hw_addr_notify(struct work_struct *work) static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct hw_addr_filt_notify_work *work; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -72,92 +72,92 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(priv->hw->dev_workqueue, &work->work); + queue_work(sdata->hw->dev_workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->short_addr = val; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->short_addr = val; + spin_unlock_bh(&sdata->mib_lock); - if ((priv->hw->ops->set_hw_addr_filt) && - (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { - priv->hw->hw.hw_filt.short_addr = priv->short_addr; + if ((sdata->hw->ops->set_hw_addr_filt) && + (sdata->hw->hw.hw_filt.short_addr != sdata->short_addr)) { + sdata->hw->hw.hw_filt.short_addr = sdata->short_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } __le16 mac802154_dev_get_short_addr(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - ret = priv->short_addr; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + ret = sdata->short_addr; + spin_unlock_bh(&sdata->mib_lock); return ret; } void mac802154_dev_set_ieee_addr(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); - struct ieee802154_local *local = priv->hw; + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_local *local = sdata->hw; - priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); + sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); if (local->ops->set_hw_addr_filt && - local->hw.hw_filt.ieee_addr != priv->extended_addr) { - local->hw.hw_filt.ieee_addr = priv->extended_addr; + local->hw.hw_filt.ieee_addr != sdata->extended_addr) { + local->hw.hw_filt.ieee_addr = sdata->extended_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); } } __le16 mac802154_dev_get_pan_id(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - ret = priv->pan_id; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + ret = sdata->pan_id; + spin_unlock_bh(&sdata->mib_lock); return ret; } void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->pan_id = val; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->pan_id = val; + spin_unlock_bh(&sdata->mib_lock); - if ((priv->hw->ops->set_hw_addr_filt) && - (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { - priv->hw->hw.hw_filt.pan_id = priv->pan_id; + if ((sdata->hw->ops->set_hw_addr_filt) && + (sdata->hw->hw.hw_filt.pan_id != sdata->pan_id)) { + sdata->hw->hw.hw_filt.pan_id = sdata->pan_id; set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } u8 mac802154_dev_get_dsn(const struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - return priv->dsn++; + return sdata->dsn++; } static void phy_chan_notify(struct work_struct *work) @@ -165,38 +165,38 @@ static void phy_chan_notify(struct work_struct *work) struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); - struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); int res; - mutex_lock(&priv->hw->phy->pib_lock); - res = local->ops->set_channel(&local->hw, priv->page, priv->chan); + mutex_lock(&sdata->hw->phy->pib_lock); + res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { - priv->hw->phy->current_channel = priv->chan; - priv->hw->phy->current_page = priv->page; + sdata->hw->phy->current_channel = sdata->chan; + sdata->hw->phy->current_page = sdata->page; } - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_unlock(&sdata->hw->phy->pib_lock); kfree(nw); } void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct phy_chan_notify_work *work; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&priv->mib_lock); - priv->page = page; - priv->chan = chan; - spin_unlock_bh(&priv->mib_lock); + spin_lock_bh(&sdata->mib_lock); + sdata->page = page; + sdata->chan = chan; + spin_unlock_bh(&sdata->mib_lock); - mutex_lock(&priv->hw->phy->pib_lock); - if (priv->hw->phy->current_channel != priv->chan || - priv->hw->phy->current_page != priv->page) { - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_lock(&sdata->hw->phy->pib_lock); + if (sdata->hw->phy->current_channel != sdata->chan || + sdata->hw->phy->current_page != sdata->page) { + mutex_unlock(&sdata->hw->phy->pib_lock); work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) @@ -204,9 +204,9 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(priv->hw->dev_workqueue, &work->work); + queue_work(sdata->hw->dev_workqueue, &work->work); } else { - mutex_unlock(&priv->hw->phy->pib_lock); + mutex_unlock(&sdata->hw->phy->pib_lock); } } @@ -214,14 +214,14 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_get_params(&priv->sec, params); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_get_params(&sdata->sec, params); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -230,14 +230,14 @@ int mac802154_set_params(struct net_device *dev, const struct ieee802154_llsec_params *params, int changed) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_set_params(&priv->sec, params, changed); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_set_params(&sdata->sec, params, changed); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -247,14 +247,14 @@ int mac802154_add_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id, const struct ieee802154_llsec_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_key_add(&priv->sec, id, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_key_add(&sdata->sec, id, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -262,14 +262,14 @@ int mac802154_add_key(struct net_device *dev, int mac802154_del_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_key_del(&priv->sec, id); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_key_del(&sdata->sec, id); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -278,28 +278,28 @@ int mac802154_del_key(struct net_device *dev, int mac802154_add_dev(struct net_device *dev, const struct ieee802154_llsec_device *llsec_dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_dev_add(&priv->sec, llsec_dev); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_dev_add(&sdata->sec, llsec_dev); + mutex_unlock(&sdata->sec_mtx); return res; } int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_dev_del(&priv->sec, dev_addr); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_dev_del(&sdata->sec, dev_addr); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -309,14 +309,14 @@ int mac802154_add_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_devkey_add(&priv->sec, device_addr, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_devkey_add(&sdata->sec, device_addr, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -325,14 +325,14 @@ int mac802154_del_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_devkey_del(&priv->sec, device_addr, key); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_devkey_del(&sdata->sec, device_addr, key); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -341,14 +341,14 @@ int mac802154_del_devkey(struct net_device *dev, int mac802154_add_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_seclevel_add(&priv->sec, sl); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_seclevel_add(&sdata->sec, sl); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -356,14 +356,14 @@ int mac802154_add_seclevel(struct net_device *dev, int mac802154_del_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); - res = mac802154_llsec_seclevel_del(&priv->sec, sl); - mutex_unlock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); + res = mac802154_llsec_seclevel_del(&sdata->sec, sl); + mutex_unlock(&sdata->sec_mtx); return res; } @@ -371,28 +371,28 @@ int mac802154_del_seclevel(struct net_device *dev, void mac802154_lock_table(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_lock(&priv->sec_mtx); + mutex_lock(&sdata->sec_mtx); } void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - *t = &priv->sec.table; + *t = &sdata->sec.table; } void mac802154_unlock_table(struct net_device *dev) { - struct mac802154_sub_if_data *priv = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = netdev_priv(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); - mutex_unlock(&priv->sec_mtx); + mutex_unlock(&sdata->sec_mtx); } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index a107fd2f2312..bd63e120b914 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -33,14 +33,14 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; u8 chan, page; - priv = netdev_priv(dev); + sdata = netdev_priv(dev); /* FIXME: locking */ - chan = priv->hw->phy->current_channel; - page = priv->hw->phy->current_page; + chan = sdata->hw->phy->current_channel; + page = sdata->hw->phy->current_page; if (chan == MAC802154_CHAN_NONE) /* not initialized */ return NETDEV_TX_OK; @@ -53,14 +53,14 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(priv->hw, skb, page, chan); + return mac802154_tx(sdata->hw, skb, page, chan); } void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; @@ -90,7 +90,7 @@ static const struct net_device_ops mac802154_monitor_ops = { void mac802154_monitor_setup(struct net_device *dev) { - struct mac802154_sub_if_data *priv; + struct ieee802154_sub_if_data *sdata; dev->addr_len = 0; dev->hard_header_len = 0; @@ -105,9 +105,9 @@ void mac802154_monitor_setup(struct net_device *dev) dev->netdev_ops = &mac802154_monitor_ops; dev->ml_priv = &mac802154_mlme_reduced; - priv = netdev_priv(dev); - priv->type = IEEE802154_DEV_MONITOR; + sdata = netdev_priv(dev); + sdata->type = IEEE802154_DEV_MONITOR; - priv->chan = MAC802154_CHAN_NONE; /* not initialized */ - priv->page = 0; + sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ + sdata->page = 0; } diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d4c92bd3ad32..d20dadd6f27c 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -41,7 +41,7 @@ struct xmit_work { static void mac802154_xmit_worker(struct work_struct *work) { struct xmit_work *xw = container_of(work, struct xmit_work, work); - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; int res; mutex_lock(&xw->local->phy->pib_lock); @@ -81,7 +81,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; - struct mac802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata; if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); -- GitLab From 04e850fe06312a9f570fcc7dbd0f141c012df404 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:37 +0200 Subject: [PATCH 1276/9457] mac802154: rename hw subif_data variable to local This patch renames the hw attribute in struct ieee802154_sub_if_data to local. This avoid confusing with the struct ieee802154_hw hw; inside of local struct. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 12 ++++++------ net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 34 ++++++++++++++++---------------- net/mac802154/mib.c | 38 ++++++++++++++++++------------------ net/mac802154/monitor.c | 6 +++--- 6 files changed, 47 insertions(+), 47 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index daaca371110f..c5b1ab743695 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -69,7 +69,7 @@ struct ieee802154_local { struct ieee802154_sub_if_data { struct list_head list; /* the ieee802154_priv->slaves list */ - struct ieee802154_local *hw; + struct ieee802154_local *local; struct net_device *dev; int type; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index d3eb8a445a81..6eace90da3ed 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -125,9 +125,9 @@ int mac802154_set_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->mac_params = *params; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); return 0; } @@ -137,16 +137,16 @@ void mac802154_get_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); *params = sdata->mac_params; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); } static int mac802154_wpan_open(struct net_device *dev) { int rc; struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct wpan_phy *phy = sdata->hw->phy; + struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); if (rc < 0) @@ -339,7 +339,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->hw, skb, page, chan); + return mac802154_tx(sdata->local, skb, page, chan); } static struct header_ops mac802154_header_ops = { diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index bccaefbe0ba2..5ee1088e47ab 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -79,7 +79,7 @@ static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); - return to_phy(get_device(&sdata->hw->phy->dev)); + return to_phy(get_device(&sdata->local->phy->dev)); } static struct ieee802154_llsec_ops mac802154_llsec_ops = { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 6f630d4990fa..9b2644ff6de5 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -33,26 +33,26 @@ int mac802154_slave_open(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); struct ieee802154_sub_if_data *subif; - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; int res = 0; ASSERT_RTNL(); if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->hw->slaves_mtx); - list_for_each_entry(subif, &sdata->hw->slaves, list) { + mutex_lock(&sdata->local->slaves_mtx); + list_for_each_entry(subif, &sdata->local->slaves, list) { if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); return -EBUSY; } } - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); } - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->running = true; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -74,7 +74,7 @@ int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: - sdata->hw->open_count--; + sdata->local->open_count--; return res; } @@ -82,15 +82,15 @@ int mac802154_slave_open(struct net_device *dev) int mac802154_slave_close(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; ASSERT_RTNL(); netif_stop_queue(dev); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); sdata->running = false; - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -109,7 +109,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) sdata = netdev_priv(dev); sdata->dev = dev; - sdata->hw = local; + sdata->local = local; dev->needed_headroom = local->hw.extra_tx_headroom; @@ -144,11 +144,11 @@ mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) sdata = netdev_priv(dev); - BUG_ON(sdata->hw->phy != phy); + BUG_ON(sdata->local->phy != phy); - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); list_del_rcu(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); synchronize_rcu(); unregister_netdevice(sdata->dev); @@ -394,9 +394,9 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) mutex_unlock(&local->slaves_mtx); list_for_each_entry_safe(sdata, next, &local->slaves, list) { - mutex_lock(&sdata->hw->slaves_mtx); + mutex_lock(&sdata->local->slaves_mtx); list_del(&sdata->list); - mutex_unlock(&sdata->hw->slaves_mtx); + mutex_unlock(&sdata->local->slaves_mtx); unregister_netdevice(sdata->dev); } diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index ef05b3bd9a63..1ffca5c6b0b9 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -42,7 +42,7 @@ static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); - return sdata->hw; + return sdata->local; } static void hw_addr_notify(struct work_struct *work) @@ -72,7 +72,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(sdata->hw->dev_workqueue, &work->work); + queue_work(sdata->local->dev_workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) @@ -85,9 +85,9 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) sdata->short_addr = val; spin_unlock_bh(&sdata->mib_lock); - if ((sdata->hw->ops->set_hw_addr_filt) && - (sdata->hw->hw.hw_filt.short_addr != sdata->short_addr)) { - sdata->hw->hw.hw_filt.short_addr = sdata->short_addr; + if ((sdata->local->ops->set_hw_addr_filt) && + (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) { + sdata->local->hw.hw_filt.short_addr = sdata->short_addr; set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); } } @@ -109,7 +109,7 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - struct ieee802154_local *local = sdata->hw; + struct ieee802154_local *local = sdata->local; sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); @@ -144,9 +144,9 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) sdata->pan_id = val; spin_unlock_bh(&sdata->mib_lock); - if ((sdata->hw->ops->set_hw_addr_filt) && - (sdata->hw->hw.hw_filt.pan_id != sdata->pan_id)) { - sdata->hw->hw.hw_filt.pan_id = sdata->pan_id; + if ((sdata->local->ops->set_hw_addr_filt) && + (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) { + sdata->local->hw.hw_filt.pan_id = sdata->pan_id; set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); } } @@ -168,15 +168,15 @@ static void phy_chan_notify(struct work_struct *work) struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); int res; - mutex_lock(&sdata->hw->phy->pib_lock); + mutex_lock(&sdata->local->phy->pib_lock); res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { - sdata->hw->phy->current_channel = sdata->chan; - sdata->hw->phy->current_page = sdata->page; + sdata->local->phy->current_channel = sdata->chan; + sdata->local->phy->current_page = sdata->page; } - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_unlock(&sdata->local->phy->pib_lock); kfree(nw); } @@ -193,10 +193,10 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) sdata->chan = chan; spin_unlock_bh(&sdata->mib_lock); - mutex_lock(&sdata->hw->phy->pib_lock); - if (sdata->hw->phy->current_channel != sdata->chan || - sdata->hw->phy->current_page != sdata->page) { - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_lock(&sdata->local->phy->pib_lock); + if (sdata->local->phy->current_channel != sdata->chan || + sdata->local->phy->current_page != sdata->page) { + mutex_unlock(&sdata->local->phy->pib_lock); work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) @@ -204,9 +204,9 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(sdata->hw->dev_workqueue, &work->work); + queue_work(sdata->local->dev_workqueue, &work->work); } else { - mutex_unlock(&sdata->hw->phy->pib_lock); + mutex_unlock(&sdata->local->phy->pib_lock); } } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index bd63e120b914..79bce5258b0c 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -39,8 +39,8 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, sdata = netdev_priv(dev); /* FIXME: locking */ - chan = sdata->hw->phy->current_channel; - page = sdata->hw->phy->current_page; + chan = sdata->local->phy->current_channel; + page = sdata->local->phy->current_page; if (chan == MAC802154_CHAN_NONE) /* not initialized */ return NETDEV_TX_OK; @@ -53,7 +53,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->hw, skb, page, chan); + return mac802154_tx(sdata->local, skb, page, chan); } -- GitLab From d98be45b3657fc233f5a098279a4e42ab6f0fa4f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:38 +0200 Subject: [PATCH 1277/9457] mac802154: rename sdata slaves and slaves_mtx This patch renamens the slaves attribute in sdata to interfaces and slaves_mtx to iflist_mtx. This is similar like the mac80211 stack naming convention. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 4 +-- net/mac802154/iface.c | 10 +++---- net/mac802154/main.c | 54 ++++++++++++++++++------------------ net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 4 +-- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index c5b1ab743695..b7cf41c989ec 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -42,8 +42,8 @@ struct ieee802154_local { * * So atomic readers can use any of this protection methods. */ - struct list_head slaves; - struct mutex slaves_mtx; + struct list_head interfaces; + struct mutex iflist_mtx; /* This one is used for scanning and other jobs not to be interfered * with serial driver. diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 6eace90da3ed..c0dbb402b99b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -125,9 +125,9 @@ int mac802154_set_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->mac_params = *params; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); return 0; } @@ -137,9 +137,9 @@ void mac802154_get_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = netdev_priv(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); *params = sdata->mac_params; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); } static int mac802154_wpan_open(struct net_device *dev) @@ -580,7 +580,7 @@ void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) } rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) { + list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9b2644ff6de5..34e7e617611a 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -39,20 +39,20 @@ int mac802154_slave_open(struct net_device *dev) ASSERT_RTNL(); if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->local->slaves_mtx); - list_for_each_entry(subif, &sdata->local->slaves, list) { + mutex_lock(&sdata->local->iflist_mtx); + list_for_each_entry(subif, &sdata->local->interfaces, list) { if (subif != sdata && subif->type == sdata->type && subif->running) { - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); return -EBUSY; } } - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); } - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->running = true; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); if (local->open_count++ == 0) { res = local->ops->start(&local->hw); @@ -88,9 +88,9 @@ int mac802154_slave_close(struct net_device *dev) netif_stop_queue(dev); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); sdata->running = false; - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); if (!--local->open_count) local->ops->stop(&local->hw); @@ -115,21 +115,21 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); if (!local->running) { - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); return -ENODEV; } - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); err = register_netdev(dev); if (err < 0) return err; rtnl_lock(); - mutex_lock(&local->slaves_mtx); - list_add_tail_rcu(&sdata->list, &local->slaves); - mutex_unlock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); + list_add_tail_rcu(&sdata->list, &local->interfaces); + mutex_unlock(&local->iflist_mtx); rtnl_unlock(); return 0; @@ -146,9 +146,9 @@ mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) BUG_ON(sdata->local->phy != phy); - mutex_lock(&sdata->local->slaves_mtx); + mutex_lock(&sdata->local->iflist_mtx); list_del_rcu(&sdata->list); - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); synchronize_rcu(); unregister_netdevice(sdata->dev); @@ -280,8 +280,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); local->ops = ops; - INIT_LIST_HEAD(&local->slaves); - mutex_init(&local->slaves_mtx); + INIT_LIST_HEAD(&local->interfaces); + mutex_init(&local->iflist_mtx); return &local->hw; } @@ -291,9 +291,9 @@ void ieee802154_free_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = mac802154_to_priv(hw); - BUG_ON(!list_empty(&local->slaves)); + BUG_ON(!list_empty(&local->interfaces)); - mutex_destroy(&local->slaves_mtx); + mutex_destroy(&local->iflist_mtx); wpan_phy_free(local->phy); } @@ -364,9 +364,9 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); local->running = MAC802154_DEVICE_RUN; - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); rtnl_unlock(); @@ -389,14 +389,14 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->slaves_mtx); + mutex_lock(&local->iflist_mtx); local->running = MAC802154_DEVICE_STOPPED; - mutex_unlock(&local->slaves_mtx); + mutex_unlock(&local->iflist_mtx); - list_for_each_entry_safe(sdata, next, &local->slaves, list) { - mutex_lock(&sdata->local->slaves_mtx); + list_for_each_entry_safe(sdata, next, &local->interfaces, list) { + mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); - mutex_unlock(&sdata->local->slaves_mtx); + mutex_unlock(&sdata->local->iflist_mtx); unregister_netdevice(sdata->dev); } diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 79bce5258b0c..9d2ac5ea6634 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -65,7 +65,7 @@ void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u8 *data; rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) { + list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) continue; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d20dadd6f27c..b6039c75d175 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -68,7 +68,7 @@ static void mac802154_xmit_worker(struct work_struct *work) /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->local->slaves, list) + list_for_each_entry_rcu(sdata, &xw->local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); @@ -109,7 +109,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->slaves, list) + list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); -- GitLab From 60741361c3ca229a1dbb18e05d11e97b7ea75d69 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:39 +0200 Subject: [PATCH 1278/9457] mac802154: introduce hw_to_local function This patch replace the mac802154_to_priv macro with a static inline function named hw_to_local. This brings a similar naming convention like mac80211 stack. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 8 ++++++-- net/mac802154/main.c | 6 +++--- net/mac802154/rx.c | 4 ++-- net/mac802154/tx.c | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index b7cf41c989ec..41e29b00e7a0 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -99,10 +99,14 @@ struct ieee802154_sub_if_data { struct mac802154_llsec sec; }; -#define mac802154_to_priv(_hw) container_of(_hw, struct ieee802154_local, hw) - #define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ +static inline struct ieee802154_local * +hw_to_local(struct ieee802154_hw *hw) +{ + return container_of(hw, struct ieee802154_local, hw); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 34e7e617611a..c7799faf508b 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(ieee802154_alloc_hw); void ieee802154_free_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); BUG_ON(!list_empty(&local->interfaces)); @@ -301,7 +301,7 @@ EXPORT_SYMBOL(ieee802154_free_hw); int ieee802154_register_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); int rc = -ENOSYS; if (hw->flags & IEEE802154_HW_TXPOWER) { @@ -381,7 +381,7 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; flush_workqueue(local->dev_workqueue); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index dc01817a92c5..1b5e8e332b9b 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -49,7 +49,7 @@ struct rx_work { static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); @@ -90,7 +90,7 @@ static void mac802154_rx_worker(struct work_struct *work) void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { - struct ieee802154_local *local = mac802154_to_priv(hw); + struct ieee802154_local *local = hw_to_local(hw); struct rx_work *work; if (!skb) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index b6039c75d175..36844264b20b 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -88,7 +88,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, goto err_tx; } - mac802154_monitors_rx(mac802154_to_priv(&local->hw), skb); + mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); -- GitLab From 59d19cd70cd38afd2d9bf2e3b48c3a5bbb630b5a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:40 +0200 Subject: [PATCH 1279/9457] mac802154: introduce IEEE802154_DEV_TO_SUB_IF This function adds a wrapper to call netdev_priv to getting the sdata attribute. This is similar like the IEEE80211_DEV_TO_SUB_IF function inside wireless stack implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 6 +++++ net/mac802154/iface.c | 18 ++++++------- net/mac802154/mac_cmd.c | 2 +- net/mac802154/main.c | 11 +++----- net/mac802154/mib.c | 49 ++++++++++++++++++------------------ net/mac802154/monitor.c | 4 +-- 6 files changed, 47 insertions(+), 43 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 41e29b00e7a0..61885aaea6b6 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -107,6 +107,12 @@ hw_to_local(struct ieee802154_hw *hw) return container_of(hw, struct ieee802154_local, hw); } +static inline struct ieee802154_sub_if_data * +IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) +{ + return netdev_priv(dev); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0dbb402b99b..cdd661f0ef3f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -33,7 +33,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); int rc = 0; @@ -56,7 +56,7 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) static int mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct sockaddr_ieee802154 *sa = (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; @@ -123,7 +123,7 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) int mac802154_set_mac_params(struct net_device *dev, const struct ieee802154_mac_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mutex_lock(&sdata->local->iflist_mtx); sdata->mac_params = *params; @@ -135,7 +135,7 @@ int mac802154_set_mac_params(struct net_device *dev, void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_mac_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mutex_lock(&sdata->local->iflist_mtx); *params = sdata->mac_params; @@ -145,7 +145,7 @@ void mac802154_get_mac_params(struct net_device *dev, static int mac802154_wpan_open(struct net_device *dev) { int rc; - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); @@ -241,7 +241,7 @@ static int mac802154_header_create(struct sk_buff *skb, unsigned len) { struct ieee802154_hdr hdr; - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; @@ -314,7 +314,7 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) u8 chan, page; int rc; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); spin_lock_bh(&sdata->mib_lock); chan = sdata->chan; @@ -357,7 +357,7 @@ static const struct net_device_ops mac802154_wpan_ops = { static void mac802154_wpan_free(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); mac802154_llsec_destroy(&sdata->sec); @@ -384,7 +384,7 @@ void mac802154_wpan_setup(struct net_device *dev) dev->netdev_ops = &mac802154_wpan_ops; dev->ml_priv = &mac802154_mlme_wpan; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_WPAN; sdata->chan = MAC802154_CHAN_NONE; diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 5ee1088e47ab..ed767f590ef9 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -75,7 +75,7 @@ static int mac802154_mlme_start_req(struct net_device *dev, static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index c7799faf508b..a34006edcb8d 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -31,7 +31,7 @@ int mac802154_slave_open(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_sub_if_data *subif; struct ieee802154_local *local = sdata->local; int res = 0; @@ -81,7 +81,7 @@ int mac802154_slave_open(struct net_device *dev) int mac802154_slave_close(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; ASSERT_RTNL(); @@ -101,13 +101,12 @@ int mac802154_slave_close(struct net_device *dev) static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { - struct ieee802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local; int err; local = wpan_phy_priv(phy); - sdata = netdev_priv(dev); sdata->dev = dev; sdata->local = local; @@ -138,12 +137,10 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) static void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) { - struct ieee802154_sub_if_data *sdata; + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); ASSERT_RTNL(); - sdata = netdev_priv(dev); - BUG_ON(sdata->local->phy != phy); mutex_lock(&sdata->local->iflist_mtx); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 1ffca5c6b0b9..d7a25048a8af 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -38,7 +38,7 @@ struct hw_addr_filt_notify_work { static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -62,7 +62,7 @@ static void hw_addr_notify(struct work_struct *work) static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct hw_addr_filt_notify_work *work; work = kzalloc(sizeof(*work), GFP_ATOMIC); @@ -77,7 +77,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -94,7 +94,7 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) __le16 mac802154_dev_get_short_addr(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -108,7 +108,7 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) void mac802154_dev_set_ieee_addr(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); @@ -122,7 +122,7 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev) __le16 mac802154_dev_get_pan_id(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); __le16 ret; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -136,7 +136,7 @@ __le16 mac802154_dev_get_pan_id(const struct net_device *dev) void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -153,7 +153,7 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) u8 mac802154_dev_get_dsn(const struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -164,8 +164,9 @@ static void phy_chan_notify(struct work_struct *work) { struct phy_chan_notify_work *nw = container_of(work, struct phy_chan_notify_work, work); - struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); - struct ieee802154_sub_if_data *sdata = netdev_priv(nw->dev); + struct net_device *dev = nw->dev; + struct ieee802154_local *local = mac802154_slave_get_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; mutex_lock(&sdata->local->phy->pib_lock); @@ -183,7 +184,7 @@ static void phy_chan_notify(struct work_struct *work) void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct phy_chan_notify_work *work; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -214,7 +215,7 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -230,7 +231,7 @@ int mac802154_set_params(struct net_device *dev, const struct ieee802154_llsec_params *params, int changed) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -247,7 +248,7 @@ int mac802154_add_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id, const struct ieee802154_llsec_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -262,7 +263,7 @@ int mac802154_add_key(struct net_device *dev, int mac802154_del_key(struct net_device *dev, const struct ieee802154_llsec_key_id *id) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -278,7 +279,7 @@ int mac802154_del_key(struct net_device *dev, int mac802154_add_dev(struct net_device *dev, const struct ieee802154_llsec_device *llsec_dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -292,7 +293,7 @@ int mac802154_add_dev(struct net_device *dev, int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -309,7 +310,7 @@ int mac802154_add_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -325,7 +326,7 @@ int mac802154_del_devkey(struct net_device *dev, __le64 device_addr, const struct ieee802154_llsec_device_key *key) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -341,7 +342,7 @@ int mac802154_del_devkey(struct net_device *dev, int mac802154_add_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -356,7 +357,7 @@ int mac802154_add_seclevel(struct net_device *dev, int mac802154_del_seclevel(struct net_device *dev, const struct ieee802154_llsec_seclevel *sl) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int res; BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -371,7 +372,7 @@ int mac802154_del_seclevel(struct net_device *dev, void mac802154_lock_table(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -381,7 +382,7 @@ void mac802154_lock_table(struct net_device *dev) void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); @@ -390,7 +391,7 @@ void mac802154_get_table(struct net_device *dev, void mac802154_unlock_table(struct net_device *dev) { - struct ieee802154_sub_if_data *sdata = netdev_priv(dev); + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); BUG_ON(dev->type != ARPHRD_IEEE802154); diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 9d2ac5ea6634..f8ea6dc8dda5 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -36,7 +36,7 @@ static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct ieee802154_sub_if_data *sdata; u8 chan, page; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); /* FIXME: locking */ chan = sdata->local->phy->current_channel; @@ -105,7 +105,7 @@ void mac802154_monitor_setup(struct net_device *dev) dev->netdev_ops = &mac802154_monitor_ops; dev->ml_priv = &mac802154_mlme_reduced; - sdata = netdev_priv(dev); + sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ -- GitLab From f773054254b6aa0196063658c7e247e7c6eacbeb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:41 +0200 Subject: [PATCH 1280/9457] mac802154: rename dev_workqueue to workqueue Small rename to use the name workqueue than dev_workqueue. To bring the same naming convention like wireless into 802.15.4. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 10 +++++----- net/mac802154/mib.c | 4 ++-- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 61885aaea6b6..7aae6920fa30 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -48,7 +48,7 @@ struct ieee802154_local { /* This one is used for scanning and other jobs not to be interfered * with serial driver. */ - struct workqueue_struct *dev_workqueue; + struct workqueue_struct *workqueue; /* SoftMAC device is registered and running. One can add subinterfaces. * This flag should be modified under slaves_mtx and RTNL, so you can diff --git a/net/mac802154/main.c b/net/mac802154/main.c index a34006edcb8d..5ce3184bc674 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -343,9 +343,9 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) local->phy->set_frame_retries = mac802154_set_frame_retries; } - local->dev_workqueue = + local->workqueue = create_singlethread_workqueue(wpan_phy_name(local->phy)); - if (!local->dev_workqueue) { + if (!local->workqueue) { rc = -ENOMEM; goto out; } @@ -370,7 +370,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) return 0; out_wq: - destroy_workqueue(local->dev_workqueue); + destroy_workqueue(local->workqueue); out: return rc; } @@ -381,8 +381,8 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; - flush_workqueue(local->dev_workqueue); - destroy_workqueue(local->dev_workqueue); + flush_workqueue(local->workqueue); + destroy_workqueue(local->workqueue); rtnl_lock(); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index d7a25048a8af..16baff1ea313 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -72,7 +72,7 @@ static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) INIT_WORK(&work->work, hw_addr_notify); work->dev = dev; work->changed = changed; - queue_work(sdata->local->dev_workqueue, &work->work); + queue_work(sdata->local->workqueue, &work->work); } void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) @@ -205,7 +205,7 @@ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) INIT_WORK(&work->work, phy_chan_notify); work->dev = dev; - queue_work(sdata->local->dev_workqueue, &work->work); + queue_work(sdata->local->workqueue, &work->work); } else { mutex_unlock(&sdata->local->phy->pib_lock); } diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 1b5e8e332b9b..53c9e0c10a87 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -105,6 +105,6 @@ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) work->hw = hw; work->lqi = lqi; - queue_work(local->dev_workqueue, &work->work); + queue_work(local->workqueue, &work->work); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 36844264b20b..2c40d9bb8387 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -119,7 +119,7 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, work->page = page; work->chan = chan; - queue_work(local->dev_workqueue, &work->work); + queue_work(local->workqueue, &work->work); return NETDEV_TX_OK; -- GitLab From c6f635faf3bca66cf73f6b3319a054959e367b19 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 25 Oct 2014 17:16:42 +0200 Subject: [PATCH 1281/9457] mac802154: remove ieee802154_addr from driver_ops This driver_ops callback function is never used by any driver. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 1 - net/mac802154/main.c | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index eb0e1cb9ca98..b07d431c0b19 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -170,7 +170,6 @@ struct ieee802154_ops { int (*set_hw_addr_filt)(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed); - int (*ieee_addr)(struct ieee802154_hw *hw, __le64 addr); int (*set_txpower)(struct ieee802154_hw *hw, int db); int (*set_lbt)(struct ieee802154_hw *hw, bool on); int (*set_cca_mode)(struct ieee802154_hw *hw, u8 mode); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 5ce3184bc674..0e9a6a203f7a 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -61,16 +61,6 @@ int mac802154_slave_open(struct net_device *dev) goto err; } - if (local->ops->ieee_addr) { - __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); - - res = local->ops->ieee_addr(&local->hw, addr); - WARN_ON(res); - if (res) - goto err; - mac802154_dev_set_ieee_addr(dev); - } - netif_start_queue(dev); return 0; err: -- GitLab From 345b48307d6961183be77748fc0ae5dd660c91a8 Mon Sep 17 00:00:00 2001 From: Hartmut Knaack Date: Sat, 25 Oct 2014 20:09:11 +0200 Subject: [PATCH 1282/9457] iio:humidity:si7020: cleanup read_raw and probe When reading temperature or humidity values, a shift of two bits to the right needs to be applied, and only for the humidity channel a mask of the lower 12 bits needs to be applied. This reduces code repetition. During probe, i2c_set_clientdata() was used, although its counterpart was not, so drop it. Signed-off-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7020.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index e336af713f20..69e49f58a455 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -56,10 +56,9 @@ static int si7020_read_raw(struct iio_dev *indio_dev, SI7020CMD_RH_HOLD); if (ret < 0) return ret; - if (chan->type == IIO_TEMP) - *val = ret >> 2; - else - *val = (ret & 0x3FFF) >> 2; + *val = ret >> 2; + if (chan->type == IIO_HUMIDITYRELATIVE) + *val &= GENMASK(11, 0); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: if (chan->type == IIO_TEMP) @@ -133,7 +132,6 @@ static int si7020_probe(struct i2c_client *client, data = iio_priv(indio_dev); *data = client; - i2c_set_clientdata(client, indio_dev); indio_dev->dev.parent = &client->dev; indio_dev->name = dev_name(&client->dev); -- GitLab From e0922e5e3ccb78aa0152e93dfbd1755ac39c8582 Mon Sep 17 00:00:00 2001 From: Hartmut Knaack Date: Sat, 25 Oct 2014 20:09:06 +0200 Subject: [PATCH 1283/9457] iio:humidity:si7020: fix pointer to i2c client In si7020_read_raw() the pointer to the i2c client was obtained as second level pointer, although a simple pointer is appropriate. Signed-off-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/humidity/si7020.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index 69e49f58a455..b54164677b89 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -45,12 +45,12 @@ static int si7020_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { - struct i2c_client **client = iio_priv(indio_dev); + struct i2c_client *client = iio_priv(indio_dev); int ret; switch (mask) { case IIO_CHAN_INFO_RAW: - ret = i2c_smbus_read_word_data(*client, + ret = i2c_smbus_read_word_data(client, chan->type == IIO_TEMP ? SI7020CMD_TEMP_HOLD : SI7020CMD_RH_HOLD); -- GitLab From ce0694841ea61607afcbdb5a67bb0b00328357ef Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 22 Oct 2014 17:13:33 +0300 Subject: [PATCH 1284/9457] iio: iadc: Qualcomm SPMI PMIC current ADC driver The current ADC is peripheral of Qualcomm SPMI PMIC chips. It has 16 bits resolution and register space inside PMIC accessible across SPMI bus. The driver registers itself through IIO interface. Signed-off-by: Ivan T. Ivanov Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/qcom,spmi-iadc.txt | 46 ++ drivers/iio/adc/Kconfig | 14 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/qcom-spmi-iadc.c | 595 ++++++++++++++++++ 4 files changed, 656 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.txt create mode 100644 drivers/iio/adc/qcom-spmi-iadc.c diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.txt new file mode 100644 index 000000000000..4e36d6e2f7b6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-iadc.txt @@ -0,0 +1,46 @@ +Qualcomm's SPMI PMIC current ADC + +QPNP PMIC current ADC (IADC) provides interface to clients to read current. +A 16 bit ADC is used for current measurements. IADC can measure the current +through an external resistor (channel 1) or internal (built-in) resistor +(channel 0). When using an external resistor it is to be described by +qcom,external-resistor-micro-ohms property. + +IADC node: + +- compatible: + Usage: required + Value type: + Definition: Should contain "qcom,spmi-iadc". + +- reg: + Usage: required + Value type: + Definition: IADC base address and length in the SPMI PMIC register map + +- interrupts: + Usage: optional + Value type: + Definition: End of ADC conversion. + +- qcom,external-resistor-micro-ohms: + Usage: optional + Value type: + Definition: Sense resister value in micro Ohm. + If not defined value of 10000 micro Ohms will be used. + +Example: + /* IADC node */ + pmic_iadc: iadc@3600 { + compatible = "qcom,spmi-iadc"; + reg = <0x3600 0x100>; + interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; + qcom,external-resistor-micro-ohms = <10000>; + #io-channel-cells = <1>; + }; + + /* IIO client node */ + bat { + io-channels = <&pmic_iadc 0>; + io-channel-names = "iadc"; + }; diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 88bdc8f612e2..d0924f3cfa25 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -206,6 +206,20 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config QCOM_SPMI_IADC + tristate "Qualcomm SPMI PMIC current ADC" + depends on SPMI + select REGMAP_SPMI + help + This is the IIO Current ADC driver for Qualcomm QPNP IADC Chip. + + The driver supports single mode operation to read from one of two + channels (external or internal). Hardware have additional + channels internally used for gain and offset calibration. + + To compile this driver as a module, choose M here: the module will + be called qcom-spmi-iadc. + config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index cb88a6a23b8f..c06718b9d8ce 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_NAU7802) += nau7802.o +obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c new file mode 100644 index 000000000000..b9666f2f5e51 --- /dev/null +++ b/drivers/iio/adc/qcom-spmi-iadc.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IADC register and bit definition */ +#define IADC_REVISION2 0x1 +#define IADC_REVISION2_SUPPORTED_IADC 1 + +#define IADC_PERPH_TYPE 0x4 +#define IADC_PERPH_TYPE_ADC 8 + +#define IADC_PERPH_SUBTYPE 0x5 +#define IADC_PERPH_SUBTYPE_IADC 3 + +#define IADC_STATUS1 0x8 +#define IADC_STATUS1_OP_MODE 4 +#define IADC_STATUS1_REQ_STS BIT(1) +#define IADC_STATUS1_EOC BIT(0) +#define IADC_STATUS1_REQ_STS_EOC_MASK 0x3 + +#define IADC_MODE_CTL 0x40 +#define IADC_OP_MODE_SHIFT 3 +#define IADC_OP_MODE_NORMAL 0 +#define IADC_TRIM_EN BIT(0) + +#define IADC_EN_CTL1 0x46 +#define IADC_EN_CTL1_SET BIT(7) + +#define IADC_CH_SEL_CTL 0x48 + +#define IADC_DIG_PARAM 0x50 +#define IADC_DIG_DEC_RATIO_SEL_SHIFT 2 + +#define IADC_HW_SETTLE_DELAY 0x51 + +#define IADC_CONV_REQ 0x52 +#define IADC_CONV_REQ_SET BIT(7) + +#define IADC_FAST_AVG_CTL 0x5a +#define IADC_FAST_AVG_EN 0x5b +#define IADC_FAST_AVG_EN_SET BIT(7) + +#define IADC_PERH_RESET_CTL3 0xda +#define IADC_FOLLOW_WARM_RB BIT(2) + +#define IADC_DATA 0x60 /* 16 bits */ + +#define IADC_SEC_ACCESS 0xd0 +#define IADC_SEC_ACCESS_DATA 0xa5 + +#define IADC_NOMINAL_RSENSE 0xf4 +#define IADC_NOMINAL_RSENSE_SIGN_MASK BIT(7) + +#define IADC_REF_GAIN_MICRO_VOLTS 17857 + +#define IADC_INT_RSENSE_DEVIATION 15625 /* nano Ohms per bit */ + +#define IADC_INT_RSENSE_IDEAL_VALUE 10000 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_VALUE 7800 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_GF 9000 /* micro Ohms */ +#define IADC_INT_RSENSE_DEFAULT_SMIC 9700 /* micro Ohms */ + +#define IADC_CONV_TIME_MIN_US 2000 +#define IADC_CONV_TIME_MAX_US 2100 + +#define IADC_DEF_PRESCALING 0 /* 1:1 */ +#define IADC_DEF_DECIMATION 0 /* 512 */ +#define IADC_DEF_HW_SETTLE_TIME 0 /* 0 us */ +#define IADC_DEF_AVG_SAMPLES 0 /* 1 sample */ + +/* IADC channel list */ +#define IADC_INT_RSENSE 0 +#define IADC_EXT_RSENSE 1 +#define IADC_GAIN_17P857MV 3 +#define IADC_EXT_OFFSET_CSP_CSN 5 +#define IADC_INT_OFFSET_CSP2_CSN2 6 + +/** + * struct iadc_chip - IADC Current ADC device structure. + * @regmap: regmap for register read/write. + * @dev: This device pointer. + * @base: base offset for the ADC peripheral. + * @rsense: Values of the internal and external sense resister in micro Ohms. + * @poll_eoc: Poll for end of conversion instead of waiting for IRQ. + * @offset: Raw offset values for the internal and external channels. + * @gain: Raw gain of the channels. + * @lock: ADC lock for access to the peripheral. + * @complete: ADC notification after end of conversion interrupt is received. + */ +struct iadc_chip { + struct regmap *regmap; + struct device *dev; + u16 base; + bool poll_eoc; + u32 rsense[2]; + u16 offset[2]; + u16 gain; + struct mutex lock; + struct completion complete; +}; + +static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data) +{ + unsigned int val; + int ret; + + ret = regmap_read(iadc->regmap, iadc->base + offset, &val); + if (ret < 0) + return ret; + + *data = val; + return 0; +} + +static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data) +{ + return regmap_write(iadc->regmap, iadc->base + offset, data); +} + +static int iadc_reset(struct iadc_chip *iadc) +{ + u8 data; + int ret; + + ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA); + if (ret < 0) + return ret; + + ret = iadc_read(iadc, IADC_PERH_RESET_CTL3, &data); + if (ret < 0) + return ret; + + ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA); + if (ret < 0) + return ret; + + data |= IADC_FOLLOW_WARM_RB; + + return iadc_write(iadc, IADC_PERH_RESET_CTL3, data); +} + +static int iadc_set_state(struct iadc_chip *iadc, bool state) +{ + return iadc_write(iadc, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0); +} + +static void iadc_status_show(struct iadc_chip *iadc) +{ + u8 mode, sta1, chan, dig, en, req; + int ret; + + ret = iadc_read(iadc, IADC_MODE_CTL, &mode); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_DIG_PARAM, &dig); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_CH_SEL_CTL, &chan); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_CONV_REQ, &req); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_STATUS1, &sta1); + if (ret < 0) + return; + + ret = iadc_read(iadc, IADC_EN_CTL1, &en); + if (ret < 0) + return; + + dev_err(iadc->dev, + "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n", + mode, en, chan, dig, req, sta1); +} + +static int iadc_configure(struct iadc_chip *iadc, int channel) +{ + u8 decim, mode; + int ret; + + /* Mode selection */ + mode = (IADC_OP_MODE_NORMAL << IADC_OP_MODE_SHIFT) | IADC_TRIM_EN; + ret = iadc_write(iadc, IADC_MODE_CTL, mode); + if (ret < 0) + return ret; + + /* Channel selection */ + ret = iadc_write(iadc, IADC_CH_SEL_CTL, channel); + if (ret < 0) + return ret; + + /* Digital parameter setup */ + decim = IADC_DEF_DECIMATION << IADC_DIG_DEC_RATIO_SEL_SHIFT; + ret = iadc_write(iadc, IADC_DIG_PARAM, decim); + if (ret < 0) + return ret; + + /* HW settle time delay */ + ret = iadc_write(iadc, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME); + if (ret < 0) + return ret; + + ret = iadc_write(iadc, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES); + if (ret < 0) + return ret; + + if (IADC_DEF_AVG_SAMPLES) + ret = iadc_write(iadc, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET); + else + ret = iadc_write(iadc, IADC_FAST_AVG_EN, 0); + + if (ret < 0) + return ret; + + if (!iadc->poll_eoc) + reinit_completion(&iadc->complete); + + ret = iadc_set_state(iadc, true); + if (ret < 0) + return ret; + + /* Request conversion */ + return iadc_write(iadc, IADC_CONV_REQ, IADC_CONV_REQ_SET); +} + +static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us) +{ + unsigned int count, retry; + int ret; + u8 sta1; + + retry = interval_us / IADC_CONV_TIME_MIN_US; + + for (count = 0; count < retry; count++) { + ret = iadc_read(iadc, IADC_STATUS1, &sta1); + if (ret < 0) + return ret; + + sta1 &= IADC_STATUS1_REQ_STS_EOC_MASK; + if (sta1 == IADC_STATUS1_EOC) + return 0; + + usleep_range(IADC_CONV_TIME_MIN_US, IADC_CONV_TIME_MAX_US); + } + + iadc_status_show(iadc); + + return -ETIMEDOUT; +} + +static int iadc_read_result(struct iadc_chip *iadc, u16 *data) +{ + return regmap_bulk_read(iadc->regmap, iadc->base + IADC_DATA, data, 2); +} + +static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data) +{ + unsigned int wait; + int ret; + + ret = iadc_configure(iadc, chan); + if (ret < 0) + goto exit; + + wait = BIT(IADC_DEF_AVG_SAMPLES) * IADC_CONV_TIME_MIN_US * 2; + + if (iadc->poll_eoc) { + ret = iadc_poll_wait_eoc(iadc, wait); + } else { + ret = wait_for_completion_timeout(&iadc->complete, wait); + if (!ret) + ret = -ETIMEDOUT; + else + /* double check conversion status */ + ret = iadc_poll_wait_eoc(iadc, IADC_CONV_TIME_MIN_US); + } + + if (!ret) + ret = iadc_read_result(iadc, data); +exit: + iadc_set_state(iadc, false); + if (ret < 0) + dev_err(iadc->dev, "conversion failed\n"); + + return ret; +} + +static int iadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct iadc_chip *iadc = iio_priv(indio_dev); + s32 isense_ua, vsense_uv; + u16 adc_raw, vsense_raw; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&iadc->lock); + ret = iadc_do_conversion(iadc, chan->channel, &adc_raw); + mutex_unlock(&iadc->lock); + if (ret < 0) + return ret; + + vsense_raw = adc_raw - iadc->offset[chan->channel]; + + vsense_uv = vsense_raw * IADC_REF_GAIN_MICRO_VOLTS; + vsense_uv /= (s32)iadc->gain - iadc->offset[chan->channel]; + + isense_ua = vsense_uv / iadc->rsense[chan->channel]; + + dev_dbg(iadc->dev, "off %d gain %d adc %d %duV I %duA\n", + iadc->offset[chan->channel], iadc->gain, + adc_raw, vsense_uv, isense_ua); + + *val = isense_ua; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 0; + *val2 = 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +} + +static const struct iio_info iadc_info = { + .read_raw = iadc_read_raw, + .driver_module = THIS_MODULE, +}; + +static irqreturn_t iadc_isr(int irq, void *dev_id) +{ + struct iadc_chip *iadc = dev_id; + + complete(&iadc->complete); + + return IRQ_HANDLED; +} + +static int iadc_update_offset(struct iadc_chip *iadc) +{ + int ret; + + ret = iadc_do_conversion(iadc, IADC_GAIN_17P857MV, &iadc->gain); + if (ret < 0) + return ret; + + ret = iadc_do_conversion(iadc, IADC_INT_OFFSET_CSP2_CSN2, + &iadc->offset[IADC_INT_RSENSE]); + if (ret < 0) + return ret; + + if (iadc->gain == iadc->offset[IADC_INT_RSENSE]) { + dev_err(iadc->dev, "error: internal offset == gain %d\n", + iadc->gain); + return -EINVAL; + } + + ret = iadc_do_conversion(iadc, IADC_EXT_OFFSET_CSP_CSN, + &iadc->offset[IADC_EXT_RSENSE]); + if (ret < 0) + return ret; + + if (iadc->gain == iadc->offset[IADC_EXT_RSENSE]) { + dev_err(iadc->dev, "error: external offset == gain %d\n", + iadc->gain); + return -EINVAL; + } + + return 0; +} + +static int iadc_version_check(struct iadc_chip *iadc) +{ + u8 val; + int ret; + + ret = iadc_read(iadc, IADC_PERPH_TYPE, &val); + if (ret < 0) + return ret; + + if (val < IADC_PERPH_TYPE_ADC) { + dev_err(iadc->dev, "%d is not ADC\n", val); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_PERPH_SUBTYPE, &val); + if (ret < 0) + return ret; + + if (val < IADC_PERPH_SUBTYPE_IADC) { + dev_err(iadc->dev, "%d is not IADC\n", val); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_REVISION2, &val); + if (ret < 0) + return ret; + + if (val < IADC_REVISION2_SUPPORTED_IADC) { + dev_err(iadc->dev, "revision %d not supported\n", val); + return -EINVAL; + } + + return 0; +} + +static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node) +{ + int ret, sign, int_sense; + u8 deviation; + + ret = of_property_read_u32(node, "qcom,external-resistor-micro-ohms", + &iadc->rsense[IADC_EXT_RSENSE]); + if (ret < 0) + iadc->rsense[IADC_EXT_RSENSE] = IADC_INT_RSENSE_IDEAL_VALUE; + + if (!iadc->rsense[IADC_EXT_RSENSE]) { + dev_err(iadc->dev, "external resistor can't be zero Ohms"); + return -EINVAL; + } + + ret = iadc_read(iadc, IADC_NOMINAL_RSENSE, &deviation); + if (ret < 0) + return ret; + + /* + * Deviation value stored is an offset from 10 mili Ohms, bit 7 is + * the sign, the remaining bits have an LSB of 15625 nano Ohms. + */ + sign = (deviation & IADC_NOMINAL_RSENSE_SIGN_MASK) ? -1 : 1; + + deviation &= ~IADC_NOMINAL_RSENSE_SIGN_MASK; + + /* Scale it to nono Ohms */ + int_sense = IADC_INT_RSENSE_IDEAL_VALUE * 1000; + int_sense += sign * deviation * IADC_INT_RSENSE_DEVIATION; + int_sense /= 1000; /* micro Ohms */ + + iadc->rsense[IADC_INT_RSENSE] = int_sense; + return 0; +} + +static const struct iio_chan_spec iadc_channels[] = { + { + .type = IIO_CURRENT, + .datasheet_name = "INTERNAL_RSENSE", + .channel = 0, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + }, + { + .type = IIO_CURRENT, + .datasheet_name = "EXTERNAL_RSENSE", + .channel = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + }, +}; + +static int iadc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct iio_dev *indio_dev; + struct iadc_chip *iadc; + int ret, irq_eoc; + u32 res; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*iadc)); + if (!indio_dev) + return -ENOMEM; + + iadc = iio_priv(indio_dev); + iadc->dev = dev; + + iadc->regmap = dev_get_regmap(dev->parent, NULL); + if (!iadc->regmap) + return -ENODEV; + + init_completion(&iadc->complete); + mutex_init(&iadc->lock); + + ret = of_property_read_u32(node, "reg", &res); + if (ret < 0) + return -ENODEV; + + iadc->base = res; + + ret = iadc_version_check(iadc); + if (ret < 0) + return -ENODEV; + + ret = iadc_rsense_read(iadc, node); + if (ret < 0) + return -ENODEV; + + dev_dbg(iadc->dev, "sense resistors %d and %d micro Ohm\n", + iadc->rsense[IADC_INT_RSENSE], + iadc->rsense[IADC_EXT_RSENSE]); + + irq_eoc = platform_get_irq(pdev, 0); + if (irq_eoc == -EPROBE_DEFER) + return irq_eoc; + + if (irq_eoc < 0) + iadc->poll_eoc = true; + + ret = iadc_reset(iadc); + if (ret < 0) { + dev_err(dev, "reset failed\n"); + return ret; + } + + if (!iadc->poll_eoc) { + ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0, + "spmi-iadc", iadc); + if (!ret) + enable_irq_wake(irq_eoc); + else + return ret; + } else { + device_init_wakeup(iadc->dev, 1); + } + + ret = iadc_update_offset(iadc); + if (ret < 0) { + dev_err(dev, "failed offset calibration\n"); + return ret; + } + + indio_dev->dev.parent = dev; + indio_dev->dev.of_node = node; + indio_dev->name = pdev->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &iadc_info; + indio_dev->channels = iadc_channels; + indio_dev->num_channels = ARRAY_SIZE(iadc_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id iadc_match_table[] = { + { .compatible = "qcom,spmi-iadc" }, + { } +}; + +MODULE_DEVICE_TABLE(of, iadc_match_table); + +static struct platform_driver iadc_driver = { + .driver = { + .name = "qcom-spmi-iadc", + .of_match_table = iadc_match_table, + }, + .probe = iadc_probe, +}; + +module_platform_driver(iadc_driver); + +MODULE_ALIAS("platform:qcom-spmi-iadc"); +MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Ivan T. Ivanov "); -- GitLab From 69088822abe7a09145fc86e1d5dd4996e29abc2d Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 25 Oct 2014 15:12:12 -0400 Subject: [PATCH 1285/9457] sunvnet: NAPIfy sunvnet Move Rx packet procssing to the NAPI poll callback. Disable VIO interrupt and unconditioanlly go into NAPI context from vnet_event. Note that we want to minimize the number of LDC STOP/START messages sent. Specifically, do not send a STOP message if vnet_walk_rx does not read all the available descriptors because of the NAPI budget limitation. Instead, note the end index as part of port state, and resume from this index when the next poll callback is triggered. Signed-off-by: Sowmini Varadhan Acked-by: Raghuram Kothakota Acked-by: Dwight Engen Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 173 ++++++++++++++++++++++------- drivers/net/ethernet/sun/sunvnet.h | 6 +- 2 files changed, 135 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 3652afd3ec78..9e048f501f24 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -311,9 +311,7 @@ static int vnet_rx_one(struct vnet_port *port, unsigned int len, dev->stats.rx_packets++; dev->stats.rx_bytes += len; - - netif_rx(skb); - + napi_gro_receive(&port->napi, skb); return 0; out_free_skb: @@ -430,6 +428,7 @@ static int vnet_walk_rx_one(struct vnet_port *port, struct vio_driver_state *vio = &port->vio; int err; + BUG_ON(desc == NULL); if (IS_ERR(desc)) return PTR_ERR(desc); @@ -456,10 +455,11 @@ static int vnet_walk_rx_one(struct vnet_port *port, } static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, - u32 start, u32 end) + u32 start, u32 end, int *npkts, int budget) { struct vio_driver_state *vio = &port->vio; int ack_start = -1, ack_end = -1; + bool send_ack = true; end = (end == (u32) -1) ? prev_idx(start, dr) : next_idx(end, dr); @@ -471,6 +471,7 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, return err; if (err != 0) break; + (*npkts)++; if (ack_start == -1) ack_start = start; ack_end = start; @@ -482,13 +483,26 @@ static int vnet_walk_rx(struct vnet_port *port, struct vio_dring_state *dr, return err; ack_start = -1; } + if ((*npkts) >= budget) { + send_ack = false; + break; + } } if (unlikely(ack_start == -1)) ack_start = ack_end = prev_idx(start, dr); - return vnet_send_ack(port, dr, ack_start, ack_end, VIO_DRING_STOPPED); + if (send_ack) { + port->napi_resume = false; + return vnet_send_ack(port, dr, ack_start, ack_end, + VIO_DRING_STOPPED); + } else { + port->napi_resume = true; + port->napi_stop_idx = ack_end; + return 1; + } } -static int vnet_rx(struct vnet_port *port, void *msgbuf) +static int vnet_rx(struct vnet_port *port, void *msgbuf, int *npkts, + int budget) { struct vio_dring_data *pkt = msgbuf; struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_RX_RING]; @@ -505,11 +519,13 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf) return 0; } - dr->rcv_nxt++; + if (!port->napi_resume) + dr->rcv_nxt++; /* XXX Validate pkt->start_idx and pkt->end_idx XXX */ - return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx); + return vnet_walk_rx(port, dr, pkt->start_idx, pkt->end_idx, + npkts, budget); } static int idx_is_pending(struct vio_dring_state *dr, u32 end) @@ -542,9 +558,12 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) if (unlikely(!idx_is_pending(dr, end))) return 0; + vp = port->vp; + dev = vp->dev; /* sync for race conditions with vnet_start_xmit() and tell xmit it * is time to send a trigger. */ + netif_tx_lock(dev); dr->cons = next_idx(end, dr); desc = vio_dring_entry(dr, dr->cons); if (desc->hdr.state == VIO_DESC_READY && port->start_cons) { @@ -559,10 +578,8 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) } else { port->start_cons = true; } + netif_tx_unlock(dev); - - vp = port->vp; - dev = vp->dev; if (unlikely(netif_queue_stopped(dev) && vnet_tx_dring_avail(dr) >= VNET_TX_WAKEUP_THRESH(dr))) return 1; @@ -591,9 +608,8 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf) return 0; } -static void maybe_tx_wakeup(unsigned long param) +static void maybe_tx_wakeup(struct vnet *vp) { - struct vnet *vp = (struct vnet *)param; struct net_device *dev = vp->dev; netif_tx_lock(dev); @@ -617,32 +633,43 @@ static void maybe_tx_wakeup(unsigned long param) netif_tx_unlock(dev); } -static void vnet_event(void *arg, int event) +static inline bool port_is_up(struct vnet_port *vnet) +{ + struct vio_driver_state *vio = &vnet->vio; + + return !!(vio->hs_state & VIO_HS_COMPLETE); +} + +static int vnet_event_napi(struct vnet_port *port, int budget) { - struct vnet_port *port = arg; struct vio_driver_state *vio = &port->vio; - unsigned long flags; int tx_wakeup, err; + int npkts = 0; + int event = (port->rx_event & LDC_EVENT_RESET); - spin_lock_irqsave(&vio->lock, flags); - +ldc_ctrl: if (unlikely(event == LDC_EVENT_RESET || event == LDC_EVENT_UP)) { vio_link_state_change(vio, event); - spin_unlock_irqrestore(&vio->lock, flags); if (event == LDC_EVENT_RESET) { port->rmtu = 0; vio_port_up(vio); } - return; + port->rx_event = 0; + return 0; } + /* We may have multiple LDC events in rx_event. Unroll send_events() */ + event = (port->rx_event & LDC_EVENT_UP); + port->rx_event &= ~(LDC_EVENT_RESET|LDC_EVENT_UP); + if (event == LDC_EVENT_UP) + goto ldc_ctrl; + event = port->rx_event; + if (!(event & LDC_EVENT_DATA_READY)) + return 0; - if (unlikely(event != LDC_EVENT_DATA_READY)) { - pr_warn("Unexpected LDC event %d\n", event); - spin_unlock_irqrestore(&vio->lock, flags); - return; - } + /* we dont expect any other bits than RESET, UP, DATA_READY */ + BUG_ON(event != LDC_EVENT_DATA_READY); tx_wakeup = err = 0; while (1) { @@ -651,6 +678,21 @@ static void vnet_event(void *arg, int event) u64 raw[8]; } msgbuf; + if (port->napi_resume) { + struct vio_dring_data *pkt = + (struct vio_dring_data *)&msgbuf; + struct vio_dring_state *dr = + &port->vio.drings[VIO_DRIVER_RX_RING]; + + pkt->tag.type = VIO_TYPE_DATA; + pkt->tag.stype = VIO_SUBTYPE_INFO; + pkt->tag.stype_env = VIO_DRING_DATA; + pkt->seq = dr->rcv_nxt; + pkt->start_idx = next_idx(port->napi_stop_idx, dr); + pkt->end_idx = -1; + goto napi_resume; + } +ldc_read: err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf)); if (unlikely(err < 0)) { if (err == -ECONNRESET) @@ -667,10 +709,22 @@ static void vnet_event(void *arg, int event) err = vio_validate_sid(vio, &msgbuf.tag); if (err < 0) break; - +napi_resume: if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) { if (msgbuf.tag.stype == VIO_SUBTYPE_INFO) { - err = vnet_rx(port, &msgbuf); + if (!port_is_up(port)) { + /* failures like handshake_failure() + * may have cleaned up dring, but + * NAPI polling may bring us here. + */ + err = -ECONNRESET; + break; + } + err = vnet_rx(port, &msgbuf, &npkts, budget); + if (npkts >= budget) + break; + if (npkts == 0 && err != -ECONNRESET) + goto ldc_read; } else if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) { err = vnet_ack(port, &msgbuf); if (err > 0) @@ -691,15 +745,33 @@ static void vnet_event(void *arg, int event) if (err == -ECONNRESET) break; } - spin_unlock(&vio->lock); - /* Kick off a tasklet to wake the queue. We cannot call - * maybe_tx_wakeup directly here because we could deadlock on - * netif_tx_lock() with dev_watchdog() - */ if (unlikely(tx_wakeup && err != -ECONNRESET)) - tasklet_schedule(&port->vp->vnet_tx_wakeup); + maybe_tx_wakeup(port->vp); + return npkts; +} + +static int vnet_poll(struct napi_struct *napi, int budget) +{ + struct vnet_port *port = container_of(napi, struct vnet_port, napi); + struct vio_driver_state *vio = &port->vio; + int processed = vnet_event_napi(port, budget); + + if (processed < budget) { + napi_complete(napi); + vio_set_intr(vio->vdev->rx_ino, HV_INTR_ENABLED); + } + return processed; +} + +static void vnet_event(void *arg, int event) +{ + struct vnet_port *port = arg; + struct vio_driver_state *vio = &port->vio; + + port->rx_event |= event; + vio_set_intr(vio->vdev->rx_ino, HV_INTR_DISABLED); + napi_schedule(&port->napi); - local_irq_restore(flags); } static int __vnet_tx_trigger(struct vnet_port *port, u32 start) @@ -746,13 +818,6 @@ static int __vnet_tx_trigger(struct vnet_port *port, u32 start) return err; } -static inline bool port_is_up(struct vnet_port *vnet) -{ - struct vio_driver_state *vio = &vnet->vio; - - return !!(vio->hs_state & VIO_HS_COMPLETE); -} - struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) { unsigned int hash = vnet_hashfn(skb->data); @@ -1342,6 +1407,21 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port) return err; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void vnet_poll_controller(struct net_device *dev) +{ + struct vnet *vp = netdev_priv(dev); + struct vnet_port *port; + unsigned long flags; + + spin_lock_irqsave(&vp->lock, flags); + if (!list_empty(&vp->port_list)) { + port = list_entry(vp->port_list.next, struct vnet_port, list); + napi_schedule(&port->napi); + } + spin_unlock_irqrestore(&vp->lock, flags); +} +#endif static LIST_HEAD(vnet_list); static DEFINE_MUTEX(vnet_list_mutex); @@ -1354,6 +1434,9 @@ static const struct net_device_ops vnet_ops = { .ndo_tx_timeout = vnet_tx_timeout, .ndo_change_mtu = vnet_change_mtu, .ndo_start_xmit = vnet_start_xmit, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = vnet_poll_controller, +#endif }; static struct vnet *vnet_new(const u64 *local_mac) @@ -1374,7 +1457,6 @@ static struct vnet *vnet_new(const u64 *local_mac) vp = netdev_priv(dev); spin_lock_init(&vp->lock); - tasklet_init(&vp->vnet_tx_wakeup, maybe_tx_wakeup, (unsigned long)vp); vp->dev = dev; INIT_LIST_HEAD(&vp->port_list); @@ -1434,7 +1516,6 @@ static void vnet_cleanup(void) vp = list_first_entry(&vnet_list, struct vnet, list); list_del(&vp->list); dev = vp->dev; - tasklet_kill(&vp->vnet_tx_wakeup); /* vio_unregister_driver() should have cleaned up port_list */ BUG_ON(!list_empty(&vp->port_list)); unregister_netdev(dev); @@ -1536,6 +1617,8 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) if (err) goto err_out_free_port; + netif_napi_add(port->vp->dev, &port->napi, vnet_poll, NAPI_POLL_WEIGHT); + err = vnet_port_alloc_tx_bufs(port); if (err) goto err_out_free_ldc; @@ -1564,6 +1647,7 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) setup_timer(&port->clean_timer, vnet_clean_timer_expire, (unsigned long)port); + napi_enable(&port->napi); vio_port_up(&port->vio); mdesc_release(hp); @@ -1571,6 +1655,7 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) return 0; err_out_free_ldc: + netif_napi_del(&port->napi); vio_ldc_free(&port->vio); err_out_free_port: @@ -1592,11 +1677,13 @@ static int vnet_port_remove(struct vio_dev *vdev) del_timer_sync(&port->vio.timer); del_timer_sync(&port->clean_timer); + napi_disable(&port->napi); spin_lock_irqsave(&vp->lock, flags); list_del(&port->list); hlist_del(&port->hash); spin_unlock_irqrestore(&vp->lock, flags); + netif_napi_del(&port->napi); vnet_port_free_tx_bufs(port); vio_ldc_free(&port->vio); diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h index c91104542619..c8a862e471dd 100644 --- a/drivers/net/ethernet/sun/sunvnet.h +++ b/drivers/net/ethernet/sun/sunvnet.h @@ -56,6 +56,11 @@ struct vnet_port { struct timer_list clean_timer; u64 rmtu; + + struct napi_struct napi; + u32 napi_stop_idx; + bool napi_resume; + int rx_event; }; static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio) @@ -97,7 +102,6 @@ struct vnet { struct list_head list; u64 local_mac; - struct tasklet_struct vnet_tx_wakeup; }; #endif /* _SUNVNET_H */ -- GitLab From 2a968dd8f7d71ae85c4fe0ff190fbfb4212faf98 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 25 Oct 2014 15:12:20 -0400 Subject: [PATCH 1286/9457] sunvnet: Use RCU to synchronize port usage with vnet_port_remove() A vnet_port_remove could be triggered as a result of an ldm-unbind operation by the peer, module unload, or other changes to the inter-vnet-link configuration. When this is concurrent with vnet_start_xmit(), there are several race sequences possible, such as thread 1 thread 2 vnet_start_xmit -> tx_port_find spin_lock_irqsave(&vp->lock..) ret = __tx_port_find(..) spin_lock_irqrestore(&vp->lock..) vio_remove -> .. ->vnet_port_remove spin_lock_irqsave(&vp->lock..) cleanup spin_lock_irqrestore(&vp->lock..) kfree(port) /* attempt to use ret will bomb */ This patch adds RCU locking for port access so that vnet_port_remove will correctly clean up port-related state. Signed-off-by: Sowmini Varadhan Acked-by: Dwight Engen Acked-by: Bob Picco Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 62 ++++++++++++++++-------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 9e048f501f24..966c252c3ca9 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -617,7 +617,8 @@ static void maybe_tx_wakeup(struct vnet *vp) struct vnet_port *port; int wake = 1; - list_for_each_entry(port, &vp->port_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(port, &vp->port_list, list) { struct vio_dring_state *dr; dr = &port->vio.drings[VIO_DRIVER_TX_RING]; @@ -627,6 +628,7 @@ static void maybe_tx_wakeup(struct vnet *vp) break; } } + rcu_read_unlock(); if (wake) netif_wake_queue(dev); } @@ -824,13 +826,13 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) struct hlist_head *hp = &vp->port_hash[hash]; struct vnet_port *port; - hlist_for_each_entry(port, hp, hash) { + hlist_for_each_entry_rcu(port, hp, hash) { if (!port_is_up(port)) continue; if (ether_addr_equal(port->raddr, skb->data)) return port; } - list_for_each_entry(port, &vp->port_list, list) { + list_for_each_entry_rcu(port, &vp->port_list, list) { if (!port->switch_port) continue; if (!port_is_up(port)) @@ -966,7 +968,7 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, void **pstart, static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vnet *vp = netdev_priv(dev); - struct vnet_port *port = tx_port_find(vp, skb); + struct vnet_port *port = NULL; struct vio_dring_state *dr; struct vio_net_desc *d; unsigned long flags; @@ -977,14 +979,15 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) int nlen = 0; unsigned pending = 0; - if (unlikely(!port)) - goto out_dropped; - skb = vnet_skb_shape(skb, &start, &nlen); - if (unlikely(!skb)) goto out_dropped; + rcu_read_lock(); + port = tx_port_find(vp, skb); + if (unlikely(!port)) + goto out_dropped; + if (skb->len > port->rmtu) { unsigned long localmtu = port->rmtu - ETH_HLEN; @@ -1002,6 +1005,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) fl4.saddr = ip_hdr(skb)->saddr; rt = ip_route_output_key(dev_net(dev), &fl4); + rcu_read_unlock(); if (!IS_ERR(rt)) { skb_dst_set(skb, &rt->dst); icmp_send(skb, ICMP_DEST_UNREACH, @@ -1027,7 +1031,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); dev->stats.tx_errors++; } - spin_unlock_irqrestore(&port->vio.lock, flags); + rcu_read_unlock(); return NETDEV_TX_BUSY; } @@ -1121,25 +1125,27 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) } spin_unlock_irqrestore(&port->vio.lock, flags); + (void)mod_timer(&port->clean_timer, jiffies + VNET_CLEAN_TIMEOUT); + rcu_read_unlock(); vnet_free_skbs(freeskbs); - (void)mod_timer(&port->clean_timer, jiffies + VNET_CLEAN_TIMEOUT); - return NETDEV_TX_OK; out_dropped_unlock: spin_unlock_irqrestore(&port->vio.lock, flags); out_dropped: - if (skb) - dev_kfree_skb(skb); - vnet_free_skbs(freeskbs); if (pending) (void)mod_timer(&port->clean_timer, jiffies + VNET_CLEAN_TIMEOUT); else if (port) del_timer(&port->clean_timer); + if (port) + rcu_read_unlock(); + if (skb) + dev_kfree_skb(skb); + vnet_free_skbs(freeskbs); dev->stats.tx_dropped++; return NETDEV_TX_OK; } @@ -1269,18 +1275,17 @@ static void vnet_set_rx_mode(struct net_device *dev) { struct vnet *vp = netdev_priv(dev); struct vnet_port *port; - unsigned long flags; - spin_lock_irqsave(&vp->lock, flags); - if (!list_empty(&vp->port_list)) { - port = list_entry(vp->port_list.next, struct vnet_port, list); + rcu_read_lock(); + list_for_each_entry_rcu(port, &vp->port_list, list) { if (port->switch_port) { __update_mc_list(vp, dev); __send_mc_list(vp, port); + break; } } - spin_unlock_irqrestore(&vp->lock, flags); + rcu_read_unlock(); } static int vnet_change_mtu(struct net_device *dev, int new_mtu) @@ -1633,10 +1638,11 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) spin_lock_irqsave(&vp->lock, flags); if (switch_port) - list_add(&port->list, &vp->port_list); + list_add_rcu(&port->list, &vp->port_list); else - list_add_tail(&port->list, &vp->port_list); - hlist_add_head(&port->hash, &vp->port_hash[vnet_hashfn(port->raddr)]); + list_add_tail_rcu(&port->list, &vp->port_list); + hlist_add_head_rcu(&port->hash, + &vp->port_hash[vnet_hashfn(port->raddr)]); spin_unlock_irqrestore(&vp->lock, flags); dev_set_drvdata(&vdev->dev, port); @@ -1671,18 +1677,16 @@ static int vnet_port_remove(struct vio_dev *vdev) struct vnet_port *port = dev_get_drvdata(&vdev->dev); if (port) { - struct vnet *vp = port->vp; - unsigned long flags; del_timer_sync(&port->vio.timer); - del_timer_sync(&port->clean_timer); napi_disable(&port->napi); - spin_lock_irqsave(&vp->lock, flags); - list_del(&port->list); - hlist_del(&port->hash); - spin_unlock_irqrestore(&vp->lock, flags); + list_del_rcu(&port->list); + hlist_del_rcu(&port->hash); + + synchronize_rcu(); + del_timer_sync(&port->clean_timer); netif_napi_del(&port->napi); vnet_port_free_tx_bufs(port); vio_ldc_free(&port->vio); -- GitLab From 13b13dd97c3a45857b2b622add06b1c70b748abf Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 25 Oct 2014 15:12:31 -0400 Subject: [PATCH 1287/9457] sunvnet: Remove irqsave/irqrestore on vio.lock After the NAPIfication of sunvnet, we no longer need to synchronize by doing irqsave/restore on vio.lock in the I/O fastpath. NAPI ->poll() is non-reentrant, so all RX processing occurs strictly in a serialized environment. TX reclaim is done in NAPI context, so the netif_tx_lock can be used to serialize critical sections between Tx and Rx paths. Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 966c252c3ca9..c390a2784546 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -842,18 +842,6 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb) return NULL; } -struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb) -{ - struct vnet_port *ret; - unsigned long flags; - - spin_lock_irqsave(&vp->lock, flags); - ret = __tx_port_find(vp, skb); - spin_unlock_irqrestore(&vp->lock, flags); - - return ret; -} - static struct sk_buff *vnet_clean_tx_ring(struct vnet_port *port, unsigned *pending) { @@ -914,11 +902,10 @@ static void vnet_clean_timer_expire(unsigned long port0) struct vnet_port *port = (struct vnet_port *)port0; struct sk_buff *freeskbs; unsigned pending; - unsigned long flags; - spin_lock_irqsave(&port->vio.lock, flags); + netif_tx_lock(port->vp->dev); freeskbs = vnet_clean_tx_ring(port, &pending); - spin_unlock_irqrestore(&port->vio.lock, flags); + netif_tx_unlock(port->vp->dev); vnet_free_skbs(freeskbs); @@ -971,7 +958,6 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) struct vnet_port *port = NULL; struct vio_dring_state *dr; struct vio_net_desc *d; - unsigned long flags; unsigned int len; struct sk_buff *freeskbs = NULL; int i, err, txi; @@ -984,7 +970,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto out_dropped; rcu_read_lock(); - port = tx_port_find(vp, skb); + port = __tx_port_find(vp, skb); if (unlikely(!port)) goto out_dropped; @@ -1020,8 +1006,6 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto out_dropped; } - spin_lock_irqsave(&port->vio.lock, flags); - dr = &port->vio.drings[VIO_DRIVER_TX_RING]; if (unlikely(vnet_tx_dring_avail(dr) < 1)) { if (!netif_queue_stopped(dev)) { @@ -1055,7 +1039,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) (LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_RW)); if (err < 0) { netdev_info(dev, "tx buffer map error %d\n", err); - goto out_dropped_unlock; + goto out_dropped; } port->tx_bufs[txi].ncookies = err; @@ -1108,7 +1092,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) netdev_info(dev, "TX trigger error %d\n", err); d->hdr.state = VIO_DESC_FREE; dev->stats.tx_carrier_errors++; - goto out_dropped_unlock; + goto out_dropped; } ldc_start_done: @@ -1124,7 +1108,6 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_wake_queue(dev); } - spin_unlock_irqrestore(&port->vio.lock, flags); (void)mod_timer(&port->clean_timer, jiffies + VNET_CLEAN_TIMEOUT); rcu_read_unlock(); @@ -1132,9 +1115,6 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; -out_dropped_unlock: - spin_unlock_irqrestore(&port->vio.lock, flags); - out_dropped: if (pending) (void)mod_timer(&port->clean_timer, -- GitLab From 50c6fb9965907732b4f5c45bd3bacf4b4f3463b9 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:01 +0100 Subject: [PATCH 1288/9457] mac802154: tx: move xmit callback to tx file This patch moves the netdev xmit callback functions into the tx.c file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 5 ++- net/mac802154/iface.c | 35 --------------------- net/mac802154/monitor.c | 27 ----------------- net/mac802154/tx.c | 59 ++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 67 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 7aae6920fa30..a9a9d8e15278 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -121,12 +121,11 @@ int mac802154_slave_close(struct net_device *dev); void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); +netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev); void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); - -netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, - u8 page, u8 chan); +netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev); /* MIB callbacks */ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index cdd661f0ef3f..f14e4365c4c7 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -307,41 +307,6 @@ mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) return sizeof(*addr); } -static netdev_tx_t -mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - u8 chan, page; - int rc; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - spin_lock_bh(&sdata->mib_lock); - chan = sdata->chan; - page = sdata->page; - spin_unlock_bh(&sdata->mib_lock); - - if (chan == MAC802154_CHAN_NONE || - page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - - rc = mac802154_llsec_encrypt(&sdata->sec, skb); - if (rc) { - pr_warn("encryption failed: %i\n", rc); - kfree_skb(skb); - return NETDEV_TX_OK; - } - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(sdata->local, skb, page, chan); -} - static struct header_ops mac802154_header_ops = { .create = mac802154_header_create, .parse = mac802154_header_parse, diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index f8ea6dc8dda5..cb9600bcca51 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -30,33 +30,6 @@ #include "ieee802154_i.h" -static netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - u8 chan, page; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - /* FIXME: locking */ - chan = sdata->local->phy->current_channel; - page = sdata->local->phy->current_page; - - if (chan == MAC802154_CHAN_NONE) /* not initialized */ - return NETDEV_TX_OK; - - if (WARN_ON(page >= WPAN_NUM_PAGES) || - WARN_ON(chan >= WPAN_NUM_CHANNELS)) - return NETDEV_TX_OK; - - skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - return mac802154_tx(sdata->local, skb, page, chan); -} - - void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 2c40d9bb8387..2eb06c2cf96d 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -77,8 +77,8 @@ static void mac802154_xmit_worker(struct work_struct *work) kfree(xw); } -netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, - u8 page, u8 chan) +static netdev_tx_t mac802154_tx(struct ieee802154_local *local, + struct sk_buff *skb, u8 page, u8 chan) { struct xmit_work *work; struct ieee802154_sub_if_data *sdata; @@ -127,3 +127,58 @@ netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, kfree_skb(skb); return NETDEV_TX_OK; } + +netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + u8 chan, page; + + /* FIXME: locking */ + chan = sdata->local->phy->current_channel; + page = sdata->local->phy->current_page; + + if (chan == MAC802154_CHAN_NONE) /* not initialized */ + return NETDEV_TX_OK; + + if (WARN_ON(page >= WPAN_NUM_PAGES) || + WARN_ON(chan >= WPAN_NUM_CHANNELS)) + return NETDEV_TX_OK; + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(sdata->local, skb, page, chan); +} + +netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + u8 chan, page; + int rc; + + spin_lock_bh(&sdata->mib_lock); + chan = sdata->chan; + page = sdata->page; + spin_unlock_bh(&sdata->mib_lock); + + if (chan == MAC802154_CHAN_NONE || + page >= WPAN_NUM_PAGES || + chan >= WPAN_NUM_CHANNELS) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + + rc = mac802154_llsec_encrypt(&sdata->sec, skb); + if (rc) { + pr_warn("encryption failed: %i\n", rc); + kfree_skb(skb); + return NETDEV_TX_OK; + } + + skb->skb_iif = dev->ifindex; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + return mac802154_tx(sdata->local, skb, page, chan); +} -- GitLab From fe24371d6645b766c59ec664c59d0a9c310ad455 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:02 +0100 Subject: [PATCH 1289/9457] mac802154: tx: remove kmalloc in xmit hotpath This patch removes the kmalloc allocation for workqueue data. This patch replaces the kmalloc and uses the control block of skb. The control block has enough space and isn't use by any other layer in this case. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 56 ++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 2eb06c2cf96d..513e760a8557 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -30,7 +30,7 @@ /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct xmit_work { +struct wpan_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; @@ -38,50 +38,54 @@ struct xmit_work { u8 page; }; +static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct wpan_xmit_cb)); + + return (struct wpan_xmit_cb *)skb->cb; +} + static void mac802154_xmit_worker(struct work_struct *work) { - struct xmit_work *xw = container_of(work, struct xmit_work, work); + struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_sub_if_data *sdata; int res; - mutex_lock(&xw->local->phy->pib_lock); - if (xw->local->phy->current_channel != xw->chan || - xw->local->phy->current_page != xw->page) { - res = xw->local->ops->set_channel(&xw->local->hw, - xw->page, - xw->chan); + mutex_lock(&cb->local->phy->pib_lock); + if (cb->local->phy->current_channel != cb->chan || + cb->local->phy->current_page != cb->page) { + res = cb->local->ops->set_channel(&cb->local->hw, cb->page, + cb->chan); if (res) { pr_debug("set_channel failed\n"); goto out; } - xw->local->phy->current_channel = xw->chan; - xw->local->phy->current_page = xw->page; + cb->local->phy->current_channel = cb->chan; + cb->local->phy->current_page = cb->page; } - res = xw->local->ops->xmit(&xw->local->hw, xw->skb); + res = cb->local->ops->xmit(&cb->local->hw, cb->skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&xw->local->phy->pib_lock); + mutex_unlock(&cb->local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &xw->local->interfaces, list) + list_for_each_entry_rcu(sdata, &cb->local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); - dev_kfree_skb(xw->skb); - - kfree(xw); + dev_kfree_skb(cb->skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb, u8 page, u8 chan) { - struct xmit_work *work; struct ieee802154_sub_if_data *sdata; + struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); if (!(local->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); @@ -101,25 +105,19 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, if (skb_cow_head(skb, local->hw.extra_tx_headroom)) goto err_tx; - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) { - kfree_skb(skb); - return NETDEV_TX_BUSY; - } - /* Stop the netif queue on each sub_if_data object. */ rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_stop_queue(sdata->dev); rcu_read_unlock(); - INIT_WORK(&work->work, mac802154_xmit_worker); - work->skb = skb; - work->local = local; - work->page = page; - work->chan = chan; + INIT_WORK(&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; + cb->page = page; + cb->chan = chan; - queue_work(local->workqueue, &work->work); + queue_work(local->workqueue, &cb->work); return NETDEV_TX_OK; -- GitLab From e89e45f22a382d14d5e2362cd4f4d12d77ee4935 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:03 +0100 Subject: [PATCH 1290/9457] mac802154: tx: squash multiple dereferencing This patch introduce some new stack variables to avoid multiple dereferencing inside the xmit worker function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 513e760a8557..d0ceb46134d9 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -48,37 +48,38 @@ static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) static void mac802154_xmit_worker(struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); + struct ieee802154_local *local = cb->local; struct ieee802154_sub_if_data *sdata; + struct sk_buff *skb = cb->skb; int res; - mutex_lock(&cb->local->phy->pib_lock); - if (cb->local->phy->current_channel != cb->chan || - cb->local->phy->current_page != cb->page) { - res = cb->local->ops->set_channel(&cb->local->hw, cb->page, - cb->chan); + mutex_lock(&local->phy->pib_lock); + if (local->phy->current_channel != cb->chan || + local->phy->current_page != cb->page) { + res = local->ops->set_channel(&local->hw, cb->page, cb->chan); if (res) { pr_debug("set_channel failed\n"); goto out; } - cb->local->phy->current_channel = cb->chan; - cb->local->phy->current_page = cb->page; + local->phy->current_channel = cb->chan; + local->phy->current_page = cb->page; } - res = cb->local->ops->xmit(&cb->local->hw, cb->skb); + res = local->ops->xmit(&local->hw, skb); if (res) pr_debug("transmission failed\n"); out: - mutex_unlock(&cb->local->phy->pib_lock); + mutex_unlock(&local->phy->pib_lock); /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &cb->local->interfaces, list) + list_for_each_entry_rcu(sdata, &local->interfaces, list) netif_wake_queue(sdata->dev); rcu_read_unlock(); - dev_kfree_skb(cb->skb); + dev_kfree_skb(skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, -- GitLab From dc67c6b30f36d57b70b70547a30e7a8432540c6f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:04 +0100 Subject: [PATCH 1291/9457] mac802154: tx: remove xmit channel context switch This patch removes the channel hopping feature before xmit. There are several issues to provide a real channel hopping (timing requirements, etc...). We don't have any known kernelspace protocol which really use this feature. And I don't know an real user of this feature. We simply drop this feature now. This patch removes also the hold of pib lock which isn't needed by any real driver xmit callback implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 3 +-- net/mac802154/tx.c | 58 +++-------------------------------------- 2 files changed, 5 insertions(+), 56 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index b07d431c0b19..ba8ddff70bb6 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -113,8 +113,7 @@ struct ieee802154_hw { * skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration. - * This function should return zero or negative errno. Called with - * pib_lock held. + * This function should return zero or negative errno. * * ed: Handler that 802.15.4 module calls for Energy Detection. * This function should place the value for detected energy diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d0ceb46134d9..be8deae19386 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -34,8 +34,6 @@ struct wpan_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; - u8 chan; - u8 page; }; static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) @@ -53,26 +51,10 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; - mutex_lock(&local->phy->pib_lock); - if (local->phy->current_channel != cb->chan || - local->phy->current_page != cb->page) { - res = local->ops->set_channel(&local->hw, cb->page, cb->chan); - if (res) { - pr_debug("set_channel failed\n"); - goto out; - } - - local->phy->current_channel = cb->chan; - local->phy->current_page = cb->page; - } - res = local->ops->xmit(&local->hw, skb); if (res) pr_debug("transmission failed\n"); -out: - mutex_unlock(&local->phy->pib_lock); - /* Restart the netif queue on each sub_if_data object. */ rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) @@ -82,17 +64,12 @@ static void mac802154_xmit_worker(struct work_struct *work) dev_kfree_skb(skb); } -static netdev_tx_t mac802154_tx(struct ieee802154_local *local, - struct sk_buff *skb, u8 page, u8 chan) +static netdev_tx_t +mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct ieee802154_sub_if_data *sdata; struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); - if (!(local->phy->channels_supported[page] & (1 << chan))) { - WARN_ON(1); - goto err_tx; - } - mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { @@ -115,8 +92,6 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; cb->local = local; - cb->page = page; - cb->chan = chan; queue_work(local->workqueue, &cb->work); @@ -130,44 +105,19 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - u8 chan, page; - - /* FIXME: locking */ - chan = sdata->local->phy->current_channel; - page = sdata->local->phy->current_page; - - if (chan == MAC802154_CHAN_NONE) /* not initialized */ - return NETDEV_TX_OK; - - if (WARN_ON(page >= WPAN_NUM_PAGES) || - WARN_ON(chan >= WPAN_NUM_CHANNELS)) - return NETDEV_TX_OK; skb->skb_iif = dev->ifindex; dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->local, skb, page, chan); + return mac802154_tx(sdata->local, skb); } netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - u8 chan, page; int rc; - spin_lock_bh(&sdata->mib_lock); - chan = sdata->chan; - page = sdata->page; - spin_unlock_bh(&sdata->mib_lock); - - if (chan == MAC802154_CHAN_NONE || - page >= WPAN_NUM_PAGES || - chan >= WPAN_NUM_CHANNELS) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { pr_warn("encryption failed: %i\n", rc); @@ -179,5 +129,5 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - return mac802154_tx(sdata->local, skb, page, chan); + return mac802154_tx(sdata->local, skb); } -- GitLab From c20851035126cc1d97c337083f98b797eed155a3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:05 +0100 Subject: [PATCH 1292/9457] mac802154: add netdev qeue helpers This patch adds a new file net/mac802154/util.c which contains utility functions for drivers, etc. This file contains functions to start and stop queues for all virtual interfaces, this is useful for asynchronous handling by driver level. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 4 +++ net/mac802154/Makefile | 2 +- net/mac802154/util.c | 55 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 net/mac802154/util.c diff --git a/include/net/mac802154.h b/include/net/mac802154.h index ba8ddff70bb6..29af5c346ebf 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -190,4 +190,8 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); +void ieee802154_wake_queue(struct ieee802154_hw *hw); +void ieee802154_stop_queue(struct ieee802154_hw *hw); +void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb); + #endif /* NET_MAC802154_H */ diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 203f42d511af..e68debaf2a59 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o iface.o llsec.o + monitor.o iface.o llsec.o util.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/util.c b/net/mac802154/util.c new file mode 100644 index 000000000000..117e4eff4ca8 --- /dev/null +++ b/net/mac802154/util.c @@ -0,0 +1,55 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/mac80211/util.c + */ + +#include "ieee802154_i.h" + +void ieee802154_wake_queue(struct ieee802154_hw *hw) +{ + struct ieee802154_local *local = hw_to_local(hw); + struct ieee802154_sub_if_data *sdata; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + netif_wake_queue(sdata->dev); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee802154_wake_queue); + +void ieee802154_stop_queue(struct ieee802154_hw *hw) +{ + struct ieee802154_local *local = hw_to_local(hw); + struct ieee802154_sub_if_data *sdata; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + netif_stop_queue(sdata->dev); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee802154_stop_queue); + +void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb) +{ + ieee802154_wake_queue(hw); + consume_skb(skb); +} +EXPORT_SYMBOL(ieee802154_xmit_complete); -- GitLab From 18d60a0d49ef3eb2d31f65cf5b652702d9c6e710 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:06 +0100 Subject: [PATCH 1293/9457] mac802154: tx: use queue helpers in xmit worker This patch uses the queue utility helpers inside the xmit worker of mac802154 subsystem. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index be8deae19386..8e2f429a4546 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -47,7 +47,6 @@ static void mac802154_xmit_worker(struct work_struct *work) { struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_local *local = cb->local; - struct ieee802154_sub_if_data *sdata; struct sk_buff *skb = cb->skb; int res; @@ -56,18 +55,12 @@ static void mac802154_xmit_worker(struct work_struct *work) pr_debug("transmission failed\n"); /* Restart the netif queue on each sub_if_data object. */ - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_wake_queue(sdata->dev); - rcu_read_unlock(); - - dev_kfree_skb(skb); + ieee802154_xmit_complete(&local->hw, skb); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct ieee802154_sub_if_data *sdata; struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); mac802154_monitors_rx(local, skb); @@ -84,10 +77,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) goto err_tx; /* Stop the netif queue on each sub_if_data object. */ - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_stop_queue(sdata->dev); - rcu_read_unlock(); + ieee802154_stop_queue(&local->hw); INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; -- GitLab From cdb66beaa0da7d326069b10bef090645d61d813f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:07 +0100 Subject: [PATCH 1294/9457] mac802154: tx: fix error handling while xmit In case of an error we should call kfree_skb instead of consume_skb which is called by ieee802154_xmit_complete function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8e2f429a4546..23139cae0764 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -51,11 +51,15 @@ static void mac802154_xmit_worker(struct work_struct *work) int res; res = local->ops->xmit(&local->hw, skb); - if (res) + if (res) { pr_debug("transmission failed\n"); - - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_xmit_complete(&local->hw, skb); + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_wake_queue(&local->hw); + kfree_skb(skb); + } else { + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_xmit_complete(&local->hw, skb); + } } static netdev_tx_t -- GitLab From ed0a5dce0c29f30ee53a87793206156cf38ae70d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:08 +0100 Subject: [PATCH 1295/9457] mac802154: tx: add support for xmit_async callback This patch renames the existsing xmit callback to xmit_sync and introduces an asynchronous xmit_async function. If ieee802154_ops doesn't provide the xmit_async callback, then we have a fallback to the xmit_sync callback. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 17 ++++++++++++++--- net/mac802154/main.c | 4 ++-- net/mac802154/tx.c | 20 +++++++++++++++----- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b0d68d7061c1..06a3e9013d60 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1237,7 +1237,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) static struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, - .xmit = at86rf230_xmit, + .xmit_sync = at86rf230_xmit, .ed = at86rf230_ed, .set_channel = at86rf230_channel, .start = at86rf230_start, diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index b827e04d481b..f6f07f4eb0ec 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -635,7 +635,7 @@ static struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, .stop = cc2520_stop, - .xmit = cc2520_tx, + .xmit_sync = cc2520_tx, .ed = cc2520_ed, .set_channel = cc2520_set_channel, .set_hw_addr_filt = cc2520_filter, diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 51e3c589d2e4..db0703f0fa41 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -131,7 +131,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) { static struct ieee802154_ops fakelb_ops = { .owner = THIS_MODULE, - .xmit = fakelb_hw_xmit, + .xmit_sync = fakelb_hw_xmit, .ed = fakelb_hw_ed, .set_channel = fakelb_hw_channel, .start = fakelb_hw_start, diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 2e267c5c44da..3d775afa217f 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -581,7 +581,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) static struct ieee802154_ops mrf24j40_ops = { .owner = THIS_MODULE, - .xmit = mrf24j40_tx, + .xmit_sync = mrf24j40_tx, .ed = mrf24j40_ed, .start = mrf24j40_start, .stop = mrf24j40_stop, diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 29af5c346ebf..57b120281afc 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -109,7 +109,16 @@ struct ieee802154_hw { * stop: Handler that 802.15.4 module calls for device cleanup. * This function is called after the last interface is removed. * - * xmit: Handler that 802.15.4 module calls for each transmitted frame. + * xmit_sync: + * Handler that 802.15.4 module calls for each transmitted frame. + * skb cntains the buffer starting from the IEEE 802.15.4 header. + * The low-level driver should send the frame based on available + * configuration. This is called by a workqueue and useful for + * synchronous 802.15.4 drivers. + * This function should return zero or negative errno. + * + * xmit_async: + * Handler that 802.15.4 module calls for each transmitted frame. * skb cntains the buffer starting from the IEEE 802.15.4 header. * The low-level driver should send the frame based on available * configuration. @@ -160,8 +169,10 @@ struct ieee802154_ops { struct module *owner; int (*start)(struct ieee802154_hw *hw); void (*stop)(struct ieee802154_hw *hw); - int (*xmit)(struct ieee802154_hw *hw, - struct sk_buff *skb); + int (*xmit_sync)(struct ieee802154_hw *hw, + struct sk_buff *skb); + int (*xmit_async)(struct ieee802154_hw *hw, + struct sk_buff *skb); int (*ed)(struct ieee802154_hw *hw, u8 *level); int (*set_channel)(struct ieee802154_hw *hw, int page, diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 0e9a6a203f7a..3c0a824d24ac 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -229,8 +229,8 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) struct ieee802154_local *local; size_t priv_size; - if (!ops || !ops->xmit || !ops->ed || !ops->start || - !ops->stop || !ops->set_channel) { + if (!ops || !(ops->xmit_async || ops->xmit_sync) || !ops->ed || + !ops->start || !ops->stop || !ops->set_channel) { pr_err("undefined IEEE802.15.4 device operations\n"); return NULL; } diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 23139cae0764..1a4f6d91ab8c 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -50,7 +50,7 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; - res = local->ops->xmit(&local->hw, skb); + res = local->ops->xmit_sync(&local->hw, skb); if (res) { pr_debug("transmission failed\n"); /* Restart the netif queue on each sub_if_data object. */ @@ -66,6 +66,7 @@ static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + int ret; mac802154_monitors_rx(local, skb); @@ -83,11 +84,20 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) /* Stop the netif queue on each sub_if_data object. */ ieee802154_stop_queue(&local->hw); - INIT_WORK(&cb->work, mac802154_xmit_worker); - cb->skb = skb; - cb->local = local; + /* async is priority, otherwise sync is fallback */ + if (local->ops->xmit_async) { + ret = local->ops->xmit_async(&local->hw, skb); + if (ret) { + ieee802154_wake_queue(&local->hw); + goto err_tx; + } + } else { + INIT_WORK(&cb->work, mac802154_xmit_worker); + cb->skb = skb; + cb->local = local; - queue_work(local->workqueue, &cb->work); + queue_work(local->workqueue, &cb->work); + } return NETDEV_TX_OK; -- GitLab From 6001d5223dd458e4f0063df2a24762eb2a619b17 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:09 +0100 Subject: [PATCH 1296/9457] mac802154: tx: don't allow if down while sync tx This patch holds rtnl lock while sync xmit inside of workqueue. Otherwise we could down the interface while worker xmit handling. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 1a4f6d91ab8c..44390419af86 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -50,16 +51,28 @@ static void mac802154_xmit_worker(struct work_struct *work) struct sk_buff *skb = cb->skb; int res; + rtnl_lock(); + + /* check if ifdown occurred while schedule */ + if (!netif_running(skb->dev)) + goto err_tx; + res = local->ops->xmit_sync(&local->hw, skb); - if (res) { - pr_debug("transmission failed\n"); - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_wake_queue(&local->hw); - kfree_skb(skb); - } else { - /* Restart the netif queue on each sub_if_data object. */ - ieee802154_xmit_complete(&local->hw, skb); - } + if (res) + goto err_tx; + + ieee802154_xmit_complete(&local->hw, skb); + + rtnl_unlock(); + + return; + +err_tx: + /* Restart the netif queue on each sub_if_data object. */ + ieee802154_wake_queue(&local->hw); + rtnl_unlock(); + kfree_skb(skb); + pr_debug("transmission failed\n"); } static netdev_tx_t -- GitLab From cfa626cb3725101fd1853c2cab857aabfd78274b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:10 +0100 Subject: [PATCH 1297/9457] mac802154: tx: use netdev print helpers This patch replace the pr_foo printout function to netdev_foo printout function. Inside the xmit handling, the interface is already known. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 44390419af86..d39c7d946bc3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -72,7 +72,7 @@ static void mac802154_xmit_worker(struct work_struct *work) ieee802154_wake_queue(&local->hw); rtnl_unlock(); kfree_skb(skb); - pr_debug("transmission failed\n"); + netdev_dbg(skb->dev, "transmission failed\n"); } static netdev_tx_t @@ -137,7 +137,7 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) rc = mac802154_llsec_encrypt(&sdata->sec, skb); if (rc) { - pr_warn("encryption failed: %i\n", rc); + netdev_warn(dev, "encryption failed: %i\n", rc); kfree_skb(skb); return NETDEV_TX_OK; } -- GitLab From b7eec52bcb7ab93a8cce0f718f42fa17d6d91745 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:11 +0100 Subject: [PATCH 1298/9457] mac802154: tx: cleanup crc calculation Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index d39c7d946bc3..70fd22632cf6 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -84,11 +84,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data = skb_put(skb, 2); + __le16 crc = cpu_to_le16(crc_ccitt(0, skb->data, skb->len)); - data[0] = crc & 0xff; - data[1] = crc >> 8; + memcpy(skb_put(skb, 2), &crc, 2); } if (skb_cow_head(skb, local->hw.extra_tx_headroom)) -- GitLab From 409c3b0c5f030e36e9d6ca747dc3059eadde0cad Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:12 +0100 Subject: [PATCH 1299/9457] mac802154: tx: move stats tx increment This patch moves the stats increment of successful transmitted packets in the right place when the skb was really successful transmitted. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 70fd22632cf6..fe105d42ef83 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -49,12 +49,13 @@ static void mac802154_xmit_worker(struct work_struct *work) struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); struct ieee802154_local *local = cb->local; struct sk_buff *skb = cb->skb; + struct net_device *dev = skb->dev; int res; rtnl_lock(); /* check if ifdown occurred while schedule */ - if (!netif_running(skb->dev)) + if (!netif_running(dev)) goto err_tx; res = local->ops->xmit_sync(&local->hw, skb); @@ -63,6 +64,9 @@ static void mac802154_xmit_worker(struct work_struct *work) ieee802154_xmit_complete(&local->hw, skb); + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + rtnl_unlock(); return; @@ -72,13 +76,14 @@ static void mac802154_xmit_worker(struct work_struct *work) ieee802154_wake_queue(&local->hw); rtnl_unlock(); kfree_skb(skb); - netdev_dbg(skb->dev, "transmission failed\n"); + netdev_dbg(dev, "transmission failed\n"); } static netdev_tx_t mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + struct net_device *dev = skb->dev; int ret; mac802154_monitors_rx(local, skb); @@ -102,6 +107,9 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) ieee802154_wake_queue(&local->hw); goto err_tx; } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; } else { INIT_WORK(&cb->work, mac802154_xmit_worker); cb->skb = skb; @@ -122,8 +130,6 @@ netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; return mac802154_tx(sdata->local, skb); } @@ -141,8 +147,6 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) } skb->skb_iif = dev->ifindex; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; return mac802154_tx(sdata->local, skb); } -- GitLab From e5e584fcc26b6b2225855b6fdba64d90dd8e2ea6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:13 +0100 Subject: [PATCH 1300/9457] mac802154: tx: change naming convention This patch changes the naming convention of the tx functions like mac80211. Just with an 802154 instead 80211 inside the name. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 6 ++++-- net/mac802154/iface.c | 2 +- net/mac802154/monitor.c | 2 +- net/mac802154/tx.c | 30 +++++++++++++++++------------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index a9a9d8e15278..ef29c10eeb66 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -121,11 +121,13 @@ int mac802154_slave_close(struct net_device *dev); void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); -netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev); +netdev_tx_t +ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); -netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev); +netdev_tx_t +ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); /* MIB callbacks */ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index f14e4365c4c7..be45dc9257b3 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -315,7 +315,7 @@ static struct header_ops mac802154_header_ops = { static const struct net_device_ops mac802154_wpan_ops = { .ndo_open = mac802154_wpan_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_wpan_xmit, + .ndo_start_xmit = ieee802154_subif_start_xmit, .ndo_do_ioctl = mac802154_wpan_ioctl, .ndo_set_mac_address = mac802154_wpan_mac_addr, }; diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index cb9600bcca51..575832231fd6 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -58,7 +58,7 @@ void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) static const struct net_device_ops mac802154_monitor_ops = { .ndo_open = mac802154_slave_open, .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = mac802154_monitor_xmit, + .ndo_start_xmit = ieee802154_monitor_start_xmit, }; void mac802154_monitor_setup(struct net_device *dev) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fe105d42ef83..74882c72b6c3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -31,22 +31,24 @@ /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. */ -struct wpan_xmit_cb { +struct ieee802154_xmit_cb { struct sk_buff *skb; struct work_struct work; struct ieee802154_local *local; }; -static inline struct wpan_xmit_cb *wpan_xmit_cb(const struct sk_buff *skb) +static inline struct ieee802154_xmit_cb * +ieee802154_xmit_cb(const struct sk_buff *skb) { - BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct wpan_xmit_cb)); + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ieee802154_xmit_cb)); - return (struct wpan_xmit_cb *)skb->cb; + return (struct ieee802154_xmit_cb *)skb->cb; } -static void mac802154_xmit_worker(struct work_struct *work) +static void ieee802154_xmit_worker(struct work_struct *work) { - struct wpan_xmit_cb *cb = container_of(work, struct wpan_xmit_cb, work); + struct ieee802154_xmit_cb *cb = + container_of(work, struct ieee802154_xmit_cb, work); struct ieee802154_local *local = cb->local; struct sk_buff *skb = cb->skb; struct net_device *dev = skb->dev; @@ -80,9 +82,9 @@ static void mac802154_xmit_worker(struct work_struct *work) } static netdev_tx_t -mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) +ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct wpan_xmit_cb *cb = wpan_xmit_cb(skb); + struct ieee802154_xmit_cb *cb = ieee802154_xmit_cb(skb); struct net_device *dev = skb->dev; int ret; @@ -111,7 +113,7 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; } else { - INIT_WORK(&cb->work, mac802154_xmit_worker); + INIT_WORK(&cb->work, ieee802154_xmit_worker); cb->skb = skb; cb->local = local; @@ -125,16 +127,18 @@ mac802154_tx(struct ieee802154_local *local, struct sk_buff *skb) return NETDEV_TX_OK; } -netdev_tx_t mac802154_monitor_xmit(struct sk_buff *skb, struct net_device *dev) +netdev_tx_t +ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); skb->skb_iif = dev->ifindex; - return mac802154_tx(sdata->local, skb); + return ieee802154_tx(sdata->local, skb); } -netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) +netdev_tx_t +ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); int rc; @@ -148,5 +152,5 @@ netdev_tx_t mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev) skb->skb_iif = dev->ifindex; - return mac802154_tx(sdata->local, skb); + return ieee802154_tx(sdata->local, skb); } -- GitLab From 1e7283a271afcd45713f2813c97de300565a0dd7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:14 +0100 Subject: [PATCH 1301/9457] mac802154: tx: add comment at sync xmit callback This patch adds a warning that xmit_sync callback is deprecated and should be removed soon. The 802.15.4 subsystem will not accept synced drivers anymore. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 57b120281afc..942dd53d4658 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -117,6 +117,10 @@ struct ieee802154_hw { * synchronous 802.15.4 drivers. * This function should return zero or negative errno. * + * WARNING: + * This will be deprecated soon. We don't accept synced xmit callbacks + * drivers anymore. + * * xmit_async: * Handler that 802.15.4 module calls for each transmitted frame. * skb cntains the buffer starting from the IEEE 802.15.4 header. -- GitLab From 955aee8b5c69594b9fb38a4f65e77db343b43a38 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 09:37:15 +0100 Subject: [PATCH 1302/9457] at86rf230: asynchronous xmit handling This patch converts the sync xmit handling into an async xmit handling. The driver was already prepared for this step, all other drivers need more work to implement a xmit_async function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 42 ++++++++++++------------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 06a3e9013d60..0669783aa3b9 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -91,7 +91,6 @@ struct at86rf230_local { bool is_tx; /* spinlock for is_tx protection */ spinlock_t lock; - struct completion tx_complete; struct sk_buff *tx_skb; struct at86rf230_state_change tx; }; @@ -452,6 +451,7 @@ at86rf230_async_error_recover(void *context) struct at86rf230_local *lp = ctx->lp; at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL, false); + ieee802154_wake_queue(lp->hw); } static void @@ -715,9 +715,23 @@ at86rf230_tx_complete(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; + struct sk_buff *skb = lp->tx_skb; enable_irq(lp->spi->irq); - complete(&lp->tx_complete); + + if (lp->max_frame_retries <= 0) { + /* Interfame spacing time, which is phy depend. + * TODO + * Move this handling in MAC 802.15.4 layer. + * This is currently a workaround to avoid fragmenation issues. + */ + if (skb->len > 18) + udelay(lp->data->t_lifs); + else + udelay(lp->data->t_sifs); + } + + ieee802154_xmit_complete(lp->hw, skb); } static void @@ -975,7 +989,6 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) struct at86rf230_state_change *ctx = &lp->tx; void (*tx_complete)(void *context) = at86rf230_write_frame; - int rc; lp->tx_skb = skb; @@ -988,26 +1001,6 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) at86rf230_async_state_change(lp, ctx, STATE_TX_ON, tx_complete, false); - rc = wait_for_completion_interruptible_timeout(&lp->tx_complete, - msecs_to_jiffies(lp->data->t_tx_timeout)); - if (!rc) { - at86rf230_async_error(lp, ctx, -ETIMEDOUT); - return -ETIMEDOUT; - } - - if (lp->max_frame_retries > 0) - return 0; - - /* Interfame spacing time, which is phy depend. - * TODO - * Move this handling in MAC 802.15.4 layer. - * This is currently a workaround to avoid fragmenation issues. - */ - if (skb->len > 18) - usleep_range(lp->data->t_lifs, lp->data->t_lifs + 10); - else - usleep_range(lp->data->t_sifs, lp->data->t_sifs + 10); - return 0; } @@ -1237,7 +1230,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) static struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, - .xmit_sync = at86rf230_xmit, + .xmit_async = at86rf230_xmit, .ed = at86rf230_ed, .set_channel = at86rf230_channel, .start = at86rf230_start, @@ -1541,7 +1534,6 @@ static int at86rf230_probe(struct spi_device *spi) goto free_dev; spin_lock_init(&lp->lock); - init_completion(&lp->tx_complete); init_completion(&lp->state_complete); spi_set_drvdata(spi, lp); -- GitLab From f81f466ca588a5bd868008154050305481f241d4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 26 Oct 2014 18:15:34 +0100 Subject: [PATCH 1303/9457] mac802154: tx: make worker information static This patch moves the worker information struct out of skb control block. Instead control block we declare it static inside of tx.c file. We can do that, because the worker can't be used twice at the same time. It's protected by stop and wake netdev queue. This patch fix an issue that the "struct ieee802154_xmit_cb" doesn't fit into the skb control block on some kernel configuartion reported by kbuild test robot. It was introduced by commit fe24371d6645b766c59ec664c59d0a9c310ad455 ("mac802154: tx: remove kmalloc in xmit hotpath"). Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 74882c72b6c3..fe2e17e6fee3 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -37,13 +37,7 @@ struct ieee802154_xmit_cb { struct ieee802154_local *local; }; -static inline struct ieee802154_xmit_cb * -ieee802154_xmit_cb(const struct sk_buff *skb) -{ - BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ieee802154_xmit_cb)); - - return (struct ieee802154_xmit_cb *)skb->cb; -} +static struct ieee802154_xmit_cb ieee802154_xmit_cb; static void ieee802154_xmit_worker(struct work_struct *work) { @@ -84,7 +78,6 @@ static void ieee802154_xmit_worker(struct work_struct *work) static netdev_tx_t ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) { - struct ieee802154_xmit_cb *cb = ieee802154_xmit_cb(skb); struct net_device *dev = skb->dev; int ret; @@ -113,11 +106,11 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; } else { - INIT_WORK(&cb->work, ieee802154_xmit_worker); - cb->skb = skb; - cb->local = local; + INIT_WORK(&ieee802154_xmit_cb.work, ieee802154_xmit_worker); + ieee802154_xmit_cb.skb = skb; + ieee802154_xmit_cb.local = local; - queue_work(local->workqueue, &cb->work); + queue_work(local->workqueue, &ieee802154_xmit_cb.work); } return NETDEV_TX_OK; -- GitLab From 1f3c2eba1e2d866ef99bb9b10ade4096e3d7607c Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 22 Oct 2014 11:17:06 +0100 Subject: [PATCH 1304/9457] xen-netfront: always keep the Rx ring full of requests A full Rx ring only requires 1 MiB of memory. This is not enough memory that it is useful to dynamically scale the number of Rx requests in the ring based on traffic rates, because: a) Even the full 1 MiB is a tiny fraction of a typically modern Linux VM (for example, the AWS micro instance still has 1 GiB of memory). b) Netfront would have used up to 1 MiB already even with moderate data rates (there was no adjustment of target based on memory pressure). c) Small VMs are going to typically have one VCPU and hence only one queue. Keeping the ring full of Rx requests handles bursty traffic better than trying to converge on an optimal number of requests to keep filled. On a 4 core host, an iperf -P 64 -t 60 run from dom0 to a 4 VCPU guest improved from 5.1 Gbit/s to 5.6 Gbit/s. Gains with more bursty traffic are expected to be higher. Signed-off-by: David Vrabel Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 253 +++++++++---------------------------- 1 file changed, 62 insertions(+), 191 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index cca871346a0f..88a70f5ed594 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -77,7 +77,9 @@ struct netfront_cb { #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) -#define TX_MAX_TARGET min_t(int, NET_TX_RING_SIZE, 256) + +/* Minimum number of Rx slots (includes slot for GSO metadata). */ +#define NET_RX_SLOTS_MIN (XEN_NETIF_NR_SLOTS_MIN + 1) /* Queue name is interface name with "-qNNN" appended */ #define QUEUE_NAME_SIZE (IFNAMSIZ + 6) @@ -137,13 +139,6 @@ struct netfront_queue { struct xen_netif_rx_front_ring rx; int rx_ring_ref; - /* Receive-ring batched refills. */ -#define RX_MIN_TARGET 8 -#define RX_DFL_MIN_TARGET 64 -#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) - unsigned rx_min_target, rx_max_target, rx_target; - struct sk_buff_head rx_batch; - struct timer_list rx_refill_timer; struct sk_buff *rx_skbs[NET_RX_RING_SIZE]; @@ -251,7 +246,7 @@ static void rx_refill_timeout(unsigned long data) static int netfront_tx_slot_available(struct netfront_queue *queue) { return (queue->tx.req_prod_pvt - queue->tx.rsp_cons) < - (TX_MAX_TARGET - MAX_SKB_FRAGS - 2); + (NET_TX_RING_SIZE - MAX_SKB_FRAGS - 2); } static void xennet_maybe_wake_tx(struct netfront_queue *queue) @@ -265,77 +260,55 @@ static void xennet_maybe_wake_tx(struct netfront_queue *queue) netif_tx_wake_queue(netdev_get_tx_queue(dev, queue->id)); } -static void xennet_alloc_rx_buffers(struct netfront_queue *queue) + +static struct sk_buff *xennet_alloc_one_rx_buffer(struct netfront_queue *queue) { - unsigned short id; struct sk_buff *skb; struct page *page; - int i, batch_target, notify; - RING_IDX req_prod = queue->rx.req_prod_pvt; - grant_ref_t ref; - unsigned long pfn; - void *vaddr; - struct xen_netif_rx_request *req; - if (unlikely(!netif_carrier_ok(queue->info->netdev))) - return; + skb = __netdev_alloc_skb(queue->info->netdev, + RX_COPY_THRESHOLD + NET_IP_ALIGN, + GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(!skb)) + return NULL; - /* - * Allocate skbuffs greedily, even though we batch updates to the - * receive ring. This creates a less bursty demand on the memory - * allocator, so should reduce the chance of failed allocation requests - * both for ourself and for other kernel subsystems. - */ - batch_target = queue->rx_target - (req_prod - queue->rx.rsp_cons); - for (i = skb_queue_len(&queue->rx_batch); i < batch_target; i++) { - skb = __netdev_alloc_skb(queue->info->netdev, - RX_COPY_THRESHOLD + NET_IP_ALIGN, - GFP_ATOMIC | __GFP_NOWARN); - if (unlikely(!skb)) - goto no_skb; - - /* Align ip header to a 16 bytes boundary */ - skb_reserve(skb, NET_IP_ALIGN); - - page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); - if (!page) { - kfree_skb(skb); -no_skb: - /* Could not allocate any skbuffs. Try again later. */ - mod_timer(&queue->rx_refill_timer, - jiffies + (HZ/10)); - - /* Any skbuffs queued for refill? Force them out. */ - if (i != 0) - goto refill; - break; - } - - skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE); - __skb_queue_tail(&queue->rx_batch, skb); + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + if (!page) { + kfree_skb(skb); + return NULL; } + skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE); + + /* Align ip header to a 16 bytes boundary */ + skb_reserve(skb, NET_IP_ALIGN); + skb->dev = queue->info->netdev; + + return skb; +} + - /* Is the batch large enough to be worthwhile? */ - if (i < (queue->rx_target/2)) { - if (req_prod > queue->rx.sring->req_prod) - goto push; +static void xennet_alloc_rx_buffers(struct netfront_queue *queue) +{ + RING_IDX req_prod = queue->rx.req_prod_pvt; + int notify; + + if (unlikely(!netif_carrier_ok(queue->info->netdev))) return; - } - /* Adjust our fill target if we risked running out of buffers. */ - if (((req_prod - queue->rx.sring->rsp_prod) < (queue->rx_target / 4)) && - ((queue->rx_target *= 2) > queue->rx_max_target)) - queue->rx_target = queue->rx_max_target; + for (req_prod = queue->rx.req_prod_pvt; + req_prod - queue->rx.rsp_cons < NET_RX_RING_SIZE; + req_prod++) { + struct sk_buff *skb; + unsigned short id; + grant_ref_t ref; + unsigned long pfn; + struct xen_netif_rx_request *req; - refill: - for (i = 0; ; i++) { - skb = __skb_dequeue(&queue->rx_batch); - if (skb == NULL) + skb = xennet_alloc_one_rx_buffer(queue); + if (!skb) break; - skb->dev = queue->info->netdev; - - id = xennet_rxidx(req_prod + i); + id = xennet_rxidx(req_prod); BUG_ON(queue->rx_skbs[id]); queue->rx_skbs[id] = skb; @@ -345,9 +318,8 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue) queue->grant_rx_ref[id] = ref; pfn = page_to_pfn(skb_frag_page(&skb_shinfo(skb)->frags[0])); - vaddr = page_address(skb_frag_page(&skb_shinfo(skb)->frags[0])); - req = RING_GET_REQUEST(&queue->rx, req_prod + i); + req = RING_GET_REQUEST(&queue->rx, req_prod); gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id, pfn_to_mfn(pfn), @@ -357,11 +329,16 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue) req->gref = ref; } + queue->rx.req_prod_pvt = req_prod; + + /* Not enough requests? Try again later. */ + if (req_prod - queue->rx.rsp_cons < NET_RX_SLOTS_MIN) { + mod_timer(&queue->rx_refill_timer, jiffies + (HZ/10)); + return; + } + wmb(); /* barrier so backend seens requests */ - /* Above is a suitable barrier to ensure backend will see requests. */ - queue->rx.req_prod_pvt = req_prod + i; - push: RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->rx, notify); if (notify) notify_remote_via_irq(queue->rx_irq); @@ -1070,13 +1047,6 @@ static int xennet_poll(struct napi_struct *napi, int budget) work_done -= handle_incoming_queue(queue, &rxq); - /* If we get a callback with very few responses, reduce fill target. */ - /* NB. Note exponential increase, linear decrease. */ - if (((queue->rx.req_prod_pvt - queue->rx.sring->rsp_prod) > - ((3*queue->rx_target) / 4)) && - (--queue->rx_target < queue->rx_min_target)) - queue->rx_target = queue->rx_min_target; - xennet_alloc_rx_buffers(queue); if (work_done < budget) { @@ -1643,11 +1613,6 @@ static int xennet_init_queue(struct netfront_queue *queue) spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->rx_lock); - skb_queue_head_init(&queue->rx_batch); - queue->rx_target = RX_DFL_MIN_TARGET; - queue->rx_min_target = RX_DFL_MIN_TARGET; - queue->rx_max_target = RX_MAX_TARGET; - init_timer(&queue->rx_refill_timer); queue->rx_refill_timer.data = (unsigned long)queue; queue->rx_refill_timer.function = rx_refill_timeout; @@ -1670,7 +1635,7 @@ static int xennet_init_queue(struct netfront_queue *queue) } /* A grant for every tx ring slot */ - if (gnttab_alloc_grant_references(TX_MAX_TARGET, + if (gnttab_alloc_grant_references(NET_TX_RING_SIZE, &queue->gref_tx_head) < 0) { pr_alert("can't alloc tx grant refs\n"); err = -ENOMEM; @@ -1678,7 +1643,7 @@ static int xennet_init_queue(struct netfront_queue *queue) } /* A grant for every rx ring slot */ - if (gnttab_alloc_grant_references(RX_MAX_TARGET, + if (gnttab_alloc_grant_references(NET_RX_RING_SIZE, &queue->gref_rx_head) < 0) { pr_alert("can't alloc rx grant refs\n"); err = -ENOMEM; @@ -2146,83 +2111,18 @@ static const struct ethtool_ops xennet_ethtool_ops = }; #ifdef CONFIG_SYSFS -static ssize_t show_rxbuf_min(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct net_device *netdev = to_net_dev(dev); - struct netfront_info *info = netdev_priv(netdev); - unsigned int num_queues = netdev->real_num_tx_queues; - - if (num_queues) - return sprintf(buf, "%u\n", info->queues[0].rx_min_target); - else - return sprintf(buf, "%u\n", RX_MIN_TARGET); -} - -static ssize_t store_rxbuf_min(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t show_rxbuf(struct device *dev, + struct device_attribute *attr, char *buf) { - struct net_device *netdev = to_net_dev(dev); - struct netfront_info *np = netdev_priv(netdev); - unsigned int num_queues = netdev->real_num_tx_queues; - char *endp; - unsigned long target; - unsigned int i; - struct netfront_queue *queue; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - target = simple_strtoul(buf, &endp, 0); - if (endp == buf) - return -EBADMSG; - - if (target < RX_MIN_TARGET) - target = RX_MIN_TARGET; - if (target > RX_MAX_TARGET) - target = RX_MAX_TARGET; - - for (i = 0; i < num_queues; ++i) { - queue = &np->queues[i]; - spin_lock_bh(&queue->rx_lock); - if (target > queue->rx_max_target) - queue->rx_max_target = target; - queue->rx_min_target = target; - if (target > queue->rx_target) - queue->rx_target = target; - - xennet_alloc_rx_buffers(queue); - - spin_unlock_bh(&queue->rx_lock); - } - return len; -} - -static ssize_t show_rxbuf_max(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct net_device *netdev = to_net_dev(dev); - struct netfront_info *info = netdev_priv(netdev); - unsigned int num_queues = netdev->real_num_tx_queues; - - if (num_queues) - return sprintf(buf, "%u\n", info->queues[0].rx_max_target); - else - return sprintf(buf, "%u\n", RX_MAX_TARGET); + return sprintf(buf, "%lu\n", NET_RX_RING_SIZE); } -static ssize_t store_rxbuf_max(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_rxbuf(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) { - struct net_device *netdev = to_net_dev(dev); - struct netfront_info *np = netdev_priv(netdev); - unsigned int num_queues = netdev->real_num_tx_queues; char *endp; unsigned long target; - unsigned int i = 0; - struct netfront_queue *queue = NULL; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -2231,44 +2131,15 @@ static ssize_t store_rxbuf_max(struct device *dev, if (endp == buf) return -EBADMSG; - if (target < RX_MIN_TARGET) - target = RX_MIN_TARGET; - if (target > RX_MAX_TARGET) - target = RX_MAX_TARGET; - - for (i = 0; i < num_queues; ++i) { - queue = &np->queues[i]; - spin_lock_bh(&queue->rx_lock); - if (target < queue->rx_min_target) - queue->rx_min_target = target; - queue->rx_max_target = target; - if (target < queue->rx_target) - queue->rx_target = target; - - xennet_alloc_rx_buffers(queue); + /* rxbuf_min and rxbuf_max are no longer configurable. */ - spin_unlock_bh(&queue->rx_lock); - } return len; } -static ssize_t show_rxbuf_cur(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct net_device *netdev = to_net_dev(dev); - struct netfront_info *info = netdev_priv(netdev); - unsigned int num_queues = netdev->real_num_tx_queues; - - if (num_queues) - return sprintf(buf, "%u\n", info->queues[0].rx_target); - else - return sprintf(buf, "0\n"); -} - static struct device_attribute xennet_attrs[] = { - __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min), - __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max), - __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL), + __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf, store_rxbuf), + __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf, store_rxbuf), + __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf, NULL), }; static int xennet_sysfs_addif(struct net_device *netdev) -- GitLab From bca516502efe1884515ff9bb8390a00f35464efa Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:02 +0200 Subject: [PATCH 1305/9457] qeth: qeth_core_main make local functions static This patch makes some global functions static and removes the prototypes from the header file. Also function qeth_query_card_info is not exported anymore, there is no external user for it, this function should never have been exported in the first place. Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 16 ---------------- drivers/s390/net/qeth_core_main.c | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index e7646ce3d659..7a8bb9f78e76 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -380,11 +380,6 @@ enum qeth_header_ids { #define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20 #define QETH_HDR_EXT_UDP 0x40 /*bit off for TCP*/ -static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale) -{ - return (sbale->eflags & SBAL_EFLAGS_LAST_ENTRY); -} - enum qeth_qdio_buffer_states { /* * inbound: read out by driver; owned by hardware in order to be filled @@ -843,13 +838,6 @@ struct qeth_trap_id { /*some helper functions*/ #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "") -static inline struct qeth_card *CARD_FROM_CDEV(struct ccw_device *cdev) -{ - struct qeth_card *card = dev_get_drvdata(&((struct ccwgroup_device *) - dev_get_drvdata(&cdev->dev))->dev); - return card; -} - static inline int qeth_get_micros(void) { return (int) (get_tod_clock() >> 12); @@ -894,7 +882,6 @@ const char *qeth_get_cardname_short(struct qeth_card *); int qeth_realloc_buffer_pool(struct qeth_card *, int); int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); void qeth_core_free_discipline(struct qeth_card *); -void qeth_buffer_reclaim_work(struct work_struct *); /* exports for qeth discipline device drivers */ extern struct qeth_card_list_struct qeth_core_card_list; @@ -913,7 +900,6 @@ int qeth_core_hardsetup_card(struct qeth_card *); void qeth_print_status_message(struct qeth_card *); int qeth_init_qdio_queues(struct qeth_card *); int qeth_send_startlan(struct qeth_card *); -int qeth_send_stoplan(struct qeth_card *); int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, int (*reply_cb) (struct qeth_card *, struct qeth_reply *, unsigned long), @@ -954,8 +940,6 @@ int qeth_snmp_command(struct qeth_card *, char __user *); int qeth_query_oat_command(struct qeth_card *, char __user *); int qeth_query_switch_attributes(struct qeth_card *card, struct qeth_switch_info *sw_info); -int qeth_query_card_info(struct qeth_card *card, - struct carrier_info *carrier_info); int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long), void *reply_param); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fd22c811cbe1..098bb0fff9cb 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -718,6 +718,13 @@ static int qeth_check_idx_response(struct qeth_card *card, return 0; } +static struct qeth_card *CARD_FROM_CDEV(struct ccw_device *cdev) +{ + struct qeth_card *card = dev_get_drvdata(&((struct ccwgroup_device *) + dev_get_drvdata(&cdev->dev))->dev); + return card; +} + static void qeth_setup_ccw(struct qeth_channel *channel, unsigned char *iob, __u32 len) { @@ -1431,6 +1438,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) } } +static void qeth_buffer_reclaim_work(struct work_struct *); static int qeth_setup_card(struct qeth_card *card) { @@ -3232,7 +3240,7 @@ int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf, } EXPORT_SYMBOL_GPL(qeth_check_qdio_errors); -void qeth_buffer_reclaim_work(struct work_struct *work) +static void qeth_buffer_reclaim_work(struct work_struct *work) { struct qeth_card *card = container_of(work, struct qeth_card, buffer_reclaim_work.work); @@ -4717,7 +4725,7 @@ static int qeth_query_card_info_cb(struct qeth_card *card, return 0; } -int qeth_query_card_info(struct qeth_card *card, +static int qeth_query_card_info(struct qeth_card *card, struct carrier_info *carrier_info) { struct qeth_cmd_buffer *iob; @@ -4730,7 +4738,6 @@ int qeth_query_card_info(struct qeth_card *card, return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, (void *)carrier_info); } -EXPORT_SYMBOL_GPL(qeth_query_card_info); static inline int qeth_get_qdio_q_format(struct qeth_card *card) { @@ -5113,6 +5120,11 @@ static inline int qeth_create_skb_frag(struct qeth_qdio_buffer *qethbuffer, return 0; } +static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale) +{ + return (sbale->eflags & SBAL_EFLAGS_LAST_ENTRY); +} + struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, struct qeth_qdio_buffer *qethbuffer, struct qdio_buffer_element **__element, int *__offset, -- GitLab From 8a5931484853c161801be9fd6824881824cd834e Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:03 +0200 Subject: [PATCH 1306/9457] qeth: fix some trace formating issues This patch fixes trace formatting issues using the QETH_CARD_TEXT_ macro. The total size of each trace entry is 8 bytes. Some of the sprintf formats exceed these 8 bytes (for example using abcd:%d and the converted value needs more than 3 bytes). The solution is to shorten the text prepending the value or use a different format (%x). Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 6 +++--- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 098bb0fff9cb..f407e3763432 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4134,7 +4134,7 @@ static int qeth_setadp_promisc_mode_cb(struct qeth_card *card, qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 4, "prmrc%2.2x", cmd->hdr.return_code); + QETH_CARD_TEXT_(card, 4, "prmrc%x", cmd->hdr.return_code); setparms->data.mode = SET_PROMISC_MODE_OFF; } card->info.promisc_mode = setparms->data.mode; @@ -4501,13 +4501,13 @@ static int qeth_snmp_command_cb(struct qeth_card *card, snmp = &cmd->data.setadapterparms.data.snmp; if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 4, "scer1%i", cmd->hdr.return_code); + QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code); return 0; } if (cmd->data.setadapterparms.hdr.return_code) { cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code; - QETH_CARD_TEXT_(card, 4, "scer2%i", cmd->hdr.return_code); + QETH_CARD_TEXT_(card, 4, "scer2%x", cmd->hdr.return_code); return 0; } data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data)); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index c2679bfe7f66..d02cd1a67943 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1512,7 +1512,7 @@ static void qeth_bridge_state_change(struct qeth_card *card, QETH_CARD_TEXT(card, 2, "brstchng"); if (qports->entry_length != sizeof(struct qeth_sbp_port_entry)) { - QETH_CARD_TEXT_(card, 2, "BPsz%.8d", qports->entry_length); + QETH_CARD_TEXT_(card, 2, "BPsz%04x", qports->entry_length); return; } extrasize = sizeof(struct qeth_sbp_port_entry) * qports->num_entries; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index afebb9709763..857a990c74c2 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2502,7 +2502,7 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) rc = -EFAULT; goto free_and_out; } - QETH_CARD_TEXT_(card, 4, "qacts"); + QETH_CARD_TEXT(card, 4, "qacts"); } free_and_out: kfree(qinfo.udata); -- GitLab From 56530d684e40a3a41fe390b065655fb229541c47 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:04 +0200 Subject: [PATCH 1307/9457] qeth: make local functions static in qeth_l3 module This patch makes 4 local functions static and removes the prototypes from the header file. Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3.h | 4 ---- drivers/s390/net/qeth_l3_main.c | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index 29c1c00e3a0f..551a4b4c03fd 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -42,10 +42,6 @@ struct qeth_ipato_entry { }; -void qeth_l3_ipaddr4_to_string(const __u8 *, char *); -int qeth_l3_string_to_ipaddr4(const char *, __u8 *); -void qeth_l3_ipaddr6_to_string(const __u8 *, char *); -int qeth_l3_string_to_ipaddr6(const char *, __u8 *); void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *); int qeth_l3_string_to_ipaddr(const char *, enum qeth_prot_versions, __u8 *); int qeth_l3_create_device_attributes(struct device *); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 857a990c74c2..625227ad16ee 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -55,12 +55,12 @@ static int qeth_l3_isxdigit(char *buf) return 1; } -void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf) +static void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf) { sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]); } -int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) +static int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) { int count = 0, rc = 0; unsigned int in[4]; @@ -78,12 +78,12 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) return 0; } -void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) +static void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) { sprintf(buf, "%pI6", addr); } -int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) +static int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) { const char *end, *end_tmp, *start; __u16 *in; -- GitLab From 3d14f661e6ae968689ff51f2f2f9b07d6ef3e3c6 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:05 +0200 Subject: [PATCH 1308/9457] qeth: s390 ethernet device driver dependency Compile the s390 10GB ethernet device driver only when ETHERNET has been defined in the kernel configuration file. Right now the qeth device driver is always built regardless of which network connectivity is active. Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 8b3f55991805..f1b5111bbaba 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -71,7 +71,7 @@ config CLAW config QETH def_tristate y prompt "Gigabit Ethernet device support" - depends on CCW && NETDEVICES && IP_MULTICAST && QDIO + depends on CCW && NETDEVICES && IP_MULTICAST && QDIO && ETHERNET help This driver supports the IBM System z OSA Express adapters in QDIO mode (all media types), HiperSockets interfaces and z/VM -- GitLab From 786f00659afd013ee8795083f3966c28323b3a03 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:06 +0200 Subject: [PATCH 1309/9457] lcs: replace sscanf by kstrto function Since a single integer value is read from the supplied buffer use the kstrto functions instead of sscanf. Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/lcs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0a7d87c372b8..92190aa20b9f 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1943,15 +1943,16 @@ static ssize_t lcs_portno_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lcs_card *card; - int value, rc; + int rc; + s16 value; card = dev_get_drvdata(dev); if (!card) return 0; - rc = sscanf(buf, "%d", &value); - if (rc != 1) + rc = kstrtos16(buf, 0, &value); + if (rc) return -EINVAL; /* TODO: sanity checks */ card->portno = value; @@ -2007,8 +2008,8 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char if (!card) return 0; - rc = sscanf(buf, "%u", &value); - if (rc != 1) + rc = kstrtouint(buf, 0, &value); + if (rc) return -EINVAL; /* TODO: sanity checks */ card->lancmd_timeout = value; -- GitLab From 652d77ba7be01093bf7e83090267533970028b12 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Oct 2014 12:18:07 +0200 Subject: [PATCH 1310/9457] ctcm: replace sscanf by kstrto function Since a single integer value is read from the supplied buffer use the kstrto functions instead of sscanf. Signed-off-by: Thomas Richter Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/ctcm_sysfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 6bcfbbb20f04..47773c4d235a 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c @@ -44,8 +44,8 @@ static ssize_t ctcm_buffer_write(struct device *dev, return -ENODEV; } - rc = sscanf(buf, "%u", &bs1); - if (rc != 1) + rc = kstrtouint(buf, 0, &bs1); + if (rc) goto einval; if (bs1 > CTCM_BUFSIZE_LIMIT) goto einval; @@ -151,8 +151,8 @@ static ssize_t ctcm_proto_store(struct device *dev, if (!priv) return -ENODEV; - rc = sscanf(buf, "%d", &value); - if ((rc != 1) || + rc = kstrtoint(buf, 0, &value); + if (rc || !((value == CTCM_PROTO_S390) || (value == CTCM_PROTO_LINUX) || (value == CTCM_PROTO_MPC) || -- GitLab From dd28153b2a8ca216350a9f42de58cf3a966cba30 Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Thu, 23 Oct 2014 21:28:37 +0200 Subject: [PATCH 1311/9457] Staging: comedi: replace timeval with ktime_t 'struct timeval last' is used for recording last time interrupt. 'struct timeval now' is used for calculating elapsed time. 32-bit systems using 'struct timeval' will break in the year 2038, so we have to replace that code with more appropriate types. This patch changes the comedi driver to use ktime_t. Since this code doesn't communicate the time values to the outside (user space, file system, network).Thus ktime_get() is a better than using do_gettimeofday() as it uses monotonic clock. ktime_to_us() returns an 's64', and using the '%' operator on that requires doing a 64-bit division which needs an expensive library function call the specific value of usec_current does not actually matter although it might matter that it's not always the same which will start with the offset from the lower 32 bit of the microsecond. Therefore: devpriv->usec_current = (ktime_to_us(devpriv->last) % USEC_PER_SEC) % devpriv->usec_period; is replaced by devpriv->usec_current = ((u32)ktime_to_us(devpriv->last)) % devpriv->usec_period; Signed-off-by: Somya Anand Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 8845075cd3cc..4d4358ce1710 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -52,13 +52,14 @@ zero volts). #include "comedi_fc.h" #include +#include #define N_CHANS 8 /* Data unique to this driver */ struct waveform_private { struct timer_list timer; - struct timeval last; /* time last timer interrupt occurred */ + ktime_t last; /* time last timer interrupt occurred */ unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */ unsigned long usec_period; /* waveform period in microseconds */ unsigned long usec_current; /* current time (mod waveform period) */ @@ -171,14 +172,12 @@ static void waveform_ai_interrupt(unsigned long arg) /* all times in microsec */ unsigned long elapsed_time; unsigned int num_scans; - struct timeval now; + ktime_t now; bool stopping = false; - do_gettimeofday(&now); + now = ktime_get(); - elapsed_time = - 1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec - - devpriv->last.tv_usec; + elapsed_time = ktime_to_us(ktime_sub(now, devpriv->last)); devpriv->last = now; num_scans = (devpriv->usec_remainder + elapsed_time) / devpriv->scan_period; @@ -317,8 +316,9 @@ static int waveform_ai_cmd(struct comedi_device *dev, else /* TRIG_TIMER */ devpriv->convert_period = cmd->convert_arg / nano_per_micro; - do_gettimeofday(&devpriv->last); - devpriv->usec_current = devpriv->last.tv_usec % devpriv->usec_period; + devpriv->last = ktime_get(); + devpriv->usec_current = + ((u32)ktime_to_us(devpriv->last)) % devpriv->usec_period; devpriv->usec_remainder = 0; devpriv->timer.expires = jiffies + 1; -- GitLab From d2b778712e3aa5258fabbb96ed05bcb073a1ce2e Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Thu, 23 Oct 2014 21:28:38 +0200 Subject: [PATCH 1312/9457] Staging: android: Replace timeval with ktime_t in timed_gpio.c 'struct timeval t' is used to return remaining time in milliseconds. 32-bit systems using 'struct timeval' will break in the year 2038, so we have to replace that code with more appropriate types. This patch changes the android driver to use ktime_t. Signed-off-by: Somya Anand Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/timed_gpio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index 8fa4758517c0..12d55148bafc 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "timed_output.h" #include "timed_gpio.h" @@ -46,16 +47,16 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) static int gpio_get_time(struct timed_output_dev *dev) { struct timed_gpio_data *data; - struct timeval t; + ktime_t t; data = container_of(dev, struct timed_gpio_data, dev); if (!hrtimer_active(&data->timer)) return 0; - t = ktime_to_timeval(hrtimer_get_remaining(&data->timer)); + t = hrtimer_get_remaining(&data->timer); - return t.tv_sec * 1000 + t.tv_usec / 1000; + return ktime_to_ms(t); } static void gpio_enable(struct timed_output_dev *dev, int value) -- GitLab From e31a0e62803c64cab5e150b94c31364a1ce1d0fd Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Thu, 23 Oct 2014 13:27:46 +0530 Subject: [PATCH 1313/9457] Staging: vme: devices: Use kasprintf This patch uses kasprintf which combines kmalloc and sprintf. kasprintf also takes care of the size calculation. This is done using Coccinelle. Semantic patch used is as follows: @@ expression a,flag; expression list args; statement S; @@ a = - \(kmalloc\|kzalloc\)(...,flag) + kasprintf (flag,args) <... when != a if (a == NULL || ...) S ...> - sprintf(a,args); Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_pio2_gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index c64776f71809..da34d5529f51 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -191,11 +191,11 @@ int pio2_gpio_init(struct pio2_card *card) int retval = 0; char *label; - label = kmalloc(PIO2_NUM_CHANNELS, GFP_KERNEL); + label = kasprintf(GFP_KERNEL, + "%s@%s", driver_name, dev_name(&card->vdev->dev)); if (label == NULL) return -ENOMEM; - sprintf(label, "%s@%s", driver_name, dev_name(&card->vdev->dev)); card->gc.label = label; card->gc.ngpio = PIO2_NUM_CHANNELS; -- GitLab From 438c582602b9e0b421bd356f3f2cdc77fe45eb5b Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Thu, 23 Oct 2014 16:10:16 +0300 Subject: [PATCH 1314/9457] staging: slicoss: Use inplace convert with __be32 * This patch fixes "cast to restricted __be32" sparse warning. remove temporary value assignment and use inplace __be32 conversion for ntohl function which is can get big endian format Signed-off-by: Ebru Akagunduz Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index f48eeb168e0b..71bc4edae322 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -596,8 +596,7 @@ static void slic_mac_address_config(struct adapter *adapter) u32 value2; __iomem struct slic_regs *slic_regs = adapter->slic_regs; - value = *(u32 *) &adapter->currmacaddr[2]; - value = ntohl(value); + value = ntohl(*(__be32 *) &adapter->currmacaddr[2]); slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH); slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH); -- GitLab From b3dd8957c23a9e2eed612469d02a6e418b585e6b Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 24 Oct 2014 21:46:00 +0530 Subject: [PATCH 1315/9457] staging: lustre: lustre: llite: Use kstrdup Use kstrdup when the goal of an allocation is copy a string into the allocated region. Patch found by coccicheck. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/xattr_cache.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c index 627cbe242f22..e2badf17d95e 100644 --- a/drivers/staging/lustre/lustre/llite/xattr_cache.c +++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c @@ -126,9 +126,7 @@ static int ll_xattr_cache_add(struct list_head *cache, return -ENOMEM; } - xattr->xe_namelen = strlen(xattr_name) + 1; - - xattr->xe_name = kzalloc(xattr->xe_namelen, GFP_NOFS); + xattr->xe_name = kstrdup(xattr_name, GFP_NOFS); if (!xattr->xe_name) { CDEBUG(D_CACHE, "failed to alloc xattr name %u\n", xattr->xe_namelen); @@ -141,7 +139,6 @@ static int ll_xattr_cache_add(struct list_head *cache, goto err_value; } - memcpy(xattr->xe_name, xattr_name, xattr->xe_namelen); memcpy(xattr->xe_value, xattr_val, xattr_val_len); xattr->xe_vallen = xattr_val_len; list_add(&xattr->xe_list, cache); -- GitLab From fe4c6a38b8379baf0bf7fe676c62e39c060d735b Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Thu, 23 Oct 2014 23:18:53 +0530 Subject: [PATCH 1316/9457] staging: xgifb: Removed an unnecessary assignment statement Used coccinelle patch @@ expression data; identifier f; @@ -data = +return f(...); -return (data); Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_util.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 1b452f8b6274..be3437ca339e 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -9,11 +9,8 @@ void xgifb_reg_set(unsigned long port, u8 index, u8 data) u8 xgifb_reg_get(unsigned long port, u8 index) { - u8 data; - outb(index, port); - data = inb(port + 1); - return data; + return inb(port + 1); } void xgifb_reg_and_or(unsigned long port, u8 index, -- GitLab From 861374fcf3e88e290b026fbddf7b5b27898df4b6 Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Thu, 23 Oct 2014 22:52:33 +0530 Subject: [PATCH 1317/9457] staging: vt6655: Replace C99 // comments by /* */ Replaced C99 // comments by /* */ in wroute.c Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wroute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index d1171fa3446e..6606a1c239ee 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -94,7 +94,7 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, if (pDevice->bEncryptionEnable == true) { bNeedEncryption = true; - // get group key + /* get group key */ pbyBSSID = pDevice->abyBroadcastAddr; if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { @@ -159,7 +159,7 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, &cbHeaderSize); if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS + /* Disable PS */ MACbPSWakeup(pDevice->PortOffset); } @@ -167,7 +167,7 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, pLastTD = pHeadTD; for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter + /* Poll Transmit the adapter */ wmb(); pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; wmb(); -- GitLab From 7424a0609063826a60a933ace872a1e747dfeede Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Thu, 23 Oct 2014 22:05:10 +0800 Subject: [PATCH 1318/9457] staging: rtl8188eu: core: fix null dereference on exit path in rtw_mlme.c If adapter is null, null dereference may occur. This patch fixes it. The following Coccinelle semantic patch was used to find the case. @@ expression E, E1; identifier f; statement S1,S2,S3; @@ * if (E == NULL) { ... when != if (E == NULL) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index 149c271e966d..bbebe67a77db 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -1437,7 +1437,7 @@ void rtw_dynamic_check_timer_handlder(void *function_context) struct registry_priv *pregistrypriv = &adapter->registrypriv; if (!adapter) - goto exit; + return; if (!adapter->hw_init_completed) goto exit; if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved)) -- GitLab From 334c826858691d306285183822e954063a116035 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 24 Oct 2014 21:44:26 +0530 Subject: [PATCH 1319/9457] staging: rtl8192u: Remove unnecessary if Remove the if condition, as the code inside the if condition is commented and does not have any FIXME or TODO comment. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_wx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 28f60d2dbe5b..361d2d0c3df1 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -171,7 +171,6 @@ static int r8192_wx_set_crcmon(struct net_device *dev, struct r8192_priv *priv = ieee80211_priv(dev); int *parms = (int *)extra; int enable = (parms[0] > 0); - short prev = priv->crcmon; down(&priv->wx_sem); @@ -183,11 +182,6 @@ static int r8192_wx_set_crcmon(struct net_device *dev, DMESG("bad CRC in monitor mode are %s", priv->crcmon ? "accepted" : "rejected"); - if (prev != priv->crcmon && priv->up) { - /* rtl8180_down(dev); */ - /* rtl8180_up(dev); */ - } - up(&priv->wx_sem); return 0; -- GitLab From eca6a8872a047069969a7f7ad420d819e4847be9 Mon Sep 17 00:00:00 2001 From: Aybuke Ozdemir Date: Thu, 23 Oct 2014 17:12:19 +0300 Subject: [PATCH 1320/9457] staging: media: lirc: Use pr_* instead of printk This patch focuses on fixing the following warning generated by checkpatch.pl for the file lirc_sasem.c: WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... WARNING: Prefer [subsystem eg: netdev]_cont([subsystem]dev, ... then dev_cont(dev, ... then pr_cont(... to printk(KERN_CONT ... Signed-off-by: Aybuke Ozdemir Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_sasem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index c20ef56202bf..05969fb451ca 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -583,10 +583,10 @@ static void incoming_packet(struct sasem_context *context, } if (debug) { - printk(KERN_INFO "Incoming data: "); + pr_info("Incoming data: "); for (i = 0; i < 8; ++i) - printk(KERN_CONT "%02x ", buf[i]); - printk(KERN_CONT "\n"); + pr_cont("%02x ", buf[i]); + pr_cont("\n"); } /* -- GitLab From f237216ebfd4c263b448df2f6e09ff6786221f03 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 23 Oct 2014 20:16:51 -0700 Subject: [PATCH 1321/9457] Staging: rtl8723au: core: Dont have { on new line This patch fixes the following checkpatch errors: ERROR: that open brace { should be on the previous line ERROR: else should follow close brace '}' Exceptions: { is left on a new line to itself when fixing this error makes the line longer than 80 characters. Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 140 ++++++------------ drivers/staging/rtl8723au/core/rtw_cmd.c | 6 +- .../staging/rtl8723au/core/rtw_ieee80211.c | 3 +- drivers/staging/rtl8723au/core/rtw_led.c | 80 ++++------ 4 files changed, 71 insertions(+), 158 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index 75ae2492699a..6a336cd2eb4d 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -231,12 +231,10 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter) psta->expire_to--; } - if (psta->expire_to <= 0) - { + if (psta->expire_to <= 0) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - if (padapter->registrypriv.wifi_spec == 1) - { + if (padapter->registrypriv.wifi_spec == 1) { psta->expire_to = pstapriv->expire_to; continue; } @@ -308,15 +306,12 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter) ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 50); psta->keep_alive_trycnt++; - if (ret == _SUCCESS) - { + if (ret == _SUCCESS) { DBG_8723A("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr)); psta->expire_to = pstapriv->expire_to; psta->keep_alive_trycnt = 0; continue; - } - else if (psta->keep_alive_trycnt <= 3) - { + } else if (psta->keep_alive_trycnt <= 3) { DBG_8723A("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt); psta->expire_to = 1; continue; @@ -363,8 +358,7 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l return; /* b/g mode ra_bitmap */ - for (i = 0; i < sizeof(psta->bssrateset); i++) - { + for (i = 0; i < sizeof(psta->bssrateset); i++) { if (psta->bssrateset[i]) tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f); } @@ -406,8 +400,7 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l raid = networktype_to_raid23a(sta_band); init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f; - if (psta->aid < NUM_STA) - { + if (psta->aid < NUM_STA) { u8 arg = 0; arg = psta->mac_id&0x1f; @@ -436,11 +429,8 @@ void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_l psta->raid = raid; psta->init_rate = init_rate; - } - else - { + } else DBG_8723A("station aid %d exceed the max number\n", psta->aid); - } } static void update_bmc_sta(struct rtw_adapter *padapter) @@ -453,8 +443,7 @@ static void update_bmc_sta(struct rtw_adapter *padapter) struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network; struct sta_info *psta = rtw_get_bcmc_stainfo23a(padapter); - if (psta) - { + if (psta) { psta->aid = 0;/* default set to 0 */ psta->mac_id = psta->aid + 1; @@ -474,8 +463,7 @@ static void update_bmc_sta(struct rtw_adapter *padapter) psta->bssratelen = supportRateNum; /* b/g mode ra_bitmap */ - for (i = 0; i < supportRateNum; i++) - { + for (i = 0; i < supportRateNum; i++) { if (psta->bssrateset[i]) tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f); } @@ -522,11 +510,8 @@ static void update_bmc_sta(struct rtw_adapter *padapter) psta->state = _FW_LINKED; spin_unlock_bh(&psta->lock); - } - else - { + } else DBG_8723A("add_RATid23a_bmc_sta error!\n"); - } } /* notes: */ @@ -561,8 +546,7 @@ void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info /* ERP */ VCS_update23a(padapter, psta); /* HT related cap */ - if (phtpriv_sta->ht_option) - { + if (phtpriv_sta->ht_option) { /* check if sta supports rx ampdu */ phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; @@ -580,9 +564,7 @@ void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info psta->qos_option = true; - } - else - { + } else { phtpriv_sta->ampdu_enable = false; phtpriv_sta->sgi = false; @@ -1258,8 +1240,7 @@ void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx) spin_lock_bh(&pmlmepriv->bcn_update_lock); - switch (ie_id) - { + switch (ie_id) { case 0xFF: /* 8: TimeStamp, 2: Beacon Interval 2:Capability */ update_bcn_fixed_ie(padapter); @@ -1386,8 +1367,7 @@ static int rtw_ht_operation_update(struct rtw_adapter *padapter) void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated) { /* update associated stations cap. */ - if (updated == true) - { + if (updated == true) { struct list_head *phead, *plist, *ptmp; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; @@ -1413,34 +1393,27 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) - { - if (!psta->no_short_preamble_set) - { + if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) { + if (!psta->no_short_preamble_set) { psta->no_short_preamble_set = 1; pmlmepriv->num_sta_no_short_preamble++; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_preamble == 1)) - { + (pmlmepriv->num_sta_no_short_preamble == 1)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } - } - else - { - if (psta->no_short_preamble_set) - { + } else { + if (psta->no_short_preamble_set) { psta->no_short_preamble_set = 0; pmlmepriv->num_sta_no_short_preamble--; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_preamble == 0)) - { + (pmlmepriv->num_sta_no_short_preamble == 0)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1448,32 +1421,25 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } } - if (psta->flags & WLAN_STA_NONERP) - { - if (!psta->nonerp_set) - { + if (psta->flags & WLAN_STA_NONERP) { + if (!psta->nonerp_set) { psta->nonerp_set = 1; pmlmepriv->num_sta_non_erp++; - if (pmlmepriv->num_sta_non_erp == 1) - { + if (pmlmepriv->num_sta_non_erp == 1) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); } } - } - else - { - if (psta->nonerp_set) - { + } else { + if (psta->nonerp_set) { psta->nonerp_set = 0; pmlmepriv->num_sta_non_erp--; - if (pmlmepriv->num_sta_non_erp == 0) - { + if (pmlmepriv->num_sta_non_erp == 0) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); } @@ -1481,42 +1447,34 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } - if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) - { - if (!psta->no_short_slot_time_set) - { + if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) { + if (!psta->no_short_slot_time_set) { psta->no_short_slot_time_set = 1; pmlmepriv->num_sta_no_short_slot_time++; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_slot_time == 1)) - { + (pmlmepriv->num_sta_no_short_slot_time == 1)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } - } - else - { - if (psta->no_short_slot_time_set) - { + } else { + if (psta->no_short_slot_time_set) { psta->no_short_slot_time_set = 0; pmlmepriv->num_sta_no_short_slot_time--; if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && - (pmlmepriv->num_sta_no_short_slot_time == 0)) - { + (pmlmepriv->num_sta_no_short_slot_time == 0)) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } } } - if (psta->flags & WLAN_STA_HT) - { + if (psta->flags & WLAN_STA_HT) { u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); DBG_8723A("HT: STA " MAC_FMT " HT Capabilities " @@ -1549,9 +1507,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info pmlmepriv->num_sta_ht_20mhz); } - } - else - { + } else { if (!psta->no_ht_set) { psta->no_ht_set = 1; pmlmepriv->num_sta_no_ht++; @@ -1564,8 +1520,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info } } - if (rtw_ht_operation_update(padapter) > 0) - { + if (rtw_ht_operation_update(padapter) > 0) { update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false); update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true); } @@ -1589,8 +1544,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info psta->no_short_preamble_set = 0; pmlmepriv->num_sta_no_short_preamble--; if (pmlmeext->cur_wireless_mode > WIRELESS_11B - && pmlmepriv->num_sta_no_short_preamble == 0) - { + && pmlmepriv->num_sta_no_short_preamble == 0) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1599,8 +1553,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info if (psta->nonerp_set) { psta->nonerp_set = 0; pmlmepriv->num_sta_non_erp--; - if (pmlmepriv->num_sta_non_erp == 0) - { + if (pmlmepriv->num_sta_non_erp == 0) { beacon_updated = true; update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true); @@ -1611,8 +1564,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info psta->no_short_slot_time_set = 0; pmlmepriv->num_sta_no_short_slot_time--; if (pmlmeext->cur_wireless_mode > WIRELESS_11B - && pmlmepriv->num_sta_no_short_slot_time == 0) - { + && pmlmepriv->num_sta_no_short_slot_time == 0) { beacon_updated = true; update_beacon23a(padapter, 0xFF, NULL, true); } @@ -1633,8 +1585,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info pmlmepriv->num_sta_ht_20mhz--; } - if (rtw_ht_operation_update(padapter) > 0) - { + if (rtw_ht_operation_update(padapter) > 0) { update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false); update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true); } @@ -1654,8 +1605,7 @@ u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool acti if (!psta) return beacon_updated; - if (active == true) - { + if (active == true) { /* tear down Rx AMPDU */ send_delba23a(padapter, 0, psta->hwaddr);/* recipient */ @@ -1783,13 +1733,10 @@ void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->qos_option = 0; /* update 802.11n ht cap. */ - if (WLAN_STA_HT&flags) - { + if (WLAN_STA_HT&flags) { psta->htpriv.ht_option = true; psta->qos_option = 1; - } - else - { + } else { psta->htpriv.ht_option = false; } @@ -1802,8 +1749,7 @@ void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta) /* called >= TSR LEVEL for USB or SDIO Interface*/ void ap_sta_info_defer_update23a(struct rtw_adapter *padapter, struct sta_info *psta) { - if (psta->state & _FW_LINKED) - { + if (psta->state & _FW_LINKED) { /* add ratid */ add_RATid23a(padapter, psta, 0);/* DM_RATR_STA_INIT */ } diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index d2d7edf38fc6..65a3cd1d8f48 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -1020,8 +1020,7 @@ static void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type) check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) return; - switch (lps_ctrl_type) - { + switch (lps_ctrl_type) { case LPS_CTRL_SCAN: rtl8723a_BT_wifiscan_notify(padapter, true); if (!rtl8723a_BT_using_antenna_1(padapter)) { @@ -1308,8 +1307,7 @@ int rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf) pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; - switch (pdrvextra_cmd->ec_id) - { + switch (pdrvextra_cmd->ec_id) { case DYNAMIC_CHK_WK_CID: dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c index c78d6eb0ef89..bbbcfc8257da 100644 --- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c @@ -302,8 +302,7 @@ void rtw_set_supported_rate23a(u8 *SupportedRates, uint mode) memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); - switch (mode) - { + switch (mode) { case WIRELESS_11B: memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); break; diff --git a/drivers/staging/rtl8723au/core/rtw_led.c b/drivers/staging/rtl8723au/core/rtw_led.c index c66e727a2bca..92ab1f8ded96 100644 --- a/drivers/staging/rtl8723au/core/rtw_led.c +++ b/drivers/staging/rtl8723au/core/rtw_led.c @@ -424,29 +424,23 @@ static void SwLedBlink3(struct led_8723a *pLed) u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { + if (pLed->BlinkingLedState == RTW_LED_ON) { SwLedOn23a(padapter, pLed); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); - } - else - { + } else { if (pLed->CurrLedState != LED_BLINK_WPS_STOP) SwLedOff23a(padapter, pLed); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); } - switch (pLed->CurrLedState) - { + switch (pLed->CurrLedState) { case LED_BLINK_SCAN: pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - { + if (pLed->BlinkTimes == 0) { bStopBlinking = true; } - if (bStopBlinking) - { + if (bStopBlinking) { if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff23a(padapter, pLed); @@ -467,15 +461,11 @@ static void SwLedBlink3(struct led_8723a *pLed) RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } pLed->bLedScanBlinkInProgress = false; - } - else - { + } else { if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff23a(padapter, pLed); - } - else - { + } else { if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else @@ -488,12 +478,10 @@ static void SwLedBlink3(struct led_8723a *pLed) case LED_BLINK_TXRX: pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - { + if (pLed->BlinkTimes == 0) { bStopBlinking = true; } - if (bStopBlinking) - { + if (bStopBlinking) { if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff23a(padapter, pLed); @@ -516,15 +504,11 @@ static void SwLedBlink3(struct led_8723a *pLed) RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState)); } pLed->bLedBlinkInProgress = false; - } - else - { + } else { if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff23a(padapter, pLed); - } - else - { + } else { if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; else @@ -545,8 +529,7 @@ static void SwLedBlink3(struct led_8723a *pLed) break; case LED_BLINK_WPS_STOP: /* WPS success */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { + if (pLed->BlinkingLedState == RTW_LED_ON) { pLed->BlinkingLedState = RTW_LED_OFF; mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); @@ -555,8 +538,7 @@ static void SwLedBlink3(struct led_8723a *pLed) bStopBlinking = true; } - if (bStopBlinking) - { + if (bStopBlinking) { if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { SwLedOff23a(padapter, pLed); @@ -586,8 +568,7 @@ static void SwLedBlink4(struct led_8723a *pLed) unsigned long delay = 0; /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == RTW_LED_ON) - { + if (pLed->BlinkingLedState == RTW_LED_ON) { SwLedOn23a(padapter, pLed); RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); } else { @@ -602,8 +583,7 @@ static void SwLedBlink4(struct led_8723a *pLed) SwLedOff23a(padapter, pLed1); } - switch (pLed->CurrLedState) - { + switch (pLed->CurrLedState) { case LED_BLINK_SLOWLY: if (pLed->bLedOn) pLed->BlinkingLedState = RTW_LED_OFF; @@ -752,8 +732,7 @@ static void SwLedBlink5(struct led_8723a *pLed) RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); } - switch (pLed->CurrLedState) - { + switch (pLed->CurrLedState) { case LED_BLINK_SCAN: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) { @@ -855,8 +834,7 @@ SwLedControlMode1(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) long delay = -1; - switch (LedAction) - { + switch (LedAction) { case LED_CTL_POWER_ON: case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: @@ -1185,8 +1163,7 @@ SwLedControlMode2(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) break; case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) - { + if (!IS_LED_BLINKING(pLed)) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; delay = 0; @@ -1230,8 +1207,7 @@ SwLedControlMode3(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) struct led_8723a *pLed = &ledpriv->SwLed0; long delay = -1; - switch (LedAction) - { + switch (LedAction) { case LED_CTL_SITE_SURVEY: if (pmlmepriv->LinkDetectInfo.bBusyTraffic) ; @@ -1345,8 +1321,7 @@ SwLedControlMode3(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) - { + if (!IS_LED_BLINKING(pLed)) { pLed->CurrLedState = RTW_LED_OFF; pLed->BlinkingLedState = RTW_LED_OFF; delay = 0; @@ -1392,8 +1367,7 @@ SwLedControlMode4(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) struct led_8723a *pLed = &ledpriv->SwLed0; struct led_8723a *pLed1 = &ledpriv->SwLed1; - switch (LedAction) - { + switch (LedAction) { case LED_CTL_START_TO_LINK: if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; @@ -1550,8 +1524,7 @@ SwLedControlMode4(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - { + if (pLed->bLedOn) { pLed->BlinkingLedState = RTW_LED_OFF; mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); @@ -1697,8 +1670,7 @@ SwLedControlMode5(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct led_8723a *pLed = &ledpriv->SwLed0; - switch (LedAction) - { + switch (LedAction) { case LED_CTL_POWER_ON: case LED_CTL_NO_LINK: case LED_CTL_LINK: /* solid blue */ @@ -1712,10 +1684,8 @@ SwLedControlMode5(struct rtw_adapter *padapter, enum led_ctl_mode LedAction) if (pmlmepriv->LinkDetectInfo.bBusyTraffic && check_fwstate(pmlmepriv, _FW_LINKED)) ; - else if (pLed->bLedScanBlinkInProgress == false) - { - if (pLed->bLedBlinkInProgress == true) - { + else if (pLed->bLedScanBlinkInProgress == false) { + if (pLed->bLedBlinkInProgress == true) { del_timer_sync(&pLed->BlinkTimer); pLed->bLedBlinkInProgress = false; } -- GitLab From 5db8bee627aadf5f666234f551a3528ccf3b5b31 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 23 Oct 2014 20:17:20 -0700 Subject: [PATCH 1322/9457] Staging: rtl8723au: core: Dont have { on new line This patch fixes the following checkpatch errors: ERROR: that open brace { should be on the previous line ERROR: else should follow close brace '}' Exceptions: { is left on a new line to itself when fixing this error makes the line longer than 80 characters. Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 43 ++++-------- drivers/staging/rtl8723au/core/rtw_pwrctrl.c | 3 +- drivers/staging/rtl8723au/core/rtw_recv.c | 9 +-- drivers/staging/rtl8723au/core/rtw_security.c | 66 +++++++------------ 4 files changed, 39 insertions(+), 82 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index e4f4934e357d..86f5217afe93 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -681,8 +681,7 @@ void mgt_dispatcher23a(struct rtw_adapter *padapter, } #ifdef CONFIG_8723AU_AP_MODE - switch (stype) - { + switch (stype) { case IEEE80211_STYPE_AUTH: if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ptable->func = &OnAuth23a; @@ -2337,8 +2336,7 @@ static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */ if (ssid_ie && ssid_len_ori > 0) { - switch (hidden_ssid_mode) - { + switch (hidden_ssid_mode) { case 1: next_ie = ssid_ie + 2 + ssid_len_ori; remain_len = 0; @@ -4363,9 +4361,7 @@ static void start_create_ibss(struct rtw_adapter *padapter) report_join_res23a(padapter, 1); pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; } - } - else - { + } else { DBG_8723A("%s: invalid cap:%x\n", __func__, caps); return; } @@ -4423,9 +4419,7 @@ static void start_clnt_join(struct rtw_adapter *padapter) pmlmeinfo->state = MSR_ADHOC; report_join_res23a(padapter, 1); - } - else - { + } else { /* DBG_8723A("marc: invalid cap:%x\n", caps); */ return; } @@ -4489,16 +4483,12 @@ int receive_disconnect23a(struct rtw_adapter *padapter, DBG_8723A("%s\n", __func__); - if ((pmlmeinfo->state&0x03) == MSR_INFRA) - { - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - { + if ((pmlmeinfo->state&0x03) == MSR_INFRA) { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { pmlmeinfo->state = MSR_NOLINK; report_del_sta_event23a(padapter, MacAddr, reason); - } - else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) - { + } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { pmlmeinfo->state = MSR_NOLINK; report_join_res23a(padapter, -2); } @@ -5004,8 +4994,7 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta) VCS_update23a(padapter, psta); /* HT */ - if (pmlmepriv->htpriv.ht_option) - { + if (pmlmepriv->htpriv.ht_option) { psta->htpriv.ht_option = true; psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; @@ -5015,9 +5004,7 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta) psta->qos_option = true; - } - else - { + } else { psta->htpriv.ht_option = false; psta->htpriv.ampdu_enable = false; @@ -5059,12 +5046,10 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, goto exit_mlmeext_joinbss_event_callback23a; } - if ((pmlmeinfo->state&0x03) == MSR_ADHOC) - { + if ((pmlmeinfo->state&0x03) == MSR_ADHOC) { /* for bc/mc */ psta_bmc = rtw_get_bcmc_stainfo23a(padapter); - if (psta_bmc) - { + if (psta_bmc) { pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc; update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id); Update_RA_Entry23a(padapter, psta_bmc); @@ -5095,8 +5080,7 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress); - if (psta) /* only for infra. mode */ - { + if (psta) { /* only for infra. mode */ pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; /* DBG_8723A("set_sta_rate23a\n"); */ @@ -5132,8 +5116,7 @@ void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) { /* adhoc master or sta_count>1 */ - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* nothing to do */ } else { /* adhoc client */ /* correcting TSF */ diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c index 32f1ab515f91..1eae885c1170 100644 --- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c @@ -338,8 +338,7 @@ s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms) start_time = jiffies; end_time = start_time + msecs_to_jiffies(delay_ms); - while (1) - { + while (1) { bAwake = rtl8723a_get_fwlps_rf_on(padapter); if (bAwake == true) break; diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 4dca863657ec..0c0896f3a16b 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -1410,8 +1410,7 @@ static int validate_recv_data_frame(struct rtw_adapter *adapter, RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt =%d\n", pattrib->encrypt)); - switch (pattrib->encrypt) - { + switch (pattrib->encrypt) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: pattrib->iv_len = IEEE80211_WEP_IV_LEN; @@ -1510,8 +1509,7 @@ static int validate_recv_frame(struct rtw_adapter *adapter, if (unlikely(bDumpRxPkt == 1)) dump_rx_pkt(skb, type, bDumpRxPkt); - switch (type) - { + switch (type) { case IEEE80211_FTYPE_MGMT: retval = validate_recv_mgnt_frame(adapter, precv_frame); if (retval == _FAIL) { @@ -2182,8 +2180,7 @@ int process_recv_indicatepkts(struct rtw_adapter *padapter, return retval; } } - } else /* B/G mode */ - { + } else { /* B/G mode */ retval = wlanhdr_to_ethhdr(prframe); if (retval != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c index 60e944554ec5..715a47414bdd 100644 --- a/drivers/staging/rtl8723au/core/rtw_security.c +++ b/drivers/staging/rtl8723au/core/rtw_security.c @@ -44,8 +44,7 @@ static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) state[counter] = (u8)counter; keyindex = 0; stateindex = 0; - for (counter = 0; counter < 256; counter++) - { + for (counter = 0; counter < 256; counter++) { t = state[counter]; stateindex = (stateindex + key[keyindex] + t) & 0xff; u = state[stateindex]; @@ -113,8 +112,7 @@ static void crc32_init(void) c = 0x12340000; - for (i = 0; i < 256; ++i) - { + for (i = 0; i < 256; ++i) { k = crc32_reverseBit((u8)i); for (c = ((u32)k) << 24, j = 8; j > 0; --j) { c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); @@ -269,8 +267,7 @@ static u32 secmicgetuint32(u8 *p) s32 i; u32 res = 0; - for (i = 0; i<4; i++) - { + for (i = 0; i<4; i++) { res |= ((u32)(*p++)) << (8*i); } @@ -282,8 +279,7 @@ static void secmicputuint32(u8 *p, u32 val) { long i; - for (i = 0; i<4; i++) - { + for (i = 0; i<4; i++) { *p++ = (u8) (val & 0xff); val >>= 8; } @@ -319,8 +315,7 @@ void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b) pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM); pmicdata->nBytesInM++; /* Process the word if it is full. */ - if (pmicdata->nBytesInM >= 4) - { + if (pmicdata->nBytesInM >= 4) { pmicdata->L ^= pmicdata->M; pmicdata->R ^= ROL32(pmicdata->L, 17); pmicdata->L += pmicdata->R; @@ -341,8 +336,7 @@ void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbytes) { /* This is simple */ - while(nbytes > 0) - { + while(nbytes > 0) { rtw_secmicappend23abyte23a(pmicdata, *src++); nbytes--; } @@ -359,8 +353,7 @@ void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst) rtw_secmicappend23abyte23a(pmicdata, 0); rtw_secmicappend23abyte23a(pmicdata, 0); /* and then zeroes until the length is a multiple of 4 */ - while(pmicdata->nBytesInM != 0) - { + while(pmicdata->nBytesInM != 0) { rtw_secmicappend23abyte23a(pmicdata, 0); } /* The appendByte function has already computed the result. */ @@ -529,8 +522,8 @@ static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) /* Now compute an unbalanced Feistel cipher with 80-bit block */ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ - for (i = 0; i < PHASE1_LOOP_CNT ;i++) - { /* Each add operation here is mod 2**16 */ + for (i = 0; i < PHASE1_LOOP_CNT ;i++) { + /* Each add operation here is mod 2**16 */ p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0)); p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2)); p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4)); @@ -600,8 +593,7 @@ static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ - for (i = 0;i<6;i++) - { + for (i = 0;i<6;i++) { rc4key[4+2*i] = Lo8(PPK[i]); rc4key[5+2*i] = Hi8(PPK[i]); } @@ -647,8 +639,7 @@ int rtw_tkip_encrypt23a(struct rtw_adapter *padapter, if (stainfo!= NULL) { - if (!(stainfo->state &_FW_LINKED)) - { + if (!(stainfo->state &_FW_LINKED)) { DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); return _FAIL; } @@ -885,8 +876,7 @@ static void byte_sub(u8 *in, u8 *out) { int i; - for (i = 0; i< 16; i++) - { + for (i = 0; i< 16; i++) { out[i] = sbox(in[i]); } @@ -926,8 +916,7 @@ static void mix_column(u8 *in, u8 *out) u8 temp[4]; u8 tempb[4]; - for (i = 0 ; i<4; i++) - { + for (i = 0 ; i<4; i++) { if ((in[i] & 0x80) == 0x80) add1b[i] = 0x1b; else @@ -949,11 +938,9 @@ static void mix_column(u8 *in, u8 *out) andf7[2] = in[2] & 0x7f; andf7[3] = in[3] & 0x7f; - for (i = 3; i>0; i--) /* logical shift left 1 bit */ - { + for (i = 3; i>0; i--) { /* logical shift left 1 bit */ andf7[i] = andf7[i] << 1; - if ((andf7[i-1] & 0x80) == 0x80) - { + if ((andf7[i-1] & 0x80) == 0x80) { andf7[i] = (andf7[i] | 0x01); } } @@ -986,21 +973,15 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) for (i = 0; i<16; i++) round_key[i] = key[i]; - for (round = 0; round < 11; round++) - { - if (round == 0) - { + for (round = 0; round < 11; round++) { + if (round == 0) { xor_128(round_key, data, ciphertext); next_key(round_key, round); - } - else if (round == 10) - { + } else if (round == 10) { byte_sub(ciphertext, intermediatea); shift_row(intermediatea, intermediateb); xor_128(intermediateb, round_key, ciphertext); - } - else /* 1 - 9 */ - { + } else { /* 1 - 9 */ byte_sub(ciphertext, intermediatea); shift_row(intermediatea, intermediateb); mix_column(&intermediateb[0], &intermediatea[0]); @@ -1086,20 +1067,17 @@ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, mic_header2[6] = 0x00; mic_header2[7] = 0x00; /* mpdu[23]; */ - if (!qc_exists && a4_exists) - { + if (!qc_exists && a4_exists) { for (i = 0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ } - if (qc_exists && !a4_exists) - { + if (qc_exists && !a4_exists) { mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ mic_header2[9] = mpdu[25] & 0x00; } - if (qc_exists && a4_exists) - { + if (qc_exists && a4_exists) { for (i = 0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ mic_header2[14] = mpdu[30] & 0x0f; -- GitLab From 3e3f878f4d38c0724e51e192f232e1726daffd89 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 23 Oct 2014 20:17:48 -0700 Subject: [PATCH 1323/9457] Staging: rtl8723au: core: Fix switch-case indent This patch fixes the following checkpatch errors in rtw_cmd.c : ERROR: switch and case should be at the same indent Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_cmd.c | 70 ++++++++++++------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index 65a3cd1d8f48..01b44a4364dc 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -1021,44 +1021,44 @@ static void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type) return; switch (lps_ctrl_type) { - case LPS_CTRL_SCAN: - rtl8723a_BT_wifiscan_notify(padapter, true); - if (!rtl8723a_BT_using_antenna_1(padapter)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) - LPS_Leave23a(padapter); + case LPS_CTRL_SCAN: + rtl8723a_BT_wifiscan_notify(padapter, true); + if (!rtl8723a_BT_using_antenna_1(padapter)) { + if (check_fwstate(pmlmepriv, _FW_LINKED)) + LPS_Leave23a(padapter); } - break; - case LPS_CTRL_JOINBSS: + break; + case LPS_CTRL_JOINBSS: + LPS_Leave23a(padapter); + break; + case LPS_CTRL_CONNECT: + mstatus = 1;/* connect */ + /* Reset LPS Setting */ + padapter->pwrctrlpriv.LpsIdleCount = 0; + rtl8723a_set_FwJoinBssReport_cmd(padapter, 1); + rtl8723a_BT_mediastatus_notify(padapter, mstatus); + break; + case LPS_CTRL_DISCONNECT: + mstatus = 0;/* disconnect */ + rtl8723a_BT_mediastatus_notify(padapter, mstatus); + if (!rtl8723a_BT_using_antenna_1(padapter)) LPS_Leave23a(padapter); - break; - case LPS_CTRL_CONNECT: - mstatus = 1;/* connect */ - /* Reset LPS Setting */ - padapter->pwrctrlpriv.LpsIdleCount = 0; - rtl8723a_set_FwJoinBssReport_cmd(padapter, 1); - rtl8723a_BT_mediastatus_notify(padapter, mstatus); - break; - case LPS_CTRL_DISCONNECT: - mstatus = 0;/* disconnect */ - rtl8723a_BT_mediastatus_notify(padapter, mstatus); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - rtl8723a_set_FwJoinBssReport_cmd(padapter, 0); - break; - case LPS_CTRL_SPECIAL_PACKET: - pwrpriv->DelayLPSLastTimeStamp = jiffies; - rtl8723a_BT_specialpacket_notify(padapter); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - break; - case LPS_CTRL_LEAVE: - rtl8723a_BT_lps_leave(padapter); - if (!rtl8723a_BT_using_antenna_1(padapter)) - LPS_Leave23a(padapter); - break; + rtl8723a_set_FwJoinBssReport_cmd(padapter, 0); + break; + case LPS_CTRL_SPECIAL_PACKET: + pwrpriv->DelayLPSLastTimeStamp = jiffies; + rtl8723a_BT_specialpacket_notify(padapter); + if (!rtl8723a_BT_using_antenna_1(padapter)) + LPS_Leave23a(padapter); + break; + case LPS_CTRL_LEAVE: + rtl8723a_BT_lps_leave(padapter); + if (!rtl8723a_BT_using_antenna_1(padapter)) + LPS_Leave23a(padapter); + break; - default: - break; + default: + break; } } -- GitLab From 1d06bb4e9df30162d8690a26792611a141676279 Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 10:58:28 +0800 Subject: [PATCH 1324/9457] staging: remove unneeded parentheses around the right hand side of an assignment In assignments such as value = (FLASH_CMD_STATUS_REG_READ << 24);, parentheses are not needed. The Coccinelle semantic patch was used to find cases. @r@ identifier x; expression e1, e2; @@ - x = (e1 << e2); + x = e1 << e2; Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 2 +- drivers/staging/lustre/lustre/libcfs/debug.c | 2 +- drivers/staging/lustre/lustre/llite/rw.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 2 +- drivers/staging/media/omap24xx/omap24xxcam.c | 2 +- drivers/staging/ozwpan/ozhcd.c | 6 +++--- drivers/staging/rtl8188eu/hal/usb_halinit.c | 2 +- drivers/staging/rtl8723au/hal/hal_com.c | 2 +- drivers/staging/vt6655/dpc.c | 2 +- drivers/staging/xgifb/vb_setmode.c | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 8f5cdd584f85..045f2beb41d2 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2411,7 +2411,7 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev) goto out; } - mr_size = (1ULL << hdev->ibh_mr_shift); + mr_size = 1ULL << hdev->ibh_mr_shift; mm_size = (unsigned long)high_memory - PAGE_OFFSET; hdev->ibh_nmrs = (int)((mm_size + mr_size - 1) >> hdev->ibh_mr_shift); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 6054eee848d3..3822e0f3faf0 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -265,7 +265,7 @@ static void ldlm_pool_recalc_slv(struct ldlm_pool *pl) * SLV. And the opposite, the more grant plan is over-consumed * (load time) the faster drops SLV. */ - slv_factor = (grant_usage << LDLM_POOL_SLV_SHIFT); + slv_factor = grant_usage << LDLM_POOL_SLV_SHIFT; do_div(slv_factor, limit); slv = slv * slv_factor; slv = dru(slv, LDLM_POOL_SLV_SHIFT, round_up); diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index ba43b3067fa3..2c15a9e7332f 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -412,7 +412,7 @@ int libcfs_debug_init(unsigned long bufsize) max = TCD_MAX_PAGES; } else { max = (max / num_possible_cpus()); - max = (max << (20 - PAGE_CACHE_SHIFT)); + max = max << (20 - PAGE_CACHE_SHIFT); } rc = cfs_tracefile_init(max); diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 1f53b9863385..613d772357ac 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -145,7 +145,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file, */ io->ci_lockreq = CILR_NEVER; - pos = (vmpage->index << PAGE_CACHE_SHIFT); + pos = vmpage->index << PAGE_CACHE_SHIFT; /* Create a temp IO to serve write. */ result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE); diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 8828d6c2aab1..415502651033 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -633,7 +633,7 @@ resizer_calculate_normal_f_div_param(struct device *dev, int input_width, if (!(val % 2)) { h1 = val; } else { - val = (input_width << 7); + val = input_width << 7; val -= rsz >> 1; val /= rsz << 1; val <<= 1; diff --git a/drivers/staging/media/omap24xx/omap24xxcam.c b/drivers/staging/media/omap24xx/omap24xxcam.c index 5ca2bf5353fe..36d81e0e114c 100644 --- a/drivers/staging/media/omap24xx/omap24xxcam.c +++ b/drivers/staging/media/omap24xx/omap24xxcam.c @@ -326,7 +326,7 @@ static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb) dma->sglen++; i++; - alloc_size = (PAGE_SIZE << order); + alloc_size = PAGE_SIZE << order; /* clear pages before giving them to user space */ memset(page_address(page), 0, alloc_size); diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index e88045228607..8a52feb6e72e 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -2032,11 +2032,11 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) break; case USB_PORT_FEAT_C_CONNECTION: oz_dbg(HUB, "USB_PORT_FEAT_C_CONNECTION\n"); - clear_bits = (USB_PORT_STAT_C_CONNECTION << 16); + clear_bits = USB_PORT_STAT_C_CONNECTION << 16; break; case USB_PORT_FEAT_C_ENABLE: oz_dbg(HUB, "USB_PORT_FEAT_C_ENABLE\n"); - clear_bits = (USB_PORT_STAT_C_ENABLE << 16); + clear_bits = USB_PORT_STAT_C_ENABLE << 16; break; case USB_PORT_FEAT_C_SUSPEND: oz_dbg(HUB, "USB_PORT_FEAT_C_SUSPEND\n"); @@ -2046,7 +2046,7 @@ static int oz_clear_port_feature(struct usb_hcd *hcd, u16 wvalue, u16 windex) break; case USB_PORT_FEAT_C_RESET: oz_dbg(HUB, "USB_PORT_FEAT_C_RESET\n"); - clear_bits = (USB_PORT_FEAT_C_RESET << 16); + clear_bits = USB_PORT_FEAT_C_RESET << 16; break; case USB_PORT_FEAT_TEST: oz_dbg(HUB, "USB_PORT_FEAT_TEST\n"); diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index caf2ca3a47e7..ac6abac58bfe 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -1673,7 +1673,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val) pRegToSet = RegToSet_Normal; /* 0xb972a841; */ FactorToSet = *((u8 *)val); if (FactorToSet <= 3) { - FactorToSet = (1<<(FactorToSet + 2)); + FactorToSet = 1 << (FactorToSet + 2); if (FactorToSet > 0xf) FactorToSet = 0xf; diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c index f906317579bc..bf4cae20bd12 100644 --- a/drivers/staging/rtl8723au/hal/hal_com.c +++ b/drivers/staging/rtl8723au/hal/hal_com.c @@ -463,7 +463,7 @@ void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet) MaxAggNum = 0xF; if (FactorToSet <= 3) { - FactorToSet = (1 << (FactorToSet + 2)); + FactorToSet = 1 << (FactorToSet + 2); if (FactorToSet > MaxAggNum) FactorToSet = MaxAggNum; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 344e12f1184e..eecf6f559e29 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -358,7 +358,7 @@ device_receive_frame( if ((*pbyRsr & RSR_CRCOK) != 0) pDevice->byBasicMap |= 0x01; - dwDuration = (FrameSize << 4); + dwDuration = FrameSize << 4; dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; if (*pbyRxRate <= RATE_11M) { if (*pbyRxSts & 0x01) { diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index d5f49d2a8db3..1f6f699e238c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -4135,7 +4135,7 @@ static void XGI_SetGroup4(unsigned short ModeIdIndex, tempax -= 1; temp = (tempax & 0xFF00) >> 8; - temp = ((temp & 0x0003) << 4); + temp = (temp & 0x0003) << 4; xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); temp = (tempax & 0x00FF); xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); -- GitLab From 4475cf2ebff33bf669661daab4fa6e9eec349552 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Sat, 25 Oct 2014 01:42:09 +0530 Subject: [PATCH 1325/9457] Staging: comedi: ni_mio_common.c: fixed brace coding style issue in two places Removed unnecessary braces with the help of checkpatch.pl tool. Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index c855787e28f3..785ad7004d98 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -686,13 +686,12 @@ static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel) { unsigned bitfield; - if (channel >= 0) { + if (channel >= 0) bitfield = (ni_stc_dma_channel_select_bitfield(channel) << AI_DMA_Select_Shift) & AI_DMA_Select_Mask; - } else { + else bitfield = 0; - } ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield); } @@ -701,13 +700,12 @@ static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel) { unsigned bitfield; - if (channel >= 0) { + if (channel >= 0) bitfield = (ni_stc_dma_channel_select_bitfield(channel) << AO_DMA_Select_Shift) & AO_DMA_Select_Mask; - } else { + else bitfield = 0; - } ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield); } -- GitLab From f14557f93620f78adcf419f1adaa281947a5101d Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 24 Oct 2014 21:45:26 +0530 Subject: [PATCH 1326/9457] staging: rtl8192e: Remove unnecessary code kfree on NULL pointer is a no-op. This used the following semantic patch to identify such a instance // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // As rxb is always null at this point, so the code to kfree it and intializing it to NULL is removed completely. Suggested by: Julia Lawall Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 1c2014fd8d81..ca76ad013f5f 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1415,10 +1415,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, return 1; rx_dropped: - if (rxb != NULL) { - kfree(rxb); - rxb = NULL; - } ieee->stats.rx_dropped++; /* Returning 0 indicates to caller that we have not handled the SKB-- -- GitLab From 157b8e59fae807936cd98884dc43f90dbb0d5e57 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Fri, 24 Oct 2014 21:45:11 +0530 Subject: [PATCH 1327/9457] staging: rtl8188eu: os_dep: Remove null check before kfree This patch is generated by the following semantic patch // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index d8605be07a71..70b729f26613 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -2697,10 +2697,8 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_beacon_ie) { - kfree(pmlmepriv->wps_beacon_ie); - pmlmepriv->wps_beacon_ie = NULL; - } + kfree(pmlmepriv->wps_beacon_ie); + pmlmepriv->wps_beacon_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); @@ -2734,10 +2732,8 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_probe_resp_ie) { - kfree(pmlmepriv->wps_probe_resp_ie); - pmlmepriv->wps_probe_resp_ie = NULL; - } + kfree(pmlmepriv->wps_probe_resp_ie); + pmlmepriv->wps_probe_resp_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); @@ -2766,10 +2762,8 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par ie_len = len-12-2;/* 12 = param header, 2:no packed */ - if (pmlmepriv->wps_assoc_resp_ie) { - kfree(pmlmepriv->wps_assoc_resp_ie); - pmlmepriv->wps_assoc_resp_ie = NULL; - } + kfree(pmlmepriv->wps_assoc_resp_ie); + pmlmepriv->wps_assoc_resp_ie = NULL; if (ie_len > 0) { pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); -- GitLab From 0297ac39fae9edcccf8752a53e6ce6f903469c4f Mon Sep 17 00:00:00 2001 From: tssurya Date: Sat, 25 Oct 2014 00:37:33 +0530 Subject: [PATCH 1328/9457] Staging: comedi: ni_tiocmd: fixed a brace coding style issue Removed unneeded braces with the help of checkpatch.pl tool. Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 26e7291c4a51..46cf3eb2ee54 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -371,9 +371,8 @@ static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, of gate interrupt via dma read/write and report bogus gate errors */ if (counter->counter_dev->variant != - ni_gpct_variant_660x) { + ni_gpct_variant_660x) *gate_error = 1; - } } } if (gxx_status & GI_TC_ERROR(cidx)) { -- GitLab From 00e053bd9f7a86a8ed8f9a057dc994b610e3add7 Mon Sep 17 00:00:00 2001 From: WANG Chao Date: Tue, 14 Oct 2014 16:58:37 +0800 Subject: [PATCH 1329/9457] staging, unisys: remove leftover function kmalloc_kernel() kmalloc_kernel() previously declared in timskmodutils.h which recently got removed. Now also remove kmalloc_kernel(), because it's not used anywhere. Signed-off-by: WANG Chao Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorutil/visorkmodutils.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/unisys/visorutil/visorkmodutils.c b/drivers/staging/unisys/visorutil/visorkmodutils.c index d6815f9e1337..64b135d83c0d 100644 --- a/drivers/staging/unisys/visorutil/visorkmodutils.c +++ b/drivers/staging/unisys/visorutil/visorkmodutils.c @@ -36,16 +36,6 @@ int unisys_spar_platform; EXPORT_SYMBOL_GPL(unisys_spar_platform); -/** Callers to interfaces that set __GFP_NORETRY flag below - * must check for a NULL (error) result as we are telling the - * kernel interface that it is okay to fail. - */ - -void *kmalloc_kernel(size_t siz) -{ - return kmalloc(siz, GFP_KERNEL | __GFP_NORETRY); -} - static __init uint32_t visorutil_spar_detect(void) { -- GitLab From 1846472c911ce93fd6a140d821f5a393ac639cc0 Mon Sep 17 00:00:00 2001 From: Shrikrishna Khare Date: Sat, 18 Oct 2014 15:57:37 -0700 Subject: [PATCH 1330/9457] Staging: unisys: visorutil: easyproc: fixed a line over 80 characters coding style issue Fixed a coding style issue. Signed-off-by: Shrikrishna Khare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorutil/easyproc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/visorutil/easyproc.c b/drivers/staging/unisys/visorutil/easyproc.c index 3b388494e2af..40f1ae9a155c 100644 --- a/drivers/staging/unisys/visorutil/easyproc.c +++ b/drivers/staging/unisys/visorutil/easyproc.c @@ -254,9 +254,9 @@ void visor_easyproc_CreateDeviceProperty(struct easyproc_device_info *p, } strcpy(px->property_name, property_name); if (px->procEntry == NULL) { - ERRDEVX(p->devno, "failed to register /proc/%s/device/%d/%s entry", - p->pdriver->ProcId, p->devno, property_name - ); + ERRDEVX(p->devno, + "failed to register /proc/%s/device/%d/%s entry", + p->pdriver->ProcId, p->devno, property_name); return; } px->show_device_property_info = show_property_info; -- GitLab From df55a1fadf4a542a2457288178354bf47321f75a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:40 -0400 Subject: [PATCH 1331/9457] staging: unisys: clean up bracing in vbuschannel_sanitize_buffer() The bracing in vbuschannel_sanitize_buffer() in vbusdeviceinfo.h is messy. Clean these up. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/vbusdeviceinfo.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index f13dddc1b5c8..58b64a3ac6eb 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -63,8 +63,9 @@ vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) p++; remain--; chars++; - } else if (p == NULL) + } else if (p == NULL) { chars++; + } nonprintable_streak = 0; } if (remain > 0) { @@ -72,10 +73,12 @@ vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) p++; remain--; chars++; - } else if (p == NULL) + } else if (p == NULL) { chars++; - } else + } + } else { nonprintable_streak = 1; + } src++; srcmax--; } -- GitLab From a6208124b260f2cdfa5470bd4de1a190db728294 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:41 -0400 Subject: [PATCH 1332/9457] staging: unisys: fix indentation on vbuschannel_devinfo_to_string() Fix the parameter indentation for vbuschannel_devinfo_to_string(), in vbusdeviceinfo.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 58b64a3ac6eb..de0447c97df4 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -151,7 +151,7 @@ vbuschannel_itoa(char *p, int remain, int num) */ static inline int vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, - char *p, int remain, int devix) + char *p, int remain, int devix) { char *psrc; int nsrc, x, i, pad; -- GitLab From 8d507c664d99ccb6885e76718b9b95c5911746d6 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:42 -0400 Subject: [PATCH 1333/9457] staging: unisys: clean up extra parens in vbuschannel_devinfo_to_string Get rid of the unnecessary parenthesis in several assignments in vbuschannel_devinfo_to_string(). Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index de0447c97df4..28864a89908c 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -157,7 +157,7 @@ vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, int nsrc, x, i, pad; int chars = 0; - psrc = &(devinfo->devtype[0]); + psrc = &devinfo->devtype[0]; nsrc = sizeof(devinfo->devtype); if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0) return 0; @@ -187,7 +187,7 @@ vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit driver name */ - psrc = &(devinfo->drvname[0]); + psrc = &devinfo->drvname[0]; nsrc = sizeof(devinfo->drvname); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; @@ -199,7 +199,7 @@ vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); /* emit strings */ - psrc = &(devinfo->infostrs[0]); + psrc = &devinfo->infostrs[0]; nsrc = sizeof(devinfo->infostrs); x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); p += x; -- GitLab From 0d2400c35824cb37cae83d6a039166a5067bf047 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:43 -0400 Subject: [PATCH 1334/9457] staging: unisys: delete extra space character in vbuschannel_itoa() There's no need for that extra space in the typecast in vbuschannel_itoa(), so just delete it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 28864a89908c..9b6d3e69355c 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -118,7 +118,7 @@ vbuschannel_itoa(char *p, int remain, int num) } /* form a backwards decimal ascii string in */ while (num > 0) { - if (digits >= (int) sizeof(s)) + if (digits >= (int)sizeof(s)) return 0; s[digits++] = (num % 10) + '0'; num = num / 10; -- GitLab From 753541ccead2353fa1afa34328cab79e791d5f05 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:44 -0400 Subject: [PATCH 1335/9457] staging: unisys: fix typedef for VMCALL_MONITOR_INTERFACE_METHOD_TUPLE Get rid of the typedef for VMCALL_MONITOR_INTERFACE_METHOD_TUPLE in favor of enum vmcall_monitor_interface_method_tuple. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vmcallinterface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index 7750086e5bb3..f19e29c003d1 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -33,7 +33,7 @@ /* define subsystem number for AppOS, used in uislib driver */ #define MDS_APPOS 0x4000000000000000L /* subsystem = 62 - AppOS */ -typedef enum { /* VMCALL identification tuples */ +enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ /* Note: when a new VMCALL is added: * - the 1st 2 hex digits correspond to one of the * VMCALL_MONITOR_INTERFACE types and @@ -66,7 +66,7 @@ typedef enum { /* VMCALL identification tuples */ * ULTRA_SERVICE_CAPABILITY_TIME * capable guest to make * VMCALL */ -} VMCALL_MONITOR_INTERFACE_METHOD_TUPLE; +}; #define VMCALL_SUCCESS 0 #define VMCALL_SUCCESSFUL(result) (result == 0) -- GitLab From d835a90c81fd13f936a6c5377caac7c61db91081 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:45 -0400 Subject: [PATCH 1336/9457] staging: unisys: fix CamelCase in ISSUE_IO_VMCALL macros Fix the parameter name in ISSUE_IO_VMCALL and ISSUE_IO_EXTENDED_VMCALL. Fix CamelCase names: InterfaceMethod => method Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/vmcallinterface.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index f19e29c003d1..cc8ed6e4cdb4 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -76,12 +76,12 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ __unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx) #define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \ __unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx) -#define ISSUE_IO_VMCALL(InterfaceMethod, param, result) \ - (result = unisys_vmcall(InterfaceMethod, (param) & 0xFFFFFFFF, \ +#define ISSUE_IO_VMCALL(method, param, result) \ + (result = unisys_vmcall(method, (param) & 0xFFFFFFFF, \ (param) >> 32)) -#define ISSUE_IO_EXTENDED_VMCALL(InterfaceMethod, param1, param2, \ +#define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, \ param3, result) \ - (result = unisys_extended_vmcall(InterfaceMethod, param1, \ + (result = unisys_extended_vmcall(method, param1, \ param2, param3)) /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently -- GitLab From eb44bd3f43429fcedde1aaff3e83badf17c8b3d9 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:46 -0400 Subject: [PATCH 1337/9457] staging: unisys: get rid of IO_DATA_STRUCTURE typedef Nobody was using this, so just remove it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vmcallinterface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h index cc8ed6e4cdb4..78333719c496 100644 --- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h +++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h @@ -107,7 +107,6 @@ struct phys_info { #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ -typedef struct phys_info IO_DATA_STRUCTURE; /* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */ /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ -- GitLab From 9eee5d1f3ee1922d5153f732149dcf0c0a26581f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:47 -0400 Subject: [PATCH 1338/9457] staging: unisys: fix CamelCase channel constants The channel definitions in channel_guid.h contain several CamelCase constants. Fix these so they are no longer incorrectly cased, and use the name spar instead of the old "ultra" reference. Also, rename the corresponding UUID macros to match. Update all references to constants or UUID macros that were changed. Fix CamelCase names: UltraVhbaChannelProtocolGuid => spar_vhba_channel_protocol_uuid UltraVnicChannelProtocolGuid => spar_vnic_channel_protocol_uuid UltraSIOVMGuid => spar_siovm_uuid UltraControlDirectorChannelProtocolGuid => spar_controldirector_channel_protocol_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/channel_guid.h | 24 +++++++++---------- .../common-spar/include/channels/iochannel.h | 12 +++++----- drivers/staging/unisys/uislib/uislib.c | 22 ++++++++--------- .../unisys/visorchipset/visorchipset_main.c | 8 ++++--- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h index 63c67ca4c9ec..16df33a751a6 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h @@ -20,44 +20,44 @@ /* Used in IOChannel * {414815ed-c58c-11da-95a9-00e08161165f} */ -#define ULTRA_VHBA_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x414815ed, 0xc58c, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVhbaChannelProtocolGuid = - ULTRA_VHBA_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vhba_channel_protocol_uuid = + SPAR_VHBA_CHANNEL_PROTOCOL_UUID; /* Used in IOChannel * {8cd5994d-c58e-11da-95a9-00e08161165f} */ -#define ULTRA_VNIC_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVnicChannelProtocolGuid = - ULTRA_VNIC_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vnic_channel_protocol_uuid = + SPAR_VNIC_CHANNEL_PROTOCOL_UUID; /* Used in IOChannel * {72120008-4AAB-11DC-8530-444553544200} */ -#define ULTRA_SIOVM_GUID \ +#define SPAR_SIOVM_UUID \ UUID_LE(0x72120008, 0x4AAB, 0x11DC, \ 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) -static const uuid_le UltraSIOVMGuid = ULTRA_SIOVM_GUID; +static const uuid_le spar_siovm_uuid = SPAR_SIOVM_UUID; /* Used in visornoop/visornoop_main.c * {5b52c5ac-e5f5-4d42-8dff-429eaecd221f} */ -#define ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID \ +#define SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x5b52c5ac, 0xe5f5, 0x4d42, \ 0x8d, 0xff, 0x42, 0x9e, 0xae, 0xcd, 0x22, 0x1f) -static const uuid_le UltraControlDirectorChannelProtocolGuid = - ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_controldirector_channel_protocol_uuid = + SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID; /* Used in visorchipset/visorchipset_main.c * {B4E79625-AEDE-4EAA-9E11-D3EDDCD4504C} */ -#define ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID \ +#define SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID \ UUID_LE(0xb4e79625, 0xaede, 0x4eaa, \ 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 806d5b3bca48..7de87a481a8c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -61,23 +61,23 @@ #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1 #define ULTRA_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVhbaChannelProtocolGuid, \ + (ULTRA_check_channel_client(pChannel, spar_vhba_channel_protocol_uuid, \ "vhba", MIN_IO_CHANNEL_SIZE, \ ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE, \ __FILE__, __LINE__, logCtx)) #define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVhbaChannelProtocolGuid, \ + (ULTRA_check_channel_server(spar_vhba_channel_protocol_uuid, \ "vhba", MIN_IO_CHANNEL_SIZE, actualBytes, \ __FILE__, __LINE__, logCtx)) #define ULTRA_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVnicChannelProtocolGuid, \ + (ULTRA_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ "vnic", MIN_IO_CHANNEL_SIZE, \ ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE, \ __FILE__, __LINE__, logCtx)) #define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVnicChannelProtocolGuid, \ + (ULTRA_check_channel_server(spar_vnic_channel_protocol_uuid, \ "vnic", MIN_IO_CHANNEL_SIZE, actualBytes, \ __FILE__, __LINE__, logCtx)) #define ULTRA_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ @@ -807,7 +807,7 @@ static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = UltraVhbaChannelProtocolGuid; + x->ChannelHeader.Type = spar_vhba_channel_protocol_uuid; x->ChannelHeader.ZoneGuid = NULL_UUID_LE; x->vhba.wwnn = *wwnn; x->vhba.max = *max; @@ -843,7 +843,7 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = UltraVnicChannelProtocolGuid; + x->ChannelHeader.Type = spar_vnic_channel_protocol_uuid; x->ChannelHeader.ZoneGuid = NULL_UUID_LE; memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); x->vnic.num_rcv_bufs = num_rcv_bufs; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index b1f6c6ef801b..35e8a61c7202 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -443,7 +443,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) struct guest_msgs cmd; if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { wait_for_valid_guid(&((CHANNEL_HEADER __iomem *) (dev-> chanptr))-> @@ -468,7 +468,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) cmd.add_vhba.intr = dev->intr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { wait_for_valid_guid(&((CHANNEL_HEADER __iomem *) (dev-> chanptr))-> @@ -585,11 +585,11 @@ pause_device(CONTROLVM_MESSAGE *msg) * guest_msgs struct to callback */ if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_PAUSE_VHBA; cmd.pause_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_PAUSE_VNIC; cmd.pause_vnic.chanptr = dev->chanptr; } else { @@ -654,11 +654,11 @@ resume_device(CONTROLVM_MESSAGE *msg) */ if (retval == CONTROLVM_RESP_SUCCESS) { if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_RESUME_VHBA; cmd.resume_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_RESUME_VNIC; cmd.resume_vnic.chanptr = dev->chanptr; } else { @@ -724,11 +724,11 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) * guest_msgs struct to callback */ if (!uuid_le_cmp(dev->channel_uuid, - UltraVhbaChannelProtocolGuid)) { + spar_vhba_channel_protocol_uuid)) { cmd.msgtype = GUEST_DEL_VHBA; cmd.del_vhba.chanptr = dev->chanptr; } else if (!uuid_le_cmp(dev->channel_uuid, - UltraVnicChannelProtocolGuid)) { + spar_vnic_channel_protocol_uuid)) { cmd.msgtype = GUEST_DEL_VNIC; cmd.del_vnic.chanptr = dev->chanptr; } else { @@ -960,7 +960,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, return 0; } msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid; + msg.cmd.createDevice.dataTypeGuid = spar_vhba_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA create_device failed.\n"); POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1019,7 +1019,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, return 0; } msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; + msg.cmd.createDevice.dataTypeGuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC create_device failed.\n"); POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1109,7 +1109,7 @@ uislib_client_add_vnic(u32 busNo) memset(&msg.cmd.createDevice.intr, 0, sizeof(struct irq_info)); msg.cmd.createDevice.channelAddr = PhysicalDataChan; msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE; - msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid; + msg.cmd.createDevice.dataTypeGuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("client create_device failed"); goto AwayCleanup; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index ee03c59dc889..cfacf17ad26a 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -80,7 +80,7 @@ static CONTROLVM_MESSAGE_HEADER g_DiagMsgHdr; static CONTROLVM_MESSAGE_HEADER g_ChipSetMsgHdr; static CONTROLVM_MESSAGE_HEADER g_DelDumpMsgHdr; static const uuid_le UltraDiagPoolChannelProtocolGuid = - ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID; + SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID; /* 0xffffff is an invalid Bus/Device number */ static ulong g_diagpoolBusNo = 0xffffff; static ulong g_diagpoolDevNo = 0xffffff; @@ -90,8 +90,10 @@ static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket; * "visorhackbus") */ #define FOR_VISORHACKBUS(channel_type_guid) \ - (((uuid_le_cmp(channel_type_guid, UltraVnicChannelProtocolGuid) == 0)\ - || (uuid_le_cmp(channel_type_guid, UltraVhbaChannelProtocolGuid) == 0))) + (((uuid_le_cmp(channel_type_guid,\ + spar_vnic_channel_protocol_uuid) == 0)\ + || (uuid_le_cmp(channel_type_guid,\ + spar_vhba_channel_protocol_uuid) == 0))) #define FOR_VISORBUS(channel_type_guid) (!(FOR_VISORHACKBUS(channel_type_guid))) #define is_diagpool_channel(channel_type_guid) \ -- GitLab From 4d08ae26accfa5189a9a22c65b593be92f67db8d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:48 -0400 Subject: [PATCH 1339/9457] staging: unisys: clean up stray blank lines in channel_guid.h Just remove extra blank lines in channel_guid.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/channel_guid.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h index 16df33a751a6..706363fc3e9a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel_guid.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel_guid.h @@ -43,7 +43,6 @@ static const uuid_le spar_vnic_channel_protocol_uuid = 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) static const uuid_le spar_siovm_uuid = SPAR_SIOVM_UUID; - /* Used in visornoop/visornoop_main.c * {5b52c5ac-e5f5-4d42-8dff-429eaecd221f} */ @@ -60,5 +59,3 @@ static const uuid_le spar_controldirector_channel_protocol_uuid = #define SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID \ UUID_LE(0xb4e79625, 0xaede, 0x4eaa, \ 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c) - - -- GitLab From e2706697fd6a08fa7457d30bb4f7d8bc4d7c36b9 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:49 -0400 Subject: [PATCH 1340/9457] staging: unisys: remove channel mismatch macros Simplify the code in channel.h by removing CHANNEL_GUID_MISMATCH, CHANNEL_u64_MISMATCH, and CHANNEL_U32_MISMATCH, and printing the messages directly instead. The CamelCase names in the functions that used to use these macros will be fixed in a later patch. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 90 +++++++------------ 1 file changed, 30 insertions(+), 60 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c25dfbf7f6bc..27de674b6432 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -50,33 +50,6 @@ #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') -#define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=%pUL actual=%pUL @%s:%d\n", \ - chName, &chType, field, \ - &expected, &actual, \ - fil, lin); \ - } while (0) -#define CHANNEL_U32_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8lx actual=0x%-8.8lx @%s:%d\n", \ - chName, &chType, field, \ - (unsigned long)expected, (unsigned long)actual, \ - fil, lin); \ - } while (0) - -#define CHANNEL_U64_MISMATCH(chType, chName, field, expected, actual, fil, \ - lin, logCtx) \ - do { \ - pr_err("Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8Lx actual=0x%-8.8Lx @%s:%d\n", \ - chName, &chType, field, \ - (unsigned long long)expected, \ - (unsigned long long)actual, \ - fil, lin); \ - } while (0) - #define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \ LineNumber, Str, args...) \ pr_info(Str, ## args) @@ -355,48 +328,45 @@ ULTRA_check_channel_client(void __iomem *pChannel, sizeof(guid)); /* caller wants us to verify type GUID */ if (uuid_le_cmp(guid, expectedTypeGuid) != 0) { - CHANNEL_GUID_MISMATCH(expectedTypeGuid, channelName, - "type", expectedTypeGuid, - guid, fileName, - lineNumber, logCtx); + pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", + channelName, &expectedTypeGuid, + &expectedTypeGuid, &guid); return 0; } } - if (expectedMinBytes > 0) /* caller wants us to verify + if (expectedMinBytes > 0) { /* caller wants us to verify * channel size */ - if (readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Size) < expectedMinBytes) { - CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName, - "size", expectedMinBytes, - readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Size), - fileName, - lineNumber, logCtx); + unsigned long long bytes = readq(&((CHANNEL_HEADER __iomem *) + (pChannel))->Size); + if (bytes < expectedMinBytes) { + pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + channelName, &expectedTypeGuid, + (unsigned long long)expectedMinBytes, bytes); return 0; } - if (expectedVersionId > 0) /* caller wants us to verify + } + if (expectedVersionId > 0) { /* caller wants us to verify * channel version */ - if (readl(&((CHANNEL_HEADER __iomem *) (pChannel))->VersionId) - != expectedVersionId) { - CHANNEL_U32_MISMATCH(expectedTypeGuid, channelName, - "version", expectedVersionId, - readl(&((CHANNEL_HEADER __iomem *) - (pChannel))->VersionId), - fileName, lineNumber, logCtx); + unsigned long ver = readl(&((CHANNEL_HEADER __iomem *) + (pChannel))->VersionId); + if (ver != expectedVersionId) { + pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n", + channelName, &expectedTypeGuid, + (unsigned long)expectedVersionId, ver); return 0; } - if (expectedSignature > 0) /* caller wants us to verify + } + if (expectedSignature > 0) { /* caller wants us to verify * channel signature */ - if (readq(&((CHANNEL_HEADER __iomem *) (pChannel))->Signature) - != expectedSignature) { - CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName, - "signature", expectedSignature, - readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Signature), - fileName, - lineNumber, logCtx); + unsigned long long sig = readq(&((CHANNEL_HEADER __iomem *) + (pChannel))->Signature); + if (sig != expectedSignature) { + pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n", + channelName, &expectedTypeGuid, + expectedSignature, sig); return 0; } + } return 1; } @@ -415,9 +385,9 @@ ULTRA_check_channel_server(uuid_le typeGuid, if (expectedMinBytes > 0) /* caller wants us to verify * channel size */ if (actualBytes < expectedMinBytes) { - CHANNEL_U64_MISMATCH(typeGuid, channelName, "size", - expectedMinBytes, actualBytes, - fileName, lineNumber, logCtx); + pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n", + channelName, &typeGuid, expectedMinBytes, + actualBytes); return 0; } return 1; -- GitLab From ddb38ae6441be221f42bf30cbd8f3fce68cc204f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:50 -0400 Subject: [PATCH 1341/9457] staging: unisys: get rid of UltraLogEvent macro Remove the UltraLogEvent macro from channel.h, and fix all references so they call pr_info directly. CamelCase names used by functions that called UltraLogEvent will be fixed in later patches. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 140 ++++++------------ 1 file changed, 48 insertions(+), 92 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 27de674b6432..d5102785c77b 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -50,10 +50,6 @@ #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') -#define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \ - LineNumber, Str, args...) \ - pr_info(Str, ## args) - typedef enum { CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ CHANNELSRV_READY = 1 /* channel has been initialized by server */ @@ -122,19 +118,14 @@ ULTRA_CHANNELCLI_STRING(u32 v) file, line) \ do { \ if (!ULTRA_VALID_CHANNELCLI_TRANSITION(old, new)) \ - UltraLogEvent(logCtx, \ - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, \ - CHANNELSTATE_DIAG_SEVERITY, \ - CHANNELSTATE_DIAG_SUBSYS, \ - __func__, __LINE__, \ - "%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliState", \ - ULTRA_CHANNELCLI_STRING(old), \ - old, \ - ULTRA_CHANNELCLI_STRING(new), \ - new, \ - PathName_Last_N_Nodes((u8 *)file, 4), \ - line); \ + pr_info("%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ + chanId, "CliState", \ + ULTRA_CHANNELCLI_STRING(old), \ + old, \ + ULTRA_CHANNELCLI_STRING(new), \ + new, \ + PathName_Last_N_Nodes((u8 *)file, 4), \ + line); \ } while (0) #define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \ @@ -145,20 +136,16 @@ ULTRA_CHANNELCLI_STRING(u32 v) (pChan))->CliStateOS)), \ newstate, \ chanId, logCtx, __FILE__, __LINE__); \ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, \ - CHANNELSTATE_DIAG_SEVERITY, \ - CHANNELSTATE_DIAG_SUBSYS, \ - __func__, __LINE__, \ - "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliStateOS", \ - ULTRA_CHANNELCLI_STRING( \ + pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ + chanId, "CliStateOS", \ + ULTRA_CHANNELCLI_STRING( \ readl(&((CHANNEL_HEADER __iomem *) \ (pChan))->CliStateOS)), \ - readl(&((CHANNEL_HEADER __iomem *) \ + readl(&((CHANNEL_HEADER __iomem *) \ (pChan))->CliStateOS), \ - ULTRA_CHANNELCLI_STRING(newstate), \ - newstate, \ - PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ + ULTRA_CHANNELCLI_STRING(newstate), \ + newstate, \ + PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ writel(newstate, &((CHANNEL_HEADER __iomem *) \ (pChan))->CliStateOS); \ mb(); /* required for channel synch */ \ @@ -439,30 +426,22 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, &pChan->CliErrorOS); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", - chanId, PathName_Last_N_Nodes( - (u8 *) file, 4), line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", + chanId, PathName_Last_N_Nodes((u8 *) file, 4), + line); } return 0; } if ((readl(&pChan->CliStateOS) != CHANNELCLI_OWNED) && (readl(&pChan->CliStateBoot) == CHANNELCLI_DISABLED)) { /* Our competitor is DISABLED, so we can transition to OWNED */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", - chanId, "CliStateOS", - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), - CHANNELCLI_OWNED, - PathName_Last_N_Nodes((u8 *) file, 4), line); + pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", + chanId, "CliStateOS", + ULTRA_CHANNELCLI_STRING(readl(&pChan->CliStateOS)), + readl(&pChan->CliStateOS), + ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), + CHANNELCLI_OWNED, + PathName_Last_N_Nodes((u8 *) file, 4), line); writel(CHANNELCLI_OWNED, &pChan->CliStateOS); mb(); /* required for channel synch */ } @@ -470,13 +449,9 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, if (readb(&pChan->CliErrorOS) != 0) { /* we are in an error msg throttling state; * come out of it */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, - 4), line); + pr_info("%s Channel OS client acquire now successful @%s:%d\n", + chanId, PathName_Last_N_Nodes((u8 *) file, 4), + line); writeb(0, &pChan->CliErrorOS); } return 1; @@ -493,17 +468,12 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED, &pChan->CliErrorOS); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n", - chanId, - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - PathName_Last_N_Nodes((u8 *) file, 4), - line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n", + chanId, ULTRA_CHANNELCLI_STRING( + readl(&pChan->CliStateOS)), + readl(&pChan->CliStateOS), + PathName_Last_N_Nodes((u8 *) file, 4), + line); } return 0; } @@ -517,13 +487,9 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, ULTRA_CLIERROROS_THROTTLEMSG_BUSY, &pChan->CliErrorOS); /* throttle until acquire successful */ - UltraLogEvent(logCtx, - CHANNELSTATE_DIAG_EVENTID_TRANSITBUSY, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, - 4), line); + pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", + chanId, PathName_Last_N_Nodes((u8 *) file, 4), + line); } /* reset busy */ writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); @@ -532,12 +498,9 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, } if (readb(&pChan->CliErrorOS) != 0) { /* we are in an error msg throttling state; come out of it */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), - line); + pr_info("%s Channel OS client acquire now successful @%s:%d\n", + chanId, PathName_Last_N_Nodes((u8 *) file, 4), + line); writeb(0, &pChan->CliErrorOS); } return 1; @@ -551,26 +514,19 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, if (readb(&pChan->CliErrorOS) != 0) { /* we are in an error msg throttling state; come out of it */ - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel OS client error state cleared @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), - line); + pr_info("%s Channel OS client error state cleared @%s:%d\n", + chanId, PathName_Last_N_Nodes((u8 *) file, 4), + line); writeb(0, &pChan->CliErrorOS); } if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) return; if (readl(&pChan->CliStateOS) != CHANNELCLI_BUSY) { - UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITERR, - CHANNELSTATE_DIAG_SEVERITY, - CHANNELSTATE_DIAG_SUBSYS, func, line, - "%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n", - chanId, - ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), - PathName_Last_N_Nodes((u8 *) file, 4), line); + pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n", + chanId, ULTRA_CHANNELCLI_STRING( + readl(&pChan->CliStateOS)), + readl(&pChan->CliStateOS), + PathName_Last_N_Nodes((u8 *) file, 4), line); /* return; */ } writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */ -- GitLab From 1e73f4b53344b1c213e110383fb0f178e1ff4368 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:51 -0400 Subject: [PATCH 1342/9457] staging: unisys: remove typedef for CHANNEL_SERVERSTATE Remove the typedef for CHANNEL_SERVERSTATE and use enum channel_serverstate instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/channel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index d5102785c77b..8c54adf724ed 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -50,10 +50,10 @@ #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') -typedef enum { +enum channel_serverstate { CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ CHANNELSRV_READY = 1 /* channel has been initialized by server */ -} CHANNEL_SERVERSTATE; +}; typedef enum { CHANNELCLI_DETACHED = 0, -- GitLab From 9831a29a384513c2c1a16c10f9ad619e112c10c0 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:52 -0400 Subject: [PATCH 1343/9457] staging: unisys: get rid of typedef for CHANNEL_CLIENTSTATE Remove the typedef for CHANNEL_CLIENTSTATE and just use enum channel_clientstate instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/channel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 8c54adf724ed..304f81b96d2a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -55,7 +55,7 @@ enum channel_serverstate { CHANNELSRV_READY = 1 /* channel has been initialized by server */ }; -typedef enum { +enum channel_clientstate { CHANNELCLI_DETACHED = 0, CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT * allowed to use it unless given TBD @@ -69,7 +69,7 @@ typedef enum { * using channel */ CHANNELCLI_OWNED = 5 /* "no worries" state - client can * access channel anytime */ -} CHANNEL_CLIENTSTATE; +}; static inline const u8 * ULTRA_CHANNELCLI_STRING(u32 v) { -- GitLab From 09a5073b822853b48f323dceb0fc999746407621 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:53 -0400 Subject: [PATCH 1344/9457] staging: unisys: fix missing blank line after enum channel_clientstate The enumeration needs to have a blank line after it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/channel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 304f81b96d2a..f32ec8496b22 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -70,6 +70,7 @@ enum channel_clientstate { CHANNELCLI_OWNED = 5 /* "no worries" state - client can * access channel anytime */ }; + static inline const u8 * ULTRA_CHANNELCLI_STRING(u32 v) { -- GitLab From 82d72bee4b5c7352be0a54747da6e206ea8893d5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:54 -0400 Subject: [PATCH 1345/9457] staging: unisys: fix spacing in ULTRA_CHANNELCLI_STRING Remove all the extraneous spaces in typecasts in ULTRA_CHANNELCLI_STRING(). Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/channel.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index f32ec8496b22..c77e9c7afcd9 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -76,21 +76,21 @@ ULTRA_CHANNELCLI_STRING(u32 v) { switch (v) { case CHANNELCLI_DETACHED: - return (const u8 *) ("DETACHED"); + return (const u8 *)("DETACHED"); case CHANNELCLI_DISABLED: - return (const u8 *) ("DISABLED"); + return (const u8 *)("DISABLED"); case CHANNELCLI_ATTACHING: - return (const u8 *) ("ATTACHING"); + return (const u8 *)("ATTACHING"); case CHANNELCLI_ATTACHED: - return (const u8 *) ("ATTACHED"); + return (const u8 *)("ATTACHED"); case CHANNELCLI_BUSY: - return (const u8 *) ("BUSY"); + return (const u8 *)("BUSY"); case CHANNELCLI_OWNED: - return (const u8 *) ("OWNED"); + return (const u8 *)("OWNED"); default: break; } - return (const u8 *) ("?"); + return (const u8 *)("?"); } #define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY) -- GitLab From 9fd1b95aab5f4e72e8516e0a8b6dcb7dd6217d09 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:55 -0400 Subject: [PATCH 1346/9457] staging: unisys: remove typedef for CHANNEL_HEADER Switch everywhere that CHANNEL_HEADER, pCHANNEL_HEADER, or ULTRA_CHANNEL_PROTOCOL was used, to struct channel_header. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 10 ++-- drivers/staging/unisys/channels/chanstub.c | 4 +- drivers/staging/unisys/channels/chanstub.h | 8 ++-- .../common-spar/include/channels/channel.h | 47 ++++++++++--------- .../include/channels/controlvmchannel.h | 2 +- .../include/channels/diagchannel.h | 4 +- .../common-spar/include/channels/iochannel.h | 2 +- .../include/channels/vbuschannel.h | 2 +- drivers/staging/unisys/include/uisqueue.h | 2 +- drivers/staging/unisys/uislib/uislib.c | 12 +++-- drivers/staging/unisys/virthba/virthba.c | 4 +- drivers/staging/unisys/virtpci/virtpci.c | 6 +-- .../unisys/visorchannel/visorchannel_funcs.c | 30 +++++++----- .../unisys/visorchipset/visorchipset_main.c | 2 +- 14 files changed, 73 insertions(+), 62 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index b4bdee4b575b..2033b3b8a11f 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -44,7 +44,8 @@ * 1 if the insertion succeeds, 0 if the queue was full. */ unsigned char -visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) +visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, + void *pSignal) { void __iomem *psignal; unsigned int head, tail, nof; @@ -102,7 +103,8 @@ EXPORT_SYMBOL_GPL(visor_signal_insert); * 1 if the removal succeeds, 0 if the queue was empty. */ unsigned char -visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) +visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, + void *pSignal) { void __iomem *psource; unsigned int head, tail; @@ -157,7 +159,7 @@ EXPORT_SYMBOL_GPL(visor_signal_remove); * # of signals copied. */ unsigned int -SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) +SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) { void *psource; unsigned int head, tail, signalCount = 0; @@ -208,7 +210,7 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) * 1 if the signal queue is empty, 0 otherwise. */ unsigned char -visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, u32 Queue) +visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue) { SIGNAL_QUEUE_HEADER __iomem *pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c index d54c5d635a94..23d5aafef2cd 100644 --- a/drivers/staging/unisys/channels/chanstub.c +++ b/drivers/staging/unisys/channels/chanstub.c @@ -42,7 +42,7 @@ channel_mod_exit(void) } unsigned char -SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, +SignalInsert_withLock(struct channel_header __iomem *pChannel, u32 Queue, void *pSignal, spinlock_t *lock) { unsigned char result; @@ -55,7 +55,7 @@ SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, } unsigned char -SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, +SignalRemove_withLock(struct channel_header __iomem *pChannel, u32 Queue, void *pSignal, spinlock_t *lock) { unsigned char result; diff --git a/drivers/staging/unisys/channels/chanstub.h b/drivers/staging/unisys/channels/chanstub.h index d08e2c69d2ad..1531759a1b31 100644 --- a/drivers/staging/unisys/channels/chanstub.h +++ b/drivers/staging/unisys/channels/chanstub.h @@ -15,9 +15,9 @@ #ifndef __CHANSTUB_H__ #define __CHANSTUB_H__ -unsigned char SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal, spinlock_t *lock); -unsigned char SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal, spinlock_t *lock); +unsigned char SignalInsert_withLock(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal, spinlock_t *lock); +unsigned char SignalRemove_withLock(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal, spinlock_t *lock); #endif diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c77e9c7afcd9..a71bac0526b2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -133,21 +133,21 @@ ULTRA_CHANNELCLI_STRING(u32 v) newstate, logCtx) \ do { \ ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \ - readl(&(((CHANNEL_HEADER __iomem *) \ + readl(&(((struct channel_header __iomem *) \ (pChan))->CliStateOS)), \ newstate, \ chanId, logCtx, __FILE__, __LINE__); \ pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ chanId, "CliStateOS", \ ULTRA_CHANNELCLI_STRING( \ - readl(&((CHANNEL_HEADER __iomem *) \ + readl(&((struct channel_header __iomem *)\ (pChan))->CliStateOS)), \ - readl(&((CHANNEL_HEADER __iomem *) \ + readl(&((struct channel_header __iomem *) \ (pChan))->CliStateOS), \ ULTRA_CHANNELCLI_STRING(newstate), \ newstate, \ PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ - writel(newstate, &((CHANNEL_HEADER __iomem *) \ + writel(newstate, &((struct channel_header __iomem *) \ (pChan))->CliStateOS); \ mb(); /* required for channel synch */ \ } while (0) @@ -200,18 +200,18 @@ ULTRA_CHANNELCLI_STRING(u32 v) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ /* Common Channel Header */ -typedef struct _CHANNEL_HEADER { +struct channel_header { u64 Signature; /* Signature */ u32 LegacyState; /* DEPRECATED - being replaced by */ /* / SrvState, CliStateBoot, and CliStateOS below */ - u32 HeaderSize; /* sizeof(CHANNEL_HEADER) */ + u32 HeaderSize; /* sizeof(struct channel_header) */ u64 Size; /* Total size of this channel in bytes */ u64 Features; /* Flags to modify behavior */ uuid_le Type; /* Channel type: data, bus, control, etc. */ u64 PartitionHandle; /* ID of guest partition */ u64 Handle; /* Device number of this channel in client */ u64 oChannelSpace; /* Offset in bytes to channel specific area */ - u32 VersionId; /* CHANNEL_HEADER Version ID */ + u32 VersionId; /* struct channel_header Version ID */ u32 PartitionIndex; /* Index of guest partition */ uuid_le ZoneGuid; /* Guid of Channel's zone */ u32 oClientString; /* offset from channel header to @@ -238,7 +238,7 @@ typedef struct _CHANNEL_HEADER { u8 Filler[1]; /* Pad out to 128 byte cacheline */ /* Please add all new single-byte values below here */ u8 RecoverChannel; -} CHANNEL_HEADER, *pCHANNEL_HEADER, ULTRA_CHANNEL_PROTOCOL; +}; #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0) @@ -312,7 +312,8 @@ ULTRA_check_channel_client(void __iomem *pChannel, uuid_le guid; memcpy_fromio(&guid, - &((CHANNEL_HEADER __iomem *)(pChannel))->Type, + &((struct channel_header __iomem *) + (pChannel))->Type, sizeof(guid)); /* caller wants us to verify type GUID */ if (uuid_le_cmp(guid, expectedTypeGuid) != 0) { @@ -324,8 +325,9 @@ ULTRA_check_channel_client(void __iomem *pChannel, } if (expectedMinBytes > 0) { /* caller wants us to verify * channel size */ - unsigned long long bytes = readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Size); + unsigned long long bytes = + readq(&((struct channel_header __iomem *) + (pChannel))->Size); if (bytes < expectedMinBytes) { pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", channelName, &expectedTypeGuid, @@ -335,7 +337,7 @@ ULTRA_check_channel_client(void __iomem *pChannel, } if (expectedVersionId > 0) { /* caller wants us to verify * channel version */ - unsigned long ver = readl(&((CHANNEL_HEADER __iomem *) + unsigned long ver = readl(&((struct channel_header __iomem *) (pChannel))->VersionId); if (ver != expectedVersionId) { pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n", @@ -346,8 +348,9 @@ ULTRA_check_channel_client(void __iomem *pChannel, } if (expectedSignature > 0) { /* caller wants us to verify * channel signature */ - unsigned long long sig = readq(&((CHANNEL_HEADER __iomem *) - (pChannel))->Signature); + unsigned long long sig = + readq(&((struct channel_header __iomem *) + (pChannel))->Signature); if (sig != expectedSignature) { pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n", channelName, &expectedTypeGuid, @@ -416,7 +419,7 @@ static inline int ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, void *logCtx, char *file, int line, char *func) { - CHANNEL_HEADER __iomem *pChan = pChannel; + struct channel_header __iomem *pChan = pChannel; if (readl(&pChan->CliStateOS) == CHANNELCLI_DISABLED) { if ((readb(&pChan->CliErrorOS) @@ -511,7 +514,7 @@ static inline void ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, void *logCtx, char *file, int line, char *func) { - CHANNEL_HEADER __iomem *pChan = pChannel; + struct channel_header __iomem *pChan = pChannel; if (readb(&pChan->CliErrorOS) != 0) { /* we are in an error msg throttling state; come out of it */ @@ -552,8 +555,8 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, * full. */ -unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal); +unsigned char visor_signal_insert(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal); /* * Routine Description: @@ -574,8 +577,8 @@ unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, * empty. */ -unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, - void *pSignal); +unsigned char visor_signal_remove(struct channel_header __iomem *pChannel, + u32 Queue, void *pSignal); /* * Routine Description: @@ -596,7 +599,7 @@ unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, * Return value: * # of signals copied. */ -unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, +unsigned int SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal); /* @@ -610,7 +613,7 @@ unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, * Return value: * 1 if the signal queue is empty, 0 otherwise. */ -unsigned char visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, +unsigned char visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue); #endif diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index f7ca6d167d60..8e8a5a57bddb 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -470,7 +470,7 @@ typedef struct _GUEST_DEVICES { } GUEST_DEVICES; typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { - CHANNEL_HEADER Header; + struct channel_header Header; GUEST_PHYSICAL_ADDRESS gpControlVm; /* guest physical address of * this channel */ GUEST_PHYSICAL_ADDRESS gpPartitionTables; /* guest physical address of diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 9912e51b89b5..590022fd9fb6 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -383,7 +383,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { /* ----------------------- */ /* Offsets/sizes for diagnostic channel attributes... */ -#define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(ULTRA_CHANNEL_PROTOCOL)) +#define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(struct channel_header)) #define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(SIGNAL_QUEUE_HEADER)) #define DIAG_CH_PROTOCOL_HEADER_OFFSET \ (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE) @@ -416,7 +416,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { *Reserved: Reserved area to allow for correct channel size padding. */ typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { - ULTRA_CHANNEL_PROTOCOL CommonChannelHeader; + struct channel_header CommonChannelHeader; SIGNAL_QUEUE_HEADER QueueHeader; DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader; DIAG_CHANNEL_EVENT Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 7de87a481a8c..77335964e3fe 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -685,7 +685,7 @@ struct uiscmdrsp { * this header there is a large region of memory which contains the command and * response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { - CHANNEL_HEADER ChannelHeader; + struct channel_header ChannelHeader; SIGNAL_QUEUE_HEADER cmdQ; SIGNAL_QUEUE_HEADER rspQ; union { diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 420b7d859522..76bc7140d5e7 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -76,7 +76,7 @@ typedef struct _ULTRA_VBUS_HEADERINFO { } ULTRA_VBUS_HEADERINFO; struct ultra_vbus_channel_protocol { - ULTRA_CHANNEL_PROTOCOL ChannelHeader; /* initialized by server */ + struct channel_header ChannelHeader; /* initialized by server */ ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */ /* the remainder of this channel is filled in by the client */ struct ultra_vbus_deviceinfo ChpInfo; diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index db9d2051ae2f..7d01c42abcb9 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -34,7 +34,7 @@ #include "controlvmcompletionstatus.h" struct uisqueue_info { - CHANNEL_HEADER __iomem *chan; + struct channel_header __iomem *chan; /* channel containing queues in which scsi commands & * responses are queued */ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 35e8a61c7202..0de0eee95b8f 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -444,8 +444,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) if (!uuid_le_cmp(dev->channel_uuid, spar_vhba_channel_protocol_uuid)) { - wait_for_valid_guid(&((CHANNEL_HEADER - __iomem *) (dev-> + wait_for_valid_guid(&(( + struct channel_header + __iomem *) (dev-> chanptr))-> Type); if (!ULTRA_VHBA_CHANNEL_OK_CLIENT @@ -469,8 +470,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) } else if (!uuid_le_cmp(dev->channel_uuid, spar_vnic_channel_protocol_uuid)) { - wait_for_valid_guid(&((CHANNEL_HEADER - __iomem *) (dev-> + wait_for_valid_guid(&(( + struct channel_header + __iomem *) (dev-> chanptr))-> Type); if (!ULTRA_VNIC_CHANNEL_OK_CLIENT @@ -1565,7 +1567,7 @@ uislib_mod_init(void) LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n", (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL)); LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", - (ulong) sizeof(CHANNEL_HEADER)); + (ulong) sizeof(struct channel_header)); LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n", (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP); diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index e4130c9714fc..c25c1d9f129c 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -420,7 +420,7 @@ static irqreturn_t virthba_ISR(int irq, void *dev_id) { struct virthba_info *virthbainfo = (struct virthba_info *) dev_id; - CHANNEL_HEADER __iomem *pChannelHeader; + struct channel_header __iomem *pChannelHeader; SIGNAL_QUEUE_HEADER __iomem *pqhdr; u64 mask; unsigned long long rc1; @@ -461,7 +461,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) int rsp; int i; irq_handler_t handler = virthba_ISR; - CHANNEL_HEADER __iomem *pChannelHeader; + struct channel_header __iomem *pChannelHeader; SIGNAL_QUEUE_HEADER __iomem *pqhdr; u64 mask; diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index f782916cbf2b..2be0447c612e 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -195,7 +195,7 @@ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(ULTRA_CHANNEL_PROTOCOL) + chan->HdrInfo.chpInfoByteOffset; + off = sizeof(struct channel_header) + chan->HdrInfo.chpInfoByteOffset; if (chan->HdrInfo.chpInfoByteOffset == 0) { LOGERR("vbus channel not used, because chpInfoByteOffset == 0"); return -1; @@ -214,7 +214,7 @@ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(ULTRA_CHANNEL_PROTOCOL) + chan->HdrInfo.busInfoByteOffset; + off = sizeof(struct channel_header) + chan->HdrInfo.busInfoByteOffset; if (chan->HdrInfo.busInfoByteOffset == 0) { LOGERR("vbus channel not used, because busInfoByteOffset == 0"); return -1; @@ -237,7 +237,7 @@ write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, return -1; } off = - (sizeof(ULTRA_CHANNEL_PROTOCOL) + + (sizeof(struct channel_header) + chan->HdrInfo.devInfoByteOffset) + (chan->HdrInfo.deviceInfoStructBytes * devix); if (chan->HdrInfo.devInfoByteOffset == 0) { diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 01a44c553500..d2fc89a0bbd2 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -30,7 +30,7 @@ struct VISORCHANNEL_Tag { MEMREGION *memregion; /* from visor_memregion_create() */ - CHANNEL_HEADER chan_hdr; + struct channel_header chan_hdr; uuid_le guid; ulong size; BOOL needs_lock; @@ -70,19 +70,19 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, /* prepare chan_hdr (abstraction to read/write channel memory) */ if (parent == NULL) p->memregion = - visor_memregion_create(physaddr, sizeof(CHANNEL_HEADER)); + visor_memregion_create(physaddr, + sizeof(struct channel_header)); else p->memregion = visor_memregion_create_overlapped(parent->memregion, - off, - sizeof(CHANNEL_HEADER)); + off, sizeof(struct channel_header)); if (p->memregion == NULL) { ERRDRV("visor_memregion_create failed failed: (status=0)\n"); rc = NULL; goto Away; } if (visor_memregion_read(p->memregion, 0, &p->chan_hdr, - sizeof(CHANNEL_HEADER)) < 0) { + sizeof(struct channel_header)) < 0) { ERRDRV("visor_memregion_read failed: (status=0)\n"); rc = NULL; goto Away; @@ -225,8 +225,11 @@ visorchannel_read(VISORCHANNEL *channel, ulong offset, { int rc = visor_memregion_read(channel->memregion, offset, local, nbytes); - if ((rc >= 0) && (offset == 0) && (nbytes >= sizeof(CHANNEL_HEADER))) - memcpy(&channel->chan_hdr, local, sizeof(CHANNEL_HEADER)); + if ((rc >= 0) && (offset == 0) && + (nbytes >= sizeof(struct channel_header))) { + memcpy(&channel->chan_hdr, local, + sizeof(struct channel_header)); + } return rc; } EXPORT_SYMBOL_GPL(visorchannel_read); @@ -235,8 +238,9 @@ int visorchannel_write(VISORCHANNEL *channel, ulong offset, void *local, ulong nbytes) { - if (offset == 0 && nbytes >= sizeof(CHANNEL_HEADER)) - memcpy(&channel->chan_hdr, local, sizeof(CHANNEL_HEADER)); + if (offset == 0 && nbytes >= sizeof(struct channel_header)) + memcpy(&channel->chan_hdr, local, + sizeof(struct channel_header)); return visor_memregion_write(channel->memregion, offset, local, nbytes); } EXPORT_SYMBOL_GPL(visorchannel_write); @@ -316,7 +320,7 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, { BOOL rc = FALSE; - if (channel->chan_hdr.oChannelSpace < sizeof(CHANNEL_HEADER)) { + if (channel->chan_hdr.oChannelSpace < sizeof(struct channel_header)) { ERRDRV("oChannelSpace too small: (status=%d)\n", rc); goto Away; } @@ -559,8 +563,8 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, HOSTADDRESS addr = 0; ulong nbytes = 0, nbytes_region = 0; MEMREGION *memregion = NULL; - CHANNEL_HEADER hdr; - CHANNEL_HEADER *phdr = &hdr; + struct channel_header hdr; + struct channel_header *phdr = &hdr; int i = 0; int errcode = 0; @@ -576,7 +580,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, addr = visor_memregion_get_physaddr(memregion); nbytes_region = visor_memregion_get_nbytes(memregion); errcode = visorchannel_read(channel, off, - phdr, sizeof(CHANNEL_HEADER)); + phdr, sizeof(struct channel_header)); if (errcode < 0) { seq_printf(seq, "Read of channel header failed with errcode=%d)\n", diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index cfacf17ad26a..e26db99c4d58 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -114,7 +114,7 @@ typedef struct { /* Manages the request payload in the controlvm channel */ static CONTROLVM_PAYLOAD_INFO ControlVm_payload_info; -static pCHANNEL_HEADER Test_Vnic_channel; +static struct channel_header *Test_Vnic_channel; typedef struct { CONTROLVM_MESSAGE_HEADER Dumpcapture_header; -- GitLab From a8a31f617721e092629f8ce27ce99376308372b1 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:56 -0400 Subject: [PATCH 1347/9457] staging: unisys: fix CamelCase names in struct channel_header Fix CamelCase names: Signature => signature LegacySignature => legacy_signature HeaderSize => header_size Size => size Features => features Type => chtype PartitionHandle => partition_handle Handle => handle oChannelSpace => ch_space_offset VersionId => version_id PartitionIndex => partition_index ZoneGuid => zone_uuid oClientString => cli_str_offset CliStateBoot => cli_state_boot CmdStateCli => cmd_state_cli CliStateOs => cli_state_os ChannelCharacteristics => ch_characteristic CmdStateSrv => cmd_state_srv srvState => srv_state CliErrorBoot => cli_error_boot CliErrorOs => cli_error_os Filler => filler RecoverChannel => recover_channel Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 8 +- .../common-spar/include/channels/channel.h | 135 +++++++++--------- .../common-spar/include/channels/iochannel.h | 40 +++--- drivers/staging/unisys/uislib/uislib.c | 4 +- drivers/staging/unisys/virthba/virthba.c | 16 +-- .../unisys/visorchannel/visorchannel_funcs.c | 50 +++---- 6 files changed, 126 insertions(+), 127 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index 2033b3b8a11f..c2f95f33b114 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -52,7 +52,7 @@ visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, SIGNAL_QUEUE_HEADER __iomem *pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) - ((char __iomem *) pChannel + readq(&pChannel->oChannelSpace)) + ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) + Queue; /* capture current head and tail */ @@ -110,7 +110,7 @@ visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, unsigned int head, tail; SIGNAL_QUEUE_HEADER __iomem *pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->oChannelSpace)) + Queue; + readq(&pChannel->ch_space_offset)) + Queue; /* capture current head and tail */ head = readl(&pqhdr->Head); @@ -165,7 +165,7 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) unsigned int head, tail, signalCount = 0; pSIGNAL_QUEUE_HEADER pqhdr = (pSIGNAL_QUEUE_HEADER) ((char *) pChannel + - pChannel->oChannelSpace) + Queue; + pChannel->ch_space_offset) + Queue; /* capture current head and tail */ head = pqhdr->Head; @@ -214,7 +214,7 @@ visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue) { SIGNAL_QUEUE_HEADER __iomem *pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->oChannelSpace)) + Queue; + readq(&pChannel->ch_space_offset)) + Queue; return readl(&pqhdr->Head) == readl(&pqhdr->Tail); } EXPORT_SYMBOL_GPL(visor_signalqueue_empty); diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index a71bac0526b2..dafb14d50c9f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -95,7 +95,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) #define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY) #define ULTRA_CHANNEL_SERVER_READY(pChannel) \ - (ULTRA_CHANNELSRV_IS_READY(readl(&(pChannel)->SrvState))) + (ULTRA_CHANNELSRV_IS_READY(readl(&(pChannel)->srv_state))) #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \ (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ @@ -134,21 +134,21 @@ ULTRA_CHANNELCLI_STRING(u32 v) do { \ ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \ readl(&(((struct channel_header __iomem *) \ - (pChan))->CliStateOS)), \ + (pChan))->cli_state_os)), \ newstate, \ chanId, logCtx, __FILE__, __LINE__); \ pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ chanId, "CliStateOS", \ ULTRA_CHANNELCLI_STRING( \ readl(&((struct channel_header __iomem *)\ - (pChan))->CliStateOS)), \ + (pChan))->cli_state_os)), \ readl(&((struct channel_header __iomem *) \ - (pChan))->CliStateOS), \ + (pChan))->cli_state_os), \ ULTRA_CHANNELCLI_STRING(newstate), \ newstate, \ PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ writel(newstate, &((struct channel_header __iomem *) \ - (pChan))->CliStateOS); \ + (pChan))->cli_state_os); \ mb(); /* required for channel synch */ \ } while (0) @@ -201,43 +201,43 @@ ULTRA_CHANNELCLI_STRING(u32 v) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ /* Common Channel Header */ struct channel_header { - u64 Signature; /* Signature */ - u32 LegacyState; /* DEPRECATED - being replaced by */ + u64 signature; /* Signature */ + u32 legacy_state; /* DEPRECATED - being replaced by */ /* / SrvState, CliStateBoot, and CliStateOS below */ - u32 HeaderSize; /* sizeof(struct channel_header) */ - u64 Size; /* Total size of this channel in bytes */ - u64 Features; /* Flags to modify behavior */ - uuid_le Type; /* Channel type: data, bus, control, etc. */ - u64 PartitionHandle; /* ID of guest partition */ - u64 Handle; /* Device number of this channel in client */ - u64 oChannelSpace; /* Offset in bytes to channel specific area */ - u32 VersionId; /* struct channel_header Version ID */ - u32 PartitionIndex; /* Index of guest partition */ - uuid_le ZoneGuid; /* Guid of Channel's zone */ - u32 oClientString; /* offset from channel header to + u32 header_size; /* sizeof(struct channel_header) */ + u64 size; /* Total size of this channel in bytes */ + u64 features; /* Flags to modify behavior */ + uuid_le chtype; /* Channel type: data, bus, control, etc. */ + u64 partition_handle; /* ID of guest partition */ + u64 handle; /* Device number of this channel in client */ + u64 ch_space_offset; /* Offset in bytes to channel specific area */ + u32 version_id; /* struct channel_header Version ID */ + u32 partition_index; /* Index of guest partition */ + uuid_le zone_uuid; /* Guid of Channel's zone */ + u32 cli_str_offset; /* offset from channel header to * nul-terminated ClientString (0 if * ClientString not present) */ - u32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot + u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot * EFI client of this channel */ - u32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in + u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, * ServerStateDown, etc) */ - u32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS + u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS * client of this channel */ - u32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_ */ - u32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in + u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_ */ + u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in * Windows drivers, see ServerStateUp, * ServerStateDown, etc) */ - u32 SrvState; /* CHANNEL_SERVERSTATE */ - u8 CliErrorBoot; /* bits to indicate err states for + u32 srv_state; /* CHANNEL_SERVERSTATE */ + u8 cli_error_boot; /* bits to indicate err states for * boot clients, so err messages can * be throttled */ - u8 CliErrorOS; /* bits to indicate err states for OS + u8 cli_error_os; /* bits to indicate err states for OS * clients, so err messages can be * throttled */ - u8 Filler[1]; /* Pad out to 128 byte cacheline */ + u8 filler[1]; /* Pad out to 128 byte cacheline */ /* Please add all new single-byte values below here */ - u8 RecoverChannel; + u8 recover_channel; }; #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0) @@ -312,9 +312,8 @@ ULTRA_check_channel_client(void __iomem *pChannel, uuid_le guid; memcpy_fromio(&guid, - &((struct channel_header __iomem *) - (pChannel))->Type, - sizeof(guid)); + &((struct channel_header __iomem *)(pChannel))->chtype, + sizeof(guid)); /* caller wants us to verify type GUID */ if (uuid_le_cmp(guid, expectedTypeGuid) != 0) { pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", @@ -327,7 +326,7 @@ ULTRA_check_channel_client(void __iomem *pChannel, * channel size */ unsigned long long bytes = readq(&((struct channel_header __iomem *) - (pChannel))->Size); + (pChannel))->size); if (bytes < expectedMinBytes) { pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", channelName, &expectedTypeGuid, @@ -338,7 +337,7 @@ ULTRA_check_channel_client(void __iomem *pChannel, if (expectedVersionId > 0) { /* caller wants us to verify * channel version */ unsigned long ver = readl(&((struct channel_header __iomem *) - (pChannel))->VersionId); + (pChannel))->version_id); if (ver != expectedVersionId) { pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n", channelName, &expectedTypeGuid, @@ -350,7 +349,7 @@ ULTRA_check_channel_client(void __iomem *pChannel, * channel signature */ unsigned long long sig = readq(&((struct channel_header __iomem *) - (pChannel))->Signature); + (pChannel))->signature); if (sig != expectedSignature) { pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n", channelName, &expectedTypeGuid, @@ -421,13 +420,13 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, { struct channel_header __iomem *pChan = pChannel; - if (readl(&pChan->CliStateOS) == CHANNELCLI_DISABLED) { - if ((readb(&pChan->CliErrorOS) + if (readl(&pChan->cli_state_os) == CHANNELCLI_DISABLED) { + if ((readb(&pChan->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&pChan->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_DISABLED, - &pChan->CliErrorOS); + &pChan->cli_error_os); /* throttle until acquire successful */ pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", @@ -436,27 +435,27 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, } return 0; } - if ((readl(&pChan->CliStateOS) != CHANNELCLI_OWNED) - && (readl(&pChan->CliStateBoot) == CHANNELCLI_DISABLED)) { + if ((readl(&pChan->cli_state_os) != CHANNELCLI_OWNED) + && (readl(&pChan->cli_state_boot) == CHANNELCLI_DISABLED)) { /* Our competitor is DISABLED, so we can transition to OWNED */ pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", - chanId, "CliStateOS", - ULTRA_CHANNELCLI_STRING(readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), + chanId, "cli_state_os", + ULTRA_CHANNELCLI_STRING(readl(&pChan->cli_state_os)), + readl(&pChan->cli_state_os), ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), CHANNELCLI_OWNED, PathName_Last_N_Nodes((u8 *) file, 4), line); - writel(CHANNELCLI_OWNED, &pChan->CliStateOS); + writel(CHANNELCLI_OWNED, &pChan->cli_state_os); mb(); /* required for channel synch */ } - if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) { - if (readb(&pChan->CliErrorOS) != 0) { + if (readl(&pChan->cli_state_os) == CHANNELCLI_OWNED) { + if (readb(&pChan->cli_error_os) != 0) { /* we are in an error msg throttling state; * come out of it */ pr_info("%s Channel OS client acquire now successful @%s:%d\n", chanId, PathName_Last_N_Nodes((u8 *) file, 4), line); - writeb(0, &pChan->CliErrorOS); + writeb(0, &pChan->cli_error_os); } return 1; } @@ -464,48 +463,48 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, /* We have to do it the "hard way". We transition to BUSY, * and can use the channel iff our competitor has not also * transitioned to BUSY. */ - if (readl(&pChan->CliStateOS) != CHANNELCLI_ATTACHED) { - if ((readb(&pChan->CliErrorOS) + if (readl(&pChan->cli_state_os) != CHANNELCLI_ATTACHED) { + if ((readb(&pChan->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&pChan->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED, - &pChan->CliErrorOS); + &pChan->cli_error_os); /* throttle until acquire successful */ pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n", chanId, ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), + readl(&pChan->cli_state_os)), + readl(&pChan->cli_state_os), PathName_Last_N_Nodes((u8 *) file, 4), line); } return 0; } - writel(CHANNELCLI_BUSY, &pChan->CliStateOS); + writel(CHANNELCLI_BUSY, &pChan->cli_state_os); mb(); /* required for channel synch */ - if (readl(&pChan->CliStateBoot) == CHANNELCLI_BUSY) { - if ((readb(&pChan->CliErrorOS) + if (readl(&pChan->cli_state_boot) == CHANNELCLI_BUSY) { + if ((readb(&pChan->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->CliErrorOS) | + writeb(readb(&pChan->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_BUSY, - &pChan->CliErrorOS); + &pChan->cli_error_os); /* throttle until acquire successful */ pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", chanId, PathName_Last_N_Nodes((u8 *) file, 4), line); } /* reset busy */ - writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); + writel(CHANNELCLI_ATTACHED, &pChan->cli_state_os); mb(); /* required for channel synch */ return 0; } - if (readb(&pChan->CliErrorOS) != 0) { + if (readb(&pChan->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client acquire now successful @%s:%d\n", chanId, PathName_Last_N_Nodes((u8 *) file, 4), line); - writeb(0, &pChan->CliErrorOS); + writeb(0, &pChan->cli_error_os); } return 1; } @@ -516,24 +515,24 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, { struct channel_header __iomem *pChan = pChannel; - if (readb(&pChan->CliErrorOS) != 0) { + if (readb(&pChan->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client error state cleared @%s:%d\n", chanId, PathName_Last_N_Nodes((u8 *) file, 4), line); - writeb(0, &pChan->CliErrorOS); + writeb(0, &pChan->cli_error_os); } - if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) + if (readl(&pChan->cli_state_os) == CHANNELCLI_OWNED) return; - if (readl(&pChan->CliStateOS) != CHANNELCLI_BUSY) { + if (readl(&pChan->cli_state_os) != CHANNELCLI_BUSY) { pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n", chanId, ULTRA_CHANNELCLI_STRING( - readl(&pChan->CliStateOS)), - readl(&pChan->CliStateOS), + readl(&pChan->cli_state_os)), + readl(&pChan->cli_state_os), PathName_Last_N_Nodes((u8 *) file, 4), line); /* return; */ } - writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */ + writel(CHANNELCLI_ATTACHED, &pChan->cli_state_os); /* release busy */ } /* diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 77335964e3fe..c26363de86dd 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -750,29 +750,29 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { #define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP) #define SignalQInit(x) \ do { \ - x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ + x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.size); \ x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ x->cmdQ.SignalSize = SIZEOF_CMDRSP; \ x->cmdQ.MaxSignalSlots = \ - QSLOTSFROMBYTES(x->ChannelHeader.Size); \ + QSLOTSFROMBYTES(x->ChannelHeader.size); \ x->cmdQ.MaxSignals = x->cmdQ.MaxSignalSlots - 1; \ - x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ + x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.size); \ x->rspQ.oSignalBase = \ (SIZEOF_PROTOCOL + x->cmdQ.Size) - \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ x->rspQ.SignalSize = SIZEOF_CMDRSP; \ x->rspQ.MaxSignalSlots = \ - QSLOTSFROMBYTES(x->ChannelHeader.Size); \ + QSLOTSFROMBYTES(x->ChannelHeader.size); \ x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \ - x->ChannelHeader.oChannelSpace = \ + x->ChannelHeader.ch_space_offset = \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ } while (0) #define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \ do { \ if (clientStr) { \ - chan->ChannelHeader.oClientString = \ + chan->ChannelHeader.cli_str_offset = \ offsetof(type, clientString); \ memcpy(chan->clientString, clientStr, \ MINNUM(clientStrLen, \ @@ -802,13 +802,13 @@ static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes) { memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.VersionId = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.Signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); - x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = spar_vhba_channel_protocol_uuid; - x->ChannelHeader.ZoneGuid = NULL_UUID_LE; + x->ChannelHeader.version_id = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; + x->ChannelHeader.signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; + x->ChannelHeader.srv_state = CHANNELSRV_UNINITIALIZED; + x->ChannelHeader.header_size = sizeof(x->ChannelHeader); + x->ChannelHeader.size = COVER(bytes, 4096); + x->ChannelHeader.chtype = spar_vhba_channel_protocol_uuid; + x->ChannelHeader.zone_uuid = NULL_UUID_LE; x->vhba.wwnn = *wwnn; x->vhba.max = *max; INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, @@ -838,13 +838,13 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, u32 clientStrLen, u64 bytes) { memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.VersionId = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.Signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader); - x->ChannelHeader.Size = COVER(bytes, 4096); - x->ChannelHeader.Type = spar_vnic_channel_protocol_uuid; - x->ChannelHeader.ZoneGuid = NULL_UUID_LE; + x->ChannelHeader.version_id = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; + x->ChannelHeader.signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; + x->ChannelHeader.srv_state = CHANNELSRV_UNINITIALIZED; + x->ChannelHeader.header_size = sizeof(x->ChannelHeader); + x->ChannelHeader.size = COVER(bytes, 4096); + x->ChannelHeader.chtype = spar_vnic_channel_protocol_uuid; + x->ChannelHeader.zone_uuid = NULL_UUID_LE; memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); x->vnic.num_rcv_bufs = num_rcv_bufs; x->vnic.mtu = mtu; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 0de0eee95b8f..687b7db94fe5 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -448,7 +448,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) struct channel_header __iomem *) (dev-> chanptr))-> - Type); + chtype); if (!ULTRA_VHBA_CHANNEL_OK_CLIENT (dev->chanptr, NULL)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.", @@ -474,7 +474,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) struct channel_header __iomem *) (dev-> chanptr))-> - Type); + chtype); if (!ULTRA_VNIC_CHANNEL_OK_CLIENT (dev->chanptr, NULL)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.", diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index c25c1d9f129c..3e9a56d78815 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -429,9 +429,9 @@ virthba_ISR(int irq, void *dev_id) return IRQ_NONE; virthbainfo->interrupts_rcvd++; pChannelHeader = virthbainfo->chinfo.queueinfo->chan; - if (((readq(&pChannelHeader->Features) + if (((readq(&pChannelHeader->features) & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) - && ((readq(&pChannelHeader->Features) & + && ((readq(&pChannelHeader->features) & ULTRA_IO_DRIVER_DISABLES_INTS) != 0)) { virthbainfo->interrupts_disabled++; @@ -444,7 +444,7 @@ virthba_ISR(int irq, void *dev_id) } pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannelHeader + - readq(&pChannelHeader->oChannelSpace)) + IOCHAN_FROM_IOPART; + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; writeq(readq(&pqhdr->NumInterruptsReceived) + 1, &pqhdr->NumInterruptsReceived); atomic_set(&virthbainfo->interrupt_rcvd, 1); @@ -578,9 +578,9 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) INIT_WORK(&virthbainfo->serverdown_completion, virthba_serverdown_complete); - writeq(readq(&virthbainfo->chinfo.queueinfo->chan->Features) | + writeq(readq(&virthbainfo->chinfo.queueinfo->chan->features) | ULTRA_IO_CHANNEL_IS_POLLING, - &virthbainfo->chinfo.queueinfo->chan->Features); + &virthbainfo->chinfo.queueinfo->chan->features); /* start thread that will receive scsicmnd responses */ DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n", virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo); @@ -588,7 +588,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) pChannelHeader = virthbainfo->chinfo.queueinfo->chan; pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *)pChannelHeader + - readq(&pChannelHeader->oChannelSpace)) + IOCHAN_FROM_IOPART; + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; virthbainfo->flags_addr = &pqhdr->FeatureFlags; if (!uisthread_start(&virthbainfo->chinfo.threadinfo, @@ -622,7 +622,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); } else { u64 __iomem *Features_addr = - &virthbainfo->chinfo.queueinfo->chan->Features; + &virthbainfo->chinfo.queueinfo->chan->features; LOGERR("request_irq(%d) uislib_virthba_ISR request succeeded\n", virthbainfo->interrupt_vector); mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | @@ -1453,7 +1453,7 @@ static ssize_t enable_ints_write(struct file *file, if (VirtHbasOpen[i].virthbainfo != NULL) { virthbainfo = VirtHbasOpen[i].virthbainfo; Features_addr = - &virthbainfo->chinfo.queueinfo->chan->Features; + &virthbainfo->chinfo.queueinfo->chan->features; if (new_value == 1) { mask = ~(ULTRA_IO_CHANNEL_IS_POLLING | ULTRA_IO_DRIVER_DISABLES_INTS); diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index d2fc89a0bbd2..19f5c775ca88 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -89,10 +89,10 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, } if (channelBytes == 0) /* we had better be a CLIENT of this channel */ - channelBytes = (ulong) p->chan_hdr.Size; + channelBytes = (ulong) p->chan_hdr.size; if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) /* we had better be a CLIENT of this channel */ - guid = p->chan_hdr.Type; + guid = p->chan_hdr.chtype; if (visor_memregion_resize(p->memregion, channelBytes) < 0) { ERRDRV("visor_memregion_resize failed: (status=0)\n"); rc = NULL; @@ -194,14 +194,14 @@ EXPORT_SYMBOL_GPL(visorchannel_id); char * visorchannel_zoneid(VISORCHANNEL *channel, char *s) { - return visorchannel_uuid_id(&channel->chan_hdr.ZoneGuid, s); + return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); } EXPORT_SYMBOL_GPL(visorchannel_zoneid); HOSTADDRESS visorchannel_get_clientpartition(VISORCHANNEL *channel) { - return channel->chan_hdr.PartitionHandle; + return channel->chan_hdr.partition_handle; } EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition); @@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); * channel header */ #define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->oChannelSpace + ((q) * sizeof(SIGNAL_QUEUE_HEADER))) + ((chan_hdr)->ch_space_offset + ((q) * sizeof(SIGNAL_QUEUE_HEADER))) /** Return offset of a specific queue entry (data) from the beginning of a * channel header @@ -320,7 +320,7 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, { BOOL rc = FALSE; - if (channel->chan_hdr.oChannelSpace < sizeof(struct channel_header)) { + if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) { ERRDRV("oChannelSpace too small: (status=%d)\n", rc); goto Away; } @@ -591,38 +591,38 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, } else return; } - nbytes = (ulong) (phdr->Size); + nbytes = (ulong) (phdr->size); seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n", addr + off, nbytes, nbytes_region); - seq_printf(seq, "Type = %pUL\n", &phdr->Type); - seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->ZoneGuid); + seq_printf(seq, "Type = %pUL\n", &phdr->chtype); + seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->zone_uuid); seq_printf(seq, "Signature = 0x%-16.16Lx\n", - (long long) phdr->Signature); - seq_printf(seq, "LegacyState = %lu\n", (ulong) phdr->LegacyState); - seq_printf(seq, "SrvState = %lu\n", (ulong) phdr->SrvState); - seq_printf(seq, "CliStateBoot = %lu\n", (ulong) phdr->CliStateBoot); - seq_printf(seq, "CliStateOS = %lu\n", (ulong) phdr->CliStateOS); - seq_printf(seq, "HeaderSize = %lu\n", (ulong) phdr->HeaderSize); - seq_printf(seq, "Size = %llu\n", (long long) phdr->Size); + (long long) phdr->signature); + seq_printf(seq, "LegacyState = %lu\n", (ulong)phdr->legacy_state); + seq_printf(seq, "SrvState = %lu\n", (ulong)phdr->srv_state); + seq_printf(seq, "CliStateBoot = %lu\n", (ulong)phdr->cli_state_boot); + seq_printf(seq, "CliStateOS = %lu\n", (ulong)phdr->cli_state_os); + seq_printf(seq, "HeaderSize = %lu\n", (ulong)phdr->header_size); + seq_printf(seq, "Size = %llu\n", (long long)phdr->size); seq_printf(seq, "Features = 0x%-16.16llx\n", - (long long) phdr->Features); + (long long) phdr->features); seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n", - (long long) phdr->PartitionHandle); + (long long) phdr->partition_handle); seq_printf(seq, "Handle = 0x%-16.16llx\n", - (long long) phdr->Handle); - seq_printf(seq, "VersionId = %lu\n", (ulong) phdr->VersionId); + (long long) phdr->handle); + seq_printf(seq, "VersionId = %lu\n", (ulong) phdr->version_id); seq_printf(seq, "oChannelSpace = %llu\n", - (long long) phdr->oChannelSpace); - if ((phdr->oChannelSpace == 0) || (errcode < 0)) + (long long) phdr->ch_space_offset); + if ((phdr->ch_space_offset == 0) || (errcode < 0)) ; else for (i = 0; i < nQueues; i++) { SIGNAL_QUEUE_HEADER q; errcode = visorchannel_read(channel, - off + phdr->oChannelSpace + - (i * sizeof(q)), - &q, sizeof(q)); + off + phdr->ch_space_offset + + (i * sizeof(q)), + &q, sizeof(q)); if (errcode < 0) { seq_printf(seq, "failed to read signal queue #%d from channel @0x%-16.16Lx errcode=%d\n", -- GitLab From 10b133c7628a83b058458c667934d35a12b3dc4f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:57 -0400 Subject: [PATCH 1348/9457] staging: unisys: clean up ULTRA_CHANNEL_SERVER_READY macro Simplify this macro so it is only one macro, rename it to SPAR_CHANNEL_SERVER_READY, and get rid of the CamelCase parameter name. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/channel.h | 5 ++--- drivers/staging/unisys/virtpci/virtpci.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index dafb14d50c9f..c6d04af589a7 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -93,9 +93,8 @@ ULTRA_CHANNELCLI_STRING(u32 v) return (const u8 *)("?"); } -#define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY) -#define ULTRA_CHANNEL_SERVER_READY(pChannel) \ - (ULTRA_CHANNELSRV_IS_READY(readl(&(pChannel)->srv_state))) +#define SPAR_CHANNEL_SERVER_READY(ch) \ + (readl(&(ch)->srv_state) == CHANNELSRV_READY) #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \ (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 2be0447c612e..160ed8284e88 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -177,7 +177,7 @@ int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) while (count > 0) { - if (ULTRA_CHANNEL_SERVER_READY(&chanptr->ChannelHeader)) + if (SPAR_CHANNEL_SERVER_READY(&chanptr->ChannelHeader)) return 1; UIS_THREAD_WAIT_SEC(1); count--; -- GitLab From 13d58a982df0227c9b57638e2f0553cba34cf576 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:58 -0400 Subject: [PATCH 1349/9457] staging: unisys: fix ULTRA_SPAR_CHANNEL_CLIENT_CHK_TRANSITION macro Rename the macro to SPAR_CHANNEL_CLIENT_CHK_TRANSITION, and rename CamelCase parameters to: chanId => id logCtx => log Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/channel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c6d04af589a7..2ce687e2cd31 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -114,12 +114,12 @@ ULTRA_CHANNELCLI_STRING(u32 v) (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ ? (1) : (0)) -#define ULTRA_CHANNEL_CLIENT_CHK_TRANSITION(old, new, chanId, logCtx, \ +#define SPAR_CHANNEL_CLIENT_CHK_TRANSITION(old, new, id, log, \ file, line) \ do { \ if (!ULTRA_VALID_CHANNELCLI_TRANSITION(old, new)) \ pr_info("%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliState", \ + id, "CliState", \ ULTRA_CHANNELCLI_STRING(old), \ old, \ ULTRA_CHANNELCLI_STRING(new), \ @@ -131,7 +131,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) #define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \ newstate, logCtx) \ do { \ - ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \ + SPAR_CHANNEL_CLIENT_CHK_TRANSITION( \ readl(&(((struct channel_header __iomem *) \ (pChan))->cli_state_os)), \ newstate, \ -- GitLab From 8800bfbc068352104efa11efb73424217427f9da Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:29:59 -0400 Subject: [PATCH 1350/9457] staging: unisys: fix CamelCase in PathName_Last_N_Nodes() Fix CamelCase name: PathName_Last_N_Nodes => pathname_last_n_nodes Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 2ce687e2cd31..c68d36cf5d48 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -124,7 +124,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) old, \ ULTRA_CHANNELCLI_STRING(new), \ new, \ - PathName_Last_N_Nodes((u8 *)file, 4), \ + pathname_last_n_nodes((u8 *)file, 4), \ line); \ } while (0) @@ -145,7 +145,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) (pChan))->cli_state_os), \ ULTRA_CHANNELCLI_STRING(newstate), \ newstate, \ - PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ + pathname_last_n_nodes(__FILE__, 4), __LINE__); \ writel(newstate, &((struct channel_header __iomem *) \ (pChan))->cli_state_os); \ mb(); /* required for channel synch */ \ @@ -389,7 +389,7 @@ ULTRA_check_channel_server(uuid_le typeGuid, * in it, the return pointer will be to the beginning of the string. */ static inline u8 * -PathName_Last_N_Nodes(u8 *s, unsigned int n) +pathname_last_n_nodes(u8 *s, unsigned int n) { u8 *p = s; unsigned int node_count = 0; @@ -429,7 +429,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, /* throttle until acquire successful */ pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), + chanId, pathname_last_n_nodes((u8 *) file, 4), line); } return 0; @@ -443,7 +443,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, readl(&pChan->cli_state_os), ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), CHANNELCLI_OWNED, - PathName_Last_N_Nodes((u8 *) file, 4), line); + pathname_last_n_nodes((u8 *) file, 4), line); writel(CHANNELCLI_OWNED, &pChan->cli_state_os); mb(); /* required for channel synch */ } @@ -452,7 +452,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, /* we are in an error msg throttling state; * come out of it */ pr_info("%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), + chanId, pathname_last_n_nodes((u8 *) file, 4), line); writeb(0, &pChan->cli_error_os); } @@ -474,7 +474,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, chanId, ULTRA_CHANNELCLI_STRING( readl(&pChan->cli_state_os)), readl(&pChan->cli_state_os), - PathName_Last_N_Nodes((u8 *) file, 4), + pathname_last_n_nodes((u8 *) file, 4), line); } return 0; @@ -490,7 +490,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, &pChan->cli_error_os); /* throttle until acquire successful */ pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), + chanId, pathname_last_n_nodes((u8 *) file, 4), line); } /* reset busy */ @@ -501,7 +501,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, if (readb(&pChan->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client acquire now successful @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), + chanId, pathname_last_n_nodes((u8 *) file, 4), line); writeb(0, &pChan->cli_error_os); } @@ -517,7 +517,7 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, if (readb(&pChan->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ pr_info("%s Channel OS client error state cleared @%s:%d\n", - chanId, PathName_Last_N_Nodes((u8 *) file, 4), + chanId, pathname_last_n_nodes((u8 *) file, 4), line); writeb(0, &pChan->cli_error_os); } @@ -528,7 +528,7 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, chanId, ULTRA_CHANNELCLI_STRING( readl(&pChan->cli_state_os)), readl(&pChan->cli_state_os), - PathName_Last_N_Nodes((u8 *) file, 4), line); + pathname_last_n_nodes((u8 *) file, 4), line); /* return; */ } writel(CHANNELCLI_ATTACHED, &pChan->cli_state_os); /* release busy */ -- GitLab From ff97a3fdf5c99adee957841aec4741cf36519870 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:00 -0400 Subject: [PATCH 1351/9457] staging: unisys: fix up ULTRA_CHANNEL_CLIENT_TRANSITION macro Rename the macro to SPAR_CHANNEL_CLIENT_TRANSITION, and fix CamelCase parameters: pChan => ch chanId => id logCtx => log Update all places the macro was used to call the new name. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 22 +++++++++---------- drivers/staging/unisys/virthba/virthba.c | 6 ++--- drivers/staging/unisys/virtpci/virtpci.c | 12 +++++----- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c68d36cf5d48..0f575e861d16 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -128,26 +128,24 @@ ULTRA_CHANNELCLI_STRING(u32 v) line); \ } while (0) -#define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \ - newstate, logCtx) \ +#define SPAR_CHANNEL_CLIENT_TRANSITION(ch, id, newstate, log) \ do { \ SPAR_CHANNEL_CLIENT_CHK_TRANSITION( \ - readl(&(((struct channel_header __iomem *) \ - (pChan))->cli_state_os)), \ - newstate, \ - chanId, logCtx, __FILE__, __LINE__); \ + readl(&(((struct channel_header __iomem *)\ + (ch))->cli_state_os)), \ + newstate, id, log, __FILE__, __LINE__); \ pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \ - chanId, "CliStateOS", \ + id, "CliStateOS", \ ULTRA_CHANNELCLI_STRING( \ readl(&((struct channel_header __iomem *)\ - (pChan))->cli_state_os)), \ - readl(&((struct channel_header __iomem *) \ - (pChan))->cli_state_os), \ + (ch))->cli_state_os)), \ + readl(&((struct channel_header __iomem *)\ + (ch))->cli_state_os), \ ULTRA_CHANNELCLI_STRING(newstate), \ newstate, \ pathname_last_n_nodes(__FILE__, 4), __LINE__); \ - writel(newstate, &((struct channel_header __iomem *) \ - (pChan))->cli_state_os); \ + writel(newstate, &((struct channel_header __iomem *)\ + (ch))->cli_state_os); \ mb(); /* required for channel synch */ \ } while (0) diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 3e9a56d78815..9e98af8451b3 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1498,9 +1498,9 @@ virthba_serverup(struct virtpci_dev *virtpcidev) /* Must transition channel to ATTACHED state BEFORE we * can start using the device again */ - ULTRA_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan, - dev_name(&virtpcidev->generic_dev), - CHANNELCLI_ATTACHED, NULL); + SPAR_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan, + dev_name(&virtpcidev->generic_dev), + CHANNELCLI_ATTACHED, NULL); /* Start Processing the IOVM Response Queue Again */ if (!uisthread_start(&virthbainfo->chinfo.threadinfo, diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 160ed8284e88..eaae4e8b9b45 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -1009,9 +1009,9 @@ static int virtpci_device_add(struct device *parentbus, int devtype, * queues can begin at any time after device_register(). */ pDev = &virtpcidev->generic_dev; - ULTRA_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), - CHANNELCLI_ATTACHED, NULL); + SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, + BUS_ID(pDev), + CHANNELCLI_ATTACHED, NULL); /* don't register until device has been added to * list. Otherwise, a device_unregister from this function can @@ -1032,9 +1032,9 @@ static int virtpci_device_add(struct device *parentbus, int devtype, if (ret) { LOGERR("device_register returned %d\n", ret); pDev = &virtpcidev->generic_dev; - ULTRA_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), - CHANNELCLI_DETACHED, NULL); + SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, + BUS_ID(pDev), + CHANNELCLI_DETACHED, NULL); /* remove virtpcidev, the one we just added, from the list */ write_lock_irqsave(&VpcidevListLock, flags); for (tmpvpcidev = VpcidevListHead, prev = NULL; -- GitLab From 9f16930e557bf64811f1e972dbbd62e40940c9dc Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:01 -0400 Subject: [PATCH 1352/9457] staging: unisys: refactor ULTRA_channel_client_acquire_os() Remove the unnecessary macro ULTRA_CHANNEL_CLIENT_ACQUIRE_OS for calling the function, and rename the function to spar_channel_client_acquire_os(). Get rid of unneeded parameters logCtx, file, and line, and Fix CamelCase names: pChannel => ch chanId => id pChan => hdr Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 93 ++++++++----------- drivers/staging/unisys/uislib/uisqueue.c | 2 +- drivers/staging/unisys/virthba/virthba.c | 4 +- 3 files changed, 43 insertions(+), 56 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 0f575e861d16..8c3fdf7e879f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -149,10 +149,6 @@ ULTRA_CHANNELCLI_STRING(u32 v) mb(); /* required for channel synch */ \ } while (0) -#define ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(pChan, chanId, logCtx) \ - ULTRA_channel_client_acquire_os(pChan, chanId, logCtx, \ - (char *)__FILE__, __LINE__, \ - (char *)__func__) #define ULTRA_CHANNEL_CLIENT_RELEASE_OS(pChan, chanId, logCtx) \ ULTRA_channel_client_release_os(pChan, chanId, logCtx, \ (char *)__FILE__, __LINE__, (char *)__func__) @@ -412,47 +408,43 @@ pathname_last_n_nodes(u8 *s, unsigned int n) } static inline int -ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, - void *logCtx, char *file, int line, char *func) +spar_channel_client_acquire_os(void __iomem *ch, u8 *id) { - struct channel_header __iomem *pChan = pChannel; + struct channel_header __iomem *hdr = ch; - if (readl(&pChan->cli_state_os) == CHANNELCLI_DISABLED) { - if ((readb(&pChan->cli_error_os) + if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->cli_error_os) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_DISABLED, - &pChan->cli_error_os); + &hdr->cli_error_os); /* throttle until acquire successful */ - pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n", - chanId, pathname_last_n_nodes((u8 *) file, 4), - line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n", + id); } return 0; } - if ((readl(&pChan->cli_state_os) != CHANNELCLI_OWNED) - && (readl(&pChan->cli_state_boot) == CHANNELCLI_DISABLED)) { + if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) + && (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) { /* Our competitor is DISABLED, so we can transition to OWNED */ - pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", - chanId, "cli_state_os", - ULTRA_CHANNELCLI_STRING(readl(&pChan->cli_state_os)), - readl(&pChan->cli_state_os), + pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n", + id, "cli_state_os", + ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os), ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED), - CHANNELCLI_OWNED, - pathname_last_n_nodes((u8 *) file, 4), line); - writel(CHANNELCLI_OWNED, &pChan->cli_state_os); + CHANNELCLI_OWNED); + writel(CHANNELCLI_OWNED, &hdr->cli_state_os); mb(); /* required for channel synch */ } - if (readl(&pChan->cli_state_os) == CHANNELCLI_OWNED) { - if (readb(&pChan->cli_error_os) != 0) { + if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; * come out of it */ - pr_info("%s Channel OS client acquire now successful @%s:%d\n", - chanId, pathname_last_n_nodes((u8 *) file, 4), - line); - writeb(0, &pChan->cli_error_os); + pr_info("%s Channel OS client acquire now successful\n", + id); + writeb(0, &hdr->cli_error_os); } return 1; } @@ -460,48 +452,43 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, /* We have to do it the "hard way". We transition to BUSY, * and can use the channel iff our competitor has not also * transitioned to BUSY. */ - if (readl(&pChan->cli_state_os) != CHANNELCLI_ATTACHED) { - if ((readb(&pChan->cli_error_os) + if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->cli_error_os) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED, - &pChan->cli_error_os); + &hdr->cli_error_os); /* throttle until acquire successful */ - pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n", - chanId, ULTRA_CHANNELCLI_STRING( - readl(&pChan->cli_state_os)), - readl(&pChan->cli_state_os), - pathname_last_n_nodes((u8 *) file, 4), - line); + pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n", + id, ULTRA_CHANNELCLI_STRING( + readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os)); } return 0; } - writel(CHANNELCLI_BUSY, &pChan->cli_state_os); + writel(CHANNELCLI_BUSY, &hdr->cli_state_os); mb(); /* required for channel synch */ - if (readl(&pChan->cli_state_boot) == CHANNELCLI_BUSY) { - if ((readb(&pChan->cli_error_os) + if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) { + if ((readb(&hdr->cli_error_os) & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) { /* we are NOT throttling this message */ - writeb(readb(&pChan->cli_error_os) | + writeb(readb(&hdr->cli_error_os) | ULTRA_CLIERROROS_THROTTLEMSG_BUSY, - &pChan->cli_error_os); + &hdr->cli_error_os); /* throttle until acquire successful */ - pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n", - chanId, pathname_last_n_nodes((u8 *) file, 4), - line); + pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n", + id); } /* reset busy */ - writel(CHANNELCLI_ATTACHED, &pChan->cli_state_os); + writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); mb(); /* required for channel synch */ return 0; } - if (readb(&pChan->cli_error_os) != 0) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ - pr_info("%s Channel OS client acquire now successful @%s:%d\n", - chanId, pathname_last_n_nodes((u8 *) file, 4), - line); - writeb(0, &pChan->cli_error_os); + pr_info("%s Channel OS client acquire now successful\n", id); + writeb(0, &hdr->cli_error_os); } return 1; } diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 44208841bd5a..27d0b2023cc7 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -81,7 +81,7 @@ do_locked_client_insert(struct uisqueue_info *queueinfo, u8 rc = 0; spin_lock_irqsave(lock, flags); - if (!ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(queueinfo->chan, channelId, NULL)) + if (!spar_channel_client_acquire_os(queueinfo->chan, channelId)) goto unlock; if (visor_signal_insert(queueinfo->chan, whichqueue, pSignal)) { queueinfo->packets_sent++; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 9e98af8451b3..5c79455962ea 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1276,8 +1276,8 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, while (1) { spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags); - if (!ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(dc->queueinfo->chan, - "vhba", NULL)) { + if (!spar_channel_client_acquire_os(dc->queueinfo->chan, + "vhba")) { spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags); virthbainfo->acquire_failed_cnt++; -- GitLab From 0859891848dcbf192afa4a73ee5f8ddd5e6c0e11 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:02 -0400 Subject: [PATCH 1353/9457] staging: unisys: refactor ULTRA_channel_client_release_os() Remove the unnecessary macro ULTRA_CHANNEL_CLIENT_RELEASE_OS(), rename the function to spar_channel_client_release_os(), fix references to the macro to call the function directly instead, remove the unnecessary logCtx, file, and line parameters, and fix CamelCase names: pChannel => ch chanId => id pChan => hdr Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 32 +++++++------------ drivers/staging/unisys/uislib/uisqueue.c | 2 +- drivers/staging/unisys/virthba/virthba.c | 3 +- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 8c3fdf7e879f..84f64624bd63 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -149,10 +149,6 @@ ULTRA_CHANNELCLI_STRING(u32 v) mb(); /* required for channel synch */ \ } while (0) -#define ULTRA_CHANNEL_CLIENT_RELEASE_OS(pChan, chanId, logCtx) \ - ULTRA_channel_client_release_os(pChan, chanId, logCtx, \ - (char *)__FILE__, __LINE__, (char *)__func__) - /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */ /* throttling invalid boot channel statetransition error due to client * disabled */ @@ -494,29 +490,25 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) } static inline void -ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId, - void *logCtx, char *file, int line, char *func) +spar_channel_client_release_os(void __iomem *ch, u8 *id) { - struct channel_header __iomem *pChan = pChannel; + struct channel_header __iomem *hdr = ch; - if (readb(&pChan->cli_error_os) != 0) { + if (readb(&hdr->cli_error_os) != 0) { /* we are in an error msg throttling state; come out of it */ - pr_info("%s Channel OS client error state cleared @%s:%d\n", - chanId, pathname_last_n_nodes((u8 *) file, 4), - line); - writeb(0, &pChan->cli_error_os); + pr_info("%s Channel OS client error state cleared\n", id); + writeb(0, &hdr->cli_error_os); } - if (readl(&pChan->cli_state_os) == CHANNELCLI_OWNED) + if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) return; - if (readl(&pChan->cli_state_os) != CHANNELCLI_BUSY) { - pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n", - chanId, ULTRA_CHANNELCLI_STRING( - readl(&pChan->cli_state_os)), - readl(&pChan->cli_state_os), - pathname_last_n_nodes((u8 *) file, 4), line); + if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) { + pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n", + id, ULTRA_CHANNELCLI_STRING( + readl(&hdr->cli_state_os)), + readl(&hdr->cli_state_os)); /* return; */ } - writel(CHANNELCLI_ATTACHED, &pChan->cli_state_os); /* release busy */ + writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */ } /* diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 27d0b2023cc7..b9694a6d40c1 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -87,7 +87,7 @@ do_locked_client_insert(struct uisqueue_info *queueinfo, queueinfo->packets_sent++; rc = 1; } - ULTRA_CHANNEL_CLIENT_RELEASE_OS(queueinfo->chan, channelId, NULL); + spar_channel_client_release_os(queueinfo->chan, channelId); unlock: spin_unlock_irqrestore((spinlock_t *)lock, flags); return rc; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 5c79455962ea..df0e89ccdc18 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1285,8 +1285,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, } qrslt = uisqueue_get_cmdrsp(dc->queueinfo, cmdrsp, IOCHAN_FROM_IOPART); - ULTRA_CHANNEL_CLIENT_RELEASE_OS(dc->queueinfo->chan, - "vhba", NULL); + spar_channel_client_release_os(dc->queueinfo->chan, "vhba"); spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags); if (qrslt == 0) break; -- GitLab From e0fed862c84dbd4b6fce1e6e525767b0a4b95c81 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:03 -0400 Subject: [PATCH 1354/9457] staging: unisys: remove typedef SIGNAL_QUEUE_HEADER Get rid of the typedef for SIGNAL_QUEUE_HEADER and use struct signal_queue_header directly instead. Fix all references to the typedef to use the struct. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 16 ++++---- .../common-spar/include/channels/channel.h | 4 +- .../include/channels/controlvmchannel.h | 8 ++-- .../include/channels/diagchannel.h | 4 +- .../common-spar/include/channels/iochannel.h | 4 +- drivers/staging/unisys/include/uisqueue.h | 4 +- drivers/staging/unisys/virthba/virthba.c | 8 ++-- .../unisys/visorchannel/visorchannel_funcs.c | 41 ++++++++++--------- 8 files changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index c2f95f33b114..d6db66181148 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -50,8 +50,8 @@ visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, void __iomem *psignal; unsigned int head, tail, nof; - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) + Queue; @@ -108,8 +108,8 @@ visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, { void __iomem *psource; unsigned int head, tail; - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) + Queue; /* capture current head and tail */ @@ -163,8 +163,8 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) { void *psource; unsigned int head, tail, signalCount = 0; - pSIGNAL_QUEUE_HEADER pqhdr = - (pSIGNAL_QUEUE_HEADER) ((char *) pChannel + + struct signal_queue_header *pqhdr = + (struct signal_queue_header *) ((char *) pChannel + pChannel->ch_space_offset) + Queue; /* capture current head and tail */ @@ -212,8 +212,8 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) unsigned char visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue) { - SIGNAL_QUEUE_HEADER __iomem *pqhdr = - (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel + + struct signal_queue_header __iomem *pqhdr = + (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) + Queue; return readl(&pqhdr->Head) == readl(&pqhdr->Tail); } diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 84f64624bd63..3c4f7c058e53 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -232,7 +232,7 @@ struct channel_header { #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0) /* Subheader for the Signal Type variation of the Common Channel */ -typedef struct _SIGNAL_QUEUE_HEADER { +struct signal_queue_header { /* 1st cache line */ u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */ u32 Type; /* Queue type: storage, network */ @@ -265,7 +265,7 @@ typedef struct _SIGNAL_QUEUE_HEADER { * to denote trouble with client's * fields */ u8 Filler[12]; /* Pad out to 64 byte cacheline */ -} SIGNAL_QUEUE_HEADER, *pSIGNAL_QUEUE_HEADER; +}; #pragma pack(pop) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 8e8a5a57bddb..91e75f4d3e21 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -542,16 +542,16 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { u32 SPReserved; u8 Reserved2[28]; /* Force signals to begin on 128-byte cache * line */ - SIGNAL_QUEUE_HEADER RequestQueue; /* Service or guest partition + struct signal_queue_header RequestQueue;/* Service or guest partition * uses this queue to send * requests to Control */ - SIGNAL_QUEUE_HEADER ResponseQueue; /* Control uses this queue to + struct signal_queue_header ResponseQueue;/* Control uses this queue to * respond to service or guest * partition requests */ - SIGNAL_QUEUE_HEADER EventQueue; /* Control uses this queue to + struct signal_queue_header EventQueue; /* Control uses this queue to * send events to service or * guest partition */ - SIGNAL_QUEUE_HEADER EventAckQueue; /* Service or guest partition + struct signal_queue_header EventAckQueue;/* Service or guest partition * uses this queue to ack * Control events */ diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 590022fd9fb6..919f628360c2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -384,7 +384,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { /* Offsets/sizes for diagnostic channel attributes... */ #define DIAG_CH_QUEUE_HEADER_OFFSET (sizeof(struct channel_header)) -#define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(SIGNAL_QUEUE_HEADER)) +#define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(struct signal_queue_header)) #define DIAG_CH_PROTOCOL_HEADER_OFFSET \ (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE) #define DIAG_CH_PROTOCOL_HEADER_SIZE (sizeof(DIAG_CHANNEL_PROTOCOL_HEADER)) @@ -417,7 +417,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { */ typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { struct channel_header CommonChannelHeader; - SIGNAL_QUEUE_HEADER QueueHeader; + struct signal_queue_header QueueHeader; DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader; DIAG_CHANNEL_EVENT Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / sizeof(DIAG_CHANNEL_EVENT)]; diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index c26363de86dd..ac78d9c2585c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -686,8 +686,8 @@ struct uiscmdrsp { * response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { struct channel_header ChannelHeader; - SIGNAL_QUEUE_HEADER cmdQ; - SIGNAL_QUEUE_HEADER rspQ; + struct signal_queue_header cmdQ; + struct signal_queue_header rspQ; union { struct { struct vhba_wwnn wwnn; /* 8 bytes */ diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index 7d01c42abcb9..25b6181d78af 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -47,8 +47,8 @@ struct uisqueue_info { u64 non_empty_wakeup_cnt; struct { - SIGNAL_QUEUE_HEADER reserved1; /* */ - SIGNAL_QUEUE_HEADER reserved2; /* */ + struct signal_queue_header reserved1; /* */ + struct signal_queue_header reserved2; /* */ } safe_uis_queue; unsigned int (*send_int_if_needed)(struct uisqueue_info *info, unsigned int whichcqueue, diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index df0e89ccdc18..9d4653d34608 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -421,7 +421,7 @@ virthba_ISR(int irq, void *dev_id) { struct virthba_info *virthbainfo = (struct virthba_info *) dev_id; struct channel_header __iomem *pChannelHeader; - SIGNAL_QUEUE_HEADER __iomem *pqhdr; + struct signal_queue_header __iomem *pqhdr; u64 mask; unsigned long long rc1; @@ -442,7 +442,7 @@ virthba_ISR(int irq, void *dev_id) virthbainfo->interrupts_notme++; return IRQ_NONE; } - pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) + pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *) pChannelHeader + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; writeq(readq(&pqhdr->NumInterruptsReceived) + 1, @@ -462,7 +462,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) int i; irq_handler_t handler = virthba_ISR; struct channel_header __iomem *pChannelHeader; - SIGNAL_QUEUE_HEADER __iomem *pqhdr; + struct signal_queue_header __iomem *pqhdr; u64 mask; LOGVER("entering virthba_probe...\n"); @@ -586,7 +586,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo); pChannelHeader = virthbainfo->chinfo.queueinfo->chan; - pqhdr = (SIGNAL_QUEUE_HEADER __iomem *) + pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *)pChannelHeader + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; virthbainfo->flags_addr = &pqhdr->FeatureFlags; diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 19f5c775ca88..7b30c66d3a3e 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -38,10 +38,10 @@ struct VISORCHANNEL_Tag { spinlock_t remove_lock; struct { - SIGNAL_QUEUE_HEADER req_queue; - SIGNAL_QUEUE_HEADER rsp_queue; - SIGNAL_QUEUE_HEADER event_queue; - SIGNAL_QUEUE_HEADER ack_queue; + struct signal_queue_header req_queue; + struct signal_queue_header rsp_queue; + struct signal_queue_header event_queue; + struct signal_queue_header ack_queue; } safe_uis_queue; }; @@ -295,7 +295,8 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); * channel header */ #define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->ch_space_offset + ((q) * sizeof(SIGNAL_QUEUE_HEADER))) + ((chan_hdr)->ch_space_offset + \ + ((q) * sizeof(struct signal_queue_header))) /** Return offset of a specific queue entry (data) from the beginning of a * channel header @@ -310,13 +311,13 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ (visor_memregion_write(channel->memregion, \ SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)+ \ - offsetof(SIGNAL_QUEUE_HEADER, FIELD), \ + offsetof(struct signal_queue_header, FIELD),\ &((sig_hdr)->FIELD), \ sizeof((sig_hdr)->FIELD)) >= 0) static BOOL sig_read_header(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr) + struct signal_queue_header *sig_hdr) { BOOL rc = FALSE; @@ -329,7 +330,8 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, if (visor_memregion_read(channel->memregion, SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), - sig_hdr, sizeof(SIGNAL_QUEUE_HEADER)) < 0) { + sig_hdr, + sizeof(struct signal_queue_header)) < 0) { ERRDRV("queue=%d SIG_QUEUE_OFFSET=%d", queue, (int)SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)); ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", rc); @@ -342,7 +344,8 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, static BOOL sig_do_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data, BOOL is_write) + struct signal_queue_header *sig_hdr, u32 slot, void *data, + BOOL is_write) { BOOL rc = FALSE; int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, @@ -368,21 +371,21 @@ sig_do_data(VISORCHANNEL *channel, u32 queue, static inline BOOL sig_read_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data) + struct signal_queue_header *sig_hdr, u32 slot, void *data) { return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE); } static inline BOOL sig_write_data(VISORCHANNEL *channel, u32 queue, - SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data) + struct signal_queue_header *sig_hdr, u32 slot, void *data) { return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE); } static inline unsigned char -safe_sig_queue_validate(pSIGNAL_QUEUE_HEADER psafe_sqh, - pSIGNAL_QUEUE_HEADER punsafe_sqh, +safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, + struct signal_queue_header *punsafe_sqh, u32 *phead, u32 *ptail) { if ((*phead >= psafe_sqh->MaxSignalSlots) @@ -406,7 +409,7 @@ BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->remove_lock); @@ -452,7 +455,7 @@ BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) { BOOL rc = FALSE; - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (channel->needs_lock) spin_lock(&channel->insert_lock); @@ -505,7 +508,7 @@ EXPORT_SYMBOL_GPL(visorchannel_signalinsert); int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) { - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; u32 slots_avail, slots_used; u32 head, tail; @@ -524,7 +527,7 @@ EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail); int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) { - SIGNAL_QUEUE_HEADER sig_hdr; + struct signal_queue_header sig_hdr; if (!sig_read_header(channel, queue, &sig_hdr)) return 0; @@ -533,7 +536,7 @@ visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots); static void -sigqueue_debug(SIGNAL_QUEUE_HEADER *q, int which, struct seq_file *seq) +sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq) { seq_printf(seq, "Signal Queue #%d\n", which); seq_printf(seq, " VersionId = %lu\n", (ulong) q->VersionId); @@ -617,7 +620,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, ; else for (i = 0; i < nQueues; i++) { - SIGNAL_QUEUE_HEADER q; + struct signal_queue_header q; errcode = visorchannel_read(channel, off + phdr->ch_space_offset + -- GitLab From 153cf7107214f0fc51df895f4fdd4f4b14011d0e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:04 -0400 Subject: [PATCH 1355/9457] staging: unisys: fix CamelCase in struct signal_queue_header Fix CamelCase names: VersionId => version Type => chtype Size => size oSignalBase => sig_base_offset FeatureFlags => features NumSignalsSent => num_sent NumOverflows => num_overflows SignalSize => signal_size MaxSignalSlots => max_slots MaxSignals => max_signals Head => head NumSignalsReceived => num_received Tail => tail Reserved1 => reserved1 Reserved2 => reserved2 ClientQueue => client_queue NumInterruptsReceived => num_irq_received NumEmptyCnt => num_empty ErrorFlags => errorflags Filler => filler Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 62 +++++++------- .../common-spar/include/channels/channel.h | 40 +++++----- .../common-spar/include/channels/iochannel.h | 38 ++++----- drivers/staging/unisys/virthba/virthba.c | 6 +- .../unisys/visorchannel/visorchannel_funcs.c | 80 +++++++++---------- 5 files changed, 113 insertions(+), 113 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index d6db66181148..0a98c5c67ff9 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -56,30 +56,30 @@ visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, + Queue; /* capture current head and tail */ - head = readl(&pqhdr->Head); - tail = readl(&pqhdr->Tail); + head = readl(&pqhdr->head); + tail = readl(&pqhdr->tail); /* queue is full if (head + 1) % n equals tail */ - if (((head + 1) % readl(&pqhdr->MaxSignalSlots)) == tail) { - nof = readq(&pqhdr->NumOverflows) + 1; - writeq(nof, &pqhdr->NumOverflows); + if (((head + 1) % readl(&pqhdr->max_slots)) == tail) { + nof = readq(&pqhdr->num_overflows) + 1; + writeq(nof, &pqhdr->num_overflows); return 0; } /* increment the head index */ - head = (head + 1) % readl(&pqhdr->MaxSignalSlots); + head = (head + 1) % readl(&pqhdr->max_slots); /* copy signal to the head location from the area pointed to * by pSignal */ - psignal = (char __iomem *)pqhdr + readq(&pqhdr->oSignalBase) + - (head * readl(&pqhdr->SignalSize)); - memcpy_toio(psignal, pSignal, readl(&pqhdr->SignalSize)); + psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) + + (head * readl(&pqhdr->signal_size)); + memcpy_toio(psignal, pSignal, readl(&pqhdr->signal_size)); mb(); /* channel synch */ - writel(head, &pqhdr->Head); + writel(head, &pqhdr->head); - writeq(readq(&pqhdr->NumSignalsSent) + 1, &pqhdr->NumSignalsSent); + writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent); return 1; } EXPORT_SYMBOL_GPL(visor_signal_insert); @@ -113,28 +113,28 @@ visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, readq(&pChannel->ch_space_offset)) + Queue; /* capture current head and tail */ - head = readl(&pqhdr->Head); - tail = readl(&pqhdr->Tail); + head = readl(&pqhdr->head); + tail = readl(&pqhdr->tail); /* queue is empty if the head index equals the tail index */ if (head == tail) { - writeq(readq(&pqhdr->NumEmptyCnt) + 1, &pqhdr->NumEmptyCnt); + writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty); return 0; } /* advance past the 'empty' front slot */ - tail = (tail + 1) % readl(&pqhdr->MaxSignalSlots); + tail = (tail + 1) % readl(&pqhdr->max_slots); /* copy signal from tail location to the area pointed to by pSignal */ - psource = (char __iomem *) pqhdr + readq(&pqhdr->oSignalBase) + - (tail * readl(&pqhdr->SignalSize)); - memcpy_fromio(pSignal, psource, readl(&pqhdr->SignalSize)); + psource = (char __iomem *) pqhdr + readq(&pqhdr->sig_base_offset) + + (tail * readl(&pqhdr->signal_size)); + memcpy_fromio(pSignal, psource, readl(&pqhdr->signal_size)); mb(); /* channel synch */ - writel(tail, &pqhdr->Tail); + writel(tail, &pqhdr->tail); - writeq(readq(&pqhdr->NumSignalsReceived) + 1, - &pqhdr->NumSignalsReceived); + writeq(readq(&pqhdr->num_received) + 1, + &pqhdr->num_received); return 1; } EXPORT_SYMBOL_GPL(visor_signal_remove); @@ -168,8 +168,8 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) pChannel->ch_space_offset) + Queue; /* capture current head and tail */ - head = pqhdr->Head; - tail = pqhdr->Tail; + head = pqhdr->head; + tail = pqhdr->tail; /* queue is empty if the head index equals the tail index */ if (head == tail) @@ -177,22 +177,22 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) while (head != tail) { /* advance past the 'empty' front slot */ - tail = (tail + 1) % pqhdr->MaxSignalSlots; + tail = (tail + 1) % pqhdr->max_slots; /* copy signal from tail location to the area pointed * to by pSignal */ psource = - (char *) pqhdr + pqhdr->oSignalBase + - (tail * pqhdr->SignalSize); - memcpy((char *) pSignal + (pqhdr->SignalSize * signalCount), - psource, pqhdr->SignalSize); + (char *) pqhdr + pqhdr->sig_base_offset + + (tail * pqhdr->signal_size); + memcpy((char *) pSignal + (pqhdr->signal_size * signalCount), + psource, pqhdr->signal_size); mb(); /* channel synch */ - pqhdr->Tail = tail; + pqhdr->tail = tail; signalCount++; - pqhdr->NumSignalsReceived++; + pqhdr->num_received++; } return signalCount; @@ -215,7 +215,7 @@ visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue) struct signal_queue_header __iomem *pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) + Queue; - return readl(&pqhdr->Head) == readl(&pqhdr->Tail); + return readl(&pqhdr->head) == readl(&pqhdr->tail); } EXPORT_SYMBOL_GPL(visor_signalqueue_empty); diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 3c4f7c058e53..c01c2e69379d 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -234,37 +234,37 @@ struct channel_header { /* Subheader for the Signal Type variation of the Common Channel */ struct signal_queue_header { /* 1st cache line */ - u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */ - u32 Type; /* Queue type: storage, network */ - u64 Size; /* Total size of this queue in bytes */ - u64 oSignalBase; /* Offset to signal queue area */ - u64 FeatureFlags; /* Flags to modify behavior */ - u64 NumSignalsSent; /* Total # of signals placed in this queue */ - u64 NumOverflows; /* Total # of inserts failed due to + u32 version; /* SIGNAL_QUEUE_HEADER Version ID */ + u32 chtype; /* Queue type: storage, network */ + u64 size; /* Total size of this queue in bytes */ + u64 sig_base_offset; /* Offset to signal queue area */ + u64 features; /* Flags to modify behavior */ + u64 num_sent; /* Total # of signals placed in this queue */ + u64 num_overflows; /* Total # of inserts failed due to * full queue */ - u32 SignalSize; /* Total size of a signal for this queue */ - u32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is + u32 signal_size; /* Total size of a signal for this queue */ + u32 max_slots; /* Max # of slots in queue, 1 slot is * always empty */ - u32 MaxSignals; /* Max # of signals in queue + u32 max_signals; /* Max # of signals in queue * (MaxSignalSlots-1) */ - u32 Head; /* Queue head signal # */ + u32 head; /* Queue head signal # */ /* 2nd cache line */ - u64 NumSignalsReceived; /* Total # of signals removed from this queue */ - u32 Tail; /* Queue tail signal # (on separate + u64 num_received; /* Total # of signals removed from this queue */ + u32 tail; /* Queue tail signal # (on separate * cache line) */ - u32 Reserved1; /* Reserved field */ - u64 Reserved2; /* Resrved field */ - u64 ClientQueue; - u64 NumInterruptsReceived; /* Total # of Interrupts received. This + u32 reserved1; /* Reserved field */ + u64 reserved2; /* Reserved field */ + u64 client_queue; + u64 num_irq_received; /* Total # of Interrupts received. This * is incremented by the ISR in the * guest windows driver */ - u64 NumEmptyCnt; /* Number of times that visor_signal_remove + u64 num_empty; /* Number of times that visor_signal_remove * is called and returned Empty * Status. */ - u32 ErrorFlags; /* Error bits set during SignalReinit + u32 errorflags; /* Error bits set during SignalReinit * to denote trouble with client's * fields */ - u8 Filler[12]; /* Pad out to 64 byte cacheline */ + u8 filler[12]; /* Pad out to 64 byte cacheline */ }; #pragma pack(pop) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index ac78d9c2585c..d487cb2f06aa 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -750,21 +750,21 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { #define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP) #define SignalQInit(x) \ do { \ - x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.size); \ - x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \ + x->cmdQ.size = QSIZEFROMBYTES(x->ChannelHeader.size); \ + x->cmdQ.sig_base_offset = SIZEOF_PROTOCOL - \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ - x->cmdQ.SignalSize = SIZEOF_CMDRSP; \ - x->cmdQ.MaxSignalSlots = \ + x->cmdQ.signal_size = SIZEOF_CMDRSP; \ + x->cmdQ.max_slots = \ QSLOTSFROMBYTES(x->ChannelHeader.size); \ - x->cmdQ.MaxSignals = x->cmdQ.MaxSignalSlots - 1; \ - x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.size); \ - x->rspQ.oSignalBase = \ - (SIZEOF_PROTOCOL + x->cmdQ.Size) - \ + x->cmdQ.max_signals = x->cmdQ.max_slots - 1; \ + x->rspQ.size = QSIZEFROMBYTES(x->ChannelHeader.size); \ + x->rspQ.sig_base_offset = \ + (SIZEOF_PROTOCOL + x->cmdQ.size) - \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ - x->rspQ.SignalSize = SIZEOF_CMDRSP; \ - x->rspQ.MaxSignalSlots = \ + x->rspQ.signal_size = SIZEOF_CMDRSP; \ + x->rspQ.max_slots = \ QSLOTSFROMBYTES(x->ChannelHeader.size); \ - x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \ + x->rspQ.max_signals = x->rspQ.max_slots - 1; \ x->ChannelHeader.ch_space_offset = \ offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ } while (0) @@ -814,12 +814,12 @@ static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, clientStrLen); SignalQInit(x); - if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) { + if ((x->cmdQ.max_slots > MAX_NUMSIGNALS) || + (x->rspQ.max_slots > MAX_NUMSIGNALS)) { return 0; } - if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) { + if ((x->cmdQ.max_slots < MIN_NUMSIGNALS) || + (x->rspQ.max_slots < MIN_NUMSIGNALS)) { return 0; } return 1; @@ -852,12 +852,12 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, clientStrLen); SignalQInit(x); - if ((x->cmdQ.MaxSignalSlots > MAX_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots > MAX_NUMSIGNALS)) { + if ((x->cmdQ.max_slots > MAX_NUMSIGNALS) || + (x->rspQ.max_slots > MAX_NUMSIGNALS)) { return 0; } - if ((x->cmdQ.MaxSignalSlots < MIN_NUMSIGNALS) || - (x->rspQ.MaxSignalSlots < MIN_NUMSIGNALS)) { + if ((x->cmdQ.max_slots < MIN_NUMSIGNALS) || + (x->rspQ.max_slots < MIN_NUMSIGNALS)) { return 0; } return 1; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 9d4653d34608..a3da5e999331 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -445,8 +445,8 @@ virthba_ISR(int irq, void *dev_id) pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *) pChannelHeader + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; - writeq(readq(&pqhdr->NumInterruptsReceived) + 1, - &pqhdr->NumInterruptsReceived); + writeq(readq(&pqhdr->num_irq_received) + 1, + &pqhdr->num_irq_received); atomic_set(&virthbainfo->interrupt_rcvd, 1); wake_up_interruptible(&virthbainfo->rsp_queue); return IRQ_HANDLED; @@ -589,7 +589,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) pqhdr = (struct signal_queue_header __iomem *) ((char __iomem *)pChannelHeader + readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART; - virthbainfo->flags_addr = &pqhdr->FeatureFlags; + virthbainfo->flags_addr = &pqhdr->features; if (!uisthread_start(&virthbainfo->chinfo.threadinfo, process_incoming_rsps, diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 7b30c66d3a3e..c24052b13fd2 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -302,8 +302,8 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header); * channel header */ #define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \ - (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->oSignalBase + \ - ((slot) * (sig_hdr)->SignalSize)) + (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \ + ((slot) * (sig_hdr)->signal_size)) /** Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back * into host memory @@ -353,13 +353,13 @@ sig_do_data(VISORCHANNEL *channel, u32 queue, if (is_write) { if (visor_memregion_write(channel->memregion, signal_data_offset, - data, sig_hdr->SignalSize) < 0) { + data, sig_hdr->signal_size) < 0) { ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", rc); goto Away; } } else { if (visor_memregion_read(channel->memregion, signal_data_offset, - data, sig_hdr->SignalSize) < 0) { + data, sig_hdr->signal_size) < 0) { ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", rc); goto Away; } @@ -388,18 +388,18 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, struct signal_queue_header *punsafe_sqh, u32 *phead, u32 *ptail) { - if ((*phead >= psafe_sqh->MaxSignalSlots) - || (*ptail >= psafe_sqh->MaxSignalSlots)) { + if ((*phead >= psafe_sqh->max_slots) + || (*ptail >= psafe_sqh->max_slots)) { /* Choose 0 or max, maybe based on current tail value */ *phead = 0; *ptail = 0; /* Sync with client as necessary */ - punsafe_sqh->Head = *phead; - punsafe_sqh->Tail = *ptail; + punsafe_sqh->head = *phead; + punsafe_sqh->tail = *ptail; ERRDRV("safe_sig_queue_validate: head = 0x%x, tail = 0x%x, MaxSlots = 0x%x", - *phead, *ptail, psafe_sqh->MaxSignalSlots); + *phead, *ptail, psafe_sqh->max_slots); return 0; } return 1; @@ -418,27 +418,27 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) rc = FALSE; goto Away; } - if (sig_hdr.Head == sig_hdr.Tail) { + if (sig_hdr.head == sig_hdr.tail) { rc = FALSE; /* no signals to remove */ goto Away; } - sig_hdr.Tail = (sig_hdr.Tail + 1) % sig_hdr.MaxSignalSlots; - if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.Tail, msg)) { + sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; + if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { ERRDRV("sig_read_data failed: (status=%d)\n", rc); goto Away; } - sig_hdr.NumSignalsReceived++; + sig_hdr.num_received++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Tail)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); goto Away; } - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsReceived)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); goto Away; } @@ -465,10 +465,10 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) goto Away; } - sig_hdr.Head = ((sig_hdr.Head + 1) % sig_hdr.MaxSignalSlots); - if (sig_hdr.Head == sig_hdr.Tail) { - sig_hdr.NumOverflows++; - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumOverflows)) { + sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); + if (sig_hdr.head == sig_hdr.tail) { + sig_hdr.num_overflows++; + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); goto Away; } @@ -476,22 +476,22 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) goto Away; } - if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.Head, msg)) { + if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { ERRDRV("sig_write_data failed: (status=%d)\n", rc); goto Away; } - sig_hdr.NumSignalsSent++; + sig_hdr.num_sent++; /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ mb(); /* required for channel synch */ - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Head)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); goto Away; } - if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, NumSignalsSent)) { + if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); goto Away; } @@ -514,12 +514,12 @@ visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) if (!sig_read_header(channel, queue, &sig_hdr)) return 0; - head = sig_hdr.Head; - tail = sig_hdr.Tail; + head = sig_hdr.head; + tail = sig_hdr.tail; if (head < tail) - head = head + sig_hdr.MaxSignalSlots; + head = head + sig_hdr.max_slots; slots_used = (head - tail); - slots_avail = sig_hdr.MaxSignals - slots_used; + slots_avail = sig_hdr.max_signals - slots_used; return (int) slots_avail; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail); @@ -531,7 +531,7 @@ visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) if (!sig_read_header(channel, queue, &sig_hdr)) return 0; - return (int) sig_hdr.MaxSignals; + return (int) sig_hdr.max_signals; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots); @@ -539,24 +539,24 @@ static void sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq) { seq_printf(seq, "Signal Queue #%d\n", which); - seq_printf(seq, " VersionId = %lu\n", (ulong) q->VersionId); - seq_printf(seq, " Type = %lu\n", (ulong) q->Type); + seq_printf(seq, " VersionId = %lu\n", (ulong)q->version); + seq_printf(seq, " Type = %lu\n", (ulong)q->chtype); seq_printf(seq, " oSignalBase = %llu\n", - (long long) q->oSignalBase); - seq_printf(seq, " SignalSize = %lu\n", (ulong) q->SignalSize); + (long long)q->sig_base_offset); + seq_printf(seq, " SignalSize = %lu\n", (ulong)q->signal_size); seq_printf(seq, " MaxSignalSlots = %lu\n", - (ulong) q->MaxSignalSlots); - seq_printf(seq, " MaxSignals = %lu\n", (ulong) q->MaxSignals); + (ulong)q->max_slots); + seq_printf(seq, " MaxSignals = %lu\n", (ulong)q->max_signals); seq_printf(seq, " FeatureFlags = %-16.16Lx\n", - (long long) q->FeatureFlags); + (long long)q->features); seq_printf(seq, " NumSignalsSent = %llu\n", - (long long) q->NumSignalsSent); + (long long)q->num_sent); seq_printf(seq, " NumSignalsReceived = %llu\n", - (long long) q->NumSignalsReceived); + (long long)q->num_received); seq_printf(seq, " NumOverflows = %llu\n", - (long long) q->NumOverflows); - seq_printf(seq, " Head = %lu\n", (ulong) q->Head); - seq_printf(seq, " Tail = %lu\n", (ulong) q->Tail); + (long long)q->num_overflows); + seq_printf(seq, " Head = %lu\n", (ulong)q->head); + seq_printf(seq, " Tail = %lu\n", (ulong)q->tail); } void -- GitLab From 93a8456556b430f5b4d753ee8872c2a7a0dd24e9 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:05 -0400 Subject: [PATCH 1356/9457] staging: unisys: refactor ULTRA_check_channel_client() Rename the function ULTRA_check_channel_client() to spar_check_channel_client(), and fix CamelCase parameter names: pChannel => ch expectedTypeGuid => expected_uuid channelName => chname expectedMinBytes => expected_min_bytes expectedVersionId => expected_version expectedSignature => expected_signature Rename macros that use spar_check_channel_client: ULTRA_CONTROLVM_CHANNEL_OK_CLIENT => SPAR_CONTROLVM_CHANNEL_OK_CLIENT ULTRA_VHBA_CHANNEL_OK_CLIENT => SPAR_VHBA_CHANNEL_OK_CLIENT ULTRA_VNIC_CHANNEL_OK_CLIENT => SPAR_VNIC_CHANNEL_OK_CLIENT ULTRA_VSWITCH_CHANNEL_OK_CLIENT => SPAR_VSWITCH_CHANNEL_OK_CLIENT ULTRA_VBUS_CHANNEL_OK_CLIENT => SPAR_VBUS_CHANNEL_OK_CLIENT Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 13 ++- drivers/staging/unisys/channels/chanstub.c | 2 +- .../common-spar/include/channels/channel.h | 82 +++++++------------ .../include/channels/controlvmchannel.h | 20 ++--- .../include/channels/diagchannel.h | 5 +- .../common-spar/include/channels/iochannel.h | 47 ++++------- .../include/channels/vbuschannel.h | 21 ++--- drivers/staging/unisys/uislib/uislib.c | 6 +- drivers/staging/unisys/uislib/uisqueue.c | 2 +- .../unisys/visorchipset/visorchipset_main.c | 5 +- 10 files changed, 73 insertions(+), 130 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index 0a98c5c67ff9..4737b77476e1 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -43,17 +43,16 @@ * Return value: * 1 if the insertion succeeds, 0 if the queue was full. */ -unsigned char -visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, - void *pSignal) +unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, + void *sig) { void __iomem *psignal; unsigned int head, tail, nof; struct signal_queue_header __iomem *pqhdr = (struct signal_queue_header __iomem *) - ((char __iomem *) pChannel + readq(&pChannel->ch_space_offset)) - + Queue; + ((char __iomem *) ch + readq(&ch->ch_space_offset)) + + queue; /* capture current head and tail */ head = readl(&pqhdr->head); @@ -74,7 +73,7 @@ visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, */ psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) + (head * readl(&pqhdr->signal_size)); - memcpy_toio(psignal, pSignal, readl(&pqhdr->signal_size)); + memcpy_toio(psignal, sig, readl(&pqhdr->signal_size)); mb(); /* channel synch */ writel(head, &pqhdr->head); @@ -82,7 +81,7 @@ visor_signal_insert(struct channel_header __iomem *pChannel, u32 Queue, writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent); return 1; } -EXPORT_SYMBOL_GPL(visor_signal_insert); +EXPORT_SYMBOL_GPL(spar_signal_insert); /* * Routine Description: diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c index 23d5aafef2cd..fae9ab3d0f60 100644 --- a/drivers/staging/unisys/channels/chanstub.c +++ b/drivers/staging/unisys/channels/chanstub.c @@ -49,7 +49,7 @@ SignalInsert_withLock(struct channel_header __iomem *pChannel, u32 Queue, unsigned long flags; spin_lock_irqsave(lock, flags); - result = visor_signal_insert(pChannel, Queue, pSignal); + result = spar_signal_insert(pChannel, Queue, pSignal); spin_unlock_irqrestore(lock, flags); return result; } diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index c01c2e69379d..16dd7a339433 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -289,89 +289,65 @@ struct signal_queue_header { * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. */ static inline int -ULTRA_check_channel_client(void __iomem *pChannel, - uuid_le expectedTypeGuid, - char *channelName, - u64 expectedMinBytes, - u32 expectedVersionId, - u64 expectedSignature, - char *fileName, int lineNumber, void *logCtx) +spar_check_channel_client(void __iomem *ch, + uuid_le expected_uuid, + char *chname, + u64 expected_min_bytes, + u32 expected_version, + u64 expected_signature) { - if (uuid_le_cmp(expectedTypeGuid, NULL_UUID_LE) != 0) { + if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) { uuid_le guid; memcpy_fromio(&guid, - &((struct channel_header __iomem *)(pChannel))->chtype, - sizeof(guid)); + &((struct channel_header __iomem *)(ch))->chtype, + sizeof(guid)); /* caller wants us to verify type GUID */ - if (uuid_le_cmp(guid, expectedTypeGuid) != 0) { + if (uuid_le_cmp(guid, expected_uuid) != 0) { pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", - channelName, &expectedTypeGuid, - &expectedTypeGuid, &guid); + chname, &expected_uuid, + &expected_uuid, &guid); return 0; } } - if (expectedMinBytes > 0) { /* caller wants us to verify + if (expected_min_bytes > 0) { /* caller wants us to verify * channel size */ unsigned long long bytes = readq(&((struct channel_header __iomem *) - (pChannel))->size); - if (bytes < expectedMinBytes) { + (ch))->size); + if (bytes < expected_min_bytes) { pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - channelName, &expectedTypeGuid, - (unsigned long long)expectedMinBytes, bytes); + chname, &expected_uuid, + (unsigned long long)expected_min_bytes, bytes); return 0; } } - if (expectedVersionId > 0) { /* caller wants us to verify + if (expected_version > 0) { /* caller wants us to verify * channel version */ unsigned long ver = readl(&((struct channel_header __iomem *) - (pChannel))->version_id); - if (ver != expectedVersionId) { + (ch))->version_id); + if (ver != expected_version) { pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n", - channelName, &expectedTypeGuid, - (unsigned long)expectedVersionId, ver); + chname, &expected_uuid, + (unsigned long)expected_version, ver); return 0; } } - if (expectedSignature > 0) { /* caller wants us to verify + if (expected_signature > 0) { /* caller wants us to verify * channel signature */ unsigned long long sig = readq(&((struct channel_header __iomem *) - (pChannel))->signature); - if (sig != expectedSignature) { + (ch))->signature); + if (sig != expected_signature) { pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n", - channelName, &expectedTypeGuid, - expectedSignature, sig); + chname, &expected_uuid, + expected_signature, sig); return 0; } } return 1; } -/* Generic function useful for validating any type of channel when it is about - * to be initialized by the server of the channel. - * Note that is only needed for callers in the EFI environment, and - * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. - */ -static inline int -ULTRA_check_channel_server(uuid_le typeGuid, - char *channelName, - u64 expectedMinBytes, - u64 actualBytes, - char *fileName, int lineNumber, void *logCtx) -{ - if (expectedMinBytes > 0) /* caller wants us to verify - * channel size */ - if (actualBytes < expectedMinBytes) { - pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n", - channelName, &typeGuid, expectedMinBytes, - actualBytes); - return 0; - } - return 1; -} - /* Given a file pathname (with '/' or '\' separating directory nodes), * returns a pointer to the beginning of a node within that pathname such * that the number of nodes from that pointer to the end of the string is @@ -530,8 +506,8 @@ spar_channel_client_release_os(void __iomem *ch, u8 *id) * full. */ -unsigned char visor_signal_insert(struct channel_header __iomem *pChannel, - u32 Queue, void *pSignal); +unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, + void *sig); /* * Routine Description: diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 91e75f4d3e21..9a7531f66fdb 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -45,19 +45,13 @@ static const uuid_le UltraControlvmChannelProtocolGuid = * channel struct withOUT needing to increment this. */ #define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_CONTROLVM_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ - UltraControlvmChannelProtocolGuid, \ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraControlvmChannelProtocolGuid, \ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - actualBytes, __FILE__, __LINE__, logCtx)) +#define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(pChannel) \ + (spar_check_channel_client(pChannel, \ + UltraControlvmChannelProtocolGuid, \ + "controlvm", \ + sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 919f628360c2..97451bab64d2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -59,13 +59,12 @@ static const uuid_le UltraDiagChannelProtocolGuid = #define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2 #define ULTRA_DIAG_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ + (spar_check_channel_client(pChannel, \ UltraDiagChannelProtocolGuid, \ "diag", \ sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) + ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) #define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes, logCtx) \ (ULTRA_check_channel_server(UltraDiagChannelProtocolGuid, \ "diag", \ diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index d487cb2f06aa..f5fd542bb67f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -60,37 +60,22 @@ #define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, spar_vhba_channel_protocol_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(spar_vhba_channel_protocol_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, actualBytes, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(spar_vnic_channel_protocol_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, actualBytes, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) -#define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - actualBytes, \ - __FILE__, __LINE__, logCtx)) +#define SPAR_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \ + (spar_check_channel_client(pChannel, spar_vhba_channel_protocol_uuid, \ + "vhba", MIN_IO_CHANNEL_SIZE, \ + ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) +#define SPAR_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ + (spar_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ + "vnic", MIN_IO_CHANNEL_SIZE, \ + ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) +#define SPAR_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ + (spar_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ + "vswitch", MIN_IO_CHANNEL_SIZE, \ + ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE)) + /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 76bc7140d5e7..7b32aa9fb90b 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -43,22 +43,13 @@ static const uuid_le UltraVbusChannelProtocolGuid = * increment this. */ #define ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 -#define ULTRA_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (ULTRA_check_channel_client(pChannel, \ - UltraVbusChannelProtocolGuid, \ - "vbus", \ - sizeof(struct ultra_vbus_channel_protocol),\ +#define SPAR_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \ + (spar_check_channel_client(pChannel, \ + UltraVbusChannelProtocolGuid, \ + "vbus", \ + sizeof(struct ultra_vbus_channel_protocol),\ ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE, \ - __FILE__, __LINE__, logCtx)) - -#define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraVbusChannelProtocolGuid, \ - "vbus", \ - sizeof(struct ultra_vbus_channel_protocol),\ - actualBytes, \ - __FILE__, __LINE__, logCtx)) - + ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE)) \ #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ typedef struct _ULTRA_VBUS_HEADERINFO { diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 687b7db94fe5..bcb80ba40160 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -142,7 +142,7 @@ init_vbus_channel(u64 channelAddr, u32 channelBytes) rc = NULL; goto Away; } - if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) { + if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) { ERRDRV("%s channel cannot be used", __func__); uislib_iounmap(pChan); rc = NULL; @@ -449,7 +449,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) __iomem *) (dev-> chanptr))-> chtype); - if (!ULTRA_VHBA_CHANNEL_OK_CLIENT + if (!SPAR_VHBA_CHANNEL_OK_CLIENT (dev->chanptr, NULL)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.", devNo); @@ -475,7 +475,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) __iomem *) (dev-> chanptr))-> chtype); - if (!ULTRA_VNIC_CHANNEL_OK_CLIENT + if (!SPAR_VNIC_CHANNEL_OK_CLIENT (dev->chanptr, NULL)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.", devNo); diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index b9694a6d40c1..66da828ca352 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -83,7 +83,7 @@ do_locked_client_insert(struct uisqueue_info *queueinfo, spin_lock_irqsave(lock, flags); if (!spar_channel_client_acquire_os(queueinfo->chan, channelId)) goto unlock; - if (visor_signal_insert(queueinfo->chan, whichqueue, pSignal)) { + if (spar_signal_insert(queueinfo->chan, whichqueue, pSignal)) { queueinfo->packets_sent++; rc = 1; } diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index e26db99c4d58..c94d65518f46 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2382,9 +2382,8 @@ visorchipset_init(void) (addr, sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), UltraControlvmChannelProtocolGuid); - if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT - (visorchannel_get_header(ControlVm_channel), - NULL)) { + if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( + visorchannel_get_header(ControlVm_channel))) { LOGINF("Channel %s (ControlVm) discovered", visorchannel_id(ControlVm_channel, s)); initialize_controlvm_payload(); -- GitLab From 3f12c5f95955ee979f55e599a586e065e710e80e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:06 -0400 Subject: [PATCH 1357/9457] staging: unisys: refactor visor_signal_remove() Rename visor_signal_remove() to spar_signal_remove() and fix CamelCase parameter names: pChannel => ch Queue => queue pSignal => sig Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 11 +++++------ drivers/staging/unisys/channels/chanstub.c | 2 +- .../unisys/common-spar/include/channels/channel.h | 4 ++-- drivers/staging/unisys/uislib/uisqueue.c | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index 4737b77476e1..0b9a7cf35698 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -102,14 +102,13 @@ EXPORT_SYMBOL_GPL(spar_signal_insert); * 1 if the removal succeeds, 0 if the queue was empty. */ unsigned char -visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, - void *pSignal) +spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig) { void __iomem *psource; unsigned int head, tail; struct signal_queue_header __iomem *pqhdr = - (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->ch_space_offset)) + Queue; + (struct signal_queue_header __iomem *) ((char __iomem *) ch + + readq(&ch->ch_space_offset)) + queue; /* capture current head and tail */ head = readl(&pqhdr->head); @@ -127,7 +126,7 @@ visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, /* copy signal from tail location to the area pointed to by pSignal */ psource = (char __iomem *) pqhdr + readq(&pqhdr->sig_base_offset) + (tail * readl(&pqhdr->signal_size)); - memcpy_fromio(pSignal, psource, readl(&pqhdr->signal_size)); + memcpy_fromio(sig, psource, readl(&pqhdr->signal_size)); mb(); /* channel synch */ writel(tail, &pqhdr->tail); @@ -136,7 +135,7 @@ visor_signal_remove(struct channel_header __iomem *pChannel, u32 Queue, &pqhdr->num_received); return 1; } -EXPORT_SYMBOL_GPL(visor_signal_remove); +EXPORT_SYMBOL_GPL(spar_signal_remove); /* * Routine Description: diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c index fae9ab3d0f60..b6fd126f16f1 100644 --- a/drivers/staging/unisys/channels/chanstub.c +++ b/drivers/staging/unisys/channels/chanstub.c @@ -61,7 +61,7 @@ SignalRemove_withLock(struct channel_header __iomem *pChannel, u32 Queue, unsigned char result; spin_lock(lock); - result = visor_signal_remove(pChannel, Queue, pSignal); + result = spar_signal_remove(pChannel, Queue, pSignal); spin_unlock(lock); return result; } diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 16dd7a339433..15c9cebcb8ec 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -528,8 +528,8 @@ unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, * empty. */ -unsigned char visor_signal_remove(struct channel_header __iomem *pChannel, - u32 Queue, void *pSignal); +unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue, + void *sig); /* * Routine Description: diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 66da828ca352..f9f8442d58c5 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -125,7 +125,7 @@ int uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo, void *cmdrsp, unsigned int whichqueue) { - if (!visor_signal_remove(queueinfo->chan, whichqueue, cmdrsp)) + if (!spar_signal_remove(queueinfo->chan, whichqueue, cmdrsp)) return 0; queueinfo->packets_received++; -- GitLab From a17f5b4af76e0a341685ca7f0327b5277ca1ec05 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:07 -0400 Subject: [PATCH 1358/9457] staging: unisys: refactor visor_signalqueue_empty() Rename visor_signalqueue_empty() to spar_signalqueue_empty(), and fix CamelCase parameter names: pChannel => ch Queue => queue Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 10 +++++----- .../unisys/common-spar/include/channels/channel.h | 4 ++-- drivers/staging/unisys/virthba/virthba.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index 0b9a7cf35698..b1e2f9568540 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -207,13 +207,13 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) * Return value: * 1 if the signal queue is empty, 0 otherwise. */ -unsigned char -visor_signalqueue_empty(struct channel_header __iomem *pChannel, u32 Queue) +unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, + u32 queue) { struct signal_queue_header __iomem *pqhdr = - (struct signal_queue_header __iomem *) ((char __iomem *) pChannel + - readq(&pChannel->ch_space_offset)) + Queue; + (struct signal_queue_header __iomem *) ((char __iomem *) ch + + readq(&ch->ch_space_offset)) + queue; return readl(&pqhdr->head) == readl(&pqhdr->tail); } -EXPORT_SYMBOL_GPL(visor_signalqueue_empty); +EXPORT_SYMBOL_GPL(spar_signalqueue_empty); diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 15c9cebcb8ec..d982afada147 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -564,7 +564,7 @@ unsigned int SignalRemoveAll(struct channel_header *pChannel, u32 Queue, * Return value: * 1 if the signal queue is empty, 0 otherwise. */ -unsigned char visor_signalqueue_empty(struct channel_header __iomem *pChannel, - u32 Queue); +unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, + u32 queue); #endif diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index a3da5e999331..4015933d78b0 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -438,7 +438,7 @@ virthba_ISR(int irq, void *dev_id) mask = ~ULTRA_CHANNEL_ENABLE_INTS; rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask); } - if (visor_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) { + if (spar_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) { virthbainfo->interrupts_notme++; return IRQ_NONE; } -- GitLab From bac9e37d744f28ce4885e3fb1555f5e789317816 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:08 -0400 Subject: [PATCH 1359/9457] staging: unisys: fix symbol placement in spar_channel_client_acquire The && belongs at the end of the previous line, not the start of the next one. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/channel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index d982afada147..90677a8852dd 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -398,8 +398,8 @@ spar_channel_client_acquire_os(void __iomem *ch, u8 *id) } return 0; } - if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) - && (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) { + if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) && + (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) { /* Our competitor is DISABLED, so we can transition to OWNED */ pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n", id, "cli_state_os", -- GitLab From 29fe22b319599c7107e6a5bfdee79fa4a12cd89f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:09 -0400 Subject: [PATCH 1360/9457] staging: unisys: refactor SignalInit Macro Rename SignalInit to spar_signal_init, and fix CamelCase names: VersionId => version Type => chtype Size => size SignalSize => signal_size oSignalBase => sig_base_offset MaxSignalSlots => max_slots MaxSignals => max_signals Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 90677a8852dd..4d9e5d457e93 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -269,18 +269,18 @@ struct signal_queue_header { #pragma pack(pop) -#define SignalInit(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \ +#define spar_signal_init(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \ do { \ memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \ - chan->QHDRFLD.VersionId = ver; \ - chan->QHDRFLD.Type = typ; \ - chan->QHDRFLD.Size = sizeof(chan->QDATAFLD); \ - chan->QHDRFLD.SignalSize = sizeof(QDATATYPE); \ - chan->QHDRFLD.oSignalBase = (u64)(chan->QDATAFLD)- \ + chan->QHDRFLD.version = ver; \ + chan->QHDRFLD.chtype = typ; \ + chan->QHDRFLD.size = sizeof(chan->QDATAFLD); \ + chan->QHDRFLD.signal_size = sizeof(QDATATYPE); \ + chan->QHDRFLD.sig_base_offset = (u64)(chan->QDATAFLD)- \ (u64)(&chan->QHDRFLD); \ - chan->QHDRFLD.MaxSignalSlots = \ + chan->QHDRFLD.max_slots = \ sizeof(chan->QDATAFLD)/sizeof(QDATATYPE); \ - chan->QHDRFLD.MaxSignals = chan->QHDRFLD.MaxSignalSlots-1; \ + chan->QHDRFLD.max_signals = chan->QHDRFLD.max_slots-1; \ } while (0) /* Generic function useful for validating any type of channel when it is -- GitLab From c11cf5fd0fb2fb12976be62ae13f0d86b6907509 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:10 -0400 Subject: [PATCH 1361/9457] staging: unisys: refactor SignalRemoveAll() Rename SignalRemoveAll to spar_signal_remove_all(), and fix CamelCase names: pChannel => ch Queue => queue pSignal => sig signalCount => count Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 16 ++++++++-------- .../common-spar/include/channels/channel.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index b1e2f9568540..2fc61a74ee54 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -156,14 +156,14 @@ EXPORT_SYMBOL_GPL(spar_signal_remove); * Return value: * # of signals copied. */ -unsigned int -SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) +unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, + void *sig) { void *psource; - unsigned int head, tail, signalCount = 0; + unsigned int head, tail, count = 0; struct signal_queue_header *pqhdr = - (struct signal_queue_header *) ((char *) pChannel + - pChannel->ch_space_offset) + Queue; + (struct signal_queue_header *) ((char *) ch + + ch->ch_space_offset) + queue; /* capture current head and tail */ head = pqhdr->head; @@ -183,17 +183,17 @@ SignalRemoveAll(struct channel_header *pChannel, u32 Queue, void *pSignal) psource = (char *) pqhdr + pqhdr->sig_base_offset + (tail * pqhdr->signal_size); - memcpy((char *) pSignal + (pqhdr->signal_size * signalCount), + memcpy((char *) sig + (pqhdr->signal_size * count), psource, pqhdr->signal_size); mb(); /* channel synch */ pqhdr->tail = tail; - signalCount++; + count++; pqhdr->num_received++; } - return signalCount; + return count; } /* diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 4d9e5d457e93..865d9a4883a3 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -550,8 +550,8 @@ unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue, * Return value: * # of signals copied. */ -unsigned int SignalRemoveAll(struct channel_header *pChannel, u32 Queue, - void *pSignal); +unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, + void *sig); /* * Routine Description: -- GitLab From 10c5ef69482d77f80678c2aa102b38cc09b241b5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:11 -0400 Subject: [PATCH 1362/9457] staging: unisys: refactor ULTRA_check_channel_server() Rename spar_check_channel_server() to spar_check_channel_server(), remove unused parameters fileName, lineNumber, and logCtx, update references to the function and remove unused parameters in macros that call it, and fix CamelCase names: typeGuid => typeuuid channelName => name expectedMinBytes => expected_min_bytes actualBytes => actual_bytes Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 20 +++++++++++++++++++ .../include/channels/controlvmchannel.h | 5 +++++ .../include/channels/diagchannel.h | 10 +++++----- .../common-spar/include/channels/iochannel.h | 11 +++++++++- .../include/channels/vbuschannel.h | 6 ++++++ 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 865d9a4883a3..6fb6e5b3ddaf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -348,6 +348,26 @@ spar_check_channel_client(void __iomem *ch, return 1; } +/* Generic function useful for validating any type of channel when it is about + * to be initialized by the server of the channel. + * Note that is only needed for callers in the EFI environment, and + * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. + */ +static inline int spar_check_channel_server(uuid_le typeuuid, char *name, + u64 expected_min_bytes, + u64 actual_bytes) +{ + if (expected_min_bytes > 0) /* caller wants us to verify + * channel size */ + if (actual_bytes < expected_min_bytes) { + pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n", + name, &typeuuid, expected_min_bytes, + actual_bytes); + return 0; + } + return 1; +} + /* Given a file pathname (with '/' or '\' separating directory nodes), * returns a pointer to the beginning of a node within that pathname such * that the number of nodes from that pointer to the end of the string is diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 9a7531f66fdb..ce601aecee65 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -52,6 +52,11 @@ static const uuid_le UltraControlvmChannelProtocolGuid = sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)) +#define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(UltraControlvmChannelProtocolGuid, \ + "controlvm", \ + sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ + actualBytes)) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 97451bab64d2..4132642aa05b 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -65,11 +65,11 @@ static const uuid_le UltraDiagChannelProtocolGuid = sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes, logCtx) \ - (ULTRA_check_channel_server(UltraDiagChannelProtocolGuid, \ - "diag", \ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ - actualBytes, __FILE__, __LINE__, logCtx)) +#define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(UltraDiagChannelProtocolGuid, \ + "diag", \ + sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ + actualBytes)) #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ #define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info * accompanying event... */ diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index f5fd542bb67f..b1f4a47b3d62 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -65,17 +65,26 @@ "vhba", MIN_IO_CHANNEL_SIZE, \ ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) +#define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(spar_vhba_channel_protocol_uuid, \ + "vhba", MIN_IO_CHANNEL_SIZE, actualBytes)) #define SPAR_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ "vnic", MIN_IO_CHANNEL_SIZE, \ ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) +#define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(spar_vnic_channel_protocol_uuid, \ + "vnic", MIN_IO_CHANNEL_SIZE, actualBytes)) #define SPAR_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ "vswitch", MIN_IO_CHANNEL_SIZE, \ ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE)) - +#define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(UltraVswitchChannelProtocolGuid, \ + "vswitch", MIN_IO_CHANNEL_SIZE, \ + actualBytes)) /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 7b32aa9fb90b..9329e2838fde 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -51,6 +51,12 @@ static const uuid_le UltraVbusChannelProtocolGuid = ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE)) \ +#define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes) \ + (spar_check_channel_server(UltraVbusChannelProtocolGuid, \ + "vbus", \ + sizeof(struct ultra_vbus_channel_protocol),\ + actualBytes)) + #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ typedef struct _ULTRA_VBUS_HEADERINFO { u32 structBytes; /* size of this struct in bytes */ -- GitLab From 3f833b54f1bea153bbbeaf485d11789f42f6e9a3 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:12 -0400 Subject: [PATCH 1363/9457] staging: unisys: refactor ultra_segment_state Rename the struct to spar_segment_state and fix CamelCase names: Enabled => enabled Active => active Alive => alive Revoked => revoked Allocated => allocated Known => known Ready => ready Operating => operating Fix all references to modified names to use the new names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlframework.h | 27 ++++++------ .../include/channels/controlvmchannel.h | 6 +-- .../unisys/visorchipset/visorchipset_main.c | 42 +++++++++---------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index e718557f1c20..9f01f402e4ca 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -36,31 +36,34 @@ /* Define Ki scale page to be traditional 4KB page */ #define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki) -struct ultra_segment_state { - u16 Enabled:1; /* Bit 0: May enter other states */ - u16 Active:1; /* Bit 1: Assigned to active partition */ - u16 Alive:1; /* Bit 2: Configure message sent to +struct spar_segment_state { + u16 enabled:1; /* Bit 0: May enter other states */ + u16 active:1; /* Bit 1: Assigned to active partition */ + u16 alive:1; /* Bit 2: Configure message sent to * service/server */ - u16 Revoked:1; /* Bit 3: similar to partition state + u16 revoked:1; /* Bit 3: similar to partition state * ShuttingDown */ - u16 Allocated:1; /* Bit 4: memory (device/port number) + u16 allocated:1; /* Bit 4: memory (device/port number) * has been selected by Command */ - u16 Known:1; /* Bit 5: has been introduced to the + u16 known:1; /* Bit 5: has been introduced to the * service/guest partition */ - u16 Ready:1; /* Bit 6: service/Guest partition has + u16 ready:1; /* Bit 6: service/Guest partition has * responded to introduction */ - u16 Operating:1; /* Bit 7: resource is configured and + u16 operating:1; /* Bit 7: resource is configured and * operating */ /* Note: don't use high bit unless we need to switch to ushort * which is non-compliant */ }; -static const struct ultra_segment_state SegmentStateRunning = { + +static const struct spar_segment_state SegmentStateRunning = { 1, 1, 1, 0, 1, 1, 1, 1 }; -static const struct ultra_segment_state SegmentStatePaused = { + +static const struct spar_segment_state SegmentStatePaused = { 1, 1, 1, 0, 1, 1, 1, 0 }; -static const struct ultra_segment_state SegmentStateStandby = { + +static const struct spar_segment_state SegmentStateStandby = { 1, 1, 0, 0, 1, 1, 1, 0 }; diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index ce601aecee65..e638f8a3a205 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -389,13 +389,13 @@ typedef struct _CONTROLVM_MESSAGE_PACKET { } reconfigureDevice; /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { u32 busNo; - struct ultra_segment_state state; + struct spar_segment_state state; u8 reserved[2]; /* Natural alignment purposes */ } busChangeState; /* for CONTROLVM_BUS_CHANGESTATE */ struct { u32 busNo; u32 devNo; - struct ultra_segment_state state; + struct spar_segment_state state; struct { u32 physicalDevice:1; /* =1 if message is for * a physical device */ @@ -406,7 +406,7 @@ typedef struct _CONTROLVM_MESSAGE_PACKET { struct { u32 busNo; u32 devNo; - struct ultra_segment_state state; + struct spar_segment_state state; u8 reserved[6]; /* Natural alignment purposes */ } deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index c94d65518f46..4f27392f35f3 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -348,9 +348,8 @@ static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response); static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, ULTRA_CHIPSET_FEATURE features); -static void controlvm_respond_physdev_changestate( - CONTROLVM_MESSAGE_HEADER *msgHdr, int response, - struct ultra_segment_state state); +static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER * + msgHdr, int response, struct spar_segment_state state); static ssize_t toolaction_show(struct device *dev, struct device_attribute *attr, @@ -743,8 +742,7 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, struct ultra_segment_state - state) + int response, struct spar_segment_state state) { CONTROLVM_MESSAGE outmsg; @@ -860,7 +858,7 @@ bus_responder(enum control_vm_id cmdId, ulong busNo, int response) static void device_changestate_responder(enum control_vm_id cmdId, ulong busNo, ulong devNo, int response, - struct ultra_segment_state responseState) + struct spar_segment_state responseState) { VISORCHIPSET_DEVICE_INFO *p = NULL; CONTROLVM_MESSAGE outmsg; @@ -994,7 +992,7 @@ bus_epilog(u32 busNo, } static void -device_epilog(u32 busNo, u32 devNo, struct ultra_segment_state state, u32 cmd, +device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr, int response, BOOL needResponse, BOOL for_visorbus) { @@ -1033,8 +1031,8 @@ device_epilog(u32 busNo, u32 devNo, struct ultra_segment_state state, u32 cmd, break; case CONTROLVM_DEVICE_CHANGESTATE: /* ServerReady / ServerRunning / SegmentStateRunning */ - if (state.Alive == SegmentStateRunning.Alive && - state.Operating == SegmentStateRunning.Operating) { + if (state.alive == SegmentStateRunning.alive && + state.operating == SegmentStateRunning.operating) { if (notifiers->device_resume) { (*notifiers->device_resume) (busNo, devNo); @@ -1042,9 +1040,9 @@ device_epilog(u32 busNo, u32 devNo, struct ultra_segment_state state, u32 cmd, } } /* ServerNotReady / ServerLost / SegmentStateStandby */ - else if (state.Alive == SegmentStateStandby.Alive && - state.Operating == - SegmentStateStandby.Operating) { + else if (state.alive == SegmentStateStandby.alive && + state.operating == + SegmentStateStandby.operating) { /* technically this is standby case * where server is lost */ @@ -1053,9 +1051,9 @@ device_epilog(u32 busNo, u32 devNo, struct ultra_segment_state state, u32 cmd, devNo); notified = TRUE; } - } else if (state.Alive == SegmentStatePaused.Alive && - state.Operating == - SegmentStatePaused.Operating) { + } else if (state.alive == SegmentStatePaused.alive && + state.operating == + SegmentStatePaused.operating) { /* this is lite pause where channel is * still valid just 'pause' of it */ @@ -1306,7 +1304,7 @@ my_device_changestate(CONTROLVM_MESSAGE *inmsg) CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; ulong busNo = cmd->deviceChangeState.busNo; ulong devNo = cmd->deviceChangeState.devNo; - struct ultra_segment_state state = cmd->deviceChangeState.state; + struct spar_segment_state state = cmd->deviceChangeState.state; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1631,7 +1629,7 @@ parahotplug_request_kickoff(struct parahotplug_request *req) sprintf(env_cmd, "SPAR_PARAHOTPLUG=1"); sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id); sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d", - cmd->deviceChangeState.state.Active); + cmd->deviceChangeState.state.active); sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d", cmd->deviceChangeState.busNo); sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d", @@ -1640,7 +1638,7 @@ parahotplug_request_kickoff(struct parahotplug_request *req) cmd->deviceChangeState.devNo & 0x7); LOGINF("parahotplug_request_kickoff: state=%d, bdf=%d/%d/%d, id=%u\n", - cmd->deviceChangeState.state.Active, + cmd->deviceChangeState.state.active, cmd->deviceChangeState.busNo, cmd->deviceChangeState.devNo >> 3, cmd->deviceChangeState.devNo & 7, req->id); @@ -1700,7 +1698,7 @@ parahotplug_request_complete(int id, u16 active) */ list_del(pos); spin_unlock(&Parahotplug_request_list_lock); - req->msg.cmd.deviceChangeState.state.Active = active; + req->msg.cmd.deviceChangeState.state.active = active; if (req->msg.hdr.Flags.responseExpected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_SUCCESS, @@ -1729,7 +1727,7 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) return; } - if (inmsg->cmd.deviceChangeState.state.Active) { + if (inmsg->cmd.deviceChangeState.state.active) { /* For enable messages, just respond with success * right away. This is a bit of a hack, but there are * issues with the early enable messages we get (with @@ -1853,13 +1851,13 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) LOGINF("DEVICE_CHANGESTATE for physical device (%lu,%lu, active=%lu)", (ulong) cmd->deviceChangeState.busNo, (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.Active); + (ulong) cmd->deviceChangeState.state.active); parahotplug_process_message(&inmsg); } else { LOGINF("DEVICE_CHANGESTATE for virtual device (%lu,%lu, state.Alive=0x%lx)", (ulong) cmd->deviceChangeState.busNo, (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.Alive); + (ulong) cmd->deviceChangeState.state.alive); /* save the hdr and cmd structures for later use */ /* when sending back the response to Command */ my_device_changestate(&inmsg); -- GitLab From bd0d2dcc03db2bffcd4bd292fadc9234006edbfb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:13 -0400 Subject: [PATCH 1364/9457] staging: unisys: fix CamelCase constant names in controlframework.h Fix CamelCase names: SegmentStateRunning => segment_state_running SegmentStatePaused => segment_state_paused SegmentStateStandby => segment_state_standby Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlframework.h | 6 +++--- drivers/staging/unisys/uislib/uislib.c | 8 +++---- .../unisys/visorchipset/visorchipset_main.c | 21 ++++++++++--------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index 9f01f402e4ca..80e2df139ea3 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -55,15 +55,15 @@ struct spar_segment_state { * which is non-compliant */ }; -static const struct spar_segment_state SegmentStateRunning = { +static const struct spar_segment_state segment_state_running = { 1, 1, 1, 0, 1, 1, 1, 1 }; -static const struct spar_segment_state SegmentStatePaused = { +static const struct spar_segment_state segment_state_paused = { 1, 1, 1, 0, 1, 1, 1, 0 }; -static const struct spar_segment_state SegmentStateStandby = { +static const struct spar_segment_state segment_state_standby = { 1, 1, 0, 0, 1, 1, 1, 0 }; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index bcb80ba40160..a0b1e042b43d 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -891,7 +891,7 @@ uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); msg.cmd.deviceChangeState.busNo = bus_no; msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = SegmentStateStandby; + msg.cmd.deviceChangeState.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n", @@ -911,7 +911,7 @@ uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); msg.cmd.deviceChangeState.busNo = bus_no; msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = SegmentStateRunning; + msg.cmd.deviceChangeState.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n", @@ -1044,7 +1044,7 @@ uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); msg.cmd.deviceChangeState.busNo = bus_no; msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = SegmentStateStandby; + msg.cmd.deviceChangeState.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n", @@ -1064,7 +1064,7 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); msg.cmd.deviceChangeState.busNo = bus_no; msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = SegmentStateRunning; + msg.cmd.deviceChangeState.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n", diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 4f27392f35f3..f0a4dfa8e31b 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1031,8 +1031,9 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, break; case CONTROLVM_DEVICE_CHANGESTATE: /* ServerReady / ServerRunning / SegmentStateRunning */ - if (state.alive == SegmentStateRunning.alive && - state.operating == SegmentStateRunning.operating) { + if (state.alive == segment_state_running.alive && + state.operating == + segment_state_running.operating) { if (notifiers->device_resume) { (*notifiers->device_resume) (busNo, devNo); @@ -1040,9 +1041,9 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, } } /* ServerNotReady / ServerLost / SegmentStateStandby */ - else if (state.alive == SegmentStateStandby.alive && + else if (state.alive == segment_state_standby.alive && state.operating == - SegmentStateStandby.operating) { + segment_state_standby.operating) { /* technically this is standby case * where server is lost */ @@ -1051,9 +1052,9 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, devNo); notified = TRUE; } - } else if (state.alive == SegmentStatePaused.alive && + } else if (state.alive == segment_state_paused.alive && state.operating == - SegmentStatePaused.operating) { + segment_state_paused.operating) { /* this is lite pause where channel is * still valid just 'pause' of it */ @@ -1292,7 +1293,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", g_diagpoolBusNo, g_diagpoolDevNo); } - device_epilog(busNo, devNo, SegmentStateRunning, + device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, inmsg->hdr.Flags.responseExpected == 1, FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); @@ -1356,7 +1357,7 @@ my_device_destroy(CONTROLVM_MESSAGE *inmsg) Away: if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo) - device_epilog(busNo, devNo, SegmentStateRunning, + device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, inmsg->hdr.Flags.responseExpected == 1, FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); @@ -2174,7 +2175,7 @@ visorchipset_device_pause_response(ulong busNo, ulong devNo, int response) device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, busNo, devNo, response, - SegmentStateStandby); + segment_state_standby); } EXPORT_SYMBOL_GPL(visorchipset_device_pause_response); @@ -2183,7 +2184,7 @@ device_resume_response(ulong busNo, ulong devNo, int response) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, busNo, devNo, response, - SegmentStateRunning); + segment_state_running); } BOOL -- GitLab From 5fbaa4b3a6fa7db8c62b7bd32a078d0dce00536a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:14 -0400 Subject: [PATCH 1365/9457] staging: unisys: refactor UltraControlvmChannelProtocolGuid rename UltraControlvmChannelProtocolGuid to spar_controlvm_channel_protocol_uuid, and change ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID to SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID to match. Update references to the old name. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 10 +++++----- .../staging/unisys/visorchipset/visorchipset_main.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index e638f8a3a205..be94db678671 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -27,12 +27,12 @@ enum { INVALID_GUEST_FIRMWARE, SAMPLE_GUEST_FIRMWARE, }; /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID \ +#define SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \ 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) -static const uuid_le UltraControlvmChannelProtocolGuid = - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_controlvm_channel_protocol_uuid = + SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID; #define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE \ ULTRA_CHANNEL_PROTOCOL_SIGNATURE @@ -47,13 +47,13 @@ static const uuid_le UltraControlvmChannelProtocolGuid = #define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(pChannel) \ (spar_check_channel_client(pChannel, \ - UltraControlvmChannelProtocolGuid, \ + spar_controlvm_channel_protocol_uuid, \ "controlvm", \ sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)) #define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(UltraControlvmChannelProtocolGuid, \ + (spar_check_channel_server(spar_controlvm_channel_protocol_uuid,\ "controlvm", \ sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ actualBytes)) diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index f0a4dfa8e31b..e84c154a6a6d 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2380,7 +2380,7 @@ visorchipset_init(void) visorchannel_create_with_lock (addr, sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), - UltraControlvmChannelProtocolGuid); + spar_controlvm_channel_protocol_uuid); if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( visorchannel_get_header(ControlVm_channel))) { LOGINF("Channel %s (ControlVm) discovered", -- GitLab From 7caac2fa2c72f76eeef01685dc505cee15fd3e71 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:15 -0400 Subject: [PATCH 1366/9457] staging: unisys: remove ULTRA_CONTROLVM_CHANNEL_OK_SERVER macro Nobody is using this macro, so remove it entirely. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index be94db678671..6b3cedf930d6 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -52,11 +52,6 @@ static const uuid_le spar_controlvm_channel_protocol_uuid = sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_CONTROLVM_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(spar_controlvm_channel_protocol_uuid,\ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - actualBytes)) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ -- GitLab From 600832fd3dffe2ddaa431cd84cd3b34a7e449285 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:16 -0400 Subject: [PATCH 1367/9457] staging: unisys: fix CamelCase in SPAR_CONTROLVM_CHANNEL_OK_CLIENT Fix CamelCase parameter name: pChannel => ch Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 6b3cedf930d6..c168e148a0c1 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -45,13 +45,13 @@ static const uuid_le spar_controlvm_channel_protocol_uuid = * channel struct withOUT needing to increment this. */ #define ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID 1 -#define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(pChannel) \ - (spar_check_channel_client(pChannel, \ - spar_controlvm_channel_protocol_uuid, \ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)) +#define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ + spar_check_channel_client(ch, \ + spar_controlvm_channel_protocol_uuid, \ + "controlvm", \ + sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ -- GitLab From 53bebb13a2ee242d33aaa3299d079e8d666a5773 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:17 -0400 Subject: [PATCH 1368/9457] staging: unisys: remove typedef CONTROLVM_ID Replace the typedef for CONTROLVM_ID with enum controlvm_id, and update all references to the old typedef. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 2 +- drivers/staging/unisys/include/uisutils.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset_main.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index c168e148a0c1..20e464eb4dde 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -82,7 +82,7 @@ static const uuid_le spar_controlvm_channel_protocol_uuid = * - issued on the EventQueue queue (q #2) in the ControlVm channel * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ -enum control_vm_id { +enum controlvm_id { CONTROLVM_INVALID = 0, /* SWITCH commands required Parameter: SwitchNumber */ /* BUS commands required Parameter: BusNumber */ diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index f8ffa0263e29..35794eff475f 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -155,7 +155,7 @@ u64 uislib_storage_channel(int client_id); #endif int uislib_get_owned_pdest(struct uisscsi_dest *pdest); -int uislib_send_event(enum control_vm_id id, CONTROLVM_MESSAGE_PACKET *event); +int uislib_send_event(enum controlvm_id id, CONTROLVM_MESSAGE_PACKET *event); /* structure used by vhba & vnic to keep track of queue & thread info */ struct chaninfo { diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index e84c154a6a6d..ed26c29ec4b0 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -817,7 +817,7 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) EXPORT_SYMBOL_GPL(visorchipset_save_message); static void -bus_responder(enum control_vm_id cmdId, ulong busNo, int response) +bus_responder(enum controlvm_id cmdId, ulong busNo, int response) { VISORCHIPSET_BUS_INFO *p = NULL; BOOL need_clear = FALSE; @@ -856,7 +856,7 @@ bus_responder(enum control_vm_id cmdId, ulong busNo, int response) } static void -device_changestate_responder(enum control_vm_id cmdId, +device_changestate_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, int response, struct spar_segment_state responseState) { @@ -893,7 +893,8 @@ device_changestate_responder(enum control_vm_id cmdId, } static void -device_responder(enum control_vm_id cmdId, ulong busNo, ulong devNo, int response) +device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, + int response) { VISORCHIPSET_DEVICE_INFO *p = NULL; BOOL need_clear = FALSE; -- GitLab From af3286bdb4037e62552c3f887e628505a63ba409 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:18 -0400 Subject: [PATCH 1369/9457] staging: unisys: fix CamelCase names in struct irq_info Fix CamelCase names in structure, and references to them: sendInterruptHandle => send_irq_handle recvInterruptHandle => recv_irq_handle recvInterruptVector => recv_irq_vector recvInterruptShared => recv_irq_shared Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 8 ++++---- drivers/staging/unisys/virthba/virthba.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 20e464eb4dde..ce628c11fd15 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -122,23 +122,23 @@ struct irq_info { * interrupt. Currently this is used by IOPart-SP to wake * up GP when Data Channel transitions from empty to * non-empty.*/ - u64 sendInterruptHandle; + u64 send_irq_handle; /**< specifies interrupt handle. It is used to retrieve the * corresponding interrupt pin from Monitor; and the * interrupt pin is used to connect to the corresponding * intrrupt. Used by IOPart-GP only. */ - u64 recvInterruptHandle; + u64 recv_irq_handle; /**< specifies interrupt vector. It, interrupt pin, and shared are * used to connect to the corresponding interrupt. Used by * IOPart-GP only. */ - u32 recvInterruptVector; + u32 recv_irq_vector; /**< specifies if the recvInterrupt is shared. It, interrupt pin * and vector are used to connect to 0 = not shared; 1 = shared. * the corresponding interrupt. Used by IOPart-GP only. */ - u8 recvInterruptShared; + u8 recv_irq_shared; u8 reserved[3]; /* Natural alignment purposes */ }; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 4015933d78b0..3a037f41ee40 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -603,16 +603,16 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) return -ENODEV; } LOGINF("sendInterruptHandle=0x%16llX", - virthbainfo->intr.sendInterruptHandle); + virthbainfo->intr.send_irq_handle); LOGINF("recvInterruptHandle=0x%16llX", - virthbainfo->intr.recvInterruptHandle); + virthbainfo->intr.recv_irq_handle); LOGINF("recvInterruptVector=0x%8X", - virthbainfo->intr.recvInterruptVector); + virthbainfo->intr.recv_irq_vector); LOGINF("recvInterruptShared=0x%2X", - virthbainfo->intr.recvInterruptShared); + virthbainfo->intr.recv_irq_shared); LOGINF("scsihost.hostt->name=%s", scsihost->hostt->name); virthbainfo->interrupt_vector = - virthbainfo->intr.recvInterruptHandle & INTERRUPT_VECTOR_MASK; + virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK; rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED, scsihost->hostt->name, virthbainfo); if (rsp != 0) { -- GitLab From 6822f736c6f02adbb9e121134e24490276bdfbfc Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:19 -0400 Subject: [PATCH 1370/9457] staging: unisys: fix CamelCase names in struct pci_id Fix CamelCase names: Domain => domain Bus => bus Slot => slot Func => func Reserved => reserved Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index ce628c11fd15..ac653330c0bc 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -143,11 +143,11 @@ struct irq_info { }; struct pci_id { - u16 Domain; - u8 Bus; - u8 Slot; - u8 Func; - u8 Reserved[3]; /* Natural alignment purposes */ + u16 domain; + u8 bus; + u8 slot; + u8 func; + u8 reserved[3]; /* Natural alignment purposes */ }; struct PciConfigHdr { -- GitLab From 18787366b1a2fcfddc01efabbdcf5d8727c144c0 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:20 -0400 Subject: [PATCH 1371/9457] staging: unisys: remove unused code from controlvmchannel.h Delete struct PciConfigHdr, struct ScsiId, struct WWID, struct VirtDiskInfo, enum CONTROLVM_ACTION, and enum ULTRA_TOOL_ACTIONS. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index ac653330c0bc..68cf118171d3 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -150,69 +150,6 @@ struct pci_id { u8 reserved[3]; /* Natural alignment purposes */ }; -struct PciConfigHdr { - u16 VendorId; - u16 SubSysVendor; - u16 DeviceId; - u16 SubSysDevice; - u32 ClassCode; - u32 Reserved; /* Natural alignment purposes */ -}; - -struct ScsiId { - u32 Bus; - u32 Target; - u32 Lun; - u32 Host; /* Command should ignore this for * - * DiskArrival/RemovalEvents */ -}; - -struct WWID { - u32 wwid1; - u32 wwid2; -}; - -struct virtDiskInfo { - u32 switchNo; /* defined by SWITCH_CREATE */ - u32 externalPortNo; /* 0 for SAS RAID provided (external) - * virtual disks, 1 for virtual disk - * images, 2 for gold disk images */ - u16 VirtualDiskIndex; /* Index of disk descriptor in the - * VirtualDisk segment associated with - * externalPortNo */ - u16 Reserved1; - u32 Reserved2; -}; - -typedef enum { - CONTROLVM_ACTION_NONE = 0, - CONTROLVM_ACTION_SET_RESTORE = 0x05E7, - CONTROLVM_ACTION_CLEAR_RESTORE = 0x0C18, - CONTROLVM_ACTION_RESTORING = 0x08E5, - CONTROLVM_ACTION_RESTORE_BUSY = 0x0999, - CONTROLVM_ACTION_CLEAR_NVRAM = 0xB01 -} CONTROLVM_ACTION; - -typedef enum _ULTRA_TOOL_ACTIONS { - /* enumeration that defines intended action */ - ULTRA_TOOL_ACTION_NONE = 0, /* normal boot of boot disk */ - ULTRA_TOOL_ACTION_INSTALL = 1, /* install source disk(s) to boot - * disk */ - ULTRA_TOOL_ACTION_CAPTURE = 2, /* capture boot disk to target disk(s) - * as 'gold image' */ - ULTRA_TOOL_ACTION_REPAIR = 3, /* use source disk(s) to repair - * installation on boot disk */ - ULTRA_TOOL_ACTION_CLEAN = 4, /* 'scrub' virtual disk before - * releasing back to storage pool */ - ULTRA_TOOL_ACTION_UPGRADE = 5, /* upgrade to use content of images - * referenced from newer blueprint */ - ULTRA_TOOL_ACTION_DIAG = 6, /* use tool to invoke diagnostic script - * provided by blueprint */ - ULTRA_TOOL_ACTION_FAILED = 7, /* used when tool fails installation - and cannot continue */ - ULTRA_TOOL_ACTION_COUNT = 8 -} ULTRA_TOOL_ACTIONS; - typedef struct _ULTRA_EFI_SPAR_INDICATION { u64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */ u64 ClearNvram:1; /* Bit 1: Clear NVRAM */ -- GitLab From 755e2ecc7d753ffe34703c0408e3923f2a58fd96 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:21 -0400 Subject: [PATCH 1372/9457] staging: unisys: replace typedef ULTRA_EFI_SPAR_INDICATION Replace ULTRA_EFI_SPAR_INDICATION with struct efi_spar_indication, and update references to the old type. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 8 ++++---- drivers/staging/unisys/visorchipset/visorchipset_main.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 68cf118171d3..0bf45960dce1 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -150,13 +150,13 @@ struct pci_id { u8 reserved[3]; /* Natural alignment purposes */ }; -typedef struct _ULTRA_EFI_SPAR_INDICATION { +struct efi_spar_indication { u64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */ u64 ClearNvram:1; /* Bit 1: Clear NVRAM */ u64 ClearCmos:1; /* Bit 2: Clear CMOS */ u64 BootToTool:1; /* Bit 3: Run install tool */ /* remaining bits are available */ -} ULTRA_EFI_SPAR_INDICATION; +}; typedef enum { ULTRA_CHIPSET_FEATURE_REPLY = 0x00000001, @@ -468,8 +468,8 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { u8 ToolAction; /* ULTRA_TOOL_ACTIONS Installation Action * field */ u8 Reserved; /* alignment */ - ULTRA_EFI_SPAR_INDICATION EfiSparIndication; - ULTRA_EFI_SPAR_INDICATION EfiSparIndicationSupported; + struct efi_spar_indication EfiSparIndication; + struct efi_spar_indication EfiSparIndicationSupported; u32 SPReserved; u8 Reserved2[28]; /* Force signals to begin on 128-byte cache * line */ diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index ed26c29ec4b0..27bfa6e42e4e 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -386,12 +386,12 @@ static ssize_t boottotool_show(struct device *dev, struct device_attribute *attr, char *buf) { - ULTRA_EFI_SPAR_INDICATION efiSparIndication; + struct efi_spar_indication efiSparIndication; visorchannel_read(ControlVm_channel, offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EfiSparIndication), &efiSparIndication, - sizeof(ULTRA_EFI_SPAR_INDICATION)); + sizeof(struct efi_spar_indication)); return scnprintf(buf, PAGE_SIZE, "%u\n", efiSparIndication.BootToTool); } @@ -401,7 +401,7 @@ static ssize_t boottotool_store(struct device *dev, const char *buf, size_t count) { int val, ret; - ULTRA_EFI_SPAR_INDICATION efiSparIndication; + struct efi_spar_indication efiSparIndication; if (kstrtoint(buf, 10, &val) != 0) return -EINVAL; @@ -411,7 +411,7 @@ static ssize_t boottotool_store(struct device *dev, offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EfiSparIndication), &(efiSparIndication), - sizeof(ULTRA_EFI_SPAR_INDICATION)); + sizeof(struct efi_spar_indication)); if (ret) return ret; -- GitLab From 2450301a676fcfa57543e3ff30d6da7f032c8f58 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:22 -0400 Subject: [PATCH 1373/9457] staging: unisys: fix CamelCase names in struct efi_spar_indication Fix CamelCase names and update all references to them: BootToFirmwareUI => boot_to_fw_ui ClearNvram => clear_nvram ClearCmos => clear_cmos BootToTool => boot_to_tool Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 8 ++++---- drivers/staging/unisys/visorchipset/visorchipset_main.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 0bf45960dce1..d59dd3545128 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -151,10 +151,10 @@ struct pci_id { }; struct efi_spar_indication { - u64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */ - u64 ClearNvram:1; /* Bit 1: Clear NVRAM */ - u64 ClearCmos:1; /* Bit 2: Clear CMOS */ - u64 BootToTool:1; /* Bit 3: Run install tool */ + u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */ + u64 clear_nvram:1; /* Bit 1: Clear NVRAM */ + u64 clear_cmos:1; /* Bit 2: Clear CMOS */ + u64 boot_to_tool:1; /* Bit 3: Run install tool */ /* remaining bits are available */ }; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 27bfa6e42e4e..9269e46a2e7e 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -393,7 +393,7 @@ static ssize_t boottotool_show(struct device *dev, EfiSparIndication), &efiSparIndication, sizeof(struct efi_spar_indication)); return scnprintf(buf, PAGE_SIZE, "%u\n", - efiSparIndication.BootToTool); + efiSparIndication.boot_to_tool); } static ssize_t boottotool_store(struct device *dev, @@ -406,7 +406,7 @@ static ssize_t boottotool_store(struct device *dev, if (kstrtoint(buf, 10, &val) != 0) return -EINVAL; - efiSparIndication.BootToTool = val; + efiSparIndication.boot_to_tool = val; ret = visorchannel_write(ControlVm_channel, offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EfiSparIndication), -- GitLab From 75185f57f110a7c48d9d33a585320c93334adf0c Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:23 -0400 Subject: [PATCH 1374/9457] staging: unisys: fix CamelCase macro names in controlframework.h Fix CamelCase names: ULTRA_MEMORY_COUNT_Ki => ULTRA_MEMORY_COUNT_KI ULTRA_MEMORY_PAGE_Ki => ULTRA_MEMORY_PAGE_KI Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .gitignore | 4 ++++ .../unisys/common-spar/include/channels/controlframework.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e213b27f3921..6bfac06d79ca 100644 --- a/.gitignore +++ b/.gitignore @@ -96,3 +96,7 @@ x509.genkey # Kconfig presets all.config + +#eclipse files +.project +.cproject diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index 80e2df139ea3..7f1adf64b173 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -28,14 +28,14 @@ #include #include "channel.h" -#define ULTRA_MEMORY_COUNT_Ki 1024 +#define ULTRA_MEMORY_COUNT_KI 1024 /* Scale order 0 is one 32-bit (4-byte) word (in 64 or 128-bit * architecture potentially 64 or 128-bit word) */ #define ULTRA_MEMORY_PAGE_WORD 4 /* Define Ki scale page to be traditional 4KB page */ -#define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki) +#define ULTRA_MEMORY_PAGE_KI (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_KI) struct spar_segment_state { u16 enabled:1; /* Bit 0: May enter other states */ u16 active:1; /* Bit 1: Assigned to active partition */ -- GitLab From b9b141e8535f157758ed1f457eb639703a7f2326 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:24 -0400 Subject: [PATCH 1375/9457] staging: unisys: refactor ULTRA_CHIPSET_FEATURE enum Get rid of the typedef and use enum ultra_chipset_feature instead, and update all references to the enumeration. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 6 +++--- drivers/staging/unisys/visorchipset/visorchipset_main.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index d59dd3545128..20c1506e7e96 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -158,11 +158,11 @@ struct efi_spar_indication { /* remaining bits are available */ }; -typedef enum { +enum ultra_chipset_feature { ULTRA_CHIPSET_FEATURE_REPLY = 0x00000001, ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, ULTRA_CHIPSET_FEATURE_PCIVBUS = 0x00000004 -} ULTRA_CHIPSET_FEATURE; +}; /** This is the common structure that is at the beginning of every * ControlVm message (both commands and responses) in any ControlVm @@ -346,7 +346,7 @@ typedef struct _CONTROLVM_MESSAGE_PACKET { u32 switchCount; /*< indicates the max number of * switches (applicable for service * partition only) */ - ULTRA_CHIPSET_FEATURE features; + enum ultra_chipset_feature features; u32 platformNumber; /* Platform Number */ } initChipset; /* for CONTROLVM_CHIPSET_INIT */ struct { diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 9269e46a2e7e..c8d8d258a7cd 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -347,7 +347,7 @@ static struct platform_device Visorchipset_platform_device = { static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response); static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, - ULTRA_CHIPSET_FEATURE features); + enum ultra_chipset_feature features); static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER * msgHdr, int response, struct spar_segment_state state); @@ -655,7 +655,7 @@ static void chipset_init(CONTROLVM_MESSAGE *inmsg) { static int chipset_inited; - ULTRA_CHIPSET_FEATURE features = 0; + enum ultra_chipset_feature features = 0; int rc = CONTROLVM_RESP_SUCCESS; POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); @@ -727,7 +727,7 @@ controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, - ULTRA_CHIPSET_FEATURE features) + enum ultra_chipset_feature features) { CONTROLVM_MESSAGE outmsg; -- GitLab From 2ea5117b5f09143f02a743e9784a6714dd800866 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:25 -0400 Subject: [PATCH 1376/9457] staging: unisys: refactor CONTROLVM_MESSAGE_PACKET This patch refactors the message union and internal structures so they will pass checkpatch.pl. The typedef is removed, and references are changed to struct controlvm_message_packet. The comments were reflowed and cleaned up to remove unnecessary information, and CamelCase member names were fixed here and in references: busNo => bus_no devNo => dev_no deviceCount => dev_count channelAddr => channel_addr channelBytes => channel_bytes busDataTypeGuid => bus_data_type_uuid busInstGuid => bus_inst_uuid destroyBus => destroy_bus guestHandle => guest_handle recvBusInterruptHandle => recv_bus_irq_handle configureBus => configure_bus createDevuce => create_device destroyDevice => destroy_device configureDevice => configure_device reconfigureDevice => reconfigure_device busChangeState => bus_change_state physicalDevice => phys_device busCount => bus_count switchCount => switch_count platformNumber => platformNumber initChipset => init_chipset Options => options Test => test chipsetSelftest => chipset_selftest Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 165 +++++++----------- drivers/staging/unisys/include/uisutils.h | 3 +- drivers/staging/unisys/uislib/uislib.c | 164 ++++++++--------- .../unisys/visorchipset/visorchipset_main.c | 154 ++++++++-------- 4 files changed, 226 insertions(+), 260 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 20c1506e7e96..6d68b2cfc4fd 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -251,135 +251,100 @@ typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { } CONTROLVM_MESSAGE_DEVICE_CONFIGURE; /* total 56 bytes */ /* This is the format for a message in any ControlVm queue. */ -typedef struct _CONTROLVM_MESSAGE_PACKET { +struct controlvm_message_packet { union { - - /* BEGIN Request messages */ struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 deviceCount; /*< indicates the max number of - * devices on this bus */ - u64 channelAddr; /*< Guest physical address of the - * channel, which can be - * dereferenced by the receiver - * of this ControlVm command */ - u64 channelBytes; /*< size of the channel in bytes */ - uuid_le busDataTypeGuid;/*< indicates format of data in - bus channel */ - uuid_le busInstGuid; /*< instance guid for the bus */ - } createBus; /* for CONTROLVM_BUS_CREATE */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_count; /* indicates the max number of + * devices on this bus */ + u64 channel_addr; /* Guest physical address of + * the channel, which can be + * dereferenced by the receiver + * of this ControlVm command */ + u64 channel_bytes; /* size of the channel */ + uuid_le bus_data_type_uuid; /* indicates format of + * data in bus channel*/ + uuid_le bus_inst_uuid; /* instance uuid for the bus */ + } create_bus; /* for CONTROLVM_BUS_CREATE */ struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ u32 reserved; /* Natural alignment purposes */ - } destroyBus; /* for CONTROLVM_BUS_DESTROY */ + } destroy_bus; /* for CONTROLVM_BUS_DESTROY */ struct { - u32 busNo; /*< bus # (0..n-1) from the - * msg receiver's - * perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 reserved1; /* for alignment purposes */ - u64 guestHandle; /* This is used to convert - * guest physical address to real - * physical address for DMA, for ex. */ - u64 recvBusInterruptHandle;/*< specifies interrupt - * info. It is used by SP to register - * to receive interrupts from the CP. - * This interrupt is used for bus - * level notifications. The - * corresponding - * sendBusInterruptHandle is kept in - * CP. */ - } configureBus; /* for CONTROLVM_BUS_CONFIGURE */ - + u32 bus_no; /* bus # (0..n-1) from the receiver's + * perspective */ + u32 reserved1; /* for alignment purposes */ + u64 guest_handle; /* This is used to convert + * guest physical address to + * physical address */ + u64 recv_bus_irq_handle; + /* specifies interrupt info. It is used by SP + * to register to receive interrupts from the + * CP. This interrupt is used for bus level + * notifications. The corresponding + * sendBusInterruptHandle is kept in CP. */ + } configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ /* for CONTROLVM_DEVICE_CREATE */ - CONTROLVM_PACKET_DEVICE_CREATE createDevice; + CONTROLVM_PACKET_DEVICE_CREATE create_device; struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /*< bus-relative (0..n-1) device - * number */ - } destroyDevice; /* for CONTROLVM_DEVICE_DESTROY */ - + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_no; /* bus-relative (0..n-1) device # */ + } destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ /* for CONTROLVM_DEVICE_CONFIGURE */ - CONTROLVM_PACKET_DEVICE_CONFIGURE configureDevice; + CONTROLVM_PACKET_DEVICE_CONFIGURE configure_device; struct { - u32 busNo; /*< bus # (0..n-1) from the msg - * receiver's perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /*< bus-relative (0..n-1) device - * number */ - } reconfigureDevice; /* for CONTROLVM_DEVICE_RECONFIGURE */ + u32 bus_no; /* bus # (0..n-1) from the msg + * receiver's perspective */ + u32 dev_no; /* bus-relative (0..n-1) device # */ + } reconfigure_device; /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { - u32 busNo; + u32 bus_no; struct spar_segment_state state; u8 reserved[2]; /* Natural alignment purposes */ - } busChangeState; /* for CONTROLVM_BUS_CHANGESTATE */ + } bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */ struct { - u32 busNo; - u32 devNo; + u32 bus_no; + u32 dev_no; struct spar_segment_state state; struct { - u32 physicalDevice:1; /* =1 if message is for + u32 phys_device:1; /* =1 if message is for * a physical device */ - /* remaining bits in this 32-bit word are available */ } flags; u8 reserved[2]; /* Natural alignment purposes */ - } deviceChangeState; /* for CONTROLVM_DEVICE_CHANGESTATE */ + } device_change_state; /* for CONTROLVM_DEVICE_CHANGESTATE */ struct { - u32 busNo; - u32 devNo; + u32 bus_no; + u32 dev_no; struct spar_segment_state state; u8 reserved[6]; /* Natural alignment purposes */ - } deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ + } device_change_state_event; + /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { - u32 busCount; /*< indicates the max number of busses */ - u32 switchCount; /*< indicates the max number of - * switches (applicable for service - * partition only) */ + u32 bus_count; /* indicates the max number of busses */ + u32 switch_count; /* indicates the max number of + * switches if a service partition */ enum ultra_chipset_feature features; - u32 platformNumber; /* Platform Number */ - } initChipset; /* for CONTROLVM_CHIPSET_INIT */ + u32 platform_number; /* Platform Number */ + } init_chipset; /* for CONTROLVM_CHIPSET_INIT */ struct { - u32 Options; /*< reserved */ - u32 Test; /*< bit 0 set to run embedded selftest */ - } chipsetSelftest; /* for CONTROLVM_CHIPSET_SELFTEST */ - - /* END Request messages */ - - /* BEGIN Response messages */ - - /* END Response messages */ - - /* BEGIN Event messages */ - - /* END Event messages */ - - /* BEGIN Ack messages */ - - /* END Ack messages */ - u64 addr; /*< a physical address of something, that - * can be dereferenced by the receiver of - * this ControlVm command (depends on - * command id) */ - u64 handle; /*< a handle of something (depends on - * command id) */ + u32 options; /* reserved */ + u32 test; /* bit 0 set to run embedded selftest */ + } chipset_selftest; /* for CONTROLVM_CHIPSET_SELFTEST */ + u64 addr; /* a physical address of something, that can be + * dereferenced by the receiver of this + * ControlVm command (depends on command id) */ + u64 handle; /* a handle of something (depends on command + * id) */ }; -} CONTROLVM_MESSAGE_PACKET; +}; /* All messages in any ControlVm queue have this layout. */ typedef struct _CONTROLVM_MESSAGE { CONTROLVM_MESSAGE_HEADER hdr; - CONTROLVM_MESSAGE_PACKET cmd; + struct controlvm_message_packet cmd; } CONTROLVM_MESSAGE; typedef struct _DEVICE_MAP { diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 35794eff475f..20758ae2bf26 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -155,7 +155,8 @@ u64 uislib_storage_channel(int client_id); #endif int uislib_get_owned_pdest(struct uisscsi_dest *pdest); -int uislib_send_event(enum controlvm_id id, CONTROLVM_MESSAGE_PACKET *event); +int uislib_send_event(enum controlvm_id id, + struct controlvm_message_packet *event); /* structure used by vhba & vnic to keep track of queue & thread info */ struct chaninfo { diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index a0b1e042b43d..87c62df526f6 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -168,8 +168,8 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_MAX_BUSES; } - busNo = msg->cmd.createBus.busNo; - deviceCount = msg->cmd.createBus.deviceCount; + busNo = msg->cmd.create_bus.bus_no; + deviceCount = msg->cmd.create_bus.dev_count; POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount, POSTCODE_SEVERITY_INFO); @@ -199,7 +199,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) bus->device_count = deviceCount; bus->device = (struct device_info **) ((char *) bus + sizeof(struct bus_info)); - bus->bus_inst_uuid = msg->cmd.createBus.busInstGuid; + bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid; bus->bus_channel_bytes = 0; bus->bus_channel = NULL; @@ -221,12 +221,12 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) kfree(bus); return CONTROLVM_RESP_ERROR_ALREADY_DONE; } - if ((msg->cmd.createBus.channelAddr != 0) - && (msg->cmd.createBus.channelBytes != 0)) { - bus->bus_channel_bytes = msg->cmd.createBus.channelBytes; + if ((msg->cmd.create_bus.channel_addr != 0) + && (msg->cmd.create_bus.channel_bytes != 0)) { + bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes; bus->bus_channel = - init_vbus_channel(msg->cmd.createBus.channelAddr, - msg->cmd.createBus.channelBytes); + init_vbus_channel(msg->cmd.create_bus.channel_addr, + msg->cmd.create_bus.channel_bytes); } /* the msg is bound for virtpci; send guest_msgs struct to callback */ if (!msg->hdr.Flags.server) { @@ -236,8 +236,8 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) cmd.add_vbus.bus_no = busNo; cmd.add_vbus.chanptr = bus->bus_channel; cmd.add_vbus.dev_count = deviceCount; - cmd.add_vbus.bus_uuid = msg->cmd.createBus.busDataTypeGuid; - cmd.add_vbus.instance_uuid = msg->cmd.createBus.busInstGuid; + cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid; + cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid; if (!virt_control_chan_func) { LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no, @@ -279,7 +279,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) struct guest_msgs cmd; u32 busNo; - busNo = msg->cmd.destroyBus.busNo; + busNo = msg->cmd.destroy_bus.bus_no; read_lock(&BusListLock); @@ -354,8 +354,8 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) u64 minSize = MIN_IO_CHANNEL_SIZE; struct req_handler_info *pReqHandler; - busNo = msg->cmd.createDevice.busNo; - devNo = msg->cmd.createDevice.devNo; + busNo = msg->cmd.create_device.busNo; + devNo = msg->cmd.create_device.devNo; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -368,9 +368,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_KMALLOC_FAILED; } - dev->channel_uuid = msg->cmd.createDevice.dataTypeGuid; - dev->intr = msg->cmd.createDevice.intr; - dev->channel_addr = msg->cmd.createDevice.channelAddr; + dev->channel_uuid = msg->cmd.create_device.dataTypeGuid; + dev->intr = msg->cmd.create_device.intr; + dev->channel_addr = msg->cmd.create_device.channelAddr; dev->bus_no = busNo; dev->dev_no = devNo; sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */ @@ -385,9 +385,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) * channel */ minSize = pReqHandler->min_channel_bytes; - if (minSize > msg->cmd.createDevice.channelBytes) { + if (minSize > msg->cmd.create_device.channelBytes) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx", - (ulong) msg->cmd.createDevice.channelBytes, + (ulong) msg->cmd.create_device.channelBytes, (ulong) minSize); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); @@ -396,19 +396,19 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) } dev->chanptr = uislib_ioremap_cache(dev->channel_addr, - msg->cmd.createDevice.channelBytes); + msg->cmd.create_device.channelBytes); if (!dev->chanptr) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", dev->channel_addr, - msg->cmd.createDevice.channelBytes); + msg->cmd.create_device.channelBytes); result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); goto Away; } } - dev->instance_uuid = msg->cmd.createDevice.devInstGuid; - dev->channel_bytes = msg->cmd.createDevice.channelBytes; + dev->instance_uuid = msg->cmd.create_device.devInstGuid; + dev->channel_bytes = msg->cmd.create_device.channelBytes; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { @@ -552,8 +552,8 @@ pause_device(CONTROLVM_MESSAGE *msg) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.deviceChangeState.busNo; - devNo = msg->cmd.deviceChangeState.devNo; + busNo = msg->cmd.device_change_state.bus_no; + devNo = msg->cmd.device_change_state.dev_no; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { @@ -620,8 +620,8 @@ resume_device(CONTROLVM_MESSAGE *msg) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.deviceChangeState.busNo; - devNo = msg->cmd.deviceChangeState.devNo; + busNo = msg->cmd.device_change_state.bus_no; + devNo = msg->cmd.device_change_state.dev_no; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { @@ -689,8 +689,8 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) struct guest_msgs cmd; int retval = CONTROLVM_RESP_SUCCESS; - busNo = msg->cmd.destroyDevice.busNo; - devNo = msg->cmd.destroyDevice.devNo; + busNo = msg->cmd.destroy_device.bus_no; + devNo = msg->cmd.destroy_device.bus_no; read_lock(&BusListLock); LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo); @@ -773,8 +773,8 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf) { POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); - MaxBusCount = msg->cmd.initChipset.busCount; - PlatformNumber = msg->cmd.initChipset.platformNumber; + MaxBusCount = msg->cmd.init_chipset.bus_count; + PlatformNumber = msg->cmd.init_chipset.platform_number; PhysicalDataChan = 0; /* We need to make sure we have our functions registered @@ -799,7 +799,7 @@ delete_bus_glue(u32 busNo) CONTROLVM_MESSAGE msg; init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.cmd.destroyBus.busNo = busNo; + msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("destroy_bus failed. busNo=0x%x\n", busNo); return 0; @@ -813,8 +813,8 @@ delete_device_glue(u32 busNo, u32 devNo) CONTROLVM_MESSAGE msg; init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); - msg.cmd.destroyDevice.busNo = busNo; - msg.cmd.destroyDevice.devNo = devNo; + msg.cmd.destroy_device.bus_no = busNo; + msg.cmd.destroy_device.dev_no = devNo; if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo, devNo); @@ -843,8 +843,8 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, * after number 4, then the add_vnic will fail, and the * ultraboot will fail. */ - msg.cmd.initChipset.busCount = 23; - msg.cmd.initChipset.switchCount = 0; + msg.cmd.init_chipset.bus_count = 23; + msg.cmd.init_chipset.switch_count = 0; if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("init_chipset failed.\n"); return 0; @@ -858,10 +858,10 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_WARNING); init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); - msg.cmd.createBus.busNo = bus_no; - msg.cmd.createBus.deviceCount = 23; /* devNo+1; */ - msg.cmd.createBus.channelAddr = channel_addr; - msg.cmd.createBus.channelBytes = n_channel_bytes; + msg.cmd.create_bus.bus_no = bus_no; + msg.cmd.create_bus.dev_count = 23; /* devNo+1; */ + msg.cmd.create_bus.channel_addr = channel_addr; + msg.cmd.create_bus.channel_bytes = n_channel_bytes; if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("create_bus failed.\n"); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, @@ -889,9 +889,9 @@ uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = bus_no; - msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = segment_state_standby; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n", @@ -909,9 +909,9 @@ uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = bus_no; - msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = segment_state_running; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n", @@ -945,15 +945,15 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, * need to be ioremap()ed */ msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = bus_no; - msg.cmd.createDevice.devNo = dev_no; - msg.cmd.createDevice.devInstGuid = inst_uuid; + msg.cmd.create_device.busNo = bus_no; + msg.cmd.create_device.devNo = dev_no; + msg.cmd.create_device.devInstGuid = inst_uuid; if (intr) - msg.cmd.createDevice.intr = *intr; + msg.cmd.create_device.intr = *intr; else - memset(&msg.cmd.createDevice.intr, 0, + memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); - msg.cmd.createDevice.channelAddr = phys_chan_addr; + msg.cmd.create_device.channelAddr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -961,8 +961,8 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = spar_vhba_channel_protocol_uuid; + msg.cmd.create_device.channelBytes = chan_bytes; + msg.cmd.create_device.dataTypeGuid = spar_vhba_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA create_device failed.\n"); POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1004,15 +1004,15 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, * need to be ioremap()ed */ msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = bus_no; - msg.cmd.createDevice.devNo = dev_no; - msg.cmd.createDevice.devInstGuid = inst_uuid; + msg.cmd.create_device.busNo = bus_no; + msg.cmd.create_device.devNo = dev_no; + msg.cmd.create_device.devInstGuid = inst_uuid; if (intr) - msg.cmd.createDevice.intr = *intr; + msg.cmd.create_device.intr = *intr; else - memset(&msg.cmd.createDevice.intr, 0, + memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); - msg.cmd.createDevice.channelAddr = phys_chan_addr; + msg.cmd.create_device.channelAddr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -1020,8 +1020,8 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.createDevice.channelBytes = chan_bytes; - msg.cmd.createDevice.dataTypeGuid = spar_vnic_channel_protocol_uuid; + msg.cmd.create_device.channelBytes = chan_bytes; + msg.cmd.create_device.dataTypeGuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC create_device failed.\n"); POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1042,9 +1042,9 @@ uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = bus_no; - msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = segment_state_standby; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_standby; rc = pause_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n", @@ -1062,9 +1062,9 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); - msg.cmd.deviceChangeState.busNo = bus_no; - msg.cmd.deviceChangeState.devNo = dev_no; - msg.cmd.deviceChangeState.state = segment_state_running; + msg.cmd.device_change_state.bus_no = bus_no; + msg.cmd.device_change_state.dev_no = dev_no; + msg.cmd.device_change_state.state = segment_state_running; rc = resume_device(&msg); if (rc != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n", @@ -1093,10 +1093,10 @@ uislib_client_add_vnic(u32 busNo) init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); msg.hdr.Flags.testMessage = 1; - msg.cmd.createBus.busNo = busNo; - msg.cmd.createBus.deviceCount = 4; - msg.cmd.createBus.channelAddr = 0; - msg.cmd.createBus.channelBytes = 0; + msg.cmd.create_bus.bus_no = busNo; + msg.cmd.create_bus.dev_count = 4; + msg.cmd.create_bus.channel_addr = 0; + msg.cmd.create_bus.channel_bytes = 0; if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("client create_bus failed"); return 0; @@ -1105,13 +1105,13 @@ uislib_client_add_vnic(u32 busNo) init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); msg.hdr.Flags.testMessage = 1; - msg.cmd.createDevice.busNo = busNo; - msg.cmd.createDevice.devNo = devNo; - msg.cmd.createDevice.devInstGuid = NULL_UUID_LE; - memset(&msg.cmd.createDevice.intr, 0, sizeof(struct irq_info)); - msg.cmd.createDevice.channelAddr = PhysicalDataChan; - msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE; - msg.cmd.createDevice.dataTypeGuid = spar_vnic_channel_protocol_uuid; + msg.cmd.create_device.busNo = busNo; + msg.cmd.create_device.devNo = devNo; + msg.cmd.create_device.devInstGuid = NULL_UUID_LE; + memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); + msg.cmd.create_device.channelAddr = PhysicalDataChan; + msg.cmd.create_device.channelBytes = MIN_IO_CHANNEL_SIZE; + msg.cmd.create_device.dataTypeGuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("client create_device failed"); goto AwayCleanup; @@ -1123,7 +1123,7 @@ uislib_client_add_vnic(u32 busNo) if (busCreated) { init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyBus.busNo = busNo; + msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) LOGERR("client destroy_bus failed.\n"); } @@ -1141,8 +1141,8 @@ uislib_client_delete_vnic(u32 busNo) init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyDevice.busNo = busNo; - msg.cmd.destroyDevice.devNo = devNo; + msg.cmd.destroy_device.bus_no = busNo; + msg.cmd.destroy_device.dev_no = devNo; if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { /* Don't error exit - try to see if bus can be destroyed... */ LOGERR("client destroy_device failed.\n"); @@ -1150,7 +1150,7 @@ uislib_client_delete_vnic(u32 busNo) init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); msg.hdr.Flags.testMessage = 1; - msg.cmd.destroyBus.busNo = busNo; + msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) LOGERR("client destroy_bus failed.\n"); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index c8d8d258a7cd..7af23386e6ae 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -84,7 +84,7 @@ static const uuid_le UltraDiagPoolChannelProtocolGuid = /* 0xffffff is an invalid Bus/Device number */ static ulong g_diagpoolBusNo = 0xffffff; static ulong g_diagpoolDevNo = 0xffffff; -static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket; +static struct controlvm_message_packet g_DeviceChangeStatePacket; /* Only VNIC and VHBA channels are sent to visorclientbus (aka * "visorhackbus") @@ -670,7 +670,7 @@ chipset_init(CONTROLVM_MESSAGE *inmsg) /* Set features to indicate we support parahotplug (if Command * also supports it). */ features = - inmsg->cmd.initChipset. + inmsg->cmd.init_chipset. features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; /* Set the "reply" bit so Command knows this is a @@ -708,9 +708,9 @@ controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) /* For DiagPool channel DEVICE_CHANGESTATE, we need to send * back the deviceChangeState structure in the packet. */ if (msgHdr->Id == CONTROLVM_DEVICE_CHANGESTATE - && g_DeviceChangeStatePacket.deviceChangeState.busNo == + && g_DeviceChangeStatePacket.device_change_state.bus_no == g_diagpoolBusNo - && g_DeviceChangeStatePacket.deviceChangeState.devNo == + && g_DeviceChangeStatePacket.device_change_state.dev_no == g_diagpoolDevNo) outmsg.cmd = g_DeviceChangeStatePacket; if (outmsg.hdr.Flags.testMessage == 1) { @@ -732,7 +732,7 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, CONTROLVM_MESSAGE outmsg; controlvm_init_response(&outmsg, msgHdr, response); - outmsg.cmd.initChipset.features = features; + outmsg.cmd.init_chipset.features = features; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { LOGERR("signalinsert failed!"); @@ -747,8 +747,8 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, CONTROLVM_MESSAGE outmsg; controlvm_init_response(&outmsg, msgHdr, response); - outmsg.cmd.deviceChangeState.state = state; - outmsg.cmd.deviceChangeState.flags.physicalDevice = 1; + outmsg.cmd.device_change_state.state = state; + outmsg.cmd.device_change_state.flags.phys_device = 1; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { LOGERR("signalinsert failed!"); @@ -879,9 +879,9 @@ device_changestate_responder(enum controlvm_id cmdId, controlvm_init_response(&outmsg, &p->pendingMsgHdr, response); - outmsg.cmd.deviceChangeState.busNo = busNo; - outmsg.cmd.deviceChangeState.devNo = devNo; - outmsg.cmd.deviceChangeState.state = responseState; + outmsg.cmd.device_change_state.bus_no = busNo; + outmsg.cmd.device_change_state.dev_no = devNo; + outmsg.cmd.device_change_state.state = responseState; if (!visorchannel_signalinsert(ControlVm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg)) { @@ -1094,8 +1094,8 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, static void bus_create(CONTROLVM_MESSAGE *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->createBus.busNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->create_bus.bus_no; int rc = CONTROLVM_RESP_SUCCESS; VISORCHIPSET_BUS_INFO *pBusInfo = NULL; @@ -1121,7 +1121,7 @@ bus_create(CONTROLVM_MESSAGE *inmsg) INIT_LIST_HEAD(&pBusInfo->entry); pBusInfo->busNo = busNo; - pBusInfo->devNo = cmd->createBus.deviceCount; + pBusInfo->devNo = cmd->create_bus.dev_count; POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); @@ -1131,10 +1131,10 @@ bus_create(CONTROLVM_MESSAGE *inmsg) pBusInfo->chanInfo.addrType = ADDRTYPE_localPhysical; pBusInfo->flags.server = inmsg->hdr.Flags.server; - pBusInfo->chanInfo.channelAddr = cmd->createBus.channelAddr; - pBusInfo->chanInfo.nChannelBytes = cmd->createBus.channelBytes; - pBusInfo->chanInfo.channelTypeGuid = cmd->createBus.busDataTypeGuid; - pBusInfo->chanInfo.channelInstGuid = cmd->createBus.busInstGuid; + pBusInfo->chanInfo.channelAddr = cmd->create_bus.channel_addr; + pBusInfo->chanInfo.nChannelBytes = cmd->create_bus.channel_bytes; + pBusInfo->chanInfo.channelTypeGuid = cmd->create_bus.bus_data_type_uuid; + pBusInfo->chanInfo.channelInstGuid = cmd->create_bus.bus_inst_uuid; list_add(&pBusInfo->entry, &BusInfoList); @@ -1148,8 +1148,8 @@ bus_create(CONTROLVM_MESSAGE *inmsg) static void bus_destroy(CONTROLVM_MESSAGE *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->destroyBus.busNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->destroy_bus.bus_no; VISORCHIPSET_BUS_INFO *pBusInfo; int rc = CONTROLVM_RESP_SUCCESS; @@ -1174,13 +1174,13 @@ bus_destroy(CONTROLVM_MESSAGE *inmsg) static void bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->configureBus.busNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->configure_bus.bus_no; VISORCHIPSET_BUS_INFO *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; char s[99]; - busNo = cmd->configureBus.busNo; + busNo = cmd->configure_bus.bus_no; POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); pBusInfo = findbus(&BusInfoList, busNo); @@ -1210,7 +1210,7 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) goto Away; } - pBusInfo->partitionHandle = cmd->configureBus.guestHandle; + pBusInfo->partitionHandle = cmd->configure_bus.guest_handle; pBusInfo->partitionGuid = parser_id_get(parser_ctx); parser_param_start(parser_ctx, PARSERSTRING_NAME); pBusInfo->name = parser_string_get(parser_ctx); @@ -1225,9 +1225,9 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) static void my_device_create(CONTROLVM_MESSAGE *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->createDevice.busNo; - ulong devNo = cmd->createDevice.devNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->create_device.busNo; + ulong devNo = cmd->create_device.devNo; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; VISORCHIPSET_BUS_INFO *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1271,7 +1271,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) INIT_LIST_HEAD(&pDevInfo->entry); pDevInfo->busNo = busNo; pDevInfo->devNo = devNo; - pDevInfo->devInstGuid = cmd->createDevice.devInstGuid; + pDevInfo->devInstGuid = cmd->create_device.devInstGuid; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -1279,10 +1279,10 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) pDevInfo->chanInfo.addrType = ADDRTYPE_localTest; else pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical; - pDevInfo->chanInfo.channelAddr = cmd->createDevice.channelAddr; - pDevInfo->chanInfo.nChannelBytes = cmd->createDevice.channelBytes; - pDevInfo->chanInfo.channelTypeGuid = cmd->createDevice.dataTypeGuid; - pDevInfo->chanInfo.intr = cmd->createDevice.intr; + pDevInfo->chanInfo.channelAddr = cmd->create_device.channelAddr; + pDevInfo->chanInfo.nChannelBytes = cmd->create_device.channelBytes; + pDevInfo->chanInfo.channelTypeGuid = cmd->create_device.dataTypeGuid; + pDevInfo->chanInfo.intr = cmd->create_device.intr; list_add(&pDevInfo->entry, &DevInfoList); POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -1303,10 +1303,10 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) static void my_device_changestate(CONTROLVM_MESSAGE *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->deviceChangeState.busNo; - ulong devNo = cmd->deviceChangeState.devNo; - struct spar_segment_state state = cmd->deviceChangeState.state; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->device_change_state.bus_no; + ulong devNo = cmd->device_change_state.dev_no; + struct spar_segment_state state = cmd->device_change_state.state; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1337,9 +1337,9 @@ my_device_changestate(CONTROLVM_MESSAGE *inmsg) static void my_device_destroy(CONTROLVM_MESSAGE *inmsg) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd; - ulong busNo = cmd->destroyDevice.busNo; - ulong devNo = cmd->destroyDevice.devNo; + struct controlvm_message_packet *cmd = &inmsg->cmd; + ulong busNo = cmd->destroy_device.bus_no; + ulong devNo = cmd->destroy_device.dev_no; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1621,7 +1621,7 @@ parahotplug_request_destroy(struct parahotplug_request *req) static void parahotplug_request_kickoff(struct parahotplug_request *req) { - CONTROLVM_MESSAGE_PACKET *cmd = &req->msg.cmd; + struct controlvm_message_packet *cmd = &req->msg.cmd; char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], env_func[40]; char *envp[] = { @@ -1631,18 +1631,19 @@ parahotplug_request_kickoff(struct parahotplug_request *req) sprintf(env_cmd, "SPAR_PARAHOTPLUG=1"); sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id); sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d", - cmd->deviceChangeState.state.active); + cmd->device_change_state.state.active); sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d", - cmd->deviceChangeState.busNo); + cmd->device_change_state.bus_no); sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d", - cmd->deviceChangeState.devNo >> 3); + cmd->device_change_state.dev_no >> 3); sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d", - cmd->deviceChangeState.devNo & 0x7); + cmd->device_change_state.dev_no & 0x7); LOGINF("parahotplug_request_kickoff: state=%d, bdf=%d/%d/%d, id=%u\n", - cmd->deviceChangeState.state.active, - cmd->deviceChangeState.busNo, cmd->deviceChangeState.devNo >> 3, - cmd->deviceChangeState.devNo & 7, req->id); + cmd->device_change_state.state.active, + cmd->device_change_state.bus_no, + cmd->device_change_state.dev_no >> 3, + cmd->device_change_state.dev_no & 7, req->id); kobject_uevent_env(&Visorchipset_platform_device.dev.kobj, KOBJ_CHANGE, envp); @@ -1669,7 +1670,7 @@ parahotplug_process_list(void) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT, - req->msg.cmd.deviceChangeState.state); + req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); } } @@ -1700,11 +1701,11 @@ parahotplug_request_complete(int id, u16 active) */ list_del(pos); spin_unlock(&Parahotplug_request_list_lock); - req->msg.cmd.deviceChangeState.state.active = active; + req->msg.cmd.device_change_state.state.active = active; if (req->msg.hdr.Flags.responseExpected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_SUCCESS, - req->msg.cmd.deviceChangeState.state); + req->msg.cmd.device_change_state.state); parahotplug_request_destroy(req); return 0; } @@ -1729,7 +1730,7 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) return; } - if (inmsg->cmd.deviceChangeState.state.active) { + if (inmsg->cmd.device_change_state.state.active) { /* For enable messages, just respond with success * right away. This is a bit of a hack, but there are * issues with the early enable messages we get (with @@ -1741,9 +1742,8 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) */ parahotplug_request_kickoff(req); controlvm_respond_physdev_changestate(&inmsg->hdr, - CONTROLVM_RESP_SUCCESS, - inmsg->cmd. - deviceChangeState.state); + CONTROLVM_RESP_SUCCESS, inmsg->cmd. + device_change_state.state); parahotplug_request_destroy(req); } else { /* For disable messages, add the request to the @@ -1773,7 +1773,7 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) static BOOL handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) { - CONTROLVM_MESSAGE_PACKET *cmd = &inmsg.cmd; + struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parametersAddr = 0; u32 parametersBytes = 0; PARSER_CONTEXT *parser_ctx = NULL; @@ -1824,42 +1824,42 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) switch (inmsg.hdr.Id) { case CONTROLVM_CHIPSET_INIT: LOGINF("CHIPSET_INIT(#busses=%lu,#switches=%lu)", - (ulong) inmsg.cmd.initChipset.busCount, - (ulong) inmsg.cmd.initChipset.switchCount); + (ulong) inmsg.cmd.init_chipset.bus_count, + (ulong) inmsg.cmd.init_chipset.switch_count); chipset_init(&inmsg); break; case CONTROLVM_BUS_CREATE: LOGINF("BUS_CREATE(%lu,#devs=%lu)", - (ulong) cmd->createBus.busNo, - (ulong) cmd->createBus.deviceCount); + (ulong) cmd->create_bus.bus_no, + (ulong) cmd->create_bus.dev_count); bus_create(&inmsg); break; case CONTROLVM_BUS_DESTROY: - LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroyBus.busNo); + LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroy_bus.bus_no); bus_destroy(&inmsg); break; case CONTROLVM_BUS_CONFIGURE: - LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configureBus.busNo); + LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configure_bus.bus_no); bus_configure(&inmsg, parser_ctx); break; case CONTROLVM_DEVICE_CREATE: LOGINF("DEVICE_CREATE(%lu,%lu)", - (ulong) cmd->createDevice.busNo, - (ulong) cmd->createDevice.devNo); + (ulong) cmd->create_device.busNo, + (ulong) cmd->create_device.devNo); my_device_create(&inmsg); break; case CONTROLVM_DEVICE_CHANGESTATE: - if (cmd->deviceChangeState.flags.physicalDevice) { + if (cmd->device_change_state.flags.phys_device) { LOGINF("DEVICE_CHANGESTATE for physical device (%lu,%lu, active=%lu)", - (ulong) cmd->deviceChangeState.busNo, - (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.active); + (ulong) cmd->device_change_state.bus_no, + (ulong) cmd->device_change_state.dev_no, + (ulong) cmd->device_change_state.state.active); parahotplug_process_message(&inmsg); } else { LOGINF("DEVICE_CHANGESTATE for virtual device (%lu,%lu, state.Alive=0x%lx)", - (ulong) cmd->deviceChangeState.busNo, - (ulong) cmd->deviceChangeState.devNo, - (ulong) cmd->deviceChangeState.state.alive); + (ulong) cmd->device_change_state.bus_no, + (ulong) cmd->device_change_state.dev_no, + (ulong) cmd->device_change_state.state.alive); /* save the hdr and cmd structures for later use */ /* when sending back the response to Command */ my_device_changestate(&inmsg); @@ -1870,14 +1870,14 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) break; case CONTROLVM_DEVICE_DESTROY: LOGINF("DEVICE_DESTROY(%lu,%lu)", - (ulong) cmd->destroyDevice.busNo, - (ulong) cmd->destroyDevice.devNo); + (ulong) cmd->destroy_device.bus_no, + (ulong) cmd->destroy_device.dev_no); my_device_destroy(&inmsg); break; case CONTROLVM_DEVICE_CONFIGURE: LOGINF("DEVICE_CONFIGURE(%lu,%lu)", - (ulong) cmd->configureDevice.busNo, - (ulong) cmd->configureDevice.devNo); + (ulong) cmd->configure_device.busNo, + (ulong) cmd->configure_device.devNo); /* no op for now, just send a respond that we passed */ if (inmsg.hdr.Flags.responseExpected) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); @@ -2056,8 +2056,8 @@ setup_crash_devices_work_queue(struct work_struct *work) /* send init chipset msg */ msg.hdr.Id = CONTROLVM_CHIPSET_INIT; - msg.cmd.initChipset.busCount = 23; - msg.cmd.initChipset.switchCount = 0; + msg.cmd.init_chipset.bus_count = 23; + msg.cmd.init_chipset.switch_count = 0; chipset_init(&msg); @@ -2116,7 +2116,7 @@ setup_crash_devices_work_queue(struct work_struct *work) } /* reuse IOVM create bus message */ - if (localCrashCreateBusMsg.cmd.createBus.channelAddr != 0) + if (localCrashCreateBusMsg.cmd.create_bus.channel_addr != 0) bus_create(&localCrashCreateBusMsg); else { LOGERR("CrashCreateBusMsg is null, no dump will be taken"); @@ -2126,7 +2126,7 @@ setup_crash_devices_work_queue(struct work_struct *work) } /* reuse create device message for storage device */ - if (localCrashCreateDevMsg.cmd.createDevice.channelAddr != 0) + if (localCrashCreateDevMsg.cmd.create_device.channelAddr != 0) my_device_create(&localCrashCreateDevMsg); else { LOGERR("CrashCreateDevMsg is null, no dump will be taken"); -- GitLab From 98d7b59477617d0950819d23168df30bf231e6bb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:26 -0400 Subject: [PATCH 1377/9457] staging: unisys: refactor CONTROLVM_MESSAGE_HEADER This patch removes the typedef from CONTROLVM_MESSAGE_HEADER, using the struct controlvm_message_header name directly instead. It fixes CamelCase names and updates all references to changed names: MessageSize => message_size SegmentIndex => segment_index CompletionStatus => completion_status responseExpected => response_expected testMessage => test_message partialCompletion => partial_completion writerInDiag => writer_in_diag Flags => flags Reserved => reserved MessageHandle => message_handle PayloadVmOffset => payload_vm_offset PayloadMaxBytes => payload_max_bytes PayloadBytes => payload_bytes Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 40 ++-- drivers/staging/unisys/uislib/uislib.c | 40 ++-- .../unisys/visorchipset/visorchipset.h | 12 +- .../unisys/visorchipset/visorchipset_main.c | 184 +++++++++--------- 4 files changed, 139 insertions(+), 137 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 6d68b2cfc4fd..abf6bc9f57d0 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -169,53 +169,51 @@ enum ultra_chipset_feature { * queue. Commands are easily distinguished from responses by * looking at the flags.response field. */ -typedef struct _CONTROLVM_MESSAGE_HEADER { - u32 Id; /* See control_vm_id. */ +struct controlvm_message_header { + u32 id; /* See CONTROLVM_ID. */ /* For requests, indicates the message type. */ /* For responses, indicates the type of message we are responding to. */ - u32 MessageSize; /* Includes size of this struct + size + u32 message_size; /* Includes size of this struct + size * of message */ - u32 SegmentIndex; /* Index of segment containing Vm + u32 segment_index; /* Index of segment containing Vm * message/information */ - u32 CompletionStatus; /* Error status code or result of + u32 completion_status; /* Error status code or result of * message completion */ struct { u32 failed:1; /**< =1 in a response to * signify * failure */ - u32 responseExpected:1; /**< =1 in all messages that expect a + u32 response_expected:1; /**< =1 in all messages that expect a * response (Control ignores this * bit) */ u32 server:1; /**< =1 in all bus & device-related * messages where the message * receiver is to act as the bus or * device server */ - u32 testMessage:1; /**< =1 for testing use only + u32 test_message:1; /**< =1 for testing use only * (Control and Command ignore this * bit) */ - u32 partialCompletion:1; /**< =1 if there are forthcoming + u32 partial_completion:1; /**< =1 if there are forthcoming * responses/acks associated * with this message */ u32 preserve:1; /**< =1 this is to let us know to * preserve channel contents * (for running guests)*/ - u32 writerInDiag:1; /**< =1 the DiagWriter is active in the + u32 writer_in_diag:1; /**< =1 the DiagWriter is active in the * Diagnostic Partition*/ - - /* remaining bits in this 32-bit word are available */ - } Flags; - u32 Reserved; /* Natural alignment */ - u64 MessageHandle; /* Identifies the particular message instance, + } flags; + u32 reserved; /* Natural alignment */ + u64 message_handle; /* Identifies the particular message instance, * and is used to match particular */ /* request instances with the corresponding response instance. */ - u64 PayloadVmOffset; /* Offset of payload area from start of this + u64 payload_vm_offset; /* Offset of payload area from start of this * instance of ControlVm segment */ - u32 PayloadMaxBytes; /* Maximum bytes allocated in payload + u32 payload_max_bytes; /* Maximum bytes allocated in payload * area of ControlVm segment */ - u32 PayloadBytes; /* Actual number of bytes of payload + u32 payload_bytes; /* Actual number of bytes of payload * area to copy between IO/Command; */ /* if non-zero, there is a payload to copy. */ -} CONTROLVM_MESSAGE_HEADER; +}; typedef struct _CONTROLVM_PACKET_DEVICE_CREATE { u32 busNo; /**< bus # (0..n-1) from the msg receiver's @@ -241,12 +239,12 @@ typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { } CONTROLVM_PACKET_DEVICE_CONFIGURE; /* for CONTROLVM_DEVICE_CONFIGURE */ typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { - CONTROLVM_MESSAGE_HEADER Header; + struct controlvm_message_header Header; CONTROLVM_PACKET_DEVICE_CREATE Packet; } CONTROLVM_MESSAGE_DEVICE_CREATE; /* total 128 bytes */ typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { - CONTROLVM_MESSAGE_HEADER Header; + struct controlvm_message_header Header; CONTROLVM_PACKET_DEVICE_CONFIGURE Packet; } CONTROLVM_MESSAGE_DEVICE_CONFIGURE; /* total 56 bytes */ @@ -343,7 +341,7 @@ struct controlvm_message_packet { /* All messages in any ControlVm queue have this layout. */ typedef struct _CONTROLVM_MESSAGE { - CONTROLVM_MESSAGE_HEADER hdr; + struct controlvm_message_header hdr; struct controlvm_message_packet cmd; } CONTROLVM_MESSAGE; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 87c62df526f6..63f1d6ef6338 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -124,9 +124,9 @@ static void init_msg_header(CONTROLVM_MESSAGE *msg, u32 id, uint rsp, uint svr) { memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); - msg->hdr.Id = id; - msg->hdr.Flags.responseExpected = rsp; - msg->hdr.Flags.server = svr; + msg->hdr.id = id; + msg->hdr.flags.response_expected = rsp; + msg->hdr.flags.server = svr; } static __iomem void * @@ -188,7 +188,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) /* Currently by default, the bus Number is the GuestHandle. * Configure Bus message can override this. */ - if (msg->hdr.Flags.testMessage) { + if (msg->hdr.flags.test_message) { /* This implies we're the IOVM so set guest handle to 0... */ bus->guest_handle = 0; bus->bus_no = busNo; @@ -229,7 +229,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) msg->cmd.create_bus.channel_bytes); } /* the msg is bound for virtpci; send guest_msgs struct to callback */ - if (!msg->hdr.Flags.server) { + if (!msg->hdr.flags.server) { struct guest_msgs cmd; cmd.msgtype = GUEST_ADD_VBUS; @@ -309,7 +309,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) } read_unlock(&BusListLock); - if (msg->hdr.Flags.server) + if (msg->hdr.flags.server) goto remove; /* client messages require us to call the virtpci callback associated @@ -376,7 +376,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */ sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo); /* map the channel memory for the device. */ - if (msg->hdr.Flags.testMessage) + if (msg->hdr.flags.test_message) dev->chanptr = (void __iomem *)__va(dev->channel_addr); else { pReqHandler = req_handler_find(dev->channel_uuid); @@ -439,7 +439,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) /* the msg is bound for virtpci; send * guest_msgs struct to callback */ - if (!msg->hdr.Flags.server) { + if (!msg->hdr.flags.server) { struct guest_msgs cmd; if (!uuid_le_cmp(dev->channel_uuid, @@ -534,7 +534,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) result = CONTROLVM_RESP_ERROR_BUS_INVALID; Away: - if (!msg->hdr.Flags.testMessage) { + if (!msg->hdr.flags.test_message) { uislib_iounmap(dev->chanptr); dev->chanptr = NULL; } @@ -758,7 +758,7 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) uislib_disable_channel_interrupts(busNo, devNo); } /* unmap the channel memory for the device. */ - if (!msg->hdr.Flags.testMessage) { + if (!msg->hdr.flags.test_message) { LOGINF("destroy_device, doing iounmap"); uislib_iounmap(dev->chanptr); } @@ -779,12 +779,12 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf) /* We need to make sure we have our functions registered * before processing messages. If we are a test vehicle the - * testMessage for init_chipset will be set. We can ignore the + * test_message for init_chipset will be set. We can ignore the * waits for the callbacks, since this will be manually entered - * from a user. If no testMessage is set, we will wait for the + * from a user. If no test_message is set, we will wait for the * functions. */ - if (!msg->hdr.Flags.testMessage) + if (!msg->hdr.flags.test_message) WAIT_ON_CALLBACK(virt_control_chan_func); chipset_inited = 1; @@ -944,7 +944,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, /* signify that the physical channel address does NOT * need to be ioremap()ed */ - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.create_device.busNo = bus_no; msg.cmd.create_device.devNo = dev_no; msg.cmd.create_device.devInstGuid = inst_uuid; @@ -1003,7 +1003,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, /* signify that the physical channel address does NOT * need to be ioremap()ed */ - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.create_device.busNo = bus_no; msg.cmd.create_device.devNo = dev_no; msg.cmd.create_device.devInstGuid = inst_uuid; @@ -1092,7 +1092,7 @@ uislib_client_add_vnic(u32 busNo) CONTROLVM_MESSAGE msg; init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.create_bus.bus_no = busNo; msg.cmd.create_bus.dev_count = 4; msg.cmd.create_bus.channel_addr = 0; @@ -1104,7 +1104,7 @@ uislib_client_add_vnic(u32 busNo) busCreated = TRUE; init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.create_device.busNo = busNo; msg.cmd.create_device.devNo = devNo; msg.cmd.create_device.devInstGuid = NULL_UUID_LE; @@ -1122,7 +1122,7 @@ uislib_client_add_vnic(u32 busNo) AwayCleanup: if (busCreated) { init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) LOGERR("client destroy_bus failed.\n"); @@ -1140,7 +1140,7 @@ uislib_client_delete_vnic(u32 busNo) CONTROLVM_MESSAGE msg; init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.destroy_device.bus_no = busNo; msg.cmd.destroy_device.dev_no = devNo; if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { @@ -1149,7 +1149,7 @@ uislib_client_delete_vnic(u32 busNo) } init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); - msg.hdr.Flags.testMessage = 1; + msg.hdr.flags.test_message = 1; msg.cmd.destroy_bus.bus_no = busNo; if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) LOGERR("client destroy_bus failed.\n"); diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index cb93da931f75..966b1dd3e669 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -86,7 +86,7 @@ typedef struct { u64 Reserved2; u32 switchNo; /* when devState.attached==1 */ u32 internalPortNo; /* when devState.attached==1 */ - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM_MESSAGE */ + struct controlvm_message_header pendingMsgHdr; /* CONTROLVM_MESSAGE */ /** For private use by the bus driver */ void *bus_driver_context; @@ -139,7 +139,7 @@ typedef struct { /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ } flags; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM MsgHdr */ + struct controlvm_message_header pendingMsgHdr; /* CONTROLVM MsgHdr */ /** For private use by the bus driver */ void *bus_driver_context; u64 devNo; @@ -172,7 +172,7 @@ typedef struct { u32 Reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; + struct controlvm_message_header pendingMsgHdr; } VISORCHIPSET_SWITCH_INFO; @@ -195,7 +195,7 @@ typedef struct { u32 Reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; + struct controlvm_message_header pendingMsgHdr; } VISORCHIPSET_EXTERNALPORT_INFO; @@ -209,8 +209,8 @@ typedef struct { u32 busNo; /* valid only when state.attached == 1 */ u32 devNo; /* valid only when state.attached == 1 */ u64 Reserved1; - u32 Reserved2; /* control_vm_id */ - CONTROLVM_MESSAGE_HEADER pendingMsgHdr; + u32 Reserved2; /* CONTROLVM_ID */ + struct controlvm_message_header pendingMsgHdr; MYPROCOBJECT *procObject; } VISORCHIPSET_INTERNALPORT_INFO; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 7af23386e6ae..b7d53527c824 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -76,9 +76,9 @@ typedef struct { unsigned int crc; } MESSAGE_ENVELOPE; -static CONTROLVM_MESSAGE_HEADER g_DiagMsgHdr; -static CONTROLVM_MESSAGE_HEADER g_ChipSetMsgHdr; -static CONTROLVM_MESSAGE_HEADER g_DelDumpMsgHdr; +static struct controlvm_message_header g_DiagMsgHdr; +static struct controlvm_message_header g_ChipSetMsgHdr; +static struct controlvm_message_header g_DelDumpMsgHdr; static const uuid_le UltraDiagPoolChannelProtocolGuid = SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID; /* 0xffffff is an invalid Bus/Device number */ @@ -117,9 +117,9 @@ static CONTROLVM_PAYLOAD_INFO ControlVm_payload_info; static struct channel_header *Test_Vnic_channel; typedef struct { - CONTROLVM_MESSAGE_HEADER Dumpcapture_header; - CONTROLVM_MESSAGE_HEADER Gettextdump_header; - CONTROLVM_MESSAGE_HEADER Dumpcomplete_header; + struct controlvm_message_header Dumpcapture_header; + struct controlvm_message_header Gettextdump_header; + struct controlvm_message_header Dumpcomplete_header; BOOL Gettextdump_outstanding; u32 crc32; ulong length; @@ -182,7 +182,7 @@ struct putfile_request { u64 sig; /* PUTFILE_REQUEST_SIG */ /* header from original TransmitFile request */ - CONTROLVM_MESSAGE_HEADER controlvm_header; + struct controlvm_message_header controlvm_header; u64 file_request_number; /* from original TransmitFile request */ /* link to next struct putfile_request */ @@ -344,12 +344,14 @@ static struct platform_device Visorchipset_platform_device = { }; /* Function prototypes */ -static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response); -static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, - enum ultra_chipset_feature features); -static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER * - msgHdr, int response, struct spar_segment_state state); +static void controlvm_respond(struct controlvm_message_header *msgHdr, + int response); +static void controlvm_respond_chipset_init( + struct controlvm_message_header *msgHdr, int response, + enum ultra_chipset_feature features); +static void controlvm_respond_physdev_changestate( + struct controlvm_message_header *msgHdr, int response, + struct spar_segment_state state); static ssize_t toolaction_show(struct device *dev, struct device_attribute *attr, @@ -680,42 +682,42 @@ chipset_init(CONTROLVM_MESSAGE *inmsg) Away: if (rc < 0) cleanup_controlvm_structures(); - if (inmsg->hdr.Flags.responseExpected) + if (inmsg->hdr.flags.response_expected) controlvm_respond_chipset_init(&inmsg->hdr, rc, features); } static void controlvm_init_response(CONTROLVM_MESSAGE *msg, - CONTROLVM_MESSAGE_HEADER *msgHdr, int response) + struct controlvm_message_header *msgHdr, int response) { memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); - memcpy(&msg->hdr, msgHdr, sizeof(CONTROLVM_MESSAGE_HEADER)); - msg->hdr.PayloadBytes = 0; - msg->hdr.PayloadVmOffset = 0; - msg->hdr.PayloadMaxBytes = 0; + memcpy(&msg->hdr, msgHdr, sizeof(struct controlvm_message_header)); + msg->hdr.payload_bytes = 0; + msg->hdr.payload_vm_offset = 0; + msg->hdr.payload_max_bytes = 0; if (response < 0) { - msg->hdr.Flags.failed = 1; - msg->hdr.CompletionStatus = (u32) (-response); + msg->hdr.flags.failed = 1; + msg->hdr.completion_status = (u32) (-response); } } static void -controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) +controlvm_respond(struct controlvm_message_header *msgHdr, int response) { CONTROLVM_MESSAGE outmsg; controlvm_init_response(&outmsg, msgHdr, response); /* For DiagPool channel DEVICE_CHANGESTATE, we need to send * back the deviceChangeState structure in the packet. */ - if (msgHdr->Id == CONTROLVM_DEVICE_CHANGESTATE + if (msgHdr->id == CONTROLVM_DEVICE_CHANGESTATE && g_DeviceChangeStatePacket.device_change_state.bus_no == g_diagpoolBusNo && g_DeviceChangeStatePacket.device_change_state.dev_no == g_diagpoolDevNo) outmsg.cmd = g_DeviceChangeStatePacket; - if (outmsg.hdr.Flags.testMessage == 1) { + if (outmsg.hdr.flags.test_message == 1) { LOGINF("%s controlvm_msg=0x%x response=%d for test message", - __func__, outmsg.hdr.Id, response); + __func__, outmsg.hdr.id, response); return; } if (!visorchannel_signalinsert(ControlVm_channel, @@ -726,7 +728,8 @@ controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) } static void -controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, +controlvm_respond_chipset_init(struct controlvm_message_header *msgHdr, + int response, enum ultra_chipset_feature features) { CONTROLVM_MESSAGE outmsg; @@ -740,9 +743,9 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, } } -static void -controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, - int response, struct spar_segment_state state) +static void controlvm_respond_physdev_changestate( + struct controlvm_message_header *msgHdr, int response, + struct spar_segment_state state) { CONTROLVM_MESSAGE outmsg; @@ -839,16 +842,16 @@ bus_responder(enum controlvm_id cmdId, ulong busNo, int response) need_clear = TRUE; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { LOGERR("bus_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pendingMsgHdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); return; } controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + p->pendingMsgHdr.id = CONTROLVM_INVALID; if (need_clear) { busInfo_clear(p); delbusdevices(&DevInfoList, busNo); @@ -868,12 +871,12 @@ device_changestate_responder(enum controlvm_id cmdId, LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); return; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pendingMsgHdr.id != cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); return; } @@ -889,7 +892,7 @@ device_changestate_responder(enum controlvm_id cmdId, return; } - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + p->pendingMsgHdr.id = CONTROLVM_INVALID; } static void @@ -911,23 +914,23 @@ device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, need_clear = TRUE; } - if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) { + if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.Id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id); + if (p->pendingMsgHdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); return; } controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.Id = CONTROLVM_INVALID; + p->pendingMsgHdr.id = CONTROLVM_INVALID; if (need_clear) devInfo_clear(p); } static void bus_epilog(u32 busNo, - u32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr, + u32 cmd, struct controlvm_message_header *msgHdr, int response, BOOL needResponse) { BOOL notified = FALSE; @@ -940,9 +943,9 @@ bus_epilog(u32 busNo, } if (needResponse) { memcpy(&pBusInfo->pendingMsgHdr, msgHdr, - sizeof(CONTROLVM_MESSAGE_HEADER)); + sizeof(struct controlvm_message_header)); } else - pBusInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; + pBusInfo->pendingMsgHdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response == CONTROLVM_RESP_SUCCESS) { @@ -994,7 +997,7 @@ bus_epilog(u32 busNo, static void device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, - CONTROLVM_MESSAGE_HEADER *msgHdr, int response, + struct controlvm_message_header *msgHdr, int response, BOOL needResponse, BOOL for_visorbus) { VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers = NULL; @@ -1017,9 +1020,9 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, notifiers = &BusDev_Client_Notifiers; if (needResponse) { memcpy(&pDevInfo->pendingMsgHdr, msgHdr, - sizeof(CONTROLVM_MESSAGE_HEADER)); + sizeof(struct controlvm_message_header)); } else - pDevInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; + pDevInfo->pendingMsgHdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response >= 0) { @@ -1125,12 +1128,12 @@ bus_create(CONTROLVM_MESSAGE *inmsg) POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.Flags.testMessage == 1) + if (inmsg->hdr.flags.test_message == 1) pBusInfo->chanInfo.addrType = ADDRTYPE_localTest; else pBusInfo->chanInfo.addrType = ADDRTYPE_localPhysical; - pBusInfo->flags.server = inmsg->hdr.Flags.server; + pBusInfo->flags.server = inmsg->hdr.flags.server; pBusInfo->chanInfo.channelAddr = cmd->create_bus.channel_addr; pBusInfo->chanInfo.nChannelBytes = cmd->create_bus.channel_bytes; pBusInfo->chanInfo.channelTypeGuid = cmd->create_bus.bus_data_type_uuid; @@ -1142,7 +1145,7 @@ bus_create(CONTROLVM_MESSAGE *inmsg) Away: bus_epilog(busNo, CONTROLVM_BUS_CREATE, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void @@ -1168,7 +1171,7 @@ bus_destroy(CONTROLVM_MESSAGE *inmsg) Away: bus_epilog(busNo, CONTROLVM_BUS_DESTROY, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void @@ -1201,9 +1204,9 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) goto Away; } /* TBD - add this check to other commands also... */ - if (pBusInfo->pendingMsgHdr.Id != CONTROLVM_INVALID) { + if (pBusInfo->pendingMsgHdr.id != CONTROLVM_INVALID) { LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu MsgId=%u outstanding", - busNo, (uint) pBusInfo->pendingMsgHdr.Id); + busNo, (uint) pBusInfo->pendingMsgHdr.id); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; @@ -1219,7 +1222,7 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO); Away: bus_epilog(busNo, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, - rc, inmsg->hdr.Flags.responseExpected == 1); + rc, inmsg->hdr.flags.response_expected == 1); } static void @@ -1275,7 +1278,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); - if (inmsg->hdr.Flags.testMessage == 1) + if (inmsg->hdr.flags.test_message == 1) pDevInfo->chanInfo.addrType = ADDRTYPE_localTest; else pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical; @@ -1296,7 +1299,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) } device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, + inmsg->hdr.flags.response_expected == 1, FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); } @@ -1330,7 +1333,7 @@ my_device_changestate(CONTROLVM_MESSAGE *inmsg) if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo) device_epilog(busNo, devNo, state, CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, + inmsg->hdr.flags.response_expected == 1, FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); } @@ -1360,7 +1363,7 @@ my_device_destroy(CONTROLVM_MESSAGE *inmsg) if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo) device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, - inmsg->hdr.Flags.responseExpected == 1, + inmsg->hdr.flags.response_expected == 1, FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); } @@ -1490,15 +1493,15 @@ visorchipset_chipset_notready(void) EXPORT_SYMBOL_GPL(visorchipset_chipset_notready); static void -chipset_ready(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_ready(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_ready(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected && !visorchipset_holdchipsetready) + if (msgHdr->flags.response_expected && !visorchipset_holdchipsetready) controlvm_respond(msgHdr, rc); - if (msgHdr->Flags.responseExpected && visorchipset_holdchipsetready) { + if (msgHdr->flags.response_expected && visorchipset_holdchipsetready) { /* Send CHIPSET_READY response when all modules have been loaded * and disks mounted for the partition */ @@ -1508,24 +1511,24 @@ chipset_ready(CONTROLVM_MESSAGE_HEADER *msgHdr) } static void -chipset_selftest(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_selftest(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_selftest(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected) + if (msgHdr->flags.response_expected) controlvm_respond(msgHdr, rc); } static void -chipset_notready(CONTROLVM_MESSAGE_HEADER *msgHdr) +chipset_notready(struct controlvm_message_header *msgHdr) { int rc = visorchipset_chipset_notready(); if (rc != CONTROLVM_RESP_SUCCESS) rc = -rc; - if (msgHdr->Flags.responseExpected) + if (msgHdr->flags.response_expected) controlvm_respond(msgHdr, rc); } @@ -1538,8 +1541,9 @@ read_controlvm_event(CONTROLVM_MESSAGE *msg) if (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_EVENT, msg)) { /* got a message */ - if (msg->hdr.Flags.testMessage == 1) { - LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", msg->hdr.Id); + if (msg->hdr.flags.test_message == 1) { + LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", + msg->hdr.id); return FALSE; } return TRUE; @@ -1666,7 +1670,7 @@ parahotplug_process_list(void) list_entry(pos, struct parahotplug_request, list); if (time_after_eq(jiffies, req->expiration)) { list_del(pos); - if (req->msg.hdr.Flags.responseExpected) + if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT, @@ -1702,7 +1706,7 @@ parahotplug_request_complete(int id, u16 active) list_del(pos); spin_unlock(&Parahotplug_request_list_lock); req->msg.cmd.device_change_state.state.active = active; - if (req->msg.hdr.Flags.responseExpected) + if (req->msg.hdr.flags.response_expected) controlvm_respond_physdev_changestate( &req->msg.hdr, CONTROLVM_RESP_SUCCESS, req->msg.cmd.device_change_state.state); @@ -1781,13 +1785,13 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) CONTROLVM_MESSAGE ackmsg; /* create parsing context if necessary */ - isLocalAddr = (inmsg.hdr.Flags.testMessage == 1); + isLocalAddr = (inmsg.hdr.flags.test_message == 1); if (channel_addr == 0) { LOGERR("HUH? channel_addr is 0!"); return TRUE; } - parametersAddr = channel_addr + inmsg.hdr.PayloadVmOffset; - parametersBytes = inmsg.hdr.PayloadBytes; + parametersAddr = channel_addr + inmsg.hdr.payload_vm_offset; + parametersBytes = inmsg.hdr.payload_bytes; /* Parameter and channel addresses within test messages actually lie * within our OS-controlled memory. We need to know that, because it @@ -1805,7 +1809,7 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) return FALSE; } LOGWRN("parsing failed"); - LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.Id); + LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.id); LOGWRN("parametersAddr=0x%llx", (u64) parametersAddr); LOGWRN("parametersBytes=%lu", (ulong) parametersBytes); LOGWRN("isLocalAddr=%d", isLocalAddr); @@ -1821,7 +1825,7 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) (ControlVm_channel, CONTROLVM_QUEUE_ACK, &ackmsg))) LOGWRN("failed to send ACK failed"); } - switch (inmsg.hdr.Id) { + switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: LOGINF("CHIPSET_INIT(#busses=%lu,#switches=%lu)", (ulong) inmsg.cmd.init_chipset.bus_count, @@ -1879,7 +1883,7 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) (ulong) cmd->configure_device.busNo, (ulong) cmd->configure_device.devNo); /* no op for now, just send a respond that we passed */ - if (inmsg.hdr.Flags.responseExpected) + if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); break; case CONTROLVM_CHIPSET_READY: @@ -1895,8 +1899,8 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) chipset_notready(&inmsg.hdr); break; default: - LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.Id); - if (inmsg.hdr.Flags.responseExpected) + LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.id); + if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN); break; @@ -1953,24 +1957,24 @@ controlvm_periodic_work(struct work_struct *work) * should be sent */ if (visorchipset_holdchipsetready - && (g_ChipSetMsgHdr.Id != CONTROLVM_INVALID)) { + && (g_ChipSetMsgHdr.id != CONTROLVM_INVALID)) { if (check_chipset_events() == 1) { LOGINF("Sending CHIPSET_READY response"); controlvm_respond(&g_ChipSetMsgHdr, 0); clear_chipset_events(); memset(&g_ChipSetMsgHdr, 0, - sizeof(CONTROLVM_MESSAGE_HEADER)); + sizeof(struct controlvm_message_header)); } } while (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_RESPONSE, &inmsg)) { - if (inmsg.hdr.PayloadMaxBytes != 0) { + if (inmsg.hdr.payload_max_bytes != 0) { LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.", - (ulong) inmsg.hdr.PayloadMaxBytes, - (ulong) inmsg.hdr.PayloadVmOffset, - inmsg.hdr.Id); + (ulong) inmsg.hdr.payload_max_bytes, + (ulong) inmsg.hdr.payload_vm_offset, + inmsg.hdr.id); } } if (!gotACommand) { @@ -2055,7 +2059,7 @@ setup_crash_devices_work_queue(struct work_struct *work) POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* send init chipset msg */ - msg.hdr.Id = CONTROLVM_CHIPSET_INIT; + msg.hdr.id = CONTROLVM_CHIPSET_INIT; msg.cmd.init_chipset.bus_count = 23; msg.cmd.init_chipset.switch_count = 0; @@ -2406,11 +2410,11 @@ visorchipset_init(void) goto Away; } - memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DiagMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_ChipSetMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DelDumpMsgHdr, 0, sizeof(struct controlvm_message_header)); Putfile_buffer_list_pool = kmem_cache_create(Putfile_buffer_list_pool_name, @@ -2499,11 +2503,11 @@ visorchipset_exit(void) cleanup_controlvm_structures(); - memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DiagMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_ChipSetMsgHdr, 0, sizeof(struct controlvm_message_header)); - memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); + memset(&g_DelDumpMsgHdr, 0, sizeof(struct controlvm_message_header)); LOGINF("Channel %s (ControlVm) disconnected", visorchannel_id(ControlVm_channel, s)); -- GitLab From f91b926273134d9bfec32d6c4fcbd5188afd07dc Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:27 -0400 Subject: [PATCH 1378/9457] staging: unisys: refactor CONTROLVM_PACKET_DEVICE_CREATE Get rid of the typedef for CONTROLVM_PACKET_DEVICE_CREATE, instead using struct controlvm_packet_device_create. Fix CamelCase names and update all references to changed names. Clean up comments. busNo => bus_no devNo => dev_no channelAddr => channel_addr channelBytes => channel_bytes dataTypeGuid => data_type_uuid devInstGuid => dev_inst_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 29 +++++----- drivers/staging/unisys/uislib/uislib.c | 56 +++++++++---------- .../unisys/visorchipset/visorchipset_main.c | 18 +++--- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index abf6bc9f57d0..78c4b3366da4 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -215,20 +215,17 @@ struct controlvm_message_header { /* if non-zero, there is a payload to copy. */ }; -typedef struct _CONTROLVM_PACKET_DEVICE_CREATE { - u32 busNo; /**< bus # (0..n-1) from the msg receiver's - * perspective */ - - /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /**< bus-relative (0..n-1) device number */ - u64 channelAddr; /**< Guest physical address of the channel, which - * can be dereferenced by the receiver - * of this ControlVm command */ - u64 channelBytes; /**< specifies size of the channel in bytes */ - uuid_le dataTypeGuid;/**< specifies format of data in channel */ - uuid_le devInstGuid; /**< instance guid for the device */ - struct irq_info intr; /**< specifies interrupt information */ -} CONTROLVM_PACKET_DEVICE_CREATE; /* for CONTROLVM_DEVICE_CREATE */ +struct controlvm_packet_device_create { + u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */ + u32 dev_no; /* bus-relative (0..n-1) device number */ + u64 channel_addr; /* Guest physical address of the channel, which + * can be dereferenced by the receiver of this + * ControlVm command */ + u64 channel_bytes; /* specifies size of the channel in bytes */ + uuid_le data_type_uuid; /* specifies format of data in channel */ + uuid_le dev_inst_uuid; /* instance guid for the device */ + struct irq_info intr; /* specifies interrupt information */ +}; /* for CONTROLVM_DEVICE_CREATE */ typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { u32 busNo; /**< bus # (0..n-1) from the msg @@ -240,7 +237,7 @@ typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { struct controlvm_message_header Header; - CONTROLVM_PACKET_DEVICE_CREATE Packet; + struct controlvm_packet_device_create Packet; } CONTROLVM_MESSAGE_DEVICE_CREATE; /* total 128 bytes */ typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { @@ -285,7 +282,7 @@ struct controlvm_message_packet { * sendBusInterruptHandle is kept in CP. */ } configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ /* for CONTROLVM_DEVICE_CREATE */ - CONTROLVM_PACKET_DEVICE_CREATE create_device; + struct controlvm_packet_device_create create_device; struct { u32 bus_no; /* bus # (0..n-1) from the msg * receiver's perspective */ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 63f1d6ef6338..2b1ae7cead46 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -354,8 +354,8 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) u64 minSize = MIN_IO_CHANNEL_SIZE; struct req_handler_info *pReqHandler; - busNo = msg->cmd.create_device.busNo; - devNo = msg->cmd.create_device.devNo; + busNo = msg->cmd.create_device.bus_no; + devNo = msg->cmd.create_device.dev_no; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -368,9 +368,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) return CONTROLVM_RESP_ERROR_KMALLOC_FAILED; } - dev->channel_uuid = msg->cmd.create_device.dataTypeGuid; + dev->channel_uuid = msg->cmd.create_device.data_type_uuid; dev->intr = msg->cmd.create_device.intr; - dev->channel_addr = msg->cmd.create_device.channelAddr; + dev->channel_addr = msg->cmd.create_device.channel_addr; dev->bus_no = busNo; dev->dev_no = devNo; sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */ @@ -385,9 +385,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) * channel */ minSize = pReqHandler->min_channel_bytes; - if (minSize > msg->cmd.create_device.channelBytes) { + if (minSize > msg->cmd.create_device.channel_bytes) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx", - (ulong) msg->cmd.create_device.channelBytes, + (ulong) msg->cmd.create_device.channel_bytes, (ulong) minSize); POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); @@ -396,19 +396,19 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) } dev->chanptr = uislib_ioremap_cache(dev->channel_addr, - msg->cmd.create_device.channelBytes); + msg->cmd.create_device.channel_bytes); if (!dev->chanptr) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed", dev->channel_addr, - msg->cmd.create_device.channelBytes); + msg->cmd.create_device.channel_bytes); result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED; POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo, POSTCODE_SEVERITY_ERR); goto Away; } } - dev->instance_uuid = msg->cmd.create_device.devInstGuid; - dev->channel_bytes = msg->cmd.create_device.channelBytes; + dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid; + dev->channel_bytes = msg->cmd.create_device.channel_bytes; read_lock(&BusListLock); for (bus = BusListHead; bus; bus = bus->next) { @@ -945,15 +945,15 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, * need to be ioremap()ed */ msg.hdr.flags.test_message = 1; - msg.cmd.create_device.busNo = bus_no; - msg.cmd.create_device.devNo = dev_no; - msg.cmd.create_device.devInstGuid = inst_uuid; + msg.cmd.create_device.bus_no = bus_no; + msg.cmd.create_device.dev_no = dev_no; + msg.cmd.create_device.dev_inst_uuid = inst_uuid; if (intr) msg.cmd.create_device.intr = *intr; else memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); - msg.cmd.create_device.channelAddr = phys_chan_addr; + msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -961,8 +961,8 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.create_device.channelBytes = chan_bytes; - msg.cmd.create_device.dataTypeGuid = spar_vhba_channel_protocol_uuid; + msg.cmd.create_device.channel_bytes = chan_bytes; + msg.cmd.create_device.data_type_uuid = spar_vhba_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VHBA create_device failed.\n"); POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1004,15 +1004,15 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, * need to be ioremap()ed */ msg.hdr.flags.test_message = 1; - msg.cmd.create_device.busNo = bus_no; - msg.cmd.create_device.devNo = dev_no; - msg.cmd.create_device.devInstGuid = inst_uuid; + msg.cmd.create_device.bus_no = bus_no; + msg.cmd.create_device.dev_no = dev_no; + msg.cmd.create_device.dev_inst_uuid = inst_uuid; if (intr) msg.cmd.create_device.intr = *intr; else memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); - msg.cmd.create_device.channelAddr = phys_chan_addr; + msg.cmd.create_device.channel_addr = phys_chan_addr; if (chan_bytes < MIN_IO_CHANNEL_SIZE) { LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n", chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE); @@ -1020,8 +1020,8 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR); return 0; } - msg.cmd.create_device.channelBytes = chan_bytes; - msg.cmd.create_device.dataTypeGuid = spar_vnic_channel_protocol_uuid; + msg.cmd.create_device.channel_bytes = chan_bytes; + msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("VNIC create_device failed.\n"); POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no, @@ -1105,13 +1105,13 @@ uislib_client_add_vnic(u32 busNo) init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0); msg.hdr.flags.test_message = 1; - msg.cmd.create_device.busNo = busNo; - msg.cmd.create_device.devNo = devNo; - msg.cmd.create_device.devInstGuid = NULL_UUID_LE; + msg.cmd.create_device.bus_no = busNo; + msg.cmd.create_device.dev_no = devNo; + msg.cmd.create_device.dev_inst_uuid = NULL_UUID_LE; memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info)); - msg.cmd.create_device.channelAddr = PhysicalDataChan; - msg.cmd.create_device.channelBytes = MIN_IO_CHANNEL_SIZE; - msg.cmd.create_device.dataTypeGuid = spar_vnic_channel_protocol_uuid; + msg.cmd.create_device.channel_addr = PhysicalDataChan; + msg.cmd.create_device.channel_bytes = MIN_IO_CHANNEL_SIZE; + msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid; if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) { LOGERR("client create_device failed"); goto AwayCleanup; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index b7d53527c824..d7f644a5e980 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1229,8 +1229,8 @@ static void my_device_create(CONTROLVM_MESSAGE *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; - ulong busNo = cmd->create_device.busNo; - ulong devNo = cmd->create_device.devNo; + ulong busNo = cmd->create_device.bus_no; + ulong devNo = cmd->create_device.dev_no; VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; VISORCHIPSET_BUS_INFO *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1274,7 +1274,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) INIT_LIST_HEAD(&pDevInfo->entry); pDevInfo->busNo = busNo; pDevInfo->devNo = devNo; - pDevInfo->devInstGuid = cmd->create_device.devInstGuid; + pDevInfo->devInstGuid = cmd->create_device.dev_inst_uuid; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); @@ -1282,9 +1282,9 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) pDevInfo->chanInfo.addrType = ADDRTYPE_localTest; else pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical; - pDevInfo->chanInfo.channelAddr = cmd->create_device.channelAddr; - pDevInfo->chanInfo.nChannelBytes = cmd->create_device.channelBytes; - pDevInfo->chanInfo.channelTypeGuid = cmd->create_device.dataTypeGuid; + pDevInfo->chanInfo.channelAddr = cmd->create_device.channel_addr; + pDevInfo->chanInfo.nChannelBytes = cmd->create_device.channel_bytes; + pDevInfo->chanInfo.channelTypeGuid = cmd->create_device.data_type_uuid; pDevInfo->chanInfo.intr = cmd->create_device.intr; list_add(&pDevInfo->entry, &DevInfoList); POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo, @@ -1848,8 +1848,8 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) break; case CONTROLVM_DEVICE_CREATE: LOGINF("DEVICE_CREATE(%lu,%lu)", - (ulong) cmd->create_device.busNo, - (ulong) cmd->create_device.devNo); + (ulong) cmd->create_device.bus_no, + (ulong) cmd->create_device.dev_no); my_device_create(&inmsg); break; case CONTROLVM_DEVICE_CHANGESTATE: @@ -2130,7 +2130,7 @@ setup_crash_devices_work_queue(struct work_struct *work) } /* reuse create device message for storage device */ - if (localCrashCreateDevMsg.cmd.create_device.channelAddr != 0) + if (localCrashCreateDevMsg.cmd.create_device.channel_addr != 0) my_device_create(&localCrashCreateDevMsg); else { LOGERR("CrashCreateDevMsg is null, no dump will be taken"); -- GitLab From e6ad00bbe5053ad4eca363105726976968ed8415 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:28 -0400 Subject: [PATCH 1379/9457] staging: unisys: refactor CONTROLVM_PACKET_DEVICE_CONFIGURE Remove the typedef from CONTROLVM_PACKET_DEVICE_CONFIGURE, in favor of struct controlvm_packet_device_configure. Fix CamelCase names and update all references to modified names. busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 12 ++++++------ .../staging/unisys/visorchipset/visorchipset_main.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 78c4b3366da4..7a5524da56c1 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -227,13 +227,13 @@ struct controlvm_packet_device_create { struct irq_info intr; /* specifies interrupt information */ }; /* for CONTROLVM_DEVICE_CREATE */ -typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE { - u32 busNo; /**< bus # (0..n-1) from the msg +struct controlvm_packet_device_configure { + u32 bus_no; /**< bus # (0..n-1) from the msg * receiver's perspective */ /* Control uses header SegmentIndex field to access bus number... */ - u32 devNo; /**< bus-relative (0..n-1) device number */ -} CONTROLVM_PACKET_DEVICE_CONFIGURE; /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; /**< bus-relative (0..n-1) device number */ +} ; /* for CONTROLVM_DEVICE_CONFIGURE */ typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { struct controlvm_message_header Header; @@ -242,7 +242,7 @@ typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { struct controlvm_message_header Header; - CONTROLVM_PACKET_DEVICE_CONFIGURE Packet; + struct controlvm_packet_device_configure Packet; } CONTROLVM_MESSAGE_DEVICE_CONFIGURE; /* total 56 bytes */ /* This is the format for a message in any ControlVm queue. */ @@ -289,7 +289,7 @@ struct controlvm_message_packet { u32 dev_no; /* bus-relative (0..n-1) device # */ } destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ /* for CONTROLVM_DEVICE_CONFIGURE */ - CONTROLVM_PACKET_DEVICE_CONFIGURE configure_device; + struct controlvm_packet_device_configure configure_device; struct { u32 bus_no; /* bus # (0..n-1) from the msg * receiver's perspective */ diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index d7f644a5e980..753ea994f293 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1880,8 +1880,8 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) break; case CONTROLVM_DEVICE_CONFIGURE: LOGINF("DEVICE_CONFIGURE(%lu,%lu)", - (ulong) cmd->configure_device.busNo, - (ulong) cmd->configure_device.devNo); + (ulong) cmd->configure_device.bus_no, + (ulong) cmd->configure_device.dev_no); /* no op for now, just send a respond that we passed */ if (inmsg.hdr.flags.response_expected) controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS); -- GitLab From c36acb55798e703acde85ad581fe615548c29dff Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:29 -0400 Subject: [PATCH 1380/9457] staging: unisys: refactor CONTROLVM_MESSAGE_DEVICE_CREATE Remove the typedef from CONTROLVM_MESSAGE_DEVICE_CREATE, in favor of struct controlvm_message_device_create, fix CamelCase names, and update all references. Header => header Packet => packet Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 7a5524da56c1..120fa58fc0c9 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -235,10 +235,10 @@ struct controlvm_packet_device_configure { u32 dev_no; /**< bus-relative (0..n-1) device number */ } ; /* for CONTROLVM_DEVICE_CONFIGURE */ -typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE { - struct controlvm_message_header Header; - struct controlvm_packet_device_create Packet; -} CONTROLVM_MESSAGE_DEVICE_CREATE; /* total 128 bytes */ +struct controlvm_message_device_create { + struct controlvm_message_header header; + struct controlvm_packet_device_create packet; +}; /* total 128 bytes */ typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { struct controlvm_message_header Header; -- GitLab From f676054dd8ca5d700bf434c56cc221ede3e33b05 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:30 -0400 Subject: [PATCH 1381/9457] staging: unisys: refactor CONTROLVM_MESSAGE_DEVICE_CONFIGURE Remove the typedef from CONTROLVM_MESSAGE_DEVICE_CONFIGURE, replacing it with struct controlvm_message_device_configure. Fix CamelCase names and update all references. Header => header Packet => packet Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/controlvmchannel.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 120fa58fc0c9..6dc79d8fd795 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -240,10 +240,10 @@ struct controlvm_message_device_create { struct controlvm_packet_device_create packet; }; /* total 128 bytes */ -typedef struct _CONTROLVM_MESSAGE_DEVICE_CONFIGURE { - struct controlvm_message_header Header; - struct controlvm_packet_device_configure Packet; -} CONTROLVM_MESSAGE_DEVICE_CONFIGURE; /* total 56 bytes */ +struct controlvm_message_device_configure { + struct controlvm_message_header header; + struct controlvm_packet_device_configure packet; +}; /* total 56 bytes */ /* This is the format for a message in any ControlVm queue. */ struct controlvm_message_packet { -- GitLab From 3ab477012935626a66ad50bdae1fe7acf03be10a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:31 -0400 Subject: [PATCH 1382/9457] staging: unisys: remove typedef from CONTROLVM_MESSAGE Remove the typedef and use struct controlvm_message instead. Update all references. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 14 ++-- drivers/staging/unisys/uislib/uislib.c | 42 ++++++------ drivers/staging/unisys/visorchipset/testing.h | 5 +- .../unisys/visorchipset/visorchipset.h | 7 +- .../unisys/visorchipset/visorchipset_main.c | 65 ++++++++++--------- 5 files changed, 68 insertions(+), 65 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 6dc79d8fd795..8bc2e174ddcc 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -337,10 +337,10 @@ struct controlvm_message_packet { }; /* All messages in any ControlVm queue have this layout. */ -typedef struct _CONTROLVM_MESSAGE { +struct controlvm_message { struct controlvm_message_header hdr; struct controlvm_message_packet cmd; -} CONTROLVM_MESSAGE; +}; typedef struct _DEVICE_MAP { GUEST_PHYSICAL_ADDRESS DeviceChannelAddress; @@ -447,19 +447,19 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { * Control events */ /* Request fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE RequestMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message RequestMsg[CONTROLVM_MESSAGE_MAX]; /* Response fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE ResponseMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message ResponseMsg[CONTROLVM_MESSAGE_MAX]; /* Event fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE EventMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message EventMsg[CONTROLVM_MESSAGE_MAX]; /* Ack fixed-size message pool - does not include payload */ - CONTROLVM_MESSAGE EventAckMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message EventAckMsg[CONTROLVM_MESSAGE_MAX]; /* Message stored during IOVM creation to be reused after crash */ - CONTROLVM_MESSAGE SavedCrashMsg[CONTROLVM_CRASHMSG_MAX]; + struct controlvm_message SavedCrashMsg[CONTROLVM_CRASHMSG_MAX]; } ULTRA_CONTROLVM_CHANNEL_PROTOCOL; /* Offsets for VM channel attributes... */ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 2b1ae7cead46..513e00d2f979 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -121,9 +121,9 @@ static const struct file_operations debugfs_info_fops = { }; static void -init_msg_header(CONTROLVM_MESSAGE *msg, u32 id, uint rsp, uint svr) +init_msg_header(struct controlvm_message *msg, u32 id, uint rsp, uint svr) { - memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); + memset(msg, 0, sizeof(struct controlvm_message)); msg->hdr.id = id; msg->hdr.flags.response_expected = rsp; msg->hdr.flags.server = svr; @@ -154,7 +154,7 @@ init_vbus_channel(u64 channelAddr, u32 channelBytes) } static int -create_bus(CONTROLVM_MESSAGE *msg, char *buf) +create_bus(struct controlvm_message *msg, char *buf) { u32 busNo, deviceCount; struct bus_info *tmp, *bus; @@ -272,7 +272,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) } static int -destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) +destroy_bus(struct controlvm_message *msg, char *buf) { int i; struct bus_info *bus, *prev = NULL; @@ -345,7 +345,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf) } static int -create_device(CONTROLVM_MESSAGE *msg, char *buf) +create_device(struct controlvm_message *msg, char *buf) { struct device_info *dev; struct bus_info *bus; @@ -544,7 +544,7 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf) } static int -pause_device(CONTROLVM_MESSAGE *msg) +pause_device(struct controlvm_message *msg) { u32 busNo, devNo; struct bus_info *bus; @@ -612,7 +612,7 @@ pause_device(CONTROLVM_MESSAGE *msg) } static int -resume_device(CONTROLVM_MESSAGE *msg) +resume_device(struct controlvm_message *msg) { u32 busNo, devNo; struct bus_info *bus; @@ -681,7 +681,7 @@ resume_device(CONTROLVM_MESSAGE *msg) } static int -destroy_device(CONTROLVM_MESSAGE *msg, char *buf) +destroy_device(struct controlvm_message *msg, char *buf) { u32 busNo, devNo; struct bus_info *bus; @@ -769,7 +769,7 @@ destroy_device(CONTROLVM_MESSAGE *msg, char *buf) } static int -init_chipset(CONTROLVM_MESSAGE *msg, char *buf) +init_chipset(struct controlvm_message *msg, char *buf) { POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); @@ -796,7 +796,7 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf) static int delete_bus_glue(u32 busNo) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0); msg.cmd.destroy_bus.bus_no = busNo; @@ -810,7 +810,7 @@ delete_bus_glue(u32 busNo) static int delete_device_glue(u32 busNo, u32 devNo) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); msg.cmd.destroy_device.bus_no = busNo; @@ -827,7 +827,7 @@ int uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid, u64 channel_addr, ulong n_channel_bytes) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; LOGINF("enter busNo=0x%x\n", bus_no); /* step 0: init the chipset */ @@ -885,7 +885,7 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus); int uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); @@ -905,7 +905,7 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba); int uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); @@ -929,7 +929,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no, int is_test_addr, uuid_le inst_uuid, struct irq_info *intr) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - @@ -988,7 +988,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no, int is_test_addr, uuid_le inst_uuid, struct irq_info *intr) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no); /* chipset init'ed with bus bus has been previously created - @@ -1038,7 +1038,7 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic); int uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); @@ -1058,7 +1058,7 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic); int uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no) { - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; int rc; init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0); @@ -1089,7 +1089,7 @@ uislib_client_add_vnic(u32 busNo) BOOL busCreated = FALSE; int devNo = 0; /* Default to 0, since only one device * will be created for this bus... */ - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0); msg.hdr.flags.test_message = 1; @@ -1137,7 +1137,7 @@ uislib_client_delete_vnic(u32 busNo) { int devNo = 0; /* Default to 0, since only one device * will be created for this bus... */ - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0); msg.hdr.flags.test_message = 1; @@ -1563,7 +1563,7 @@ uislib_mod_init(void) LOGINF("sizeof(uiscmdrsp_net):%lu\n", (ulong) sizeof(struct uiscmdrsp_net)); LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n", - (ulong) sizeof(CONTROLVM_MESSAGE)); + (ulong) sizeof(struct controlvm_message)); LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n", (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL)); LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", diff --git a/drivers/staging/unisys/visorchipset/testing.h b/drivers/staging/unisys/visorchipset/testing.h index 015d502cbb16..573aa8b5ba6a 100644 --- a/drivers/staging/unisys/visorchipset/testing.h +++ b/drivers/staging/unisys/visorchipset/testing.h @@ -23,8 +23,9 @@ #include "globals.h" #include "controlvmchannel.h" -void test_produce_test_message(CONTROLVM_MESSAGE *msg, int isLocalTestAddr); -BOOL test_consume_test_message(CONTROLVM_MESSAGE *msg); +void test_produce_test_message(struct controlvm_message *msg, + int isLocalTestAddr); +BOOL test_consume_test_message(struct controlvm_message *msg); void test_manufacture_vnic_client_add(void *p); void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr); void test_manufacture_preamble_messages(void); diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 966b1dd3e669..feae36885376 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -267,7 +267,7 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, struct ultra_vbus_deviceinfo *driverInfo); -typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (CONTROLVM_MESSAGE *msg, +typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response); @@ -285,9 +285,10 @@ BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); int visorchipset_chipset_notready(void); -void visorchipset_controlvm_respond_reportEvent(CONTROLVM_MESSAGE *msg, +void visorchipset_controlvm_respond_reportEvent(struct controlvm_message *msg, void *payload); -void visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type); +void visorchipset_save_message(struct controlvm_message *msg, + CRASH_OBJ_TYPE type); void *visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, char *fn, int ln); void visorchipset_cache_free(struct kmem_cache *pool, void *p, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 753ea994f293..e94e13422b6d 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -72,7 +72,7 @@ static struct workqueue_struct *Periodic_controlvm_workqueue; static DEFINE_SEMAPHORE(NotifierLock); typedef struct { - CONTROLVM_MESSAGE message; + struct controlvm_message message; unsigned int crc; } MESSAGE_ENVELOPE; @@ -136,7 +136,7 @@ static LIVEDUMP_INFO LiveDump_info; * this scenario, we simply stash the controlvm message, then attempt to * process it again the next time controlvm_periodic_work() runs. */ -static CONTROLVM_MESSAGE ControlVm_Pending_Msg; +static struct controlvm_message ControlVm_Pending_Msg; static BOOL ControlVm_Pending_Msg_Valid = FALSE; /* Pool of struct putfile_buffer_entry, for keeping track of pending (incoming) @@ -220,7 +220,7 @@ struct parahotplug_request { struct list_head list; int id; unsigned long expiration; - CONTROLVM_MESSAGE msg; + struct controlvm_message msg; }; static LIST_HEAD(Parahotplug_request_list); @@ -654,7 +654,7 @@ cleanup_controlvm_structures(void) } static void -chipset_init(CONTROLVM_MESSAGE *inmsg) +chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum ultra_chipset_feature features = 0; @@ -687,10 +687,10 @@ chipset_init(CONTROLVM_MESSAGE *inmsg) } static void -controlvm_init_response(CONTROLVM_MESSAGE *msg, +controlvm_init_response(struct controlvm_message *msg, struct controlvm_message_header *msgHdr, int response) { - memset(msg, 0, sizeof(CONTROLVM_MESSAGE)); + memset(msg, 0, sizeof(struct controlvm_message)); memcpy(&msg->hdr, msgHdr, sizeof(struct controlvm_message_header)); msg->hdr.payload_bytes = 0; msg->hdr.payload_vm_offset = 0; @@ -704,7 +704,7 @@ controlvm_init_response(CONTROLVM_MESSAGE *msg, static void controlvm_respond(struct controlvm_message_header *msgHdr, int response) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); /* For DiagPool channel DEVICE_CHANGESTATE, we need to send @@ -732,7 +732,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msgHdr, int response, enum ultra_chipset_feature features) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); outmsg.cmd.init_chipset.features = features; @@ -747,7 +747,7 @@ static void controlvm_respond_physdev_changestate( struct controlvm_message_header *msgHdr, int response, struct spar_segment_state state) { - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; controlvm_init_response(&outmsg, msgHdr, response); outmsg.cmd.device_change_state.state = state; @@ -760,7 +760,7 @@ static void controlvm_respond_physdev_changestate( } void -visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) +visorchipset_save_message(struct controlvm_message *msg, CRASH_OBJ_TYPE type) { u32 localSavedCrashMsgOffset; u16 localSavedCrashMsgCount; @@ -799,7 +799,8 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) if (type == CRASH_bus) { if (visorchannel_write(ControlVm_channel, localSavedCrashMsgOffset, - msg, sizeof(CONTROLVM_MESSAGE)) < 0) { + msg, + sizeof(struct controlvm_message)) < 0) { LOGERR("SAVE_MSG_BUS_FAILURE: Failed to write CrashCreateBusMsg!"); POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -808,8 +809,8 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type) } else { if (visorchannel_write(ControlVm_channel, localSavedCrashMsgOffset + - sizeof(CONTROLVM_MESSAGE), msg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message), msg, + sizeof(struct controlvm_message)) < 0) { LOGERR("SAVE_MSG_DEV_FAILURE: Failed to write CrashCreateDevMsg!"); POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -864,7 +865,7 @@ device_changestate_responder(enum controlvm_id cmdId, struct spar_segment_state responseState) { VISORCHIPSET_DEVICE_INFO *p = NULL; - CONTROLVM_MESSAGE outmsg; + struct controlvm_message outmsg; p = finddevice(&DevInfoList, busNo, devNo); if (!p) { @@ -1095,7 +1096,7 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, } static void -bus_create(CONTROLVM_MESSAGE *inmsg) +bus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->create_bus.bus_no; @@ -1149,7 +1150,7 @@ bus_create(CONTROLVM_MESSAGE *inmsg) } static void -bus_destroy(CONTROLVM_MESSAGE *inmsg) +bus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->destroy_bus.bus_no; @@ -1175,7 +1176,7 @@ bus_destroy(CONTROLVM_MESSAGE *inmsg) } static void -bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) +bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->configure_bus.bus_no; @@ -1226,7 +1227,7 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx) } static void -my_device_create(CONTROLVM_MESSAGE *inmsg) +my_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->create_device.bus_no; @@ -1304,7 +1305,7 @@ my_device_create(CONTROLVM_MESSAGE *inmsg) } static void -my_device_changestate(CONTROLVM_MESSAGE *inmsg) +my_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->device_change_state.bus_no; @@ -1338,7 +1339,7 @@ my_device_changestate(CONTROLVM_MESSAGE *inmsg) } static void -my_device_destroy(CONTROLVM_MESSAGE *inmsg) +my_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->destroy_device.bus_no; @@ -1536,7 +1537,7 @@ chipset_notready(struct controlvm_message_header *msgHdr) * CONTROLVM_QUEUE_EVENT queue in the controlvm channel. */ static BOOL -read_controlvm_event(CONTROLVM_MESSAGE *msg) +read_controlvm_event(struct controlvm_message *msg) { if (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_EVENT, msg)) { @@ -1593,7 +1594,7 @@ parahotplug_next_expiration(void) * CONTROLVM_MESSAGE that we can stick on a list */ static struct parahotplug_request * -parahotplug_request_create(CONTROLVM_MESSAGE *msg) +parahotplug_request_create(struct controlvm_message *msg) { struct parahotplug_request *req = kmalloc(sizeof(struct parahotplug_request), @@ -1723,7 +1724,7 @@ parahotplug_request_complete(int id, u16 active) * Enables or disables a PCI device by kicking off a udev script */ static void -parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) +parahotplug_process_message(struct controlvm_message *inmsg) { struct parahotplug_request *req; @@ -1775,14 +1776,14 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg) * either successfully or with an error. */ static BOOL -handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr) +handle_command(struct controlvm_message inmsg, HOSTADDRESS channel_addr) { struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parametersAddr = 0; u32 parametersBytes = 0; PARSER_CONTEXT *parser_ctx = NULL; BOOL isLocalAddr = FALSE; - CONTROLVM_MESSAGE ackmsg; + struct controlvm_message ackmsg; /* create parsing context if necessary */ isLocalAddr = (inmsg.hdr.flags.test_message == 1); @@ -1931,7 +1932,7 @@ static void controlvm_periodic_work(struct work_struct *work) { VISORCHIPSET_CHANNEL_INFO chanInfo; - CONTROLVM_MESSAGE inmsg; + struct controlvm_message inmsg; BOOL gotACommand = FALSE; BOOL handle_command_failed = FALSE; static u64 Poll_Count; @@ -2040,9 +2041,9 @@ static void setup_crash_devices_work_queue(struct work_struct *work) { - CONTROLVM_MESSAGE localCrashCreateBusMsg; - CONTROLVM_MESSAGE localCrashCreateDevMsg; - CONTROLVM_MESSAGE msg; + struct controlvm_message localCrashCreateBusMsg; + struct controlvm_message localCrashCreateDevMsg; + struct controlvm_message msg; u32 localSavedCrashMsgOffset; u16 localSavedCrashMsgCount; @@ -2100,7 +2101,7 @@ setup_crash_devices_work_queue(struct work_struct *work) if (visorchannel_read(ControlVm_channel, localSavedCrashMsgOffset, &localCrashCreateBusMsg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message)) < 0) { LOGERR("CRASH_DEV_RD_BUS_FAIULRE: Failed to read CrashCreateBusMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC, POSTCODE_SEVERITY_ERR); @@ -2110,9 +2111,9 @@ setup_crash_devices_work_queue(struct work_struct *work) /* read create device message for storage device */ if (visorchannel_read(ControlVm_channel, localSavedCrashMsgOffset + - sizeof(CONTROLVM_MESSAGE), + sizeof(struct controlvm_message), &localCrashCreateDevMsg, - sizeof(CONTROLVM_MESSAGE)) < 0) { + sizeof(struct controlvm_message)) < 0) { LOGERR("CRASH_DEV_RD_DEV_FAIULRE: Failed to read CrashCreateDevMsg!"); POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC, POSTCODE_SEVERITY_ERR); -- GitLab From a348e0dcca13bd2823629622bc7fc9d0319e5e72 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:32 -0400 Subject: [PATCH 1383/9457] staging: unisys: refactor DEVICE_MAP Get rid of the typedef for DEVICE_MAP and use struct device_map instead. Fix CamelCase names. DeviceChannelSize => device_channel_size CA_Index => ca_index Reserved => reserved Reserved2 => reserved2 Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 8bc2e174ddcc..5aff65dd9d04 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -342,20 +342,20 @@ struct controlvm_message { struct controlvm_message_packet cmd; }; -typedef struct _DEVICE_MAP { - GUEST_PHYSICAL_ADDRESS DeviceChannelAddress; - u64 DeviceChannelSize; - u32 CA_Index; - u32 Reserved; /* natural alignment */ - u64 Reserved2; /* Align structure on 32-byte boundary */ -} DEVICE_MAP; +struct device_map { + GUEST_PHYSICAL_ADDRESS device_channel_address; + u64 device_channel_size; + u32 ca_index; + u32 reserved; /* natural alignment */ + u64 reserved2; /* Align structure on 32-byte boundary */ +}; typedef struct _GUEST_DEVICES { - DEVICE_MAP VideoChannel; - DEVICE_MAP KeyboardChannel; - DEVICE_MAP NetworkChannel; - DEVICE_MAP StorageChannel; - DEVICE_MAP ConsoleChannel; + struct device_map VideoChannel; + struct device_map KeyboardChannel; + struct device_map NetworkChannel; + struct device_map StorageChannel; + struct device_map ConsoleChannel; u32 PartitionIndex; u32 Pad; } GUEST_DEVICES; -- GitLab From 6f5a5b7b501e38fa6cc6faae39a19b819f712a11 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:33 -0400 Subject: [PATCH 1384/9457] staging: unisys: refactor GUEST_DEVICES Remove the typedef from GUEST_DEVICES and switch to struct guest_devices. Fix CamelCase names and update all references to renamed members. VideoChannel => video_channel KeyboardChannel => keyboard_channel NetworkChannel => network_channel StorageChannel => storage_channel ConsoleChannel => console_channel PartitionIndex => partition_index Pad => pad Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 5aff65dd9d04..363967a55267 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -350,15 +350,15 @@ struct device_map { u64 reserved2; /* Align structure on 32-byte boundary */ }; -typedef struct _GUEST_DEVICES { - struct device_map VideoChannel; - struct device_map KeyboardChannel; - struct device_map NetworkChannel; - struct device_map StorageChannel; - struct device_map ConsoleChannel; - u32 PartitionIndex; - u32 Pad; -} GUEST_DEVICES; +struct guest_devices { + struct device_map video_channel; + struct device_map keyboard_channel; + struct device_map network_channel; + struct device_map storage_channel; + struct device_map console_channel; + u32 partition_index; + u32 pad; +}; typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { struct channel_header Header; @@ -394,7 +394,7 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { GUEST_PHYSICAL_ADDRESS gpPhysicalSmbiosTable; /* guest phys addr of * SMBIOS table */ /* ULTRA_MAX_GUESTS_PER_SERVICE */ - GUEST_DEVICES gpObsoleteGuestDevices[16]; + struct guest_devices gpObsoleteGuestDevices[16]; /* guest physical address of EFI firmware image base */ GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareImageBase; -- GitLab From d19642f656c88e57a7e8b68730126cde591fe217 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:34 -0400 Subject: [PATCH 1385/9457] staging: unisys: refactor SPAR_CONTROLVM_CHANNEL_PROTOCOL Get rid of the typedef for SPAR_CONTROLVM_CHANNEL_PROTOCOL and replace it with struct spar_controlvm_channel_protocol. Fix CamelCase members of the structure and update all references to changed names. Header => header gpControlVm => gp_control_vm gpPartitionTables => gp_partition_tables gpDiagGuest => gp_diag_guest gpBootRomDisk => gp_boot_romdisk gpBootRamDisk => gp_boot_ramdisk gpAcpiTable => gp_acpi_table gpControlChannel => gp_control_channel gpdiagRomDisk => gp_diag_romdisk gpNvram => gp_nvram RequestPayloadOffset => request_payload_offset EventPayloadOffset => event_payload_offset RequestPayloadBytes => request_payload_bytes EventPayloadBytes => event_payload_bytes ControlChannelBytes => control_channel_bytes NvramChannelBytes => nvram_channel_bytes MessageBytes => message_bytes MessageCount => message_count gpSmbiosTable => gp_smbios_table gpPhysicalSmbiosTable => gp_physical_smbios_table gpobsoleteGuestDevices => gp_obsolete_guest_devices VirtualGuestFirmwareImageBase => virtual_guest_firmware_image_base VirtualGuestFirmwareEntryPoint => virtual_guest_firmware_entry_point VirtualGuestFirmwareImageSize => virtual_guest_firmware_image_size VirtualGuestFirmwareBootBase => virtual_guest_firmware_boot_base VirtualGuestImageBase => virtual_guest_image_base VirtualGuestImageSize => virtual_guest_image_size PrototypeControlChannelOffset => prototype_control_channel_offset VirtualGuestPartitionHandle => virtual_guest_partition_handle RestoreAction => restore_action DumpAction => dump_action NvramFailCount => nvram_fail_count SavedCrashMsgCount => saved_crash_message_count SavedCrashMsgOffset => saved_crash_message_offset InstallationError => installation_error InstallationTextId => installation_text_id InstallationRemainingSteps => installation_remaining_steps ToolAction => tool_action Reserved => reserved EfiSparIndication => efi_spar_ind EfiSparIndicationSupported => efi_spar_ind_supported SPReserved => sp_reserved Reserved2 => reserved2 RequestQueue => request_queue ResponseQueue => response_queue EventQueue => event_queue EventAckQueue => event_ack_queue RequestMsg => request_msg ResponseMsg => response_msg EventMsg => event_msg EventAckMsg => event_ack_msg SavedCrashMsg => saved_crash_msg Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 156 +++++++++--------- drivers/staging/unisys/uislib/uislib.c | 4 +- drivers/staging/unisys/visorchipset/file.c | 6 +- .../unisys/visorchipset/visorchipset_main.c | 62 +++---- 4 files changed, 114 insertions(+), 114 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 363967a55267..c949cd47cc82 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -47,11 +47,11 @@ static const uuid_le spar_controlvm_channel_protocol_uuid = #define SPAR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ spar_check_channel_client(ch, \ - spar_controlvm_channel_protocol_uuid, \ - "controlvm", \ - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE) + spar_controlvm_channel_protocol_uuid, \ + "controlvm", \ + sizeof(struct spar_controlvm_channel_protocol), \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \ + ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE) #define MY_DEVICE_INDEX 0 #define MAX_MACDATA_LEN 8 /* number of bytes for MAC address in config packet */ @@ -360,127 +360,127 @@ struct guest_devices { u32 pad; }; -typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL { - struct channel_header Header; - GUEST_PHYSICAL_ADDRESS gpControlVm; /* guest physical address of +struct spar_controlvm_channel_protocol { + struct channel_header header; + GUEST_PHYSICAL_ADDRESS gp_controlvm; /* guest physical address of * this channel */ - GUEST_PHYSICAL_ADDRESS gpPartitionTables; /* guest physical address of - * partition tables */ - GUEST_PHYSICAL_ADDRESS gpDiagGuest; /* guest physical address of + GUEST_PHYSICAL_ADDRESS gp_partition_tables;/* guest physical address of + * partition tables */ + GUEST_PHYSICAL_ADDRESS gp_diag_guest; /* guest physical address of * diagnostic channel */ - GUEST_PHYSICAL_ADDRESS gpBootRomDisk; /* guest phys addr of (read + GUEST_PHYSICAL_ADDRESS gp_boot_romdisk;/* guest phys addr of (read * only) Boot ROM disk */ - GUEST_PHYSICAL_ADDRESS gpBootRamDisk; /* guest phys addr of writable + GUEST_PHYSICAL_ADDRESS gp_boot_ramdisk;/* guest phys addr of writable * Boot RAM disk */ - GUEST_PHYSICAL_ADDRESS gpAcpiTable; /* guest phys addr of acpi + GUEST_PHYSICAL_ADDRESS gp_acpi_table; /* guest phys addr of acpi * table */ - GUEST_PHYSICAL_ADDRESS gpControlChannel; /* guest phys addr of control - * channel */ - GUEST_PHYSICAL_ADDRESS gpDiagRomDisk; /* guest phys addr of diagnostic + GUEST_PHYSICAL_ADDRESS gp_control_channel;/* guest phys addr of control + * channel */ + GUEST_PHYSICAL_ADDRESS gp_diag_romdisk;/* guest phys addr of diagnostic * ROM disk */ - GUEST_PHYSICAL_ADDRESS gpNvram; /* guest phys addr of NVRAM + GUEST_PHYSICAL_ADDRESS gp_nvram; /* guest phys addr of NVRAM * channel */ - u64 RequestPayloadOffset; /* Offset to request payload area */ - u64 EventPayloadOffset; /* Offset to event payload area */ - u32 RequestPayloadBytes; /* Bytes available in request payload + u64 request_payload_offset; /* Offset to request payload area */ + u64 event_payload_offset; /* Offset to event payload area */ + u32 request_payload_bytes; /* Bytes available in request payload * area */ - u32 EventPayloadBytes; /* Bytes available in event payload area */ - u32 ControlChannelBytes; - u32 NvramChannelBytes; /* Bytes in PartitionNvram segment */ - u32 MessageBytes; /* sizeof(CONTROLVM_MESSAGE) */ - u32 MessageCount; /* CONTROLVM_MESSAGE_MAX */ - GUEST_PHYSICAL_ADDRESS gpSmbiosTable; /* guest phys addr of SMBIOS + u32 event_payload_bytes;/* Bytes available in event payload area */ + u32 control_channel_bytes; + u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */ + u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */ + u32 message_count; /* CONTROLVM_MESSAGE_MAX */ + GUEST_PHYSICAL_ADDRESS gp_smbios_table;/* guest phys addr of SMBIOS * tables */ - GUEST_PHYSICAL_ADDRESS gpPhysicalSmbiosTable; /* guest phys addr of - * SMBIOS table */ + GUEST_PHYSICAL_ADDRESS gp_physical_smbios_table;/* guest phys addr of + * SMBIOS table */ /* ULTRA_MAX_GUESTS_PER_SERVICE */ - struct guest_devices gpObsoleteGuestDevices[16]; + struct guest_devices gp_obsolete_guest_devices[16]; /* guest physical address of EFI firmware image base */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareImageBase; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_image_base; /* guest physical address of EFI firmware entry point */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareEntryPoint; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_entry_point; /* guest EFI firmware image size */ - u64 VirtualGuestFirmwareImageSize; + u64 virtual_guest_firmware_image_size; /* GPA = 1MB where EFI firmware image is copied to */ - GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareBootBase; - GUEST_PHYSICAL_ADDRESS VirtualGuestImageBase; - GUEST_PHYSICAL_ADDRESS VirtualGuestImageSize; - u64 PrototypeControlChannelOffset; - GUEST_PHYSICAL_ADDRESS VirtualGuestPartitionHandle; + GUEST_PHYSICAL_ADDRESS virtual_guest_firmware_boot_base; + GUEST_PHYSICAL_ADDRESS virtual_guest_image_base; + GUEST_PHYSICAL_ADDRESS virtual_guest_image_size; + u64 prototype_control_channel_offset; + GUEST_PHYSICAL_ADDRESS virtual_guest_partition_handle; - u16 RestoreAction; /* Restore Action field to restore the guest + u16 restore_action; /* Restore Action field to restore the guest * partition */ - u16 DumpAction; /* For Windows guests it shows if the visordisk + u16 dump_action; /* For Windows guests it shows if the visordisk * is running in dump mode */ - u16 NvramFailCount; - u16 SavedCrashMsgCount; /* = CONTROLVM_CRASHMSG_MAX */ - u32 SavedCrashMsgOffset; /* Offset to request payload area needed + u16 nvram_fail_count; + u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */ + u32 saved_crash_message_offset; /* Offset to request payload area needed * for crash dump */ - u32 InstallationError; /* Type of error encountered during + u32 installation_error; /* Type of error encountered during * installation */ - u32 InstallationTextId; /* Id of string to display */ - u16 InstallationRemainingSteps; /* Number of remaining installation - * steps (for progress bars) */ - u8 ToolAction; /* ULTRA_TOOL_ACTIONS Installation Action + u32 installation_text_id; /* Id of string to display */ + u16 installation_remaining_steps;/* Number of remaining installation + * steps (for progress bars) */ + u8 tool_action; /* ULTRA_TOOL_ACTIONS Installation Action * field */ - u8 Reserved; /* alignment */ - struct efi_spar_indication EfiSparIndication; - struct efi_spar_indication EfiSparIndicationSupported; - u32 SPReserved; - u8 Reserved2[28]; /* Force signals to begin on 128-byte cache + u8 reserved; /* alignment */ + struct efi_spar_indication efi_spar_ind; + struct efi_spar_indication efi_spar_ind_supported; + u32 sp_reserved; + u8 reserved2[28]; /* Force signals to begin on 128-byte cache * line */ - struct signal_queue_header RequestQueue;/* Service or guest partition - * uses this queue to send - * requests to Control */ - struct signal_queue_header ResponseQueue;/* Control uses this queue to - * respond to service or guest - * partition requests */ - struct signal_queue_header EventQueue; /* Control uses this queue to + struct signal_queue_header request_queue;/* Service or guest partition + * uses this queue to send + * requests to Control */ + struct signal_queue_header response_queue;/* Control uses this queue to + * respond to service or guest + * partition requests */ + struct signal_queue_header event_queue; /* Control uses this queue to * send events to service or * guest partition */ - struct signal_queue_header EventAckQueue;/* Service or guest partition - * uses this queue to ack - * Control events */ + struct signal_queue_header event_ack_queue;/* Service or guest partition + * uses this queue to ack + * Control events */ /* Request fixed-size message pool - does not include payload */ - struct controlvm_message RequestMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; /* Response fixed-size message pool - does not include payload */ - struct controlvm_message ResponseMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; /* Event fixed-size message pool - does not include payload */ - struct controlvm_message EventMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; /* Ack fixed-size message pool - does not include payload */ - struct controlvm_message EventAckMsg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; /* Message stored during IOVM creation to be reused after crash */ - struct controlvm_message SavedCrashMsg[CONTROLVM_CRASHMSG_MAX]; -} ULTRA_CONTROLVM_CHANNEL_PROTOCOL; + struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; +}; /* Offsets for VM channel attributes... */ #define VM_CH_REQ_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestQueue) + offsetof(struct spar_controlvm_channel_protocol, request_queue) #define VM_CH_RESP_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseQueue) + offsetof(struct spar_controlvm_channel_protocol, response_queue) #define VM_CH_EVENT_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventQueue) + offsetof(struct spar_controlvm_channel_protocol, event_queue) #define VM_CH_ACK_QUEUE_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckQueue) + offsetof(struct spar_controlvm_channel_protocol, event_ack_queue) #define VM_CH_REQ_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, RequestMsg) + offsetof(struct spar_controlvm_channel_protocol, request_msg) #define VM_CH_RESP_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ResponseMsg) + offsetof(struct spar_controlvm_channel_protocol, response_msg) #define VM_CH_EVENT_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventMsg) + offsetof(struct spar_controlvm_channel_protocol, event_msg) #define VM_CH_ACK_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EventAckMsg) + offsetof(struct spar_controlvm_channel_protocol, event_ack_msg) #define VM_CH_CRASH_MSG_OFFSET \ - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, SavedCrashMsg) + offsetof(struct spar_controlvm_channel_protocol, saved_crash_msg) /* The following header will be located at the beginning of PayloadVmOffset for * various ControlVm commands. The receiver of a ControlVm command with a diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 513e00d2f979..b8db2700a1df 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1564,8 +1564,8 @@ uislib_mod_init(void) (ulong) sizeof(struct uiscmdrsp_net)); LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n", (ulong) sizeof(struct controlvm_message)); - LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n", - (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL)); + LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n", + (ulong) sizeof(struct spar_controlvm_channel_protocol)); LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", (ulong) sizeof(struct channel_header)); LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n", diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index 3321764069de..373fa36b7119 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -155,9 +155,9 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma) return -ENXIO; } visorchannel_read(*PControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - gpControlChannel), &addr, - sizeof(addr)); + offsetof(struct spar_controlvm_channel_protocol, + gp_control_channel), + &addr, sizeof(addr)); if (addr == 0) { ERRDRV("%s control channel address is 0", __func__); return -ENXIO; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index e94e13422b6d..392e046be359 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -360,8 +360,8 @@ static ssize_t toolaction_show(struct device *dev, u8 toolAction; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - ToolAction), &toolAction, sizeof(u8)); + offsetof(struct spar_controlvm_channel_protocol, + tool_action), &toolAction, sizeof(u8)); return scnprintf(buf, PAGE_SIZE, "%u\n", toolAction); } @@ -376,7 +376,7 @@ static ssize_t toolaction_store(struct device *dev, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ToolAction), + offsetof(struct spar_controlvm_channel_protocol, tool_action), &toolAction, sizeof(u8)); if (ret) @@ -391,8 +391,8 @@ static ssize_t boottotool_show(struct device *dev, struct efi_spar_indication efiSparIndication; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - EfiSparIndication), &efiSparIndication, + offsetof(struct spar_controlvm_channel_protocol, + efi_spar_ind), &efiSparIndication, sizeof(struct efi_spar_indication)); return scnprintf(buf, PAGE_SIZE, "%u\n", efiSparIndication.boot_to_tool); @@ -410,8 +410,8 @@ static ssize_t boottotool_store(struct device *dev, efiSparIndication.boot_to_tool = val; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - EfiSparIndication), + offsetof(struct spar_controlvm_channel_protocol, + efi_spar_ind), &(efiSparIndication), sizeof(struct efi_spar_indication)); @@ -426,7 +426,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, u32 error; visorchannel_read(ControlVm_channel, offsetof( - ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationError), + struct spar_controlvm_channel_protocol, installation_error), &error, sizeof(u32)); return scnprintf(buf, PAGE_SIZE, "%i\n", error); } @@ -441,8 +441,8 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationError), + offsetof(struct spar_controlvm_channel_protocol, + installation_error), &error, sizeof(u32)); if (ret) return ret; @@ -455,7 +455,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, u32 textId; visorchannel_read(ControlVm_channel, offsetof( - ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationTextId), + struct spar_controlvm_channel_protocol, installation_text_id), &textId, sizeof(u32)); return scnprintf(buf, PAGE_SIZE, "%i\n", textId); } @@ -470,8 +470,8 @@ static ssize_t textid_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationTextId), + offsetof(struct spar_controlvm_channel_protocol, + installation_text_id), &textId, sizeof(u32)); if (ret) return ret; @@ -485,8 +485,8 @@ static ssize_t remaining_steps_show(struct device *dev, u16 remainingSteps; visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationRemainingSteps), + offsetof(struct spar_controlvm_channel_protocol, + installation_remaining_steps), &remainingSteps, sizeof(u16)); return scnprintf(buf, PAGE_SIZE, "%hu\n", remainingSteps); @@ -502,8 +502,8 @@ static ssize_t remaining_steps_store(struct device *dev, return -EINVAL; ret = visorchannel_write(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - InstallationRemainingSteps), + offsetof(struct spar_controlvm_channel_protocol, + installation_remaining_steps), &remainingSteps, sizeof(u16)); if (ret) return ret; @@ -767,8 +767,8 @@ visorchipset_save_message(struct controlvm_message *msg, CRASH_OBJ_TYPE type) /* get saved message count */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgCount), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -787,8 +787,8 @@ visorchipset_save_message(struct controlvm_message *msg, CRASH_OBJ_TYPE type) /* get saved crash message offset */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgOffset), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -1389,7 +1389,7 @@ initialize_controlvm_payload_info(HOSTADDRESS phys_addr, u64 offset, u32 bytes, } memset(info, 0, sizeof(CONTROLVM_PAYLOAD_INFO)); if ((offset == 0) || (bytes == 0)) { - LOGERR("CONTROLVM_PAYLOAD_INIT Failed: RequestPayloadOffset=%llu RequestPayloadBytes=%llu!", + LOGERR("CONTROLVM_PAYLOAD_INIT Failed: request_payload_offset=%llu request_payload_bytes=%llu!", (u64) offset, (u64) bytes); rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; goto Away; @@ -1436,8 +1436,8 @@ initialize_controlvm_payload(void) u32 payloadBytes = 0; if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - RequestPayloadOffset), + offsetof(struct spar_controlvm_channel_protocol, + request_payload_offset), &payloadOffset, sizeof(payloadOffset)) < 0) { LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, @@ -1445,8 +1445,8 @@ initialize_controlvm_payload(void) return; } if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - RequestPayloadBytes), + offsetof(struct spar_controlvm_channel_protocol, + request_payload_bytes), &payloadBytes, sizeof(payloadBytes)) < 0) { LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!"); POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, @@ -2068,8 +2068,8 @@ setup_crash_devices_work_queue(struct work_struct *work) /* get saved message count */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgCount), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), &localSavedCrashMsgCount, sizeof(u16)) < 0) { LOGERR("failed to get Saved Message Count"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -2088,8 +2088,8 @@ setup_crash_devices_work_queue(struct work_struct *work) /* get saved crash message offset */ if (visorchannel_read(ControlVm_channel, - offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, - SavedCrashMsgOffset), + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), &localSavedCrashMsgOffset, sizeof(u32)) < 0) { LOGERR("failed to get Saved Message Offset"); POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, @@ -2385,7 +2385,7 @@ visorchipset_init(void) ControlVm_channel = visorchannel_create_with_lock (addr, - sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL), + sizeof(struct spar_controlvm_channel_protocol), spar_controlvm_channel_protocol_uuid); if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT( visorchannel_get_header(ControlVm_channel))) { -- GitLab From 6242089330454dd5abb5dcd9726944b0176ed249 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:35 -0400 Subject: [PATCH 1386/9457] staging: unisys: refactor ULTRA_CONTROLVM_PARAMETERS_HEADER Remove the typedef from ULTRA_CONTROLVM_PARAMETERS_HEADER, and use struct spar_controlvm_parameters_header instead. Fix CamelCase names in the structure, and update references to fixed names in other files and the comments. TotalLength => total_length HeaderLength => header_length ConnectionOffset => connection_offset ConnectionLength => connection_length InitiatorOffset => initiator_offset InitiatorLength => initiator_length TargetOffset => target_offset TargetLength => target_length ClientOffset => client_offset ClientLength => client_length NameOffset => name_offset NameLength => name_length Id => id Revision => revision Reserved => reserved Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/controlvmchannel.h | 48 +++++++++--------- drivers/staging/unisys/visorchipset/parser.c | 50 ++++++++++--------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index c949cd47cc82..4633b786fd55 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -483,31 +483,29 @@ struct spar_controlvm_channel_protocol { offsetof(struct spar_controlvm_channel_protocol, saved_crash_msg) /* The following header will be located at the beginning of PayloadVmOffset for - * various ControlVm commands. The receiver of a ControlVm command with a - * PayloadVmOffset will dereference this address and then use ConnectionOffset, - * InitiatorOffset, and TargetOffset to get the location of UTF-8 formatted - * strings that can be parsed to obtain command-specific information. The value - * of TotalLength should equal PayloadBytes. The format of the strings at - * PayloadVmOffset will take different forms depending on the message. See the - * following Wiki page for more information: - * https://ustr-linux-1.na.uis.unisys.com/spar/index.php/ControlVm_Parameters_Area + * various ControlVm commands. The receiver of a ControlVm command with a + * PayloadVmOffset will dereference this address and then use connection_offset, + * initiator_offset, and target_offset to get the location of UTF-8 formatted + * strings that can be parsed to obtain command-specific information. The value + * of total_length should equal PayloadBytes. The format of the strings at + * PayloadVmOffset will take different forms depending on the message. */ -typedef struct _ULTRA_CONTROLVM_PARAMETERS_HEADER { - u32 TotalLength; - u32 HeaderLength; - u32 ConnectionOffset; - u32 ConnectionLength; - u32 InitiatorOffset; - u32 InitiatorLength; - u32 TargetOffset; - u32 TargetLength; - u32 ClientOffset; - u32 ClientLength; - u32 NameOffset; - u32 NameLength; - uuid_le Id; - u32 Revision; - u32 Reserved; /* Natural alignment */ -} ULTRA_CONTROLVM_PARAMETERS_HEADER; +struct spar_controlvm_parameters_header { + u32 total_length; + u32 header_length; + u32 connection_offset; + u32 connection_length; + u32 initiator_offset; + u32 initiator_length; + u32 target_offset; + u32 target_length; + u32 client_offset; + u32 client_length; + u32 name_offset; + u32 name_length; + uuid_le id; + u32 revision; + u32 reserved; /* Natural alignment */ +}; #endif /* __CONTROLVMCHANNEL_H__ */ diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c index 661aaae9b154..6c2eac0346b6 100644 --- a/drivers/staging/unisys/visorchipset/parser.c +++ b/drivers/staging/unisys/visorchipset/parser.c @@ -48,7 +48,7 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, PARSER_CONTEXT *rc = NULL; PARSER_CONTEXT *ctx = NULL; MEMREGION *rgn = NULL; - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (tryAgain) *tryAgain = FALSE; @@ -110,27 +110,29 @@ parser_init_guts(u64 addr, u32 bytes, BOOL isLocal, rc = ctx; goto Away; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); - if (phdr->TotalLength != bytes) { + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + if (phdr->total_length != bytes) { ERRDRV("%s - bad total length %lu (should be %lu)", __func__, - (ulong) (phdr->TotalLength), (ulong) (bytes)); + (ulong) (phdr->total_length), (ulong) (bytes)); rc = NULL; goto Away; } - if (phdr->TotalLength < phdr->HeaderLength) { + if (phdr->total_length < phdr->header_length) { ERRDRV("%s - total length < header length (%lu < %lu)", __func__, - (ulong) (phdr->TotalLength), - (ulong) (phdr->HeaderLength)); + (ulong) (phdr->total_length), + (ulong) (phdr->header_length)); rc = NULL; goto Away; } - if (phdr->HeaderLength < sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER)) { + if (phdr->header_length < + sizeof(struct spar_controlvm_parameters_header)) { ERRDRV("%s - header is too small (%lu < %lu)", __func__, - (ulong) (phdr->HeaderLength), - (ulong) (sizeof(ULTRA_CONTROLVM_PARAMETERS_HEADER))); + (ulong) (phdr->header_length), + (ulong)(sizeof( + struct spar_controlvm_parameters_header))); rc = NULL; goto Away; } @@ -159,7 +161,7 @@ parser_init(u64 addr, u32 bytes, BOOL isLocal, BOOL *tryAgain) } /* Call this instead of parser_init() if the payload area consists of just - * a sequence of bytes, rather than a ULTRA_CONTROLVM_PARAMETERS_HEADER + * a sequence of bytes, rather than a struct spar_controlvm_parameters_header * structures. Afterwards, you can call parser_simpleString_get() or * parser_byteStream_get() to obtain the data. */ @@ -196,44 +198,44 @@ parser_byteStream_get(PARSER_CONTEXT *ctx, ulong *nbytes) uuid_le parser_id_get(PARSER_CONTEXT *ctx) { - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (ctx == NULL) { ERRDRV("%s (%s:%d) - no context", __func__, __FILE__, __LINE__); return NULL_UUID_LE; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); - return phdr->Id; + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); + return phdr->id; } void parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string) { - ULTRA_CONTROLVM_PARAMETERS_HEADER *phdr = NULL; + struct spar_controlvm_parameters_header *phdr = NULL; if (ctx == NULL) { ERRDRV("%s (%s:%d) - no context", __func__, __FILE__, __LINE__); goto Away; } - phdr = (ULTRA_CONTROLVM_PARAMETERS_HEADER *) (ctx->data); + phdr = (struct spar_controlvm_parameters_header *)(ctx->data); switch (which_string) { case PARSERSTRING_INITIATOR: - ctx->curr = ctx->data + phdr->InitiatorOffset; - ctx->bytes_remaining = phdr->InitiatorLength; + ctx->curr = ctx->data + phdr->initiator_offset; + ctx->bytes_remaining = phdr->initiator_length; break; case PARSERSTRING_TARGET: - ctx->curr = ctx->data + phdr->TargetOffset; - ctx->bytes_remaining = phdr->TargetLength; + ctx->curr = ctx->data + phdr->target_offset; + ctx->bytes_remaining = phdr->target_length; break; case PARSERSTRING_CONNECTION: - ctx->curr = ctx->data + phdr->ConnectionOffset; - ctx->bytes_remaining = phdr->ConnectionLength; + ctx->curr = ctx->data + phdr->connection_offset; + ctx->bytes_remaining = phdr->connection_length; break; case PARSERSTRING_NAME: - ctx->curr = ctx->data + phdr->NameOffset; - ctx->bytes_remaining = phdr->NameLength; + ctx->curr = ctx->data + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; break; default: ERRDRV("%s - bad which_string %d", __func__, which_string); -- GitLab From 9921b74d48bb131ca21e6db84476445070bc23cb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:36 -0400 Subject: [PATCH 1387/9457] staging: unisys: fix misspelled word in controlvmchannel.h "intrrupt" should be "interrupt" in the comments in controlvmchannel.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 4633b786fd55..a66db7968d6c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -127,7 +127,7 @@ struct irq_info { /**< specifies interrupt handle. It is used to retrieve the * corresponding interrupt pin from Monitor; and the * interrupt pin is used to connect to the corresponding - * intrrupt. Used by IOPart-GP only. */ + * interrupt. Used by IOPart-GP only. */ u64 recv_irq_handle; /**< specifies interrupt vector. It, interrupt pin, and shared are -- GitLab From e926cd5958d0554b0458f3ae9bf5288094aea902 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:37 -0400 Subject: [PATCH 1388/9457] staging: unisys: refactor UltraDiagChannelProtocolGuid Fix the CamelCase name: UltraDiagChannelProtocolGuid => spar_diag_channel_protocol_uuid Also, rename ULTRA_DIAG_CHANNEL_PROTOCOL_GUID to SPAR_DIAG_CHANNEL_PROTOCOL_UUID to match the new variable name. Update all references to the changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/diagchannel.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 4132642aa05b..920dc361750e 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -37,12 +37,12 @@ #include "channel.h" /* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */ -#define ULTRA_DIAG_CHANNEL_PROTOCOL_GUID \ +#define SPAR_DIAG_CHANNEL_PROTOCOL_UUID \ UUID_LE(0xeea7a573, 0xdb82, 0x447c, \ 0x87, 0x16, 0xef, 0xbe, 0xaa, 0xae, 0x48, 0x58) -static const uuid_le UltraDiagChannelProtocolGuid = - ULTRA_DIAG_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_diag_channel_protocol_uuid = + SPAR_DIAG_CHANNEL_PROTOCOL_UUID; /* {E850F968-3263-4484-8CA5-2A35D087A5A8} */ #define ULTRA_DIAG_ROOT_CHANNEL_PROTOCOL_GUID \ @@ -60,13 +60,13 @@ static const uuid_le UltraDiagChannelProtocolGuid = #define ULTRA_DIAG_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, \ - UltraDiagChannelProtocolGuid, \ + spar_diag_channel_protocol_uuid, \ "diag", \ sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) #define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(UltraDiagChannelProtocolGuid, \ + (spar_check_channel_server(spar_diag_channel_protocol_uuid, \ "diag", \ sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ actualBytes)) -- GitLab From a2c758e2010c4b30bc33de57d76c2d2d153166f8 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:38 -0400 Subject: [PATCH 1389/9457] staging: unisys: refactor ULTRA_DIAG_CHANNEL_OK_CLIENT Rename this macro to SPAR_DIAG_CHANNEL_OK_CLIENT, fix the CamelCase parameter and get rid of the unused LogCtx parameter. pChannel => ch Fix the indentation and add a blank line after the macro definition so it looks nicer. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/diagchannel.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 920dc361750e..13fe4751ca79 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -58,13 +58,14 @@ static const uuid_le spar_diag_channel_protocol_uuid = * increment this. */ #define ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID 2 -#define ULTRA_DIAG_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (spar_check_channel_client(pChannel, \ - spar_diag_channel_protocol_uuid, \ - "diag", \ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ - ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) +#define SPAR_DIAG_CHANNEL_OK_CLIENT(ch)\ + (spar_check_channel_client(ch,\ + spar_diag_channel_protocol_uuid,\ + "diag",\ + sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL),\ + ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ + ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) + #define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes) \ (spar_check_channel_server(spar_diag_channel_protocol_uuid, \ "diag", \ -- GitLab From a7a6cceb09ecf9f1325a9ce5ba57a35a25e3a2d0 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:39 -0400 Subject: [PATCH 1390/9457] staging: unisys: refactor ULTRA_DIAG_CHANNEL_OK_SERVER Rename this macro to SPAR_DIAG_CHANNEL_OK_SERVER and fix the CamelCase parameter. ActualBytes => bytes Fix indentation and add a blank line after the macro for better readability. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/diagchannel.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 13fe4751ca79..db8b9829eea4 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -66,11 +66,12 @@ static const uuid_le spar_diag_channel_protocol_uuid = ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_DIAG_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(spar_diag_channel_protocol_uuid, \ - "diag", \ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL), \ - actualBytes)) +#define SPAR_DIAG_CHANNEL_OK_SERVER(bytes)\ + (spar_check_channel_server(spar_diag_channel_protocol_uuid,\ + "diag",\ + sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL),\ + bytes)) + #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ #define MAX_ADDITIONAL_INFO_SIZE 256 /* Maximum length of any additional info * accompanying event... */ -- GitLab From f38c5b13490a01b27adf4641b51b9cc41d06b377 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:40 -0400 Subject: [PATCH 1391/9457] staging: unisys: refactor DIAG_EFI_TIME Get rid of the typedef and use struct diag_efi_time instead. Fix CamelCase member names and update references to changed names. Year => year Month => month Day => day Hour => hour Minute => minute Second => second Pad1 => pad1 Nanosecond => nanosecond TimeZone => timezone Daylight => daylight Pad2 => pad2 Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/diagchannel.h | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index db8b9829eea4..8f2a7626cdfa 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -106,19 +106,19 @@ static const uuid_le spar_diag_channel_protocol_uuid = /* Copied from EFI's EFI_TIME struct in efidef.h. EFI headers are not allowed * in some of the Supervisor areas, such as Monitor, so it has been "ported" here * for use in diagnostic event timestamps... */ -typedef struct _DIAG_EFI_TIME { - u16 Year; /* 1998 - 20XX */ - u8 Month; /* 1 - 12 */ - u8 Day; /* 1 - 31 */ - u8 Hour; /* 0 - 23 */ - u8 Minute; /* 0 - 59 */ - u8 Second; /* 0 - 59 */ - u8 Pad1; - u32 Nanosecond; /* 0 - 999, 999, 999 */ - s16 TimeZone; /* -1440 to 1440 or 2047 */ - u8 Daylight; - u8 Pad2; -} DIAG_EFI_TIME; +struct diag_efi_time { + u16 year; /* 1998 - 20XX */ + u8 month; /* 1 - 12 */ + u8 day; /* 1 - 31 */ + u8 hour; /* 0 - 23 */ + u8 minute; /* 0 - 59 */ + u8 second; /* 0 - 59 */ + u8 pad1; + u32 nanosecond; /* 0 - 999, 999, 999 */ + s16 timezone; /* -1440 to 1440 or 2047 */ + u8 daylight; + u8 pad2; +}; typedef enum { ULTRA_COMPONENT_GUEST = 0, @@ -161,7 +161,7 @@ typedef struct _DIAG_CHANNEL_EVENT { u32 Severity; u8 ModuleName[MAX_MODULE_NAME_SIZE]; u32 LineNumber; - DIAG_EFI_TIME Timestamp; /* Size = 16 bytes */ + struct diag_efi_time Timestamp; /* Size = 16 bytes */ u32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are * filled */ u16 VirtualProcessorNumber; -- GitLab From e91a008a47efcaeb20745e0bf77797b36d559fc5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:41 -0400 Subject: [PATCH 1392/9457] staging: unisys: refactor ULTRA_COMPONENT_TYPES Get rid of the typedef for ULTRA_COMPONENT_TYPES and use enum spar_component_types instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/diagchannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 8f2a7626cdfa..61259e48905a 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -120,7 +120,7 @@ struct diag_efi_time { u8 pad2; }; -typedef enum { +enum spar_component_types { ULTRA_COMPONENT_GUEST = 0, ULTRA_COMPONENT_MONITOR = 0x01, ULTRA_COMPONENT_CCM = 0x02, /* Common Control module */ @@ -145,7 +145,7 @@ typedef enum { ULTRA_COMPONENT_PSERVICES = 0x17, ULTRA_COMPONENT_PDIAG = 0x18 /* RESERVED 0x18 - 0x1F */ -} ULTRA_COMPONENT_TYPES; +}; /* Structure: DIAG_CHANNEL_EVENT Purpose: Contains attributes that make up an * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of -- GitLab From 4cdc6890063ecc0a0c40df127366a5342e48723e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:42 -0400 Subject: [PATCH 1393/9457] staging: unisys: refactor DIAG_CHANNEL_EVENT Get rid of the typedef on DIAG_CHANNEL_EVENT, and use struct diag_channel_event instead. Update comments and fix CamelCase member names: EventId => event_id Severity => severity ModuleName => module_name LineNumber => line_number Timestamp => timestamp PartitionNumber => partition_number VirtualProcessorNumber => vcpu_number LogicalProcessorNumber => lcpu_number ComponentType => component_type Subsystem => subsystem Reserved0 => reserved0 BlockNumber => block_no BlockNumberHigh => block_no_high EventNumber => event_no EventNumberHigh => event_no_high Reserved => reserved AdditionalInfo => additional_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/diagchannel.h | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 61259e48905a..6b3c4c82b10e 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -147,7 +147,7 @@ enum spar_component_types { /* RESERVED 0x18 - 0x1F */ }; -/* Structure: DIAG_CHANNEL_EVENT Purpose: Contains attributes that make up an +/* Structure: diag_channel_event Purpose: Contains attributes that make up an * event to be written to the DIAG_CHANNEL memory. Attributes: EventId: Id of * the diagnostic event to write to memory. Severity: Severity of the event * (Error, Info, etc). ModuleName: Module/file name where event originated. @@ -156,40 +156,40 @@ enum spar_component_types { * Reserved: Padding to align structure on a 64-byte cache line boundary. * AdditionalInfo: Array of characters for additional event info (may be * empty). */ -typedef struct _DIAG_CHANNEL_EVENT { - u32 EventId; - u32 Severity; - u8 ModuleName[MAX_MODULE_NAME_SIZE]; - u32 LineNumber; - struct diag_efi_time Timestamp; /* Size = 16 bytes */ - u32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are +struct diag_channel_event { + u32 event_id; + u32 severity; + u8 module_name[MAX_MODULE_NAME_SIZE]; + u32 line_number; + struct diag_efi_time timestamp; /* Size = 16 bytes */ + u32 partition_number; /* Filled in by Diag Switch as pool blocks are * filled */ - u16 VirtualProcessorNumber; - u16 LogicalProcessorNumber; - u8 ComponentType; /* ULTRA_COMPONENT_TYPES */ - u8 Subsystem; - u16 Reserved0; /* pad to u64 alignment */ - u32 BlockNumber; /* filled in by DiagSwitch as pool blocks are + u16 vcpu_number; + u16 lcpu_number; + u8 component_type; /* ULTRA_COMPONENT_TYPES */ + u8 subsystem; + u16 reserved0; /* pad to u64 alignment */ + u32 block_no; /* filled in by DiagSwitch as pool blocks are * filled */ - u32 BlockNumberHigh; - u32 EventNumber; /* filled in by DiagSwitch as pool blocks are + u32 block_no_high; + u32 event_no; /* filled in by DiagSwitch as pool blocks are * filled */ - u32 EventNumberHigh; + u32 event_no_high; - /* The BlockNumber and EventNumber fields are set only by DiagSwitch + /* The block_no and event_no fields are set only by DiagSwitch * and referenced only by WinDiagDisplay formatting tool as * additional diagnostic information. Other tools including * WinDiagDisplay currently ignore these 'Reserved' bytes. */ - u8 Reserved[8]; - u8 AdditionalInfo[MAX_ADDITIONAL_INFO_SIZE]; + u8 reserved[8]; + u8 additional_info[MAX_ADDITIONAL_INFO_SIZE]; - /* NOTE: Changesto DIAG_CHANNEL_EVENT generally need to be reflected in + /* NOTE: Changes to diag_channel_event generally need to be reflected in * existing copies * * - for AppOS at * GuestLinux/visordiag_early/supervisor_diagchannel.h * * - for WinDiagDisplay at * EFI/Ultra/Tools/WinDiagDisplay/WinDiagDisplay/diagstruct.h */ -} DIAG_CHANNEL_EVENT; +}; /* Levels of severity for diagnostic events, in order from lowest severity to * highest (i.e. fatal errors are the most severe, and should always be logged, @@ -240,14 +240,14 @@ typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, * "DIAG_SEVERITY_PRINT" (=4), is used for transferring text or binary file to * the Diag partition. This cause-severity combination will be used by Logger * DiagSwitch to segregate events into block types. The files are transferred in -* 256 byte chunks maximum, in the AdditionalInfo field of the DIAG_CHANNEL_EVENT +* 256 byte chunks maximum, in the AdditionalInfo field of the diag_channel_event * structure. In the file transfer mode, some event fields will have different * meaning: EventId specifies the file offset, severity specifies the block type, * ModuleName specifies the filename, LineNumber specifies the number of valid * data bytes in an event and AdditionalInfo contains up to 256 bytes of data. */ /* The Diag DiagWriter appends event blocks to events.raw as today, and for data - * blocks uses DIAG_CHANNEL_EVENT + * blocks uses diag_channel_event * PartitionNumber to extract and append 'AdditionalInfo' to filename (specified * by ModuleName). */ @@ -378,7 +378,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { /* ----------------------- */ /* | DiagChannel Header | Defined by DIAG_CHANNEL_PROTOCOL_HEADER */ /* ----------------------- */ -/* | Channel Event Info | Defined by (DIAG_CHANNEL_EVENT * MAX_EVENTS) */ +/* | Channel Event Info | Defined by diag_channel_event*MAX_EVENTS */ /* ----------------------- */ /* | Reserved | Reserved (pad out to 4MB) */ /* ----------------------- */ @@ -420,8 +420,8 @@ typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { struct channel_header CommonChannelHeader; struct signal_queue_header QueueHeader; DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader; - DIAG_CHANNEL_EVENT Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / - sizeof(DIAG_CHANNEL_EVENT)]; + struct diag_channel_event Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / + sizeof(struct diag_channel_event)]; } ULTRA_DIAG_CHANNEL_PROTOCOL; -- GitLab From 1ac6f52dcc38ec024e7daa4e078cfa515bf00b6d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:43 -0400 Subject: [PATCH 1394/9457] staging: unisys: remove typedef for DIAG_SEVERITY Get rid of the typedef for DIAG_SEVERITY and just use the enum diag_severity instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/diagchannel.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 6b3c4c82b10e..2f0a523a9659 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -202,7 +202,8 @@ struct diag_channel_event { * they are valid for controlling the amount of event data. This enum is also * defined in DotNet\sParFramework\ControlFramework\ControlFramework.cs. If a * change is made to this enum, they should also be reflected in that file. */ -typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, +enum diag_severity { + DIAG_SEVERITY_ENUM_BEGIN = 0, DIAG_SEVERITY_OVERRIDE = DIAG_SEVERITY_ENUM_BEGIN, DIAG_SEVERITY_VERBOSE = DIAG_SEVERITY_OVERRIDE, /* 0 */ DIAG_SEVERITY_INFO = DIAG_SEVERITY_VERBOSE + 1, /* 1 */ @@ -213,7 +214,7 @@ typedef enum { DIAG_SEVERITY_ENUM_BEGIN = 0, DIAG_SEVERITY_ENUM_END = DIAG_SEVERITY_SHUTOFF, /* 5 */ DIAG_SEVERITY_NONFATAL_ERR = DIAG_SEVERITY_ERR, DIAG_SEVERITY_FATAL_ERR = DIAG_SEVERITY_PRINT -} DIAG_SEVERITY; +}; /* Event Cause enums * -- GitLab From c41ace756d3edd24fd742bdd5cc67393cb906045 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:44 -0400 Subject: [PATCH 1395/9457] staging: unisys: remove extra blank lines in diagchannel.h Take out the extra blank lines in diagchannel.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/diagchannel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 2f0a523a9659..5d378811fc33 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -235,8 +235,6 @@ enum diag_severity { * If a change is made to this enum, they should also be reflected in that * file. */ - - /* A cause value "DIAG_CAUSE_FILE_XFER" together with a severity value of * "DIAG_SEVERITY_PRINT" (=4), is used for transferring text or binary file to * the Diag partition. This cause-severity combination will be used by Logger -- GitLab From e63dc4e1149881adb5c9b6fe480d4a9ffb04aa0e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:45 -0400 Subject: [PATCH 1396/9457] staging: unisys: remove typedef from DIAG_CAUSE Remove the typedef from DIAG_CAUSE and just use enum diag_cause instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/diagchannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 5d378811fc33..b24194ea546b 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -252,7 +252,7 @@ enum diag_severity { /* The Dell PDiag uses this new mechanism to stash DSET .zip onto the * 'diagnostic' virtual disk. */ -typedef enum { +enum diag_cause { DIAG_CAUSE_UNKNOWN = 0, DIAG_CAUSE_UNKNOWN_DEBUG = DIAG_CAUSE_UNKNOWN + 1, /* 1 */ DIAG_CAUSE_DEBUG = DIAG_CAUSE_UNKNOWN_DEBUG + 1, /* 2 */ @@ -264,7 +264,7 @@ typedef enum { DIAG_CAUSE_INTERNAL_ERROR = DIAG_CAUSE_INVALID_REQUEST + 1, /* 8 */ DIAG_CAUSE_FILE_XFER = DIAG_CAUSE_INTERNAL_ERROR + 1, /* 9 */ DIAG_CAUSE_ENUM_END = DIAG_CAUSE_FILE_XFER /* 9 */ -} DIAG_CAUSE; +}; /* Event Cause category defined into the byte 2 of Severity */ #define CAUSE_DEBUG (DIAG_CAUSE_DEBUG << CAUSE_SHIFT_AMT) -- GitLab From 5f0a528bc1f4af28287b80532d2f2cbd047b4307 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:46 -0400 Subject: [PATCH 1397/9457] staging: unisys: refactor DIAG_CHANNEL_PROTOCOL_HEADER Get rid of the typedef and use struct diag_channel_protocol_header instead. Fix CamelCase member names and update references and comments. DiagLock => diag_lock IsChannelInitialized => channel_initialized Reserved => reserved SubsystemSeverityFilter => subsystem_severity_filter Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/diagchannel.h | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index b24194ea546b..022027c9997c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -344,7 +344,7 @@ enum diag_cause { #define CAUSE_FILE_XFER_SEVERITY_PRINT \ (CAUSE_FILE_XFER | DIAG_SEVERITY_PRINT) -/* Structure: DIAG_CHANNEL_PROTOCOL_HEADER +/* Structure: diag_channel_protocol_header * * Purpose: Contains attributes that make up the header specific to the * DIAG_CHANNEL area. @@ -362,12 +362,12 @@ enum diag_cause { * whether events are logged. Any event's severity for a * particular subsystem below this level will be discarded. */ -typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { - volatile u32 DiagLock; - u8 IsChannelInitialized; - u8 Reserved[3]; - u8 SubsystemSeverityFilter[64]; -} DIAG_CHANNEL_PROTOCOL_HEADER; +struct diag_channel_protocol_header { + u32 diag_lock; + u8 channel_initialized; + u8 reserved[3]; + u8 subsystem_severity_filter[64]; +}; /* The Diagram for the Diagnostic Channel: */ /* ----------------------- */ @@ -375,7 +375,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { /* ----------------------- */ /* | Signal Queue Header | Defined by SIGNAL_QUEUE_HEADER */ /* ----------------------- */ -/* | DiagChannel Header | Defined by DIAG_CHANNEL_PROTOCOL_HEADER */ +/* | DiagChannel Header | Defined by diag_channel_protocol_header */ /* ----------------------- */ /* | Channel Event Info | Defined by diag_channel_event*MAX_EVENTS */ /* ----------------------- */ @@ -387,7 +387,8 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { #define DIAG_CH_QUEUE_HEADER_SIZE (sizeof(struct signal_queue_header)) #define DIAG_CH_PROTOCOL_HEADER_OFFSET \ (DIAG_CH_QUEUE_HEADER_OFFSET + DIAG_CH_QUEUE_HEADER_SIZE) -#define DIAG_CH_PROTOCOL_HEADER_SIZE (sizeof(DIAG_CHANNEL_PROTOCOL_HEADER)) +#define DIAG_CH_PROTOCOL_HEADER_SIZE \ + (sizeof(struct diag_channel_protocol_header)) #define DIAG_CH_EVENT_OFFSET \ (DIAG_CH_PROTOCOL_HEADER_OFFSET + DIAG_CH_PROTOCOL_HEADER_SIZE) #define DIAG_CH_SIZE (4096 * 1024) @@ -409,7 +410,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { * store event. * * DiagChannelHeader: Diagnostic channel header info (see - * DIAG_CHANNEL_PROTOCOL_HEADER comments). + * diag_channel_protocol_header comments). * * Events: Area where diagnostic events (up to MAX_EVENTS) are written. * @@ -418,7 +419,7 @@ typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER { typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { struct channel_header CommonChannelHeader; struct signal_queue_header QueueHeader; - DIAG_CHANNEL_PROTOCOL_HEADER DiagChannelHeader; + struct diag_channel_protocol_header DiagChannelHeader; struct diag_channel_event Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / sizeof(struct diag_channel_event)]; } -- GitLab From f207671f402b9aa7367ee21dbab2e450d16c9d7e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:47 -0400 Subject: [PATCH 1398/9457] staging: unisys: refactor ULTRA_DIAG_CHANNEL_PROTOCOL Get rid of the typedef and use struct spar_diag_channel_protocol instead. Fix CamelCase member names, and update references and comments to match. struct channel_header CommonChannelHeader; QueueHeader => queue_header DiagChannelHeader => diag_channel_header Events => events Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/diagchannel.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index 022027c9997c..e8fb8678a8e2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -62,14 +62,14 @@ static const uuid_le spar_diag_channel_protocol_uuid = (spar_check_channel_client(ch,\ spar_diag_channel_protocol_uuid,\ "diag",\ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL),\ + sizeof(struct spar_diag_channel_protocol),\ ULTRA_DIAG_CHANNEL_PROTOCOL_VERSIONID,\ ULTRA_DIAG_CHANNEL_PROTOCOL_SIGNATURE)) #define SPAR_DIAG_CHANNEL_OK_SERVER(bytes)\ (spar_check_channel_server(spar_diag_channel_protocol_uuid,\ "diag",\ - sizeof(ULTRA_DIAG_CHANNEL_PROTOCOL),\ + sizeof(struct spar_diag_channel_protocol),\ bytes)) #define MAX_MODULE_NAME_SIZE 128 /* Maximum length of module name... */ @@ -398,7 +398,7 @@ struct diag_channel_protocol_header { #define DIAG_CH_LRG_SIZE (2 * DIAG_CH_SIZE) /* 8 MB */ /* - * Structure: ULTRA_DIAG_CHANNEL_PROTOCOL + * Structure: spar_diag_channel_protocol * * Purpose: Contains attributes that make up the DIAG_CHANNEL memory. * @@ -416,13 +416,12 @@ struct diag_channel_protocol_header { * *Reserved: Reserved area to allow for correct channel size padding. */ -typedef struct _ULTRA_DIAG_CHANNEL_PROTOCOL { - struct channel_header CommonChannelHeader; - struct signal_queue_header QueueHeader; - struct diag_channel_protocol_header DiagChannelHeader; - struct diag_channel_event Events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / +struct spar_diag_channel_protocol { + struct channel_header common_channel_header; + struct signal_queue_header queue_header; + struct diag_channel_protocol_header diag_channel_header; + struct diag_channel_event events[(DIAG_CH_SIZE - DIAG_CH_EVENT_OFFSET) / sizeof(struct diag_channel_event)]; -} -ULTRA_DIAG_CHANNEL_PROTOCOL; +}; #endif -- GitLab From cd2f87e60b09f0c83c959a35da441269e429d6d4 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:48 -0400 Subject: [PATCH 1399/9457] staging: unisys: clean up line spacing in iochannel.h Get rid of extra blank lines in iochannel.h Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/iochannel.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index b1f4a47b3d62..87c66c084b97 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -8,7 +8,6 @@ * this file. Note: Everything is OS-independent because this file is * used by Windows, Linux and possible EFI drivers. */ - /* * Communication flow between the IOPart and GuestPart uses the channel headers * channel state. The following states are currently being used: @@ -89,7 +88,6 @@ * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ - /* * Defines and enums. */ @@ -236,7 +234,6 @@ typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, /* * structs with pragma pack */ - /* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */ /* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */ @@ -404,12 +401,10 @@ struct uiscmdrsp_scsi { } \ } while (0) - /* * Struct & Defines to support sense information. */ - /* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is * initialized in exactly the manner that is recommended in Windows (hence the * odd values). @@ -478,7 +473,6 @@ struct net_pkt_xmt { * each fragment */ char ethhdr[ETH_HEADER_SIZE]; /* the ethernet header */ struct { - /* these are needed for csum at uisnic end */ u8 valid; /* 1 = rest of this struct is valid - else * ignore */ @@ -528,7 +522,6 @@ struct net_pkt_rcvpost { }; struct net_pkt_rcv { - /* the number of receive buffers that can be chained */ /* is based on max mtu and size of each rcv buf */ u32 rcv_done_len; /* length of received data */ @@ -727,7 +720,6 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { * INLINE functions for initializing and accessing I/O data channels */ - #define NUMSIGNALS(x, q) (((ULTRA_IO_CHANNEL_PROTOCOL *)(x))->q.MaxSignalSlots) #define SIZEOF_PROTOCOL (COVER(sizeof(ULTRA_IO_CHANNEL_PROTOCOL), 64)) #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) @@ -781,7 +773,6 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { return 0; \ } while (0) - #define ULTRA_IO_CHANNEL_SERVER_READY(x, chanId, logCtx) \ ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, CHANNELSRV_READY, \ logCtx) @@ -864,7 +855,6 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, * pfn-off-size entires. */ - /* we deal with 4K page sizes when we it comes to passing page information * between */ /* Guest and IOPartition. */ @@ -894,7 +884,6 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { - /* the input entry spans only one page - add as is */ if (index >= max_pi_arr_entries) return 0; @@ -920,7 +909,6 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used pi_arr[index + i].pi_len = (u16) MINNUM(len, (u32) PI_PAGE_SIZE); } - } return index + i; } -- GitLab From 797d682a454caaba3f05f82f6d5f2a88248d5245 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:49 -0400 Subject: [PATCH 1400/9457] staging: unisys: fix typecast spacing in iochannel.h Fix all the spaces between typecasts and their targets in iochannel.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/iochannel.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 87c66c084b97..631fc0450bf2 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -204,7 +204,7 @@ typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving #endif /* MAX_MACADDR_LEN */ #define ETH_IS_LOCALLY_ADMINISTERED(Address) \ - (((u8 *) (Address))[0] & ((u8) 0x02)) + (((u8 *)(Address))[0] & ((u8) 0x02)) #define NIC_VENDOR_ID 0x0008000B /* various types of scsi task mgmt commands */ @@ -368,16 +368,16 @@ struct uiscmdrsp_scsi { do { \ memset(buf, 0, \ MINNUM(len, \ - (unsigned int) NO_DISK_INQUIRY_RESULT_LEN)); \ - buf[2] = (u8) SCSI_SPC2_VER; \ + (unsigned int)NO_DISK_INQUIRY_RESULT_LEN)); \ + buf[2] = (u8)SCSI_SPC2_VER; \ if (lun == 0) { \ - buf[0] = (u8) lun0notpresent; \ - buf[3] = (u8) DEV_HISUPPORT; \ + buf[0] = (u8)lun0notpresent; \ + buf[3] = (u8)DEV_HISUPPORT; \ } else \ - buf[0] = (u8) notpresent; \ - buf[4] = (u8) ( \ + buf[0] = (u8)notpresent; \ + buf[4] = (u8)( \ MINNUM(len, \ - (unsigned int) NO_DISK_INQUIRY_RESULT_LEN) - 5); \ + (unsigned int)NO_DISK_INQUIRY_RESULT_LEN) - 5);\ if (len >= NO_DISK_INQUIRY_RESULT_LEN) { \ buf[8] = 'D'; \ buf[9] = 'E'; \ @@ -762,9 +762,9 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { offsetof(type, clientString); \ memcpy(chan->clientString, clientStr, \ MINNUM(clientStrLen, \ - (u32) (MAX_CLIENTSTRING_LEN - 1))); \ + (u32)(MAX_CLIENTSTRING_LEN - 1))); \ chan->clientString[MINNUM(clientStrLen, \ - (u32) (MAX_CLIENTSTRING_LEN \ + (u32)(MAX_CLIENTSTRING_LEN \ - 1))] \ = '\0'; \ } \ @@ -888,8 +888,8 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used if (index >= max_pi_arr_entries) return 0; pi_arr[index].pi_pfn = inp_pfn; - pi_arr[index].pi_off = (u16) inp_off; - pi_arr[index].pi_len = (u16) inp_len; + pi_arr[index].pi_off = (u16)inp_off; + pi_arr[index].pi_len = (u16)inp_len; return index + 1; } @@ -907,7 +907,7 @@ add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used else { pi_arr[index + i].pi_off = 0; pi_arr[index + i].pi_len = - (u16) MINNUM(len, (u32) PI_PAGE_SIZE); + (u16)MINNUM(len, (u32)PI_PAGE_SIZE); } } return index + i; -- GitLab From 47da307d2c378a5ea3f8bfbb6a109a99a1a3b221 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:50 -0400 Subject: [PATCH 1401/9457] staging: unisys: clean up CamelCase parameter in SPAR_VHBA_CHANNEL_OK_CLIENT Remove the unused logCtx parameter and fix CamelCase parameter name: pChannel => ch Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 631fc0450bf2..2e015498eb4f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -59,8 +59,8 @@ #define ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID 2 #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID 1 -#define SPAR_VHBA_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (spar_check_channel_client(pChannel, spar_vhba_channel_protocol_uuid, \ +#define SPAR_VHBA_CHANNEL_OK_CLIENT(ch) \ + (spar_check_channel_client(ch, spar_vhba_channel_protocol_uuid, \ "vhba", MIN_IO_CHANNEL_SIZE, \ ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index b8db2700a1df..72c8479fe49c 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -450,7 +450,7 @@ create_device(struct controlvm_message *msg, char *buf) chanptr))-> chtype); if (!SPAR_VHBA_CHANNEL_OK_CLIENT - (dev->chanptr, NULL)) { + (dev->chanptr)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.", devNo); POSTCODE_LINUX_4 -- GitLab From c0eafd65de50f8f94e014e5bfdd561d57c0858d1 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:51 -0400 Subject: [PATCH 1402/9457] staging: unisys: remove unused macro ULTRA_VHBA_CHANNEL_OK_SERVER This macro is not used so remove it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 2e015498eb4f..67f3a7ea31f4 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -64,9 +64,7 @@ "vhba", MIN_IO_CHANNEL_SIZE, \ ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_VHBA_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(spar_vhba_channel_protocol_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, actualBytes)) + #define SPAR_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ "vnic", MIN_IO_CHANNEL_SIZE, \ -- GitLab From dabf9dc1e27eb922b2d6f4504375deb340a3ba90 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:52 -0400 Subject: [PATCH 1403/9457] staging: unisys: remove unused macro ULTRA_VNIC_CHANNEL_OK_SERVER This macro isn't being used either, so delete it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 67f3a7ea31f4..0e446c06605c 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -70,9 +70,7 @@ "vnic", MIN_IO_CHANNEL_SIZE, \ ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_VNIC_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(spar_vnic_channel_protocol_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, actualBytes)) + #define SPAR_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ "vswitch", MIN_IO_CHANNEL_SIZE, \ -- GitLab From 44bd648d28dc5d7b522d1050e88f9ed10cf0cd1c Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:53 -0400 Subject: [PATCH 1404/9457] staging: unisys: remove unused macro ULTRA_VSWITCH_CHANNEL_OK_SERVER This macro isn't being used so take it out. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 0e446c06605c..51373a182e0d 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -76,10 +76,7 @@ "vswitch", MIN_IO_CHANNEL_SIZE, \ ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE)) -#define ULTRA_VSWITCH_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - actualBytes)) + /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ -- GitLab From bdedd94ad5b0931ef0bd56f8d9a2892d86f2049e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:54 -0400 Subject: [PATCH 1405/9457] staging: unisys: fix parameters to macro SPAR_VNIC_CHANNEL_OK_CLIENT Remove the unused logCtx parameter and fix the CamelCase name: pChannel => ch Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- drivers/staging/unisys/uislib/uislib.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 51373a182e0d..1fb7174fc597 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -65,8 +65,8 @@ ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE)) -#define SPAR_VNIC_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (spar_check_channel_client(pChannel, spar_vnic_channel_protocol_uuid, \ +#define SPAR_VNIC_CHANNEL_OK_CLIENT(ch) \ + (spar_check_channel_client(ch, spar_vnic_channel_protocol_uuid, \ "vnic", MIN_IO_CHANNEL_SIZE, \ ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 72c8479fe49c..14948a082934 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -476,7 +476,7 @@ create_device(struct controlvm_message *msg, char *buf) chanptr))-> chtype); if (!SPAR_VNIC_CHANNEL_OK_CLIENT - (dev->chanptr, NULL)) { + (dev->chanptr)) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.", devNo); POSTCODE_LINUX_4 -- GitLab From 21f131b5d1da2b09cc8e8d6d506dd4ed357a1cd5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:55 -0400 Subject: [PATCH 1406/9457] staging: unisys: remove unused macro SPAR_VSWITCH_CHANNEL_OK_CLIENT Nobody is using this one either... Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 1fb7174fc597..520fd3f3e8cc 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -71,12 +71,6 @@ ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID, \ ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE)) -#define SPAR_VSWITCH_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (spar_check_channel_client(pChannel, UltraVswitchChannelProtocolGuid, \ - "vswitch", MIN_IO_CHANNEL_SIZE, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE)) - /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ -- GitLab From 9c68aae24738ae2df50affce9252eb5a89432ca0 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:56 -0400 Subject: [PATCH 1407/9457] staging: unisys: remove typedef from NET_TYPES Take out the typedef and just use enum net_types instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/iochannel.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 520fd3f3e8cc..3f30969098c3 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -151,8 +151,9 @@ * SCSI Host value */ /* various types of network packets that can be sent in cmdrsp */ -typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving - * incoming packet */ +enum net_types { + NET_RCV_POST = 0, /* submit buffer to hold receiving + * incoming packet */ /* virtnic -> uisnic */ NET_RCV, /* incoming packet received */ /* uisnic -> virtpci */ @@ -174,7 +175,7 @@ typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving * its MAC addr */ NET_MACADDR_ACK, /* MAC address */ -} NET_TYPES; +}; #define ETH_HEADER_SIZE 14 /* size of ethernet header */ @@ -534,7 +535,7 @@ struct net_pkt_macaddr { /* cmd rsp packet used for VNIC network traffic */ struct uiscmdrsp_net { - NET_TYPES type; + enum net_types type; void *buf; union { struct net_pkt_xmt xmt; /* used for NET_XMIT */ -- GitLab From f43d9b50cded1d3a6908679a57bd9d83e1b8149a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:57 -0400 Subject: [PATCH 1408/9457] staging: unisys: fix CamelCase in ETH_IS_LOCALLY_ADMINISTERED Fix the CamelCase parameter in this macro: Address => address Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 3f30969098c3..6ee45066742f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -191,8 +191,8 @@ enum net_types { #define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ #endif /* MAX_MACADDR_LEN */ -#define ETH_IS_LOCALLY_ADMINISTERED(Address) \ - (((u8 *)(Address))[0] & ((u8) 0x02)) +#define ETH_IS_LOCALLY_ADMINISTERED(address) \ + (((u8 *)(address))[0] & ((u8)0x02)) #define NIC_VENDOR_ID 0x0008000B /* various types of scsi task mgmt commands */ -- GitLab From 63f06ba1eeebf720366ee4836695828d47a3bf26 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:58 -0400 Subject: [PATCH 1409/9457] staging: unisys: refactor TASK_MGMT_TYPES Get rid of the typedef and use enum task_mgmt_types in its place. Clean up the indentation of the enumeration values and update all use of the name to the new name. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/iochannel.h | 12 +++++++----- drivers/staging/unisys/virthba/virthba.c | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 6ee45066742f..129f4b6d2d37 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -196,10 +196,12 @@ enum net_types { #define NIC_VENDOR_ID 0x0008000B /* various types of scsi task mgmt commands */ -typedef enum { TASK_MGMT_ABORT_TASK = - 1, TASK_MGMT_BUS_RESET, TASK_MGMT_LUN_RESET, - TASK_MGMT_TARGET_RESET, -} TASK_MGMT_TYPES; +enum task_mgmt_types { + TASK_MGMT_ABORT_TASK = 1, + TASK_MGMT_BUS_RESET, + TASK_MGMT_LUN_RESET, + TASK_MGMT_TARGET_RESET, +}; /* various types of vdisk mgmt commands */ typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, @@ -551,7 +553,7 @@ struct uiscmdrsp_net { }; struct uiscmdrsp_scsitaskmgmt { - TASK_MGMT_TYPES tasktype; + enum task_mgmt_types tasktype; /* the type of task */ struct uisscsi_dest vdest; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 3a037f41ee40..fdf5e22ab548 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -738,7 +738,8 @@ forward_vdiskmgmt_command(VDISK_MGMT_TYPES vdiskcmdtype, /*****************************************************/ static int -forward_taskmgmt_command(TASK_MGMT_TYPES tasktype, struct scsi_device *scsidev) +forward_taskmgmt_command(enum task_mgmt_types tasktype, + struct scsi_device *scsidev) { struct uiscmdrsp *cmdrsp; struct virthba_info *virthbainfo = -- GitLab From c8cf5d075e2fe20bb29a63a48c32dbb4c48a59e9 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:30:59 -0400 Subject: [PATCH 1410/9457] staging: unisys: refactor enum VDISK_MGMT_TYPES Get rid of the typedef and use enum vdisk_mgmt_types instead. Reformat the enumeration names and update any references to use the enum directly. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/iochannel.h | 8 +++++--- drivers/staging/unisys/virthba/virthba.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 129f4b6d2d37..3256ff526859 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -204,8 +204,10 @@ enum task_mgmt_types { }; /* various types of vdisk mgmt commands */ -typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, -} VDISK_MGMT_TYPES; +enum vdisk_mgmt_types { + VDISK_MGMT_ACQUIRE = 1, + VDISK_MGMT_RELEASE, +}; /* this is used in the vdest field */ #define VDEST_ALL 0xFFFF @@ -600,7 +602,7 @@ struct uiscmdrsp_disknotify { /* The following is used by virthba/vSCSI to send the Acquire/Release commands * to the IOVM. */ struct uiscmdrsp_vdiskmgmt { - VDISK_MGMT_TYPES vdisktype; + enum vdisk_mgmt_types vdisktype; /* the type of task */ struct uisscsi_dest vdest; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index fdf5e22ab548..1e921f0f596d 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -674,7 +674,7 @@ virthba_remove(struct virtpci_dev *virtpcidev) } static int -forward_vdiskmgmt_command(VDISK_MGMT_TYPES vdiskcmdtype, +forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype, struct Scsi_Host *scsihost, struct uisscsi_dest *vdest) { -- GitLab From 3f549af37963bf5805652e31053401875bbee6f3 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:00 -0400 Subject: [PATCH 1411/9457] staging: unisys: fix CamelCase names in struct sense_data Fix CamelCase names: ErrorCode => error_code Valid => valid SegmentNumber => segment_number SenseKey => sense_key Reserved => reserved IncorrectLength => incorrect_length EndOfMedia => end_of_media FileMark => file_mark Information => information AdditionalSenseLength => additional_sense_length CommandSpecificInformation => commmand_specific_information AdditionalSenseCode => additional_sense_code AdditionalSenseCodeQualifier => additional_sense_code_qualifier FieldReplaceableUnitCode => fru_code SenseKeySpecific => sense_key_specific Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/iochannel.h | 30 +++++++++---------- drivers/staging/unisys/virthba/virthba.c | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 3256ff526859..1ebaa5b66eb9 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -410,21 +410,21 @@ struct uiscmdrsp_scsi { * AdditionalSenseLength contains will be sizeof(sense_data)-8=10. */ struct sense_data { - u8 ErrorCode:7; - u8 Valid:1; - u8 SegmentNumber; - u8 SenseKey:4; - u8 Reserved:1; - u8 IncorrectLength:1; - u8 EndOfMedia:1; - u8 FileMark:1; - u8 Information[4]; - u8 AdditionalSenseLength; - u8 CommandSpecificInformation[4]; - u8 AdditionalSenseCode; - u8 AdditionalSenseCodeQualifier; - u8 FieldReplaceableUnitCode; - u8 SenseKeySpecific[3]; + u8 errorcode:7; + u8 valid:1; + u8 segment_number; + u8 sense_key:4; + u8 reserved:1; + u8 incorrect_length:1; + u8 end_of_media:1; + u8 file_mark:1; + u8 information[4]; + u8 additional_sense_length; + u8 command_specific_information[4]; + u8 additional_sense_code; + u8 additional_sense_code_qualifier; + u8 fru_code; + u8 sense_key_specific[3]; }; /* some SCSI ADSENSE codes */ diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index 1e921f0f596d..a3ea0871664b 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1143,9 +1143,9 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) scsicmd, cmdrsp->scsi.cmnd[0], scsidev->host->host_no, scsidev->id, scsidev->channel, scsidev->lun, - cmdrsp->scsi.linuxstat, sd->Valid, sd->SenseKey, - sd->AdditionalSenseCode, - sd->AdditionalSenseCodeQualifier); + cmdrsp->scsi.linuxstat, sd->valid, sd->sense_key, + sd->additional_sense_code, + sd->additional_sense_code_qualifier); if (atomic_read(&vdisk->error_count) == VIRTHBA_ERROR_COUNT) { LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n", -- GitLab From 60a2708327f3c30c8e87c54cf3044f1e0c6a5d4b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:01 -0400 Subject: [PATCH 1412/9457] staging: unisys: fix CamelCase name in net_pkt_rcvpost Fix the CamelCase name in this struct: UniqueNum => unique_num Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/iochannel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 1ebaa5b66eb9..949562295ca4 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -508,7 +508,7 @@ struct net_pkt_rcvpost { * to be describable */ struct phys_info frag; /* physical page information for the * single fragment 2K rcv buf */ - u64 UniqueNum; /* This is used to make sure that + u64 unique_num; /* This is used to make sure that * receive posts are returned to */ /* the Adapter which sent them origonally. */ }; -- GitLab From efc84499e90b7192dbf80a6493a487f695f344e4 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:02 -0400 Subject: [PATCH 1413/9457] staging: unisys: fix CamelCase names in net_pkt_rcv Fix CamelCase names: UniqueNum => unique_num RcvsDroppedDelta => rcvs_dropped_delta Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 949562295ca4..2f0cf5f341a6 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -523,8 +523,8 @@ struct net_pkt_rcv { * that must be chained; */ /* each entry is a receive buffer provided by NET_RCV_POST. */ /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ - u64 UniqueNum; - u32 RcvsDroppedDelta; + u64 unique_num; + u32 rcvs_dropped_delta; }; struct net_pkt_enbdis { -- GitLab From be3c366905e56ff324018e00339167a3beead31e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:03 -0400 Subject: [PATCH 1414/9457] staging: unisys: fix CamelCase in uiscmdrsp_disknotify Fix the CamelCase member of this structure: vHba => v_hba Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/iochannel.h | 2 +- drivers/staging/unisys/virthba/virthba.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 2f0cf5f341a6..b4da34758b3d 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -594,7 +594,7 @@ struct uiscmdrsp_scsitaskmgmt { /* Note that the vHba pointer is not used by the Client/Guest side. */ struct uiscmdrsp_disknotify { u8 add; /* 0-remove, 1-add */ - void *vHba; /* Pointer to vhba_info for channel info to + void *v_hba; /* Pointer to vhba_info for channel info to * route msg */ u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ }; diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index a3ea0871664b..ee1be5a83e39 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -1310,7 +1310,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc, * a Client/Guest Partition. Let's be * safe and set it to NULL now. Do * not use it here! */ - cmdrsp->disknotify.vHba = NULL; + cmdrsp->disknotify.v_hba = NULL; process_disk_notify(shost, cmdrsp); } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) { if (!del_scsipending_entry(virthbainfo, -- GitLab From bedc756e3ae6b367cb740ddb5480dd63479b8a19 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:04 -0400 Subject: [PATCH 1415/9457] staging: unisys: refactor ULTRA_IO_CHANNEL_PROTOCOL Remove the typedef from ULTRA_IO_CHANNEL_PROTOCOL and use the name struct spar_io_channel_protocol instead. Fix CamelCase member names: ChannelHeader => channel_header cmdQ => cmd_q rspQ => rsp_q zoneGuid => zone_uuid ClientString => client_string Update all references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/iochannel.h | 127 +++++++++--------- drivers/staging/unisys/uislib/uislib.c | 4 +- drivers/staging/unisys/virtpci/virtpci.c | 26 ++-- 3 files changed, 79 insertions(+), 78 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index b4da34758b3d..071cf72125a1 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -662,11 +662,11 @@ struct uiscmdrsp { /* This is just the header of the IO channel. It is assumed that directly after * this header there is a large region of memory which contains the command and -* response queues as specified in cmdQ and rspQ SIGNAL_QUEUE_HEADERS. */ -typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { - struct channel_header ChannelHeader; - struct signal_queue_header cmdQ; - struct signal_queue_header rspQ; +* response queues as specified in cmd_q and rsp_q SIGNAL_QUEUE_HEADERS. */ +struct spar_io_channel_protocol { + struct channel_header channel_header; + struct signal_queue_header cmd_q; + struct signal_queue_header rsp_q; union { struct { struct vhba_wwnn wwnn; /* 8 bytes */ @@ -676,14 +676,14 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ u32 num_rcv_bufs; /* 4 */ u32 mtu; /* 4 */ - uuid_le zoneGuid; /* 16 */ + uuid_le zone_uuid; /* 16 */ } vnic; /* total 30 */ }; #define MAX_CLIENTSTRING_LEN 1024 - u8 clientString[MAX_CLIENTSTRING_LEN]; /* NULL terminated - so holds + u8 client_string[MAX_CLIENTSTRING_LEN];/* NULL terminated - so holds * max - 1 bytes */ -} ULTRA_IO_CHANNEL_PROTOCOL; +}; #pragma pack(pop) /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ @@ -712,13 +712,14 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { * INLINE functions for initializing and accessing I/O data channels */ -#define NUMSIGNALS(x, q) (((ULTRA_IO_CHANNEL_PROTOCOL *)(x))->q.MaxSignalSlots) -#define SIZEOF_PROTOCOL (COVER(sizeof(ULTRA_IO_CHANNEL_PROTOCOL), 64)) +#define NUMSIGNALS(x, q) \ + (((struct spar_io_channel_protocol *)(x))->q.MaxSignalSlots) +#define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64)) #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) #define IO_CHANNEL_SIZE(x) COVER(SIZEOF_PROTOCOL + \ - (NUMSIGNALS(x, cmdQ) + \ - NUMSIGNALS(x, rspQ)) * SIZEOF_CMDRSP, 4096) + (NUMSIGNALS(x, cmd_q) + \ + NUMSIGNALS(x, rsp_q)) * SIZEOF_CMDRSP, 4096) #define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \ 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096) #ifdef __GNUC__ @@ -728,34 +729,34 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { #define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP) #define SignalQInit(x) \ do { \ - x->cmdQ.size = QSIZEFROMBYTES(x->ChannelHeader.size); \ - x->cmdQ.sig_base_offset = SIZEOF_PROTOCOL - \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ - x->cmdQ.signal_size = SIZEOF_CMDRSP; \ - x->cmdQ.max_slots = \ - QSLOTSFROMBYTES(x->ChannelHeader.size); \ - x->cmdQ.max_signals = x->cmdQ.max_slots - 1; \ - x->rspQ.size = QSIZEFROMBYTES(x->ChannelHeader.size); \ - x->rspQ.sig_base_offset = \ - (SIZEOF_PROTOCOL + x->cmdQ.size) - \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ - x->rspQ.signal_size = SIZEOF_CMDRSP; \ - x->rspQ.max_slots = \ - QSLOTSFROMBYTES(x->ChannelHeader.size); \ - x->rspQ.max_signals = x->rspQ.max_slots - 1; \ - x->ChannelHeader.ch_space_offset = \ - offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ + x->cmd_q.size = QSIZEFROMBYTES(x->channel_header.size); \ + x->cmd_q.sig_base_offset = SIZEOF_PROTOCOL - \ + offsetof(struct spar_io_channel_protocol, cmd_q);\ + x->cmd_q.signal_size = SIZEOF_CMDRSP; \ + x->cmd_q.max_slots = \ + QSLOTSFROMBYTES(x->channel_header.size); \ + x->cmd_q.max_signals = x->cmd_q.max_slots - 1; \ + x->rsp_q.size = QSIZEFROMBYTES(x->channel_header.size); \ + x->rsp_q.sig_base_offset = \ + (SIZEOF_PROTOCOL + x->cmd_q.size) - \ + offsetof(struct spar_io_channel_protocol, rsp_q);\ + x->rsp_q.signal_size = SIZEOF_CMDRSP; \ + x->rsp_q.max_slots = \ + QSLOTSFROMBYTES(x->channel_header.size); \ + x->rsp_q.max_signals = x->rsp_q.max_slots - 1; \ + x->channel_header.ch_space_offset = \ + offsetof(struct spar_io_channel_protocol, cmd_q);\ } while (0) #define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \ do { \ if (clientStr) { \ - chan->ChannelHeader.cli_str_offset = \ - offsetof(type, clientString); \ - memcpy(chan->clientString, clientStr, \ + chan->channel_header.cli_str_offset = \ + offsetof(type, client_string); \ + memcpy(chan->client_string, clientStr, \ MINNUM(clientStrLen, \ (u32)(MAX_CLIENTSTRING_LEN - 1))); \ - chan->clientString[MINNUM(clientStrLen, \ + chan->client_string[MINNUM(clientStrLen, \ (u32)(MAX_CLIENTSTRING_LEN \ - 1))] \ = '\0'; \ @@ -773,68 +774,68 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, \ CHANNELSRV_UNINITIALIZED, logCtx) -static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, +static inline int ULTRA_VHBA_init_channel(struct spar_io_channel_protocol *x, struct vhba_wwnn *wwnn, struct vhba_config_max *max, unsigned char *clientStr, u32 clientStrLen, u64 bytes) { - memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.version_id = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.srv_state = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.header_size = sizeof(x->ChannelHeader); - x->ChannelHeader.size = COVER(bytes, 4096); - x->ChannelHeader.chtype = spar_vhba_channel_protocol_uuid; - x->ChannelHeader.zone_uuid = NULL_UUID_LE; + memset(x, 0, sizeof(struct spar_io_channel_protocol)); + x->channel_header.version_id = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; + x->channel_header.signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; + x->channel_header.srv_state = CHANNELSRV_UNINITIALIZED; + x->channel_header.header_size = sizeof(x->channel_header); + x->channel_header.size = COVER(bytes, 4096); + x->channel_header.chtype = spar_vhba_channel_protocol_uuid; + x->channel_header.zone_uuid = NULL_UUID_LE; x->vhba.wwnn = *wwnn; x->vhba.max = *max; - INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, + INIT_CLIENTSTRING(x, struct spar_io_channel_protocol, clientStr, clientStrLen); SignalQInit(x); - if ((x->cmdQ.max_slots > MAX_NUMSIGNALS) || - (x->rspQ.max_slots > MAX_NUMSIGNALS)) { + if ((x->cmd_q.max_slots > MAX_NUMSIGNALS) || + (x->rsp_q.max_slots > MAX_NUMSIGNALS)) { return 0; } - if ((x->cmdQ.max_slots < MIN_NUMSIGNALS) || - (x->rspQ.max_slots < MIN_NUMSIGNALS)) { + if ((x->cmd_q.max_slots < MIN_NUMSIGNALS) || + (x->rsp_q.max_slots < MIN_NUMSIGNALS)) { return 0; } return 1; } -static inline void ULTRA_VHBA_set_max(ULTRA_IO_CHANNEL_PROTOCOL *x, +static inline void ULTRA_VHBA_set_max(struct spar_io_channel_protocol *x, struct vhba_config_max *max) { x->vhba.max = *max; } -static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, +static inline int ULTRA_VNIC_init_channel(struct spar_io_channel_protocol *x, unsigned char *macaddr, u32 num_rcv_bufs, u32 mtu, uuid_le zoneGuid, unsigned char *clientStr, u32 clientStrLen, u64 bytes) { - memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); - x->ChannelHeader.version_id = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; - x->ChannelHeader.signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; - x->ChannelHeader.srv_state = CHANNELSRV_UNINITIALIZED; - x->ChannelHeader.header_size = sizeof(x->ChannelHeader); - x->ChannelHeader.size = COVER(bytes, 4096); - x->ChannelHeader.chtype = spar_vnic_channel_protocol_uuid; - x->ChannelHeader.zone_uuid = NULL_UUID_LE; + memset(x, 0, sizeof(struct spar_io_channel_protocol)); + x->channel_header.version_id = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; + x->channel_header.signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; + x->channel_header.srv_state = CHANNELSRV_UNINITIALIZED; + x->channel_header.header_size = sizeof(x->channel_header); + x->channel_header.size = COVER(bytes, 4096); + x->channel_header.chtype = spar_vnic_channel_protocol_uuid; + x->channel_header.zone_uuid = NULL_UUID_LE; memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); x->vnic.num_rcv_bufs = num_rcv_bufs; x->vnic.mtu = mtu; - x->vnic.zoneGuid = zoneGuid; - INIT_CLIENTSTRING(x, ULTRA_IO_CHANNEL_PROTOCOL, clientStr, + x->vnic.zone_uuid = zoneGuid; + INIT_CLIENTSTRING(x, struct spar_io_channel_protocol, clientStr, clientStrLen); SignalQInit(x); - if ((x->cmdQ.max_slots > MAX_NUMSIGNALS) || - (x->rspQ.max_slots > MAX_NUMSIGNALS)) { + if ((x->cmd_q.max_slots > MAX_NUMSIGNALS) || + (x->rsp_q.max_slots > MAX_NUMSIGNALS)) { return 0; } - if ((x->cmdQ.max_slots < MIN_NUMSIGNALS) || - (x->rspQ.max_slots < MIN_NUMSIGNALS)) { + if ((x->cmd_q.max_slots < MIN_NUMSIGNALS) || + (x->rsp_q.max_slots < MIN_NUMSIGNALS)) { return 0; } return 1; diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 14948a082934..6e0873455651 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1568,8 +1568,8 @@ uislib_mod_init(void) (ulong) sizeof(struct spar_controlvm_channel_protocol)); LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n", (ulong) sizeof(struct channel_header)); - LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n", - (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL)); + LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n", + (ulong) sizeof(struct spar_io_channel_protocol)); LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP); LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL); diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index eaae4e8b9b45..ee1beb546635 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -171,13 +171,13 @@ struct virtpci_busdev { /*****************************************************/ static inline -int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem *chanptr) +int WAIT_FOR_IO_CHANNEL(struct spar_io_channel_protocol __iomem *chanptr) { int count = 120; while (count > 0) { - if (SPAR_CHANNEL_SERVER_READY(&chanptr->ChannelHeader)) + if (SPAR_CHANNEL_SERVER_READY(&chanptr->channel_header)) return 1; UIS_THREAD_WAIT_SEC(1); count--; @@ -293,11 +293,11 @@ static int add_vbus(struct add_vbus_guestpart *addparams) */ #define GET_SCSIADAPINFO_FROM_CHANPTR(chanptr) { \ memcpy_fromio(&scsi.wwnn, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + &((struct spar_io_channel_protocol __iomem *) \ chanptr)->vhba.wwnn, \ sizeof(struct vhba_wwnn)); \ memcpy_fromio(&scsi.max, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + &((struct spar_io_channel_protocol __iomem *) \ chanptr)->vhba.max, \ sizeof(struct vhba_config_max)); \ } @@ -325,7 +325,7 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *) addparams->chanptr)) { LOGERR("Timed out. Channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -355,17 +355,17 @@ static int add_vhba(struct add_virt_guestpart *addparams) */ #define GET_NETADAPINFO_FROM_CHANPTR(chanptr) { \ memcpy_fromio(net.mac_addr, \ - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + ((struct spar_io_channel_protocol __iomem *) \ chanptr)->vnic.macaddr, \ MAX_MACADDR_LEN); \ net.num_rcv_bufs = \ - readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + readl(&((struct spar_io_channel_protocol __iomem *)\ chanptr)->vnic.num_rcv_bufs); \ - net.mtu = readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ + net.mtu = readl(&((struct spar_io_channel_protocol __iomem *) \ chanptr)->vnic.mtu); \ memcpy_fromio(&net.zoneGuid, \ - &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \ - chanptr)->vnic.zoneGuid, \ + &((struct spar_io_channel_protocol __iomem *)\ + chanptr)->vnic.zone_uuid, \ sizeof(uuid_le)); \ } @@ -382,7 +382,7 @@ add_vnic(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *) addparams->chanptr)) { LOGERR("Timed out, channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -905,7 +905,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, struct virtpci_dev *tmpvpcidev = NULL, *prev; unsigned long flags; int ret; - ULTRA_IO_CHANNEL_PROTOCOL __iomem *pIoChan = NULL; + struct spar_io_channel_protocol __iomem *pIoChan = NULL; struct device *pDev; LOGINF("virtpci_device_add parentbus:%p chanptr:%p\n", parentbus, @@ -946,7 +946,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, virtpcidev->queueinfo.send_int_if_needed = NULL; /* Set up safe queue... */ - pIoChan = (ULTRA_IO_CHANNEL_PROTOCOL __iomem *) + pIoChan = (struct spar_io_channel_protocol __iomem *) virtpcidev->queueinfo.chan; virtpcidev->intr = addparams->intr; -- GitLab From e80f6e3bd6f305fa551526b709e4d319126feb83 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:05 -0400 Subject: [PATCH 1416/9457] staging: unisys: remove unused code from iochannel.h The following macros and functions are unused, and should be deleted: NUMSIGNALS IO_CHANNEL_SIZE QSLOTSFROMBYTES QSIZEFROMBYTES SignalQInit INIT_CLIENTSTRING ULTRA_IO_CHANNEL_SERVER_READY ULTRA_IO_CHANNEL_SERVER_NOTREADY ULTRA_VHBA_init_channel ULTRA_VHBA_set_max ULTRA_VNIC_init_channel Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/iochannel.h | 125 ------------------ 1 file changed, 125 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 071cf72125a1..eb7efe484f6f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -712,136 +712,11 @@ struct spar_io_channel_protocol { * INLINE functions for initializing and accessing I/O data channels */ -#define NUMSIGNALS(x, q) \ - (((struct spar_io_channel_protocol *)(x))->q.MaxSignalSlots) #define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64)) #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) -#define IO_CHANNEL_SIZE(x) COVER(SIZEOF_PROTOCOL + \ - (NUMSIGNALS(x, cmd_q) + \ - NUMSIGNALS(x, rsp_q)) * SIZEOF_CMDRSP, 4096) #define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \ 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096) -#ifdef __GNUC__ -/* These defines should only ever be used in service partitons */ -/* because they rely on the size of uiscmdrsp */ -#define QSLOTSFROMBYTES(bytes) (((bytes-SIZEOF_PROTOCOL)/2)/SIZEOF_CMDRSP) -#define QSIZEFROMBYTES(bytes) (QSLOTSFROMBYTES(bytes)*SIZEOF_CMDRSP) -#define SignalQInit(x) \ - do { \ - x->cmd_q.size = QSIZEFROMBYTES(x->channel_header.size); \ - x->cmd_q.sig_base_offset = SIZEOF_PROTOCOL - \ - offsetof(struct spar_io_channel_protocol, cmd_q);\ - x->cmd_q.signal_size = SIZEOF_CMDRSP; \ - x->cmd_q.max_slots = \ - QSLOTSFROMBYTES(x->channel_header.size); \ - x->cmd_q.max_signals = x->cmd_q.max_slots - 1; \ - x->rsp_q.size = QSIZEFROMBYTES(x->channel_header.size); \ - x->rsp_q.sig_base_offset = \ - (SIZEOF_PROTOCOL + x->cmd_q.size) - \ - offsetof(struct spar_io_channel_protocol, rsp_q);\ - x->rsp_q.signal_size = SIZEOF_CMDRSP; \ - x->rsp_q.max_slots = \ - QSLOTSFROMBYTES(x->channel_header.size); \ - x->rsp_q.max_signals = x->rsp_q.max_slots - 1; \ - x->channel_header.ch_space_offset = \ - offsetof(struct spar_io_channel_protocol, cmd_q);\ - } while (0) - -#define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \ - do { \ - if (clientStr) { \ - chan->channel_header.cli_str_offset = \ - offsetof(type, client_string); \ - memcpy(chan->client_string, clientStr, \ - MINNUM(clientStrLen, \ - (u32)(MAX_CLIENTSTRING_LEN - 1))); \ - chan->client_string[MINNUM(clientStrLen, \ - (u32)(MAX_CLIENTSTRING_LEN \ - - 1))] \ - = '\0'; \ - } \ - else \ - if (clientStrLen > 0) \ - return 0; \ - } while (0) - -#define ULTRA_IO_CHANNEL_SERVER_READY(x, chanId, logCtx) \ - ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, CHANNELSRV_READY, \ - logCtx) - -#define ULTRA_IO_CHANNEL_SERVER_NOTREADY(x, chanId, logCtx) \ - ULTRA_CHANNEL_SERVER_TRANSITION(x, chanId, SrvState, \ - CHANNELSRV_UNINITIALIZED, logCtx) - -static inline int ULTRA_VHBA_init_channel(struct spar_io_channel_protocol *x, - struct vhba_wwnn *wwnn, - struct vhba_config_max *max, - unsigned char *clientStr, - u32 clientStrLen, u64 bytes) { - memset(x, 0, sizeof(struct spar_io_channel_protocol)); - x->channel_header.version_id = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID; - x->channel_header.signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE; - x->channel_header.srv_state = CHANNELSRV_UNINITIALIZED; - x->channel_header.header_size = sizeof(x->channel_header); - x->channel_header.size = COVER(bytes, 4096); - x->channel_header.chtype = spar_vhba_channel_protocol_uuid; - x->channel_header.zone_uuid = NULL_UUID_LE; - x->vhba.wwnn = *wwnn; - x->vhba.max = *max; - INIT_CLIENTSTRING(x, struct spar_io_channel_protocol, clientStr, - clientStrLen); - SignalQInit(x); - if ((x->cmd_q.max_slots > MAX_NUMSIGNALS) || - (x->rsp_q.max_slots > MAX_NUMSIGNALS)) { - return 0; - } - if ((x->cmd_q.max_slots < MIN_NUMSIGNALS) || - (x->rsp_q.max_slots < MIN_NUMSIGNALS)) { - return 0; - } - return 1; -} - -static inline void ULTRA_VHBA_set_max(struct spar_io_channel_protocol *x, - struct vhba_config_max *max) { - x->vhba.max = *max; -} - -static inline int ULTRA_VNIC_init_channel(struct spar_io_channel_protocol *x, - unsigned char *macaddr, - u32 num_rcv_bufs, u32 mtu, - uuid_le zoneGuid, - unsigned char *clientStr, - u32 clientStrLen, - u64 bytes) { - memset(x, 0, sizeof(struct spar_io_channel_protocol)); - x->channel_header.version_id = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID; - x->channel_header.signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE; - x->channel_header.srv_state = CHANNELSRV_UNINITIALIZED; - x->channel_header.header_size = sizeof(x->channel_header); - x->channel_header.size = COVER(bytes, 4096); - x->channel_header.chtype = spar_vnic_channel_protocol_uuid; - x->channel_header.zone_uuid = NULL_UUID_LE; - memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); - x->vnic.num_rcv_bufs = num_rcv_bufs; - x->vnic.mtu = mtu; - x->vnic.zone_uuid = zoneGuid; - INIT_CLIENTSTRING(x, struct spar_io_channel_protocol, clientStr, - clientStrLen); - SignalQInit(x); - if ((x->cmd_q.max_slots > MAX_NUMSIGNALS) || - (x->rsp_q.max_slots > MAX_NUMSIGNALS)) { - return 0; - } - if ((x->cmd_q.max_slots < MIN_NUMSIGNALS) || - (x->rsp_q.max_slots < MIN_NUMSIGNALS)) { - return 0; - } - return 1; -} - -#endif /* __GNUC__ */ /* * INLINE function for expanding a guest's pfn-off-size into multiple 4K page -- GitLab From 8bde404338709f5d34f4123dd94e39d42c1a6957 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:06 -0400 Subject: [PATCH 1417/9457] staging: unisys: clean up UltraVbusChannelProtocol Fix the CamelCase name: UltraVbusChannelProtocolGuid => spar_vbus_channel_protocol_uuid Update related macro names to match. Update references to changed names. Fix indentation in macros where names changed. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/vbuschannel.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 9329e2838fde..aa2b34badf37 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -28,34 +28,34 @@ #include "channel.h" /* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define ULTRA_VBUS_CHANNEL_PROTOCOL_GUID \ +#define SPAR_VBUS_CHANNEL_PROTOCOL_UUID \ UUID_LE(0x193b331b, 0xc58f, 0x11da, \ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le UltraVbusChannelProtocolGuid = - ULTRA_VBUS_CHANNEL_PROTOCOL_GUID; +static const uuid_le spar_vbus_channel_protocol_uuid = + SPAR_VBUS_CHANNEL_PROTOCOL_UUID; -#define ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE +#define SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE /* Must increment this whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this * channel struct so as to break pre-existing software. Note that you can * usually add fields to the END of the channel struct withOUT needing to * increment this. */ -#define ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 +#define SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 #define SPAR_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \ (spar_check_channel_client(pChannel, \ - UltraVbusChannelProtocolGuid, \ + spar_vbus_channel_protocol_uuid, \ "vbus", \ sizeof(struct ultra_vbus_channel_protocol),\ - ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ - ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE)) \ + SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ + SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE)) \ #define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes) \ - (spar_check_channel_server(UltraVbusChannelProtocolGuid, \ - "vbus", \ - sizeof(struct ultra_vbus_channel_protocol),\ - actualBytes)) + (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ + "vbus", \ + sizeof(struct ultra_vbus_channel_protocol),\ + actualBytes)) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ typedef struct _ULTRA_VBUS_HEADERINFO { -- GitLab From 1aa46ce43dc26e69c8e46ac7d97fa0ef55178815 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:07 -0400 Subject: [PATCH 1418/9457] staging: unisys: fix parameters for SPAR_VBUS_CHANNEL_OK_CLIENT macro Remove the unused logCtx parameter and fix the CamelCase name: pChannel => ch Update calls to the macro to remove the unused second parameter. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/vbuschannel.h | 14 +++++++------- drivers/staging/unisys/uislib/uislib.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index aa2b34badf37..c1a73df43f35 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -43,13 +43,13 @@ static const uuid_le spar_vbus_channel_protocol_uuid = * increment this. */ #define SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID 1 -#define SPAR_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \ - (spar_check_channel_client(pChannel, \ - spar_vbus_channel_protocol_uuid, \ - "vbus", \ - sizeof(struct ultra_vbus_channel_protocol),\ - SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ - SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE)) \ +#define SPAR_VBUS_CHANNEL_OK_CLIENT(ch) \ + spar_check_channel_client(ch, \ + spar_vbus_channel_protocol_uuid, \ + "vbus", \ + sizeof(struct ultra_vbus_channel_protocol),\ + SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ + SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) #define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes) \ (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 6e0873455651..354b6827bac4 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -142,7 +142,7 @@ init_vbus_channel(u64 channelAddr, u32 channelBytes) rc = NULL; goto Away; } - if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) { + if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan)) { ERRDRV("%s channel cannot be used", __func__); uislib_iounmap(pChan); rc = NULL; -- GitLab From 9b8a8a96b7b41fac458fab603f51ec562b31ae21 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:08 -0400 Subject: [PATCH 1419/9457] staging: unisys: refactor ULTRA_VBUS_CHANNEL_OK_SERVER Fix the name to SPAR_VBUS_CHANNEL_OK_SERVER and fix the CamelCase parameter: actualBytes => actual_bytes Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/common-spar/include/channels/vbuschannel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index c1a73df43f35..873ba76253dd 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -51,11 +51,11 @@ static const uuid_le spar_vbus_channel_protocol_uuid = SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) -#define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes) \ +#define SPAR_VBUS_CHANNEL_OK_SERVER(actual_bytes) \ (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ "vbus", \ sizeof(struct ultra_vbus_channel_protocol),\ - actualBytes)) + actual_bytes)) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ typedef struct _ULTRA_VBUS_HEADERINFO { -- GitLab From 1cb3b9de239b2aecfa3326401f2214e9c4770158 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:09 -0400 Subject: [PATCH 1420/9457] staging: unisys: refactor ULTRA_VBUS_HEADERINFO Remove the typedef and rename to struct spar_vbus_headerinfo. Fix CamelCase member names: structBytes => struct_bytes deviceInfoStructBytes => device_info_struct_bytes devInfoCount => dev_info_count chpInfoByteOffset => chp_info_offset busInfoByteOffset => bus_info_offset devInfoByteOffset => dev_info_offset Update all references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/vbuschannel.h | 18 ++++++++--------- drivers/staging/unisys/virtpci/virtpci.c | 20 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 873ba76253dd..360fba67da15 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -58,23 +58,23 @@ static const uuid_le spar_vbus_channel_protocol_uuid = actual_bytes)) #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ -typedef struct _ULTRA_VBUS_HEADERINFO { - u32 structBytes; /* size of this struct in bytes */ - u32 deviceInfoStructBytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */ - u32 devInfoCount; /* num of items in DevInfo member */ +struct spar_vbus_headerinfo { + u32 struct_bytes; /* size of this struct in bytes */ + u32 device_info_struct_bytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */ + u32 dev_info_count; /* num of items in DevInfo member */ /* (this is the allocated size) */ - u32 chpInfoByteOffset; /* byte offset from beginning of this struct */ + u32 chp_info_offset; /* byte offset from beginning of this struct */ /* to the ChpInfo struct (below) */ - u32 busInfoByteOffset; /* byte offset from beginning of this struct */ + u32 bus_info_offset; /* byte offset from beginning of this struct */ /* to the BusInfo struct (below) */ - u32 devInfoByteOffset; /* byte offset from beginning of this struct */ + u32 dev_info_offset; /* byte offset from beginning of this struct */ /* to the DevInfo array (below) */ u8 reserved[104]; -} ULTRA_VBUS_HEADERINFO; +}; struct ultra_vbus_channel_protocol { struct channel_header ChannelHeader; /* initialized by server */ - ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */ + struct spar_vbus_headerinfo HdrInfo; /* initialized by server */ /* the remainder of this channel is filled in by the client */ struct ultra_vbus_deviceinfo ChpInfo; /* describes client chipset device and driver */ diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index ee1beb546635..36174628af41 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -195,9 +195,9 @@ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(struct channel_header) + chan->HdrInfo.chpInfoByteOffset; - if (chan->HdrInfo.chpInfoByteOffset == 0) { - LOGERR("vbus channel not used, because chpInfoByteOffset == 0"); + off = sizeof(struct channel_header) + chan->HdrInfo.chp_info_offset; + if (chan->HdrInfo.chp_info_offset == 0) { + LOGERR("vbus channel not used, because chp_info_offset == 0"); return -1; } memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); @@ -214,9 +214,9 @@ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(struct channel_header) + chan->HdrInfo.busInfoByteOffset; - if (chan->HdrInfo.busInfoByteOffset == 0) { - LOGERR("vbus channel not used, because busInfoByteOffset == 0"); + off = sizeof(struct channel_header) + chan->HdrInfo.bus_info_offset; + if (chan->HdrInfo.bus_info_offset == 0) { + LOGERR("vbus channel not used, because bus_info_offset == 0"); return -1; } memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); @@ -238,10 +238,10 @@ write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, } off = (sizeof(struct channel_header) + - chan->HdrInfo.devInfoByteOffset) + - (chan->HdrInfo.deviceInfoStructBytes * devix); - if (chan->HdrInfo.devInfoByteOffset == 0) { - LOGERR("vbus channel not used, because devInfoByteOffset == 0"); + chan->HdrInfo.dev_info_offset) + + (chan->HdrInfo.device_info_struct_bytes * devix); + if (chan->HdrInfo.dev_info_offset == 0) { + LOGERR("vbus channel not used, because dev_info_offset == 0"); return -1; } memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); -- GitLab From a02fd66ec80d25ff9c792e96bdc895e4b8e0935b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Thu, 23 Oct 2014 14:31:10 -0400 Subject: [PATCH 1421/9457] staging: unisys: refactor struct struct ultra_vbus_channel_protocol Rename the struct to spar_vbus_channel_protocol. Fix CamelCase member names: ChannelHeader => channel_header HdrInfo => hdr_info ChpInfo => chp_info BusInfo => bus_info DevInfo => dev_info Update all references to use the changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/channels/vbuschannel.h | 22 +++++++++---------- drivers/staging/unisys/virtpci/virtpci.c | 20 ++++++++--------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 360fba67da15..2c42ce16e0cf 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -45,11 +45,11 @@ static const uuid_le spar_vbus_channel_protocol_uuid = #define SPAR_VBUS_CHANNEL_OK_CLIENT(ch) \ spar_check_channel_client(ch, \ - spar_vbus_channel_protocol_uuid, \ - "vbus", \ - sizeof(struct ultra_vbus_channel_protocol),\ - SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ - SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) + spar_vbus_channel_protocol_uuid, \ + "vbus", \ + sizeof(struct spar_vbus_channel_protocol),\ + SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ + SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) #define SPAR_VBUS_CHANNEL_OK_SERVER(actual_bytes) \ (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ @@ -72,15 +72,15 @@ struct spar_vbus_headerinfo { u8 reserved[104]; }; -struct ultra_vbus_channel_protocol { - struct channel_header ChannelHeader; /* initialized by server */ - struct spar_vbus_headerinfo HdrInfo; /* initialized by server */ +struct spar_vbus_channel_protocol { + struct channel_header channel_header; /* initialized by server */ + struct spar_vbus_headerinfo hdr_info; /* initialized by server */ /* the remainder of this channel is filled in by the client */ - struct ultra_vbus_deviceinfo ChpInfo; + struct ultra_vbus_deviceinfo chp_info; /* describes client chipset device and driver */ - struct ultra_vbus_deviceinfo BusInfo; + struct ultra_vbus_deviceinfo bus_info; /* describes client bus device and driver */ - struct ultra_vbus_deviceinfo DevInfo[0]; + struct ultra_vbus_deviceinfo dev_info[0]; /* describes client device and driver for each device on the bus */ }; diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 36174628af41..6fa8caf5381e 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -186,7 +186,7 @@ int WAIT_FOR_IO_CHANNEL(struct spar_io_channel_protocol __iomem *chanptr) } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */ -static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, +static int write_vbus_chpInfo(struct spar_vbus_channel_protocol *chan, struct ultra_vbus_deviceinfo *info) { int off; @@ -195,8 +195,8 @@ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(struct channel_header) + chan->HdrInfo.chp_info_offset; - if (chan->HdrInfo.chp_info_offset == 0) { + off = sizeof(struct channel_header) + chan->hdr_info.chp_info_offset; + if (chan->hdr_info.chp_info_offset == 0) { LOGERR("vbus channel not used, because chp_info_offset == 0"); return -1; } @@ -205,7 +205,7 @@ static int write_vbus_chpInfo(struct ultra_vbus_channel_protocol *chan, } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */ -static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, +static int write_vbus_busInfo(struct spar_vbus_channel_protocol *chan, struct ultra_vbus_deviceinfo *info) { int off; @@ -214,8 +214,8 @@ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, LOGERR("vbus channel not present"); return -1; } - off = sizeof(struct channel_header) + chan->HdrInfo.bus_info_offset; - if (chan->HdrInfo.bus_info_offset == 0) { + off = sizeof(struct channel_header) + chan->hdr_info.bus_info_offset; + if (chan->hdr_info.bus_info_offset == 0) { LOGERR("vbus channel not used, because bus_info_offset == 0"); return -1; } @@ -227,7 +227,7 @@ static int write_vbus_busInfo(struct ultra_vbus_channel_protocol *chan, * ULTRA_VBUS_CHANNEL_PROTOCOL.DevInfo[]. */ static int -write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, +write_vbus_devInfo(struct spar_vbus_channel_protocol *chan, struct ultra_vbus_deviceinfo *info, int devix) { int off; @@ -238,9 +238,9 @@ write_vbus_devInfo(struct ultra_vbus_channel_protocol *chan, } off = (sizeof(struct channel_header) + - chan->HdrInfo.dev_info_offset) + - (chan->HdrInfo.device_info_struct_bytes * devix); - if (chan->HdrInfo.dev_info_offset == 0) { + chan->hdr_info.dev_info_offset) + + (chan->hdr_info.device_info_struct_bytes * devix); + if (chan->hdr_info.dev_info_offset == 0) { LOGERR("vbus channel not used, because dev_info_offset == 0"); return -1; } -- GitLab From 5c1e9f2c1ff7ed91c03906e0bf1d7fbbddae3970 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 25 Oct 2014 17:27:09 +0200 Subject: [PATCH 1422/9457] xfrm: fix set but not used warning in xfrm_policy_queue_process() err was set but unused. Signed-off-by: Fabian Frederick Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_policy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 4c4e457e7888..dc653249e845 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1878,7 +1878,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, static void xfrm_policy_queue_process(unsigned long arg) { - int err = 0; struct sk_buff *skb; struct sock *sk; struct dst_entry *dst; @@ -1941,7 +1940,7 @@ static void xfrm_policy_queue_process(unsigned long arg) skb_dst_drop(skb); skb_dst_set(skb, dst); - err = dst_output(skb); + dst_output(skb); } out: -- GitLab From 1998d90ad424c1ff12ea24816ce158d5262e06a5 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:00 -0700 Subject: [PATCH 1423/9457] cfg80211: support creating wiphy with suggested name Kernel will attempt to use the name if it is supplied, but if name cannot be used for some reason, the default phyX name will be used instead. Signed-off-by: Ben Greear [while at it, use wiphy_name() instead of dev_name(), fix format string issue reported by Kees Cook] Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 23 +++++++++++++++- net/wireless/core.c | 60 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 77aa805d7e7c..39d7996b0609 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3184,6 +3184,23 @@ static inline const char *wiphy_name(const struct wiphy *wiphy) return dev_name(&wiphy->dev); } +/** + * wiphy_new_nm - create a new wiphy for use with cfg80211 + * + * @ops: The configuration operations for this device + * @sizeof_priv: The size of the private area to allocate + * @requested_name: Request a particular name. + * NULL is valid value, and means use the default phy%d naming. + * + * Create a new wiphy and associate the given operations with it. + * @sizeof_priv bytes are allocated for private use. + * + * Return: A pointer to the new wiphy. This pointer must be + * assigned to each netdev's ieee80211_ptr for proper operation. + */ +struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, + const char *requested_name); + /** * wiphy_new - create a new wiphy for use with cfg80211 * @@ -3196,7 +3213,11 @@ static inline const char *wiphy_name(const struct wiphy *wiphy) * Return: A pointer to the new wiphy. This pointer must be * assigned to each netdev's ieee80211_ptr for proper operation. */ -struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); +static inline struct wiphy *wiphy_new(const struct cfg80211_ops *ops, + int sizeof_priv) +{ + return wiphy_new_nm(ops, sizeof_priv, NULL); +} /** * wiphy_register - register a wiphy with cfg80211 diff --git a/net/wireless/core.c b/net/wireless/core.c index f52a4cd7017c..87bb502bc8de 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -86,11 +86,11 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) return &rdev->wiphy; } -int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, - char *newname) +static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, + const char *newname) { struct cfg80211_registered_device *rdev2; - int wiphy_idx, taken = -1, result, digits; + int wiphy_idx, taken = -1, digits; ASSERT_RTNL(); @@ -109,15 +109,28 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, return -EINVAL; } + /* Ensure another device does not already have this name. */ + list_for_each_entry(rdev2, &cfg80211_rdev_list, list) + if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0) + return -EINVAL; + + return 0; +} + +int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, + char *newname) +{ + int result; + + ASSERT_RTNL(); /* Ignore nop renames */ - if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) + if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0) return 0; - /* Ensure another device does not already have this name. */ - list_for_each_entry(rdev2, &cfg80211_rdev_list, list) - if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) - return -EINVAL; + result = cfg80211_dev_check_name(rdev, newname); + if (result < 0) + return result; result = device_rename(&rdev->wiphy.dev, newname); if (result) @@ -309,7 +322,8 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work) /* exported functions */ -struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) +struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, + const char *requested_name) { static atomic_t wiphy_counter = ATOMIC_INIT(0); @@ -346,7 +360,31 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) rdev->wiphy_idx--; /* give it a proper name */ - dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + if (requested_name && requested_name[0]) { + int rv; + + rtnl_lock(); + rv = cfg80211_dev_check_name(rdev, requested_name); + + if (rv < 0) { + rtnl_unlock(); + goto use_default_name; + } + + rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name); + rtnl_unlock(); + if (rv) + goto use_default_name; + } else { +use_default_name: + /* NOTE: This is *probably* safe w/out holding rtnl because of + * the restrictions on phy names. Probably this call could + * fail if some other part of the kernel (re)named a device + * phyX. But, might should add some locking and check return + * value, and use a different name if this one exists? + */ + dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); + } INIT_LIST_HEAD(&rdev->wdev_list); INIT_LIST_HEAD(&rdev->beacon_registrations); @@ -406,7 +444,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) return &rdev->wiphy; } -EXPORT_SYMBOL(wiphy_new); +EXPORT_SYMBOL(wiphy_new_nm); static int wiphy_verify_combinations(struct wiphy *wiphy) { -- GitLab From ad28757eef268e609677d0e3d8c0bdadde52a711 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:01 -0700 Subject: [PATCH 1424/9457] mac80211: allow creating wiphy devices with suggested name Support creating wiphy devices with an optional name. This will be used by hwsim to have better automated control over virtual radio creation/deletion. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- include/net/mac80211.h | 28 ++++++++++++++++++++++++++-- net/mac80211/main.c | 9 +++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2b7426a90ff0..bb50e8beec0e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3063,7 +3063,7 @@ struct ieee80211_ops { }; /** - * ieee80211_alloc_hw - Allocate a new hardware device + * ieee80211_alloc_hw_nm - Allocate a new hardware device * * This must be called once for each hardware device. The returned pointer * must be used to refer to this device when calling other functions. @@ -3073,11 +3073,35 @@ struct ieee80211_ops { * * @priv_data_len: length of private data * @ops: callbacks for this device + * @requested_name: Requested name for this device. + * NULL is valid value, and means use the default naming (phy%d) * * Return: A pointer to the new hardware device, or %NULL on error. */ +struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + const struct ieee80211_ops *ops, + const char *requested_name); + +/** + * ieee80211_alloc_hw - Allocate a new hardware device + * + * This must be called once for each hardware device. The returned pointer + * must be used to refer to this device when calling other functions. + * mac80211 allocates a private data area for the driver pointed to by + * @priv in &struct ieee80211_hw, the size of this area is given as + * @priv_data_len. + * + * @priv_data_len: length of private data + * @ops: callbacks for this device + * + * Return: A pointer to the new hardware device, or %NULL on error. + */ +static inline struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - const struct ieee80211_ops *ops); + const struct ieee80211_ops *ops) +{ + return ieee80211_alloc_hw_nm(priv_data_len, ops, NULL); +} /** * ieee80211_register_hw - Register hardware device diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9e322dce64ec..b189122d4b20 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -478,8 +478,9 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = { }, }; -struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - const struct ieee80211_ops *ops) +struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + const struct ieee80211_ops *ops, + const char *requested_name) { struct ieee80211_local *local; int priv_size, i; @@ -519,7 +520,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, */ priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; - wiphy = wiphy_new(&mac80211_config_ops, priv_size); + wiphy = wiphy_new_nm(&mac80211_config_ops, priv_size, requested_name); if (!wiphy) return NULL; @@ -649,7 +650,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, return &local->hw; } -EXPORT_SYMBOL(ieee80211_alloc_hw); +EXPORT_SYMBOL(ieee80211_alloc_hw_nm); static int ieee80211_init_cipher_suites(struct ieee80211_local *local) { -- GitLab From 5cd8926bbf47ee0eb51a266bd9614dd3f93c004f Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:02 -0700 Subject: [PATCH 1425/9457] mac80211-hwsim: support creating radios with specific name Otherwise, it can be very difficult to know which is which if you are trying to do detailed testing. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e9f7c1ec50a4..23f184dbfec6 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2023,7 +2023,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, const struct ieee80211_regdomain *regd, bool reg_strict, bool p2p_device, bool use_chanctx, bool destroy_on_close, - u32 portid) + u32 portid, const char *hwname) { int err; u8 addr[ETH_ALEN]; @@ -2042,7 +2042,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, if (use_chanctx) ops = &mac80211_hwsim_mchan_ops; - hw = ieee80211_alloc_hw(sizeof(*data), ops); + hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, hwname); if (!hw) { printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n"); err = -ENOMEM; @@ -2516,10 +2516,14 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; bool use_chanctx; + const char *hwname = NULL; if (info->attrs[HWSIM_ATTR_CHANNELS]) chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); + if (info->attrs[HWSIM_ATTR_RADIO_NAME]) + hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); + if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) use_chanctx = true; else @@ -2538,7 +2542,8 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, p2p_device, use_chanctx, - destroy_on_close, info->snd_portid); + destroy_on_close, info->snd_portid, + hwname); } static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) @@ -2794,7 +2799,7 @@ static int __init init_mac80211_hwsim(void) err = mac80211_hwsim_create_radio(channels, reg_alpha2, regd, reg_strict, support_p2p_device, - channels > 1, false, 0); + channels > 1, false, 0, NULL); if (err < 0) goto out_free_radios; } -- GitLab From e27513fbd030d8558cfa9250bd62b2baf19dc114 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:03 -0700 Subject: [PATCH 1426/9457] mac80211: support creating wiphy w/out creating wlanX This will be helpful when using the mac80211_hwsim wiphys and automated testing. Let user create the vifs as needed, and named as expected. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- include/net/mac80211.h | 7 ++++++- net/mac80211/main.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index bb50e8beec0e..1614b2fc3bf6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1583,6 +1583,10 @@ struct ieee80211_tx_control { * a virtual monitor interface when monitor interfaces are the only * active interfaces. * + * @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to + * be created. It is expected user-space will create vifs as + * desired (and thus have them named as desired). + * * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface * queue mapping in order to use different queues (not just one per AC) * for different virtual interfaces. See the doc section on HW queue @@ -1629,7 +1633,8 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, IEEE80211_HW_MFP_CAPABLE = 1<<13, IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, - /* free slots */ + IEEE80211_HW_NO_AUTO_VIF = 1<<15, + /* free slot */ IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b189122d4b20..7d40e3f0a77b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1023,7 +1023,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } /* add one default STA interface if supported */ - if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && + !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) { result = ieee80211_if_add(local, "wlan%d", NULL, NL80211_IFTYPE_STATION, NULL); if (result) -- GitLab From 9a0cb89a8aad7c04505abf88202b1dd376fc50bc Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:04 -0700 Subject: [PATCH 1427/9457] mac80211-hwsim: support creating wiphy w/out creating wlanX Good for automated testing, where user can create wlan interfaces with specified names. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 15 ++++++++++++--- drivers/net/wireless/mac80211_hwsim.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 23f184dbfec6..d109e5050857 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2023,7 +2023,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, const struct ieee80211_regdomain *regd, bool reg_strict, bool p2p_device, bool use_chanctx, bool destroy_on_close, - u32 portid, const char *hwname) + u32 portid, const char *hwname, + bool no_vif) { int err; u8 addr[ETH_ALEN]; @@ -2230,6 +2231,9 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, schedule_timeout_interruptible(1); } + if (no_vif) + hw->flags |= IEEE80211_HW_NO_AUTO_VIF; + err = ieee80211_register_hw(hw); if (err < 0) { printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n", @@ -2516,11 +2520,15 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; bool use_chanctx; + bool no_vif = false; const char *hwname = NULL; if (info->attrs[HWSIM_ATTR_CHANNELS]) chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); + if (info->attrs[HWSIM_ATTR_NO_VIF]) + no_vif = true; + if (info->attrs[HWSIM_ATTR_RADIO_NAME]) hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); @@ -2543,7 +2551,7 @@ static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, p2p_device, use_chanctx, destroy_on_close, info->snd_portid, - hwname); + hwname, no_vif); } static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) @@ -2799,7 +2807,8 @@ static int __init init_mac80211_hwsim(void) err = mac80211_hwsim_create_radio(channels, reg_alpha2, regd, reg_strict, support_p2p_device, - channels > 1, false, 0, NULL); + channels > 1, false, 0, NULL, + false); if (err < 0) goto out_free_radios; } diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 98c69984878d..f560b7493968 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -114,6 +114,7 @@ enum { * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO * command to force radio removal when process that created the radio dies * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 + * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. * @__HWSIM_ATTR_MAX: enum limit */ @@ -137,6 +138,7 @@ enum { HWSIM_ATTR_USE_CHANCTX, HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, HWSIM_ATTR_RADIO_NAME, + HWSIM_ATTR_NO_VIF, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) -- GitLab From e8f479b11268af3f206d1580f6b0d572d6ecb4f7 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:05 -0700 Subject: [PATCH 1428/9457] cfg80211: support configuring vif mac addr on create This is useful when creating virtual interfaces. Keeps udev from mucking with things it shouldn't, since the default MAC is never seen by udev when specified on the cmd-line during creation. Signed-off-by: Ben Greear [check for feature flag in nl80211 to force drivers to set it] Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 9 ++++++--- include/uapi/linux/nl80211.h | 4 ++++ net/wireless/nl80211.c | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 39d7996b0609..f67948e18600 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -319,9 +319,12 @@ struct ieee80211_supported_band { /** * struct vif_params - describes virtual interface parameters * @use_4addr: use 4-address frames - * @macaddr: address to use for this virtual interface. This will only - * be used for non-netdevice interfaces. If this parameter is set - * to zero address the driver may determine the address as needed. + * @macaddr: address to use for this virtual interface. + * If this parameter is set to zero address the driver may + * determine the address as needed. + * This feature is only fully supported by drivers that enable the + * %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating + ** only p2p devices with specified MAC. */ struct vif_params { int use_4addr; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index be1d5def304d..f7daae59248e 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4056,6 +4056,9 @@ enum nl80211_ap_sme_features { * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it * needs to be able to handle Block-Ack agreements and other things. + * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring + * the vif's MAC address upon creation. + * See 'macaddr' field in the vif_params (cfg80211.h). */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4085,6 +4088,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_STATIC_SMPS = 1 << 24, NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, + NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d98d4ea27819..12736a7cd506 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2605,7 +2605,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) !(rdev->wiphy.interface_modes & (1 << type))) return -EOPNOTSUPP; - if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) { + if ((type == NL80211_IFTYPE_P2P_DEVICE || + rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) && + info->attrs[NL80211_ATTR_MAC]) { nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], ETH_ALEN); if (!is_valid_ether_addr(params.macaddr)) -- GitLab From b5dfae020b3539feaa014d3b6152f48660c2d75b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 22 Oct 2014 12:23:06 -0700 Subject: [PATCH 1429/9457] mac80211: support creating vifs with specified mac address This is useful when creating virtual interfaces. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 5 ++++- net/mac80211/main.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e469b3390f2a..1ffcc0701244 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1671,7 +1671,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, } ieee80211_assign_perm_addr(local, ndev->perm_addr, type); - memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); + if (params && is_valid_ether_addr(params->macaddr)) + memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN); + else + memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7d40e3f0a77b..282a4f36eb92 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -542,6 +542,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, NL80211_FEATURE_SAE | NL80211_FEATURE_HT_IBSS | NL80211_FEATURE_VIF_TXPOWER | + NL80211_FEATURE_MAC_ON_CREATE | NL80211_FEATURE_USERSPACE_MPM; if (!ops->hw_scan) -- GitLab From cfede0d80d785cc6d972cad2df2df0a502312d25 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 20 Oct 2014 15:57:18 +0300 Subject: [PATCH 1430/9457] mac80211: don't flush when probing the AP All the callers of ieee80211_mgd_probe_ap_send return right after they call the flush() callback. This means that calling flush() is uneeded since its meaning is to wait until the queues of the device are empty. Devices that know how to report status on Tx will do so using the regular path (ieee80211_tx_status) and this status will trigger the continuation of the flow of the probe (ieee80211_sta_tx_notify). Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d9b4d165ce8..c078cd344ca4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2207,8 +2207,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); run_again(sdata, ifmgd->probe_timeout); - if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) - ieee80211_flush_queues(sdata->local, sdata); } static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, -- GitLab From 9ffe904405580fa54f935e2a30fb7b2c9328f9ff Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Fri, 24 Oct 2014 14:34:49 +0200 Subject: [PATCH 1431/9457] mac80211: minstrel_ht: do not always skip ht rates vht_only is true When CONFIG_MAC80211_RC_MINSTREL_VHT is set, the module param minstrel_vht_only tells minstrel_ht whether to allow the mix of ht rates with vht rates. ATM, minstrel_ht skips ht rates when minstrel_vht_only is true, but it does that even if vht is not supported, which makes the sta rates fallback to legacy as no ht rate gets enabled. Fixes: 9208247d74bc ("mac80211: minstrel_ht: add basic support for VHT rates <= 3SS@80MHz") Signed-off-by: Karl Beldan Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 46666818719b..c50fd94d2aef 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1193,7 +1193,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, /* HT rate */ if (gflags & IEEE80211_TX_RC_MCS) { #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT - if (minstrel_vht_only) + if (use_vht && minstrel_vht_only) continue; #endif mi->groups[i].supported = mcs->rx_mask[nss - 1]; -- GitLab From 94d2fc6361a75b61a0753114e52379f1c900fb30 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Sat, 25 Oct 2014 11:56:29 +0530 Subject: [PATCH 1432/9457] Staging: rtl8723au: Use USB API functions This patch replaces driver specific functions(RT_usb_endpoint_is_bulk_in, RT_usb_endpoint_is_bulk_out, RT_usb_endpoint_is_int_in) with USB API functions(usb_endpoint_is_bulk_in, usb_endpoint_is_bulk_out, usb_endpoint_is_int_in). Also, this patch removes these three RT functions as they are no longer needed after replacement. This patch also have one line over 80 characters as limiting it to 80 characters does not make code look good. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/os_dep/usb_intf.c | 27 +++++---------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c index 865743ecd855..08424d478039 100644 --- a/drivers/staging/rtl8723au/os_dep/usb_intf.c +++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c @@ -59,21 +59,6 @@ static struct usb_driver rtl8723a_usb_drv = { static struct usb_driver *usb_drv = &rtl8723a_usb_drv; -static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); -} - -static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); -} - -static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) -{ - return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); -} - static int rtw_init_intf_priv(struct dvobj_priv *dvobj) { mutex_init(&dvobj->usb_vendor_req_mutex); @@ -143,21 +128,21 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) le16_to_cpu(pendp_desc->wMaxPacketSize)); DBG_8723A("bInterval =%x\n", pendp_desc->bInterval); - if (RT_usb_endpoint_is_bulk_in(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n", + if (usb_endpoint_is_bulk_in(pendp_desc)) { + DBG_8723A("usb_endpoint_is_bulk_in = %x\n", usb_endpoint_num(pendp_desc)); pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = usb_endpoint_num(pendp_desc); pdvobjpriv->RtNumInPipes++; - } else if (RT_usb_endpoint_is_int_in(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", + } else if (usb_endpoint_is_int_in(pendp_desc)) { + DBG_8723A("usb_endpoint_is_int_in = %x, Interval = %x\n", usb_endpoint_num(pendp_desc), pendp_desc->bInterval); pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = usb_endpoint_num(pendp_desc); pdvobjpriv->RtNumInPipes++; - } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) { - DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n", + } else if (usb_endpoint_is_bulk_out(pendp_desc)) { + DBG_8723A("usb_endpoint_is_bulk_out = %x\n", usb_endpoint_num(pendp_desc)); pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = usb_endpoint_num(pendp_desc); -- GitLab From 8a0aa750c1e8626808775bb7a55d6ae6bb1111cd Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 20:07:52 +0800 Subject: [PATCH 1433/9457] staging: rtl8723au: delete successive assignments to the same location Successive assignments to the same location is meaningless and can be deleted. The Coccinelle semantic patch was used to find cases. @@ expression e1,e2,e3; @@ ( (<+...e1++...+>)=e2; | (<+...e1--...+>)=e2; | (<+...++e1...+>)=e2; | (<+...--e1...+>)=e2; | e1=e2; e1 = <+...e1...+>; | *e1=e2; *e1=e3; ) Signed-off-by: Jiayi Ye Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 2 -- drivers/staging/rtl8723au/hal/usb_halinit.c | 1 - drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | 1 - 3 files changed, 4 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 86f5217afe93..10f8031e29cf 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -2339,8 +2339,6 @@ static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) switch (hidden_ssid_mode) { case 1: next_ie = ssid_ie + 2 + ssid_len_ori; - remain_len = 0; - remain_len = ies_len -(next_ie-ies); ssid_ie[1] = 0; diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index a5de03d45aa9..6c1dcf0b0d7d 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -1485,7 +1485,6 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter, } /* mask &= 0x0fffffff; */ - rate_bitmap = 0x0fffffff; rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask, rssi_level); DBG_8723A("%s => mac_id:%d, networkType:0x%02x, " diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index 2f01714bc9e2..e154de9b656b 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c @@ -2363,7 +2363,6 @@ void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, ie_offset = offsetof(struct ieee80211_mgmt, u.reassoc_req.variable); - sinfo.filled = 0; sinfo.filled = STATION_INFO_ASSOC_REQ_IES; sinfo.assoc_req_ies = pmgmt_frame + ie_offset; sinfo.assoc_req_ies_len = frame_len - ie_offset; -- GitLab From de1de2f68b2be51cdc90e920cb9173598a88a9c0 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Sat, 25 Oct 2014 16:56:01 -0700 Subject: [PATCH 1434/9457] Staging: rtl8723au: core: Add braces around macro This patch fixes the following checkpatch warning: ERROR: Macros with complex values should be enclosed in parentheses 1535: FILE: drivers/staging/rtl8723au/core/rtw_mlme.c:1535: Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 21484e757b15..ba201300cc1f 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -1532,7 +1532,8 @@ void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms) } #if defined(IEEE80211_SCAN_RESULT_EXPIRE) -#define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 /* 3000 -1000 */ +#define RTW_SCAN_RESULT_EXPIRE \ + ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */ #else #define RTW_SCAN_RESULT_EXPIRE 2000 #endif -- GitLab From 08551cbb176afa0d71d4a059b2893c6575e8a8ad Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:05 +0200 Subject: [PATCH 1435/9457] staging: rtl8723au: Do not use comparisons on bool tests This patch removes unnecessary comparisons to bool. It fixes the following warning detected using coccinelle tool: WARNING: Comparison to bool. Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 2 +- drivers/staging/rtl8723au/core/rtw_cmd.c | 2 +- drivers/staging/rtl8723au/core/rtw_mlme.c | 2 +- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 2 +- drivers/staging/rtl8723au/core/rtw_pwrctrl.c | 2 +- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 2 +- drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c | 2 +- drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c | 4 ++-- drivers/staging/rtl8723au/hal/usb_halinit.c | 2 +- drivers/staging/rtl8723au/include/rtw_mlme.h | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index 6a336cd2eb4d..d00255fbfcbc 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -1605,7 +1605,7 @@ u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool acti if (!psta) return beacon_updated; - if (active == true) { + if (active) { /* tear down Rx AMPDU */ send_delba23a(padapter, 0, psta->hwaddr);/* recipient */ diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index 01b44a4364dc..424d96a1859a 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -1149,7 +1149,7 @@ static void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter) val = rtl8723a_chk_hi_queue_empty(padapter); - while (val == false) { + while (!val) { msleep(100); cnt++; diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index ba201300cc1f..4e2b22d97101 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -1121,7 +1121,7 @@ void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf) if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { /* s1. find ptarget_wlan */ if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (the_same_macaddr == true) { + if (the_same_macaddr) { ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); } else { pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 10f8031e29cf..2624c778eff7 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -3999,7 +3999,7 @@ int send_beacon23a(struct rtw_adapter *padapter) yield(); bxmitok = rtl8723a_get_bcn_valid(padapter); poll++; - } while ((poll % 10) != 0 && bxmitok == false && + } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c index 1eae885c1170..e2d51afe522c 100644 --- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c @@ -159,7 +159,7 @@ void rtw_ps_processor23a(struct rtw_adapter *padapter) if (pwrpriv->ips_mode_req == IPS_NONE) goto exit; - if (rtw_pwr_unassociated_idle(padapter) == false) + if (!rtw_pwr_unassociated_idle(padapter)) goto exit; if (pwrpriv->rf_pwrstate == rf_on && diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index c0325c96d616..bc63d6f1773a 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -866,7 +866,7 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter, int pie_len, ssid_len, privacy; const u8 *p, *ssid; - if (is_client_associated_to_ap23a(Adapter) == false) + if (!is_client_associated_to_ap23a(Adapter)) return _SUCCESS; if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) { diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c index 4b41bc4ce1e6..179a1ba03029 100644 --- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c @@ -612,7 +612,7 @@ static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, bool isP u32 i; pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2T) { + if (!is2T) { pathOn = 0x0bdb25a0; PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, 0x0b1b25a0); } else { diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index 8523908d5e5f..1ccf60a9e528 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -1945,13 +1945,13 @@ Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, /* */ /* ThermalMeter from EEPROM */ /* */ - if (AutoloadFail == false) + if (!AutoloadFail) pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723A]; else pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; - if ((pHalData->EEPROMThermalMeter == 0xff) || (AutoloadFail == true)) { + if ((pHalData->EEPROMThermalMeter == 0xff) || AutoloadFail) { pHalData->bAPKThermalMeterIgnore = true; pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; } diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c index 6c1dcf0b0d7d..adc2953fcaf4 100644 --- a/drivers/staging/rtl8723au/hal/usb_halinit.c +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c @@ -480,7 +480,7 @@ static void _InitRFType(struct rtw_adapter *Adapter) pHalData->rf_chip = RF_6052; - if (is92CU == false) { + if (!is92CU) { pHalData->rf_type = RF_1T1R; DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n"); return; diff --git a/drivers/staging/rtl8723au/include/rtw_mlme.h b/drivers/staging/rtl8723au/include/rtw_mlme.h index 2ff01eb8fc0c..a6751f138336 100644 --- a/drivers/staging/rtl8723au/include/rtw_mlme.h +++ b/drivers/staging/rtl8723au/include/rtw_mlme.h @@ -270,7 +270,7 @@ static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state) static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state) { spin_lock_bh(&pmlmepriv->lock); - if (check_fwstate(pmlmepriv, state) == true) + if (check_fwstate(pmlmepriv, state)) pmlmepriv->fw_state ^= state; spin_unlock_bh(&pmlmepriv->lock); } -- GitLab From b9b4224b13c338f752c12a402e2db99f59047827 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:06 +0200 Subject: [PATCH 1436/9457] staging: rtl8723au: Remove uneeded semicolon This patch fixes the following warning detected using coccinelle: Unneeded semicolon. Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_ap.c | 2 +- drivers/staging/rtl8723au/core/rtw_recv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c index d00255fbfcbc..e394d12c36b0 100644 --- a/drivers/staging/rtl8723au/core/rtw_ap.c +++ b/drivers/staging/rtl8723au/core/rtw_ap.c @@ -636,7 +636,7 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf) bcn_interval = (u16)pnetwork->beacon_interval; cur_channel = pnetwork->DSConfig; - cur_bwmode = HT_CHANNEL_WIDTH_20;; + cur_bwmode = HT_CHANNEL_WIDTH_20; cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; /* check if there is wps ie, */ diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 0c0896f3a16b..6cdfc2337c4b 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -1694,7 +1694,7 @@ struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter, skb_put(skb, pnfhdr->pkt->len); prframe->attrib.icv_len = pnfhdr->attrib.icv_len; - }; + } /* free the defrag_q queue and return the prframe */ rtw_free_recvframe23a_queue(defrag_q); -- GitLab From 147e45d9210ce303eb8a3a3c6593631ff78cd072 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:07 +0200 Subject: [PATCH 1437/9457] staging: rtl8723au: hal: Remove uneeded return variable This patch removes uneeded return variables, just using 'return _SUCCESS' or 'return HCI_STATUS_SUCCESS' instead. This fixes the following warning detected using coccinelle: Unneeded variable. It was done using the following semantic patch: @@ identifier ret; type T; expression e; @@ -T ret = e; ... when != ret when strict -return ret; +return e; Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/hal/rtl8723a_bt-coexist.c | 17 +++++------------ drivers/staging/rtl8723au/hal/rtl8723a_cmd.c | 7 ++----- .../staging/rtl8723au/hal/rtl8723a_hal_init.c | 14 ++++---------- drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c | 3 +-- 4 files changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c index 9054a987f06b..5de806e45c3b 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c @@ -1766,9 +1766,7 @@ bthci_CmdSetEventFilter( struct packet_irp_hcicmd_data *pHciCmd ) { - enum hci_status status = HCI_STATUS_SUCCESS; - - return status; + return HCI_STATUS_SUCCESS; } /* 7.3.14 */ @@ -2984,8 +2982,7 @@ bthci_CmdReadLinkQuality( static enum hci_status bthci_CmdReadRSSI(struct rtw_adapter *padapter) { - enum hci_status status = HCI_STATUS_SUCCESS; - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status @@ -2994,7 +2991,6 @@ bthci_CmdCreateLogicalLink( struct packet_irp_hcicmd_data *pHciCmd ) { - enum hci_status status = HCI_STATUS_SUCCESS; struct bt_30info *pBTInfo = GET_BT_INFO(padapter); struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; @@ -3003,7 +2999,7 @@ bthci_CmdCreateLogicalLink( bthci_BuildLogicalLink(padapter, pHciCmd, HCI_CREATE_LOGICAL_LINK); - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status @@ -3012,7 +3008,6 @@ bthci_CmdAcceptLogicalLink( struct packet_irp_hcicmd_data *pHciCmd ) { - enum hci_status status = HCI_STATUS_SUCCESS; struct bt_30info *pBTInfo = GET_BT_INFO(padapter); struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; @@ -3021,7 +3016,7 @@ bthci_CmdAcceptLogicalLink( bthci_BuildLogicalLink(padapter, pHciCmd, HCI_ACCEPT_LOGICAL_LINK); - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status @@ -4141,9 +4136,7 @@ static enum hci_status bthci_CmdHostNumberOfCompletedPackets(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd) { - enum hci_status status = HCI_STATUS_SUCCESS; - - return status; + return HCI_STATUS_SUCCESS; } static enum hci_status diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c index 271c33d6ca5a..7b56411cc3c8 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c @@ -115,19 +115,16 @@ int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u8 *param) { - int res = _SUCCESS; - *((u32 *)param) = cpu_to_le32(*((u32 *)param)); FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param); - return res; + return _SUCCESS; } int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) { u8 buf[5]; - int res = _SUCCESS; memset(buf, 0, 5); mask = cpu_to_le32(mask); @@ -136,7 +133,7 @@ int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf); - return res; + return _SUCCESS; } /* bitmap[0:27] = tx_rate_bitmap */ diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c index 1ccf60a9e528..9a75eb6bb5a3 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c @@ -1522,10 +1522,8 @@ static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) /* HW Auto state machine */ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) { - int rtStatus = _SUCCESS; - if (padapter->bSurpriseRemoved) { - return rtStatus; + return _SUCCESS; } /* RF Off Sequence ==== */ _DisableRFAFEAndResetBB(padapter); @@ -1542,18 +1540,14 @@ int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n")); - return rtStatus; + return _SUCCESS; } /* without HW Auto state machine */ int CardDisableWithoutHWSM(struct rtw_adapter *padapter) { - int rtStatus = _SUCCESS; - - /* RT_TRACE(COMP_INIT, DBG_LOUD, - ("======> Card Disable Without HWSM .\n")); */ if (padapter->bSurpriseRemoved) { - return rtStatus; + return _SUCCESS; } /* RF Off Sequence ==== */ @@ -1573,7 +1567,7 @@ int CardDisableWithoutHWSM(struct rtw_adapter *padapter) /* RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n")); */ - return rtStatus; + return _SUCCESS; } void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c index 3d4d7ec27509..88e91cd8ebb9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c @@ -418,7 +418,6 @@ PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, *---------------------------------------------------------------------------*/ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) { - int rtStatus = _SUCCESS; struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); bool is92C = IS_92C_SERIAL(pHalData->VersionID); @@ -433,7 +432,7 @@ int PHY_MACConfig8723A(struct rtw_adapter *Adapter) if (is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) rtl8723au_write8(Adapter, 0x40, 0x04); - return rtStatus; + return _SUCCESS; } /** -- GitLab From 35a0072771b14acdd437873c5aacf6715552ac85 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:08 +0200 Subject: [PATCH 1438/9457] staging: rtl8723au: os_dep: Remove uneeded return variable This patch removes uneeded return variables, using only 'return _SUCCESS' instead. It fixes the following warning detected by coccinelle: Unneeded variable. It was done using the following semantic patch: @@ identifier ret; type T; expression e; @@ -T ret = e; ... when != ret when strict -return ret; +return e; Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/os_dep/os_intfs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c index ddd0a9f1eefb..d00100356630 100644 --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c @@ -175,7 +175,6 @@ static int netdev_close(struct net_device *pnetdev); static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) { struct registry_priv *registry_par = &padapter->registrypriv; - int status = _SUCCESS; GlobalDebugLevel23A = rtw_debug; registry_par->chip_version = (u8)rtw_chip_version; @@ -234,7 +233,7 @@ static int loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; registry_par->regulatory_tid = (u8)rtw_regulatory_id; - return status; + return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -384,7 +383,6 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; - int ret = _SUCCESS; /* xmit_priv */ pxmitpriv->vcs = pregistrypriv->vcs_type; @@ -423,7 +421,7 @@ static int rtw_init_default_value(struct rtw_adapter *padapter) /* misc. */ padapter->bReadPortCancel = false; padapter->bWritePortCancel = false; - return ret; + return _SUCCESS; } int rtw_reset_drv_sw23a(struct rtw_adapter *padapter) -- GitLab From 038b70395a8a9b290bcd3aed292e4130a83944c7 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:09 +0200 Subject: [PATCH 1439/9457] staging: rtl8723au: core: Remove uneeded return variable This patch removes uneeded return variables, using only 'return _SUCCESS' instead. It fixes the following warning detected by coccinelle: Unneeded variable. It was done using the following semantic patch: @@ identifier ret; type T; expression e; @@ -T ret = e; ... when != ret when strict -return ret; +return e; Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_mlme.c | 3 +-- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 3 +-- drivers/staging/rtl8723au/core/rtw_recv.c | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c index 4e2b22d97101..85d1eca5af8b 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme.c @@ -50,7 +50,6 @@ static void rtw_init_mlme_timer(struct rtw_adapter *padapter) int rtw_init_mlme_priv23a(struct rtw_adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - int res = _SUCCESS; pmlmepriv->nic_hdl = padapter; @@ -68,7 +67,7 @@ int rtw_init_mlme_priv23a(struct rtw_adapter *padapter) rtw_clear_scan_deny(padapter); rtw_init_mlme_timer(padapter); - return res; + return _SUCCESS; } #ifdef CONFIG_8723AU_AP_MODE diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 2624c778eff7..0e0f73c86e53 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -567,7 +567,6 @@ static u8 init_channel_set(struct rtw_adapter *padapter, u8 cplan, int init_mlme_ext_priv23a(struct rtw_adapter *padapter) { - int res = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -594,7 +593,7 @@ int init_mlme_ext_priv23a(struct rtw_adapter *padapter) pmlmeext->mlmeext_init = true; pmlmeext->active_keep_alive_check = true; - return res; + return _SUCCESS; } void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext) diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c index 6cdfc2337c4b..de98da5baa2b 100644 --- a/drivers/staging/rtl8723au/core/rtw_recv.c +++ b/drivers/staging/rtl8723au/core/rtw_recv.c @@ -1554,8 +1554,6 @@ static int wlanhdr_to_ethhdr (struct recv_frame *precvframe) u16 eth_type, len, hdrlen; u8 bsnaphdr; u8 *psnap; - - int ret = _SUCCESS; struct rtw_adapter *adapter = precvframe->adapter; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; @@ -1616,7 +1614,7 @@ static int wlanhdr_to_ethhdr (struct recv_frame *precvframe) } - return ret; + return _SUCCESS; } /* perform defrag */ -- GitLab From 85b4260ddfed16b0069262a2a843fd59562a2ee2 Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Sun, 26 Oct 2014 23:30:10 +0200 Subject: [PATCH 1440/9457] staging: rtl8723au: Remove duplicated argument to || This patch removes duplicated argument to ||, fixing the following warning detected using coccinelle tool: duplicated argument to && or ||. Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index bc63d6f1773a..69d9e0f17fd8 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -1322,7 +1322,6 @@ unsigned char check_assoc_AP23a(u8 *pframe, uint len) DBG_8723A("link to Artheros AP\n"); return HT_IOT_PEER_ATHEROS; } else if (!memcmp(p + 2, BROADCOM_OUI1, 3) || - !memcmp(p + 2, BROADCOM_OUI2, 3) || !memcmp(p + 2, BROADCOM_OUI2, 3)) { DBG_8723A("link to Broadcom AP\n"); return HT_IOT_PEER_BROADCOM; -- GitLab From 3247c4e5ef5d78b47bf2b223d2e684e77845431b Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 11:40:32 +0800 Subject: [PATCH 1441/9457] staging: lustre: lnet: klnds: o2iblnd: fix null dereference on failed path in o2iblnd.c If net is null and failed path is executed, dereference null may happen. This patch fixes it. The following Coccinelle semantic patch was used. @@ expression E, E1; identifier f; statement S1,S2,S3; @@ * if (E == NULL) { ... when != if (E == NULL) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 Signed-off-by: Jiayi Ye Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 045f2beb41d2..bc479a721a60 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -3081,7 +3081,7 @@ kiblnd_startup (lnet_ni_t *ni) LIBCFS_ALLOC(net, sizeof(*net)); ni->ni_data = net; if (net == NULL) - goto failed; + goto net_failed; do_gettimeofday(&tv); net->ibn_incarnation = (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec; @@ -3147,6 +3147,7 @@ kiblnd_startup (lnet_ni_t *ni) if (net->ibn_dev == NULL && ibdev != NULL) kiblnd_destroy_dev(ibdev); +net_failed: kiblnd_shutdown(ni); CDEBUG(D_NET, "kiblnd_startup failed\n"); -- GitLab From f526b20adf27f0a78c643b3fd7c4efc9687d313e Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Sat, 25 Oct 2014 14:45:55 -0700 Subject: [PATCH 1442/9457] Staging: lustre: lnet: Make functions static This patch makes the following functions static as they are only used in their respective files. These functions were detected by sparse. - lib-md.c : lnet_md_validate - lib-move.c : lnet_ni_* lnet_setpayloadbuffer lnet_peer_alive_locked lnet_msg2bufpool lnet_post_routed_recv_locked lnet_configure / lnet_unconfigure lnet_ioctl init_lnet fini_lnet Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/lib-md.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- drivers/staging/lustre/lnet/lnet/module.c | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index e4d906a65635..3225c069637d 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -218,7 +218,7 @@ lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd) lnet_eq2handle(&umd->eq_handle, lmd->md_eq); } -int +static int lnet_md_validate(lnet_md_t *umd) { if (umd->start == NULL && umd->length != 0) { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 4b9567d67f33..5754725f0745 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -561,7 +561,7 @@ lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst, } EXPORT_SYMBOL(lnet_extract_kiov); -void +static void lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, unsigned int offset, unsigned int mlen, unsigned int rlen) { @@ -599,7 +599,7 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed, lnet_finalize(ni, msg, rc); } -void +static void lnet_setpayloadbuffer(lnet_msg_t *msg) { lnet_libmd_t *md = msg->msg_md; @@ -639,7 +639,7 @@ lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target, msg->msg_hdr.payload_length = cpu_to_le32(len); } -void +static void lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) { void *priv = msg->msg_private; @@ -654,7 +654,7 @@ lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg) lnet_finalize(ni, msg, rc); } -int +static int lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) { int rc; @@ -679,7 +679,7 @@ lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) } /* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */ -void +static void lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp) { unsigned long last_alive = 0; @@ -731,7 +731,7 @@ lnet_peer_is_alive(lnet_peer_t *lp, unsigned long now) /* NB: returns 1 when alive, 0 when dead, negative when error; * may drop the lnet_net_lock */ -int +static int lnet_peer_alive_locked(lnet_peer_t *lp) { unsigned long now = cfs_time_current(); @@ -871,7 +871,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) } -lnet_rtrbufpool_t * +static lnet_rtrbufpool_t * lnet_msg2bufpool(lnet_msg_t *msg) { lnet_rtrbufpool_t *rbp; @@ -891,7 +891,7 @@ lnet_msg2bufpool(lnet_msg_t *msg) return rbp; } -int +static int lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv) { /* lnet_parse is going to lnet_net_unlock immediately after this, so it diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index e84d59d23ae0..dc09b4377a2f 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -43,7 +43,7 @@ MODULE_PARM_DESC(config_on_load, "configure network at module load"); static struct mutex lnet_config_mutex; -int +static int lnet_configure(void *arg) { /* 'arg' only there so I can be passed to cfs_create_thread() */ @@ -63,7 +63,7 @@ lnet_configure(void *arg) return rc; } -int +static int lnet_unconfigure(void) { int refcount; @@ -83,7 +83,7 @@ lnet_unconfigure(void) return (refcount == 0) ? 0 : -EBUSY; } -int +static int lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) { int rc; @@ -110,7 +110,7 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl); -int +static int init_lnet(void) { int rc; @@ -135,7 +135,7 @@ init_lnet(void) return 0; } -void +static void fini_lnet(void) { int rc; -- GitLab From c650ba7377ad3602b3fad8651ceeec8a20b74b17 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Sat, 25 Oct 2014 16:35:49 -0700 Subject: [PATCH 1443/9457] Staging: lustre: llite: Simplify error handling This patch fixes the following checkpatch error: ERROR: do not use assignment in if condition 2172: FILE: drivers/staging/lustre/lustre/llite/llite_lib.c:2172: if (!inode || !(sbi = ll_i2sbi(inode))) { Signed-off-by: Tina Ruchandani Suggested-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_lib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 43ab250b087e..74cd4515ac50 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -2169,7 +2169,13 @@ int ll_obd_statfs(struct inode *inode, void *arg) __u32 flags; int len = 0, rc; - if (!inode || !(sbi = ll_i2sbi(inode))) { + if (!inode) { + rc = -EINVAL; + goto out_statfs; + } + + sbi = ll_i2sbi(inode); + if (!sbi) { rc = -EINVAL; goto out_statfs; } -- GitLab From a13cff318cafbd493b8d5d679e5f3f761084c4fe Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Thu, 23 Oct 2014 12:07:14 +0200 Subject: [PATCH 1444/9457] s390/mm: recfactor global pgste updates Replace the s390 specific page table walker for the pgste updates with a call to the common code walk_page_range function. There are now two pte modification functions, one for the reset of the CMMA state and another one for the initialization of the storage keys. Signed-off-by: Dominik Dingel Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgalloc.h | 2 - arch/s390/include/asm/pgtable.h | 1 + arch/s390/kvm/kvm-s390.c | 2 +- arch/s390/mm/pgtable.c | 153 +++++++++++--------------------- 4 files changed, 56 insertions(+), 102 deletions(-) diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index d39a31c3cdf2..e510b9460efa 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -22,8 +22,6 @@ unsigned long *page_table_alloc(struct mm_struct *); void page_table_free(struct mm_struct *, unsigned long *); void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long); -void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long, - bool init_skey); int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, unsigned long key, bool nq); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 57c882761dea..4399be1aaeff 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1747,6 +1747,7 @@ extern int vmem_add_mapping(unsigned long start, unsigned long size); extern int vmem_remove_mapping(unsigned long start, unsigned long size); extern int s390_enable_sie(void); extern void s390_enable_skey(void); +extern void s390_reset_cmma(struct mm_struct *mm); /* * No page table caches to initialise diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 55aade49b6d1..6b049ee75a56 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -271,7 +271,7 @@ static int kvm_s390_mem_control(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_MEM_CLR_CMMA: mutex_lock(&kvm->lock); idx = srcu_read_lock(&kvm->srcu); - page_table_reset_pgste(kvm->arch.gmap->mm, 0, TASK_SIZE, false); + s390_reset_cmma(kvm->arch.gmap->mm); srcu_read_unlock(&kvm->srcu, idx); mutex_unlock(&kvm->lock); ret = 0; diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 1b79ca67392f..019afdf50b1a 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -834,99 +834,6 @@ static inline void page_table_free_pgste(unsigned long *table) __free_page(page); } -static inline unsigned long page_table_reset_pte(struct mm_struct *mm, pmd_t *pmd, - unsigned long addr, unsigned long end, bool init_skey) -{ - pte_t *start_pte, *pte; - spinlock_t *ptl; - pgste_t pgste; - - start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl); - pte = start_pte; - do { - pgste = pgste_get_lock(pte); - pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; - if (init_skey) { - unsigned long address; - - pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT | - PGSTE_GR_BIT | PGSTE_GC_BIT); - - /* skip invalid and not writable pages */ - if (pte_val(*pte) & _PAGE_INVALID || - !(pte_val(*pte) & _PAGE_WRITE)) { - pgste_set_unlock(pte, pgste); - continue; - } - - address = pte_val(*pte) & PAGE_MASK; - page_set_storage_key(address, PAGE_DEFAULT_KEY, 1); - } - pgste_set_unlock(pte, pgste); - } while (pte++, addr += PAGE_SIZE, addr != end); - pte_unmap_unlock(start_pte, ptl); - - return addr; -} - -static inline unsigned long page_table_reset_pmd(struct mm_struct *mm, pud_t *pud, - unsigned long addr, unsigned long end, bool init_skey) -{ - unsigned long next; - pmd_t *pmd; - - pmd = pmd_offset(pud, addr); - do { - next = pmd_addr_end(addr, end); - if (pmd_none_or_clear_bad(pmd)) - continue; - next = page_table_reset_pte(mm, pmd, addr, next, init_skey); - } while (pmd++, addr = next, addr != end); - - return addr; -} - -static inline unsigned long page_table_reset_pud(struct mm_struct *mm, pgd_t *pgd, - unsigned long addr, unsigned long end, bool init_skey) -{ - unsigned long next; - pud_t *pud; - - pud = pud_offset(pgd, addr); - do { - next = pud_addr_end(addr, end); - if (pud_none_or_clear_bad(pud)) - continue; - next = page_table_reset_pmd(mm, pud, addr, next, init_skey); - } while (pud++, addr = next, addr != end); - - return addr; -} - -void page_table_reset_pgste(struct mm_struct *mm, unsigned long start, - unsigned long end, bool init_skey) -{ - unsigned long addr, next; - pgd_t *pgd; - - down_write(&mm->mmap_sem); - if (init_skey && mm_use_skey(mm)) - goto out_up; - addr = start; - pgd = pgd_offset(mm, addr); - do { - next = pgd_addr_end(addr, end); - if (pgd_none_or_clear_bad(pgd)) - continue; - next = page_table_reset_pud(mm, pgd, addr, next, init_skey); - } while (pgd++, addr = next, addr != end); - if (init_skey) - current->mm->context.use_skey = 1; -out_up: - up_write(&mm->mmap_sem); -} -EXPORT_SYMBOL(page_table_reset_pgste); - int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, unsigned long key, bool nq) { @@ -992,11 +899,6 @@ static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm) return NULL; } -void page_table_reset_pgste(struct mm_struct *mm, unsigned long start, - unsigned long end, bool init_skey) -{ -} - static inline void page_table_free_pgste(unsigned long *table) { } @@ -1347,12 +1249,65 @@ EXPORT_SYMBOL_GPL(s390_enable_sie); * Enable storage key handling from now on and initialize the storage * keys with the default key. */ +static int __s390_enable_skey(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + unsigned long ptev; + pgste_t pgste; + + pgste = pgste_get_lock(pte); + /* Clear storage key */ + pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT | + PGSTE_GR_BIT | PGSTE_GC_BIT); + ptev = pte_val(*pte); + if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE)) + page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1); + pgste_set_unlock(pte, pgste); + return 0; +} + void s390_enable_skey(void) { - page_table_reset_pgste(current->mm, 0, TASK_SIZE, true); + struct mm_walk walk = { .pte_entry = __s390_enable_skey }; + struct mm_struct *mm = current->mm; + + down_write(&mm->mmap_sem); + if (mm_use_skey(mm)) + goto out_up; + walk.mm = mm; + walk_page_range(0, TASK_SIZE, &walk); + mm->context.use_skey = 1; + +out_up: + up_write(&mm->mmap_sem); } EXPORT_SYMBOL_GPL(s390_enable_skey); +/* + * Reset CMMA state, make all pages stable again. + */ +static int __s390_reset_cmma(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pgste_t pgste; + + pgste = pgste_get_lock(pte); + pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; + pgste_set_unlock(pte, pgste); + return 0; +} + +void s390_reset_cmma(struct mm_struct *mm) +{ + struct mm_walk walk = { .pte_entry = __s390_reset_cmma }; + + down_write(&mm->mmap_sem); + walk.mm = mm; + walk_page_range(0, TASK_SIZE, &walk); + up_write(&mm->mmap_sem); +} +EXPORT_SYMBOL_GPL(s390_reset_cmma); + /* * Test and reset if a guest page is dirty */ -- GitLab From 593befa6ab74a805e4f503c8c737c3cffa8066b6 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Thu, 23 Oct 2014 12:07:44 +0200 Subject: [PATCH 1445/9457] mm: introduce mm_forbids_zeropage function Add a new function stub to allow architectures to disable for an mm_structthe backing of non-present, anonymous pages with read-only empty zero pages. Signed-off-by: Dominik Dingel Reviewed-by: Paolo Bonzini Signed-off-by: Martin Schwidefsky --- include/linux/mm.h | 11 +++++++++++ mm/huge_memory.c | 2 +- mm/memory.c | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 27eb1bfbe704..ab7dadca4ea5 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -56,6 +56,17 @@ extern int sysctl_legacy_va_layout; #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) #endif +/* + * To prevent common memory management code establishing + * a zero page mapping on a read fault. + * This macro should be defined within . + * s390 does this to prevent multiplexing of hardware bits + * related to the physical page in case of virtualization. + */ +#ifndef mm_forbids_zeropage +#define mm_forbids_zeropage(X) (0) +#endif + extern unsigned long sysctl_user_reserve_kbytes; extern unsigned long sysctl_admin_reserve_kbytes; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 74c78aa8bc2f..7e9c15cb93a9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -805,7 +805,7 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, return VM_FAULT_OOM; if (unlikely(khugepaged_enter(vma))) return VM_FAULT_OOM; - if (!(flags & FAULT_FLAG_WRITE) && + if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm) && transparent_hugepage_use_zero_page()) { spinlock_t *ptl; pgtable_t pgtable; diff --git a/mm/memory.c b/mm/memory.c index 1cc6bfbd872e..d722d4f481c9 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2640,7 +2640,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, return VM_FAULT_SIGBUS; /* Use the zero-page for reads */ - if (!(flags & FAULT_FLAG_WRITE)) { + if (!(flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(mm)) { entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), vma->vm_page_prot)); page_table = pte_offset_map_lock(mm, pmd, address, &ptl); -- GitLab From 2faee8ff9dc6f4bfe46f6d2d110add858140fb20 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Thu, 23 Oct 2014 12:08:38 +0200 Subject: [PATCH 1446/9457] s390/mm: prevent and break zero page mappings in case of storage keys As soon as storage keys are enabled we need to stop working on zero page mappings to prevent inconsistencies between storage keys and pgste. Otherwise following data corruption could happen: 1) guest enables storage key 2) guest sets storage key for not mapped page X -> change goes to PGSTE 3) guest reads from page X -> as X was not dirty before, the page will be zero page backed, storage key from PGSTE for X will go to storage key for zero page 4) guest sets storage key for not mapped page Y (same logic as above 5) guest reads from page Y -> as Y was not dirty before, the page will be zero page backed, storage key from PGSTE for Y will got to storage key for zero page overwriting storage key for X While holding the mmap sem, we are safe against changes on entries we already fixed, as every fault would need to take the mmap_sem (read). Other vCPUs executing storage key instructions will get a one time interception and be serialized also with mmap_sem. Signed-off-by: Dominik Dingel Reviewed-by: Paolo Bonzini Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 5 +++++ arch/s390/mm/pgtable.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 4399be1aaeff..df2e7f14ffb7 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -479,6 +479,11 @@ static inline int mm_has_pgste(struct mm_struct *mm) return 0; } +/* + * In the case that a guest uses storage keys + * faults should no longer be backed by zero pages + */ +#define mm_forbids_zeropage mm_use_skey static inline int mm_use_skey(struct mm_struct *mm) { #ifdef CONFIG_PGSTE diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 019afdf50b1a..0f1e9ff6bc12 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -1256,6 +1256,15 @@ static int __s390_enable_skey(pte_t *pte, unsigned long addr, pgste_t pgste; pgste = pgste_get_lock(pte); + /* + * Remove all zero page mappings, + * after establishing a policy to forbid zero page mappings + * following faults for that page will get fresh anonymous pages + */ + if (is_zero_pfn(pte_pfn(*pte))) { + ptep_flush_direct(walk->mm, addr, pte); + pte_val(*pte) = _PAGE_INVALID; + } /* Clear storage key */ pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT | PGSTE_GR_BIT | PGSTE_GC_BIT); @@ -1274,9 +1283,11 @@ void s390_enable_skey(void) down_write(&mm->mmap_sem); if (mm_use_skey(mm)) goto out_up; + + mm->context.use_skey = 1; + walk.mm = mm; walk_page_range(0, TASK_SIZE, &walk); - mm->context.use_skey = 1; out_up: up_write(&mm->mmap_sem); -- GitLab From 3ac8e38015d4fd1c12e4e048a01a9f059a2053a2 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Thu, 23 Oct 2014 12:09:17 +0200 Subject: [PATCH 1447/9457] s390/mm: disable KSM for storage key enabled pages When storage keys are enabled unmerge already merged pages and prevent new pages from being merged. Signed-off-by: Dominik Dingel Acked-by: Christian Borntraeger Reviewed-by: Paolo Bonzini Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 2 +- arch/s390/kvm/priv.c | 17 ++++++++++++----- arch/s390/mm/pgtable.c | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index df2e7f14ffb7..00d460742e1e 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1751,7 +1751,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) extern int vmem_add_mapping(unsigned long start, unsigned long size); extern int vmem_remove_mapping(unsigned long start, unsigned long size); extern int s390_enable_sie(void); -extern void s390_enable_skey(void); +extern int s390_enable_skey(void); extern void s390_reset_cmma(struct mm_struct *mm); /* diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 72bb2dd8b9cd..f47cb0c6d906 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -156,21 +156,25 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu) return 0; } -static void __skey_check_enable(struct kvm_vcpu *vcpu) +static int __skey_check_enable(struct kvm_vcpu *vcpu) { + int rc = 0; if (!(vcpu->arch.sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE))) - return; + return rc; - s390_enable_skey(); + rc = s390_enable_skey(); trace_kvm_s390_skey_related_inst(vcpu); vcpu->arch.sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE); + return rc; } static int handle_skey(struct kvm_vcpu *vcpu) { - __skey_check_enable(vcpu); + int rc = __skey_check_enable(vcpu); + if (rc) + return rc; vcpu->stat.instruction_storage_key++; if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) @@ -683,7 +687,10 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) } if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) { - __skey_check_enable(vcpu); + int rc = __skey_check_enable(vcpu); + + if (rc) + return rc; if (set_guest_storage_key(current->mm, useraddr, vcpu->run->s.regs.gprs[reg1] & PFMF_KEY, vcpu->run->s.regs.gprs[reg1] & PFMF_NQ)) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0f1e9ff6bc12..b1871d39e46e 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -1275,22 +1277,34 @@ static int __s390_enable_skey(pte_t *pte, unsigned long addr, return 0; } -void s390_enable_skey(void) +int s390_enable_skey(void) { struct mm_walk walk = { .pte_entry = __s390_enable_skey }; struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + int rc = 0; down_write(&mm->mmap_sem); if (mm_use_skey(mm)) goto out_up; mm->context.use_skey = 1; + for (vma = mm->mmap; vma; vma = vma->vm_next) { + if (ksm_madvise(vma, vma->vm_start, vma->vm_end, + MADV_UNMERGEABLE, &vma->vm_flags)) { + mm->context.use_skey = 0; + rc = -ENOMEM; + goto out_up; + } + } + mm->def_flags &= ~VM_MERGEABLE; walk.mm = mm; walk_page_range(0, TASK_SIZE, &walk); out_up: up_write(&mm->mmap_sem); + return rc; } EXPORT_SYMBOL_GPL(s390_enable_skey); -- GitLab From f7f242ff004499e0904d3664713dfba01f24c408 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 15 Oct 2014 12:17:34 +0200 Subject: [PATCH 1448/9457] kprobes: introduce weak arch_check_ftrace_location() helper function Introduce weak arch_check_ftrace_location() helper function which architectures can override in order to implement handling of kprobes on function tracer call sites on their own, without depending on common code or implementing the KPROBES_ON_FTRACE feature. Signed-off-by: Heiko Carstens Acked-by: Masami Hiramatsu Acked-by: Steven Rostedt Signed-off-by: Martin Schwidefsky --- include/linux/kprobes.h | 1 + kernel/kprobes.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index f7296e57d614..5297f9fa0ef2 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -335,6 +335,7 @@ extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, extern int arch_prepare_kprobe_ftrace(struct kprobe *p); #endif +int arch_check_ftrace_location(struct kprobe *p); /* Get the kprobe at this addr (if any) - called with preemption disabled */ struct kprobe *get_kprobe(void *addr); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3995f546d0f3..317eb8ad28dd 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1410,16 +1410,10 @@ static inline int check_kprobe_rereg(struct kprobe *p) return ret; } -static int check_kprobe_address_safe(struct kprobe *p, - struct module **probed_mod) +int __weak arch_check_ftrace_location(struct kprobe *p) { - int ret = 0; unsigned long ftrace_addr; - /* - * If the address is located on a ftrace nop, set the - * breakpoint to the following instruction. - */ ftrace_addr = ftrace_location((unsigned long)p->addr); if (ftrace_addr) { #ifdef CONFIG_KPROBES_ON_FTRACE @@ -1431,7 +1425,17 @@ static int check_kprobe_address_safe(struct kprobe *p, return -EINVAL; #endif } + return 0; +} +static int check_kprobe_address_safe(struct kprobe *p, + struct module **probed_mod) +{ + int ret; + + ret = arch_check_ftrace_location(p); + if (ret) + return ret; jump_label_lock(); preempt_disable(); -- GitLab From c933146a5e41e42ea3eb4f34fa02e201da3f068e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 15 Oct 2014 12:17:38 +0200 Subject: [PATCH 1449/9457] s390/ftrace,kprobes: allow to patch first instruction If the function tracer is enabled, allow to set kprobes on the first instruction of a function (which is the function trace caller): If no kprobe is set handling of enabling and disabling function tracing of a function simply patches the first instruction. Either it is a nop (right now it's an unconditional branch, which skips the mcount block), or it's a branch to the ftrace_caller() function. If a kprobe is being placed on a function tracer calling instruction we encode if we actually have a nop or branch in the remaining bytes after the breakpoint instruction (illegal opcode). This is possible, since the size of the instruction used for the nop and branch is six bytes, while the size of the breakpoint is only two bytes. Therefore the first two bytes contain the illegal opcode and the last four bytes contain either "0" for nop or "1" for branch. The kprobes code will then execute/simulate the correct instruction. Instruction patching for kprobes and function tracer is always done with stop_machine(). Therefore we don't have any races where an instruction is patched concurrently on a different cpu. Besides that also the program check handler which executes the function trace caller instruction won't be executed concurrently to any stop_machine() execution. This allows to keep full fault based kprobes handling which generates correct pt_regs contents automatically. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ftrace.h | 52 +++++++++++-- arch/s390/include/asm/kprobes.h | 1 + arch/s390/include/asm/lowcore.h | 4 +- arch/s390/include/asm/pgtable.h | 12 +++ arch/s390/kernel/asm-offsets.c | 1 - arch/s390/kernel/early.c | 4 - arch/s390/kernel/ftrace.c | 132 ++++++++++++++++++++------------ arch/s390/kernel/kprobes.c | 92 +++++++++++++++------- arch/s390/kernel/mcount.S | 1 + arch/s390/kernel/setup.c | 2 - arch/s390/kernel/smp.c | 1 - scripts/recordmcount.c | 2 +- scripts/recordmcount.pl | 2 +- 13 files changed, 214 insertions(+), 92 deletions(-) diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 3aef8afec336..785041f1dc77 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h @@ -1,25 +1,67 @@ #ifndef _ASM_S390_FTRACE_H #define _ASM_S390_FTRACE_H +#define ARCH_SUPPORTS_FTRACE_OPS 1 + +#define MCOUNT_INSN_SIZE 24 +#define MCOUNT_RETURN_FIXUP 18 + #ifndef __ASSEMBLY__ -extern void _mcount(void); +void _mcount(void); +void ftrace_caller(void); + extern char ftrace_graph_caller_end; +extern unsigned long ftrace_plt; struct dyn_arch_ftrace { }; -#define MCOUNT_ADDR ((long)_mcount) +#define MCOUNT_ADDR ((unsigned long)_mcount) +#define FTRACE_ADDR ((unsigned long)ftrace_caller) +#define KPROBE_ON_FTRACE_NOP 0 +#define KPROBE_ON_FTRACE_CALL 1 static inline unsigned long ftrace_call_adjust(unsigned long addr) { return addr; } -#endif /* __ASSEMBLY__ */ +struct ftrace_insn { + u16 opc; + s32 disp; +} __packed; -#define MCOUNT_INSN_SIZE 18 +static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn) +{ +#ifdef CONFIG_FUNCTION_TRACER + /* jg .+24 */ + insn->opc = 0xc0f4; + insn->disp = MCOUNT_INSN_SIZE / 2; +#endif +} -#define ARCH_SUPPORTS_FTRACE_OPS 1 +static inline int is_ftrace_nop(struct ftrace_insn *insn) +{ +#ifdef CONFIG_FUNCTION_TRACER + if (insn->disp == MCOUNT_INSN_SIZE / 2) + return 1; +#endif + return 0; +} + +static inline void ftrace_generate_call_insn(struct ftrace_insn *insn, + unsigned long ip) +{ +#ifdef CONFIG_FUNCTION_TRACER + unsigned long target; + /* brasl r0,ftrace_caller */ + target = is_module_addr((void *) ip) ? ftrace_plt : FTRACE_ADDR; + insn->opc = 0xc005; + insn->disp = (target - ip) / 2; +#endif +} + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_S390_FTRACE_H */ diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h index 98629173ce3b..b47ad3b642cc 100644 --- a/arch/s390/include/asm/kprobes.h +++ b/arch/s390/include/asm/kprobes.h @@ -60,6 +60,7 @@ typedef u16 kprobe_opcode_t; struct arch_specific_insn { /* copy of original instruction */ kprobe_opcode_t *insn; + unsigned int is_ftrace_insn : 1; }; struct prev_kprobe { diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 6cc51fe84410..34fbcac61133 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -147,7 +147,7 @@ struct _lowcore { __u32 softirq_pending; /* 0x02ec */ __u32 percpu_offset; /* 0x02f0 */ __u32 machine_flags; /* 0x02f4 */ - __u32 ftrace_func; /* 0x02f8 */ + __u8 pad_0x02f8[0x02fc-0x02f8]; /* 0x02f8 */ __u32 spinlock_lockval; /* 0x02fc */ __u8 pad_0x0300[0x0e00-0x0300]; /* 0x0300 */ @@ -297,7 +297,7 @@ struct _lowcore { __u64 percpu_offset; /* 0x0378 */ __u64 vdso_per_cpu_data; /* 0x0380 */ __u64 machine_flags; /* 0x0388 */ - __u64 ftrace_func; /* 0x0390 */ + __u8 pad_0x0390[0x0398-0x0390]; /* 0x0390 */ __u64 gmap; /* 0x0398 */ __u32 spinlock_lockval; /* 0x03a0 */ __u8 pad_0x03a0[0x0400-0x03a4]; /* 0x03a4 */ diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 00d460742e1e..5ef1a266936a 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -133,6 +133,18 @@ extern unsigned long MODULES_END; #define MODULES_LEN (1UL << 31) #endif +static inline int is_module_addr(void *addr) +{ +#ifdef CONFIG_64BIT + BUILD_BUG_ON(MODULES_LEN > (1UL << 31)); + if (addr < (void *)MODULES_VADDR) + return 0; + if (addr > (void *)MODULES_END) + return 0; +#endif + return 1; +} + /* * A 31 bit pagetable entry of S390 has following format: * | PFRA | | OS | diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index ef279a136801..f3a78337ca86 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -156,7 +156,6 @@ int main(void) DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); - DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib)); BLANK(); DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cef2879edff3..302ac1f7f8e7 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -490,8 +489,5 @@ void __init startup_init(void) detect_machine_facilities(); setup_topology(); sclp_early_detect(); -#ifdef CONFIG_DYNAMIC_FTRACE - S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; -#endif lockdep_on(); } diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 51d14fe5eb9a..5744d25c1d33 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -7,6 +7,7 @@ * Martin Schwidefsky */ +#include #include #include #include @@ -15,60 +16,39 @@ #include #include #include +#include #include "entry.h" -void mcount_replace_code(void); -void ftrace_disable_code(void); -void ftrace_enable_insn(void); - /* * The mcount code looks like this: * stg %r14,8(%r15) # offset 0 * larl %r1,<&counter> # offset 6 * brasl %r14,_mcount # offset 12 * lg %r14,8(%r15) # offset 18 - * Total length is 24 bytes. The complete mcount block initially gets replaced - * by ftrace_make_nop. Subsequent calls to ftrace_make_call / ftrace_make_nop - * only patch the jg/lg instruction within the block. - * Note: we do not patch the first instruction to an unconditional branch, - * since that would break kprobes/jprobes. It is easier to leave the larl - * instruction in and only modify the second instruction. + * Total length is 24 bytes. Only the first instruction will be patched + * by ftrace_make_call / ftrace_make_nop. * The enabled ftrace code block looks like this: - * larl %r0,.+24 # offset 0 - * > lg %r1,__LC_FTRACE_FUNC # offset 6 - * br %r1 # offset 12 - * brcl 0,0 # offset 14 - * brc 0,0 # offset 20 + * > brasl %r0,ftrace_caller # offset 0 + * larl %r1,<&counter> # offset 6 + * brasl %r14,_mcount # offset 12 + * lg %r14,8(%r15) # offset 18 * The ftrace function gets called with a non-standard C function call ABI * where r0 contains the return address. It is also expected that the called * function only clobbers r0 and r1, but restores r2-r15. + * For module code we can't directly jump to ftrace caller, but need a + * trampoline (ftrace_plt), which clobbers also r1. * The return point of the ftrace function has offset 24, so execution * continues behind the mcount block. - * larl %r0,.+24 # offset 0 - * > jg .+18 # offset 6 - * br %r1 # offset 12 - * brcl 0,0 # offset 14 - * brc 0,0 # offset 20 + * The disabled ftrace code block looks like this: + * > jg .+24 # offset 0 + * larl %r1,<&counter> # offset 6 + * brasl %r14,_mcount # offset 12 + * lg %r14,8(%r15) # offset 18 * The jg instruction branches to offset 24 to skip as many instructions * as possible. */ -asm( - " .align 4\n" - "mcount_replace_code:\n" - " larl %r0,0f\n" - "ftrace_disable_code:\n" - " jg 0f\n" - " br %r1\n" - " brcl 0,0\n" - " brc 0,0\n" - "0:\n" - " .align 4\n" - "ftrace_enable_insn:\n" - " lg %r1,"__stringify(__LC_FTRACE_FUNC)"\n"); - -#define MCOUNT_BLOCK_SIZE 24 -#define MCOUNT_INSN_OFFSET 6 -#define FTRACE_INSN_SIZE 6 + +unsigned long ftrace_plt; int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) @@ -79,24 +59,62 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { - /* Initial replacement of the whole mcount block */ - if (addr == MCOUNT_ADDR) { - if (probe_kernel_write((void *) rec->ip - MCOUNT_INSN_OFFSET, - mcount_replace_code, - MCOUNT_BLOCK_SIZE)) - return -EPERM; - return 0; + struct ftrace_insn insn; + unsigned short op; + void *from, *to; + size_t size; + + ftrace_generate_nop_insn(&insn); + size = sizeof(insn); + from = &insn; + to = (void *) rec->ip; + if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op))) + return -EFAULT; + /* + * If we find a breakpoint instruction, a kprobe has been placed + * at the beginning of the function. We write the constant + * KPROBE_ON_FTRACE_NOP into the remaining four bytes of the original + * instruction so that the kprobes handler can execute a nop, if it + * reaches this breakpoint. + */ + if (op == BREAKPOINT_INSTRUCTION) { + size -= 2; + from += 2; + to += 2; + insn.disp = KPROBE_ON_FTRACE_NOP; } - if (probe_kernel_write((void *) rec->ip, ftrace_disable_code, - MCOUNT_INSN_SIZE)) + if (probe_kernel_write(to, from, size)) return -EPERM; return 0; } int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { - if (probe_kernel_write((void *) rec->ip, ftrace_enable_insn, - FTRACE_INSN_SIZE)) + struct ftrace_insn insn; + unsigned short op; + void *from, *to; + size_t size; + + ftrace_generate_call_insn(&insn, rec->ip); + size = sizeof(insn); + from = &insn; + to = (void *) rec->ip; + if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op))) + return -EFAULT; + /* + * If we find a breakpoint instruction, a kprobe has been placed + * at the beginning of the function. We write the constant + * KPROBE_ON_FTRACE_CALL into the remaining four bytes of the original + * instruction so that the kprobes handler can execute a brasl if it + * reaches this breakpoint. + */ + if (op == BREAKPOINT_INSTRUCTION) { + size -= 2; + from += 2; + to += 2; + insn.disp = KPROBE_ON_FTRACE_CALL; + } + if (probe_kernel_write(to, from, size)) return -EPERM; return 0; } @@ -111,6 +129,24 @@ int __init ftrace_dyn_arch_init(void) return 0; } +static int __init ftrace_plt_init(void) +{ + unsigned int *ip; + + ftrace_plt = (unsigned long) module_alloc(PAGE_SIZE); + if (!ftrace_plt) + panic("cannot allocate ftrace plt\n"); + ip = (unsigned int *) ftrace_plt; + ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */ + ip[1] = 0x100a0004; + ip[2] = 0x07f10000; + ip[3] = FTRACE_ADDR >> 32; + ip[4] = FTRACE_ADDR & 0xffffffff; + set_memory_ro(ftrace_plt, 1); + return 0; +} +device_initcall(ftrace_plt_init); + #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* * Hook the return address and push it in the stack of return addresses diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 014d4729b134..d6716c29b7f8 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -60,10 +61,21 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = { static void __kprobes copy_instruction(struct kprobe *p) { + unsigned long ip = (unsigned long) p->addr; s64 disp, new_disp; u64 addr, new_addr; - memcpy(p->ainsn.insn, p->addr, insn_length(p->opcode >> 8)); + if (ftrace_location(ip) == ip) { + /* + * If kprobes patches the instruction that is morphed by + * ftrace make sure that kprobes always sees the branch + * "jg .+24" that skips the mcount block + */ + ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn); + p->ainsn.is_ftrace_insn = 1; + } else + memcpy(p->ainsn.insn, p->addr, insn_length(p->opcode >> 8)); + p->opcode = p->ainsn.insn[0]; if (!probe_is_insn_relative_long(p->ainsn.insn)) return; /* @@ -85,18 +97,6 @@ static inline int is_kernel_addr(void *addr) return addr < (void *)_end; } -static inline int is_module_addr(void *addr) -{ -#ifdef CONFIG_64BIT - BUILD_BUG_ON(MODULES_LEN > (1UL << 31)); - if (addr < (void *)MODULES_VADDR) - return 0; - if (addr > (void *)MODULES_END) - return 0; -#endif - return 1; -} - static int __kprobes s390_get_insn_slot(struct kprobe *p) { /* @@ -132,43 +132,63 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return -EINVAL; if (s390_get_insn_slot(p)) return -ENOMEM; - p->opcode = *p->addr; copy_instruction(p); return 0; } -struct ins_replace_args { - kprobe_opcode_t *ptr; - kprobe_opcode_t opcode; +int arch_check_ftrace_location(struct kprobe *p) +{ + return 0; +} + +struct swap_insn_args { + struct kprobe *p; + unsigned int arm_kprobe : 1; }; -static int __kprobes swap_instruction(void *aref) +static int __kprobes swap_instruction(void *data) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); unsigned long status = kcb->kprobe_status; - struct ins_replace_args *args = aref; - + struct swap_insn_args *args = data; + struct ftrace_insn new_insn, *insn; + struct kprobe *p = args->p; + size_t len; + + new_insn.opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode; + len = sizeof(new_insn.opc); + if (!p->ainsn.is_ftrace_insn) + goto skip_ftrace; + len = sizeof(new_insn); + insn = (struct ftrace_insn *) p->addr; + if (args->arm_kprobe) { + if (is_ftrace_nop(insn)) + new_insn.disp = KPROBE_ON_FTRACE_NOP; + else + new_insn.disp = KPROBE_ON_FTRACE_CALL; + } else { + ftrace_generate_call_insn(&new_insn, (unsigned long)p->addr); + if (insn->disp == KPROBE_ON_FTRACE_NOP) + ftrace_generate_nop_insn(&new_insn); + } +skip_ftrace: kcb->kprobe_status = KPROBE_SWAP_INST; - probe_kernel_write(args->ptr, &args->opcode, sizeof(args->opcode)); + probe_kernel_write(p->addr, &new_insn, len); kcb->kprobe_status = status; return 0; } void __kprobes arch_arm_kprobe(struct kprobe *p) { - struct ins_replace_args args; + struct swap_insn_args args = {.p = p, .arm_kprobe = 1}; - args.ptr = p->addr; - args.opcode = BREAKPOINT_INSTRUCTION; stop_machine(swap_instruction, &args, NULL); } void __kprobes arch_disarm_kprobe(struct kprobe *p) { - struct ins_replace_args args; + struct swap_insn_args args = {.p = p, .arm_kprobe = 0}; - args.ptr = p->addr; - args.opcode = p->opcode; stop_machine(swap_instruction, &args, NULL); } @@ -459,6 +479,24 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) unsigned long ip = regs->psw.addr & PSW_ADDR_INSN; int fixup = probe_get_fixup_type(p->ainsn.insn); + /* Check if the kprobes location is an enabled ftrace caller */ + if (p->ainsn.is_ftrace_insn) { + struct ftrace_insn *insn = (struct ftrace_insn *) p->addr; + struct ftrace_insn call_insn; + + ftrace_generate_call_insn(&call_insn, (unsigned long) p->addr); + /* + * A kprobe on an enabled ftrace call site actually single + * stepped an unconditional branch (ftrace nop equivalent). + * Now we need to fixup things and pretend that a brasl r0,... + * was executed instead. + */ + if (insn->disp == KPROBE_ON_FTRACE_CALL) { + ip += call_insn.disp * 2 - MCOUNT_INSN_SIZE; + regs->gprs[0] = (unsigned long)p->addr + sizeof(*insn); + } + } + if (fixup & FIXUP_PSW_NORMAL) ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn; diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 4300ea374826..b6dfc5bfcb89 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -27,6 +27,7 @@ ENTRY(ftrace_caller) .globl ftrace_regs_caller .set ftrace_regs_caller,ftrace_caller lgr %r1,%r15 + aghi %r0,MCOUNT_RETURN_FIXUP aghi %r15,-STACK_FRAME_SIZE stg %r1,__SF_BACKCHAIN(%r15) stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e80d9ff9a56d..4e532c67832f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -356,7 +355,6 @@ static void __init setup_lowcore(void) lc->steal_timer = S390_lowcore.steal_timer; lc->last_update_timer = S390_lowcore.last_update_timer; lc->last_update_clock = S390_lowcore.last_update_clock; - lc->ftrace_func = S390_lowcore.ftrace_func; restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0); restart_stack += ASYNC_SIZE; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 6fd9e60101f1..0b499f5cbe19 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -236,7 +236,6 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) lc->percpu_offset = __per_cpu_offset[cpu]; lc->kernel_asce = S390_lowcore.kernel_asce; lc->machine_flags = S390_lowcore.machine_flags; - lc->ftrace_func = S390_lowcore.ftrace_func; lc->user_timer = lc->system_timer = lc->steal_timer = 0; __ctl_store(lc->cregs_save_area, 0, 15); save_access_regs((unsigned int *) lc->access_regs_save_area); diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 001facfa5b74..3d1984e59a30 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -404,7 +404,7 @@ do_file(char const *const fname) } if (w2(ghdr->e_machine) == EM_S390) { reltype = R_390_64; - mcount_adjust_64 = -8; + mcount_adjust_64 = -14; } if (w2(ghdr->e_machine) == EM_MIPS) { reltype = R_MIPS_64; diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index d4b665610d67..56ea99a12ab7 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -243,7 +243,7 @@ if ($arch eq "x86_64") { } elsif ($arch eq "s390" && $bits == 64) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; - $mcount_adjust = -8; + $mcount_adjust = -14; $alignment = 8; $type = ".quad"; $ld .= " -m elf64_s390"; -- GitLab From 7a5388de5c70f7a92de71e03ce72692c1827d162 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 22 Oct 2014 12:42:38 +0200 Subject: [PATCH 1450/9457] s390/kprobes: make use of NOKPROBE_SYMBOL() Use NOKPROBE_SYMBOL() instead of __kprobes annotation. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ftrace.c | 4 +- arch/s390/kernel/idle.c | 3 +- arch/s390/kernel/kprobes.c | 88 ++++++++++++++++++++++++-------------- arch/s390/kernel/process.c | 2 +- arch/s390/kernel/time.c | 3 +- arch/s390/kernel/traps.c | 14 +++--- arch/s390/mm/fault.c | 6 ++- 7 files changed, 74 insertions(+), 46 deletions(-) diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 5744d25c1d33..708c772b086d 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -152,8 +152,7 @@ device_initcall(ftrace_plt_init); * Hook the return address and push it in the stack of return addresses * in current thread info. */ -unsigned long __kprobes prepare_ftrace_return(unsigned long parent, - unsigned long ip) +unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip) { struct ftrace_graph_ent trace; @@ -171,6 +170,7 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent, out: return parent; } +NOKPROBE_SYMBOL(prepare_ftrace_return); /* * Patch the kernel code at ftrace_graph_caller location. The instruction diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index 7559f1beab29..05fbc2c98faf 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -19,7 +19,7 @@ static DEFINE_PER_CPU(struct s390_idle_data, s390_idle); -void __kprobes enabled_wait(void) +void enabled_wait(void) { struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); unsigned long long idle_time; @@ -46,6 +46,7 @@ void __kprobes enabled_wait(void) smp_wmb(); idle->sequence++; } +NOKPROBE_SYMBOL(enabled_wait); static ssize_t show_idle_count(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index d6716c29b7f8..ee0396755430 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -59,7 +59,7 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = { .insn_size = MAX_INSN_SIZE, }; -static void __kprobes copy_instruction(struct kprobe *p) +static void copy_instruction(struct kprobe *p) { unsigned long ip = (unsigned long) p->addr; s64 disp, new_disp; @@ -91,13 +91,14 @@ static void __kprobes copy_instruction(struct kprobe *p) new_disp = ((addr + (disp * 2)) - new_addr) / 2; *(s32 *)&p->ainsn.insn[1] = new_disp; } +NOKPROBE_SYMBOL(copy_instruction); static inline int is_kernel_addr(void *addr) { return addr < (void *)_end; } -static int __kprobes s390_get_insn_slot(struct kprobe *p) +static int s390_get_insn_slot(struct kprobe *p) { /* * Get an insn slot that is within the same 2GB area like the original @@ -111,8 +112,9 @@ static int __kprobes s390_get_insn_slot(struct kprobe *p) p->ainsn.insn = get_insn_slot(); return p->ainsn.insn ? 0 : -ENOMEM; } +NOKPROBE_SYMBOL(s390_get_insn_slot); -static void __kprobes s390_free_insn_slot(struct kprobe *p) +static void s390_free_insn_slot(struct kprobe *p) { if (!p->ainsn.insn) return; @@ -122,8 +124,9 @@ static void __kprobes s390_free_insn_slot(struct kprobe *p) free_insn_slot(p->ainsn.insn, 0); p->ainsn.insn = NULL; } +NOKPROBE_SYMBOL(s390_free_insn_slot); -int __kprobes arch_prepare_kprobe(struct kprobe *p) +int arch_prepare_kprobe(struct kprobe *p) { if ((unsigned long) p->addr & 0x01) return -EINVAL; @@ -135,6 +138,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) copy_instruction(p); return 0; } +NOKPROBE_SYMBOL(arch_prepare_kprobe); int arch_check_ftrace_location(struct kprobe *p) { @@ -146,7 +150,7 @@ struct swap_insn_args { unsigned int arm_kprobe : 1; }; -static int __kprobes swap_instruction(void *data) +static int swap_instruction(void *data) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); unsigned long status = kcb->kprobe_status; @@ -177,29 +181,33 @@ static int __kprobes swap_instruction(void *data) kcb->kprobe_status = status; return 0; } +NOKPROBE_SYMBOL(swap_instruction); -void __kprobes arch_arm_kprobe(struct kprobe *p) +void arch_arm_kprobe(struct kprobe *p) { struct swap_insn_args args = {.p = p, .arm_kprobe = 1}; stop_machine(swap_instruction, &args, NULL); } +NOKPROBE_SYMBOL(arch_arm_kprobe); -void __kprobes arch_disarm_kprobe(struct kprobe *p) +void arch_disarm_kprobe(struct kprobe *p) { struct swap_insn_args args = {.p = p, .arm_kprobe = 0}; stop_machine(swap_instruction, &args, NULL); } +NOKPROBE_SYMBOL(arch_disarm_kprobe); -void __kprobes arch_remove_kprobe(struct kprobe *p) +void arch_remove_kprobe(struct kprobe *p) { s390_free_insn_slot(p); } +NOKPROBE_SYMBOL(arch_remove_kprobe); -static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb, - struct pt_regs *regs, - unsigned long ip) +static void enable_singlestep(struct kprobe_ctlblk *kcb, + struct pt_regs *regs, + unsigned long ip) { struct per_regs per_kprobe; @@ -219,10 +227,11 @@ static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb, regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); regs->psw.addr = ip | PSW_ADDR_AMODE; } +NOKPROBE_SYMBOL(enable_singlestep); -static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb, - struct pt_regs *regs, - unsigned long ip) +static void disable_singlestep(struct kprobe_ctlblk *kcb, + struct pt_regs *regs, + unsigned long ip) { /* Restore control regs and psw mask, set new psw address */ __ctl_load(kcb->kprobe_saved_ctl, 9, 11); @@ -230,41 +239,43 @@ static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb, regs->psw.mask |= kcb->kprobe_saved_imask; regs->psw.addr = ip | PSW_ADDR_AMODE; } +NOKPROBE_SYMBOL(disable_singlestep); /* * Activate a kprobe by storing its pointer to current_kprobe. The * previous kprobe is stored in kcb->prev_kprobe. A stack of up to * two kprobes can be active, see KPROBE_REENTER. */ -static void __kprobes push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p) +static void push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p) { kcb->prev_kprobe.kp = __this_cpu_read(current_kprobe); kcb->prev_kprobe.status = kcb->kprobe_status; __this_cpu_write(current_kprobe, p); } +NOKPROBE_SYMBOL(push_kprobe); /* * Deactivate a kprobe by backing up to the previous state. If the * current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL, * for any other state prev_kprobe.kp will be NULL. */ -static void __kprobes pop_kprobe(struct kprobe_ctlblk *kcb) +static void pop_kprobe(struct kprobe_ctlblk *kcb) { __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; } +NOKPROBE_SYMBOL(pop_kprobe); -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - struct pt_regs *regs) +void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14]; /* Replace the return addr with trampoline addr */ regs->gprs[14] = (unsigned long) &kretprobe_trampoline; } +NOKPROBE_SYMBOL(arch_prepare_kretprobe); -static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb, - struct kprobe *p) +static void kprobe_reenter_check(struct kprobe_ctlblk *kcb, struct kprobe *p) { switch (kcb->kprobe_status) { case KPROBE_HIT_SSDONE: @@ -284,8 +295,9 @@ static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb, BUG(); } } +NOKPROBE_SYMBOL(kprobe_reenter_check); -static int __kprobes kprobe_handler(struct pt_regs *regs) +static int kprobe_handler(struct pt_regs *regs) { struct kprobe_ctlblk *kcb; struct kprobe *p; @@ -359,6 +371,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) preempt_enable_no_resched(); return 0; } +NOKPROBE_SYMBOL(kprobe_handler); /* * Function return probe trampoline: @@ -375,8 +388,7 @@ static void __used kretprobe_trampoline_holder(void) /* * Called when the probe at kretprobe trampoline is hit */ -static int __kprobes trampoline_probe_handler(struct kprobe *p, - struct pt_regs *regs) +static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri; struct hlist_head *head, empty_rp; @@ -464,6 +476,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, */ return 1; } +NOKPROBE_SYMBOL(trampoline_probe_handler); /* * Called after single-stepping. p->addr is the address of the @@ -473,7 +486,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, * single-stepped a copy of the instruction. The address of this * copy is p->ainsn.insn. */ -static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) +static void resume_execution(struct kprobe *p, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); unsigned long ip = regs->psw.addr & PSW_ADDR_INSN; @@ -514,8 +527,9 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) disable_singlestep(kcb, regs, ip); } +NOKPROBE_SYMBOL(resume_execution); -static int __kprobes post_kprobe_handler(struct pt_regs *regs) +static int post_kprobe_handler(struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe *p = kprobe_running(); @@ -542,8 +556,9 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) return 1; } +NOKPROBE_SYMBOL(post_kprobe_handler); -static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) +static int kprobe_trap_handler(struct pt_regs *regs, int trapnr) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe *p = kprobe_running(); @@ -605,8 +620,9 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) } return 0; } +NOKPROBE_SYMBOL(kprobe_trap_handler); -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +int kprobe_fault_handler(struct pt_regs *regs, int trapnr) { int ret; @@ -617,12 +633,13 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) local_irq_restore(regs->psw.mask & ~PSW_MASK_PER); return ret; } +NOKPROBE_SYMBOL(kprobe_fault_handler); /* * Wrapper routine to for handling exceptions. */ -int __kprobes kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) +int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data) { struct die_args *args = (struct die_args *) data; struct pt_regs *regs = args->regs; @@ -654,8 +671,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, return ret; } +NOKPROBE_SYMBOL(kprobe_exceptions_notify); -int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) +int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) { struct jprobe *jp = container_of(p, struct jprobe, kp); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -673,13 +691,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack)); return 1; } +NOKPROBE_SYMBOL(setjmp_pre_handler); -void __kprobes jprobe_return(void) +void jprobe_return(void) { asm volatile(".word 0x0002"); } +NOKPROBE_SYMBOL(jprobe_return); -int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) +int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); unsigned long stack; @@ -693,6 +713,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) preempt_enable_no_resched(); return 1; } +NOKPROBE_SYMBOL(longjmp_break_handler); static struct kprobe trampoline = { .addr = (kprobe_opcode_t *) &kretprobe_trampoline, @@ -704,7 +725,8 @@ int __init arch_init_kprobes(void) return register_kprobe(&trampoline); } -int __kprobes arch_trampoline_kprobe(struct kprobe *p) +int arch_trampoline_kprobe(struct kprobe *p) { return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline; } +NOKPROBE_SYMBOL(arch_trampoline_kprobe); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index ed84cc224899..4192dfd55ddc 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -61,7 +61,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return sf->gprs[8]; } -extern void __kprobes kernel_thread_starter(void); +extern void kernel_thread_starter(void); /* * Free current thread data structures etc.. diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 005d665fe4a5..20660dddb2d6 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -61,10 +61,11 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); /* * Scheduler clock - returns current time in nanosec units. */ -unsigned long long notrace __kprobes sched_clock(void) +unsigned long long notrace sched_clock(void) { return tod_to_ns(get_tod_clock_monotonic()); } +NOKPROBE_SYMBOL(sched_clock); /* * Monotonic_clock - returns # of nanoseconds passed since time_init() diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 9ff5ecba26ab..1e1b866b2966 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -87,16 +87,16 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) } } -static void __kprobes do_trap(struct pt_regs *regs, int si_signo, int si_code, - char *str) +static void do_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) { if (notify_die(DIE_TRAP, str, regs, 0, regs->int_code, si_signo) == NOTIFY_STOP) return; do_report_trap(regs, si_signo, si_code, str); } +NOKPROBE_SYMBOL(do_trap); -void __kprobes do_per_trap(struct pt_regs *regs) +void do_per_trap(struct pt_regs *regs) { siginfo_t info; @@ -111,6 +111,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) (void __force __user *) current->thread.per_event.address; force_sig_info(SIGTRAP, &info, current); } +NOKPROBE_SYMBOL(do_per_trap); void default_trap_handler(struct pt_regs *regs) { @@ -179,7 +180,7 @@ static inline void do_fp_trap(struct pt_regs *regs, int fpc) do_trap(regs, SIGFPE, si_code, "floating point exception"); } -void __kprobes illegal_op(struct pt_regs *regs) +void illegal_op(struct pt_regs *regs) { siginfo_t info; __u8 opcode[6]; @@ -252,7 +253,7 @@ void __kprobes illegal_op(struct pt_regs *regs) if (signal) do_trap(regs, signal, ILL_ILLOPC, "illegal operation"); } - +NOKPROBE_SYMBOL(illegal_op); #ifdef CONFIG_MATHEMU void specification_exception(struct pt_regs *regs) @@ -469,7 +470,7 @@ void space_switch_exception(struct pt_regs *regs) do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); } -void __kprobes kernel_stack_overflow(struct pt_regs * regs) +void kernel_stack_overflow(struct pt_regs *regs) { bust_spinlocks(1); printk("Kernel stack overflow.\n"); @@ -477,6 +478,7 @@ void __kprobes kernel_stack_overflow(struct pt_regs * regs) bust_spinlocks(0); panic("Corrupt kernel stack, can't continue."); } +NOKPROBE_SYMBOL(kernel_stack_overflow); void __init trap_init(void) { diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index a2b81d6ce8a5..ca70fad2fc92 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -548,7 +548,7 @@ static inline int do_exception(struct pt_regs *regs, int access) return fault; } -void __kprobes do_protection_exception(struct pt_regs *regs) +void do_protection_exception(struct pt_regs *regs) { unsigned long trans_exc_code; int fault; @@ -574,8 +574,9 @@ void __kprobes do_protection_exception(struct pt_regs *regs) if (unlikely(fault)) do_fault_error(regs, fault); } +NOKPROBE_SYMBOL(do_protection_exception); -void __kprobes do_dat_exception(struct pt_regs *regs) +void do_dat_exception(struct pt_regs *regs) { int access, fault; @@ -584,6 +585,7 @@ void __kprobes do_dat_exception(struct pt_regs *regs) if (unlikely(fault)) do_fault_error(regs, fault); } +NOKPROBE_SYMBOL(do_dat_exception); #ifdef CONFIG_PFAULT /* -- GitLab From 6972cae523de728ad5e8dae01da4a631d98b874c Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Wed, 15 Oct 2014 15:29:01 +0200 Subject: [PATCH 1451/9457] s390/mm: missing pte for gmap_ipte_notify should trigger a VM_BUG After fixup_user_fault does not fail we have a writeable pte. That pte might transform but it should not vanish. Signed-off-by: Dominik Dingel Signed-off-by: Martin Schwidefsky --- arch/s390/mm/pgtable.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index b1871d39e46e..9c8a6dd8a49c 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -752,8 +752,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len) break; /* Walk the process page table, lock and get pte pointer */ ptep = get_locked_pte(gmap->mm, addr, &ptl); - if (unlikely(!ptep)) - continue; + VM_BUG_ON(!ptep); /* Set notification bit in the pgste of the pte */ entry = *ptep; if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) { -- GitLab From fcbe08d66f57c368e77ca729dd01e6b539ffb3ff Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 24 Oct 2014 10:52:29 +0200 Subject: [PATCH 1452/9457] s390/mm: pmdp_get_and_clear_full optimization Analog to ptep_get_and_clear_full define a variant of the pmpd_get_and_clear primitive which gets the full hint from the mmu_gather struct. This allows s390 to avoid a costly instruction when destroying an address space. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 13 +++++++++++++ include/asm-generic/pgtable.h | 11 +++++++++++ mm/huge_memory.c | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 5ef1a266936a..5e102422c9ab 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1651,6 +1651,19 @@ static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, return pmd; } +#define __HAVE_ARCH_PMDP_GET_AND_CLEAR_FULL +static inline pmd_t pmdp_get_and_clear_full(struct mm_struct *mm, + unsigned long address, + pmd_t *pmdp, int full) +{ + pmd_t pmd = *pmdp; + + if (!full) + pmdp_flush_lazy(mm, address, pmdp); + pmd_clear(pmdp); + return pmd; +} + #define __HAVE_ARCH_PMDP_CLEAR_FLUSH static inline pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 752e30d63904..177d5973b132 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -103,6 +103,17 @@ static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif +#ifndef __HAVE_ARCH_PMDP_GET_AND_CLEAR_FULL +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline pmd_t pmdp_get_and_clear_full(struct mm_struct *mm, + unsigned long address, pmd_t *pmdp, + int full) +{ + return pmdp_get_and_clear(mm, address, pmdp); +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +#endif + #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long address, pte_t *ptep, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 7e9c15cb93a9..6a37f1b2ed1e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1400,7 +1400,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, * pgtable_trans_huge_withdraw after finishing pmdp related * operations. */ - orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd); + orig_pmd = pmdp_get_and_clear_full(tlb->mm, addr, pmd, + tlb->fullmm); tlb_remove_pmd_tlb_entry(tlb, pmd, addr); pgtable = pgtable_trans_huge_withdraw(tlb->mm, pmd); if (is_huge_zero_pmd(orig_pmd)) { -- GitLab From 66797f36fd17e8975f4a3449aed895cda952c0ce Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 27 Oct 2014 15:15:44 +0100 Subject: [PATCH 1453/9457] ALSA: hda - Pass printf argument directly to request_module() request_module() handles the printf style arguments, so we don't have to render strings in the caller side. Not only it reduces the unnecessary temporary string buffer, it's even safer from the security POV. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 259fbeaa37bd..0025bf4c2f44 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -966,14 +966,12 @@ find_codec_preset(struct hda_codec *codec) mutex_unlock(&preset_mutex); if (mod_requested < HDA_MODREQ_MAX_COUNT) { - char name[32]; if (!mod_requested) - snprintf(name, sizeof(name), "snd-hda-codec-id:%08x", - codec->vendor_id); + request_module("snd-hda-codec-id:%08x", + codec->vendor_id); else - snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*", - (codec->vendor_id >> 16) & 0xffff); - request_module(name); + request_module("snd-hda-codec-id:%04x*", + (codec->vendor_id >> 16) & 0xffff); mod_requested++; goto again; } -- GitLab From f8b361768ea2eaf9b21dfbe7388958ec31798c8b Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:53 +0100 Subject: [PATCH 1454/9457] 6lowpan: remove skb_deliver from IPHC Separating skb delivery from decompression ensures that we can support further decompression schemes and removes the mixed return value of error codes with NET_RX_FOO. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- include/net/6lowpan.h | 4 +--- net/6lowpan/iphc.c | 32 +++++---------------------- net/bluetooth/6lowpan.c | 14 ++++++++++-- net/ieee802154/6lowpan_rtnl.c | 41 ++++++++++++++++++++++------------- 4 files changed, 45 insertions(+), 46 deletions(-) diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index d184df1d0d41..abfa3593e911 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset) return skb->len + uncomp_header - ret; } -typedef int (*skb_delivery_cb)(struct sk_buff *skb, struct net_device *dev); - int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, const u8 *saddr, const u8 saddr_type, const u8 saddr_len, const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1, skb_delivery_cb skb_deliver); + u8 iphc0, u8 iphc1); int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len); diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 747b3ccfc4f8..45714fe885f0 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb, return 0; } -static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, - struct net_device *dev, skb_delivery_cb deliver_skb) -{ - int stat; - - skb_push(skb, sizeof(struct ipv6hdr)); - skb_reset_network_header(skb); - skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr)); - - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - skb->dev = dev; - - raw_dump_table(__func__, "raw skb data dump before receiving", - skb->data, skb->len); - - stat = deliver_skb(skb, dev); - - consume_skb(skb); - - return stat; -} - /* Uncompress function for multicast destination address, * when M bit is set. */ @@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, const u8 *saddr, const u8 saddr_type, const u8 saddr_len, const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb) + u8 iphc0, u8 iphc1) { struct ipv6hdr hdr = {}; u8 tmp, num_context = 0; @@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, hdr.hop_limit, &hdr.daddr); - raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); + skb_push(skb, sizeof(hdr)); + skb_reset_network_header(skb); + skb_copy_to_linear_data(skb, &hdr, sizeof(hdr)); - return skb_deliver(skb, &hdr, dev, deliver_skb); + raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); + return 0; drop: kfree_skb(skb); return -EINVAL; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 6c5c2eff45bd..45d9a9fef634 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -252,7 +252,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) - return -ENOMEM; + return NET_RX_DROP; return netif_rx(skb_cp); } @@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev, return lowpan_process_data(skb, netdev, saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - iphc0, iphc1, give_skb_to_upper); + iphc0, iphc1); drop: kfree_skb(skb); @@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (ret != NET_RX_SUCCESS) goto drop; + local_skb->protocol = htons(ETH_P_IPV6); + local_skb->pkt_type = PACKET_HOST; + local_skb->dev = dev; + + if (give_skb_to_upper(local_skb, dev) + != NET_RX_SUCCESS) { + kfree_skb(local_skb); + goto drop; + } + dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 1779a08d110a..15c7717c5e06 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -141,20 +141,28 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb, struct sk_buff *skb_cp; int stat = NET_RX_SUCCESS; + skb->protocol = htons(ETH_P_IPV6); + skb->pkt_type = PACKET_HOST; + rcu_read_lock(); list_for_each_entry_rcu(entry, &lowpan_devices, list) if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) { skb_cp = skb_copy(skb, GFP_ATOMIC); if (!skb_cp) { - stat = -ENOMEM; - break; + kfree_skb(skb); + rcu_read_unlock(); + return NET_RX_DROP; } skb_cp->dev = entry->ldev; stat = netif_rx(skb_cp); + if (stat == NET_RX_DROP) + break; } rcu_read_unlock(); + consume_skb(skb); + return stat; } @@ -190,8 +198,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, IEEE802154_ADDR_LEN, dap, da.addr_type, - IEEE802154_ADDR_LEN, iphc0, iphc1, - lowpan_give_skb_to_devices); + IEEE802154_ADDR_LEN, iphc0, iphc1); drop: kfree_skb(skb); @@ -528,44 +535,48 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, /* check that it's our buffer */ if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { - skb->protocol = htons(ETH_P_IPV6); - skb->pkt_type = PACKET_HOST; - /* Pull off the 1-byte of 6lowpan header. */ skb_pull(skb, 1); - - ret = lowpan_give_skb_to_devices(skb, NULL); - if (ret == NET_RX_DROP) - goto drop; + return lowpan_give_skb_to_devices(skb, NULL); } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; - break; + + return lowpan_give_skb_to_devices(skb, NULL); case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; + + return lowpan_give_skb_to_devices(skb, NULL); + } else if (ret == -1) { + return NET_RX_DROP; + } else { + return NET_RX_SUCCESS; } - break; case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { ret = process_data(skb, &hdr); if (ret == NET_RX_DROP) goto drop; + + return lowpan_give_skb_to_devices(skb, NULL); + } else if (ret == -1) { + return NET_RX_DROP; + } else { + return NET_RX_SUCCESS; } - break; default: break; } } - return NET_RX_SUCCESS; drop_skb: kfree_skb(skb); drop: -- GitLab From 04dfd7386ab7a0f016bbcf30b3a5051650242120 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:54 +0100 Subject: [PATCH 1455/9457] 6lowpan: fix process_data return values As process_data now returns just error codes fix up the calls to this function to only drop the skb if an error code is returned. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 2 +- net/ieee802154/6lowpan_rtnl.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 45d9a9fef634..94bbb6611bc5 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -347,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, goto drop; ret = process_data(local_skb, dev, chan); - if (ret != NET_RX_SUCCESS) + if (ret < 0) goto drop; local_skb->protocol = htons(ETH_P_IPV6); diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 15c7717c5e06..21742c827475 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -542,7 +542,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); @@ -550,7 +550,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); @@ -563,7 +563,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { ret = process_data(skb, &hdr); - if (ret == NET_RX_DROP) + if (ret < 0) goto drop; return lowpan_give_skb_to_devices(skb, NULL); -- GitLab From 3c400b843d4c07703b68e91854bc395c95e4c51a Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:55 +0100 Subject: [PATCH 1456/9457] bluetooth:6lowpan: use consume_skb when packet processed successfully Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 94bbb6611bc5..40e2cec7fcef 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -337,8 +337,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; - kfree_skb(local_skb); - kfree_skb(skb); + consume_skb(local_skb); + consume_skb(skb); } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ @@ -363,7 +363,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; - kfree_skb(skb); + consume_skb(local_skb); + consume_skb(skb); break; default: break; -- GitLab From 01141234f237957ec962dda2f1ca89d9ef180884 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 23 Oct 2014 15:40:56 +0100 Subject: [PATCH 1457/9457] ieee802154: 6lowpan: rename process_data and lowpan_process_data As we have decouple decompression from data delivery we can now rename all occurences of process_data in receive path. Signed-off-by: Martin Townsend Acked-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- include/net/6lowpan.h | 10 ++++++---- net/6lowpan/iphc.c | 12 +++++++----- net/bluetooth/6lowpan.c | 15 ++++++++------- net/ieee802154/6lowpan_rtnl.c | 15 ++++++++------- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index abfa3593e911..dc03d77ad23b 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -372,10 +372,12 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset) return skb->len + uncomp_header - ret; } -int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, - const u8 *saddr, const u8 saddr_type, const u8 saddr_len, - const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1); +int +lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, + const u8 *saddr, const u8 saddr_type, + const u8 saddr_len, const u8 *daddr, + const u8 daddr_type, const u8 daddr_len, + u8 iphc0, u8 iphc1); int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len); diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 45714fe885f0..73a7065f0c6b 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -301,10 +301,12 @@ static int uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh) /* TTL uncompression values */ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; -int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, - const u8 *saddr, const u8 saddr_type, const u8 saddr_len, - const u8 *daddr, const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1) +int +lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, + const u8 *saddr, const u8 saddr_type, + const u8 saddr_len, const u8 *daddr, + const u8 daddr_type, const u8 daddr_len, + u8 iphc0, u8 iphc1) { struct ipv6hdr hdr = {}; u8 tmp, num_context = 0; @@ -480,7 +482,7 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, kfree_skb(skb); return -EINVAL; } -EXPORT_SYMBOL_GPL(lowpan_process_data); +EXPORT_SYMBOL_GPL(lowpan_header_decompress); static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift, const struct in6_addr *ipaddr, diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 40e2cec7fcef..aa6ebbfc5d31 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -257,8 +257,8 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) return netif_rx(skb_cp); } -static int process_data(struct sk_buff *skb, struct net_device *netdev, - struct l2cap_chan *chan) +static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, + struct l2cap_chan *chan) { const u8 *saddr, *daddr; u8 iphc0, iphc1; @@ -287,10 +287,11 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev, if (lowpan_fetch_skb_u8(skb, &iphc1)) goto drop; - return lowpan_process_data(skb, netdev, - saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, - iphc0, iphc1); + return lowpan_header_decompress(skb, netdev, + saddr, IEEE802154_ADDR_LONG, + EUI64_ADDR_LEN, daddr, + IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, + iphc0, iphc1); drop: kfree_skb(skb); @@ -346,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, if (!local_skb) goto drop; - ret = process_data(local_skb, dev, chan); + ret = iphc_decompress(local_skb, dev, chan); if (ret < 0) goto drop; diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 21742c827475..519a65452d90 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -166,7 +166,8 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb, return stat; } -static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) +static int +iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) { u8 iphc0, iphc1; struct ieee802154_addr_sa sa, da; @@ -196,9 +197,9 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) else dap = &da.hwaddr; - return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, - IEEE802154_ADDR_LEN, dap, da.addr_type, - IEEE802154_ADDR_LEN, iphc0, iphc1); + return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, + IEEE802154_ADDR_LEN, dap, da.addr_type, + IEEE802154_ADDR_LEN, iphc0, iphc1); drop: kfree_skb(skb); @@ -541,7 +542,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, } else { switch (skb->data[0] & 0xe0) { case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; @@ -549,7 +550,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1); if (ret == 1) { - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; @@ -562,7 +563,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN); if (ret == 1) { - ret = process_data(skb, &hdr); + ret = iphc_decompress(skb, &hdr); if (ret < 0) goto drop; -- GitLab From 8447a0fee974433f7e0035fd30e1edecf00e014f Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Mon, 20 Oct 2014 15:50:29 +0400 Subject: [PATCH 1458/9457] cpuset: convert callback_mutex to a spinlock The callback_mutex is only used to synchronize reads/updates of cpusets' flags and cpu/node masks. These operations should always proceed fast so there's no reason why we can't use a spinlock instead of the mutex. Converting the callback_mutex into a spinlock will let us call cpuset_zone_allowed_softwall from atomic context. This, in turn, makes it possible to simplify the code by merging the hardwall and asoftwall checks into the same function, which is the business of the next patch. Suggested-by: Zefan Li Signed-off-by: Vladimir Davydov Acked-by: Christoph Lameter Acked-by: Zefan Li Signed-off-by: Tejun Heo --- kernel/cpuset.c | 107 +++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1f107c74087b..f21ba868f0d1 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -248,34 +248,34 @@ static struct cpuset top_cpuset = { if (is_cpuset_online(((des_cs) = css_cs((pos_css))))) /* - * There are two global mutexes guarding cpuset structures - cpuset_mutex - * and callback_mutex. The latter may nest inside the former. We also - * require taking task_lock() when dereferencing a task's cpuset pointer. - * See "The task_lock() exception", at the end of this comment. + * There are two global locks guarding cpuset structures - cpuset_mutex and + * callback_lock. We also require taking task_lock() when dereferencing a + * task's cpuset pointer. See "The task_lock() exception", at the end of this + * comment. * - * A task must hold both mutexes to modify cpusets. If a task holds + * A task must hold both locks to modify cpusets. If a task holds * cpuset_mutex, then it blocks others wanting that mutex, ensuring that it - * is the only task able to also acquire callback_mutex and be able to + * is the only task able to also acquire callback_lock and be able to * modify cpusets. It can perform various checks on the cpuset structure * first, knowing nothing will change. It can also allocate memory while * just holding cpuset_mutex. While it is performing these checks, various - * callback routines can briefly acquire callback_mutex to query cpusets. - * Once it is ready to make the changes, it takes callback_mutex, blocking + * callback routines can briefly acquire callback_lock to query cpusets. + * Once it is ready to make the changes, it takes callback_lock, blocking * everyone else. * * Calls to the kernel memory allocator can not be made while holding - * callback_mutex, as that would risk double tripping on callback_mutex + * callback_lock, as that would risk double tripping on callback_lock * from one of the callbacks into the cpuset code from within * __alloc_pages(). * - * If a task is only holding callback_mutex, then it has read-only + * If a task is only holding callback_lock, then it has read-only * access to cpusets. * * Now, the task_struct fields mems_allowed and mempolicy may be changed * by other task, we use alloc_lock in the task_struct fields to protect * them. * - * The cpuset_common_file_read() handlers only hold callback_mutex across + * The cpuset_common_file_read() handlers only hold callback_lock across * small pieces of code, such as when reading out possibly multi-word * cpumasks and nodemasks. * @@ -284,7 +284,7 @@ static struct cpuset top_cpuset = { */ static DEFINE_MUTEX(cpuset_mutex); -static DEFINE_MUTEX(callback_mutex); +static DEFINE_SPINLOCK(callback_lock); /* * CPU / memory hotplug is handled asynchronously. @@ -329,7 +329,7 @@ static struct file_system_type cpuset_fs_type = { * One way or another, we guarantee to return some non-empty subset * of cpu_online_mask. * - * Call with callback_mutex held. + * Call with callback_lock or cpuset_mutex held. */ static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask) { @@ -347,7 +347,7 @@ static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask) * One way or another, we guarantee to return some non-empty subset * of node_states[N_MEMORY]. * - * Call with callback_mutex held. + * Call with callback_lock or cpuset_mutex held. */ static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) { @@ -359,7 +359,7 @@ static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) /* * update task's spread flag if cpuset's page/slab spread flag is set * - * Called with callback_mutex/cpuset_mutex held + * Call with callback_lock or cpuset_mutex held. */ static void cpuset_update_task_spread_flag(struct cpuset *cs, struct task_struct *tsk) @@ -876,9 +876,9 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) continue; rcu_read_unlock(); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cpumask_copy(cp->effective_cpus, new_cpus); - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); WARN_ON(!cgroup_on_dfl(cp->css.cgroup) && !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); @@ -943,9 +943,9 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, if (retval < 0) return retval; - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); /* use trialcs->cpus_allowed as a temp variable */ update_cpumasks_hier(cs, trialcs->cpus_allowed); @@ -1132,9 +1132,9 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) continue; rcu_read_unlock(); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cp->effective_mems = *new_mems; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); WARN_ON(!cgroup_on_dfl(cp->css.cgroup) && !nodes_equal(cp->mems_allowed, cp->effective_mems)); @@ -1155,7 +1155,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) * mempolicies and if the cpuset is marked 'memory_migrate', * migrate the tasks pages to the new memory. * - * Call with cpuset_mutex held. May take callback_mutex during call. + * Call with cpuset_mutex held. May take callback_lock during call. * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, * lock each such tasks mm->mmap_sem, scan its vma's and rebind * their mempolicies to the cpusets new mems_allowed. @@ -1202,9 +1202,9 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, if (retval < 0) goto done; - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cs->mems_allowed = trialcs->mems_allowed; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); /* use trialcs->mems_allowed as a temp variable */ update_nodemasks_hier(cs, &cs->mems_allowed); @@ -1295,9 +1295,9 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs)) || (is_spread_page(cs) != is_spread_page(trialcs))); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cs->flags = trialcs->flags; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) rebuild_sched_domains_locked(); @@ -1713,7 +1713,7 @@ static int cpuset_common_seq_show(struct seq_file *sf, void *v) count = seq_get_buf(sf, &buf); s = buf; - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); switch (type) { case FILE_CPULIST: @@ -1740,7 +1740,7 @@ static int cpuset_common_seq_show(struct seq_file *sf, void *v) seq_commit(sf, -1); } out_unlock: - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); return ret; } @@ -1957,12 +1957,12 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) cpuset_inc(); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); if (cgroup_on_dfl(cs->css.cgroup)) { cpumask_copy(cs->effective_cpus, parent->effective_cpus); cs->effective_mems = parent->effective_mems; } - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) goto out_unlock; @@ -1989,10 +1989,10 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) } rcu_read_unlock(); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cs->mems_allowed = parent->mems_allowed; cpumask_copy(cs->cpus_allowed, parent->cpus_allowed); - mutex_unlock(&callback_mutex); + spin_lock_irq(&callback_lock); out_unlock: mutex_unlock(&cpuset_mutex); return 0; @@ -2031,7 +2031,7 @@ static void cpuset_css_free(struct cgroup_subsys_state *css) static void cpuset_bind(struct cgroup_subsys_state *root_css) { mutex_lock(&cpuset_mutex); - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); if (cgroup_on_dfl(root_css->cgroup)) { cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask); @@ -2042,7 +2042,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) top_cpuset.mems_allowed = top_cpuset.effective_mems; } - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); mutex_unlock(&cpuset_mutex); } @@ -2127,12 +2127,12 @@ hotplug_update_tasks_legacy(struct cpuset *cs, { bool is_empty; - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cpumask_copy(cs->cpus_allowed, new_cpus); cpumask_copy(cs->effective_cpus, new_cpus); cs->mems_allowed = *new_mems; cs->effective_mems = *new_mems; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); /* * Don't call update_tasks_cpumask() if the cpuset becomes empty, @@ -2169,10 +2169,10 @@ hotplug_update_tasks(struct cpuset *cs, if (nodes_empty(*new_mems)) *new_mems = parent_cs(cs)->effective_mems; - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); cpumask_copy(cs->effective_cpus, new_cpus); cs->effective_mems = *new_mems; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); if (cpus_updated) update_tasks_cpumask(cs); @@ -2258,21 +2258,21 @@ static void cpuset_hotplug_workfn(struct work_struct *work) /* synchronize cpus_allowed to cpu_active_mask */ if (cpus_updated) { - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); if (!on_dfl) cpumask_copy(top_cpuset.cpus_allowed, &new_cpus); cpumask_copy(top_cpuset.effective_cpus, &new_cpus); - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); /* we don't mess with cpumasks of tasks in top_cpuset */ } /* synchronize mems_allowed to N_MEMORY */ if (mems_updated) { - mutex_lock(&callback_mutex); + spin_lock_irq(&callback_lock); if (!on_dfl) top_cpuset.mems_allowed = new_mems; top_cpuset.effective_mems = new_mems; - mutex_unlock(&callback_mutex); + spin_unlock_irq(&callback_lock); update_tasks_nodemask(&top_cpuset); } @@ -2365,11 +2365,13 @@ void __init cpuset_init_smp(void) void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask) { - mutex_lock(&callback_mutex); + unsigned long flags; + + spin_lock_irqsave(&callback_lock, flags); rcu_read_lock(); guarantee_online_cpus(task_cs(tsk), pmask); rcu_read_unlock(); - mutex_unlock(&callback_mutex); + spin_unlock_irqrestore(&callback_lock, flags); } void cpuset_cpus_allowed_fallback(struct task_struct *tsk) @@ -2415,12 +2417,13 @@ void cpuset_init_current_mems_allowed(void) nodemask_t cpuset_mems_allowed(struct task_struct *tsk) { nodemask_t mask; + unsigned long flags; - mutex_lock(&callback_mutex); + spin_lock_irqsave(&callback_lock, flags); rcu_read_lock(); guarantee_online_mems(task_cs(tsk), &mask); rcu_read_unlock(); - mutex_unlock(&callback_mutex); + spin_unlock_irqrestore(&callback_lock, flags); return mask; } @@ -2439,7 +2442,7 @@ int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) /* * nearest_hardwall_ancestor() - Returns the nearest mem_exclusive or * mem_hardwall ancestor to the specified cpuset. Call holding - * callback_mutex. If no ancestor is mem_exclusive or mem_hardwall + * callback_lock. If no ancestor is mem_exclusive or mem_hardwall * (an unusual configuration), then returns the root cpuset. */ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) @@ -2481,13 +2484,12 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) * GFP_KERNEL allocations are not so marked, so can escape to the * nearest enclosing hardwalled ancestor cpuset. * - * Scanning up parent cpusets requires callback_mutex. The + * Scanning up parent cpusets requires callback_lock. The * __alloc_pages() routine only calls here with __GFP_HARDWALL bit * _not_ set if it's a GFP_KERNEL allocation, and all nodes in the * current tasks mems_allowed came up empty on the first pass over * the zonelist. So only GFP_KERNEL allocations, if all nodes in the - * cpuset are short of memory, might require taking the callback_mutex - * mutex. + * cpuset are short of memory, might require taking the callback_lock. * * The first call here from mm/page_alloc:get_page_from_freelist() * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, @@ -2514,6 +2516,7 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) { struct cpuset *cs; /* current cpuset ancestors */ int allowed; /* is allocation in zone z allowed? */ + unsigned long flags; if (in_interrupt() || (gfp_mask & __GFP_THISNODE)) return 1; @@ -2533,14 +2536,14 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) return 1; /* Not hardwall and node outside mems_allowed: scan up cpusets */ - mutex_lock(&callback_mutex); + spin_lock_irqsave(&callback_lock, flags); rcu_read_lock(); cs = nearest_hardwall_ancestor(task_cs(current)); allowed = node_isset(node, cs->mems_allowed); rcu_read_unlock(); - mutex_unlock(&callback_mutex); + spin_unlock_irqrestore(&callback_lock, flags); return allowed; } -- GitLab From 344736f29b359790facd0b7a521e367f1715c11c Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Mon, 20 Oct 2014 15:50:30 +0400 Subject: [PATCH 1459/9457] cpuset: simplify cpuset_node_allowed API Current cpuset API for checking if a zone/node is allowed to allocate from looks rather awkward. We have hardwall and softwall versions of cpuset_node_allowed with the softwall version doing literally the same as the hardwall version if __GFP_HARDWALL is passed to it in gfp flags. If it isn't, the softwall version may check the given node against the enclosing hardwall cpuset, which it needs to take the callback lock to do. Such a distinction was introduced by commit 02a0e53d8227 ("cpuset: rework cpuset_zone_allowed api"). Before, we had the only version with the __GFP_HARDWALL flag determining its behavior. The purpose of the commit was to avoid sleep-in-atomic bugs when someone would mistakenly call the function without the __GFP_HARDWALL flag for an atomic allocation. The suffixes introduced were intended to make the callers think before using the function. However, since the callback lock was converted from mutex to spinlock by the previous patch, the softwall check function cannot sleep, and these precautions are no longer necessary. So let's simplify the API back to the single check. Suggested-by: David Rientjes Signed-off-by: Vladimir Davydov Acked-by: Christoph Lameter Acked-by: Zefan Li Signed-off-by: Tejun Heo --- include/linux/cpuset.h | 37 ++++++---------------------- kernel/cpuset.c | 55 ++---------------------------------------- mm/hugetlb.c | 2 +- mm/oom_kill.c | 2 +- mm/page_alloc.c | 6 ++--- mm/slab.c | 2 +- mm/slub.c | 3 ++- mm/vmscan.c | 5 ++-- 8 files changed, 20 insertions(+), 92 deletions(-) diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 2f073db7392e..1b357997cac5 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -48,29 +48,16 @@ extern nodemask_t cpuset_mems_allowed(struct task_struct *p); void cpuset_init_current_mems_allowed(void); int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask); -extern int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask); -extern int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask); +extern int __cpuset_node_allowed(int node, gfp_t gfp_mask); -static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) +static inline int cpuset_node_allowed(int node, gfp_t gfp_mask) { - return nr_cpusets() <= 1 || - __cpuset_node_allowed_softwall(node, gfp_mask); + return nr_cpusets() <= 1 || __cpuset_node_allowed(node, gfp_mask); } -static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask) +static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask) { - return nr_cpusets() <= 1 || - __cpuset_node_allowed_hardwall(node, gfp_mask); -} - -static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask) -{ - return cpuset_node_allowed_softwall(zone_to_nid(z), gfp_mask); -} - -static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask) -{ - return cpuset_node_allowed_hardwall(zone_to_nid(z), gfp_mask); + return cpuset_node_allowed(zone_to_nid(z), gfp_mask); } extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1, @@ -179,22 +166,12 @@ static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) return 1; } -static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) -{ - return 1; -} - -static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask) -{ - return 1; -} - -static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask) +static inline int cpuset_node_allowed(int node, gfp_t gfp_mask) { return 1; } -static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask) +static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask) { return 1; } diff --git a/kernel/cpuset.c b/kernel/cpuset.c index f21ba868f0d1..38f7433c1cd2 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -2453,7 +2453,7 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) } /** - * cpuset_node_allowed_softwall - Can we allocate on a memory node? + * cpuset_node_allowed - Can we allocate on a memory node? * @node: is this an allowed node? * @gfp_mask: memory allocation flags * @@ -2465,13 +2465,6 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) * flag, yes. * Otherwise, no. * - * If __GFP_HARDWALL is set, cpuset_node_allowed_softwall() reduces to - * cpuset_node_allowed_hardwall(). Otherwise, cpuset_node_allowed_softwall() - * might sleep, and might allow a node from an enclosing cpuset. - * - * cpuset_node_allowed_hardwall() only handles the simpler case of hardwall - * cpusets, and never sleeps. - * * The __GFP_THISNODE placement logic is really handled elsewhere, * by forcibly using a zonelist starting at a specified node, and by * (in get_page_from_freelist()) refusing to consider the zones for @@ -2506,13 +2499,8 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs) * TIF_MEMDIE - any node ok * GFP_KERNEL - any node in enclosing hardwalled cpuset ok * GFP_USER - only nodes in current tasks mems allowed ok. - * - * Rule: - * Don't call cpuset_node_allowed_softwall if you can't sleep, unless you - * pass in the __GFP_HARDWALL flag set in gfp_flag, which disables - * the code that might scan up ancestor cpusets and sleep. */ -int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) +int __cpuset_node_allowed(int node, gfp_t gfp_mask) { struct cpuset *cs; /* current cpuset ancestors */ int allowed; /* is allocation in zone z allowed? */ @@ -2520,7 +2508,6 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) if (in_interrupt() || (gfp_mask & __GFP_THISNODE)) return 1; - might_sleep_if(!(gfp_mask & __GFP_HARDWALL)); if (node_isset(node, current->mems_allowed)) return 1; /* @@ -2547,44 +2534,6 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask) return allowed; } -/* - * cpuset_node_allowed_hardwall - Can we allocate on a memory node? - * @node: is this an allowed node? - * @gfp_mask: memory allocation flags - * - * If we're in interrupt, yes, we can always allocate. If __GFP_THISNODE is - * set, yes, we can always allocate. If node is in our task's mems_allowed, - * yes. If the task has been OOM killed and has access to memory reserves as - * specified by the TIF_MEMDIE flag, yes. - * Otherwise, no. - * - * The __GFP_THISNODE placement logic is really handled elsewhere, - * by forcibly using a zonelist starting at a specified node, and by - * (in get_page_from_freelist()) refusing to consider the zones for - * any node on the zonelist except the first. By the time any such - * calls get to this routine, we should just shut up and say 'yes'. - * - * Unlike the cpuset_node_allowed_softwall() variant, above, - * this variant requires that the node be in the current task's - * mems_allowed or that we're in interrupt. It does not scan up the - * cpuset hierarchy for the nearest enclosing mem_exclusive cpuset. - * It never sleeps. - */ -int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask) -{ - if (in_interrupt() || (gfp_mask & __GFP_THISNODE)) - return 1; - if (node_isset(node, current->mems_allowed)) - return 1; - /* - * Allow tasks that have access to memory reserves because they have - * been OOM killed to get memory anywhere. - */ - if (unlikely(test_thread_flag(TIF_MEMDIE))) - return 1; - return 0; -} - /** * cpuset_mem_spread_node() - On which node to begin search for a file page * cpuset_slab_spread_node() - On which node to begin search for a slab page diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9fd722769927..82da930fa3f8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -582,7 +582,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, for_each_zone_zonelist_nodemask(zone, z, zonelist, MAX_NR_ZONES - 1, nodemask) { - if (cpuset_zone_allowed_softwall(zone, htlb_alloc_mask(h))) { + if (cpuset_zone_allowed(zone, htlb_alloc_mask(h))) { page = dequeue_huge_page_node(h, zone_to_nid(zone)); if (page) { if (avoid_reserve) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 5340f6b91312..3348280eef89 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -233,7 +233,7 @@ static enum oom_constraint constrained_alloc(struct zonelist *zonelist, /* Check this allocation failure is caused by cpuset's wall function */ for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx, nodemask) - if (!cpuset_zone_allowed_softwall(zone, gfp_mask)) + if (!cpuset_zone_allowed(zone, gfp_mask)) cpuset_limited = true; if (cpuset_limited) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9cd36b822444..ab07b496672f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1962,7 +1962,7 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order, /* * Scan zonelist, looking for a zone with enough free. - * See also __cpuset_node_allowed_softwall() comment in kernel/cpuset.c. + * See also __cpuset_node_allowed() comment in kernel/cpuset.c. */ for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx, nodemask) { @@ -1973,7 +1973,7 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order, continue; if (cpusets_enabled() && (alloc_flags & ALLOC_CPUSET) && - !cpuset_zone_allowed_softwall(zone, gfp_mask)) + !cpuset_zone_allowed(zone, gfp_mask)) continue; /* * Distribute pages in proportion to the individual @@ -2514,7 +2514,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask) alloc_flags |= ALLOC_HARDER; /* * Ignore cpuset mems for GFP_ATOMIC rather than fail, see the - * comment for __cpuset_node_allowed_softwall(). + * comment for __cpuset_node_allowed(). */ alloc_flags &= ~ALLOC_CPUSET; } else if (unlikely(rt_task(current)) && !in_interrupt()) diff --git a/mm/slab.c b/mm/slab.c index eb2b2ea30130..063a91bc8826 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -3012,7 +3012,7 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { nid = zone_to_nid(zone); - if (cpuset_zone_allowed_hardwall(zone, flags) && + if (cpuset_zone_allowed(zone, flags | __GFP_HARDWALL) && get_node(cache, nid) && get_node(cache, nid)->free_objects) { obj = ____cache_alloc_node(cache, diff --git a/mm/slub.c b/mm/slub.c index ae7b9f1ad394..7d12f51d9bac 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1662,7 +1662,8 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags, n = get_node(s, zone_to_nid(zone)); - if (n && cpuset_zone_allowed_hardwall(zone, flags) && + if (n && cpuset_zone_allowed(zone, + flags | __GFP_HARDWALL) && n->nr_partial > s->min_partial) { object = get_partial_node(s, n, c, flags); if (object) { diff --git a/mm/vmscan.c b/mm/vmscan.c index dcb47074ae03..38878b2ab1d0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2405,7 +2405,8 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) * to global LRU. */ if (global_reclaim(sc)) { - if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) + if (!cpuset_zone_allowed(zone, + GFP_KERNEL | __GFP_HARDWALL)) continue; lru_pages += zone_reclaimable_pages(zone); @@ -3388,7 +3389,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx) if (!populated_zone(zone)) return; - if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) + if (!cpuset_zone_allowed(zone, GFP_KERNEL | __GFP_HARDWALL)) return; pgdat = zone->zone_pgdat; if (pgdat->kswapd_max_order < order) { -- GitLab From 8fb87deb95ce3a0fa320ebc9df19f6f928714861 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Wed, 1 Oct 2014 15:33:00 +0530 Subject: [PATCH 1460/9457] gpio: amd8111: unmap ioport on failure case This change unmaps ioport when gpiochip_add fails Signed-off-by: Pramod Gurav Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-amd8111.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c index 3c09f1a6872a..d3d2d1099f64 100644 --- a/drivers/gpio/gpio-amd8111.c +++ b/drivers/gpio/gpio-amd8111.c @@ -223,6 +223,7 @@ static int __init amd_gpio_init(void) if (err) { printk(KERN_ERR "GPIO registering failed (%d)\n", err); + ioport_unmap(gp.pm); release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE); goto out; } -- GitLab From cea74465e27b1306a237087fca2f5f0befcf1daf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 27 Oct 2014 16:27:02 +0300 Subject: [PATCH 1461/9457] cpuset: lock vs unlock typo This will deadlock instead of unlocking. Fixes: f73eae8d8384 ('cpuset: simplify cpuset_node_allowed API') Signed-off-by: Dan Carpenter Acked-by: Vladimir Davydov Signed-off-by: Tejun Heo --- kernel/cpuset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 38f7433c1cd2..4eaa203aa953 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1992,7 +1992,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) spin_lock_irq(&callback_lock); cs->mems_allowed = parent->mems_allowed; cpumask_copy(cs->cpus_allowed, parent->cpus_allowed); - spin_lock_irq(&callback_lock); + spin_unlock_irq(&callback_lock); out_unlock: mutex_unlock(&cpuset_mutex); return 0; -- GitLab From 061ef8f915988839b12460c47ebfcf3700e124f0 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:28 +0100 Subject: [PATCH 1462/9457] mac802154: tx: use put_unaligned_le16 for copy crc This patch replaces the memcpy with a put_unaligned_le16. The placement of crc inside of PSDU can also be unaligned. With memcpy this can fail on some architectures. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index fe2e17e6fee3..31e51e4635e4 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -84,9 +85,9 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) mac802154_monitors_rx(local, skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { - __le16 crc = cpu_to_le16(crc_ccitt(0, skb->data, skb->len)); + u16 crc = crc_ccitt(0, skb->data, skb->len); - memcpy(skb_put(skb, 2), &crc, 2); + put_unaligned_le16(crc, skb_put(skb, 2)); } if (skb_cow_head(skb, local->hw.extra_tx_headroom)) -- GitLab From 61a2281458956db519f2c24fa40bf277adea2a67 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:29 +0100 Subject: [PATCH 1463/9457] ieee802154: drivers: use dev_alloc_skb This patch change the allocation of skb inside the ieee802154 driver layer to dev_alloc_skb. This changes also the gfp mask to GFP_ATOMIC which is needed for upcomming change that the receiving is done by a tasklet and not a workqueue anymore. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 0669783aa3b9..e4fbcaa602b6 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -811,7 +811,7 @@ at86rf230_rx(struct at86rf230_local *lp, memcpy(rx_local_buf, data, len); enable_irq(lp->spi->irq); - skb = alloc_skb(IEEE802154_MTU, GFP_ATOMIC); + skb = dev_alloc_skb(IEEE802154_MTU); if (!skb) { dev_vdbg(&lp->spi->dev, "failed to allocate sk_buff\n"); return; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index f6f07f4eb0ec..a31b5b62a353 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -524,7 +524,7 @@ static int cc2520_rx(struct cc2520_private *priv) if (len < 2 || len > IEEE802154_MTU) return -EINVAL; - skb = alloc_skb(len, GFP_KERNEL); + skb = dev_alloc_skb(len); if (!skb) return -ENOMEM; diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 3d775afa217f..7abb237cb989 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -544,7 +544,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) val |= 4; /* SET RXDECINV */ write_short_reg(devrec, REG_BBREG1, val); - skb = alloc_skb(len, GFP_KERNEL); + skb = dev_alloc_skb(len); if (!skb) { ret = -ENOMEM; goto out; -- GitLab From c5c47e67bcd24638a059b1b5e9ec18c95f8634ca Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:30 +0100 Subject: [PATCH 1464/9457] mac802154: rx: use tasklet instead workqueue Tasklets have much less overhead than workqueues. This patch also removes the heap allocation for the worker on receiving path. Like mac80211 we should prefer use a tasklet here instead a workqueue to getting fast out of interrupt context when ieee802154_rx_irqsafe is called by driver. Like wireless inside the tasklet context we should call netif_receive_skb instead netif_rx_ni anymore. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 1 + net/mac802154/ieee802154_i.h | 7 ++++++ net/mac802154/iface.c | 2 +- net/mac802154/main.c | 30 ++++++++++++++++++++++ net/mac802154/rx.c | 48 ++++++------------------------------ 5 files changed, 47 insertions(+), 41 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 942dd53d4658..4c4642ef244f 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -202,6 +202,7 @@ void ieee802154_free_hw(struct ieee802154_hw *hw); int ieee802154_register_hw(struct ieee802154_hw *hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw); +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi); diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index ef29c10eeb66..603509a94a86 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -55,11 +55,18 @@ struct ieee802154_local { * read them using any of protection methods. */ bool running; + + struct tasklet_struct tasklet; + struct sk_buff_head skb_queue; }; #define MAC802154_DEVICE_STOPPED 0x00 #define MAC802154_DEVICE_RUN 0x01 +enum { + IEEE802154_RX_MSG = 1, +}; + /* Slave interface definition. * * Slaves represent typical network interfaces available from userspace. diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index be45dc9257b3..311f60c8629b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -376,7 +376,7 @@ void mac802154_wpan_setup(struct net_device *dev) static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { - return netif_rx_ni(skb); + return netif_receive_skb(skb); } static int diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 3c0a824d24ac..ff0de0f990cb 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -222,6 +222,29 @@ static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) return local->ops->set_frame_retries(&local->hw, retries); } +static void ieee802154_tasklet_handler(unsigned long data) +{ + struct ieee802154_local *local = (struct ieee802154_local *)data; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&local->skb_queue))) { + switch (skb->pkt_type) { + case IEEE802154_RX_MSG: + /* Clear skb->pkt_type in order to not confuse kernel + * netstack. + */ + skb->pkt_type = 0; + ieee802154_rx(&local->hw, skb); + break; + default: + WARN(1, "mac802154: Packet is of unknown type %d\n", + skb->pkt_type); + kfree_skb(skb); + break; + } + } +} + struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) { @@ -270,6 +293,12 @@ ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) INIT_LIST_HEAD(&local->interfaces); mutex_init(&local->iflist_mtx); + tasklet_init(&local->tasklet, + ieee802154_tasklet_handler, + (unsigned long)local); + + skb_queue_head_init(&local->skb_queue); + return &local->hw; } EXPORT_SYMBOL(ieee802154_alloc_hw); @@ -371,6 +400,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_sub_if_data *sdata, *next; + tasklet_kill(&local->tasklet); flush_workqueue(local->workqueue); destroy_workqueue(local->workqueue); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 53c9e0c10a87..2851a3f7ac0b 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -28,30 +27,11 @@ #include "ieee802154_i.h" -/* The IEEE 802.15.4 standard defines 4 MAC packet types: - * - beacon frame - * - MAC command frame - * - acknowledgement frame - * - data frame - * - * and only the data frame should be pushed to the upper layers, other types - * are just internal MAC layer management information. So only data packets - * are going to be sent to the networking queue, all other will be processed - * right here by using the device workqueue. - */ -struct rx_work { - struct sk_buff *skb; - struct work_struct work; - struct ieee802154_hw *hw; - u8 lqi; -}; - static void -mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) +mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); - mac_cb(skb)->lqi = lqi; skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); @@ -79,32 +59,20 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) kfree_skb(skb); } -static void mac802154_rx_worker(struct work_struct *work) +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { - struct rx_work *rw = container_of(work, struct rx_work, work); - - mac802154_subif_rx(rw->hw, rw->skb, rw->lqi); - kfree(rw); + mac802154_subif_rx(hw, skb); } +EXPORT_SYMBOL(ieee802154_rx); void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { struct ieee802154_local *local = hw_to_local(hw); - struct rx_work *work; - if (!skb) - return; - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, mac802154_rx_worker); - work->skb = skb; - work->hw = hw; - work->lqi = lqi; - - queue_work(local->workqueue, &work->work); + mac_cb(skb)->lqi = lqi; + skb->pkt_type = IEEE802154_RX_MSG; + skb_queue_tail(&local->skb_queue, skb); + tasklet_schedule(&local->tasklet); } EXPORT_SYMBOL(ieee802154_rx_irqsafe); -- GitLab From c730c90316aa5753c6b2d3d5af40085c220e3a91 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:31 +0100 Subject: [PATCH 1465/9457] mac802154: rx: document ieee802154_rx() context requirement This patch is similar like d20ef63d32461332958661df73e21c0ca42601b0 ("mac80211: document ieee80211_rx() context requirement"). The netif_receive_skb call requires with softirqs disabled. This patch adds a warning if softirqs are pending while calling ieee802154_rx. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 2851a3f7ac0b..c4df3210c5e6 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -61,6 +61,8 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { + WARN_ON_ONCE(softirq_count() == 0); + mac802154_subif_rx(hw, skb); } EXPORT_SYMBOL(ieee802154_rx); -- GitLab From 2a9820c9e20a7889bf464e1edff5f75d685a8214 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:32 +0100 Subject: [PATCH 1466/9457] mac802154: rx: move receive handling into rx.c This patch removes all relevant receiving functions inclusive frame parsing into rx file. Like mac80211 we should implement the complete receive handling and parsing in this file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 - net/mac802154/iface.c | 186 ------------------------------ net/mac802154/monitor.c | 27 ----- net/mac802154/rx.c | 214 +++++++++++++++++++++++++++++++++++ 4 files changed, 214 insertions(+), 214 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 603509a94a86..be2f2f6774ae 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -131,7 +131,6 @@ void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); -void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_wpan_setup(struct net_device *dev); netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 311f60c8629b..7e4bffcbcd4d 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -373,189 +373,3 @@ void mac802154_wpan_setup(struct net_device *dev) mac802154_llsec_init(&sdata->sec); } - -static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) -{ - return netif_receive_skb(skb); -} - -static int -mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, - const struct ieee802154_hdr *hdr) -{ - __le16 span, sshort; - int rc; - - pr_debug("getting packet via slave interface %s\n", sdata->dev->name); - - spin_lock_bh(&sdata->mib_lock); - - span = sdata->pan_id; - sshort = sdata->short_addr; - - switch (mac_cb(skb)->dest.mode) { - case IEEE802154_ADDR_NONE: - if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) - /* FIXME: check if we are PAN coordinator */ - skb->pkt_type = PACKET_OTHERHOST; - else - /* ACK comes with both addresses empty */ - skb->pkt_type = PACKET_HOST; - break; - case IEEE802154_ADDR_LONG: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) - skb->pkt_type = PACKET_HOST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - case IEEE802154_ADDR_SHORT: - if (mac_cb(skb)->dest.pan_id != span && - mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) - skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.short_addr == sshort) - skb->pkt_type = PACKET_HOST; - else if (mac_cb(skb)->dest.short_addr == - cpu_to_le16(IEEE802154_ADDR_BROADCAST)) - skb->pkt_type = PACKET_BROADCAST; - else - skb->pkt_type = PACKET_OTHERHOST; - break; - default: - spin_unlock_bh(&sdata->mib_lock); - pr_debug("invalid dest mode\n"); - kfree_skb(skb); - return NET_RX_DROP; - } - - spin_unlock_bh(&sdata->mib_lock); - - skb->dev = sdata->dev; - - rc = mac802154_llsec_decrypt(&sdata->sec, skb); - if (rc) { - pr_debug("decryption failed: %i\n", rc); - goto fail; - } - - sdata->dev->stats.rx_packets++; - sdata->dev->stats.rx_bytes += skb->len; - - switch (mac_cb(skb)->type) { - case IEEE802154_FC_TYPE_DATA: - return mac802154_process_data(sdata->dev, skb); - default: - pr_warn("ieee802154: bad frame received (type = %d)\n", - mac_cb(skb)->type); - goto fail; - } - -fail: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void mac802154_print_addr(const char *name, - const struct ieee802154_addr *addr) -{ - if (addr->mode == IEEE802154_ADDR_NONE) - pr_debug("%s not present\n", name); - - pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); - if (addr->mode == IEEE802154_ADDR_SHORT) { - pr_debug("%s is short: %04x\n", name, - le16_to_cpu(addr->short_addr)); - } else { - u64 hw = swab64((__force u64) addr->extended_addr); - - pr_debug("%s is hardware: %8phC\n", name, &hw); - } -} - -static int mac802154_parse_frame_start(struct sk_buff *skb, - struct ieee802154_hdr *hdr) -{ - int hlen; - struct ieee802154_mac_cb *cb = mac_cb_init(skb); - - hlen = ieee802154_hdr_pull(skb, hdr); - if (hlen < 0) - return -EINVAL; - - skb->mac_len = hlen; - - pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), - hdr->seq); - - cb->type = hdr->fc.type; - cb->ackreq = hdr->fc.ack_request; - cb->secen = hdr->fc.security_enabled; - - mac802154_print_addr("destination", &hdr->dest); - mac802154_print_addr("source", &hdr->source); - - cb->source = hdr->source; - cb->dest = hdr->dest; - - if (hdr->fc.security_enabled) { - u64 key; - - pr_debug("seclevel %i\n", hdr->sec.level); - - switch (hdr->sec.key_id_mode) { - case IEEE802154_SCF_KEY_IMPLICIT: - pr_debug("implicit key\n"); - break; - - case IEEE802154_SCF_KEY_INDEX: - pr_debug("key %02x\n", hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_SHORT_INDEX: - pr_debug("key %04x:%04x %02x\n", - le32_to_cpu(hdr->sec.short_src) >> 16, - le32_to_cpu(hdr->sec.short_src) & 0xffff, - hdr->sec.key_id); - break; - - case IEEE802154_SCF_KEY_HW_INDEX: - key = swab64((__force u64) hdr->sec.extended_src); - pr_debug("key source %8phC %02x\n", &key, - hdr->sec.key_id); - break; - } - } - - return 0; -} - -void mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) -{ - int ret; - struct ieee802154_sub_if_data *sdata; - struct ieee802154_hdr hdr; - - ret = mac802154_parse_frame_start(skb, &hdr); - if (ret) { - pr_debug("got invalid frame\n"); - kfree_skb(skb); - return; - } - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_WPAN || - !netif_running(sdata->dev)) - continue; - - mac802154_subif_frame(sdata, skb, &hdr); - skb = NULL; - break; - } - rcu_read_unlock(); - - if (skb) - kfree_skb(skb); -} diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c index 575832231fd6..dfdedc206c6a 100644 --- a/net/mac802154/monitor.c +++ b/net/mac802154/monitor.c @@ -18,9 +18,7 @@ */ #include -#include #include -#include #include #include @@ -30,31 +28,6 @@ #include "ieee802154_i.h" -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) -{ - struct sk_buff *skb2; - struct ieee802154_sub_if_data *sdata; - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data; - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_MONITOR || - !netif_running(sdata->dev)) - continue; - - skb2 = skb_clone(skb, GFP_ATOMIC); - skb2->dev = sdata->dev; - skb2->pkt_type = PACKET_HOST; - data = skb_put(skb2, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; - - netif_rx_ni(skb2); - } - rcu_read_unlock(); -} - static const struct net_device_ops mac802154_monitor_ops = { .ndo_open = mac802154_slave_open, .ndo_stop = mac802154_slave_close, diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c4df3210c5e6..d8498c5fc297 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -24,9 +24,223 @@ #include #include +#include +#include #include "ieee802154_i.h" +static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +{ + return netif_receive_skb(skb); +} + +static int +mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, + const struct ieee802154_hdr *hdr) +{ + __le16 span, sshort; + int rc; + + pr_debug("getting packet via slave interface %s\n", sdata->dev->name); + + spin_lock_bh(&sdata->mib_lock); + + span = sdata->pan_id; + sshort = sdata->short_addr; + + switch (mac_cb(skb)->dest.mode) { + case IEEE802154_ADDR_NONE: + if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) + /* FIXME: check if we are PAN coordinator */ + skb->pkt_type = PACKET_OTHERHOST; + else + /* ACK comes with both addresses empty */ + skb->pkt_type = PACKET_HOST; + break; + case IEEE802154_ADDR_LONG: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) + skb->pkt_type = PACKET_HOST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + case IEEE802154_ADDR_SHORT: + if (mac_cb(skb)->dest.pan_id != span && + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) + skb->pkt_type = PACKET_OTHERHOST; + else if (mac_cb(skb)->dest.short_addr == sshort) + skb->pkt_type = PACKET_HOST; + else if (mac_cb(skb)->dest.short_addr == + cpu_to_le16(IEEE802154_ADDR_BROADCAST)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_OTHERHOST; + break; + default: + spin_unlock_bh(&sdata->mib_lock); + pr_debug("invalid dest mode\n"); + kfree_skb(skb); + return NET_RX_DROP; + } + + spin_unlock_bh(&sdata->mib_lock); + + skb->dev = sdata->dev; + + rc = mac802154_llsec_decrypt(&sdata->sec, skb); + if (rc) { + pr_debug("decryption failed: %i\n", rc); + goto fail; + } + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + + switch (mac_cb(skb)->type) { + case IEEE802154_FC_TYPE_DATA: + return mac802154_process_data(sdata->dev, skb); + default: + pr_warn("ieee802154: bad frame received (type = %d)\n", + mac_cb(skb)->type); + goto fail; + } + +fail: + kfree_skb(skb); + return NET_RX_DROP; +} + +static void mac802154_print_addr(const char *name, + const struct ieee802154_addr *addr) +{ + if (addr->mode == IEEE802154_ADDR_NONE) + pr_debug("%s not present\n", name); + + pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); + if (addr->mode == IEEE802154_ADDR_SHORT) { + pr_debug("%s is short: %04x\n", name, + le16_to_cpu(addr->short_addr)); + } else { + u64 hw = swab64((__force u64)addr->extended_addr); + + pr_debug("%s is hardware: %8phC\n", name, &hw); + } +} + +static int mac802154_parse_frame_start(struct sk_buff *skb, + struct ieee802154_hdr *hdr) +{ + int hlen; + struct ieee802154_mac_cb *cb = mac_cb_init(skb); + + hlen = ieee802154_hdr_pull(skb, hdr); + if (hlen < 0) + return -EINVAL; + + skb->mac_len = hlen; + + pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc), + hdr->seq); + + cb->type = hdr->fc.type; + cb->ackreq = hdr->fc.ack_request; + cb->secen = hdr->fc.security_enabled; + + mac802154_print_addr("destination", &hdr->dest); + mac802154_print_addr("source", &hdr->source); + + cb->source = hdr->source; + cb->dest = hdr->dest; + + if (hdr->fc.security_enabled) { + u64 key; + + pr_debug("seclevel %i\n", hdr->sec.level); + + switch (hdr->sec.key_id_mode) { + case IEEE802154_SCF_KEY_IMPLICIT: + pr_debug("implicit key\n"); + break; + + case IEEE802154_SCF_KEY_INDEX: + pr_debug("key %02x\n", hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_SHORT_INDEX: + pr_debug("key %04x:%04x %02x\n", + le32_to_cpu(hdr->sec.short_src) >> 16, + le32_to_cpu(hdr->sec.short_src) & 0xffff, + hdr->sec.key_id); + break; + + case IEEE802154_SCF_KEY_HW_INDEX: + key = swab64((__force u64)hdr->sec.extended_src); + pr_debug("key source %8phC %02x\n", &key, + hdr->sec.key_id); + break; + } + } + + return 0; +} + +static void +mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) +{ + int ret; + struct ieee802154_sub_if_data *sdata; + struct ieee802154_hdr hdr; + + ret = mac802154_parse_frame_start(skb, &hdr); + if (ret) { + pr_debug("got invalid frame\n"); + kfree_skb(skb); + return; + } + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (sdata->type != IEEE802154_DEV_WPAN || + !netif_running(sdata->dev)) + continue; + + mac802154_subif_frame(sdata, skb, &hdr); + skb = NULL; + break; + } + rcu_read_unlock(); + + if (skb) + kfree_skb(skb); +} + +void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +{ + struct sk_buff *skb2; + struct ieee802154_sub_if_data *sdata; + u16 crc = crc_ccitt(0, skb->data, skb->len); + u8 *data; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (sdata->type != IEEE802154_DEV_MONITOR || + !netif_running(sdata->dev)) + continue; + + skb2 = skb_clone(skb, GFP_ATOMIC); + skb2->dev = sdata->dev; + skb2->pkt_type = PACKET_HOST; + data = skb_put(skb2, 2); + data[0] = crc & 0xff; + data[1] = crc >> 8; + + netif_rx_ni(skb2); + } + rcu_read_unlock(); +} + static void mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { -- GitLab From 4ca18be54f507ddb2bedb44c2e3b988163684988 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:33 +0100 Subject: [PATCH 1467/9457] mac802154: tx: remove monitor receive while xmit This removes the call of monitor receive funktion when any interface type call xmit. There exist no such use case that a monitor interface should receive the actual sending frame. One use case could be that a wpan interface and monitor interface could be running at the same time on one phy. Then the monitor interface receives the wpan frames also. Furthermore we adding support for promiscous mode setting. With promiscous mode setting we can't run a wpan and monitor interface at the same time. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 - net/mac802154/rx.c | 3 ++- net/mac802154/tx.c | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index be2f2f6774ae..ac907d943bae 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -126,7 +126,6 @@ extern struct ieee802154_mlme_ops mac802154_mlme_wpan; int mac802154_slave_open(struct net_device *dev); int mac802154_slave_close(struct net_device *dev); -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb); void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index d8498c5fc297..04f3d61719ec 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -216,7 +216,8 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) kfree_skb(skb); } -void mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +static void +mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 31e51e4635e4..e85767355c48 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -82,8 +82,6 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) struct net_device *dev = skb->dev; int ret; - mac802154_monitors_rx(local, skb); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); -- GitLab From 469100d6c2ff22cd1f50672ac6d09a1633334489 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:34 +0100 Subject: [PATCH 1468/9457] mac802154: rx: rename remove mac802154_subif_rx This patch removes the mac802154_subif_rx function and do the necessary calls inside of ieee802154_rx function. The ieee802154_rx is small enough to move the functionality inside this function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 04f3d61719ec..246a60e8f76a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -242,11 +242,12 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) rcu_read_unlock(); } -static void -mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) +void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); + WARN_ON_ONCE(softirq_count() == 0); + skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); @@ -273,13 +274,6 @@ mac802154_subif_rx(struct ieee802154_hw *hw, struct sk_buff *skb) fail: kfree_skb(skb); } - -void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) -{ - WARN_ON_ONCE(softirq_count() == 0); - - mac802154_subif_rx(hw, skb); -} EXPORT_SYMBOL(ieee802154_rx); void -- GitLab From 702dcf994a0f0c467aae4b65885833a114126387 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:35 +0100 Subject: [PATCH 1469/9457] mac802154: rx: move skb->protocol setting This patch moves the skb->protocol setting to the position when it's needed. It's only needed when frame parsing was successful. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 246a60e8f76a..c4066b5006f1 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -31,6 +31,8 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { + skb->protocol = htons(ETH_P_IEEE802154); + return netif_receive_skb(skb); } @@ -224,6 +226,8 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb->protocol = htons(ETH_P_IEEE802154); + rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || @@ -248,7 +252,6 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - skb->protocol = htons(ETH_P_IEEE802154); skb_reset_mac_header(skb); if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { -- GitLab From 75a46f0ee774894152d505de594616f9c4dd7ef5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:36 +0100 Subject: [PATCH 1470/9457] mac802154: rx: add CHECKSUM_UNNECESSARY This patch adds CHECKSUM_UNNECESSARY to skb->ip_summed before delivery. There exist no transceiver with IP checksum functionality. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c4066b5006f1..14eecace1859 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -31,6 +31,7 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) { + skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); return netif_receive_skb(skb); @@ -226,6 +227,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); rcu_read_lock(); -- GitLab From c9ca6401405ea0c197ab7c8bcab2b82b26678145 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:37 +0100 Subject: [PATCH 1471/9457] mac802154: rx: add monitor pkt_type information This patch adds a PACKET_OTHERHOST setting when a monitor interface receives a skb. All receiving skb's to the monitor interface should be PACKET_OTHERHOST. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 14eecace1859..f7f09b46faa4 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -228,6 +228,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u8 *data; skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); rcu_read_lock(); -- GitLab From 9cf215d0733256687796ef1161b7b358be1b0602 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:38 +0100 Subject: [PATCH 1472/9457] mac802154: rx: move skb_reset_mac_header This patch moves the skb_reset_mac_header call before frame parsing while wpan rx and before monitor deliver functionality. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index f7f09b46faa4..c2999804126a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -138,6 +138,8 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, int hlen; struct ieee802154_mac_cb *cb = mac_cb_init(skb); + skb_reset_mac_header(skb); + hlen = ieee802154_hdr_pull(skb, hdr); if (hlen < 0) return -EINVAL; @@ -227,6 +229,7 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) u16 crc = crc_ccitt(0, skb->data, skb->len); u8 *data; + skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); @@ -255,8 +258,6 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - skb_reset_mac_header(skb); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { u16 crc; -- GitLab From e176b681b00d2b60e9231072d3ca841f9ddc74ea Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:39 +0100 Subject: [PATCH 1473/9457] mac802154: rx: move rcu locking Instead of twice lock and unlock mechanism this patch hold these locks only once at one position. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c2999804126a..689bb7ff5b2a 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -205,7 +205,6 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) return; } - rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_WPAN || !netif_running(sdata->dev)) @@ -215,7 +214,6 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) skb = NULL; break; } - rcu_read_unlock(); if (skb) kfree_skb(skb); @@ -234,7 +232,6 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_IEEE802154); - rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->type != IEEE802154_DEV_MONITOR || !netif_running(sdata->dev)) @@ -249,7 +246,6 @@ mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) netif_rx_ni(skb2); } - rcu_read_unlock(); } void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) @@ -273,9 +269,13 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) skb_trim(skb, skb->len - 2); /* CRC */ } + rcu_read_lock(); + mac802154_monitors_rx(local, skb); mac802154_wpans_rx(local, skb); + rcu_read_unlock(); + return; fail: -- GitLab From fa491001e4edae5ed68a562b61ed729968a3ca1c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:40 +0100 Subject: [PATCH 1474/9457] ieee802154: add valid psdu length helper This patch adds a generic valid psdu length check function helper. This is useful to check the length field after receiving. For example the at86rf231 doesn't filter invalid psdu length. Sometimes the CRC can also be correct. If we get the lqi value with an invalid frame length the kernel may crash because we dereference an invalid pointer in the receive buffer. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 2dfab2db103a..6e50a2a1d485 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -23,7 +23,10 @@ #ifndef LINUX_IEEE802154_H #define LINUX_IEEE802154_H +#include + #define IEEE802154_MTU 127 +#define IEEE802154_MIN_PSDU_LEN 5 #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ #define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ @@ -185,5 +188,13 @@ enum { IEEE802154_SCAN_IN_PROGRESS = 0xfc, }; +/** + * ieee802154_is_valid_psdu_len - check if psdu len is valid + * @len: psdu len with (MHR + payload + MFR) + */ +static inline bool ieee802154_is_valid_psdu_len(const u8 len) +{ + return (len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU); +} #endif /* LINUX_IEEE802154_H */ -- GitLab From d0e73c470471a0f2eda02de44fb17f020b32269c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:41 +0100 Subject: [PATCH 1475/9457] at86rf230: use ieee802154_is_valid_psdu_len helper This patch adds the ieee802154_is_valid_psdu_len function to validate the psdu length. If the psdu length is invalid we use the maximum payload to receive also corrupted frames in monitor mode. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index e4fbcaa602b6..368791b28585 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -788,26 +788,11 @@ at86rf230_tx_trac_status(void *context) static void at86rf230_rx(struct at86rf230_local *lp, - const u8 *data, u8 len) + const u8 *data, const u8 len) { - u8 lqi; struct sk_buff *skb; u8 rx_local_buf[AT86RF2XX_MAX_BUF]; - if (len < 2) - return; - - /* read full frame buffer and invalid lqi value to lowest - * indicator if frame was is in a corrupted state. - */ - if (len > IEEE802154_MTU) { - lqi = 0; - len = IEEE802154_MTU; - dev_vdbg(&lp->spi->dev, "corrupted frame received\n"); - } else { - lqi = data[len]; - } - memcpy(rx_local_buf, data, len); enable_irq(lp->spi->irq); @@ -822,7 +807,7 @@ at86rf230_rx(struct at86rf230_local *lp, /* We do not put CRC into the frame */ skb_trim(skb, len - 2); - ieee802154_rx_irqsafe(lp->hw, skb, lqi); + ieee802154_rx_irqsafe(lp->hw, skb, rx_local_buf[len]); } static void @@ -831,7 +816,12 @@ at86rf230_rx_read_frame_complete(void *context) struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; const u8 *buf = lp->irq.buf; - const u8 len = buf[1]; + u8 len = buf[1]; + + if (!ieee802154_is_valid_psdu_len(len)) { + dev_vdbg(&lp->spi->dev, "corrupted frame received\n"); + len = IEEE802154_MTU; + } at86rf230_rx(lp, buf + 2, len); } -- GitLab From b89c33417ffcc816df5755aec375a16d2657e4d3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:42 +0100 Subject: [PATCH 1476/9457] at86rf230: improve receive handling Current behaviour it to copy the frame inclusive CRC into a skb, then remove the CRC from the skb. This patch optimizes this by not copying the CRC at the first place. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 368791b28585..a1558385bac9 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -788,7 +788,7 @@ at86rf230_tx_trac_status(void *context) static void at86rf230_rx(struct at86rf230_local *lp, - const u8 *data, const u8 len) + const u8 *data, const u8 len, const u8 lqi) { struct sk_buff *skb; u8 rx_local_buf[AT86RF2XX_MAX_BUF]; @@ -803,11 +803,7 @@ at86rf230_rx(struct at86rf230_local *lp, } memcpy(skb_put(skb, len), rx_local_buf, len); - - /* We do not put CRC into the frame */ - skb_trim(skb, len - 2); - - ieee802154_rx_irqsafe(lp->hw, skb, rx_local_buf[len]); + ieee802154_rx_irqsafe(lp->hw, skb, lqi); } static void @@ -823,7 +819,7 @@ at86rf230_rx_read_frame_complete(void *context) len = IEEE802154_MTU; } - at86rf230_rx(lp, buf + 2, len); + at86rf230_rx(lp, buf + 2, len - 2, buf[2 + len]); } static void -- GitLab From be9d215fa9d13ecfe013a1b0d0f92f6d84a52c5c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 27 Oct 2014 17:13:43 +0100 Subject: [PATCH 1477/9457] mac802154: rx: change naming convention This patch changes the naming convention of mac802154 rx file. It should be more named like mac80211 stack. Furthermore we introduce a new frame parsing implementation which is much similar the mac80211 implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 689bb7ff5b2a..86394befbf88 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -29,7 +29,7 @@ #include "ieee802154_i.h" -static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) +static int ieee802154_deliver_skb(struct net_device *dev, struct sk_buff *skb) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); @@ -38,8 +38,8 @@ static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) } static int -mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, - const struct ieee802154_hdr *hdr) +ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, + struct sk_buff *skb, const struct ieee802154_hdr *hdr) { __le16 span, sshort; int rc; @@ -103,7 +103,7 @@ mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, switch (mac_cb(skb)->type) { case IEEE802154_FC_TYPE_DATA: - return mac802154_process_data(sdata->dev, skb); + return ieee802154_deliver_skb(sdata->dev, skb); default: pr_warn("ieee802154: bad frame received (type = %d)\n", mac_cb(skb)->type); @@ -115,8 +115,8 @@ mac802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, return NET_RX_DROP; } -static void mac802154_print_addr(const char *name, - const struct ieee802154_addr *addr) +static void +ieee802154_print_addr(const char *name, const struct ieee802154_addr *addr) { if (addr->mode == IEEE802154_ADDR_NONE) pr_debug("%s not present\n", name); @@ -132,8 +132,8 @@ static void mac802154_print_addr(const char *name, } } -static int mac802154_parse_frame_start(struct sk_buff *skb, - struct ieee802154_hdr *hdr) +static int +ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr) { int hlen; struct ieee802154_mac_cb *cb = mac_cb_init(skb); @@ -153,8 +153,8 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, cb->ackreq = hdr->fc.ack_request; cb->secen = hdr->fc.security_enabled; - mac802154_print_addr("destination", &hdr->dest); - mac802154_print_addr("source", &hdr->source); + ieee802154_print_addr("destination", &hdr->dest); + ieee802154_print_addr("source", &hdr->source); cb->source = hdr->source; cb->dest = hdr->dest; @@ -192,13 +192,14 @@ static int mac802154_parse_frame_start(struct sk_buff *skb, } static void -mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) +__ieee802154_rx_handle_packet(struct ieee802154_local *local, + struct sk_buff *skb) { int ret; struct ieee802154_sub_if_data *sdata; struct ieee802154_hdr hdr; - ret = mac802154_parse_frame_start(skb, &hdr); + ret = ieee802154_parse_frame_start(skb, &hdr); if (ret) { pr_debug("got invalid frame\n"); kfree_skb(skb); @@ -210,7 +211,7 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) !netif_running(sdata->dev)) continue; - mac802154_subif_frame(sdata, skb, &hdr); + ieee802154_subif_frame(sdata, skb, &hdr); skb = NULL; break; } @@ -220,7 +221,7 @@ mac802154_wpans_rx(struct ieee802154_local *local, struct sk_buff *skb) } static void -mac802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) +ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; @@ -271,8 +272,8 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) rcu_read_lock(); - mac802154_monitors_rx(local, skb); - mac802154_wpans_rx(local, skb); + ieee802154_monitors_rx(local, skb); + __ieee802154_rx_handle_packet(local, skb); rcu_read_unlock(); -- GitLab From 1972c97db5b0c125918f662cd084c7d5370674c0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 27 Oct 2014 18:15:15 +0100 Subject: [PATCH 1478/9457] gpio: dwapb: fix compile errors Whereas the DWAPB driver does not really depend on the ARM architecture, it uses [readl|writel]_relaxed() not found on arch such as Blackfin, so restrict this to ARM until there is another architecture that can make use of it. It is also using the of_node of the gpiochip, so fix this too by requiring OF_GPIO. All error/warnings: make.cross ARCH=blackfin drivers/gpio/gpio-dwapb.c: In function 'dwapb_irq_handler': drivers/gpio/gpio-dwapb.c:91:2: error: implicit declaration of function 'readl_relaxed' [-Werror=implicit-function-declaration] drivers/gpio/gpio-dwapb.c: In function 'dwapb_configure_irqs': drivers/gpio/gpio-dwapb.c:212:32: error: 'struct gpio_chip' has no member named 'of_node' drivers/gpio/gpio-dwapb.c:221:16: error: 'struct gpio_chip' has no member named 'of_node' drivers/gpio/gpio-dwapb.c: In function 'dwapb_gpio_add_port': drivers/gpio/gpio-dwapb.c:331:14: error: 'struct gpio_chip' has no member named 'of_node' cc1: some warnings being treated as errors Cc: Jamie Iles Cc: Alan Tull Reported-by: kbuild test robot Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 690ad0b20414..414d0559d32f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -148,6 +148,8 @@ config GPIO_GENERIC_PLATFORM config GPIO_DWAPB tristate "Synopsys DesignWare APB GPIO driver" + depends on ARM + depends on OF_GPIO select GPIO_GENERIC select GENERIC_IRQ_CHIP help -- GitLab From 39581031a90d69e4b79cd044756169ff35ecab46 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 24 Oct 2014 13:49:46 +0530 Subject: [PATCH 1479/9457] ASoC: Intel: mrfld: Replace pci_id with unique device id In order to support both ACPI and PCI devices we need to use a genric device id in driver, so change all pci_id instances to device_id Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 10 +++++----- sound/soc/intel/sst/sst.h | 5 +++-- sound/soc/intel/sst/sst_pvt.c | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index d88cdd97f747..fa3421706e4e 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -167,7 +167,7 @@ static struct intel_sst_ops mrfld_ops = { int sst_driver_ops(struct intel_sst_drv *sst) { - switch (sst->pci_id) { + switch (sst->dev_id) { case SST_MRFLD_PCI_ID: sst->tstamp = SST_TIME_STAMP_MRFLD; sst->ops = &mrfld_ops; @@ -175,7 +175,7 @@ int sst_driver_ops(struct intel_sst_drv *sst) default: dev_err(sst->dev, - "SST Driver capablities missing for pci_id: %x", sst->pci_id); + "SST Driver capablities missing for dev_id: %x", sst->dev_id); return -EINVAL; }; } @@ -210,7 +210,7 @@ static int intel_sst_probe(struct pci_dev *pci, return -ENOMEM; sst_drv_ctx->dev = &pci->dev; - sst_drv_ctx->pci_id = pci->device; + sst_drv_ctx->dev_id = pci->device; if (!sst_pdata) return -EINVAL; @@ -278,7 +278,7 @@ static int intel_sst_probe(struct pci_dev *pci, /* map registers */ /* DDR base */ - if (sst_drv_ctx->pci_id == SST_MRFLD_PCI_ID) { + if (sst_drv_ctx->dev_id == SST_MRFLD_PCI_ID) { sst_drv_ctx->ddr_base = pci_resource_start(pci, 0); /* check that the relocated IMR base matches with FW Binary */ ddr_base = relocate_imr_addr_mrfld(sst_drv_ctx->ddr_base); @@ -357,7 +357,7 @@ static int intel_sst_probe(struct pci_dev *pci, dev_dbg(sst_drv_ctx->dev, "Registered IRQ 0x%x\n", pci->irq); /* default intr are unmasked so set this as masked */ - if (sst_drv_ctx->pci_id == SST_MRFLD_PCI_ID) + if (sst_drv_ctx->dev_id == SST_MRFLD_PCI_ID) sst_shim_write64(sst_drv_ctx->shim, SST_IMRX, 0xFFFF0038); pci_set_drvdata(pci, sst_drv_ctx); diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index bfcf51ad3f5a..b65b9c0d8750 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h @@ -337,7 +337,8 @@ struct sst_shim_regs64 { * struct intel_sst_drv - driver ops * * @sst_state : current sst device state - * @pci_id : PCI device id loaded + * @dev_id : device identifier, pci_id for pci devices and acpi_id for acpi + * devices * @shim : SST shim pointer * @mailbox : SST mailbox pointer * @iram : SST IRAM pointer @@ -371,7 +372,7 @@ struct sst_shim_regs64 { struct intel_sst_drv { int sst_state; int irq_num; - unsigned int pci_id; + unsigned int dev_id; void __iomem *ddr; void __iomem *shim; void __iomem *mailbox; diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/sst/sst_pvt.c index 9e5f69b6b395..1c2e081fd813 100644 --- a/sound/soc/intel/sst/sst_pvt.c +++ b/sound/soc/intel/sst/sst_pvt.c @@ -115,7 +115,7 @@ unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr) { unsigned long long val = 0; - switch (sst->pci_id) { + switch (sst->dev_id) { case SST_MRFLD_PCI_ID: val = sst_shim_read64(sst->shim, addr); break; @@ -126,7 +126,7 @@ unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr) void write_shim_data(struct intel_sst_drv *sst, int addr, unsigned long long data) { - switch (sst->pci_id) { + switch (sst->dev_id) { case SST_MRFLD_PCI_ID: sst_shim_write64(sst->shim, addr, (u64) data); break; -- GitLab From 43c5e23197a187a6f4dade97f3bd23e35636ab1f Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 24 Oct 2014 13:49:47 +0530 Subject: [PATCH 1480/9457] ASoC: Intel: mrfld - Define ipc_info structure This will be used to abstract the differances in ipc offsets for different chips. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- arch/x86/include/asm/platform_sst_audio.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h index 268a96aec77c..6021dee3866a 100644 --- a/arch/x86/include/asm/platform_sst_audio.h +++ b/arch/x86/include/asm/platform_sst_audio.h @@ -102,6 +102,11 @@ struct sst_lib_dnld_info { bool mod_ddr_dnld; }; +struct sst_ipc_info { + int ipc_offset; + unsigned int mbox_recv_off; +}; + struct sst_platform_info { const struct sst_info *probe_data; const struct sst_ipc_info *ipc_info; -- GitLab From 9a80e8f597f3bde0e1d4a4abb021d475520005a5 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 24 Oct 2014 13:49:48 +0530 Subject: [PATCH 1481/9457] ASoC: Intel: mrfld: Define sst_res_info for acpi To query resources in ACPI systems we need to define a data structure. This would be set as platform_info for the devices. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- arch/x86/include/asm/platform_sst_audio.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h index 6021dee3866a..7249e6d0902d 100644 --- a/arch/x86/include/asm/platform_sst_audio.h +++ b/arch/x86/include/asm/platform_sst_audio.h @@ -102,6 +102,27 @@ struct sst_lib_dnld_info { bool mod_ddr_dnld; }; +struct sst_res_info { + unsigned int shim_offset; + unsigned int shim_size; + unsigned int shim_phy_addr; + unsigned int ssp0_offset; + unsigned int ssp0_size; + unsigned int dma0_offset; + unsigned int dma0_size; + unsigned int dma1_offset; + unsigned int dma1_size; + unsigned int iram_offset; + unsigned int iram_size; + unsigned int dram_offset; + unsigned int dram_size; + unsigned int mbox_offset; + unsigned int mbox_size; + unsigned int acpi_lpe_res_index; + unsigned int acpi_ddr_index; + unsigned int acpi_ipc_irq_index; +}; + struct sst_ipc_info { int ipc_offset; unsigned int mbox_recv_off; @@ -110,7 +131,9 @@ struct sst_ipc_info { struct sst_platform_info { const struct sst_info *probe_data; const struct sst_ipc_info *ipc_info; + const struct sst_res_info *res_info; const struct sst_lib_dnld_info *lib_info; + const char *platform; }; int add_sst_platform_device(void); #endif -- GitLab From ab54bc8460b5730ce4d2b50f5b928b230ec994d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 3 Oct 2014 17:00:24 +0200 Subject: [PATCH 1482/9457] bcma: fill core details for every device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were setting things like dma_dev, IRQ, etc. during core registration only. We need such info for cores handled internally (e.g. ChipCommon) as well. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/bcma_private.h | 1 + drivers/bcma/main.c | 9 ++++++--- drivers/bcma/scan.c | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index b6412b2d748d..314ae4032f3e 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -24,6 +24,7 @@ struct bcma_bus; /* main.c */ bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, int timeout); +void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); int bcma_bus_register(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index d1656c2f70af..9b229c9c35e5 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -169,10 +169,8 @@ static void bcma_of_fill_device(struct platform_device *parent, } #endif /* CONFIG_OF */ -static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) +void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) { - int err; - core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); @@ -196,6 +194,11 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) case BCMA_HOSTTYPE_SDIO: break; } +} + +static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) +{ + int err; err = device_register(&core->dev); if (err) { diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index 14b56561a36f..917520776879 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -505,6 +505,7 @@ int bcma_bus_scan(struct bcma_bus *bus) bus->nr_cores++; other_core = bcma_find_core_reverse(bus, core->id.id); core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1; + bcma_prepare_core(bus, core); bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", core->core_index, bcma_device_name(&core->id), -- GitLab From e9dc51aa2b0fe64d23561544c67db939b71bd32c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 8 Oct 2014 14:16:37 +0200 Subject: [PATCH 1483/9457] rt2x00: tune multi-registers I/O timeout We provide timeout value to rt2x00usb_vendor_request_buff() based on number of registers to process. That value is passed down to rt2x00usb_vendor_req_buff_lock() and ends in usb_control_msg(). But we do not read/write all registers in rt2x00usb_vendor_req_buff_lock() at once. We read/write them in chunks of 64 bytes in the loop, hence passed timeout value to low level is too big. Patch removes timeout argument from rt2x00usb_vendor_request_buff() and use short REGISTER_TIMEOUT in rt2x00usb_vendor_req_buff_lock(). That timeout value should be fine for 64 bytes and smaller requests. For EEPROM read we introduced new timeout value equal to 2 seconds. Patch fixes process uninterruptible sleep stalls for long period, when USB bus has problem to satisfy a request and we wait very long time on usb_start_wait_urb(). Reported-and-tested-by: Sakari Ailus Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 10 +++---- drivers/net/wireless/rt2x00/rt2x00usb.c | 4 +-- drivers/net/wireless/rt2x00/rt2x00usb.h | 39 +++++++------------------ 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index d849d590de25..c878e3f3993c 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -62,7 +62,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, __le16 reg; rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, USB_VENDOR_REQUEST_IN, offset, - ®, sizeof(reg), REGISTER_TIMEOUT); + ®, sizeof(reg)); *value = le16_to_cpu(reg); } @@ -83,8 +83,7 @@ static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev, { rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, USB_VENDOR_REQUEST_IN, offset, - value, length, - REGISTER_TIMEOUT16(length)); + value, length); } static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, @@ -94,7 +93,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, __le16 reg = cpu_to_le16(value); rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, USB_VENDOR_REQUEST_OUT, offset, - ®, sizeof(reg), REGISTER_TIMEOUT); + ®, sizeof(reg)); } static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, @@ -113,8 +112,7 @@ static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, { rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, USB_VENDOR_REQUEST_OUT, offset, - value, length, - REGISTER_TIMEOUT16(length)); + value, length); } static int rt2500usb_regbusy_read(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 86c43d112a4b..dc85d3e0ffe5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock); int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, const u8 request, const u8 requesttype, const u16 offset, void *buffer, - const u16 buffer_length, const int timeout) + const u16 buffer_length) { int status = 0; unsigned char *tb; @@ -131,7 +131,7 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, bsize = min_t(u16, CSR_CACHE_SIZE, len); status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, requesttype, off, tb, - bsize, timeout); + bsize, REGISTER_TIMEOUT); tb += bsize; len -= bsize; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 831b65f93feb..819690e978c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -33,27 +33,14 @@ }) /* - * For USB vendor requests we need to pass a timeout - * time in ms, for this we use the REGISTER_TIMEOUT, - * however when loading firmware a higher value is - * required. In that case we use the REGISTER_TIMEOUT_FIRMWARE. + * For USB vendor requests we need to pass a timeout time in ms, for this we + * use the REGISTER_TIMEOUT, however when loading firmware or read EEPROM + * a higher value is required. In that case we use the REGISTER_TIMEOUT_FIRMWARE + * and EEPROM_TIMEOUT. */ #define REGISTER_TIMEOUT 500 #define REGISTER_TIMEOUT_FIRMWARE 1000 - -/** - * REGISTER_TIMEOUT16 - Determine the timeout for 16bit register access - * @__datalen: Data length - */ -#define REGISTER_TIMEOUT16(__datalen) \ - ( REGISTER_TIMEOUT * ((__datalen) / sizeof(u16)) ) - -/** - * REGISTER_TIMEOUT32 - Determine the timeout for 32bit register access - * @__datalen: Data length - */ -#define REGISTER_TIMEOUT32(__datalen) \ - ( REGISTER_TIMEOUT * ((__datalen) / sizeof(u32)) ) +#define EEPROM_TIMEOUT 2000 /* * Cache size @@ -126,7 +113,6 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, * @offset: Register offset to perform action on * @buffer: Buffer where information will be read/written to by device * @buffer_length: Size of &buffer - * @timeout: Operation timeout * * This function will use a previously with kmalloc allocated cache * to communicate with the device. The contents of the buffer pointer @@ -139,7 +125,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, const u8 request, const u8 requesttype, const u16 offset, void *buffer, - const u16 buffer_length, const int timeout); + const u16 buffer_length); /** * rt2x00usb_vendor_request_buff - Send register command to device (buffered) @@ -197,8 +183,7 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, { return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, USB_VENDOR_REQUEST_IN, 0, 0, - eeprom, length, - REGISTER_TIMEOUT16(length)); + eeprom, length, EEPROM_TIMEOUT); } /** @@ -217,7 +202,7 @@ static inline void rt2x00usb_register_read(struct rt2x00_dev *rt2x00dev, __le32 reg; rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, USB_VENDOR_REQUEST_IN, offset, - ®, sizeof(reg), REGISTER_TIMEOUT); + ®, sizeof(reg)); *value = le32_to_cpu(reg); } @@ -257,8 +242,7 @@ static inline void rt2x00usb_register_multiread(struct rt2x00_dev *rt2x00dev, { rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, USB_VENDOR_REQUEST_IN, offset, - value, length, - REGISTER_TIMEOUT32(length)); + value, length); } /** @@ -277,7 +261,7 @@ static inline void rt2x00usb_register_write(struct rt2x00_dev *rt2x00dev, __le32 reg = cpu_to_le32(value); rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, USB_VENDOR_REQUEST_OUT, offset, - ®, sizeof(reg), REGISTER_TIMEOUT); + ®, sizeof(reg)); } /** @@ -316,8 +300,7 @@ static inline void rt2x00usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, { rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, USB_VENDOR_REQUEST_OUT, offset, - (void *)value, length, - REGISTER_TIMEOUT32(length)); + (void *)value, length); } /** -- GitLab From 2aa01652cf85f3e5885b173a2f4c53080046c6e0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Oct 2014 12:57:42 +0300 Subject: [PATCH 1484/9457] ipw2x00: remove unused ->ibss_dfs pointer The ->ibss_dfs pointer is always allocated with a user controlled length. This caused a static checker warning because what if the length was zero? In that case, any dereference of ->ibss_dfs would lead to an Oops. It turns out that this isn't a problem because the ->ibss_dfs pointer is never used. This patch deletes it along with all the related code. In particular the entire libipw_network_reset() function can be removed. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/libipw.h | 5 ----- drivers/net/wireless/ipw2x00/libipw_module.c | 15 +------------- drivers/net/wireless/ipw2x00/libipw_rx.c | 21 ++------------------ 3 files changed, 3 insertions(+), 38 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 5ce2f59d3378..b0571618c2ed 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -654,10 +654,6 @@ struct libipw_network { /* TPC Report - mandatory if spctrm mgmt required */ struct libipw_tpc_report tpc_report; - /* IBSS DFS - mandatory if spctrm mgmt required and IBSS - * NOTE: This is variable length and so must be allocated dynamically */ - struct libipw_ibss_dfs *ibss_dfs; - /* Channel Switch Announcement - optional if spctrm mgmt required */ struct libipw_csa csa; @@ -970,7 +966,6 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, /* make sure to set stats->len */ void libipw_rx_mgt(struct libipw_device *ieee, struct libipw_hdr_4addr *header, struct libipw_rx_stats *stats); -void libipw_network_reset(struct libipw_network *network); /* libipw_geo.c */ const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee); diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 5f31b72a4921..60f28740f6af 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -84,25 +84,12 @@ static int libipw_networks_allocate(struct libipw_device *ieee) return 0; } -void libipw_network_reset(struct libipw_network *network) -{ - if (!network) - return; - - if (network->ibss_dfs) { - kfree(network->ibss_dfs); - network->ibss_dfs = NULL; - } -} - static inline void libipw_networks_free(struct libipw_device *ieee) { int i; - for (i = 0; i < MAX_NETWORK_COUNT; i++) { - kfree(ieee->networks[i]->ibss_dfs); + for (i = 0; i < MAX_NETWORK_COUNT; i++) kfree(ieee->networks[i]); - } } void libipw_networks_age(struct libipw_device *ieee, diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 2d66984079bb..a6877dd6ba73 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -1298,13 +1298,6 @@ static int libipw_parse_info_param(struct libipw_info_element break; case WLAN_EID_IBSS_DFS: - if (network->ibss_dfs) - break; - network->ibss_dfs = kmemdup(info_element->data, - info_element->len, - GFP_ATOMIC); - if (!network->ibss_dfs) - return 1; network->flags |= NETWORK_HAS_IBSS_DFS; break; @@ -1335,9 +1328,7 @@ static int libipw_parse_info_param(struct libipw_info_element static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_assoc_response *frame, struct libipw_rx_stats *stats) { - struct libipw_network network_resp = { - .ibss_dfs = NULL, - }; + struct libipw_network network_resp = { }; struct libipw_network *network = &network_resp; struct net_device *dev = ieee->dev; @@ -1472,9 +1463,6 @@ static void update_network(struct libipw_network *dst, int qos_active; u8 old_param; - libipw_network_reset(dst); - dst->ibss_dfs = src->ibss_dfs; - /* We only update the statistics if they were created by receiving * the network information on the actual channel the network is on. * @@ -1548,9 +1536,7 @@ static void libipw_process_probe_response(struct libipw_device *stats) { struct net_device *dev = ieee->dev; - struct libipw_network network = { - .ibss_dfs = NULL, - }; + struct libipw_network network = { }; struct libipw_network *target; struct libipw_network *oldest = NULL; #ifdef CONFIG_LIBIPW_DEBUG @@ -1618,7 +1604,6 @@ static void libipw_process_probe_response(struct libipw_device LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n", target->ssid_len, target->ssid, target->bssid); - libipw_network_reset(target); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -1634,7 +1619,6 @@ static void libipw_process_probe_response(struct libipw_device "BEACON" : "PROBE RESPONSE"); #endif memcpy(target, &network, sizeof(*target)); - network.ibss_dfs = NULL; list_add_tail(&target->list, &ieee->network_list); } else { LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n", @@ -1643,7 +1627,6 @@ static void libipw_process_probe_response(struct libipw_device is_beacon(beacon->header.frame_ctl) ? "BEACON" : "PROBE RESPONSE"); update_network(target, &network); - network.ibss_dfs = NULL; } spin_unlock_irqrestore(&ieee->lock, flags); -- GitLab From 9fdc723abf50e3317387f712c5c1b70f86ac0d74 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Oct 2014 12:59:39 +0300 Subject: [PATCH 1485/9457] ipw2x00: clean up a condition The original condition was "(PAGE_SIZE - len)" when "(len < PAGE_SIZE)" is intended. This condition is not really sufficient, but also not really needed... If "len > PAGE_SIZE" then it we will print a warning message in dmesg but there are no other effects. Maybe we should just remove the condition? Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index edc344334a75..67cad9b05ad8 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -1363,7 +1363,7 @@ static ssize_t show_cmd_log(struct device *d, if (!priv->cmdlog) return 0; for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len; - (i != priv->cmdlog_pos) && (PAGE_SIZE - len); + (i != priv->cmdlog_pos) && (len < PAGE_SIZE); i = (i + 1) % priv->cmdlog_len) { len += snprintf(buf + len, PAGE_SIZE - len, -- GitLab From 992a36a641651934a12ba1f0f1bf5fcc89e649f9 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 14 Oct 2014 22:21:00 +0200 Subject: [PATCH 1486/9457] ath9k: do not overwrite AR_PHY_RADAR_1 MSB Do not overwrite AR_PHY_RADAR_1 most significant byte default value Signed-off-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 ++++- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index b72d0be716db..ba3d788c57d3 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1190,7 +1190,7 @@ static void ar5008_hw_set_nf_limits(struct ath_hw *ah) static void ar5008_hw_set_radar_params(struct ath_hw *ah, struct ath_hw_radar_conf *conf) { - u32 radar_0 = 0, radar_1 = 0; + u32 radar_0 = 0, radar_1; if (!conf) { REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); @@ -1204,6 +1204,9 @@ static void ar5008_hw_set_radar_params(struct ath_hw *ah, radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); + radar_1 = REG_READ(ah, AR_PHY_RADAR_1); + radar_1 &= ~(AR_PHY_RADAR_1_MAXLEN | AR_PHY_RADAR_1_RELSTEP_THRESH | + AR_PHY_RADAR_1_RELPWR_THRESH); radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 697c4ae90af0..30b2f95e926c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1348,7 +1348,7 @@ static void ar9003_hw_set_radar_params(struct ath_hw *ah, struct ath_hw_radar_conf *conf) { unsigned int regWrites = 0; - u32 radar_0 = 0, radar_1 = 0; + u32 radar_0 = 0, radar_1; if (!conf) { REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); @@ -1362,6 +1362,9 @@ static void ar9003_hw_set_radar_params(struct ath_hw *ah, radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI); radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND); + radar_1 = REG_READ(ah, AR_PHY_RADAR_1); + radar_1 &= ~(AR_PHY_RADAR_1_MAXLEN | AR_PHY_RADAR_1_RELSTEP_THRESH | + AR_PHY_RADAR_1_RELPWR_THRESH); radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI; radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK; radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN); -- GitLab From df3c6eb34da5ed61d288c23466e1ec4dd7ca509a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:08 +0530 Subject: [PATCH 1487/9457] ath9k: Use sta_state() callback Instead of using the sta_add()/sta_remove() callbacks, use the sta_state() callback since this gives more fine-grained control. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6f6a974f7fdb..902807e98f5e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1547,6 +1547,31 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, return 0; } +static int ath9k_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct ath_softc *sc = hw->priv; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + int ret = 0; + + if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) { + ret = ath9k_sta_add(hw, vif, sta); + ath_dbg(common, CONFIG, + "Add station: %pM\n", sta->addr); + } else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) { + ret = ath9k_sta_remove(hw, vif, sta); + ath_dbg(common, CONFIG, + "Remove station: %pM\n", sta->addr); + } + + return ret; +} + static void ath9k_sta_set_tx_filter(struct ath_hw *ah, struct ath_node *an, bool set) @@ -2471,8 +2496,7 @@ struct ieee80211_ops ath9k_ops = { .remove_interface = ath9k_remove_interface, .config = ath9k_config, .configure_filter = ath9k_configure_filter, - .sta_add = ath9k_sta_add, - .sta_remove = ath9k_sta_remove, + .sta_state = ath9k_sta_state, .sta_notify = ath9k_sta_notify, .conf_tx = ath9k_conf_tx, .bss_info_changed = ath9k_bss_info_changed, -- GitLab From b8f9279be048677d6d8244dd91493f684ce5c7d0 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:09 +0530 Subject: [PATCH 1488/9457] ath9k: Enable multi-channel properly In MCC mode, currently the decision to enable the multi-channel state machine is done based on the association status if one of the interfaces assigned to a context is in station mode. This allows the driver to switch to the other context before the current station is able to complete the 4-way handshake in case it is required and this causes problems. Instead, enable multi-channel mode when the station moves to the authorized state. This disallows an early switch to the other channel. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/channel.c | 4 ++-- drivers/net/wireless/ath/ath9k/main.c | 13 +++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 01a7db061c6a..aff5e4c9f565 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -362,7 +362,7 @@ enum ath_chanctx_event { ATH_CHANCTX_EVENT_BEACON_SENT, ATH_CHANCTX_EVENT_TSF_TIMER, ATH_CHANCTX_EVENT_BEACON_RECEIVED, - ATH_CHANCTX_EVENT_ASSOC, + ATH_CHANCTX_EVENT_AUTHORIZED, ATH_CHANCTX_EVENT_SWITCH, ATH_CHANCTX_EVENT_ASSIGN, ATH_CHANCTX_EVENT_UNASSIGN, diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 945c89826b14..16bed6acec93 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -171,7 +171,7 @@ static const char *chanctx_event_string(enum ath_chanctx_event ev) case_rtn_string(ATH_CHANCTX_EVENT_BEACON_SENT); case_rtn_string(ATH_CHANCTX_EVENT_TSF_TIMER); case_rtn_string(ATH_CHANCTX_EVENT_BEACON_RECEIVED); - case_rtn_string(ATH_CHANCTX_EVENT_ASSOC); + case_rtn_string(ATH_CHANCTX_EVENT_AUTHORIZED); case_rtn_string(ATH_CHANCTX_EVENT_SWITCH); case_rtn_string(ATH_CHANCTX_EVENT_ASSIGN); case_rtn_string(ATH_CHANCTX_EVENT_UNASSIGN); @@ -510,7 +510,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, ath_chanctx_setup_timer(sc, tsf_time); break; - case ATH_CHANCTX_EVENT_ASSOC: + case ATH_CHANCTX_EVENT_AUTHORIZED: if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE || avp->chanctx != sc->cur_chan) break; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 902807e98f5e..446bc46733f9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1569,6 +1569,13 @@ static int ath9k_sta_state(struct ieee80211_hw *hw, "Remove station: %pM\n", sta->addr); } + if (ath9k_is_chanctx_enabled()) { + if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTHORIZED) + ath_chanctx_event(sc, vif, + ATH_CHANCTX_EVENT_AUTHORIZED); + } + return ret; } @@ -1761,12 +1768,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, avp->assoc = bss_conf->assoc; ath9k_calculate_summary_state(sc, avp->chanctx); - - if (ath9k_is_chanctx_enabled()) { - if (bss_conf->assoc) - ath_chanctx_event(sc, vif, - ATH_CHANCTX_EVENT_ASSOC); - } } if (changed & BSS_CHANGED_IBSS) { -- GitLab From be247c1faeeead695378989a0806951ebf0403ae Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:10 +0530 Subject: [PATCH 1489/9457] ath9k: Process beacons properly When the current operating channel context has been marked as ATH_CHANCTX_STATE_FORCE_ACTIVE, do not process beacons that might be received, since we have to wait for the station to become authorized. Also, since the cached TSF value will be zero initially do not rearm the timer in this case when a beacon is received, since it results in spurious values. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 16bed6acec93..135f74cd6147 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -495,10 +495,15 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, sc->cur_chan == &sc->offchannel.chan) break; - ath_chanctx_adjust_tbtt_delta(sc); sc->sched.beacon_pending = false; sc->sched.beacon_miss = 0; + if (sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE || + !sc->cur_chan->tsf_val) + break; + + ath_chanctx_adjust_tbtt_delta(sc); + /* TSF time might have been updated by the incoming beacon, * need update the channel switch timer to reflect the change. */ -- GitLab From 5555c955249b0d942e8ae066e80a24237b16e7f8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:11 +0530 Subject: [PATCH 1490/9457] ath9k: Unify reset API Instead of having ath_reset_internal() and ath_reset() as two separate calls to perform a HW reset, have one function. This makes sure that the behavior will be the same at all callsites. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-- drivers/net/wireless/ath/ath9k/channel.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 12 +++++++----- drivers/net/wireless/ath/ath9k/tx99.c | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index aff5e4c9f565..bc90fabdd921 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -540,7 +540,6 @@ static inline void ath_chanctx_check_active(struct ath_softc *sc, #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ -int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); void ath_startrecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc); u32 ath_calcrxfilter(struct ath_softc *sc); @@ -1069,7 +1068,7 @@ void ath9k_tasklet(unsigned long data); int ath_cabq_update(struct ath_softc *); u8 ath9k_parse_mpdudensity(u8 mpdudensity); irqreturn_t ath_isr(int irq, void *dev); -int ath_reset(struct ath_softc *sc); +int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan); void ath_cancel_work(struct ath_softc *sc); void ath_restart_work(struct ath_softc *sc); int ath9k_init_device(u16 devid, struct ath_softc *sc, diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 135f74cd6147..709facca8acd 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -66,7 +66,7 @@ static int ath_set_channel(struct ath_softc *sc) } hchan = &sc->sc_ah->channels[pos]; - r = ath_reset_internal(sc, hchan); + r = ath_reset(sc, hchan); if (r) return r; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 446bc46733f9..eb6ba9f8d9ff 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -270,7 +270,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) return true; } -int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) +static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -598,12 +598,12 @@ irqreturn_t ath_isr(int irq, void *dev) #undef SCHED_INTR } -int ath_reset(struct ath_softc *sc) +int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan) { int r; ath9k_ps_wakeup(sc); - r = ath_reset_internal(sc, NULL); + r = ath_reset_internal(sc, hchan); ath9k_ps_restore(sc); return r; @@ -623,7 +623,9 @@ void ath_reset_work(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); - ath_reset(sc); + ath9k_ps_wakeup(sc); + ath_reset_internal(sc, NULL); + ath9k_ps_restore(sc); } /**********************/ @@ -2044,7 +2046,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) spin_unlock_bh(&sc->sc_pcu_lock); if (!drain_txq) - ath_reset(sc); + ath_reset(sc, NULL); ath9k_ps_restore(sc); } diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c index 40ab65e6882f..ac4781f37e78 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c @@ -99,7 +99,7 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) static void ath9k_tx99_deinit(struct ath_softc *sc) { - ath_reset(sc); + ath_reset(sc, NULL); ath9k_ps_wakeup(sc); ath9k_tx99_stop(sc); @@ -127,7 +127,7 @@ static int ath9k_tx99_init(struct ath_softc *sc) memset(&txctl, 0, sizeof(txctl)); txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; - ath_reset(sc); + ath_reset(sc, NULL); ath9k_ps_wakeup(sc); -- GitLab From ae2ff23930d78ff619852c47a4b89aef5a26ef2b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:12 +0530 Subject: [PATCH 1491/9457] ath9k: Set ATH_OP_HW_RESET before HW reset When a HW reset is done, the interrupt tasklet is disabled before ISRs are disabled in the HW. This allows a small window where the HW can still generate interrupts. Since the tasklet is disabled and not killed, it is not scheduled but deferred for execution at a later time. This happens because ATH_OP_HW_RESET is not set when ath_reset() is called. When the hw_reset_work workqueue is used, this problem doesn't arise because ATH_OP_HW_RESET is set and the ISR bails out. Set ATH_OP_HW_RESET properly in ath_reset() to avoid this race - all the ath_reset_internal() callers have been converted to use ath_reset() in the previous patch. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index eb6ba9f8d9ff..dda09ba321d7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -598,10 +598,17 @@ irqreturn_t ath_isr(int irq, void *dev) #undef SCHED_INTR } +/* + * This function is called when a HW reset cannot be deferred + * and has to be immediate. + */ int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); int r; + set_bit(ATH_OP_HW_RESET, &common->op_flags); + ath9k_ps_wakeup(sc); r = ath_reset_internal(sc, hchan); ath9k_ps_restore(sc); @@ -609,6 +616,11 @@ int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan) return r; } +/* + * When a HW reset can be deferred, it is added to the + * hw_reset_work workqueue, but we set ATH_OP_HW_RESET before + * queueing. + */ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); -- GitLab From eaf04a6915660c29e5e3532afb76cb41918ec5c5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:13 +0530 Subject: [PATCH 1492/9457] ath9k: Disable beacon tasklet during reset When a chip reset is done, all running timers, tasklets etc. are stopped but the beacon tasklet is left running. Fix this. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index dda09ba321d7..5d54f39a61a8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -281,6 +281,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) __ath_cancel_work(sc); tasklet_disable(&sc->intr_tq); + tasklet_disable(&sc->bcon_tasklet); spin_lock_bh(&sc->sc_pcu_lock); if (!sc->cur_chan->offchannel) { @@ -326,6 +327,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) out: spin_unlock_bh(&sc->sc_pcu_lock); + tasklet_enable(&sc->bcon_tasklet); tasklet_enable(&sc->intr_tq); return r; -- GitLab From 8890d05ff5f4bc0ba81f2d3d845cc95631c78cac Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:14 +0530 Subject: [PATCH 1493/9457] ath9k: Clear NoA schedule properly When an active context transitions to inactive state, the NoA schedule needs to be removed for the context that has beaconing enabled. Not doing this will affect p2p clients. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 709facca8acd..74a5c27ba63f 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -356,6 +356,21 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, "Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n"); } + /* + * When a context becomes inactive, for example, + * disassociation of a station context, the NoA + * attribute needs to be removed from subsequent + * beacons. + */ + if (!ctx->active && avp->noa_duration && + sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) { + avp->noa_duration = 0; + avp->periodic_noa = false; + + ath_dbg(common, CHAN_CTX, + "Clearing NoA schedule\n"); + } + if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) break; -- GitLab From 2fae0d9fb038d8cd354d51fbb0560cf252a66ecc Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:15 +0530 Subject: [PATCH 1494/9457] ath9k: Use configurable timeout for flush The timeout value for flushing the TX queues is hardcoded at 200ms right now. Use a channel context-specific value instead to allow adjustments to the timeout in case MCC is enabled. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/channel.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bc90fabdd921..43c1987978a8 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -345,6 +345,7 @@ struct ath_chanctx { u64 tsf_val; u32 last_beacon; + int flush_timeout; u16 txpower; bool offchannel; bool stopped; diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 74a5c27ba63f..5045b107b6d8 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -117,6 +117,7 @@ void ath_chanctx_init(struct ath_softc *sc) cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20); INIT_LIST_HEAD(&ctx->vifs); ctx->txpower = ATH_TXPOWER_MAX; + ctx->flush_timeout = HZ / 5; /* 200ms */ for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) INIT_LIST_HEAD(&ctx->acq[j]); } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5d54f39a61a8..81a20de771c5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2034,7 +2034,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - int timeout = HZ / 5; /* 200 ms */ + int timeout; bool drain_txq; cancel_delayed_work_sync(&sc->tx_complete_work); @@ -2049,6 +2049,13 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) return; } + spin_lock_bh(&sc->chan_lock); + timeout = sc->cur_chan->flush_timeout; + spin_unlock_bh(&sc->chan_lock); + + ath_dbg(common, CHAN_CTX, + "Flush timeout: %d\n", jiffies_to_msecs(timeout)); + if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc), timeout) > 0) drop = false; -- GitLab From 67259d51dfea82f824699db4458bacb2124cb074 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:16 +0530 Subject: [PATCH 1495/9457] ath9k: Fix MCC flush timeout In MCC mode, the duration for a channel context is half the beacon interval and having a large flush timeout will adversely affect GO operation, since the default value of 200ms will overshoot the advertised NoA absence duration. The scheduler initiates a channel context switch only when the slot duration for the current context expires, so there is no possibility of having a fixed timeout for flush. Since the channel_switch_time is added to the absence duration when the GO sets up the NoA attribute, this is the maximum time that we have to flush the TX queues. The duration is very small, but we don't have a choice in MCC mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 5045b107b6d8..7e518aad37ea 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -199,6 +199,7 @@ static const char *chanctx_state_string(enum ath_chanctx_state state) void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_chanctx *ictx; struct ath_vif *avp; bool active = false; u8 n_active = 0; @@ -206,6 +207,8 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) if (!ctx) return; + ictx = ctx; + list_for_each_entry(avp, &ctx->vifs, list) { struct ieee80211_vif *vif = avp->vif; @@ -228,12 +231,23 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) n_active++; } + spin_lock_bh(&sc->chan_lock); + if (n_active <= 1) { + ictx->flush_timeout = HZ / 5; clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags); + spin_unlock_bh(&sc->chan_lock); return; } - if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) + + ictx->flush_timeout = usecs_to_jiffies(sc->sched.channel_switch_time); + + if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) { + spin_unlock_bh(&sc->chan_lock); return; + } + + spin_unlock_bh(&sc->chan_lock); if (ath9k_is_chanctx_enabled()) { ath_chanctx_event(sc, NULL, -- GitLab From 290c8a77e8a9c719bbb11862138e76c9c1dfda61 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:17 +0530 Subject: [PATCH 1496/9457] ath9k: Fix offchannel flush timeout An offchannel operation also needs to have a flush timeout that doesn't exceed the NoA absence duration of a GO context, so use channel_switch_time. The first offchannel operation is set a flush timeout of 10ms since channel_switch_time will be zero. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 7e518aad37ea..abc3e2e77ba6 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -207,6 +207,26 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) if (!ctx) return; + if (ctx == &sc->offchannel.chan) { + spin_lock_bh(&sc->chan_lock); + + if (likely(sc->sched.channel_switch_time)) + ctx->flush_timeout = + usecs_to_jiffies(sc->sched.channel_switch_time); + else + ctx->flush_timeout = + msecs_to_jiffies(10); + + spin_unlock_bh(&sc->chan_lock); + + /* + * There is no need to iterate over the + * active/assigned channel contexts if + * the current context is offchannel. + */ + return; + } + ictx = ctx; list_for_each_entry(avp, &ctx->vifs, list) { -- GitLab From e2d389b5aa3741431fc89fca993b7818545dc0f1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:18 +0530 Subject: [PATCH 1497/9457] ath9k: Check for pending frames properly Pending frames in the driver can be present either in the HW queues or SW. ath9k_has_pending_frames() currently checks for the HW queues first and then checks if any ACs are queued in the driver. In MCC mode, we need to check the HW queues alone, since the SW queues are just marked as 'stopped' - they will be processed in the next context switch. But since we don't differentiate this now, mention whether we want to check if there are frames in the SW queues. * The flush() callback checks both HW and SW queues. * The tx_frames_pending() callback does the same. * The call to __ath9k_flush() in MCC mode checks HW queues alone. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/channel.c | 5 +++-- drivers/net/wireless/ath/ath9k/main.c | 21 ++++++++++++++------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 43c1987978a8..d4b71ed90236 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -715,7 +715,8 @@ int ath_update_survey_stats(struct ath_softc *sc); void ath_update_survey_nf(struct ath_softc *sc, int channel); void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); void ath_ps_full_sleep(unsigned long data); -void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop); +void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, + bool sw_pending); /**********/ /* BTCOEX */ diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index abc3e2e77ba6..9c4f872c6e27 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -1137,10 +1137,11 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) ath9k_chanctx_stop_queues(sc, sc->cur_chan); queues_stopped = true; - __ath9k_flush(sc->hw, ~0, true); + __ath9k_flush(sc->hw, ~0, true, false); if (ath_chanctx_send_ps_frame(sc, true)) - __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false); + __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), + false, false); send_ps = true; spin_lock_bh(&sc->chan_lock); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 81a20de771c5..2048ef1d8369 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -54,7 +54,8 @@ u8 ath9k_parse_mpdudensity(u8 mpdudensity) } } -static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) +static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq, + bool sw_pending) { bool pending = false; @@ -65,6 +66,9 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) goto out; } + if (!sw_pending) + goto out; + if (txq->mac80211_qnum >= 0) { struct list_head *list; @@ -2003,7 +2007,8 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, mutex_unlock(&sc->mutex); } -static bool ath9k_has_tx_pending(struct ath_softc *sc) +static bool ath9k_has_tx_pending(struct ath_softc *sc, + bool sw_pending) { int i, npend = 0; @@ -2011,7 +2016,8 @@ static bool ath9k_has_tx_pending(struct ath_softc *sc) if (!ATH_TXQ_SETUP(sc, i)) continue; - npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); + npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i], + sw_pending); if (npend) break; } @@ -2025,11 +2031,12 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath_softc *sc = hw->priv; mutex_lock(&sc->mutex); - __ath9k_flush(hw, queues, drop); + __ath9k_flush(hw, queues, drop, true); mutex_unlock(&sc->mutex); } -void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) +void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, + bool sw_pending) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; @@ -2056,7 +2063,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) ath_dbg(common, CHAN_CTX, "Flush timeout: %d\n", jiffies_to_msecs(timeout)); - if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc), + if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc, sw_pending), timeout) > 0) drop = false; @@ -2079,7 +2086,7 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; - return ath9k_has_tx_pending(sc); + return ath9k_has_tx_pending(sc, true); } static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) -- GitLab From 91e6ceb354289ef1b143735b218599b5ad1b58c8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:19 +0530 Subject: [PATCH 1498/9457] ath9k: Send AUTHORIZED event only for station mode ATH_CHANCTX_EVENT_AUTHORIZED is required to trigger the MCC scheduler when a station interface becomes authorized. But, since the driver gets station state notifications when the current operating mode is AP too, make sure that we send ATH_CHANCTX_EVENT_AUTHORIZED only when the interface is in station mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2048ef1d8369..0545fe64e1e5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1590,10 +1590,12 @@ static int ath9k_sta_state(struct ieee80211_hw *hw, } if (ath9k_is_chanctx_enabled()) { - if (old_state == IEEE80211_STA_ASSOC && - new_state == IEEE80211_STA_AUTHORIZED) - ath_chanctx_event(sc, vif, - ATH_CHANCTX_EVENT_AUTHORIZED); + if (vif->type == NL80211_IFTYPE_STATION) { + if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTHORIZED) + ath_chanctx_event(sc, vif, + ATH_CHANCTX_EVENT_AUTHORIZED); + } } return ret; -- GitLab From 62ae1aef2070e9d281e2daab2447ab85d30df99a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:20 +0530 Subject: [PATCH 1499/9457] ath9k: Fix address management Since both the arguments need to satisfy the alignment requirements of ether_addr_copy(), use memcpy() in cases where there will be no big performance benefit and make sure that ether_addr_copy() calls use properly aligned arguments. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 +- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index e5ba6faf3281..9c56ecbae37f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -147,7 +147,7 @@ struct ath_common { u16 cachelsz; u16 curaid; u8 macaddr[ETH_ALEN]; - u8 curbssid[ETH_ALEN]; + u8 curbssid[ETH_ALEN] __aligned(2); u8 bssidmask[ETH_ALEN]; u32 rx_bufsize; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d4b71ed90236..9e92cb2145bc 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -595,7 +595,7 @@ struct ath_vif { u16 seq_no; /* BSS info */ - u8 bssid[ETH_ALEN]; + u8 bssid[ETH_ALEN] __aligned(2); u16 aid; bool assoc; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0545fe64e1e5..c291d54756ef 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1057,7 +1057,7 @@ static void ath9k_set_offchannel_state(struct ath_softc *sc) eth_zero_addr(common->curbssid); eth_broadcast_addr(common->bssidmask); - ether_addr_copy(common->macaddr, vif->addr); + memcpy(common->macaddr, vif->addr, ETH_ALEN); common->curaid = 0; ah->opmode = vif->type; ah->imask &= ~ATH9K_INT_SWBA; @@ -1098,7 +1098,7 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, ath9k_calculate_iter_data(sc, ctx, &iter_data); if (iter_data.has_hw_macaddr) - ether_addr_copy(common->macaddr, iter_data.hw_macaddr); + memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN); memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ath_hw_setbssidmask(common); @@ -1785,7 +1785,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", bss_conf->bssid, bss_conf->assoc); - ether_addr_copy(avp->bssid, bss_conf->bssid); + memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); avp->aid = bss_conf->aid; avp->assoc = bss_conf->assoc; -- GitLab From 26103b8d1da2117b3995f431f90e9bfb9ee3d7ec Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:21 +0530 Subject: [PATCH 1500/9457] ath9k: Add a function to check for an active GO Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/channel.c | 30 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9e92cb2145bc..8f6f46c8f070 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -469,6 +469,7 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force); void ath_offchannel_next(struct ath_softc *sc); void ath_scan_complete(struct ath_softc *sc, bool abort); void ath_roc_complete(struct ath_softc *sc, bool abort); +struct ath_chanctx* ath_is_go_chanctx_present(struct ath_softc *sc); #else diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 9c4f872c6e27..2066b0950235 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -146,6 +146,36 @@ void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx, #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT +/*************/ +/* Utilities */ +/*************/ + +struct ath_chanctx* ath_is_go_chanctx_present(struct ath_softc *sc) +{ + struct ath_chanctx *ctx; + struct ath_vif *avp; + struct ieee80211_vif *vif; + + spin_lock_bh(&sc->chan_lock); + + ath_for_each_chanctx(sc, ctx) { + if (!ctx->active) + continue; + + list_for_each_entry(avp, &ctx->vifs, list) { + vif = avp->vif; + + if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_P2P_GO) { + spin_unlock_bh(&sc->chan_lock); + return ctx; + } + } + } + + spin_unlock_bh(&sc->chan_lock); + return NULL; +} + /**********************************************************/ /* Functions to handle the channel context state machine. */ /**********************************************************/ -- GitLab From c6500ea29a8f695d5bbddf1b31e1b0b5312a6019 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:22 +0530 Subject: [PATCH 1501/9457] ath9k: Check for active GO in mgd_prepare_tx() If a GO interface is active when we receive a mgd_prepare_tx() call, then we need to send out a new NoA before switching to a new context. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/channel.c | 14 ++++++++ drivers/net/wireless/ath/ath9k/main.c | 45 ++++++++++++++++++++---- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8f6f46c8f070..b7abb4f2b226 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -385,6 +385,7 @@ struct ath_chanctx_sched { bool wait_switch; bool force_noa_update; bool extend_absence; + bool mgd_prepare_tx; enum ath_chanctx_state state; u8 beacon_miss; @@ -977,6 +978,7 @@ struct ath_softc { struct ath_chanctx_sched sched; struct ath_offchannel offchannel; struct ath_chanctx *next_chan; + struct completion go_beacon; #endif unsigned long driver_data; diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 2066b0950235..45d2c48bf126 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -421,6 +421,9 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, "Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n"); } + if (sc->sched.mgd_prepare_tx) + sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; + /* * When a context becomes inactive, for example, * disassociation of a station context, the NoA @@ -547,6 +550,15 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, } sc->sched.beacon_pending = false; + + if (sc->sched.mgd_prepare_tx) { + sc->sched.mgd_prepare_tx = false; + complete(&sc->go_beacon); + ath_dbg(common, CHAN_CTX, + "Beacon sent, complete go_beacon\n"); + break; + } + if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) break; @@ -1263,6 +1275,8 @@ void ath9k_init_channel_context(struct ath_softc *sc) (unsigned long)sc); setup_timer(&sc->sched.timer, ath_chanctx_timer, (unsigned long)sc); + + init_completion(&sc->go_beacon); } void ath9k_deinit_channel_context(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c291d54756ef..f58781a14792 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2474,7 +2474,11 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_vif *avp = (struct ath_vif *) vif->drv_priv; + struct ath_beacon_config *cur_conf; + struct ath_chanctx *go_ctx; + unsigned long timeout; bool changed = false; + u32 beacon_int; if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) return; @@ -2485,19 +2489,46 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); spin_lock_bh(&sc->chan_lock); - if (sc->next_chan || (sc->cur_chan != avp->chanctx)) { - sc->next_chan = avp->chanctx; + if (sc->next_chan || (sc->cur_chan != avp->chanctx)) changed = true; + spin_unlock_bh(&sc->chan_lock); + + if (!changed) + goto out; + + go_ctx = ath_is_go_chanctx_present(sc); + + if (go_ctx) { + /* + * Wait till the GO interface gets a chance + * to send out an NoA. + */ + spin_lock_bh(&sc->chan_lock); + sc->sched.mgd_prepare_tx = true; + cur_conf = &go_ctx->beacon; + beacon_int = TU_TO_USEC(cur_conf->beacon_interval); + spin_unlock_bh(&sc->chan_lock); + + timeout = usecs_to_jiffies(beacon_int); + init_completion(&sc->go_beacon); + + if (wait_for_completion_timeout(&sc->go_beacon, + timeout) == 0) + ath_dbg(common, CHAN_CTX, + "Failed to send new NoA\n"); } + ath_dbg(common, CHAN_CTX, - "%s: Set chanctx state to FORCE_ACTIVE, changed: %d\n", - __func__, changed); + "%s: Set chanctx state to FORCE_ACTIVE for vif: %pM\n", + __func__, vif->addr); + + spin_lock_bh(&sc->chan_lock); + sc->next_chan = avp->chanctx; sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE; spin_unlock_bh(&sc->chan_lock); - if (changed) - ath_chanctx_set_next(sc, true); - + ath_chanctx_set_next(sc, true); +out: mutex_unlock(&sc->mutex); } -- GitLab From a23152a82f2c98acba2255ea57ca49a0180d863f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:23 +0530 Subject: [PATCH 1502/9457] ath9k: Use a helper function for offchannel NoA Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 45 ++++++++++++++---------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 45d2c48bf126..c6e130da683f 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -366,6 +366,32 @@ static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time) "Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time)); } +static void ath_chanctx_offchannel_noa(struct ath_softc *sc, + struct ath_chanctx *ctx, + struct ath_vif *avp, + u32 tsf_time) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + avp->noa_index++; + avp->offchannel_start = tsf_time; + avp->offchannel_duration = sc->sched.offchannel_duration; + + ath_dbg(common, CHAN_CTX, + "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n", + avp->offchannel_duration, + avp->offchannel_start, + avp->noa_index); + + /* + * When multiple contexts are active, the NoA + * has to be recalculated and advertised after + * an offchannel operation. + */ + if (ctx->active && avp->noa_duration) + avp->noa_duration = 0; +} + void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, enum ath_chanctx_event ev) { @@ -461,24 +487,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, * values and increment the index. */ if (sc->next_chan == &sc->offchannel.chan) { - avp->noa_index++; - avp->offchannel_start = tsf_time; - avp->offchannel_duration = sc->sched.offchannel_duration; - - ath_dbg(common, CHAN_CTX, - "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n", - avp->offchannel_duration, - avp->offchannel_start, - avp->noa_index); - - /* - * When multiple contexts are active, the NoA - * has to be recalculated and advertised after - * an offchannel operation. - */ - if (ctx->active && avp->noa_duration) - avp->noa_duration = 0; - + ath_chanctx_offchannel_noa(sc, ctx, avp, tsf_time); break; } -- GitLab From 347a9566ab1c8929d8ceaab59a8b56ac901ca312 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:24 +0530 Subject: [PATCH 1503/9457] ath9k: Use a helper function to set NoA Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 61 ++++++++++++++---------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index c6e130da683f..7d6f76b46132 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -392,6 +392,39 @@ static void ath_chanctx_offchannel_noa(struct ath_softc *sc, avp->noa_duration = 0; } +static void ath_chanctx_set_periodic_noa(struct ath_softc *sc, + struct ath_vif *avp, + struct ath_beacon_config *cur_conf, + u32 tsf_time, + u32 beacon_int) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + avp->noa_index++; + avp->noa_start = tsf_time; + + if (sc->sched.extend_absence) + avp->noa_duration = (3 * beacon_int / 2) + + sc->sched.channel_switch_time; + else + avp->noa_duration = + TU_TO_USEC(cur_conf->beacon_interval) / 2 + + sc->sched.channel_switch_time; + + if (test_bit(ATH_OP_SCANNING, &common->op_flags) || + sc->sched.extend_absence) + avp->periodic_noa = false; + else + avp->periodic_noa = true; + + ath_dbg(common, CHAN_CTX, + "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", + avp->noa_duration, + avp->noa_start, + avp->noa_index, + avp->periodic_noa); +} + void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, enum ath_chanctx_event ev) { @@ -521,31 +554,9 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, * announcement. */ if (ctx->active && - (!avp->noa_duration || sc->sched.force_noa_update)) { - avp->noa_index++; - avp->noa_start = tsf_time; - - if (sc->sched.extend_absence) - avp->noa_duration = (3 * beacon_int / 2) + - sc->sched.channel_switch_time; - else - avp->noa_duration = - TU_TO_USEC(cur_conf->beacon_interval) / 2 + - sc->sched.channel_switch_time; - - if (test_bit(ATH_OP_SCANNING, &common->op_flags) || - sc->sched.extend_absence) - avp->periodic_noa = false; - else - avp->periodic_noa = true; - - ath_dbg(common, CHAN_CTX, - "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", - avp->noa_duration, - avp->noa_start, - avp->noa_index, - avp->periodic_noa); - } + (!avp->noa_duration || sc->sched.force_noa_update)) + ath_chanctx_set_periodic_noa(sc, avp, cur_conf, + tsf_time, beacon_int); if (ctx->active && sc->sched.force_noa_update) sc->sched.force_noa_update = false; -- GitLab From 828fe01acb5edcd47b50901ef944b7d98b329636 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:25 +0530 Subject: [PATCH 1504/9457] ath9k: Use a helper function for bmiss Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 45 ++++++++++++++---------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 7d6f76b46132..7fe35a5911f4 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -366,6 +366,31 @@ static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time) "Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time)); } +static void ath_chanctx_handle_bmiss(struct ath_softc *sc, + struct ath_chanctx *ctx, + struct ath_vif *avp) +{ + /* + * Clear the extend_absence flag if it had been + * set during the previous beacon transmission, + * since we need to revert to the normal NoA + * schedule. + */ + if (ctx->active && sc->sched.extend_absence) { + avp->noa_duration = 0; + sc->sched.extend_absence = false; + } + + /* If at least two consecutive beacons were missed on the STA + * chanctx, stay on the STA channel for one extra beacon period, + * to resync the timer properly. + */ + if (ctx->active && sc->sched.beacon_miss >= 2) { + avp->noa_duration = 0; + sc->sched.extend_absence = true; + } +} + static void ath_chanctx_offchannel_noa(struct ath_softc *sc, struct ath_chanctx *ctx, struct ath_vif *avp, @@ -524,25 +549,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, break; } - /* - * Clear the extend_absence flag if it had been - * set during the previous beacon transmission, - * since we need to revert to the normal NoA - * schedule. - */ - if (ctx->active && sc->sched.extend_absence) { - avp->noa_duration = 0; - sc->sched.extend_absence = false; - } - - /* If at least two consecutive beacons were missed on the STA - * chanctx, stay on the STA channel for one extra beacon period, - * to resync the timer properly. - */ - if (ctx->active && sc->sched.beacon_miss >= 2) { - avp->noa_duration = 0; - sc->sched.extend_absence = true; - } + ath_chanctx_handle_bmiss(sc, ctx, avp); /* Prevent wrap-around issues */ if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30)) -- GitLab From a350335c5f3bbba2974446a18958d8c334de55f8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:26 +0530 Subject: [PATCH 1505/9457] ath9k: Fix RoC expiration mac80211 has to be notified when a RoC period expires in the driver. In MCC mode, since the offchannel/RoC timer is set with the requested duration, ieee80211_remain_on_channel_expired() needs to be called when the timer expires. But, currently it is done after we move back to the operating channel. This is incorrect - fix this by calling ieee80211_remain_on_channel_expired() when the RoC timer expires and in ath_roc_complete() when the RoC request is aborted. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 7fe35a5911f4..447b397ca62e 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -894,7 +894,7 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) sc->offchannel.roc_vif = NULL; sc->offchannel.roc_chan = NULL; - if (!abort) + if (abort) ieee80211_remain_on_channel_expired(sc->hw); ath_offchannel_next(sc); ath9k_ps_restore(sc); @@ -1028,6 +1028,7 @@ static void ath_offchannel_timer(unsigned long data) case ATH_OFFCHANNEL_ROC_WAIT: ctx = ath_chanctx_get_oper_chan(sc, false); sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE; + ieee80211_remain_on_channel_expired(sc->hw); ath_chanctx_switch(sc, ctx, NULL); break; default: -- GitLab From 0a019a58e3c830cd4505ae791e1d38952b001afe Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:27 +0530 Subject: [PATCH 1506/9457] ath9k: Send oneshot NoA This patch makes sure that a GO interface sends out a new NoA schedule with 200ms duration when mgd_prepare_tx() is called. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/channel.c | 41 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b7abb4f2b226..7ac1b06e8fbc 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -620,6 +620,7 @@ struct ath_vif { u32 noa_start; u32 noa_duration; bool periodic_noa; + bool oneshot_noa; }; struct ath9k_vif_iter_data { diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 447b397ca62e..366a4d9098e7 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -450,6 +450,27 @@ static void ath_chanctx_set_periodic_noa(struct ath_softc *sc, avp->periodic_noa); } +static void ath_chanctx_set_oneshot_noa(struct ath_softc *sc, + struct ath_vif *avp, + u32 tsf_time, + u32 duration) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + avp->noa_index++; + avp->noa_start = tsf_time; + avp->periodic_noa = false; + avp->oneshot_noa = true; + avp->noa_duration = duration + sc->sched.channel_switch_time; + + ath_dbg(common, CHAN_CTX, + "oneshot noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", + avp->noa_duration, + avp->noa_start, + avp->noa_index, + avp->periodic_noa); +} + void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, enum ath_chanctx_event ev) { @@ -476,6 +497,14 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, if (avp->offchannel_duration) avp->offchannel_duration = 0; + if (avp->oneshot_noa) { + avp->noa_duration = 0; + avp->oneshot_noa = false; + + ath_dbg(common, CHAN_CTX, + "Clearing oneshot NoA\n"); + } + if (avp->chanctx != sc->cur_chan) { ath_dbg(common, CHAN_CTX, "Contexts differ, not preparing beacon\n"); @@ -551,6 +580,18 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, ath_chanctx_handle_bmiss(sc, ctx, avp); + /* + * If a mgd_prepare_tx() has been called by mac80211, + * a one-shot NoA needs to be sent. This can happen + * with one or more active channel contexts - in both + * cases, a new NoA schedule has to be advertised. + */ + if (sc->sched.mgd_prepare_tx) { + ath_chanctx_set_oneshot_noa(sc, avp, tsf_time, + jiffies_to_usecs(HZ / 5)); + break; + } + /* Prevent wrap-around issues */ if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30)) avp->noa_duration = 0; -- GitLab From 23aab0c25fb1b481ae28a816e0388a3515a8c9df Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:28 +0530 Subject: [PATCH 1507/9457] ath9k: Fix HW scan abort Instead of using ATH_CHANCTX_EVENT_ASSIGN to abort a HW scan when a new interface becomes active, use the mgd_prepare_tx() callback. This allows us to make sure that the GO's channel becomes operational by using flush_work(). Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 16 ---------------- drivers/net/wireless/ath/ath9k/main.c | 14 +++++++++++++- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 366a4d9098e7..25b898e0e61d 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -743,22 +743,6 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, ieee80211_queue_work(sc->hw, &sc->chanctx_work); break; case ATH_CHANCTX_EVENT_ASSIGN: - /* - * When adding a new channel context, check if a scan - * is in progress and abort it since the addition of - * a new channel context is usually followed by VIF - * assignment, in which case we have to start multi-channel - * operation. - */ - if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { - ath_dbg(common, CHAN_CTX, - "Aborting HW scan to add new context\n"); - - spin_unlock_bh(&sc->chan_lock); - del_timer_sync(&sc->offchannel.timer); - ath_scan_complete(sc, true); - spin_lock_bh(&sc->chan_lock); - } break; case ATH_CHANCTX_EVENT_CHANGE: break; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f58781a14792..a524eebda673 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2365,7 +2365,6 @@ static int ath9k_add_chanctx(struct ieee80211_hw *hw, conf->def.chan->center_freq); ath_chanctx_set_channel(sc, ctx, &conf->def); - ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ASSIGN); mutex_unlock(&sc->mutex); return 0; @@ -2496,6 +2495,19 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, if (!changed) goto out; + if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { + ath_dbg(common, CHAN_CTX, + "%s: Aborting HW scan\n", __func__); + + mutex_unlock(&sc->mutex); + + del_timer_sync(&sc->offchannel.timer); + ath_scan_complete(sc, true); + flush_work(&sc->chanctx_work); + + mutex_lock(&sc->mutex); + } + go_ctx = ath_is_go_chanctx_present(sc); if (go_ctx) { -- GitLab From 25f3bc7dbdf56edc7025450ecb88c626137aed5f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:29 +0530 Subject: [PATCH 1508/9457] ath9k: Improve flush() in mcc mode The flush timeout in MCC mode is very small, since we are constrained by the time slice for each channel context, but since only the HW queues are flushed when switching contexts, it is acceptable. Since the SW queues are also emptied in the mac80211 flush() callback, a larger duration is needed. Add an override argument to __ath9k_flush() and set it when flush() is called in MCC mode. This allows the driver to drain both the SW and HW queues. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/channel.c | 4 ++-- drivers/net/wireless/ath/ath9k/main.c | 28 +++++++++++++++++++++--- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7ac1b06e8fbc..85d74ff0767c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -719,7 +719,7 @@ void ath_update_survey_nf(struct ath_softc *sc, int channel); void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); void ath_ps_full_sleep(unsigned long data); void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, - bool sw_pending); + bool sw_pending, bool timeout_override); /**********/ /* BTCOEX */ diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 25b898e0e61d..c7234d5dda34 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -1232,11 +1232,11 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) ath9k_chanctx_stop_queues(sc, sc->cur_chan); queues_stopped = true; - __ath9k_flush(sc->hw, ~0, true, false); + __ath9k_flush(sc->hw, ~0, true, false, false); if (ath_chanctx_send_ps_frame(sc, true)) __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), - false, false); + false, false, false); send_ps = true; spin_lock_bh(&sc->chan_lock); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a524eebda673..961a3887a589 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2031,14 +2031,33 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) { struct ath_softc *sc = hw->priv; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + if (ath9k_is_chanctx_enabled()) { + if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) + goto flush; + /* + * If MCC is active, extend the flush timeout + * and wait for the HW/SW queues to become + * empty. This needs to be done outside the + * sc->mutex lock to allow the channel scheduler + * to switch channel contexts. + * + * The vif queues have been stopped in mac80211, + * so there won't be any incoming frames. + */ + __ath9k_flush(hw, queues, drop, true, true); + return; + } +flush: mutex_lock(&sc->mutex); - __ath9k_flush(hw, queues, drop, true); + __ath9k_flush(hw, queues, drop, true, false); mutex_unlock(&sc->mutex); } void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, - bool sw_pending) + bool sw_pending, bool timeout_override) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; @@ -2059,7 +2078,10 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, } spin_lock_bh(&sc->chan_lock); - timeout = sc->cur_chan->flush_timeout; + if (timeout_override) + timeout = HZ / 5; + else + timeout = sc->cur_chan->flush_timeout; spin_unlock_bh(&sc->chan_lock); ath_dbg(common, CHAN_CTX, -- GitLab From 1e929d3e02bfa1138f99566ee791358f213018eb Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Fri, 17 Oct 2014 07:40:30 +0530 Subject: [PATCH 1509/9457] ath9k: Do not start BA when scanning mac80211 currently has a race which can be hit with this sequence: * Start a scan operation. * TX BA is initiated by ieee80211_start_tx_ba_session(). * Driver sets up internal state and calls ieee80211_start_tx_ba_cb_irqsafe(). * mac80211 adds a packet to sdata->skb_queue with type IEEE80211_SDATA_QUEUE_AGG_START. * ieee80211_iface_work() doesn't process the packet because scan is in progress. * ADDBA response timer expires and the sta/tid is torn down. * Driver receives BA stop notification and calls ieee80211_stop_tx_ba_cb_irqsafe(). * This is also added to the queue by mac80211. * Now, scan finishes. At this point, the queued up packets might be processed if some other operation schedules the sdata work. Since the tids have been cleaned up already, warnings are hit. If this doesn't happen, the packets are left in the queue until the interface is torn down. Since initiating a BA session when scan is in progress leads to flaky connections, especially in MCC mode, we can drop the TX BA request. This improves connectivity with legacy clients in MCC mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 961a3887a589..68c5670d0a88 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1885,6 +1885,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, u16 tid, u16 *ssn, u8 buf_size) { struct ath_softc *sc = hw->priv; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); bool flush = false; int ret = 0; @@ -1896,6 +1897,12 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: + if (ath9k_is_chanctx_enabled()) { + if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { + ret = -EBUSY; + break; + } + } ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) -- GitLab From d19c230f5f93d9439883ed81ec2f41f0b2b89b75 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 22 Oct 2014 12:21:44 +0530 Subject: [PATCH 1510/9457] ath9k: Update AR9580 initvals This fixes RX sensitivity issues with AR9580. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- .../wireless/ath/ath9k/ar9580_1p0_initvals.h | 144 +++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index a5ca65240af3..5d4629f96c15 100644 --- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h @@ -24,7 +24,149 @@ #define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble -#define ar9580_1p0_radio_core ar9300_2p2_radio_core +static const u32 ar9580_1p0_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db2db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73f00000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x76d005b5}, + {0x00016050, 0x556cf031}, + {0x00016054, 0x13449440}, + {0x00016058, 0x0c51c92c}, + {0x0001605c, 0x3db7fffc}, + {0x00016060, 0xfffffffc}, + {0x00016064, 0x000f0278}, + {0x0001606c, 0x6db60000}, + {0x00016080, 0x00000000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x54214514}, + {0x0001608c, 0x119f481e}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd2888888}, + {0x000160a0, 0x0a108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92480080}, + {0x000160c0, 0x00adb6d0}, + {0x000160c4, 0x6db6db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x01e6c000}, + {0x00016100, 0x3fffbe01}, + {0x00016104, 0xfff80000}, + {0x00016108, 0x00080010}, + {0x00016144, 0x02084080}, + {0x00016148, 0x00000000}, + {0x00016280, 0x058a0001}, + {0x00016284, 0x3d840208}, + {0x00016288, 0x05a20408}, + {0x0001628c, 0x00038c07}, + {0x00016290, 0x00000004}, + {0x00016294, 0x458a214f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, + {0x00016400, 0x36db2db6}, + {0x00016404, 0x6db6db40}, + {0x00016408, 0x73f00000}, + {0x0001640c, 0x00000000}, + {0x00016440, 0x7f80fff8}, + {0x0001644c, 0x76d005b5}, + {0x00016450, 0x556cf031}, + {0x00016454, 0x13449440}, + {0x00016458, 0x0c51c92c}, + {0x0001645c, 0x3db7fffc}, + {0x00016460, 0xfffffffc}, + {0x00016464, 0x000f0278}, + {0x0001646c, 0x6db60000}, + {0x00016500, 0x3fffbe01}, + {0x00016504, 0xfff80000}, + {0x00016508, 0x00080010}, + {0x00016544, 0x02084080}, + {0x00016548, 0x00000000}, + {0x00016780, 0x00000000}, + {0x00016784, 0x00000000}, + {0x00016788, 0x00800700}, + {0x0001678c, 0x00800700}, + {0x00016790, 0x00800700}, + {0x00016794, 0x00000000}, + {0x00016798, 0x00000000}, + {0x0001679c, 0x00000000}, + {0x000167a0, 0x00000001}, + {0x000167a4, 0x00000001}, + {0x000167a8, 0x00000000}, + {0x000167ac, 0x00000000}, + {0x000167b0, 0x00000000}, + {0x000167b4, 0x00000000}, + {0x000167b8, 0x00000000}, + {0x000167bc, 0x00000000}, + {0x000167c0, 0x000000a0}, + {0x000167c4, 0x000c0000}, + {0x000167c8, 0x14021402}, + {0x000167cc, 0x00001402}, + {0x000167d0, 0x00000000}, + {0x000167d4, 0x00000000}, + {0x00016800, 0x36db2db6}, + {0x00016804, 0x6db6db40}, + {0x00016808, 0x73f00000}, + {0x0001680c, 0x00000000}, + {0x00016840, 0x7f80fff8}, + {0x0001684c, 0x76d005b5}, + {0x00016850, 0x556cf031}, + {0x00016854, 0x13449440}, + {0x00016858, 0x0c51c92c}, + {0x0001685c, 0x3db7fffc}, + {0x00016860, 0xfffffffc}, + {0x00016864, 0x000f0278}, + {0x0001686c, 0x6db60000}, + {0x00016900, 0x3fffbe01}, + {0x00016904, 0xfff80000}, + {0x00016908, 0x00080010}, + {0x00016944, 0x02084080}, + {0x00016948, 0x00000000}, + {0x00016b80, 0x00000000}, + {0x00016b84, 0x00000000}, + {0x00016b88, 0x00800700}, + {0x00016b8c, 0x00800700}, + {0x00016b90, 0x00800700}, + {0x00016b94, 0x00000000}, + {0x00016b98, 0x00000000}, + {0x00016b9c, 0x00000000}, + {0x00016ba0, 0x00000001}, + {0x00016ba4, 0x00000001}, + {0x00016ba8, 0x00000000}, + {0x00016bac, 0x00000000}, + {0x00016bb0, 0x00000000}, + {0x00016bb4, 0x00000000}, + {0x00016bb8, 0x00000000}, + {0x00016bbc, 0x00000000}, + {0x00016bc0, 0x000000a0}, + {0x00016bc4, 0x000c0000}, + {0x00016bc8, 0x14021402}, + {0x00016bcc, 0x00001402}, + {0x00016bd0, 0x00000000}, + {0x00016bd4, 0x00000000}, +}; #define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble -- GitLab From 6424b036e540c1c360d52b237a71bbfe51584321 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 22 Oct 2014 12:21:45 +0530 Subject: [PATCH 1511/9457] ath9k: Update AR955x initvals * Fix a 11b/EVM issue by adjusting FIR filter coefficients. * Fix a problem with receiving probe request frames sent at 11b rate. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h index 74d8bc05b317..fd6a84ccd49e 100644 --- a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h @@ -507,7 +507,7 @@ static const u32 ar955x_1p0_baseband_core[][2] = { {0x00009d04, 0x40206c10}, {0x00009d08, 0x009c4060}, {0x00009d0c, 0x9883800a}, - {0x00009d10, 0x01834061}, + {0x00009d10, 0x01884061}, {0x00009d14, 0x00c0040b}, {0x00009d18, 0x00000000}, {0x00009e08, 0x0038230c}, @@ -545,9 +545,9 @@ static const u32 ar955x_1p0_baseband_core[][2] = { {0x0000a370, 0x00000000}, {0x0000a390, 0x00000001}, {0x0000a394, 0x00000444}, - {0x0000a398, 0x1f020503}, - {0x0000a39c, 0x29180c03}, - {0x0000a3a0, 0x9a8b6844}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, {0x0000a3a4, 0x00000000}, {0x0000a3a8, 0xaaaaaaaa}, {0x0000a3ac, 0x3c466478}, -- GitLab From 935477ed7b537cf28b38f0c6b4471915d8c0e12a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:26 +0200 Subject: [PATCH 1512/9457] ath9k_hw: make support for PC-OEM cards optional The initvals use up quite a bit of space, and PC-OEM support is typically not needed on embedded systems Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 5 +++ drivers/net/wireless/ath/ath9k/Makefile | 3 +- drivers/net/wireless/ath/ath9k/ar9003_rtt.h | 36 +++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 17 +++++++--- drivers/net/wireless/ath/ath9k/init.c | 3 ++ drivers/net/wireless/ath/ath9k/pci.c | 6 ++++ drivers/net/wireless/ath/ath9k/reg.h | 33 +++++++++++-------- 7 files changed, 84 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 896e63281b3b..ca101d7cb99f 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -148,6 +148,11 @@ config ATH9K_CHANNEL_CONTEXT for multi-channel concurrency. Enable this if P2P PowerSave support is required. +config ATH9K_PCOEM + bool "Atheros ath9k support for PC OEM cards" if EXPERT + depends on ATH9K + default y + config ATH9K_HTC tristate "Atheros HTC based wireless cards support" depends on USB && MAC80211 diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 73704c1be736..22b934b07bd4 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -32,7 +32,6 @@ ath9k_hw-y:= \ ar5008_phy.o \ ar9002_calib.o \ ar9003_calib.o \ - ar9003_rtt.o \ calib.o \ eeprom.o \ eeprom_def.o \ @@ -50,6 +49,8 @@ ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ ar9003_mci.o +ath9k_hw-$(CONFIG_ATH9K_PCOEM) += ar9003_rtt.o + ath9k_hw-$(CONFIG_ATH9K_DYNACK) += dynack.o obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h index a43b30d723a4..6290467a75a0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h @@ -17,6 +17,7 @@ #ifndef AR9003_RTT_H #define AR9003_RTT_H +#ifdef CONFIG_ATH9K_PCOEM void ar9003_hw_rtt_enable(struct ath_hw *ah); void ar9003_hw_rtt_disable(struct ath_hw *ah); void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask); @@ -25,5 +26,40 @@ void ar9003_hw_rtt_load_hist(struct ath_hw *ah); void ar9003_hw_rtt_fill_hist(struct ath_hw *ah); void ar9003_hw_rtt_clear_hist(struct ath_hw *ah); bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan); +#else +static inline void ar9003_hw_rtt_enable(struct ath_hw *ah) +{ +} + +static inline void ar9003_hw_rtt_disable(struct ath_hw *ah) +{ +} + +static inline void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask) +{ +} + +static inline bool ar9003_hw_rtt_force_restore(struct ath_hw *ah) +{ + return false; +} + +static inline void ar9003_hw_rtt_load_hist(struct ath_hw *ah) +{ +} + +static inline void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) +{ +} + +static inline void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) +{ +} + +static inline bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) +{ + return false; +} +#endif #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 975074fc11bc..7a81f5b864c7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -244,13 +244,20 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_2GHZ = BIT(11), ATH9K_HW_CAP_5GHZ = BIT(12), ATH9K_HW_CAP_APM = BIT(13), +#ifdef CONFIG_ATH9K_PCOEM ATH9K_HW_CAP_RTT = BIT(14), ATH9K_HW_CAP_MCI = BIT(15), - ATH9K_HW_CAP_DFS = BIT(16), - ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), - ATH9K_HW_CAP_PAPRD = BIT(18), - ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(19), - ATH9K_HW_CAP_BT_ANT_DIV = BIT(20), + ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(16), + ATH9K_HW_CAP_BT_ANT_DIV = BIT(17), +#else + ATH9K_HW_CAP_RTT = 0, + ATH9K_HW_CAP_MCI = 0, + ATH9K_HW_WOW_DEVICE_CAPABLE = 0, + ATH9K_HW_CAP_BT_ANT_DIV = 0, +#endif + ATH9K_HW_CAP_DFS = BIT(18), + ATH9K_HW_CAP_PAPRD = BIT(19), + ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(20), }; /* diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 156a944134dc..57a17601b0b6 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -362,6 +362,9 @@ static void ath9k_init_pcoem_platform(struct ath_softc *sc) struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); + if (!IS_ENABLED(CONFIG_ATH9K_PCOEM)) + return; + if (common->bus_ops->ath_bus_type != ATH_PCI) return; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index c018dea0b2e8..e3f60d5c5263 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -30,6 +30,7 @@ static const struct pci_device_id ath_pci_id_table[] = { { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ +#ifdef CONFIG_ATH9K_PCOEM { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 0x002A, PCI_VENDOR_ID_AZWAVE, @@ -82,6 +83,7 @@ static const struct pci_device_id ath_pci_id_table[] = { PCI_VENDOR_ID_AZWAVE, 0x2C37), .driver_data = ATH9K_PCI_BT_ANT_DIV }, +#endif { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ @@ -102,6 +104,7 @@ static const struct pci_device_id ath_pci_id_table[] = { { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ +#ifdef CONFIG_ATH9K_PCOEM /* PCI-E CUS198 */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 0x0032, @@ -294,10 +297,12 @@ static const struct pci_device_id ath_pci_id_table[] = { PCI_VENDOR_ID_ASUSTEK, 0x850D), .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, +#endif { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ +#ifdef CONFIG_ATH9K_PCOEM /* PCI-E CUS217 */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 0x0034, @@ -657,6 +662,7 @@ static const struct pci_device_id ath_pci_id_table[] = { /* PCI-E AR9565 (WB335) */ { PCI_VDEVICE(ATHEROS, 0x0036), .driver_data = ATH9K_PCI_BT_ANT_DIV }, +#endif { 0 } }; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 2a938f4feac5..1c0b1c1c5350 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -892,10 +892,21 @@ (AR_SREV_9330((_ah)) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12)) +#ifdef CONFIG_ATH9K_PCOEM +#define AR_SREV_9462(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) #define AR_SREV_9485(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) +#define AR_SREV_9565(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) +#else +#define AR_SREV_9462(_ah) 0 +#define AR_SREV_9485(_ah) 0 +#define AR_SREV_9565(_ah) 0 +#endif + #define AR_SREV_9485_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485) && \ + (AR_SREV_9485(_ah) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11)) #define AR_SREV_9485_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485)) @@ -915,34 +926,30 @@ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) -#define AR_SREV_9462(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) #define AR_SREV_9462_20(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ + (AR_SREV_9462(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) #define AR_SREV_9462_21(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ + (AR_SREV_9462(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21)) #define AR_SREV_9462_20_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ + (AR_SREV_9462(_ah) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) #define AR_SREV_9462_21_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ + (AR_SREV_9462(_ah) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21)) -#define AR_SREV_9565(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) #define AR_SREV_9565_10(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ + (AR_SREV_9565(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) #define AR_SREV_9565_101(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ + (AR_SREV_9565(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101)) #define AR_SREV_9565_11(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ + (AR_SREV_9565(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11)) #define AR_SREV_9565_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ + (AR_SREV_9565(_ah) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11)) #define AR_SREV_9550(_ah) \ -- GitLab From 257b5bc6803738c0c87aa675ee8437f07dd64b44 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:27 +0200 Subject: [PATCH 1513/9457] ath9k_hw: remove support for UB124 tx gain table UB124 is a USB based reference design not supported by ath9k or ath9k_htc. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index ddef9eedbac6..cb09102245b2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -670,9 +670,6 @@ static void ar9003_tx_gain_table_mode5(struct ath_hw *ah) if (AR_SREV_9485_11_OR_LATER(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485Modes_green_ob_db_tx_gain_1_1); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9340Modes_ub124_tx_gain_table_1p0); else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9580_1p0_type5_tx_gain_table); -- GitLab From 3b580144725ba6adc034713fe243e69c0f63dd05 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:28 +0200 Subject: [PATCH 1514/9457] ath9k: fix processing RXORN interrupts The "goto chip_reset" is a bit misleading, because it does not actually issue a chip reset. Instead it is bypassing processing of other interrupts and assumes that the tasklet will issue a chip reset. In the case of RXORN this does not happen, so bypassing processing of other interrupts will simply allow them to fire again. Even if RXORN was triggering a reset, it is not critical enough to need the bypass here. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 68c5670d0a88..45465d8e3f0a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -545,11 +545,10 @@ irqreturn_t ath_isr(int irq, void *dev) sched = true; /* - * If a FATAL or RXORN interrupt is received, we have to reset the - * chip immediately. + * If a FATAL interrupt is received, we have to reset the chip + * immediately. */ - if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) && - !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) + if (status & ATH9K_INT_FATAL) goto chip_reset; if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) && -- GitLab From 70e535ed00290ed415ccfb200695ea30b6af51e5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:29 +0200 Subject: [PATCH 1515/9457] ath9k: clean up debugfs print of reset causes Reduce code duplication Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 48 +++++++++++--------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 46f20a309b5f..cf4a98b98cf3 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -852,36 +852,30 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; + static const char * const reset_cause[__RESET_TYPE_MAX] = { + [RESET_TYPE_BB_HANG] = "Baseband Hang", + [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog", + [RESET_TYPE_FATAL_INT] = "Fatal HW Error", + [RESET_TYPE_TX_ERROR] = "TX HW error", + [RESET_TYPE_TX_GTT] = "Transmit timeout", + [RESET_TYPE_TX_HANG] = "TX Path Hang", + [RESET_TYPE_PLL_HANG] = "PLL RX Hang", + [RESET_TYPE_MAC_HANG] = "MAC Hang", + [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", + [RESET_TYPE_MCI] = "MCI Reset", + }; char buf[512]; unsigned int len = 0; + int i; - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Baseband Hang", - sc->debug.stats.reset[RESET_TYPE_BB_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Baseband Watchdog", - sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Fatal HW Error", - sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "TX HW error", - sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "TX Path Hang", - sc->debug.stats.reset[RESET_TYPE_TX_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "PLL RX Hang", - sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "MAC Hang", - sc->debug.stats.reset[RESET_TYPE_MAC_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Stuck Beacon", - sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "MCI Reset", - sc->debug.stats.reset[RESET_TYPE_MCI]); + for (i = 0; i < ARRAY_SIZE(reset_cause); i++) { + if (!reset_cause[i]) + continue; + + len += scnprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", reset_cause[i], + sc->debug.stats.reset[i]); + } if (len > sizeof(buf)) len = sizeof(buf); -- GitLab From 7b8aaead958e38b1eb8944c5f9c90ce066500268 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:30 +0200 Subject: [PATCH 1516/9457] ath9k: restart hardware after noise floor calibration failure When NF calibration fails, the radio often becomes deaf. The usual hardware hang checks do not detect this, so it's better to issue a reset when that happens. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 11 ++++++----- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 11 ++++++----- drivers/net/wireless/ath/ath9k/calib.c | 6 ++++-- drivers/net/wireless/ath/ath9k/calib.h | 2 +- drivers/net/wireless/ath/ath9k/debug.c | 1 + drivers/net/wireless/ath/ath9k/debug.h | 1 + drivers/net/wireless/ath/ath9k/hw-ops.h | 7 +++---- drivers/net/wireless/ath/ath9k/hw.h | 6 ++---- drivers/net/wireless/ath/ath9k/link.c | 12 +++++++++--- 9 files changed, 33 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index cdc74005650c..6bfdebfcdeef 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -657,14 +657,13 @@ static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah) ar9280_hw_olc_temp_compensation(ah); } -static bool ar9002_hw_calibrate(struct ath_hw *ah, - struct ath9k_channel *chan, - u8 rxchainmask, - bool longcal) +static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, + u8 rxchainmask, bool longcal) { bool iscaldone = true; struct ath9k_cal_list *currCal = ah->cal_list_curr; bool nfcal, nfcal_pending = false; + int ret; nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); if (ah->caldata) @@ -698,7 +697,9 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, * NF is slow time-variant, so it is OK to use a * historical value. */ - ath9k_hw_loadnf(ah, ah->curchan); + ret = ath9k_hw_loadnf(ah, ah->curchan); + if (ret < 0) + return ret; } if (longcal) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index ac8301ef5242..06ab71db6e80 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -121,13 +121,12 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah, return iscaldone; } -static bool ar9003_hw_calibrate(struct ath_hw *ah, - struct ath9k_channel *chan, - u8 rxchainmask, - bool longcal) +static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, + u8 rxchainmask, bool longcal) { bool iscaldone = true; struct ath9k_cal_list *currCal = ah->cal_list_curr; + int ret; /* * For given calibration: @@ -163,7 +162,9 @@ static bool ar9003_hw_calibrate(struct ath_hw *ah, * NF is slow time-variant, so it is OK to use a historical * value. */ - ath9k_hw_loadnf(ah, ah->curchan); + ret = ath9k_hw_loadnf(ah, ah->curchan); + if (ret < 0) + return ret; /* start NF calibration, without updating BB NF register */ ath9k_hw_start_nfcal(ah, false); diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 278365b8a895..e200a6e3aca5 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -234,7 +234,7 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update) REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); } -void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) +int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath9k_nfcal_hist *h = NULL; unsigned i, j; @@ -301,7 +301,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ath_dbg(common, ANY, "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", REG_READ(ah, AR_PHY_AGC_CONTROL)); - return; + return -ETIMEDOUT; } /* @@ -322,6 +322,8 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) } } REGWRITE_BUFFER_FLUSH(ah); + + return 0; } diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index b8ed95e9a335..87badf4bb8a4 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -109,7 +109,7 @@ struct ath9k_pacal_info{ bool ath9k_hw_reset_calvalid(struct ath_hw *ah); void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update); -void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); +int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index cf4a98b98cf3..2a2a17df5fb3 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -863,6 +863,7 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, [RESET_TYPE_MAC_HANG] = "MAC Hang", [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", [RESET_TYPE_MCI] = "MCI Reset", + [RESET_TYPE_CALIBRATION] = "Calibration error", }; char buf[512]; unsigned int len = 0; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 53ae15bd0c9d..bd75b1f716db 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -49,6 +49,7 @@ enum ath_reset_type { RESET_TYPE_MAC_HANG, RESET_TYPE_BEACON_STUCK, RESET_TYPE_MCI, + RESET_TYPE_CALIBRATION, __RESET_TYPE_MAX }; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 8e85efeaeffc..88769b64b20b 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -41,10 +41,9 @@ static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set_desc_link(ds, link); } -static inline bool ath9k_hw_calibrate(struct ath_hw *ah, - struct ath9k_channel *chan, - u8 rxchainmask, - bool longcal) +static inline int ath9k_hw_calibrate(struct ath_hw *ah, + struct ath9k_channel *chan, + u8 rxchainmask, bool longcal) { return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal); } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7a81f5b864c7..f204099c38b8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -688,10 +688,8 @@ struct ath_hw_ops { bool power_off); void (*rx_enable)(struct ath_hw *ah); void (*set_desc_link)(void *ds, u32 link); - bool (*calibrate)(struct ath_hw *ah, - struct ath9k_channel *chan, - u8 rxchainmask, - bool longcal); + int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan, + u8 rxchainmask, bool longcal); bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked, u32 *sync_cause_p); void (*set_txdesc)(struct ath_hw *ah, void *ds, diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 2343f56e6498..b829263e3d0a 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -371,9 +371,15 @@ void ath_ani_calibrate(unsigned long data) /* Perform calibration if necessary */ if (longcal || shortcal) { - common->ani.caldone = - ath9k_hw_calibrate(ah, ah->curchan, - ah->rxchainmask, longcal); + int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask, + longcal); + if (ret < 0) { + common->ani.caldone = 0; + ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION); + return; + } + + common->ani.caldone = ret; } ath_dbg(common, ANI, -- GitLab From 6339244b3ba0fe1440c640f6a699b59ae4138269 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:31 +0200 Subject: [PATCH 1517/9457] ath9k_hw: do not run NF and periodic calibration at the same time It can cause inconsistent calibration results or in some cases turn the radio deaf. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 6bfdebfcdeef..07994e322329 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -660,27 +660,26 @@ static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah) static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, bool longcal) { - bool iscaldone = true; struct ath9k_cal_list *currCal = ah->cal_list_curr; - bool nfcal, nfcal_pending = false; + bool nfcal, nfcal_pending = false, percal_pending; int ret; nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); if (ah->caldata) nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags); - if (currCal && !nfcal && - (currCal->calState == CAL_RUNNING || - currCal->calState == CAL_WAITING)) { - iscaldone = ar9002_hw_per_calibration(ah, chan, - rxchainmask, currCal); - if (iscaldone) { - ah->cal_list_curr = currCal = currCal->calNext; - - if (currCal->calState == CAL_WAITING) { - iscaldone = false; - ath9k_hw_reset_calibration(ah, currCal); - } + percal_pending = (currCal && + (currCal->calState == CAL_RUNNING || + currCal->calState == CAL_WAITING)); + + if (percal_pending && !nfcal) { + if (!ar9002_hw_per_calibration(ah, chan, rxchainmask, currCal)) + return 0; + + ah->cal_list_curr = currCal = currCal->calNext; + if (currCal->calState == CAL_WAITING) { + ath9k_hw_reset_calibration(ah, currCal); + return 0; } } @@ -710,7 +709,7 @@ static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, } } - return iscaldone; + return !percal_pending; } /* Carrier leakage Calibration fix */ -- GitLab From 7b89fccf1547722115538976e0d9b989f5e12e9b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:32 +0200 Subject: [PATCH 1518/9457] ath9k_hw: start initial NF calibration after PA calibration on Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 2 ++ drivers/net/wireless/ath/ath9k/hw.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 07994e322329..42190b67c671 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -856,6 +856,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) /* Do PA Calibration */ ar9002_hw_pa_cal(ah, true); + ath9k_hw_loadnf(ah, chan); + ath9k_hw_start_nfcal(ah, true); if (ah->caldata) set_bit(NFCAL_PENDING, &ah->caldata->cal_flags); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8be4b1453394..85a78176b809 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1953,8 +1953,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_check_bt(ah); - ath9k_hw_loadnf(ah, chan); - ath9k_hw_start_nfcal(ah, true); + if (AR_SREV_9300_20_OR_LATER(ah)) { + ath9k_hw_loadnf(ah, chan); + ath9k_hw_start_nfcal(ah, true); + } if (AR_SREV_9300_20_OR_LATER(ah)) ar9003_hw_bb_watchdog_config(ah); -- GitLab From a59dadbeeaf7d33f2e92dbf5a290965d6df64162 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:33 +0200 Subject: [PATCH 1519/9457] ath9k: add support for endian swap of eeprom from platform data On some devices (especially little-endian ones), the flash EEPROM data has a different endian, which needs to be detected. Add a flag to the platform data to allow overriding that behavior Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_def.c | 31 +++++++-------------- drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 2 ++ include/linux/ath9k_platform.h | 1 + 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 3218ca994746..122b846b8ec0 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) { struct ar5416_eeprom_def *eep = &ah->eeprom.def; struct ath_common *common = ath9k_hw_common(ah); - u16 *eepdata, temp, magic, magic2; + u16 *eepdata, temp, magic; u32 sum = 0, el; bool need_swap = false; int i, addr, size; @@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) return false; } - if (!ath9k_hw_use_flash(ah)) { - ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); - - if (magic != AR5416_EEPROM_MAGIC) { - magic2 = swab16(magic); - - if (magic2 == AR5416_EEPROM_MAGIC) { - size = sizeof(struct ar5416_eeprom_def); - need_swap = true; - eepdata = (u16 *) (&ah->eeprom); + if (swab16(magic) == AR5416_EEPROM_MAGIC && + !(ah->ah_flags & AH_NO_EEP_SWAP)) { + size = sizeof(struct ar5416_eeprom_def); + need_swap = true; + eepdata = (u16 *) (&ah->eeprom); - for (addr = 0; addr < size / sizeof(u16); addr++) { - temp = swab16(*eepdata); - *eepdata = temp; - eepdata++; - } - } else { - ath_err(common, - "Invalid EEPROM Magic. Endianness mismatch.\n"); - return -EINVAL; - } + for (addr = 0; addr < size / sizeof(u16); addr++) { + temp = swab16(*eepdata); + *eepdata = temp; + eepdata++; } } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f204099c38b8..c6dba9b4afdf 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -731,6 +731,7 @@ enum ath_cal_list { #define AH_USE_EEPROM 0x1 #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ #define AH_FASTCC 0x4 +#define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */ struct ath_hw { struct ath_ops reg_ops; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 57a17601b0b6..5d9c711b6aa0 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -531,6 +531,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ah->is_clk_25mhz = pdata->is_clk_25mhz; ah->get_mac_revision = pdata->get_mac_revision; ah->external_reset = pdata->external_reset; + if (!pdata->endian_check) + ah->ah_flags |= AH_NO_EEP_SWAP; } common->ops = &ah->reg_ops; diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index a495a959e8a7..43501657bce9 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -31,6 +31,7 @@ struct ath9k_platform_data { u32 gpio_mask; u32 gpio_val; + bool endian_check; bool is_clk_25mhz; bool tx_gain_buffalo; -- GitLab From 3468968ef766d7bb4ab29c0ef7ebd169a4ac2e96 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:34 +0200 Subject: [PATCH 1520/9457] ath9k: allow disabling bands via platform data Some devices have multiple bands enables in the EEPROM data, even though they are only calibrated for one. Allow platform data to disable unsupported bands. Signed-off-by: Gabor Juhos Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 24 ++++++++++++++++-------- drivers/net/wireless/ath/ath9k/hw.h | 2 ++ drivers/net/wireless/ath/ath9k/init.c | 2 ++ include/linux/ath9k_platform.h | 2 ++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 85a78176b809..47f410ed7cd4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2344,17 +2344,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) } eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); - if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) { - ath_err(common, - "no band has been marked as supported in EEPROM\n"); - return -EINVAL; + + if (eeval & AR5416_OPFLAGS_11A) { + if (ah->disable_5ghz) + ath_warn(common, "disabling 5GHz band\n"); + else + pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; } - if (eeval & AR5416_OPFLAGS_11A) - pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; + if (eeval & AR5416_OPFLAGS_11G) { + if (ah->disable_2ghz) + ath_warn(common, "disabling 2GHz band\n"); + else + pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; + } - if (eeval & AR5416_OPFLAGS_11G) - pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; + if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) { + ath_err(common, "both bands are disabled\n"); + return -EINVAL; + } if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c6dba9b4afdf..e49721e85f6a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -930,6 +930,8 @@ struct ath_hw { bool is_clk_25mhz; int (*get_mac_revision)(void); int (*external_reset)(void); + bool disable_2ghz; + bool disable_5ghz; const struct firmware *eeprom_blob; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5d9c711b6aa0..2294109f79e9 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -531,6 +531,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ah->is_clk_25mhz = pdata->is_clk_25mhz; ah->get_mac_revision = pdata->get_mac_revision; ah->external_reset = pdata->external_reset; + ah->disable_2ghz = pdata->disable_2ghz; + ah->disable_5ghz = pdata->disable_5ghz; if (!pdata->endian_check) ah->ah_flags |= AH_NO_EEP_SWAP; } diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index 43501657bce9..33eb274cd0e6 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -34,6 +34,8 @@ struct ath9k_platform_data { bool endian_check; bool is_clk_25mhz; bool tx_gain_buffalo; + bool disable_2ghz; + bool disable_5ghz; int (*get_mac_revision)(void); int (*external_reset)(void); -- GitLab From 5ca06ebe75d933d65722bdb2f064c26a2b087d95 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Oct 2014 17:19:35 +0200 Subject: [PATCH 1521/9457] ath9k: use a random MAC address if the EEPROM address is invalid Based on OpenWrt patch by Gabor Juhos Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 47f410ed7cd4..ee9fb52cec62 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "hw.h" @@ -446,8 +447,16 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) common->macaddr[2 * i] = eeval >> 8; common->macaddr[2 * i + 1] = eeval & 0xff; } - if (sum == 0 || sum == 0xffff * 3) - return -EADDRNOTAVAIL; + if (!is_valid_ether_addr(common->macaddr)) { + ath_err(common, + "eeprom contains invalid mac address: %pM\n", + common->macaddr); + + random_ether_addr(common->macaddr); + ath_err(common, + "random mac address will be used: %pM\n", + common->macaddr); + } return 0; } -- GitLab From 6b436d338177729ae5c5a58e0acc5f35df603f82 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 19:03:22 +0100 Subject: [PATCH 1522/9457] ipv4: remove set but unused variable sha unsigned char *sha (source) was already in original git version but was never used. Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 648fa1490ea7..a896da50f398 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -498,7 +498,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt struct arphdr *rarp; unsigned char *rarp_ptr; __be32 sip, tip; - unsigned char *sha, *tha; /* s for "source", t for "target" */ + unsigned char *tha; /* t for "target" */ struct ic_device *d; if (!net_eq(dev_net(dev), &init_net)) @@ -549,7 +549,6 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt goto drop_unlock; /* should never happen */ /* Extract variable-width fields */ - sha = rarp_ptr; rarp_ptr += dev->addr_len; memcpy(&sip, rarp_ptr, 4); rarp_ptr += 4; -- GitLab From 9451a304ceeb96c45f91f88f2caa7364f5cee087 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 19:11:56 +0100 Subject: [PATCH 1523/9457] ipv6: replace min/casting by min_t Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 725c763270a0..50b95b2db87c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2315,8 +2315,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) else stored_lft = 0; if (!update_lft && !create && stored_lft) { - const u32 minimum_lft = min( - stored_lft, (u32)MIN_VALID_LIFETIME); + const u32 minimum_lft = min_t(u32, + stored_lft, MIN_VALID_LIFETIME); valid_lft = max(valid_lft, minimum_lft); /* RFC4862 Section 5.5.3e: -- GitLab From ce256981e5f1be1f0aa6b4b8b16e0c2918468457 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 19:12:58 +0100 Subject: [PATCH 1524/9457] ipv6: include linux/uaccess.h instead of asm/uaccess.h Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv6/exthdrs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index bfde361b6134..601d896f22d0 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -47,7 +47,7 @@ #include #endif -#include +#include /* * Parsing tlv encoded headers. -- GitLab From 5e96d788d93b90e6e1769fb9376ee28bcdc1a041 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 20:00:41 +0100 Subject: [PATCH 1525/9457] ipx: move extern sysctl_ipx_pprop_broadcasting to header file include ipx.h from sysctl_net_ipx.c Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- include/net/ipx.h | 3 +++ net/ipx/sysctl_net_ipx.c | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/net/ipx.h b/include/net/ipx.h index 0143180fecc9..320f47b64a7a 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -42,6 +42,9 @@ struct ipxhdr { struct ipx_address ipx_source __packed; }; +/* From af_ipx.c */ +extern int sysctl_ipx_pprop_broadcasting; + static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb) { return (struct ipxhdr *)skb_transport_header(skb); diff --git a/net/ipx/sysctl_net_ipx.c b/net/ipx/sysctl_net_ipx.c index ad7c03dedaab..0dafcc561ed6 100644 --- a/net/ipx/sysctl_net_ipx.c +++ b/net/ipx/sysctl_net_ipx.c @@ -9,14 +9,12 @@ #include #include #include +#include #ifndef CONFIG_SYSCTL #error This file should not be compiled without CONFIG_SYSCTL defined #endif -/* From af_ipx.c */ -extern int sysctl_ipx_pprop_broadcasting; - static struct ctl_table ipx_table[] = { { .procname = "ipx_pprop_broadcasting", -- GitLab From e0f36310f793333d667334bb580c0de8c943bae2 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 20:55:08 +0100 Subject: [PATCH 1526/9457] ipx: remove unnecessary casting on ntohl use %08X instead of %08lX and remove casting. Suggested-by: Joe Perches Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipx/ipx_proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index e15c16a517e7..8391191d3d9c 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c @@ -89,8 +89,8 @@ static int ipx_seq_route_show(struct seq_file *seq, void *v) seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net)); if (rt->ir_routed) - seq_printf(seq, "%08lX %02X%02X%02X%02X%02X%02X\n", - (long unsigned int)ntohl(rt->ir_intrfc->if_netnum), + seq_printf(seq, "%08X %02X%02X%02X%02X%02X%02X\n", + ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); -- GitLab From b8901ac319768cdd3afa060787503e0c405f9607 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 27 Oct 2014 21:12:08 +0100 Subject: [PATCH 1527/9457] ipx: remove __inline__ in c file on static Let compiler decide what to do with static void __ipxitf_put() Suggested-by: David S. Miller Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipx/af_ipx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 91729b807c7d..313ef4644069 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -306,7 +306,7 @@ void ipxitf_down(struct ipx_interface *intrfc) spin_unlock_bh(&ipx_interfaces_lock); } -static __inline__ void __ipxitf_put(struct ipx_interface *intrfc) +static void __ipxitf_put(struct ipx_interface *intrfc) { if (atomic_dec_and_test(&intrfc->refcnt)) __ipxitf_down(intrfc); -- GitLab From 8b13eddfdf04cbfa561725cfc42d6868fe896f56 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Thu, 16 Oct 2014 12:23:29 +0200 Subject: [PATCH 1528/9457] netfilter: refactor NAT redirect IPv4 to use it from nf_tables This patch refactors the IPv4 code so it can be usable both from xt and nf_tables. A similar patch follows-up to handle IPv6. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/ipv4/nf_nat_redirect.h | 9 +++ net/ipv4/netfilter/Kconfig | 6 ++ net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/nf_nat_redirect_ipv4.c | 82 ++++++++++++++++++++ net/netfilter/Kconfig | 1 + net/netfilter/xt_REDIRECT.c | 44 +---------- 6 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 include/net/netfilter/ipv4/nf_nat_redirect.h create mode 100644 net/ipv4/netfilter/nf_nat_redirect_ipv4.c diff --git a/include/net/netfilter/ipv4/nf_nat_redirect.h b/include/net/netfilter/ipv4/nf_nat_redirect.h new file mode 100644 index 000000000000..19e1df3a0a4d --- /dev/null +++ b/include/net/netfilter/ipv4/nf_nat_redirect.h @@ -0,0 +1,9 @@ +#ifndef _NF_NAT_REDIRECT_IPV4_H_ +#define _NF_NAT_REDIRECT_IPV4_H_ + +unsigned int +nf_nat_redirect_ipv4(struct sk_buff *skb, + const struct nf_nat_ipv4_multi_range_compat *mr, + unsigned int hooknum); + +#endif /* _NF_NAT_REDIRECT_IPV4_H_ */ diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 4c019d5c3f57..a300e2c32b26 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -104,6 +104,12 @@ config NF_NAT_MASQUERADE_IPV4 This is the kernel functionality to provide NAT in the masquerade flavour (automatic source address selection). +config NF_NAT_REDIRECT_IPV4 + tristate "IPv4 redirect support" + help + This is the kernel functionality to provide NAT in the redirect + flavour (redirect packets to local machine). + config NFT_MASQ_IPV4 tristate "IPv4 masquerading support for nf_tables" depends on NF_TABLES_IPV4 diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index f4cef5af0969..34e436c92015 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o +obj-$(CONFIG_NF_NAT_REDIRECT_IPV4) += nf_nat_redirect_ipv4.o # NAT protocols (nf_nat) obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o diff --git a/net/ipv4/netfilter/nf_nat_redirect_ipv4.c b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c new file mode 100644 index 000000000000..a220552fc532 --- /dev/null +++ b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c @@ -0,0 +1,82 @@ +/* + * (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2006 Netfilter Core Team + * Copyright (c) 2011 Patrick McHardy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 + * NAT funded by Astaro. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned int +nf_nat_redirect_ipv4(struct sk_buff *skb, + const struct nf_nat_ipv4_multi_range_compat *mr, + unsigned int hooknum) +{ + struct nf_conn *ct; + enum ip_conntrack_info ctinfo; + __be32 newdst; + struct nf_nat_range newrange; + + NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || + hooknum == NF_INET_LOCAL_OUT); + + ct = nf_ct_get(skb, &ctinfo); + NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); + + /* Local packets: make them go to loopback */ + if (hooknum == NF_INET_LOCAL_OUT) { + newdst = htonl(0x7F000001); + } else { + struct in_device *indev; + struct in_ifaddr *ifa; + + newdst = 0; + + rcu_read_lock(); + indev = __in_dev_get_rcu(skb->dev); + if (indev != NULL) { + ifa = indev->ifa_list; + newdst = ifa->ifa_local; + } + rcu_read_unlock(); + + if (!newdst) + return NF_DROP; + } + + /* Transfer from original range. */ + memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); + memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); + newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS; + newrange.min_addr.ip = newdst; + newrange.max_addr.ip = newdst; + newrange.min_proto = mr->range[0].min; + newrange.max_proto = mr->range[0].max; + + /* Hand modified range to generic setup. */ + return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); +} +EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Patrick McHardy "); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index ae5096ab65eb..a0716a3f08b0 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -835,6 +835,7 @@ config NETFILTER_XT_TARGET_RATEEST config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT + select NF_NAT_REDIRECT_IPV4 ---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets to diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c index 22a10309297c..b4ffac5fe8e9 100644 --- a/net/netfilter/xt_REDIRECT.c +++ b/net/netfilter/xt_REDIRECT.c @@ -26,6 +26,7 @@ #include #include #include +#include static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; @@ -98,48 +99,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par) static unsigned int redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) { - struct nf_conn *ct; - enum ip_conntrack_info ctinfo; - __be32 newdst; - const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; - struct nf_nat_range newrange; - - NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || - par->hooknum == NF_INET_LOCAL_OUT); - - ct = nf_ct_get(skb, &ctinfo); - NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); - - /* Local packets: make them go to loopback */ - if (par->hooknum == NF_INET_LOCAL_OUT) - newdst = htonl(0x7F000001); - else { - struct in_device *indev; - struct in_ifaddr *ifa; - - newdst = 0; - - rcu_read_lock(); - indev = __in_dev_get_rcu(skb->dev); - if (indev && (ifa = indev->ifa_list)) - newdst = ifa->ifa_local; - rcu_read_unlock(); - - if (!newdst) - return NF_DROP; - } - - /* Transfer from original range. */ - memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); - memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); - newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS; - newrange.min_addr.ip = newdst; - newrange.max_addr.ip = newdst; - newrange.min_proto = mr->range[0].min; - newrange.max_proto = mr->range[0].max; - - /* Hand modified range to generic setup. */ - return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); + return nf_nat_redirect_ipv4(skb, par->targinfo, par->hooknum); } static struct xt_target redirect_tg_reg[] __read_mostly = { -- GitLab From 9de920eddb74bf67f1d6af603acc5ed05dcd35e9 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Fri, 17 Oct 2014 12:37:52 +0200 Subject: [PATCH 1529/9457] netfilter: refactor NAT redirect IPv6 code to use it from nf_tables This patch refactors the IPv6 code so it can be usable both from xt and nf_tables. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/ipv6/nf_nat_redirect.h | 8 +++ net/ipv6/netfilter/Kconfig | 6 ++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/nf_nat_redirect_ipv6.c | 75 ++++++++++++++++++++ net/netfilter/Kconfig | 1 + net/netfilter/xt_REDIRECT.c | 40 +---------- 6 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 include/net/netfilter/ipv6/nf_nat_redirect.h create mode 100644 net/ipv6/netfilter/nf_nat_redirect_ipv6.c diff --git a/include/net/netfilter/ipv6/nf_nat_redirect.h b/include/net/netfilter/ipv6/nf_nat_redirect.h new file mode 100644 index 000000000000..1ebdffc461cc --- /dev/null +++ b/include/net/netfilter/ipv6/nf_nat_redirect.h @@ -0,0 +1,8 @@ +#ifndef _NF_NAT_REDIRECT_IPV6_H_ +#define _NF_NAT_REDIRECT_IPV6_H_ + +unsigned int +nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range, + unsigned int hooknum); + +#endif /* _NF_NAT_REDIRECT_IPV6_H_ */ diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 6af874fc187f..462eebbf4377 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -82,6 +82,12 @@ config NF_NAT_MASQUERADE_IPV6 This is the kernel functionality to provide NAT in the masquerade flavour (automatic source address selection) for IPv6. +config NF_NAT_REDIRECT_IPV6 + tristate "IPv6 redirect support" + help + This is the kernel functionality to provide NAT in the redirect + flavour (redirect packet to local machine) for IPv6. + config NFT_MASQ_IPV6 tristate "IPv6 masquerade support for nf_tables" depends on NF_TABLES_IPV6 diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index fbb25f01143c..6c2baab10f21 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o obj-$(CONFIG_NF_NAT_MASQUERADE_IPV6) += nf_nat_masquerade_ipv6.o +obj-$(CONFIG_NF_NAT_REDIRECT_IPV6) += nf_nat_redirect_ipv6.o # defrag nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o diff --git a/net/ipv6/netfilter/nf_nat_redirect_ipv6.c b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c new file mode 100644 index 000000000000..ea1308aeb048 --- /dev/null +++ b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c @@ -0,0 +1,75 @@ +/* + * (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2006 Netfilter Core Team + * Copyright (c) 2011 Patrick McHardy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 + * NAT funded by Astaro. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; + +unsigned int +nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range, + unsigned int hooknum) +{ + struct nf_nat_range newrange; + struct in6_addr newdst; + enum ip_conntrack_info ctinfo; + struct nf_conn *ct; + + ct = nf_ct_get(skb, &ctinfo); + if (hooknum == NF_INET_LOCAL_OUT) { + newdst = loopback_addr; + } else { + struct inet6_dev *idev; + struct inet6_ifaddr *ifa; + bool addr = false; + + rcu_read_lock(); + idev = __in6_dev_get(skb->dev); + if (idev != NULL) { + list_for_each_entry(ifa, &idev->addr_list, if_list) { + newdst = ifa->addr; + addr = true; + break; + } + } + rcu_read_unlock(); + + if (!addr) + return NF_DROP; + } + + newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; + newrange.min_addr.in6 = newdst; + newrange.max_addr.in6 = newdst; + newrange.min_proto = range->min_proto; + newrange.max_proto = range->max_proto; + + return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); +} +EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Patrick McHardy "); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index a0716a3f08b0..49deb4edbac6 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -836,6 +836,7 @@ config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT select NF_NAT_REDIRECT_IPV4 + select NF_NAT_REDIRECT_IPV6 if IP6_NF_IPTABLES ---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets to diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c index b4ffac5fe8e9..b6ec67efd900 100644 --- a/net/netfilter/xt_REDIRECT.c +++ b/net/netfilter/xt_REDIRECT.c @@ -27,48 +27,12 @@ #include #include #include - -static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; +#include static unsigned int redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par) { - const struct nf_nat_range *range = par->targinfo; - struct nf_nat_range newrange; - struct in6_addr newdst; - enum ip_conntrack_info ctinfo; - struct nf_conn *ct; - - ct = nf_ct_get(skb, &ctinfo); - if (par->hooknum == NF_INET_LOCAL_OUT) - newdst = loopback_addr; - else { - struct inet6_dev *idev; - struct inet6_ifaddr *ifa; - bool addr = false; - - rcu_read_lock(); - idev = __in6_dev_get(skb->dev); - if (idev != NULL) { - list_for_each_entry(ifa, &idev->addr_list, if_list) { - newdst = ifa->addr; - addr = true; - break; - } - } - rcu_read_unlock(); - - if (!addr) - return NF_DROP; - } - - newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; - newrange.min_addr.in6 = newdst; - newrange.max_addr.in6 = newdst; - newrange.min_proto = range->min_proto; - newrange.max_proto = range->max_proto; - - return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); + return nf_nat_redirect_ipv6(skb, par->targinfo, par->hooknum); } static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) -- GitLab From e9105f1bead4ec3f64904564c7c6268185d6b363 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Fri, 17 Oct 2014 12:39:09 +0200 Subject: [PATCH 1530/9457] netfilter: nf_tables: add new expression nft_redir This new expression provides NAT in the redirect flavour, which is to redirect packets to local machine. Signed-off-by: Arturo Borrero Gonzalez Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nft_redir.h | 21 +++++ include/uapi/linux/netfilter/nf_tables.h | 16 ++++ net/ipv4/netfilter/Kconfig | 9 +++ net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/nft_redir_ipv4.c | 77 +++++++++++++++++++ net/ipv6/netfilter/Kconfig | 9 +++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/nft_redir_ipv6.c | 77 +++++++++++++++++++ net/netfilter/Kconfig | 9 +++ net/netfilter/Makefile | 1 + net/netfilter/nft_redir.c | 98 ++++++++++++++++++++++++ 11 files changed, 319 insertions(+) create mode 100644 include/net/netfilter/nft_redir.h create mode 100644 net/ipv4/netfilter/nft_redir_ipv4.c create mode 100644 net/ipv6/netfilter/nft_redir_ipv6.c create mode 100644 net/netfilter/nft_redir.c diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h new file mode 100644 index 000000000000..a2d67546afab --- /dev/null +++ b/include/net/netfilter/nft_redir.h @@ -0,0 +1,21 @@ +#ifndef _NFT_REDIR_H_ +#define _NFT_REDIR_H_ + +struct nft_redir { + enum nft_registers sreg_proto_min:8; + enum nft_registers sreg_proto_max:8; + u16 flags; +}; + +extern const struct nla_policy nft_redir_policy[]; + +int nft_redir_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]); + +int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr); + +int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, + const struct nft_data **data); + +#endif /* _NFT_REDIR_H_ */ diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index f31fe7b660a5..16f62a5cf04d 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -837,6 +837,22 @@ enum nft_masq_attributes { }; #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) +/** + * enum nft_redir_attributes - nf_tables redirect expression netlink attributes + * + * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) + * @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) + * @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) + */ +enum nft_redir_attributes { + NFTA_REDIR_UNSPEC, + NFTA_REDIR_REG_PROTO_MIN, + NFTA_REDIR_REG_PROTO_MAX, + NFTA_REDIR_FLAGS, + __NFTA_REDIR_MAX +}; +#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1) + /** * enum nft_gen_attributes - nf_tables ruleset generation attributes * diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index a300e2c32b26..8358b2da1549 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -119,6 +119,15 @@ config NFT_MASQ_IPV4 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV4 + tristate "IPv4 redirect support for nf_tables" + depends on NF_TABLES_IPV4 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV4 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + config NF_NAT_SNMP_BASIC tristate "Basic SNMP-ALG support" depends on NF_CONNTRACK_SNMP diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 34e436c92015..902bcd1597bb 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o +obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o # generic IP tables diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c new file mode 100644 index 000000000000..643c5967aa27 --- /dev/null +++ b/net/ipv4/netfilter/nft_redir_ipv4.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014 Arturo Borrero Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void nft_redir_ipv4_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt) +{ + struct nft_redir *priv = nft_expr_priv(expr); + struct nf_nat_ipv4_multi_range_compat mr; + unsigned int verdict; + + memset(&mr, 0, sizeof(mr)); + if (priv->sreg_proto_min) { + mr.range[0].min.all = (__force __be16) + data[priv->sreg_proto_min].data[0]; + mr.range[0].max.all = (__force __be16) + data[priv->sreg_proto_max].data[0]; + mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; + } + + mr.range[0].flags |= priv->flags; + + verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum); + data[NFT_REG_VERDICT].verdict = verdict; +} + +static struct nft_expr_type nft_redir_ipv4_type; +static const struct nft_expr_ops nft_redir_ipv4_ops = { + .type = &nft_redir_ipv4_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), + .eval = nft_redir_ipv4_eval, + .init = nft_redir_init, + .dump = nft_redir_dump, + .validate = nft_redir_validate, +}; + +static struct nft_expr_type nft_redir_ipv4_type __read_mostly = { + .family = NFPROTO_IPV4, + .name = "redir", + .ops = &nft_redir_ipv4_ops, + .policy = nft_redir_policy, + .maxattr = NFTA_REDIR_MAX, + .owner = THIS_MODULE, +}; + +static int __init nft_redir_ipv4_module_init(void) +{ + return nft_register_expr(&nft_redir_ipv4_type); +} + +static void __exit nft_redir_ipv4_module_exit(void) +{ + nft_unregister_expr(&nft_redir_ipv4_type); +} + +module_init(nft_redir_ipv4_module_init); +module_exit(nft_redir_ipv4_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arturo Borrero Gonzalez "); +MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir"); diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 462eebbf4377..0dbe5c7953e5 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -97,6 +97,15 @@ config NFT_MASQ_IPV6 This is the expression that provides IPv4 masquerading support for nf_tables. +config NFT_REDIR_IPV6 + tristate "IPv6 redirect support for nf_tables" + depends on NF_TABLES_IPV6 + depends on NFT_REDIR + select NF_NAT_REDIRECT_IPV6 + help + This is the expression that provides IPv4 redirect support for + nf_tables. + endif # NF_NAT_IPV6 config IP6_NF_IPTABLES diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index 6c2baab10f21..d2ac9f5f212c 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o +obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o # matches obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c new file mode 100644 index 000000000000..83420eeaad1c --- /dev/null +++ b/net/ipv6/netfilter/nft_redir_ipv6.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014 Arturo Borrero Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void nft_redir_ipv6_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt) +{ + struct nft_redir *priv = nft_expr_priv(expr); + struct nf_nat_range range; + unsigned int verdict; + + memset(&range, 0, sizeof(range)); + if (priv->sreg_proto_min) { + range.min_proto.all = (__force __be16) + data[priv->sreg_proto_min].data[0]; + range.max_proto.all = (__force __be16) + data[priv->sreg_proto_max].data[0]; + range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; + } + + range.flags |= priv->flags; + + verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum); + data[NFT_REG_VERDICT].verdict = verdict; +} + +static struct nft_expr_type nft_redir_ipv6_type; +static const struct nft_expr_ops nft_redir_ipv6_ops = { + .type = &nft_redir_ipv6_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), + .eval = nft_redir_ipv6_eval, + .init = nft_redir_init, + .dump = nft_redir_dump, + .validate = nft_redir_validate, +}; + +static struct nft_expr_type nft_redir_ipv6_type __read_mostly = { + .family = NFPROTO_IPV6, + .name = "redir", + .ops = &nft_redir_ipv6_ops, + .policy = nft_redir_policy, + .maxattr = NFTA_REDIR_MAX, + .owner = THIS_MODULE, +}; + +static int __init nft_redir_ipv6_module_init(void) +{ + return nft_register_expr(&nft_redir_ipv6_type); +} + +static void __exit nft_redir_ipv6_module_exit(void) +{ + nft_unregister_expr(&nft_redir_ipv6_type); +} + +module_init(nft_redir_ipv6_module_init); +module_exit(nft_redir_ipv6_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arturo Borrero Gonzalez "); +MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir"); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 49deb4edbac6..373486ae4159 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -505,6 +505,15 @@ config NFT_MASQ This option adds the "masquerade" expression that you can use to perform NAT in the masquerade flavour. +config NFT_REDIR + depends on NF_TABLES + depends on NF_CONNTRACK + depends on NF_NAT + tristate "Netfilter nf_tables redirect support" + help + This options adds the "redirect" expression that you can use + to perform NAT in the redirect flavour. + config NFT_NAT depends on NF_TABLES depends on NF_CONNTRACK diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index a9571be3f791..f3eb4680f2ec 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_NFT_HASH) += nft_hash.o obj-$(CONFIG_NFT_COUNTER) += nft_counter.o obj-$(CONFIG_NFT_LOG) += nft_log.o obj-$(CONFIG_NFT_MASQ) += nft_masq.o +obj-$(CONFIG_NFT_REDIR) += nft_redir.o # generic X tables obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c new file mode 100644 index 000000000000..e27b4e35718a --- /dev/null +++ b/net/netfilter/nft_redir.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 Arturo Borrero Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = { + [NFTA_REDIR_REG_PROTO_MIN] = { .type = NLA_U32 }, + [NFTA_REDIR_REG_PROTO_MAX] = { .type = NLA_U32 }, + [NFTA_REDIR_FLAGS] = { .type = NLA_U32 }, +}; +EXPORT_SYMBOL_GPL(nft_redir_policy); + +int nft_redir_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) +{ + struct nft_redir *priv = nft_expr_priv(expr); + u32 nla_be32; + int err; + + err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); + if (err < 0) + return err; + + if (tb[NFTA_REDIR_REG_PROTO_MIN]) { + nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]); + priv->sreg_proto_min = ntohl(nla_be32); + err = nft_validate_input_register(priv->sreg_proto_min); + if (err < 0) + return err; + + if (tb[NFTA_REDIR_REG_PROTO_MAX]) { + nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]); + priv->sreg_proto_max = ntohl(nla_be32); + err = nft_validate_input_register(priv->sreg_proto_max); + if (err < 0) + return err; + } else { + priv->sreg_proto_max = priv->sreg_proto_min; + } + } + + if (tb[NFTA_REDIR_FLAGS]) { + priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS])); + if (priv->flags & ~NF_NAT_RANGE_MASK) + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(nft_redir_init); + +int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) +{ + const struct nft_redir *priv = nft_expr_priv(expr); + + if (priv->sreg_proto_min) { + if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN, + htonl(priv->sreg_proto_min))) + goto nla_put_failure; + if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX, + htonl(priv->sreg_proto_max))) + goto nla_put_failure; + } + + if (priv->flags != 0 && + nla_put_be32(skb, NFTA_REDIR_FLAGS, htonl(priv->flags))) + goto nla_put_failure; + + return 0; + +nla_put_failure: + return -1; +} +EXPORT_SYMBOL_GPL(nft_redir_dump); + +int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, + const struct nft_data **data) +{ + return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); +} +EXPORT_SYMBOL_GPL(nft_redir_validate); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arturo Borrero Gonzalez "); -- GitLab From 958501163ddd6ea22a98f94fa0e7ce6d4734e5c4 Mon Sep 17 00:00:00 2001 From: Kyeyoon Park Date: Thu, 23 Oct 2014 14:49:17 -0700 Subject: [PATCH 1531/9457] bridge: Add support for IEEE 802.11 Proxy ARP This feature is defined in IEEE Std 802.11-2012, 10.23.13. It allows the AP devices to keep track of the hardware-address-to-IP-address mapping of the mobile devices within the WLAN network. The AP will learn this mapping via observing DHCP, ARP, and NS/NA frames. When a request for such information is made (i.e. ARP request, Neighbor Solicitation), the AP will respond on behalf of the associated mobile device. In the process of doing so, the AP will drop the multicast request frame that was intended to go out to the wireless medium. It was recommended at the LKS workshop to do this implementation in the bridge layer. vxlan.c is already doing something very similar. The DHCP snooping code will be added to the userspace application (hostapd) per the recommendation. This RFC commit is only for IPv4. A similar approach in the bridge layer will be taken for IPv6 as well. Signed-off-by: Kyeyoon Park Signed-off-by: David S. Miller --- include/uapi/linux/if_link.h | 1 + net/bridge/br_forward.c | 5 +++ net/bridge/br_input.c | 60 ++++++++++++++++++++++++++++++++++++ net/bridge/br_netlink.c | 4 ++- net/bridge/br_private.h | 1 + net/bridge/br_sysfs_if.c | 2 ++ 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 0bdb77e16875..7072d8325016 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -243,6 +243,7 @@ enum { IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ IFLA_BRPORT_LEARNING, /* mac learning */ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ + IFLA_BRPORT_PROXYARP, /* proxy ARP */ __IFLA_BRPORT_MAX }; #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 992ec49a96aa..1510b54e6a2e 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -183,6 +183,11 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb, /* Do not flood unicast traffic to ports that turn it off */ if (unicast && !(p->flags & BR_FLOOD)) continue; + + /* Do not flood to ports that enable proxy ARP */ + if (p->flags & BR_PROXYARP) + continue; + prev = maybe_deliver(prev, p, skb, __packet_hook); if (IS_ERR(prev)) goto out; diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 6fd5522df696..1f1de715197c 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include "br_private.h" @@ -57,6 +59,60 @@ static int br_pass_frame_up(struct sk_buff *skb) netif_receive_skb); } +static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, + u16 vid) +{ + struct net_device *dev = br->dev; + struct neighbour *n; + struct arphdr *parp; + u8 *arpptr, *sha; + __be32 sip, tip; + + if (dev->flags & IFF_NOARP) + return; + + if (!pskb_may_pull(skb, arp_hdr_len(dev))) { + dev->stats.tx_dropped++; + return; + } + parp = arp_hdr(skb); + + if (parp->ar_pro != htons(ETH_P_IP) || + parp->ar_op != htons(ARPOP_REQUEST) || + parp->ar_hln != dev->addr_len || + parp->ar_pln != 4) + return; + + arpptr = (u8 *)parp + sizeof(struct arphdr); + sha = arpptr; + arpptr += dev->addr_len; /* sha */ + memcpy(&sip, arpptr, sizeof(sip)); + arpptr += sizeof(sip); + arpptr += dev->addr_len; /* tha */ + memcpy(&tip, arpptr, sizeof(tip)); + + if (ipv4_is_loopback(tip) || + ipv4_is_multicast(tip)) + return; + + n = neigh_lookup(&arp_tbl, &tip, dev); + if (n) { + struct net_bridge_fdb_entry *f; + + if (!(n->nud_state & NUD_VALID)) { + neigh_release(n); + return; + } + + f = __br_fdb_get(br, n->ha, vid); + if (f) + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip, + sha, n->ha, sha); + + neigh_release(n); + } +} + /* note: already called with rcu_read_lock */ int br_handle_frame_finish(struct sk_buff *skb) { @@ -98,6 +154,10 @@ int br_handle_frame_finish(struct sk_buff *skb) dst = NULL; if (is_broadcast_ether_addr(dest)) { + if (p->flags & BR_PROXYARP && + skb->protocol == htons(ETH_P_ARP)) + br_do_proxy_arp(skb, br, vid); + skb2 = skb; unicast = false; } else if (is_multicast_ether_addr(dest)) { diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2ff9706647f2..86c239b06f6e 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -60,7 +60,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, nla_put_u8(skb, IFLA_BRPORT_PROTECT, !!(p->flags & BR_ROOT_BLOCK)) || nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, !!(p->flags & BR_MULTICAST_FAST_LEAVE)) || nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) || - nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, !!(p->flags & BR_FLOOD))) + nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, !!(p->flags & BR_FLOOD)) || + nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP))) return -EMSGSIZE; return 0; @@ -332,6 +333,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK); br_set_port_flag(p, tb, IFLA_BRPORT_LEARNING, BR_LEARNING); br_set_port_flag(p, tb, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD); + br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP, BR_PROXYARP); if (tb[IFLA_BRPORT_COST]) { err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST])); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 4d783d071305..8f3f08140258 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -172,6 +172,7 @@ struct net_bridge_port #define BR_FLOOD 0x00000040 #define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING) #define BR_PROMISC 0x00000080 +#define BR_PROXYARP 0x00000100 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING struct bridge_mcast_own_query ip4_own_query; diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index e561cd59b8a6..2de5d91199e8 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -170,6 +170,7 @@ BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD); BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); BRPORT_ATTR_FLAG(learning, BR_LEARNING); BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); +BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); #ifdef CONFIG_BRIDGE_IGMP_SNOOPING static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) @@ -213,6 +214,7 @@ static const struct brport_attribute *brport_attrs[] = { &brport_attr_multicast_router, &brport_attr_multicast_fast_leave, #endif + &brport_attr_proxyarp, NULL }; -- GitLab From 5e9b4dce850d6e3d3dbd1ee7f9466c875c20e487 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 24 Oct 2014 07:42:06 +0530 Subject: [PATCH 1532/9457] ethernet: wiznet: remove unnecessary check devm_ioremap_resource checks platform_get_resource() return value. We can remove the duplicate check here. Signed-off-by: Varka Bhadram Signed-off-by: David S. Miller --- drivers/net/ethernet/wiznet/w5100.c | 6 ++---- drivers/net/ethernet/wiznet/w5300.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c index 0f56b1c0e082..70a930ac4fa9 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -638,14 +638,12 @@ static int w5100_hw_probe(struct platform_device *pdev) } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENXIO; - mem_size = resource_size(mem); - priv->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + mem_size = resource_size(mem); + spin_lock_init(&priv->reg_lock); priv->indirect = mem_size < W5100_BUS_DIRECT_SIZE; if (priv->indirect) { diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c index f961f14a0473..7974b7d90fcc 100644 --- a/drivers/net/ethernet/wiznet/w5300.c +++ b/drivers/net/ethernet/wiznet/w5300.c @@ -558,14 +558,12 @@ static int w5300_hw_probe(struct platform_device *pdev) } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENXIO; - mem_size = resource_size(mem); - priv->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + mem_size = resource_size(mem); + spin_lock_init(&priv->reg_lock); priv->indirect = mem_size < W5300_BUS_DIRECT_SIZE; if (priv->indirect) { -- GitLab From 534249d6e095a607bc8769bdd60941d3887dd386 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 24 Oct 2014 07:42:07 +0530 Subject: [PATCH 1533/9457] ethernet: apm: xgene: remove unnecessary check devm_ioremap_resource checks platform_get_resource() return value. We can remove the duplicate check here. Signed-off-by: Varka Bhadram Signed-off-by: David S. Miller --- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 3c208cc6f6bb..f22659438436 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -761,10 +761,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) ndev = pdata->ndev; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "enet_csr"); - if (!res) { - dev_err(dev, "Resource enet_csr not defined\n"); - return -ENODEV; - } pdata->base_addr = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->base_addr)) { dev_err(dev, "Unable to retrieve ENET Port CSR region\n"); @@ -772,10 +768,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_csr"); - if (!res) { - dev_err(dev, "Resource ring_csr not defined\n"); - return -ENODEV; - } pdata->ring_csr_addr = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->ring_csr_addr)) { dev_err(dev, "Unable to retrieve ENET Ring CSR region\n"); @@ -783,10 +775,6 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_cmd"); - if (!res) { - dev_err(dev, "Resource ring_cmd not defined\n"); - return -ENODEV; - } pdata->ring_cmd_addr = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->ring_cmd_addr)) { dev_err(dev, "Unable to retrieve ENET Ring command region\n"); -- GitLab From 7e5ae24aa009110c7c1340bf682a3e6586de39da Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 24 Oct 2014 07:42:08 +0530 Subject: [PATCH 1534/9457] ethernet: marvell: remove unnecessary check devm_ioremap_resource checks platform_get_resource() return value. We can remove the duplicate check here. Signed-off-by: Varka Bhadram Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/pxa168_eth.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index bee4c369f0fe..21ddecef151e 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1450,16 +1450,14 @@ static int pxa168_eth_probe(struct platform_device *pdev) pep = netdev_priv(dev); pep->dev = dev; pep->clk = clk; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - err = -ENODEV; - goto err_netdev; - } pep->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(pep->base)) { err = -ENOMEM; goto err_netdev; } + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); BUG_ON(!res); dev->irq = res->start; -- GitLab From c960804f536fe810fa7c8c5eb0dffa8c9aa21390 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 24 Oct 2014 07:42:09 +0530 Subject: [PATCH 1535/9457] ethernet: renesas: remove unnecessary check devm_ioremap_resource checks platform_get_resource() return value. We can remove the duplicate check here. Signed-off-by: Varka Bhadram Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 60e9c2cd051e..dbe860650bfe 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2769,10 +2769,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) /* get base addr */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(res == NULL)) { - dev_err(&pdev->dev, "invalid resource\n"); - return -EINVAL; - } ndev = alloc_etherdev(sizeof(struct sh_eth_private)); if (!ndev) @@ -2781,8 +2777,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - /* The sh Ether-specific entries in the device structure. */ - ndev->base_addr = res->start; devno = pdev->id; if (devno < 0) devno = 0; @@ -2806,6 +2800,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) goto out_release; } + ndev->base_addr = res->start; + spin_lock_init(&mdp->lock); mdp->pdev = pdev; -- GitLab From aaa14fe396019adab3877678dd2e3b5a53088be1 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 24 Oct 2014 07:42:10 +0530 Subject: [PATCH 1536/9457] ethernet: samsung: sxgbe: remove unnecessary check devm_ioremap_resource checks platform_get_resource() return value. We can remove the duplicate check here. Signed-off-by: Varka Bhadram Signed-off-by: David S. Miller --- drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index b147d469a799..7fd6e275d1c2 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c @@ -90,9 +90,6 @@ static int sxgbe_platform_probe(struct platform_device *pdev) /* Get memory resource */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - goto err_out; - addr = devm_ioremap_resource(dev, res); if (IS_ERR(addr)) return PTR_ERR(addr); -- GitLab From 4a2019480bc5146eb54fc5f0b2ff57b95629a09a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:41:56 +0200 Subject: [PATCH 1537/9457] ASoC: dapm: Only mark paths dirty when the connection status changed Rework soc_dapm_{mixer,mux}_update_power() to only mark a path dirty if the connect state if the path has actually changed. This avoids unnecessary power state checks for the widgets involved. Also factor out the common code that is involved in this into a helper function. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f03e0cfc65be..116d4436c575 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1925,12 +1925,31 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) #endif +/* + * soc_dapm_connect_path() - Connects or disconnects a path + * @path: The path to update + * @connect: The new connect state of the path. True if the path is connected, + * false if it is disconneted. + * @reason: The reason why the path changed (for debugging only) + */ +static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, + bool connect, const char *reason) +{ + if (path->connect == connect) + return; + + path->connect = connect; + dapm_mark_dirty(path->source, reason); + dapm_mark_dirty(path->sink, reason); +} + /* test and update the power status of a mux widget */ static int soc_dapm_mux_update_power(struct snd_soc_card *card, struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) { struct snd_soc_dapm_path *path; int found = 0; + bool connect; lockdep_assert_held(&card->dapm_mutex); @@ -1941,16 +1960,12 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card, found = 1; /* we now need to match the string in the enum to the path */ - if (!(strcmp(path->name, e->texts[mux]))) { - path->connect = 1; /* new connection */ - dapm_mark_dirty(path->source, "mux connection"); - } else { - if (path->connect) - dapm_mark_dirty(path->source, - "mux disconnection"); - path->connect = 0; /* old connection must be powered down */ - } - dapm_mark_dirty(path->sink, "mux change"); + if (!(strcmp(path->name, e->texts[mux]))) + connect = true; + else + connect = false; + + soc_dapm_connect_path(path, connect, "mux update"); } if (found) @@ -1989,9 +2004,7 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card, /* find dapm widget path assoc with kcontrol */ dapm_kcontrol_for_each_path(path, kcontrol) { found = 1; - path->connect = connect; - dapm_mark_dirty(path->source, "mixer connection"); - dapm_mark_dirty(path->sink, "mixer update"); + soc_dapm_connect_path(path, connect, "mixer update"); } if (found) -- GitLab From 98407efc1384b31cdcb1eeddc74ee35499d3418f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:41:57 +0200 Subject: [PATCH 1538/9457] ASoC: dapm: Do not add un-muxed paths to MUX control Paths that are directly connected to a MUX widget are not affected by changes to the MUX's control. Rather than checking if a path is directly connected each time the MUX is updated do it only once when MUX is created. We can also remove the check for e->texts[mux] != NULL, since if that condition was true the code would have had already crashed much earlier (And generally speaking if a enum's 'texts' entry is NULL it's a bug in the driver). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 116d4436c575..1fed2207b024 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -738,8 +738,10 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) if (ret < 0) return ret; - list_for_each_entry(path, &w->sources, list_sink) - dapm_kcontrol_add_path(w->kcontrols[0], path); + list_for_each_entry(path, &w->sources, list_sink) { + if (path->name) + dapm_kcontrol_add_path(w->kcontrols[0], path); + } return 0; } @@ -1955,9 +1957,6 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card, /* find dapm widget path assoc with kcontrol */ dapm_kcontrol_for_each_path(path, kcontrol) { - if (!path->name || !e->texts[mux]) - continue; - found = 1; /* we now need to match the string in the enum to the path */ if (!(strcmp(path->name, e->texts[mux]))) -- GitLab From 5fe5b767dc6fb3df6fa6eaa8e05b727914f2bb4c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:41:58 +0200 Subject: [PATCH 1539/9457] ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets Controls on a path only have an effect if the sink on the path is either a mixer or mux widget. Currently we sort of silently ignore controls on other paths, but since they don't do anything having them on other paths does not make much sense and it is probably safe to assume that if we see such a path it is a mistake in the driver that registered the path. This patch modifies snd_soc_dapm_add_path() to report an error if a path with and control is encountered where we didn't expect a control. This also allows to simplify the code quite a bit. The patch also moves the connecting of the path lists out of dapm_connect_mux() and dapm_connect_mixer() into snd_soc_dapm_add_path(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 112 ++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 75 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1fed2207b024..c49df10d1c33 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -469,10 +469,9 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, /* connect mux widget to its interconnecting audio paths */ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, - struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, - struct snd_soc_dapm_path *path, const char *control_name, - const struct snd_kcontrol_new *kcontrol) + struct snd_soc_dapm_path *path, const char *control_name) { + const struct snd_kcontrol_new *kcontrol = &path->sink->kcontrol_news[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val, item; int i; @@ -493,9 +492,6 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, for (i = 0; i < e->items; i++) { if (!(strcmp(control_name, e->texts[i]))) { - list_add(&path->list, &dapm->card->paths); - list_add(&path->list_sink, &dest->sources); - list_add(&path->list_source, &src->sinks); path->name = e->texts[i]; if (i == item) path->connect = 1; @@ -509,11 +505,10 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, } /* set up initial codec paths */ -static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, - struct snd_soc_dapm_path *p, int i) +static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i) { struct soc_mixer_control *mc = (struct soc_mixer_control *) - w->kcontrol_news[i].private_value; + p->sink->kcontrol_news[i].private_value; unsigned int reg = mc->reg; unsigned int shift = mc->shift; unsigned int max = mc->max; @@ -522,7 +517,7 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, unsigned int val; if (reg != SND_SOC_NOPM) { - soc_dapm_read(w->dapm, reg, &val); + soc_dapm_read(p->sink->dapm, reg, &val); val = (val >> shift) & mask; if (invert) val = max - val; @@ -534,19 +529,15 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w, /* connect mixer widget to its interconnecting audio paths */ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, - struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name) { int i; /* search for mixer kcontrol */ - for (i = 0; i < dest->num_kcontrols; i++) { - if (!strcmp(control_name, dest->kcontrol_news[i].name)) { - list_add(&path->list, &dapm->card->paths); - list_add(&path->list_sink, &dest->sources); - list_add(&path->list_source, &src->sinks); - path->name = dest->kcontrol_news[i].name; - dapm_set_mixer_path_status(dest, path, i); + for (i = 0; i < path->sink->num_kcontrols; i++) { + if (!strcmp(control_name, path->sink->kcontrol_news[i].name)) { + path->name = path->sink->kcontrol_news[i].name; + dapm_set_mixer_path_status(path, i); return 0; } } @@ -2272,69 +2263,40 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, wsource->ext = 1; } - dapm_mark_dirty(wsource, "Route added"); - dapm_mark_dirty(wsink, "Route added"); - /* connect static paths */ if (control == NULL) { - list_add(&path->list, &dapm->card->paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); path->connect = 1; - return 0; - } - - /* connect dynamic paths */ - switch (wsink->id) { - case snd_soc_dapm_adc: - case snd_soc_dapm_dac: - case snd_soc_dapm_pga: - case snd_soc_dapm_out_drv: - case snd_soc_dapm_input: - case snd_soc_dapm_output: - case snd_soc_dapm_siggen: - case snd_soc_dapm_micbias: - case snd_soc_dapm_vmid: - case snd_soc_dapm_pre: - case snd_soc_dapm_post: - case snd_soc_dapm_supply: - case snd_soc_dapm_regulator_supply: - case snd_soc_dapm_clock_supply: - case snd_soc_dapm_aif_in: - case snd_soc_dapm_aif_out: - case snd_soc_dapm_dai_in: - case snd_soc_dapm_dai_out: - case snd_soc_dapm_dai_link: - case snd_soc_dapm_kcontrol: - list_add(&path->list, &dapm->card->paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); - path->connect = 1; - return 0; - case snd_soc_dapm_mux: - ret = dapm_connect_mux(dapm, wsource, wsink, path, control, - &wsink->kcontrol_news[0]); - if (ret != 0) - goto err; - break; - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: - ret = dapm_connect_mixer(dapm, wsource, wsink, path, control); - if (ret != 0) + } else { + /* connect dynamic paths */ + switch (wsink->id) { + case snd_soc_dapm_mux: + ret = dapm_connect_mux(dapm, path, control); + if (ret != 0) + goto err; + break; + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + case snd_soc_dapm_mixer_named_ctl: + ret = dapm_connect_mixer(dapm, path, control); + if (ret != 0) + goto err; + break; + default: + dev_err(dapm->dev, + "Control not supported for path %s -> [%s] -> %s\n", + wsource->name, control, wsink->name); + ret = -EINVAL; goto err; - break; - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_line: - case snd_soc_dapm_spk: - list_add(&path->list, &dapm->card->paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); - path->connect = 0; - return 0; + } } + list_add(&path->list, &dapm->card->paths); + list_add(&path->list_sink, &wsink->sources); + list_add(&path->list_source, &wsource->sinks); + + dapm_mark_dirty(wsource, "Route added"); + dapm_mark_dirty(wsink, "Route added"); + return 0; err: kfree(path); -- GitLab From 6dd98b0a3e58b7b48a422802b5610b95ef5128eb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:41:59 +0200 Subject: [PATCH 1540/9457] ASoC: dapm: Introduce toplevel widget categories DAPM widgets can be classified into four categories: * supply: Supply widgets do not affect the power state of their non-supply widget neighbors and unlike other widgets a supply widget is not powered up when it is on an active path, but when at least on of its neighbors is powered up. * source: A source is a widget that receives data from outside the DAPM graph or generates data. This can for example be a microphone, the playback DMA or a signal generator. A source widget will be considered powered up if there is an active path to a sink widget. * sink: A sink is a widget that transmits data to somewhere outside of the DAPM graph. This can e.g. be a speaker or the capture DMA. A sink widget will be considered powered up if there is an active path from a source widget. * normal: Normal widgets are widgets not covered by the categories above. A normal widget will be considered powered up if it is on an active path between a source widget and a sink widget. The way the number of input and output paths for a widget is calculated depends on its category. There are a bunch of factors which decide which category a widget is. Currently there is no formal classification of these categories and we calculate the category of the widget based on these factors whenever we want to know it. This is at least once for every widget during each power update sequence. The factors which determine the category of the widgets are mostly static though and if at all change rather seldom. This patch introduces three new per widget flags, one for each of non-normal widgets categories. Instead of re-computing the category each time we want to know them the flags will be checked. For the majority of widgets the category is solely determined by the widget id, which means it never changes and only has to be set once when the widget is created. The only widgets with dynamic categories are: snd_soc_dapm_dai_out: Is considered a sink iff the capture stream is active, otherwise normal. snd_soc_dapm_dai_in: Is considered a source iff the playback stream is active, otherwise normal. snd_soc_dapm_input: Is considered a sink iff it has no outgoing paths, otherwise normal. snd_soc_dapm_output: Is considered a source iff it has no incoming paths, otherwise normal. snd_soc_dapm_line: Is considered a sink iff it has no outgoing paths and is considered a source iff it has no incoming paths, otherwise normal. For snd_soc_dapm_dai_out/snd_soc_dapm_dai_in widgets the category will be updated when a stream is started or stopped. For the other dynamic widgets the category will be updated when a path connecting to it is added or removed. Introducing those new widget categories allows to make is_connected_{output,input}_ep, which are among the hottest paths of the DAPM algorithm, more generic and significantly shorter. The before and after sizes for is_connected_{output,input}_ep are: On ARM (defconfig + CONFIG_SND_SOC): function old new delta is_connected_output_ep 480 340 -140 is_connected_input_ep 456 352 -104 On amd64 (defconfig + CONFIG_SND_SOC): function old new delta is_connected_output_ep 579 427 -152 is_connected_input_ep 563 427 -136 Which is about a 25%-30% decrease, other architectures are expected to have similar numbers. At the same time the size of the snd_soc_dapm_widget struct does not change since the new flags are stored in the same word as the existing flags. Note: that since the per widget 'ext' flag was only used to decide whether a snd_soc_dapm_input or snd_soc_dapm_output widget was a source or a sink it is now unused and can be removed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 4 +- sound/soc/soc-dapm.c | 210 +++++++++++++++++---------------------- 2 files changed, 95 insertions(+), 119 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index ebb93f29e4f3..8cf3aad30864 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -543,11 +543,13 @@ struct snd_soc_dapm_widget { unsigned char active:1; /* active stream on DAC, ADC's */ unsigned char connected:1; /* connected codec pin */ unsigned char new:1; /* cnew complete */ - unsigned char ext:1; /* has external widgets */ unsigned char force:1; /* force state */ unsigned char ignore_suspend:1; /* kept enabled over suspend */ unsigned char new_power:1; /* power from this run */ unsigned char power_checked:1; /* power checked this run */ + unsigned char is_supply:1; /* Widget is a supply type widget */ + unsigned char is_sink:1; /* Widget is a sink type widget */ + unsigned char is_source:1; /* Widget is a source type widget */ int subseq; /* sort within widget type */ int (*power_check)(struct snd_soc_dapm_widget *w); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c49df10d1c33..2cad5f77ec60 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -821,43 +821,12 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, DAPM_UPDATE_STAT(widget, path_checks); - switch (widget->id) { - case snd_soc_dapm_supply: - case snd_soc_dapm_regulator_supply: - case snd_soc_dapm_clock_supply: - case snd_soc_dapm_kcontrol: + if (widget->is_supply) return 0; - default: - break; - } - switch (widget->id) { - case snd_soc_dapm_adc: - case snd_soc_dapm_aif_out: - case snd_soc_dapm_dai_out: - if (widget->active) { - widget->outputs = snd_soc_dapm_suspend_check(widget); - return widget->outputs; - } - default: - break; - } - - if (widget->connected) { - /* connected pin ? */ - if (widget->id == snd_soc_dapm_output && !widget->ext) { - widget->outputs = snd_soc_dapm_suspend_check(widget); - return widget->outputs; - } - - /* connected jack or spk ? */ - if (widget->id == snd_soc_dapm_hp || - widget->id == snd_soc_dapm_spk || - (widget->id == snd_soc_dapm_line && - !list_empty(&widget->sources))) { - widget->outputs = snd_soc_dapm_suspend_check(widget); - return widget->outputs; - } + if (widget->is_sink && widget->connected) { + widget->outputs = snd_soc_dapm_suspend_check(widget); + return widget->outputs; } list_for_each_entry(path, &widget->sinks, list_source) { @@ -913,55 +882,12 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, DAPM_UPDATE_STAT(widget, path_checks); - switch (widget->id) { - case snd_soc_dapm_supply: - case snd_soc_dapm_regulator_supply: - case snd_soc_dapm_clock_supply: - case snd_soc_dapm_kcontrol: + if (widget->is_supply) return 0; - default: - break; - } - - /* active stream ? */ - switch (widget->id) { - case snd_soc_dapm_dac: - case snd_soc_dapm_aif_in: - case snd_soc_dapm_dai_in: - if (widget->active) { - widget->inputs = snd_soc_dapm_suspend_check(widget); - return widget->inputs; - } - default: - break; - } - - if (widget->connected) { - /* connected pin ? */ - if (widget->id == snd_soc_dapm_input && !widget->ext) { - widget->inputs = snd_soc_dapm_suspend_check(widget); - return widget->inputs; - } - /* connected VMID/Bias for lower pops */ - if (widget->id == snd_soc_dapm_vmid) { - widget->inputs = snd_soc_dapm_suspend_check(widget); - return widget->inputs; - } - - /* connected jack ? */ - if (widget->id == snd_soc_dapm_mic || - (widget->id == snd_soc_dapm_line && - !list_empty(&widget->sinks))) { - widget->inputs = snd_soc_dapm_suspend_check(widget); - return widget->inputs; - } - - /* signal generator */ - if (widget->id == snd_soc_dapm_siggen) { - widget->inputs = snd_soc_dapm_suspend_check(widget); - return widget->inputs; - } + if (widget->is_source && widget->connected) { + widget->inputs = snd_soc_dapm_suspend_check(widget); + return widget->inputs; } list_for_each_entry(path, &widget->sources, list_sink) { @@ -1554,18 +1480,11 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, list_for_each_entry(path, &w->sources, list_sink) dapm_widget_set_peer_power(path->source, power, path->connect); - switch (w->id) { - case snd_soc_dapm_supply: - case snd_soc_dapm_regulator_supply: - case snd_soc_dapm_clock_supply: - case snd_soc_dapm_kcontrol: - /* Supplies can't affect their outputs, only their inputs */ - break; - default: + /* Supplies can't affect their outputs, only their inputs */ + if (!w->is_supply) { list_for_each_entry(path, &w->sinks, list_source) dapm_widget_set_peer_power(path->sink, power, path->connect); - break; } if (power) @@ -2226,6 +2145,53 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); +/* + * dapm_update_widget_flags() - Re-compute widget sink and source flags + * @w: The widget for which to update the flags + * + * Some widgets have a dynamic category which depends on which neighbors they + * are connected to. This function update the category for these widgets. + * + * This function must be called whenever a path is added or removed to a widget. + */ +static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_dapm_path *p; + + switch (w->id) { + case snd_soc_dapm_input: + w->is_source = 1; + list_for_each_entry(p, &w->sources, list_sink) { + if (p->source->id == snd_soc_dapm_micbias || + p->source->id == snd_soc_dapm_mic || + p->source->id == snd_soc_dapm_line || + p->source->id == snd_soc_dapm_output) { + w->is_source = 0; + break; + } + } + break; + case snd_soc_dapm_output: + w->is_sink = 1; + list_for_each_entry(p, &w->sinks, list_source) { + if (p->sink->id == snd_soc_dapm_spk || + p->sink->id == snd_soc_dapm_hp || + p->sink->id == snd_soc_dapm_line || + p->sink->id == snd_soc_dapm_input) { + w->is_sink = 0; + break; + } + } + break; + case snd_soc_dapm_line: + w->is_sink = !list_empty(&w->sources); + w->is_source = !list_empty(&w->sinks); + break; + default: + break; + } +} + static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink, const char *control, @@ -2247,22 +2213,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, INIT_LIST_HEAD(&path->list_source); INIT_LIST_HEAD(&path->list_sink); - /* check for external widgets */ - if (wsink->id == snd_soc_dapm_input) { - if (wsource->id == snd_soc_dapm_micbias || - wsource->id == snd_soc_dapm_mic || - wsource->id == snd_soc_dapm_line || - wsource->id == snd_soc_dapm_output) - wsink->ext = 1; - } - if (wsource->id == snd_soc_dapm_output) { - if (wsink->id == snd_soc_dapm_spk || - wsink->id == snd_soc_dapm_hp || - wsink->id == snd_soc_dapm_line || - wsink->id == snd_soc_dapm_input) - wsource->ext = 1; - } - /* connect static paths */ if (control == NULL) { path->connect = 1; @@ -2294,6 +2244,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); + dapm_update_widget_flags(wsource); + dapm_update_widget_flags(wsink); + dapm_mark_dirty(wsource, "Route added"); dapm_mark_dirty(wsink, "Route added"); @@ -2377,6 +2330,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route) { + struct snd_soc_dapm_widget *wsource, *wsink; struct snd_soc_dapm_path *path, *p; const char *sink; const char *source; @@ -2414,10 +2368,17 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, } if (path) { - dapm_mark_dirty(path->source, "Route removed"); - dapm_mark_dirty(path->sink, "Route removed"); + wsource = path->source; + wsink = path->sink; + + dapm_mark_dirty(wsource, "Route removed"); + dapm_mark_dirty(wsink, "Route removed"); dapm_free_path(path); + + /* Update any path related flags */ + dapm_update_widget_flags(wsource); + dapm_update_widget_flags(wsink); } else { dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", source, sink); @@ -2975,26 +2936,33 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, } switch (w->id) { - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - case snd_soc_dapm_mixer_named_ctl: + case snd_soc_dapm_mic: + case snd_soc_dapm_input: + w->is_source = 1; w->power_check = dapm_generic_check_power; break; - case snd_soc_dapm_mux: + case snd_soc_dapm_spk: + case snd_soc_dapm_hp: + case snd_soc_dapm_output: + w->is_sink = 1; w->power_check = dapm_generic_check_power; break; + case snd_soc_dapm_vmid: + case snd_soc_dapm_siggen: + w->is_source = 1; + w->power_check = dapm_always_on_check_power; + break; + case snd_soc_dapm_mux: + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + case snd_soc_dapm_mixer_named_ctl: case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: case snd_soc_dapm_dac: case snd_soc_dapm_aif_in: case snd_soc_dapm_pga: case snd_soc_dapm_out_drv: - case snd_soc_dapm_input: - case snd_soc_dapm_output: case snd_soc_dapm_micbias: - case snd_soc_dapm_spk: - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: case snd_soc_dapm_line: case snd_soc_dapm_dai_link: case snd_soc_dapm_dai_out: @@ -3005,6 +2973,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_regulator_supply: case snd_soc_dapm_clock_supply: case snd_soc_dapm_kcontrol: + w->is_supply = 1; w->power_check = dapm_supply_check_power; break; default: @@ -3368,6 +3337,11 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: break; } + + if (w->id == snd_soc_dapm_dai_in) + w->is_source = w->active; + else + w->is_sink = w->active; } } -- GitLab From c1862c8bae520a8986dd7c47ce33f16eb7c791c2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:42:00 +0200 Subject: [PATCH 1541/9457] ASoC: dapm: Add a flag to mark paths connected to supply widgets Supply widgets do not count towards the input and output widgets of their neighbors and for supply widgets themselves we do not care for the number of input or output paths. This means that a path that connects to a supply widget effectively behaves the same as a path that as the weak property set. This patch adds a new path flag that gets set to true when the path is connected to at least one supply widget. If a path with the flag set is encountered in is_connected_{input,output}_ep() is is skipped in the same way that weak paths are skipped. This slightly brings down the number of path checks. Since both the weak and the supply flag are implemented as bitfields which are stored in the same word there is no runtime overhead due to checking both rather than just one and also the size of the path struct is not increased by this patch. Another advantage is that we do not have to handle supply widgets in is_connected_{input,output}_ep() anymore since it will never be called for supply widgets. The only exception is from dapm_widget_power_read_file() where a check is added to special case supply widgets. Testing with the ADAU1761, which has a handful of supply widgets, shows the following changes in the DAPM stats for a playback stream start. Power Path Neighbour Before: 34 78 117 After: 34 48 117 Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 1 + sound/soc/soc-dapm.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 8cf3aad30864..e7ebeb717482 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -510,6 +510,7 @@ struct snd_soc_dapm_path { u32 connect:1; /* source and sink widgets are connected */ u32 walking:1; /* path is in the process of being walked */ u32 weak:1; /* path ignored for power management */ + u32 is_supply:1; /* At least one of the connected widgets is a supply */ int (*connected)(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2cad5f77ec60..d89be153a9e0 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -821,9 +821,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, DAPM_UPDATE_STAT(widget, path_checks); - if (widget->is_supply) - return 0; - if (widget->is_sink && widget->connected) { widget->outputs = snd_soc_dapm_suspend_check(widget); return widget->outputs; @@ -832,7 +829,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, list_for_each_entry(path, &widget->sinks, list_source) { DAPM_UPDATE_STAT(widget, neighbour_checks); - if (path->weak) + if (path->weak || path->is_supply) continue; if (path->walking) @@ -882,9 +879,6 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, DAPM_UPDATE_STAT(widget, path_checks); - if (widget->is_supply) - return 0; - if (widget->is_source && widget->connected) { widget->inputs = snd_soc_dapm_suspend_check(widget); return widget->inputs; @@ -893,7 +887,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, list_for_each_entry(path, &widget->sources, list_sink) { DAPM_UPDATE_STAT(widget, neighbour_checks); - if (path->weak) + if (path->weak || path->is_supply) continue; if (path->walking) @@ -1691,8 +1685,14 @@ static ssize_t dapm_widget_power_read_file(struct file *file, if (!buf) return -ENOMEM; - in = is_connected_input_ep(w, NULL); - out = is_connected_output_ep(w, NULL); + /* Supply widgets are not handled by is_connected_{input,output}_ep() */ + if (w->is_supply) { + in = 0; + out = 0; + } else { + in = is_connected_input_ep(w, NULL); + out = is_connected_output_ep(w, NULL); + } ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", w->name, w->power ? "On" : "Off", @@ -2213,6 +2213,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, INIT_LIST_HEAD(&path->list_source); INIT_LIST_HEAD(&path->list_sink); + if (wsource->is_supply || wsink->is_supply) + path->is_supply = 1; + /* connect static paths */ if (control == NULL) { path->connect = 1; -- GitLab From 8be4da29cf5b8ec65e974c36e7ae4d90b381ac5e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:42:01 +0200 Subject: [PATCH 1542/9457] ASoC: dapm: Mark endpoints instead of IO widgets dirty during suspend/resume The state of endpoint widgets is affected by that card's power state. Endpoint widgets that do no have the ignore_suspend flag set will be considered inactive during suspend. So they have to be re-checked and marked dirty after the card's power state changes. Currently the input and output widgets are marked dirty instead, this works most of the time since typically a path from one endpoint to another will go via a input or output widget. But marking the endpoints dirty is technically more correct and will also work for odd corner cases. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 2 +- sound/soc/soc-core.c | 8 ++++---- sound/soc/soc-dapm.c | 15 ++++----------- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e7ebeb717482..43ca1656dab4 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -435,7 +435,7 @@ void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card); unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol); /* Mostly internal - should not normally be used */ -void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm); +void dapm_mark_endpoints_dirty(struct snd_soc_card *card); /* dapm path query */ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..443be0061129 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -629,8 +629,8 @@ int snd_soc_suspend(struct device *dev) SND_SOC_DAPM_STREAM_SUSPEND); } - /* Recheck all analogue paths too */ - dapm_mark_io_dirty(&card->dapm); + /* Recheck all endpoints too, their state is affected by suspend */ + dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); /* suspend all CODECs */ @@ -796,8 +796,8 @@ static void soc_resume_deferred(struct work_struct *work) /* userspace can access us now we are back as we were before */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); - /* Recheck all analogue paths too */ - dapm_mark_io_dirty(&card->dapm); + /* Recheck all endpoints too, their state is affected by suspend */ + dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d89be153a9e0..ffcda7ecd832 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -159,27 +159,20 @@ static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) } } -void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) +void dapm_mark_endpoints_dirty(struct snd_soc_card *card) { - struct snd_soc_card *card = dapm->card; struct snd_soc_dapm_widget *w; mutex_lock(&card->dapm_mutex); list_for_each_entry(w, &card->widgets, list) { - switch (w->id) { - case snd_soc_dapm_input: - case snd_soc_dapm_output: - dapm_mark_dirty(w, "Rechecking inputs and outputs"); - break; - default: - break; - } + if (w->is_sink || w->is_source) + dapm_mark_dirty(w, "Rechecking endpoints"); } mutex_unlock(&card->dapm_mutex); } -EXPORT_SYMBOL_GPL(dapm_mark_io_dirty); +EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty); /* create a new dapm widget */ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( -- GitLab From e409dfbfccf9a49409197afc677a21e1c11ba015 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:42:02 +0200 Subject: [PATCH 1543/9457] ASoC: dapm: Add a few supply widget sanity checks Supply widgets are somewhat special and not all kinds of paths to or from supply widgets make sense. This patch adds a few sanity checks that errors out during the path instantiation for those invalid paths. This will prevent drivers to depend on weird behavior resulting from such paths as well as will allow the DAPM algorithms to assume that they never see such paths. This patch adds checks for the following three invalid types of paths: * A path with a non-supply widget as a source connected to a supply widget as a sink. Such a path has no effect on either of the two connected widgets. * Paths with a connected() callback that have a non-supply widget as the source. The DAPM algorithm only uses the conneceted() callback for supply widget power checks. And since it prevents caching of the DAPM state there is no intention to make it more generic as it has negative performance implications. * Paths which connect a supply to a mixer or mux via a control. Controls are only meant to affect the routing of audio data. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index ffcda7ecd832..8e26c2bc7fdf 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2194,6 +2194,27 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_path *path; int ret; + if (wsink->is_supply && !wsource->is_supply) { + dev_err(dapm->dev, + "Connecting non-supply widget to supply widget is not supported (%s -> %s)\n", + wsource->name, wsink->name); + return -EINVAL; + } + + if (connected && !wsource->is_supply) { + dev_err(dapm->dev, + "connected() callback only supported for supply widgets (%s -> %s)\n", + wsource->name, wsink->name); + return -EINVAL; + } + + if (wsource->is_supply && control) { + dev_err(dapm->dev, + "Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n", + wsource->name, control, wsink->name); + return -EINVAL; + } + path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); if (!path) return -ENOMEM; -- GitLab From 92a99ea439c4e27fc6e32eb6d51c5d091c6084bd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 17:42:03 +0200 Subject: [PATCH 1544/9457] ASoC: dapm: Use more aggressive caching Currently we cache the number of input and output paths going to/from a widget only within a power update sequence. But not in between power update sequences. But we know how changes to the DAPM graph affect the number of input (form a source) and output (to a sink) paths of a widget and only need to recalculate them if a operation has been performed that might have changed them. * Adding/removing or connecting/disconnecting a path means that the for the source of the path the number of output paths can change and for the sink the number of input paths can change. * Connecting/disconnecting a widget has the same effect has connecting/ disconnecting all paths of the widget. So for the widget itself the number of inputs and outputs can change, for all sinks of the widget the number of inputs can change and for all sources of the widget the number of outputs can change. * Activating/Deactivating a stream can either change the number of outputs on the sources of the widget associated with the stream or the number of inputs on the sinks. Instead of always invalidating all cached numbers of input and output paths for each power up or down sequence this patch restructures the code to only invalidate the cached numbers when a operation that might change them has been performed. This can greatly reduce the number of DAPM power checks for some very common operations. Since per DAPM operation typically only either change the number of inputs or outputs the number of path checks is reduced by at least 50%. The number of neighbor checks is also reduced about the same percentage, but since the number of neighbors encountered when walking from sink to source is not the same as when walking from source to sink the actual numbers will slightly vary from card to card (e.g. for a mixer we see 1 neighbor when walking from source to sink, but the number of inputs neighbors when walking from source to sink). Bigger improvements can be observed for widgets with multiple connected inputs and output (e.g. mixers probably being the most widespread form of this). Previously we had to re-calculate the number of inputs and outputs on all input and output paths. With this change we only have to re-calculate the number of outputs on the input path that got changed and the number of inputs on the output paths. E.g. imagine the following example: A --> B ----. v M --> N --> Z <-- S <-- R | v X Widget Z has multiple input paths, if any change was made that cause Z to be marked as dirty the power state of Z has to be re-computed. This requires to know the number of inputs and outputs of Z, which requires to know the number of inputs and outputs of all widgets on all paths from or to Z. Previously this meant re-computing all inputs and outputs of all the path going into or out of Z. With this patch in place only paths that actually have changed need to be re-computed. If the system is idle (or the part of the system affected by the changed path) the number of path checks drops to either 0 or 1, regardless of how large or complex the DAPM context is. 0 if there is no connected sink and no connected source. 1 if there is either a connected source or sink, but not both. The number of neighbor checks again will scale accordingly and will be a constant number that is the number of inputs or outputs of the widget for which we did the path check. When loading a state file or switching between different profiles typically multiple mixer and mux settings are changed, so we see the benefit of this patch multiplied for these kinds of operations. Testing with the ADAU1761 shows the following changes in DAPM stats for changing a single Mixer switch for a Mixer with 5 inputs while the DAPM context is idle. Power Path Neighbour Before: 2 12 30 After: 2 1 2 For the same switch, but with a active playback stream the stat changed are as follows. Power Path Neighbour Before: 10 20 54 After: 10 7 21 Cumulative numbers for switching the audio profile which changes 7 controls while the system is idle: Power Path Neighbour Before: 16 80 170 After: 16 7 23 Cumulative numbers for switching the audio profile which changes 7 controls while playback is active: Power Path Neighbour Before: 51 123 273 After: 51 29 109 Starting (or stopping) the playback stream: Power Path Neighbour Before: 34 34 117 After: 34 17 69 Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 1 + sound/soc/soc-dapm.c | 161 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 154 insertions(+), 8 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 43ca1656dab4..89823cfe6f04 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -569,6 +569,7 @@ struct snd_soc_dapm_widget { struct list_head sinks; /* used during DAPM updates */ + struct list_head work_list; struct list_head power_list; struct list_head dirty; int inputs; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8e26c2bc7fdf..6bf2c9795df2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -159,6 +159,116 @@ static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) } } +/* + * dapm_widget_invalidate_input_paths() - Invalidate the cached number of input + * paths + * @w: The widget for which to invalidate the cached number of input paths + * + * The function resets the cached number of inputs for the specified widget and + * all widgets that can be reached via outgoing paths from the widget. + * + * This function must be called if the number of input paths for a widget might + * have changed. E.g. if the source state of a widget changes or a path is added + * or activated with the widget as the sink. + */ +static void dapm_widget_invalidate_input_paths(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_dapm_widget *sink; + struct snd_soc_dapm_path *p; + LIST_HEAD(list); + + dapm_assert_locked(w->dapm); + + if (w->inputs == -1) + return; + + w->inputs = -1; + list_add_tail(&w->work_list, &list); + + list_for_each_entry(w, &list, work_list) { + list_for_each_entry(p, &w->sinks, list_source) { + if (p->is_supply || p->weak || !p->connect) + continue; + sink = p->sink; + if (sink->inputs != -1) { + sink->inputs = -1; + list_add_tail(&sink->work_list, &list); + } + } + } +} + +/* + * dapm_widget_invalidate_output_paths() - Invalidate the cached number of + * output paths + * @w: The widget for which to invalidate the cached number of output paths + * + * Resets the cached number of outputs for the specified widget and all widgets + * that can be reached via incoming paths from the widget. + * + * This function must be called if the number of output paths for a widget might + * have changed. E.g. if the sink state of a widget changes or a path is added + * or activated with the widget as the source. + */ +static void dapm_widget_invalidate_output_paths(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_dapm_widget *source; + struct snd_soc_dapm_path *p; + LIST_HEAD(list); + + dapm_assert_locked(w->dapm); + + if (w->outputs == -1) + return; + + w->outputs = -1; + list_add_tail(&w->work_list, &list); + + list_for_each_entry(w, &list, work_list) { + list_for_each_entry(p, &w->sources, list_sink) { + if (p->is_supply || p->weak || !p->connect) + continue; + source = p->source; + if (source->outputs != -1) { + source->outputs = -1; + list_add_tail(&source->work_list, &list); + } + } + } +} + +/* + * dapm_path_invalidate() - Invalidates the cached number of inputs and outputs + * for the widgets connected to a path + * @p: The path to invalidate + * + * Resets the cached number of inputs for the sink of the path and the cached + * number of outputs for the source of the path. + * + * This function must be called when a path is added, removed or the connected + * state changes. + */ +static void dapm_path_invalidate(struct snd_soc_dapm_path *p) +{ + /* + * Weak paths or supply paths do not influence the number of input or + * output paths of their neighbors. + */ + if (p->weak || p->is_supply) + return; + + /* + * The number of connected endpoints is the sum of the number of + * connected endpoints of all neighbors. If a node with 0 connected + * endpoints is either connected or disconnected that sum won't change, + * so there is no need to re-check the path. + */ + if (p->source->inputs != 0) + dapm_widget_invalidate_input_paths(p->sink); + if (p->sink->outputs != 0) + dapm_widget_invalidate_output_paths(p->source); +} + void dapm_mark_endpoints_dirty(struct snd_soc_card *card) { struct snd_soc_dapm_widget *w; @@ -166,8 +276,13 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card) mutex_lock(&card->dapm_mutex); list_for_each_entry(w, &card->widgets, list) { - if (w->is_sink || w->is_source) + if (w->is_sink || w->is_source) { dapm_mark_dirty(w, "Rechecking endpoints"); + if (w->is_sink) + dapm_widget_invalidate_output_paths(w); + if (w->is_source) + dapm_widget_invalidate_input_paths(w); + } } mutex_unlock(&card->dapm_mutex); @@ -379,8 +494,6 @@ static void dapm_reset(struct snd_soc_card *card) list_for_each_entry(w, &card->widgets, list) { w->new_power = w->power; w->power_checked = false; - w->inputs = -1; - w->outputs = -1; } } @@ -931,10 +1044,19 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget_list **list) { struct snd_soc_card *card = dai->card; + struct snd_soc_dapm_widget *w; int paths; mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); - dapm_reset(card); + + /* + * For is_connected_{output,input}_ep fully discover the graph we need + * to reset the cached number of inputs and outputs. + */ + list_for_each_entry(w, &card->widgets, list) { + w->inputs = -1; + w->outputs = -1; + } if (stream == SNDRV_PCM_STREAM_PLAYBACK) paths = is_connected_output_ep(dai->playback_widget, list); @@ -1846,6 +1968,7 @@ static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, path->connect = connect; dapm_mark_dirty(path->source, reason); dapm_mark_dirty(path->sink, reason); + dapm_path_invalidate(path); } /* test and update the power status of a mux widget */ @@ -2084,8 +2207,11 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, return -EINVAL; } - if (w->connected != status) + if (w->connected != status) { dapm_mark_dirty(w, "pin configuration"); + dapm_widget_invalidate_input_paths(w); + dapm_widget_invalidate_output_paths(w); + } w->connected = status; if (status == 0) @@ -2267,6 +2393,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, dapm_mark_dirty(wsource, "Route added"); dapm_mark_dirty(wsink, "Route added"); + if (dapm->card->instantiated && path->connect) + dapm_path_invalidate(path); + return 0; err: kfree(path); @@ -2390,6 +2519,8 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm, dapm_mark_dirty(wsource, "Route removed"); dapm_mark_dirty(wsink, "Route removed"); + if (path->connect) + dapm_path_invalidate(path); dapm_free_path(path); @@ -3007,6 +3138,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, INIT_LIST_HEAD(&w->dirty); list_add(&w->list, &dapm->card->widgets); + w->inputs = -1; + w->outputs = -1; + /* machine layer set ups unconnected pins and insertions */ w->connected = 1; return w; @@ -3355,10 +3489,13 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, break; } - if (w->id == snd_soc_dapm_dai_in) + if (w->id == snd_soc_dapm_dai_in) { w->is_source = w->active; - else + dapm_widget_invalidate_input_paths(w); + } else { w->is_sink = w->active; + dapm_widget_invalidate_output_paths(w); + } } } @@ -3485,7 +3622,15 @@ int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, } dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin); - w->connected = 1; + if (!w->connected) { + /* + * w->force does not affect the number of input or output paths, + * so we only have to recheck if w->connected is changed + */ + dapm_widget_invalidate_input_paths(w); + dapm_widget_invalidate_output_paths(w); + w->connected = 1; + } w->force = 1; dapm_mark_dirty(w, "force enable"); -- GitLab From c1b4d1c7774189002bc08766ec10e339dfbc98d6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 25 Oct 2014 20:25:56 +0200 Subject: [PATCH 1545/9457] ASoC: Use generic control handlers for S8 control Commit f227b88f0fce ("ASoC: core: Add signed register volume control logic") added support for signed control to the generic volsw control handler. This makes it possible to use them for the S8 control as well, rather than having to use a custom control handler implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 19 ++++------ sound/soc/soc-core.c | 87 -------------------------------------------- 2 files changed, 8 insertions(+), 98 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..ad47e9660b22 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -36,6 +36,11 @@ {.reg = xreg, .rreg = xreg, .shift = shift_left, \ .rshift = shift_right, .max = xmax, .platform_max = xmax, \ .invert = xinvert, .autodisable = xautodisable}) +#define SOC_DOUBLE_S_VALUE(xreg, shift_left, shift_right, xmin, xmax, xsign_bit, xinvert, xautodisable) \ + ((unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .rreg = xreg, .shift = shift_left, \ + .rshift = shift_right, .min = xmin, .max = xmax, .platform_max = xmax, \ + .sign_bit = xsign_bit, .invert = xinvert, .autodisable = xautodisable}) #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, xautodisable) \ SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert, xautodisable) #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ @@ -171,11 +176,9 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ - .put = snd_soc_put_volsw_s8, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .min = xmin, .max = xmax, \ - .platform_max = xmax} } + .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ + .put = snd_soc_put_volsw, \ + .private_value = SOC_DOUBLE_S_VALUE(xreg, 0, 8, xmin, xmax, 7, 0, 0) } #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xitems, xtexts) \ { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ .items = xitems, .texts = xtexts, \ @@ -545,12 +548,6 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 96ecdc30eb60..47c378abb9a2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2720,93 +2720,6 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); -/** - * snd_soc_info_volsw_s8 - signed mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a signed mixer control. - * - * Returns 0 for success. - */ -int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int platform_max; - int min = mc->min; - - if (!mc->platform_max) - mc->platform_max = mc->max; - platform_max = mc->platform_max; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = platform_max - min; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); - -/** - * snd_soc_get_volsw_s8 - signed mixer get callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value of a signed mixer control. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - unsigned int reg = mc->reg; - unsigned int val; - int min = mc->min; - int ret; - - ret = snd_soc_component_read(component, reg, &val); - if (ret) - return ret; - - ucontrol->value.integer.value[0] = - ((signed char)(val & 0xff))-min; - ucontrol->value.integer.value[1] = - ((signed char)((val >> 8) & 0xff))-min; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8); - -/** - * snd_soc_put_volsw_sgn - signed mixer put callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to set the value of a signed mixer control. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - unsigned int reg = mc->reg; - int min = mc->min; - unsigned int val; - - val = (ucontrol->value.integer.value[0]+min) & 0xff; - val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; - - return snd_soc_component_update_bits(component, reg, 0xffff, val); -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); - /** * snd_soc_info_volsw_range - single mixer info callback with range. * @kcontrol: mixer control -- GitLab From 728384a10b673dbd9819b524852df23142ee2fdd Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 24 Oct 2014 21:50:04 +0400 Subject: [PATCH 1546/9457] ARM: pxa: spitz: register spitz-audio device Register spitz-audio device to be used by ASoC driver to bind ASoC platform driver. Currently old 'soc-audio' approach is used, which needs to be replaced with proper device. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- arch/arm/mach-pxa/spitz.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 840c3a48e720..962a7f31f596 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -923,6 +923,14 @@ static void __init spitz_i2c_init(void) static inline void spitz_i2c_init(void) {} #endif +/****************************************************************************** + * Audio devices + ******************************************************************************/ +static inline void spitz_audio_init(void) +{ + platform_device_register_simple("spitz-audio", -1, NULL, 0); +} + /****************************************************************************** * Machine init ******************************************************************************/ @@ -970,6 +978,7 @@ static void __init spitz_init(void) spitz_nor_init(); spitz_nand_init(); spitz_i2c_init(); + spitz_audio_init(); } static void __init spitz_fixup(struct tag *tags, char **cmdline) -- GitLab From ecf0015161b2220879fcd41c030761b4eb561b95 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 24 Oct 2014 21:50:05 +0400 Subject: [PATCH 1547/9457] ASoC: pxa: Convert spitz to use snd_soc_register_card() Use snd_soc_register_card() instead of creating a "soc-audio" platform device. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- sound/soc/pxa/spitz.c | 52 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 1373b017a951..d7d5fb20ea6f 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -305,19 +305,15 @@ static struct snd_soc_card snd_soc_spitz = { .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), }; -static struct platform_device *spitz_snd_device; - -static int __init spitz_init(void) +static int spitz_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &snd_soc_spitz; int ret; - if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) - return -ENODEV; - - if (machine_is_borzoi() || machine_is_spitz()) - spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; - else + if (machine_is_akita()) spitz_mic_gpio = AKITA_GPIO_MIC_BIAS; + else + spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; ret = gpio_request(spitz_mic_gpio, "MIC GPIO"); if (ret) @@ -327,37 +323,45 @@ static int __init spitz_init(void) if (ret) goto err2; - spitz_snd_device = platform_device_alloc("soc-audio", -1); - if (!spitz_snd_device) { - ret = -ENOMEM; + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); goto err2; } - platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); - - ret = platform_device_add(spitz_snd_device); - if (ret) - goto err3; - return 0; -err3: - platform_device_put(spitz_snd_device); err2: gpio_free(spitz_mic_gpio); err1: return ret; } -static void __exit spitz_exit(void) +static int spitz_remove(struct platform_device *pdev) { - platform_device_unregister(spitz_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); gpio_free(spitz_mic_gpio); + return 0; } -module_init(spitz_init); -module_exit(spitz_exit); +static struct platform_driver spitz_driver = { + .driver = { + .name = "spitz-audio", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = spitz_probe, + .remove = spitz_remove, +}; + +module_platform_driver(spitz_driver); MODULE_AUTHOR("Richard Purdie"); MODULE_DESCRIPTION("ALSA SoC Spitz"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spitz-audio"); -- GitLab From 3f7256fe5fc64132a2dd19695255c990aa2188cf Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 24 Oct 2014 13:01:25 -0200 Subject: [PATCH 1548/9457] ASoC: sgtl5000: Use the preferred form for passing a size of a struct According to Documentation/CodingStyle - Chapter 14: "The preferred form for passing a size of a struct is the following: p = kmalloc(sizeof(*p), ...); The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not." So do it as recommeded. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 59336f6aba80..490404c6b4d8 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1439,8 +1439,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, struct device_node *np = client->dev.of_node; u32 value; - sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), - GFP_KERNEL); + sgtl5000 = devm_kzalloc(&client->dev, sizeof(*sgtl5000), GFP_KERNEL); if (!sgtl5000) return -ENOMEM; -- GitLab From 54ec2d5f3f751ddcbf07b0fc1e5f01e43015e8e0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 24 Oct 2014 13:01:26 -0200 Subject: [PATCH 1549/9457] ASoC: wm8962: Use the preferred form for passing a size of a struct According to Documentation/CodingStyle - Chapter 14: "The preferred form for passing a size of a struct is the following: p = kmalloc(sizeof(*p), ...); The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not." So do it as recommeded. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 9077411e62ce..cfd38917acb8 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3552,8 +3552,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, unsigned int reg; int ret, i, irq_pol, trigger; - wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv), - GFP_KERNEL); + wm8962 = devm_kzalloc(&i2c->dev, sizeof(*wm8962), GFP_KERNEL); if (wm8962 == NULL) return -ENOMEM; -- GitLab From cea82d8af3986508a05949cfbb6ad8e99ffc15eb Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 24 Oct 2014 13:01:27 -0200 Subject: [PATCH 1550/9457] ASoC: wm8731: Use the preferred form for passing a size of a struct According to Documentation/CodingStyle - Chapter 14: "The preferred form for passing a size of a struct is the following: p = kmalloc(sizeof(*p), ...); The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not." So do it as recommeded. Cc: Charles Keepax Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/codecs/wm8731.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index eebb3280bfad..2c9f2a7005c3 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -680,8 +680,7 @@ static int wm8731_spi_probe(struct spi_device *spi) struct wm8731_priv *wm8731; int ret; - wm8731 = devm_kzalloc(&spi->dev, sizeof(struct wm8731_priv), - GFP_KERNEL); + wm8731 = devm_kzalloc(&spi->dev, sizeof(*wm8731), GFP_KERNEL); if (wm8731 == NULL) return -ENOMEM; -- GitLab From d7701089118d23bfed03bad0a6b5cc5115990c9e Mon Sep 17 00:00:00 2001 From: Alex Gartrell Date: Mon, 6 Oct 2014 13:30:08 -0700 Subject: [PATCH 1551/9457] ipvs: remove unnecessary assignment in __ip_vs_get_out_rt It is a precondition of the function that daddr be equal to dest->addr.ip if dest is non-NULL, so this additional assignment is just confusing for stupid engineers like me. Signed-off-by: Alex Gartrell Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_xmit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 91f17c1eb8a2..5efa59792505 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -293,7 +293,6 @@ __ip_vs_get_out_rt(int skb_af, struct sk_buff *skb, struct ip_vs_dest *dest, &dest->addr.ip, &dest_dst->dst_saddr.ip, atomic_read(&rt->dst.__refcnt)); } - daddr = dest->addr.ip; if (ret_saddr) *ret_saddr = dest_dst->dst_saddr.ip; } else { -- GitLab From a707edd2360e739a27fd7b1720edd075ee5f7f64 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sun, 26 Oct 2014 21:35:04 +0530 Subject: [PATCH 1552/9457] staging: rtl8188eu: core: Remove redundant memset before memcpy The region set by the call to memset, immediately overwritten by the subsequent call to memcpy makes the memset redundant. This patch removes the redundant memset before memcpy using the following coccinelle script: @@ expression e1,e2,e3,e4; @@ - memset(e1,e2,e3); memcpy(e1,e4,e3); Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 1 - drivers/staging/rtl8188eu/core/rtw_mlme.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index fc280ce57d2c..2faf6b2e8129 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -98,7 +98,6 @@ u8 rtw_do_join(struct adapter *padapter) pibss = padapter->registrypriv.dev_network.MacAddress; - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(padapter); diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index bbebe67a77db..b4e8504b34ed 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -674,7 +674,6 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n")); - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); @@ -1334,7 +1333,6 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network)); - memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid)); rtw_update_registrypriv_dev_network(adapter); -- GitLab From be40a5e29e3eba9c5628512b6f991ab6822a3f04 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sat, 25 Oct 2014 10:46:02 +0530 Subject: [PATCH 1553/9457] staging: unisys: visorchannel: Improved cleanup code kfree on NULL pointer is a no-op. This patch used the following semantic patch to find an instance where NULL check is present before kfree // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Code is made more simpler by breaking up of sequence of kmallocs and adding some more exit labels. Removed unnecessary initialization of buf and fmtbuf to NULL as they are local variables. Suggested-by: Arnd Bergmann Suggested-by: Julia Lawall Signed-off-by: Tapasweni Pathak Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchannel/visorchannel_funcs.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index c24052b13fd2..5fbd5ada52e9 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -650,15 +650,17 @@ visorchannel_dump_section(VISORCHANNEL *chan, char *s, fmtbufsize = 100 * COVQ(len, 16); buf = kmalloc(len, GFP_KERNEL|__GFP_NORETRY); + if (!buf) + return; fmtbuf = kmalloc(fmtbufsize, GFP_KERNEL|__GFP_NORETRY); - if (buf == NULL || fmtbuf == NULL) - goto Away; + if (!fmtbuf) + goto fmt_failed; errcode = visorchannel_read(chan, off, buf, len); if (errcode < 0) { ERRDRV("%s failed to read %s from channel errcode=%d", s, __func__, errcode); - goto Away; + goto read_failed; } seq_printf(seq, "channel %s:\n", s); tbuf = buf; @@ -670,14 +672,9 @@ visorchannel_dump_section(VISORCHANNEL *chan, char *s, len -= 16; } -Away: - if (buf != NULL) { - kfree(buf); - buf = NULL; - } - if (fmtbuf != NULL) { - kfree(fmtbuf); - fmtbuf = NULL; - } +read_failed: + kfree(fmtbuf); +fmt_failed: + kfree(buf); } EXPORT_SYMBOL_GPL(visorchannel_dump_section); -- GitLab From f474f5e5353d9a935833b69d029db4856b6bd6e9 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Sat, 25 Oct 2014 13:16:42 +0300 Subject: [PATCH 1554/9457] staging: wlan-ng: Fix incorrect type in assignments fc variable type was u16 and it has an assignment from cpu_to_le16() so its type changed as __le16. This bug found by sparse. Signed-off-by: Ebru Akagunduz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 2 +- drivers/staging/wlan-ng/p80211hdr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 3b5468c64fde..7eaaf9a63503 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -107,7 +107,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, struct p80211_metawep *p80211_wep) { - u16 fc; + __le16 fc; u16 proto; struct wlan_ethhdr e_hdr; struct wlan_llc *e_llc; diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h index 66b5e201d418..79d9b20b364d 100644 --- a/drivers/staging/wlan-ng/p80211hdr.h +++ b/drivers/staging/wlan-ng/p80211hdr.h @@ -148,7 +148,7 @@ /* Generic 802.11 Header types */ struct p80211_hdr_a3 { - u16 fc; + __le16 fc; u16 dur; u8 a1[ETH_ALEN]; u8 a2[ETH_ALEN]; -- GitLab From 308c32f9e8f4ead8e6b37ed3a479ac5f95e58707 Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 20:04:17 +0800 Subject: [PATCH 1555/9457] staging: dgnc: delete successive assignments to the same location Successive assignments to the same location is meaningless and can be deleted. The Coccinelle semantic patch was used to find cases. @@ expression e1,e2,e3; @@ ( (<+...e1++...+>)=e2; | (<+...e1--...+>)=e2; | (<+...++e1...+>)=e2; | (<+...--e1...+>)=e2; | e1=e2; e1 = <+...e1...+>; | *e1=e2; *e1=e3; ) Signed-off-by: Jiayi Ye Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 8384e3d770f1..f81a375f8bc1 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -2205,8 +2205,6 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns if (!bd || bd->magic != DGNC_BOARD_MAGIC) return ret; - ret = 0; - ret = get_user(arg, value); if (ret) return ret; -- GitLab From 7353871aff29c09f342b774b524e6223e8954858 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 27 Oct 2014 22:22:07 +0530 Subject: [PATCH 1556/9457] Staging: lustre: Place a space after a semi colon. Removes the following errors generated using checkpatch.pl tool: drivers/staging/lustre/lustre/ldlm/ldlm_internal.h:247: ERROR: space required after that ';' (ctx:VxV) drivers/staging/lustre/lustre/ldlm/ldlm_internal.h:269: ERROR: space required after that ';' (ctx:VxV) Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ldlm/ldlm_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h index f997566ef11e..06cf6d282e65 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h @@ -244,7 +244,7 @@ typedef enum ldlm_policy_res ldlm_policy_res_t; \ return lprocfs_rd_uint(m, &tmp); \ } \ - struct __##var##__dummy_read {;} /* semicolon catcher */ + struct __##var##__dummy_read {; } /* semicolon catcher */ #define LDLM_POOL_PROC_WRITER(var, type) \ static int lprocfs_wr_##var(struct file *file, const char *buffer, \ @@ -266,7 +266,7 @@ typedef enum ldlm_policy_res ldlm_policy_res_t; \ return rc; \ } \ - struct __##var##__dummy_write {;} /* semicolon catcher */ + struct __##var##__dummy_write {; } /* semicolon catcher */ static inline int is_granted_or_cancelled(struct ldlm_lock *lock) { -- GitLab From 427eed0244010c64f6905212f48258d3631bcb4d Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 20:05:43 +0800 Subject: [PATCH 1557/9457] staging: rtl8192e: delete successive assignments to the same location Successive assignments to the same location is meaningless and can be deleted. The Coccinelle semantic patch was used to find cases. @@ expression e1,e2,e3; @@ ( (<+...e1++...+>)=e2; | (<+...e1--...+>)=e2; | (<+...++e1...+>)=e2; | (<+...--e1...+>)=e2; | e1=e2; e1 = <+...e1...+>; | *e1=e2; *e1=e3; ) Signed-off-by: Jiayi Ye Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index b6ce8c3b2f8c..885315cac3a4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -1449,13 +1449,11 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; @@ -1465,13 +1463,11 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); - TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; @@ -1493,7 +1489,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ @@ -1501,7 +1496,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; @@ -1515,7 +1509,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ @@ -1523,7 +1516,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; -- GitLab From 2f12163369562146699bb156d26975991d465edd Mon Sep 17 00:00:00 2001 From: Jiayi Ye Date: Sat, 25 Oct 2014 20:06:59 +0800 Subject: [PATCH 1558/9457] staging: rtl8192u: delete successive assignments to the same location Successive assignments to the same location is meaningless and can be deleted. The Coccinelle semantic patch was used to find cases. @@ expression e1,e2,e3; @@ ( (<+...e1++...+>)=e2; | (<+...e1--...+>)=e2; | (<+...++e1...+>)=e2; | (<+...--e1...+>)=e2; | e1=e2; e1 = <+...e1...+>; | *e1=e2; *e1=e3; ) Signed-off-by: Jiayi Ye Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_dm.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index cf4d3dc5dc76..936565d46014 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -1476,14 +1476,12 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; @@ -1496,14 +1494,12 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+ (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24); rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] + (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ; @@ -1528,7 +1524,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ @@ -1537,7 +1532,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; @@ -1556,7 +1550,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ @@ -1565,7 +1558,6 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 - TempVal = 0; TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; -- GitLab From baf9ef82fc96ef37cb1d85aaf225663ff0c15fa6 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Mon, 27 Oct 2014 17:56:33 +0530 Subject: [PATCH 1559/9457] Staging: rtl8192u: Annotate association types with proper endianness This patch fixes following sparse warning at number of places in file rtl819x_BAProc.c. Warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] tmp got restricted __le16 [usertype] Here, code before this change is correct. But this change silents sparse warnings and will not harm code too. Signed-off-by: Vaishali Thakkar Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 51552d42d66c..a95508d9820e 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -110,7 +110,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P struct sk_buff *skb = NULL; struct ieee80211_hdr_3addr *BAReq = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; u16 len = ieee->tx_headroom + 9; //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); @@ -196,7 +196,7 @@ static struct sk_buff *ieee80211_DELBA( struct sk_buff *skb = NULL; struct ieee80211_hdr_3addr *Delba = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; //len = head len + DELBA Parameter Set(2) + Reason Code(2) u16 len = 6 + ieee->tx_headroom; -- GitLab From 9ab6388cb8e7afa5377ae7f6976ab514025875d6 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Sat, 25 Oct 2014 23:13:39 +0530 Subject: [PATCH 1560/9457] Staging: iio: light: Removed unnecessary parentheses Unnecessary parentheses around the right hand side of an assignment is removed using the following semantic patch: @@ identifier x,f; constant C; @@ ( -x = (f / C ); +x = f / C ; | -x = (f % C ); +x = f % C ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2x7x_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index b3d73a9a42ab..423f96bdf595 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1040,8 +1040,8 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev, y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; z = y * TSL2X7X_MIN_ITIME; filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F); - y = (filter_delay / 1000); - z = (filter_delay % 1000); + y = filter_delay / 1000; + z = filter_delay % 1000; return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); } @@ -1086,8 +1086,8 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; z = y * TSL2X7X_MIN_ITIME; filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4); - y = (filter_delay / 1000); - z = (filter_delay % 1000); + y = filter_delay / 1000; + z = filter_delay % 1000; return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); } -- GitLab From dfd94488a8aa9320d8048a108c602bf4307d4734 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Sat, 25 Oct 2014 23:13:40 +0530 Subject: [PATCH 1561/9457] Staging: ft1000: ft1000-usb: Removed unnecessary parentheses Unnecessary parentheses around the right hand side of an assignment is removed using the following semantic patch: @@ identifier x,f; constant C; @@ ( -x = (f / C ); +x = f / C ; | -x = (f % C ); +x = f % C ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 37707da09e9c..7fb5c3f00632 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -837,7 +837,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, if (word_length & 0x1) word_length++; - word_length = (word_length / 2); + word_length = word_length / 2; for (; word_length > 0; word_length--) { /* In words */ @@ -871,7 +871,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, if (word_length & 0x1) word_length++; - word_length = (word_length / 2); + word_length = word_length / 2; for (; word_length > 0; word_length--) { /* In words */ -- GitLab From db9c9305701a2ee006d2a28770a7aa2dda70a087 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Sat, 25 Oct 2014 23:13:41 +0530 Subject: [PATCH 1562/9457] Staging: slicoss: Removed unnecessary parentheses Unnecessary parentheses around the right hand side of an assignment is removed using the following semantic patch: @@ identifier x,f; constant C; @@ ( -x = (f / C ); +x = f / C ; | -x = (f % C ); +x = f % C ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 71bc4edae322..cff7cbea526b 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1611,7 +1611,7 @@ static int slic_rcvqueue_init(struct adapter *adapter) rcvq->size = SLIC_RCVQ_ENTRIES; rcvq->errors = 0; rcvq->count = 0; - i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES); + i = SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES; count = 0; while (i) { count += slic_rcvqueue_fill(adapter); -- GitLab From 9fd4af8ab48a1485615eeb771d5461b4157ba079 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Sat, 25 Oct 2014 23:13:42 +0530 Subject: [PATCH 1563/9457] Staging: rts5208: Removed unnecessary parentheses Unnecessary parentheses around the right hand side of an assignment is removed using the following semantic patch: @@ identifier x,f; constant C; @@ ( -x = (f / C ); +x = f / C ; | -x = (f % C ); +x = f % C ; ) Signed-off-by: Tina Johnson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 0a67dca72dff..91fb61f61c91 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -539,7 +539,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); else - sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); + sg_cnt = HOST_SG_TBL_BUF_LEN / 8; chip->sgi = 0; for (j = 0; j < sg_cnt; j++) { -- GitLab From 87a979318faa1dac75fe28df9440efe6c1c9c28b Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 27 Oct 2014 19:56:06 +0530 Subject: [PATCH 1564/9457] Staging: rts5028: rtsx_transport.c: fixed a brace coding style issue. Removed unwanted braces using checkpatch.pl tool. Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_transport.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 91fb61f61c91..756a9687c293 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -728,15 +728,13 @@ int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) return -EIO; - if (use_sg) { + if (use_sg) err = rtsx_transfer_sglist_adma_partial(chip, card, (struct scatterlist *)buf, use_sg, index, offset, (int)len, dma_dir, timeout); - } else { + else err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); - } - if (err < 0) { if (RTSX_TST_DELINK(chip)) { RTSX_CLR_DELINK(chip); -- GitLab From 81a4e959f2011ecc9de133c509c37497800bf3bd Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 22:26:56 +0200 Subject: [PATCH 1565/9457] staging: vt6655: device.h: Comments fixes Replace C99 "//" comments by "/* */", remove not needed comments (year of adding code, commented code) Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 181 +++++++++++++++----------------- 1 file changed, 86 insertions(+), 95 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index ab6be41d4964..d769d092fb87 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -50,7 +50,6 @@ #include #include #include -//#include #include #include #include @@ -58,16 +57,13 @@ #include /* Include Wireless Extension definition and check version - Jean II */ #include -#include // New driver API +#include /* New driver API */ -//2008-0409-07, by Einsn Liu #ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #endif -// -// device specific -// +/* device specific */ #include "device_cfg.h" #include "ttype.h" @@ -112,7 +108,7 @@ #define FB_RATE0 0 #define FB_RATE1 1 -// Antenna Mode +/* Antenna Mode */ #define ANT_A 0 #define ANT_B 1 #define ANT_DIVERSITY 2 @@ -129,10 +125,10 @@ #define RUN_AT(x) (jiffies+(x)) #endif -// DMA related +/* DMA related */ #define RESERV_AC0DMA 4 -// BUILD OBJ mode +/* BUILD OBJ mode */ #define AVAIL_TD(p, q) ((p)->sOpts.nTxDescs[(q)] - ((p)->iTDUsed[(q)])) @@ -148,7 +144,7 @@ do { \ printk(p, ##args); \ } while (0) -//0:11A 1:11B 2:11G +/* 0:11A 1:11B 2:11G */ typedef enum _VIA_BB_TYPE { BB_TYPE_11A = 0, @@ -156,7 +152,7 @@ typedef enum _VIA_BB_TYPE BB_TYPE_11G } VIA_BB_TYPE, *PVIA_BB_TYPE; -//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) +/* 0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) */ typedef enum _VIA_PKT_TYPE { PK_TYPE_11A = 0, @@ -166,21 +162,20 @@ typedef enum _VIA_PKT_TYPE } VIA_PKT_TYPE, *PVIA_PKT_TYPE; typedef enum __device_msg_level { - MSG_LEVEL_ERR = 0, //Errors that will cause abnormal operation. - MSG_LEVEL_NOTICE = 1, //Some errors need users to be notified. - MSG_LEVEL_INFO = 2, //Normal message. - MSG_LEVEL_VERBOSE = 3, //Will report all trival errors. - MSG_LEVEL_DEBUG = 4 //Only for debug purpose. + MSG_LEVEL_ERR = 0, /* Errors that will cause abnormal operation. */ + MSG_LEVEL_NOTICE = 1, /* Some errors need users to be notified. */ + MSG_LEVEL_INFO = 2, /* Normal message. */ + MSG_LEVEL_VERBOSE = 3, /* Will report all trival errors. */ + MSG_LEVEL_DEBUG = 4 /* Only for debug purpose. */ } DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL; -//++ NDIS related - +/* NDIS related */ #define MAX_BSSIDINFO_4_PMKID 16 #define MAX_PMKIDLIST 5 -//Flags for PMKID Candidate list structure +/* Flags for PMKID Candidate list structure */ #define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -// PMKID Structures +/* PMKID Structures */ typedef unsigned char NDIS_802_11_PMKID_VALUE[16]; typedef enum _NDIS_802_11_WEP_STATUS { @@ -203,10 +198,10 @@ typedef enum _NDIS_802_11_STATUS_TYPE { Ndis802_11StatusType_Authentication, Ndis802_11StatusType_MediaStreamMode, Ndis802_11StatusType_PMKID_CandidateList, - Ndis802_11StatusTypeMax // not a real type, defined as an upper bound + Ndis802_11StatusTypeMax /* defined as an upper bound */ } NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; -//Added new types for PMKID Candidate lists. +/* Added new types for PMKID Candidate lists. */ struct pmkid_candidate { NDIS_802_11_MAC_ADDRESS BSSID; unsigned long Flags; @@ -225,14 +220,12 @@ typedef struct tagSPMKID { typedef struct tagSPMKIDCandidateEvent { NDIS_802_11_STATUS_TYPE StatusType; - unsigned long Version; // Version of the structure - unsigned long NumCandidates; // No. of pmkid candidates + unsigned long Version; /* Version of the structure */ + unsigned long NumCandidates; /* No. of pmkid candidates */ struct pmkid_candidate CandidateList[MAX_PMKIDLIST]; } SPMKIDCandidateEvent, *PSPMKIDCandidateEvent; -//-- - -//++ 802.11h related +/* 802.11h related */ #define MAX_QUIET_COUNT 8 typedef struct tagSQuietControl { @@ -242,7 +235,6 @@ typedef struct tagSQuietControl { unsigned short wDuration; } SQuietControl, *PSQuietControl; -//-- typedef struct __chip_info_tbl { CHIP_TYPE chip_id; char *name; @@ -256,22 +248,22 @@ typedef enum { OWNED_BY_NIC = 1 } DEVICE_OWNER_TYPE, *PDEVICE_OWNER_TYPE; -// The receive duplicate detection cache entry +/* The receive duplicate detection cache entry */ typedef struct tagSCacheEntry { unsigned short wFmSequence; unsigned char abyAddr2[ETH_ALEN]; } SCacheEntry, *PSCacheEntry; typedef struct tagSCache { -/* The receive cache is updated circularly. The next entry to be written is +/* The receive cache is updated circularly. The next entry to be written is * indexed by the "InPtr". */ - unsigned int uInPtr; // Place to use next + unsigned int uInPtr; /* Place to use next */ SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; } SCache, *PSCache; #define CB_MAX_RX_FRAG 64 -// DeFragment Control Block, used for collecting fragments prior to reassembly +/* DeFragment Control Block, used for collecting fragments prior to reassembly */ typedef struct tagSDeFragControlBlock { unsigned short wSequence; unsigned short wFragNum; @@ -283,7 +275,7 @@ typedef struct tagSDeFragControlBlock { bool bInUse; } SDeFragControlBlock, *PSDeFragControlBlock; -//flags for options +/* flags for options */ #define DEVICE_FLAGS_IP_ALIGN 0x00000001UL #define DEVICE_FLAGS_PREAMBLE_TYPE 0x00000002UL #define DEVICE_FLAGS_OP_MODE 0x00000004UL @@ -291,15 +283,15 @@ typedef struct tagSDeFragControlBlock { #define DEVICE_FLAGS_80211h_MODE 0x00000010UL #define DEVICE_FLAGS_DiversityANT 0x00000020UL -//flags for driver status +/* flags for driver status */ #define DEVICE_FLAGS_OPENED 0x00010000UL #define DEVICE_FLAGS_WOL_ENABLED 0x00080000UL -//flags for capabilities +/* flags for capabilities */ #define DEVICE_FLAGS_TX_ALIGN 0x01000000UL #define DEVICE_FLAGS_HAVE_CAM 0x02000000UL #define DEVICE_FLAGS_FLOW_CTRL 0x04000000UL -//flags for MII status +/* flags for MII status */ #define DEVICE_LINK_FAIL 0x00000001UL #define DEVICE_SPEED_10 0x00000002UL #define DEVICE_SPEED_100 0x00000004UL @@ -307,15 +299,15 @@ typedef struct tagSDeFragControlBlock { #define DEVICE_DUPLEX_FULL 0x00000010UL #define DEVICE_AUTONEG_ENABLE 0x00000020UL #define DEVICE_FORCED_BY_EEPROM 0x00000040UL -//for device_set_media_duplex +/* for device_set_media_duplex */ #define DEVICE_LINK_CHANGE 0x00000001UL typedef struct __device_opt { - int nRxDescs0; //Number of RX descriptors0 - int nRxDescs1; //Number of RX descriptors1 - int nTxDescs[2]; //Number of TX descriptors 0, 1 - int int_works; //interrupt limits - int rts_thresh; //rts threshold + int nRxDescs0; /* Number of RX descriptors0 */ + int nRxDescs1; /* Number of RX descriptors1 */ + int nTxDescs[2]; /* Number of TX descriptors 0, 1 */ + int int_works; /* interrupt limits */ + int rts_thresh; /* rts threshold */ int frag_thresh; int data_rate; int channel_num; @@ -328,10 +320,10 @@ typedef struct __device_opt { struct vnt_private { struct pci_dev *pcid; -// netdev +/* netdev */ struct net_device *dev; -//dma addr, rx/tx pool +/* dma addr, rx/tx pool */ dma_addr_t pool_dma; dma_addr_t rd0_pool_dma; dma_addr_t rd1_pool_dma; @@ -394,7 +386,7 @@ struct vnt_private { u32 rx_bytes; - // Version control + /* Version control */ unsigned char byLocalID; unsigned char byRFType; @@ -404,18 +396,18 @@ struct vnt_private { unsigned char byOriginalZonetype; unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; unsigned char abyCurrentNetAddr[ETH_ALEN]; - bool bLinkPass; // link status: OK or fail + bool bLinkPass; /* link status: OK or fail */ - // Adapter statistics + /* Adapter statistics */ SStatCounter scStatistic; - // 802.11 counter + /* 802.11 counter */ SDot11Counters s802_11Counter; - // 802.11 management + /* 802.11 management */ PSMgmtObject pMgmt; SMgmtObject sMgmtObj; - // 802.11 MAC specific + /* 802.11 MAC specific */ unsigned int uCurrRSSI; unsigned char byCurrSQ; @@ -427,22 +419,26 @@ struct vnt_private { bool bTxRxAntInv; unsigned char *pbyTmpBuff; - unsigned int uSIFS; //Current SIFS - unsigned int uDIFS; //Current DIFS - unsigned int uEIFS; //Current EIFS - unsigned int uSlot; //Current SlotTime - unsigned int uCwMin; //Current CwMin - unsigned int uCwMax; //CwMax is fixed on 1023. - // PHY parameter + unsigned int uSIFS; /* Current SIFS */ + unsigned int uDIFS; /* Current DIFS */ + unsigned int uEIFS; /* Current EIFS */ + unsigned int uSlot; /* Current SlotTime */ + unsigned int uCwMin; /* Current CwMin */ + unsigned int uCwMax; /* CwMax is fixed on 1023. */ + /* PHY parameter */ unsigned char bySIFS; unsigned char byDIFS; unsigned char byEIFS; unsigned char bySlot; unsigned char byCWMaxMin; - CARD_PHY_TYPE eCurrentPHYType; - - VIA_BB_TYPE byBBType; //0: 11A, 1:11B, 2:11G - VIA_PKT_TYPE byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate) + CARD_PHY_TYPE eCurrentPHYType; + + VIA_BB_TYPE byBBType; /* 0:11A, 1:11B, 2:11G */ + VIA_PKT_TYPE byPacketType; /* + * 0:11a,1:11b,2:11gb (only CCK + * in BasicRate), 3:11ga (OFDM in + * Basic Rate) + */ unsigned short wBasicRate; unsigned char byACKRate; unsigned char byTopOFDMBasicRate; @@ -466,12 +462,12 @@ struct vnt_private { unsigned short wMaxTransmitMSDULifetime; unsigned char abyBSSID[ETH_ALEN]; unsigned char abyDesireBSSID[ETH_ALEN]; - unsigned short wACKDuration; // update while speed change - unsigned short wRTSTransmitLen; // update while speed change - unsigned char byRTSServiceField; // update while speed change - unsigned char byRTSSignalField; // update while speed change + unsigned short wACKDuration; /* update while speed change */ + unsigned short wRTSTransmitLen; /* update while speed change */ + unsigned char byRTSServiceField; /* update while speed change */ + unsigned char byRTSSignalField; /* update while speed change */ - unsigned long dwMaxReceiveLifetime; // dot11MaxReceiveLifetime + unsigned long dwMaxReceiveLifetime; /* dot11MaxReceiveLifetime */ bool bEncryptionEnable; bool bLongHeader; @@ -490,14 +486,14 @@ struct vnt_private { bool bPWBitOn; WMAC_POWER_MODE ePSMode; - // GPIO Radio Control + /* GPIO Radio Control */ unsigned char byRadioCtl; unsigned char byGPIO; bool bHWRadioOff; bool bPrvActive4RadioOFF; bool bGPIOBlockRead; - // Beacon related + /* Beacon related */ unsigned short wSeqCounter; unsigned short wBCNBufLen; bool bBeaconBufReady; @@ -518,7 +514,7 @@ struct vnt_private { bool bStopTx0Pkt; unsigned int uAutoReConnectTime; - // 802.11 counter + /* 802.11 counter */ CMD_ITEM eCmdQueue[CMD_Q_SIZE]; unsigned int uCmdDequeueIdx; @@ -528,14 +524,11 @@ struct vnt_private { bool bCmdClear; bool bRoaming; - //WOW unsigned char abyIPAddr[4]; unsigned long ulTxPower; NDIS_802_11_WEP_STATUS eEncryptionStatus; bool bTransmitKey; -//2007-0925-01by MikeLiu -//mike add :save old Encryption NDIS_802_11_WEP_STATUS eOldEncryptionStatus; SKeyManagement sKey; @@ -553,14 +546,14 @@ struct vnt_private { bool bAES; unsigned char byCntMeasure; - // for AP mode + /* for AP mode */ unsigned int uAssocCount; bool bMoreData; - // QoS + /* QoS */ bool bGrpAckPolicy; - // for OID_802_11_ASSOCIATION_INFORMATION + /* for OID_802_11_ASSOCIATION_INFORMATION */ bool bAssocInfoSet; unsigned char byAutoFBCtrl; @@ -570,7 +563,7 @@ struct vnt_private { unsigned int uRATEIdx; - // For Update BaseBand VGA Gain Offset + /* For Update BaseBand VGA Gain Offset */ bool bUpdateBBVGA; unsigned int uBBVGADiffCount; unsigned char byBBVGANew; @@ -584,11 +577,10 @@ struct vnt_private { bool bRadioCmd; unsigned long dwDiagRefCount; - // For FOE Tuning + /* For FOE Tuning */ unsigned char byFOETuning; - // For Auto Power Tunning - + /* For Auto Power Tunning */ unsigned char byAutoPwrTunning; short sPSetPointCCK; short sPSetPointOFDMG; @@ -598,7 +590,7 @@ struct vnt_private { char cAdjustStep; char cMinTxAGC; - // For RF Power table + /* For RF Power table */ unsigned char byCCKPwr; unsigned char byOFDMPwrG; unsigned char byCurPwr; @@ -610,13 +602,13 @@ struct vnt_private { char abyRegPwr[CB_MAX_CHANNEL+1]; char abyLocalPwr[CB_MAX_CHANNEL+1]; - // BaseBand Loopback Use + /* BaseBand Loopback Use */ unsigned char byBBCR4d; unsigned char byBBCRc9; unsigned char byBBCR88; unsigned char byBBCR09; - // command timer + /* command timer */ struct timer_list sTimerCommand; struct timer_list sTimerTxData; unsigned long nTxDataTimeCout; @@ -624,9 +616,9 @@ struct vnt_private { bool IsTxDataTrigger; #ifdef WPA_SM_Transtatus - bool fWPA_Authened; //is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? + bool fWPA_Authened; /* is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */ #endif - unsigned char byReAssocCount; //mike add:re-association retry times! + unsigned char byReAssocCount; unsigned char byLinkWaitCount; unsigned char abyNodeName[17]; @@ -640,13 +632,13 @@ struct vnt_private { unsigned char byTMax3; unsigned long ulSQ3TH; -// ANT diversity + /* ANT diversity */ unsigned long uDiversityCnt; unsigned char byAntennaState; unsigned long ulRatio_State0; unsigned long ulRatio_State1; - //SQ3 functions for antenna diversity + /* SQ3 functions for antenna diversity */ struct timer_list TimerSQ3Tmax1; struct timer_list TimerSQ3Tmax2; struct timer_list TimerSQ3Tmax3; @@ -659,15 +651,15 @@ struct vnt_private { unsigned char abyBroadcastAddr[ETH_ALEN]; unsigned char abySNAP_RFC1042[ETH_ALEN]; unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; - unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; //unsigned long alignment - // Pre-Authentication & PMK cache + unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ + /* Pre-Authentication & PMK cache */ SPMKID gsPMKID; SPMKIDCandidateEvent gsPMKIDCandidate; - // for 802.11h + /* for 802.11h */ bool b11hEnable; unsigned char abyCountryCode[3]; - // for 802.11h DFS + /* for 802.11h DFS */ unsigned int uNumOfMeasureEIDs; PWLAN_IE_MEASURE_REQ pCurrMeasureEID; bool bMeasureInProgress; @@ -688,13 +680,13 @@ struct vnt_private { unsigned int uQuietEnqueue; unsigned long dwCurrentQuietEndTime; SQuietControl sQuiet[MAX_QUIET_COUNT]; - // for 802.11h TPC + /* for 802.11h TPC */ bool bCountryInfo5G; bool bCountryInfo24G; unsigned short wBeaconInterval; - //WPA supplicant deamon + /* WPA supplicant deamon */ struct net_device *wpadev; bool bWPADEVUp; struct sk_buff *skb; @@ -703,9 +695,8 @@ struct vnt_private { bool bWPASuppWextEnabled; #endif - //-- #ifdef HOSTAP - // user space daemon: hostapd, is used for HOSTAP + /* user space daemon: hostapd, is used for HOSTAP */ bool bEnableHostapd; bool bEnable8021x; bool bEnableHostWEP; @@ -715,7 +706,7 @@ struct vnt_private { unsigned int uChannel; bool bMACSuspend; - struct iw_statistics wstats; // wireless stats + struct iw_statistics wstats; /* wireless stats */ bool bCommit; }; -- GitLab From 77b6a6a3f52e980f91a471f3d3a99671292355b0 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 22:34:38 +0200 Subject: [PATCH 1566/9457] staging: vt6655: card.c: Comments fixes Replace C99 "//" comments by "/* */", remove not needed comments (year of adding code, commented code) Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 296 +++++++++++++++------------------- 1 file changed, 126 insertions(+), 170 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index f2a33a9742c6..eae67897a615 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -59,28 +59,28 @@ /*--------------------- Static Definitions -------------------------*/ -#define C_SIFS_A 16 // micro sec. +#define C_SIFS_A 16 /* micro sec. */ #define C_SIFS_BG 10 -#define C_EIFS 80 // micro sec. +#define C_EIFS 80 /* micro sec. */ -#define C_SLOT_SHORT 9 // micro sec. +#define C_SLOT_SHORT 9 /* micro sec. */ #define C_SLOT_LONG 20 -#define C_CWMIN_A 15 // slot time +#define C_CWMIN_A 15 /* slot time */ #define C_CWMIN_B 31 -#define C_CWMAX 1023 // slot time +#define C_CWMAX 1023 /* slot time */ -#define WAIT_BEACON_TX_DOWN_TMO 3 // Times +#define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ -//1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M +/* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M */ static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; -//6M, 9M, 12M, 48M +/* 6M, 9M, 12M, 48M */ static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; -//6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M +/* 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M */ static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; -//1M, 2M, 5M, 11M, +/* 1M, 2M, 5M, 11M, */ static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; /*--------------------- Static Variables --------------------------*/ @@ -113,7 +113,6 @@ s_vCalculateOFDMRParameter( * pbyRsvTime - pointer to RSPINF RsvTime field * * Return Value: none - * */ static void @@ -126,7 +125,7 @@ s_vCalculateOFDMRParameter( { switch (byRate) { case RATE_6M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9B; *pbyRsvTime = 44; } else { @@ -136,7 +135,7 @@ s_vCalculateOFDMRParameter( break; case RATE_9M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9F; *pbyRsvTime = 36; } else { @@ -146,7 +145,7 @@ s_vCalculateOFDMRParameter( break; case RATE_12M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9A; *pbyRsvTime = 32; } else { @@ -156,7 +155,7 @@ s_vCalculateOFDMRParameter( break; case RATE_18M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9E; *pbyRsvTime = 28; } else { @@ -166,7 +165,7 @@ s_vCalculateOFDMRParameter( break; case RATE_36M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9D; *pbyRsvTime = 24; } else { @@ -176,7 +175,7 @@ s_vCalculateOFDMRParameter( break; case RATE_48M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x98; *pbyRsvTime = 24; } else { @@ -186,7 +185,7 @@ s_vCalculateOFDMRParameter( break; case RATE_54M: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x9C; *pbyRsvTime = 24; } else { @@ -197,7 +196,7 @@ s_vCalculateOFDMRParameter( case RATE_24M: default: - if (ePHYType == PHY_TYPE_11A) {//5GHZ + if (ePHYType == PHY_TYPE_11A) { /* 5GHZ */ *pbyTxRate = 0x99; *pbyRsvTime = 28; } else { @@ -218,7 +217,6 @@ s_vCalculateOFDMRParameter( * none * * Return Value: None. - * */ static void @@ -226,9 +224,9 @@ s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs) { union vnt_phy_field_swap phy; - unsigned char byTxRate = 0, byRsvTime = 0; // For OFDM + unsigned char byTxRate = 0, byRsvTime = 0; /* For OFDM */ - //Set to Page1 + /* Set to Page1 */ MACvSelectPage1(pDevice->PortOffset); /* RSPINF_b_1 */ @@ -270,60 +268,60 @@ s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); - //RSPINF_a_6 + /* RSPINF_a_6 */ s_vCalculateOFDMRParameter(RATE_6M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_9 + /* RSPINF_a_9 */ s_vCalculateOFDMRParameter(RATE_9M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_12 + /* RSPINF_a_12 */ s_vCalculateOFDMRParameter(RATE_12M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_18 + /* RSPINF_a_18 */ s_vCalculateOFDMRParameter(RATE_18M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_24 + /* RSPINF_a_24 */ s_vCalculateOFDMRParameter(RATE_24M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_36 + /* RSPINF_a_36 */ s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_48 + /* RSPINF_a_48 */ s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_54 + /* RSPINF_a_54 */ s_vCalculateOFDMRParameter( VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_72 + /* RSPINF_a_72 */ VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); - //Set to Page0 + /* Set to Page0 */ MACvSelectPage0(pDevice->PortOffset); } @@ -339,7 +337,6 @@ s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, * none * * Return Value: true if short preamble; otherwise false - * */ bool CARDbIsShortPreamble(struct vnt_private *pDevice) { @@ -360,7 +357,6 @@ bool CARDbIsShortPreamble(struct vnt_private *pDevice) * none * * Return Value: true if short slot time; otherwise false - * */ bool CARDbIsShorSlotTime(struct vnt_private *pDevice) { @@ -378,7 +374,6 @@ bool CARDbIsShorSlotTime(struct vnt_private *pDevice) * none * * Return Value: None. - * */ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, @@ -392,13 +387,13 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs; PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs; - //Set SIFS, DIFS, EIFS, SlotTime, CwMin + /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ if (ePHYType == PHY_TYPE_11A) { if (pSupportRates == NULL) pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA; if (pDevice->byRFType == RF_AIROHA7230) { - // AL7230 use single PAPE and connect to PAPE_2.4G + /* AL7230 use single PAPE and connect to PAPE_2.4G */ MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); pDevice->abyBBVGA[0] = 0x20; pDevice->abyBBVGA[2] = 0x10; @@ -449,7 +444,7 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, bySIFS = C_SIFS_BG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; byCWMaxMin = 0xA5; - } else {// PK_TYPE_11GA & PK_TYPE_11GB + } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ if (pSupportRates == NULL) { pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG; pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG; @@ -503,13 +498,17 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, } if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us - // hardware's processing time here is 2 us. + /* + * bcs TX_PE will reserve 3 us hardware's processing + * time here is 2 us. + */ bySIFS -= 3; byDIFS -= 3; - //{{ RobertYu: 20041202 - //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput - //// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us. + /* + * TX_PE will reserve 3 us for MAX2829 A mode only, it is for + * better TX throughput; MAC will need 2 us to process, so the + * SIFS, DIFS can be shorter by 2 us. + */ } if (pDevice->bySIFS != bySIFS) { @@ -545,7 +544,7 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates); pDevice->eCurrentPHYType = ePHYType; - // set for NDIS OID_802_11SUPPORTED_RATES + /* set for NDIS OID_802_11SUPPORTED_RATES */ return true; } @@ -563,7 +562,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, * none * * Return Value: none - * */ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF) @@ -572,8 +570,7 @@ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, if (qwBSSTimestamp != qwLocalTSF) { qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); - // adjust TSF - // HW's TSF add TSF Offset reg + /* adjust TSF, HW's TSF add TSF Offset reg */ VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset); VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32)); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); @@ -593,21 +590,20 @@ bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, * none * * Return Value: true if succeed; otherwise false - * */ bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, unsigned short wBeaconInterval) { u64 qwNextTBTT = 0; - CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter + CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); /* Get Local TSF counter */ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); - // set HW beacon interval + /* set HW beacon interval */ VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); pDevice->wBeaconInterval = wBeaconInterval; - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); @@ -626,7 +622,6 @@ bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, * none * * Return Value: true if all data packet complete; otherwise false. - * */ bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) { @@ -654,12 +649,12 @@ bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) pDevice->cbBeaconBufReadySetCnt = 0; MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); } - // wait all TD0 complete + /* wait all TD0 complete */ if (pDevice->bStopTx0Pkt == true) { if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) return false; } - // wait all Data TD complete + /* wait all Data TD complete */ if (pDevice->bStopDataPkt == true) { if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) return false; @@ -679,7 +674,6 @@ bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) * none * * Return Value: true if success; false if failed. - * */ bool CARDbStartTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) { @@ -717,7 +711,6 @@ bool CARDbStartTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) * none * * Return Value: true if success; false if failed. - * */ bool CARDbSetBSSID(struct vnt_private *pDevice, unsigned char *pbyBSSID, enum nl80211_iftype op_mode) @@ -748,7 +741,7 @@ bool CARDbSetBSSID(struct vnt_private *pDevice, } pr_debug("wmgr: rx_mode = %x\n", pDevice->byRxMode); } - // Adopt BSS state in Adapter Device Object + /* Adopt BSS state in Adapter Device Object */ pDevice->op_mode = op_mode; return true; } @@ -764,7 +757,6 @@ bool CARDbSetBSSID(struct vnt_private *pDevice, * none * * Return Value: true if success; false if failed. - * */ /* @@ -782,7 +774,6 @@ bool CARDbSetBSSID(struct vnt_private *pDevice, * none * * Return Value: true if succeed; otherwise false - * */ bool CARDbSetTxDataRate( struct vnt_private *pDevice, @@ -794,8 +785,7 @@ bool CARDbSetTxDataRate( return true; } -/*+ - * +/* * Routine Description: * Consider to power down when no more packets to tx or rx. * @@ -806,8 +796,7 @@ bool CARDbSetTxDataRate( * none * * Return Value: true if power down success; otherwise false - * - -*/ + */ bool CARDbPowerDown( struct vnt_private *pDevice @@ -815,14 +804,14 @@ CARDbPowerDown( { unsigned int uIdx; - // check if already in Doze mode + /* check if already in Doze mode */ if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) return true; - // Froce PSEN on + /* Froce PSEN on */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - // check if all TD are empty, + /* check if all TD are empty */ for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { if (pDevice->iTDUsed[uIdx] != 0) @@ -844,7 +833,6 @@ CARDbPowerDown( * none * * Return Value: true if success; otherwise false - * */ bool CARDbRadioPowerOff(struct vnt_private *pDevice) { @@ -861,7 +849,7 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) case RF_AIROHA: case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 + case RF_AIROHA7230: MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2); MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); break; @@ -873,9 +861,8 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID); pDevice->bRadioOff = true; - //2007-0409-03, by chester pr_debug("chester power off\n"); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ return bResult; } @@ -889,7 +876,6 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) * none * * Return Value: true if success; otherwise false - * */ bool CARDbRadioPowerOn(struct vnt_private *pDevice) { @@ -919,7 +905,7 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) case RF_AIROHA: case RF_AL2230S: - case RF_AIROHA7230: //RobertYu:20050104 + case RF_AIROHA7230: MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); break; @@ -927,9 +913,8 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) } pDevice->bRadioOff = false; -// 2007-0409-03, by chester pr_debug("chester power on\n"); - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue + MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ return bResult; } @@ -941,7 +926,6 @@ bool CARDbRemoveKey(struct vnt_private *pDevice, unsigned char *pbyBSSID) } /* - * * Description: * Add BSSID in PMKID Candidate list. * @@ -954,8 +938,7 @@ bool CARDbRemoveKey(struct vnt_private *pDevice, unsigned char *pbyBSSID) * none * * Return Value: none. - * - -*/ + */ bool CARDbAdd_PMKID_Candidate( struct vnt_private *pDevice, @@ -980,7 +963,7 @@ CARDbAdd_PMKID_Candidate( pr_debug("\n"); - // Update Old Candidate + /* Update Old Candidate */ for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { @@ -993,7 +976,7 @@ CARDbAdd_PMKID_Candidate( } } - // New Candidate + /* New Candidate */ pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; if (bRSNCapExist && (wRSNCap & BIT0)) pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; @@ -1017,7 +1000,6 @@ CARDpGetCurrentAddress( } /* - * * Description: * Start Spectrum Measure defined in 802.11h * @@ -1028,8 +1010,7 @@ CARDpGetCurrentAddress( * none * * Return Value: none. - * - -*/ + */ bool CARDbStartMeasure( struct vnt_private *pDevice, @@ -1054,7 +1035,7 @@ CARDbStartMeasure( MACvSelectPage1(pDevice->PortOffset); VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - // clear measure control + /* clear measure control */ MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); MACvSelectPage0(pDevice->PortOffset); set_channel(pDevice, pDevice->byOrgChannel); @@ -1072,16 +1053,16 @@ CARDbStartMeasure( if (pDevice->byLocalID > REV_ID_VT3253_B1) { qwStartTSF = *((u64 *)(pDevice->pCurrMeasureEID->sReq.abyStartTime)); wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); - wDuration += 1; // 1 TU for channel switching + wDuration += 1; /* 1 TU for channel switching */ if (qwStartTSF == 0) { - // start immediately by setting start TSF == current TSF + 2 TU + /* start immediately by setting start TSF == current TSF + 2 TU */ qwStartTSF = qwCurrTSF + 2048; bExpired = false; break; } else { - // start at setting start TSF - 1TU(for channel switching) + /* start at setting start TSF - 1TU(for channel switching) */ qwStartTSF -= 1024; } @@ -1098,7 +1079,7 @@ CARDbStartMeasure( pDevice->abyRPIs ); } else { - // hardware do not support measure + /* hardware do not support measure */ VNTWIFIbMeasureReport(pDevice->pMgmt, false, pDevice->pCurrMeasureEID, @@ -1118,7 +1099,7 @@ CARDbStartMeasure( MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); MACvSelectPage0(pDevice->PortOffset); } else { - // all measure start time expired we should complete action + /* all measure start time expired we should complete action */ VNTWIFIbMeasureReport(pDevice->pMgmt, true, NULL, @@ -1132,7 +1113,6 @@ CARDbStartMeasure( } /* - * * Description: * Do Channel Switch defined in 802.11h * @@ -1143,8 +1123,7 @@ CARDbStartMeasure( * none * * Return Value: none. - * - -*/ + */ bool CARDbChannelSwitch( struct vnt_private *pDevice, @@ -1173,7 +1152,6 @@ CARDbChannelSwitch( } /* - * * Description: * Handle Quiet EID defined in 802.11h * @@ -1184,8 +1162,7 @@ CARDbChannelSwitch( * none * * Return Value: none. - * - -*/ + */ bool CARDbSetQuiet( struct vnt_private *pDevice, @@ -1224,7 +1201,6 @@ CARDbSetQuiet( } /* - * * Description: * Do Quiet, It will be called by either ISR(after start) * or VNTWIFI(before start) so we do not need a SPINLOCK @@ -1236,8 +1212,7 @@ CARDbSetQuiet( * none * * Return Value: none. - * - -*/ + */ bool CARDbStartQuiet( struct vnt_private *pDevice @@ -1258,12 +1233,12 @@ CARDbStartQuiet( } } if (dwStartTime == 0xFFFFFFFF) { - // no more quiet + /* no more quiet */ pDevice->bQuietEnable = false; MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); } else { if (pDevice->bQuietEnable == false) { - // first quiet + /* first quiet */ pDevice->byQuietStartCount--; dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; dwNextTime %= pDevice->wBeaconInterval; @@ -1279,10 +1254,14 @@ CARDbStartQuiet( MACvSelectPage0(pDevice->PortOffset); } else { if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) { - // overlap with previous Quiet + /* overlap with previous Quiet */ dwGap = pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) { - // return false to indicate next quiet expired, should call this function again + /* + * return false to indicate next quiet + * expired, should call this function + * again + */ return false; } dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap; @@ -1291,7 +1270,7 @@ CARDbStartQuiet( dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime; dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration; } - // set GAP and Next duration + /* set GAP and Next duration */ MACvSelectPage1(pDevice->PortOffset); VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap); VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration); @@ -1302,16 +1281,16 @@ CARDbStartQuiet( pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration; if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) { - // not period disable current quiet element + /* not period disable current quiet element */ pDevice->sQuiet[uCurrentQuietIndex].bEnable = false; } else { - // set next period start time + /* set next period start time */ dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod; dwNextTime *= pDevice->wBeaconInterval; pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime; } if (pDevice->dwCurrentQuietEndTime > 0x80010000) { - // decreament all time to avoid wrap around + /* decreament all time to avoid wrap around */ for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { if (pDevice->sQuiet[ii].bEnable == true) pDevice->sQuiet[ii].dwStartTime -= 0x80000000; @@ -1324,7 +1303,6 @@ CARDbStartQuiet( } /* - * * Description: * Set Local Power Constraint * @@ -1335,8 +1313,7 @@ CARDbStartQuiet( * none * * Return Value: none. - * - -*/ + */ void CARDvSetPowerConstraint( struct vnt_private *pDevice, @@ -1357,7 +1334,6 @@ CARDvSetPowerConstraint( } /* - * * Description: * Set Local Power Constraint * @@ -1368,8 +1344,7 @@ CARDvSetPowerConstraint( * none * * Return Value: none. - * - -*/ + */ void CARDvGetPowerCapability( struct vnt_private *pDevice, @@ -1391,7 +1366,6 @@ CARDvGetPowerCapability( } /* - * * Description: * Get Current Tx Power * @@ -1402,7 +1376,6 @@ CARDvGetPowerCapability( * none * * Return Value: none. - * */ char CARDbyGetTransmitPower( @@ -1413,7 +1386,6 @@ CARDbyGetTransmitPower( return pDevice->byCurPwrdBm; } -//xxx void CARDvSafeResetTx( struct vnt_private *pDevice @@ -1422,7 +1394,7 @@ CARDvSafeResetTx( unsigned int uu; PSTxDesc pCurrTD; - // initialize TD index + /* initialize TD index */ pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); @@ -1432,28 +1404,27 @@ CARDvSafeResetTx( for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) { pCurrTD = &(pDevice->apTD0Rings[uu]); pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL + /* init all Tx Packet pointer to NULL */ } for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) { pCurrTD = &(pDevice->apTD1Rings[uu]); pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST; - // init all Tx Packet pointer to NULL + /* init all Tx Packet pointer to NULL */ } - // set MAC TD pointer + /* set MAC TD pointer */ MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset, (pDevice->td0_pool_dma)); MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset, (pDevice->td1_pool_dma)); - // set MAC Beacon TX pointer + /* set MAC Beacon TX pointer */ MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); } -/*+ - * +/* * Description: * Reset Rx * @@ -1464,8 +1435,7 @@ CARDvSafeResetTx( * none * * Return Value: none - * - -*/ + */ void CARDvSafeResetRx( struct vnt_private *pDevice @@ -1474,11 +1444,11 @@ CARDvSafeResetRx( unsigned int uu; PSRxDesc pDesc; - // initialize RD index + /* initialize RD index */ pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); - // init state, all RD is chip's + /* init state, all RD is chip's */ for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) { pDesc = &(pDevice->aRD0Ring[uu]); pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); @@ -1486,7 +1456,7 @@ CARDvSafeResetRx( pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz); } - // init state, all RD is chip's + /* init state, all RD is chip's */ for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) { pDesc = &(pDevice->aRD1Ring[uu]); pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz); @@ -1497,10 +1467,10 @@ CARDvSafeResetRx( pDevice->cbDFCB = CB_MAX_RX_FRAG; pDevice->cbFreeDFCB = pDevice->cbDFCB; - // set perPkt mode + /* set perPkt mode */ MACvRx0PerPktMode(pDevice->PortOffset); MACvRx1PerPktMode(pDevice->PortOffset); - // set MAC RD pointer + /* set MAC RD pointer */ MACvSetCurrRx0DescAddr(pDevice->PortOffset, pDevice->rd0_pool_dma); @@ -1519,7 +1489,6 @@ CARDvSafeResetRx( * none * * Return Value: response Control frame rate - * */ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, unsigned short wRateIdx) @@ -1546,7 +1515,6 @@ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, * none * * Return Value: response Control frame rate - * */ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, unsigned short wRateIdx) @@ -1582,14 +1550,13 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, * none * * Return Value: None. - * */ void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) { union vnt_phy_field_swap phy; - unsigned char byTxRate, byRsvTime; //For OFDM + unsigned char byTxRate, byRsvTime; /* For OFDM */ - //Set to Page1 + /* Set to Page1 */ MACvSelectPage1(pDevice->PortOffset); /* RSPINF_b_1 */ @@ -1629,62 +1596,61 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); - //RSPINF_a_6 + /* RSPINF_a_6 */ s_vCalculateOFDMRParameter(RATE_6M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_9 + /* RSPINF_a_9 */ s_vCalculateOFDMRParameter(RATE_9M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_12 + /* RSPINF_a_12 */ s_vCalculateOFDMRParameter(RATE_12M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_18 + /* RSPINF_a_18 */ s_vCalculateOFDMRParameter(RATE_18M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_24 + /* RSPINF_a_24 */ s_vCalculateOFDMRParameter(RATE_24M, ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_36 + /* RSPINF_a_36 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_48 + /* RSPINF_a_48 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); - //RSPINF_a_54 + /* RSPINF_a_54 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); - - //RSPINF_a_72 + /* RSPINF_a_72 */ s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); - //Set to Page0 + /* Set to Page0 */ MACvSelectPage0(pDevice->PortOffset); } @@ -1698,7 +1664,6 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) * none * * Return Value: None. - * */ void vUpdateIFS(struct vnt_private *pDevice) { @@ -1706,19 +1671,20 @@ void vUpdateIFS(struct vnt_private *pDevice) unsigned char byMaxMin = 0; - if (pDevice->byPacketType == PK_TYPE_11A) {//0000 0000 0000 0000,11a + if (pDevice->byPacketType == PK_TYPE_11A) { /*0000 0000 0000 0000,11a*/ pDevice->uSlot = C_SLOT_SHORT; pDevice->uSIFS = C_SIFS_A; pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT; pDevice->uCwMin = C_CWMIN_A; byMaxMin = 4; - } else if (pDevice->byPacketType == PK_TYPE_11B) {//0000 0001 0000 0000,11b + } else if (pDevice->byPacketType == PK_TYPE_11B) { + /* 0000 0001 0000 0000,11b */ pDevice->uSlot = C_SLOT_LONG; pDevice->uSIFS = C_SIFS_BG; pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG; pDevice->uCwMin = C_CWMIN_B; byMaxMin = 5; - } else { // PK_TYPE_11GA & PK_TYPE_11GB + } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ pDevice->uSIFS = C_SIFS_BG; if (pDevice->bShortSlotTime) pDevice->uSlot = C_SLOT_SHORT; @@ -1726,7 +1692,8 @@ void vUpdateIFS(struct vnt_private *pDevice) pDevice->uSlot = C_SLOT_LONG; pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot; - if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M + if (pDevice->wBasicRate & 0x0150) { + /* 0000 0001 0101 0000,24M,12M,6M */ pDevice->uCwMin = C_CWMIN_A; byMaxMin = 4; } else { @@ -1738,7 +1705,7 @@ void vUpdateIFS(struct vnt_private *pDevice) pDevice->uCwMax = C_CWMAX; pDevice->uEIFS = C_EIFS; if (pDevice->byRFType == RF_RFMD2959) { - // bcs TX_PE will reserve 3 us + /* bcs TX_PE will reserve 3 us */ VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3)); VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3)); } else { @@ -1747,7 +1714,7 @@ void vUpdateIFS(struct vnt_private *pDevice) } VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS); VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot); - byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023 + byMaxMin |= 0xA0; /* 1010 1111,C_CWMAX = 1023 */ VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin); } @@ -1756,7 +1723,7 @@ void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; unsigned char ii; - //Determines the highest basic rate. + /* Determines the highest basic rate. */ for (ii = RATE_54M; ii >= RATE_6M; ii--) { if ((pDevice->wBasicRate) & ((unsigned short)(1<wBasicRate |= wRate; - //Determines the highest basic rate. + /* Determines the highest basic rate. */ CARDvUpdateBasicTopRate((void *)pDevice); return true; @@ -1821,7 +1788,6 @@ unsigned char CARDbyGetPktType(struct vnt_private *pDevice) * none * * Return Value: none - * */ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) { @@ -1834,9 +1800,9 @@ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) ASSERT(false); break; } - // set MAC loopback + /* set MAC loopback */ MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode)); - // set Baseband loopback + /* set Baseband loopback */ } /* @@ -1849,12 +1815,11 @@ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) * none * * Return Value: none - * */ bool CARDbSoftwareReset(struct vnt_private *pDevice) { - // reset MAC + /* reset MAC */ if (!MACbSafeSoftwareReset(pDevice->PortOffset)) return false; @@ -1874,7 +1839,6 @@ bool CARDbSoftwareReset(struct vnt_private *pDevice) * none * * Return Value: TSF Offset value - * */ u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) { @@ -1901,7 +1865,6 @@ u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) * qwCurrTSF - Current TSF counter * * Return Value: true if success; otherwise false - * */ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) { @@ -1934,17 +1897,12 @@ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) * qwCurrTSF - Current TSF counter * * Return Value: TSF value of next Beacon - * */ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) { u32 beacon_int; beacon_int = wBeaconInterval * 1024; - - /* Next TBTT = - * ((local_current_TSF / beacon_interval) + 1) * beacon_interval - */ if (beacon_int) { do_div(qwTSF, beacon_int); qwTSF += 1; @@ -1966,16 +1924,15 @@ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) * none * * Return Value: none - * */ void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval) { u64 qwNextTBTT = 0; - CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter + CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); /* Get Local TSF counter */ qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); @@ -1994,12 +1951,11 @@ void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterva * none * * Return Value: none - * */ void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval) { qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); - // Set NextTBTT + /* Set NextTBTT */ VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF); VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); -- GitLab From 99b4a7e0a2a42b33f5f10cce50d75472d8914652 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 22:44:25 +0200 Subject: [PATCH 1567/9457] staging: vt6655: dpc.h: Replace C99 // comment by /* */ Replace C99 "//" comment by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index a068b846b1be..e97e32811916 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -39,4 +39,4 @@ device_receive_frame( PSRxDesc pCurrRD ); -#endif // __RXTX_H__ +#endif /* __RXTX_H__ */ -- GitLab From 1d39fe040b7e8cb77e330e4fa65c2ab2c73b26b3 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:06:56 +0200 Subject: [PATCH 1568/9457] staging: vt6655: dpc.c: Comment fixes Replace C99 "//" comments by "/* */", remove not needed comments about adding code Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 241 ++++++++++++++++++----------------- 1 file changed, 125 insertions(+), 116 deletions(-) diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index eecf6f559e29..67cadeaf2f7d 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -160,10 +160,10 @@ s_vProcessRxMACHeader(struct vnt_private *pDevice, if (bIsWEP) { if (bExtIV) { - // strip IV&ExtIV , add 8 byte + /* strip IV&ExtIV, add 8 byte */ cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); } else { - // strip IV , add 4 byte + /* strip IV, add 4 byte */ cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); } } else { @@ -182,9 +182,9 @@ s_vProcessRxMACHeader(struct vnt_private *pDevice, pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); if (bIsWEP) { if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); /* 8 is IV&ExtIV */ else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); /* 4 is IV */ } else { *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); @@ -195,9 +195,9 @@ s_vProcessRxMACHeader(struct vnt_private *pDevice, pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); if (bIsWEP) { if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); /* 8 is IV&ExtIV */ else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV + *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); /* 4 is IV */ } else { *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); @@ -243,14 +243,14 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; } } else { - // IBSS mode + /* IBSS mode */ for (ii = 0; ii < ETH_ALEN; ii++) { psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; } } } else { - // Is AP mode.. + /* Is AP mode.. */ if (pMACHeader->wFrameCtl & FC_FROMDS) { for (ii = 0; ii < ETH_ALEN; ii++) { psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; @@ -303,7 +303,7 @@ device_receive_frame( unsigned short wRxTSC15_0 = 0; unsigned long dwRxTSC47_16 = 0; SKeyItem STempKey; - // 802.11h RPI + /* 802.11h RPI */ unsigned long dwDuration = 0; long ldBm = 0; long ldBmThreshold = 0; @@ -318,10 +318,12 @@ device_receive_frame( pwFrameSize = (unsigned short *)(skb->data + 2); FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); - // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR + /* + * Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR + * Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR + */ if ((FrameSize > 2364) || (FrameSize <= 32)) { - // Frame Size error drop this packet. + /* Frame Size error drop this packet. */ pr_debug("---------- WRONG Length 1\n"); return false; } @@ -335,16 +337,18 @@ device_receive_frame( pqwTSFTime = (__le64 *)(skb->data + FrameSize - 12); pbyFrame = (unsigned char *)(skb->data + 4); - // get packet size + /* get packet size */ FrameSize = cpu_to_le16(*pwFrameSize); - if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC - // Min: 14 bytes ACK + if ((FrameSize > 2346)|(FrameSize < 14)) { /* + * Max: 2312Payload + 30HD +4CRC + * Min: 14 bytes ACK + */ pr_debug("---------- WRONG Length 2\n"); return false; } - // update receive statistic counter + /* update receive statistic counter */ STAvUpdateRDStatCounter(&pDevice->scStatistic, *pbyRsr, *pbyNewRsr, @@ -362,10 +366,10 @@ device_receive_frame( dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; if (*pbyRxRate <= RATE_11M) { if (*pbyRxSts & 0x01) { - // long preamble + /* long preamble */ dwDuration += 192; } else { - // short preamble + /* short preamble */ dwDuration += 96; } } else { @@ -391,10 +395,10 @@ device_receive_frame( } } - // Use for TKIP MIC + /* Use for TKIP MIC */ s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); - // filter packet send from myself + /* filter packet send from myself */ if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr, pDevice->abyCurrentNetAddr)) return false; @@ -402,7 +406,7 @@ device_receive_frame( if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (PS802_11Header)(pbyFrame); - // get SA NodeIndex + /* get SA NodeIndex */ if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; @@ -474,25 +478,22 @@ device_receive_frame( return false; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - FrameSize -= 8; // Message Integrity Code + FrameSize -= 8; /* Message Integrity Code */ else - FrameSize -= 4; // 4 is ICV + FrameSize -= 4; /* 4 is ICV */ } - // - // RX OK - // - //remove the CRC length + /* RX OK, remove the CRC length */ FrameSize -= ETH_FCS_LEN; - if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address + if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && /* unicast address */ (IS_FRAGMENT_PKT((skb->data+4))) ) { - // defragment + /* defragment */ bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV); pDevice->s802_11Counter.ReceivedFragmentCount++; if (bDeFragRx) { - // defrag complete + /* defrag complete */ skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; @@ -501,9 +502,9 @@ device_receive_frame( } } -// Management & Control frame Handle +/* Management & Control frame Handle */ if ((IS_TYPE_DATA((skb->data+4))) == false) { - // Handle Control & Manage Frame + /* Handle Control & Manage Frame */ if (IS_TYPE_MGMT((skb->data+4))) { unsigned char *pbyData1; @@ -515,7 +516,7 @@ device_receive_frame( pRxPacket->bySQ = *pbySQ; pRxPacket->qwLocalTSF = le64_to_cpu(*pqwTSFTime); if (bIsWEP) { - // strip IV + /* strip IV */ pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; for (ii = 0; ii < (FrameSize - 4); ii++) { @@ -529,7 +530,7 @@ device_receive_frame( vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); - // hostap Deamon handle 802.11 management + /* hostap Deamon handle 802.11 management */ if (pDevice->bEnableHostapd) { skb->dev = pDevice->apdev; skb->data += 4; @@ -547,7 +548,7 @@ device_receive_frame( return false; } else { if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. + /* In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. */ if (!(*pbyRsr & RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { @@ -558,7 +559,7 @@ device_receive_frame( return false; } } else { - // discard DATA packet while not associate || BSSID error + /* discard DATA packet while not associate || BSSID error */ if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { @@ -568,10 +569,9 @@ device_receive_frame( } return false; } - //mike add:station mode check eapol-key challenge---> { - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication + unsigned char Protocol_Version; /* 802.1x Authentication */ + unsigned char Packet_Type; /* 802.1x Authentication */ if (bIsWEP) cbIVOffset = 8; @@ -581,18 +581,17 @@ device_receive_frame( skb->data[cbIVOffset + 8 + 24 + 6 + 1]; Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1]; Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1]; - if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header + if (wEtherType == ETH_P_PAE) { /* Protocol Type in LLC-Header */ if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame receive + (Packet_Type == 3)) { /*802.1x OR eapol-key challenge frame receive */ bRxeapol_key = true; } } } - //mike add:station mode check eapol-key challenge<--- } } -// Data frame Handle +/* Data frame Handle */ if (pDevice->bEnablePSMode) { if (!IS_FC_MOREDATA((skb->data+4))) { @@ -601,7 +600,7 @@ device_receive_frame( } } - // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps + /* Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps */ if (pDevice->bDiversityEnable && (FrameSize > 50) && (pDevice->op_mode == NL80211_IFTYPE_STATION) && pDevice->bLinkPass) { @@ -616,7 +615,7 @@ device_receive_frame( if ((*pbyRSSI != 0) && (pMgmt->pCurrBSS != NULL)) { RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - // Monitor if RSSI is too strong. + /* Monitor if RSSI is too strong. */ pMgmt->pCurrBSS->byRSSIStatCnt++; pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; @@ -626,12 +625,10 @@ device_receive_frame( } - // ----------------------------------------------- - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) { unsigned char abyMacHdr[24]; - // Only 802.1x packet incoming allowed + /* Only 802.1x packet incoming allowed */ if (bIsWEP) cbIVOffset = 8; else @@ -644,7 +641,7 @@ device_receive_frame( skb->dev = pDevice->apdev; if (bIsWEP) { - // strip IV header(8) + /* strip IV header(8) */ memcpy(&abyMacHdr[0], (skb->data + 4), 24); memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); } @@ -660,18 +657,17 @@ device_receive_frame( return true; } - // check if 802.1x authorized + /* check if 802.1x authorized */ if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) return false; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { if (bIsWEP) - FrameSize -= 8; //MIC + FrameSize -= 8; /* MIC */ } - //-------------------------------------------------------------------------------- - // Soft MIC + /* Soft MIC */ if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { if (bIsWEP) { __le32 *pdwMIC_L; @@ -702,7 +698,7 @@ device_receive_frame( MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. + /* 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. */ MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8), FrameSize - WLAN_HDR_ADDR3_LEN - 8); MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); @@ -723,13 +719,12 @@ device_receive_frame( pDevice->dev->name); } } - //2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //send event to wpa_supplicant + /* send event to wpa_supplicant */ { union iwreq_data wrqu; struct iw_michaelmicfailure ev; - int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits + int keyidx = pbyFrame[cbHeaderSize+3] >> 6; /* top two-bits */ memset(&ev, 0, sizeof(ev)); ev.flags = keyidx & IW_MICFAILURE_KEY_ID; @@ -776,17 +771,16 @@ device_receive_frame( } } - } //---end of SOFT MIC----------------------------------------------------------------------- - - // ++++++++++ Reply Counter Check +++++++++++++ + } + /* ++++++++++ Reply Counter Check +++++++++++++ */ if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || (pKey->byCipherSuite == KEY_CTL_CCMP))) { if (bIsWEP) { unsigned short wLocalTSC15_0 = 0; unsigned long dwLocalTSC47_16 = 0; unsigned long long RSC = 0; - // endian issues + /* endian issues */ RSC = *((unsigned long long *)&(pKey->KeyRSC)); wLocalTSC15_0 = (unsigned short)RSC; dwLocalTSC47_16 = (unsigned long)(RSC>>16); @@ -798,7 +792,7 @@ device_receive_frame( if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { - // check RSC + /* check RSC */ if ((wRxTSC15_0 < wLocalTSC15_0) && (dwRxTSC47_16 <= dwLocalTSC47_16) && !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { @@ -818,13 +812,13 @@ device_receive_frame( } } } - } // ----- End of Reply Counter Check -------------------------- + } s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); FrameSize -= cbHeaderOffset; - cbHeaderOffset += 4; // 4 is Rcv buffer header + cbHeaderOffset += 4; /* 4 is Rcv buffer header */ - // Null data, framesize = 14 + /* Null data, framesize = 14 */ if (FrameSize < 15) return false; @@ -851,7 +845,7 @@ device_receive_frame( skb_put(skb, FrameSize); skb->protocol = eth_type_trans(skb, skb->dev); - //drop frame not met IEEE 802.3 + /* drop frame not met IEEE 802.3 */ skb->ip_summed = CHECKSUM_NONE; pStats->rx_bytes += skb->len; @@ -882,13 +876,14 @@ static bool s_bAPModeRxCtl( if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (PS802_11Header)(pbyFrame); if (!IS_TYPE_MGMT(pbyFrame)) { - // Data & PS-Poll packet - // check frame class + /* Data & PS-Poll packet, check frame class */ if (iSANodeIndex > 0) { - // frame class 3 fliter & checking + /* frame class 3 fliter & checking */ if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta + /* + * send deauth notification + * reason = (6) class 2 received from nonauth sta + */ vMgrDeAuthenBeginSta(pDevice, pMgmt, (unsigned char *)(p802_11Header->abyAddr2), @@ -899,8 +894,10 @@ static bool s_bAPModeRxCtl( return true; } if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { - // send deassoc notification - // reason = (7) class 3 received from nonassoc sta + /* + * send deassoc notification + * reason = (7) class 3 received from nonassoc sta + */ vMgrDisassocBeginSta(pDevice, pMgmt, (unsigned char *)(p802_11Header->abyAddr2), @@ -912,14 +909,16 @@ static bool s_bAPModeRxCtl( } if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { - // delcare received ps-poll event + /* delcare received ps-poll event */ if (IS_CTL_PSPOLL(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); pr_debug("dpc: WLAN_CMD_RX_PSPOLL 1\n"); } else { - // check Data PS state - // if PW bit off, send out all PS bufferring packets. + /* + * check Data PS state + * if PW bit off, send out all PS bufferring packets. + */ if (!IS_FC_POWERMGT(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; @@ -930,10 +929,10 @@ static bool s_bAPModeRxCtl( } else { if (IS_FC_POWERMGT(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; - // Once if STA in PS state, enable multicast bufferring + /* Once if STA in PS state, enable multicast bufferring */ pMgmt->sNodeDBTable[0].bPSEnable = true; } else { - // clear all pending PS frame. + /* clear all pending PS frame. */ if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; @@ -994,7 +993,7 @@ static bool s_bHandleRxEncryption( pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; // 6 is 802.11 address4 + pbyIV += 6; /* 6 is 802.11 address4 */ PayloadLen -= 6; } byKeyIdx = (*(pbyIV+3) & 0xc0); @@ -1008,7 +1007,7 @@ static bool s_bHandleRxEncryption( (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { - // unicast pkt use pairwise key + /* unicast pkt use pairwise key */ pr_debug("unicast pkt\n"); if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP) @@ -1018,7 +1017,7 @@ static bool s_bHandleRxEncryption( } pr_debug("unicast pkt: %d, %p\n", byDecMode, pKey); } else { - // use group key + /* use group key */ KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) byDecMode = KEY_CTL_TKIP; @@ -1028,9 +1027,9 @@ static bool s_bHandleRxEncryption( byKeyIdx, byDecMode, pKey); } } - // our WEP only support Default Key + /* our WEP only support Default Key */ if (pKey == NULL) { - // use default group key + /* use default group key */ KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) byDecMode = KEY_CTL_TKIP; @@ -1053,14 +1052,16 @@ static bool s_bHandleRxEncryption( return false; } if (byDecMode == KEY_CTL_WEP) { - // handle WEP + /* handle WEP */ if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { - // Software WEP - // 1. 3253A - // 2. WEP 256 + /* + * Software WEP + * 1. 3253A + * 2. WEP 256 + */ - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); /* 24 is 802.11 header,4 is IV, 4 is crc */ memcpy(pDevice->abyPRNG, pbyIV, 3); memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); @@ -1072,9 +1073,9 @@ static bool s_bHandleRxEncryption( } } else if ((byDecMode == KEY_CTL_TKIP) || (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES + /* TKIP/AES */ - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); /* 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc */ *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) @@ -1086,8 +1087,10 @@ static bool s_bHandleRxEncryption( if ((byDecMode == KEY_CTL_TKIP) && (pDevice->byLocalID <= REV_ID_VT3253_A1)) { - // Software TKIP - // 1. 3253 A + /* + * Software TKIP + * 1. 3253 A + */ PS802_11Header pMACHeader = (PS802_11Header)(pbyFrame); TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); @@ -1101,7 +1104,7 @@ static bool s_bHandleRxEncryption( pr_debug("PayloadLen = %d\n", PayloadLen); } } - }// end of TKIP/AES + } if ((*(pbyIV+3) & 0x20) != 0) *pbExtIV = true; @@ -1133,7 +1136,7 @@ static bool s_bHostWepRxEncryption( pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; // 6 is 802.11 address4 + pbyIV += 6; /* 6 is 802.11 address4 */ PayloadLen -= 6; } byKeyIdx = (*(pbyIV+3) & 0xc0); @@ -1152,18 +1155,20 @@ static bool s_bHostWepRxEncryption( return false; if (byDecMode == KEY_CTL_WEP) { - // handle WEP + /* handle WEP */ pr_debug("byDecMode == KEY_CTL_WEP\n"); if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || !bOnFly) { - // Software WEP - // 1. 3253A - // 2. WEP 256 - // 3. NotOnFly - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc + /* + * Software WEP + * 1. 3253A + * 2. WEP 256 + * 3. NotOnFly + */ + + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); /* 24 is 802.11 header,4 is IV, 4 is crc */ memcpy(pDevice->abyPRNG, pbyIV, 3); memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); @@ -1175,9 +1180,9 @@ static bool s_bHostWepRxEncryption( } } else if ((byDecMode == KEY_CTL_TKIP) || (byDecMode == KEY_CTL_CCMP)) { - // TKIP/AES + /* TKIP/AES */ - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc + PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); /* 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc */ *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); @@ -1190,9 +1195,11 @@ static bool s_bHostWepRxEncryption( if (byDecMode == KEY_CTL_TKIP) { if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) { - // Software TKIP - // 1. 3253 A - // 2. NotOnFly + /* + * Software TKIP + * 1. 3253 A + * 2. NotOnFly + */ pr_debug("soft KEY_CTL_TKIP\n"); pMACHeader = (PS802_11Header)(pbyFrame); TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); @@ -1211,8 +1218,10 @@ static bool s_bHostWepRxEncryption( if (byDecMode == KEY_CTL_CCMP) { if (!bOnFly) { - // Software CCMP - // NotOnFly + /* + * Software CCMP + * NotOnFly + */ pr_debug("soft KEY_CTL_CCMP\n"); if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { *pbyNewRsr |= NEWRSR_DECRYPTOK; @@ -1223,7 +1232,7 @@ static bool s_bHostWepRxEncryption( } } - }// end of TKIP/AES + } if ((*(pbyIV+3) & 0x20) != 0) *pbExtIV = true; @@ -1249,12 +1258,12 @@ static bool s_bAPModeRxData( if (FrameSize > CB_MAX_BUF_SIZE) return false; - // check DA + /* check DA */ if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) { if (pMgmt->sNodeDBTable[0].bPSEnable) { skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); - // if any node in PS mode, buffer packet until DTIM. + /* if any node in PS mode, buffer packet until DTIM. */ if (skbcpy == NULL) { pr_info("relay multicast no skb available\n"); } else { @@ -1264,18 +1273,18 @@ static bool s_bAPModeRxData( skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map + /* set tx map */ pMgmt->abyPSTxMap[0] |= byMask[0]; } } else { bRelayAndForward = true; } } else { - // check if relay + /* check if relay */ if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { - // queue this skb until next PS tx, and then release. + /* queue this skb until next PS tx, and then release. */ skb->data += cbHeaderOffset; skb->tail += cbHeaderOffset; @@ -1296,7 +1305,7 @@ static bool s_bAPModeRxData( } if (bRelayOnly || bRelayAndForward) { - // relay this packet right now + /* relay this packet right now */ if (bRelayAndForward) iDANodeIndex = 0; @@ -1306,7 +1315,7 @@ static bool s_bAPModeRxData( if (bRelayOnly) return false; } - // none associate, don't forward + /* none associate, don't forward */ if (pDevice->uAssocCount == 0) return false; -- GitLab From b69c0bfd92e46cceda1757b5eaf1e25e04bd7c63 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:08:50 +0200 Subject: [PATCH 1569/9457] staging: vt6655: desc.h: Comments fixes Replace C99 "//" comments by "/* */", remove blank commented lines Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 101 +++++++++++++++------------------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 5a2bbd2047d8..8f510c69cee1 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -40,38 +40,30 @@ #define B_OWNED_BY_CHIP 1 #define B_OWNED_BY_HOST 0 -// -// Bits in the RSR register -// +/* Bits in the RSR register */ #define RSR_ADDRBROAD 0x80 #define RSR_ADDRMULTI 0x40 #define RSR_ADDRUNI 0x00 #define RSR_IVLDTYP 0x20 -#define RSR_IVLDLEN 0x10 // invalid len (> 2312 byte) +#define RSR_IVLDLEN 0x10 /* invalid len (> 2312 byte) */ #define RSR_BSSIDOK 0x08 #define RSR_CRCOK 0x04 #define RSR_BCNSSIDOK 0x02 #define RSR_ADDROK 0x01 -// -// Bits in the new RSR register -// +/* Bits in the new RSR register */ #define NEWRSR_DECRYPTOK 0x10 #define NEWRSR_CFPIND 0x08 #define NEWRSR_HWUTSF 0x04 #define NEWRSR_BCNHITAID 0x02 #define NEWRSR_BCNHITAID0 0x01 -// -// Bits in the TSR0 register -// +/* Bits in the TSR0 register */ #define TSR0_PWRSTS1_2 0xC0 #define TSR0_PWRSTS7 0x20 #define TSR0_NCR 0x1F -// -// Bits in the TSR1 register -// +/* Bits in the TSR1 register */ #define TSR1_TERR 0x80 #define TSR1_PWRSTS4_6 0x70 #define TSR1_RETRYTMO 0x08 @@ -79,16 +71,14 @@ #define TSR1_PWRSTS3 0x02 #define ACK_DATA 0x01 -// -// Bits in the TCR register -// -#define EDMSDU 0x04 // end of sdu -#define TCR_EDP 0x02 // end of packet -#define TCR_STP 0x01 // start of packet +/* Bits in the TCR register */ +#define EDMSDU 0x04 /* end of sdu */ +#define TCR_EDP 0x02 /* end of packet */ +#define TCR_STP 0x01 /* start of packet */ -// max transmit or receive buffer size +/* max transmit or receive buffer size */ #define CB_MAX_BUF_SIZE 2900U - // NOTE: must be multiple of 4 + /* NOTE: must be multiple of 4 */ #define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE #define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE @@ -100,18 +90,21 @@ #define CB_MIN_TX_DESC 16 #define CB_MAX_RECEIVED_PACKETS 16 - // limit our receive routine to indicating - // this many at a time for 2 reasons: - // 1. driver flow control to protocol layer - // 2. limit the time used in ISR routine + /* + * limit our receive routine to indicating + * this many at a time for 2 reasons: + * 1. driver flow control to protocol layer + * 2. limit the time used in ISR routine + */ #define CB_EXTRA_RD_NUM 32 #define CB_RD_NUM 32 #define CB_TD_NUM 32 -// max number of physical segments -// in a single NDIS packet. Above this threshold, the packet -// is copied into a single physically contiguous buffer +/* + * max number of physical segments in a single NDIS packet. Above this + * threshold, the packet is copied into a single physically contiguous buffer + */ #define CB_MAX_SEGMENT 4 #define CB_MIN_MAP_REG_NUM 4 @@ -119,14 +112,15 @@ #define CB_PROTOCOL_RESERVED_SECTION 16 -// if retrys excess 15 times , tx will abort, and -// if tx fifo underflow, tx will fail -// we should try to resend it +/* + * if retrys excess 15 times , tx will abort, and if tx fifo underflow, + * tx will fail, we should try to resend it + */ #define CB_MAX_TX_ABORT_RETRY 3 #ifdef __BIG_ENDIAN -// WMAC definition FIFO Control +/* WMAC definition FIFO Control */ #define FIFOCTL_AUTO_FB_1 0x0010 #define FIFOCTL_AUTO_FB_0 0x0008 #define FIFOCTL_GRPACK 0x0004 @@ -143,7 +137,7 @@ #define FIFOCTL_NEEDACK 0x0200 #define FIFOCTL_LHEAD 0x0100 -//WMAC definition Frag Control +/* WMAC definition Frag Control */ #define FRAGCTL_AES 0x0003 #define FRAGCTL_TKIP 0x0002 #define FRAGCTL_LEGACY 0x0001 @@ -171,7 +165,7 @@ #define FIFOCTL_NEEDACK 0x0002 #define FIFOCTL_LHEAD 0x0001 -//WMAC definition Frag Control +/* WMAC definition Frag Control */ #define FRAGCTL_AES 0x0300 #define FRAGCTL_TKIP 0x0200 #define FRAGCTL_LEGACY 0x0100 @@ -195,14 +189,17 @@ #define TYPE_RXDMA1 1 #define TYPE_MAXRD 2 -// TD_INFO flags control bit -#define TD_FLAGS_NETIF_SKB 0x01 // check if need release skb -#define TD_FLAGS_PRIV_SKB 0x02 // check if called from private skb(hostap) -#define TD_FLAGS_PS_RETRY 0x04 // check if PS STA frame re-transmit +/* TD_INFO flags control bit */ +#define TD_FLAGS_NETIF_SKB 0x01 /* check if need release skb */ +#define TD_FLAGS_PRIV_SKB 0x02 /* check if called from private skb (hostap) */ +#define TD_FLAGS_PS_RETRY 0x04 /* check if PS STA frame re-transmit */ -// ref_sk_buff is used for mapping the skb structure between pre-built driver-obj & running kernel. -// Since different kernel version (2.4x) may change skb structure, i.e. pre-built driver-obj -// may link to older skb that leads error. +/* + * ref_sk_buff is used for mapping the skb structure between pre-built + * driver-obj & running kernel. Since different kernel version (2.4x) may + * change skb structure, i.e. pre-built driver-obj may link to older skb that + * leads error. + */ typedef struct tagDEVICE_RD_INFO { struct sk_buff *skb; @@ -242,9 +239,7 @@ typedef struct tagRDES1 { } __attribute__ ((__packed__)) SRDES1; -// -// Rx descriptor -// +/* Rx descriptor*/ typedef struct tagSRxDesc { volatile SRDES0 m_rd0RD0; volatile SRDES1 m_rd1RD1; @@ -302,9 +297,7 @@ typedef struct tagDEVICE_TD_INFO { unsigned char byFlags; } DEVICE_TD_INFO, *PDEVICE_TD_INFO; -// -// transmit descriptor -// +/* transmit descriptor */ typedef struct tagSTxDesc { volatile STDES0 m_td0TD0; volatile STDES1 m_td1TD1; @@ -319,8 +312,8 @@ typedef const STxDesc *PCSTxDesc; typedef struct tagSTxSyncDesc { volatile STDES0 m_td0TD0; volatile STDES1 m_td1TD1; - volatile u32 buff_addr; // pointer to logical buffer - volatile u32 next_desc; // pointer to next logical descriptor + volatile u32 buff_addr; /* pointer to logical buffer */ + volatile u32 next_desc; /* pointer to next logical descriptor */ volatile unsigned short m_wFIFOCtl; volatile unsigned short m_wTimeStamp; struct tagSTxSyncDesc *next __aligned(8); @@ -329,9 +322,7 @@ typedef struct tagSTxSyncDesc { STxSyncDesc, *PSTxSyncDesc; typedef const STxSyncDesc *PCSTxSyncDesc; -// -// RsvTime buffer header -// +/* RsvTime buffer header */ typedef struct tagSRrvTime_atim { unsigned short wCTSTxRrvTime_ba; unsigned short wTxRrvTime_a; @@ -352,9 +343,7 @@ union vnt_phy_field_swap { u32 field_write; }; -// -// Tx FIFO header -// +/* Tx FIFO header */ typedef struct tagSTxBufHead { u32 adwTxKey[4]; unsigned short wFIFOCtl; @@ -392,4 +381,4 @@ typedef struct tagSKeyEntry { } __attribute__ ((__packed__)) SKeyEntry; -#endif // __DESC_H__ +#endif /* __DESC_H__ */ -- GitLab From 29425feb5c498e2983c820ed0787d53a84eb3d55 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:10:43 +0200 Subject: [PATCH 1570/9457] staging: vt6655: bssdb.h: Replace C99 // comments by /* */ Replace C99 "//" comments by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/bssdb.h | 47 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index 5d4dd28b6223..8a37a11809bb 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -37,44 +37,43 @@ #define MAX_NODE_NUM 64 #define MAX_BSS_NUM 42 -#define LOST_BEACON_COUNT 10 // 10 sec, XP defined -#define MAX_PS_TX_BUF 32 // sta max power saving tx buf -#define ADHOC_LOST_BEACON_COUNT 30 // 30 sec, beacon lost for adhoc only -#define MAX_INACTIVE_COUNT 300 // 300 sec, inactive STA node refresh +#define LOST_BEACON_COUNT 10 /* 10 sec, XP defined */ +#define MAX_PS_TX_BUF 32 /* sta max power saving tx buf */ +#define ADHOC_LOST_BEACON_COUNT 30 /* 30 sec, beacon lost for adhoc only */ +#define MAX_INACTIVE_COUNT 300 /* 300 sec, inactive STA node refresh */ -#define USE_PROTECT_PERIOD 10 // 10 sec, Use protect mode check period -#define ERP_RECOVER_COUNT 30 // 30 sec, ERP support callback check +#define USE_PROTECT_PERIOD 10 /*10 sec, Use protect mode check period*/ +#define ERP_RECOVER_COUNT 30 /* 30 sec, ERP support callback check */ #define BSS_CLEAR_COUNT 1 #define RSSI_STAT_COUNT 10 #define MAX_CHECK_RSSI_COUNT 8 -// STA dwflags +/* STA dwflags */ #define WLAN_STA_AUTH BIT0 #define WLAN_STA_ASSOC BIT1 #define WLAN_STA_PS BIT2 #define WLAN_STA_TIM BIT3 -// permanent; do not remove entry on expiration +/* permanent; do not remove entry on expiration */ #define WLAN_STA_PERM BIT4 -// If 802.1X is used, this flag is -// controlling whether STA is authorized to -// send and receive non-IEEE 802.1X frames +/* + * If 802.1X is used, this flag is controlling whether STA is authorized + * to send and receive non-IEEE 802.1X frames + */ #define WLAN_STA_AUTHORIZED BIT5 #define MAX_RATE 12 #define MAX_WPA_IE_LEN 64 -// -// IEEE 802.11 Structures and definitions -// +/* IEEE 802.11 Structures and definitions */ typedef enum _NDIS_802_11_NETWORK_TYPE { Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound + Ndis802_11NetworkTypeMax /* defined as an upper bound */ } NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; typedef struct tagSERPObject { @@ -87,7 +86,7 @@ typedef struct tagSRSNCapObject { unsigned short wRSNCap; } SRSNCapObject, *PSRSNCapObject; -// BSS info(AP) +/* BSS info(AP) */ #pragma pack(1) typedef struct tagKnownBSS { bool bActive; @@ -152,7 +151,7 @@ typedef enum tagNODE_STATE { NODE_ASSOC } NODE_STATE, *PNODE_STATE; -// STA node info +/* STA node info */ typedef struct tagKnownNodeDB { bool bActive; unsigned char abyMACAddr[WLAN_ADDR_LEN]; @@ -163,13 +162,13 @@ typedef struct tagKnownNodeDB { bool bERPExist; bool bShortSlotTime; unsigned int uInActiveCount; - unsigned short wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. - unsigned short wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. + unsigned short wMaxBasicRate; /* Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. */ + unsigned short wMaxSuppRate; /* Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. */ unsigned short wSuppRate; - unsigned char byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode - unsigned char byTopCCKBasicRate; //Records the highest basic rate in CCK mode + unsigned char byTopOFDMBasicRate; /* Records the highest basic rate in OFDM mode */ + unsigned char byTopCCKBasicRate; /* Records the highest basic rate in CCK mode */ - // For AP mode + /* For AP mode */ struct sk_buff_head sTxPSQueue; unsigned short wCapInfo; unsigned short wListenInterval; @@ -192,7 +191,7 @@ typedef struct tagKnownNodeDB { unsigned short wTSC15_0; unsigned int uWepKeyLength; unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN]; - // Auto rate fallback vars + /* Auto rate fallback vars */ bool bIsInFallback; unsigned int uAverageRSSI; unsigned int uRateRecoveryTimeout; @@ -323,4 +322,4 @@ BSSvClearAnyBSSJoinRecord( void *hDeviceContext ); -#endif //__BSSDB_H__ +#endif /*__BSSDB_H__ */ -- GitLab From c834e7656b6caeee56259bf4b241dd7f016b57e4 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:12:46 +0200 Subject: [PATCH 1571/9457] staging: vt6655: channel.c: Comments fixes Replace C99 "//" comments by "/* */", remove not needed comments about adding code Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 4ce964ba14b7..a19965fbcc97 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -375,9 +375,7 @@ bool is_channel_valid(unsigned int ChannelIndex) bool bValid; bValid = false; - /* - * If Channel Index is invalid, return invalid - */ + /* If Channel Index is invalid, return invalid */ if ((ChannelIndex > CB_MAX_CHANNEL) || (ChannelIndex == 0)) { bValid = false; @@ -450,7 +448,6 @@ void init_channel_table(void *pDeviceHandler) } } else { for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - //2008-8-4 by chester if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { sChannelTbl[ii + 1].bValid = true; pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; @@ -538,27 +535,25 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) (pDevice->eCurrentPHYType == PHY_TYPE_11A)) { CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL); } - // clear NAV + /* clear NAV */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); - //{{ RobertYu: 20041202 - //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput + /* TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput */ if (pDevice->byRFType == RF_AIROHA7230) RFbAL7230SelectChannelPostProcess(pDevice->PortOffset, pDevice->byCurrentCh, (unsigned char)uConnectionChannel); - //}} RobertYu pDevice->byCurrentCh = (unsigned char)uConnectionChannel; bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (unsigned char)uConnectionChannel); - // Init Synthesizer Table + /* Init Synthesizer Table */ if (pDevice->bEnablePSMode) RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel); BBvSoftwareReset(pDevice->PortOffset); if (pDevice->byLocalID > REV_ID_VT3253_B1) { - // set HW default power register + /* set HW default power register */ MACvSelectPage1(pDevice->PortOffset); RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWRCCK, pDevice->byCurPwr); @@ -644,7 +639,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) pIE->len = 0; pbyChTupple = pIE->abyChannelTuple; byLen = 2; - // lower band + /* lower band */ byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == true) { for (ii = 28; ii < 36; ii += 2) { @@ -665,7 +660,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) *pbyChTupple++ = byCount; byLen += 2; } - // middle band + /* middle band */ byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == true) { for (ii = 36; ii < 40; ii++) { @@ -677,7 +672,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) *pbyChTupple++ = byCount; byLen += 2; } - // higher band + /* higher band */ byCount = 0; if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == true) { for (ii = 40; ii < 51; ii++) { -- GitLab From d8e340de7d2e7df230bd0dc9f43e8205a8a70350 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:18:03 +0200 Subject: [PATCH 1572/9457] staging: vt6655: IEEE11h.h: Replace C99 // comment by /* */ Replace C99 "//" comment by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/IEEE11h.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h index 551922022b19..b3e318d7278f 100644 --- a/drivers/staging/vt6655/IEEE11h.h +++ b/drivers/staging/vt6655/IEEE11h.h @@ -39,4 +39,4 @@ bool IEEE11hbMSRRepTx( void *pMgmtHandle ); -#endif // __IEEE11h_H__ +#endif /* __IEEE11h_H__ */ -- GitLab From bd2ac90116fdd516922095557278eb75d934a810 Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:19:40 +0200 Subject: [PATCH 1573/9457] staging: vt6655: ioctl.h: Replace C99 // comment by /* */ Replace C99 "//" comment by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h index 2dc5a5743e8d..1b5d19495fad 100644 --- a/drivers/staging/vt6655/ioctl.h +++ b/drivers/staging/vt6655/ioctl.h @@ -33,4 +33,4 @@ int private_ioctl(struct vnt_private *, struct ifreq *rq); -#endif // __IOCTL_H__ +#endif /* __IOCTL_H__ */ -- GitLab From fab2f89359dc1656c3d84629f76f16603514173f Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:21:20 +0200 Subject: [PATCH 1574/9457] staging: vt6655: iowpa.h: Replace C99 // comments by /* */ Replace C99 "//" comments by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iowpa.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h index fe4b22ed49f4..7f79eaeecc9e 100644 --- a/drivers/staging/vt6655/iowpa.h +++ b/drivers/staging/vt6655/iowpa.h @@ -31,7 +31,7 @@ #define WPA_IE_LEN 64 -//WPA related +/* WPA related */ enum { VIAWGET_SET_WPA = 1, @@ -117,9 +117,9 @@ struct viawget_scan_result { u16 wpa_ie_len; u8 rsn_ie[WPA_IE_LEN]; u16 rsn_ie_len; - int freq; // MHz - int caps; // e.g. privacy - int qual; // signal quality + int freq; /* MHz */ + int caps; /* e.g. privacy */ + int qual; /* signal quality */ int noise; int level; int maxrate; @@ -127,4 +127,4 @@ struct viawget_scan_result { #pragma pack() -#endif //__IOWPA_H__ +#endif /* __IOWPA_H__ */ -- GitLab From af969c84571d9d9140122f5f7c8c615e64d2d7fa Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:23:04 +0200 Subject: [PATCH 1575/9457] staging: vt6655: iocmd.h: Replace C99 // comments by /* */ Replace C99 "//" comments by "/* */" Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iocmd.h | 84 +++++++++++++--------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h index a665cfd8a482..804c903404a1 100644 --- a/drivers/staging/vt6655/iocmd.h +++ b/drivers/staging/vt6655/iocmd.h @@ -31,7 +31,7 @@ #include "ttype.h" -// ioctl Command code +/* ioctl Command code */ #define MAGIC_CODE 0x3142 #define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0) #define IOCTL_CMD_SET (SIOCDEVPRIVATE + 1) @@ -88,9 +88,7 @@ typedef enum tagWZONETYPE { #define WEP_104BIT_LEN 13 #define WEP_232BIT_LEN 16 -// Ioctl interface structure -// Command structure -// +/* Ioctl interface structure, Command structure */ #pragma pack(1) typedef struct tagSCmdRequest { u8 name[16]; @@ -99,18 +97,12 @@ typedef struct tagSCmdRequest { u16 wCmdCode; } SCmdRequest, *PSCmdRequest; -// -// Scan -// - +/* Scan */ typedef struct tagSCmdScan { u8 ssid[SSID_MAXLEN + 2]; } SCmdScan, *PSCmdScan; -// -// BSS Join -// - +/* BSS Join */ typedef struct tagSCmdBSSJoin { u16 wBSSType; u16 wBBPType; @@ -120,10 +112,7 @@ typedef struct tagSCmdBSSJoin { bool bShareKeyAuth; } SCmdBSSJoin, *PSCmdBSSJoin; -// -// Zonetype Setting -// - +/* Zonetype Setting */ typedef struct tagSCmdZoneTypeSet { bool bWrite; WZONETYPE ZoneType; @@ -163,7 +152,7 @@ typedef struct tagSBSSIDItem { u8 abySSID[SSID_MAXLEN + 1]; u8 byNetType; u16 wBeaconInterval; - u16 wCapInfo; // for address of byNetType at align 4 + u16 wCapInfo; /* for address of byNetType at align 4 */ bool bWEPOn; u32 uRSSI; @@ -184,9 +173,7 @@ typedef struct tagSCmdLinkStatus { u32 uLinkRate; } SCmdLinkStatus, *PSCmdLinkStatus; -// -// 802.11 counter -// +/* 802.11 counter */ typedef struct tagSDot11MIBCount { u32 TransmittedFragmentCount; u32 MulticastTransmittedFrameCount; @@ -202,13 +189,9 @@ typedef struct tagSDot11MIBCount { u32 FCSErrorCount; } SDot11MIBCount, *PSDot11MIBCount; -// -// statistic counter -// +/* statistic counter */ typedef struct tagSStatMIBCount { - // - // ISR status count - // + /* ISR status count */ u32 dwIsrTx0OK; u32 dwIsrTx1OK; u32 dwIsrBeaconTxOK; @@ -221,8 +204,7 @@ typedef struct tagSStatMIBCount { u32 dwIsrUnknown; - // RSR status count - // + /* RSR status count */ u32 dwRsrFrmAlgnErr; u32 dwRsrErr; u32 dwRsrCRCErr; @@ -243,10 +225,10 @@ typedef struct tagSStatMIBCount { u32 dwRsrBroadcast; u32 dwRsrMulticast; u32 dwRsrDirected; - // 64-bit OID + /* 64-bit OID */ u32 ullRsrOK; - // for some optional OIDs (64 bits) and DMI support + /* for some optional OIDs (64 bits) and DMI support */ u32 ullRxBroadcastBytes; u32 ullRxMulticastBytes; u32 ullRxDirectedBytes; @@ -262,13 +244,12 @@ typedef struct tagSStatMIBCount { u32 dwRsrRxFrmLen512_1023; u32 dwRsrRxFrmLen1024_1518; - // TSR0,1 status count - // - u32 dwTsrTotalRetry[2]; // total collision retry count - u32 dwTsrOnceRetry[2]; // this packet only occur one collision - u32 dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision - u32 dwTsrRetry[2]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) + /* TSR0,1 status count */ + u32 dwTsrTotalRetry[2]; /* total collision retry count */ + u32 dwTsrOnceRetry[2]; /* this packet only occur one collision */ + u32 dwTsrMoreThanOnceRetry[2]; /* this packet occur more than one collision */ + u32 dwTsrRetry[2]; /* this packet has ever occur collision */ + /* that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) */ u32 dwTsrACKData[2]; u32 dwTsrErr[2]; u32 dwAllTsrOK[2]; @@ -281,23 +262,23 @@ typedef struct tagSStatMIBCount { u32 dwTsrMulticast[2]; u32 dwTsrDirected[2]; - // RD/TD count + /* RD/TD count */ u32 dwCntRxFrmLength; u32 dwCntTxBufLength; u8 abyCntRxPattern[16]; u8 abyCntTxPattern[16]; - // Software check.... - u32 dwCntRxDataErr; // rx buffer data software compare CRC err count - u32 dwCntDecryptErr; // rx buffer data software compare CRC err count - u32 dwCntRxICVErr; // rx buffer data software compare CRC err count - u32 idxRxErrorDesc; // index for rx data error RD + /* Software check */ + u32 dwCntRxDataErr; /* rx buffer data software compare CRC err count */ + u32 dwCntDecryptErr; /* rx buffer data software compare CRC err count */ + u32 dwCntRxICVErr; /* rx buffer data software compare CRC err count */ + u32 idxRxErrorDesc; /* index for rx data error RD */ - // 64-bit OID + /* 64-bit OID */ u32 ullTsrOK[2]; - // for some optional OIDs (64 bits) and DMI support + /* for some optional OIDs (64 bits) and DMI support */ u32 ullTxBroadcastFrames[2]; u32 ullTxMulticastFrames[2]; u32 ullTxDirectedFrames[2]; @@ -307,7 +288,7 @@ typedef struct tagSStatMIBCount { } SStatMIBCount, *PSStatMIBCount; typedef struct tagSNodeItem { - // STA info + /* STA info */ u16 wAID; u8 abyMACAddr[6]; u16 wTxDataRate; @@ -318,7 +299,7 @@ typedef struct tagSNodeItem { u8 byKeyIndex; u16 wWepKeyLength; u8 abyWepKey[WEP_KEYMAXLEN]; - // Auto rate fallback vars + /* Auto rate fallback vars */ bool bIsInFallback; u32 uTxFailures; u32 uTxAttempts; @@ -334,10 +315,7 @@ typedef struct tagSCmdValue { u32 dwValue; } SCmdValue, *PSCmdValue; -// -// hostapd & viawget ioctl related -// - +/* hostapd & viawget ioctl related */ enum { VIAWGET_HOSTAPD_FLUSH = 1, VIAWGET_HOSTAPD_ADD_STA = 2, @@ -356,7 +334,7 @@ enum { #define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ ((int)(&((struct viawget_hostapd_param *)0)->u.generic_elem.data)) -// Maximum length for algorithm names (-1 for nul termination) used in ioctl() +/*Maximum length for algorithm names (-1 for nul termination) used in ioctl()*/ struct viawget_hostapd_param { u32 cmd; @@ -405,4 +383,4 @@ struct viawget_hostapd_param { #pragma pack() -#endif //__IOCMD_H__ +#endif /* __IOCMD_H__ */ -- GitLab From 1e06c3a492107ca392798ccf835288969ea269ec Mon Sep 17 00:00:00 2001 From: Veronika Kabatova Date: Sat, 25 Oct 2014 23:53:38 +0200 Subject: [PATCH 1576/9457] staging: vt6655: iwctl.c: Comments fixes Replace C99 "//" comments by "/* */", remove comments about adding code, remove commented code (one left there for debugging of the function) Signed-off-by: Veronika Kabatova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iwctl.c | 510 ++++++++++++++------------------- 1 file changed, 220 insertions(+), 290 deletions(-) diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index cc261d7dd058..cbcb152a4a0b 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -46,11 +46,10 @@ #endif #include -extern unsigned short TxRate_iwconfig;//2008-5-8 by chester +extern unsigned short TxRate_iwconfig; /*--------------------- Static Definitions -------------------------*/ -//2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #define SUPPORTED_WIRELESS_EXT 18 #else @@ -109,10 +108,8 @@ static int iwctl_commit(struct net_device *dev, return 0; } -/* - * Wireless Handler : get protocol name - */ +/* Wireless Handler : get protocol name */ int iwctl_giwname(struct net_device *dev, struct iw_request_info *info, char *wrq, @@ -122,10 +119,7 @@ int iwctl_giwname(struct net_device *dev, return 0; } -/* - * Wireless Handler : set scan - */ - +/* Wireless Handler : set scan */ static int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -139,8 +133,8 @@ static int iwctl_siwscan(struct net_device *dev, pr_debug(" SIOCSIWSCAN\n"); - if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! -//send scan event to wpa_Supplicant + if (pDevice->byReAssocCount > 0) { /* reject scan when re-associating! */ +/* send scan event to wpa_Supplicant */ union iwreq_data wrqu; PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); @@ -152,9 +146,9 @@ static int iwctl_siwscan(struct net_device *dev, spin_lock_irq(&pDevice->lock); BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); -//mike add: active scan OR passive scan OR desire_ssid scan +/* active scan OR passive scan OR desire_ssid scan */ if (wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan + if (wrq->flags & IW_SCAN_THIS_ESSID) { /* desire_ssid scan */ memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); pItemSSID = (PWLAN_IE_SSID)abyScanSSID; pItemSSID->byElementID = WLAN_EID_SSID; @@ -171,10 +165,10 @@ static int iwctl_siwscan(struct net_device *dev, spin_unlock_irq(&pDevice->lock); return 0; - } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan + } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { /* passive scan */ pMgmt->eScanType = WMAC_SCAN_PASSIVE; } - } else { //active scan + } else { /* active scan */ pMgmt->eScanType = WMAC_SCAN_ACTIVE; } @@ -185,10 +179,7 @@ static int iwctl_siwscan(struct net_device *dev, return 0; } -/* - * Wireless Handler : get scan results - */ - +/* Wireless Handler : get scan results */ static int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -210,7 +201,7 @@ static int iwctl_giwscan(struct net_device *dev, pr_debug(" SIOCGIWSCAN\n"); if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. + /* In scanning.. */ return -EAGAIN; } pBSS = &(pMgmt->sBSSList[0]); @@ -219,20 +210,20 @@ static int iwctl_giwscan(struct net_device *dev, break; pBSS = &(pMgmt->sBSSList[jj]); if (pBSS->bActive) { - //ADD mac address + /* ADD mac address */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); - //ADD ssid + /* ADD ssid */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; iwe.u.data.length = pItemSSID->len; iwe.u.data.flags = 1; current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); - //ADD mode + /* ADD mode */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) @@ -242,7 +233,7 @@ static int iwctl_giwscan(struct net_device *dev, iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - //ADD frequency + /* ADD frequency */ pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; memset(&iwe, 0, sizeof(iwe)); @@ -251,7 +242,6 @@ static int iwctl_giwscan(struct net_device *dev, iwe.u.freq.e = 0; iwe.u.freq.i = 0; current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - //2008-0409-04, by Einsn Liu { int f = (int)pBSS->uChannel - 1; @@ -260,13 +250,12 @@ static int iwctl_giwscan(struct net_device *dev, iwe.u.freq.e = 1; } current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - //ADD quality + /* ADD quality */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); iwe.u.qual.level = ldBm; iwe.u.qual.noise = 0; -//2008-0409-01, by Einsn Liu if (-ldBm < 50) iwe.u.qual.qual = 100; else if (-ldBm > 90) @@ -296,14 +285,14 @@ static int iwctl_giwscan(struct net_device *dev, for (kk = 0; kk < 12; kk++) { if (pSuppRates->abyRates[kk] == 0) break; - // Bit rate given in 500 kb/s units (+ 0x80) + /* Bit rate given in 500 kb/s units (+ 0x80) */ iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } for (kk = 0; kk < 8; kk++) { if (pExtSuppRates->abyRates[kk] == 0) break; - // Bit rate given in 500 kb/s units (+ 0x80) + /* Bit rate given in 500 kb/s units (+ 0x80) */ iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } @@ -332,16 +321,13 @@ static int iwctl_giwscan(struct net_device *dev, } } - }// for + } wrq->length = current_ev - extra; return 0; } -/* - * Wireless Handler : set frequency or channel - */ - +/* Wireless Handler : set frequency or channel */ int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, @@ -352,7 +338,7 @@ int iwctl_siwfreq(struct net_device *dev, pr_debug(" SIOCSIWFREQ\n"); - // If setting by frequency, convert to a channel + /* If setting by frequency, convert to a channel */ if ((wrq->e == 1) && (wrq->m >= (int) 2.412e8) && (wrq->m <= (int) 2.487e8)) { @@ -364,7 +350,7 @@ int iwctl_siwfreq(struct net_device *dev, wrq->e = 0; wrq->m = c + 1; } - // Setting by channel number + /* Setting by channel number */ if ((wrq->m > 14) || (wrq->e > 0)) rc = -EOPNOTSUPP; else { @@ -375,11 +361,10 @@ int iwctl_siwfreq(struct net_device *dev, dev->name, wrq->m); rc = -EINVAL; } else { - // Yes ! We can set it !!! + /* Yes ! We can set it !!! */ pr_debug(" Set to channel = %d\n", channel); pDevice->uChannel = channel; - //2007-0207-04, by EinsnLiu - //Make change effect at once + /* Make change effect at once */ pDevice->bCommit = true; } } @@ -387,10 +372,7 @@ int iwctl_siwfreq(struct net_device *dev, return rc; } -/* - * Wireless Handler : get frequency or channel - */ - +/* Wireless Handler : get frequency or channel */ int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *wrq, @@ -418,10 +400,7 @@ int iwctl_giwfreq(struct net_device *dev, return 0; } -/* - * Wireless Handler : set operation mode - */ - +/* Wireless Handler : set operation mode */ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, @@ -475,10 +454,7 @@ int iwctl_siwmode(struct net_device *dev, return rc; } -/* - * Wireless Handler : get operation mode - */ - +/* Wireless Handler : get operation mode */ int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, @@ -488,7 +464,7 @@ int iwctl_giwmode(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); pr_debug(" SIOCGIWMODE\n"); - // If not managed, assume it's ad-hoc + /* If not managed, assume it's ad-hoc */ switch (pMgmt->eConfigMode) { case WMAC_CONFIG_ESS_STA: *wmode = IW_MODE_INFRA; @@ -509,10 +485,7 @@ int iwctl_giwmode(struct net_device *dev, return 0; } -/* - * Wireless Handler : get capability range - */ - +/* Wireless Handler : get capability range */ int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -529,16 +502,18 @@ int iwctl_giwrange(struct net_device *dev, range->min_nwid = 0x0000; range->max_nwid = 0x0000; range->num_channels = 14; - // Should be based on cap_rid.country to give only - // what the current card support + /* + * Should be based on cap_rid.country to give only + * what the current card supports + */ k = 0; for (i = 0; i < 14; i++) { - range->freq[k].i = i + 1; // List index + range->freq[k].i = i + 1; /* List index */ range->freq[k].m = frequency_list[i] * 100000; - range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10 + range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ } range->num_frequency = k; - // Hum... Should put the right values there + /* Hum... Should put the right values there */ #ifdef Calcu_LinkQual range->max_qual.qual = 100; #else @@ -555,9 +530,10 @@ int iwctl_giwrange(struct net_device *dev, } range->num_bitrates = i; - // Set an indication of the max TCP throughput - // in bit/s that we can expect using this interface. - // May be use for QoS stuff... Jean II + /* + * Set an indication of the max TCP throughput in bit/s that we + * can expect using this interface. May be used for QoS stuff + */ if (i > 2) range->throughput = 5 * 1000 * 1000; else @@ -568,29 +544,29 @@ int iwctl_giwrange(struct net_device *dev, range->min_frag = 256; range->max_frag = 2312; - // the encoding capabilities + /* the encoding capabilities */ range->num_encoding_sizes = 3; - // 64(40) bits WEP + /* 64(40) bits WEP */ range->encoding_size[0] = 5; - // 128(104) bits WEP + /* 128(104) bits WEP */ range->encoding_size[1] = 13; - // 256 bits for WPA-PSK + /* 256 bits for WPA-PSK */ range->encoding_size[2] = 32; - // 4 keys are allowed + /* 4 keys are allowed */ range->max_encoding_tokens = 4; range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; range->min_pmp = 0; - range->max_pmp = 1000000;// 1 secs + range->max_pmp = 1000000; /* 1 secs */ range->min_pmt = 0; - range->max_pmt = 1000000;// 1 secs + range->max_pmt = 1000000; /* 1 secs */ range->pmp_flags = IW_POWER_PERIOD; range->pmt_flags = IW_POWER_TIMEOUT; range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - // Transmit Power - values are in mW + /* Transmit Power - values are in mW */ range->txpower[0] = 100; range->num_txpower = 1; @@ -604,21 +580,20 @@ int iwctl_giwrange(struct net_device *dev, range->max_retry = 65535; range->min_r_time = 1024; range->max_r_time = 65535 * 1024; - // Experimental measurements - boundary 11/5.5 Mb/s - // Note : with or without the (local->rssi), results - // are somewhat different. - Jean II + /* + * Experimental measurements - boundary 11/5.5 Mb/s + * Note : with or without the (local->rssi), results + * are somewhat different. - Jean II + */ range->avg_qual.qual = 6; - range->avg_qual.level = 176; // -80 dBm + range->avg_qual.level = 176; /* -80 dBm */ range->avg_qual.noise = 0; } return 0; } -/* - * Wireless Handler : set ap mac address - */ - +/* Wireless Handler : set ap mac address */ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, @@ -631,26 +606,26 @@ int iwctl_siwap(struct net_device *dev, pr_debug(" SIOCSIWAP\n"); if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. + /* In scanning.. */ pr_debug("SIOCSIWAP(??)-->In scanning..\n"); } if (wrq->sa_family != ARPHRD_ETHER) rc = -EINVAL; else { memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - //2008-0409-05, by Einsn Liu if ((pDevice->bLinkPass == true) && (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6) == 0)) { return rc; } - //mike :add if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) { PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); return rc; } - //mike add: if desired AP is hidden ssid(there are two same BSSID in list), - // then ignore,because you don't known which one to be connect with?? + /* if desired AP is hidden ssid(there are two same BSSID in + * list), then ignore,because you don't known which one + * to be connected with?? + */ { unsigned int ii, uSameBssidNum = 0; @@ -661,7 +636,7 @@ int iwctl_siwap(struct net_device *dev, uSameBssidNum++; } } - if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + if (uSameBssidNum >= 2) { /* hit: desired AP is in hidden ssid mode!!! */ PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); return rc; } @@ -674,10 +649,7 @@ int iwctl_siwap(struct net_device *dev, return rc; } -/* - * Wireless Handler : get ap mac address - */ - +/* Wireless Handler : get ap mac address */ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *wrq, @@ -689,7 +661,6 @@ int iwctl_giwap(struct net_device *dev, pr_debug(" SIOCGIWAP\n"); memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - //2008-0410, by Einsn Liu if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) memset(wrq->sa_data, 0, 6); @@ -701,10 +672,7 @@ int iwctl_giwap(struct net_device *dev, return 0; } -/* - * Wireless Handler : get ap list - */ - +/* Wireless Handler : get ap list */ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -774,10 +742,7 @@ int iwctl_giwaplist(struct net_device *dev, return rc; } -/* - * Wireless Handler : set essid - */ - +/* Wireless Handler : set essid */ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -786,18 +751,17 @@ int iwctl_siwessid(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; - //2008-0409-05, by Einsn Liu unsigned char len; pr_debug(" SIOCSIWESSID\n"); pDevice->fWPA_Authened = false; if (pMgmt->eScanState == WMAC_IS_SCANNING) { - // In scanning.. + /* In scanning.. */ pr_debug("SIOCSIWESSID(??)-->In scanning..\n"); } - // Check if we asked for `any' + /* Check if we asked for 'any' */ if (wrq->flags == 0) { - // Just send an empty SSID list + /* Just send an empty SSID list */ memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); memset(pMgmt->abyDesireBSSID, 0xFF, 6); PRINT_K("set essid to 'any'\n"); @@ -805,7 +769,7 @@ int iwctl_siwessid(struct net_device *dev, return 0; #endif } else { - // Set the SSID + /* Set the SSID */ memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; pItemSSID->byElementID = WLAN_EID_SSID; @@ -817,21 +781,22 @@ int iwctl_siwessid(struct net_device *dev, } else pItemSSID->len = wrq->length; pr_debug("set essid to %s\n", pItemSSID->abySSID); - //2008-0409-05, by Einsn Liu len = (pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) ? pItemSSID->len : ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; if ((pDevice->bLinkPass == true) && (memcmp(pItemSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, len) == 0)) return 0; - //mike:need clear desiredBSSID + /* need clear desiredBSSID */ if (pItemSSID->len == 0) { memset(pMgmt->abyDesireBSSID, 0xFF, 6); return 0; } #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //Wext wil order another command of siwap to link with desired AP, - //so here need not associate?? + /* + * Wext wil order another command of siwap to link with desired + * AP, so here need not associate?? + */ if (pDevice->bWPASuppWextEnabled == true) { /*******search if in hidden ssid mode ****/ { @@ -852,8 +817,12 @@ int iwctl_siwessid(struct net_device *dev, pMgmt->eScanType = WMAC_SCAN_ACTIVE; bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } else { //mike:to find out if that desired SSID is a hidden-ssid AP , - // by means of judging if there are two same BSSID exist in list ? + } else { /* + * to find out if that desired SSID + * is a hidden-ssid AP, by means of + * judging if there are two same + * BSSID exist in list ? + */ for (ii = 0; ii < MAX_BSS_NUM; ii++) { if (pMgmt->sBSSList[ii].bActive && ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, @@ -861,10 +830,10 @@ int iwctl_siwessid(struct net_device *dev, uSameBssidNum++; } } - if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! + if (uSameBssidNum >= 2) { /* hit: desired AP is in hidden ssid mode!!! */ pr_debug("SIOCSIWESSID:hidden ssid directly associate.......\n"); vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! + pMgmt->eScanType = WMAC_SCAN_PASSIVE; /* this scan type, you'll submit scan result! */ bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } @@ -883,10 +852,7 @@ int iwctl_siwessid(struct net_device *dev, return 0; } -/* - * Wireless Handler : get essid - */ - +/* Wireless Handler : get essid */ int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -898,25 +864,23 @@ int iwctl_giwessid(struct net_device *dev, pr_debug(" SIOCGIWESSID\n"); - // Note : if wrq->u.data.flags != 0, we should - // get the relevant SSID from the SSID list... + /* + * Note : if wrq->u.data.flags != 0, we should get the relevant SSID + * from the SSID list... + */ - // Get the current SSID + /* Get the current SSID */ pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; memcpy(extra, pItemSSID->abySSID , pItemSSID->len); extra[pItemSSID->len] = '\0'; wrq->length = pItemSSID->len + 1; - //2008-0409-03, by Einsn Liu wrq->length = pItemSSID->len; - wrq->flags = 1; // active + wrq->flags = 1; /* active */ return 0; } -/* - * Wireless Handler : set data rate - */ - +/* Wireless Handler : set data rate */ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -934,19 +898,18 @@ int iwctl_siwrate(struct net_device *dev, return rc; } - // First : get a valid bit rate value + /* First : get a valid bit rate value */ - // Which type of value + /* Which type of value */ if ((wrq->value < 13) && (wrq->value >= 0)) { - // Setting by rate index - // Find value in the magic rate table + /* Setting by rate index, Find value in the magic rate table */ brate = wrq->value; } else { - // Setting by frequency value + /* Setting by frequency value */ u8 normvalue = (u8) (wrq->value/500000); - // Check if rate is valid + /* Check if rate is valid */ for (i = 0; i < 13; i++) { if (normvalue == abySupportedRates[i]) { brate = i; @@ -954,9 +917,9 @@ int iwctl_siwrate(struct net_device *dev, } } } - // -1 designed the max rate (mostly auto mode) + /* -1 designed the max rate (mostly auto mode) */ if (wrq->value == -1) { - // Get the highest available rate + /* Get the highest available rate */ for (i = 0; i < 13; i++) { if (abySupportedRates[i] == 0) break; @@ -965,17 +928,15 @@ int iwctl_siwrate(struct net_device *dev, brate = i - 1; } - // Check that it is valid - // brate is index of abySupportedRates[] + /* Check that it is valid, brate is index of abySupportedRates[] */ if (brate > 13) { rc = -EINVAL; return rc; } - // Now, check if we want a fixed or auto value + /* Now, check if we want a fixed or auto value */ if (wrq->fixed != 0) { - // Fixed mode - // One rate, fixed + /* Fixed mode, One rate, fixed */ pr_debug("Rate Fix\n"); pDevice->bFixRate = true; if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { @@ -995,25 +956,18 @@ int iwctl_siwrate(struct net_device *dev, return rc; } -/* - * Wireless Handler : get data rate - */ - +/* Wireless Handler : get data rate */ int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { struct vnt_private *pDevice = netdev_priv(dev); -//2007-0118-05, by EinsnLiu -//Mark the unnecessary sentences. -// PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - +/* Mark the unnecessary sentences. */ pr_debug(" SIOCGIWRATE\n"); { unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; int brate = 0; -//2008-5-8 by chester if (pDevice->bLinkPass) { if (pDevice->bFixRate == true) { if (pDevice->uConnectionRate < 13) { @@ -1032,7 +986,7 @@ int iwctl_giwrate(struct net_device *dev, } else brate = 0; wrq->value = brate * 500000; - // If more than one rate, set auto + /* If more than one rate, set auto */ if (pDevice->bFixRate == true) wrq->fixed = true; } @@ -1040,10 +994,7 @@ int iwctl_giwrate(struct net_device *dev, return 0; } -/* - * Wireless Handler : set rts threshold - */ - +/* Wireless Handler : set rts threshold */ int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1069,10 +1020,7 @@ int iwctl_siwrts(struct net_device *dev, return 0; } -/* - * Wireless Handler : get rts - */ - +/* Wireless Handler : get rts */ int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1088,10 +1036,7 @@ int iwctl_giwrts(struct net_device *dev, return 0; } -/* - * Wireless Handler : set fragment threshold - */ - +/* Wireless Handler : set fragment threshold */ int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1108,17 +1053,14 @@ int iwctl_siwfrag(struct net_device *dev, if ((fthr < 256) || (fthr > 2312)) { rc = -EINVAL; } else { - fthr &= ~0x1; // Get an even value + fthr &= ~0x1; /* Get an even value */ pDevice->wFragmentationThreshold = (u16)fthr; } return rc; } -/* - * Wireless Handler : get fragment threshold - */ - +/* Wireless Handler : get fragment threshold */ int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1134,9 +1076,7 @@ int iwctl_giwfrag(struct net_device *dev, return 0; } -/* - * Wireless Handler : set retry threshold - */ +/* Wireless Handler : set retry threshold */ int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1158,7 +1098,7 @@ int iwctl_siwretry(struct net_device *dev, else if (wrq->flags & IW_RETRY_MIN) pDevice->byShortRetryLimit = wrq->value; else { - // No modifier : set both + /* No modifier : set both */ pDevice->byShortRetryLimit = wrq->value; pDevice->byLongRetryLimit = wrq->value; } @@ -1169,9 +1109,7 @@ int iwctl_siwretry(struct net_device *dev, return rc; } -/* - * Wireless Handler : get retry threshold - */ +/* Wireless Handler : get retry threshold */ int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1180,12 +1118,12 @@ int iwctl_giwretry(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); pr_debug(" SIOCGIWRETRY\n"); - wrq->disabled = 0; // Can't be disabled + wrq->disabled = 0; /* Can't be disabled */ - // Note : by default, display the min retry number + /* Note : by default, display the min retry number */ if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { wrq->flags = IW_RETRY_LIFETIME; - wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms + wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; /* ms */ } else if ((wrq->flags & IW_RETRY_MAX)) { wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrq->value = (int)pDevice->byLongRetryLimit; @@ -1199,9 +1137,7 @@ int iwctl_giwretry(struct net_device *dev, return 0; } -/* - * Wireless Handler : set encode mode - */ +/* Wireless Handler : set encode mode */ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -1213,28 +1149,30 @@ int iwctl_siwencode(struct net_device *dev, int ii, uu, rc = 0; int index = (wrq->flags & IW_ENCODE_INDEX); -//2007-0207-07, by EinsnLiu -//There are some problems when using iwconfig encode/key command to set the WEP key. -//I almost rewrite this function. -//now it support:(assume the wireless interface's name is eth0) -//iwconfig eth0 key [1] 1122334455 open /*set key stirng to index 1,and driver using key index is set to 1*/ -//iwconfig eth0 key [3] /*set driver using key index to 3,the key string no change */ -//iwconfig eth0 key 1122334455 /*set key string to driver using index*/ -//iwconfig eth0 key restricted /*enable share key*/ +/* + * There are some problems when using iwconfig encode/key command to set the + * WEP key. I almost rewrite this function. Now it supports: (assume the + * wireless interface's name is eth0) + * iwconfig eth0 key [1] 1122334455 open -> set key stirng to index 1, and + driver using key index is set to 1 + * iwconfig eth0 key [3] -> set driver using key index to 3,the key string no change + * iwconfig eth0 key 1122334455 -> set key string to driver using index + * iwconfig eth0 key restricted -> enable share key + */ PSKeyTable pkeytab; pr_debug(" SIOCSIWENCODE\n"); if ((wrq->flags & IW_ENCODE_DISABLED) == 0) { - //Not disable encryption + /* Not disable encryption */ if (dwKeyIndex > WLAN_WEP_NKEYS) { rc = -EINVAL; return rc; } - if (dwKeyIndex < 1 && ((wrq->flags & IW_ENCODE_NOKEY) == 0)) {//set default key + if (dwKeyIndex < 1 && ((wrq->flags & IW_ENCODE_NOKEY) == 0)) { /* set default key */ if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) dwKeyIndex = pDevice->byKeyIndex; else @@ -1243,13 +1181,13 @@ int iwctl_siwencode(struct net_device *dev, dwKeyIndex--; } - // Check the size of the key + /* Check the size of the key */ if (wrq->length > WLAN_WEP232_KEYLEN) { rc = -EINVAL; return rc; } - if (wrq->length > 0) {//have key + if (wrq->length > 0) { /* have key */ if (wrq->length == WLAN_WEP232_KEYLEN) { pr_debug("Set 232 bit wep key\n"); @@ -1258,7 +1196,7 @@ int iwctl_siwencode(struct net_device *dev, } else if (wrq->length == WLAN_WEP40_KEYLEN) { pr_debug("Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); - } else {//no support length + } else { /* no support length */ rc = -EINVAL; return rc; } @@ -1289,8 +1227,11 @@ int iwctl_siwencode(struct net_device *dev, pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; } else if (index > 0) { - //when the length is 0 the request only changes the default transmit key index - //check the new key if it has a non zero length + /* + * when the length is 0 the request only changes the + * default transmit key index, check the new key if it + * has a non zero length + */ if (pDevice->bEncryptionEnable == false) { rc = -EINVAL; return rc; @@ -1307,7 +1248,7 @@ int iwctl_siwencode(struct net_device *dev, pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex = dwKeyIndex | (1 << 31); } - } else {//disable the key + } else { /* disable the key */ pr_debug("Disable WEP function\n"); if (pDevice->bEncryptionEnable == false) return 0; @@ -1321,7 +1262,6 @@ int iwctl_siwencode(struct net_device *dev, spin_unlock_irq(&pDevice->lock); } } -//End Modify,Einsn if (wrq->flags & IW_ENCODE_RESTRICTED) { pr_debug("Enable WEP & ShareKey System\n"); @@ -1351,7 +1291,7 @@ int iwctl_giwencode(struct net_device *dev, if (index > WLAN_WEP_NKEYS) return -EINVAL; - if (index < 1) {//get default key + if (index < 1) { /* get default key */ if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) index = pDevice->byKeyIndex; else @@ -1361,9 +1301,9 @@ int iwctl_giwencode(struct net_device *dev, } memset(abyKey, 0, WLAN_WEP232_KEYLEN); - // Check encryption mode + /* Check encryption mode */ wrq->flags = IW_ENCODE_NOKEY; - // Is WEP enabled ??? + /* Is WEP enabled ??? */ if (pDevice->bEncryptionEnable) wrq->flags |= IW_ENCODE_ENABLED; else @@ -1376,7 +1316,7 @@ int iwctl_giwencode(struct net_device *dev, wrq->length = 0; if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled || - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) {//get wpa pairwise key + pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) { /* get wpa pairwise key */ if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) { wrq->length = pKey->uKeyLength; memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); @@ -1393,9 +1333,7 @@ int iwctl_giwencode(struct net_device *dev, return 0; } -/* - * Wireless Handler : set power mode - */ +/* Wireless Handler : set power mode */ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1443,9 +1381,7 @@ int iwctl_siwpower(struct net_device *dev, return rc; } -/* - * Wireless Handler : get power mode - */ +/* Wireless Handler : get power mode */ int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1473,9 +1409,7 @@ int iwctl_giwpower(struct net_device *dev, return 0; } -/* - * Wireless Handler : get Sensitivity - */ +/* Wireless Handler : get Sensitivity */ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -1497,7 +1431,6 @@ int iwctl_giwsens(struct net_device *dev, return 0; } -//2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT int iwctl_siwauth(struct net_device *dev, @@ -1508,7 +1441,7 @@ int iwctl_siwauth(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; - static int wpa_version = 0; //must be static to save the last value,einsn liu + static int wpa_version = 0; /* must be static to save the last value */ static int pairwise = 0; pr_debug(" SIOCSIWAUTH\n"); @@ -1532,7 +1465,7 @@ int iwctl_siwauth(struct net_device *dev, else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; else if (pairwise == IW_AUTH_CIPHER_NONE) - ; /* do nothing,einsn liu */ + ; /* do nothing */ else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; @@ -1645,7 +1578,7 @@ int iwctl_siwgenie(struct net_device *dev, pMgmt->wWPAIELen = 0; } -out://not completely ...not necessary in wpa_supplicant 0.5.8 +out: /* not completely ...not necessary in wpa_supplicant 0.5.8 */ return ret; } @@ -1682,7 +1615,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; struct viawget_wpa_param *param = NULL; -//original member +/* original member */ enum wpa_alg alg_name; u8 addr[6]; int key_idx, set_tx = 0; @@ -1699,7 +1632,7 @@ int iwctl_siwencodeext(struct net_device *dev, if (param == NULL) return -ENOMEM; -//recover alg_name +/* recover alg_name */ switch (ext->alg) { case IW_ENCODE_ALG_NONE: alg_name = WPA_ALG_NONE; @@ -1718,19 +1651,19 @@ int iwctl_siwencodeext(struct net_device *dev, ret = -ENOMEM; goto error; } -//recover addr +/* recover addr */ ether_addr_copy(addr, ext->addr.sa_data); -//recover key_idx +/* recover key_idx */ key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; -//recover set_tx +/* recover set_tx */ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) set_tx = 1; -//recover seq,seq_len +/* recover seq,seq_len */ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { seq_len = IW_ENCODE_SEQ_MAX_SIZE; memcpy(seq, ext->rx_seq, seq_len); } -//recover key,key_len +/* recover key,key_len */ if (ext->key_len) { key_len = ext->key_len; memcpy(key, &ext->key[0], key_len); @@ -1740,7 +1673,7 @@ int iwctl_siwencodeext(struct net_device *dev, if (key_len > 0) { memcpy(key_array, key, key_len); if (key_len == 32) { - // notice ! the oder + /* notice ! the oder */ memcpy(&key_array[16], &key[24], 8); memcpy(&key_array[24], &key[16], 8); } @@ -1756,8 +1689,10 @@ int iwctl_siwencodeext(struct net_device *dev, param->u.wpa_key.seq = (u8 *)seq; param->u.wpa_key.seq_len = seq_len; -//****set if current action is Network Manager count?? -//****this method is so foolish,but there is no other way??? +/* + * set if current action is Network Manager count?? this method is so + * foolish,but there is no other way??? + */ if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { if (param->u.wpa_key.key_index == 0) pDevice->bwextcount++; @@ -1777,7 +1712,6 @@ int iwctl_siwencodeext(struct net_device *dev, pDevice->bwextcount = 0; pDevice->bWPASuppWextEnabled = true; } -//****** spin_lock_irq(&pDevice->lock); ret = wpa_set_keys(pDevice, param, true); @@ -1817,13 +1751,15 @@ int iwctl_siwmlme(struct net_device *dev, } switch (mime.cmd) { case IW_MLME_DEAUTH: - //this command seems to be not complete,please test it --einsnliu - //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); + /* + * this command seems to be not complete,please test it --einsnliu + * bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); + */ break; case IW_MLME_DISASSOC: if (pDevice->bLinkPass == true) { pr_debug("iwctl_siwmlme--->send DISASSOCIATE\n"); - //clear related flags + /* clear related flags */ memset(pMgmt->abyDesireBSSID, 0xFF, 6); KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); @@ -1838,76 +1774,70 @@ int iwctl_siwmlme(struct net_device *dev, #endif -/*------------------------------------------------------------------*/ -/* - * Structures to export the Wireless Handlers - */ - +/* Structures to export the Wireless Handlers */ static const iw_handler iwctl_handler[] = { - (iw_handler) iwctl_commit, // SIOCSIWCOMMIT - (iw_handler) NULL, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (iw_handler) NULL, // SIOCGIWNWID - (iw_handler) NULL, // SIOCSIWFREQ - (iw_handler) NULL, // SIOCGIWFREQ - (iw_handler) NULL, // SIOCSIWMODE - (iw_handler) NULL, // SIOCGIWMODE - (iw_handler) NULL, // SIOCSIWSENS - (iw_handler) NULL, // SIOCGIWSENS - (iw_handler) NULL, // SIOCSIWRANGE - (iw_handler) iwctl_giwrange, // SIOCGIWRANGE - (iw_handler) NULL, // SIOCSIWPRIV - (iw_handler) NULL, // SIOCGIWPRIV - (iw_handler) NULL, // SIOCSIWSTATS - (iw_handler) NULL, // SIOCGIWSTATS - (iw_handler) NULL, // SIOCSIWSPY - (iw_handler) NULL, // SIOCGIWSPY - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWAP - (iw_handler) NULL, // SIOCGIWAP - (iw_handler) NULL, // -- hole -- 0x16 - (iw_handler) NULL, // SIOCGIWAPLIST - (iw_handler) iwctl_siwscan, // SIOCSIWSCAN - (iw_handler) iwctl_giwscan, // SIOCGIWSCAN - (iw_handler) NULL, // SIOCSIWESSID - (iw_handler) NULL, // SIOCGIWESSID - (iw_handler) NULL, // SIOCSIWNICKN - (iw_handler) NULL, // SIOCGIWNICKN - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWRATE 0x20 - (iw_handler) NULL, // SIOCGIWRATE - (iw_handler) NULL, // SIOCSIWRTS - (iw_handler) NULL, // SIOCGIWRTS - (iw_handler) NULL, // SIOCSIWFRAG - (iw_handler) NULL, // SIOCGIWFRAG - (iw_handler) NULL, // SIOCSIWTXPOW - (iw_handler) NULL, // SIOCGIWTXPOW - (iw_handler) NULL, // SIOCSIWRETRY - (iw_handler) NULL, // SIOCGIWRETRY - (iw_handler) NULL, // SIOCSIWENCODE - (iw_handler) NULL, // SIOCGIWENCODE - (iw_handler) NULL, // SIOCSIWPOWER - (iw_handler) NULL, // SIOCGIWPOWER - -//2008-0409-07, by Einsn Liu - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // -- hole -- - (iw_handler) NULL, // SIOCSIWGENIE - (iw_handler) NULL, // SIOCGIWGENIE - (iw_handler) NULL, // SIOCSIWAUTH - (iw_handler) NULL, // SIOCGIWAUTH - (iw_handler) NULL, // SIOCSIWENCODEEXT - (iw_handler) NULL, // SIOCGIWENCODEEXT - (iw_handler) NULL, // SIOCSIWPMKSA - (iw_handler) NULL, // -- hole -- + (iw_handler) iwctl_commit, /* SIOCSIWCOMMIT */ + (iw_handler) NULL, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) NULL, /* SIOCSIWFREQ */ + (iw_handler) NULL, /* SIOCGIWFREQ */ + (iw_handler) NULL, /* SIOCSIWMODE */ + (iw_handler) NULL, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) iwctl_giwrange, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + (iw_handler) NULL, /* SIOCSIWSPY */ + (iw_handler) NULL, /* SIOCGIWSPY */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) NULL, /* SIOCGIWAP */ + (iw_handler) NULL, /* -- hole -- 0x16 */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) iwctl_siwscan, /* SIOCSIWSCAN */ + (iw_handler) iwctl_giwscan, /* SIOCGIWSCAN */ + (iw_handler) NULL, /* SIOCSIWESSID */ + (iw_handler) NULL, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) NULL, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWRATE 0x20 */ + (iw_handler) NULL, /* SIOCGIWRATE */ + (iw_handler) NULL, /* SIOCSIWRTS */ + (iw_handler) NULL, /* SIOCGIWRTS */ + (iw_handler) NULL, /* SIOCSIWFRAG */ + (iw_handler) NULL, /* SIOCGIWFRAG */ + (iw_handler) NULL, /* SIOCSIWTXPOW */ + (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) NULL, /* SIOCSIWRETRY */ + (iw_handler) NULL, /* SIOCGIWRETRY */ + (iw_handler) NULL, /* SIOCSIWENCODE */ + (iw_handler) NULL, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWGENIE */ + (iw_handler) NULL, /* SIOCGIWGENIE */ + (iw_handler) NULL, /* SIOCSIWAUTH */ + (iw_handler) NULL, /* SIOCGIWAUTH */ + (iw_handler) NULL, /* SIOCSIWENCODEEXT */ + (iw_handler) NULL, /* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ + (iw_handler) NULL, /* -- hole -- */ }; static const iw_handler iwctl_private_handler[] = { - NULL, // SIOCIWFIRSTPRIV + NULL, /* SIOCIWFIRSTPRIV */ }; struct iw_priv_args iwctl_private_args[] = { -- GitLab From 8a43572c32ffbfe122c38873e29e98ef7ace1709 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 25 Oct 2014 23:33:06 +0200 Subject: [PATCH 1577/9457] staging: dgnc: dgnc_kcompat.h: remove unused macros This patch removes the macros PARM_STR and PARM_ULONG given that they are not used anywhere in the driver files. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_kcompat.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_kcompat.h b/drivers/staging/dgnc/dgnc_kcompat.h index eaec7e6a28e1..4a347e54fe7f 100644 --- a/drivers/staging/dgnc/dgnc_kcompat.h +++ b/drivers/staging/dgnc/dgnc_kcompat.h @@ -42,23 +42,10 @@ # define __chk_user_ptr(x) (void)0 # endif - -# define PARM_STR(VAR, INIT, PERM, DESC) \ - static char *VAR = INIT; \ - char *dgnc_##VAR; \ - module_param(VAR, charp, PERM); \ - MODULE_PARM_DESC(VAR, DESC); - # define PARM_INT(VAR, INIT, PERM, DESC) \ static int VAR = INIT; \ int dgnc_##VAR; \ module_param(VAR, int, PERM); \ MODULE_PARM_DESC(VAR, DESC); -# define PARM_ULONG(VAR, INIT, PERM, DESC) \ - static ulong VAR = INIT; \ - ulong dgnc_##VAR; \ - module_param(VAR, long, PERM); \ - MODULE_PARM_DESC(VAR, DESC); - #endif /* ! __DGNC_KCOMPAT_H */ -- GitLab From 6db43a9c388061060dfab0146d4f4e1cc990ecf8 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 25 Oct 2014 23:40:15 +0200 Subject: [PATCH 1578/9457] staging: dgnc: dgnc_driver: remove all occurences of trcbuf_size This patch removes the variable trcbuf_size given there is no real use for it anymore. All of the debug variables in this driver is basically dead code. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 2 -- drivers/staging/dgnc/dgnc_driver.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 0eafd1f35a82..62843d6f8d05 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -57,7 +57,6 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ PARM_INT(debug, 0x00, 0644, "Driver debugging level"); PARM_INT(rawreadok, 1, 0644, "Bypass flip buffers on input"); -PARM_INT(trcbuf_size, 0x100000, 0644, "Debugging trace buffer size."); /************************************************************************** * @@ -743,7 +742,6 @@ static void dgnc_init_globals(void) int i = 0; dgnc_rawreadok = rawreadok; - dgnc_trcbuf_size = trcbuf_size; dgnc_debug = debug; dgnc_NumBoards = 0; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 695c3c6d3233..f1b15645a82f 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -431,7 +431,6 @@ extern uint dgnc_Major; /* Our driver/mgmt major */ extern int dgnc_debug; /* Debug variable */ extern int dgnc_rawreadok; /* Set if user wants rawreads */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ -extern int dgnc_trcbuf_size; /* Size of the ringbuffer */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern uint dgnc_NumBoards; /* Total number of boards */ extern struct dgnc_board *dgnc_Board[MAXBOARDS]; /* Array of board structs */ -- GitLab From ade5b9435bd6038f552dd25f7529103a7c7af5ff Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 25 Oct 2014 23:43:33 +0200 Subject: [PATCH 1579/9457] staging: dgnc: remove unused variable named rawreadok This patch removes the variable rawreadok since it is only intialized but not used in any of the driver functions. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 2 -- drivers/staging/dgnc/dgnc_driver.h | 1 - drivers/staging/dgnc/dgnc_sysfs.c | 19 ------------------- 3 files changed, 22 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 62843d6f8d05..bf8632841c2e 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -56,7 +56,6 @@ MODULE_SUPPORTED_DEVICE("dgnc"); * us to specify the variable type, name, initial value, and description. */ PARM_INT(debug, 0x00, 0644, "Driver debugging level"); -PARM_INT(rawreadok, 1, 0644, "Bypass flip buffers on input"); /************************************************************************** * @@ -741,7 +740,6 @@ static void dgnc_init_globals(void) { int i = 0; - dgnc_rawreadok = rawreadok; dgnc_debug = debug; dgnc_NumBoards = 0; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index f1b15645a82f..e67b913224ec 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -429,7 +429,6 @@ struct channel_t { */ extern uint dgnc_Major; /* Our driver/mgmt major */ extern int dgnc_debug; /* Debug variable */ -extern int dgnc_rawreadok; /* Set if user wants rawreads */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern uint dgnc_NumBoards; /* Total number of boards */ diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 6c3b387622e9..ba0d8ac2d32a 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -80,23 +80,6 @@ static ssize_t dgnc_driver_debug_store(struct device_driver *ddp, const char *bu static DRIVER_ATTR(debug, (S_IRUSR | S_IWUSR), dgnc_driver_debug_show, dgnc_driver_debug_store); -static ssize_t dgnc_driver_rawreadok_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%x\n", dgnc_rawreadok); -} - -static ssize_t dgnc_driver_rawreadok_store(struct device_driver *ddp, const char *buf, size_t count) -{ - int ret; - - ret = sscanf(buf, "0x%x\n", &dgnc_rawreadok); - if (ret != 1) - return -EINVAL; - return count; -} -static DRIVER_ATTR(rawreadok, (S_IRUSR | S_IWUSR), dgnc_driver_rawreadok_show, dgnc_driver_rawreadok_store); - - static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf) { return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick); @@ -123,7 +106,6 @@ void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) rc |= driver_create_file(driverfs, &driver_attr_boards); rc |= driver_create_file(driverfs, &driver_attr_maxboards); rc |= driver_create_file(driverfs, &driver_attr_debug); - rc |= driver_create_file(driverfs, &driver_attr_rawreadok); rc |= driver_create_file(driverfs, &driver_attr_pollrate); if (rc) printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n"); @@ -138,7 +120,6 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) driver_remove_file(driverfs, &driver_attr_boards); driver_remove_file(driverfs, &driver_attr_maxboards); driver_remove_file(driverfs, &driver_attr_debug); - driver_remove_file(driverfs, &driver_attr_rawreadok); driver_remove_file(driverfs, &driver_attr_pollrate); } -- GitLab From 2a71a3c7c7c1add1ecbfba4ef77c28ef234e82b4 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 25 Oct 2014 23:46:03 +0200 Subject: [PATCH 1580/9457] staging: dgnc: remove debug symbols This patch removes all of the debug symbols and the variable dgnc_debug since they are not used anywhere in the code. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 9 --------- drivers/staging/dgnc/dgnc_driver.h | 32 +----------------------------- drivers/staging/dgnc/dgnc_sysfs.c | 18 ----------------- 3 files changed, 1 insertion(+), 58 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index bf8632841c2e..ba98ff348112 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -49,14 +49,6 @@ MODULE_AUTHOR("Digi International, http://www.digi.com"); MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_SUPPORTED_DEVICE("dgnc"); -/* - * insmod command line overrideable parameters - * - * NOTE: we use a set of macros to create the variables, which allows - * us to specify the variable type, name, initial value, and description. - */ -PARM_INT(debug, 0x00, 0644, "Driver debugging level"); - /************************************************************************** * * protos for this file @@ -740,7 +732,6 @@ static void dgnc_init_globals(void) { int i = 0; - dgnc_debug = debug; dgnc_NumBoards = 0; for (i = 0; i < MAXBOARDS; i++) diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index e67b913224ec..a8157eba28da 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -42,42 +42,13 @@ * *************************************************************************/ -/* Driver identification, error and debugging statments */ +/* Driver identification and error statments */ #define PROCSTR "dgnc" /* /proc entries */ #define DEVSTR "/dev/dg/dgnc" /* /dev entries */ #define DRVSTR "dgnc" /* Driver name string */ #define TRC_TO_CONSOLE 1 -/* - * Debugging levels can be set using debug insmod variable - * They can also be compiled out completely. - */ - -#define DBG_INIT (dgnc_debug & 0x01) -#define DBG_BASIC (dgnc_debug & 0x02) -#define DBG_CORE (dgnc_debug & 0x04) - -#define DBG_OPEN (dgnc_debug & 0x08) -#define DBG_CLOSE (dgnc_debug & 0x10) -#define DBG_READ (dgnc_debug & 0x20) -#define DBG_WRITE (dgnc_debug & 0x40) - -#define DBG_IOCTL (dgnc_debug & 0x80) - -#define DBG_PROC (dgnc_debug & 0x100) -#define DBG_PARAM (dgnc_debug & 0x200) -#define DBG_PSCAN (dgnc_debug & 0x400) -#define DBG_EVENT (dgnc_debug & 0x800) - -#define DBG_DRAIN (dgnc_debug & 0x1000) -#define DBG_MSIGS (dgnc_debug & 0x2000) - -#define DBG_MGMT (dgnc_debug & 0x4000) -#define DBG_INTR (dgnc_debug & 0x8000) - -#define DBG_CARR (dgnc_debug & 0x10000) - /* Number of boards we support at once. */ #define MAXBOARDS 20 #define MAXPORTS 8 @@ -428,7 +399,6 @@ struct channel_t { * Our Global Variables. */ extern uint dgnc_Major; /* Our driver/mgmt major */ -extern int dgnc_debug; /* Debug variable */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern uint dgnc_NumBoards; /* Total number of boards */ diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index ba0d8ac2d32a..2fd34ca70c59 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -63,22 +63,6 @@ static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf) } static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL); -static ssize_t dgnc_driver_debug_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%x\n", dgnc_debug); -} - -static ssize_t dgnc_driver_debug_store(struct device_driver *ddp, const char *buf, size_t count) -{ - int ret; - - ret = sscanf(buf, "0x%x\n", &dgnc_debug); - if (ret != 1) - return -EINVAL; - return count; -} -static DRIVER_ATTR(debug, (S_IRUSR | S_IWUSR), dgnc_driver_debug_show, dgnc_driver_debug_store); - static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf) { @@ -105,7 +89,6 @@ void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) rc |= driver_create_file(driverfs, &driver_attr_version); rc |= driver_create_file(driverfs, &driver_attr_boards); rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_debug); rc |= driver_create_file(driverfs, &driver_attr_pollrate); if (rc) printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n"); @@ -119,7 +102,6 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) driver_remove_file(driverfs, &driver_attr_version); driver_remove_file(driverfs, &driver_attr_boards); driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_debug); driver_remove_file(driverfs, &driver_attr_pollrate); } -- GitLab From ac611dc60fc0cc050344861668f916c191f4b6cd Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sat, 25 Oct 2014 23:47:57 +0200 Subject: [PATCH 1581/9457] staging: dgnc: dgnc_kcompat.h: remove unused macro This patch removes the macro PARM_INT after removing all the variables that depended on it. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_kcompat.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_kcompat.h b/drivers/staging/dgnc/dgnc_kcompat.h index 4a347e54fe7f..566cad0d33e7 100644 --- a/drivers/staging/dgnc/dgnc_kcompat.h +++ b/drivers/staging/dgnc/dgnc_kcompat.h @@ -42,10 +42,5 @@ # define __chk_user_ptr(x) (void)0 # endif -# define PARM_INT(VAR, INIT, PERM, DESC) \ - static int VAR = INIT; \ - int dgnc_##VAR; \ - module_param(VAR, int, PERM); \ - MODULE_PARM_DESC(VAR, DESC); #endif /* ! __DGNC_KCOMPAT_H */ -- GitLab From 353fdf17060b15d1d857899cd3ed9d5db4818acf Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sun, 26 Oct 2014 19:20:16 +0530 Subject: [PATCH 1582/9457] staging: android: Replace timeval with timespec64 'timeval' is used to print timestamps in seconds and millisecond. 32-bit systems using 'struct timeval' will break in the year 2038, So we have to replace that code with more appropriate types. This patch changes the android driver to use timespec64. Since this is a staging driver and the output is only used for a debugfs file, it is fine to slightly change the output and use nanoseconds instead. ktime_to_timespec64, is used which will return seconds and nanoseconds. Signed-off-by: Tapasweni Pathak Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sync_debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c index 257fc91bf02b..1532a86404be 100644 --- a/drivers/staging/android/sync_debug.c +++ b/drivers/staging/android/sync_debug.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "sync.h" #ifdef CONFIG_DEBUG_FS @@ -95,9 +96,9 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) sync_status_str(status)); if (status <= 0) { - struct timeval tv = ktime_to_timeval(pt->base.timestamp); + struct timespec64 ts64 = ktime_to_timespec64(pt->base.timestamp); - seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec); + seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); } if (parent->ops->timeline_value_str && -- GitLab From 43f61da20769923f951ded489b3b2de2e5dc0e3f Mon Sep 17 00:00:00 2001 From: Melike Yurtoglu Date: Sun, 26 Oct 2014 23:55:22 +0200 Subject: [PATCH 1583/9457] staging: ozwpan: Fix incorrect type in assignments This patch fixes following sparse warnings: drivers/staging/ozwpan/ozhcd.c:1917:35: warning: incorrect type in assignment (different base types) drivers/staging/ozwpan/ozhcd.c:1917:35: expected restricted __le16 [usertype] wHubCharacteristics drivers/staging/ozwpan/ozhcd.c:1917:35: got unsigned short [unsigned] [usertype] Signed-off-by: Melike Yurtoglu Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 8a52feb6e72e..3d03e9255831 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1914,7 +1914,7 @@ static void oz_get_hub_descriptor(struct usb_hcd *hcd, memset(desc, 0, sizeof(*desc)); desc->bDescriptorType = 0x29; desc->bDescLength = 9; - desc->wHubCharacteristics = (__force __u16)cpu_to_le16(0x0001); + desc->wHubCharacteristics = cpu_to_le16(0x0001); desc->bNbrPorts = OZ_NB_PORTS; } -- GitLab From ac2f46c365e655dd2c366f69c609febc4ac310fd Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sun, 26 Oct 2014 20:38:32 +0530 Subject: [PATCH 1584/9457] staging: dgap: Use unsigned for loop index The following semantic patch is used to do this @r exists@ // find anything that might decrement the variable identifier i; expression E; position p; @@ int i@p; ... ( &i | i-- | --i | i-=E | i+=E ) @x disable decl_init@ identifier r.i; expression E; position p1 != r.p; @@ ( volatile int i = 0; | volatile int i; | + unsigned int i@p1 = 0; | + unsigned int i@p1; ) <... when != i = E ( i = 0 | i = 1 ) ...> Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index ad8c8ecaaf06..dfdf20969987 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -656,7 +656,7 @@ static void dgap_remove_one(struct pci_dev *dev) */ static void dgap_cleanup_module(void) { - int i; + unsigned int i; ulong lock_flags; spin_lock_irqsave(&dgap_poll_lock, lock_flags); @@ -691,7 +691,7 @@ static void dgap_cleanup_module(void) */ static void dgap_cleanup_board(struct board_t *brd) { - int i; + unsigned int i; if (!brd || brd->magic != DGAP_BOARD_MAGIC) return; @@ -1063,7 +1063,7 @@ static void dgap_unmap(struct board_t *brd) static void dgap_poll_handler(ulong dummy) { - int i; + unsigned int i; struct board_t *brd; unsigned long lock_flags; ulong new_time; @@ -1196,7 +1196,7 @@ static irqreturn_t dgap_intr(int irq, void *voidbrd) */ static void dgap_init_globals(void) { - int i; + unsigned int i; for (i = 0; i < MAXBOARDS; i++) dgap_board[i] = NULL; @@ -1515,7 +1515,7 @@ static void dgap_tty_free(struct board_t *brd) static void dgap_cleanup_tty(struct board_t *brd) { struct device *dev; - int i; + unsigned int i; dgap_boards_by_major[brd->serial_driver->major] = NULL; brd->dgap_serial_major = 0; @@ -4121,7 +4121,7 @@ static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len) { u8 __iomem *addr; uint offset; - int i; + unsigned int i; if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) return; @@ -4217,7 +4217,7 @@ static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len) u8 string[100]; u8 __iomem *config; u8 *xconfig; - int i = 0; + unsigned int i = 0; xconfig = dgap_create_config_string(brd, string); @@ -4293,7 +4293,7 @@ static void dgap_do_reset_board(struct board_t *brd) u8 check; u32 check1; u32 check2; - int i; + unsigned int i; if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase || !brd->re_map_port) @@ -5630,7 +5630,7 @@ static ssize_t dgap_ports_state_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5651,7 +5651,7 @@ static ssize_t dgap_ports_baud_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5672,7 +5672,7 @@ static ssize_t dgap_ports_msignals_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5709,7 +5709,7 @@ static ssize_t dgap_ports_iflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5729,7 +5729,7 @@ static ssize_t dgap_ports_cflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5749,7 +5749,7 @@ static ssize_t dgap_ports_oflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5769,7 +5769,7 @@ static ssize_t dgap_ports_lflag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5789,7 +5789,7 @@ static ssize_t dgap_ports_digi_flag_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5809,7 +5809,7 @@ static ssize_t dgap_ports_rxcount_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) @@ -5829,7 +5829,7 @@ static ssize_t dgap_ports_txcount_show(struct device *p, { struct board_t *bd; int count = 0; - int i; + unsigned int i; bd = dgap_verify_board(p); if (!bd) -- GitLab From 6b9214b793a4ae2350f748a587a61a267bfd119b Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 27 Oct 2014 19:58:20 +0530 Subject: [PATCH 1585/9457] Staging: comedi: nio_tiocmd: fixed a brace coding style issue. Removed unnecessary braces using checkpatch.pl tool Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 46cf3eb2ee54..6037bec77ef1 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -449,11 +449,10 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, return; } gpct_mite_status = mite_get_status(counter->mite_chan); - if (gpct_mite_status & CHSR_LINKC) { + if (gpct_mite_status & CHSR_LINKC) writel(CHOR_CLRLC, counter->mite_chan->mite->mite_io_addr + MITE_CHOR(counter->mite_chan->channel)); - } mite_sync_input_dma(counter->mite_chan, s); spin_unlock_irqrestore(&counter->lock, flags); } -- GitLab From 346b0d4a0818fa76bfe0dbe67c6c7ad3e19845e1 Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Tue, 28 Oct 2014 10:46:35 +0200 Subject: [PATCH 1586/9457] staging: ft1000: Remove curly braces for single statement blocks This patch removes curly braces for single statement blocks using following coccinelle script: @@ expression e1; @@ - if (e1) { + if (e1) return ...; - } Signed-off-by: Ebru Akagunduz Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 5899c4eca41f..4672c4d56205 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -540,17 +540,14 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/ - if (ft1000_flarion_cnt == 0) { + if (ft1000_flarion_cnt == 0) return -EBADF; - } - if (ft1000dev->DrvMsgPend) { + if (ft1000dev->DrvMsgPend) return -ENOTTY; - } - if (ft1000dev->fProvComplete == 0) { + if (ft1000dev->fProvComplete == 0) return -EACCES; - } ft1000dev->fAppMsgPend = 1; @@ -677,9 +674,8 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ - if (ft1000_flarion_cnt == 0) { + if (ft1000_flarion_cnt == 0) return -EBADF; - } /* Search for matching file object */ for (i=0; i Date: Wed, 1 Oct 2014 14:48:42 +0200 Subject: [PATCH 1587/9457] KVM: s390: Make the simple ipte mutex specific to a VM instead of global The ipte-locking should be done for each VM seperately, not globally. This way we avoid possible congestions when the simple ipte-lock is used and multiple VMs are running. Suggested-by: Heiko Carstens Signed-off-by: Thomas Huth Acked-by: Heiko Carstens Reviewed-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 2 ++ arch/s390/kvm/gaccess.c | 20 +++++++++----------- arch/s390/kvm/kvm-s390.c | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 2175f911a73a..584b820eeaf8 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -434,6 +434,8 @@ struct kvm_arch{ int user_cpu_state_ctrl; struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; wait_queue_head_t ipte_wq; + int ipte_lock_count; + struct mutex ipte_mutex; spinlock_t start_stop_lock; struct kvm_s390_crypto crypto; }; diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 0f961a1c64b3..c1424e8b7f09 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -207,8 +207,6 @@ union raddress { unsigned long pfra : 52; /* Page-Frame Real Address */ }; -static int ipte_lock_count; -static DEFINE_MUTEX(ipte_mutex); int ipte_lock_held(struct kvm_vcpu *vcpu) { @@ -216,16 +214,16 @@ int ipte_lock_held(struct kvm_vcpu *vcpu) if (vcpu->arch.sie_block->eca & 1) return ic->kh != 0; - return ipte_lock_count != 0; + return vcpu->kvm->arch.ipte_lock_count != 0; } static void ipte_lock_simple(struct kvm_vcpu *vcpu) { union ipte_control old, new, *ic; - mutex_lock(&ipte_mutex); - ipte_lock_count++; - if (ipte_lock_count > 1) + mutex_lock(&vcpu->kvm->arch.ipte_mutex); + vcpu->kvm->arch.ipte_lock_count++; + if (vcpu->kvm->arch.ipte_lock_count > 1) goto out; ic = &vcpu->kvm->arch.sca->ipte_control; do { @@ -238,16 +236,16 @@ static void ipte_lock_simple(struct kvm_vcpu *vcpu) new.k = 1; } while (cmpxchg(&ic->val, old.val, new.val) != old.val); out: - mutex_unlock(&ipte_mutex); + mutex_unlock(&vcpu->kvm->arch.ipte_mutex); } static void ipte_unlock_simple(struct kvm_vcpu *vcpu) { union ipte_control old, new, *ic; - mutex_lock(&ipte_mutex); - ipte_lock_count--; - if (ipte_lock_count) + mutex_lock(&vcpu->kvm->arch.ipte_mutex); + vcpu->kvm->arch.ipte_lock_count--; + if (vcpu->kvm->arch.ipte_lock_count) goto out; ic = &vcpu->kvm->arch.sca->ipte_control; do { @@ -256,7 +254,7 @@ static void ipte_unlock_simple(struct kvm_vcpu *vcpu) } while (cmpxchg(&ic->val, old.val, new.val) != old.val); wake_up(&vcpu->kvm->arch.ipte_wq); out: - mutex_unlock(&ipte_mutex); + mutex_unlock(&vcpu->kvm->arch.ipte_mutex); } static void ipte_lock_siif(struct kvm_vcpu *vcpu) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 55aade49b6d1..3e83d4b357b9 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -453,6 +453,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) spin_lock_init(&kvm->arch.float_int.lock); INIT_LIST_HEAD(&kvm->arch.float_int.list); init_waitqueue_head(&kvm->arch.ipte_wq); + mutex_init(&kvm->arch.ipte_mutex); debug_register_view(kvm->arch.dbf, &debug_sprintf_view); VM_EVENT(kvm, 3, "%s", "vm created"); -- GitLab From edeb69e53729342ec08a0906e1208d846a5e4f4c Mon Sep 17 00:00:00 2001 From: "Jason J. Herne" Date: Tue, 7 Oct 2014 13:31:37 -0400 Subject: [PATCH 1588/9457] KVM: s390: Cleanup usage of current->mm in set_guest_storage_key In set_guest_storage_key, we really want to reference the mm struct given as a parameter to the function. So replace the current->mm reference with the mm struct passed in by the caller. Signed-off-by: Jason J. Herne Signed-off-by: Christian Borntraeger --- arch/s390/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 1b79ca67392f..cfecc241f9a4 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -936,7 +936,7 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, down_read(&mm->mmap_sem); retry: - ptep = get_locked_pte(current->mm, addr, &ptl); + ptep = get_locked_pte(mm, addr, &ptl); if (unlikely(!ptep)) { up_read(&mm->mmap_sem); return -EFAULT; -- GitLab From a36c5393266222129ce6f622e3bc3fb5463f290c Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 16 Oct 2014 14:31:53 +0200 Subject: [PATCH 1589/9457] KVM: s390: Fix size of monitor-class number field The monitor-class number field is only 16 bits, so we have to use a u16 pointer to access it. Signed-off-by: Thomas Huth Reviewed-by: David Hildenbrand CC: stable@vger.kernel.org # v3.16+ Signed-off-by: Christian Borntraeger --- arch/s390/kvm/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a39838457f01..4fc3fed636dc 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -270,7 +270,7 @@ static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, break; case PGM_MONITOR: rc = put_guest_lc(vcpu, pgm_info->mon_class_nr, - (u64 *)__LC_MON_CLASS_NR); + (u16 *)__LC_MON_CLASS_NR); rc |= put_guest_lc(vcpu, pgm_info->mon_code, (u64 *)__LC_MON_CODE); break; -- GitLab From 3526a66b66e3a997fb7d77af2f65dbdd77d2556e Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 19 Mar 2014 14:57:49 +0100 Subject: [PATCH 1590/9457] KVM: s390: sigp: dispatch orders with one target in a separate function All sigp orders except SIGP SET ARCHITECTURE target exactly one vcpu. Let's move the dispatch code for these orders into a separate function to prepare for cleaner target availability checks. Signed-off-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kvm/sigp.c | 74 +++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index cf243ba3d50f..5e259bd62515 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -349,32 +349,15 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) return rc; } -int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) +static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, + u16 cpu_addr, u32 parameter, u64 *status_reg) { - int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; - int r3 = vcpu->arch.sie_block->ipa & 0x000f; - u32 parameter; - u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; - u8 order_code; int rc; - /* sigp in userspace can exit */ - if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) - return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); - - order_code = kvm_s390_get_base_disp_rs(vcpu); - - if (r1 % 2) - parameter = vcpu->run->s.regs.gprs[r1]; - else - parameter = vcpu->run->s.regs.gprs[r1 + 1]; - - trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); switch (order_code) { case SIGP_SENSE: vcpu->stat.instruction_sigp_sense++; - rc = __sigp_sense(vcpu, cpu_addr, - &vcpu->run->s.regs.gprs[r1]); + rc = __sigp_sense(vcpu, cpu_addr, status_reg); break; case SIGP_EXTERNAL_CALL: vcpu->stat.instruction_sigp_external_call++; @@ -395,25 +378,19 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) break; case SIGP_STORE_STATUS_AT_ADDRESS: rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, - &vcpu->run->s.regs.gprs[r1]); - break; - case SIGP_SET_ARCHITECTURE: - vcpu->stat.instruction_sigp_arch++; - rc = __sigp_set_arch(vcpu, parameter); + status_reg); break; case SIGP_SET_PREFIX: vcpu->stat.instruction_sigp_prefix++; - rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, - &vcpu->run->s.regs.gprs[r1]); + rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, status_reg); break; case SIGP_COND_EMERGENCY_SIGNAL: rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, - &vcpu->run->s.regs.gprs[r1]); + status_reg); break; case SIGP_SENSE_RUNNING: vcpu->stat.instruction_sigp_sense_running++; - rc = __sigp_sense_running(vcpu, cpu_addr, - &vcpu->run->s.regs.gprs[r1]); + rc = __sigp_sense_running(vcpu, cpu_addr, status_reg); break; case SIGP_START: rc = sigp_check_callable(vcpu, cpu_addr); @@ -432,7 +409,42 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) } break; default: - return -EOPNOTSUPP; + rc = -EOPNOTSUPP; + } + + return rc; +} + +int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) +{ + int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; + int r3 = vcpu->arch.sie_block->ipa & 0x000f; + u32 parameter; + u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; + u8 order_code; + int rc; + + /* sigp in userspace can exit */ + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); + + order_code = kvm_s390_get_base_disp_rs(vcpu); + + if (r1 % 2) + parameter = vcpu->run->s.regs.gprs[r1]; + else + parameter = vcpu->run->s.regs.gprs[r1 + 1]; + + trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); + switch (order_code) { + case SIGP_SET_ARCHITECTURE: + vcpu->stat.instruction_sigp_arch++; + rc = __sigp_set_arch(vcpu, parameter); + break; + default: + rc = handle_sigp_dst(vcpu, order_code, cpu_addr, + parameter, + &vcpu->run->s.regs.gprs[r1]); } if (rc < 0) -- GitLab From 3d95c7d2d7cb9a1f47e9a46473413844c6245c15 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 19 Mar 2014 16:59:39 +0100 Subject: [PATCH 1591/9457] KVM: s390: sigp: move target cpu checks into dispatcher All sigp orders targeting one VCPU have to verify that the target is valid and available. Let's move the check from the single functions to the dispatcher. The destination VCPU is directly passed as a pointer - instead of the cpu address of the target. Please note that all SIGP orders except SIGP SET ARCHITECTURE - even unknown ones - will now check for the availability of the target VCPU. This is what the architecture documentation specifies. Signed-off-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kvm/sigp.c | 139 +++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 91 deletions(-) diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 5e259bd62515..660a9459ff2a 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -20,20 +20,13 @@ #include "kvm-s390.h" #include "trace.h" -static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, +static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, u64 *reg) { struct kvm_s390_local_interrupt *li; - struct kvm_vcpu *dst_vcpu = NULL; int cpuflags; int rc; - if (cpu_addr >= KVM_MAX_VCPUS) - return SIGP_CC_NOT_OPERATIONAL; - - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; li = &dst_vcpu->arch.local_int; cpuflags = atomic_read(li->cpuflags); @@ -48,44 +41,36 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, rc = SIGP_CC_STATUS_STORED; } - VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", cpu_addr, rc); + VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", dst_vcpu->vcpu_id, + rc); return rc; } -static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) +static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) { struct kvm_s390_interrupt s390int = { .type = KVM_S390_INT_EMERGENCY, .parm = vcpu->vcpu_id, }; - struct kvm_vcpu *dst_vcpu = NULL; int rc = 0; - if (cpu_addr < KVM_MAX_VCPUS) - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int); if (!rc) - VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr); + VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", + dst_vcpu->vcpu_id); return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; } -static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, +static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u16 asn, u64 *reg) { - struct kvm_vcpu *dst_vcpu = NULL; const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; u16 p_asn, s_asn; psw_t *psw; u32 flags; - if (cpu_addr < KVM_MAX_VCPUS) - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); psw = &dst_vcpu->arch.sie_block->gpsw; p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ @@ -96,7 +81,7 @@ static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, || (psw->mask & psw_int_mask) != psw_int_mask || ((flags & CPUSTAT_WAIT) && psw->addr != 0) || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { - return __sigp_emergency(vcpu, cpu_addr); + return __sigp_emergency(vcpu, dst_vcpu); } else { *reg &= 0xffffffff00000000UL; *reg |= SIGP_STATUS_INCORRECT_STATE; @@ -104,23 +89,19 @@ static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, } } -static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) +static int __sigp_external_call(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu) { struct kvm_s390_interrupt s390int = { .type = KVM_S390_INT_EXTERNAL_CALL, .parm = vcpu->vcpu_id, }; - struct kvm_vcpu *dst_vcpu = NULL; int rc; - if (cpu_addr < KVM_MAX_VCPUS) - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int); if (!rc) - VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr); + VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", + dst_vcpu->vcpu_id); return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; } @@ -160,21 +141,13 @@ static int __inject_sigp_stop(struct kvm_vcpu *dst_vcpu, int action) return rc; } -static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) +static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, + int action) { - struct kvm_vcpu *dst_vcpu = NULL; int rc; - if (cpu_addr >= KVM_MAX_VCPUS) - return SIGP_CC_NOT_OPERATIONAL; - - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - rc = __inject_sigp_stop(dst_vcpu, action); - - VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); + VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", dst_vcpu->vcpu_id); if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) { /* If the CPU has already been stopped, we still have @@ -212,18 +185,13 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) return rc; } -static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, - u64 *reg) +static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, + u32 address, u64 *reg) { struct kvm_s390_local_interrupt *li; - struct kvm_vcpu *dst_vcpu = NULL; struct kvm_s390_interrupt_info *inti; int rc; - if (cpu_addr < KVM_MAX_VCPUS) - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; li = &dst_vcpu->arch.local_int; /* @@ -260,24 +228,20 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, kvm_s390_vcpu_wakeup(dst_vcpu); rc = SIGP_CC_ORDER_CODE_ACCEPTED; - VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address); + VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", dst_vcpu->vcpu_id, + address); out_li: spin_unlock(&li->lock); return rc; } -static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id, - u32 addr, u64 *reg) +static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, + u32 addr, u64 *reg) { - struct kvm_vcpu *dst_vcpu = NULL; int flags; int rc; - if (cpu_id < KVM_MAX_VCPUS) - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - spin_lock(&dst_vcpu->arch.local_int.lock); flags = atomic_read(dst_vcpu->arch.local_int.cpuflags); spin_unlock(&dst_vcpu->arch.local_int.lock); @@ -297,19 +261,12 @@ static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id, return rc; } -static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, - u64 *reg) +static int __sigp_sense_running(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u64 *reg) { struct kvm_s390_local_interrupt *li; - struct kvm_vcpu *dst_vcpu = NULL; int rc; - if (cpu_addr >= KVM_MAX_VCPUS) - return SIGP_CC_NOT_OPERATIONAL; - - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; li = &dst_vcpu->arch.local_int; if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { /* running */ @@ -321,26 +278,18 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, rc = SIGP_CC_STATUS_STORED; } - VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", cpu_addr, - rc); + VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", + dst_vcpu->vcpu_id, rc); return rc; } /* Test whether the destination CPU is available and not busy */ -static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) +static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) { - struct kvm_s390_local_interrupt *li; + struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; int rc = SIGP_CC_ORDER_CODE_ACCEPTED; - struct kvm_vcpu *dst_vcpu = NULL; - if (cpu_addr >= KVM_MAX_VCPUS) - return SIGP_CC_NOT_OPERATIONAL; - - dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); - if (!dst_vcpu) - return SIGP_CC_NOT_OPERATIONAL; - li = &dst_vcpu->arch.local_int; spin_lock(&li->lock); if (li->action_bits & ACTION_STOP_ON_STOP) rc = SIGP_CC_BUSY; @@ -353,53 +302,61 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, u16 cpu_addr, u32 parameter, u64 *status_reg) { int rc; + struct kvm_vcpu *dst_vcpu; + + if (cpu_addr >= KVM_MAX_VCPUS) + return SIGP_CC_NOT_OPERATIONAL; + + dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); + if (!dst_vcpu) + return SIGP_CC_NOT_OPERATIONAL; switch (order_code) { case SIGP_SENSE: vcpu->stat.instruction_sigp_sense++; - rc = __sigp_sense(vcpu, cpu_addr, status_reg); + rc = __sigp_sense(vcpu, dst_vcpu, status_reg); break; case SIGP_EXTERNAL_CALL: vcpu->stat.instruction_sigp_external_call++; - rc = __sigp_external_call(vcpu, cpu_addr); + rc = __sigp_external_call(vcpu, dst_vcpu); break; case SIGP_EMERGENCY_SIGNAL: vcpu->stat.instruction_sigp_emergency++; - rc = __sigp_emergency(vcpu, cpu_addr); + rc = __sigp_emergency(vcpu, dst_vcpu); break; case SIGP_STOP: vcpu->stat.instruction_sigp_stop++; - rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP); + rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STOP_ON_STOP); break; case SIGP_STOP_AND_STORE_STATUS: vcpu->stat.instruction_sigp_stop++; - rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | + rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STORE_ON_STOP | ACTION_STOP_ON_STOP); break; case SIGP_STORE_STATUS_AT_ADDRESS: - rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, + rc = __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_SET_PREFIX: vcpu->stat.instruction_sigp_prefix++; - rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, status_reg); + rc = __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_COND_EMERGENCY_SIGNAL: - rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, + rc = __sigp_conditional_emergency(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_SENSE_RUNNING: vcpu->stat.instruction_sigp_sense_running++; - rc = __sigp_sense_running(vcpu, cpu_addr, status_reg); + rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); break; case SIGP_START: - rc = sigp_check_callable(vcpu, cpu_addr); + rc = sigp_check_callable(vcpu, dst_vcpu); if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) rc = -EOPNOTSUPP; /* Handle START in user space */ break; case SIGP_RESTART: vcpu->stat.instruction_sigp_restart++; - rc = sigp_check_callable(vcpu, cpu_addr); + rc = sigp_check_callable(vcpu, dst_vcpu); if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace", -- GitLab From b8983830826f3b0747a6d1c1f351121b9cc93276 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 23 May 2014 12:22:56 +0200 Subject: [PATCH 1592/9457] KVM: s390: sigp: separate preparation handlers This patch introduces in preparation for further code changes separate handler functions for: - SIGP (RE)START - will not be allowed to terminate pending orders - SIGP (INITIAL) CPU RESET - will be allowed to terminate certain pending orders - unknown sigp orders All sigp orders that require user space intervention are logged. Signed-off-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/sigp.h | 1 + arch/s390/kvm/sigp.c | 47 ++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 49576115dbb7..fad4ae23ece0 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -10,6 +10,7 @@ #define SIGP_RESTART 6 #define SIGP_STOP_AND_STORE_STATUS 9 #define SIGP_INITIAL_CPU_RESET 11 +#define SIGP_CPU_RESET 12 #define SIGP_SET_PREFIX 13 #define SIGP_STORE_STATUS_AT_ADDRESS 14 #define SIGP_SET_ARCHITECTURE 18 diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 660a9459ff2a..a9e17397305e 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -284,11 +284,12 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, return rc; } -/* Test whether the destination CPU is available and not busy */ -static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) +static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u8 order_code) { struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; - int rc = SIGP_CC_ORDER_CODE_ACCEPTED; + /* handle (RE)START in user space */ + int rc = -EOPNOTSUPP; spin_lock(&li->lock); if (li->action_bits & ACTION_STOP_ON_STOP) @@ -298,6 +299,20 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) return rc; } +static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u8 order_code) +{ + /* handle (INITIAL) CPU RESET in user space */ + return -EOPNOTSUPP; +} + +static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu) +{ + /* handle unknown orders in user space */ + return -EOPNOTSUPP; +} + static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, u16 cpu_addr, u32 parameter, u64 *status_reg) { @@ -350,25 +365,27 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); break; case SIGP_START: - rc = sigp_check_callable(vcpu, dst_vcpu); - if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) - rc = -EOPNOTSUPP; /* Handle START in user space */ + rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_RESTART: vcpu->stat.instruction_sigp_restart++; - rc = sigp_check_callable(vcpu, dst_vcpu); - if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { - VCPU_EVENT(vcpu, 4, - "sigp restart %x to handle userspace", - cpu_addr); - /* user space must know about restart */ - rc = -EOPNOTSUPP; - } + rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); + break; + case SIGP_INITIAL_CPU_RESET: + rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); + break; + case SIGP_CPU_RESET: + rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; default: - rc = -EOPNOTSUPP; + rc = __prepare_sigp_unknown(vcpu, dst_vcpu); } + if (rc == -EOPNOTSUPP) + VCPU_EVENT(vcpu, 4, + "sigp order %u -> cpu %x: handled in user space", + order_code, dst_vcpu->vcpu_id); + return rc; } -- GitLab From 42cb0c9ff92eba2168d1b8f69d6e62d2af608a13 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 23 May 2014 12:25:11 +0200 Subject: [PATCH 1593/9457] KVM: s390: sigp: instruction counters for all sigp orders This patch introduces instruction counters for all known sigp orders and also a separate one for unknown orders that are passed to user space. Signed-off-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/kvm_host.h | 7 +++++++ arch/s390/kvm/kvm-s390.c | 7 +++++++ arch/s390/kvm/sigp.c | 8 +++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 584b820eeaf8..7e02d77f8ecc 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -226,10 +226,17 @@ struct kvm_vcpu_stat { u32 instruction_sigp_sense_running; u32 instruction_sigp_external_call; u32 instruction_sigp_emergency; + u32 instruction_sigp_cond_emergency; + u32 instruction_sigp_start; u32 instruction_sigp_stop; + u32 instruction_sigp_stop_store_status; + u32 instruction_sigp_store_status; u32 instruction_sigp_arch; u32 instruction_sigp_prefix; u32 instruction_sigp_restart; + u32 instruction_sigp_init_cpu_reset; + u32 instruction_sigp_cpu_reset; + u32 instruction_sigp_unknown; u32 diagnose_10; u32 diagnose_44; u32 diagnose_9c; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 3e83d4b357b9..06878bdf0c6b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -81,10 +81,17 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) }, { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) }, { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) }, + { "instruction_sigp_cond_emergency", VCPU_STAT(instruction_sigp_cond_emergency) }, + { "instruction_sigp_start", VCPU_STAT(instruction_sigp_start) }, { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) }, + { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) }, + { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) }, { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) }, { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) }, { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, + { "instruction_sigp_cpu_reset", VCPU_STAT(instruction_sigp_cpu_reset) }, + { "instruction_sigp_init_cpu_reset", VCPU_STAT(instruction_sigp_init_cpu_reset) }, + { "instruction_sigp_unknown", VCPU_STAT(instruction_sigp_unknown) }, { "diagnose_10", VCPU_STAT(diagnose_10) }, { "diagnose_44", VCPU_STAT(diagnose_44) }, { "diagnose_9c", VCPU_STAT(diagnose_9c) }, diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index a9e17397305e..9ee63e4d8a24 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -344,11 +344,12 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STOP_ON_STOP); break; case SIGP_STOP_AND_STORE_STATUS: - vcpu->stat.instruction_sigp_stop++; + vcpu->stat.instruction_sigp_stop_store_status++; rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STORE_ON_STOP | ACTION_STOP_ON_STOP); break; case SIGP_STORE_STATUS_AT_ADDRESS: + vcpu->stat.instruction_sigp_store_status++; rc = __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter, status_reg); break; @@ -357,6 +358,7 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_COND_EMERGENCY_SIGNAL: + vcpu->stat.instruction_sigp_cond_emergency++; rc = __sigp_conditional_emergency(vcpu, dst_vcpu, parameter, status_reg); break; @@ -365,6 +367,7 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); break; case SIGP_START: + vcpu->stat.instruction_sigp_start++; rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_RESTART: @@ -372,12 +375,15 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_INITIAL_CPU_RESET: + vcpu->stat.instruction_sigp_init_cpu_reset++; rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; case SIGP_CPU_RESET: + vcpu->stat.instruction_sigp_cpu_reset++; rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; default: + vcpu->stat.instruction_sigp_unknown++; rc = __prepare_sigp_unknown(vcpu, dst_vcpu); } -- GitLab From 07b0303540e1951c75c98b7dd729ff1851a0049f Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 6 Jun 2014 10:24:15 +0200 Subject: [PATCH 1594/9457] KVM: s390: sigp: inject emergency calls in a separate function In preparation for further code changes, this patch moves the injection of emergency calls into a separate function and uses it for the processing of SIGP EMERGENCY CALL and SIGP CONDITIONAL EMERGENCY CALL. Signed-off-by: David Hildenbrand Acked-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kvm/sigp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 9ee63e4d8a24..1b330d4eb20b 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -46,7 +46,8 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, return rc; } -static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) +static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu) { struct kvm_s390_interrupt s390int = { .type = KVM_S390_INT_EMERGENCY, @@ -62,6 +63,11 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; } +static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) +{ + return __inject_sigp_emergency(vcpu, dst_vcpu); +} + static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, u16 asn, u64 *reg) @@ -76,12 +82,12 @@ static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ - /* Deliver the emergency signal? */ + /* Inject the emergency signal? */ if (!(flags & CPUSTAT_STOPPED) || (psw->mask & psw_int_mask) != psw_int_mask || ((flags & CPUSTAT_WAIT) && psw->addr != 0) || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { - return __sigp_emergency(vcpu, dst_vcpu); + return __inject_sigp_emergency(vcpu, dst_vcpu); } else { *reg &= 0xffffffff00000000UL; *reg |= SIGP_STATUS_INCORRECT_STATE; -- GitLab From a6cc3108567e0adc06c4a8031186f84ad1e1e194 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 6 Jun 2014 10:25:09 +0200 Subject: [PATCH 1595/9457] KVM: s390: sigp: split handling of SIGP STOP (AND STORE STATUS) In preparation for further code changes (e.g. getting rid of action_flags), this patch splits the handling of the two sigp orders SIGP STOP and SIGP STOP AND STORE STATUS by introducing a separate handler function for SIGP STOP AND STORE STATUS. Signed-off-by: David Hildenbrand Acked-by: Cornelia Huck Signed-off-by: Christian Borntraeger --- arch/s390/kvm/sigp.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 1b330d4eb20b..f7cd3f774f25 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -147,15 +147,27 @@ static int __inject_sigp_stop(struct kvm_vcpu *dst_vcpu, int action) return rc; } -static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, - int action) +static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) { int rc; - rc = __inject_sigp_stop(dst_vcpu, action); + rc = __inject_sigp_stop(dst_vcpu, ACTION_STOP_ON_STOP); VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", dst_vcpu->vcpu_id); - if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) { + return rc; +} + +static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u64 *reg) +{ + int rc; + + rc = __inject_sigp_stop(dst_vcpu, ACTION_STOP_ON_STOP | + ACTION_STORE_ON_STOP); + VCPU_EVENT(vcpu, 4, "sent sigp stop and store status to cpu %x", + dst_vcpu->vcpu_id); + + if (rc == -ESHUTDOWN) { /* If the CPU has already been stopped, we still have * to save the status when doing stop-and-store. This * has to be done after unlocking all spinlocks. */ @@ -347,12 +359,11 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, break; case SIGP_STOP: vcpu->stat.instruction_sigp_stop++; - rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STOP_ON_STOP); + rc = __sigp_stop(vcpu, dst_vcpu); break; case SIGP_STOP_AND_STORE_STATUS: vcpu->stat.instruction_sigp_stop_store_status++; - rc = __sigp_stop(vcpu, dst_vcpu, ACTION_STORE_ON_STOP | - ACTION_STOP_ON_STOP); + rc = __sigp_stop_and_store_status(vcpu, dst_vcpu, status_reg); break; case SIGP_STORE_STATUS_AT_ADDRESS: vcpu->stat.instruction_sigp_store_status++; -- GitLab From 326f0480b7f8504c4f594c4f36ab7874e17780bc Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Tue, 28 Oct 2014 14:27:44 +0200 Subject: [PATCH 1596/9457] ALSA: pcxhr: convert timeval to ktime_t This patch is concerned with migrating the time variables in the pcxhr module found in the sound driver. The changes are concerend with the y2038 problem where timeval will overflow in the year 2038. ktime_t was used instead of timeval to get the wall time. The difference is displayed now in nanoseconds instead of microseconds. Signed-off-by: Aya Mahfouz Reviewed-by: Arnd Bergmann Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 10 ++++++---- sound/pci/pcxhr/pcxhr_core.c | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index b854fc5e01f5..7c33c973dbd5 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -711,8 +711,9 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) int playback_mask = 0; #ifdef CONFIG_SND_DEBUG_VERBOSE - struct timeval my_tv1, my_tv2; - do_gettimeofday(&my_tv1); + ktime_t start_time, stop_time, diff_time; + + start_time = ktime_get(); #endif mutex_lock(&mgr->setup_mutex); @@ -823,9 +824,10 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) mutex_unlock(&mgr->setup_mutex); #ifdef CONFIG_SND_DEBUG_VERBOSE - do_gettimeofday(&my_tv2); + stop_time = ktime_get(); + diff_time = ktime_sub(stop_time, start_time); dev_dbg(&mgr->pci->dev, "***TRIGGER START*** TIME = %ld (err = %x)\n", - (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); + (long)(ktime_to_ns(diff_time)), err); #endif } diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index a584acb61c00..181f7729d409 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -910,8 +910,9 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int audio_mask; #ifdef CONFIG_SND_DEBUG_VERBOSE - struct timeval my_tv1, my_tv2; - do_gettimeofday(&my_tv1); + ktime_t start_time, stop_time, diff_time; + + start_time = ktime_get(); #endif audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); @@ -960,9 +961,10 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, return err; } #ifdef CONFIG_SND_DEBUG_VERBOSE - do_gettimeofday(&my_tv2); + stop_time = ktime_get(); + diff_time = ktime_sub(stop_time, start_time); dev_dbg(&mgr->pci->dev, "***SET PIPE STATE*** TIME = %ld (err = %x)\n", - (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); + (long)(ktime_to_ns(diff_time)), err); #endif return 0; } -- GitLab From da213f8e0cf03146925205b663413e4589b5b359 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 15:22:12 +0100 Subject: [PATCH 1597/9457] Bluetooth: Revert SMP self-test patches This reverts commits c6992e9ef2a17e9738b7bb8a03a7fe581a8f9977 and 4cd3362da899a59955146851dd860198b0aaaa75. The reason for the revert is that we cannot have more than one module initialization function and the SMP one breaks the build with modular kernels. As the proper fix for this is right now looking non-trivial it's better to simply revert the problematic patches in order to keep the upstream tree compilable. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/Kconfig | 6 --- net/bluetooth/smp.c | 120 ------------------------------------------ 2 files changed, 126 deletions(-) diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 2675b4106b00..600fb29288f4 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -45,12 +45,6 @@ config BT_6LOWPAN help IPv6 compression over Bluetooth Low Energy. -config BT_SELFTEST - bool "Run self-tests on boot" - depends on BT && DEBUG_KERNEL - help - Run self-tests during boot. Currently limited to SMP. - source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/bnep/Kconfig" diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 983d1e0793f6..fea3782989f4 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1743,123 +1743,3 @@ void smp_unregister(struct hci_dev *hdev) hdev->smp_data = NULL; l2cap_chan_put(chan); } - -#ifdef CONFIG_BT_SELFTEST - -static int __init test_ah(struct crypto_blkcipher *tfm_aes) -{ - u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, - 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; - u8 r[3] = { 0x94, 0x81, 0x70 }; - u8 exp[3] = { 0xaa, 0xfb, 0x0d }; - u8 res[3]; - int err; - - err = smp_ah(tfm_aes, irk, r, res); - if (err) - return err; - - if (memcmp(res, exp, 3) != 0) - return -EINVAL; - - return 0; -} - -static int __init test_c1(struct crypto_blkcipher *tfm_aes) -{ - u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 r[16] = { 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, - 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; - u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; - u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; - u8 _iat = 0x01; - u8 _rat = 0x00; - bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; - bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; - u8 exp[16] = { 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, - 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; - u8 res[16]; - int err; - - err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); - if (err) - return err; - - if (memcmp(res, exp, 16) != 0) - return -EINVAL; - - return 0; -} - -static int __init test_s1(struct crypto_blkcipher *tfm_aes) -{ - u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 r1[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; - u8 r2[16] = { 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; - u8 exp[16] = { 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, - 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; - u8 res[16]; - int err; - - err = smp_s1(tfm_aes, k, r1, r2, res); - if (err) - return err; - - if (memcmp(res, exp, 16) != 0) - return -EINVAL; - - return 0; -} - -static int __init run_selftests(struct crypto_blkcipher *tfm_aes) -{ - int err; - - err = test_ah(tfm_aes); - if (err) { - BT_ERR("smp_ah test failed"); - return err; - } - - err = test_c1(tfm_aes); - if (err) { - BT_ERR("smp_c1 test failed"); - return err; - } - - err = test_s1(tfm_aes); - if (err) { - BT_ERR("smp_s1 test failed"); - return err; - } - - return 0; -} - -static int __init test_smp(void) -{ - struct crypto_blkcipher *tfm_aes; - int err; - - tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm_aes)) { - BT_ERR("Unable to create ECB crypto context"); - return PTR_ERR(tfm_aes); - } - - err = run_selftests(tfm_aes); - if (err < 0) - BT_ERR("Self tests failed"); - else - BT_INFO("Self-tests passed"); - - crypto_free_blkcipher(tfm_aes); - - return err; -} - -module_init(test_smp); - -#endif /* CONFIG_BT_SELFTEST */ -- GitLab From 90446d0746c399e47246232f66ff2fa8616ba470 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2014 15:28:07 +0100 Subject: [PATCH 1598/9457] ALSA: doc: Add missing headers and compress stuff to alsa-driver-api.tmpl Some header files have kereldoc comments but are not referred properly. Let's add them. Signed-off-by: Takashi Iwai --- Documentation/DocBook/alsa-driver-api.tmpl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl index 0230a96f0564..13f8b241f042 100644 --- a/Documentation/DocBook/alsa-driver-api.tmpl +++ b/Documentation/DocBook/alsa-driver-api.tmpl @@ -57,6 +57,7 @@ !Esound/core/pcm.c !Esound/core/pcm_lib.c !Esound/core/pcm_native.c +!include/sound/pcm.h PCM Format Helpers !Esound/core/pcm_misc.c @@ -64,6 +65,10 @@ PCM Memory Management !Esound/core/pcm_memory.c + PCM DMA Engine API +!Esound/core/pcm_dmaengine.c +!Iinclude/sound/dmaengine_pcm.h + Control/Mixer API General Control Interface @@ -91,12 +96,19 @@ !Esound/core/info.c + Compress Offload + Compress Offload API +!Esound/core/compress_offload.c +!Iinclude/sound/compress_driver.h + + Miscellaneous Functions Hardware-Dependent Devices API !Esound/core/hwdep.c Jack Abstraction Layer API !Esound/core/jack.c +!Iinclude/sound/jack.h ISA DMA Helpers !Esound/core/isadma.c -- GitLab From 7b366d5f161c2a69eeafe525105a5a9277982472 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2014 15:30:00 +0100 Subject: [PATCH 1599/9457] ALSA: jack: Fix kerneldoc comments Signed-off-by: Takashi Iwai --- include/sound/jack.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/sound/jack.h b/include/sound/jack.h index 58916573db58..37e612e77410 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -28,8 +28,9 @@ struct input_dev; /** - * Jack types which can be reported. These values are used as a - * bitmask. + * enum snd_jack_types: Jack types which can be reported + * + * These values are used as a bitmask. * * Note that this must be kept in sync with the lookup table in * sound/core/jack.c. -- GitLab From 65fdc966c012b62ce4da5bf8175140a9b2ec2ee7 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Thu, 2 Oct 2014 00:08:04 +0530 Subject: [PATCH 1600/9457] gpio: grgpio: remove irq_domain resources on failure Call irq_domain_remove when gpiochip_add fails to release irq_domain resources. Signed-off-by: Pramod Gurav Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-grgpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 66ad3df9d9cf..38acdcea9799 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -441,6 +441,7 @@ static int grgpio_probe(struct platform_device *ofdev) err = gpiochip_add(gc); if (err) { dev_err(&ofdev->dev, "Could not add gpiochip\n"); + irq_domain_remove(priv->domain); return err; } -- GitLab From 6c892df2686c5611979792aaa4ddea9ee9f18749 Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Thu, 9 Oct 2014 16:18:55 -0700 Subject: [PATCH 1601/9457] Smack: Lock mode for the floor and hat labels The lock access mode allows setting a read lock on a file for with the process has only read access. The floor label is defined to make it easy to have the basic system installed such that everyone can read it. Once there's a desire to read lock (rationally or otherwise) a floor file a rule needs to get set. This happens all the time, so make the floor label a little bit more special and allow everyone lock access, too. By implication, give processes with the hat label (hat can read everything) lock access as well. This reduces clutter in the Smack rule set. Signed-off-by: Casey Schaufler --- security/smack/smack_access.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 5b970ffde024..999224fe8593 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -142,8 +142,7 @@ int smk_access(struct smack_known *subject, struct smack_known *object, * Tasks cannot be assigned the internet label. * An internet subject can access any object. */ - if (object == &smack_known_web || - subject == &smack_known_web) + if (object == &smack_known_web || subject == &smack_known_web) goto out_audit; /* * A star object can be accessed by any subject. @@ -157,10 +156,11 @@ int smk_access(struct smack_known *subject, struct smack_known *object, if (subject->smk_known == object->smk_known) goto out_audit; /* - * A hat subject can read any object. - * A floor object can be read by any subject. + * A hat subject can read or lock any object. + * A floor object can be read or locked by any subject. */ - if ((request & MAY_ANYREAD) == request) { + if ((request & MAY_ANYREAD) == request || + (request & MAY_LOCK) == request) { if (object == &smack_known_floor) goto out_audit; if (subject == &smack_known_hat) -- GitLab From f85698cd296f08218a7750f321e94607da128600 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 15:57:07 -0300 Subject: [PATCH 1602/9457] [media] smiapp: Take mutex during PLL update in sensor initialisation The mutex does not serialise anything in this case but avoids a lockdep warning from the control framework. Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 932ed9be9ff3..6174a592adcc 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2677,7 +2677,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev) pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; + mutex_lock(&sensor->mutex); rval = smiapp_update_mode(sensor); + mutex_unlock(&sensor->mutex); if (rval) { dev_err(&client->dev, "update mode failed\n"); goto out_nvm_release; -- GitLab From bc47150ab93988714d1fab7bc82fe5f505a107ad Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 1 Apr 2014 10:22:46 -0300 Subject: [PATCH 1603/9457] [media] smiapp-pll: Correct clock debug prints The PLL flags were not used correctly. Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index 2335529b195c..ab5d9a3adebf 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -67,7 +67,7 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) { dev_dbg(dev, "pre_pll_clk_div\t%d\n", pll->pre_pll_clk_div); dev_dbg(dev, "pll_multiplier \t%d\n", pll->pll_multiplier); - if (pll->flags != SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div); dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div); } @@ -77,7 +77,7 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz); dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz); dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz); - if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n", pll->op_sys_clk_freq_hz); dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n", -- GitLab From c37f9bf91900cce9c619b689b28d45a04c1644f1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 1 Apr 2014 10:31:59 -0300 Subject: [PATCH 1604/9457] [media] smiapp-pll: The clock tree values are unsigned --- fix debug prints These values are unsigned, so use %u instead of %d. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 94 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index ab5d9a3adebf..d14af5c1020b 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -65,26 +65,26 @@ static int bounds_check(struct device *dev, uint32_t val, static void print_pll(struct device *dev, struct smiapp_pll *pll) { - dev_dbg(dev, "pre_pll_clk_div\t%d\n", pll->pre_pll_clk_div); - dev_dbg(dev, "pll_multiplier \t%d\n", pll->pll_multiplier); + dev_dbg(dev, "pre_pll_clk_div\t%u\n", pll->pre_pll_clk_div); + dev_dbg(dev, "pll_multiplier \t%u\n", pll->pll_multiplier); if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { - dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div); - dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div); + dev_dbg(dev, "op_sys_clk_div \t%u\n", pll->op_sys_clk_div); + dev_dbg(dev, "op_pix_clk_div \t%u\n", pll->op_pix_clk_div); } - dev_dbg(dev, "vt_sys_clk_div \t%d\n", pll->vt_sys_clk_div); - dev_dbg(dev, "vt_pix_clk_div \t%d\n", pll->vt_pix_clk_div); + dev_dbg(dev, "vt_sys_clk_div \t%u\n", pll->vt_sys_clk_div); + dev_dbg(dev, "vt_pix_clk_div \t%u\n", pll->vt_pix_clk_div); - dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz); - dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz); - dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz); + dev_dbg(dev, "ext_clk_freq_hz \t%u\n", pll->ext_clk_freq_hz); + dev_dbg(dev, "pll_ip_clk_freq_hz \t%u\n", pll->pll_ip_clk_freq_hz); + dev_dbg(dev, "pll_op_clk_freq_hz \t%u\n", pll->pll_op_clk_freq_hz); if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { - dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n", + dev_dbg(dev, "op_sys_clk_freq_hz \t%u\n", pll->op_sys_clk_freq_hz); - dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n", + dev_dbg(dev, "op_pix_clk_freq_hz \t%u\n", pll->op_pix_clk_freq_hz); } - dev_dbg(dev, "vt_sys_clk_freq_hz \t%d\n", pll->vt_sys_clk_freq_hz); - dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz); + dev_dbg(dev, "vt_sys_clk_freq_hz \t%u\n", pll->vt_sys_clk_freq_hz); + dev_dbg(dev, "vt_pix_clk_freq_hz \t%u\n", pll->vt_pix_clk_freq_hz); } /* @@ -123,11 +123,11 @@ static int __smiapp_pll_calculate(struct device *dev, * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be * too high. */ - dev_dbg(dev, "pre_pll_clk_div %d\n", pll->pre_pll_clk_div); + dev_dbg(dev, "pre_pll_clk_div %u\n", pll->pre_pll_clk_div); /* Don't go above max pll multiplier. */ more_mul_max = limits->max_pll_multiplier / mul; - dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %d\n", + dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %u\n", more_mul_max); /* Don't go above max pll op frequency. */ more_mul_max = @@ -135,30 +135,30 @@ static int __smiapp_pll_calculate(struct device *dev, more_mul_max, limits->max_pll_op_freq_hz / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul)); - dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %d\n", + dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %u\n", more_mul_max); /* Don't go above the division capability of op sys clock divider. */ more_mul_max = min(more_mul_max, limits->op.max_sys_clk_div * pll->pre_pll_clk_div / div); - dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %d\n", + dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n", more_mul_max); /* Ensure we won't go above min_pll_multiplier. */ more_mul_max = min(more_mul_max, DIV_ROUND_UP(limits->max_pll_multiplier, mul)); - dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %d\n", + dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %u\n", more_mul_max); /* Ensure we won't go below min_pll_op_freq_hz. */ more_mul_min = DIV_ROUND_UP(limits->min_pll_op_freq_hz, pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul); - dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %d\n", + dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %u\n", more_mul_min); /* Ensure we won't go below min_pll_multiplier. */ more_mul_min = max(more_mul_min, DIV_ROUND_UP(limits->min_pll_multiplier, mul)); - dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %d\n", + dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %u\n", more_mul_min); if (more_mul_min > more_mul_max) { @@ -168,23 +168,23 @@ static int __smiapp_pll_calculate(struct device *dev, } more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div; - dev_dbg(dev, "more_mul_factor: %d\n", more_mul_factor); + dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor); more_mul_factor = lcm(more_mul_factor, limits->op.min_sys_clk_div); - dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n", + dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %u\n", more_mul_factor); i = roundup(more_mul_min, more_mul_factor); if (!is_one_or_even(i)) i <<= 1; - dev_dbg(dev, "final more_mul: %d\n", i); + dev_dbg(dev, "final more_mul: %u\n", i); if (i > more_mul_max) { - dev_dbg(dev, "final more_mul is bad, max %d\n", more_mul_max); + dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max); return -EINVAL; } pll->pll_multiplier = mul * i; pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div; - dev_dbg(dev, "op_sys_clk_div: %d\n", pll->op_sys_clk_div); + dev_dbg(dev, "op_sys_clk_div: %u\n", pll->op_sys_clk_div); pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz / pll->pre_pll_clk_div; @@ -197,7 +197,7 @@ static int __smiapp_pll_calculate(struct device *dev, pll->pll_op_clk_freq_hz / pll->op_sys_clk_div; pll->op_pix_clk_div = pll->bits_per_pixel; - dev_dbg(dev, "op_pix_clk_div: %d\n", pll->op_pix_clk_div); + dev_dbg(dev, "op_pix_clk_div: %u\n", pll->op_pix_clk_div); pll->op_pix_clk_freq_hz = pll->op_sys_clk_freq_hz / pll->op_pix_clk_div; @@ -214,7 +214,7 @@ static int __smiapp_pll_calculate(struct device *dev, vt_op_binning_div = pll->binning_horizontal; else vt_op_binning_div = 1; - dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div); + dev_dbg(dev, "vt_op_binning_div: %u\n", vt_op_binning_div); /* * Profile 2 supports vt_pix_clk_div E [4, 10] @@ -227,30 +227,30 @@ static int __smiapp_pll_calculate(struct device *dev, * * Find absolute limits for the factor of vt divider. */ - dev_dbg(dev, "scale_m: %d\n", pll->scale_m); + dev_dbg(dev, "scale_m: %u\n", pll->scale_m); min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div * pll->scale_n, lane_op_clock_ratio * vt_op_binning_div * pll->scale_m); /* Find smallest and biggest allowed vt divisor. */ - dev_dbg(dev, "min_vt_div: %d\n", min_vt_div); + dev_dbg(dev, "min_vt_div: %u\n", min_vt_div); min_vt_div = max(min_vt_div, DIV_ROUND_UP(pll->pll_op_clk_freq_hz, limits->vt.max_pix_clk_freq_hz)); - dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %d\n", + dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %u\n", min_vt_div); min_vt_div = max_t(uint32_t, min_vt_div, limits->vt.min_pix_clk_div * limits->vt.min_sys_clk_div); - dev_dbg(dev, "min_vt_div: min_vt_clk_div: %d\n", min_vt_div); + dev_dbg(dev, "min_vt_div: min_vt_clk_div: %u\n", min_vt_div); max_vt_div = limits->vt.max_sys_clk_div * limits->vt.max_pix_clk_div; - dev_dbg(dev, "max_vt_div: %d\n", max_vt_div); + dev_dbg(dev, "max_vt_div: %u\n", max_vt_div); max_vt_div = min(max_vt_div, DIV_ROUND_UP(pll->pll_op_clk_freq_hz, limits->vt.min_pix_clk_freq_hz)); - dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %d\n", + dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %u\n", max_vt_div); /* @@ -258,28 +258,28 @@ static int __smiapp_pll_calculate(struct device *dev, * with all values of pix_clk_div. */ min_sys_div = limits->vt.min_sys_clk_div; - dev_dbg(dev, "min_sys_div: %d\n", min_sys_div); + dev_dbg(dev, "min_sys_div: %u\n", min_sys_div); min_sys_div = max(min_sys_div, DIV_ROUND_UP(min_vt_div, limits->vt.max_pix_clk_div)); - dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div); + dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %u\n", min_sys_div); min_sys_div = max(min_sys_div, pll->pll_op_clk_freq_hz / limits->vt.max_sys_clk_freq_hz); - dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div); + dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %u\n", min_sys_div); min_sys_div = clk_div_even_up(min_sys_div); - dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div); + dev_dbg(dev, "min_sys_div: one or even: %u\n", min_sys_div); max_sys_div = limits->vt.max_sys_clk_div; - dev_dbg(dev, "max_sys_div: %d\n", max_sys_div); + dev_dbg(dev, "max_sys_div: %u\n", max_sys_div); max_sys_div = min(max_sys_div, DIV_ROUND_UP(max_vt_div, limits->vt.min_pix_clk_div)); - dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %d\n", max_sys_div); + dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %u\n", max_sys_div); max_sys_div = min(max_sys_div, DIV_ROUND_UP(pll->pll_op_clk_freq_hz, limits->vt.min_pix_clk_freq_hz)); - dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %d\n", max_sys_div); + dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %u\n", max_sys_div); /* * Find pix_div such that a legal pix_div * sys_div results @@ -296,7 +296,7 @@ static int __smiapp_pll_calculate(struct device *dev, if (pix_div < limits->vt.min_pix_clk_div || pix_div > limits->vt.max_pix_clk_div) { dev_dbg(dev, - "pix_div %d too small or too big (%d--%d)\n", + "pix_div %u too small or too big (%u--%u)\n", pix_div, limits->vt.min_pix_clk_div, limits->vt.max_pix_clk_div); @@ -390,9 +390,9 @@ int smiapp_pll_calculate(struct device *dev, lane_op_clock_ratio = pll->csi2.lanes; else lane_op_clock_ratio = 1; - dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio); + dev_dbg(dev, "lane_op_clock_ratio: %u\n", lane_op_clock_ratio); - dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal, + dev_dbg(dev, "binning: %ux%u\n", pll->binning_horizontal, pll->binning_vertical); switch (pll->bus_type) { @@ -411,7 +411,7 @@ int smiapp_pll_calculate(struct device *dev, } /* Figure out limits for pre-pll divider based on extclk */ - dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n", + dev_dbg(dev, "min / max pre_pll_clk_div: %u / %u\n", limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div); max_pre_pll_clk_div = min_t(uint16_t, limits->max_pre_pll_clk_div, @@ -422,20 +422,20 @@ int smiapp_pll_calculate(struct device *dev, clk_div_even_up( DIV_ROUND_UP(pll->ext_clk_freq_hz, limits->max_pll_ip_freq_hz))); - dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n", + dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %u / %u\n", min_pre_pll_clk_div, max_pre_pll_clk_div); i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz); mul = div_u64(pll->pll_op_clk_freq_hz, i); div = pll->ext_clk_freq_hz / i; - dev_dbg(dev, "mul %d / div %d\n", mul, div); + dev_dbg(dev, "mul %u / div %u\n", mul, div); min_pre_pll_clk_div = max_t(uint16_t, min_pre_pll_clk_div, clk_div_even_up( DIV_ROUND_UP(mul * pll->ext_clk_freq_hz, limits->max_pll_op_freq_hz))); - dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n", + dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %u / %u\n", min_pre_pll_clk_div, max_pre_pll_clk_div); for (pll->pre_pll_clk_div = min_pre_pll_clk_div; -- GitLab From c859470ac1bf2b89c147f7e456ac16070003d8c8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 15 Sep 2014 18:35:18 -0300 Subject: [PATCH 1605/9457] [media] smiapp-pll: Separate bounds checking into a separate function Enough work for this function already. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 110 ++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index d14af5c1020b..bde8eb839ccc 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -87,6 +87,64 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) dev_dbg(dev, "vt_pix_clk_freq_hz \t%u\n", pll->vt_pix_clk_freq_hz); } +static int check_all_bounds(struct device *dev, + const struct smiapp_pll_limits *limits, + struct smiapp_pll *pll) +{ + int rval; + + rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, + limits->min_pll_ip_freq_hz, + limits->max_pll_ip_freq_hz, + "pll_ip_clk_freq_hz"); + if (!rval) + rval = bounds_check( + dev, pll->pll_multiplier, + limits->min_pll_multiplier, limits->max_pll_multiplier, + "pll_multiplier"); + if (!rval) + rval = bounds_check( + dev, pll->pll_op_clk_freq_hz, + limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, + "pll_op_clk_freq_hz"); + if (!rval) + rval = bounds_check( + dev, pll->op_sys_clk_div, + limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, + "op_sys_clk_div"); + if (!rval) + rval = bounds_check( + dev, pll->op_pix_clk_div, + limits->op.min_pix_clk_div, limits->op.max_pix_clk_div, + "op_pix_clk_div"); + if (!rval) + rval = bounds_check( + dev, pll->op_sys_clk_freq_hz, + limits->op.min_sys_clk_freq_hz, + limits->op.max_sys_clk_freq_hz, + "op_sys_clk_freq_hz"); + if (!rval) + rval = bounds_check( + dev, pll->op_pix_clk_freq_hz, + limits->op.min_pix_clk_freq_hz, + limits->op.max_pix_clk_freq_hz, + "op_pix_clk_freq_hz"); + if (!rval) + rval = bounds_check( + dev, pll->vt_sys_clk_freq_hz, + limits->vt.min_sys_clk_freq_hz, + limits->vt.max_sys_clk_freq_hz, + "vt_sys_clk_freq_hz"); + if (!rval) + rval = bounds_check( + dev, pll->vt_pix_clk_freq_hz, + limits->vt.min_pix_clk_freq_hz, + limits->vt.max_pix_clk_freq_hz, + "vt_pix_clk_freq_hz"); + + return rval; +} + /* * Heuristically guess the PLL tree for a given common multiplier and * divisor. Begin with the operational timing and continue to video @@ -117,7 +175,6 @@ static int __smiapp_pll_calculate(struct device *dev, uint32_t min_vt_div, max_vt_div, vt_div; uint32_t min_sys_div, max_sys_div; unsigned int i; - int rval; /* * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be @@ -323,56 +380,7 @@ static int __smiapp_pll_calculate(struct device *dev, pll->pixel_rate_csi = pll->op_pix_clk_freq_hz * lane_op_clock_ratio; - rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, - limits->min_pll_ip_freq_hz, - limits->max_pll_ip_freq_hz, - "pll_ip_clk_freq_hz"); - if (!rval) - rval = bounds_check( - dev, pll->pll_multiplier, - limits->min_pll_multiplier, limits->max_pll_multiplier, - "pll_multiplier"); - if (!rval) - rval = bounds_check( - dev, pll->pll_op_clk_freq_hz, - limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, - "pll_op_clk_freq_hz"); - if (!rval) - rval = bounds_check( - dev, pll->op_sys_clk_div, - limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, - "op_sys_clk_div"); - if (!rval) - rval = bounds_check( - dev, pll->op_pix_clk_div, - limits->op.min_pix_clk_div, limits->op.max_pix_clk_div, - "op_pix_clk_div"); - if (!rval) - rval = bounds_check( - dev, pll->op_sys_clk_freq_hz, - limits->op.min_sys_clk_freq_hz, - limits->op.max_sys_clk_freq_hz, - "op_sys_clk_freq_hz"); - if (!rval) - rval = bounds_check( - dev, pll->op_pix_clk_freq_hz, - limits->op.min_pix_clk_freq_hz, - limits->op.max_pix_clk_freq_hz, - "op_pix_clk_freq_hz"); - if (!rval) - rval = bounds_check( - dev, pll->vt_sys_clk_freq_hz, - limits->vt.min_sys_clk_freq_hz, - limits->vt.max_sys_clk_freq_hz, - "vt_sys_clk_freq_hz"); - if (!rval) - rval = bounds_check( - dev, pll->vt_pix_clk_freq_hz, - limits->vt.min_pix_clk_freq_hz, - limits->vt.max_pix_clk_freq_hz, - "vt_pix_clk_freq_hz"); - - return rval; + return check_all_bounds(dev, limits, pll); } int smiapp_pll_calculate(struct device *dev, -- GitLab From fff888c711764177a25a746d99a20e0549c54e3e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 09:04:35 -0300 Subject: [PATCH 1606/9457] [media] smiapp-pll: External clock frequency isn't an output value It's input. Move it elsewhere in the struct. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/smiapp-pll.h b/drivers/media/i2c/smiapp-pll.h index 5ce2b61da3c5..2885cd76ff8c 100644 --- a/drivers/media/i2c/smiapp-pll.h +++ b/drivers/media/i2c/smiapp-pll.h @@ -53,6 +53,7 @@ struct smiapp_pll { uint8_t scale_n; uint8_t bits_per_pixel; uint32_t link_freq; + uint32_t ext_clk_freq_hz; /* output values */ uint16_t pre_pll_clk_div; @@ -62,7 +63,6 @@ struct smiapp_pll { uint16_t vt_sys_clk_div; uint16_t vt_pix_clk_div; - uint32_t ext_clk_freq_hz; uint32_t pll_ip_clk_freq_hz; uint32_t pll_op_clk_freq_hz; uint32_t op_sys_clk_freq_hz; -- GitLab From e3f8bc8c6ecd0bcb7b4d413332b068ebbbcc31ee Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 09:07:11 -0300 Subject: [PATCH 1607/9457] [media] smiapp-pll: Unify OP and VT PLL structs Uniform representation for VT and OP clocks. This is preparation for calculating the VT clocks using the OP clock code. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 60 +++++++++++++------------- drivers/media/i2c/smiapp-pll.h | 18 ++++---- drivers/media/i2c/smiapp/smiapp-core.c | 14 +++--- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index bde8eb839ccc..40a18ba85557 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -68,23 +68,23 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) dev_dbg(dev, "pre_pll_clk_div\t%u\n", pll->pre_pll_clk_div); dev_dbg(dev, "pll_multiplier \t%u\n", pll->pll_multiplier); if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { - dev_dbg(dev, "op_sys_clk_div \t%u\n", pll->op_sys_clk_div); - dev_dbg(dev, "op_pix_clk_div \t%u\n", pll->op_pix_clk_div); + dev_dbg(dev, "op_sys_clk_div \t%u\n", pll->op.sys_clk_div); + dev_dbg(dev, "op_pix_clk_div \t%u\n", pll->op.pix_clk_div); } - dev_dbg(dev, "vt_sys_clk_div \t%u\n", pll->vt_sys_clk_div); - dev_dbg(dev, "vt_pix_clk_div \t%u\n", pll->vt_pix_clk_div); + dev_dbg(dev, "vt_sys_clk_div \t%u\n", pll->vt.sys_clk_div); + dev_dbg(dev, "vt_pix_clk_div \t%u\n", pll->vt.pix_clk_div); dev_dbg(dev, "ext_clk_freq_hz \t%u\n", pll->ext_clk_freq_hz); dev_dbg(dev, "pll_ip_clk_freq_hz \t%u\n", pll->pll_ip_clk_freq_hz); dev_dbg(dev, "pll_op_clk_freq_hz \t%u\n", pll->pll_op_clk_freq_hz); if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { dev_dbg(dev, "op_sys_clk_freq_hz \t%u\n", - pll->op_sys_clk_freq_hz); + pll->op.sys_clk_freq_hz); dev_dbg(dev, "op_pix_clk_freq_hz \t%u\n", - pll->op_pix_clk_freq_hz); + pll->op.pix_clk_freq_hz); } - dev_dbg(dev, "vt_sys_clk_freq_hz \t%u\n", pll->vt_sys_clk_freq_hz); - dev_dbg(dev, "vt_pix_clk_freq_hz \t%u\n", pll->vt_pix_clk_freq_hz); + dev_dbg(dev, "vt_sys_clk_freq_hz \t%u\n", pll->vt.sys_clk_freq_hz); + dev_dbg(dev, "vt_pix_clk_freq_hz \t%u\n", pll->vt.pix_clk_freq_hz); } static int check_all_bounds(struct device *dev, @@ -109,35 +109,35 @@ static int check_all_bounds(struct device *dev, "pll_op_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->op_sys_clk_div, + dev, pll->op.sys_clk_div, limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, "op_sys_clk_div"); if (!rval) rval = bounds_check( - dev, pll->op_pix_clk_div, + dev, pll->op.pix_clk_div, limits->op.min_pix_clk_div, limits->op.max_pix_clk_div, "op_pix_clk_div"); if (!rval) rval = bounds_check( - dev, pll->op_sys_clk_freq_hz, + dev, pll->op.sys_clk_freq_hz, limits->op.min_sys_clk_freq_hz, limits->op.max_sys_clk_freq_hz, "op_sys_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->op_pix_clk_freq_hz, + dev, pll->op.pix_clk_freq_hz, limits->op.min_pix_clk_freq_hz, limits->op.max_pix_clk_freq_hz, "op_pix_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->vt_sys_clk_freq_hz, + dev, pll->vt.sys_clk_freq_hz, limits->vt.min_sys_clk_freq_hz, limits->vt.max_sys_clk_freq_hz, "vt_sys_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->vt_pix_clk_freq_hz, + dev, pll->vt.pix_clk_freq_hz, limits->vt.min_pix_clk_freq_hz, limits->vt.max_pix_clk_freq_hz, "vt_pix_clk_freq_hz"); @@ -240,8 +240,8 @@ static int __smiapp_pll_calculate(struct device *dev, } pll->pll_multiplier = mul * i; - pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div; - dev_dbg(dev, "op_sys_clk_div: %u\n", pll->op_sys_clk_div); + pll->op.sys_clk_div = div * i / pll->pre_pll_clk_div; + dev_dbg(dev, "op_sys_clk_div: %u\n", pll->op.sys_clk_div); pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz / pll->pre_pll_clk_div; @@ -250,14 +250,14 @@ static int __smiapp_pll_calculate(struct device *dev, * pll->pll_multiplier; /* Derive pll_op_clk_freq_hz. */ - pll->op_sys_clk_freq_hz = - pll->pll_op_clk_freq_hz / pll->op_sys_clk_div; + pll->op.sys_clk_freq_hz = + pll->pll_op_clk_freq_hz / pll->op.sys_clk_div; - pll->op_pix_clk_div = pll->bits_per_pixel; - dev_dbg(dev, "op_pix_clk_div: %u\n", pll->op_pix_clk_div); + pll->op.pix_clk_div = pll->bits_per_pixel; + dev_dbg(dev, "op_pix_clk_div: %u\n", pll->op.pix_clk_div); - pll->op_pix_clk_freq_hz = - pll->op_sys_clk_freq_hz / pll->op_pix_clk_div; + pll->op.pix_clk_freq_hz = + pll->op.sys_clk_freq_hz / pll->op.pix_clk_div; /* * Some sensors perform analogue binning and some do this @@ -285,7 +285,7 @@ static int __smiapp_pll_calculate(struct device *dev, * Find absolute limits for the factor of vt divider. */ dev_dbg(dev, "scale_m: %u\n", pll->scale_m); - min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div + min_vt_div = DIV_ROUND_UP(pll->op.pix_clk_div * pll->op.sys_clk_div * pll->scale_n, lane_op_clock_ratio * vt_op_binning_div * pll->scale_m); @@ -369,16 +369,16 @@ static int __smiapp_pll_calculate(struct device *dev, break; } - pll->vt_sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div); - pll->vt_pix_clk_div = best_pix_div; + pll->vt.sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div); + pll->vt.pix_clk_div = best_pix_div; - pll->vt_sys_clk_freq_hz = - pll->pll_op_clk_freq_hz / pll->vt_sys_clk_div; - pll->vt_pix_clk_freq_hz = - pll->vt_sys_clk_freq_hz / pll->vt_pix_clk_div; + pll->vt.sys_clk_freq_hz = + pll->pll_op_clk_freq_hz / pll->vt.sys_clk_div; + pll->vt.pix_clk_freq_hz = + pll->vt.sys_clk_freq_hz / pll->vt.pix_clk_div; pll->pixel_rate_csi = - pll->op_pix_clk_freq_hz * lane_op_clock_ratio; + pll->op.pix_clk_freq_hz * lane_op_clock_ratio; return check_all_bounds(dev, limits, pll); } diff --git a/drivers/media/i2c/smiapp-pll.h b/drivers/media/i2c/smiapp-pll.h index 2885cd76ff8c..b7c0e6609ad4 100644 --- a/drivers/media/i2c/smiapp-pll.h +++ b/drivers/media/i2c/smiapp-pll.h @@ -35,6 +35,13 @@ #define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0) #define SMIAPP_PLL_FLAG_NO_OP_CLOCKS (1 << 1) +struct smiapp_pll_branch { + uint16_t sys_clk_div; + uint16_t pix_clk_div; + uint32_t sys_clk_freq_hz; + uint32_t pix_clk_freq_hz; +}; + struct smiapp_pll { /* input values */ uint8_t bus_type; @@ -58,17 +65,10 @@ struct smiapp_pll { /* output values */ uint16_t pre_pll_clk_div; uint16_t pll_multiplier; - uint16_t op_sys_clk_div; - uint16_t op_pix_clk_div; - uint16_t vt_sys_clk_div; - uint16_t vt_pix_clk_div; - uint32_t pll_ip_clk_freq_hz; uint32_t pll_op_clk_freq_hz; - uint32_t op_sys_clk_freq_hz; - uint32_t op_pix_clk_freq_hz; - uint32_t vt_sys_clk_freq_hz; - uint32_t vt_pix_clk_freq_hz; + struct smiapp_pll_branch vt; + struct smiapp_pll_branch op; uint32_t pixel_rate_csi; }; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 6174a592adcc..389e7751ebb4 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -205,12 +205,12 @@ static int smiapp_pll_configure(struct smiapp_sensor *sensor) int rval; rval = smiapp_write( - sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt_pix_clk_div); + sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt.pix_clk_div); if (rval < 0) return rval; rval = smiapp_write( - sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt_sys_clk_div); + sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt.sys_clk_div); if (rval < 0) return rval; @@ -227,17 +227,17 @@ static int smiapp_pll_configure(struct smiapp_sensor *sensor) /* Lane op clock ratio does not apply here. */ rval = smiapp_write( sensor, SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS, - DIV_ROUND_UP(pll->op_sys_clk_freq_hz, 1000000 / 256 / 256)); + DIV_ROUND_UP(pll->op.sys_clk_freq_hz, 1000000 / 256 / 256)); if (rval < 0 || sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) return rval; rval = smiapp_write( - sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op_pix_clk_div); + sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op.pix_clk_div); if (rval < 0) return rval; return smiapp_write( - sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op_sys_clk_div); + sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op.sys_clk_div); } static int smiapp_pll_update(struct smiapp_sensor *sensor) @@ -299,7 +299,7 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor) return rval; __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray, - pll->vt_pix_clk_freq_hz); + pll->vt.pix_clk_freq_hz); __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi); return 0; @@ -904,7 +904,7 @@ static int smiapp_update_mode(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val); dev_dbg(&client->dev, "real timeperframe\t100/%d\n", - sensor->pll.vt_pix_clk_freq_hz / + sensor->pll.vt.pix_clk_freq_hz / ((sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width + sensor->hblank->val) * (sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height -- GitLab From 974abe4460f02060f0507e261a7ebdaede7f84a2 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 09:39:08 -0300 Subject: [PATCH 1608/9457] [media] smiapp-pll: Calculate OP clocks only for sensors that have them Profile 0 sensors have no OP clock branck in the clock tree. The PLL calculator still calculated them, they just weren't used for anything. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 82 +++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 30 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index 40a18ba85557..cac1407b77fb 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -89,7 +89,9 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) static int check_all_bounds(struct device *dev, const struct smiapp_pll_limits *limits, - struct smiapp_pll *pll) + const struct smiapp_pll_branch_limits *op_limits, + struct smiapp_pll *pll, + struct smiapp_pll_branch *op_pll) { int rval; @@ -109,25 +111,25 @@ static int check_all_bounds(struct device *dev, "pll_op_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->op.sys_clk_div, - limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, + dev, op_pll->sys_clk_div, + op_limits->min_sys_clk_div, op_limits->max_sys_clk_div, "op_sys_clk_div"); if (!rval) rval = bounds_check( - dev, pll->op.pix_clk_div, - limits->op.min_pix_clk_div, limits->op.max_pix_clk_div, + dev, op_pll->pix_clk_div, + op_limits->min_pix_clk_div, op_limits->max_pix_clk_div, "op_pix_clk_div"); if (!rval) rval = bounds_check( - dev, pll->op.sys_clk_freq_hz, - limits->op.min_sys_clk_freq_hz, - limits->op.max_sys_clk_freq_hz, + dev, op_pll->sys_clk_freq_hz, + op_limits->min_sys_clk_freq_hz, + op_limits->max_sys_clk_freq_hz, "op_sys_clk_freq_hz"); if (!rval) rval = bounds_check( - dev, pll->op.pix_clk_freq_hz, - limits->op.min_pix_clk_freq_hz, - limits->op.max_pix_clk_freq_hz, + dev, op_pll->pix_clk_freq_hz, + op_limits->min_pix_clk_freq_hz, + op_limits->max_pix_clk_freq_hz, "op_pix_clk_freq_hz"); if (!rval) rval = bounds_check( @@ -156,10 +158,11 @@ static int check_all_bounds(struct device *dev, * * @return Zero on success, error code on error. */ -static int __smiapp_pll_calculate(struct device *dev, - const struct smiapp_pll_limits *limits, - struct smiapp_pll *pll, uint32_t mul, - uint32_t div, uint32_t lane_op_clock_ratio) +static int __smiapp_pll_calculate( + struct device *dev, const struct smiapp_pll_limits *limits, + const struct smiapp_pll_branch_limits *op_limits, + struct smiapp_pll *pll, struct smiapp_pll_branch *op_pll, uint32_t mul, + uint32_t div, uint32_t lane_op_clock_ratio) { uint32_t sys_div; uint32_t best_pix_div = INT_MAX >> 1; @@ -196,7 +199,7 @@ static int __smiapp_pll_calculate(struct device *dev, more_mul_max); /* Don't go above the division capability of op sys clock divider. */ more_mul_max = min(more_mul_max, - limits->op.max_sys_clk_div * pll->pre_pll_clk_div + op_limits->max_sys_clk_div * pll->pre_pll_clk_div / div); dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %u\n", more_mul_max); @@ -226,8 +229,8 @@ static int __smiapp_pll_calculate(struct device *dev, more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div; dev_dbg(dev, "more_mul_factor: %u\n", more_mul_factor); - more_mul_factor = lcm(more_mul_factor, limits->op.min_sys_clk_div); - dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %u\n", + more_mul_factor = lcm(more_mul_factor, op_limits->min_sys_clk_div); + dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n", more_mul_factor); i = roundup(more_mul_min, more_mul_factor); if (!is_one_or_even(i)) @@ -240,8 +243,8 @@ static int __smiapp_pll_calculate(struct device *dev, } pll->pll_multiplier = mul * i; - pll->op.sys_clk_div = div * i / pll->pre_pll_clk_div; - dev_dbg(dev, "op_sys_clk_div: %u\n", pll->op.sys_clk_div); + op_pll->sys_clk_div = div * i / pll->pre_pll_clk_div; + dev_dbg(dev, "op_sys_clk_div: %u\n", op_pll->sys_clk_div); pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz / pll->pre_pll_clk_div; @@ -250,14 +253,19 @@ static int __smiapp_pll_calculate(struct device *dev, * pll->pll_multiplier; /* Derive pll_op_clk_freq_hz. */ - pll->op.sys_clk_freq_hz = - pll->pll_op_clk_freq_hz / pll->op.sys_clk_div; + op_pll->sys_clk_freq_hz = + pll->pll_op_clk_freq_hz / op_pll->sys_clk_div; - pll->op.pix_clk_div = pll->bits_per_pixel; - dev_dbg(dev, "op_pix_clk_div: %u\n", pll->op.pix_clk_div); + op_pll->pix_clk_div = pll->bits_per_pixel; + dev_dbg(dev, "op_pix_clk_div: %u\n", op_pll->pix_clk_div); - pll->op.pix_clk_freq_hz = - pll->op.sys_clk_freq_hz / pll->op.pix_clk_div; + op_pll->pix_clk_freq_hz = + op_pll->sys_clk_freq_hz / op_pll->pix_clk_div; + + if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + /* No OP clocks --- VT clocks are used instead. */ + goto out_skip_vt_calc; + } /* * Some sensors perform analogue binning and some do this @@ -285,7 +293,7 @@ static int __smiapp_pll_calculate(struct device *dev, * Find absolute limits for the factor of vt divider. */ dev_dbg(dev, "scale_m: %u\n", pll->scale_m); - min_vt_div = DIV_ROUND_UP(pll->op.pix_clk_div * pll->op.sys_clk_div + min_vt_div = DIV_ROUND_UP(op_pll->pix_clk_div * op_pll->sys_clk_div * pll->scale_n, lane_op_clock_ratio * vt_op_binning_div * pll->scale_m); @@ -377,16 +385,19 @@ static int __smiapp_pll_calculate(struct device *dev, pll->vt.pix_clk_freq_hz = pll->vt.sys_clk_freq_hz / pll->vt.pix_clk_div; +out_skip_vt_calc: pll->pixel_rate_csi = - pll->op.pix_clk_freq_hz * lane_op_clock_ratio; + op_pll->pix_clk_freq_hz * lane_op_clock_ratio; - return check_all_bounds(dev, limits, pll); + return check_all_bounds(dev, limits, op_limits, pll, op_pll); } int smiapp_pll_calculate(struct device *dev, const struct smiapp_pll_limits *limits, struct smiapp_pll *pll) { + const struct smiapp_pll_branch_limits *op_limits = &limits->op; + struct smiapp_pll_branch *op_pll = &pll->op; uint16_t min_pre_pll_clk_div; uint16_t max_pre_pll_clk_div; uint32_t lane_op_clock_ratio; @@ -394,6 +405,16 @@ int smiapp_pll_calculate(struct device *dev, unsigned int i; int rval = -EINVAL; + if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + /* + * If there's no OP PLL at all, use the VT values + * instead. The OP values are ignored for the rest of + * the PLL calculation. + */ + op_limits = &limits->vt; + op_pll = &pll->vt; + } + if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE) lane_op_clock_ratio = pll->csi2.lanes; else @@ -449,7 +470,8 @@ int smiapp_pll_calculate(struct device *dev, for (pll->pre_pll_clk_div = min_pre_pll_clk_div; pll->pre_pll_clk_div <= max_pre_pll_clk_div; pll->pre_pll_clk_div += 2 - (pll->pre_pll_clk_div & 1)) { - rval = __smiapp_pll_calculate(dev, limits, pll, mul, div, + rval = __smiapp_pll_calculate(dev, limits, op_limits, pll, + op_pll, mul, div, lane_op_clock_ratio); if (rval) continue; -- GitLab From 63516b55e3efed3a306ada6f79aa7052c83249ce Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 15 Sep 2014 18:47:32 -0300 Subject: [PATCH 1609/9457] [media] smiapp-pll: Don't validate OP clocks if there are none For profile 0 sensors (which have no OP clocks), the OP limits are in fact VT limits. Do not verify them again. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index cac1407b77fb..862ca0ca5362 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -131,6 +131,14 @@ static int check_all_bounds(struct device *dev, op_limits->min_pix_clk_freq_hz, op_limits->max_pix_clk_freq_hz, "op_pix_clk_freq_hz"); + + /* + * If there are no OP clocks, the VT clocks are contained in + * the OP clock struct. + */ + if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) + return rval; + if (!rval) rval = bounds_check( dev, pll->vt.sys_clk_freq_hz, -- GitLab From 9249e9a4ca113517307c5044f66ec9cc0ede20b1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 15 Sep 2014 17:07:07 -0300 Subject: [PATCH 1610/9457] [media] smiapp: The PLL calculator handles sensors with VT clocks only No need to pretend the OP limits are there anymore. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 389e7751ebb4..d0ea7a3bfc0a 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -277,16 +277,6 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor) struct smiapp_pll *pll = &sensor->pll; int rval; - if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) { - /* - * Fill in operational clock divisors limits from the - * video timing ones. On profile 0 sensors the - * requirements regarding them are essentially the - * same as on VT ones. - */ - lim.op = lim.vt; - } - pll->binning_horizontal = sensor->binning_horizontal; pll->binning_vertical = sensor->binning_vertical; pll->link_freq = -- GitLab From 29391300f9b4e7e2a657d73a061d6bee1960e82d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 1 Apr 2014 18:47:55 -0300 Subject: [PATCH 1611/9457] [media] smiapp: Remove validation of op_pix_clk_div op_pix_clk_div is directly assigned and not calculated. There's no need to verify it. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index 862ca0ca5362..0d5c50374c2c 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -114,11 +114,6 @@ static int check_all_bounds(struct device *dev, dev, op_pll->sys_clk_div, op_limits->min_sys_clk_div, op_limits->max_sys_clk_div, "op_sys_clk_div"); - if (!rval) - rval = bounds_check( - dev, op_pll->pix_clk_div, - op_limits->min_pix_clk_div, op_limits->max_pix_clk_div, - "op_pix_clk_div"); if (!rval) rval = bounds_check( dev, op_pll->sys_clk_freq_hz, -- GitLab From e7c329a0a94b6bd7743a04f7f4309ad693f7a112 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 1 Apr 2014 19:18:09 -0300 Subject: [PATCH 1612/9457] [media] smiapp-pll: Add pixel rate in pixel array as output parameters The actual pixel array pixel rate may be something else than vt_pix_clk_freq on some implementations. Add a new field which contains the corrected value. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp-pll.c | 1 + drivers/media/i2c/smiapp-pll.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c index 0d5c50374c2c..e40d9027df3d 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/smiapp-pll.c @@ -391,6 +391,7 @@ static int __smiapp_pll_calculate( out_skip_vt_calc: pll->pixel_rate_csi = op_pll->pix_clk_freq_hz * lane_op_clock_ratio; + pll->pixel_rate_pixel_array = pll->vt.pix_clk_freq_hz; return check_all_bounds(dev, limits, op_limits, pll, op_pll); } diff --git a/drivers/media/i2c/smiapp-pll.h b/drivers/media/i2c/smiapp-pll.h index b7c0e6609ad4..e8f035a50c76 100644 --- a/drivers/media/i2c/smiapp-pll.h +++ b/drivers/media/i2c/smiapp-pll.h @@ -71,6 +71,7 @@ struct smiapp_pll { struct smiapp_pll_branch op; uint32_t pixel_rate_csi; + uint32_t pixel_rate_pixel_array; }; struct smiapp_pll_branch_limits { -- GitLab From 83313d9ff6e083bf1e6062520a57b6cc3e029172 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Apr 2014 18:38:17 -0300 Subject: [PATCH 1613/9457] [media] smiapp: Use actual pixel rate calculated by the PLL calculator Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index d0ea7a3bfc0a..861312e1a48a 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -289,7 +289,7 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor) return rval; __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray, - pll->vt.pix_clk_freq_hz); + pll->pixel_rate_pixel_array); __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi); return 0; @@ -894,7 +894,7 @@ static int smiapp_update_mode(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val); dev_dbg(&client->dev, "real timeperframe\t100/%d\n", - sensor->pll.vt.pix_clk_freq_hz / + sensor->pll.pixel_rate_pixel_array / ((sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width + sensor->hblank->val) * (sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height -- GitLab From 183bec80ce80b3f71dadb601e7e2fc9f712b1d52 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 16:19:37 -0300 Subject: [PATCH 1614/9457] [media] smiapp: Split calculating PLL with sensor's limits from updating it The first one is handy for just trying out a PLL configuration without a need to apply it. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 861312e1a48a..4d3dc25eb4a8 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -240,7 +240,8 @@ static int smiapp_pll_configure(struct smiapp_sensor *sensor) sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op.sys_clk_div); } -static int smiapp_pll_update(struct smiapp_sensor *sensor) +static int smiapp_pll_try(struct smiapp_sensor *sensor, + struct smiapp_pll *pll) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct smiapp_pll_limits lim = { @@ -274,6 +275,12 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor) .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN], .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK], }; + + return smiapp_pll_calculate(&client->dev, &lim, pll); +} + +static int smiapp_pll_update(struct smiapp_sensor *sensor) +{ struct smiapp_pll *pll = &sensor->pll; int rval; @@ -284,7 +291,7 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor) pll->scale_m = sensor->scale_m; pll->bits_per_pixel = sensor->csi_format->compressed; - rval = smiapp_pll_calculate(&client->dev, &lim, pll); + rval = smiapp_pll_try(sensor, pll); if (rval < 0) return rval; -- GitLab From 38a833c7fd75dbbf97a5df25e1e04159693c2b1e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 17 Sep 2014 02:54:37 -0300 Subject: [PATCH 1615/9457] [media] smiapp: Gather information on valid link rate and BPP combinations Not all link rates are possible with all BPP values. Also rearrange other initialisation a little. Obtaining possible PLL configurations earlier requires that. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 69 +++++++++++++++++++------- drivers/media/i2c/smiapp/smiapp.h | 8 +++ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 4d3dc25eb4a8..d65521abf0cc 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -742,6 +742,7 @@ static int smiapp_get_limits_binning(struct smiapp_sensor *sensor) static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + struct smiapp_pll *pll = &sensor->pll; unsigned int type, n; unsigned int i, pixel_order; int rval; @@ -816,6 +817,41 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) } } + /* Figure out which BPP values can be used with which formats. */ + pll->binning_horizontal = 1; + pll->binning_vertical = 1; + pll->scale_m = sensor->scale_m; + + for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) { + const struct smiapp_csi_data_format *f = + &smiapp_csi_data_formats[i]; + unsigned long *valid_link_freqs = + &sensor->valid_link_freqs[ + f->compressed - SMIAPP_COMPRESSED_BASE]; + unsigned int j; + + BUG_ON(f->compressed < SMIAPP_COMPRESSED_BASE); + BUG_ON(f->compressed > SMIAPP_COMPRESSED_MAX); + + if (!(sensor->default_mbus_frame_fmts & 1 << i)) + continue; + + pll->bits_per_pixel = f->compressed; + + for (j = 0; sensor->platform_data->op_sys_clock[j]; j++) { + pll->link_freq = sensor->platform_data->op_sys_clock[j]; + + rval = smiapp_pll_try(sensor, pll); + dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n", + pll->link_freq, pll->bits_per_pixel, + rval ? "not ok" : "ok"); + if (rval) + continue; + + set_bit(j, valid_link_freqs); + } + } + if (!sensor->csi_format) { dev_err(&client->dev, "no supported mbus code found\n"); return -EINVAL; @@ -2479,12 +2515,6 @@ static int smiapp_registered(struct v4l2_subdev *subdev) goto out_power_off; } - rval = smiapp_get_mbus_formats(sensor); - if (rval) { - rval = -ENODEV; - goto out_power_off; - } - if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) { u32 val; @@ -2566,6 +2596,22 @@ static int smiapp_registered(struct v4l2_subdev *subdev) sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; + /* prepare PLL configuration input values */ + pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; + pll->csi2.lanes = sensor->platform_data->lanes; + pll->ext_clk_freq_hz = sensor->platform_data->ext_clk; + pll->flags = smiapp_call_quirk(sensor, pll_flags); + pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; + /* Profile 0 sensors have no separate OP clock branch. */ + if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) + pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; + + rval = smiapp_get_mbus_formats(sensor); + if (rval) { + rval = -ENODEV; + goto out_nvm_release; + } + for (i = 0; i < SMIAPP_SUBDEVS; i++) { struct { struct smiapp_subdev *ssd; @@ -2663,17 +2709,6 @@ static int smiapp_registered(struct v4l2_subdev *subdev) if (rval < 0) goto out_nvm_release; - /* prepare PLL configuration input values */ - pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; - pll->csi2.lanes = sensor->platform_data->lanes; - pll->ext_clk_freq_hz = sensor->platform_data->ext_clk; - pll->flags = smiapp_call_quirk(sensor, pll_flags); - - /* Profile 0 sensors have no separate OP clock branch. */ - if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) - pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; - pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; - mutex_lock(&sensor->mutex); rval = smiapp_update_mode(sensor); mutex_unlock(&sensor->mutex); diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index 874b49ffd88f..f88f8ec344d3 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -156,6 +156,11 @@ struct smiapp_csi_data_format { #define SMIAPP_PAD_SRC 1 #define SMIAPP_PADS 2 +#define SMIAPP_COMPRESSED_BASE 8 +#define SMIAPP_COMPRESSED_MAX 12 +#define SMIAPP_NR_OF_COMPRESSED (SMIAPP_COMPRESSED_MAX - \ + SMIAPP_COMPRESSED_BASE + 1) + struct smiapp_binning_subtype { u8 horizontal:4; u8 vertical:4; @@ -232,6 +237,9 @@ struct smiapp_sensor { struct smiapp_pll pll; + /* Is a default format supported for a given BPP? */ + unsigned long valid_link_freqs[SMIAPP_NR_OF_COMPRESSED]; + /* Pixel array controls */ struct v4l2_ctrl *analog_gain; struct v4l2_ctrl *exposure; -- GitLab From cd78b6afa7adb3aca9aa189ba5fb8a0adab647a2 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 18:08:30 -0300 Subject: [PATCH 1616/9457] [media] smiapp: Take valid link frequencies into account in supported mbus codes Some media bus codes may be unavailable depending on the available media bus codes. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index d65521abf0cc..926f60c00ba1 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -806,14 +806,6 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) dev_dbg(&client->dev, "jolly good! %d\n", j); sensor->default_mbus_frame_fmts |= 1 << j; - if (!sensor->csi_format - || f->width > sensor->csi_format->width - || (f->width == sensor->csi_format->width - && f->compressed - > sensor->csi_format->compressed)) { - sensor->csi_format = f; - sensor->internal_csi_format = f; - } } } @@ -850,6 +842,22 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) set_bit(j, valid_link_freqs); } + + if (!*valid_link_freqs) { + dev_info(&client->dev, + "no valid link frequencies for %u bpp\n", + f->compressed); + sensor->default_mbus_frame_fmts &= ~BIT(i); + continue; + } + + if (!sensor->csi_format + || f->width > sensor->csi_format->width + || (f->width == sensor->csi_format->width + && f->compressed > sensor->csi_format->compressed)) { + sensor->csi_format = f; + sensor->internal_csi_format = f; + } } if (!sensor->csi_format) { -- GitLab From e91cbeb29990d762c997ceec353a14fbbd80a0e1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 26 Sep 2014 10:12:38 -0300 Subject: [PATCH 1617/9457] [media] smiapp: Clean up smiapp_set_format() smiapp_set_format() has accumulated a fair amount of changes without a needed refactoring, do the cleanup now. There's also an unlocked version of v4l2_ctrl_range_changed(), using that fixes a small serialisation issue with the user space interface. __v4l2_ctrl_modify_range() is used instead of v4l2_ctrl_modify_range() in smiapp_set_format_source() since the mutex is now held during the function call. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 73 +++++++++++++++----------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 926f60c00ba1..416b7bd1142c 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -1728,51 +1728,64 @@ static const struct smiapp_csi_data_format return csi_format; } -static int smiapp_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_fh *fh, - struct v4l2_subdev_format *fmt) +static int smiapp_set_format_source(struct v4l2_subdev *subdev, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *fmt) { struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); - struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); - struct v4l2_rect *crops[SMIAPP_PADS]; + const struct smiapp_csi_data_format *csi_format, + *old_csi_format = sensor->csi_format; + u32 code = fmt->format.code; + unsigned int i; + int rval; - mutex_lock(&sensor->mutex); + rval = __smiapp_get_format(subdev, fh, fmt); + if (rval) + return rval; /* * Media bus code is changeable on src subdev's source pad. On * other source pads we just get format here. */ - if (fmt->pad == ssd->source_pad) { - u32 code = fmt->format.code; - int rval = __smiapp_get_format(subdev, fh, fmt); - bool range_changed = false; - unsigned int i; - - if (!rval && subdev == &sensor->src->sd) { - const struct smiapp_csi_data_format *csi_format = - smiapp_validate_csi_data_format(sensor, code); + if (subdev != &sensor->src->sd) + return 0; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - if (csi_format->width != - sensor->csi_format->width) - range_changed = true; + csi_format = smiapp_validate_csi_data_format(sensor, code); - sensor->csi_format = csi_format; - } + fmt->format.code = csi_format->code; - fmt->format.code = csi_format->code; - } + if (fmt->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return 0; - mutex_unlock(&sensor->mutex); - if (rval || !range_changed) - return rval; + sensor->csi_format = csi_format; + if (csi_format->width != old_csi_format->width) for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) - v4l2_ctrl_modify_range( - sensor->test_data[i], - 0, (1 << sensor->csi_format->width) - 1, 1, 0); + __v4l2_ctrl_modify_range( + sensor->test_data[i], 0, + (1 << csi_format->width) - 1, 1, 0); - return 0; + return 0; +} + +static int smiapp_set_format(struct v4l2_subdev *subdev, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *fmt) +{ + struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); + struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); + struct v4l2_rect *crops[SMIAPP_PADS]; + + mutex_lock(&sensor->mutex); + + if (fmt->pad == ssd->source_pad) { + int rval; + + rval = smiapp_set_format_source(subdev, fh, fmt); + + mutex_unlock(&sensor->mutex); + + return rval; } /* Sink pad. Width and height are changeable here. */ -- GitLab From 602cbcaa8ebe0444ab99f4e6f3b0ef6497d94033 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 26 Sep 2014 10:19:43 -0300 Subject: [PATCH 1618/9457] [media] smiapp: Set valid link frequency range Set supported link frequencies in the menu in control initialisation and when the bpp changes. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 416b7bd1142c..f1a9f82dd44a 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -523,6 +523,8 @@ static const struct v4l2_ctrl_ops smiapp_ctrl_ops = { static int smiapp_init_controls(struct smiapp_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + unsigned long *valid_link_freqs = &sensor->valid_link_freqs[ + sensor->csi_format->compressed - SMIAPP_COMPRESSED_BASE]; unsigned int max, i; int rval; @@ -605,8 +607,8 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor) sensor->link_freq = v4l2_ctrl_new_int_menu( &sensor->src->ctrl_handler, &smiapp_ctrl_ops, - V4L2_CID_LINK_FREQ, max, 0, - sensor->platform_data->op_sys_clock); + V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs), + __ffs(*valid_link_freqs), sensor->platform_data->op_sys_clock); sensor->pixel_rate_csi = v4l2_ctrl_new_std( &sensor->src->ctrl_handler, &smiapp_ctrl_ops, @@ -1735,6 +1737,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); const struct smiapp_csi_data_format *csi_format, *old_csi_format = sensor->csi_format; + unsigned long *valid_link_freqs; u32 code = fmt->format.code; unsigned int i; int rval; @@ -1765,6 +1768,18 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, sensor->test_data[i], 0, (1 << csi_format->width) - 1, 1, 0); + if (csi_format->compressed == old_csi_format->compressed) + return 0; + + valid_link_freqs = + &sensor->valid_link_freqs[sensor->csi_format->compressed + - SMIAPP_COMPRESSED_BASE]; + + __v4l2_ctrl_modify_range( + sensor->link_freq, 0, + __fls(*valid_link_freqs), ~*valid_link_freqs, + __ffs(*valid_link_freqs)); + return 0; } -- GitLab From 373fbbce546be8914e625373eaa16036a695d39d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 16 Sep 2014 17:19:04 -0300 Subject: [PATCH 1619/9457] [media] smiapp: Update PLL when setting format The media bus format BPP does affect PLL. Recalculate PLL if the format changes. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index f1a9f82dd44a..bcc5866175b7 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -1780,7 +1780,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, __fls(*valid_link_freqs), ~*valid_link_freqs, __ffs(*valid_link_freqs)); - return 0; + return smiapp_pll_update(sensor); } static int smiapp_set_format(struct v4l2_subdev *subdev, -- GitLab From 1f923a42033ad05baf755775e3339b5c319b5898 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 22 Sep 2014 09:27:17 -0300 Subject: [PATCH 1620/9457] [media] mem2mem_testdev: rename to vim2m This is 1) *much* easier to type, and 2) is consistent with vivid ('vi' for virtual). More of such virtual drivers are planned, so keeping the naming consistent makes sense. Note that the old module name is retained as a module alias. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 4 +- drivers/media/platform/Makefile | 2 +- .../platform/{mem2mem_testdev.c => vim2m.c} | 221 +++++++++--------- 3 files changed, 113 insertions(+), 114 deletions(-) rename drivers/media/platform/{mem2mem_testdev.c => vim2m.c} (81%) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 3aac88f1d54a..0c61155699f7 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -267,8 +267,8 @@ if V4L_TEST_DRIVERS source "drivers/media/platform/vivid/Kconfig" -config VIDEO_MEM2MEM_TESTDEV - tristate "Virtual test device for mem2mem framework" +config VIDEO_VIM2M + tristate "Virtual Memory-to-Memory Driver" depends on VIDEO_DEV && VIDEO_V4L2 select VIDEOBUF2_VMALLOC select V4L2_MEM2MEM_DEV diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 579046bc276f..b818afb4d336 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/ obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o obj-$(CONFIG_VIDEO_VIVID) += vivid/ -obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o +obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/ diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/vim2m.c similarity index 81% rename from drivers/media/platform/mem2mem_testdev.c rename to drivers/media/platform/vim2m.c index c1b03cfd6ded..87af47ae1f76 100644 --- a/drivers/media/platform/mem2mem_testdev.c +++ b/drivers/media/platform/vim2m.c @@ -31,12 +31,11 @@ #include #include -#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev" - MODULE_DESCRIPTION("Virtual device for mem2mem framework testing"); MODULE_AUTHOR("Pawel Osciak, "); MODULE_LICENSE("GPL"); MODULE_VERSION("0.1.1"); +MODULE_ALIAS("mem2mem_testdev"); static unsigned debug; module_param(debug, uint, 0644); @@ -52,7 +51,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define MEM2MEM_CAPTURE (1 << 0) #define MEM2MEM_OUTPUT (1 << 1) -#define MEM2MEM_NAME "m2m-testdev" +#define MEM2MEM_NAME "vim2m" /* Per queue */ #define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME @@ -72,15 +71,15 @@ MODULE_PARM_DESC(debug, "activates debug info"); v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) -static void m2mtest_dev_release(struct device *dev) +static void vim2m_dev_release(struct device *dev) {} -static struct platform_device m2mtest_pdev = { +static struct platform_device vim2m_pdev = { .name = MEM2MEM_NAME, - .dev.release = m2mtest_dev_release, + .dev.release = vim2m_dev_release, }; -struct m2mtest_fmt { +struct vim2m_fmt { char *name; u32 fourcc; int depth; @@ -88,7 +87,7 @@ struct m2mtest_fmt { u32 types; }; -static struct m2mtest_fmt formats[] = { +static struct vim2m_fmt formats[] = { { .name = "RGB565 (BE)", .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ @@ -108,12 +107,12 @@ static struct m2mtest_fmt formats[] = { #define NUM_FORMATS ARRAY_SIZE(formats) /* Per-queue, driver-specific private data */ -struct m2mtest_q_data { +struct vim2m_q_data { unsigned int width; unsigned int height; unsigned int sizeimage; unsigned int sequence; - struct m2mtest_fmt *fmt; + struct vim2m_fmt *fmt; }; enum { @@ -124,9 +123,9 @@ enum { #define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000) #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001) -static struct m2mtest_fmt *find_format(struct v4l2_format *f) +static struct vim2m_fmt *find_format(struct v4l2_format *f) { - struct m2mtest_fmt *fmt; + struct vim2m_fmt *fmt; unsigned int k; for (k = 0; k < NUM_FORMATS; k++) { @@ -141,7 +140,7 @@ static struct m2mtest_fmt *find_format(struct v4l2_format *f) return &formats[k]; } -struct m2mtest_dev { +struct vim2m_dev { struct v4l2_device v4l2_dev; struct video_device *vfd; @@ -154,9 +153,9 @@ struct m2mtest_dev { struct v4l2_m2m_dev *m2m_dev; }; -struct m2mtest_ctx { +struct vim2m_ctx { struct v4l2_fh fh; - struct m2mtest_dev *dev; + struct vim2m_dev *dev; struct v4l2_ctrl_handler hdl; @@ -177,15 +176,15 @@ struct m2mtest_ctx { enum v4l2_colorspace colorspace; /* Source and destination queue data */ - struct m2mtest_q_data q_data[2]; + struct vim2m_q_data q_data[2]; }; -static inline struct m2mtest_ctx *file2ctx(struct file *file) +static inline struct vim2m_ctx *file2ctx(struct file *file) { - return container_of(file->private_data, struct m2mtest_ctx, fh); + return container_of(file->private_data, struct vim2m_ctx, fh); } -static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, +static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx, enum v4l2_buf_type type) { switch (type) { @@ -200,12 +199,12 @@ static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, } -static int device_process(struct m2mtest_ctx *ctx, +static int device_process(struct vim2m_ctx *ctx, struct vb2_buffer *in_vb, struct vb2_buffer *out_vb) { - struct m2mtest_dev *dev = ctx->dev; - struct m2mtest_q_data *q_data; + struct vim2m_dev *dev = ctx->dev; + struct vim2m_q_data *q_data; u8 *p_in, *p_out; int x, y, t, w; int tile_w, bytes_left; @@ -334,7 +333,7 @@ static int device_process(struct m2mtest_ctx *ctx, return 0; } -static void schedule_irq(struct m2mtest_dev *dev, int msec_timeout) +static void schedule_irq(struct vim2m_dev *dev, int msec_timeout) { dprintk(dev, "Scheduling a simulated irq\n"); mod_timer(&dev->timer, jiffies + msecs_to_jiffies(msec_timeout)); @@ -349,7 +348,7 @@ static void schedule_irq(struct m2mtest_dev *dev, int msec_timeout) */ static int job_ready(void *priv) { - struct m2mtest_ctx *ctx = priv; + struct vim2m_ctx *ctx = priv; if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) { @@ -362,7 +361,7 @@ static int job_ready(void *priv) static void job_abort(void *priv) { - struct m2mtest_ctx *ctx = priv; + struct vim2m_ctx *ctx = priv; /* Will cancel the transaction in the next interrupt handler */ ctx->aborting = 1; @@ -376,8 +375,8 @@ static void job_abort(void *priv) */ static void device_run(void *priv) { - struct m2mtest_ctx *ctx = priv; - struct m2mtest_dev *dev = ctx->dev; + struct vim2m_ctx *ctx = priv; + struct vim2m_dev *dev = ctx->dev; struct vb2_buffer *src_buf, *dst_buf; src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); @@ -391,12 +390,12 @@ static void device_run(void *priv) static void device_isr(unsigned long priv) { - struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv; - struct m2mtest_ctx *curr_ctx; + struct vim2m_dev *vim2m_dev = (struct vim2m_dev *)priv; + struct vim2m_ctx *curr_ctx; struct vb2_buffer *src_vb, *dst_vb; unsigned long flags; - curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev); + curr_ctx = v4l2_m2m_get_curr_priv(vim2m_dev->m2m_dev); if (NULL == curr_ctx) { pr_err("Instance released before the end of transaction\n"); @@ -408,16 +407,16 @@ static void device_isr(unsigned long priv) curr_ctx->num_processed++; - spin_lock_irqsave(&m2mtest_dev->irqlock, flags); + spin_lock_irqsave(&vim2m_dev->irqlock, flags); v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); - spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags); + spin_unlock_irqrestore(&vim2m_dev->irqlock, flags); if (curr_ctx->num_processed == curr_ctx->translen || curr_ctx->aborting) { dprintk(curr_ctx->dev, "Finishing transaction\n"); curr_ctx->num_processed = 0; - v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->fh.m2m_ctx); + v4l2_m2m_job_finish(vim2m_dev->m2m_dev, curr_ctx->fh.m2m_ctx); } else { device_run(curr_ctx); } @@ -441,7 +440,7 @@ static int vidioc_querycap(struct file *file, void *priv, static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) { int i, num; - struct m2mtest_fmt *fmt; + struct vim2m_fmt *fmt; num = 0; @@ -480,10 +479,10 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, return enum_fmt(f, MEM2MEM_OUTPUT); } -static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) +static int vidioc_g_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f) { struct vb2_queue *vq; - struct m2mtest_q_data *q_data; + struct vim2m_q_data *q_data; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) @@ -514,7 +513,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, return vidioc_g_fmt(file2ctx(file), f); } -static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt) +static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt) { /* V4L2 specification suggests the driver corrects the format struct * if any of the dimensions is unsupported */ @@ -539,8 +538,8 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct m2mtest_fmt *fmt; - struct m2mtest_ctx *ctx = file2ctx(file); + struct vim2m_fmt *fmt; + struct vim2m_ctx *ctx = file2ctx(file); fmt = find_format(f); if (!fmt) { @@ -561,8 +560,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { - struct m2mtest_fmt *fmt; - struct m2mtest_ctx *ctx = file2ctx(file); + struct vim2m_fmt *fmt; + struct vim2m_ctx *ctx = file2ctx(file); fmt = find_format(f); if (!fmt) { @@ -581,9 +580,9 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, return vidioc_try_fmt(f, fmt); } -static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) +static int vidioc_s_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f) { - struct m2mtest_q_data *q_data; + struct vim2m_q_data *q_data; struct vb2_queue *vq; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); @@ -627,7 +626,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { - struct m2mtest_ctx *ctx = file2ctx(file); + struct vim2m_ctx *ctx = file2ctx(file); int ret; ret = vidioc_try_fmt_vid_out(file, priv, f); @@ -640,10 +639,10 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, return ret; } -static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl) +static int vim2m_s_ctrl(struct v4l2_ctrl *ctrl) { - struct m2mtest_ctx *ctx = - container_of(ctrl->handler, struct m2mtest_ctx, hdl); + struct vim2m_ctx *ctx = + container_of(ctrl->handler, struct vim2m_ctx, hdl); switch (ctrl->id) { case V4L2_CID_HFLIP: @@ -676,12 +675,12 @@ static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static const struct v4l2_ctrl_ops m2mtest_ctrl_ops = { - .s_ctrl = m2mtest_s_ctrl, +static const struct v4l2_ctrl_ops vim2m_ctrl_ops = { + .s_ctrl = vim2m_s_ctrl, }; -static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = { +static const struct v4l2_ioctl_ops vim2m_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, @@ -711,13 +710,13 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = { * Queue operations */ -static int m2mtest_queue_setup(struct vb2_queue *vq, +static int vim2m_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { - struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq); - struct m2mtest_q_data *q_data; + struct vim2m_ctx *ctx = vb2_get_drv_priv(vq); + struct vim2m_q_data *q_data; unsigned int size, count = *nbuffers; q_data = get_q_data(ctx, vq->type); @@ -741,10 +740,10 @@ static int m2mtest_queue_setup(struct vb2_queue *vq, return 0; } -static int m2mtest_buf_prepare(struct vb2_buffer *vb) +static int vim2m_buf_prepare(struct vb2_buffer *vb) { - struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct m2mtest_q_data *q_data; + struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vim2m_q_data *q_data; dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); @@ -770,25 +769,25 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb) return 0; } -static void m2mtest_buf_queue(struct vb2_buffer *vb) +static void vim2m_buf_queue(struct vb2_buffer *vb) { - struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); } -static int m2mtest_start_streaming(struct vb2_queue *q, unsigned count) +static int vim2m_start_streaming(struct vb2_queue *q, unsigned count) { - struct m2mtest_ctx *ctx = vb2_get_drv_priv(q); - struct m2mtest_q_data *q_data = get_q_data(ctx, q->type); + struct vim2m_ctx *ctx = vb2_get_drv_priv(q); + struct vim2m_q_data *q_data = get_q_data(ctx, q->type); q_data->sequence = 0; return 0; } -static void m2mtest_stop_streaming(struct vb2_queue *q) +static void vim2m_stop_streaming(struct vb2_queue *q) { - struct m2mtest_ctx *ctx = vb2_get_drv_priv(q); + struct vim2m_ctx *ctx = vb2_get_drv_priv(q); struct vb2_buffer *vb; unsigned long flags; @@ -805,26 +804,26 @@ static void m2mtest_stop_streaming(struct vb2_queue *q) } } -static struct vb2_ops m2mtest_qops = { - .queue_setup = m2mtest_queue_setup, - .buf_prepare = m2mtest_buf_prepare, - .buf_queue = m2mtest_buf_queue, - .start_streaming = m2mtest_start_streaming, - .stop_streaming = m2mtest_stop_streaming, +static struct vb2_ops vim2m_qops = { + .queue_setup = vim2m_queue_setup, + .buf_prepare = vim2m_buf_prepare, + .buf_queue = vim2m_buf_queue, + .start_streaming = vim2m_start_streaming, + .stop_streaming = vim2m_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, }; static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) { - struct m2mtest_ctx *ctx = priv; + struct vim2m_ctx *ctx = priv; int ret; src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - src_vq->ops = &m2mtest_qops; + src_vq->ops = &vim2m_qops; src_vq->mem_ops = &vb2_vmalloc_memops; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->dev->dev_mutex; @@ -837,7 +836,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - dst_vq->ops = &m2mtest_qops; + dst_vq->ops = &vim2m_qops; dst_vq->mem_ops = &vb2_vmalloc_memops; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock = &ctx->dev->dev_mutex; @@ -845,8 +844,8 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds return vb2_queue_init(dst_vq); } -static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = { - .ops = &m2mtest_ctrl_ops, +static const struct v4l2_ctrl_config vim2m_ctrl_trans_time_msec = { + .ops = &vim2m_ctrl_ops, .id = V4L2_CID_TRANS_TIME_MSEC, .name = "Transaction Time (msec)", .type = V4L2_CTRL_TYPE_INTEGER, @@ -856,8 +855,8 @@ static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = { .step = 1, }; -static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = { - .ops = &m2mtest_ctrl_ops, +static const struct v4l2_ctrl_config vim2m_ctrl_trans_num_bufs = { + .ops = &vim2m_ctrl_ops, .id = V4L2_CID_TRANS_NUM_BUFS, .name = "Buffers Per Transaction", .type = V4L2_CTRL_TYPE_INTEGER, @@ -870,10 +869,10 @@ static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = { /* * File operations */ -static int m2mtest_open(struct file *file) +static int vim2m_open(struct file *file) { - struct m2mtest_dev *dev = video_drvdata(file); - struct m2mtest_ctx *ctx = NULL; + struct vim2m_dev *dev = video_drvdata(file); + struct vim2m_ctx *ctx = NULL; struct v4l2_ctrl_handler *hdl; int rc = 0; @@ -890,10 +889,10 @@ static int m2mtest_open(struct file *file) ctx->dev = dev; hdl = &ctx->hdl; v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_time_msec, NULL); - v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_num_bufs, NULL); + v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_time_msec, NULL); + v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_num_bufs, NULL); if (hdl->error) { rc = hdl->error; v4l2_ctrl_handler_free(hdl); @@ -933,10 +932,10 @@ static int m2mtest_open(struct file *file) return rc; } -static int m2mtest_release(struct file *file) +static int vim2m_release(struct file *file) { - struct m2mtest_dev *dev = video_drvdata(file); - struct m2mtest_ctx *ctx = file2ctx(file); + struct vim2m_dev *dev = video_drvdata(file); + struct vim2m_ctx *ctx = file2ctx(file); dprintk(dev, "Releasing instance %p\n", ctx); @@ -953,20 +952,20 @@ static int m2mtest_release(struct file *file) return 0; } -static const struct v4l2_file_operations m2mtest_fops = { +static const struct v4l2_file_operations vim2m_fops = { .owner = THIS_MODULE, - .open = m2mtest_open, - .release = m2mtest_release, + .open = vim2m_open, + .release = vim2m_release, .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, .mmap = v4l2_m2m_fop_mmap, }; -static struct video_device m2mtest_videodev = { +static struct video_device vim2m_videodev = { .name = MEM2MEM_NAME, .vfl_dir = VFL_DIR_M2M, - .fops = &m2mtest_fops, - .ioctl_ops = &m2mtest_ioctl_ops, + .fops = &vim2m_fops, + .ioctl_ops = &vim2m_ioctl_ops, .minor = -1, .release = video_device_release, }; @@ -977,9 +976,9 @@ static struct v4l2_m2m_ops m2m_ops = { .job_abort = job_abort, }; -static int m2mtest_probe(struct platform_device *pdev) +static int vim2m_probe(struct platform_device *pdev) { - struct m2mtest_dev *dev; + struct vim2m_dev *dev; struct video_device *vfd; int ret; @@ -1003,7 +1002,7 @@ static int m2mtest_probe(struct platform_device *pdev) goto unreg_dev; } - *vfd = m2mtest_videodev; + *vfd = vim2m_videodev; vfd->lock = &dev->dev_mutex; vfd->v4l2_dev = &dev->v4l2_dev; @@ -1014,7 +1013,7 @@ static int m2mtest_probe(struct platform_device *pdev) } video_set_drvdata(vfd, dev); - snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name); + snprintf(vfd->name, sizeof(vfd->name), "%s", vim2m_videodev.name); dev->vfd = vfd; v4l2_info(&dev->v4l2_dev, "Device registered as /dev/video%d\n", vfd->num); @@ -1042,11 +1041,11 @@ static int m2mtest_probe(struct platform_device *pdev) return ret; } -static int m2mtest_remove(struct platform_device *pdev) +static int vim2m_remove(struct platform_device *pdev) { - struct m2mtest_dev *dev = platform_get_drvdata(pdev); + struct vim2m_dev *dev = platform_get_drvdata(pdev); - v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); + v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); v4l2_m2m_release(dev->m2m_dev); del_timer_sync(&dev->timer); video_unregister_device(dev->vfd); @@ -1055,35 +1054,35 @@ static int m2mtest_remove(struct platform_device *pdev) return 0; } -static struct platform_driver m2mtest_pdrv = { - .probe = m2mtest_probe, - .remove = m2mtest_remove, +static struct platform_driver vim2m_pdrv = { + .probe = vim2m_probe, + .remove = vim2m_remove, .driver = { .name = MEM2MEM_NAME, .owner = THIS_MODULE, }, }; -static void __exit m2mtest_exit(void) +static void __exit vim2m_exit(void) { - platform_driver_unregister(&m2mtest_pdrv); - platform_device_unregister(&m2mtest_pdev); + platform_driver_unregister(&vim2m_pdrv); + platform_device_unregister(&vim2m_pdev); } -static int __init m2mtest_init(void) +static int __init vim2m_init(void) { int ret; - ret = platform_device_register(&m2mtest_pdev); + ret = platform_device_register(&vim2m_pdev); if (ret) return ret; - ret = platform_driver_register(&m2mtest_pdrv); + ret = platform_driver_register(&vim2m_pdrv); if (ret) - platform_device_unregister(&m2mtest_pdev); + platform_device_unregister(&vim2m_pdev); return 0; } -module_init(m2mtest_init); -module_exit(m2mtest_exit); +module_init(vim2m_init); +module_exit(vim2m_exit); -- GitLab From 1f2b045205ce9f54babf912c9d875d7b013e4660 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 16 Oct 2014 21:47:57 +0200 Subject: [PATCH 1621/9457] pinctrl: imx: add gpio pinmux support for vf610 Add pinmux support for GPIO for Vybrid (vf610) IOMUX controller. This is needed since direction configuration is not part of the GPIO module in Vybrid. Signed-off-by: Stefan Agner Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx.c | 72 +++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index f2446769247f..52f2b9404fe0 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -294,11 +294,83 @@ static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } +static int imx_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + const struct imx_pin_reg *pin_reg; + struct imx_pin_group *grp; + struct imx_pin *imx_pin; + unsigned int pin, group; + u32 reg; + + /* Currently implementation only for shared mux/conf register */ + if (!(info->flags & SHARE_MUX_CONF_REG)) + return -EINVAL; + + pin_reg = &info->pin_regs[offset]; + if (pin_reg->mux_reg == -1) + return -EINVAL; + + /* Find the pinctrl config with GPIO mux mode for the requested pin */ + for (group = 0; group < info->ngroups; group++) { + grp = &info->groups[group]; + for (pin = 0; pin < grp->npins; pin++) { + imx_pin = &grp->pins[pin]; + if (imx_pin->pin == offset && !imx_pin->mux_mode) + goto mux_pin; + } + } + + return -EINVAL; + +mux_pin: + reg = readl(ipctl->base + pin_reg->mux_reg); + reg &= ~(0x7 << 20); + reg |= imx_pin->config; + writel(reg, ipctl->base + pin_reg->mux_reg); + + return 0; +} + +static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset, bool input) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + const struct imx_pin_reg *pin_reg; + u32 reg; + + /* + * Only Vybrid has the input/output buffer enable flags (IBE/OBE) + * They are part of the shared mux/conf register. + */ + if (!(info->flags & SHARE_MUX_CONF_REG)) + return -EINVAL; + + pin_reg = &info->pin_regs[offset]; + if (pin_reg->mux_reg == -1) + return -EINVAL; + + /* IBE always enabled allows us to read the value "on the wire" */ + reg = readl(ipctl->base + pin_reg->mux_reg); + if (input) + reg &= ~0x2; + else + reg |= 0x2; + writel(reg, ipctl->base + pin_reg->mux_reg); + + return 0; +} + static const struct pinmux_ops imx_pmx_ops = { .get_functions_count = imx_pmx_get_funcs_count, .get_function_name = imx_pmx_get_func_name, .get_function_groups = imx_pmx_get_groups, .set_mux = imx_pmx_set, + .gpio_request_enable = imx_pmx_gpio_request_enable, + .gpio_set_direction = imx_pmx_gpio_set_direction, }; static int imx_pinconf_get(struct pinctrl_dev *pctldev, -- GitLab From 9067bbe5989c39bd4d482edfd4d38ad99d5b081f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 13 Oct 2014 15:50:08 -0500 Subject: [PATCH 1622/9457] pinctrl: baytrail: add missing module removal support pinctrl-baytrail driver provides a proper ->remove() method on its platform_driver definition, however there's no way, currently, to unload the driver due to missing module_exit(). This patch adds module_exit(). Signed-off-by: Felipe Balbi Acked-by: David Cohen Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-baytrail.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index e12e5b07f6d7..3ece00164523 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -612,5 +612,10 @@ static int __init byt_gpio_init(void) { return platform_driver_register(&byt_gpio_driver); } - subsys_initcall(byt_gpio_init); + +static void __exit byt_gpio_exit(void) +{ + platform_driver_unregister(&byt_gpio_driver); +} +module_exit(byt_gpio_exit); -- GitLab From c61c2d7071d865adc3bbd92dee670bcf7bf56099 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 12:12:22 +0200 Subject: [PATCH 1623/9457] pinctrl: tegra-xusb: Don't leak configurations The pinctrl config helpers make a separate copy of the configuration, so callers must make sure to free any dynamically allocated memory that was used to store it. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tegra-xusb.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c index 1631ec94fb02..080ec7723ef2 100644 --- a/drivers/pinctrl/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/pinctrl-tegra-xusb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -171,7 +172,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, if (err == -EINVAL) continue; - return err; + goto out; } config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value); @@ -179,7 +180,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, err = pinctrl_utils_add_config(padctl->pinctrl, &configs, &num_configs, config); if (err < 0) - return err; + goto out; } if (function) @@ -190,14 +191,14 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, err = of_property_count_strings(np, "nvidia,lanes"); if (err < 0) - return err; + goto out; reserve *= err; err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps, num_maps, reserve); if (err < 0) - return err; + goto out; of_property_for_each_string(np, "nvidia,lanes", prop, group) { if (function) { @@ -205,7 +206,7 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, reserved_maps, num_maps, group, function); if (err < 0) - return err; + goto out; } if (num_configs) { @@ -214,11 +215,15 @@ static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl, configs, num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); if (err < 0) - return err; + goto out; } } - return 0; + err = 0; + +out: + kfree(configs); + return err; } static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl, -- GitLab From eec450713e5c5cafa9b8565c84548580080b1f64 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Thu, 16 Oct 2014 10:11:29 -0700 Subject: [PATCH 1624/9457] pinctrl: pinconf-generic: Add flag to print arguments When dumping pinconf information in debugfs, config arguments are only printed when a unit is present and the argument is != 0. For parameters like the slew rate, this does not work. The slew rate uses a driver specific format for the argument, i.e. 0 can be a valid argument and a unit is not provided for it. For that reason, add a flag to enable printing the argument instead of inferring it from the presence of a unit and the value of the argument. Signed-off-by: Soren Brinkmann Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 65 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 29ff77f90fcb..e28ef957ca2d 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -32,30 +32,32 @@ struct pin_config_item { const enum pin_config_param param; const char * const display; const char * const format; + bool has_arg; }; -#define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c } +#define PCONFDUMP(a, b, c, d) { .param = a, .display = b, .format = c, \ + .has_arg = d } static struct pin_config_item conf_items[] = { - PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL), - PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL), - PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL), - PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL), - PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL), + PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false), + PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false), + PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false), + PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false), + PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, - "input bias pull to pin specific state", NULL), - PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), - PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), - PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), - PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"), - PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL), - PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL), - PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), - PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec"), - PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), - PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL), - PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"), - PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"), + "input bias pull to pin specific state", NULL, false), + PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false), + PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false), + PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false), + PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA", true), + PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false), + PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false), + PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false), + PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec", true), + PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true), + PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true), + PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true), + PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true), }; void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, @@ -85,11 +87,14 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, seq_puts(s, " "); seq_puts(s, conf_items[i].display); /* Print unit if available */ - if (conf_items[i].format && - pinconf_to_config_argument(config) != 0) - seq_printf(s, " (%u %s)", - pinconf_to_config_argument(config), - conf_items[i].format); + if (conf_items[i].has_arg) { + seq_printf(s, " (%u", + pinconf_to_config_argument(config)); + if (conf_items[i].format) + seq_printf(s, " %s)", conf_items[i].format); + else + seq_puts(s, ")"); + } } } @@ -121,10 +126,14 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev, seq_puts(s, " "); seq_puts(s, conf_items[i].display); /* Print unit if available */ - if (conf_items[i].format && config != 0) - seq_printf(s, " (%u %s)", - pinconf_to_config_argument(config), - conf_items[i].format); + if (conf_items[i].has_arg) { + seq_printf(s, " (%u", + pinconf_to_config_argument(config)); + if (conf_items[i].format) + seq_printf(s, " %s)", conf_items[i].format); + else + seq_puts(s, ")"); + } } } -- GitLab From 90305829635d90a5053ec99a261035b4ce0a2649 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 28 Oct 2014 17:16:47 +0200 Subject: [PATCH 1625/9457] Bluetooth: 6lowpan: Converting rwlocks to use RCU The rwlocks are converted to use RCU. This helps performance as the irq locks are not needed any more. Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 222 +++++++++++++++++++++++----------------- 1 file changed, 127 insertions(+), 95 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index aa6ebbfc5d31..a681247b0aee 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -53,7 +53,7 @@ struct skb_cb { * The list contains struct lowpan_dev elements. */ static LIST_HEAD(bt_6lowpan_devices); -static DEFINE_RWLOCK(devices_lock); +static DEFINE_SPINLOCK(devices_lock); /* If psm is set to 0 (default value), then 6lowpan is disabled. * Other values are used to indicate a Protocol Service Multiplexer @@ -67,6 +67,7 @@ static struct l2cap_chan *listen_chan; struct lowpan_peer { struct list_head list; + struct rcu_head rcu; struct l2cap_chan *chan; /* peer addresses in various formats */ @@ -86,6 +87,13 @@ struct lowpan_dev { struct delayed_work notify_peers; }; +static inline void peer_free(struct rcu_head *head) +{ + struct lowpan_peer *e = container_of(head, struct lowpan_peer, rcu); + + kfree(e); +} + static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) { return netdev_priv(netdev); @@ -93,13 +101,14 @@ static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) { - list_add(&peer->list, &dev->peers); + list_add_rcu(&peer->list, &dev->peers); atomic_inc(&dev->peer_count); } static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) { - list_del(&peer->list); + list_del_rcu(&peer->list); + call_rcu(&peer->rcu, peer_free); module_put(THIS_MODULE); @@ -114,31 +123,37 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, bdaddr_t *ba, __u8 type) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; BT_DBG("peers %d addr %pMR type %d", atomic_read(&dev->peer_count), ba, type); - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + rcu_read_lock(); + + list_for_each_entry_rcu(peer, &dev->peers, list) { BT_DBG("dst addr %pMR dst type %d", &peer->chan->dst, peer->chan->dst_type); if (bacmp(&peer->chan->dst, ba)) continue; - if (type == peer->chan->dst_type) + if (type == peer->chan->dst_type) { + rcu_read_unlock(); return peer; + } } + rcu_read_unlock(); + return NULL; } -static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev, - struct l2cap_chan *chan) +static inline struct lowpan_peer *__peer_lookup_chan(struct lowpan_dev *dev, + struct l2cap_chan *chan) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + list_for_each_entry_rcu(peer, &dev->peers, list) { if (peer->chan == chan) return peer; } @@ -146,12 +161,12 @@ static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev, return NULL; } -static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev, - struct l2cap_conn *conn) +static inline struct lowpan_peer *__peer_lookup_conn(struct lowpan_dev *dev, + struct l2cap_conn *conn) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + list_for_each_entry_rcu(peer, &dev->peers, list) { if (peer->chan->conn == conn) return peer; } @@ -163,7 +178,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, struct in6_addr *daddr, struct sk_buff *skb) { - struct lowpan_peer *peer, *tmp; + struct lowpan_peer *peer; struct in6_addr *nexthop; struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); int count = atomic_read(&dev->peer_count); @@ -174,9 +189,13 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, * send the packet. If only one peer exists, then we can send the * packet right away. */ - if (count == 1) - return list_first_entry(&dev->peers, struct lowpan_peer, - list); + if (count == 1) { + rcu_read_lock(); + peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer, + list); + rcu_read_unlock(); + return peer; + } if (!rt) { nexthop = &lowpan_cb(skb)->gw; @@ -195,53 +214,57 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, BT_DBG("gw %pI6c", nexthop); - list_for_each_entry_safe(peer, tmp, &dev->peers, list) { + rcu_read_lock(); + + list_for_each_entry_rcu(peer, &dev->peers, list) { BT_DBG("dst addr %pMR dst type %d ip %pI6c", &peer->chan->dst, peer->chan->dst_type, &peer->peer_addr); - if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) + if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) { + rcu_read_unlock(); return peer; + } } + rcu_read_unlock(); + return NULL; } static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_peer *peer = NULL; - unsigned long flags; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { - peer = peer_lookup_conn(entry, conn); + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + peer = __peer_lookup_conn(entry, conn); if (peer) break; } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return peer; } static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_dev *dev = NULL; - unsigned long flags; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { if (conn->hcon->hdev == entry->hdev) { dev = entry; break; } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return dev; } @@ -264,13 +287,12 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, u8 iphc0, iphc1; struct lowpan_dev *dev; struct lowpan_peer *peer; - unsigned long flags; dev = lowpan_dev(netdev); - read_lock_irqsave(&devices_lock, flags); - peer = peer_lookup_chan(dev, chan); - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_lock(); + peer = __peer_lookup_chan(dev, chan); + rcu_read_unlock(); if (!peer) goto drop; @@ -452,7 +474,6 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, if (ipv6_addr_is_multicast(&ipv6_daddr)) { lowpan_cb(skb)->chan = NULL; } else { - unsigned long flags; u8 addr_type; /* Get destination BT device from skb. @@ -463,19 +484,14 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, BT_DBG("dest addr %pMR type %d IP %pI6c", &addr, addr_type, &ipv6_daddr); - read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_ba(dev, &addr, addr_type); - read_unlock_irqrestore(&devices_lock, flags); - if (!peer) { /* The packet might be sent to 6lowpan interface * because of routing (either via default route * or user set route) so get peer according to * the destination address. */ - read_lock_irqsave(&devices_lock, flags); peer = peer_lookup_dst(dev, &ipv6_daddr, skb); - read_unlock_irqrestore(&devices_lock, flags); if (!peer) { BT_DBG("no such peer %pMR found", &addr); return -ENOENT; @@ -558,14 +574,13 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) { struct sk_buff *local_skb; - struct lowpan_dev *entry, *tmp; - unsigned long flags; + struct lowpan_dev *entry; int err = 0; - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { - struct lowpan_peer *pentry, *ptmp; + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + struct lowpan_peer *pentry; struct lowpan_dev *dev; if (entry->netdev != netdev) @@ -573,7 +588,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) dev = lowpan_dev(entry->netdev); - list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { + list_for_each_entry_rcu(pentry, &dev->peers, list) { int ret; local_skb = skb_clone(skb, GFP_ATOMIC); @@ -590,7 +605,7 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); return err; } @@ -792,7 +807,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, struct lowpan_dev *dev) { struct lowpan_peer *peer; - unsigned long flags; peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -815,10 +829,10 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, */ set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8); - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); INIT_LIST_HEAD(&peer->list); peer_add(dev, peer); - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); /* Notifying peers about us needs to be done without locks held */ INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers); @@ -831,7 +845,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) { struct net_device *netdev; int err = 0; - unsigned long flags; netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN, netdev_setup); @@ -861,10 +874,10 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) (*dev)->hdev = chan->conn->hcon->hdev; INIT_LIST_HEAD(&(*dev)->peers); - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); INIT_LIST_HEAD(&(*dev)->list); - list_add(&(*dev)->list, &bt_6lowpan_devices); - write_unlock_irqrestore(&devices_lock, flags); + list_add_rcu(&(*dev)->list, &bt_6lowpan_devices); + spin_unlock(&devices_lock); return 0; @@ -918,11 +931,10 @@ static void delete_netdev(struct work_struct *work) static void chan_close_cb(struct l2cap_chan *chan) { - struct lowpan_dev *entry, *tmp; + struct lowpan_dev *entry; struct lowpan_dev *dev = NULL; struct lowpan_peer *peer; int err = -ENOENT; - unsigned long flags; bool last = false, removed = true; BT_DBG("chan %p conn %p", chan, chan->conn); @@ -937,11 +949,11 @@ static void chan_close_cb(struct l2cap_chan *chan) removed = false; } - write_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { dev = lowpan_dev(entry->netdev); - peer = peer_lookup_chan(dev, chan); + peer = __peer_lookup_chan(dev, chan); if (peer) { last = peer_del(dev, peer); err = 0; @@ -952,13 +964,12 @@ static void chan_close_cb(struct l2cap_chan *chan) atomic_read(&chan->kref.refcount)); l2cap_chan_put(chan); - kfree(peer); break; } } if (!err && last && dev && !atomic_read(&dev->peer_count)) { - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); cancel_delayed_work_sync(&dev->notify_peers); @@ -969,7 +980,7 @@ static void chan_close_cb(struct l2cap_chan *chan) schedule_work(&entry->delete_netdev); } } else { - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); } return; @@ -1161,10 +1172,9 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type, static void disconnect_all_peers(void) { - struct lowpan_dev *entry, *tmp_dev; + struct lowpan_dev *entry; struct lowpan_peer *peer, *tmp_peer, *new_peer; struct list_head peers; - unsigned long flags; INIT_LIST_HEAD(&peers); @@ -1173,10 +1183,10 @@ static void disconnect_all_peers(void) * with the same list at the same time. */ - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { - list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(peer, &entry->peers, list) { new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC); if (!new_peer) break; @@ -1188,26 +1198,36 @@ static void disconnect_all_peers(void) } } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); + spin_lock(&devices_lock); list_for_each_entry_safe(peer, tmp_peer, &peers, list) { l2cap_chan_close(peer->chan, ENOENT); - kfree(peer); + + list_del_rcu(&peer->list); + call_rcu(&peer->rcu, peer_free); + + module_put(THIS_MODULE); } + spin_unlock(&devices_lock); } -static int lowpan_psm_set(void *data, u64 val) -{ +struct set_psm { + struct work_struct work; u16 psm; +}; - psm = val; - if (psm == 0 || psm_6lowpan != psm) +static void do_psm_set(struct work_struct *work) +{ + struct set_psm *set_psm = container_of(work, struct set_psm, work); + + if (set_psm->psm == 0 || psm_6lowpan != set_psm->psm) /* Disconnect existing connections if 6lowpan is * disabled (psm = 0), or if psm changes. */ disconnect_all_peers(); - psm_6lowpan = psm; + psm_6lowpan = set_psm->psm; if (listen_chan) { l2cap_chan_close(listen_chan, 0); @@ -1216,6 +1236,22 @@ static int lowpan_psm_set(void *data, u64 val) listen_chan = bt_6lowpan_listen(); + kfree(set_psm); +} + +static int lowpan_psm_set(void *data, u64 val) +{ + struct set_psm *set_psm; + + set_psm = kzalloc(sizeof(*set_psm), GFP_KERNEL); + if (!set_psm) + return -ENOMEM; + + set_psm->psm = val; + INIT_WORK(&set_psm->work, do_psm_set); + + schedule_work(&set_psm->work); + return 0; } @@ -1297,19 +1333,18 @@ static ssize_t lowpan_control_write(struct file *fp, static int lowpan_control_show(struct seq_file *f, void *ptr) { - struct lowpan_dev *entry, *tmp_dev; - struct lowpan_peer *peer, *tmp_peer; - unsigned long flags; + struct lowpan_dev *entry; + struct lowpan_peer *peer; - read_lock_irqsave(&devices_lock, flags); + spin_lock(&devices_lock); - list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) { - list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) + list_for_each_entry(entry, &bt_6lowpan_devices, list) { + list_for_each_entry(peer, &entry->peers, list) seq_printf(f, "%pMR (type %u)\n", &peer->chan->dst, peer->chan->dst_type); } - read_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); return 0; } @@ -1329,9 +1364,8 @@ static const struct file_operations lowpan_control_fops = { static void disconnect_devices(void) { - struct lowpan_dev *entry, *tmp, *new_dev; + struct lowpan_dev *entry, *new_dev; struct list_head devices; - unsigned long flags; INIT_LIST_HEAD(&devices); @@ -1340,9 +1374,9 @@ static void disconnect_devices(void) * devices list. */ - read_lock_irqsave(&devices_lock, flags); + rcu_read_lock(); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { + list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC); if (!new_dev) break; @@ -1350,12 +1384,12 @@ static void disconnect_devices(void) new_dev->netdev = entry->netdev; INIT_LIST_HEAD(&new_dev->list); - list_add(&new_dev->list, &devices); + list_add_rcu(&new_dev->list, &devices); } - read_unlock_irqrestore(&devices_lock, flags); + rcu_read_unlock(); - list_for_each_entry_safe(entry, tmp, &devices, list) { + list_for_each_entry(entry, &devices, list) { ifdown(entry->netdev); BT_DBG("Unregistering netdev %s %p", entry->netdev->name, entry->netdev); @@ -1368,17 +1402,15 @@ static int device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *netdev = netdev_notifier_info_to_dev(ptr); - struct lowpan_dev *entry, *tmp; - unsigned long flags; + struct lowpan_dev *entry; if (netdev->type != ARPHRD_6LOWPAN) return NOTIFY_DONE; switch (event) { case NETDEV_UNREGISTER: - write_lock_irqsave(&devices_lock, flags); - list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, - list) { + spin_lock(&devices_lock); + list_for_each_entry(entry, &bt_6lowpan_devices, list) { if (entry->netdev == netdev) { BT_DBG("Unregistered netdev %s %p", netdev->name, netdev); @@ -1387,7 +1419,7 @@ static int device_event(struct notifier_block *unused, break; } } - write_unlock_irqrestore(&devices_lock, flags); + spin_unlock(&devices_lock); break; } -- GitLab From df092306d688438b39f7d433f24e091fa387afaf Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 28 Oct 2014 17:16:48 +0200 Subject: [PATCH 1626/9457] Bluetooth: 6lowpan: Fix lockdep splats When a device ndo_start_xmit() calls again dev_queue_xmit(), lockdep can complain because dev_queue_xmit() is re-entered and the spinlocks protecting tx queues share a common lockdep class. Same issue was fixed for ieee802154 in commit "20e7c4e80dcd" Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index a681247b0aee..7254bddaca2f 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -662,7 +662,26 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) return err < 0 ? NET_XMIT_DROP : err; } +static struct lock_class_key bt_tx_busylock; +static struct lock_class_key bt_netdev_xmit_lock_key; + +static void bt_set_lockdep_class_one(struct net_device *dev, + struct netdev_queue *txq, + void *_unused) +{ + lockdep_set_class(&txq->_xmit_lock, &bt_netdev_xmit_lock_key); +} + +static int bt_dev_init(struct net_device *dev) +{ + netdev_for_each_tx_queue(dev, bt_set_lockdep_class_one, NULL); + dev->qdisc_tx_busylock = &bt_tx_busylock; + + return 0; +} + static const struct net_device_ops netdev_ops = { + .ndo_init = bt_dev_init, .ndo_start_xmit = bt_xmit, }; -- GitLab From 41282920aa35033a4fcf2bc68aeba42a037e6c4d Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 24 Oct 2014 16:48:11 -0700 Subject: [PATCH 1627/9457] ASoC: fsl-asoc-card: Don't bypass settings if cpu-dai is Master When cpu-dai is the DAI Master (CBM_CFx), it may need some configurations, set_sysclk() call for eample, for cpu-dai side in the hw_params(), even if the set_bias_level() has already taken care of the codec-dai side. So this patch just simply adds an additional condition. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl-asoc-card.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 007c772f3cef..14572e62dd51 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -125,7 +125,12 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, priv->sample_rate = params_rate(params); priv->sample_format = params_format(params); - if (priv->card.set_bias_level) + /* + * If codec-dai is DAI Master and all configurations are already in the + * set_bias_level(), bypass the remaining settings in hw_params(). + * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS. + */ + if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) return 0; /* Specific configurations of DAIs starts from here */ -- GitLab From d9b53c3c4ce0657000cad1efbbcd95fdd699a7b6 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 21 Oct 2014 12:42:59 +0530 Subject: [PATCH 1628/9457] gpio: gpio-stp-xway: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Linus Walleij --- drivers/gpio/gpio-stp-xway.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c index 7e359b7cce1b..7892e0fa8ba7 100644 --- a/drivers/gpio/gpio-stp-xway.c +++ b/drivers/gpio/gpio-stp-xway.c @@ -199,21 +199,17 @@ static int xway_stp_hw_init(struct xway_stp *chip) static int xway_stp_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct resource *res; const __be32 *shadow, *groups, *dsl, *phy; struct xway_stp *chip; struct clk *clk; int ret = 0; - if (!res) { - dev_err(&pdev->dev, "failed to request STP resource\n"); - return -ENOENT; - } - chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); chip->virt = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(chip->virt)) return PTR_ERR(chip->virt); -- GitLab From ee2a9f7f06a5bff86cf3468fe74bf504640cf5e6 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 21 Oct 2014 12:43:00 +0530 Subject: [PATCH 1629/9457] gpio: gpio-tb10x: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tb10x.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c index 9e615be8032c..8b1e8c0dd2fb 100644 --- a/drivers/gpio/gpio-tb10x.c +++ b/drivers/gpio/gpio-tb10x.c @@ -195,18 +195,13 @@ static int tb10x_gpio_probe(struct platform_device *pdev) if (of_property_read_u32(dn, "abilis,ngpio", &ngpio)) return -EINVAL; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(&pdev->dev, "No memory resource defined.\n"); - return -EINVAL; - } - tb10x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tb10x_gpio), GFP_KERNEL); if (tb10x_gpio == NULL) return -ENOMEM; spin_lock_init(&tb10x_gpio->spinlock); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); tb10x_gpio->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(tb10x_gpio->base)) return PTR_ERR(tb10x_gpio->base); -- GitLab From f157cf49186e87b6e8cda5a97e1f0f2ff39f57df Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:42 -0300 Subject: [PATCH 1630/9457] [media] coda: clear aborting flag in stop_streaming Clearing the aborting flag in stop_streaming is necessary if we want to start streaming again without having to closing and reopening the device. Also, do not explicitly set it in default_params; the context is zeroed by kzalloc anyway. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index ced47609f5ef..3f8a04fe01a7 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -880,7 +880,6 @@ static void set_default_params(struct coda_ctx *ctx) ctx->params.codec_mode = ctx->codec->mode; ctx->colorspace = V4L2_COLORSPACE_REC709; ctx->params.framerate = 30; - ctx->aborting = 0; /* Default formats for output and input queues */ ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc; @@ -1144,6 +1143,7 @@ static void coda_stop_streaming(struct vb2_queue *q) kfifo_init(&ctx->bitstream_fifo, ctx->bitstream.vaddr, ctx->bitstream.size); ctx->runcounter = 0; + ctx->aborting = 0; } } -- GitLab From aa2c35e5a66194f36578345a23708851935bdff6 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 21 Oct 2014 14:36:59 +0530 Subject: [PATCH 1631/9457] pinctrl-tb10x: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tb10x.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 3b9bfcf717ac..9363563f9777 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -759,7 +759,7 @@ static struct pinctrl_desc tb10x_pindesc = { static int tb10x_pinctrl_probe(struct platform_device *pdev) { int ret = -EINVAL; - struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct resource *mem; struct device *dev = &pdev->dev; struct device_node *of_node = dev->of_node; struct device_node *child; @@ -771,11 +771,6 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev) return -EINVAL; } - if (!mem) { - dev_err(dev, "No memory resource defined.\n"); - return -EINVAL; - } - state = devm_kzalloc(dev, sizeof(struct tb10x_pinctrl) + of_get_child_count(of_node) * sizeof(struct tb10x_of_pinfunc), @@ -787,6 +782,7 @@ static int tb10x_pinctrl_probe(struct platform_device *pdev) state->pinfuncs = (struct tb10x_of_pinfunc *)(state + 1); mutex_init(&state->mutex); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); state->base = devm_ioremap_resource(dev, mem); if (IS_ERR(state->base)) { ret = PTR_ERR(state->base); -- GitLab From 6da999d935a58095e15e752c7ec29d2bdac64adb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:43 -0300 Subject: [PATCH 1632/9457] [media] coda: remove superfluous error message on devm_kzalloc failure When devm_kzalloc causes an OOM condition, this is already reported by the MM subsystem. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 3f8a04fe01a7..538d4acef17e 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1846,11 +1846,8 @@ static int coda_probe(struct platform_device *pdev) int ret, irq; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&pdev->dev, "Not enough memory for %s\n", - CODA_NAME); + if (!dev) return -ENOMEM; - } spin_lock_init(&dev->irqlock); INIT_LIST_HEAD(&dev->instances); -- GitLab From 49c922bb1ec01ac3a98e5881f6c85ea7ef52d53f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Oct 2014 21:12:20 -0700 Subject: [PATCH 1633/9457] Bluetooth: spelling fixes Fix spelling errors in comments. Signed-off-by: Stephen Hemminger Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 6 +++--- net/bluetooth/hci_event.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/l2cap_core.c | 2 +- net/bluetooth/smp.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cb05d7f16a34..ddf33900f7f3 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4477,7 +4477,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete) BT_DBG("length %u", skb_queue_len(&req->cmd_q)); - /* If an error occured during request building, remove all HCI + /* If an error occurred during request building, remove all HCI * commands queued on the HCI request queue. */ if (req->err) { @@ -4546,7 +4546,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, return -ENOMEM; } - /* Stand-alone HCI commands must be flaged as + /* Stand-alone HCI commands must be flagged as * single-command requests. */ bt_cb(skb)->req.start = true; @@ -4566,7 +4566,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); - /* If an error occured during request building, there is no point in + /* If an error occurred during request building, there is no point in * queueing the HCI command. We can simply return. */ if (req->err) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 96291530606d..f5704bae67a2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1045,7 +1045,7 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - /* If we're doing connection initation as peripheral. Set a + /* If we're doing connection initiation as peripheral. Set a * timeout in case something goes wrong. */ if (*sent) { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 115f149362ba..bbc4ac748263 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -987,7 +987,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, skb_queue_tail(&hdev->raw_q, skb); queue_work(hdev->workqueue, &hdev->tx_work); } else { - /* Stand-alone HCI commands must be flaged as + /* Stand-alone HCI commands must be flagged as * single-command requests. */ bt_cb(skb)->req.start = true; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d46c5127f6c3..fc15174c612c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4082,7 +4082,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, chan->num_conf_req++; } - /* Got Conf Rsp PENDING from remote side and asume we sent + /* Got Conf Rsp PENDING from remote side and assume we sent Conf Rsp PENDING in the code above */ if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fea3782989f4..3ebf65b50881 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -964,7 +964,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) if (sec_level > conn->hcon->pending_sec_level) conn->hcon->pending_sec_level = sec_level; - /* If we need MITM check that it can be acheived */ + /* If we need MITM check that it can be achieved */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; @@ -1022,7 +1022,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) auth = rsp->auth_req & AUTH_REQ_MASK; - /* If we need MITM check that it can be acheived */ + /* If we need MITM check that it can be achieved */ if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { u8 method; -- GitLab From 856d7d932641b884a22bf861a1896bdf82778277 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:44 -0300 Subject: [PATCH 1634/9457] [media] coda: add coda_write_base helper Add a helper function that writes a vb2_buffer's Y, Cb, and Cr plane base addresses of into three consecutive registers. This moves common code out of coda-bit.c. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 68 +++++------------------ drivers/media/platform/coda/coda-common.c | 24 ++++++++ drivers/media/platform/coda/coda.h | 2 + 3 files changed, 40 insertions(+), 54 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 9b8ea8bbeb4e..f01393ccf30c 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1036,9 +1036,9 @@ static int coda_prepare_encode(struct coda_ctx *ctx) struct coda_dev *dev = ctx->dev; int force_ipicture; int quant_param = 0; - u32 picture_y, picture_cb, picture_cr; u32 pic_stream_buffer_addr, pic_stream_buffer_size; u32 dst_fourcc; + u32 reg; src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); @@ -1129,37 +1129,17 @@ static int coda_prepare_encode(struct coda_ctx *ctx) coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS); - picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0); - switch (q_data_src->fourcc) { - case V4L2_PIX_FMT_YVU420: - /* Switch Cb and Cr for YVU420 format */ - picture_cr = picture_y + q_data_src->bytesperline * - q_data_src->height; - picture_cb = picture_cr + q_data_src->bytesperline / 2 * - q_data_src->height / 2; - break; - case V4L2_PIX_FMT_YUV420: - default: - picture_cb = picture_y + q_data_src->bytesperline * - q_data_src->height; - picture_cr = picture_cb + q_data_src->bytesperline / 2 * - q_data_src->height / 2; - break; - } - if (dev->devtype->product == CODA_960) { coda_write(dev, 4/*FIXME: 0*/, CODA9_CMD_ENC_PIC_SRC_INDEX); coda_write(dev, q_data_src->width, CODA9_CMD_ENC_PIC_SRC_STRIDE); coda_write(dev, 0, CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC); - coda_write(dev, picture_y, CODA9_CMD_ENC_PIC_SRC_ADDR_Y); - coda_write(dev, picture_cb, CODA9_CMD_ENC_PIC_SRC_ADDR_CB); - coda_write(dev, picture_cr, CODA9_CMD_ENC_PIC_SRC_ADDR_CR); + reg = CODA9_CMD_ENC_PIC_SRC_ADDR_Y; } else { - coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y); - coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB); - coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR); + reg = CODA_CMD_ENC_PIC_SRC_ADDR_Y; } + coda_write_base(ctx, q_data_src, src_buf, reg); + coda_write(dev, force_ipicture << 1 & 0x2, CODA_CMD_ENC_PIC_OPTION); @@ -1501,20 +1481,11 @@ static int coda_prepare_decode(struct coda_ctx *ctx) struct vb2_buffer *dst_buf; struct coda_dev *dev = ctx->dev; struct coda_q_data *q_data_dst; - u32 stridey, height; - u32 picture_y, picture_cb, picture_cr; + u32 reg_addr, reg_stride; dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - if (ctx->params.rot_mode & CODA_ROT_90) { - stridey = q_data_dst->height; - height = q_data_dst->width; - } else { - stridey = q_data_dst->width; - height = q_data_dst->height; - } - /* Try to copy source buffer contents into the bitstream ringbuffer */ mutex_lock(&ctx->bitstream_mutex); coda_fill_bitstream(ctx); @@ -1545,17 +1516,6 @@ static int coda_prepare_decode(struct coda_ctx *ctx) if (dev->devtype->product == CODA_960) coda_set_gdi_regs(ctx); - /* Set rotator output */ - picture_y = vb2_dma_contig_plane_dma_addr(dst_buf, 0); - if (q_data_dst->fourcc == V4L2_PIX_FMT_YVU420) { - /* Switch Cr and Cb for YVU420 format */ - picture_cr = picture_y + stridey * height; - picture_cb = picture_cr + stridey / 2 * height / 2; - } else { - picture_cb = picture_y + stridey * height; - picture_cr = picture_cb + stridey / 2 * height / 2; - } - if (dev->devtype->product == CODA_960) { /* * The CODA960 seems to have an internal list of buffers with @@ -1565,16 +1525,16 @@ static int coda_prepare_decode(struct coda_ctx *ctx) */ coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->v4l2_buf.index, CODA9_CMD_DEC_PIC_ROT_INDEX); - coda_write(dev, picture_y, CODA9_CMD_DEC_PIC_ROT_ADDR_Y); - coda_write(dev, picture_cb, CODA9_CMD_DEC_PIC_ROT_ADDR_CB); - coda_write(dev, picture_cr, CODA9_CMD_DEC_PIC_ROT_ADDR_CR); - coda_write(dev, stridey, CODA9_CMD_DEC_PIC_ROT_STRIDE); + + reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y; + reg_stride = CODA9_CMD_DEC_PIC_ROT_STRIDE; } else { - coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y); - coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB); - coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR); - coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE); + reg_addr = CODA_CMD_DEC_PIC_ROT_ADDR_Y; + reg_stride = CODA_CMD_DEC_PIC_ROT_STRIDE; } + coda_write_base(ctx, q_data_dst, dst_buf, reg_addr); + coda_write(dev, q_data_dst->bytesperline, reg_stride); + coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode, CODA_CMD_DEC_PIC_ROT_MODE); diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 538d4acef17e..fac25170c4c3 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -82,6 +82,30 @@ unsigned int coda_read(struct coda_dev *dev, u32 reg) return data; } +void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data, + struct vb2_buffer *buf, unsigned int reg_y) +{ + u32 base_y = vb2_dma_contig_plane_dma_addr(buf, 0); + u32 base_cb, base_cr; + + switch (q_data->fourcc) { + case V4L2_PIX_FMT_YVU420: + /* Switch Cb and Cr for YVU420 format */ + base_cr = base_y + q_data->bytesperline * q_data->height; + base_cb = base_cr + q_data->bytesperline * q_data->height / 4; + break; + case V4L2_PIX_FMT_YUV420: + default: + base_cb = base_y + q_data->bytesperline * q_data->height; + base_cr = base_cb + q_data->bytesperline * q_data->height / 4; + break; + } + + coda_write(ctx->dev, base_y, reg_y); + coda_write(ctx->dev, base_cb, reg_y + 4); + coda_write(ctx->dev, base_cr, reg_y + 8); +} + /* * Array of all formats supported by any version of Coda: */ diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index bbc18c0dacd9..76ba83c03191 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -232,6 +232,8 @@ extern int coda_debug; void coda_write(struct coda_dev *dev, u32 data, u32 reg); unsigned int coda_read(struct coda_dev *dev, u32 reg); +void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data, + struct vb2_buffer *buf, unsigned int reg_y); int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf, size_t size, const char *name, struct dentry *parent); -- GitLab From 59ebc2e4464dd376df234621a5ad678ac74b9d39 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:45 -0300 Subject: [PATCH 1635/9457] [media] coda: disable rotator if not needed This will still do a 1:1 copy into the internal buffers, but stop producing visual artifacts in chroma interleaved (NV12) mode. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index f01393ccf30c..747b54405bf1 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1037,6 +1037,7 @@ static int coda_prepare_encode(struct coda_ctx *ctx) int force_ipicture; int quant_param = 0; u32 pic_stream_buffer_addr, pic_stream_buffer_size; + u32 rot_mode = 0; u32 dst_fourcc; u32 reg; @@ -1124,8 +1125,9 @@ static int coda_prepare_encode(struct coda_ctx *ctx) } /* submit */ - coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode, - CODA_CMD_ENC_PIC_ROT_MODE); + if (ctx->params.rot_mode) + rot_mode = CODA_ROT_MIR_ENABLE | ctx->params.rot_mode; + coda_write(dev, rot_mode, CODA_CMD_ENC_PIC_ROT_MODE); coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS); -- GitLab From 2bf299cd4651405c8630a9cabd5ac3a87854bdf7 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:46 -0300 Subject: [PATCH 1636/9457] [media] coda: simplify frame memory control register handling Since the firmware newer writes to FRAME_MEM_CTRL, we can initialize it once per context (incidentally, we already do write it in coda_hw_init) and never have to read it back. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 8 ++++---- drivers/media/platform/coda/coda-common.c | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 747b54405bf1..3839e3507628 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -729,10 +729,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) break; } - value = coda_read(dev, CODA_REG_BIT_FRAME_MEM_CTRL); - value &= ~(1 << 2 | 0x7 << 9); - ctx->frame_mem_ctrl = value; - coda_write(dev, value, CODA_REG_BIT_FRAME_MEM_CTRL); + coda_write(dev, ctx->frame_mem_ctrl, CODA_REG_BIT_FRAME_MEM_CTRL); if (dev->devtype->product == CODA_DX6) { /* Configure the coda */ @@ -741,6 +738,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) } /* Could set rotation here if needed */ + value = 0; switch (dev->devtype->product) { case CODA_DX6: value = (q_data_src->width & CODADX6_PICWIDTH_MASK) @@ -1296,6 +1294,8 @@ static int __coda_start_decoding(struct coda_ctx *ctx) /* Update coda bitstream read and write pointers from kfifo */ coda_kfifo_sync_to_device_full(ctx); + coda_write(dev, ctx->frame_mem_ctrl, CODA_REG_BIT_FRAME_MEM_CTRL); + ctx->display_idx = -1; ctx->frm_dis_flg = 0; coda_write(dev, 0, CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index fac25170c4c3..feb270f2860b 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1423,8 +1423,10 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type, ctx->dev = dev; ctx->idx = idx; switch (dev->devtype->product) { - case CODA_7541: case CODA_960: + ctx->frame_mem_ctrl = 1 << 12; + /* fallthrough */ + case CODA_7541: ctx->reg_idx = 0; break; default: -- GitLab From e3a2e87893125bcd99bd7e1ddf9bfc421e492572 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 23 Oct 2014 17:27:07 +0900 Subject: [PATCH 1637/9457] gpio: rename gpio_lock_as_irq to gpiochip_lock_as_irq This function actually operates on a gpio_chip, so its prefix should reflect that fact for consistency with other functions defined in gpio/driver.h. Signed-off-by: Alexandre Courbot Signed-off-by: Linus Walleij --- Documentation/gpio/driver.txt | 4 ++-- drivers/gpio/gpio-bcm-kona.c | 4 ++-- drivers/gpio/gpio-dwapb.c | 4 ++-- drivers/gpio/gpio-em.c | 4 ++-- drivers/gpio/gpio-mcp23s08.c | 4 ++-- drivers/gpio/gpio-omap.c | 2 +- drivers/gpio/gpio-tegra.c | 4 ++-- drivers/gpio/gpio-vr41xx.c | 4 ++-- drivers/gpio/gpiolib-acpi.c | 6 +++--- drivers/gpio/gpiolib-sysfs.c | 4 ++-- drivers/gpio/gpiolib.c | 16 ++++++++-------- drivers/pinctrl/pinctrl-at91.c | 4 ++-- drivers/pinctrl/samsung/pinctrl-exynos.c | 4 ++-- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 +++--- include/linux/gpio.h | 7 ++++--- include/linux/gpio/driver.h | 4 ++-- 16 files changed, 41 insertions(+), 40 deletions(-) diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt index 31e0b5db55d8..90d0f6aba7a6 100644 --- a/Documentation/gpio/driver.txt +++ b/Documentation/gpio/driver.txt @@ -158,12 +158,12 @@ Locking IRQ usage Input GPIOs can be used as IRQ signals. When this happens, a driver is requested to mark the GPIO as being used as an IRQ: - int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) + int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock is released: - void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) + void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) When implementing an irqchip inside a GPIO driver, these two functions should typically be called in the .startup() and .shutdown() callbacks from the diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index de0801e9767a..56fb5ce47aa1 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -470,7 +470,7 @@ static int bcm_kona_gpio_irq_reqres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq)) { + if (gpiochip_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq)) { dev_err(kona_gpio->gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", d->hwirq); @@ -483,7 +483,7 @@ static void bcm_kona_gpio_irq_relres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq); + gpiochip_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq); } static struct irq_chip bcm_gpio_irq_chip = { diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index b43cd84b61f1..4beb37839392 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -194,7 +194,7 @@ static int dwapb_irq_reqres(struct irq_data *d) struct dwapb_gpio *gpio = igc->private; struct bgpio_chip *bgc = &gpio->ports[0].bgc; - if (gpio_lock_as_irq(&bgc->gc, irqd_to_hwirq(d))) { + if (gpiochip_lock_as_irq(&bgc->gc, irqd_to_hwirq(d))) { dev_err(gpio->dev, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); return -EINVAL; @@ -208,7 +208,7 @@ static void dwapb_irq_relres(struct irq_data *d) struct dwapb_gpio *gpio = igc->private; struct bgpio_chip *bgc = &gpio->ports[0].bgc; - gpio_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d)); + gpiochip_unlock_as_irq(&bgc->gc, irqd_to_hwirq(d)); } static int dwapb_irq_set_type(struct irq_data *d, u32 type) diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index fe49ec3cdb7d..21d34d4d473d 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -103,7 +103,7 @@ static int em_gio_irq_reqres(struct irq_data *d) { struct em_gio_priv *p = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d))) { + if (gpiochip_lock_as_irq(&p->gpio_chip, irqd_to_hwirq(d))) { dev_err(p->gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", irqd_to_hwirq(d)); @@ -116,7 +116,7 @@ static void em_gio_irq_relres(struct irq_data *d) { struct em_gio_priv *p = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d)); + gpiochip_unlock_as_irq(&p->gpio_chip, irqd_to_hwirq(d)); } diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 8488e2fd307c..468d10d2ac1e 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -444,7 +444,7 @@ static int mcp23s08_irq_reqres(struct irq_data *data) { struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); - if (gpio_lock_as_irq(&mcp->chip, data->hwirq)) { + if (gpiochip_lock_as_irq(&mcp->chip, data->hwirq)) { dev_err(mcp->chip.dev, "unable to lock HW IRQ %lu for IRQ usage\n", data->hwirq); @@ -458,7 +458,7 @@ static void mcp23s08_irq_relres(struct irq_data *data) { struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); - gpio_unlock_as_irq(&mcp->chip, data->hwirq); + gpiochip_unlock_as_irq(&mcp->chip, data->hwirq); } static struct irq_chip mcp23s08_irq_chip = { diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 415682f69214..a38686786e46 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -800,7 +800,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d) unsigned offset = GPIO_INDEX(bank, gpio); spin_lock_irqsave(&bank->lock, flags); - gpio_unlock_as_irq(&bank->chip, offset); + gpiochip_unlock_as_irq(&bank->chip, offset); bank->irq_usage &= ~(BIT(offset)); omap_disable_gpio_module(bank, offset); omap_reset_gpio(bank, gpio); diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 4e8fb8261a87..61bcfa93606d 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -233,7 +233,7 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - ret = gpio_lock_as_irq(&tegra_gpio_chip, gpio); + ret = gpiochip_lock_as_irq(&tegra_gpio_chip, gpio); if (ret) { dev_err(dev, "unable to lock Tegra GPIO %d as IRQ\n", gpio); return ret; @@ -263,7 +263,7 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d) { int gpio = d->hwirq; - gpio_unlock_as_irq(&tegra_gpio_chip, gpio); + gpiochip_unlock_as_irq(&tegra_gpio_chip, gpio); } static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index dbf28fa03f67..cec55226143d 100644 --- a/drivers/gpio/gpio-vr41xx.c +++ b/drivers/gpio/gpio-vr41xx.c @@ -138,7 +138,7 @@ static void unmask_giuint_low(struct irq_data *d) static unsigned int startup_giuint(struct irq_data *data) { - if (gpio_lock_as_irq(&vr41xx_gpio_chip, data->hwirq)) + if (gpiochip_lock_as_irq(&vr41xx_gpio_chip, data->hwirq)) dev_err(vr41xx_gpio_chip.dev, "unable to lock HW IRQ %lu for IRQ\n", data->hwirq); @@ -150,7 +150,7 @@ static unsigned int startup_giuint(struct irq_data *data) static void shutdown_giuint(struct irq_data *data) { mask_giuint_low(data); - gpio_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq); + gpiochip_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq); } static struct irq_chip giuint_low_irq_chip = { diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 05c6275da224..349a7552dd23 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -153,7 +153,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, gpiod_direction_input(desc); - ret = gpio_lock_as_irq(chip, pin); + ret = gpiochip_lock_as_irq(chip, pin); if (ret) { dev_err(chip->dev, "Failed to lock GPIO as interrupt\n"); goto fail_free_desc; @@ -209,7 +209,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares, fail_free_event: kfree(event); fail_unlock_irq: - gpio_unlock_as_irq(chip, pin); + gpiochip_unlock_as_irq(chip, pin); fail_free_desc: gpiochip_free_own_desc(desc); @@ -280,7 +280,7 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) desc = event->desc; if (WARN_ON(IS_ERR(desc))) continue; - gpio_unlock_as_irq(chip, event->pin); + gpiochip_unlock_as_irq(chip, event->pin); gpiochip_free_own_desc(desc); list_del(&event->node); kfree(event); diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 5f2150b619a7..781fbed00fc3 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -161,7 +161,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, desc->flags &= ~GPIO_TRIGGER_MASK; if (!gpio_flags) { - gpio_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); + gpiochip_unlock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); ret = 0; goto free_id; } @@ -200,7 +200,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, if (ret < 0) goto free_id; - ret = gpio_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); + ret = gpiochip_lock_as_irq(desc->chip, gpio_chip_hwgpio(desc)); if (ret < 0) { gpiod_warn(desc, "failed to flag the GPIO for IRQ\n"); goto free_id; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8e98ca25ec7..50e18a4b3a9f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -495,7 +495,7 @@ static int gpiochip_irq_reqres(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - if (gpio_lock_as_irq(chip, d->hwirq)) { + if (gpiochip_lock_as_irq(chip, d->hwirq)) { chip_err(chip, "unable to lock HW IRQ %lu for IRQ\n", d->hwirq); @@ -508,7 +508,7 @@ static void gpiochip_irq_relres(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(chip, d->hwirq); + gpiochip_unlock_as_irq(chip, d->hwirq); } static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) @@ -1332,14 +1332,14 @@ int gpiod_to_irq(const struct gpio_desc *desc) EXPORT_SYMBOL_GPL(gpiod_to_irq); /** - * gpio_lock_as_irq() - lock a GPIO to be used as IRQ + * gpiochip_lock_as_irq() - lock a GPIO to be used as IRQ * @chip: the chip the GPIO to lock belongs to * @offset: the offset of the GPIO to lock as IRQ * * This is used directly by GPIO drivers that want to lock down * a certain GPIO line to be used for IRQs. */ -int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) +int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) return -EINVAL; @@ -1354,24 +1354,24 @@ int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) set_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); return 0; } -EXPORT_SYMBOL_GPL(gpio_lock_as_irq); +EXPORT_SYMBOL_GPL(gpiochip_lock_as_irq); /** - * gpio_unlock_as_irq() - unlock a GPIO used as IRQ + * gpiochip_unlock_as_irq() - unlock a GPIO used as IRQ * @chip: the chip the GPIO to lock belongs to * @offset: the offset of the GPIO to lock as IRQ * * This is used directly by GPIO drivers that want to indicate * that a certain GPIO is no longer used exclusively for IRQ. */ -void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) +void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) return; clear_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); } -EXPORT_SYMBOL_GPL(gpio_unlock_as_irq); +EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); /** * gpiod_get_raw_value_cansleep() - return a gpio's raw value diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 354a81d40925..608671704522 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1472,7 +1472,7 @@ static unsigned int gpio_irq_startup(struct irq_data *d) unsigned pin = d->hwirq; int ret; - ret = gpio_lock_as_irq(&at91_gpio->chip, pin); + ret = gpiochip_lock_as_irq(&at91_gpio->chip, pin); if (ret) { dev_err(at91_gpio->chip.dev, "unable to lock pind %lu IRQ\n", d->hwirq); @@ -1488,7 +1488,7 @@ static void gpio_irq_shutdown(struct irq_data *d) unsigned pin = d->hwirq; gpio_irq_mask(d); - gpio_unlock_as_irq(&at91_gpio->chip, pin); + gpiochip_unlock_as_irq(&at91_gpio->chip, pin); } #ifdef CONFIG_PM diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d7154ed0b0eb..fa54a2d1c966 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -180,7 +180,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd) unsigned int con; int ret; - ret = gpio_lock_as_irq(&bank->gpio_chip, irqd->hwirq); + ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq); if (ret) { dev_err(bank->gpio_chip.dev, "unable to lock pin %s-%lu IRQ\n", bank->name, irqd->hwirq); @@ -233,7 +233,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd) spin_unlock_irqrestore(&bank->slock, flags); - gpio_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); + gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); } /* diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index ef9d804e55de..3d0744337736 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -553,7 +553,7 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) if (!func) return -EINVAL; - ret = gpio_lock_as_irq(pctl->chip, + ret = gpiochip_lock_as_irq(pctl->chip, pctl->irq_array[d->hwirq] - pctl->desc->pin_base); if (ret) { dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n", @@ -571,8 +571,8 @@ static void sunxi_pinctrl_irq_release_resources(struct irq_data *d) { struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); - gpio_unlock_as_irq(pctl->chip, - pctl->irq_array[d->hwirq] - pctl->desc->pin_base); + gpiochip_unlock_as_irq(pctl->chip, + pctl->irq_array[d->hwirq] - pctl->desc->pin_base); } static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 85aa5d0b9357..ab81339a8590 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -216,14 +216,15 @@ static inline int gpio_to_irq(unsigned gpio) return -EINVAL; } -static inline int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset) +static inline int gpiochip_lock_as_irq(struct gpio_chip *chip, + unsigned int offset) { WARN_ON(1); return -EINVAL; } -static inline void gpio_unlock_as_irq(struct gpio_chip *chip, - unsigned int offset) +static inline void gpiochip_unlock_as_irq(struct gpio_chip *chip, + unsigned int offset) { WARN_ON(1); } diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 249db3057e4d..ff200a75501e 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -149,8 +149,8 @@ extern struct gpio_chip *gpiochip_find(void *data, int (*match)(struct gpio_chip *chip, void *data)); /* lock/unlock as IRQ */ -int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset); -void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); +int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset); +void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc); -- GitLab From 1cb12cf3c0d4b594b027e920ce9599a5e6448748 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 29 Sep 2014 09:53:47 -0300 Subject: [PATCH 1638/9457] [media] coda: add support for partial interleaved YCbCr 4:2:0 (NV12) format This patch adds support for the two-plane NV12 format with one luma plane and one interleaved chroma plane. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 26 ++++++++++++++++++----- drivers/media/platform/coda/coda-common.c | 8 +++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 3839e3507628..fde777573f7b 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -729,6 +729,9 @@ static int coda_start_encoding(struct coda_ctx *ctx) break; } + ctx->frame_mem_ctrl &= ~CODA_FRAME_CHROMA_INTERLEAVE; + if (q_data_src->fourcc == V4L2_PIX_FMT_NV12) + ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE; coda_write(dev, ctx->frame_mem_ctrl, CODA_REG_BIT_FRAME_MEM_CTRL); if (dev->devtype->product == CODA_DX6) { @@ -1128,7 +1131,6 @@ static int coda_prepare_encode(struct coda_ctx *ctx) coda_write(dev, rot_mode, CODA_CMD_ENC_PIC_ROT_MODE); coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS); - if (dev->devtype->product == CODA_960) { coda_write(dev, 4/*FIXME: 0*/, CODA9_CMD_ENC_PIC_SRC_INDEX); coda_write(dev, q_data_src->width, CODA9_CMD_ENC_PIC_SRC_STRIDE); @@ -1273,7 +1275,7 @@ static int __coda_start_decoding(struct coda_ctx *ctx) u32 bitstream_buf, bitstream_size; struct coda_dev *dev = ctx->dev; int width, height; - u32 src_fourcc; + u32 src_fourcc, dst_fourcc; u32 val; int ret; @@ -1283,6 +1285,7 @@ static int __coda_start_decoding(struct coda_ctx *ctx) bitstream_buf = ctx->bitstream.paddr; bitstream_size = ctx->bitstream.size; src_fourcc = q_data_src->fourcc; + dst_fourcc = q_data_dst->fourcc; /* Allocate per-instance buffers */ ret = coda_alloc_context_buffers(ctx, q_data_src); @@ -1294,6 +1297,9 @@ static int __coda_start_decoding(struct coda_ctx *ctx) /* Update coda bitstream read and write pointers from kfifo */ coda_kfifo_sync_to_device_full(ctx); + ctx->frame_mem_ctrl &= ~CODA_FRAME_CHROMA_INTERLEAVE; + if (dst_fourcc == V4L2_PIX_FMT_NV12) + ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE; coda_write(dev, ctx->frame_mem_ctrl, CODA_REG_BIT_FRAME_MEM_CTRL); ctx->display_idx = -1; @@ -1424,13 +1430,23 @@ static int __coda_start_decoding(struct coda_ctx *ctx) } if (dev->devtype->product == CODA_960) { - coda_write(dev, -1, CODA9_CMD_SET_FRAME_DELAY); + int cbb_size, crb_size; + coda_write(dev, -1, CODA9_CMD_SET_FRAME_DELAY); + /* Luma 2x0 page, 2x6 cache, chroma 2x0 page, 2x4 cache size */ coda_write(dev, 0x20262024, CODA9_CMD_SET_FRAME_CACHE_SIZE); + + if (dst_fourcc == V4L2_PIX_FMT_NV12) { + cbb_size = 0; + crb_size = 16; + } else { + cbb_size = 8; + crb_size = 8; + } coda_write(dev, 2 << CODA9_CACHE_PAGEMERGE_OFFSET | 32 << CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET | - 8 << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET | - 8 << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET, + cbb_size << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET | + crb_size << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET, CODA9_CMD_SET_FRAME_CACHE_CONFIG); } diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index feb270f2860b..02d47fabae65 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -95,6 +95,7 @@ void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data, base_cb = base_cr + q_data->bytesperline * q_data->height / 4; break; case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_NV12: default: base_cb = base_y + q_data->bytesperline * q_data->height; base_cr = base_cb + q_data->bytesperline * q_data->height / 4; @@ -118,6 +119,10 @@ static const struct coda_fmt coda_formats[] = { .name = "YUV 4:2:0 Planar, YCrCb", .fourcc = V4L2_PIX_FMT_YVU420, }, + { + .name = "YUV 4:2:0 Partial interleaved Y/CbCr", + .fourcc = V4L2_PIX_FMT_NV12, + }, { .name = "H264 Encoded Stream", .fourcc = V4L2_PIX_FMT_H264, @@ -162,6 +167,7 @@ static bool coda_format_is_yuv(u32 fourcc) switch (fourcc) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: return true; default: return false; @@ -366,6 +372,7 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, switch (f->fmt.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_MPEG4: case V4L2_PIX_FMT_JPEG: @@ -380,6 +387,7 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, switch (f->fmt.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: /* Frame stride must be multiple of 8, but 16 for h.264 */ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * -- GitLab From 1b5721b24306c2daf786f3b31f678b40ab9b2ce7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 27 Oct 2014 18:04:52 -0700 Subject: [PATCH 1639/9457] ASoC: simple-card: add asoc_simple_card_parse_daifmt() Current daifmt setting method in simple-card driver is placed to many places, and using un-readable/confusable method. This patch adds new asoc_simple_card_parse_daifmt() and tidyup code. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 134 ++++++++++++++++---------------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 4f192ee3cb16..cac95d79fc8f 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -226,6 +226,53 @@ asoc_simple_card_sub_parse_of(struct device_node *np, return 0; } +static int asoc_simple_card_parse_daifmt(struct device_node *node, + struct simple_card_data *priv, + struct device_node *cpu, + struct device_node *codec, + char *prefix, int idx) +{ + struct device *dev = simple_priv_to_dev(priv); + struct device_node *bitclkmaster = NULL; + struct device_node *framemaster = NULL; + struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); + struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; + struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; + unsigned int daifmt; + + daifmt = snd_soc_of_parse_daifmt(node, prefix, + &bitclkmaster, &framemaster); + daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; + + if (strlen(prefix) && !bitclkmaster && !framemaster) { + /* + * No dai-link level and master setting was not found from + * sound node level, revert back to legacy DT parsing and + * take the settings from codec node. + */ + dev_dbg(dev, "Revert to legacy daifmt parsing\n"); + + cpu_dai->fmt = codec_dai->fmt = + snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) | + (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); + } else { + if (codec == bitclkmaster) + daifmt |= (codec == framemaster) ? + SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS; + else + daifmt |= (codec == framemaster) ? + SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; + + cpu_dai->fmt = daifmt; + codec_dai->fmt = daifmt; + } + + of_node_put(bitclkmaster); + of_node_put(framemaster); + + return 0; +} + static int asoc_simple_card_dai_link_of(struct device_node *node, struct simple_card_data *priv, int idx, @@ -234,10 +281,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, struct device *dev = simple_priv_to_dev(priv); struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); - struct device_node *np = NULL; - struct device_node *bitclkmaster = NULL; - struct device_node *framemaster = NULL; - unsigned int daifmt; + struct device_node *cpu = NULL; + struct device_node *codec = NULL; char *name; char prop[128]; char *prefix = ""; @@ -247,85 +292,36 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, if (is_top_level_node) prefix = "simple-audio-card,"; - daifmt = snd_soc_of_parse_daifmt(node, prefix, - &bitclkmaster, &framemaster); - daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; - snprintf(prop, sizeof(prop), "%scpu", prefix); - np = of_get_child_by_name(node, prop); - if (!np) { + cpu = of_get_child_by_name(node, prop); + + snprintf(prop, sizeof(prop), "%scodec", prefix); + codec = of_get_child_by_name(node, prop); + + if (!cpu || !codec) { ret = -EINVAL; dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); goto dai_link_of_err; } - ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai, + ret = asoc_simple_card_parse_daifmt(node, priv, + cpu, codec, prefix, idx); + if (ret < 0) + goto dai_link_of_err; + + ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, &dai_link->cpu_of_node, &dai_link->cpu_dai_name, &cpu_args); if (ret < 0) goto dai_link_of_err; - dai_props->cpu_dai.fmt = daifmt; - switch (((np == bitclkmaster) << 4) | (np == framemaster)) { - case 0x11: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; - break; - case 0x10: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; - break; - case 0x01: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; - break; - default: - dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; - break; - } - - of_node_put(np); - snprintf(prop, sizeof(prop), "%scodec", prefix); - np = of_get_child_by_name(node, prop); - if (!np) { - ret = -EINVAL; - dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); - goto dai_link_of_err; - } - - ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai, + ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai, &dai_link->codec_of_node, &dai_link->codec_dai_name, NULL); if (ret < 0) goto dai_link_of_err; - if (strlen(prefix) && !bitclkmaster && !framemaster) { - /* - * No DAI link level and master setting was found - * from sound node level, revert back to legacy DT - * parsing and take the settings from codec node. - */ - dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n", - __func__); - dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt = - snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) | - (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); - } else { - dai_props->codec_dai.fmt = daifmt; - switch (((np == bitclkmaster) << 4) | (np == framemaster)) { - case 0x11: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; - break; - case 0x10: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; - break; - case 0x01: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; - break; - default: - dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; - break; - } - } - if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { ret = -EINVAL; goto dai_link_of_err; @@ -368,9 +364,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, dai_link->cpu_dai_name = NULL; dai_link_of_err: - of_node_put(np); - of_node_put(bitclkmaster); - of_node_put(framemaster); + of_node_put(cpu); + of_node_put(codec); + return ret; } -- GitLab From 859b2e374a86482004d1b8b94c1666269e1d7fd6 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 28 Oct 2014 21:25:13 +0530 Subject: [PATCH 1640/9457] ALSA: compress: fix documentation errors Some structure documentation was not right so fix it now Reported-by: kbuild test robot Signed-off-by: Vinod Koul Signed-off-by: Takashi Iwai --- include/sound/compress_driver.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index ae6c3b8ed2f5..396e8f73670a 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -42,12 +42,11 @@ struct snd_compr_ops; * @buffer_size: size of the above buffer * @fragment_size: size of buffer fragment in bytes * @fragments: number of such fragments - * @hw_pointer: offset of last location in buffer where DSP copied data - * @app_pointer: offset of last location in buffer where app wrote data * @total_bytes_available: cumulative number of bytes made available in * the ring buffer * @total_bytes_transferred: cumulative bytes transferred by offload DSP * @sleep: poll sleep + * @private_data: driver private data pointer */ struct snd_compr_runtime { snd_pcm_state_t state; @@ -94,6 +93,8 @@ struct snd_compr_stream { * This can be called in during stream creation only to set codec params * and the stream properties * @get_params: retrieve the codec parameters, mandatory + * @set_metadata: Set the metadata values for a stream + * @get_metadata: retreives the requested metadata values from stream * @trigger: Trigger operations like start, pause, resume, drain, stop. * This callback is mandatory * @pointer: Retrieve current h/w pointer information. Mandatory -- GitLab From 2e6705c09065ecb357140e44d12dc32274b1a723 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2014 17:16:51 +0100 Subject: [PATCH 1641/9457] ALSA: ctxfi: Kill the rest snd_print*() Use the standard dev_*() instead. Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctatc.c | 6 ++++-- sound/pci/ctxfi/cttimer.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 632e843fa95e..977a59855fa6 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -438,7 +438,9 @@ atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) position = src->ops->get_ca(src); if (position < apcm->vm_block->addr) { - snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size); + dev_dbg(atc->card->dev, + "bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", + position, apcm->vm_block->addr, apcm->vm_block->size); position = apcm->vm_block->addr; } @@ -1295,7 +1297,7 @@ static int atc_identify_card(struct ct_atc *atc, unsigned int ssid) atc->model = CT20K2_UNKNOWN; } atc->model_name = ct_subsys_name[atc->model]; - snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", + dev_info(atc->card->dev, "chip %s model %s (%04x:%04x) is found\n", atc->chip_name, atc->model_name, vendor_id, device_id); return 0; diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index 03fb909085af..a5d460453d7b 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c @@ -421,12 +421,12 @@ struct ct_timer *ct_timer_new(struct ct_atc *atc) atimer->atc = atc; hw = atc->hw; if (!use_system_timer && hw->set_timer_irq) { - snd_printd(KERN_INFO "ctxfi: Use xfi-native timer\n"); + dev_info(atc->card->dev, "Use xfi-native timer\n"); atimer->ops = &ct_xfitimer_ops; hw->irq_callback_data = atimer; hw->irq_callback = ct_timer_interrupt; } else { - snd_printd(KERN_INFO "ctxfi: Use system timer\n"); + dev_info(atc->card->dev, "Use system timer\n"); atimer->ops = &ct_systimer_ops; } return atimer; -- GitLab From f48a6df28239f5bf35d80e43e580261d2298395a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2014 17:22:45 +0100 Subject: [PATCH 1642/9457] ALSA: pcxhr: Kill the rest snd_print*() Use the standard dev_*() instead. Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 7c33c973dbd5..a60293015267 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -501,10 +501,10 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, /* * start or stop playback/capture substream */ -static int pcxhr_set_stream_state(struct pcxhr_stream *stream) +static int pcxhr_set_stream_state(struct snd_pcxhr *chip, + struct pcxhr_stream *stream) { int err; - struct snd_pcxhr *chip; struct pcxhr_rmh rmh; int stream_mask, start; @@ -512,8 +512,8 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream) start = 1; else { if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { - snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state " - "CANNOT be stopped\n"); + dev_err(chip->card->dev, + "pcxhr_set_stream_state CANNOT be stopped\n"); return -EINVAL; } start = 0; @@ -560,6 +560,7 @@ static int pcxhr_set_format(struct pcxhr_stream *stream) struct pcxhr_rmh rmh; unsigned int header; + chip = snd_pcm_substream_chip(stream->substream); switch (stream->format) { case SNDRV_PCM_FORMAT_U8: header = HEADER_FMT_BASE_LIN; @@ -582,11 +583,10 @@ static int pcxhr_set_format(struct pcxhr_stream *stream) header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; break; default: - snd_printk(KERN_ERR - "error pcxhr_set_format() : unknown format\n"); + dev_err(chip->card->dev, + "error pcxhr_set_format() : unknown format\n"); return -EINVAL; } - chip = snd_pcm_substream_chip(stream->substream); sample_rate = chip->mgr->sample_rate; if (sample_rate <= 32000 && sample_rate !=0) { @@ -643,11 +643,11 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream) is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); stream_num = is_capture ? 0 : subs->number; - snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : " - "addr(%p) bytes(%zx) subs(%d)\n", - is_capture ? 'c' : 'p', - chip->chip_idx, (void *)(long)subs->runtime->dma_addr, - subs->runtime->dma_bytes, subs->number); + dev_dbg(chip->card->dev, + "pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", + is_capture ? 'c' : 'p', + chip->chip_idx, (void *)(long)subs->runtime->dma_addr, + subs->runtime->dma_bytes, subs->number); pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, @@ -687,7 +687,7 @@ static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, *sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24; *sample_count += (snd_pcm_uframes_t)rmh.stat[1]; } - snd_printdd("PIPE_SAMPLE_COUNT = %lx\n", *sample_count); + dev_dbg(chip->card->dev, "PIPE_SAMPLE_COUNT = %lx\n", *sample_count); return err; } #endif @@ -779,12 +779,12 @@ static void pcxhr_start_linked_stream(struct pcxhr_mgr *mgr) for (j = 0; j < chip->nb_streams_capt; j++) { stream = &chip->capture_stream[j]; if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) - err = pcxhr_set_stream_state(stream); + err = pcxhr_set_stream_state(chip, stream); } for (j = 0; j < chip->nb_streams_play; j++) { stream = &chip->playback_stream[j]; if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) - err = pcxhr_set_stream_state(stream); + err = pcxhr_set_stream_state(chip, stream); } } @@ -839,12 +839,12 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) { struct pcxhr_stream *stream; struct snd_pcm_substream *s; + struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); switch (cmd) { case SNDRV_PCM_TRIGGER_START: - snd_printdd("SNDRV_PCM_TRIGGER_START\n"); + dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_START\n"); if (snd_pcm_stream_linked(subs)) { - struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); snd_pcm_group_for_each_entry(s, subs) { if (snd_pcm_substream_chip(s) != chip) continue; @@ -856,7 +856,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) pcxhr_start_linked_stream(chip->mgr); } else { stream = subs->runtime->private_data; - snd_printdd("Only one Substream %c %d\n", + dev_dbg(chip->card->dev, "Only one Substream %c %d\n", stream->pipe->is_capture ? 'C' : 'P', stream->pipe->first_audio); if (pcxhr_set_format(stream)) @@ -865,17 +865,17 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; - if (pcxhr_set_stream_state(stream)) + if (pcxhr_set_stream_state(chip, stream)) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_RUNNING; } break; case SNDRV_PCM_TRIGGER_STOP: - snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); + dev_dbg(chip->card->dev, "SNDRV_PCM_TRIGGER_STOP\n"); snd_pcm_group_for_each_entry(s, subs) { stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; - if (pcxhr_set_stream_state(stream)) + if (pcxhr_set_stream_state(chip, stream)) return -EINVAL; snd_pcm_trigger_done(s, subs); } -- GitLab From f994cb3a09a5f2018c286f854c10277132f4a9a5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2014 17:36:50 +0100 Subject: [PATCH 1643/9457] ALSA: au88x0: Kill the rest snd_print*() Use the standard dev_*() instead. Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index e9c3833f6d44..996369134ea8 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -314,7 +314,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, sizeof(snd_vortex_synth_arg_t), &wave) < 0 || wave == NULL) { - snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n"); + dev_err(card->dev, "Can't initialize Aureal wavetable synth\n"); } else { snd_vortex_synth_arg_t *arg; -- GitLab From 4de69319f013f8ebf6ec5b949497870353eb799a Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:26 -0300 Subject: [PATCH 1644/9457] [media] coda: add support for planar YCbCr 4:2:2 (YUV422P) format This patch adds support for the three-plane YUV422P format with one luma plane and two horizontally subsampled chroma planes. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 14 +++++++++++++- drivers/media/platform/coda/coda-common.c | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index fde777573f7b..746a6158ccd0 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1591,6 +1591,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) struct coda_q_data *q_data_dst; struct vb2_buffer *dst_buf; struct coda_timestamp *ts; + unsigned long payload; int width, height; int decoded_idx; int display_idx; @@ -1776,7 +1777,18 @@ static void coda_finish_decode(struct coda_ctx *ctx) dst_buf->v4l2_buf.timecode = ts->timecode; dst_buf->v4l2_buf.timestamp = ts->timestamp; - vb2_set_plane_payload(dst_buf, 0, width * height * 3 / 2); + switch (q_data_dst->fourcc) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: + default: + payload = width * height * 3 / 2; + break; + case V4L2_PIX_FMT_YUV422P: + payload = width * height * 2; + break; + } + vb2_set_plane_payload(dst_buf, 0, payload); v4l2_m2m_buf_done(dst_buf, ctx->frame_errors[display_idx] ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 02d47fabae65..48be97330ee1 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -100,6 +100,9 @@ void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data, base_cb = base_y + q_data->bytesperline * q_data->height; base_cr = base_cb + q_data->bytesperline * q_data->height / 4; break; + case V4L2_PIX_FMT_YUV422P: + base_cb = base_y + q_data->bytesperline * q_data->height; + base_cr = base_cb + q_data->bytesperline * q_data->height / 2; } coda_write(ctx->dev, base_y, reg_y); @@ -123,6 +126,10 @@ static const struct coda_fmt coda_formats[] = { .name = "YUV 4:2:0 Partial interleaved Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12, }, + { + .name = "YUV 4:2:2 Planar, YCbCr", + .fourcc = V4L2_PIX_FMT_YUV422P, + }, { .name = "H264 Encoded Stream", .fourcc = V4L2_PIX_FMT_H264, @@ -168,6 +175,7 @@ static bool coda_format_is_yuv(u32 fourcc) case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_YUV422P: return true; default: return false; @@ -393,6 +401,11 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height * 3 / 2; break; + case V4L2_PIX_FMT_YUV422P: + f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); + f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * + f->fmt.pix.height * 2; + break; case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_MPEG4: case V4L2_PIX_FMT_JPEG: -- GitLab From b2f91ae30edfa95500183179082f0568e3e9b38e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:27 -0300 Subject: [PATCH 1645/9457] [media] coda: identify platform device earlier We'll use this information to decide whether to request the JPEG IRQ later. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 48be97330ee1..fb83c56afd26 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1896,6 +1896,15 @@ static int coda_probe(struct platform_device *pdev) if (!dev) return -ENOMEM; + pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); + + if (of_id) + dev->devtype = of_id->data; + else if (pdev_id) + dev->devtype = &coda_devdata[pdev_id->driver_data]; + else + return -EINVAL; + spin_lock_init(&dev->irqlock); INIT_LIST_HEAD(&dev->instances); @@ -1963,17 +1972,6 @@ static int coda_probe(struct platform_device *pdev) mutex_init(&dev->dev_mutex); mutex_init(&dev->coda_mutex); - pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); - - if (of_id) { - dev->devtype = of_id->data; - } else if (pdev_id) { - dev->devtype = &coda_devdata[pdev_id->driver_data]; - } else { - v4l2_device_unregister(&dev->v4l2_dev); - return -EINVAL; - } - dev->debugfs_root = debugfs_create_dir("coda", NULL); if (!dev->debugfs_root) dev_warn(&pdev->dev, "failed to create debugfs root\n"); -- GitLab From 2c11d1bdfc7175cc75a603e433367caaf038ab69 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:28 -0300 Subject: [PATCH 1646/9457] [media] coda: add coda_video_device descriptors Each video device descriptor determines the name, callback ops, and input and output formats on the corresponding video device. This simplifies coda_enum_fmt and coda_try_fmt a bit and will simplify adding separate video devices for JPEG codecs due to the slightly different behavior in the CodaDx6/CODA7542 case and a separate hardware unit on CODA960. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 350 ++++++++++++---------- drivers/media/platform/coda/coda.h | 7 +- 2 files changed, 204 insertions(+), 153 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index fb83c56afd26..45db1da2dbcf 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -43,6 +43,7 @@ #define CODA_NAME "coda" #define CODADX6_MAX_INSTANCES 4 +#define CODA_MAX_FORMATS 4 #define CODA_PARA_BUF_SIZE (10 * 1024) #define CODA_ISRAM_SIZE (2048 * 2) @@ -169,6 +170,58 @@ static const struct coda_codec coda9_codecs[] = { CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1088), }; +struct coda_video_device { + const char *name; + enum coda_inst_type type; + const struct coda_context_ops *ops; + u32 src_formats[CODA_MAX_FORMATS]; + u32 dst_formats[CODA_MAX_FORMATS]; +}; + +static const struct coda_video_device coda_bit_encoder = { + .name = "coda-encoder", + .type = CODA_INST_ENCODER, + .ops = &coda_bit_encode_ops, + .src_formats = { + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YVU420, + V4L2_PIX_FMT_NV12, + }, + .dst_formats = { + V4L2_PIX_FMT_H264, + V4L2_PIX_FMT_MPEG4, + }, +}; + +static const struct coda_video_device coda_bit_decoder = { + .name = "coda-decoder", + .type = CODA_INST_DECODER, + .ops = &coda_bit_decode_ops, + .src_formats = { + V4L2_PIX_FMT_H264, + V4L2_PIX_FMT_MPEG4, + }, + .dst_formats = { + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YVU420, + V4L2_PIX_FMT_NV12, + }, +}; + +static const struct coda_video_device *codadx6_video_devices[] = { + &coda_bit_encoder, +}; + +static const struct coda_video_device *coda7_video_devices[] = { + &coda_bit_encoder, + &coda_bit_decoder, +}; + +static const struct coda_video_device *coda9_video_devices[] = { + &coda_bit_encoder, + &coda_bit_decoder, +}; + static bool coda_format_is_yuv(u32 fourcc) { switch (fourcc) { @@ -182,6 +235,18 @@ static bool coda_format_is_yuv(u32 fourcc) } } +static const char *coda_format_name(u32 fourcc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coda_formats); i++) { + if (coda_formats[i].fourcc == fourcc) + return coda_formats[i].name; + } + + return NULL; +} + /* * Normalize all supported YUV 4:2:0 formats to the value used in the codec * tables. @@ -240,6 +305,17 @@ static void coda_get_max_dimensions(struct coda_dev *dev, *max_h = h; } +const struct coda_video_device *to_coda_video_device(struct video_device *vdev) +{ + struct coda_dev *dev = video_get_drvdata(vdev); + unsigned int i = vdev - dev->vfd; + + if (i >= dev->devtype->num_vdevs) + return NULL; + + return dev->devtype->vdevs[i]; +} + const char *coda_product_name(int product) { static char buf[9]; @@ -278,58 +354,28 @@ static int coda_querycap(struct file *file, void *priv, static int coda_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct coda_ctx *ctx = fh_to_ctx(priv); - const struct coda_codec *codecs = ctx->dev->devtype->codecs; - const struct coda_fmt *formats = coda_formats; - const struct coda_fmt *fmt; - int num_codecs = ctx->dev->devtype->num_codecs; - int num_formats = ARRAY_SIZE(coda_formats); - int i, k, num = 0; - bool yuv; - - if (ctx->inst_type == CODA_INST_ENCODER) - yuv = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); + struct video_device *vdev = video_devdata(file); + const struct coda_video_device *cvd = to_coda_video_device(vdev); + const u32 *formats; + const char *name; + + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + formats = cvd->src_formats; + else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + formats = cvd->dst_formats; else - yuv = (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE); - - for (i = 0; i < num_formats; i++) { - /* Skip either raw or compressed formats */ - if (yuv != coda_format_is_yuv(formats[i].fourcc)) - continue; - /* All uncompressed formats are always supported */ - if (yuv) { - if (num == f->index) - break; - ++num; - continue; - } - /* Compressed formats may be supported, check the codec list */ - for (k = 0; k < num_codecs; k++) { - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - formats[i].fourcc == codecs[k].dst_fourcc) - break; - if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - formats[i].fourcc == codecs[k].src_fourcc) - break; - } - if (k < num_codecs) { - if (num == f->index) - break; - ++num; - } - } + return -EINVAL; - if (i < num_formats) { - fmt = &formats[i]; - strlcpy(f->description, fmt->name, sizeof(f->description)); - f->pixelformat = fmt->fourcc; - if (!yuv) - f->flags |= V4L2_FMT_FLAG_COMPRESSED; - return 0; - } + if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0) + return -EINVAL; + + name = coda_format_name(formats[f->index]); + strlcpy(f->description, name, sizeof(f->description)); + f->pixelformat = formats[f->index]; + if (!coda_format_is_yuv(formats[f->index])) + f->flags |= V4L2_FMT_FLAG_COMPRESSED; - /* Format not found */ - return -EINVAL; + return 0; } static int coda_g_fmt(struct file *file, void *priv, @@ -354,11 +400,37 @@ static int coda_g_fmt(struct file *file, void *priv, return 0; } +static int coda_try_pixelformat(struct coda_ctx *ctx, struct v4l2_format *f) +{ + struct coda_q_data *q_data; + const u32 *formats; + int i; + + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + formats = ctx->cvd->src_formats; + else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + formats = ctx->cvd->dst_formats; + else + return -EINVAL; + + for (i = 0; i < CODA_MAX_FORMATS; i++) { + if (formats[i] == f->fmt.pix.pixelformat) { + f->fmt.pix.pixelformat = formats[i]; + return 0; + } + } + + /* Fall back to currently set pixelformat */ + q_data = get_q_data(ctx, f->type); + f->fmt.pix.pixelformat = q_data->fourcc; + + return 0; +} + static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, struct v4l2_format *f) { struct coda_dev *dev = ctx->dev; - struct coda_q_data *q_data; unsigned int max_w, max_h; enum v4l2_field field; @@ -377,21 +449,6 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, &f->fmt.pix.height, MIN_H, max_h, H_ALIGN, S_ALIGN); - switch (f->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_H264: - case V4L2_PIX_FMT_MPEG4: - case V4L2_PIX_FMT_JPEG: - break; - default: - q_data = get_q_data(ctx, f->type); - if (!q_data) - return -EINVAL; - f->fmt.pix.pixelformat = q_data->fourcc; - } - switch (f->fmt.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: @@ -423,34 +480,35 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct coda_ctx *ctx = fh_to_ctx(priv); - const struct coda_codec *codec = NULL; + const struct coda_q_data *q_data_src; + const struct coda_codec *codec; struct vb2_queue *src_vq; int ret; + ret = coda_try_pixelformat(ctx, f); + if (ret < 0) + return ret; + + q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + /* - * If the source format is already fixed, try to find a codec that - * converts to the given destination format + * If the source format is already fixed, only allow the same output + * resolution */ src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); if (vb2_is_streaming(src_vq)) { - struct coda_q_data *q_data_src; - - q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); - codec = coda_find_codec(ctx->dev, q_data_src->fourcc, - f->fmt.pix.pixelformat); - if (!codec) - return -EINVAL; - f->fmt.pix.width = q_data_src->width; f->fmt.pix.height = q_data_src->height; - } else { - /* Otherwise determine codec by encoded format, if possible */ - codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, - f->fmt.pix.pixelformat); } f->fmt.pix.colorspace = ctx->colorspace; + q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + codec = coda_find_codec(ctx->dev, q_data_src->fourcc, + f->fmt.pix.pixelformat); + if (!codec) + return -EINVAL; + ret = coda_try_fmt(ctx, codec, f); if (ret < 0) return ret; @@ -471,22 +529,21 @@ static int coda_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f) { struct coda_ctx *ctx = fh_to_ctx(priv); - const struct coda_codec *codec = NULL; + struct coda_dev *dev = ctx->dev; + const struct coda_q_data *q_data_dst; + const struct coda_codec *codec; + int ret; - /* Determine codec by encoded format, returns NULL if raw or invalid */ - if (ctx->inst_type == CODA_INST_DECODER) { - codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat, - V4L2_PIX_FMT_YUV420); - if (!codec) - codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_H264, - V4L2_PIX_FMT_YUV420); - if (!codec) - return -EINVAL; - } + ret = coda_try_pixelformat(ctx, f); + if (ret < 0) + return ret; if (!f->fmt.pix.colorspace) f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; + q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + codec = coda_find_codec(dev, f->fmt.pix.pixelformat, q_data_dst->fourcc); + return coda_try_fmt(ctx, codec, f); } @@ -907,18 +964,10 @@ static void coda_set_tiled_map_type(struct coda_ctx *ctx, int tiled_map_type) static void set_default_params(struct coda_ctx *ctx) { - u32 src_fourcc, dst_fourcc; - int max_w; - int max_h; + int max_w, max_h; - if (ctx->inst_type == CODA_INST_ENCODER) { - src_fourcc = V4L2_PIX_FMT_YUV420; - dst_fourcc = V4L2_PIX_FMT_H264; - } else { - src_fourcc = V4L2_PIX_FMT_H264; - dst_fourcc = V4L2_PIX_FMT_YUV420; - } - ctx->codec = coda_find_codec(ctx->dev, src_fourcc, dst_fourcc); + ctx->codec = coda_find_codec(ctx->dev, ctx->cvd->src_formats[0], + ctx->cvd->dst_formats[0]); max_w = ctx->codec->max_w; max_h = ctx->codec->max_h; @@ -1409,10 +1458,14 @@ static int coda_next_free_instance(struct coda_dev *dev) return idx; } -static int coda_open(struct file *file, enum coda_inst_type inst_type, - const struct coda_context_ops *ctx_ops) +/* + * File operations + */ + +static int coda_open(struct file *file) { - struct coda_dev *dev = video_drvdata(file); + struct video_device *vdev = video_devdata(file); + struct coda_dev *dev = video_get_drvdata(vdev); struct coda_ctx *ctx = NULL; char *name; int ret; @@ -1433,8 +1486,9 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type, ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); kfree(name); - ctx->inst_type = inst_type; - ctx->ops = ctx_ops; + ctx->cvd = to_coda_video_device(vdev); + ctx->inst_type = ctx->cvd->type; + ctx->ops = ctx->cvd->ops; init_completion(&ctx->completion); INIT_WORK(&ctx->pic_run_work, coda_pic_run_work); INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work); @@ -1542,16 +1596,6 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type, return ret; } -static int coda_encoder_open(struct file *file) -{ - return coda_open(file, CODA_INST_ENCODER, &coda_bit_encode_ops); -} - -static int coda_decoder_open(struct file *file) -{ - return coda_open(file, CODA_INST_DECODER, &coda_bit_decode_ops); -} - static int coda_release(struct file *file) { struct coda_dev *dev = video_drvdata(file); @@ -1595,18 +1639,9 @@ static int coda_release(struct file *file) return 0; } -static const struct v4l2_file_operations coda_encoder_fops = { - .owner = THIS_MODULE, - .open = coda_encoder_open, - .release = coda_release, - .poll = v4l2_m2m_fop_poll, - .unlocked_ioctl = video_ioctl2, - .mmap = v4l2_m2m_fop_mmap, -}; - -static const struct v4l2_file_operations coda_decoder_fops = { +static const struct v4l2_file_operations coda_fops = { .owner = THIS_MODULE, - .open = coda_decoder_open, + .open = coda_open, .release = coda_release, .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, @@ -1711,8 +1746,16 @@ static int coda_hw_init(struct coda_dev *dev) return ret; } -static int coda_register_device(struct coda_dev *dev, struct video_device *vfd) +static int coda_register_device(struct coda_dev *dev, int i) { + struct video_device *vfd = &dev->vfd[i]; + + if (i > ARRAY_SIZE(dev->vfd)) + return -EINVAL; + + snprintf(vfd->name, sizeof(vfd->name), dev->devtype->vdevs[i]->name); + vfd->fops = &coda_fops; + vfd->ioctl_ops = &coda_ioctl_ops; vfd->release = video_device_release_empty, vfd->lock = &dev->dev_mutex; vfd->v4l2_dev = &dev->v4l2_dev; @@ -1731,7 +1774,7 @@ static void coda_fw_callback(const struct firmware *fw, void *context) { struct coda_dev *dev = context; struct platform_device *pdev = dev->plat_dev; - int ret; + int i, ret; if (!fw) { v4l2_err(&dev->v4l2_dev, "firmware request failed\n"); @@ -1772,33 +1815,25 @@ static void coda_fw_callback(const struct firmware *fw, void *context) goto rel_ctx; } - dev->vfd[0].fops = &coda_encoder_fops, - dev->vfd[0].ioctl_ops = &coda_ioctl_ops; - snprintf(dev->vfd[0].name, sizeof(dev->vfd[0].name), "coda-encoder"); - ret = coda_register_device(dev, &dev->vfd[0]); - if (ret) { - v4l2_err(&dev->v4l2_dev, - "Failed to register encoder video device\n"); - goto rel_m2m; - } - - dev->vfd[1].fops = &coda_decoder_fops, - dev->vfd[1].ioctl_ops = &coda_ioctl_ops; - snprintf(dev->vfd[1].name, sizeof(dev->vfd[1].name), "coda-decoder"); - ret = coda_register_device(dev, &dev->vfd[1]); - if (ret) { - v4l2_err(&dev->v4l2_dev, - "Failed to register decoder video device\n"); - goto rel_m2m; + for (i = 0; i < dev->devtype->num_vdevs; i++) { + ret = coda_register_device(dev, i); + if (ret) { + v4l2_err(&dev->v4l2_dev, + "Failed to register %s video device: %d\n", + dev->devtype->vdevs[i]->name, ret); + goto rel_vfd; + } } v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video[%d-%d]\n", - dev->vfd[0].num, dev->vfd[1].num); + dev->vfd[0].num, dev->vfd[i - 1].num); pm_runtime_put_sync(&pdev->dev); return; -rel_m2m: +rel_vfd: + while (--i >= 0) + video_unregister_device(&dev->vfd[i]); v4l2_m2m_release(dev->m2m_dev); rel_ctx: vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); @@ -1830,6 +1865,8 @@ static const struct coda_devtype coda_devdata[] = { .product = CODA_DX6, .codecs = codadx6_codecs, .num_codecs = ARRAY_SIZE(codadx6_codecs), + .vdevs = codadx6_video_devices, + .num_vdevs = ARRAY_SIZE(codadx6_video_devices), .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024, .iram_size = 0xb000, }, @@ -1838,6 +1875,8 @@ static const struct coda_devtype coda_devdata[] = { .product = CODA_7541, .codecs = coda7_codecs, .num_codecs = ARRAY_SIZE(coda7_codecs), + .vdevs = coda7_video_devices, + .num_vdevs = ARRAY_SIZE(coda7_video_devices), .workbuf_size = 128 * 1024, .tempbuf_size = 304 * 1024, .iram_size = 0x14000, @@ -1847,6 +1886,8 @@ static const struct coda_devtype coda_devdata[] = { .product = CODA_960, .codecs = coda9_codecs, .num_codecs = ARRAY_SIZE(coda9_codecs), + .vdevs = coda9_video_devices, + .num_vdevs = ARRAY_SIZE(coda9_video_devices), .workbuf_size = 80 * 1024, .tempbuf_size = 204 * 1024, .iram_size = 0x21000, @@ -1856,6 +1897,8 @@ static const struct coda_devtype coda_devdata[] = { .product = CODA_960, .codecs = coda9_codecs, .num_codecs = ARRAY_SIZE(coda9_codecs), + .vdevs = coda9_video_devices, + .num_vdevs = ARRAY_SIZE(coda9_video_devices), .workbuf_size = 80 * 1024, .tempbuf_size = 204 * 1024, .iram_size = 0x20000, @@ -2035,9 +2078,12 @@ static int coda_probe(struct platform_device *pdev) static int coda_remove(struct platform_device *pdev) { struct coda_dev *dev = platform_get_drvdata(pdev); + int i; - video_unregister_device(&dev->vfd[0]); - video_unregister_device(&dev->vfd[1]); + for (i = 0; i < ARRAY_SIZE(dev->vfd); i++) { + if (video_get_drvdata(&dev->vfd[i])) + video_unregister_device(&dev->vfd[i]); + } if (dev->m2m_dev) v4l2_m2m_release(dev->m2m_dev); pm_runtime_disable(&pdev->dev); diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 76ba83c03191..07eaf58303ef 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -45,11 +45,15 @@ enum coda_product { CODA_960 = 0xf020, }; +struct coda_video_device; + struct coda_devtype { char *firmware; enum coda_product product; const struct coda_codec *codecs; unsigned int num_codecs; + const struct coda_video_device **vdevs; + unsigned int num_vdevs; size_t workbuf_size; size_t tempbuf_size; size_t iram_size; @@ -65,7 +69,7 @@ struct coda_aux_buf { struct coda_dev { struct v4l2_device v4l2_dev; - struct video_device vfd[2]; + struct video_device vfd[3]; struct platform_device *plat_dev; const struct coda_devtype *devtype; @@ -183,6 +187,7 @@ struct coda_ctx { struct work_struct pic_run_work; struct work_struct seq_end_work; struct completion completion; + const struct coda_video_device *cvd; const struct coda_context_ops *ops; int aborting; int initialized; -- GitLab From bfc732f6eb5f6778caff33495dfe87d296ecc89c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:29 -0300 Subject: [PATCH 1647/9457] [media] coda: split out encoder control setup to specify controls per video device This patch splits the encoder specific controls out of the main control setup function. This way each video device registers only relevant controls. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 45db1da2dbcf..7fc0dc06298f 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1334,14 +1334,8 @@ static const struct v4l2_ctrl_ops coda_ctrl_ops = { .s_ctrl = coda_s_ctrl, }; -static int coda_ctrls_setup(struct coda_ctx *ctx) +static void coda_encode_ctrls(struct coda_ctx *ctx) { - v4l2_ctrl_handler_init(&ctx->ctrls, 9); - - v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, @@ -1385,6 +1379,18 @@ static int coda_ctrls_setup(struct coda_ctx *ctx) v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, 0, 1920 * 1088 / 256, 1, 0); +} + +static int coda_ctrls_setup(struct coda_ctx *ctx) +{ + v4l2_ctrl_handler_init(&ctx->ctrls, 2); + + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (ctx->inst_type == CODA_INST_ENCODER) + coda_encode_ctrls(ctx); if (ctx->ctrls.error) { v4l2_err(&ctx->dev->v4l2_dev, -- GitLab From 0ab54524f3ff6463b389cbd160c8efcf64c46865 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:30 -0300 Subject: [PATCH 1648/9457] [media] coda: add JPEG register definitions for CODA7541 Add JPEG specific sequence initialization registers and bit definitions. Signed-off-by: Lucas Stach Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda_regs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h index c791275e307b..8e015b8aa8fa 100644 --- a/drivers/media/platform/coda/coda_regs.h +++ b/drivers/media/platform/coda/coda_regs.h @@ -147,6 +147,7 @@ #define CODA_CMD_DEC_SEQ_BB_START 0x180 #define CODA_CMD_DEC_SEQ_BB_SIZE 0x184 #define CODA_CMD_DEC_SEQ_OPTION 0x188 +#define CODA_NO_INT_ENABLE (1 << 10) #define CODA_REORDER_ENABLE (1 << 1) #define CODADX6_QP_REPORT (1 << 0) #define CODA7_MP4_DEBLK_ENABLE (1 << 0) @@ -332,6 +333,12 @@ #define CODA9_CMD_ENC_SEQ_ME_OPTION 0x1d8 #define CODA_RET_ENC_SEQ_SUCCESS 0x1c0 +#define CODA_CMD_ENC_SEQ_JPG_PARA 0x198 +#define CODA_CMD_ENC_SEQ_JPG_RST_INTERVAL 0x19C +#define CODA_CMD_ENC_SEQ_JPG_THUMB_EN 0x1a0 +#define CODA_CMD_ENC_SEQ_JPG_THUMB_SIZE 0x1a4 +#define CODA_CMD_ENC_SEQ_JPG_THUMB_OFFSET 0x1a8 + /* Encoder Picture Run */ #define CODA9_CMD_ENC_PIC_SRC_INDEX 0x180 #define CODA9_CMD_ENC_PIC_SRC_STRIDE 0x184 -- GitLab From cb1d3a336371e35c3920cc50a701c5403c255644 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:31 -0300 Subject: [PATCH 1649/9457] [media] coda: add CODA7541 JPEG support This patch adds JPEG encoding and decoding support for CODA7541, using the BIT processor. Separate JPEG encoder and decoder video devices are created due to different streaming behaviour and different supported pixel formats. The hardware can not change subsampling on the fly, but encode and decode 4:2:2 subsampled JPEG images from and into this format. The CODA7541 JPEG decoder uses the bitstream buffer and thus can run without new buffers queued if there is a buffer in the bitstream. Since there is no standard way to store the colorspace used in JPEGs, and to make v4l2-compliance happy, the JPEG format always reports V4L2_COLORSPACE_JPEG. Signed-off-by: Lucas Stach Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/Makefile | 2 +- drivers/media/platform/coda/coda-bit.c | 103 +++++++--- drivers/media/platform/coda/coda-common.c | 112 +++++++++-- drivers/media/platform/coda/coda-jpeg.c | 225 ++++++++++++++++++++++ drivers/media/platform/coda/coda.h | 8 +- 5 files changed, 398 insertions(+), 52 deletions(-) create mode 100644 drivers/media/platform/coda/coda-jpeg.c diff --git a/drivers/media/platform/coda/Makefile b/drivers/media/platform/coda/Makefile index 3543291e6273..25ce15561695 100644 --- a/drivers/media/platform/coda/Makefile +++ b/drivers/media/platform/coda/Makefile @@ -1,3 +1,3 @@ -coda-objs := coda-common.o coda-bit.o coda-h264.o +coda-objs := coda-common.o coda-bit.o coda-h264.o coda-jpeg.o obj-$(CONFIG_VIDEO_CODA) += coda.o diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 746a6158ccd0..931248dc60f9 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -691,6 +691,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) struct vb2_buffer *buf; int gamma, ret, value; u32 dst_fourcc; + u32 stride; q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); @@ -710,6 +711,14 @@ static int coda_start_encoding(struct coda_ctx *ctx) return -EFAULT; } + if (dst_fourcc == V4L2_PIX_FMT_JPEG) { + if (!ctx->params.jpeg_qmat_tab[0]) + ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL); + if (!ctx->params.jpeg_qmat_tab[1]) + ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL); + coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality); + } + mutex_lock(&dev->coda_mutex); coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); @@ -765,6 +774,8 @@ static int coda_start_encoding(struct coda_ctx *ctx) << CODA_PICHEIGHT_OFFSET; } coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE); + if (dst_fourcc == V4L2_PIX_FMT_JPEG) + ctx->params.framerate = 0; coda_write(dev, ctx->params.framerate, CODA_CMD_ENC_SEQ_SRC_F_RATE); @@ -798,6 +809,16 @@ static int coda_start_encoding(struct coda_ctx *ctx) } coda_write(dev, value, CODA_CMD_ENC_SEQ_264_PARA); break; + case V4L2_PIX_FMT_JPEG: + coda_write(dev, 0, CODA_CMD_ENC_SEQ_JPG_PARA); + coda_write(dev, ctx->params.jpeg_restart_interval, + CODA_CMD_ENC_SEQ_JPG_RST_INTERVAL); + coda_write(dev, 0, CODA_CMD_ENC_SEQ_JPG_THUMB_EN); + coda_write(dev, 0, CODA_CMD_ENC_SEQ_JPG_THUMB_SIZE); + coda_write(dev, 0, CODA_CMD_ENC_SEQ_JPG_THUMB_OFFSET); + + coda_jpeg_write_tables(ctx); + break; default: v4l2_err(v4l2_dev, "dst format (0x%08x) invalid.\n", dst_fourcc); @@ -805,28 +826,36 @@ static int coda_start_encoding(struct coda_ctx *ctx) goto out; } - switch (ctx->params.slice_mode) { - case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE: - value = 0; - break; - case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB: - value = (ctx->params.slice_max_mb & CODA_SLICING_SIZE_MASK) - << CODA_SLICING_SIZE_OFFSET; - value |= (1 & CODA_SLICING_UNIT_MASK) - << CODA_SLICING_UNIT_OFFSET; - value |= 1 & CODA_SLICING_MODE_MASK; - break; - case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES: - value = (ctx->params.slice_max_bits & CODA_SLICING_SIZE_MASK) - << CODA_SLICING_SIZE_OFFSET; - value |= (0 & CODA_SLICING_UNIT_MASK) - << CODA_SLICING_UNIT_OFFSET; - value |= 1 & CODA_SLICING_MODE_MASK; - break; + /* + * slice mode and GOP size registers are used for thumb size/offset + * in JPEG mode + */ + if (dst_fourcc != V4L2_PIX_FMT_JPEG) { + switch (ctx->params.slice_mode) { + case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE: + value = 0; + break; + case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB: + value = (ctx->params.slice_max_mb & + CODA_SLICING_SIZE_MASK) + << CODA_SLICING_SIZE_OFFSET; + value |= (1 & CODA_SLICING_UNIT_MASK) + << CODA_SLICING_UNIT_OFFSET; + value |= 1 & CODA_SLICING_MODE_MASK; + break; + case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES: + value = (ctx->params.slice_max_bits & + CODA_SLICING_SIZE_MASK) + << CODA_SLICING_SIZE_OFFSET; + value |= (0 & CODA_SLICING_UNIT_MASK) + << CODA_SLICING_UNIT_OFFSET; + value |= 1 & CODA_SLICING_MODE_MASK; + break; + } + coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE); + value = ctx->params.gop_size & CODA_GOP_SIZE_MASK; + coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE); } - coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE); - value = ctx->params.gop_size & CODA_GOP_SIZE_MASK; - coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE); if (ctx->params.bitrate) { /* Rate control enabled */ @@ -917,19 +946,24 @@ static int coda_start_encoding(struct coda_ctx *ctx) goto out; } - if (dev->devtype->product == CODA_960) - ctx->num_internal_frames = 4; - else - ctx->num_internal_frames = 2; - ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc); - if (ret < 0) { - v4l2_err(v4l2_dev, "failed to allocate framebuffers\n"); - goto out; + if (dst_fourcc != V4L2_PIX_FMT_JPEG) { + if (dev->devtype->product == CODA_960) + ctx->num_internal_frames = 4; + else + ctx->num_internal_frames = 2; + ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc); + if (ret < 0) { + v4l2_err(v4l2_dev, "failed to allocate framebuffers\n"); + goto out; + } + stride = q_data_src->bytesperline; + } else { + ctx->num_internal_frames = 0; + stride = 0; } - coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM); - coda_write(dev, q_data_src->bytesperline, - CODA_CMD_SET_FRAME_BUF_STRIDE); + coda_write(dev, stride, CODA_CMD_SET_FRAME_BUF_STRIDE); + if (dev->devtype->product == CODA_7541) { coda_write(dev, q_data_src->bytesperline, CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE); @@ -1104,6 +1138,9 @@ static int coda_prepare_encode(struct coda_ctx *ctx) case V4L2_PIX_FMT_MPEG4: quant_param = ctx->params.mpeg4_intra_qp; break; + case V4L2_PIX_FMT_JPEG: + quant_param = 30; + break; default: v4l2_warn(&ctx->dev->v4l2_dev, "cannot set intra qp, fmt not supported\n"); @@ -1315,6 +1352,8 @@ static int __coda_start_decoding(struct coda_ctx *ctx) if ((dev->devtype->product == CODA_7541) || (dev->devtype->product == CODA_960)) val |= CODA_REORDER_ENABLE; + if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG) + val |= CODA_NO_INT_ENABLE; coda_write(dev, val, CODA_CMD_DEC_SEQ_OPTION); ctx->params.codec_mode = ctx->codec->mode; diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 7fc0dc06298f..76b80d27a135 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -139,6 +139,10 @@ static const struct coda_fmt coda_formats[] = { .name = "MPEG4 Encoded Stream", .fourcc = V4L2_PIX_FMT_MPEG4, }, + { + .name = "JPEG Encoded Images", + .fourcc = V4L2_PIX_FMT_JPEG, + }, }; #define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \ @@ -159,8 +163,10 @@ static const struct coda_codec codadx6_codecs[] = { static const struct coda_codec coda7_codecs[] = { CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1280, 720), CODA_CODEC(CODA7_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1280, 720), + CODA_CODEC(CODA7_MODE_ENCODE_MJPG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_JPEG, 8192, 8192), CODA_CODEC(CODA7_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1088), CODA_CODEC(CODA7_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1088), + CODA_CODEC(CODA7_MODE_DECODE_MJPG, V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420, 8192, 8192), }; static const struct coda_codec coda9_codecs[] = { @@ -193,6 +199,21 @@ static const struct coda_video_device coda_bit_encoder = { }, }; +static const struct coda_video_device coda_bit_jpeg_encoder = { + .name = "coda-jpeg-encoder", + .type = CODA_INST_ENCODER, + .ops = &coda_bit_encode_ops, + .src_formats = { + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YVU420, + V4L2_PIX_FMT_NV12, + V4L2_PIX_FMT_YUV422P, + }, + .dst_formats = { + V4L2_PIX_FMT_JPEG, + }, +}; + static const struct coda_video_device coda_bit_decoder = { .name = "coda-decoder", .type = CODA_INST_DECODER, @@ -208,11 +229,28 @@ static const struct coda_video_device coda_bit_decoder = { }, }; +static const struct coda_video_device coda_bit_jpeg_decoder = { + .name = "coda-jpeg-decoder", + .type = CODA_INST_DECODER, + .ops = &coda_bit_decode_ops, + .src_formats = { + V4L2_PIX_FMT_JPEG, + }, + .dst_formats = { + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YVU420, + V4L2_PIX_FMT_NV12, + V4L2_PIX_FMT_YUV422P, + }, +}; + static const struct coda_video_device *codadx6_video_devices[] = { &coda_bit_encoder, }; static const struct coda_video_device *coda7_video_devices[] = { + &coda_bit_jpeg_encoder, + &coda_bit_jpeg_decoder, &coda_bit_encoder, &coda_bit_decoder, }; @@ -395,7 +433,10 @@ static int coda_g_fmt(struct file *file, void *priv, f->fmt.pix.bytesperline = q_data->bytesperline; f->fmt.pix.sizeimage = q_data->sizeimage; - f->fmt.pix.colorspace = ctx->colorspace; + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) + f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + else + f->fmt.pix.colorspace = ctx->colorspace; return 0; } @@ -453,7 +494,10 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_NV12: - /* Frame stride must be multiple of 8, but 16 for h.264 */ + /* + * Frame stride must be at least multiple of 8, + * but multiple of 16 for h.264 or JPEG 4:2:x + */ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16); f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height * 3 / 2; @@ -463,9 +507,11 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height * 2; break; + case V4L2_PIX_FMT_JPEG: + f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + /* fallthrough */ case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_MPEG4: - case V4L2_PIX_FMT_JPEG: f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; break; @@ -538,8 +584,12 @@ static int coda_try_fmt_vid_out(struct file *file, void *priv, if (ret < 0) return ret; - if (!f->fmt.pix.colorspace) - f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; + if (!f->fmt.pix.colorspace) { + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) + f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; + else + f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; + } q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); codec = coda_find_codec(dev, f->fmt.pix.pixelformat, q_data_dst->fourcc); @@ -883,6 +933,7 @@ static int coda_job_ready(void *m2m_priv) if (ctx->hold || ((ctx->inst_type == CODA_INST_DECODER) && + !v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) && (coda_get_bitstream_payload(ctx) < 512) && !(ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG))) { v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, @@ -1057,7 +1108,7 @@ static void coda_buf_queue(struct vb2_buffer *vb) * In the decoder case, immediately try to copy the buffer into the * bitstream ringbuffer and mark it as ready to be dequeued. */ - if (q_data->fourcc == V4L2_PIX_FMT_H264 && + if (ctx->inst_type == CODA_INST_DECODER && vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { /* * For backwards compatibility, queuing an empty buffer marks @@ -1120,12 +1171,13 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; struct coda_q_data *q_data_src, *q_data_dst; struct vb2_buffer *buf; - u32 dst_fourcc; int ret = 0; q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - if (q_data_src->fourcc == V4L2_PIX_FMT_H264) { + if (q_data_src->fourcc == V4L2_PIX_FMT_H264 || + (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && + ctx->dev->devtype->product == CODA_7541)) { /* copy the buffers that where queued before streamon */ mutex_lock(&ctx->bitstream_mutex); coda_fill_bitstream(ctx); @@ -1156,13 +1208,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) if (!(ctx->streamon_out & ctx->streamon_cap)) return 0; - /* Allow decoder device_run with no new buffers queued */ + /* Allow BIT decoder device_run with no new buffers queued */ if (ctx->inst_type == CODA_INST_DECODER) v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); ctx->gopcounter = ctx->params.gop_size - 1; q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - dst_fourcc = q_data_dst->fourcc; ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, q_data_dst->fourcc); @@ -1172,6 +1223,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) goto err; } + if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) + ctx->params.gop_size = 1; + ctx->gopcounter = ctx->params.gop_size - 1; + ret = ctx->ops->start_streaming(ctx); if (ctx->inst_type == CODA_INST_DECODER) { if (ret == -EAGAIN) @@ -1320,6 +1375,12 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: ctx->params.intra_refresh = ctrl->val; break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + coda_set_jpeg_compression_quality(ctx, ctrl->val); + break; + case V4L2_CID_JPEG_RESTART_INTERVAL: + ctx->params.jpeg_restart_interval = ctrl->val; + break; default: v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", @@ -1381,6 +1442,14 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) 1920 * 1088 / 256, 1, 0); } +static void coda_jpeg_encode_ctrls(struct coda_ctx *ctx) +{ + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 5, 100, 1, 50); + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, 1, 0); +} + static int coda_ctrls_setup(struct coda_ctx *ctx) { v4l2_ctrl_handler_init(&ctx->ctrls, 2); @@ -1389,8 +1458,12 @@ static int coda_ctrls_setup(struct coda_ctx *ctx) V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - if (ctx->inst_type == CODA_INST_ENCODER) - coda_encode_ctrls(ctx); + if (ctx->inst_type == CODA_INST_ENCODER) { + if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) + coda_jpeg_encode_ctrls(ctx); + else + coda_encode_ctrls(ctx); + } if (ctx->ctrls.error) { v4l2_err(&ctx->dev->v4l2_dev, @@ -1548,16 +1621,17 @@ static int coda_open(struct file *file) ctx->fh.ctrl_handler = &ctx->ctrls; - ret = coda_alloc_context_buf(ctx, &ctx->parabuf, CODA_PARA_BUF_SIZE, - "parabuf"); + ret = coda_alloc_context_buf(ctx, &ctx->parabuf, + CODA_PARA_BUF_SIZE, "parabuf"); if (ret < 0) { v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf"); goto err_dma_alloc; } ctx->bitstream.size = CODA_MAX_FRAME_SIZE; - ctx->bitstream.vaddr = dma_alloc_writecombine(&dev->plat_dev->dev, - ctx->bitstream.size, &ctx->bitstream.paddr, GFP_KERNEL); + ctx->bitstream.vaddr = dma_alloc_writecombine( + &dev->plat_dev->dev, ctx->bitstream.size, + &ctx->bitstream.paddr, GFP_KERNEL); if (!ctx->bitstream.vaddr) { v4l2_err(&dev->v4l2_dev, "failed to allocate bitstream ringbuffer"); @@ -1625,8 +1699,10 @@ static int coda_release(struct file *file) list_del(&ctx->list); coda_unlock(ctx); - dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size, - ctx->bitstream.vaddr, ctx->bitstream.paddr); + if (ctx->bitstream.vaddr) { + dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size, + ctx->bitstream.vaddr, ctx->bitstream.paddr); + } if (ctx->dev->devtype->product == CODA_DX6) coda_free_aux_buf(dev, &ctx->workbuf); diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c new file mode 100644 index 000000000000..967b0159c8b9 --- /dev/null +++ b/drivers/media/platform/coda/coda-jpeg.c @@ -0,0 +1,225 @@ +/* + * Coda multi-standard codec IP - JPEG support functions + * + * Copyright (C) 2014 Philipp Zabel, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +#include "coda.h" + +/* + * Typical Huffman tables for 8-bit precision luminance and + * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3 + */ + +static const unsigned char luma_dc_bits[16] = { + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char luma_dc_value[12] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, +}; + +static const unsigned char chroma_dc_bits[16] = { + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char chroma_dc_value[12] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, +}; + +static const unsigned char luma_ac_bits[16] = { + 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, +}; + +static const unsigned char luma_ac_value[162 + 2] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, /* padded to 32-bit */ +}; + +static const unsigned char chroma_ac_bits[16] = { + 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, +}; + +static const unsigned char chroma_ac_value[162 + 2] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, /* padded to 32-bit */ +}; + +/* + * Quantization tables for luminance and chrominance components in + * zig-zag scan order from the Freescale i.MX VPU libaries + */ + +static unsigned char luma_q[64] = { + 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05, + 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b, + 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a, + 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, +}; + +static unsigned char chroma_q[64] = { + 0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10, + 0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14, + 0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, +}; + +struct coda_memcpy_desc { + int offset; + const void *src; + size_t len; +}; + +static void coda_memcpy_parabuf(void *parabuf, + const struct coda_memcpy_desc *desc) +{ + u32 *dst = parabuf + desc->offset; + const u32 *src = desc->src; + int len = desc->len / 4; + int i; + + for (i = 0; i < len; i += 2) { + dst[i + 1] = swab32(src[i]); + dst[i] = swab32(src[i + 1]); + } +} + +int coda_jpeg_write_tables(struct coda_ctx *ctx) +{ + int i; + static const struct coda_memcpy_desc huff[8] = { + { 0, luma_dc_bits, sizeof(luma_dc_bits) }, + { 16, luma_dc_value, sizeof(luma_dc_value) }, + { 32, luma_ac_bits, sizeof(luma_ac_bits) }, + { 48, luma_ac_value, sizeof(luma_ac_value) }, + { 216, chroma_dc_bits, sizeof(chroma_dc_bits) }, + { 232, chroma_dc_value, sizeof(chroma_dc_value) }, + { 248, chroma_ac_bits, sizeof(chroma_ac_bits) }, + { 264, chroma_ac_value, sizeof(chroma_ac_value) }, + }; + struct coda_memcpy_desc qmat[3] = { + { 512, ctx->params.jpeg_qmat_tab[0], 64 }, + { 576, ctx->params.jpeg_qmat_tab[1], 64 }, + { 640, ctx->params.jpeg_qmat_tab[1], 64 }, + }; + + /* Write huffman tables to parameter memory */ + for (i = 0; i < ARRAY_SIZE(huff); i++) + coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i); + + /* Write Q-matrix to parameter memory */ + for (i = 0; i < ARRAY_SIZE(qmat); i++) + coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i); + + return 0; +} + +/* + * Scale quantization table using nonlinear scaling factor + * u8 qtab[64], scale [50,190] + */ +static void coda_scale_quant_table(u8 *q_tab, int scale) +{ + unsigned int temp; + int i; + + for (i = 0; i < 64; i++) { + temp = DIV_ROUND_CLOSEST((unsigned int)q_tab[i] * scale, 100); + if (temp <= 0) + temp = 1; + if (temp > 255) + temp = 255; + q_tab[i] = (unsigned char)temp; + } +} + +void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality) +{ + unsigned int scale; + + ctx->params.jpeg_quality = quality; + + /* Clip quality setting to [5,100] interval */ + if (quality > 100) + quality = 100; + if (quality < 5) + quality = 5; + + /* + * Non-linear scaling factor: + * [5,50] -> [1000..100], [51,100] -> [98..0] + */ + if (quality < 50) + scale = 5000 / quality; + else + scale = 200 - 2 * quality; + + if (ctx->params.jpeg_qmat_tab[0]) { + memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64); + coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale); + } + if (ctx->params.jpeg_qmat_tab[1]) { + memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64); + coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale); + } +} diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 07eaf58303ef..c14dee82891f 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -69,7 +69,7 @@ struct coda_aux_buf { struct coda_dev { struct v4l2_device v4l2_dev; - struct video_device vfd[3]; + struct video_device vfd[5]; struct platform_device *plat_dev; const struct coda_devtype *devtype; @@ -118,6 +118,9 @@ struct coda_params { u8 mpeg4_inter_qp; u8 gop_size; int intra_refresh; + u8 jpeg_quality; + u8 jpeg_restart_interval; + u8 *jpeg_qmat_tab[3]; int codec_mode; int codec_mode_aux; enum v4l2_mpeg_video_multi_slice_mode slice_mode; @@ -288,6 +291,9 @@ void coda_bit_stream_end_flag(struct coda_ctx *ctx); int coda_h264_padding(int size, char *p); +int coda_jpeg_write_tables(struct coda_ctx *ctx); +void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality); + extern const struct coda_context_ops coda_bit_encode_ops; extern const struct coda_context_ops coda_bit_decode_ops; -- GitLab From 7cbb105feff82722206613f3e4cee3e98df827d9 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:32 -0300 Subject: [PATCH 1650/9457] [media] coda: store bitstream buffer position with buffer metadata Storing the buffer position in the bitstream with the buffer metadata allows to later use that information to drop metadata for skipped buffers and to determine whether bitstream padding has to be applied. This patch also renames struct coda_timestamp to struct coda_buffer_meta to make clear that it contains more than only the buffer timestamp. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 53 +++++++++++++---------- drivers/media/platform/coda/coda-common.c | 14 +++--- drivers/media/platform/coda/coda.h | 8 ++-- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 931248dc60f9..d1ecda54666e 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -217,11 +217,16 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx, void coda_fill_bitstream(struct coda_ctx *ctx) { struct vb2_buffer *src_buf; - struct coda_timestamp *ts; + struct coda_buffer_meta *meta; + u32 start; while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) { src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + /* Buffer start position */ + start = ctx->bitstream_fifo.kfifo.in & + ctx->bitstream_fifo.kfifo.mask; + if (coda_bitstream_try_queue(ctx, src_buf)) { /* * Source buffer is queued in the bitstream ringbuffer; @@ -229,12 +234,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx) */ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - ts = kmalloc(sizeof(*ts), GFP_KERNEL); - if (ts) { - ts->sequence = src_buf->v4l2_buf.sequence; - ts->timecode = src_buf->v4l2_buf.timecode; - ts->timestamp = src_buf->v4l2_buf.timestamp; - list_add_tail(&ts->list, &ctx->timestamp_list); + meta = kmalloc(sizeof(*meta), GFP_KERNEL); + if (meta) { + meta->sequence = src_buf->v4l2_buf.sequence; + meta->timecode = src_buf->v4l2_buf.timecode; + meta->timestamp = src_buf->v4l2_buf.timestamp; + meta->start = start; + meta->end = ctx->bitstream_fifo.kfifo.in & + ctx->bitstream_fifo.kfifo.mask; + list_add_tail(&meta->list, + &ctx->buffer_meta_list); } v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); @@ -1629,7 +1638,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) struct coda_q_data *q_data_src; struct coda_q_data *q_data_dst; struct vb2_buffer *dst_buf; - struct coda_timestamp *ts; + struct coda_buffer_meta *meta; unsigned long payload; int width, height; int decoded_idx; @@ -1757,23 +1766,23 @@ static void coda_finish_decode(struct coda_ctx *ctx) val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1; val -= ctx->sequence_offset; mutex_lock(&ctx->bitstream_mutex); - if (!list_empty(&ctx->timestamp_list)) { - ts = list_first_entry(&ctx->timestamp_list, - struct coda_timestamp, list); - list_del(&ts->list); - if (val != (ts->sequence & 0xffff)) { + if (!list_empty(&ctx->buffer_meta_list)) { + meta = list_first_entry(&ctx->buffer_meta_list, + struct coda_buffer_meta, list); + list_del(&meta->list); + if (val != (meta->sequence & 0xffff)) { v4l2_err(&dev->v4l2_dev, "sequence number mismatch (%d(%d) != %d)\n", val, ctx->sequence_offset, - ts->sequence); + meta->sequence); } - ctx->frame_timestamps[decoded_idx] = *ts; - kfree(ts); + ctx->frame_metas[decoded_idx] = *meta; + kfree(meta); } else { v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n"); - memset(&ctx->frame_timestamps[decoded_idx], 0, - sizeof(struct coda_timestamp)); - ctx->frame_timestamps[decoded_idx].sequence = val; + memset(&ctx->frame_metas[decoded_idx], 0, + sizeof(struct coda_buffer_meta)); + ctx->frame_metas[decoded_idx].sequence = val; } mutex_unlock(&ctx->bitstream_mutex); @@ -1812,9 +1821,9 @@ static void coda_finish_decode(struct coda_ctx *ctx) V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME); dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx]; - ts = &ctx->frame_timestamps[ctx->display_idx]; - dst_buf->v4l2_buf.timecode = ts->timecode; - dst_buf->v4l2_buf.timestamp = ts->timestamp; + meta = &ctx->frame_metas[ctx->display_idx]; + dst_buf->v4l2_buf.timecode = meta->timecode; + dst_buf->v4l2_buf.timestamp = meta->timestamp; switch (q_data_dst->fourcc) { case V4L2_PIX_FMT_YUV420: diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 76b80d27a135..6eaf88e88862 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1279,14 +1279,14 @@ static void coda_stop_streaming(struct vb2_queue *q) } if (!ctx->streamon_out && !ctx->streamon_cap) { - struct coda_timestamp *ts; + struct coda_buffer_meta *meta; mutex_lock(&ctx->bitstream_mutex); - while (!list_empty(&ctx->timestamp_list)) { - ts = list_first_entry(&ctx->timestamp_list, - struct coda_timestamp, list); - list_del(&ts->list); - kfree(ts); + while (!list_empty(&ctx->buffer_meta_list)) { + meta = list_first_entry(&ctx->buffer_meta_list, + struct coda_buffer_meta, list); + list_del(&meta->list); + kfree(meta); } mutex_unlock(&ctx->bitstream_mutex); kfifo_init(&ctx->bitstream_fifo, @@ -1642,7 +1642,7 @@ static int coda_open(struct file *file) ctx->bitstream.vaddr, ctx->bitstream.size); mutex_init(&ctx->bitstream_mutex); mutex_init(&ctx->buffer_mutex); - INIT_LIST_HEAD(&ctx->timestamp_list); + INIT_LIST_HEAD(&ctx->buffer_meta_list); coda_lock(ctx); list_add(&ctx->list, &dev->instances); diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index c14dee82891f..8dd81a75c2fb 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -130,11 +130,13 @@ struct coda_params { u32 slice_max_mb; }; -struct coda_timestamp { +struct coda_buffer_meta { struct list_head list; u32 sequence; struct v4l2_timecode timecode; struct timeval timestamp; + u32 start; + u32 end; }; /* Per-queue, driver-specific private data */ @@ -220,9 +222,9 @@ struct coda_ctx { struct coda_aux_buf slicebuf; struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS]; u32 frame_types[CODA_MAX_FRAMEBUFFERS]; - struct coda_timestamp frame_timestamps[CODA_MAX_FRAMEBUFFERS]; + struct coda_buffer_meta frame_metas[CODA_MAX_FRAMEBUFFERS]; u32 frame_errors[CODA_MAX_FRAMEBUFFERS]; - struct list_head timestamp_list; + struct list_head buffer_meta_list; struct coda_aux_buf workbuf; int num_internal_frames; int idx; -- GitLab From 5269aed0f82e703533b7831a49ab76b955b01b6b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:33 -0300 Subject: [PATCH 1651/9457] [media] coda: pad input stream for JPEG decoder Before starting a PIC_RUN, pad the bitstream with 0xff until 256 bytes past the next multiple of 256 bytes, if the buffer to be decoded is the last buffer in the bitstream. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index d1ecda54666e..27e0764e3ac5 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1625,6 +1625,26 @@ static int coda_prepare_decode(struct coda_ctx *ctx) coda_write(dev, ctx->iram_info.axi_sram_use, CODA7_REG_BIT_AXI_SRAM_USE); + if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG) { + struct coda_buffer_meta *meta; + + /* If this is the last buffer in the bitstream, add padding */ + meta = list_first_entry(&ctx->buffer_meta_list, + struct coda_buffer_meta, list); + if (meta->end == (ctx->bitstream_fifo.kfifo.in & + ctx->bitstream_fifo.kfifo.mask)) { + static unsigned char buf[512]; + unsigned int pad; + + /* Pad to multiple of 256 and then add 256 more */ + pad = ((0 - meta->end) & 0xff) + 256; + + memset(buf, 0xff, sizeof(buf)); + + kfifo_in(&ctx->bitstream_fifo, buf, pad); + } + } + coda_kfifo_sync_to_device_full(ctx); coda_command_async(ctx, CODA_COMMAND_PIC_RUN); -- GitLab From 619165628d8f0e296c66a2f37bcea50769b7873d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:34 -0300 Subject: [PATCH 1652/9457] [media] coda: try to only queue a single JPEG into the bitstream With bitstream padding, it is possible to decode a single JPEG in the bitstream immediately. This allows us to only ever queue a single JPEG into the bitstream buffer, except to increase payload over 512 bytes or to back out of hold state. This is a measure to decrease JPEG decoder latency. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 27e0764e3ac5..2a6810e47a5c 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -221,6 +221,14 @@ void coda_fill_bitstream(struct coda_ctx *ctx) u32 start; while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) { + /* + * Only queue a single JPEG into the bitstream buffer, except + * to increase payload over 512 bytes or if in hold state. + */ + if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG && + (coda_get_bitstream_payload(ctx) >= 512) && !ctx->hold) + break; + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); /* Buffer start position */ -- GitLab From d4c6a416b9d57af6ff8a2dc71f81dad70dbefb2b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 2 Oct 2014 14:08:35 -0300 Subject: [PATCH 1653/9457] [media] coda: allow userspace to set compressed buffer size in a certain range For small frame sizes, allocating 1 MiB per compressed buffer is a waste of space. On the other hand, incompressible 1080p data can produce JPEGs larger than 1 MiB at higher quality settings. Allow userspace to set the compressed buffer size and clamp the value to a sensible range. Also set the initial sizeimage to a value inside the range allowed by try_fmt. While at it, reduce the default image size to a maximum of 1920*1088 (otherwise JPEG will default to 8k*8k and 96 MiB buffers). Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 4 ++-- drivers/media/platform/coda/coda-common.c | 25 +++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 2a6810e47a5c..0c67cfd23c16 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1129,7 +1129,7 @@ static int coda_prepare_encode(struct coda_ctx *ctx) ctx->vpu_header_size[0] + ctx->vpu_header_size[1] + ctx->vpu_header_size[2]; - pic_stream_buffer_size = CODA_MAX_FRAME_SIZE - + pic_stream_buffer_size = q_data_dst->sizeimage - ctx->vpu_header_size[0] - ctx->vpu_header_size[1] - ctx->vpu_header_size[2]; @@ -1143,7 +1143,7 @@ static int coda_prepare_encode(struct coda_ctx *ctx) } else { pic_stream_buffer_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); - pic_stream_buffer_size = CODA_MAX_FRAME_SIZE; + pic_stream_buffer_size = q_data_dst->sizeimage; } if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) { diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 6eaf88e88862..151e45b62547 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -513,7 +513,15 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec, case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_MPEG4: f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE; + /* + * This is a rough estimate for sensible compressed buffer + * sizes (between 1 and 16 bits per pixel). This could be + * improved by better format specific worst case estimates. + */ + f->fmt.pix.sizeimage = round_up(clamp(f->fmt.pix.sizeimage, + f->fmt.pix.width * f->fmt.pix.height / 8, + f->fmt.pix.width * f->fmt.pix.height * 2), + PAGE_SIZE); break; default: BUG(); @@ -1015,12 +1023,13 @@ static void coda_set_tiled_map_type(struct coda_ctx *ctx, int tiled_map_type) static void set_default_params(struct coda_ctx *ctx) { - int max_w, max_h; + unsigned int max_w, max_h, size; ctx->codec = coda_find_codec(ctx->dev, ctx->cvd->src_formats[0], ctx->cvd->dst_formats[0]); - max_w = ctx->codec->max_w; - max_h = ctx->codec->max_h; + max_w = min(ctx->codec->max_w, 1920U); + max_h = min(ctx->codec->max_h, 1088U); + size = max_w * max_h * 3 / 2; ctx->params.codec_mode = ctx->codec->mode; ctx->colorspace = V4L2_COLORSPACE_REC709; @@ -1035,14 +1044,14 @@ static void set_default_params(struct coda_ctx *ctx) ctx->q_data[V4L2_M2M_DST].height = max_h; if (ctx->codec->src_fourcc == V4L2_PIX_FMT_YUV420) { ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w; - ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2; + ctx->q_data[V4L2_M2M_SRC].sizeimage = size; ctx->q_data[V4L2_M2M_DST].bytesperline = 0; - ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE; + ctx->q_data[V4L2_M2M_DST].sizeimage = round_up(size, PAGE_SIZE); } else { ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; - ctx->q_data[V4L2_M2M_SRC].sizeimage = CODA_MAX_FRAME_SIZE; + ctx->q_data[V4L2_M2M_SRC].sizeimage = round_up(size, PAGE_SIZE); ctx->q_data[V4L2_M2M_DST].bytesperline = max_w; - ctx->q_data[V4L2_M2M_DST].sizeimage = (max_w * max_h * 3) / 2; + ctx->q_data[V4L2_M2M_DST].sizeimage = size; } ctx->q_data[V4L2_M2M_SRC].rect.width = max_w; ctx->q_data[V4L2_M2M_SRC].rect.height = max_h; -- GitLab From d4bb75f6eee2f9cd7dc0787e3a8fb6bb3e430802 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 13:09:11 -0300 Subject: [PATCH 1654/9457] [media] coda: set bitstream end flag in coda_release This should fix CODA crashes due to timeouts when stopping the decoding process with SIGINT. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 151e45b62547..ffb99442ac6a 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1695,6 +1695,9 @@ static int coda_release(struct file *file) debugfs_remove_recursive(ctx->debugfs_entry); + if (ctx->inst_type == CODA_INST_DECODER) + coda_bit_stream_end_flag(ctx); + /* If this instance is running, call .job_abort and wait for it to end */ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); -- GitLab From edc16cb1159c03864c74fd0411ec5d0bcce845be Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 13:09:27 -0300 Subject: [PATCH 1655/9457] [media] coda: drop JPEG buffers not framed by SOI and EOI markers This patch adds a quick check for valid JPEG frames before feeding them into the bitstream buffer: Frames that do not begin with the JPEG start of image marker and end with the end of image marker are dropped. Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 10 ++++++++++ drivers/media/platform/coda/coda-jpeg.c | 13 +++++++++++++ drivers/media/platform/coda/coda.h | 1 + 3 files changed, 24 insertions(+) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 0c67cfd23c16..b4029ae293d3 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -231,6 +231,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx) src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + /* Drop frames that do not start/end with a SOI/EOI markers */ + if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG && + !coda_jpeg_check_buffer(ctx, src_buf)) { + v4l2_err(&ctx->dev->v4l2_dev, + "dropping invalid JPEG frame\n"); + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); + continue; + } + /* Buffer start position */ start = ctx->bitstream_fifo.kfifo.in & ctx->bitstream_fifo.kfifo.mask; diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c index 967b0159c8b9..8fa3e353f9e2 100644 --- a/drivers/media/platform/coda/coda-jpeg.c +++ b/drivers/media/platform/coda/coda-jpeg.c @@ -14,6 +14,9 @@ #include "coda.h" +#define SOI_MARKER 0xffd8 +#define EOI_MARKER 0xffd9 + /* * Typical Huffman tables for 8-bit precision luminance and * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3 @@ -174,6 +177,16 @@ int coda_jpeg_write_tables(struct coda_ctx *ctx) return 0; } +bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb) +{ + void *vaddr = vb2_plane_vaddr(vb, 0); + u16 soi = be16_to_cpup((__be16 *)vaddr); + u16 eoi = be16_to_cpup((__be16 *)(vaddr + + vb2_get_plane_payload(vb, 0) - 2)); + + return soi == SOI_MARKER && eoi == EOI_MARKER; +} + /* * Scale quantization table using nonlinear scaling factor * u8 qtab[64], scale [50,190] diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 8dd81a75c2fb..5dd47e5f97c1 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h @@ -293,6 +293,7 @@ void coda_bit_stream_end_flag(struct coda_ctx *ctx); int coda_h264_padding(int size, char *p); +bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb); int coda_jpeg_write_tables(struct coda_ctx *ctx); void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality); -- GitLab From c4b1ce051e1f5c1e82cf25f35e24460a9ece993c Mon Sep 17 00:00:00 2001 From: Kiran AVND Date: Tue, 21 Oct 2014 08:06:55 -0300 Subject: [PATCH 1656/9457] [media] s5p-mfc: support MIN_BUFFERS query for encoder Add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT query for encoder. Once mfc encoder state is HEAD_PARSED, which is sequence header produced, dpb_count is avaialable. Let user space query this value. Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index a904a1c7bb21..4816f31acf68 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -690,6 +690,16 @@ static struct mfc_control controls[] = { .step = 1, .default_value = 0, }, + { + .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Minimum number of output bufs", + .minimum = 1, + .maximum = 32, + .step = 1, + .default_value = 1, + .is_volatile = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(controls) @@ -1624,8 +1634,40 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) return ret; } +static int s5p_mfc_enc_g_v_ctrl(struct v4l2_ctrl *ctrl) +{ + struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); + struct s5p_mfc_dev *dev = ctx->dev; + + switch (ctrl->id) { + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + if (ctx->state >= MFCINST_HEAD_PARSED && + ctx->state < MFCINST_ABORT) { + ctrl->val = ctx->pb_count; + break; + } else if (ctx->state != MFCINST_INIT) { + v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); + return -EINVAL; + } + /* Should wait for the header to be produced */ + s5p_mfc_clean_ctx_int_flags(ctx); + s5p_mfc_wait_for_done_ctx(ctx, + S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); + if (ctx->state >= MFCINST_HEAD_PARSED && + ctx->state < MFCINST_ABORT) { + ctrl->val = ctx->pb_count; + } else { + v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); + return -EINVAL; + } + break; + } + return 0; +} + static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = { .s_ctrl = s5p_mfc_enc_s_ctrl, + .g_volatile_ctrl = s5p_mfc_enc_g_v_ctrl, }; static int vidioc_s_parm(struct file *file, void *priv, -- GitLab From 53c51492d6e800fad07cb0fdaf68a5515ebf3058 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 21 Oct 2014 08:06:56 -0300 Subject: [PATCH 1657/9457] [media] s5p-mfc: Fix REQBUFS(0) for encoder Handle REQBUFS(0) for CAPTURE queue as well. Also use the proper queue to call it on for OUTPUT. Signed-off-by: Pawel Osciak Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 4816f31acf68..6a1c890a390d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1147,6 +1147,11 @@ static int vidioc_reqbufs(struct file *file, void *priv, (reqbufs->memory != V4L2_MEMORY_USERPTR)) return -EINVAL; if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + if (reqbufs->count == 0) { + ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); + ctx->capture_state = QUEUE_FREE; + return ret; + } if (ctx->capture_state != QUEUE_FREE) { mfc_err("invalid capture state: %d\n", ctx->capture_state); @@ -1168,6 +1173,14 @@ static int vidioc_reqbufs(struct file *file, void *priv, return -ENOMEM; } } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (reqbufs->count == 0) { + mfc_debug(2, "Freeing buffers\n"); + ret = vb2_reqbufs(&ctx->vq_src, reqbufs); + s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, + ctx); + ctx->output_state = QUEUE_FREE; + return ret; + } if (ctx->output_state != QUEUE_FREE) { mfc_err("invalid output state: %d\n", ctx->output_state); -- GitLab From 643709941d152a8dee58f5ea9f9e19d3f1725722 Mon Sep 17 00:00:00 2001 From: Prathyush K Date: Tue, 21 Oct 2014 08:06:57 -0300 Subject: [PATCH 1658/9457] [media] s5p-mfc: clear 'enter_suspend' flag if suspend fails The enter_suspend flag is set after we enter mfc suspend function but if suspend fails after that due to any reason (like hardware timeout etc), this flag must be cleared before returning an error. Otherwise, this flag never gets cleared and the MFC suspend will always return an error on subsequent tries. If clock off fails, disable hw_lock also. Signed-off-by: Prathyush K Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 165bc86c5962..79c953779fe9 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1284,11 +1284,17 @@ static int s5p_mfc_suspend(struct device *dev) m_dev->int_cond, msecs_to_jiffies(MFC_INT_TIMEOUT)); if (ret == 0) { mfc_err("Waiting for hardware to finish timed out\n"); + clear_bit(0, &m_dev->enter_suspend); return -EIO; } } - return s5p_mfc_sleep(m_dev); + ret = s5p_mfc_sleep(m_dev); + if (ret) { + clear_bit(0, &m_dev->enter_suspend); + clear_bit(0, &m_dev->hw_lock); + } + return ret; } static int s5p_mfc_resume(struct device *dev) -- GitLab From bb21c54af7c6d7896f218cc8e4e5d4a466b8e137 Mon Sep 17 00:00:00 2001 From: Ilja Friedel Date: Tue, 21 Oct 2014 08:06:58 -0300 Subject: [PATCH 1659/9457] [media] s5p-mfc: Only set timestamp/timecode for new frames Timestamp i of a previously decoded buffer was overwritten for some H.264 streams with timestamp i+1 of the next buffer. This happened when encountering frame_type S5P_FIMV_DECODE_FRAME_SKIPPED, indicating no new frame. In most cases this wrong indexing might not have been noticed except for a one frame delay in frame presentation. For H.264 streams though that require reordering of frames for presentation, it caused a slightly erratic presentation time lookup and consequently dropped frames in the Pepper Flash plugin. Signed-off-by: Ilja H. Friedel Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 79c953779fe9..eb710554cb2d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -220,11 +220,14 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) size_t dec_y_addr; unsigned int frame_type; - dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev); + /* Make sure we actually have a new frame before continuing. */ frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev); + if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) + return; + dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev); /* Copy timestamp / timecode from decoded src to dst and set - appropriate flags */ + appropriate flags. */ src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); list_for_each_entry(dst_buf, &ctx->dst_queue, list) { if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) { @@ -250,6 +253,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) dst_buf->b->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME; break; + default: + /* Don't know how to handle + S5P_FIMV_DECODE_FRAME_OTHER_FRAME. */ + mfc_debug(2, "Unexpected frame type: %d\n", + frame_type); } break; } -- GitLab From d7dce6a3cdcfa95703c551a921068223df46732a Mon Sep 17 00:00:00 2001 From: Kiran AVND Date: Tue, 21 Oct 2014 08:06:59 -0300 Subject: [PATCH 1660/9457] [media] s5p-mfc: keep RISC ON during reset for V7/V8 Reset sequence for MFC V7 and V8 do not need RISC_ON to be set to 0, while for MFC V6 it is still needed. Also, remove a couple of register settings during Reset which are not needed from V6 onwards. Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/s5p-mfc/s5p_mfc_common.h | 1 + drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 3e41ca1293ed..5b0c33420e61 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -340,6 +340,7 @@ struct s5p_mfc_dev { struct s5p_mfc_hw_cmds *mfc_cmds; const struct s5p_mfc_regs *mfc_regs; enum s5p_mfc_fw_ver fw_ver; + bool risc_on; /* indicates if RISC is on or off */ }; /** diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 0c885a8a0e9f..f5bb6b2b3a5f 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -139,12 +139,6 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev) mfc_debug_enter(); if (IS_MFCV6_PLUS(dev)) { - /* Reset IP */ - /* except RISC, reset */ - mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6); - /* reset release */ - mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6); - /* Zero Initialization of MFC registers */ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6); @@ -153,8 +147,13 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev) for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++) mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4)); - /* Reset */ - mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); + /* Reset + * set RISC_ON to 0 during power_on & wake_up. + * V6 needs RISC_ON set to 0 during reset also. + */ + if ((!dev->risc_on) || (!IS_MFCV7(dev))) + mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); + mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6); mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6); } else { @@ -226,6 +225,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) /* 0. MFC reset */ mfc_debug(2, "MFC reset..\n"); s5p_mfc_clock_on(); + dev->risc_on = 0; ret = s5p_mfc_reset(dev); if (ret) { mfc_err("Failed to reset MFC - timeout\n"); @@ -238,8 +238,10 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) s5p_mfc_clear_cmds(dev); /* 3. Release reset signal to the RISC */ s5p_mfc_clean_dev_int_flags(dev); - if (IS_MFCV6_PLUS(dev)) + if (IS_MFCV6_PLUS(dev)) { + dev->risc_on = 1; mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); + } else mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); mfc_debug(2, "Will now wait for completion of firmware transfer\n"); @@ -336,6 +338,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) /* 0. MFC reset */ mfc_debug(2, "MFC reset..\n"); s5p_mfc_clock_on(); + dev->risc_on = 0; ret = s5p_mfc_reset(dev); if (ret) { mfc_err("Failed to reset MFC - timeout\n"); @@ -354,8 +357,10 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) return ret; } /* 4. Release reset signal to the RISC */ - if (IS_MFCV6_PLUS(dev)) + if (IS_MFCV6_PLUS(dev)) { + dev->risc_on = 1; mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); + } else mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); -- GitLab From 09accdad0d4b2a6415d3b09bd1b97024f32bb18a Mon Sep 17 00:00:00 2001 From: Kiran AVND Date: Tue, 21 Oct 2014 08:07:00 -0300 Subject: [PATCH 1661/9457] [media] s5p-mfc: check mfc bus ctrl before reset during reset sequence, it is advisable to follow the below sequence, in order to avoid unexpected behavior from MFC . set SFR 0x7110 MFC_BUS_RESET_CTRL 0x1 // wait for REQ_STATUS to be 1 . get SFR 0x7110 MFC_BUS_RESET_CTRL 0x3 // reset now Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/regs-mfc-v6.h | 1 + drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h index 51cb2dd0e13a..83e01f3466e9 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h @@ -71,6 +71,7 @@ #define S5P_FIMV_R2H_CMD_ENC_BUFFER_FUL_RET_V6 16 #define S5P_FIMV_R2H_CMD_ERR_RET_V6 32 +#define S5P_FIMV_MFC_BUS_RESET_CTRL 0x7110 #define S5P_FIMV_FW_VERSION_V6 0xf000 #define S5P_FIMV_INSTANCE_ID_V6 0xf008 diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index f5bb6b2b3a5f..0d3661b5eaf1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -129,6 +129,25 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev) return 0; } +int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) +{ + unsigned int status; + unsigned long timeout; + + /* Reset */ + mfc_write(dev, 0x1, S5P_FIMV_MFC_BUS_RESET_CTRL); + timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT); + /* Check bus status */ + do { + if (time_after(jiffies, timeout)) { + mfc_err("Timeout while resetting MFC.\n"); + return -EIO; + } + status = mfc_read(dev, S5P_FIMV_MFC_BUS_RESET_CTRL); + } while ((status & 0x2) == 0); + return 0; +} + /* Reset the device */ int s5p_mfc_reset(struct s5p_mfc_dev *dev) { @@ -147,11 +166,15 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev) for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++) mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4)); + /* check bus reset control before reset */ + if (dev->risc_on) + if (s5p_mfc_bus_reset(dev)) + return -EIO; /* Reset * set RISC_ON to 0 during power_on & wake_up. * V6 needs RISC_ON set to 0 during reset also. */ - if ((!dev->risc_on) || (!IS_MFCV7(dev))) + if ((!dev->risc_on) || (!IS_MFCV7_PLUS(dev))) mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6); mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6); -- GitLab From 5932f74a116cf14b69b9b3e23dcaf8698151976e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Oct 2014 15:48:50 -0200 Subject: [PATCH 1662/9457] [media] s5p-mfc: declare s5p_mfc_bus_reset as static drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c:132:5: warning: no previous prototype for 's5p_mfc_bus_reset' [-Wmissing-prototypes] int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) ^ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 0d3661b5eaf1..fbffb102ef78 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -129,7 +129,7 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev) return 0; } -int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) +static int s5p_mfc_bus_reset(struct s5p_mfc_dev *dev) { unsigned int status; unsigned long timeout; -- GitLab From 9a7bc6b0c456bdc642269659fb13f29a8c13815b Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 21 Oct 2014 08:07:01 -0300 Subject: [PATCH 1663/9457] [media] s5p-mfc: Don't crash the kernel if the watchdog kicks in If the software watchdog kicks in, the watchdog worker is not synchronized with hardware interrupts and does not block other instances. It's possible for it to clear the hw_lock, making other instances trigger a BUG() on hw_lock checks. Since it's not fatal to clear the hw_lock to zero twice, just WARN in those cases for now. We should not explode, as firmware will return errors as needed for other instances after it's reloaded, or they will time out. A clean fix should involve killing other instances when watchdog kicks in, but requires a major redesign of locking in the driver. Signed-off-by: Pawel Osciak Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index eb710554cb2d..8620236200b7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -342,8 +342,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, ctx->state = MFCINST_RES_CHANGE_INIT; s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); return; @@ -415,8 +414,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, clear_work_bit(ctx); s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); /* if suspending, wake up device and do not try_run again*/ if (test_bit(0, &dev->enter_suspend)) @@ -463,8 +461,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev, break; } } - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); s5p_mfc_clock_off(); wake_up_dev(dev, reason, err); @@ -518,8 +515,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, } s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); clear_work_bit(ctx); - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); wake_up_ctx(ctx, reason, err); @@ -557,16 +553,14 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, } else { ctx->dpb_flush_flag = 0; } - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); wake_up(&ctx->queue); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); } else { - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); @@ -643,8 +637,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) mfc_err("post_frame_start() failed\n"); s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); - if (test_and_clear_bit(0, &dev->hw_lock) == 0) - BUG(); + WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_clock_off(); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); } else { -- GitLab From 773e635266b10244c63259f3366b5b4bc7c215c1 Mon Sep 17 00:00:00 2001 From: Arun Mankuzhi Date: Tue, 21 Oct 2014 08:07:02 -0300 Subject: [PATCH 1664/9457] [media] s5p-mfc: modify mfc wakeup sequence for V8 MFC wakeup command has to be sent after the host receives firmware load complete status from risc. Signed-off-by: Arun Mankuzhi Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index fbffb102ef78..6308150e638f 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -353,6 +353,58 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev) return ret; } +static int s5p_mfc_v8_wait_wakeup(struct s5p_mfc_dev *dev) +{ + int ret; + + /* Release reset signal to the RISC */ + dev->risc_on = 1; + mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); + + if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { + mfc_err("Failed to reset MFCV8\n"); + return -EIO; + } + mfc_debug(2, "Write command to wakeup MFCV8\n"); + ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); + if (ret) { + mfc_err("Failed to send command to MFCV8 - timeout\n"); + return ret; + } + + if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { + mfc_err("Failed to wakeup MFC\n"); + return -EIO; + } + return ret; +} + +static int s5p_mfc_wait_wakeup(struct s5p_mfc_dev *dev) +{ + int ret; + + /* Send MFC wakeup command */ + ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); + if (ret) { + mfc_err("Failed to send command to MFC - timeout\n"); + return ret; + } + + /* Release reset signal to the RISC */ + if (IS_MFCV6_PLUS(dev)) { + dev->risc_on = 1; + mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); + } else { + mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); + } + + if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { + mfc_err("Failed to wakeup MFC\n"); + return -EIO; + } + return ret; +} + int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) { int ret; @@ -365,6 +417,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) ret = s5p_mfc_reset(dev); if (ret) { mfc_err("Failed to reset MFC - timeout\n"); + s5p_mfc_clock_off(); return ret; } mfc_debug(2, "Done MFC reset..\n"); @@ -373,25 +426,16 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) /* 2. Initialize registers of channel I/F */ s5p_mfc_clear_cmds(dev); s5p_mfc_clean_dev_int_flags(dev); - /* 3. Initialize firmware */ - ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev); - if (ret) { - mfc_err("Failed to send command to MFC - timeout\n"); - return ret; - } - /* 4. Release reset signal to the RISC */ - if (IS_MFCV6_PLUS(dev)) { - dev->risc_on = 1; - mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6); - } + /* 3. Send MFC wakeup command and wait for completion*/ + if (IS_MFCV8(dev)) + ret = s5p_mfc_v8_wait_wakeup(dev); else - mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); - mfc_debug(2, "Ok, now will write a command to wakeup the system\n"); - if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) { - mfc_err("Failed to load firmware\n"); - return -EIO; - } + ret = s5p_mfc_wait_wakeup(dev); + s5p_mfc_clock_off(); + if (ret) + return ret; + dev->int_cond = 0; if (dev->int_err != 0 || dev->int_type != S5P_MFC_R2H_CMD_WAKEUP_RET) { -- GitLab From b16e64482dd2346f7fc68ec4150bb1ddf1f988e6 Mon Sep 17 00:00:00 2001 From: Arun Mankuzhi Date: Tue, 21 Oct 2014 08:07:03 -0300 Subject: [PATCH 1665/9457] [media] s5p-mfc: De-init MFC when watchdog kicks in If the software watchdog kicks in, we need to de-init MFC before reloading firmware and re-intializing it again. Signed-off-by: Arun Mankuzhi Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 8620236200b7..39f8f2af39da 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -159,6 +159,10 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work) } clear_bit(0, &dev->hw_lock); spin_unlock_irqrestore(&dev->irqlock, flags); + + /* De-init MFC */ + s5p_mfc_deinit_hw(dev); + /* Double check if there is at least one instance running. * If no instance is in memory than no firmware should be present */ if (dev->num_inst > 0) { -- GitLab From 16258649bf8d7d4379050a51f3cee414e0f8aa8f Mon Sep 17 00:00:00 2001 From: Kiran AVND Date: Tue, 21 Oct 2014 08:07:04 -0300 Subject: [PATCH 1666/9457] [media] s5p-mfc: flush dpbs when resolution changes While resolution change is detected by MFC, we flush out older dpbs, send the resolution change event to application, and then accept further queuing of new src buffers. Sometimes, we error out during dpb flush because of lack of src buffers. Since we have not started decoding new resolution yet, it is simpler to push zero-size buffer until we flush out all dpbs. This is already been done while handling EOS command, and this patch extends the same logic to resolution change as well. Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 8798b14bacce..7b1cf736843c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1532,27 +1532,11 @@ static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev) static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf *temp_vb; - unsigned long flags; - - spin_lock_irqsave(&dev->irqlock, flags); - - /* Frames are being decoded */ - if (list_empty(&ctx->src_queue)) { - mfc_debug(2, "No src buffers.\n"); - spin_unlock_irqrestore(&dev->irqlock, flags); - return; - } - /* Get the next source buffer */ - temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); - temp_vb->flags |= MFC_BUF_FLAG_USED; - s5p_mfc_set_dec_stream_buffer_v6(ctx, - vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0); - spin_unlock_irqrestore(&dev->irqlock, flags); + s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); dev->curr_ctx = ctx->num; s5p_mfc_clean_ctx_int_flags(ctx); - s5p_mfc_decode_one_frame_v6(ctx, 1); + s5p_mfc_decode_one_frame_v6(ctx, MFC_DEC_LAST_FRAME); } static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) -- GitLab From f1c3f44a13ea8d245fc7c2d98f1221ee018dc236 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 21 Oct 2014 08:07:05 -0300 Subject: [PATCH 1667/9457] [media] s5p-mfc: Remove unused alloc field from private buffer struct This field is no longer used as MFC driver doesn't use vb2 alloc contexts anymore. Signed-off-by: Pawel Osciak Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 5b0c33420e61..15f7663dd9f5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -237,8 +237,6 @@ struct s5p_mfc_variant { /** * struct s5p_mfc_priv_buf - represents internal used buffer - * @alloc: allocation-specific context for each buffer - * (videobuf2 allocator) * @ofs: offset of each buffer, will be used for MFC * @virt: kernel virtual address, only valid when the * buffer accessed by driver @@ -246,7 +244,6 @@ struct s5p_mfc_variant { * @size: size of the buffer */ struct s5p_mfc_priv_buf { - void *alloc; unsigned long ofs; void *virt; dma_addr_t dma; -- GitLab From 9841dde5d965963cb9d0548054bc2f408cf7d8d5 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 21 Oct 2014 08:07:06 -0300 Subject: [PATCH 1668/9457] [media] s5p-mfc: fix V4L2_CID_MIN_BUFFERS_FOR_CAPTURE on resolution change G_CTRL on V4L2_CID_MIN_BUFFERS_FOR_CAPTURE will fail if userspace happens to query it after getting a resolution change event and before the codec has a chance to parse the header and switch to an initialized state. Signed-off-by: Pawel Osciak Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index a98fe023deaf..de90465dbc7a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -740,7 +740,8 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) ctx->state < MFCINST_ABORT) { ctrl->val = ctx->pb_count; break; - } else if (ctx->state != MFCINST_INIT) { + } else if (ctx->state != MFCINST_INIT && + ctx->state != MFCINST_RES_CHANGE_END) { v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); return -EINVAL; } -- GitLab From f2035364ccbf357ae23bddd6ebf67b35ecdc6a67 Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Tue, 21 Oct 2014 08:07:07 -0300 Subject: [PATCH 1669/9457] [media] s5p-mfc: fix a race in interrupt flags handling Interrupt result flags have to be cleared before a hardware job is run. Otherwise, if they are cleared asynchronously, we may end up clearing them after the interrupt for which we wanted to wait has already arrived, thus overwriting the job results that we intended to wait for. To prevent this, clear the flags only under hw_lock and before running a hardware job. Signed-off-by: Pawel Osciak Signed-off-by: Kiran AVND Signed-off-by: Arun Kumar K Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 2 -- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 3 --- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 1 - drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 13 ++----------- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 12 ++---------- 5 files changed, 4 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 6308150e638f..40d8a03a141d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -468,7 +468,6 @@ int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) } set_work_bit_irqsave(ctx); - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); if (s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { @@ -494,7 +493,6 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) { ctx->state = MFCINST_RETURN_INST; set_work_bit_irqsave(ctx); - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); /* Wait until instance is returned or timeout occurred */ if (s5p_mfc_wait_for_done_ctx(ctx, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index de90465dbc7a..74bcec8228ee 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -334,7 +334,6 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) MFCINST_RES_CHANGE_END)) { /* If the MFC is parsing the header, * so wait until it is finished */ - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); } @@ -746,7 +745,6 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } /* Should wait for the header to be parsed */ - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); if (ctx->state >= MFCINST_HEAD_PARSED && @@ -1058,7 +1056,6 @@ static void s5p_mfc_stop_streaming(struct vb2_queue *q) if (IS_MFCV6_PLUS(dev) && (ctx->state == MFCINST_RUNNING)) { ctx->state = MFCINST_FLUSH; set_work_bit_irqsave(ctx); - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev); if (s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_DPB_FLUSH_RET, 0)) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 6a1c890a390d..7f919e42b279 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1663,7 +1663,6 @@ static int s5p_mfc_enc_g_v_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } /* Should wait for the header to be produced */ - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); if (ctx->state >= MFCINST_HEAD_PARSED && diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index 7cf07963187d..0c4fcf2dfd09 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -1178,7 +1178,6 @@ static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx) s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE); } @@ -1192,7 +1191,6 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) last_frame = MFC_DEC_LAST_FRAME; s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_decode_one_frame_v5(ctx, last_frame); return 0; } @@ -1212,7 +1210,6 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame) ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); if (temp_vb->b->v4l2_planes[0].bytesused == 0) { last_frame = MFC_DEC_LAST_FRAME; mfc_debug(2, "Setting ctx->state to FINISHING\n"); @@ -1273,7 +1270,6 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); mfc_debug(2, "encoding buffer with index=%d state=%d\n", src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); s5p_mfc_encode_one_frame_v5(ctx); @@ -1297,7 +1293,6 @@ static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) 0, temp_vb->b->v4l2_planes[0].bytesused); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_init_decode_v5(ctx); } @@ -1317,7 +1312,6 @@ static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_init_encode_v5(ctx); } @@ -1352,7 +1346,6 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) 0, temp_vb->b->v4l2_planes[0].bytesused); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_set_dec_frame_buffer_v5(ctx); if (ret) { mfc_err("Failed to alloc frame mem\n"); @@ -1396,6 +1389,8 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) * Now obtaining frames from MFC buffer */ s5p_mfc_clock_on(); + s5p_mfc_clean_ctx_int_flags(ctx); + if (ctx->type == MFCINST_DECODER) { s5p_mfc_set_dec_desc_buffer(ctx); switch (ctx->state) { @@ -1406,12 +1401,10 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME); break; case MFCINST_INIT: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, ctx); break; case MFCINST_RETURN_INST: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, ctx); break; @@ -1444,12 +1437,10 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) ret = s5p_mfc_run_enc_frame(ctx); break; case MFCINST_INIT: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, ctx); break; case MFCINST_RETURN_INST: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, ctx); break; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 7b1cf736843c..9aea179943ce 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1394,7 +1394,6 @@ static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) if (flush) { dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); writel(ctx->inst_no, mfc_regs->instance_id); s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); @@ -1535,7 +1534,6 @@ static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_decode_one_frame_v6(ctx, MFC_DEC_LAST_FRAME); } @@ -1572,7 +1570,6 @@ static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); if (temp_vb->b->v4l2_planes[0].bytesused == 0) { last_frame = 1; mfc_debug(2, "Setting ctx->state to FINISHING\n"); @@ -1629,7 +1626,6 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_encode_one_frame_v6(ctx); return 0; @@ -1651,7 +1647,6 @@ static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) temp_vb->b->v4l2_planes[0].bytesused); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_init_decode_v6(ctx); } @@ -1671,7 +1666,6 @@ static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); spin_unlock_irqrestore(&dev->irqlock, flags); dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); s5p_mfc_init_encode_v6(ctx); } @@ -1691,7 +1685,6 @@ static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) } dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_set_dec_frame_buffer_v6(ctx); if (ret) { mfc_err("Failed to alloc frame mem.\n"); @@ -1706,7 +1699,6 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) int ret; dev->curr_ctx = ctx->num; - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); if (ret) { mfc_err("Failed to alloc frame mem.\n"); @@ -1755,6 +1747,8 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) * Now obtaining frames from MFC buffer */ s5p_mfc_clock_on(); + s5p_mfc_clean_ctx_int_flags(ctx); + if (ctx->type == MFCINST_DECODER) { switch (ctx->state) { case MFCINST_FINISHING: @@ -1764,12 +1758,10 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) ret = s5p_mfc_run_dec_frame(ctx); break; case MFCINST_INIT: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, ctx); break; case MFCINST_RETURN_INST: - s5p_mfc_clean_ctx_int_flags(ctx); ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, ctx); break; -- GitLab From b8b1b58c5dd3d8448ace438bb52ea9f8670fdd5b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 21 Oct 2014 13:25:52 -0300 Subject: [PATCH 1670/9457] [media] coda: re-queue buffers if start_streaming fails Patch b906352c2338 ([media] coda: dequeue buffers if start_streaming fails) incorrectly marked buffers as DEQUEUED in case of start_streaming failure, when in fact they should be set to QUEUED. The videobuf2 core warns about this. Reported-by: Jean-Michel Hautbois Signed-off-by: Philipp Zabel Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index ffb99442ac6a..c588fad0f1fd 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1250,10 +1250,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) err: if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) - v4l2_m2m_buf_done(buf, VB2_BUF_STATE_DEQUEUED); + v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); } else { while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) - v4l2_m2m_buf_done(buf, VB2_BUF_STATE_DEQUEUED); + v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); } return ret; } -- GitLab From bf69877d65df83ac4bf0e92e354e3a7b6c568291 Mon Sep 17 00:00:00 2001 From: ayaka Date: Wed, 22 Oct 2014 15:03:08 -0300 Subject: [PATCH 1671/9457] [media] s5p-mfc: correct the formats info for encoder The NV12M is supported by all the version of MFC, so it is better to use it as default OUTPUT format. MFC v5 doesn't support NV21, I have tested it, for the SEC doc it is not supported either. Signed-off-by: ayaka Signed-off-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 7f919e42b279..9391b8ea4682 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -32,7 +32,7 @@ #include "s5p_mfc_intr.h" #include "s5p_mfc_opr.h" -#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12MT +#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 static struct s5p_mfc_fmt formats[] = { @@ -67,8 +67,7 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, .num_planes = 2, - .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | - MFC_V8_BIT, + .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, }, { .name = "H264 Encoded Stream", -- GitLab From e71a180628c71bbf69575f2801d3ce435e37c3db Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:31 -0300 Subject: [PATCH 1672/9457] [media] media: davinci: vpbe: initialize vb2 queue and DMA context in probe this patch moves the initialization of vb2 queue and the DMA context to probe() and clean up in remove() callback respectively. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 128 ++++++++---------- 1 file changed, 60 insertions(+), 68 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 73496d953ba0..ff9eac4050d0 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -207,10 +207,9 @@ static irqreturn_t venc_isr(int irq, void *arg) */ static int vpbe_buffer_prepare(struct vb2_buffer *vb) { - struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); struct vb2_queue *q = vb->vb2_queue; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = vb2_get_drv_priv(q); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; unsigned long addr; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -247,9 +246,8 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = vb2_get_drv_priv(vq); - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = vb2_get_drv_priv(vq); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n"); @@ -271,12 +269,11 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, static void vpbe_buffer_queue(struct vb2_buffer *vb) { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); struct vpbe_disp_buffer *buf = container_of(vb, struct vpbe_disp_buffer, vb); - struct vpbe_layer *layer = fh->layer; - struct vpbe_display *disp = fh->disp_dev; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue); + struct vpbe_display *disp = layer->disp_dev; + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; unsigned long flags; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -296,9 +293,8 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb) static void vpbe_buf_cleanup(struct vb2_buffer *vb) { /* Get the file handle object and layer object */ - struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue); - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; struct vpbe_disp_buffer *buf = container_of(vb, struct vpbe_disp_buffer, vb); unsigned long flags; @@ -314,16 +310,14 @@ static void vpbe_buf_cleanup(struct vb2_buffer *vb) static void vpbe_wait_prepare(struct vb2_queue *vq) { - struct vpbe_fh *fh = vb2_get_drv_priv(vq); - struct vpbe_layer *layer = fh->layer; + struct vpbe_layer *layer = vb2_get_drv_priv(vq); mutex_unlock(&layer->opslock); } static void vpbe_wait_finish(struct vb2_queue *vq) { - struct vpbe_fh *fh = vb2_get_drv_priv(vq); - struct vpbe_layer *layer = fh->layer; + struct vpbe_layer *layer = vb2_get_drv_priv(vq); mutex_lock(&layer->opslock); } @@ -339,8 +333,7 @@ static int vpbe_buffer_init(struct vb2_buffer *vb) static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) { - struct vpbe_fh *fh = vb2_get_drv_priv(vq); - struct vpbe_layer *layer = fh->layer; + struct vpbe_layer *layer = vb2_get_drv_priv(vq); int ret; /* Get the next frame from the buffer queue */ @@ -354,7 +347,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) layer->field_id = 0; /* Set parameters in OSD and VENC */ - ret = vpbe_set_osd_display_params(fh->disp_dev, layer); + ret = vpbe_set_osd_display_params(layer->disp_dev, layer); if (ret < 0) { struct vpbe_disp_buffer *buf, *tmp; @@ -379,9 +372,8 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) static void vpbe_stop_streaming(struct vb2_queue *vq) { - struct vpbe_fh *fh = vb2_get_drv_priv(vq); - struct vpbe_layer *layer = fh->layer; - struct vpbe_display *disp = fh->disp_dev; + struct vpbe_layer *layer = vb2_get_drv_priv(vq); + struct vpbe_display *disp = layer->disp_dev; unsigned long flags; if (!vb2_is_streaming(vq)) @@ -1380,8 +1372,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, struct vpbe_fh *fh = file->private_data; struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - struct vb2_queue *q; - int ret; + v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) { @@ -1394,39 +1385,14 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n"); return -EBUSY; } - /* Initialize videobuf queue as per the buffer type */ - layer->alloc_ctx = vb2_dma_contig_init_ctx(vpbe_dev->pdev); - if (IS_ERR(layer->alloc_ctx)) { - v4l2_err(&vpbe_dev->v4l2_dev, "Failed to get the context\n"); - return PTR_ERR(layer->alloc_ctx); - } - q = &layer->buffer_queue; - memset(q, 0, sizeof(*q)); - q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - q->io_modes = VB2_MMAP | VB2_USERPTR; - q->drv_priv = fh; - q->ops = &video_qops; - q->mem_ops = &vb2_dma_contig_memops; - q->buf_struct_size = sizeof(struct vpbe_disp_buffer); - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - q->min_buffers_needed = 1; - - ret = vb2_queue_init(q); - if (ret) { - v4l2_err(&vpbe_dev->v4l2_dev, "vb2_queue_init() failed\n"); - vb2_dma_contig_cleanup_ctx(layer->alloc_ctx); - return ret; - } /* Set io allowed member of file handle to TRUE */ fh->io_allowed = 1; /* Increment io usrs member of layer object to 1 */ layer->io_usrs = 1; /* Store type of memory requested in layer object */ layer->memory = req_buf->memory; - /* Initialize buffer queue */ - INIT_LIST_HEAD(&layer->dma_queue); /* Allocate buffers */ - return vb2_reqbufs(q, req_buf); + return vb2_reqbufs(&layer->buffer_queue, req_buf); } /* @@ -1551,9 +1517,6 @@ static int vpbe_display_release(struct file *file) osd_device->ops.disable_layer(osd_device, layer->layer_info.id); layer->started = 0; - /* Free buffers allocated */ - vb2_queue_release(&layer->buffer_queue); - vb2_dma_contig_cleanup_ctx(&layer->buffer_queue); } /* Decrement layer usrs counter */ @@ -1724,9 +1687,10 @@ static int register_device(struct vpbe_layer *vpbe_display_layer, */ static int vpbe_display_probe(struct platform_device *pdev) { - struct vpbe_layer *vpbe_display_layer; struct vpbe_display *disp_dev; + struct v4l2_device *v4l2_dev; struct resource *res = NULL; + struct vb2_queue *q; int k; int i; int err; @@ -1748,13 +1712,14 @@ static int vpbe_display_probe(struct platform_device *pdev) vpbe_device_get); if (err < 0) return err; + + v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev; /* Initialize the vpbe display controller */ if (NULL != disp_dev->vpbe_dev->ops.initialize) { err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev, disp_dev->vpbe_dev); if (err) { - v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, - "Error initing vpbe\n"); + v4l2_err(v4l2_dev, "Error initing vpbe\n"); err = -ENOMEM; goto probe_out; } @@ -1769,8 +1734,7 @@ static int vpbe_display_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { - v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, - "Unable to get VENC interrupt resource\n"); + v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n"); err = -ENODEV; goto probe_out; } @@ -1779,30 +1743,57 @@ static int vpbe_display_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, irq, venc_isr, 0, VPBE_DISPLAY_DRIVER, disp_dev); if (err) { - v4l2_err(&disp_dev->vpbe_dev->v4l2_dev, - "Unable to request interrupt\n"); + v4l2_err(v4l2_dev, "VPBE IRQ request failed\n"); goto probe_out; } for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { + /* initialize vb2 queue */ + q = &disp_dev->dev[i]->buffer_queue; + memset(q, 0, sizeof(*q)); + q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + q->io_modes = VB2_MMAP | VB2_USERPTR; + q->drv_priv = disp_dev->dev[i]; + q->ops = &video_qops; + q->mem_ops = &vb2_dma_contig_memops; + q->buf_struct_size = sizeof(struct vpbe_disp_buffer); + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 1; + + err = vb2_queue_init(q); + if (err) { + v4l2_err(v4l2_dev, "vb2_queue_init() failed\n"); + goto probe_out; + } + + disp_dev->dev[i]->alloc_ctx = + vb2_dma_contig_init_ctx(disp_dev->vpbe_dev->pdev); + if (IS_ERR(disp_dev->dev[i]->alloc_ctx)) { + v4l2_err(v4l2_dev, "Failed to get the context\n"); + err = PTR_ERR(disp_dev->dev[i]->alloc_ctx); + goto probe_out; + } + + INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue); + if (register_device(disp_dev->dev[i], disp_dev, pdev)) { err = -ENODEV; goto probe_out; } } - printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n"); + v4l2_dbg(1, debug, v4l2_dev, + "Successfully completed the probing of vpbe v4l2 device\n"); + return 0; probe_out: for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { - /* Get the pointer to the layer object */ - vpbe_display_layer = disp_dev->dev[k]; /* Unregister video device */ - if (vpbe_display_layer) { - video_unregister_device( - &vpbe_display_layer->video_dev); - kfree(disp_dev->dev[k]); + if (disp_dev->dev[k] != NULL) { + vb2_dma_contig_cleanup_ctx(disp_dev->dev[k]->alloc_ctx); + video_unregister_device(&disp_dev->dev[k]->video_dev); + kfree(disp_dev->dev[k]); } } return err; @@ -1828,6 +1819,7 @@ static int vpbe_display_remove(struct platform_device *pdev) for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { /* Get the pointer to the layer object */ vpbe_display_layer = disp_dev->dev[i]; + vb2_dma_contig_cleanup_ctx(vpbe_display_layer->alloc_ctx); /* Unregister video device */ video_unregister_device(&vpbe_display_layer->video_dev); -- GitLab From f92a4e2d96387368e460f74e2c652d4ad34b0906 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:32 -0300 Subject: [PATCH 1673/9457] [media] media: davinci: vpbe: drop buf_init() callback this patch drops the buf_init() callback as init of buf list is not required. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index ff9eac4050d0..e2bda17f0ffd 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -322,15 +322,6 @@ static void vpbe_wait_finish(struct vb2_queue *vq) mutex_lock(&layer->opslock); } -static int vpbe_buffer_init(struct vb2_buffer *vb) -{ - struct vpbe_disp_buffer *buf = container_of(vb, - struct vpbe_disp_buffer, vb); - - INIT_LIST_HEAD(&buf->list); - return 0; -} - static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vpbe_layer *layer = vb2_get_drv_priv(vq); @@ -405,7 +396,6 @@ static struct vb2_ops video_qops = { .queue_setup = vpbe_buffer_queue_setup, .wait_prepare = vpbe_wait_prepare, .wait_finish = vpbe_wait_finish, - .buf_init = vpbe_buffer_init, .buf_prepare = vpbe_buffer_prepare, .start_streaming = vpbe_start_streaming, .stop_streaming = vpbe_stop_streaming, -- GitLab From 488735bfed9bc17e244d1fc8da4a090dc0af58a9 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:33 -0300 Subject: [PATCH 1674/9457] [media] media: davinci: vpbe: use vb2_ops_wait_prepare/finish helper functions this patch makes use of vb2_ops_wait_prepare/finish helper functions. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index e2bda17f0ffd..6f9599deb355 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -308,20 +308,6 @@ static void vpbe_buf_cleanup(struct vb2_buffer *vb) spin_unlock_irqrestore(&layer->irqlock, flags); } -static void vpbe_wait_prepare(struct vb2_queue *vq) -{ - struct vpbe_layer *layer = vb2_get_drv_priv(vq); - - mutex_unlock(&layer->opslock); -} - -static void vpbe_wait_finish(struct vb2_queue *vq) -{ - struct vpbe_layer *layer = vb2_get_drv_priv(vq); - - mutex_lock(&layer->opslock); -} - static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vpbe_layer *layer = vb2_get_drv_priv(vq); @@ -394,8 +380,8 @@ static void vpbe_stop_streaming(struct vb2_queue *vq) static struct vb2_ops video_qops = { .queue_setup = vpbe_buffer_queue_setup, - .wait_prepare = vpbe_wait_prepare, - .wait_finish = vpbe_wait_finish, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, .buf_prepare = vpbe_buffer_prepare, .start_streaming = vpbe_start_streaming, .stop_streaming = vpbe_stop_streaming, @@ -1749,7 +1735,7 @@ static int vpbe_display_probe(struct platform_device *pdev) q->buf_struct_size = sizeof(struct vpbe_disp_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 1; - + q->lock = &disp_dev->dev[i]->opslock; err = vb2_queue_init(q); if (err) { v4l2_err(v4l2_dev, "vb2_queue_init() failed\n"); -- GitLab From f2095f658df7f660fbf97e116096473a5b0d2f8f Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:34 -0300 Subject: [PATCH 1675/9457] [media] media: davinci: vpbe: drop buf_cleanup() callback this patch drops buf_cleanup() callback as this callback is never called with buffer state active. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 6f9599deb355..491b8320f6a6 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -285,29 +285,6 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&disp->dma_queue_lock, flags); } -/* - * vpbe_buf_cleanup() - * This function is called from the vb2 layer to free memory allocated to - * the buffers - */ -static void vpbe_buf_cleanup(struct vb2_buffer *vb) -{ - /* Get the file handle object and layer object */ - struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - struct vpbe_disp_buffer *buf = container_of(vb, - struct vpbe_disp_buffer, vb); - unsigned long flags; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "vpbe_buf_cleanup\n"); - - spin_lock_irqsave(&layer->irqlock, flags); - if (vb->state == VB2_BUF_STATE_ACTIVE) - list_del_init(&buf->list); - spin_unlock_irqrestore(&layer->irqlock, flags); -} - static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vpbe_layer *layer = vb2_get_drv_priv(vq); @@ -385,7 +362,6 @@ static struct vb2_ops video_qops = { .buf_prepare = vpbe_buffer_prepare, .start_streaming = vpbe_start_streaming, .stop_streaming = vpbe_stop_streaming, - .buf_cleanup = vpbe_buf_cleanup, .buf_queue = vpbe_buffer_queue, }; -- GitLab From 50d9481ddcc88a6a0b282a5d74f2f62639d70660 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:35 -0300 Subject: [PATCH 1676/9457] [media] media: davinci: vpbe: improve vpbe_buffer_prepare() callback this patch improve vpbe_buffer_prepare() callback, as buf_prepare() callback is never called with invalid state and check for vb2_plane_vaddr(vb, 0) is dropped as payload check should be done unconditionally. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 491b8320f6a6..524e1fd53ada 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -215,22 +215,15 @@ static int vpbe_buffer_prepare(struct vb2_buffer *vb) v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_prepare\n"); - if (vb->state != VB2_BUF_STATE_ACTIVE && - vb->state != VB2_BUF_STATE_PREPARED) { - vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage); - if (vb2_plane_vaddr(vb, 0) && - vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) - return -EINVAL; + vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage); + if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) + return -EINVAL; - addr = vb2_dma_contig_plane_dma_addr(vb, 0); - if (q->streaming) { - if (!IS_ALIGNED(addr, 8)) { - v4l2_err(&vpbe_dev->v4l2_dev, - "buffer_prepare:offset is \ - not aligned to 32 bytes\n"); - return -EINVAL; - } - } + addr = vb2_dma_contig_plane_dma_addr(vb, 0); + if (!IS_ALIGNED(addr, 8)) { + v4l2_err(&vpbe_dev->v4l2_dev, + "buffer_prepare:offset is not aligned to 32 bytes\n"); + return -EINVAL; } return 0; } -- GitLab From 266c9c2d33ec8382470affe1eef90cd757dfefdd Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:36 -0300 Subject: [PATCH 1677/9457] [media] media: davinci: vpbe: use vb2_fop_mmap/poll this patch teaches vpbe driver to use vb2_fop_mmap/poll helpers. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 44 ++----------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 524e1fd53ada..fc3bdb6afafe 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1340,45 +1340,6 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, return vb2_reqbufs(&layer->buffer_queue, req_buf); } -/* - * vpbe_display_mmap() - * It is used to map kernel space buffers into user spaces - */ -static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma) -{ - /* Get the layer object and file handle object */ - struct vpbe_fh *fh = filep->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - int ret; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n"); - - if (mutex_lock_interruptible(&layer->opslock)) - return -ERESTARTSYS; - ret = vb2_mmap(&layer->buffer_queue, vma); - mutex_unlock(&layer->opslock); - return ret; -} - -/* vpbe_display_poll(): It is used for select/poll system call - */ -static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait) -{ - struct vpbe_fh *fh = filep->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - unsigned int err = 0; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n"); - if (layer->started) { - mutex_lock(&layer->opslock); - err = vb2_poll(&layer->buffer_queue, filep, wait); - mutex_unlock(&layer->opslock); - } - return err; -} - /* * vpbe_display_open() * It creates object of file handle structure and stores it in private_data @@ -1527,8 +1488,8 @@ static struct v4l2_file_operations vpbe_fops = { .open = vpbe_display_open, .release = vpbe_display_release, .unlocked_ioctl = video_ioctl2, - .mmap = vpbe_display_mmap, - .poll = vpbe_display_poll + .mmap = vb2_fop_mmap, + .poll = vb2_fop_poll, }; static int vpbe_device_get(struct device *dev, void *data) @@ -1608,6 +1569,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer, (int)vpbe_display_layer, (int)&vpbe_display_layer->video_dev); + vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue; err = video_register_device(&vpbe_display_layer->video_dev, VFL_TYPE_GRABBER, -1); -- GitLab From 4bb1231a5f3262eec8d879386b88b4d48082fd46 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:37 -0300 Subject: [PATCH 1678/9457] [media] media: davinci: vpbe: use fh handling provided by v4l this patch converts the driver to use fh handling provided by the v4l core instead of driver doing it. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 189 ++++++------------ include/media/davinci/vpbe_display.h | 11 - 2 files changed, 65 insertions(+), 135 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index fc3bdb6afafe..970242caad4d 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -628,8 +628,8 @@ static int vpbe_try_format(struct vpbe_display *disp_dev, static int vpbe_display_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; cap->version = VPBE_DISPLAY_VERSION_CODE; cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; @@ -646,9 +646,8 @@ static int vpbe_display_querycap(struct file *file, void *priv, static int vpbe_display_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_display *disp_dev = fh->disp_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_display *disp_dev = layer->disp_dev; struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; struct osd_layer_config *cfg = &layer->layer_info.config; struct osd_state *osd_device = disp_dev->osd_device; @@ -715,11 +714,10 @@ static int vpbe_display_s_crop(struct file *file, void *priv, static int vpbe_display_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; + struct vpbe_layer *layer = video_drvdata(file); struct osd_layer_config *cfg = &layer->layer_info.config; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - struct osd_state *osd_device = fh->disp_dev->osd_device; + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; + struct osd_state *osd_device = layer->disp_dev->osd_device; struct v4l2_rect *rect = &crop->c; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -743,8 +741,8 @@ static int vpbe_display_g_crop(struct file *file, void *priv, static int vpbe_display_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n"); @@ -761,9 +759,8 @@ static int vpbe_display_cropcap(struct file *file, void *priv, static int vpbe_display_g_fmt(struct file *file, void *priv, struct v4l2_format *fmt) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_FMT, layer id = %d\n", @@ -783,9 +780,8 @@ static int vpbe_display_g_fmt(struct file *file, void *priv, static int vpbe_display_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *fmt) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; unsigned int index = 0; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -815,9 +811,8 @@ static int vpbe_display_enum_fmt(struct file *file, void *priv, static int vpbe_display_s_fmt(struct file *file, void *priv, struct v4l2_format *fmt) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_display *disp_dev = fh->disp_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_display *disp_dev = layer->disp_dev; struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; struct osd_layer_config *cfg = &layer->layer_info.config; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; @@ -904,9 +899,9 @@ static int vpbe_display_s_fmt(struct file *file, void *priv, static int vpbe_display_try_fmt(struct file *file, void *priv, struct v4l2_format *fmt) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_display *disp_dev = fh->disp_dev; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_display *disp_dev = layer->disp_dev; + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n"); @@ -930,9 +925,8 @@ static int vpbe_display_try_fmt(struct file *file, void *priv, static int vpbe_display_s_std(struct file *file, void *priv, v4l2_std_id std_id) { - struct vpbe_fh *fh = priv; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n"); @@ -965,8 +959,8 @@ static int vpbe_display_s_std(struct file *file, void *priv, static int vpbe_display_g_std(struct file *file, void *priv, v4l2_std_id *std_id) { - struct vpbe_fh *fh = priv; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n"); @@ -988,8 +982,8 @@ static int vpbe_display_g_std(struct file *file, void *priv, static int vpbe_display_enum_output(struct file *file, void *priv, struct v4l2_output *output) { - struct vpbe_fh *fh = priv; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n"); @@ -1016,9 +1010,8 @@ static int vpbe_display_enum_output(struct file *file, void *priv, static int vpbe_display_s_output(struct file *file, void *priv, unsigned int i) { - struct vpbe_fh *fh = priv; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n"); @@ -1047,8 +1040,8 @@ static int vpbe_display_s_output(struct file *file, void *priv, static int vpbe_display_g_output(struct file *file, void *priv, unsigned int *i) { - struct vpbe_fh *fh = priv; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n"); /* Get the standard from the current encoder */ @@ -1067,8 +1060,8 @@ static int vpbe_display_enum_dv_timings(struct file *file, void *priv, struct v4l2_enum_dv_timings *timings) { - struct vpbe_fh *fh = priv; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n"); @@ -1097,9 +1090,8 @@ static int vpbe_display_s_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings) { - struct vpbe_fh *fh = priv; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n"); @@ -1135,8 +1127,8 @@ static int vpbe_display_g_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *dv_timings) { - struct vpbe_fh *fh = priv; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n"); @@ -1155,10 +1147,9 @@ vpbe_display_g_dv_timings(struct file *file, void *priv, static int vpbe_display_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; - struct osd_state *osd_device = fh->disp_dev->osd_device; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; + struct osd_state *osd_device = layer->disp_dev->osd_device; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -1170,12 +1161,6 @@ static int vpbe_display_streamoff(struct file *file, void *priv, return -EINVAL; } - /* If io is allowed for this file handle, return error */ - if (!fh->io_allowed) { - v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n"); - return -EACCES; - } - /* If streaming is not started, return error */ if (!layer->started) { v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer" @@ -1194,10 +1179,9 @@ static int vpbe_display_streamoff(struct file *file, void *priv, static int vpbe_display_streamon(struct file *file, void *priv, enum v4l2_buf_type buf_type) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_display *disp_dev = fh->disp_dev; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_display *disp_dev = layer->disp_dev; + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; struct osd_state *osd_device = disp_dev->osd_device; int ret; @@ -1212,11 +1196,6 @@ static int vpbe_display_streamon(struct file *file, void *priv, return -EINVAL; } - /* If file handle is not allowed IO, return error */ - if (!fh->io_allowed) { - v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n"); - return -EACCES; - } /* If Streaming is already started, return error */ if (layer->started) { v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n"); @@ -1239,9 +1218,8 @@ static int vpbe_display_streamon(struct file *file, void *priv, static int vpbe_display_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, @@ -1252,11 +1230,6 @@ static int vpbe_display_dqbuf(struct file *file, void *priv, v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); return -EINVAL; } - /* If this file handle is not allowed to do IO, return error */ - if (!fh->io_allowed) { - v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n"); - return -EACCES; - } if (file->f_flags & O_NONBLOCK) /* Call videobuf_dqbuf for non blocking mode */ ret = vb2_dqbuf(&layer->buffer_queue, buf, 1); @@ -1270,9 +1243,8 @@ static int vpbe_display_dqbuf(struct file *file, void *priv, static int vpbe_display_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_QBUF, layer id = %d\n", @@ -1283,21 +1255,14 @@ static int vpbe_display_qbuf(struct file *file, void *priv, return -EINVAL; } - /* If this file handle is not allowed to do IO, return error */ - if (!fh->io_allowed) { - v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n"); - return -EACCES; - } - return vb2_qbuf(&layer->buffer_queue, p); } static int vpbe_display_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_QUERYBUF, layer id = %d\n", @@ -1314,9 +1279,8 @@ static int vpbe_display_querybuf(struct file *file, void *priv, static int vpbe_display_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *req_buf) { - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; - struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; + struct vpbe_layer *layer = video_drvdata(file); + struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); @@ -1330,8 +1294,6 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n"); return -EBUSY; } - /* Set io allowed member of file handle to TRUE */ - fh->io_allowed = 1; /* Increment io usrs member of layer object to 1 */ layer->io_usrs = 1; /* Store type of memory requested in layer object */ @@ -1347,30 +1309,22 @@ static int vpbe_display_reqbufs(struct file *file, void *priv, */ static int vpbe_display_open(struct file *file) { - struct vpbe_fh *fh = NULL; struct vpbe_layer *layer = video_drvdata(file); - struct video_device *vdev = video_devdata(file); struct vpbe_display *disp_dev = layer->disp_dev; struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; struct osd_state *osd_device = disp_dev->osd_device; int err; - /* Allocate memory for the file handle object */ - fh = kmalloc(sizeof(struct vpbe_fh), GFP_KERNEL); - if (fh == NULL) { - v4l2_err(&vpbe_dev->v4l2_dev, - "unable to allocate memory for file handle object\n"); - return -ENOMEM; + /* creating context for file descriptor */ + err = v4l2_fh_open(file); + if (err) { + v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n"); + return err; } - v4l2_fh_init(&fh->fh, vdev); - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "vpbe display open plane = %d\n", - layer->device_id); - /* store pointer to fh in private_data member of filep */ - file->private_data = fh; - fh->layer = layer; - fh->disp_dev = disp_dev; + /* leaving if layer is already initialized */ + if (!v4l2_fh_is_singular_file(file)) + return err; if (!layer->usrs) { if (mutex_lock_interruptible(&layer->opslock)) @@ -1383,15 +1337,12 @@ static int vpbe_display_open(struct file *file) /* Couldn't get layer */ v4l2_err(&vpbe_dev->v4l2_dev, "Display Manager failed to allocate layer\n"); - kfree(fh); + v4l2_fh_release(file); return -EINVAL; } } /* Increment layer usrs counter */ layer->usrs++; - /* Set io_allowed member to false */ - fh->io_allowed = 0; - v4l2_fh_add(&fh->fh); v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe display device opened successfully\n"); return 0; @@ -1404,26 +1355,21 @@ static int vpbe_display_open(struct file *file) */ static int vpbe_display_release(struct file *file) { - /* Get the layer object and file handle object */ - struct vpbe_fh *fh = file->private_data; - struct vpbe_layer *layer = fh->layer; + struct vpbe_layer *layer = video_drvdata(file); struct osd_layer_config *cfg = &layer->layer_info.config; - struct vpbe_display *disp_dev = fh->disp_dev; + struct vpbe_display *disp_dev = layer->disp_dev; struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; struct osd_state *osd_device = disp_dev->osd_device; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n"); mutex_lock(&layer->opslock); - /* if this instance is doing IO */ - if (fh->io_allowed) { - /* Reset io_usrs member of layer object */ - layer->io_usrs = 0; + /* Reset io_usrs member of layer object */ + layer->io_usrs = 0; - osd_device->ops.disable_layer(osd_device, - layer->layer_info.id); - layer->started = 0; - } + osd_device->ops.disable_layer(osd_device, + layer->layer_info.id); + layer->started = 0; /* Decrement layer usrs counter */ layer->usrs--; @@ -1444,14 +1390,9 @@ static int vpbe_display_release(struct file *file) layer->layer_info.id); } - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - file->private_data = NULL; + _vb2_fop_release(file, NULL); mutex_unlock(&layer->opslock); - /* Free memory allocated to file handle object */ - kfree(fh); - disp_dev->cbcr_ofst = 0; return 0; diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h index 637749a91432..06ea81576e5f 100644 --- a/include/media/davinci/vpbe_display.h +++ b/include/media/davinci/vpbe_display.h @@ -131,17 +131,6 @@ struct vpbe_display { struct osd_state *osd_device; }; -/* File handle structure */ -struct vpbe_fh { - struct v4l2_fh fh; - /* vpbe device structure */ - struct vpbe_display *disp_dev; - /* pointer to layer object for opened device */ - struct vpbe_layer *layer; - /* Indicates whether this file handle is doing IO */ - unsigned char io_allowed; -}; - struct buf_config_params { unsigned char min_numbuffers; unsigned char numbuffers[VPBE_DISPLAY_MAX_DEVICES]; -- GitLab From 41cf47b37c34fe47d39293e2114b914506311212 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:38 -0300 Subject: [PATCH 1679/9457] [media] media: davinci: vpbe: use vb2_ioctl_* helpers this patch adds support for using vb2_ioctl_* helpers. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 178 ++---------------- 1 file changed, 14 insertions(+), 164 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 970242caad4d..76450aa04de5 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -281,8 +281,11 @@ static void vpbe_buffer_queue(struct vb2_buffer *vb) static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vpbe_layer *layer = vb2_get_drv_priv(vq); + struct osd_state *osd_device = layer->disp_dev->osd_device; int ret; + osd_device->ops.disable_layer(osd_device, layer->layer_info.id); + /* Get the next frame from the buffer queue */ layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next, struct vpbe_disp_buffer, list); @@ -320,12 +323,15 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) static void vpbe_stop_streaming(struct vb2_queue *vq) { struct vpbe_layer *layer = vb2_get_drv_priv(vq); + struct osd_state *osd_device = layer->disp_dev->osd_device; struct vpbe_display *disp = layer->disp_dev; unsigned long flags; if (!vb2_is_streaming(vq)) return; + osd_device->ops.disable_layer(osd_device, layer->layer_info.id); + /* release all active buffers */ spin_lock_irqsave(&disp->dma_queue_lock, flags); if (layer->cur_frm == layer->next_frm) { @@ -1144,164 +1150,6 @@ vpbe_display_g_dv_timings(struct file *file, void *priv, return 0; } -static int vpbe_display_streamoff(struct file *file, void *priv, - enum v4l2_buf_type buf_type) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - struct osd_state *osd_device = layer->disp_dev->osd_device; - int ret; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "VIDIOC_STREAMOFF,layer id = %d\n", - layer->device_id); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - - /* If streaming is not started, return error */ - if (!layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer" - " id = %d\n", layer->device_id); - return -EINVAL; - } - - osd_device->ops.disable_layer(osd_device, - layer->layer_info.id); - layer->started = 0; - ret = vb2_streamoff(&layer->buffer_queue, buf_type); - - return ret; -} - -static int vpbe_display_streamon(struct file *file, void *priv, - enum v4l2_buf_type buf_type) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_display *disp_dev = layer->disp_dev; - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - struct osd_state *osd_device = disp_dev->osd_device; - int ret; - - osd_device->ops.disable_layer(osd_device, - layer->layer_info.id); - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_STREAMON, layerid=%d\n", - layer->device_id); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - - /* If Streaming is already started, return error */ - if (layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n"); - return -EBUSY; - } - - /* - * Call vb2_streamon to start streaming - * in videobuf - */ - ret = vb2_streamon(&layer->buffer_queue, buf_type); - if (ret) { - v4l2_err(&vpbe_dev->v4l2_dev, - "error in vb2_streamon\n"); - return ret; - } - return ret; -} - -static int vpbe_display_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - int ret; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "VIDIOC_DQBUF, layer id = %d\n", - layer->device_id); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - if (file->f_flags & O_NONBLOCK) - /* Call videobuf_dqbuf for non blocking mode */ - ret = vb2_dqbuf(&layer->buffer_queue, buf, 1); - else - /* Call videobuf_dqbuf for blocking mode */ - ret = vb2_dqbuf(&layer->buffer_queue, buf, 0); - - return ret; -} - -static int vpbe_display_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "VIDIOC_QBUF, layer id = %d\n", - layer->device_id); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != p->type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - - return vb2_qbuf(&layer->buffer_queue, p); -} - -static int vpbe_display_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, - "VIDIOC_QUERYBUF, layer id = %d\n", - layer->device_id); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - /* Call vb2_querybuf to get information */ - return vb2_querybuf(&layer->buffer_queue, buf); -} - -static int vpbe_display_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *req_buf) -{ - struct vpbe_layer *layer = video_drvdata(file); - struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - - v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n"); - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) { - v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n"); - return -EINVAL; - } - - /* If io users of the layer is not zero, return error */ - if (0 != layer->io_usrs) { - v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n"); - return -EBUSY; - } - /* Increment io usrs member of layer object to 1 */ - layer->io_usrs = 1; - /* Store type of memory requested in layer object */ - layer->memory = req_buf->memory; - /* Allocate buffers */ - return vb2_reqbufs(&layer->buffer_queue, req_buf); -} - /* * vpbe_display_open() * It creates object of file handle structure and stores it in private_data @@ -1405,12 +1253,14 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt, .vidioc_s_fmt_vid_out = vpbe_display_s_fmt, .vidioc_try_fmt_vid_out = vpbe_display_try_fmt, - .vidioc_reqbufs = vpbe_display_reqbufs, - .vidioc_querybuf = vpbe_display_querybuf, - .vidioc_qbuf = vpbe_display_qbuf, - .vidioc_dqbuf = vpbe_display_dqbuf, - .vidioc_streamon = vpbe_display_streamon, - .vidioc_streamoff = vpbe_display_streamoff, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_cropcap = vpbe_display_cropcap, .vidioc_g_crop = vpbe_display_g_crop, .vidioc_s_crop = vpbe_display_s_crop, -- GitLab From 01118c9fb75f723ac0f7791a74dc38d8556ff466 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:39 -0300 Subject: [PATCH 1680/9457] [media] media: davinci: vpbe: add support for VB2_DMABUF Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 76450aa04de5..c33b77e52ac2 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1450,7 +1450,7 @@ static int vpbe_display_probe(struct platform_device *pdev) q = &disp_dev->dev[i]->buffer_queue; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = disp_dev->dev[i]; q->ops = &video_qops; q->mem_ops = &vb2_dma_contig_memops; -- GitLab From c24376f30262c5ceb26f49da34edff6512d7c671 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:41 -0300 Subject: [PATCH 1681/9457] [media] media: davinci: vpbe: add support for VIDIOC_EXPBUF Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index c33b77e52ac2..26d2335fe416 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1260,6 +1260,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_expbuf = vb2_ioctl_expbuf, .vidioc_cropcap = vpbe_display_cropcap, .vidioc_g_crop = vpbe_display_g_crop, -- GitLab From 1b73f03cbf483dbf986cb299f6d6c4ebdfbe6ba7 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:42 -0300 Subject: [PATCH 1682/9457] [media] media: davinci: vpbe: use helpers provided by core if streaming is started this patch uses vb2_is_busy() helper to check if streaming is actually started, instead of driver managing it. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 34 ++++++------------- include/media/davinci/vpbe_display.h | 4 --- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 26d2335fe416..57dc4951c979 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -152,8 +152,8 @@ static irqreturn_t venc_isr(int irq, void *arg) for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { layer = disp_dev->dev[i]; - /* If streaming is started in this layer */ - if (!layer->started) + + if (!vb2_start_streaming_called(&layer->buffer_queue)) continue; if (layer->layer_first_int) { @@ -314,7 +314,6 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) * if request format is yuv420 semiplanar, need to * enable both video windows */ - layer->started = 1; layer->layer_first_int = 1; return ret; @@ -829,11 +828,9 @@ static int vpbe_display_s_fmt(struct file *file, void *priv, "VIDIOC_S_FMT, layer id = %d\n", layer->device_id); - /* If streaming is started, return error */ - if (layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n"); + if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - } + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) { v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n"); return -EINVAL; @@ -937,11 +934,9 @@ static int vpbe_display_s_std(struct file *file, void *priv, v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n"); - /* If streaming is started, return error */ - if (layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n"); + if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - } + if (NULL != vpbe_dev->ops.s_std) { ret = vpbe_dev->ops.s_std(vpbe_dev, std_id); if (ret) { @@ -1021,11 +1016,10 @@ static int vpbe_display_s_output(struct file *file, void *priv, int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n"); - /* If streaming is started, return error */ - if (layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n"); + + if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - } + if (NULL == vpbe_dev->ops.set_output) return -EINVAL; @@ -1102,12 +1096,8 @@ vpbe_display_s_dv_timings(struct file *file, void *priv, v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n"); - - /* If streaming is started, return error */ - if (layer->started) { - v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n"); + if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - } /* Set the given standard in the encoder */ if (!vpbe_dev->ops.s_dv_timings) @@ -1212,13 +1202,9 @@ static int vpbe_display_release(struct file *file) v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n"); mutex_lock(&layer->opslock); - /* Reset io_usrs member of layer object */ - layer->io_usrs = 0; osd_device->ops.disable_layer(osd_device, layer->layer_info.id); - layer->started = 0; - /* Decrement layer usrs counter */ layer->usrs--; /* If this file handle has initialize encoder device, reset it */ diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h index 06ea81576e5f..de0843d6f05c 100644 --- a/include/media/davinci/vpbe_display.h +++ b/include/media/davinci/vpbe_display.h @@ -106,12 +106,8 @@ struct vpbe_layer { unsigned char window_enable; /* number of open instances of the layer */ unsigned int usrs; - /* number of users performing IO */ - unsigned int io_usrs; /* Indicates id of the field which is being displayed */ unsigned int field_id; - /* Indicates whether streaming started */ - unsigned char started; /* Identifies device object */ enum vpbe_display_device_id device_id; /* facilitation of ioctl ops lock by v4l2*/ -- GitLab From 8a93dbc1f4d5c33b444d561a8f4c4ddfc2e7cb74 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:43 -0300 Subject: [PATCH 1683/9457] [media] media: davinci: vpbe: drop unused member memory from vpbe_layer Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/davinci/vpbe_display.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h index de0843d6f05c..163a02b92c04 100644 --- a/include/media/davinci/vpbe_display.h +++ b/include/media/davinci/vpbe_display.h @@ -91,10 +91,6 @@ struct vpbe_layer { /* V4l2 specific parameters */ /* Identifies video device for this layer */ struct video_device video_dev; - /* This field keeps track of type of buffer exchange mechanism user - * has selected - */ - enum v4l2_memory memory; /* Used to store pixel format */ struct v4l2_pix_format pix_fmt; enum v4l2_field buf_field; -- GitLab From a8afe3817d61f26728d8ced8d646fb1322aebd7e Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:44 -0300 Subject: [PATCH 1684/9457] [media] media: davinci: vpbe: group v4l2_ioctl_ops this patch groups the v4l2_ioctl_ops. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 57dc4951c979..3b607498bb48 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1251,11 +1251,14 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { .vidioc_cropcap = vpbe_display_cropcap, .vidioc_g_crop = vpbe_display_g_crop, .vidioc_s_crop = vpbe_display_s_crop, + .vidioc_s_std = vpbe_display_s_std, .vidioc_g_std = vpbe_display_g_std, + .vidioc_enum_output = vpbe_display_enum_output, .vidioc_s_output = vpbe_display_s_output, .vidioc_g_output = vpbe_display_g_output, + .vidioc_s_dv_timings = vpbe_display_s_dv_timings, .vidioc_g_dv_timings = vpbe_display_g_dv_timings, .vidioc_enum_dv_timings = vpbe_display_enum_dv_timings, -- GitLab From f9cc70bfa4ab40b95aa49e9e7e4bb166364d07e6 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Sun, 12 Oct 2014 17:40:45 -0300 Subject: [PATCH 1685/9457] [media] media: davinci: vpbe: return -ENODATA for *dv_timings/*_std calls this patch adds support for returning -ENODATA if the current output doesn't support it. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 33b9660b7f77..49d2de0eea2d 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -341,7 +341,7 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev, if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_DV_TIMINGS)) - return -EINVAL; + return -ENODATA; for (i = 0; i < output->num_modes; i++) { if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS && @@ -384,6 +384,13 @@ static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev, static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev, struct v4l2_dv_timings *dv_timings) { + struct vpbe_config *cfg = vpbe_dev->cfg; + int out_index = vpbe_dev->current_out_index; + + if (!(cfg->outputs[out_index].output.capabilities & + V4L2_OUT_CAP_DV_TIMINGS)) + return -ENODATA; + if (vpbe_dev->current_timings.timings_type & VPBE_ENC_DV_TIMINGS) { *dv_timings = vpbe_dev->current_timings.dv_timings; @@ -409,7 +416,7 @@ static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev, int i; if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS)) - return -EINVAL; + return -ENODATA; for (i = 0; i < output->num_modes; i++) { if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) { @@ -440,7 +447,7 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id) if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD)) - return -EINVAL; + return -ENODATA; ret = vpbe_get_std_info(vpbe_dev, std_id); if (ret) @@ -473,6 +480,11 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id) static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id) { struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings; + struct vpbe_config *cfg = vpbe_dev->cfg; + int out_index = vpbe_dev->current_out_index; + + if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD)) + return -ENODATA; if (cur_timings->timings_type & VPBE_ENC_STD) { *std_id = cur_timings->std_id; -- GitLab From 7a7f1ab37dc8f66cf0ef10f3d3f1b79ac4bc67fc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 22 Sep 2014 11:08:55 -0300 Subject: [PATCH 1686/9457] [media] v4l2-ctrls: fix sparse warning The warning is simple: drivers/media/v4l2-core/v4l2-ctrls.c:1685:15: warning: incorrect type in assignment (different address spaces) but the fix isn't. The core problem was that the conversion from user to kernelspace was done at too low a level and that needed to be moved up. That made it possible to drop pointers to v4l2_ext_control from set_ctrl and validate_new and clean up this sparse warning because those functions now always operate on kernelspace pointers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ctrls.c | 87 +++++++++++++++++----------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 86012140923f..45c5b4710601 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1658,10 +1658,8 @@ static int check_range(enum v4l2_ctrl_type type, } /* Validate a new control */ -static int validate_new(const struct v4l2_ctrl *ctrl, - struct v4l2_ext_control *c) +static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) { - union v4l2_ctrl_ptr ptr; unsigned idx; int err = 0; @@ -1674,19 +1672,14 @@ static int validate_new(const struct v4l2_ctrl *ctrl, case V4L2_CTRL_TYPE_BOOLEAN: case V4L2_CTRL_TYPE_BUTTON: case V4L2_CTRL_TYPE_CTRL_CLASS: - ptr.p_s32 = &c->value; - return ctrl->type_ops->validate(ctrl, 0, ptr); - case V4L2_CTRL_TYPE_INTEGER64: - ptr.p_s64 = &c->value64; - return ctrl->type_ops->validate(ctrl, 0, ptr); + return ctrl->type_ops->validate(ctrl, 0, p_new); default: break; } } - ptr.p = c->ptr; - for (idx = 0; !err && idx < c->size / ctrl->elem_size; idx++) - err = ctrl->type_ops->validate(ctrl, idx, ptr); + for (idx = 0; !err && idx < ctrl->elems; idx++) + err = ctrl->type_ops->validate(ctrl, idx, p_new); return err; } @@ -3012,6 +3005,7 @@ static int validate_ctrls(struct v4l2_ext_controls *cs, cs->error_idx = cs->count; for (i = 0; i < cs->count; i++) { struct v4l2_ctrl *ctrl = helpers[i].ctrl; + union v4l2_ctrl_ptr p_new; cs->error_idx = i; @@ -3025,7 +3019,17 @@ static int validate_ctrls(struct v4l2_ext_controls *cs, best-effort to avoid that. */ if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) return -EBUSY; - ret = validate_new(ctrl, &cs->controls[i]); + /* + * Skip validation for now if the payload needs to be copied + * from userspace into kernelspace. We'll validate those later. + */ + if (ctrl->is_ptr) + continue; + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + p_new.p_s64 = &cs->controls[i].value64; + else + p_new.p_s32 = &cs->controls[i].value; + ret = validate_new(ctrl, p_new); if (ret) return ret; } @@ -3120,7 +3124,11 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, /* Copy the new caller-supplied control values. user_to_new() sets 'is_new' to 1. */ do { - ret = user_to_new(cs->controls + idx, helpers[idx].ctrl); + struct v4l2_ctrl *ctrl = helpers[idx].ctrl; + + ret = user_to_new(cs->controls + idx, ctrl); + if (!ret && ctrl->is_ptr) + ret = validate_new(ctrl, ctrl->p_new); idx = helpers[idx].next; } while (!ret && idx); @@ -3170,10 +3178,10 @@ int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls); /* Helper function for VIDIOC_S_CTRL compatibility */ -static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, - struct v4l2_ext_control *c, u32 ch_flags) +static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) { struct v4l2_ctrl *master = ctrl->cluster[0]; + int ret; int i; /* Reset the 'is_new' flags of the cluster */ @@ -3181,8 +3189,9 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, if (master->cluster[i]) master->cluster[i]->is_new = 0; - if (c) - user_to_new(c, ctrl); + ret = validate_new(ctrl, ctrl->p_new); + if (ret) + return ret; /* For autoclusters with volatiles that are switched from auto to manual mode we have to update the current volatile values since @@ -3199,15 +3208,14 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) { - int ret = validate_new(ctrl, c); + int ret; - if (!ret) { - v4l2_ctrl_lock(ctrl); - ret = set_ctrl(fh, ctrl, c, 0); - if (!ret) - cur_to_user(c, ctrl); - v4l2_ctrl_unlock(ctrl); - } + v4l2_ctrl_lock(ctrl); + user_to_new(c, ctrl); + ret = set_ctrl(fh, ctrl, 0); + if (!ret) + cur_to_user(c, ctrl); + v4l2_ctrl_unlock(ctrl); return ret; } @@ -3215,7 +3223,7 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) { struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); - struct v4l2_ext_control c; + struct v4l2_ext_control c = { control->id }; int ret; if (ctrl == NULL || !ctrl->is_int) @@ -3244,7 +3252,7 @@ int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) /* It's a driver bug if this happens. */ WARN_ON(!ctrl->is_int); ctrl->val = val; - return set_ctrl(NULL, ctrl, NULL, 0); + return set_ctrl(NULL, ctrl, 0); } EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl); @@ -3255,7 +3263,7 @@ int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) /* It's a driver bug if this happens. */ WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64); *ctrl->p_new.p_s64 = val; - return set_ctrl(NULL, ctrl, NULL, 0); + return set_ctrl(NULL, ctrl, 0); } EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64); @@ -3266,7 +3274,7 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s) /* It's a driver bug if this happens. */ WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING); strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1); - return set_ctrl(NULL, ctrl, NULL, 0); + return set_ctrl(NULL, ctrl, 0); } EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); @@ -3289,8 +3297,8 @@ EXPORT_SYMBOL(v4l2_ctrl_notify); int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, s64 min, s64 max, u64 step, s64 def) { + bool changed; int ret; - struct v4l2_ext_control c; lockdep_assert_held(ctrl->handler->lock); @@ -3317,11 +3325,20 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, ctrl->maximum = max; ctrl->step = step; ctrl->default_value = def; - c.value = *ctrl->p_cur.p_s32; - if (validate_new(ctrl, &c)) - c.value = def; - if (c.value != *ctrl->p_cur.p_s32) - ret = set_ctrl(NULL, ctrl, &c, V4L2_EVENT_CTRL_CH_RANGE); + cur_to_new(ctrl); + if (validate_new(ctrl, ctrl->p_new)) { + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + *ctrl->p_new.p_s64 = def; + else + *ctrl->p_new.p_s32 = def; + } + + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64; + else + changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32; + if (changed) + ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); else send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); return ret; -- GitLab From 62b9c8d0372d11a5e048c6b56997374901e0445b Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 22 Oct 2014 17:29:06 +0200 Subject: [PATCH 1687/9457] ovs: Turn vports with dependencies into separate modules The internal and netdev vport remain part of openvswitch.ko. Encap vports including vxlan, gre, and geneve can be built as separate modules and are loaded on demand. Modules can be unloaded after use. Datapath ports keep a reference to the vport module during their lifetime. Allows to remove the error prone maintenance of the global list vport_ops_list. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/openvswitch/Kconfig | 18 ++--- net/openvswitch/Makefile | 14 +--- net/openvswitch/datapath.c | 16 ++++- net/openvswitch/vport-geneve.c | 23 +++++- net/openvswitch/vport-gre.c | 23 +++++- net/openvswitch/vport-internal_dev.c | 17 ++++- net/openvswitch/vport-netdev.c | 14 +++- net/openvswitch/vport-netdev.h | 3 + net/openvswitch/vport-vxlan.c | 23 +++++- net/openvswitch/vport.c | 102 ++++++++++++++++++--------- net/openvswitch/vport.h | 14 ++-- 11 files changed, 199 insertions(+), 68 deletions(-) diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index ba3bb8203b99..2a9673e39ca1 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig @@ -29,11 +29,11 @@ config OPENVSWITCH If unsure, say N. config OPENVSWITCH_GRE - bool "Open vSwitch GRE tunneling support" + tristate "Open vSwitch GRE tunneling support" depends on INET depends on OPENVSWITCH - depends on NET_IPGRE_DEMUX && !(OPENVSWITCH=y && NET_IPGRE_DEMUX=m) - default y + depends on NET_IPGRE_DEMUX + default OPENVSWITCH ---help--- If you say Y here, then the Open vSwitch will be able create GRE vport. @@ -43,11 +43,11 @@ config OPENVSWITCH_GRE If unsure, say Y. config OPENVSWITCH_VXLAN - bool "Open vSwitch VXLAN tunneling support" + tristate "Open vSwitch VXLAN tunneling support" depends on INET depends on OPENVSWITCH - depends on VXLAN && !(OPENVSWITCH=y && VXLAN=m) - default y + depends on VXLAN + default OPENVSWITCH ---help--- If you say Y here, then the Open vSwitch will be able create vxlan vport. @@ -56,11 +56,11 @@ config OPENVSWITCH_VXLAN If unsure, say Y. config OPENVSWITCH_GENEVE - bool "Open vSwitch Geneve tunneling support" + tristate "Open vSwitch Geneve tunneling support" depends on INET depends on OPENVSWITCH - depends on GENEVE && !(OPENVSWITCH=y && GENEVE=m) - default y + depends on GENEVE + default OPENVSWITCH ---help--- If you say Y here, then the Open vSwitch will be able create geneve vport. diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile index 9a33a273c375..91b9478413ef 100644 --- a/net/openvswitch/Makefile +++ b/net/openvswitch/Makefile @@ -15,14 +15,6 @@ openvswitch-y := \ vport-internal_dev.o \ vport-netdev.o -ifneq ($(CONFIG_OPENVSWITCH_GENEVE),) -openvswitch-y += vport-geneve.o -endif - -ifneq ($(CONFIG_OPENVSWITCH_VXLAN),) -openvswitch-y += vport-vxlan.o -endif - -ifneq ($(CONFIG_OPENVSWITCH_GRE),) -openvswitch-y += vport-gre.o -endif +obj-$(CONFIG_OPENVSWITCH_GENEVE)+= vport-geneve.o +obj-$(CONFIG_OPENVSWITCH_VXLAN) += vport-vxlan.o +obj-$(CONFIG_OPENVSWITCH_GRE) += vport-gre.o diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e6d7255183eb..aecddb9bb80a 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -59,6 +59,7 @@ #include "vport-netdev.h" int ovs_net_id __read_mostly; +EXPORT_SYMBOL(ovs_net_id); static struct genl_family dp_packet_genl_family; static struct genl_family dp_flow_genl_family; @@ -1764,6 +1765,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) return -ENOMEM; ovs_lock(); +restart: dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex); err = -ENODEV; if (!dp) @@ -1795,8 +1797,11 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) vport = new_vport(&parms); err = PTR_ERR(vport); - if (IS_ERR(vport)) + if (IS_ERR(vport)) { + if (err == -EAGAIN) + goto restart; goto exit_unlock_free; + } err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, info->snd_seq, 0, OVS_VPORT_CMD_NEW); @@ -2112,12 +2117,18 @@ static int __init dp_init(void) if (err) goto error_netns_exit; + err = ovs_netdev_init(); + if (err) + goto error_unreg_notifier; + err = dp_register_genl(); if (err < 0) - goto error_unreg_notifier; + goto error_unreg_netdev; return 0; +error_unreg_netdev: + ovs_netdev_exit(); error_unreg_notifier: unregister_netdevice_notifier(&ovs_dp_device_notifier); error_netns_exit: @@ -2137,6 +2148,7 @@ static int __init dp_init(void) static void dp_cleanup(void) { dp_unregister_genl(ARRAY_SIZE(dp_genl_families)); + ovs_netdev_exit(); unregister_netdevice_notifier(&ovs_dp_device_notifier); unregister_pernet_device(&ovs_net_ops); rcu_barrier(); diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 106a9d80b663..70c9765011f4 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,8 @@ #include "datapath.h" #include "vport.h" +static struct vport_ops ovs_geneve_vport_ops; + /** * struct geneve_port - Keeps track of open UDP ports * @gs: The socket created for this port number. @@ -225,11 +228,29 @@ static const char *geneve_get_name(const struct vport *vport) return geneve_port->name; } -const struct vport_ops ovs_geneve_vport_ops = { +static struct vport_ops ovs_geneve_vport_ops = { .type = OVS_VPORT_TYPE_GENEVE, .create = geneve_tnl_create, .destroy = geneve_tnl_destroy, .get_name = geneve_get_name, .get_options = geneve_get_options, .send = geneve_tnl_send, + .owner = THIS_MODULE, }; + +static int __init ovs_geneve_tnl_init(void) +{ + return ovs_vport_ops_register(&ovs_geneve_vport_ops); +} + +static void __exit ovs_geneve_tnl_exit(void) +{ + ovs_vport_ops_unregister(&ovs_geneve_vport_ops); +} + +module_init(ovs_geneve_tnl_init); +module_exit(ovs_geneve_tnl_exit); + +MODULE_DESCRIPTION("OVS: Geneve swiching port"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("vport-type-5"); diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 108b82da2fd9..00270b608844 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,8 @@ #include "datapath.h" #include "vport.h" +static struct vport_ops ovs_gre_vport_ops; + /* Returns the least-significant 32 bits of a __be64. */ static __be32 be64_get_low32(__be64 x) { @@ -281,10 +284,28 @@ static void gre_tnl_destroy(struct vport *vport) gre_exit(); } -const struct vport_ops ovs_gre_vport_ops = { +static struct vport_ops ovs_gre_vport_ops = { .type = OVS_VPORT_TYPE_GRE, .create = gre_create, .destroy = gre_tnl_destroy, .get_name = gre_get_name, .send = gre_tnl_send, + .owner = THIS_MODULE, }; + +static int __init ovs_gre_tnl_init(void) +{ + return ovs_vport_ops_register(&ovs_gre_vport_ops); +} + +static void __exit ovs_gre_tnl_exit(void) +{ + ovs_vport_ops_unregister(&ovs_gre_vport_ops); +} + +module_init(ovs_gre_tnl_init); +module_exit(ovs_gre_tnl_exit); + +MODULE_DESCRIPTION("OVS: GRE switching port"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("vport-type-3"); diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 84516126e5f3..10dc07e1678b 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -36,6 +36,8 @@ struct internal_dev { struct vport *vport; }; +static struct vport_ops ovs_internal_vport_ops; + static struct internal_dev *internal_dev_priv(struct net_device *netdev) { return netdev_priv(netdev); @@ -238,7 +240,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) return len; } -const struct vport_ops ovs_internal_vport_ops = { +static struct vport_ops ovs_internal_vport_ops = { .type = OVS_VPORT_TYPE_INTERNAL, .create = internal_dev_create, .destroy = internal_dev_destroy, @@ -261,10 +263,21 @@ struct vport *ovs_internal_dev_get_vport(struct net_device *netdev) int ovs_internal_dev_rtnl_link_register(void) { - return rtnl_link_register(&internal_dev_link_ops); + int err; + + err = rtnl_link_register(&internal_dev_link_ops); + if (err < 0) + return err; + + err = ovs_vport_ops_register(&ovs_internal_vport_ops); + if (err < 0) + rtnl_link_unregister(&internal_dev_link_ops); + + return err; } void ovs_internal_dev_rtnl_link_unregister(void) { + ovs_vport_ops_unregister(&ovs_internal_vport_ops); rtnl_link_unregister(&internal_dev_link_ops); } diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index d21f77d875ba..877ee74b4f08 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -33,6 +33,8 @@ #include "vport-internal_dev.h" #include "vport-netdev.h" +static struct vport_ops ovs_netdev_vport_ops; + /* Must be called with rcu_read_lock. */ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) { @@ -224,10 +226,20 @@ struct vport *ovs_netdev_get_vport(struct net_device *dev) return NULL; } -const struct vport_ops ovs_netdev_vport_ops = { +static struct vport_ops ovs_netdev_vport_ops = { .type = OVS_VPORT_TYPE_NETDEV, .create = netdev_create, .destroy = netdev_destroy, .get_name = ovs_netdev_get_name, .send = netdev_send, }; + +int __init ovs_netdev_init(void) +{ + return ovs_vport_ops_register(&ovs_netdev_vport_ops); +} + +void ovs_netdev_exit(void) +{ + ovs_vport_ops_unregister(&ovs_netdev_vport_ops); +} diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h index 8df01c1127e5..6f7038e79c52 100644 --- a/net/openvswitch/vport-netdev.h +++ b/net/openvswitch/vport-netdev.h @@ -41,4 +41,7 @@ netdev_vport_priv(const struct vport *vport) const char *ovs_netdev_get_name(const struct vport *); void ovs_netdev_detach_dev(struct vport *); +int __init ovs_netdev_init(void); +void ovs_netdev_exit(void); + #endif /* vport_netdev.h */ diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 2735e01dca73..965e7500c5a6 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,8 @@ struct vxlan_port { char name[IFNAMSIZ]; }; +static struct vport_ops ovs_vxlan_vport_ops; + static inline struct vxlan_port *vxlan_vport(const struct vport *vport) { return vport_priv(vport); @@ -192,11 +195,29 @@ static const char *vxlan_get_name(const struct vport *vport) return vxlan_port->name; } -const struct vport_ops ovs_vxlan_vport_ops = { +static struct vport_ops ovs_vxlan_vport_ops = { .type = OVS_VPORT_TYPE_VXLAN, .create = vxlan_tnl_create, .destroy = vxlan_tnl_destroy, .get_name = vxlan_get_name, .get_options = vxlan_get_options, .send = vxlan_tnl_send, + .owner = THIS_MODULE, }; + +static int __init ovs_vxlan_tnl_init(void) +{ + return ovs_vport_ops_register(&ovs_vxlan_vport_ops); +} + +static void __exit ovs_vxlan_tnl_exit(void) +{ + ovs_vport_ops_unregister(&ovs_vxlan_vport_ops); +} + +module_init(ovs_vxlan_tnl_init); +module_exit(ovs_vxlan_tnl_exit); + +MODULE_DESCRIPTION("OVS: VXLAN switching port"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("vport-type-4"); diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 6015802ebe6f..8168ef021337 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "datapath.h" #include "vport.h" @@ -36,22 +37,7 @@ static void ovs_vport_record_error(struct vport *, enum vport_err_type err_type); -/* List of statically compiled vport implementations. Don't forget to also - * add yours to the list at the bottom of vport.h. */ -static const struct vport_ops *vport_ops_list[] = { - &ovs_netdev_vport_ops, - &ovs_internal_vport_ops, - -#ifdef CONFIG_OPENVSWITCH_GRE - &ovs_gre_vport_ops, -#endif -#ifdef CONFIG_OPENVSWITCH_VXLAN - &ovs_vxlan_vport_ops, -#endif -#ifdef CONFIG_OPENVSWITCH_GENEVE - &ovs_geneve_vport_ops, -#endif -}; +static LIST_HEAD(vport_ops_list); /* Protected by RCU read lock for reading, ovs_mutex for writing. */ static struct hlist_head *dev_table; @@ -88,6 +74,32 @@ static struct hlist_head *hash_bucket(struct net *net, const char *name) return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; } +int ovs_vport_ops_register(struct vport_ops *ops) +{ + int err = -EEXIST; + struct vport_ops *o; + + ovs_lock(); + list_for_each_entry(o, &vport_ops_list, list) + if (ops->type == o->type) + goto errout; + + list_add_tail(&ops->list, &vport_ops_list); + err = 0; +errout: + ovs_unlock(); + return err; +} +EXPORT_SYMBOL(ovs_vport_ops_register); + +void ovs_vport_ops_unregister(struct vport_ops *ops) +{ + ovs_lock(); + list_del(&ops->list); + ovs_unlock(); +} +EXPORT_SYMBOL(ovs_vport_ops_unregister); + /** * ovs_vport_locate - find a port that has already been created * @@ -153,6 +165,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, return vport; } +EXPORT_SYMBOL(ovs_vport_alloc); /** * ovs_vport_free - uninitialize and free vport @@ -173,6 +186,18 @@ void ovs_vport_free(struct vport *vport) free_percpu(vport->percpu_stats); kfree(vport); } +EXPORT_SYMBOL(ovs_vport_free); + +static struct vport_ops *ovs_vport_lookup(const struct vport_parms *parms) +{ + struct vport_ops *ops; + + list_for_each_entry(ops, &vport_ops_list, list) + if (ops->type == parms->type) + return ops; + + return NULL; +} /** * ovs_vport_add - add vport device (for kernel callers) @@ -184,31 +209,40 @@ void ovs_vport_free(struct vport *vport) */ struct vport *ovs_vport_add(const struct vport_parms *parms) { + struct vport_ops *ops; struct vport *vport; - int err = 0; - int i; - for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) { - if (vport_ops_list[i]->type == parms->type) { - struct hlist_head *bucket; + ops = ovs_vport_lookup(parms); + if (ops) { + struct hlist_head *bucket; - vport = vport_ops_list[i]->create(parms); - if (IS_ERR(vport)) { - err = PTR_ERR(vport); - goto out; - } + if (!try_module_get(ops->owner)) + return ERR_PTR(-EAFNOSUPPORT); - bucket = hash_bucket(ovs_dp_get_net(vport->dp), - vport->ops->get_name(vport)); - hlist_add_head_rcu(&vport->hash_node, bucket); + vport = ops->create(parms); + if (IS_ERR(vport)) { + module_put(ops->owner); return vport; } + + bucket = hash_bucket(ovs_dp_get_net(vport->dp), + vport->ops->get_name(vport)); + hlist_add_head_rcu(&vport->hash_node, bucket); + return vport; } - err = -EAFNOSUPPORT; + /* Unlock to attempt module load and return -EAGAIN if load + * was successful as we need to restart the port addition + * workflow. + */ + ovs_unlock(); + request_module("vport-type-%d", parms->type); + ovs_lock(); -out: - return ERR_PTR(err); + if (!ovs_vport_lookup(parms)) + return ERR_PTR(-EAFNOSUPPORT); + else + return ERR_PTR(-EAGAIN); } /** @@ -242,6 +276,8 @@ void ovs_vport_del(struct vport *vport) hlist_del_rcu(&vport->hash_node); vport->ops->destroy(vport); + + module_put(vport->ops->owner); } /** @@ -457,6 +493,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, } ovs_dp_process_packet(skb, &key); } +EXPORT_SYMBOL(ovs_vport_receive); /** * ovs_vport_send - send a packet on a device @@ -535,3 +572,4 @@ void ovs_vport_deferred_free(struct vport *vport) call_rcu(&vport->rcu, free_vport_rcu); } +EXPORT_SYMBOL(ovs_vport_deferred_free); diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index 8942125de3a6..e41c3facf799 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h @@ -161,6 +161,9 @@ struct vport_ops { const char *(*get_name)(const struct vport *); int (*send)(struct vport *, struct sk_buff *); + + struct module *owner; + struct list_head list; }; enum vport_err_type { @@ -209,14 +212,6 @@ static inline struct vport *vport_from_priv(void *priv) void ovs_vport_receive(struct vport *, struct sk_buff *, struct ovs_tunnel_info *); -/* List of statically compiled vport implementations. Don't forget to also - * add yours to the list at the top of vport.c. */ -extern const struct vport_ops ovs_netdev_vport_ops; -extern const struct vport_ops ovs_internal_vport_ops; -extern const struct vport_ops ovs_gre_vport_ops; -extern const struct vport_ops ovs_vxlan_vport_ops; -extern const struct vport_ops ovs_geneve_vport_ops; - static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb, const void *start, unsigned int len) { @@ -224,4 +219,7 @@ static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb, skb->csum = csum_add(skb->csum, csum_partial(start, len, 0)); } +int ovs_vport_ops_register(struct vport_ops *ops); +void ovs_vport_ops_unregister(struct vport_ops *ops); + #endif /* vport.h */ -- GitLab From b02241755d0edc67204d475e746750bc754ead4f Mon Sep 17 00:00:00 2001 From: Viet Nga Dao Date: Thu, 23 Oct 2014 19:41:53 -0700 Subject: [PATCH 1688/9457] net: phy: Adding SGMII support for Marvell 88ee1145 driver Additional code to m88e1145_config_init function to allow the driver to support SGMII mode. Signed-off-by: Viet Nga Dao Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d2b2f2f795d5..3e3d7cadeb27 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -50,9 +50,13 @@ #define MII_M1011_PHY_SCR 0x10 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 +#define MII_M1145_PHY_EXT_SR 0x1b #define MII_M1145_PHY_EXT_CR 0x14 #define MII_M1145_RGMII_RX_DELAY 0x0080 #define MII_M1145_RGMII_TX_DELAY 0x0002 +#define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 +#define MII_M1145_HWCFG_MODE_MASK 0xf +#define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 #define MII_M1111_PHY_LED_CONTROL 0x18 #define MII_M1111_PHY_LED_DIRECT 0x4100 @@ -642,6 +646,7 @@ static int m88e1149_config_init(struct phy_device *phydev) static int m88e1145_config_init(struct phy_device *phydev) { int err; + int temp; /* Take care of errata E0 & E1 */ err = phy_write(phydev, 0x1d, 0x001b); @@ -698,6 +703,20 @@ static int m88e1145_config_init(struct phy_device *phydev) } } + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); + if (temp < 0) + return temp; + + temp &= ~(MII_M1145_HWCFG_MODE_MASK); + temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK; + temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO; + + err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp); + if (err < 0) + return err; + } + err = marvell_of_reg_init(phydev); if (err < 0) return err; -- GitLab From 95f259ca3bf485a0c1f17d9024813d4aab485a23 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Sat, 25 Oct 2014 12:08:59 +0200 Subject: [PATCH 1689/9457] net: pxa168_eth: Fix providing of phy_interface mode on platform_data Do not add phy include to the board file but platform_data include instead. Signed-off-by: Sebastian Hesselbarth Signed-off-by: David S. Miller --- arch/arm/mach-mmp/gplugd.c | 1 - include/linux/pxa168_eth.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index 3b5794cd0357..22762a1f9f72 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/include/linux/pxa168_eth.h b/include/linux/pxa168_eth.h index 37c381120bc8..e1ab6e86cdb3 100644 --- a/include/linux/pxa168_eth.h +++ b/include/linux/pxa168_eth.h @@ -4,6 +4,8 @@ #ifndef __LINUX_PXA168_ETH_H #define __LINUX_PXA168_ETH_H +#include + struct pxa168_eth_platform_data { int port_number; int phy_addr; -- GitLab From 941d8ebcf773fd5da5c79e1c86e1afaae7032a0b Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 27 Oct 2014 16:12:16 +0900 Subject: [PATCH 1690/9457] datapath: Rename last_action() as nla_is_last() and move to netlink.h The original motivation for this change was to allow the helper to be used in files other than actions.c as part of work on an odp select group action. It was as pointed out by Thomas Graf that this helper would be best off living in netlink.h. Furthermore, I think that the generic nature of this helper means it is best off in netlink.h regardless of if it is used more than one .c file or not. Thus, I would like it considered independent of the work on an odp select group action. Cc: Thomas Graf Cc: Pravin Shelar Cc: Andy Zhou Signed-off-by: Simon Horman Acked-by: Thomas Graf Signed-off-by: David S. Miller --- include/net/netlink.h | 10 ++++++++++ net/openvswitch/actions.c | 11 +++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 7b903e1bdbbb..64158353ecb2 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -1185,4 +1185,14 @@ static inline int nla_validate_nested(const struct nlattr *start, int maxtype, #define nla_for_each_nested(pos, nla, rem) \ nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem) +/** + * nla_is_last - Test if attribute is last in stream + * @nla: attribute to test + * @rem: bytes remaining in stream + */ +static inline bool nla_is_last(const struct nlattr *nla, int rem) +{ + return nla->nla_len == rem; +} + #endif diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 006886dbee36..922c133b1933 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -504,11 +504,6 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, return ovs_dp_upcall(dp, skb, &upcall); } -static bool last_action(const struct nlattr *a, int rem) -{ - return a->nla_len == rem; -} - static int sample(struct datapath *dp, struct sk_buff *skb, struct sw_flow_key *key, const struct nlattr *attr) { @@ -543,7 +538,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb, * user space. This skb will be consumed by its caller. */ if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE && - last_action(a, rem))) + nla_is_last(a, rem))) return output_userspace(dp, skb, key, a); skb = skb_clone(skb, GFP_ATOMIC); @@ -633,7 +628,7 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb, if (err) return err; - if (!last_action(a, rem)) { + if (!nla_is_last(a, rem)) { /* Recirc action is the not the last action * of the action list, need to clone the skb. */ @@ -707,7 +702,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, case OVS_ACTION_ATTR_RECIRC: err = execute_recirc(dp, skb, key, a, rem); - if (last_action(a, rem)) { + if (nla_is_last(a, rem)) { /* If this is the last action, the skb has * been consumed or freed. * Return immediately. -- GitLab From 32a173c7f9e9ec2b87142f67e1478cd20084a45b Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:35 +0200 Subject: [PATCH 1691/9457] net/mlx4_core: Introduce mlx4_get_module_info for cable module info reading Added new MAD_IFC command to read cable module info with attribute id (0xFF60). Update include/linux/mlx4/device.h with function declaration (mlx4_get_module_info) and the needed defines/enums for future use. Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/port.c | 156 ++++++++++++++++++++++ include/linux/mlx4/device.h | 30 +++++ 2 files changed, 186 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 94eeb2c7d7e4..30eb1ead0fe6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -1311,3 +1311,159 @@ int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, return 0; } EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); + +/* Cable Module Info */ +#define MODULE_INFO_MAX_READ 48 + +#define I2C_ADDR_LOW 0x50 +#define I2C_ADDR_HIGH 0x51 +#define I2C_PAGE_SIZE 256 + +/* Module Info Data */ +struct mlx4_cable_info { + u8 i2c_addr; + u8 page_num; + __be16 dev_mem_address; + __be16 reserved1; + __be16 size; + __be32 reserved2[2]; + u8 data[MODULE_INFO_MAX_READ]; +}; + +enum cable_info_err { + CABLE_INF_INV_PORT = 0x1, + CABLE_INF_OP_NOSUP = 0x2, + CABLE_INF_NOT_CONN = 0x3, + CABLE_INF_NO_EEPRM = 0x4, + CABLE_INF_PAGE_ERR = 0x5, + CABLE_INF_INV_ADDR = 0x6, + CABLE_INF_I2C_ADDR = 0x7, + CABLE_INF_QSFP_VIO = 0x8, + CABLE_INF_I2C_BUSY = 0x9, +}; + +#define MAD_STATUS_2_CABLE_ERR(mad_status) ((mad_status >> 8) & 0xFF) + +static inline const char *cable_info_mad_err_str(u16 mad_status) +{ + u8 err = MAD_STATUS_2_CABLE_ERR(mad_status); + + switch (err) { + case CABLE_INF_INV_PORT: + return "invalid port selected"; + case CABLE_INF_OP_NOSUP: + return "operation not supported for this port (the port is of type CX4 or internal)"; + case CABLE_INF_NOT_CONN: + return "cable is not connected"; + case CABLE_INF_NO_EEPRM: + return "the connected cable has no EPROM (passive copper cable)"; + case CABLE_INF_PAGE_ERR: + return "page number is greater than 15"; + case CABLE_INF_INV_ADDR: + return "invalid device_address or size (that is, size equals 0 or address+size is greater than 256)"; + case CABLE_INF_I2C_ADDR: + return "invalid I2C slave address"; + case CABLE_INF_QSFP_VIO: + return "at least one cable violates the QSFP specification and ignores the modsel signal"; + case CABLE_INF_I2C_BUSY: + return "I2C bus is constantly busy"; + } + return "Unknown Error"; +} + +/** + * mlx4_get_module_info - Read cable module eeprom data + * @dev: mlx4_dev. + * @port: port number. + * @offset: byte offset in eeprom to start reading data from. + * @size: num of bytes to read. + * @data: output buffer to put the requested data into. + * + * Reads cable module eeprom data, puts the outcome data into + * data pointer paramer. + * Returns num of read bytes on success or a negative error + * code. + */ +int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + u16 offset, u16 size, u8 *data) +{ + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; + u16 i2c_addr; + int ret; + + if (size > MODULE_INFO_MAX_READ) + size = MODULE_INFO_MAX_READ; + + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); + + outbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(outbox)) { + mlx4_free_cmd_mailbox(dev, inbox); + return PTR_ERR(outbox); + } + + inmad = (struct mlx4_mad_ifc *)(inbox->buf); + outmad = (struct mlx4_mad_ifc *)(outbox->buf); + + inmad->method = 0x1; /* Get */ + inmad->class_version = 0x1; + inmad->mgmt_class = 0x1; + inmad->base_version = 0x1; + inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ + + if (offset < I2C_PAGE_SIZE && offset + size > I2C_PAGE_SIZE) + /* Cross pages reads are not allowed + * read until offset 256 in low page + */ + size -= offset + size - I2C_PAGE_SIZE; + + i2c_addr = I2C_ADDR_LOW; + if (offset >= I2C_PAGE_SIZE) { + /* Reset offset to high page */ + i2c_addr = I2C_ADDR_HIGH; + offset -= I2C_PAGE_SIZE; + } + + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = cpu_to_be16(offset); + cable_info->page_num = 0; + cable_info->i2c_addr = i2c_addr; + cable_info->size = cpu_to_be16(size); + + ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, + MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (ret) + goto out; + + if (be16_to_cpu(outmad->status)) { + /* Mad returned with bad status */ + ret = be16_to_cpu(outmad->status); + mlx4_warn(dev, + "MLX4_CMD_MAD_IFC Get Module info attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", + 0xFF60, port, i2c_addr, offset, size, + ret, cable_info_mad_err_str(ret)); + + if (i2c_addr == I2C_ADDR_HIGH && + MAD_STATUS_2_CABLE_ERR(ret) == CABLE_INF_I2C_ADDR) + /* Some SFP cables do not support i2c slave + * address 0x51 (high page), abort silently. + */ + ret = 0; + else + ret = -ret; + goto out; + } + cable_info = (struct mlx4_cable_info *)outmad->data; + memcpy(data, cable_info->data, size); + ret = size; +out: + mlx4_free_cmd_mailbox(dev, inbox); + mlx4_free_cmd_mailbox(dev, outbox); + return ret; +} +EXPORT_SYMBOL(mlx4_get_module_info); diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 37e4404d0227..73910daec317 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -379,6 +379,13 @@ enum { #define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \ MLX4_EQ_PORT_INFO_MSTR_SM_LID_CHANGE_MASK) +enum mlx4_module_id { + MLX4_MODULE_ID_SFP = 0x3, + MLX4_MODULE_ID_QSFP = 0xC, + MLX4_MODULE_ID_QSFP_PLUS = 0xD, + MLX4_MODULE_ID_QSFP28 = 0x11, +}; + static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor) { return (major << 32) | (minor << 16) | subminor; @@ -799,6 +806,26 @@ struct mlx4_init_port_param { u64 si_guid; }; +#define MAD_IFC_DATA_SZ 192 +/* MAD IFC Mailbox */ +struct mlx4_mad_ifc { + u8 base_version; + u8 mgmt_class; + u8 class_version; + u8 method; + __be16 status; + __be16 class_specific; + __be64 tid; + __be16 attr_id; + __be16 resv; + __be32 attr_mod; + __be64 mkey; + __be16 dr_slid; + __be16 dr_dlid; + u8 reserved[28]; + u8 data[MAD_IFC_DATA_SZ]; +} __packed; + #define mlx4_foreach_port(port, dev, type) \ for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++) \ if ((type) == (dev)->caps.port_mask[(port)]) @@ -1283,6 +1310,9 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, u64 iova, u64 size, int npages, int page_shift, struct mlx4_mpt_entry *mpt_entry); +int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + u16 offset, u16 size, u8 *data); + /* Returns true if running in low memory profile (kdump kernel) */ static inline bool mlx4_low_memory_profile(void) { -- GitLab From 7202da8b7f7131d25411d81aa557e28cd941c5b6 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:36 +0200 Subject: [PATCH 1692/9457] ethtool, net/mlx4_en: Cable info, get_module_info/eeprom ethtool support Added support for get_module_info/get_module_eeprom ethtool support for cable info reading. Added new cable types enum in include/uapi/linux/ethtool.h for ethtool use. +#define ETH_MODULE_SFF_8636 0x3 +#define ETH_MODULE_SFF_8636_LEN 256 +#define ETH_MODULE_SFF_8436 0x4 +#define ETH_MODULE_SFF_8436_LEN 256 Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 83 +++++++++++++++++++ include/uapi/linux/ethtool.h | 4 + 2 files changed, 87 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index ae83da9cd18a..279f4233de59 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -1309,6 +1310,86 @@ static int mlx4_en_set_tunable(struct net_device *dev, return ret; } +static int mlx4_en_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + int ret; + u8 data[4]; + + /* Read first 2 bytes to get Module & REV ID */ + ret = mlx4_get_module_info(mdev->dev, priv->port, + 0/*offset*/, 2/*size*/, data); + if (ret < 2) + return -EIO; + + switch (data[0] /* identifier */) { + case MLX4_MODULE_ID_QSFP: + modinfo->type = ETH_MODULE_SFF_8436; + modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; + break; + case MLX4_MODULE_ID_QSFP_PLUS: + if (data[1] >= 0x3) { /* revision id */ + modinfo->type = ETH_MODULE_SFF_8636; + modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; + } else { + modinfo->type = ETH_MODULE_SFF_8436; + modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; + } + break; + case MLX4_MODULE_ID_QSFP28: + modinfo->type = ETH_MODULE_SFF_8636; + modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; + break; + case MLX4_MODULE_ID_SFP: + modinfo->type = ETH_MODULE_SFF_8472; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + break; + default: + return -ENOSYS; + } + + return 0; +} + +static int mlx4_en_get_module_eeprom(struct net_device *dev, + struct ethtool_eeprom *ee, + u8 *data) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + int offset = ee->offset; + int i = 0, ret; + + if (ee->len == 0) + return -EINVAL; + + memset(data, 0, ee->len); + + while (i < ee->len) { + en_dbg(DRV, priv, + "mlx4_get_module_info i(%d) offset(%d) len(%d)\n", + i, offset, ee->len - i); + + ret = mlx4_get_module_info(mdev->dev, priv->port, + offset, ee->len - i, data + i); + + if (!ret) /* Done reading */ + return 0; + + if (ret < 0) { + en_err(priv, + "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n", + i, offset, ee->len - i, ret); + return 0; + } + + i += ret; + offset += ret; + } + return 0; +} const struct ethtool_ops mlx4_en_ethtool_ops = { .get_drvinfo = mlx4_en_get_drvinfo, @@ -1341,6 +1422,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_priv_flags = mlx4_en_get_priv_flags, .get_tunable = mlx4_en_get_tunable, .set_tunable = mlx4_en_set_tunable, + .get_module_info = mlx4_en_get_module_info, + .get_module_eeprom = mlx4_en_get_module_eeprom }; diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 99b43056a6fe..b6acd78b821c 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1343,6 +1343,10 @@ enum ethtool_sfeatures_retval_bits { #define ETH_MODULE_SFF_8079_LEN 256 #define ETH_MODULE_SFF_8472 0x2 #define ETH_MODULE_SFF_8472_LEN 512 +#define ETH_MODULE_SFF_8636 0x3 +#define ETH_MODULE_SFF_8636_LEN 256 +#define ETH_MODULE_SFF_8436 0x4 +#define ETH_MODULE_SFF_8436_LEN 256 /* Reset flags */ /* The reset() operation must clear the flags for the components which -- GitLab From adbc7ac5c15eb5e9d70393428345e72a1a897d6a Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:37 +0200 Subject: [PATCH 1693/9457] net/mlx4_core: Introduce ACCESS_REG CMD and eth_prot_ctrl dev cap Adding ACCESS REG mlx4 command and use it to implement Query method for PTYS (Port Type and Speed Register). Query and store eth_prot_ctrl dev cap. Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 ++ drivers/net/ethernet/mellanox/mlx4/fw.c | 118 ++++++++++++++++++++++- include/linux/mlx4/cmd.h | 2 + include/linux/mlx4/device.h | 40 +++++++- 4 files changed, 166 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index b16e1b95566f..916459effcfa 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1338,6 +1338,15 @@ static struct mlx4_cmd_info cmd_info[] = { .verify = NULL, .wrapper = mlx4_QUERY_IF_STAT_wrapper }, + { + .opcode = MLX4_CMD_ACCESS_REG, + .has_inbox = true, + .has_outbox = true, + .out_is_imm = false, + .encode_slave_id = false, + .verify = NULL, + .wrapper = NULL, + }, /* Native multicast commands are not available for guests */ { .opcode = MLX4_CMD_QP_ATTACH, diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 2e88a235e26b..6fd9b8581e95 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -139,7 +139,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [10] = "TCP/IP offloads/flow-steering for VXLAN support", [11] = "MAD DEMUX (Secure-Host) support", [12] = "Large cache line (>64B) CQE stride support", - [13] = "Large cache line (>64B) EQE stride support" + [13] = "Large cache line (>64B) EQE stride support", + [14] = "Ethernet protocol control support" }; int i; @@ -560,6 +561,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 #define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 #define QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE 0x7a +#define QUERY_DEV_CAP_ETH_PROT_CTRL_OFFSET 0x7a #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 @@ -737,11 +739,12 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET); dev_cap->max_rq_desc_sz = size; MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE); + if (field & (1 << 5)) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL; if (field & (1 << 6)) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CQE_STRIDE; if (field & (1 << 7)) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE; - MLX4_GET(dev_cap->bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); MLX4_GET(dev_cap->reserved_lkey, outbox, @@ -2144,3 +2147,114 @@ int mlx4_config_mad_demux(struct mlx4_dev *dev) mlx4_free_cmd_mailbox(dev, mailbox); return err; } + +/* Access Reg commands */ +enum mlx4_access_reg_masks { + MLX4_ACCESS_REG_STATUS_MASK = 0x7f, + MLX4_ACCESS_REG_METHOD_MASK = 0x7f, + MLX4_ACCESS_REG_LEN_MASK = 0x7ff +}; + +struct mlx4_access_reg { + __be16 constant1; + u8 status; + u8 resrvd1; + __be16 reg_id; + u8 method; + u8 constant2; + __be32 resrvd2[2]; + __be16 len_const; + __be16 resrvd3; +#define MLX4_ACCESS_REG_HEADER_SIZE (20) + u8 reg_data[MLX4_MAILBOX_SIZE-MLX4_ACCESS_REG_HEADER_SIZE]; +} __attribute__((__packed__)); + +/** + * mlx4_ACCESS_REG - Generic access reg command. + * @dev: mlx4_dev. + * @reg_id: register ID to access. + * @method: Access method Read/Write. + * @reg_len: register length to Read/Write in bytes. + * @reg_data: reg_data pointer to Read/Write From/To. + * + * Access ConnectX registers FW command. + * Returns 0 on success and copies outbox mlx4_access_reg data + * field into reg_data or a negative error code. + */ +static int mlx4_ACCESS_REG(struct mlx4_dev *dev, u16 reg_id, + enum mlx4_access_reg_method method, + u16 reg_len, void *reg_data) +{ + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_access_reg *inbuf, *outbuf; + int err; + + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); + + outbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(outbox)) { + mlx4_free_cmd_mailbox(dev, inbox); + return PTR_ERR(outbox); + } + + inbuf = inbox->buf; + outbuf = outbox->buf; + + inbuf->constant1 = cpu_to_be16(0x1<<11 | 0x4); + inbuf->constant2 = 0x1; + inbuf->reg_id = cpu_to_be16(reg_id); + inbuf->method = method & MLX4_ACCESS_REG_METHOD_MASK; + + reg_len = min(reg_len, (u16)(sizeof(inbuf->reg_data))); + inbuf->len_const = + cpu_to_be16(((reg_len/4 + 1) & MLX4_ACCESS_REG_LEN_MASK) | + ((0x3) << 12)); + + memcpy(inbuf->reg_data, reg_data, reg_len); + err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 0, 0, + MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (err) + goto out; + + if (outbuf->status & MLX4_ACCESS_REG_STATUS_MASK) { + err = outbuf->status & MLX4_ACCESS_REG_STATUS_MASK; + mlx4_err(dev, + "MLX4_CMD_ACCESS_REG(%x) returned REG status (%x)\n", + reg_id, err); + goto out; + } + + memcpy(reg_data, outbuf->reg_data, reg_len); +out: + mlx4_free_cmd_mailbox(dev, inbox); + mlx4_free_cmd_mailbox(dev, outbox); + return err; +} + +/* ConnectX registers IDs */ +enum mlx4_reg_id { + MLX4_REG_ID_PTYS = 0x5004, +}; + +/** + * mlx4_ACCESS_PTYS_REG - Access PTYs (Port Type and Speed) + * register + * @dev: mlx4_dev. + * @method: Access method Read/Write. + * @ptys_reg: PTYS register data pointer. + * + * Access ConnectX PTYS register, to Read/Write Port Type/Speed + * configuration + * Returns 0 on success or a negative error code. + */ +int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev, + enum mlx4_access_reg_method method, + struct mlx4_ptys_reg *ptys_reg) +{ + return mlx4_ACCESS_REG(dev, MLX4_REG_ID_PTYS, + method, sizeof(*ptys_reg), ptys_reg); +} +EXPORT_SYMBOL_GPL(mlx4_ACCESS_PTYS_REG); diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 379c02648ab3..ff5f5deb3dcf 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -67,6 +67,8 @@ enum { MLX4_CMD_MAP_ICM_AUX = 0xffc, MLX4_CMD_UNMAP_ICM_AUX = 0xffb, MLX4_CMD_SET_ICM_SIZE = 0xffd, + MLX4_CMD_ACCESS_REG = 0x3b, + /*master notify fw on finish for slave's flr*/ MLX4_CMD_INFORM_FLR_DONE = 0x5b, MLX4_CMD_GET_OP_REQ = 0x59, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 73910daec317..181cd9fc90f2 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -186,7 +186,8 @@ enum { MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS = 1LL << 10, MLX4_DEV_CAP_FLAG2_MAD_DEMUX = 1LL << 11, MLX4_DEV_CAP_FLAG2_CQE_STRIDE = 1LL << 12, - MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13 + MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, + MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14 }; enum { @@ -1319,4 +1320,41 @@ static inline bool mlx4_low_memory_profile(void) return is_kdump_kernel(); } +/* ACCESS REG commands */ +enum mlx4_access_reg_method { + MLX4_ACCESS_REG_QUERY = 0x1, + MLX4_ACCESS_REG_WRITE = 0x2, +}; + +/* ACCESS PTYS Reg command */ +enum mlx4_ptys_proto { + MLX4_PTYS_IB = 1<<0, + MLX4_PTYS_EN = 1<<2, +}; + +struct mlx4_ptys_reg { + u8 resrvd1; + u8 local_port; + u8 resrvd2; + u8 proto_mask; + __be32 resrvd3[2]; + __be32 eth_proto_cap; + __be16 ib_width_cap; + __be16 ib_speed_cap; + __be32 resrvd4; + __be32 eth_proto_admin; + __be16 ib_width_admin; + __be16 ib_speed_admin; + __be32 resrvd5; + __be32 eth_proto_oper; + __be16 ib_width_oper; + __be16 ib_speed_oper; + __be32 resrvd6; + __be32 eth_proto_lp_adv; +} __packed; + +int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev, + enum mlx4_access_reg_method method, + struct mlx4_ptys_reg *ptys_reg); + #endif /* MLX4_DEVICE_H */ -- GitLab From a53e3e8c1db547981e13d1ebf24a659bd4e87710 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:38 +0200 Subject: [PATCH 1694/9457] net/mlx4_core: Add ethernet backplane autoneg device capability Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 7 ++++++- include/linux/mlx4/device.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 6fd9b8581e95..72289ef5ebbe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -140,7 +140,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [11] = "MAD DEMUX (Secure-Host) support", [12] = "Large cache line (>64B) CQE stride support", [13] = "Large cache line (>64B) EQE stride support", - [14] = "Ethernet protocol control support" + [14] = "Ethernet protocol control support", + [15] = "Ethernet Backplane autoneg support" }; int i; @@ -575,6 +576,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_BMME_FLAGS_OFFSET 0x94 #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 +#define QUERY_DEV_CAP_ETH_BACKPL_OFFSET 0x9c #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d #define QUERY_DEV_CAP_VXLAN 0x9e #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 @@ -749,6 +751,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) QUERY_DEV_CAP_BMME_FLAGS_OFFSET); MLX4_GET(dev_cap->reserved_lkey, outbox, QUERY_DEV_CAP_RSVD_LKEY_OFFSET); + MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET); + if (field32 & (1 << 0)) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP; MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC); if (field & 1<<6) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 181cd9fc90f2..e4c136ebe79b 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -187,7 +187,8 @@ enum { MLX4_DEV_CAP_FLAG2_MAD_DEMUX = 1LL << 11, MLX4_DEV_CAP_FLAG2_CQE_STRIDE = 1LL << 12, MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, - MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14 + MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, + MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15 }; enum { -- GitLab From dcf972a334dd76975bf144ca57350c1f3132c947 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:39 +0200 Subject: [PATCH 1695/9457] ethtool, net/mlx4_en: Add 100M, 20G, 56G speeds ethtool reporting support Added 100M, 20G and 56G ethtool speed reporting support. Update mlx4_en_test_speed self test with the new speeds. Defined new link speeds in include/uapi/linux/ethtool.h: +#define SPEED_20000 20000 +#define SPEED_40000 40000 +#define SPEED_56000 56000 Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_port.c | 15 ++++++++++++--- drivers/net/ethernet/mellanox/mlx4/en_port.h | 9 ++++++--- drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 12 ++++++++---- include/uapi/linux/ethtool.h | 14 +++++++++++++- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index 0a0261d128b9..afd303662d17 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c @@ -91,15 +91,24 @@ int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) * already synchronized, no need in locking */ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); switch (qport_context->link_speed & MLX4_EN_SPEED_MASK) { + case MLX4_EN_100M_SPEED: + state->link_speed = SPEED_100; + break; case MLX4_EN_1G_SPEED: - state->link_speed = 1000; + state->link_speed = SPEED_1000; break; case MLX4_EN_10G_SPEED_XAUI: case MLX4_EN_10G_SPEED_XFI: - state->link_speed = 10000; + state->link_speed = SPEED_10000; + break; + case MLX4_EN_20G_SPEED: + state->link_speed = SPEED_20000; break; case MLX4_EN_40G_SPEED: - state->link_speed = 40000; + state->link_speed = SPEED_40000; + break; + case MLX4_EN_56G_SPEED: + state->link_speed = SPEED_56000; break; default: state->link_speed = -1; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.h b/drivers/net/ethernet/mellanox/mlx4/en_port.h index 745090b49d9e..a5fc93bfe5da 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.h +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.h @@ -54,10 +54,13 @@ enum { }; enum { - MLX4_EN_1G_SPEED = 0x02, - MLX4_EN_10G_SPEED_XFI = 0x01, + MLX4_EN_100M_SPEED = 0x04, MLX4_EN_10G_SPEED_XAUI = 0x00, + MLX4_EN_10G_SPEED_XFI = 0x01, + MLX4_EN_1G_SPEED = 0x02, + MLX4_EN_20G_SPEED = 0x08, MLX4_EN_40G_SPEED = 0x40, + MLX4_EN_56G_SPEED = 0x20, MLX4_EN_OTHER_SPEED = 0x0f, }; @@ -68,7 +71,7 @@ struct mlx4_en_query_port_context { __be16 mtu; u8 reserved2; u8 link_speed; -#define MLX4_EN_SPEED_MASK 0x43 +#define MLX4_EN_SPEED_MASK 0x6f u16 reserved3[5]; __be64 mac; u8 transceiver; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c index 49d5afc7cfb8..2d8ee66138e8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c @@ -129,11 +129,15 @@ static int mlx4_en_test_speed(struct mlx4_en_priv *priv) if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) return -ENOMEM; - /* The device supports 1G, 10G and 40G speeds */ - if (priv->port_state.link_speed != 1000 && - priv->port_state.link_speed != 10000 && - priv->port_state.link_speed != 40000) + /* The device supports 100M, 1G, 10G, 20G, 40G and 56G speed */ + if (priv->port_state.link_speed != SPEED_100 && + priv->port_state.link_speed != SPEED_1000 && + priv->port_state.link_speed != SPEED_10000 && + priv->port_state.link_speed != SPEED_20000 && + priv->port_state.link_speed != SPEED_40000 && + priv->port_state.link_speed != SPEED_56000) return priv->port_state.link_speed; + return 0; } diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index b6acd78b821c..eb2095b42fbb 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1213,6 +1213,10 @@ enum ethtool_sfeatures_retval_bits { #define SUPPORTED_40000baseCR4_Full (1 << 24) #define SUPPORTED_40000baseSR4_Full (1 << 25) #define SUPPORTED_40000baseLR4_Full (1 << 26) +#define SUPPORTED_56000baseKR4_Full (1 << 27) +#define SUPPORTED_56000baseCR4_Full (1 << 28) +#define SUPPORTED_56000baseSR4_Full (1 << 29) +#define SUPPORTED_56000baseLR4_Full (1 << 30) #define ADVERTISED_10baseT_Half (1 << 0) #define ADVERTISED_10baseT_Full (1 << 1) @@ -1241,6 +1245,10 @@ enum ethtool_sfeatures_retval_bits { #define ADVERTISED_40000baseCR4_Full (1 << 24) #define ADVERTISED_40000baseSR4_Full (1 << 25) #define ADVERTISED_40000baseLR4_Full (1 << 26) +#define ADVERTISED_56000baseKR4_Full (1 << 27) +#define ADVERTISED_56000baseCR4_Full (1 << 28) +#define ADVERTISED_56000baseSR4_Full (1 << 29) +#define ADVERTISED_56000baseLR4_Full (1 << 30) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the @@ -1248,12 +1256,16 @@ enum ethtool_sfeatures_retval_bits { * it was forced up into this mode or autonegotiated. */ -/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */ +/* The forced speed, 10Mb, 100Mb, gigabit, [2.5|10|20|40|56]GbE. */ #define SPEED_10 10 #define SPEED_100 100 #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_10000 10000 +#define SPEED_20000 20000 +#define SPEED_40000 40000 +#define SPEED_56000 56000 + #define SPEED_UNKNOWN -1 /* Duplex, half or full. */ -- GitLab From 2c762679435dc812b7031ef9a839b901827294a9 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:40 +0200 Subject: [PATCH 1696/9457] net/mlx4_en: Use PTYS register to query ethtool settings - If dev cap MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL is ON, query PTYS register to fill ethtool settings. else use default values. - Use autoneg port cap and dev backplane autoneg cap to reprort autoneg interface capbilities. - Fix typo in mlx4_en_port_state struct field (transciver to transceiver). Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 311 +++++++++++++++++- drivers/net/ethernet/mellanox/mlx4/en_port.c | 9 +- drivers/net/ethernet/mellanox/mlx4/en_port.h | 26 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 8 +- 4 files changed, 338 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 279f4233de59..64b6743afdd2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -375,7 +375,277 @@ static void mlx4_en_get_strings(struct net_device *dev, } } -static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static u32 mlx4_en_autoneg_get(struct net_device *dev) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + u32 autoneg = AUTONEG_DISABLE; + + if ((mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP) && + (priv->port_state.flags & MLX4_EN_PORT_ANE)) + autoneg = AUTONEG_ENABLE; + + return autoneg; +} + +static u32 ptys_get_supported_port(struct mlx4_ptys_reg *ptys_reg) +{ + u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap); + + if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_T) + | MLX4_PROT_MASK(MLX4_1000BASE_T) + | MLX4_PROT_MASK(MLX4_100BASE_TX))) { + return SUPPORTED_TP; + } + + if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR) + | MLX4_PROT_MASK(MLX4_10GBASE_SR) + | MLX4_PROT_MASK(MLX4_56GBASE_SR4) + | MLX4_PROT_MASK(MLX4_40GBASE_CR4) + | MLX4_PROT_MASK(MLX4_40GBASE_SR4) + | MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII))) { + return SUPPORTED_FIBRE; + } + + if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4) + | MLX4_PROT_MASK(MLX4_40GBASE_KR4) + | MLX4_PROT_MASK(MLX4_20GBASE_KR2) + | MLX4_PROT_MASK(MLX4_10GBASE_KR) + | MLX4_PROT_MASK(MLX4_10GBASE_KX4) + | MLX4_PROT_MASK(MLX4_1000BASE_KX))) { + return SUPPORTED_Backplane; + } + return 0; +} + +static u32 ptys_get_active_port(struct mlx4_ptys_reg *ptys_reg) +{ + u32 eth_proto = be32_to_cpu(ptys_reg->eth_proto_oper); + + if (!eth_proto) /* link down */ + eth_proto = be32_to_cpu(ptys_reg->eth_proto_cap); + + if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_T) + | MLX4_PROT_MASK(MLX4_1000BASE_T) + | MLX4_PROT_MASK(MLX4_100BASE_TX))) { + return PORT_TP; + } + + if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_SR) + | MLX4_PROT_MASK(MLX4_56GBASE_SR4) + | MLX4_PROT_MASK(MLX4_40GBASE_SR4) + | MLX4_PROT_MASK(MLX4_1000BASE_CX_SGMII))) { + return PORT_FIBRE; + } + + if (eth_proto & (MLX4_PROT_MASK(MLX4_10GBASE_CR) + | MLX4_PROT_MASK(MLX4_56GBASE_CR4) + | MLX4_PROT_MASK(MLX4_40GBASE_CR4))) { + return PORT_DA; + } + + if (eth_proto & (MLX4_PROT_MASK(MLX4_56GBASE_KR4) + | MLX4_PROT_MASK(MLX4_40GBASE_KR4) + | MLX4_PROT_MASK(MLX4_20GBASE_KR2) + | MLX4_PROT_MASK(MLX4_10GBASE_KR) + | MLX4_PROT_MASK(MLX4_10GBASE_KX4) + | MLX4_PROT_MASK(MLX4_1000BASE_KX))) { + return PORT_NONE; + } + return PORT_OTHER; +} + +#define MLX4_LINK_MODES_SZ \ + (FIELD_SIZEOF(struct mlx4_ptys_reg, eth_proto_cap) * 8) + +enum ethtool_report { + SUPPORTED = 0, + ADVERTISED = 1, + SPEED = 2 +}; + +/* Translates mlx4 link mode to equivalent ethtool Link modes/speed */ +static u32 ptys2ethtool_map[MLX4_LINK_MODES_SZ][3] = { + [MLX4_100BASE_TX] = { + SUPPORTED_100baseT_Full, + ADVERTISED_100baseT_Full, + SPEED_100 + }, + + [MLX4_1000BASE_T] = { + SUPPORTED_1000baseT_Full, + ADVERTISED_1000baseT_Full, + SPEED_1000 + }, + [MLX4_1000BASE_CX_SGMII] = { + SUPPORTED_1000baseKX_Full, + ADVERTISED_1000baseKX_Full, + SPEED_1000 + }, + [MLX4_1000BASE_KX] = { + SUPPORTED_1000baseKX_Full, + ADVERTISED_1000baseKX_Full, + SPEED_1000 + }, + + [MLX4_10GBASE_T] = { + SUPPORTED_10000baseT_Full, + ADVERTISED_10000baseT_Full, + SPEED_10000 + }, + [MLX4_10GBASE_CX4] = { + SUPPORTED_10000baseKX4_Full, + ADVERTISED_10000baseKX4_Full, + SPEED_10000 + }, + [MLX4_10GBASE_KX4] = { + SUPPORTED_10000baseKX4_Full, + ADVERTISED_10000baseKX4_Full, + SPEED_10000 + }, + [MLX4_10GBASE_KR] = { + SUPPORTED_10000baseKR_Full, + ADVERTISED_10000baseKR_Full, + SPEED_10000 + }, + [MLX4_10GBASE_CR] = { + SUPPORTED_10000baseKR_Full, + ADVERTISED_10000baseKR_Full, + SPEED_10000 + }, + [MLX4_10GBASE_SR] = { + SUPPORTED_10000baseKR_Full, + ADVERTISED_10000baseKR_Full, + SPEED_10000 + }, + + [MLX4_20GBASE_KR2] = { + SUPPORTED_20000baseMLD2_Full | SUPPORTED_20000baseKR2_Full, + ADVERTISED_20000baseMLD2_Full | ADVERTISED_20000baseKR2_Full, + SPEED_20000 + }, + + [MLX4_40GBASE_CR4] = { + SUPPORTED_40000baseCR4_Full, + ADVERTISED_40000baseCR4_Full, + SPEED_40000 + }, + [MLX4_40GBASE_KR4] = { + SUPPORTED_40000baseKR4_Full, + ADVERTISED_40000baseKR4_Full, + SPEED_40000 + }, + [MLX4_40GBASE_SR4] = { + SUPPORTED_40000baseSR4_Full, + ADVERTISED_40000baseSR4_Full, + SPEED_40000 + }, + + [MLX4_56GBASE_KR4] = { + SUPPORTED_56000baseKR4_Full, + ADVERTISED_56000baseKR4_Full, + SPEED_56000 + }, + [MLX4_56GBASE_CR4] = { + SUPPORTED_56000baseCR4_Full, + ADVERTISED_56000baseCR4_Full, + SPEED_56000 + }, + [MLX4_56GBASE_SR4] = { + SUPPORTED_56000baseSR4_Full, + ADVERTISED_56000baseSR4_Full, + SPEED_56000 + }, +}; + +static u32 ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report) +{ + int i; + u32 link_modes = 0; + + for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { + if (eth_proto & MLX4_PROT_MASK(i)) + link_modes |= ptys2ethtool_map[i][report]; + } + return link_modes; +} + +static int ethtool_get_ptys_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_ptys_reg ptys_reg; + u32 eth_proto; + int ret; + + memset(&ptys_reg, 0, sizeof(ptys_reg)); + ptys_reg.local_port = priv->port; + ptys_reg.proto_mask = MLX4_PTYS_EN; + ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev, + MLX4_ACCESS_REG_QUERY, &ptys_reg); + if (ret) { + en_warn(priv, "Failed to run mlx4_ACCESS_PTYS_REG status(%x)", + ret); + return ret; + } + en_dbg(DRV, priv, "ptys_reg.proto_mask %x\n", + ptys_reg.proto_mask); + en_dbg(DRV, priv, "ptys_reg.eth_proto_cap %x\n", + be32_to_cpu(ptys_reg.eth_proto_cap)); + en_dbg(DRV, priv, "ptys_reg.eth_proto_admin %x\n", + be32_to_cpu(ptys_reg.eth_proto_admin)); + en_dbg(DRV, priv, "ptys_reg.eth_proto_oper %x\n", + be32_to_cpu(ptys_reg.eth_proto_oper)); + en_dbg(DRV, priv, "ptys_reg.eth_proto_lp_adv %x\n", + be32_to_cpu(ptys_reg.eth_proto_lp_adv)); + + cmd->supported = 0; + cmd->advertising = 0; + + cmd->supported |= ptys_get_supported_port(&ptys_reg); + + eth_proto = be32_to_cpu(ptys_reg.eth_proto_cap); + cmd->supported |= ptys2ethtool_link_modes(eth_proto, SUPPORTED); + + eth_proto = be32_to_cpu(ptys_reg.eth_proto_admin); + cmd->advertising |= ptys2ethtool_link_modes(eth_proto, ADVERTISED); + + cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; + cmd->advertising |= (priv->prof->tx_pause) ? ADVERTISED_Pause : 0; + + cmd->advertising |= (priv->prof->tx_pause ^ priv->prof->rx_pause) ? + ADVERTISED_Asym_Pause : 0; + + cmd->port = ptys_get_active_port(&ptys_reg); + cmd->transceiver = (SUPPORTED_TP & cmd->supported) ? + XCVR_EXTERNAL : XCVR_INTERNAL; + + if (mlx4_en_autoneg_get(dev)) { + cmd->supported |= SUPPORTED_Autoneg; + cmd->advertising |= ADVERTISED_Autoneg; + } + + cmd->autoneg = (priv->port_state.flags & MLX4_EN_PORT_ANC) ? + AUTONEG_ENABLE : AUTONEG_DISABLE; + + eth_proto = be32_to_cpu(ptys_reg.eth_proto_lp_adv); + cmd->lp_advertising = ptys2ethtool_link_modes(eth_proto, ADVERTISED); + + cmd->lp_advertising |= (priv->port_state.flags & MLX4_EN_PORT_ANC) ? + ADVERTISED_Autoneg : 0; + + cmd->phy_address = 0; + cmd->mdio_support = 0; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + cmd->eth_tp_mdix = ETH_TP_MDI_INVALID; + cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO; + + return ret; +} + +static void ethtool_get_default_settings(struct net_device *dev, + struct ethtool_cmd *cmd) { struct mlx4_en_priv *priv = netdev_priv(dev); int trans_type; @@ -383,18 +653,7 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->autoneg = AUTONEG_DISABLE; cmd->supported = SUPPORTED_10000baseT_Full; cmd->advertising = ADVERTISED_10000baseT_Full; - - if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) - return -ENOMEM; - - trans_type = priv->port_state.transciver; - if (netif_carrier_ok(dev)) { - ethtool_cmd_speed_set(cmd, priv->port_state.link_speed); - cmd->duplex = DUPLEX_FULL; - } else { - ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); - cmd->duplex = DUPLEX_UNKNOWN; - } + trans_type = priv->port_state.transceiver; if (trans_type > 0 && trans_type <= 0xC) { cmd->port = PORT_FIBRE; @@ -410,6 +669,32 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->port = -1; cmd->transceiver = -1; } +} + +static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + int ret = -EINVAL; + + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + + en_dbg(DRV, priv, "query port state.flags ANC(%x) ANE(%x)\n", + priv->port_state.flags & MLX4_EN_PORT_ANC, + priv->port_state.flags & MLX4_EN_PORT_ANE); + + if (priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) + ret = ethtool_get_ptys_settings(dev, cmd); + if (ret) /* ETH PROT CRTL is not supported or PTYS CMD failed */ + ethtool_get_default_settings(dev, cmd); + + if (netif_carrier_ok(dev)) { + ethtool_cmd_speed_set(cmd, priv->port_state.link_speed); + cmd->duplex = DUPLEX_FULL; + } else { + ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); + cmd->duplex = DUPLEX_UNKNOWN; + } return 0; } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index afd303662d17..134b12e17da5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c @@ -114,7 +114,14 @@ int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) state->link_speed = -1; break; } - state->transciver = qport_context->transceiver; + + state->transceiver = qport_context->transceiver; + + state->flags = 0; /* Reset and recalculate the port flags */ + state->flags |= (qport_context->link_up & MLX4_EN_ANC_MASK) ? + MLX4_EN_PORT_ANC : 0; + state->flags |= (qport_context->autoneg & MLX4_EN_AUTONEG_MASK) ? + MLX4_EN_PORT_ANE : 0; out: mlx4_free_cmd_mailbox(mdev->dev, mailbox); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.h b/drivers/net/ethernet/mellanox/mlx4/en_port.h index a5fc93bfe5da..040da4b16b1c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.h +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.h @@ -53,6 +53,28 @@ enum { MLX4_MCAST_ENABLE = 2, }; +enum mlx4_link_mode { + MLX4_1000BASE_CX_SGMII = 0, + MLX4_1000BASE_KX = 1, + MLX4_10GBASE_CX4 = 2, + MLX4_10GBASE_KX4 = 3, + MLX4_10GBASE_KR = 4, + MLX4_20GBASE_KR2 = 5, + MLX4_40GBASE_CR4 = 6, + MLX4_40GBASE_KR4 = 7, + MLX4_56GBASE_KR4 = 8, + MLX4_10GBASE_CR = 12, + MLX4_10GBASE_SR = 13, + MLX4_40GBASE_SR4 = 15, + MLX4_56GBASE_CR4 = 17, + MLX4_56GBASE_SR4 = 18, + MLX4_100BASE_TX = 24, + MLX4_1000BASE_T = 25, + MLX4_10GBASE_T = 26, +}; + +#define MLX4_PROT_MASK(link_mode) (1< Date: Mon, 27 Oct 2014 11:37:41 +0200 Subject: [PATCH 1697/9457] net/mlx4_en: Use PTYS register to set ethtool settings (Speed) Added Support to set speed or advertised link modes via ethtool: ethtool -s [speed ] [advertise ] Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 108 +++++++++++++++++- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 64b6743afdd2..144d6bdc183f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -570,6 +570,31 @@ static u32 ptys2ethtool_link_modes(u32 eth_proto, enum ethtool_report report) return link_modes; } +static u32 ethtool2ptys_link_modes(u32 link_modes, enum ethtool_report report) +{ + int i; + u32 ptys_modes = 0; + + for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { + if (ptys2ethtool_map[i][report] & link_modes) + ptys_modes |= 1 << i; + } + return ptys_modes; +} + +/* Convert actual speed (SPEED_XXX) to ptys link modes */ +static u32 speed2ptys_link_modes(u32 speed) +{ + int i; + u32 ptys_modes = 0; + + for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { + if (ptys2ethtool_map[i][SPEED] == speed) + ptys_modes |= 1 << i; + } + return ptys_modes; +} + static int ethtool_get_ptys_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -698,14 +723,89 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; } +/* Calculate PTYS admin according ethtool speed (SPEED_XXX) */ +static __be32 speed_set_ptys_admin(struct mlx4_en_priv *priv, u32 speed, + __be32 proto_cap) +{ + __be32 proto_admin = 0; + + if (!speed) { /* Speed = 0 ==> Reset Link modes */ + proto_admin = proto_cap; + en_info(priv, "Speed was set to 0, Reset advertised Link Modes to default (%x)\n", + be32_to_cpu(proto_cap)); + } else { + u32 ptys_link_modes = speed2ptys_link_modes(speed); + + proto_admin = cpu_to_be32(ptys_link_modes) & proto_cap; + en_info(priv, "Setting Speed to %d\n", speed); + } + return proto_admin; +} + static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - if ((cmd->autoneg == AUTONEG_ENABLE) || - (ethtool_cmd_speed(cmd) != SPEED_10000) || - (cmd->duplex != DUPLEX_FULL)) + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_ptys_reg ptys_reg; + __be32 proto_admin; + int ret; + + u32 ptys_adv = ethtool2ptys_link_modes(cmd->advertising, ADVERTISED); + int speed = ethtool_cmd_speed(cmd); + + en_dbg(DRV, priv, "Set Speed=%d adv=0x%x autoneg=%d duplex=%d\n", + speed, cmd->advertising, cmd->autoneg, cmd->duplex); + + if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) || + (cmd->autoneg == AUTONEG_ENABLE) || (cmd->duplex == DUPLEX_HALF)) return -EINVAL; - /* Nothing to change */ + memset(&ptys_reg, 0, sizeof(ptys_reg)); + ptys_reg.local_port = priv->port; + ptys_reg.proto_mask = MLX4_PTYS_EN; + ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev, + MLX4_ACCESS_REG_QUERY, &ptys_reg); + if (ret) { + en_warn(priv, "Failed to QUERY mlx4_ACCESS_PTYS_REG status(%x)\n", + ret); + return 0; + } + + proto_admin = cpu_to_be32(ptys_adv); + if (speed >= 0 && speed != priv->port_state.link_speed) + /* If speed was set then speed decides :-) */ + proto_admin = speed_set_ptys_admin(priv, speed, + ptys_reg.eth_proto_cap); + + proto_admin &= ptys_reg.eth_proto_cap; + + if (proto_admin == ptys_reg.eth_proto_admin) + return 0; /* Nothing to change */ + + if (!proto_admin) { + en_warn(priv, "Not supported link mode(s) requested, check supported link modes.\n"); + return -EINVAL; /* nothing to change due to bad input */ + } + + en_dbg(DRV, priv, "mlx4_ACCESS_PTYS_REG SET: ptys_reg.eth_proto_admin = 0x%x\n", + be32_to_cpu(proto_admin)); + + ptys_reg.eth_proto_admin = proto_admin; + ret = mlx4_ACCESS_PTYS_REG(priv->mdev->dev, MLX4_ACCESS_REG_WRITE, + &ptys_reg); + if (ret) { + en_warn(priv, "Failed to write mlx4_ACCESS_PTYS_REG eth_proto_admin(0x%x) status(0x%x)", + be32_to_cpu(ptys_reg.eth_proto_admin), ret); + return ret; + } + + en_warn(priv, "Port link mode changed, restarting port...\n"); + mutex_lock(&priv->mdev->state_lock); + if (priv->port_up) { + mlx4_en_stop_port(dev, 1); + if (mlx4_en_start_port(dev)) + en_err(priv, "Failed restarting port %d\n", priv->port); + } + mutex_unlock(&priv->mdev->state_lock); return 0; } -- GitLab From 7787fa661b8b9acba95ba35974b7092675baee8a Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:42 +0200 Subject: [PATCH 1698/9457] net/mlx4_en: Add support for setting rxvlan offload OFF/ON Rename mlx4_en_timestamp_config to mlx4_en_reset_config and extend it to support choosing RX vlan offload configuration. Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 53 +++++++++++++++---- .../net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 10 ++-- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 57dda95b67d8..285fccf01404 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -35,16 +35,26 @@ #include "mlx4_en.h" -int mlx4_en_timestamp_config(struct net_device *dev, int tx_type, int rx_filter) +int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t features) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; int port_up = 0; int err = 0; - if (priv->hwtstamp_config.tx_type == tx_type && - priv->hwtstamp_config.rx_filter == rx_filter) - return 0; + if (priv->hwtstamp_config.tx_type == ts_config.tx_type && + priv->hwtstamp_config.rx_filter == ts_config.rx_filter && + !DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) + return 0; /* Nothing to change */ + + if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) && + (features & NETIF_F_HW_VLAN_CTAG_RX) && + (priv->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE)) { + en_warn(priv, "Can't turn ON rx vlan offload while time-stamping rx filter is ON\n"); + return -EINVAL; + } mutex_lock(&mdev->state_lock); if (priv->port_up) { @@ -54,15 +64,36 @@ int mlx4_en_timestamp_config(struct net_device *dev, int tx_type, int rx_filter) mlx4_en_free_resources(priv); - en_warn(priv, "Changing Time Stamp configuration\n"); - - priv->hwtstamp_config.tx_type = tx_type; - priv->hwtstamp_config.rx_filter = rx_filter; + en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n", + ts_config.rx_filter, !!(features & NETIF_F_HW_VLAN_CTAG_RX)); + + priv->hwtstamp_config.tx_type = ts_config.tx_type; + priv->hwtstamp_config.rx_filter = ts_config.rx_filter; + + if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) { + if (features & NETIF_F_HW_VLAN_CTAG_RX) + dev->features |= NETIF_F_HW_VLAN_CTAG_RX; + else + dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) { + /* RX time-stamping is OFF, update the RX vlan offload + * to the latest wanted state + */ + if (dev->wanted_features & NETIF_F_HW_VLAN_CTAG_RX) + dev->features |= NETIF_F_HW_VLAN_CTAG_RX; + else + dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } - if (rx_filter != HWTSTAMP_FILTER_NONE) + /* RX vlan offload and RX time-stamping can't co-exist ! + * Regardless of the caller's choice, + * Turn Off RX vlan offload in case of time-stamping is ON + */ + if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) { + if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) + en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n"); dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; - else - dev->features |= NETIF_F_HW_VLAN_CTAG_RX; + } err = mlx4_en_alloc_resources(priv); if (err) { diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index f3032fec8fce..c4bd2c7a8d2e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2157,7 +2157,7 @@ static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) return -ERANGE; } - if (mlx4_en_timestamp_config(dev, config.tx_type, config.rx_filter)) { + if (mlx4_en_reset_config(dev, config, dev->features)) { config.tx_type = HWTSTAMP_TX_OFF; config.rx_filter = HWTSTAMP_FILTER_NONE; } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 946754ed393f..6beb4d34dce0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -835,6 +835,13 @@ void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv); void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); +#define DEV_FEATURE_CHANGED(dev, new_features, feature) \ + ((dev->features & feature) ^ (new_features & feature)) + +int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t new_features); + /* * Functions for time stamping */ @@ -844,9 +851,6 @@ void mlx4_en_fill_hwtstamps(struct mlx4_en_dev *mdev, u64 timestamp); void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev); void mlx4_en_remove_timestamp(struct mlx4_en_dev *mdev); -int mlx4_en_timestamp_config(struct net_device *dev, - int tx_type, - int rx_filter); /* Globals */ -- GitLab From 537f6f951e1489054c283fa97b636cc55af1a60b Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Mon, 27 Oct 2014 11:37:43 +0200 Subject: [PATCH 1699/9457] net/mlx4_en: Add ethtool support for [rx|tx]vlan offload set to OFF/ON Move mlx4_en_reset_config to en_netdev.c as it now serves more general purpose. Add support for turning OFF/ON the rx/tx vlan offlad. Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 77 ---------------- .../net/ethernet/mellanox/mlx4/en_netdev.c | 89 ++++++++++++++++++- 2 files changed, 88 insertions(+), 78 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 285fccf01404..999014413b1a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -35,83 +35,6 @@ #include "mlx4_en.h" -int mlx4_en_reset_config(struct net_device *dev, - struct hwtstamp_config ts_config, - netdev_features_t features) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int port_up = 0; - int err = 0; - - if (priv->hwtstamp_config.tx_type == ts_config.tx_type && - priv->hwtstamp_config.rx_filter == ts_config.rx_filter && - !DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) - return 0; /* Nothing to change */ - - if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) && - (features & NETIF_F_HW_VLAN_CTAG_RX) && - (priv->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE)) { - en_warn(priv, "Can't turn ON rx vlan offload while time-stamping rx filter is ON\n"); - return -EINVAL; - } - - mutex_lock(&mdev->state_lock); - if (priv->port_up) { - port_up = 1; - mlx4_en_stop_port(dev, 1); - } - - mlx4_en_free_resources(priv); - - en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n", - ts_config.rx_filter, !!(features & NETIF_F_HW_VLAN_CTAG_RX)); - - priv->hwtstamp_config.tx_type = ts_config.tx_type; - priv->hwtstamp_config.rx_filter = ts_config.rx_filter; - - if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) { - if (features & NETIF_F_HW_VLAN_CTAG_RX) - dev->features |= NETIF_F_HW_VLAN_CTAG_RX; - else - dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; - } else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) { - /* RX time-stamping is OFF, update the RX vlan offload - * to the latest wanted state - */ - if (dev->wanted_features & NETIF_F_HW_VLAN_CTAG_RX) - dev->features |= NETIF_F_HW_VLAN_CTAG_RX; - else - dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; - } - - /* RX vlan offload and RX time-stamping can't co-exist ! - * Regardless of the caller's choice, - * Turn Off RX vlan offload in case of time-stamping is ON - */ - if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) { - if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) - en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n"); - dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; - } - - err = mlx4_en_alloc_resources(priv); - if (err) { - en_err(priv, "Failed reallocating port resources\n"); - goto out; - } - if (port_up) { - err = mlx4_en_start_port(dev); - if (err) - en_err(priv, "Failed starting port\n"); - } - -out: - mutex_unlock(&mdev->state_lock); - netdev_features_change(dev); - return err; -} - /* mlx4_en_read_clock - read raw cycle counter (to be used by time counter) */ static cycle_t mlx4_en_read_clock(const struct cyclecounter *tc) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index c4bd2c7a8d2e..3c6a58a94763 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2190,6 +2190,16 @@ static int mlx4_en_set_features(struct net_device *netdev, netdev_features_t features) { struct mlx4_en_priv *priv = netdev_priv(netdev); + int ret = 0; + + if (DEV_FEATURE_CHANGED(netdev, features, NETIF_F_HW_VLAN_CTAG_RX)) { + en_info(priv, "Turn %s RX vlan strip offload\n", + (features & NETIF_F_HW_VLAN_CTAG_RX) ? "ON" : "OFF"); + ret = mlx4_en_reset_config(netdev, priv->hwtstamp_config, + features); + if (ret) + return ret; + } if (features & NETIF_F_LOOPBACK) priv->ctrl_flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); @@ -2559,7 +2569,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->features = dev->hw_features | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; - dev->hw_features |= NETIF_F_LOOPBACK; + dev->hw_features |= NETIF_F_LOOPBACK | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; if (mdev->dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) @@ -2633,3 +2644,79 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, return err; } +int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t features) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + int port_up = 0; + int err = 0; + + if (priv->hwtstamp_config.tx_type == ts_config.tx_type && + priv->hwtstamp_config.rx_filter == ts_config.rx_filter && + !DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) + return 0; /* Nothing to change */ + + if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) && + (features & NETIF_F_HW_VLAN_CTAG_RX) && + (priv->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE)) { + en_warn(priv, "Can't turn ON rx vlan offload while time-stamping rx filter is ON\n"); + return -EINVAL; + } + + mutex_lock(&mdev->state_lock); + if (priv->port_up) { + port_up = 1; + mlx4_en_stop_port(dev, 1); + } + + mlx4_en_free_resources(priv); + + en_warn(priv, "Changing device configuration rx filter(%x) rx vlan(%x)\n", + ts_config.rx_filter, !!(features & NETIF_F_HW_VLAN_CTAG_RX)); + + priv->hwtstamp_config.tx_type = ts_config.tx_type; + priv->hwtstamp_config.rx_filter = ts_config.rx_filter; + + if (DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX)) { + if (features & NETIF_F_HW_VLAN_CTAG_RX) + dev->features |= NETIF_F_HW_VLAN_CTAG_RX; + else + dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) { + /* RX time-stamping is OFF, update the RX vlan offload + * to the latest wanted state + */ + if (dev->wanted_features & NETIF_F_HW_VLAN_CTAG_RX) + dev->features |= NETIF_F_HW_VLAN_CTAG_RX; + else + dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } + + /* RX vlan offload and RX time-stamping can't co-exist ! + * Regardless of the caller's choice, + * Turn Off RX vlan offload in case of time-stamping is ON + */ + if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) { + if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) + en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n"); + dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; + } + + err = mlx4_en_alloc_resources(priv); + if (err) { + en_err(priv, "Failed reallocating port resources\n"); + goto out; + } + if (port_up) { + err = mlx4_en_start_port(dev); + if (err) + en_err(priv, "Failed starting port\n"); + } + +out: + mutex_unlock(&mdev->state_lock); + netdev_features_change(dev); + return err; +} -- GitLab From c2a3d4b4cac1a9ad0547b0807e118cb34885dbd5 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 27 Oct 2014 11:37:44 +0200 Subject: [PATCH 1700/9457] net/mlx4_en: Cleanups suggested by clang static checker clang flagged the following. All are actually cosmetic cleanups, not really bugs: drivers/net/ethernet/mellanox/mlx4/en_main.c:233:3: warning: Value stored to 'err' is never read err = -ENOMEM; ^ ~~~~~~~ drivers/net/ethernet/mellanox/mlx4/en_main.c:293:3: warning: Value stored to 'err' is never read err = -ENOMEM; drivers/net/ethernet/mellanox/mlx4/en_netdev.c:648:16: warning: Assigned value is garbage or undefined entry->reg_id = reg_id; ^ ~~~~~~ drivers/net/ethernet/mellanox/mlx4/en_netdev.c:659:2: warning: Function call argument is an uninitialized value mlx4_en_uc_steer_release(priv, priv->dev->dev_addr, *qpn, reg_id); (NOTE: reg_id is only used in the device-managed flow steering path, in which is it always initialized. This is not a bug. Cleanup here is therefore cosmetic only). drivers/net/ethernet/mellanox/mlx4/en_rx.c:122:3: warning: Value stored to 'frag_info' is never read frag_info = &priv->frag_info[i]; ^ ~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jack Morgenstein Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_main.c | 12 +++--------- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 1 - 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index 2091ae88615d..9f16f754137b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -221,15 +221,12 @@ static void *mlx4_en_add(struct mlx4_dev *dev) { struct mlx4_en_dev *mdev; int i; - int err; printk_once(KERN_INFO "%s", mlx4_en_version); mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); - if (!mdev) { - err = -ENOMEM; + if (!mdev) goto err_free_res; - } if (mlx4_pd_alloc(dev, &mdev->priv_pdn)) goto err_free_dev; @@ -264,8 +261,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev) } /* Build device profile according to supplied module parameters */ - err = mlx4_en_get_profile(mdev); - if (err) { + if (mlx4_en_get_profile(mdev)) { mlx4_err(mdev, "Bad module parameters, aborting\n"); goto err_mr; } @@ -286,10 +282,8 @@ static void *mlx4_en_add(struct mlx4_dev *dev) * Note: we cannot use the shared workqueue because of deadlocks caused * by the rtnl lock */ mdev->workqueue = create_singlethread_workqueue("mlx4_en"); - if (!mdev->workqueue) { - err = -ENOMEM; + if (!mdev->workqueue) goto err_mr; - } /* At this stage all non-port specific tasks are complete: * mark the card state as up */ diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 3c6a58a94763..a23aa309e2f0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -575,7 +575,7 @@ static int mlx4_en_get_qp(struct mlx4_en_priv *priv) struct mlx4_mac_entry *entry; int index = 0; int err = 0; - u64 reg_id; + u64 reg_id = 0; int *qpn = &priv->base_qpn; u64 mac = mlx4_mac_to_u64(priv->dev->dev_addr); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 01660c595f5c..c8e75dab8055 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -119,7 +119,6 @@ static int mlx4_en_alloc_frags(struct mlx4_en_priv *priv, out: while (i--) { - frag_info = &priv->frag_info[i]; if (page_alloc[i].page != ring_alloc[i].page) { dma_unmap_page(priv->ddev, page_alloc[i].dma, page_alloc[i].page_size, PCI_DMA_FROMDEVICE); -- GitLab From f4a36751584bbdfcfd6f3f232e0fe899763434a4 Mon Sep 17 00:00:00 2001 From: Ido Shamay Date: Mon, 27 Oct 2014 11:37:45 +0200 Subject: [PATCH 1701/9457] net/mlx4_en: Call napi_synchronize on stop_port This is instead of calling the actual implementation of napi_synchronize, for better encapsulation. Signed-off-by: Ido Shamay Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index a23aa309e2f0..0e77cb27d7d7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1843,8 +1843,7 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) } local_bh_enable(); - while (test_bit(NAPI_STATE_SCHED, &cq->napi.state)) - msleep(1); + napi_synchronize(&cq->napi); mlx4_en_deactivate_rx_ring(priv, priv->rx_ring[i]); mlx4_en_deactivate_cq(priv, cq); -- GitLab From 207af6c5073021dfe32ae01d342a4dbf08e57515 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Mon, 27 Oct 2014 11:37:46 +0200 Subject: [PATCH 1702/9457] net/mlx4_en: Move spinlocks and work initalizations to beginning of init_netdev Upon failures, destroy_netdev is called, and spinlocks/works must be initialized before calling it. Otherwise kernel panic may occur. Signed-off-by: Eugenia Emantayev Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_netdev.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 0e77cb27d7d7..0efbae90f1ba 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2440,6 +2440,21 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv = netdev_priv(dev); memset(priv, 0, sizeof(struct mlx4_en_priv)); + spin_lock_init(&priv->stats_lock); + INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); + INIT_WORK(&priv->watchdog_task, mlx4_en_restart); + INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); + INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); + INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); +#ifdef CONFIG_MLX4_EN_VXLAN + INIT_WORK(&priv->vxlan_add_task, mlx4_en_add_vxlan_offloads); + INIT_WORK(&priv->vxlan_del_task, mlx4_en_del_vxlan_offloads); +#endif +#ifdef CONFIG_RFS_ACCEL + INIT_LIST_HEAD(&priv->filters); + spin_lock_init(&priv->filters_lock); +#endif + priv->dev = dev; priv->mdev = mdev; priv->ddev = &mdev->pdev->dev; @@ -2471,16 +2486,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->cqe_size = mdev->dev->caps.cqe_size; priv->mac_index = -1; priv->msg_enable = MLX4_EN_MSG_LEVEL; - spin_lock_init(&priv->stats_lock); - INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); - INIT_WORK(&priv->watchdog_task, mlx4_en_restart); - INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); - INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); - INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); -#ifdef CONFIG_MLX4_EN_VXLAN - INIT_WORK(&priv->vxlan_add_task, mlx4_en_add_vxlan_offloads); - INIT_WORK(&priv->vxlan_del_task, mlx4_en_del_vxlan_offloads); -#endif #ifdef CONFIG_MLX4_EN_DCB if (!mlx4_is_slave(priv->mdev->dev)) { if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_SET_ETH_SCHED) { @@ -2523,11 +2528,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, if (err) goto out; -#ifdef CONFIG_RFS_ACCEL - INIT_LIST_HEAD(&priv->filters); - spin_lock_init(&priv->filters_lock); -#endif - /* Initialize time stamping config */ priv->hwtstamp_config.flags = 0; priv->hwtstamp_config.tx_type = HWTSTAMP_TX_OFF; -- GitLab From d5ec899adb442161b8ae43777572ef8076f379a0 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Mon, 27 Oct 2014 11:37:47 +0200 Subject: [PATCH 1703/9457] net/mlx4_en: Report actual number of rings in indirection table Hardware requires the number of rings in indirection table to be a power of 2. When setting number of channels to a non power of 2 number, indirection table is using only the closest power of 2 rings. Report this number in 'ethtool -x' and not the total number of rx rings. Signed-off-by: Amir Vadai Signed-off-by: Eugenia Emantayev Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 144d6bdc183f..8ea4d5be7376 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -982,6 +982,7 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) int err = 0; rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num; + rss_rings = 1 << ilog2(rss_rings); while (n--) { ring_index[n] = rss_map->qps[n % rss_rings].qpn - -- GitLab From 2c6c49ded7a7209fe8618423c457b8000ee528a4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Oct 2014 17:27:23 -0400 Subject: [PATCH 1704/9457] openvswitch: Export lockdep_ovsl_is_held to modules. ERROR: "lockdep_ovsl_is_held" [net/openvswitch/vport-gre.ko] undefined! Reported-by: Alexei Starovoitov Signed-off-by: David S. Miller --- net/openvswitch/datapath.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index aecddb9bb80a..f18302f32049 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -131,6 +131,7 @@ int lockdep_ovsl_is_held(void) else return 1; } +EXPORT_SYMBOL(lockdep_ovsl_is_held); #endif static struct vport *new_vport(const struct vport_parms *); -- GitLab From 980ffc0a2cec2c37589cc97993e1ad17252f4f47 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 22:23:26 +0100 Subject: [PATCH 1705/9457] Bluetooth: Fix LE connection timeout deadlock The le_conn_timeout() may call hci_le_conn_failed() which in turn may call hci_conn_del(). Trying to use the _sync variant for cancelling the conn timeout from hci_conn_del() could therefore result in a deadlock. This patch converts hci_conn_del() to use the non-sync variant so the deadlock is not possible. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 3.16.x --- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6a3225bf7bac..74b8e2421e96 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -518,7 +518,7 @@ int hci_conn_del(struct hci_conn *conn) /* Unacked frames */ hdev->acl_cnt += conn->sent; } else if (conn->type == LE_LINK) { - cancel_delayed_work_sync(&conn->le_conn_timeout); + cancel_delayed_work(&conn->le_conn_timeout); if (hdev->le_pkts) hdev->le_cnt += conn->sent; -- GitLab From 0b1db38ca26b322296cbd141f3080eccfe1cc3e1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 28 Oct 2014 22:23:27 +0100 Subject: [PATCH 1706/9457] Bluetooth: Fix check for direct advertising These days we allow simultaneous LE scanning and advertising. Checking for whether advertising is enabled or not is therefore not a reliable way to determine whether directed advertising was used to trigger the connection creation. The appropriate place to check (instead of the hdev context) is the connection role that's stored in the hci_conn. This patch fixes such a check in le_conn_timeout() which could otherwise lead to incorrect HCI commands being sent. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 3.16.x --- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 74b8e2421e96..96887ae8375b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -416,7 +416,7 @@ static void le_conn_timeout(struct work_struct *work) * happen with broken hardware or if low duty cycle was used * (which doesn't have a timeout of its own). */ - if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) { + if (conn->role == HCI_ROLE_SLAVE) { u8 enable = 0x00; hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable); -- GitLab From b9ff77e50c6e469db63dfc8fcc62586522649cd3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:16 +0100 Subject: [PATCH 1707/9457] mac802154: monitor: merge into iface implementation This patch removes the monitor implementation file and put all monitor stuff into iface file. It's now small enough to put all necessary handling into iface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/iface.c | 30 +++++++++++++++++++++ net/mac802154/monitor.c | 59 ----------------------------------------- 3 files changed, 31 insertions(+), 60 deletions(-) delete mode 100644 net/mac802154/monitor.c diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index e68debaf2a59..2e497d0c829a 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - monitor.o iface.o llsec.o util.o + iface.o llsec.o util.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 7e4bffcbcd4d..dafb2c3ac109 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -320,6 +320,12 @@ static const struct net_device_ops mac802154_wpan_ops = { .ndo_set_mac_address = mac802154_wpan_mac_addr, }; +static const struct net_device_ops mac802154_monitor_ops = { + .ndo_open = mac802154_slave_open, + .ndo_stop = mac802154_slave_close, + .ndo_start_xmit = ieee802154_monitor_start_xmit, +}; + static void mac802154_wpan_free(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); @@ -373,3 +379,27 @@ void mac802154_wpan_setup(struct net_device *dev) mac802154_llsec_init(&sdata->sec); } + +void mac802154_monitor_setup(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata; + + dev->addr_len = 0; + dev->hard_header_len = 0; + dev->needed_tailroom = 2; /* room for FCS */ + dev->mtu = IEEE802154_MTU; + dev->tx_queue_len = 10; + dev->type = ARPHRD_IEEE802154_MONITOR; + dev->flags = IFF_NOARP | IFF_BROADCAST; + dev->watchdog_timeo = 0; + + dev->destructor = free_netdev; + dev->netdev_ops = &mac802154_monitor_ops; + dev->ml_priv = &mac802154_mlme_reduced; + + sdata = IEEE802154_DEV_TO_SUB_IF(dev); + sdata->type = IEEE802154_DEV_MONITOR; + + sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ + sdata->page = 0; +} diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c deleted file mode 100644 index dfdedc206c6a..000000000000 --- a/net/mac802154/monitor.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Written by: - * Dmitry Eremin-Solenikov - * Sergey Lapin - * Maxim Gorbachyov - * Alexander Smirnov - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "ieee802154_i.h" - -static const struct net_device_ops mac802154_monitor_ops = { - .ndo_open = mac802154_slave_open, - .ndo_stop = mac802154_slave_close, - .ndo_start_xmit = ieee802154_monitor_start_xmit, -}; - -void mac802154_monitor_setup(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata; - - dev->addr_len = 0; - dev->hard_header_len = 0; - dev->needed_tailroom = 2; /* room for FCS */ - dev->mtu = IEEE802154_MTU; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154_MONITOR; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; - - dev->destructor = free_netdev; - dev->netdev_ops = &mac802154_monitor_ops; - dev->ml_priv = &mac802154_mlme_reduced; - - sdata = IEEE802154_DEV_TO_SUB_IF(dev); - sdata->type = IEEE802154_DEV_MONITOR; - - sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ - sdata->page = 0; -} -- GitLab From 19ec690a431d8ebf3e9d939160dc223ad40d7d63 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:17 +0100 Subject: [PATCH 1708/9457] mac802154: main: move open and close into iface These functions can be static inside the iface file, because it's not used anywhere else. This patch moves these functions into iface file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 -- net/mac802154/iface.c | 59 ++++++++++++++++++++++++++++++++++++ net/mac802154/main.c | 59 ------------------------------------ 3 files changed, 59 insertions(+), 62 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index ac907d943bae..4408c463af35 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -123,9 +123,6 @@ IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; -int mac802154_slave_open(struct net_device *dev); -int mac802154_slave_close(struct net_device *dev); - void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index dafb2c3ac109..0b21413081f1 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -142,6 +142,46 @@ void mac802154_get_mac_params(struct net_device *dev, mutex_unlock(&sdata->local->iflist_mtx); } +static int mac802154_slave_open(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_sub_if_data *subif; + struct ieee802154_local *local = sdata->local; + int res = 0; + + ASSERT_RTNL(); + + if (sdata->type == IEEE802154_DEV_WPAN) { + mutex_lock(&sdata->local->iflist_mtx); + list_for_each_entry(subif, &sdata->local->interfaces, list) { + if (subif != sdata && subif->type == sdata->type && + subif->running) { + mutex_unlock(&sdata->local->iflist_mtx); + return -EBUSY; + } + } + mutex_unlock(&sdata->local->iflist_mtx); + } + + mutex_lock(&sdata->local->iflist_mtx); + sdata->running = true; + mutex_unlock(&sdata->local->iflist_mtx); + + if (local->open_count++ == 0) { + res = local->ops->start(&local->hw); + WARN_ON(res); + if (res) + goto err; + } + + netif_start_queue(dev); + return 0; +err: + sdata->local->open_count--; + + return res; +} + static int mac802154_wpan_open(struct net_device *dev) { int rc; @@ -201,6 +241,25 @@ static int mac802154_wpan_open(struct net_device *dev) return rc; } +static int mac802154_slave_close(struct net_device *dev) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_local *local = sdata->local; + + ASSERT_RTNL(); + + netif_stop_queue(dev); + + mutex_lock(&sdata->local->iflist_mtx); + sdata->running = false; + mutex_unlock(&sdata->local->iflist_mtx); + + if (!--local->open_count) + local->ops->stop(&local->hw); + + return 0; +} + static int mac802154_set_header_security(struct ieee802154_sub_if_data *sdata, struct ieee802154_hdr *hdr, const struct ieee802154_mac_cb *cb) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index ff0de0f990cb..2c6d77259822 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -29,65 +29,6 @@ #include "ieee802154_i.h" -int mac802154_slave_open(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct ieee802154_sub_if_data *subif; - struct ieee802154_local *local = sdata->local; - int res = 0; - - ASSERT_RTNL(); - - if (sdata->type == IEEE802154_DEV_WPAN) { - mutex_lock(&sdata->local->iflist_mtx); - list_for_each_entry(subif, &sdata->local->interfaces, list) { - if (subif != sdata && subif->type == sdata->type && - subif->running) { - mutex_unlock(&sdata->local->iflist_mtx); - return -EBUSY; - } - } - mutex_unlock(&sdata->local->iflist_mtx); - } - - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = true; - mutex_unlock(&sdata->local->iflist_mtx); - - if (local->open_count++ == 0) { - res = local->ops->start(&local->hw); - WARN_ON(res); - if (res) - goto err; - } - - netif_start_queue(dev); - return 0; -err: - sdata->local->open_count--; - - return res; -} - -int mac802154_slave_close(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct ieee802154_local *local = sdata->local; - - ASSERT_RTNL(); - - netif_stop_queue(dev); - - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = false; - mutex_unlock(&sdata->local->iflist_mtx); - - if (!--local->open_count) - local->ops->stop(&local->hw); - - return 0; -} - static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) { -- GitLab From 16301861004e50be9c47113cceca62f56516a9a2 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:18 +0100 Subject: [PATCH 1709/9457] mac802154: declare struct ieee802154_ops as const The ieee802154_ops structure should be never changed during runtime. This patch declare this structure as const to avoid a runtime change. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 2 +- include/net/mac802154.h | 2 +- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index a1558385bac9..662efd3e07b9 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1214,7 +1214,7 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) return rc; } -static struct ieee802154_ops at86rf230_ops = { +static const struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, .xmit_async = at86rf230_xmit, .ed = at86rf230_ed, diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index a31b5b62a353..b479c9d560f8 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -631,7 +631,7 @@ cc2520_filter(struct ieee802154_hw *hw, return 0; } -static struct ieee802154_ops cc2520_ops = { +static const struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, .stop = cc2520_stop, diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index db0703f0fa41..2a97cbb3aa01 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -129,7 +129,7 @@ fakelb_hw_stop(struct ieee802154_hw *hw) { spin_unlock(&priv->lock); } -static struct ieee802154_ops fakelb_ops = { +static const struct ieee802154_ops fakelb_ops = { .owner = THIS_MODULE, .xmit_sync = fakelb_hw_xmit, .ed = fakelb_hw_ed, diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 7abb237cb989..f19cf588de2e 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -579,7 +579,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) return ret; } -static struct ieee802154_ops mrf24j40_ops = { +static const struct ieee802154_ops mrf24j40_ops = { .owner = THIS_MODULE, .xmit_sync = mrf24j40_tx, .ed = mrf24j40_ed, diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 4c4642ef244f..0ea44cda2920 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -197,7 +197,7 @@ struct ieee802154_ops { /* Basic interface to register ieee802154 hwice */ struct ieee802154_hw * -ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops); +ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); void ieee802154_free_hw(struct ieee802154_hw *hw); int ieee802154_register_hw(struct ieee802154_hw *hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw); diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4408c463af35..a379b971b13c 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -28,7 +28,7 @@ /* mac802154 device private data */ struct ieee802154_local { struct ieee802154_hw hw; - struct ieee802154_ops *ops; + const struct ieee802154_ops *ops; /* ieee802154 phy */ struct wpan_phy *phy; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 2c6d77259822..632707bc47b9 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -187,7 +187,7 @@ static void ieee802154_tasklet_handler(unsigned long data) } struct ieee802154_hw * -ieee802154_alloc_hw(size_t priv_data_len, struct ieee802154_ops *ops) +ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) { struct wpan_phy *phy; struct ieee802154_local *local; -- GitLab From e37d2ec82a222f1819e7793a27bc052999a379fb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:19 +0100 Subject: [PATCH 1710/9457] mac802154: ops: declare channel and page as u8 The range of channel and page fits into an unsigned byte range. This patch changes the set_channel parameter definitions for channel and page to u8. Signed-off-by: Alexander Aring Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 8 ++++---- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/ieee802154/fakelb.c | 2 +- drivers/net/ieee802154/mrf24j40.c | 3 +-- include/net/mac802154.h | 5 ++--- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 662efd3e07b9..5068c1bd0046 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -54,7 +54,7 @@ struct at86rf2xx_chip_data { u16 t_tx_timeout; int rssi_base_val; - int (*set_channel)(struct at86rf230_local *, int, int); + int (*set_channel)(struct at86rf230_local *, u8, u8); int (*get_desense_steps)(struct at86rf230_local *, s32); }; @@ -1012,13 +1012,13 @@ at86rf230_stop(struct ieee802154_hw *hw) } static int -at86rf23x_set_channel(struct at86rf230_local *lp, int page, int channel) +at86rf23x_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) { return at86rf230_write_subreg(lp, SR_CHANNEL, channel); } static int -at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel) +at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) { int rc; @@ -1043,7 +1043,7 @@ at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel) } static int -at86rf230_channel(struct ieee802154_hw *hw, int page, int channel) +at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { struct at86rf230_local *lp = hw->priv; int rc; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index b479c9d560f8..78ea2cadeb78 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -569,7 +569,7 @@ cc2520_ed(struct ieee802154_hw *hw, u8 *level) } static int -cc2520_set_channel(struct ieee802154_hw *hw, int page, int channel) +cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { struct cc2520_private *priv = hw->priv; int ret; diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 2a97cbb3aa01..4092e704c4aa 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -55,7 +55,7 @@ fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level) } static int -fakelb_hw_channel(struct ieee802154_hw *hw, int page, int channel) +fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { pr_debug("set channel to %d\n", channel); diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index f19cf588de2e..52b3d3116755 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -423,8 +423,7 @@ static void mrf24j40_stop(struct ieee802154_hw *hw) write_short_reg(devrec, REG_INTCON, val); } -static int mrf24j40_set_channel(struct ieee802154_hw *hw, - int page, int channel) +static int mrf24j40_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { struct mrf24j40 *devrec = hw->priv; u8 val; diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 0ea44cda2920..85a4efca418b 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -178,9 +178,8 @@ struct ieee802154_ops { int (*xmit_async)(struct ieee802154_hw *hw, struct sk_buff *skb); int (*ed)(struct ieee802154_hw *hw, u8 *level); - int (*set_channel)(struct ieee802154_hw *hw, - int page, - int channel); + int (*set_channel)(struct ieee802154_hw *hw, u8 page, + u8 channel); int (*set_hw_addr_filt)(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed); -- GitLab From b6eea9ca354aeb80d358ff52d046bb8a26bd2b17 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:20 +0100 Subject: [PATCH 1711/9457] mac802154: introduce driver-ops header This patch introduce a driver-ops header file with function wrappers to call the driver ops. These wrappers checking on right context information and warn if optional driver ops are called when these aren't implemented. This behaviour is like mac80211 driver-ops header file, just without function tracing calls. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 202 +++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 net/mac802154/driver-ops.h diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h new file mode 100644 index 000000000000..bf7980bbceff --- /dev/null +++ b/net/mac802154/driver-ops.h @@ -0,0 +1,202 @@ +#ifndef __MAC802154_DRVIER_OPS +#define __MAC802154_DRIVER_OPS + +#include +#include + +#include + +#include "ieee802154_i.h" + +static inline int +drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) +{ + return local->ops->xmit_async(&local->hw, skb); +} + +static inline int +drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) +{ + /* don't allow other operations while sync xmit */ + ASSERT_RTNL(); + + might_sleep(); + + return local->ops->xmit_sync(&local->hw, skb); +} + +static inline int drv_start(struct ieee802154_local *local) +{ + might_sleep(); + + return local->ops->start(&local->hw); +} + +static inline void drv_stop(struct ieee802154_local *local) +{ + might_sleep(); + + local->ops->stop(&local->hw); +} + +static inline int drv_set_channel(struct ieee802154_local *local, + const u8 page, const u8 channel) +{ + might_sleep(); + + return local->ops->set_channel(&local->hw, page, channel); +} + +static inline int drv_set_tx_power(struct ieee802154_local *local, + const s8 dbm) +{ + might_sleep(); + + if (!local->ops->set_txpower) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_txpower(&local->hw, dbm); +} + +static inline int drv_set_cca_mode(struct ieee802154_local *local, + const u8 cca_mode) +{ + might_sleep(); + + if (!local->ops->set_cca_mode) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_cca_mode(&local->hw, cca_mode); +} + +static inline int drv_set_lbt_mode(struct ieee802154_local *local, + const bool mode) +{ + might_sleep(); + + if (!local->ops->set_lbt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_lbt(&local->hw, mode); +} + +static inline int drv_set_cca_ed_level(struct ieee802154_local *local, + const s32 ed_level) +{ + might_sleep(); + + if (!local->ops->set_cca_ed_level) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_cca_ed_level(&local->hw, ed_level); +} + +static inline int drv_set_pan_id(struct ieee802154_local *local, + const __le16 pan_id) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.pan_id = pan_id; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_PANID_CHANGED); +} + +static inline int drv_set_extended_addr(struct ieee802154_local *local, + const __le64 extended_addr) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.ieee_addr = extended_addr; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_IEEEADDR_CHANGED); +} + +static inline int drv_set_short_addr(struct ieee802154_local *local, + const __le16 short_addr) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.short_addr = short_addr; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_SADDR_CHANGED); +} + +static inline int drv_set_pan_coord(struct ieee802154_local *local, + const bool is_coord) +{ + struct ieee802154_hw_addr_filt filt; + + might_sleep(); + + if (!local->ops->set_hw_addr_filt) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + filt.pan_coord = is_coord; + + return local->ops->set_hw_addr_filt(&local->hw, &filt, + IEEE802154_AFILT_PANC_CHANGED); +} + +static inline int drv_set_csma_params(struct ieee802154_local *local, + u8 min_be, u8 max_be, + u8 max_csma_backoffs) +{ + might_sleep(); + + if (!local->ops->set_csma_params) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_csma_params(&local->hw, min_be, max_be, + max_csma_backoffs); +} + +static inline int drv_set_max_frame_retries(struct ieee802154_local *local, + s8 max_frame_retries) +{ + might_sleep(); + + if (!local->ops->set_frame_retries) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_frame_retries(&local->hw, max_frame_retries); +} + +#endif /* __MAC802154_DRVIER_OPS */ -- GitLab From 59cb300f2b2ce1fc46696deb9a7bd066cd53a65a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:21 +0100 Subject: [PATCH 1712/9457] mac802154: use driver-ops function wrappers This patch replaces all directly called driver ops by previous introduced driver-ops function wrappers. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 25 ++++++++++++++----------- net/mac802154/main.c | 13 +++++++------ net/mac802154/mib.c | 3 ++- net/mac802154/tx.c | 5 +++-- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 0b21413081f1..025cd5aba13f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -30,6 +30,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" static int mac802154_wpan_update_llsec(struct net_device *dev) { @@ -168,7 +169,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); if (local->open_count++ == 0) { - res = local->ops->start(&local->hw); + res = drv_start(local); WARN_ON(res); if (res) goto err; @@ -186,6 +187,7 @@ static int mac802154_wpan_open(struct net_device *dev) { int rc; struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_local *local = sdata->local; struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); @@ -195,40 +197,41 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); if (phy->set_txpower) { - rc = phy->set_txpower(phy, sdata->mac_params.transmit_power); + rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) goto out; } if (phy->set_lbt) { - rc = phy->set_lbt(phy, sdata->mac_params.lbt); + rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); if (rc < 0) goto out; } if (phy->set_cca_mode) { - rc = phy->set_cca_mode(phy, sdata->mac_params.cca_mode); + rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode); if (rc < 0) goto out; } if (phy->set_cca_ed_level) { - rc = phy->set_cca_ed_level(phy, sdata->mac_params.cca_ed_level); + rc = drv_set_cca_ed_level(local, + sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } if (phy->set_csma_params) { - rc = phy->set_csma_params(phy, sdata->mac_params.min_be, - sdata->mac_params.max_be, - sdata->mac_params.csma_retries); + rc = drv_set_csma_params(local, sdata->mac_params.min_be, + sdata->mac_params.max_be, + sdata->mac_params.csma_retries); if (rc < 0) goto out; } if (phy->set_frame_retries) { - rc = phy->set_frame_retries(phy, - sdata->mac_params.frame_retries); + rc = drv_set_max_frame_retries(local, + sdata->mac_params.frame_retries); if (rc < 0) goto out; } @@ -255,7 +258,7 @@ static int mac802154_slave_close(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); if (!--local->open_count) - local->ops->stop(&local->hw); + drv_stop(local); return 0; } diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 632707bc47b9..24ecc09de2a4 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) @@ -124,28 +125,28 @@ static int mac802154_set_txpower(struct wpan_phy *phy, int db) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_txpower(&local->hw, db); + return drv_set_tx_power(local, db); } static int mac802154_set_lbt(struct wpan_phy *phy, bool on) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_lbt(&local->hw, on); + return drv_set_lbt_mode(local, on); } static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_cca_mode(&local->hw, mode); + return drv_set_cca_mode(local, mode); } static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_cca_ed_level(&local->hw, level); + return drv_set_cca_ed_level(local, level); } static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, @@ -153,14 +154,14 @@ static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_csma_params(&local->hw, min_be, max_be, retries); + return drv_set_csma_params(local, min_be, max_be, retries); } static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) { struct ieee802154_local *local = wpan_phy_priv(phy); - return local->ops->set_frame_retries(&local->hw, retries); + return drv_set_max_frame_retries(local, retries); } static void ieee802154_tasklet_handler(unsigned long data) diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 16baff1ea313..3fbc217dbdcc 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -24,6 +24,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" struct phy_chan_notify_work { struct work_struct work; @@ -170,7 +171,7 @@ static void phy_chan_notify(struct work_struct *work) int res; mutex_lock(&sdata->local->phy->pib_lock); - res = local->ops->set_channel(&local->hw, sdata->page, sdata->chan); + res = drv_set_channel(local, sdata->page, sdata->chan); if (res) { pr_debug("set_channel failed\n"); } else { diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index e85767355c48..77973a84e9a2 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process * packets through the workqueue. @@ -55,7 +56,7 @@ static void ieee802154_xmit_worker(struct work_struct *work) if (!netif_running(dev)) goto err_tx; - res = local->ops->xmit_sync(&local->hw, skb); + res = drv_xmit_sync(local, skb); if (res) goto err_tx; @@ -96,7 +97,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) /* async is priority, otherwise sync is fallback */ if (local->ops->xmit_async) { - ret = local->ops->xmit_async(&local->hw, skb); + ret = drv_xmit_async(local, skb); if (ret) { ieee802154_wake_queue(&local->hw); goto err_tx; -- GitLab From e1d299f61a1660cbbabccfa0d07421861b9b9711 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:22 +0100 Subject: [PATCH 1713/9457] mac802154: remove might_sleep from driver layer This patch removes all might_sleep calls from driver layer. This handling is already done by mac802154 layer. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 3 --- drivers/net/ieee802154/cc2520.c | 1 - drivers/net/ieee802154/fakelb.c | 4 ---- 3 files changed, 8 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 5068c1bd0046..b83ad0b38688 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -993,7 +993,6 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) static int at86rf230_ed(struct ieee802154_hw *hw, u8 *level) { - might_sleep(); BUG_ON(!level); *level = 0xbe; return 0; @@ -1048,8 +1047,6 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel) struct at86rf230_local *lp = hw->priv; int rc; - might_sleep(); - if (page < 0 || page > 31 || !(lp->hw->phy->channels_supported[page] & BIT(channel))) { WARN_ON(1); diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 78ea2cadeb78..c56d10c7ccfa 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -574,7 +574,6 @@ cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel) struct cc2520_private *priv = hw->priv; int ret; - might_sleep(); dev_dbg(&priv->spi->dev, "trying to set channel\n"); BUG_ON(page != 0); diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 4092e704c4aa..6e62286cef78 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -47,7 +47,6 @@ struct fakelb_priv { static int fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level) { - might_sleep(); BUG_ON(!level); *level = 0xbe; @@ -59,7 +58,6 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { pr_debug("set channel to %d\n", channel); - might_sleep(); hw->phy->current_page = page; hw->phy->current_channel = channel; @@ -85,8 +83,6 @@ fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) struct fakelb_dev_priv *priv = hw->priv; struct fakelb_priv *fake = priv->fake; - might_sleep(); - read_lock_bh(&fake->lock); if (priv->list.next == priv->list.prev) { /* we are the only one device */ -- GitLab From a543c5989d7711d984608f4e12a73218642ca865 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:23 +0100 Subject: [PATCH 1714/9457] mac802154: remove driver ops in wpan-phy This patch removes the driver ops callbacks inside of wpan_phy struct. It was used to check if a phy supports this driver ops call. We do this now via hardware flags. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 8 ---- net/ieee802154/nl-mac.c | 19 +-------- net/mac802154/iface.c | 12 +++--- net/mac802154/main.c | 85 ----------------------------------------- 4 files changed, 8 insertions(+), 116 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 5c674673ef20..440b9bece9c6 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -57,14 +57,6 @@ struct wpan_phy { const char *name, int type); void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); - int (*set_txpower)(struct wpan_phy *phy, int db); - int (*set_lbt)(struct wpan_phy *phy, bool on); - int (*set_cca_mode)(struct wpan_phy *phy, u8 cca_mode); - int (*set_cca_ed_level)(struct wpan_phy *phy, int level); - int (*set_csma_params)(struct wpan_phy *phy, u8 min_be, u8 max_be, - u8 retries); - int (*set_frame_retries)(struct wpan_phy *phy, s8 retries); - char priv[0] __aligned(NETDEV_ALIGN); }; diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index fb6866d1dd39..abd0f31bdc66 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -664,20 +664,6 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) phy = ops->get_phy(dev); - if ((!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) || - (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) || - (!phy->set_cca_ed_level && - info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) || - (!phy->set_csma_params && - (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] || - info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] || - info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])) || - (!phy->set_frame_retries && - info->attrs[IEEE802154_ATTR_FRAME_RETRIES])) { - rc = -EOPNOTSUPP; - goto out_phy; - } - ops->get_mac_params(dev, ¶ms); if (info->attrs[IEEE802154_ATTR_TXPOWER]) @@ -708,10 +694,9 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) wpan_phy_put(phy); dev_put(dev); - return rc; -out_phy: - wpan_phy_put(phy); + return 0; + out: dev_put(dev); return rc; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 025cd5aba13f..300877a1a0c9 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -196,32 +196,32 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); - if (phy->set_txpower) { + if (local->hw.flags & IEEE802154_HW_TXPOWER) { rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) goto out; } - if (phy->set_lbt) { + if (local->hw.flags & IEEE802154_HW_LBT) { rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); if (rc < 0) goto out; } - if (phy->set_cca_mode) { + if (local->hw.flags & IEEE802154_HW_CCA_MODE) { rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode); if (rc < 0) goto out; } - if (phy->set_cca_ed_level) { + if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) { rc = drv_set_cca_ed_level(local, sdata->mac_params.cca_ed_level); if (rc < 0) goto out; } - if (phy->set_csma_params) { + if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { rc = drv_set_csma_params(local, sdata->mac_params.min_be, sdata->mac_params.max_be, sdata->mac_params.csma_retries); @@ -229,7 +229,7 @@ static int mac802154_wpan_open(struct net_device *dev) goto out; } - if (phy->set_frame_retries) { + if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { rc = drv_set_max_frame_retries(local, sdata->mac_params.frame_retries); if (rc < 0) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 24ecc09de2a4..9fa9514b3a36 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -121,49 +121,6 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) return ERR_PTR(err); } -static int mac802154_set_txpower(struct wpan_phy *phy, int db) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_tx_power(local, db); -} - -static int mac802154_set_lbt(struct wpan_phy *phy, bool on) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_lbt_mode(local, on); -} - -static int mac802154_set_cca_mode(struct wpan_phy *phy, u8 mode) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_cca_mode(local, mode); -} - -static int mac802154_set_cca_ed_level(struct wpan_phy *phy, s32 level) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_cca_ed_level(local, level); -} - -static int mac802154_set_csma_params(struct wpan_phy *phy, u8 min_be, - u8 max_be, u8 retries) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_csma_params(local, min_be, max_be, retries); -} - -static int mac802154_set_frame_retries(struct wpan_phy *phy, s8 retries) -{ - struct ieee802154_local *local = wpan_phy_priv(phy); - - return drv_set_max_frame_retries(local, retries); -} - static void ieee802154_tasklet_handler(unsigned long data) { struct ieee802154_local *local = (struct ieee802154_local *)data; @@ -262,48 +219,6 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) struct ieee802154_local *local = hw_to_local(hw); int rc = -ENOSYS; - if (hw->flags & IEEE802154_HW_TXPOWER) { - if (!local->ops->set_txpower) - goto out; - - local->phy->set_txpower = mac802154_set_txpower; - } - - if (hw->flags & IEEE802154_HW_LBT) { - if (!local->ops->set_lbt) - goto out; - - local->phy->set_lbt = mac802154_set_lbt; - } - - if (hw->flags & IEEE802154_HW_CCA_MODE) { - if (!local->ops->set_cca_mode) - goto out; - - local->phy->set_cca_mode = mac802154_set_cca_mode; - } - - if (hw->flags & IEEE802154_HW_CCA_ED_LEVEL) { - if (!local->ops->set_cca_ed_level) - goto out; - - local->phy->set_cca_ed_level = mac802154_set_cca_ed_level; - } - - if (hw->flags & IEEE802154_HW_CSMA_PARAMS) { - if (!local->ops->set_csma_params) - goto out; - - local->phy->set_csma_params = mac802154_set_csma_params; - } - - if (hw->flags & IEEE802154_HW_FRAME_RETRIES) { - if (!local->ops->set_frame_retries) - goto out; - - local->phy->set_frame_retries = mac802154_set_frame_retries; - } - local->workqueue = create_singlethread_workqueue(wpan_phy_name(local->phy)); if (!local->workqueue) { -- GitLab From 0ea3da64fa602efa0a89502eefdb396be84d2eba Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:24 +0100 Subject: [PATCH 1715/9457] mac802154: rework sdata state change to running This patch reworks the handling for setting the state like mac80211. We use bit's instead a bool variable. The mutex is not needed because it use test and set bits which are atomic operations. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 12 +++++++++++- net/mac802154/iface.c | 12 +++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index a379b971b13c..e34fe51043f2 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -67,6 +67,10 @@ enum { IEEE802154_RX_MSG = 1, }; +enum ieee802154_sdata_state_bits { + SDATA_STATE_RUNNING, +}; + /* Slave interface definition. * * Slaves represent typical network interfaces available from userspace. @@ -80,7 +84,7 @@ struct ieee802154_sub_if_data { struct net_device *dev; int type; - bool running; + unsigned long state; spinlock_t mib_lock; @@ -120,6 +124,12 @@ IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) return netdev_priv(dev); } +static inline bool +ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) +{ + return test_bit(SDATA_STATE_RUNNING, &sdata->state); +} + extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 300877a1a0c9..e10fd786a11f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -156,7 +156,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_lock(&sdata->local->iflist_mtx); list_for_each_entry(subif, &sdata->local->interfaces, list) { if (subif != sdata && subif->type == sdata->type && - subif->running) { + ieee802154_sdata_running(subif)) { mutex_unlock(&sdata->local->iflist_mtx); return -EBUSY; } @@ -164,9 +164,7 @@ static int mac802154_slave_open(struct net_device *dev) mutex_unlock(&sdata->local->iflist_mtx); } - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = true; - mutex_unlock(&sdata->local->iflist_mtx); + set_bit(SDATA_STATE_RUNNING, &sdata->state); if (local->open_count++ == 0) { res = drv_start(local); @@ -178,6 +176,8 @@ static int mac802154_slave_open(struct net_device *dev) netif_start_queue(dev); return 0; err: + /* might already be clear but that doesn't matter */ + clear_bit(SDATA_STATE_RUNNING, &sdata->state); sdata->local->open_count--; return res; @@ -253,9 +253,7 @@ static int mac802154_slave_close(struct net_device *dev) netif_stop_queue(dev); - mutex_lock(&sdata->local->iflist_mtx); - sdata->running = false; - mutex_unlock(&sdata->local->iflist_mtx); + clear_bit(SDATA_STATE_RUNNING, &sdata->state); if (!--local->open_count) drv_stop(local); -- GitLab From 5d65cae4bf6ffe29bba90f621e947922c5fb80db Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:25 +0100 Subject: [PATCH 1716/9457] mac802154: rename running to started This variable should be handled like ieee80211_local struct of mac80211. We rename this variable to started now to have the same name convention. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index e34fe51043f2..f52afd4ced92 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -54,7 +54,7 @@ struct ieee802154_local { * This flag should be modified under slaves_mtx and RTNL, so you can * read them using any of protection methods. */ - bool running; + bool started; struct tasklet_struct tasklet; struct sk_buff_head skb_queue; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 9fa9514b3a36..7458f71c151c 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -47,7 +47,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); mutex_lock(&local->iflist_mtx); - if (!local->running) { + if (!local->started) { mutex_unlock(&local->iflist_mtx); return -ENODEV; } @@ -238,7 +238,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); mutex_lock(&local->iflist_mtx); - local->running = MAC802154_DEVICE_RUN; + local->started = MAC802154_DEVICE_RUN; mutex_unlock(&local->iflist_mtx); rtnl_unlock(); @@ -264,7 +264,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); mutex_lock(&local->iflist_mtx); - local->running = MAC802154_DEVICE_STOPPED; + local->started = MAC802154_DEVICE_STOPPED; mutex_unlock(&local->iflist_mtx); list_for_each_entry_safe(sdata, next, &local->interfaces, list) { -- GitLab From e363eca386d0c28d8c6c4f176e1fa48b09a75315 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:26 +0100 Subject: [PATCH 1717/9457] mac802154: move local started handling This patch removes the current handling of started boolean. This is actually dead code, because mac802154_netdev_register can't never be called before ieee802154_register_hw. This means that local->started is always be true when mac802154_netdev_register is called. Instead we using this now like mac80211 to indicate that an instance of sdata is running. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 4 ++++ net/mac802154/ieee802154_i.h | 7 ------- net/mac802154/main.c | 19 ------------------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index bf7980bbceff..bb3ee03c1669 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -29,6 +29,8 @@ static inline int drv_start(struct ieee802154_local *local) { might_sleep(); + local->started = true; + return local->ops->start(&local->hw); } @@ -37,6 +39,8 @@ static inline void drv_stop(struct ieee802154_local *local) might_sleep(); local->ops->stop(&local->hw); + + local->started = false; } static inline int drv_set_channel(struct ieee802154_local *local, diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index f52afd4ced92..bf0b5f613c36 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -50,19 +50,12 @@ struct ieee802154_local { */ struct workqueue_struct *workqueue; - /* SoftMAC device is registered and running. One can add subinterfaces. - * This flag should be modified under slaves_mtx and RTNL, so you can - * read them using any of protection methods. - */ bool started; struct tasklet_struct tasklet; struct sk_buff_head skb_queue; }; -#define MAC802154_DEVICE_STOPPED 0x00 -#define MAC802154_DEVICE_RUN 0x01 - enum { IEEE802154_RX_MSG = 1, }; diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 7458f71c151c..21dcc56930d1 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -46,13 +46,6 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) SET_NETDEV_DEV(dev, &local->phy->dev); - mutex_lock(&local->iflist_mtx); - if (!local->started) { - mutex_unlock(&local->iflist_mtx); - return -ENODEV; - } - mutex_unlock(&local->iflist_mtx); - err = register_netdev(dev); if (err < 0) return err; @@ -235,14 +228,6 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) if (rc < 0) goto out_wq; - rtnl_lock(); - - mutex_lock(&local->iflist_mtx); - local->started = MAC802154_DEVICE_RUN; - mutex_unlock(&local->iflist_mtx); - - rtnl_unlock(); - return 0; out_wq: @@ -263,10 +248,6 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); - mutex_lock(&local->iflist_mtx); - local->started = MAC802154_DEVICE_STOPPED; - mutex_unlock(&local->iflist_mtx); - list_for_each_entry_safe(sdata, next, &local->interfaces, list) { mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); -- GitLab From 538181a879368f54544b91e414ea56a88008782b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:27 +0100 Subject: [PATCH 1718/9457] mac802154: add synchronization handling This patch adds synchronization handling in start and stop driver ops calls. This patch is mostly grab from mac80211 which was introduced by commit ea77f12f2cc0f31168f2e0259e65a22202ac4dc2 ("mac80211: remove tasklet enable/disable"). This is to be sure that we don't run into same issues. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index bb3ee03c1669..4b820cfeb538 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -30,6 +30,7 @@ static inline int drv_start(struct ieee802154_local *local) might_sleep(); local->started = true; + smp_mb(); return local->ops->start(&local->hw); } @@ -40,6 +41,12 @@ static inline void drv_stop(struct ieee802154_local *local) local->ops->stop(&local->hw); + /* sync away all work on the tasklet before clearing started */ + tasklet_disable(&local->tasklet); + tasklet_enable(&local->tasklet); + + barrier(); + local->started = false; } -- GitLab From 33d4189f51f0dbb522a4d81aafc7edb2e048c570 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:28 +0100 Subject: [PATCH 1719/9457] mac802154: iface: remove assign to zero These variables should already be zero, so we remove the extra assign to zero. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index e10fd786a11f..2423aa7671df 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -409,7 +409,6 @@ void mac802154_wpan_setup(struct net_device *dev) dev->tx_queue_len = 300; dev->type = ARPHRD_IEEE802154; dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; dev->destructor = mac802154_wpan_free; dev->netdev_ops = &mac802154_wpan_ops; @@ -419,7 +418,6 @@ void mac802154_wpan_setup(struct net_device *dev) sdata->type = IEEE802154_DEV_WPAN; sdata->chan = MAC802154_CHAN_NONE; - sdata->page = 0; spin_lock_init(&sdata->mib_lock); mutex_init(&sdata->sec_mtx); @@ -444,14 +442,11 @@ void mac802154_monitor_setup(struct net_device *dev) { struct ieee802154_sub_if_data *sdata; - dev->addr_len = 0; - dev->hard_header_len = 0; dev->needed_tailroom = 2; /* room for FCS */ dev->mtu = IEEE802154_MTU; dev->tx_queue_len = 10; dev->type = ARPHRD_IEEE802154_MONITOR; dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; dev->destructor = free_netdev; dev->netdev_ops = &mac802154_monitor_ops; @@ -461,5 +456,4 @@ void mac802154_monitor_setup(struct net_device *dev) sdata->type = IEEE802154_DEV_MONITOR; sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ - sdata->page = 0; } -- GitLab From 12439a53560097bc8e42cf14967717d14588dddd Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:29 +0100 Subject: [PATCH 1720/9457] mac802154: remove channel attributes from sdata These channel attributes was part of "channel context switch while xmit" which was removed by commit dc67c6b30f36d57b70b70547a30e7a8432540c6f ("mac802154: tx: remove xmit channel context switch"). This patch removes these unnecessary variables and use the current_page and current_channel by wpan_phy struct now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 -- net/mac802154/iface.c | 4 --- net/mac802154/mib.c | 55 ++++++------------------------------ 3 files changed, 9 insertions(+), 53 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index bf0b5f613c36..46c9fe7ba2b2 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -85,9 +85,6 @@ struct ieee802154_sub_if_data { __le16 short_addr; __le64 extended_addr; - u8 chan; - u8 page; - struct ieee802154_mac_params mac_params; /* MAC BSN field */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 2423aa7671df..1c0274ed9370 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -417,8 +417,6 @@ void mac802154_wpan_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_WPAN; - sdata->chan = MAC802154_CHAN_NONE; - spin_lock_init(&sdata->mib_lock); mutex_init(&sdata->sec_mtx); @@ -454,6 +452,4 @@ void mac802154_monitor_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; - - sdata->chan = MAC802154_CHAN_NONE; /* not initialized */ } diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 3fbc217dbdcc..0184fced2f62 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -26,11 +26,6 @@ #include "ieee802154_i.h" #include "driver-ops.h" -struct phy_chan_notify_work { - struct work_struct work; - struct net_device *dev; -}; - struct hw_addr_filt_notify_work { struct work_struct work; struct net_device *dev; @@ -161,54 +156,22 @@ u8 mac802154_dev_get_dsn(const struct net_device *dev) return sdata->dsn++; } -static void phy_chan_notify(struct work_struct *work) -{ - struct phy_chan_notify_work *nw = container_of(work, - struct phy_chan_notify_work, work); - struct net_device *dev = nw->dev; - struct ieee802154_local *local = mac802154_slave_get_priv(dev); - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - int res; - - mutex_lock(&sdata->local->phy->pib_lock); - res = drv_set_channel(local, sdata->page, sdata->chan); - if (res) { - pr_debug("set_channel failed\n"); - } else { - sdata->local->phy->current_channel = sdata->chan; - sdata->local->phy->current_page = sdata->page; - } - mutex_unlock(&sdata->local->phy->pib_lock); - - kfree(nw); -} - void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct phy_chan_notify_work *work; + struct ieee802154_local *local = sdata->local; + int res; BUG_ON(dev->type != ARPHRD_IEEE802154); - spin_lock_bh(&sdata->mib_lock); - sdata->page = page; - sdata->chan = chan; - spin_unlock_bh(&sdata->mib_lock); - - mutex_lock(&sdata->local->phy->pib_lock); - if (sdata->local->phy->current_channel != sdata->chan || - sdata->local->phy->current_page != sdata->page) { - mutex_unlock(&sdata->local->phy->pib_lock); - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, phy_chan_notify); - work->dev = dev; - queue_work(sdata->local->workqueue, &work->work); + res = drv_set_channel(local, page, chan); + if (res) { + pr_debug("set_channel failed\n"); } else { - mutex_unlock(&sdata->local->phy->pib_lock); + mutex_lock(&local->phy->pib_lock); + local->phy->current_channel = chan; + local->phy->current_page = page; + mutex_unlock(&local->phy->pib_lock); } } -- GitLab From c7420c367d63a7e1414e010afb52c3837fd9134e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:30 +0100 Subject: [PATCH 1721/9457] mac802154: move mac_params functions into mac_cmd These functions can be static in mac_cmd file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 5 ----- net/mac802154/mac_cmd.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 46c9fe7ba2b2..7cebc9844c00 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -140,11 +140,6 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); u8 mac802154_dev_get_dsn(const struct net_device *dev); -int mac802154_set_mac_params(struct net_device *dev, - const struct ieee802154_mac_params *params); -void mac802154_get_mac_params(struct net_device *dev, - struct ieee802154_mac_params *params); - int mac802154_get_params(struct net_device *dev, struct ieee802154_llsec_params *params); int mac802154_set_params(struct net_device *dev, diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index ed767f590ef9..fc261ab33347 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -82,6 +82,28 @@ static struct wpan_phy *mac802154_get_phy(const struct net_device *dev) return to_phy(get_device(&sdata->local->phy->dev)); } +static int mac802154_set_mac_params(struct net_device *dev, + const struct ieee802154_mac_params *params) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + + mutex_lock(&sdata->local->iflist_mtx); + sdata->mac_params = *params; + mutex_unlock(&sdata->local->iflist_mtx); + + return 0; +} + +static void mac802154_get_mac_params(struct net_device *dev, + struct ieee802154_mac_params *params) +{ + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + + mutex_lock(&sdata->local->iflist_mtx); + *params = sdata->mac_params; + mutex_unlock(&sdata->local->iflist_mtx); +} + static struct ieee802154_llsec_ops mac802154_llsec_ops = { .get_params = mac802154_get_params, .set_params = mac802154_set_params, -- GitLab From 74457641558baded3c9f05bc3fb81293a2c02b2e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:31 +0100 Subject: [PATCH 1722/9457] mac802154: cleanup open count handling This patch cleanups the open_count variable increment in open and close calls of netdev. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 1c0274ed9370..c0bf5f9b9953 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -166,19 +166,19 @@ static int mac802154_slave_open(struct net_device *dev) set_bit(SDATA_STATE_RUNNING, &sdata->state); - if (local->open_count++ == 0) { + if (!local->open_count) { res = drv_start(local); WARN_ON(res); if (res) goto err; } + local->open_count++; netif_start_queue(dev); return 0; err: /* might already be clear but that doesn't matter */ clear_bit(SDATA_STATE_RUNNING, &sdata->state); - sdata->local->open_count--; return res; } @@ -252,10 +252,11 @@ static int mac802154_slave_close(struct net_device *dev) ASSERT_RTNL(); netif_stop_queue(dev); + local->open_count--; clear_bit(SDATA_STATE_RUNNING, &sdata->state); - if (!--local->open_count) + if (!local->open_count) drv_stop(local); return 0; -- GitLab From e23e9ec16bf4bbaf12fc030079b277cb00f618f4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 28 Oct 2014 18:21:32 +0100 Subject: [PATCH 1723/9457] ieee802154: introduce sysfs file This patch moves the sysfs handling in a own file. This is like wireless sysfs file handling. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/Makefile | 2 +- net/ieee802154/core.c | 73 ++------------------------------ net/ieee802154/sysfs.c | 94 +++++++++++++++++++++++++++++++++++++++++ net/ieee802154/sysfs.h | 9 ++++ 4 files changed, 108 insertions(+), 70 deletions(-) create mode 100644 net/ieee802154/sysfs.c create mode 100644 net/ieee802154/sysfs.h diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index e58c4cbb3639..38354d4a70cb 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ - header_ops.o + header_ops.o sysfs.o af_802154-y := af_ieee802154.o raw.o dgram.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 760b7d752190..620abc2ba5fc 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -20,72 +20,7 @@ #include #include "ieee802154.h" - -#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ -static ssize_t name ## _show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ - int ret; \ - \ - mutex_lock(&phy->pib_lock); \ - ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ - mutex_unlock(&phy->pib_lock); \ - return ret; \ -} \ -static DEVICE_ATTR_RO(name) - -#define MASTER_SHOW(field, format_string) \ - MASTER_SHOW_COMPLEX(field, format_string, phy->field) - -MASTER_SHOW(current_channel, "%d"); -MASTER_SHOW(current_page, "%d"); -MASTER_SHOW(transmit_power, "%d +- 1 dB"); -MASTER_SHOW(cca_mode, "%d"); - -static ssize_t channels_supported_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); - int ret; - int i, len = 0; - - mutex_lock(&phy->pib_lock); - for (i = 0; i < 32; i++) { - ret = snprintf(buf + len, PAGE_SIZE - len, - "%#09x\n", phy->channels_supported[i]); - if (ret < 0) - break; - len += ret; - } - mutex_unlock(&phy->pib_lock); - return len; -} -static DEVICE_ATTR_RO(channels_supported); - -static struct attribute *pmib_attrs[] = { - &dev_attr_current_channel.attr, - &dev_attr_current_page.attr, - &dev_attr_channels_supported.attr, - &dev_attr_transmit_power.attr, - &dev_attr_cca_mode.attr, - NULL, -}; -ATTRIBUTE_GROUPS(pmib); - -static void wpan_phy_release(struct device *d) -{ - struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); - - kfree(phy); -} - -static struct class wpan_phy_class = { - .name = "ieee802154", - .dev_release = wpan_phy_release, - .dev_groups = pmib_groups, -}; +#include "sysfs.h" static DEFINE_MUTEX(wpan_phy_mutex); static int wpan_phy_idx; @@ -197,7 +132,7 @@ static int __init wpan_phy_class_init(void) { int rc; - rc = class_register(&wpan_phy_class); + rc = wpan_phy_sysfs_init(); if (rc) goto err; @@ -207,7 +142,7 @@ static int __init wpan_phy_class_init(void) return 0; err_nl: - class_unregister(&wpan_phy_class); + wpan_phy_sysfs_exit(); err: return rc; } @@ -216,7 +151,7 @@ subsys_initcall(wpan_phy_class_init); static void __exit wpan_phy_class_exit(void) { ieee802154_nl_exit(); - class_unregister(&wpan_phy_class); + wpan_phy_sysfs_exit(); } module_exit(wpan_phy_class_exit); diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c new file mode 100644 index 000000000000..eb9ca6f99122 --- /dev/null +++ b/net/ieee802154/sysfs.c @@ -0,0 +1,94 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/wireless/sysfs.c + */ + +#include + +#include + +#define MASTER_SHOW_COMPLEX(name, format_string, args...) \ +static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ + int ret; \ + \ + mutex_lock(&phy->pib_lock); \ + ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ + mutex_unlock(&phy->pib_lock); \ + return ret; \ +} \ +static DEVICE_ATTR_RO(name) + +#define MASTER_SHOW(field, format_string) \ + MASTER_SHOW_COMPLEX(field, format_string, phy->field) + +MASTER_SHOW(current_channel, "%d"); +MASTER_SHOW(current_page, "%d"); +MASTER_SHOW(transmit_power, "%d +- 1 dB"); +MASTER_SHOW(cca_mode, "%d"); + +static ssize_t channels_supported_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); + int ret; + int i, len = 0; + + mutex_lock(&phy->pib_lock); + for (i = 0; i < 32; i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, + "%#09x\n", phy->channels_supported[i]); + if (ret < 0) + break; + len += ret; + } + mutex_unlock(&phy->pib_lock); + return len; +} +static DEVICE_ATTR_RO(channels_supported); + +static void wpan_phy_release(struct device *d) +{ + struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); + + kfree(phy); +} + +static struct attribute *pmib_attrs[] = { + &dev_attr_current_channel.attr, + &dev_attr_current_page.attr, + &dev_attr_channels_supported.attr, + &dev_attr_transmit_power.attr, + &dev_attr_cca_mode.attr, + NULL, +}; +ATTRIBUTE_GROUPS(pmib); + +struct class wpan_phy_class = { + .name = "ieee802154", + .dev_release = wpan_phy_release, + .dev_groups = pmib_groups, +}; + +int wpan_phy_sysfs_init(void) +{ + return class_register(&wpan_phy_class); +} + +void wpan_phy_sysfs_exit(void) +{ + class_unregister(&wpan_phy_class); +} diff --git a/net/ieee802154/sysfs.h b/net/ieee802154/sysfs.h new file mode 100644 index 000000000000..aa42e39ecbec --- /dev/null +++ b/net/ieee802154/sysfs.h @@ -0,0 +1,9 @@ +#ifndef __IEEE802154_SYSFS_H +#define __IEEE802154_SYSFS_H + +int wpan_phy_sysfs_init(void); +void wpan_phy_sysfs_exit(void); + +extern struct class wpan_phy_class; + +#endif /* __IEEE802154_SYSFS_H */ -- GitLab From e9600bc166d529cf03862afae51fb2e3cf987d02 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 28 Oct 2014 17:37:12 +0000 Subject: [PATCH 1724/9457] ASoC: Intel: Make ADSP memory block allocation more generic Current block allocation is tied to block type and requestor type. Make the allocation more generic by removing the struct module parameter and adding a generic block allocator structure. Also pass in the list that the blocks have to be added too in order to remove dependence on block requestor type. ASoC: Intel: update scratch allocator to use generic block allocator Update the scratch allocator to use the generic block allocator and calculate total scratch buffer size. ASoC: Intel: Add call to calculate offsets internally within the DSP. A call to calculate internal DSP memory addresses used to allocate persistent and scartch buffers. ASoC: Intel: Add runtime module support. Add support for runtime module objects that can be created for every FW module that is parsed from the FW file. This gives a 1:N mapping between the FW module from file and the runtime instantiations of that module. We also need to make sure we remove every module and runtime module when we unload the FW. ASoC: Intel: Add DMA firmware loading support Add support for DMA to load firmware modules to the DSP memory blocks. Two DMA engines are supported, DesignWare and Intel MID. ASoC: Intel: Add runtime module lookup API call Add an API to allow quick lookup of runtime modules based on ID. ASoC: Intel: Provide streams with dynamic module information Remove the hard coded module paramaters and provide each module with dynamically generated buffer information for scratch and persistent buffers. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-baytrail-dsp.c | 24 +- sound/soc/intel/sst-dsp-priv.h | 133 +++-- sound/soc/intel/sst-dsp.c | 8 + sound/soc/intel/sst-dsp.h | 7 + sound/soc/intel/sst-firmware.c | 929 +++++++++++++++++++++++------ sound/soc/intel/sst-haswell-dsp.c | 59 +- sound/soc/intel/sst-haswell-ipc.c | 112 ++-- sound/soc/intel/sst-haswell-ipc.h | 11 +- sound/soc/intel/sst-haswell-pcm.c | 83 ++- 9 files changed, 1025 insertions(+), 341 deletions(-) diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/sst-baytrail-dsp.c index fc588764ffa3..5a9e56700f31 100644 --- a/sound/soc/intel/sst-baytrail-dsp.c +++ b/sound/soc/intel/sst-baytrail-dsp.c @@ -67,17 +67,12 @@ static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, { struct dma_block_info *block; struct sst_module *mod; - struct sst_module_data block_data; struct sst_module_template template; int count; memset(&template, 0, sizeof(template)); template.id = module->type; template.entry = module->entry_point; - template.p.type = SST_MEM_DRAM; - template.p.data_type = SST_DATA_P; - template.s.type = SST_MEM_DRAM; - template.s.data_type = SST_DATA_S; mod = sst_module_new(fw, &template, NULL); if (mod == NULL) @@ -94,19 +89,19 @@ static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, switch (block->type) { case SST_BYT_IRAM: - block_data.offset = block->ram_offset + + mod->offset = block->ram_offset + dsp->addr.iram_offset; - block_data.type = SST_MEM_IRAM; + mod->type = SST_MEM_IRAM; break; case SST_BYT_DRAM: - block_data.offset = block->ram_offset + + mod->offset = block->ram_offset + dsp->addr.dram_offset; - block_data.type = SST_MEM_DRAM; + mod->type = SST_MEM_DRAM; break; case SST_BYT_CACHE: - block_data.offset = block->ram_offset + + mod->offset = block->ram_offset + (dsp->addr.fw_ext - dsp->addr.lpe); - block_data.type = SST_MEM_CACHE; + mod->type = SST_MEM_CACHE; break; default: dev_err(dsp->dev, "wrong ram type 0x%x in block0x%x\n", @@ -114,11 +109,10 @@ static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, return -EINVAL; } - block_data.size = block->size; - block_data.data_type = SST_DATA_M; - block_data.data = (void *)block + sizeof(*block); + mod->size = block->size; + mod->data = (void *)block + sizeof(*block); - sst_module_insert_fixed_block(mod, &block_data); + sst_module_alloc_blocks(mod); block = (void *)block + sizeof(*block) + block->size; } diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index ffb308bd81ce..be81b86b6462 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h @@ -26,6 +26,9 @@ struct sst_mem_block; struct sst_module; struct sst_fw; +/* do we need to remove or keep */ +#define DSP_DRAM_ADDR_OFFSET 0x400000 + /* * DSP Operations exported by platform Audio DSP driver. */ @@ -67,6 +70,8 @@ struct sst_addr { u32 shim_offset; u32 iram_offset; u32 dram_offset; + u32 dsp_iram_offset; + u32 dsp_dram_offset; void __iomem *lpe; void __iomem *shim; void __iomem *pci_cfg; @@ -83,15 +88,6 @@ struct sst_mailbox { size_t out_size; }; -/* - * Audio DSP Firmware data types. - */ -enum sst_data_type { - SST_DATA_M = 0, /* module block data */ - SST_DATA_P = 1, /* peristant data (text, data) */ - SST_DATA_S = 2, /* scratch data (usually buffers) */ -}; - /* * Audio DSP memory block types. */ @@ -124,23 +120,6 @@ struct sst_fw { void *private; /* core doesn't touch this */ }; -/* - * Audio DSP Generic Module data. - * - * This is used to dsecribe any sections of persistent (text and data) and - * scratch (buffers) of module data in ADSP memory space. - */ -struct sst_module_data { - - enum sst_mem_type type; /* destination memory type */ - enum sst_data_type data_type; /* type of module data */ - - u32 size; /* size in bytes */ - int32_t offset; /* offset in FW file */ - u32 data_offset; /* offset in ADSP memory space */ - void *data; /* module data */ -}; - /* * Audio DSP Generic Module Template. * @@ -150,15 +129,52 @@ struct sst_module_data { struct sst_module_template { u32 id; u32 entry; /* entry point */ - struct sst_module_data s; /* scratch data */ - struct sst_module_data p; /* peristant data */ + u32 scratch_size; + u32 persistent_size; +}; + +/* + * Block Allocator - Used to allocate blocks of DSP memory. + */ +struct sst_block_allocator { + u32 id; + u32 offset; + int size; + enum sst_mem_type type; +}; + +/* + * Runtime Module Instance - A module object can be instanciated multiple + * times within the DSP FW. + */ +struct sst_module_runtime { + struct sst_dsp *dsp; + int id; + struct sst_module *module; /* parent module we belong too */ + + u32 persistent_offset; /* private memory offset */ + void *private; + + struct list_head list; + struct list_head block_list; /* list of blocks used */ +}; + +/* + * Runtime Module Context - The runtime context must be manually stored by the + * driver prior to enter S3 and restored after leaving S3. This should really be + * part of the memory context saved by the enter D3 message IPC ??? + */ +struct sst_module_runtime_context { + dma_addr_t dma_buffer; + u32 *buffer; }; /* * Audio DSP Generic Module. * * Each Firmware file can consist of 1..N modules. A module can span multiple - * ADSP memory blocks. The simplest FW will be a file with 1 module. + * ADSP memory blocks. The simplest FW will be a file with 1 module. A module + * can be instanciated multiple times in the DSP. */ struct sst_module { struct sst_dsp *dsp; @@ -167,10 +183,13 @@ struct sst_module { /* module configuration */ u32 id; u32 entry; /* module entry point */ - u32 offset; /* module offset in firmware file */ + s32 offset; /* module offset in firmware file */ u32 size; /* module size */ - struct sst_module_data s; /* scratch data */ - struct sst_module_data p; /* peristant data */ + u32 scratch_size; /* global scratch memory required */ + u32 persistent_size; /* private memory required */ + enum sst_mem_type type; /* destination memory type */ + u32 data_offset; /* offset in ADSP memory space */ + void *data; /* module data */ /* runtime */ u32 usage_count; /* can be unloaded if count == 0 */ @@ -180,6 +199,7 @@ struct sst_module { struct list_head block_list; /* Module list of blocks in use */ struct list_head list; /* DSP list of modules */ struct list_head list_fw; /* FW list of modules */ + struct list_head runtime_list; /* list of runtime module objects*/ }; /* @@ -208,7 +228,6 @@ struct sst_mem_block { struct sst_block_ops *ops; /* block operations, if any */ /* block status */ - enum sst_data_type data_type; /* data type held in this block */ u32 bytes_used; /* bytes in use by modules */ void *private; /* generic core does not touch this */ int users; /* number of modules using this block */ @@ -253,6 +272,11 @@ struct sst_dsp { struct list_head module_list; struct list_head fw_list; + /* scratch buffer */ + struct list_head scratch_block_list; + u32 scratch_offset; + u32 scratch_size; + /* platform data */ struct sst_pdata *pdata; @@ -290,18 +314,33 @@ void sst_fw_unload(struct sst_fw *sst_fw); /* Create/Free firmware modules */ struct sst_module *sst_module_new(struct sst_fw *sst_fw, struct sst_module_template *template, void *private); -void sst_module_free(struct sst_module *sst_module); -int sst_module_insert(struct sst_module *sst_module); -int sst_module_remove(struct sst_module *sst_module); -int sst_module_insert_fixed_block(struct sst_module *module, - struct sst_module_data *data); +void sst_module_free(struct sst_module *module); struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id); - -/* allocate/free pesistent/scratch memory regions managed by drv */ -struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp); -void sst_mem_block_free_scratch(struct sst_dsp *dsp, - struct sst_module *scratch); -int sst_block_module_remove(struct sst_module *module); +int sst_module_alloc_blocks(struct sst_module *module); +int sst_module_free_blocks(struct sst_module *module); + +/* Create/Free firmware module runtime instances */ +struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module, + int id, void *private); +void sst_module_runtime_free(struct sst_module_runtime *runtime); +struct sst_module_runtime *sst_module_runtime_get_from_id( + struct sst_module *module, u32 id); +int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime, + int offset); +int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime); +int sst_module_runtime_save(struct sst_module_runtime *runtime, + struct sst_module_runtime_context *context); +int sst_module_runtime_restore(struct sst_module_runtime *runtime, + struct sst_module_runtime_context *context); + +/* generic block allocation */ +int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba, + struct list_head *block_list); +int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list); + +/* scratch allocation */ +int sst_block_alloc_scratch(struct sst_dsp *dsp); +void sst_block_free_scratch(struct sst_dsp *dsp); /* Register the DSPs memory blocks - would be nice to read from ACPI */ struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, @@ -309,4 +348,10 @@ struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, void *private); void sst_mem_block_unregister_all(struct sst_dsp *dsp); +/* Create/Free DMA resources */ +int sst_dma_new(struct sst_dsp *sst); +void sst_dma_free(struct sst_dma *dma); + +u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset, + enum sst_mem_type type); #endif diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c index cd23060a0d86..d0fc6853b2b7 100644 --- a/sound/soc/intel/sst-dsp.c +++ b/sound/soc/intel/sst-dsp.c @@ -352,6 +352,7 @@ struct sst_dsp *sst_dsp_new(struct device *dev, INIT_LIST_HEAD(&sst->free_block_list); INIT_LIST_HEAD(&sst->module_list); INIT_LIST_HEAD(&sst->fw_list); + INIT_LIST_HEAD(&sst->scratch_block_list); /* Initialise SST Audio DSP */ if (sst->ops->init) { @@ -366,6 +367,10 @@ struct sst_dsp *sst_dsp_new(struct device *dev, if (err) goto irq_err; + err = sst_dma_new(sst); + if (err) + dev_warn(dev, "sst_dma_new failed %d\n", err); + return sst; irq_err: @@ -381,6 +386,9 @@ void sst_dsp_free(struct sst_dsp *sst) free_irq(sst->irq, sst); if (sst->ops->free) sst->ops->free(sst); + + if (sst->dma) + sst_dma_free(sst->dma); } EXPORT_SYMBOL_GPL(sst_dsp_free); diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h index 3165dfa97408..17ee9239092a 100644 --- a/sound/soc/intel/sst-dsp.h +++ b/sound/soc/intel/sst-dsp.h @@ -245,6 +245,13 @@ void sst_memcpy_fromio_32(struct sst_dsp *sst, /* DSP reset & boot */ void sst_dsp_reset(struct sst_dsp *sst); int sst_dsp_boot(struct sst_dsp *sst); +/* DMA */ +int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id); +void sst_dsp_dma_put_channel(struct sst_dsp *dsp); +int sst_dsp_dma_copyfrom(struct sst_dsp *sst, dma_addr_t dest_addr, + dma_addr_t src_addr, size_t size); +int sst_dsp_dma_copyto(struct sst_dsp *sst, dma_addr_t dest_addr, + dma_addr_t src_addr, size_t size); /* Msg IO */ void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg); diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index cf3d19997126..692a6aef82df 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -23,6 +23,11 @@ #include #include #include +#include + +/* supported DMA engine drivers */ +#include +#include #include #include @@ -30,7 +35,20 @@ #include "sst-dsp.h" #include "sst-dsp-priv.h" -static void block_module_remove(struct sst_module *module); +#define SST_DMA_RESOURCES 2 +#define SST_DSP_DMA_MAX_BURST 0x3 +#define SST_HSW_BLOCK_ANY 0xffffffff + +#define SST_HSW_MASK_DMA_ADDR_DSP 0xfff00000 + +struct sst_dma { + struct sst_dsp *sst; + + struct dw_dma_chip *chip; + + struct dma_async_tx_descriptor *desc; + struct dma_chan *ch; +}; static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) { @@ -38,6 +56,281 @@ static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 byte __iowrite32_copy((void *)dest, src, bytes/4); } +static void sst_dma_transfer_complete(void *arg) +{ + struct sst_dsp *sst = (struct sst_dsp *)arg; + + dev_dbg(sst->dev, "DMA: callback\n"); +} + +static int sst_dsp_dma_copy(struct sst_dsp *sst, dma_addr_t dest_addr, + dma_addr_t src_addr, size_t size) +{ + struct dma_async_tx_descriptor *desc; + struct sst_dma *dma = sst->dma; + + if (dma->ch == NULL) { + dev_err(sst->dev, "error: no DMA channel\n"); + return -ENODEV; + } + + dev_dbg(sst->dev, "DMA: src: 0x%lx dest 0x%lx size %zu\n", + (unsigned long)src_addr, (unsigned long)dest_addr, size); + + desc = dma->ch->device->device_prep_dma_memcpy(dma->ch, dest_addr, + src_addr, size, DMA_CTRL_ACK); + if (!desc){ + dev_err(sst->dev, "error: dma prep memcpy failed\n"); + return -EINVAL; + } + + desc->callback = sst_dma_transfer_complete; + desc->callback_param = sst; + + desc->tx_submit(desc); + dma_wait_for_async_tx(desc); + + return 0; +} + +/* copy to DSP */ +int sst_dsp_dma_copyto(struct sst_dsp *sst, dma_addr_t dest_addr, + dma_addr_t src_addr, size_t size) +{ + return sst_dsp_dma_copy(sst, dest_addr | SST_HSW_MASK_DMA_ADDR_DSP, + src_addr, size); +} +EXPORT_SYMBOL_GPL(sst_dsp_dma_copyto); + +/* copy from DSP */ +int sst_dsp_dma_copyfrom(struct sst_dsp *sst, dma_addr_t dest_addr, + dma_addr_t src_addr, size_t size) +{ + return sst_dsp_dma_copy(sst, dest_addr, + src_addr | SST_HSW_MASK_DMA_ADDR_DSP, size); +} +EXPORT_SYMBOL_GPL(sst_dsp_dma_copyfrom); + +/* remove module from memory - callers hold locks */ +static void block_list_remove(struct sst_dsp *dsp, + struct list_head *block_list) +{ + struct sst_mem_block *block, *tmp; + int err; + + /* disable each block */ + list_for_each_entry(block, block_list, module_list) { + + if (block->ops && block->ops->disable) { + err = block->ops->disable(block); + if (err < 0) + dev_err(dsp->dev, + "error: cant disable block %d:%d\n", + block->type, block->index); + } + } + + /* mark each block as free */ + list_for_each_entry_safe(block, tmp, block_list, module_list) { + list_del(&block->module_list); + list_move(&block->list, &dsp->free_block_list); + dev_dbg(dsp->dev, "block freed %d:%d at offset 0x%x\n", + block->type, block->index, block->offset); + } +} + +/* prepare the memory block to receive data from host - callers hold locks */ +static int block_list_prepare(struct sst_dsp *dsp, + struct list_head *block_list) +{ + struct sst_mem_block *block; + int ret = 0; + + /* enable each block so that's it'e ready for data */ + list_for_each_entry(block, block_list, module_list) { + + if (block->ops && block->ops->enable) { + ret = block->ops->enable(block); + if (ret < 0) { + dev_err(dsp->dev, + "error: cant disable block %d:%d\n", + block->type, block->index); + goto err; + } + } + } + return ret; + +err: + list_for_each_entry(block, block_list, module_list) { + if (block->ops && block->ops->disable) + block->ops->disable(block); + } + return ret; +} + +struct dw_dma_platform_data dw_pdata = { + .is_private = 1, + .chan_allocation_order = CHAN_ALLOCATION_ASCENDING, + .chan_priority = CHAN_PRIORITY_ASCENDING, +}; + +static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem, + int irq) +{ + struct dw_dma_chip *chip; + int err; + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return ERR_PTR(-ENOMEM); + + chip->irq = irq; + chip->regs = devm_ioremap_resource(dev, mem); + if (IS_ERR(chip->regs)) + return ERR_CAST(chip->regs); + + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31)); + if (err) + return ERR_PTR(err); + + chip->dev = dev; + err = dw_dma_probe(chip, &dw_pdata); + if (err) + return ERR_PTR(err); + + return chip; +} + +static void dw_remove(struct dw_dma_chip *chip) +{ + dw_dma_remove(chip); +} + +static bool dma_chan_filter(struct dma_chan *chan, void *param) +{ + struct sst_dsp *dsp = (struct sst_dsp *)param; + + return chan->device->dev == dsp->dma_dev; +} + +int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id) +{ + struct sst_dma *dma = dsp->dma; + struct dma_slave_config slave; + dma_cap_mask_t mask; + int ret; + + /* The Intel MID DMA engine driver needs the slave config set but + * Synopsis DMA engine driver safely ignores the slave config */ + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_MEMCPY, mask); + + dma->ch = dma_request_channel(mask, dma_chan_filter, dsp); + if (dma->ch == NULL) { + dev_err(dsp->dev, "error: DMA request channel failed\n"); + return -EIO; + } + + memset(&slave, 0, sizeof(slave)); + slave.direction = DMA_MEM_TO_DEV; + slave.src_addr_width = + slave.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + slave.src_maxburst = slave.dst_maxburst = SST_DSP_DMA_MAX_BURST; + + ret = dmaengine_slave_config(dma->ch, &slave); + if (ret) { + dev_err(dsp->dev, "error: unable to set DMA slave config %d\n", + ret); + dma_release_channel(dma->ch); + dma->ch = NULL; + } + + return ret; +} +EXPORT_SYMBOL_GPL(sst_dsp_dma_get_channel); + +void sst_dsp_dma_put_channel(struct sst_dsp *dsp) +{ + struct sst_dma *dma = dsp->dma; + + if (!dma->ch) + return; + + dma_release_channel(dma->ch); + dma->ch = NULL; +} +EXPORT_SYMBOL_GPL(sst_dsp_dma_put_channel); + +int sst_dma_new(struct sst_dsp *sst) +{ + struct sst_pdata *sst_pdata = sst->pdata; + struct sst_dma *dma; + struct resource mem; + const char *dma_dev_name; + int ret = 0; + + /* configure the correct platform data for whatever DMA engine + * is attached to the ADSP IP. */ + switch (sst->pdata->dma_engine) { + case SST_DMA_TYPE_DW: + dma_dev_name = "dw_dmac"; + break; + case SST_DMA_TYPE_MID: + dma_dev_name = "Intel MID DMA"; + break; + default: + dev_err(sst->dev, "error: invalid DMA engine %d\n", + sst->pdata->dma_engine); + return -EINVAL; + } + + dma = devm_kzalloc(sst->dev, sizeof(struct sst_dma), GFP_KERNEL); + if (!dma) + return -ENOMEM; + + dma->sst = sst; + + memset(&mem, 0, sizeof(mem)); + + mem.start = sst->addr.lpe_base + sst_pdata->dma_base; + mem.end = sst->addr.lpe_base + sst_pdata->dma_base + sst_pdata->dma_size - 1; + mem.flags = IORESOURCE_MEM; + + /* now register DMA engine device */ + dma->chip = dw_probe(sst->dma_dev, &mem, sst_pdata->irq); + if (IS_ERR(dma->chip)) { + dev_err(sst->dev, "error: DMA device register failed\n"); + ret = PTR_ERR(dma->chip); + goto err_dma_dev; + } + + sst->dma = dma; + sst->fw_use_dma = true; + return 0; + +err_dma_dev: + devm_kfree(sst->dev, dma); + return ret; +} +EXPORT_SYMBOL(sst_dma_new); + +void sst_dma_free(struct sst_dma *dma) +{ + + if (dma == NULL) + return; + + if (dma->ch) + dma_release_channel(dma->ch); + + if (dma->chip) + dw_remove(dma->chip); + +} +EXPORT_SYMBOL(sst_dma_free); + /* create new generic firmware object */ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, const struct firmware *fw, void *private) @@ -68,6 +361,12 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, /* copy FW data to DMA-able memory */ memcpy((void *)sst_fw->dma_buf, (void *)fw->data, fw->size); + if (dsp->fw_use_dma) { + err = sst_dsp_dma_get_channel(dsp, 0); + if (err < 0) + goto chan_err; + } + /* call core specific FW paser to load FW data into DSP */ err = dsp->ops->parse_fw(sst_fw); if (err < 0) { @@ -75,6 +374,9 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, goto parse_err; } + if (dsp->fw_use_dma) + sst_dsp_dma_put_channel(dsp); + mutex_lock(&dsp->mutex); list_add(&sst_fw->list, &dsp->fw_list); mutex_unlock(&dsp->mutex); @@ -82,9 +384,13 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, return sst_fw; parse_err: - dma_free_coherent(dsp->dev, sst_fw->size, + if (dsp->fw_use_dma) + sst_dsp_dma_put_channel(dsp); +chan_err: + dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf, sst_fw->dmable_fw_paddr); + sst_fw->dma_buf = NULL; kfree(sst_fw); return NULL; } @@ -108,21 +414,37 @@ EXPORT_SYMBOL_GPL(sst_fw_reload); void sst_fw_unload(struct sst_fw *sst_fw) { - struct sst_dsp *dsp = sst_fw->dsp; - struct sst_module *module, *tmp; + struct sst_dsp *dsp = sst_fw->dsp; + struct sst_module *module, *mtmp; + struct sst_module_runtime *runtime, *rtmp; + + dev_dbg(dsp->dev, "unloading firmware\n"); - dev_dbg(dsp->dev, "unloading firmware\n"); + mutex_lock(&dsp->mutex); + + /* check module by module */ + list_for_each_entry_safe(module, mtmp, &dsp->module_list, list) { + if (module->sst_fw == sst_fw) { + + /* remove runtime modules */ + list_for_each_entry_safe(runtime, rtmp, &module->runtime_list, list) { + + block_list_remove(dsp, &runtime->block_list); + list_del(&runtime->list); + kfree(runtime); + } + + /* now remove the module */ + block_list_remove(dsp, &module->block_list); + list_del(&module->list); + kfree(module); + } + } - mutex_lock(&dsp->mutex); - list_for_each_entry_safe(module, tmp, &dsp->module_list, list) { - if (module->sst_fw == sst_fw) { - block_module_remove(module); - list_del(&module->list); - kfree(module); - } - } + /* remove all scratch blocks */ + block_list_remove(dsp, &dsp->scratch_block_list); - mutex_unlock(&dsp->mutex); + mutex_unlock(&dsp->mutex); } EXPORT_SYMBOL_GPL(sst_fw_unload); @@ -135,7 +457,8 @@ void sst_fw_free(struct sst_fw *sst_fw) list_del(&sst_fw->list); mutex_unlock(&dsp->mutex); - dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf, + if (sst_fw->dma_buf) + dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf, sst_fw->dmable_fw_paddr); kfree(sst_fw); } @@ -172,11 +495,11 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw, sst_module->id = template->id; sst_module->dsp = dsp; sst_module->sst_fw = sst_fw; - - memcpy(&sst_module->s, &template->s, sizeof(struct sst_module_data)); - memcpy(&sst_module->p, &template->p, sizeof(struct sst_module_data)); + sst_module->scratch_size = template->scratch_size; + sst_module->persistent_size = template->persistent_size; INIT_LIST_HEAD(&sst_module->block_list); + INIT_LIST_HEAD(&sst_module->runtime_list); mutex_lock(&dsp->mutex); list_add(&sst_module->list, &dsp->module_list); @@ -199,73 +522,122 @@ void sst_module_free(struct sst_module *sst_module) } EXPORT_SYMBOL_GPL(sst_module_free); -static struct sst_mem_block *find_block(struct sst_dsp *dsp, int type, - u32 offset) +struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module, + int id, void *private) +{ + struct sst_dsp *dsp = module->dsp; + struct sst_module_runtime *runtime; + + runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + if (runtime == NULL) + return NULL; + + runtime->id = id; + runtime->dsp = dsp; + runtime->module = module; + INIT_LIST_HEAD(&runtime->block_list); + + mutex_lock(&dsp->mutex); + list_add(&runtime->list, &module->runtime_list); + mutex_unlock(&dsp->mutex); + + return runtime; +} +EXPORT_SYMBOL_GPL(sst_module_runtime_new); + +void sst_module_runtime_free(struct sst_module_runtime *runtime) +{ + struct sst_dsp *dsp = runtime->dsp; + + mutex_lock(&dsp->mutex); + list_del(&runtime->list); + mutex_unlock(&dsp->mutex); + + kfree(runtime); +} +EXPORT_SYMBOL_GPL(sst_module_runtime_free); + +static struct sst_mem_block *find_block(struct sst_dsp *dsp, + struct sst_block_allocator *ba) { struct sst_mem_block *block; list_for_each_entry(block, &dsp->free_block_list, list) { - if (block->type == type && block->offset == offset) + if (block->type == ba->type && block->offset == ba->offset) return block; } return NULL; } -static int block_alloc_contiguous(struct sst_module *module, - struct sst_module_data *data, u32 offset, int size) +/* Block allocator must be on block boundary */ +static int block_alloc_contiguous(struct sst_dsp *dsp, + struct sst_block_allocator *ba, struct list_head *block_list) { struct list_head tmp = LIST_HEAD_INIT(tmp); - struct sst_dsp *dsp = module->dsp; struct sst_mem_block *block; + u32 block_start = SST_HSW_BLOCK_ANY; + int size = ba->size, offset = ba->offset; - while (size > 0) { - block = find_block(dsp, data->type, offset); + while (ba->size > 0) { + + block = find_block(dsp, ba); if (!block) { list_splice(&tmp, &dsp->free_block_list); + + ba->size = size; + ba->offset = offset; return -ENOMEM; } list_move_tail(&block->list, &tmp); - offset += block->size; - size -= block->size; + ba->offset += block->size; + ba->size -= block->size; } + ba->size = size; + ba->offset = offset; + + list_for_each_entry(block, &tmp, list) { + + if (block->offset < block_start) + block_start = block->offset; + + list_add(&block->module_list, block_list); - list_for_each_entry(block, &tmp, list) - list_add(&block->module_list, &module->block_list); + dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n", + block->type, block->index, block->offset); + } list_splice(&tmp, &dsp->used_block_list); return 0; } -/* allocate free DSP blocks for module data - callers hold locks */ -static int block_alloc(struct sst_module *module, - struct sst_module_data *data) +/* allocate first free DSP blocks for data - callers hold locks */ +static int block_alloc(struct sst_dsp *dsp, struct sst_block_allocator *ba, + struct list_head *block_list) { - struct sst_dsp *dsp = module->dsp; struct sst_mem_block *block, *tmp; int ret = 0; - if (data->size == 0) + if (ba->size == 0) return 0; /* find first free whole blocks that can hold module */ list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) { /* ignore blocks with wrong type */ - if (block->type != data->type) + if (block->type != ba->type) continue; - if (data->size > block->size) + if (ba->size > block->size) continue; - data->offset = block->offset; - block->data_type = data->data_type; - block->bytes_used = data->size % block->size; - list_add(&block->module_list, &module->block_list); + ba->offset = block->offset; + block->bytes_used = ba->size % block->size; + list_add(&block->module_list, block_list); list_move(&block->list, &dsp->used_block_list); - dev_dbg(dsp->dev, " *module %d added block %d:%d\n", - module->id, block->type, block->index); + dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n", + block->type, block->index, block->offset); return 0; } @@ -273,15 +645,19 @@ static int block_alloc(struct sst_module *module, list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) { /* ignore blocks with wrong type */ - if (block->type != data->type) + if (block->type != ba->type) continue; /* do we span > 1 blocks */ - if (data->size > block->size) { - ret = block_alloc_contiguous(module, data, - block->offset, data->size); + if (ba->size > block->size) { + + /* align ba to block boundary */ + ba->offset = block->offset; + + ret = block_alloc_contiguous(dsp, ba, block_list); if (ret == 0) return ret; + } } @@ -289,93 +665,74 @@ static int block_alloc(struct sst_module *module, return -ENOMEM; } -/* remove module from memory - callers hold locks */ -static void block_module_remove(struct sst_module *module) +int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba, + struct list_head *block_list) { - struct sst_mem_block *block, *tmp; - struct sst_dsp *dsp = module->dsp; - int err; + int ret; - /* disable each block */ - list_for_each_entry(block, &module->block_list, module_list) { + dev_dbg(dsp->dev, "block request 0x%x bytes at offset 0x%x type %d\n", + ba->size, ba->offset, ba->type); - if (block->ops && block->ops->disable) { - err = block->ops->disable(block); - if (err < 0) - dev_err(dsp->dev, - "error: cant disable block %d:%d\n", - block->type, block->index); - } - } + mutex_lock(&dsp->mutex); - /* mark each block as free */ - list_for_each_entry_safe(block, tmp, &module->block_list, module_list) { - list_del(&block->module_list); - list_move(&block->list, &dsp->free_block_list); + ret = block_alloc(dsp, ba, block_list); + if (ret < 0) { + dev_err(dsp->dev, "error: can't alloc blocks %d\n", ret); + goto out; } -} -/* prepare the memory block to receive data from host - callers hold locks */ -static int block_module_prepare(struct sst_module *module) -{ - struct sst_mem_block *block; - int ret = 0; - - /* enable each block so that's it'e ready for module P/S data */ - list_for_each_entry(block, &module->block_list, module_list) { + /* prepare DSP blocks for module usage */ + ret = block_list_prepare(dsp, block_list); + if (ret < 0) + dev_err(dsp->dev, "error: prepare failed\n"); - if (block->ops && block->ops->enable) { - ret = block->ops->enable(block); - if (ret < 0) { - dev_err(module->dsp->dev, - "error: cant disable block %d:%d\n", - block->type, block->index); - goto err; - } - } - } +out: + mutex_unlock(&dsp->mutex); return ret; +} +EXPORT_SYMBOL_GPL(sst_alloc_blocks); -err: - list_for_each_entry(block, &module->block_list, module_list) { - if (block->ops && block->ops->disable) - block->ops->disable(block); - } - return ret; +int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list) +{ + mutex_lock(&dsp->mutex); + block_list_remove(dsp, block_list); + mutex_unlock(&dsp->mutex); + return 0; } +EXPORT_SYMBOL_GPL(sst_free_blocks); /* allocate memory blocks for static module addresses - callers hold locks */ -static int block_alloc_fixed(struct sst_module *module, - struct sst_module_data *data) +static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba, + struct list_head *block_list) { - struct sst_dsp *dsp = module->dsp; struct sst_mem_block *block, *tmp; - u32 end = data->offset + data->size, block_end; + u32 end = ba->offset + ba->size, block_end; int err; /* only IRAM/DRAM blocks are managed */ - if (data->type != SST_MEM_IRAM && data->type != SST_MEM_DRAM) + if (ba->type != SST_MEM_IRAM && ba->type != SST_MEM_DRAM) return 0; /* are blocks already attached to this module */ - list_for_each_entry_safe(block, tmp, &module->block_list, module_list) { + list_for_each_entry_safe(block, tmp, block_list, module_list) { - /* force compacting mem blocks of the same data_type */ - if (block->data_type != data->data_type) + /* ignore blocks with wrong type */ + if (block->type != ba->type) continue; block_end = block->offset + block->size; /* find block that holds section */ - if (data->offset >= block->offset && end < block_end) + if (ba->offset >= block->offset && end <= block_end) return 0; /* does block span more than 1 section */ - if (data->offset >= block->offset && data->offset < block_end) { + if (ba->offset >= block->offset && ba->offset < block_end) { - err = block_alloc_contiguous(module, data, - block->offset + block->size, - data->size - block->size); + /* align ba to block boundary */ + ba->size -= block_end - ba->offset; + ba->offset = block_end; + err = block_alloc_contiguous(dsp, ba, block_list); if (err < 0) return -ENOMEM; @@ -388,82 +745,270 @@ static int block_alloc_fixed(struct sst_module *module, list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) { block_end = block->offset + block->size; + /* ignore blocks with wrong type */ + if (block->type != ba->type) + continue; + /* find block that holds section */ - if (data->offset >= block->offset && end < block_end) { + if (ba->offset >= block->offset && end <= block_end) { /* add block */ - block->data_type = data->data_type; list_move(&block->list, &dsp->used_block_list); - list_add(&block->module_list, &module->block_list); + list_add(&block->module_list, block_list); + dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n", + block->type, block->index, block->offset); return 0; } /* does block span more than 1 section */ - if (data->offset >= block->offset && data->offset < block_end) { + if (ba->offset >= block->offset && ba->offset < block_end) { - err = block_alloc_contiguous(module, data, - block->offset, data->size); + /* align ba to block boundary */ + ba->offset = block->offset; + + err = block_alloc_contiguous(dsp, ba, block_list); if (err < 0) return -ENOMEM; return 0; } - } return -ENOMEM; } /* Load fixed module data into DSP memory blocks */ -int sst_module_insert_fixed_block(struct sst_module *module, - struct sst_module_data *data) +int sst_module_alloc_blocks(struct sst_module *module) { struct sst_dsp *dsp = module->dsp; + struct sst_fw *sst_fw = module->sst_fw; + struct sst_block_allocator ba; int ret; + ba.size = module->size; + ba.type = module->type; + ba.offset = module->offset; + + dev_dbg(dsp->dev, "block request 0x%x bytes at offset 0x%x type %d\n", + ba.size, ba.offset, ba.type); + mutex_lock(&dsp->mutex); /* alloc blocks that includes this section */ - ret = block_alloc_fixed(module, data); + ret = block_alloc_fixed(dsp, &ba, &module->block_list); if (ret < 0) { dev_err(dsp->dev, "error: no free blocks for section at offset 0x%x size 0x%x\n", - data->offset, data->size); + module->offset, module->size); mutex_unlock(&dsp->mutex); return -ENOMEM; } /* prepare DSP blocks for module copy */ - ret = block_module_prepare(module); + ret = block_list_prepare(dsp, &module->block_list); if (ret < 0) { dev_err(dsp->dev, "error: fw module prepare failed\n"); goto err; } /* copy partial module data to blocks */ - sst_memcpy32(dsp->addr.lpe + data->offset, data->data, data->size); + if (dsp->fw_use_dma) { + ret = sst_dsp_dma_copyto(dsp, + dsp->addr.lpe_base + module->offset, + sst_fw->dmable_fw_paddr + module->data_offset, + module->size); + if (ret < 0) { + dev_err(dsp->dev, "error: module copy failed\n"); + goto err; + } + } else + sst_memcpy32(dsp->addr.lpe + module->offset, module->data, + module->size); mutex_unlock(&dsp->mutex); return ret; err: - block_module_remove(module); + block_list_remove(dsp, &module->block_list); mutex_unlock(&dsp->mutex); return ret; } -EXPORT_SYMBOL_GPL(sst_module_insert_fixed_block); +EXPORT_SYMBOL_GPL(sst_module_alloc_blocks); /* Unload entire module from DSP memory */ -int sst_block_module_remove(struct sst_module *module) +int sst_module_free_blocks(struct sst_module *module) { struct sst_dsp *dsp = module->dsp; mutex_lock(&dsp->mutex); - block_module_remove(module); + block_list_remove(dsp, &module->block_list); + mutex_unlock(&dsp->mutex); + return 0; +} +EXPORT_SYMBOL_GPL(sst_module_free_blocks); + +int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime, + int offset) +{ + struct sst_dsp *dsp = runtime->dsp; + struct sst_module *module = runtime->module; + struct sst_block_allocator ba; + int ret; + + if (module->persistent_size == 0) + return 0; + + ba.size = module->persistent_size; + ba.type = SST_MEM_DRAM; + + mutex_lock(&dsp->mutex); + + /* do we need to allocate at a fixed address ? */ + if (offset != 0) { + + ba.offset = offset; + + dev_dbg(dsp->dev, "persistent fixed block request 0x%x bytes type %d offset 0x%x\n", + ba.size, ba.type, ba.offset); + + /* alloc blocks that includes this section */ + ret = block_alloc_fixed(dsp, &ba, &runtime->block_list); + + } else { + dev_dbg(dsp->dev, "persistent block request 0x%x bytes type %d\n", + ba.size, ba.type); + + /* alloc blocks that includes this section */ + ret = block_alloc(dsp, &ba, &runtime->block_list); + } + if (ret < 0) { + dev_err(dsp->dev, + "error: no free blocks for runtime module size 0x%x\n", + module->persistent_size); + mutex_unlock(&dsp->mutex); + return -ENOMEM; + } + runtime->persistent_offset = ba.offset; + + /* prepare DSP blocks for module copy */ + ret = block_list_prepare(dsp, &runtime->block_list); + if (ret < 0) { + dev_err(dsp->dev, "error: runtime block prepare failed\n"); + goto err; + } + + mutex_unlock(&dsp->mutex); + return ret; + +err: + block_list_remove(dsp, &module->block_list); + mutex_unlock(&dsp->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(sst_module_runtime_alloc_blocks); + +int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime) +{ + struct sst_dsp *dsp = runtime->dsp; + + mutex_lock(&dsp->mutex); + block_list_remove(dsp, &runtime->block_list); mutex_unlock(&dsp->mutex); return 0; } -EXPORT_SYMBOL_GPL(sst_block_module_remove); +EXPORT_SYMBOL_GPL(sst_module_runtime_free_blocks); + +int sst_module_runtime_save(struct sst_module_runtime *runtime, + struct sst_module_runtime_context *context) +{ + struct sst_dsp *dsp = runtime->dsp; + struct sst_module *module = runtime->module; + int ret = 0; + + dev_dbg(dsp->dev, "saving runtime %d memory at 0x%x size 0x%x\n", + runtime->id, runtime->persistent_offset, + module->persistent_size); + + context->buffer = dma_alloc_coherent(dsp->dma_dev, + module->persistent_size, + &context->dma_buffer, GFP_DMA | GFP_KERNEL); + if (!context->buffer) { + dev_err(dsp->dev, "error: DMA context alloc failed\n"); + return -ENOMEM; + } + + mutex_lock(&dsp->mutex); + + if (dsp->fw_use_dma) { + + ret = sst_dsp_dma_get_channel(dsp, 0); + if (ret < 0) + goto err; + + ret = sst_dsp_dma_copyfrom(dsp, context->dma_buffer, + dsp->addr.lpe_base + runtime->persistent_offset, + module->persistent_size); + sst_dsp_dma_put_channel(dsp); + if (ret < 0) { + dev_err(dsp->dev, "error: context copy failed\n"); + goto err; + } + } else + sst_memcpy32(context->buffer, dsp->addr.lpe + + runtime->persistent_offset, + module->persistent_size); + +err: + mutex_unlock(&dsp->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(sst_module_runtime_save); + +int sst_module_runtime_restore(struct sst_module_runtime *runtime, + struct sst_module_runtime_context *context) +{ + struct sst_dsp *dsp = runtime->dsp; + struct sst_module *module = runtime->module; + int ret = 0; + + dev_dbg(dsp->dev, "restoring runtime %d memory at 0x%x size 0x%x\n", + runtime->id, runtime->persistent_offset, + module->persistent_size); + + mutex_lock(&dsp->mutex); + + if (!context->buffer) { + dev_info(dsp->dev, "no context buffer need to restore!\n"); + goto err; + } + + if (dsp->fw_use_dma) { + + ret = sst_dsp_dma_get_channel(dsp, 0); + if (ret < 0) + goto err; + + ret = sst_dsp_dma_copyto(dsp, + dsp->addr.lpe_base + runtime->persistent_offset, + context->dma_buffer, module->persistent_size); + sst_dsp_dma_put_channel(dsp); + if (ret < 0) { + dev_err(dsp->dev, "error: module copy failed\n"); + goto err; + } + } else + sst_memcpy32(dsp->addr.lpe + runtime->persistent_offset, + context->buffer, module->persistent_size); + + dma_free_coherent(dsp->dma_dev, module->persistent_size, + context->buffer, context->dma_buffer); + context->buffer = NULL; + +err: + mutex_unlock(&dsp->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(sst_module_runtime_restore); /* register a DSP memory block for use with FW based modules */ struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, @@ -516,80 +1061,83 @@ void sst_mem_block_unregister_all(struct sst_dsp *dsp) EXPORT_SYMBOL_GPL(sst_mem_block_unregister_all); /* allocate scratch buffer blocks */ -struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp) +int sst_block_alloc_scratch(struct sst_dsp *dsp) { - struct sst_module *sst_module, *scratch; - struct sst_mem_block *block, *tmp; - u32 block_size; - int ret = 0; - - scratch = kzalloc(sizeof(struct sst_module), GFP_KERNEL); - if (scratch == NULL) - return NULL; + struct sst_module *module; + struct sst_block_allocator ba; + int ret; mutex_lock(&dsp->mutex); /* calculate required scratch size */ - list_for_each_entry(sst_module, &dsp->module_list, list) { - if (scratch->s.size < sst_module->s.size) - scratch->s.size = sst_module->s.size; + dsp->scratch_size = 0; + list_for_each_entry(module, &dsp->module_list, list) { + dev_dbg(dsp->dev, "module %d scratch req 0x%x bytes\n", + module->id, module->scratch_size); + if (dsp->scratch_size < module->scratch_size) + dsp->scratch_size = module->scratch_size; } - dev_dbg(dsp->dev, "scratch buffer required is %d bytes\n", - scratch->s.size); - - /* init scratch module */ - scratch->dsp = dsp; - scratch->s.type = SST_MEM_DRAM; - scratch->s.data_type = SST_DATA_S; - INIT_LIST_HEAD(&scratch->block_list); + dev_dbg(dsp->dev, "scratch buffer required is 0x%x bytes\n", + dsp->scratch_size); - /* check free blocks before looking at used blocks for space */ - if (!list_empty(&dsp->free_block_list)) - block = list_first_entry(&dsp->free_block_list, - struct sst_mem_block, list); - else - block = list_first_entry(&dsp->used_block_list, - struct sst_mem_block, list); - block_size = block->size; + if (dsp->scratch_size == 0) { + dev_info(dsp->dev, "no modules need scratch buffer\n"); + mutex_unlock(&dsp->mutex); + return 0; + } /* allocate blocks for module scratch buffers */ dev_dbg(dsp->dev, "allocating scratch blocks\n"); - ret = block_alloc(scratch, &scratch->s); + + ba.size = dsp->scratch_size; + ba.type = SST_MEM_DRAM; + + /* do we need to allocate at fixed offset */ + if (dsp->scratch_offset != 0) { + + dev_dbg(dsp->dev, "block request 0x%x bytes type %d at 0x%x\n", + ba.size, ba.type, ba.offset); + + ba.offset = dsp->scratch_offset; + + /* alloc blocks that includes this section */ + ret = block_alloc_fixed(dsp, &ba, &dsp->scratch_block_list); + + } else { + dev_dbg(dsp->dev, "block request 0x%x bytes type %d\n", + ba.size, ba.type); + + ba.offset = 0; + ret = block_alloc(dsp, &ba, &dsp->scratch_block_list); + } if (ret < 0) { dev_err(dsp->dev, "error: can't alloc scratch blocks\n"); - goto err; + mutex_unlock(&dsp->mutex); + return ret; } - /* assign the same offset of scratch to each module */ - list_for_each_entry(sst_module, &dsp->module_list, list) - sst_module->s.offset = scratch->s.offset; - - mutex_unlock(&dsp->mutex); - return scratch; + ret = block_list_prepare(dsp, &dsp->scratch_block_list); + if (ret < 0) { + dev_err(dsp->dev, "error: scratch block prepare failed\n"); + return ret; + } -err: - list_for_each_entry_safe(block, tmp, &scratch->block_list, module_list) - list_del(&block->module_list); + /* assign the same offset of scratch to each module */ + dsp->scratch_offset = ba.offset; mutex_unlock(&dsp->mutex); - return NULL; + return dsp->scratch_size; } -EXPORT_SYMBOL_GPL(sst_mem_block_alloc_scratch); +EXPORT_SYMBOL_GPL(sst_block_alloc_scratch); /* free all scratch blocks */ -void sst_mem_block_free_scratch(struct sst_dsp *dsp, - struct sst_module *scratch) +void sst_block_free_scratch(struct sst_dsp *dsp) { - struct sst_mem_block *block, *tmp; - mutex_lock(&dsp->mutex); - - list_for_each_entry_safe(block, tmp, &scratch->block_list, module_list) - list_del(&block->module_list); - + block_list_remove(dsp, &dsp->scratch_block_list); mutex_unlock(&dsp->mutex); } -EXPORT_SYMBOL_GPL(sst_mem_block_free_scratch); +EXPORT_SYMBOL_GPL(sst_block_free_scratch); /* get a module from it's unique ID */ struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id) @@ -609,3 +1157,40 @@ struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id) return NULL; } EXPORT_SYMBOL_GPL(sst_module_get_from_id); + +struct sst_module_runtime *sst_module_runtime_get_from_id( + struct sst_module *module, u32 id) +{ + struct sst_module_runtime *runtime; + struct sst_dsp *dsp = module->dsp; + + mutex_lock(&dsp->mutex); + + list_for_each_entry(runtime, &module->runtime_list, list) { + if (runtime->id == id) { + mutex_unlock(&dsp->mutex); + return runtime; + } + } + + mutex_unlock(&dsp->mutex); + return NULL; +} +EXPORT_SYMBOL_GPL(sst_module_runtime_get_from_id); + +/* returns block address in DSP address space */ +u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset, + enum sst_mem_type type) +{ + switch (type) { + case SST_MEM_IRAM: + return offset - dsp->addr.iram_offset + + dsp->addr.dsp_iram_offset; + case SST_MEM_DRAM: + return offset - dsp->addr.dram_offset + + dsp->addr.dsp_dram_offset; + default: + return 0; + } +} +EXPORT_SYMBOL_GPL(sst_dsp_get_offset); diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 4b6c163c10ff..5058dc8bfed0 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c @@ -42,6 +42,10 @@ #define SST_LP_SHIM_OFFSET 0xE7000 #define SST_WPT_IRAM_OFFSET 0xA0000 #define SST_LP_IRAM_OFFSET 0x80000 +#define SST_WPT_DSP_DRAM_OFFSET 0x400000 +#define SST_WPT_DSP_IRAM_OFFSET 0x00000 +#define SST_LPT_DSP_DRAM_OFFSET 0x400000 +#define SST_LPT_DSP_IRAM_OFFSET 0x00000 #define SST_SHIM_PM_REG 0x84 @@ -86,9 +90,8 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, { struct dma_block_info *block; struct sst_module *mod; - struct sst_module_data block_data; struct sst_module_template template; - int count; + int count, ret; void __iomem *ram; /* TODO: allowed module types need to be configurable */ @@ -109,13 +112,9 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, memset(&template, 0, sizeof(template)); template.id = module->type; - template.entry = module->entry_point; - template.p.size = module->info.persistent_size; - template.p.type = SST_MEM_DRAM; - template.p.data_type = SST_DATA_P; - template.s.size = module->info.scratch_size; - template.s.type = SST_MEM_DRAM; - template.s.data_type = SST_DATA_S; + template.entry = module->entry_point - 4; + template.persistent_size = module->info.persistent_size; + template.scratch_size = module->info.scratch_size; mod = sst_module_new(fw, &template, NULL); if (mod == NULL) @@ -135,14 +134,14 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, switch (block->type) { case SST_HSW_IRAM: ram = dsp->addr.lpe; - block_data.offset = + mod->offset = block->ram_offset + dsp->addr.iram_offset; - block_data.type = SST_MEM_IRAM; + mod->type = SST_MEM_IRAM; break; case SST_HSW_DRAM: ram = dsp->addr.lpe; - block_data.offset = block->ram_offset; - block_data.type = SST_MEM_DRAM; + mod->offset = block->ram_offset; + mod->type = SST_MEM_DRAM; break; default: dev_err(dsp->dev, "error: bad type 0x%x for block 0x%x\n", @@ -151,30 +150,34 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw, return -EINVAL; } - block_data.size = block->size; - block_data.data_type = SST_DATA_M; - block_data.data = (void *)block + sizeof(*block); - block_data.data_offset = block_data.data - fw->dma_buf; + mod->size = block->size; + mod->data = (void *)block + sizeof(*block); + mod->data_offset = mod->data - fw->dma_buf; - dev_dbg(dsp->dev, "copy firmware block %d type 0x%x " + dev_dbg(dsp->dev, "module block %d type 0x%x " "size 0x%x ==> ram %p offset 0x%x\n", - count, block->type, block->size, ram, + count, mod->type, block->size, ram, block->ram_offset); - sst_module_insert_fixed_block(mod, &block_data); + ret = sst_module_alloc_blocks(mod); + if (ret < 0) { + dev_err(dsp->dev, "error: could not allocate blocks for module %d\n", + count); + sst_module_free(mod); + return ret; + } block = (void *)block + sizeof(*block) + block->size; } + return 0; } static int hsw_parse_fw_image(struct sst_fw *sst_fw) { struct fw_header *header; - struct sst_module *scratch; struct fw_module_header *module; struct sst_dsp *dsp = sst_fw->dsp; - struct sst_hsw *hsw = sst_fw->private; int ret, count; /* Read the header information from the data pointer */ @@ -204,12 +207,8 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw) module = (void *)module + sizeof(*module) + module->mod_size; } - /* allocate persistent/scratch mem regions */ - scratch = sst_mem_block_alloc_scratch(dsp); - if (scratch == NULL) - return -ENOMEM; - - sst_hsw_set_scratch_module(hsw, scratch); + /* allocate scratch mem regions */ + sst_block_alloc_scratch(dsp); return 0; } @@ -467,12 +466,16 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) region = lp_region; region_count = ARRAY_SIZE(lp_region); sst->addr.iram_offset = SST_LP_IRAM_OFFSET; + sst->addr.dsp_iram_offset = SST_LPT_DSP_IRAM_OFFSET; + sst->addr.dsp_dram_offset = SST_LPT_DSP_DRAM_OFFSET; sst->addr.shim_offset = SST_LP_SHIM_OFFSET; break; case SST_DEV_ID_WILDCAT_POINT: region = wpt_region; region_count = ARRAY_SIZE(wpt_region); sst->addr.iram_offset = SST_WPT_IRAM_OFFSET; + sst->addr.dsp_iram_offset = SST_WPT_DSP_IRAM_OFFSET; + sst->addr.dsp_dram_offset = SST_WPT_DSP_DRAM_OFFSET; sst->addr.shim_offset = SST_WPT_SHIM_OFFSET; break; default: diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 4799768c43cd..770d46708dcb 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1351,10 +1351,11 @@ int sst_hsw_stream_buffer(struct sst_hsw *hsw, struct sst_hsw_stream *stream, } int sst_hsw_stream_set_module_info(struct sst_hsw *hsw, - struct sst_hsw_stream *stream, enum sst_hsw_module_id module_id, - u32 entry_point) + struct sst_hsw_stream *stream, struct sst_module_runtime *runtime) { struct sst_hsw_module_map *map = &stream->request.map; + struct sst_dsp *dsp = sst_hsw_get_dsp(hsw); + struct sst_module *module = runtime->module; if (stream->commited) { dev_err(hsw->dev, "error: stream committed for set module\n"); @@ -1363,36 +1364,25 @@ int sst_hsw_stream_set_module_info(struct sst_hsw *hsw, /* only support initial module atm */ map->module_entries_count = 1; - map->module_entries[0].module_id = module_id; - map->module_entries[0].entry_point = entry_point; - - return 0; -} - -int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw, - struct sst_hsw_stream *stream, u32 offset, u32 size) -{ - if (stream->commited) { - dev_err(hsw->dev, "error: stream committed for set pmem\n"); - return -EINVAL; - } - - stream->request.persistent_mem.offset = offset; - stream->request.persistent_mem.size = size; - - return 0; -} - -int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, - struct sst_hsw_stream *stream, u32 offset, u32 size) -{ - if (stream->commited) { - dev_err(hsw->dev, "error: stream committed for set smem\n"); - return -EINVAL; - } - - stream->request.scratch_mem.offset = offset; - stream->request.scratch_mem.size = size; + map->module_entries[0].module_id = module->id; + map->module_entries[0].entry_point = module->entry; + + stream->request.persistent_mem.offset = + sst_dsp_get_offset(dsp, runtime->persistent_offset, SST_MEM_DRAM); + stream->request.persistent_mem.size = module->persistent_size; + + stream->request.scratch_mem.offset = + sst_dsp_get_offset(dsp, dsp->scratch_offset, SST_MEM_DRAM); + stream->request.scratch_mem.size = dsp->scratch_size; + + dev_dbg(hsw->dev, "module %d runtime %d using:\n", module->id, + runtime->id); + dev_dbg(hsw->dev, " persistent offset 0x%x bytes 0x%x\n", + stream->request.persistent_mem.offset, + stream->request.persistent_mem.size); + dev_dbg(hsw->dev, " scratch offset 0x%x bytes 0x%x\n", + stream->request.scratch_mem.offset, + stream->request.scratch_mem.size); return 0; } @@ -1673,32 +1663,48 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw, dev_dbg(hsw->dev, "ipc: got %d entry numbers for state %d\n", dx->entries_no, state); - memcpy(&hsw->dx, dx, sizeof(*dx)); - return 0; + return ret; } -/* Used to save state into hsw->dx_reply */ -int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item, - u32 *offset, u32 *size, u32 *source) +struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw, + int mod_id, int offset) { - struct sst_hsw_ipc_dx_memory_item *dx_mem; - struct sst_hsw_ipc_dx_reply *dx_reply; - int entry_no; + struct sst_dsp *dsp = hsw->dsp; + struct sst_module *module; + struct sst_module_runtime *runtime; + int err; - dx_reply = &hsw->dx; - entry_no = dx_reply->entries_no; + module = sst_module_get_from_id(dsp, mod_id); + if (module == NULL) { + dev_err(dsp->dev, "error: failed to get module %d for pcm\n", + mod_id); + return NULL; + } - trace_ipc_request("PM get Dx state", entry_no); + runtime = sst_module_runtime_new(module, mod_id, NULL); + if (runtime == NULL) { + dev_err(dsp->dev, "error: failed to create module %d runtime\n", + mod_id); + return NULL; + } - if (item >= entry_no) - return -EINVAL; + err = sst_module_runtime_alloc_blocks(runtime, offset); + if (err < 0) { + dev_err(dsp->dev, "error: failed to alloc blocks for module %d runtime\n", + mod_id); + sst_module_runtime_free(runtime); + return NULL; + } - dx_mem = &dx_reply->mem_info[item]; - *offset = dx_mem->offset; - *size = dx_mem->size; - *source = dx_mem->source; + dev_dbg(dsp->dev, "runtime id %d created for module %d\n", runtime->id, + mod_id); + return runtime; +} - return 0; +void sst_hsw_runtime_module_free(struct sst_module_runtime *runtime) +{ + sst_module_runtime_free_blocks(runtime); + sst_module_runtime_free(runtime); } static int msg_empty_list_init(struct sst_hsw *hsw) @@ -1718,12 +1724,6 @@ static int msg_empty_list_init(struct sst_hsw *hsw) return 0; } -void sst_hsw_set_scratch_module(struct sst_hsw *hsw, - struct sst_module *scratch) -{ - hsw->scratch = scratch; -} - struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw) { return hsw->dsp; diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index 063dd6b669bf..fe6e63f6524a 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h @@ -40,6 +40,7 @@ struct sst_hsw_stream; struct sst_hsw_log_stream; struct sst_pdata; struct sst_module; +struct sst_module_runtime; extern struct sst_ops haswell_ops; /* Stream Allocate Path ID */ @@ -432,8 +433,7 @@ int sst_hsw_stream_set_map_config(struct sst_hsw *hsw, int sst_hsw_stream_set_style(struct sst_hsw *hsw, struct sst_hsw_stream *stream, enum sst_hsw_interleaving style); int sst_hsw_stream_set_module_info(struct sst_hsw *hsw, - struct sst_hsw_stream *stream, enum sst_hsw_module_id module_id, - u32 entry_point); + struct sst_hsw_stream *stream, struct sst_module_runtime *runtime); int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw, struct sst_hsw_stream *stream, u32 offset, u32 size); int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, @@ -486,7 +486,10 @@ int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item, int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata); void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata); struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw); -void sst_hsw_set_scratch_module(struct sst_hsw *hsw, - struct sst_module *scratch); + +/* runtime module management */ +struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw, + int mod_id, int offset); +void sst_hsw_runtime_module_free(struct sst_module_runtime *runtime); #endif diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 32a6470ae38a..522edef20c86 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -89,16 +89,23 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = { .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE, }; +struct hsw_pcm_module_map { + int dai_id; + enum sst_hsw_module_id mod_id; +}; + /* private data for each PCM DSP stream */ struct hsw_pcm_data { int dai_id; struct sst_hsw_stream *stream; + struct sst_module_runtime *runtime; u32 volume[2]; struct snd_pcm_substream *substream; struct snd_compr_stream *cstream; unsigned int wpos; struct mutex mutex; bool allocated; + int persistent_offset; }; /* private data for the driver */ @@ -472,28 +479,8 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* we use hardcoded memory offsets atm, will be updated for new FW */ - if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) { - sst_hsw_stream_set_module_info(hsw, pcm_data->stream, - SST_HSW_MODULE_PCM_CAPTURE, module_data->entry); - sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, - 0x449400, 0x4000); - sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, - 0x400000, 0); - } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */ - sst_hsw_stream_set_module_info(hsw, pcm_data->stream, - SST_HSW_MODULE_PCM_SYSTEM, module_data->entry); - - sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, - module_data->offset, module_data->size); - sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, - 0x44d400, 0x3800); - - sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, - module_data->offset, module_data->size); - sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, - 0x400000, 0); - } + sst_hsw_stream_set_module_info(hsw, pcm_data->stream, + pcm_data->runtime); ret = sst_hsw_stream_commit(hsw, pcm_data->stream); if (ret < 0) { @@ -654,6 +641,55 @@ static struct snd_pcm_ops hsw_pcm_ops = { .page = snd_pcm_sgbuf_ops_page, }; +/* static mappings between PCMs and modules - may be dynamic in future */ +static struct hsw_pcm_module_map mod_map[] = { + {0, SST_HSW_MODULE_PCM_SYSTEM}, /* "System Pin" */ + {1, SST_HSW_MODULE_PCM}, /* "Offload0 Pin" */ + {2, SST_HSW_MODULE_PCM}, /* "Offload1 Pin" */ + {3, SST_HSW_MODULE_PCM_REFERENCE}, /* "Loopback Pin" */ + {4, SST_HSW_MODULE_PCM_CAPTURE}, /* "Capture Pin" */ +}; + +static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) +{ + struct sst_hsw *hsw = pdata->hsw; + struct hsw_pcm_data *pcm_data; + int i; + + for (i = 0; i < ARRAY_SIZE(mod_map); i++) { + pcm_data = &pdata->pcm[i]; + + pcm_data->runtime = sst_hsw_runtime_module_create(hsw, + mod_map[i].mod_id, pcm_data->persistent_offset); + if (pcm_data->runtime == NULL) + goto err; + pcm_data->persistent_offset = + pcm_data->runtime->persistent_offset; + } + + return 0; + +err: + for (--i; i >= 0; i--) { + pcm_data = &pdata->pcm[i]; + sst_hsw_runtime_module_free(pcm_data->runtime); + } + + return -ENODEV; +} + +static void hsw_pcm_free_modules(struct hsw_priv_data *pdata) +{ + struct hsw_pcm_data *pcm_data; + int i; + + for (i = 0; i < ARRAY_SIZE(mod_map); i++) { + pcm_data = &pdata->pcm[i]; + + sst_hsw_runtime_module_free(pcm_data->runtime); + } +} + static void hsw_pcm_free(struct snd_pcm *pcm) { snd_pcm_lib_preallocate_free_for_all(pcm); @@ -797,6 +833,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) } } + /* allocate runtime modules */ + hsw_pcm_create_modules(priv_data); + return 0; err: -- GitLab From 4e44923847b0b2597eaef07d5e700f5dbed2162e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 28 Oct 2014 17:08:40 +0100 Subject: [PATCH 1725/9457] ASoC: cs42l51: make driver user-selectable Since we are removing the Armada 370 DB audio machine driver to use the 'simple-card' Device Tree binding, we can no longer select the CS42L51 codec driver using a Kconfig 'select', and we instead need it to be user-selectable. Therefore, this commit adds a prompt to make the CS42L51 I2C codec driver user-selectable. Signed-off-by: Thomas Petazzoni Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..f4fb12fab166 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -336,7 +336,7 @@ config SND_SOC_CS42L51 tristate config SND_SOC_CS42L51_I2C - tristate + tristate "Cirrus Logic CS42L51 CODEC (I2C)" select SND_SOC_CS42L51 config SND_SOC_CS42L52 -- GitLab From a5c2db964d3eb26b41bd7abc1b13486f732b3aa2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Oct 2014 18:25:01 +0200 Subject: [PATCH 1726/9457] spi: dw-mid: refactor to use helpers This patch splits few helpers, namely dw_spi_dma_prepare_rx(), dw_spi_dma_prepare_tx(), and dw_spi_dma_setup() which will be useful for the consequent improvements. There is no functional change. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 69 ++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 46c6d58e1fda..c8319ab0bbdf 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -111,28 +111,11 @@ static void dw_spi_dma_done(void *arg) dw_spi_xfer_done(dws); } -static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) +static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) { - struct dma_async_tx_descriptor *txdesc, *rxdesc; - struct dma_slave_config txconf, rxconf; - u16 dma_ctrl = 0; - - /* 1. setup DMA related registers */ - if (cs_change) { - spi_enable_chip(dws, 0); - dw_writew(dws, DW_SPI_DMARDLR, 0xf); - dw_writew(dws, DW_SPI_DMATDLR, 0x10); - if (dws->tx_dma) - dma_ctrl |= SPI_DMA_TDMAE; - if (dws->rx_dma) - dma_ctrl |= SPI_DMA_RDMAE; - dw_writew(dws, DW_SPI_DMACR, dma_ctrl); - spi_enable_chip(dws, 1); - } + struct dma_slave_config txconf; + struct dma_async_tx_descriptor *txdesc; - dws->dma_chan_done = 0; - - /* 2. Prepare the TX dma transfer */ txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = LNW_DMA_MSIZE_16; @@ -154,7 +137,14 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) txdesc->callback = dw_spi_dma_done; txdesc->callback_param = dws; - /* 3. Prepare the RX dma transfer */ + return txdesc; +} + +static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) +{ + struct dma_slave_config rxconf; + struct dma_async_tx_descriptor *rxdesc; + rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = LNW_DMA_MSIZE_16; @@ -176,6 +166,43 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) rxdesc->callback = dw_spi_dma_done; rxdesc->callback_param = dws; + return rxdesc; +} + +static void dw_spi_dma_setup(struct dw_spi *dws) +{ + u16 dma_ctrl = 0; + + spi_enable_chip(dws, 0); + + dw_writew(dws, DW_SPI_DMARDLR, 0xf); + dw_writew(dws, DW_SPI_DMATDLR, 0x10); + + if (dws->tx_dma) + dma_ctrl |= SPI_DMA_TDMAE; + if (dws->rx_dma) + dma_ctrl |= SPI_DMA_RDMAE; + dw_writew(dws, DW_SPI_DMACR, dma_ctrl); + + spi_enable_chip(dws, 1); +} + +static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) +{ + struct dma_async_tx_descriptor *txdesc, *rxdesc; + + /* 1. setup DMA related registers */ + if (cs_change) + dw_spi_dma_setup(dws); + + dws->dma_chan_done = 0; + + /* 2. Prepare the TX dma transfer */ + txdesc = dw_spi_dma_prepare_tx(dws); + + /* 3. Prepare the RX dma transfer */ + rxdesc = dw_spi_dma_prepare_rx(dws); + /* rx must be started before tx due to spi instinct */ dmaengine_submit(rxdesc); dma_async_issue_pending(dws->rxchan); -- GitLab From 30c8eb52cc4a7bed59d85243e769ce420f179140 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 28 Oct 2014 18:25:02 +0200 Subject: [PATCH 1727/9457] spi: dw-mid: split rx and tx callbacks when DMA Currently driver wouldn't work properly if user asked for simplex transfer. The patch separates DMA rx and tx callbacks and finishes transfer correctly in any case. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-dw-mid.c | 53 +++++++++++++++++++++++++++++----------- drivers/spi/spi-dw.h | 2 +- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index c8319ab0bbdf..7281316a5ecb 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -26,6 +26,9 @@ #include #include +#define RX_BUSY 0 +#define TX_BUSY 1 + struct mid_dma { struct intel_mid_dma_slave dmas_tx; struct intel_mid_dma_slave dmas_rx; @@ -98,15 +101,14 @@ static void mid_spi_dma_exit(struct dw_spi *dws) } /* - * dws->dma_chan_done is cleared before the dma transfer starts, - * callback for rx/tx channel will each increment it by 1. - * Reaching 2 means the whole spi transaction is done. + * dws->dma_chan_busy is set before the dma transfer starts, callback for tx + * channel will clear a corresponding bit. */ -static void dw_spi_dma_done(void *arg) +static void dw_spi_dma_tx_done(void *arg) { struct dw_spi *dws = arg; - if (++dws->dma_chan_done != 2) + if (test_and_clear_bit(TX_BUSY, &dws->dma_chan_busy) & BIT(RX_BUSY)) return; dw_spi_xfer_done(dws); } @@ -116,6 +118,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) struct dma_slave_config txconf; struct dma_async_tx_descriptor *txdesc; + if (!dws->tx_dma) + return NULL; + txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = LNW_DMA_MSIZE_16; @@ -134,17 +139,33 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - txdesc->callback = dw_spi_dma_done; + txdesc->callback = dw_spi_dma_tx_done; txdesc->callback_param = dws; return txdesc; } +/* + * dws->dma_chan_busy is set before the dma transfer starts, callback for rx + * channel will clear a corresponding bit. + */ +static void dw_spi_dma_rx_done(void *arg) +{ + struct dw_spi *dws = arg; + + if (test_and_clear_bit(RX_BUSY, &dws->dma_chan_busy) & BIT(TX_BUSY)) + return; + dw_spi_xfer_done(dws); +} + static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) { struct dma_slave_config rxconf; struct dma_async_tx_descriptor *rxdesc; + if (!dws->rx_dma) + return NULL; + rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = LNW_DMA_MSIZE_16; @@ -163,7 +184,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - rxdesc->callback = dw_spi_dma_done; + rxdesc->callback = dw_spi_dma_rx_done; rxdesc->callback_param = dws; return rxdesc; @@ -195,8 +216,6 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) if (cs_change) dw_spi_dma_setup(dws); - dws->dma_chan_done = 0; - /* 2. Prepare the TX dma transfer */ txdesc = dw_spi_dma_prepare_tx(dws); @@ -204,11 +223,17 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) rxdesc = dw_spi_dma_prepare_rx(dws); /* rx must be started before tx due to spi instinct */ - dmaengine_submit(rxdesc); - dma_async_issue_pending(dws->rxchan); - - dmaengine_submit(txdesc); - dma_async_issue_pending(dws->txchan); + if (rxdesc) { + set_bit(RX_BUSY, &dws->dma_chan_busy); + dmaengine_submit(rxdesc); + dma_async_issue_pending(dws->rxchan); + } + + if (txdesc) { + set_bit(TX_BUSY, &dws->dma_chan_busy); + dmaengine_submit(txdesc); + dma_async_issue_pending(dws->txchan); + } return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 83a103a76481..3d32be68c142 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -139,7 +139,7 @@ struct dw_spi { struct scatterlist tx_sgl; struct dma_chan *rxchan; struct scatterlist rx_sgl; - int dma_chan_done; + unsigned long dma_chan_busy; struct device *dma_dev; dma_addr_t dma_addr; /* phy address of the Data register */ struct dw_spi_dma_ops *dma_ops; -- GitLab From e6f6ebc1f8f60d6d44f6be22c6386c238d6a9d97 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 22 Oct 2014 16:11:39 +0800 Subject: [PATCH 1728/9457] ASoC: rt5677: Add TDM channel mapping function It is for channel to slot mapping, and it is not only for 8 channels mapping, but also in 2, 4 and 6 channels mapping. If we want to use the 2 channels in the stereo2 adc path, we need to set the item "2/1/3/4" or "2/3/1/4". It also adds for stereo channel swap. It can map the sterero channels "L/R" to "R/L", "L/L" or R/R. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 239 ++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/rt5677.h | 38 +++++- 2 files changed, 262 insertions(+), 15 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 413bccbff19e..ca264f885195 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -1834,6 +1834,93 @@ static SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new rt5677_if4_adc_mux = SOC_DAPM_ENUM("IF4 ADC Source", rt5677_if4_adc_enum); +/* TDM IF1/2 ADC Data Selection */ /* MX-3B MX-40 [7:6][5:4][3:2][1:0] */ +static const char * const rt5677_if12_adc_swap_src[] = { + "L/R", "R/L", "L/L", "R/R" +}; + +static SOC_ENUM_SINGLE_DECL( + rt5677_if1_adc1_swap_enum, RT5677_TDM1_CTRL1, + RT5677_IF1_ADC1_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if1_adc1_swap_mux = + SOC_DAPM_ENUM("IF1 ADC1 Swap Source", rt5677_if1_adc1_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if1_adc2_swap_enum, RT5677_TDM1_CTRL1, + RT5677_IF1_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if1_adc2_swap_mux = + SOC_DAPM_ENUM("IF1 ADC2 Swap Source", rt5677_if1_adc2_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if1_adc3_swap_enum, RT5677_TDM1_CTRL1, + RT5677_IF1_ADC3_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if1_adc3_swap_mux = + SOC_DAPM_ENUM("IF1 ADC3 Swap Source", rt5677_if1_adc3_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if1_adc4_swap_enum, RT5677_TDM1_CTRL1, + RT5677_IF1_ADC4_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if1_adc4_swap_mux = + SOC_DAPM_ENUM("IF1 ADC4 Swap Source", rt5677_if1_adc4_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if2_adc1_swap_enum, RT5677_TDM2_CTRL1, + RT5677_IF1_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if2_adc1_swap_mux = + SOC_DAPM_ENUM("IF1 ADC2 Swap Source", rt5677_if2_adc1_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if2_adc2_swap_enum, RT5677_TDM2_CTRL1, + RT5677_IF2_ADC2_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if2_adc2_swap_mux = + SOC_DAPM_ENUM("IF2 ADC2 Swap Source", rt5677_if2_adc2_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if2_adc3_swap_enum, RT5677_TDM2_CTRL1, + RT5677_IF2_ADC3_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if2_adc3_swap_mux = + SOC_DAPM_ENUM("IF2 ADC3 Swap Source", rt5677_if2_adc3_swap_enum); + +static SOC_ENUM_SINGLE_DECL( + rt5677_if2_adc4_swap_enum, RT5677_TDM2_CTRL1, + RT5677_IF2_ADC4_SWAP_SFT, rt5677_if12_adc_swap_src); + +static const struct snd_kcontrol_new rt5677_if2_adc4_swap_mux = + SOC_DAPM_ENUM("IF2 ADC4 Swap Source", rt5677_if2_adc4_swap_enum); + +/* TDM IF1 ADC Data Selection */ /* MX-3C [2:0] */ +static const char * const rt5677_if1_adc_tdm_swap_src[] = { + "1/2/3/4", "2/1/3/4", "2/3/1/4", "4/1/2/3", "1/3/2/4", "1/4/2/3", + "3/1/2/4", "3/4/1/2" +}; + +static SOC_ENUM_SINGLE_DECL( + rt5677_if1_adc_tdm_swap_enum, RT5677_TDM1_CTRL2, + RT5677_IF1_ADC_CTRL_SFT, rt5677_if1_adc_tdm_swap_src); + +static const struct snd_kcontrol_new rt5677_if1_adc_tdm_swap_mux = + SOC_DAPM_ENUM("IF1 ADC TDM Swap Source", rt5677_if1_adc_tdm_swap_enum); + +/* TDM IF2 ADC Data Selection */ /* MX-41[2:0] */ +static const char * const rt5677_if2_adc_tdm_swap_src[] = { + "1/2/3/4", "2/1/3/4", "3/1/2/4", "4/1/2/3", "1/3/2/4", "1/4/2/3", + "2/3/1/4", "3/4/1/2" +}; + +static SOC_ENUM_SINGLE_DECL( + rt5677_if2_adc_tdm_swap_enum, RT5677_TDM2_CTRL2, + RT5677_IF2_ADC_CTRL_SFT, rt5677_if2_adc_tdm_swap_src); + +static const struct snd_kcontrol_new rt5677_if2_adc_tdm_swap_mux = + SOC_DAPM_ENUM("IF2 ADC TDM Swap Source", rt5677_if2_adc_tdm_swap_enum); + static int rt5677_bst1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1945,6 +2032,52 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + unsigned int value; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + regmap_read(rt5677->regmap, RT5677_TDM1_CTRL2, &value); + if (value & RT5677_IF1_ADC_CTRL_MASK) + regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1, + RT5677_IF1_ADC_MODE_MASK, + RT5677_IF1_ADC_MODE_TDM); + break; + + default: + return 0; + } + + return 0; +} + +static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + unsigned int value; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + regmap_read(rt5677->regmap, RT5677_TDM2_CTRL2, &value); + if (value & RT5677_IF2_ADC_CTRL_MASK) + regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1, + RT5677_IF2_ADC_MODE_MASK, + RT5677_IF2_ADC_MODE_TDM); + break; + + default: + return 0; + } + + return 0; +} + static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT, 0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU), @@ -2104,10 +2237,8 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_PGA("Stereo4 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Mono ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), /* DSP */ SND_SOC_DAPM_MUX("IB9 Mux", SND_SOC_NOPM, 0, 0, @@ -2230,6 +2361,17 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { &rt5677_if1_adc3_mux), SND_SOC_DAPM_MUX("IF1 ADC4 Mux", SND_SOC_NOPM, 0, 0, &rt5677_if1_adc4_mux), + SND_SOC_DAPM_MUX("IF1 ADC1 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if1_adc1_swap_mux), + SND_SOC_DAPM_MUX("IF1 ADC2 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if1_adc2_swap_mux), + SND_SOC_DAPM_MUX("IF1 ADC3 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if1_adc3_swap_mux), + SND_SOC_DAPM_MUX("IF1 ADC4 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if1_adc4_swap_mux), + SND_SOC_DAPM_MUX_E("IF1 ADC TDM Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if1_adc_tdm_swap_mux, rt5677_if1_adc_tdm_event, + SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_MUX("IF2 ADC1 Mux", SND_SOC_NOPM, 0, 0, &rt5677_if2_adc1_mux), SND_SOC_DAPM_MUX("IF2 ADC2 Mux", SND_SOC_NOPM, 0, 0, @@ -2238,6 +2380,17 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { &rt5677_if2_adc3_mux), SND_SOC_DAPM_MUX("IF2 ADC4 Mux", SND_SOC_NOPM, 0, 0, &rt5677_if2_adc4_mux), + SND_SOC_DAPM_MUX("IF2 ADC1 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if2_adc1_swap_mux), + SND_SOC_DAPM_MUX("IF2 ADC2 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if2_adc2_swap_mux), + SND_SOC_DAPM_MUX("IF2 ADC3 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if2_adc3_swap_mux), + SND_SOC_DAPM_MUX("IF2 ADC4 Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if2_adc4_swap_mux), + SND_SOC_DAPM_MUX_E("IF2 ADC TDM Swap Mux", SND_SOC_NOPM, 0, 0, + &rt5677_if2_adc_tdm_swap_mux, rt5677_if2_adc_tdm_event, + SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_MUX("IF3 ADC Mux", SND_SOC_NOPM, 0, 0, &rt5677_if3_adc_mux), SND_SOC_DAPM_MUX("IF4 ADC Mux", SND_SOC_NOPM, 0, 0, @@ -2621,11 +2774,42 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "IF1 ADC4 Mux", "OB67", "OB67" }, { "IF1 ADC4 Mux", "OB01", "OB01 Bypass Mux" }, + { "IF1 ADC1 Swap Mux", "L/R", "IF1 ADC1 Mux" }, + { "IF1 ADC1 Swap Mux", "R/L", "IF1 ADC1 Mux" }, + { "IF1 ADC1 Swap Mux", "L/L", "IF1 ADC1 Mux" }, + { "IF1 ADC1 Swap Mux", "R/R", "IF1 ADC1 Mux" }, + + { "IF1 ADC2 Swap Mux", "L/R", "IF1 ADC2 Mux" }, + { "IF1 ADC2 Swap Mux", "R/L", "IF1 ADC2 Mux" }, + { "IF1 ADC2 Swap Mux", "L/L", "IF1 ADC2 Mux" }, + { "IF1 ADC2 Swap Mux", "R/R", "IF1 ADC2 Mux" }, + + { "IF1 ADC3 Swap Mux", "L/R", "IF1 ADC3 Mux" }, + { "IF1 ADC3 Swap Mux", "R/L", "IF1 ADC3 Mux" }, + { "IF1 ADC3 Swap Mux", "L/L", "IF1 ADC3 Mux" }, + { "IF1 ADC3 Swap Mux", "R/R", "IF1 ADC3 Mux" }, + + { "IF1 ADC4 Swap Mux", "L/R", "IF1 ADC4 Mux" }, + { "IF1 ADC4 Swap Mux", "R/L", "IF1 ADC4 Mux" }, + { "IF1 ADC4 Swap Mux", "L/L", "IF1 ADC4 Mux" }, + { "IF1 ADC4 Swap Mux", "R/R", "IF1 ADC4 Mux" }, + + { "IF1 ADC", NULL, "IF1 ADC1 Swap Mux" }, + { "IF1 ADC", NULL, "IF1 ADC2 Swap Mux" }, + { "IF1 ADC", NULL, "IF1 ADC3 Swap Mux" }, + { "IF1 ADC", NULL, "IF1 ADC4 Swap Mux" }, + + { "IF1 ADC TDM Swap Mux", "1/2/3/4", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "2/1/3/4", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "2/3/1/4", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "4/1/2/3", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "1/3/2/4", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "1/4/2/3", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "3/1/2/4", "IF1 ADC" }, + { "IF1 ADC TDM Swap Mux", "3/4/1/2", "IF1 ADC" }, + { "AIF1TX", NULL, "I2S1" }, - { "AIF1TX", NULL, "IF1 ADC1 Mux" }, - { "AIF1TX", NULL, "IF1 ADC2 Mux" }, - { "AIF1TX", NULL, "IF1 ADC3 Mux" }, - { "AIF1TX", NULL, "IF1 ADC4 Mux" }, + { "AIF1TX", NULL, "IF1 ADC TDM Swap Mux" }, { "IF2 ADC1 Mux", "STO1 ADC MIX", "Stereo1 ADC MIX" }, { "IF2 ADC1 Mux", "OB01", "OB01 Bypass Mux" }, @@ -2642,11 +2826,42 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "IF2 ADC4 Mux", "OB67", "OB67" }, { "IF2 ADC4 Mux", "OB01", "OB01 Bypass Mux" }, + { "IF2 ADC1 Swap Mux", "L/R", "IF2 ADC1 Mux" }, + { "IF2 ADC1 Swap Mux", "R/L", "IF2 ADC1 Mux" }, + { "IF2 ADC1 Swap Mux", "L/L", "IF2 ADC1 Mux" }, + { "IF2 ADC1 Swap Mux", "R/R", "IF2 ADC1 Mux" }, + + { "IF2 ADC2 Swap Mux", "L/R", "IF2 ADC2 Mux" }, + { "IF2 ADC2 Swap Mux", "R/L", "IF2 ADC2 Mux" }, + { "IF2 ADC2 Swap Mux", "L/L", "IF2 ADC2 Mux" }, + { "IF2 ADC2 Swap Mux", "R/R", "IF2 ADC2 Mux" }, + + { "IF2 ADC3 Swap Mux", "L/R", "IF2 ADC3 Mux" }, + { "IF2 ADC3 Swap Mux", "R/L", "IF2 ADC3 Mux" }, + { "IF2 ADC3 Swap Mux", "L/L", "IF2 ADC3 Mux" }, + { "IF2 ADC3 Swap Mux", "R/R", "IF2 ADC3 Mux" }, + + { "IF2 ADC4 Swap Mux", "L/R", "IF2 ADC4 Mux" }, + { "IF2 ADC4 Swap Mux", "R/L", "IF2 ADC4 Mux" }, + { "IF2 ADC4 Swap Mux", "L/L", "IF2 ADC4 Mux" }, + { "IF2 ADC4 Swap Mux", "R/R", "IF2 ADC4 Mux" }, + + { "IF2 ADC", NULL, "IF2 ADC1 Swap Mux" }, + { "IF2 ADC", NULL, "IF2 ADC2 Swap Mux" }, + { "IF2 ADC", NULL, "IF2 ADC3 Swap Mux" }, + { "IF2 ADC", NULL, "IF2 ADC4 Swap Mux" }, + + { "IF2 ADC TDM Swap Mux", "1/2/3/4", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "2/1/3/4", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "3/1/2/4", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "4/1/2/3", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "1/3/2/4", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "1/4/2/3", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "2/3/1/4", "IF2 ADC" }, + { "IF2 ADC TDM Swap Mux", "3/4/1/2", "IF2 ADC" }, + { "AIF2TX", NULL, "I2S2" }, - { "AIF2TX", NULL, "IF2 ADC1 Mux" }, - { "AIF2TX", NULL, "IF2 ADC2 Mux" }, - { "AIF2TX", NULL, "IF2 ADC3 Mux" }, - { "AIF2TX", NULL, "IF2 ADC4 Mux" }, + { "AIF2TX", NULL, "IF2 ADC TDM Swap Mux" }, { "IF3 ADC Mux", "STO1 ADC MIX", "Stereo1 ADC MIX" }, { "IF3 ADC Mux", "STO2 ADC MIX", "Stereo2 ADC MIX" }, diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index d2c743c255a1..2f5b8c6c279e 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -799,7 +799,21 @@ #define RT5677_PDM2_I2C_EXE (0x1 << 1) #define RT5677_PDM2_I2C_BUSY (0x1 << 0) -/* MX3C TDM1 control 1 (0x3c) */ +/* MX3B TDM1 control 1 (0x3b) */ +#define RT5677_IF1_ADC_MODE_MASK (0x1 << 12) +#define RT5677_IF1_ADC_MODE_SFT 12 +#define RT5677_IF1_ADC_MODE_I2S (0x0 << 12) +#define RT5677_IF1_ADC_MODE_TDM (0x1 << 12) +#define RT5677_IF1_ADC1_SWAP_MASK (0x3 << 6) +#define RT5677_IF1_ADC1_SWAP_SFT 6 +#define RT5677_IF1_ADC2_SWAP_MASK (0x3 << 4) +#define RT5677_IF1_ADC2_SWAP_SFT 4 +#define RT5677_IF1_ADC3_SWAP_MASK (0x3 << 2) +#define RT5677_IF1_ADC3_SWAP_SFT 2 +#define RT5677_IF1_ADC4_SWAP_MASK (0x3 << 0) +#define RT5677_IF1_ADC4_SWAP_SFT 0 + +/* MX3C TDM1 control 2 (0x3c) */ #define RT5677_IF1_ADC4_MASK (0x3 << 10) #define RT5677_IF1_ADC4_SFT 10 #define RT5677_IF1_ADC3_MASK (0x3 << 8) @@ -808,8 +822,24 @@ #define RT5677_IF1_ADC2_SFT 6 #define RT5677_IF1_ADC1_MASK (0x3 << 4) #define RT5677_IF1_ADC1_SFT 4 - -/* MX41 TDM2 control 1 (0x41) */ +#define RT5677_IF1_ADC_CTRL_MASK (0x7 << 0) +#define RT5677_IF1_ADC_CTRL_SFT 0 + +/* MX40 TDM2 control 1 (0x40) */ +#define RT5677_IF2_ADC_MODE_MASK (0x1 << 12) +#define RT5677_IF2_ADC_MODE_SFT 12 +#define RT5677_IF2_ADC_MODE_I2S (0x0 << 12) +#define RT5677_IF2_ADC_MODE_TDM (0x1 << 12) +#define RT5677_IF2_ADC1_SWAP_MASK (0x3 << 6) +#define RT5677_IF2_ADC1_SWAP_SFT 6 +#define RT5677_IF2_ADC2_SWAP_MASK (0x3 << 4) +#define RT5677_IF2_ADC2_SWAP_SFT 4 +#define RT5677_IF2_ADC3_SWAP_MASK (0x3 << 2) +#define RT5677_IF2_ADC3_SWAP_SFT 2 +#define RT5677_IF2_ADC4_SWAP_MASK (0x3 << 0) +#define RT5677_IF2_ADC4_SWAP_SFT 0 + +/* MX41 TDM2 control 2 (0x41) */ #define RT5677_IF2_ADC4_MASK (0x3 << 10) #define RT5677_IF2_ADC4_SFT 10 #define RT5677_IF2_ADC3_MASK (0x3 << 8) @@ -818,6 +848,8 @@ #define RT5677_IF2_ADC2_SFT 6 #define RT5677_IF2_ADC1_MASK (0x3 << 4) #define RT5677_IF2_ADC1_SFT 4 +#define RT5677_IF2_ADC_CTRL_MASK (0x7 << 0) +#define RT5677_IF2_ADC_CTRL_SFT 0 /* Digital Microphone Control 1 (0x50) */ #define RT5677_DMIC_1_EN_MASK (0x1 << 15) -- GitLab From e83280f96f108ee7af8c5669080cf664b0c2b8fb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2014 08:20:46 +0100 Subject: [PATCH 1729/9457] ALSA: doc: Fix enum snd_jack_types comments Follow the proper kerneldoc rule, and complete enum item comments. Signed-off-by: Takashi Iwai --- include/sound/jack.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/sound/jack.h b/include/sound/jack.h index 37e612e77410..67f2bbcd515e 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -28,7 +28,21 @@ struct input_dev; /** - * enum snd_jack_types: Jack types which can be reported + * enum snd_jack_types - Jack types which can be reported + * @SND_JACK_HEADPHONE: Headphone + * @SND_JACK_MICROPHONE: Microphone + * @SND_JACK_HEADSET: Headset + * @SND_JACK_LINEOUT: Line out + * @SND_JACK_MECHANICAL: Mechanical switch + * @SND_JACK_VIDEOOUT: Video out + * @SND_JACK_AVOUT: AV (Audio Video) out + * @SND_JACK_LINEIN: Line in + * @SND_JACK_BTN_0: Button 0 + * @SND_JACK_BTN_1: Button 1 + * @SND_JACK_BTN_2: Button 2 + * @SND_JACK_BTN_3: Button 3 + * @SND_JACK_BTN_4: Button 4 + * @SND_JACK_BTN_5: Button 5 * * These values are used as a bitmask. * -- GitLab From f533ccb61edf008e14c9e1b91b48cd2c7397f33d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2014 08:22:05 +0100 Subject: [PATCH 1730/9457] ALSA: doc: Fix uapi/sound/compress_offload.h kerneldoc comments so that make htmldocs works properly. Since kerneldoc can't handle noname enum properly, name enum sndrv_compress_encoder. Signed-off-by: Takashi Iwai --- include/uapi/sound/compress_offload.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h index 1964026b5e09..22ed8cb7800b 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -32,7 +32,7 @@ #define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2) /** - * struct snd_compressed_buffer: compressed buffer + * struct snd_compressed_buffer - compressed buffer * @fragment_size: size of buffer fragment in bytes * @fragments: number of such fragments */ @@ -42,7 +42,7 @@ struct snd_compressed_buffer { } __attribute__((packed, aligned(4))); /** - * struct snd_compr_params: compressed stream params + * struct snd_compr_params - compressed stream params * @buffer: buffer description * @codec: codec parameters * @no_wake_mode: dont wake on fragment elapsed @@ -54,7 +54,7 @@ struct snd_compr_params { } __attribute__((packed, aligned(4))); /** - * struct snd_compr_tstamp: timestamp descriptor + * struct snd_compr_tstamp - timestamp descriptor * @byte_offset: Byte offset in ring buffer to DSP * @copied_total: Total number of bytes copied from/to ring buffer to/by DSP * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by @@ -73,7 +73,7 @@ struct snd_compr_tstamp { } __attribute__((packed, aligned(4))); /** - * struct snd_compr_avail: avail descriptor + * struct snd_compr_avail - avail descriptor * @avail: Number of bytes available in ring buffer for writing/reading * @tstamp: timestamp infomation */ @@ -88,7 +88,7 @@ enum snd_compr_direction { }; /** - * struct snd_compr_caps: caps descriptor + * struct snd_compr_caps - caps descriptor * @codecs: pointer to array of codecs * @direction: direction supported. Of type snd_compr_direction * @min_fragment_size: minimum fragment supported by DSP @@ -110,7 +110,7 @@ struct snd_compr_caps { } __attribute__((packed, aligned(4))); /** - * struct snd_compr_codec_caps: query capability of codec + * struct snd_compr_codec_caps - query capability of codec * @codec: codec for which capability is queried * @num_descriptors: number of codec descriptors * @descriptor: array of codec capability descriptor @@ -122,18 +122,19 @@ struct snd_compr_codec_caps { } __attribute__((packed, aligned(4))); /** + * enum sndrv_compress_encoder * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the * end of the track * @SNDRV_COMPRESS_ENCODER_DELAY: no of samples inserted by the encoder at the * beginning of the track */ -enum { +enum sndrv_compress_encoder { SNDRV_COMPRESS_ENCODER_PADDING = 1, SNDRV_COMPRESS_ENCODER_DELAY = 2, }; /** - * struct snd_compr_metadata: compressed stream metadata + * struct snd_compr_metadata - compressed stream metadata * @key: key id * @value: key value */ -- GitLab From 00dad6cfd25b75cc9cc24b8abfc263177e581ae2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2014 08:23:31 +0100 Subject: [PATCH 1731/9457] ALSA: doc: Include uapi/sound/compress_*.h, too Signed-off-by: Takashi Iwai --- Documentation/DocBook/alsa-driver-api.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl index 13f8b241f042..7bec270e2494 100644 --- a/Documentation/DocBook/alsa-driver-api.tmpl +++ b/Documentation/DocBook/alsa-driver-api.tmpl @@ -99,6 +99,8 @@ Compress Offload Compress Offload API !Esound/core/compress_offload.c +!Iinclude/uapi/sound/compress_offload.h +!Iinclude/uapi/sound/compress_params.h !Iinclude/sound/compress_driver.h -- GitLab From be4aa8157c981a8bb9634b886bf1180f97205259 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sun, 26 Oct 2014 19:59:43 +0200 Subject: [PATCH 1732/9457] staging: media: lirc: lirc_zilog.c: replace custom print macros with dev_* and pr_* This patch removes the custom printk macros dprintk, zilog_notify, zilog_error, and zilog_info. All the calls to these macros were replaced by dev_dbg, dev_notice, dev_err, and dev_info respectively whenever possible. There were cases in which pr_debug, pr_notice, pr_err and pr_info were used. It was when the calling function did not provide an appropiate dev variable. Applying this patch will trigger the out of memory checkpatch warning for two lines. It will be fixed in a separate patch. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_zilog.c | 139 ++++++++++++------------ 1 file changed, 68 insertions(+), 71 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 567feba0011c..11a7cb128d9e 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -152,23 +152,12 @@ struct tx_data_struct { static struct tx_data_struct *tx_data; static struct mutex tx_data_lock; -#define zilog_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, \ - ## args) -#define zilog_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) -#define zilog_info(s, args...) printk(KERN_INFO KBUILD_MODNAME ": " s, ## args) /* module parameters */ static bool debug; /* debug output */ static bool tx_only; /* only handle the IR Tx function */ static int minor = -1; /* minor number */ -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ - ## args); \ - } while (0) - /* struct IR reference counting */ static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held) @@ -333,7 +322,7 @@ static int add_to_buf(struct IR *ir) struct IR_tx *tx; if (lirc_buffer_full(rbuf)) { - dprintk("buffer overflow\n"); + dev_dbg(ir->l.dev, "buffer overflow\n"); return -EOVERFLOW; } @@ -379,16 +368,17 @@ static int add_to_buf(struct IR *ir) */ ret = i2c_master_send(rx->c, sendbuf, 1); if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(ir->l.dev, "i2c_master_send failed with %d\n", + ret); if (failures >= 3) { mutex_unlock(&ir->ir_lock); - zilog_error("unable to read from the IR chip " + dev_err(ir->l.dev, "unable to read from the IR chip " "after 3 resets, giving up\n"); break; } /* Looks like the chip crashed, reset it */ - zilog_error("polling the IR receiver chip failed, " + dev_err(ir->l.dev, "polling the IR receiver chip failed, " "trying reset\n"); set_current_state(TASK_UNINTERRUPTIBLE); @@ -415,13 +405,14 @@ static int add_to_buf(struct IR *ir) ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); mutex_unlock(&ir->ir_lock); if (ret != sizeof(keybuf)) { - zilog_error("i2c_master_recv failed with %d -- " + dev_err(ir->l.dev, "i2c_master_recv failed with %d -- " "keeping last read buffer\n", ret); } else { rx->b[0] = keybuf[3]; rx->b[1] = keybuf[4]; rx->b[2] = keybuf[5]; - dprintk("key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]); + dev_dbg(ir->l.dev, "key (0x%02x/0x%02x)\n", + rx->b[0], rx->b[1]); } /* key pressed ? */ @@ -472,7 +463,7 @@ static int lirc_thread(void *arg) struct IR *ir = arg; struct lirc_buffer *rbuf = ir->l.rbuf; - dprintk("poll thread started\n"); + dev_dbg(ir->l.dev, "poll thread started\n"); while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); @@ -500,7 +491,7 @@ static int lirc_thread(void *arg) wake_up_interruptible(&rbuf->wait_poll); } - dprintk("poll thread ended\n"); + dev_dbg(ir->l.dev, "poll thread ended\n"); return 0; } @@ -644,7 +635,7 @@ static int get_key_data(unsigned char *buf, return -EPROTO; corrupt: - zilog_error("firmware is corrupt\n"); + pr_err("firmware is corrupt\n"); return -EFAULT; } @@ -662,10 +653,11 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block) buf[0] = (unsigned char)(i + 1); for (j = 0; j < tosend; ++j) buf[1 + j] = data_block[i + j]; - dprintk("%*ph", 5, buf); + dev_dbg(tx->ir->l.dev, "%*ph", 5, buf); ret = i2c_master_send(tx->c, buf, tosend + 1); if (ret != tosend + 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", + ret); return ret < 0 ? ret : -EFAULT; } i += tosend; @@ -689,7 +681,7 @@ static int send_boot_data(struct IR_tx *tx) buf[1] = 0x20; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -706,21 +698,22 @@ static int send_boot_data(struct IR_tx *tx) } if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Here comes the firmware version... (hopefully) */ ret = i2c_master_recv(tx->c, buf, 4); if (ret != 4) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return 0; } if ((buf[0] != 0x80) && (buf[0] != 0xa0)) { - zilog_error("unexpected IR TX init response: %02x\n", buf[0]); + dev_err(tx->ir->l.dev, "unexpected IR TX init response: %02x\n", + buf[0]); return 0; } - zilog_notify("Zilog/Hauppauge IR blaster firmware version " + dev_notice(tx->ir->l.dev, "Zilog/Hauppauge IR blaster firmware version " "%d.%d.%d loaded\n", buf[1], buf[2], buf[3]); return 0; @@ -738,7 +731,7 @@ static void fw_unload_locked(void) vfree(tx_data); tx_data = NULL; - dprintk("successfully unloaded IR blaster firmware\n"); + pr_debug("successfully unloaded IR blaster firmware\n"); } } @@ -768,17 +761,17 @@ static int fw_load(struct IR_tx *tx) /* Request codeset data file */ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); if (ret != 0) { - zilog_error("firmware haup-ir-blaster.bin not available (%d)\n", + dev_err(tx->ir->l.dev, "firmware haup-ir-blaster.bin not available (%d)\n", ret); ret = ret < 0 ? ret : -EFAULT; goto out; } - dprintk("firmware of size %zu loaded\n", fw_entry->size); + dev_dbg(tx->ir->l.dev, "firmware of size %zu loaded\n", fw_entry->size); /* Parse the file */ tx_data = vmalloc(sizeof(*tx_data)); if (tx_data == NULL) { - zilog_error("out of memory\n"); + dev_err(tx->ir->l.dev, "out of memory\n"); release_firmware(fw_entry); ret = -ENOMEM; goto out; @@ -788,7 +781,7 @@ static int fw_load(struct IR_tx *tx) /* Copy the data so hotplug doesn't get confused and timeout */ tx_data->datap = vmalloc(fw_entry->size); if (tx_data->datap == NULL) { - zilog_error("out of memory\n"); + dev_err(tx->ir->l.dev, "out of memory\n"); release_firmware(fw_entry); vfree(tx_data); ret = -ENOMEM; @@ -803,7 +796,7 @@ static int fw_load(struct IR_tx *tx) if (!read_uint8(&data, tx_data->endp, &version)) goto corrupt; if (version != 1) { - zilog_error("unsupported code set file version (%u, expected" + dev_err(tx->ir->l.dev, "unsupported code set file version (%u, expected" "1) -- please upgrade to a newer driver", version); fw_unload_locked(); @@ -820,7 +813,8 @@ static int fw_load(struct IR_tx *tx) &tx_data->num_code_sets)) goto corrupt; - dprintk("%u IR blaster codesets loaded\n", tx_data->num_code_sets); + dev_dbg(tx->ir->l.dev, "%u IR blaster codesets loaded\n", + tx_data->num_code_sets); tx_data->code_sets = vmalloc( tx_data->num_code_sets * sizeof(char *)); @@ -884,7 +878,7 @@ static int fw_load(struct IR_tx *tx) goto out; corrupt: - zilog_error("firmware is corrupt\n"); + dev_err(tx->ir->l.dev, "firmware is corrupt\n"); fw_unload_locked(); ret = -EFAULT; @@ -904,9 +898,9 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, unsigned int m; DECLARE_WAITQUEUE(wait, current); - dprintk("read called\n"); + dev_dbg(ir->l.dev, "read called\n"); if (n % rbuf->chunk_size) { - dprintk("read result = -EINVAL\n"); + dev_dbg(ir->l.dev, "read result = -EINVAL\n"); return -EINVAL; } @@ -950,7 +944,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, unsigned char buf[MAX_XFER_SIZE]; if (rbuf->chunk_size > sizeof(buf)) { - zilog_error("chunk_size is too big (%d)!\n", + dev_err(ir->l.dev, "chunk_size is too big (%d)!\n", rbuf->chunk_size); ret = -EINVAL; break; @@ -964,7 +958,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, retries++; } if (retries >= 5) { - zilog_error("Buffer read failed!\n"); + dev_err(ir->l.dev, "Buffer read failed!\n"); ret = -EIO; } } @@ -974,7 +968,8 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, put_ir_rx(rx, false); set_current_state(TASK_RUNNING); - dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK"); + dev_dbg(ir->l.dev, "read result = %d (%s)\n", + ret, ret ? "Error" : "OK"); return ret ? ret : written; } @@ -990,7 +985,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = get_key_data(data_block, code, key); if (ret == -EPROTO) { - zilog_error("failed to get data for code %u, key %u -- check " + dev_err(tx->ir->l.dev, "failed to get data for code %u, key %u -- check " "lircd.conf entries\n", code, key); return ret; } else if (ret != 0) @@ -1006,7 +1001,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x40; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1019,18 +1014,18 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) } if (ret != 1) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Send finished download? */ ret = i2c_master_recv(tx->c, buf, 1); if (ret != 1) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } if (buf[0] != 0xA0) { - zilog_error("unexpected IR TX response #1: %02x\n", + dev_err(tx->ir->l.dev, "unexpected IR TX response #1: %02x\n", buf[0]); return -EFAULT; } @@ -1040,7 +1035,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x80; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - zilog_error("i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1050,7 +1045,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) * going to skip this whole mess and say we're done on the HD PVR */ if (!tx->post_tx_ready_poll) { - dprintk("sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1066,11 +1061,11 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = i2c_master_send(tx->c, buf, 1); if (ret == 1) break; - dprintk("NAK expected: i2c_master_send " + dev_dbg(tx->ir->l.dev, "NAK expected: i2c_master_send " "failed with %d (try %d)\n", ret, i+1); } if (ret != 1) { - zilog_error("IR TX chip never got ready: last i2c_master_send " + dev_err(tx->ir->l.dev, "IR TX chip never got ready: last i2c_master_send " "failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1078,16 +1073,17 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) /* Seems to be an 'ok' response */ i = i2c_master_recv(tx->c, buf, 1); if (i != 1) { - zilog_error("i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); return -EFAULT; } if (buf[0] != 0x80) { - zilog_error("unexpected IR TX response #2: %02x\n", buf[0]); + dev_err(tx->ir->l.dev, "unexpected IR TX response #2: %02x\n", + buf[0]); return -EFAULT; } /* Oh good, it worked */ - dprintk("sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1173,11 +1169,11 @@ static ssize_t write(struct file *filep, const char __user *buf, size_t n, */ if (ret != 0) { /* Looks like the chip crashed, reset it */ - zilog_error("sending to the IR transmitter chip " + dev_err(tx->ir->l.dev, "sending to the IR transmitter chip " "failed, trying reset\n"); if (failures >= 3) { - zilog_error("unable to send to the IR chip " + dev_err(tx->ir->l.dev, "unable to send to the IR chip " "after 3 resets, giving up\n"); mutex_unlock(&ir->ir_lock); mutex_unlock(&tx->client_lock); @@ -1212,7 +1208,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) struct lirc_buffer *rbuf = ir->l.rbuf; unsigned int ret; - dprintk("poll called\n"); + dev_dbg(ir->l.dev, "poll called\n"); rx = get_ir_rx(ir); if (rx == NULL) { @@ -1220,7 +1216,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) * Revisit this, if our poll function ever reports writeable * status for Tx */ - dprintk("poll result = POLLERR\n"); + dev_dbg(ir->l.dev, "poll result = POLLERR\n"); return POLLERR; } @@ -1233,7 +1229,8 @@ static unsigned int poll(struct file *filep, poll_table *wait) /* Indicate what ops could happen immediately without blocking */ ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM); - dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none"); + dev_dbg(ir->l.dev, "poll result = %s\n", + ret ? "POLLIN|POLLRDNORM" : "none"); return ret; } @@ -1340,7 +1337,7 @@ static int close(struct inode *node, struct file *filep) struct IR *ir = filep->private_data; if (ir == NULL) { - zilog_error("close: no private_data attached to the file!\n"); + dev_err(ir->l.dev, "close: no private_data attached to the file!\n"); return -ENODEV; } @@ -1452,7 +1449,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) int ret; bool tx_probe = false; - dprintk("%s: %s on i2c-%d (%s), client addr=0x%02x\n", + pr_debug("%s: %s on i2c-%d (%s), client addr=0x%02x\n", __func__, id->name, adap->nr, adap->name, client->addr); /* @@ -1465,7 +1462,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) else if (tx_only) /* module option */ return -ENXIO; - zilog_info("probing IR %s on %s (i2c-%d)\n", + pr_info("probing IR %s on %s (i2c-%d)\n", tx_probe ? "Tx" : "Rx", adap->name, adap->nr); mutex_lock(&ir_devices_lock); @@ -1547,7 +1544,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Proceed only if the Rx client is also ready or not needed */ if (rx == NULL && !tx_only) { - zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting" + dev_info(tx->ir->l.dev, "probe of IR Tx on %s (i2c-%d) done. Waiting" " on IR Rx.\n", adap->name, adap->nr); goto out_ok; } @@ -1586,7 +1583,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) "zilog-rx-i2c-%d", adap->nr); if (IS_ERR(rx->task)) { ret = PTR_ERR(rx->task); - zilog_error("%s: could not start IR Rx polling thread" + dev_err(tx->ir->l.dev, "%s: could not start IR Rx polling thread" "\n", __func__); /* Failed kthread, so put back the ir ref */ put_ir_device(ir, true); @@ -1599,7 +1596,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Proceed only if the Tx client is also ready */ if (tx == NULL) { - zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting" + pr_info("probe of IR Rx on %s (i2c-%d) done. Waiting" " on IR Tx.\n", adap->name, adap->nr); goto out_ok; } @@ -1609,12 +1606,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir->l.minor = minor; /* module option: user requested minor number */ ir->l.minor = lirc_register_driver(&ir->l); if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { - zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", + dev_err(tx->ir->l.dev, "%s: \"minor\" must be between 0 and %d (%d)!\n", __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); ret = -EBADRQC; goto out_put_xx; } - zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n", + dev_info(ir->l.dev, "IR unit on %s (i2c-%d) registered as lirc%d and ready\n", adap->name, adap->nr, ir->l.minor); out_ok: @@ -1623,7 +1620,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) if (tx != NULL) put_ir_tx(tx, true); put_ir_device(ir, true); - zilog_info("probe of IR %s on %s (i2c-%d) done\n", + dev_info(ir->l.dev, "probe of IR %s on %s (i2c-%d) done\n", tx_probe ? "Tx" : "Rx", adap->name, adap->nr); mutex_unlock(&ir_devices_lock); return 0; @@ -1636,7 +1633,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) out_put_ir: put_ir_device(ir, true); out_no_ir: - zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", + dev_err(ir->l.dev, "%s: probing IR %s on %s (i2c-%d) failed with %d\n", __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, ret); mutex_unlock(&ir_devices_lock); @@ -1647,7 +1644,7 @@ static int __init zilog_init(void) { int ret; - zilog_notify("Zilog/Hauppauge IR driver initializing\n"); + pr_notice("Zilog/Hauppauge IR driver initializing\n"); mutex_init(&tx_data_lock); @@ -1655,9 +1652,9 @@ static int __init zilog_init(void) ret = i2c_add_driver(&driver); if (ret) - zilog_error("initialization failed\n"); + pr_err("initialization failed\n"); else - zilog_notify("initialization complete\n"); + pr_notice("initialization complete\n"); return ret; } @@ -1667,7 +1664,7 @@ static void __exit zilog_exit(void) i2c_del_driver(&driver); /* if loaded */ fw_unload(); - zilog_notify("Zilog/Hauppauge IR driver unloaded\n"); + pr_notice("Zilog/Hauppauge IR driver unloaded\n"); } module_init(zilog_init); -- GitLab From c96bf1d6a49f0b0d38d668195ee34de52693fb87 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sun, 26 Oct 2014 19:46:00 +0200 Subject: [PATCH 1733/9457] staging: media: lirc: lirc_sir.c: use pr_debug and dev_dbg instead of dprintk This patch removes the custom printk macro dprintk and replaces most of the calls made to it by dev_dbg. pr_debug was used when the calling function did not provide the appropiate device variable. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_sir.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c index 2ee55eaf2a53..4af82e6b2d77 100644 --- a/drivers/staging/media/lirc/lirc_sir.c +++ b/drivers/staging/media/lirc/lirc_sir.c @@ -140,12 +140,6 @@ static int rx_buf[RBUF_LEN]; static unsigned int rx_tail, rx_head; static bool debug; -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ - fmt, ## args); \ - } while (0) /* SECTION: Prototypes */ @@ -322,7 +316,7 @@ static void add_read_queue(int flag, unsigned long val) unsigned int new_rx_tail; int newval; - dprintk("add flag %d with val %lu\n", flag, val); + pr_debug("add flag %d with val %lu\n", flag, val); newval = val & PULSE_MASK; @@ -342,7 +336,7 @@ static void add_read_queue(int flag, unsigned long val) } new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); if (new_rx_tail == rx_head) { - dprintk("Buffer overrun.\n"); + pr_debug("Buffer overrun.\n"); return; } rx_buf[rx_tail] = newval; @@ -439,7 +433,8 @@ static void sir_timeout(unsigned long data) outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); /* determine 'virtual' pulse end: */ pulse_end = delta(&last_tv, &last_intr_tv); - dprintk("timeout add %d for %lu usec\n", last_value, pulse_end); + dev_dbg(driver.dev, "timeout add %d for %lu usec\n", + last_value, pulse_end); add_read_queue(last_value, pulse_end); last_value = 0; last_tv = last_intr_tv; @@ -479,14 +474,15 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) do_gettimeofday(&curr_tv); deltv = delta(&last_tv, &curr_tv); deltintrtv = delta(&last_intr_tv, &curr_tv); - dprintk("t %lu, d %d\n", deltintrtv, (int)data); + dev_dbg(driver.dev, "t %lu, d %d\n", + deltintrtv, (int)data); /* * if nothing came in last X cycles, * it was gap */ if (deltintrtv > TIME_CONST * threshold) { if (last_value) { - dprintk("GAP\n"); + dev_dbg(driver.dev, "GAP\n"); /* simulate signal change */ add_read_queue(last_value, deltv - -- GitLab From 732ba199ab07973dbc8f70903bea54cfbb63d11b Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sun, 26 Oct 2014 19:39:27 +0200 Subject: [PATCH 1734/9457] staging: media: lirc: lirc_imon.c: replace printk by dev_dbg This patch replaces the calls to printk by dev_dbg. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_imon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index e4cfbe34e56d..e3b1fa9fd2f4 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -600,8 +600,8 @@ static void imon_incoming_packet(struct imon_context *context, if (debug) { dev_info(dev, "raw packet: "); for (i = 0; i < len; ++i) - printk("%02x ", buf[i]); - printk("\n"); + dev_dbg(dev, "%02x ", buf[i]); + dev_dbg(dev, "\n"); } /* -- GitLab From 72f3f59e734c88f789fca5c60707c78e6533d064 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Sun, 26 Oct 2014 19:35:20 +0200 Subject: [PATCH 1735/9457] staging: media: lirc: lirc_bt829.c: replace dprintk by dev_dbg This patch removes the custom printk macro dprintk and replaces all the calls made to it by dev_dbg. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_bt829.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c index 4c806ba41323..44f565547179 100644 --- a/drivers/staging/media/lirc/lirc_bt829.c +++ b/drivers/staging/media/lirc/lirc_bt829.c @@ -56,11 +56,6 @@ static unsigned char do_get_bits(void); #define DRIVER_NAME "lirc_bt829" static bool debug; -#define dprintk(fmt, args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG DRIVER_NAME ": "fmt, ## args); \ - } while (0) static int atir_minor; static phys_addr_t pci_addr_phys; @@ -101,7 +96,7 @@ static int atir_add_to_buf(void *data, struct lirc_buffer *buf) status = poll_main(); key = (status >> 8) & 0xFF; if (status & 0xFF) { - dprintk("reading key %02X\n", key); + dev_dbg(atir_driver.dev, "reading key %02X\n", key); lirc_buffer_write(buf, &key); return 0; } @@ -110,13 +105,13 @@ static int atir_add_to_buf(void *data, struct lirc_buffer *buf) static int atir_set_use_inc(void *data) { - dprintk("driver is opened\n"); + dev_dbg(atir_driver.dev, "driver is opened\n"); return 0; } static void atir_set_use_dec(void *data) { - dprintk("driver is closed\n"); + dev_dbg(atir_driver.dev, "driver is closed\n"); } int init_module(void) @@ -154,7 +149,8 @@ int init_module(void) rc = atir_minor; goto err_unmap; } - dprintk("driver is registered on minor %d\n", atir_minor); + dev_dbg(atir_driver.dev, "driver is registered on minor %d\n", + atir_minor); return 0; -- GitLab From ed09b447dd079d2e73f7aa9b00b2cd0e81ba2b21 Mon Sep 17 00:00:00 2001 From: anuvazhayil Date: Wed, 29 Oct 2014 03:43:26 +0530 Subject: [PATCH 1736/9457] Staging: rtl8723au: rtw_cmd: Fix space prohibited between function name and open parenthesis Fixed the checkpatch.pl WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: anuvazhayil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_cmd.c | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index 424d96a1859a..f80e81cd14e6 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -36,25 +36,25 @@ static struct cmd_hdl wlancmds[] = { GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/ - GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/ - GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl23a) /*20*/ - GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl23a) - GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ - GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) - GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/ + GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/ + GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl23a) /*20*/ + GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl23a) + GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL) /*30*/ + GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) GEN_MLME_EXT_HANDLER(0, NULL) -- GitLab From 1e76bb40f85c543c306562b4e7fcb6209b39c5fa Mon Sep 17 00:00:00 2001 From: anuvazhayil Date: Wed, 29 Oct 2014 03:13:54 +0530 Subject: [PATCH 1737/9457] Staging: lustre: libcfs_cpu: Fix ERROR: do not initialise globals to 0 or NULL Fixed the ERROR: do not initialise globals to 0 or NULL Signed-off-by: anuvazhayil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c index dbb81b6cc200..31a558115a96 100644 --- a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c @@ -38,7 +38,7 @@ #include "../../include/linux/libcfs/libcfs.h" /** Global CPU partition table */ -struct cfs_cpt_table *cfs_cpt_table __read_mostly = NULL; +struct cfs_cpt_table *cfs_cpt_table __read_mostly; EXPORT_SYMBOL(cfs_cpt_table); #ifndef HAVE_LIBCFS_CPT -- GitLab From af3491b3709e9da39c42b8ce9a2cc17ded0926fd Mon Sep 17 00:00:00 2001 From: anuvazhayil Date: Wed, 29 Oct 2014 02:34:56 +0530 Subject: [PATCH 1738/9457] Staging: media: dm365_isif: Add blank line after variable declarations WARNING: Missing a blank line after declarations Signed-off-by: anuvazhayil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/davinci_vpfe/dm365_isif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index f00cd9f23227..fe66d98e28f4 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1602,6 +1602,7 @@ isif_pad_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_rect *rect; + rect = v4l2_subdev_get_try_crop(fh, ISIF_PAD_SINK); memcpy(&crop->rect, rect, sizeof(*rect)); } else { -- GitLab From c2f5a8d79358851cef76cb0b941d467dadfb5458 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 13 Oct 2014 13:41:20 +0100 Subject: [PATCH 1739/9457] staging: comedi: cb_pcimdas: use preferred block comment style Use the preferred block comment style for the copyright and Comedi driver description header comments. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcimdas.c | 71 +++++++++++---------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index fe4d2544f3dc..804b3c3d6a9d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -1,40 +1,41 @@ /* - comedi/drivers/cb_pcimdas.c - Comedi driver for Computer Boards PCIM-DAS1602/16 - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ + * comedi/drivers/cb_pcimdas.c + * Comedi driver for Computer Boards PCIM-DAS1602/16 + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + /* -Driver: cb_pcimdas -Description: Measurement Computing PCI Migration series boards -Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas) -Author: Richard Bytheway -Updated: Wed, 13 Nov 2002 12:34:56 +0000 -Status: experimental - -Written to support the PCIM-DAS1602/16 on a 2.4 series kernel. - -Configuration Options: - [0] - PCI bus number - [1] - PCI slot number - -Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). -Only supports DIO, AO and simple AI in it's present form. -No interrupts, multi channel or FIFO AI, -although the card looks like it could support this. -See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. -*/ + * Driver: cb_pcimdas + * Description: Measurement Computing PCI Migration series boards + * Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas) + * Author: Richard Bytheway + * Updated: Wed, 13 Nov 2002 12:34:56 +0000 + * Status: experimental + * + * Written to support the PCIM-DAS1602/16 on a 2.4 series kernel. + * + * Configuration Options: + * [0] - PCI bus number + * [1] - PCI slot number + * + * Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). + * Only supports DIO, AO and simple AI in it's present form. + * No interrupts, multi channel or FIFO AI, + * although the card looks like it could support this. + * See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. + */ #include #include -- GitLab From a3f8c58d6ad69949ba2724b0992b6f2bff94a9a3 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 10 Oct 2014 20:32:42 +0100 Subject: [PATCH 1740/9457] staging: comedi: usbduxsigma: updated contact details and status I've updated my contact details of the driver. I've also tested it thoroughly and it works perfectly. I've changed the status to stable. Signed-off-by: Bernd Porr Reviewed-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index ebd68e365bac..a869e38c777b 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1,6 +1,6 @@ /* * usbduxsigma.c - * Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com + * Copyright (C) 2011-2014 Bernd Porr, mail@berndporr.me.uk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,9 +17,9 @@ * Driver: usbduxsigma * Description: University of Stirling USB DAQ & INCITE Technology Limited * Devices: (ITL) USB-DUX [usbduxsigma] - * Author: Bernd Porr - * Updated: 8 Nov 2011 - * Status: testing + * Author: Bernd Porr + * Updated: 10 Oct 2014 + * Status: stable */ /* -- GitLab From 430c7421694c7508f557bf5a565c5a75c94bfa57 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 13 Oct 2014 13:41:21 +0100 Subject: [PATCH 1741/9457] staging: comedi: cb_pcimdas: update driver comment The Comedi driver comment mentions a couple of manual configuration options, but manual configuration via the COMEDI_DEVCONFIG ioctl and comedi "attach" handler is no longer supported by this driver. Update the comment appropriately. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcimdas.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 804b3c3d6a9d..433941a9aa36 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -27,8 +27,10 @@ * Written to support the PCIM-DAS1602/16 on a 2.4 series kernel. * * Configuration Options: - * [0] - PCI bus number - * [1] - PCI slot number + * none + * + * Manual configuration of PCI cards is not supported; they are configured + * automatically. * * Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). * Only supports DIO, AO and simple AI in it's present form. -- GitLab From 79f54ac18be5f5cadd7d0c1439491f98ab4c3a47 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 10 Oct 2014 20:34:04 +0100 Subject: [PATCH 1742/9457] staging: comedi: usbdux: updated contact details / comments I've updated my contact details and removed obsolete comments. Signed-off-by: Bernd Porr Reviewed-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 59 ++++++++++++------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 5adbfedf780f..89f6ece2f0aa 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,37 +1,34 @@ /* - comedi/drivers/usbdux.c - Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + * usbdux.c + * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * 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. */ + /* -Driver: usbdux -Description: University of Stirling USB DAQ & INCITE Technology Limited -Devices: [ITL] USB-DUX (usbdux.o) -Author: Bernd Porr -Updated: 8 Dec 2008 -Status: Stable -Configuration options: - You have to upload firmware with the -i option. The - firmware is usually installed under /usr/share/usb or - /usr/local/share/usb or /lib/firmware. - -Connection scheme for the counter at the digital port: - 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. - The sampling rate of the counter is approximately 500Hz. - -Please note that under USB2.0 the length of the channel list determines -the max sampling rate. If you sample only one channel you get 8kHz -sampling rate. If you sample two channels you get 4kHz and so on. -*/ + * Driver: usbdux + * Description: University of Stirling USB DAQ & INCITE Technology Limited + * Devices: (ITL) USB-DUX [usbdux] + * Author: Bernd Porr + * Updated: 10 Oct 2014 + * Status: Stable + * Connection scheme for the counter at the digital port: + * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. + * The sampling rate of the counter is approximately 500Hz. + * + * Note that under USB2.0 the length of the channel list determines + * the max sampling rate. If you sample only one channel you get 8kHz + * sampling rate. If you sample two channels you get 4kHz and so on. + */ + /* * I must give credit here to Chris Baugher who * wrote the driver for AT-MIO-16d. I used some parts of this -- GitLab From 4e3d14af1286886b5a06ee0da5600df8ce320773 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 13 Oct 2014 13:41:22 +0100 Subject: [PATCH 1743/9457] staging: comedi: cb_pcimdas: add support for PCIe-DAS1602/16 The Measurement Computing PCIe-DAS1602/16 is a PCI-Express version of the PCIM-DAS1602/16, but has a different PCI device ID. Add support for this device and update the driver description, Kconfig description and MODULE_DESCRIPTION. Thanks to Christoph Langbein for supplying the PCI device ID. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 4 ++-- drivers/staging/comedi/drivers/cb_pcimdas.c | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index a8bc2b567789..77c5013d81c5 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -939,11 +939,11 @@ config COMEDI_CB_PCIDDA called cb_pcidda. config COMEDI_CB_PCIMDAS - tristate "MeasurementComputing PCIM-DAS1602/16 support" + tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support" select COMEDI_8255 ---help--- Enable support for ComputerBoards/MeasurementComputing PCI Migration - series PCIM-DAS1602/16 + series PCIM-DAS1602/16 and PCIe-DAS1602/16. To compile this driver as a module, choose M here: the module will be called cb_pcimdas. diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 433941a9aa36..73e5c96ff249 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -1,6 +1,6 @@ /* * comedi/drivers/cb_pcimdas.c - * Comedi driver for Computer Boards PCIM-DAS1602/16 + * Comedi driver for Computer Boards PCIM-DAS1602/16 and PCIe-DAS1602/16 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef @@ -19,24 +19,26 @@ /* * Driver: cb_pcimdas * Description: Measurement Computing PCI Migration series boards - * Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas) + * Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas), PCIe-DAS1602/16 * Author: Richard Bytheway - * Updated: Wed, 13 Nov 2002 12:34:56 +0000 + * Updated: Mon, 13 Oct 2014 11:57:39 +0000 * Status: experimental * - * Written to support the PCIM-DAS1602/16 on a 2.4 series kernel. + * Written to support the PCIM-DAS1602/16 and PCIe-DAS1602/16. * * Configuration Options: * none * - * Manual configuration of PCI cards is not supported; they are configured + * Manual configuration of PCI(e) cards is not supported; they are configured * automatically. * * Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). * Only supports DIO, AO and simple AI in it's present form. * No interrupts, multi channel or FIFO AI, * although the card looks like it could support this. - * See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. + * + * http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf + * http://www.mccdaq.com/PDFs/Manuals/pcie-das1602-16.pdf */ #include @@ -48,7 +50,7 @@ #include "plx9052.h" #include "8255.h" -/* Registers for the PCIM-DAS1602/16 */ +/* Registers for the PCIM-DAS1602/16 and PCIe-DAS1602/16 */ /* DAC Offsets */ #define ADC_TRIG 0 @@ -254,7 +256,8 @@ static int cb_pcimdas_pci_probe(struct pci_dev *dev, } static const struct pci_device_id cb_pcimdas_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, /* PCIM-DAS1602/16 */ + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0115) }, /* PCIe-DAS1602/16 */ { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); @@ -268,5 +271,5 @@ static struct pci_driver cb_pcimdas_pci_driver = { module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for PCIM-DAS1602/16 and PCIe-DAS1602/16"); MODULE_LICENSE("GPL"); -- GitLab From 533de0f865d727a01a545116fb2447fd60c0bf19 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 10 Oct 2014 20:35:11 +0100 Subject: [PATCH 1744/9457] staging: comedi: usbduxfast: updated address details Updated the range of years, e-mail and added driver desription as usually done in comedi. Signed-off-by: Bernd Porr Reviewed-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index f85818dd5e11..cddc2ba294bb 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com + * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,6 +12,15 @@ * GNU General Public License for more details. */ +/* + * Driver: usbduxfast + * Description: University of Stirling USB DAQ & INCITE Technology Limited + * Devices: (ITL) USB-DUX [usbduxfast] + * Author: Bernd Porr + * Updated: 10 Oct 2014 + * Status: stable + */ + /* * I must give credit here to Chris Baugher who * wrote the driver for AT-MIO-16d. I used some parts of this -- GitLab From 42170711b7190824a7458b0719353912c9199bfc Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 12 Oct 2014 14:23:24 +0200 Subject: [PATCH 1745/9457] staging: comedi: drivers: comedi_bond.c: Changed from using strncat to strlcat Changed from using strncat to strlcat to simplify the code Signed-off-by: Rickard Strandqvist Reviewed-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_bond.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 8450c99af8b0..5d19861fbabc 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -262,12 +262,10 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) { /* Append dev:subdev to devpriv->name */ char buf[20]; - int left = - MAX_BOARD_NAME - strlen(devpriv->name) - 1; snprintf(buf, sizeof(buf), "%u:%u ", bdev->minor, bdev->subdev); - buf[sizeof(buf) - 1] = 0; - strncat(devpriv->name, buf, left); + strlcat(devpriv->name, buf, + sizeof(devpriv->name)); } } -- GitLab From bb856b6c041c200910b031b535397e2c805789c5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 13 Oct 2014 09:56:07 -0700 Subject: [PATCH 1746/9457] staging: comedi: comedidev.h: don't expose COMEDI_CB_* defines to userspace The COMEDI_CB_* defines are the comedi_async "events" that the drivers set to let the core detect the state of running async commands. These "events" are only relevant to the kernel modules and should not be exposed to userspace in the comedi.h user API header. Move the defines to comedidev.h to avoid exposing them. For aesthetics, convert the defines to bit shifts to better indicate that they are bitmask values. Cleanup the documentation. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 11 ----------- drivers/staging/comedi/comedidev.h | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index c8c99e65423b..f302ce6c93de 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -514,17 +514,6 @@ struct comedi_bufinfo { #define COMEDI_MIN_SPEED ((unsigned int)0xffffffff) -/* callback stuff */ -/* only relevant to kernel modules. */ - -#define COMEDI_CB_EOS 1 /* end of scan */ -#define COMEDI_CB_EOA 2 /* end of acquisition/output */ -#define COMEDI_CB_BLOCK 4 /* data has arrived: - * wakes up read() / write() */ -#define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ -#define COMEDI_CB_ERROR 16 /* card error during acquisition */ -#define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ - /**********************************************************/ /* everything after this line is ALPHA */ /**********************************************************/ diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 1b2bbd56f6ef..0b504b1d3f00 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -213,6 +213,22 @@ struct comedi_async { unsigned int x); }; +/** + * comedi_async callback "events" + * @COMEDI_CB_EOS: end-of-scan + * @COMEDI_CB_EOA: end-of-acquisition/output + * @COMEDI_CB_BLOCK: data has arrived, wakes up read() / write() + * @COMEDI_CB_EOBUF: DEPRECATED: end of buffer + * @COMEDI_CB_ERROR: card error during acquisition + * @COMEDI_CB_OVERFLOW: buffer overflow/underflow + */ +#define COMEDI_CB_EOS (1 << 0) +#define COMEDI_CB_EOA (1 << 1) +#define COMEDI_CB_BLOCK (1 << 2) +#define COMEDI_CB_EOBUF (1 << 3) +#define COMEDI_CB_ERROR (1 << 4) +#define COMEDI_CB_OVERFLOW (1 << 5) + struct comedi_driver { struct comedi_driver *next; -- GitLab From 781f933c151ee47e3cc1c8ef5491db23f1b61c9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 13 Oct 2014 09:56:08 -0700 Subject: [PATCH 1747/9457] staging: comedi: comedidev.h: clarify async->event error/cancel detection Introduce COMEDI_CB_ERROR_MASK and COMEDI_CB_CANCEL_MASK to clarify the async->events that indicate errors and cancel an async command. Use the new defines to tidy up and clarify the code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 18 ++++++++---------- drivers/staging/comedi/comedidev.h | 6 ++++++ drivers/staging/comedi/drivers.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 10 ++-------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 224af2b2a685..2fb0f874f71f 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1555,9 +1555,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, comedi_buf_reset(s); - async->cb_mask = - COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW; + async->cb_mask = COMEDI_CB_BLOCK | COMEDI_CB_CANCEL_MASK; if (async->cmd.flags & CMDF_WAKE_EOS) async->cb_mask |= COMEDI_CB_EOS; @@ -2390,14 +2388,14 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) if (!comedi_is_subdevice_running(s)) return; - if (s-> - async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW)) { + if (s->async->events & COMEDI_CB_CANCEL_MASK) runflags_mask |= SRF_RUNNING; - } - /* remember if an error event has occurred, so an error - * can be returned the next time the user does a read() */ - if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { + + /* + * Remember if an error event has occurred, so an error + * can be returned the next time the user does a read(). + */ + if (s->async->events & COMEDI_CB_ERROR_MASK) { runflags_mask |= SRF_ERROR; runflags |= SRF_ERROR; } diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 0b504b1d3f00..fb8ff84dab35 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -221,6 +221,9 @@ struct comedi_async { * @COMEDI_CB_EOBUF: DEPRECATED: end of buffer * @COMEDI_CB_ERROR: card error during acquisition * @COMEDI_CB_OVERFLOW: buffer overflow/underflow + * + * @COMEDI_CB_ERROR_MASK: events that indicate an error has occurred + * @COMEDI_CB_CANCEL_MASK: events that will cancel an async command */ #define COMEDI_CB_EOS (1 << 0) #define COMEDI_CB_EOA (1 << 1) @@ -229,6 +232,9 @@ struct comedi_async { #define COMEDI_CB_ERROR (1 << 4) #define COMEDI_CB_OVERFLOW (1 << 5) +#define COMEDI_CB_ERROR_MASK (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW) +#define COMEDI_CB_CANCEL_MASK (COMEDI_CB_EOA | COMEDI_CB_ERROR_MASK) + struct comedi_driver { struct comedi_driver *next; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 859b722188cc..ff2df8587eca 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -375,7 +375,7 @@ unsigned int comedi_handle_events(struct comedi_device *dev, if (events == 0) return events; - if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) + if (events & COMEDI_CB_CANCEL_MASK) s->cancel(dev, s); comedi_event(dev, s); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a04ce6bd3705..a3b34d881a08 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1119,7 +1119,6 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, unsigned short dacstat; unsigned int i, n; unsigned int events = 0; - bool running; /* Get DAC FIFO status. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); @@ -1201,12 +1200,8 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; } } - if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) - running = false; - else - running = true; async->events |= events; - return running; + return !(async->events & COMEDI_CB_CANCEL_MASK); } static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, @@ -2128,8 +2123,7 @@ static void pci230_handle_ai(struct comedi_device *dev, events |= COMEDI_CB_BLOCK; } async->events |= events; - if (!(async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | - COMEDI_CB_OVERFLOW))) { + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { /* update FIFO interrupt trigger level */ pci230_ai_update_fifo_trigger_level(dev, s); } -- GitLab From 8e89ba5b3ddc976f01944eaacd354d91a222b0dc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:11:26 -0700 Subject: [PATCH 1748/9457] staging: comedi: addi_apci_3200: remove driver This driver has some serious bitrot. In addition, it's not in the Kconfig or Makefile so it can't even be built. Just remove it. It would be easier to rewrite the driver than fix it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 3002 ----------------- .../staging/comedi/drivers/addi_apci_3200.c | 125 - 2 files changed, 3127 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c delete mode 100644 drivers/staging/comedi/drivers/addi_apci_3200.c diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c deleted file mode 100644 index 470b3f0d457f..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ /dev/null @@ -1,3002 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-3200 | Compiler : GCC | - | Module name : hwdrv_apci3200.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-3200 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | 02.07.04 | J. Krauth | Modification from the driver in order to | - | | | correct some errors when using several boards. | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ - | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 | - | | | - Read eeprom value | - | | | - Append APCI-3300 | - +----------+-----------+------------------------------------------------+ -*/ - -/* Card Specific information */ -/* #define APCI3200_ADDRESS_RANGE 264 */ - -/* Analog Input related Defines */ -#define APCI3200_AI_OFFSET_GAIN 0 -#define APCI3200_AI_SC_TEST 4 -#define APCI3200_AI_IRQ 8 -#define APCI3200_AI_AUTOCAL 12 -#define APCI3200_RELOAD_CONV_TIME_VAL 32 -#define APCI3200_CONV_TIME_TIME_BASE 36 -#define APCI3200_RELOAD_DELAY_TIME_VAL 40 -#define APCI3200_DELAY_TIME_TIME_BASE 44 -#define APCI3200_AI_MODULE1 0 -#define APCI3200_AI_MODULE2 64 -#define APCI3200_AI_MODULE3 128 -#define APCI3200_AI_MODULE4 192 -#define TRUE 1 -#define FALSE 0 -#define APCI3200_AI_EOSIRQ 16 -#define APCI3200_AI_EOS 20 -#define APCI3200_AI_CHAN_ID 24 -#define APCI3200_AI_CHAN_VAL 28 -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define APCI3200_MAXVOLT 2.5 -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -#define MAX_MODULE 4 - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3200_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci3300_ai = { - 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -int MODULE_NO; -struct { - int i_Gain; - int i_Polarity; - int i_OffsetRange; - int i_Coupling; - int i_SingleDiff; - int i_AutoCalibration; - unsigned int ui_ReloadValue; - unsigned int ui_TimeUnitReloadVal; - int i_Interrupt; - int i_ModuleSelection; -} Config_Parameters_Module1, Config_Parameters_Module2, - Config_Parameters_Module3, Config_Parameters_Module4; - - -struct str_ADDIDATA_RTDStruct { - unsigned int ul_NumberOfValue; - unsigned int *pul_ResistanceValue; - unsigned int *pul_TemperatureValue; -}; - -struct str_Module { - unsigned long ul_CurrentSourceCJC; - unsigned long ul_CurrentSource[5]; - unsigned long ul_GainFactor[8]; /* Gain Factor */ - unsigned int w_GainValue[10]; -}; - -struct str_BoardInfos { - - int i_CJCAvailable; - int i_CJCPolarity; - int i_CJCGain; - int i_InterruptFlag; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration; - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum; - int i_Offset; - unsigned int ui_Channel_num; - int i_Count; - int i_Initialised; - unsigned int ui_InterruptChannelValue[144]; /* Buffer */ - unsigned char b_StructInitialized; - /* 7 is the maximal number of channels */ - unsigned int ui_ScanValueArray[7 + 12]; - - int i_ConnectionType; - int i_NbrOfModule; - struct str_Module s_Module[MAX_MODULE]; -}; - -/* BEGIN JK 06.07.04: Management of sevrals boards */ -/* - int i_CJCAvailable=1; - int i_CJCPolarity=0; - int i_CJCGain=2;/* changed from 0 to 2 */ - int i_InterruptFlag=0; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration=0; /* : auto calibration */ - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount=0; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum=0; - int i_Offset; - unsigned int ui_Channel_num=0; - static int i_Count=0; - int i_Initialised=0; - unsigned int ui_InterruptChannelValue[96]; /* Buffer */ -*/ -struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of boards to be used */ -/* END JK 06.07.04: Management of sevrals boards */ - -#define AMCC_OP_REG_MCSR 0x3c -#define EEPROM_BUSY 0x80000000 -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ - -static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, - unsigned short *pw_DataRead) -{ - unsigned int dw_eeprom_busy = 0; - int i_Counter = 0; - int i_WordCounter; - int i; - unsigned char pb_ReadByte[1]; - unsigned char b_ReadLowByte = 0; - unsigned char b_ReadHighByte = 0; - unsigned char b_SelectedAddressLow = 0; - unsigned char b_SelectedAddressHigh = 0; - unsigned short w_ReadWord = 0; - - for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead; - i_WordCounter++) { - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - for (i_Counter = 0; i_Counter < 2; i_Counter++) { - b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; /* Read the low 8 bit part */ - b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; /* Read the high 8 bit part */ - - /* Select the load low address mode */ - outb(NVCMD_LOAD_LOW, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the low address */ - outb(b_SelectedAddressLow, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the load high address mode */ - outb(NVCMD_LOAD_HIGH, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Load the high address */ - outb(b_SelectedAddressHigh, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the READ mode */ - outb(NVCMD_BEGIN_READ, - dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR + - 3); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Read data into the EEPROM */ - *pb_ReadByte = - inb(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR + 2); - - /* Wait on busy */ - do { - dw_eeprom_busy = - inl(dw_PCIBoardEepromAddress + - AMCC_OP_REG_MCSR); - dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY; - } while (dw_eeprom_busy == EEPROM_BUSY); - - /* Select the upper address part */ - if (i_Counter == 0) - b_ReadLowByte = pb_ReadByte[0]; - else - b_ReadHighByte = pb_ReadByte[0]; - - - /* Sleep */ - msleep(1); - - } - w_ReadWord = - (b_ReadLowByte | (((unsigned short)b_ReadHighByte) * - 256)); - - pw_DataRead[i_WordCounter] = w_ReadWord; - - w_EepromStartAddress += 2; /* to read the next word */ - - } /* for (...) i_NbOfWordsToRead */ - return 0; -} - -static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, - struct str_BoardInfos *BoardInformations) -{ - unsigned short w_AnalogInputMainHeaderAddress; - unsigned short w_AnalogInputComponentAddress; - unsigned short w_NumberOfModuls = 0; - unsigned short w_CurrentSources[2]; - unsigned short w_ModulCounter = 0; - unsigned short w_FirstHeaderSize = 0; - unsigned short w_NumberOfInputs = 0; - unsigned short w_CJCFlag = 0; - unsigned short w_NumberOfGainValue = 0; - unsigned short w_SingleHeaderAddress = 0; - unsigned short w_SingleHeaderSize = 0; - unsigned short w_Input = 0; - unsigned short w_GainFactorAddress = 0; - unsigned short w_GainFactorValue[2]; - unsigned short w_GainIndex = 0; - unsigned short w_GainValue = 0; - - /*****************************************/ - /** Get the Analog input header address **/ - /*****************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, 0x116, /* w_EepromStartAddress: Analog input header address */ - &w_AnalogInputMainHeaderAddress); - - /*******************************************/ - /** Compute the real analog input address **/ - /*******************************************/ - w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100; - - /******************************/ - /** Get the number of moduls **/ - /******************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, /* w_EepromStartAddress: Number of conponment */ - &w_NumberOfModuls); - - for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls; - w_ModulCounter++) { - /***********************************/ - /** Compute the component address **/ - /***********************************/ - w_AnalogInputComponentAddress = - w_AnalogInputMainHeaderAddress + - (w_FirstHeaderSize * w_ModulCounter) + 0x04; - - /****************************/ - /** Read first header size **/ - /****************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, /* Address of the first header */ - &w_FirstHeaderSize); - - w_FirstHeaderSize = w_FirstHeaderSize >> 4; - - /***************************/ - /** Read number of inputs **/ - /***************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, /* Number of inputs for the first modul */ - &w_NumberOfInputs); - - w_NumberOfInputs = w_NumberOfInputs >> 4; - - /***********************/ - /** Read the CJC flag **/ - /***********************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, /* CJC flag */ - &w_CJCFlag); - - w_CJCFlag = (w_CJCFlag >> 3) & 0x1; /* Get only the CJC flag */ - - /*******************************/ - /** Read number of gain value **/ - /*******************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, /* Number of gain value */ - &w_NumberOfGainValue); - - w_NumberOfGainValue = w_NumberOfGainValue & 0xFF; - - /***********************************/ - /** Compute single header address **/ - /***********************************/ - w_SingleHeaderAddress = - w_AnalogInputComponentAddress + 0x46 + - (((w_NumberOfGainValue / 16) + 1) * 2) + - (6 * w_NumberOfGainValue) + - (4 * (((w_NumberOfGainValue / 16) + 1) * 2)); - - /********************************************/ - /** Read current sources value for input 1 **/ - /********************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_SingleHeaderAddress, /* w_EepromStartAddress: Single header address */ - &w_SingleHeaderSize); - - w_SingleHeaderSize = w_SingleHeaderSize >> 4; - - /*************************************/ - /** Read gain factor for the module **/ - /*************************************/ - w_GainFactorAddress = w_AnalogInputComponentAddress; - - for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue; - w_GainIndex++) { - /************************************/ - /** Read gain value for the module **/ - /************************************/ - i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), /* Gain value */ - &w_GainValue); - - BoardInformations->s_Module[w_ModulCounter]. - w_GainValue[w_GainIndex] = w_GainValue; - - /*************************************/ - /** Read gain factor for the module **/ - /*************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), /* Gain factor */ - w_GainFactorValue); - - BoardInformations->s_Module[w_ModulCounter]. - ul_GainFactor[w_GainIndex] = - (w_GainFactorValue[1] << 16) + - w_GainFactorValue[0]; - } - - /***************************************************************/ - /** Read current source value for each channels of the module **/ - /***************************************************************/ - for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) { - /********************************************/ - /** Read current sources value for input 1 **/ - /********************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, - (w_Input * w_SingleHeaderSize) + - w_SingleHeaderAddress + 0x0C, w_CurrentSources); - - /************************************/ - /** Save the current sources value **/ - /************************************/ - BoardInformations->s_Module[w_ModulCounter]. - ul_CurrentSource[w_Input] = - (w_CurrentSources[0] + - ((w_CurrentSources[1] & 0xFFF) << 16)); - } - - /***************************************/ - /** Read the CJC current source value **/ - /***************************************/ - i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */ - dw_PCIBoardEepromAddress, - (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress + - 0x0C, w_CurrentSources); - - /************************************/ - /** Save the current sources value **/ - /************************************/ - BoardInformations->s_Module[w_ModulCounter]. - ul_CurrentSourceCJC = - (w_CurrentSources[0] + - ((w_CurrentSources[1] & 0xFFF) << 16)); - } -} - -static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, - unsigned int ui_Channel_num, - unsigned int *CJCCurrentSource, - unsigned int *ChannelCurrentSource, - unsigned int *ChannelGainFactor) -{ - int i_DiffChannel = 0; - int i_Module = 0; - - /* Test if single or differential mode */ - if (s_BoardInfos[dev->minor].i_ConnectionType == 1) { - /* if diff */ - - if (ui_Channel_num <= 1) - i_DiffChannel = ui_Channel_num, i_Module = 0; - else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3)) - i_DiffChannel = ui_Channel_num - 2, i_Module = 1; - else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5)) - i_DiffChannel = ui_Channel_num - 4, i_Module = 2; - else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7)) - i_DiffChannel = ui_Channel_num - 6, i_Module = 3; - - } else { - /* if single */ - if ((ui_Channel_num == 0) || (ui_Channel_num == 1)) - i_DiffChannel = 0, i_Module = 0; - else if ((ui_Channel_num == 2) || (ui_Channel_num == 3)) - i_DiffChannel = 1, i_Module = 0; - else if ((ui_Channel_num == 4) || (ui_Channel_num == 5)) - i_DiffChannel = 0, i_Module = 1; - else if ((ui_Channel_num == 6) || (ui_Channel_num == 7)) - i_DiffChannel = 1, i_Module = 1; - else if ((ui_Channel_num == 8) || (ui_Channel_num == 9)) - i_DiffChannel = 0, i_Module = 2; - else if ((ui_Channel_num == 10) || (ui_Channel_num == 11)) - i_DiffChannel = 1, i_Module = 2; - else if ((ui_Channel_num == 12) || (ui_Channel_num == 13)) - i_DiffChannel = 0, i_Module = 3; - else if ((ui_Channel_num == 14) || (ui_Channel_num == 15)) - i_DiffChannel = 1, i_Module = 3; - } - - /* Test if thermocouple or RTD mode */ - *CJCCurrentSource = - s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC; - - *ChannelCurrentSource = - s_BoardInfos[dev->minor].s_Module[i_Module]. - ul_CurrentSource[i_DiffChannel]; - /* } */ - /* } */ - - /* Channle gain factor */ - *ChannelGainFactor = - s_BoardInfos[dev->minor].s_Module[i_Module]. - ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain]; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - return 0; -} - -static int apci3200_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - data[1] = inl(devpriv->i_IobaseReserved) & 0xf; - - return insn->n; -} - -static int apci3200_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - s->state = inl(devpriv->i_IobaseAddon) & 0xf; - - if (comedi_dio_update_state(s, data)) - outl(s->state, devpriv->i_IobaseAddon); - - data[1] = s->state; - - return insn->n; -} - -static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_ChannelNo=i_ChannelNo; */ - ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo; - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - outl(0 | s_BoardInfos[dev->minor].i_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* End JK 20.10.2004: Bad channel value is used when using differential mode */ - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /**************************************************************************/ - /* Set the start end stop index to the selected channel and set the start */ - /**************************************************************************/ - - ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /* Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /******************************/ - /* Write the command register */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*************************/ - /*Read the EOC Status bit */ - /*************************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /***************************************/ - /* Read the digital value of the input */ - /***************************************/ - - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* END JK 06.07.04: Management of sevrals boards */ - - } - return 0; -} - -static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp = 0, ui_EOC = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /*****************************/ - /*Read the calibration offset */ - /*****************************/ - /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*********************************/ - /*Configure the Offset Conversion */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */ - outl((ui_Temp | 0x00020000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - - ui_CommandRegister = 0; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /**************************************************/ - /*Read the digital value of the calibration Offset */ - /**************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ - - /***************************/ - /*Read the calibration gain */ - /***************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /*******************************/ - /*Configure the Gain Conversion */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */ - outl(0x00040000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - - ui_CommandRegister = 0; - - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /************************************************/ - /*Read the digital value of the calibration Gain */ - /************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - } - return 0; -} - -static int i_APCI3200_ReadCJCValue(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /******************************/ - /*Set the converting time unit */ - /******************************/ - - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - - ui_CommandRegister = ui_CommandRegister | 0x00080000; - - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*Test if interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - - /*******************/ - /*Read the EOC flag */ - /*******************/ - - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - - } while (ui_EOC != 1); - - /***********************************/ - /*Read the digital value of the CJC */ - /***********************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /*******************************************/ - /*Read calibration offset value for the CJC */ - /*******************************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*********************************/ - /*Configure the Offset Conversion */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */ - outl(0x00020000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - - /**************************************************/ - /*Read the digital value of the calibration Offset */ - /**************************************************/ - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; - - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Configure the Gain Conversion */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */ - outl(0x00040000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*Test if the interrupt is enable */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { - /*Enable the interrupt */ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - /************************************************/ - /*Read the digital value of the calibration Gain */ - /************************************************/ - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } - return 0; -} - -static int apci3200_reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - int i_Temp; - unsigned int dw_Dummy; - - /* i_InterruptFlag=0; */ - /* i_Initialised==0; */ - /* i_Count=0; */ - /* i_Sum=0; */ - - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 0; - - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - outl(0, devpriv->i_IobaseAddon); /* Resets the output */ - /***************/ - /*Empty the buffer */ - /**************/ - for (i_Temp = 0; i_Temp <= 95; i_Temp++) { - /* ui_InterruptChannelValue[i_Temp]=0; */ - s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; - } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - for (i_Temp = 0; i_Temp <= 192;) { - while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; - outl(0, devpriv->iobase + i_Temp + 8); - i_Temp = i_Temp + 64; - } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ - return 0; -} - -/* - * Read value of the selected channel - * - * data[0] : Digital Value Of Input - * data[1] : Calibration Offset Value - * data[2] : Calibration Gain Value - * data[3] : CJC value - * data[4] : CJC offset value - * data[5] : CJC gain value - * data[6] : CJC current source from eeprom - * data[7] : Channel current source from eeprom - * data[8] : Channle gain factor from eeprom - */ -static int apci3200_ai_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ui_DummyValue = 0; - int i_ConvertCJCCalibration; - int i = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_Initialised==0) */ - if (s_BoardInfos[dev->minor].i_Initialised == 0) - /* END JK 06.07.04: Management of sevrals boards */ - { - apci3200_reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ - - switch (insn->unused[0]) { - case 0: - - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 6], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 7], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 8]); - /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCalibrationOffsetValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 1] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 2] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - /**********************************/ - /*Test if the polarity is the same */ - /**********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor].i_CJCPolarity != - s_BoardInfos[dev->minor].i_ADDIDATAPolarity) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor].i_CJCGain == - s_BoardInfos[dev->minor].i_ADDIDATAGain) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=0; */ - /* ui_InterruptChannelValue[i_Count+5]=0; */ - - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* i_Count=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - } /* if(i_ScanType!=1) */ - else { - /* i_Count=i_Count +6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* else if(i_ScanType!=1) */ - - /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ - if ((s_BoardInfos[dev->minor].i_ScanType == 1) - && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { - /* i_Count=i_Count-6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count - 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - /* if(i_ScanType==0) */ - if (s_BoardInfos[dev->minor].i_ScanType == 0) { - /* - data[0]= ui_InterruptChannelValue[0]; - data[1]= ui_InterruptChannelValue[1]; - data[2]= ui_InterruptChannelValue[2]; - data[3]= ui_InterruptChannelValue[3]; - data[4]= ui_InterruptChannelValue[4]; - data[5]= ui_InterruptChannelValue[5]; - */ - data[0] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[0]; - data[1] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[1]; - data[2] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[2]; - data[3] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[3]; - data[4] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[4]; - data[5] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[5]; - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &data[6], &data[7], &data[8]); - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - break; - case 1: - - for (i = 0; i < insn->n; i++) { - /* data[i]=ui_InterruptChannelValue[i]; */ - data[i] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[i]; - } - - /* i_Count=0; */ - /* i_Sum=0; */ - /* if(i_ScanType==1) */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - if (s_BoardInfos[dev->minor].i_ScanType == 1) { - /* i_Initialised=0; */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } - break; - default: - printk("\nThe parameters passed are in error\n"); - apci3200_reset(dev); - return -EINVAL; - } /* switch(insn->unused[0]) */ - - return insn->n; -} - -/* - * Configures The Analog Input Subdevice - * - * data[0] = 0 Normal AI - * = 1 RTD - * = 2 THERMOCOUPLE - * data[1] = Gain To Use - * data[2] = 0 Bipolar - * = 1 Unipolar - * data[3] = Offset Range - * data[4] = 0 DC Coupling - * = 1 AC Coupling - * data[5] = 0 Single - * = 1 Differential - * data[6] = TimerReloadValue - * data[7] = ConvertingTimeUnit - * data[8] = 0 Analog voltage measurement - * = 1 Resistance measurement - * = 2 Temperature measurement - * data[9] = 0 Interrupt Disable - * = 1 INterrupt Enable - * data[10] = Type of Thermocouple - * data[11] = single channel Module Number - * data[12] = 0 Single Read - * = 1 Read more channel - * = 2 Single scan - * = 3 Continuous Scan - * data[13] = Number of channels to read - * data[14] = 0 RTD not used - * = 1 RTD 2 wire connection - * = 2 RTD 3 wire connection - * = 3 RTD 4 wire connection - */ -static int apci3200_ai_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ul_Config = 0, ul_Temp = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_Dummy = 0; - int i_err = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* Initialize the structure */ - if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { - s_BoardInfos[dev->minor].i_CJCAvailable = 1; - s_BoardInfos[dev->minor].i_CJCPolarity = 0; - s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ - s_BoardInfos[dev->minor].i_ChannelCount = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].ui_Channel_num = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 1; - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_ConnectionType = 0; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - memset(s_BoardInfos[dev->minor].s_Module, 0, - sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); - - v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, - &s_BoardInfos[dev->minor]); - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - - if (data[0] != 0 && data[0] != 1 && data[0] != 2) { - printk("\nThe selection of acquisition type is in error\n"); - i_err++; - } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ - if (data[0] == 1) { - if (data[14] != 0 && data[14] != 1 && data[14] != 2 - && data[14] != 4) { - printk("\n Error in selection of RTD connection type\n"); - i_err++; - } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ - } /* if(data[0]==1 ) */ - if (data[1] < 0 || data[1] > 7) { - printk("\nThe selection of gain is in error\n"); - i_err++; - } /* if(data[1]<0 || data[1]>7) */ - if (data[2] != 0 && data[2] != 1) { - printk("\nThe selection of polarity is in error\n"); - i_err++; - } /* if(data[2]!=0 && data[2]!=1) */ - if (data[3] != 0) { - printk("\nThe selection of offset range is in error\n"); - i_err++; - } /* if(data[3]!=0) */ - if (data[4] != 0 && data[4] != 1) { - printk("\nThe selection of coupling is in error\n"); - i_err++; - } /* if(data[4]!=0 && data[4]!=1) */ - if (data[5] != 0 && data[5] != 1) { - printk("\nThe selection of single/differential mode is in error\n"); - i_err++; - } /* if(data[5]!=0 && data[5]!=1) */ - if (data[8] != 0 && data[8] != 1 && data[2] != 2) { - printk("\nError in selection of functionality\n"); - } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ - if (data[12] == 0 || data[12] == 1) { - if (data[6] != 20 && data[6] != 40 && data[6] != 80 - && data[6] != 160) { - printk("\nThe selection of conversion time reload value is in error\n"); - i_err++; - } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ - if (data[7] != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - i_err++; - } /* if(data[7]!=2) */ - } - if (data[9] != 0 && data[9] != 1) { - printk("\nThe selection of interrupt enable is in error\n"); - i_err++; - } /* if(data[9]!=0 && data[9]!=1) */ - if (data[11] < 0 || data[11] > 4) { - printk("\nThe selection of module is in error\n"); - i_err++; - } /* if(data[11] <0 || data[11]>1) */ - if (data[12] < 0 || data[12] > 3) { - printk("\nThe selection of singlechannel/scan selection is in error\n"); - i_err++; - } /* if(data[12] < 0 || data[12]> 3) */ - if (data[13] < 0 || data[13] > 16) { - printk("\nThe selection of number of channels is in error\n"); - i_err++; - } /* if(data[13] <0 ||data[13] >15) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* - i_ChannelCount=data[13]; - i_ScanType=data[12]; - i_ADDIDATAPolarity = data[2]; - i_ADDIDATAGain=data[1]; - i_ADDIDATAConversionTime=data[6]; - i_ADDIDATAConversionTimeUnit=data[7]; - i_ADDIDATAType=data[0]; - */ - - /* Save acquisition configuration for the actual board */ - s_BoardInfos[dev->minor].i_ChannelCount = data[13]; - s_BoardInfos[dev->minor].i_ScanType = data[12]; - s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; - s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; - s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - s_BoardInfos[dev->minor].i_ConnectionType = data[5]; - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - /* while(i_InterruptFlag==1) */ - while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { -#ifndef MSXBOX - udelay(1); -#else - /* In the case where the driver is compiled for the MSX-Box */ - /* we used a printk to have a little delay because udelay */ - /* seems to be broken under the MSX-Box. */ - /* This solution hat to be studied. */ - printk(""); -#endif - } - /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - - ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=ui_ChannelNo; */ - /* ui_Channel_num =ui_ChannelNo; */ - - s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; - s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; - - /* END JK 06.07.04: Management of sevrals boards */ - - if (data[5] == 0) { - if (ui_ChannelNo > 15) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>15) */ - } /* if(data[5]==0) */ - else { - if (data[14] == 2) { - if (ui_ChannelNo > 3) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>3) */ - } /* if(data[14]==2) */ - else { - if (ui_ChannelNo > 7) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo>7) */ - } /* elseif(data[14]==2) */ - } /* elseif(data[5]==0) */ - if (data[12] == 0 || data[12] == 1) { - switch (data[5]) { - case 0: - if (ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ - if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ - if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ - break; - case 1: - if (data[14] == 2) { - if (ui_ChannelNo == 0) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==0 ) */ - if (ui_ChannelNo == 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==1) */ - if (ui_ChannelNo == 2) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==2 ) */ - if (ui_ChannelNo == 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==3) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=0; */ - s_BoardInfos[dev->minor].i_ChannelNo = 0; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = 0; - break; - } /* if(data[14]==2) */ - if (ui_ChannelNo <= 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo <=1) */ - if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-2; */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 2; - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 2; - } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-4; */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 4; - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 4; - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ - if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-6; */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 6; - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 6; - } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ - break; - - default: - printk("\n This selection of polarity does not exist\n"); - i_err++; - } /* switch(data[2]) */ - } /* if(data[12]==0 || data[12]==1) */ - else { - switch (data[11]) { - case 1: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 2: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 3: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 4: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - break; - default: - printk("\nError in module selection\n"); - i_err++; - } /* switch(data[11]) */ - } /* elseif(data[12]==0 || data[12]==1) */ - if (i_err) { - apci3200_reset(dev); - return -EINVAL; - } - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ScanType!=1) */ - - ul_Config = - data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | - (data[4] << 9); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ - outl(0 | ui_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /**************************/ - /* Reset the configuration */ - /**************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ - outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /* Write the configuration */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ - outl(ul_Config, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /*Reset the calibration bit */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ - outl((ul_Temp & 0xFFF9FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - if (data[9] == 1) { - devpriv->tsk_Current = current; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=1; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 1; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(data[9]==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* else if(data[9]==1) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Initialised=1; */ - s_BoardInfos[dev->minor].i_Initialised = 1; - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor].i_ScanType == 1) - /* END JK 06.07.04: Management of sevrals boards */ - { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Sum=i_Sum+1; */ - s_BoardInfos[dev->minor].i_Sum = - s_BoardInfos[dev->minor].i_Sum + 1; - /* END JK 06.07.04: Management of sevrals boards */ - - insn->unused[0] = 0; - apci3200_ai_read(dev, s, insn, &ui_Dummy); - } - - return insn->n; -} - -/* - * Tests the Selected Anlog Input Channel - * - * data[0] = 0 TestAnalogInputShortCircuit - * = 1 TestAnalogInputConnection - * - * data[0] : Digital value obtained - * data[1] : calibration offset - * data[2] : calibration gain - */ -static int apci3200_ai_bits_test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Configuration = 0; - int i_Temp; /* ,i_TimeUnit; */ - - /* if(i_Initialised==0) */ - - if (s_BoardInfos[dev->minor].i_Initialised == 0) { - apci3200_reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ - if (data[0] != 0 && data[0] != 1) { - printk("\nError in selection of functionality\n"); - apci3200_reset(dev); - return -EINVAL; - } /* if(data[0]!=0 && data[0]!=1) */ - - if (data[0] == 1) /* Perform Short Circuit TEST */ - { - /**************************/ - /*Set the short-cicuit bit */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + 12) >> 19) & 1) != - 1) ; - /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 4); - /*************************/ - /*Set the time unit to ns */ - /*************************/ - /* i_TimeUnit= i_ADDIDATAConversionTimeUnit; - i_ADDIDATAConversionTimeUnit= 1; */ - /* i_Temp= i_InterruptFlag ; */ - i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data); - /* if(i_AutoCalibration == FALSE) */ - if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00001000 | s_BoardInfos[dev->minor]. - i_ChannelNo), - devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 4); - data++; - i_APCI3200_ReadCalibrationOffsetValue(dev, data); - data++; - i_APCI3200_ReadCalibrationGainValue(dev, data); - } - } else { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + 12) >> 19) & 1) != - 1) ; - /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 4); - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 0); */ - ui_Configuration = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 0); - /*************************/ - /*Set the time unit to ns */ - /*************************/ - /* i_TimeUnit= i_ADDIDATAConversionTimeUnit; - i_ADDIDATAConversionTimeUnit= 1; */ - /* i_Temp= i_InterruptFlag ; */ - i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data); - /* if(i_AutoCalibration == FALSE) */ - if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) { - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor]. - i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */ - outl((0x00000800 | s_BoardInfos[dev->minor]. - i_ChannelNo), - devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 4); - data++; - i_APCI3200_ReadCalibrationOffsetValue(dev, data); - data++; - i_APCI3200_ReadCalibrationGainValue(dev, data); - } - } - /* i_InterruptFlag=i_Temp ; */ - s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp; - return insn->n; -} - -static int apci3200_ai_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - apci3200_reset(dev); - return insn->n; -} - -static int apci3200_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - - int err = 0; - unsigned int ui_ConvertTime = 0; - unsigned int ui_ConvertTimeBase = 0; - unsigned int ui_DelayTime = 0; - unsigned int ui_DelayTimeBase = 0; - int i_NbrOfChannel = 0; - int i_Cpt = 0; - double d_ConversionTimeForAllChannels = 0.0; - double d_SCANTimeNewUnit = 0.0; - unsigned int arg; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) - err |= -EINVAL; - - if (err) { - apci3200_reset(dev); - return 1; - } - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(&cmd->start_src); - err |= cfc_check_trigger_is_unique(&cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(&cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) { - apci3200_reset(dev); - return 2; - } - - /* Step 3: check if arguments are trivially valid */ - - switch (cmd->start_src) { - case TRIG_NOW: - err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - break; - case TRIG_EXT: - /* validate the trigger edge selection */ - arg = cmd->start_arg & 0xffff; - if (arg < 1 || arg > 3) { - cmd->start_arg &= ~0xffff; - cmd->start_arg |= 1; - err |= -EINVAL; - } - /* validate the trigger mode selection */ - arg = cmd->start_arg >> 16; - if (arg != 2) { - cmd->start_arg &= ~(0xffff << 16); - cmd->start_arg |= (2 << 16); - err |= -EINVAL; - } - break; - } - - err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - - /* i_FirstChannel=cmd->chanlist[0]; */ - s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; - /* i_LastChannel=cmd->chanlist[1]; */ - s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1]; - - if (cmd->convert_src == TRIG_TIMER) { - ui_ConvertTime = cmd->convert_arg & 0xFFFF; - ui_ConvertTimeBase = cmd->convert_arg >> 16; - if (ui_ConvertTime != 20 && ui_ConvertTime != 40 - && ui_ConvertTime != 80 && ui_ConvertTime != 160) - { - printk("\nThe selection of conversion time reload value is in error\n"); - err++; - } /* if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 ) */ - if (ui_ConvertTimeBase != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - err++; - } /* if(ui_ConvertTimeBase!=2) */ - } else { - ui_ConvertTime = 0; - ui_ConvertTimeBase = 0; - } - if (cmd->scan_begin_src == TRIG_FOLLOW) { - ui_DelayTime = 0; - ui_DelayTimeBase = 0; - } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */ - else { - ui_DelayTime = cmd->scan_begin_arg & 0xFFFF; - ui_DelayTimeBase = cmd->scan_begin_arg >> 16; - if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) { - err++; - printk("\nThe Delay time base selection is in error\n"); - } - if (ui_DelayTime < 1 || ui_DelayTime > 1023) { - err++; - printk("\nThe Delay time value is in error\n"); - } - if (err) { - apci3200_reset(dev); - return 3; - } - fpu_begin(); - d_SCANTimeNewUnit = (double)ui_DelayTime; - /* i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4; */ - i_NbrOfChannel = - s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor].i_FirstChannel + 4; - /**********************************************************/ - /*calculate the total conversion time for all the channels */ - /**********************************************************/ - d_ConversionTimeForAllChannels = - (double)((double)ui_ConvertTime / - (double)i_NbrOfChannel); - - /*******************************/ - /*Convert the frequence in time */ - /*******************************/ - d_ConversionTimeForAllChannels = - (double)1.0 / d_ConversionTimeForAllChannels; - ui_ConvertTimeBase = 3; - /***********************************/ - /*Test if the time unit is the same */ - /***********************************/ - - if (ui_DelayTimeBase <= ui_ConvertTimeBase) { - - for (i_Cpt = 0; - i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase); - i_Cpt++) { - - d_ConversionTimeForAllChannels = - d_ConversionTimeForAllChannels * 1000; - d_ConversionTimeForAllChannels = - d_ConversionTimeForAllChannels + 1; - } - } else { - for (i_Cpt = 0; - i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase); - i_Cpt++) { - d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000; - - } - } - - if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) { - - printk("\nSCAN Delay value cannot be used\n"); - /*********************************/ - /*SCAN Delay value cannot be used */ - /*********************************/ - err++; - } - fpu_end(); - } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */ - - if (err) { - apci3200_reset(dev); - return 4; - } - - return 0; -} - -static int apci3200_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Configuration = 0; - - /* i_InterruptFlag=0; */ - /* i_Initialised=0; */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - - /*******************/ - /*Read the register */ - /*******************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8); */ - outl((ui_Configuration & 0xFFE7FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - return 0; -} - -/* - * Does asynchronous acquisition - * Determines the mode 1 or 2. - */ -static int apci3200_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - unsigned int ui_Configuration = 0; - /* INT i_CurrentSource = 0; */ - unsigned int ui_Trigger = 0; - unsigned int ui_TriggerEdge = 0; - unsigned int ui_Triggermode = 0; - unsigned int ui_ScanMode = 0; - unsigned int ui_ConvertTime = 0; - unsigned int ui_ConvertTimeBase = 0; - unsigned int ui_DelayTime = 0; - unsigned int ui_DelayTimeBase = 0; - unsigned int ui_DelayMode = 0; - - /* i_FirstChannel=cmd->chanlist[0]; */ - /* i_LastChannel=cmd->chanlist[1]; */ - s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; - s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1]; - if (cmd->start_src == TRIG_EXT) { - ui_Trigger = 1; - ui_TriggerEdge = cmd->start_arg & 0xFFFF; - ui_Triggermode = cmd->start_arg >> 16; - } /* if(cmd->start_src==TRIG_EXT) */ - else { - ui_Trigger = 0; - } /* elseif(cmd->start_src==TRIG_EXT) */ - - if (cmd->stop_src == TRIG_COUNT) { - ui_ScanMode = 0; - } /* if (cmd->stop_src==TRIG_COUNT) */ - else { - ui_ScanMode = 2; - } /* else if (cmd->stop_src==TRIG_COUNT) */ - - if (cmd->scan_begin_src == TRIG_FOLLOW) { - ui_DelayTime = 0; - ui_DelayTimeBase = 0; - ui_DelayMode = 0; - } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */ - else { - ui_DelayTime = cmd->scan_begin_arg & 0xFFFF; - ui_DelayTimeBase = cmd->scan_begin_arg >> 16; - ui_DelayMode = 1; - } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */ - if (cmd->convert_src == TRIG_TIMER) { - ui_ConvertTime = cmd->convert_arg & 0xFFFF; - ui_ConvertTimeBase = cmd->convert_arg >> 16; - } else { - ui_ConvertTime = 0; - ui_ConvertTimeBase = 0; - } - - /* if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2))) */ - /* { */ - /**************************************************/ - /*Read the old configuration of the current source */ - /**************************************************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 12); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /***********************************************/ - /*Write the configuration of the current source */ - /***********************************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12); */ - outl((ui_Configuration & 0xFFC00000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* } */ - ui_Configuration = 0; - - /* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */ - ui_Configuration = - s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev-> - minor]. - i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) | - (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode - << 18) | (ui_ScanMode << 16); - - /*************************/ - /*Write the Configuration */ - /*************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8); */ - outl(ui_Configuration, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8); - /***********************/ - /*Write the Delay Value */ - /***********************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_DelayTime,devpriv->iobase+i_Offset + 40); */ - outl(ui_DelayTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40); - /***************************/ - /*Write the Delay time base */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44); */ - outl(ui_DelayTimeBase, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44); - /*********************************/ - /*Write the conversion time value */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32); */ - outl(ui_ConvertTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - - /********************************/ - /*Write the conversion time base */ - /********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36); */ - outl(ui_ConvertTimeBase, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /*******************/ - /*Read the register */ - /*******************/ - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 4); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /******************/ - /*Set the SCAN bit */ - /******************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - - /* outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4); */ - outl(((ui_Configuration & 0x1E0FF) | 0x00002000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************/ - /*Read the register */ - /*******************/ - ui_Configuration = 0; - /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */ - ui_Configuration = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*******************/ - /*Set the START bit */ - /*******************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */ - outl((ui_Configuration | 0x00080000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - return 0; -} - -/* - * This function copies the acquired data(from FIFO) to Comedi buffer. - */ -static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - unsigned int ui_StatusRegister = 0; - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* comedi_async *async = s->async; */ - /* UINT *data; */ - /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ - int n = 0, i = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); - - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* This value is not used */ - /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /*************************************/ - /*Read the digital Analog Input value */ - /*************************************/ - - /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ - s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ - if ((s_BoardInfos[dev->minor].i_Count == - (s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor]. - i_FirstChannel + 3))) { - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_Count++; - - for (i = s_BoardInfos[dev->minor].i_FirstChannel; - i <= s_BoardInfos[dev->minor].i_LastChannel; - i++) { - i_APCI3200_GetChannelCalibrationValue(dev, i, - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3)], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 1], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 2]); - } - - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* i_Count=-1; */ - - s_BoardInfos[dev->minor].i_Count = -1; - - /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* comedi_eos(dev,s); */ - - /* Set the event type (Comedi Buffer End Of Scan) */ - s->async->events |= COMEDI_CB_EOS; - - /* Test if enougth memory is available and allocate it for 7 values */ - n = comedi_buf_write_alloc(s, - (7 + 12) * sizeof(unsigned int)); - - /* If not enough memory available, event is set to Comedi Buffer Error */ - if (n > ((7 + 12) * sizeof(unsigned int))) { - printk("\ncomedi_buf_write_alloc n = %i", n); - s->async->events |= COMEDI_CB_ERROR; - } - /* Write all 7 scan values in the comedi buffer */ - comedi_buf_memcpy_to(s, 0, - (unsigned int *) s_BoardInfos[dev->minor]. - ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); - - /* Update comedi buffer pinters indexes */ - comedi_buf_write_free(s, - (7 + 12) * sizeof(unsigned int)); - - comedi_handle_events(dev, s); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* */ - /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ - /* { */ - /* /* buffer rollover */ */ - /* s->async->buf_int_ptr=0; */ - /* comedi_eobuf(dev,s); */ - /* } */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - } - /* i_Count++; */ - s_BoardInfos[dev->minor].i_Count++; - } - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - return 0; -} - -static void apci3200_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - unsigned int ui_StatusRegister = 0; - unsigned int ui_ChannelNumber = 0; - int i_CalibrationFlag = 0; - int i_CJCFlag = 0; - unsigned int ui_DummyValue = 0; - unsigned int ui_DigitalTemperature = 0; - unsigned int ui_DigitalInput = 0; - int i_ConvertCJCCalibration; - /* BEGIN JK TEST */ - int i_ReturnValue = 0; - /* END JK TEST */ - - /* switch(i_ScanType) */ - switch (s_BoardInfos[dev->minor].i_ScanType) { - case 0: - case 1: - /* switch(i_ADDIDATAType) */ - switch (s_BoardInfos[dev->minor].i_ADDIDATAType) { - case 0: - case 1: - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 16); - if ((ui_StatusRegister & 0x2) == 0x2) { - /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */ - i_CalibrationFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 12) & 0x00060000) >> - 17); - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - - /*************************************/ - /*Read the digital analog input value */ - /*************************************/ - /* ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28); */ - ui_DigitalInput = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - /***********************************************/ - /* Test if the value read is the channel value */ - /***********************************************/ - if (i_CalibrationFlag == 0) { - /* ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DigitalInput; - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num, - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6], - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7], - &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]); - */ - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /******************************************************/ - /*Start the conversion of the calibration offset value */ - /******************************************************/ - i_APCI3200_ReadCalibrationOffsetValue - (dev, &ui_DummyValue); - } /* if (i_CalibrationFlag == 0) */ - /**********************************************************/ - /* Test if the value read is the calibration offset value */ - /**********************************************************/ - - if (i_CalibrationFlag == 1) { - - /******************/ - /* Save the value */ - /******************/ - - /* ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 1] = ui_DigitalInput; - - /******************************************************/ - /* Start the conversion of the calibration gain value */ - /******************************************************/ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - } /* if (i_CalibrationFlag == 1) */ - /******************************************************/ - /*Test if the value read is the calibration gain value */ - /******************************************************/ - - if (i_CalibrationFlag == 2) { - - /****************/ - /*Save the value */ - /****************/ - /* ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 2] = ui_DigitalInput; - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType == 1) { - - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor]. - i_InterruptFlag = 0; - /* i_Count=i_Count + 6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */ - s_BoardInfos[dev->minor]. - i_Count = - s_BoardInfos[dev-> - minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* if(i_ScanType==1) */ - else { - /* i_Count=0; */ - s_BoardInfos[dev->minor]. - i_Count = 0; - } /* elseif(i_ScanType==1) */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType != 1) { - i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } /* if(i_ScanType!=1) */ - else { - /* if(i_ChannelCount==i_Sum) */ - if (s_BoardInfos[dev->minor]. - i_ChannelCount == - s_BoardInfos[dev-> - minor].i_Sum) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } - } /* if(i_ScanType!=1) */ - } /* if (i_CalibrationFlag == 2) */ - } /* if ((ui_StatusRegister & 0x2) == 0x2) */ - - break; - - case 2: - /************************************/ - /*Read the interrupt status register */ - /************************************/ - - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 16); - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - - /* i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10); */ - i_CJCFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 4) & 0x00000400) >> 10); - - /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */ - i_CalibrationFlag = - ((inl(devpriv->iobase + - s_BoardInfos[dev-> - minor]. - i_Offset + - 12) & 0x00060000) >> - 17); - - /*************************/ - /*Read the channel number */ - /*************************/ - - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - ui_ChannelNumber = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 24); - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].ui_Channel_num = - ui_ChannelNumber; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /************************************/ - /*Read the digital temperature value */ - /************************************/ - /* ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28); */ - ui_DigitalTemperature = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - - /*********************************************/ - /*Test if the value read is the channel value */ - /*********************************************/ - - if ((i_CalibrationFlag == 0) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 0] = - ui_DigitalTemperature; - - /*********************************/ - /*Start the conversion of the CJC */ - /*********************************/ - i_APCI3200_ReadCJCValue(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0)) */ - - /*****************************************/ - /*Test if the value read is the CJC value */ - /*****************************************/ - - if ((i_CJCFlag == 1) - && (i_CalibrationFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 3] = - ui_DigitalTemperature; - - /******************************************************/ - /*Start the conversion of the calibration offset value */ - /******************************************************/ - i_APCI3200_ReadCalibrationOffsetValue - (dev, &ui_DummyValue); - } /* if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0)) */ - - /********************************************************/ - /*Test if the value read is the calibration offset value */ - /********************************************************/ - - if ((i_CalibrationFlag == 1) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 1] = - ui_DigitalTemperature; - - /****************************************************/ - /*Start the conversion of the calibration gain value */ - /****************************************************/ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0)) */ - - /******************************************************/ - /*Test if the value read is the calibration gain value */ - /******************************************************/ - - if ((i_CalibrationFlag == 2) - && (i_CJCFlag == 0)) { - /* ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 2] = - ui_DigitalTemperature; - - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - - /*Test if the polarity is the same */ - /**********************************/ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor]. - i_CJCPolarity != - s_BoardInfos[dev->minor]. - i_ADDIDATAPolarity) { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor]. - i_CJCGain == - s_BoardInfos[dev-> - minor]. - i_ADDIDATAGain) { - i_ConvertCJCCalibration - = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration - = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - /****************************************************************/ - /*Start the conversion of the calibration gain value for the CJC */ - /****************************************************************/ - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* ui_InterruptChannelValue[i_Count + 4]=0; */ - /* ui_InterruptChannelValue[i_Count + 5]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev-> - minor].i_Count + - 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev-> - minor].i_Count + - 5] = 0; - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0)) */ - - /********************************************************************/ - /*Test if the value read is the calibration offset value for the CJC */ - /********************************************************************/ - - if ((i_CalibrationFlag == 1) - && (i_CJCFlag == 1)) { - /* ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 4] = - ui_DigitalTemperature; - - /****************************************************************/ - /*Start the conversion of the calibration gain value for the CJC */ - /****************************************************************/ - i_APCI3200_ReadCJCCalGain(dev, - &ui_DummyValue); - - } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1)) */ - - /******************************************************************/ - /*Test if the value read is the calibration gain value for the CJC */ - /******************************************************************/ - - if ((i_CalibrationFlag == 2) - && (i_CJCFlag == 1)) { - /* ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue - [s_BoardInfos[dev->minor]. - i_Count + 5] = - ui_DigitalTemperature; - - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType == 1) { - - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor]. - i_InterruptFlag = 0; - /* i_Count=i_Count + 6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */ - s_BoardInfos[dev->minor]. - i_Count = - s_BoardInfos[dev-> - minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* if(i_ScanType==1) */ - else { - /* i_Count=0; */ - s_BoardInfos[dev->minor]. - i_Count = 0; - } /* elseif(i_ScanType==1) */ - - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor]. - i_ScanType != 1) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } /* if(i_ScanType!=1) */ - else { - /* if(i_ChannelCount==i_Sum) */ - if (s_BoardInfos[dev->minor]. - i_ChannelCount == - s_BoardInfos[dev-> - minor].i_Sum) { - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - - } /* if(i_ChannelCount==i_Sum) */ - } /* else if(i_ScanType!=1) */ - } /* if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1)) */ - - } /* else if ((ui_StatusRegister & 0x2) == 0x2) */ - break; - } /* switch(i_ADDIDATAType) */ - break; - case 2: - case 3: - i_APCI3200_InterruptHandleEos(dev); - break; - } /* switch(i_ScanType) */ - return; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c deleted file mode 100644 index fe6897eff3db..000000000000 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include - -#include - -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -static void fpu_begin(void) -{ - kernel_fpu_begin(); -} - -static void fpu_end(void) -{ - kernel_fpu_end(); -} - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci3200.c" -#include "addi-data/addi_common.c" - -enum apci3200_boardid { - BOARD_APCI3200, - BOARD_APCI3300, -}; - -static const struct addi_board apci3200_boardtypes[] = { - [BOARD_APCI3200] = { - .pc_DriverName = "apci3200", - .i_IorangeBase1 = 256, - .i_PCIEeprom = 1, - .pc_EepromChip = "S5920", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3200_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = apci3200_interrupt, - .reset = apci3200_reset, - .ai_config = apci3200_ai_config, - .ai_read = apci3200_ai_read, - .ai_write = apci3200_ai_write, - .ai_bits = apci3200_ai_bits_test, - .ai_cmdtest = apci3200_ai_cmdtest, - .ai_cmd = apci3200_ai_cmd, - .ai_cancel = apci3200_cancel, - .di_bits = apci3200_di_insn_bits, - .do_bits = apci3200_do_insn_bits, - }, - [BOARD_APCI3300] = { - .pc_DriverName = "apci3300", - .i_IorangeBase1 = 256, - .i_PCIEeprom = 1, - .pc_EepromChip = "S5920", - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3300_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = apci3200_interrupt, - .reset = apci3200_reset, - .ai_config = apci3200_ai_config, - .ai_read = apci3200_ai_read, - .ai_write = apci3200_ai_write, - .ai_bits = apci3200_ai_bits_test, - .ai_cmdtest = apci3200_ai_cmdtest, - .ai_cmd = apci3200_ai_cmd, - .ai_cancel = apci3200_cancel, - .di_bits = apci3200_di_insn_bits, - .do_bits = apci3200_do_insn_bits, - }, -}; - -static int apci3200_auto_attach(struct comedi_device *dev, - unsigned long context) -{ - const struct addi_board *board = NULL; - - if (context < ARRAY_SIZE(apci3200_boardtypes)) - board = &apci3200_boardtypes[context]; - if (!board) - return -ENODEV; - dev->board_ptr = board; - - return addi_auto_attach(dev, context); -} - -static struct comedi_driver apci3200_driver = { - .driver_name = "addi_apci_3200", - .module = THIS_MODULE, - .auto_attach = apci3200_auto_attach, - .detach = i_ADDI_Detach, -}; - -static int apci3200_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); -} - -static const struct pci_device_id apci3200_pci_table[] = { - { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 }, - { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci3200_pci_table); - -static struct pci_driver apci3200_pci_driver = { - .name = "addi_apci_3200", - .id_table = apci3200_pci_table, - .probe = apci3200_pci_probe, - .remove = comedi_pci_auto_unconfig, -}; -module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver); -- GitLab From 6a9c41990da91566733e559b6af8286a902a16e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:17 -0700 Subject: [PATCH 1749/9457] staging: comedi: addi_common.c: remove i_ADDI_Detach() The addi_apci_035 and addi_apci_1500 are the only drivers left that use this function in addi_common.c. Remove the function an add a private comedi_driver (*detach) function to those drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 7 ------- drivers/staging/comedi/drivers/addi_apci_035.c | 9 ++++++++- drivers/staging/comedi/drivers/addi_apci_1500.c | 9 ++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 2e7fb218340f..51574a8d027a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -265,10 +265,3 @@ static int addi_auto_attach(struct comedi_device *dev, i_ADDI_Reset(dev); return 0; } - -static void i_ADDI_Detach(struct comedi_device *dev) -{ - if (dev->iobase) - i_ADDI_Reset(dev); - comedi_pci_detach(dev); -} diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index af70c8401880..b06fde1d6c39 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -45,11 +45,18 @@ static int apci035_auto_attach(struct comedi_device *dev, return addi_auto_attach(dev, context); } +static void apci035_detach(struct comedi_device *dev) +{ + if (dev->iobase) + i_ADDI_Reset(dev); + comedi_pci_detach(dev); +} + static struct comedi_driver apci035_driver = { .driver_name = "addi_apci_035", .module = THIS_MODULE, .auto_attach = apci035_auto_attach, - .detach = i_ADDI_Detach, + .detach = apci035_detach, }; static int apci035_pci_probe(struct pci_dev *dev, diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index b7a284ac6649..50a147fc38bf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -44,11 +44,18 @@ static int apci1500_auto_attach(struct comedi_device *dev, return addi_auto_attach(dev, context); } +static void apci1500_detach(struct comedi_device *dev) +{ + if (dev->iobase) + i_ADDI_Reset(dev); + comedi_pci_detach(dev); +} + static struct comedi_driver apci1500_driver = { .driver_name = "addi_apci_1500", .module = THIS_MODULE, .auto_attach = apci1500_auto_attach, - .detach = i_ADDI_Detach, + .detach = apci1500_detach, }; static int apci1500_pci_probe(struct pci_dev *dev, -- GitLab From 5b1ccca7276d49daa3546dabebc5cdbb63c8d21d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:18 -0700 Subject: [PATCH 1750/9457] staging: comedi: addi_common.c: remove i_ADDI_Reset() The addi_apci_035 and addi_apci_1500 are the only drivers left that use this function in addi_common.c. The function simply calls the 'reset' function that is in the boardinfo of the driver. Both drivers use the same 'reset' function for all boardnfo entries. Remove the i_ADDI_Reset() function as well as the 'reset' boardinfo and just call the 'reset' function directly. The i_ADDI_Reset() is called by addi_auto_attach() in addi_common.c after a sucessful attach. Modify the (*auto_attach) in the drivers to call the 'reset' function directly and remove it from addi_auto_attach(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 9 --------- drivers/staging/comedi/drivers/addi_apci_035.c | 13 ++++++++++--- drivers/staging/comedi/drivers/addi_apci_1500.c | 13 ++++++++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 51574a8d027a..d0bd8127d52c 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -65,14 +65,6 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = dev->board_ptr; - - this_board->reset(dev); - return 0; -} - static int addi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { @@ -262,6 +254,5 @@ static int addi_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - i_ADDI_Reset(dev); return 0; } diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index b06fde1d6c39..dd28adb00e3d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -28,7 +28,6 @@ static const struct addi_board apci035_boardtypes[] = { .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, .interrupt = apci035_interrupt, - .reset = apci035_reset, .ai_config = apci035_ai_config, .ai_read = apci035_ai_read, .timer_config = apci035_timer_config, @@ -40,15 +39,23 @@ static const struct addi_board apci035_boardtypes[] = { static int apci035_auto_attach(struct comedi_device *dev, unsigned long context) { + int ret; + dev->board_ptr = &apci035_boardtypes[0]; - return addi_auto_attach(dev, context); + ret = addi_auto_attach(dev, context); + if (ret) + return ret; + + apci035_reset(dev); + + return 0; } static void apci035_detach(struct comedi_device *dev) { if (dev->iobase) - i_ADDI_Reset(dev); + apci035_reset(dev); comedi_pci_detach(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 50a147fc38bf..d4b42618859e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -21,7 +21,6 @@ static const struct addi_board apci1500_boardtypes[] = { .i_DoMaxdata = 0xffff, .i_Timer = 1, .interrupt = apci1500_interrupt, - .reset = apci1500_reset, .di_config = apci1500_di_config, .di_read = apci1500_di_read, .di_write = apci1500_di_write, @@ -39,15 +38,23 @@ static const struct addi_board apci1500_boardtypes[] = { static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { + int ret; + dev->board_ptr = &apci1500_boardtypes[0]; - return addi_auto_attach(dev, context); + ret = addi_auto_attach(dev, context); + if (ret) + return ret; + + apci1500_reset(dev); + + return 0; } static void apci1500_detach(struct comedi_device *dev) { if (dev->iobase) - i_ADDI_Reset(dev); + apci1500_reset(dev); comedi_pci_detach(dev); } -- GitLab From 3c3dcdd7eb6c4353620392c27965cf14a4231c62 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:19 -0700 Subject: [PATCH 1751/9457] staging: comedi: addi_common.c: remove addi_auto_attach() The addi_apci_035 and addi_apci_1500 are the only drivers left that use this function in addi_common.c. The addi_common code adds a lot of bloat to the drivers. Copy the addi_auto_attach() code to the (*auto_attach) functions of the drivers and remove the function. This will help with removing the bloat. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.c | 192 ------------------ .../staging/comedi/drivers/addi_apci_035.c | 180 +++++++++++++++- .../staging/comedi/drivers/addi_apci_1500.c | 180 +++++++++++++++- 3 files changed, 358 insertions(+), 194 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index d0bd8127d52c..850bdae48243 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -64,195 +64,3 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) this_board->interrupt(irq, d); return IRQ_RETVAL(1); } - -static int addi_auto_attach(struct comedi_device *dev, - unsigned long context_unused) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv; - struct comedi_subdevice *s; - int ret, n_subdevices; - unsigned int dw_Dummy; - - dev->board_name = this_board->pc_DriverName; - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - ret = comedi_pci_enable(dev); - if (ret) - return ret; - - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - - if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret == 0) - dev->irq = pcidev->irq; - } - - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - else - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) - return ret; - - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) - s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - - /* EEPROM */ - s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index dd28adb00e3d..4f068c2e6a70 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -39,14 +39,192 @@ static const struct addi_board apci035_boardtypes[] = { static int apci035_auto_attach(struct comedi_device *dev, unsigned long context) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board = dev->board_ptr; + struct addi_private *devpriv; + struct comedi_subdevice *s; + unsigned int dw_Dummy; int ret; dev->board_ptr = &apci035_boardtypes[0]; + dev->board_name = this_board->pc_DriverName; - ret = addi_auto_attach(dev, context); + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + + ret = comedi_pci_enable(dev); if (ret) return ret; + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + else + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + ret = comedi_alloc_subdevices(dev, 7); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) + s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; + else + s->n_chan = this_board->i_NbrAiChannelDiff; + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + s->type = COMEDI_SUBD_UNUSED; + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + apci035_reset(dev); return 0; diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index d4b42618859e..a4a0dab85d6a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -38,14 +38,192 @@ static const struct addi_board apci1500_boardtypes[] = { static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board = dev->board_ptr; + struct addi_private *devpriv; + struct comedi_subdevice *s; + unsigned int dw_Dummy; int ret; dev->board_ptr = &apci1500_boardtypes[0]; + dev->board_name = this_board->pc_DriverName; - ret = addi_auto_attach(dev, context); + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + + ret = comedi_pci_enable(dev); if (ret) return ret; + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + else + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + ret = comedi_alloc_subdevices(dev, 7); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) + s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; + else + s->n_chan = this_board->i_NbrAiChannelDiff; + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + s->type = COMEDI_SUBD_UNUSED; + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + apci1500_reset(dev); return 0; -- GitLab From 6c76d4e778a05c86f463a5bee3e2b06a9cc4396a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:20 -0700 Subject: [PATCH 1752/9457] staging: comedi: addi_common.c: remove v_ADDI_Interrupt() The addi_apci_035 and addi_apci_1500 are the only drivers left that use this function in addi_common.c. The function simply calls the 'interrupt' function that is in the boardinfo of the driver. Both drivers use the same 'interrupt' function for all boardnfo entries. Remove the i_ADDI_Reset() function as well as the 'interrupt' boardinfo and use the 'interrupt' function directly when doing the request_irq(). In addition, the addi_apci_3120 driver has a private v_ADDI_Interrupt() function that is doing the same thing. Remove that one as well. Fix the return type of 'interrupt' functions in the drivers and add the return vaules. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 9 --------- .../comedi/drivers/addi-data/hwdrv_apci035.c | 4 +++- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 4 +++- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 6 ++++-- drivers/staging/comedi/drivers/addi_apci_035.c | 3 +-- drivers/staging/comedi/drivers/addi_apci_1500.c | 3 +-- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 +------------ 7 files changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 850bdae48243..014342748765 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -55,12 +55,3 @@ static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, return insn->n; } - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - const struct addi_board *this_board = dev->board_ptr; - - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 53bb51bd77b5..a07ee1bd3311 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -434,7 +434,7 @@ static int apci035_reset(struct comedi_device *dev) return 0; } -static void apci035_interrupt(int irq, void *d) +static irqreturn_t apci035_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; @@ -477,4 +477,6 @@ static void apci035_interrupt(int irq, void *d) /* send signal to the sample */ send_sig(SIGIO, devpriv->tsk_Current, 0); } + + return IRQ_HANDLED; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 0ea081e1e119..9896468d86f9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -2011,7 +2011,7 @@ static int apci1500_do_bits(struct comedi_device *dev, return insn->n; } -static void apci1500_interrupt(int irq, void *d) +static irqreturn_t apci1500_interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -2180,6 +2180,8 @@ static void apci1500_interrupt(int irq, void *d) "Interrupt from unknown source\n"); } + + return IRQ_HANDLED; } static int apci1500_reset(struct comedi_device *dev) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b06142b27df7..ed1d92ecc9ea 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1415,7 +1415,7 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) return 0; } -static void apci3120_interrupt(int irq, void *d) +static irqreturn_t apci3120_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; @@ -1432,7 +1432,7 @@ static void apci3120_interrupt(int irq, void *d) if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) { dev_err(dev->class_dev, "IRQ from unknown source\n"); - return; + return IRQ_NONE; } outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* shutdown IRQ reasons in AMCC */ @@ -1587,6 +1587,8 @@ static void apci3120_interrupt(int irq, void *d) } comedi_handle_events(dev, s); + + return IRQ_HANDLED; } /* diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 4f068c2e6a70..a712cc522006 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -27,7 +27,6 @@ static const struct addi_board apci035_boardtypes[] = { .i_Timer = 1, .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, - .interrupt = apci035_interrupt, .ai_config = apci035_ai_config, .ai_read = apci035_ai_read, .timer_config = apci035_timer_config, @@ -84,7 +83,7 @@ static int apci035_auto_attach(struct comedi_device *dev, /* ## */ if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + ret = request_irq(pcidev->irq, apci035_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index a4a0dab85d6a..857ac9876467 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -20,7 +20,6 @@ static const struct addi_board apci1500_boardtypes[] = { .i_NbrDoChannel = 16, .i_DoMaxdata = 0xffff, .i_Timer = 1, - .interrupt = apci1500_interrupt, .di_config = apci1500_di_config, .di_read = apci1500_di_read, .di_write = apci1500_di_write, @@ -83,7 +82,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* ## */ if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ba71e24a56fd..38da44bd4eef 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -26,7 +26,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .interrupt = apci3120_interrupt, }, [BOARD_APCI3001] = { .pc_DriverName = "apci3001", @@ -37,19 +36,9 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .interrupt = apci3120_interrupt, }, }; -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - const struct addi_board *this_board = dev->board_ptr; - - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} - static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -82,7 +71,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; -- GitLab From f6a154c5c737013865f50c61367d30381a8584f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:21 -0700 Subject: [PATCH 1753/9457] staging: comedi: addi_common.c: remove included source file The addi_apci_035 and addi_apci_1500 are the only drivers left that include this source file. Copy the i_ADDIDATA_InsnReadEeprom() function from that file to those drivers and remove the addi_common.c file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.c | 57 ------------------- .../staging/comedi/drivers/addi_apci_035.c | 18 +++++- .../staging/comedi/drivers/addi_apci_1500.c | 18 +++++- 3 files changed, 34 insertions(+), 59 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/addi_common.c diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c deleted file mode 100644 index 014342748765..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ /dev/null @@ -1,57 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : ADDI DATA | Compiler : GCC | - | Modulname : addi_common.c | Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Author : | Date : | - +-----------------------------------------------------------------------+ - | Description : ADDI COMMON Main Module | - +-----------------------------------------------------------------------+ -*/ - -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index a712cc522006..fd7d3f1d7205 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -11,7 +11,6 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci035.c" -#include "addi-data/addi_common.c" static const struct addi_board apci035_boardtypes[] = { { @@ -35,6 +34,23 @@ static const struct addi_board apci035_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = dev->board_ptr; + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + static int apci035_auto_attach(struct comedi_device *dev, unsigned long context) { diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 857ac9876467..a68840e721a6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -9,7 +9,6 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" -#include "addi-data/addi_common.c" static const struct addi_board apci1500_boardtypes[] = { { @@ -34,6 +33,23 @@ static const struct addi_board apci1500_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = dev->board_ptr; + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { -- GitLab From 422b5353d013d7f9ebb2a6cfa9d3886776e68ea5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:22 -0700 Subject: [PATCH 1754/9457] staging: comedi: addi_apci_035: remove subdevice callbacks from boardinfo This driver only has one boardinfo entry so the subdevice callbacks are always the same. Remvoe the callbacks from the boardinfo and use them directly when initializing the subdevices. Remove all the subdevice callback initialization that would be set to NULL. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_035.c | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index fd7d3f1d7205..c9cd68cc6101 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -26,11 +26,6 @@ static const struct addi_board apci035_boardtypes[] = { .i_Timer = 1, .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, - .ai_config = apci035_ai_config, - .ai_read = apci035_ai_read, - .timer_config = apci035_timer_config, - .timer_write = apci035_timer_write, - .timer_read = apci035_timer_read, }, }; @@ -142,15 +137,8 @@ static int apci035_auto_attach(struct comedi_device *dev, s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; s->range_table = this_board->pr_AiRangelist; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - + s->insn_config = apci035_ai_config; + s->insn_read = apci035_ai_read; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -164,7 +152,6 @@ static int apci035_auto_attach(struct comedi_device *dev, s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel; - s->insn_write = this_board->ao_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -178,10 +165,6 @@ static int apci035_auto_attach(struct comedi_device *dev, s->len_chanlist = devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -196,12 +179,6 @@ static int apci035_auto_attach(struct comedi_device *dev, s->len_chanlist = devpriv->s_EeParameters.i_NbrDoChannel; s->range_table = &range_digital; - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -215,11 +192,9 @@ static int apci035_auto_attach(struct comedi_device *dev, s->maxdata = 0; s->len_chanlist = 1; s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; + s->insn_write = apci035_timer_write; + s->insn_read = apci035_timer_read; + s->insn_config = apci035_timer_config; } else { s->type = COMEDI_SUBD_UNUSED; } -- GitLab From 4cab75b5557490d7beefc60c79947a9b4d82a8ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:23 -0700 Subject: [PATCH 1755/9457] staging: comedi: addi_apci_1500: remove subdevice callbacks from boardinfo This driver only has one boardinfo entry so the subdevice callbacks are always the same. Remvoe the callbacks from the boardinfo and use them directly when initializing the subdevices. Remove all the subdevice callback initialization that would be set to NULL. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1500.c | 47 +++++-------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index a68840e721a6..d6d2e67c5ba7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -19,17 +19,6 @@ static const struct addi_board apci1500_boardtypes[] = { .i_NbrDoChannel = 16, .i_DoMaxdata = 0xffff, .i_Timer = 1, - .di_config = apci1500_di_config, - .di_read = apci1500_di_read, - .di_write = apci1500_di_write, - .di_bits = apci1500_di_insn_bits, - .do_config = apci1500_do_config, - .do_write = apci1500_do_write, - .do_bits = apci1500_do_bits, - .timer_config = apci1500_timer_config, - .timer_write = apci1500_timer_write, - .timer_read = apci1500_timer_read, - .timer_bits = apci1500_timer_bits, }, }; @@ -141,15 +130,6 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; s->range_table = this_board->pr_AiRangelist; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - } else { s->type = COMEDI_SUBD_UNUSED; } @@ -163,7 +143,6 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel; - s->insn_write = this_board->ao_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -177,10 +156,10 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->len_chanlist = devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; + s->insn_config = apci1500_di_config; + s->insn_read = apci1500_di_read; + s->insn_write = apci1500_di_write; + s->insn_bits = apci1500_di_insn_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -195,12 +174,9 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->len_chanlist = devpriv->s_EeParameters.i_NbrDoChannel; s->range_table = &range_digital; - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; + s->insn_config = apci1500_do_config; + s->insn_write = apci1500_do_write; + s->insn_bits = apci1500_do_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -214,11 +190,10 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->maxdata = 0; s->len_chanlist = 1; s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; + s->insn_write = apci1500_timer_write; + s->insn_read = apci1500_timer_read; + s->insn_config = apci1500_timer_config; + s->insn_bits = apci1500_timer_bits; } else { s->type = COMEDI_SUBD_UNUSED; } -- GitLab From 1881c0f3b9b67bc9a836f19f5b3a2d521174ce66 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:24 -0700 Subject: [PATCH 1756/9457] staging: comedi: addi_common.h: remove subdevice callbacks from struct addi_board None of the drivers that still include this header use the subdevice callbacks. Remove all of them to reduce the bloat. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.h | 54 ------------------- 1 file changed, 54 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index e2a3ffeee5cf..b757f460740a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -38,60 +38,6 @@ struct addi_board { int i_Timer; /* timer subdevice present or not */ unsigned int ui_MinAcquisitiontimeNs; /* Minimum Acquisition in Nano secs */ unsigned int ui_MinDelaytimeNs; /* Minimum Delay in Nano secs */ - - /* interrupt and reset */ - void (*interrupt)(int irq, void *d); - int (*reset)(struct comedi_device *); - - /* Subdevice functions */ - - /* ANALOG INPUT */ - int (*ai_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*ai_cmdtest)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_cmd *); - int (*ai_cmd)(struct comedi_device *, struct comedi_subdevice *); - int (*ai_cancel)(struct comedi_device *, struct comedi_subdevice *); - - /* Analog Output */ - int (*ao_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* Digital Input */ - int (*di_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*di_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* Digital Output */ - int (*do_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*do_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - /* TIMER */ - int (*timer_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*timer_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); }; struct addi_private { -- GitLab From 8d3e0bf092309808f715fd703bed2719eb77b982 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:25 -0700 Subject: [PATCH 1757/9457] staging: comedi: addi_apci_035: remove unnecessary subdevice initialization The subdevices that don't initialize any of the callbacks don't really exist. Remove the unnecessary initialzation and just set the type to COMEDI_SUBD_UNUSED. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_035.c | 38 +++---------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index c9cd68cc6101..f2cc95aaa8a2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -145,43 +145,15 @@ static int apci035_auto_attach(struct comedi_device *dev, /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; + /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; + /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- GitLab From a6b5d2a272f7cecec3f01f0049bd26ccb61a6d23 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:26 -0700 Subject: [PATCH 1758/9457] staging: comedi: addi_apci_035: remove unused subdevices Only allocate space for the subdevicess used by the driver. Remove all the COMEDI_SUBD_UNUSED subdevices. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_035.c | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index f2cc95aaa8a2..3eeb244ef855 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -117,7 +117,7 @@ static int apci035_auto_attach(struct comedi_device *dev, addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } - ret = comedi_alloc_subdevices(dev, 7); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -143,20 +143,8 @@ static int apci035_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_UNUSED; - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; + s = &dev->subdevices[1]; if (devpriv->s_EeParameters.i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -171,12 +159,8 @@ static int apci035_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - /* EEPROM */ - s = &dev->subdevices[6]; + s = &dev->subdevices[2]; if (this_board->i_PCIEeprom) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; -- GitLab From 35ce3c3cc1b8b1fc108abd5f482326213fb68c0b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:27 -0700 Subject: [PATCH 1759/9457] staging: comedi: addi_apci_1500: remove unnecessary subdevice initialization The subdevices that don't initialize any of the callbacks don't really exist. Remove the unnecessary initialzation and just set the type to COMEDI_SUBD_UNUSED. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1500.c | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index d6d2e67c5ba7..13b31aba2378 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -116,36 +116,12 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) - s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - } else { s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_NbrDiChannel) { -- GitLab From dd2762023e2dccc1b095032c65314035974b74f6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:28 -0700 Subject: [PATCH 1760/9457] staging: comedi: addi_apci_1500: remove unused subdevices Only allocate space for the subdevicess used by the driver. Remove all the COMEDI_SUBD_UNUSED subdevices. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1500.c | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 13b31aba2378..7da0c35d12b1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -110,20 +110,12 @@ static int apci1500_auto_attach(struct comedi_device *dev, addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } - ret = comedi_alloc_subdevices(dev, 7); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_UNUSED; - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; + s = &dev->subdevices[0]; if (devpriv->s_EeParameters.i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -140,7 +132,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; + s = &dev->subdevices[1]; if (devpriv->s_EeParameters.i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = @@ -158,7 +150,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, } /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; + s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -174,12 +166,8 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - /* EEPROM */ - s = &dev->subdevices[6]; + s = &dev->subdevices[3]; if (this_board->i_PCIEeprom) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; -- GitLab From 23abae881b69b903b07b34a0bece086811d77271 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:29 -0700 Subject: [PATCH 1761/9457] staging: comedi: addi_common.h: rename boardinfo 'pc_DriverName' Rename this CamelCase member of the boardinfo. The comedi_device 'board_name' is set to this member during the (*auto_attach) of the addi-data that still use this boardinfo drivers. For aesthetics, use the dev->board_name instead of the boardinfo in the drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.h | 2 +- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 2 +- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 12 ++++-------- drivers/staging/comedi/drivers/addi_apci_035.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1500.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3120.c | 6 +++--- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index b757f460740a..9def296568ff 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -19,7 +19,7 @@ #include struct addi_board { - const char *pc_DriverName; /* driver name */ + const char *name; int i_IorangeBase1; int i_PCIEeprom; /* eeprom present or not */ char *pc_EepromChip; /* type of chip */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index b731856c27da..4e3d5ed70990 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -287,7 +287,7 @@ static void addi_eeprom_read_ai_info(struct comedi_device *dev, /* No of channels for 1st hard component */ tmp = addi_eeprom_readw(iobase, type, addr + 10); devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff; - if (!strcmp(this_board->pc_DriverName, "apci3200")) + if (!strcmp(dev->board_name, "apci3200")) devpriv->s_EeParameters.i_NbrAiChannel *= 4; tmp = addi_eeprom_readw(iobase, type, addr + 16); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index ed1d92ecc9ea..d76435668d9a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -351,7 +351,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv = dev->private; unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; @@ -382,7 +381,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { + || !strcmp(dev->board_name, "apci3001")) { us_ConvertTiming = (us_ConvertTiming * 2) - 2; } else { us_ConvertTiming = @@ -781,7 +780,6 @@ static int apci3120_cyclic_ai(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned char b_Tmp; @@ -838,7 +836,7 @@ static int apci3120_cyclic_ai(int mode, /* EL241003 Begin: add this section to replace floats calculation by integer calculations */ /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { + || !strcmp(dev->board_name, "apci3001")) { ui_TimerValue0 = ui_ConvertTiming * 2 - 2000; ui_TimerValue0 = ui_TimerValue0 / 1000; @@ -1604,7 +1602,6 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2; unsigned short us_TmpValue; @@ -1624,7 +1621,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, * is an APCI3001 and calculate the time value to set in the timer */ if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { + || !strcmp(dev->board_name, "apci3001")) { /* Calculate the time value to set in the timer */ ui_Timervalue2 = ui_Timervalue2 / 50; } else { @@ -1742,7 +1739,6 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2 = 0; unsigned short us_TmpValue; @@ -1862,7 +1858,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, * is an APCI3001 and calculate the time value to set in the timer */ if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(this_board->pc_DriverName, "apci3001")) { + || !strcmp(dev->board_name, "apci3001")) { /* Calculate the time value to set in the timer */ ui_Timervalue2 = ui_Timervalue2 / 50; } else { diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 3eeb244ef855..a5e3d325165a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -14,7 +14,7 @@ static const struct addi_board apci035_boardtypes[] = { { - .pc_DriverName = "apci035", + .name = "apci035", .i_IorangeBase1 = APCI035_ADDRESS_RANGE, .i_PCIEeprom = 1, .pc_EepromChip = "S5920", @@ -57,7 +57,7 @@ static int apci035_auto_attach(struct comedi_device *dev, int ret; dev->board_ptr = &apci035_boardtypes[0]; - dev->board_name = this_board->pc_DriverName; + dev->board_name = this_board->name; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 7da0c35d12b1..03e65a106816 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -12,7 +12,7 @@ static const struct addi_board apci1500_boardtypes[] = { { - .pc_DriverName = "apci1500", + .name = "apci1500", .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, .i_PCIEeprom = 0, .i_NbrDiChannel = 16, @@ -50,7 +50,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, int ret; dev->board_ptr = &apci1500_boardtypes[0]; - dev->board_name = this_board->pc_DriverName; + dev->board_name = this_board->name; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 38da44bd4eef..1fa53cf629fc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,7 +16,7 @@ enum apci3120_boardid { static const struct addi_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { - .pc_DriverName = "apci3120", + .name = "apci3120", .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -28,7 +28,7 @@ static const struct addi_board apci3120_boardtypes[] = { .i_DoMaxdata = 0x0f, }, [BOARD_APCI3001] = { - .pc_DriverName = "apci3001", + .name = "apci3001", .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -53,7 +53,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, if (!this_board) return -ENODEV; dev->board_ptr = this_board; - dev->board_name = this_board->pc_DriverName; + dev->board_name = this_board->name; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) -- GitLab From d75a78435c7d0ca945de0ba17e5814a0875700c5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:30 -0700 Subject: [PATCH 1762/9457] staging: comedi: addi_common.h: remove boardinfo 'i_IorangeBase1' This member of the boardinfo is used as a flag to determine what PCI BAR to use for the main 'iobase' used by the driver. Remove the boardinfo member and refactor the (*auto_attach) of the drivers to use the correct PCI BAR. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.h | 1 - drivers/staging/comedi/drivers/addi_apci_035.c | 7 +------ drivers/staging/comedi/drivers/addi_apci_1500.c | 7 +------ 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 9def296568ff..0752a61a7c2a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -20,7 +20,6 @@ struct addi_board { const char *name; - int i_IorangeBase1; int i_PCIEeprom; /* eeprom present or not */ char *pc_EepromChip; /* type of chip */ int i_NbrAiChannel; /* num of A/D chans */ diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index a5e3d325165a..a197f64e63c1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -15,7 +15,6 @@ static const struct addi_board apci035_boardtypes[] = { { .name = "apci035", - .i_IorangeBase1 = APCI035_ADDRESS_RANGE, .i_PCIEeprom = 1, .pc_EepromChip = "S5920", .i_NbrAiChannel = 16, @@ -67,11 +66,7 @@ static int apci035_auto_attach(struct comedi_device *dev, if (ret) return ret; - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - + dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 03e65a106816..c69510bcf931 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -13,7 +13,6 @@ static const struct addi_board apci1500_boardtypes[] = { { .name = "apci1500", - .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, .i_PCIEeprom = 0, .i_NbrDiChannel = 16, .i_NbrDoChannel = 16, @@ -60,11 +59,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, if (ret) return ret; - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - + dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); -- GitLab From 73901b52156775361f222b93663b680b190f1945 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:31 -0700 Subject: [PATCH 1763/9457] staging: comedi: addi_apci_1500: remove eeprom support As indicated in the boardinfo, the hardware does not have an eeprom. Remove the subdevice and support code for it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1500.c | 51 +------------------ 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index c69510bcf931..7c32c856f562 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -7,13 +7,11 @@ #include "addi-data/addi_common.h" -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" static const struct addi_board apci1500_boardtypes[] = { { .name = "apci1500", - .i_PCIEeprom = 0, .i_NbrDiChannel = 16, .i_NbrDoChannel = 16, .i_DoMaxdata = 0xffff, @@ -21,23 +19,6 @@ static const struct addi_board apci1500_boardtypes[] = { }, }; -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -45,7 +26,6 @@ static int apci1500_auto_attach(struct comedi_device *dev, const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv; struct comedi_subdevice *s; - unsigned int dw_Dummy; int ret; dev->board_ptr = &apci1500_boardtypes[0]; @@ -88,24 +68,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - else - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - - ret = comedi_alloc_subdevices(dev, 4); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -161,18 +124,6 @@ static int apci1500_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* EEPROM */ - s = &dev->subdevices[3]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - apci1500_reset(dev); return 0; -- GitLab From b6cc74814f86e3057eba4440d5843433e238ef49 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:32 -0700 Subject: [PATCH 1764/9457] staging: comedi: addi_apci_035: board has eeprom As indicated in the boardinfo, the hardware has an eeprom. Simplify the board attach code and remove the boardinfo. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_035.c | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index a197f64e63c1..ed4ed17888a1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -15,7 +15,6 @@ static const struct addi_board apci035_boardtypes[] = { { .name = "apci035", - .i_PCIEeprom = 1, .pc_EepromChip = "S5920", .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, @@ -95,22 +94,15 @@ static int apci035_auto_attach(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ + /* Set 3 wait stait */ + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - else - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + + /* Read eepeom and fill addi_board Structure */ + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -156,15 +148,11 @@ static int apci035_auto_attach(struct comedi_device *dev, /* EEPROM */ s = &dev->subdevices[2]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; apci035_reset(dev); -- GitLab From e10e23db5478d3159cabe8f6af8dcfef2f627aa0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:33 -0700 Subject: [PATCH 1765/9457] staging: comedi: addi_common.h: remove boardinfo member 'i_PCIEeprom' This member of the boardinfo is not used by any of the drivers. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 0752a61a7c2a..5518332d677a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -20,7 +20,6 @@ struct addi_board { const char *name; - int i_PCIEeprom; /* eeprom present or not */ char *pc_EepromChip; /* type of chip */ int i_NbrAiChannel; /* num of A/D chans */ int i_NbrAiChannelDiff; /* num of A/D chans in diff mode */ -- GitLab From bb599f39fa8fbffbe43d7c1937333544e0cdbf16 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:34 -0700 Subject: [PATCH 1766/9457] staging: comedi: addi_apci_1500: remove boardinfo The hardware does not have an eeprom so the 's_EeParameters' use is not necessary. Remove it. Since the boardinfo only has one entry its not really necessary. Remove it and initialize the subdevices directly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_1500.c | 103 +++++------------- 1 file changed, 29 insertions(+), 74 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 7c32c856f562..dc90a8f5388f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -9,28 +9,14 @@ #include "addi-data/hwdrv_apci1500.c" -static const struct addi_board apci1500_boardtypes[] = { - { - .name = "apci1500", - .i_NbrDiChannel = 16, - .i_NbrDoChannel = 16, - .i_DoMaxdata = 0xffff, - .i_Timer = 1, - }, -}; - static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv; struct comedi_subdevice *s; int ret; - dev->board_ptr = &apci1500_boardtypes[0]; - dev->board_name = this_board->name; - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; @@ -45,22 +31,6 @@ static int apci1500_auto_attach(struct comedi_device *dev, devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, dev->board_name, dev); @@ -74,55 +44,40 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->insn_config = apci1500_di_config; - s->insn_read = apci1500_di_read; - s->insn_write = apci1500_di_write; - s->insn_bits = apci1500_di_insn_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = apci1500_di_config; + s->insn_read = apci1500_di_read; + s->insn_write = apci1500_di_write; + s->insn_bits = apci1500_di_insn_bits; + /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - s->insn_config = apci1500_do_config; - s->insn_write = apci1500_do_write; - s->insn_bits = apci1500_do_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = apci1500_do_config; + s->insn_write = apci1500_do_write; + s->insn_bits = apci1500_do_bits; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - s->insn_write = apci1500_timer_write; - s->insn_read = apci1500_timer_read; - s->insn_config = apci1500_timer_config; - s->insn_bits = apci1500_timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + s->insn_write = apci1500_timer_write; + s->insn_read = apci1500_timer_read; + s->insn_config = apci1500_timer_config; + s->insn_bits = apci1500_timer_bits; apci1500_reset(dev); -- GitLab From 715ce8aac445efd2e9319bccb0919cb30856a26a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:35 -0700 Subject: [PATCH 1767/9457] staging: comedi: addi_apci_035: remove boardinfo The hardware has an eeprom but the boardinfo properly defines the subdevice support so reading the eeprom and setting the 's_EeParameters' use is not necessary. Since the boardinfo only has one entry its not really necessary. Also, providing a subdevice the read the eeprom is not really interesting. Remove the eeprom support code along with the boardinfo and initialize the subdevices directly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_035.c | 116 +++--------------- 1 file changed, 19 insertions(+), 97 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index ed4ed17888a1..37b58845231b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -9,54 +9,17 @@ #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci035.c" -static const struct addi_board apci035_boardtypes[] = { - { - .name = "apci035", - .pc_EepromChip = "S5920", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xff, - .pr_AiRangelist = &range_apci035_ai, - .i_Timer = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - }, -}; - -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static int apci035_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv; struct comedi_subdevice *s; unsigned int dw_Dummy; int ret; - dev->board_ptr = &apci035_boardtypes[0]; - dev->board_name = this_board->name; - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; @@ -71,22 +34,6 @@ static int apci035_auto_attach(struct comedi_device *dev, devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci035_interrupt, IRQF_SHARED, dev->board_name, dev); @@ -101,58 +48,33 @@ static int apci035_auto_attach(struct comedi_device *dev, dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - /* Read eepeom and fill addi_board Structure */ - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - - ret = comedi_alloc_subdevices(dev, 3); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) - s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - s->insn_config = apci035_ai_config; - s->insn_read = apci035_ai_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; + s->n_chan = 16; + s->maxdata = 0xff; + s->len_chanlist = s->n_chan; + s->range_table = &range_apci035_ai; + s->insn_config = apci035_ai_config; + s->insn_read = apci035_ai_read; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - s->insn_write = apci035_timer_write; - s->insn_read = apci035_timer_read; - s->insn_config = apci035_timer_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* EEPROM */ - s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + s->insn_write = apci035_timer_write; + s->insn_read = apci035_timer_read; + s->insn_config = apci035_timer_config; apci035_reset(dev); -- GitLab From 3b00a0e0d6611935bbed56fd2b298fb10cfb3f7b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:36 -0700 Subject: [PATCH 1768/9457] staging: comedi: addi_eeprom: remove source file This source file is no longer included by any of the addi-data drivers. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_eeprom.c | 360 ------------------ 1 file changed, 360 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/addi_eeprom.c diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c deleted file mode 100644 index 4e3d5ed70990..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * addi_eeprom.c - ADDI EEPROM Module - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * Project manager: Eric Stolz - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include - -#define NVRAM_USER_DATA_START 0x100 - -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ - -#define EE93C76_CLK_BIT (1 << 0) -#define EE93C76_CS_BIT (1 << 1) -#define EE93C76_DOUT_BIT (1 << 2) -#define EE93C76_DIN_BIT (1 << 3) -#define EE93C76_READ_CMD (0x0180 << 4) -#define EE93C76_CMD_LEN 13 - -#define EEPROM_DIGITALINPUT 0 -#define EEPROM_DIGITALOUTPUT 1 -#define EEPROM_ANALOGINPUT 2 -#define EEPROM_ANALOGOUTPUT 3 -#define EEPROM_TIMER 4 -#define EEPROM_WATCHDOG 5 -#define EEPROM_TIMER_WATCHDOG_COUNTER 10 - -static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) -{ - outl(val & ~EE93C76_CLK_BIT, iobase); - udelay(100); - - outl(val | EE93C76_CLK_BIT, iobase); - udelay(100); -} - -static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase, - unsigned int cmd, - unsigned char len) -{ - unsigned int val = EE93C76_CS_BIT; - int i; - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(val, iobase); - udelay(100); - - /* Send EEPROM command - one bit at a time */ - for (i = (len - 1); i >= 0; i--) { - if (cmd & (1 << i)) - val |= EE93C76_DOUT_BIT; - else - val &= ~EE93C76_DOUT_BIT; - - /* Write the command */ - outl(val, iobase); - udelay(100); - - addi_eeprom_clk_93c76(iobase, val); - } - return val; -} - -static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, - unsigned short addr) -{ - unsigned short val = 0; - unsigned int cmd; - unsigned int tmp; - int i; - - /* Send EEPROM read command and offset to EEPROM */ - cmd = EE93C76_READ_CMD | (addr / 2); - cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN); - - /* Get the 16-bit value */ - for (i = 0; i < 16; i++) { - addi_eeprom_clk_93c76(iobase, cmd); - - tmp = inl(iobase); - udelay(100); - - val <<= 1; - if (tmp & EE93C76_DIN_BIT) - val |= 0x1; - } - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(0, iobase); - udelay(100); - - return val; -} - -static void addi_eeprom_nvram_wait(unsigned long iobase) -{ - unsigned char val; - - do { - val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD); - } while (val & 0x80); -} - -static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, - unsigned short addr) -{ - unsigned short val = 0; - unsigned char tmp; - unsigned char i; - - for (i = 0; i < 2; i++) { - /* Load the low 8 bit address */ - outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - /* Load the high 8 bit address */ - outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - outb(((addr + i) >> 8) & 0xff, - iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - /* Read the eeprom data byte */ - outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); - addi_eeprom_nvram_wait(iobase); - tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); - addi_eeprom_nvram_wait(iobase); - - if (i == 0) - val |= tmp; - else - val |= (tmp << 8); - } - - return val; -} - -static unsigned short addi_eeprom_readw(unsigned long iobase, - char *type, - unsigned short addr) -{ - unsigned short val = 0; - - /* Add the offset to the start of the user data */ - addr += NVRAM_USER_DATA_START; - - if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) - val = addi_eeprom_readw_nvram(iobase, addr); - - if (!strcmp(type, "93C76")) - val = addi_eeprom_readw_93c76(iobase, addr); - - return val; -} - -static void addi_eeprom_read_di_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* Number of channels */ - tmp = addi_eeprom_readw(iobase, type, addr + 6); - devpriv->s_EeParameters.i_NbrDiChannel = tmp; - - /* Interruptible or not */ - tmp = addi_eeprom_readw(iobase, type, addr + 8); - tmp = (tmp >> 7) & 0x01; - - /* How many interruptible logic */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); -} - -static void addi_eeprom_read_do_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* Number of channels */ - tmp = addi_eeprom_readw(iobase, type, addr + 6); - devpriv->s_EeParameters.i_NbrDoChannel = tmp; - - devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp); -} - -static void addi_eeprom_read_timer_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - struct addi_private *devpriv = dev->private; -#if 0 - const struct addi_board *this_board = dev->board_ptr; - char *type = this_board->pc_EepromChip; - unsigned short offset = 0; - unsigned short ntimers; - unsigned short tmp; - int i; - - /* Number of Timers */ - ntimers = addi_eeprom_readw(iobase, type, addr + 6); - - /* Read header size */ - for (i = 0; i < ntimers; i++) { - unsigned short size; - unsigned short res; - unsigned short mode; - unsigned short min_timing; - unsigned short timebase; - - size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0); - - /* Resolution / Mode */ - tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2); - res = (tmp >> 10) & 0x3f; - mode = (tmp >> 4) & 0x3f; - - /* MinTiming / Timebase */ - tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4); - min_timing = (tmp >> 6) & 0x3ff; - Timebase = tmp & 0x3f; - - offset += size; - } -#endif - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; -} - -static void addi_eeprom_read_ao_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short tmp; - - /* No of channels for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); - devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff; - - /* Resolution for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 16); - tmp = (tmp >> 8) & 0xff; - devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp); -} - -static void addi_eeprom_read_ai_info(struct comedi_device *dev, - unsigned long iobase, - unsigned short addr) -{ - const struct addi_board *this_board = dev->board_ptr; - struct addi_private *devpriv = dev->private; - char *type = this_board->pc_EepromChip; - unsigned short offset; - unsigned short tmp; - - /* No of channels for 1st hard component */ - tmp = addi_eeprom_readw(iobase, type, addr + 10); - devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff; - if (!strcmp(dev->board_name, "apci3200")) - devpriv->s_EeParameters.i_NbrAiChannel *= 4; - - tmp = addi_eeprom_readw(iobase, type, addr + 16); - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000; - - tmp = addi_eeprom_readw(iobase, type, addr + 30); - devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000; - - tmp = addi_eeprom_readw(iobase, type, addr + 20); - /* dma = (tmp >> 13) & 0x01; */ - - tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff; - if (tmp) { /* > 0 */ - /* offset of first analog input single header */ - offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16))); - } else { /* = 0 */ - offset = 74; - } - - /* Resolution */ - tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f; - devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp); -} - -static void addi_eeprom_read_info(struct comedi_device *dev, - unsigned long iobase) -{ - const struct addi_board *this_board = dev->board_ptr; - char *type = this_board->pc_EepromChip; - unsigned short size; - unsigned char nfuncs; - int i; - - size = addi_eeprom_readw(iobase, type, 8); - nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff; - - /* Read functionality details */ - for (i = 0; i < nfuncs; i++) { - unsigned short offset = i * 4; - unsigned short addr; - unsigned char func; - - func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f; - addr = addi_eeprom_readw(iobase, type, 14 + offset); - - switch (func) { - case EEPROM_DIGITALINPUT: - addi_eeprom_read_di_info(dev, iobase, addr); - break; - - case EEPROM_DIGITALOUTPUT: - addi_eeprom_read_do_info(dev, iobase, addr); - break; - - case EEPROM_ANALOGINPUT: - addi_eeprom_read_ai_info(dev, iobase, addr); - break; - - case EEPROM_ANALOGOUTPUT: - addi_eeprom_read_ao_info(dev, iobase, addr); - break; - - case EEPROM_TIMER: - case EEPROM_WATCHDOG: - case EEPROM_TIMER_WATCHDOG_COUNTER: - addi_eeprom_read_timer_info(dev, iobase, addr); - break; - } - } -} -- GitLab From 7fab573b61a7cc771a9f7537e54818b13dcb07cc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:37 -0700 Subject: [PATCH 1769/9457] staging: comedi: hwdrv_apci3120: remove need for boardinfo access The apci3120_ai_insn_config() function is broken in this driver. It does not follow the comedi API and will fail to work correctly. For now just remove the need for the boardinfo access to allow additional cleanup. The 'i_NbrAiChannel' is actually the subdevice 'n_chan' use that instead and remove the boardinfo access. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d76435668d9a..e120d620b3ce 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -246,7 +246,6 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv = dev->private; unsigned int i; @@ -261,8 +260,7 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, /* Test the number of the channel */ for (i = 0; i < data[3]; i++) { - if (CR_CHAN(data[4 + i]) >= - this_board->i_NbrAiChannel) { + if (CR_CHAN(data[4 + i]) >= s->n_chan) { dev_err(dev->class_dev, "bad channel list\n"); return -2; } -- GitLab From dbf502e4b8d7eb016321ac97489384f8ae404822 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:38 -0700 Subject: [PATCH 1770/9457] staging: comedi: addi_common.h: remove boardinfo definition The addi_board definition is not only used by the addi_apci_3120 driver. Introduce a private definition in that driver and remove the global definition from addi_common.h. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.h | 20 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 17 ++++++++++++++-- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 5518332d677a..28aec3f8352d 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -18,26 +18,6 @@ #include #include -struct addi_board { - const char *name; - char *pc_EepromChip; /* type of chip */ - int i_NbrAiChannel; /* num of A/D chans */ - int i_NbrAiChannelDiff; /* num of A/D chans in diff mode */ - int i_AiChannelList; /* len of chanlist */ - int i_NbrAoChannel; /* num of D/A chans */ - int i_AiMaxdata; /* resolution of A/D */ - int i_AoMaxdata; /* resolution of D/A */ - const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ - - int i_NbrDiChannel; /* Number of DI channels */ - int i_NbrDoChannel; /* Number of DO channels */ - int i_DoMaxdata; /* data to set all channels high */ - - int i_Timer; /* timer subdevice present or not */ - unsigned int ui_MinAcquisitiontimeNs; /* Minimum Acquisition in Nano secs */ - unsigned int ui_MinDelaytimeNs; /* Minimum Delay in Nano secs */ -}; - struct addi_private { int iobase; int i_IobaseAmcc; /* base+size for AMCC chip */ diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 1fa53cf629fc..ae81fdb2a97f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -14,7 +14,20 @@ enum apci3120_boardid { BOARD_APCI3001, }; -static const struct addi_board apci3120_boardtypes[] = { +struct apci3120_board { + const char *name; + int i_NbrAiChannel; + int i_NbrAiChannelDiff; + int i_AiChannelList; + int i_NbrAoChannel; + int i_AiMaxdata; + int i_AoMaxdata; + int i_NbrDiChannel; + int i_NbrDoChannel; + int i_DoMaxdata; +}; + +static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { .name = "apci3120", .i_NbrAiChannel = 16, @@ -43,7 +56,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board = NULL; + const struct apci3120_board *this_board = NULL; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, order, i; -- GitLab From 7067a347665feec4aa1f7ecdd892a24715f094a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:39 -0700 Subject: [PATCH 1771/9457] staging: comedi: addi_common.h: remove unused members from addi_private Remove all the unused members from the addi_private definition. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 28aec3f8352d..52f35b4c00dc 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -49,20 +49,4 @@ struct addi_private { /* Pointer to the current process */ struct task_struct *tsk_Current; - - /* Parameters read from EEPROM overriding static board info */ - struct { - int i_NbrAiChannel; /* num of A/D chans */ - int i_NbrAoChannel; /* num of D/A chans */ - int i_AiMaxdata; /* resolution of A/D */ - int i_AoMaxdata; /* resolution of D/A */ - int i_NbrDiChannel; /* Number of DI channels */ - int i_NbrDoChannel; /* Number of DO channels */ - int i_DoMaxdata; /* data to set all channels high */ - int i_Timer; /* timer subdevice present or not */ - unsigned int ui_MinAcquisitiontimeNs; - /* Minimum Acquisition in Nano secs */ - unsigned int ui_MinDelaytimeNs; - /* Minimum Delay in Nano secs */ - } s_EeParameters; }; -- GitLab From 73fc3c6c0516754c8b1ce5f8c0dcc54e0d37a9f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:40 -0700 Subject: [PATCH 1772/9457] staging: comedi: addi_apci_3120: remove boardinfo 'i_DoMaxdata' The maxdata for a Digital Output subdevice is always '1'. Remove this incorrect boardinfo. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ae81fdb2a97f..9f5d7a528945 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -24,7 +24,6 @@ struct apci3120_board { int i_AoMaxdata; int i_NbrDiChannel; int i_NbrDoChannel; - int i_DoMaxdata; }; static const struct apci3120_board apci3120_boardtypes[] = { @@ -38,7 +37,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_AoMaxdata = 0x3fff, .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, }, [BOARD_APCI3001] = { .name = "apci3001", @@ -48,7 +46,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_AiMaxdata = 0xfff, .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, }, }; @@ -166,7 +163,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->i_NbrDoChannel; - s->maxdata = this_board->i_DoMaxdata; + s->maxdata = 1; s->len_chanlist = this_board->i_NbrDoChannel; s->range_table = &range_digital; s->insn_bits = apci3120_do_insn_bits; -- GitLab From 4241d6b82ddf080ce82f062281b93eb68c291298 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:41 -0700 Subject: [PATCH 1773/9457] staging: comedi: addi_apci_3120: remove boardinfo 'i_NbrDoChannel' All boardinfo entries have this member set as '4'. Remove the member and initialize the Digial Output 'n_chan' with 4 directly. Also, remove the initialization of 'len_chanlist'. This member is only used with subdevices that support async commands. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9f5d7a528945..fd6f64ab7fc1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -23,7 +23,6 @@ struct apci3120_board { int i_AiMaxdata; int i_AoMaxdata; int i_NbrDiChannel; - int i_NbrDoChannel; }; static const struct apci3120_board apci3120_boardtypes[] = { @@ -36,7 +35,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_AiMaxdata = 0xffff, .i_AoMaxdata = 0x3fff, .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, }, [BOARD_APCI3001] = { .name = "apci3001", @@ -45,7 +43,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_AiChannelList = 16, .i_AiMaxdata = 0xfff, .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, }, }; @@ -162,9 +159,8 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDoChannel; + s->n_chan = 4; s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDoChannel; s->range_table = &range_digital; s->insn_bits = apci3120_do_insn_bits; -- GitLab From 171192d0d084ae432f9da25230e17d967ed7eeed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:42 -0700 Subject: [PATCH 1774/9457] staging: comedi: addi_apci_3120: remove boardinfo 'i_NbrDiChannel' All boardinfo entries have this member set as '4'. Remove the member and initialize the Digial Input 'n_chan' with 4 directly. Also, remove the initialization of 'len_chanlist'. This member is only used with subdevices that support async commands. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index fd6f64ab7fc1..18e0b1367ce4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -22,7 +22,6 @@ struct apci3120_board { int i_NbrAoChannel; int i_AiMaxdata; int i_AoMaxdata; - int i_NbrDiChannel; }; static const struct apci3120_board apci3120_boardtypes[] = { @@ -34,7 +33,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, .i_AoMaxdata = 0x3fff, - .i_NbrDiChannel = 4, }, [BOARD_APCI3001] = { .name = "apci3001", @@ -42,7 +40,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, .i_AiMaxdata = 0xfff, - .i_NbrDiChannel = 4, }, }; @@ -148,9 +145,8 @@ static int apci3120_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDiChannel; + s->n_chan = 4; s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDiChannel; s->range_table = &range_digital; s->insn_bits = apci3120_di_insn_bits; -- GitLab From 98ea9f854a2577b36e3a06d0824db5f51c514667 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:43 -0700 Subject: [PATCH 1775/9457] staging: comedi: addi_apci_3120: remove boardinfo 'i_NbrAiChannel' All boardinfo entries have this member set as '16'. This will initialize the Analog Input 'n_chan' and cause the 'i_NbrAiChannelDiff' member to never get used. Remove both members and initialize the Analog Input 'n_chan' with 16 directly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 18e0b1367ce4..32e5ad487a1c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,8 +16,6 @@ enum apci3120_boardid { struct apci3120_board { const char *name; - int i_NbrAiChannel; - int i_NbrAiChannelDiff; int i_AiChannelList; int i_NbrAoChannel; int i_AiMaxdata; @@ -27,8 +25,6 @@ struct apci3120_board { static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { .name = "apci3120", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, @@ -36,8 +32,6 @@ static const struct apci3120_board apci3120_boardtypes[] = { }, [BOARD_APCI3001] = { .name = "apci3001", - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, .i_AiMaxdata = 0xfff, }, @@ -113,10 +107,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - if (this_board->i_NbrAiChannel) - s->n_chan = this_board->i_NbrAiChannel; - else - s->n_chan = this_board->i_NbrAiChannelDiff; + s->n_chan = 16; s->maxdata = this_board->i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; s->range_table = &range_apci3120_ai; -- GitLab From 7fcf666b4a57b9317739f13a6a65d0dbecd47ca8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:44 -0700 Subject: [PATCH 1776/9457] staging: comedi: addi_apci_3120: remove boardinfo 'i_AiChannelList' All boardinfo entries have this member set as '16'. This is also the Analog Input 'n_chan'. For aesthetics, initialize the Analog Input 'len_chanlist' with s->n_chan and remove the boardinfo member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 32e5ad487a1c..d555427d3359 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,7 +16,6 @@ enum apci3120_boardid { struct apci3120_board { const char *name; - int i_AiChannelList; int i_NbrAoChannel; int i_AiMaxdata; int i_AoMaxdata; @@ -25,14 +24,12 @@ struct apci3120_board { static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { .name = "apci3120", - .i_AiChannelList = 16, .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, .i_AoMaxdata = 0x3fff, }, [BOARD_APCI3001] = { .name = "apci3001", - .i_AiChannelList = 16, .i_AiMaxdata = 0xfff, }, }; @@ -109,7 +106,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, | SDF_DIFF; s->n_chan = 16; s->maxdata = this_board->i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; + s->len_chanlist = s->n_chan; s->range_table = &range_apci3120_ai; s->insn_config = apci3120_ai_insn_config; -- GitLab From 2cd6b2b2a9ebca2d8ab9e74ac919a82e6eae45b3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:45 -0700 Subject: [PATCH 1777/9457] staging: comedi: addi_apci_3120: simplify analog output boardinfo There are two boards supported by this driver. One with eight 14-bit analog outputs and the other without analog outputs. Add a bit field flag, 'has_ao', to the boardinfo and remove the 'i_NbrAoChannel' and 'i_AoMaxdata' members. Use the new flag to determine if the analog output subdevice needs to be initialized and open code the n_chan and maxdata. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d555427d3359..de1dabf72bb3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,17 +16,15 @@ enum apci3120_boardid { struct apci3120_board { const char *name; - int i_NbrAoChannel; int i_AiMaxdata; - int i_AoMaxdata; + unsigned int has_ao:1; }; static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { .name = "apci3120", - .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, - .i_AoMaxdata = 0x3fff, + .has_ao = 1, }, [BOARD_APCI3001] = { .name = "apci3001", @@ -117,12 +115,11 @@ static int apci3120_auto_attach(struct comedi_device *dev, /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (this_board->i_NbrAoChannel) { + if (this_board->has_ao) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrAoChannel; - s->maxdata = this_board->i_AoMaxdata; - s->len_chanlist = this_board->i_NbrAoChannel; + s->n_chan = 8; + s->maxdata = 0x3fff; s->range_table = &range_apci3120_ao; s->insn_write = apci3120_ao_insn_write; } else { -- GitLab From 6a02623de52c574a68be09e03ce15abe378b85aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:46 -0700 Subject: [PATCH 1778/9457] staging: comedi: addi_apci_3120: simplify analog input boardinfo There are two boards supported by this driver. One with 16-bit analog inputs and the other 12-bit analog inputs. Add a bit field flag, 'ai_is_16bit', to the boardinfo and remove the 'i_AiMaxdata' member. Use the new flag to initialize tne analog input subdevice maxdata correctly. For aesthetics, adjust the whitespace in the boardinfo declaration. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index de1dabf72bb3..9ba66d8ab04f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,19 +16,18 @@ enum apci3120_boardid { struct apci3120_board { const char *name; - int i_AiMaxdata; + unsigned int ai_is_16bit:1; unsigned int has_ao:1; }; static const struct apci3120_board apci3120_boardtypes[] = { [BOARD_APCI3120] = { - .name = "apci3120", - .i_AiMaxdata = 0xffff, - .has_ao = 1, + .name = "apci3120", + .ai_is_16bit = 1, + .has_ao = 1, }, [BOARD_APCI3001] = { - .name = "apci3001", - .i_AiMaxdata = 0xfff, + .name = "apci3001", }, }; @@ -103,7 +102,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; s->n_chan = 16; - s->maxdata = this_board->i_AiMaxdata; + s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; s->len_chanlist = s->n_chan; s->range_table = &range_apci3120_ai; -- GitLab From 0317ffd281663c8f19567d8895866b23cb02e4fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:47 -0700 Subject: [PATCH 1779/9457] staging: comedi: addi_apci_035: separate from addi_common.h Remove the need to include addi_common.h by introducing a new private data definition. Only include the members that are actually used by the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci035.c | 14 +++++++------- drivers/staging/comedi/drivers/addi_apci_035.c | 13 +++++++++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index a07ee1bd3311..d833da2eeac6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -118,7 +118,7 @@ static int apci035_timer_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; unsigned int ui_Status; unsigned int ui_Command; unsigned int ui_Mode; @@ -248,7 +248,7 @@ static int apci035_timer_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; unsigned int ui_Command; int i_Count; @@ -345,7 +345,7 @@ static int apci035_timer_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; unsigned int ui_Status; /* Status register */ i_WatchdogNbr = insn->unused[0]; @@ -380,7 +380,7 @@ static int apci035_ai_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; devpriv->tsk_Current = current; outl(0x200 | 0, devpriv->iobase + 128 + 0x4); @@ -404,7 +404,7 @@ static int apci035_ai_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; unsigned int ui_CommandRegister; /* Set the start */ @@ -420,7 +420,7 @@ static int apci035_ai_read(struct comedi_device *dev, static int apci035_reset(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; int i_Count; for (i_Count = 1; i_Count <= 4; i_Count++) { @@ -437,7 +437,7 @@ static int apci035_reset(struct comedi_device *dev) static irqreturn_t apci035_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; + struct apci035_private *devpriv = dev->private; unsigned int ui_StatusRegister1; unsigned int ui_StatusRegister2; unsigned int ui_ReadCommand; diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 37b58845231b..d7b7e1aa8b33 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -1,11 +1,20 @@ #include #include +#include +#include #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" +struct apci035_private { + int iobase; + int i_IobaseAmcc; + int i_IobaseAddon; + int i_IobaseReserved; + unsigned char b_TimerSelectMode; + struct task_struct *tsk_Current; +}; #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ @@ -15,7 +24,7 @@ static int apci035_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct addi_private *devpriv; + struct apci035_private *devpriv; struct comedi_subdevice *s; unsigned int dw_Dummy; int ret; -- GitLab From 1b7d0642b873370babbd4cb7843de0f2d0446dc9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:48 -0700 Subject: [PATCH 1780/9457] staging: comedi: addi_apci_1500: separate from addi_common.h Remove the need to include addi_common.h by introducing a new private data definition. Only include the members that are actually used by the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 24 +++++++++---------- .../staging/comedi/drivers/addi_apci_1500.c | 13 ++++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 9896468d86f9..bfa9228c833f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -158,7 +158,7 @@ static int apci1500_di_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; int i_PatternTransitionCount = 0, i_RegValue; @@ -466,7 +466,7 @@ static int apci1500_di_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = 0, i_RegValue; @@ -653,7 +653,7 @@ static int apci1500_di_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_DummyRead = 0; /* Software reset */ @@ -789,7 +789,7 @@ static int apci1500_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP); @@ -807,7 +807,7 @@ static int apci1500_do_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; devpriv->b_OutputMemoryStatus = data[0]; return insn->n; @@ -821,7 +821,7 @@ static int apci1500_do_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; static unsigned int ui_Temp; unsigned int ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ @@ -981,7 +981,7 @@ static int apci1500_timer_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_TimerCounterMode, i_MasterConfiguration; devpriv->tsk_Current = current; @@ -1471,7 +1471,7 @@ static int apci1500_timer_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -1731,7 +1731,7 @@ static int apci1500_timer_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -1895,7 +1895,7 @@ static int apci1500_do_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; unsigned int ui_Status; int i_RegValue; int i_Constant; @@ -2015,7 +2015,7 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; unsigned int ui_InterruptStatus = 0; int i_RegValue = 0; @@ -2186,7 +2186,7 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) static int apci1500_reset(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci1500_private *devpriv = dev->private; int i_DummyRead = 0; i_TimerCounter1Init = 0; diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index dc90a8f5388f..de8d74fc6335 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,11 +1,20 @@ #include #include +#include +#include #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" +struct apci1500_private { + int iobase; + int i_IobaseAmcc; + int i_IobaseAddon; + int i_IobaseReserved; + unsigned char b_OutputMemoryStatus; + struct task_struct *tsk_Current; +}; #include "addi-data/hwdrv_apci1500.c" @@ -13,7 +22,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct addi_private *devpriv; + struct apci1500_private *devpriv; struct comedi_subdevice *s; int ret; -- GitLab From 4e068bec48c6c25ce0be41a5e38edb5442665b1d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:49 -0700 Subject: [PATCH 1781/9457] staging: comedi: addi_apci_3120: separate from addi_common.h Remove the need to include addi_common.h by introducing a new private data definition. Only include the members that are actually used by the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 38 ++++++++--------- .../staging/comedi/drivers/addi_apci_3120.c | 42 ++++++++++++++++--- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index e120d620b3ce..a2db2facab70 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -246,7 +246,7 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int i; if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE)) @@ -300,7 +300,7 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, unsigned int *chanlist, char check) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int i; unsigned int gain; unsigned short us_TmpValue; @@ -349,7 +349,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; @@ -585,7 +585,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, static int apci3120_reset(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int i; unsigned short us_TmpValue; @@ -638,7 +638,7 @@ static int apci3120_reset(struct comedi_device *dev) static int apci3120_exttrig_enable(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); @@ -647,7 +647,7 @@ static int apci3120_exttrig_enable(struct comedi_device *dev) static int apci3120_exttrig_disable(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); @@ -657,7 +657,7 @@ static int apci3120_exttrig_disable(struct comedi_device *dev) static int apci3120_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; /* Disable A2P Fifo write and AMWEN signal */ outw(0, devpriv->i_IobaseAddon + 4); @@ -778,7 +778,7 @@ static int apci3120_cyclic_ai(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned char b_Tmp; unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = @@ -1200,7 +1200,7 @@ static int apci3120_cyclic_ai(int mode, static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; /* loading private structure with cmd structure inputs */ @@ -1225,7 +1225,7 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, unsigned short *dma_buffer, unsigned int num_samples) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; devpriv->ui_AiActualScan += @@ -1245,7 +1245,7 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, static void apci3120_interrupt_dma(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; unsigned int next_dma_buf, samplesinbuf; @@ -1393,7 +1393,7 @@ static void apci3120_interrupt_dma(int irq, void *d) */ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; int n_chan, i; int err = 1; @@ -1414,7 +1414,7 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) static irqreturn_t apci3120_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned short int_daq; unsigned int int_amcc, ui_Check, i; @@ -1600,7 +1600,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int ui_Timervalue2; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -1737,7 +1737,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int ui_Timervalue2 = 0; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -1902,7 +1902,7 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned char b_Tmp; unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue; @@ -1950,7 +1950,7 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int val; /* the input channels are bits 11:8 of the status reg */ @@ -1965,7 +1965,7 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; if (comedi_dio_update_state(s, data)) { /* The do channels are bits 7:4 of the do register */ @@ -1985,7 +1985,7 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; unsigned int ui_Range, ui_Channel; unsigned short us_TmpValue; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9ba66d8ab04f..2f0b642cfbff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,14 +1,12 @@ #include #include +#include +#include #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" - -#include "addi-data/hwdrv_apci3120.c" - enum apci3120_boardid { BOARD_APCI3120, BOARD_APCI3001, @@ -31,12 +29,44 @@ static const struct apci3120_board apci3120_boardtypes[] = { }, }; +struct apci3120_private { + int iobase; + int i_IobaseAmcc; + int i_IobaseAddon; + int i_IobaseReserved; + unsigned int ui_AiActualScan; + unsigned int ui_AiNbrofChannels; + unsigned int ui_AiChannelList[32]; + unsigned int ui_AiReadData[32]; + unsigned short us_UseDma; + unsigned char b_DmaDoubleBuffer; + unsigned int ui_DmaActualBuffer; + unsigned short *ul_DmaBufferVirtual[2]; + dma_addr_t ul_DmaBufferHw[2]; + unsigned int ui_DmaBufferSize[2]; + unsigned int ui_DmaBufferUsesize[2]; + unsigned char b_DigitalOutputRegister; + unsigned char b_TimerSelectMode; + unsigned char b_ModeSelectRegister; + unsigned short us_OutputRegister; + unsigned char b_Timer2Mode; + unsigned char b_Timer2Interrupt; + unsigned int ai_running:1; + unsigned char b_InterruptMode; + unsigned char b_EocEosInterrupt; + unsigned int ui_EocEosConversionTime; + unsigned char b_ExttrigEnable; + struct task_struct *tsk_Current; +}; + +#include "addi-data/hwdrv_apci3120.c" + static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct apci3120_board *this_board = NULL; - struct addi_private *devpriv; + struct apci3120_private *devpriv; struct comedi_subdevice *s; int ret, order, i; @@ -163,7 +193,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, static void apci3120_detach(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + struct apci3120_private *devpriv = dev->private; if (dev->iobase) apci3120_reset(dev); -- GitLab From a0a7ae158a18a62b0661b3ef23ec1cbfec09ace0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 10:44:50 -0700 Subject: [PATCH 1782/9457] staging: comedi: addi_common.h: remove file This header is no longer included by any of the addi-data drivers. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_common.h | 52 ------------------- 1 file changed, 52 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/addi_common.h diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h deleted file mode 100644 index 52f35b4c00dc..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include - -struct addi_private { - int iobase; - int i_IobaseAmcc; /* base+size for AMCC chip */ - int i_IobaseAddon; /* addon base address */ - int i_IobaseReserved; - unsigned int ui_AiActualScan; /* how many scans we finished */ - unsigned int ui_AiNbrofChannels; /* how many channels is measured */ - unsigned int ui_AiChannelList[32]; /* actual chanlist */ - unsigned int ui_AiReadData[32]; - unsigned short us_UseDma; /* To use Dma or not */ - unsigned char b_DmaDoubleBuffer; /* we can use double buffering */ - unsigned int ui_DmaActualBuffer; /* which buffer is used now */ - unsigned short *ul_DmaBufferVirtual[2]; /* pointers to DMA buffer */ - dma_addr_t ul_DmaBufferHw[2]; /* hw address of DMA buff */ - unsigned int ui_DmaBufferSize[2]; /* size of dma buffer in bytes */ - unsigned int ui_DmaBufferUsesize[2]; /* which size we may now used for transfer */ - unsigned char b_DigitalOutputRegister; /* Digital Output Register */ - unsigned char b_OutputMemoryStatus; - unsigned char b_TimerSelectMode; /* Contain data written at iobase + 0C */ - unsigned char b_ModeSelectRegister; /* Contain data written at iobase + 0E */ - unsigned short us_OutputRegister; /* Contain data written at iobase + 0 */ - unsigned char b_Timer2Mode; /* Specify the timer 2 mode */ - unsigned char b_Timer2Interrupt; /* Timer2 interrupt enable or disable */ - unsigned int ai_running:1; - unsigned char b_InterruptMode; /* eoc eos or dma */ - unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */ - unsigned int ui_EocEosConversionTime; - unsigned char b_ExttrigEnable; /* To enable or disable external trigger */ - - /* Pointer to the current process */ - struct task_struct *tsk_Current; -}; -- GitLab From 67f61f7ae9dd3e1b0ac9c2136aba2fca6740d8bf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 12:14:37 -0700 Subject: [PATCH 1783/9457] staging: comedi: usbdux: introduce usbduxsub_ao_handle_urb() Factor the urb handling and resubmit out of the analog output urb completion handler and tidy it up. This allows a common exit path to be used in the completion handler to stop the async command and handle the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Reviewed-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 130 +++++++++++------------- 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 89f6ece2f0aa..5fdbf2644e09 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -399,69 +399,25 @@ static int usbdux_ao_cancel(struct comedi_device *dev, return 0; } -static void usbduxsub_ao_isoc_irq(struct urb *urb) +static void usbduxsub_ao_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; - struct comedi_subdevice *s = dev->write_subdev; struct usbdux_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; uint8_t *datap; int ret; int i; - switch (urb->status) { - case 0: - /* success */ - break; - - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ECONNABORTED: - /* after an unlink command, unplug, ... etc */ - /* no unlink needed here. Already shutting down. */ - if (devpriv->ao_cmd_running) { - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - usbdux_ao_stop(dev, 0); - } - return; - - default: - /* a real error */ - if (devpriv->ao_cmd_running) { - dev_err(dev->class_dev, - "Non-zero urb status received in ao intr context: %d\n", - urb->status); - s->async->events |= COMEDI_CB_ERROR; - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - /* we do an unlink if we are in the high speed mode */ - usbdux_ao_stop(dev, 0); - } - return; - } - - /* are we actually running? */ - if (!devpriv->ao_cmd_running) - return; - - /* normal operation: executing a command in this subdevice */ devpriv->ao_counter--; - if ((int)devpriv->ao_counter <= 0) { - /* timer zero */ + if (devpriv->ao_counter == 0) { devpriv->ao_counter = devpriv->ao_timer; - /* handle non continous acquisition */ if (cmd->stop_src == TRIG_COUNT) { - /* fixed number of samples */ devpriv->ao_sample_count--; if (devpriv->ao_sample_count < 0) { - /* all samples transmitted */ - usbdux_ao_stop(dev, 0); - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - /* no resubmit of the urb */ + async->events |= COMEDI_CB_EOA; return; } } @@ -473,26 +429,26 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - ret = comedi_buf_get(s, &val); - if (ret < 0) { + if (!comedi_buf_get(s, &val)) { dev_err(dev->class_dev, "buffer underflow\n"); - s->async->events |= (COMEDI_CB_EOA | - COMEDI_CB_OVERFLOW); + async->events |= COMEDI_CB_OVERFLOW; + return; } + /* pointer to the DA */ *datap++ = val & 0xff; *datap++ = (val >> 8) & 0xff; *datap++ = chan << 6; s->readback[chan] = val; - - s->async->events |= COMEDI_CB_BLOCK; - comedi_event(dev, s); } + async->events |= COMEDI_CB_BLOCK; } - urb->transfer_buffer_length = SIZEOUTBUF; - urb->dev = comedi_to_usb_dev(dev); - urb->status = 0; - if (devpriv->ao_cmd_running) { + + /* if command is still running, resubmit urb for BULK transfer */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->transfer_buffer_length = SIZEOUTBUF; + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; if (devpriv->high_speed) urb->interval = 8; /* uframes */ else @@ -509,16 +465,54 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) if (ret == -EL2NSYNC) dev_err(dev->class_dev, "buggy USB host controller or bug in IRQ handling!\n"); - - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ - usbdux_ao_stop(dev, 0); + async->events |= COMEDI_CB_ERROR; } } } +static void usbduxsub_ao_isoc_irq(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct comedi_subdevice *s = dev->write_subdev; + struct comedi_async *async = s->async; + struct usbdux_private *devpriv = dev->private; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ao_cmd_running) + return; + + switch (urb->status) { + case 0: + usbduxsub_ao_handle_urb(dev, s, urb); + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* after an unlink command, unplug, ... etc */ + async->events |= COMEDI_CB_ERROR; + break; + + default: + /* a real error */ + dev_err(dev->class_dev, + "Non-zero urb status received in ao intr context: %d\n", + urb->status); + async->events |= COMEDI_CB_ERROR; + break; + } + + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbdux_ao_stop(dev, 0); + + comedi_event(dev, s); +} + static int usbdux_submit_urbs(struct comedi_device *dev, struct urb **urbs, int num_urbs, int input_urb) -- GitLab From 41ca22a8c575b5f2e76150a30db5d1a934ed7ca9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 12:14:38 -0700 Subject: [PATCH 1784/9457] staging: comedi: usbdux: introduce usbduxsub_ai_handle_urb() Factor the urb handling and resubmit out of the analog input urb completion handler and tidy it up. This allows a common exit path to be used in the completion handler to stop the async command and handle the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Reviewed-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 174 +++++++++++------------- 1 file changed, 79 insertions(+), 95 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 5fdbf2644e09..eae441f3858c 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -250,128 +250,112 @@ static int usbdux_ai_cancel(struct comedi_device *dev, return 0; } -/* analogue IN - interrupt service routine */ +static void usbduxsub_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) +{ + struct usbdux_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + int ret; + int i; + + devpriv->ai_counter--; + if (devpriv->ai_counter == 0) { + devpriv->ai_counter = devpriv->ai_timer; + + if (cmd->stop_src == TRIG_COUNT) { + devpriv->ai_sample_count--; + if (devpriv->ai_sample_count < 0) { + async->events |= COMEDI_CB_EOA; + return; + } + } + + /* get the data from the USB bus and hand it over to comedi */ + for (i = 0; i < cmd->chanlist_len; i++) { + unsigned int range = CR_RANGE(cmd->chanlist[i]); + uint16_t val = le16_to_cpu(devpriv->in_buf[i]); + + /* bipolar data is two's-complement */ + if (comedi_range_is_bipolar(s, range)) + val ^= ((s->maxdata + 1) >> 1); + + /* transfer data */ + if (!comedi_buf_put(s, val)) + return; + } + async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + } + + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, + "urb resubmit failed in int-context! err=%d\n", + ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler!\n"); + async->events |= COMEDI_CB_ERROR; + } + } +} + static void usbduxsub_ai_isoc_irq(struct urb *urb) { struct comedi_device *dev = urb->context; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; struct usbdux_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - int i, err; - /* first we test if something unusual has just happened */ + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) + return; + switch (urb->status) { case 0: /* copy the result in the transfer buffer */ memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); + usbduxsub_ai_handle_urb(dev, s, urb); break; + case -EILSEQ: - /* error in the ISOchronous data */ - /* we don't copy the data into the transfer buffer */ - /* and recycle the last data byte */ + /* + * error in the ISOchronous data + * we don't copy the data into the transfer buffer + * and recycle the last data byte + */ dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); + usbduxsub_ai_handle_urb(dev, s, urb); break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: case -ECONNABORTED: - /* happens after an unlink command */ - if (devpriv->ai_cmd_running) { - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* stop the transfer w/o unlink */ - usbdux_ai_stop(dev, 0); - } - return; + /* after an unlink command, unplug, ... etc */ + async->events |= COMEDI_CB_ERROR; + break; default: - /* a real error on the bus */ - /* pass error to comedi if we are really running a command */ - if (devpriv->ai_cmd_running) { - dev_err(dev->class_dev, - "Non-zero urb status received in ai intr context: %d\n", - urb->status); - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ - usbdux_ai_stop(dev, 0); - } - return; + /* a real error */ + dev_err(dev->class_dev, + "Non-zero urb status received in ai intr context: %d\n", + urb->status); + async->events |= COMEDI_CB_ERROR; + break; } /* - * at this point we are reasonably sure that nothing dodgy has happened - * are we running a command? + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. */ - if (unlikely(!devpriv->ai_cmd_running)) { - /* - * not running a command, do not continue execution if no - * asynchronous command is running in particular not resubmit - */ - return; - } - - urb->dev = comedi_to_usb_dev(dev); - - /* resubmit the urb */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err < 0)) { - dev_err(dev->class_dev, - "urb resubmit failed in int-context! err=%d\n", err); - if (err == -EL2NSYNC) - dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler!\n"); - s->async->events |= COMEDI_CB_EOA; - s->async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* don't do an unlink here */ + if (async->events & COMEDI_CB_CANCEL_MASK) usbdux_ai_stop(dev, 0); - return; - } - - devpriv->ai_counter--; - if (likely(devpriv->ai_counter > 0)) - return; - - /* timer zero, transfer measurements to comedi */ - devpriv->ai_counter = devpriv->ai_timer; - /* test, if we transmit only a fixed number of samples */ - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - devpriv->ai_sample_count--; - /* all samples received? */ - if (devpriv->ai_sample_count < 0) { - /* prevent a resubmit next time */ - usbdux_ai_stop(dev, 0); - /* say comedi that the acquistion is over */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - } - /* get the data from the USB bus and hand it over to comedi */ - for (i = 0; i < cmd->chanlist_len; i++) { - unsigned int range = CR_RANGE(cmd->chanlist[i]); - uint16_t val = le16_to_cpu(devpriv->in_buf[i]); - - /* bipolar data is two's-complement */ - if (comedi_range_is_bipolar(s, range)) - val ^= ((s->maxdata + 1) >> 1); - - /* transfer data */ - err = comedi_buf_put(s, val); - if (unlikely(err == 0)) { - /* buffer overflow */ - usbdux_ai_stop(dev, 0); - return; - } - } - /* tell comedi that data is there */ - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; comedi_event(dev, s); } -- GitLab From 7c88f9f48c6fcf31aeda755b723befad642150ca Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 12:14:39 -0700 Subject: [PATCH 1785/9457] staging: comedi: usbduxfast: introduce usbduxfast_ai_handle_urb() Factor the urb handling and resubmit out of the completion handler and tidy it up. This allows a common exit path to be used in the completion handler to stop the async command and handle the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Reviewed-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 131 ++++++++------------ 1 file changed, 52 insertions(+), 79 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index cddc2ba294bb..95c2ec7ed22a 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -236,114 +236,87 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev, return ret; } -/* - * analogue IN - * interrupt service routine - */ +static void usbduxfast_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) +{ + struct usbduxfast_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + int ret; + + if (devpriv->ignore) { + devpriv->ignore--; + } else { + unsigned int nbytes = urb->actual_length; + + if (cmd->stop_src == TRIG_COUNT) { + unsigned int nsamples = nbytes / bytes_per_sample(s); + + if (devpriv->ai_sample_count < nsamples) { + nsamples = devpriv->ai_sample_count; + async->events |= COMEDI_CB_EOA; + } + devpriv->ai_sample_count -= nsamples; + nbytes = nsamples * bytes_per_sample(s); + } + + cfc_write_array_to_buffer(s, urb->transfer_buffer, nbytes); + } + + /* if command is still running, resubmit urb for BULK transfer */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, "urb resubm failed: %d", ret); + async->events |= COMEDI_CB_ERROR; + } + } +} + static void usbduxfast_ai_interrupt(struct urb *urb) { struct comedi_device *dev = urb->context; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - struct usb_device *usb = comedi_to_usb_dev(dev); struct usbduxfast_private *devpriv = dev->private; - int n, err; - /* are we running a command? */ - if (unlikely(!devpriv->ai_cmd_running)) { - /* - * not running a command - * do not continue execution if no asynchronous command - * is running in particular not resubmit - */ + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) return; - } - /* first we test if something unusual has just happened */ switch (urb->status) { case 0: + usbduxfast_ai_handle_urb(dev, s, urb); break; - /* - * happens after an unlink command or when the device - * is plugged out - */ case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: case -ECONNABORTED: - /* tell this comedi */ - async->events |= COMEDI_CB_EOA; + /* after an unlink command, unplug, ... etc */ async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - /* stop the transfer w/o unlink */ - usbduxfast_ai_stop(dev, 0); - return; + break; default: + /* a real error */ dev_err(dev->class_dev, "non-zero urb status received in ai intr context: %d\n", urb->status); - async->events |= COMEDI_CB_EOA; async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); - usbduxfast_ai_stop(dev, 0); - return; - } - - if (!devpriv->ignore) { - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - n = urb->actual_length / sizeof(uint16_t); - if (unlikely(devpriv->ai_sample_count < n)) { - unsigned int num_bytes; - - /* partial sample received */ - num_bytes = devpriv->ai_sample_count * - sizeof(uint16_t); - cfc_write_array_to_buffer(s, - urb->transfer_buffer, - num_bytes); - usbduxfast_ai_stop(dev, 0); - /* tell comedi that the acquistion is over */ - async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - devpriv->ai_sample_count -= n; - } - /* write the full buffer to comedi */ - err = cfc_write_array_to_buffer(s, urb->transfer_buffer, - urb->actual_length); - if (unlikely(err == 0)) { - /* buffer overflow */ - usbduxfast_ai_stop(dev, 0); - return; - } - - /* tell comedi that data is there */ - comedi_event(dev, s); - } else { - /* ignore this packet */ - devpriv->ignore--; + break; } /* - * command is still running - * resubmit urb for BULK transfer + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. */ - urb->dev = usb; - urb->status = 0; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - dev_err(dev->class_dev, - "urb resubm failed: %d", err); - async->events |= COMEDI_CB_EOA; - async->events |= COMEDI_CB_ERROR; - comedi_event(dev, s); + if (async->events & COMEDI_CB_CANCEL_MASK) usbduxfast_ai_stop(dev, 0); - } + + comedi_event(dev, s); } static int usbduxfast_submit_urb(struct comedi_device *dev) -- GitLab From 7a5dfb212010e017b8bbc91f8df196258f790f90 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 12:14:40 -0700 Subject: [PATCH 1786/9457] staging: comedi: usbduxsigma: introduce usbduxsigma_ao_handle_urb() Factor the urb handling and resubmit out of the analog output urb completion handler and tidy it up. This allows a common exit path to be used in the completion handler to stop the async command and handle the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Reviewed-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 148 ++++++++++--------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index a869e38c777b..985c6f08c56e 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -349,62 +349,25 @@ static int usbduxsigma_ao_cancel(struct comedi_device *dev, return 0; } -static void usbduxsigma_ao_urb_complete(struct urb *urb) +static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; struct usbduxsigma_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->write_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; uint8_t *datap; int ret; int i; - switch (urb->status) { - case 0: - /* success */ - break; - - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ECONNABORTED: - /* happens after an unlink command */ - if (devpriv->ao_cmd_running) { - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - } - return; - - default: - /* a real error */ - if (devpriv->ao_cmd_running) { - dev_err(dev->class_dev, - "%s: non-zero urb status (%d)\n", - __func__, urb->status); - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA); - comedi_event(dev, s); - } - return; - } - - if (!devpriv->ao_cmd_running) - return; - devpriv->ao_counter--; - if ((int)devpriv->ao_counter <= 0) { - /* timer zero, transfer from comedi */ + if (devpriv->ao_counter == 0) { devpriv->ao_counter = devpriv->ao_timer; if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ devpriv->ao_sample_count--; if (devpriv->ao_sample_count < 0) { - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - /* acquistion is over, tell comedi */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); + async->events |= COMEDI_CB_EOA; return; } } @@ -416,44 +379,85 @@ static void usbduxsigma_ao_urb_complete(struct urb *urb) unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - ret = comedi_buf_get(s, &val); - if (ret < 0) { + if (!comedi_buf_get(s, &val)) { dev_err(dev->class_dev, "buffer underflow\n"); - s->async->events |= (COMEDI_CB_EOA | - COMEDI_CB_OVERFLOW); + async->events |= COMEDI_CB_OVERFLOW; + return; } + *datap++ = val; *datap++ = chan; s->readback[chan] = val; - - s->async->events |= COMEDI_CB_BLOCK; - comedi_event(dev, s); } + async->events |= COMEDI_CB_BLOCK; } - urb->transfer_buffer_length = SIZEOUTBUF; - urb->dev = comedi_to_usb_dev(dev); - urb->status = 0; - if (devpriv->high_speed) - urb->interval = 8; /* uframes */ - else - urb->interval = 1; /* frames */ - urb->number_of_packets = 1; - urb->iso_frame_desc[0].offset = 0; - urb->iso_frame_desc[0].length = SIZEOUTBUF; - urb->iso_frame_desc[0].status = 0; - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) { - dev_err(dev->class_dev, - "%s: urb resubmit failed (%d)\n", - __func__, ret); - if (ret == -EL2NSYNC) + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->transfer_buffer_length = SIZEOUTBUF; + urb->dev = comedi_to_usb_dev(dev); + urb->status = 0; + if (devpriv->high_speed) + urb->interval = 8; /* uframes */ + else + urb->interval = 1; /* frames */ + urb->number_of_packets = 1; + urb->iso_frame_desc[0].offset = 0; + urb->iso_frame_desc[0].length = SIZEOUTBUF; + urb->iso_frame_desc[0].status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler\n"); - usbduxsigma_ao_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); + "%s: urb resubmit failed (%d)\n", + __func__, ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler\n"); + async->events |= COMEDI_CB_ERROR; + } + } +} + +static void usbduxsigma_ao_urb_complete(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct usbduxsigma_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->write_subdev; + struct comedi_async *async = s->async; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ao_cmd_running) + return; + + switch (urb->status) { + case 0: + usbduxsigma_ao_handle_urb(dev, s, urb); + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* happens after an unlink command */ + async->events |= COMEDI_CB_ERROR; + break; + + default: + /* a real error */ + dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", + __func__, urb->status); + async->events |= COMEDI_CB_ERROR; + break; } + + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbduxsigma_ao_stop(dev, 0); + + comedi_event(dev, s); } static int usbduxsigma_submit_urbs(struct comedi_device *dev, -- GitLab From bcbb0c47c73dc19f19b78e849545cb4b030e94dd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 14 Oct 2014 12:14:41 -0700 Subject: [PATCH 1787/9457] staging: comedi: usbduxsigma: introduce usbduxsigma_ai_handle_urb() Factor the urb handling and resubmit out of the analog input urb completion handler and tidy it up. This allows a common exit path to be used in the completion handler to stop the async command and handle the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Reviewed-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 157 +++++++++---------- 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 985c6f08c56e..1d12cc6c1ade 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -211,23 +211,80 @@ static int usbduxsigma_ai_cancel(struct comedi_device *dev, return 0; } -static void usbduxsigma_ai_urb_complete(struct urb *urb) +static void usbduxsigma_ai_handle_urb(struct comedi_device *dev, + struct comedi_subdevice *s, + struct urb *urb) { - struct comedi_device *dev = urb->context; struct usbduxsigma_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; unsigned int dio_state; uint32_t val; int ret; int i; - /* first we test if something unusual has just happened */ + devpriv->ai_counter--; + if (devpriv->ai_counter == 0) { + devpriv->ai_counter = devpriv->ai_timer; + + if (cmd->stop_src == TRIG_COUNT) { + devpriv->ai_sample_count--; + if (devpriv->ai_sample_count < 0) { + async->events |= COMEDI_CB_EOA; + return; + } + } + + /* get the state of the dio pins to allow external trigger */ + dio_state = be32_to_cpu(devpriv->in_buf[0]); + + /* get the data from the USB bus and hand it over to comedi */ + for (i = 0; i < cmd->chanlist_len; i++) { + /* transfer data, note first byte is the DIO state */ + val = be32_to_cpu(devpriv->in_buf[i+1]); + val &= 0x00ffffff; /* strip status byte */ + val ^= 0x00800000; /* convert to unsigned */ + + if (!cfc_write_array_to_buffer(s, &val, + sizeof(uint32_t))) + return; + } + } + + /* if command is still running, resubmit urb */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) { + urb->dev = comedi_to_usb_dev(dev); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(dev->class_dev, + "%s: urb resubmit failed (%d)\n", + __func__, ret); + if (ret == -EL2NSYNC) + dev_err(dev->class_dev, + "buggy USB host controller or bug in IRQ handler\n"); + async->events |= COMEDI_CB_ERROR; + } + } +} + +static void usbduxsigma_ai_urb_complete(struct urb *urb) +{ + struct comedi_device *dev = urb->context; + struct usbduxsigma_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + + /* exit if not running a command, do not resubmit urb */ + if (!devpriv->ai_cmd_running) + return; + switch (urb->status) { case 0: /* copy the result in the transfer buffer */ memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); + usbduxsigma_ai_handle_urb(dev, s, urb); break; + case -EILSEQ: /* * error in the ISOchronous data @@ -235,7 +292,7 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb) * and recycle the last data byte */ dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); - + usbduxsigma_ai_handle_urb(dev, s, urb); break; case -ECONNRESET: @@ -243,86 +300,24 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb) case -ESHUTDOWN: case -ECONNABORTED: /* happens after an unlink command */ - if (devpriv->ai_cmd_running) { - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - /* we are still running a command, tell comedi */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - } - return; + async->events |= COMEDI_CB_ERROR; + break; default: - /* - * a real error on the bus - * pass error to comedi if we are really running a command - */ - if (devpriv->ai_cmd_running) { - dev_err(dev->class_dev, - "%s: non-zero urb status (%d)\n", - __func__, urb->status); - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - } - return; - } - - if (unlikely(!devpriv->ai_cmd_running)) - return; - - urb->dev = comedi_to_usb_dev(dev); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(ret < 0)) { - dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n", - __func__, ret); - if (ret == -EL2NSYNC) - dev_err(dev->class_dev, - "buggy USB host controller or bug in IRQ handler\n"); - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR); - comedi_event(dev, s); - return; - } - - /* get the state of the dio pins to allow external trigger */ - dio_state = be32_to_cpu(devpriv->in_buf[0]); - - devpriv->ai_counter--; - if (likely(devpriv->ai_counter > 0)) - return; - - /* timer zero, transfer measurements to comedi */ - devpriv->ai_counter = devpriv->ai_timer; - - if (cmd->stop_src == TRIG_COUNT) { - /* not continuous, fixed number of samples */ - devpriv->ai_sample_count--; - if (devpriv->ai_sample_count < 0) { - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - /* acquistion is over, tell comedi */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } + /* a real error */ + dev_err(dev->class_dev, "%s: non-zero urb status (%d)\n", + __func__, urb->status); + async->events |= COMEDI_CB_ERROR; + break; } - /* get the data from the USB bus and hand it over to comedi */ - for (i = 0; i < cmd->chanlist_len; i++) { - /* transfer data, note first byte is the DIO state */ - val = be32_to_cpu(devpriv->in_buf[i+1]); - val &= 0x00ffffff; /* strip status byte */ - val ^= 0x00800000; /* convert to unsigned */ + /* + * comedi_handle_events() cannot be used in this driver. The (*cancel) + * operation would unlink the urb. + */ + if (async->events & COMEDI_CB_CANCEL_MASK) + usbduxsigma_ai_stop(dev, 0); - ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t)); - if (unlikely(ret == 0)) { - /* buffer overflow */ - usbduxsigma_ai_stop(dev, 0); /* w/o unlink */ - return; - } - } - /* tell comedi that data is there */ - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); comedi_event(dev, s); } -- GitLab From 4a3df1540b980216d558c063a1e32a81d194bf6d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 10:37:43 -0700 Subject: [PATCH 1788/9457] staging: comedi: addi_apci_035: remove driver According to ADDI-DATA, this board was discontinued last year and they feel that no further development is needed for this driver. Remove the driver from comedi to help with the addi-data cleanup. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 8 - drivers/staging/comedi/drivers/Makefile | 1 - .../comedi/drivers/addi-data/hwdrv_apci035.c | 482 ------------------ .../staging/comedi/drivers/addi_apci_035.c | 129 ----- 4 files changed, 620 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c delete mode 100644 drivers/staging/comedi/drivers/addi_apci_035.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 77c5013d81c5..d4214c086f39 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -594,14 +594,6 @@ config COMEDI_ADDI_WATCHDOG boards. This module will be automatically selected when needed. The module will be called addi_watchdog. -config COMEDI_ADDI_APCI_035 - tristate "ADDI-DATA APCI_035 support" - ---help--- - Enable support for ADDI-DATA APCI_035 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_035. - config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" ---help--- diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 6bc9ef3b25b3..84fdf20ca986 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_COMEDI_S526) += s526.o # Comedi PCI drivers obj-$(CONFIG_COMEDI_8255_PCI) += 8255_pci.o obj-$(CONFIG_COMEDI_ADDI_WATCHDOG) += addi_watchdog.o -obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c deleted file mode 100644 index d833da2eeac6..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * 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. - */ - -/* Card Specific information */ -#define APCI035_ADDRESS_RANGE 255 - -/* Timer / Watchdog Related Defines */ -#define APCI035_TCW_SYNC_ENABLEDISABLE 0 -#define APCI035_TCW_RELOAD_VALUE 4 -#define APCI035_TCW_TIMEBASE 8 -#define APCI035_TCW_PROG 12 -#define APCI035_TCW_TRIG_STATUS 16 -#define APCI035_TCW_IRQ 20 -#define APCI035_TCW_WARN_TIMEVAL 24 -#define APCI035_TCW_WARN_TIMEBASE 28 - -#define ADDIDATA_TIMER 0 -/* #define ADDIDATA_WATCHDOG 1 */ - -#define APCI035_TW1 0 -#define APCI035_TW2 32 -#define APCI035_TW3 64 -#define APCI035_TW4 96 - -#define APCI035_AI_OFFSET 0 -#define APCI035_TEMP 128 -#define APCI035_ALR_SEQ 4 -#define APCI035_START_STOP_INDEX 8 -#define APCI035_ALR_START_STOP 12 -#define APCI035_ALR_IRQ 16 -#define APCI035_EOS 20 -#define APCI035_CHAN_NO 24 -#define APCI035_CHAN_VAL 28 -#define APCI035_CONV_TIME_TIME_BASE 36 -#define APCI035_RELOAD_CONV_TIME_VAL 32 -#define APCI035_DELAY_TIME_TIME_BASE 44 -#define APCI035_RELOAD_DELAY_TIME_VAL 40 -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define APCI035_MAXVOLT 2.5 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* ANALOG INPUT RANGE */ -static struct comedi_lrange range_apci035_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -static int i_WatchdogNbr; -static int i_Temp; -static int i_Flag = 1; - -/* - * Configures The Timer , Counter or Watchdog - * - * data[0] 0 = Configure As Timer, 1 = Configure As Watchdog - * data[1] Watchdog number - * data[2] Time base Unit - * data[3] Reload Value - * data[4] External Trigger, 1 = Enable, 0 = Disable - * data[5] External Trigger Level - * 00 = Trigger Disabled - * 01 = Trigger Enabled (Low level) - * 10 = Trigger Enabled (High Level) - * 11 = Trigger Enabled (High/Low level) - * data[6] External Gate, 1 = Enable, 0 = Disable - * data[7] External Gate level - * 00 = Gate Disabled - * 01 = Gate Enabled (Low level) - * 10 = Gate Enabled (High Level) - * data[8] Warning Relay, 1 = Enable, 0 = Disable - * data[9] Warning Delay available - * data[10] Warning Relay Time unit - * data[11] Warning Relay Time Reload value - * data[12] Reset Relay, 1 = Enable, 0 = Disable - * data[13] Interrupt, 1 = Enable, 0 = Disable - */ -static int apci035_timer_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci035_private *devpriv = dev->private; - unsigned int ui_Status; - unsigned int ui_Command; - unsigned int ui_Mode; - - i_Temp = 0; - devpriv->tsk_Current = current; - devpriv->b_TimerSelectMode = data[0]; - i_WatchdogNbr = data[1]; - if (data[0] == 0) - ui_Mode = 2; - else - ui_Mode = 0; - - ui_Command = 0; - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the reload value */ - outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4); - - /* Set the time unit */ - outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8); - if (data[0] == ADDIDATA_TIMER) { - - /* Set the mode : */ - /* - Disable the hardware */ - /* - Disable the counter mode */ - /* - Disable the warning */ - /* - Disable the reset */ - /* - Enable the timer mode */ - /* - Set the timer mode */ - - ui_Command = - (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL; - - } else if (data[0] == ADDIDATA_WATCHDOG) { - - /* Set the mode : */ - /* - Disable the hardware */ - /* - Disable the counter mode */ - /* - Disable the warning */ - /* - Disable the reset */ - /* - Disable the timer mode */ - - ui_Command = ui_Command & 0xFFF819E2UL; - - } else { - dev_err(dev->class_dev, "The parameter for Timer/watchdog selection is in error\n"); - return -EINVAL; - } - - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware trigger */ - ui_Command = ui_Command & 0xFFFFF89FUL; - if (data[4] == 1) { - /* Set the hardware trigger level */ - ui_Command = ui_Command | (data[5] << 5); - } - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware gate */ - ui_Command = ui_Command & 0xFFFFF87FUL; - if (data[6] == 1) { - /* Set the hardware gate level */ - ui_Command = ui_Command | (data[7] << 7); - } - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware output */ - ui_Command = ui_Command & 0xFFFFF9FBUL; - - /* Set the hardware output level */ - ui_Command = ui_Command | (data[8] << 2); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - if (data[9] == 1) { - /* Set the reload value */ - outl(data[11], - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24); - - /* Set the time unite */ - outl(data[10], - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28); - } - - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Disable the hardware output */ - ui_Command = ui_Command & 0xFFFFF9F7UL; - - /* Set the hardware output level */ - ui_Command = ui_Command | (data[12] << 3); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Enable the watchdog interrupt */ - ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the interrupt selection */ - ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16); - - ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1); - outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - return insn->n; -} - -/* - * Start / Stop The Selected Timer , or Watchdog - * - * data[0] - * 0 - Stop Selected Timer/Watchdog - * 1 - Start Selected Timer/Watch*dog - * 2 - Trigger Selected Timer/Watchdog - * 3 - Stop All Timer/Watchdog - * 4 - Start All Timer/Watchdog - * 5 - Trigger All Timer/Watchdog - */ -static int apci035_timer_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci035_private *devpriv = dev->private; - unsigned int ui_Command; - int i_Count; - - if (data[0] == 1) { - ui_Command = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Start the hardware */ - ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - if (data[0] == 2) { - ui_Command = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - - /* Set the trigger command */ - ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - - if (data[0] == 0) { - /* Stop The Watchdog */ - ui_Command = 0; - /* - * ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12); - * ui_Command = ui_Command & 0xFFFFF9FEUL; - */ - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); - } - if (data[0] == 3) { - /* stop all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x2UL; - else - ui_Command = 0x10UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - - } - if (data[0] == 4) { - /* start all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x1UL; - else - ui_Command = 0x8UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - } - if (data[0] == 5) { - /* trigger all Watchdogs */ - ui_Command = 0; - for (i_Count = 1; i_Count <= 4; i_Count++) { - if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) - ui_Command = 0x4UL; - else - ui_Command = 0x20UL; - - i_WatchdogNbr = i_Count; - outl(ui_Command, - devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + - 0); - } - i_Temp = 1; - } - return insn->n; -} - -/* - * Read The Selected Timer , Counter or Watchdog - * - * data[0] software trigger status - * data[1] hardware trigger status - * data[2] Software clear status - * data[3] Overflow status - * data[4] Timer actual value - */ -static int apci035_timer_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci035_private *devpriv = dev->private; - unsigned int ui_Status; /* Status register */ - - i_WatchdogNbr = insn->unused[0]; - - /* Get the status */ - ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16); - - /* Get the software trigger status */ - data[0] = ((ui_Status >> 1) & 1); - - /* Get the hardware trigger status */ - data[1] = ((ui_Status >> 2) & 1); - - /* Get the software clear status */ - data[2] = ((ui_Status >> 3) & 1); - - /* Get the overflow status */ - data[3] = ((ui_Status >> 0) & 1); - if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) - data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); - - return insn->n; -} - -/* - * Configures The Analog Input Subdevice - * - * data[0] Warning delay value - */ -static int apci035_ai_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci035_private *devpriv = dev->private; - - devpriv->tsk_Current = current; - outl(0x200 | 0, devpriv->iobase + 128 + 0x4); - outl(0, devpriv->iobase + 128 + 0); - - /* Initialise the warning value */ - outl(0x300 | 0, devpriv->iobase + 128 + 0x4); - outl((data[0] << 8), devpriv->iobase + 128 + 0); - outl(0x200000UL, devpriv->iobase + 128 + 12); - - return insn->n; -} - -/* - * Read value of the selected channel - * - * data[0] Digital Value Of Input - */ -static int apci035_ai_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci035_private *devpriv = dev->private; - unsigned int ui_CommandRegister; - - /* Set the start */ - ui_CommandRegister = 0x80000; - - /* Write the command register */ - outl(ui_CommandRegister, devpriv->iobase + 128 + 8); - - /* Read the digital value of the input */ - data[0] = inl(devpriv->iobase + 128 + 28); - return insn->n; -} - -static int apci035_reset(struct comedi_device *dev) -{ - struct apci035_private *devpriv = dev->private; - int i_Count; - - for (i_Count = 1; i_Count <= 4; i_Count++) { - i_WatchdogNbr = i_Count; - - /* stop all timers */ - outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); - } - outl(0x0, devpriv->iobase + 128 + 12); /* Disable the warning delay */ - - return 0; -} - -static irqreturn_t apci035_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct apci035_private *devpriv = dev->private; - unsigned int ui_StatusRegister1; - unsigned int ui_StatusRegister2; - unsigned int ui_ReadCommand; - unsigned int ui_ChannelNumber; - unsigned int ui_DigitalTemperature; - - if (i_Temp == 1) { - i_WatchdogNbr = i_Flag; - i_Flag = i_Flag + 1; - } - - /* Read the interrupt status register of temperature Warning */ - ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16); - - /* Read the interrupt status register for Watchdog/timer */ - ui_StatusRegister2 = - inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20); - - /* Test if warning relay interrupt */ - if ((((ui_StatusRegister1) & 0x8) == 0x8)) { - - /* Disable the temperature warning */ - ui_ReadCommand = inl(devpriv->iobase + 128 + 12); - ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL; - outl(ui_ReadCommand, devpriv->iobase + 128 + 12); - - /* Read the channel number */ - ui_ChannelNumber = inl(devpriv->iobase + 128 + 60); - - /* Read the digital temperature value */ - ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60); - - /* send signal to the sample */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - - } else if ((ui_StatusRegister2 & 0x1) == 0x1) { - /* send signal to the sample */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - } - - return IRQ_HANDLED; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c deleted file mode 100644 index d7b7e1aa8b33..000000000000 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include -#include - -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -struct apci035_private { - int iobase; - int i_IobaseAmcc; - int i_IobaseAddon; - int i_IobaseReserved; - unsigned char b_TimerSelectMode; - struct task_struct *tsk_Current; -}; - -#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ - -#include "addi-data/hwdrv_apci035.c" - -static int apci035_auto_attach(struct comedi_device *dev, - unsigned long context) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct apci035_private *devpriv; - struct comedi_subdevice *s; - unsigned int dw_Dummy; - int ret; - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - ret = comedi_pci_enable(dev); - if (ret) - return ret; - - dev->iobase = pci_resource_start(pcidev, 1); - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - - if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, apci035_interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret == 0) - dev->irq = pcidev->irq; - } - - /* Set 3 wait stait */ - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - - ret = comedi_alloc_subdevices(dev, 2); - if (ret) - return ret; - - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - s->n_chan = 16; - s->maxdata = 0xff; - s->len_chanlist = s->n_chan; - s->range_table = &range_apci035_ai; - s->insn_config = apci035_ai_config; - s->insn_read = apci035_ai_read; - - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - s->insn_write = apci035_timer_write; - s->insn_read = apci035_timer_read; - s->insn_config = apci035_timer_config; - - apci035_reset(dev); - - return 0; -} - -static void apci035_detach(struct comedi_device *dev) -{ - if (dev->iobase) - apci035_reset(dev); - comedi_pci_detach(dev); -} - -static struct comedi_driver apci035_driver = { - .driver_name = "addi_apci_035", - .module = THIS_MODULE, - .auto_attach = apci035_auto_attach, - .detach = apci035_detach, -}; - -static int apci035_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data); -} - -static const struct pci_device_id apci035_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci035_pci_table); - -static struct pci_driver apci035_pci_driver = { - .name = "addi_apci_035", - .id_table = apci035_pci_table, - .probe = apci035_pci_probe, - .remove = comedi_pci_auto_unconfig, -}; -module_comedi_pci_driver(apci035_driver, apci035_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); -- GitLab From 60942e707f78b2910444579079ba5426b296cb9e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 15:04:30 -0700 Subject: [PATCH 1789/9457] staging: comedi: ni_mio_common: remove deadcode in ni_cdio_cmdtest() Reported-by: coverity (CID 142967) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 785ad7004d98..fa5b25063661 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -3513,9 +3513,6 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); -- GitLab From e7ea440a57fa0ace880e3c9406e02d580f24a91f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 15:03:15 -0700 Subject: [PATCH 1790/9457] staging: comedi: ni_6527: remove deadcode in ni6527_intr_cmdtest() Reported-by: coverity (CID 142962) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index b77354bc75e6..b35e1aeb6626 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -238,9 +238,6 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); -- GitLab From c3e1715890b2c3009155e8865d5c6d649a16a4b5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 15:02:14 -0700 Subject: [PATCH 1791/9457] staging: comedi: ni_65xx: remove deadcode in ni_65xx_intr_cmdtest() Reported-by: coverity (CID 142963) Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 3c27f532aa6e..973f0058a1e4 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -534,9 +534,6 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ /* Step 2b : and mutually compatible */ - if (err) - return 2; - /* Step 3: check if arguments are trivially valid */ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); -- GitLab From 1b90779b238a8554a465fb99b3828a9e0500ff2a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:08 -0700 Subject: [PATCH 1792/9457] staging: comedi: addi_apci_3120: DMA requires an interrupt An interrupt is required for DMA to work. Factor out the DMA buffer allocation from the (*auto_attach) and only allocate the buffers if the interrupt is available. For aesthetics, also factor the DMA buffer free from the (*detach). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_3120.c | 85 +++++++++++-------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 2f0b642cfbff..08ac390edc3f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -61,6 +61,51 @@ struct apci3120_private { #include "addi-data/hwdrv_apci3120.c" +static void apci3120_dma_alloc(struct comedi_device *dev) +{ + struct apci3120_private *devpriv = dev->private; + int order; + int i; + + for (i = 0; i < 2; i++) { + for (order = 2; order >= 0; order--) { + devpriv->ul_DmaBufferVirtual[i] = + dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order, + &devpriv->ul_DmaBufferHw[i], + GFP_KERNEL); + + if (devpriv->ul_DmaBufferVirtual[i]) + break; + } + if (!devpriv->ul_DmaBufferVirtual[i]) + break; + devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order; + + if (i == 0) + devpriv->us_UseDma = 1; + if (i == 1) + devpriv->b_DmaDoubleBuffer = 1; + } +} + +static void apci3120_dma_free(struct comedi_device *dev) +{ + struct apci3120_private *devpriv = dev->private; + int i; + + if (!devpriv) + return; + + for (i = 0; i < 2; i++) { + if (devpriv->ul_DmaBufferVirtual[i]) { + dma_free_coherent(dev->hw_dev, + devpriv->ui_DmaBufferSize[i], + devpriv->ul_DmaBufferVirtual[i], + devpriv->ul_DmaBufferHw[i]); + } + } +} + static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -68,7 +113,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, const struct apci3120_board *this_board = NULL; struct apci3120_private *devpriv; struct comedi_subdevice *s; - int ret, order, i; + int ret; if (context < ARRAY_SIZE(apci3120_boardtypes)) this_board = &apci3120_boardtypes[context]; @@ -95,30 +140,12 @@ static int apci3120_auto_attach(struct comedi_device *dev, if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, dev->board_name, dev); - if (ret == 0) + if (ret == 0) { dev->irq = pcidev->irq; - } - - /* Allocate DMA buffers */ - for (i = 0; i < 2; i++) { - for (order = 2; order >= 0; order--) { - devpriv->ul_DmaBufferVirtual[i] = - dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order, - &devpriv->ul_DmaBufferHw[i], - GFP_KERNEL); - if (devpriv->ul_DmaBufferVirtual[i]) - break; + apci3120_dma_alloc(dev); } - if (!devpriv->ul_DmaBufferVirtual[i]) - break; - devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order; } - if (devpriv->ul_DmaBufferVirtual[0]) - devpriv->us_UseDma = 1; - - if (devpriv->ul_DmaBufferVirtual[1]) - devpriv->b_DmaDoubleBuffer = 1; ret = comedi_alloc_subdevices(dev, 5); if (ret) @@ -193,24 +220,10 @@ static int apci3120_auto_attach(struct comedi_device *dev, static void apci3120_detach(struct comedi_device *dev) { - struct apci3120_private *devpriv = dev->private; - if (dev->iobase) apci3120_reset(dev); comedi_pci_detach(dev); - if (devpriv) { - unsigned int i; - - for (i = 0; i < 2; i++) { - if (devpriv->ul_DmaBufferVirtual[i]) { - dma_free_coherent(dev->hw_dev, - devpriv->ui_DmaBufferSize[i], - devpriv-> - ul_DmaBufferVirtual[i], - devpriv->ul_DmaBufferHw[i]); - } - } - } + apci3120_dma_free(dev); } static struct comedi_driver apci3120_driver = { -- GitLab From 8f83d52d305216f5d6516d11af48abfb0b44bab6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:09 -0700 Subject: [PATCH 1793/9457] staging: comedi: addi_apci_3120: introduce struct apci3120_dmabuf For aesthetics, wrap the DMA buffer information in a struct. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 85 ++++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 39 +++++---- 2 files changed, 57 insertions(+), 67 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a2db2facab70..7ed04b692301 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1003,6 +1003,8 @@ static int apci3120_cyclic_ai(int mode, } } else { /* If DMA Enabled */ + struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; + struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short); devpriv->b_InterruptMode = APCI3120_DMA_MODE; @@ -1014,8 +1016,8 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - dmalen0 = devpriv->ui_DmaBufferSize[0]; - dmalen1 = devpriv->ui_DmaBufferSize[1]; + dmalen0 = dmabuf0->size; + dmalen1 = dmabuf1->size; if (cmd->stop_src == TRIG_COUNT) { /* @@ -1050,8 +1052,8 @@ static int apci3120_cyclic_ai(int mode, if (dmalen1 > s->async->prealloc_bufsz) dmalen1 = s->async->prealloc_bufsz; } - devpriv->ui_DmaBufferUsesize[0] = dmalen0; - devpriv->ui_DmaBufferUsesize[1] = dmalen1; + dmabuf0->use_size = dmalen0; + dmabuf1->use_size = dmalen1; /* Initialize DMA */ @@ -1094,13 +1096,11 @@ static int apci3120_cyclic_ai(int mode, /* DMA Start Address Low */ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF), - devpriv->i_IobaseAddon + 2); + outw(dmabuf0->hw & 0xffff, devpriv->i_IobaseAddon + 2); /* DMA Start Address High */ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw((devpriv->ul_DmaBufferHw[0] / 65536), - devpriv->i_IobaseAddon + 2); + outw((dmabuf0->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2); /* * 4 @@ -1110,13 +1110,12 @@ static int apci3120_cyclic_ai(int mode, /* Nbr of acquisition LOW */ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF), - devpriv->i_IobaseAddon + 2); + outw(dmabuf0->use_size & 0xffff, devpriv->i_IobaseAddon + 2); /* Nbr of acquisition HIGH */ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw((devpriv->ui_DmaBufferUsesize[0] / 65536), - devpriv->i_IobaseAddon + 2); + outw((dmabuf0->use_size >> 16) & 0xffff, + devpriv->i_IobaseAddon + 2); /* * 5 @@ -1248,18 +1247,17 @@ static void apci3120_interrupt_dma(int irq, void *d) struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int next_dma_buf, samplesinbuf; - unsigned long low_word, high_word, var; + struct apci3120_dmabuf *dmabuf; + unsigned int samplesinbuf; unsigned int ui_Tmp; - samplesinbuf = - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); + dmabuf = &devpriv->dmabuf[devpriv->ui_DmaActualBuffer]; + + samplesinbuf = dmabuf->use_size - + inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); - if (samplesinbuf < - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { + if (samplesinbuf < dmabuf->use_size) dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); - } if (samplesinbuf & 1) { dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); apci3120_cancel(dev, s); @@ -1268,7 +1266,9 @@ static void apci3120_interrupt_dma(int irq, void *d) samplesinbuf = samplesinbuf >> 1; /* number of received samples */ if (devpriv->b_DmaDoubleBuffer) { /* switch DMA buffers if is used double buffering */ - next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; + struct apci3120_dmabuf *next_dmabuf; + + next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); @@ -1280,31 +1280,24 @@ static void apci3120_interrupt_dma(int irq, void *d) outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - high_word = var / 65536; - /* DMA Start Address Low */ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); + outw(next_dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2); /* DMA Start Address High */ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - high_word = var / 65536; + outw((next_dmabuf->hw >> 16) & 0xffff, + devpriv->i_IobaseAddon + 2); /* Nbr of acquisition LOW */ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); + outw(next_dmabuf->use_size & 0xffff, + devpriv->i_IobaseAddon + 2); /* Nbr of acquisition HIGH */ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); + outw((next_dmabuf->use_size > 16) & 0xffff, + devpriv->i_IobaseAddon + 2); /* * To configure A2P FIFO @@ -1319,9 +1312,8 @@ static void apci3120_interrupt_dma(int irq, void *d) } if (samplesinbuf) { - v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, - devpriv->ul_DmaBufferVirtual[devpriv-> - ui_DmaActualBuffer], samplesinbuf); + v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, dmabuf->virt, + samplesinbuf); if (!(cmd->flags & CMDF_WAKE_EOS)) s->async->events |= COMEDI_CB_EOS; @@ -1356,23 +1348,16 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - var = devpriv->ul_DmaBufferHw[0]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[0]; - high_word = var / 65536; outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); + outw(dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2); outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); + outw((dmabuf->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2); - var = devpriv->ui_DmaBufferUsesize[0]; - low_word = var & 0xffff; /* changed */ - var = devpriv->ui_DmaBufferUsesize[0]; - high_word = var / 65536; outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); + outw(dmabuf->use_size & 0xffff, devpriv->i_IobaseAddon + 2); outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); + outw((dmabuf->use_size >> 16) & 0xffff, + devpriv->i_IobaseAddon + 2); /* * To configure A2P FIFO diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 08ac390edc3f..759245b5b707 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -29,6 +29,13 @@ static const struct apci3120_board apci3120_boardtypes[] = { }, }; +struct apci3120_dmabuf { + unsigned short *virt; + dma_addr_t hw; + unsigned int size; + unsigned int use_size; +}; + struct apci3120_private { int iobase; int i_IobaseAmcc; @@ -41,10 +48,7 @@ struct apci3120_private { unsigned short us_UseDma; unsigned char b_DmaDoubleBuffer; unsigned int ui_DmaActualBuffer; - unsigned short *ul_DmaBufferVirtual[2]; - dma_addr_t ul_DmaBufferHw[2]; - unsigned int ui_DmaBufferSize[2]; - unsigned int ui_DmaBufferUsesize[2]; + struct apci3120_dmabuf dmabuf[2]; unsigned char b_DigitalOutputRegister; unsigned char b_TimerSelectMode; unsigned char b_ModeSelectRegister; @@ -64,22 +68,23 @@ struct apci3120_private { static void apci3120_dma_alloc(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; + struct apci3120_dmabuf *dmabuf; int order; int i; for (i = 0; i < 2; i++) { + dmabuf = &devpriv->dmabuf[i]; for (order = 2; order >= 0; order--) { - devpriv->ul_DmaBufferVirtual[i] = - dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order, - &devpriv->ul_DmaBufferHw[i], - GFP_KERNEL); - - if (devpriv->ul_DmaBufferVirtual[i]) + dmabuf->virt = dma_alloc_coherent(dev->hw_dev, + PAGE_SIZE << order, + &dmabuf->hw, + GFP_KERNEL); + if (dmabuf->virt) break; } - if (!devpriv->ul_DmaBufferVirtual[i]) + if (!dmabuf->virt) break; - devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order; + dmabuf->size = PAGE_SIZE << order; if (i == 0) devpriv->us_UseDma = 1; @@ -91,17 +96,17 @@ static void apci3120_dma_alloc(struct comedi_device *dev) static void apci3120_dma_free(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; + struct apci3120_dmabuf *dmabuf; int i; if (!devpriv) return; for (i = 0; i < 2; i++) { - if (devpriv->ul_DmaBufferVirtual[i]) { - dma_free_coherent(dev->hw_dev, - devpriv->ui_DmaBufferSize[i], - devpriv->ul_DmaBufferVirtual[i], - devpriv->ul_DmaBufferHw[i]); + dmabuf = &devpriv->dmabuf[i]; + if (dmabuf->virt) { + dma_free_coherent(dev->hw_dev, dmabuf->size, + dmabuf->virt, dmabuf->hw); } } } -- GitLab From 99940229e58b98c30c7d570d36cd77ed9cf29d90 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:10 -0700 Subject: [PATCH 1794/9457] staging: comedi: addi_apci_3120: remove unused struct definition The struct str_AnalogReadInformation is not used in this driver. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 7ed04b692301..e7cb66f557ee 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -200,23 +200,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY APCI3120_DISABLE_TIMER1 & \ APCI3120_DISABLE_TIMER2) -#define MAX_ANALOGINPUT_CHANNELS 32 - -struct str_AnalogReadInformation { - /* EOC or EOS */ - unsigned char b_Type; - /* Interrupt use or not */ - unsigned char b_InterruptFlag; - /* Selection of the conversion time */ - unsigned int ui_ConvertTiming; - /* Number of channel to read */ - unsigned char b_NbrOfChannel; - /* Number of the channel to be read */ - unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; - /* Gain of each channel */ - unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; -}; - /* ANALOG INPUT RANGE */ static const struct comedi_lrange range_apci3120_ai = { 8, { -- GitLab From 12d984ed512aa20b46ba16abf3c4f64c6a893fe7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:11 -0700 Subject: [PATCH 1795/9457] staging: comedi: addi_apci_3120: remove unipolar range from analog outputs The analog outputs of the APCI-3120 have a 14-bit bipolar range and use straight binary values (0x0000 = -10V to 0x3fff = +10V) to set the outputs. This driver tries to fake a unipolar range by munging the comedi data values to only output 0V to +10V signals (0x0000 to 0x1fff values are munged to 0x2000 - 0x3fff). This causes problems with the comedilib API functions that convert between comedi values and physical values. It's also possible for the user to pass a data value that would get munged and actually change the wrong channel. Fix this by change the subdevice range_table to range_bipolar10 and remove the munging in apci3120_ao_insn_write(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 31 ++----------------- .../staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index e7cb66f557ee..b9f444e36b6a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -214,16 +214,6 @@ static const struct comedi_lrange range_apci3120_ai = { } }; -/* ANALOG OUTPUT RANGE */ -static const struct comedi_lrange range_apci3120_ao = { - 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - - -/* FUNCTION DEFINITIONS */ static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -1954,29 +1944,12 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned int ui_Range, ui_Channel; + unsigned int ui_Channel; unsigned short us_TmpValue; - ui_Range = CR_RANGE(insn->chanspec); ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Range) { /* if 1 then unipolar */ - - if (data[0] != 0) - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << - 13) | (data[0] + 8191)); - else - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << - 13) | 8192); - - } else { /* if 0 then bipolar */ - data[0] = - ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) | - data[0]); - - } + data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | data[0]); do { /* Waiting of DA_READY BIT */ us_TmpValue = diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 759245b5b707..774ba7abc95d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -181,7 +181,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; s->maxdata = 0x3fff; - s->range_table = &range_apci3120_ao; + s->range_table = &range_bipolar10; s->insn_write = apci3120_ao_insn_write; } else { s->type = COMEDI_SUBD_UNUSED; -- GitLab From 82263947b1023bdb9cec39c0f8deb0c447433014 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:12 -0700 Subject: [PATCH 1796/9457] staging: comedi: addi_apci_3120: remove private data 'i_IobaseReserved' This member of the private data is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 774ba7abc95d..5a5392fe0bac 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,7 +40,6 @@ struct apci3120_private { int iobase; int i_IobaseAmcc; int i_IobaseAddon; - int i_IobaseReserved; unsigned int ui_AiActualScan; unsigned int ui_AiNbrofChannels; unsigned int ui_AiChannelList[32]; @@ -140,7 +139,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, -- GitLab From 0defecbfd24fdd78754c1a0fc1bef38adc31b408 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:13 -0700 Subject: [PATCH 1797/9457] staging: comedi: addi_apci_3120: use correct iobase to write AMCC registers The AMCC registers are accessed using the base address devpriv->i_IobaseAmcc not devpriv->i_IobaseAddon. Fix a couple writes in apci3120_interrupt_dma() that are using the wrong base address. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b9f444e36b6a..c651756f9467 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1244,7 +1244,7 @@ static void apci3120_interrupt_dma(int irq, void *d) next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); + outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); @@ -1306,7 +1306,7 @@ static void apci3120_interrupt_dma(int irq, void *d) * ADDED REINITIALISE THE DMA */ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); + outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); -- GitLab From 758cdd4a1723ae6fdeef411d4112da1bb4920f4d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:14 -0700 Subject: [PATCH 1798/9457] staging: comedi: addi_apci_3120: use correct iobase to read board register The board registers are accessed using the bse address devpriv->iobase not devpriv->i_IobaseAmcc. Fix a read in apci3120_interrupt() that is using the wrong base address. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c651756f9467..133266931ca0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1399,7 +1399,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) devpriv->b_ExttrigEnable = APCI3120_DISABLE; } /* clear the timer 2 interrupt */ - inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER); + inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); if (int_amcc & MASTER_ABORT_INT) dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); -- GitLab From 67941734d146658dc8e284b57f57abd9ad0f7c04 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:15 -0700 Subject: [PATCH 1799/9457] staging: comedi: addi_apci_3120: rename private data 'i_IobaseAddon' This member of the private data holds the start address of PCI BAR 2 that is used to access the AMCC Add-On registers. Rename this CamelCase member and fix its type. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 99 +++++++++---------- .../staging/comedi/drivers/addi_apci_3120.c | 4 +- 2 files changed, 47 insertions(+), 56 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 133266931ca0..615302c049f2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -633,13 +633,13 @@ static int apci3120_cancel(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; /* Disable A2P Fifo write and AMWEN signal */ - outw(0, devpriv->i_IobaseAddon + 4); + outw(0, devpriv->addon + 4); /* Disable Bus Master ADD ON */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(0, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(0, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); + outw(0, devpriv->addon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); + outw(0, devpriv->addon + 2); /* Disable BUS Master PCI */ outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); @@ -1039,19 +1039,17 @@ static int apci3120_cyclic_ai(int mode, /* changed since 16 bit interface for add on */ /* ENABLE BUS MASTER */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); /* * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux * driver */ - outw(0x1000, devpriv->i_IobaseAddon + 2); + outw(0x1000, devpriv->addon + 2); /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ /* 2 No change */ @@ -1068,12 +1066,12 @@ static int apci3120_cyclic_ai(int mode, */ /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(dmabuf0->hw & 0xffff, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); + outw(dmabuf0->hw & 0xffff, devpriv->addon + 2); /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw((dmabuf0->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); + outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2); /* * 4 @@ -1082,13 +1080,12 @@ static int apci3120_cyclic_ai(int mode, */ /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(dmabuf0->use_size & 0xffff, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); + outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2); /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw((dmabuf0->use_size >> 16) & 0xffff, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); + outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2); /* * 5 @@ -1122,7 +1119,7 @@ static int apci3120_cyclic_ai(int mode, /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ - outw(3, devpriv->i_IobaseAddon + 4); + outw(3, devpriv->addon + 4); /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ /* A2P FIFO RESET */ @@ -1247,37 +1244,33 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); /* 0x1000 is out putted in windows driver */ /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(next_dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); + outw(next_dmabuf->hw & 0xffff, devpriv->addon + 2); /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw((next_dmabuf->hw >> 16) & 0xffff, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); + outw((next_dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(next_dmabuf->use_size & 0xffff, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); + outw(next_dmabuf->use_size & 0xffff, devpriv->addon + 2); /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw((next_dmabuf->use_size > 16) & 0xffff, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); + outw((next_dmabuf->use_size > 16) & 0xffff, devpriv->addon + 2); /* * To configure A2P FIFO * ENABLE A2P FIFO WRITE AND ENABLE AMWEN * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 */ - outw(3, devpriv->i_IobaseAddon + 4); + outw(3, devpriv->addon + 4); /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT), @@ -1309,11 +1302,10 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); /* * A2P FIFO MANAGEMENT * A2P fifo reset & transfer control enable @@ -1321,23 +1313,22 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw((dmabuf->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); + outw(dmabuf->hw & 0xffff, devpriv->addon + 2); + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); + outw((dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(dmabuf->use_size & 0xffff, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw((dmabuf->use_size >> 16) & 0xffff, - devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); + outw(dmabuf->use_size & 0xffff, devpriv->addon + 2); + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); + outw((dmabuf->use_size >> 16) & 0xffff, devpriv->addon + 2); /* * To configure A2P FIFO * ENABLE A2P FIFO WRITE AND ENABLE AMWEN * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 */ - outw(3, devpriv->i_IobaseAddon + 4); + outw(3, devpriv->addon + 4); /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT), diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 5a5392fe0bac..e4cbc15e7df2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -39,7 +39,7 @@ struct apci3120_dmabuf { struct apci3120_private { int iobase; int i_IobaseAmcc; - int i_IobaseAddon; + unsigned long addon; unsigned int ui_AiActualScan; unsigned int ui_AiNbrofChannels; unsigned int ui_AiChannelList[32]; @@ -138,7 +138,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->addon = pci_resource_start(pcidev, 2); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, -- GitLab From 323503bfec1a0e1a310ec8e483b528f5e4b87c2d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:16 -0700 Subject: [PATCH 1800/9457] staging: comedi: addi_apci_3120: rename private data 'i_IobaseAmcc' This member of the private data holds the start address of PCI BAR 0 that is used to access the AMCC registers. Rename this CamelCase member and fix its type. Remove an unnecessary local variable, 'ui_Tmp', in apci3120_cyclic_ai() and tidy up the rest of the local variable declarations. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 61 ++++++++++--------- .../staging/comedi/drivers/addi_apci_3120.c | 4 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 615302c049f2..d6875d96d5c9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -642,7 +642,7 @@ static int apci3120_cancel(struct comedi_device *dev, outw(0, devpriv->addon + 2); /* Disable BUS Master PCI */ - outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); + outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); /* Disable ext trigger */ apci3120_exttrig_disable(dev); @@ -754,9 +754,13 @@ static int apci3120_cyclic_ai(int mode, struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned char b_Tmp; - unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = - 0, dmalen1 = 0, ui_TimerValue2 = - 0, ui_TimerValue0, ui_ConvertTiming; + unsigned int ui_DelayTiming = 0; + unsigned int ui_TimerValue1 = 0; + unsigned int dmalen0 = 0; + unsigned int dmalen1 = 0; + unsigned int ui_TimerValue2 = 0; + unsigned int ui_TimerValue0; + unsigned int ui_ConvertTiming; unsigned short us_TmpValue; /* Resets the FIFO */ @@ -771,7 +775,7 @@ static int apci3120_cyclic_ai(int mode, /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_REG_INTCSR); + devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); /* Disables All Timer */ /* Sets PR and PA to 0 */ @@ -1034,8 +1038,8 @@ static int apci3120_cyclic_ai(int mode, * Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS * register 1 */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ /* ENABLE BUS MASTER */ @@ -1055,8 +1059,8 @@ static int apci3120_cyclic_ai(int mode, /* 2 No change */ /* A2P FIFO MANAGEMENT */ /* A2P fifo reset & transfer control enable */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc + - APCI3120_AMCC_OP_MCSR); + outl(APCI3120_A2P_FIFO_MANAGEMENT, + devpriv->amcc + APCI3120_AMCC_OP_MCSR); /* * 3 @@ -1090,7 +1094,7 @@ static int apci3120_cyclic_ai(int mode, /* * 5 * To configure A2P FIFO testing outl( - * FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); + * FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR); */ /* A2P FIFO RESET */ @@ -1098,7 +1102,7 @@ static int apci3120_cyclic_ai(int mode, * TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux * driver */ - outl(0x04000000UL, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); + outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR); /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ /* @@ -1115,7 +1119,7 @@ static int apci3120_cyclic_ai(int mode, /* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); + devpriv->amcc + AMCC_OP_REG_INTCSR); /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ @@ -1124,8 +1128,7 @@ static int apci3120_cyclic_ai(int mode, /* A2P FIFO RESET */ /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - outl(0x04000000UL, - devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_MCSR); + outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR); /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ } @@ -1223,8 +1226,7 @@ static void apci3120_interrupt_dma(int irq, void *d) dmabuf = &devpriv->dmabuf[devpriv->ui_DmaActualBuffer]; - samplesinbuf = dmabuf->use_size - - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); + samplesinbuf = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); if (samplesinbuf < dmabuf->use_size) dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); @@ -1241,7 +1243,7 @@ static void apci3120_interrupt_dma(int irq, void *d) next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); + outl(ui_Tmp, devpriv->amcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); @@ -1272,9 +1274,9 @@ static void apci3120_interrupt_dma(int irq, void *d) */ outw(3, devpriv->addon + 4); /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT, + devpriv->amcc + AMCC_OP_REG_INTCSR); } if (samplesinbuf) { @@ -1298,8 +1300,8 @@ static void apci3120_interrupt_dma(int irq, void *d) * restart DMA if is not used double buffering * ADDED REINITIALISE THE DMA */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS); + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); /* changed since 16 bit interface for add on */ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); @@ -1311,7 +1313,7 @@ static void apci3120_interrupt_dma(int irq, void *d) * A2P fifo reset & transfer control enable */ outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); + devpriv->amcc + AMCC_OP_REG_MCSR); outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); outw(dmabuf->hw & 0xffff, devpriv->addon + 2); @@ -1330,9 +1332,9 @@ static void apci3120_interrupt_dma(int irq, void *d) */ outw(3, devpriv->addon + 4); /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT, + devpriv->amcc + AMCC_OP_REG_INTCSR); } } @@ -1373,14 +1375,14 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) ui_Check = 1; int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ - int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* get AMCC int register */ + int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) { dev_err(dev->class_dev, "IRQ from unknown source\n"); return IRQ_NONE; } - outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* shutdown IRQ reasons in AMCC */ + outl(int_amcc | 0x00ff0000, devpriv->amcc + AMCC_OP_REG_INTCSR); int_daq = (int_daq >> 12) & 0xF; @@ -1515,8 +1517,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->i_IobaseAmcc + - APCI3120_AMCC_OP_REG_INTCSR); + devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); /* Clears the timer status register */ inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e4cbc15e7df2..c6f3bc940d0b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -38,7 +38,7 @@ struct apci3120_dmabuf { struct apci3120_private { int iobase; - int i_IobaseAmcc; + unsigned long amcc; unsigned long addon; unsigned int ui_AiActualScan; unsigned int ui_AiNbrofChannels; @@ -137,7 +137,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->amcc = pci_resource_start(pcidev, 0); devpriv->addon = pci_resource_start(pcidev, 2); if (pcidev->irq > 0) { -- GitLab From 695f34cef33421ac89dd77e5e047e131bb3f36c0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:17 -0700 Subject: [PATCH 1801/9457] staging: comedi: addi_apci_3120: remove private data 'iobase' This member of the private data holds the start address of PCI BAR 1 that is used to access the board registers. The start address is also stored in the comedi_device 'iobase' member. Use that instead and remove the private data member. Remove some unnecessary casts when reading the board registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 144 ++++++++---------- .../staging/comedi/drivers/addi_apci_3120.c | 2 - 2 files changed, 67 insertions(+), 79 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d6875d96d5c9..0ba4b79cf515 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -347,8 +347,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, * Testing if board have the new Quartz and calculate the time value * to set in the timer */ - us_TmpValue = - (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); + us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ if ((us_TmpValue & 0x00B0) == 0x00B0 @@ -368,7 +367,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* * Testing the interrupt flag and set the EOC bit Clears the FIFO */ - inw(devpriv->iobase + APCI3120_RESET_FIFO); + inw(dev->iobase + APCI3120_RESET_FIFO); /* Initialize the sequence array */ if (!apci3120_setup_chan_list(dev, s, 1, @@ -381,7 +380,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_4; outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); + dev->iobase + APCI3120_TIMER_CRT1); /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ devpriv->b_ModeSelectRegister = @@ -396,7 +395,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT) | APCI3120_ENABLE_EOC_INT; - inw(devpriv->iobase); + inw(dev->iobase + 0); } else { devpriv->b_ModeSelectRegister = @@ -406,7 +405,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, } outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Sets gate 0 */ devpriv->us_OutputRegister = @@ -414,17 +413,17 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, us_OutputRegister & APCI3120_CLEAR_PA_PR) | APCI3120_ENABLE_TIMER0; outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); + dev->iobase + APCI3120_WR_ADDRESS); /* Select Timer 0 */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ outw(us_ConvertTiming, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); @@ -433,26 +432,25 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, do { /* Waiting for the end of conversion */ - us_TmpValue = - inw(devpriv->iobase + - APCI3120_RD_STATUS); + us_TmpValue = inw(dev->iobase + + APCI3120_RD_STATUS); } while ((us_TmpValue & APCI3120_EOC) == APCI3120_EOC); /* Read the result in FIFO and put it in insn data pointer */ - us_TmpValue = inw(devpriv->iobase + 0); + us_TmpValue = inw(dev->iobase + 0); *data = us_TmpValue; - inw(devpriv->iobase + APCI3120_RESET_FIFO); + inw(dev->iobase + APCI3120_RESET_FIFO); } break; case APCI3120_EOS_MODE: - inw(devpriv->iobase); + inw(dev->iobase + 0); /* Clears the FIFO */ - inw(devpriv->iobase + APCI3120_RESET_FIFO); + inw(dev->iobase + APCI3120_RESET_FIFO); /* clear PA PR and disable timer 0 */ devpriv->us_OutputRegister = @@ -461,7 +459,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, APCI3120_DISABLE_TIMER0; outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); + dev->iobase + APCI3120_WR_ADDRESS); if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, @@ -474,24 +472,24 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2; outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); + dev->iobase + APCI3120_TIMER_CRT1); /* Select Timer 0 */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ outw(us_ConvertTiming, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* Set the scan bit */ devpriv->b_ModeSelectRegister = devpriv-> b_ModeSelectRegister | APCI3120_ENABLE_SCAN; outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); /* If Interrupt function is loaded */ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { @@ -501,7 +499,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | APCI3120_ENABLE_EOS_INT; - inw(devpriv->iobase); + inw(dev->iobase + 0); } else devpriv->b_ModeSelectRegister = @@ -510,34 +508,33 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER; outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); - inw(devpriv->iobase + APCI3120_RD_STATUS); + inw(dev->iobase + APCI3120_RD_STATUS); /* Sets gate 0 */ devpriv->us_OutputRegister = devpriv-> us_OutputRegister | APCI3120_ENABLE_TIMER0; outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); + dev->iobase + APCI3120_WR_ADDRESS); /* Start conversion */ - outw(0, devpriv->iobase + APCI3120_START_CONVERSION); + outw(0, dev->iobase + APCI3120_START_CONVERSION); /* Waiting of end of conversion if interrupt is not installed */ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { /* Waiting the end of conversion */ do { - us_TmpValue = - inw(devpriv->iobase + - APCI3120_RD_STATUS); + us_TmpValue = inw(dev->iobase + + APCI3120_RD_STATUS); } while ((us_TmpValue & APCI3120_EOS) != APCI3120_EOS); for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { /* Read the result in FIFO and write them in shared memory */ - us_TmpValue = inw(devpriv->iobase); + us_TmpValue = inw(dev->iobase); data[i] = (unsigned int) us_TmpValue; } @@ -787,7 +784,7 @@ static int apci3120_cyclic_ai(int mode, /* Resets the FIFO */ /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - inb(devpriv->iobase + APCI3120_RESET_FIFO); + inb(dev->iobase + APCI3120_RESET_FIFO); /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ devpriv->ui_AiActualScan = 0; @@ -1392,7 +1389,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) devpriv->b_ExttrigEnable = APCI3120_DISABLE; } /* clear the timer 2 interrupt */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); + inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); if (int_amcc & MASTER_ABORT_INT) dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); @@ -1405,8 +1402,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* Read the AI Value */ - devpriv->ui_AiReadData[0] = - (unsigned int) inw(devpriv->iobase + 0); + devpriv->ui_AiReadData[0] = inw(dev->iobase + 0); devpriv->b_EocEosInterrupt = APCI3120_DISABLE; send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ } else { @@ -1415,8 +1411,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) devpriv-> b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT; outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); - + dev->iobase + APCI3120_WRITE_MODE_SELECT); } } @@ -1440,7 +1435,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) ui_Check = 0; for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { - us_TmpValue = inw(devpriv->iobase + 0); + us_TmpValue = inw(dev->iobase + 0); devpriv->ui_AiReadData[i] = (unsigned int) us_TmpValue; } @@ -1562,7 +1557,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, ui_Timervalue2 = data[1] / 1000; /* convert nano seconds to u seconds */ - us_TmpValue = (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); + us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); /* * EL250804: Testing if board APCI3120 have the new Quartz or if it @@ -1580,7 +1575,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ devpriv->us_OutputRegister = devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2; - outw(devpriv->us_OutputRegister, devpriv->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); /* Disable TIMER Interrupt */ devpriv->b_ModeSelectRegister = @@ -1593,14 +1588,14 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ devpriv->b_TimerSelectMode = (devpriv-> b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2; outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); + dev->iobase + APCI3120_TIMER_CRT1); /* * Configure the timer 2 for writing the LOW unsigned short of timer @@ -1614,17 +1609,17 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* timer2 in Timer mode enabled */ devpriv->b_Timer2Mode = APCI3120_TIMER; @@ -1635,7 +1630,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, (devpriv-> b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5; outb(devpriv->b_TimerSelectMode, - devpriv->iobase + APCI3120_TIMER_CRT1); + dev->iobase + APCI3120_TIMER_CRT1); /* * Configure the timer 2 for writing the LOW unsigned short of timer @@ -1649,18 +1644,18 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* watchdog enabled */ devpriv->b_Timer2Mode = APCI3120_WATCHDOG; @@ -1715,7 +1710,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, case APCI3120_START: /* Reset FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); + inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* Enable Timer */ devpriv->b_ModeSelectRegister = @@ -1745,7 +1740,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, APCI3120_DISABLE_TIMER_INT; } outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* For Timer mode is Gate2 must be activated timer started */ @@ -1753,7 +1748,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, devpriv-> us_OutputRegister | APCI3120_ENABLE_TIMER2; outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); + dev->iobase + APCI3120_WR_ADDRESS); } break; @@ -1779,16 +1774,16 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, /* Write above states to register */ outb(devpriv->b_ModeSelectRegister, - devpriv->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Reset Gate 2 */ devpriv->us_OutputRegister = devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT; outw(devpriv->us_OutputRegister, - devpriv->iobase + APCI3120_WR_ADDRESS); + dev->iobase + APCI3120_WR_ADDRESS); /* Reset FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); + inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); break; @@ -1798,8 +1793,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, "timer2 not configured in TIMER MODE\n"); return -EINVAL; } - us_TmpValue = - (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); + us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); /* * EL250804: Testing if board APCI3120 have the new Quartz or if it @@ -1817,19 +1811,19 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(ui_Timervalue2 & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw((ui_Timervalue2 >> 16) & 0xffff, - devpriv->iobase + APCI3120_TIMER_VALUE); + dev->iobase + APCI3120_TIMER_VALUE); break; default: @@ -1866,29 +1860,29 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - us_TmpValue = inw(devpriv->iobase + APCI3120_TIMER_VALUE); + us_TmpValue = inw(dev->iobase + APCI3120_TIMER_VALUE); /* Read the HIGH unsigned short of Timer 2 register */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); + outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - us_TmpValue_2 = inw(devpriv->iobase + APCI3120_TIMER_VALUE); + us_TmpValue_2 = inw(dev->iobase + APCI3120_TIMER_VALUE); /* combining both words */ data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); } else { /* Read watch dog status */ - us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS); + us_StatusValue = inw(dev->iobase + APCI3120_RD_STATUS); us_StatusValue = ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1; if (us_StatusValue == 1) { /* RESET FC_TIMER BIT */ - inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); + inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); } data[0] = us_StatusValue; /* when data[0] = 1 then the watch dog has rundown */ } @@ -1900,11 +1894,10 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct apci3120_private *devpriv = dev->private; unsigned int val; /* the input channels are bits 11:8 of the status reg */ - val = inw(devpriv->iobase + APCI3120_RD_STATUS); + val = inw(dev->iobase + APCI3120_RD_STATUS); data[1] = (val >> 8) & 0xf; return insn->n; @@ -1922,7 +1915,7 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, devpriv->b_DigitalOutputRegister = s->state << 4; outb(devpriv->b_DigitalOutputRegister, - devpriv->iobase + APCI3120_DIGITAL_OUTPUT); + dev->iobase + APCI3120_DIGITAL_OUTPUT); } data[1] = s->state; @@ -1935,7 +1928,6 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct apci3120_private *devpriv = dev->private; unsigned int ui_Channel; unsigned short us_TmpValue; @@ -1944,9 +1936,7 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | data[0]); do { /* Waiting of DA_READY BIT */ - us_TmpValue = - ((unsigned short) inw(devpriv->iobase + - APCI3120_RD_STATUS)) & 0x0001; + us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS) & 0x0001; } while (us_TmpValue != 0x0001); if (ui_Channel <= 3) @@ -1955,14 +1945,14 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, * typecasted to ushort since word write is to be done */ outw((unsigned short) data[0], - devpriv->iobase + APCI3120_ANALOG_OUTPUT_1); + dev->iobase + APCI3120_ANALOG_OUTPUT_1); else /* * for channel 4-7 out at the register 2 (wrDac5-8) data[i] * typecasted to ushort since word write is to be done */ outw((unsigned short) data[0], - devpriv->iobase + APCI3120_ANALOG_OUTPUT_2); + dev->iobase + APCI3120_ANALOG_OUTPUT_2); return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c6f3bc940d0b..6b4a51db9c9e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -37,7 +37,6 @@ struct apci3120_dmabuf { }; struct apci3120_private { - int iobase; unsigned long amcc; unsigned long addon; unsigned int ui_AiActualScan; @@ -136,7 +135,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, pci_set_master(pcidev); dev->iobase = pci_resource_start(pcidev, 1); - devpriv->iobase = dev->iobase; devpriv->amcc = pci_resource_start(pcidev, 0); devpriv->addon = pci_resource_start(pcidev, 2); -- GitLab From ce987a8a8f86c063c6332da83dfa514a1582c2f3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:18 -0700 Subject: [PATCH 1802/9457] staging: comedi: addi_apci_3120: prevent deadlock in apci3120_ao_insn_write() The DA_READY bit (0x0001) in the status register needs to be set before the analog outputs can be updated. Use comedi_timeout() to prevent a deadlock condition while waiting for the DA_READY bit to get set. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0ba4b79cf515..b6c11fed957c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1923,21 +1923,34 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, return insn->n; } +static int apci3120_ao_ready(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_RD_STATUS); + if (status & 0x0001) /* waiting for DA_READY */ + return 0; + return -EBUSY; +} + static int apci3120_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int ui_Channel; - unsigned short us_TmpValue; + int ret; ui_Channel = CR_CHAN(insn->chanspec); data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | data[0]); - do { /* Waiting of DA_READY BIT */ - us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS) & 0x0001; - } while (us_TmpValue != 0x0001); + ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); + if (ret) + return ret; if (ui_Channel <= 3) /* -- GitLab From b9ae204658334a4a34a60dd2de6ba0415b3a79d4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:19 -0700 Subject: [PATCH 1803/9457] staging: comedi: addi_apci_3120: remove analog output reset The apci3120_reset() function is called at the end of the (*auto_attach) and with the (*detach) is called to unload the driver. Part of this function resets all the analog output channels to 0V. There are two problems with this. 1) Only the APCI-3120 has analog outputs, the APCI-3001 does not. 2) The DA_READY bit in the status register needs to be checked before each write to update the analog outputs. It's unknown what the DA_READY bit does on the APCI-3001 board. Just remove the analog output reset to avoid any problems. Also, remove the unnecessary udelay() in apci3120_reset(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b6c11fed957c..fbe17917cea1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -40,8 +40,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY +----------+-----------+------------------------------------------------+ */ -#include - /* * ADDON RELATED ADDITIONS */ @@ -578,22 +576,6 @@ static int apci3120_reset(struct comedi_device *dev) devpriv->us_OutputRegister = 0; outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - /* - * Code to set the all anolog o/p channel to 0v 8191 is decimal - * value for zero(0 v)volt in bipolar mode(default) - */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ - - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ - - udelay(10); - inw(dev->iobase + 0); /* make a dummy read */ inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ -- GitLab From 6174801d7e9ff27b3a589fe766f4cd75de14c31b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:20 -0700 Subject: [PATCH 1804/9457] staging: comedi: addi_apci_3120: fix apci3120_ao_insn_write() The comedi core expects (*insn_write) functions to write insn->n values and return the number of values written or an errno. This function currently returns insn->n but it only writes a single data value. Fix the function to work like the core expects. There are two registers used to update the analog outputs. Offset 0x08 is used to update channels 0-3 and offset 0x0a to update channels 4-7. Bits 14 and 15 in each register set the mux to select which channel to update. The lower 14 bits are the value used to set the DAC. For aesthetics, tidy up the defines used for the register offsets and bits in the registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 45 +++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 16 +++++++ 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index fbe17917cea1..47b1741758d1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -96,24 +96,12 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_SET4DIGITALOUTPUTON 1 #define APCI3120_SET4DIGITALOUTPUTOFF 0 -/* analog output SELECT BIT */ -#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000 -#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000 - /* Enable external trigger bit in nWrAddress */ #define APCI3120_ENABLE_EXT_TRIGGER 0x8000 /* ANALOG OUTPUT AND INPUT DEFINE */ #define APCI3120_UNIPOLAR 0x80 #define APCI3120_BIPOLAR 0x00 -#define APCI3120_ANALOG_OUTPUT_1 0x08 -#define APCI3120_ANALOG_OUTPUT_2 0x0a #define APCI3120_1_GAIN 0x00 #define APCI3120_2_GAIN 0x10 #define APCI3120_5_GAIN 0x20 @@ -1923,31 +1911,20 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int ui_Channel; - int ret; - - ui_Channel = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); + int i; - data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | data[0]); + for (i = 0; i < insn->n; i++) { + unsigned int val = data[i]; + int ret; - ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); - if (ret) - return ret; + ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); + if (ret) + return ret; - if (ui_Channel <= 3) - /* - * for channel 0-3 out at the register 1 (wrDac1-8) data[i] - * typecasted to ushort since word write is to be done - */ - outw((unsigned short) data[0], - dev->iobase + APCI3120_ANALOG_OUTPUT_1); - else - /* - * for channel 4-7 out at the register 2 (wrDac5-8) data[i] - * typecasted to ushort since word write is to be done - */ - outw((unsigned short) data[0], - dev->iobase + APCI3120_ANALOG_OUTPUT_2); + outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), + dev->iobase + APCI3120_AO_REG(chan)); + } return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6b4a51db9c9e..abc85bf000ff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -7,6 +7,22 @@ #include "comedi_fc.h" #include "amcc_s5933.h" +/* + * PCI BAR 0 register map (devpriv->amcc) + * see amcc_s5933.h for register and bit defines + */ + +/* + * PCI BAR 1 register map (dev->iobase) + */ +#define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) +#define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) +#define APCI3120_AO_DATA(x) ((x) << 0) + +/* + * PCI BAR 2 register map (devpriv->addon) + */ + enum apci3120_boardid { BOARD_APCI3120, BOARD_APCI3001, -- GitLab From bf34c2262270bc4d7e1d7747a15675942a5dd9c4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:21 -0700 Subject: [PATCH 1805/9457] staging: comedi: addi_apci_3120: provide analog output 'readback' Use the comedi_subdevice 'readback' member and the core provided (*insn_read) function to provide radback of the analog output channels. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 ++ drivers/staging/comedi/drivers/addi_apci_3120.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 47b1741758d1..c093cd4bce3d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1924,6 +1924,8 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), dev->iobase + APCI3120_AO_REG(chan)); + + s->readback[chan] = val; } return insn->n; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index abc85bf000ff..5db52cd04319 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -195,6 +195,11 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->maxdata = 0x3fff; s->range_table = &range_bipolar10; s->insn_write = apci3120_ao_insn_write; + s->insn_read = comedi_readback_insn_read; + + ret = comedi_alloc_subdev_readback(s); + if (ret) + return ret; } else { s->type = COMEDI_SUBD_UNUSED; } -- GitLab From f6dc93082613dbc89f03b85539cf6cf3eda2f073 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:22 -0700 Subject: [PATCH 1806/9457] staging: comedi: addi_apci_3120: tidy up analog output subdevice init For aesthetics, add some white space to the analog output subdevice initialization. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_3120.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 5db52cd04319..8cd3ef13536e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -186,22 +186,22 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->do_cmd = apci3120_ai_cmd; s->cancel = apci3120_cancel; - /* Allocate and Initialise AO Subdevice Structures */ + /* Analog Output subdevice */ s = &dev->subdevices[1]; if (this_board->has_ao) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 8; - s->maxdata = 0x3fff; - s->range_table = &range_bipolar10; - s->insn_write = apci3120_ao_insn_write; - s->insn_read = comedi_readback_insn_read; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 8; + s->maxdata = 0x3fff; + s->range_table = &range_bipolar10; + s->insn_write = apci3120_ao_insn_write; + s->insn_read = comedi_readback_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DI Subdevice Structures */ -- GitLab From dc842931be5a8d8a2a2441e6c762b93b7aaaecbf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:23 -0700 Subject: [PATCH 1807/9457] staging: comedi: addi_apci_3120: tidy up digital input subdevice init For aesthetics, add some white space to the digital input subdevice initialization. Remove the subdev_flags SDF_GROUND and SDF_COMMON. These only apply to analog subdevices. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 8cd3ef13536e..b0d62cd475e1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -204,14 +204,14 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise DI Subdevice Structures */ + /* Digital Input subdevice */ s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = apci3120_di_insn_bits; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci3120_di_insn_bits; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; -- GitLab From 1bed58e3b6c02614aeb14dea58e1f12ec79a9d17 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:24 -0700 Subject: [PATCH 1808/9457] staging: comedi: addi_apci_3120: tidy up digital output subdevice init For aesthetics, add some white space to the digital output subdevice initialization. Remove the subdev_flags SDF_GROUND and SDF_COMMON. These only apply to analog subdevices. Also remove the unnecessary SDF_READABLE subdev_flag. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index b0d62cd475e1..358bfd3f3417 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -213,15 +213,14 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = apci3120_di_insn_bits; - /* Allocate and Initialise DO Subdevice Structures */ + /* Digital Output subdevice */ s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = apci3120_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci3120_do_insn_bits; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- GitLab From 2a420f408aa73759b61446503adbd83c88e33966 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:25 -0700 Subject: [PATCH 1809/9457] staging: comedi: addi_apci_3120: tidy up analog input subdevice init For aesthetics, add some white space to the analog input subdevice initialization. The async command support in this driver is pretty messed up. I'm not really sure if it actually works yet. Luckly this driver was not setting the SDF_CMD_READ subdev_flag so the command support was not actually getting enabled. The command support only works if an interrupt is available. Refactor the subdevice init so that the command support is only hooked up if we have an interrupt. For now always disable the command support. Once the driver has been cleaned up the command will be enabled. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_3120.c | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 358bfd3f3417..cc561788e740 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -168,23 +168,23 @@ static int apci3120_auto_attach(struct comedi_device *dev, if (ret) return ret; - /* Allocate and Initialise AI Subdevice Structures */ + /* Analog Input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - s->n_chan = 16; - s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; - s->len_chanlist = s->n_chan; - s->range_table = &range_apci3120_ai; - - s->insn_config = apci3120_ai_insn_config; - s->insn_read = apci3120_ai_insn_read; - s->do_cmdtest = apci3120_ai_cmdtest; - s->do_cmd = apci3120_ai_cmd; - s->cancel = apci3120_cancel; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; + s->n_chan = 16; + s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; + s->range_table = &range_apci3120_ai; + s->insn_config = apci3120_ai_insn_config; + s->insn_read = apci3120_ai_insn_read; + if (0 /* dev->irq */) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmdtest = apci3120_ai_cmdtest; + s->do_cmd = apci3120_ai_cmd; + s->cancel = apci3120_cancel; + } /* Analog Output subdevice */ s = &dev->subdevices[1]; -- GitLab From 758505199e89de48374ed1c8618f95c218e9cd6f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:26 -0700 Subject: [PATCH 1810/9457] staging: comedi: addi_apci_3120: tidy up timer subdevice init It appears that this subdevice is actually broken. The subdevice functions all violate the comedi API and, it they did work, it appears they would break the analog input async commands. For now just tidy up the subdevice init. Add the SDF_READABLE subdev_flag, this subdevice provides an (*insn_read). Fix the subdevice 'maxdata' initialization. The timer is 24-bits. Remove the 'len_chanlist' initialization. This member is only used by subdevices that support async commands. Also remove the 'range_table' initialization. The core will set it to range_unknown which is appropriate. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi_apci_3120.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index cc561788e740..ec6f89b9e99c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -222,18 +222,15 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = apci3120_do_insn_bits; - /* Allocate and Initialise Timer Subdevice Structures */ + /* Timer subdevice */ s = &dev->subdevices[4]; - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = apci3120_write_insn_timer; - s->insn_read = apci3120_read_insn_timer; - s->insn_config = apci3120_config_insn_timer; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_READABLE; + s->n_chan = 1; + s->maxdata = 0x00ffffff; + s->insn_write = apci3120_write_insn_timer; + s->insn_read = apci3120_read_insn_timer; + s->insn_config = apci3120_config_insn_timer; apci3120_reset(dev); return 0; -- GitLab From 73ef19314649fbd915d39c04de5057ece3b604e4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:27 -0700 Subject: [PATCH 1811/9457] staging: comedi: addi_apci_3120: reset the board before hooking up the interrupt Move the apci3120_reset() call in the (*auto_attach) to ensure that the board is reset before hooking up the interrupt. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ec6f89b9e99c..3b4fa2ebbc85 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -154,6 +154,8 @@ static int apci3120_auto_attach(struct comedi_device *dev, devpriv->amcc = pci_resource_start(pcidev, 0); devpriv->addon = pci_resource_start(pcidev, 2); + apci3120_reset(dev); + if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED, dev->board_name, dev); @@ -232,7 +234,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->insn_read = apci3120_read_insn_timer; s->insn_config = apci3120_config_insn_timer; - apci3120_reset(dev); return 0; } -- GitLab From a2eb0fd71c7729625bd5d7168c01f89a8d51af37 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:28 -0700 Subject: [PATCH 1812/9457] staging: comedi: addi_apci_3120: don't reset board when canceling ai command The analog input (*cancel) stops the async command. There is not reason to also call the board reset function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c093cd4bce3d..10deb72a4b37 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -635,7 +635,7 @@ static int apci3120_cancel(struct comedi_device *dev, devpriv->ai_running = 0; devpriv->b_InterruptMode = APCI3120_EOC_MODE; devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - apci3120_reset(dev); + return 0; } -- GitLab From 22be3f81429608aad8229ee60e8f834024291f09 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:29 -0700 Subject: [PATCH 1813/9457] staging: comedi: addi_apci_3120: don't reset board when detaching driver The comedi core calls all the subdevice (*cancel) functions before it does the driver (*detach). There is no reason to call the board reset function in the (*detach). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3b4fa2ebbc85..e5dbbdf33b40 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -239,8 +239,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, static void apci3120_detach(struct comedi_device *dev) { - if (dev->iobase) - apci3120_reset(dev); comedi_pci_detach(dev); apci3120_dma_free(dev); } -- GitLab From 4455d7c351dada63ec031a82760fa00d7806139a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:34 -0700 Subject: [PATCH 1814/9457] staging: comedi: comedi_buf: introduce comedi_buf_read_samples() Introduce a generic method to read samples from the async buffer. The number of requested samples is clampled to the number of samples that would fill the async buffer. The size of each sample is determined using the bytes_per_sample() helper. The number of bytes need are then read from the async buffer using comedi_read_array_from_buffer(). This will allow converting all the comedi drivers to use a common method to read data from the async buffer. Since comedi_read_array_from_buffer() sets the COMEDI_CB_BLOCK event after reading the data, those events can be removed from the drivers. In addition, comedi_inc_scan_progress() will automatically detect the end of scan and set the COMEDI_CB_EOS event. Those events can also be removed from the drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 27 +++++++++++++++++++++++++++ drivers/staging/comedi/comedidev.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c60a45ad12b9..88a7cae97811 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -575,3 +575,30 @@ unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, return num_bytes; } EXPORT_SYMBOL_GPL(comedi_read_array_from_buffer); + +/** + * comedi_buf_read_samples - read sample data from comedi buffer + * @s: comedi_subdevice struct + * @data: destination + * @nsamples: maximum number of samples to read + * + * Reads up to nsamples from the comedi buffer associated with the subdevice, + * marks it as read and updates the acquisition scan progress. + * + * Returns the amount of data read in bytes. + */ +unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples) +{ + unsigned int max_samples; + unsigned int nbytes; + + max_samples = s->async->prealloc_bufsz / bytes_per_sample(s); + if (nsamples > max_samples) + nsamples = max_samples; + + nbytes = nsamples * bytes_per_sample(s); + + return comedi_read_array_from_buffer(s, data, nbytes); +} +EXPORT_SYMBOL_GPL(comedi_buf_read_samples); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index fb8ff84dab35..ba4084bd5ed8 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -453,6 +453,8 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, unsigned int num_bytes); unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, void *data, unsigned int num_bytes); +unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples); /* drivers.c - general comedi driver functions */ -- GitLab From bcdbe8848e8dbcd0bee3fcfa86c08f16c9730a15 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:35 -0700 Subject: [PATCH 1815/9457] staging: comedi: amplc_pci224: use comedi_buf_read_samples() Use the new generic method to read the analog output samples from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 9fcf6f77c96e..342779f1f84a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -514,14 +514,13 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, { struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int bytes_per_scan = comedi_bytes_per_scan(s); unsigned int num_scans; unsigned int room; unsigned short dacstat; unsigned int i, n; /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / bytes_per_scan; + num_scans = comedi_buf_read_n_available(s) / comedi_bytes_per_scan(s); if (cmd->stop_src == TRIG_COUNT) { /* Fixed number of scans. */ if (num_scans > devpriv->ao_stop_count) @@ -568,8 +567,8 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, /* Process scans. */ for (n = 0; n < num_scans; n++) { - cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0], - bytes_per_scan); + comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0], + cmd->chanlist_len); for (i = 0; i < cmd->chanlist_len; i++) { outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]], dev->iobase + PCI224_DACDATA); -- GitLab From 2cc9854caf92526199935bc29685e253349362bc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:36 -0700 Subject: [PATCH 1816/9457] staging: comedi: cb_pcidas: introduce cb_pcidas_ao_load_fifo() Introduce a helper function to load the analog output FIFO. This fixes a bug in cb_pcidas_ao_inttrig(). That function was writing 'num_bytes' data values to the FIFO instead of 'num_points'. This results in twice the number of data values getting written to the FIFO. Use comedi_buf_read_samples() read the analog output samples from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 54 +++++++++------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e7ab6bcfa90b..a0d462fecf20 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1134,32 +1134,39 @@ static int cb_pcidas_cancel(struct comedi_device *dev, return 0; } +static void cb_pcidas_ao_load_fifo(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int nsamples) +{ + struct cb_pcidas_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nbytes; + + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples) + nsamples = devpriv->ao_count; + + nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples); + nsamples = nbytes / bytes_per_sample(s); + if (cmd->stop_src == TRIG_COUNT) + devpriv->ao_count -= nsamples; + + outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples); +} + static int cb_pcidas_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { const struct cb_pcidas_board *thisboard = dev->board_ptr; struct cb_pcidas_private *devpriv = dev->private; - unsigned int num_bytes, num_points = thisboard->fifo_size; struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_cmd *cmd = &async->cmd; unsigned long flags; if (trig_num != cmd->start_arg) return -EINVAL; - /* load up fifo */ - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) - num_points = devpriv->ao_count; - - num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, - num_points * sizeof(short)); - num_points = num_bytes / sizeof(short); - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= num_points; - /* write data to board's fifo */ - outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); + cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size); /* enable dac half-full and empty interrupts */ spin_lock_irqsave(&dev->spinlock, flags); @@ -1275,8 +1282,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) struct comedi_subdevice *s = dev->write_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int half_fifo = thisboard->fifo_size / 2; - unsigned int num_points; unsigned long flags; if (status & DAEMI) { @@ -1295,23 +1300,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) async->events |= COMEDI_CB_EOA; } } else if (status & DAHFI) { - unsigned int num_bytes; + cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2); - /* figure out how many points we are writing to fifo */ - num_points = half_fifo; - if (cmd->stop_src == TRIG_COUNT && - devpriv->ao_count < num_points) - num_points = devpriv->ao_count; - num_bytes = - cfc_read_array_from_buffer(s, devpriv->ao_buffer, - num_points * sizeof(short)); - num_points = num_bytes / sizeof(short); - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= num_points; - /* write data to board's fifo */ - outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, - num_points); /* clear half-full interrupt latch */ spin_lock_irqsave(&dev->spinlock, flags); outw(devpriv->adc_fifo_bits | DAHFI, -- GitLab From 7bd7d905629a8748fa43d20b930213f54ac9177d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:37 -0700 Subject: [PATCH 1817/9457] staging: comedi: cb_pcidas: introduce cb_pcidas64_ao_fill_buffer() Introduce a helper function to read the analog output samples from the async buffer. This fixes a bug in load_ao_dma_buffer(). That function was decrementing the 'ao_count' by the number of bytes, not the number of samples, that were read from the async buffer. Use comedi_buf_read_samples() to read the analog output samples from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 79 ++++++++++++-------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index eafbe9f56060..06e846f38992 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2912,32 +2912,46 @@ static void restart_ao_dma(struct comedi_device *dev) dma_start_sync(dev, 0); } +static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned short *dest, + unsigned int max_bytes) +{ + struct pcidas64_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nsamples = max_bytes / bytes_per_sample(s); + unsigned int actual_bytes; + + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples) + nsamples = devpriv->ao_count; + + actual_bytes = comedi_buf_read_samples(s, dest, nsamples); + nsamples = actual_bytes / bytes_per_sample(s); + if (cmd->stop_src == TRIG_COUNT) + devpriv->ao_count -= nsamples; + + return nsamples; +} + static unsigned int load_ao_dma_buffer(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes, buffer_index, prev_buffer_index; + struct comedi_subdevice *s = dev->write_subdev; + unsigned int buffer_index = devpriv->ao_dma_index; + unsigned int prev_buffer_index = prev_ao_dma_index(dev); + unsigned int nsamples; + unsigned int nbytes; unsigned int next_bits; - buffer_index = devpriv->ao_dma_index; - prev_buffer_index = prev_ao_dma_index(dev); - - num_bytes = comedi_buf_read_n_available(dev->write_subdev); - if (num_bytes > DMA_BUFFER_SIZE) - num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) - num_bytes = devpriv->ao_count; - num_bytes -= num_bytes % bytes_in_sample; - - if (num_bytes == 0) + nsamples = cb_pcidas64_ao_fill_buffer(dev, s, + devpriv->ao_buffer[buffer_index], + DMA_BUFFER_SIZE); + if (nsamples == 0) return 0; - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv-> - ao_buffer[buffer_index], - num_bytes); - devpriv->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); + nbytes = nsamples * bytes_per_sample(s); + devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes); /* set end of chain bit so we catch underruns */ next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); next_bits |= PLX_END_OF_CHAIN_BIT; @@ -2949,9 +2963,8 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - devpriv->ao_count -= num_bytes; - return num_bytes; + return nbytes; } static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) @@ -3191,7 +3204,9 @@ static void set_dac_interval_regs(struct comedi_device *dev, static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes; + struct comedi_subdevice *s = dev->write_subdev; + unsigned int nsamples; + unsigned int nbytes; int i; /* clear queue pointer too, since external queue has @@ -3199,22 +3214,22 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); - num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && - num_bytes / bytes_in_sample > devpriv->ao_count) - num_bytes = devpriv->ao_count * bytes_in_sample; - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv->ao_bounce_buffer, - num_bytes); - for (i = 0; i < num_bytes / bytes_in_sample; i++) { + nsamples = cb_pcidas64_ao_fill_buffer(dev, s, + devpriv->ao_bounce_buffer, + DAC_FIFO_SIZE); + if (nsamples == 0) + return -1; + + for (i = 0; i < nsamples; i++) { writew(devpriv->ao_bounce_buffer[i], devpriv->main_iobase + DAC_FIFO_REG); } - devpriv->ao_count -= num_bytes / bytes_in_sample; + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) return 0; - num_bytes = load_ao_dma_buffer(dev, cmd); - if (num_bytes == 0) + + nbytes = load_ao_dma_buffer(dev, cmd); + if (nbytes == 0) return -1; load_ao_dma(dev, cmd); -- GitLab From ecb11d8c28aa7fe761467873e69a3c5c66b57aed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:38 -0700 Subject: [PATCH 1818/9457] staging: comedi: dt282x: introduce dt282x_ao_setup_dma() Introduce a helper function to read the analog output samples from the async buffer and prep the DMA. Use comedi_buf_read_samples() to read the analog output samples from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index f23d883f2544..88b56104d4e7 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -449,13 +449,29 @@ static void dt282x_munge(struct comedi_device *dev, } } +static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev, + struct comedi_subdevice *s, + int cur_dma) +{ + struct dt282x_private *devpriv = dev->private; + void *ptr = devpriv->dma[cur_dma].buf; + unsigned int nsamples = devpriv->dma_maxsize / bytes_per_sample(s); + unsigned int nbytes; + + nbytes = comedi_buf_read_samples(s, ptr, nsamples); + if (nbytes) + dt282x_prep_ao_dma(dev, cur_dma, nbytes); + else + dev_err(dev->class_dev, "AO underrun\n"); + + return nbytes; +} + static void dt282x_ao_dma_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { struct dt282x_private *devpriv = dev->private; int cur_dma = devpriv->current_dma_index; - void *ptr = devpriv->dma[cur_dma].buf; - int size; outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, dev->iobase + DT2821_SUPCSR_REG); @@ -464,13 +480,8 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev, devpriv->current_dma_index = 1 - cur_dma; - size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, cur_dma)) s->async->events |= COMEDI_CB_OVERFLOW; - } else { - dt282x_prep_ao_dma(dev, cur_dma, size); - } } static void dt282x_ai_dma_interrupt(struct comedi_device *dev, @@ -916,26 +927,15 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, { struct dt282x_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - int size; if (trig_num != cmd->start_src) return -EINVAL; - size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf, - devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, 0)) return -EPIPE; - } - dt282x_prep_ao_dma(dev, 0, size); - size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf, - devpriv->dma_maxsize); - if (size == 0) { - dev_err(dev->class_dev, "AO underrun\n"); + if (!dt282x_ao_setup_dma(dev, s, 1)) return -EPIPE; - } - dt282x_prep_ao_dma(dev, 1, size); outw(devpriv->supcsr | DT2821_SUPCSR_STRIG, dev->iobase + DT2821_SUPCSR_REG); -- GitLab From 65ad7c89aa4d376419a134ffe69113db0333d25f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:39 -0700 Subject: [PATCH 1819/9457] staging: comedi: comedi_fc.h: remove cfc_read_array_from_buffer() This inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 0f4b360cf9ec..fed0a54e5af6 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -42,13 +42,6 @@ static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *s, return comedi_write_array_to_buffer(s, &data, sizeof(data)); }; -static inline unsigned int -cfc_read_array_from_buffer(struct comedi_subdevice *s, void *data, - unsigned int num_bytes) -{ - return comedi_read_array_from_buffer(s, data, num_bytes); -} - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate -- GitLab From 2b3e13b8605ee0915804ce73d6e5e4e72fc51ba2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:40 -0700 Subject: [PATCH 1820/9457] staging: comedi: comedi_buf: remove export of comedi_read_array_from_buffer() This function is only used internally. Remove the export. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 17 +++-------------- drivers/staging/comedi/comedidev.h | 2 -- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 88a7cae97811..d1303a831462 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -549,19 +549,9 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); -/** - * comedi_read_array_from_buffer - read data from comedi buffer - * @s: comedi_subdevice struct - * @data: destination - * @num_bytes: number of bytes to read - * - * Reads up to num_bytes bytes of data from the comedi buffer associated with - * the subdevice, marks it as read and updates the acquisition scan progress. - * - * Returns the amount of data read in bytes. - */ -unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, unsigned int num_bytes) +static unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, + void *data, + unsigned int num_bytes) { if (num_bytes == 0) return 0; @@ -574,7 +564,6 @@ unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, return num_bytes; } -EXPORT_SYMBOL_GPL(comedi_read_array_from_buffer); /** * comedi_buf_read_samples - read sample data from comedi buffer diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index ba4084bd5ed8..766387dcab95 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -451,8 +451,6 @@ void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes); -unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, unsigned int num_bytes); unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, void *data, unsigned int nsamples); -- GitLab From 109bf06e2a88a04607c93d8223e4be0af09ebc8c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:41 -0700 Subject: [PATCH 1821/9457] staging: comedi: comedi_buf: absorb comedi_read_array_from_buffer() This function is only called by comedi_buf_read_samples(). Absorb it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index d1303a831462..9074da2cbe0a 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -549,22 +549,6 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); -static unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, - unsigned int num_bytes) -{ - if (num_bytes == 0) - return 0; - - num_bytes = comedi_buf_read_alloc(s, num_bytes); - comedi_buf_memcpy_from(s, 0, data, num_bytes); - comedi_buf_read_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); - s->async->events |= COMEDI_CB_BLOCK; - - return num_bytes; -} - /** * comedi_buf_read_samples - read sample data from comedi buffer * @s: comedi_subdevice struct @@ -587,7 +571,15 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, nsamples = max_samples; nbytes = nsamples * bytes_per_sample(s); + if (nbytes == 0) + return 0; - return comedi_read_array_from_buffer(s, data, nbytes); + nbytes = comedi_buf_read_alloc(s, nbytes); + comedi_buf_memcpy_from(s, 0, data, nbytes); + comedi_buf_read_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); + s->async->events |= COMEDI_CB_BLOCK; + + return nbytes; } EXPORT_SYMBOL_GPL(comedi_buf_read_samples); -- GitLab From 8de27e7010cbd8c75a4e04a9807adacc7a8d70b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:42 -0700 Subject: [PATCH 1822/9457] staging: comedi: comedi_buf: make comedi_buf_read_samples() always return full samples A number of drivers currently use comedi_buf_get() to read single samples from the the async buffer. This works but the drivers have to handle the COMEDI_CB_BLOCK and COMEDI_CB_EOS events. Converting those drivers to use comedi_buf_read_samples() moves the handling of those events into the core. Modify comedi_buf_read_samples() so that the async buffer is checked for the number of full samples available. Use that to clamp the number of samples that will be read. This makes sure that only full samples are read from the async buffer making comedi_buf_read_samples() mimic the action of comedi_buf_get() with the added benifit of handling the events. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 9074da2cbe0a..fb2e91a0e724 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -566,15 +566,15 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, unsigned int max_samples; unsigned int nbytes; - max_samples = s->async->prealloc_bufsz / bytes_per_sample(s); + /* clamp nsamples to the number of full samples available */ + max_samples = comedi_buf_read_n_available(s) / bytes_per_sample(s); if (nsamples > max_samples) nsamples = max_samples; - nbytes = nsamples * bytes_per_sample(s); - if (nbytes == 0) + if (nsamples == 0) return 0; - nbytes = comedi_buf_read_alloc(s, nbytes); + nbytes = comedi_buf_read_alloc(s, nsamples * bytes_per_sample(s)); comedi_buf_memcpy_from(s, 0, data, nbytes); comedi_buf_read_free(s, nbytes); comedi_inc_scan_progress(s, nbytes); -- GitLab From e14c6a60b51eb53f96a91f4650e16e61b4e9c861 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:43 -0700 Subject: [PATCH 1823/9457] staging: comedi: ni_mio_common: use comedi_buf_read_samples() Use comedi_buf_read_samples() to get the single samples from the async buffer. The number of samples in the buffer was validated by the callers so the error checking can be removed. In addition, the core will set the COMEDI_CB_BLOCK event so it can also be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index fa5b25063661..8004e8ac945d 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1132,13 +1132,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev, unsigned short d; u32 packed_data; int range; - int err = 1; chan = async->cur_chan; for (i = 0; i < n; i++) { - err &= comedi_buf_get(s, &d); - if (err == 0) - break; + comedi_buf_read_samples(s, &d, 1); range = CR_RANGE(cmd->chanlist[chan]); @@ -1146,9 +1143,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev, packed_data = d & 0xffff; /* 6711 only has 16 bit wide ao fifo */ if (!devpriv->is_6711) { - err &= comedi_buf_get(s, &d); - if (err == 0) - break; + comedi_buf_read_samples(s, &d, 1); chan++; i++; packed_data |= (d << 16) & 0xffff0000; @@ -1161,8 +1156,6 @@ static void ni_ao_fifo_load(struct comedi_device *dev, chan %= cmd->chanlist_len; } async->cur_chan = chan; - if (err == 0) - async->events |= COMEDI_CB_OVERFLOW; } /* @@ -1199,8 +1192,6 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, ni_ao_fifo_load(dev, s, n); - s->async->events |= COMEDI_CB_BLOCK; - return 1; } -- GitLab From dec1a2668629755b4c926f1473ecd2615d3a3d73 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:44 -0700 Subject: [PATCH 1824/9457] staging: comedi: amplc_pci230: use comedi_buf_read_samples() Use comedi_buf_read_samples() to read the analog output samples from the async buffer. That function will set the COMEDI_CB_BLOCK event when samples are read from the async buffer. In addition, the core will also handle the end-of-scan detection and set the COMEDI_CB_EOS event. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a3b34d881a08..f9b952f7173e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1075,26 +1075,25 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s) { struct pci230_private *devpriv = dev->private; - unsigned short data; - int i, ret; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; + unsigned short data; + int i; if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0) return; + for (i = 0; i < cmd->chanlist_len; i++) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); - /* Read sample from Comedi's circular buffer. */ - ret = comedi_buf_get(s, &data); - if (ret == 0) { - s->async->events |= COMEDI_CB_OVERFLOW; + if (!comedi_buf_read_samples(s, &data, 1)) { + async->events |= COMEDI_CB_OVERFLOW; return; } pci230_ao_write_nofifo(dev, data, chan); s->readback[chan] = data; } - async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + if (cmd->stop_src == TRIG_COUNT) { devpriv->ao_scan_count--; if (devpriv->ao_scan_count == 0) { @@ -1171,12 +1170,12 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short datum; - comedi_buf_get(s, &datum); + comedi_buf_read_samples(s, &datum, 1); pci230_ao_write_fifo(dev, datum, chan); s->readback[chan] = datum; } } - events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK; + if (cmd->stop_src == TRIG_COUNT) { devpriv->ao_scan_count -= num_scans; if (devpriv->ao_scan_count == 0) { -- GitLab From 664ab5d6db57c5805ed3e1bfc06f39aad80ce34e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:45 -0700 Subject: [PATCH 1825/9457] staging: comedi: usbdux: use comedi_buf_read_samples() Use comedi_buf_read_samples() to read the analog output samples from the async buffer. That function will set the COMEDI_CB_BLOCK event when samples are read from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index eae441f3858c..53f1e218d0d9 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -413,7 +413,7 @@ static void usbduxsub_ao_handle_urb(struct comedi_device *dev, unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - if (!comedi_buf_get(s, &val)) { + if (!comedi_buf_read_samples(s, &val, 1)) { dev_err(dev->class_dev, "buffer underflow\n"); async->events |= COMEDI_CB_OVERFLOW; return; @@ -425,7 +425,6 @@ static void usbduxsub_ao_handle_urb(struct comedi_device *dev, *datap++ = chan << 6; s->readback[chan] = val; } - async->events |= COMEDI_CB_BLOCK; } /* if command is still running, resubmit urb for BULK transfer */ -- GitLab From e463fbe419b70744c7126ec198c6d6e2cffa5c87 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:46 -0700 Subject: [PATCH 1826/9457] staging: comedi: usbduxsigma: use comedi_buf_read_samples() Use comedi_buf_read_samples() to read the analog output samples from the async buffer. That function will set the COMEDI_CB_BLOCK event when samples are read from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 1d12cc6c1ade..de3fb41b1886 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -374,7 +374,7 @@ static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, unsigned int chan = CR_CHAN(cmd->chanlist[i]); unsigned short val; - if (!comedi_buf_get(s, &val)) { + if (!comedi_buf_read_samples(s, &val, 1)) { dev_err(dev->class_dev, "buffer underflow\n"); async->events |= COMEDI_CB_OVERFLOW; return; @@ -384,7 +384,6 @@ static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, *datap++ = chan; s->readback[chan] = val; } - async->events |= COMEDI_CB_BLOCK; } /* if command is still running, resubmit urb */ -- GitLab From 04c4166a22717241c3d5fdf8740c7e4c9a0bdf25 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:47 -0700 Subject: [PATCH 1827/9457] staging: comedi: comedi_buf: remove comedi_buf_get() This function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 14 -------------- drivers/staging/comedi/comedidev.h | 1 - 2 files changed, 15 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index fb2e91a0e724..f7ff420ed612 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -442,20 +442,6 @@ int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) } EXPORT_SYMBOL_GPL(comedi_buf_put); -int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x) -{ - struct comedi_async *async = s->async; - unsigned int n = comedi_buf_read_n_available(s); - - if (n < sizeof(short)) - return 0; - comedi_buf_read_alloc(s, sizeof(short)); - *x = *(unsigned short *)(async->prealloc_buf + async->buf_read_ptr); - comedi_buf_read_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_get); - void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, const void *data, unsigned int num_bytes) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 766387dcab95..df0209a53206 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -442,7 +442,6 @@ unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n); unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); -int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x); void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, const void *source, unsigned int num_bytes); -- GitLab From 9e2093d2399a771f3896292b95ca44a147f5ac6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:48 -0700 Subject: [PATCH 1828/9457] staging: comedi: comedi_buf: dont't export comedi_buf_memcpy_from() This function is only used internally. Remove the export. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 6 +++--- drivers/staging/comedi/comedidev.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index f7ff420ed612..a87b8e66fde0 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -469,8 +469,9 @@ void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, } EXPORT_SYMBOL_GPL(comedi_buf_memcpy_to); -void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, - void *dest, unsigned int nbytes) +static void comedi_buf_memcpy_from(struct comedi_subdevice *s, + unsigned int offset, + void *dest, unsigned int nbytes) { void *src; struct comedi_async *async = s->async; @@ -495,7 +496,6 @@ void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, read_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_from); /** * comedi_write_array_to_buffer - write data to comedi buffer diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index df0209a53206..ce48828bdae8 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -445,8 +445,7 @@ int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, const void *source, unsigned int num_bytes); -void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, - void *destination, unsigned int num_bytes); + unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes); -- GitLab From aa26e46b0f1d2c0093ec59a68aec715df3f06715 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:49 -0700 Subject: [PATCH 1829/9457] staging: comedi: comedi_buf: don't export comedi_buf_memcpy_to() This function is only used internally. Remove the export. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 6 +++--- drivers/staging/comedi/comedidev.h | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index a87b8e66fde0..0e4727dee030 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -442,8 +442,9 @@ int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) } EXPORT_SYMBOL_GPL(comedi_buf_put); -void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, - const void *data, unsigned int num_bytes) +static void comedi_buf_memcpy_to(struct comedi_subdevice *s, + unsigned int offset, + const void *data, unsigned int num_bytes) { struct comedi_async *async = s->async; unsigned int write_ptr = async->buf_write_ptr + offset; @@ -467,7 +468,6 @@ void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, write_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_to); static void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index ce48828bdae8..9f4f9ef2b79a 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -443,9 +443,6 @@ unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); -void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, - const void *source, unsigned int num_bytes); - unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes); -- GitLab From 319ad742bddace99d6576e4b6fba1f074f29ed2a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:50 -0700 Subject: [PATCH 1830/9457] staging: comedi: comedi_buf: comedi_buf_memcpy_to() remove 'offset' param This parameter is always passed as '0'. Remove the unnecessary parameter. This allows removing the unnecessary check of the write_ptr overflow. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 0e4727dee030..c60fa1aa2048 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -443,14 +443,10 @@ int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) EXPORT_SYMBOL_GPL(comedi_buf_put); static void comedi_buf_memcpy_to(struct comedi_subdevice *s, - unsigned int offset, const void *data, unsigned int num_bytes) { struct comedi_async *async = s->async; - unsigned int write_ptr = async->buf_write_ptr + offset; - - if (write_ptr >= async->prealloc_bufsz) - write_ptr %= async->prealloc_bufsz; + unsigned int write_ptr = async->buf_write_ptr; while (num_bytes) { unsigned int block_size; @@ -526,7 +522,7 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, return 0; } - comedi_buf_memcpy_to(s, 0, data, num_bytes); + comedi_buf_memcpy_to(s, data, num_bytes); comedi_buf_write_free(s, num_bytes); comedi_inc_scan_progress(s, num_bytes); async->events |= COMEDI_CB_BLOCK; -- GitLab From 0ca7f61cd67f7cd581bc6ba968072b4f7b0a2ef8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 14:36:51 -0700 Subject: [PATCH 1831/9457] staging: comedi: comedi_buf: comedi_buf_memcpy_from() remove 'offset' param This parameter is always passed as '0'. Remove the unnecessary parameter. This allows removing the unnecessary check of the read_ptr overflow. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c60fa1aa2048..1f916072cd93 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -466,15 +466,11 @@ static void comedi_buf_memcpy_to(struct comedi_subdevice *s, } static void comedi_buf_memcpy_from(struct comedi_subdevice *s, - unsigned int offset, void *dest, unsigned int nbytes) { void *src; struct comedi_async *async = s->async; - unsigned int read_ptr = async->buf_read_ptr + offset; - - if (read_ptr >= async->prealloc_bufsz) - read_ptr %= async->prealloc_bufsz; + unsigned int read_ptr = async->buf_read_ptr; while (nbytes) { unsigned int block_size; @@ -557,7 +553,7 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, return 0; nbytes = comedi_buf_read_alloc(s, nsamples * bytes_per_sample(s)); - comedi_buf_memcpy_from(s, 0, data, nbytes); + comedi_buf_memcpy_from(s, data, nbytes); comedi_buf_read_free(s, nbytes); comedi_inc_scan_progress(s, nbytes); s->async->events |= COMEDI_CB_BLOCK; -- GitLab From 5438da85fc482c63f7a6f93e5b07d7c55fc77135 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:24 -0700 Subject: [PATCH 1832/9457] staging: comedi: comedi_buf: introduce comedi_buf_write_samples() Introduce a generic method to write samples to the async buffer. The number of samples is first checked against the number of samples that would fill the async buffer. The size of each sample is determined using the bytes_per_sample() helper. If all the samples will fit in the async buffer they are written to the buffer using comedi_write_array_to_buffer(). This will allow converting all the comedi drivers to use a common method to write data to the async buffer. Since comedi_write_array_to_buffer() sets the COMEDI_CB_BLOCK event after writing the data, those events can be removed from the drivers. In addition, comedi_inc_scan_progress() will automatically detect the end of scan and set the COMEDI_CB_EOS event. Those events can also be removed from the drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 31 +++++++++++++++++++++++++++++ drivers/staging/comedi/comedidev.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 1f916072cd93..a41a414bef74 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -527,6 +527,37 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); +/** + * comedi_buf_write_samples - write sample data to comedi buffer + * @s: comedi_subdevice struct + * @data: samples + * @nsamples: number of samples + * + * Writes nsamples to the comedi buffer associated with the subdevice, marks + * it as written and updates the acquisition scan progress. + * + * Returns the amount of data written in bytes. + */ +unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, unsigned int nsamples) +{ + unsigned int max_samples; + unsigned int nbytes; + + /* make sure there is enought room in the buffer for all the samples */ + max_samples = comedi_buf_write_n_available(s) / bytes_per_sample(s); + if (nsamples > max_samples) { + dev_warn(s->device->class_dev, "buffer overrun\n"); + s->async->events |= COMEDI_CB_OVERFLOW; + return 0; + } + + nbytes = nsamples * bytes_per_sample(s); + + return comedi_write_array_to_buffer(s, data, nbytes); +} +EXPORT_SYMBOL_GPL(comedi_buf_write_samples); + /** * comedi_buf_read_samples - read sample data from comedi buffer * @s: comedi_subdevice struct diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 9f4f9ef2b79a..eee4dd45a122 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -446,6 +446,8 @@ int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes); +unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, unsigned int nsamples); unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, void *data, unsigned int nsamples); -- GitLab From ce8bfa275a3c9fabd3bd670ea0da0b2d1d4ba8d2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:25 -0700 Subject: [PATCH 1833/9457] staging: comedi: comedi_fc.h: remove cfc_write_long_to_buffer() The inline function is not used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index fed0a54e5af6..de9331cda600 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -36,12 +36,6 @@ static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *s, return comedi_write_array_to_buffer(s, &data, sizeof(data)); }; -static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *s, - unsigned int data) -{ - return comedi_write_array_to_buffer(s, &data, sizeof(data)); -}; - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate -- GitLab From 88f9662abbedb43ecf9ec4e03ab67500bbf66d7d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:26 -0700 Subject: [PATCH 1834/9457] staging: comedi: comedi_test: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add the single sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 4d4358ce1710..b8fd4d24b421 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -203,7 +203,7 @@ static void waveform_ai_interrupt(unsigned long arg) devpriv->usec_current + i * devpriv->scan_period + j * devpriv->convert_period); - cfc_write_to_buffer(s, sample); + comedi_buf_write_samples(s, &sample, 1); } } -- GitLab From ad9eb43c93d83578674e1da78a0bd792c3a22513 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:27 -0700 Subject: [PATCH 1835/9457] staging: comedi: das800: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add the single sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event from the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das800.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index e284d202b7e7..6013099891c0 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -511,12 +511,11 @@ static irqreturn_t das800_interrupt(int irq, void *d) /* if there are more data points to collect */ if (cmd->stop_src == TRIG_NONE || devpriv->count > 0) { - /* write data point to buffer */ - cfc_write_to_buffer(s, val & s->maxdata); + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); devpriv->count--; } } - async->events |= COMEDI_CB_BLOCK; if (fifo_overflow) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); -- GitLab From 7138e892a627215fad394160808d2084b51456d8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:28 -0700 Subject: [PATCH 1836/9457] staging: comedi: ni_at_a2150: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add the single sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index f1fe9efda6df..5c17def29f8d 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -237,7 +237,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) dpnt = devpriv->dma_buffer[i]; /* convert from 2's complement to unsigned coding */ dpnt ^= 0x8000; - cfc_write_to_buffer(s, dpnt); + comedi_buf_write_samples(s, &dpnt, 1); if (cmd->stop_src == TRIG_COUNT) { if (--devpriv->count == 0) { /* end of acquisition */ async->events |= COMEDI_CB_EOA; @@ -253,8 +253,6 @@ static irqreturn_t a2150_interrupt(int irq, void *d) } release_dma_lock(flags); - async->events |= COMEDI_CB_BLOCK; - comedi_handle_events(dev, s); /* clear interrupt */ -- GitLab From 0e017a4bbee454df42d1fc983c3c9eea0981fb30 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:29 -0700 Subject: [PATCH 1837/9457] staging: comedi: s626: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add the single sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index efd438f0ca62..6976bb098f54 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1493,8 +1493,7 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev) tempdata = s626_ai_reg_to_uint(*readaddr); readaddr++; - /* put data into read buffer */ - cfc_write_to_buffer(s, tempdata); + comedi_buf_write_samples(s, &tempdata, 1); } /* end of scan occurs */ -- GitLab From 8d185f52dc3d47ceda9c3f1e7f186a8adc53640c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:30 -0700 Subject: [PATCH 1838/9457] staging: comedi: ni_labpc_common: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add the single sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index 72dc78632cd5..685220369c32 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -818,7 +818,7 @@ static int labpc_drain_fifo(struct comedi_device *dev) devpriv->count--; } data = labpc_read_adc_fifo(dev); - cfc_write_to_buffer(dev->read_subdev, data); + comedi_buf_write_samples(dev->read_subdev, &data, 1); devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); } if (i == timeout) { -- GitLab From b9357cba10f866799516befba2bb374463ccf74d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:31 -0700 Subject: [PATCH 1839/9457] staging: comedi: ni_labpc_isadma: use comedi_buf_write_samples() Use comedi_buf_write_samples() instead of cfc_write_to_buffer() to add all the samples to the async buffer in one operation. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc_isadma.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 967202e0635e..6d386050e59d 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -91,7 +91,6 @@ void labpc_drain_dma(struct comedi_device *dev) int status; unsigned long flags; unsigned int max_points, num_points, residue, leftover; - int i; status = devpriv->stat1; @@ -122,9 +121,7 @@ void labpc_drain_dma(struct comedi_device *dev) leftover = max_points; } - /* write data to comedi buffer */ - for (i = 0; i < num_points; i++) - cfc_write_to_buffer(s, devpriv->dma_buffer[i]); + comedi_buf_write_samples(s, devpriv->dma_buffer, num_points); if (cmd->stop_src == TRIG_COUNT) devpriv->count -= num_points; @@ -133,8 +130,6 @@ void labpc_drain_dma(struct comedi_device *dev) set_dma_addr(devpriv->dma_chan, devpriv->dma_addr); set_dma_count(devpriv->dma_chan, leftover * sample_size); release_dma_lock(flags); - - async->events |= COMEDI_CB_BLOCK; } EXPORT_SYMBOL_GPL(labpc_drain_dma); -- GitLab From 880f582068ab8dc92c00dcea409c26e7ddaca675 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:32 -0700 Subject: [PATCH 1840/9457] staging: comedi: das1800: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle single and multi samples writes by determining the number of bytes to add based on the number of samples and the bytes_per_sample(). Also, remove the unnecessary COMEDI_CB_BLOCK event. comedi_buf_write_samples() will automatically add that event after adding the samples to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 7b0b65e883f6..246a18648223 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -488,8 +488,7 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, numPoints = devpriv->count; insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); munge_data(dev, devpriv->ai_buf0, numPoints); - cfc_write_array_to_buffer(s, devpriv->ai_buf0, - numPoints * sizeof(devpriv->ai_buf0[0])); + comedi_buf_write_samples(s, devpriv->ai_buf0, numPoints); if (cmd->stop_src == TRIG_COUNT) devpriv->count -= numPoints; } @@ -512,7 +511,7 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev, if (!unipolar) ; dpnt = munge_bipolar_sample(dev, dpnt); - cfc_write_to_buffer(s, dpnt); + comedi_buf_write_samples(s, &dpnt, 1); if (cmd->stop_src == TRIG_COUNT) devpriv->count--; } @@ -543,7 +542,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, num_samples = devpriv->count; munge_data(dev, buffer, num_samples); - cfc_write_array_to_buffer(s, buffer, num_bytes); + comedi_buf_write_samples(s, buffer, num_samples); if (cmd->stop_src == TRIG_COUNT) devpriv->count -= num_samples; } @@ -649,7 +648,6 @@ static void das1800_ai_handler(struct comedi_device *dev) das1800_handle_fifo_not_empty(dev, s); } - async->events |= COMEDI_CB_BLOCK; /* if the card's fifo has overflowed */ if (status & OVF) { /* clear OVF interrupt bit */ -- GitLab From 8d47c085e855da6ce24fa7d9fe3cbb2868f3d8b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:33 -0700 Subject: [PATCH 1841/9457] staging: comedi: cb_pcidas: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle single and multi samples writes by determining the number of bytes to add based on the number of samples and the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index a0d462fecf20..53afae093c4c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1359,8 +1359,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) } insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, num_samples); - cfc_write_array_to_buffer(s, devpriv->ai_buffer, - num_samples * sizeof(short)); + comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); devpriv->count -= num_samples; if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) async->events |= COMEDI_CB_EOA; @@ -1372,11 +1371,14 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) /* else if fifo not empty */ } else if (status & (ADNEI | EOBI)) { for (i = 0; i < timeout; i++) { + unsigned short val; + /* break if fifo is empty */ if ((ADNE & inw(devpriv->control_status + INT_ADCFIFO)) == 0) break; - cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); + val = inw(devpriv->adc_fifo); + comedi_buf_write_samples(s, &val, 1); if (cmd->stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */ -- GitLab From 28e8c8984c95202cf09ee3d27becf4d1494350ee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:34 -0700 Subject: [PATCH 1842/9457] staging: comedi: adl_pci9118: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. The number of bytes to add is determined automatically based on the number of samples and the bytes_per_sample(). Change the return type of move_block_from_dma() to void and remove the unnecessary check of the return value of comedi_buf_write_samples(). The callers don't check the return and it's really not necessary. If comedi_buf_write_samples() fails to allocate enough space in the async buffer to add all the samples it sets the COMEDI_CB_OVERFLOW event. This will cause the async command to (*cancel) when the events are handled. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 7b1720f8fb30..cb2c48522efd 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -472,26 +472,21 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev, return j; } -static int move_block_from_dma(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned short *dma_buffer, - unsigned int num_samples) +static void move_block_from_dma(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned short *dma_buffer, + unsigned int num_samples) { struct pci9118_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int num_bytes; num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples); devpriv->ai_act_scan += (s->async->cur_chan + num_samples) / cmd->scan_end_arg; s->async->cur_chan += num_samples; s->async->cur_chan %= cmd->scan_end_arg; - num_bytes = - cfc_write_array_to_buffer(s, dma_buffer, - num_samples * sizeof(short)); - if (num_bytes < num_samples * sizeof(short)) - return -1; - return 0; + + comedi_buf_write_samples(s, dma_buffer, num_samples); } static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable) @@ -617,7 +612,7 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG); - cfc_write_to_buffer(s, sampl); + comedi_buf_write_samples(s, &sampl, 1); s->async->cur_chan++; if (s->async->cur_chan >= cmd->scan_end_arg) { /* one scan done */ -- GitLab From 7ba38a01444ef99e6ebeeb41167082f32991514e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:35 -0700 Subject: [PATCH 1843/9457] staging: comedi: cb_pcidas64: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle single and multi samples writes by determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 22 ++++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 06e846f38992..9196680581b8 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2689,9 +2689,10 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) } for (i = 0; i < num_samples; i++) { - cfc_write_to_buffer(s, - readw(devpriv->main_iobase + - ADC_FIFO_REG)); + unsigned short val; + + val = readw(devpriv->main_iobase + ADC_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); } } while (read_segment != write_segment); @@ -2722,11 +2723,15 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) } for (i = 0; read_code != write_code && i < max_transfer;) { + unsigned short val; + fifo_data = readl(dev->mmio + ADC_FIFO_REG); - cfc_write_to_buffer(s, fifo_data & 0xffff); + val = fifo_data & 0xffff; + comedi_buf_write_samples(s, &val, 1); i++; if (i < max_transfer) { - cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff); + val = (fifo_data >> 16) & 0xffff; + comedi_buf_write_samples(s, &val, 1); i++; } read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & @@ -2778,10 +2783,9 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) num_samples = devpriv->ai_count; devpriv->ai_count -= num_samples; } - cfc_write_array_to_buffer(dev->read_subdev, - devpriv->ai_buffer[devpriv-> - ai_dma_index], - num_samples * sizeof(uint16_t)); + comedi_buf_write_samples(dev->read_subdev, + devpriv->ai_buffer[devpriv->ai_dma_index], + num_samples); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % ai_dma_ring_count(thisboard); } -- GitLab From 9caba3296103f41f90f78aa482f0dfaf89a3f260 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:36 -0700 Subject: [PATCH 1844/9457] staging: comedi: ni_mio_common: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle single and multi sample writes by determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/ni_mio_common.c | 63 +++++++++---------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 8004e8ac945d..18e68cd3ac53 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1226,44 +1226,42 @@ static void ni_ai_fifo_read(struct comedi_device *dev, { struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; + u32 dl; + unsigned short data; int i; if (devpriv->is_611x) { - unsigned short data[2]; - u32 dl; - for (i = 0; i < n / 2; i++) { dl = ni_readl(dev, ADC_FIFO_Data_611x); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16) & 0xffff; - data[1] = dl & 0xffff; - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } /* Check if there's a single sample stuck in the FIFO */ if (n % 2) { dl = ni_readl(dev, ADC_FIFO_Data_611x); - data[0] = dl & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else if (devpriv->is_6143) { - unsigned short data[2]; - u32 dl; - /* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */ for (i = 0; i < n / 2; i++) { dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - data[1] = dl & 0xffff; - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } if (n % 2) { /* Assume there is a single sample stuck in the FIFO */ /* Get stranded sample into FIFO */ ni_writel(dev, 0x01, AIFIFO_Control_6143); dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else { if (n > sizeof(devpriv->ai_fifo_buffer) / @@ -1277,9 +1275,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev, devpriv->ai_fifo_buffer[i] = ni_readw(dev, ADC_FIFO_Data_Register); } - cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer, - n * - sizeof(devpriv->ai_fifo_buffer[0])); + comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, n); } } @@ -1302,8 +1298,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) { struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - unsigned short data[2]; u32 dl; + unsigned short data; unsigned short fifo_empty; int i; @@ -1313,9 +1309,10 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) dl = ni_readl(dev, ADC_FIFO_Data_611x); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16); - data[1] = (dl & 0xffff); - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = dl >> 16; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else if (devpriv->is_6143) { i = 0; @@ -1323,9 +1320,10 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) dl = ni_readl(dev, AIFIFO_Data_6143); /* This may get the hi/lo data in the wrong order */ - data[0] = (dl >> 16); - data[1] = (dl & 0xffff); - cfc_write_array_to_buffer(s, data, sizeof(data)); + data = dl >> 16; + comedi_buf_write_samples(s, &data, 1); + data = dl & 0xffff; + comedi_buf_write_samples(s, &data, 1); i += 2; } /* Check if stranded sample is present */ @@ -1333,8 +1331,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) /* Get stranded sample into FIFO */ ni_writel(dev, 0x01, AIFIFO_Control_6143); dl = ni_readl(dev, AIFIFO_Data_6143); - data[0] = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data[0]); + data = (dl >> 16) & 0xffff; + comedi_buf_write_samples(s, &data, 1); } } else { @@ -1353,10 +1351,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) devpriv->ai_fifo_buffer[i] = ni_readw(dev, ADC_FIFO_Data_Register); } - cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer, - i * - sizeof(devpriv-> - ai_fifo_buffer[0])); + comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, i); } } } @@ -1375,7 +1370,7 @@ static void get_last_sample_611x(struct comedi_device *dev) if (ni_readb(dev, XXX_Status) & 0x80) { dl = ni_readl(dev, ADC_FIFO_Data_611x); data = (dl & 0xffff); - cfc_write_to_buffer(s, data); + comedi_buf_write_samples(s, &data, 1); } } @@ -1397,7 +1392,7 @@ static void get_last_sample_6143(struct comedi_device *dev) /* This may get the hi/lo data in the wrong order */ data = (dl >> 16) & 0xffff; - cfc_write_to_buffer(s, data); + comedi_buf_write_samples(s, &data, 1); } } -- GitLab From be591d5c42cdc25cfe8a586082a7e0e3ef0223b1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:37 -0700 Subject: [PATCH 1845/9457] staging: comedi: comedi_fc.h: remove cfc_write_to_buffer() The inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index de9331cda600..8ecb6bc9b60b 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -30,12 +30,6 @@ static inline unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *s, return comedi_write_array_to_buffer(s, data, num_bytes); } -static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *s, - unsigned short data) -{ - return comedi_write_array_to_buffer(s, &data, sizeof(data)); -}; - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate -- GitLab From 9fdfe0fd009b261aa51c0226ca261ab039feaf62 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:38 -0700 Subject: [PATCH 1846/9457] staging: comedi: adl_pci9111: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. The number of bytes to add is determined automatically based on the number of samples and the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 076866e121a0..18f5f7fc1bc8 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -477,9 +477,8 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, devpriv->ai_bounce_buffer, samples); if (devpriv->scan_delay < 1) { - total = cfc_write_array_to_buffer(s, - devpriv->ai_bounce_buffer, - samples * sizeof(short)); + total = comedi_buf_write_samples(s, devpriv->ai_bounce_buffer, + samples); } else { unsigned int pos = 0; unsigned int to_read; @@ -492,9 +491,9 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, if (to_read > samples - pos) to_read = samples - pos; - total += cfc_write_array_to_buffer(s, + total += comedi_buf_write_samples(s, devpriv->ai_bounce_buffer + pos, - to_read * sizeof(short)); + to_read); } else { to_read = devpriv->chunk_num_samples - devpriv->chunk_counter; -- GitLab From 5759a14d829354aea9dd639d7dc41ac35db11ab5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:39 -0700 Subject: [PATCH 1847/9457] staging: comedi: hwdrv_apci3120: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle the '* sizeof(foo)' calculation to determine the number of bytes to add. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 10deb72a4b37..4959fc663d85 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1172,7 +1172,7 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, s->async->cur_chan += num_samples; s->async->cur_chan %= cmd->scan_end_arg; - cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); + comedi_buf_write_samples(s, dma_buffer, num_samples); } /* -- GitLab From b45a7beb3bc3c43e6abea5b3da9c8df8377540e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:40 -0700 Subject: [PATCH 1848/9457] staging: comedi: das16m1: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. The number of bytes to add is determined automatically based on the number of samples and the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index f98bcbe0d72a..54ccffca8497 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -442,8 +442,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status) num_samples = FIFO_SIZE; insw(dev->iobase, devpriv->ai_buffer, num_samples); munge_sample_array(devpriv->ai_buffer, num_samples); - cfc_write_array_to_buffer(s, devpriv->ai_buffer, - num_samples * sizeof(short)); + comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); devpriv->adc_count += num_samples; if (cmd->stop_src == TRIG_COUNT) { -- GitLab From 2e7b65e4bbe3b35ece1b8c8179a77071be042c38 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:41 -0700 Subject: [PATCH 1849/9457] staging: comedi: das16: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 5d47d0a1d45f..aa9e3e10d59d 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -541,6 +541,7 @@ static void das16_interrupt(struct comedi_device *dev) struct comedi_cmd *cmd = &async->cmd; unsigned long spin_flags; unsigned long dma_flags; + unsigned int nsamples; int num_bytes, residue; int buffer_index; @@ -583,8 +584,9 @@ static void das16_interrupt(struct comedi_device *dev) spin_unlock_irqrestore(&dev->spinlock, spin_flags); - cfc_write_array_to_buffer(s, - devpriv->dma_buffer[buffer_index], num_bytes); + nsamples = num_bytes / bytes_per_sample(s); + comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index], + nsamples); comedi_handle_events(dev, s); } -- GitLab From d4c2acd233191fe67fddac7bf74e93ddb12bc1f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:42 -0700 Subject: [PATCH 1850/9457] staging: comedi: dt282x: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 88b56104d4e7..1d9fa371d03c 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -491,6 +491,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev, int cur_dma = devpriv->current_dma_index; void *ptr = devpriv->dma[cur_dma].buf; int size = devpriv->dma[cur_dma].size; + unsigned int nsamples = size / bytes_per_sample(s); int ret; outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, @@ -501,13 +502,11 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev, devpriv->current_dma_index = 1 - cur_dma; dt282x_munge(dev, s, ptr, size); - ret = cfc_write_array_to_buffer(s, ptr, size); - if (ret != size) { - s->async->events |= COMEDI_CB_OVERFLOW; + ret = comedi_buf_write_samples(s, ptr, nsamples); + if (ret != size) return; - } - devpriv->nread -= size / 2; + devpriv->nread -= nsamples; if (devpriv->nread < 0) { dev_info(dev->class_dev, "nread off by one\n"); devpriv->nread = 0; @@ -566,7 +565,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) } #if 0 if (adcsr & DT2821_ADCSR_ADDONE) { - int ret; unsigned short data; data = inw(dev->iobase + DT2821_ADDAT_REG); @@ -574,10 +572,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) if (devpriv->ad_2scomp) data = comedi_offset_munge(s, data); - ret = comedi_buf_put(s, data); - - if (ret == 0) - s->async->events |= COMEDI_CB_OVERFLOW; + comedi_buf_write_samples(s, &data, 1); devpriv->nread--; if (!devpriv->nread) { -- GitLab From 60e6644399337185a860552cba977f7c47ac0723 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:43 -0700 Subject: [PATCH 1851/9457] staging: comedi: gsc_hpdi: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will handle the '* sizeof(foo)' calculation to determine the number of bytes to add. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index e99edaa3b9fa..58a99e812818 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -196,8 +196,8 @@ static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel) size = devpriv->dio_count; devpriv->dio_count -= size; } - cfc_write_array_to_buffer(s, devpriv->desc_dio_buffer[idx], - size * sizeof(uint32_t)); + comedi_buf_write_samples(s, devpriv->desc_dio_buffer[idx], + size); idx++; idx %= devpriv->num_dma_descriptors; start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr); -- GitLab From 504d0239f624a8cd65a2dbbcee6230014ada43d5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:44 -0700 Subject: [PATCH 1852/9457] staging: comedi: usbduxsigma: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. That function will determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index de3fb41b1886..7b7698c3ccd2 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -245,8 +245,7 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev, val &= 0x00ffffff; /* strip status byte */ val ^= 0x00800000; /* convert to unsigned */ - if (!cfc_write_array_to_buffer(s, &val, - sizeof(uint32_t))) + if (!comedi_buf_write_samples(s, &val, 1)) return; } } -- GitLab From f81ac41b89798a53f03e2204153598b229958660 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:45 -0700 Subject: [PATCH 1853/9457] staging: comedi: usbduxfast: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. That function will determining the number of bytes to add based on the bytes_per_sample(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 95c2ec7ed22a..70ec2f552dfc 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -249,19 +249,17 @@ static void usbduxfast_ai_handle_urb(struct comedi_device *dev, devpriv->ignore--; } else { unsigned int nbytes = urb->actual_length; + unsigned int nsamples = nbytes / bytes_per_sample(s); if (cmd->stop_src == TRIG_COUNT) { - unsigned int nsamples = nbytes / bytes_per_sample(s); - if (devpriv->ai_sample_count < nsamples) { nsamples = devpriv->ai_sample_count; async->events |= COMEDI_CB_EOA; } devpriv->ai_sample_count -= nsamples; - nbytes = nsamples * bytes_per_sample(s); } - cfc_write_array_to_buffer(s, urb->transfer_buffer, nbytes); + comedi_buf_write_samples(s, urb->transfer_buffer, nsamples); } /* if command is still running, resubmit urb for BULK transfer */ -- GitLab From f4add8df72e38a41886c35065c0a794f96fc057a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:46 -0700 Subject: [PATCH 1854/9457] staging: comedi: comedi_fc.h: remove cfc_write_array_to_buffer() The inline function is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 8ecb6bc9b60b..756be931c1a4 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -23,13 +23,6 @@ #include "../comedidev.h" -static inline unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) -{ - return comedi_write_array_to_buffer(s, data, num_bytes); -} - /** * cfc_check_trigger_src() - trivially validate a comedi_cmd trigger source * @src: pointer to the trigger source to validate -- GitLab From 6bb45f2b0c868281311e14d9c6fb94c15eabe13a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:47 -0700 Subject: [PATCH 1855/9457] staging: comedi: addi_apci_1032: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_BLOCK and COMEDI_CB_EOS will be detected and set by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 12601a9337f3..bf14165297b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -258,8 +258,7 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; - comedi_buf_put(s, s->state); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); /* enable the interrupt */ -- GitLab From c4a58f281a0c657310541dfccf176d1f40fc1add Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:48 -0700 Subject: [PATCH 1856/9457] staging: comedi: addi_apci_1564: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_BLOCK and COMEDI_CB_EOS will be detected and set by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1564.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index cf544ab1fc65..47b63e176c08 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -95,8 +95,7 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) & 0xffff; - comedi_buf_put(s, s->state); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); /* enable the interrupt */ -- GitLab From 6aec0f9af4c769fd104294745467fd8399548da7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:49 -0700 Subject: [PATCH 1857/9457] staging: comedi: addi_apci_3xxx: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index fe9ac2d72694..db3ee9c429ad 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -371,7 +371,7 @@ static irqreturn_t apci3xxx_irq_handler(int irq, void *d) writel(status, dev->mmio + 16); val = readl(dev->mmio + 28); - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); s->async->events |= COMEDI_CB_EOA; comedi_handle_events(dev, s); -- GitLab From a9c3a015c12f5c83773411bf06c6daf3d60ed61d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:50 -0700 Subject: [PATCH 1858/9457] staging: comedi: adv_pci1710: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5f387fabe1f5..c5422f376927 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -770,7 +770,8 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, break; } - comedi_buf_put(s, val & s->maxdata); + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); s->async->cur_chan++; if (s->async->cur_chan >= cmd->chanlist_len) @@ -814,7 +815,8 @@ static int move_block_from_fifo(struct comedi_device *dev, return ret; } - comedi_buf_put(s, val & s->maxdata); + val &= s->maxdata; + comedi_buf_write_samples(s, &val, 1); s->async->cur_chan++; if (s->async->cur_chan >= cmd->chanlist_len) { -- GitLab From 27913fa08cf56df2c925e2dad7827be87d7644c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:51 -0700 Subject: [PATCH 1859/9457] staging: comedi: amplc_pc236_common: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_BLOCK and COMEDI_CB_EOS will be detected and set by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index 04c3d73ec5ba..be87172d1f3f 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -135,8 +135,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d) handled = pc236_intr_check(dev); if (dev->attached && handled) { - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); } return IRQ_RETVAL(handled); -- GitLab From 48e08de087ad53b9893cbc44d5ce88e0b8d9f025 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:52 -0700 Subject: [PATCH 1860/9457] staging: comedi: amplc_pci230: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events will set properly by the core. A dev_warn() message will also be output by the core if the buffer overflows. Remove the unnecessary events and dev_err() message in the driver. The core will also add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index f9b952f7173e..44c967f43d9a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2053,6 +2053,7 @@ static void pci230_handle_ai(struct comedi_device *dev, unsigned int i; unsigned int todo; unsigned int fifoamount; + unsigned short val; /* Determine number of samples to read. */ if (cmd->stop_src != TRIG_COUNT) { @@ -2099,12 +2100,10 @@ static void pci230_handle_ai(struct comedi_device *dev, fifoamount = 1; } } - /* Read sample and store in Comedi's circular buffer. */ - if (comedi_buf_put(s, pci230_ai_read(dev)) == 0) { - events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; - dev_err(dev->class_dev, "AI buffer overflow\n"); - break; - } + + val = pci230_ai_read(dev); + comedi_buf_write_samples(s, &val, 1); + fifoamount--; devpriv->ai_scan_pos++; if (devpriv->ai_scan_pos == scanlen) { @@ -2117,9 +2116,6 @@ static void pci230_handle_ai(struct comedi_device *dev, if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) { /* End of acquisition. */ events |= COMEDI_CB_EOA; - } else { - /* More samples required, tell Comedi to block. */ - events |= COMEDI_CB_BLOCK; } async->events |= events; if (!(async->events & COMEDI_CB_CANCEL_MASK)) { -- GitLab From 9a84a7d2e7111aa77a9f35da5e669423d11e0d37 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:53 -0700 Subject: [PATCH 1861/9457] staging: comedi: comedi_parport: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_BLOCK and COMEDI_CB_EOS will be detected and set by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_parport.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 0bc3844073ee..3bac903c8627 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -225,10 +225,9 @@ static irqreturn_t parport_interrupt(int irq, void *d) if (!(ctrl & PARPORT_CTRL_IRQ_ENA)) return IRQ_NONE; - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); + return IRQ_HANDLED; } -- GitLab From 1700529b24cc99ad5c77ab765da2f290fcd0c92c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:54 -0700 Subject: [PATCH 1862/9457] staging: comedi: dmm32at: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dmm32at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 7e69d317b7ef..fc2c0db73999 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -501,7 +501,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d) /* invert sign bit to make range unsigned */ samp = ((msb ^ 0x0080) << 8) + lsb; - comedi_buf_put(s, samp); + comedi_buf_write_samples(s, &samp, 1); } if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */ -- GitLab From aa96f6ef6f8672c6fabd461f6259af73d7f515c6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:55 -0700 Subject: [PATCH 1863/9457] staging: comedi: dt3000: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. The core will set the COMEDi_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event from the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 6544f4482740..c2058ba39fa1 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -315,7 +315,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, for (i = 0; i < count; i++) { data = readw(dev->mmio + DPR_ADC_buffer + rear); - comedi_buf_put(s, data); + comedi_buf_write_samples(s, &data, 1); rear++; if (rear >= AI_FIFO_DEPTH) rear = 0; @@ -351,10 +351,8 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) status = readw(dev->mmio + DPR_Intr_Flag); - if (status & DT3000_ADFULL) { + if (status & DT3000_ADFULL) dt3k_ai_empty_fifo(dev, s); - s->async->events |= COMEDI_CB_BLOCK; - } if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; -- GitLab From de88924f67d1bd49c742d5ba64d3275e4d6f29d3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:56 -0700 Subject: [PATCH 1864/9457] staging: comedi: me4000: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_OVERFLOW will be set by the core if the async buffer overflows. A dev_warn() message will also be output by the core if the buffer overflows. Remove the unnecessary event and the dev_err() messages in the driver. The core will also add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove these unnecessary events from the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 6516ac0c7b46..97a06749e07d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1092,8 +1092,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) { - s->async->events |= COMEDI_CB_BLOCK; - c = ME4000_AI_FIFO_COUNT / 2; } else { dev_err(dev->class_dev, @@ -1119,7 +1117,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; - if (!comedi_buf_put(s, lval)) { + if (!comedi_buf_write_samples(s, &lval, 1)) { /* * Buffer overflow, so stop conversion * and disable all interrupts @@ -1128,11 +1126,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ); outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); - - s->async->events |= COMEDI_CB_OVERFLOW; - - dev_err(dev->class_dev, "Buffer overflow\n"); - break; } } @@ -1146,7 +1139,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & ME4000_IRQ_STATUS_BIT_SC) { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_EOA; /* * Acquisition is complete, so stop @@ -1164,11 +1157,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF; lval ^= 0x8000; - if (!comedi_buf_put(s, lval)) { - dev_err(dev->class_dev, "Buffer overflow\n"); - s->async->events |= COMEDI_CB_OVERFLOW; + if (!comedi_buf_write_samples(s, &lval, 1)) break; - } } /* Work is done, so reset the interrupt */ -- GitLab From 191db0902606214aed1a90396698c28044d0a753 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:57 -0700 Subject: [PATCH 1865/9457] staging: comedi: ni_6527: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_EOS will automatically be set by the core with the end-of-scan is detected. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index b35e1aeb6626..f99847f3999f 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -208,8 +208,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d) return IRQ_NONE; if (status & NI6527_STATUS_EDGE) { - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); } -- GitLab From 562de49c526117fac6c78fb1e92dd7f1f1349af6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:58 -0700 Subject: [PATCH 1866/9457] staging: comedi: ni_65xx: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_EOS will automatically be set by the core with the end-of-scan is detected. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 973f0058a1e4..bcb326e31562 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -508,9 +508,9 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT, dev->mmio + NI_65XX_CLR_REG); - comedi_buf_put(s, 0); - s->async->events |= COMEDI_CB_EOS; + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); + return IRQ_HANDLED; } -- GitLab From 67fdc3073b78506dc671d49a02f6f47ba7c128d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:36:59 -0700 Subject: [PATCH 1867/9457] staging: comedi: ni_atmio16d: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio16d.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 24f8bca9ba05..2bac69339202 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -217,10 +217,12 @@ static irqreturn_t atmio16d_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; + unsigned short val; - comedi_buf_put(s, inw(dev->iobase + AD_FIFO_REG)); - + val = inw(dev->iobase + AD_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); comedi_handle_events(dev, s); + return IRQ_HANDLED; } -- GitLab From 1f44c034de2e1591f4fad38c685dd167e1da7062 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:00 -0700 Subject: [PATCH 1868/9457] staging: comedi: pcl711: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events will set properly by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl711.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index b6e7f342935d..48a79b8221fc 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -213,14 +213,12 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG); - if (comedi_buf_put(s, data) == 0) { - s->async->events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; - } else { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + if (comedi_buf_write_samples(s, &data, 1)) { if (cmd->stop_src == TRIG_COUNT && !(--devpriv->ntrig)) s->async->events |= COMEDI_CB_EOA; } comedi_handle_events(dev, s); + return IRQ_HANDLED; } -- GitLab From 778d695e67ac836130694942026d686995e2ddaa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:01 -0700 Subject: [PATCH 1869/9457] staging: comedi: pcl726: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events will set properly by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl726.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index be43cdaf9479..a1ac567fb192 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -235,8 +235,7 @@ static irqreturn_t pcl726_interrupt(int irq, void *d) if (devpriv->cmd_running) { pcl726_intr_cancel(dev, s); - comedi_buf_put(s, 0); - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); + comedi_buf_write_samples(s, &s->state, 1); comedi_handle_events(dev, s); } -- GitLab From 76cb501924258b222317d15ccd7df8feb057e593 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:02 -0700 Subject: [PATCH 1870/9457] staging: comedi: pcl812: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the nnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 72ae48f4d256..eef646253bf9 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -844,8 +844,6 @@ static bool pcl812_ai_next_chan(struct comedi_device *dev, struct pcl812_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - s->async->cur_chan++; if (s->async->cur_chan >= cmd->chanlist_len) { s->async->cur_chan = 0; @@ -868,6 +866,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev, { struct comedi_cmd *cmd = &s->async->cmd; unsigned int next_chan; + unsigned short val; if (pcl812_ai_eoc(dev, s, NULL, 0)) { dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); @@ -875,7 +874,8 @@ static void pcl812_handle_eoc(struct comedi_device *dev, return; } - comedi_buf_put(s, pcl812_ai_get_sample(dev, s)); + val = pcl812_ai_get_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); /* Set up next channel. Added by abbotti 2010-01-20, but untested. */ next_chan = s->async->cur_chan + 1; @@ -893,9 +893,11 @@ static void transfer_from_dma_buf(struct comedi_device *dev, unsigned int bufptr, unsigned int len) { unsigned int i; + unsigned short val; for (i = len; i; i--) { - comedi_buf_put(s, ptr[bufptr++]); + val = ptr[bufptr++]; + comedi_buf_write_samples(s, &val, 1); if (!pcl812_ai_next_chan(dev, s)) break; -- GitLab From c0491d4eb4b19721331f6986edfd106ce975f63d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:03 -0700 Subject: [PATCH 1871/9457] staging: comedi: pcl816: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 65cbafb85698..a471c3df12b4 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -289,8 +289,6 @@ static bool pcl816_ai_next_chan(struct comedi_device *dev, struct pcl816_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - s->async->cur_chan++; if (s->async->cur_chan >= cmd->chanlist_len) { s->async->cur_chan = 0; @@ -313,10 +311,12 @@ static void transfer_from_dma_buf(struct comedi_device *dev, unsigned short *ptr, unsigned int bufptr, unsigned int len) { + unsigned short val; int i; for (i = 0; i < len; i++) { - comedi_buf_put(s, ptr[bufptr++]); + val = ptr[bufptr++]; + comedi_buf_write_samples(s, &val, 1); if (!pcl816_ai_next_chan(dev, s)) return; -- GitLab From edf4537bcbf53bb6297678431da12b766fe16610 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:04 -0700 Subject: [PATCH 1872/9457] staging: comedi: pcl818: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 9921e1fa7515..e6d897bf5714 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -521,8 +521,6 @@ static bool pcl818_ai_next_chan(struct comedi_device *dev, struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->events |= COMEDI_CB_BLOCK; - devpriv->act_chanlist_pos++; if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) devpriv->act_chanlist_pos = 0; @@ -560,7 +558,7 @@ static void pcl818_handle_eoc(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) return; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); pcl818_ai_next_chan(dev, s); } @@ -589,7 +587,7 @@ static void pcl818_handle_dma(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) break; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); if (!pcl818_ai_next_chan(dev, s)) break; @@ -630,7 +628,7 @@ static void pcl818_handle_fifo(struct comedi_device *dev, if (pcl818_ai_dropout(dev, s, chan)) break; - comedi_buf_put(s, val); + comedi_buf_write_samples(s, &val, 1); if (!pcl818_ai_next_chan(dev, s)) break; -- GitLab From a4a68fe2a264778d1452b64964ebf65670ef774d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:05 -0700 Subject: [PATCH 1873/9457] staging: comedi: quatech_daqp_cs: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. The core will add the COMEDI_CB_BLOCK event when data is written to the async buffer. Remove the unnecessary event in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 21e99fdf28ad..f6c678eef8d5 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -221,7 +221,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) data |= inb(dev->iobase + DAQP_FIFO) << 8; data ^= 0x8000; - comedi_buf_put(s, data); + comedi_buf_write_samples(s, &data, 1); /* If there's a limit, decrement it * and stop conversion if zero @@ -245,8 +245,6 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - s->async->events |= COMEDI_CB_BLOCK; - comedi_handle_events(dev, s); } return IRQ_HANDLED; -- GitLab From 5023a4bb10f5372a8a9d2429d1dcb32b4ed79b80 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:06 -0700 Subject: [PATCH 1874/9457] staging: comedi: rtd520: use comedi_buf_write_samples() For aesthetics, use comedi_buf_write_samples() to add the sample to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 1a62e8f249ae..888238e26073 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -623,7 +623,7 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = comedi_offset_munge(s, d); d &= s->maxdata; - if (!comedi_buf_put(s, d)) + if (!comedi_buf_write_samples(s, &d, 1)) return -1; if (devpriv->ai_count > 0) /* < 0, means read forever */ -- GitLab From 290d028e0478c5020d69875d817a8b529439874e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:07 -0700 Subject: [PATCH 1875/9457] staging: comedi: usbdux: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The async events COMEDI_CB_BLOCK and COMEDI_CB_EOS will be detected and set by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 53f1e218d0d9..579e6bce529d 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -282,10 +282,9 @@ static void usbduxsub_ai_handle_urb(struct comedi_device *dev, val ^= ((s->maxdata + 1) >> 1); /* transfer data */ - if (!comedi_buf_put(s, val)) + if (!comedi_buf_write_samples(s, &val, 1)) return; } - async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; } /* if command is still running, resubmit urb */ -- GitLab From 435efc8a43330d957cf6e8b79f8e98317668a895 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:08 -0700 Subject: [PATCH 1876/9457] staging: comedi: hwdrv_apci3120: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the samples to the async buffer. The COMEDI_CB_EOS and COMEDI_CB_OVERFLOW events will be automatically handled by the core. Remove the unecessary handling in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 4959fc663d85..975ee5fc93dc 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1313,18 +1313,13 @@ static int apci3120_interrupt_handle_eos(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - int n_chan, i; - int err = 1; - - n_chan = devpriv->ui_AiNbrofChannels; - - for (i = 0; i < n_chan; i++) - err &= comedi_buf_put(s, inw(dev->iobase + 0)); - - s->async->events |= COMEDI_CB_EOS; + unsigned short val; + int i; - if (err == 0) - s->async->events |= COMEDI_CB_OVERFLOW; + for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { + val = inw(dev->iobase + 0); + comedi_buf_write_samples(s, &val, 1); + } return 0; } -- GitLab From 4c704690e743200de94526938cb03cf80c5ae0c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:10 -0700 Subject: [PATCH 1877/9457] staging: comedi: addi_apci_2032: use comedi_buf_write_samples() The dev->read_subdev used in this driver for async commands returns the full scan with each sample so it should have the SDF_PACKED subdev_flag set. Add the missing subdev_flags and use comedi_buf_write_samples() to add the sample to the async buffer. The core sets the async events appropriately. Remove the unnecessary event handling in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_2032.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index ad7529459429..7a5659fafbb3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -211,8 +211,7 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) bits |= (1 << i); } - if (comedi_buf_put(s, bits)) { - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + if (comedi_buf_write_samples(s, &bits, 1)) { if (cmd->stop_src == TRIG_COUNT && subpriv->stop_count > 0) { subpriv->stop_count--; @@ -221,8 +220,6 @@ static irqreturn_t apci2032_interrupt(int irq, void *d) s->async->events |= COMEDI_CB_EOA; } } - } else { - s->async->events |= COMEDI_CB_OVERFLOW; } } @@ -299,7 +296,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, return -ENOMEM; spin_lock_init(&subpriv->spinlock); s->private = subpriv; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED; s->len_chanlist = 2; s->do_cmdtest = apci2032_int_cmdtest; s->do_cmd = apci2032_int_cmd; -- GitLab From 2a07616cd9d5482c8388b8c4762b51f7ec02ba42 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:11 -0700 Subject: [PATCH 1878/9457] staging: comedi: amplc_dio200_common: use comedi_buf_write_samples() The dev->read_subdev used in this driver for async commands returns the full scan with each sample so it should have the SDF_PACKED subdev_flag set. Add the missing subdev_flags and use comedi_buf_write_samples() to add the sample to the async buffer. The async events will set properly by the core. A dev_warn() message will also be output by the core if the buffer overflows. Remove the unnecessary events and dev_err() message in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200_common.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 944d454b7a37..c306226790bf 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -267,14 +267,8 @@ static void dio200_read_scan_intr(struct comedi_device *dev, if (triggered & (1U << ch)) val |= (1U << n); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val)) { - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Error! Stop acquisition. */ - s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; - dev_err(dev->class_dev, "buffer overflow\n"); - } + + comedi_buf_write_samples(s, &val, 1); /* Check for end of acquisition. */ if (cmd->stop_src == TRIG_COUNT) { @@ -463,7 +457,7 @@ static int dio200_subdev_intr_init(struct comedi_device *dev, dio200_write8(dev, subpriv->ofs, 0); s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED; if (board->has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; -- GitLab From dbe81a93f499345499d7f06ba2893af7cc881053 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:12 -0700 Subject: [PATCH 1879/9457] staging: comedi: ni_pcidio: use comedi_buf_write_samples() Use comedi_buf_write_samples() to add the sample to the async buffer. The 32-bit sample size is automatically determined due to the subddev_flag SDF_LSAMPL. The async event COMEDI_CB_BLOCK will be automatically set by the core. Remove the unnecessary event in the driver. This driver also has the SDF_PACKED subdev_flag set so the core will automatically set the COMEDI_CB_EOS event after adding the sample. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 0bb776366264..db7e8aac67b5 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -384,11 +384,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; - - /* int i, j; */ - unsigned int auxdata = 0; - unsigned short data1 = 0; - unsigned short data2 = 0; + unsigned int auxdata; int flags; int status; int work = 0; @@ -451,13 +447,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d) goto out; } auxdata = readl(dev->mmio + Group_1_FIFO); - data1 = auxdata & 0xffff; - data2 = (auxdata & 0xffff0000) >> 16; - comedi_buf_put(s, data1); - comedi_buf_put(s, data2); + comedi_buf_write_samples(s, &auxdata, 1); flags = readb(dev->mmio + Group_1_Flags); } - async->events |= COMEDI_CB_BLOCK; } if (flags & CountExpired) { -- GitLab From ff5eb046cf43726f961644b84aa416960e0f2824 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:13 -0700 Subject: [PATCH 1880/9457] staging: comedi: pcmmio: use comedi_buf_write_samples() The dev->read_subdev used in this driver for async commands returns 32-bit samples and should have the SDF_LSAMPL subdev_flag set. It also returns the full scan with each sample so it should have the SDF_PACKED subdev_flag set. Add the missing subdev_flags and use comedi_buf_write_samples() to add the sample to the async buffer. The COMEDI_CB_BLOCK and COMEDI_CB_EOS events will be automatically handled by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmmio.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 6d60d40733f4..df47967c2650 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -356,10 +356,7 @@ static void pcmmio_handle_dio_intr(struct comedi_device *dev, val |= (1 << i); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); + comedi_buf_write_samples(s, &val, 1); /* Check for end of acquisition. */ if (cmd->stop_src == TRIG_COUNT && devpriv->stop_count > 0) { @@ -764,7 +761,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_config = pcmmio_dio_insn_config; if (dev->irq) { dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; + s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL | SDF_PACKED; s->len_chanlist = s->n_chan; s->cancel = pcmmio_cancel; s->do_cmd = pcmmio_cmd; -- GitLab From 7dd1b528c1008f65653b0bdc027a90fd24ddc2eb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:14 -0700 Subject: [PATCH 1881/9457] staging: comedi: pcmuio: use comedi_buf_write_samples() The dev->read_subdev used in this driver for async commands returns 32-bit samples and should have the SDF_LSAMPL subdev_flag set. It also returns the full scan with each sample so it should have the SDF_PACKED subdev_flag set. Add the missing subdev_flags and use comedi_buf_write_samples() to add the sample to the async buffer. The COMEDI_CB_BLOCK and COMEDI_CB_EOS events will be automatically handled by the core. Remove the unnecessary events in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmuio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 28e659889e4f..18c2ac28e34a 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -336,10 +336,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, val |= (1 << i); } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s, val) && - comedi_buf_put(s, val >> 16)) - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); + comedi_buf_write_samples(s, &val, 1); /* Check for end of acquisition. */ if (cmd->stop_src == TRIG_COUNT) { @@ -604,7 +601,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) { /* setup the interrupt subdevice */ dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; + s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL | + SDF_PACKED; s->len_chanlist = s->n_chan; s->cancel = pcmuio_cancel; s->do_cmd = pcmuio_cmd; -- GitLab From 0ce64e65177e9ddf22e375f0ccbcbfb59cfd6841 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:15 -0700 Subject: [PATCH 1882/9457] staging: comedi: comedi_buf: remove comedi_buf_put() All comedi drivers now use comedi_buf_write_samples() to add the samples to the async buffer. Remove this unused function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 15 --------------- drivers/staging/comedi/comedidev.h | 2 -- 2 files changed, 17 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index a41a414bef74..f4b75d177d7f 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -427,21 +427,6 @@ unsigned int comedi_buf_read_free(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_buf_read_free); -int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) -{ - struct comedi_async *async = s->async; - unsigned int n = __comedi_buf_write_alloc(s, sizeof(short), 1); - - if (n < sizeof(short)) { - async->events |= COMEDI_CB_ERROR; - return 0; - } - *(unsigned short *)(async->prealloc_buf + async->buf_write_ptr) = x; - comedi_buf_write_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_put); - static void comedi_buf_memcpy_to(struct comedi_subdevice *s, const void *data, unsigned int num_bytes) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index eee4dd45a122..d60b83c26a28 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -441,8 +441,6 @@ unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s); unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n); unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); -int comedi_buf_put(struct comedi_subdevice *s, unsigned short x); - unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, const void *data, unsigned int num_bytes); -- GitLab From 8f90726196b60e94e744b58e004064b84ac2d63d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:16 -0700 Subject: [PATCH 1883/9457] staging: comedi: comedi_buf: don't export comedi_write_array_to_buffer() All the comedi drivers have been converted to use comedi_buf_write_samples(). This function is now only used internally by comedi_buf. Remvoe the export. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 19 +++---------------- drivers/staging/comedi/comedidev.h | 3 --- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index f4b75d177d7f..c3152d89e608 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -474,21 +474,9 @@ static void comedi_buf_memcpy_from(struct comedi_subdevice *s, } } -/** - * comedi_write_array_to_buffer - write data to comedi buffer - * @s: comedi_subdevice struct - * @data: destination - * @num_bytes: number of bytes to write - * - * Writes up to num_bytes bytes of data to the comedi buffer associated with - * the subdevice, marks it as written and updates the acquisition scan - * progress. - * - * Returns the amount of data written in bytes. - */ -unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) +static unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, + const void *data, + unsigned int num_bytes) { struct comedi_async *async = s->async; unsigned int retval; @@ -510,7 +498,6 @@ unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, return num_bytes; } -EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); /** * comedi_buf_write_samples - write sample data to comedi buffer diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index d60b83c26a28..f970a8f95cee 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -441,9 +441,6 @@ unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s); unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n); unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n); -unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes); unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, const void *data, unsigned int nsamples); unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, -- GitLab From e19a3c97242825d7426758bad9e293068adf16ec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:17 -0700 Subject: [PATCH 1884/9457] staging: comedi: comedi_buf: absorb comedi_write_array_to_buffer() This function is only called by comedi_buf_write_samples(). Absorb it. The buffer overflow was already checked so the overflow check of comedi_buf_write_alloc() can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 36 ++++++++--------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c3152d89e608..23e3bd175caa 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -474,31 +474,6 @@ static void comedi_buf_memcpy_from(struct comedi_subdevice *s, } } -static unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) -{ - struct comedi_async *async = s->async; - unsigned int retval; - - if (num_bytes == 0) - return 0; - - retval = comedi_buf_write_alloc(s, num_bytes); - if (retval != num_bytes) { - dev_warn(s->device->class_dev, "buffer overrun\n"); - async->events |= COMEDI_CB_OVERFLOW; - return 0; - } - - comedi_buf_memcpy_to(s, data, num_bytes); - comedi_buf_write_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); - async->events |= COMEDI_CB_BLOCK; - - return num_bytes; -} - /** * comedi_buf_write_samples - write sample data to comedi buffer * @s: comedi_subdevice struct @@ -524,9 +499,16 @@ unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, return 0; } - nbytes = nsamples * bytes_per_sample(s); + if (nsamples == 0) + return 0; - return comedi_write_array_to_buffer(s, data, nbytes); + nbytes = comedi_buf_write_alloc(s, nsamples * bytes_per_sample(s)); + comedi_buf_memcpy_to(s, data, nbytes); + comedi_buf_write_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); + s->async->events |= COMEDI_CB_BLOCK; + + return nbytes; } EXPORT_SYMBOL_GPL(comedi_buf_write_samples); -- GitLab From 0cf5efaa4bca230c7b733694932a4355d94dc5e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 22 Oct 2014 15:37:18 -0700 Subject: [PATCH 1885/9457] staging: comedi: comedi_buf: absorb __comedi_buf_write_alloc() This function is only called by comedi_buf_write_alloc(). Absorb it and remove the unused 'strict' parameter. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 23e3bd175caa..6dd87cb2a8af 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -252,15 +252,15 @@ static unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s) return free_end - async->buf_write_alloc_count; } -static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes, - int strict) +/* allocates chunk for the writer from free buffer space */ +unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes) { struct comedi_async *async = s->async; unsigned int available = comedi_buf_write_n_available(s); if (nbytes > available) - nbytes = strict ? 0 : available; + nbytes = available; async->buf_write_alloc_count += nbytes; @@ -272,13 +272,6 @@ static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, return nbytes; } - -/* allocates chunk for the writer from free buffer space */ -unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes) -{ - return __comedi_buf_write_alloc(s, nbytes, 0); -} EXPORT_SYMBOL_GPL(comedi_buf_write_alloc); /* -- GitLab From ac584af599452748187cf6d7865b1607c54ee443 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 23 Oct 2014 12:19:34 -0700 Subject: [PATCH 1886/9457] staging: comedi: me4000: fix firmware downloading Convert this driver to use comedi_load_firmware() to download the firmware to the board. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 93 +++++++++++-------------- 1 file changed, 40 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 97a06749e07d..b5115d8d6170 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -44,8 +44,6 @@ broken. #include #include #include -#include -#include #include "../comedidev.h" @@ -53,10 +51,7 @@ broken. #include "8253.h" #include "plx9052.h" -#if 0 -/* file removed due to GPL incompatibility */ -#include "me4000_fw.h" -#endif +#define ME4000_FIRMWARE "me4000_firmware.bin" /* * ME4000 Register map and bit defines @@ -333,27 +328,20 @@ static const struct comedi_lrange me4000_ai_range = { } }; -#define FIRMWARE_NOT_AVAILABLE 1 -#if FIRMWARE_NOT_AVAILABLE -extern unsigned char *xilinx_firm; -#endif - -static int xilinx_download(struct comedi_device *dev) +static int me4000_xilinx_download(struct comedi_device *dev, + const u8 *data, size_t size, + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct me4000_info *info = dev->private; unsigned long xilinx_iobase = pci_resource_start(pcidev, 5); - u32 value = 0; - wait_queue_head_t queue; - int idx = 0; - int size = 0; - unsigned int intcsr; + unsigned int file_length; + unsigned int val; + unsigned int i; if (!xilinx_iobase) return -ENODEV; - init_waitqueue_head(&queue); - /* * Set PLX local interrupt 2 polarity to high. * Interrupt is thrown by init pin of xilinx. @@ -361,61 +349,58 @@ static int xilinx_download(struct comedi_device *dev) outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR); /* Set /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value |= PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val |= PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); /* Init Xilinx with CS1 */ inb(xilinx_iobase + 0xC8); /* Wait until /INIT pin is set */ udelay(20); - intcsr = inl(info->plx_regbase + PLX9052_INTCSR); - if (!(intcsr & PLX9052_INTCSR_LI2STAT)) { + val = inl(info->plx_regbase + PLX9052_INTCSR); + if (!(val & PLX9052_INTCSR_LI2STAT)) { dev_err(dev->class_dev, "Can't init Xilinx\n"); return -EIO; } /* Reset /CS and /WRITE of the Xilinx */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value &= ~PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); - if (FIRMWARE_NOT_AVAILABLE) { - dev_err(dev->class_dev, - "xilinx firmware unavailable due to licensing, aborting"); - return -EIO; - } else { - /* Download Xilinx firmware */ - size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) + - (xilinx_firm[2] << 8) + xilinx_firm[3]; - udelay(10); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val &= ~PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); - for (idx = 0; idx < size; idx++) { - outb(xilinx_firm[16 + idx], xilinx_iobase); - udelay(10); + /* Download Xilinx firmware */ + file_length = (((unsigned int)data[0] & 0xff) << 24) + + (((unsigned int)data[1] & 0xff) << 16) + + (((unsigned int)data[2] & 0xff) << 8) + + ((unsigned int)data[3] & 0xff); + udelay(10); - /* Check if BUSY flag is low */ - if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) { - dev_err(dev->class_dev, - "Xilinx is still busy (idx = %d)\n", - idx); - return -EIO; - } + for (i = 0; i < file_length; i++) { + outb(data[16 + i], xilinx_iobase); + udelay(10); + + /* Check if BUSY flag is low */ + val = inl(info->plx_regbase + PLX9052_CNTRL); + if (val & PLX9052_CNTRL_UIO1_DATA) { + dev_err(dev->class_dev, + "Xilinx is still busy (i = %d)\n", i); + return -EIO; } } /* If done flag is high download was successful */ - if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) { - } else { + val = inl(info->plx_regbase + PLX9052_CNTRL); + if (!(val & PLX9052_CNTRL_UIO0_DATA)) { dev_err(dev->class_dev, "DONE flag is not set\n"); dev_err(dev->class_dev, "Download not successful\n"); return -EIO; } /* Set /CS and /WRITE */ - value = inl(info->plx_regbase + PLX9052_CNTRL); - value |= PLX9052_CNTRL_UIO2_DATA; - outl(value, info->plx_regbase + PLX9052_CNTRL); + val = inl(info->plx_regbase + PLX9052_CNTRL); + val |= PLX9052_CNTRL_UIO2_DATA; + outl(val, info->plx_regbase + PLX9052_CNTRL); return 0; } @@ -1386,8 +1371,9 @@ static int me4000_auto_attach(struct comedi_device *dev, if (!info->plx_regbase || !dev->iobase || !info->timer_regbase) return -ENODEV; - result = xilinx_download(dev); - if (result) + result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE, + me4000_xilinx_download, 0); + if (result < 0) return result; me4000_reset(dev); @@ -1550,3 +1536,4 @@ module_comedi_pci_driver(me4000_driver, me4000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(ME4000_FIRMWARE); -- GitLab From b3ba2be24cf197cadf3614ee5203ee42ac1109a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 24 Oct 2014 10:26:04 -0700 Subject: [PATCH 1887/9457] staging: comedi: addi_apci_1564: remove APCI1564_COUNTER[1234] defines These defines don't add any significant clarity to the driver. Remove them. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 12 ++++-------- drivers/staging/comedi/drivers/addi_apci_1564.c | 8 ++++---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 98de96953a29..5282f468f36f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -16,10 +16,6 @@ #define ADDIDATA_TIMER 0 #define ADDIDATA_COUNTER 1 #define ADDIDATA_WATCHDOG 2 -#define APCI1564_COUNTER1 0 -#define APCI1564_COUNTER2 1 -#define APCI1564_COUNTER3 2 -#define APCI1564_COUNTER4 3 /* * devpriv->amcc_iobase Register Map @@ -97,13 +93,13 @@ static int apci1564_timer_config(struct comedi_device *dev, outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG); outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG); outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER1)); + APCI1564_COUNTER_IRQ_REG(0)); outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER2)); + APCI1564_COUNTER_IRQ_REG(1)); outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER3)); + APCI1564_COUNTER_IRQ_REG(2)); outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER4)); + APCI1564_COUNTER_IRQ_REG(3)); } else { /* disable Timer interrupt */ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 47b63e176c08..61a7b27b37a1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -65,10 +65,10 @@ static int apci1564_reset(struct comedi_device *dev) outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG); /* Reset the counter registers */ - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER1)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER2)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER3)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER4)); + outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(0)); + outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(1)); + outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(2)); + outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(3)); return 0; } -- GitLab From 367ff14edd97bbd0d54e5bdfeb10201cbe491d0b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 24 Oct 2014 10:26:06 -0700 Subject: [PATCH 1888/9457] staging: comedi: addi_apci_1564: board has 3 timers According to ADDI-DATA, the APCI-1564 only has 3 timers. There are some customer specific boards with 4 timers but they use out of tree drivers. Now that the timer 'channels' are handled correctly in the subdevice functions, fix the number of timer channels for the subdevice and remove the code that would access a 4th timer. Also, remove the unnecessary initialzation of the subdevice 'len_chanlist'. That member is only used by subdevices that support async commands. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 2 -- drivers/staging/comedi/drivers/addi_apci_1564.c | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 5282f468f36f..45f977236162 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -98,8 +98,6 @@ static int apci1564_timer_config(struct comedi_device *dev, APCI1564_COUNTER_IRQ_REG(1)); outl(0x0, dev->iobase + APCI1564_COUNTER_IRQ_REG(2)); - outl(0x0, dev->iobase + - APCI1564_COUNTER_IRQ_REG(3)); } else { /* disable Timer interrupt */ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 61a7b27b37a1..b95da410a8e3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -68,7 +68,6 @@ static int apci1564_reset(struct comedi_device *dev) outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(0)); outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(1)); outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(2)); - outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(3)); return 0; } @@ -434,9 +433,8 @@ static int apci1564_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE; - s->n_chan = 1; + s->n_chan = 3; s->maxdata = 0; - s->len_chanlist = 1; s->range_table = &range_digital; s->insn_write = apci1564_timer_write; s->insn_read = apci1564_timer_read; -- GitLab From 7885b070b83ce5c8fb42bf65047e7dd6388d7b20 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 24 Oct 2014 10:26:05 -0700 Subject: [PATCH 1889/9457] staging: comedi: addi_apci_1564: remove private data 'mode_select_register' This driver currently passes the timer channel as the data[5] element to the timer (*insn_config) function. This is stored in the private data and use in the timer (*insn_read) and (*insn_write) functions to read/write the timer. This is just wrong, comedi passes the channel number in the insn->chanspec. Use that instead and remove the private data member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 24 ++++++++++--------- .../staging/comedi/drivers/addi_apci_1564.c | 1 - 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 45f977236162..ad9949c39eae 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -75,6 +75,7 @@ static int apci1564_timer_config(struct comedi_device *dev, unsigned int *data) { struct apci1564_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); unsigned int ul_Command1 = 0; devpriv->tsk_current = current; @@ -115,19 +116,18 @@ static int apci1564_timer_config(struct comedi_device *dev, outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); } else if (data[0] == ADDIDATA_COUNTER) { devpriv->timer_select_mode = ADDIDATA_COUNTER; - devpriv->mode_select_register = data[5]; /* First Stop The Counter */ ul_Command1 = inl(dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; /* Stop The Timer */ outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); /* Set the reload value */ outl(data[3], dev->iobase + - APCI1564_COUNTER_RELOAD_REG(data[5] - 1)); + APCI1564_COUNTER_RELOAD_REG(chan)); /* Set the mode : */ /* - Disable the hardware */ @@ -141,17 +141,17 @@ static int apci1564_timer_config(struct comedi_device *dev, (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | (unsigned int) ((unsigned int) data[4] << 16UL); outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); /* Enable or Disable Interrupt */ ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1); outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); /* Set the Up/Down selection */ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18); outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(data[5] - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } @@ -170,6 +170,7 @@ static int apci1564_timer_write(struct comedi_device *dev, unsigned int *data) { struct apci1564_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); unsigned int ul_Command1 = 0; if (devpriv->timer_select_mode == ADDIDATA_TIMER) { @@ -189,7 +190,7 @@ static int apci1564_timer_write(struct comedi_device *dev, } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { ul_Command1 = inl(dev->iobase + - APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); if (data[1] == 1) { /* Start the Counter subdevice */ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; @@ -202,7 +203,7 @@ static int apci1564_timer_write(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400; } outl(ul_Command1, dev->iobase + - APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(chan)); } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } @@ -218,6 +219,7 @@ static int apci1564_timer_read(struct comedi_device *dev, unsigned int *data) { struct apci1564_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); unsigned int ul_Command1 = 0; if (devpriv->timer_select_mode == ADDIDATA_TIMER) { @@ -230,10 +232,10 @@ static int apci1564_timer_read(struct comedi_device *dev, /* Read the Counter Actual Value. */ data[0] = inl(dev->iobase + - APCI1564_COUNTER_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_REG(chan)); ul_Command1 = inl(dev->iobase + - APCI1564_COUNTER_STATUS_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_STATUS_REG(chan)); /* Get the software trigger status */ data[1] = (unsigned char) ((ul_Command1 >> 1) & 1); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index b95da410a8e3..c328230b85ec 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -37,7 +37,6 @@ struct apci1564_private { unsigned int mode2; /* falling-edge/low level channels */ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ unsigned char timer_select_mode; - unsigned char mode_select_register; struct task_struct *tsk_current; }; -- GitLab From bf33eb4b4f57d277eac611b5d331976059bcc700 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 23 Oct 2014 13:47:51 +0100 Subject: [PATCH 1890/9457] staging: comedi: introduce some sample size manipulation functions Introduce a few static inline helper functions: `comedi_bytes_per_sample(s)` is the same as the existing `bytes_per_sample(s)` and determines the size of a comedi sample in bytes. (`bytes_per_sample(s)` will be removed.) `comedi_sample_shift(s)` determines the log2 of the comedi sample size, so it can be used in bit-shift operations to multiply or divide by the sample size. `comedi_bytes_to_samples(s, nbytes)` converts a number of bytes to a number of samples (rounding down). `comedi_samples_to_bytes(s, nsamples)` converts a number of samples to a number of bytes. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 63 ++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index f970a8f95cee..d18f70203422 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -413,12 +413,67 @@ static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s, return val ^ s->maxdata ^ (s->maxdata >> 1); } -static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd) +/** + * comedi_bytes_per_sample - determine subdevice sample size + * @s: comedi_subdevice struct + * + * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on + * whether the SDF_LSAMPL subdevice flag is set or not. + * + * Returns the subdevice sample size. + */ +static inline unsigned int comedi_bytes_per_sample(struct comedi_subdevice *s) { - if (subd->subdev_flags & SDF_LSAMPL) - return sizeof(unsigned int); + return s->subdev_flags & SDF_LSAMPL ? sizeof(int) : sizeof(short); +} - return sizeof(short); +/* to be removed */ +static inline unsigned int bytes_per_sample(struct comedi_subdevice *s) +{ + return comedi_bytes_per_sample(s); +} + +/** + * comedi_sample_shift - determine log2 of subdevice sample size + * @s: comedi_subdevice struct + * + * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on + * whether the SDF_LSAMPL subdevice flag is set or not. The log2 of the + * sample size will be 2 or 1 and can be used as the right operand of a + * bit-shift operator to multiply or divide something by the sample size. + * + * Returns log2 of the subdevice sample size. + */ +static inline unsigned int comedi_sample_shift(struct comedi_subdevice *s) +{ + return s->subdev_flags & SDF_LSAMPL ? 2 : 1; +} + +/** + * comedi_bytes_to_samples - converts a number of bytes to a number of samples + * @s: comedi_subdevice struct + * @nbytes: number of bytes + * + * Returns the number of bytes divided by the subdevice sample size. + */ +static inline unsigned int comedi_bytes_to_samples(struct comedi_subdevice *s, + unsigned int nbytes) +{ + return nbytes >> comedi_sample_shift(s); +} + +/** + * comedi_samples_to_bytes - converts a number of samples to a number of bytes + * @s: comedi_subdevice struct + * @nsamples: number of samples + * + * Returns the number of samples multiplied by the subdevice sample size. + * Does not check for arithmetic overflow. + */ +static inline unsigned int comedi_samples_to_bytes(struct comedi_subdevice *s, + unsigned int nsamples) +{ + return nsamples << comedi_sample_shift(s); } /* -- GitLab From 73e0e4dfed4c5c3bd1533321c98f2dac379324f8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 28 Oct 2014 13:07:22 +0000 Subject: [PATCH 1891/9457] staging: comedi: comedi_test: fix timer lock-up Commit 240512474424 ("staging: comedi: comedi_test: use comedi_handle_events()") resulted in the timer routine `waveform_ai_interrupt()` calling `comedi_handle_events()` instead of `comedi_events()`. That had the advantage of automatically stopping the acquisition on overflow/error/end-of-acquisition conditions (by calling the comedi subdevice's "cancel" handler), but currently results in the timer routine locking when one of those conditions occur. This is because the "cancel" handler `waveform_ai_cancel()` calls `del_timer_sync()`. Fix it by adding a bit to the device private data that indicates whether the acquisition is active or not, and changing the "cancel" handler to use `del_timer()` instead of `del_timer_sync()`. The bit is set when starting the acquisition, cleared when ending the acquisition (in the "cancel" handler), and tested in the timer routine, which will do nothing if the acquisition is inactive. Also, make sure any scheduled timeout event gets cancelled when the low-level device gets "detached" from the comedi core by calling `del_timer_sync()` in the "detach" handler `waveform_detach()`. Fixes: 240512474424 ("staging: comedi: comedi_test: use comedi_handle_events()") Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 21 ++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index b8fd4d24b421..8c348bbf9e71 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -56,6 +56,10 @@ zero volts). #define N_CHANS 8 +enum waveform_state_bits { + WAVEFORM_AI_RUNNING = 0 +}; + /* Data unique to this driver */ struct waveform_private { struct timer_list timer; @@ -65,6 +69,7 @@ struct waveform_private { unsigned long usec_current; /* current time (mod waveform period) */ unsigned long usec_remainder; /* usec since last scan */ unsigned long ai_count; /* number of conversions remaining */ + unsigned long state_bits; unsigned int scan_period; /* scan period in usec */ unsigned int convert_period; /* conversion period in usec */ unsigned int ao_loopbacks[N_CHANS]; @@ -175,6 +180,10 @@ static void waveform_ai_interrupt(unsigned long arg) ktime_t now; bool stopping = false; + /* check command is still active */ + if (!test_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits)) + return; + now = ktime_get(); elapsed_time = ktime_to_us(ktime_sub(now, devpriv->last)); @@ -322,6 +331,10 @@ static int waveform_ai_cmd(struct comedi_device *dev, devpriv->usec_remainder = 0; devpriv->timer.expires = jiffies + 1; + /* mark command as active */ + smp_mb__before_atomic(); + set_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); + smp_mb__after_atomic(); add_timer(&devpriv->timer); return 0; } @@ -331,7 +344,11 @@ static int waveform_ai_cancel(struct comedi_device *dev, { struct waveform_private *devpriv = dev->private; - del_timer_sync(&devpriv->timer); + /* mark command as no longer active */ + clear_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits); + smp_mb__after_atomic(); + /* cannot call del_timer_sync() as may be called from timer routine */ + del_timer(&devpriv->timer); return 0; } @@ -433,7 +450,7 @@ static void waveform_detach(struct comedi_device *dev) struct waveform_private *devpriv = dev->private; if (devpriv) - waveform_ai_cancel(dev, dev->read_subdev); + del_timer_sync(&devpriv->timer); } static struct comedi_driver waveform_driver = { -- GitLab From 1bca2822b4420dfc1f7f40bbea5011bbf25e1113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20Gon=C3=A7alves?= Date: Sat, 11 Oct 2014 22:33:39 +0100 Subject: [PATCH 1892/9457] drivers/staging: Removed unnecessary check for LUSTRE_VERSION_CODE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given that this code is now part of the kernel tree, the #ifdef directive comparing LUSTRE_VERSION_CODE to the kernel version is no longer needed. As a side effect, this will also remove the sparse error "directive in argument list". Signed-off-by: Filipe Gonçalves Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/layout.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index 5b8337187b59..78364ec4fbf0 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -980,18 +980,7 @@ EXPORT_SYMBOL(RMF_CONN); struct req_msg_field RMF_CONNECT_DATA = DEFINE_MSGF("cdata", RMF_F_NO_SIZE_CHECK /* we allow extra space for interop */, -#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 7, 50, 0) sizeof(struct obd_connect_data), -#else -/* For interoperability with 1.8 and 2.0 clients/servers. - * The RPC verification code allows larger RPC buffers, but not - * smaller buffers. Until we no longer need to keep compatibility - * with older servers/clients we can only check that the buffer - * size is at least as large as obd_connect_data_v1. That is not - * not in itself harmful, since the chance of just corrupting this - * field is low. See JIRA LU-16 for details. */ - sizeof(struct obd_connect_data_v1), -#endif lustre_swab_connect, NULL); EXPORT_SYMBOL(RMF_CONNECT_DATA); -- GitLab From 0237d9dc94b6e5f1e31c0db90bce6301d0884350 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sat, 11 Oct 2014 22:46:52 -0400 Subject: [PATCH 1893/9457] staging/lustre/ptlrpc: get rid of lustre 1.8 compatible checksums Old version of lustre (1.8) calculated RPC checksums differently, but the compat code is no longer important since in-kernel version of lustre is nto compatible with 1.8 lustre servers (that are long deprecated too). Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/include/lustre_net.h | 5 ---- .../lustre/lustre/ptlrpc/pack_generic.c | 26 ------------------- .../staging/lustre/lustre/ptlrpc/sec_null.c | 18 ------------- 3 files changed, 49 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index d4da2431b407..36396d1c94dc 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -2627,12 +2627,7 @@ __u32 lustre_msg_get_timeout(struct lustre_msg *msg); __u32 lustre_msg_get_service_time(struct lustre_msg *msg); char *lustre_msg_get_jobid(struct lustre_msg *msg); __u32 lustre_msg_get_cksum(struct lustre_msg *msg); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18); -#else -# warning "remove checksum compatibility support for b1_8" __u32 lustre_msg_calc_cksum(struct lustre_msg *msg); -#endif void lustre_msg_set_handle(struct lustre_msg *msg, struct lustre_handle *handle); void lustre_msg_set_type(struct lustre_msg *msg, __u32 type); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 50556db15f79..60552f4e9798 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -1313,43 +1313,17 @@ __u32 lustre_msg_get_cksum(struct lustre_msg *msg) } } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -/* - * In 1.6 and 1.8 the checksum was computed only on struct ptlrpc_body as - * it was in 1.6 (88 bytes, smaller than the full size in 1.8). It makes - * more sense to compute the checksum on the full ptlrpc_body, regardless - * of what size it is, but in order to keep interoperability with 1.8 we - * can optionally also checksum only the first 88 bytes (caller decides). */ -# define ptlrpc_body_cksum_size_compat18 88 - -__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18) -#else -# warning "remove checksum compatibility support for b1_8" __u32 lustre_msg_calc_cksum(struct lustre_msg *msg) -#endif { switch (msg->lm_magic) { case LUSTRE_MSG_MAGIC_V2: { struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - __u32 crc; - unsigned int hsize = 4; - __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 : - lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF); - LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg); - cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb, - len, NULL, 0, (unsigned char *)&crc, - &hsize); - return crc; -#else -# warning "remove checksum compatibility support for b1_8" __u32 crc; unsigned int hsize = 4; cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb, lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF), NULL, 0, (unsigned char *)&crc, &hsize); return crc; -#endif } default: CERROR("incorrect message magic: %08x\n", msg->lm_magic); diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c index 099cec3b669f..4e132435b450 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c @@ -101,16 +101,7 @@ int null_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) if (req->rq_early) { cksums = lustre_msg_get_cksum(req->rq_repdata); -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - if (lustre_msghdr_get_flags(req->rq_reqmsg) & - MSGHDR_CKSUM_INCOMPAT18) - cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 0); - else - cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 1); -#else -# warning "remove checksum compatibility support for b1_8" cksumc = lustre_msg_calc_cksum(req->rq_repmsg); -#endif if (cksumc != cksums) { CDEBUG(D_SEC, "early reply checksum mismatch: %08x != %08x\n", @@ -371,16 +362,7 @@ int null_authorize(struct ptlrpc_request *req) } else { __u32 cksum; -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - if (lustre_msghdr_get_flags(req->rq_reqmsg) & - MSGHDR_CKSUM_INCOMPAT18) - cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 0); - else - cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 1); -#else -# warning "remove checksum compatibility support for b1_8" cksum = lustre_msg_calc_cksum(rs->rs_repbuf); -#endif lustre_msg_set_cksum(rs->rs_repbuf, cksum); req->rq_reply_off = 0; } -- GitLab From 13a7de7bbc7c43dc6c4b16b60034a926aa436277 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sat, 11 Oct 2014 22:46:53 -0400 Subject: [PATCH 1894/9457] staging/lustre: get rid of deprecaed acl mount option code This is long since unused code, so get rid of it. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/llite/llite_lib.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 74cd4515ac50..afb433a33d25 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -818,25 +818,6 @@ static int ll_options(char *options, int *flags) *flags &= ~tmp; goto next; } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 5, 50, 0) - tmp = ll_set_opt("acl", s1, LL_SBI_ACL); - if (tmp) { - /* Ignore deprecated mount option. The client will - * always try to mount with ACL support, whether this - * is used depends on whether server supports it. */ - LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated " - "mount option 'acl'.\n"); - goto next; - } - tmp = ll_set_opt("noacl", s1, LL_SBI_ACL); - if (tmp) { - LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated " - "mount option 'noacl'.\n"); - goto next; - } -#else -#warning "{no}acl options have been deprecated since 1.8, please remove them" -#endif tmp = ll_set_opt("remote_client", s1, LL_SBI_RMT_CLIENT); if (tmp) { *flags |= tmp; -- GitLab From 0017af422bd3edf6dcedc5a87dfb973e3c462db3 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sat, 11 Oct 2014 22:46:54 -0400 Subject: [PATCH 1895/9457] staging/lustre/quota: Get rid of compat quota code Nobody should be using any fo the old lustre 1.8 era tools anymore, so drop compatibility with those. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/dir.c | 58 ------------------- .../lustre/lustre/llite/llite_internal.h | 18 ------ 2 files changed, 76 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index a07e0fe06207..f9b30cfa23ec 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1693,64 +1693,6 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) OBD_FREE_PTR(check); return rc; } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) - case LL_IOC_QUOTACTL_18: { - /* copy the old 1.x quota struct for internal use, then copy - * back into old format struct. For 1.8 compatibility. */ - struct if_quotactl_18 *qctl_18; - struct if_quotactl *qctl_20; - - qctl_18 = kzalloc(sizeof(*qctl_18), GFP_NOFS); - if (!qctl_18) - return -ENOMEM; - - qctl_20 = kzalloc(sizeof(*qctl_20), GFP_NOFS); - if (!qctl_20) { - rc = -ENOMEM; - goto out_quotactl_18; - } - - if (copy_from_user(qctl_18, (void *)arg, sizeof(*qctl_18))) { - rc = -ENOMEM; - goto out_quotactl_20; - } - - QCTL_COPY(qctl_20, qctl_18); - qctl_20->qc_idx = 0; - - /* XXX: dqb_valid was borrowed as a flag to mark that - * only mds quota is wanted */ - if (qctl_18->qc_cmd == Q_GETQUOTA && - qctl_18->qc_dqblk.dqb_valid) { - qctl_20->qc_valid = QC_MDTIDX; - qctl_20->qc_dqblk.dqb_valid = 0; - } else if (qctl_18->obd_uuid.uuid[0] != '\0') { - qctl_20->qc_valid = QC_UUID; - qctl_20->obd_uuid = qctl_18->obd_uuid; - } else { - qctl_20->qc_valid = QC_GENERAL; - } - - rc = quotactl_ioctl(sbi, qctl_20); - - if (rc == 0) { - QCTL_COPY(qctl_18, qctl_20); - qctl_18->obd_uuid = qctl_20->obd_uuid; - - if (copy_to_user((void *)arg, qctl_18, - sizeof(*qctl_18))) - rc = -EFAULT; - } - -out_quotactl_20: - OBD_FREE_PTR(qctl_20); -out_quotactl_18: - OBD_FREE_PTR(qctl_18); - return rc; - } -#else -#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" -#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */ case LL_IOC_QUOTACTL: { struct if_quotactl *qctl; diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 36aa0fd147f2..2845aab282ea 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1509,24 +1509,6 @@ static inline void d_lustre_revalidate(struct dentry *dentry) spin_unlock(&dentry->d_lock); } -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) -/* Compatibility for old (1.8) compiled userspace quota code */ -struct if_quotactl_18 { - __u32 qc_cmd; - __u32 qc_type; - __u32 qc_id; - __u32 qc_stat; - struct obd_dqinfo qc_dqinfo; - struct obd_dqblk qc_dqblk; - char obd_type[16]; - struct obd_uuid obd_uuid; -}; -#define LL_IOC_QUOTACTL_18 _IOWR('f', 162, struct if_quotactl_18 *) -/* End compatibility for old (1.8) compiled userspace quota code */ -#else -#warning "remove old LL_IOC_QUOTACTL_18 compatibility code" -#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */ - enum { LL_LAYOUT_GEN_NONE = ((__u32)-2), /* layout lock was cancelled */ LL_LAYOUT_GEN_EMPTY = ((__u32)-1) /* for empty layout */ -- GitLab From 5a13503ecdf3ee6127b2833ed37dfc5dccb6a3dd Mon Sep 17 00:00:00 2001 From: Anh Le Date: Sun, 12 Oct 2014 16:07:10 +0700 Subject: [PATCH 1896/9457] Staging: lustre: llite: fix some sparse warnings about userspace pointer Add __user macro to the function declarations that accept userspace pointers as arguments. Signed-off-by: Anh Le Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/include/lprocfs_status.h | 6 +- .../staging/lustre/lustre/llite/lproc_llite.c | 56 +++++++++++-------- .../lustre/lustre/obdclass/lprocfs_status.c | 4 +- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index ccb6cd42a67d..54c522667228 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -374,8 +374,8 @@ static inline void s2dhms(struct dhms *ts, time_t secs) #define JOBSTATS_PROCNAME_UID "procname_uid" #define JOBSTATS_NODELOCAL "nodelocal" -extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count, - int *val, int mult); +extern int lprocfs_write_frac_helper(const char __user *buffer, + unsigned long count, int *val, int mult); extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, int mult); #if defined (CONFIG_PROC_FS) @@ -647,7 +647,7 @@ extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data); extern int lprocfs_rd_filestotal(struct seq_file *m, void *data); extern int lprocfs_rd_filesfree(struct seq_file *m, void *data); -extern int lprocfs_write_helper(const char *buffer, unsigned long count, +extern int lprocfs_write_helper(const char __user *buffer, unsigned long count, int *val); extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult); extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count, diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index f175c59dc166..4dc1bfa5c1cf 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -227,8 +227,9 @@ static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v) return lprocfs_seq_read_frac_helper(m, pages_number, mult); } -static ssize_t ll_max_readahead_mb_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_max_readahead_mb_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -269,7 +270,7 @@ static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v) } static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, - const char *buffer, + const char __user *buffer, size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; @@ -313,7 +314,7 @@ static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *unused) } static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, - const char *buffer, + const char __user *buffer, size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; @@ -469,8 +470,9 @@ static int ll_checksum_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0); } -static ssize_t ll_checksum_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_checksum_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -504,8 +506,9 @@ static int ll_max_rw_chunk_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%lu\n", ll_s2sbi(sb)->ll_max_rw_chunk); } -static ssize_t ll_max_rw_chunk_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_max_rw_chunk_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; int rc, val; @@ -533,8 +536,8 @@ static int ll_rd_track_id(struct seq_file *m, enum stats_track_type type) } } -static int ll_wr_track_id(const char *buffer, unsigned long count, void *data, - enum stats_track_type type) +static int ll_wr_track_id(const char __user *buffer, unsigned long count, + void *data, enum stats_track_type type) { struct super_block *sb = data; int rc, pid; @@ -556,8 +559,9 @@ static int ll_track_pid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_PID); } -static ssize_t ll_track_pid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_pid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PID); @@ -569,8 +573,9 @@ static int ll_track_ppid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_PPID); } -static ssize_t ll_track_ppid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_ppid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PPID); @@ -582,8 +587,9 @@ static int ll_track_gid_seq_show(struct seq_file *m, void *v) return ll_rd_track_id(m, STATS_TRACK_GID); } -static ssize_t ll_track_gid_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_track_gid_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct seq_file *seq = file->private_data; return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_GID); @@ -598,8 +604,9 @@ static int ll_statahead_max_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u\n", sbi->ll_sa_max); } -static ssize_t ll_statahead_max_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_statahead_max_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -628,8 +635,9 @@ static int ll_statahead_agl_seq_show(struct seq_file *m, void *v) sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0); } -static ssize_t ll_statahead_agl_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_statahead_agl_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -672,8 +680,9 @@ static int ll_lazystatfs_seq_show(struct seq_file *m, void *v) (sbi->ll_flags & LL_SBI_LAZYSTATFS) ? 1 : 0); } -static ssize_t ll_lazystatfs_seq_write(struct file *file, const char *buffer, - size_t count, loff_t *off) +static ssize_t ll_lazystatfs_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) { struct super_block *sb = ((struct seq_file *)file->private_data)->private; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -787,7 +796,8 @@ static int ll_xattr_cache_seq_show(struct seq_file *m, void *v) return rc; } -static ssize_t ll_xattr_cache_seq_write(struct file *file, const char *buffer, +static ssize_t ll_xattr_cache_seq_write(struct file *file, + const char __user *buffer, size_t count, loff_t *off) { struct seq_file *seq = file->private_data; diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 61e04af2464f..686bc182a9bb 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -177,7 +177,7 @@ int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, } EXPORT_SYMBOL(lprocfs_read_frac_helper); -int lprocfs_write_frac_helper(const char *buffer, unsigned long count, +int lprocfs_write_frac_helper(const char __user *buffer, unsigned long count, int *val, int mult) { char kernbuf[20], *end, *pbuf; @@ -1819,7 +1819,7 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc, } EXPORT_SYMBOL(lprocfs_read_helper); -int lprocfs_write_helper(const char *buffer, unsigned long count, +int lprocfs_write_helper(const char __user *buffer, unsigned long count, int *val) { return lprocfs_write_frac_helper(buffer, count, val, 1); -- GitLab From 22e1dd69fec2f0e887103f6b0dc8e310f649c1c1 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 12 Oct 2014 17:55:33 +0200 Subject: [PATCH 1897/9457] staging: lustre: lustre: ptlrpc: sec.c: Replacing strncat with strlcat to avoid overwrite size Changed from using strncat with strlcat to avoid overwrite the max size. Take the opportunity to change a snprint to strlcpy. Signed-off-by: Rickard Strandqvist Acked-by: Chen Gang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/sec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c index 4ce76852e6ee..6ac8a8330c7c 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -209,7 +209,7 @@ EXPORT_SYMBOL(sptlrpc_flavor2name_bulk); char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize) { - snprintf(buf, bufsize, "%s", sptlrpc_flavor2name_base(sf->sf_rpc)); + strlcpy(buf, sptlrpc_flavor2name_base(sf->sf_rpc), bufsize); /* * currently we don't support customized bulk specification for @@ -220,10 +220,9 @@ char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize) bspec[0] = '-'; sptlrpc_flavor2name_bulk(sf, &bspec[1], sizeof(bspec) - 1); - strncat(buf, bspec, bufsize); + strlcat(buf, bspec, bufsize); } - buf[bufsize - 1] = '\0'; return buf; } EXPORT_SYMBOL(sptlrpc_flavor2name); -- GitLab From 92a1daba3a11c027e491c4850dc35163f4a142b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 16 Oct 2014 10:56:25 +0300 Subject: [PATCH 1898/9457] staging: lustre: silence a static checker warning Static checkers warn that if cfs_cpt_table_print() returns an error other than -EFBIG, then it would lead to a double free. This is true but cfs_cpt_table_print() only returns -EFBIG on error so it also won't happen in real life. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c index bbe2c68c18a6..83d3f08a37b2 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c @@ -365,8 +365,8 @@ static int __proc_cpt_table(void *data, int write, if (rc >= 0) break; - LIBCFS_FREE(buf, len); if (rc == -EFBIG) { + LIBCFS_FREE(buf, len); len <<= 1; continue; } -- GitLab From c654b6bf2cda7e051d1d5ba7e696855511f1105a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 17 Oct 2014 11:49:40 +0200 Subject: [PATCH 1899/9457] pinctrl: at91: use own header Copy the mach/at91_pio.h header locally and use it for pinctrl-at91.c. This allows to remove the dependency on mach/at91_pio.h to be able to move at91 to multiplatform. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Linus Walleij --- MAINTAINERS | 2 +- drivers/pinctrl/pinctrl-at91.c | 4 +- drivers/pinctrl/pinctrl-at91.h | 72 ++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 drivers/pinctrl/pinctrl-at91.h diff --git a/MAINTAINERS b/MAINTAINERS index a20df9bf8ab0..c017d90bc739 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7161,7 +7161,7 @@ PIN CONTROLLER - ATMEL AT91 M: Jean-Christophe Plagniol-Villard L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: drivers/pinctrl/pinctrl-at91.c +F: drivers/pinctrl/pinctrl-at91.* PIN CONTROLLER - RENESAS M: Laurent Pinchart diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 354a81d40925..94643bbaee37 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -25,9 +25,7 @@ /* Since we request GPIOs from ourself */ #include -#include -#include - +#include "pinctrl-at91.h" #include "core.h" #define MAX_GPIO_BANKS 5 diff --git a/drivers/pinctrl/pinctrl-at91.h b/drivers/pinctrl/pinctrl-at91.h new file mode 100644 index 000000000000..79b957f1dfa2 --- /dev/null +++ b/drivers/pinctrl/pinctrl-at91.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Parallel I/O Controller (PIO) - System peripherals registers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __PINCTRL_AT91_H +#define __PINCTRL_AT91_H + +#define PIO_PER 0x00 /* Enable Register */ +#define PIO_PDR 0x04 /* Disable Register */ +#define PIO_PSR 0x08 /* Status Register */ +#define PIO_OER 0x10 /* Output Enable Register */ +#define PIO_ODR 0x14 /* Output Disable Register */ +#define PIO_OSR 0x18 /* Output Status Register */ +#define PIO_IFER 0x20 /* Glitch Input Filter Enable */ +#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */ +#define PIO_IFSR 0x28 /* Glitch Input Filter Status */ +#define PIO_SODR 0x30 /* Set Output Data Register */ +#define PIO_CODR 0x34 /* Clear Output Data Register */ +#define PIO_ODSR 0x38 /* Output Data Status Register */ +#define PIO_PDSR 0x3c /* Pin Data Status Register */ +#define PIO_IER 0x40 /* Interrupt Enable Register */ +#define PIO_IDR 0x44 /* Interrupt Disable Register */ +#define PIO_IMR 0x48 /* Interrupt Mask Register */ +#define PIO_ISR 0x4c /* Interrupt Status Register */ +#define PIO_MDER 0x50 /* Multi-driver Enable Register */ +#define PIO_MDDR 0x54 /* Multi-driver Disable Register */ +#define PIO_MDSR 0x58 /* Multi-driver Status Register */ +#define PIO_PUDR 0x60 /* Pull-up Disable Register */ +#define PIO_PUER 0x64 /* Pull-up Enable Register */ +#define PIO_PUSR 0x68 /* Pull-up Status Register */ +#define PIO_ASR 0x70 /* Peripheral A Select Register */ +#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */ +#define PIO_BSR 0x74 /* Peripheral B Select Register */ +#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */ +#define PIO_ABSR 0x78 /* AB Status Register */ +#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ +#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ +#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ +#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ +#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ +#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ +#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ +#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ +#define PIO_OWER 0xa0 /* Output Write Enable Register */ +#define PIO_OWDR 0xa4 /* Output Write Disable Register */ +#define PIO_OWSR 0xa8 /* Output Write Status Register */ +#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ +#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ +#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ +#define PIO_ESR 0xc0 /* Edge Select Register */ +#define PIO_LSR 0xc4 /* Level Select Register */ +#define PIO_ELSR 0xc8 /* Edge/Level Status Register */ +#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ +#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ +#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ +#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ + +#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/ +#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/ + +#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/ +#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/ + +#endif -- GitLab From 43059f6ba21177f25ab1b10f95149cff1895806a Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 22 Oct 2014 12:58:44 +0300 Subject: [PATCH 1900/9457] pinctrl: Device tree bindings for Qualcomm PMIC GPIO block This introduced the device tree bindings for the GPIO block found in PMIC's from Qualcomm. Signed-off-by: Bjorn Andersson Signed-off-by: Ivan T. Ivanov Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,pmic-gpio.txt | 215 ++++++++++++++++++ include/dt-bindings/pinctrl/qcom,pmic-gpio.h | 142 ++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt create mode 100644 include/dt-bindings/pinctrl/qcom,pmic-gpio.h diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt new file mode 100644 index 000000000000..7ed08048516a --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -0,0 +1,215 @@ +Qualcomm PMIC GPIO block + +This binding describes the GPIO block(s) found in the 8xxx series of +PMIC's from Qualcomm. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,pm8018-gpio" + "qcom,pm8038-gpio" + "qcom,pm8058-gpio" + "qcom,pm8917-gpio" + "qcom,pm8921-gpio" + "qcom,pm8941-gpio" + "qcom,pma8084-gpio" + +- reg: + Usage: required + Value type: + Definition: Register base of the GPIO block and length. + +- interrupts: + Usage: required + Value type: + Definition: Must contain an array of encoded interrupt specifiers for + each available GPIO + +- gpio-controller: + Usage: required + Value type: + Definition: Mark the device node as a GPIO controller + +- #gpio-cells: + Usage: required + Value type: + Definition: Must be 2; + the first cell will be used to define gpio number and the + second denotes the flags for this gpio + +Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for +a general description of GPIO and interrupt bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +The pin configuration nodes act as a container for an arbitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin or a list of pins. This configuration can include the +mux function to select on those pin(s), and various pin configuration +parameters, as listed below. + + +SUBNODES: + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function. + +The following generic properties as defined in pinctrl-bindings.txt are valid +to specify in a pin configuration subnode: + +- pins: + Usage: required + Value type: + Definition: List of gpio pins affected by the properties specified in + this subnode. Valid pins are: + gpio1-gpio6 for pm8018 + gpio1-gpio12 for pm8038 + gpio1-gpio40 for pm8058 + gpio1-gpio38 for pm8917 + gpio1-gpio44 for pm8921 + gpio1-gpio36 for pm8941 + gpio1-gpio22 for pma8084 + +- function: + Usage: required + Value type: + Definition: Specify the alternative function to be configured for the + specified pins. Valid values are: + "normal", + "paired", + "func1", + "func2", + "dtest1", + "dtest2", + "dtest3", + "dtest4" + +- bias-disable: + Usage: optional + Value type: + Definition: The specified pins should be configured as no pull. + +- bias-pull-down: + Usage: optional + Value type: + Definition: The specified pins should be configured as pull down. + +- bias-pull-up: + Usage: optional + Value type: + Definition: The specified pins should be configured as pull up. + +- qcom,pull-up-strength: + Usage: optional + Value type: + Definition: Specifies the strength to use for pull up, if selected. + Valid values are; as defined in + : + 1: 30uA (PMIC_GPIO_PULL_UP_30) + 2: 1.5uA (PMIC_GPIO_PULL_UP_1P5) + 3: 31.5uA (PMIC_GPIO_PULL_UP_31P5) + 4: 1.5uA + 30uA boost (PMIC_GPIO_PULL_UP_1P5_30) + If this property is ommited 30uA strength will be used if + pull up is selected + +- bias-high-impedance: + Usage: optional + Value type: + Definition: The specified pins will put in high-Z mode and disabled. + +- input-enable: + Usage: optional + Value type: + Definition: The specified pins are put in input mode. + +- output-high: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + high. + +- output-low: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + low. + +- power-source: + Usage: optional + Value type: + Definition: Selects the power source for the specified pins. Valid + power sources are defined per chip in + + +- qcom,drive-strength: + Usage: optional + Value type: + Definition: Selects the drive strength for the specified pins. Value + drive strengths are: + 0: no (PMIC_GPIO_STRENGTH_NO) + 1: high (PMIC_GPIO_STRENGTH_HIGH) 0.9mA @ 1.8V - 1.9mA @ 2.6V + 2: medium (PMIC_GPIO_STRENGTH_MED) 0.6mA @ 1.8V - 1.25mA @ 2.6V + 3: low (PMIC_GPIO_STRENGTH_LOW) 0.15mA @ 1.8V - 0.3mA @ 2.6V + as defined in + +- drive-push-pull: + Usage: optional + Value type: + Definition: The specified pins are configured in push-pull mode. + +- drive-open-drain: + Usage: optional + Value type: + Definition: The specified pins are configured in open-drain mode. + +- drive-open-source: + Usage: optional + Value type: + Definition: The specified pins are configured in open-source mode. + +Example: + + pm8921_gpio: gpio@150 { + compatible = "qcom,pm8921-gpio"; + reg = <0x150 0x160>; + interrupts = <192 1>, <193 1>, <194 1>, + <195 1>, <196 1>, <197 1>, + <198 1>, <199 1>, <200 1>, + <201 1>, <202 1>, <203 1>, + <204 1>, <205 1>, <206 1>, + <207 1>, <208 1>, <209 1>, + <210 1>, <211 1>, <212 1>, + <213 1>, <214 1>, <215 1>, + <216 1>, <217 1>, <218 1>, + <219 1>, <220 1>, <221 1>, + <222 1>, <223 1>, <224 1>, + <225 1>, <226 1>, <227 1>, + <228 1>, <229 1>, <230 1>, + <231 1>, <232 1>, <233 1>, + <234 1>, <235 1>; + + gpio-controller; + #gpio-cells = <2>; + + pm8921_gpio_keys: gpio-keys { + volume-keys { + pins = "gpio20", "gpio21"; + function = "normal"; + + input-enable; + bias-pull-up; + drive-push-pull; + qcom,drive-strength = ; + power-source = ; + }; + }; + }; diff --git a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h new file mode 100644 index 000000000000..fa74d7cc960c --- /dev/null +++ b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h @@ -0,0 +1,142 @@ +/* + * This header provides constants for the Qualcomm PMIC GPIO binding. + */ + +#ifndef _DT_BINDINGS_PINCTRL_QCOM_PMIC_GPIO_H +#define _DT_BINDINGS_PINCTRL_QCOM_PMIC_GPIO_H + +#define PMIC_GPIO_PULL_UP_30 0 +#define PMIC_GPIO_PULL_UP_1P5 1 +#define PMIC_GPIO_PULL_UP_31P5 2 +#define PMIC_GPIO_PULL_UP_1P5_30 3 + +#define PMIC_GPIO_STRENGTH_NO 0 +#define PMIC_GPIO_STRENGTH_HIGH 1 +#define PMIC_GPIO_STRENGTH_MED 2 +#define PMIC_GPIO_STRENGTH_LOW 3 + +/* + * Note: PM8018 GPIO3 and GPIO4 are supporting + * only S3 and L2 options (1.8V) + */ +#define PM8018_GPIO_L6 0 +#define PM8018_GPIO_L5 1 +#define PM8018_GPIO_S3 2 +#define PM8018_GPIO_L14 3 +#define PM8018_GPIO_L2 4 +#define PM8018_GPIO_L4 5 +#define PM8018_GPIO_VDD 6 + +/* + * Note: PM8038 GPIO7 and GPIO8 are supporting + * only L11 and L4 options (1.8V) + */ +#define PM8038_GPIO_VPH 0 +#define PM8038_GPIO_BB 1 +#define PM8038_GPIO_L11 2 +#define PM8038_GPIO_L15 3 +#define PM8038_GPIO_L4 4 +#define PM8038_GPIO_L3 5 +#define PM8038_GPIO_L17 6 + +#define PM8058_GPIO_VPH 0 +#define PM8058_GPIO_BB 1 +#define PM8058_GPIO_S3 2 +#define PM8058_GPIO_L3 3 +#define PM8058_GPIO_L7 4 +#define PM8058_GPIO_L6 5 +#define PM8058_GPIO_L5 6 +#define PM8058_GPIO_L2 7 + +#define PM8917_GPIO_VPH 0 +#define PM8917_GPIO_S4 2 +#define PM8917_GPIO_L15 3 +#define PM8917_GPIO_L4 4 +#define PM8917_GPIO_L3 5 +#define PM8917_GPIO_L17 6 + +#define PM8921_GPIO_VPH 0 +#define PM8921_GPIO_BB 1 +#define PM8921_GPIO_S4 2 +#define PM8921_GPIO_L15 3 +#define PM8921_GPIO_L4 4 +#define PM8921_GPIO_L3 5 +#define PM8921_GPIO_L17 6 + +/* + * Note: PM8941 gpios from 15 to 18 are supporting + * only S3 and L6 options (1.8V) + */ +#define PM8941_GPIO_VPH 0 +#define PM8941_GPIO_L1 1 +#define PM8941_GPIO_S3 2 +#define PM8941_GPIO_L6 3 + +/* + * Note: PMA8084 gpios from 15 to 18 are supporting + * only S4 and L6 options (1.8V) + */ +#define PMA8084_GPIO_VPH 0 +#define PMA8084_GPIO_L1 1 +#define PMA8084_GPIO_S4 2 +#define PMA8084_GPIO_L6 3 + +/* To be used with "function" */ +#define PMIC_GPIO_FUNC_NORMAL "normal" +#define PMIC_GPIO_FUNC_PAIRED "paired" +#define PMIC_GPIO_FUNC_FUNC1 "func1" +#define PMIC_GPIO_FUNC_FUNC2 "func2" +#define PMIC_GPIO_FUNC_DTEST1 "dtest1" +#define PMIC_GPIO_FUNC_DTEST2 "dtest2" +#define PMIC_GPIO_FUNC_DTEST3 "dtest3" +#define PMIC_GPIO_FUNC_DTEST4 "dtest4" + +#define PM8038_GPIO1_2_LPG_DRV PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO3_5V_BOOST_EN PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO4_SSBI_ALT_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO5_6_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO10_11_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO6_7_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO9_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1 +#define PM8038_GPIO6_12_KYPD_DRV PMIC_GPIO_FUNC_FUNC2 + +#define PM8058_GPIO7_8_MP3_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO7_8_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC2 +#define PM8058_GPIO9_26_KYPD_DRV PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO21_23_UART_TX PMIC_GPIO_FUNC_FUNC2 +#define PM8058_GPIO24_26_LPG_DRV PMIC_GPIO_FUNC_FUNC2 +#define PM8058_GPIO33_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO34_35_MP3_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO36_BCLK_19P2MHZ PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO37_UPL_OUT PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO37_UART_M_RX PMIC_GPIO_FUNC_FUNC2 +#define PM8058_GPIO38_XO_SLEEP_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO38_39_CLK_32KHZ PMIC_GPIO_FUNC_FUNC2 +#define PM8058_GPIO39_MP3_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8058_GPIO40_EXT_BB_EN PMIC_GPIO_FUNC_FUNC1 + +#define PM8917_GPIO9_18_KEYP_DRV PMIC_GPIO_FUNC_FUNC1 +#define PM8917_GPIO20_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1 +#define PM8917_GPIO21_23_UART_TX PMIC_GPIO_FUNC_FUNC2 +#define PM8917_GPIO25_26_EXT_REG_EN PMIC_GPIO_FUNC_FUNC1 +#define PM8917_GPIO37_38_XO_SLEEP_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8917_GPIO37_38_MP3_CLK PMIC_GPIO_FUNC_FUNC2 + +#define PM8941_GPIO9_14_KYPD_DRV PMIC_GPIO_FUNC_FUNC1 +#define PM8941_GPIO15_18_DIV_CLK PMIC_GPIO_FUNC_FUNC1 +#define PM8941_GPIO15_18_SLEEP_CLK PMIC_GPIO_FUNC_FUNC2 +#define PM8941_GPIO23_26_KYPD_DRV PMIC_GPIO_FUNC_FUNC1 +#define PM8941_GPIO23_26_LPG_DRV_HI PMIC_GPIO_FUNC_FUNC2 +#define PM8941_GPIO31_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1 +#define PM8941_GPIO33_36_LPG_DRV_3D PMIC_GPIO_FUNC_FUNC1 +#define PM8941_GPIO33_36_LPG_DRV_HI PMIC_GPIO_FUNC_FUNC2 + +#define PMA8084_GPIO4_5_LPG_DRV PMIC_GPIO_FUNC_FUNC1 +#define PMA8084_GPIO7_10_LPG_DRV PMIC_GPIO_FUNC_FUNC1 +#define PMA8084_GPIO5_14_KEYP_DRV PMIC_GPIO_FUNC_FUNC2 +#define PMA8084_GPIO19_21_KEYP_DRV PMIC_GPIO_FUNC_FUNC2 +#define PMA8084_GPIO15_18_DIV_CLK PMIC_GPIO_FUNC_FUNC1 +#define PMA8084_GPIO15_18_SLEEP_CLK PMIC_GPIO_FUNC_FUNC2 +#define PMA8084_GPIO22_BAT_ALRM_OUT PMIC_GPIO_FUNC_FUNC1 + +#endif -- GitLab From 89a7117d56d405b49b7d1f8ed30e01188e9d5a05 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 22 Oct 2014 12:58:45 +0300 Subject: [PATCH 1901/9457] pinctrl: Device tree bindings for Qualcomm PMIC MPP block DeviceTree binding documentation for Qualcomm SPMI PMIC MPP pinctrl drivers. Signed-off-by: Ivan T. Ivanov Acked-by: Bjorn Andersson Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,pmic-mpp.txt | 162 ++++++++++++++++++ include/dt-bindings/pinctrl/qcom,pmic-mpp.h | 44 +++++ 2 files changed, 206 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt create mode 100644 include/dt-bindings/pinctrl/qcom,pmic-mpp.h diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt new file mode 100644 index 000000000000..854774b194ed --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt @@ -0,0 +1,162 @@ +Qualcomm PMIC Multi-Purpose Pin (MPP) block + +This binding describes the MPP block(s) found in the 8xxx series +of PMIC's from Qualcomm. + +- compatible: + Usage: required + Value type: + Definition: Should contain one of: + "qcom,pm8841-mpp", + "qcom,pm8941-mpp", + "qcom,pma8084-mpp", + +- reg: + Usage: required + Value type: + Definition: Register base of the MPP block and length. + +- interrupts: + Usage: required + Value type: + Definition: Must contain an array of encoded interrupt specifiers for + each available MPP + +- gpio-controller: + Usage: required + Value type: + Definition: Mark the device node as a GPIO controller + +- #gpio-cells: + Usage: required + Value type: + Definition: Must be 2; + the first cell will be used to define MPP number and the + second denotes the flags for this MPP + +Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for +a general description of GPIO and interrupt bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +The pin configuration nodes act as a container for an arbitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin or a list of pins. This configuration can include the +mux function to select on those pin(s), and various pin configuration +parameters, as listed below. + +SUBNODES: + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function. + +The following generic properties as defined in pinctrl-bindings.txt are valid +to specify in a pin configuration subnode: + +- pins: + Usage: required + Value type: + Definition: List of MPP pins affected by the properties specified in + this subnode. Valid pins are: + mpp1-mpp4 for pm8841 + mpp1-mpp8 for pm8941 + mpp1-mpp4 for pma8084 + +- function: + Usage: required + Value type: + Definition: Specify the alternative function to be configured for the + specified pins. Valid values are: + "normal", + "paired", + "dtest1", + "dtest2", + "dtest3", + "dtest4" + +- bias-disable: + Usage: optional + Value type: + Definition: The specified pins should be configured as no pull. + +- bias-pull-up: + Usage: optional + Value type: + Definition: The specified pins should be configured as pull up. + Valid values are 600, 10000 and 30000 in bidirectional mode + only, i.e. when operating in qcom,analog-mode and input and + outputs are enabled. The hardware ignores the configuration + when operating in other modes. + +- bias-high-impedance: + Usage: optional + Value type: + Definition: The specified pins will put in high-Z mode and disabled. + +- input-enable: + Usage: optional + Value type: + Definition: The specified pins are put in input mode, i.e. their input + buffer is enabled + +- output-high: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + high. + +- output-low: + Usage: optional + Value type: + Definition: The specified pins are configured in output mode, driven + low. + +- power-source: + Usage: optional + Value type: + Definition: Selects the power source for the specified pins. Valid power + sources are defined in + +- qcom,analog-mode: + Usage: optional + Value type: + Definition: Selects Analog mode of operation: combined with input-enable + and/or output-high, output-low MPP could operate as + Bidirectional Logic, Analog Input, Analog Output. + +- qcom,amux-route: + Usage: optional + Value type: + Definition: Selects the source for analog input. Valid values are + defined in + PMIC_MPP_AMUX_ROUTE_CH5, PMIC_MPP_AMUX_ROUTE_CH6... + +Example: + + mpps@a000 { + compatible = "qcom,pm8841-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <4 0xa0 0 0>, <4 0xa1 0 0>, <4 0xa2 0 0>, <4 0xa3 0 0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pm8841_default>; + + pm8841_default: default { + gpio { + pins = "mpp1", "mpp2", "mpp3", "mpp4"; + function = "normal"; + input-enable; + power-source = ; + }; + }; + }; diff --git a/include/dt-bindings/pinctrl/qcom,pmic-mpp.h b/include/dt-bindings/pinctrl/qcom,pmic-mpp.h new file mode 100644 index 000000000000..d2c7dabe3223 --- /dev/null +++ b/include/dt-bindings/pinctrl/qcom,pmic-mpp.h @@ -0,0 +1,44 @@ +/* + * This header provides constants for the Qualcomm PMIC's + * Multi-Purpose Pin binding. + */ + +#ifndef _DT_BINDINGS_PINCTRL_QCOM_PMIC_MPP_H +#define _DT_BINDINGS_PINCTRL_QCOM_PMIC_MPP_H + +/* power-source */ +#define PM8841_MPP_VPH 0 +#define PM8841_MPP_S3 2 + +#define PM8941_MPP_VPH 0 +#define PM8941_MPP_L1 1 +#define PM8941_MPP_S3 2 +#define PM8941_MPP_L6 3 + +#define PMA8084_MPP_VPH 0 +#define PMA8084_MPP_L1 1 +#define PMA8084_MPP_S4 2 +#define PMA8084_MPP_L6 3 + +/* + * Analog Input - Set the source for analog input. + * To be used with "qcom,amux-route" property + */ +#define PMIC_MPP_AMUX_ROUTE_CH5 0 +#define PMIC_MPP_AMUX_ROUTE_CH6 1 +#define PMIC_MPP_AMUX_ROUTE_CH7 2 +#define PMIC_MPP_AMUX_ROUTE_CH8 3 +#define PMIC_MPP_AMUX_ROUTE_ABUS1 4 +#define PMIC_MPP_AMUX_ROUTE_ABUS2 5 +#define PMIC_MPP_AMUX_ROUTE_ABUS3 6 +#define PMIC_MPP_AMUX_ROUTE_ABUS4 7 + +/* To be used with "function" */ +#define PMIC_MPP_FUNC_NORMAL "normal" +#define PMIC_MPP_FUNC_PAIRED "paired" +#define PMIC_MPP_FUNC_DTEST1 "dtest1" +#define PMIC_MPP_FUNC_DTEST2 "dtest2" +#define PMIC_MPP_FUNC_DTEST3 "dtest3" +#define PMIC_MPP_FUNC_DTEST4 "dtest4" + +#endif -- GitLab From eadff3024472f8a7955fae7e5484d235ed407453 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 22 Oct 2014 12:58:46 +0300 Subject: [PATCH 1902/9457] pinctrl: Qualcomm SPMI PMIC GPIO pin controller driver This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm GPIO sub-function blocks found in the PMIC chips. Signed-off-by: Ivan T. Ivanov Acked-by: Bjorn Andersson Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 13 + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 933 +++++++++++++++++++++++ 3 files changed, 947 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 81275af9638b..3cd243c26b7d 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -47,4 +47,17 @@ config PINCTRL_MSM8X74 This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm TLMM block found in the Qualcomm 8974 platform. +config PINCTRL_QCOM_SPMI_PMIC + tristate "Qualcomm SPMI PMIC pin controller driver" + depends on GPIOLIB && OF && SPMI + select REGMAP_SPMI + select PINMUX + select PINCONF + select GENERIC_PINCONF + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm GPIO and MPP blocks found in the Qualcomm PMIC's chips, + which are using SPMI for communication with SoC. Example PMIC's + devices are pm8841, pm8941 and pma8084. + endif diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index ba8519fcd8d3..9b49c65a1cab 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_PINCTRL_APQ8084) += pinctrl-apq8084.o obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o +obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c new file mode 100644 index 000000000000..b863b5080890 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -0,0 +1,933 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define PMIC_GPIO_ADDRESS_RANGE 0x100 + +/* type and subtype registers base address offsets */ +#define PMIC_GPIO_REG_TYPE 0x4 +#define PMIC_GPIO_REG_SUBTYPE 0x5 + +/* GPIO peripheral type and subtype out_values */ +#define PMIC_GPIO_TYPE 0x10 +#define PMIC_GPIO_SUBTYPE_GPIO_4CH 0x1 +#define PMIC_GPIO_SUBTYPE_GPIOC_4CH 0x5 +#define PMIC_GPIO_SUBTYPE_GPIO_8CH 0x9 +#define PMIC_GPIO_SUBTYPE_GPIOC_8CH 0xd + +#define PMIC_MPP_REG_RT_STS 0x10 +#define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 + +/* control register base address offsets */ +#define PMIC_GPIO_REG_MODE_CTL 0x40 +#define PMIC_GPIO_REG_DIG_VIN_CTL 0x41 +#define PMIC_GPIO_REG_DIG_PULL_CTL 0x42 +#define PMIC_GPIO_REG_DIG_OUT_CTL 0x45 +#define PMIC_GPIO_REG_EN_CTL 0x46 + +/* PMIC_GPIO_REG_MODE_CTL */ +#define PMIC_GPIO_REG_MODE_VALUE_SHIFT 0x1 +#define PMIC_GPIO_REG_MODE_FUNCTION_SHIFT 1 +#define PMIC_GPIO_REG_MODE_FUNCTION_MASK 0x7 +#define PMIC_GPIO_REG_MODE_DIR_SHIFT 4 +#define PMIC_GPIO_REG_MODE_DIR_MASK 0x7 + +/* PMIC_GPIO_REG_DIG_VIN_CTL */ +#define PMIC_GPIO_REG_VIN_SHIFT 0 +#define PMIC_GPIO_REG_VIN_MASK 0x7 + +/* PMIC_GPIO_REG_DIG_PULL_CTL */ +#define PMIC_GPIO_REG_PULL_SHIFT 0 +#define PMIC_GPIO_REG_PULL_MASK 0x7 + +#define PMIC_GPIO_PULL_DOWN 4 +#define PMIC_GPIO_PULL_DISABLE 5 + +/* PMIC_GPIO_REG_DIG_OUT_CTL */ +#define PMIC_GPIO_REG_OUT_STRENGTH_SHIFT 0 +#define PMIC_GPIO_REG_OUT_STRENGTH_MASK 0x3 +#define PMIC_GPIO_REG_OUT_TYPE_SHIFT 4 +#define PMIC_GPIO_REG_OUT_TYPE_MASK 0x3 + +/* + * Output type - indicates pin should be configured as push-pull, + * open drain or open source. + */ +#define PMIC_GPIO_OUT_BUF_CMOS 0 +#define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1 +#define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2 + +/* PMIC_GPIO_REG_EN_CTL */ +#define PMIC_GPIO_REG_MASTER_EN_SHIFT 7 + +#define PMIC_GPIO_PHYSICAL_OFFSET 1 + +/* Qualcomm specific pin configurations */ +#define PMIC_GPIO_CONF_PULL_UP (PIN_CONFIG_END + 1) +#define PMIC_GPIO_CONF_STRENGTH (PIN_CONFIG_END + 2) + +/** + * struct pmic_gpio_pad - keep current GPIO settings + * @base: Address base in SPMI device. + * @irq: IRQ number which this GPIO generate. + * @is_enabled: Set to false when GPIO should be put in high Z state. + * @out_value: Cached pin output value + * @have_buffer: Set to true if GPIO output could be configured in push-pull, + * open-drain or open-source mode. + * @output_enabled: Set to true if GPIO output logic is enabled. + * @input_enabled: Set to true if GPIO input buffer logic is enabled. + * @num_sources: Number of power-sources supported by this GPIO. + * @power_source: Current power-source used. + * @buffer_type: Push-pull, open-drain or open-source. + * @pullup: Constant current which flow trough GPIO output buffer. + * @strength: No, Low, Medium, High + * @function: See pmic_gpio_functions[] + */ +struct pmic_gpio_pad { + u16 base; + int irq; + bool is_enabled; + bool out_value; + bool have_buffer; + bool output_enabled; + bool input_enabled; + unsigned int num_sources; + unsigned int power_source; + unsigned int buffer_type; + unsigned int pullup; + unsigned int strength; + unsigned int function; +}; + +struct pmic_gpio_state { + struct device *dev; + struct regmap *map; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; +}; + +struct pmic_gpio_bindings { + const char *property; + unsigned param; +}; + +static struct pmic_gpio_bindings pmic_gpio_bindings[] = { + {"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP}, + {"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH}, +}; + +static const char *const pmic_gpio_groups[] = { + "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", + "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15", + "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", + "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", + "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", +}; + +static const char *const pmic_gpio_functions[] = { + PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED, + PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2, + PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2, + PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4, +}; + +static inline struct pmic_gpio_state *to_gpio_state(struct gpio_chip *chip) +{ + return container_of(chip, struct pmic_gpio_state, chip); +}; + +static int pmic_gpio_read(struct pmic_gpio_state *state, + struct pmic_gpio_pad *pad, unsigned int addr) +{ + unsigned int val; + int ret; + + ret = regmap_read(state->map, pad->base + addr, &val); + if (ret < 0) + dev_err(state->dev, "read 0x%x failed\n", addr); + else + ret = val; + + return ret; +} + +static int pmic_gpio_write(struct pmic_gpio_state *state, + struct pmic_gpio_pad *pad, unsigned int addr, + unsigned int val) +{ + int ret; + + ret = regmap_write(state->map, pad->base + addr, val); + if (ret < 0) + dev_err(state->dev, "write 0x%x failed\n", addr); + + return ret; +} + +static int pmic_gpio_get_groups_count(struct pinctrl_dev *pctldev) +{ + /* Every PIN is a group */ + return pctldev->desc->npins; +} + +static const char *pmic_gpio_get_group_name(struct pinctrl_dev *pctldev, + unsigned pin) +{ + return pctldev->desc->pins[pin].name; +} + +static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned pin, + const unsigned **pins, unsigned *num_pins) +{ + *pins = &pctldev->desc->pins[pin].number; + *num_pins = 1; + return 0; +} + +static int pmic_gpio_parse_dt_config(struct device_node *np, + struct pinctrl_dev *pctldev, + unsigned long **configs, + unsigned int *nconfs) +{ + struct pmic_gpio_bindings *par; + unsigned long cfg; + int ret, i; + u32 val; + + for (i = 0; i < ARRAY_SIZE(pmic_gpio_bindings); i++) { + par = &pmic_gpio_bindings[i]; + ret = of_property_read_u32(np, par->property, &val); + + /* property not found */ + if (ret == -EINVAL) + continue; + + /* use zero as default value */ + if (ret) + val = 0; + + dev_dbg(pctldev->dev, "found %s with value %u\n", + par->property, val); + + cfg = pinconf_to_config_packed(par->param, val); + + ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg); + if (ret) + return ret; + } + + return 0; +} + +static int pmic_gpio_dt_subnode_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *reserv, unsigned *nmaps, + enum pinctrl_map_type type) +{ + unsigned long *configs = NULL; + unsigned nconfs = 0; + struct property *prop; + const char *group; + int ret; + + ret = pmic_gpio_parse_dt_config(np, pctldev, &configs, &nconfs); + if (ret < 0) + return ret; + + if (!nconfs) + return 0; + + ret = of_property_count_strings(np, "pins"); + if (ret < 0) + goto exit; + + ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret); + if (ret < 0) + goto exit; + + of_property_for_each_string(np, "pins", prop, group) { + ret = pinctrl_utils_add_map_configs(pctldev, map, + reserv, nmaps, group, + configs, nconfs, type); + if (ret < 0) + break; + } +exit: + kfree(configs); + return ret; +} + +static int pmic_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, unsigned *nmaps) +{ + enum pinctrl_map_type type; + struct device_node *np; + unsigned reserv; + int ret; + + ret = 0; + *map = NULL; + *nmaps = 0; + reserv = 0; + type = PIN_MAP_TYPE_CONFIGS_GROUP; + + for_each_child_of_node(np_config, np) { + ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, + &reserv, nmaps, type); + if (ret) + break; + + ret = pmic_gpio_dt_subnode_to_map(pctldev, np, map, &reserv, + nmaps, type); + if (ret) + break; + } + + if (ret < 0) + pinctrl_utils_dt_free_map(pctldev, *map, *nmaps); + + return ret; +} + +static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { + .get_groups_count = pmic_gpio_get_groups_count, + .get_group_name = pmic_gpio_get_group_name, + .get_group_pins = pmic_gpio_get_group_pins, + .dt_node_to_map = pmic_gpio_dt_node_to_map, + .dt_free_map = pinctrl_utils_dt_free_map, +}; + +static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(pmic_gpio_functions); +} + +static const char *pmic_gpio_get_function_name(struct pinctrl_dev *pctldev, + unsigned function) +{ + return pmic_gpio_functions[function]; +} + +static int pmic_gpio_get_function_groups(struct pinctrl_dev *pctldev, + unsigned function, + const char *const **groups, + unsigned *const num_qgroups) +{ + *groups = pmic_gpio_groups; + *num_qgroups = pctldev->desc->npins; + return 0; +} + +static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function, + unsigned pin) +{ + struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_gpio_pad *pad; + unsigned int val; + int ret; + + pad = pctldev->desc->pins[pin].drv_data; + + pad->function = function; + + val = 0; + if (pad->output_enabled) { + if (pad->input_enabled) + val = 2; + else + val = 1; + } + + val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; + val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; + + ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); + if (ret < 0) + return ret; + + val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; + + return pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); +} + +static const struct pinmux_ops pmic_gpio_pinmux_ops = { + .get_functions_count = pmic_gpio_get_functions_count, + .get_function_name = pmic_gpio_get_function_name, + .get_function_groups = pmic_gpio_get_function_groups, + .set_mux = pmic_gpio_set_mux, +}; + +static int pmic_gpio_config_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + unsigned param = pinconf_to_config_param(*config); + struct pmic_gpio_pad *pad; + unsigned arg; + + pad = pctldev->desc->pins[pin].drv_data; + + switch (param) { + case PIN_CONFIG_DRIVE_PUSH_PULL: + arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_CMOS; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = pad->pullup == PMIC_GPIO_PULL_DOWN; + break; + case PIN_CONFIG_BIAS_DISABLE: + arg = pad->pullup = PMIC_GPIO_PULL_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_UP: + arg = pad->pullup == PMIC_GPIO_PULL_UP_30; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + arg = !pad->is_enabled; + break; + case PIN_CONFIG_POWER_SOURCE: + arg = pad->power_source; + break; + case PIN_CONFIG_INPUT_ENABLE: + arg = pad->input_enabled; + break; + case PIN_CONFIG_OUTPUT: + arg = pad->out_value; + break; + case PMIC_GPIO_CONF_PULL_UP: + arg = pad->pullup; + break; + case PMIC_GPIO_CONF_STRENGTH: + arg = pad->strength; + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned nconfs) +{ + struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_gpio_pad *pad; + unsigned param, arg; + unsigned int val; + int i, ret; + + pad = pctldev->desc->pins[pin].drv_data; + + for (i = 0; i < nconfs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_DRIVE_PUSH_PULL: + pad->buffer_type = PMIC_GPIO_OUT_BUF_CMOS; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!pad->have_buffer) + return -EINVAL; + pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + if (!pad->have_buffer) + return -EINVAL; + pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; + break; + case PIN_CONFIG_BIAS_DISABLE: + pad->pullup = PMIC_GPIO_PULL_DISABLE; + break; + case PIN_CONFIG_BIAS_PULL_UP: + pad->pullup = PMIC_GPIO_PULL_UP_30; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (arg) + pad->pullup = PMIC_GPIO_PULL_DOWN; + else + pad->pullup = PMIC_GPIO_PULL_DISABLE; + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + pad->is_enabled = false; + break; + case PIN_CONFIG_POWER_SOURCE: + if (arg > pad->num_sources) + return -EINVAL; + pad->power_source = arg; + break; + case PIN_CONFIG_INPUT_ENABLE: + pad->input_enabled = arg ? true : false; + break; + case PIN_CONFIG_OUTPUT: + pad->output_enabled = true; + pad->out_value = arg; + break; + case PMIC_GPIO_CONF_PULL_UP: + if (arg > PMIC_GPIO_PULL_UP_1P5_30) + return -EINVAL; + pad->pullup = arg; + break; + case PMIC_GPIO_CONF_STRENGTH: + if (arg > PMIC_GPIO_STRENGTH_LOW) + return -EINVAL; + pad->strength = arg; + break; + default: + return -EINVAL; + } + } + + val = pad->power_source << PMIC_GPIO_REG_VIN_SHIFT; + + ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL, val); + if (ret < 0) + return ret; + + val = pad->pullup << PMIC_GPIO_REG_PULL_SHIFT; + + ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL, val); + if (ret < 0) + return ret; + + val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; + val = pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; + + ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); + if (ret < 0) + return ret; + + val = 0; + if (pad->output_enabled) { + if (pad->input_enabled) + val = 2; + else + val = 1; + } + + val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; + val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; + val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; + + return pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); +} + +static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned pin) +{ + struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_gpio_pad *pad; + int ret, val; + + static const char *const biases[] = { + "pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA", + "pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull" + }; + static const char *const buffer_types[] = { + "push-pull", "open-drain", "open-source" + }; + static const char *const strengths[] = { + "no", "high", "medium", "low" + }; + + pad = pctldev->desc->pins[pin].drv_data; + + seq_printf(s, " gpio%-2d:", pin + PMIC_GPIO_PHYSICAL_OFFSET); + + val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_EN_CTL); + + if (val < 0 || !(val >> PMIC_GPIO_REG_MASTER_EN_SHIFT)) { + seq_puts(s, " ---"); + } else { + + if (!pad->input_enabled) { + ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); + if (!ret) { + ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; + pad->out_value = ret; + } + } + + seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); + seq_printf(s, " %-7s", pmic_gpio_functions[pad->function]); + seq_printf(s, " vin-%d", pad->power_source); + seq_printf(s, " %-27s", biases[pad->pullup]); + seq_printf(s, " %-10s", buffer_types[pad->buffer_type]); + seq_printf(s, " %-4s", pad->out_value ? "high" : "low"); + seq_printf(s, " %-7s", strengths[pad->strength]); + } +} + +static const struct pinconf_ops pmic_gpio_pinconf_ops = { + .pin_config_group_get = pmic_gpio_config_get, + .pin_config_group_set = pmic_gpio_config_set, + .pin_config_group_dbg_show = pmic_gpio_config_dbg_show, +}; + +static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); + + return pmic_gpio_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_gpio_direction_output(struct gpio_chip *chip, + unsigned pin, int val) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); + + return pmic_gpio_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + struct pmic_gpio_pad *pad; + int ret; + + pad = state->ctrl->desc->pins[pin].drv_data; + + if (!pad->is_enabled) + return -EINVAL; + + if (pad->input_enabled) { + ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); + if (ret < 0) + return ret; + + pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK; + } + + return pad->out_value; +} + +static void pmic_gpio_set(struct gpio_chip *chip, unsigned pin, int value) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); + + pmic_gpio_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_gpio_request(struct gpio_chip *chip, unsigned base) +{ + return pinctrl_request_gpio(chip->base + base); +} + +static void pmic_gpio_free(struct gpio_chip *chip, unsigned base) +{ + pinctrl_free_gpio(chip->base + base); +} + +static int pmic_gpio_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *gpio_desc, + u32 *flags) +{ + if (chip->of_gpio_n_cells < 2) + return -EINVAL; + + if (flags) + *flags = gpio_desc->args[1]; + + return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET; +} + +static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + struct pmic_gpio_pad *pad; + + pad = state->ctrl->desc->pins[pin].drv_data; + + return pad->irq; +} + +static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + struct pmic_gpio_state *state = to_gpio_state(chip); + unsigned i; + + for (i = 0; i < chip->ngpio; i++) { + pmic_gpio_config_dbg_show(state->ctrl, s, i); + seq_puts(s, "\n"); + } +} + +static const struct gpio_chip pmic_gpio_gpio_template = { + .direction_input = pmic_gpio_direction_input, + .direction_output = pmic_gpio_direction_output, + .get = pmic_gpio_get, + .set = pmic_gpio_set, + .request = pmic_gpio_request, + .free = pmic_gpio_free, + .of_xlate = pmic_gpio_of_xlate, + .to_irq = pmic_gpio_to_irq, + .dbg_show = pmic_gpio_dbg_show, +}; + +static int pmic_gpio_populate(struct pmic_gpio_state *state, + struct pmic_gpio_pad *pad) +{ + int type, subtype, val, dir; + + type = pmic_gpio_read(state, pad, PMIC_GPIO_REG_TYPE); + if (type < 0) + return type; + + if (type != PMIC_GPIO_TYPE) { + dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n", + type, pad->base); + return -ENODEV; + } + + subtype = pmic_gpio_read(state, pad, PMIC_GPIO_REG_SUBTYPE); + if (subtype < 0) + return subtype; + + switch (subtype) { + case PMIC_GPIO_SUBTYPE_GPIO_4CH: + pad->have_buffer = true; + case PMIC_GPIO_SUBTYPE_GPIOC_4CH: + pad->num_sources = 4; + break; + case PMIC_GPIO_SUBTYPE_GPIO_8CH: + pad->have_buffer = true; + case PMIC_GPIO_SUBTYPE_GPIOC_8CH: + pad->num_sources = 8; + break; + default: + dev_err(state->dev, "unknown GPIO type 0x%x\n", subtype); + return -ENODEV; + } + + val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_MODE_CTL); + if (val < 0) + return val; + + pad->out_value = val & PMIC_GPIO_REG_MODE_VALUE_SHIFT; + + dir = val >> PMIC_GPIO_REG_MODE_DIR_SHIFT; + dir &= PMIC_GPIO_REG_MODE_DIR_MASK; + switch (dir) { + case 0: + pad->input_enabled = true; + pad->output_enabled = false; + break; + case 1: + pad->input_enabled = false; + pad->output_enabled = true; + break; + case 2: + pad->input_enabled = true; + pad->output_enabled = true; + break; + default: + dev_err(state->dev, "unknown GPIO direction\n"); + return -ENODEV; + } + + pad->function = val >> PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; + pad->function &= PMIC_GPIO_REG_MODE_FUNCTION_MASK; + + val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL); + if (val < 0) + return val; + + pad->power_source = val >> PMIC_GPIO_REG_VIN_SHIFT; + pad->power_source &= PMIC_GPIO_REG_VIN_MASK; + + val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL); + if (val < 0) + return val; + + pad->pullup = val >> PMIC_GPIO_REG_PULL_SHIFT; + pad->pullup &= PMIC_GPIO_REG_PULL_MASK; + + val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL); + if (val < 0) + return val; + + pad->strength = val >> PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; + pad->strength &= PMIC_GPIO_REG_OUT_STRENGTH_MASK; + + pad->buffer_type = val >> PMIC_GPIO_REG_OUT_TYPE_SHIFT; + pad->buffer_type &= PMIC_GPIO_REG_OUT_TYPE_MASK; + + /* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */ + pad->is_enabled = true; + return 0; +} + +static int pmic_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_pin_desc *pindesc; + struct pinctrl_desc *pctrldesc; + struct pmic_gpio_pad *pad, *pads; + struct pmic_gpio_state *state; + int ret, npins, i; + u32 res[2]; + + ret = of_property_read_u32_array(dev->of_node, "reg", res, 2); + if (ret < 0) { + dev_err(dev, "missing base address and/or range"); + return ret; + } + + npins = res[1] / PMIC_GPIO_ADDRESS_RANGE; + + if (!npins) + return -EINVAL; + + BUG_ON(npins > ARRAY_SIZE(pmic_gpio_groups)); + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + platform_set_drvdata(pdev, state); + + state->dev = &pdev->dev; + state->map = dev_get_regmap(dev->parent, NULL); + + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); + if (!pindesc) + return -ENOMEM; + + pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); + if (!pads) + return -ENOMEM; + + pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); + if (!pctrldesc) + return -ENOMEM; + + pctrldesc->pctlops = &pmic_gpio_pinctrl_ops; + pctrldesc->pmxops = &pmic_gpio_pinmux_ops; + pctrldesc->confops = &pmic_gpio_pinconf_ops; + pctrldesc->owner = THIS_MODULE; + pctrldesc->name = dev_name(dev); + pctrldesc->pins = pindesc; + pctrldesc->npins = npins; + + for (i = 0; i < npins; i++, pindesc++) { + pad = &pads[i]; + pindesc->drv_data = pad; + pindesc->number = i; + pindesc->name = pmic_gpio_groups[i]; + + pad->irq = platform_get_irq(pdev, i); + if (pad->irq < 0) + return pad->irq; + + pad->base = res[0] + i * PMIC_GPIO_ADDRESS_RANGE; + + ret = pmic_gpio_populate(state, pad); + if (ret < 0) + return ret; + } + + state->chip = pmic_gpio_gpio_template; + state->chip.dev = dev; + state->chip.base = -1; + state->chip.ngpio = npins; + state->chip.label = dev_name(dev); + state->chip.of_gpio_n_cells = 2; + state->chip.can_sleep = false; + + state->ctrl = pinctrl_register(pctrldesc, dev, state); + if (!state->ctrl) + return -ENODEV; + + ret = gpiochip_add(&state->chip); + if (ret) { + dev_err(state->dev, "can't add gpio chip\n"); + goto err_chip; + } + + ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); + if (ret) { + dev_err(dev, "failed to add pin range\n"); + goto err_range; + } + + return 0; + +err_range: + gpiochip_remove(&state->chip); +err_chip: + pinctrl_unregister(state->ctrl); + return ret; +} + +static int pmic_gpio_remove(struct platform_device *pdev) +{ + struct pmic_gpio_state *state = platform_get_drvdata(pdev); + + gpiochip_remove(&state->chip); + pinctrl_unregister(state->ctrl); + return 0; +} + +static const struct of_device_id pmic_gpio_of_match[] = { + { .compatible = "qcom,pm8941-gpio" }, /* 36 GPIO's */ + { .compatible = "qcom,pma8084-gpio" }, /* 22 GPIO's */ + { }, +}; + +MODULE_DEVICE_TABLE(of, pmic_gpio_of_match); + +static struct platform_driver pmic_gpio_driver = { + .driver = { + .name = "qcom-spmi-gpio", + .of_match_table = pmic_gpio_of_match, + }, + .probe = pmic_gpio_probe, + .remove = pmic_gpio_remove, +}; + +module_platform_driver(pmic_gpio_driver); + +MODULE_AUTHOR("Ivan T. Ivanov "); +MODULE_DESCRIPTION("Qualcomm SPMI PMIC GPIO pin control driver"); +MODULE_ALIAS("platform:qcom-spmi-gpio"); +MODULE_LICENSE("GPL v2"); -- GitLab From cfb24f6ebd38137ebf072cb5629fdf6df51e49c1 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 22 Oct 2014 12:58:47 +0300 Subject: [PATCH 1903/9457] pinctrl: Qualcomm SPMI PMIC MPP pin controller driver This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm MPP sub-function blocks found in the PMIC chips. Signed-off-by: Ivan T. Ivanov Acked-by: Bjorn Andersson Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 949 ++++++++++++++++++++++++ 2 files changed, 950 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 9b49c65a1cab..bfd79af5f982 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o +obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c new file mode 100644 index 000000000000..a8924dba335e --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-spmi-mpp.c @@ -0,0 +1,949 @@ +/* + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define PMIC_MPP_ADDRESS_RANGE 0x100 + +/* + * Pull Up Values - it indicates whether a pull-up should be + * applied for bidirectional mode only. The hardware ignores the + * configuration when operating in other modes. + */ +#define PMIC_MPP_PULL_UP_0P6KOHM 0 +#define PMIC_MPP_PULL_UP_10KOHM 1 +#define PMIC_MPP_PULL_UP_30KOHM 2 +#define PMIC_MPP_PULL_UP_OPEN 3 + +/* type registers base address bases */ +#define PMIC_MPP_REG_TYPE 0x4 +#define PMIC_MPP_REG_SUBTYPE 0x5 + +/* mpp peripheral type and subtype values */ +#define PMIC_MPP_TYPE 0x11 +#define PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT 0x3 +#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT 0x4 +#define PMIC_MPP_SUBTYPE_4CH_NO_SINK 0x5 +#define PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK 0x6 +#define PMIC_MPP_SUBTYPE_4CH_FULL_FUNC 0x7 +#define PMIC_MPP_SUBTYPE_8CH_FULL_FUNC 0xf + +#define PMIC_MPP_REG_RT_STS 0x10 +#define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 + +/* control register base address bases */ +#define PMIC_MPP_REG_MODE_CTL 0x40 +#define PMIC_MPP_REG_DIG_VIN_CTL 0x41 +#define PMIC_MPP_REG_DIG_PULL_CTL 0x42 +#define PMIC_MPP_REG_DIG_IN_CTL 0x43 +#define PMIC_MPP_REG_EN_CTL 0x46 +#define PMIC_MPP_REG_AIN_CTL 0x4a + +/* PMIC_MPP_REG_MODE_CTL */ +#define PMIC_MPP_REG_MODE_VALUE_MASK 0x1 +#define PMIC_MPP_REG_MODE_FUNCTION_SHIFT 1 +#define PMIC_MPP_REG_MODE_FUNCTION_MASK 0x7 +#define PMIC_MPP_REG_MODE_DIR_SHIFT 4 +#define PMIC_MPP_REG_MODE_DIR_MASK 0x7 + +/* PMIC_MPP_REG_DIG_VIN_CTL */ +#define PMIC_MPP_REG_VIN_SHIFT 0 +#define PMIC_MPP_REG_VIN_MASK 0x7 + +/* PMIC_MPP_REG_DIG_PULL_CTL */ +#define PMIC_MPP_REG_PULL_SHIFT 0 +#define PMIC_MPP_REG_PULL_MASK 0x7 + +/* PMIC_MPP_REG_EN_CTL */ +#define PMIC_MPP_REG_MASTER_EN_SHIFT 7 + +/* PMIC_MPP_REG_AIN_CTL */ +#define PMIC_MPP_REG_AIN_ROUTE_SHIFT 0 +#define PMIC_MPP_REG_AIN_ROUTE_MASK 0x7 + +#define PMIC_MPP_PHYSICAL_OFFSET 1 + +/* Qualcomm specific pin configurations */ +#define PMIC_MPP_CONF_AMUX_ROUTE (PIN_CONFIG_END + 1) +#define PMIC_MPP_CONF_ANALOG_MODE (PIN_CONFIG_END + 2) + +/** + * struct pmic_mpp_pad - keep current MPP settings + * @base: Address base in SPMI device. + * @irq: IRQ number which this MPP generate. + * @is_enabled: Set to false when MPP should be put in high Z state. + * @out_value: Cached pin output value. + * @output_enabled: Set to true if MPP output logic is enabled. + * @input_enabled: Set to true if MPP input buffer logic is enabled. + * @analog_mode: Set to true when MPP should operate in Analog Input, Analog + * Output or Bidirectional Analog mode. + * @num_sources: Number of power-sources supported by this MPP. + * @power_source: Current power-source used. + * @amux_input: Set the source for analog input. + * @pullup: Pullup resistor value. Valid in Bidirectional mode only. + * @function: See pmic_mpp_functions[]. + */ +struct pmic_mpp_pad { + u16 base; + int irq; + bool is_enabled; + bool out_value; + bool output_enabled; + bool input_enabled; + bool analog_mode; + unsigned int num_sources; + unsigned int power_source; + unsigned int amux_input; + unsigned int pullup; + unsigned int function; +}; + +struct pmic_mpp_state { + struct device *dev; + struct regmap *map; + struct pinctrl_dev *ctrl; + struct gpio_chip chip; +}; + +struct pmic_mpp_bindings { + const char *property; + unsigned param; +}; + +static struct pmic_mpp_bindings pmic_mpp_bindings[] = { + {"qcom,amux-route", PMIC_MPP_CONF_AMUX_ROUTE}, + {"qcom,analog-mode", PMIC_MPP_CONF_ANALOG_MODE}, +}; + +static const char *const pmic_mpp_groups[] = { + "mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8", +}; + +static const char *const pmic_mpp_functions[] = { + PMIC_MPP_FUNC_NORMAL, PMIC_MPP_FUNC_PAIRED, + "reserved1", "reserved2", + PMIC_MPP_FUNC_DTEST1, PMIC_MPP_FUNC_DTEST2, + PMIC_MPP_FUNC_DTEST3, PMIC_MPP_FUNC_DTEST4, +}; + +static inline struct pmic_mpp_state *to_mpp_state(struct gpio_chip *chip) +{ + return container_of(chip, struct pmic_mpp_state, chip); +}; + +static int pmic_mpp_read(struct pmic_mpp_state *state, + struct pmic_mpp_pad *pad, unsigned int addr) +{ + unsigned int val; + int ret; + + ret = regmap_read(state->map, pad->base + addr, &val); + if (ret < 0) + dev_err(state->dev, "read 0x%x failed\n", addr); + else + ret = val; + + return ret; +} + +static int pmic_mpp_write(struct pmic_mpp_state *state, + struct pmic_mpp_pad *pad, unsigned int addr, + unsigned int val) +{ + int ret; + + ret = regmap_write(state->map, pad->base + addr, val); + if (ret < 0) + dev_err(state->dev, "write 0x%x failed\n", addr); + + return ret; +} + +static int pmic_mpp_get_groups_count(struct pinctrl_dev *pctldev) +{ + /* Every PIN is a group */ + return pctldev->desc->npins; +} + +static const char *pmic_mpp_get_group_name(struct pinctrl_dev *pctldev, + unsigned pin) +{ + return pctldev->desc->pins[pin].name; +} + +static int pmic_mpp_get_group_pins(struct pinctrl_dev *pctldev, + unsigned pin, + const unsigned **pins, unsigned *num_pins) +{ + *pins = &pctldev->desc->pins[pin].number; + *num_pins = 1; + return 0; +} + +static int pmic_mpp_parse_dt_config(struct device_node *np, + struct pinctrl_dev *pctldev, + unsigned long **configs, + unsigned int *nconfs) +{ + struct pmic_mpp_bindings *par; + unsigned long cfg; + int ret, i; + u32 val; + + for (i = 0; i < ARRAY_SIZE(pmic_mpp_bindings); i++) { + par = &pmic_mpp_bindings[i]; + ret = of_property_read_u32(np, par->property, &val); + + /* property not found */ + if (ret == -EINVAL) + continue; + + /* use zero as default value, when no value is specified */ + if (ret) + val = 0; + + dev_dbg(pctldev->dev, "found %s with value %u\n", + par->property, val); + + cfg = pinconf_to_config_packed(par->param, val); + + ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg); + if (ret) + return ret; + } + + return 0; +} + +static int pmic_mpp_dt_subnode_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *reserv, unsigned *nmaps, + enum pinctrl_map_type type) +{ + unsigned long *configs = NULL; + unsigned nconfs = 0; + struct property *prop; + const char *group; + int ret; + + ret = pmic_mpp_parse_dt_config(np, pctldev, &configs, &nconfs); + if (ret < 0) + return ret; + + if (!nconfs) + return 0; + + ret = of_property_count_strings(np, "pins"); + if (ret < 0) + goto exit; + + ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret); + if (ret < 0) + goto exit; + + of_property_for_each_string(np, "pins", prop, group) { + ret = pinctrl_utils_add_map_configs(pctldev, map, + reserv, nmaps, group, + configs, nconfs, type); + if (ret < 0) + break; + } +exit: + kfree(configs); + return ret; +} + +static int pmic_mpp_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, unsigned *nmaps) +{ + struct device_node *np; + enum pinctrl_map_type type; + unsigned reserv; + int ret; + + ret = 0; + *map = NULL; + *nmaps = 0; + reserv = 0; + type = PIN_MAP_TYPE_CONFIGS_GROUP; + + for_each_child_of_node(np_config, np) { + ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, + &reserv, nmaps, type); + if (ret) + break; + + ret = pmic_mpp_dt_subnode_to_map(pctldev, np, map, &reserv, + nmaps, type); + if (ret) + break; + } + + if (ret < 0) + pinctrl_utils_dt_free_map(pctldev, *map, *nmaps); + + return ret; +} + +static const struct pinctrl_ops pmic_mpp_pinctrl_ops = { + .get_groups_count = pmic_mpp_get_groups_count, + .get_group_name = pmic_mpp_get_group_name, + .get_group_pins = pmic_mpp_get_group_pins, + .dt_node_to_map = pmic_mpp_dt_node_to_map, + .dt_free_map = pinctrl_utils_dt_free_map, +}; + +static int pmic_mpp_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(pmic_mpp_functions); +} + +static const char *pmic_mpp_get_function_name(struct pinctrl_dev *pctldev, + unsigned function) +{ + return pmic_mpp_functions[function]; +} + +static int pmic_mpp_get_function_groups(struct pinctrl_dev *pctldev, + unsigned function, + const char *const **groups, + unsigned *const num_qgroups) +{ + *groups = pmic_mpp_groups; + *num_qgroups = pctldev->desc->npins; + return 0; +} + +static int pmic_mpp_set_mux(struct pinctrl_dev *pctldev, unsigned function, + unsigned pin) +{ + struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_mpp_pad *pad; + unsigned int val; + int ret; + + pad = pctldev->desc->pins[pin].drv_data; + + pad->function = function; + + if (!pad->analog_mode) { + val = 0; /* just digital input */ + if (pad->output_enabled) { + if (pad->input_enabled) + val = 2; /* digital input and output */ + else + val = 1; /* just digital output */ + } + } else { + val = 4; /* just analog input */ + if (pad->output_enabled) { + if (pad->input_enabled) + val = 3; /* analog input and output */ + else + val = 5; /* just analog output */ + } + } + + val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; + val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; + + ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val); + if (ret < 0) + return ret; + + val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT; + + return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val); +} + +static const struct pinmux_ops pmic_mpp_pinmux_ops = { + .get_functions_count = pmic_mpp_get_functions_count, + .get_function_name = pmic_mpp_get_function_name, + .get_function_groups = pmic_mpp_get_function_groups, + .set_mux = pmic_mpp_set_mux, +}; + +static int pmic_mpp_config_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + unsigned param = pinconf_to_config_param(*config); + struct pmic_mpp_pad *pad; + unsigned arg = 0; + + pad = pctldev->desc->pins[pin].drv_data; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN; + break; + case PIN_CONFIG_BIAS_PULL_UP: + switch (pad->pullup) { + case PMIC_MPP_PULL_UP_OPEN: + arg = 0; + break; + case PMIC_MPP_PULL_UP_0P6KOHM: + arg = 600; + break; + case PMIC_MPP_PULL_UP_10KOHM: + arg = 10000; + break; + case PMIC_MPP_PULL_UP_30KOHM: + arg = 30000; + break; + default: + return -EINVAL; + } + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + arg = !pad->is_enabled; + break; + case PIN_CONFIG_POWER_SOURCE: + arg = pad->power_source; + break; + case PIN_CONFIG_INPUT_ENABLE: + arg = pad->input_enabled; + break; + case PIN_CONFIG_OUTPUT: + arg = pad->out_value; + break; + case PMIC_MPP_CONF_AMUX_ROUTE: + arg = pad->amux_input; + break; + case PMIC_MPP_CONF_ANALOG_MODE: + arg = pad->analog_mode; + break; + default: + return -EINVAL; + } + + /* Convert register value to pinconf value */ + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned nconfs) +{ + struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_mpp_pad *pad; + unsigned param, arg; + unsigned int val; + int i, ret; + + pad = pctldev->desc->pins[pin].drv_data; + + for (i = 0; i < nconfs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + pad->pullup = PMIC_MPP_PULL_UP_OPEN; + break; + case PIN_CONFIG_BIAS_PULL_UP: + switch (arg) { + case 600: + pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM; + break; + case 10000: + pad->pullup = PMIC_MPP_PULL_UP_10KOHM; + break; + case 30000: + pad->pullup = PMIC_MPP_PULL_UP_30KOHM; + break; + default: + return -EINVAL; + } + break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + pad->is_enabled = false; + break; + case PIN_CONFIG_POWER_SOURCE: + if (arg >= pad->num_sources) + return -EINVAL; + pad->power_source = arg; + break; + case PIN_CONFIG_INPUT_ENABLE: + pad->input_enabled = arg ? true : false; + break; + case PIN_CONFIG_OUTPUT: + pad->output_enabled = true; + pad->out_value = arg; + break; + case PMIC_MPP_CONF_AMUX_ROUTE: + if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4) + return -EINVAL; + pad->amux_input = arg; + break; + case PMIC_MPP_CONF_ANALOG_MODE: + pad->analog_mode = true; + break; + default: + return -EINVAL; + } + } + + val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT; + + ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val); + if (ret < 0) + return ret; + + val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT; + + ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_PULL_CTL, val); + if (ret < 0) + return ret; + + val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK; + + ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val); + if (ret < 0) + return ret; + + if (!pad->analog_mode) { + val = 0; /* just digital input */ + if (pad->output_enabled) { + if (pad->input_enabled) + val = 2; /* digital input and output */ + else + val = 1; /* just digital output */ + } + } else { + val = 4; /* just analog input */ + if (pad->output_enabled) { + if (pad->input_enabled) + val = 3; /* analog input and output */ + else + val = 5; /* just analog output */ + } + } + + val = val << PMIC_MPP_REG_MODE_DIR_SHIFT; + val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; + val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; + + return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val); +} + +static void pmic_mpp_config_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned pin) +{ + struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev); + struct pmic_mpp_pad *pad; + int ret, val; + + static const char *const biases[] = { + "0.6kOhm", "10kOhm", "30kOhm", "Disabled" + }; + + + pad = pctldev->desc->pins[pin].drv_data; + + seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET); + + val = pmic_mpp_read(state, pad, PMIC_MPP_REG_EN_CTL); + + if (val < 0 || !(val >> PMIC_MPP_REG_MASTER_EN_SHIFT)) { + seq_puts(s, " ---"); + } else { + + if (pad->input_enabled) { + ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); + if (!ret) { + ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; + pad->out_value = ret; + } + } + + seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); + seq_printf(s, " %-4s", pad->analog_mode ? "ana" : "dig"); + seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]); + seq_printf(s, " vin-%d", pad->power_source); + seq_printf(s, " %-8s", biases[pad->pullup]); + seq_printf(s, " %-4s", pad->out_value ? "high" : "low"); + } +} + +static const struct pinconf_ops pmic_mpp_pinconf_ops = { + .pin_config_group_get = pmic_mpp_config_get, + .pin_config_group_set = pmic_mpp_config_set, + .pin_config_group_dbg_show = pmic_mpp_config_dbg_show, +}; + +static int pmic_mpp_direction_input(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1); + + return pmic_mpp_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_mpp_direction_output(struct gpio_chip *chip, + unsigned pin, int val) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val); + + return pmic_mpp_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_mpp_get(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + struct pmic_mpp_pad *pad; + int ret; + + pad = state->ctrl->desc->pins[pin].drv_data; + + if (pad->input_enabled) { + ret = pmic_mpp_read(state, pad, PMIC_MPP_REG_RT_STS); + if (ret < 0) + return ret; + + pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK; + } + + return pad->out_value; +} + +static void pmic_mpp_set(struct gpio_chip *chip, unsigned pin, int value) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + unsigned long config; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value); + + pmic_mpp_config_set(state->ctrl, pin, &config, 1); +} + +static int pmic_mpp_request(struct gpio_chip *chip, unsigned base) +{ + return pinctrl_request_gpio(chip->base + base); +} + +static void pmic_mpp_free(struct gpio_chip *chip, unsigned base) +{ + pinctrl_free_gpio(chip->base + base); +} + +static int pmic_mpp_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *gpio_desc, + u32 *flags) +{ + if (chip->of_gpio_n_cells < 2) + return -EINVAL; + + if (flags) + *flags = gpio_desc->args[1]; + + return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET; +} + +static int pmic_mpp_to_irq(struct gpio_chip *chip, unsigned pin) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + struct pmic_mpp_pad *pad; + + pad = state->ctrl->desc->pins[pin].drv_data; + + return pad->irq; +} + +static void pmic_mpp_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + struct pmic_mpp_state *state = to_mpp_state(chip); + unsigned i; + + for (i = 0; i < chip->ngpio; i++) { + pmic_mpp_config_dbg_show(state->ctrl, s, i); + seq_puts(s, "\n"); + } +} + +static const struct gpio_chip pmic_mpp_gpio_template = { + .direction_input = pmic_mpp_direction_input, + .direction_output = pmic_mpp_direction_output, + .get = pmic_mpp_get, + .set = pmic_mpp_set, + .request = pmic_mpp_request, + .free = pmic_mpp_free, + .of_xlate = pmic_mpp_of_xlate, + .to_irq = pmic_mpp_to_irq, + .dbg_show = pmic_mpp_dbg_show, +}; + +static int pmic_mpp_populate(struct pmic_mpp_state *state, + struct pmic_mpp_pad *pad) +{ + int type, subtype, val, dir; + + type = pmic_mpp_read(state, pad, PMIC_MPP_REG_TYPE); + if (type < 0) + return type; + + if (type != PMIC_MPP_TYPE) { + dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n", + type, pad->base); + return -ENODEV; + } + + subtype = pmic_mpp_read(state, pad, PMIC_MPP_REG_SUBTYPE); + if (subtype < 0) + return subtype; + + switch (subtype) { + case PMIC_MPP_SUBTYPE_4CH_NO_ANA_OUT: + case PMIC_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT: + case PMIC_MPP_SUBTYPE_4CH_NO_SINK: + case PMIC_MPP_SUBTYPE_ULT_4CH_NO_SINK: + case PMIC_MPP_SUBTYPE_4CH_FULL_FUNC: + pad->num_sources = 4; + break; + case PMIC_MPP_SUBTYPE_8CH_FULL_FUNC: + pad->num_sources = 8; + break; + default: + dev_err(state->dev, "unknown MPP type 0x%x at 0x%x\n", + subtype, pad->base); + return -ENODEV; + } + + val = pmic_mpp_read(state, pad, PMIC_MPP_REG_MODE_CTL); + if (val < 0) + return val; + + pad->out_value = val & PMIC_MPP_REG_MODE_VALUE_MASK; + + dir = val >> PMIC_MPP_REG_MODE_DIR_SHIFT; + dir &= PMIC_MPP_REG_MODE_DIR_MASK; + + switch (dir) { + case 0: + pad->input_enabled = true; + pad->output_enabled = false; + pad->analog_mode = false; + break; + case 1: + pad->input_enabled = false; + pad->output_enabled = true; + pad->analog_mode = false; + break; + case 2: + pad->input_enabled = true; + pad->output_enabled = true; + pad->analog_mode = false; + break; + case 3: + pad->input_enabled = true; + pad->output_enabled = true; + pad->analog_mode = true; + break; + case 4: + pad->input_enabled = true; + pad->output_enabled = false; + pad->analog_mode = true; + break; + case 5: + pad->input_enabled = false; + pad->output_enabled = true; + pad->analog_mode = true; + break; + default: + dev_err(state->dev, "unknown MPP direction\n"); + return -ENODEV; + } + + pad->function = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT; + pad->function &= PMIC_MPP_REG_MODE_FUNCTION_MASK; + + val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL); + if (val < 0) + return val; + + pad->power_source = val >> PMIC_MPP_REG_VIN_SHIFT; + pad->power_source &= PMIC_MPP_REG_VIN_MASK; + + val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_PULL_CTL); + if (val < 0) + return val; + + pad->pullup = val >> PMIC_MPP_REG_PULL_SHIFT; + pad->pullup &= PMIC_MPP_REG_PULL_MASK; + + val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AIN_CTL); + if (val < 0) + return val; + + pad->amux_input = val >> PMIC_MPP_REG_AIN_ROUTE_SHIFT; + pad->amux_input &= PMIC_MPP_REG_AIN_ROUTE_MASK; + + /* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */ + pad->is_enabled = true; + return 0; +} + +static int pmic_mpp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pinctrl_pin_desc *pindesc; + struct pinctrl_desc *pctrldesc; + struct pmic_mpp_pad *pad, *pads; + struct pmic_mpp_state *state; + int ret, npins, i; + u32 res[2]; + + ret = of_property_read_u32_array(dev->of_node, "reg", res, 2); + if (ret < 0) { + dev_err(dev, "missing base address and/or range"); + return ret; + } + + npins = res[1] / PMIC_MPP_ADDRESS_RANGE; + if (!npins) + return -EINVAL; + + BUG_ON(npins > ARRAY_SIZE(pmic_mpp_groups)); + + state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + platform_set_drvdata(pdev, state); + + state->dev = &pdev->dev; + state->map = dev_get_regmap(dev->parent, NULL); + + pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL); + if (!pindesc) + return -ENOMEM; + + pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL); + if (!pads) + return -ENOMEM; + + pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL); + if (!pctrldesc) + return -ENOMEM; + + pctrldesc->pctlops = &pmic_mpp_pinctrl_ops; + pctrldesc->pmxops = &pmic_mpp_pinmux_ops; + pctrldesc->confops = &pmic_mpp_pinconf_ops; + pctrldesc->owner = THIS_MODULE; + pctrldesc->name = dev_name(dev); + pctrldesc->pins = pindesc; + pctrldesc->npins = npins; + + for (i = 0; i < npins; i++, pindesc++) { + pad = &pads[i]; + pindesc->drv_data = pad; + pindesc->number = i; + pindesc->name = pmic_mpp_groups[i]; + + pad->irq = platform_get_irq(pdev, i); + if (pad->irq < 0) + return pad->irq; + + pad->base = res[0] + i * PMIC_MPP_ADDRESS_RANGE; + + ret = pmic_mpp_populate(state, pad); + if (ret < 0) + return ret; + } + + state->chip = pmic_mpp_gpio_template; + state->chip.dev = dev; + state->chip.base = -1; + state->chip.ngpio = npins; + state->chip.label = dev_name(dev); + state->chip.of_gpio_n_cells = 2; + state->chip.can_sleep = false; + + state->ctrl = pinctrl_register(pctrldesc, dev, state); + if (!state->ctrl) + return -ENODEV; + + ret = gpiochip_add(&state->chip); + if (ret) { + dev_err(state->dev, "can't add gpio chip\n"); + goto err_chip; + } + + ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins); + if (ret) { + dev_err(dev, "failed to add pin range\n"); + goto err_range; + } + + return 0; + +err_range: + gpiochip_remove(&state->chip); +err_chip: + pinctrl_unregister(state->ctrl); + return ret; +} + +static int pmic_mpp_remove(struct platform_device *pdev) +{ + struct pmic_mpp_state *state = platform_get_drvdata(pdev); + + gpiochip_remove(&state->chip); + pinctrl_unregister(state->ctrl); + return 0; +} + +static const struct of_device_id pmic_mpp_of_match[] = { + { .compatible = "qcom,pm8841-mpp" }, /* 4 MPP's */ + { .compatible = "qcom,pm8941-mpp" }, /* 8 MPP's */ + { .compatible = "qcom,pma8084-mpp" }, /* 8 MPP's */ + { }, +}; + +MODULE_DEVICE_TABLE(of, pmic_mpp_of_match); + +static struct platform_driver pmic_mpp_driver = { + .driver = { + .name = "qcom-spmi-mpp", + .of_match_table = pmic_mpp_of_match, + }, + .probe = pmic_mpp_probe, + .remove = pmic_mpp_remove, +}; + +module_platform_driver(pmic_mpp_driver); + +MODULE_AUTHOR("Ivan T. Ivanov "); +MODULE_DESCRIPTION("Qualcomm SPMI PMIC MPP pin control driver"); +MODULE_ALIAS("platform:qcom-spmi-mpp"); +MODULE_LICENSE("GPL v2"); -- GitLab From 557732ad671e0a0768062c843f03b8eef5250e3a Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Mon, 20 Oct 2014 10:27:40 -0500 Subject: [PATCH 1904/9457] drivers: staging: lustre: Fix "space prohibited before that close parenthesis ')'" errors Fix checkpatch.pl "space prohibited before that close parenthesis ')'" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_capa.h | 2 +- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 2 +- drivers/staging/lustre/lustre/obdclass/capa.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_capa.h b/drivers/staging/lustre/lustre/include/lustre_capa.h index ab6b9ea98a70..fe19534ebd8f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_capa.h +++ b/drivers/staging/lustre/lustre/include/lustre_capa.h @@ -154,7 +154,7 @@ static inline __u32 capa_expiry(struct lustre_capa *capa) } void _debug_capa(struct lustre_capa *, struct libcfs_debug_msg_data *, - const char *fmt, ... ); + const char *fmt, ...); #define DEBUG_CAPA(level, capa, fmt, args...) \ do { \ if (((level) & D_CANTMASK) != 0 || \ diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index f9b30cfa23ec..661b2cf2f804 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1384,7 +1384,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(lumv1, lumv1p, sizeof(*lumv1))) return -EFAULT; - if ((lumv1->lmm_magic == LOV_USER_MAGIC_V3) ) { + if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) { if (copy_from_user(&lumv3, lumv3p, sizeof(lumv3))) return -EFAULT; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index d3f967a78138..168aafb95f25 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -709,7 +709,7 @@ static int vvp_io_fault_start(const struct lu_env *env, } - if (fio->ft_mkwrite ) { + if (fio->ft_mkwrite) { pgoff_t last_index; /* * Capture the size while holding the lli_trunc_sem from above diff --git a/drivers/staging/lustre/lustre/obdclass/capa.c b/drivers/staging/lustre/lustre/obdclass/capa.c index cd1abce378ea..8d80ea4833c0 100644 --- a/drivers/staging/lustre/lustre/obdclass/capa.c +++ b/drivers/staging/lustre/lustre/obdclass/capa.c @@ -302,7 +302,7 @@ int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen) /* passing "aes" in a variable instead of a constant string keeps gcc * 4.3.2 happy */ - tfm = crypto_alloc_blkcipher(alg, 0, 0 ); + tfm = crypto_alloc_blkcipher(alg, 0, 0); if (IS_ERR(tfm)) { CERROR("failed to load transform for aes\n"); return PTR_ERR(tfm); @@ -355,7 +355,7 @@ int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen) /* passing "aes" in a variable instead of a constant string keeps gcc * 4.3.2 happy */ - tfm = crypto_alloc_blkcipher(alg, 0, 0 ); + tfm = crypto_alloc_blkcipher(alg, 0, 0); if (IS_ERR(tfm)) { CERROR("failed to load transform for aes\n"); return PTR_ERR(tfm); @@ -407,7 +407,7 @@ EXPORT_SYMBOL(capa_cpy); void _debug_capa(struct lustre_capa *c, struct libcfs_debug_msg_data *msgdata, - const char *fmt, ... ) + const char *fmt, ...) { va_list args; va_start(args, fmt); -- GitLab From e9e2fa6958f13b511346f1c5e6b883a56b1e5c8a Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Mon, 20 Oct 2014 10:58:13 -0500 Subject: [PATCH 1905/9457] drivers: staging: lustre: Fix 'that open brace { should be on the previous line' errors Fix checkpatch.pl 'that open brace { should be on the previous line' errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/ldlm/ldlm_pool.c | 3 +-- drivers/staging/lustre/lustre/libcfs/hash.c | 25 +++++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 3822e0f3faf0..c80c76a6e181 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -1205,8 +1205,7 @@ int ldlm_pools_recalc(ldlm_side_t client) * The rest is given to greedy namespaces. */ list_for_each_entry(ns, ldlm_namespace_list(client), - ns_list_chain) - { + ns_list_chain) { if (!equal && ns->ns_appetite != LDLM_NAMESPACE_GREEDY) continue; diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 3b67b7b6428c..32da78357c7e 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -1371,8 +1371,7 @@ cfs_hash_lookup(struct cfs_hash *hs, const void *key) EXPORT_SYMBOL(cfs_hash_lookup); static void -cfs_hash_for_each_enter(struct cfs_hash *hs) -{ +cfs_hash_for_each_enter(struct cfs_hash *hs) { LASSERT(!cfs_hash_is_exiting(hs)); if (!cfs_hash_with_rehash(hs)) @@ -1397,8 +1396,7 @@ cfs_hash_for_each_enter(struct cfs_hash *hs) } static void -cfs_hash_for_each_exit(struct cfs_hash *hs) -{ +cfs_hash_for_each_exit(struct cfs_hash *hs) { int remained; int bits; @@ -1429,8 +1427,7 @@ cfs_hash_for_each_exit(struct cfs_hash *hs) */ static __u64 cfs_hash_for_each_tight(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, - void *data, int remove_safe) -{ + void *data, int remove_safe) { struct hlist_node *hnode; struct hlist_node *pos; struct cfs_hash_bd bd; @@ -1523,8 +1520,7 @@ EXPORT_SYMBOL(cfs_hash_for_each); void cfs_hash_for_each_safe(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { cfs_hash_for_each_tight(hs, func, data, 1); } EXPORT_SYMBOL(cfs_hash_for_each_safe); @@ -1572,8 +1568,8 @@ EXPORT_SYMBOL(cfs_hash_size_get); * two cases, so iteration has to be stopped on change. */ static int -cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void *data) -{ +cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, + void *data) { struct hlist_node *hnode; struct hlist_node *tmp; struct cfs_hash_bd bd; @@ -1634,8 +1630,7 @@ cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, void * int cfs_hash_for_each_nolock(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { if (cfs_hash_with_no_lock(hs) || cfs_hash_with_rehash_key(hs) || !cfs_hash_with_no_itemref(hs)) @@ -1667,8 +1662,7 @@ EXPORT_SYMBOL(cfs_hash_for_each_nolock); */ int cfs_hash_for_each_empty(struct cfs_hash *hs, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { unsigned i = 0; if (cfs_hash_with_no_lock(hs)) @@ -1726,8 +1720,7 @@ EXPORT_SYMBOL(cfs_hash_hlist_for_each); */ void cfs_hash_for_each_key(struct cfs_hash *hs, const void *key, - cfs_hash_for_each_cb_t func, void *data) -{ + cfs_hash_for_each_cb_t func, void *data) { struct hlist_node *hnode; struct cfs_hash_bd bds[2]; unsigned i; -- GitLab From 544426100b66f23cce010bd6e2b386b282a2767c Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Mon, 20 Oct 2014 11:18:12 -0500 Subject: [PATCH 1906/9457] drivers: staging: lustre: Fix "'foo * bar' should be 'foo *bar'" errors Fix checkpatch.pl "'foo * bar' should be 'foo *bar'" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/dt_object.h | 2 +- drivers/staging/lustre/lustre/include/lprocfs_status.h | 2 +- drivers/staging/lustre/lustre/include/lustre_dlm.h | 2 +- drivers/staging/lustre/lustre/obdclass/genops.c | 8 ++++---- .../staging/lustre/lustre/obdclass/linux/linux-module.c | 4 ++-- drivers/staging/lustre/lustre/obdclass/obd_config.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h index c2e7622469ca..be4c7d95e788 100644 --- a/drivers/staging/lustre/lustre/include/dt_object.h +++ b/drivers/staging/lustre/lustre/include/dt_object.h @@ -667,7 +667,7 @@ static inline int lu_device_is_dt(const struct lu_device *d) return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT); } -static inline struct dt_device * lu2dt_dev(struct lu_device *l) +static inline struct dt_device *lu2dt_dev(struct lu_device *l) { LASSERT(lu_device_is_dt(l)); return container_of0(l, struct dt_device, dd_lu_dev); diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index 54c522667228..cfe503b7df62 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -557,7 +557,7 @@ extern void lprocfs_free_obd_stats(struct obd_device *obddev); extern void lprocfs_free_md_stats(struct obd_device *obddev); struct obd_export; struct nid_stat; -extern int lprocfs_add_clear_entry(struct obd_device * obd, +extern int lprocfs_add_clear_entry(struct obd_device *obd, struct proc_dir_entry *entry); extern int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *peer_nid, int *newnid); diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 14ac46f45fd1..83bc0a9d7d4c 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -1446,7 +1446,7 @@ static inline void check_res_locked(struct ldlm_resource *res) assert_spin_locked(&res->lr_lock); } -struct ldlm_resource * lock_res_and_lock(struct ldlm_lock *lock); +struct ldlm_resource *lock_res_and_lock(struct ldlm_lock *lock); void unlock_res_and_lock(struct ldlm_lock *lock); /* ldlm_pool.c */ diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index c314e9c2343e..b6592ee54c48 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -524,8 +524,8 @@ void class_obd_list(void) /* Search for a client OBD connected to tgt_uuid. If grp_uuid is specified, then only the client with that uuid is returned, otherwise any client connected to the tgt is returned. */ -struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid, - const char * typ_name, +struct obd_device *class_find_client_obd(struct obd_uuid *tgt_uuid, + const char *typ_name, struct obd_uuid *grp_uuid) { int i; @@ -557,7 +557,7 @@ EXPORT_SYMBOL(class_find_client_obd); searching at *next, and if a device is found, the next index to look at is saved in *next. If next is NULL, then the first matching device will always be returned. */ -struct obd_device * class_devices_in_group(struct obd_uuid *grp_uuid, int *next) +struct obd_device *class_devices_in_group(struct obd_uuid *grp_uuid, int *next) { int i; @@ -1783,7 +1783,7 @@ EXPORT_SYMBOL(kuc_len); * @param p Pointer to payload area * @returns Pointer to kuc header */ -struct kuc_hdr * kuc_ptr(void *p) +struct kuc_hdr *kuc_ptr(void *p) { struct kuc_hdr *lh = ((struct kuc_hdr *)p) - 1; LASSERT(lh->kuc_magic == KUC_MAGIC); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index 7eaaaa648dfb..66ceab20c743 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -166,14 +166,14 @@ int obd_ioctl_popdata(void *arg, void *data, int len) EXPORT_SYMBOL(obd_ioctl_popdata); /* opening /dev/obd */ -static int obd_class_open(struct inode * inode, struct file * file) +static int obd_class_open(struct inode *inode, struct file *file) { try_module_get(THIS_MODULE); return 0; } /* closing /dev/obd */ -static int obd_class_release(struct inode * inode, struct file * file) +static int obd_class_release(struct inode *inode, struct file *file) { module_put(THIS_MODULE); return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 5e7b3d7cc984..47213a970e7d 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -835,7 +835,7 @@ int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg) LIST_HEAD(lustre_profile_list); -struct lustre_profile *class_get_profile(const char * prof) +struct lustre_profile *class_get_profile(const char *prof) { struct lustre_profile *lprof; -- GitLab From 31e7213ab21e2c251a61a13fca4c9548f1f875fd Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Mon, 20 Oct 2014 11:42:36 -0500 Subject: [PATCH 1907/9457] drivers: staging: lustre: Fix "spaces required around that '='" errors Fix checkpatch.pl "spaces required around that '='" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/super25.c | 2 +- drivers/staging/lustre/lustre/obdclass/genops.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index e61dbed120a3..6aff155651cc 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -162,7 +162,7 @@ static int __init init_lustre_lite(void) /* Nodes with small feet have little entropy * the NID for this node gives the most entropy in the low bits */ - for (i=0; ; i++) { + for (i = 0; ; i++) { if (LNetGetId(i, &lnet_id) == -ENOENT) { break; } diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index b6592ee54c48..ac8db2f98078 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -317,7 +317,7 @@ struct obd_device *class_newdev(const char *type_name, const char *name) result->obd_minor, new_obd_minor); obd_devs[result->obd_minor] = NULL; - result->obd_name[0]='\0'; + result->obd_name[0] = '\0'; } result = ERR_PTR(-EEXIST); break; -- GitLab From 85bcfab46955e6f4bcfd08ffb989f941e003da2a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Oct 2014 11:11:39 +0300 Subject: [PATCH 1908/9457] staging: lustre: validate size in lustre_posix_acl_xattr_filter() This is mostly to silence static checker complaints. In theory the problem here is that if size is in the 1-3 range then we don't allocate enough memory for the posix_acl_xattr_header struct and it results in memory corruption. But in reality kmalloc() return values are aligned at sizeof(long) so corrupting this small amount of data is not harmful. The "size" variable should be type size_t. The value of size is checked in setxattr() so we know it is a number between "0 - XATTR_SIZE_MAX". There is no need to check for negative sizes. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/include/lustre_eacl.h | 2 +- drivers/staging/lustre/lustre/obdclass/acl.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_eacl.h b/drivers/staging/lustre/lustre/include/lustre_eacl.h index b94f76a3301b..0f8f76c43ee1 100644 --- a/drivers/staging/lustre/lustre/include/lustre_eacl.h +++ b/drivers/staging/lustre/lustre/include/lustre_eacl.h @@ -74,7 +74,7 @@ typedef struct { extern ext_acl_xattr_header * lustre_posix_acl_xattr_2ext(posix_acl_xattr_header *header, int size); extern int -lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size, +lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size, posix_acl_xattr_header **out); extern void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size); diff --git a/drivers/staging/lustre/lustre/obdclass/acl.c b/drivers/staging/lustre/lustre/obdclass/acl.c index 2619bfeceb8b..9a69f6b35a0e 100644 --- a/drivers/staging/lustre/lustre/obdclass/acl.c +++ b/drivers/staging/lustre/lustre/obdclass/acl.c @@ -171,17 +171,17 @@ EXPORT_SYMBOL(lustre_posix_acl_xattr_2ext); /* * Filter out the "nobody" entries in the posix ACL. */ -int lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size, +int lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, size_t size, posix_acl_xattr_header **out) { int count, i, j, rc = 0; __u32 id; posix_acl_xattr_header *new; - if (unlikely(size < 0)) - return -EINVAL; - else if (!size) + if (!size) return 0; + if (size < sizeof(*new)) + return -EINVAL; OBD_ALLOC(new, size); if (unlikely(new == NULL)) -- GitLab From 87ebccf97f54fe20c0a8a86e21164473cc7d57e1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Oct 2014 17:23:07 +0300 Subject: [PATCH 1909/9457] staging: lustre: validate size in ll_setxattr() If size is smaller than the lov_user_md struct then we are reading beyond the end of the buffer. I guess this is an information leak or it could cause an Oops if the memory is not mapped. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/xattr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 252a6194ed9b..3ad979635c60 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -234,6 +234,9 @@ int ll_setxattr(struct dentry *dentry, const char *name, struct lov_user_md *lump = (struct lov_user_md *)value; int rc = 0; + if (size != 0 && size < sizeof(struct lov_user_md)) + return -EINVAL; + /* Attributes that are saved via getxattr will always have * the stripe_offset as 0. Instead, the MDS should be * allowed to pick the starting OST index. b=17846 */ -- GitLab From 828ebb8f82d9117762ebc22c6bc0b21d68301d44 Mon Sep 17 00:00:00 2001 From: Mariusz Gorski Date: Sat, 25 Oct 2014 03:30:38 +0200 Subject: [PATCH 1910/9457] staging: lustre: Use __init and __exit markers for lifecycle functions Apply __init marker to module's init function and __exit to module's exit function as they both have no other usage. Signed-off-by: Mariusz Gorski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index dc09b4377a2f..3c23677bc280 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -110,7 +110,7 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data) DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl); -static int +static int __init init_lnet(void) { int rc; @@ -135,7 +135,7 @@ init_lnet(void) return 0; } -static void +static void __exit fini_lnet(void) { int rc; -- GitLab From 24443a244b2ccac0883ddc3f929a8a6ea8457daa Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:29:34 -0500 Subject: [PATCH 1911/9457] staging: skein: Collapses threefish module Collapses threefish module into skein module. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/Kconfig | 22 +++------------------- drivers/staging/skein/Makefile | 11 +++++------ 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/staging/skein/Kconfig b/drivers/staging/skein/Kconfig index b9172bfcdc1b..de8bdd768a7f 100644 --- a/drivers/staging/skein/Kconfig +++ b/drivers/staging/skein/Kconfig @@ -1,8 +1,8 @@ config CRYPTO_SKEIN bool "Skein digest algorithm" depends on (X86 || UML_X86) && 64BIT && CRYPTO - select CRYPTO_THREEFISH select CRYPTO_HASH + select CRYPTO_ALGAPI help Skein secure hash algorithm is one of 5 finalists from the NIST SHA3 competition. @@ -12,21 +12,5 @@ config CRYPTO_SKEIN http://www.skein-hash.info/sites/default/files/skein1.3.pdf - for more information. This module depends on the threefish block - cipher module. - -config CRYPTO_THREEFISH - bool "Threefish tweakable block cipher" - depends on (X86 || UML_X86) && 64BIT && CRYPTO - select CRYPTO_ALGAPI - help - Threefish cipher algorithm is the tweakable block cipher underneath - the Skein family of secure hash algorithms. Skein is one of 5 - finalists from the NIST SHA3 competition. - - Skein is optimized for modern, 64bit processors and is highly - customizable. See: - - http://www.skein-hash.info/sites/default/files/skein1.3.pdf - - for more information. + for more information. This module also contains the threefish block + cipher algorithm. diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index a14aaddd829c..4b60171c81dd 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -1,9 +1,8 @@ # # Makefile for the skein secure hash algorithm # -obj-$(CONFIG_CRYPTO_SKEIN) += skein.o \ - skein_api.o \ - skein_block.o - -obj-$(CONFIG_CRYPTO_THREEFISH) += threefish_block.o \ - threefish_api.o +obj-$(CONFIG_CRYPTO_SKEIN) += skein.o \ + skein_api.o \ + skein_block.o \ + threefish_block.o \ + threefish_api.o -- GitLab From c17cdeb41950a69d3e1f43b39a7e5e59ed59c8f9 Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:32:53 -0500 Subject: [PATCH 1912/9457] staging: skein: Renames skein to skein_base Renames skein.c to skein_base.c and skein.h to skein_base.h in preparation for naming loadable module skein.ko Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/Makefile | 2 +- drivers/staging/skein/skein_api.h | 2 +- drivers/staging/skein/{skein.c => skein_base.c} | 3 ++- drivers/staging/skein/{skein.h => skein_base.h} | 0 drivers/staging/skein/skein_block.c | 2 +- drivers/staging/skein/skein_block.h | 2 +- drivers/staging/skein/skein_iv.h | 2 +- drivers/staging/skein/threefish_api.h | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) rename drivers/staging/skein/{skein.c => skein_base.c} (99%) rename drivers/staging/skein/{skein.h => skein_base.h} (100%) diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index 4b60171c81dd..ca746a9eb2ad 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -1,7 +1,7 @@ # # Makefile for the skein secure hash algorithm # -obj-$(CONFIG_CRYPTO_SKEIN) += skein.o \ +obj-$(CONFIG_CRYPTO_SKEIN) += skein_base.o \ skein_api.o \ skein_block.o \ threefish_block.o \ diff --git a/drivers/staging/skein/skein_api.h b/drivers/staging/skein/skein_api.h index e02fa19d9458..171b87549548 100644 --- a/drivers/staging/skein/skein_api.h +++ b/drivers/staging/skein/skein_api.h @@ -79,7 +79,7 @@ OTHER DEALINGS IN THE SOFTWARE. */ #include -#include "skein.h" +#include "skein_base.h" /** * Which Skein size to use diff --git a/drivers/staging/skein/skein.c b/drivers/staging/skein/skein_base.c similarity index 99% rename from drivers/staging/skein/skein.c rename to drivers/staging/skein/skein_base.c index 8cc83587b1f1..e0994eae5b40 100644 --- a/drivers/staging/skein/skein.c +++ b/drivers/staging/skein/skein_base.c @@ -11,7 +11,8 @@ #define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */ #include /* get the memcpy/memset functions */ -#include "skein.h" /* get the Skein API definitions */ +#include +#include "skein_base.h" /* get the Skein API definitions */ #include "skein_iv.h" /* get precomputed IVs */ #include "skein_block.h" diff --git a/drivers/staging/skein/skein.h b/drivers/staging/skein/skein_base.h similarity index 100% rename from drivers/staging/skein/skein.h rename to drivers/staging/skein/skein_base.h diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 88bc718ae5b6..36b0b400acf3 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -15,7 +15,7 @@ ************************************************************************/ #include -#include "skein.h" +#include "skein_base.h" #include "skein_block.h" #ifndef SKEIN_USE_ASM diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h index bd7bdc35df29..9d40f4a5267b 100644 --- a/drivers/staging/skein/skein_block.h +++ b/drivers/staging/skein/skein_block.h @@ -10,7 +10,7 @@ #ifndef _SKEIN_BLOCK_H_ #define _SKEIN_BLOCK_H_ -#include "skein.h" /* get the Skein API definitions */ +#include "skein_base.h" /* get the Skein API definitions */ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, size_t blk_cnt, size_t byte_cnt_add); diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h index d9dc1d5ed551..8a06314d0ed4 100644 --- a/drivers/staging/skein/skein_iv.h +++ b/drivers/staging/skein/skein_iv.h @@ -1,7 +1,7 @@ #ifndef _SKEIN_IV_H_ #define _SKEIN_IV_H_ -#include "skein.h" /* get Skein macros and types */ +#include "skein_base.h" /* get Skein macros and types */ /* ***************** Pre-computed Skein IVs ******************* diff --git a/drivers/staging/skein/threefish_api.h b/drivers/staging/skein/threefish_api.h index 8d5ddf8b3a9b..8e0a0b77ecce 100644 --- a/drivers/staging/skein/threefish_api.h +++ b/drivers/staging/skein/threefish_api.h @@ -29,7 +29,7 @@ */ #include -#include "skein.h" +#include "skein_base.h" #define KEY_SCHEDULE_CONST 0x1BD11BDAA9FC1A22L -- GitLab From f96d8ced8ec6e37b8c128bd9c7c65919cc273711 Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:33:15 -0500 Subject: [PATCH 1913/9457] staging: skein: Adds CryptoAPI Support Adds CryptoAPI support to the Skein Hashing Algorithm driver. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/Makefile | 3 +- drivers/staging/skein/skein_base.h | 5 + drivers/staging/skein/skein_generic.c | 199 ++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/skein/skein_generic.c diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index ca746a9eb2ad..d8177cccf3f0 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_CRYPTO_SKEIN) += skein_base.o \ skein_api.o \ skein_block.o \ threefish_block.o \ - threefish_api.o + threefish_api.o \ + skein_generic.o diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index e6669f196e5d..9f10af910f41 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -28,6 +28,11 @@ ** ***************************************************************************/ +/*Skein digest sizes for crypto api*/ +#define SKEIN256_DIGEST_BIT_SIZE 256 +#define SKEIN512_DIGEST_BIT_SIZE 512 +#define SKEIN1024_DIGEST_BIT_SIZE 1024 + #ifndef rotl_64 #define rotl_64(x, N) (((x) << (N)) | ((x) >> (64-(N)))) #endif diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c new file mode 100644 index 000000000000..f2d6dfbc66a4 --- /dev/null +++ b/drivers/staging/skein/skein_generic.c @@ -0,0 +1,199 @@ +/* + * Cryptographic API. + * + * Skein256 Hash Algorithm. + * + * Derived from cryptoapi implementation, adapted for in-place + * scatterlist interface. + * + * Copyright (c) Eric Rost + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include +#include +#include +#include "skein_base.h" + + +static int skein256_init(struct shash_desc *desc) +{ + return skein_256_init((struct skein_256_ctx *) shash_desc_ctx(desc), + SKEIN256_DIGEST_BIT_SIZE); +} + +int skein256_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_256_update((struct skein_256_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein256_final(struct shash_desc *desc, u8 *out) +{ + return skein_256_final((struct skein_256_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein256_export(struct shash_desc *desc, void *out) +{ + struct skein_256_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein256_import(struct shash_desc *desc, const void *in) +{ + struct skein_256_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static int skein512_init(struct shash_desc *desc) +{ + return skein_512_init((struct skein_512_ctx *)shash_desc_ctx(desc), + SKEIN512_DIGEST_BIT_SIZE); +} + +int skein512_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_512_update((struct skein_512_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein512_final(struct shash_desc *desc, u8 *out) +{ + return skein_512_final((struct skein_512_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein512_export(struct shash_desc *desc, void *out) +{ + struct skein_512_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein512_import(struct shash_desc *desc, const void *in) +{ + struct skein_512_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static int skein1024_init(struct shash_desc *desc) +{ + return skein_1024_init((struct skein_1024_ctx *)shash_desc_ctx(desc), + SKEIN1024_DIGEST_BIT_SIZE); +} + +int skein1024_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + return skein_1024_update((struct skein_1024_ctx *)shash_desc_ctx(desc), + data, len); +} + +static int skein1024_final(struct shash_desc *desc, u8 *out) +{ + return skein_1024_final((struct skein_1024_ctx *)shash_desc_ctx(desc), + out); +} + +static int skein1024_export(struct shash_desc *desc, void *out) +{ + struct skein_1024_ctx *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, sizeof(*sctx)); + return 0; +} + +static int skein1024_import(struct shash_desc *desc, const void *in) +{ + struct skein_1024_ctx *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, sizeof(*sctx)); + return 0; +} + +static struct shash_alg alg256 = { + .digestsize = (SKEIN256_DIGEST_BIT_SIZE / 8), + .init = skein256_init, + .update = skein256_update, + .final = skein256_final, + .export = skein256_export, + .import = skein256_import, + .descsize = sizeof(struct skein_256_ctx), + .statesize = sizeof(struct skein_256_ctx), + .base = { + .cra_name = "skein256", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_256_BLOCK_BYTES, + } +}; + +static struct shash_alg alg512 = { + .digestsize = (SKEIN512_DIGEST_BIT_SIZE / 8), + .init = skein512_init, + .update = skein512_update, + .final = skein512_final, + .export = skein512_export, + .import = skein512_import, + .descsize = sizeof(struct skein_512_ctx), + .statesize = sizeof(struct skein_512_ctx), + .base = { + .cra_name = "skein512", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_512_BLOCK_BYTES, + } +}; + +static struct shash_alg alg1024 = { + .digestsize = (SKEIN1024_DIGEST_BIT_SIZE / 8), + .init = skein1024_init, + .update = skein1024_update, + .final = skein1024_final, + .export = skein1024_export, + .import = skein1024_import, + .descsize = sizeof(struct skein_1024_ctx), + .statesize = sizeof(struct skein_1024_ctx), + .base = { + .cra_name = "skein1024", + .cra_driver_name = "skein", + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SKEIN_1024_BLOCK_BYTES, + } +}; + +static int __init skein_generic_init(void) +{ + if (crypto_register_shash(&alg256)) + goto out; + if (crypto_register_shash(&alg512)) + goto unreg256; + if (crypto_register_shash(&alg1024)) + goto unreg512; + + return 0; + + +unreg512: + crypto_unregister_shash(&alg512); +unreg256: + crypto_unregister_shash(&alg256); +out: + return -1; +} + +device_initcall(skein_generic_init); -- GitLab From 075c267566a49680f77119d04066339ee354678b Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:33:41 -0500 Subject: [PATCH 1914/9457] staging: skein: Adds Loadable Module Support Adds loadable module support to the Skein Hashing Algorithm driver. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/Kconfig | 2 +- drivers/staging/skein/Makefile | 13 +++++++------ drivers/staging/skein/skein_generic.c | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/staging/skein/Kconfig b/drivers/staging/skein/Kconfig index de8bdd768a7f..012a8233376e 100644 --- a/drivers/staging/skein/Kconfig +++ b/drivers/staging/skein/Kconfig @@ -1,5 +1,5 @@ config CRYPTO_SKEIN - bool "Skein digest algorithm" + tristate "Skein digest algorithm" depends on (X86 || UML_X86) && 64BIT && CRYPTO select CRYPTO_HASH select CRYPTO_ALGAPI diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index d8177cccf3f0..b7f947fb98f0 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -1,9 +1,10 @@ # # Makefile for the skein secure hash algorithm # -obj-$(CONFIG_CRYPTO_SKEIN) += skein_base.o \ - skein_api.o \ - skein_block.o \ - threefish_block.o \ - threefish_api.o \ - skein_generic.o +obj-$(CONFIG_CRYPTO_SKEIN) += skein.o +skein-y := skein_base.o \ + skein_api.o \ + skein_block.o \ + threefish_block.o \ + threefish_api.o \ + skein_generic.o diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c index f2d6dfbc66a4..60d16b639b91 100644 --- a/drivers/staging/skein/skein_generic.c +++ b/drivers/staging/skein/skein_generic.c @@ -16,6 +16,7 @@ */ #include #include +#include #include #include "skein_base.h" @@ -139,6 +140,7 @@ static struct shash_alg alg256 = { .cra_driver_name = "skein", .cra_flags = CRYPTO_ALG_TYPE_SHASH, .cra_blocksize = SKEIN_256_BLOCK_BYTES, + .cra_module = THIS_MODULE, } }; @@ -156,6 +158,7 @@ static struct shash_alg alg512 = { .cra_driver_name = "skein", .cra_flags = CRYPTO_ALG_TYPE_SHASH, .cra_blocksize = SKEIN_512_BLOCK_BYTES, + .cra_module = THIS_MODULE, } }; @@ -173,6 +176,7 @@ static struct shash_alg alg1024 = { .cra_driver_name = "skein", .cra_flags = CRYPTO_ALG_TYPE_SHASH, .cra_blocksize = SKEIN_1024_BLOCK_BYTES, + .cra_module = THIS_MODULE, } }; @@ -196,4 +200,17 @@ static int __init skein_generic_init(void) return -1; } -device_initcall(skein_generic_init); +static void __exit skein_generic_fini(void) +{ + crypto_unregister_shash(&alg256); + crypto_unregister_shash(&alg512); + crypto_unregister_shash(&alg1024); +} + +module_init(skein_generic_init); +module_exit(skein_generic_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Skein Hash Algorithm"); + +MODULE_ALIAS("skein"); -- GitLab From c4597c4426265667c225140ffc84032aae6d937e Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:34:13 -0500 Subject: [PATCH 1915/9457] staging: skein: Inlines rotl_64 Inlines the rotl_64 macro. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_base.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index 9f10af910f41..0111fa426b32 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -33,10 +33,6 @@ #define SKEIN512_DIGEST_BIT_SIZE 512 #define SKEIN1024_DIGEST_BIT_SIZE 1024 -#ifndef rotl_64 -#define rotl_64(x, N) (((x) << (N)) | ((x) >> (64-(N)))) -#endif - /* below two prototype assume we are handed aligned data */ #define skein_put64_lsb_first(dst08, src64, b_cnt) memcpy(dst08, src64, b_cnt) #define skein_get64_lsb_first(dst64, src08, w_cnt) \ @@ -49,12 +45,12 @@ enum { SKEIN_BAD_HASHLEN = 2 }; -#define SKEIN_MODIFIER_WORDS (2) /* number of modifier (tweak) words */ +#define SKEIN_MODIFIER_WORDS 2 /* number of modifier (tweak) words */ -#define SKEIN_256_STATE_WORDS (4) -#define SKEIN_512_STATE_WORDS (8) -#define SKEIN_1024_STATE_WORDS (16) -#define SKEIN_MAX_STATE_WORDS (16) +#define SKEIN_256_STATE_WORDS 4 +#define SKEIN_512_STATE_WORDS 8 +#define SKEIN_1024_STATE_WORDS 16 +#define SKEIN_MAX_STATE_WORDS 16 #define SKEIN_256_STATE_BYTES (8*SKEIN_256_STATE_WORDS) #define SKEIN_512_STATE_BYTES (8*SKEIN_512_STATE_WORDS) @@ -92,6 +88,11 @@ struct skein_1024_ctx { /* 1024-bit Skein hash context structure */ u8 b[SKEIN_1024_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */ }; +static inline int rotl_64(int x, int N) +{ + return (x << N) | (x >> (64 - N)); +} + /* Skein APIs for (incremental) "straight hashing" */ int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len); int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len); -- GitLab From 71077bb2fced15764a2d091c79dad74788771db3 Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Fri, 24 Oct 2014 17:34:37 -0500 Subject: [PATCH 1916/9457] staging: skein: Removes unneeded #define Removes unneeded #define SKEIN_PORT_CODE since skein_port.h is nonexistent. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_base.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/skein/skein_base.c b/drivers/staging/skein/skein_base.c index e0994eae5b40..ebc436a1098f 100644 --- a/drivers/staging/skein/skein_base.c +++ b/drivers/staging/skein/skein_base.c @@ -8,8 +8,6 @@ ** ************************************************************************/ -#define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */ - #include /* get the memcpy/memset functions */ #include #include "skein_base.h" /* get the Skein API definitions */ -- GitLab From 7d95983735889d8f97356fb875a490b55bfd744e Mon Sep 17 00:00:00 2001 From: Koray Gulcu Date: Sun, 12 Oct 2014 19:46:50 +0100 Subject: [PATCH 1917/9457] staging: rtl8192u: Fix sparse warnings of r8182U_core This patch fixes the following endianness warnings found by sparse running with CF=-D__CHECK_ENDIAN__: drivers/staging/rtl8192u/r8192U_core.c:1794:10: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1794:10: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1794:10: got int drivers/staging/rtl8192u/r8192U_core.c:1794:13: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1794:13: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1794:13: got int drivers/staging/rtl8192u/r8192U_core.c:1794:16: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1794:16: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1794:16: got int drivers/staging/rtl8192u/r8192U_core.c:1794:19: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1794:19: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1794:19: got int drivers/staging/rtl8192u/r8192U_core.c:1795:10: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1795:10: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1795:10: got int drivers/staging/rtl8192u/r8192U_core.c:1795:13: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1795:13: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1795:13: got int drivers/staging/rtl8192u/r8192U_core.c:1795:16: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1795:16: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1795:16: got int drivers/staging/rtl8192u/r8192U_core.c:1795:19: warning: incorrect type in initializer (different base types) drivers/staging/rtl8192u/r8192U_core.c:1795:19: expected restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1795:19: got int drivers/staging/rtl8192u/r8192U_core.c:1838:34: warning: cast from restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1839:34: warning: cast from restricted __le16 drivers/staging/rtl8192u/r8192U_core.c:1840:34: warning: cast from restricted __le16 Signed-off-by: Koray Gulcu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 929ac29197cc..49b40eabd819 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1791,8 +1791,8 @@ static void rtl8192_link_change(struct net_device *dev) } static struct ieee80211_qos_parameters def_qos_parameters = { - {3, 3, 3, 3},/* cw_min */ - {7, 7, 7, 7},/* cw_max */ + {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, + {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, {2, 2, 2, 2},/* aifs */ {0, 0, 0, 0},/* flags */ {0, 0, 0, 0} /* tx_op_limit */ @@ -1835,9 +1835,9 @@ static void rtl8192_qos_activate(struct work_struct *work) for (i = 0; i < QOS_QUEUE_NUM; i++) { //Mode G/A: slotTimeTimer = 9; Mode B: 20 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; - u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| - (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| - (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| + u4bAcParam = ((((u32)(le16_to_cpu(qos_parameters->tx_op_limit[i]))) << AC_PARAM_TXOP_LIMIT_OFFSET)| + (((u32)(le16_to_cpu(qos_parameters->cw_max[i]))) << AC_PARAM_ECW_MAX_OFFSET)| + (((u32)(le16_to_cpu(qos_parameters->cw_min[i]))) << AC_PARAM_ECW_MIN_OFFSET)| ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); -- GitLab From 7efa16c3b04e53e1a1c2ddecfcfb9b3aaafb71b5 Mon Sep 17 00:00:00 2001 From: Koray Gulcu Date: Sun, 12 Oct 2014 19:46:51 +0100 Subject: [PATCH 1918/9457] staging: rtl8192u: Fix checkpatch.pl warnings This patch fixes "line over 80 characters" warnings found in the first patch by breaking u4bAcParam's calculation down into a few steps. Signed-off-by: Koray Gulcu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 49b40eabd819..e031a253e2ae 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1821,8 +1821,11 @@ static void rtl8192_qos_activate(struct work_struct *work) struct net_device *dev = priv->ieee80211->dev; struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; u8 mode = priv->ieee80211->current_network.mode; - u8 u1bAIFS; + u32 u1bAIFS; u32 u4bAcParam; + u32 op_limit; + u32 cw_max; + u32 cw_min; int i; mutex_lock(&priv->mutex); @@ -1835,11 +1838,14 @@ static void rtl8192_qos_activate(struct work_struct *work) for (i = 0; i < QOS_QUEUE_NUM; i++) { //Mode G/A: slotTimeTimer = 9; Mode B: 20 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; - u4bAcParam = ((((u32)(le16_to_cpu(qos_parameters->tx_op_limit[i]))) << AC_PARAM_TXOP_LIMIT_OFFSET)| - (((u32)(le16_to_cpu(qos_parameters->cw_max[i]))) << AC_PARAM_ECW_MAX_OFFSET)| - (((u32)(le16_to_cpu(qos_parameters->cw_min[i]))) << AC_PARAM_ECW_MIN_OFFSET)| - ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - + u1bAIFS <<= AC_PARAM_AIFS_OFFSET; + op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[i]); + op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET; + cw_max = (u32)le16_to_cpu(qos_parameters->cw_max[i]); + cw_max <<= AC_PARAM_ECW_MAX_OFFSET; + cw_min = (u32)le16_to_cpu(qos_parameters->cw_min[i]); + cw_min <<= AC_PARAM_ECW_MIN_OFFSET; + u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS; write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); } -- GitLab From 422caed999f9d596dd5f51c62dcf7e2d97ca8df3 Mon Sep 17 00:00:00 2001 From: Paul McQuade Date: Mon, 27 Oct 2014 16:13:29 +0000 Subject: [PATCH 1919/9457] staging: rtl8188eu: hal: space required ERROR: space required before the open brace '{' Signed-off-by: Paul McQuade Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/bb_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index 80e8cc92c10a..c2d166fa0a7f 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -173,7 +173,7 @@ static bool set_baseband_agc_config(struct adapter *adapt) u32 v1 = array[i]; u32 v2 = array[i+1]; - if (v1 < 0xCDCDCDCD){ + if (v1 < 0xCDCDCDCD) { phy_set_bb_reg(adapt, v1, bMaskDWord, v2); udelay(1); } -- GitLab From d59d6f5d38962caf82536b393db2bdf7578a0719 Mon Sep 17 00:00:00 2001 From: Greg Donald Date: Sun, 26 Oct 2014 15:19:22 -0500 Subject: [PATCH 1920/9457] staging: rtl8192u: Fix "space prohibited after that open parenthesis '('" errors Fix checkpatch.pl "space prohibited after that open parenthesis '('" errors Signed-off-by: Greg Donald Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192u/ieee80211/ieee80211_rx.c | 22 ++++++++----------- .../rtl8192u/ieee80211/ieee80211_softmac.c | 11 ++++------ .../rtl8192u/ieee80211/ieee80211_softmac_wx.c | 2 +- .../staging/rtl8192u/ieee80211/ieee80211_tx.c | 3 +-- .../rtl8192u/ieee80211/rtl819x_BAProc.c | 16 +++++--------- .../rtl8192u/ieee80211/rtl819x_HTProc.c | 11 ++++------ 6 files changed, 25 insertions(+), 40 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 73de9e9669f6..d401dbf4c7c6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -713,8 +713,8 @@ static void RxReorderIndicatePacket(struct ieee80211_device *ieee, while(!list_empty(&pTS->RxPendingPktList)) { IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__func__); pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) + if (SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { /* This protect buffer from overflow. */ if(index >= REORDER_WIN_SIZE) { @@ -800,9 +800,8 @@ static u8 parse_subframe(struct sk_buff *skb, // Null packet, don't indicate it to upper layer ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ - if( skb->len <= ChkLength ) { + if (skb->len <= ChkLength) return 0; - } skb_pull(skb, LLCOffset); @@ -1035,10 +1034,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, { // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__func__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc)); - if( (fc & (1<<11)) && - (frag == pRxTS->RxLastFragNum) && - (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) ) - { + if ((fc & (1<<11)) && + (frag == pRxTS->RxLastFragNum) && + (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) { goto rx_dropped; } else @@ -2456,7 +2454,7 @@ static inline void ieee80211_process_probe_response( // then wireless adapter should do active scan from ch1~11 and // passive scan from ch12~14 - if( !IsLegalChannel(ieee, network.channel) ) + if (!IsLegalChannel(ieee, network.channel)) return; if(ieee->bGlobalDomain) { @@ -2465,8 +2463,7 @@ static inline void ieee80211_process_probe_response( // Case 1: Country code if(IS_COUNTRY_IE_VALID(ieee) ) { - if( !IsLegalChannel(ieee, network.channel) ) - { + if (!IsLegalChannel(ieee, network.channel)) { printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); return; } @@ -2487,8 +2484,7 @@ static inline void ieee80211_process_probe_response( // Case 1: Country code if(IS_COUNTRY_IE_VALID(ieee) ) { - if( !IsLegalChannel(ieee, network.channel) ) - { + if (!IsLegalChannel(ieee, network.channel)) { printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel); return; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index a1c745b1cf99..9b874086766f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1043,10 +1043,9 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco { ccxrm_ie_len = 6+2; } - if( beacon->BssCcxVerNumber >= 2 ) - { + if (beacon->BssCcxVerNumber >= 2) cxvernum_ie_len = 5+2; - } + #ifdef THOMAS_TURBO len = sizeof(struct ieee80211_assoc_request_frame)+ 2 + beacon->ssid_len//essid tagged val @@ -1118,8 +1117,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco ieee80211_MFIE_Brate(ieee, &tag); ieee80211_MFIE_Grate(ieee, &tag); // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. - if( beacon->bCkipSupported ) - { + if (beacon->bCkipSupported) { static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" u8 CcxAironetBuf[30]; OCTET_STRING osCcxAironetIE; @@ -1158,8 +1156,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco tag += osCcxRmCap.Length; } - if( beacon->BssCcxVerNumber >= 2 ) - { + if (beacon->BssCcxVerNumber >= 2) { u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; OCTET_STRING osCcxVerNum; CcxVerNumBuf[4] = beacon->BssCcxVerNumber; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index 82ea533a0cf4..644368df6342 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -374,7 +374,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info goto out; } - if ( ieee->state == IEEE80211_LINKED){ + if (ieee->state == IEEE80211_LINKED) { queue_work(ieee->wq, &ieee->wx_sync_scan_wq); /* intentionally forget to up sem */ return 0; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 57bef219687b..fca73c7c9fbe 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -529,8 +529,7 @@ static void ieee80211_query_protectionmode(struct ieee80211_device *ieee, } } // For test , CTS replace with RTS - if( 0 ) - { + if (0) { tcb_desc->bCTSEnable = true; tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index a95508d9820e..cd196cec0dd9 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c @@ -342,8 +342,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb) PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL; PRX_TS_RECORD pTS = NULL; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, @@ -444,8 +443,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) PBA_PARAM_SET pBaParamSet = NULL; u16 ReasonCode; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, @@ -463,10 +461,9 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb) // Check the capability // Since we can always receive A-MPDU, we just check if it is under HT mode. - if( ieee->current_network.qos_data.active == 0 || - ieee->pHTInfo->bCurrentHTSupport == false || - ieee->pHTInfo->bCurrentAMPDUEnable == false ) - { + if (ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false || + ieee->pHTInfo->bCurrentAMPDUEnable == false) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; @@ -577,8 +574,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb) u16 *pReasonCode = NULL; u8 *dst = NULL; - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) - { + if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) { IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index 1ea2cd392670..e60d926a3973 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -602,8 +602,7 @@ void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u // TODO: Nedd to take care of this part IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); - if( IsEncrypt) - { + if (IsEncrypt) { pCapELE->MPDUDensity = 7; // 8us pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K } @@ -951,8 +950,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee) static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - if( pHTInfo->bCurrentHTSupport == false ) - { + if (pHTInfo->bCurrentHTSupport == false) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n"); return; } @@ -1043,7 +1041,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee) // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily if (ieee->current_network.bssht.bdRT2RTAggregation) { - if( ieee->pairwise_key_type != KEY_TYPE_NA) + if (ieee->pairwise_key_type != KEY_TYPE_NA) // Realtek may set 32k in security mode and 64k for others pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; else @@ -1332,8 +1330,7 @@ u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame) { if(ieee->pHTInfo->bCurrentHTSupport) { - if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) - { + if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n"); return true; } -- GitLab From c42645a2c54ffd82817e7a11fa05fffde08463a3 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 21 Oct 2014 17:00:24 +0200 Subject: [PATCH 1921/9457] staging: vt6655: Remove redundant cast Both sides have type const struct iw_handler_def*, so the cast is unnecessary and confusing. Signed-off-by: Rasmus Villemoes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index c8f262f58c7b..ef848e2f0585 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -932,7 +932,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) dev->irq = pcid->irq; dev->netdev_ops = &device_netdev_ops; - dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def; + dev->wireless_handlers = &iwctl_handler_def; rc = register_netdev(dev); if (rc) { -- GitLab From 79bffc5344f1fa35e8a0656e7beac593a99a7034 Mon Sep 17 00:00:00 2001 From: Nicky Chorley Date: Sun, 26 Oct 2014 06:30:29 +0000 Subject: [PATCH 1922/9457] Staging: vt6655: Remove C99 comments This patch fixes the following errors identified by checkpatch.pl: ERROR: do not use C99 // comments 36: FILE: card.h:36: // ERROR: do not use C99 // comments 37: FILE: card.h:37: // Loopback mode ERROR: do not use C99 // comments 38: FILE: card.h:38: // ERROR: do not use C99 // comments 39: FILE: card.h:39: // LOBYTE is MAC LB mode, HIBYTE is MII LB mode ERROR: do not use C99 // comments 41: FILE: card.h:41: #define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) // PHY must ISO, avoid MAC loopback packet go out ERROR: do not use C99 // comments 44: FILE: card.h:44: #define DEFAULT_MSDU_LIFETIME 512 // ms ERROR: do not use C99 // comments 45: FILE: card.h:45: #define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us ERROR: do not use C99 // comments 47: FILE: card.h:47: #define DEFAULT_MGN_LIFETIME 8 // ms ERROR: do not use C99 // comments 48: FILE: card.h:48: #define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us ERROR: do not use C99 // comments 175: FILE: card.h:175: #endif // __CARD_H__ Signed-off-by: Nicky Chorley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 96f5b6c46e82..e5bde0920553 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -33,19 +33,20 @@ #include #include -// -// Loopback mode -// -// LOBYTE is MAC LB mode, HIBYTE is MII LB mode +/* + * Loopback mode + * + * LOBYTE is MAC LB mode, HIBYTE is MII LB mode + */ #define CARD_LB_NONE MAKEWORD(MAC_LB_NONE, 0) -#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) // PHY must ISO, avoid MAC loopback packet go out +#define CARD_LB_MAC MAKEWORD(MAC_LB_INTERNAL, 0) /* PHY must ISO, avoid MAC loopback packet go out */ #define CARD_LB_PHY MAKEWORD(MAC_LB_EXT, 0) -#define DEFAULT_MSDU_LIFETIME 512 // ms -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us +#define DEFAULT_MSDU_LIFETIME 512 /* ms */ +#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ -#define DEFAULT_MGN_LIFETIME 8 // ms -#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us +#define DEFAULT_MGN_LIFETIME 8 /* ms */ +#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ #define CB_MAX_CHANNEL_24G 14 #define CB_MAX_CHANNEL_5G 42 @@ -172,4 +173,4 @@ CARDbyGetTransmitPower( struct vnt_private * ); -#endif // __CARD_H__ +#endif /* __CARD_H__ */ -- GitLab From 4baa70f69d842a04fc247b5ba4d2778306668f54 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Mon, 20 Oct 2014 13:20:08 -0700 Subject: [PATCH 1923/9457] staging: clocking-wizard: Contain macro argument in parenthesis A macro doing some arithmetic to calculate a register offset, did not contain an argument to the macro in parentheses, potentially leading to unexpected results when using that macro with arithmetic expressions as argument. Signed-off-by: Soren Brinkmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c index b8d89525bffd..7202d8e889aa 100644 --- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c @@ -29,7 +29,7 @@ #define WZRD_NUM_OUTPUTS 7 #define WZRD_ACLK_MAX_FREQ 250000000UL -#define WZRD_CLK_CFG_REG(n) (0x200 + 4 * n) +#define WZRD_CLK_CFG_REG(n) (0x200 + 4 * (n)) #define WZRD_CLkOUT0_FRAC_EN BIT(18) #define WZRD_CLkFBOUT_FRAC_EN BIT(26) -- GitLab From b7da2d68bb72b9565747bf4b5e785428867b4165 Mon Sep 17 00:00:00 2001 From: Chen Weixiang Date: Sun, 19 Oct 2014 20:59:44 +0800 Subject: [PATCH 1924/9457] staging: ft1000: do not initialise statics to 0 or NULL Remove following checkpatch.pl error from ft1000/ft1000-usb/ft1000_debug.c ERROR: do not initialise statics to 0 or NULL Signed-off-by: Chen Weixiang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 4672c4d56205..4397ada1e387 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -38,7 +38,7 @@ #include #include "ft1000_usb.h" -static int ft1000_flarion_cnt = 0; +static int ft1000_flarion_cnt; static int ft1000_open(struct inode *inode, struct file *file); static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); -- GitLab From 5d069c8886fe80ce001dd6bdfadee1d42a6c8efa Mon Sep 17 00:00:00 2001 From: Fabio Falzoi Date: Sun, 19 Oct 2014 21:30:02 +0200 Subject: [PATCH 1925/9457] Staging: rts5208: helper function to manage aspm during reset Define the helper function rtsx_reset_aspm to shorten the rtsx_reset_chip code and get rid of the LONG_LINE checkpatch warnings. Signed-off-by: Fabio Falzoi Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 70 ++++++++++++++++------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index ffcf5deb49b2..ea6cfd1f7282 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -227,6 +227,42 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) } #endif +static int rtsx_reset_aspm(struct rtsx_chip *chip) +{ + int ret; + + if (chip->dynamic_aspm) { + if (!CHK_SDIO_EXIST(chip) || !CHECK_PID(chip, 0x5288)) + return STATUS_SUCCESS; + + ret = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, + chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; + } + + if (CHECK_PID(chip, 0x5208)) + RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); + ret = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->aspm_level[0] = chip->aspm_l0s_l1_en; + if (CHK_SDIO_EXIST(chip)) { + chip->aspm_level[1] = chip->aspm_l0s_l1_en; + ret = rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, + 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + chip->aspm_enabled = 1; + + return STATUS_SUCCESS; +} + int rtsx_reset_chip(struct rtsx_chip *chip) { int retval; @@ -289,37 +325,9 @@ int rtsx_reset_chip(struct rtsx_chip *chip) /* Enable ASPM */ if (chip->aspm_l0s_l1_en) { - if (chip->dynamic_aspm) { - if (CHK_SDIO_EXIST(chip) && CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, - chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (CHECK_PID(chip, 0x5208)) - RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, - 0xFF, 0x3F); - - retval = rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->aspm_level[0] = chip->aspm_l0s_l1_en; - if (CHK_SDIO_EXIST(chip)) { - chip->aspm_level[1] = chip->aspm_l0s_l1_en; - retval = rtsx_write_cfg_dw(chip, - CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF, - chip->aspm_l0s_l1_en); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - chip->aspm_enabled = 1; - } + retval = rtsx_reset_aspm(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); } else { if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_write_phy_register(chip, 0x07, 0x0129); -- GitLab From 506fe17daee8040f642150df504db09a4573214e Mon Sep 17 00:00:00 2001 From: Fabio Falzoi Date: Sun, 19 Oct 2014 21:30:03 +0200 Subject: [PATCH 1926/9457] Staging: rts5208: helper function to enable interrupts during reset Define the helper function rtsx_enable_pcie_intr to shorten the rtsx_reset_chip code and get rid of the LONG_LINE checkpatch warnings. Signed-off-by: Fabio Falzoi Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_chip.c | 95 +++++++++++++++-------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index ea6cfd1f7282..9593d8132938 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -263,6 +263,51 @@ static int rtsx_reset_aspm(struct rtsx_chip *chip) return STATUS_SUCCESS; } +static int rtsx_enable_pcie_intr(struct rtsx_chip *chip) +{ + int ret; + + if (!chip->asic_code || !CHECK_PID(chip, 0x5208)) { + rtsx_enable_bus_int(chip); + return STATUS_SUCCESS; + } + + if (chip->phy_debug_mode) { + RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); + rtsx_disable_bus_int(chip); + } else { + rtsx_enable_bus_int(chip); + } + + if (chip->ic_version >= IC_VER_D) { + u16 reg; + + ret = rtsx_read_phy_register(chip, 0x00, ®); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFE7F; + reg |= 0x80; + ret = rtsx_write_phy_register(chip, 0x00, reg); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ret = rtsx_read_phy_register(chip, 0x1C, ®); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFFF7; + ret = rtsx_write_phy_register(chip, 0x1C, reg); + if (ret != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) + rtsx_calibration(chip); + + return STATUS_SUCCESS; +} + int rtsx_reset_chip(struct rtsx_chip *chip) { int retval; @@ -367,53 +412,9 @@ int rtsx_reset_chip(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); - /* Enable PCIE interrupt */ - if (chip->asic_code) { - if (CHECK_PID(chip, 0x5208)) { - if (chip->phy_debug_mode) { - RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); - rtsx_disable_bus_int(chip); - } else { - rtsx_enable_bus_int(chip); - } - - if (chip->ic_version >= IC_VER_D) { - u16 reg; - - retval = rtsx_read_phy_register(chip, 0x00, - ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFE7F; - reg |= 0x80; - retval = rtsx_write_phy_register(chip, 0x00, - reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_read_phy_register(chip, 0x1C, - ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFFF7; - retval = rtsx_write_phy_register(chip, 0x1C, - reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if (chip->driver_first_load && - (chip->ic_version < IC_VER_C)) - rtsx_calibration(chip); - - } else { - rtsx_enable_bus_int(chip); - } - } else { - rtsx_enable_bus_int(chip); - } + retval = rtsx_enable_pcie_intr(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); chip->need_reset = 0; -- GitLab From 0c05a5d66397d7c3d4ac05075a3ba7ecef1e1978 Mon Sep 17 00:00:00 2001 From: Brian Vandre Date: Tue, 21 Oct 2014 17:56:47 -0500 Subject: [PATCH 1927/9457] Staging: iio: adc: fix line over 80 characters This fixes the 2 checkpatch.pl warnings: WARNING: line over 80 characters Signed-off-by: Brian Vandre Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/mxs-lradc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 32a19264a170..62449a67ebd6 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -455,7 +455,8 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch) * SoC's delay unit and start the conversion later * and automatically. */ - mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ + mxs_lradc_reg_wrt(lradc, + LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */ LRADC_DELAY_KICK | LRADC_DELAY_DELAY(lradc->settling_delay), @@ -513,7 +514,8 @@ static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1, * SoC's delay unit and start the conversion later * and automatically. */ - mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ + mxs_lradc_reg_wrt(lradc, + LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */ LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */ LRADC_DELAY_KICK | LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2)); -- GitLab From eecc515a1b5ed6188562471f41a78988290376e6 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 22 Oct 2014 23:22:27 +0200 Subject: [PATCH 1928/9457] staging: rtl8712: Remove redundant cast struct firmware::data has type const u8*, as does *ppmappedfw, so the cast to u8* is unnecessary and slightly confusing. Signed-off-by: Rasmus Villemoes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/hal_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 1d6ade05fa18..83f93412c154 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -86,7 +86,7 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw) (int)padapter->fw->size); return 0; } - *ppmappedfw = (u8 *)((*praw)->data); + *ppmappedfw = (*praw)->data; return (*praw)->size; } -- GitLab From 5fae8b86fdf083bc43bf759abad6661be9d0b9ac Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 24 Oct 2014 15:16:52 +0300 Subject: [PATCH 1929/9457] pinctrl: Move Intel Baytrail pinctrl driver under intel directory We are going to have more pinctrl drivers for Intel hardware so separate all our pin controller drivers to own directory. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 13 +------------ drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/intel/Kconfig | 15 +++++++++++++++ drivers/pinctrl/intel/Makefile | 3 +++ drivers/pinctrl/{ => intel}/pinctrl-baytrail.c | 0 5 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 drivers/pinctrl/intel/Kconfig create mode 100644 drivers/pinctrl/intel/Makefile rename drivers/pinctrl/{ => intel}/pinctrl-baytrail.c (100%) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c6a66de6ed72..d014f22f387a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -67,18 +67,6 @@ config PINCTRL_AT91 help Say Y here to enable the at91 pinctrl driver -config PINCTRL_BAYTRAIL - bool "Intel Baytrail GPIO pin control" - depends on GPIOLIB && ACPI && X86 - select GPIOLIB_IRQCHIP - help - driver for memory mapped GPIO functionality on Intel Baytrail - platforms. Supports 3 banks with 102, 28 and 44 gpios. - Most pins are usually muxed to some other functionality by firmware, - so only a small amount is available for gpio use. - - Requires ACPI device enumeration code to set up a platform device. - config PINCTRL_BCM2835 bool select PINMUX @@ -205,6 +193,7 @@ config PINCTRL_PALMAS source "drivers/pinctrl/berlin/Kconfig" source "drivers/pinctrl/freescale/Kconfig" +source "drivers/pinctrl/intel/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/nomadik/Kconfig" source "drivers/pinctrl/qcom/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 51f52d32859e..c030b3db8034 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o -obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o @@ -39,6 +38,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-y += freescale/ +obj-$(CONFIG_X86) += intel/ obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-y += nomadik/ obj-$(CONFIG_ARCH_QCOM) += qcom/ diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig new file mode 100644 index 000000000000..957c90386307 --- /dev/null +++ b/drivers/pinctrl/intel/Kconfig @@ -0,0 +1,15 @@ +# +# Intel pin control drivers +# + +config PINCTRL_BAYTRAIL + bool "Intel Baytrail GPIO pin control" + depends on GPIOLIB && ACPI + select GPIOLIB_IRQCHIP + help + driver for memory mapped GPIO functionality on Intel Baytrail + platforms. Supports 3 banks with 102, 28 and 44 gpios. + Most pins are usually muxed to some other functionality by firmware, + so only a small amount is available for gpio use. + + Requires ACPI device enumeration code to set up a platform device. diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile new file mode 100644 index 000000000000..d049b769e327 --- /dev/null +++ b/drivers/pinctrl/intel/Makefile @@ -0,0 +1,3 @@ +# Intel pin control drivers + +obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c similarity index 100% rename from drivers/pinctrl/pinctrl-baytrail.c rename to drivers/pinctrl/intel/pinctrl-baytrail.c -- GitLab From cbd1b6529f07308bc4921a088b0f83895e403109 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 24 Oct 2014 15:16:53 +0300 Subject: [PATCH 1930/9457] MAINTAINERS: Add entry for Intel pin controller drivers Add MAINTAINERS entry for Intel pin controller drivers. I will be maintaining them with Heikki, who kindly promised to help me with this. Signed-off-by: Heikki Krogerus Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c017d90bc739..f8042cfa4f6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7163,6 +7163,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/pinctrl/pinctrl-at91.* +PIN CONTROLLER - INTEL +M: Mika Westerberg +M: Heikki Krogerus +S: Maintained +F: drivers/pinctrl/intel/ + PIN CONTROLLER - RENESAS M: Laurent Pinchart L: linux-sh@vger.kernel.org -- GitLab From e29d3ebcda3ebc0193fb98c53c6c3ca6fa2fc030 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 27 Oct 2014 17:42:25 +0530 Subject: [PATCH 1931/9457] staging: rtl8712: remove unused variables unused variables are removed. These variables were only assigned some values and after that they were never being used. So they are safe to be removed , and it has been build tested. I left a call to r8712_read32(padapter, TCR) and r8712_read8(padapter, SDIO_HCPWM) . r8712_read32() and r8712_read8() is ultimately calling usb_read32() and usb_read8() respectively. and they are again calling r8712_usbctrl_vendorreq(). this r8712_usbctrl_vendorreq() is communicating through the usb bus and is sending and receiving the control msg. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/hal_init.c | 9 ++------ drivers/staging/rtl8712/ieee80211.c | 3 +-- drivers/staging/rtl8712/rtl8712_cmd.c | 13 +---------- drivers/staging/rtl8712/rtl8712_efuse.c | 3 +-- drivers/staging/rtl8712/rtl8712_recv.c | 15 ++---------- drivers/staging/rtl8712/rtl871x_cmd.c | 2 -- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 19 ++++----------- drivers/staging/rtl8712/rtl871x_ioctl_set.c | 4 ---- drivers/staging/rtl8712/rtl871x_mlme.c | 23 ++++++------------- drivers/staging/rtl8712/rtl871x_mp_ioctl.c | 3 --- drivers/staging/rtl8712/rtl871x_pwrctrl.c | 4 +--- drivers/staging/rtl8712/rtl871x_recv.c | 19 +-------------- drivers/staging/rtl8712/rtl871x_recv.h | 3 --- drivers/staging/rtl8712/rtl871x_security.c | 10 ++------ drivers/staging/rtl8712/rtl871x_sta_mgt.c | 11 +-------- drivers/staging/rtl8712/rtl871x_xmit.c | 13 ++++------- drivers/staging/rtl8712/usb_intf.c | 6 ----- drivers/staging/rtl8712/usb_ops_linux.c | 3 +-- drivers/staging/rtl8712/xmit_linux.c | 4 +--- 19 files changed, 30 insertions(+), 137 deletions(-) diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 83f93412c154..324da34383ea 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -136,15 +136,10 @@ static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw) static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength) { u32 fwhdrsz, fw_sz; - u8 intf, rfconf; /* check signature */ if ((pfwhdr->signature != 0x8712) && (pfwhdr->signature != 0x8192)) return _FAIL; - /* check interface */ - intf = (u8)((pfwhdr->version&0x3000) >> 12); - /* check rf_conf */ - rfconf = (u8)((pfwhdr->version&0xC000) >> 14); /* check fw_priv_sze & sizeof(struct fw_priv) */ if (pfwhdr->fw_priv_sz != sizeof(struct fw_priv)) return _FAIL; @@ -162,7 +157,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) sint i; u8 tmp8, tmp8_a; u16 tmp16; - u32 maxlen = 0, tmp32; /* for compare usage */ + u32 maxlen = 0; /* for compare usage */ uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ struct fw_hdr fwhdr; u32 ulfilelength; /* FW file size */ @@ -262,7 +257,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) if (tmp8_a != (tmp8|BIT(2))) goto exit_fail; - tmp32 = r8712_read32(padapter, TCR); + r8712_read32(padapter, TCR); /* 4.polling IMEM Ready */ i = 100; diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index eb23b08cb7fd..57868085ce58 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -368,13 +368,12 @@ int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len) { - u8 authmode, sec_idx; + u8 authmode; u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; uint cnt; /*Search required WPA or WPA2 IE and copy to sec_ie[ ]*/ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); - sec_idx = 0; while (cnt < in_len) { authmode = in_ie[cnt]; if ((authmode == _WPA_IE_ID_) && diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 720e8a15db96..62e53cc1d8b9 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -157,10 +157,8 @@ static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) { u32 val; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct readBB_parm *prdbbparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - prdbbparm = (struct readBB_parm *)pcmd->parmbuf; if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; @@ -174,10 +172,8 @@ static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) { void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct writeBB_parm *pwritebbparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - pwritebbparm = (struct writeBB_parm *)pcmd->parmbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; if (pcmd_callback == NULL) r8712_free_cmd_obj(pcmd); @@ -190,10 +186,8 @@ static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) { u32 val; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct readRF_parm *prdrfparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - prdrfparm = (struct readRF_parm *)pcmd->parmbuf; if (pcmd->rsp && pcmd->rspsz > 0) memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); pcmd_callback = cmd_callback[pcmd->cmdcode].callback; @@ -207,10 +201,8 @@ static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) { void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct writeRF_parm *pwriterfparm; struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - pwriterfparm = (struct writeRF_parm *)pcmd->parmbuf; pcmd_callback = cmd_callback[pcmd->cmdcode].callback; if (pcmd_callback == NULL) r8712_free_cmd_obj(pcmd); @@ -222,9 +214,7 @@ static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) static u8 sys_suspend_hdl(struct _adapter *padapter, u8 *pbuf) { struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - struct usb_suspend_parm *psetusbsuspend; - psetusbsuspend = (struct usb_suspend_parm *)pcmd->parmbuf; r8712_free_cmd_obj(pcmd); return H2C_SUCCESS; } @@ -320,7 +310,7 @@ void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag) int r8712_cmd_thread(void *context) { struct cmd_obj *pcmd; - unsigned int cmdsz, wr_sz, *pcmdbuf, *prspbuf; + unsigned int cmdsz, wr_sz, *pcmdbuf; struct tx_desc *pdesc; void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); struct _adapter *padapter = (struct _adapter *)context; @@ -342,7 +332,6 @@ int r8712_cmd_thread(void *context) continue; } pcmdbuf = (unsigned int *)pcmdpriv->cmd_buf; - prspbuf = (unsigned int *)pcmdpriv->rsp_buf; pdesc = (struct tx_desc *)pcmdbuf; memset(pdesc, 0, TXDESC_SIZE); pcmd = cmd_hdl_filter(padapter, pcmd); diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index 97b78392e6c8..d95716999498 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -219,13 +219,12 @@ u16 r8712_efuse_get_current_size(struct _adapter *padapter) { int bContinual = true; u16 efuse_addr = 0; - u8 hoffset = 0, hworden = 0; + u8 hworden = 0; u8 efuse_data, word_cnts = 0; while (bContinual && efuse_one_byte_read(padapter, efuse_addr, &efuse_data) && (efuse_addr < efuse_available_max_size)) { if (efuse_data != 0xFF) { - hoffset = (efuse_data >> 4) & 0x0F; hworden = efuse_data & 0x0F; word_cnts = calculate_word_cnts(hworden); /* read next header */ diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index b27806209268..27f38acc2d62 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -158,8 +158,6 @@ int r8712_free_recvframe(union recv_frame *precvframe, static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, struct recv_stat *prxstat) { - u32 *pphy_info; - struct phy_stat *pphy_stat; u16 drvinfo_sz = 0; drvinfo_sz = (le32_to_cpu(prxstat->rxdw0)&0x000f0000)>>16; @@ -189,10 +187,6 @@ static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, /*Offset 16*/ /*Offset 20*/ /*phy_info*/ - if (drvinfo_sz) { - pphy_stat = (struct phy_stat *)(prxstat+1); - pphy_info = (u32 *)prxstat+1; - } } /*perform defrag*/ @@ -200,7 +194,7 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter, struct __queue *defrag_q) { struct list_head *plist, *phead; - u8 *data, wlanhdr_offset; + u8 wlanhdr_offset; u8 curfragnum; struct recv_frame_hdr *pfhdr, *pnfhdr; union recv_frame *prframe, *pnextrframe; @@ -223,7 +217,6 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter, curfragnum++; plist = &defrag_q->queue; plist = plist->next; - data = get_recvframe_data(prframe); while (end_of_queue_search(phead, plist) == false) { pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); pnfhdr = &pnextrframe->u.hdr; @@ -436,13 +429,11 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) { uint voffset; u8 *poffset; - u16 pkt_len, cmd_len, drvinfo_sz; - u8 eid, cmd_seq; + u16 cmd_len, drvinfo_sz; struct recv_stat *prxstat; poffset = (u8 *)prxcmdbuf; voffset = *(uint *)poffset; - pkt_len = le32_to_cpu(voffset) & 0x00003fff; prxstat = (struct recv_stat *)prxcmdbuf; drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16); drvinfo_sz = drvinfo_sz << 3; @@ -450,8 +441,6 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) do { voffset = *(uint *)poffset; cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff); - cmd_seq = (u8)((le32_to_cpu(voffset) >> 24) & 0x7f); - eid = (u8)((le32_to_cpu(voffset) >> 16) & 0xff); r8712_event_handle(padapter, (uint *)poffset); poffset += (cmd_len + 8);/*8 bytes alignment*/ } while (le32_to_cpu(voffset) & BIT(31)); diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 92101b98c49a..fe5e315319f7 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -470,7 +470,6 @@ u8 r8712_createbss_cmd(struct _adapter *padapter) u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) { - u8 *auth; uint t_len = 0; struct ndis_wlan_bssid_ex *psecnetwork; struct cmd_obj *pcmd; @@ -517,7 +516,6 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) return _FAIL; } memcpy(psecnetwork, &pnetwork->network, t_len); - auth = &psecuritypriv->authenticator_ie[0]; psecuritypriv->authenticator_ie[0] = (unsigned char) psecnetwork->IELength; if ((psecnetwork->IELength-12) < (256 - 1)) diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index b4ffc0e31110..73b7d864ccbd 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -170,7 +170,7 @@ static inline char *translate_scan(struct _adapter *padapter, s8 *p; u32 i = 0, ht_ielen = 0; u16 cap, ht_cap = false, mcs_rate; - u8 rssi, bw_40MHz = 0, short_GI = 0; + u8 rssi; if ((pnetwork->network.Configuration.DSConfig < 1) || (pnetwork->network.Configuration.DSConfig > 14)) { @@ -197,10 +197,6 @@ static inline char *translate_scan(struct _adapter *padapter, ht_cap = true; pht_capie = (struct ieee80211_ht_cap *)(p + 2); memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2); - bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) - ? 1 : 0; - short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; } /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; @@ -287,12 +283,10 @@ static inline char *translate_scan(struct _adapter *padapter, u8 wpa_ie[255], rsn_ie[255]; u16 wpa_len = 0, rsn_len = 0; int n; - sint out_len = 0; - out_len = r8712_get_sec_ie(pnetwork->network.IEs, - pnetwork->network. - IELength, rsn_ie, &rsn_len, - wpa_ie, &wpa_len); + r8712_get_sec_ie(pnetwork->network.IEs, + pnetwork->network.IELength, rsn_ie, &rsn_len, + wpa_ie, &wpa_len); if (wpa_len > 0) { memset(buf, 0, MAX_WPA_IE_LEN); n = sprintf(buf, "wpa_ie="); @@ -512,7 +506,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, unsigned short ielen) { - u8 *buf = NULL, *pos = NULL; + u8 *buf = NULL; int group_cipher = 0, pairwise_cipher = 0; int ret = 0; @@ -522,7 +516,6 @@ static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, buf = kmemdup(pie, ielen, GFP_ATOMIC); if (buf == NULL) return -ENOMEM; - pos = buf; if (ielen < RSN_HEADER_LEN) { ret = -EINVAL; goto exit; @@ -1133,13 +1126,11 @@ static int r871x_wx_set_mlme(struct net_device *dev, union iwreq_data *wrqu, char *extra) { int ret = 0; - u16 reason; struct _adapter *padapter = (struct _adapter *)netdev_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *) extra; if (mlme == NULL) return -1; - reason = cpu_to_le16(mlme->reason_code); switch (mlme->cmd) { case IW_MLME_DEAUTH: if (!r8712_set_802_11_disassociate(padapter)) diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index a240b6389683..6318a0e65e6e 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -343,13 +343,9 @@ u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter, u8 r8712_set_802_11_add_wep(struct _adapter *padapter, struct NDIS_802_11_WEP *wep) { - u8 bdefaultkey; - u8 btransmitkey; sint keyid; struct security_priv *psecuritypriv = &padapter->securitypriv; - bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? false : true; - btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? true : false; keyid = wep->KeyIndex & 0x3fffffff; if (keyid >= WEP_KEYS) return false; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 4b602fe1dba1..b7462e8145d6 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -1372,7 +1372,7 @@ static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len) { - u8 authmode = 0, securitytype, match; + u8 authmode = 0, match; u8 sec_ie[255], uncst_oui[4], bkup_ie[255]; u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; uint ielength, cnt, remove_cnt; @@ -1399,21 +1399,17 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, switch (ndissecuritytype) { case Ndis802_11Encryption1Enabled: case Ndis802_11Encryption1KeyAbsent: - securitytype = _WEP40_; uncst_oui[3] = 0x1; break; case Ndis802_11Encryption2Enabled: case Ndis802_11Encryption2KeyAbsent: - securitytype = _TKIP_; uncst_oui[3] = 0x2; break; case Ndis802_11Encryption3Enabled: case Ndis802_11Encryption3KeyAbsent: - securitytype = _AES_; uncst_oui[3] = 0x4; break; default: - securitytype = _NO_PRIVACY_; break; } /*Search required WPA or WPA2 IE and copy to sec_ie[] */ @@ -1705,7 +1701,7 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) { u32 ielen, out_len; - unsigned char *p, *pframe; + unsigned char *p; struct ieee80211_ht_cap ht_capie; unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -1717,10 +1713,8 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, if (p && (ielen > 0)) { if (pqospriv->qos_option == 0) { out_len = *pout_len; - pframe = r8712_set_ie(out_ie+out_len, - _VENDOR_SPECIFIC_IE_, - _WMM_IE_Length_, - WMM_IE, pout_len); + r8712_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_, + _WMM_IE_Length_, WMM_IE, pout_len); pqospriv->qos_option = 1; } out_len = *pout_len; @@ -1733,9 +1727,9 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, IEEE80211_HT_CAP_DSSSCCK40; ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); - pframe = r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, - sizeof(struct ieee80211_ht_cap), - (unsigned char *)&ht_capie, pout_len); + r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, + sizeof(struct ieee80211_ht_cap), + (unsigned char *)&ht_capie, pout_len); phtpriv->ht_option = 1; } return phtpriv->ht_option; @@ -1748,7 +1742,6 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) int i, len; struct sta_info *bmc_sta, *psta; struct ieee80211_ht_cap *pht_capie; - struct ieee80211_ht_addt_info *pht_addtinfo; struct recv_reorder_ctrl *preorder_ctrl; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ht_priv *phtpriv = &pmlmepriv->htpriv; @@ -1801,8 +1794,6 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof(struct NDIS_802_11_FIXED_IEs)); - if (p && len > 0) - pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2); } void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c index 9827ff8143b2..a16f15e91992 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c @@ -1431,11 +1431,8 @@ unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) /*-------------------------------------------------------------------------*/ uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) { - u8 bpwrup; - if (poid_par_priv->type_of_oid != SET_OID) return RNDIS_STATUS_NOT_ACCEPTED; - bpwrup = *(u8 *)poid_par_priv->information_buf; /*CALL the power_down function*/ return RNDIS_STATUS_SUCCESS; } diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index 51dcf5555b62..ed2844d2b02a 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -156,11 +156,9 @@ static void rpwm_workitem_callback(struct work_struct *work) struct pwrctrl_priv, rpwm_workitem); struct _adapter *padapter = container_of(pwrpriv, struct _adapter, pwrctrlpriv); - u8 cpwm = pwrpriv->cpwm; - if (pwrpriv->cpwm != pwrpriv->rpwm) { _enter_pwrlock(&pwrpriv->lock); - cpwm = r8712_read8(padapter, SDIO_HCPWM); + r8712_read8(padapter, SDIO_HCPWM); pwrpriv->rpwm_retry = 1; r8712_set_rpwm(padapter, pwrpriv->rpwm); up(&pwrpriv->lock); diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 9b99a71670f3..06f15f81c4d8 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -601,7 +601,7 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) { /*remove the wlanhdr and add the eth_hdr*/ sint rmv_len; - u16 eth_type, len; + u16 len; u8 bsnaphdr; u8 *psnap_type; struct ieee80211_snap_hdr *psnap; @@ -635,7 +635,6 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) ptr += rmv_len; *ptr = 0x87; *(ptr+1) = 0x12; - eth_type = 0x8712; /* append rx status for mp test packets */ ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24); @@ -658,27 +657,11 @@ s32 r8712_recv_entry(union recv_frame *precvframe) { struct _adapter *padapter; struct recv_priv *precvpriv; - struct mlme_priv *pmlmepriv; - struct recv_stat *prxstat; - struct dvobj_priv *pdev; - u8 *phead, *pdata, *ptail, *pend; - struct __queue *pfree_recv_queue, *ppending_recv_queue; s32 ret = _SUCCESS; - struct intf_hdl *pintfhdl; padapter = precvframe->u.hdr.adapter; - pintfhdl = &padapter->pio_queue->intf; - pmlmepriv = &padapter->mlmepriv; precvpriv = &(padapter->recvpriv); - pdev = &padapter->dvobjpriv; - pfree_recv_queue = &(precvpriv->free_recv_queue); - ppending_recv_queue = &(precvpriv->recv_pending_queue); - phead = precvframe->u.hdr.rx_head; - pdata = precvframe->u.hdr.rx_data; - ptail = precvframe->u.hdr.rx_tail; - pend = precvframe->u.hdr.rx_end; - prxstat = (struct recv_stat *)phead; padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX); diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index 92ca8997e5bc..77487bb9d3c0 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -170,11 +170,8 @@ static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz) /* used for append sz bytes from ptr to rx_tail, update rx_tail and * return the updated rx_tail to the caller * after putting, rx_tail must be still larger than rx_end. */ - unsigned char *prev_rx_tail; - if (precvframe == NULL) return NULL; - prev_rx_tail = precvframe->u.hdr.rx_tail; precvframe->u.hdr.rx_tail += sz; if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) { precvframe->u.hdr.rx_tail -= sz; diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 8faf22bb7c90..c653ad6854b4 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -578,7 +578,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) u8 ttkey[16]; u8 crc[4]; struct arc4context mycontext; - u32 curfragnum, length, prwskeylen; + u32 curfragnum, length; u8 *pframe, *payload, *iv, *prwskey; union pn48 txpn; @@ -600,7 +600,6 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) &pattrib->ra[0]); if (stainfo != NULL) { prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { iv = pframe + pattrib->hdrlen; @@ -655,7 +654,7 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) u8 ttkey[16]; u8 crc[4]; struct arc4context mycontext; - u32 length, prwskeylen; + u32 length; u8 *pframe, *payload, *iv, *prwskey, idx = 0; union pn48 txpn; struct sta_info *stainfo; @@ -683,7 +682,6 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) return _FAIL; } else prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; GET_TKIP_PN(iv, txpn); pnl = (u16)(txpn.val); pnh = (u32)(txpn.val >> 16); @@ -1154,7 +1152,6 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) { /* exclude ICV */ /* Intermediate Buffers */ sint curfragnum, length; - u32 prwskeylen; u8 *pframe, *prwskey; struct sta_info *stainfo; struct pkt_attrib *pattrib = &((struct xmit_frame *) @@ -1174,7 +1171,6 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) &pattrib->ra[0]); if (stainfo != NULL) { prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { if ((curfragnum + 1) == pattrib->nr_frags) { @@ -1363,7 +1359,6 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) { /* exclude ICV */ /* Intermediate Buffers */ sint length; - u32 prwskeylen; u8 *pframe, *prwskey, *iv, idx; struct sta_info *stainfo; struct rx_pkt_attrib *prxattrib = &((union recv_frame *) @@ -1387,7 +1382,6 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) } else prwskey = &stainfo->x_UncstKey.skey[0]; - prwskeylen = 16; length = ((union recv_frame *)precvframe)-> u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; aes_decipher(prwskey, prxattrib->hdrlen, pframe, diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index e769bb5c5fb8..4c9b98e8210e 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -79,13 +79,11 @@ static void mfree_all_stainfo(struct sta_priv *pstapriv) { unsigned long irqL; struct list_head *plist, *phead; - struct sta_info *psta = NULL; spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = &pstapriv->free_sta_queue.queue; plist = phead->next; while ((end_of_queue_search(phead, plist)) == false) { - psta = LIST_CONTAINOR(plist, struct sta_info, list); plist = plist->next; } @@ -109,7 +107,6 @@ u32 _r8712_free_sta_priv(struct sta_priv *pstapriv) struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { - uint tmp_aid; s32 index; struct list_head *phash_list; struct sta_info *psta; @@ -127,7 +124,6 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) psta = LIST_CONTAINOR(pfree_sta_queue->queue.next, struct sta_info, list); list_del_init(&(psta->list)); - tmp_aid = psta->aid; _init_stainfo(psta); memcpy(psta->hwaddr, hwaddr, ETH_ALEN); index = wifi_mac_hash(hwaddr); @@ -267,15 +263,10 @@ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) void r8712_init_bcmc_stainfo(struct _adapter *padapter) { - struct sta_info *psta; - struct tx_servq *ptxservq; unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct sta_priv *pstapriv = &padapter->stapriv; - psta = r8712_alloc_stainfo(pstapriv, bcast_addr); - if (psta == NULL) - return; - ptxservq = &(psta->sta_xmitpriv.be_q); + r8712_alloc_stainfo(pstapriv, bcast_addr); } struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter) diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 9d26fd26d0d4..62a377e7fdc7 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -184,7 +184,6 @@ void _free_xmit_priv(struct xmit_priv *pxmitpriv) sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib) { - uint i; struct pkt_file pktfile; struct sta_info *psta = NULL; struct ethhdr etherhdr; @@ -199,7 +198,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, _r8712_open_pktfile(pkt, &pktfile); - i = _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); + _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); pattrib->ether_type = ntohs(etherhdr.h_proto); @@ -236,7 +235,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, /* for mp storing the txcmd per packet, * according to the info of txcmd to update pattrib */ /*get MP_TXDESC_SIZE bytes txcmd per packet*/ - i = _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); + _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); memcpy(pattrib->ta, pattrib->src, ETH_ALEN); pattrib->pctrl = 1; @@ -347,7 +346,7 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, static sint xmitframe_addmic(struct _adapter *padapter, struct xmit_frame *pxmitframe) { - u32 curfragnum, length, datalen; + u32 curfragnum, length; u8 *pframe, *payload, mic[8]; struct mic_data micdata; struct sta_info *stainfo; @@ -369,7 +368,6 @@ static sint xmitframe_addmic(struct _adapter *padapter, u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - datalen = pattrib->pktlen - pattrib->hdrlen; pframe = pxmitframe->buf_addr + TXDESC_OFFSET; if (bmcst) { if (!memcmp(psecuritypriv->XGrptxmickey @@ -825,16 +823,13 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, unsigned long irqL; struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; struct _adapter *padapter = pxmitpriv->adapter; - struct sk_buff *pndis_pkt = NULL; if (pxmitframe == NULL) return; spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); list_del_init(&pxmitframe->list); - if (pxmitframe->pkt) { - pndis_pkt = pxmitframe->pkt; + if (pxmitframe->pkt) pxmitframe->pkt = NULL; - } list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue); pxmitpriv->free_xmitframe_cnt++; spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index da3856dda728..7d0d1719b136 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -255,9 +255,6 @@ static struct drv_priv drvpriv = { static uint r8712_usb_dvobj_init(struct _adapter *padapter) { uint status = _SUCCESS; - struct usb_device_descriptor *pdev_desc; - struct usb_host_config *phost_conf; - struct usb_config_descriptor *pconf_desc; struct usb_host_interface *phost_iface; struct usb_interface_descriptor *piface_desc; struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; @@ -265,9 +262,6 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter) pdvobjpriv->padapter = padapter; padapter->EepromAddressSize = 6; - pdev_desc = &pusbd->descriptor; - phost_conf = pusbd->actconfig; - pconf_desc = &phost_conf->desc; phost_iface = &pintf->altsetting[0]; piface_desc = &phost_iface->desc; pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index e0a155a4fac1..c3a4e3f26b40 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -168,7 +168,6 @@ static void usb_write_mem_complete(struct urb *purb) void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) { unsigned int pipe; - int status; struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; struct io_queue *pio_queue = (struct io_queue *)padapter->pio_queue; @@ -186,7 +185,7 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) usb_fill_bulk_urb(piorw_urb, pusbd, pipe, wmem, cnt, usb_write_mem_complete, pio_queue); - status = usb_submit_urb(piorw_urb, GFP_ATOMIC); + usb_submit_urb(piorw_urb, GFP_ATOMIC); _down_sema(&pintfpriv->io_retevt); } diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index 0ac9130faf6c..039b598152bc 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -79,7 +79,6 @@ sint r8712_endofpktfile(struct pkt_file *pfile) void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) { - int i; struct ethhdr etherhdr; struct iphdr ip_hdr; u16 UserPriority = 0; @@ -89,8 +88,7 @@ void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) /* get UserPriority from IP hdr*/ if (pattrib->ether_type == 0x0800) { - i = _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, - sizeof(ip_hdr)); + _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); /*UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/ UserPriority = ip_hdr.tos >> 5; } else { -- GitLab From 92bf93f1260402f17552f91599474bb9ead2a1b2 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 25 Oct 2014 02:01:54 +0530 Subject: [PATCH 1932/9457] staging: gs_fpgaboot: cleanup in gs_fpgaboot_init function the error path is cleanup to return the correct (function call return value) error code. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 0c18c4c311b4..bf2f898d3853 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -344,43 +344,38 @@ static int gs_fpgaboot(void) static int __init gs_fpgaboot_init(void) { - int err, r; - - r = -1; + int err; pr_info("FPGA DOWNLOAD --->\n"); pr_info("FPGA image file name: %s\n", file); err = init_driver(); - if (err != 0) { + if (err) { pr_err("FPGA DRIVER INIT FAIL!!\n"); - return r; + return err; } err = xl_init_io(); if (err) { pr_err("GPIO INIT FAIL!!\n"); - r = -1; goto errout; } err = gs_fpgaboot(); if (err) { pr_err("FPGA DOWNLOAD FAIL!!\n"); - r = -1; goto errout; } pr_info("FPGA DOWNLOAD DONE <---\n"); - r = 0; - return r; + return 0; errout: finish_driver(); - return r; + return err; } static void __exit gs_fpgaboot_exit(void) -- GitLab From a5841ff372c3c79c266ef383e7faee8206f0f757 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 25 Oct 2014 02:01:55 +0530 Subject: [PATCH 1933/9457] staging: gs_fpgpaboot: fix compiler warning with make W=1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the following compiler warning has been fixed: drivers/staging/gs_fpgaboot/gs_fpgaboot.c: In function ‘gs_read_bitstream’: drivers/staging/gs_fpgaboot/gs_fpgaboot.c:160:6: warning: variable ‘size’ set but not used [-Wunused-but-set-variable] CC drivers/staging/gs_fpgaboot/io.o LD drivers/staging/gs_fpgaboot/gs_fpga.o LD drivers/staging/gs_fpgaboot/built-in.o by removing the size variable. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index bf2f898d3853..31caa7464597 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -136,12 +136,10 @@ static void gs_print_header(struct fpgaimage *fimage) static void gs_read_bitstream(struct fpgaimage *fimage) { char *bitdata; - int size; int offset; offset = 0; bitdata = (char *)fimage->fw_entry->data; - size = fimage->fw_entry->size; readmagic_bitstream(bitdata, &offset); readinfo_bitstream(bitdata, fimage->filename, &offset); -- GitLab From 84e9cd6b5c42d021cc0a2dac7d6e49e9d9dfa037 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 25 Oct 2014 02:01:56 +0530 Subject: [PATCH 1934/9457] staging: gs_fpgaboot: fix a compiler warning with make W=2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The below warning is fixed: drivers/staging/gs_fpgaboot/gs_fpgaboot.c: In function ‘gs_load_image’: drivers/staging/gs_fpgaboot/gs_fpgaboot.c:196:58: warning: declaration of ‘file’ shadows a global declaration [-Wshadow] drivers/staging/gs_fpgaboot/gs_fpgaboot.c:45:14: warning: shadowed declaration is here [-Wshadow] by renaming file function argument of gs_load_image with fw_file. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 31caa7464597..6da72858d28c 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -172,15 +172,15 @@ static int gs_read_image(struct fpgaimage *fimage) return 0; } -static int gs_load_image(struct fpgaimage *fimage, char *file) +static int gs_load_image(struct fpgaimage *fimage, char *fw_file) { int err; - pr_info("load fpgaimage %s\n", file); + pr_info("load fpgaimage %s\n", fw_file); - err = request_firmware(&fimage->fw_entry, file, &firmware_pdev->dev); + err = request_firmware(&fimage->fw_entry, fw_file, &firmware_pdev->dev); if (err != 0) { - pr_err("firmware %s is missing, cannot continue.\n", file); + pr_err("firmware %s is missing, cannot continue.\n", fw_file); return err; } -- GitLab From 086241e6d01e627ad40831b76a1bdb9ec7028a51 Mon Sep 17 00:00:00 2001 From: Nicky Chorley Date: Sun, 26 Oct 2014 06:21:04 +0000 Subject: [PATCH 1935/9457] Staging: ft1000: ft1000-pcmcia: Fix whitespace issues This patch fixes the following errors and warnings identified by checkpatch.pl: WARNING: please, no spaces at the start of a line 814: FILE: ft1000_hw.c:814: tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);$ WARNING: please, no spaces at the start of a line 815: FILE: ft1000_hw.c:815: i=0;$ ERROR: spaces required around that '=' (ctx:VxV) 815: FILE: ft1000_hw.c:815: i=0; WARNING: please, no spaces at the start of a line 816: FILE: ft1000_hw.c:816: while (tempword & FT1000_DB_DPRAM_TX) {$ ERROR: code indent should use tabs where possible 817: FILE: ft1000_hw.c:817: mdelay(10);$ WARNING: please, no spaces at the start of a line 817: FILE: ft1000_hw.c:817: mdelay(10);$ ERROR: code indent should use tabs where possible 818: FILE: ft1000_hw.c:818: i++;$ WARNING: please, no spaces at the start of a line 818: FILE: ft1000_hw.c:818: i++;$ ERROR: code indent should use tabs where possible 819: FILE: ft1000_hw.c:819: if (i==10) {$ WARNING: please, no spaces at the start of a line 819: FILE: ft1000_hw.c:819: if (i==10) {$ WARNING: suspect code indent for conditional statements (8, 12) 819: FILE: ft1000_hw.c:819: if (i==10) { spin_unlock_irqrestore(&info->dpram_lock, flags); ERROR: spaces required around that '==' (ctx:VxV) 819: FILE: ft1000_hw.c:819: if (i==10) { ERROR: code indent should use tabs where possible 820: FILE: ft1000_hw.c:820: spin_unlock_irqrestore(&info->dpram_lock, flags);$ WARNING: please, no spaces at the start of a line 820: FILE: ft1000_hw.c:820: spin_unlock_irqrestore(&info->dpram_lock, flags);$ ERROR: code indent should use tabs where possible 821: FILE: ft1000_hw.c:821: return;$ WARNING: please, no spaces at the start of a line 821: FILE: ft1000_hw.c:821: return;$ ERROR: code indent should use tabs where possible 822: FILE: ft1000_hw.c:822: }$ WARNING: please, no spaces at the start of a line 822: FILE: ft1000_hw.c:822: }$ ERROR: code indent should use tabs where possible 823: FILE: ft1000_hw.c:823: tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);$ WARNING: please, no spaces at the start of a line 823: FILE: ft1000_hw.c:823: tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);$ WARNING: please, no spaces at the start of a line 824: FILE: ft1000_hw.c:824: }$ Signed-off-by: Nicky Chorley Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index a9bcb9e1af78..9de308906054 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -810,18 +810,18 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, */ spin_lock_irqsave(&info->dpram_lock, flags); - /* Make sure SLOWQ doorbell is clear */ - tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - i=0; - while (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - i++; - if (i==10) { - spin_unlock_irqrestore(&info->dpram_lock, flags); - return; - } - tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - } + /* Make sure SLOWQ doorbell is clear */ + tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); + i = 0; + while (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + i++; + if (i == 10) { + spin_unlock_irqrestore(&info->dpram_lock, flags); + return; + } + tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); + } if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, -- GitLab From 5689de903e3131b0e501ec9bdb67d1a5bec4392e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Mon, 27 Oct 2014 14:18:12 -0400 Subject: [PATCH 1936/9457] staging: unisys: fix CamelCase in net_adap_info Fix the CamelCase member name in this structure: zoneGuid => zone_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 4 ++-- drivers/staging/unisys/virtpci/virtpci.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 6fa8caf5381e..1616109408a4 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -363,7 +363,7 @@ static int add_vhba(struct add_virt_guestpart *addparams) chanptr)->vnic.num_rcv_bufs); \ net.mtu = readl(&((struct spar_io_channel_protocol __iomem *) \ chanptr)->vnic.mtu); \ - memcpy_fromio(&net.zoneGuid, \ + memcpy_fromio(&net.zone_uuid, \ &((struct spar_io_channel_protocol __iomem *)\ chanptr)->vnic.zone_uuid, \ sizeof(uuid_le)); \ @@ -395,7 +395,7 @@ add_vnic(struct add_virt_guestpart *addparams) LOGINF("Adding vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x rcvbufs:%d mtu:%d chanptr:%p%pUL\n", net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], net.mac_addr[3], net.mac_addr[4], net.mac_addr[5], net.num_rcv_bufs, net.mtu, - addparams->chanptr, &net.zoneGuid); + addparams->chanptr, &net.zone_uuid); i = virtpci_device_add(vbus, VIRTNIC_TYPE, addparams, NULL, &net); if (i) { LOGINF("Added vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index 8a0d43947596..de2182f37914 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -42,7 +42,7 @@ struct net_adap_info { u8 mac_addr[MAX_MACADDR_LEN]; int num_rcv_bufs; unsigned mtu; - uuid_le zoneGuid; + uuid_le zone_uuid; }; typedef enum { -- GitLab From 2a73a82d13bfb742f85f80069cb53ef5202d8a91 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Mon, 27 Oct 2014 14:18:13 -0400 Subject: [PATCH 1937/9457] staging: unisys: get rid of typedef for VIRTPCI_DEV_TYPE Remove the typedef and use enum virtpc_dev_type instead. Update references. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 3 ++- drivers/staging/unisys/virtpci/virtpci.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 1616109408a4..430ad6c83e9a 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -614,7 +614,8 @@ static void delete_all(void) /* deletes all vnics or vhbas * returns 0 failure, 1 success, */ -static int delete_all_virt(VIRTPCI_DEV_TYPE devtype, struct del_vbus_guestpart *delparams) +static int delete_all_virt(enum virtpci_dev_type devtype, + struct del_vbus_guestpart *delparams) { int i; unsigned char busid[BUS_ID_SIZE]; diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index de2182f37914..49025458a1d6 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -45,14 +45,14 @@ struct net_adap_info { uuid_le zone_uuid; }; -typedef enum { +enum virtpci_dev_type { VIRTHBA_TYPE = 0, VIRTNIC_TYPE = 1, VIRTBUS_TYPE = 6, -} VIRTPCI_DEV_TYPE; +}; struct virtpci_dev { - VIRTPCI_DEV_TYPE devtype; /* indicates type of the + enum virtpci_dev_type devtype; /* indicates type of the * virtual pci device */ struct virtpci_driver *mydriver; /* which driver has allocated * this device */ -- GitLab From 55f714cd487900c914a7efdf259a9b0a7cda7900 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Mon, 27 Oct 2014 14:18:14 -0400 Subject: [PATCH 1938/9457] staging: unisys: fix CamelCase members of virtpci_dev Fix CamelCase names in this structure: busNo => bus_no deviceNo => device_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virthba/virthba.c | 28 ++++++++++++------------ drivers/staging/unisys/virtpci/virtpci.c | 15 ++++++++----- drivers/staging/unisys/virtpci/virtpci.h | 4 ++-- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c index ee1be5a83e39..04d3c213205f 100644 --- a/drivers/staging/unisys/virthba/virthba.c +++ b/drivers/staging/unisys/virthba/virthba.c @@ -466,12 +466,12 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id) u64 mask; LOGVER("entering virthba_probe...\n"); - LOGVER("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGVER("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); LOGINF("entering virthba_probe...\n"); - LOGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO); /* call scsi_host_alloc to register a scsi host adapter * instance - this virthba that has just been created is an @@ -649,8 +649,8 @@ virthba_remove(struct virtpci_dev *virtpcidev) struct Scsi_Host *scsihost = (struct Scsi_Host *) virtpcidev->scsi.scsihost; - LOGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); virthbainfo = (struct virthba_info *) scsihost->hostdata; if (virthbainfo->interrupt_vector != -1) free_irq(virthbainfo->interrupt_vector, virthbainfo); @@ -1482,8 +1482,8 @@ virthba_serverup(struct virtpci_dev *virtpcidev) (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi. scsihost)->hostdata; - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); if (!virthbainfo->serverdown) { DBGINF("Server up message received while server is already up.\n"); @@ -1573,13 +1573,13 @@ virthba_serverdown_complete(struct work_struct *work) virtpcidev = virthbainfo->virtpcidev; - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); virthbainfo->serverdown = true; virthbainfo->serverchangingstate = false; /* Return the ServerDown response to Command */ - visorchipset_device_pause_response(virtpcidev->busNo, - virtpcidev->deviceNo, 0); + visorchipset_device_pause_response(virtpcidev->bus_no, + virtpcidev->device_no, 0); } /* As per VirtpciFunc returns 1 for success and 0 for failure */ @@ -1591,8 +1591,8 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state) scsihost)->hostdata; DBGINF("virthba_serverdown"); - DBGINF("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo, - virtpcidev->deviceNo); + DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no, + virtpcidev->device_no); if (!virthbainfo->serverdown && !virthbainfo->serverchangingstate) { virthbainfo->serverchangingstate = true; diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 430ad6c83e9a..52ec69f06b92 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -843,7 +843,7 @@ static int virtpci_device_probe(struct device *dev) */ error = virtpcidrv->probe(virtpcidev, id); if (!error) { - fix_vbus_devInfo(dev, virtpcidev->deviceNo, + fix_vbus_devInfo(dev, virtpcidev->device_no, virtpcidev->device, virtpcidrv); virtpcidev->mydriver = virtpcidrv; POSTCODE_LINUX_2(VPCI_PROBE_EXIT_PC, @@ -940,8 +940,8 @@ static int virtpci_device_add(struct device *parentbus, int devtype, virtpcidev->net = *net; } virtpcidev->vendor = PCI_VENDOR_ID_UNISYS; - virtpcidev->busNo = addparams->bus_no; - virtpcidev->deviceNo = addparams->device_no; + virtpcidev->bus_no = addparams->bus_no; + virtpcidev->device_no = addparams->device_no; virtpcidev->queueinfo.chan = addparams->chanptr; virtpcidev->queueinfo.send_int_if_needed = NULL; @@ -1173,7 +1173,8 @@ static int virtpci_device_serverup(struct device *parentbus, * ever have a bus that contains NO devices, since we * would never even get here in that case. */ - fix_vbus_devInfo(&tmpvpcidev->generic_dev, tmpvpcidev->deviceNo, + fix_vbus_devInfo(&tmpvpcidev->generic_dev, + tmpvpcidev->device_no, tmpvpcidev->device, vpcidriver); rc = vpcidriver->resume(tmpvpcidev); } @@ -1458,7 +1459,8 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, if (tmpvpcidev->devtype == VIRTHBA_TYPE) { str_pos += scnprintf(vbuf + str_pos, len - str_pos, "[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d", - tmpvpcidev->busNo, tmpvpcidev->deviceNo, + tmpvpcidev->bus_no, + tmpvpcidev->device_no, tmpvpcidev->scsi.wwnn.wwnn1, tmpvpcidev->scsi.wwnn.wwnn2, tmpvpcidev->scsi.max.max_channel, @@ -1468,7 +1470,8 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, } else { str_pos += scnprintf(vbuf + str_pos, len - str_pos, "[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d", - tmpvpcidev->busNo, tmpvpcidev->deviceNo, + tmpvpcidev->bus_no, + tmpvpcidev->device_no, tmpvpcidev->net.mac_addr[0], tmpvpcidev->net.mac_addr[1], tmpvpcidev->net.mac_addr[2], diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index 49025458a1d6..42a98de47e1d 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -58,8 +58,8 @@ struct virtpci_dev { * this device */ unsigned short vendor; /* vendor id for device */ unsigned short device; /* device id for device */ - u32 busNo; /* number of bus on which device exists */ - u32 deviceNo; /* device's number on the bus */ + u32 bus_no; /* number of bus on which device exists */ + u32 device_no; /* device's number on the bus */ struct irq_info intr; /* interrupt info */ struct device generic_dev; /* generic device */ union { -- GitLab From 61b27ac8372f30aacb317e48834ef2c5cfeffe5a Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Mon, 27 Oct 2014 14:18:15 -0400 Subject: [PATCH 1939/9457] staging: unisys: fix alignment in virtpci.h Clean up misaligned indentation in virtpci.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h index 42a98de47e1d..9d85f55e8169 100644 --- a/drivers/staging/unisys/virtpci/virtpci.h +++ b/drivers/staging/unisys/virtpci/virtpci.h @@ -80,15 +80,15 @@ struct virtpci_driver { const struct pci_device_id *id_table; /* must be non-NULL for probe * to be called */ int (*probe)(struct virtpci_dev *dev, - const struct pci_device_id *id); /* device inserted */ + const struct pci_device_id *id); /* device inserted */ void (*remove)(struct virtpci_dev *dev); /* Device removed (NULL if * not a hot-plug capable * driver) */ int (*suspend)(struct virtpci_dev *dev, - u32 state); /* Device suspended */ + u32 state); /* Device suspended */ int (*resume)(struct virtpci_dev *dev); /* Device woken up */ int (*enable_wake)(struct virtpci_dev *dev, - u32 state, int enable); /* Enable wake event */ + u32 state, int enable); /* Enable wake event */ struct device_driver core_driver; /* VIRTPCI core fills this in */ }; -- GitLab From 2aef999ba0e6dc9e253e547c0b32f6658aa1393d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 28 Oct 2014 09:36:28 -0400 Subject: [PATCH 1940/9457] staging: unisys: fix macro spacing in uisutils.h Add some space between the macros in uisutils.h for readability. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index 20758ae2bf26..7414220676d3 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -179,11 +179,14 @@ struct chaninfo { set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(msecs_to_jiffies(x)); \ } + #define UIS_THREAD_WAIT_USEC(x) { \ set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(usecs_to_jiffies(x)); \ } + #define UIS_THREAD_WAIT UIS_THREAD_WAIT_MSEC(5) + #define UIS_THREAD_WAIT_SEC(x) { \ set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout((x)*HZ); \ -- GitLab From c241c5eea822344639898512780cff823fc7d730 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:23 -0400 Subject: [PATCH 1941/9457] HID: fix merge from wacom into the HID tree While merging wacom from the input to the hid tree, some comments have been duplicated. We can also integrate the test for Synaptics devices in the switch case below, so it is clear that there will be only one place for such quirks. No functional changes are expected in this commit. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 17 +++++++---------- include/linux/hid.h | 4 ---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 73bd9e2e42bc..aef7c56ca5e7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -779,16 +779,6 @@ static int hid_scan_report(struct hid_device *hid) (hid->group == HID_GROUP_MULTITOUCH)) hid->group = HID_GROUP_MULTITOUCH_WIN_8; - /* - * Vendor specific handlings - */ - if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) && - (hid->group == HID_GROUP_GENERIC) && - /* only bind to the mouse interface of composite USB devices */ - (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) - /* hid-rmi should take care of them, not hid-generic */ - hid->group = HID_GROUP_RMI; - /* * Vendor specific handlings */ @@ -796,6 +786,13 @@ static int hid_scan_report(struct hid_device *hid) case USB_VENDOR_ID_WACOM: hid->group = HID_GROUP_WACOM; break; + case USB_VENDOR_ID_SYNAPTICS: + if ((hid->group == HID_GROUP_GENERIC) && + (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE)) + /* hid-rmi should only bind to the mouse interface of + * composite USB devices */ + hid->group = HID_GROUP_RMI; + break; } vfree(parser); diff --git a/include/linux/hid.h b/include/linux/hid.h index 78ea9bf941cd..5b1ff6110e25 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -312,10 +312,6 @@ struct hid_item { * Vendor specific HID device groups */ #define HID_GROUP_RMI 0x0100 - -/* - * Vendor specific HID device groups - */ #define HID_GROUP_WACOM 0x0101 /* -- GitLab From 9578f41aeaee5010384f4f8484da1566e2ce4901 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:24 -0400 Subject: [PATCH 1942/9457] HID: core: do not scan reports if the group is already set This allows the transport layer (I have in mind hid-logitech-dj and uhid) to set the group before it is added to the hid bus. This way, it can bypass the hid_scan_report() call, and choose in advance which driver will handle the newly created hid device. Signed-off-by: Benjamin Tisssoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index aef7c56ca5e7..946540e1764d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2535,7 +2535,8 @@ int hid_add_device(struct hid_device *hdev) * Scan generic devices for group information */ if (hid_ignore_special_drivers || - !hid_match_id(hdev, hid_have_special_driver)) { + (!hdev->group && + !hid_match_id(hdev, hid_have_special_driver))) { ret = hid_scan_report(hdev); if (ret) hid_warn(hdev, "bad device descriptor (%d)\n", ret); -- GitLab From d610274b0301e5ef35811fa736036d022f707564 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:25 -0400 Subject: [PATCH 1943/9457] HID: logitech-dj: rely on hid groups to separate receivers from dj devices Several benefits here: - we can drop the macro is_dj_device: I never been really conviced by this macro as we could fall into a null pointer anytime. Anyway time showed that this never happened. - we can simplify the hid driver logitech-djdevice, and make it aware of any new receiver VID/PID. - we can use the Wireless PID of the DJ device as the product id of the hid device, this way the sysfs will differentiate between different DJ devices. Signed-off-by: Benjamin Tisssoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 38 +++++++++-------------------------- drivers/hid/hid-logitech-dj.h | 10 --------- include/linux/hid.h | 1 + 3 files changed, 11 insertions(+), 38 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 71f569292cab..42d38d50afdf 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -256,11 +256,15 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, dj_hiddev->dev.parent = &djrcv_hdev->dev; dj_hiddev->bus = BUS_USB; dj_hiddev->vendor = le16_to_cpu(usbdev->descriptor.idVendor); - dj_hiddev->product = le16_to_cpu(usbdev->descriptor.idProduct); + dj_hiddev->product = + (dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB] + << 8) | + dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB]; snprintf(dj_hiddev->name, sizeof(dj_hiddev->name), - "Logitech Unifying Device. Wireless PID:%02x%02x", - dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_MSB], - dj_report->report_params[DEVICE_PAIRED_PARAM_EQUAD_ID_LSB]); + "Logitech Unifying Device. Wireless PID:%04x", + dj_hiddev->product); + + dj_hiddev->group = HID_GROUP_LOGITECH_DJ_DEVICE; usb_make_path(usbdev, dj_hiddev->phys, sizeof(dj_hiddev->phys)); snprintf(tmpstr, sizeof(tmpstr), ":%d", dj_report->device_index); @@ -714,9 +718,6 @@ static int logi_dj_probe(struct hid_device *hdev, struct dj_receiver_dev *djrcv_dev; int retval; - if (is_dj_device((struct dj_device *)hdev->driver_data)) - return -ENODEV; - dbg_hid("%s called for ifnum %d\n", __func__, intf->cur_altsetting->desc.bInterfaceNumber); @@ -869,22 +870,6 @@ static void logi_dj_remove(struct hid_device *hdev) hid_set_drvdata(hdev, NULL); } -static int logi_djdevice_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - struct dj_device *dj_dev = hdev->driver_data; - - if (!is_dj_device(dj_dev)) - return -ENODEV; - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - return ret; -} - static const struct hid_device_id logi_dj_receivers[] = { {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)}, @@ -908,17 +893,14 @@ static struct hid_driver logi_djreceiver_driver = { static const struct hid_device_id logi_dj_devices[] = { - {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, - USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER)}, - {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, - USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2)}, + { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, + USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, {} }; static struct hid_driver logi_djdevice_driver = { .name = "logitech-djdevice", .id_table = logi_dj_devices, - .probe = logi_djdevice_probe, }; diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h index daeb0aa4bee9..b1208c9c0573 100644 --- a/drivers/hid/hid-logitech-dj.h +++ b/drivers/hid/hid-logitech-dj.h @@ -112,14 +112,4 @@ struct dj_device { u8 device_index; }; -/** - * is_dj_device - know if the given dj_device is not the receiver. - * @dj_dev: the dj device to test - * - * This macro tests if a struct dj_device pointer is a device created - * by the bus enumarator. - */ -#define is_dj_device(dj_dev) \ - (&(dj_dev)->dj_receiver_dev->hdev->dev == (dj_dev)->hdev->dev.parent) - #endif diff --git a/include/linux/hid.h b/include/linux/hid.h index 5b1ff6110e25..7d6e0556302a 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -313,6 +313,7 @@ struct hid_item { */ #define HID_GROUP_RMI 0x0100 #define HID_GROUP_WACOM 0x0101 +#define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102 /* * This is the global environment of the parser. This information is -- GitLab From 8cb3746a6ee28c7b4d061689e13b8e5be80b14cc Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:26 -0400 Subject: [PATCH 1944/9457] HID: logitech-dj: merge header file into the source There is no point in keeping the header in a separate file, nobody but hid-logitech-dj should have access to its content. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 88 +++++++++++++++++++++++++- drivers/hid/hid-logitech-dj.h | 115 ---------------------------------- 2 files changed, 87 insertions(+), 116 deletions(-) delete mode 100644 drivers/hid/hid-logitech-dj.h diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 42d38d50afdf..6aea16dca3ff 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -26,9 +26,95 @@ #include #include #include +#include #include #include "hid-ids.h" -#include "hid-logitech-dj.h" + +#define DJ_MAX_PAIRED_DEVICES 6 +#define DJ_MAX_NUMBER_NOTIFICATIONS 8 +#define DJ_RECEIVER_INDEX 0 +#define DJ_DEVICE_INDEX_MIN 1 +#define DJ_DEVICE_INDEX_MAX 6 + +#define DJREPORT_SHORT_LENGTH 15 +#define DJREPORT_LONG_LENGTH 32 + +#define REPORT_ID_DJ_SHORT 0x20 +#define REPORT_ID_DJ_LONG 0x21 + +#define REPORT_TYPE_RFREPORT_LAST 0x1F + +/* Command Switch to DJ mode */ +#define REPORT_TYPE_CMD_SWITCH 0x80 +#define CMD_SWITCH_PARAM_DEVBITFIELD 0x00 +#define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01 +#define TIMEOUT_NO_KEEPALIVE 0x00 + +/* Command to Get the list of Paired devices */ +#define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81 + +/* Device Paired Notification */ +#define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x41 +#define SPFUNCTION_MORE_NOTIF_EXPECTED 0x01 +#define SPFUNCTION_DEVICE_LIST_EMPTY 0x02 +#define DEVICE_PAIRED_PARAM_SPFUNCTION 0x00 +#define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x01 +#define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x02 +#define DEVICE_PAIRED_RF_REPORT_TYPE 0x03 + +/* Device Un-Paired Notification */ +#define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40 + + +/* Connection Status Notification */ +#define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42 +#define CONNECTION_STATUS_PARAM_STATUS 0x00 +#define STATUS_LINKLOSS 0x01 + +/* Error Notification */ +#define REPORT_TYPE_NOTIF_ERROR 0x7F +#define NOTIF_ERROR_PARAM_ETYPE 0x00 +#define ETYPE_KEEPALIVE_TIMEOUT 0x01 + +/* supported DJ HID && RF report types */ +#define REPORT_TYPE_KEYBOARD 0x01 +#define REPORT_TYPE_MOUSE 0x02 +#define REPORT_TYPE_CONSUMER_CONTROL 0x03 +#define REPORT_TYPE_SYSTEM_CONTROL 0x04 +#define REPORT_TYPE_MEDIA_CENTER 0x08 +#define REPORT_TYPE_LEDS 0x0E + +/* RF Report types bitfield */ +#define STD_KEYBOARD 0x00000002 +#define STD_MOUSE 0x00000004 +#define MULTIMEDIA 0x00000008 +#define POWER_KEYS 0x00000010 +#define MEDIA_CENTER 0x00000100 +#define KBD_LEDS 0x00004000 + +struct dj_report { + u8 report_id; + u8 device_index; + u8 report_type; + u8 report_params[DJREPORT_SHORT_LENGTH - 3]; +}; + +struct dj_receiver_dev { + struct hid_device *hdev; + struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES + + DJ_DEVICE_INDEX_MIN]; + struct work_struct work; + struct kfifo notif_fifo; + spinlock_t lock; + bool querying_devices; +}; + +struct dj_device { + struct hid_device *hdev; + struct dj_receiver_dev *dj_receiver_dev; + u32 reports_supported; + u8 device_index; +}; /* Keyboard descriptor (1) */ static const char kbd_descriptor[] = { diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h deleted file mode 100644 index b1208c9c0573..000000000000 --- a/drivers/hid/hid-logitech-dj.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef __HID_LOGITECH_DJ_H -#define __HID_LOGITECH_DJ_H - -/* - * HID driver for Logitech Unifying receivers - * - * Copyright (c) 2011 Logitech - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include - -#define DJ_MAX_PAIRED_DEVICES 6 -#define DJ_MAX_NUMBER_NOTIFICATIONS 8 -#define DJ_RECEIVER_INDEX 0 -#define DJ_DEVICE_INDEX_MIN 1 -#define DJ_DEVICE_INDEX_MAX 6 - -#define DJREPORT_SHORT_LENGTH 15 -#define DJREPORT_LONG_LENGTH 32 - -#define REPORT_ID_DJ_SHORT 0x20 -#define REPORT_ID_DJ_LONG 0x21 - -#define REPORT_TYPE_RFREPORT_FIRST 0x01 -#define REPORT_TYPE_RFREPORT_LAST 0x1F - -/* Command Switch to DJ mode */ -#define REPORT_TYPE_CMD_SWITCH 0x80 -#define CMD_SWITCH_PARAM_DEVBITFIELD 0x00 -#define CMD_SWITCH_PARAM_TIMEOUT_SECONDS 0x01 -#define TIMEOUT_NO_KEEPALIVE 0x00 - -/* Command to Get the list of Paired devices */ -#define REPORT_TYPE_CMD_GET_PAIRED_DEVICES 0x81 - -/* Device Paired Notification */ -#define REPORT_TYPE_NOTIF_DEVICE_PAIRED 0x41 -#define SPFUNCTION_MORE_NOTIF_EXPECTED 0x01 -#define SPFUNCTION_DEVICE_LIST_EMPTY 0x02 -#define DEVICE_PAIRED_PARAM_SPFUNCTION 0x00 -#define DEVICE_PAIRED_PARAM_EQUAD_ID_LSB 0x01 -#define DEVICE_PAIRED_PARAM_EQUAD_ID_MSB 0x02 -#define DEVICE_PAIRED_RF_REPORT_TYPE 0x03 - -/* Device Un-Paired Notification */ -#define REPORT_TYPE_NOTIF_DEVICE_UNPAIRED 0x40 - - -/* Connection Status Notification */ -#define REPORT_TYPE_NOTIF_CONNECTION_STATUS 0x42 -#define CONNECTION_STATUS_PARAM_STATUS 0x00 -#define STATUS_LINKLOSS 0x01 - -/* Error Notification */ -#define REPORT_TYPE_NOTIF_ERROR 0x7F -#define NOTIF_ERROR_PARAM_ETYPE 0x00 -#define ETYPE_KEEPALIVE_TIMEOUT 0x01 - -/* supported DJ HID && RF report types */ -#define REPORT_TYPE_KEYBOARD 0x01 -#define REPORT_TYPE_MOUSE 0x02 -#define REPORT_TYPE_CONSUMER_CONTROL 0x03 -#define REPORT_TYPE_SYSTEM_CONTROL 0x04 -#define REPORT_TYPE_MEDIA_CENTER 0x08 -#define REPORT_TYPE_LEDS 0x0E - -/* RF Report types bitfield */ -#define STD_KEYBOARD 0x00000002 -#define STD_MOUSE 0x00000004 -#define MULTIMEDIA 0x00000008 -#define POWER_KEYS 0x00000010 -#define MEDIA_CENTER 0x00000100 -#define KBD_LEDS 0x00004000 - -struct dj_report { - u8 report_id; - u8 device_index; - u8 report_type; - u8 report_params[DJREPORT_SHORT_LENGTH - 3]; -}; - -struct dj_receiver_dev { - struct hid_device *hdev; - struct dj_device *paired_dj_devices[DJ_MAX_PAIRED_DEVICES + - DJ_DEVICE_INDEX_MIN]; - struct work_struct work; - struct kfifo notif_fifo; - spinlock_t lock; - bool querying_devices; -}; - -struct dj_device { - struct hid_device *hdev; - struct dj_receiver_dev *dj_receiver_dev; - u32 reports_supported; - u8 device_index; -}; - -#endif -- GitLab From 2f31c52529103d8f0e1485272064f982d14ce54a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:27 -0400 Subject: [PATCH 1945/9457] HID: Introduce hidpp, a module to handle Logitech hid++ devices Logitech devices use a vendor protocol to communicate various information with the device. This protocol is called HID++, and an exerpt can be found here: https://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28&usp=shar The main difficulty which is related to this protocol is that it is a synchronous protocol using the input reports. So when we want to get some information from the device, we need to wait for a matching input report. This driver introduce this capabilities to be able to support the multitouch mode of the Logitech Wireless Touchpad T651 (the bluetooth one). The multitouch data is available directly from the mouse input reports, and we just need to query the device on connect about its caracteristics. HID++ and the touchpad features has a specific reporting mode which uses pure HID++ reports, but Logitech told us not to use it for this specific device. During QA, they detected that some bluetooth input reports where lost, and so the only supported mode is the pointer mode. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 11 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-logitech-hidpp.c | 842 +++++++++++++++++++++++++++++++ 5 files changed, 856 insertions(+) create mode 100644 drivers/hid/hid-logitech-hidpp.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index f42df4dd58d2..6f299cd54e6d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -378,6 +378,17 @@ config HID_LOGITECH_DJ generic USB_HID driver and all incoming events will be multiplexed into a single mouse and a single keyboard device. +config HID_LOGITECH_HIDPP + tristate "Logitech HID++ devices support" + depends on HID_LOGITECH + ---help--- + Support for Logitech devices relyingon the HID++ Logitech specification + + Say Y if you want support for Logitech devices relying on the HID++ + specification. Such devices are the various Logitech Touchpads (T650, + T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar + Keayboard). + config LOGITECH_FF bool "Logitech force feedback support" depends on HID_LOGITECH diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index e2850d8af9ca..b102774b4e16 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o +obj-$(CONFIG_HID_LOGITECH_HIDPP) += hid-logitech-hidpp.o obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 946540e1764d..395549fea44c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1818,6 +1818,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cd9c9e96cf0e..2aa5091ecc08 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -575,6 +575,7 @@ #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e +#define USB_DEVICE_ID_LOGITECH_T651 0xb00c #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c new file mode 100644 index 000000000000..7dd9163f7e03 --- /dev/null +++ b/drivers/hid/hid-logitech-hidpp.c @@ -0,0 +1,842 @@ +/* + * HIDPP protocol for Logitech Unifying receivers + * + * Copyright (c) 2011 Logitech (c) + * Copyright (c) 2012-2013 Google (c) + * Copyright (c) 2013-2014 Red Hat Inc. + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hid-ids.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Benjamin Tissoires "); +MODULE_AUTHOR("Nestor Lopez Casado "); + +#define REPORT_ID_HIDPP_SHORT 0x10 +#define REPORT_ID_HIDPP_LONG 0x11 + +#define HIDPP_REPORT_SHORT_LENGTH 7 +#define HIDPP_REPORT_LONG_LENGTH 20 + +#define HIDPP_QUIRK_CLASS_WTP BIT(0) + +/* + * There are two hidpp protocols in use, the first version hidpp10 is known + * as register access protocol or RAP, the second version hidpp20 is known as + * feature access protocol or FAP + * + * Most older devices (including the Unifying usb receiver) use the RAP protocol + * where as most newer devices use the FAP protocol. Both protocols are + * compatible with the underlying transport, which could be usb, Unifiying, or + * bluetooth. The message lengths are defined by the hid vendor specific report + * descriptor for the HIDPP_SHORT report type (total message lenth 7 bytes) and + * the HIDPP_LONG report type (total message length 20 bytes) + * + * The RAP protocol uses both report types, whereas the FAP only uses HIDPP_LONG + * messages. The Unifying receiver itself responds to RAP messages (device index + * is 0xFF for the receiver), and all messages (short or long) with a device + * index between 1 and 6 are passed untouched to the corresponding paired + * Unifying device. + * + * The paired device can be RAP or FAP, it will receive the message untouched + * from the Unifiying receiver. + */ + +struct fap { + u8 feature_index; + u8 funcindex_clientid; + u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; +}; + +struct rap { + u8 sub_id; + u8 reg_address; + u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; +}; + +struct hidpp_report { + u8 report_id; + u8 device_index; + union { + struct fap fap; + struct rap rap; + u8 rawbytes[sizeof(struct fap)]; + }; +} __packed; + +struct hidpp_device { + struct hid_device *hid_dev; + struct mutex send_mutex; + void *send_receive_buf; + wait_queue_head_t wait; + bool answer_available; + u8 protocol_major; + u8 protocol_minor; + + void *private_data; + + unsigned long quirks; +}; + + +#define HIDPP_ERROR 0x8f +#define HIDPP_ERROR_SUCCESS 0x00 +#define HIDPP_ERROR_INVALID_SUBID 0x01 +#define HIDPP_ERROR_INVALID_ADRESS 0x02 +#define HIDPP_ERROR_INVALID_VALUE 0x03 +#define HIDPP_ERROR_CONNECT_FAIL 0x04 +#define HIDPP_ERROR_TOO_MANY_DEVICES 0x05 +#define HIDPP_ERROR_ALREADY_EXISTS 0x06 +#define HIDPP_ERROR_BUSY 0x07 +#define HIDPP_ERROR_UNKNOWN_DEVICE 0x08 +#define HIDPP_ERROR_RESOURCE_ERROR 0x09 +#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a +#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b +#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c + +static int __hidpp_send_report(struct hid_device *hdev, + struct hidpp_report *hidpp_report) +{ + int fields_count, ret; + + switch (hidpp_report->report_id) { + case REPORT_ID_HIDPP_SHORT: + fields_count = HIDPP_REPORT_SHORT_LENGTH; + break; + case REPORT_ID_HIDPP_LONG: + fields_count = HIDPP_REPORT_LONG_LENGTH; + break; + default: + return -ENODEV; + } + + /* + * set the device_index as the receiver, it will be overwritten by + * hid_hw_request if needed + */ + hidpp_report->device_index = 0xff; + + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + + return ret == fields_count ? 0 : -1; +} + +static int hidpp_send_message_sync(struct hidpp_device *hidpp, + struct hidpp_report *message, + struct hidpp_report *response) +{ + int ret; + + mutex_lock(&hidpp->send_mutex); + + hidpp->send_receive_buf = response; + hidpp->answer_available = false; + + /* + * So that we can later validate the answer when it arrives + * in hidpp_raw_event + */ + *response = *message; + + ret = __hidpp_send_report(hidpp->hid_dev, message); + + if (ret) { + dbg_hid("__hidpp_send_report returned err: %d\n", ret); + memset(response, 0, sizeof(struct hidpp_report)); + goto exit; + } + + if (!wait_event_timeout(hidpp->wait, hidpp->answer_available, + 5*HZ)) { + dbg_hid("%s:timeout waiting for response\n", __func__); + memset(response, 0, sizeof(struct hidpp_report)); + ret = -ETIMEDOUT; + } + + if (response->report_id == REPORT_ID_HIDPP_SHORT && + response->fap.feature_index == HIDPP_ERROR) { + ret = response->fap.params[1]; + dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret); + goto exit; + } + +exit: + mutex_unlock(&hidpp->send_mutex); + return ret; + +} + +static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, + u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count, + struct hidpp_report *response) +{ + struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report), + GFP_KERNEL); + int ret; + + if (param_count > sizeof(message->fap.params)) + return -EINVAL; + + message->report_id = REPORT_ID_HIDPP_LONG; + message->fap.feature_index = feat_index; + message->fap.funcindex_clientid = funcindex_clientid; + memcpy(&message->fap.params, params, param_count); + + ret = hidpp_send_message_sync(hidpp, message, response); + kfree(message); + return ret; +} + +static inline bool hidpp_match_answer(struct hidpp_report *question, + struct hidpp_report *answer) +{ + return (answer->fap.feature_index == question->fap.feature_index) && + (answer->fap.funcindex_clientid == question->fap.funcindex_clientid); +} + +static inline bool hidpp_match_error(struct hidpp_report *question, + struct hidpp_report *answer) +{ + return (answer->fap.feature_index == HIDPP_ERROR) && + (answer->fap.funcindex_clientid == question->fap.feature_index) && + (answer->fap.params[0] == question->fap.funcindex_clientid); +} + +/* -------------------------------------------------------------------------- */ +/* 0x0000: Root */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_ROOT 0x0000 +#define HIDPP_PAGE_ROOT_IDX 0x00 + +#define CMD_ROOT_GET_FEATURE 0x01 +#define CMD_ROOT_GET_PROTOCOL_VERSION 0x11 + +static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature, + u8 *feature_index, u8 *feature_type) +{ + struct hidpp_report response; + int ret; + u8 params[2] = { feature >> 8, feature & 0x00FF }; + + ret = hidpp_send_fap_command_sync(hidpp, + HIDPP_PAGE_ROOT_IDX, + CMD_ROOT_GET_FEATURE, + params, 2, &response); + if (ret) + return ret; + + *feature_index = response.fap.params[0]; + *feature_type = response.fap.params[1]; + + return ret; +} + +static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) +{ + struct hidpp_report response; + int ret; + + ret = hidpp_send_fap_command_sync(hidpp, + HIDPP_PAGE_ROOT_IDX, + CMD_ROOT_GET_PROTOCOL_VERSION, + NULL, 0, &response); + + if (ret == 1) { + hidpp->protocol_major = 1; + hidpp->protocol_minor = 0; + return 0; + } + + if (ret) + return -ret; + + hidpp->protocol_major = response.fap.params[0]; + hidpp->protocol_minor = response.fap.params[1]; + + return ret; +} + +static bool hidpp_is_connected(struct hidpp_device *hidpp) +{ + int ret; + + ret = hidpp_root_get_protocol_version(hidpp); + if (!ret) + hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n", + hidpp->protocol_major, hidpp->protocol_minor); + return ret == 0; +} + +/* -------------------------------------------------------------------------- */ +/* 0x0005: GetDeviceNameType */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005 + +#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01 +#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11 +#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21 + +static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp, + u8 feature_index, u8 *nameLength) +{ + struct hidpp_report response; + int ret; + + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response); + + if (ret) + return -ret; + + *nameLength = response.fap.params[0]; + + return ret; +} + +static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, + u8 feature_index, u8 char_index, char *device_name, int len_buf) +{ + struct hidpp_report response; + int ret, i; + int count; + + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1, + &response); + + if (ret) + return -ret; + + if (response.report_id == REPORT_ID_HIDPP_LONG) + count = HIDPP_REPORT_LONG_LENGTH - 4; + else + count = HIDPP_REPORT_SHORT_LENGTH - 4; + + if (len_buf < count) + count = len_buf; + + for (i = 0; i < count; i++) + device_name[i] = response.fap.params[i]; + + return count; +} + +static char *hidpp_get_device_name(struct hidpp_device *hidpp, u8 *name_length) +{ + u8 feature_type; + u8 feature_index; + u8 __name_length; + char *name; + unsigned index = 0; + int ret; + + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_GET_DEVICE_NAME_TYPE, + &feature_index, &feature_type); + if (ret) + goto out_err; + + ret = hidpp_devicenametype_get_count(hidpp, feature_index, + &__name_length); + if (ret) + goto out_err; + + name = kzalloc(__name_length + 1, GFP_KERNEL); + if (!name) + goto out_err; + + *name_length = __name_length + 1; + while (index < __name_length) + index += hidpp_devicenametype_get_device_name(hidpp, + feature_index, index, name + index, + __name_length - index); + + return name; + +out_err: + *name_length = 0; + return NULL; +} + +/* -------------------------------------------------------------------------- */ +/* 0x6100: TouchPadRawXY */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100 + +#define CMD_TOUCHPAD_GET_RAW_INFO 0x01 + +#define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01 +#define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03 + +struct hidpp_touchpad_raw_info { + u16 x_size; + u16 y_size; + u8 z_range; + u8 area_range; + u8 timestamp_unit; + u8 maxcontacts; + u8 origin; + u16 res; +}; + +struct hidpp_touchpad_raw_xy_finger { + u8 contact_type; + u8 contact_status; + u16 x; + u16 y; + u8 z; + u8 area; + u8 finger_id; +}; + +struct hidpp_touchpad_raw_xy { + u16 timestamp; + struct hidpp_touchpad_raw_xy_finger fingers[2]; + u8 spurious_flag; + u8 end_of_frame; + u8 finger_count; + u8 button; +}; + +static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp, + u8 feature_index, struct hidpp_touchpad_raw_info *raw_info) +{ + struct hidpp_report response; + int ret; + u8 *params = (u8 *)response.fap.params; + + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response); + + if (ret) + return -ret; + + raw_info->x_size = get_unaligned_be16(¶ms[0]); + raw_info->y_size = get_unaligned_be16(¶ms[2]); + raw_info->z_range = params[4]; + raw_info->area_range = params[5]; + raw_info->maxcontacts = params[7]; + raw_info->origin = params[8]; + /* res is given in unit per inch */ + raw_info->res = get_unaligned_be16(¶ms[13]) * 2 / 51; + + return ret; +} + +/* ************************************************************************** */ +/* */ +/* Device Support */ +/* */ +/* ************************************************************************** */ + +/* -------------------------------------------------------------------------- */ +/* Touchpad HID++ devices */ +/* -------------------------------------------------------------------------- */ + +struct wtp_data { + struct input_dev *input; + u16 x_size, y_size; + u8 finger_count; + u8 mt_feature_index; + u8 button_feature_index; + u8 maxcontacts; + bool flip_y; + unsigned int resolution; +}; + +static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + return -1; +} + +static void wtp_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct wtp_data *wd = hidpp->private_data; + struct input_dev *input_dev = hidinput->input; + + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(EV_KEY, input_dev->evbit); + __clear_bit(EV_REL, input_dev->evbit); + __clear_bit(EV_LED, input_dev->evbit); + + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0); + input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0); + input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution); + + /* Max pressure is not given by the devices, pick one */ + input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 50, 0, 0); + + input_set_capability(input_dev, EV_KEY, BTN_LEFT); + + __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); + + input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER | + INPUT_MT_DROP_UNUSED); + + wd->input = input_dev; +} + +static void wtp_touch_event(struct wtp_data *wd, + struct hidpp_touchpad_raw_xy_finger *touch_report) +{ + int slot; + + if (!touch_report->finger_id || touch_report->contact_type) + /* no actual data */ + return; + + slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id); + + input_mt_slot(wd->input, slot); + input_mt_report_slot_state(wd->input, MT_TOOL_FINGER, + touch_report->contact_status); + if (touch_report->contact_status) { + input_event(wd->input, EV_ABS, ABS_MT_POSITION_X, + touch_report->x); + input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y, + wd->flip_y ? wd->y_size - touch_report->y : + touch_report->y); + input_event(wd->input, EV_ABS, ABS_MT_PRESSURE, + touch_report->area); + } +} + +static void wtp_send_raw_xy_event(struct hidpp_device *hidpp, + struct hidpp_touchpad_raw_xy *raw) +{ + struct wtp_data *wd = hidpp->private_data; + int i; + + for (i = 0; i < 2; i++) + wtp_touch_event(wd, &(raw->fingers[i])); + + if (raw->end_of_frame) + input_event(wd->input, EV_KEY, BTN_LEFT, raw->button); + + if (raw->end_of_frame || raw->finger_count <= 2) { + input_mt_sync_frame(wd->input); + input_sync(wd->input); + } +} + +static int wtp_mouse_raw_xy_event(struct hidpp_device *hidpp, u8 *data) +{ + struct wtp_data *wd = hidpp->private_data; + u8 c1_area = ((data[7] & 0xf) * (data[7] & 0xf) + + (data[7] >> 4) * (data[7] >> 4)) / 2; + u8 c2_area = ((data[13] & 0xf) * (data[13] & 0xf) + + (data[13] >> 4) * (data[13] >> 4)) / 2; + struct hidpp_touchpad_raw_xy raw = { + .timestamp = data[1], + .fingers = { + { + .contact_type = 0, + .contact_status = !!data[7], + .x = get_unaligned_le16(&data[3]), + .y = get_unaligned_le16(&data[5]), + .z = c1_area, + .area = c1_area, + .finger_id = data[2], + }, { + .contact_type = 0, + .contact_status = !!data[13], + .x = get_unaligned_le16(&data[9]), + .y = get_unaligned_le16(&data[11]), + .z = c2_area, + .area = c2_area, + .finger_id = data[8], + } + }, + .finger_count = wd->maxcontacts, + .spurious_flag = 0, + .end_of_frame = (data[0] >> 7) == 0, + .button = data[0] & 0x01, + }; + + wtp_send_raw_xy_event(hidpp, &raw); + + return 1; +} + +static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct wtp_data *wd = hidpp->private_data; + + if (!wd || !wd->input || (data[0] != 0x02) || size < 21) + return 1; + + return wtp_mouse_raw_xy_event(hidpp, &data[7]); +} + +static int wtp_get_config(struct hidpp_device *hidpp) +{ + struct wtp_data *wd = hidpp->private_data; + struct hidpp_touchpad_raw_info raw_info = {0}; + u8 feature_type; + int ret; + + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_TOUCHPAD_RAW_XY, + &wd->mt_feature_index, &feature_type); + if (ret) + /* means that the device is not powered up */ + return ret; + + ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index, + &raw_info); + if (ret) + return ret; + + wd->x_size = raw_info.x_size; + wd->y_size = raw_info.y_size; + wd->maxcontacts = raw_info.maxcontacts; + wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT; + wd->resolution = raw_info.res; + + return 0; +} + +static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct wtp_data *wd; + + wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data), + GFP_KERNEL); + if (!wd) + return -ENOMEM; + + hidpp->private_data = wd; + + return 0; +}; + +/* -------------------------------------------------------------------------- */ +/* Generic HID++ devices */ +/* -------------------------------------------------------------------------- */ + +static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + return wtp_input_mapping(hdev, hi, field, usage, bit, max); + + return 0; +} + +static void hidpp_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + wtp_input_configured(hdev, hidinput); +} + +static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, + int size) +{ + struct hidpp_report *question = hidpp->send_receive_buf; + struct hidpp_report *answer = hidpp->send_receive_buf; + struct hidpp_report *report = (struct hidpp_report *)data; + + /* + * If the mutex is locked then we have a pending answer from a + * previoulsly sent command + */ + if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { + /* + * Check for a correct hidpp20 answer or the corresponding + * error + */ + if (hidpp_match_answer(question, report) || + hidpp_match_error(question, report)) { + *answer = *report; + hidpp->answer_available = true; + wake_up(&hidpp->wait); + /* + * This was an answer to a command that this driver sent + * We return 1 to hid-core to avoid forwarding the + * command upstream as it has been treated by the driver + */ + + return 1; + } + } + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + return wtp_raw_event(hidpp->hid_dev, data, size); + + return 0; +} + +static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, + u8 *data, int size) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + switch (data[0]) { + case REPORT_ID_HIDPP_LONG: + if (size != HIDPP_REPORT_LONG_LENGTH) { + hid_err(hdev, "received hid++ report of bad size (%d)", + size); + return 1; + } + return hidpp_raw_hidpp_event(hidpp, data, size); + case REPORT_ID_HIDPP_SHORT: + if (size != HIDPP_REPORT_SHORT_LENGTH) { + hid_err(hdev, "received hid++ report of bad size (%d)", + size); + return 1; + } + return hidpp_raw_hidpp_event(hidpp, data, size); + } + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + return wtp_raw_event(hdev, data, size); + + return 0; +} + +static void hidpp_overwrite_name(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + char *name; + u8 name_length; + + name = hidpp_get_device_name(hidpp, &name_length); + + if (!name) + hid_err(hdev, "unable to retrieve the name of the device"); + else + snprintf(hdev->name, sizeof(hdev->name), "%s", name); + + kfree(name); +} + +static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct hidpp_device *hidpp; + int ret; + bool connected; + + hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device), + GFP_KERNEL); + if (!hidpp) + return -ENOMEM; + + hidpp->hid_dev = hdev; + hid_set_drvdata(hdev, hidpp); + + hidpp->quirks = id->driver_data; + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { + ret = wtp_allocate(hdev, id); + if (ret) + return ret; + } + + mutex_init(&hidpp->send_mutex); + init_waitqueue_head(&hidpp->wait); + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "%s:parse failed\n", __func__); + goto hid_parse_fail; + } + + /* Allow incoming packets */ + hid_device_io_start(hdev); + + connected = hidpp_is_connected(hidpp); + if (!connected) { + hid_err(hdev, "Device not connected"); + goto hid_parse_fail; + } + + /* the device is connected, we can ask for its name */ + hid_info(hdev, "HID++ %u.%u device connected.\n", + hidpp->protocol_major, hidpp->protocol_minor); + hidpp_overwrite_name(hdev); + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { + ret = wtp_get_config(hidpp); + if (ret) + goto hid_parse_fail; + } + + /* Block incoming packets */ + hid_device_io_stop(hdev); + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); + goto hid_hw_start_fail; + } + + return ret; + +hid_hw_start_fail: +hid_parse_fail: + mutex_destroy(&hidpp->send_mutex); + hid_set_drvdata(hdev, NULL); + return ret; +} + +static void hidpp_remove(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + mutex_destroy(&hidpp->send_mutex); + hid_hw_stop(hdev); +} + +static const struct hid_device_id hidpp_devices[] = { + { /* wireless touchpad T651 */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_LOGITECH_T651), + .driver_data = HIDPP_QUIRK_CLASS_WTP }, + {} +}; + +MODULE_DEVICE_TABLE(hid, hidpp_devices); + +static struct hid_driver hidpp_driver = { + .name = "logitech-hidpp-device", + .id_table = hidpp_devices, + .probe = hidpp_probe, + .remove = hidpp_remove, + .raw_event = hidpp_raw_event, + .input_configured = hidpp_input_configured, + .input_mapping = hidpp_input_mapping, +}; + +module_hid_driver(hidpp_driver); -- GitLab From ab94e562ed45c99914fe874b7feaf75b80ceea84 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:28 -0400 Subject: [PATCH 1946/9457] HID: logitech: move dj devices to the HID++ module Devices connected through the Logitech Wireless Receiver are HID++ devices. We can handle them here to benefit from this new module and activate enhaced support of the various wireless touchpad or mice with touch sensors on them. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-logitech-dj.c | 42 +------------------------------- drivers/hid/hid-logitech-hidpp.c | 21 ++++++++++------ 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6f299cd54e6d..dd49a9b14b9c 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -371,6 +371,7 @@ config HID_LOGITECH_DJ tristate "Logitech Unifying receivers full support" depends on HIDRAW depends on HID_LOGITECH + select HID_LOGITECH_HIDPP ---help--- Say Y if you want support for Logitech Unifying receivers and devices. Unifying receivers are capable of pairing up to 6 Logitech compliant diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 6aea16dca3ff..45a7eacdfe98 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -977,48 +977,8 @@ static struct hid_driver logi_djreceiver_driver = { #endif }; +module_hid_driver(logi_djreceiver_driver); -static const struct hid_device_id logi_dj_devices[] = { - { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, - USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, - {} -}; - -static struct hid_driver logi_djdevice_driver = { - .name = "logitech-djdevice", - .id_table = logi_dj_devices, -}; - - -static int __init logi_dj_init(void) -{ - int retval; - - dbg_hid("Logitech-DJ:%s\n", __func__); - - retval = hid_register_driver(&logi_djreceiver_driver); - if (retval) - return retval; - - retval = hid_register_driver(&logi_djdevice_driver); - if (retval) - hid_unregister_driver(&logi_djreceiver_driver); - - return retval; - -} - -static void __exit logi_dj_exit(void) -{ - dbg_hid("Logitech-DJ:%s\n", __func__); - - hid_unregister_driver(&logi_djdevice_driver); - hid_unregister_driver(&logi_djreceiver_driver); - -} - -module_init(logi_dj_init); -module_exit(logi_dj_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Logitech"); MODULE_AUTHOR("Nestor Lopez Casado"); diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 7dd9163f7e03..48dec394dd38 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -777,15 +777,17 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hid_device_io_start(hdev); connected = hidpp_is_connected(hidpp); - if (!connected) { - hid_err(hdev, "Device not connected"); - goto hid_parse_fail; - } + if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) { + if (!connected) { + hid_err(hdev, "Device not connected"); + goto hid_parse_fail; + } - /* the device is connected, we can ask for its name */ - hid_info(hdev, "HID++ %u.%u device connected.\n", - hidpp->protocol_major, hidpp->protocol_minor); - hidpp_overwrite_name(hdev); + /* the device is connected, we can ask for its name */ + hid_info(hdev, "HID++ %u.%u device connected.\n", + hidpp->protocol_major, hidpp->protocol_minor); + hidpp_overwrite_name(hdev); + } if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { ret = wtp_get_config(hidpp); @@ -824,6 +826,9 @@ static const struct hid_device_id hidpp_devices[] = { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651), .driver_data = HIDPP_QUIRK_CLASS_WTP }, + + { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, + USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, {} }; -- GitLab From 925f0f3ed24f98b40c28627e74ff3e7f9d1e28bc Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:29 -0400 Subject: [PATCH 1947/9457] HID: logitech-dj: allow transfer of HID++ reports from/to the correct dj device HID++ is a Logitech-specific protocol for communicating with HID devices. DJ devices implement HID++, and so we can add the HID++ collection in the report descriptor and forward the incoming reports from the receiver to the appropriate DJ device. The same can be done in the other way, if someone calls a .raw_request(), we can forward it to the correct dj device by overriding the device_index in the HID++ report. Signed-off-by: Benjamin Tisssoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 188 +++++++++++++++++++++++++++++----- 1 file changed, 160 insertions(+), 28 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 45a7eacdfe98..feddacd87b8b 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -42,6 +42,15 @@ #define REPORT_ID_DJ_SHORT 0x20 #define REPORT_ID_DJ_LONG 0x21 +#define REPORT_ID_HIDPP_SHORT 0x10 +#define REPORT_ID_HIDPP_LONG 0x11 + +#define HIDPP_REPORT_SHORT_LENGTH 7 +#define HIDPP_REPORT_LONG_LENGTH 20 + +#define HIDPP_RECEIVER_INDEX 0xff + +#define REPORT_TYPE_RFREPORT_FIRST 0x01 #define REPORT_TYPE_RFREPORT_LAST 0x1F /* Command Switch to DJ mode */ @@ -242,6 +251,57 @@ static const char media_descriptor[] = { 0xc0, /* EndCollection */ }; /* */ +/* HIDPP descriptor */ +static const char hidpp_descriptor[] = { + 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ + 0x09, 0x01, /* Usage (Vendor Usage 1) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x10, /* Report ID (16) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x06, /* Report Count (6) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xff, 0x00, /* Logical Maximum (255) */ + 0x09, 0x01, /* Usage (Vendor Usage 1) */ + 0x81, 0x00, /* Input (Data,Arr,Abs) */ + 0x09, 0x01, /* Usage (Vendor Usage 1) */ + 0x91, 0x00, /* Output (Data,Arr,Abs) */ + 0xc0, /* End Collection */ + 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ + 0x09, 0x02, /* Usage (Vendor Usage 2) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x11, /* Report ID (17) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x13, /* Report Count (19) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xff, 0x00, /* Logical Maximum (255) */ + 0x09, 0x02, /* Usage (Vendor Usage 2) */ + 0x81, 0x00, /* Input (Data,Arr,Abs) */ + 0x09, 0x02, /* Usage (Vendor Usage 2) */ + 0x91, 0x00, /* Output (Data,Arr,Abs) */ + 0xc0, /* End Collection */ + 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ + 0x09, 0x04, /* Usage (Vendor Usage 0x04) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x85, 0x20, /* Report ID (32) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x0e, /* Report Count (14) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xff, 0x00, /* Logical Maximum (255) */ + 0x09, 0x41, /* Usage (Vendor Usage 0x41) */ + 0x81, 0x00, /* Input (Data,Arr,Abs) */ + 0x09, 0x41, /* Usage (Vendor Usage 0x41) */ + 0x91, 0x00, /* Output (Data,Arr,Abs) */ + 0x85, 0x21, /* Report ID (33) */ + 0x95, 0x1f, /* Report Count (31) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xff, 0x00, /* Logical Maximum (255) */ + 0x09, 0x42, /* Usage (Vendor Usage 0x42) */ + 0x81, 0x00, /* Input (Data,Arr,Abs) */ + 0x09, 0x42, /* Usage (Vendor Usage 0x42) */ + 0x91, 0x00, /* Output (Data,Arr,Abs) */ + 0xc0, /* End Collection */ +}; + /* Maximum size of all defined hid reports in bytes (including report id) */ #define MAX_REPORT_SIZE 8 @@ -251,7 +311,8 @@ static const char media_descriptor[] = { sizeof(mse_descriptor) + \ sizeof(consumer_descriptor) + \ sizeof(syscontrol_descriptor) + \ - sizeof(media_descriptor)) + sizeof(media_descriptor) + \ + sizeof(hidpp_descriptor)) /* Number of possible hid report types that can be created by this driver. * @@ -512,6 +573,13 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev, } } +static void logi_dj_recv_forward_hidpp(struct dj_device *dj_dev, u8 *data, + int size) +{ + /* We are called from atomic context (tasklet && djrcv->lock held) */ + if (hid_input_report(dj_dev->hdev, HID_INPUT_REPORT, data, size, 1)) + dbg_hid("hid_input_report error\n"); +} static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, struct dj_report *dj_report) @@ -609,6 +677,16 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, u8 *out_buf; int ret; + if ((buf[0] == REPORT_ID_HIDPP_SHORT) || + (buf[0] == REPORT_ID_HIDPP_LONG)) { + if (count < 2) + return -EINVAL; + + buf[1] = djdev->device_index; + return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, + count, report_type, reqtype); + } + if (buf[0] != REPORT_TYPE_LEDS) return -EINVAL; @@ -687,6 +765,8 @@ static int logi_dj_ll_parse(struct hid_device *hid) __func__, djdev->reports_supported); } + rdcat(rdesc, &rsize, hidpp_descriptor, sizeof(hidpp_descriptor)); + retval = hid_parse_report(hid, rdesc, rsize); kfree(rdesc); @@ -714,8 +794,7 @@ static struct hid_ll_driver logi_dj_ll_driver = { .raw_request = logi_dj_ll_raw_request, }; - -static int logi_dj_raw_event(struct hid_device *hdev, +static int logi_dj_dj_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) { @@ -723,36 +802,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, struct dj_report *dj_report = (struct dj_report *) data; unsigned long flags; - dbg_hid("%s, size:%d\n", __func__, size); - - /* Here we receive all data coming from iface 2, there are 4 cases: - * - * 1) Data should continue its normal processing i.e. data does not - * come from the DJ collection, in which case we do nothing and - * return 0, so hid-core can continue normal processing (will forward - * to associated hidraw device) + /* + * Here we receive all data coming from iface 2, there are 3 cases: * - * 2) Data is from DJ collection, and is intended for this driver i. e. - * data contains arrival, departure, etc notifications, in which case - * we queue them for delayed processing by the work queue. We return 1 - * to hid-core as no further processing is required from it. + * 1) Data is intended for this driver i. e. data contains arrival, + * departure, etc notifications, in which case we queue them for delayed + * processing by the work queue. We return 1 to hid-core as no further + * processing is required from it. * - * 3) Data is from DJ collection, and informs a connection change, - * if the change means rf link loss, then we must send a null report - * to the upper layer to discard potentially pressed keys that may be - * repeated forever by the input layer. Return 1 to hid-core as no - * further processing is required. + * 2) Data informs a connection change, if the change means rf link + * loss, then we must send a null report to the upper layer to discard + * potentially pressed keys that may be repeated forever by the input + * layer. Return 1 to hid-core as no further processing is required. * - * 4) Data is from DJ collection and is an actual input event from - * a paired DJ device in which case we forward it to the correct hid - * device (via hid_input_report() ) and return 1 so hid-core does not do - * anything else with it. + * 3) Data is an actual input event from a paired DJ device in which + * case we forward it to the correct hid device (via hid_input_report() + * ) and return 1 so hid-core does not anything else with it. */ - /* case 1) */ - if (data[0] != REPORT_ID_DJ_SHORT) - return false; - if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { /* @@ -797,6 +864,71 @@ static int logi_dj_raw_event(struct hid_device *hdev, return true; } +static int logi_dj_hidpp_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, + int size) +{ + struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); + struct dj_report *dj_report = (struct dj_report *) data; + unsigned long flags; + u8 device_index = dj_report->device_index; + + if (device_index == HIDPP_RECEIVER_INDEX) + return false; + + /* + * Data is from the HID++ collection, in this case, we forward the + * data to the corresponding child dj device and return 0 to hid-core + * so he data also goes to the hidraw device of the receiver. This + * allows a user space application to implement the full HID++ routing + * via the receiver. + */ + + if ((device_index < DJ_DEVICE_INDEX_MIN) || + (device_index > DJ_DEVICE_INDEX_MAX)) { + /* + * Device index is wrong, bail out. + * This driver can ignore safely the receiver notifications, + * so ignore those reports too. + */ + dev_err(&hdev->dev, "%s: invalid device index:%d\n", + __func__, dj_report->device_index); + return false; + } + + spin_lock_irqsave(&djrcv_dev->lock, flags); + + if (!djrcv_dev->paired_dj_devices[device_index]) + /* received an event for an unknown device, bail out */ + goto out; + + logi_dj_recv_forward_hidpp(djrcv_dev->paired_dj_devices[device_index], + data, size); + +out: + spin_unlock_irqrestore(&djrcv_dev->lock, flags); + + return false; +} + +static int logi_dj_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, + int size) +{ + dbg_hid("%s, size:%d\n", __func__, size); + + switch (data[0]) { + case REPORT_ID_DJ_SHORT: + return logi_dj_dj_event(hdev, report, data, size); + case REPORT_ID_HIDPP_SHORT: + /* intentional fallthrough */ + case REPORT_ID_HIDPP_LONG: + return logi_dj_hidpp_event(hdev, report, data, size); + } + + return false; +} + static int logi_dj_probe(struct hid_device *hdev, const struct hid_device_id *id) { -- GitLab From 33797820af98cde5c7cee00d00f0d8e255ea199f Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:30 -0400 Subject: [PATCH 1948/9457] HID: logitech: allow the DJ device to request the unifying name The names of the DJ devices are stored in the receiver. These names can be retrieved through a HID++ command. However, the protocol says that you have to ask the receiver for that, not the device iteself. Introduce a special case in the DJ handling where a device can request its unifying name, and when such a name is given, forward it also to the corresponding device. On the HID++ side, the receiver talks only HID++ 1.0, so we need to implement this part of the protocol in the module. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 24 ++++++++-- drivers/hid/hid-logitech-hidpp.c | 80 ++++++++++++++++++++++++++++++-- 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index feddacd87b8b..9bc39421627f 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -667,6 +667,9 @@ static void logi_dj_ll_close(struct hid_device *hid) dbg_hid("%s:%s\n", __func__, hid->phys); } +static u8 unifying_name_query[] = {0x10, 0xff, 0x83, 0xb5, 0x40, 0x00, 0x00}; +static u8 unifying_name_answer[] = {0x11, 0xff, 0x83, 0xb5}; + static int logi_dj_ll_raw_request(struct hid_device *hid, unsigned char reportnum, __u8 *buf, size_t count, unsigned char report_type, @@ -682,7 +685,13 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, if (count < 2) return -EINVAL; - buf[1] = djdev->device_index; + /* special case where we should not overwrite + * the device_index */ + if (count == 7 && !memcmp(buf, unifying_name_query, + sizeof(unifying_name_query))) + buf[4] |= djdev->device_index - 1; + else + buf[1] = djdev->device_index; return hid_hw_raw_request(djrcv_dev->hdev, reportnum, buf, count, report_type, reqtype); } @@ -873,8 +882,17 @@ static int logi_dj_hidpp_event(struct hid_device *hdev, unsigned long flags; u8 device_index = dj_report->device_index; - if (device_index == HIDPP_RECEIVER_INDEX) - return false; + if (device_index == HIDPP_RECEIVER_INDEX) { + /* special case were the device wants to know its unifying + * name */ + if (size == HIDPP_REPORT_LONG_LENGTH && + !memcmp(data, unifying_name_answer, + sizeof(unifying_name_answer)) && + ((data[4] & 0xF0) == 0x40)) + device_index = (data[4] & 0x0F) + 1; + else + return false; + } /* * Data is from the HID++ collection, in this case, we forward the diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 48dec394dd38..e748e45b5b2f 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -205,6 +205,31 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, return ret; } +static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, + u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count, + struct hidpp_report *response) +{ + struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report), + GFP_KERNEL); + int ret; + + if ((report_id != REPORT_ID_HIDPP_SHORT) && + (report_id != REPORT_ID_HIDPP_LONG)) + return -EINVAL; + + if (param_count > sizeof(message->rap.params)) + return -EINVAL; + + message->report_id = report_id; + message->rap.sub_id = sub_id; + message->rap.reg_address = reg_address; + memcpy(&message->rap.params, params, param_count); + + ret = hidpp_send_message_sync(hidpp_dev, message, response); + kfree(message); + return ret; +} + static inline bool hidpp_match_answer(struct hidpp_report *question, struct hidpp_report *answer) { @@ -220,6 +245,45 @@ static inline bool hidpp_match_error(struct hidpp_report *question, (answer->fap.params[0] == question->fap.funcindex_clientid); } +/* -------------------------------------------------------------------------- */ +/* HIDP++ 1.0 commands */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_SET_REGISTER 0x80 +#define HIDPP_GET_REGISTER 0x81 +#define HIDPP_SET_LONG_REGISTER 0x82 +#define HIDPP_GET_LONG_REGISTER 0x83 + +#define HIDPP_REG_PAIRING_INFORMATION 0xB5 +#define DEVICE_NAME 0x40 + +static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) +{ + struct hidpp_report response; + int ret; + /* hid-logitech-dj is in charge of setting the right device index */ + u8 params[1] = { DEVICE_NAME }; + char *name; + int len; + + ret = hidpp_send_rap_command_sync(hidpp_dev, + REPORT_ID_HIDPP_SHORT, + HIDPP_GET_LONG_REGISTER, + HIDPP_REG_PAIRING_INFORMATION, + params, 1, &response); + if (ret) + return NULL; + + len = response.rap.params[1]; + + name = kzalloc(len + 1, GFP_KERNEL); + if (!name) + return NULL; + + memcpy(name, &response.rap.params[2], len); + return name; +} + /* -------------------------------------------------------------------------- */ /* 0x0000: Root */ /* -------------------------------------------------------------------------- */ @@ -726,13 +790,21 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, return 0; } -static void hidpp_overwrite_name(struct hid_device *hdev) +static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); char *name; u8 name_length; - name = hidpp_get_device_name(hidpp, &name_length); + if (use_unifying) + /* + * the device is connected through an Unifying receiver, and + * might not be already connected. + * Ask the receiver for its name. + */ + name = hidpp_get_unifying_name(hidpp); + else + name = hidpp_get_device_name(hidpp, &name_length); if (!name) hid_err(hdev, "unable to retrieve the name of the device"); @@ -783,12 +855,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_parse_fail; } - /* the device is connected, we can ask for its name */ hid_info(hdev, "HID++ %u.%u device connected.\n", hidpp->protocol_major, hidpp->protocol_minor); - hidpp_overwrite_name(hdev); } + hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE); + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { ret = wtp_get_config(hidpp); if (ret) -- GitLab From 6a9ddc8978835deae0b2d918df74fc83588a4104 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:31 -0400 Subject: [PATCH 1949/9457] HID: logitech-dj: enable notifications on connect/disconnect The receiver can send HID++ notifications to the DJ devices when the physical devices are connected/disconnected. Enable this feature by default. This command uses a HID++ command instead of a DJ one, so use a direct call to usbhid instead of using logi_dj_recv_send_report() Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9bc39421627f..c917ab61aafa 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -630,7 +630,9 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { + struct hid_device *hdev = djrcv_dev->hdev; struct dj_report *dj_report; + u8 *buf; int retval; dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); @@ -642,7 +644,6 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; retval = logi_dj_recv_send_report(djrcv_dev, dj_report); - kfree(dj_report); /* * Ugly sleep to work around a USB 3.0 bug when the receiver is still @@ -651,6 +652,30 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, */ msleep(50); + /* + * Magical bits to set up hidpp notifications when the dj devices + * are connected/disconnected. + * + * We can reuse dj_report because HIDPP_REPORT_SHORT_LENGTH is smaller + * than DJREPORT_SHORT_LENGTH. + */ + buf = (u8 *)dj_report; + + memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH); + + buf[0] = REPORT_ID_HIDPP_SHORT; + buf[1] = 0xFF; + buf[2] = 0x80; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x09; + buf[6] = 0x00; + + hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, + HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + + kfree(dj_report); return retval; } -- GitLab From c39e3d5fc9dd3e16c6f59dd94d827540040de66d Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:32 -0400 Subject: [PATCH 1950/9457] HID: logitech-hidpp: late bind the input device on wireless connection Now that the receiver forwards the connect/disconnect events, we can know when the device is available to communicate with us. When it is ready, we can for instance retrieve its full name, which guarantee that we always have the same name for the DJ device (the DJ name is somewhat shorter than the HID++ name). This mechanism is mandatory for the touchpads line, which has the min/max information stored in the device. This information can only be retrieved when the device is connected. So we can not populate the input device until we are sure that the device is connected. This patch creates a new input device for such devices. However, this input is not bound to hid directly, so the various drivers which wants to use it are required to process completely the incoming reports in .raw_event(). Note that the patch in itself just adds the bits for the next ones, and this feature is disabled by default. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 155 +++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index e748e45b5b2f..9561a1f9b42b 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -36,6 +36,9 @@ MODULE_AUTHOR("Nestor Lopez Casado "); #define HIDPP_QUIRK_CLASS_WTP BIT(0) +/* bits 1..20 are reserved for classes */ +#define HIDPP_QUIRK_DELAYED_INIT BIT(21) + /* * There are two hidpp protocols in use, the first version hidpp10 is known * as register access protocol or RAP, the second version hidpp20 is known as @@ -91,6 +94,11 @@ struct hidpp_device { void *private_data; + struct work_struct work; + struct kfifo delayed_work_fifo; + atomic_t connected; + struct input_dev *delayed_input; + unsigned long quirks; }; @@ -110,6 +118,8 @@ struct hidpp_device { #define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b #define HIDPP_ERROR_WRONG_PIN_CODE 0x0c +static void hidpp_connect_event(struct hidpp_device *hidpp_dev); + static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { @@ -230,6 +240,13 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, return ret; } +static void delayed_work_cb(struct work_struct *work) +{ + struct hidpp_device *hidpp = container_of(work, struct hidpp_device, + work); + hidpp_connect_event(hidpp); +} + static inline bool hidpp_match_answer(struct hidpp_report *question, struct hidpp_report *answer) { @@ -245,6 +262,12 @@ static inline bool hidpp_match_error(struct hidpp_report *question, (answer->fap.params[0] == question->fap.funcindex_clientid); } +static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) +{ + return (report->report_id == REPORT_ID_HIDPP_SHORT) && + (report->rap.sub_id == 0x41); +} + /* -------------------------------------------------------------------------- */ /* HIDP++ 1.0 commands */ /* -------------------------------------------------------------------------- */ @@ -535,12 +558,10 @@ static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return -1; } -static void wtp_input_configured(struct hid_device *hdev, - struct hid_input *hidinput) +static void wtp_populate_input(struct hidpp_device *hidpp, + struct input_dev *input_dev, bool origin_is_hid_core) { - struct hidpp_device *hidpp = hid_get_drvdata(hdev); struct wtp_data *wd = hidpp->private_data; - struct input_dev *input_dev = hidinput->input; __set_bit(EV_ABS, input_dev->evbit); __set_bit(EV_KEY, input_dev->evbit); @@ -716,13 +737,20 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static void hidpp_populate_input(struct hidpp_device *hidpp, + struct input_dev *input, bool origin_is_hid_core) +{ + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + wtp_populate_input(hidpp, input, origin_is_hid_core); +} + static void hidpp_input_configured(struct hid_device *hdev, struct hid_input *hidinput) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct input_dev *input = hidinput->input; - if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) - wtp_input_configured(hdev, hidinput); + hidpp_populate_input(hidpp, input, true); } static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, @@ -756,6 +784,15 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, } } + if (unlikely(hidpp_report_is_connect_event(report))) { + atomic_set(&hidpp->connected, + !(report->rap.params[0] & (1 << 6))); + if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) && + (schedule_work(&hidpp->work) == 0)) + dbg_hid("%s: connect event already queued\n", __func__); + return 1; + } + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) return wtp_raw_event(hidpp->hid_dev, data, size); @@ -814,11 +851,99 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) kfree(name); } +static int hidpp_input_open(struct input_dev *dev) +{ + struct hid_device *hid = input_get_drvdata(dev); + + return hid_hw_open(hid); +} + +static void hidpp_input_close(struct input_dev *dev) +{ + struct hid_device *hid = input_get_drvdata(dev); + + hid_hw_close(hid); +} + +static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) +{ + struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); + + if (!input_dev) + return NULL; + + input_set_drvdata(input_dev, hdev); + input_dev->open = hidpp_input_open; + input_dev->close = hidpp_input_close; + + input_dev->name = hdev->name; + input_dev->phys = hdev->phys; + input_dev->uniq = hdev->uniq; + input_dev->id.bustype = hdev->bus; + input_dev->id.vendor = hdev->vendor; + input_dev->id.product = hdev->product; + input_dev->id.version = hdev->version; + input_dev->dev.parent = &hdev->dev; + + return input_dev; +} + +static void hidpp_connect_event(struct hidpp_device *hidpp) +{ + struct hid_device *hdev = hidpp->hid_dev; + int ret = 0; + bool connected = atomic_read(&hidpp->connected); + struct input_dev *input; + char *name, *devm_name; + u8 name_length; + + if (!connected || hidpp->delayed_input) + return; + + if (!hidpp->protocol_major) { + ret = !hidpp_is_connected(hidpp); + if (ret) { + hid_err(hdev, "Can not get the protocol version.\n"); + return; + } + } + + /* the device is already connected, we can ask for its name and + * protocol */ + hid_info(hdev, "HID++ %u.%u device connected.\n", + hidpp->protocol_major, hidpp->protocol_minor); + + input = hidpp_allocate_input(hdev); + if (!input) { + hid_err(hdev, "cannot allocate new input device: %d\n", ret); + return; + } + + name = hidpp_get_device_name(hidpp, &name_length); + if (!name) { + hid_err(hdev, "unable to retrieve the name of the device"); + } else { + devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name); + if (devm_name) + input->name = devm_name; + kfree(name); + } + + hidpp_populate_input(hidpp, input, false); + + ret = input_register_device(input); + if (ret) + input_free_device(input); + + hidpp->delayed_input = input; +} + static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct hidpp_device *hidpp; int ret; bool connected; + unsigned int connect_mask = HID_CONNECT_DEFAULT; hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device), GFP_KERNEL); @@ -836,6 +961,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } + INIT_WORK(&hidpp->work, delayed_work_cb); mutex_init(&hidpp->send_mutex); init_waitqueue_head(&hidpp->wait); @@ -860,8 +986,9 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) } hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE); + atomic_set(&hidpp->connected, connected); - if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { + if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { ret = wtp_get_config(hidpp); if (ret) goto hid_parse_fail; @@ -870,16 +997,27 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) /* Block incoming packets */ hid_device_io_stop(hdev); - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) + connect_mask &= ~HID_CONNECT_HIDINPUT; + + ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); goto hid_hw_start_fail; } + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) { + /* Allow incoming packets */ + hid_device_io_start(hdev); + + hidpp_connect_event(hidpp); + } + return ret; hid_hw_start_fail: hid_parse_fail: + cancel_work_sync(&hidpp->work); mutex_destroy(&hidpp->send_mutex); hid_set_drvdata(hdev, NULL); return ret; @@ -889,6 +1027,7 @@ static void hidpp_remove(struct hid_device *hdev) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); + cancel_work_sync(&hidpp->work); mutex_destroy(&hidpp->send_mutex); hid_hw_stop(hdev); } -- GitLab From 586bdc4e4f15fec37dc37167d6f314ea94aa14d1 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:33 -0400 Subject: [PATCH 1951/9457] HID: logitech-hidpp: Add Wireless Touchpad T650 support All the bits are now in place to add the support of the Touchpad T650. The creation/population of the input device is delayed until the device is ready. The T650 uses the special HID++ reporting protocol, so activate this on connect. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 105 ++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 9561a1f9b42b..f9a4ec0ff76d 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -471,6 +471,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp, u8 *name_length) #define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100 #define CMD_TOUCHPAD_GET_RAW_INFO 0x01 +#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21 + +#define EVENT_TOUCHPAD_RAW_XY 0x00 #define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01 #define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03 @@ -530,6 +533,59 @@ static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp, return ret; } +static int hidpp_touchpad_set_raw_report_state(struct hidpp_device *hidpp_dev, + u8 feature_index, bool send_raw_reports, + bool sensor_enhanced_settings) +{ + struct hidpp_report response; + + /* + * Params: + * bit 0 - enable raw + * bit 1 - 16bit Z, no area + * bit 2 - enhanced sensitivity + * bit 3 - width, height (4 bits each) instead of area + * bit 4 - send raw + gestures (degrades smoothness) + * remaining bits - reserved + */ + u8 params = send_raw_reports | (sensor_enhanced_settings << 2); + + return hidpp_send_fap_command_sync(hidpp_dev, feature_index, + CMD_TOUCHPAD_SET_RAW_REPORT_STATE, ¶ms, 1, &response); +} + +static void hidpp_touchpad_touch_event(u8 *data, + struct hidpp_touchpad_raw_xy_finger *finger) +{ + u8 x_m = data[0] << 2; + u8 y_m = data[2] << 2; + + finger->x = x_m << 6 | data[1]; + finger->y = y_m << 6 | data[3]; + + finger->contact_type = data[0] >> 6; + finger->contact_status = data[2] >> 6; + + finger->z = data[4]; + finger->area = data[5]; + finger->finger_id = data[6] >> 4; +} + +static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, + u8 *data, struct hidpp_touchpad_raw_xy *raw_xy) +{ + memset(raw_xy, 0, sizeof(struct hidpp_touchpad_raw_xy)); + raw_xy->end_of_frame = data[8] & 0x01; + raw_xy->spurious_flag = (data[8] >> 1) & 0x01; + raw_xy->finger_count = data[15] & 0x0f; + raw_xy->button = (data[8] >> 2) & 0x01; + + if (raw_xy->finger_count) { + hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]); + hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]); + } +} + /* ************************************************************************** */ /* */ /* Device Support */ @@ -672,11 +728,28 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) { struct hidpp_device *hidpp = hid_get_drvdata(hdev); struct wtp_data *wd = hidpp->private_data; + struct hidpp_report *report = (struct hidpp_report *)data; + struct hidpp_touchpad_raw_xy raw; - if (!wd || !wd->input || (data[0] != 0x02) || size < 21) + if (!wd || !wd->input) return 1; - return wtp_mouse_raw_xy_event(hidpp, &data[7]); + switch (data[0]) { + case 0x02: + if (size < 21) + return 1; + return wtp_mouse_raw_xy_event(hidpp, &data[7]); + case REPORT_ID_HIDPP_LONG: + if ((report->fap.feature_index != wd->mt_feature_index) || + (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) + return 1; + hidpp_touchpad_raw_xy_event(hidpp, data + 4, &raw); + + wtp_send_raw_xy_event(hidpp, &raw); + return 0; + } + + return 0; } static int wtp_get_config(struct hidpp_device *hidpp) @@ -721,6 +794,27 @@ static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id) return 0; }; +static void wtp_connect(struct hid_device *hdev, bool connected) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct wtp_data *wd = hidpp->private_data; + int ret; + + if (!connected) + return; + + if (!wd->x_size) { + ret = wtp_get_config(hidpp); + if (ret) { + hid_err(hdev, "Can not get wtp config: %d\n", ret); + return; + } + } + + hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index, + true, true); +} + /* -------------------------------------------------------------------------- */ /* Generic HID++ devices */ /* -------------------------------------------------------------------------- */ @@ -897,6 +991,9 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) char *name, *devm_name; u8 name_length; + if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) + wtp_connect(hdev, connected); + if (!connected || hidpp->delayed_input) return; @@ -1033,6 +1130,10 @@ static void hidpp_remove(struct hid_device *hdev) } static const struct hid_device_id hidpp_devices[] = { + { /* wireless touchpad T650 */ + HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, + USB_VENDOR_ID_LOGITECH, 0x4101), + .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, { /* wireless touchpad T651 */ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651), -- GitLab From 57ac86cf52e903d9e3e0f12b34c814cce6b65550 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:34 -0400 Subject: [PATCH 1952/9457] HID: logitech-hidpp: add support of the first Logitech Wireless Touchpad This touchpad differs from the T650 in several ways: - the resolution is not correctly returned by the device - it presents physical buttons, so the button flag in the raw touch report is not filled. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index f9a4ec0ff76d..17e27e98e442 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -38,6 +38,7 @@ MODULE_AUTHOR("Nestor Lopez Casado "); /* bits 1..20 are reserved for classes */ #define HIDPP_QUIRK_DELAYED_INIT BIT(21) +#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) /* * There are two hidpp protocols in use, the first version hidpp10 is known @@ -596,6 +597,8 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, /* Touchpad HID++ devices */ /* -------------------------------------------------------------------------- */ +#define WTP_MANUAL_RESOLUTION 39 + struct wtp_data { struct input_dev *input; u16 x_size, y_size; @@ -634,7 +637,10 @@ static void wtp_populate_input(struct hidpp_device *hidpp, input_set_capability(input_dev, EV_KEY, BTN_LEFT); - __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); + if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) + input_set_capability(input_dev, EV_KEY, BTN_RIGHT); + else + __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); @@ -676,7 +682,8 @@ static void wtp_send_raw_xy_event(struct hidpp_device *hidpp, for (i = 0; i < 2; i++) wtp_touch_event(wd, &(raw->fingers[i])); - if (raw->end_of_frame) + if (raw->end_of_frame && + !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)) input_event(wd->input, EV_KEY, BTN_LEFT, raw->button); if (raw->end_of_frame || raw->finger_count <= 2) { @@ -736,9 +743,17 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) switch (data[0]) { case 0x02: - if (size < 21) - return 1; - return wtp_mouse_raw_xy_event(hidpp, &data[7]); + if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { + input_event(wd->input, EV_KEY, BTN_LEFT, + !!(data[1] & 0x01)); + input_event(wd->input, EV_KEY, BTN_RIGHT, + !!(data[1] & 0x02)); + input_sync(wd->input); + } else { + if (size < 21) + return 1; + return wtp_mouse_raw_xy_event(hidpp, &data[7]); + } case REPORT_ID_HIDPP_LONG: if ((report->fap.feature_index != wd->mt_feature_index) || (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) @@ -775,6 +790,8 @@ static int wtp_get_config(struct hidpp_device *hidpp) wd->maxcontacts = raw_info.maxcontacts; wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT; wd->resolution = raw_info.res; + if (!wd->resolution) + wd->resolution = WTP_MANUAL_RESOLUTION; return 0; } @@ -1130,6 +1147,11 @@ static void hidpp_remove(struct hid_device *hdev) } static const struct hid_device_id hidpp_devices[] = { + { /* wireless touchpad */ + HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, + USB_VENDOR_ID_LOGITECH, 0x4011), + .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | + HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, { /* wireless touchpad T650 */ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, USB_VENDOR_ID_LOGITECH, 0x4101), -- GitLab From 3a61e97563d78a2ca10752902449570d8433ce76 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 13:18:35 -0400 Subject: [PATCH 1953/9457] HID: logitech-hidpp: support combo keyboard touchpad TK820 The TK820 presents both a keyboard and a touchpad on the same physical (and logical device). Use the generic hid-input processing for the keyboard part. The keyboard input device is created when the receiver is plugged in, so no events are missed on connect. When the device actaully connects, we can set it to use the raw multitouch reporting to have a consistent user experience accross all Logitech touchpads. Signed-off-by: Benjamin Tissoires Tested-by: Andrew de los Reyes Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 17e27e98e442..361e97da1169 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -39,6 +39,7 @@ MODULE_AUTHOR("Nestor Lopez Casado "); /* bits 1..20 are reserved for classes */ #define HIDPP_QUIRK_DELAYED_INIT BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) +#define HIDPP_QUIRK_MULTI_INPUT BIT(23) /* * There are two hidpp protocols in use, the first version hidpp10 is known @@ -614,6 +615,12 @@ static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && + (field->application == HID_GD_KEYBOARD)) + return 0; + return -1; } @@ -622,6 +629,10 @@ static void wtp_populate_input(struct hidpp_device *hidpp, { struct wtp_data *wd = hidpp->private_data; + if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core) + /* this is the generic hid-input call */ + return; + __set_bit(EV_ABS, input_dev->evbit); __set_bit(EV_KEY, input_dev->evbit); __clear_bit(EV_REL, input_dev->evbit); @@ -1114,6 +1125,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) connect_mask &= ~HID_CONNECT_HIDINPUT; + /* Re-enable hidinput for multi-input devices */ + if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) + connect_mask |= HID_CONNECT_HIDINPUT; + ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); @@ -1160,6 +1175,11 @@ static const struct hid_device_id hidpp_devices[] = { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651), .driver_data = HIDPP_QUIRK_CLASS_WTP }, + { /* Keyboard TK820 */ + HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, + USB_VENDOR_ID_LOGITECH, 0x4102), + .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT | + HIDPP_QUIRK_CLASS_WTP }, { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, -- GitLab From b905811a49bcd6e6726ce5bbb591f57aaddfd3be Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 30 Sep 2014 14:28:22 -0400 Subject: [PATCH 1954/9457] HID: usbhid: prevent unwanted events to be sent when re-opening the device When events occurs while no one is listening to the node (hid->open == 0 and usb_kill_urb() called) some events are still stacked somewhere in the USB (kernel or device?) stack. When the node gets reopened, these events are drained, and this results in spurious touch down/up, or mouse button clicks. The problem was spotted with touchscreens in fdo bug #81781 [1], but it actually occurs with any mouse using hid-generic or touchscreen. A way to reproduce it is to call: $ xinput disable 9 ; sleep 5 ; xinput enable 9 With 9 being the device ID for the touchscreen/mouse. During the "sleep", produce some touch events or click events. When "xinput enable" is called, at least one click is generated. This patch tries to fix this by draining the queue for 50 msec and during this time frame, not forwarding these old events to the hid layer. Hans completed the explanation: """ Devices like mice (basically any hid device) will have a fifo on the device side, when we stop submitting urbs to get hid reports from it, that fifo will fill up, and when we resume we will get whatever is there in that fifo. """ [1] https://bugs.freedesktop.org/show_bug.cgi?id=81781 Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 36 +++++++++++++++++++++++------------ drivers/hid/usbhid/usbhid.h | 1 + 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ca6849a0121e..04e34b917045 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -278,18 +278,20 @@ static void hid_irq_in(struct urb *urb) usbhid->retry_delay = 0; if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) break; - hid_input_report(urb->context, HID_INPUT_REPORT, - urb->transfer_buffer, - urb->actual_length, 1); - /* - * autosuspend refused while keys are pressed - * because most keyboards don't wake up when - * a key is released - */ - if (hid_check_keys_pressed(hid)) - set_bit(HID_KEYS_PRESSED, &usbhid->iofl); - else - clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); + if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { + hid_input_report(urb->context, HID_INPUT_REPORT, + urb->transfer_buffer, + urb->actual_length, 1); + /* + * autosuspend refused while keys are pressed + * because most keyboards don't wake up when + * a key is released + */ + if (hid_check_keys_pressed(hid)) + set_bit(HID_KEYS_PRESSED, &usbhid->iofl); + else + clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); + } break; case -EPIPE: /* stall */ usbhid_mark_busy(usbhid); @@ -688,6 +690,7 @@ int usbhid_open(struct hid_device *hid) goto done; } usbhid->intf->needs_remote_wakeup = 1; + set_bit(HID_RESUME_RUNNING, &usbhid->iofl); res = hid_start_in(hid); if (res) { if (res != -ENOSPC) { @@ -701,6 +704,15 @@ int usbhid_open(struct hid_device *hid) } } usb_autopm_put_interface(usbhid->intf); + + /* + * In case events are generated while nobody was listening, + * some are released when the device is re-opened. + * Wait 50 msec for the queue to empty before allowing events + * to go through hid. + */ + msleep(50); + clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); } done: mutex_unlock(&hid_open_mut); diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index f633c24ce28b..807922b49aa4 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -52,6 +52,7 @@ struct usb_interface *usbhid_find_interface(int minor); #define HID_STARTED 8 #define HID_KEYS_PRESSED 10 #define HID_NO_BANDWIDTH 11 +#define HID_RESUME_RUNNING 12 /* * USB-specific HID struct, to be pointed to -- GitLab From 63ae1fe7739ec81eb63ad241b4e217d1fa0e8e53 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Oct 2014 10:33:31 +0000 Subject: [PATCH 1955/9457] ASoC: Intel: Add dependency on DesignWare DMA controller We have calls into the controller so we need to ensure it is being built. Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 2a3af880868b..ae7f87221a3c 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -20,6 +20,7 @@ config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI depends on (X86 || COMPILE_TEST) + depends on DW_DMAC_CORE help This adds support for Intel(R) Smart Sound Technology (SST). Say Y if you have such a device -- GitLab From dc574e526381ddcc7e5103ca091fd93c29129c6d Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 17 Sep 2014 13:56:29 +0300 Subject: [PATCH 1956/9457] iwlwifi: rs: option to easily disable Tx MIMO The current TLC isn't optimized for low latency and some devices have issues with MIMO. This kind of combo creates latency issues. Allow to temporarily disable MIMO for tests in order to solve the latency issues without the added complexity of MIMO. Signed-off-by: Eyal Shapira Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/constants.h | 1 + drivers/net/wireless/iwlwifi/mvm/rs.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index d4dfbe4cb66d..dfec5b5e7e14 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -95,5 +95,6 @@ #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 #define IWL_MVM_QUOTA_THRESHOLD 8 #define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 +#define IWL_MVM_RS_DISABLE_MIMO 0 #endif /* __MVM_CONSTANTS_H */ diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 18a539999580..0d836fe67e83 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -2684,6 +2684,9 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->ldpc = true; } + if (IWL_MVM_RS_DISABLE_MIMO) + lq_sta->active_mimo2_rate = 0; + lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, BITS_PER_LONG); lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate, -- GitLab From 8dfc275109e794371c58be69e4286fa7061cd3a1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 21 Sep 2014 13:29:48 +0300 Subject: [PATCH 1957/9457] iwlwifi: mvm: remove unneeded NULL pointer check mac80211 will never call rate_control_tx_status with a NULL pointer for sta. Remove the superfluous check. This check misled smatch. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 0d836fe67e83..66e971a99d7c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1225,7 +1225,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); done: /* See if there's a better rate or modulation mode to try. */ - if (sta && sta->supp_rates[info->band]) + if (sta->supp_rates[info->band]) rs_rate_scale_perform(mvm, sta, lq_sta, tid); } -- GitLab From 31ca09dd6becfd954098ca7ddb6c1e27b13fe5d7 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 22 Sep 2014 13:22:51 +0300 Subject: [PATCH 1958/9457] iwlwifi: mvm: hold the rtnl when resuming from a d3 test We use ieee80211_iter_keys() which requires the rtnl to be held. If we don't lock the rtnl, like we do when we suspend during a d3 test, we get the following splat: RTNL: assertion failed at net/mac80211/key.c (566) CPU: 1 PID: 26529 Comm: cat Tainted: G W O 3.10.29-dev #1 Hardware name: Dell Inc. Latitude E6430/0CPWYR, BIOS A09 12/13/2012 e7b15008 e7b15008 e68adc1c c168aa62 e68adc54 f91f20b6 f923700c f9236fd8 00000236 00000000 ece23874 00000000 f94941e0 00000000 e43b8e48 e7b15008 00000000 e8b69e78 e68adcc0 f9493ab9 e68adc68 00000000 e43b8e48 e7b15008 Call Trace: [] dump_stack+0x16/0x18 [] ieee80211_iter_keys+0x166/0x170 [mac80211] [] ? iwl_mvm_query_wakeup_reasons+0x5f0/0x5f0 [iwlmvm] [] iwl_mvm_setup_connection_keep.isra.5+0x99/0x1d0 [iwlmvm] [] ? cfg80211_report_wowlan_wakeup+0x308/0x510 [cfg80211] [] iwl_mvm_query_wakeup_reasons+0x3f5/0x5f0 [iwlmvm] [] ? init_object+0x3a/0x70 [] ? iwl_trans_pcie_d3_resume+0x1be/0x3a0 [iwlwifi] [] __iwl_mvm_resume+0x14a/0x180 [iwlmvm] [] iwl_mvm_d3_test_release+0x26/0xc0 [iwlmvm] [] __fput+0xad/0x210 [] ____fput+0xd/0x10 [] task_work_run+0x81/0xb0 [] do_exit+0x255/0xac0 [] ? dequeue_signal+0x31/0x1a0 [] do_group_exit+0x38/0xa0 [] ? trace_hardirqs_on+0xb/0x10 [] get_signal_to_deliver+0x1e1/0x8e0 [] ? try_to_del_timer_sync+0x42/0x60 [] ? try_to_del_timer_sync+0x60/0x60 [] ? schedule_timeout+0x102/0x2a0 [] do_signal+0x3a/0x8e0 [] ? __internal_add_timer+0xb0/0xb0 [] ? schedule_timeout_interruptible+0x1a/0x20 [] ? msleep_interruptible+0x39/0x40 [] ? iwl_mvm_d3_test_read+0x49/0x70 [iwlmvm] [] ? vfs_read+0x8c/0x160 [] ? SyS_fadvise64_64+0x15f/0x2b0 [] ? iwl_mvm_wowlan_program_keys+0x4a0/0x4a0 [iwlmvm] [] ? SyS_read+0x57/0xa0 [] do_notify_resume+0x6f/0xa0 [] work_notifysig+0x29/0x31 Fix this by hold the rtnl lock when calling __iwl_mvm_resume() in the d3 test wake up path. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c17be0fb7283..5b269224f817 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1741,7 +1741,9 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) int remaining_time = 10; mvm->d3_test_active = false; + rtnl_lock(); __iwl_mvm_resume(mvm, true); + rtnl_unlock(); iwl_abort_notification_waits(&mvm->notif_wait); ieee80211_restart_hw(mvm->hw); -- GitLab From 671b58202e485f26abf1f92c1b52ed45d03d0438 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 22 Sep 2014 10:59:53 +0300 Subject: [PATCH 1959/9457] iwlwifi: mvm: split wowlan handling out of the main suspend function Take the WoWLAN handling code out of the main suspend function, dividing it into three parts: get_config (which is used before the firmware is switched), switch_to_d3 (which handles the rebooting of the hardware with the D3 firmware) and config (which configures the D3 firmware for WoWLAN operation). This is necessary to prepare for the net-detect implementation, which will use only the switch_to_d3 part of this flow. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 266 +++++++++++++++----------- 1 file changed, 151 insertions(+), 115 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 5b269224f817..b8e8a97e002c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -783,6 +783,35 @@ void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) IWL_ERR(mvm, "failed to set non-QoS seqno\n"); } +static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm) +{ + iwl_mvm_cancel_scan(mvm); + + iwl_trans_stop_device(mvm->trans); + + /* + * Set the HW restart bit -- this is mostly true as we're + * going to load new firmware and reprogram that, though + * the reprogramming is going to be manual to avoid adding + * all the MACs that aren't support. + * We don't have to clear up everything though because the + * reprogramming is manual. When we resume, we'll actually + * go through a proper restart sequence again to switch + * back to the runtime firmware image. + */ + set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); + + /* We reprogram keys and shouldn't allocate new key indices */ + memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); + + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + + return iwl_mvm_load_d3_fw(mvm); +} + static int iwl_mvm_send_wowlan_config_cmd(struct iwl_mvm *mvm, const struct iwl_wowlan_config_cmd_v3 *cmd) @@ -797,116 +826,52 @@ iwl_mvm_send_wowlan_config_cmd(struct iwl_mvm *mvm, cmd_len, cmd); } -static int __iwl_mvm_suspend(struct ieee80211_hw *hw, - struct cfg80211_wowlan *wowlan, - bool test) +static int +iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, + struct cfg80211_wowlan *wowlan, + struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd, + struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif, + struct ieee80211_sta *ap_sta) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_d3_iter_data suspend_iter_data = { - .mvm = mvm, - }; - struct ieee80211_vif *vif; - struct iwl_mvm_vif *mvmvif; - struct ieee80211_sta *ap_sta; - struct iwl_mvm_sta *mvm_ap_sta; - struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; - struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; - struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; - struct iwl_d3_manager_config d3_cfg_cmd_data = { - /* - * Program the minimum sleep time to 10 seconds, as many - * platforms have issues processing a wakeup signal while - * still being in the process of suspending. - */ - .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), - }; - struct iwl_host_cmd d3_cfg_cmd = { - .id = D3_CONFIG_CMD, - .flags = CMD_WANT_SKB, - .data[0] = &d3_cfg_cmd_data, - .len[0] = sizeof(d3_cfg_cmd_data), - }; - struct wowlan_key_data key_data = { - .use_rsc_tsc = false, - .tkip = &tkip_cmd, - .use_tkip = false, - }; int ret; - int len __maybe_unused; - - if (!wowlan) { - /* - * mac80211 shouldn't get here, but for D3 test - * it doesn't warrant a warning - */ - WARN_ON(!test); - return -EINVAL; - } - - key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); - if (!key_data.rsc_tsc) - return -ENOMEM; - - mutex_lock(&mvm->mutex); - - /* see if there's only a single BSS vif and it's associated */ - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_iface_iterator, &suspend_iter_data); + struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; - if (suspend_iter_data.error || !suspend_iter_data.vif) { - ret = 1; - goto out_noreset; - } - - vif = suspend_iter_data.vif; - mvmvif = iwl_mvm_vif_from_mac80211(vif); - - ap_sta = rcu_dereference_protected( - mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], - lockdep_is_held(&mvm->mutex)); - if (IS_ERR_OR_NULL(ap_sta)) { - ret = -EINVAL; - goto out_noreset; - } + /* TODO: wowlan_config_cmd->common.wowlan_ba_teardown_tids */ - mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; - - /* TODO: wowlan_config_cmd.common.wowlan_ba_teardown_tids */ - - wowlan_config_cmd.common.is_11n_connection = + wowlan_config_cmd->common.is_11n_connection = ap_sta->ht_cap.ht_supported; /* Query the last used seqno and set it */ ret = iwl_mvm_get_last_nonqos_seq(mvm, vif); if (ret < 0) - goto out_noreset; - wowlan_config_cmd.common.non_qos_seq = cpu_to_le16(ret); + return ret; + + wowlan_config_cmd->common.non_qos_seq = cpu_to_le16(ret); - iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &wowlan_config_cmd.common); + iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &wowlan_config_cmd->common); if (wowlan->disconnect) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | IWL_WOWLAN_WAKEUP_LINK_CHANGE); if (wowlan->magic_pkt) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET); if (wowlan->gtk_rekey_failure) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL); if (wowlan->eap_identity_req) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ); if (wowlan->four_way_handshake) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE); if (wowlan->n_patterns) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); if (wowlan->rfkill_release) - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); if (wowlan->tcp) { @@ -914,44 +879,39 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * Set the "link change" (really "link lost") flag as well * since that implies losing the TCP connection. */ - wowlan_config_cmd.common.wakeup_filter |= + wowlan_config_cmd->common.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | IWL_WOWLAN_WAKEUP_LINK_CHANGE); } - iwl_mvm_cancel_scan(mvm); - - iwl_trans_stop_device(mvm->trans); - - /* - * Set the HW restart bit -- this is mostly true as we're - * going to load new firmware and reprogram that, though - * the reprogramming is going to be manual to avoid adding - * all the MACs that aren't support. - * We don't have to clear up everything though because the - * reprogramming is manual. When we resume, we'll actually - * go through a proper restart sequence again to switch - * back to the runtime firmware image. - */ - set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); - - /* We reprogram keys and shouldn't allocate new key indices */ - memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); - - mvm->ptk_ivlen = 0; - mvm->ptk_icvlen = 0; - mvm->ptk_ivlen = 0; - mvm->ptk_icvlen = 0; + return 0; +} - ret = iwl_mvm_load_d3_fw(mvm); - if (ret) - goto out; +static int +iwl_mvm_wowlan_config(struct iwl_mvm *mvm, + struct cfg80211_wowlan *wowlan, + struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd, + struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif, + struct ieee80211_sta *ap_sta) +{ + struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; + struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; + struct wowlan_key_data key_data = { + .use_rsc_tsc = false, + .tkip = &tkip_cmd, + .use_tkip = false, + }; + int ret; ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta); if (ret) - goto out; + return ret; + + key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); + if (!key_data.rsc_tsc) + return -ENOMEM; if (!iwlwifi_mod_params.sw_crypto) { /* @@ -1010,7 +970,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, } } - ret = iwl_mvm_send_wowlan_config_cmd(mvm, &wowlan_config_cmd); + ret = iwl_mvm_send_wowlan_config_cmd(mvm, wowlan_config_cmd); if (ret) goto out; @@ -1023,6 +983,84 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, goto out; ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); + +out: + kfree(key_data.rsc_tsc); + return ret; +} + +static int __iwl_mvm_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan, + bool test) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_d3_iter_data suspend_iter_data = { + .mvm = mvm, + }; + struct ieee80211_vif *vif = NULL; + struct iwl_mvm_vif *mvmvif = NULL; + struct ieee80211_sta *ap_sta = NULL; + struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; + struct iwl_d3_manager_config d3_cfg_cmd_data = { + /* + * Program the minimum sleep time to 10 seconds, as many + * platforms have issues processing a wakeup signal while + * still being in the process of suspending. + */ + .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), + }; + struct iwl_host_cmd d3_cfg_cmd = { + .id = D3_CONFIG_CMD, + .flags = CMD_WANT_SKB, + .data[0] = &d3_cfg_cmd_data, + .len[0] = sizeof(d3_cfg_cmd_data), + }; + int ret; + int len __maybe_unused; + + if (!wowlan) { + /* + * mac80211 shouldn't get here, but for D3 test + * it doesn't warrant a warning + */ + WARN_ON(!test); + return -EINVAL; + } + + mutex_lock(&mvm->mutex); + + /* see if there's only a single BSS vif and it's associated */ + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_d3_iface_iterator, &suspend_iter_data); + + if (suspend_iter_data.error || !suspend_iter_data.vif) { + ret = 1; + goto out_noreset; + } + + vif = suspend_iter_data.vif; + mvmvif = iwl_mvm_vif_from_mac80211(vif); + + ap_sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(ap_sta)) { + ret = -EINVAL; + goto out_noreset; + } + + ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd, vif, + mvmvif, ap_sta); + if (ret) + goto out_noreset; + + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + goto out; + + ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd, + vif, mvmvif, ap_sta); if (ret) goto out; @@ -1060,8 +1098,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, if (ret < 0) ieee80211_restart_hw(mvm->hw); out_noreset: - kfree(key_data.rsc_tsc); - mutex_unlock(&mvm->mutex); return ret; -- GitLab From 1e4d19ca6efba26964c9597b643a1dcda79ad296 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 22 Sep 2014 13:01:59 +0300 Subject: [PATCH 1960/9457] iwlwifi: mvm: move the check if associated outside of the iterator for wowlan Instead of checking if we are associated when suspending with wowlan enabled in the interface iterator, allow it to return an unassociated vif and move the check to the main suspend function. This will be needed by netdetect, since it should also work when we are not associated but the vif is active. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 48 ++++++++++++++------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index b8e8a97e002c..7a66a0903515 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -611,14 +611,10 @@ static void iwl_mvm_d3_iface_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { struct iwl_d3_iter_data *data = _data; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) return; - if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) - return; - if (data->vif) { IWL_ERR(data->mvm, "More than one managed interface active!\n"); data->error = true; @@ -1029,7 +1025,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); - /* see if there's only a single BSS vif and it's associated */ + /* see if there's only a single BSS vif */ ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_d3_iface_iterator, &suspend_iter_data); @@ -1042,27 +1038,33 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif = suspend_iter_data.vif; mvmvif = iwl_mvm_vif_from_mac80211(vif); - ap_sta = rcu_dereference_protected( - mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], - lockdep_is_held(&mvm->mutex)); - if (IS_ERR_OR_NULL(ap_sta)) { - ret = -EINVAL; - goto out_noreset; - } + /* if we're associated, this is wowlan */ + if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { + ap_sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(ap_sta)) { + ret = -EINVAL; + goto out_noreset; + } - ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd, vif, - mvmvif, ap_sta); - if (ret) - goto out_noreset; + ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd, + vif, mvmvif, ap_sta); + if (ret) + goto out_noreset; - ret = iwl_mvm_switch_to_d3(mvm); - if (ret) - goto out; + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + goto out; - ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd, - vif, mvmvif, ap_sta); - if (ret) - goto out; + ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd, + vif, mvmvif, ap_sta); + if (ret) + goto out; + } else { + ret = 1; + goto out_noreset; + } ret = iwl_mvm_power_update_device(mvm); if (ret) -- GitLab From b141c23581164bfa7eb5eb19c2f00cb303c70d3b Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 1 Oct 2014 13:22:40 +0300 Subject: [PATCH 1961/9457] iwlwifi: mvm: spin off a function to start scan offload The net-detect feature will require a scan offload to be started in the same way it is done now for scheduled scan. Spin a new function off of the sched_scan_start op code for reuse. Additionally, restructure the function a bit for more readability. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 ++--------------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ++++ drivers/net/wireless/iwlwifi/mvm/scan.c | 25 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 585fe5b7100f..b17877ce207f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2170,25 +2170,9 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, mvm->scan_status = IWL_MVM_SCAN_SCHED; - if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { - ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); - if (ret) - goto err; - } - - ret = iwl_mvm_config_sched_scan_profiles(mvm, req); + ret = iwl_mvm_scan_offload_start(mvm, vif, req, ies); if (ret) - goto err; - - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); - else - ret = iwl_mvm_sched_scan_start(mvm, req); - - if (!ret) - goto out; -err: - mvm->scan_status = IWL_MVM_SCAN_NONE; + mvm->scan_status = IWL_MVM_SCAN_NONE; out: mutex_unlock(&mvm->mutex); return ret; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index b153ced7015b..14ec67864bf2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -949,6 +949,10 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req); int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req); +int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_sched_scan_request *req, + struct ieee80211_scan_ies *ies); int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify); int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index b280d5d87127..64c02a274f76 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1007,6 +1007,31 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, sizeof(scan_req), &scan_req); } +int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_sched_scan_request *req, + struct ieee80211_scan_ies *ies) +{ + int ret; + + if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { + ret = iwl_mvm_config_sched_scan_profiles(mvm, req); + if (ret) + return ret; + ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); + } else { + ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); + if (ret) + return ret; + ret = iwl_mvm_config_sched_scan_profiles(mvm, req); + if (ret) + return ret; + ret = iwl_mvm_sched_scan_start(mvm, req); + } + + return ret; +} + static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm) { int ret; -- GitLab From 3c2f3b20e4a834f1d8ae34002b22f9021a861715 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 24 Sep 2014 08:29:11 +0300 Subject: [PATCH 1962/9457] iwlwifi: mvm: add debugfs entry to configure netdetect SSIDs Before we get all the chain (ie. mac80211, cfg80211, nl80211 and userspace) changed to support net-detect, we can use this debugfs entry for easy testing and as a proof of concept. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 9 ++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 122 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 + drivers/net/wireless/iwlwifi/mvm/ops.c | 7 ++ 4 files changed, 142 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 7a66a0903515..0b3295e3f6a6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1061,6 +1061,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif, mvmvif, ap_sta); if (ret) goto out; + } else if (mvm->nd_config) { + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + goto out; + + ret = iwl_mvm_scan_offload_start(mvm, vif, mvm->nd_config, + mvm->nd_ies); + if (ret) + goto out; } else { ret = 1; goto out_noreset; diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 50527a9bb267..2a61baca5081 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -1250,6 +1250,126 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, return ret; } + +#define MAX_NUM_ND_MATCHSETS 10 + +static ssize_t iwl_dbgfs_netdetect_write(struct iwl_mvm *mvm, char *buf, + size_t count, loff_t *ppos) +{ + const char *seps = ",\n"; + char *buf_ptr = buf; + char *value_str = NULL; + int ret, i; + + /* TODO: don't free if write is being called several times in one go */ + if (mvm->nd_config) { + kfree(mvm->nd_config->match_sets); + kfree(mvm->nd_config); + mvm->nd_config = NULL; + kfree(mvm->nd_ies); + mvm->nd_ies = NULL; + } + + mvm->nd_ies = kzalloc(sizeof(*mvm->nd_ies), GFP_KERNEL); + if (!mvm->nd_ies) + return -ENOMEM; + + mvm->nd_config = kzalloc(sizeof(*mvm->nd_config) + + (11 * sizeof(struct ieee80211_channel *)), + GFP_KERNEL); + if (!mvm->nd_config) { + ret = -ENOMEM; + goto out_free; + } + + mvm->nd_config->n_channels = 11; + mvm->nd_config->scan_width = NL80211_BSS_CHAN_WIDTH_20; + mvm->nd_config->interval = 5; + mvm->nd_config->min_rssi_thold = -80; + for (i = 0; i < mvm->nd_config->n_channels; i++) + mvm->nd_config->channels[i] = &mvm->nvm_data->channels[i]; + + mvm->nd_config->match_sets = + kcalloc(MAX_NUM_ND_MATCHSETS, + sizeof(*mvm->nd_config->match_sets), + GFP_KERNEL); + if (!mvm->nd_config->match_sets) { + ret = -ENOMEM; + goto out_free; + } + + while ((value_str = strsep(&buf_ptr, seps)) && + strlen(value_str)) { + struct cfg80211_match_set *set; + + if (mvm->nd_config->n_match_sets >= MAX_NUM_ND_MATCHSETS) { + ret = -EINVAL; + goto out_free; + } + + set = &mvm->nd_config->match_sets[mvm->nd_config->n_match_sets]; + set->ssid.ssid_len = strlen(value_str); + + if (set->ssid.ssid_len > IEEE80211_MAX_SSID_LEN) { + ret = -EINVAL; + goto out_free; + } + + memcpy(set->ssid.ssid, value_str, set->ssid.ssid_len); + + mvm->nd_config->n_match_sets++; + } + + ret = count; + + if (mvm->nd_config->n_match_sets) + goto out; + +out_free: + if (mvm->nd_config) + kfree(mvm->nd_config->match_sets); + kfree(mvm->nd_config); + mvm->nd_config = NULL; + kfree(mvm->nd_ies); + mvm->nd_ies = NULL; +out: + return ret; +} + +static ssize_t +iwl_dbgfs_netdetect_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + size_t bufsz, ret; + char *buf; + int i, n_match_sets, pos = 0; + + n_match_sets = mvm->nd_config ? mvm->nd_config->n_match_sets : 0; + + bufsz = n_match_sets * (IEEE80211_MAX_SSID_LEN + 1) + 1; + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (i = 0; i < n_match_sets; i++) { + if (pos + + mvm->nd_config->match_sets[i].ssid.ssid_len + 2 > bufsz) { + ret = -EIO; + goto out; + } + + memcpy(buf + pos, mvm->nd_config->match_sets[i].ssid.ssid, + mvm->nd_config->match_sets[i].ssid.ssid_len); + pos += mvm->nd_config->match_sets[i].ssid.ssid_len; + buf[pos++] = '\n'; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); +out: + kfree(buf); + return ret; +} #endif #define PRINT_MVM_REF(ref) do { \ @@ -1428,6 +1548,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); #ifdef CONFIG_PM_SLEEP MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8); +MVM_DEBUGFS_READ_WRITE_FILE_OPS(netdetect, 384); #endif int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) @@ -1487,6 +1608,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, mvm->debugfs_dir, &mvm->d3_wake_sysassert)) goto err; + MVM_DEBUGFS_ADD_FILE(netdetect, mvm->debugfs_dir, S_IRUSR | S_IWUSR); #endif if (!debugfs_create_u8("low_latency_agg_frame_limit", S_IRUSR | S_IWUSR, diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 14ec67864bf2..60aee625b966 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -659,6 +659,10 @@ struct iwl_mvm { #ifdef CONFIG_PM_SLEEP struct wiphy_wowlan_support wowlan; int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; + + /* sched scan settings for net detect */ + struct cfg80211_sched_scan_request *nd_config; + struct ieee80211_scan_ies *nd_ies; #ifdef CONFIG_IWLWIFI_DEBUGFS u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ bool d3_test_active; diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 48cb25a93591..047d83d8b25a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -594,6 +594,13 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) kfree(mvm->d3_resume_sram); + if (mvm->nd_config) { + kfree(mvm->nd_config->match_sets); + kfree(mvm->nd_config); + mvm->nd_config = NULL; + kfree(mvm->nd_ies); + mvm->nd_ies = NULL; + } #endif iwl_trans_op_mode_leave(mvm->trans); -- GitLab From 7f549e2c45ba216f629aad7c463c00a3fc1ec2ea Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 2 Oct 2014 15:38:04 +0300 Subject: [PATCH 1963/9457] iwlwifi: mvm: change the iwl_mvm_d3_iface_iterator into a generic function Getting the BSS station vif is something that may be needed by other parts of the code. So, instead of having an iterator specifically for d3, change it into a generic one in utils.c. Additionally, add a iwl_mvm_get_bss_vif() function to make it easier to retrieving it. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 47 ++---------------------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 + drivers/net/wireless/iwlwifi/mvm/utils.c | 37 +++++++++++++++++++ 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 0b3295e3f6a6..3bbb511b0b38 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -601,29 +601,6 @@ static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, return ret; } -struct iwl_d3_iter_data { - struct iwl_mvm *mvm; - struct ieee80211_vif *vif; - bool error; -}; - -static void iwl_mvm_d3_iface_iterator(void *_data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct iwl_d3_iter_data *data = _data; - - if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) - return; - - if (data->vif) { - IWL_ERR(data->mvm, "More than one managed interface active!\n"); - data->error = true; - return; - } - - data->vif = vif; -} - static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *ap_sta) { @@ -990,9 +967,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, bool test) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_d3_iter_data suspend_iter_data = { - .mvm = mvm, - }; struct ieee80211_vif *vif = NULL; struct iwl_mvm_vif *mvmvif = NULL; struct ieee80211_sta *ap_sta = NULL; @@ -1025,17 +999,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); - /* see if there's only a single BSS vif */ - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_iface_iterator, &suspend_iter_data); - - if (suspend_iter_data.error || !suspend_iter_data.vif) { + vif = iwl_mvm_get_bss_vif(mvm); + if (IS_ERR_OR_NULL(vif)) { ret = 1; goto out_noreset; } - vif = suspend_iter_data.vif; mvmvif = iwl_mvm_vif_from_mac80211(vif); /* if we're associated, this is wowlan */ @@ -1639,9 +1608,6 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac, static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) { - struct iwl_d3_iter_data resume_iter_data = { - .mvm = mvm, - }; struct ieee80211_vif *vif = NULL; int ret; enum iwl_d3_status d3_status; @@ -1650,15 +1616,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) mutex_lock(&mvm->mutex); /* get the BSS vif pointer again */ - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_iface_iterator, &resume_iter_data); - - if (WARN_ON(resume_iter_data.error || !resume_iter_data.vif)) + vif = iwl_mvm_get_bss_vif(mvm); + if (IS_ERR_OR_NULL(vif)) goto out_unlock; - vif = resume_iter_data.vif; - ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test); if (ret) goto out_unlock; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 60aee625b966..aec9f579f5a9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1214,6 +1214,8 @@ void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); + void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); #ifdef CONFIG_IWLWIFI_DEBUGFS void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 8021f6eec27f..e56e77ef5d2e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -734,3 +734,40 @@ bool iwl_mvm_is_idle(struct iwl_mvm *mvm) return idle; } + +struct iwl_bss_iter_data { + struct ieee80211_vif *vif; + bool error; +}; + +static void iwl_mvm_bss_iface_iterator(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_bss_iter_data *data = _data; + + if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) + return; + + if (data->vif) { + data->error = true; + return; + } + + data->vif = vif; +} + +struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm) +{ + struct iwl_bss_iter_data bss_iter_data = {}; + + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_bss_iface_iterator, &bss_iter_data); + + if (bss_iter_data.error) { + IWL_ERR(mvm, "More than one managed interface active!\n"); + return ERR_PTR(-EINVAL); + } + + return bss_iter_data.vif; +} -- GitLab From 77d96730db597ec82d78f3063daab2f17d14eff4 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 2 Sep 2014 16:04:58 +0200 Subject: [PATCH 1964/9457] iwlwifi: allow to restrict Tx aggregation size per-device A few slave bus devices show better performance when we reduce the size of the Tx A-MPDU. Signed-off-by: Gregory Greenman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-config.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 2ef83a39ff10..76d363d1a497 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -246,6 +246,7 @@ struct iwl_pwr_tx_backoff { * @nvm_hw_section_num: the ID of the HW NVM section * @pwr_tx_backoffs: translation table between power limits and backoffs * @max_rx_agg_size: max RX aggregation size of the ADDBA request/response + * @max_tx_agg_size: max TX aggregation size of the ADDBA request/response * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -285,6 +286,7 @@ struct iwl_cfg { const char *default_nvm_file; unsigned int max_rx_agg_size; bool disable_dummy_notification; + unsigned int max_tx_agg_size; }; /* diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 047d83d8b25a..91b28e869969 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -403,6 +403,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (cfg->max_rx_agg_size) hw->max_rx_aggregation_subframes = cfg->max_rx_agg_size; + if (cfg->max_tx_agg_size) + hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size; + op_mode = hw->priv; op_mode->ops = &iwl_mvm_ops; -- GitLab From 40a76905ad85903dc35ca9967056817e21a6d5d7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 18 Sep 2014 15:44:04 +0300 Subject: [PATCH 1965/9457] iwlwifi: pcie: warn if extern fw_debug buffer failed Otherwise we have no way to know that the buffer hasn't been allocated. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 3781b029e54a..5c9064fdbfda 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -133,7 +133,7 @@ static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans) break; } - if (!page) + if (WARN_ON_ONCE(!page)) return; trans_pcie->fw_mon_page = page; -- GitLab From a3ead6568c511d47b6cdc3d624ef0b4924e9dd27 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 12 Oct 2014 13:23:40 +0300 Subject: [PATCH 1966/9457] iwlwifi: pcie: fix recovery from ARC reset in WoWLAN When the ARC is reset when we exit from Sx in case we had WoWLAN running, we can't access the prph before we reset the NIC. Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5c9064fdbfda..aea0fe9d1779 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1023,14 +1023,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, return 0; } - iwl_pcie_set_pwr(trans, false); - - val = iwl_read32(trans, CSR_RESET); - if (val & CSR_RESET_REG_FLAG_NEVO_RESET) { - *status = IWL_D3_STATUS_RESET; - return 0; - } - /* * Also enables interrupts - none will happen as the device doesn't * know we're waking it up, only when the opmode actually tells it @@ -1050,6 +1042,8 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, return ret; } + iwl_pcie_set_pwr(trans, false); + iwl_trans_pcie_tx_reset(trans); ret = iwl_pcie_rx_init(trans); @@ -1058,7 +1052,12 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, return ret; } - *status = IWL_D3_STATUS_ALIVE; + val = iwl_read32(trans, CSR_RESET); + if (val & CSR_RESET_REG_FLAG_NEVO_RESET) + *status = IWL_D3_STATUS_RESET; + else + *status = IWL_D3_STATUS_ALIVE; + return 0; } -- GitLab From c7583d7dd62d44a5e930d67e7e6b881a569a5561 Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Mon, 29 Sep 2014 08:27:56 +0200 Subject: [PATCH 1967/9457] iwlwifi: always run the secured flow for family 8000 In the new format the "CSS section" has the same TLV type as the "mem section". So we need to run the secured flow for all the 8000 products. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-config.h | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-drv.c | 3 --- drivers/net/wireless/iwlwifi/iwl-fw.h | 1 - drivers/net/wireless/iwlwifi/pcie/trans.c | 10 ++++------ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 76d363d1a497..f8aa9cf08279 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -87,6 +87,16 @@ enum iwl_device_family { IWL_DEVICE_FAMILY_8000, }; +static inline bool iwl_has_secure_boot(u32 hw_rev, + enum iwl_device_family family) +{ + /* return 1 only for family 8000 B0 */ + if ((family == IWL_DEVICE_FAMILY_8000) && (hw_rev & 0xC)) + return 1; + + return 0; +} + /* * LED mode * IWL_LED_DEFAULT: use device default diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 0f1084f09caa..d9fa8e034da2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -807,19 +807,16 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, tlv_len); drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_REGULAR].is_secure = true; break; case IWL_UCODE_TLV_SECURE_SEC_INIT: iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, tlv_len); drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_INIT].is_secure = true; break; case IWL_UCODE_TLV_SECURE_SEC_WOWLAN: iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, tlv_len); drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_WOWLAN].is_secure = true; break; case IWL_UCODE_TLV_NUM_OF_CPU: if (tlv_len != sizeof(u32)) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 4f6e66892acc..6f7ae5f7bdae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -227,7 +227,6 @@ struct fw_desc { struct fw_img { struct fw_desc sec[IWL_UCODE_SECTION_MAX]; - bool is_secure; bool is_dual_cpus; }; diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index aea0fe9d1779..8027138c47e9 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -746,15 +746,12 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, int ret = 0; int first_ucode_section; - IWL_DEBUG_FW(trans, - "working with %s image\n", - image->is_secure ? "Secured" : "Non Secured"); IWL_DEBUG_FW(trans, "working with %s CPU\n", image->is_dual_cpus ? "Dual" : "Single"); /* configure the ucode to be ready to get the secured image */ - if (image->is_secure) { + if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { /* set secure boot inspector addresses */ iwl_write_prph(trans, LMPM_SECURE_INSPECTOR_CODE_ADDR, @@ -790,7 +787,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, LMPM_SECURE_CPU2_HDR_MEM_SPACE); /* load to FW the binary sections of CPU2 */ - if (image->is_secure) + if (iwl_has_secure_boot(trans->hw_rev, + trans->cfg->device_family)) ret = iwl_pcie_load_cpu_secured_sections( trans, image, 2, &first_ucode_section); @@ -821,7 +819,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, else iwl_write32(trans, CSR_RESET, 0); - if (image->is_secure) { + if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { /* wait for image verification to complete */ ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR, -- GitLab From f3b2098d98d88a8137f795cbd5c58be90632f548 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 7 Oct 2014 14:44:18 +0300 Subject: [PATCH 1968/9457] iwlwifi: mvm: BT Coex - move BT_ANTENNA_COUPLING_THRESHOLD to constants This is were it really needs to be. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 4 +--- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 5 ++--- drivers/net/wireless/iwlwifi/mvm/constants.h | 1 + 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index da2ffb785194..515f9cbcf289 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -72,8 +72,6 @@ #include "mvm.h" #include "iwl-debug.h" -#define BT_ANTENNA_COUPLING_THRESHOLD (30) - const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX] = { [BT_KILL_MSK_DEFAULT] = 0xfffffc00, [BT_KILL_MSK_NEVER] = 0xffffffff, @@ -605,7 +603,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) bt_cmd->max_kill = cpu_to_le32(5); bt_cmd->bt4_antenna_isolation_thr = - cpu_to_le32(BT_ANTENNA_COUPLING_THRESHOLD); + cpu_to_le32(IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS); bt_cmd->bt4_tx_tx_delta_freq_thr = cpu_to_le32(15); bt_cmd->bt4_tx_rx_max_freq0 = cpu_to_le32(15); bt_cmd->override_primary_lut = cpu_to_le32(BT_COEX_INVALID_LUT); diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index 8a1d2f33d5b7..3f3b8ee51b1c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -102,8 +102,6 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { #undef EVENT_PRIO_ANT -#define BT_ANTENNA_COUPLING_THRESHOLD (30) - static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) { if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) @@ -593,7 +591,8 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm) } bt_cmd->max_kill = 5; - bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD; + bt_cmd->bt4_antenna_isolation_thr = + IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS; bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling; bt_cmd->bt4_tx_tx_delta_freq_thr = 15; bt_cmd->bt4_tx_rx_max_freq0 = 15; diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index dfec5b5e7e14..f2887838cd39 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -96,5 +96,6 @@ #define IWL_MVM_QUOTA_THRESHOLD 8 #define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 #define IWL_MVM_RS_DISABLE_MIMO 0 +#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 #endif /* __MVM_CONSTANTS_H */ -- GitLab From 3b8983b17c78f08e40e1ddc8051bdf839097ba27 Mon Sep 17 00:00:00 2001 From: Max Stepanov Date: Wed, 15 Oct 2014 11:27:16 +0300 Subject: [PATCH 1969/9457] iwlwifi: mvm: add MVM_FW_BCAST_FILTER_PASS_ALL option The MVM_FW_BCAST_FILTER_PASS_ALL option defined in iwl-dbg-cfg.ini configuration file allows to enable/disable FW broadcast filtering. If MVM_FW_BCAST_FILTER_PASS_ALL is not defined in iwl-dbg-cfg.ini or its value is 0, the mvm broadcast filtering is enabled. Setting MVM_FW_BCAST_FILTER_PASS_ALL=1 in iwl-dbg-cfg.ini blocks sending of BCAST_FILTER_CMD to FW. Signed-off-by: Max Stepanov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/constants.h | 3 ++- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index f2887838cd39..a2b473d50362 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -92,10 +92,11 @@ #define IWL_MVM_BT_COEX_SYNC2SCO 1 #define IWL_MVM_BT_COEX_CORUNNING 0 #define IWL_MVM_BT_COEX_MPLUT 1 +#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 +#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 #define IWL_MVM_QUOTA_THRESHOLD 8 #define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 #define IWL_MVM_RS_DISABLE_MIMO 0 -#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 #endif /* __MVM_CONSTANTS_H */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index b17877ce207f..9fc843e6dd2a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1382,6 +1382,9 @@ bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm, .cmd = cmd, }; + if (IWL_MVM_FW_BCAST_FILTER_PASS_ALL) + return false; + memset(cmd, 0, sizeof(*cmd)); cmd->max_bcast_filters = ARRAY_SIZE(cmd->filters); cmd->max_macs = ARRAY_SIZE(cmd->macs); -- GitLab From d92b732e35432d473d18b068597a6220a10e9a96 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 21 Sep 2014 19:00:42 +0300 Subject: [PATCH 1970/9457] iwlwifi: mvm: remove mvm argument from get_queues_mask It is unused and won't be available in some future invocations of the function. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 5 ++--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +-- drivers/net/wireless/iwlwifi/mvm/sta.c | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 0c5c0b0e23f5..b8ab4a108720 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -197,8 +197,7 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, /* * Get the mask of the queues used by the vif */ -u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) +u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif) { u32 qmask = 0, ac; @@ -227,7 +226,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, } /* Mark the queues used by the vif */ - data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif); + data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif); /* Mark MAC IDs as used by clearing the available bit, and * (below) mark TSFs as used if their existing use is not diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 9fc843e6dd2a..c087bf69d290 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1086,7 +1086,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { - u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif); + u32 tfd_msk = iwl_mvm_mac_get_queues_mask(vif); if (tfd_msk) { mutex_lock(&mvm->mutex); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index aec9f579f5a9..d14dc061d1c2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -909,8 +909,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool force_assoc_off, const u8 *bssid_override); int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); -u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, - struct ieee80211_vif *vif); +u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif); int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 1731c205c81d..dd0dc5bf8583 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -609,7 +609,7 @@ int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) lockdep_assert_held(&mvm->mutex); - qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); + qmask = iwl_mvm_mac_get_queues_mask(vif); /* * The firmware defines the TFD queue mask to only be relevant -- GitLab From ee00aed175e64c570e9da7052e39cdcc4ec822af Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 19 Oct 2014 14:18:14 +0300 Subject: [PATCH 1971/9457] iwlwifi: mvm: BT Coex - make the multiprio lut a constant This makes it easier to tune the values during the testing. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 9 ++------- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 9 ++------- drivers/net/wireless/iwlwifi/mvm/constants.h | 2 ++ 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 515f9cbcf289..508c81359e41 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -300,11 +300,6 @@ static const __le64 iwl_ci_mask[][3] = { }, }; -static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = { - cpu_to_le32(0x2e402280), - cpu_to_le32(0x7711a751), -}; - struct corunning_block_luts { u8 range; __le32 lut20[BT_COEX_CORUN_LUT_SIZE]; @@ -636,8 +631,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) memcpy(&bt_cmd->mplut_prio_boost, iwl_bt_prio_boost, sizeof(iwl_bt_prio_boost)); - memcpy(&bt_cmd->multiprio_lut, iwl_bt_mprio_lut, - sizeof(iwl_bt_mprio_lut)); + bt_cmd->multiprio_lut[0] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG0); + bt_cmd->multiprio_lut[1] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG1); send_cmd: memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index 3f3b8ee51b1c..b571e1b0550c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -288,11 +288,6 @@ static const __le64 iwl_ci_mask[][3] = { }, }; -static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = { - cpu_to_le32(0x2e402280), - cpu_to_le32(0x7711a751), -}; - struct corunning_block_luts { u8 range; __le32 lut20[BT_COEX_CORUN_LUT_SIZE]; @@ -648,8 +643,8 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm) memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost, sizeof(iwl_bt_prio_boost)); - memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut, - sizeof(iwl_bt_mprio_lut)); + bt_cmd->bt4_multiprio_lut[0] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG0); + bt_cmd->bt4_multiprio_lut[1] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG1); send_cmd: memset(&mvm->last_bt_notif_old, 0, sizeof(mvm->last_bt_notif_old)); diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index a2b473d50362..5c1ea80d5e3b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -92,6 +92,8 @@ #define IWL_MVM_BT_COEX_SYNC2SCO 1 #define IWL_MVM_BT_COEX_CORUNNING 0 #define IWL_MVM_BT_COEX_MPLUT 1 +#define IWL_MVM_BT_COEX_MPLUT_REG0 0x2e402280 +#define IWL_MVM_BT_COEX_MPLUT_REG1 0x7711a751 #define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 #define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 -- GitLab From f85e9d19d451b9cc3b0381a9422320f9b630441c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 8 Oct 2014 09:57:29 +0200 Subject: [PATCH 1972/9457] iwlwifi: mvm: improve MCS rate warning The warning gives no information about the frame, and presents the flags so that one might think they're the frame. Clarify and add more information. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index c6a517c771df..8d848735cdb8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -189,8 +189,10 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, /* HT rate doesn't make sense for a non data frame */ WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS, - "Got an HT rate for a non data frame 0x%x\n", - info->control.rates[0].flags); + "Got an HT rate (flags:0x%x/mcs:%d) for a non data frame (fc:0x%x)\n", + info->control.rates[0].flags, + info->control.rates[0].idx, + le16_to_cpu(fc)); rate_idx = info->control.rates[0].idx; /* if the rate isn't a well known legacy rate, take the lowest one */ -- GitLab From 480acbcee4e25ea3af0df3c0423dc29540551258 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 10 Oct 2014 08:59:27 +0200 Subject: [PATCH 1973/9457] iwlwifi: mvm: flush queues without mutex held For WMM-AC we may have to be changing QoS parameters while the queues are being flushed. This is not relevant in the "drop" case, but matters when we wait for the device to finish the transmissions. To allow this, do the actual waiting without holding the mutex. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c087bf69d290..14be10829510 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2997,18 +2997,24 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, mvmvif = iwl_mvm_vif_from_mac80211(vif); mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id); - if (WARN_ON_ONCE(!mvmsta)) - goto done; + if (WARN_ON_ONCE(!mvmsta)) { + mutex_unlock(&mvm->mutex); + return; + } if (drop) { if (iwl_mvm_flush_tx_path(mvm, mvmsta->tfd_queue_msk, true)) IWL_ERR(mvm, "flush request fail\n"); + mutex_unlock(&mvm->mutex); } else { - iwl_trans_wait_tx_queue_empty(mvm->trans, - mvmsta->tfd_queue_msk); + u32 tfd_queue_msk = mvmsta->tfd_queue_msk; + mutex_unlock(&mvm->mutex); + + /* this can take a while, and we may need/want other operations + * to succeed while doing this, so do it without the mutex held + */ + iwl_trans_wait_tx_queue_empty(mvm->trans, tfd_queue_msk); } -done: - mutex_unlock(&mvm->mutex); } const struct ieee80211_ops iwl_mvm_hw_ops = { -- GitLab From 7ae83d00825b39347b9a591703cd7cc3163523fb Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 10 Oct 2014 10:03:02 +0300 Subject: [PATCH 1974/9457] iwlwifi: mvm: remove unnecessary includes in tt.c We used to need to include some headers in order to read the registers and do all the calculations by ourselves, but this is not done anymore (i.e. we let the firmware do this for us), so we don't need to include those headers anymore. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/tt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index acca44a45086..d4f2c29025c7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c @@ -64,10 +64,6 @@ *****************************************************************************/ #include "mvm.h" -#include "iwl-config.h" -#include "iwl-io.h" -#include "iwl-csr.h" -#include "iwl-prph.h" #define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ -- GitLab From 50f6635afe565a0e1c5ab78f040294fe1dc41de0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 26 Oct 2014 22:25:03 -0700 Subject: [PATCH 1975/9457] iwlwifi: dvm: Fix probable mask then right shift defect Precedence of & and >> is not the same and is not left to right. shift has higher precedence and should be done after the mask. Add parentheses around the mask. Signed-off-by: Joe Perches Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/dvm/lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 2191621d69c1..02e4ede2b042 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -418,8 +418,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) static bool iwlagn_bt_traffic_is_sco(struct iwl_bt_uart_msg *uart_msg) { - return BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3 >> - BT_UART_MSG_FRAME3SCOESCO_POS; + return (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SCOESCO_POS; } static void iwlagn_bt_traffic_change_work(struct work_struct *work) -- GitLab From b260362ab70f5a37179192465f901b9729718cbc Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Thu, 23 Oct 2014 15:30:47 +0300 Subject: [PATCH 1976/9457] iwlwifi: enable STBC support for 8000 chips These chips support STBC in both Tx and Rx. Given that we've added STBC Tx support enable it. Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-8000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index d2b7234b1c73..896ea906549c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -104,6 +104,7 @@ static const struct iwl_base_params iwl8000_base_params = { }; static const struct iwl_ht_params iwl8000_ht_params = { + .stbc = true, .ldpc = true, .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; -- GitLab From 7077148fb50a120d20a50516a332ed6eb9233c16 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 28 Oct 2014 22:15:31 +0000 Subject: [PATCH 1977/9457] ASoC: core: Split ops out of soc-core.c The main ASoC source file is getting quite large and the standard ops don't really have anything to do with the rest of the file so split them out into a separate file. Signed-off-by: Mark Brown --- sound/soc/Makefile | 2 +- sound/soc/soc-core.c | 919 ----------------------------------------- sound/soc/soc-ops.c | 952 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 953 insertions(+), 920 deletions(-) create mode 100644 sound/soc/soc-ops.c diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 534714a1ca44..a384d145e4d2 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -1,5 +1,5 @@ snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o -snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o +snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-objs += soc-generic-dmaengine-pcm.o diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 47c378abb9a2..a2b51edf6d83 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2333,925 +2333,6 @@ int snd_soc_add_dai_controls(struct snd_soc_dai *dai, } EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls); -/** - * snd_soc_info_enum_double - enumerated double mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a double enumerated - * mixer control. - * - * Returns 0 for success. - */ -int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, - e->items, e->texts); -} -EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); - -/** - * snd_soc_get_enum_double - enumerated double mixer get callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value of a double enumerated mixer. - * - * Returns 0 for success. - */ -int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int val, item; - unsigned int reg_val; - int ret; - - ret = snd_soc_component_read(component, e->reg, ®_val); - if (ret) - return ret; - val = (reg_val >> e->shift_l) & e->mask; - item = snd_soc_enum_val_to_item(e, val); - ucontrol->value.enumerated.item[0] = item; - if (e->shift_l != e->shift_r) { - val = (reg_val >> e->shift_l) & e->mask; - item = snd_soc_enum_val_to_item(e, val); - ucontrol->value.enumerated.item[1] = item; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); - -/** - * snd_soc_put_enum_double - enumerated double mixer put callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to set the value of a double enumerated mixer. - * - * Returns 0 for success. - */ -int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int *item = ucontrol->value.enumerated.item; - unsigned int val; - unsigned int mask; - - if (item[0] >= e->items) - return -EINVAL; - val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; - mask = e->mask << e->shift_l; - if (e->shift_l != e->shift_r) { - if (item[1] >= e->items) - return -EINVAL; - val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; - mask |= e->mask << e->shift_r; - } - - return snd_soc_component_update_bits(component, e->reg, mask, val); -} -EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); - -/** - * snd_soc_read_signed - Read a codec register and interprete as signed value - * @component: component - * @reg: Register to read - * @mask: Mask to use after shifting the register value - * @shift: Right shift of register value - * @sign_bit: Bit that describes if a number is negative or not. - * @signed_val: Pointer to where the read value should be stored - * - * This functions reads a codec register. The register value is shifted right - * by 'shift' bits and masked with the given 'mask'. Afterwards it translates - * the given registervalue into a signed integer if sign_bit is non-zero. - * - * Returns 0 on sucess, otherwise an error value - */ -static int snd_soc_read_signed(struct snd_soc_component *component, - unsigned int reg, unsigned int mask, unsigned int shift, - unsigned int sign_bit, int *signed_val) -{ - int ret; - unsigned int val; - - ret = snd_soc_component_read(component, reg, &val); - if (ret < 0) - return ret; - - val = (val >> shift) & mask; - - if (!sign_bit) { - *signed_val = val; - return 0; - } - - /* non-negative number */ - if (!(val & BIT(sign_bit))) { - *signed_val = val; - return 0; - } - - ret = val; - - /* - * The register most probably does not contain a full-sized int. - * Instead we have an arbitrary number of bits in a signed - * representation which has to be translated into a full-sized int. - * This is done by filling up all bits above the sign-bit. - */ - ret |= ~((int)(BIT(sign_bit) - 1)); - - *signed_val = ret; - - return 0; -} - -/** - * snd_soc_info_volsw - single mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a single mixer control, or a double - * mixer control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int platform_max; - - if (!mc->platform_max) - mc->platform_max = mc->max; - platform_max = mc->platform_max; - - if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - else - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = platform_max - mc->min; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw); - -/** - * snd_soc_get_volsw - single mixer get callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value of a single mixer control, or a double mixer - * control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; - int sign_bit = mc->sign_bit; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; - int val; - int ret; - - if (sign_bit) - mask = BIT(sign_bit + 1) - 1; - - ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); - if (ret) - return ret; - - ucontrol->value.integer.value[0] = val - min; - if (invert) - ucontrol->value.integer.value[0] = - max - ucontrol->value.integer.value[0]; - - if (snd_soc_volsw_is_stereo(mc)) { - if (reg == reg2) - ret = snd_soc_read_signed(component, reg, mask, rshift, - sign_bit, &val); - else - ret = snd_soc_read_signed(component, reg2, mask, shift, - sign_bit, &val); - if (ret) - return ret; - - ucontrol->value.integer.value[1] = val - min; - if (invert) - ucontrol->value.integer.value[1] = - max - ucontrol->value.integer.value[1]; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw); - -/** - * snd_soc_put_volsw - single mixer put callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to set the value of a single mixer control, or a double mixer - * control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; - unsigned int sign_bit = mc->sign_bit; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; - int err; - bool type_2r = false; - unsigned int val2 = 0; - unsigned int val, val_mask; - - if (sign_bit) - mask = BIT(sign_bit + 1) - 1; - - val = ((ucontrol->value.integer.value[0] + min) & mask); - if (invert) - val = max - val; - val_mask = mask << shift; - val = val << shift; - if (snd_soc_volsw_is_stereo(mc)) { - val2 = ((ucontrol->value.integer.value[1] + min) & mask); - if (invert) - val2 = max - val2; - if (reg == reg2) { - val_mask |= mask << rshift; - val |= val2 << rshift; - } else { - val2 = val2 << shift; - type_2r = true; - } - } - err = snd_soc_component_update_bits(component, reg, val_mask, val); - if (err < 0) - return err; - - if (type_2r) - err = snd_soc_component_update_bits(component, reg2, val_mask, - val2); - - return err; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw); - -/** - * snd_soc_get_volsw_sx - single mixer get callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value of a single mixer control, or a double mixer - * control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; - int mask = (1 << (fls(min + max) - 1)) - 1; - unsigned int val; - int ret; - - ret = snd_soc_component_read(component, reg, &val); - if (ret < 0) - return ret; - - ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; - - if (snd_soc_volsw_is_stereo(mc)) { - ret = snd_soc_component_read(component, reg2, &val); - if (ret < 0) - return ret; - - val = ((val >> rshift) - min) & mask; - ucontrol->value.integer.value[1] = val; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); - -/** - * snd_soc_put_volsw_sx - double mixer set callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a double mixer control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; - int mask = (1 << (fls(min + max) - 1)) - 1; - int err = 0; - unsigned int val, val_mask, val2 = 0; - - val_mask = mask << shift; - val = (ucontrol->value.integer.value[0] + min) & mask; - val = val << shift; - - err = snd_soc_component_update_bits(component, reg, val_mask, val); - if (err < 0) - return err; - - if (snd_soc_volsw_is_stereo(mc)) { - val_mask = mask << rshift; - val2 = (ucontrol->value.integer.value[1] + min) & mask; - val2 = val2 << rshift; - - err = snd_soc_component_update_bits(component, reg2, val_mask, - val2); - } - return err; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); - -/** - * snd_soc_info_volsw_range - single mixer info callback with range. - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information, within a range, about a single - * mixer control. - * - * returns 0 for success. - */ -int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int platform_max; - int min = mc->min; - - if (!mc->platform_max) - mc->platform_max = mc->max; - platform_max = mc->platform_max; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = platform_max - min; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); - -/** - * snd_soc_put_volsw_range - single mixer put value callback with range. - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to set the value, within a range, for a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - int min = mc->min; - int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; - unsigned int val, val_mask; - int ret; - - if (invert) - val = (max - ucontrol->value.integer.value[0]) & mask; - else - val = ((ucontrol->value.integer.value[0] + min) & mask); - val_mask = mask << shift; - val = val << shift; - - ret = snd_soc_component_update_bits(component, reg, val_mask, val); - if (ret < 0) - return ret; - - if (snd_soc_volsw_is_stereo(mc)) { - if (invert) - val = (max - ucontrol->value.integer.value[1]) & mask; - else - val = ((ucontrol->value.integer.value[1] + min) & mask); - val_mask = mask << shift; - val = val << shift; - - ret = snd_soc_component_update_bits(component, rreg, val_mask, - val); - } - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); - -/** - * snd_soc_get_volsw_range - single mixer get callback with range - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value, within a range, of a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - int min = mc->min; - int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; - unsigned int invert = mc->invert; - unsigned int val; - int ret; - - ret = snd_soc_component_read(component, reg, &val); - if (ret) - return ret; - - ucontrol->value.integer.value[0] = (val >> shift) & mask; - if (invert) - ucontrol->value.integer.value[0] = - max - ucontrol->value.integer.value[0]; - else - ucontrol->value.integer.value[0] = - ucontrol->value.integer.value[0] - min; - - if (snd_soc_volsw_is_stereo(mc)) { - ret = snd_soc_component_read(component, rreg, &val); - if (ret) - return ret; - - ucontrol->value.integer.value[1] = (val >> shift) & mask; - if (invert) - ucontrol->value.integer.value[1] = - max - ucontrol->value.integer.value[1]; - else - ucontrol->value.integer.value[1] = - ucontrol->value.integer.value[1] - min; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); - -/** - * snd_soc_limit_volume - Set new limit to an existing volume control. - * - * @codec: where to look for the control - * @name: Name of the control - * @max: new maximum limit - * - * Return 0 for success, else error. - */ -int snd_soc_limit_volume(struct snd_soc_codec *codec, - const char *name, int max) -{ - struct snd_card *card = codec->component.card->snd_card; - struct snd_kcontrol *kctl; - struct soc_mixer_control *mc; - int found = 0; - int ret = -EINVAL; - - /* Sanity check for name and max */ - if (unlikely(!name || max <= 0)) - return -EINVAL; - - list_for_each_entry(kctl, &card->controls, list) { - if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) { - found = 1; - break; - } - } - if (found) { - mc = (struct soc_mixer_control *)kctl->private_value; - if (max <= mc->max) { - mc->platform_max = max; - ret = 0; - } - } - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_limit_volume); - -int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_bytes *params = (void *)kcontrol->private_value; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = params->num_regs * component->val_bytes; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_bytes_info); - -int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_bytes *params = (void *)kcontrol->private_value; - int ret; - - if (component->regmap) - ret = regmap_raw_read(component->regmap, params->base, - ucontrol->value.bytes.data, - params->num_regs * component->val_bytes); - else - ret = -EINVAL; - - /* Hide any masked bytes to ensure consistent data reporting */ - if (ret == 0 && params->mask) { - switch (component->val_bytes) { - case 1: - ucontrol->value.bytes.data[0] &= ~params->mask; - break; - case 2: - ((u16 *)(&ucontrol->value.bytes.data))[0] - &= cpu_to_be16(~params->mask); - break; - case 4: - ((u32 *)(&ucontrol->value.bytes.data))[0] - &= cpu_to_be32(~params->mask); - break; - default: - return -EINVAL; - } - } - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_bytes_get); - -int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_bytes *params = (void *)kcontrol->private_value; - int ret, len; - unsigned int val, mask; - void *data; - - if (!component->regmap || !params->num_regs) - return -EINVAL; - - len = params->num_regs * component->val_bytes; - - data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); - if (!data) - return -ENOMEM; - - /* - * If we've got a mask then we need to preserve the register - * bits. We shouldn't modify the incoming data so take a - * copy. - */ - if (params->mask) { - ret = regmap_read(component->regmap, params->base, &val); - if (ret != 0) - goto out; - - val &= params->mask; - - switch (component->val_bytes) { - case 1: - ((u8 *)data)[0] &= ~params->mask; - ((u8 *)data)[0] |= val; - break; - case 2: - mask = ~params->mask; - ret = regmap_parse_val(component->regmap, - &mask, &mask); - if (ret != 0) - goto out; - - ((u16 *)data)[0] &= mask; - - ret = regmap_parse_val(component->regmap, - &val, &val); - if (ret != 0) - goto out; - - ((u16 *)data)[0] |= val; - break; - case 4: - mask = ~params->mask; - ret = regmap_parse_val(component->regmap, - &mask, &mask); - if (ret != 0) - goto out; - - ((u32 *)data)[0] &= mask; - - ret = regmap_parse_val(component->regmap, - &val, &val); - if (ret != 0) - goto out; - - ((u32 *)data)[0] |= val; - break; - default: - ret = -EINVAL; - goto out; - } - } - - ret = regmap_raw_write(component->regmap, params->base, - data, len); - -out: - kfree(data); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_bytes_put); - -int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *ucontrol) -{ - struct soc_bytes_ext *params = (void *)kcontrol->private_value; - - ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; - ucontrol->count = params->max; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); - -int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, - unsigned int size, unsigned int __user *tlv) -{ - struct soc_bytes_ext *params = (void *)kcontrol->private_value; - unsigned int count = size < params->max ? size : params->max; - int ret = -ENXIO; - - switch (op_flag) { - case SNDRV_CTL_TLV_OP_READ: - if (params->get) - ret = params->get(tlv, count); - break; - case SNDRV_CTL_TLV_OP_WRITE: - if (params->put) - ret = params->put(tlv, count); - break; - } - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); - -/** - * snd_soc_info_xr_sx - signed multi register info callback - * @kcontrol: mreg control - * @uinfo: control element information - * - * Callback to provide information of a control that can - * span multiple codec registers which together - * forms a single signed value in a MSB/LSB manner. - * - * Returns 0 for success. - */ -int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_mreg_control *mc = - (struct soc_mreg_control *)kcontrol->private_value; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = mc->min; - uinfo->value.integer.max = mc->max; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); - -/** - * snd_soc_get_xr_sx - signed multi register get callback - * @kcontrol: mreg control - * @ucontrol: control element information - * - * Callback to get the value of a control that can span - * multiple codec registers which together forms a single - * signed value in a MSB/LSB manner. The control supports - * specifying total no of bits used to allow for bitfields - * across the multiple codec registers. - * - * Returns 0 for success. - */ -int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mreg_control *mc = - (struct soc_mreg_control *)kcontrol->private_value; - unsigned int regbase = mc->regbase; - unsigned int regcount = mc->regcount; - unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1<invert; - unsigned long mask = (1UL<nbits)-1; - long min = mc->min; - long max = mc->max; - long val = 0; - unsigned int regval; - unsigned int i; - int ret; - - for (i = 0; i < regcount; i++) { - ret = snd_soc_component_read(component, regbase+i, ®val); - if (ret) - return ret; - val |= (regval & regwmask) << (regwshift*(regcount-i-1)); - } - val &= mask; - if (min < 0 && val > max) - val |= ~mask; - if (invert) - val = max - val; - ucontrol->value.integer.value[0] = val; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); - -/** - * snd_soc_put_xr_sx - signed multi register get callback - * @kcontrol: mreg control - * @ucontrol: control element information - * - * Callback to set the value of a control that can span - * multiple codec registers which together forms a single - * signed value in a MSB/LSB manner. The control supports - * specifying total no of bits used to allow for bitfields - * across the multiple codec registers. - * - * Returns 0 for success. - */ -int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mreg_control *mc = - (struct soc_mreg_control *)kcontrol->private_value; - unsigned int regbase = mc->regbase; - unsigned int regcount = mc->regcount; - unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1<invert; - unsigned long mask = (1UL<nbits)-1; - long max = mc->max; - long val = ucontrol->value.integer.value[0]; - unsigned int i, regval, regmask; - int err; - - if (invert) - val = max - val; - val &= mask; - for (i = 0; i < regcount; i++) { - regval = (val >> (regwshift*(regcount-i-1))) & regwmask; - regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; - err = snd_soc_component_update_bits(component, regbase+i, - regmask, regval); - if (err < 0) - return err; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); - -/** - * snd_soc_get_strobe - strobe get callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback get the value of a strobe mixer control. - * - * Returns 0 for success. - */ -int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int shift = mc->shift; - unsigned int mask = 1 << shift; - unsigned int invert = mc->invert != 0; - unsigned int val; - int ret; - - ret = snd_soc_component_read(component, reg, &val); - if (ret) - return ret; - - val &= mask; - - if (shift != 0 && val != 0) - val = val >> shift; - ucontrol->value.enumerated.item[0] = val ^ invert; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_strobe); - -/** - * snd_soc_put_strobe - strobe put callback - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback strobe a register bit to high then low (or the inverse) - * in one pass of a single mixer enum control. - * - * Returns 1 for success. - */ -int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int shift = mc->shift; - unsigned int mask = 1 << shift; - unsigned int invert = mc->invert != 0; - unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; - unsigned int val1 = (strobe ^ invert) ? mask : 0; - unsigned int val2 = (strobe ^ invert) ? 0 : mask; - int err; - - err = snd_soc_component_update_bits(component, reg, mask, val1); - if (err < 0) - return err; - - return snd_soc_component_update_bits(component, reg, mask, val2); -} -EXPORT_SYMBOL_GPL(snd_soc_put_strobe); - /** * snd_soc_dai_set_sysclk - configure DAI system or master clock. * @dai: DAI diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c new file mode 100644 index 000000000000..100d92b5b77e --- /dev/null +++ b/sound/soc/soc-ops.c @@ -0,0 +1,952 @@ +/* + * soc-ops.c -- Generic ASoC operations + * + * Copyright 2005 Wolfson Microelectronics PLC. + * Copyright 2005 Openedhand Ltd. + * Copyright (C) 2010 Slimlogic Ltd. + * Copyright (C) 2010 Texas Instruments Inc. + * + * Author: Liam Girdwood + * with code, comments and ideas from :- + * Richard Purdie + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * snd_soc_info_enum_double - enumerated double mixer info callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information about a double enumerated + * mixer control. + * + * Returns 0 for success. + */ +int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + + return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, + e->items, e->texts); +} +EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); + +/** + * snd_soc_get_enum_double - enumerated double mixer get callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to get the value of a double enumerated mixer. + * + * Returns 0 for success. + */ +int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val, item; + unsigned int reg_val; + int ret; + + ret = snd_soc_component_read(component, e->reg, ®_val); + if (ret) + return ret; + val = (reg_val >> e->shift_l) & e->mask; + item = snd_soc_enum_val_to_item(e, val); + ucontrol->value.enumerated.item[0] = item; + if (e->shift_l != e->shift_r) { + val = (reg_val >> e->shift_l) & e->mask; + item = snd_soc_enum_val_to_item(e, val); + ucontrol->value.enumerated.item[1] = item; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); + +/** + * snd_soc_put_enum_double - enumerated double mixer put callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to set the value of a double enumerated mixer. + * + * Returns 0 for success. + */ +int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + unsigned int val; + unsigned int mask; + + if (item[0] >= e->items) + return -EINVAL; + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + mask = e->mask << e->shift_l; + if (e->shift_l != e->shift_r) { + if (item[1] >= e->items) + return -EINVAL; + val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; + mask |= e->mask << e->shift_r; + } + + return snd_soc_component_update_bits(component, e->reg, mask, val); +} +EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); + +/** + * snd_soc_read_signed - Read a codec register and interprete as signed value + * @component: component + * @reg: Register to read + * @mask: Mask to use after shifting the register value + * @shift: Right shift of register value + * @sign_bit: Bit that describes if a number is negative or not. + * @signed_val: Pointer to where the read value should be stored + * + * This functions reads a codec register. The register value is shifted right + * by 'shift' bits and masked with the given 'mask'. Afterwards it translates + * the given registervalue into a signed integer if sign_bit is non-zero. + * + * Returns 0 on sucess, otherwise an error value + */ +static int snd_soc_read_signed(struct snd_soc_component *component, + unsigned int reg, unsigned int mask, unsigned int shift, + unsigned int sign_bit, int *signed_val) +{ + int ret; + unsigned int val; + + ret = snd_soc_component_read(component, reg, &val); + if (ret < 0) + return ret; + + val = (val >> shift) & mask; + + if (!sign_bit) { + *signed_val = val; + return 0; + } + + /* non-negative number */ + if (!(val & BIT(sign_bit))) { + *signed_val = val; + return 0; + } + + ret = val; + + /* + * The register most probably does not contain a full-sized int. + * Instead we have an arbitrary number of bits in a signed + * representation which has to be translated into a full-sized int. + * This is done by filling up all bits above the sign-bit. + */ + ret |= ~((int)(BIT(sign_bit) - 1)); + + *signed_val = ret; + + return 0; +} + +/** + * snd_soc_info_volsw - single mixer info callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information about a single mixer control, or a double + * mixer control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int platform_max; + + if (!mc->platform_max) + mc->platform_max = mc->max; + platform_max = mc->platform_max; + + if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = platform_max - mc->min; + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_info_volsw); + +/** + * snd_soc_get_volsw - single mixer get callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to get the value of a single mixer control, or a double mixer + * control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; + int max = mc->max; + int min = mc->min; + int sign_bit = mc->sign_bit; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + int val; + int ret; + + if (sign_bit) + mask = BIT(sign_bit + 1) - 1; + + ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); + if (ret) + return ret; + + ucontrol->value.integer.value[0] = val - min; + if (invert) + ucontrol->value.integer.value[0] = + max - ucontrol->value.integer.value[0]; + + if (snd_soc_volsw_is_stereo(mc)) { + if (reg == reg2) + ret = snd_soc_read_signed(component, reg, mask, rshift, + sign_bit, &val); + else + ret = snd_soc_read_signed(component, reg2, mask, shift, + sign_bit, &val); + if (ret) + return ret; + + ucontrol->value.integer.value[1] = val - min; + if (invert) + ucontrol->value.integer.value[1] = + max - ucontrol->value.integer.value[1]; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_volsw); + +/** + * snd_soc_put_volsw - single mixer put callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to set the value of a single mixer control, or a double mixer + * control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; + int max = mc->max; + int min = mc->min; + unsigned int sign_bit = mc->sign_bit; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + int err; + bool type_2r = false; + unsigned int val2 = 0; + unsigned int val, val_mask; + + if (sign_bit) + mask = BIT(sign_bit + 1) - 1; + + val = ((ucontrol->value.integer.value[0] + min) & mask); + if (invert) + val = max - val; + val_mask = mask << shift; + val = val << shift; + if (snd_soc_volsw_is_stereo(mc)) { + val2 = ((ucontrol->value.integer.value[1] + min) & mask); + if (invert) + val2 = max - val2; + if (reg == reg2) { + val_mask |= mask << rshift; + val |= val2 << rshift; + } else { + val2 = val2 << shift; + type_2r = true; + } + } + err = snd_soc_component_update_bits(component, reg, val_mask, val); + if (err < 0) + return err; + + if (type_2r) + err = snd_soc_component_update_bits(component, reg2, val_mask, + val2); + + return err; +} +EXPORT_SYMBOL_GPL(snd_soc_put_volsw); + +/** + * snd_soc_get_volsw_sx - single mixer get callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to get the value of a single mixer control, or a double mixer + * control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; + int max = mc->max; + int min = mc->min; + int mask = (1 << (fls(min + max) - 1)) - 1; + unsigned int val; + int ret; + + ret = snd_soc_component_read(component, reg, &val); + if (ret < 0) + return ret; + + ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; + + if (snd_soc_volsw_is_stereo(mc)) { + ret = snd_soc_component_read(component, reg2, &val); + if (ret < 0) + return ret; + + val = ((val >> rshift) - min) & mask; + ucontrol->value.integer.value[1] = val; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); + +/** + * snd_soc_put_volsw_sx - double mixer set callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to set the value of a double mixer control that spans 2 registers. + * + * Returns 0 for success. + */ +int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + + unsigned int reg = mc->reg; + unsigned int reg2 = mc->rreg; + unsigned int shift = mc->shift; + unsigned int rshift = mc->rshift; + int max = mc->max; + int min = mc->min; + int mask = (1 << (fls(min + max) - 1)) - 1; + int err = 0; + unsigned int val, val_mask, val2 = 0; + + val_mask = mask << shift; + val = (ucontrol->value.integer.value[0] + min) & mask; + val = val << shift; + + err = snd_soc_component_update_bits(component, reg, val_mask, val); + if (err < 0) + return err; + + if (snd_soc_volsw_is_stereo(mc)) { + val_mask = mask << rshift; + val2 = (ucontrol->value.integer.value[1] + min) & mask; + val2 = val2 << rshift; + + err = snd_soc_component_update_bits(component, reg2, val_mask, + val2); + } + return err; +} +EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); + +/** + * snd_soc_info_volsw_range - single mixer info callback with range. + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information, within a range, about a single + * mixer control. + * + * returns 0 for success. + */ +int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int platform_max; + int min = mc->min; + + if (!mc->platform_max) + mc->platform_max = mc->max; + platform_max = mc->platform_max; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = platform_max - min; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); + +/** + * snd_soc_put_volsw_range - single mixer put value callback with range. + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to set the value, within a range, for a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + unsigned int reg = mc->reg; + unsigned int rreg = mc->rreg; + unsigned int shift = mc->shift; + int min = mc->min; + int max = mc->max; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + unsigned int val, val_mask; + int ret; + + if (invert) + val = (max - ucontrol->value.integer.value[0]) & mask; + else + val = ((ucontrol->value.integer.value[0] + min) & mask); + val_mask = mask << shift; + val = val << shift; + + ret = snd_soc_component_update_bits(component, reg, val_mask, val); + if (ret < 0) + return ret; + + if (snd_soc_volsw_is_stereo(mc)) { + if (invert) + val = (max - ucontrol->value.integer.value[1]) & mask; + else + val = ((ucontrol->value.integer.value[1] + min) & mask); + val_mask = mask << shift; + val = val << shift; + + ret = snd_soc_component_update_bits(component, rreg, val_mask, + val); + } + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); + +/** + * snd_soc_get_volsw_range - single mixer get callback with range + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback to get the value, within a range, of a single mixer control. + * + * Returns 0 for success. + */ +int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int rreg = mc->rreg; + unsigned int shift = mc->shift; + int min = mc->min; + int max = mc->max; + unsigned int mask = (1 << fls(max)) - 1; + unsigned int invert = mc->invert; + unsigned int val; + int ret; + + ret = snd_soc_component_read(component, reg, &val); + if (ret) + return ret; + + ucontrol->value.integer.value[0] = (val >> shift) & mask; + if (invert) + ucontrol->value.integer.value[0] = + max - ucontrol->value.integer.value[0]; + else + ucontrol->value.integer.value[0] = + ucontrol->value.integer.value[0] - min; + + if (snd_soc_volsw_is_stereo(mc)) { + ret = snd_soc_component_read(component, rreg, &val); + if (ret) + return ret; + + ucontrol->value.integer.value[1] = (val >> shift) & mask; + if (invert) + ucontrol->value.integer.value[1] = + max - ucontrol->value.integer.value[1]; + else + ucontrol->value.integer.value[1] = + ucontrol->value.integer.value[1] - min; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); + +/** + * snd_soc_limit_volume - Set new limit to an existing volume control. + * + * @codec: where to look for the control + * @name: Name of the control + * @max: new maximum limit + * + * Return 0 for success, else error. + */ +int snd_soc_limit_volume(struct snd_soc_codec *codec, + const char *name, int max) +{ + struct snd_card *card = codec->component.card->snd_card; + struct snd_kcontrol *kctl; + struct soc_mixer_control *mc; + int found = 0; + int ret = -EINVAL; + + /* Sanity check for name and max */ + if (unlikely(!name || max <= 0)) + return -EINVAL; + + list_for_each_entry(kctl, &card->controls, list) { + if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) { + found = 1; + break; + } + } + if (found) { + mc = (struct soc_mixer_control *)kctl->private_value; + if (max <= mc->max) { + mc->platform_max = max; + ret = 0; + } + } + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_limit_volume); + +int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_bytes *params = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = params->num_regs * component->val_bytes; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_bytes_info); + +int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_bytes *params = (void *)kcontrol->private_value; + int ret; + + if (component->regmap) + ret = regmap_raw_read(component->regmap, params->base, + ucontrol->value.bytes.data, + params->num_regs * component->val_bytes); + else + ret = -EINVAL; + + /* Hide any masked bytes to ensure consistent data reporting */ + if (ret == 0 && params->mask) { + switch (component->val_bytes) { + case 1: + ucontrol->value.bytes.data[0] &= ~params->mask; + break; + case 2: + ((u16 *)(&ucontrol->value.bytes.data))[0] + &= cpu_to_be16(~params->mask); + break; + case 4: + ((u32 *)(&ucontrol->value.bytes.data))[0] + &= cpu_to_be32(~params->mask); + break; + default: + return -EINVAL; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_bytes_get); + +int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_bytes *params = (void *)kcontrol->private_value; + int ret, len; + unsigned int val, mask; + void *data; + + if (!component->regmap || !params->num_regs) + return -EINVAL; + + len = params->num_regs * component->val_bytes; + + data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); + if (!data) + return -ENOMEM; + + /* + * If we've got a mask then we need to preserve the register + * bits. We shouldn't modify the incoming data so take a + * copy. + */ + if (params->mask) { + ret = regmap_read(component->regmap, params->base, &val); + if (ret != 0) + goto out; + + val &= params->mask; + + switch (component->val_bytes) { + case 1: + ((u8 *)data)[0] &= ~params->mask; + ((u8 *)data)[0] |= val; + break; + case 2: + mask = ~params->mask; + ret = regmap_parse_val(component->regmap, + &mask, &mask); + if (ret != 0) + goto out; + + ((u16 *)data)[0] &= mask; + + ret = regmap_parse_val(component->regmap, + &val, &val); + if (ret != 0) + goto out; + + ((u16 *)data)[0] |= val; + break; + case 4: + mask = ~params->mask; + ret = regmap_parse_val(component->regmap, + &mask, &mask); + if (ret != 0) + goto out; + + ((u32 *)data)[0] &= mask; + + ret = regmap_parse_val(component->regmap, + &val, &val); + if (ret != 0) + goto out; + + ((u32 *)data)[0] |= val; + break; + default: + ret = -EINVAL; + goto out; + } + } + + ret = regmap_raw_write(component->regmap, params->base, + data, len); + +out: + kfree(data); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_bytes_put); + +int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *ucontrol) +{ + struct soc_bytes_ext *params = (void *)kcontrol->private_value; + + ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; + ucontrol->count = params->max; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); + +int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv) +{ + struct soc_bytes_ext *params = (void *)kcontrol->private_value; + unsigned int count = size < params->max ? size : params->max; + int ret = -ENXIO; + + switch (op_flag) { + case SNDRV_CTL_TLV_OP_READ: + if (params->get) + ret = params->get(tlv, count); + break; + case SNDRV_CTL_TLV_OP_WRITE: + if (params->put) + ret = params->put(tlv, count); + break; + } + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); + +/** + * snd_soc_info_xr_sx - signed multi register info callback + * @kcontrol: mreg control + * @uinfo: control element information + * + * Callback to provide information of a control that can + * span multiple codec registers which together + * forms a single signed value in a MSB/LSB manner. + * + * Returns 0 for success. + */ +int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = mc->min; + uinfo->value.integer.max = mc->max; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); + +/** + * snd_soc_get_xr_sx - signed multi register get callback + * @kcontrol: mreg control + * @ucontrol: control element information + * + * Callback to get the value of a control that can span + * multiple codec registers which together forms a single + * signed value in a MSB/LSB manner. The control supports + * specifying total no of bits used to allow for bitfields + * across the multiple codec registers. + * + * Returns 0 for success. + */ +int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regbase = mc->regbase; + unsigned int regcount = mc->regcount; + unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; + unsigned int regwmask = (1<invert; + unsigned long mask = (1UL<nbits)-1; + long min = mc->min; + long max = mc->max; + long val = 0; + unsigned int regval; + unsigned int i; + int ret; + + for (i = 0; i < regcount; i++) { + ret = snd_soc_component_read(component, regbase+i, ®val); + if (ret) + return ret; + val |= (regval & regwmask) << (regwshift*(regcount-i-1)); + } + val &= mask; + if (min < 0 && val > max) + val |= ~mask; + if (invert) + val = max - val; + ucontrol->value.integer.value[0] = val; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); + +/** + * snd_soc_put_xr_sx - signed multi register get callback + * @kcontrol: mreg control + * @ucontrol: control element information + * + * Callback to set the value of a control that can span + * multiple codec registers which together forms a single + * signed value in a MSB/LSB manner. The control supports + * specifying total no of bits used to allow for bitfields + * across the multiple codec registers. + * + * Returns 0 for success. + */ +int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mreg_control *mc = + (struct soc_mreg_control *)kcontrol->private_value; + unsigned int regbase = mc->regbase; + unsigned int regcount = mc->regcount; + unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; + unsigned int regwmask = (1<invert; + unsigned long mask = (1UL<nbits)-1; + long max = mc->max; + long val = ucontrol->value.integer.value[0]; + unsigned int i, regval, regmask; + int err; + + if (invert) + val = max - val; + val &= mask; + for (i = 0; i < regcount; i++) { + regval = (val >> (regwshift*(regcount-i-1))) & regwmask; + regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; + err = snd_soc_component_update_bits(component, regbase+i, + regmask, regval); + if (err < 0) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); + +/** + * snd_soc_get_strobe - strobe get callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback get the value of a strobe mixer control. + * + * Returns 0 for success. + */ +int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int mask = 1 << shift; + unsigned int invert = mc->invert != 0; + unsigned int val; + int ret; + + ret = snd_soc_component_read(component, reg, &val); + if (ret) + return ret; + + val &= mask; + + if (shift != 0 && val != 0) + val = val >> shift; + ucontrol->value.enumerated.item[0] = val ^ invert; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_strobe); + +/** + * snd_soc_put_strobe - strobe put callback + * @kcontrol: mixer control + * @ucontrol: control element information + * + * Callback strobe a register bit to high then low (or the inverse) + * in one pass of a single mixer enum control. + * + * Returns 1 for success. + */ +int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int mask = 1 << shift; + unsigned int invert = mc->invert != 0; + unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; + unsigned int val1 = (strobe ^ invert) ? mask : 0; + unsigned int val2 = (strobe ^ invert) ? 0 : mask; + int err; + + err = snd_soc_component_update_bits(component, reg, mask, val1); + if (err < 0) + return err; + + return snd_soc_component_update_bits(component, reg, mask, val2); +} +EXPORT_SYMBOL_GPL(snd_soc_put_strobe); -- GitLab From aadede6e9f4c8ee46808b2f697b714ee50810e23 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Oct 2014 17:01:36 +0200 Subject: [PATCH 1978/9457] iwlwifi: mvm: port to devcoredump framework iwlwifi features a debug mechanism that allows to dump binary data which is helpful to debug the firmware. Until now, this data was made available for the userspace through debugfs. For this exact purpose, devcoredump was created. Move to the new infrastructure. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/Kconfig | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 4 -- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 79 --------------------- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 57 ++++++++++++--- drivers/net/wireless/iwlwifi/mvm/mvm.h | 5 -- drivers/net/wireless/iwlwifi/mvm/ops.c | 5 -- drivers/net/wireless/iwlwifi/pcie/trans.c | 16 ++--- 7 files changed, 55 insertions(+), 112 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 267e48a2915e..139de90c2aaf 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -59,6 +59,7 @@ config IWLDVM config IWLMVM tristate "Intel Wireless WiFi MVM Firmware support" + select BACKPORT_WANT_DEV_COREDUMP help This is the driver that supports the MVM firmware which is currently only available for 7260 and 3160 devices. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index d8fc548c0d6c..0768f83e709d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -535,9 +535,7 @@ struct iwl_trans_ops { void (*ref)(struct iwl_trans *trans); void (*unref)(struct iwl_trans *trans); -#ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans); -#endif }; /** @@ -704,7 +702,6 @@ static inline void iwl_trans_unref(struct iwl_trans *trans) trans->ops->unref(trans); } -#ifdef CONFIG_IWLWIFI_DEBUGFS static inline struct iwl_trans_dump_data * iwl_trans_dump_data(struct iwl_trans *trans) { @@ -712,7 +709,6 @@ iwl_trans_dump_data(struct iwl_trans *trans) return NULL; return trans->ops->dump_data(trans); } -#endif static inline int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 2a61baca5081..51b7116965ed 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -121,78 +121,6 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf, return ret; } -static int iwl_dbgfs_fw_error_dump_open(struct inode *inode, struct file *file) -{ - struct iwl_mvm *mvm = inode->i_private; - int ret; - - if (!mvm) - return -EINVAL; - - mutex_lock(&mvm->mutex); - if (!mvm->fw_error_dump) { - ret = -ENODATA; - goto out; - } - - file->private_data = mvm->fw_error_dump; - mvm->fw_error_dump = NULL; - ret = 0; - -out: - mutex_unlock(&mvm->mutex); - return ret; -} - -static ssize_t iwl_dbgfs_fw_error_dump_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data; - ssize_t bytes_read = 0; - ssize_t bytes_read_trans = 0; - - if (*ppos < dump_ptrs->op_mode_len) - bytes_read += - simple_read_from_buffer(user_buf, count, ppos, - dump_ptrs->op_mode_ptr, - dump_ptrs->op_mode_len); - - if (bytes_read < 0 || *ppos < dump_ptrs->op_mode_len) - return bytes_read; - - if (dump_ptrs->trans_ptr) { - *ppos -= dump_ptrs->op_mode_len; - bytes_read_trans = - simple_read_from_buffer(user_buf + bytes_read, - count - bytes_read, ppos, - dump_ptrs->trans_ptr->data, - dump_ptrs->trans_ptr->len); - *ppos += dump_ptrs->op_mode_len; - - if (bytes_read_trans >= 0) - bytes_read += bytes_read_trans; - else if (!bytes_read) - /* propagate the failure */ - return bytes_read_trans; - } - - return bytes_read; - -} - -static int iwl_dbgfs_fw_error_dump_release(struct inode *inode, - struct file *file) -{ - struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data; - - vfree(dump_ptrs->op_mode_ptr); - vfree(dump_ptrs->trans_ptr); - kfree(dump_ptrs); - - return 0; -} - static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1535,12 +1463,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10); MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); -static const struct file_operations iwl_dbgfs_fw_error_dump_ops = { - .open = iwl_dbgfs_fw_error_dump_open, - .read = iwl_dbgfs_fw_error_dump_read, - .release = iwl_dbgfs_fw_error_dump_release, -}; - #ifdef CONFIG_IWLWIFI_BCAST_FILTERING MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); @@ -1567,7 +1489,6 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) S_IWUSR | S_IRUSR); MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); - MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 14be10829510..3276b31898da 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -679,10 +680,51 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac, memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data)); } -#ifdef CONFIG_IWLWIFI_DEBUGFS +static ssize_t iwl_mvm_read_coredump(char *buffer, loff_t offset, size_t count, + const void *data, size_t datalen) +{ + const struct iwl_mvm_dump_ptrs *dump_ptrs = data; + ssize_t bytes_read; + ssize_t bytes_read_trans; + + if (offset < dump_ptrs->op_mode_len) { + bytes_read = min_t(ssize_t, count, + dump_ptrs->op_mode_len - offset); + memcpy(buffer, (u8 *)dump_ptrs->op_mode_ptr + offset, + bytes_read); + offset += bytes_read; + count -= bytes_read; + + if (count == 0) + return bytes_read; + } else { + bytes_read = 0; + } + + if (!dump_ptrs->trans_ptr) + return bytes_read; + + offset -= dump_ptrs->op_mode_len; + bytes_read_trans = min_t(ssize_t, count, + dump_ptrs->trans_ptr->len - offset); + memcpy(buffer + bytes_read, + (u8 *)dump_ptrs->trans_ptr->data + offset, + bytes_read_trans); + + return bytes_read + bytes_read_trans; +} + +static void iwl_mvm_free_coredump(const void *data) +{ + const struct iwl_mvm_dump_ptrs *fw_error_dump = data; + + vfree(fw_error_dump->op_mode_ptr); + vfree(fw_error_dump->trans_ptr); + kfree(fw_error_dump); +} + void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) { - static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL }; struct iwl_fw_error_dump_file *dump_file; struct iwl_fw_error_dump_data *dump_data; struct iwl_fw_error_dump_info *dump_info; @@ -695,10 +737,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) lockdep_assert_held(&mvm->mutex); - if (mvm->fw_error_dump) - return; - - fw_error_dump = kzalloc(sizeof(*mvm->fw_error_dump), GFP_KERNEL); + fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); if (!fw_error_dump) return; @@ -773,12 +812,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) if (fw_error_dump->trans_ptr) file_len += fw_error_dump->trans_ptr->len; dump_file->file_len = cpu_to_le32(file_len); - mvm->fw_error_dump = fw_error_dump; - /* notify the userspace about the error we had */ - kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env); + dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0, + GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump); } -#endif static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) { diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d14dc061d1c2..256765accbc6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -648,7 +648,6 @@ struct iwl_mvm { /* -1 for always, 0 for never, >0 for that many times */ s8 restart_fw; struct work_struct fw_error_dump_wk; - struct iwl_mvm_dump_ptrs *fw_error_dump; #ifdef CONFIG_IWLWIFI_LEDS struct led_classdev led; @@ -1216,10 +1215,6 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); -#ifdef CONFIG_IWLWIFI_DEBUGFS void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); -#else -static inline void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) {} -#endif #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 91b28e869969..bd52ecfabedb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -587,11 +587,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) ieee80211_unregister_hw(mvm->hw); kfree(mvm->scan_cmd); - if (mvm->fw_error_dump) { - vfree(mvm->fw_error_dump->op_mode_ptr); - vfree(mvm->fw_error_dump->trans_ptr); - kfree(mvm->fw_error_dump); - } kfree(mvm->mcast_filter_cmd); mvm->mcast_filter_cmd = NULL; diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 8027138c47e9..40a290603ead 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1764,6 +1764,13 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, IWL_ERR(trans, "failed to create the trans debugfs entry\n"); return -ENOMEM; } +#else +static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, + struct dentry *dir) +{ + return 0; +} +#endif /*CONFIG_IWLWIFI_DEBUGFS */ static u32 iwl_trans_pcie_get_cmdlen(struct iwl_tfd *tfd) { @@ -2042,13 +2049,6 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) return dump_data; } -#else -static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, - struct dentry *dir) -{ - return 0; -} -#endif /*CONFIG_IWLWIFI_DEBUGFS */ static const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, @@ -2085,9 +2085,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { .release_nic_access = iwl_trans_pcie_release_nic_access, .set_bits_mask = iwl_trans_pcie_set_bits_mask, -#ifdef CONFIG_IWLWIFI_DEBUGFS .dump_data = iwl_trans_pcie_dump_data, -#endif }; struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, -- GitLab From 1e2ebe0e407159ae94974a93264260883f9a39ad Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Sun, 26 Oct 2014 15:53:27 +0200 Subject: [PATCH 1979/9457] iwlwifi: mvm: fix scan condition iterator Scan condition iterator assumes that an interface is associated if phy_ctxt is assigned, but this isn't the sutuation in P2P device. OTOH P2P device is never associated so we can simply ignore it. Signed-off-by: David Spinadel Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 64c02a274f76..042fcdc81f41 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -270,7 +270,8 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); bool *global_bound = data; - if (mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < MAX_PHYS) + if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt && + mvmvif->phy_ctxt->id < MAX_PHYS) *global_bound = true; } -- GitLab From d8bafeaf46a0e442723859f58fbf863f7c39875f Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Thu, 23 Oct 2014 13:58:38 +0300 Subject: [PATCH 1980/9457] iwlwifi: mvm: rs: add Tx STBC support STBC is enabled on HT/VHT SISO rates in case we don't care about power consumption and it won't hurt BT. This is done only in case the peer and our chip support STBC of course. While at it fixed a bug which was causing bw and ldpc flags to be set incorrectly in the rate scale table in case we are switching to a legacy Tx column. This had no real impact. Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 75 +++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/rs.h | 2 + 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 66e971a99d7c..ce884847cc8a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -505,10 +505,11 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type) static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, const char *prefix) { - IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d\n", + IWL_DEBUG_RATE(mvm, + "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d STBC %d\n", prefix, rs_pretty_lq_type(rate->type), rate->index, rs_pretty_ant(rate->ant), - rate->bw, rate->sgi, rate->ldpc); + rate->bw, rate->sgi, rate->ldpc, rate->stbc); } static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) @@ -741,6 +742,12 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type); } + if (is_siso(rate) && rate->stbc) { + /* To enable STBC we need to set both a flag and ANT_AB */ + ucode_rate |= RATE_MCS_ANT_AB_MSK; + ucode_rate |= RATE_MCS_VHT_STBC_MSK; + } + ucode_rate |= rate->bw; if (rate->sgi) ucode_rate |= RATE_MCS_SGI_MSK; @@ -785,6 +792,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, rate->sgi = true; if (ucode_rate & RATE_MCS_LDPC_MSK) rate->ldpc = true; + if (ucode_rate & RATE_MCS_VHT_STBC_MSK) + rate->stbc = true; rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; @@ -794,7 +803,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, if (nss == 1) { rate->type = LQ_HT_SISO; - WARN_ON_ONCE(num_of_ant != 1); + WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); } else if (nss == 2) { rate->type = LQ_HT_MIMO2; WARN_ON_ONCE(num_of_ant != 2); @@ -992,7 +1001,15 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, static inline bool rs_rate_match(struct rs_rate *a, struct rs_rate *b) { - return (a->type == b->type) && (a->ant == b->ant) && (a->sgi == b->sgi); + bool ant_match; + + if (a->stbc) + ant_match = (b->ant == ANT_A || b->ant == ANT_B); + else + ant_match = (a->ant == b->ant); + + return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) + && ant_match; } static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) @@ -1623,6 +1640,8 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, else rate->type = LQ_LEGACY_G; + rate->bw = RATE_MCS_CHAN_WIDTH_20; + rate->ldpc = false; rate_mask = lq_sta->active_legacy_rate; } else if (column->mode == RS_SISO) { rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; @@ -1634,8 +1653,11 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, WARN_ON_ONCE("Bad column mode"); } - rate->bw = rs_bw_from_sta_bw(sta); - rate->ldpc = lq_sta->ldpc; + if (column->mode != RS_LEGACY) { + rate->bw = rs_bw_from_sta_bw(sta); + rate->ldpc = lq_sta->ldpc; + } + search_tbl->column = col_id; rs_set_expected_tpt_table(lq_sta, search_tbl); @@ -1754,6 +1776,29 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm, return action; } +static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta) +{ + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + struct ieee80211_vif *vif = mvmsta->vif; + bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION && + !vif->bss_conf.ps); + + /* Our chip supports Tx STBC and the peer is an HT/VHT STA which + * supports STBC of at least 1*SS + */ + if (!lq_sta->stbc) + return false; + + if (!mvm->ps_disabled && !sta_ps_disabled) + return false; + + if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) + return false; + + return true; +} + static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index, int *weaker, int *stronger) { @@ -2675,6 +2720,11 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (mvm->cfg->ht_params->ldpc && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) lq_sta->ldpc = true; + + if (mvm->cfg->ht_params->stbc && + (num_of_ant(mvm->fw->valid_tx_ant) > 1) && + (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) + lq_sta->stbc = true; } else { rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); lq_sta->is_vht = true; @@ -2682,6 +2732,11 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (mvm->cfg->ht_params->ldpc && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) lq_sta->ldpc = true; + + if (mvm->cfg->ht_params->stbc && + (num_of_ant(mvm->fw->valid_tx_ant) > 1) && + (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK)) + lq_sta->stbc = true; } if (IWL_MVM_RS_DISABLE_MIMO) @@ -2695,11 +2750,11 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, BITS_PER_LONG); IWL_DEBUG_RATE(mvm, - "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d\n", + "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n", lq_sta->active_legacy_rate, lq_sta->active_siso_rate, lq_sta->active_mimo2_rate, - lq_sta->is_vht, lq_sta->ldpc); + lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc); IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", lq_sta->max_legacy_rate_idx, lq_sta->max_siso_rate_idx, @@ -2823,6 +2878,7 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm, * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps */ static void rs_build_rates_table(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, const struct rs_rate *initial_rate) { @@ -2835,6 +2891,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, memcpy(&rate, initial_rate, sizeof(rate)); valid_tx_ant = mvm->fw->valid_tx_ant; + rate.stbc = rs_stbc_allow(mvm, sta, lq_sta); if (is_siso(&rate)) { num_rates = RS_INITIAL_SISO_NUM_RATES; @@ -2906,7 +2963,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, if (WARN_ON_ONCE(!sta || !initial_rate)) return; - rs_build_rates_table(mvm, lq_sta, initial_rate); + rs_build_rates_table(mvm, sta, lq_sta, initial_rate); if (num_of_ant(initial_rate->ant) == 1) lq_cmd->single_stream_ant_msk = initial_rate->ant; diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index eb34c1209acc..defd70a6d9e6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -208,6 +208,7 @@ struct rs_rate { u32 bw; bool sgi; bool ldpc; + bool stbc; }; @@ -331,6 +332,7 @@ struct iwl_lq_sta { u64 last_tx; bool is_vht; bool ldpc; /* LDPC Rx is supported by the STA */ + bool stbc; /* Tx STBC is supported by chip and Rx by STA */ enum ieee80211_band band; /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ -- GitLab From 4ff78181f4efa91e914e2d0940f3bdc4685aae6b Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 22 Jun 2014 14:44:44 +0300 Subject: [PATCH 1981/9457] iwlwifi: mvm: unref SCAN ref on scan completion The scan reference wasn't released in case of offloaded scan, causing the refcount to go wrong and prevent the device from going into d0i3. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/scan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 042fcdc81f41..5cd59a43e1da 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -673,6 +673,7 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, mvm->scan_status = IWL_MVM_SCAN_NONE; ieee80211_scan_completed(mvm->hw, status == IWL_SCAN_OFFLOAD_ABORTED); + iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); } mvm->last_ebs_successful = !ebs_status; @@ -1107,8 +1108,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) /* * Clear the scan status so the next scan requests will succeed. This * also ensures the Rx handler doesn't do anything, as the scan was - * stopped from above. + * stopped from above. Since the rx handler won't do anything now, + * we have to release the scan reference here. */ + if (mvm->scan_status == IWL_MVM_SCAN_OS) + iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); + mvm->scan_status = IWL_MVM_SCAN_NONE; if (notify) { -- GitLab From cd9b8e2c48b241be084dc794440e0e69267ef8e1 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Tue, 28 Oct 2014 00:03:43 +0200 Subject: [PATCH 1982/9457] KVM: x86: Fix far-jump to non-canonical check Commit d1442d85cc30 ("KVM: x86: Handle errors when RIP is set during far jumps") introduced a bug that caused the fix to be incomplete. Due to incorrect evaluation, far jump to segment with L bit cleared (i.e., 32-bit segment) and RIP with any of the high bits set (i.e, RIP[63:32] != 0) set may not trigger #GP. As we know, this imposes a security problem. In addition, the condition for two warnings was incorrect. Reported-by: Dan Carpenter Signed-off-by: Nadav Amit [Add #ifdef CONFIG_X86_64 to avoid complaints of undefined behavior. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 52a96270b560..5edf088ca51e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -574,12 +574,14 @@ static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, case 4: ctxt->_eip = (u32)dst; break; +#ifdef CONFIG_X86_64 case 8: if ((cs_l && is_noncanonical_address(dst)) || - (!cs_l && (dst & ~(u32)-1))) + (!cs_l && (dst >> 32) != 0)) return emulate_gp(ctxt, 0); ctxt->_eip = dst; break; +#endif default: WARN(1, "unsupported eip assignment size\n"); } @@ -2035,7 +2037,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); if (rc != X86EMUL_CONTINUE) { - WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); + WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); /* assigning eip failed; restore the old cs */ ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); return rc; @@ -2132,7 +2134,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) return rc; rc = assign_eip_far(ctxt, eip, new_desc.l); if (rc != X86EMUL_CONTINUE) { - WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); + WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); } return rc; -- GitLab From 41e7ed64d86db351a94063596b478a0bfc040258 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 8 Oct 2014 18:05:39 +0200 Subject: [PATCH 1983/9457] KVM: nVMX: Disable preemption while reading from shadow VMCS In order to access the shadow VMCS, we need to load it. At this point, vmx->loaded_vmcs->vmcs and the actually loaded one start to differ. If we now get preempted by Linux, vmx_vcpu_put and, on return, the vmx_vcpu_load will work against the wrong vmcs. That can cause copy_shadow_to_vmcs12 to corrupt the vmcs12 state. Fix the issue by disabling preemption during the copy operation. copy_vmcs12_to_shadow is safe from this issue as it is executed by vmx_vcpu_run when preemption is already disabled before vmentry. This bug is exposed by running Jailhouse within KVM on CPUs with shadow VMCS support. Jailhouse never expects an interrupt pending vmexit, but the bug can cause it if, after copy_shadow_to_vmcs12 is preempted, the active VMCS happens to have the virtual interrupt pending flag set in the CPU-based execution controls. Signed-off-by: Jan Kiszka Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a8b76c4c95e2..a0f78dbaabee 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6426,6 +6426,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) const unsigned long *fields = shadow_read_write_fields; const int num_fields = max_shadow_read_write_fields; + preempt_disable(); + vmcs_load(shadow_vmcs); for (i = 0; i < num_fields; i++) { @@ -6449,6 +6451,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) vmcs_clear(shadow_vmcs); vmcs_load(vmx->loaded_vmcs->vmcs); + + preempt_enable(); } static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) -- GitLab From 36bcecd0a73eb4a11c9748bc96c2d254d5364d12 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 29 Oct 2014 13:55:44 +0200 Subject: [PATCH 1984/9457] ASoC: davinci-mcasp: Correct TX start sequence Follow the sequence described in the TRMs when starting TX. This sequence will make sure that we are not facing with initial channel swap caused by no data available in McASP for transmit. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 25 +++++++++---------------- sound/soc/davinci/davinci-mcasp.h | 6 ++++++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 0eed9b1b24e1..e1c1f40dd77f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -183,31 +183,24 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp) static void mcasp_start_tx(struct davinci_mcasp *mcasp) { - u8 offset = 0, i; u32 cnt; + /* Start clocks */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); + /* Activate serializer(s) */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); - mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); - mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); - for (i = 0; i < mcasp->num_serializer; i++) { - if (mcasp->serial_dir[i] == TX_MODE) { - offset = i; - break; - } - } - - /* wait for TX ready */ + /* wait for XDATA to be cleared */ cnt = 0; - while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(offset)) & - TXSTATE) && (cnt < 100000)) + while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) & + ~XRDATA) && (cnt < 100000)) cnt++; - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); + /* Release TX state machine */ + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); + /* Release Frame Sync generator */ + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); } static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream) diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 98fbc451892a..9737108f0305 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -252,6 +252,12 @@ #define TXSMRST BIT(11) /* Transmitter State Machine Reset */ #define TXFSRST BIT(12) /* Frame Sync Generator Reset */ +/* + * DAVINCI_MCASP_TXSTAT_REG - Transmitter Status Register Bits + * DAVINCI_MCASP_RXSTAT_REG - Receiver Status Register Bits + */ +#define XRDATA BIT(5) /* Transmit/Receive data ready */ + /* * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits */ -- GitLab From 4498273551d4e27c93d3585bc7e4676623c46da8 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 29 Oct 2014 13:55:45 +0200 Subject: [PATCH 1985/9457] ASoC: davinci-mcasp: Correct RX start sequence Follow the sequence described in the TRMs when starting RX. Write to RXBUF register was not correct and there is no need to release the RX state machine/Receive frame sync generator twice. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index e1c1f40dd77f..142da94f8878 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -154,9 +154,9 @@ static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp) static void mcasp_start_rx(struct davinci_mcasp *mcasp) { + /* Start clocks */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); - /* * When ASYNC == 0 the transmit and receive sections operate * synchronously from the transmit clock and frame sync. We need to make @@ -167,16 +167,12 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp) mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); } + /* Activate serializer(s) */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); - mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); - - mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); - mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); - mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); - + /* Release RX state machine */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); + /* Release Frame Sync generator */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); - if (mcasp_is_synchronous(mcasp)) mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); } -- GitLab From 0380866a9131646787dc60d19a6d5d2c22dffdd1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 29 Oct 2014 13:55:46 +0200 Subject: [PATCH 1986/9457] ASoC: davinci-mcasp: When stopping TX/RX stop the AFIFO as the last step The AFIFO should not be stopped (or started for that matter) when McASP is running since it can cause unpredictable issues because we are switching off AFIFO for the direction which was handling the requests from McASP and was generating DMA request toward the system DMA. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 142da94f8878..002351f9fc40 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -233,6 +233,12 @@ static void mcasp_stop_rx(struct davinci_mcasp *mcasp) mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); + + if (mcasp->rxnumevt) { /* disable FIFO */ + u32 reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + } } static void mcasp_stop_tx(struct davinci_mcasp *mcasp) @@ -248,27 +254,22 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp) mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); + + if (mcasp->txnumevt) { /* disable FIFO */ + u32 reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + } } static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) { - u32 reg; - mcasp->streams--; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (mcasp->txnumevt) { /* disable FIFO */ - reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; - mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); - } + if (stream == SNDRV_PCM_STREAM_PLAYBACK) mcasp_stop_tx(mcasp); - } else { - if (mcasp->rxnumevt) { /* disable FIFO */ - reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; - mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); - } + else mcasp_stop_rx(mcasp); - } } static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, -- GitLab From bb372af0f7040fb637bfe0859aaa0ba49018506b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 29 Oct 2014 13:55:47 +0200 Subject: [PATCH 1987/9457] ASoC: davinci-mcasp: Move the AFIFO related code under start_tx/rx functions In this way the start code for tx/rx going to be located at the same place. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 002351f9fc40..6b1bfd9de57d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -154,6 +154,13 @@ static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp) static void mcasp_start_rx(struct davinci_mcasp *mcasp) { + if (mcasp->rxnumevt) { /* enable FIFO */ + u32 reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + mcasp_set_bits(mcasp, reg, FIFO_ENABLE); + } + /* Start clocks */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); @@ -181,6 +188,13 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp) { u32 cnt; + if (mcasp->txnumevt) { /* enable FIFO */ + u32 reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + mcasp_set_bits(mcasp, reg, FIFO_ENABLE); + } + /* Start clocks */ mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); @@ -201,25 +215,12 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp) static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream) { - u32 reg; - mcasp->streams++; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (mcasp->txnumevt) { /* enable FIFO */ - reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; - mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); - mcasp_set_bits(mcasp, reg, FIFO_ENABLE); - } + if (stream == SNDRV_PCM_STREAM_PLAYBACK) mcasp_start_tx(mcasp); - } else { - if (mcasp->rxnumevt) { /* enable FIFO */ - reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; - mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); - mcasp_set_bits(mcasp, reg, FIFO_ENABLE); - } + else mcasp_start_rx(mcasp); - } } static void mcasp_stop_rx(struct davinci_mcasp *mcasp) -- GitLab From 720a8d369b7f841741baf723cecd32cdef19d040 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 1 Oct 2014 15:30:31 +0200 Subject: [PATCH 1988/9457] gadget_configfs.txt: fix spelling of 'function' Signed-off-by: Frans Klaver Signed-off-by: Jiri Kosina --- Documentation/usb/gadget_configfs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/gadget_configfs.txt b/Documentation/usb/gadget_configfs.txt index 4cf53e406613..635e57493709 100644 --- a/Documentation/usb/gadget_configfs.txt +++ b/Documentation/usb/gadget_configfs.txt @@ -376,7 +376,7 @@ functions and binds them. This way the whole gadget is bound. configured, so config_groups for particular functions are defined in the functions implementation files drivers/usb/gadget/f_*.c. -5. Funciton's code is written in such a way that it uses +5. Function's code is written in such a way that it uses usb_get_function_instance(), which, in turn, calls request_module. So, provided that modprobe works, modules for particular functions -- GitLab From de869917c663f44b5b032bff238bad22e15dda56 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Thu, 2 Oct 2014 06:45:38 +0200 Subject: [PATCH 1989/9457] mod_devicetable.h: grammar fix in comment Signed-off-by: Michael Opdenacker Signed-off-by: Jiri Kosina --- include/linux/mod_devicetable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 44eeef0da186..745def862580 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -69,7 +69,7 @@ struct ieee1394_device_id { * @bDeviceClass: Class of device; numbers are assigned * by the USB forum. Products may choose to implement classes, * or be vendor-specific. Device classes specify behavior of all - * the interfaces on a devices. + * the interfaces on a device. * @bDeviceSubClass: Subclass of device; associated with bDeviceClass. * @bDeviceProtocol: Protocol of device; associated with bDeviceClass. * @bInterfaceClass: Class of interface; numbers are assigned -- GitLab From 542cb4593104ae306970eb181ea42a01f1a79ed2 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Fri, 3 Oct 2014 11:42:17 +1000 Subject: [PATCH 1990/9457] scsi: Fix "choir" and "beeing" malaprops Signed-off-by: Finn Thain Reviewed-by: Christoph Hellwig Signed-off-by: Jiri Kosina --- Documentation/scsi/scsi_eh.txt | 4 ++-- drivers/scsi/aha152x.c | 2 +- drivers/scsi/mac_scsi.c | 2 +- include/scsi/scsi_host.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index a0c85110a07e..8638f61c8c9d 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt @@ -172,7 +172,7 @@ ways. - eh_strategy_handler() callback This is one big callback which should perform whole error - handling. As such, it should do all choirs SCSI midlayer + handling. As such, it should do all chores the SCSI midlayer performs during recovery. This will be discussed in [2-2]. Once recovery is complete, SCSI EH resumes normal operation by @@ -428,7 +428,7 @@ scmd->allowed. scsi_unjam_host() and it is responsible for whole recovery process. On completion, the handler should have made lower layers forget about all failed scmds and either ready for new commands or offline. Also, -it should perform SCSI EH maintenance choirs to maintain integrity of +it should perform SCSI EH maintenance chores to maintain integrity of SCSI midlayer. IOW, of the steps described in [2-1-2], all steps except for #1 must be implemented by eh_strategy_handler(). diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index e77b72f78006..ee2407b83afb 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -345,7 +345,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) enum { not_issued = 0x0001, /* command not yet issued */ - selecting = 0x0002, /* target is beeing selected */ + selecting = 0x0002, /* target is being selected */ identified = 0x0004, /* IDENTIFY was sent */ disconnected = 0x0008, /* target disconnected */ completed = 0x0010, /* target sent COMMAND COMPLETE */ diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 6a039eb1cbce..dccce08d0ad4 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -360,7 +360,7 @@ const char * macscsi_info (struct Scsi_Host *spnt) { XXX: Since bus errors in the PDMA routines never happen on my computer, the bus error code is untested. If the code works as intended, a bus error results in Pseudo-DMA - beeing disabled, meaning that the driver switches to slow handshake. + being disabled, meaning that the driver switches to slow handshake. If bus errors are NOT extremely rare, this has to be changed. */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index ba2034779961..b286b5787c85 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -555,7 +555,7 @@ struct Scsi_Host { * __devices is protected by the host_lock, but you should * usually use scsi_device_lookup / shost_for_each_device * to access it and don't care about locking yourself. - * In the rare case of beeing in irq context you can use + * In the rare case of being in irq context you can use * their __ prefixed variants with the lock held. NEVER * access this list directly from a driver. */ -- GitLab From f09ced92fa37dbed7aafba3bfdc03a44cfe4bc67 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Mon, 6 Oct 2014 12:32:11 +0200 Subject: [PATCH 1991/9457] IBM Akebono: Remove obsolete config select The original implementation of MMC support for Akebono introduced a new configuration symbol (MMC_SDHCI_OF_476GTR). This symbol has been dropped in favour of using the generic platform driver however the select for this symbol was mistakenly left in the platform configuration. This patch removes the obsolete symbol selection. Signed-off-by: Alistair Popple Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- arch/powerpc/platforms/44x/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 4d88f6a19058..54835e61997b 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -220,7 +220,6 @@ config AKEBONO select USB_EHCI_HCD_PLATFORM select MMC_SDHCI select MMC_SDHCI_PLTFM - select MMC_SDHCI_OF_476GTR select ATA select SATA_AHCI_PLATFORM help -- GitLab From fe4e437229d43e3545416e63598a8476abeb0c01 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 17 Oct 2014 00:09:24 +0900 Subject: [PATCH 1992/9457] treewide: Fix company name in module descriptions This patch fix company name's spelling typo in module descriptions and a Kconfig. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Acked-by: Chris Snook Acked-by: Linus Walleij Signed-off-by: Jiri Kosina --- drivers/clk/Kconfig | 2 +- drivers/gpio/gpio-spear-spics.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- drivers/pinctrl/spear/pinctrl-plgpio.c | 2 +- drivers/video/fbdev/exynos/exynos_mipi_dsi.c | 2 +- drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index cfd3af7b2cbd..01abbbe49bab 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -28,7 +28,7 @@ config COMMON_CLK_WM831X depends on MFD_WM831X ---help--- Supports the clocking subsystem of the WM831x/2x series of - PMICs from Wolfson Microlectronics. + PMICs from Wolfson Microelectronics. source "drivers/clk/versatile/Kconfig" diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c index 353263c85d26..506a2ea0eb4c 100644 --- a/drivers/gpio/gpio-spear-spics.c +++ b/drivers/gpio/gpio-spear-spics.c @@ -204,5 +204,5 @@ static int __init spics_gpio_init(void) subsys_initcall(spics_gpio_init); MODULE_AUTHOR("Shiraz Hashim "); -MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); +MODULE_DESCRIPTION("STMicroelectronics SPEAr SPI Chip Select Abstraction"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index e11bf18fbbd1..9915a273cb00 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -48,7 +48,7 @@ MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl); MODULE_AUTHOR("Jie Yang"); MODULE_AUTHOR("Qualcomm Atheros Inc., "); -MODULE_DESCRIPTION("Qualcom Atheros 100/1000M Ethernet Network Driver"); +MODULE_DESCRIPTION("Qualcomm Atheros 100/1000M Ethernet Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(ATL1C_DRV_VERSION); diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index ff2940e9f2a7..ecfc6aacf270 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -746,5 +746,5 @@ static int __init plgpio_init(void) subsys_initcall(plgpio_init); MODULE_AUTHOR("Viresh Kumar "); -MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); +MODULE_DESCRIPTION("STMicroelectronics SPEAr PLGPIO driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c index cee9602f9a7b..716bfad6a1c0 100644 --- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c @@ -570,5 +570,5 @@ static struct platform_driver exynos_mipi_dsi_driver = { module_platform_driver(exynos_mipi_dsi_driver); MODULE_AUTHOR("InKi Dae "); -MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver"); +MODULE_DESCRIPTION("Samsung SoC MIPI-DSI driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c index 85edabfdef5a..2358a2fbbbcd 100644 --- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c @@ -876,5 +876,5 @@ int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim, } MODULE_AUTHOR("InKi Dae "); -MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver"); +MODULE_DESCRIPTION("Samsung SoC MIPI-DSI common driver"); MODULE_LICENSE("GPL"); -- GitLab From b8bcf32af910c75fa56ec10440965bdf77eafed3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:49:03 +0200 Subject: [PATCH 1993/9457] usb: gadget: zero: Spelling s/infrastucture/infrastructure/ Signed-off-by: Geert Uytterhoeven Cc: Felipe Balbi Acked-by: Felipe Balbi Signed-off-by: Jiri Kosina --- drivers/usb/gadget/legacy/zero.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index c3d496828b74..5ee95152493c 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -28,7 +28,7 @@ * * Why is *this* driver using two configurations, rather than setting up * two interfaces with different functions? To help verify that multiple - * configuration infrastucture is working correctly; also, so that it can + * configuration infrastructure is working correctly; also, so that it can * work with low capability USB controllers without four bulk endpoints. */ -- GitLab From 4e210519453efb71219b0915cf7bc5343a9dc600 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:49:02 +0200 Subject: [PATCH 1994/9457] isci: Spelling s/stucture/structure/ Signed-off-by: Geert Uytterhoeven Cc: James E.J. Bottomley Signed-off-by: Jiri Kosina --- drivers/scsi/isci/task.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 5d6fda72d659..c086c075e8c4 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c @@ -595,7 +595,7 @@ int isci_task_abort_task(struct sas_task *task) ret = TMF_RESP_FUNC_COMPLETE; } else { - /* Fill in the tmf stucture */ + /* Fill in the tmf structure */ isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort, old_request); -- GitLab From 994bef1094500f78f36d0df56b5c0c58c73a7492 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:50:40 +0200 Subject: [PATCH 1995/9457] clk: st: Spelling s/stucture/structure/ Signed-off-by: Geert Uytterhoeven Cc: Mike Turquette Signed-off-by: Jiri Kosina --- Documentation/devicetree/bindings/clock/st/st,flexgen.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt index 1d3ace088172..b7ee5c7e0f75 100644 --- a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt +++ b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt @@ -11,7 +11,7 @@ Please find an example below: Clockgen block diagram ------------------------------------------------------------------- - | Flexgen stucture | + | Flexgen structure | | --------------------------------------------- | | | ------- -------- -------- | | clk_sysin | | | | | | | | | -- GitLab From c2522dcdcb5d54534cfec6d43b646d23efe9eb80 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 26 Sep 2014 19:45:34 +0200 Subject: [PATCH 1996/9457] powerpc: Fix comment typos 'CONFiG_ALTIVEC' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- arch/powerpc/lib/copyuser_power7.S | 2 +- arch/powerpc/lib/memcpy_power7.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index c46c876ac96a..92ee840529bc 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -718,4 +718,4 @@ err3; stb r0,0(r3) 15: addi r1,r1,STACKFRAMESIZE b exit_vmx_usercopy /* tail call optimise */ -#endif /* CONFiG_ALTIVEC */ +#endif /* CONFIG_ALTIVEC */ diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 2ff5c142f87b..0830587df16e 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S @@ -653,4 +653,4 @@ _GLOBAL(memcpy_power7) 15: addi r1,r1,STACKFRAMESIZE ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) b exit_vmx_copy /* tail call optimise */ -#endif /* CONFiG_ALTIVEC */ +#endif /* CONFIG_ALTIVEC */ -- GitLab From b823982cd78ee4c62fa58aa844583738003fbf75 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 26 Sep 2014 19:49:12 +0200 Subject: [PATCH 1997/9457] powerpc: Fix comment typo 'CONIFG_8xx' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- arch/powerpc/mm/mmu_decl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 9615d82919b8..78c45f392f5b 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -67,7 +67,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid, { __tlbil_va(address, pid); } -#endif /* CONIFG_8xx */ +#endif /* CONFIG_8xx */ #if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x) extern void _tlbivax_bcast(unsigned long address, unsigned int pid, -- GitLab From 2386dc4fb00118d5939d790d41d4a3dec3d09b16 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 26 Sep 2014 19:53:11 +0200 Subject: [PATCH 1998/9457] PCI: Fix comment typo 'COMFIG_PM_OPS' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/pci/pci-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d04c5adafc16..0f369d7326de 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1234,11 +1234,11 @@ static const struct dev_pm_ops pci_dev_pm_ops = { #define PCI_PM_OPS_PTR (&pci_dev_pm_ops) -#else /* !COMFIG_PM_OPS */ +#else /* !CONFIG_PM */ #define PCI_PM_OPS_PTR NULL -#endif /* !COMFIG_PM_OPS */ +#endif /* !CONFIG_PM */ /** * __pci_register_driver - register a new pci driver -- GitLab From 8b648f13b4daa6c713691935aef7e64a7ff09a86 Mon Sep 17 00:00:00 2001 From: Roman Mindalev Date: Sat, 27 Sep 2014 10:08:35 +0400 Subject: [PATCH 1999/9457] usb: Fix typo in usb-serial-simple.c Signed-off-by: Roman Mindalev Signed-off-by: Jiri Kosina --- drivers/usb/serial/usb-serial-simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index fb79775447b0..675f9fae9cf2 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -58,7 +58,7 @@ DEVICE(vivopay, VIVOPAY_IDS); /* Motorola USB Phone driver */ #define MOTO_IDS() \ { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ \ - { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ \ + { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Motorola phone */ \ { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ \ { USB_DEVICE(0x22b8, 0x2c84) }, /* Motorola VE240 phone */ \ { USB_DEVICE(0x22b8, 0x2c64) } /* Motorola V950 phone */ -- GitLab From 5887010040c9ff4c5d41781075f64116f5f1c781 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 24 Oct 2014 15:29:57 +0100 Subject: [PATCH 2000/9457] gpio: msm-v1: make boolean argument more obvious irq_set_irq_wake() treats its second argument as a boolean. It is much easier to read code when constant booleans are either 0 or 1! This particular line of code distracted me somewhat when I was doing a bit of work in a code browser since it (spuriously) got me worried that I had misunderstood how irq_set_irq_wake() worked. Signed-off-by: Daniel Thompson Cc: Linus Walleij Cc: Alexandre Courbot Reviewed-by: Alexandre Courbot [jkosina@suse.cz: alter subject to be more descriptive] Signed-off-by: Jiri Kosina --- drivers/gpio/gpio-msm-v1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index 73b73969d361..997e61ef173c 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c @@ -686,7 +686,7 @@ static int gpio_msm_v1_probe(struct platform_device *pdev) irq_set_chained_handler(irq1, msm_gpio_irq_handler); irq_set_chained_handler(irq2, msm_gpio_irq_handler); irq_set_irq_wake(irq1, 1); - irq_set_irq_wake(irq2, 2); + irq_set_irq_wake(irq2, 1); return 0; } -- GitLab From 52b6a8f7b33435121b150984ec93ecdce28a365a Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sun, 14 Sep 2014 20:24:10 +0100 Subject: [PATCH 2001/9457] arm: fix wording of "Crotex" in CONFIG_ARCH_EXYNOS3 help Signed-off-by: Ian Campbell Cc: Russell King Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: trivial@kernel.org Signed-off-by: Jiri Kosina --- arch/arm/mach-exynos/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 2d0240f241b8..1cdf38b4684c 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -33,7 +33,7 @@ config ARCH_EXYNOS3 bool "SAMSUNG EXYNOS3" select ARM_CPU_SUSPEND if PM help - Samsung EXYNOS3 (Crotex-A7) SoC based systems + Samsung EXYNOS3 (Cortex-A7) SoC based systems config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" -- GitLab From be278e980d95f52b280cefac1a98b87fa518dd29 Mon Sep 17 00:00:00 2001 From: James Hartley Date: Thu, 18 Sep 2014 15:59:07 +0100 Subject: [PATCH 2002/9457] clocksource: Fix 'clcoksource' typo in comment Simple typo in a comment, so fix it. Signed-off-by: James Hartley Signed-off-by: Jiri Kosina --- kernel/time/clocksource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 2e949cc9c9f1..b79f39bda7e1 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -792,7 +792,7 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) /* Initialize mult/shift and max_idle_ns */ __clocksource_updatefreq_scale(cs, scale, freq); - /* Add clocksource to the clcoksource list */ + /* Add clocksource to the clocksource list */ mutex_lock(&clocksource_mutex); clocksource_enqueue(cs); clocksource_enqueue_watchdog(cs); -- GitLab From 6354b7e25b7617f71a2b544be82c399013b13917 Mon Sep 17 00:00:00 2001 From: Hans Duedal Date: Sat, 11 Oct 2014 17:01:49 +0200 Subject: [PATCH 2003/9457] HID: roccat: Fix code style issues Missing whitespace, semi-colon after macro, and a duplicated out of memory message. Signed-off-by: Hans Duedal Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 6101816a7ddd..c29265055ac1 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -46,6 +46,7 @@ static void kone_profile_activated(struct kone_device *kone, uint new_profile) static void kone_profile_report(struct kone_device *kone, uint new_profile) { struct kone_roccat_report roccat_report; + roccat_report.event = kone_mouse_event_switch_profile; roccat_report.value = new_profile; roccat_report.key = 0; @@ -163,6 +164,7 @@ static int kone_set_settings(struct usb_device *usb_dev, struct kone_settings const *settings) { int retval; + retval = kone_send(usb_dev, kone_command_settings, settings, sizeof(struct kone_settings)); if (retval) @@ -387,7 +389,7 @@ static struct bin_attribute bin_attr_profile##number = { \ .read = kone_sysfs_read_profilex, \ .write = kone_sysfs_write_profilex, \ .private = &profile_numbers[number-1], \ -}; +} PROFILE_ATTR(1); PROFILE_ATTR(2); PROFILE_ATTR(3); @@ -456,6 +458,7 @@ static ssize_t kone_sysfs_show_tcu(struct device *dev, static int kone_tcu_command(struct usb_device *usb_dev, int number) { unsigned char value; + value = number; return kone_send(usb_dev, kone_command_calibrate, &value, 1); } @@ -697,10 +700,8 @@ static int kone_init_specials(struct hid_device *hdev) == USB_INTERFACE_PROTOCOL_MOUSE) { kone = kzalloc(sizeof(*kone), GFP_KERNEL); - if (!kone) { - hid_err(hdev, "can't alloc device descriptor\n"); + if (!kone) return -ENOMEM; - } hid_set_drvdata(hdev, kone); retval = kone_init_kone_device_struct(usb_dev, kone); -- GitLab From a11e9b168646cfc5d3b8d605d430d7e4ff267d72 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2014 15:06:01 +0100 Subject: [PATCH 2004/9457] ALSA: hda - Correct kerneldoc comments Complete the missing parameters and fix anything wrong there. Just comment changes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_auto_parser.c | 15 ++++- sound/pci/hda/hda_codec.c | 114 ++++++++++++++++++++++++++++++-- sound/pci/hda/hda_eld.c | 2 +- sound/pci/hda/hda_jack.c | 21 ++++++ 4 files changed, 146 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index fcc5e478c9a1..7388958b01af 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -464,8 +464,12 @@ EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr); /** * hda_get_input_pin_label - Give a label for the given input pin + * @codec: the HDA codec + * @item: ping config item to refer + * @pin: the pin NID + * @check_location: flag to add the jack location prefix * - * When check_location is true, the function checks the pin location + * When @check_location is true, the function checks the pin location * for mic and line-in pins, and set an appropriate prefix like "Front", * "Rear", "Internal". */ @@ -550,6 +554,9 @@ static int check_mic_location_need(struct hda_codec *codec, /** * hda_get_autocfg_input_label - Get a label for the given input + * @codec: the HDA codec + * @cfg: the parsed pin configuration + * @input: the input index number * * Get a label for the given input pin defined by the autocfg item. * Unlike hda_get_input_pin_label(), this function checks all inputs @@ -677,6 +684,12 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, /** * snd_hda_get_pin_label - Get a label for the given I/O pin + * @codec: the HDA codec + * @nid: pin NID + * @cfg: the parsed pin configuration + * @label: the string buffer to store + * @maxlen: the max length of string buffer (including termination) + * @indexp: the pointer to return the index number (for multiple ctls) * * Get a label for the given pin. This function works for both input and * output pins. When @cfg is given as non-NULL, the function tries to get diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0025bf4c2f44..e15254204c72 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -416,7 +416,6 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) * snd_hda_get_conn_list - get connection list * @codec: the HDA codec * @nid: NID to parse - * @len: number of connection list entries * @listp: the pointer to store NID list * * Parses the connection list of the given widget and stores the pointer @@ -2004,6 +2003,7 @@ EXPORT_SYMBOL_GPL(query_amp_caps); * @codec: the HD-audio codec * @nid: the NID to query * @dir: either #HDA_INPUT or #HDA_OUTPUT + * @bits: bit mask to check the result * * Check whether the widget has the given amp capability for the direction. */ @@ -2023,7 +2023,7 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps); * snd_hda_override_amp_caps - Override the AMP capabilities * @codec: the CODEC to clean up * @nid: the NID to clean up - * @direction: either #HDA_INPUT or #HDA_OUTPUT + * @dir: either #HDA_INPUT or #HDA_OUTPUT * @caps: the capability bits to set * * Override the cached AMP caps bits value by the given one. @@ -2320,6 +2320,8 @@ static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, /** * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer + * @kcontrol: referred ctl element + * @uinfo: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -2381,6 +2383,8 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid, /** * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -2406,6 +2410,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_get); /** * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -2436,6 +2442,10 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); /** * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume + * @kcontrol: ctl element + * @op_flag: operation flag + * @size: byte size of input TLV + * @_tlv: TLV data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -3012,6 +3022,8 @@ EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook); /** * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch + * @kcontrol: referred ctl element + * @uinfo: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -3031,6 +3043,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_info); /** * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -3057,6 +3071,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get); /** * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_COMPOSE_AMP_VAL*() or related macros. @@ -3100,6 +3116,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put); /** * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_BIND_MUTE*() macros. @@ -3123,6 +3141,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_get); /** * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_BIND_MUTE*() macros. @@ -3153,6 +3173,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_put); /** * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control + * @kcontrol: referred ctl element + * @uinfo: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. @@ -3176,6 +3198,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_info); /** * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. @@ -3199,6 +3223,8 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_get); /** * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data * * The control element is supposed to have the private_value field * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. @@ -3228,6 +3254,10 @@ EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_put); /** * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control + * @kcontrol: ctl element + * @op_flag: operation flag + * @size: byte size of input TLV + * @tlv: TLV data * * The control element is supposed to have the private_value field * set up via HDA_BIND_VOL() macro. @@ -4305,6 +4335,7 @@ static struct hda_rate_tbl rate_bits[] = { * @channels: the number of channels * @format: the PCM format (SNDRV_PCM_FORMAT_XXX) * @maxbps: the max. bps + * @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant) * * Calculate the format bitset from the given rate, channels and th PCM format. * @@ -4980,6 +5011,7 @@ static void __snd_hda_power_down(struct hda_codec *codec) * snd_hda_power_save - Power-up/down/sync the codec * @codec: HD-audio codec * @delta: the counter delta to change + * @d3wait: sync for D3 transition complete * * Change the power-up counter via @delta, and power up or down the hardware * appropriately. For the power-down, queue to the delayed action. @@ -5055,6 +5087,10 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power); /** * snd_hda_ch_mode_info - Info callback helper for the channel mode enum + * @codec: the HDA codec + * @uinfo: pointer to get/store the data + * @chmode: channel mode array + * @num_chmodes: channel mode array size */ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, @@ -5074,6 +5110,11 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_info); /** * snd_hda_ch_mode_get - Get callback helper for the channel mode enum + * @codec: the HDA codec + * @ucontrol: pointer to get/store the data + * @chmode: channel mode array + * @num_chmodes: channel mode array size + * @max_channels: max number of channels */ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, @@ -5095,6 +5136,11 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_get); /** * snd_hda_ch_mode_put - Put callback helper for the channel mode enum + * @codec: the HDA codec + * @ucontrol: pointer to get/store the data + * @chmode: channel mode array + * @num_chmodes: channel mode array size + * @max_channelsp: pointer to store the max channels */ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, @@ -5123,6 +5169,8 @@ EXPORT_SYMBOL_GPL(snd_hda_ch_mode_put); /** * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum + * @imux: imux helper object + * @uinfo: pointer to get/store the data */ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) @@ -5144,6 +5192,11 @@ EXPORT_SYMBOL_GPL(snd_hda_input_mux_info); /** * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum + * @codec: the HDA codec + * @imux: imux helper object + * @ucontrol: pointer to get/store the data + * @nid: input mux NID + * @cur_val: pointer to get/store the current imux value */ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, @@ -5168,7 +5221,13 @@ int snd_hda_input_mux_put(struct hda_codec *codec, EXPORT_SYMBOL_GPL(snd_hda_input_mux_put); -/* +/** + * snd_hda_enum_helper_info - Helper for simple enum ctls + * @kcontrol: ctl element + * @uinfo: pointer to get/store the data + * @num_items: number of enum items + * @texts: enum item string array + * * process kcontrol info callback of a simple string enum array * when @num_items is 0 or @texts is NULL, assume a boolean enum array */ @@ -5257,6 +5316,8 @@ EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify); /** * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode + * @codec: the HDA codec + * @mout: hda_multi_out object */ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) @@ -5273,6 +5334,11 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open); /** * snd_hda_multi_out_dig_prepare - prepare the digital out stream + * @codec: the HDA codec + * @mout: hda_multi_out object + * @stream_tag: stream tag to assign + * @format: format id to assign + * @substream: PCM substream to assign */ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, struct hda_multi_out *mout, @@ -5289,6 +5355,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare); /** * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream + * @codec: the HDA codec + * @mout: hda_multi_out object */ int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) @@ -5302,6 +5370,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup); /** * snd_hda_multi_out_dig_close - release the digital out stream + * @codec: the HDA codec + * @mout: hda_multi_out object */ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) @@ -5315,6 +5385,10 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close); /** * snd_hda_multi_out_analog_open - open analog outputs + * @codec: the HDA codec + * @mout: hda_multi_out object + * @substream: PCM substream to assign + * @hinfo: PCM information to assign * * Open analog outputs and set up the hw-constraints. * If the digital outputs can be opened as slave, open the digital @@ -5365,6 +5439,11 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_open); /** * snd_hda_multi_out_analog_prepare - Preapre the analog outputs. + * @codec: the HDA codec + * @mout: hda_multi_out object + * @stream_tag: stream tag to assign + * @format: format id to assign + * @substream: PCM substream to assign * * Set up the i/o for analog out. * When the digital out is available, copy the front out to digital out, too. @@ -5442,6 +5521,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_prepare); /** * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out + * @codec: the HDA codec + * @mout: hda_multi_out object */ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) @@ -5473,6 +5554,8 @@ EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup); /** * snd_hda_get_default_vref - Get the default (mic) VREF pin bits + * @codec: the HDA codec + * @pin: referred pin NID * * Guess the suitable VREF pin bits to be set as the pin-control value. * Note: the function doesn't set the AC_PINCTL_IN_EN bit. @@ -5498,7 +5581,12 @@ unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) } EXPORT_SYMBOL_GPL(snd_hda_get_default_vref); -/* correct the pin ctl value for matching with the pin cap */ +/** + * snd_hda_correct_pin_ctl - correct the pin ctl value for matching with the pin cap + * @codec: the HDA codec + * @pin: referred pin NID + * @val: pin ctl value to audit + */ unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val) { @@ -5549,6 +5637,19 @@ unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl); +/** + * _snd_hda_pin_ctl - Helper to set pin ctl value + * @codec: the HDA codec + * @pin: referred pin NID + * @val: pin control value to set + * @cached: access over codec pinctl cache or direct write + * + * This function is a helper to set a pin ctl value more safely. + * It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the + * value in pin target array via snd_hda_codec_set_pin_target(), then + * actually writes the value via either snd_hda_codec_update_cache() or + * snd_hda_codec_write() depending on @cached flag. + */ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val, bool cached) { @@ -5565,6 +5666,11 @@ EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl); /** * snd_hda_add_imux_item - Add an item to input_mux + * @codec: the HDA codec + * @imux: imux helper object + * @label: the name of imux item to assign + * @index: index number of imux item to assign + * @type_idx: pointer to store the resultant label index * * When the same label is used already in the existing items, the number * suffix is appended to the label. This label index number is stored diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index e1cd34d9011d..0e6d7534f491 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -371,7 +371,7 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, return ret; } -/** +/* * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with * hdmi-specific routine. */ diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index f56765ae73a7..b2d81ab22fb0 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -57,6 +57,8 @@ static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) /** * snd_hda_jack_tbl_get - query the jack-table entry for the given NID + * @codec: the HDA codec + * @nid: pin NID to refer to */ struct hda_jack_tbl * snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) @@ -75,6 +77,8 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get); /** * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag + * @codec: the HDA codec + * @tag: tag value to refer to */ struct hda_jack_tbl * snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) @@ -93,6 +97,8 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag); /** * snd_hda_jack_tbl_new - create a jack-table entry for the given NID + * @codec: the HDA codec + * @nid: pin NID to assign */ static struct hda_jack_tbl * snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) @@ -162,6 +168,7 @@ static void jack_detect_update(struct hda_codec *codec, /** * snd_hda_set_dirty_all - Mark all the cached as dirty + * @codec: the HDA codec * * This function sets the dirty flag to all entries of jack table. * It's called from the resume path in hda_codec.c. @@ -218,6 +225,9 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state); /** * snd_hda_jack_detect_enable - enable the jack-detection + * @codec: the HDA codec + * @nid: pin NID to enable + * @func: callback function to register * * In the case of error, the return value will be a pointer embedded with * errno. Check and handle the return value appropriately with standard @@ -266,6 +276,9 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); /** * snd_hda_jack_set_gating_jack - Set gating jack. + * @codec: the HDA codec + * @gated_nid: gated pin NID + * @gating_nid: gating pin NID * * Indicates the gated jack is only valid when the gating jack is plugged. */ @@ -287,6 +300,7 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack); /** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed + * @codec: the HDA codec */ void snd_hda_jack_report_sync(struct hda_codec *codec) { @@ -349,6 +363,11 @@ static void hda_free_jack_priv(struct snd_jack *jack) /** * snd_hda_jack_add_kctl - Add a kctl for the given pin + * @codec: the HDA codec + * @nid: pin NID to assign + * @name: string name for the jack + * @idx: index number for the jack + * @phantom_jack: flag to deal as a phantom jack * * This assigns a jack-detection kctl to the given pin. The kcontrol * will have the given name and index. @@ -456,6 +475,8 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, /** * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg + * @codec: the HDA codec + * @cfg: pin config table to parse */ int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) -- GitLab From 9f295664e2f2cdf53c596f74bcf3f644cae9fecc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 11:45:04 +0300 Subject: [PATCH 2005/9457] percpu: off by one in BUG_ON() The unit_map[] array has "nr_cpu_ids" number of elements. It's allocated a few lines earlier in the function. So this test should be >= instead of >. Signed-off-by: Dan Carpenter Signed-off-by: Tejun Heo --- mm/percpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/percpu.c b/mm/percpu.c index 014bab65e0ff..d39e2f4e335c 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1591,7 +1591,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, if (cpu == NR_CPUS) continue; - PCPU_SETUP_BUG_ON(cpu > nr_cpu_ids); + PCPU_SETUP_BUG_ON(cpu >= nr_cpu_ids); PCPU_SETUP_BUG_ON(!cpu_possible(cpu)); PCPU_SETUP_BUG_ON(unit_map[cpu] != UINT_MAX); -- GitLab From 95a962c36f6e3c3edb438d1ba59e30964900d16a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2014 16:03:58 +0100 Subject: [PATCH 2006/9457] ALSA: hda - More kerneldoc comments Put more kerneldoc comments to the exported functions. Still the generic parser code and the HD-audio controller code aren't covered yet, though. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_auto_parser.c | 51 ++++++++++- sound/pci/hda/hda_beep.c | 38 ++++++++ sound/pci/hda/hda_codec.c | 148 +++++++++++++++++++++++++++++--- sound/pci/hda/hda_jack.c | 39 +++++++++ sound/pci/hda/hda_jack.h | 5 ++ sound/pci/hda/hda_sysfs.c | 35 +++++++- 6 files changed, 297 insertions(+), 19 deletions(-) diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 7388958b01af..1ede82200ee5 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -441,6 +441,13 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg); +/** + * snd_hda_get_input_pin_attr - Get the input pin attribute from pin config + * @def_conf: pin configuration value + * + * Guess the input pin attribute (INPUT_PIN_ATTR_XXX) from the given + * default pin configuration value. + */ int snd_hda_get_input_pin_attr(unsigned int def_conf) { unsigned int loc = get_defcfg_location(def_conf); @@ -473,7 +480,6 @@ EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr); * for mic and line-in pins, and set an appropriate prefix like "Front", * "Rear", "Internal". */ - static const char *hda_get_input_pin_label(struct hda_codec *codec, const struct auto_pin_cfg_item *item, hda_nid_t pin, bool check_location) @@ -761,6 +767,14 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); +/** + * snd_hda_add_verbs - Add verbs to the init list + * @codec: the HDA codec + * @list: zero-terminated verb list to add + * + * Append the given verb list to the execution list. The verbs will be + * performed at init and resume time via snd_hda_apply_verbs(). + */ int snd_hda_add_verbs(struct hda_codec *codec, const struct hda_verb *list) { @@ -773,6 +787,10 @@ int snd_hda_add_verbs(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_add_verbs); +/** + * snd_hda_apply_verbs - Execute the init verb lists + * @codec: the HDA codec + */ void snd_hda_apply_verbs(struct hda_codec *codec) { int i; @@ -783,6 +801,11 @@ void snd_hda_apply_verbs(struct hda_codec *codec) } EXPORT_SYMBOL_GPL(snd_hda_apply_verbs); +/** + * snd_hda_apply_pincfgs - Set each pin config in the given list + * @codec: the HDA codec + * @cfg: NULL-terminated pin config table + */ void snd_hda_apply_pincfgs(struct hda_codec *codec, const struct hda_pintbl *cfg) { @@ -850,6 +873,11 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth) } } +/** + * snd_hda_apply_fixup - Apply the fixup chain with the given action + * @codec: the HDA codec + * @action: fixup action (HDA_FIXUP_ACT_XXX) + */ void snd_hda_apply_fixup(struct hda_codec *codec, int action) { if (codec->fixup_list) @@ -868,6 +896,12 @@ static bool pin_config_match(struct hda_codec *codec, return true; } +/** + * snd_hda_pick_pin_fixup - Pick up a fixup matching with the pin quirk list + * @codec: the HDA codec + * @pin_quirk: zero-terminated pin quirk list + * @fixlist: the fixup list + */ void snd_hda_pick_pin_fixup(struct hda_codec *codec, const struct snd_hda_pin_quirk *pin_quirk, const struct hda_fixup *fixlist) @@ -894,6 +928,21 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); +/** + * snd_hda_pick_fixup - Pick up a fixup matching with PCI/codec SSID or model string + * @codec: the HDA codec + * @models: NULL-terminated model string list + * @quirk: zero-terminated PCI/codec SSID quirk list + * @fixlist: the fixup list + * + * Pick up a fixup entry matching with the given model string or SSID. + * If a fixup was already set beforehand, the function doesn't do anything. + * When a special model string "nofixup" is given, also no fixup is applied. + * + * The function tries to find the matching model name at first, if given. + * If nothing matched, try to look up the PCI SSID. + * If still nothing matched, try to look up the codec SSID. + */ void snd_hda_pick_fixup(struct hda_codec *codec, const struct hda_model_fixup *models, const struct snd_pci_quirk *quirk, diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 8c6c50afc0b7..1e7de08e77cb 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -175,6 +175,11 @@ static int snd_hda_do_attach(struct hda_beep *beep) return 0; } +/** + * snd_hda_enable_beep_device - Turn on/off beep sound + * @codec: the HDA codec + * @enable: flag to turn on/off + */ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) { struct hda_beep *beep = codec->beep; @@ -191,6 +196,20 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) } EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device); +/** + * snd_hda_attach_beep_device - Attach a beep input device + * @codec: the HDA codec + * @nid: beep NID + * + * Attach a beep object to the given widget. If beep hint is turned off + * explicitly or beep_mode of the codec is turned off, this doesn't nothing. + * + * The attached beep device has to be registered via + * snd_hda_register_beep_device() and released via snd_hda_detach_beep_device() + * appropriately. + * + * Currently, only one beep device is allowed to each codec. + */ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) { struct hda_beep *beep; @@ -228,6 +247,10 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) } EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device); +/** + * snd_hda_detach_beep_device - Detach the beep device + * @codec: the HDA codec + */ void snd_hda_detach_beep_device(struct hda_codec *codec) { struct hda_beep *beep = codec->beep; @@ -240,6 +263,10 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) } EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device); +/** + * snd_hda_register_beep_device - Register the beep device + * @codec: the HDA codec + */ int snd_hda_register_beep_device(struct hda_codec *codec) { struct hda_beep *beep = codec->beep; @@ -269,6 +296,12 @@ static bool ctl_has_mute(struct snd_kcontrol *kcontrol) } /* get/put callbacks for beep mute mixer switches */ + +/** + * snd_hda_mixer_amp_switch_get_beep - Get callback for beep controls + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data + */ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -283,6 +316,11 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get_beep); +/** + * snd_hda_mixer_amp_switch_put_beep - Put callback for beep controls + * @kcontrol: ctl element + * @ucontrol: pointer to get/store the data + */ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e15254204c72..ca98f5209f8f 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -77,6 +77,10 @@ static struct hda_vendor_id hda_vendor_ids[] = { static DEFINE_MUTEX(preset_mutex); static LIST_HEAD(hda_preset_tables); +/** + * snd_hda_add_codec_preset - Add a codec preset to the chain + * @preset: codec preset table to add + */ int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) { mutex_lock(&preset_mutex); @@ -86,6 +90,10 @@ int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) } EXPORT_SYMBOL_GPL(snd_hda_add_codec_preset); +/** + * snd_hda_delete_codec_preset - Delete a codec preset from the chain + * @preset: codec preset table to delete + */ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) { mutex_lock(&preset_mutex); @@ -1187,7 +1195,16 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) } EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg); -/* remember the current pinctl target value */ +/** + * snd_hda_codec_set_pin_target - remember the current pinctl target value + * @codec: the HDA codec + * @nid: pin NID + * @val: assigned pinctl value + * + * This function stores the given value to a pinctl target value in the + * pincfg table. This isn't always as same as the actually written value + * but can be referred at any time via snd_hda_codec_get_pin_target(). + */ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, unsigned int val) { @@ -1201,7 +1218,11 @@ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target); -/* return the current pinctl target value */ +/** + * snd_hda_codec_get_pin_target - return the current pinctl target value + * @codec: the HDA codec + * @nid: pin NID + */ int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) { struct hda_pincfg *pin; @@ -1573,6 +1594,13 @@ int snd_hda_codec_new(struct hda_bus *bus, } EXPORT_SYMBOL_GPL(snd_hda_codec_new); +/** + * snd_hda_codec_update_widgets - Refresh widget caps and pin defaults + * @codec: the HDA codec + * + * Forcibly refresh the all widget caps and the init pin configurations of + * the given codec. + */ int snd_hda_codec_update_widgets(struct hda_codec *codec) { hda_nid_t fg; @@ -2239,7 +2267,17 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo); -/* Works like snd_hda_codec_amp_update() but it writes the value only at +/** + * snd_hda_codec_amp_init - initialize the AMP value + * @codec: the HDA codec + * @nid: NID to read the AMP value + * @ch: channel (left=0 or right=1) + * @dir: #HDA_INPUT or #HDA_OUTPUT + * @idx: the index value (only for input direction) + * @mask: bit mask to set + * @val: the bits value to set + * + * Works like snd_hda_codec_amp_update() but it writes the value only at * the first access. If the amp was already initialized / updated beforehand, * this does nothing. */ @@ -2250,6 +2288,17 @@ int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, } EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init); +/** + * snd_hda_codec_amp_init_stereo - initialize the stereo AMP value + * @codec: the HDA codec + * @nid: NID to read the AMP value + * @dir: #HDA_INPUT or #HDA_OUTPUT + * @idx: the index value (only for input direction) + * @mask: bit mask to set + * @val: the bits value to set + * + * Call snd_hda_codec_amp_init() for both stereo channels. + */ int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, int dir, int idx, int mask, int val) { @@ -2644,7 +2693,10 @@ void snd_hda_ctls_clear(struct hda_codec *codec) snd_array_free(&codec->nids); } -/* pseudo device locking +/** + * snd_hda_lock_devices - pseudo device locking + * @bus: the BUS + * * toggle card->shutdown to allow/disallow the device access (as a hack) */ int snd_hda_lock_devices(struct hda_bus *bus) @@ -2681,6 +2733,10 @@ int snd_hda_lock_devices(struct hda_bus *bus) } EXPORT_SYMBOL_GPL(snd_hda_lock_devices); +/** + * snd_hda_unlock_devices - pseudo device unlocking + * @bus: the BUS + */ void snd_hda_unlock_devices(struct hda_bus *bus) { struct snd_card *card = bus->card; @@ -2867,7 +2923,7 @@ static int add_slave(struct hda_codec *codec, } /** - * snd_hda_add_vmaster - create a virtual master control and add slaves + * __snd_hda_add_vmaster - create a virtual master control and add slaves * @codec: HD-audio codec * @name: vmaster control name * @tlv: TLV data (optional) @@ -2970,10 +3026,15 @@ static struct snd_kcontrol_new vmaster_mute_mode = { .put = vmaster_mute_mode_put, }; -/* - * Add a mute-LED hook with the given vmaster switch kctl - * "Mute-LED Mode" control is automatically created and associated with - * the given hook. +/** + * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED + * @codec: the HDA codec + * @hook: the vmaster hook object + * @expose_enum_ctl: flag to create an enum ctl + * + * Add a mute-LED hook with the given vmaster switch kctl. + * When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically + * created and associated with the given hook. */ int snd_hda_add_vmaster_hook(struct hda_codec *codec, struct hda_vmaster_mute_hook *hook, @@ -2995,9 +3056,12 @@ int snd_hda_add_vmaster_hook(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook); -/* - * Call the hook with the current value for synchronization - * Should be called in init callback +/** + * snd_hda_sync_vmaster_hook - Sync vmaster hook + * @hook: the vmaster hook + * + * Call the hook with the current value for synchronization. + * Should be called in init callback. */ void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) { @@ -3599,7 +3663,11 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls); -/* get the hda_spdif_out entry from the given NID +/** + * snd_hda_spdif_out_of_nid - get the hda_spdif_out entry from the given NID + * @codec: the HDA codec + * @nid: widget NID + * * call within spdif_mutex lock */ struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, @@ -3616,6 +3684,13 @@ struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid); +/** + * snd_hda_spdif_ctls_unassign - Unassign the given SPDIF ctl + * @codec: the HDA codec + * @idx: the SPDIF ctl index + * + * Unassign the widget from the given SPDIF control. + */ void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) { struct hda_spdif_out *spdif; @@ -3627,6 +3702,14 @@ void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) } EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign); +/** + * snd_hda_spdif_ctls_assign - Assign the SPDIF controls to the given NID + * @codec: the HDA codec + * @idx: the SPDIF ctl idx + * @nid: widget NID + * + * Assign the widget to the SPDIF control with the given index. + */ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) { struct hda_spdif_out *spdif; @@ -3946,6 +4029,16 @@ void snd_hda_codec_flush_cache(struct hda_codec *codec) } EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache); +/** + * snd_hda_codec_set_power_to_all - Set the power state to all widgets + * @codec: the HDA codec + * @fg: function group (not used now) + * @power_state: the power state to set (AC_PWRST_*) + * + * Set the given power state to all widgets that have the power control. + * If the codec has power_filter set, it evaluates the power state and + * filter out if it's unchanged as D3. + */ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { @@ -4010,7 +4103,15 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec, return state; } -/* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */ +/** + * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD + * @codec: the HDA codec + * @nid: widget NID + * @power_state: power state to evalue + * + * Don't power down the widget if it controls eapd and EAPD_BTLENABLE is set. + * This can be used a codec power_filter callback. + */ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state) @@ -4671,6 +4772,17 @@ static int set_pcm_default_values(struct hda_codec *codec, /* * codec prepare/cleanup entries */ +/** + * snd_hda_codec_prepare - Prepare a stream + * @codec: the HDA codec + * @hinfo: PCM information + * @stream: stream tag to assign + * @format: format id to assign + * @substream: PCM substream to assign + * + * Calls the prepare callback set by the codec with the given arguments. + * Clean up the inactive streams when successful. + */ int snd_hda_codec_prepare(struct hda_codec *codec, struct hda_pcm_stream *hinfo, unsigned int stream, @@ -4687,6 +4799,14 @@ int snd_hda_codec_prepare(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_codec_prepare); +/** + * snd_hda_codec_cleanup - Prepare a stream + * @codec: the HDA codec + * @hinfo: PCM information + * @substream: PCM substream + * + * Calls the cleanup callback set by the codec with the given arguments. + */ void snd_hda_codec_cleanup(struct hda_codec *codec, struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index b2d81ab22fb0..e664307617bd 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -20,6 +20,16 @@ #include "hda_auto_parser.h" #include "hda_jack.h" +/** + * is_jack_detectable - Check whether the given pin is jack-detectable + * @codec: the HDA codec + * @nid: pin NID + * + * Check whether the given pin is capable to report the jack detection. + * The jack detection might not work by various reasons, e.g. the jack + * detection is prohibited in the codec level, the pin config has + * AC_DEFCFG_MISC_NO_PRESENCE bit, no unsol support, etc. + */ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { if (codec->no_jack_detect) @@ -268,6 +278,14 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); +/** + * snd_hda_jack_detect_enable - Enable the jack detection on the given pin + * @codec: the HDA codec + * @nid: pin NID to enable jack detection + * + * Enable the jack detection with the default callback. Returns zero if + * successful or a negative error code. + */ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid) { return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL)); @@ -410,6 +428,15 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, return 0; } +/** + * snd_hda_jack_add_kctl - Add a jack kctl for the given pin + * @codec: the HDA codec + * @nid: pin NID + * @name: the name string for the jack ctl + * @idx: the ctl index for the jack ctl + * + * This is a simple helper calling __snd_hda_jack_add_kctl(). + */ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, const char *name, int idx) { @@ -552,6 +579,11 @@ static void call_jack_callback(struct hda_codec *codec, } } +/** + * snd_hda_jack_unsol_event - Handle an unsolicited event + * @codec: the HDA codec + * @res: the unsolicited event data + */ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) { struct hda_jack_tbl *event; @@ -567,6 +599,13 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) } EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event); +/** + * snd_hda_jack_poll_all - Poll all jacks + * @codec: the HDA codec + * + * Poll all detectable jacks with dirty flag, update the status, call + * callbacks and call snd_hda_jack_report_sync() if any changes are found. + */ void snd_hda_jack_poll_all(struct hda_codec *codec) { struct hda_jack_tbl *jack = codec->jacktbl.list; diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 13cb375454f6..b279e327a23b 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -72,6 +72,11 @@ enum { int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid); +/** + * snd_hda_jack_detect - Detect the jack + * @codec: the HDA codec + * @nid: pin NID to check jack detection + */ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) { return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT; diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c index 9b49f156a12e..bef721592c3a 100644 --- a/sound/pci/hda/hda_sysfs.c +++ b/sound/pci/hda/hda_sysfs.c @@ -417,8 +417,13 @@ static DEVICE_ATTR_RW(user_pin_configs); static DEVICE_ATTR_WO(reconfig); static DEVICE_ATTR_WO(clear); -/* - * Look for hint string +/** + * snd_hda_get_hint - Look for hint string + * @codec: the HDA codec + * @key: the hint key string + * + * Look for a hint key/value pair matching with the given key string + * and returns the value string. If nothing found, returns NULL. */ const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) { @@ -427,6 +432,15 @@ const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) } EXPORT_SYMBOL_GPL(snd_hda_get_hint); +/** + * snd_hda_get_bool_hint - Get a boolean hint value + * @codec: the HDA codec + * @key: the hint key string + * + * Look for a hint key/value pair matching with the given key string + * and returns a boolean value parsed from the value. If no matching + * key is found, return a negative value. + */ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) { const char *p; @@ -453,6 +467,16 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) } EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint); +/** + * snd_hda_get_bool_hint - Get a boolean hint value + * @codec: the HDA codec + * @key: the hint key string + * @valp: pointer to store a value + * + * Look for a hint key/value pair matching with the given key string + * and stores the integer value to @valp. If no matching key is found, + * return a negative error code. Otherwise it returns zero. + */ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) { const char *p; @@ -690,8 +714,11 @@ static int get_line_from_fw(char *buf, int size, size_t *fw_size_p, return 1; } -/* - * load a "patch" firmware file and parse it +/** + * snd_hda_load_patch - load a "patch" firmware file and parse it + * @bus: HD-audio bus + * @fw_size: the firmware byte size + * @fw_buf: the firmware data */ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) { -- GitLab From df57de172a47f16548ee4bb69d1110e32686d6a9 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 29 Oct 2014 20:09:45 +0530 Subject: [PATCH 2007/9457] ALSA: hdspm: remove unused variable removed the unused variables. These variables were only being assigned some value, but the values were never being used. it has been build tested after removing the variables. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 7f7277bfb66a..e09348c156d8 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1257,14 +1257,13 @@ static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate) /* check for external sample rate, returns the sample rate in Hz*/ static int hdspm_external_sample_rate(struct hdspm *hdspm) { - unsigned int status, status2, timecode; + unsigned int status, status2; int syncref, rate = 0, rate_bits; switch (hdspm->io_type) { case AES32: status2 = hdspm_read(hdspm, HDSPM_statusRegister2); status = hdspm_read(hdspm, HDSPM_statusRegister); - timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); syncref = hdspm_autosync_ref(hdspm); switch (syncref) { @@ -4862,18 +4861,15 @@ snd_hdspm_proc_read_madi(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct hdspm *hdspm = entry->private_data; - unsigned int status, status2, control, freq; + unsigned int status, status2; char *pref_sync_ref; char *autosync_ref; char *system_clock_mode; - char *insel; int x, x2; status = hdspm_read(hdspm, HDSPM_statusRegister); status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - control = hdspm->control_register; - freq = hdspm_read(hdspm, HDSPM_timecodeRegister); snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", hdspm->card_name, hdspm->card->number + 1, @@ -4936,17 +4932,6 @@ snd_hdspm_proc_read_madi(struct snd_info_entry *entry, snd_iprintf(buffer, "Line out: %s\n", (hdspm->control_register & HDSPM_LineOut) ? "on " : "off"); - switch (hdspm->control_register & HDSPM_InputMask) { - case HDSPM_InputOptical: - insel = "Optical"; - break; - case HDSPM_InputCoaxial: - insel = "Coaxial"; - break; - default: - insel = "Unknown"; - } - snd_iprintf(buffer, "ClearTrackMarker = %s, Transmit in %s Channel Mode, " "Auto Input %s\n", @@ -5191,15 +5176,13 @@ snd_hdspm_proc_read_raydat(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct hdspm *hdspm = entry->private_data; - unsigned int status1, status2, status3, control, i; + unsigned int status1, status2, status3, i; unsigned int lock, sync; status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */ status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */ status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */ - control = hdspm->control_register; - snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1); snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2); snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3); -- GitLab From 56e4dea81a55c338eede625f715c7fa21f1a28c4 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 27 Oct 2014 10:49:45 -0500 Subject: [PATCH 2008/9457] percpu: Convert remaining __get_cpu_var uses in 3.18-rcX During the 3.18 merge period additional __get_cpu_var uses were added. The patch converts these to this_cpu_ptr(). Signed-off-by: Christoph Lameter Acked-by: Will Deacon Acked-by: Thomas Gleixner Signed-off-by: Tejun Heo --- arch/arm64/kernel/psci.c | 4 ++-- kernel/irq_work.c | 4 ++-- kernel/time/tick-sched.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 866c1c821860..d56394b6dc99 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -511,7 +511,7 @@ static int cpu_psci_cpu_kill(unsigned int cpu) static int psci_suspend_finisher(unsigned long index) { - struct psci_power_state *state = __get_cpu_var(psci_power_state); + struct psci_power_state *state = __this_cpu_read(psci_power_state); return psci_ops.cpu_suspend(state[index - 1], virt_to_phys(cpu_resume)); @@ -520,7 +520,7 @@ static int psci_suspend_finisher(unsigned long index) static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) { int ret; - struct psci_power_state *state = __get_cpu_var(psci_power_state); + struct psci_power_state *state = __this_cpu_read(psci_power_state); /* * idle state index 0 corresponds to wfi, should never be called * from the cpu_suspend operations diff --git a/kernel/irq_work.c b/kernel/irq_work.c index 3ab9048483fa..cbf9fb899d92 100644 --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -175,11 +175,11 @@ EXPORT_SYMBOL_GPL(irq_work_run); void irq_work_tick(void) { - struct llist_head *raised = &__get_cpu_var(raised_list); + struct llist_head *raised = this_cpu_ptr(&raised_list); if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) irq_work_run_list(raised); - irq_work_run_list(&__get_cpu_var(lazy_list)); + irq_work_run_list(this_cpu_ptr(&lazy_list)); } /* diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 7b5741fc4110..b1c6a512cdd0 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -235,7 +235,7 @@ void tick_nohz_full_kick(void) if (!tick_nohz_full_cpu(smp_processor_id())) return; - irq_work_queue(&__get_cpu_var(nohz_full_kick_work)); + irq_work_queue(this_cpu_ptr(&nohz_full_kick_work)); } /* -- GitLab From 9cfd5a23a49c2a2cb9ff5537128d03547cbd2990 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 29 Oct 2014 10:16:00 +0200 Subject: [PATCH 2009/9457] Bluetooth: Wrong style spin lock used Use spin_lock_bh() as the code is called from softirq in networking subsystem. This is needed to prevent deadlocks when 6lowpan link is in use. Signed-off-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ddf33900f7f3..91995f8ab0a0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4661,8 +4661,12 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, skb_shinfo(skb)->frag_list = NULL; - /* Queue all fragments atomically */ - spin_lock(&queue->lock); + /* Queue all fragments atomically. We need to use spin_lock_bh + * here because of 6LoWPAN links, as there this function is + * called from softirq and using normal spin lock could cause + * deadlocks. + */ + spin_lock_bh(&queue->lock); __skb_queue_tail(queue, skb); @@ -4679,7 +4683,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, __skb_queue_tail(queue, skb); } while (list); - spin_unlock(&queue->lock); + spin_unlock_bh(&queue->lock); } } -- GitLab From eb63192bb8cc0186265aad4f79fa4fd49c22b021 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 11:44:16 +0300 Subject: [PATCH 2010/9457] SUNRPC: off by one in BUG_ON() The m->pool_to[] array has "maxpools" number of elements. It's allocated in svc_pool_map_alloc_arrays() which we called earlier in the function. This test should be >= instead of >. Signed-off-by: Dan Carpenter Signed-off-by: J. Bruce Fields --- net/sunrpc/svc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index ca8a7958f4e6..349c98f9818b 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -189,7 +189,7 @@ svc_pool_map_init_percpu(struct svc_pool_map *m) return err; for_each_online_cpu(cpu) { - BUG_ON(pidx > maxpools); + BUG_ON(pidx >= maxpools); m->to_pool[cpu] = pidx; m->pool_to[pidx] = cpu; pidx++; -- GitLab From 5940c3e4f3a0164d8720775f2cc922104569f0dc Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 27 Oct 2014 12:44:46 +0200 Subject: [PATCH 2011/9457] mac80211-hwsim: Rename CREATE and DESTROY radio to NEW and DEL radio Using the name HWSIM_CMD_NEW_RADIO and HWSIM_CMD_DEL_RADIO is more fitting on how other pieces of the wireless system work. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index f560b7493968..448e64b619cb 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -65,9 +65,10 @@ enum hwsim_tx_control_flags { * kernel, uses: * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE - * @HWSIM_CMD_CREATE_RADIO: create a new radio with the given parameters, - * returns the radio ID (>= 0) or negative on errors - * @HWSIM_CMD_DESTROY_RADIO: destroy a radio + * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, + * returns the radio ID (>= 0) or negative on errors, if successful + * then multicast the result + * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted * @__HWSIM_CMD_MAX: enum limit */ enum { @@ -75,12 +76,15 @@ enum { HWSIM_CMD_REGISTER, HWSIM_CMD_FRAME, HWSIM_CMD_TX_INFO_FRAME, - HWSIM_CMD_CREATE_RADIO, - HWSIM_CMD_DESTROY_RADIO, + HWSIM_CMD_NEW_RADIO, + HWSIM_CMD_DEL_RADIO, __HWSIM_CMD_MAX, }; #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) +#define HWSIM_CMD_CREATE_RADIO HWSIM_CMD_NEW_RADIO +#define HWSIM_CMD_DESTROY_RADIO HWSIM_CMD_DEL_RADIO + /** * enum hwsim_attrs - hwsim netlink attributes * -- GitLab From ef0bbac33dc051057237d1dac82e1d218b0cf306 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 16:15:22 +0530 Subject: [PATCH 2012/9457] MAINTAINERS: add cc2520 driver maintainer This patch adds maintainer for cc2520 radio driver Signed-off-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 15867a680422..7ec37a396ffe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2302,6 +2302,14 @@ F: security/capability.c F: security/commoncap.c F: kernel/capability.c +CC2520 IEEE-802.15.4 RADIO DRIVER +M: Varka Bhadram +L: linux-wpan@vger.kernel.org +S: Maintained +F: drivers/net/ieee802154/cc2520.c +F: include/linux/spi/cc2520.h +F: Documentation/devicetree/bindings/net/ieee802154/cc2520.txt + CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann L: linuxppc-dev@lists.ozlabs.org -- GitLab From 137f6d541ae75b3769c4c67e61c25340789b3cbc Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 29 Oct 2014 15:40:27 +0000 Subject: [PATCH 2013/9457] ASoC: Intel: dw_pdata can be static sound/soc/intel/sst-firmware.c:172:29: sparse: symbol 'dw_pdata' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 692a6aef82df..35788ad4087e 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -169,7 +169,7 @@ static int block_list_prepare(struct sst_dsp *dsp, return ret; } -struct dw_dma_platform_data dw_pdata = { +static struct dw_dma_platform_data dw_pdata = { .is_private = 1, .chan_allocation_order = CHAN_ALLOCATION_ASCENDING, .chan_priority = CHAN_PRIORITY_ASCENDING, -- GitLab From d96c53a193dd65380452c8e9f6dcf15cf829c7dc Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 29 Oct 2014 15:40:28 +0000 Subject: [PATCH 2014/9457] ASoC: Intel: Add generic support for DSP wake, sleep and stall Add generic functions to support DSP sleep, wake and stall. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-dsp-priv.h | 3 +++ sound/soc/intel/sst-dsp.c | 23 +++++++++++++++++++++++ sound/soc/intel/sst-dsp.h | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index be81b86b6462..b9da030e312d 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h @@ -36,6 +36,9 @@ struct sst_ops { /* DSP core boot / reset */ void (*boot)(struct sst_dsp *); void (*reset)(struct sst_dsp *); + int (*wake)(struct sst_dsp *); + void (*sleep)(struct sst_dsp *); + void (*stall)(struct sst_dsp *); /* Shim IO */ void (*write)(void __iomem *addr, u32 offset, u32 value); diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c index d0fc6853b2b7..86e410845670 100644 --- a/sound/soc/intel/sst-dsp.c +++ b/sound/soc/intel/sst-dsp.c @@ -245,6 +245,29 @@ int sst_dsp_boot(struct sst_dsp *sst) } EXPORT_SYMBOL_GPL(sst_dsp_boot); +int sst_dsp_wake(struct sst_dsp *sst) +{ + if (sst->ops->wake) + return sst->ops->wake(sst); + + return 0; +} +EXPORT_SYMBOL_GPL(sst_dsp_wake); + +void sst_dsp_sleep(struct sst_dsp *sst) +{ + if (sst->ops->sleep) + sst->ops->sleep(sst); +} +EXPORT_SYMBOL_GPL(sst_dsp_sleep); + +void sst_dsp_stall(struct sst_dsp *sst) +{ + if (sst->ops->stall) + sst->ops->stall(sst); +} +EXPORT_SYMBOL_GPL(sst_dsp_stall); + void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg) { sst_dsp_shim_write_unlocked(dsp, SST_IPCX, msg | SST_IPCX_BUSY); diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h index 17ee9239092a..7bb482053489 100644 --- a/sound/soc/intel/sst-dsp.h +++ b/sound/soc/intel/sst-dsp.h @@ -245,6 +245,10 @@ void sst_memcpy_fromio_32(struct sst_dsp *sst, /* DSP reset & boot */ void sst_dsp_reset(struct sst_dsp *sst); int sst_dsp_boot(struct sst_dsp *sst); +int sst_dsp_wake(struct sst_dsp *sst); +void sst_dsp_sleep(struct sst_dsp *sst); +void sst_dsp_stall(struct sst_dsp *sst); + /* DMA */ int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id); void sst_dsp_dma_put_channel(struct sst_dsp *dsp); -- GitLab From 1fef62c1423b694da517b18dc80d59a7eaf7dd74 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 21 Oct 2014 15:08:41 +0200 Subject: [PATCH 2015/9457] mtd: nand: add sunxi NAND flash controller support Add support for the sunxi NAND Flash Controller (NFC). Signed-off-by: Boris Brezillon [Brian: tweaked to fix ecc->steps issue] Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 6 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/sunxi_nand.c | 1432 +++++++++++++++++++++++++++++++++ 3 files changed, 1439 insertions(+) create mode 100644 drivers/mtd/nand/sunxi_nand.c diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index dd10646982ae..4c51d2c9acc1 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -516,4 +516,10 @@ config MTD_NAND_XWAY Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached to the External Bus Unit (EBU). +config MTD_NAND_SUNXI + tristate "Support for NAND on Allwinner SoCs" + depends on ARCH_SUNXI + help + Enables support for NAND Flash chips on Allwinner SoCs. + endif # MTD_NAND diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 9c847e469ca7..bd38f21d2e28 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -50,5 +50,6 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ +obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o nand-objs := nand_base.o nand_bbt.o nand_timings.o diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c new file mode 100644 index 000000000000..ccaa8e283388 --- /dev/null +++ b/drivers/mtd/nand/sunxi_nand.c @@ -0,0 +1,1432 @@ +/* + * Copyright (C) 2013 Boris BREZILLON + * + * Derived from: + * https://github.com/yuq/sunxi-nfc-mtd + * Copyright (C) 2013 Qiang Yu + * + * https://github.com/hno/Allwinner-Info + * Copyright (C) 2013 Henrik Nordström + * + * Copyright (C) 2013 Dmitriy B. + * Copyright (C) 2013 Sergey Lapin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NFC_REG_CTL 0x0000 +#define NFC_REG_ST 0x0004 +#define NFC_REG_INT 0x0008 +#define NFC_REG_TIMING_CTL 0x000C +#define NFC_REG_TIMING_CFG 0x0010 +#define NFC_REG_ADDR_LOW 0x0014 +#define NFC_REG_ADDR_HIGH 0x0018 +#define NFC_REG_SECTOR_NUM 0x001C +#define NFC_REG_CNT 0x0020 +#define NFC_REG_CMD 0x0024 +#define NFC_REG_RCMD_SET 0x0028 +#define NFC_REG_WCMD_SET 0x002C +#define NFC_REG_IO_DATA 0x0030 +#define NFC_REG_ECC_CTL 0x0034 +#define NFC_REG_ECC_ST 0x0038 +#define NFC_REG_DEBUG 0x003C +#define NFC_REG_ECC_CNT0 0x0040 +#define NFC_REG_ECC_CNT1 0x0044 +#define NFC_REG_ECC_CNT2 0x0048 +#define NFC_REG_ECC_CNT3 0x004c +#define NFC_REG_USER_DATA_BASE 0x0050 +#define NFC_REG_SPARE_AREA 0x00A0 +#define NFC_RAM0_BASE 0x0400 +#define NFC_RAM1_BASE 0x0800 + +/* define bit use in NFC_CTL */ +#define NFC_EN BIT(0) +#define NFC_RESET BIT(1) +#define NFC_BUS_WIDYH BIT(2) +#define NFC_RB_SEL BIT(3) +#define NFC_CE_SEL GENMASK(26, 24) +#define NFC_CE_CTL BIT(6) +#define NFC_CE_CTL1 BIT(7) +#define NFC_PAGE_SIZE GENMASK(11, 8) +#define NFC_SAM BIT(12) +#define NFC_RAM_METHOD BIT(14) +#define NFC_DEBUG_CTL BIT(31) + +/* define bit use in NFC_ST */ +#define NFC_RB_B2R BIT(0) +#define NFC_CMD_INT_FLAG BIT(1) +#define NFC_DMA_INT_FLAG BIT(2) +#define NFC_CMD_FIFO_STATUS BIT(3) +#define NFC_STA BIT(4) +#define NFC_NATCH_INT_FLAG BIT(5) +#define NFC_RB_STATE0 BIT(8) +#define NFC_RB_STATE1 BIT(9) +#define NFC_RB_STATE2 BIT(10) +#define NFC_RB_STATE3 BIT(11) + +/* define bit use in NFC_INT */ +#define NFC_B2R_INT_ENABLE BIT(0) +#define NFC_CMD_INT_ENABLE BIT(1) +#define NFC_DMA_INT_ENABLE BIT(2) +#define NFC_INT_MASK (NFC_B2R_INT_ENABLE | \ + NFC_CMD_INT_ENABLE | \ + NFC_DMA_INT_ENABLE) + +/* define bit use in NFC_CMD */ +#define NFC_CMD_LOW_BYTE GENMASK(7, 0) +#define NFC_CMD_HIGH_BYTE GENMASK(15, 8) +#define NFC_ADR_NUM GENMASK(18, 16) +#define NFC_SEND_ADR BIT(19) +#define NFC_ACCESS_DIR BIT(20) +#define NFC_DATA_TRANS BIT(21) +#define NFC_SEND_CMD1 BIT(22) +#define NFC_WAIT_FLAG BIT(23) +#define NFC_SEND_CMD2 BIT(24) +#define NFC_SEQ BIT(25) +#define NFC_DATA_SWAP_METHOD BIT(26) +#define NFC_ROW_AUTO_INC BIT(27) +#define NFC_SEND_CMD3 BIT(28) +#define NFC_SEND_CMD4 BIT(29) +#define NFC_CMD_TYPE GENMASK(31, 30) + +/* define bit use in NFC_RCMD_SET */ +#define NFC_READ_CMD GENMASK(7, 0) +#define NFC_RANDOM_READ_CMD0 GENMASK(15, 8) +#define NFC_RANDOM_READ_CMD1 GENMASK(23, 16) + +/* define bit use in NFC_WCMD_SET */ +#define NFC_PROGRAM_CMD GENMASK(7, 0) +#define NFC_RANDOM_WRITE_CMD GENMASK(15, 8) +#define NFC_READ_CMD0 GENMASK(23, 16) +#define NFC_READ_CMD1 GENMASK(31, 24) + +/* define bit use in NFC_ECC_CTL */ +#define NFC_ECC_EN BIT(0) +#define NFC_ECC_PIPELINE BIT(3) +#define NFC_ECC_EXCEPTION BIT(4) +#define NFC_ECC_BLOCK_SIZE BIT(5) +#define NFC_RANDOM_EN BIT(9) +#define NFC_RANDOM_DIRECTION BIT(10) +#define NFC_ECC_MODE_SHIFT 12 +#define NFC_ECC_MODE GENMASK(15, 12) +#define NFC_RANDOM_SEED GENMASK(30, 16) + +#define NFC_DEFAULT_TIMEOUT_MS 1000 + +#define NFC_SRAM_SIZE 1024 + +#define NFC_MAX_CS 7 + +/* + * Ready/Busy detection type: describes the Ready/Busy detection modes + * + * @RB_NONE: no external detection available, rely on STATUS command + * and software timeouts + * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy + * pin of the NAND flash chip must be connected to one of the + * native NAND R/B pins (those which can be muxed to the NAND + * Controller) + * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy + * pin of the NAND flash chip must be connected to a GPIO capable + * pin. + */ +enum sunxi_nand_rb_type { + RB_NONE, + RB_NATIVE, + RB_GPIO, +}; + +/* + * Ready/Busy structure: stores information related to Ready/Busy detection + * + * @type: the Ready/Busy detection mode + * @info: information related to the R/B detection mode. Either a gpio + * id or a native R/B id (those supported by the NAND controller). + */ +struct sunxi_nand_rb { + enum sunxi_nand_rb_type type; + union { + int gpio; + int nativeid; + } info; +}; + +/* + * Chip Select structure: stores information related to NAND Chip Select + * + * @cs: the NAND CS id used to communicate with a NAND Chip + * @rb: the Ready/Busy description + */ +struct sunxi_nand_chip_sel { + u8 cs; + struct sunxi_nand_rb rb; +}; + +/* + * sunxi HW ECC infos: stores information related to HW ECC support + * + * @mode: the sunxi ECC mode field deduced from ECC requirements + * @layout: the OOB layout depending on the ECC requirements and the + * selected ECC mode + */ +struct sunxi_nand_hw_ecc { + int mode; + struct nand_ecclayout layout; +}; + +/* + * NAND chip structure: stores NAND chip device related information + * + * @node: used to store NAND chips into a list + * @nand: base NAND chip structure + * @mtd: base MTD structure + * @clk_rate: clk_rate required for this NAND chip + * @selected: current active CS + * @nsels: number of CS lines required by the NAND chip + * @sels: array of CS lines descriptions + */ +struct sunxi_nand_chip { + struct list_head node; + struct nand_chip nand; + struct mtd_info mtd; + unsigned long clk_rate; + int selected; + int nsels; + struct sunxi_nand_chip_sel sels[0]; +}; + +static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) +{ + return container_of(nand, struct sunxi_nand_chip, nand); +} + +/* + * NAND Controller structure: stores sunxi NAND controller information + * + * @controller: base controller structure + * @dev: parent device (used to print error messages) + * @regs: NAND controller registers + * @ahb_clk: NAND Controller AHB clock + * @mod_clk: NAND Controller mod clock + * @assigned_cs: bitmask describing already assigned CS lines + * @clk_rate: NAND controller current clock rate + * @chips: a list containing all the NAND chips attached to + * this NAND controller + * @complete: a completion object used to wait for NAND + * controller events + */ +struct sunxi_nfc { + struct nand_hw_control controller; + struct device *dev; + void __iomem *regs; + struct clk *ahb_clk; + struct clk *mod_clk; + unsigned long assigned_cs; + unsigned long clk_rate; + struct list_head chips; + struct completion complete; +}; + +static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl) +{ + return container_of(ctrl, struct sunxi_nfc, controller); +} + +static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id) +{ + struct sunxi_nfc *nfc = dev_id; + u32 st = readl(nfc->regs + NFC_REG_ST); + u32 ien = readl(nfc->regs + NFC_REG_INT); + + if (!(ien & st)) + return IRQ_NONE; + + if ((ien & st) == ien) + complete(&nfc->complete); + + writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST); + writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT); + + return IRQ_HANDLED; +} + +static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags, + unsigned int timeout_ms) +{ + init_completion(&nfc->complete); + + writel(flags, nfc->regs + NFC_REG_INT); + + if (!timeout_ms) + timeout_ms = NFC_DEFAULT_TIMEOUT_MS; + + if (!wait_for_completion_timeout(&nfc->complete, + msecs_to_jiffies(timeout_ms))) { + dev_err(nfc->dev, "wait interrupt timedout\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc) +{ + unsigned long timeout = jiffies + + msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS); + + do { + if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS)) + return 0; + } while (time_before(jiffies, timeout)); + + dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n"); + return -ETIMEDOUT; +} + +static int sunxi_nfc_rst(struct sunxi_nfc *nfc) +{ + unsigned long timeout = jiffies + + msecs_to_jiffies(NFC_DEFAULT_TIMEOUT_MS); + + writel(0, nfc->regs + NFC_REG_ECC_CTL); + writel(NFC_RESET, nfc->regs + NFC_REG_CTL); + + do { + if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET)) + return 0; + } while (time_before(jiffies, timeout)); + + dev_err(nfc->dev, "wait for NAND controller reset timedout\n"); + return -ETIMEDOUT; +} + +static int sunxi_nfc_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_rb *rb; + unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20); + int ret; + + if (sunxi_nand->selected < 0) + return 0; + + rb = &sunxi_nand->sels[sunxi_nand->selected].rb; + + switch (rb->type) { + case RB_NATIVE: + ret = !!(readl(nfc->regs + NFC_REG_ST) & + (NFC_RB_STATE0 << rb->info.nativeid)); + if (ret) + break; + + sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo); + ret = !!(readl(nfc->regs + NFC_REG_ST) & + (NFC_RB_STATE0 << rb->info.nativeid)); + break; + case RB_GPIO: + ret = gpio_get_value(rb->info.gpio); + break; + case RB_NONE: + default: + ret = 0; + dev_err(nfc->dev, "cannot check R/B NAND status!\n"); + break; + } + + return ret; +} + +static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_chip_sel *sel; + u32 ctl; + + if (chip > 0 && chip >= sunxi_nand->nsels) + return; + + if (chip == sunxi_nand->selected) + return; + + ctl = readl(nfc->regs + NFC_REG_CTL) & + ~(NFC_CE_SEL | NFC_RB_SEL | NFC_EN); + + if (chip >= 0) { + sel = &sunxi_nand->sels[chip]; + + ctl |= (sel->cs << 24) | NFC_EN | + (((nand->page_shift - 10) & 0xf) << 8); + if (sel->rb.type == RB_NONE) { + nand->dev_ready = NULL; + } else { + nand->dev_ready = sunxi_nfc_dev_ready; + if (sel->rb.type == RB_NATIVE) + ctl |= (sel->rb.info.nativeid << 3); + } + + writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA); + + if (nfc->clk_rate != sunxi_nand->clk_rate) { + clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate); + nfc->clk_rate = sunxi_nand->clk_rate; + } + } + + writel(ctl, nfc->regs + NFC_REG_CTL); + + sunxi_nand->selected = chip; +} + +static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + int cnt; + int offs = 0; + u32 tmp; + + while (len > offs) { + cnt = min(len - offs, NFC_SRAM_SIZE); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + break; + + writel(cnt, nfc->regs + NFC_REG_CNT); + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD; + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + break; + + if (buf) + memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, + cnt); + offs += cnt; + } +} + +static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, + int len) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + int cnt; + int offs = 0; + u32 tmp; + + while (len > offs) { + cnt = min(len - offs, NFC_SRAM_SIZE); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + break; + + writel(cnt, nfc->regs + NFC_REG_CNT); + memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt); + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | + NFC_ACCESS_DIR; + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + break; + + offs += cnt; + } +} + +static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd) +{ + uint8_t ret; + + sunxi_nfc_read_buf(mtd, &ret, 1); + + return ret; +} + +static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, + unsigned int ctrl) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + int ret; + u32 tmp; + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return; + + if (ctrl & NAND_CTRL_CHANGE) { + tmp = readl(nfc->regs + NFC_REG_CTL); + if (ctrl & NAND_NCE) + tmp |= NFC_CE_CTL; + else + tmp &= ~NFC_CE_CTL; + writel(tmp, nfc->regs + NFC_REG_CTL); + } + + if (dat == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) { + writel(NFC_SEND_CMD1 | dat, nfc->regs + NFC_REG_CMD); + } else { + writel(dat, nfc->regs + NFC_REG_ADDR_LOW); + writel(NFC_SEND_ADR, nfc->regs + NFC_REG_CMD); + } + + sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); +} + +static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct nand_ecclayout *layout = ecc->layout; + struct sunxi_nand_hw_ecc *data = ecc->priv; + unsigned int max_bitflips = 0; + int offset; + int ret; + u32 tmp; + int i; + int cnt; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + if (i) + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i * ecc->size, -1); + + offset = mtd->writesize + layout->eccpos[i * ecc->bytes] - 4; + + chip->read_buf(mtd, NULL, ecc->size); + + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + memcpy_fromio(buf + (i * ecc->size), + nfc->regs + NFC_RAM0_BASE, ecc->size); + + if (readl(nfc->regs + NFC_REG_ECC_ST) & 0x1) { + mtd->ecc_stats.failed++; + } else { + tmp = readl(nfc->regs + NFC_REG_ECC_CNT0) & 0xff; + mtd->ecc_stats.corrected += tmp; + max_bitflips = max_t(unsigned int, max_bitflips, tmp); + } + + if (oob_required) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + offset -= mtd->writesize; + chip->read_buf(mtd, chip->oob_poi + offset, + ecc->bytes + 4); + } + } + + if (oob_required) { + cnt = ecc->layout->oobfree[ecc->steps].length; + if (cnt > 0) { + offset = mtd->writesize + + ecc->layout->oobfree[ecc->steps].offset; + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + offset -= mtd->writesize; + chip->read_buf(mtd, chip->oob_poi + offset, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return max_bitflips; +} + +static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf, int oob_required) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct nand_ecclayout *layout = ecc->layout; + struct sunxi_nand_hw_ecc *data = ecc->priv; + int offset; + int ret; + u32 tmp; + int i; + int cnt; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + if (i) + chip->cmdfunc(mtd, NAND_CMD_RNDIN, i * ecc->size, -1); + + chip->write_buf(mtd, buf + (i * ecc->size), ecc->size); + + offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize; + + /* Fill OOB data in */ + if (oob_required) { + tmp = 0xffffffff; + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, + 4); + } else { + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, + chip->oob_poi + offset - mtd->writesize, + 4); + } + + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + + ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); + if (ret) + return ret; + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | + (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + } + + if (oob_required) { + cnt = ecc->layout->oobfree[i].length; + if (cnt > 0) { + offset = mtd->writesize + + ecc->layout->oobfree[i].offset; + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + offset -= mtd->writesize; + chip->write_buf(mtd, chip->oob_poi + offset, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return 0; +} + +static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf, int oob_required, + int page) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct sunxi_nand_hw_ecc *data = ecc->priv; + unsigned int max_bitflips = 0; + uint8_t *oob = chip->oob_poi; + int offset = 0; + int ret; + int cnt; + u32 tmp; + int i; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + chip->read_buf(mtd, NULL, ecc->size); + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + memcpy_fromio(buf, nfc->regs + NFC_RAM0_BASE, ecc->size); + buf += ecc->size; + offset += ecc->size; + + if (readl(nfc->regs + NFC_REG_ECC_ST) & 0x1) { + mtd->ecc_stats.failed++; + } else { + tmp = readl(nfc->regs + NFC_REG_ECC_CNT0) & 0xff; + mtd->ecc_stats.corrected += tmp; + max_bitflips = max_t(unsigned int, max_bitflips, tmp); + } + + if (oob_required) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + chip->read_buf(mtd, oob, ecc->bytes + ecc->prepad); + oob += ecc->bytes + ecc->prepad; + } + + offset += ecc->bytes + ecc->prepad; + } + + if (oob_required) { + cnt = mtd->oobsize - (oob - chip->oob_poi); + if (cnt > 0) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); + chip->read_buf(mtd, oob, cnt); + } + } + + writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, + nfc->regs + NFC_REG_ECC_CTL); + + return max_bitflips; +} + +static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf, + int oob_required) +{ + struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller); + struct nand_ecc_ctrl *ecc = &chip->ecc; + struct sunxi_nand_hw_ecc *data = ecc->priv; + uint8_t *oob = chip->oob_poi; + int offset = 0; + int ret; + int cnt; + u32 tmp; + int i; + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~(NFC_ECC_MODE | NFC_ECC_PIPELINE | NFC_ECC_BLOCK_SIZE); + tmp |= NFC_ECC_EN | (data->mode << NFC_ECC_MODE_SHIFT) | + NFC_ECC_EXCEPTION; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + for (i = 0; i < ecc->steps; i++) { + chip->write_buf(mtd, buf + (i * ecc->size), ecc->size); + offset += ecc->size; + + /* Fill OOB data in */ + if (oob_required) { + tmp = 0xffffffff; + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, + 4); + } else { + memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob, + 4); + } + + tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | + (1 << 30); + writel(tmp, nfc->regs + NFC_REG_CMD); + + ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + if (ret) + return ret; + + offset += ecc->bytes + ecc->prepad; + oob += ecc->bytes + ecc->prepad; + } + + if (oob_required) { + cnt = mtd->oobsize - (oob - chip->oob_poi); + if (cnt > 0) { + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); + chip->write_buf(mtd, oob, cnt); + } + } + + tmp = readl(nfc->regs + NFC_REG_ECC_CTL); + tmp &= ~NFC_ECC_EN; + + writel(tmp, nfc->regs + NFC_REG_ECC_CTL); + + return 0; +} + +static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip, + const struct nand_sdr_timings *timings) +{ + u32 min_clk_period = 0; + + /* T1 <=> tCLS */ + if (timings->tCLS_min > min_clk_period) + min_clk_period = timings->tCLS_min; + + /* T2 <=> tCLH */ + if (timings->tCLH_min > min_clk_period) + min_clk_period = timings->tCLH_min; + + /* T3 <=> tCS */ + if (timings->tCS_min > min_clk_period) + min_clk_period = timings->tCS_min; + + /* T4 <=> tCH */ + if (timings->tCH_min > min_clk_period) + min_clk_period = timings->tCH_min; + + /* T5 <=> tWP */ + if (timings->tWP_min > min_clk_period) + min_clk_period = timings->tWP_min; + + /* T6 <=> tWH */ + if (timings->tWH_min > min_clk_period) + min_clk_period = timings->tWH_min; + + /* T7 <=> tALS */ + if (timings->tALS_min > min_clk_period) + min_clk_period = timings->tALS_min; + + /* T8 <=> tDS */ + if (timings->tDS_min > min_clk_period) + min_clk_period = timings->tDS_min; + + /* T9 <=> tDH */ + if (timings->tDH_min > min_clk_period) + min_clk_period = timings->tDH_min; + + /* T10 <=> tRR */ + if (timings->tRR_min > (min_clk_period * 3)) + min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3); + + /* T11 <=> tALH */ + if (timings->tALH_min > min_clk_period) + min_clk_period = timings->tALH_min; + + /* T12 <=> tRP */ + if (timings->tRP_min > min_clk_period) + min_clk_period = timings->tRP_min; + + /* T13 <=> tREH */ + if (timings->tREH_min > min_clk_period) + min_clk_period = timings->tREH_min; + + /* T14 <=> tRC */ + if (timings->tRC_min > (min_clk_period * 2)) + min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2); + + /* T15 <=> tWC */ + if (timings->tWC_min > (min_clk_period * 2)) + min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2); + + + /* Convert min_clk_period from picoseconds to nanoseconds */ + min_clk_period = DIV_ROUND_UP(min_clk_period, 1000); + + /* + * Convert min_clk_period into a clk frequency, then get the + * appropriate rate for the NAND controller IP given this formula + * (specified in the datasheet): + * nand clk_rate = 2 * min_clk_rate + */ + chip->clk_rate = (2 * NSEC_PER_SEC) / min_clk_period; + + /* TODO: configure T16-T19 */ + + return 0; +} + +static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, + struct device_node *np) +{ + const struct nand_sdr_timings *timings; + int ret; + int mode; + + mode = onfi_get_async_timing_mode(&chip->nand); + if (mode == ONFI_TIMING_MODE_UNKNOWN) { + mode = chip->nand.onfi_timing_mode_default; + } else { + uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {}; + + mode = fls(mode) - 1; + if (mode < 0) + mode = 0; + + feature[0] = mode; + ret = chip->nand.onfi_set_features(&chip->mtd, &chip->nand, + ONFI_FEATURE_ADDR_TIMING_MODE, + feature); + if (ret) + return ret; + } + + timings = onfi_async_timing_mode_to_sdr_timings(mode); + if (IS_ERR(timings)) + return PTR_ERR(timings); + + return sunxi_nand_chip_set_timings(chip, timings); +} + +static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; + struct nand_chip *nand = mtd->priv; + struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); + struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + struct sunxi_nand_hw_ecc *data; + struct nand_ecclayout *layout; + int nsectors; + int ret; + int i; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* Add ECC info retrieval from DT */ + for (i = 0; i < ARRAY_SIZE(strengths); i++) { + if (ecc->strength <= strengths[i]) + break; + } + + if (i >= ARRAY_SIZE(strengths)) { + dev_err(nfc->dev, "unsupported strength\n"); + ret = -ENOTSUPP; + goto err; + } + + data->mode = i; + + /* HW ECC always request ECC bytes for 1024 bytes blocks */ + ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); + + /* HW ECC always work with even numbers of ECC bytes */ + ecc->bytes = ALIGN(ecc->bytes, 2); + + layout = &data->layout; + nsectors = mtd->writesize / ecc->size; + + if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) { + ret = -EINVAL; + goto err; + } + + layout->eccbytes = (ecc->bytes * nsectors); + + ecc->layout = layout; + ecc->priv = data; + + return 0; + +err: + kfree(data); + + return ret; +} + +static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc) +{ + kfree(ecc->priv); +} + +static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_ecclayout *layout; + int nsectors; + int i, j; + int ret; + + ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + + ecc->read_page = sunxi_nfc_hw_ecc_read_page; + ecc->write_page = sunxi_nfc_hw_ecc_write_page; + layout = ecc->layout; + nsectors = mtd->writesize / ecc->size; + + for (i = 0; i < nsectors; i++) { + if (i) { + layout->oobfree[i].offset = + layout->oobfree[i - 1].offset + + layout->oobfree[i - 1].length + + ecc->bytes; + layout->oobfree[i].length = 4; + } else { + /* + * The first 2 bytes are used for BB markers, hence we + * only have 2 bytes available in the first user data + * section. + */ + layout->oobfree[i].length = 2; + layout->oobfree[i].offset = 2; + } + + for (j = 0; j < ecc->bytes; j++) + layout->eccpos[(ecc->bytes * i) + j] = + layout->oobfree[i].offset + + layout->oobfree[i].length + j; + } + + if (mtd->oobsize > (ecc->bytes + 4) * nsectors) { + layout->oobfree[nsectors].offset = + layout->oobfree[nsectors - 1].offset + + layout->oobfree[nsectors - 1].length + + ecc->bytes; + layout->oobfree[nsectors].length = mtd->oobsize - + ((ecc->bytes + 4) * nsectors); + } + + return 0; +} + +static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd, + struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_ecclayout *layout; + int nsectors; + int i; + int ret; + + ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + + ecc->prepad = 4; + ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page; + ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page; + + layout = ecc->layout; + nsectors = mtd->writesize / ecc->size; + + for (i = 0; i < (ecc->bytes * nsectors); i++) + layout->eccpos[i] = i; + + layout->oobfree[0].length = mtd->oobsize - i; + layout->oobfree[0].offset = i; + + return 0; +} + +static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) +{ + switch (ecc->mode) { + case NAND_ECC_HW: + case NAND_ECC_HW_SYNDROME: + sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc); + break; + case NAND_ECC_NONE: + kfree(ecc->layout); + default: + break; + } +} + +static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, + struct device_node *np) +{ + struct nand_chip *nand = mtd->priv; + int strength; + int blk_size; + int ret; + + blk_size = of_get_nand_ecc_step_size(np); + strength = of_get_nand_ecc_strength(np); + if (blk_size > 0 && strength > 0) { + ecc->size = blk_size; + ecc->strength = strength; + } else { + ecc->size = nand->ecc_step_ds; + ecc->strength = nand->ecc_strength_ds; + } + + if (!ecc->size || !ecc->strength) + return -EINVAL; + + ecc->mode = NAND_ECC_HW; + + ret = of_get_nand_ecc_mode(np); + if (ret >= 0) + ecc->mode = ret; + + switch (ecc->mode) { + case NAND_ECC_SOFT_BCH: + ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * ecc->size), + 8); + break; + case NAND_ECC_HW: + ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + break; + case NAND_ECC_HW_SYNDROME: + ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc, np); + if (ret) + return ret; + break; + case NAND_ECC_NONE: + ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL); + if (!ecc->layout) + return -ENOMEM; + ecc->layout->oobfree[0].length = mtd->oobsize; + case NAND_ECC_SOFT: + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, + struct device_node *np) +{ + const struct nand_sdr_timings *timings; + struct sunxi_nand_chip *chip; + struct mtd_part_parser_data ppdata; + struct mtd_info *mtd; + struct nand_chip *nand; + int nsels; + int ret; + int i; + u32 tmp; + + if (!of_get_property(np, "reg", &nsels)) + return -EINVAL; + + nsels /= sizeof(u32); + if (!nsels) { + dev_err(dev, "invalid reg property size\n"); + return -EINVAL; + } + + chip = devm_kzalloc(dev, + sizeof(*chip) + + (nsels * sizeof(struct sunxi_nand_chip_sel)), + GFP_KERNEL); + if (!chip) { + dev_err(dev, "could not allocate chip\n"); + return -ENOMEM; + } + + chip->nsels = nsels; + chip->selected = -1; + + for (i = 0; i < nsels; i++) { + ret = of_property_read_u32_index(np, "reg", i, &tmp); + if (ret) { + dev_err(dev, "could not retrieve reg property: %d\n", + ret); + return ret; + } + + if (tmp > NFC_MAX_CS) { + dev_err(dev, + "invalid reg value: %u (max CS = 7)\n", + tmp); + return -EINVAL; + } + + if (test_and_set_bit(tmp, &nfc->assigned_cs)) { + dev_err(dev, "CS %d already assigned\n", tmp); + return -EINVAL; + } + + chip->sels[i].cs = tmp; + + if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) && + tmp < 2) { + chip->sels[i].rb.type = RB_NATIVE; + chip->sels[i].rb.info.nativeid = tmp; + } else { + ret = of_get_named_gpio(np, "rb-gpios", i); + if (ret >= 0) { + tmp = ret; + chip->sels[i].rb.type = RB_GPIO; + chip->sels[i].rb.info.gpio = tmp; + ret = devm_gpio_request(dev, tmp, "nand-rb"); + if (ret) + return ret; + + ret = gpio_direction_input(tmp); + if (ret) + return ret; + } else { + chip->sels[i].rb.type = RB_NONE; + } + } + } + + timings = onfi_async_timing_mode_to_sdr_timings(0); + if (IS_ERR(timings)) { + ret = PTR_ERR(timings); + dev_err(dev, + "could not retrieve timings for ONFI mode 0: %d\n", + ret); + return ret; + } + + ret = sunxi_nand_chip_set_timings(chip, timings); + if (ret) { + dev_err(dev, "could not configure chip timings: %d\n", ret); + return ret; + } + + nand = &chip->nand; + /* Default tR value specified in the ONFI spec (chapter 4.15.1) */ + nand->chip_delay = 200; + nand->controller = &nfc->controller; + nand->select_chip = sunxi_nfc_select_chip; + nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; + nand->read_buf = sunxi_nfc_read_buf; + nand->write_buf = sunxi_nfc_write_buf; + nand->read_byte = sunxi_nfc_read_byte; + + if (of_get_nand_on_flash_bbt(np)) + nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; + + mtd = &chip->mtd; + mtd->dev.parent = dev; + mtd->priv = nand; + mtd->owner = THIS_MODULE; + + ret = nand_scan_ident(mtd, nsels, NULL); + if (ret) + return ret; + + ret = sunxi_nand_chip_init_timings(chip, np); + if (ret) { + dev_err(dev, "could not configure chip timings: %d\n", ret); + return ret; + } + + ret = sunxi_nand_ecc_init(mtd, &nand->ecc, np); + if (ret) { + dev_err(dev, "ECC init failed: %d\n", ret); + return ret; + } + + ret = nand_scan_tail(mtd); + if (ret) { + dev_err(dev, "nand_scan_tail failed: %d\n", ret); + return ret; + } + + ppdata.of_node = np; + ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); + if (ret) { + dev_err(dev, "failed to register mtd device: %d\n", ret); + nand_release(mtd); + return ret; + } + + list_add_tail(&chip->node, &nfc->chips); + + return 0; +} + +static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc) +{ + struct device_node *np = dev->of_node; + struct device_node *nand_np; + int nchips = of_get_child_count(np); + int ret; + + if (nchips > 8) { + dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips); + return -EINVAL; + } + + for_each_child_of_node(np, nand_np) { + ret = sunxi_nand_chip_init(dev, nfc, nand_np); + if (ret) + return ret; + } + + return 0; +} + +static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) +{ + struct sunxi_nand_chip *chip; + + while (!list_empty(&nfc->chips)) { + chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, + node); + nand_release(&chip->mtd); + sunxi_nand_ecc_cleanup(&chip->nand.ecc); + } +} + +static int sunxi_nfc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct sunxi_nfc *nfc; + int irq; + int ret; + + nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); + if (!nfc) + return -ENOMEM; + + nfc->dev = dev; + spin_lock_init(&nfc->controller.lock); + init_waitqueue_head(&nfc->controller.wq); + INIT_LIST_HEAD(&nfc->chips); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + nfc->regs = devm_ioremap_resource(dev, r); + if (IS_ERR(nfc->regs)) + return PTR_ERR(nfc->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "failed to retrieve irq\n"); + return irq; + } + + nfc->ahb_clk = devm_clk_get(dev, "ahb"); + if (IS_ERR(nfc->ahb_clk)) { + dev_err(dev, "failed to retrieve ahb clk\n"); + return PTR_ERR(nfc->ahb_clk); + } + + ret = clk_prepare_enable(nfc->ahb_clk); + if (ret) + return ret; + + nfc->mod_clk = devm_clk_get(dev, "mod"); + if (IS_ERR(nfc->mod_clk)) { + dev_err(dev, "failed to retrieve mod clk\n"); + ret = PTR_ERR(nfc->mod_clk); + goto out_ahb_clk_unprepare; + } + + ret = clk_prepare_enable(nfc->mod_clk); + if (ret) + goto out_ahb_clk_unprepare; + + ret = sunxi_nfc_rst(nfc); + if (ret) + goto out_mod_clk_unprepare; + + writel(0, nfc->regs + NFC_REG_INT); + ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt, + 0, "sunxi-nand", nfc); + if (ret) + goto out_mod_clk_unprepare; + + platform_set_drvdata(pdev, nfc); + + /* + * TODO: replace these magic values with proper flags as soon as we + * know what they are encoding. + */ + writel(0x100, nfc->regs + NFC_REG_TIMING_CTL); + writel(0x7ff, nfc->regs + NFC_REG_TIMING_CFG); + + ret = sunxi_nand_chips_init(dev, nfc); + if (ret) { + dev_err(dev, "failed to init nand chips\n"); + goto out_mod_clk_unprepare; + } + + return 0; + +out_mod_clk_unprepare: + clk_disable_unprepare(nfc->mod_clk); +out_ahb_clk_unprepare: + clk_disable_unprepare(nfc->ahb_clk); + + return ret; +} + +static int sunxi_nfc_remove(struct platform_device *pdev) +{ + struct sunxi_nfc *nfc = platform_get_drvdata(pdev); + + sunxi_nand_chips_cleanup(nfc); + + return 0; +} + +static const struct of_device_id sunxi_nfc_ids[] = { + { .compatible = "allwinner,sun4i-a10-nand" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sunxi_nfc_ids); + +static struct platform_driver sunxi_nfc_driver = { + .driver = { + .name = "sunxi_nand", + .of_match_table = sunxi_nfc_ids, + }, + .probe = sunxi_nfc_probe, + .remove = sunxi_nfc_remove, +}; +module_platform_driver(sunxi_nfc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Boris BREZILLON"); +MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver"); +MODULE_ALIAS("platform:sunxi_nand"); -- GitLab From 5935946c6a1180dcb495fffb2c45eddedfa09064 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 21 Oct 2014 15:08:42 +0200 Subject: [PATCH 2016/9457] mtd: nand: add sunxi NFC dt bindings doc Add the sunxi NAND Flash Controller dt bindings documentation. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- .../devicetree/bindings/mtd/sunxi-nand.txt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/sunxi-nand.txt diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt new file mode 100644 index 000000000000..0273adb8638c --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt @@ -0,0 +1,45 @@ +Allwinner NAND Flash Controller (NFC) + +Required properties: +- compatible : "allwinner,sun4i-a10-nand". +- reg : shall contain registers location and length for data and reg. +- interrupts : shall define the nand controller interrupt. +- #address-cells: shall be set to 1. Encode the nand CS. +- #size-cells : shall be set to 0. +- clocks : shall reference nand controller clocks. +- clock-names : nand controller internal clock names. Shall contain : + * "ahb" : AHB gating clock + * "mod" : nand controller clock + +Optional children nodes: +Children nodes represent the available nand chips. + +Optional properties: +- allwinner,rb : shall contain the native Ready/Busy ids. + or +- rb-gpios : shall contain the gpios used as R/B pins. +- nand-ecc-mode : one of the supported ECC modes ("hw", "hw_syndrome", "soft", + "soft_bch" or "none") + +see Documentation/devicetree/mtd/nand.txt for generic bindings. + + +Examples: +nfc: nand@01c03000 { + compatible = "allwinner,sun4i-a10-nand"; + reg = <0x01c03000 0x1000>; + interrupts = <0 37 1>; + clocks = <&ahb_gates 13>, <&nand_clk>; + clock-names = "ahb", "mod"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>; + status = "okay"; + + nand@0 { + reg = <0>; + allwinner,rb = <0>; + nand-ecc-mode = "soft_bch"; + }; +}; -- GitLab From 74c450521dd8d245b982da62592a18aa6f88b045 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 29 Oct 2014 11:14:52 -0600 Subject: [PATCH 2017/9457] blk-mq: add a 'list' parameter to ->queue_rq() Since we have the notion of a 'last' request in a chain, we can use this to have the hardware optimize the issuing of requests. Add a list_head parameter to queue_rq that the driver can use to temporarily store hw commands for issue when 'last' is true. If we are doing a chain of requests, pass in a NULL list for the first request to force issue of that immediately, then batch the remainder for deferred issue until the last request has been sent. Instead of adding yet another argument to the hot ->queue_rq path, encapsulate the passed arguments in a blk_mq_queue_data structure. This is passed as a constant, and has been tested as faster than passing 4 (or even 3) args through ->queue_rq. Update drivers for the new ->queue_rq() prototype. There are no functional changes in this patch for drivers - if they don't use the passed in list, then they will just queue requests individually like before. Signed-off-by: Jens Axboe --- block/blk-mq.c | 29 +++++++++++++++++++++++++++-- drivers/block/mtip32xx/mtip32xx.c | 5 +++-- drivers/block/null_blk.c | 10 +++++----- drivers/block/virtio_blk.c | 7 ++++--- drivers/scsi/scsi_lib.c | 5 +++-- include/linux/blk-mq.h | 8 +++++++- 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 68929bad9a6a..7e5303820452 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -680,6 +680,8 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) struct request_queue *q = hctx->queue; struct request *rq; LIST_HEAD(rq_list); + LIST_HEAD(driver_list); + struct list_head *dptr; int queued; WARN_ON(!cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)); @@ -705,17 +707,28 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) spin_unlock(&hctx->lock); } + /* + * Start off with dptr being NULL, so we start the first request + * immediately, even if we have more pending. + */ + dptr = NULL; + /* * Now process all the entries, sending them to the driver. */ queued = 0; while (!list_empty(&rq_list)) { + struct blk_mq_queue_data bd; int ret; rq = list_first_entry(&rq_list, struct request, queuelist); list_del_init(&rq->queuelist); - ret = q->mq_ops->queue_rq(hctx, rq, list_empty(&rq_list)); + bd.rq = rq; + bd.list = dptr; + bd.last = list_empty(&rq_list); + + ret = q->mq_ops->queue_rq(hctx, &bd); switch (ret) { case BLK_MQ_RQ_QUEUE_OK: queued++; @@ -734,6 +747,13 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) if (ret == BLK_MQ_RQ_QUEUE_BUSY) break; + + /* + * We've done the first request. If we have more than 1 + * left in the list, set dptr to defer issue. + */ + if (!dptr && rq_list.next != rq_list.prev) + dptr = &driver_list; } if (!queued) @@ -1153,6 +1173,11 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio) } if (is_sync) { + struct blk_mq_queue_data bd = { + .rq = rq, + .list = NULL, + .last = 1 + }; int ret; blk_mq_bio_to_request(rq, bio); @@ -1162,7 +1187,7 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio) * error (busy), just add it to our list as we previously * would have done */ - ret = q->mq_ops->queue_rq(data.hctx, rq, true); + ret = q->mq_ops->queue_rq(data.hctx, &bd); if (ret == BLK_MQ_RQ_QUEUE_OK) goto done; else { diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 1bd5f523f8fd..3bd7ca9853a8 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -3775,9 +3775,10 @@ static bool mtip_check_unal_depth(struct blk_mq_hw_ctx *hctx, return false; } -static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq, - bool last) +static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct request *rq = bd->rq; int ret; if (unlikely(mtip_check_unal_depth(hctx, rq))) diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 2671a3f02f0c..8433bc8ead3d 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -313,15 +313,15 @@ static void null_request_fn(struct request_queue *q) } } -static int null_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq, - bool last) +static int null_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); + struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); - cmd->rq = rq; + cmd->rq = bd->rq; cmd->nq = hctx->driver_data; - blk_mq_start_request(rq); + blk_mq_start_request(bd->rq); null_handle_cmd(cmd); return BLK_MQ_RQ_QUEUE_OK; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c6a27d54ad62..cecd3f983e49 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -158,10 +158,11 @@ static void virtblk_done(struct virtqueue *vq) spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); } -static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, - bool last) +static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { struct virtio_blk *vblk = hctx->queue->queuedata; + struct request *req = bd->rq; struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); unsigned long flags; unsigned int num; @@ -222,7 +223,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, return BLK_MQ_RQ_QUEUE_ERROR; } - if (last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) + if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) notify = true; spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9eff8a375132..161dcc93ac75 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1858,9 +1858,10 @@ static void scsi_mq_done(struct scsi_cmnd *cmd) blk_mq_complete_request(cmd->request); } -static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, - bool last) +static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct request *req = bd->rq; struct request_queue *q = req->q; struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost = sdev->host; diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index c9be1589415a..be01d7a687d4 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -79,7 +79,13 @@ struct blk_mq_tag_set { struct list_head tag_list; }; -typedef int (queue_rq_fn)(struct blk_mq_hw_ctx *, struct request *, bool); +struct blk_mq_queue_data { + struct request *rq; + struct list_head *list; + bool last; +}; + +typedef int (queue_rq_fn)(struct blk_mq_hw_ctx *, const struct blk_mq_queue_data *); typedef struct blk_mq_hw_ctx *(map_queue_fn)(struct request_queue *, const int); typedef enum blk_eh_timer_return (timeout_fn)(struct request *, bool); typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int); -- GitLab From e167dfb53cb85fde7b15f644e9dbef7ba31896b6 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 29 Oct 2014 11:18:26 -0600 Subject: [PATCH 2018/9457] blk-mq: add BLK_MQ_F_DEFER_ISSUE support flag Drivers can now tell blk-mq if they take advantage of the deferred issue through 'last' or not. If they do, don't do queue-direct for sync IO. This is a preparation patch for the nvme conversion. Signed-off-by: Jens Axboe --- block/blk-mq.c | 7 ++++++- include/linux/blk-mq.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 7e5303820452..b355b5957cd7 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1172,7 +1172,12 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio) goto run_queue; } - if (is_sync) { + /* + * If the driver supports defer issued based on 'last', then + * queue it up like normal since we can potentially save some + * CPU this way. + */ + if (is_sync && !(data.hctx->flags & BLK_MQ_F_DEFER_ISSUE)) { struct blk_mq_queue_data bd = { .rq = rq, .list = NULL, diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index be01d7a687d4..c3b64ec5321e 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -146,6 +146,7 @@ enum { BLK_MQ_F_TAG_SHARED = 1 << 1, BLK_MQ_F_SG_MERGE = 1 << 2, BLK_MQ_F_SYSFS_UP = 1 << 3, + BLK_MQ_F_DEFER_ISSUE = 1 << 4, BLK_MQ_S_STOPPED = 0, BLK_MQ_S_TAG_ACTIVE = 1, -- GitLab From 4f86ed8f87c07b3e1c1291bbb262c8de7e7f1233 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 27 Oct 2014 15:04:46 -0700 Subject: [PATCH 2019/9457] mac80211-hwsim: add frequency attribute to netlink pkts Add frequency attribute when sending to user-space over netlink socket. The frequency is currently ignored when receiving from user-space. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 6 ++++++ drivers/net/wireless/mac80211_hwsim.h | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index d109e5050857..f808706d9ee3 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -910,6 +910,9 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags)) goto nla_put_failure; + if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq)) + goto nla_put_failure; + /* We get the tx control (rate and retries) info*/ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { @@ -2463,6 +2466,9 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, /* A frame is received from user space */ memset(&rx_status, 0, sizeof(rx_status)); + /* TODO: Check ATTR_FREQ if it exists, and maybe throw away off-channel + * packets? + */ rx_status.freq = data2->channel->center_freq; rx_status.band = data2->channel->band; rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index 448e64b619cb..f08debdd639b 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -60,7 +60,7 @@ enum hwsim_tx_control_flags { * space, uses: * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER, * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE, - * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE + * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE, %HWSIM_ATTR_FREQ (optional) * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to * kernel, uses: * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, @@ -119,6 +119,7 @@ enum { * command to force radio removal when process that created the radio dies * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. + * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. * @__HWSIM_ATTR_MAX: enum limit */ @@ -143,6 +144,7 @@ enum { HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, HWSIM_ATTR_RADIO_NAME, HWSIM_ATTR_NO_VIF, + HWSIM_ATTR_FREQ, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) -- GitLab From dcc6c2f5165788fdc37be9a13a909e8c16f254ce Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sat, 25 Oct 2014 17:57:35 +0200 Subject: [PATCH 2020/9457] cfg80211: fix set but not used warning in nl80211_channel_switch() radar_detect_width is unused since commit 97dc94f1d933 ("cfg80211: remove channel_switch combination check") Signed-off-by: Fabian Frederick Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 12736a7cd506..33aff7466f2f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6038,7 +6038,6 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) * function is called under RTNL lock, so this should not be a problem. */ static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; - u8 radar_detect_width = 0; int err; bool need_new_beacon = false; int len, i; @@ -6174,10 +6173,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) if (err < 0) return err; - if (err > 0) { - radar_detect_width = BIT(params.chandef.width); + if (err > 0) params.radar_required = true; - } if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) params.block_tx = true; -- GitLab From fc1f48ffd5793e0a35c3b02375c2e2923e0f2bf3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 29 Oct 2014 17:05:39 +0100 Subject: [PATCH 2021/9457] cfg80211: fix integer signedness in chandef_primary_freqs() The helper function can't ever create negative values, so use u32 pointers as the function arguments as the caller does. Signed-off-by: Johannes Berg --- net/wireless/chan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 72d81e2154d5..8f39e33e71bb 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -115,7 +115,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) EXPORT_SYMBOL(cfg80211_chandef_valid); static void chandef_primary_freqs(const struct cfg80211_chan_def *c, - int *pri40, int *pri80) + u32 *pri40, u32 *pri80) { int tmp; -- GitLab From e49786dbebc91658c86fb2be746968221147ffc4 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 24 Oct 2014 11:12:08 -0700 Subject: [PATCH 2022/9457] mac80211-hwsim: support SGI-20 This lets hostapd start if you have SGI-20 configured as one of your HT capabilities. Signed-off-by: Ben Greear Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index f808706d9ee3..06ca3a92fc7e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2178,6 +2178,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, sband->ht_cap.ht_supported = true; sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_DSSSCCK40; sband->ht_cap.ampdu_factor = 0x3; -- GitLab From 171fdf77dbe65ad87a7e2884cb1adc0058e6b609 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 29 Oct 2014 18:43:39 +0100 Subject: [PATCH 2023/9457] mac80211-hwsim: remove spurious newline This newline shouldn't be there, remove it. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 06ca3a92fc7e..a24b7f5aea9f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2424,7 +2424,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, struct genl_info *info) { - struct mac80211_hwsim_data *data2; struct ieee80211_rx_status rx_status; const u8 *dst; -- GitLab From cf987afc7eb182d04071bed5e2aaea8eb7d17052 Mon Sep 17 00:00:00 2001 From: Pavaluca Matei-B46610 Date: Mon, 27 Oct 2014 10:42:42 +0200 Subject: [PATCH 2024/9457] Add flow control support flags to gianfar's capabilities The phy device supports 802.3x flow control, but the specific flags are not set in the phy initialisation code. Flow control flags need to be added to the supported capabilities of the phydev by the driver. This is needed in order for ethtool to work ('ethtool -A' code checks for these flags) Signed-off-by: Pavaluca Matei Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 3 +++ drivers/net/ethernet/freescale/gianfar.h | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4fdf0aa16978..2485b742ba70 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1687,6 +1687,9 @@ static int init_phy(struct net_device *dev) priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support); priv->phydev->advertising = priv->phydev->supported; + /* Add support for flow control, but don't advertise it by default */ + priv->phydev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); + return 0; } diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 2805cfbf1765..6b008685837c 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -145,9 +145,7 @@ extern const char gfar_driver_version[]; | SUPPORTED_Autoneg \ | SUPPORTED_MII) -#define GFAR_SUPPORTED_GBIT (SUPPORTED_1000baseT_Full \ - | SUPPORTED_Pause \ - | SUPPORTED_Asym_Pause) +#define GFAR_SUPPORTED_GBIT SUPPORTED_1000baseT_Full /* TBI register addresses */ #define MII_TBICON 0x11 -- GitLab From 43ef8d29eebb6f533f11439d48a927426c5a1918 Mon Sep 17 00:00:00 2001 From: Pavaluca Matei-B46610 Date: Mon, 27 Oct 2014 10:42:43 +0200 Subject: [PATCH 2025/9457] Fix the way the local advertising flow options are determined Local flow control options needed in order to resolve the negotiation are incorrectly calculated. Previously 'mii_advertise_flowctrl' was called to determine the local advertising options, but these were determined based on FLOW_CTRL_RX/TX flags which are never set through ethtool. The patch simply translates from ethtool flow options to mii flow options. Signed-off-by: Pavaluca Matei Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 2485b742ba70..329efcad4fe0 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -3373,7 +3373,11 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv) if (phydev->asym_pause) rmt_adv |= LPA_PAUSE_ASYM; - lcl_adv = mii_advertise_flowctrl(phydev->advertising); + lcl_adv = 0; + if (phydev->advertising & ADVERTISED_Pause) + lcl_adv |= ADVERTISE_PAUSE_CAP; + if (phydev->advertising & ADVERTISED_Asym_Pause) + lcl_adv |= ADVERTISE_PAUSE_ASYM; flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); if (flowctrl & FLOW_CTRL_TX) -- GitLab From 45b679c9a3ccd9e34f28e6ec677b812a860eb8eb Mon Sep 17 00:00:00 2001 From: Matei Pavaluca Date: Mon, 27 Oct 2014 10:42:44 +0200 Subject: [PATCH 2026/9457] gianfar: Implement PAUSE frame generation support The hardware can automatically generate pause frames when the number of free buffers drops under a certain threshold, but in order to do this, the address of the last free buffer needs to be written to a specific register for each RX queue. This has to be done in 'gfar_clean_rx_ring' which is called for each RX queue. In order not to impact performance, by adding a register write for each incoming packet, this operation is done only when the PAUSE frame transmission is enabled. Whenever the link is readjusted, this capability is turned on or off. Signed-off-by: Matei Pavaluca Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/gianfar.c | 54 +++++++++++++++++++ drivers/net/ethernet/freescale/gianfar.h | 34 +++++++++++- .../net/ethernet/freescale/gianfar_ethtool.c | 7 ++- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 329efcad4fe0..86dccb26fecc 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -173,10 +173,12 @@ static void gfar_init_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, static int gfar_init_bds(struct net_device *ndev) { struct gfar_private *priv = netdev_priv(ndev); + struct gfar __iomem *regs = priv->gfargrp[0].regs; struct gfar_priv_tx_q *tx_queue = NULL; struct gfar_priv_rx_q *rx_queue = NULL; struct txbd8 *txbdp; struct rxbd8 *rxbdp; + u32 *rfbptr; int i, j; for (i = 0; i < priv->num_tx_queues; i++) { @@ -201,6 +203,7 @@ static int gfar_init_bds(struct net_device *ndev) txbdp->status |= TXBD_WRAP; } + rfbptr = ®s->rfbptr0; for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; rx_queue->cur_rx = rx_queue->rx_bd_base; @@ -227,6 +230,8 @@ static int gfar_init_bds(struct net_device *ndev) rxbdp++; } + rx_queue->rfbptr = rfbptr; + rfbptr += 2; } return 0; @@ -336,6 +341,20 @@ static void gfar_init_tx_rx_base(struct gfar_private *priv) } } +static void gfar_init_rqprm(struct gfar_private *priv) +{ + struct gfar __iomem *regs = priv->gfargrp[0].regs; + u32 __iomem *baddr; + int i; + + baddr = ®s->rqprm0; + for (i = 0; i < priv->num_rx_queues; i++) { + gfar_write(baddr, priv->rx_queue[i]->rx_ring_size | + (DEFAULT_RX_LFC_THR << FBTHR_SHIFT)); + baddr++; + } +} + static void gfar_rx_buff_size_config(struct gfar_private *priv) { int frame_size = priv->ndev->mtu + ETH_HLEN + ETH_FCS_LEN; @@ -396,6 +415,13 @@ static void gfar_mac_rx_config(struct gfar_private *priv) if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX) rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; + /* Clear the LFC bit */ + gfar_write(®s->rctrl, rctrl); + /* Init flow control threshold values */ + gfar_init_rqprm(priv); + gfar_write(®s->ptv, DEFAULT_LFC_PTVVAL); + rctrl |= RCTRL_LFC; + /* Init rctrl based on our settings */ gfar_write(®s->rctrl, rctrl); } @@ -2859,6 +2885,10 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) /* Setup the new bdp */ gfar_new_rxbdp(rx_queue, bdp, newskb); + /* Update Last Free RxBD pointer for LFC */ + if (unlikely(rx_queue->rfbptr && priv->tx_actual_en)) + gfar_write(rx_queue->rfbptr, (u32)bdp); + /* Update to the next pointer */ bdp = next_bd(bdp, base, rx_queue->rx_ring_size); @@ -3393,6 +3423,9 @@ static noinline void gfar_update_link_state(struct gfar_private *priv) { struct gfar __iomem *regs = priv->gfargrp[0].regs; struct phy_device *phydev = priv->phydev; + struct gfar_priv_rx_q *rx_queue = NULL; + int i; + struct rxbd8 *bdp; if (unlikely(test_bit(GFAR_RESETTING, &priv->state))) return; @@ -3401,6 +3434,7 @@ static noinline void gfar_update_link_state(struct gfar_private *priv) u32 tempval1 = gfar_read(®s->maccfg1); u32 tempval = gfar_read(®s->maccfg2); u32 ecntrl = gfar_read(®s->ecntrl); + u32 tx_flow_oldval = (tempval & MACCFG1_TX_FLOW); if (phydev->duplex != priv->oldduplex) { if (!(phydev->duplex)) @@ -3445,6 +3479,26 @@ static noinline void gfar_update_link_state(struct gfar_private *priv) tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); tempval1 |= gfar_get_flowctrl_cfg(priv); + /* Turn last free buffer recording on */ + if ((tempval1 & MACCFG1_TX_FLOW) && !tx_flow_oldval) { + for (i = 0; i < priv->num_rx_queues; i++) { + rx_queue = priv->rx_queue[i]; + bdp = rx_queue->cur_rx; + /* skip to previous bd */ + bdp = skip_bd(bdp, rx_queue->rx_ring_size - 1, + rx_queue->rx_bd_base, + rx_queue->rx_ring_size); + + if (rx_queue->rfbptr) + gfar_write(rx_queue->rfbptr, (u32)bdp); + } + + priv->tx_actual_en = 1; + } + + if (unlikely(!(tempval1 & MACCFG1_TX_FLOW) && tx_flow_oldval)) + priv->tx_actual_en = 0; + gfar_write(®s->maccfg1, tempval1); gfar_write(®s->maccfg2, tempval); gfar_write(®s->ecntrl, ecntrl); diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 6b008685837c..b581b8823a2a 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -99,6 +99,10 @@ extern const char gfar_driver_version[]; #define GFAR_MAX_FIFO_STARVE 511 #define GFAR_MAX_FIFO_STARVE_OFF 511 +#define FBTHR_SHIFT 24 +#define DEFAULT_RX_LFC_THR 16 +#define DEFAULT_LFC_PTVVAL 4 + #define DEFAULT_RX_BUFFER_SIZE 1536 #define TX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1) @@ -273,6 +277,7 @@ extern const char gfar_driver_version[]; #define RCTRL_TS_ENABLE 0x01000000 #define RCTRL_PAL_MASK 0x001f0000 +#define RCTRL_LFC 0x00004000 #define RCTRL_VLEX 0x00002000 #define RCTRL_FILREN 0x00001000 #define RCTRL_GHTX 0x00000400 @@ -849,7 +854,32 @@ struct gfar { u8 res23c[248]; u32 attr; /* 0x.bf8 - Attributes Register */ u32 attreli; /* 0x.bfc - Attributes Extract Length and Extract Index Register */ - u8 res24[688]; + u32 rqprm0; /* 0x.c00 - Receive queue parameters register 0 */ + u32 rqprm1; /* 0x.c04 - Receive queue parameters register 1 */ + u32 rqprm2; /* 0x.c08 - Receive queue parameters register 2 */ + u32 rqprm3; /* 0x.c0c - Receive queue parameters register 3 */ + u32 rqprm4; /* 0x.c10 - Receive queue parameters register 4 */ + u32 rqprm5; /* 0x.c14 - Receive queue parameters register 5 */ + u32 rqprm6; /* 0x.c18 - Receive queue parameters register 6 */ + u32 rqprm7; /* 0x.c1c - Receive queue parameters register 7 */ + u8 res24[36]; + u32 rfbptr0; /* 0x.c44 - Last free RxBD pointer for ring 0 */ + u8 res24a[4]; + u32 rfbptr1; /* 0x.c4c - Last free RxBD pointer for ring 1 */ + u8 res24b[4]; + u32 rfbptr2; /* 0x.c54 - Last free RxBD pointer for ring 2 */ + u8 res24c[4]; + u32 rfbptr3; /* 0x.c5c - Last free RxBD pointer for ring 3 */ + u8 res24d[4]; + u32 rfbptr4; /* 0x.c64 - Last free RxBD pointer for ring 4 */ + u8 res24e[4]; + u32 rfbptr5; /* 0x.c6c - Last free RxBD pointer for ring 5 */ + u8 res24f[4]; + u32 rfbptr6; /* 0x.c74 - Last free RxBD pointer for ring 6 */ + u8 res24g[4]; + u32 rfbptr7; /* 0x.c7c - Last free RxBD pointer for ring 7 */ + u8 res24h[4]; + u8 res24x[556]; u32 isrg0; /* 0x.eb0 - Interrupt steering group 0 register */ u32 isrg1; /* 0x.eb4 - Interrupt steering group 1 register */ u32 isrg2; /* 0x.eb8 - Interrupt steering group 2 register */ @@ -1009,6 +1039,7 @@ struct gfar_priv_rx_q { /* RX Coalescing values */ unsigned char rxcoalescing; unsigned long rxic; + u32 *rfbptr; }; enum gfar_irqinfo_id { @@ -1099,6 +1130,7 @@ struct gfar_private { unsigned int num_tx_queues; unsigned int num_rx_queues; unsigned int num_grps; + int tx_actual_en; /* Network Statistics */ struct gfar_extra_stats extra_stats; diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 76d70708f864..3e1a9c1a67a9 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -579,8 +579,13 @@ static int gfar_spauseparam(struct net_device *dev, u32 tempval; tempval = gfar_read(®s->maccfg1); tempval &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); - if (priv->tx_pause_en) + + priv->tx_actual_en = 0; + if (priv->tx_pause_en) { + priv->tx_actual_en = 1; tempval |= MACCFG1_TX_FLOW; + } + if (priv->rx_pause_en) tempval |= MACCFG1_RX_FLOW; gfar_write(®s->maccfg1, tempval); -- GitLab From 33b1c8c13fb8c9c3c5320345258a4d33806262f4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:36 +0000 Subject: [PATCH 2027/9457] staging: vt6655: mac80211 conversion: add new rx functions vnt_receive_frame which replaces device_receive_frame and vnt_rx_data which handles mac80211 rx data structures ieee80211_hw, ieee80211_vif and variable rx_rate are added in structure vnt_private Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 6 +- drivers/staging/vt6655/device_main.c | 13 +-- drivers/staging/vt6655/dpc.c | 123 +++++++++++++++++++++++++++ drivers/staging/vt6655/dpc.h | 2 + 4 files changed, 137 insertions(+), 7 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index d769d092fb87..82e18455501c 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -56,6 +56,7 @@ #include #include /* Include Wireless Extension definition and check version - Jean II */ +#include #include #include /* New driver API */ @@ -319,7 +320,9 @@ typedef struct __device_opt { struct vnt_private { struct pci_dev *pcid; - + /* mac80211 */ + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; /* netdev */ struct net_device *dev; @@ -378,6 +381,7 @@ struct vnt_private { u32 flags; u32 rx_buf_sz; + u8 rx_rate; int multicast_limit; pid_t MLMEThr_pid; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ef848e2f0585..84a35d7d01e8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1336,7 +1336,7 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) pRD = pRD->next) { if (works++ > 15) break; - if (device_receive_frame(pDevice, pRD)) { + if (vnt_receive_frame(pDevice, pRD)) { if (!device_alloc_rx_buf(pDevice, pRD)) { dev_err(&pDevice->pcid->dev, "can not allocate rx buf\n"); @@ -1344,7 +1344,6 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) } } pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC; - pDevice->dev->last_rx = jiffies; } pDevice->pCurrRD[uIdx] = pRD; @@ -1360,9 +1359,12 @@ static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD) if (pRDInfo->skb == NULL) return false; ASSERT(pRDInfo->skb); - pRDInfo->skb->dev = pDevice->dev; - pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb), - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + + pRDInfo->skb_dma = + pci_map_single(pDevice->pcid, + skb_put(pRDInfo->skb, skb_tailroom(pRDInfo->skb)), + pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); + *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */ pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz); @@ -1380,7 +1382,6 @@ bool device_alloc_frag_buf(struct vnt_private *pDevice, if (pDeF->skb == NULL) return false; ASSERT(pDeF->skb); - pDeF->skb->dev = pDevice->dev; return true; } diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 67cadeaf2f7d..036bbb0f4824 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -1321,3 +1321,126 @@ static bool s_bAPModeRxData( return true; } + +static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, + u16 bytes_received) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_supported_band *sband; + struct ieee80211_rx_status rx_status = { 0 }; + struct ieee80211_hdr *hdr; + __le16 fc; + u8 *rsr, *new_rsr, *rssi; + __le64 *tsf_time; + u16 frame_size; + int ii, r; + u8 *rx_sts, *rx_rate, *sq; + u8 *skb_data; + u8 rate_idx = 0; + u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; + long rx_dbm; + + /* [31:16]RcvByteCount ( not include 4-byte Status ) */ + frame_size = le16_to_cpu(*((__le16 *)(skb->data + 2))); + if (frame_size > 2346 || frame_size < 14) { + dev_dbg(&priv->pcid->dev, "------- WRONG Length 1\n"); + return false; + } + + skb_data = (u8 *)skb->data; + + rx_sts = skb_data; + rx_rate = skb_data + 1; + + sband = hw->wiphy->bands[hw->conf.chandef.chan->band]; + + for (r = RATE_1M; r < MAX_RATE; r++) { + if (*rx_rate == rate[r]) + break; + } + + priv->rx_rate = r; + + for (ii = 0; ii < sband->n_bitrates; ii++) { + if (sband->bitrates[ii].hw_value == r) { + rate_idx = ii; + break; + } + } + + if (ii == sband->n_bitrates) { + dev_dbg(&priv->pcid->dev, "Wrong RxRate %x\n", *rx_rate); + return false; + } + + tsf_time = (__le64 *)(skb_data + bytes_received - 12); + sq = skb_data + bytes_received - 4; + new_rsr = skb_data + bytes_received - 3; + rssi = skb_data + bytes_received - 2; + rsr = skb_data + bytes_received - 1; + + RFvRSSITodBm(priv, *rssi, &rx_dbm); + + priv->byBBPreEDRSSI = (u8)rx_dbm + 1; + priv->uCurrRSSI = priv->byBBPreEDRSSI; + + skb_pull(skb, 4); + skb_trim(skb, frame_size); + + rx_status.mactime = le64_to_cpu(*tsf_time); + rx_status.band = hw->conf.chandef.chan->band; + rx_status.signal = rx_dbm; + rx_status.flag = 0; + rx_status.freq = hw->conf.chandef.chan->center_freq; + + hdr = (struct ieee80211_hdr *)(skb->data); + fc = hdr->frame_control; + + rx_status.rate_idx = rate_idx; + + if (ieee80211_has_protected(fc)) { + if (priv->byLocalID > REV_ID_VT3253_A1) + rx_status.flag = RX_FLAG_DECRYPTED; + } + + if (priv->vif && priv->bDiversityEnable) { + if (ieee80211_is_data(fc) && + (frame_size > 50) && priv->vif->bss_conf.assoc) + BBvAntennaDiversity(priv, priv->rx_rate, 0); + } + + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + ieee80211_rx_irqsafe(priv->hw, skb); + + return true; +} + +bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd) +{ + PDEVICE_RD_INFO rd_info = curr_rd->pRDInfo; + struct sk_buff *skb; + u16 frame_size; + + skb = rd_info->skb; + + pci_unmap_single(priv->pcid, rd_info->skb_dma, + priv->rx_buf_sz, PCI_DMA_FROMDEVICE); + + frame_size = le16_to_cpu(curr_rd->m_rd1RD1.wReqCount) + - cpu_to_le16(curr_rd->m_rd0RD0.wResCount); + + if ((frame_size > 2364) || (frame_size < 33)) { + /* Frame Size error drop this packet.*/ + dev_dbg(&priv->pcid->dev, "Wrong frame size %d\n", frame_size); + dev_kfree_skb_irq(skb); + return true; + } + + if (vnt_rx_data(priv, skb, frame_size)) + return true; + + dev_kfree_skb_irq(skb); + + return true; +} diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index e97e32811916..dd48e4125477 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -39,4 +39,6 @@ device_receive_frame( PSRxDesc pCurrRD ); +bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd); + #endif /* __RXTX_H__ */ -- GitLab From fee7506a121a4666aa42b22bcdc2172752b9f65b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:37 +0000 Subject: [PATCH 2028/9457] staging: vt6655: mac80211 conversion: add new key functions vnt_key_init_table to initialize the table vnt_set_keys to set the keys Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 1 + drivers/staging/vt6655/key.c | 136 ++++++++++++++++++++++++++++++++ drivers/staging/vt6655/key.h | 17 ++++ 3 files changed, 154 insertions(+) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 82e18455501c..bc9b81ad5185 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -323,6 +323,7 @@ struct vnt_private { /* mac80211 */ struct ieee80211_hw *hw; struct ieee80211_vif *vif; + unsigned long key_entry_inuse; /* netdev */ struct net_device *dev; diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 02caffb06e59..b2fa8125e29d 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -790,3 +790,139 @@ bool KeybSetAllGroupKey( } return true; } + +int vnt_key_init_table(struct vnt_private *priv) +{ + u32 i; + + for (i = 0; i < MAX_KEY_TABLE; i++) + MACvDisableKeyEntry(priv->PortOffset, i); + + return 0; +} + +static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, + struct ieee80211_key_conf *key, u32 key_type, u32 mode, + bool onfly_latch) +{ + struct vnt_private *priv = hw->priv; + u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u16 key_mode = 0; + u32 entry = 0; + u8 *bssid; + u8 key_inx = key->keyidx; + u8 i; + + if (mac_addr) + bssid = mac_addr; + else + bssid = &broadcast[0]; + + if (key_type != VNT_KEY_DEFAULTKEY) { + for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { + if (!test_bit(i, &priv->key_entry_inuse)) { + set_bit(i, &priv->key_entry_inuse); + + key->hw_key_idx = i; + entry = key->hw_key_idx; + break; + } + } + } + + switch (key_type) { + /* fallthrough */ + case VNT_KEY_DEFAULTKEY: + /* default key last entry */ + entry = MAX_KEY_TABLE - 1; + key->hw_key_idx = entry; + case VNT_KEY_ALLGROUP: + key_mode |= VNT_KEY_ALLGROUP; + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY_ALL; + case VNT_KEY_GROUP_ADDRESS: + key_mode |= mode; + case VNT_KEY_GROUP: + key_mode |= (mode << 4); + key_mode |= VNT_KEY_GROUP; + break; + case VNT_KEY_PAIRWISE: + key_mode |= mode; + key_inx = 4; + break; + default: + return -EINVAL; + } + + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY; + + if (mode == KEY_CTL_WEP) { + if (key->keylen == WLAN_KEY_LEN_WEP40) + key->key[15] &= 0x7f; + if (key->keylen == WLAN_KEY_LEN_WEP104) + key->key[15] |= 0x80; + } + + MACvSetKeyEntry(priv->PortOffset, key_mode, entry, key_inx, + bssid, (u32 *)key->key, priv->byLocalID); + + return 0; +} + +int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct ieee80211_vif *vif, struct ieee80211_key_conf *key) +{ + struct ieee80211_bss_conf *conf = &vif->bss_conf; + struct vnt_private *priv = hw->priv; + u8 *mac_addr = NULL; + u8 key_dec_mode = 0; + int ret = 0; + u32 u; + + if (sta) + mac_addr = &sta->addr[0]; + + switch (key->cipher) { + case 0: + for (u = 0 ; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); + return ret; + + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + for (u = 0; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); + + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true); + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + return ret; + case WLAN_CIPHER_SUITE_TKIP: + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + key_dec_mode = KEY_CTL_TKIP; + + break; + case WLAN_CIPHER_SUITE_CCMP: + key_dec_mode = KEY_CTL_CCMP; + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + } + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_PAIRWISE, key_dec_mode, true); + } else { + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, key_dec_mode, true); + + vnt_set_keymode(hw, (u8 *)conf->bssid, + key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); + } + + return 0; +} diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 44efe18315af..d70ffd6fe728 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -30,6 +30,8 @@ #ifndef __KEY_H__ #define __KEY_H__ +#include + #include "ttype.h" #include "tether.h" #include "80211mgr.h" @@ -53,6 +55,14 @@ #define KEY_CTL_CCMP 0x03 #define KEY_CTL_INVALID 0xFF +#define VNT_KEY_DEFAULTKEY 0x1 +#define VNT_KEY_GROUP_ADDRESS 0x2 +#define VNT_KEY_ALLGROUP 0x4 +#define VNT_KEY_GROUP 0x40 +#define VNT_KEY_PAIRWISE 0x00 +#define VNT_KEY_ONFLY 0x8000 +#define VNT_KEY_ONFLY_ALL 0x4000 + typedef struct tagSKeyItem { bool bKeyValid; unsigned long uKeyLength; @@ -173,4 +183,11 @@ bool KeybSetAllGroupKey( unsigned char byLocalID ); +struct vnt_private; + +int vnt_key_init_table(struct vnt_private *); + +int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct ieee80211_vif *vif, struct ieee80211_key_conf *key); + #endif // __KEY_H__ -- GitLab From 01eec153ab38a476f0f16d849fba77bbf0f95edf Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:38 +0000 Subject: [PATCH 2029/9457] staging: vt6655: mac8021 conversion: add new tx functions vnt_fill_txkey a mac80211 repacement for s_vFillTxKey vnt_generate_fifo_header mac80211 replacement for vGenerateFIFOHeader vnt_beacon_make for making and despatching beacon. vnt_beacon_enable to enabling beacon struct vnt_tx_fifo_head is also added to replace typedef struct tagSTxBufHead that will be removed later. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 1 + drivers/staging/vt6655/rxtx.c | 311 ++++++++++++++++++++++++++++++++++ drivers/staging/vt6655/rxtx.h | 14 ++ 3 files changed, 326 insertions(+) diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 8f510c69cee1..9068c3ed696f 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -287,6 +287,7 @@ typedef struct tagTDES1 { STDES1; typedef struct tagDEVICE_TD_INFO { + void *mic_hdr; struct sk_buff *skb; unsigned char *buf; dma_addr_t skb_dma; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index da7c0a8674b6..99ce5a3d4ece 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -2994,3 +2994,314 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, // Poll Transmit the adapter MACvTransmit0(pDevice->PortOffset); } + +static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer, + struct ieee80211_key_conf *tx_key, + struct sk_buff *skb, u16 payload_len, + struct vnt_mic_hdr *mic_hdr) +{ + struct ieee80211_key_seq seq; + u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); + + /* strip header and icv len from payload */ + payload_len -= ieee80211_get_hdrlen_from_skb(skb); + payload_len -= tx_key->icv_len; + + switch (tx_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + memcpy(key_buffer, iv, 3); + memcpy(key_buffer + 3, tx_key->key, tx_key->keylen); + + if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { + memcpy(key_buffer + 8, iv, 3); + memcpy(key_buffer + 11, + tx_key->key, WLAN_KEY_LEN_WEP40); + } + + break; + case WLAN_CIPHER_SUITE_TKIP: + ieee80211_get_tkip_p2k(tx_key, skb, key_buffer); + + break; + case WLAN_CIPHER_SUITE_CCMP: + + if (!mic_hdr) + return; + + mic_hdr->id = 0x59; + mic_hdr->payload_len = cpu_to_be16(payload_len); + ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); + + ieee80211_get_key_tx_seq(tx_key, &seq); + + memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); + + if (ieee80211_has_a4(hdr->frame_control)) + mic_hdr->hlen = cpu_to_be16(28); + else + mic_hdr->hlen = cpu_to_be16(22); + + ether_addr_copy(mic_hdr->addr1, hdr->addr1); + ether_addr_copy(mic_hdr->addr2, hdr->addr2); + ether_addr_copy(mic_hdr->addr3, hdr->addr3); + + mic_hdr->frame_control = cpu_to_le16( + le16_to_cpu(hdr->frame_control) & 0xc78f); + mic_hdr->seq_ctrl = cpu_to_le16( + le16_to_cpu(hdr->seq_ctrl) & 0xf); + + if (ieee80211_has_a4(hdr->frame_control)) + ether_addr_copy(mic_hdr->addr4, hdr->addr4); + + memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP); + + break; + default: + break; + } +} + +int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, + PSTxDesc head_td, struct sk_buff *skb) +{ + PDEVICE_TD_INFO td_info = head_td->pTDInfo; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; + struct ieee80211_rate *rate; + struct ieee80211_key_conf *tx_key; + struct ieee80211_hdr *hdr; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u32 frag; + u16 tx_body_size = skb->len, current_rate; + u8 pkt_type; + bool is_pspoll = false; + + memset(tx_buffer_head, 0, sizeof(*tx_buffer_head)); + + hdr = (struct ieee80211_hdr *)(skb->data); + + rate = ieee80211_get_tx_rate(priv->hw, info); + + current_rate = rate->hw_value; + if (priv->wCurrentRate != current_rate && + !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { + priv->wCurrentRate = current_rate; + + RFbSetPower(priv, priv->wCurrentRate, + priv->hw->conf.chandef.chan->hw_value); + } + + if (current_rate > RATE_11M) + pkt_type = (u8)priv->byPacketType; + else + pkt_type = PK_TYPE_11B; + + /*Set fifo controls */ + if (pkt_type == PK_TYPE_11A) + tx_buffer_head->fifo_ctl = 0; + else if (pkt_type == PK_TYPE_11B) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); + else if (pkt_type == PK_TYPE_11GB) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); + else if (pkt_type == PK_TYPE_11GA) + tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); + + /* generate interrupt */ + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); + + if (!ieee80211_is_data(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0); + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); + } else { + tx_buffer_head->time_stamp = + cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); + } + + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); + + if (ieee80211_has_retry(hdr->frame_control)) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); + + if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + priv->byPreambleType = PREAMBLE_SHORT; + else + priv->byPreambleType = PREAMBLE_LONG; + + if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); + + if (ieee80211_has_a4(hdr->frame_control)) { + tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); + priv->bLongHeader = true; + } + + if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) + is_pspoll = true; + + tx_buffer_head->frag_ctl = + cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10); + + if (info->control.hw_key) { + tx_key = info->control.hw_key; + + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); + break; + case WLAN_CIPHER_SUITE_TKIP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); + break; + case WLAN_CIPHER_SUITE_CCMP: + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES); + default: + break; + } + } + + tx_buffer_head->current_rate = cpu_to_le16(current_rate); + + /* legacy rates TODO use ieee80211_tx_rate */ + if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) { + if (priv->byAutoFBCtrl == AUTO_FB_0) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_0); + else if (priv->byAutoFBCtrl == AUTO_FB_1) + tx_buffer_head->fifo_ctl |= + cpu_to_le16(FIFOCTL_AUTO_FB_1); + + } + + tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); + + s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, skb->len, + dma_idx, head_td, NULL, (u8 *)skb->data, + false, NULL, is_pspoll, &frag); + + if (info->control.hw_key) { + tx_key = info->control.hw_key; + if (tx_key->keylen > 0) + vnt_fill_txkey(hdr, tx_buffer_head->tx_key, + tx_key, skb, tx_body_size, td_info->mic_hdr); + } + + return 0; +} + +static int vnt_beacon_xmit(struct vnt_private *priv, + struct sk_buff *skb) +{ + struct vnt_tx_short_buf_head *short_head = + (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs; + struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *) + (priv->tx_beacon_bufs + sizeof(*short_head)); + struct ieee80211_tx_info *info; + u32 frame_size = skb->len + 4; + u16 current_rate; + + memset(priv->tx_beacon_bufs, 0, sizeof(*short_head)); + + if (priv->byBBType == BB_TYPE_11A) { + current_rate = RATE_6M; + + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11A, &short_head->ab); + + /* Get Duration and TimeStampOff */ + short_head->duration = + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11A, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); + + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); + } else { + current_rate = RATE_1M; + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); + + /* Get SignalField,ServiceField,Length */ + vnt_get_phy_field(priv, frame_size, current_rate, + PK_TYPE_11B, &short_head->ab); + + /* Get Duration and TimeStampOff */ + short_head->duration = + cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, + frame_size, PK_TYPE_11B, current_rate, + false, 0, 0, 1, AUTO_FB_NONE)); + + short_head->time_stamp_off = + vnt_time_stamp_off(priv, current_rate); + } + + short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); + + /* Copy Beacon */ + memcpy(mgmt_hdr, skb->data, skb->len); + + /* time stamp always 0 */ + mgmt_hdr->u.beacon.timestamp = 0; + + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; + + hdr->duration_id = 0; + hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4); + } + + priv->wSeqCounter++; + if (priv->wSeqCounter > 0x0fff) + priv->wSeqCounter = 0; + + priv->wBCNBufLen = sizeof(*short_head) + skb->len; + + MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma); + + MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen); + /* Set auto Transmit on */ + MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + /* Poll Transmit the adapter */ + MACvTransmitBCN(priv->PortOffset); + + return 0; +} + +int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) +{ + struct sk_buff *beacon; + + beacon = ieee80211_beacon_get(priv->hw, vif); + if (!beacon) + return -ENOMEM; + + if (vnt_beacon_xmit(priv, beacon)) { + ieee80211_free_txskb(priv->hw, beacon); + return -ENODEV; + } + + return 0; +} + +int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + int ret; + + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); + + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + + CARDvSetFirstNextTBTT(priv->PortOffset, conf->beacon_int); + + CARDbSetBeaconPeriod(priv, conf->beacon_int); + + ret = vnt_beacon_make(priv, vif); + + return ret; +} diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 8ee62887dee5..145713dc4110 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -173,6 +173,14 @@ struct vnt_cts_fb { u16 reserved2; } __packed; +struct vnt_tx_fifo_head { + u8 tx_key[WLAN_KEY_LEN_CCMP]; + __le16 fifo_ctl; + __le16 time_stamp; + __le16 frag_ctl; + __le16 current_rate; +} __packed; + struct vnt_tx_short_buf_head { __le16 fifo_ctl; u16 time_stamp; @@ -215,4 +223,10 @@ void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb, CMD_STATUS csMgmt_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); CMD_STATUS csBeacon_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); +int vnt_generate_fifo_header(struct vnt_private *, u32, + PSTxDesc head_td, struct sk_buff *); +int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *); +int vnt_beacon_enable(struct vnt_private *, struct ieee80211_vif *, + struct ieee80211_bss_conf *); + #endif // __RXTX_H__ -- GitLab From cfd9f0d6b173a3410370e9e0d82f56bb795fcf64 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:39 +0000 Subject: [PATCH 2030/9457] staging: vt6655: mac80211 conversion: s_cbFillTxBufHead Covert to handle mac80211 sk_buff data removing fragmentation processing via s_vFillFragParameter and calls to vGenerateMACHeader and s_vSWencryption fragmentation is now handled by mac80211. There is still more todos with this function when legacy net device code have been remove from driver. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 583 +++------------------------------- 1 file changed, 46 insertions(+), 537 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 99ce5a3d4ece..b114a603bfe3 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -144,7 +144,7 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ); @@ -1176,7 +1176,7 @@ s_vGenerateTxParameter( unsigned int cbFrameSize, bool bNeedACK, unsigned int uDMAIdx, - PSEthernetHeader psEthHeader, + void *psEthHeader, unsigned short wCurrentRate ) { @@ -1301,46 +1301,26 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, unsigned int uDMAIdx, PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum) + unsigned int is_pspoll, unsigned int *puMACfragNum) { - unsigned int cbMACHdLen; + PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo; + struct sk_buff *skb = td_info->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct vnt_tx_fifo_head *tx_buffer_head = + (struct vnt_tx_fifo_head *)td_info->buf; + u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl); unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbLastFragPayloadSize; - unsigned int uFragIdx; - unsigned char *pbyPayloadHead; - unsigned char *pbyIVHead; - unsigned char *pbyMacHdr; - unsigned short wFragType; //00:Non-Frag, 01:Start, 10:Mid, 11:Last __le16 uDuration; unsigned char *pbyBuffer; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int cb802_1_H_len = 0; unsigned int uLength = 0; - unsigned int uTmpLen = 0; unsigned int cbMICHDR = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - u32 dwSafeMIC_L, dwSafeMIC_R; /* Fix "Last Frag Size" < "MIC length". */ - bool bMIC2Frag = false; - unsigned int uMICFragLen = 0; unsigned int uMACfragNum = 1; unsigned int uPadding = 0; unsigned int cbReqCount = 0; - - bool bNeedACK; - bool bRTS; - bool bIsAdhoc; - unsigned char *pbyType; + bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK); + bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS); PSTxDesc ptdCurr; - PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; unsigned int cbHeaderLength = 0; void *pvRrvTime; struct vnt_mic_hdr *pMICHDR; @@ -1348,72 +1328,35 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, void *pvCTS; void *pvTxDataHd; unsigned short wTxBufSize; // FFinfo size - unsigned int uTotalCopyLength = 0; unsigned char byFBOption = AUTO_FB_NONE; - bool bIsWEP256 = false; - PSMgmtObject pMgmt = pDevice->pMgmt; pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - bIsAdhoc = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - bIsAdhoc = false; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; + cbFrameSize = skb->len + 4; - if ((bNeedEncrypt == true) && (pTransmitKey != NULL)) { - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) - bIsWEP256 = true; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } - if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC + if (info->control.hw_key) { + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_CCMP: cbMICHDR = sizeof(struct vnt_mic_hdr); + default: + break; } + + cbFrameSize += info->control.hw_key->icv_len; + if (pDevice->byLocalID > REV_ID_VT3253_A1) { //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMACHdLen%4); + uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4); uPadding %= 4; } } - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((bNeedACK == false) || - (cbFrameSize < pDevice->wRTSThreshold) || - ((cbFrameSize >= pDevice->wFragmentationThreshold) && (pDevice->wFragmentationThreshold <= pDevice->wRTSThreshold)) -) { - bRTS = false; - } else { - bRTS = true; - psTxBufHd->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY); - } // // Use for AUTO FALL BACK // - if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_0) + if (fifo_ctl & FIFOCTL_AUTO_FB_0) byFBOption = AUTO_FB_0; - else if (psTxBufHd->wFIFOCtl & FIFOCTL_AUTO_FB_1) + else if (fifo_ctl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; ////////////////////////////////////////////////////// @@ -1507,471 +1450,37 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, } } // Auto Fall Back } - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - -////////////////////////////////////////////////////////////////// - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - } else { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]); - } - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); - } - -/////////////////////////////////////////////////////////////////// - - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderLength); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMACHdLen + uPadding); - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true) && (bIsWEP256 == false)) { - // Fragmentation - // FragThreshold = Fragment size(Hdr+(IV)+fragment payload+(MIC)+(ICV)+FCS) - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - //FragNum = (FrameSize-(Hdr+FCS))/(Fragment Size -(Hrd+FCS))) - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) - cbLastFragPayloadSize = cbFragPayloadSize; - else - uMACfragNum++; - - //[Hdr+(IV)+last fragment payload+(MIC)+(ICV)+FCS] - cbLastFragmentSize = cbMACHdLen + cbLastFragPayloadSize + cbIVlen + cbICVlen + cbFCSlen; - - for (uFragIdx = 0; uFragIdx < uMACfragNum; uFragIdx++) { - if (uFragIdx == 0) { - //========================= - // Start Fragmentation - //========================= - pr_debug("Start Fragmentation...\n"); - wFragType = FRAGCTL_STAFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - //Fill IV(ExtIV,RSNHDR) - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + td_info->mic_hdr = pMICHDR; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); - - uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("Start MIC: %d\n", - cbFragPayloadSize); - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); - - } - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } else if (uFragIdx == (uMACfragNum-1)) { - //========================= - // Last Fragmentation - //========================= - pr_debug("Last Fragmentation...\n"); - - wFragType = FRAGCTL_ENDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbLastFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbLastFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - if (bMIC2Frag == false) { - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - (cbLastFragPayloadSize - cbMIClen) -); - //TODO check uTmpLen ! - uTmpLen = cbLastFragPayloadSize - cbMIClen; - - } - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbLastFragPayloadSize, - uTmpLen); - - if (bMIC2Frag == false) { - if (uTmpLen != 0) - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - pr_debug("Last MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } else { - if (uMICFragLen >= 4) { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - pr_debug("LAST: uMICFragLen >= 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + (uMICFragLen - 4)), - (cbMIClen - uMICFragLen)); - - } else { - memcpy((pbyBuffer + uLength), ((unsigned char *)&dwSafeMIC_L + uMICFragLen), - (4 - uMICFragLen)); - memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4); - pr_debug("LAST: uMICFragLen < 4: %X, %d\n", - *(unsigned char *)((unsigned char *)&dwSafeMIC_R + uMICFragLen - 4), - (cbMIClen - uMICFragLen)); - } - } - MIC_vUnInit(); - } else { - ASSERT(uTmpLen == (cbLastFragPayloadSize - cbMIClen)); - } - - //--------------------------- - // S/W Encryption - //--------------------------- - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbLastFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - - } else { - //========================= - // Middle Fragmentation - //========================= - pr_debug("Middle Fragmentation...\n"); - - wFragType = FRAGCTL_MIDFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, - uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, uFragIdx); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFragPayloadSize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cbFragPayloadSize; - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14 + uTotalCopyLength), - cbFragPayloadSize -); - uTmpLen = cbFragPayloadSize; - - uTotalCopyLength += uTmpLen; - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - MIC_vAppend((pbyBuffer + uLength), uTmpLen); - - if (uTmpLen < cbFragPayloadSize) { - bMIC2Frag = true; - uMICFragLen = cbFragPayloadSize - uTmpLen; - ASSERT(uMICFragLen < cbMIClen); - - pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); - pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - dwSafeMIC_L = *pdwMIC_L; - dwSafeMIC_R = *pdwMIC_R; - - pr_debug("MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, - cbFragPayloadSize, - uTmpLen); - pr_debug("Fill MIC in Middle frag [%d]\n", - uMICFragLen); - pr_debug("Get MIC:%X, %X\n", - *pdwMIC_L, *pdwMIC_R); - } - pr_debug("Middle frag len: %d\n", - uTmpLen); - - } else { - ASSERT(uTmpLen == (cbFragPayloadSize)); - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength), (unsigned short)cbFragPayloadSize); - cbReqCount += cbICVlen; - } - } - - ptdCurr = (PSTxDesc)pHeadTD; - - //-------------------- - //1.Set TSR1 & ReqCount in TxDescHead - //2.Set FragCtl in TxBufferHead - //3.Set Frame Control - //4.Set Sequence Control - //5.Get S/W generate FCS - //-------------------- - - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); - - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - pDevice->iTDUsed[uDMAIdx]++; - pHeadTD = ptdCurr->next; - } - } // for (uMACfragNum) - } else { - //========================= - // No Fragmentation - //========================= - wFragType = FRAGCTL_NONFRAG; - - //Set FragCtl in TxBufferHead - psTxBufHd->wFragCtl |= (unsigned short)wFragType; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, - 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); - - // Generate TX MAC Header - vGenerateMACHeader(pDevice, pbyMacHdr, uDuration, psEthHeader, bNeedEncrypt, - wFragType, uDMAIdx, 0); - - if (bNeedEncrypt == true) { - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(psTxBufHd->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - } - - // 802.1H - if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { - if ((psEthHeader->wType == TYPE_PKT_IPX) || - (psEthHeader->wType == cpu_to_le16(0xF380))) { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); - } else { - memcpy((unsigned char *)(pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6); - } - pbyType = (unsigned char *)(pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->wType), sizeof(unsigned short)); - cb802_1_H_len = 8; - } - - cbReqCount = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; - uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; - - //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (void *)psTxBufHd, uLength); - - // Copy the Packet into a tx Buffer - memcpy((pbyBuffer + uLength), - (pPacket + 14), - cbFrameBodySize - cb802_1_H_len -); - - if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - pr_debug("Length:%d, %d\n", - cbFrameBodySize - cb802_1_H_len, uLength); - - MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize); - pdwMIC_R = (u32 *)(pbyBuffer + uLength - cb802_1_H_len + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderLength, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); + /* Fill FIFO,RrvTime,RTS,and CTS */ + s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS, + cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate); + /* Fill DataHead */ + uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, + 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); - } + hdr->duration_id = uDuration; - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) { - if (bNeedEncrypt) { - s_vSWencryption(pDevice, pTransmitKey, (pbyBuffer + uLength - cb802_1_H_len), - (unsigned short)(cbFrameBodySize + cbMIClen)); - cbReqCount += cbICVlen; - } - } + cbReqCount = cbHeaderLength + uPadding + cbFrameBodySize; + pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf; + uLength = cbHeaderLength + uPadding; - ptdCurr = (PSTxDesc)pHeadTD; + /* Copy the Packet into a tx Buffer */ + memcpy((pbyBuffer + uLength), pPacket, cbFrameBodySize); - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; - ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; - ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; - ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); + ptdCurr = (PSTxDesc)pHeadTD; - pDevice->iTDUsed[uDMAIdx]++; + ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; + ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; + ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); + /* Set TSR1 & ReqCount in TxDescHead */ + ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - } *puMACfragNum = uMACfragNum; return cbHeaderLength; -- GitLab From 9c71cb32099a5a3441503555918cf36f5716275d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:40 +0000 Subject: [PATCH 2031/9457] staging: vt6655: dead code remove s_vFillFragParameter. s_vFillFragParameter is nolonger used. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 47 ----------------------------------- 1 file changed, 47 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index b114a603bfe3..09df536d9be0 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -148,15 +148,6 @@ s_vGenerateTxParameter( unsigned short wCurrentRate ); -static void s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -); - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, @@ -1257,44 +1248,6 @@ s_vGenerateTxParameter( } } -static -void -s_vFillFragParameter( - struct vnt_private *pDevice, - unsigned char *pbyBuffer, - unsigned int uTxType, - void *pvtdCurr, - unsigned short wFragType, - unsigned int cbReqCount -) -{ - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; - - if (uTxType == TYPE_SYNCDMA) { - PSTxSyncDesc ptdCurr = (PSTxSyncDesc)pvtdCurr; - - //Set FIFOCtl & TimeStamp in TxSyncDesc - ptdCurr->m_wFIFOCtl = pTxBufHead->wFIFOCtl; - ptdCurr->m_wTimeStamp = pTxBufHead->wTimeStamp; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - else - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } else { - PSTxDesc ptdCurr = (PSTxDesc)pvtdCurr; - //Set TSR1 & ReqCount in TxDescHead - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - if (wFragType == FRAGCTL_ENDFRAG) //Last Fragmentation - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - else - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP); - } - - pTxBufHead->wFragCtl |= (unsigned short)wFragType;//0x0001; //0000 0000 0000 0001 -} - static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, -- GitLab From 7c0496d19159df8b5a537154194a75dcdfca873a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:41 +0000 Subject: [PATCH 2032/9457] staging: vt6655: mac80211 conversion: s_vFillRTSHead convert to using struct ieee80211_hdr Removing PSEthernetHeader Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 91 +++++------------------------------ 1 file changed, 12 insertions(+), 79 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 09df536d9be0..a1a594fa10d5 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -127,7 +127,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ); @@ -789,7 +789,7 @@ s_vFillRTSHead( unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, - PSEthernetHeader psEthHeader, + struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ) @@ -841,22 +841,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - ether_addr_copy(buf->data.ra, - psEthHeader->abyDstAddr); - } else { - ether_addr_copy(buf->data.ra, - pDevice->abyBSSID); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - ether_addr_copy(buf->data.ta, - pDevice->abyBSSID); - else - ether_addr_copy(buf->data.ta, - psEthHeader->abySrcAddr); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_g_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -909,23 +895,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - ether_addr_copy(buf->data.ra, - psEthHeader->abyDstAddr); - } else { - ether_addr_copy(buf->data.ra, - pDevice->abyBSSID); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - ether_addr_copy(buf->data.ta, - pDevice->abyBSSID); - else - ether_addr_copy(buf->data.ta, - psEthHeader->abySrcAddr); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } // if (byFBOption == AUTO_FB_NONE) } else if (byPktType == PK_TYPE_11A) { if (byFBOption == AUTO_FB_NONE) { @@ -946,23 +917,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - ether_addr_copy(buf->data.ra, - psEthHeader->abyDstAddr); - } else { - ether_addr_copy(buf->data.ra, - pDevice->abyBSSID); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - ether_addr_copy(buf->data.ta, - pDevice->abyBSSID); - else - ether_addr_copy(buf->data.ta, - psEthHeader->abySrcAddr); - + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_a_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ @@ -991,20 +947,8 @@ s_vFillRTSHead( cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - ether_addr_copy(buf->data.ra, - psEthHeader->abyDstAddr); - } else { - ether_addr_copy(buf->data.ra, - pDevice->abyBSSID); - } - if (pDevice->op_mode == NL80211_IFTYPE_AP) - ether_addr_copy(buf->data.ta, - pDevice->abyBSSID); - else - ether_addr_copy(buf->data.ta, - psEthHeader->abySrcAddr); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } else if (byPktType == PK_TYPE_11B) { struct vnt_rts_ab *buf = pvRTS; @@ -1023,19 +967,8 @@ s_vFillRTSHead( buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - ether_addr_copy(buf->data.ra, - psEthHeader->abyDstAddr); - } else { - ether_addr_copy(buf->data.ra, pDevice->abyBSSID); - } - - if (pDevice->op_mode == NL80211_IFTYPE_AP) - ether_addr_copy(buf->data.ta, pDevice->abyBSSID); - else - ether_addr_copy(buf->data.ta, - psEthHeader->abySrcAddr); + ether_addr_copy(buf->data.ra, hdr->addr1); + ether_addr_copy(buf->data.ta, hdr->addr2); } } -- GitLab From 89cf9be6e6e128d64cf0c914ec71db1d25427524 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:42 +0000 Subject: [PATCH 2033/9457] staging: vt6655: mac80211 conversion: s_uFillDataHead add power saving poll Replace variable wCurrentRate with is_pspoll. add current_aid to structure vnt_private which is to be used by mac80211 operations. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 1 + drivers/staging/vt6655/rxtx.c | 64 +++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index bc9b81ad5185..7d521c63a55f 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -324,6 +324,7 @@ struct vnt_private { struct ieee80211_hw *hw; struct ieee80211_vif *vif; unsigned long key_entry_inuse; + u16 current_aid; /* netdev */ struct net_device *dev; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index a1a594fa10d5..23ee3799e86e 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -169,7 +169,8 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ); /*--------------------- Export Variables --------------------------*/ @@ -674,7 +675,8 @@ s_uFillDataHead( unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, - unsigned short wCurrentRate + unsigned short wCurrentRate, + bool is_pspoll ) { @@ -693,15 +695,24 @@ s_uFillDataHead( pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); - /* Get Duration and TimeStamp */ - buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, - byPktType, wCurrentRate, bNeedAck, uFragIdx, - cbLastFragmentSize, uMACfragNum, - byFBOption)); - buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, - PK_TYPE_11B, pDevice->byTopCCKBasicRate, - bNeedAck, uFragIdx, cbLastFragmentSize, - uMACfragNum, byFBOption)); + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration_a = dur; + buf->duration_b = dur; + } else { + /* Get Duration and TimeStamp */ + buf->duration_a = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, + byPktType, wCurrentRate, bNeedAck, uFragIdx, + cbLastFragmentSize, uMACfragNum, + byFBOption)); + buf->duration_b = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, + PK_TYPE_11B, pDevice->byTopCCKBasicRate, + bNeedAck, uFragIdx, cbLastFragmentSize, + uMACfragNum, byFBOption)); + } buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); @@ -755,11 +766,18 @@ s_uFillDataHead( vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; @@ -769,17 +787,27 @@ s_uFillDataHead( /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); - /* Get Duration and TimeStampOff */ - buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, + + if (is_pspoll) { + __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); + + buf->duration = dur; + } else { + /* Get Duration and TimeStampOff */ + buf->duration = + cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); + } + buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } return 0; } + static void s_vFillRTSHead( @@ -1346,7 +1374,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate); /* Fill DataHead */ uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, - 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate); + 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll); hdr->duration_id = uDuration; @@ -1750,7 +1778,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + 0, 0, 1, AUTO_FB_NONE, wCurrentRate, false); pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); @@ -2245,7 +2273,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate); + 0, 0, 1, AUTO_FB_NONE, wCurrentRate, false); pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); -- GitLab From 432c856fcf45c468fffe2e5029cb3f95c7dc9475 Mon Sep 17 00:00:00 2001 From: Toshiaki Makita Date: Mon, 27 Oct 2014 10:30:51 -0700 Subject: [PATCH 2034/9457] net: skb_segment() should preserve backpressure This patch generalizes commit d6a4a1041176 ("tcp: GSO should be TSQ friendly") to protocols using skb_set_owner_w() TCP uses its own destructor (tcp_wfree) and needs a more complex scheme as explained in commit 6ff50cd55545 ("tcp: gso: do not generate out of order packets") This allows UDP sockets using UFO to get proper backpressure, thus avoiding qdisc drops and excessive cpu usage. Here are performance test results (macvlan on vlan): - Before # netperf -t UDP_STREAM ... Socket Message Elapsed Messages Size Size Time Okay Errors Throughput bytes bytes secs # # 10^6bits/sec 212992 65507 60.00 144096 1224195 1258.56 212992 60.00 51 0.45 Average: CPU %user %nice %system %iowait %steal %idle Average: all 0.23 0.00 25.26 0.08 0.00 74.43 - After # netperf -t UDP_STREAM ... Socket Message Elapsed Messages Size Size Time Okay Errors Throughput bytes bytes secs # # 10^6bits/sec 212992 65507 60.00 109593 0 957.20 212992 60.00 109593 957.20 Average: CPU %user %nice %system %iowait %steal %idle Average: all 0.18 0.00 8.38 0.02 0.00 91.43 [edumazet] Rewrote patch and changelog. Signed-off-by: Toshiaki Makita Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/skbuff.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c16615bfb61e..e48e5c02e877 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3099,6 +3099,16 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, * (see validate_xmit_skb_list() for example) */ segs->prev = tail; + + /* Following permits correct backpressure, for protocols + * using skb_set_owner_w(). + * Idea is to tranfert ownership from head_skb to last segment. + */ + if (head_skb->destructor == sock_wfree) { + swap(tail->truesize, head_skb->truesize); + swap(tail->destructor, head_skb->destructor); + swap(tail->sk, head_skb->sk); + } return segs; err: -- GitLab From 7aef06db0f91c7b48305d07b62edf43179adb28c Mon Sep 17 00:00:00 2001 From: Roberto Medina Date: Tue, 28 Oct 2014 00:51:56 +0100 Subject: [PATCH 2035/9457] net: ethernet: realtek: atp: checkpatch errors and warnings corrected Several warnings and errors of coding style rules corrected. Compile tested. Signed-off-by: Roberto Medina Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/atp.h | 246 +++++++++++++++-------------- 1 file changed, 127 insertions(+), 119 deletions(-) diff --git a/drivers/net/ethernet/realtek/atp.h b/drivers/net/ethernet/realtek/atp.h index 040b13739947..32497f0e537c 100644 --- a/drivers/net/ethernet/realtek/atp.h +++ b/drivers/net/ethernet/realtek/atp.h @@ -6,10 +6,10 @@ /* The header prepended to received packets. */ struct rx_header { - ushort pad; /* Pad. */ - ushort rx_count; - ushort rx_status; /* Unknown bit assignments :-<. */ - ushort cur_addr; /* Apparently the current buffer address(?) */ + ushort pad; /* Pad. */ + ushort rx_count; + ushort rx_status; /* Unknown bit assignments :-<. */ + ushort cur_addr; /* Apparently the current buffer address(?) */ }; #define PAR_DATA 0 @@ -29,22 +29,25 @@ struct rx_header { #define RdAddr 0xC0 #define HNib 0x10 -enum page0_regs -{ - /* The first six registers hold the ethernet physical station address. */ - PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5, - TxCNT0 = 6, TxCNT1 = 7, /* The transmit byte count. */ - TxSTAT = 8, RxSTAT = 9, /* Tx and Rx status. */ - ISR = 10, IMR = 11, /* Interrupt status and mask. */ - CMR1 = 12, /* Command register 1. */ - CMR2 = 13, /* Command register 2. */ - MODSEL = 14, /* Mode select register. */ - MAR = 14, /* Memory address register (?). */ - CMR2_h = 0x1d, }; - -enum eepage_regs -{ PROM_CMD = 6, PROM_DATA = 7 }; /* Note that PROM_CMD is in the "high" bits. */ +enum page0_regs { + /* The first six registers hold + * the ethernet physical station address. + */ + PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5, + TxCNT0 = 6, TxCNT1 = 7, /* The transmit byte count. */ + TxSTAT = 8, RxSTAT = 9, /* Tx and Rx status. */ + ISR = 10, IMR = 11, /* Interrupt status and mask. */ + CMR1 = 12, /* Command register 1. */ + CMR2 = 13, /* Command register 2. */ + MODSEL = 14, /* Mode select register. */ + MAR = 14, /* Memory address register (?). */ + CMR2_h = 0x1d, +}; +enum eepage_regs { + PROM_CMD = 6, + PROM_DATA = 7 /* Note that PROM_CMD is in the "high" bits. */ +}; #define ISR_TxOK 0x01 #define ISR_RxOK 0x04 @@ -72,141 +75,146 @@ enum eepage_regs #define CMR2h_Normal 2 /* Accept physical and broadcast address. */ #define CMR2h_PROMISC 3 /* Promiscuous mode. */ -/* An inline function used below: it differs from inb() by explicitly return an unsigned - char, saving a truncation. */ +/* An inline function used below: it differs from inb() by explicitly + * return an unsigned char, saving a truncation. + */ static inline unsigned char inbyte(unsigned short port) { - unsigned char _v; - __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port)); - return _v; + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%b0" : "=a" (_v) : "d" (port)); + return _v; } /* Read register OFFSET. - This command should always be terminated with read_end(). */ + * This command should always be terminated with read_end(). + */ static inline unsigned char read_nibble(short port, unsigned char offset) { - unsigned char retval; - outb(EOC+offset, port + PAR_DATA); - outb(RdAddr+offset, port + PAR_DATA); - inbyte(port + PAR_STATUS); /* Settling time delay */ - retval = inbyte(port + PAR_STATUS); - outb(EOC+offset, port + PAR_DATA); - - return retval; + unsigned char retval; + + outb(EOC+offset, port + PAR_DATA); + outb(RdAddr+offset, port + PAR_DATA); + inbyte(port + PAR_STATUS); /* Settling time delay */ + retval = inbyte(port + PAR_STATUS); + outb(EOC+offset, port + PAR_DATA); + + return retval; } /* Functions for bulk data read. The interrupt line is always disabled. */ /* Get a byte using read mode 0, reading data from the control lines. */ static inline unsigned char read_byte_mode0(short ioaddr) { - unsigned char low_nib; - - outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL); - inbyte(ioaddr + PAR_STATUS); - low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; - outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL); - inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ - inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ - return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); + unsigned char low_nib; + + outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL); + inbyte(ioaddr + PAR_STATUS); + low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; + outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL); + inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ + inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ + return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); } /* The same as read_byte_mode0(), but does multiple inb()s for stability. */ static inline unsigned char read_byte_mode2(short ioaddr) { - unsigned char low_nib; - - outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL); - inbyte(ioaddr + PAR_STATUS); - low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; - outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL); - inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ - return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); + unsigned char low_nib; + + outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL); + inbyte(ioaddr + PAR_STATUS); + low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; + outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL); + inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */ + return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); } /* Read a byte through the data register. */ static inline unsigned char read_byte_mode4(short ioaddr) { - unsigned char low_nib; + unsigned char low_nib; - outb(RdAddr | MAR, ioaddr + PAR_DATA); - low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; - outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA); - return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); + outb(RdAddr | MAR, ioaddr + PAR_DATA); + low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; + outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA); + return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); } /* Read a byte through the data register, double reading to allow settling. */ static inline unsigned char read_byte_mode6(short ioaddr) { - unsigned char low_nib; - - outb(RdAddr | MAR, ioaddr + PAR_DATA); - inbyte(ioaddr + PAR_STATUS); - low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; - outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA); - inbyte(ioaddr + PAR_STATUS); - return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); + unsigned char low_nib; + + outb(RdAddr | MAR, ioaddr + PAR_DATA); + inbyte(ioaddr + PAR_STATUS); + low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f; + outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA); + inbyte(ioaddr + PAR_STATUS); + return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0); } static inline void write_reg(short port, unsigned char reg, unsigned char value) { - unsigned char outval; - outb(EOC | reg, port + PAR_DATA); - outval = WrAddr | reg; - outb(outval, port + PAR_DATA); - outb(outval, port + PAR_DATA); /* Double write for PS/2. */ - - outval &= 0xf0; - outval |= value; - outb(outval, port + PAR_DATA); - outval &= 0x1f; - outb(outval, port + PAR_DATA); - outb(outval, port + PAR_DATA); - - outb(EOC | outval, port + PAR_DATA); + unsigned char outval; + + outb(EOC | reg, port + PAR_DATA); + outval = WrAddr | reg; + outb(outval, port + PAR_DATA); + outb(outval, port + PAR_DATA); /* Double write for PS/2. */ + + outval &= 0xf0; + outval |= value; + outb(outval, port + PAR_DATA); + outval &= 0x1f; + outb(outval, port + PAR_DATA); + outb(outval, port + PAR_DATA); + + outb(EOC | outval, port + PAR_DATA); } static inline void write_reg_high(short port, unsigned char reg, unsigned char value) { - unsigned char outval = EOC | HNib | reg; + unsigned char outval = EOC | HNib | reg; - outb(outval, port + PAR_DATA); - outval &= WrAddr | HNib | 0x0f; - outb(outval, port + PAR_DATA); - outb(outval, port + PAR_DATA); /* Double write for PS/2. */ + outb(outval, port + PAR_DATA); + outval &= WrAddr | HNib | 0x0f; + outb(outval, port + PAR_DATA); + outb(outval, port + PAR_DATA); /* Double write for PS/2. */ - outval = WrAddr | HNib | value; - outb(outval, port + PAR_DATA); - outval &= HNib | 0x0f; /* HNib | value */ - outb(outval, port + PAR_DATA); - outb(outval, port + PAR_DATA); + outval = WrAddr | HNib | value; + outb(outval, port + PAR_DATA); + outval &= HNib | 0x0f; /* HNib | value */ + outb(outval, port + PAR_DATA); + outb(outval, port + PAR_DATA); - outb(EOC | HNib | outval, port + PAR_DATA); + outb(EOC | HNib | outval, port + PAR_DATA); } /* Write a byte out using nibble mode. The low nibble is written first. */ static inline void write_reg_byte(short port, unsigned char reg, unsigned char value) { - unsigned char outval; - outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */ - outval = WrAddr | reg; - outb(outval, port + PAR_DATA); - outb(outval, port + PAR_DATA); /* Double write for PS/2. */ - - outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA); - outb(value & 0x0f, port + PAR_DATA); - value >>= 4; - outb(value, port + PAR_DATA); - outb(0x10 | value, port + PAR_DATA); - outb(0x10 | value, port + PAR_DATA); - - outb(EOC | value, port + PAR_DATA); /* Reset the address register. */ + unsigned char outval; + + outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */ + outval = WrAddr | reg; + outb(outval, port + PAR_DATA); + outb(outval, port + PAR_DATA); /* Double write for PS/2. */ + + outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA); + outb(value & 0x0f, port + PAR_DATA); + value >>= 4; + outb(value, port + PAR_DATA); + outb(0x10 | value, port + PAR_DATA); + outb(0x10 | value, port + PAR_DATA); + + outb(EOC | value, port + PAR_DATA); /* Reset the address register. */ } -/* - * Bulk data writes to the packet buffer. The interrupt line remains enabled. +/* Bulk data writes to the packet buffer. The interrupt line remains enabled. * The first, faster method uses only the dataport (data modes 0, 2 & 4). * The second (backup) method uses data and control regs (modes 1, 3 & 5). * It should only be needed when there is skew between the individual data @@ -214,28 +222,28 @@ write_reg_byte(short port, unsigned char reg, unsigned char value) */ static inline void write_byte_mode0(short ioaddr, unsigned char value) { - outb(value & 0x0f, ioaddr + PAR_DATA); - outb((value>>4) | 0x10, ioaddr + PAR_DATA); + outb(value & 0x0f, ioaddr + PAR_DATA); + outb((value>>4) | 0x10, ioaddr + PAR_DATA); } static inline void write_byte_mode1(short ioaddr, unsigned char value) { - outb(value & 0x0f, ioaddr + PAR_DATA); - outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL); - outb((value>>4) | 0x10, ioaddr + PAR_DATA); - outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL); + outb(value & 0x0f, ioaddr + PAR_DATA); + outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL); + outb((value>>4) | 0x10, ioaddr + PAR_DATA); + outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL); } /* Write 16bit VALUE to the packet buffer: the same as above just doubled. */ static inline void write_word_mode0(short ioaddr, unsigned short value) { - outb(value & 0x0f, ioaddr + PAR_DATA); - value >>= 4; - outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA); - value >>= 4; - outb(value & 0x0f, ioaddr + PAR_DATA); - value >>= 4; - outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA); + outb(value & 0x0f, ioaddr + PAR_DATA); + value >>= 4; + outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA); + value >>= 4; + outb(value & 0x0f, ioaddr + PAR_DATA); + value >>= 4; + outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA); } /* EEPROM_Ctrl bits. */ @@ -248,10 +256,10 @@ static inline void write_word_mode0(short ioaddr, unsigned short value) /* Delay between EEPROM clock transitions. */ #define eeprom_delay(ticks) \ -do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) +do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; } } while (0) /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD(offset) (((5 << 6) + (offset)) << 17) -#define EE_READ(offset) (((6 << 6) + (offset)) << 17) +#define EE_READ(offset) (((6 << 6) + (offset)) << 17) #define EE_ERASE(offset) (((7 << 6) + (offset)) << 17) #define EE_CMD_SIZE 27 /* The command+address+data size. */ -- GitLab From dca145ffaa8d39ea1904491ac81b92b7049372c0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Oct 2014 21:45:24 -0700 Subject: [PATCH 2036/9457] tcp: allow for bigger reordering level While testing upcoming Yaogong patch (converting out of order queue into an RB tree), I hit the max reordering level of linux TCP stack. Reordering level was limited to 127 for no good reason, and some network setups [1] can easily reach this limit and get limited throughput. Allow a new max limit of 300, and add a sysctl to allow admins to even allow bigger (or lower) values if needed. [1] Aggregation of links, per packet load balancing, fabrics not doing deep packet inspections, alternative TCP congestion modules... Signed-off-by: Eric Dumazet Cc: Yaogong Wang Signed-off-by: David S. Miller --- Documentation/networking/bonding.txt | 7 ++----- Documentation/networking/ip-sysctl.txt | 10 +++++++++- include/linux/tcp.h | 4 ++-- include/net/tcp.h | 4 +--- net/ipv4/sysctl_net_ipv4.c | 7 +++++++ net/ipv4/tcp_input.c | 3 ++- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index eeb5b2e97bed..83bf4986baea 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -2230,11 +2230,8 @@ balance-rr: This mode is the only mode that will permit a single It is possible to adjust TCP/IP's congestion limits by altering the net.ipv4.tcp_reordering sysctl parameter. The - usual default value is 3, and the maximum useful value is 127. - For a four interface balance-rr bond, expect that a single - TCP/IP stream will utilize no more than approximately 2.3 - interface's worth of throughput, even after adjusting - tcp_reordering. + usual default value is 3. But keep in mind TCP stack is able + to automatically increase this when it detects reorders. Note that the fraction of packets that will be delivered out of order is highly variable, and is unlikely to be zero. The level diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 0307e2875f21..9028b879a97b 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -376,9 +376,17 @@ tcp_orphan_retries - INTEGER may consume significant resources. Cf. tcp_max_orphans. tcp_reordering - INTEGER - Maximal reordering of packets in a TCP stream. + Initial reordering level of packets in a TCP stream. + TCP stack can then dynamically adjust flow reordering level + between this initial value and tcp_max_reordering Default: 3 +tcp_max_reordering - INTEGER + Maximal reordering level of packets in a TCP stream. + 300 is a fairly conservative value, but you might increase it + if paths are using per packet load balancing (like bonding rr mode) + Default: 300 + tcp_retrans_collapse - BOOLEAN Bug-to-bug compatibility with some broken printers. On retransmit try to send bigger packets to work around bugs in diff --git a/include/linux/tcp.h b/include/linux/tcp.h index c2dee7deefa8..f566b8567892 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -204,10 +204,10 @@ struct tcp_sock { u16 urg_data; /* Saved octet of OOB data and control flags */ u8 ecn_flags; /* ECN status bits. */ - u8 reordering; /* Packet reordering metric. */ + u8 keepalive_probes; /* num of allowed keep alive probes */ + u32 reordering; /* Packet reordering metric. */ u32 snd_up; /* Urgent pointer */ - u8 keepalive_probes; /* num of allowed keep alive probes */ /* * Options received (usually on last packet, some only on SYN packets). */ diff --git a/include/net/tcp.h b/include/net/tcp.h index c73fc145ee45..3a35b1500359 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -70,9 +70,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); /* After receiving this amount of duplicate ACKs fast retransmit starts. */ #define TCP_FASTRETRANS_THRESH 3 -/* Maximal reordering. */ -#define TCP_MAX_REORDERING 127 - /* Maximal number of ACKs sent quickly to accelerate slow-start. */ #define TCP_MAX_QUICKACKS 16U @@ -252,6 +249,7 @@ extern int sysctl_tcp_abort_on_overflow; extern int sysctl_tcp_max_orphans; extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; +extern int sysctl_tcp_max_reordering; extern int sysctl_tcp_dsack; extern long sysctl_tcp_mem[3]; extern int sysctl_tcp_wmem[3]; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index b3c53c8b331e..e0ee384a448f 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -495,6 +495,13 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "tcp_max_reordering", + .data = &sysctl_tcp_max_reordering, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, { .procname = "tcp_dsack", .data = &sysctl_tcp_dsack, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a12b455928e5..9a18cdd633f3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -81,6 +81,7 @@ int sysctl_tcp_window_scaling __read_mostly = 1; int sysctl_tcp_sack __read_mostly = 1; int sysctl_tcp_fack __read_mostly = 1; int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH; +int sysctl_tcp_max_reordering __read_mostly = 300; EXPORT_SYMBOL(sysctl_tcp_reordering); int sysctl_tcp_dsack __read_mostly = 1; int sysctl_tcp_app_win __read_mostly = 31; @@ -833,7 +834,7 @@ static void tcp_update_reordering(struct sock *sk, const int metric, if (metric > tp->reordering) { int mib_idx; - tp->reordering = min(TCP_MAX_REORDERING, metric); + tp->reordering = min(sysctl_tcp_max_reordering, metric); /* This exciting event is worth to be remembered. 8) */ if (ts) -- GitLab From f37119c57ba7591b365b41697f971ca3e1f16ed1 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Tue, 28 Oct 2014 14:05:51 +0800 Subject: [PATCH 2037/9457] r8152: rename tx_underun Replace tx_underun with tx_underrun for checkpatch.pl. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e3d84c322e4e..fdea19412cdb 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -486,7 +486,7 @@ struct tally_counter { __le64 rx_broadcast; __le32 rx_multicast; __le16 tx_aborted; - __le16 tx_underun; + __le16 tx_underrun; }; struct rx_desc { @@ -3420,7 +3420,7 @@ static void rtl8152_get_ethtool_stats(struct net_device *dev, data[9] = le64_to_cpu(tally.rx_broadcast); data[10] = le32_to_cpu(tally.rx_multicast); data[11] = le16_to_cpu(tally.tx_aborted); - data[12] = le16_to_cpu(tally.tx_underun); + data[12] = le16_to_cpu(tally.tx_underrun); } static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) -- GitLab From 8884f5078085a3cd4dc9c24bc81e00177c49cf5b Mon Sep 17 00:00:00 2001 From: hayeswang Date: Tue, 28 Oct 2014 14:05:52 +0800 Subject: [PATCH 2038/9457] r8152: support nway_reset of ethtool Support the nway_reset() function for ethtool. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index fdea19412cdb..e1810bc386b7 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3558,11 +3558,33 @@ rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) return ret; } +static int rtl8152_nway_reset(struct net_device *dev) +{ + struct r8152 *tp = netdev_priv(dev); + int ret; + + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + goto out; + + mutex_lock(&tp->control); + + ret = mii_nway_restart(&tp->mii); + + mutex_unlock(&tp->control); + + usb_autopm_put_interface(tp->intf); + +out: + return ret; +} + static struct ethtool_ops ops = { .get_drvinfo = rtl8152_get_drvinfo, .get_settings = rtl8152_get_settings, .set_settings = rtl8152_set_settings, .get_link = ethtool_op_get_link, + .nway_reset = rtl8152_nway_reset, .get_msglevel = rtl8152_get_msglevel, .set_msglevel = rtl8152_set_msglevel, .get_wol = rtl8152_get_wol, -- GitLab From 7fd2561e4ebdd070ebba6d3326c4c5b13942323f Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Tue, 28 Oct 2014 18:11:14 +0900 Subject: [PATCH 2039/9457] net: ipv6: Add a sysctl to make optimistic addresses useful candidates Add a sysctl that causes an interface's optimistic addresses to be considered equivalent to other non-deprecated addresses for source address selection purposes. Preferred addresses will still take precedence over optimistic addresses, subject to other ranking in the source address selection algorithm. This is useful where different interfaces are connected to different networks from different ISPs (e.g., a cell network and a home wifi network). The current behaviour complies with RFC 3484/6724, and it makes sense if the host has only one interface, or has multiple interfaces on the same network (same or cooperating administrative domain(s), but not in the multiple distinct networks case. For example, if a mobile device has an IPv6 address on an LTE network and then connects to IPv6-enabled wifi, while the wifi IPv6 address is undergoing DAD, IPv6 connections will try use the wifi default route with the LTE IPv6 address, and will get stuck until they time out. Also, because optimistic nodes can receive frames, issue an RTM_NEWADDR as soon as DAD starts (with the IFA_F_OPTIMSTIC flag appropriately set). A second RTM_NEWADDR is sent if DAD completes (the address flags have changed), otherwise an RTM_DELADDR is sent. Also: add an entry in ip-sysctl.txt for optimistic_dad. Signed-off-by: Erik Kline Acked-by: Lorenzo Colitti Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 13 ++++++++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 1 + net/ipv6/addrconf.c | 46 ++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 9028b879a97b..368e3251c553 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1460,6 +1460,19 @@ suppress_frag_ndisc - INTEGER 1 - (default) discard fragmented neighbor discovery packets 0 - allow fragmented neighbor discovery packets +optimistic_dad - BOOLEAN + Whether to perform Optimistic Duplicate Address Detection (RFC 4429). + 0: disabled (default) + 1: enabled + +use_optimistic - BOOLEAN + If enabled, do not classify optimistic addresses as deprecated during + source address selection. Preferred addresses will still be chosen + before optimistic addresses, subject to other ranking in the source + address selection algorithm. + 0: disabled (default) + 1: enabled + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index ff560537dd61..7121a2e97ce2 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -42,6 +42,7 @@ struct ipv6_devconf { __s32 accept_ra_from_local; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD __s32 optimistic_dad; + __s32 use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE __s32 mc_forwarding; diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index efa2666f4b8a..e863d088b9a5 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -164,6 +164,7 @@ enum { DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL, DEVCONF_SUPPRESS_FRAG_NDISC, DEVCONF_ACCEPT_RA_FROM_LOCAL, + DEVCONF_USE_OPTIMISTIC, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 50b95b2db87c..8d12b7c7018f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1170,6 +1170,9 @@ enum { IPV6_SADDR_RULE_PRIVACY, IPV6_SADDR_RULE_ORCHID, IPV6_SADDR_RULE_PREFIX, +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + IPV6_SADDR_RULE_NOT_OPTIMISTIC, +#endif IPV6_SADDR_RULE_MAX }; @@ -1197,6 +1200,15 @@ static inline int ipv6_saddr_preferred(int type) return 0; } +static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev) +{ +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic; +#else + return false; +#endif +} + static int ipv6_get_saddr_eval(struct net *net, struct ipv6_saddr_score *score, struct ipv6_saddr_dst *dst, @@ -1257,10 +1269,16 @@ static int ipv6_get_saddr_eval(struct net *net, score->scopedist = ret; break; case IPV6_SADDR_RULE_PREFERRED: + { /* Rule 3: Avoid deprecated and optimistic addresses */ + u8 avoid = IFA_F_DEPRECATED; + + if (!ipv6_use_optimistic_addr(score->ifa->idev)) + avoid |= IFA_F_OPTIMISTIC; ret = ipv6_saddr_preferred(score->addr_type) || - !(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)); + !(score->ifa->flags & avoid); break; + } #ifdef CONFIG_IPV6_MIP6 case IPV6_SADDR_RULE_HOA: { @@ -1306,6 +1324,14 @@ static int ipv6_get_saddr_eval(struct net *net, ret = score->ifa->prefix_len; score->matchlen = ret; break; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + case IPV6_SADDR_RULE_NOT_OPTIMISTIC: + /* Optimistic addresses still have lower precedence than other + * preferred addresses. + */ + ret = !(score->ifa->flags & IFA_F_OPTIMISTIC); + break; +#endif default: ret = 0; } @@ -3222,8 +3248,15 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) * Optimistic nodes can start receiving * Frames right away */ - if (ifp->flags & IFA_F_OPTIMISTIC) + if (ifp->flags & IFA_F_OPTIMISTIC) { ip6_ins_rt(ifp->rt); + if (ipv6_use_optimistic_addr(idev)) { + /* Because optimistic nodes can use this address, + * notify listeners. If DAD fails, RTM_DELADDR is sent. + */ + ipv6_ifa_notify(RTM_NEWADDR, ifp); + } + } addrconf_dad_kick(ifp); out: @@ -4330,6 +4363,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad; + array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic; #endif #ifdef CONFIG_IPV6_MROUTE array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; @@ -5155,6 +5189,14 @@ static struct addrconf_sysctl_table .proc_handler = proc_dointvec, }, + { + .procname = "use_optimistic", + .data = &ipv6_devconf.use_optimistic, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, #endif #ifdef CONFIG_IPV6_MROUTE { -- GitLab From 49ed9ee442227e7f2ef617ca1399269d567834b9 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 9 Oct 2014 22:23:57 -0700 Subject: [PATCH 2040/9457] clk: rockchip: change PLL setting for better clock jitter dclk_vop0/1 is the source of HDMI TMDS clock in rk3288, usually we use 594MHz for clock source of dclk_vop0/1. HDMI CTS 7-9 require TMDS Clock jitter is lower than 0.25*Tbit: TMDS clock(MHz) CTS require jitter (ps) 297 84.2 148.5 168 74.25 336 27 1247 PLL BW and VCO frequency effects the jitter of PLL output clock, clock jitter is better if BW is lower or VCO frequency is higher. If PLL use default setting of RK3066_PLL_RATE( 594000000, 2, 198, 4), the TMDS Clock jitter is higher than 250ps, which means we can't pass the test when TMDS clock is 297MHz or 148.5MHz. If we use RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1), the TMDS Clock jitter is about 60ps and we can pass all test case. So we need this patch to make hdmi si test pass. Signed-off-by: Kever Yang Reviewed-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/clk/rockchip/clk.h | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 4cef77b5006d..279a662f5bd7 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -83,7 +83,7 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE( 742500000, 8, 495, 2), RK3066_PLL_RATE( 696000000, 1, 58, 2), RK3066_PLL_RATE( 600000000, 1, 50, 2), - RK3066_PLL_RATE( 594000000, 2, 198, 4), + RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1), RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 504000000, 1, 84, 4), RK3066_PLL_RATE( 500000000, 3, 125, 2), diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ca009ab0a33a..6baf6655b5c3 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -62,6 +62,15 @@ enum rockchip_pll_type { .bwadj = (_nf >> 1), \ } +#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw) \ +{ \ + .rate = _rate##U, \ + .nr = _nr, \ + .nf = _nf, \ + .no = _no, \ + .bwadj = _bw, \ +} + struct rockchip_pll_rate_table { unsigned long rate; unsigned int nr; -- GitLab From 8fe78989c3445a221cfcc54964e7e62718883615 Mon Sep 17 00:00:00 2001 From: Zoltan Kiss Date: Tue, 28 Oct 2014 15:29:30 +0000 Subject: [PATCH 2041/9457] xen-netback: Disable NAPI after disabling interrupts Otherwise the interrupt handler still calls napi_complete. Although it won't schedule NAPI again as either NAPI_STATE_DISABLE or NAPI_STATE_SCHED is set, it is just unnecessary, and it makes more sense to do this way. Signed-off-by: Zoltan Kiss Signed-off-by: David Vrabel Acked-by: Wei Liu Signed-off-by: David S. Miller --- drivers/net/xen-netback/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index f379689dde30..7342a6bb5557 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -281,10 +281,10 @@ static void xenvif_down(struct xenvif *vif) for (queue_index = 0; queue_index < num_queues; ++queue_index) { queue = &vif->queues[queue_index]; - napi_disable(&queue->napi); disable_irq(queue->tx_irq); if (queue->tx_irq != queue->rx_irq) disable_irq(queue->rx_irq); + napi_disable(&queue->napi); del_timer_sync(&queue->credit_timeout); } } -- GitLab From 44cc8ed17e203479827ef6b6d37404d2665da6fb Mon Sep 17 00:00:00 2001 From: Zoltan Kiss Date: Tue, 28 Oct 2014 15:29:31 +0000 Subject: [PATCH 2042/9457] xen-netback: Remove __GFP_COLD This flag is unnecessary, it came from some old code. Suggested-by: Eric Dumazet Signed-off-by: Zoltan Kiss Signed-off-by: David Vrabel Acked-by: Wei Liu Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 08f65996534c..85fec0fb4ec2 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1494,7 +1494,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s unsigned int len; BUG_ON(i >= MAX_SKB_FRAGS); - page = alloc_page(GFP_ATOMIC|__GFP_COLD); + page = alloc_page(GFP_ATOMIC); if (!page) { int j; skb->truesize += skb->data_len; -- GitLab From 876d716ba9af205f46b7e911d39482e627aea0e8 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 21 Oct 2014 10:47:32 -0700 Subject: [PATCH 2043/9457] pinctrl: rockchip: Set wake_enabled The rockchip pinctrl driver uses irq_gc_set_wake() but doesn't setup the .wake_enabled member. That means that we can never actually use a pin for wakeup. When "irq_set_irq_wake()" tries to call through it will always get a failure from set_irq_wake_real() and will then set wake_depth to 0. Assuming you can resume you'll later get an error message about "Unbalanced IRQ x wake disable". Signed-off-by: Doug Anderson Tested-by: Chris Zhong Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 016f4578e494..230d8f379129 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1563,6 +1563,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev, gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; + gc->wake_enabled = IRQ_MSK(bank->nr_pins); irq_set_handler_data(bank->irq, bank); irq_set_chained_handler(bank->irq, rockchip_irq_demux); -- GitLab From e5c2c9db0a2cff4d4df4b94f91146b26a0f0adc7 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 21 Oct 2014 10:47:33 -0700 Subject: [PATCH 2044/9457] pinctrl: rockchip: Don't call pinctrl_gpio_direction_output() in pin_config_set() The Rockchip pinctrl driver was calling rockchip_gpio_direction_output() in the pin_config_set() callback. This was just a shortcut for: * rockchip_gpio_set() * pinctrl_gpio_direction_output() Unfortunately it's not so good to call pinctrl_gpio_direction_output() from pin_config_set(). Specifically when initting hogs you'll get an error. Let's refactor a little so we can call _rockchip_pmx_gpio_set_direction() directly. Signed-off-by: Doug Anderson Tested-by: Chris Zhong Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 41 ++++++++++++++++++------------ 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 230d8f379129..8a3c582108c5 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -856,22 +856,14 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, * leads to this function call (via the pinctrl_gpio_direction_{input|output}() * function called from the gpiolib interface). */ -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset, bool input) +static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, + int pin, bool input) { - struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct rockchip_pin_bank *bank; - struct gpio_chip *chip; - int pin, ret; + int ret; u32 data; - chip = range->gc; bank = gc_to_pin_bank(chip); - pin = offset - chip->base; - - dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", - offset, range->name, pin, input ? "input" : "output"); ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); if (ret < 0) @@ -888,6 +880,23 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, return 0; } +static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, bool input) +{ + struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct gpio_chip *chip; + int pin; + + chip = range->gc; + pin = offset - chip->base; + dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", + offset, range->name, pin, input ? "input" : "output"); + + return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base, + input); +} + static const struct pinmux_ops rockchip_pmx_ops = { .get_functions_count = rockchip_pmx_get_funcs_count, .get_function_name = rockchip_pmx_get_func_name, @@ -917,8 +926,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return false; } -static int rockchip_gpio_direction_output(struct gpio_chip *gc, - unsigned offset, int value); +static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value); static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); /* set the pin config settings for a specified pin */ @@ -959,9 +967,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, return rc; break; case PIN_CONFIG_OUTPUT: - rc = rockchip_gpio_direction_output(&bank->gpio_chip, - pin - bank->pin_base, - arg); + rockchip_gpio_set(&bank->gpio_chip, + pin - bank->pin_base, arg); + rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip, + pin - bank->pin_base, false); if (rc) return rc; break; -- GitLab From 0fb7dcb1b3328e2ec4958b681f2e31dfd8f004fb Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 21 Oct 2014 10:47:34 -0700 Subject: [PATCH 2045/9457] pinctrl: rockchip: Parse pin groups before calling pinctrl_register() Just like in (529301c pinctrl: samsung: Parse pin groups before calling pinctrl_register()), Rockchip also needs to parse pin groups earlier to make hogs work. Signed-off-by: Doug Anderson Tested-by: Chris Zhong Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 8a3c582108c5..6c14f6c9c455 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1262,6 +1262,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, } } + ret = rockchip_pinctrl_parse_dt(pdev, info); + if (ret) + return ret; + info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); if (!info->pctl_dev) { dev_err(&pdev->dev, "could not register pinctrl driver\n"); @@ -1279,12 +1283,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); } - ret = rockchip_pinctrl_parse_dt(pdev, info); - if (ret) { - pinctrl_unregister(info->pctl_dev); - return ret; - } - return 0; } -- GitLab From fab262f5000407ce86a010ab5bc683c01c02d1a6 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 21 Oct 2014 10:47:35 -0700 Subject: [PATCH 2046/9457] pinctrl: rockchip: Protect read-modify-write with the spinlock There were a few instances where the rockchip pinctrl driver would do read-modify-write with no spinlock. Add a spinlock for these cases. Signed-off-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 6c14f6c9c455..59a54617bf75 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -861,6 +861,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, { struct rockchip_pin_bank *bank; int ret; + unsigned long flags; u32 data; bank = gc_to_pin_bank(chip); @@ -869,6 +870,8 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, if (ret < 0) return ret; + spin_lock_irqsave(&bank->slock, flags); + data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); /* set bit to 1 for output, 0 for input */ if (!input) @@ -877,6 +880,8 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip, data &= ~BIT(pin); writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); + spin_unlock_irqrestore(&bank->slock, flags); + return 0; } @@ -1394,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) u32 polarity = 0, data = 0; u32 pend; bool edge_changed = false; + unsigned long flags; dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); @@ -1439,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) if (bank->toggle_edge_mode && edge_changed) { /* Interrupt params should only be set with ints disabled */ + spin_lock_irqsave(&bank->slock, flags); + data = readl_relaxed(bank->reg_base + GPIO_INTEN); writel_relaxed(0, bank->reg_base + GPIO_INTEN); writel(polarity, bank->reg_base + GPIO_INT_POLARITY); writel(data, bank->reg_base + GPIO_INTEN); + + spin_unlock_irqrestore(&bank->slock, flags); } chained_irq_exit(chip, desc); @@ -1456,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) u32 polarity; u32 level; u32 data; + unsigned long flags; int ret; /* make sure the pin is configured as gpio input */ @@ -1463,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) if (ret < 0) return ret; + spin_lock_irqsave(&bank->slock, flags); + data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); data &= ~mask; writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); + spin_unlock_irqrestore(&bank->slock, flags); + if (type & IRQ_TYPE_EDGE_BOTH) __irq_set_handler_locked(d->irq, handle_edge_irq); else __irq_set_handler_locked(d->irq, handle_level_irq); + spin_lock_irqsave(&bank->slock, flags); irq_gc_lock(gc); level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); @@ -1514,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) break; default: irq_gc_unlock(gc); + spin_unlock_irqrestore(&bank->slock, flags); return -EINVAL; } @@ -1521,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); irq_gc_unlock(gc); + spin_unlock_irqrestore(&bank->slock, flags); return 0; } -- GitLab From bc9ad166e38ae1cdcb5323a8aa45dff834d68bfa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Oct 2014 18:05:13 -0700 Subject: [PATCH 2047/9457] net: introduce napi_schedule_irqoff() napi_schedule() can be called from any context and has to mask hard irqs. Add a variant that can only be called from hard interrupts handlers or when irqs are already masked. Many NIC drivers can use it from their hard IRQ handler instead of generic variant. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 13 +++++++++++++ net/core/dev.c | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 74fd5d37f15a..c85e06512246 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -386,6 +386,7 @@ typedef enum rx_handler_result rx_handler_result_t; typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb); void __napi_schedule(struct napi_struct *n); +void __napi_schedule_irqoff(struct napi_struct *n); static inline bool napi_disable_pending(struct napi_struct *n) { @@ -420,6 +421,18 @@ static inline void napi_schedule(struct napi_struct *n) __napi_schedule(n); } +/** + * napi_schedule_irqoff - schedule NAPI poll + * @n: napi context + * + * Variant of napi_schedule(), assuming hard irqs are masked. + */ +static inline void napi_schedule_irqoff(struct napi_struct *n) +{ + if (napi_schedule_prep(n)) + __napi_schedule_irqoff(n); +} + /* Try to reschedule poll. Called by dev->poll() after napi_complete(). */ static inline bool napi_reschedule(struct napi_struct *napi) { diff --git a/net/core/dev.c b/net/core/dev.c index b793e3521a36..759940cdf896 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4372,7 +4372,8 @@ static int process_backlog(struct napi_struct *napi, int quota) * __napi_schedule - schedule for receive * @n: entry to schedule * - * The entry's receive function will be scheduled to run + * The entry's receive function will be scheduled to run. + * Consider using __napi_schedule_irqoff() if hard irqs are masked. */ void __napi_schedule(struct napi_struct *n) { @@ -4384,6 +4385,18 @@ void __napi_schedule(struct napi_struct *n) } EXPORT_SYMBOL(__napi_schedule); +/** + * __napi_schedule_irqoff - schedule for receive + * @n: entry to schedule + * + * Variant of __napi_schedule() assuming hard irqs are masked + */ +void __napi_schedule_irqoff(struct napi_struct *n) +{ + ____napi_schedule(this_cpu_ptr(&softnet_data), n); +} +EXPORT_SYMBOL(__napi_schedule_irqoff); + void __napi_complete(struct napi_struct *n) { BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); -- GitLab From 75fbfd33234a71556bec34b099d98f970190905d Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 29 Oct 2014 19:29:31 +0100 Subject: [PATCH 2048/9457] neigh: optimize neigh_parms_release() In neigh_parms_release() we loop over all entries to find the entry given in argument and being able to remove it from the list. By using a double linked list, we can avoid this loop. Here are some numbers with 30 000 dummy interfaces configured: Before the patch: $ time rmmod dummy real 2m0.118s user 0m0.000s sys 1m50.048s After the patch: $ time rmmod dummy real 1m9.970s user 0m0.000s sys 0m47.976s Suggested-by: Thierry Herbelot Signed-off-by: Nicolas Dichtel Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/neighbour.h | 3 ++- net/core/neighbour.c | 32 +++++++++++++------------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index f60558d0254c..dedfb188b1a7 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -69,7 +69,7 @@ struct neigh_parms { struct net *net; #endif struct net_device *dev; - struct neigh_parms *next; + struct list_head list; int (*neigh_setup)(struct neighbour *); void (*neigh_cleanup)(struct neighbour *); struct neigh_table *tbl; @@ -203,6 +203,7 @@ struct neigh_table { void (*proxy_redo)(struct sk_buff *skb); char *id; struct neigh_parms parms; + struct list_head parms_list; int gc_interval; int gc_thresh1; int gc_thresh2; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index ef31fef25e5a..edd04116ecb7 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -773,7 +773,7 @@ static void neigh_periodic_work(struct work_struct *work) if (time_after(jiffies, tbl->last_rand + 300 * HZ)) { struct neigh_parms *p; tbl->last_rand = jiffies; - for (p = &tbl->parms; p; p = p->next) + list_for_each_entry(p, &tbl->parms_list, list) p->reachable_time = neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); } @@ -1446,7 +1446,7 @@ static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl, { struct neigh_parms *p; - for (p = &tbl->parms; p; p = p->next) { + list_for_each_entry(p, &tbl->parms_list, list) { if ((p->dev && p->dev->ifindex == ifindex && net_eq(neigh_parms_net(p), net)) || (!p->dev && !ifindex && net_eq(net, &init_net))) return p; @@ -1481,8 +1481,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, } write_lock_bh(&tbl->lock); - p->next = tbl->parms.next; - tbl->parms.next = p; + list_add(&p->list, &tbl->parms.list); write_unlock_bh(&tbl->lock); neigh_parms_data_state_cleanall(p); @@ -1501,24 +1500,15 @@ static void neigh_rcu_free_parms(struct rcu_head *head) void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) { - struct neigh_parms **p; - if (!parms || parms == &tbl->parms) return; write_lock_bh(&tbl->lock); - for (p = &tbl->parms.next; *p; p = &(*p)->next) { - if (*p == parms) { - *p = parms->next; - parms->dead = 1; - write_unlock_bh(&tbl->lock); - if (parms->dev) - dev_put(parms->dev); - call_rcu(&parms->rcu_head, neigh_rcu_free_parms); - return; - } - } + list_del(&parms->list); + parms->dead = 1; write_unlock_bh(&tbl->lock); - neigh_dbg(1, "%s: not found\n", __func__); + if (parms->dev) + dev_put(parms->dev); + call_rcu(&parms->rcu_head, neigh_rcu_free_parms); } EXPORT_SYMBOL(neigh_parms_release); @@ -1535,6 +1525,8 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl) unsigned long now = jiffies; unsigned long phsize; + INIT_LIST_HEAD(&tbl->parms_list); + list_add(&tbl->parms.list, &tbl->parms_list); write_pnet(&tbl->parms.net, &init_net); atomic_set(&tbl->parms.refcnt, 1); tbl->parms.reachable_time = @@ -2154,7 +2146,9 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) NLM_F_MULTI) <= 0) break; - for (nidx = 0, p = tbl->parms.next; p; p = p->next) { + nidx = 0; + p = list_next_entry(&tbl->parms, list); + list_for_each_entry_from(p, &tbl->parms_list, list) { if (!net_eq(neigh_parms_net(p), net)) continue; -- GitLab From 67013f2c0e5811a4fd60c51e3233e1f027d1c1e0 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:43 +0000 Subject: [PATCH 2049/9457] staging: vt6655: mac80211 conversion add main mac80211 functions Replace existing vt6655_probe with one converted to mac80211 with the following operations vnt_tx_80211 vnt_start vnt_stop vnt_add_interface vnt_remove_interface vnt_config vnt_bss_info_changed vnt_prepare_multicast vnt_configure vnt_set_key vnt_get_tsf vnt_set_tsf vnt_reset_tsf The following variables are also added. basic_rates mc_list_count mac_hw Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 3 + drivers/staging/vt6655/device_main.c | 754 ++++++++++++++++++++++----- 2 files changed, 621 insertions(+), 136 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 7d521c63a55f..17a36dc4eda1 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -324,7 +324,10 @@ struct vnt_private { struct ieee80211_hw *hw; struct ieee80211_vif *vif; unsigned long key_entry_inuse; + u32 basic_rates; u16 current_aid; + int mc_list_count; + u8 mac_hw; /* netdev */ struct net_device *dev; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 84a35d7d01e8..23d934400783 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -809,142 +809,6 @@ static const struct net_device_ops device_netdev_ops = { .ndo_set_rx_mode = device_set_multi, }; -static int -vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) -{ - static bool bFirst = true; - struct net_device *dev = NULL; - PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; - struct vnt_private *pDevice; - int rc; - - dev = alloc_etherdev(sizeof(*pDevice)); - - pDevice = netdev_priv(dev); - - if (dev == NULL) { - pr_err(DEVICE_NAME ": allocate net device failed\n"); - return -ENOMEM; - } - - // Chain it all together - SET_NETDEV_DEV(dev, &pcid->dev); - - if (bFirst) { - pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); - pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); - bFirst = false; - } - - vt6655_init_info(pcid, &pDevice, pChip_info); - pDevice->dev = dev; - - if (pci_enable_device(pcid)) { - device_free_info(pDevice); - return -ENODEV; - } - dev->irq = pcid->irq; - -#ifdef DEBUG - pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr); -#endif - if (!device_get_pci_info(pDevice, pcid)) { - pr_err(DEVICE_NAME ": Failed to find PCI device.\n"); - device_free_info(pDevice); - return -ENODEV; - } - -#ifdef DEBUG - - pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size); - { - int i; - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0}; - for (i = 0; address[i]; i++) { - pci_read_config_dword(pcid, address[i], &bar); - pr_debug("bar %d is %x\n", i, bar); - if (!bar) { - pr_debug("bar %d not implemented\n", i); - continue; - } - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - - len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - pr_debug("IO space: len in IO %x, BAR %d\n", len, i); - } else { - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - pr_debug("len in MEM %x, BAR %d\n", len, i); - } - } - } -#endif - - pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size); - - if (pDevice->PortOffset == NULL) { - pr_err(DEVICE_NAME ": Failed to IO remapping ..\n"); - device_free_info(pDevice); - return -ENODEV; - } - - rc = pci_request_regions(pcid, DEVICE_NAME); - if (rc) { - pr_err(DEVICE_NAME ": Failed to find PCI device\n"); - device_free_info(pDevice); - return -ENODEV; - } - - dev->base_addr = pDevice->ioaddr; - // do reset - if (!MACbSoftwareReset(pDevice->PortOffset)) { - pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n"); - device_free_info(pDevice); - return -ENODEV; - } - // initial to reload eeprom - MACvInitialize(pDevice->PortOffset); - MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr); - - device_get_options(pDevice); - device_set_options(pDevice); - //Mask out the options cannot be set to the chip - pDevice->sOpts.flags &= pChip_info->flags; - - //Enable the chip specified capabilities - pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); - pDevice->tx_80211 = device_dma0_tx_80211; - pDevice->sMgmtObj.pAdapter = (void *)pDevice; - pDevice->pMgmt = &(pDevice->sMgmtObj); - - dev->irq = pcid->irq; - dev->netdev_ops = &device_netdev_ops; - - dev->wireless_handlers = &iwctl_handler_def; - - rc = register_netdev(dev); - if (rc) { - pr_err(DEVICE_NAME " Failed to register netdev\n"); - device_free_info(pDevice); - return -ENODEV; - } - device_print_info(pDevice); - pci_set_drvdata(pcid, pDevice); - return 0; -} - static void device_print_info(struct vnt_private *pDevice) { struct net_device *dev = pDevice->dev; @@ -2996,6 +2860,624 @@ static int ethtool_ioctl(struct net_device *dev, void __user *useraddr) return -EOPNOTSUPP; } +static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + PSTxDesc head_td; + u32 dma_idx = TYPE_AC0DMA; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + if (!ieee80211_is_data(hdr->frame_control)) + dma_idx = TYPE_TXDMA0; + + if (AVAIL_TD(priv, dma_idx) < 1) { + spin_unlock_irqrestore(&priv->lock, flags); + return -ENOMEM; + } + + head_td = priv->apCurrTD[dma_idx]; + + head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); + + head_td->pTDInfo->skb = skb; + + priv->iTDUsed[dma_idx]++; + + /* Take ownership */ + wmb(); + head_td->m_td0TD0.f1Owner = OWNED_BY_NIC; + + /* get Next */ + wmb(); + priv->apCurrTD[dma_idx] = head_td->next; + + spin_unlock_irqrestore(&priv->lock, flags); + + vnt_generate_fifo_header(priv, dma_idx, head_td, skb); + + if (MACbIsRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) + MACbPSWakeup(priv->PortOffset); + + spin_lock_irqsave(&priv->lock, flags); + + priv->bPWBitOn = false; + + head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; + + if (dma_idx == TYPE_AC0DMA) + MACvTransmitAC0(priv->PortOffset); + else + MACvTransmit0(priv->PortOffset); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static void vnt_tx_80211(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct vnt_private *priv = hw->priv; + + ieee80211_stop_queues(hw); + + if (vnt_tx_packet(priv, skb)) { + ieee80211_free_txskb(hw, skb); + + ieee80211_wake_queues(hw); + } +} + +static int vnt_start(struct ieee80211_hw *hw) +{ + struct vnt_private *priv = hw->priv; + int ret; + + priv->rx_buf_sz = PKT_BUF_SZ; + if (!device_init_rings(priv)) + return -ENOMEM; + + ret = request_irq(priv->pcid->irq, &device_intr, + IRQF_SHARED, "vt6655", priv); + if (ret) { + dev_dbg(&priv->pcid->dev, "failed to start irq\n"); + return ret; + } + + dev_dbg(&priv->pcid->dev, "call device init rd0 ring\n"); + device_init_rd0_ring(priv); + device_init_rd1_ring(priv); + device_init_defrag_cb(priv); + device_init_td0_ring(priv); + device_init_td1_ring(priv); + + device_init_registers(priv); + + dev_dbg(&priv->pcid->dev, "call MACvIntEnable\n"); + MACvIntEnable(priv->PortOffset, IMR_MASK_VALUE); + + ieee80211_wake_queues(hw); + + return 0; +} + +static void vnt_stop(struct ieee80211_hw *hw) +{ + struct vnt_private *priv = hw->priv; + + ieee80211_stop_queues(hw); + + MACbShutdown(priv->PortOffset); + MACbSoftwareReset(priv->PortOffset); + CARDbRadioPowerOff(priv); + + device_free_td0_ring(priv); + device_free_td1_ring(priv); + device_free_rd0_ring(priv); + device_free_rd1_ring(priv); + device_free_frag_buf(priv); + device_free_rings(priv); + + free_irq(priv->pcid->irq, priv); +} + +static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + + priv->vif = vif; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (priv->bDiversityRegCtlON) + device_init_diversity_timer(priv); + break; + case NL80211_IFTYPE_ADHOC: + MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST); + + MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); + + break; + case NL80211_IFTYPE_AP: + MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST); + + MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); + + break; + default: + return -EOPNOTSUPP; + } + + priv->op_mode = vif->type; + + return 0; +} + +static void vnt_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + if (priv->bDiversityRegCtlON) { + del_timer(&priv->TimerSQ3Tmax1); + del_timer(&priv->TimerSQ3Tmax2); + del_timer(&priv->TimerSQ3Tmax3); + } + break; + case NL80211_IFTYPE_ADHOC: + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOff(priv->PortOffset, + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); + break; + case NL80211_IFTYPE_AP: + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOff(priv->PortOffset, + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); + MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); + break; + default: + break; + } + + priv->op_mode = NL80211_IFTYPE_UNSPECIFIED; +} + + +static int vnt_config(struct ieee80211_hw *hw, u32 changed) +{ + struct vnt_private *priv = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + u8 bb_type; + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) + PSvEnablePowerSaving(priv, conf->listen_interval); + else + PSvDisablePowerSaving(priv); + } + + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || + (conf->flags & IEEE80211_CONF_OFFCHANNEL)) { + set_channel(priv, conf->chandef.chan->hw_value); + + if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ) + bb_type = BB_TYPE_11A; + else + bb_type = BB_TYPE_11G; + + if (priv->byBBType != bb_type) { + priv->byBBType = bb_type; + + CARDbSetPhyParameter(priv, + priv->byBBType, 0, 0, NULL, NULL); + } + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + if (priv->byBBType == BB_TYPE_11B) + priv->wCurrentRate = RATE_1M; + else + priv->wCurrentRate = RATE_54M; + + RFbSetPower(priv, priv->wCurrentRate, + conf->chandef.chan->hw_value); + } + + return 0; +} + +static void vnt_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf, + u32 changed) +{ + struct vnt_private *priv = hw->priv; + + priv->current_aid = conf->aid; + + if (changed & BSS_CHANGED_BSSID) + MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid); + + if (changed & BSS_CHANGED_BASIC_RATES) { + priv->basic_rates = conf->basic_rates; + + CARDvUpdateBasicTopRate(priv); + + dev_dbg(&priv->pcid->dev, + "basic rates %x\n", conf->basic_rates); + } + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + if (conf->use_short_preamble) { + MACvEnableBarkerPreambleMd(priv->PortOffset); + priv->byPreambleType = true; + } else { + MACvDisableBarkerPreambleMd(priv->PortOffset); + priv->byPreambleType = false; + } + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + if (conf->use_cts_prot) + MACvEnableProtectMD(priv->PortOffset); + else + MACvDisableProtectMD(priv->PortOffset); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + if (conf->use_short_slot) + priv->bShortSlotTime = true; + else + priv->bShortSlotTime = false; + + vUpdateIFS(priv); + CARDbSetPhyParameter(priv, priv->byBBType, 0, 0, NULL, NULL); + BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]); + } + + if (changed & BSS_CHANGED_TXPOWER) + RFbSetPower(priv, priv->wCurrentRate, + conf->chandef.chan->hw_value); + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + dev_dbg(&priv->pcid->dev, + "Beacon enable %d\n", conf->enable_beacon); + + if (conf->enable_beacon) { + vnt_beacon_enable(priv, vif, conf); + + MACvRegBitsOn(priv, MAC_REG_TCR, TCR_AUTOBCNTX); + } else { + MACvRegBitsOff(priv, MAC_REG_TCR, TCR_AUTOBCNTX); + } + } + + if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) { + if (conf->assoc) { + CARDbUpdateTSF(priv, conf->beacon_rate->hw_value, + conf->sync_device_ts, conf->sync_tsf); + + CARDbSetBeaconPeriod(priv, conf->beacon_int); + + CARDvSetFirstNextTBTT(priv->PortOffset, + conf->beacon_int); + } + } +} + +static u64 vnt_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + struct vnt_private *priv = hw->priv; + struct netdev_hw_addr *ha; + u64 mc_filter = 0; + u32 bit_nr = 0; + + netdev_hw_addr_list_for_each(ha, mc_list) { + bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + + mc_filter |= 1ULL << (bit_nr & 0x3f); + } + + priv->mc_list_count = mc_list->count; + + return mc_filter; +} + +static void vnt_configure(struct ieee80211_hw *hw, + unsigned int changed_flags, unsigned int *total_flags, u64 multicast) +{ + struct vnt_private *priv = hw->priv; + u8 rx_mode = 0; + + *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS | + FIF_BCN_PRBRESP_PROMISC; + + VNSvInPortB(priv->PortOffset + MAC_REG_RCR, &rx_mode); + + dev_dbg(&priv->pcid->dev, "rx mode in = %x\n", rx_mode); + + if (changed_flags & FIF_PROMISC_IN_BSS) { + /* unconditionally log net taps */ + if (*total_flags & FIF_PROMISC_IN_BSS) + rx_mode |= RCR_UNICAST; + else + rx_mode &= ~RCR_UNICAST; + } + + if (changed_flags & FIF_ALLMULTI) { + if (*total_flags & FIF_ALLMULTI) { + if (priv->mc_list_count > 2) { + MACvSelectPage1(priv->PortOffset); + + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0, 0xffffffff); + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0 + 4, 0xffffffff); + + MACvSelectPage0(priv->PortOffset); + } else { + MACvSelectPage1(priv->PortOffset); + + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0, (u32)multicast); + VNSvOutPortD(priv->PortOffset + + MAC_REG_MAR0 + 4, + (u32)(multicast >> 32)); + + MACvSelectPage0(priv->PortOffset); + } + + rx_mode |= RCR_MULTICAST | RCR_BROADCAST; + } else { + rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST); + } + } + + if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) { + rx_mode |= RCR_MULTICAST | RCR_BROADCAST; + + if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) + rx_mode &= ~RCR_BSSID; + else + rx_mode |= RCR_BSSID; + } + + VNSvOutPortB(priv->PortOffset + MAC_REG_RCR, rx_mode); + + dev_dbg(&priv->pcid->dev, "rx mode out= %x\n", rx_mode); +} + +static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct vnt_private *priv = hw->priv; + + switch (cmd) { + case SET_KEY: + if (vnt_set_keys(hw, sta, vif, key)) + return -EOPNOTSUPP; + break; + case DISABLE_KEY: + if (test_bit(key->hw_key_idx, &priv->key_entry_inuse)) + clear_bit(key->hw_key_idx, &priv->key_entry_inuse); + default: + break; + } + + return 0; +} + +static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + u64 tsf; + + CARDbGetCurrentTSF(priv->PortOffset, &tsf); + + return tsf; +} + +static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 tsf) +{ + struct vnt_private *priv = hw->priv; + + CARDvUpdateNextTBTT(priv->PortOffset, tsf, vif->bss_conf.beacon_int); +} + +static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct vnt_private *priv = hw->priv; + + /* reset TSF counter */ + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); +} + +static const struct ieee80211_ops vnt_mac_ops = { + .tx = vnt_tx_80211, + .start = vnt_start, + .stop = vnt_stop, + .add_interface = vnt_add_interface, + .remove_interface = vnt_remove_interface, + .config = vnt_config, + .bss_info_changed = vnt_bss_info_changed, + .prepare_multicast = vnt_prepare_multicast, + .configure_filter = vnt_configure, + .set_key = vnt_set_key, + .get_tsf = vnt_get_tsf, + .set_tsf = vnt_set_tsf, + .reset_tsf = vnt_reset_tsf, +}; + +int vnt_init(struct vnt_private *priv) +{ + SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr); + + if (ieee80211_register_hw(priv->hw)) + return -ENODEV; + + priv->mac_hw = true; + + CARDbRadioPowerOff(priv); + + return 0; +} + +static int +vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) +{ + PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data; + struct vnt_private *priv; + struct ieee80211_hw *hw; + struct wiphy *wiphy; + int rc; + + dev_notice(&pcid->dev, + "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION); + + dev_notice(&pcid->dev, + "Copyright (c) 2003 VIA Networking Technologies, Inc.\n"); + + hw = ieee80211_alloc_hw(sizeof(*priv), &vnt_mac_ops); + if (!hw) { + dev_err(&pcid->dev, "could not register ieee80211_hw\n"); + return -ENOMEM; + } + + priv = hw->priv; + + vt6655_init_info(pcid, &priv, pChip_info); + + priv->hw = hw; + + SET_IEEE80211_DEV(priv->hw, &pcid->dev); + + if (pci_enable_device(pcid)) { + device_free_info(priv); + return -ENODEV; + } + + dev_dbg(&pcid->dev, + "Before get pci_info memaddr is %x\n", priv->memaddr); + + if (!device_get_pci_info(priv, pcid)) { + dev_err(&pcid->dev, ": Failed to find PCI device.\n"); + device_free_info(priv); + return -ENODEV; + } + +#ifdef DEBUG + dev_dbg(&pcid->dev, + "after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", + priv->memaddr, priv->ioaddr, priv->io_size); + { + int i; + u32 bar, len; + u32 address[] = { + PCI_BASE_ADDRESS_0, + PCI_BASE_ADDRESS_1, + PCI_BASE_ADDRESS_2, + PCI_BASE_ADDRESS_3, + PCI_BASE_ADDRESS_4, + PCI_BASE_ADDRESS_5, + 0}; + for (i = 0; address[i]; i++) { + pci_read_config_dword(pcid, address[i], &bar); + + dev_dbg(&pcid->dev, "bar %d is %x\n", i, bar); + + if (!bar) { + dev_dbg(&pcid->dev, + "bar %d not implemented\n", i); + continue; + } + + if (bar & PCI_BASE_ADDRESS_SPACE_IO) { + /* This is IO */ + + len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xffff); + len = len & ~(len - 1); + + dev_dbg(&pcid->dev, + "IO space: len in IO %x, BAR %d\n", + len, i); + } else { + len = bar & 0xfffffff0; + len = ~len + 1; + + dev_dbg(&pcid->dev, + "len in MEM %x, BAR %d\n", len, i); + } + } + } +#endif + + priv->PortOffset = ioremap(priv->memaddr & PCI_BASE_ADDRESS_MEM_MASK, + priv->io_size); + if (!priv->PortOffset) { + dev_err(&pcid->dev, ": Failed to IO remapping ..\n"); + device_free_info(priv); + return -ENODEV; + } + + rc = pci_request_regions(pcid, DEVICE_NAME); + if (rc) { + dev_err(&pcid->dev, ": Failed to find PCI device\n"); + device_free_info(priv); + return -ENODEV; + } + + /* do reset */ + if (!MACbSoftwareReset(priv->PortOffset)) { + dev_err(&pcid->dev, ": Failed to access MAC hardware..\n"); + device_free_info(priv); + return -ENODEV; + } + /* initial to reload eeprom */ + MACvInitialize(priv->PortOffset); + MACvReadEtherAddress(priv->PortOffset, priv->abyCurrentNetAddr); + + device_get_options(priv); + device_set_options(priv); + /* Mask out the options cannot be set to the chip */ + priv->sOpts.flags &= pChip_info->flags; + + /* Enable the chip specified capabilities */ + priv->flags = priv->sOpts.flags | (pChip_info->flags & 0xff000000UL); + priv->tx_80211 = device_dma0_tx_80211; + priv->sMgmtObj.pAdapter = (void *)priv; + priv->pMgmt = &(priv->sMgmtObj); + + wiphy = priv->hw->wiphy; + + wiphy->frag_threshold = FRAG_THRESH_DEF; + wiphy->rts_threshold = RTS_THRESH_DEF; + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); + + priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_TIMING_BEACON_ONLY; + + priv->hw->max_signal = 100; + + if (vnt_init(priv)) + return -ENODEV; + + device_print_info(priv); + pci_set_drvdata(pcid, priv); + + return 0; +} + /*------------------------------------------------------------------*/ MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table); -- GitLab From 3d75b9e235e4cd99cbf44e3d5084c6066299e53d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:44 +0000 Subject: [PATCH 2050/9457] staging: vt6655: mac80211 conversion add channel bands Add rates and channels according to rf type for vnt_init_bands which is a mac80211 replacement for init_channel_table. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 140 +++++++++++++++++++++++++++ drivers/staging/vt6655/channel.h | 2 + drivers/staging/vt6655/device_main.c | 2 + 3 files changed, 144 insertions(+) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index a19965fbcc97..4b3c798ff444 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -352,6 +352,146 @@ static struct /*--------------------- Export Functions --------------------------*/ +static struct ieee80211_rate vnt_rates_bg[] = { + { .bitrate = 10, .hw_value = RATE_1M }, + { .bitrate = 20, .hw_value = RATE_2M }, + { .bitrate = 55, .hw_value = RATE_5M }, + { .bitrate = 110, .hw_value = RATE_11M }, + { .bitrate = 60, .hw_value = RATE_6M }, + { .bitrate = 90, .hw_value = RATE_9M }, + { .bitrate = 120, .hw_value = RATE_12M }, + { .bitrate = 180, .hw_value = RATE_18M }, + { .bitrate = 240, .hw_value = RATE_24M }, + { .bitrate = 360, .hw_value = RATE_36M }, + { .bitrate = 480, .hw_value = RATE_48M }, + { .bitrate = 540, .hw_value = RATE_54M }, +}; + +static struct ieee80211_rate vnt_rates_a[] = { + { .bitrate = 60, .hw_value = RATE_6M }, + { .bitrate = 90, .hw_value = RATE_9M }, + { .bitrate = 120, .hw_value = RATE_12M }, + { .bitrate = 180, .hw_value = RATE_18M }, + { .bitrate = 240, .hw_value = RATE_24M }, + { .bitrate = 360, .hw_value = RATE_36M }, + { .bitrate = 480, .hw_value = RATE_48M }, + { .bitrate = 540, .hw_value = RATE_54M }, +}; + +static struct ieee80211_channel vnt_channels_2ghz[] = { + { .center_freq = 2412, .hw_value = 1 }, + { .center_freq = 2417, .hw_value = 2 }, + { .center_freq = 2422, .hw_value = 3 }, + { .center_freq = 2427, .hw_value = 4 }, + { .center_freq = 2432, .hw_value = 5 }, + { .center_freq = 2437, .hw_value = 6 }, + { .center_freq = 2442, .hw_value = 7 }, + { .center_freq = 2447, .hw_value = 8 }, + { .center_freq = 2452, .hw_value = 9 }, + { .center_freq = 2457, .hw_value = 10 }, + { .center_freq = 2462, .hw_value = 11 }, + { .center_freq = 2467, .hw_value = 12 }, + { .center_freq = 2472, .hw_value = 13 }, + { .center_freq = 2484, .hw_value = 14 } +}; + +static struct ieee80211_channel vnt_channels_5ghz[] = { + { .center_freq = 4915, .hw_value = 15 }, + { .center_freq = 4920, .hw_value = 16 }, + { .center_freq = 4925, .hw_value = 17 }, + { .center_freq = 4935, .hw_value = 18 }, + { .center_freq = 4940, .hw_value = 19 }, + { .center_freq = 4945, .hw_value = 20 }, + { .center_freq = 4960, .hw_value = 21 }, + { .center_freq = 4980, .hw_value = 22 }, + { .center_freq = 5035, .hw_value = 23 }, + { .center_freq = 5040, .hw_value = 24 }, + { .center_freq = 5045, .hw_value = 25 }, + { .center_freq = 5055, .hw_value = 26 }, + { .center_freq = 5060, .hw_value = 27 }, + { .center_freq = 5080, .hw_value = 28 }, + { .center_freq = 5170, .hw_value = 29 }, + { .center_freq = 5180, .hw_value = 30 }, + { .center_freq = 5190, .hw_value = 31 }, + { .center_freq = 5200, .hw_value = 32 }, + { .center_freq = 5210, .hw_value = 33 }, + { .center_freq = 5220, .hw_value = 34 }, + { .center_freq = 5230, .hw_value = 35 }, + { .center_freq = 5240, .hw_value = 36 }, + { .center_freq = 5260, .hw_value = 37 }, + { .center_freq = 5280, .hw_value = 38 }, + { .center_freq = 5300, .hw_value = 39 }, + { .center_freq = 5320, .hw_value = 40 }, + { .center_freq = 5500, .hw_value = 41 }, + { .center_freq = 5520, .hw_value = 42 }, + { .center_freq = 5540, .hw_value = 43 }, + { .center_freq = 5560, .hw_value = 44 }, + { .center_freq = 5580, .hw_value = 45 }, + { .center_freq = 5600, .hw_value = 46 }, + { .center_freq = 5620, .hw_value = 47 }, + { .center_freq = 5640, .hw_value = 48 }, + { .center_freq = 5660, .hw_value = 49 }, + { .center_freq = 5680, .hw_value = 50 }, + { .center_freq = 5700, .hw_value = 51 }, + { .center_freq = 5745, .hw_value = 52 }, + { .center_freq = 5765, .hw_value = 53 }, + { .center_freq = 5785, .hw_value = 54 }, + { .center_freq = 5805, .hw_value = 55 }, + { .center_freq = 5825, .hw_value = 56 } +}; + +static struct ieee80211_supported_band vnt_supported_2ghz_band = { + .channels = vnt_channels_2ghz, + .n_channels = ARRAY_SIZE(vnt_channels_2ghz), + .bitrates = vnt_rates_bg, + .n_bitrates = ARRAY_SIZE(vnt_rates_bg), +}; + +static struct ieee80211_supported_band vnt_supported_5ghz_band = { + .channels = vnt_channels_5ghz, + .n_channels = ARRAY_SIZE(vnt_channels_5ghz), + .bitrates = vnt_rates_a, + .n_bitrates = ARRAY_SIZE(vnt_rates_a), +}; + +void vnt_init_bands(struct vnt_private *priv) +{ + struct ieee80211_channel *ch; + int i; + + switch (priv->byRFType) { + case RF_AIROHA7230: + case RF_UW2452: + case RF_NOTHING: + default: + ch = vnt_channels_5ghz; + + for (i = 0; i < ARRAY_SIZE(vnt_channels_5ghz); i++) { + ch[i].max_power = 0x3f; + ch[i].flags = IEEE80211_CHAN_NO_HT40; + } + + priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &vnt_supported_5ghz_band; + /* fallthrough */ + case RF_RFMD2959: + case RF_AIROHA: + case RF_AL2230S: + case RF_UW2451: + case RF_VT3226: + ch = vnt_channels_2ghz; + + for (i = 0; i < ARRAY_SIZE(vnt_channels_2ghz); i++) { + ch[i].max_power = 0x3f; + ch[i].flags = IEEE80211_CHAN_NO_HT40; + } + + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &vnt_supported_2ghz_band; + break; + } +} + /** * is_channel_valid() - Is Country Channel Valid * @ChanneIndex: defined as VT3253 MAC channel: diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 4f44c8a3d3cf..0d3e1f121759 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -33,6 +33,8 @@ typedef struct tagSChannelTblElement { unsigned char byMAP; } SChannelTblElement, *PSChannelTblElement; +void vnt_init_bands(struct vnt_private *); + bool is_channel_valid(unsigned int CountryCode); void init_channel_table(void *pDeviceHandler); unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 23d934400783..054841b0663a 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3320,6 +3320,8 @@ int vnt_init(struct vnt_private *priv) { SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr); + vnt_init_bands(priv); + if (ieee80211_register_hw(priv->hw)) return -ENODEV; -- GitLab From 000fe0f53433a4dea2738c3cb34e19d2ef952092 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:45 +0000 Subject: [PATCH 2051/9457] staging: vt6655: mac80211 conversion replace suspend resume functions add vt6655_suspend and vt6655_resume remove viawget_suspend and viawget_resume. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 104 +++++++++------------------ 1 file changed, 34 insertions(+), 70 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 054841b0663a..b0f94a804ceb 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -274,8 +274,6 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef CONFIG_PM static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); -static int viawget_suspend(struct pci_dev *pcid, pm_message_t state); -static int viawget_resume(struct pci_dev *pcid); static struct notifier_block device_notifier = { .notifier_call = device_notify_reboot, .next = NULL, @@ -3482,6 +3480,37 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) /*------------------------------------------------------------------*/ +#ifdef CONFIG_PM +static int vt6655_suspend(struct pci_dev *pcid, pm_message_t state) +{ + struct vnt_private *priv = pci_get_drvdata(pcid); + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + pci_save_state(pcid); + + MACbShutdown(priv->PortOffset); + + pci_disable_device(pcid); + pci_set_power_state(pcid, pci_choose_state(pcid, state)); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static int vt6655_resume(struct pci_dev *pcid) +{ + + pci_set_power_state(pcid, PCI_D0); + pci_enable_wake(pcid, PCI_D0, 0); + pci_restore_state(pcid); + + return 0; +} +#endif + MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table); static struct pci_driver device_driver = { @@ -3490,8 +3519,8 @@ static struct pci_driver device_driver = { .probe = vt6655_probe, .remove = vt6655_remove, #ifdef CONFIG_PM - .suspend = viawget_suspend, - .resume = viawget_resume, + .suspend = vt6655_suspend, + .resume = vt6655_resume, #endif }; @@ -3532,75 +3561,10 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) for_each_pci_dev(pdev) { if (pci_dev_driver(pdev) == &device_driver) { if (pci_get_drvdata(pdev)) - viawget_suspend(pdev, PMSG_HIBERNATE); + vt6655_suspend(pdev, PMSG_HIBERNATE); } } } return NOTIFY_DONE; } - -static int -viawget_suspend(struct pci_dev *pcid, pm_message_t state) -{ - int power_status; // to silence the compiler - - struct vnt_private *pDevice = pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - pci_save_state(pcid); - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pci_disable_device(pcid); - power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); - spin_unlock_irq(&pDevice->lock); - return 0; -} - -static int -viawget_resume(struct pci_dev *pcid) -{ - struct vnt_private *pDevice = pci_get_drvdata(pcid); - PSMgmtObject pMgmt = pDevice->pMgmt; - int power_status; // to silence the compiler - - power_status = pci_set_power_state(pcid, PCI_D0); - power_status = pci_enable_wake(pcid, PCI_D0, 0); - pci_restore_state(pcid); - if (netif_running(pDevice->dev)) { - spin_lock_irq(&pDevice->lock); - MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext); - device_init_registers(pDevice); - if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS - pMgmt->sNodeDBTable[0].bActive = false; - pDevice->bLinkPass = false; - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // In Adhoc, BSS state set back to started. - pMgmt->eCurrState = WMAC_STATE_STARTED; - } else { - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - } - init_timer(&pMgmt->sTimerSecondCallback); - init_timer(&pDevice->sTimerCommand); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - return 0; -} - #endif -- GitLab From bc5d431c9b11f39c81dea25748e18014f3e210f4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:46 +0000 Subject: [PATCH 2052/9457] staging: vt6655: mac80211 conversion: device_print_info remove netdevice. use dev_info for device name and pcid->irq for irq number. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index b0f94a804ceb..5ece18401ed4 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -809,12 +809,11 @@ static const struct net_device_ops device_netdev_ops = { static void device_print_info(struct vnt_private *pDevice) { - struct net_device *dev = pDevice->dev; + dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id)); - pr_info("%s: %s\n", dev->name, get_chip_name(pDevice->chip_id)); - pr_info("%s: MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n", - dev->name, dev->dev_addr, (unsigned long)pDevice->ioaddr, - (unsigned long)pDevice->PortOffset, pDevice->dev->irq); + dev_info(&pDevice->pcid->dev, "MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n", + pDevice->abyCurrentNetAddr, (unsigned long)pDevice->ioaddr, + (unsigned long)pDevice->PortOffset, pDevice->pcid->irq); } static void vt6655_init_info(struct pci_dev *pcid, -- GitLab From e70abceb05a36665c3378619217c35acffb14ca4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:47 +0000 Subject: [PATCH 2053/9457] staging: vt6655: mac80211 conversion: changes to device_intr Remove net device code. Remove current measure code and function s_vCompleteCurrentMeasure and switch code which are now handled by mac80211 Change beaconing to mac80211. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 175 ++------------------------- 1 file changed, 8 insertions(+), 167 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 5ece18401ed4..69c98c2989c4 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -400,45 +400,6 @@ device_set_options(struct vnt_private *pDevice) (int)pDevice->bDiversityRegCtlON); } -static void s_vCompleteCurrentMeasure(struct vnt_private *pDevice, - unsigned char byResult) -{ - unsigned int ii; - unsigned long dwDuration = 0; - unsigned char byRPI0 = 0; - - for (ii = 1; ii < 8; ii++) { - pDevice->dwRPIs[ii] *= 255; - dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); - dwDuration <<= 10; - pDevice->dwRPIs[ii] /= dwDuration; - pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii]; - byRPI0 += pDevice->abyRPIs[ii]; - } - pDevice->abyRPIs[0] = (0xFF - byRPI0); - - if (pDevice->uNumOfMeasureEIDs == 0) { - VNTWIFIbMeasureReport(pDevice->pMgmt, - true, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - byResult, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs); - } -} - // // Initialisation of MAC & BBP registers // @@ -2056,14 +2017,11 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { static irqreturn_t device_intr(int irq, void *dev_instance) { - struct net_device *dev = dev_instance; - struct vnt_private *pDevice = netdev_priv(dev); + struct vnt_private *pDevice = dev_instance; int max_count = 0; unsigned long dwMIBCounter = 0; - PSMgmtObject pMgmt = pDevice->pMgmt; unsigned char byOrgPageSel = 0; int handled = 0; - unsigned char byData = 0; int ii = 0; unsigned long flags; @@ -2106,94 +2064,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) device_error(pDevice, pDevice->dwIsr); } - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - if (pDevice->dwIsr & ISR_MEASURESTART) { - // 802.11h measure start - pDevice->byOrgChannel = pDevice->byCurrentCh; - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR)); - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR)); - MACvSelectPage1(pDevice->PortOffset); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0)); - VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4)); - MACvSelectPage0(pDevice->PortOffset); - //xxxx - if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) { - pDevice->bMeasureInProgress = true; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byBasicMap = 0; - pDevice->byCCAFraction = 0; - for (ii = 0; ii < 8; ii++) - pDevice->dwRPIs[ii] = 0; - - } else { - // can not measure because set channel fail - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - } - if (pDevice->dwIsr & ISR_MEASUREEND) { - // 802.11h measure end - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData); - pDevice->byBasicMap |= (byData >> 4); - VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction); - VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData); - // clear measure control - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - if (byData & MSRCTL_FINISH) { - // measure success - s_vCompleteCurrentMeasure(pDevice, 0); - } else { - // can not measure because not ready before end of measure time - s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE); - } - } - if (pDevice->dwIsr & ISR_QUIETSTART) { - do { - ; - } while (!CARDbStartQuiet(pDevice)); - } - } - if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->bEnableFirstQuiet) { - pDevice->byQuietStartCount--; - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - MACvSelectPage0(pDevice->PortOffset); - } - } - if (pDevice->bChannelSwitch && - (pDevice->op_mode == NL80211_IFTYPE_STATION)) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - - } - } if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) { if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) { long ldBm; @@ -2234,10 +2105,11 @@ static irqreturn_t device_intr(int irq, void *dev_instance) if (pDevice->bEnablePSMode) PSbIsNextTBTTWakeUp((void *)pDevice); - if ((pDevice->op_mode == NL80211_IFTYPE_AP) || - (pDevice->op_mode == NL80211_IFTYPE_ADHOC)) { + if ((pDevice->op_mode == NL80211_IFTYPE_AP || + pDevice->op_mode == NL80211_IFTYPE_ADHOC) && + pDevice->vif->bss_conf.enable_beacon) { MACvOneShotTimer1MicroSec(pDevice->PortOffset, - (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10); + (pDevice->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10); } /* TODO: adhoc PS mode */ @@ -2250,34 +2122,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) pDevice->cbBeaconBufReadySetCnt = 0; } - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - if (pMgmt->byDTIMCount > 0) { - pMgmt->byDTIMCount--; - pMgmt->sNodeDBTable[0].bRxPSPoll = false; - } else { - if (pMgmt->byDTIMCount == 0) { - // check if mutltcast tx bufferring - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - } - } - } pDevice->bBeaconSent = true; - - if (pDevice->bChannelSwitch) { - pDevice->byChannelSwitchCount--; - if (pDevice->byChannelSwitchCount == 0) { - pDevice->bChannelSwitch = false; - set_channel(pDevice, pDevice->byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL); - } - } - } if (pDevice->dwIsr & ISR_RXDMA0) @@ -2293,14 +2138,10 @@ static irqreturn_t device_intr(int irq, void *dev_instance) max_count += device_tx_srv(pDevice, TYPE_AC0DMA); if (pDevice->dwIsr & ISR_SOFTTIMER1) { - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - if (pDevice->bShortSlotTime) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - else - pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)); + if (pDevice->vif) { + if (pDevice->vif->bss_conf.enable_beacon) + vnt_beacon_make(pDevice, pDevice->vif); } - bMgrPrepareBeaconToSend(pDevice, pMgmt); - pDevice->byCntMeasure = 0; } MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); -- GitLab From 59918beada362e47de3b7a7467573ab001528077 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:48 +0000 Subject: [PATCH 2054/9457] staging: vt6655: mac80211 conversion: device_tx_srv tx and add report rates vnt_int_report_rate reports backs tx rate and is replacment for STAvUpdateTDStatCounter and BSSvUpdateNodeTxCounter. Replacing existing code. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 166 ++++++++++++++------------- 1 file changed, 85 insertions(+), 81 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 69c98c2989c4..a888c268042d 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1208,19 +1208,84 @@ bool device_alloc_frag_buf(struct vnt_private *pDevice, return true; } +static const u8 fallback_rate0[5][5] = { + {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, + {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, + {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} +}; + +static const u8 fallback_rate1[5][5] = { + {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, + {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, + {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, + {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} +}; + +static int vnt_int_report_rate(struct vnt_private *priv, + PDEVICE_TD_INFO context, u8 tsr0, u8 tsr1) +{ + struct vnt_tx_fifo_head *fifo_head; + struct ieee80211_tx_info *info; + struct ieee80211_rate *rate; + u16 fb_option; + u8 tx_retry = (tsr0 & TSR0_NCR); + s8 idx; + + if (!context) + return -ENOMEM; + + if (!context->skb) + return -EINVAL; + + fifo_head = (struct vnt_tx_fifo_head *)context->buf; + fb_option = (le16_to_cpu(fifo_head->fifo_ctl) & + (FIFOCTL_AUTO_FB_0 | FIFOCTL_AUTO_FB_1)); + + info = IEEE80211_SKB_CB(context->skb); + idx = info->control.rates[0].idx; + + if (fb_option && !(tsr1 & TSR1_TERR)) { + u8 tx_rate; + u8 retry = tx_retry; + + rate = ieee80211_get_tx_rate(priv->hw, info); + tx_rate = rate->hw_value - RATE_18M; + + if (retry > 4) + retry = 4; + + if (fb_option & FIFOCTL_AUTO_FB_0) + tx_rate = fallback_rate0[tx_rate][retry]; + else if (fb_option & FIFOCTL_AUTO_FB_1) + tx_rate = fallback_rate1[tx_rate][retry]; + + if (info->band == IEEE80211_BAND_5GHZ) + idx = tx_rate - RATE_6M; + else + idx = tx_rate; + } + + ieee80211_tx_info_clear_status(info); + + info->status.rates[0].count = tx_retry; + + if (!(tsr1 & TSR1_TERR)) { + info->status.rates[0].idx = idx; + info->flags |= IEEE80211_TX_STAT_ACK; + } + + return 0; +} + static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) { PSTxDesc pTD; - bool bFull = false; int works = 0; unsigned char byTsr0; unsigned char byTsr1; - unsigned int uFrameSize, uFIFOHeaderSize; - PSTxBufHead pTxBufHead; - struct net_device_stats *pStats = &pDevice->dev->stats; - struct sk_buff *skb; - unsigned int uNodeIndex; - PSMgmtObject pMgmt = pDevice->pMgmt; for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) { if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC) @@ -1234,22 +1299,8 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) //Only the status of first TD in the chain is correct if (pTD->m_td1TD1.byTCR & TCR_STP) { if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) { - uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength; - uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize; - pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf); - // Update the statistics based on the Transmit status - // now, we DONT check TSR0_CDH - - STAvUpdateTDStatCounter(&pDevice->scStatistic, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize), - uFrameSize, uIdx); - - BSSvUpdateNodeTxCounter(pDevice, - byTsr0, byTsr1, - (unsigned char *)(pTD->pTDInfo->buf), - uFIFOHeaderSize - ); + + vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1); if (!(byTsr1 & TSR1_TERR)) { if (byTsr0 != 0) { @@ -1257,28 +1308,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) (int)uIdx, byTsr1, byTsr0); } - if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) - pDevice->s802_11Counter.TransmittedFragmentCount++; - - pStats->tx_packets++; - pStats->tx_bytes += pTD->pTDInfo->skb->len; } else { pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n", (int)uIdx, byTsr1, byTsr0); - pStats->tx_errors++; - pStats->tx_dropped++; - } - } - - if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { - if (pDevice->bEnableHostapd) { - pr_debug("tx call back netif..\n"); - skb = pTD->pTDInfo->skb; - skb->dev = pDevice->apdev; - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); } } @@ -1287,47 +1319,14 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n", (int)uIdx, byTsr1, byTsr0); } - - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && - (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) { - unsigned short wAID; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - - skb = pTD->pTDInfo->skb; - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB); - pr_debug("tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n", - (int)uNodeIndex, - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt); - pStats->tx_errors--; - pStats->tx_dropped--; - } - } - } } device_free_tx_buf(pDevice, pTD); pDevice->iTDUsed[uIdx]--; - } - } - - if (uIdx == TYPE_AC0DMA) { - // RESERV_AC0DMA reserved for relay - if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) { - bFull = true; - pr_debug(" AC0DMA is Full = %d\n", - pDevice->iTDUsed[uIdx]); + /* Make sure queue is available */ + if (AVAIL_TD(pDevice, uIdx)) + ieee80211_wake_queues(pDevice->hw); } - if (netif_queue_stopped(pDevice->dev) && !bFull) - netif_wake_queue(pDevice->dev); - } pDevice->apTailTD[uIdx] = pTD; @@ -1360,7 +1359,9 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) PCI_DMA_TODEVICE); } - if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) + if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) + ieee80211_tx_status_irqsafe(pDevice->hw, skb); + else dev_kfree_skb_irq(skb); pTDInfo->skb_dma = 0; @@ -2065,8 +2066,11 @@ static irqreturn_t device_intr(int irq, void *dev_instance) } if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) { - if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) { + if (pDevice->vif && + pDevice->op_mode != NL80211_IFTYPE_ADHOC) { + if (pDevice->bUpdateBBVGA && + pDevice->vif->bss_conf.assoc && + pDevice->uCurrRSSI) { long ldBm; RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm); -- GitLab From b956374239481f62014bfb27f7ecb0f804e5029b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:49 +0000 Subject: [PATCH 2055/9457] staging: vt6655: mac80211 conversion: changes to set channel Remove call to sChannelTbl, the channel under mac80211 is always valid. CARDbSetPhyParameter is nolonger set here. RFbSetPower is now set on byBBType Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 4b3c798ff444..237969673f2e 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -665,16 +665,6 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) if (pDevice->byCurrentCh == uConnectionChannel) return bResult; - if (!sChannelTbl[uConnectionChannel].bValid) - return false; - - if ((uConnectionChannel > CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType != PHY_TYPE_11A)) { - CARDbSetPhyParameter(pDevice, PHY_TYPE_11A, 0, 0, NULL, NULL); - } else if ((uConnectionChannel <= CB_MAX_CHANNEL_24G) && - (pDevice->eCurrentPHYType == PHY_TYPE_11A)) { - CARDbSetPhyParameter(pDevice, PHY_TYPE_11G, 0, 0, NULL, NULL); - } /* clear NAV */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); @@ -702,7 +692,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) MACvSelectPage0(pDevice->PortOffset); } - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) + if (pDevice->byBBType == BB_TYPE_11B) RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh); else RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh); -- GitLab From e99d357c6f87c8ab0c118150e533443be8e4988b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:50 +0000 Subject: [PATCH 2056/9457] staging: vt6655: mac80211 conversion: enable power saving Convert PSvEnablePowerSaving and PSvEnablePowerSaving Remove mgmt->wCurrAID and use pDevice->current_aid We nolonger send the PSbSendNullPacket. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/power.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 08241b917777..fe33bb2fd7ff 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -73,8 +73,7 @@ PSvEnablePowerSaving( ) { struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15; + u16 wAID = pDevice->current_aid | BIT(14) | BIT(15); // set period of power up before TBTT VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); @@ -83,7 +82,9 @@ PSvEnablePowerSaving( VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); } else { // set ATIM Window +#if 0 /* TODO atim window */ MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); +#endif } // Set AutoSleep MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); @@ -95,22 +96,15 @@ PSvEnablePowerSaving( MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); // first time set listen next beacon MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - pMgmt->wCountToWakeUp = wListenInterval; } else { // always listen beacon MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); - pMgmt->wCountToWakeUp = 0; } // enable power saving hw function MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); pDevice->bEnablePSMode = true; - /* We don't send null pkt in ad hoc mode since beacon will handle this. */ - if (pDevice->op_mode != NL80211_IFTYPE_ADHOC && - pDevice->op_mode == NL80211_IFTYPE_STATION) - PSbSendNullPacket(pDevice); - pDevice->bPWBitOn = true; pr_debug("PS:Power Saving Mode Enable...\n"); } @@ -143,9 +137,6 @@ PSvDisablePowerSaving( pDevice->bEnablePSMode = false; - if (pDevice->op_mode == NL80211_IFTYPE_STATION) - PSbSendNullPacket(pDevice); - pDevice->bPWBitOn = false; } -- GitLab From 0614a0e84d3f4c3c6180b8c5ec91bb40954015f3 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:51 +0000 Subject: [PATCH 2057/9457] staging: vt6655: mac80211 conversion: changes to CARDbSetPhyParameter CARDbSetPhyParameter appears to use two different strutures to find supported rates. Remove PWLAN_IE_SUPP_RATES and use basic_rates to find rates supported. mac80211 now sets bShortSlotTime, bBarkerPreambleMd and byPreambleType remove these. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 61 +++++++---------------------------- 1 file changed, 11 insertions(+), 50 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index eae67897a615..090c28618ec9 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -74,15 +74,6 @@ #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ -/* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M */ -static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; -/* 6M, 9M, 12M, 48M */ -static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; -/* 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M */ -static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; -/* 1M, 2M, 5M, 11M, */ -static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - /*--------------------- Static Variables --------------------------*/ static const unsigned short cwRXBCNTSFOff[MAX_RATE] = @@ -384,14 +375,10 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, unsigned char bySIFS = 0; unsigned char byDIFS = 0; unsigned char byData; - PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs; - PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs; + int i; /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ if (ePHYType == PHY_TYPE_11A) { - if (pSupportRates == NULL) - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA; - if (pDevice->byRFType == RF_AIROHA7230) { /* AL7230 use single PAPE and connect to PAPE_2.4G */ MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); @@ -419,9 +406,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; byCWMaxMin = 0xA4; } else if (ePHYType == PHY_TYPE_11B) { - if (pSupportRates == NULL) - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB; - MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B); if (pDevice->byRFType == RF_AIROHA7230) { pDevice->abyBBVGA[0] = 0x1C; @@ -445,10 +429,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; byCWMaxMin = 0xA5; } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ - if (pSupportRates == NULL) { - pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG; - pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG; - } MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G); if (pDevice->byRFType == RF_AIROHA7230) { pDevice->abyBBVGA[0] = 0x1C; @@ -468,32 +448,22 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, } BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); bySIFS = C_SIFS_BG; - if (VNTWIFIbIsShortSlotTime(wCapInfo)) { + + if (pDevice->bShortSlotTime) { bySlot = C_SLOT_SHORT; byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT; } else { bySlot = C_SLOT_LONG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; } - if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) - byCWMaxMin = 0xA4; - else - byCWMaxMin = 0xA5; - if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) { - pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField); - if (pDevice->bProtectMode) - MACvEnableProtectMD(pDevice->PortOffset); - else - MACvDisableProtectMD(pDevice->PortOffset); + byCWMaxMin = 0xa4; - } - if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) { - pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField); - if (pDevice->bBarkerPreambleMd) - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - else - MACvDisableBarkerPreambleMd(pDevice->PortOffset); + for (i = RATE_54M; i >= RATE_6M; i--) { + if (pDevice->basic_rates & ((u32)(0x1 << i))) { + byCWMaxMin |= 0x1; + break; + } } } @@ -526,10 +496,6 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, if (pDevice->bySlot != bySlot) { pDevice->bySlot = bySlot; VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot); - if (pDevice->bySlot == C_SLOT_SHORT) - pDevice->bShortSlotTime = true; - else - pDevice->bShortSlotTime = false; BBvSetShortSlotTime(pDevice); } @@ -537,14 +503,9 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->byCWMaxMin = byCWMaxMin; VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); } - if (VNTWIFIbIsShortPreamble(wCapInfo)) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = 0; - s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates); - pDevice->eCurrentPHYType = ePHYType; - /* set for NDIS OID_802_11SUPPORTED_RATES */ + s_vSetRSPINF(pDevice, ePHYType, NULL, NULL); + return true; } -- GitLab From c01ef29e38362518e269e35c3bce090a3d60fa5b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:52 +0000 Subject: [PATCH 2058/9457] staging: vt6655: mac80211 conversion: card.c use basic_rates Use basic_rates to find cck and ofdm rates. wBasicRate will be removed later. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 090c28618ec9..a1330bce63ff 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1457,7 +1457,7 @@ static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, unsigned int ui = (unsigned int) wRateIdx; while (ui > RATE_1M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) + if (pDevice->basic_rates & ((u32)0x1 << ui)) return (unsigned short)ui; ui--; @@ -1482,7 +1482,7 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, { unsigned int ui = (unsigned int) wRateIdx; - pr_debug("BASIC RATE: %X\n", pDevice->wBasicRate); + pr_debug("BASIC RATE: %X\n", pDevice->basic_rates); if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); @@ -1491,7 +1491,7 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, return wRateIdx; } while (ui > RATE_11M) { - if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { + if (pDevice->basic_rates & ((u32)0x1 << ui)) { pr_debug("CARDwGetOFDMControlRate : %d\n", ui); return (unsigned short)ui; } -- GitLab From 3fbbb75f55ffeb0d37dd27c55ea88f6d9514dac4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:53 +0000 Subject: [PATCH 2059/9457] staging: vt6655: CARDbSetPhyParameter replace s_vSetRSPINF with CARDvSetRSPINF Removing s_vSetRSPINF Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 120 +--------------------------------- 1 file changed, 1 insertion(+), 119 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index a1330bce63ff..72896c1b842d 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -198,124 +198,6 @@ s_vCalculateOFDMRParameter( } } -/* - * Description: Set RSPINF - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: None. - */ -static -void -s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, - void *pvSupportRateIEs, void *pvExtSupportRateIEs) -{ - union vnt_phy_field_swap phy; - unsigned char byTxRate = 0, byRsvTime = 0; /* For OFDM */ - - /* Set to Page1 */ - MACvSelectPage1(pDevice->PortOffset); - - /* RSPINF_b_1 */ - vnt_get_phy_field(pDevice, - 14, - VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, - &phy.field_read); - - /* swap over to get correct write order */ - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write); - - /* RSPINF_b_2 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write); - - /* RSPINF_b_5 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write); - - /* RSPINF_b_11 */ - vnt_get_phy_field(pDevice, 14, - VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs), - PK_TYPE_11B, &phy.field_read); - - swap(phy.swap[0], phy.swap[1]); - - VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); - - /* RSPINF_a_6 */ - s_vCalculateOFDMRParameter(RATE_6M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_9 */ - s_vCalculateOFDMRParameter(RATE_9M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_12 */ - s_vCalculateOFDMRParameter(RATE_12M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_18 */ - s_vCalculateOFDMRParameter(RATE_18M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_24 */ - s_vCalculateOFDMRParameter(RATE_24M, - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_36 */ - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_48 */ - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_54 */ - s_vCalculateOFDMRParameter( - VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs), - ePHYType, - &byTxRate, - &byRsvTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime)); - /* RSPINF_a_72 */ - VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime)); - /* Set to Page0 */ - MACvSelectPage0(pDevice->PortOffset); -} - /*--------------------- Export Functions --------------------------*/ /* @@ -504,7 +386,7 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); } - s_vSetRSPINF(pDevice, ePHYType, NULL, NULL); + CARDvSetRSPINF(pDevice, ePHYType); return true; } -- GitLab From 1d6d3c1a62012653df86979658db3b86ef94b63b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:54 +0000 Subject: [PATCH 2060/9457] staging: vt6655: mac80211 conversion: device_init_registers remove legacy code Remove pMgmt, byCurrentCh, VNTWIFIbConfigPhyMode, eEncryptionStatus and netif_stop_queue. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index a888c268042d..77d81b339158 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -412,7 +412,6 @@ static void device_init_registers(struct vnt_private *pDevice) unsigned char byCCKPwrdBm = 0; unsigned char byOFDMPwrdBm = 0; int zonetype = 0; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); MACbShutdown(pDevice->PortOffset); BBvSoftwareReset(pDevice->PortOffset); @@ -616,8 +615,6 @@ static void device_init_registers(struct vnt_private *pDevice) (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); } - init_channel_table((void *)pDevice); - if (pDevice->byLocalID > REV_ID_VT3253_B1) { MACvSelectPage1(pDevice->PortOffset); @@ -652,8 +649,6 @@ static void device_init_registers(struct vnt_private *pDevice) BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode); BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode); - pDevice->byCurrentCh = 0; - /* Set BB and packet type at the same time. */ /* Set Short Slot Time, xIFS, and RSPINF. */ if (pDevice->uConnectionRate == RATE_AUTO) @@ -661,10 +656,6 @@ static void device_init_registers(struct vnt_private *pDevice) else pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - /* default G Mode */ - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G); - VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO); - pDevice->bRadioOff = false; pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, @@ -685,8 +676,6 @@ static void device_init_registers(struct vnt_private *pDevice) if (pDevice->bHWRadioOff || pDevice->bRadioControlOff) CARDbRadioPowerOff(pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - /* get Permanent network address */ SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); pr_debug("Network address = %pM\n", pDevice->abyCurrentNetAddr); @@ -699,16 +688,12 @@ static void device_init_registers(struct vnt_private *pDevice) if (pDevice->byLocalID <= REV_ID_VT3253_A1) MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR); - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - /* Turn On Rx DMA */ MACvReceive0(pDevice->PortOffset); MACvReceive1(pDevice->PortOffset); /* start the adapter */ MACvStart(pDevice->PortOffset); - - netif_stop_queue(pDevice->dev); } static void device_init_diversity_timer(struct vnt_private *pDevice) -- GitLab From 14e5300631fa504058315cc74da66ce18ed41e11 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:55 +0000 Subject: [PATCH 2061/9457] staging: vt6655: mac80211 conversion: device_free_info Remove net device code and add mac80211 unregister code. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 77d81b339158..451b608ca1f1 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -806,31 +806,20 @@ static bool device_get_pci_info(struct vnt_private *pDevice, static void device_free_info(struct vnt_private *pDevice) { - struct net_device *dev = pDevice->dev; - - ASSERT(pDevice); -//2008-0714-01by chester - device_release_WPADEV(pDevice); - -//2008-07-21-01by MikeLiu -//unregister wpadev - if (wpa_set_wpadev(pDevice, 0) != 0) - pr_err("unregister wpadev fail?\n"); + if (!pDevice) + return; -#ifdef HOSTAP - if (dev) - vt6655_hostap_set_hostapd(pDevice, 0, 0); -#endif - if (dev) - unregister_netdev(dev); + if (pDevice->mac_hw) + ieee80211_unregister_hw(pDevice->hw); if (pDevice->PortOffset) iounmap(pDevice->PortOffset); if (pDevice->pcid) pci_release_regions(pDevice->pcid); - if (dev) - free_netdev(dev); + + if (pDevice->hw) + ieee80211_free_hw(pDevice->hw); } static bool device_init_rings(struct vnt_private *pDevice) -- GitLab From 1f7a081abfc1a5e452a40d727fa35f1402fe705e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:56 +0000 Subject: [PATCH 2062/9457] staging: vt6655: switch driver over to mac80211 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Kconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig index c3ba693a8cad..77cfc708c516 100644 --- a/drivers/staging/vt6655/Kconfig +++ b/drivers/staging/vt6655/Kconfig @@ -1,8 +1,6 @@ config VT6655 tristate "VIA Technologies VT6655 support" - depends on PCI && WLAN && m - select WIRELESS_EXT - select WEXT_PRIV + depends on PCI && MAC80211 && m ---help--- This is a vendor-written driver for VIA VT6655. -- GitLab From 64fea6e455fe5b5d939df73dee078087be40f4d3 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:57 +0000 Subject: [PATCH 2063/9457] staging: vt6655: phy type same as bb type To maintain functionality typedef enum _CARD_PHY_TYPE should have the same values as typedef enum _VIA_PKT_TYPE TODO both these types need merging. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index e5bde0920553..cb95a0de5bf6 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -53,10 +53,10 @@ #define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G) typedef enum _CARD_PHY_TYPE { - PHY_TYPE_AUTO, + PHY_TYPE_11A = 0, PHY_TYPE_11B, PHY_TYPE_11G, - PHY_TYPE_11A + PHY_TYPE_AUTO } CARD_PHY_TYPE, *PCARD_PHY_TYPE; typedef enum _CARD_PKT_TYPE { -- GitLab From 7e5d88d89b22baa3fa69b0f92e1780d1a9e865d6 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:58 +0000 Subject: [PATCH 2064/9457] staging: vt6655: mac80211 conversion: device_error remove legacy functions Remove netif_stop_queue, bCmdRunning and timer functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 451b608ca1f1..0bd2ca8b49b5 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1313,10 +1313,6 @@ static void device_error(struct vnt_private *pDevice, unsigned short status) if (status & ISR_FETALERR) { dev_err(&pDevice->pcid->dev, "Hardware fatal error\n"); - netif_stop_queue(pDevice->dev); - del_timer(&pDevice->sTimerCommand); - del_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - pDevice->bCmdRunning = false; MACbShutdown(pDevice->PortOffset); return; } -- GitLab From b4bdf94d7dfb0146241185abafb26c3920cb7b33 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:43:59 +0000 Subject: [PATCH 2065/9457] staging: vt6655: vt6655_probe remove management pointers All these pointers are now dead. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 0bd2ca8b49b5..d7dd002f8daf 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3266,8 +3266,6 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) /* Enable the chip specified capabilities */ priv->flags = priv->sOpts.flags | (pChip_info->flags & 0xff000000UL); priv->tx_80211 = device_dma0_tx_80211; - priv->sMgmtObj.pAdapter = (void *)priv; - priv->pMgmt = &(priv->sMgmtObj); wiphy = priv->hw->wiphy; -- GitLab From e24c235b5d5edf55a4d9413c01bc08f2138c4f42 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:00 +0000 Subject: [PATCH 2066/9457] staging: vt6655: mac80211 conversion: PSbIsNextTBTTWakeUp convert to mac80211 Wake up to listen to next beacon when struct ieee80211_conf -> listen_interval == 1 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/power.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index fe33bb2fd7ff..53718026910c 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -327,21 +327,14 @@ PSbIsNextTBTTWakeUp( ) { struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; + struct ieee80211_hw *hw = pDevice->hw; + struct ieee80211_conf *conf = &hw->conf; bool bWakeUp = false; - if (pMgmt->wListenInterval >= 2) { - if (pMgmt->wCountToWakeUp == 0) - pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - - pMgmt->wCountToWakeUp--; - - if (pMgmt->wCountToWakeUp == 1) { - // Turn on wake up to listen next beacon - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); - bWakeUp = true; - } - + if (conf->listen_interval == 1) { + /* Turn on wake up to listen next beacon */ + MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); + bWakeUp = true; } return bWakeUp; -- GitLab From b0a08a8a73ce698e5d8d0b724a1e88aa1c2becff Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:01 +0000 Subject: [PATCH 2067/9457] staging: vt6655: MACvSetDefaultKeyEntry replace WLAN_WEP104_KEYLEN with WLAN_KEY_LEN_WEP40 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index e3b0b7f7ca85..a347f3963934 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -1526,7 +1526,7 @@ void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); } dwData = *pdwKey; - if (uKeyLen == WLAN_WEP104_KEYLEN) + if (uKeyLen == WLAN_KEY_LEN_WEP40) dwData |= 0x80000000; VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); -- GitLab From 837a38f71b40c9dcb86facbd08dc7d683bd675f1 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:02 +0000 Subject: [PATCH 2068/9457] staging: vt6655: baseband.c replace BIT0 with BIT(0) Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index b8a64c07b97a..8adeea4da0ec 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2116,7 +2116,7 @@ bool BBbVT3253Init(struct vnt_private *pDevice) bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); } pDevice->abyBBVGA[0] = 0x18; pDevice->abyBBVGA[1] = 0x0A; @@ -2149,7 +2149,7 @@ bool BBbVT3253Init(struct vnt_private *pDevice) bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); - MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT0); + MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); pDevice->abyBBVGA[0] = 0x14; pDevice->abyBBVGA[1] = 0x0A; @@ -2455,7 +2455,7 @@ BBvPowerSaveModeON(void __iomem *dwIoBase) unsigned char byOrgData; BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData |= BIT0; + byOrgData |= BIT(0); BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } @@ -2477,7 +2477,7 @@ BBvPowerSaveModeOFF(void __iomem *dwIoBase) unsigned char byOrgData; BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); - byOrgData &= ~(BIT0); + byOrgData &= ~(BIT(0)); BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); } -- GitLab From f038ad0e72614970ddcc088a7685f93d27d373b6 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:03 +0000 Subject: [PATCH 2069/9457] staging: vt6655: s_vGenerateTxParameter remove unused cbMACHdLen Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 23ee3799e86e..9beabea88b3f 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -1132,7 +1132,6 @@ s_vGenerateTxParameter( unsigned short wCurrentRate ) { - unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 unsigned short wFifoCtl; bool bDisCRC = false; unsigned char byFBOption = AUTO_FB_NONE; @@ -1150,9 +1149,6 @@ s_vGenerateTxParameter( else if (wFifoCtl & FIFOCTL_AUTO_FB_1) byFBOption = AUTO_FB_1; - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - if (!pvRrvTime) return; -- GitLab From 10d6f1b743961b191ff6347d3a5b5f8801a638fe Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:04 +0000 Subject: [PATCH 2070/9457] staging: vt6655: device_init_registers replace spin lock Use spin_lock_irqsave and spin_unlock_irqrestore. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index d7dd002f8daf..c5eca1075d3a 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -406,6 +406,7 @@ device_set_options(struct vnt_private *pDevice) static void device_init_registers(struct vnt_private *pDevice) { + unsigned long flags; unsigned int ii; unsigned char byValue; unsigned char byValue1; @@ -439,11 +440,11 @@ static void device_init_registers(struct vnt_private *pDevice) /* Get Local ID */ VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &pDevice->byLocalID); - spin_lock_irq(&pDevice->lock); + spin_lock_irqsave(&pDevice->lock, flags); SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irqrestore(&pDevice->lock, flags); /* Get Channel range */ pDevice->byMinChannel = 1; -- GitLab From a9c049b86d937fb1be9eb485353b44e47b4fc41c Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:05 +0000 Subject: [PATCH 2071/9457] staging: vt6655: baseband.c timers replace spin lock Use spin_lock_irqsave and spin_unlock_irqrestore in functions TimerSQ3CallBack and TimerState1CallBack Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 8adeea4da0ec..c7ad927084d7 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2786,9 +2786,11 @@ TimerSQ3CallBack( ) { struct vnt_private *pDevice = hDeviceContext; + unsigned long flags; pr_debug("TimerSQ3CallBack...\n"); - spin_lock_irq(&pDevice->lock); + + spin_lock_irqsave(&pDevice->lock, flags); pr_debug("3.[%08x][%08x], %d\n", (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, @@ -2803,7 +2805,7 @@ TimerSQ3CallBack( add_timer(&pDevice->TimerSQ3Tmax3); add_timer(&pDevice->TimerSQ3Tmax2); - spin_unlock_irq(&pDevice->lock); + spin_unlock_irqrestore(&pDevice->lock, flags); } /*+ @@ -2830,10 +2832,12 @@ TimerState1CallBack( ) { struct vnt_private *pDevice = hDeviceContext; + unsigned long flags; pr_debug("TimerState1CallBack...\n"); - spin_lock_irq(&pDevice->lock); + spin_lock_irqsave(&pDevice->lock, flags); + if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) { s_vChangeAntenna(pDevice); pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); @@ -2864,5 +2868,6 @@ TimerState1CallBack( } pDevice->byAntennaState = 0; BBvClearAntDivSQ3Value(pDevice); - spin_unlock_irq(&pDevice->lock); + + spin_unlock_irqrestore(&pDevice->lock, flags); } -- GitLab From 9aa5bedaa0e154cca34aba853589dbc0ceb272bb Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:06 +0000 Subject: [PATCH 2072/9457] staging: vt6655: fifo & frag control remove big endian values Endian conversion now happens at run time only little endian values are valid. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 9068c3ed696f..b59405bca606 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -118,37 +118,7 @@ */ #define CB_MAX_TX_ABORT_RETRY 3 -#ifdef __BIG_ENDIAN - /* WMAC definition FIFO Control */ -#define FIFOCTL_AUTO_FB_1 0x0010 -#define FIFOCTL_AUTO_FB_0 0x0008 -#define FIFOCTL_GRPACK 0x0004 -#define FIFOCTL_11GA 0x0003 -#define FIFOCTL_11GB 0x0002 -#define FIFOCTL_11B 0x0001 -#define FIFOCTL_11A 0x0000 -#define FIFOCTL_RTS 0x8000 -#define FIFOCTL_ISDMA0 0x4000 -#define FIFOCTL_GENINT 0x2000 -#define FIFOCTL_TMOEN 0x1000 -#define FIFOCTL_LRETRY 0x0800 -#define FIFOCTL_CRCDIS 0x0400 -#define FIFOCTL_NEEDACK 0x0200 -#define FIFOCTL_LHEAD 0x0100 - -/* WMAC definition Frag Control */ -#define FRAGCTL_AES 0x0003 -#define FRAGCTL_TKIP 0x0002 -#define FRAGCTL_LEGACY 0x0001 -#define FRAGCTL_NONENCRYPT 0x0000 -#define FRAGCTL_ENDFRAG 0x0300 -#define FRAGCTL_MIDFRAG 0x0200 -#define FRAGCTL_STAFRAG 0x0100 -#define FRAGCTL_NONFRAG 0x0000 - -#else - #define FIFOCTL_AUTO_FB_1 0x1000 #define FIFOCTL_AUTO_FB_0 0x0800 #define FIFOCTL_GRPACK 0x0400 @@ -175,8 +145,6 @@ #define FRAGCTL_STAFRAG 0x0001 #define FRAGCTL_NONFRAG 0x0000 -#endif - #define TYPE_TXDMA0 0 #define TYPE_AC0DMA 1 #define TYPE_ATIMDMA 2 -- GitLab From f218f40d48bf0e5e1968c7ecaa44a2d1a7dc61c8 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:07 +0000 Subject: [PATCH 2073/9457] staging: vt6655: vnt_rx_data: uCurrRSSI should have the value of *rssi Fixes issue of byBBVGANew is wrong in device_intr Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 036bbb0f4824..11153ef0dd95 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -1382,7 +1382,7 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, RFvRSSITodBm(priv, *rssi, &rx_dbm); priv->byBBPreEDRSSI = (u8)rx_dbm + 1; - priv->uCurrRSSI = priv->byBBPreEDRSSI; + priv->uCurrRSSI = *rssi; skb_pull(skb, 4); skb_trim(skb, frame_size); -- GitLab From d855802b8d45cf36622a640b71b58437cfee41d0 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:08 +0000 Subject: [PATCH 2074/9457] staging: vt6655: don't update bUpdateBBVGA when off channel Check flag conf IEEE80211_CONF_OFFCHANNEL so that RSSI doesn't swing wildly on scanning. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index c5eca1075d3a..968ea9aa0efb 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2040,6 +2040,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) if (pDevice->vif && pDevice->op_mode != NL80211_IFTYPE_ADHOC) { if (pDevice->bUpdateBBVGA && + !(pDevice->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && pDevice->vif->bss_conf.assoc && pDevice->uCurrRSSI) { long ldBm; -- GitLab From c7b14ea09632cb92658d7b1f758de2abd71c00f3 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:44:09 +0000 Subject: [PATCH 2075/9457] staging: vt6655: reset tsf on dissociation Ensuring that tsf counter does not run while idle. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 968ea9aa0efb..07d2101613d8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2980,6 +2980,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, CARDvSetFirstNextTBTT(priv->PortOffset, conf->beacon_int); + } else { + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, + TFTCTL_TSFCNTRST); + VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, + TFTCTL_TSFCNTREN); } } } -- GitLab From f4cf678fd783b7ed6c423b3ac8c1c6faded95986 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:19 +0000 Subject: [PATCH 2076/9457] staging: vt6655: deadcode remove zone file operations and vntconfiguration.dat These are now all handled by mac80211. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 2 - drivers/staging/vt6655/device_main.c | 113 +------------------- drivers/staging/vt6655/vntconfiguration.dat | 1 - 3 files changed, 3 insertions(+), 113 deletions(-) delete mode 100644 drivers/staging/vt6655/vntconfiguration.dat diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 17a36dc4eda1..214f73fc9def 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -750,6 +750,4 @@ bool device_dma0_xmit(struct vnt_private *pDevice, struct sk_buff *skb, unsigned int uNodeIndex); bool device_alloc_frag_buf(struct vnt_private *pDevice, PSDeFragControlBlock pDeF); -int Config_FileOperation(struct vnt_private *pDevice, - bool fwrite, unsigned char *Parameter); #endif diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 07d2101613d8..12fa63c73f01 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -303,8 +303,6 @@ static void device_free_rd0_ring(struct vnt_private *pDevice); static void device_free_rd1_ring(struct vnt_private *pDevice); static void device_free_rings(struct vnt_private *pDevice); static void device_free_frag_buf(struct vnt_private *pDevice); -static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source); /*--------------------- Export Variables --------------------------*/ @@ -412,7 +410,6 @@ static void device_init_registers(struct vnt_private *pDevice) unsigned char byValue1; unsigned char byCCKPwrdBm = 0; unsigned char byOFDMPwrdBm = 0; - int zonetype = 0; MACbShutdown(pDevice->PortOffset); BBvSoftwareReset(pDevice->PortOffset); @@ -517,41 +514,6 @@ static void device_init_registers(struct vnt_private *pDevice) /* zonetype initial */ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - zonetype = Config_FileOperation(pDevice, false, NULL); - - if (zonetype >= 0) { - if ((zonetype == 0) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { - /* for USA */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; - - pr_debug("Init Zone Type :USA\n"); - } else if ((zonetype == 1) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { - /* for Japan */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - } else if ((zonetype == 2) && - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { - /* for Europe */ - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - - pr_debug("Init Zone Type :Europe\n"); - } else { - if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE]) - pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", - zonetype, - pDevice->abyEEPROM[EEP_OFS_ZONETYPE]); - else - pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n", - zonetype); - } - } else { - pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n", - SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE)); - } /* Get RFType */ pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); @@ -595,14 +557,9 @@ static void device_init_registers(struct vnt_private *pDevice) } /* recover 12,13 ,14channel for EUROPE by 11 channel */ - if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) && - (pDevice->byOriginalZonetype == ZoneType_USA)) { - for (ii = 11; ii < 14; ii++) { - pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; - pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; - - } + for (ii = 11; ii < 14; ii++) { + pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; + pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; } /* Load OFDM A Power Table */ @@ -2139,70 +2096,6 @@ static irqreturn_t device_intr(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -//2008-8-4 by chester -static int Config_FileGetParameter(unsigned char *string, - unsigned char *dest, unsigned char *source) -{ - unsigned char buf1[100]; - int source_len = strlen(source); - - memset(buf1, 0, 100); - strcat(buf1, string); - strcat(buf1, "="); - source += strlen(buf1); - - memcpy(dest, source, source_len - strlen(buf1)); - return true; -} - -int Config_FileOperation(struct vnt_private *pDevice, - bool fwrite, unsigned char *Parameter) -{ - unsigned char *buffer = kmalloc(1024, GFP_KERNEL); - unsigned char tmpbuffer[20]; - struct file *file; - int result = 0; - - if (!buffer) { - pr_err("allocate mem for file fail?\n"); - return -1; - } - file = filp_open(CONFIG_PATH, O_RDONLY, 0); - if (IS_ERR(file)) { - kfree(buffer); - pr_err("Config_FileOperation:open file fail?\n"); - return -1; - } - - if (kernel_read(file, 0, buffer, 1024) < 0) { - pr_err("read file error?\n"); - result = -1; - goto error1; - } - - if (Config_FileGetParameter("ZONETYPE", tmpbuffer, buffer) != true) { - pr_err("get parameter error?\n"); - result = -1; - goto error1; - } - - if (memcmp(tmpbuffer, "USA", 3) == 0) { - result = ZoneType_USA; - } else if (memcmp(tmpbuffer, "JAPAN", 5) == 0) { - result = ZoneType_Japan; - } else if (memcmp(tmpbuffer, "EUROPE", 5) == 0) { - result = ZoneType_Europe; - } else { - result = -1; - pr_err("Unknown Zonetype[%s]?\n", tmpbuffer); - } - -error1: - kfree(buffer); - fput(file); - return result; -} - static void device_set_multi(struct net_device *dev) { struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = pDevice->pMgmt; diff --git a/drivers/staging/vt6655/vntconfiguration.dat b/drivers/staging/vt6655/vntconfiguration.dat deleted file mode 100644 index 0064ddce7c11..000000000000 --- a/drivers/staging/vt6655/vntconfiguration.dat +++ /dev/null @@ -1 +0,0 @@ -ZONETYPE=EUROPE \ No newline at end of file -- GitLab From 3f9aceeddb95d7349148a085a834b8f544d2328f Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:20 +0000 Subject: [PATCH 2077/9457] staging: vt6655: dead code remove zones and channel table elements emply functions will be deleted later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 605 +------------------------------ drivers/staging/vt6655/channel.h | 8 - 2 files changed, 2 insertions(+), 611 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 237969673f2e..a7b39d4c18c5 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -26,332 +26,6 @@ #include "device.h" #include "rf.h" -/*--------------------- Static Definitions -------------------------*/ - -#define CARD_MAX_CHANNEL_TBL 56 - -/*--------------------- Static Variables --------------------------*/ - -static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL + 1] = -{ - {0, 0, false, 0}, - {1, 2412, true, 0}, - {2, 2417, true, 0}, - {3, 2422, true, 0}, - {4, 2427, true, 0}, - {5, 2432, true, 0}, - {6, 2437, true, 0}, - {7, 2442, true, 0}, - {8, 2447, true, 0}, - {9, 2452, true, 0}, - {10, 2457, true, 0}, - {11, 2462, true, 0}, - {12, 2467, true, 0}, - {13, 2472, true, 0}, - {14, 2484, true, 0}, - {183, 4915, true, 0}, - {184, 4920, true, 0}, - {185, 4925, true, 0}, - {187, 4935, true, 0}, - {188, 4940, true, 0}, - {189, 4945, true, 0}, - {192, 4960, true, 0}, - {196, 4980, true, 0}, - {7, 5035, true, 0}, - {8, 5040, true, 0}, - {9, 5045, true, 0}, - {11, 5055, true, 0}, - {12, 5060, true, 0}, - {16, 5080, true, 0}, - {34, 5170, true, 0}, - {36, 5180, true, 0}, - {38, 5190, true, 0}, - {40, 5200, true, 0}, - {42, 5210, true, 0}, - {44, 5220, true, 0}, - {46, 5230, true, 0}, - {48, 5240, true, 0}, - {52, 5260, true, 0}, - {56, 5280, true, 0}, - {60, 5300, true, 0}, - {64, 5320, true, 0}, - {100, 5500, true, 0}, - {104, 5520, true, 0}, - {108, 5540, true, 0}, - {112, 5560, true, 0}, - {116, 5580, true, 0}, - {120, 5600, true, 0}, - {124, 5620, true, 0}, - {128, 5640, true, 0}, - {132, 5660, true, 0}, - {136, 5680, true, 0}, - {140, 5700, true, 0}, - {149, 5745, true, 0}, - {153, 5765, true, 0}, - {157, 5785, true, 0}, - {161, 5805, true, 0}, - {165, 5825, true, 0} -}; - -/************************************************************************ - * The Radar regulation rules for each country - ************************************************************************/ -static struct -{ - unsigned char byChannelCountryCode; /* The country code */ - char chCountryCode[2]; - unsigned char bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */ - unsigned char byPower[CB_MAX_CHANNEL]; -} ChannelRuleTab[] = -{ -/************************************************************************ - * This table is based on Athero driver rules - ************************************************************************/ -/* Country Available channels, ended with 0 */ -/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ - {CCODE_FCC, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_TELEC, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ETSI, {'E' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_RESV3, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV4, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV5, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV6, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV7, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV8, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESV9, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVa, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVb, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVc, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVd, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RESVe, {' ' , ' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALLBAND, {' ' , ' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALBANIA, {'A' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ALGERIA, {'D' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ARGENTINA, {'A' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, - {CCODE_ARMENIA, {'A' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_AUSTRALIA, {'A' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_AUSTRIA, {'A' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_AZERBAIJAN, {'A' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BAHRAIN, {'B' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELARUS, {'B' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELGIUM, {'B' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BELIZE, {'B' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BOLIVIA, {'B' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BRAZIL, {'B' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_BRUNEI_DARUSSALAM, {'B' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_BULGARIA, {'B' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} }, - {CCODE_CANADA, {'C' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_CHILE, {'C' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} }, - {CCODE_CHINA, {'C' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_COLOMBIA, {'C' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_COSTA_RICA, {'C' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_CROATIA, {'H' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_CYPRUS, {'C' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_CZECH, {'C' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_DENMARK, {'D' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_DOMINICAN_REPUBLIC, {'D' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_ECUADOR, {'E' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_EGYPT, {'E' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_EL_SALVADOR, {'S' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ESTONIA, {'E' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_FINLAND, {'F' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_FRANCE, {'F' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GERMANY, {'D' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_GREECE, {'G' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GEORGIA, {'G' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_GUATEMALA, {'G' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_HONDURAS, {'H' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_HONG_KONG, {'H' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_HUNGARY, {'H' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ICELAND, {'I' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_INDIA, {'I' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_INDONESIA, {'I' , 'D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_IRAN, {'I' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_IRELAND, {'I' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_ITALY, {'I' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_ISRAEL, {'I' , 'L'}, { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JAPAN, {'J' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JORDAN, {'J' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_KAZAKHSTAN, {'K' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_KUWAIT, {'K' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LATVIA, {'L' , 'V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LEBANON, {'L' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LEICHTENSTEIN, {'L' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_LITHUANIA, {'L' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_LUXEMBURG, {'L' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_MACAU, {'M' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_MACEDONIA, {'M' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MALTA, {'M' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_MALAYSIA, {'M' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MEXICO, {'M' , 'X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_MONACO, {'M' , 'C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MOROCCO, {'M' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_NETHERLANDS, {'N' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_NEW_ZEALAND, {'N' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_NORTH_KOREA, {'K' , 'P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_NORWAY, {'N' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_OMAN, {'O' , 'M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PAKISTAN, {'P' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PANAMA, {'P' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_PERU, {'P' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_PHILIPPINES, {'P' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_POLAND, {'P' , 'L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_PORTUGAL, {'P' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_PUERTO_RICO, {'P' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_QATAR, {'Q' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ROMANIA, {'R' , 'O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_RUSSIA, {'R' , 'U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SAUDI_ARABIA, {'S' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SINGAPORE, {'S' , 'G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} }, - {CCODE_SLOVAKIA, {'S' , 'K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_SLOVENIA, {'S' , 'I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SOUTH_AFRICA, {'Z' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SOUTH_KOREA, {'K' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_SPAIN, {'E' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} }, - {CCODE_SWEDEN, {'S' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_SWITZERLAND, {'C' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_SYRIA, {'S' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TAIWAN, {'T' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} }, - {CCODE_THAILAND, {'T' , 'H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_TRINIDAD_TOBAGO, {'T' , 'T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TUNISIA, {'T' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_TURKEY, {'T' , 'R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UK, {'G' , 'B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} }, - {CCODE_UKRAINE, {'U' , 'A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UNITED_ARAB_EMIRATES, {'A' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_UNITED_STATES, {'U' , 'S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} - , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} }, - {CCODE_URUGUAY, {'U' , 'Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_UZBEKISTAN, {'U' , 'Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_VENEZUELA, {'V' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0} - , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} }, - {CCODE_VIETNAM, {'V' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_YEMEN, {'Y' , 'E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_ZIMBABWE, {'Z' , 'W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_JAPAN_W52_W53, {'J' , 'J'}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {CCODE_MAX, {'U' , 'N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } -/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */ -}; - -/*--------------------- Export Functions --------------------------*/ - static struct ieee80211_rate vnt_rates_bg[] = { { .bitrate = 10, .hw_value = RATE_1M }, { .bitrate = 20, .hw_value = RATE_2M }, @@ -521,9 +195,6 @@ bool is_channel_valid(unsigned int ChannelIndex) bValid = false; goto exit; } - - bValid = sChannelTbl[ChannelIndex].bValid; - exit: return bValid; } @@ -542,110 +213,17 @@ bool is_channel_valid(unsigned int ChannelIndex) bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable) { - if (uCountryCodeIdx >= CCODE_MAX) - return false; - - memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL); - return true; } -void init_channel_table(void *pDeviceHandler) -{ - struct vnt_private *pDevice = pDeviceHandler; - bool bMultiBand = false; - unsigned int ii; - - for (ii = 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) - sChannelTbl[ii].bValid = false; - - switch (pDevice->byRFType) { - case RF_RFMD2959: - case RF_AIROHA: - case RF_AL2230S: - case RF_UW2451: - case RF_VT3226: - bMultiBand = false; - break; - case RF_AIROHA7230: - case RF_UW2452: - case RF_NOTHING: - default: - bMultiBand = true; - break; - } - - if ((pDevice->dwDiagRefCount != 0) || pDevice->b11hEnable) { - if (bMultiBand) { - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - } - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - } - } else { - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - pDevice->abyLocalPwr[ii + 1] = pDevice->abyCCKDefaultPwr[ii + 1]; - } - } - } - } else if (pDevice->byZoneType <= CCODE_MAX) { - if (bMultiBand) { - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } - } else { - for (ii = 0; ii < CHANNEL_MAX_24G; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - sChannelTbl[ii + 1].bValid = true; - pDevice->abyRegPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - pDevice->abyLocalPwr[ii + 1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } - } - } - - pr_info("Zone=[%d][%c][%c]!!\n", - pDevice->byZoneType, - ChannelRuleTab[pDevice->byZoneType].chCountryCode[0], - ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]); - - for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { - if (pDevice->abyRegPwr[ii + 1] == 0) - pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - if (pDevice->abyLocalPwr[ii + 1] == 0) - pDevice->abyLocalPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; - } -} - unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType) { - unsigned int ii; - - if ((ePhyType == PHY_TYPE_11B) || (ePhyType == PHY_TYPE_11G)) - return byChannelNumber; - - for (ii = (CB_MAX_CHANNEL_24G + 1); ii <= CB_MAX_CHANNEL;) { - if (sChannelTbl[ii].byChannelNumber == byChannelNumber) - return (unsigned char) ii; - ii++; - } return 0; } unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex) { - return sChannelTbl[byChannelIndex].byChannelNumber; + return 0; } /** @@ -709,41 +287,6 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) { - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii = 0; - unsigned int uu = 0; - unsigned int step = 0; - unsigned int uNumOfCountryInfo = 0; - unsigned char byCh = 0; - PWLAN_IE_COUNTRY pIE_Country = (PWLAN_IE_COUNTRY) pIE; - - uNumOfCountryInfo = (pIE_Country->len - 3); - uNumOfCountryInfo /= 3; - - if (ePHYType == PHY_TYPE_11A) { - pDevice->bCountryInfo5G = true; - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CARD_MAX_CHANNEL_TBL; ii++) - sChannelTbl[ii].bValid = false; - - step = 4; - } else { - pDevice->bCountryInfo24G = true; - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) - sChannelTbl[ii].bValid = false; - - step = 1; - } - pDevice->abyCountryCode[0] = pIE_Country->abyCountryString[0]; - pDevice->abyCountryCode[1] = pIE_Country->abyCountryString[1]; - pDevice->abyCountryCode[2] = pIE_Country->abyCountryString[2]; - - for (ii = 0; ii < uNumOfCountryInfo; ii++) { - for (uu = 0; uu < pIE_Country->abyCountryInfo[ii*3+1]; uu++) { - byCh = get_channel_mapping(pDevice, (unsigned char)(pIE_Country->abyCountryInfo[ii*3]+step*uu), ePHYType); - sChannelTbl[byCh].bValid = true; - pDevice->abyRegPwr[byCh] = pIE_Country->abyCountryInfo[ii*3+2]; - } - } } /** @@ -758,176 +301,32 @@ void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) { - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - unsigned char byCount; - PWLAN_IE_SUPP_CH pIE = (PWLAN_IE_SUPP_CH) pbyIEs; - unsigned char *pbyChTupple; unsigned char byLen = 0; - - pIE->byElementID = WLAN_EID_SUPP_CH; - pIE->len = 0; - pbyChTupple = pIE->abyChannelTuple; - byLen = 2; - /* lower band */ - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[28] == true) { - for (ii = 28; ii < 36; ii += 2) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 34; - *pbyChTupple++ = byCount; - byLen += 2; - } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[29] == true) { - for (ii = 29; ii < 36; ii += 2) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 36; - *pbyChTupple++ = byCount; - byLen += 2; - } - /* middle band */ - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[36] == true) { - for (ii = 36; ii < 40; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 52; - *pbyChTupple++ = byCount; - byLen += 2; - } - /* higher band */ - byCount = 0; - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[40] == true) { - for (ii = 40; ii < 51; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 100; - *pbyChTupple++ = byCount; - byLen += 2; - } else if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[51] == true) { - for (ii = 51; ii < 56; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] == true) - byCount++; - } - - *pbyChTupple++ = 149; - *pbyChTupple++ = byCount; - byLen += 2; - } - pIE->len += (byLen - 2); return byLen; } void set_country_IE(void *pDeviceHandler, void *pIE) { - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - PWLAN_IE_COUNTRY pIECountry = (PWLAN_IE_COUNTRY) pIE; - - pIECountry->byElementID = WLAN_EID_COUNTRY; - pIECountry->len = 0; - pIECountry->abyCountryString[0] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[0]; - pIECountry->abyCountryString[1] = ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]; - pIECountry->abyCountryString[2] = ' '; - for (ii = CB_MAX_CHANNEL_24G; ii < CB_MAX_CHANNEL; ii++) { - if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { - pIECountry->abyCountryInfo[pIECountry->len++] = sChannelTbl[ii + 1].byChannelNumber; - pIECountry->abyCountryInfo[pIECountry->len++] = 1; - pIECountry->abyCountryInfo[pIECountry->len++] = ChannelRuleTab[pDevice->byZoneType].byPower[ii]; - } - } - pIECountry->len += 3; } bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, unsigned char *pbyChannelNumber, unsigned char *pbyMap) { - if (uChannelIndex > CB_MAX_CHANNEL) - return false; - - *pbyChannelNumber = sChannelTbl[uChannelIndex].byChannelNumber; - *pbyMap = sChannelTbl[uChannelIndex].byMAP; - return sChannelTbl[uChannelIndex].bValid; + return 0; } void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, unsigned char byMap) { - if (uChannelIndex > CB_MAX_CHANNEL) - return; - - sChannelTbl[uChannelIndex].byMAP |= byMap; } void clear_channel_map_info(void *pDeviceHandler) { - unsigned int ii = 0; - for (ii = 1; ii <= CB_MAX_CHANNEL; ii++) - sChannelTbl[ii].byMAP = 0; } unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) { - unsigned int ii = 0; unsigned char byOptionChannel = 0; - int aiWeight[CB_MAX_CHANNEL_24G + 1] = {-1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - if (ePHYType == PHY_TYPE_11A) { - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (sChannelTbl[ii].bValid) { - if (byOptionChannel == 0) - byOptionChannel = (unsigned char) ii; - - if (sChannelTbl[ii].byMAP == 0) - return (unsigned char) ii; - else if (!(sChannelTbl[ii].byMAP & 0x08)) - byOptionChannel = (unsigned char) ii; - } - } - } else { - byOptionChannel = 0; - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if (sChannelTbl[ii].bValid) { - if (sChannelTbl[ii].byMAP == 0) { - aiWeight[ii] += 100; - } else if (sChannelTbl[ii].byMAP & 0x01) { - if (ii > 3) - aiWeight[ii - 3] -= 10; - - if (ii > 2) - aiWeight[ii - 2] -= 20; - - if (ii > 1) - aiWeight[ii - 1] -= 40; - - aiWeight[ii] -= 80; - if (ii < CB_MAX_CHANNEL_24G) - aiWeight[ii + 1] -= 40; - - if (ii < (CB_MAX_CHANNEL_24G - 1)) - aiWeight[ii+2] -= 20; - - if (ii < (CB_MAX_CHANNEL_24G - 2)) - aiWeight[ii+3] -= 10; - } - } - } - for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if (sChannelTbl[ii].bValid && - (aiWeight[ii] > aiWeight[byOptionChannel])) { - byOptionChannel = (unsigned char) ii; - } - } - } return byOptionChannel; } diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 0d3e1f121759..78ab642738ed 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -26,17 +26,9 @@ #include "ttype.h" #include "card.h" -typedef struct tagSChannelTblElement { - unsigned char byChannelNumber; - unsigned int uFrequency; - bool bValid; - unsigned char byMAP; -} SChannelTblElement, *PSChannelTblElement; - void vnt_init_bands(struct vnt_private *); bool is_channel_valid(unsigned int CountryCode); -void init_channel_table(void *pDeviceHandler); unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType); bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable); unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex); -- GitLab From 7af1ead431ec82b64de511fa28ac54b3cc5b66ca Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:21 +0000 Subject: [PATCH 2078/9457] staging: vt6655: dead code remove net device code All functions are dead and nolonger of use. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 2 - drivers/staging/vt6655/device_main.c | 1176 -------------------------- drivers/staging/vt6655/wcmd.c | 4 - 3 files changed, 1182 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 214f73fc9def..6729d237a6ae 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -746,8 +746,6 @@ static inline PDEVICE_TD_INFO alloc_td_info(void) /*--------------------- Export Functions --------------------------*/ -bool device_dma0_xmit(struct vnt_private *pDevice, - struct sk_buff *skb, unsigned int uNodeIndex); bool device_alloc_frag_buf(struct vnt_private *pDevice, PSDeFragControlBlock pDeF); #endif diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 12fa63c73f01..870016ae9905 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -32,20 +32,12 @@ * device_free_info - device structure resource free function * device_get_pci_info - get allocated pci io/mem resource * device_print_info - print out resource - * device_open - allocate dma/descripter resource & initial mac/bbp function - * device_xmit - asynchrous data tx function * device_intr - interrupt handle function - * device_set_multi - set mac filter - * device_ioctl - ioctl entry - * device_close - shutdown mac/bbp & free dma/descripter resource * device_rx_srv - rx service function - * device_receive_frame - rx data function * device_alloc_rx_buf - rx buffer pre-allocated function * device_alloc_frag_buf - rx fragement pre-allocated function * device_free_tx_buf - free tx buffer function * device_free_frag_buf- free de-fragement buffer - * device_dma0_tx_80211- tx 802.11 frame via dma0 - * device_dma0_xmit- tx PS bufferred frame via dma0 * device_init_rd0_ring- initial rd dma0 ring * device_init_rd1_ring- initial rd dma1 ring * device_init_td0_ring- initial tx dma0 ring buffer @@ -265,12 +257,7 @@ static void device_free_info(struct vnt_private *pDevice); static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid); static void device_print_info(struct vnt_private *pDevice); static void device_init_diversity_timer(struct vnt_private *pDevice); -static int device_open(struct net_device *dev); -static int device_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t device_intr(int irq, void *dev_instance); -static void device_set_multi(struct net_device *dev); -static int device_close(struct net_device *dev); -static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef CONFIG_PM static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); @@ -287,11 +274,6 @@ static void device_init_defrag_cb(struct vnt_private *pDevice); static void device_init_td0_ring(struct vnt_private *pDevice); static void device_init_td1_ring(struct vnt_private *pDevice); -static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev); -//2008-0714by Mike Liu -static bool device_release_WPADEV(struct vnt_private *pDevice); - -static int ethtool_ioctl(struct net_device *dev, void __user *useraddr); static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx); static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx); static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pDesc); @@ -672,45 +654,6 @@ static void device_init_diversity_timer(struct vnt_private *pDevice) pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); } -static bool device_release_WPADEV(struct vnt_private *pDevice) -{ - viawget_wpa_header *wpahdr; - int ii = 0; - - //send device close to wpa_supplicnat layer - if (pDevice->bWPADEVUp) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DEVICECLOSE_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - - while (pDevice->bWPADEVUp) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ / 20); //wait 50ms - ii++; - if (ii > 20) - break; - } - } - return true; -} - -static const struct net_device_ops device_netdev_ops = { - .ndo_open = device_open, - .ndo_stop = device_close, - .ndo_do_ioctl = device_ioctl, - .ndo_start_xmit = device_xmit, - .ndo_set_rx_mode = device_set_multi, -}; - static void device_print_info(struct vnt_private *pDevice) { dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id)); @@ -1297,653 +1240,6 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) pTDInfo->byFlags = 0; } -static int device_open(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int i; - - pDevice->rx_buf_sz = PKT_BUF_SZ; - if (!device_init_rings(pDevice)) - return -ENOMEM; - -//2008-5-13 by chester - i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev); - if (i) - return i; - -#ifdef WPA_SM_Transtatus - pDevice->fWPA_Authened = false; -#endif - pr_debug("call device init rd0 ring\n"); - device_init_rd0_ring(pDevice); - device_init_rd1_ring(pDevice); - device_init_defrag_cb(pDevice); - device_init_td0_ring(pDevice); - device_init_td1_ring(pDevice); - - if (pDevice->bDiversityRegCtlON) - device_init_diversity_timer(pDevice); - - vMgrObjectInit(pDevice); - vMgrTimerInit(pDevice); - - pr_debug("call device_init_registers\n"); - device_init_registers(pDevice); - - MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - ether_addr_copy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr); - device_set_multi(pDevice->dev); - - // Init for Key Management - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - add_timer(&(pDevice->pMgmt->sTimerSecondCallback)); - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = false; -#endif - pDevice->byReAssocCount = 0; - pDevice->bWPADEVUp = false; - // Patch: if WEP key already set by iwconfig but device not yet open - if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) { - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(pDevice->byKeyIndex | (1 << 31)), - pDevice->uKeyLength, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID - ); - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } - - pr_debug("call MACvIntEnable\n"); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - - if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - } else { - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - } - pDevice->flags |= DEVICE_FLAGS_OPENED; - - pr_debug("device_open success..\n"); - return 0; -} - -static int device_close(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; -//2007-1121-02by EinsnLiu - if (pDevice->bLinkPass) { - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - mdelay(30); - } - - del_timer(&pDevice->sTimerTxData); - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - if (pDevice->bDiversityRegCtlON) { - del_timer(&pDevice->TimerSQ3Tmax1); - del_timer(&pDevice->TimerSQ3Tmax2); - del_timer(&pDevice->TimerSQ3Tmax3); - } - - netif_stop_queue(dev); - pDevice->bCmdRunning = false; - MACbShutdown(pDevice->PortOffset); - MACbSoftwareReset(pDevice->PortOffset); - CARDbRadioPowerOff(pDevice); - - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - device_free_td0_ring(pDevice); - device_free_td1_ring(pDevice); - device_free_rd0_ring(pDevice); - device_free_rd1_ring(pDevice); - device_free_frag_buf(pDevice); - device_free_rings(pDevice); - BSSvClearNodeDBTable(pDevice, 0); - free_irq(dev->irq, dev); - pDevice->flags &= (~DEVICE_FLAGS_OPENED); - //2008-0714-01by chester - device_release_WPADEV(pDevice); - - pr_debug("device_close..\n"); - return 0; -} - -static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - unsigned char *pbMPDU; - unsigned int cbMPDULen = 0; - - pr_debug("device_dma0_tx_80211\n"); - spin_lock_irq(&pDevice->lock); - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - pr_debug("device_dma0_tx_80211, td0 <=0\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pDevice->bStopTx0Pkt) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - cbMPDULen = skb->len; - pbMPDU = skb->data; - - vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen); - - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -bool device_dma0_xmit(struct vnt_private *pDevice, - struct sk_buff *skb, unsigned int uNodeIndex) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum; - unsigned char byPktType; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; - unsigned int ii; - SKeyItem STempKey; - - if (pDevice->bStopTx0Pkt) { - dev_kfree_skb_irq(skb); - return false; - } - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - dev_kfree_skb_irq(skb); - pr_debug("device_dma0_xmit, td0 <=0\n"); - return false; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - pr_debug("device_dma0_xmit, assocCount = 0\n"); - return false; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) { - dev_kfree_skb_irq(skb); - return false; - } - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } - } else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - //preamble type - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = PREAMBLE_LONG; - - pr_debug("dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate); - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode) - byPktType = PK_TYPE_11GB; - else - byPktType = PK_TYPE_11GA; - } - - if (pDevice->bEncryptionEnable) - bNeedEncryption = true; - - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_TXDMA0, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; - - pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD; - - MACvTransmit0(pDevice->PortOffset); - - return true; -} - -//TYPE_AC0DMA data tx -static int device_xmit(struct sk_buff *skb, struct net_device *dev) { - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int uNodeIndex = 0; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - unsigned int uMACfragNum = 1; - unsigned int cbFrameBodySize; - unsigned char byPktType; - unsigned int cbHeaderSize; - bool bNeedEncryption = false; - PSKeyItem pTransmitKey = NULL; - SKeyItem STempKey; - unsigned int ii; - bool bTKIP_UseGTK = false; - bool bNeedDeAuth = false; - unsigned char *pbyBSSID; - bool bNodeExist = false; - - spin_lock_irq(&pDevice->lock); - if (!pDevice->bLinkPass) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pDevice->bStopDataPkt) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (pDevice->uAssocCount == 0) { - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - if (is_multicast_ether_addr((unsigned char *)(skb->data))) { - uNodeIndex = 0; - bNodeExist = true; - if (pMgmt->sNodeDBTable[0].bPSEnable) { - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb); - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - // set tx map - pMgmt->abyPSTxMap[0] |= byMask[0]; - spin_unlock_irq(&pDevice->lock); - return 0; - } - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) { - skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++; - // set tx map - wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pr_debug("Set:pMgmt->abyPSTxMap[%d]= %d\n", - (wAID >> 3), - pMgmt->abyPSTxMap[wAID >> 3]); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->byPreambleType = pDevice->byShortPreamble; - else - pDevice->byPreambleType = PREAMBLE_LONG; - - bNodeExist = true; - - } - } - - if (!bNodeExist) { - pr_debug("Unknown STA not found in node DB\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN); - cbFrameBodySize = skb->len - ETH_HLEN; - // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - if (pDevice->bEncryptionEnable) { - bNeedEncryption = true; - // get Transmit key - do { - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - bTKIP_UseGTK = true; - pr_debug("Get GTK\n"); - break; - } - } else { - pr_debug("Get PTK\n"); - break; - } - } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 - pr_debug("IBSS Serach Key:\n"); - for (ii = 0; ii < 6; ii++) - pr_debug("%x\n", *(pbyBSSID+ii)); - pr_debug("\n"); - - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) - break; - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - pr_debug("IBSS and KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - else - pr_debug("NOT IBSS and KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - } else { - bTKIP_UseGTK = true; - pr_debug("Get GTK\n"); - } - } while (false); - } - - if (pDevice->bEnableHostWEP) { - pr_debug("acdma0: STA index %d\n", uNodeIndex); - if (pDevice->bEncryptionEnable) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength - ); - } - } - - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { - pr_debug("uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", - uMACfragNum); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - - if (pTransmitKey != NULL) { - if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) && - (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) { - uMACfragNum = 1; //WEP256 doesn't support fragment - } - } - - byPktType = (unsigned char)pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; - - } - } - pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - //auto rate - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - pDevice->wCurrentRate = RATE_1M; - pDevice->byACKRate = RATE_1M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } else { - pDevice->wCurrentRate = RATE_6M; - pDevice->byACKRate = RATE_6M; - pDevice->byTopCCKBasicRate = RATE_1M; - pDevice->byTopOFDMBasicRate = RATE_6M; - } - } else { - VNTWIFIvGetTxRate(pDevice->pMgmt, - pDevice->sTxEthHeader.abyDstAddr, - &(pDevice->wCurrentRate), - &(pDevice->byACKRate), - &(pDevice->byTopCCKBasicRate), - &(pDevice->byTopOFDMBasicRate)); - - } - } - - - if (pDevice->wCurrentRate <= RATE_11M) { - byPktType = PK_TYPE_11B; - } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - byPktType = PK_TYPE_11A; - } else { - if (pDevice->bProtectMode) - byPktType = PK_TYPE_11GB; - else - byPktType = PK_TYPE_11GA; - } - - if (bNeedEncryption) { - pr_debug("ntohs Pkt Type=%04x\n", - ntohs(pDevice->sTxEthHeader.wType)); - if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { - bNeedEncryption = false; - pr_debug("Pkt Type=%04x\n", - (pDevice->sTxEthHeader.wType)); - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (pTransmitKey == NULL) { - pr_debug("Don't Find TX KEY\n"); - } else { - if (bTKIP_UseGTK) { - pr_debug("error: KEY is GTK!!~~\n"); - } else { - pr_debug("Find PTK [%lX]\n", - pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } - - if (pDevice->byCntMeasure == 2) { - bNeedDeAuth = true; - pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++; - } - - if (pDevice->bEnableHostWEP) { - if ((uNodeIndex != 0) && - (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - pr_debug("Find PTK [%lX]\n", - pTransmitKey->dwKeyIndex); - bNeedEncryption = true; - } - } - } else { - if (pTransmitKey == NULL) { - pr_debug("return no tx key\n"); - dev_kfree_skb_irq(skb); - spin_unlock_irq(&pDevice->lock); - return 0; - } - } - } - - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, - cbFrameBodySize, TYPE_AC0DMA, pHeadTD, - &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex, - &uMACfragNum, - &cbHeaderSize - ); - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - // Poll Transmit the adapter - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == uMACfragNum - 1) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - // Save the information needed by the tx interrupt handler - // to complete the Send request - pLastTD->pTDInfo->skb = skb; - pLastTD->pTDInfo->byFlags = 0; - pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; - pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet - - if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) - netif_stop_queue(dev); - - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; - - if (pDevice->bFixRate) - pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr); - - { - unsigned char Protocol_Version; //802.1x Authentication - unsigned char Packet_Type; //802.1x Authentication - unsigned char Descriptor_type; - unsigned short Key_info; - bool bTxeapol_key = false; - - Protocol_Version = skb->data[ETH_HLEN]; - Packet_Type = skb->data[ETH_HLEN+1]; - Descriptor_type = skb->data[ETH_HLEN+1+1+2]; - Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); - if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer - bTxeapol_key = true; - if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN - if (!(Key_info & BIT3) && //group-key challenge - (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key - pDevice->fWPA_Authened = true; - if (Descriptor_type == 254) - pr_debug("WPA "); - else - pr_debug("WPA2 "); - pr_debug("Authentication completed!!\n"); - } - } - } - } - } - - MACvTransmitAC0(pDevice->PortOffset); - - dev->trans_start = jiffies; - - spin_unlock_irq(&pDevice->lock); - return 0; -} - static irqreturn_t device_intr(int irq, void *dev_instance) { struct vnt_private *pDevice = dev_instance; @@ -2096,477 +1392,6 @@ static irqreturn_t device_intr(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -static void device_set_multi(struct net_device *dev) { - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = pDevice->pMgmt; - u32 mc_filter[2]; - struct netdev_hw_addr *ha; - - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); - - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - pr_notice("%s: Promiscuous mode enabled\n", dev->name); - /* Unconditionally log net taps. */ - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST); - } else if ((netdev_mc_count(dev) > pDevice->multicast_limit) - || (dev->flags & IFF_ALLMULTI)) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - } else { - memset(mc_filter, 0, sizeof(mc_filter)); - netdev_for_each_mc_addr(ha, dev) { - int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; - - mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); - } - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]); - MACvSelectPage0(pDevice->PortOffset); - pDevice->byRxMode &= ~(RCR_UNICAST); - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - } - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac. - pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST); - pDevice->byRxMode &= ~(RCR_UNICAST); - } - - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode); - pr_debug("pDevice->byRxMode = %x\n", pDevice->byRxMode); -} - -static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct vnt_private *pDevice = netdev_priv(dev); - struct iwreq *wrq = (struct iwreq *)rq; - int rc = 0; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSCmdRequest pReq; - - if (pMgmt == NULL) { - rc = -EFAULT; - return rc; - } - - switch (cmd) { - case SIOCGIWNAME: - rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL); - break; - - case SIOCGIWNWID: //0x8b03 support - rc = -EOPNOTSUPP; - break; - - // Set frequency/channel - case SIOCSIWFREQ: - rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL); - break; - - // Get frequency/channel - case SIOCGIWFREQ: - rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL); - break; - - // Set desired network name (ESSID) - case SIOCSIWESSID: - - { - char essid[IW_ESSID_MAX_SIZE+1]; - - if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) { - rc = -E2BIG; - break; - } - if (copy_from_user(essid, wrq->u.essid.pointer, - wrq->u.essid.length)) { - rc = -EFAULT; - break; - } - rc = iwctl_siwessid(dev, NULL, - &(wrq->u.essid), essid); - } - break; - - // Get current network name (ESSID) - case SIOCGIWESSID: - - { - char essid[IW_ESSID_MAX_SIZE+1]; - - if (wrq->u.essid.pointer) - rc = iwctl_giwessid(dev, NULL, - &(wrq->u.essid), essid); - if (copy_to_user(wrq->u.essid.pointer, - essid, - wrq->u.essid.length)) - rc = -EFAULT; - } - break; - - case SIOCSIWAP: - - rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL); - break; - - // Get current Access Point (BSSID) - case SIOCGIWAP: - rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL); - break; - - // Set desired station name - case SIOCSIWNICKN: - pr_debug(" SIOCSIWNICKN\n"); - rc = -EOPNOTSUPP; - break; - - // Get current station name - case SIOCGIWNICKN: - pr_debug(" SIOCGIWNICKN\n"); - rc = -EOPNOTSUPP; - break; - - // Set the desired bit-rate - case SIOCSIWRATE: - rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL); - break; - - // Get the current bit-rate - case SIOCGIWRATE: - - rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL); - break; - - // Set the desired RTS threshold - case SIOCSIWRTS: - - rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL); - break; - - // Get the current RTS threshold - case SIOCGIWRTS: - - rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL); - break; - - // Set the desired fragmentation threshold - case SIOCSIWFRAG: - - rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL); - break; - - // Get the current fragmentation threshold - case SIOCGIWFRAG: - - rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL); - break; - - // Set mode of operation - case SIOCSIWMODE: - rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL); - break; - - // Get mode of operation - case SIOCGIWMODE: - rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL); - break; - - // Set WEP keys and mode - case SIOCSIWENCODE: { - char abyKey[WLAN_WEP232_KEYLEN]; - - if (wrq->u.encoding.pointer) { - if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) { - rc = -E2BIG; - break; - } - memset(abyKey, 0, WLAN_WEP232_KEYLEN); - if (copy_from_user(abyKey, - wrq->u.encoding.pointer, - wrq->u.encoding.length)) { - rc = -EFAULT; - break; - } - } else if (wrq->u.encoding.length != 0) { - rc = -EINVAL; - break; - } - rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey); - } - break; - - // Get the WEP keys and mode - case SIOCGIWENCODE: - - if (!capable(CAP_NET_ADMIN)) { - rc = -EPERM; - break; - } - { - char abyKey[WLAN_WEP232_KEYLEN]; - - rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey); - if (rc != 0) - break; - if (wrq->u.encoding.pointer) { - if (copy_to_user(wrq->u.encoding.pointer, - abyKey, - wrq->u.encoding.length)) - rc = -EFAULT; - } - } - break; - - // Get the current Tx-Power - case SIOCGIWTXPOW: - pr_debug(" SIOCGIWTXPOW\n"); - rc = -EOPNOTSUPP; - break; - - case SIOCSIWTXPOW: - pr_debug(" SIOCSIWTXPOW\n"); - rc = -EOPNOTSUPP; - break; - - case SIOCSIWRETRY: - - rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL); - break; - - case SIOCGIWRETRY: - - rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL); - break; - - // Get range of parameters - case SIOCGIWRANGE: - - { - struct iw_range range; - - rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range); - if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) - rc = -EFAULT; - } - - break; - - case SIOCGIWPOWER: - - rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL); - break; - - case SIOCSIWPOWER: - - rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL); - break; - - case SIOCGIWSENS: - - rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL); - break; - - case SIOCSIWSENS: - pr_debug(" SIOCSIWSENS\n"); - rc = -EOPNOTSUPP; - break; - - case SIOCGIWAPLIST: { - char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))]; - - if (wrq->u.data.pointer) { - rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); - if (rc == 0) { - if (copy_to_user(wrq->u.data.pointer, - buffer, - (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality))) - )) - rc = -EFAULT; - } - } - } - break; - -#ifdef WIRELESS_SPY - // Set the spy list - case SIOCSIWSPY: - - pr_debug(" SIOCSIWSPY\n"); - rc = -EOPNOTSUPP; - break; - - // Get the spy list - case SIOCGIWSPY: - - pr_debug(" SIOCGIWSPY\n"); - rc = -EOPNOTSUPP; - break; - -#endif // WIRELESS_SPY - - case SIOCGIWPRIV: - pr_debug(" SIOCGIWPRIV\n"); - rc = -EOPNOTSUPP; - break; - -//2008-0409-07, by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - case SIOCSIWAUTH: - pr_debug(" SIOCSIWAUTH\n"); - rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL); - break; - - case SIOCGIWAUTH: - pr_debug(" SIOCGIWAUTH\n"); - rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL); - break; - - case SIOCSIWGENIE: - pr_debug(" SIOCSIWGENIE\n"); - rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; - - case SIOCGIWGENIE: - pr_debug(" SIOCGIWGENIE\n"); - rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; - - case SIOCSIWENCODEEXT: { - char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1]; - - pr_debug(" SIOCSIWENCODEEXT\n"); - if (wrq->u.encoding.pointer) { - memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1); - if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) { - rc = -E2BIG; - break; - } - if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) { - rc = -EFAULT; - break; - } - } else if (wrq->u.encoding.length != 0) { - rc = -EINVAL; - break; - } - rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra); - } - break; - - case SIOCGIWENCODEEXT: - pr_debug(" SIOCGIWENCODEEXT\n"); - rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL); - break; - - case SIOCSIWMLME: - pr_debug(" SIOCSIWMLME\n"); - rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); - break; - -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, by Einsn Liu - - case IOCTL_CMD_TEST: - - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EFAULT; - break; - } - rc = 0; - pReq = (PSCmdRequest)rq; - pReq->wResult = MAGIC_CODE; - break; - - case IOCTL_CMD_SET: - - if (!(pDevice->flags & DEVICE_FLAGS_OPENED) && - (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA)) { - rc = -EFAULT; - break; - } - rc = 0; - - if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy))) - return -EBUSY; - - rc = private_ioctl(pDevice, rq); - clear_bit(0, (void *)&(pMgmt->uCmdBusy)); - break; - - case IOCTL_CMD_HOSTAPD: - - rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data); - break; - - case IOCTL_CMD_WPA: - - rc = wpa_ioctl(pDevice, &wrq->u.data); - break; - - case SIOCETHTOOL: - return ethtool_ioctl(dev, rq->ifr_data); - // All other calls are currently unsupported - - default: - rc = -EOPNOTSUPP; - pr_debug("Ioctl command not support..%x\n", cmd); - - } - - if (pDevice->bCommit) { - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - spin_unlock_irq(&pDevice->lock); - } else { - pr_debug("Commit the settings\n"); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - if (!pDevice->bWPASuppWextEnabled) -#endif - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - } - pDevice->bCommit = false; - } - - return rc; -} - -static int ethtool_ioctl(struct net_device *dev, void __user *useraddr) -{ - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - - strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1); - strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - } - - return -EOPNOTSUPP; -} - static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -3165,7 +1990,6 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) /* Enable the chip specified capabilities */ priv->flags = priv->sOpts.flags | (pChip_info->flags & 0xff000000UL); - priv->tx_80211 = device_dma0_tx_80211; wiphy = priv->hw->wiphy; diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 7302196eda03..53f81f1fefdc 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -723,8 +723,6 @@ vCommandTimer( } else { pDevice->bMoreData = true; } - if (!device_dma0_xmit(pDevice, skb, 0)) - pr_debug("Multicast ps tx fail\n"); pMgmt->sNodeDBTable[0].wEnQueueCnt--; } @@ -746,8 +744,6 @@ vCommandTimer( } else { pDevice->bMoreData = true; } - if (!device_dma0_xmit(pDevice, skb, ii)) - pr_debug("sta ps tx fail\n"); pMgmt->sNodeDBTable[ii].wEnQueueCnt--; // check if sta ps enabled, and wait next pspoll. -- GitLab From 0d24c97093f304fdca68af48e38e91d5ad01daf0 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:22 +0000 Subject: [PATCH 2079/9457] staging: vt6655: dead code remove iwctl.c/h The iw handler and functions are nolonger required. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/iwctl.c | 1858 -------------------------- drivers/staging/vt6655/iwctl.h | 206 --- 4 files changed, 2066 deletions(-) delete mode 100644 drivers/staging/vt6655/iwctl.c delete mode 100644 drivers/staging/vt6655/iwctl.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index f7544a6cb63e..455f088d54cb 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -29,7 +29,6 @@ vt6655_stage-y += device_main.o \ michael.o \ wroute.o \ rf.o \ - iwctl.o \ wpactl.o \ wpa2.o \ aes_ccmp.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 870016ae9905..51b20f3d8e1b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -71,7 +71,6 @@ #include "hostap.h" #include "wpactl.h" #include "ioctl.h" -#include "iwctl.h" #include "dpc.h" #include "datarate.h" #include "rf.h" diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c deleted file mode 100644 index cbcb152a4a0b..000000000000 --- a/drivers/staging/vt6655/iwctl.c +++ /dev/null @@ -1,1858 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iwctl.c - * - * Purpose: wireless ext & ioctl functions - * - * Author: Lyndon Chen - * - * Date: July 5, 2006 - * - * Functions: - * - * Revision History: - * - */ - -#include "device.h" -#include "ioctl.h" -#include "iocmd.h" -#include "iwctl.h" -#include "mac.h" -#include "card.h" -#include "hostap.h" -#include "power.h" -#include "rf.h" - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#include "iowpa.h" -#include "wpactl.h" -#endif - -#include -extern unsigned short TxRate_iwconfig; - -/*--------------------- Static Definitions -------------------------*/ - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#define SUPPORTED_WIRELESS_EXT 18 -#else -#define SUPPORTED_WIRELESS_EXT 17 -#endif - -static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, - 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, - 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, - 5700, 5745, 5765, 5785, 5805, 5825 -}; - -/*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) -{ - struct vnt_private *pDevice = netdev_priv(dev); - long ldBm; - - pDevice->wstats.status = pDevice->op_mode; -#ifdef Calcu_LinkQual - if (pDevice->scStatistic.LinkQuality > 100) - pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual = (unsigned char)pDevice->scStatistic.LinkQuality; -#else - pDevice->wstats.qual.qual = pDevice->byCurrSQ; -#endif - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - pDevice->wstats.qual.level = ldBm; - pDevice->wstats.qual.noise = 0; - pDevice->wstats.qual.updated = 1; - pDevice->wstats.discard.nwid = 0; - pDevice->wstats.discard.code = 0; - pDevice->wstats.discard.fragment = 0; - pDevice->wstats.discard.retries = (unsigned long)pDevice->scStatistic.dwTsrErr; - pDevice->wstats.discard.misc = 0; - pDevice->wstats.miss.beacon = 0; - - return &pDevice->wstats; -} - -/*------------------------------------------------------------------*/ - -static int iwctl_commit(struct net_device *dev, - struct iw_request_info *info, - void *wrq, - char *extra) -{ - pr_debug(" SIOCSIWCOMMIT\n"); - - return 0; -} - -/* Wireless Handler : get protocol name */ -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra) -{ - strcpy(wrq, "802.11-a/b/g"); - return 0; -} - -/* Wireless Handler : set scan */ -static int iwctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct iw_scan_req *req = (struct iw_scan_req *)extra; - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - PWLAN_IE_SSID pItemSSID = NULL; - - pr_debug(" SIOCSIWSCAN\n"); - - if (pDevice->byReAssocCount > 0) { /* reject scan when re-associating! */ -/* send scan event to wpa_Supplicant */ - union iwreq_data wrqu; - - PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - return 0; - } - - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - -/* active scan OR passive scan OR desire_ssid scan */ - if (wrq->length == sizeof(struct iw_scan_req)) { - if (wrq->flags & IW_SCAN_THIS_ESSID) { /* desire_ssid scan */ - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)abyScanSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); - if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { - if (req->essid_len > 0) - pItemSSID->len = req->essid_len - 1; - } else - pItemSSID->len = req->essid_len; - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID, - ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - spin_unlock_irq(&pDevice->lock); - - return 0; - } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { /* passive scan */ - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - } - } else { /* active scan */ - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - } - - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* Wireless Handler : get scan results */ -static int iwctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - int ii, jj, kk; - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PKnownBSS pBSS; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; - char *current_ev = extra; - char *end_buf = extra + IW_SCAN_MAX_DATA; - char *current_val = NULL; - struct iw_event iwe; - long ldBm; - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - pr_debug(" SIOCGIWSCAN\n"); - - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - /* In scanning.. */ - return -EAGAIN; - } - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { - if (current_ev >= end_buf) - break; - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - /* ADD mac address */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); - /* ADD ssid */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - iwe.u.data.length = pItemSSID->len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); - /* ADD mode */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - /* ADD frequency */ - pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; - pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = pBSS->uChannel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - { - int f = (int)pBSS->uChannel - 1; - - if (f < 0)f = 0; - iwe.u.freq.m = frequency_list[f] * 100000; - iwe.u.freq.e = 1; - } - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - /* ADD quality */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); - iwe.u.qual.level = ldBm; - iwe.u.qual.noise = 0; - if (-ldBm < 50) - iwe.u.qual.qual = 100; - else if (-ldBm > 90) - iwe.u.qual.qual = 0; - else - iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40; - - iwe.u.qual.updated = 7; - - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - iwe.u.data.length = 0; - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - current_val = current_ev + IW_EV_LCP_LEN; - - for (kk = 0; kk < 12; kk++) { - if (pSuppRates->abyRates[kk] == 0) - break; - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - for (kk = 0; kk < 8; kk++) { - if (pExtSuppRates->abyRates[kk] == 0) - break; - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); - current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); - } - - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf); - - if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wWPALen; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE); - } - - if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = pBSS->wRSNLen; - current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE); - } - - } - } - - wrq->length = current_ev - extra; - return 0; -} - -/* Wireless Handler : set frequency or channel */ -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWFREQ\n"); - - /* If setting by frequency, convert to a channel */ - if ((wrq->e == 1) && - (wrq->m >= (int) 2.412e8) && - (wrq->m <= (int) 2.487e8)) { - int f = wrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != frequency_list[c])) - c++; - wrq->e = 0; - wrq->m = c + 1; - } - /* Setting by channel number */ - if ((wrq->m > 14) || (wrq->e > 0)) - rc = -EOPNOTSUPP; - else { - int channel = wrq->m; - - if ((channel < 1) || (channel > 14)) { - pr_debug("%s: New channel value of %d is invalid!\n", - dev->name, wrq->m); - rc = -EINVAL; - } else { - /* Yes ! We can set it !!! */ - pr_debug(" Set to channel = %d\n", channel); - pDevice->uChannel = channel; - /* Make change effect at once */ - pDevice->bCommit = true; - } - } - - return rc; -} - -/* Wireless Handler : get frequency or channel */ -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWFREQ\n"); - -#ifdef WEXT_USECHANNELS - wrq->m = (int)pMgmt->uCurrChannel; - wrq->e = 0; -#else - { - int f = (int)pMgmt->uCurrChannel - 1; - - if (f < 0) - f = 0; - wrq->m = frequency_list[f] * 100000; - wrq->e = 1; - } -#endif - - return 0; -} - -/* Wireless Handler : set operation mode */ -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - - pr_debug(" SIOCSIWMODE\n"); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { - pr_debug("Can't set operation mode, hostapd is running\n"); - return rc; - } - - switch (*wmode) { - case IW_MODE_ADHOC: - if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to ad-hoc\n"); - break; - case IW_MODE_AUTO: - case IW_MODE_INFRA: - if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - pr_debug("set mode to infrastructure\n"); - break; - case IW_MODE_MASTER: - - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - rc = -EOPNOTSUPP; - break; - - case IW_MODE_REPEAT: - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - rc = -EOPNOTSUPP; - break; - default: - rc = -EINVAL; - } - - return rc; -} - -/* Wireless Handler : get operation mode */ -int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWMODE\n"); - /* If not managed, assume it's ad-hoc */ - switch (pMgmt->eConfigMode) { - case WMAC_CONFIG_ESS_STA: - *wmode = IW_MODE_INFRA; - break; - case WMAC_CONFIG_IBSS_STA: - *wmode = IW_MODE_ADHOC; - break; - case WMAC_CONFIG_AUTO: - *wmode = IW_MODE_INFRA; - break; - case WMAC_CONFIG_AP: - *wmode = IW_MODE_MASTER; - break; - default: - *wmode = IW_MODE_ADHOC; - } - - return 0; -} - -/* Wireless Handler : get capability range */ -int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - int i, k; - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - - pr_debug(" SIOCGIWRANGE\n"); - if (wrq->pointer) { - wrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - range->min_nwid = 0x0000; - range->max_nwid = 0x0000; - range->num_channels = 14; - /* - * Should be based on cap_rid.country to give only - * what the current card supports - */ - k = 0; - for (i = 0; i < 14; i++) { - range->freq[k].i = i + 1; /* List index */ - range->freq[k].m = frequency_list[i] * 100000; - range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ - } - range->num_frequency = k; - /* Hum... Should put the right values there */ -#ifdef Calcu_LinkQual - range->max_qual.qual = 100; -#else - range->max_qual.qual = 255; -#endif - range->max_qual.level = 0; - range->max_qual.noise = 0; - range->sensitivity = 255; - - for (i = 0; i < 13; i++) { - range->bitrate[i] = abySupportedRates[i] * 500000; - if (range->bitrate[i] == 0) - break; - } - range->num_bitrates = i; - - /* - * Set an indication of the max TCP throughput in bit/s that we - * can expect using this interface. May be used for QoS stuff - */ - if (i > 2) - range->throughput = 5 * 1000 * 1000; - else - range->throughput = 1.5 * 1000 * 1000; - - range->min_rts = 0; - range->max_rts = 2312; - range->min_frag = 256; - range->max_frag = 2312; - - /* the encoding capabilities */ - range->num_encoding_sizes = 3; - /* 64(40) bits WEP */ - range->encoding_size[0] = 5; - /* 128(104) bits WEP */ - range->encoding_size[1] = 13; - /* 256 bits for WPA-PSK */ - range->encoding_size[2] = 32; - /* 4 keys are allowed */ - range->max_encoding_tokens = 4; - - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - range->min_pmp = 0; - range->max_pmp = 1000000; /* 1 secs */ - range->min_pmt = 0; - range->max_pmt = 1000000; /* 1 secs */ - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - - /* Transmit Power - values are in mW */ - - range->txpower[0] = 100; - range->num_txpower = 1; - range->txpower_capa = IW_TXPOW_MWATT; - range->we_version_source = SUPPORTED_WIRELESS_EXT; - range->we_version_compiled = WIRELESS_EXT; - range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = IW_RETRY_LIFETIME; - range->min_retry = 1; - range->max_retry = 65535; - range->min_r_time = 1024; - range->max_r_time = 65535 * 1024; - /* - * Experimental measurements - boundary 11/5.5 Mb/s - * Note : with or without the (local->rssi), results - * are somewhat different. - Jean II - */ - range->avg_qual.qual = 6; - range->avg_qual.level = 176; /* -80 dBm */ - range->avg_qual.noise = 0; - } - - return 0; -} - -/* Wireless Handler : set ap mac address */ -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - pr_debug(" SIOCSIWAP\n"); - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - /* In scanning.. */ - pr_debug("SIOCSIWAP(??)-->In scanning..\n"); - } - if (wrq->sa_family != ARPHRD_ETHER) - rc = -EINVAL; - else { - memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); - if ((pDevice->bLinkPass == true) && - (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6) == 0)) { - return rc; - } - if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || - (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) { - PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); - return rc; - } - /* if desired AP is hidden ssid(there are two same BSSID in - * list), then ignore,because you don't known which one - * to be connected with?? - */ - { - unsigned int ii, uSameBssidNum = 0; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pMgmt->abyDesireBSSID)) { - uSameBssidNum++; - } - } - if (uSameBssidNum >= 2) { /* hit: desired AP is in hidden ssid mode!!! */ - PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); - return rc; - } - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - } - return rc; -} - -/* Wireless Handler : get ap mac address */ -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWAP\n"); - - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) - memset(wrq->sa_data, 0, 6); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) - memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); - - wrq->sa_family = ARPHRD_ETHER; - - return 0; -} - -/* Wireless Handler : get ap list */ -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - int ii, jj, rc = 0; - struct sockaddr *sock = NULL; - struct sockaddr *s = NULL; - struct iw_quality *qual = NULL; - struct iw_quality *q = NULL; - PKnownBSS pBSS = NULL; - - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pr_debug(" SIOCGIWAPLIST\n"); - - if (!capable(CAP_NET_ADMIN)) { - rc = -EPERM; - goto exit; - } - - if (!wrq->pointer) - goto exit; - - sock = kmalloc_array(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL); - if (!sock) { - rc = -ENOMEM; - goto exit; - } - - qual = kmalloc_array(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL); - if (!qual) { - rc = -ENOMEM; - goto exit; - } - - for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - - if (!pBSS->bActive) - continue; - if (jj >= IW_MAX_AP) - break; - - s = &sock[jj]; - q = &qual[jj]; - - memcpy(s->sa_data, pBSS->abyBSSID, 6); - s->sa_family = ARPHRD_ETHER; - q->level = pBSS->uRSSI; - q->qual = 0; - q->noise = 0; - q->updated = 2; - jj++; - } - - wrq->flags = 1; /* Should be define'd */ - wrq->length = jj; - memcpy(extra, sock, sizeof(struct sockaddr) * jj); - memcpy(extra + sizeof(struct sockaddr) * jj, - qual, - sizeof(struct iw_quality) * jj); -exit: - kfree(sock); - kfree(qual); - return rc; -} - -/* Wireless Handler : set essid */ -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - unsigned char len; - - pr_debug(" SIOCSIWESSID\n"); - pDevice->fWPA_Authened = false; - if (pMgmt->eScanState == WMAC_IS_SCANNING) { - /* In scanning.. */ - pr_debug("SIOCSIWESSID(??)-->In scanning..\n"); - } - /* Check if we asked for 'any' */ - if (wrq->flags == 0) { - /* Just send an empty SSID list */ - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - PRINT_K("set essid to 'any'\n"); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - return 0; -#endif - } else { - /* Set the SSID */ - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - - memcpy(pItemSSID->abySSID, extra, wrq->length); - if (pItemSSID->abySSID[wrq->length - 1] == '\0') { - if (wrq->length > 0) - pItemSSID->len = wrq->length - 1; - } else - pItemSSID->len = wrq->length; - pr_debug("set essid to %s\n", pItemSSID->abySSID); - len = (pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) ? pItemSSID->len : ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; - if ((pDevice->bLinkPass == true) && - (memcmp(pItemSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, len) == 0)) - return 0; - - /* need clear desiredBSSID */ - if (pItemSSID->len == 0) { - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - return 0; - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - /* - * Wext wil order another command of siwap to link with desired - * AP, so here need not associate?? - */ - if (pDevice->bWPASuppWextEnabled == true) { - /*******search if in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned int ii, uSameBssidNum = 0; - - memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID)); - pCurr = BSSpSearchBSSList(pDevice, - NULL, - abyTmpDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } else { /* - * to find out if that desired SSID - * is a hidden-ssid AP, by means of - * judging if there are two same - * BSSID exist in list ? - */ - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pCurr->abyBSSID)) { - uSameBssidNum++; - } - } - if (uSameBssidNum >= 2) { /* hit: desired AP is in hidden ssid mode!!! */ - pr_debug("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((void *)pDevice); - pMgmt->eScanType = WMAC_SCAN_PASSIVE; /* this scan type, you'll submit scan result! */ - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); - } - } - } - return 0; - } -#endif - - pr_debug("set essid = %s\n", pItemSSID->abySSID); - } - - if (pDevice->flags & DEVICE_FLAGS_OPENED) - pDevice->bCommit = true; - - return 0; -} - -/* Wireless Handler : get essid */ -int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - - pr_debug(" SIOCGIWESSID\n"); - - /* - * Note : if wrq->u.data.flags != 0, we should get the relevant SSID - * from the SSID list... - */ - - /* Get the current SSID */ - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - memcpy(extra, pItemSSID->abySSID , pItemSSID->len); - extra[pItemSSID->len] = '\0'; - wrq->length = pItemSSID->len + 1; - wrq->length = pItemSSID->len; - wrq->flags = 1; /* active */ - - return 0; -} - -/* Wireless Handler : set data rate */ -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - u8 brate = 0; - int i; - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - - pr_debug(" SIOCSIWRATE\n"); - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } - - /* First : get a valid bit rate value */ - - /* Which type of value */ - if ((wrq->value < 13) && - (wrq->value >= 0)) { - /* Setting by rate index, Find value in the magic rate table */ - brate = wrq->value; - } else { - /* Setting by frequency value */ - u8 normvalue = (u8) (wrq->value/500000); - - /* Check if rate is valid */ - for (i = 0; i < 13; i++) { - if (normvalue == abySupportedRates[i]) { - brate = i; - break; - } - } - } - /* -1 designed the max rate (mostly auto mode) */ - if (wrq->value == -1) { - /* Get the highest available rate */ - for (i = 0; i < 13; i++) { - if (abySupportedRates[i] == 0) - break; - } - if (i != 0) - brate = i - 1; - - } - /* Check that it is valid, brate is index of abySupportedRates[] */ - if (brate > 13) { - rc = -EINVAL; - return rc; - } - - /* Now, check if we want a fixed or auto value */ - if (wrq->fixed != 0) { - /* Fixed mode, One rate, fixed */ - pr_debug("Rate Fix\n"); - pDevice->bFixRate = true; - if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) { - pDevice->uConnectionRate = 3; - } else { - pDevice->uConnectionRate = brate; - pr_debug("Fixed to Rate %d\n", - pDevice->uConnectionRate); - } - - } else { - pDevice->bFixRate = false; - pDevice->uConnectionRate = 13; - pr_debug("auto rate:connection_rate is 13\n"); - } - - return rc; -} - -/* Wireless Handler : get data rate */ -int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); -/* Mark the unnecessary sentences. */ - pr_debug(" SIOCGIWRATE\n"); - { - unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - int brate = 0; - if (pDevice->bLinkPass) { - if (pDevice->bFixRate == true) { - if (pDevice->uConnectionRate < 13) { - brate = abySupportedRates[pDevice->uConnectionRate]; - } else { - if (pDevice->byBBType == BB_TYPE_11B) - brate = 0x16; - if (pDevice->byBBType == BB_TYPE_11G) - brate = 0x6C; - if (pDevice->byBBType == BB_TYPE_11A) - brate = 0x6C; - } - } else { - brate = abySupportedRates[TxRate_iwconfig]; - } - } else brate = 0; - - wrq->value = brate * 500000; - /* If more than one rate, set auto */ - if (pDevice->bFixRate == true) - wrq->fixed = true; - } - - return 0; -} - -/* Wireless Handler : set rts threshold */ -int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWRTS\n"); - - { - int rthr = wrq->value; - - if (wrq->disabled) - rthr = 2312; - - if ((rthr < 0) || (rthr > 2312)) - rc = -EINVAL; - else - pDevice->wRTSThreshold = rthr; - } - - return 0; -} - -/* Wireless Handler : get rts */ -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWRTS\n"); - wrq->value = pDevice->wRTSThreshold; - wrq->disabled = (wrq->value >= 2312); - wrq->fixed = 1; - - return 0; -} - -/* Wireless Handler : set fragment threshold */ -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - int fthr = wrq->value; - - pr_debug(" SIOCSIWFRAG\n"); - - if (wrq->disabled) - fthr = 2312; - if ((fthr < 256) || (fthr > 2312)) { - rc = -EINVAL; - } else { - fthr &= ~0x1; /* Get an even value */ - pDevice->wFragmentationThreshold = (u16)fthr; - } - - return rc; -} - -/* Wireless Handler : get fragment threshold */ -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWFRAG\n"); - wrq->value = pDevice->wFragmentationThreshold; - wrq->disabled = (wrq->value >= 2312); - wrq->fixed = 1; - - return 0; -} - -/* Wireless Handler : set retry threshold */ -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - int rc = 0; - - pr_debug(" SIOCSIWRETRY\n"); - - if (wrq->disabled) { - rc = -EINVAL; - return rc; - } - - if (wrq->flags & IW_RETRY_LIMIT) { - if (wrq->flags & IW_RETRY_MAX) - pDevice->byLongRetryLimit = wrq->value; - else if (wrq->flags & IW_RETRY_MIN) - pDevice->byShortRetryLimit = wrq->value; - else { - /* No modifier : set both */ - pDevice->byShortRetryLimit = wrq->value; - pDevice->byLongRetryLimit = wrq->value; - } - } - if (wrq->flags & IW_RETRY_LIFETIME) - pDevice->wMaxTransmitMSDULifetime = wrq->value; - - return rc; -} - -/* Wireless Handler : get retry threshold */ -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - - pr_debug(" SIOCGIWRETRY\n"); - wrq->disabled = 0; /* Can't be disabled */ - - /* Note : by default, display the min retry number */ - if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - wrq->flags = IW_RETRY_LIFETIME; - wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; /* ms */ - } else if ((wrq->flags & IW_RETRY_MAX)) { - wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - wrq->value = (int)pDevice->byLongRetryLimit; - } else { - wrq->flags = IW_RETRY_LIMIT; - wrq->value = (int)pDevice->byShortRetryLimit; - if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) - wrq->flags |= IW_RETRY_MIN; - } - - return 0; -} - -/* Wireless Handler : set encode mode */ -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - unsigned long dwKeyIndex = (unsigned long)(wrq->flags & IW_ENCODE_INDEX); - int ii, uu, rc = 0; - int index = (wrq->flags & IW_ENCODE_INDEX); - -/* - * There are some problems when using iwconfig encode/key command to set the - * WEP key. I almost rewrite this function. Now it supports: (assume the - * wireless interface's name is eth0) - * iwconfig eth0 key [1] 1122334455 open -> set key stirng to index 1, and - driver using key index is set to 1 - * iwconfig eth0 key [3] -> set driver using key index to 3,the key string no change - * iwconfig eth0 key 1122334455 -> set key string to driver using index - * iwconfig eth0 key restricted -> enable share key - */ - - PSKeyTable pkeytab; - - pr_debug(" SIOCSIWENCODE\n"); - - if ((wrq->flags & IW_ENCODE_DISABLED) == 0) { - /* Not disable encryption */ - - if (dwKeyIndex > WLAN_WEP_NKEYS) { - rc = -EINVAL; - return rc; - } - - if (dwKeyIndex < 1 && ((wrq->flags & IW_ENCODE_NOKEY) == 0)) { /* set default key */ - if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) - dwKeyIndex = pDevice->byKeyIndex; - else - dwKeyIndex = 0; - } else { - dwKeyIndex--; - } - - /* Check the size of the key */ - if (wrq->length > WLAN_WEP232_KEYLEN) { - rc = -EINVAL; - return rc; - } - - if (wrq->length > 0) { /* have key */ - - if (wrq->length == WLAN_WEP232_KEYLEN) { - pr_debug("Set 232 bit wep key\n"); - } else if (wrq->length == WLAN_WEP104_KEYLEN) { - pr_debug("Set 104 bit wep key\n"); - } else if (wrq->length == WLAN_WEP40_KEYLEN) { - pr_debug("Set 40 bit wep key, index= %d\n", - (int)dwKeyIndex); - } else { /* no support length */ - rc = -EINVAL; - return rc; - } - memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); - memcpy(pDevice->abyKey, extra, wrq->length); - - pr_debug("abyKey: "); - for (ii = 0; ii < wrq->length; ii++) - pr_debug("%02x ", pDevice->abyKey[ii]); - - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - KeybSetDefaultKey(&(pDevice->sKey), - (unsigned long)(dwKeyIndex | (1 << 31)), - wrq->length, - NULL, - pDevice->abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID -); - spin_unlock_irq(&pDevice->lock); - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->uKeyLength = wrq->length; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - - } else if (index > 0) { - /* - * when the length is 0 the request only changes the - * default transmit key index, check the new key if it - * has a non zero length - */ - if (pDevice->bEncryptionEnable == false) { - rc = -EINVAL; - return rc; - } - pr_debug("Just set Default key Index:\n"); - pkeytab = &(pDevice->sKey.KeyTable[MAX_KEY_TABLE - 1]); - if (pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength == 0) { - pr_debug("Default key len is 0\n"); - rc = -EINVAL; - return rc; - } - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pkeytab->dwGTKeyIndex = dwKeyIndex | (1 << 31); - pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex = dwKeyIndex | (1 << 31); - } - - } else { /* disable the key */ - pr_debug("Disable WEP function\n"); - if (pDevice->bEncryptionEnable == false) - return 0; - pMgmt->bShareKeyAlgorithm = false; - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - if (pDevice->flags & DEVICE_FLAGS_OPENED) { - spin_lock_irq(&pDevice->lock); - for (uu = 0; uu < MAX_KEY_TABLE; uu++) - MACvDisableKeyEntry(pDevice->PortOffset, uu); - spin_unlock_irq(&pDevice->lock); - } - } - - if (wrq->flags & IW_ENCODE_RESTRICTED) { - pr_debug("Enable WEP & ShareKey System\n"); - pMgmt->bShareKeyAlgorithm = true; - } - if (wrq->flags & IW_ENCODE_OPEN) { - pr_debug("Enable WEP & Open System\n"); - pMgmt->bShareKeyAlgorithm = false; - } - return rc; -} - -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - char abyKey[WLAN_WEP232_KEYLEN]; - - unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); - PSKeyItem pKey = NULL; - - pr_debug(" SIOCGIWENCODE\n"); - - if (index > WLAN_WEP_NKEYS) - return -EINVAL; - - if (index < 1) { /* get default key */ - if (pDevice->byKeyIndex < WLAN_WEP_NKEYS) - index = pDevice->byKeyIndex; - else - index = 0; - } else { - index--; - } - - memset(abyKey, 0, WLAN_WEP232_KEYLEN); - /* Check encryption mode */ - wrq->flags = IW_ENCODE_NOKEY; - /* Is WEP enabled ??? */ - if (pDevice->bEncryptionEnable) - wrq->flags |= IW_ENCODE_ENABLED; - else - wrq->flags |= IW_ENCODE_DISABLED; - - if (pMgmt->bShareKeyAlgorithm) - wrq->flags |= IW_ENCODE_RESTRICTED; - else - wrq->flags |= IW_ENCODE_OPEN; - wrq->length = 0; - - if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled || - pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) { /* get wpa pairwise key */ - if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) { - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)) { - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - } - - wrq->flags |= index+1; - - return 0; -} - -/* Wireless Handler : set power mode */ -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int rc = 0; - - pr_debug(" SIOCSIWPOWER\n"); - - if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { - rc = -EINVAL; - return rc; - } - - if (wrq->disabled) { - pDevice->ePSMode = WMAC_POWER_CAM; - PSvDisablePowerSaving(pDevice); - return rc; - } - if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - - } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - } - switch (wrq->flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - pr_debug(" SIOCSIWPOWER: IW_POWER_UNICAST_R\n"); - rc = -EINVAL; - break; - case IW_POWER_ALL_R: - pr_debug(" SIOCSIWPOWER: IW_POWER_ALL_R\n"); - rc = -EINVAL; - case IW_POWER_ON: - pr_debug(" SIOCSIWPOWER: IW_POWER_ON\n"); - break; - default: - rc = -EINVAL; - } - - return rc; -} - -/* Wireless Handler : get power mode */ -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int mode = pDevice->ePSMode; - - pr_debug(" SIOCGIWPOWER\n"); - - wrq->disabled = (mode == WMAC_POWER_CAM); - if (wrq->disabled) - return 0; - - if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); - wrq->flags = IW_POWER_TIMEOUT; - } else { - wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); - wrq->flags = IW_POWER_PERIOD; - } - wrq->flags |= IW_POWER_ALL_R; - - return 0; -} - -/* Wireless Handler : get Sensitivity */ -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - long ldBm; - - pr_debug(" SIOCGIWSENS\n"); - if (pDevice->bLinkPass == true) { - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - wrq->value = ldBm; - } else { - wrq->value = 0; - } - wrq->disabled = (wrq->value == 0); - wrq->fixed = 1; - - return 0; -} - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - static int wpa_version = 0; /* must be static to save the last value */ - static int pairwise = 0; - - pr_debug(" SIOCSIWAUTH\n"); - switch (wrq->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - wpa_version = wrq->value; - if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) - PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); - else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) - PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); - else - PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); - - break; - case IW_AUTH_CIPHER_PAIRWISE: - pairwise = wrq->value; - if (pairwise == IW_AUTH_CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else if (pairwise == IW_AUTH_CIPHER_TKIP) - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - else if (pairwise == IW_AUTH_CIPHER_WEP40 || pairwise == IW_AUTH_CIPHER_WEP104) - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - else if (pairwise == IW_AUTH_CIPHER_NONE) - ; /* do nothing */ - else - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - - break; - case IW_AUTH_CIPHER_GROUP: - if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED) - break; - if (pairwise == IW_AUTH_CIPHER_NONE) { - if (wrq->value == IW_AUTH_CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - } - break; - case IW_AUTH_KEY_MGMT: - - if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) { - if (wrq->value == IW_AUTH_KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) { - if (wrq->value == 0) - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - else if (wrq->value == IW_AUTH_KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA; - } - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - break; /* FIXME */ - case IW_AUTH_DROP_UNENCRYPTED: - break; - case IW_AUTH_80211_AUTH_ALG: - if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM) - pMgmt->bShareKeyAlgorithm = false; - else if (wrq->value == IW_AUTH_ALG_SHARED_KEY) - pMgmt->bShareKeyAlgorithm = true; - - break; - case IW_AUTH_WPA_ENABLED: - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_ROAMING_CONTROL: - ret = -EOPNOTSUPP; - break; - case IW_AUTH_PRIVACY_INVOKED: - pDevice->bEncryptionEnable = !!wrq->value; - if (pDevice->bEncryptionEnable == false) { - wpa_version = 0; - pairwise = 0; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - pMgmt->bShareKeyAlgorithm = false; - pMgmt->eAuthenMode = false; - } - - break; - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - return -EOPNOTSUPP; -} - -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - char length; - - if (wrq->length) { - if (wrq->length < 2) - return -EINVAL; - - ret = get_user(length, extra + 1); - if (ret) - return ret; - - if (length + 2 != wrq->length) - return -EINVAL; - - if (wrq->length > MAX_WPA_IE_LEN) { - ret = -ENOMEM; - goto out; - } - memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)) { - ret = -EFAULT; - goto out; - } - pMgmt->wWPAIELen = wrq->length; - } else { - memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); - pMgmt->wWPAIELen = 0; - } - -out: /* not completely ...not necessary in wpa_supplicant 0.5.8 */ - return ret; -} - -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - int space = wrq->length; - - wrq->length = 0; - if (pMgmt->wWPAIELen > 0) { - wrq->length = pMgmt->wWPAIELen; - if (pMgmt->wWPAIELen <= space) { - if (copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)) - ret = -EFAULT; - - } else { - ret = -E2BIG; - } - } - - return ret; -} - -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct viawget_wpa_param *param = NULL; -/* original member */ - enum wpa_alg alg_name; - u8 addr[6]; - int key_idx, set_tx = 0; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 key[64]; - size_t seq_len = 0, key_len = 0; - - u8 key_array[64]; - int ret = 0; - - PRINT_K("SIOCSIWENCODEEXT......\n"); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - -/* recover alg_name */ - switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = WPA_ALG_NONE; - break; - case IW_ENCODE_ALG_WEP: - alg_name = WPA_ALG_WEP; - break; - case IW_ENCODE_ALG_TKIP: - alg_name = WPA_ALG_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - alg_name = WPA_ALG_CCMP; - break; - default: - PRINT_K("Unknown alg = %d\n", ext->alg); - ret = -ENOMEM; - goto error; - } -/* recover addr */ - ether_addr_copy(addr, ext->addr.sa_data); -/* recover key_idx */ - key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; -/* recover set_tx */ - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - set_tx = 1; -/* recover seq,seq_len */ - if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - seq_len = IW_ENCODE_SEQ_MAX_SIZE; - memcpy(seq, ext->rx_seq, seq_len); - } -/* recover key,key_len */ - if (ext->key_len) { - key_len = ext->key_len; - memcpy(key, &ext->key[0], key_len); - } - - memset(key_array, 0, 64); - if (key_len > 0) { - memcpy(key_array, key, key_len); - if (key_len == 32) { - /* notice ! the oder */ - memcpy(&key_array[16], &key[24], 8); - memcpy(&key_array[24], &key[16], 8); - } - } - -/**************Translate iw_encode_ext to viawget_wpa_param****************/ - ether_addr_copy(param->addr, addr); - param->u.wpa_key.alg_name = (int)alg_name; - param->u.wpa_key.set_tx = set_tx; - param->u.wpa_key.key_index = key_idx; - param->u.wpa_key.key_len = key_len; - param->u.wpa_key.key = (u8 *)key_array; - param->u.wpa_key.seq = (u8 *)seq; - param->u.wpa_key.seq_len = seq_len; - -/* - * set if current action is Network Manager count?? this method is so - * foolish,but there is no other way??? - */ - if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { - if (param->u.wpa_key.key_index == 0) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 1) && (param->u.wpa_key.key_index == 1)) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 2) && (param->u.wpa_key.key_index == 2)) - pDevice->bwextcount++; - - if ((pDevice->bwextcount == 3) && (param->u.wpa_key.key_index == 3)) - pDevice->bwextcount++; - - } - if (pDevice->bwextcount == 4) { - pr_debug("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = true; - } - - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, true); - spin_unlock_irq(&pDevice->lock); - -error: - kfree(param); - return ret; -} - -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra) -{ - return -EOPNOTSUPP; -} - -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra) -{ - struct vnt_private *pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct iw_mlme mime; - - int ret = 0; - - ret = copy_from_user(&mime, extra, sizeof(mime)); - if (ret) - return -EFAULT; - - if (memcmp(pMgmt->abyCurrBSSID, mime.addr.sa_data, ETH_ALEN)) { - ret = -EINVAL; - return ret; - } - switch (mime.cmd) { - case IW_MLME_DEAUTH: - /* - * this command seems to be not complete,please test it --einsnliu - * bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); - */ - break; - case IW_MLME_DISASSOC: - if (pDevice->bLinkPass == true) { - pr_debug("iwctl_siwmlme--->send DISASSOCIATE\n"); - /* clear related flags */ - memset(pMgmt->abyDesireBSSID, 0xFF, 6); - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - } - break; - default: - ret = -EOPNOTSUPP; - } - - return ret; -} - -#endif - -/* Structures to export the Wireless Handlers */ -static const iw_handler iwctl_handler[] = -{ - (iw_handler) iwctl_commit, /* SIOCSIWCOMMIT */ - (iw_handler) NULL, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) NULL, /* SIOCSIWFREQ */ - (iw_handler) NULL, /* SIOCGIWFREQ */ - (iw_handler) NULL, /* SIOCSIWMODE */ - (iw_handler) NULL, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) iwctl_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL, /* SIOCSIWPRIV */ - (iw_handler) NULL, /* SIOCGIWPRIV */ - (iw_handler) NULL, /* SIOCSIWSTATS */ - (iw_handler) NULL, /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWAP */ - (iw_handler) NULL, /* SIOCGIWAP */ - (iw_handler) NULL, /* -- hole -- 0x16 */ - (iw_handler) NULL, /* SIOCGIWAPLIST */ - (iw_handler) iwctl_siwscan, /* SIOCSIWSCAN */ - (iw_handler) iwctl_giwscan, /* SIOCGIWSCAN */ - (iw_handler) NULL, /* SIOCSIWESSID */ - (iw_handler) NULL, /* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) NULL, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWRATE 0x20 */ - (iw_handler) NULL, /* SIOCGIWRATE */ - (iw_handler) NULL, /* SIOCSIWRTS */ - (iw_handler) NULL, /* SIOCGIWRTS */ - (iw_handler) NULL, /* SIOCSIWFRAG */ - (iw_handler) NULL, /* SIOCGIWFRAG */ - (iw_handler) NULL, /* SIOCSIWTXPOW */ - (iw_handler) NULL, /* SIOCGIWTXPOW */ - (iw_handler) NULL, /* SIOCSIWRETRY */ - (iw_handler) NULL, /* SIOCGIWRETRY */ - (iw_handler) NULL, /* SIOCSIWENCODE */ - (iw_handler) NULL, /* SIOCGIWENCODE */ - (iw_handler) NULL, /* SIOCSIWPOWER */ - (iw_handler) NULL, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWGENIE */ - (iw_handler) NULL, /* SIOCGIWGENIE */ - (iw_handler) NULL, /* SIOCSIWAUTH */ - (iw_handler) NULL, /* SIOCGIWAUTH */ - (iw_handler) NULL, /* SIOCSIWENCODEEXT */ - (iw_handler) NULL, /* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ - (iw_handler) NULL, /* -- hole -- */ -}; - -static const iw_handler iwctl_private_handler[] = -{ - NULL, /* SIOCIWFIRSTPRIV */ -}; - -struct iw_priv_args iwctl_private_args[] = { - { IOCTL_CMD_SET, - IW_PRIV_TYPE_CHAR | 1024, 0, - "set"}, -}; - -const struct iw_handler_def iwctl_handler_def = -{ - .get_wireless_stats = &iwctl_get_wireless_stats, - .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), - .num_private = 0, - .num_private_args = 0, - .standard = (iw_handler *)iwctl_handler, - .private = NULL, - .private_args = NULL, -}; diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h deleted file mode 100644 index 7dd63102182d..000000000000 --- a/drivers/staging/vt6655/iwctl.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iwctl.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2004 - * - */ - -#ifndef __IWCTL_H__ -#define __IWCTL_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev); - -int iwctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -int iwctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *wmode, - char *extra); - -int iwctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *wrq, - char *extra); - -int iwctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *wrq, - char *extra); - -int iwctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *wrq, - char *extra); - -int iwctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -//2008-0409-07, by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -int iwctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - -int iwctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); - -int iwctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); - -int iwctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char *extra); - -int iwctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *wrq, - char __user *extra); -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, by Einsn Liu - -extern const struct iw_handler_def iwctl_handler_def; -extern struct iw_priv_args iwctl_private_args[]; - -#endif // __IWCTL_H__ -- GitLab From ae1927eb348908ea92eb9ce8c452e053a4830adf Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:23 +0000 Subject: [PATCH 2080/9457] staging: vt6655: dead code remove ioctl.c/h The driver nolonger supports these io functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/ioctl.c | 582 --------------------------- drivers/staging/vt6655/ioctl.h | 36 -- 4 files changed, 620 deletions(-) delete mode 100644 drivers/staging/vt6655/ioctl.c delete mode 100644 drivers/staging/vt6655/ioctl.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 455f088d54cb..6e9349976174 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -21,7 +21,6 @@ vt6655_stage-y += device_main.o \ rc4.o \ tether.o \ tcrc.o \ - ioctl.o \ hostap.o \ wpa.o \ key.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 51b20f3d8e1b..5b54cabdc863 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -70,7 +70,6 @@ #include "bssdb.h" #include "hostap.h" #include "wpactl.h" -#include "ioctl.h" #include "dpc.h" #include "datarate.h" #include "rf.h" diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c deleted file mode 100644 index c2b6763c8ab9..000000000000 --- a/drivers/staging/vt6655/ioctl.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: ioctl.c - * - * Purpose: private ioctl functions - * - * Author: Lyndon Chen - * - * Date: Auguest 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "ioctl.h" -#include "iocmd.h" -#include "mac.h" -#include "card.h" -#include "hostap.h" -#include "wpactl.h" -#include "rf.h" - -int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) -{ - PSCmdRequest pReq = (PSCmdRequest)rq; - PSMgmtObject pMgmt = pDevice->pMgmt; - int result = 0; - PWLAN_IE_SSID pItemSSID; - SCmdBSSJoin sJoinCmd; - SCmdScan sScanCmd; - SCmdStartAP sStartAPCmd; - SCmdSetWEP sWEPCmd; - SCmdValue sValue; - SBSSIDList sList; - SNodeList sNodeList; - PSBSSIDList pList; - PSNodeList pNodeList; - unsigned int cbListCount; - PKnownBSS pBSS; - PKnownNodeDB pNode; - unsigned int ii, jj; - unsigned char abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned long dwKeyIndex = 0; - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - long ldBm; - - pReq->wResult = 0; - - switch (pReq->wCmdCode) { - case WLAN_CMD_BSS_SCAN: - pr_debug("WLAN_CMD_BSS_SCAN..begin\n"); - if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) { - result = -EFAULT; - break; - } - - pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - if (pItemSSID->len != 0) { - memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - } - - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - spin_lock_irq(&pDevice->lock); - if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((void *)pDevice, false); - else - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - - if (pItemSSID->len != 0) - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - else - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_ZONETYPE_SET: - /* mike add :can't support. */ - result = -EOPNOTSUPP; - break; - - case WLAN_CMD_BSS_JOIN: - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - - if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { - result = -EFAULT; - break; - } - - pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - if (sJoinCmd.wBSSType == ADHOC) { - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - pr_debug("ioct set to adhoc mode\n"); - } else { - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - pr_debug("ioct set to STA mode\n"); - } - if (sJoinCmd.bPSEnable == true) { - pDevice->ePSMode = WMAC_POWER_FAST; - pMgmt->wListenInterval = 2; - pr_debug("Power Saving On\n"); - } else { - pDevice->ePSMode = WMAC_POWER_CAM; - pMgmt->wListenInterval = 1; - pr_debug("Power Saving Off\n"); - } - - if (sJoinCmd.bShareKeyAuth == true) { - pMgmt->bShareKeyAlgorithm = true; - pr_debug("Share Key\n"); - } else { - pMgmt->bShareKeyAlgorithm = false; - pr_debug("Open System\n"); - } - pDevice->uChannel = sJoinCmd.uChannel; - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_SET_WEP: - pr_debug("WLAN_CMD_SET_WEP Key\n"); - memset(&sWEPCmd, 0, sizeof(SCmdSetWEP)); - if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) { - result = -EFAULT; - break; - } - if (sWEPCmd.bEnableWep != true) { - pDevice->bEncryptionEnable = false; - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - MACvDisableDefaultKey(pDevice->PortOffset); - pr_debug("WEP function disable\n"); - break; - } - - for (ii = 0; ii < WLAN_WEP_NKEYS; ii++) { - if (sWEPCmd.bWepKeyAvailable[ii]) { - if (ii == sWEPCmd.byKeyIndex) - dwKeyIndex = ii | (1 << 31); - else - dwKeyIndex = ii; - - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - sWEPCmd.auWepKeyLength[ii], - NULL, - (unsigned char *)&sWEPCmd.abyWepKey[ii][0], - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - } - } - pDevice->byKeyIndex = sWEPCmd.byKeyIndex; - pDevice->bTransmitKey = true; - pDevice->bEncryptionEnable = true; - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - break; - - case WLAN_CMD_GET_LINK: { - SCmdLinkStatus sLinkStatus; - - pr_debug("WLAN_CMD_GET_LINK status\n"); - - memset(&sLinkStatus, 0, sizeof(sLinkStatus)); - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - sLinkStatus.wBSSType = ADHOC; - else - sLinkStatus.wBSSType = INFRA; - - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) - sLinkStatus.byState = ADHOC_JOINTED; - else - sLinkStatus.byState = ADHOC_STARTED; - - sLinkStatus.uChannel = pMgmt->uCurrChannel; - if (pDevice->bLinkPass == true) { - sLinkStatus.bLink = true; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); - memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; - pr_debug(" Link Success!\n"); - } else { - sLinkStatus.bLink = false; - sLinkStatus.uLinkRate = 0; - } - if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) { - result = -EFAULT; - break; - } - break; - } - case WLAN_CMD_GET_LISTLEN: - cbListCount = 0; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - cbListCount++; - } - sList.uItem = cbListCount; - if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) { - result = -EFAULT; - break; - } - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_LIST: - if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) { - result = -EFAULT; - break; - } - if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) { - result = -EINVAL; - break; - } - pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), - GFP_ATOMIC); - if (pList == NULL) { - result = -ENOMEM; - break; - } - pList->uItem = sList.uItem; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) { - pBSS = &(pMgmt->sBSSList[jj]); - if (pBSS->bActive) { - pList->sBSSIDList[ii].uChannel = pBSS->uChannel; - pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; - pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; - RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); - pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm; - memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1); - memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len); - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) - pList->sBSSIDList[ii].byNetType = INFRA; - else - pList->sBSSIDList[ii].byNetType = ADHOC; - - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) - pList->sBSSIDList[ii].bWEPOn = true; - else - pList->sBSSIDList[ii].bWEPOn = false; - - ii++; - if (ii >= pList->uItem) - break; - } - } - - if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) { - result = -EFAULT; - break; - } - kfree(pList); - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_MIB: - if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) { - result = -EFAULT; - break; - } - break; - - case WLAN_CMD_GET_STAT: - if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) { - result = -EFAULT; - break; - } - break; - - case WLAN_CMD_STOP_MAC: - pr_debug("WLAN_CMD_STOP_MAC\n"); - netif_stop_queue(pDevice->dev); - - spin_lock_irq(&pDevice->lock); - if (pDevice->bRadioOff == false) - CARDbRadioPowerOff(pDevice); - - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - del_timer(&pDevice->sTimerCommand); - del_timer(&pMgmt->sTimerSecondCallback); - pDevice->bCmdRunning = false; - pDevice->bMACSuspend = true; - MACvIntDisable(pDevice->PortOffset); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_START_MAC: - pr_debug("WLAN_CMD_START_MAC\n"); - - if (pDevice->bMACSuspend == true) { - if (pDevice->bRadioOff == true) - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - pDevice->bMACSuspend = false; - } - break; - - case WLAN_CMD_SET_HOSTAPD: - pr_debug("WLAN_CMD_SET_HOSTAPD\n"); - - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - if (sValue.dwValue == 1) { - if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0) { - pr_debug("Enable HOSTAP\n"); - } else { - result = -EFAULT; - break; - } - } else { - vt6655_hostap_set_hostapd(pDevice, 0, 1); - pr_debug("Disable HOSTAP\n"); - } - break; - - case WLAN_CMD_SET_HOSTAPD_STA: - pr_debug("WLAN_CMD_SET_HOSTAPD_STA\n"); - break; - - case WLAN_CMD_SET_802_1X: - pr_debug("WLAN_CMD_SET_802_1X\n"); - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - - if (sValue.dwValue == 1) { - pDevice->bEnable8021x = true; - pr_debug("Enable 802.1x\n"); - } else { - pDevice->bEnable8021x = false; - pr_debug("Disable 802.1x\n"); - } - break; - - case WLAN_CMD_SET_HOST_WEP: - pr_debug("WLAN_CMD_SET_HOST_WEP\n"); - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - - if (sValue.dwValue == 1) { - pDevice->bEnableHostWEP = true; - pr_debug("Enable HostWEP\n"); - } else { - pDevice->bEnableHostWEP = false; - pr_debug("Disable HostWEP\n"); - } - break; - - case WLAN_CMD_SET_WPA: - pr_debug("WLAN_CMD_SET_WPA\n"); - - if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { - result = -EFAULT; - break; - } - if (sValue.dwValue == 1) { - pr_debug("up wpadev\n"); - eth_hw_addr_inherit(pDevice->wpadev, pDevice->dev); - pDevice->bWPADEVUp = true; - } else { - pr_debug("close wpadev\n"); - pDevice->bWPADEVUp = false; - } - break; - - case WLAN_CMD_AP_START: - pr_debug("WLAN_CMD_AP_START\n"); - if (pDevice->bRadioOff == true) { - CARDbRadioPowerOn(pDevice); - vMgrTimerInit(pDevice); - MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - add_timer(&pMgmt->sTimerSecondCallback); - } - if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) { - result = -EFAULT; - break; - } - - if (sStartAPCmd.wBSSType == AP) { - pMgmt->eConfigMode = WMAC_CONFIG_AP; - pr_debug("ioct set to AP mode\n"); - } else { - pr_debug("ioct BSS type not set to AP mode\n"); - result = -EFAULT; - break; - } - - if (sStartAPCmd.wBBPType == PHY80211g) - pMgmt->byAPBBType = PHY_TYPE_11G; - else if (sStartAPCmd.wBBPType == PHY80211a) - pMgmt->byAPBBType = PHY_TYPE_11A; - else - pMgmt->byAPBBType = PHY_TYPE_11B; - - pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid; - if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) - return -EINVAL; - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); - - if ((sStartAPCmd.uChannel > 0) && (sStartAPCmd.uChannel <= 14)) - pDevice->uChannel = sStartAPCmd.uChannel; - - if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000)) - pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt; - else - pMgmt->wIBSSBeaconPeriod = 100; - - if (sStartAPCmd.bShareKeyAuth == true) { - pMgmt->bShareKeyAlgorithm = true; - pr_debug("Share Key\n"); - } else { - pMgmt->bShareKeyAlgorithm = false; - pr_debug("Open System\n"); - } - memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6); - - if (sStartAPCmd.byBasicRate & BIT3) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - pMgmt->abyIBSSSuppRates[4] |= BIT7; - pMgmt->abyIBSSSuppRates[5] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT2) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - pMgmt->abyIBSSSuppRates[4] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT1) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - } else if (sStartAPCmd.byBasicRate & BIT1) { - pMgmt->abyIBSSSuppRates[2] |= BIT7; - } else { - /* default 1,2M */ - pMgmt->abyIBSSSuppRates[2] |= BIT7; - pMgmt->abyIBSSSuppRates[3] |= BIT7; - } - - pr_debug("Support Rate= %*ph\n", - 4, pMgmt->abyIBSSSuppRates + 2); - - netif_stop_queue(pDevice->dev); - spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); - spin_unlock_irq(&pDevice->lock); - break; - - case WLAN_CMD_GET_NODE_CNT: - cbListCount = 0; - pNode = &(pMgmt->sNodeDBTable[0]); - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - pNode = &(pMgmt->sNodeDBTable[ii]); - if (!pNode->bActive) - continue; - cbListCount++; - } - - sNodeList.uItem = cbListCount; - if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) { - result = -EFAULT; - break; - } - pReq->wResult = 0; - break; - - case WLAN_CMD_GET_NODE_LIST: - if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) { - result = -EFAULT; - break; - } - if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) { - result = -EINVAL; - break; - } - pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), - GFP_ATOMIC); - if (pNodeList == NULL) { - result = -ENOMEM; - break; - } - pNodeList->uItem = sNodeList.uItem; - pNode = &(pMgmt->sNodeDBTable[0]); - for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) { - pNode = &(pMgmt->sNodeDBTable[ii]); - if (pNode->bActive) { - pNodeList->sNodeList[jj].wAID = pNode->wAID; - memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN); - pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate; - pNodeList->sNodeList[jj].wInActiveCount = (unsigned short)pNode->uInActiveCount; - pNodeList->sNodeList[jj].wEnQueueCnt = (unsigned short)pNode->wEnQueueCnt; - pNodeList->sNodeList[jj].wFlags = (unsigned short)pNode->dwFlags; - pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable; - pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex; - pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength; - memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN); - pr_debug("key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - pNodeList->sNodeList[jj].abyWepKey[0], - pNodeList->sNodeList[jj].abyWepKey[1], - pNodeList->sNodeList[jj].abyWepKey[2], - pNodeList->sNodeList[jj].abyWepKey[3], - pNodeList->sNodeList[jj].abyWepKey[4]); - pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback; - pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures; - pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts; - pNodeList->sNodeList[jj].wFailureRatio = (unsigned short)pNode->uFailureRatio; - jj++; - if (jj >= pNodeList->uItem) - break; - } - } - if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { - result = -EFAULT; - break; - } - kfree(pNodeList); - pReq->wResult = 0; - break; - - default: - pr_debug("Private command not support..\n"); - } - - return result; -} diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h deleted file mode 100644 index 1b5d19495fad..000000000000 --- a/drivers/staging/vt6655/ioctl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __IOCTL_H__ -#define __IOCTL_H__ - -#include "device.h" - -int private_ioctl(struct vnt_private *, struct ifreq *rq); - -#endif /* __IOCTL_H__ */ -- GitLab From ee1464902c25e22c15d7eda41f00a8a40acc7ec9 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:24 +0000 Subject: [PATCH 2081/9457] staging: vt6655: dead code remove legacy hostap.c/h hoatap is now supported by mac80211 in nl80211 mode Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/dpc.c | 1 - drivers/staging/vt6655/hostap.c | 764 --------------------------- drivers/staging/vt6655/hostap.h | 58 -- drivers/staging/vt6655/rxtx.c | 1 - 6 files changed, 826 deletions(-) delete mode 100644 drivers/staging/vt6655/hostap.c delete mode 100644 drivers/staging/vt6655/hostap.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 6e9349976174..2d534504c456 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -21,7 +21,6 @@ vt6655_stage-y += device_main.o \ rc4.o \ tether.o \ tcrc.o \ - hostap.o \ wpa.o \ key.o \ tkip.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 5b54cabdc863..3a90401ab7aa 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -68,7 +68,6 @@ #include "rxtx.h" #include "wroute.h" #include "bssdb.h" -#include "hostap.h" #include "wpactl.h" #include "dpc.h" #include "datarate.h" diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 11153ef0dd95..6842baf73ed1 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -50,7 +50,6 @@ #include "tcrc.h" #include "wctl.h" #include "wroute.h" -#include "hostap.h" #include "rf.h" #include "iowpa.h" #include "aes_ccmp.h" diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c deleted file mode 100644 index 2db08df0656d..000000000000 --- a/drivers/staging/vt6655/hostap.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.c - * - * Purpose: handle hostap deamon ioctl input/out functions - * - * Author: Lyndon Chen - * - * Date: Oct. 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "hostap.h" -#include "iocmd.h" -#include "mac.h" -#include "card.h" -#include "baseband.h" -#include "wpactl.h" -#include "key.h" - -#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024 -#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0 -#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 -#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * register net_device (AP) for hostap deamon - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) -{ - struct vnt_private *apdev_priv; - struct net_device *dev = pDevice->dev; - int ret; - const struct net_device_ops apdev_netdev_ops = { - .ndo_start_xmit = pDevice->tx_80211, - }; - - pr_debug("%s: Enabling hostapd mode\n", dev->name); - - pDevice->apdev = alloc_etherdev(sizeof(*apdev_priv)); - if (pDevice->apdev == NULL) - return -ENOMEM; - - apdev_priv = netdev_priv(pDevice->apdev); - *apdev_priv = *pDevice; - eth_hw_addr_inherit(pDevice->apdev, dev); - - pDevice->apdev->netdev_ops = &apdev_netdev_ops; - - pDevice->apdev->type = ARPHRD_IEEE80211; - - pDevice->apdev->base_addr = dev->base_addr; - pDevice->apdev->irq = dev->irq; - pDevice->apdev->mem_start = dev->mem_start; - pDevice->apdev->mem_end = dev->mem_end; - sprintf(pDevice->apdev->name, "%sap", dev->name); - if (rtnl_locked) - ret = register_netdevice(pDevice->apdev); - else - ret = register_netdev(pDevice->apdev); - if (ret) { - pr_debug("%s: register_netdevice(AP) failed!\n", - dev->name); - free_netdev(pDevice->apdev); - pDevice->apdev = NULL; - return -1; - } - - pr_debug("%s: Registered netdevice %s for AP management\n", - dev->name, pDevice->apdev->name); - - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - - return 0; -} - -/* - * Description: - * unregister net_device(AP) - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked) -{ - pr_debug("%s: disabling hostapd mode\n", pDevice->dev->name); - - if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) { - if (rtnl_locked) - unregister_netdevice(pDevice->apdev); - else - unregister_netdev(pDevice->apdev); - pr_debug("%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->apdev->name); - } - if (pDevice->apdev) - free_netdev(pDevice->apdev); - pDevice->apdev = NULL; - pDevice->bEnable8021x = false; - pDevice->bEnableHostWEP = false; - pDevice->bEncryptionEnable = false; - -/* 4.2007-0118-03, by EinsnLiu */ -/* execute some clear work */ - pDevice->pMgmt->byCSSPK = KEY_CTL_NONE; - pDevice->pMgmt->byCSSGK = KEY_CTL_NONE; - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - - return 0; -} - -/* - * Description: - * Set enable/disable hostapd mode - * - * Parameters: - * In: - * pDevice - - * rtnl_locked - - * Out: - * - * Return Value: - * - */ - -int vt6655_hostap_set_hostapd(struct vnt_private *pDevice, - int val, int rtnl_locked) -{ - if (val < 0 || val > 1) - return -EINVAL; - - if (pDevice->bEnableHostapd == val) - return 0; - - pDevice->bEnableHostapd = val; - - if (val) - return hostap_enable_hostapd(pDevice, rtnl_locked); - return hostap_disable_hostapd(pDevice, rtnl_locked); -} - -/* - * Description: - * remove station function supported for hostap deamon - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_remove_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - return -ENOENT; - - return 0; -} - -/* - * Description: - * add a station from hostap deamon - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_add_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) - BSSvCreateOneNode(pDevice, &uNodeIndex); - - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; -/* TODO listenInterval */ - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; - - /* set max tx rate */ - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - /* set max basic rate */ - pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; - /* Todo: check sta preamble, if ap can't support, set status code */ - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); - - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid; - - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; - - pr_debug("Add STA AID= %d\n", pMgmt->sNodeDBTable[uNodeIndex].wAID); - pr_debug("MAC=%pM\n", param->sta_addr); - pr_debug("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - - return 0; -} - -/* - * Description: - * get station info - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int hostap_get_info_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - param->u.get_info_sta.inactive_sec = - (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; - } else { - return -ENOENT; - } - - return 0; -} - -/* - * Description: - * set station flag - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_flags_sta(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex; - - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { - pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; - pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; - pr_debug(" dwFlags = %x\n", - (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); - } else { - return -ENOENT; - } - - return 0; -} - -/* - * Description: - * set generic element (wpa ie) - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_generic_element(struct vnt_private *pDevice, - struct viawget_hostapd_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (param->u.generic_elem.len > sizeof(pMgmt->abyWPAIE)) - return -EINVAL; - - memcpy(pMgmt->abyWPAIE, - param->u.generic_elem.data, - param->u.generic_elem.len - ); - - pMgmt->wWPAIELen = param->u.generic_elem.len; - - pr_debug("pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); - - /* disable wpa */ - if (pMgmt->wWPAIELen == 0) { - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - pr_debug(" No WPAIE, Disable WPA\n"); - } else { - /* enable wpa */ - if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) || - (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) { - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - pr_debug("Set WPAIE enable WPA\n"); - } else - return -EINVAL; - } - - return 0; -} - -/* - * Description: - * flush station nodes table. - * - * Parameters: - * In: - * pDevice - - * Out: - * - * Return Value: - * - */ - -static void hostap_flush_sta(struct vnt_private *pDevice) -{ - /* reserved node index =0 for multicast node. */ - BSSvClearNodeDBTable(pDevice, 1); - pDevice->uAssocCount = 0; -} - -/* - * Description: - * set each stations encryption key - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_set_encryption(struct vnt_private *pDevice, - struct viawget_hostapd_param *param, - int param_len) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; - int iNodeIndex = -1; - int ii; - bool bKeyTableFull = false; - unsigned short wKeyCtl = 0; - - param->u.crypt.err = 0; - - if (param->u.crypt.alg > WPA_ALG_CCMP) - return -EINVAL; - - if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - pr_debug(" HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); - return -EINVAL; - } - - if (is_broadcast_ether_addr(param->sta_addr)) { - if (param->u.crypt.idx >= MAX_GROUP_KEY) - return -EINVAL; - iNodeIndex = 0; - - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - pr_debug(" HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } - } - pr_debug(" hostap_set_encryption: sta_index %d\n", iNodeIndex); - pr_debug(" hostap_set_encryption: alg %d\n", param->u.crypt.alg); - - if (param->u.crypt.alg == WPA_ALG_NONE) { - if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) { - if (!KeybRemoveKey(&(pDevice->sKey), - param->sta_addr, - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, - pDevice->PortOffset)) { - pr_debug("KeybRemoveKey fail\n"); - } - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - } - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; - pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; - memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - 0, - MAX_KEY_LEN -); - - return 0; - } - - memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); - /* copy to node key tbl */ - pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; - pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; - memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - param->u.crypt.key, - param->u.crypt.key_len -); - - dwKeyIndex = (unsigned long)(param->u.crypt.idx); - if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } - - if (param->u.crypt.alg == WPA_ALG_WEP) { - if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.crypt.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } else { - /* 8021x enable, individual key */ - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex & ~(USE_KEYRSC), - param->u.crypt.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID)) { - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - /* Key Table Full */ - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - } - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - return 0; - } - - if (param->u.crypt.seq) { - memcpy(&abySeq, param->u.crypt.seq, 8); - for (ii = 0; ii < 8; ii++) - KeyRSC |= (u64)abySeq[ii] << (ii * 8); - - dwKeyIndex |= 1 << 29; - pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; - } - - if (param->u.crypt.alg == WPA_ALG_TKIP) { - if (param->u.crypt.key_len != MAX_KEY_LEN) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - byKeyDecMode = KEY_CTL_TKIP; - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; - } - - if (param->u.crypt.alg == WPA_ALG_CCMP) { - if ((param->u.crypt.key_len != AES_KEY_LEN) || - (pDevice->byLocalID <= REV_ID_VT3253_A1)) - return -EINVAL; - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - byKeyDecMode = KEY_CTL_CCMP; - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } - - if (iNodeIndex == 0) { - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.crypt.key_len, - (u64 *) &KeyRSC, - abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID); - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (KeybSetKey(&(pDevice->sKey), - ¶m->sta_addr[0], - dwKeyIndex, - param->u.crypt.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; - - } else { - /* Key Table Full */ - pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; - bKeyTableFull = true; - pr_debug(" Key Table Full\n"); - } - - } - - if (bKeyTableFull) { - wKeyCtl &= 0x7F00; /* clear all key control filed */ - wKeyCtl |= (byKeyDecMode << 4); - wKeyCtl |= (byKeyDecMode); - wKeyCtl |= 0x0044; /* use group key for all address */ - wKeyCtl |= 0x4000; /* disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int */ - MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); - } - - pr_debug(" Set key sta_index= %d\n", iNodeIndex); - pr_debug(" tx_index=%d len=%d\n", - param->u.crypt.idx, param->u.crypt.key_len); - pr_debug(" key=%x-%x-%x-%x-%x-xxxxx\n", - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], - pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]); - - /* set wep key */ - pDevice->bEncryptionEnable = true; - pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; - pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; - pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; - pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; - - return 0; -} - -/* - * Description: - * get each stations encryption key - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ -static int hostap_get_encryption(struct vnt_private *pDevice, - struct viawget_hostapd_param *param, - int param_len) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - int iNodeIndex = 0; - - param->u.crypt.err = 0; - - if (is_broadcast_ether_addr(param->sta_addr)) { - iNodeIndex = 0; - } else { - if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - pr_debug("hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); - return -EINVAL; - } - } - pr_debug("hostap_get_encryption: %d\n", iNodeIndex); - memset(param->u.crypt.seq, 0, 8); - for (ii = 0; ii < 8; ii++) - param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); - - return 0; -} - -/* - * Description: - * vt6655_hostap_ioctl main function supported for hostap deamon. - * - * Parameters: - * In: - * pDevice - - * iw_point - - * Out: - * - * Return Value: - * - */ -int vt6655_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p) -{ - struct viawget_hostapd_param *param; - int ret = 0; - int ap_ioctl = 0; - - if (p->length < sizeof(struct viawget_hostapd_param) || - p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) - return -EINVAL; - - param = kmalloc((int)p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case VIAWGET_HOSTAPD_SET_ENCRYPTION: - pr_debug("VIAWGET_HOSTAPD_SET_ENCRYPTION\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_set_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_GET_ENCRYPTION: - pr_debug("VIAWGET_HOSTAPD_GET_ENCRYPTION\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_get_encryption(pDevice, param, p->length); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR: - pr_debug("VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_FLUSH: - pr_debug("VIAWGET_HOSTAPD_FLUSH\n"); - spin_lock_irq(&pDevice->lock); - hostap_flush_sta(pDevice); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_ADD_STA: - pr_debug("VIAWGET_HOSTAPD_ADD_STA\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_add_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_REMOVE_STA: - pr_debug("VIAWGET_HOSTAPD_REMOVE_STA\n"); - spin_lock_irq(&pDevice->lock); - ret = hostap_remove_sta(pDevice, param); - spin_unlock_irq(&pDevice->lock); - break; - case VIAWGET_HOSTAPD_GET_INFO_STA: - pr_debug("VIAWGET_HOSTAPD_GET_INFO_STA\n"); - ret = hostap_get_info_sta(pDevice, param); - ap_ioctl = 1; - break; - case VIAWGET_HOSTAPD_SET_FLAGS_STA: - pr_debug("VIAWGET_HOSTAPD_SET_FLAGS_STA\n"); - ret = hostap_set_flags_sta(pDevice, param); - break; - case VIAWGET_HOSTAPD_MLME: - pr_debug("VIAWGET_HOSTAPD_MLME\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: - pr_debug("VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n"); - ret = hostap_set_generic_element(pDevice, param); - break; - case VIAWGET_HOSTAPD_SCAN_REQ: - pr_debug("VIAWGET_HOSTAPD_SCAN_REQ\n"); - ret = -EOPNOTSUPP; - goto out; - case VIAWGET_HOSTAPD_STA_CLEAR_STATS: - pr_debug("VIAWGET_HOSTAPD_STA_CLEAR_STATS\n"); - ret = -EOPNOTSUPP; - goto out; - default: - pr_debug("vt6655_hostap_ioctl: unknown cmd=%d\n", - (int)param->cmd); - ret = -EOPNOTSUPP; - goto out; - } - - if ((ret == 0) && ap_ioctl) { - if (copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - } - -out: - kfree(param); - return ret; -} diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h deleted file mode 100644 index fc5f9ed4674b..000000000000 --- a/drivers/staging/vt6655/hostap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: hostap.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __HOSTAP_H__ -#define __HOSTAP_H__ - -#include "device.h" - -#define WLAN_RATE_1M BIT0 -#define WLAN_RATE_2M BIT1 -#define WLAN_RATE_5M5 BIT2 -#define WLAN_RATE_11M BIT3 -#define WLAN_RATE_6M BIT4 -#define WLAN_RATE_9M BIT5 -#define WLAN_RATE_12M BIT6 -#define WLAN_RATE_18M BIT7 -#define WLAN_RATE_24M BIT8 -#define WLAN_RATE_36M BIT9 -#define WLAN_RATE_48M BIT10 -#define WLAN_RATE_54M BIT11 - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#ifndef ARPHRD_IEEE80211 -#define ARPHRD_IEEE80211 801 -#endif - -int vt6655_hostap_set_hostapd(struct vnt_private *, int val, int rtnl_locked); -int vt6655_hostap_ioctl(struct vnt_private *, struct iw_point *p); - -#endif /* __HOSTAP_H__ */ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 9beabea88b3f..aa7e454cd9d3 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -60,7 +60,6 @@ #include "tcrc.h" #include "wctl.h" #include "wroute.h" -#include "hostap.h" #include "rf.h" /*--------------------- Static Definitions -------------------------*/ -- GitLab From 2759e2172de880c9aa6b2cd68abdca0f769a6b53 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:25 +0000 Subject: [PATCH 2082/9457] staging: vt6655: dead code remove wpactl.c/h All these functions are now dead. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/wpactl.c | 893 --------------------------- drivers/staging/vt6655/wpactl.h | 64 -- 4 files changed, 959 deletions(-) delete mode 100644 drivers/staging/vt6655/wpactl.c delete mode 100644 drivers/staging/vt6655/wpactl.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 2d534504c456..2cad0d09cdd0 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -27,7 +27,6 @@ vt6655_stage-y += device_main.o \ michael.o \ wroute.o \ rf.o \ - wpactl.o \ wpa2.o \ aes_ccmp.o \ vntwifi.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 3a90401ab7aa..991a276f1ecf 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -68,7 +68,6 @@ #include "rxtx.h" #include "wroute.h" #include "bssdb.h" -#include "wpactl.h" #include "dpc.h" #include "datarate.h" #include "rf.h" diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c deleted file mode 100644 index cc39829cbacc..000000000000 --- a/drivers/staging/vt6655/wpactl.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpactl.c - * - * Purpose: handle wpa supplicant ioctl input/out functions - * - * Author: Lyndon Chen - * - * Date: Oct. 20, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#include "wpactl.h" -#include "key.h" -#include "mac.h" -#include "device.h" -#include "wmgr.h" -#include "iocmd.h" -#include "iowpa.h" -#include "rf.h" - -/*--------------------- Static Definitions -------------------------*/ - -#define VIAWGET_WPA_MAX_BUF_SIZE 1024 - -static const int frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 -}; -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ -static void wpadev_setup(struct net_device *dev) -{ - dev->type = ARPHRD_IEEE80211; - dev->hard_header_len = ETH_HLEN; - dev->mtu = 2048; - dev->addr_len = ETH_ALEN; - dev->tx_queue_len = 1000; - - memset(dev->broadcast, 0xFF, ETH_ALEN); - - dev->flags = IFF_BROADCAST|IFF_MULTICAST; -} - -/* - * Description: - * register netdev for wpa supplicant daemon - * - * Parameters: - * In: - * pDevice - - * enable - - * Out: - * - * Return Value: - * - */ - -static int wpa_init_wpadev(struct vnt_private *pDevice) -{ - struct vnt_private *wpadev_priv; - struct net_device *dev = pDevice->dev; - int ret = 0; - - pDevice->wpadev = alloc_netdev(sizeof(*wpadev_priv), "vntwpa", - NET_NAME_UNKNOWN, wpadev_setup); - if (pDevice->wpadev == NULL) - return -ENOMEM; - - wpadev_priv = netdev_priv(pDevice->wpadev); - *wpadev_priv = *pDevice; - eth_hw_addr_inherit(pDevice->wpadev, dev); - pDevice->wpadev->base_addr = dev->base_addr; - pDevice->wpadev->irq = dev->irq; - pDevice->wpadev->mem_start = dev->mem_start; - pDevice->wpadev->mem_end = dev->mem_end; - ret = register_netdev(pDevice->wpadev); - if (ret) { - pr_debug("%s: register_netdev(WPA) failed!\n", dev->name); - free_netdev(pDevice->wpadev); - return -1; - } - - if (pDevice->skb == NULL) { - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - if (pDevice->skb == NULL) - return -ENOMEM; - } - - pr_debug("%s: Registered netdev %s for WPA management\n", - dev->name, pDevice->wpadev->name); - - return 0; -} - -/* - * Description: - * unregister net_device (wpadev) - * - * Parameters: - * In: - * pDevice - - * Out: - * - * Return Value: - * - */ - -static int wpa_release_wpadev(struct vnt_private *pDevice) -{ - if (pDevice->skb) { - dev_kfree_skb(pDevice->skb); - pDevice->skb = NULL; - } - - if (pDevice->wpadev) { - pr_debug("%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->wpadev->name); - unregister_netdev(pDevice->wpadev); - free_netdev(pDevice->wpadev); - pDevice->wpadev = NULL; - } - - return 0; -} - -/* - * Description: - * Set enable/disable dev for wpa supplicant daemon - * - * Parameters: - * In: - * pDevice - - * val - - * Out: - * - * Return Value: - * - */ - -int wpa_set_wpadev(struct vnt_private *pDevice, int val) -{ - if (val) - return wpa_init_wpadev(pDevice); - else - return wpa_release_wpadev(pDevice); -} - -/* - * Description: - * Set WPA algorithm & keys - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -int wpa_set_keys(struct vnt_private *pDevice, void *ctx, - bool fcpfkernel) __must_hold(&pDevice->lock) -{ - struct viawget_wpa_param *param = ctx; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned long dwKeyIndex = 0; - unsigned char abyKey[MAX_KEY_LEN]; - unsigned char abySeq[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned char byKeyDecMode = KEY_CTL_WEP; - int ret = 0; - int uu, ii; - - if (param->u.wpa_key.alg_name > WPA_ALG_CCMP || - param->u.wpa_key.key_len > MAX_KEY_LEN || - param->u.wpa_key.seq_len > MAX_KEY_LEN) - return -EINVAL; - - pr_debug("param->u.wpa_key.alg_name = %d\n", param->u.wpa_key.alg_name); - if (param->u.wpa_key.alg_name == WPA_ALG_NONE) { - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - pDevice->bEncryptionEnable = false; - pDevice->byKeyIndex = 0; - pDevice->bTransmitKey = false; - KeyvRemoveAllWEPKey(&(pDevice->sKey), pDevice->PortOffset); - for (uu = 0; uu < MAX_KEY_TABLE; uu++) - MACvDisableKeyEntry(pDevice->PortOffset, uu); - - return ret; - } - - if (param->u.wpa_key.key && fcpfkernel) { - memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len); - } else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.key && - copy_from_user(&abyKey[0], - (void __user *)param->u.wpa_key.key, - param->u.wpa_key.key_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } - spin_lock_irq(&pDevice->lock); - } - - dwKeyIndex = (unsigned long)(param->u.wpa_key.key_index); - - if (param->u.wpa_key.alg_name == WPA_ALG_WEP) { - if (dwKeyIndex > 3) { - return -EINVAL; - } else { - if (param->u.wpa_key.set_tx) { - pDevice->byKeyIndex = (unsigned char)dwKeyIndex; - pDevice->bTransmitKey = true; - dwKeyIndex |= (1 << 31); - } - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.wpa_key.key_len, - NULL, - abyKey, - KEY_CTL_WEP, - pDevice->PortOffset, - pDevice->byLocalID); - - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = true; - return ret; - } - - if (param->u.wpa_key.seq && fcpfkernel) { - memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len); - } else { - spin_unlock_irq(&pDevice->lock); - if (param->u.wpa_key.seq && - copy_from_user(&abySeq[0], - (void __user *)param->u.wpa_key.seq, - param->u.wpa_key.seq_len)) { - spin_lock_irq(&pDevice->lock); - return -EINVAL; - } - spin_lock_irq(&pDevice->lock); - } - - if (param->u.wpa_key.seq_len > 0) { - for (ii = 0; ii < param->u.wpa_key.seq_len; ii++) { - if (ii < 4) - KeyRSC |= (u64)(abySeq[ii] << (ii * 8)); - else - KeyRSC |= (u64)(abySeq[ii] << ((ii-4) * 8)); - } - dwKeyIndex |= 1 << 29; - } - - if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { - pr_debug("return dwKeyIndex > 3\n"); - return -EINVAL; - } - - if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - - if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - - if (param->u.wpa_key.set_tx) - dwKeyIndex |= (1 << 31); - - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - byKeyDecMode = KEY_CTL_CCMP; - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - byKeyDecMode = KEY_CTL_TKIP; - else - byKeyDecMode = KEY_CTL_WEP; - - /* Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled */ - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (param->u.wpa_key.key_len == MAX_KEY_LEN) - byKeyDecMode = KEY_CTL_TKIP; - else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN) - byKeyDecMode = KEY_CTL_WEP; - } - - /* Check TKIP key length */ - if ((byKeyDecMode == KEY_CTL_TKIP) && - (param->u.wpa_key.key_len != MAX_KEY_LEN)) { - /* TKIP Key must be 256 bits */ - pr_debug("return- TKIP Key must be 256 bits!\n"); - return -EINVAL; - } - /* Check AES key length */ - if ((byKeyDecMode == KEY_CTL_CCMP) && - (param->u.wpa_key.key_len != AES_KEY_LEN)) { - /* AES Key must be 128 bits */ - return -EINVAL; - } - - /* spin_lock_irq(&pDevice->lock); */ - if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { - /* If is_broadcast_ether_addr, set the key as every key entry's group key. */ - pr_debug("Groupe Key Assign\n"); - - if (KeybSetAllGroupKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID) && - KeybSetDefaultKey(&(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pr_debug("GROUP Key Assign\n"); - - } else { - return -EINVAL; - } - - } else { - pr_debug("Pairwise Key Assign\n"); - /* BSSID not 0xffffffffffff */ - /* Pairwise Key can't be WEP */ - if (byKeyDecMode == KEY_CTL_WEP) { - pr_debug("Pairwise Key can't be WEP\n"); - return -EINVAL; - } - - dwKeyIndex |= (1 << 30); /* set pairwise key */ - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) - return -EINVAL; - - if (KeybSetKey(&(pDevice->sKey), - ¶m->addr[0], - dwKeyIndex, - param->u.wpa_key.key_len, - (u64 *) &KeyRSC, - (unsigned char *)abyKey, - byKeyDecMode, - pDevice->PortOffset, - pDevice->byLocalID)) { - pr_debug("Pairwise Key Set\n"); - - } else { - /* Key Table Full */ - return -EINVAL; - } - } /* BSSID not 0xffffffffffff */ - if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { - pDevice->byKeyIndex = (unsigned char)param->u.wpa_key.key_index; - pDevice->bTransmitKey = true; - } - pDevice->bEncryptionEnable = true; - - return ret; -} - -/* - * Description: - * enable wpa auth & mode - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_wpa(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - pMgmt->bShareKeyAlgorithm = false; - - return 0; -} - -/* - * Description: - * set disassociate - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_disassociate(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - spin_lock_irq(&pDevice->lock); - if (pDevice->bLinkPass) { - if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) - bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); - } - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * enable scan process - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_scan(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * get bssid - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_bssid(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - - memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6); - - return 0; -} - -/* - * Description: - * get bssid - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_ssid(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len); - param->u.wpa_associate.ssid_len = pItemSSID->len; - - return 0; -} - -/* - * Description: - * get scan results - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_get_scan(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - struct viawget_scan_result *scan_buf; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PKnownBSS pBSS; - unsigned char *pBuf; - int ret = 0; - u16 count = 0; - u16 ii, jj; - unsigned char *ptempBSS; - - ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC); - - if (ptempBSS == NULL) { - pr_err("bubble sort kmalloc memory fail@@@\n"); - - ret = -ENOMEM; - - return ret; - - } - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) { - if ((pMgmt->sBSSList[jj].bActive != true) || - - ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI) && (pMgmt->sBSSList[jj + 1].bActive != false))) { - memcpy(ptempBSS, &pMgmt->sBSSList[jj], sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1], sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS)); - - } - - } - - } - - kfree(ptempBSS); - -//******mike:bubble sort by stronger RSSI*****// - - count = 0; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - count++; - } - - pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC); - - if (pBuf == NULL) { - ret = -ENOMEM; - return ret; - } - scan_buf = (struct viawget_scan_result *)pBuf; - pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (pBSS->bActive) { - if (jj >= count) - break; - memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN); - pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; - memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len); - scan_buf->ssid_len = pItemSSID->len; - scan_buf->freq = frequency_list[pBSS->uChannel-1]; - scan_buf->caps = pBSS->wCapInfo; - - if (pBSS->wWPALen != 0) { - scan_buf->wpa_ie_len = pBSS->wWPALen; - memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen); - } - if (pBSS->wRSNLen != 0) { - scan_buf->rsn_ie_len = pBSS->wRSNLen; - memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen); - } - scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result)); - jj++; - } - } - - if (jj < count) - count = jj; - - if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) - ret = -EFAULT; - - param->u.scan_results.scan_count = count; - pr_debug(" param->u.scan_results.scan_count = %d\n", count); - - kfree(pBuf); - return ret; -} - -/* - * Description: - * set associate with AP - * - * Parameters: - * In: - * pDevice - - * param - - * Out: - * - * Return Value: - * - */ - -static int wpa_set_associate(struct vnt_private *pDevice, - struct viawget_wpa_param *param) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - unsigned char abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char abyWPAIE[64]; - bool bWepEnabled = false; - - /* set key type & algorithm */ - pr_debug("pairwise_suite = %d\n", - param->u.wpa_associate.pairwise_suite); - pr_debug("group_suite = %d\n", param->u.wpa_associate.group_suite); - pr_debug("key_mgmt_suite = %d\n", - param->u.wpa_associate.key_mgmt_suite); - pr_debug("auth_alg = %d\n", param->u.wpa_associate.auth_alg); - pr_debug("mode = %d\n", param->u.wpa_associate.mode); - pr_debug("wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); - - if (param->u.wpa_associate.wpa_ie_len) { - if (!param->u.wpa_associate.wpa_ie) - return -EINVAL; - if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE)) - return -EINVAL; - if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) - return -EFAULT; - } - - if (param->u.wpa_associate.mode == 1) - pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - else - pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - /* set ssid */ - memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->byElementID = WLAN_EID_SSID; - pItemSSID->len = param->u.wpa_associate.ssid_len; - memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len); - /* set bssid */ - if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) - memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); - else - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); - - if (param->u.wpa_associate.wpa_ie_len == 0) { - if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY) - pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY; - else - pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - } else if (abyWPAIE[0] == RSN_INFO_ELEM) { - if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA2; - } else { - if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE) - pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; - else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK) - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - else - pMgmt->eAuthenMode = WMAC_AUTH_WPA; - } - - switch (param->u.wpa_associate.pairwise_suite) { - case CIPHER_CCMP: - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - break; - case CIPHER_TKIP: - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - break; - case CIPHER_WEP40: - case CIPHER_WEP104: - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - bWepEnabled = true; - break; - case CIPHER_NONE: - if (param->u.wpa_associate.group_suite == CIPHER_CCMP) - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; - else - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; - break; - default: - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - } - -//DavidWang add for WPA_supplicant support open/share mode - - if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pMgmt->bShareKeyAlgorithm = true; - } else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { - if (!bWepEnabled) pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; - else pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } -//mike save old encryption status - pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus; - - if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) - pDevice->bEncryptionEnable = true; - else - pDevice->bEncryptionEnable = false; - if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || - ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && bWepEnabled))) //DavidWang //20080717-06, by chester//Not to initial WEP - KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = false; - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - //20080701-02, by Mike Liu -/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/ - { - PKnownBSS pCurr = NULL; - - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - pr_debug("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - } - } -/****************************************************************/ - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); - spin_unlock_irq(&pDevice->lock); - - return 0; -} - -/* - * Description: - * wpa_ioctl main function supported for wpa supplicant - * - * Parameters: - * In: - * pDevice - - * iw_point - - * Out: - * - * Return Value: - * - */ - -int wpa_ioctl(struct vnt_private *pDevice, struct iw_point *p) -{ - struct viawget_wpa_param *param; - int ret = 0; - int wpa_ioctl = 0; - - if (p->length < sizeof(struct viawget_wpa_param) || - p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) - return -EINVAL; - - param = kmalloc((int)p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case VIAWGET_SET_WPA: - ret = wpa_set_wpa(pDevice, param); - pr_debug("VIAWGET_SET_WPA\n"); - break; - - case VIAWGET_SET_KEY: - pr_debug("VIAWGET_SET_KEY\n"); - spin_lock_irq(&pDevice->lock); - ret = wpa_set_keys(pDevice, param, false); - spin_unlock_irq(&pDevice->lock); - break; - - case VIAWGET_SET_SCAN: - pr_debug("VIAWGET_SET_SCAN\n"); - ret = wpa_set_scan(pDevice, param); - break; - - case VIAWGET_GET_SCAN: - pr_debug("VIAWGET_GET_SCAN\n"); - ret = wpa_get_scan(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_GET_SSID: - pr_debug("VIAWGET_GET_SSID\n"); - ret = wpa_get_ssid(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_GET_BSSID: - pr_debug("VIAWGET_GET_BSSID\n"); - ret = wpa_get_bssid(pDevice, param); - wpa_ioctl = 1; - break; - - case VIAWGET_SET_ASSOCIATE: - pr_debug("VIAWGET_SET_ASSOCIATE\n"); - ret = wpa_set_associate(pDevice, param); - break; - - case VIAWGET_SET_DISASSOCIATE: - pr_debug("VIAWGET_SET_DISASSOCIATE\n"); - ret = wpa_set_disassociate(pDevice, param); - break; - - case VIAWGET_SET_DROP_UNENCRYPT: - pr_debug("VIAWGET_SET_DROP_UNENCRYPT\n"); - break; - - case VIAWGET_SET_DEAUTHENTICATE: - pr_debug("VIAWGET_SET_DEAUTHENTICATE\n"); - break; - - default: - pr_debug("wpa_ioctl: unknown cmd=%d\n", - param->cmd); - ret = -EOPNOTSUPP; - goto out; - } - - if ((ret == 0) && wpa_ioctl) { - if (copy_to_user(p->pointer, param, p->length)) { - ret = -EFAULT; - goto out; - } - } - -out: - kfree(param); - - return ret; -} diff --git a/drivers/staging/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h deleted file mode 100644 index c1b4a7292061..000000000000 --- a/drivers/staging/vt6655/wpactl.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wpactl.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: March 1, 2005 - * - */ - -#ifndef __WPACTL_H__ -#define __WPACTL_H__ - -#include "device.h" -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#include "iowpa.h" -#endif - -/*--------------------- Export Definitions -------------------------*/ - -//WPA related - -enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; -enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, - CIPHER_WEP104 }; -enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_CCKM, KEY_MGMT_PSK, KEY_MGMT_NONE, - KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; - -#define AUTH_ALG_OPEN_SYSTEM 0x01 -#define AUTH_ALG_SHARED_KEY 0x02 -#define AUTH_ALG_LEAP 0x04 - -#define GENERIC_INFO_ELEM 0xdd -#define RSN_INFO_ELEM 0x30 - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -int wpa_set_wpadev(struct vnt_private *, int val); -int wpa_ioctl(struct vnt_private *, struct iw_point *p); -int wpa_set_keys(struct vnt_private *, void *ctx, bool fcpfkernel); - -#endif // __WPACL_H__ -- GitLab From 01b8979244ee164dd90958521ed9aecec9dafe3f Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:26 +0000 Subject: [PATCH 2083/9457] staging: vt6655: dpc.c/h remove dead functions s_byGetRateIdx s_vGetDASA s_vProcessRxMACHeader s_bAPModeRxCtl s_bAPModeRxData s_bHandleRxEncryption s_bHostWepRxEncryption s_vProcessRxMACHeader s_byGetRateIdx s_vGetDASA device_receive_frame s_bAPModeRxCtl Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 1286 ---------------------------------- drivers/staging/vt6655/dpc.h | 8 - 2 files changed, 1294 deletions(-) diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 6842baf73ed1..977683cb7391 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -25,1302 +25,16 @@ * Date: May 20, 2003 * * Functions: - * device_receive_frame - Rcv 802.11 frame function - * s_bAPModeRxCtl- AP Rcv frame filer Ctl. - * s_bAPModeRxData- AP Rcv data frame handle - * s_bHandleRxEncryption- Rcv decrypted data via on-fly - * s_bHostWepRxEncryption- Rcv encrypted data via host - * s_byGetRateIdx- get rate index - * s_vGetDASA- get data offset - * s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3 * * Revision History: * */ #include "device.h" -#include "rxtx.h" -#include "tether.h" -#include "card.h" -#include "bssdb.h" -#include "mac.h" #include "baseband.h" -#include "michael.h" -#include "tkip.h" -#include "tcrc.h" -#include "wctl.h" -#include "wroute.h" #include "rf.h" -#include "iowpa.h" -#include "aes_ccmp.h" #include "dpc.h" -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ -static const unsigned char acbyRxRate[MAX_RATE] = -{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static unsigned char s_byGetRateIdx(unsigned char byRate); - -static void -s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, - PSEthernetHeader psEthHeader); - -static void -s_vProcessRxMACHeader(struct vnt_private *pDevice, unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize); - -static bool s_bAPModeRxCtl( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - int iSANodeIndex -); - -static bool s_bAPModeRxData( - struct vnt_private *pDevice, - struct sk_buff *skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex -); - -static bool s_bHandleRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -); - -static bool s_bHostWepRxEncryption( - - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 - -); - -/*--------------------- Export Variables --------------------------*/ - -/*+ - * - * Description: - * Translate Rcv 802.11 header to 802.3 header with Rx buffer - * - * Parameters: - * In: - * pDevice - * dwRxBufferAddr - Address of Rcv Buffer - * cbPacketSize - Rcv Packet size - * bIsWEP - If Rcv with WEP - * Out: - * pcbHeaderSize - 802.11 header size - * - * Return Value: None - * - -*/ -static void -s_vProcessRxMACHeader(struct vnt_private *pDevice, - unsigned char *pbyRxBufferAddr, - unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, - unsigned int *pcbHeadSize) -{ - unsigned char *pbyRxBuffer; - unsigned int cbHeaderSize = 0; - unsigned short *pwType; - PS802_11Header pMACHeader; - int ii; - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - s_vGetDASA((unsigned char *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader); - - if (bIsWEP) { - if (bExtIV) { - /* strip IV&ExtIV, add 8 byte */ - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8); - } else { - /* strip IV, add 4 byte */ - cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4); - } - } else { - cbHeaderSize += WLAN_HDR_ADDR3_LEN; - } - - pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); - if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) { - cbHeaderSize += 6; - } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) { - cbHeaderSize += 6; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) { - } else { - cbHeaderSize -= 8; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); /* 8 is IV&ExtIV */ - else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); /* 4 is IV */ - - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - } else { - cbHeaderSize -= 2; - pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize); - if (bIsWEP) { - if (bExtIV) - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); /* 8 is IV&ExtIV */ - else - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); /* 4 is IV */ - - } else { - *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN); - } - } - - cbHeaderSize -= (ETH_ALEN * 2); - pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); - for (ii = 0; ii < ETH_ALEN; ii++) - *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii]; - for (ii = 0; ii < ETH_ALEN; ii++) - *pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii]; - - *pcbHeadSize = cbHeaderSize; -} - -static unsigned char s_byGetRateIdx(unsigned char byRate) -{ - unsigned char byRateIdx; - - for (byRateIdx = 0; byRateIdx < MAX_RATE; byRateIdx++) { - if (acbyRxRate[byRateIdx % MAX_RATE] == byRate) - return byRateIdx; - } - - return 0; -} - -static void -s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, - PSEthernetHeader psEthHeader) -{ - unsigned int cbHeaderSize = 0; - PS802_11Header pMACHeader; - int ii; - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; - } - } else { - /* IBSS mode */ - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } else { - /* Is AP mode.. */ - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; - cbHeaderSize += 6; - } - } else { - for (ii = 0; ii < ETH_ALEN; ii++) { - psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } - *pcbHeaderSize = cbHeaderSize; -} - -bool -device_receive_frame( - struct vnt_private *pDevice, - PSRxDesc pCurrRD -) -{ - PDEVICE_RD_INFO pRDInfo = pCurrRD->pRDInfo; - struct net_device_stats *pStats = &pDevice->dev->stats; - struct sk_buff *skb; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = &(pDevice->pMgmt->sRxPacket); - PS802_11Header p802_11Header; - unsigned char *pbyRsr; - unsigned char *pbyNewRsr; - unsigned char *pbyRSSI; - __le64 *pqwTSFTime; - unsigned short *pwFrameSize; - unsigned char *pbyFrame; - bool bDeFragRx = false; - bool bIsWEP = false; - unsigned int cbHeaderOffset; - unsigned int FrameSize; - unsigned short wEtherType = 0; - int iSANodeIndex = -1; - int iDANodeIndex = -1; - unsigned int ii; - unsigned int cbIVOffset; - bool bExtIV = false; - unsigned char *pbyRxSts; - unsigned char *pbyRxRate; - unsigned char *pbySQ; - unsigned int cbHeaderSize; - PSKeyItem pKey = NULL; - unsigned short wRxTSC15_0 = 0; - unsigned long dwRxTSC47_16 = 0; - SKeyItem STempKey; - /* 802.11h RPI */ - unsigned long dwDuration = 0; - long ldBm = 0; - long ldBmThreshold = 0; - PS802_11Header pMACHeader; - bool bRxeapol_key = false; - - skb = pRDInfo->skb; - - pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, - pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); - - pwFrameSize = (unsigned short *)(skb->data + 2); - FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); - - /* - * Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - * Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR - */ - if ((FrameSize > 2364) || (FrameSize <= 32)) { - /* Frame Size error drop this packet. */ - pr_debug("---------- WRONG Length 1\n"); - return false; - } - - pbyRxSts = (unsigned char *)(skb->data); - pbyRxRate = (unsigned char *)(skb->data + 1); - pbyRsr = (unsigned char *)(skb->data + FrameSize - 1); - pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2); - pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3); - pbySQ = (unsigned char *)(skb->data + FrameSize - 4); - pqwTSFTime = (__le64 *)(skb->data + FrameSize - 12); - pbyFrame = (unsigned char *)(skb->data + 4); - - /* get packet size */ - FrameSize = cpu_to_le16(*pwFrameSize); - - if ((FrameSize > 2346)|(FrameSize < 14)) { /* - * Max: 2312Payload + 30HD +4CRC - * Min: 14 bytes ACK - */ - pr_debug("---------- WRONG Length 2\n"); - return false; - } - - /* update receive statistic counter */ - STAvUpdateRDStatCounter(&pDevice->scStatistic, - *pbyRsr, - *pbyNewRsr, - *pbyRxRate, - pbyFrame, - FrameSize); - - pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8); - - if (pDevice->bMeasureInProgress) { - if ((*pbyRsr & RSR_CRCOK) != 0) - pDevice->byBasicMap |= 0x01; - - dwDuration = FrameSize << 4; - dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; - if (*pbyRxRate <= RATE_11M) { - if (*pbyRxSts & 0x01) { - /* long preamble */ - dwDuration += 192; - } else { - /* short preamble */ - dwDuration += 96; - } - } else { - dwDuration += 16; - } - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - ldBmThreshold = -57; - for (ii = 7; ii > 0;) { - if (ldBm > ldBmThreshold) - break; - - ldBmThreshold -= 5; - ii--; - } - pDevice->dwRPIs[ii] += dwDuration; - return false; - } - - if (!is_multicast_ether_addr(pbyFrame)) { - if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) { - pDevice->s802_11Counter.FrameDuplicateCount++; - return false; - } - } - - /* Use for TKIP MIC */ - s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); - - /* filter packet send from myself */ - if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr, - pDevice->abyCurrentNetAddr)) - return false; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - p802_11Header = (PS802_11Header)(pbyFrame); - /* get SA NodeIndex */ - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { - pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; - pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex)) - return false; - } - - if (IS_FC_WEP(pbyFrame)) { - bool bRxDecryOK = false; - - pr_debug("rx WEP pkt\n"); - bIsWEP = true; - if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { - pKey = &STempKey; - pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; - pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; - pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; - pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; - pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; - memcpy(pKey->abyKey, - &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], - pKey->uKeyLength -); - - bRxDecryOK = s_bHostWepRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, - pKey, - pbyNewRsr, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } else { - bRxDecryOK = s_bHandleRxEncryption(pDevice, - pbyFrame, - FrameSize, - pbyRsr, - pbyNewRsr, - &pKey, - &bExtIV, - &wRxTSC15_0, - &dwRxTSC47_16); - } - - if (bRxDecryOK) { - if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { - pr_debug("ICV Fail\n"); - if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) - pDevice->s802_11Counter.TKIPICVErrors++; - else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - pDevice->s802_11Counter.CCMPDecryptErrors++; - } - return false; - } - } else { - pr_debug("WEP Func Fail\n"); - return false; - } - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) - FrameSize -= 8; /* Message Integrity Code */ - else - FrameSize -= 4; /* 4 is ICV */ - } - - /* RX OK, remove the CRC length */ - FrameSize -= ETH_FCS_LEN; - - if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && /* unicast address */ - (IS_FRAGMENT_PKT((skb->data+4))) -) { - /* defragment */ - bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV); - pDevice->s802_11Counter.ReceivedFragmentCount++; - if (bDeFragRx) { - /* defrag complete */ - skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; - FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; - - } else { - return false; - } - } - -/* Management & Control frame Handle */ - if ((IS_TYPE_DATA((skb->data+4))) == false) { - /* Handle Control & Manage Frame */ - - if (IS_TYPE_MGMT((skb->data+4))) { - unsigned char *pbyData1; - unsigned char *pbyData2; - - pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4); - pRxPacket->cbMPDULen = FrameSize; - pRxPacket->uRSSI = *pbyRSSI; - pRxPacket->bySQ = *pbySQ; - pRxPacket->qwLocalTSF = le64_to_cpu(*pqwTSFTime); - if (bIsWEP) { - /* strip IV */ - pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); - pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; - for (ii = 0; ii < (FrameSize - 4); ii++) { - *pbyData1 = *pbyData2; - pbyData1++; - pbyData2++; - } - } - pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); - pRxPacket->byRxChannel = (*pbyRxSts) >> 2; - - vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); - - /* hostap Deamon handle 802.11 management */ - if (pDevice->bEnableHostapd) { - skb->dev = pDevice->apdev; - skb->data += 4; - skb->tail += 4; - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; - } - } - - return false; - } else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - /* In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC. */ - if (!(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } else { - /* discard DATA packet while not associate || BSSID error */ - if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - { - unsigned char Protocol_Version; /* 802.1x Authentication */ - unsigned char Packet_Type; /* 802.1x Authentication */ - - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) | - skb->data[cbIVOffset + 8 + 24 + 6 + 1]; - Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1]; - Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 + 1 + 1]; - if (wEtherType == ETH_P_PAE) { /* Protocol Type in LLC-Header */ - if (((Protocol_Version == 1) || (Protocol_Version == 2)) && - (Packet_Type == 3)) { /*802.1x OR eapol-key challenge frame receive */ - bRxeapol_key = true; - } - } - } - } - } - -/* Data frame Handle */ - - if (pDevice->bEnablePSMode) { - if (!IS_FC_MOREDATA((skb->data+4))) { - if (pDevice->pMgmt->bInTIMWake == true) - pDevice->pMgmt->bInTIMWake = false; - } - } - - /* Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps */ - if (pDevice->bDiversityEnable && (FrameSize > 50) && - (pDevice->op_mode == NL80211_IFTYPE_STATION) && - pDevice->bLinkPass) { - BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); - } - - if (pDevice->byLocalID != REV_ID_VT3253_B1) - pDevice->uCurrRSSI = *pbyRSSI; - - pDevice->byCurrSQ = *pbySQ; - - if ((*pbyRSSI != 0) && - (pMgmt->pCurrBSS != NULL)) { - RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); - /* Monitor if RSSI is too strong. */ - pMgmt->pCurrBSS->byRSSIStatCnt++; - pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT; - pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm; - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) - if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) - pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm); - - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) { - unsigned char abyMacHdr[24]; - - /* Only 802.1x packet incoming allowed */ - if (bIsWEP) - cbIVOffset = 8; - else - cbIVOffset = 0; - wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) | - skb->data[cbIVOffset + 4 + 24 + 6 + 1]; - - pr_debug("wEtherType = %04x\n", wEtherType); - if (wEtherType == ETH_P_PAE) { - skb->dev = pDevice->apdev; - - if (bIsWEP) { - /* strip IV header(8) */ - memcpy(&abyMacHdr[0], (skb->data + 4), 24); - memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); - } - skb->data += (cbIVOffset + 4); - skb->tail += (cbIVOffset + 4); - skb_put(skb, FrameSize); - skb_reset_mac_header(skb); - - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - return true; - - } - /* check if 802.1x authorized */ - if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED)) - return false; - } - - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) - FrameSize -= 8; /* MIC */ - } - - /* Soft MIC */ - if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) { - if (bIsWEP) { - __le32 *pdwMIC_L; - __le32 *pdwMIC_R; - __le32 dwMIC_Priority; - __le32 dwMICKey0 = 0, dwMICKey1 = 0; - u32 dwLocalMIC_L = 0; - u32 dwLocalMIC_R = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); - } else { - if (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); - } else if ((pKey->dwKeyIndex & BIT28) == 0) { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20])); - } else { - dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24])); - dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28])); - } - } - - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - /* 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV. */ - MIC_vAppend((unsigned char *)(skb->data + 4 + WLAN_HDR_ADDR3_LEN + 8), - FrameSize - WLAN_HDR_ADDR3_LEN - 8); - MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R); - MIC_vUnInit(); - - pdwMIC_L = (__le32 *)(skb->data + 4 + FrameSize); - pdwMIC_R = (__le32 *)(skb->data + 4 + FrameSize + 4); - - if ((le32_to_cpu(*pdwMIC_L) != dwLocalMIC_L) || - (le32_to_cpu(*pdwMIC_R) != dwLocalMIC_R) || - pDevice->bRxMICFail) { - pr_debug("MIC comparison is fail!\n"); - pDevice->bRxMICFail = false; - pDevice->s802_11Counter.TKIPLocalMICFailures++; - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - /* send event to wpa_supplicant */ - { - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - int keyidx = pbyFrame[cbHeaderSize+3] >> 6; /* top two-bits */ - - memset(&ev, 0, sizeof(ev)); - ev.flags = keyidx & IW_MICFAILURE_KEY_ID; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { - ev.flags |= IW_MICFAILURE_PAIRWISE; - } else { - ev.flags |= IW_MICFAILURE_GROUP; - } - - ev.src_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(ev.src_addr.sa_data, - pMACHeader->abyAddr2); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); - - } -#endif - - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC) && - (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) { - wpahdr->type = VIAWGET_PTK_MIC_MSG; - } else { - wpahdr->type = VIAWGET_GTK_MIC_MSG; - } - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - - return false; - - } - } - } - - /* ++++++++++ Reply Counter Check +++++++++++++ */ - if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) || - (pKey->byCipherSuite == KEY_CTL_CCMP))) { - if (bIsWEP) { - unsigned short wLocalTSC15_0 = 0; - unsigned long dwLocalTSC47_16 = 0; - unsigned long long RSC = 0; - /* endian issues */ - RSC = *((unsigned long long *)&(pKey->KeyRSC)); - wLocalTSC15_0 = (unsigned short)RSC; - dwLocalTSC47_16 = (unsigned long)(RSC>>16); - - RSC = dwRxTSC47_16; - RSC <<= 16; - RSC += wRxTSC15_0; - pKey->KeyRSC = RSC; - - if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && - (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { - /* check RSC */ - if ((wRxTSC15_0 < wLocalTSC15_0) && - (dwRxTSC47_16 <= dwLocalTSC47_16) && - !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { - pr_debug("TSC is illegal~~!\n "); - if (pKey->byCipherSuite == KEY_CTL_TKIP) - pDevice->s802_11Counter.TKIPReplays++; - else - pDevice->s802_11Counter.CCMPReplays++; - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } - } - } - - s_vProcessRxMACHeader(pDevice, (unsigned char *)(skb->data+4), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset); - FrameSize -= cbHeaderOffset; - cbHeaderOffset += 4; /* 4 is Rcv buffer header */ - - /* Null data, framesize = 14 */ - if (FrameSize < 15) - return false; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (!s_bAPModeRxData(pDevice, - skb, - FrameSize, - cbHeaderOffset, - iSANodeIndex, - iDANodeIndex -)) { - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - } - return false; - } - } - - skb->data += cbHeaderOffset; - skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb->protocol = eth_type_trans(skb, skb->dev); - - /* drop frame not met IEEE 802.3 */ - - skb->ip_summed = CHECKSUM_NONE; - pStats->rx_bytes += skb->len; - pStats->rx_packets++; - netif_rx(skb); - - if (bDeFragRx) { - if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - pr_err("%s: can not alloc more frag bufs\n", - pDevice->dev->name); - } - return false; - } - - return true; -} - -static bool s_bAPModeRxCtl( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - int iSANodeIndex -) -{ - PS802_11Header p802_11Header; - CMD_STATUS Status; - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { - p802_11Header = (PS802_11Header)(pbyFrame); - if (!IS_TYPE_MGMT(pbyFrame)) { - /* Data & PS-Poll packet, check frame class */ - if (iSANodeIndex > 0) { - /* frame class 3 fliter & checking */ - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) { - /* - * send deauth notification - * reason = (6) class 2 received from nonauth sta - */ - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status -); - pr_debug("dpc: send vMgrDeAuthenBeginSta 1\n"); - return true; - } - if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { - /* - * send deassoc notification - * reason = (7) class 3 received from nonassoc sta - */ - vMgrDisassocBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS3_NONASSOC), - &Status -); - pr_debug("dpc: send vMgrDisassocBeginSta 2\n"); - return true; - } - - if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) { - /* delcare received ps-poll event */ - if (IS_CTL_PSPOLL(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 1\n"); - } else { - /* - * check Data PS state - * if PW bit off, send out all PS bufferring packets. - */ - if (!IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 2\n"); - } - } - } else { - if (IS_FC_POWERMGT(pbyFrame)) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = true; - /* Once if STA in PS state, enable multicast bufferring */ - pMgmt->sNodeDBTable[0].bPSEnable = true; - } else { - /* clear all pending PS frame. */ - if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { - pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; - pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; - bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - pr_debug("dpc: WLAN_CMD_RX_PSPOLL 3\n"); - - } - } - } - } else { - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - (unsigned char *)(p802_11Header->abyAddr2), - (WLAN_MGMT_REASON_CLASS2_NONAUTH), - &Status -); - pr_debug("dpc: send vMgrDeAuthenBeginSta 3\n"); - pr_debug("BSSID:%pM\n", - p802_11Header->abyAddr3); - pr_debug("ADDR2:%pM\n", - p802_11Header->abyAddr2); - pr_debug("ADDR1:%pM\n", - p802_11Header->abyAddr1); - pr_debug("dpc: wFrameCtl= %x\n", - p802_11Header->wFrameCtl); - VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); - pr_debug("dpc:pDevice->byRxMode = %x\n", - pDevice->byRxMode); - return true; - } - } - } - return false; -} - -static bool s_bHandleRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - unsigned char *pbyNewRsr, - PSKeyItem *pKeyOut, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -) -{ - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - PSKeyItem pKey = NULL; - unsigned char byDecMode = KEY_CTL_WEP; - PSMgmtObject pMgmt = pDevice->pMgmt; - - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; /* 6 is 802.11 address4 */ - PayloadLen -= 6; - } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - pr_debug("\nKeyIdx: %d\n", byKeyIdx); - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && - (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { - /* unicast pkt use pairwise key */ - pr_debug("unicast pkt\n"); - if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) { - if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - pr_debug("unicast pkt: %d, %p\n", byDecMode, pKey); - } else { - /* use group key */ - KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - pr_debug("group pkt: %d, %d, %p\n", - byKeyIdx, byDecMode, pKey); - } - } - /* our WEP only support Default Key */ - if (pKey == NULL) { - /* use default group key */ - KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey); - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - } - *pKeyOut = pKey; - - pr_debug("AES:%d %d %d\n", - pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); - - if (pKey == NULL) { - pr_debug("pKey == NULL\n"); - - return false; - } - if (byDecMode != pKey->byCipherSuite) { - - *pKeyOut = NULL; - return false; - } - if (byDecMode == KEY_CTL_WEP) { - /* handle WEP */ - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) { - /* - * Software WEP - * 1. 3253A - * 2. WEP 256 - */ - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); /* 24 is 802.11 header,4 is IV, 4 is crc */ - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); - - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) - *pbyNewRsr |= NEWRSR_DECRYPTOK; - - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - /* TKIP/AES */ - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); /* 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc */ - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); - if (byDecMode == KEY_CTL_TKIP) - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV + 2), *pbyIV)); - else - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - - pr_debug("TSC0_15: %x\n", *pwRxTSC15_0); - - if ((byDecMode == KEY_CTL_TKIP) && - (pDevice->byLocalID <= REV_ID_VT3253_A1)) { - /* - * Software TKIP - * 1. 3253 A - */ - PS802_11Header pMACHeader = (PS802_11Header)(pbyFrame); - - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("ICV OK!\n"); - } else { - pr_debug("ICV FAIL!!!\n"); - pr_debug("PayloadLen = %d\n", PayloadLen); - } - } - } - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; - return true; -} - -static bool s_bHostWepRxEncryption( - struct vnt_private *pDevice, - unsigned char *pbyFrame, - unsigned int FrameSize, - unsigned char *pbyRsr, - bool bOnFly, - PSKeyItem pKey, - unsigned char *pbyNewRsr, - bool *pbExtIV, - unsigned short *pwRxTSC15_0, - unsigned long *pdwRxTSC47_16 -) -{ - unsigned int PayloadLen = FrameSize; - unsigned char *pbyIV; - unsigned char byKeyIdx; - unsigned char byDecMode = KEY_CTL_WEP; - PS802_11Header pMACHeader; - - *pwRxTSC15_0 = 0; - *pdwRxTSC47_16 = 0; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - pbyIV += 6; /* 6 is 802.11 address4 */ - PayloadLen -= 6; - } - byKeyIdx = (*(pbyIV+3) & 0xc0); - byKeyIdx >>= 6; - pr_debug("\nKeyIdx: %d\n", byKeyIdx); - - if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP) - byDecMode = KEY_CTL_TKIP; - else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) - byDecMode = KEY_CTL_CCMP; - - pr_debug("AES:%d %d %d\n", - pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); - - if (byDecMode != pKey->byCipherSuite) - return false; - - if (byDecMode == KEY_CTL_WEP) { - /* handle WEP */ - pr_debug("byDecMode == KEY_CTL_WEP\n"); - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || - !bOnFly) { - /* - * Software WEP - * 1. 3253A - * 2. WEP 256 - * 3. NotOnFly - */ - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); /* 24 is 802.11 header,4 is IV, 4 is crc */ - memcpy(pDevice->abyPRNG, pbyIV, 3); - memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen); - - if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) - *pbyNewRsr |= NEWRSR_DECRYPTOK; - - } - } else if ((byDecMode == KEY_CTL_TKIP) || - (byDecMode == KEY_CTL_CCMP)) { - /* TKIP/AES */ - - PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); /* 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc */ - *pdwRxTSC47_16 = cpu_to_le32(*(unsigned long *)(pbyIV + 4)); - pr_debug("ExtIV: %lx\n", *pdwRxTSC47_16); - - if (byDecMode == KEY_CTL_TKIP) - *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); - else - *pwRxTSC15_0 = cpu_to_le16(*(unsigned short *)pbyIV); - - pr_debug("TSC0_15: %x\n", *pwRxTSC15_0); - - if (byDecMode == KEY_CTL_TKIP) { - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) { - /* - * Software TKIP - * 1. 3253 A - * 2. NotOnFly - */ - pr_debug("soft KEY_CTL_TKIP\n"); - pMACHeader = (PS802_11Header)(pbyFrame); - TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG); - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); - if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("ICV OK!\n"); - } else { - pr_debug("ICV FAIL!!!\n"); - pr_debug("PayloadLen = %d\n", - PayloadLen); - } - } - } - - if (byDecMode == KEY_CTL_CCMP) { - if (!bOnFly) { - /* - * Software CCMP - * NotOnFly - */ - pr_debug("soft KEY_CTL_CCMP\n"); - if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { - *pbyNewRsr |= NEWRSR_DECRYPTOK; - pr_debug("CCMP MIC compare OK!\n"); - } else { - pr_debug("CCMP MIC fail!\n"); - } - } - } - - } - - if ((*(pbyIV+3) & 0x20) != 0) - *pbExtIV = true; - return true; -} - -static bool s_bAPModeRxData( - struct vnt_private *pDevice, - struct sk_buff *skb, - unsigned int FrameSize, - unsigned int cbHeaderOffset, - int iSANodeIndex, - int iDANodeIndex -) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - bool bRelayAndForward = false; - bool bRelayOnly = false; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned short wAID; - - struct sk_buff *skbcpy = NULL; - - if (FrameSize > CB_MAX_BUF_SIZE) - return false; - /* check DA */ - if (is_multicast_ether_addr((unsigned char *)(skb->data+cbHeaderOffset))) { - if (pMgmt->sNodeDBTable[0].bPSEnable) { - skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz); - - /* if any node in PS mode, buffer packet until DTIM. */ - if (skbcpy == NULL) { - pr_info("relay multicast no skb available\n"); - } else { - skbcpy->dev = pDevice->dev; - skbcpy->len = FrameSize; - memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize); - skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy); - - pMgmt->sNodeDBTable[0].wEnQueueCnt++; - /* set tx map */ - pMgmt->abyPSTxMap[0] |= byMask[0]; - } - } else { - bRelayAndForward = true; - } - } else { - /* check if relay */ - if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data+cbHeaderOffset), &iDANodeIndex)) { - if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) { - if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) { - /* queue this skb until next PS tx, and then release. */ - - skb->data += cbHeaderOffset; - skb->tail += cbHeaderOffset; - skb_put(skb, FrameSize); - skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb); - pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; - wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; - pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - pr_debug("relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", - iDANodeIndex, (wAID >> 3), - pMgmt->abyPSTxMap[wAID >> 3]); - return true; - } else { - bRelayOnly = true; - } - } - } - } - - if (bRelayOnly || bRelayAndForward) { - /* relay this packet right now */ - if (bRelayAndForward) - iDANodeIndex = 0; - - if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) - ROUTEbRelay(pDevice, (unsigned char *)(skb->data + cbHeaderOffset), FrameSize, (unsigned int)iDANodeIndex); - - if (bRelayOnly) - return false; - } - /* none associate, don't forward */ - if (pDevice->uAssocCount == 0) - return false; - - return true; -} - static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb, u16 bytes_received) { diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index dd48e4125477..ad495719a251 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -29,15 +29,7 @@ #ifndef __DPC_H__ #define __DPC_H__ -#include "ttype.h" #include "device.h" -#include "wcmd.h" - -bool -device_receive_frame( - struct vnt_private *, - PSRxDesc pCurrRD -); bool vnt_receive_frame(struct vnt_private *priv, PSRxDesc curr_rd); -- GitLab From 55340d6bb898ed6993ed79a79cb6f3e14dfb4aad Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:27 +0000 Subject: [PATCH 2084/9457] staging: vt6655: remove dead functions in power.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/power.c | 171 --------------------------------- drivers/staging/vt6655/power.h | 16 --- drivers/staging/vt6655/wcmd.c | 2 - drivers/staging/vt6655/wmgr.c | 6 -- 4 files changed, 195 deletions(-) diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 53718026910c..040484e204e3 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -43,7 +43,6 @@ #include "wmgr.h" #include "power.h" #include "wcmd.h" -#include "rxtx.h" #include "card.h" /*--------------------- Static Definitions -------------------------*/ @@ -140,176 +139,6 @@ PSvDisablePowerSaving( pDevice->bPWBitOn = false; } -/*+ - * - * Routine Description: - * Consider to power down when no more packets to tx or rx. - * - * Return Value: - * true, if power down success - * false, if fail - -*/ - -bool -PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - // check if already in Doze mode - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - // check if in TIM wake period - if (pMgmt->bInTIMWake) - return false; - } - - // check scan state - if (pDevice->bCmdRunning) - return false; - - // Force PSEN on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - - // check if all TD are empty, - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - - // check if rx isr is clear - if (bCheckRxDMA && - ((pDevice->dwIsr & ISR_RXDMA0) != 0) && - ((pDevice->dwIsr & ISR_RXDMA1) != 0)) { - return false; - } - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - if (bCheckCountToWakeUp && - (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) { - return false; - } - } - - // no Tx, no Rx isr, now go to Doze - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; -} - -/*+ - * - * Routine Description: - * Send PS-POLL packet - * - * Return Value: - * None. - * - -*/ - -void -PSvSendPSPOLL( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxMgmtPacket pTxPacket = NULL; - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | - WLAN_SET_FC_PWRMGT(0) -)); - pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; - memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Send PS-Poll packet failed..\n"); -} - -/*+ - * - * Routine Description: - * Send NULL packet to AP for notification power state of STA - * - * Return Value: - * None. - * - -*/ -bool -PSbSendNullPacket( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uIdx; - - if (!pDevice->bLinkPass) - return false; - - if (!pDevice->bEnablePSMode && !pDevice->fTxDataInSleep) - return false; - - if (pDevice->bEnablePSMode) { - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - } - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - if (pDevice->bEnablePSMode) { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(1) -)); - } else { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(0) -)); - } - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) - pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_TODS(1)); - - memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - pr_debug("Send Null Packet failed !\n"); - return false; - } - - return true; -} /*+ * diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index 936f171a6b19..1083341b2a47 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -33,13 +33,6 @@ #define PS_FAST_INTERVAL 1 // Fast power saving listen interval #define PS_MAX_INTERVAL 4 // MAX power saving listen interval -bool -PSbConsiderPowerDown( - void *hDeviceContext, - bool bCheckRxDMA, - bool bCheckCountToWakeUp -); - void PSvDisablePowerSaving( void *hDeviceContext @@ -51,15 +44,6 @@ PSvEnablePowerSaving( unsigned short wListenInterval ); -void -PSvSendPSPOLL( - void *hDeviceContext -); - -bool -PSbSendNullPacket( - void *hDeviceContext -); bool PSbIsNextTBTTWakeUp( diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 53f81f1fefdc..33ee84f4c5a8 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -646,7 +646,6 @@ vCommandTimer( bClearBSSID_SCAN(pDevice); if (pDevice->byFOETuning) { BBvSetFOE(pDevice->PortOffset); - PSbSendNullPacket(pDevice); } if (netif_queue_stopped(pDevice->dev)) netif_wake_queue(pDevice->dev); @@ -1009,7 +1008,6 @@ BSSvSecondTxData( if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || pDevice->fWPA_Authened) { /* wpa linking */ pDevice->fTxDataInSleep = true; - PSbSendNullPacket(pDevice); /* send null packet */ pDevice->fTxDataInSleep = false; } diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index a1bada1173f3..72906b0d1d45 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -2025,19 +2025,13 @@ s_vMgrRxBeacon( pMgmt->bInTIMWake = true; // send out ps-poll packet - if (pMgmt->bInTIM) - PSvSendPSPOLL(pDevice); } else { pMgmt->bInTIMWake = false; pr_debug("BCN: Not In TIM..\n"); if (!pDevice->bPWBitOn) { pr_debug("BCN: Send Null Packet\n"); - if (PSbSendNullPacket(pDevice)) - pDevice->bPWBitOn = true; } - if (PSbConsiderPowerDown(pDevice, false, false)) - pr_debug("BCN: Power down now...\n"); } } -- GitLab From 185cb4e6ced612a987cd7e5995339271d885cdfe Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:28 +0000 Subject: [PATCH 2085/9457] staging: vt6655: dead code remove wmgr.c Remove all functions Header will be deleted later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/bssdb.c | 1 - drivers/staging/vt6655/wcmd.c | 60 - drivers/staging/vt6655/wmgr.c | 4597 ------------------------------- drivers/staging/vt6655/wmgr.h | 103 - 5 files changed, 4762 deletions(-) delete mode 100644 drivers/staging/vt6655/wmgr.c diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 2cad0d09cdd0..fa154ef10edc 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -10,7 +10,6 @@ vt6655_stage-y += device_main.o \ wctl.o \ 80211mgr.o \ wcmd.o \ - wmgr.o \ bssdb.o \ rxtx.o \ dpc.o \ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 996d3302ce3d..2b508ff5f492 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -443,7 +443,6 @@ BSSbInsertToBSSList( } if (bIs802_1x && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); if (pDevice->bLinkPass && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) || diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 33ee84f4c5a8..3c980806a515 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -244,37 +244,10 @@ s_MgrMakeProbeRequest( ) { PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBEREQ sFrame; pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; - vMgrEncodeProbeRequest(&sFrame); - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); - // Copy the SSID, pSSID->len=0 indicate broadcast SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - // Copy the extension rate set - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; return pTxPacket; } @@ -304,7 +277,6 @@ vCommandTimer( PSMgmtObject pMgmt = pDevice->pMgmt; PWLAN_IE_SSID pItemSSID; PWLAN_IE_SSID pItemSSIDCurr; - CMD_STATUS Status; unsigned int ii; unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; struct sk_buff *skb; @@ -456,7 +428,6 @@ vCommandTimer( } else { pr_debug("Send Disassociation Packet..\n"); // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); pDevice->bLinkPass = false; // unlock command busy pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; @@ -530,24 +501,12 @@ vCommandTimer( PSvDisablePowerSaving((void *)pDevice); BSSvClearNodeDBTable(pDevice, 0); - vMgrJoinBSSBegin((void *)pDevice, &Status); // if Infra mode if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { // Call mgr to begin the deauthentication // reason = (3) because sta has left ESS - if (pMgmt->eCurrState >= WMAC_STATE_AUTH) - vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); // Call mgr to begin the authentication - vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - pDevice->byLinkWaitCount = 0; - pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - pr_debug(" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); - return; - } } // if Adhoc mode else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { @@ -562,9 +521,6 @@ vCommandTimer( bClearBSSID_SCAN(pDevice); } else { // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); BSSvAddMulticastNode(pDevice); } @@ -574,9 +530,6 @@ vCommandTimer( if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { // start own IBSS - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); BSSvAddMulticastNode(pDevice); if (netif_queue_stopped(pDevice->dev)) @@ -607,15 +560,6 @@ vCommandTimer( // Call mgr to begin the association pDevice->byLinkWaitCount = 0; pr_debug("eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - pDevice->byLinkWaitCount = 0; - pr_debug("eCommandState = WLAN_ASSOCIATE_WAIT\n"); - pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - return; - } } else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { @@ -694,10 +638,6 @@ vCommandTimer( pMgmt->eCurrState = WMAC_STATE_IDLE; pDevice->bFixRate = false; - vMgrCreateOwnIBSS((void *)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) - pr_debug(" vMgrCreateOwnIBSS fail !\n"); - // alway turn off unicast bit MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); pDevice->byRxMode &= ~RCR_UNICAST; diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c deleted file mode 100644 index 72906b0d1d45..000000000000 --- a/drivers/staging/vt6655/wmgr.c +++ /dev/null @@ -1,4597 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wmgr.c - * - * Purpose: Handles the 802.11 management functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - * Functions: - * nsMgrObjectInitial - Initialize Management Object data structure - * vMgrObjectReset - Reset Management Object data structure - * vMgrAssocBeginSta - Start associate function - * vMgrReAssocBeginSta - Start reassociate function - * vMgrDisassocBeginSta - Start disassociate function - * s_vMgrRxAssocRequest - Handle Rcv associate_request - * s_vMgrRxAssocResponse - Handle Rcv associate_response - * vMrgAuthenBeginSta - Start authentication function - * vMgrDeAuthenDeginSta - Start deauthentication function - * s_vMgrRxAuthentication - Handle Rcv authentication - * s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1 - * s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2 - * s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3 - * s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4 - * s_vMgrRxDisassociation - Handle Rcv disassociation - * s_vMgrRxBeacon - Handle Rcv Beacon - * vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS - * vMgrJoinBSSBegin - Join BSS function - * s_vMgrSynchBSS - Synch & adopt BSS parameters - * s_MgrMakeBeacon - Create Baecon frame - * s_MgrMakeProbeResponse - Create Probe Response frame - * s_MgrMakeAssocRequest - Create Associate Request frame - * s_MgrMakeReAssocRequest - Create ReAssociate Request frame - * s_vMgrRxProbeResponse - Handle Rcv probe_response - * s_vMrgRxProbeRequest - Handle Rcv probe_request - * bMgrPrepareBeaconToSend - Prepare Beacon frame - * s_vMgrLogStatus - Log 802.11 Status - * vMgrRxManagePacket - Rcv management frame dispatch function - * s_vMgrFormatTIM- Assembler TIM field of beacon - * vMgrTimerInit- Initial 1-sec and command call back funtions - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "desc.h" -#include "device.h" -#include "card.h" -#include "channel.h" -#include "80211hdr.h" -#include "80211mgr.h" -#include "wmgr.h" -#include "wcmd.h" -#include "mac.h" -#include "bssdb.h" -#include "power.h" -#include "datarate.h" -#include "baseband.h" -#include "rxtx.h" -#include "wpa.h" -#include "rf.h" -#include "iowpa.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ -//2008-8-4 by chester -static bool ChannelExceedZoneType( - struct vnt_private *pDevice, - unsigned char byCurrChannel -); - -// Association/diassociation functions -static -PSTxMgmtPacket -s_MgrMakeAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -void -s_vMgrRxAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -); - -static -PSTxMgmtPacket -s_MgrMakeReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -void -s_vMgrRxAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType -); - -static -void -s_vMgrRxDisassociation( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// Authentication/deauthen functions -static -void -s_vMgrRxAuthenSequence_1( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_2( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_3( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthenSequence_4( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -); - -static -void -s_vMgrRxAuthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -static -void -s_vMgrRxDeauthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// Scan functions -// probe request/response functions -static -void -s_vMgrRxProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -static -void -s_vMgrRxProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -// beacon functions -static -void -s_vMgrRxBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan -); - -static -void -s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM -); - -static -PSTxMgmtPacket -s_MgrMakeBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// Association response -static -PSTxMgmtPacket -s_MgrMakeAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// ReAssociation response -static -PSTxMgmtPacket -s_MgrMakeReAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -// Probe response -static -PSTxMgmtPacket -s_MgrMakeProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType -); - -// received status -static -void -s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus -); - -static -void -s_vMgrSynchBSS( - struct vnt_private *pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus -); - -static bool -s_bCipherMatch( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK -); - -static void Encyption_Rebuild( - struct vnt_private *pDevice, - PKnownBSS pCurr -); - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Allocates and initializes the Management object. - * - * Return Value: - * Ndis_staus. - * - -*/ - -void -vMgrObjectInit( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0]; - pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0]; - pMgmt->uCurrChannel = pDevice->uChannel; - for (ii = 0; ii < WLAN_BSSID_LEN; ii++) - pMgmt->abyDesireBSSID[ii] = 0xFF; - - pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_NONE; - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - BSSvClearBSSList((void *)pDevice, false); -} - -/*+ - * - * Routine Description: - * Initializes timer object - * - * Return Value: - * Ndis_staus. - * - -*/ - -void -vMgrTimerInit( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - init_timer(&pMgmt->sTimerSecondCallback); - pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice; - pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack; - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->IsTxDataTrigger = false; - pDevice->nTxDataTimeCout = 0; - - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; -} - -/*+ - * - * Routine Description: - * Reset the management object structure. - * - * Return Value: - * None. - * - -*/ - -void -vMgrObjectReset( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bEnablePSMode = false; - // TODO: timer -} - -/*+ - * - * Routine Description: - * Start the station association procedure. Namely, send an - * association request frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - if (pMgmt->b11hEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - /* build an assocreq frame and send it */ - pTxPacket = s_MgrMakeAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if (pTxPacket != NULL) { - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } - } else { - *pStatus = CMD_STATUS_RESOURCES; - } -} - -/*+ - * - * Routine Description: - * Start the station re-association procedure. - * - * Return Value: - * None. - * - -*/ - -void -vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - pMgmt->wCurrCapInfo = 0; - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - if (pDevice->bEncryptionEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - - if (pMgmt->wListenInterval == 0) - pMgmt->wListenInterval = 1; // at least one. - - // ERP Phy (802.11g) should support short preamble. - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); - } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - } - - if (pMgmt->b11hEnable) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - - pTxPacket = s_MgrMakeReAssocRequest - ( - pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - pMgmt->wCurrCapInfo, - pMgmt->wListenInterval, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if (pTxPacket != NULL) { - /* send the frame */ - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus != CMD_STATUS_PENDING) - pr_debug("Mgt:Reassociation tx failed\n"); - else - pr_debug("Mgt:Reassociation tx sending\n"); - } -} - -/*+ - * - * Routine Description: - * Send an dis-association request frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_DISASSOC sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DISASSOC_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeDisassociation(&sFrame); - - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC) -)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set reason code - *(sFrame.pwReason) = cpu_to_le16(wReason); - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - // send the frame - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - *pStatus = CMD_STATUS_SUCCESS; - } -} - -/*+ - * - * Routine Description:(AP function) - * Handle incoming station association request frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -) -{ - WLAN_FR_ASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ)); - memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - vMgrDecodeAssocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - else - abyCurrExtSuppRates[1] = 0; - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) -); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - - pr_debug("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - - // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - // check if ERP support - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->bBarkerPreambleMd = true; - - pr_info("Associate AID= %d\n", wAssocAID); - pr_info("MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); - pr_info("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - } else { - /* TODO: received STA under state1 handle */ - return; - } - - // assoc response reply.. - pTxPacket = s_MgrMakeAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - if (pTxPacket != NULL) { - if (pDevice->bEnableHostapd) - return; - - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:Assoc response tx failed\n"); - else - pr_debug("Mgt:Assoc response tx sending..\n"); - } -} - -/*+ - * - * Description:(AP function) - * Handle incoming station re-association request frames. - * - * Parameters: - * In: - * pMgmt - Management Object structure - * pRxPacket - Received Packet - * Out: - * none - * - * Return Value: None. - * - -*/ - -static -void -s_vMgrRxReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - unsigned int uNodeIndex -) -{ - WLAN_FR_REASSOCREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned short wAssocStatus = 0; - unsigned short wAssocAID = 0; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) - return; - // node index not found - if (!uNodeIndex) - return; - //check if node is authenticated - //decode the frame - memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeReassocRequest(&sFrame); - - if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; - pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval); - pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = - WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false; - // Todo: check sta basic rate, if ap can't support, set status code - - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - uRateLen); - abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - uRateLen); - } else { - abyCurrExtSuppRates[1] = 0; - } - - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, - false, // do not change our basic rate - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) -); - - // set max tx rate - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - - pr_debug("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - - // Todo: check sta preamble, if ap can't support, set status code - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = - WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = - WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex; - wAssocStatus = WLAN_MGMT_STATUS_SUCCESS; - wAssocAID = (unsigned short)uNodeIndex; - - // if suppurt ERP - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M) - pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true; - - if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) { - // B only STA join - pDevice->bProtectMode = true; - pDevice->bNonERPPresent = true; - } - if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) - pDevice->bBarkerPreambleMd = true; - - pr_info("Rx ReAssociate AID= %d\n", wAssocAID); - pr_info("MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); - pr_info("Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); - - } - - // assoc response reply.. - pTxPacket = s_MgrMakeReAssocResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - wAssocStatus, - wAssocAID, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates - ); - - if (pTxPacket != NULL) { - /* send the frame */ - if (pDevice->bEnableHostapd) - return; - - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:ReAssoc response tx failed\n"); - else - pr_debug("Mgt:ReAssoc response tx sending..\n"); - } -} - -/*+ - * - * Routine Description: - * Handle incoming association response frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bReAssocType -) -{ - WLAN_FR_ASSOCRESP sFrame; - PWLAN_IE_SSID pItemSSID; - unsigned char *pbyIEs; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING || - pMgmt->eCurrState == WMAC_STATE_ASSOC) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - // decode the frame - vMgrDecodeAssocResponse(&sFrame); - if ((sFrame.pwCapInfo == NULL) || - (sFrame.pwStatus == NULL) || - (sFrame.pwAid == NULL) || - (sFrame.pSuppRates == NULL)) { - DBG_PORT80(0xCC); - return; - } - - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus); - pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid); - pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07; - - pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6; - pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength; - pbyIEs = pMgmt->sAssocInfo.abyIEs; - pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength); - - // save values and set current BSS state - if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - // set AID - pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid))); - if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1)) - pr_debug("AID from AP, has two msb clear\n"); - - pr_info("Association Successful, AID=%d\n", - pMgmt->wCurrAID & ~(BIT14 | BIT15)); - pMgmt->eCurrState = WMAC_STATE_ASSOC; - BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pr_info("Link with AP(SSID): %s\n", pItemSSID->abySSID); - pDevice->bLinkPass = true; - pDevice->uBBVGADiffCount = 0; - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength + - pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough - dev_kfree_skb(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_ASSOC_MSG; - wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len); - memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len, - pbyIEs, - wpahdr->resp_ie_len -); - skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -//2008-0409-07, by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - unsigned char buf[512]; - size_t len; - union iwreq_data wrqu; - int we_event; - - memset(buf, 0, 512); - - len = pMgmt->sAssocInfo.AssocInfo.RequestIELength; - if (len) { - memcpy(buf, pMgmt->sAssocInfo.abyIEs, len); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCREQIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); - } - - memset(buf, 0, 512); - len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength; - - if (len) { - memcpy(buf, pbyIEs, len); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = len; - we_event = IWEVASSOCRESPIE; - wireless_send_event(pDevice->dev, we_event, &wrqu, buf); - } - - memset(&wrqu, 0, sizeof(wrqu)); - ether_addr_copy(wrqu.ap_addr.sa_data, - &pMgmt->abyCurrBSSID[0]); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//End Add -- //2008-0409-07, by Einsn Liu - } else { - if (bReAssocType) { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } else { - // jump back to the auth state and indicate the error - pMgmt->eCurrState = WMAC_STATE_AUTH; - } - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus)))); - } - - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -//need clear flags related to Networkmanager - - pDevice->bwextcount = 0; - pDevice->bWPASuppWextEnabled = false; -#endif - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) - timer_expire(pDevice->sTimerCommand, 0); -} - -/*+ - * - * Routine Description: - * Start the station authentication procedure. Namely, send an - * authentication frame to the AP. - * - * Return Value: - * None. - * - -*/ - -void -vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY); - else - *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM); - - *(sFrame.pwAuthSequence) = cpu_to_le16(1); - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) { - pMgmt->eCurrState = WMAC_STATE_AUTHPENDING; - *pStatus = CMD_STATUS_SUCCESS; - } -} - -/*+ - * - * Routine Description: - * Start the station(AP) deauthentication procedure. Namely, send an - * deauthentication frame to the AP or Sta. - * - * Return Value: - * None. - * - -*/ - -void -vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - WLAN_FR_DEAUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN; - vMgrEncodeDeauthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN) -)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - *pStatus = csMgmt_xmit(pDevice, pTxPacket); - if (*pStatus == CMD_STATUS_PENDING) - *pStatus = CMD_STATUS_SUCCESS; -} - -/*+ - * - * Routine Description: - * Handle incoming authentication frames. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_AUTHEN sFrame; - - // we better be an AP or a STA in AUTHPENDING otherwise ignore - if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP || - pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) { - return; - } - - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeAuthen(&sFrame); - switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) { - case 1: - //AP function - s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame); - break; - case 2: - s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame); - break; - case 3: - //AP function - s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame); - break; - case 4: - s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame); - break; - default: - pr_debug("Auth Sequence error, seq = %d\n", - cpu_to_le16((*(sFrame.pwAuthSequence)))); - break; - } -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 1. Currently - * assumes we're an AP. So far, no one appears to use authentication - * in Ad-Hoc mode. - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_1( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uNodeIndex; - WLAN_FR_AUTHEN sFrame; - PSKeyItem pTransmitKey; - - // Insert a Node entry - if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - BSSvCreateOneNode(pDevice, &uNodeIndex); - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2, - WLAN_ADDR_LEN); - } - - if (pMgmt->bShareKeyAlgorithm) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1; - } else { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - } - - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(2); - - if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - } else { - if (pMgmt->bShareKeyAlgorithm) - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG); - else - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - } - - if (pMgmt->bShareKeyAlgorithm && - (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) { - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN); - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) { - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3); - rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN); - } - memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN); - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) - return; - - pr_debug("Mgt:Authreq_reply sequence_1 tx..\n"); - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Authreq_reply sequence_1 tx failed\n"); -} - -/*+ - * - * Routine Description: - * Handles incoming auth frames with sequence number 2. Currently - * assumes we're a station. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_2( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - WLAN_FR_AUTHEN sFrame; - PSTxMgmtPacket pTxPacket = NULL; - - switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) { - case WLAN_AUTH_ALG_OPENSYSTEM: - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pr_info("802.11 Authen (OPEN) Successful\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } else { - pr_info("802.11 Authen (OPEN) Failed\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - - break; - - case WLAN_AUTH_ALG_SHAREDKEY: - - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - // insert values - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(1) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(3); - *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS); - sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len); - sFrame.len += WLAN_CHALLENGE_IE_LEN; - sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE; - sFrame.pChallenge->len = WLAN_CHALLENGE_LEN; - memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN); - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Auth_reply sequence_2 tx failed\n"); - - pr_debug("Mgt:Auth_reply sequence_2 tx ...\n"); - } else { - pr_debug("Mgt:rx Auth_reply sequence_2 status error ...\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - } - break; - default: - pr_debug("Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", - cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); - break; - } -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 3. Currently - * assumes we're an AP. This function assumes the frame has - * already been successfully decrypted. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxAuthenSequence_3( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - PSTxMgmtPacket pTxPacket = NULL; - unsigned int uStatusCode = 0; - unsigned int uNodeIndex = 0; - WLAN_FR_AUTHEN sFrame; - - if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) { - uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ; - goto reply; - } - if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) { - uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL; - goto reply; - } - } else { - uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE; - goto reply; - } - - if (uNodeIndex) { - pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH; - pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0; - } - uStatusCode = WLAN_MGMT_STATUS_SUCCESS; - pr_debug("Challenge text check ok..\n"); - -reply: - // send auth reply - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_AUTHEN_FR_MAXLEN; - // format buffer structure - vMgrEncodeAuthen(&sFrame); - /* insert values */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)| - WLAN_SET_FC_ISWEP(0) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm); - *(sFrame.pwAuthSequence) = cpu_to_le16(4); - *(sFrame.pwStatus) = cpu_to_le16(uStatusCode); - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - // send the frame - if (pDevice->bEnableHostapd) - return; - - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Mgt:Authreq_reply sequence_4 tx failed\n"); -} - -/*+ - * - * Routine Description: - * Handles incoming authen frames with sequence 4 - * - * - * Return Value: - * None. - * - -*/ -static -void -s_vMgrRxAuthenSequence_4( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PWLAN_FR_AUTHEN pFrame -) -{ - if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - pr_info("802.11 Authen (SHAREDKEY) Successful\n"); - pMgmt->eCurrState = WMAC_STATE_AUTH; - timer_expire(pDevice->sTimerCommand, 0); - } else{ - pr_info("802.11 Authen (SHAREDKEY) Failed\n"); - s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); - pMgmt->eCurrState = WMAC_STATE_IDLE; - } -} - -/*+ - * - * Routine Description: - * Handles incoming disassociation frames - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxDisassociation( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_DISASSOC sFrame; - unsigned int uNodeIndex = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - pr_debug("Rx disassoc, sta not found\n"); - - } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDisassociation(&sFrame); - pr_info("AP disassociated me, reason=%d\n", - cpu_to_le16(*(sFrame.pwReason))); - //TODO: do something let upper layer know or - //try to send associate packet again because of inactivity timeout - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - pr_debug("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } - /* else, ignore it */ -} - -/*+ - * - * Routine Description: - * Handles incoming deauthentication frames - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxDeauthentication( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_DEAUTHEN sFrame; - unsigned int uNodeIndex = 0; - viawget_wpa_header *wpahdr; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - //Todo: - // if is acting an AP.. - // a STA is leaving this BSS.. - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - BSSvRemoveOneNode(pDevice, uNodeIndex); - else - pr_info("Rx deauth, sta not found\n"); - } else { - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeDeauthen(&sFrame); - pr_info("AP deauthed me, reason=%d\n", - cpu_to_le16((*(sFrame.pwReason)))); - // TODO: update BSS list for specific BSSID if pre-authentication case - if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3, - pMgmt->abyCurrBSSID)) { - if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - - } - /* else, ignore it. TODO: IBSS authentication service - would be implemented here */ - } -} - -//2008-8-4 by chester -/*+ - * - * Routine Description: - * check if current channel is match ZoneType. - *for USA:1~11; - * Japan:1~13; - * Europe:1~13 - * Return Value: - * True:exceed; - * False:normal case - -*/ -static bool -ChannelExceedZoneType( - struct vnt_private *pDevice, - unsigned char byCurrChannel -) -{ - bool exceed = false; - - switch (pDevice->byZoneType) { - case 0x00: //USA:1~11 - if ((byCurrChannel < 1) || (byCurrChannel > 11)) - exceed = true; - break; - case 0x01: //Japan:1~13 - case 0x02: //Europe:1~13 - if ((byCurrChannel < 1) || (byCurrChannel > 13)) - exceed = true; - break; - default: //reserve for other zonetype - break; - } - - return exceed; -} - -/*+ - * - * Routine Description: - * Handles and analysis incoming beacon frames. - * - * - * Return Value: - * None. - * - -*/ - -static -void -s_vMgrRxBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket, - bool bInScan -) -{ - PKnownBSS pBSSList; - WLAN_FR_BEACON sFrame; - u64 qwTSFOffset; - bool bIsBSSIDEqual = false; - bool bIsSSIDEqual = false; - bool bTSFLargeDiff = false; - bool bTSFOffsetPostive = false; - bool bUpdateTSF = false; - bool bIsAPBeacon = false; - bool bIsChannelEqual = false; - unsigned int uLocateByteIndex; - unsigned char byTIMBitOn = 0; - unsigned short wAIDNumber = 0; - unsigned int uNodeIndex; - u64 qwTimestamp, qwLocalTSF; - u64 qwCurrTSF; - unsigned short wStartIndex = 0; - unsigned short wAIDIndex = 0; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - bool bChannelHit = false; - bool bUpdatePhyParameter = false; - unsigned char byIEChannel = 0; - - memset(&sFrame, 0, sizeof(WLAN_FR_BEACON)); - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - - // decode the beacon frame - vMgrDecodeBeacon(&sFrame); - - if ((sFrame.pwBeaconInterval == NULL) || - (sFrame.pwCapInfo == NULL) || - (sFrame.pSSID == NULL) || - (sFrame.pSuppRates == NULL)) { - pr_debug("Rx beacon frame error\n"); - return; - } - - if (sFrame.pDSParms != NULL) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } -//2008-0730-01by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel)) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList == NULL) { - pr_debug("Beacon/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket -); - } else { - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket -); - - } - - if (bInScan) - return; - - if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel) - bIsChannelEqual = true; - - if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - // if rx beacon without ERP field - if (sERP.bERPExist) { - if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) { - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - } else { - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - if (!sERP.bERPExist) - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - } - - // set to MAC&BBP - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) - return; - - // check if BSSID the same - if (memcmp(sFrame.pHdr->sA3.abyAddr3, - pMgmt->abyCurrBSSID, - WLAN_BSSID_LEN) == 0) { - bIsBSSIDEqual = true; - -// 2008-05-21 by Richardtai - pDevice->uCurrRSSI = pRxPacket->uRSSI; - pDevice->byCurrSQ = pRxPacket->bySQ; - - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - } - // check if SSID the same - if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) { - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - sFrame.pSSID->len -) == 0) { - bIsSSIDEqual = true; - } - } - - if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) && - bIsBSSIDEqual && - bIsSSIDEqual && - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // add state check to prevent reconnect fail since we'll receive Beacon - - bIsAPBeacon = true; - - if (pBSSList != NULL) { - // Compare PHY parameter setting - if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) { - bUpdatePhyParameter = true; - pMgmt->wCurrCapInfo = pBSSList->wCapInfo; - } - if (sFrame.pERP != NULL) { - if ((sFrame.pERP->byElementID == WLAN_EID_ERP) && - (pMgmt->byERPContext != sFrame.pERP->byContext)) { - bUpdatePhyParameter = true; - pMgmt->byERPContext = sFrame.pERP->byContext; - } - } - // - // Basic Rate Set may change dynamically - // - if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) - ); - if (bUpdatePhyParameter) { - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - } - if (sFrame.pIE_PowerConstraint != NULL) { - CARDvSetPowerConstraint(pMgmt->pAdapter, - (unsigned char) pBSSList->uChannel, - sFrame.pIE_PowerConstraint->byPower -); - } - if (sFrame.pIE_CHSW != NULL) { - CARDbChannelSwitch(pMgmt->pAdapter, - sFrame.pIE_CHSW->byMode, - get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode), - sFrame.pIE_CHSW->byCount - ); - - } else if (!bIsChannelEqual) { - set_channel(pMgmt->pAdapter, pBSSList->uChannel); - } - } - } - -// pr_debug("Beacon 2\n"); - // check if CF field exists - if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { - if (sFrame.pCFParms->wCFPDurRemaining > 0) { - // TODO: deal with CFP period to set NAV - } - } - - qwTimestamp = le64_to_cpu(*sFrame.pqwTimestamp); - qwLocalTSF = pRxPacket->qwLocalTSF; - - // check if beacon TSF larger or small than our local TSF - if (qwTimestamp >= qwLocalTSF) - bTSFOffsetPostive = true; - else - bTSFOffsetPostive = false; - - if (bTSFOffsetPostive) - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF)); - else - qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp)); - - if (qwTSFOffset > TRIVIAL_SYNC_DIFFERENCE) - bTSFLargeDiff = true; - - // if infra mode - if (bIsAPBeacon) { - // Infra mode: Local TSF always follow AP's TSF if Difference huge. - if (bTSFLargeDiff) - bUpdateTSF = true; - - if (pDevice->bEnablePSMode && (sFrame.pTIM != NULL)) { - // deal with DTIM, analysis TIM - pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false; - pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; - pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod; - wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15); - - // check if AID in TIM field bit on - // wStartIndex = N1 - wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1; - // AIDIndex = N2 - wAIDIndex = (wAIDNumber >> 3); - if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) { - uLocateByteIndex = wAIDIndex - wStartIndex; - // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250] - if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) { - byTIMBitOn = (0x01) << ((wAIDNumber) % 8); - pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false; - } else { - pMgmt->bInTIM = false; - } - } else { - pMgmt->bInTIM = false; - } - - if (pMgmt->bInTIM || - (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) { - pMgmt->bInTIMWake = true; - // send out ps-poll packet - - - } else { - pMgmt->bInTIMWake = false; - pr_debug("BCN: Not In TIM..\n"); - if (!pDevice->bPWBitOn) { - pr_debug("BCN: Send Null Packet\n"); - } - } - - } - - } - // if adhoc mode - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) { - if (bIsBSSIDEqual) { - // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count. - if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - // adhoc mode:TSF updated only when beacon larger than local TSF - if (bTSFLargeDiff && bTSFOffsetPostive && - (pMgmt->eCurrState == WMAC_STATE_JOINTED)) - bUpdateTSF = true; - - // During dpc, already in spinlocked. - if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) { - // Update the STA, (Technically the Beacons of all the IBSS nodes - // should be identical, but that's not happening in practice. - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0; - } else { - // Todo, initial Node content - BSSvCreateOneNode(pDevice, &uNodeIndex); - - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, - true, - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate) - ); - - memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo); - pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; - { - pr_debug("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex); - } - } - - // if other stations joined, indicate connection to upper layer.. - if (pMgmt->eCurrState == WMAC_STATE_STARTED) { - pr_debug("Current IBSS State: [Started]........to: [Jointed]\n"); - pMgmt->eCurrState = WMAC_STATE_JOINTED; - pDevice->bLinkPass = true; - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - - } - } else if (bIsSSIDEqual) { - // See other adhoc sta with the same SSID but BSSID is different. - // adpot this vars only when TSF larger then us. - if (bTSFLargeDiff && bTSFOffsetPostive) { - // we don't support ATIM under adhoc mode - // if (sFrame.pIBSSParms->wATIMWindow == 0) { - // adpot this vars - // TODO: check sFrame cap if privacy on, and support rate syn - memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN); - memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow); - pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval); - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set HW beacon interval and re-synchronizing.... - pr_debug("Rejoining to Other Adhoc group with same SSID........\n"); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - // Turn off bssid filter to avoid filter others adhoc station which bssid is different. - MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates); - - // Prepare beacon frame - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } - } - } - // endian issue ??? - // Update TSF -if (bUpdateTSF) { - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF); - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod); - } -} - -/*+ - * - * Routine Description: - * Instructs the hw to create a bss using the supplied - * attributes. Note that this implementation only supports Ad-Hoc - * BSS creation. - * - * - * Return Value: - * CMD_STATUS - * - -*/ -void -vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wMaxBasicRate; - unsigned short wMaxSuppRate; - unsigned char byTopCCKBasicRate; - unsigned char byTopOFDMBasicRate; - u64 qwCurrTSF; - unsigned int ii; - unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60}; - unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96}; - unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned short wSuppRate; - - pr_debug("Create Basic Service Set .......\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) && - (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) { - // encryption mode error - *pStatus = CMD_STATUS_FAILURE; - return; - } - } - - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES; - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - pMgmt->eCurrentPHYMode = pMgmt->byAPBBType; - } else { - if (pDevice->byBBType == BB_TYPE_11G) - pMgmt->eCurrentPHYMode = PHY_TYPE_11G; - if (pDevice->byBBType == BB_TYPE_11B) - pMgmt->eCurrentPHYMode = PHY_TYPE_11B; - if (pDevice->byBBType == BB_TYPE_11A) - pMgmt->eCurrentPHYMode = PHY_TYPE_11A; - } - - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { - pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } else { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 0; - for (ii = 0; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii]; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - pMgmt->abyCurrSuppRates[1] = 8; - pMgmt->abyCurrExtSuppRates[1] = 4; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii]; - for (ii = 4; ii < 8; ii++) - pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4]; - for (ii = 0; ii < 4; ii++) - pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4]; - } - - // Disable Protect Mode - pDevice->bProtectMode = false; - MACvDisableProtectMD(pDevice->PortOffset); - - pDevice->bBarkerPreambleMd = false; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - - // Kyle Test 2003.11.04 - - // set HW beacon interval - if (pMgmt->wIBSSBeaconPeriod == 0) - pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - // clear TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); - // enable TSF counter - VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); - - // set Next TBTT - CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod); - - pMgmt->uIBSSChannel = pDevice->uChannel; - - if (pMgmt->uIBSSChannel == 0) - pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL; - - // set basic rate - - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) - pMgmt->eCurrMode = WMAC_MODE_ESS_AP; - - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { - memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6); - pMgmt->byIBSSDFSRecovery = 10; - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; - } - - // Adopt pre-configured IBSS vars to current vars - pMgmt->eCurrState = WMAC_STATE_STARTED; - pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod; - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow; - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pDevice->uCurrRSSI = 0; - pDevice->byCurrSQ = 0; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrSSID, - pMgmt->abyDesireSSID, - ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN -); - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - // AP mode BSSID = MAC addr - memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pr_info("AP beacon created BSSID:%pM\n", - pMgmt->abyCurrBSSID); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // BSSID selected must be randomized as spec 11.1.3 - pMgmt->abyCurrBSSID[5] = (u8) (qwCurrTSF & 0x000000ff); - pMgmt->abyCurrBSSID[4] = (u8) ((qwCurrTSF & 0x0000ff00) >> 8); - pMgmt->abyCurrBSSID[3] = (u8) ((qwCurrTSF & 0x00ff0000) >> 16); - pMgmt->abyCurrBSSID[2] = (u8) ((qwCurrTSF & 0x00000ff0) >> 4); - pMgmt->abyCurrBSSID[1] = (u8) ((qwCurrTSF & 0x000ff000) >> 12); - pMgmt->abyCurrBSSID[0] = (u8) ((qwCurrTSF & 0x0ff00000) >> 20); - pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0]; - pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1]; - pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2]; - pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3]; - pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4]; - pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5]; - pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP; - pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - - pr_info("Adhoc beacon created bssid:%pM\n", - pMgmt->abyCurrBSSID); - } - - // Set Capability Info - pMgmt->wCurrCapInfo = 0; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1); - pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD; - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1); - - if (pDevice->bEncryptionEnable) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - pMgmt->byCSSPK = KEY_CTL_CCMP; - pMgmt->byCSSGK = KEY_CTL_CCMP; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - pMgmt->byCSSPK = KEY_CTL_TKIP; - pMgmt->byCSSGK = KEY_CTL_TKIP; - } else { - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } else { - pMgmt->byCSSPK = KEY_CTL_WEP; - pMgmt->byCSSGK = KEY_CTL_WEP; - } - } - - pMgmt->byERPContext = 0; - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_AP); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - } - - CARDbSetPhyParameter(pMgmt->pAdapter, - pMgmt->eCurrentPHYMode, - pMgmt->wCurrCapInfo, - pMgmt->byERPContext, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ); - - CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod); - // set channel and clear NAV - set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel); - pMgmt->uCurrChannel = pMgmt->uIBSSChannel; - - if (CARDbIsShortPreamble(pMgmt->pAdapter)) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - else - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1)); - - if (pMgmt->b11hEnable && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); - } else { - pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1)); - } - - pMgmt->eCurrState = WMAC_STATE_STARTED; - // Prepare beacon to send - if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) - *pStatus = CMD_STATUS_SUCCESS; -} - -/*+ - * - * Routine Description: - * Instructs wmac to join a bss using the supplied attributes. - * The arguments may the BSSID or SSID and the rest of the - * attributes are obtained from the scan result of known bss list. - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pCurr = NULL; - unsigned int ii, uu; - PWLAN_IE_SUPP_RATES pItemRates = NULL; - PWLAN_IE_SUPP_RATES pItemExtRates = NULL; - PWLAN_IE_SSID pItemSSID; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - unsigned short wMaxBasicRate = RATE_1M; - unsigned short wMaxSuppRate = RATE_1M; - unsigned short wSuppRate; - unsigned char byTopCCKBasicRate = RATE_1M; - unsigned char byTopOFDMBasicRate = RATE_1M; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive) - break; - } - - if (ii == MAX_BSS_NUM) { - *pStatus = CMD_STATUS_RESOURCES; - pr_info("BSS finding:BSS list is empty\n"); - return; - } - - // Search known BSS list for prefer BSSID or SSID - - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pMgmt->eConfigPHYMode -); - - if (pCurr == NULL) { - *pStatus = CMD_STATUS_RESOURCES; - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pr_info("Scanning [%s] not found, disconnected !\n", - pItemSSID->abySSID); - return; - } - - pr_info("AP(BSS) finding:Found a AP(BSS)..\n"); - if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) { - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { - // patch for CISCO migration mode - } - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - Encyption_Rebuild(pDevice, pCurr); -#endif - // Infrastructure BSS - s_vMgrSynchBSS(pDevice, - WMAC_MODE_ESS_STA, - pCurr, - pStatus -); - - if (*pStatus == CMD_STATUS_SUCCESS) { - // Adopt this BSS state vars in Mgmt Object - pMgmt->uCurrChannel = pCurr->uChannel; - - memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - - pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates; - pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates; - - // Parse Support Rate IE - pItemRates->byElementID = WLAN_EID_SUPP_RATES; - pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - pItemRates, - uRateLen); - - // Parse Extension Support Rate IE - pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES; - pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates, - pItemExtRates, - uRateLen); - // Stuffing Rate IE - if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) { - for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) { - pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii]; - ii++; - if (pItemExtRates->len <= ii) - break; - } - pItemRates->len += (unsigned char)ii; - if (pItemExtRates->len - ii > 0) { - pItemExtRates->len -= (unsigned char)ii; - for (uu = 0; uu < pItemExtRates->len; uu++) - pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii]; - } else { - pItemExtRates->len = 0; - } - } - - RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true, - &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - // TODO: deal with if wCapInfo the privacy is on, but station WEP is off - // TODO: deal with if wCapInfo the PS-Pollable is on. - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - pMgmt->eCurrMode = WMAC_MODE_ESS_STA; - - pMgmt->eCurrState = WMAC_STATE_JOINTED; - - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - - pr_debug("bAdd_PMKID_Candidate: 1(%d)\n", - bResult); - if (!bResult) { - vFlush_PMKID_Candidate((void *)pDevice); - pr_debug("vFlush_PMKID_Candidate: 4\n"); - bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - } - } - - // Preamble type auto-switch: if AP can receive short-preamble cap, - // we can turn on too. - - pr_debug("Join ESS\n"); - - pr_debug("End of Join AP -- A/B/G Action\n"); - } else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - - } else { - // ad-hoc mode BSS - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } else { - // encryption mode error - pMgmt->eCurrState = WMAC_STATE_IDLE; - return; - } - } - - s_vMgrSynchBSS(pDevice, - WMAC_MODE_IBSS_STA, - pCurr, - pStatus -); - - if (*pStatus == CMD_STATUS_SUCCESS) { - // Adopt this BSS state vars in Mgmt Object - // TODO: check if CapInfo privacy on, but we don't.. - pMgmt->uCurrChannel = pCurr->uChannel; - - // Parse Support Rate IE - pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES; - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - WLAN_RATES_MAXLEN_11B); - // set basic rate - RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, - &byTopCCKBasicRate, &byTopOFDMBasicRate); - - pMgmt->wCurrCapInfo = pCurr->wCapInfo; - pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval; - memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); - memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN); - MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - pMgmt->eCurrMode = WMAC_MODE_IBSS_STA; - - pMgmt->eCurrState = WMAC_STATE_STARTED; - - pr_debug("Join IBSS ok:%pM\n", - pMgmt->abyCurrBSSID); - // Preamble type auto-switch: if AP can receive short-preamble cap, - // and if registry setting is short preamble we can turn on too. - - // Prepare beacon - bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); - } else { - pMgmt->eCurrState = WMAC_STATE_IDLE; - } - } -} - -/*+ - * - * Routine Description: - * Set HW to synchronize a specific BSS from known BSS list. - * - * - * Return Value: - * PCM_STATUS - * - -*/ -static -void -s_vMgrSynchBSS( - struct vnt_private *pDevice, - unsigned int uBSSMode, - PKnownBSS pCurr, - PCMD_STATUS pStatus -) -{ - CARD_PHY_TYPE ePhyType = PHY_TYPE_11B; - PSMgmtObject pMgmt = pDevice->pMgmt; - - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - - *pStatus = CMD_STATUS_FAILURE; - - if (!s_bCipherMatch(pCurr, - pDevice->eEncryptionStatus, - &(pMgmt->byCSSPK), - &(pMgmt->byCSSGK))) { - pr_debug("s_bCipherMatch Fail .......\n"); - return; - } - - pMgmt->pCurrBSS = pCurr; - - // if previous mode is IBSS. - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY); - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - // Init the BSS informations - pDevice->bProtectMode = false; - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bNonERPPresent = false; - pDevice->byPreambleType = 0; - pDevice->wBasicRate = 0; - // Set Basic Rate - CARDbAddBasicRate((void *)pDevice, RATE_1M); - // calculate TSF offset - // TSF Offset = Received Timestamp TSF - Marked Local's TSF - CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF); - - CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval); - - // set Next TBTT - // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval); - - // set BSSID - MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID); - - MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - - pr_debug("Sync:set CurrBSSID address = %pM\n", pMgmt->abyCurrBSSID); - - if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11A; - } else { - return; - } - } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) || - (pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } else { - if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) || - (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) { - ePhyType = PHY_TYPE_11G; - } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) { - ePhyType = PHY_TYPE_11B; - } else { - return; - } - } - - if (ePhyType == PHY_TYPE_11A) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else if (ePhyType == PHY_TYPE_11B) { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB)); - pMgmt->abyCurrExtSuppRates[1] = 0; - } else { - memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG)); - memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG)); - } - - if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, NL80211_IFTYPE_STATION); - // Add current BSS to Candidate list - // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap); - } else { - CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, NL80211_IFTYPE_ADHOC); - } - - if (!CARDbSetPhyParameter(pMgmt->pAdapter, - ePhyType, - pCurr->wCapInfo, - pCurr->sERP.byERP, - pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates)) { - pr_debug("<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); - return; - } - // set channel and clear NAV - if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) { - pr_debug("<----s_bSynchBSS Set Channel [%d]\n", - pCurr->uChannel); - return; - } - - pMgmt->uCurrChannel = pCurr->uChannel; - pMgmt->eCurrentPHYMode = ePhyType; - pMgmt->byERPContext = pCurr->sERP.byERP; - pr_debug("Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); - - *pStatus = CMD_STATUS_SUCCESS; - - return; -}; - -//mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption -// ,need reset eAuthenMode and eEncryptionStatus -static void Encyption_Rebuild( - struct vnt_private *pDevice, - PKnownBSS pCurr -) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. - if (pCurr->bWPAValid) { //WPA-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; - if (pCurr->abyPKType[0] == WPA_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n"); - } else if (pCurr->abyPKType[0] == WPA_AESCCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n"); - } - } else if (pCurr->bWPA2Valid) { //WPA2-PSK - pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; - if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n"); - } else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) { - pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES - PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n"); - } - } - } -} - -/*+ - * - * Routine Description: - * Format TIM field - * - * - * Return Value: - * void - * - -*/ - -static -void -s_vMgrFormatTIM( - PSMgmtObject pMgmt, - PWLAN_IE_TIM pTIM -) -{ - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - unsigned char byMap; - unsigned int ii, jj; - bool bStartFound = false; - bool bMulticast = false; - unsigned short wStartIndex = 0; - unsigned short wEndIndex = 0; - - // Find size of partial virtual bitmap - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - byMap = pMgmt->abyPSTxMap[ii]; - if (!ii) { - // Mask out the broadcast bit which is indicated separately. - bMulticast = (byMap & byMask[0]) != 0; - if (bMulticast) - pMgmt->sNodeDBTable[0].bRxPSPoll = true; - - byMap = 0; - } - if (byMap) { - if (!bStartFound) { - bStartFound = true; - wStartIndex = ii; - } - wEndIndex = ii; - } - } - - // Round start index down to nearest even number - wStartIndex &= ~BIT0; - - // Round end index up to nearest even number - wEndIndex = ((wEndIndex + 1) & ~BIT0); - - // Size of element payload - - pTIM->len = 3 + (wEndIndex - wStartIndex) + 1; - - // Fill in the Fixed parts of the TIM - pTIM->byDTIMCount = pMgmt->byDTIMCount; - pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod; - pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) | - (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK); - - // Append variable part of TIM - - for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++) - pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii]; - - // Aid = 0 don't used. - pTIM->byVirtBitMap[0] &= ~BIT0; -} - -/*+ - * - * Routine Description: - * Constructs an Beacon frame(Ad-hoc mode) - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static -PSTxMgmtPacket -s_MgrMakeBeacon( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_BEACON sFrame; - unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - // prepare beacon frame - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_BEACON_FR_MAXLEN; - vMgrEncodeBeacon(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON) -)); - - if (pDevice->bEnablePSMode) - sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1)); - - memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN -); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - // TIM field - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len); - sFrame.pTIM->byElementID = WLAN_EID_TIM; - s_vMgrFormatTIM(pMgmt, sFrame.pTIM); - sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len); - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - /* RSN parameter */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 12; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP - else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) - sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40 - else - sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 0; - // Auth Key Management Suite - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; - sFrame.pRSNWPA->len += 2; - - // RSN Capabilities - *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0; - sFrame.pRSNWPA->len += 2; - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - } - } - - if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy(pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an Prob-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wCurrBeaconPeriod, - unsigned int uCurrChannel, - unsigned short wCurrATIMWinodw, - unsigned char *pDstAddr, - PWLAN_IE_SSID pCurrSSID, - unsigned char *pCurrBSSID, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - unsigned char byPHYType -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char *pbyBuffer; - unsigned int uLength = 0; - PWLAN_IE_IBSS_DFS pIBSSDFS = NULL; - unsigned int ii; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBERESP_FR_MAXLEN; - vMgrEncodeProbeResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN); - *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod); - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - - if (byPHYType == BB_TYPE_11B) - *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1))); - - // Copy SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, - pCurrSSID, - ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN -); - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - // DS parameter - if (pDevice->eCurrentPHYType != PHY_TYPE_11A) { - sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (1) + WLAN_IEHDR_LEN; - sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS; - sFrame.pDSParms->len = 1; - sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel; - } - - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - // IBSS parameter - sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len); - sFrame.len += (2) + WLAN_IEHDR_LEN; - sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS; - sFrame.pIBSSParms->len = 2; - sFrame.pIBSSParms->wATIMWindow = 0; - } - if (pDevice->eCurrentPHYType == PHY_TYPE_11G) { - sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len); - sFrame.len += 1 + WLAN_IEHDR_LEN; - sFrame.pERP->byElementID = WLAN_EID_ERP; - sFrame.pERP->len = 1; - sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode) - sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent) - sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd) - sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; - } - - if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { - // Country IE - pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); - set_country_IE(pMgmt->pAdapter, pbyBuffer); - set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer); - uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN; - pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN); - // Power Constrain IE - ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT; - ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1; - ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; - pbyBuffer += (1) + WLAN_IEHDR_LEN; - uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel) { - // Channel Switch IE - ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; - ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; - ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1; - ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel); - ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0; - pbyBuffer += (3) + WLAN_IEHDR_LEN; - uLength += (3) + WLAN_IEHDR_LEN; - } - // TPC report - ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP; - ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2; - ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0; - pbyBuffer += (2) + WLAN_IEHDR_LEN; - uLength += (2) + WLAN_IEHDR_LEN; - // IBSS DFS - if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) { - pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer; - pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS; - pIBSSDFS->len = 7; - memcpy(pIBSSDFS->abyDFSOwner, - pMgmt->abyIBSSDFSOwner, - 6); - pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery; - pbyBuffer += (7) + WLAN_IEHDR_LEN; - uLength += (7) + WLAN_IEHDR_LEN; - for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { - pbyBuffer += 2; - uLength += 2; - pIBSSDFS->len += 2; - } - } - } - sFrame.len += uLength; - } - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { - if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { - if (pMgmt->wWPAIELen != 0) { - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen); - sFrame.len += pMgmt->wWPAIELen; - } - } - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an association request frame - * - * - * Return Value: - * A ptr to frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure. - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN; - // format fixed field frame structure - vMgrEncodeAssocRequest(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - // Set the capability and listen interval - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - // sFrame.len point to end of fixed field - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4)) - sFrame.len += 4 + WLAN_IEHDR_LEN; - else - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - // for 802.11h - if (pMgmt->b11hEnable) { - if (sFrame.pCurrPowerCap == NULL) { - sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len); - sFrame.len += (2 + WLAN_IEHDR_LEN); - sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY; - sFrame.pCurrPowerCap->len = 2; - CARDvGetPowerCapability(pMgmt->pAdapter, - &(sFrame.pCurrPowerCap->byMinPower), - &(sFrame.pCurrPowerCap->byMaxPower) -); - } - if (sFrame.pCurrSuppCh == NULL) { - sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len); - sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh); - } - } - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++ = 0x01; - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - - *pbyRSN++ = 0x50; - *pbyRSN++ = 0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) - *pbyRSN++ = WPA_AUTH_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) - *pbyRSN++ = WPA_AUTH_IEEE802_1X; - else - *pbyRSN++ = WPA_NONE; - - sFrame.pRSNWPA->len += 6; - - // RSN Capabilities - - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - sFrame.pRSNWPA->len += 2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - // WPA IE - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len += 2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - if (*pwPMKID != 0) - sFrame.pRSN->len += (2 + (*pwPMKID)*16); - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an re-association request frame - * - * - * Return Value: - * A ptr to frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeReAssocRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pDAddr, - unsigned short wCurrCapInfo, - unsigned short wListenInterval, - PWLAN_IE_SSID pCurrSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCREQ sFrame; - unsigned char *pbyIEs; - unsigned char *pbyRSN; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - /* Setup the sFrame structure. */ - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN; - - // format fixed field frame structure - vMgrEncodeReassocRequest(&sFrame); - - /* Setup the header */ - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - /* Set the capability and listen interval */ - *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo); - *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval); - - memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - /* Copy the SSID */ - /* sFrame.len point to end of fixed field */ - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - - pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN; - pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); - pbyIEs = pMgmt->sAssocInfo.abyIEs; - memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN; - - /* Copy the rate set */ - /* sFrame.len point to end of SSID */ - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - - // Copy the extension rate set - if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - - pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA IE */ - sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len); - sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA; - sFrame.pRSNWPA->len = 16; - sFrame.pRSNWPA->abyOUI[0] = 0x00; - sFrame.pRSNWPA->abyOUI[1] = 0x50; - sFrame.pRSNWPA->abyOUI[2] = 0xf2; - sFrame.pRSNWPA->abyOUI[3] = 0x01; - sFrame.pRSNWPA->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSNWPA->abyMulticast[0] = 0x00; - sFrame.pRSNWPA->abyMulticast[1] = 0x50; - sFrame.pRSNWPA->abyMulticast[2] = 0xf2; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE; - - // Pairwise Key Cipher Suite - sFrame.pRSNWPA->wPKCount = 1; - sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00; - sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50; - sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP; - else - sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE; - - // Auth Key Management Suite - pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len); - *pbyRSN++ = 0x01; - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - - *pbyRSN++ = 0x50; - *pbyRSN++ = 0xf2; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) - *pbyRSN++ = WPA_AUTH_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) - *pbyRSN++ = WPA_AUTH_IEEE802_1X; - else - *pbyRSN++ = WPA_NONE; - - sFrame.pRSNWPA->len += 6; - - // RSN Capabilities - *pbyRSN++ = 0x00; - *pbyRSN++ = 0x00; - sFrame.pRSNWPA->len += 2; - - sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN; - - } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - unsigned int ii; - unsigned short *pwPMKID; - - /* WPA IE */ - sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); - sFrame.pRSN->byElementID = WLAN_EID_RSN; - sFrame.pRSN->len = 6; //Version(2)+GK(4) - sFrame.pRSN->wVersion = 1; - //Group Key Cipher Suite - sFrame.pRSN->abyRSN[0] = 0x00; - sFrame.pRSN->abyRSN[1] = 0x0F; - sFrame.pRSN->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - sFrame.pRSN->abyRSN[4] = 1; - sFrame.pRSN->abyRSN[5] = 0; - sFrame.pRSN->abyRSN[6] = 0x00; - sFrame.pRSN->abyRSN[7] = 0x0F; - sFrame.pRSN->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // Auth Key Management Suite - sFrame.pRSN->abyRSN[10] = 1; - sFrame.pRSN->abyRSN[11] = 0; - sFrame.pRSN->abyRSN[12] = 0x00; - sFrame.pRSN->abyRSN[13] = 0x0F; - sFrame.pRSN->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - sFrame.pRSN->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { - memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - sFrame.pRSN->abyRSN[16] = 0; - sFrame.pRSN->abyRSN[17] = 0; - } - sFrame.pRSN->len += 2; - - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pbyRSN = &sFrame.pRSN->abyRSN[18]; - pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } - - if (*pwPMKID != 0) - sFrame.pRSN->len += (2 + (*pwPMKID) * 16); - } - - sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN; - // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION - pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN; - memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN); - pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN; - } - - /* Adjust the length fields */ - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an assoc-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_ASSOCRESP sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeAssocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Constructs an reassoc-response frame - * - * - * Return Value: - * PTR to frame; or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeReAssocResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned short wCurrCapInfo, - unsigned short wAssocStatus, - unsigned short wAssocAID, - unsigned char *pDstAddr, - PWLAN_IE_SUPP_RATES pCurrSuppRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -) -{ - PSTxMgmtPacket pTxPacket = NULL; - WLAN_FR_REASSOCRESP sFrame; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - // Setup the sFrame structure - sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header; - sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN; - vMgrEncodeReassocResponse(&sFrame); - // Setup the header - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP) -)); - memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo); - *sFrame.pwStatus = cpu_to_le16(wAssocStatus); - *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15)); - - // Copy the rate set - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, - pCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN -); - - if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, - pCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - - // Adjust the length fields - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; -} - -/*+ - * - * Routine Description: - * Handles probe response management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vMgrRxProbeResponse( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - PKnownBSS pBSSList = NULL; - WLAN_FR_PROBERESP sFrame; - unsigned char byCurrChannel = pRxPacket->byRxChannel; - ERPObject sERP; - unsigned char byIEChannel = 0; - bool bChannelHit = true; - - memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeResponse(&sFrame); - - if ((sFrame.pqwTimestamp == NULL) || - (sFrame.pwBeaconInterval == NULL) || - (sFrame.pwCapInfo == NULL) || - (sFrame.pSSID == NULL) || - (sFrame.pSuppRates == NULL)) { - pr_debug("Probe resp:Fail addr:[%p]\n", - pRxPacket->p80211Header); - DBG_PORT80(0xCC); - return; - } - - if (sFrame.pSSID->len == 0) - pr_debug("Rx Probe resp: SSID len = 0\n"); - - if (sFrame.pDSParms != NULL) { - if (byCurrChannel > CB_MAX_CHANNEL_24G) { - // channel remapping to - byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A); - } else { - byIEChannel = sFrame.pDSParms->byCurrChannel; - } - if (byCurrChannel != byIEChannel) { - // adjust channel info. bcs we rcv adjacent channel packets - bChannelHit = false; - byCurrChannel = byIEChannel; - } - } else { - // no DS channel info - bChannelHit = true; - } - -//2008-0730-01by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel)) - return; - - if (sFrame.pERP != NULL) { - sERP.byERP = sFrame.pERP->byContext; - sERP.bERPExist = true; - } else { - sERP.bERPExist = false; - sERP.byERP = 0; - } - - // update or insert the bss - pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); - if (pBSSList) { - BSSbUpdateToBSSList((void *)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (void *)pRxPacket -); - } else { - pr_debug("Probe resp/insert: RxChannel = : %d\n", - byCurrChannel); - BSSbInsertToBSSList((void *)pDevice, - sFrame.pHdr->sA3.abyAddr3, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (void *)pRxPacket -); - } -} - -/*+ - * - * Routine Description:(AP)or(Ad-hoc STA) - * Handles probe request management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vMgrRxProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - WLAN_FR_PROBEREQ sFrame; - CMD_STATUS Status; - PSTxMgmtPacket pTxPacket; - unsigned char byPHYType = BB_TYPE_11B; - - // STA in Ad-hoc mode: when latest TBTT beacon transmit success, - // STA have to response this request. - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) { - memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ)); - // decode the frame - sFrame.len = pRxPacket->cbMPDULen; - sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; - vMgrDecodeProbeRequest(&sFrame); - - if (sFrame.pSSID->len != 0) { - if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) - return; - if (memcmp(sFrame.pSSID->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, - ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) { - return; - } - } - - if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) - byPHYType = BB_TYPE_11G; - - // Probe response reply.. - pTxPacket = s_MgrMakeProbeResponse - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - 0, - sFrame.pHdr->sA3.abyAddr2, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - byPHYType -); - if (pTxPacket != NULL) { - /* send the frame */ - Status = csMgmt_xmit(pDevice, pTxPacket); - if (Status != CMD_STATUS_PENDING) - pr_debug("Mgt:Probe response tx failed\n"); - } - } -} - -/*+ - * - * Routine Description: - * - * Entry point for the reception and handling of 802.11 management - * frames. Makes a determination of the frame type and then calls - * the appropriate function. - * - * - * Return Value: - * none. - * - -*/ - -void -vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -) -{ - struct vnt_private *pDevice = hDeviceContext; - bool bInScan = false; - unsigned int uNodeIndex = 0; - NODE_STATE eNodeState = 0; - CMD_STATUS Status; - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) - eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState; - } - - switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) { - case WLAN_FSTYPE_ASSOCREQ: - // Frame Clase = 2 - pr_debug("rx assocreq\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 1\n"); - } else { - s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - } - break; - - case WLAN_FSTYPE_ASSOCRESP: - // Frame Clase = 2 - pr_debug("rx assocresp1\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false); - pr_debug("rx assocresp2\n"); - break; - - case WLAN_FSTYPE_REASSOCREQ: - // Frame Clase = 2 - pr_debug("rx reassocreq\n"); - // Todo: reassoc - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 2\n"); - - } - s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); - break; - - case WLAN_FSTYPE_REASSOCRESP: - // Frame Clase = 2 - pr_debug("rx reassocresp\n"); - s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true); - break; - - case WLAN_FSTYPE_PROBEREQ: - // Frame Clase = 0 - s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_PROBERESP: - // Frame Clase = 0 - pr_debug("rx proberesp\n"); - - s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_BEACON: - // Frame Clase = 0 - if (pMgmt->eScanState != WMAC_NO_SCANNING) - bInScan = true; - - s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan); - break; - - case WLAN_FSTYPE_ATIM: - // Frame Clase = 1 - pr_debug("rx atim\n"); - break; - - case WLAN_FSTYPE_DISASSOC: - // Frame Clase = 2 - pr_debug("rx disassoc\n"); - if (eNodeState < NODE_AUTH) { - // send deauth notification - // reason = (6) class 2 received from nonauth sta - vMgrDeAuthenBeginSta(pDevice, - pMgmt, - pRxPacket->p80211Header->sA3.abyAddr2, - (6), - &Status -); - pr_debug("wmgr: send vMgrDeAuthenBeginSta 3\n"); - } - s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_AUTHEN: - // Frame Clase = 1 - pr_debug("rx authen\n"); - s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket); - break; - - case WLAN_FSTYPE_DEAUTHEN: - // Frame Clase = 1 - pr_debug("rx deauthen\n"); - s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket); - break; - - default: - pr_debug("rx unknown mgmt\n"); - } -} - -/*+ - * - * Routine Description: - * - * - * Prepare beacon to send - * - * Return Value: - * true if success; false if failed. - * - -*/ -bool -bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSTxMgmtPacket pTxPacket; - - if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) - pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1); - else - pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1); - - pTxPacket = s_MgrMakeBeacon - ( - pDevice, - pMgmt, - pMgmt->wCurrCapInfo, - pMgmt->wCurrBeaconPeriod, - pMgmt->uCurrChannel, - pMgmt->wCurrATIMWindow, - (PWLAN_IE_SSID)pMgmt->abyCurrSSID, - (unsigned char *)pMgmt->abyCurrBSSID, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates -); - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->abyCurrBSSID[0] == 0)) - return false; - - csBeacon_xmit(pDevice, pTxPacket); - - return true; -} - -/*+ - * - * Routine Description: - * - * Log a warning message based on the contents of the Status - * Code field of an 802.11 management frame. Defines are - * derived from 802.11-1997 SPEC. - * - * Return Value: - * none. - * - -*/ -static -void -s_vMgrLogStatus( - PSMgmtObject pMgmt, - unsigned short wStatus -) -{ - switch (wStatus) { - case WLAN_MGMT_STATUS_UNSPEC_FAILURE: - pr_info("Status code == Unspecified error\n"); - break; - case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: - pr_info("Status code == Can't support all requested capabilities\n"); - break; - case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: - pr_info("Status code == Reassoc denied, can't confirm original Association\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: - pr_info("Status code == Assoc denied, undefine in spec\n"); - break; - case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: - pr_info("Status code == Peer doesn't support authen algorithm\n"); - break; - case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: - pr_info("Status code == Authen frame received out of sequence\n"); - break; - case WLAN_MGMT_STATUS_CHALLENGE_FAIL: - pr_info("Status code == Authen rejected, challenge failure\n"); - break; - case WLAN_MGMT_STATUS_AUTH_TIMEOUT: - pr_info("Status code == Authen rejected, timeout waiting for next frame\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: - pr_info("Status code == Assoc denied, AP too busy\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: - pr_info("Status code == Assoc denied, we haven't enough basic rates\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE: - pr_info("Status code == Assoc denied, we do not support short preamble\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC: - pr_info("Status code == Assoc denied, we do not support PBCC\n"); - break; - case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY: - pr_info("Status code == Assoc denied, we do not support channel agility\n"); - break; - default: - pr_info("Unknown status code %d\n", wStatus); - break; - } -} - -/* - * - * Description: - * Add BSSID in PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * pbyBSSID - BSSID address for adding - * wRSNCap - BSS's RSN capability - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -bAdd_PMKID_Candidate( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj -) -{ - struct vnt_private *pDevice = hDeviceContext; - struct pmkid_candidate *pCandidateList; - unsigned int ii = 0; - - pr_debug("bAdd_PMKID_Candidate START: (%d)\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL)) - return false; - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) - return false; - - // Update Old Candidate - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - return true; - } - } - - // New Candidate - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - ether_addr_copy(pCandidateList->BSSID, pbyBSSID); - pDevice->gsPMKIDCandidate.NumCandidates++; - pr_debug("NumCandidates:%d\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; -} - -/* - * - * Description: - * Flush PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - * - -*/ -void -vFlush_PMKID_Candidate( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - - if (pDevice == NULL) - return; - - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); -} - -static bool -s_bCipherMatch( - PKnownBSS pBSSNode, - NDIS_802_11_ENCRYPTION_STATUS EncStatus, - unsigned char *pbyCCSPK, - unsigned char *pbyCCSGK -) -{ - unsigned char byMulticastCipher = KEY_CTL_INVALID; - unsigned char byCipherMask = 0x00; - int i; - - if (pBSSNode == NULL) - return false; - - // check cap. of BSS - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (EncStatus == Ndis802_11Encryption1Enabled)) { - // default is WEP only - byMulticastCipher = KEY_CTL_WEP; - } - - if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - pBSSNode->bWPA2Valid && - //20080123-01, by Einsn Liu - ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA2 - // check Group Key Cipher - if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) || - (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for (i = 0; i < pBSSNode->wCSSPKCount; i++) { - if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) || - (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) { - // this should not happen as defined 802.11i - byCipherMask |= 0x01; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wCSSPKCount; - } - } - - } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - pBSSNode->bWPAValid && - ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { - //WPA - // check Group Key Cipher - if ((pBSSNode->byGKType == WPA_WEP40) || - (pBSSNode->byGKType == WPA_WEP104)) { - byMulticastCipher = KEY_CTL_WEP; - } else if (pBSSNode->byGKType == WPA_TKIP) { - byMulticastCipher = KEY_CTL_TKIP; - } else if (pBSSNode->byGKType == WPA_AESCCMP) { - byMulticastCipher = KEY_CTL_CCMP; - } else { - byMulticastCipher = KEY_CTL_INVALID; - } - - // check Pairwise Key Cipher - for (i = 0; i < pBSSNode->wPKCount; i++) { - if (pBSSNode->abyPKType[i] == WPA_TKIP) { - byCipherMask |= 0x02; - } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) { - byCipherMask |= 0x04; - } else if (pBSSNode->abyPKType[i] == WPA_NONE) { - // use group key only ignore all others - byCipherMask = 0; - i = pBSSNode->wPKCount; - } - } - } - - pr_debug("%d, %d, %d, %d, EncStatus:%d\n", - byMulticastCipher, byCipherMask, - pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus); - - // mask our cap. with BSS - if (EncStatus == Ndis802_11Encryption1Enabled) { - // For supporting Cisco migration mode, don't care pairwise key cipher - if ((byMulticastCipher == KEY_CTL_WEP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else { - return false; - } - - } else if (EncStatus == Ndis802_11Encryption2Enabled) { - if ((byMulticastCipher == KEY_CTL_TKIP) && - (byCipherMask == 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_NONE; - return true; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x02) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_TKIP; - return true; - } else { - return false; - } - } else if (EncStatus == Ndis802_11Encryption3Enabled) { - if ((byMulticastCipher == KEY_CTL_CCMP) && - (byCipherMask == 0)) { - // When CCMP is enable, "Use group cipher suite" shall not be a valid option. - return false; - } else if ((byMulticastCipher == KEY_CTL_WEP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_WEP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_TKIP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_TKIP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else if ((byMulticastCipher == KEY_CTL_CCMP) && - ((byCipherMask & 0x04) != 0)) { - *pbyCCSGK = KEY_CTL_CCMP; - *pbyCCSPK = KEY_CTL_CCMP; - return true; - } else { - return false; - } - } - return true; -} diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index a00652bfec4e..4b7196bd1607 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -314,107 +314,4 @@ typedef struct tagSMgmtObject { struct sk_buff skb; } SMgmtObject, *PSMgmtObject; -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -vMgrObjectInit( - void *hDeviceContext -); - -void -vMgrTimerInit( - void *hDeviceContext -); - -void -vMgrObjectReset( - void *hDeviceContext -); - -void -vMgrAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrReAssocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrDisassocBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -); - -void -vMgrAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus -); - -void -vMgrCreateOwnIBSS( - void *hDeviceContext, - PCMD_STATUS pStatus -); - -void -vMgrJoinBSSBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -); - -void -vMgrRxManagePacket( - void *hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket -); - -/* - void - vMgrScanBegin( - void *hDeviceContext, - PCMD_STATUS pStatus -); -*/ - -void -vMgrDeAuthenBeginSta( - void *hDeviceContext, - PSMgmtObject pMgmt, - unsigned char *abyDestAddress, - unsigned short wReason, - PCMD_STATUS pStatus -); - -bool -bMgrPrepareBeaconToSend( - void *hDeviceContext, - PSMgmtObject pMgmt -); - -bool -bAdd_PMKID_Candidate( - void *hDeviceContext, - unsigned char *pbyBSSID, - PSRSNCapObject psRSNCapObj -); - -void -vFlush_PMKID_Candidate( - void *hDeviceContext -); - #endif // __WMGR_H__ -- GitLab From 8d0126b1f06a8921a6fe669870de1c5644a276f4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:29 +0000 Subject: [PATCH 2086/9457] staging: vt6655: dead code remove wcmd.c header will be removed later. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/bssdb.c | 7 - drivers/staging/vt6655/wcmd.c | 958 -------------------------------- drivers/staging/vt6655/wcmd.h | 32 -- 4 files changed, 998 deletions(-) delete mode 100644 drivers/staging/vt6655/wcmd.c diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index fa154ef10edc..271ca9df43a9 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -9,7 +9,6 @@ vt6655_stage-y += device_main.o \ baseband.o \ wctl.o \ 80211mgr.o \ - wcmd.o \ bssdb.o \ rxtx.o \ dpc.o \ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 2b508ff5f492..abe38e1f34eb 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -1092,7 +1092,6 @@ BSSvSecondCallBack( if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) { pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); } if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { @@ -1151,8 +1150,6 @@ BSSvSecondCallBack( pr_debug("Roaming ...\n"); BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); pDevice->uAutoReConnectTime = 0; } } @@ -1166,8 +1163,6 @@ BSSvSecondCallBack( } else { pr_info("Adhoc re-scanning ...\n"); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); pDevice->uAutoReConnectTime = 0; } } @@ -1430,8 +1425,6 @@ void s_vCheckSensitivity( } if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { pDevice->uBBVGADiffCount++; - if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) - bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); } else { pDevice->uBBVGADiffCount = 0; } diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c deleted file mode 100644 index 3c980806a515..000000000000 --- a/drivers/staging/vt6655/wcmd.c +++ /dev/null @@ -1,958 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wcmd.c - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2003 - * - * Functions: - * s_vProbeChannel - Active scan channel - * s_MgrMakeProbeRequest - Make ProbeRequest packet - * CommandTimer - Timer function to handle command - * s_bCommandComplete - Command Complete function - * bScheduleCommand - Push Command and wait Command Scheduler to do - * vCommandTimer- Command call back functions - * vCommandTimerWait- Call back timer - * bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue - * - * Revision History: - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "device.h" -#include "mac.h" -#include "card.h" -#include "80211hdr.h" -#include "wcmd.h" -#include "wmgr.h" -#include "power.h" -#include "wctl.h" -#include "baseband.h" -#include "rxtx.h" -#include "rf.h" -#include "iowpa.h" -#include "channel.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static -void -s_vProbeChannel( - struct vnt_private *pDevice -); - -static -PSTxMgmtPacket -s_MgrMakeProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates -); - -static -bool -s_bCommandComplete( - struct vnt_private *pDevice -); - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: - * Stop AdHoc beacon during scan process - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: none - * - */ -static -void -vAdHocBeaconStop(struct vnt_private *pDevice) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - bool bStop; - - /* - * temporarily stop Beacon packet for AdHoc Server - * if all of the following conditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - * (3) One of the following conditions is met - * (3.1) AdHoc channel is in B/G band and the - * current scan channel is in A band - * or - * (3.2) AdHoc channel is in A mode - */ - bStop = false; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { - if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && - (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { - bStop = true; - } - if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) - bStop = true; - - } - - if (bStop) - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); -} /* vAdHocBeaconStop */ - -/* - * Description: - * Restart AdHoc beacon after scan process complete - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * Out: - * none - * - * Return Value: none - * - */ -static -void -vAdHocBeaconRestart(struct vnt_private *pDevice) -{ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - /* - * Restart Beacon packet for AdHoc Server - * if all of the following coditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - */ - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } -} - -/*+ - * - * Routine Description: - * Prepare and send probe request management frames. - * - * - * Return Value: - * none. - * - -*/ - -static -void -s_vProbeChannel( - struct vnt_private *pDevice -) -{ - //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M - unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C}; - unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60}; - //6M, 9M, 12M, 48M - unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; - unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; - unsigned char *pbyRate; - PSTxMgmtPacket pTxPacket; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) - pbyRate = &abyCurrSuppRatesA[0]; - else if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - pbyRate = &abyCurrSuppRatesB[0]; - else - pbyRate = &abyCurrSuppRatesG[0]; - - // build an assocreq frame and send it - pTxPacket = s_MgrMakeProbeRequest - ( - pDevice, - pMgmt, - pMgmt->abyScanBSSID, - (PWLAN_IE_SSID)pMgmt->abyScanSSID, - (PWLAN_IE_SUPP_RATES)pbyRate, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG - ); - - if (pTxPacket != NULL) { - for (ii = 0; ii < 2; ii++) { - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - pr_debug("Probe request sending fail..\n"); - else - pr_debug("Probe request is sending..\n"); - } - } -} - -/*+ - * - * Routine Description: - * Constructs an probe request frame - * - * - * Return Value: - * A ptr to Tx frame or NULL on allocation failure - * - -*/ - -static PSTxMgmtPacket -s_MgrMakeProbeRequest( - struct vnt_private *pDevice, - PSMgmtObject pMgmt, - unsigned char *pScanBSSID, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pCurrRates, - PWLAN_IE_SUPP_RATES pCurrExtSuppRates - -) -{ - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - return pTxPacket; -} - -void -vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond -) -{ - struct vnt_private *pDevice = hDeviceContext; - - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - // RUN_AT :1 msec ~= (HZ/1024) - pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); - add_timer(&pDevice->sTimerCommand); -} - -void -vCommandTimer( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PWLAN_IE_SSID pItemSSID; - PWLAN_IE_SSID pItemSSIDCurr; - unsigned int ii; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; - - if (pDevice->dwDiagRefCount != 0) - return; - if (!pDevice->bCmdRunning) - return; - - spin_lock_irq(&pDevice->lock); - - switch (pDevice->eCommandState) { - case WLAN_CMD_SCAN_START: - - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - s_bCommandComplete(pDevice); - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_AP); - spin_unlock_irq(&pDevice->lock); - return; - } - - pr_debug("eCommandState= WLAN_CMD_SCAN_START\n"); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; - // wait all Data TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, 10); - return; - } - - if (pMgmt->uScanChannel == 0) { - pMgmt->uScanChannel = pDevice->byMinChannel; - // Set Baseband to be more sensitive. - - } - if (pMgmt->uScanChannel > pDevice->byMaxChannel) { - pMgmt->eScanState = WMAC_NO_SCANNING; - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - pr_debug("Scanning, set back to channel: [%d]\n", - pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - else - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION); - - vAdHocBeaconRestart(pDevice); - s_bCommandComplete(pDevice); - - } else { -//2008-8-4 by chester - if (!is_channel_valid(pMgmt->uScanChannel)) { - pr_debug("Invalid channel pMgmt->uScanChannel = %d\n", - pMgmt->uScanChannel); - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pMgmt->uScanChannel == pDevice->byMinChannel) { - pMgmt->abyScanBSSID[0] = 0xFF; - pMgmt->abyScanBSSID[1] = 0xFF; - pMgmt->abyScanBSSID[2] = 0xFF; - pMgmt->abyScanBSSID[3] = 0xFF; - pMgmt->abyScanBSSID[4] = 0xFF; - pMgmt->abyScanBSSID[5] = 0xFF; - pItemSSID->byElementID = WLAN_EID_SSID; - pMgmt->eScanState = WMAC_IS_SCANNING; - - } - - vAdHocBeaconStop(pDevice); - - if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) - pr_debug("SCAN Channel: %d\n", - pMgmt->uScanChannel); - else - pr_debug("SET SCAN Channel Fail: %d\n", - pMgmt->uScanChannel); - - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_UNSPECIFIED); - pMgmt->uScanChannel++; -//2008-8-4 by chester - if (!is_channel_valid(pMgmt->uScanChannel) && - pMgmt->uScanChannel <= pDevice->byMaxChannel) { - pMgmt->uScanChannel = pDevice->byMaxChannel + 1; - pMgmt->eCommandState = WLAN_CMD_SCAN_END; - - } - - if (!pMgmt->b11hEnable || - (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { - s_vProbeChannel(pDevice); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); - return; - } else { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); - return; - } - - } - - break; - - case WLAN_CMD_SCAN_END: - - // Set Baseband's sensitivity back. - // Set channel back - set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - pr_debug("Scanning, set back to channel: [%d]\n", - pMgmt->uCurrChannel); - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC); - else - CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION); - - pMgmt->eScanState = WMAC_NO_SCANNING; - vAdHocBeaconRestart(pDevice); -//2008-0409-07, by Einsn Liu -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) { - //send scan event to wpa_Supplicant - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - } -#endif - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_DISASSOCIATE_START: - pDevice->byReAssocCount = 0; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } else { - pr_debug("Send Disassociation Packet..\n"); - // reason = 8 : disassoc because sta has left - pDevice->bLinkPass = false; - // unlock command busy - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->sNodeDBTable[0].bActive = false; - } - netif_stop_queue(pDevice->dev); - pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - pr_debug(" CARDbRadioPowerOff\n"); - //2008-09-02 by chester - s_bCommandComplete(pDevice); - break; - - case WLAN_DISASSOCIATE_WAIT: - // wait all Control TD complete - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } -//2008-09-02 by chester - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_SSID_START: - pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pr_debug(" cmd: desire ssid = %s\n", pItemSSID->abySSID); - pr_debug(" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - pr_debug(" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); - pr_debug(" pItemSSID->len =%d\n", pItemSSID->len); - pr_debug(" pItemSSIDCurr->len = %d\n", - pItemSSIDCurr->len); - pr_debug(" desire ssid = %s\n", pItemSSID->abySSID); - pr_debug(" curr ssid = %s\n", pItemSSIDCurr->abySSID); - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - if (pItemSSID->len == pItemSSIDCurr->len) { - if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - } - - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - // set initial state - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((void *)pDevice); - BSSvClearNodeDBTable(pDevice, 0); - - // if Infra mode - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { - // Call mgr to begin the deauthentication - // reason = (3) because sta has left ESS - - // Call mgr to begin the authentication - } - // if Adhoc mode - else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - bClearBSSID_SCAN(pDevice); - } else { - // start own IBSS - - BSSvAddMulticastNode(pDevice); - } - } - // if SSID not found - else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || - pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { - // start own IBSS - - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - } else { - pr_debug("Disconnect SSID none\n"); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - pr_debug("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - - } - } - s_bCommandComplete(pDevice); - break; - - case WLAN_AUTHENTICATE_WAIT: - pr_debug("eCommandState == WLAN_AUTHENTICATE_WAIT\n"); - if (pMgmt->eCurrState == WMAC_STATE_AUTH) { - // Call mgr to begin the association - pDevice->byLinkWaitCount = 0; - pr_debug("eCurrState == WMAC_STATE_AUTH\n"); - } - - else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { - pr_debug("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); - } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if authenticated_frame delay! - pDevice->byLinkWaitCount++; - pr_debug("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - s_bCommandComplete(pDevice); - break; - - case WLAN_ASSOCIATE_WAIT: - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - pr_debug("eCurrState == WMAC_STATE_ASSOC\n"); - if (pDevice->ePSMode != WMAC_POWER_CAM) - PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); - - if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) - KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); - - pDevice->bLinkPass = true; - pDevice->byLinkWaitCount = 0; - pDevice->byReAssocCount = 0; - bClearBSSID_SCAN(pDevice); - if (pDevice->byFOETuning) { - BBvSetFOE(pDevice->PortOffset); - } - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - if (pDevice->IsTxDataTrigger) { //TxDataTimer is not triggered at the first time - del_timer(&pDevice->sTimerTxData); - init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (unsigned long) pDevice; - pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - pDevice->fTxDataInSleep = false; - pDevice->nTxDataTimeCout = 0; - } - - pDevice->IsTxDataTrigger = true; - add_timer(&pDevice->sTimerTxData); - - } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { - netdev_err(pDevice->dev, - "WLAN_ASSOCIATE_WAIT:Association Fail???\n"); - } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! - pDevice->byLinkWaitCount++; - pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_AP_MODE_START: - pr_debug("eCommandState == WLAN_CMD_AP_MODE_START\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - del_timer(&pMgmt->sTimerSecondCallback); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pDevice->bLinkPass = false; - if (pDevice->bEnableHostWEP) - BSSvClearNodeDBTable(pDevice, 1); - else - BSSvClearNodeDBTable(pDevice, 0); - pDevice->uAssocCount = 0; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bFixRate = false; - - // alway turn off unicast bit - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); - pDevice->byRxMode &= ~RCR_UNICAST; - pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode); - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)) - netif_wake_queue(pDevice->dev); - - pDevice->bLinkPass = true; - add_timer(&pMgmt->sTimerSecondCallback); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_TX_PSPACKET_START: - // DTIM Multicast tx - if (pMgmt->sNodeDBTable[0].bRxPSPoll) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { - pMgmt->abyPSTxMap[0] &= ~byMask[0]; - pDevice->bMoreData = false; - } else { - pDevice->bMoreData = true; - } - - pMgmt->sNodeDBTable[0].wEnQueueCnt--; - } - } - - // PS nodes tx - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive && - pMgmt->sNodeDBTable[ii].bRxPSPoll) { - pr_debug("Index=%d Enqueu Cnt= %d\n", - ii, - pMgmt->sNodeDBTable[ii].wEnQueueCnt); - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pDevice->bMoreData = false; - } else { - pDevice->bMoreData = true; - } - - pMgmt->sNodeDBTable[ii].wEnQueueCnt--; - // check if sta ps enabled, and wait next pspoll. - // if sta ps disable, then send all pending buffers. - if (pMgmt->sNodeDBTable[ii].bPSEnable) - break; - } - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pr_debug("Index=%d PS queue clear\n", - ii); - } - pMgmt->sNodeDBTable[ii].bRxPSPoll = false; - } - } - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_RADIO_START: - pr_debug("eCommandState == WLAN_CMD_RADIO_START\n"); - if (pDevice->bRadioCmd) - CARDbRadioPowerOn(pDevice); - else - CARDbRadioPowerOff(pDevice); - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE: - // wait all TD complete - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) { - vCommandTimerWait((void *)pDevice, 10); - spin_unlock_irq(&pDevice->lock); - return; - } - pDevice->byBBVGACurrent = pDevice->byBBVGANew; - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - pr_debug("SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); - s_bCommandComplete(pDevice); - break; - - default: - s_bCommandComplete(pDevice); - break; - - } //switch - spin_unlock_irq(&pDevice->lock); -} - -static -bool -s_bCommandComplete( - struct vnt_private *pDevice -) -{ - PWLAN_IE_SSID pSSID; - bool bRadioCmd = false; - bool bForceSCAN = true; - PSMgmtObject pMgmt = pDevice->pMgmt; - - pDevice->eCommandState = WLAN_CMD_IDLE; - if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { - //Command Queue Empty - pDevice->bCmdRunning = false; - return true; - } else { - pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; - pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; - bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; - bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue++; - pDevice->bCmdRunning = true; - switch (pDevice->eCommand) { - case WLAN_CMD_BSSID_SCAN: - pr_debug("eCommandState= WLAN_CMD_BSSID_SCAN\n"); - pDevice->eCommandState = WLAN_CMD_SCAN_START; - pMgmt->uScanChannel = 0; - if (pSSID->len != 0) - memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - else - memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - break; - case WLAN_CMD_SSID: - pDevice->eCommandState = WLAN_CMD_SSID_START; - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - if (pSSID->len != 0) - memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pr_debug("eCommandState= WLAN_CMD_SSID_START\n"); - break; - case WLAN_CMD_DISASSOCIATE: - pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; - break; - case WLAN_CMD_RX_PSPOLL: - pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; - break; - case WLAN_CMD_RUN_AP: - pDevice->eCommandState = WLAN_CMD_AP_MODE_START; - break; - case WLAN_CMD_RADIO: - pDevice->eCommandState = WLAN_CMD_RADIO_START; - pDevice->bRadioCmd = bRadioCmd; - break; - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; - - default: - break; - - } - - vCommandTimerWait((void *)pDevice, 0); - } - - return true; -} - -bool bScheduleCommand( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 -) -{ - struct vnt_private *pDevice = hDeviceContext; - - if (pDevice->cbFreeCmdQueue == 0) - return false; - - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; - memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - - if (pbyItem0 != NULL) { - switch (eCommand) { - case WLAN_CMD_BSSID_SCAN: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; - break; - - case WLAN_CMD_SSID: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - break; - - case WLAN_CMD_DISASSOCIATE: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); - break; - - case WLAN_CMD_RX_PSPOLL: - break; - - case WLAN_CMD_RADIO: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); - break; - - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE; - break; - - default: - break; - } - } - - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue--; - - if (!pDevice->bCmdRunning) - s_bCommandComplete(pDevice); - - return true; -} - -/* - * Description: - * Clear BSSID_SCAN cmd in CMD Queue - * - * Parameters: - * In: - * hDeviceContext - Pointer to the adapter - * eCommand - Command - * Out: - * none - * - * Return Value: true if success; otherwise false - * - */ -bool bClearBSSID_SCAN( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; - unsigned int ii; - - if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { - for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) { - if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) - pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; - ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); - if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) - break; - } - } - return true; -} - -//mike add:reset command timer -void -vResetCommandTimer( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - - //delete timer - del_timer(&pDevice->sTimerCommand); - //init timer - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long) pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; - pDevice->sTimerCommand.expires = RUN_AT(HZ); - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - pDevice->eCommandState = WLAN_CMD_IDLE; - pDevice->bCmdRunning = false; - pDevice->bCmdClear = false; -} - -void -BSSvSecondTxData( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - pDevice->nTxDataTimeCout++; - - if (pDevice->nTxDataTimeCout < 4) //don't tx data if timer less than 40s - { - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - add_timer(&pDevice->sTimerTxData); - return; - } - - spin_lock_irq(&pDevice->lock); - - /* open && sharekey linking */ - if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || - pDevice->fWPA_Authened) { /* wpa linking */ - pDevice->fTxDataInSleep = true; - pDevice->fTxDataInSleep = false; - } - - spin_unlock_irq(&pDevice->lock); - - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); /* 10s callback */ - add_timer(&pDevice->sTimerTxData); -} diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index 6ef04de69f37..ae7ddeaeb014 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -88,36 +88,4 @@ typedef enum tagCMD_STATE { WLAN_CMD_IDLE } CMD_STATE, *PCMD_STATE; -void -vResetCommandTimer( - void *hDeviceContext -); - -void -vCommandTimer( - void *hDeviceContext -); - -bool bClearBSSID_SCAN( - void *hDeviceContext -); - -bool -bScheduleCommand( - void *hDeviceContext, - CMD_CODE eCommand, - unsigned char *pbyItem0 -); - -void -vCommandTimerWait( - void *hDeviceContext, - unsigned int MSecond -); - -void -BSSvSecondTxData( - void *hDeviceContext -); - #endif //__WCMD_H__ -- GitLab From d829163fa9736846baef47837f2b0cfa1a3a9202 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:30 +0000 Subject: [PATCH 2087/9457] staging: vt6655: rxtx remove dead functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/IEEE11h.c | 2 - drivers/staging/vt6655/rxtx.c | 1185 ------------------------------ drivers/staging/vt6655/rxtx.h | 34 - drivers/staging/vt6655/wroute.c | 12 +- 4 files changed, 1 insertion(+), 1232 deletions(-) diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c index 180a27cc74d7..65eb4823a7f5 100644 --- a/drivers/staging/vt6655/IEEE11h.c +++ b/drivers/staging/vt6655/IEEE11h.c @@ -135,7 +135,5 @@ bool IEEE11hbMSRRepTx(void *pMgmtHandle) pTxPacket->cbMPDULen = uLength; pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; - if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) - return false; return true; } diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index aa7e454cd9d3..5c460ad7665a 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -104,19 +104,6 @@ static const unsigned short wFB_Opt1[2][5] = { #define DATADUR_A_F1 13 /*--------------------- Static Functions --------------------------*/ - -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -); - static void s_vFillRTSHead( @@ -174,160 +161,6 @@ s_uFillDataHead( /*--------------------- Export Variables --------------------------*/ -static -void -s_vFillTxKey( - struct vnt_private *pDevice, - unsigned char *pbyBuf, - unsigned char *pbyIVHead, - PSKeyItem pTransmitKey, - unsigned char *pbyHdrBuf, - unsigned short wPayloadLen, - unsigned char *pMICHDR -) -{ - struct vnt_mic_hdr *mic_hdr = (struct vnt_mic_hdr *)pMICHDR; - unsigned long *pdwIV = (unsigned long *)pbyIVHead; - unsigned long *pdwExtIV = (unsigned long *)((unsigned char *)pbyIVHead+4); - PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; - unsigned long dwRevIVCounter; - unsigned char byKeyIndex = 0; - - //Fill TXKEY - if (pTransmitKey == NULL) - return; - - dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter); - *pdwIV = pDevice->dwIVCounter; - byKeyIndex = pTransmitKey->dwKeyIndex & 0xf; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) { - memcpy(pDevice->abyPRNG, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } else { - memcpy(pbyBuf, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) { - memcpy(pbyBuf+8, (unsigned char *)&(dwRevIVCounter), 3); - memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength); - } - memcpy(pDevice->abyPRNG, pbyBuf, 16); - } - // Append IV after Mac Header - *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (unsigned long)byKeyIndex << 30; - *pdwIV = cpu_to_le32(*pdwIV); - pDevice->dwIVCounter++; - if (pDevice->dwIVCounter > WEP_IV_MASK) - pDevice->dwIVCounter = 0; - - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr, - pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG); - memcpy(pbyBuf, pDevice->abyPRNG, 16); - // Make IV - memcpy(pdwIV, pDevice->abyPRNG, 3); - - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - // Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - pr_debug("vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); - - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - pTransmitKey->wTSC15_0++; - if (pTransmitKey->wTSC15_0 == 0) - pTransmitKey->dwTSC47_16++; - - memcpy(pbyBuf, pTransmitKey->abyKey, 16); - - // Make IV - *pdwIV = 0; - *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV - *pdwIV |= cpu_to_le16((unsigned short)(pTransmitKey->wTSC15_0)); - //Append IV&ExtIV after Mac Header - *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - - /* MICHDR0 */ - mic_hdr->id = 0x59; - mic_hdr->tx_priority = 0; - ether_addr_copy(mic_hdr->mic_addr2, pMACHeader->abyAddr2); - - /* ccmp pn big endian order */ - mic_hdr->ccmp_pn[0] = (u8)(pTransmitKey->dwTSC47_16 >> 24); - mic_hdr->ccmp_pn[1] = (u8)(pTransmitKey->dwTSC47_16 >> 16); - mic_hdr->ccmp_pn[2] = (u8)(pTransmitKey->dwTSC47_16 >> 8); - mic_hdr->ccmp_pn[3] = (u8)pTransmitKey->dwTSC47_16; - mic_hdr->ccmp_pn[4] = (u8)(pTransmitKey->wTSC15_0 >> 8); - mic_hdr->ccmp_pn[5] = (u8)pTransmitKey->wTSC15_0; - - /* MICHDR1 */ - mic_hdr->payload_len = cpu_to_be16(wPayloadLen); - - if (pDevice->bLongHeader) - mic_hdr->hlen = cpu_to_be16(28); - else - mic_hdr->hlen = cpu_to_be16(22); - - ether_addr_copy(mic_hdr->addr1, pMACHeader->abyAddr1); - ether_addr_copy(mic_hdr->addr2, pMACHeader->abyAddr2); - - /* MICHDR2 */ - ether_addr_copy(mic_hdr->addr3, pMACHeader->abyAddr3); - mic_hdr->frame_control = - cpu_to_le16(pMACHeader->wFrameCtl & 0xc78f); - mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->wSeqCtl & 0xf); - - if (pDevice->bLongHeader) - ether_addr_copy(mic_hdr->addr4, pMACHeader->abyAddr4); - } -} - -static -void -s_vSWencryption( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned char *pbyPayloadHead, - unsigned short wPayloadSize -) -{ - unsigned int cbICVlen = 4; - unsigned long dwICV = 0xFFFFFFFFL; - unsigned long *pdwICV; - - if (pTransmitKey == NULL) - return; - - if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - //======================================================================= - // Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - //======================================================================= - //Append ICV after payload - dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload) - pdwICV = (unsigned long *)(pbyPayloadHead + wPayloadSize); - // finally, we must invert dwCRC to get the correct answer - *pdwICV = cpu_to_le32(~dwICV); - // RC4 encryption - rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN); - rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen); - //======================================================================= - } -} - static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) { return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2] @@ -1395,1024 +1228,6 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, return cbHeaderLength; } -void -vGenerateFIFOHeader(struct vnt_private *pDevice, unsigned char byPktType, - unsigned char *pbyTxBufferAddr, bool bNeedEncrypt, - unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, unsigned char *pPacket, - PSKeyItem pTransmitKey, unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize) -{ - unsigned int wTxBufSize; // FFinfo size - bool bNeedACK; - bool bIsAdhoc; - unsigned short cbMacHdLen; - PSTxBufHead pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - - wTxBufSize = sizeof(STxBufHead); - - memset(pTxBufHead, 0, wTxBufSize); - //Set FIFOCTL_NEEDACK - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - bIsAdhoc = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - bIsAdhoc = false; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); - - //Set FIFOCTL_LHEAD - if (pDevice->bLongHeader) - pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; - - //Set FIFOCTL_GENINT - - pTxBufHead->wFIFOCtl |= FIFOCTL_GENINT; - - //Set FIFOCTL_ISDMA0 - if (TYPE_TXDMA0 == uDMAIdx) - pTxBufHead->wFIFOCtl |= FIFOCTL_ISDMA0; - - //Set FRAGCTL_MACHDCNT - if (pDevice->bLongHeader) - cbMacHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - //Set packet type - if (byPktType == PK_TYPE_11A) //0000 0000 0000 0000 - ; - else if (byPktType == PK_TYPE_11B) //0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - else if (byPktType == PK_TYPE_11GB) //0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - else if (byPktType == PK_TYPE_11GA) //0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - - //Set Auto Fallback Ctl - if (pDevice->wCurrentRate >= RATE_18M) { - if (pDevice->byAutoFBCtrl == AUTO_FB_0) - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0; - else if (pDevice->byAutoFBCtrl == AUTO_FB_1) - pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1; - } - - //Set FRAGCTL_WEPTYP - pDevice->bAES = false; - - //Set FRAGCTL_WEPTYP - if (pDevice->byLocalID > REV_ID_VT3253_A1) { - if ((bNeedEncrypt) && (pTransmitKey != NULL)) { //WEP enabled - if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104 - if (pTransmitKey->uKeyLength != WLAN_WEP232_KEYLEN) - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP - pTxBufHead->wFragCtl |= FRAGCTL_AES; - } - } - } - - RFbSetPower(pDevice, pDevice->wCurrentRate, pDevice->byCurrentCh); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - - *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize, - uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt, - pTransmitKey, uNodeIndex, puMACfragNum); -} - -/*+ - * - * Description: - * Translate 802.3 to 802.11 header - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * dwTxBufferAddr - Transmit Buffer - * pPacket - Packet from upper layer - * cbPacketSize - Transmit Data Length - * Out: - * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header - * pcbAppendPayload - size of append payload for 802.1H translation - * - * Return Value: none - * - -*/ - -void -vGenerateMACHeader( - struct vnt_private *pDevice, - unsigned char *pbyBufferAddr, - __le16 wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx -) -{ - PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; - - memset(pMACHeader, 0, (sizeof(S802_11Header))); - - if (uDMAIdx == TYPE_ATIMDMA) - pMACHeader->wFrameCtl = TYPE_802_11_ATIM; - else - pMACHeader->wFrameCtl = TYPE_802_11_DATA; - - if (pDevice->op_mode == NL80211_IFTYPE_AP) { - ether_addr_copy(&(pMACHeader->abyAddr1[0]), - &(psEthHeader->abyDstAddr[0])); - ether_addr_copy(&(pMACHeader->abyAddr2[0]), - &(pDevice->abyBSSID[0])); - ether_addr_copy(&(pMACHeader->abyAddr3[0]), - &(psEthHeader->abySrcAddr[0])); - pMACHeader->wFrameCtl |= FC_FROMDS; - } else { - if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { - ether_addr_copy(&(pMACHeader->abyAddr1[0]), - &(psEthHeader->abyDstAddr[0])); - ether_addr_copy(&(pMACHeader->abyAddr2[0]), - &(psEthHeader->abySrcAddr[0])); - ether_addr_copy(&(pMACHeader->abyAddr3[0]), - &(pDevice->abyBSSID[0])); - } else { - ether_addr_copy(&(pMACHeader->abyAddr3[0]), - &(psEthHeader->abyDstAddr[0])); - ether_addr_copy(&(pMACHeader->abyAddr2[0]), - &(psEthHeader->abySrcAddr[0])); - ether_addr_copy(&(pMACHeader->abyAddr1[0]), - &(pDevice->abyBSSID[0])); - pMACHeader->wFrameCtl |= FC_TODS; - } - } - - if (bNeedEncrypt) - pMACHeader->wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_ISWEP(1)); - - pMACHeader->wDurationID = le16_to_cpu(wDuration); - - if (pDevice->bLongHeader) { - PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; - - pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS); - memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); - } - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - - //Set FragNumber in Sequence Control - pMACHeader->wSeqCtl |= cpu_to_le16((unsigned short)uFragIdx); - - if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) { - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - } - - if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) //StartFrag or MidFrag - pMACHeader->wFrameCtl |= FC_MOREFRAG; -} - -CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) -{ - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - struct vnt_cts *pCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) - return CMD_STATUS_RESOURCES; - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - cbFrameBodySize = pPacket->cbPayloadLen; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; - } - - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); - else - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - if (is_multicast_ether_addr(&(pPacket->p80211Header->sA3.abyAddr1[0]))) - bNeedACK = false; - else { - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)(cbMacHdLen << 10)); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; - } - - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() - - //Set RrvTime/RTS/CTS Buffer - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - pvRrvTime = (void *) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); - } else { // 802.11a/b packet - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = NULL; - pvRTS = NULL; - pCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_ab)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - sizeof(struct vnt_tx_datahead_ab); - } - - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - - ether_addr_copy(&(sEthHeader.abyDstAddr[0]), - &(pPacket->p80211Header->sA3.abyAddr1[0])); - ether_addr_copy(&(sEthHeader.abySrcAddr[0]), - &(pPacket->p80211Header->sA3.abyAddr2[0])); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); - - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate, false); - - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize; - - if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyBSSID; - PSKeyItem pTransmitKey = NULL; - - pbyIVHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding); - pbyPayloadHead = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen); - - //Fill TXKEY - //Kyle: Need fix: TKIP and AES did't encrypt Mnt Packet. - //s_vFillTxKey(pDevice, (unsigned char *)pTxBufHead->adwTxKey, NULL); - - //Fill IV(ExtIV,RSNHDR) - //s_vFillPrePayload(pDevice, pbyIVHead, NULL); - //--------------------------- - // S/W or H/W Encryption - //--------------------------- - do { - if ((pDevice->op_mode == NL80211_IFTYPE_STATION) && - (pDevice->bLinkPass == true)) { - pbyBSSID = pDevice->abyBSSID; - // get pairwise key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { - // get group key - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - pr_debug("Get GTK\n"); - break; - } - } else { - pr_debug("Get PTK\n"); - break; - } - } - // get group key - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - pr_debug("KEY is NULL. OP Mode[%d]\n", - pDevice->op_mode); - } else { - pr_debug("Get GTK\n"); - } - } while (false); - //Fill TXKEY - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - (unsigned char *)pMACHeader, (unsigned short)cbFrameBodySize, NULL); - - memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen); - memcpy(pbyPayloadHead, ((unsigned char *)(pPacket->p80211Header) + cbMacHdLen), - cbFrameBodySize); - } else { - // Copy the Packet into a tx Buffer - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - } - - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet to be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID); - } - } - - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); - - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; - - pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet - - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); - - return CMD_STATUS_PENDING; -} - -CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) -{ - unsigned char byPktType; - unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; - unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - unsigned int cbHeaderSize = 0; - struct vnt_tx_short_buf_head *short_head = - (struct vnt_tx_short_buf_head *)pbyBuffer; - PS802_11Header pMACHeader; - unsigned short wCurrentRate; - - memset(short_head, 0, sizeof(*short_head)); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_2M; - byPktType = PK_TYPE_11B; - } - - //Set Preamble type always long - pDevice->byPreambleType = PREAMBLE_LONG; - - /* Set FIFOCTL_GENINT */ - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); - - /* Set packet type & Get Duration */ - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, - cbFrameSize, byPktType, wCurrentRate, false, - 0, 0, 1, AUTO_FB_NONE)); - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); - - short_head->duration = - cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, - cbFrameSize, byPktType, wCurrentRate, false, - 0, 0, 1, AUTO_FB_NONE)); - } - - vnt_get_phy_field(pDevice, cbFrameSize, - wCurrentRate, byPktType, &short_head->ab); - - /* Get TimeStampOff */ - short_head->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); - cbHeaderSize = sizeof(struct vnt_tx_short_buf_head); - - //Generate Beacon Header - pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize); - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - - pMACHeader->wDurationID = 0; - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - // Set Beacon buffer length - pDevice->wBCNBufLen = pPacket->cbMPDULen + cbHeaderSize; - - MACvSetCurrBCNTxDescAddr(pDevice->PortOffset, (pDevice->tx_beacon_dma)); - - MACvSetCurrBCNLength(pDevice->PortOffset, pDevice->wBCNBufLen); - // Set auto Transmit on - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - // Poll Transmit the adapter - MACvTransmitBCN(pDevice->PortOffset); - - return CMD_STATUS_PENDING; -} - -unsigned int -cbGetFragCount( - struct vnt_private *pDevice, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader -) -{ - unsigned int cbMACHdLen; - unsigned int cbFrameSize; - unsigned int cbFragmentSize; //Hdr+(IV)+payoad+(MIC)+(ICV)+FCS - unsigned int cbFragPayloadSize; - unsigned int cbLastFragPayloadSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uMACfragNum = 1; - bool bNeedACK; - - if ((pDevice->op_mode == NL80211_IFTYPE_ADHOC) || - (pDevice->op_mode == NL80211_IFTYPE_AP)) { - if (is_multicast_ether_addr(&(psEthHeader->abyDstAddr[0]))) - bNeedACK = false; - else - bNeedACK = true; - } else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - } - - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - else - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - - if (pDevice->bEncryptionEnable == true) { - if (pTransmitKey == NULL) { - if ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) || - (pDevice->pMgmt->eAuthenMode < WMAC_AUTH_WPA)) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } else if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { - cbIVlen = 4; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - } - } - - cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen; - - if ((cbFrameSize > pDevice->wFragmentationThreshold) && (bNeedACK == true)) { - // Fragmentation - cbFragmentSize = pDevice->wFragmentationThreshold; - cbFragPayloadSize = cbFragmentSize - cbMACHdLen - cbIVlen - cbICVlen - cbFCSlen; - uMACfragNum = (unsigned short) ((cbFrameBodySize + cbMIClen) / cbFragPayloadSize); - cbLastFragPayloadSize = (cbFrameBodySize + cbMIClen) % cbFragPayloadSize; - if (cbLastFragPayloadSize == 0) - cbLastFragPayloadSize = cbFragPayloadSize; - else - uMACfragNum++; - } - return uMACfragNum; -} - -void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, - unsigned char *pbMPDU, unsigned int cbMPDULen) -{ - PSTxDesc pFrstTD; - unsigned char byPktType; - unsigned char *pbyTxBufferAddr; - void *pvRTS; - void *pvCTS; - void *pvTxDataHd; - unsigned int uDuration; - unsigned int cbReqCount; - PS802_11Header pMACHeader; - unsigned int cbHeaderSize; - unsigned int cbFrameBodySize; - bool bNeedACK; - bool bIsPSPOLL = false; - PSTxBufHead pTxBufHead; - unsigned int cbFrameSize; - unsigned int cbIVlen = 0; - unsigned int cbICVlen = 0; - unsigned int cbMIClen = 0; - unsigned int cbFCSlen = 4; - unsigned int uPadding = 0; - unsigned int cbMICHDR = 0; - unsigned int uLength = 0; - u32 dwMICKey0, dwMICKey1; - u32 dwMIC_Priority; - u32 *pdwMIC_L; - u32 *pdwMIC_R; - unsigned short wTxBufSize; - unsigned int cbMacHdLen; - SEthernetHeader sEthHeader; - void *pvRrvTime; - void *pMICHDR; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned short wCurrentRate = RATE_1M; - PUWLAN_80211HDR p80211Header; - unsigned int uNodeIndex = 0; - bool bNodeExist = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned char *pbyIVHead; - unsigned char *pbyPayloadHead; - unsigned char *pbyMacHdr; - - unsigned int cbExtSuppRate = 0; - - pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - - if (cbMPDULen <= WLAN_HDR_ADDR3_LEN) - cbFrameBodySize = 0; - else - cbFrameBodySize = cbMPDULen - WLAN_HDR_ADDR3_LEN; - - p80211Header = (PUWLAN_80211HDR)pbMPDU; - - pFrstTD = pDevice->apCurrTD[TYPE_TXDMA0]; - pbyTxBufferAddr = (unsigned char *)pFrstTD->pTDInfo->buf; - pTxBufHead = (PSTxBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxBufHead); - memset(pTxBufHead, 0, wTxBufSize); - - if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { - wCurrentRate = RATE_6M; - byPktType = PK_TYPE_11A; - } else { - wCurrentRate = RATE_1M; - byPktType = PK_TYPE_11B; - } - - // SetPower will cause error power TX state for OFDM Date packet in TX buffer. - // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability. - // And cmd timer will wait data pkt TX to finish before scanning so it's OK - // to set power here. - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh); - else - RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel); - - pTxBufHead->byTxPower = pDevice->byCurPwr; - - //+++++++++++++++++++++ Patch VT3253 A1 performance +++++++++++++++++++++++++++ - if (pDevice->byFOETuning) { - if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) { - wCurrentRate = RATE_24M; - byPktType = PK_TYPE_11GA; - } - } - - pr_debug("vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n", - p80211Header->sA3.wFrameCtl); - - //Set packet type - if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000 - pTxBufHead->wFIFOCtl = 0; - } else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - } else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GB; - } else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_11GA; - } - - pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN; - pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); - - if (is_multicast_ether_addr(&(p80211Header->sA3.abyAddr1[0]))) { - bNeedACK = false; - if (pDevice->bEnableHostWEP) { - uNodeIndex = 0; - bNodeExist = true; - } - } else { - if (pDevice->bEnableHostWEP) { - if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex)) - bNodeExist = true; - } - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY; - } - - pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0); - - if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) { - bIsPSPOLL = true; - cbMacHdLen = WLAN_HDR_ADDR2_LEN; - } else { - cbMacHdLen = WLAN_HDR_ADDR3_LEN; - } - - // hostapd deamon ext support rate patch - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN; - - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN; - - if (cbExtSuppRate > 0) - cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES; - } - - //Set FRAGCTL_MACHDCNT - pTxBufHead->wFragCtl |= cpu_to_le16((unsigned short)cbMacHdLen << 10); - - // Notes: - // Although spec says MMPDU can be fragmented; In most cases, - // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP - - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { - cbIVlen = 4; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_LEGACY; - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - cbIVlen = 8;//IV+ExtIV - cbMIClen = 8; - cbICVlen = 4; - pTxBufHead->wFragCtl |= FRAGCTL_TKIP; - //We need to get seed here for filling TxKey entry. - } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - cbIVlen = 8;//RSN Header - cbICVlen = 8;//MIC - cbMICHDR = sizeof(struct vnt_mic_hdr); - pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; - } - //MAC Header should be padding 0 to DW alignment. - uPadding = 4 - (cbMacHdLen%4); - uPadding %= 4; - } - - cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate; - - //Set FIFOCTL_GrpAckPolicy - if (pDevice->bGrpAckPolicy == true) //0000 0100 0000 0000 - pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK; - - //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter() - - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet - - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts)); - pvRTS = NULL; - pvCTS = (struct vnt_cts *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR); - pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + - sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts)); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + - cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g); - - } else {//802.11a/b packet - - pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize); - pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab)); - pvRTS = NULL; - pvCTS = NULL; - pvTxDataHd = (void *)(pbyTxBufferAddr + - wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + - cbMICHDR + sizeof(struct vnt_tx_datahead_ab); - - } - - memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - ether_addr_copy(&(sEthHeader.abyDstAddr[0]), - &(p80211Header->sA3.abyAddr1[0])); - ether_addr_copy(&(sEthHeader.abySrcAddr[0]), - &(p80211Header->sA3.abyAddr2[0])); - //========================= - // No Fragmentation - //========================= - pTxBufHead->wFragCtl |= (unsigned short)FRAGCTL_NONFRAG; - - //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, - cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate); - - //Fill DataHead - uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK, - 0, 0, 1, AUTO_FB_NONE, wCurrentRate, false); - - pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize); - - cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate; - - pbyMacHdr = (unsigned char *)(pbyTxBufferAddr + cbHeaderSize); - pbyPayloadHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen); - pbyIVHead = (unsigned char *)(pbyMacHdr + cbMacHdLen + uPadding); - - // Copy the Packet into a tx Buffer - memcpy(pbyMacHdr, pbMPDU, cbMacHdLen); - - // version set to 0, patch for hostapd deamon - pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc); - memcpy(pbyPayloadHead, (pbMPDU + cbMacHdLen), cbFrameBodySize); - - // replace support rate, patch for hostapd deamon(only support 11M) - if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) { - if (cbExtSuppRate != 0) { - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize), - pMgmt->abyCurrSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN -); - if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) - memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN, - pMgmt->abyCurrExtSuppRates, - ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN -); - } - } - - // Set wep - if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { - if (pDevice->bEnableHostWEP) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength -); - } - - if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]); - dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]); - - // DO Software Michael - MIC_vInit(dwMICKey0, dwMICKey1); - MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); - dwMIC_Priority = 0; - MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n", - dwMICKey0, dwMICKey1); - - uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; - - MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize); - - pdwMIC_L = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize); - pdwMIC_R = (u32 *)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4); - - MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - MIC_vUnInit(); - - if (pDevice->bTxMICFail == true) { - *pdwMIC_L = 0; - *pdwMIC_R = 0; - pDevice->bTxMICFail = false; - } - - pr_debug("uLength: %d, %d\n", uLength, cbFrameBodySize); - pr_debug("cbReqCount:%d, %d, %d, %d\n", - cbReqCount, cbHeaderSize, uPadding, cbIVlen); - pr_debug("MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); - - } - - s_vFillTxKey(pDevice, (unsigned char *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey, - pbyMacHdr, (unsigned short)cbFrameBodySize, (unsigned char *)pMICHDR); - - if (pDevice->bEnableHostWEP) { - pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16; - pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0; - } - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) - s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (unsigned short)(cbFrameBodySize + cbMIClen)); - } - - pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; - - if (bIsPSPOLL) { - // The MAC will automatically replace the Duration-field of MAC header by Duration-field - // of FIFO control header. - // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is - // in the same place of other packet's Duration-field). - // And it will cause Cisco-AP to issue Disassociation-packet - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_a = cpu_to_le16(p80211Header->sA2.wDurationID); - ((struct vnt_tx_datahead_g *)pvTxDataHd)->duration_b = cpu_to_le16(p80211Header->sA2.wDurationID); - } else { - ((struct vnt_tx_datahead_ab *)pvTxDataHd)->duration = cpu_to_le16(p80211Header->sA2.wDurationID); - } - } - - // first TD is the only TD - //Set TSR1 & ReqCount in TxDescHead - pFrstTD->pTDInfo->skb = skb; - pFrstTD->m_td1TD1.byTCR = (TCR_STP | TCR_EDP | EDMSDU); - pFrstTD->pTDInfo->skb_dma = pFrstTD->pTDInfo->buf_dma; - pFrstTD->m_td1TD1.wReqCount = cpu_to_le16(cbReqCount); - pFrstTD->buff_addr = cpu_to_le32(pFrstTD->pTDInfo->skb_dma); - pFrstTD->pTDInfo->byFlags = 0; - pFrstTD->pTDInfo->byFlags |= TD_FLAGS_PRIV_SKB; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - // Disable PS - MACbPSWakeup(pDevice->PortOffset); - } - pDevice->bPWBitOn = false; - - wmb(); - pFrstTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - - pDevice->iTDUsed[TYPE_TXDMA0]++; - - if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - pr_debug(" available td0 <= 1\n"); - - pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; - - // Poll Transmit the adapter - MACvTransmit0(pDevice->PortOffset); -} - static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer, struct ieee80211_key_conf *tx_key, struct sk_buff *skb, u16 payload_len, diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 145713dc4110..7b0566ce42a7 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -189,40 +189,6 @@ struct vnt_tx_short_buf_head { __le16 time_stamp_off; } __packed; -void -vGenerateMACHeader( - struct vnt_private *, - unsigned char *pbyBufferAddr, - unsigned short wDuration, - PSEthernetHeader psEthHeader, - bool bNeedEncrypt, - unsigned short wFragType, - unsigned int uDMAIdx, - unsigned int uFragIdx -); - -unsigned int -cbGetFragCount( - struct vnt_private *, - PSKeyItem pTransmitKey, - unsigned int cbFrameBodySize, - PSEthernetHeader psEthHeader -); - -void -vGenerateFIFOHeader(struct vnt_private *, unsigned char byPktTyp, - unsigned char *pbyTxBufferAddr, bool bNeedEncrypt, - unsigned int cbPayloadSize, unsigned int uDMAIdx, - PSTxDesc pHeadTD, PSEthernetHeader psEthHeader, - unsigned char *pPacket, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum, - unsigned int *pcbHeaderSize); - -void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb, - unsigned char *pbMPDU, unsigned int cbMPDULen); -CMD_STATUS csMgmt_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); -CMD_STATUS csBeacon_xmit(struct vnt_private *, PSTxMgmtPacket pPacket); - int vnt_generate_fifo_header(struct vnt_private *, u32, PSTxDesc head_td, struct sk_buff *); int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *); diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 6606a1c239ee..430e9441bc9e 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -66,12 +66,11 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, PSMgmtObject pMgmt = pDevice->pMgmt; PSTxDesc pHeadTD, pLastTD; unsigned int cbFrameBodySize; - unsigned int uMACfragNum; + unsigned int uMACfragNum = 0; unsigned char byPktType; bool bNeedEncryption = false; SKeyItem STempKey; PSKeyItem pTransmitKey = NULL; - unsigned int cbHeaderSize; unsigned int ii; unsigned char *pbyBSSID; @@ -120,9 +119,6 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, } } - uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, - cbFrameBodySize, &pDevice->sTxEthHeader); - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) return false; @@ -152,12 +148,6 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, if (pDevice->wCurrentRate <= RATE_11M) byPktType = PK_TYPE_11B; - vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, - bNeedEncryption, cbFrameBodySize, TYPE_AC0DMA, - pHeadTD, &pDevice->sTxEthHeader, pbySkbData, - pTransmitKey, uNodeIndex, &uMACfragNum, - &cbHeaderSize); - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { /* Disable PS */ MACbPSWakeup(pDevice->PortOffset); -- GitLab From 1a48e8c412b7524bd140cd5220ce1abed8c32004 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:31 +0000 Subject: [PATCH 2088/9457] staging: vt6655: s_cbFillTxBufHead remove unused parameters Remove the following parameters PSEthernetHeader psEthHeader PSKeyItem pTransmitKey bool bNeedEncrypt Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 5c460ad7665a..c47042c07aad 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -138,9 +138,8 @@ static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int uNodeIndex, unsigned int *puMACfragNum); + unsigned char *pPacket, unsigned int uNodeIndex, + unsigned int *puMACfragNum); static __le16 @@ -1041,9 +1040,8 @@ static unsigned int s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, unsigned int cbFrameBodySize, unsigned int uDMAIdx, PSTxDesc pHeadTD, - PSEthernetHeader psEthHeader, unsigned char *pPacket, - bool bNeedEncrypt, PSKeyItem pTransmitKey, - unsigned int is_pspoll, unsigned int *puMACfragNum) + unsigned char *pPacket, unsigned int is_pspoll, + unsigned int *puMACfragNum) { PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo; struct sk_buff *skb = td_info->skb; @@ -1413,8 +1411,8 @@ int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx, tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head, skb->len, - dma_idx, head_td, NULL, (u8 *)skb->data, - false, NULL, is_pspoll, &frag); + dma_idx, head_td, (u8 *)skb->data, + is_pspoll, &frag); if (info->control.hw_key) { tx_key = info->control.hw_key; -- GitLab From 7d48710aecf6acb8457f8e7d117beaa4c1554587 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:32 +0000 Subject: [PATCH 2089/9457] staging: vt6655: dead code remove bssdb.c header will be removed later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/bssdb.c | 1504 ------------------------------ drivers/staging/vt6655/bssdb.h | 115 --- drivers/staging/vt6655/vntwifi.c | 16 - 4 files changed, 1636 deletions(-) delete mode 100644 drivers/staging/vt6655/bssdb.c diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 271ca9df43a9..2c0b7932b297 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -9,7 +9,6 @@ vt6655_stage-y += device_main.o \ baseband.o \ wctl.o \ 80211mgr.o \ - bssdb.o \ rxtx.o \ dpc.o \ power.o \ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c deleted file mode 100644 index abe38e1f34eb..000000000000 --- a/drivers/staging/vt6655/bssdb.c +++ /dev/null @@ -1,1504 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: bssdb.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID - * BSSvClearBSSList - Clear BSS List - * BSSbInsertToBSSList - Insert a BSS set into known BSS list - * BSSbUpdateToBSSList - Update BSS set in known BSS list - * BSSDBbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr - * BSSvCreateOneNode - Allocate an Node for Node DB - * BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB - * BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status - * BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control - * - * Revision History: - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "device.h" -#include "80211hdr.h" -#include "bssdb.h" -#include "wmgr.h" -#include "datarate.h" -#include "desc.h" -#include "wcmd.h" -#include "wpa.h" -#include "baseband.h" -#include "rf.h" -#include "card.h" -#include "channel.h" -#include "mac.h" -#include "wpa2.h" -#include "iowpa.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ -static const unsigned short awHWRetry0[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, - {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, - {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} -}; -static const unsigned short awHWRetry1[5][5] = { - {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, - {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, - {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M}, - {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M} -}; - -/*--------------------- Static Functions --------------------------*/ - -void s_vCheckSensitivity( - void *hDeviceContext -); - -#ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - void *hDeviceContext -); -#endif - -void s_vCheckPreEDThreshold( - void *hDeviceContext -); -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Search known BSS list for Desire SSID or BSSID. - * - * Return Value: - * PTR to KnownBSS or NULL - * - -*/ - -PKnownBSS -BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char *pbyBSSID = NULL; - PWLAN_IE_SSID pSSID = NULL; - PKnownBSS pCurrBSS = NULL; - PKnownBSS pSelect = NULL; - unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned int ii = 0; - - if (pbyDesireBSSID != NULL) { - pr_debug("BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); - if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && - (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) - pbyBSSID = pbyDesireBSSID; - } - if (pbyDesireSSID != NULL) { - if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) - pSSID = (PWLAN_IE_SSID) pbyDesireSSID; - } - - if (pbyBSSID != NULL) { - /* match BSSID first */ - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pCurrBSS = &(pMgmt->sBSSList[ii]); - if (!pDevice->bLinkPass) - pCurrBSS->bSelected = false; - if ((pCurrBSS->bActive) && - (!pCurrBSS->bSelected)) { - if (ether_addr_equal(pCurrBSS->abyBSSID, - pbyBSSID)) { - if (pSSID != NULL) { - /* compare ssid */ - if (!memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len)) { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) -) { - pCurrBSS->bSelected = true; - return pCurrBSS; - } - } - } else { - if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) || - ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) -) { - pCurrBSS->bSelected = true; - return pCurrBSS; - } - } - } - } - } - } else { - /* ignore BSSID */ - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pCurrBSS = &(pMgmt->sBSSList[ii]); - /* 2007-0721-01by MikeLiu */ - pCurrBSS->bSelected = false; - if (pCurrBSS->bActive) { - if (pSSID != NULL) { - /* matched SSID */ - if (!!memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, - pSSID->len) || - (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) { - /* SSID not match skip this BSS */ - continue; - } - } - if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) || - ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) -) { - /* Type not match skip this BSS */ - pr_debug("BSS type mismatch.... Config[%d] BSS[0x%04x]\n", - pMgmt->eConfigMode, - pCurrBSS->wCapInfo); - continue; - } - - if (ePhyType != PHY_TYPE_AUTO) { - if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) || - ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) { - /* PhyType not match skip this BSS */ - pr_debug("Physical type mismatch.... ePhyType[%d] BSS[%d]\n", - ePhyType, - pCurrBSS->eNetworkTypeInUse); - continue; - } - } - - if (pSelect == NULL) { - pSelect = pCurrBSS; - } else { - /* compare RSSI, select signal strong one */ - if (pCurrBSS->uRSSI < pSelect->uRSSI) - pSelect = pCurrBSS; - } - } - } - if (pSelect != NULL) { - pSelect->bSelected = true; - return pSelect; - } - } - return NULL; -} - -/*+ - * - * Routine Description: - * Clear BSS List - * - * Return Value: - * None. - * - -*/ - -void -BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (bKeepCurrBSSID) { - if (pMgmt->sBSSList[ii].bActive && - ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, - pMgmt->abyCurrBSSID)) { - continue; - } - } - - if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) { - pMgmt->sBSSList[ii].uClearCount++; - continue; - } - - pMgmt->sBSSList[ii].bActive = false; - memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS)); - } - BSSvClearAnyBSSJoinRecord(pDevice); -} - -/*+ - * - * Routine Description: - * search BSS list by BSSID & SSID if matched - * - * Return Value: - * true if found. - * - -*/ -PKnownBSS -BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PKnownBSS pBSSList = NULL; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = &(pMgmt->sBSSList[ii]); - if (pBSSList->bActive) { - if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) { - if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) { - if (memcmp(pSSID->abySSID, - ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID, - pSSID->len) == 0) - return pBSSList; - } - } - } - } - - return NULL; -}; - -/*+ - * - * Routine Description: - * Insert a BSS set into known BSS list - * - * Return Value: - * true if success. - * - -*/ - -bool -BSSbInsertToBSSList( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - PKnownBSS pBSSList = NULL; - unsigned int ii; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]); - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]); - if (!pBSSList->bActive) - break; - } - - if (ii == MAX_BSS_NUM) { - pr_debug("Get free KnowBSS node failed\n"); - return false; - } - /* save the BSS info */ - pBSSList->bActive = true; - memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); - pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - - pBSSList->uChannel = byCurrChannel; - - if (pSuppRates->len > WLAN_RATES_MAXLEN) - pSuppRates->len = WLAN_RATES_MAXLEN; - memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) { - if (pExtSuppRates->len > WLAN_RATES_MAXLEN) - pExtSuppRates->len = WLAN_RATES_MAXLEN; - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - pr_debug("BSSbInsertToBSSList: pExtSuppRates->len = %d\n", - pExtSuppRates->len); - - } else { - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - } - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - /* check if BSS is 802.11a/b/g */ - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist) - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - else - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - /* assoc with BSS */ - if (pBSSList == pMgmt->pCurrBSS) - bParsingQuiet = true; - } - - WPA_ClearRSN(pBSSList); - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || pBSSList->bWPA2Valid) { - PSKeyItem pTransmitKey = NULL; - bool bIs802_1x = false; - - for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii++) { - if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) { - bIs802_1x = true; - break; - } - } - if (bIs802_1x && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && - (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - - if (pDevice->bLinkPass && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) || - KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey)) { - pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList; - pDevice->gsPMKIDCandidate.Version = 1; - - } - - } - } - } - - if (pDevice->bUpdateBBVGA) { - /* monitor if RSSI is too strong */ - pBSSList->byRSSIStatCnt = 0; - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); - pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; - for (ii = 1; ii < RSSI_STAT_COUNT; ii++) - pBSSList->ldBmAverage[ii] = 0; - } - - if ((pIE_Country != NULL) && pMgmt->b11hEnable) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if (bParsingQuiet && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - /* valid EID */ - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) -); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if (bParsingQuiet && (pQuiet != NULL)) - CARDbStartQuiet(pMgmt->pAdapter); - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; -} - -/*+ - * - * Routine Description: - * Update BSS set in known BSS list - * - * Return Value: - * true if success. - * - -*/ -/* TODO: input structure modify */ - -bool -BSSbUpdateToBSSList( - void *hDeviceContext, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -) -{ - int ii; - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - long ldBm; - bool bParsingQuiet = false; - PWLAN_IE_QUIET pQuiet = NULL; - - if (pBSSList == NULL) - return false; - - pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); - pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); - pBSSList->wCapInfo = cpu_to_le16(wCapInfo); - pBSSList->uClearCount = 0; - pBSSList->uChannel = byCurrChannel; - - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - - if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0)) - memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - - if (pExtSuppRates != NULL) - memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - else - memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - pBSSList->sERP.byERP = psERP->byERP; - pBSSList->sERP.bERPExist = psERP->bERPExist; - - /* check if BSS is 802.11a/b/g */ - if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { - pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; - } else { - if (pBSSList->sERP.bERPExist) - pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - else - pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } - - pBSSList->byRxRate = pRxPacket->byRxRate; - pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF; - if (bChannelHit) - pBSSList->uRSSI = pRxPacket->uRSSI; - pBSSList->bySQ = pRxPacket->bySQ; - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - /* assoc with BSS */ - if (pBSSList == pMgmt->pCurrBSS) - bParsingQuiet = true; - } - - WPA_ClearRSN(pBSSList); /* mike update */ - - if (pRSNWPA != NULL) { - unsigned int uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } - - WPA2_ClearRSN(pBSSList); /* mike update */ - - if (pRSN != NULL) { - unsigned int uLen = pRSN->len + 2; - - if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } - } - - if (pRxPacket->uRSSI != 0) { - RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm); - /* monitor if RSSI is too strong */ - pBSSList->byRSSIStatCnt++; - pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; - pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) - pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm); - } - } - - if ((pIE_Country != NULL) && pMgmt->b11hEnable) { - set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, - pIE_Country); - } - - if (bParsingQuiet && (pIE_Quiet != NULL)) { - if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && - (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - /* valid EID */ - if (pQuiet == NULL) { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - true, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) -); - } else { - pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; - CARDbSetQuiet(pMgmt->pAdapter, - false, - pQuiet->byQuietCount, - pQuiet->byQuietPeriod, - *((unsigned short *)pQuiet->abyQuietDuration), - *((unsigned short *)pQuiet->abyQuietOffset) - ); - } - } - } - - if (bParsingQuiet && (pQuiet != NULL)) - CARDbStartQuiet(pMgmt->pAdapter); - - pBSSList->uIELength = uIELength; - if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN) - pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN; - memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength); - - return true; -} - -/*+ - * - * Routine Description: - * Search Node DB table to find the index of matched DstAddr - * - * Return Value: - * None - * - -*/ - -bool -BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, - unsigned int *puNodeIndex) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned int ii; - - /* Index = 0 reserved for AP Node */ - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (ether_addr_equal(abyDstAddr, - pMgmt->sNodeDBTable[ii].abyMACAddr)) { - *puNodeIndex = ii; - return true; - } - } - } - - return false; -}; - -/*+ - * - * Routine Description: - * Find an empty node and allocat it; if there is no empty node, - * then use the most inactive one. - * - * Return Value: - * None - * - -*/ -void -BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - unsigned int BigestCount = 0; - unsigned int SelectIndex; - struct sk_buff *skb; - /* - * Index = 0 reserved for AP Node (In STA mode) - * Index = 0 reserved for Broadcast/MultiCast (In AP mode) - */ - SelectIndex = 1; - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) { - BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount; - SelectIndex = ii; - } - } else { - break; - } - } - - /* if not found replace uInActiveCount is largest one */ - if (ii == (MAX_NODE_NUM + 1)) { - *puNodeIndex = SelectIndex; - pr_info("Replace inactive node = %d\n", SelectIndex); - /* clear ps buffer */ - if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - } - } else { - *puNodeIndex = ii; - } - - memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB)); - pMgmt->sNodeDBTable[*puNodeIndex].bActive = true; - pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND; - /* for AP mode PS queue */ - skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); - pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; - pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; - pr_debug("Create node index = %d\n", ii); - return; -}; - -/*+ - * - * Routine Description: - * Remove Node by NodeIndex - * - * - * Return Value: - * None - * - -*/ -void -BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL) - dev_kfree_skb(skb); - /* clear context */ - memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB)); - /* clear tx bit map */ - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7]; - - return; -}; -/*+ - * - * Routine Description: - * Update AP Node content in Index 0 of KnownNodeDB - * - * - * Return Value: - * None - * - -*/ - -void -BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uRateLen = WLAN_RATES_MAXLEN; - - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - - pMgmt->sNodeDBTable[0].bActive = true; - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - uRateLen); - pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - uRateLen); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) -); - memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate; - pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo); - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; - netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n", - pMgmt->sNodeDBTable[0].wMaxSuppRate); - /* auto rate fallback function initiation */ - pr_debug("pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); -}; - -/*+ - * - * Routine Description: - * Add Multicast Node content in Index 0 of KnownNodeDB - * - * - * Return Value: - * None - * - -*/ - -void -BSSvAddMulticastNode( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - - if (!pDevice->bEnableHostWEP) - memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); - memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN); - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].bPSEnable = false; - skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); - RATEvParseMaxRate((void *)pDevice, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, - (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, - true, - &(pMgmt->sNodeDBTable[0].wMaxBasicRate), - &(pMgmt->sNodeDBTable[0].wMaxSuppRate), - &(pMgmt->sNodeDBTable[0].wSuppRate), - &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), - &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) -); - pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate; - netdev_dbg(pDevice->dev, - "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; -}; - -/*+ - * - * Routine Description: - * - * - * Second call back function to update Node DB info & AP link status - * - * - * Return Value: - * none. - * - -*/ -void -BSSvSecondCallBack( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - PWLAN_IE_SSID pItemSSID, pCurrSSID; - unsigned int uSleepySTACnt = 0; - unsigned int uNonShortSlotSTACnt = 0; - unsigned int uLongPreambleSTACnt = 0; - viawget_wpa_header *wpahdr; /* DavidWang */ - - spin_lock_irq(&pDevice->lock); - - pDevice->uAssocCount = 0; - - pDevice->byERPFlag &= - ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1)); - - if (pDevice->wUseProtectCntDown > 0) { - pDevice->wUseProtectCntDown--; - } else { - /* disable protect mode */ - pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1)); - } - - if (pDevice->eCommandState == WLAN_ASSOCIATE_WAIT) { - pDevice->byReAssocCount++; - /* 10 sec timeout */ - if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) { - netdev_info(pDevice->dev, "Re-association timeout!!!\n"); - pDevice->byReAssocCount = 0; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } else if (pDevice->bLinkPass) - pDevice->byReAssocCount = 0; - } - -#ifdef Calcu_LinkQual - s_uCalculateLinkQual((void *)pDevice); -#endif - - for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - /* increase in-activity counter */ - pMgmt->sNodeDBTable[ii].uInActiveCount++; - - if (ii > 0) { - if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) { - BSSvRemoveOneNode(pDevice, ii); - pr_debug("Inactive timeout [%d] sec, STA index = [%d] remove\n", - MAX_INACTIVE_COUNT, ii); - continue; - } - - if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) { - pDevice->uAssocCount++; - - /* check if Non ERP exist */ - if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) { - if (!pMgmt->sNodeDBTable[ii].bShortPreamble) { - pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); - uLongPreambleSTACnt++; - } - if (!pMgmt->sNodeDBTable[ii].bERPExist) { - pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1); - pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1); - } - if (!pMgmt->sNodeDBTable[ii].bShortSlotTime) - uNonShortSlotSTACnt++; - } - } - - /* check if any STA in PS mode */ - if (pMgmt->sNodeDBTable[ii].bPSEnable) - uSleepySTACnt++; - - } - - /* rate fallback check */ - if (!pDevice->bFixRate) { - if (ii > 0) { - /* ii = 0 for multicast node (AP & Adhoc) */ - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); - } else { - /* ii = 0 reserved for unicast AP node (Infra STA) */ - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) - netdev_dbg(pDevice->dev, - "SecondCallback:Before:TxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); - netdev_dbg(pDevice->dev, - "SecondCallback:After:TxDataRate is %d\n", - pMgmt->sNodeDBTable[0].wTxDataRate); - - } - - } - - /* check if pending PS queue */ - if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { - pr_debug("Index= %d, Queue = %d pending\n", - ii, - pMgmt->sNodeDBTable[ii].wEnQueueCnt); - if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { - BSSvRemoveOneNode(pDevice, ii); - pr_info("Pending many queues PS STA Index = %d remove\n", - ii); - continue; - } - } - } - - } - - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) { - /* on/off protect mode */ - if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { - if (!pDevice->bProtectMode) { - MACvEnableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = true; - } - } else { - if (pDevice->bProtectMode) { - MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bProtectMode = false; - } - } - /* on/off short slot time */ - - if (uNonShortSlotSTACnt > 0) { - if (pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = false; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } else { - if (!pDevice->bShortSlotTime) { - pDevice->bShortSlotTime = true; - BBvSetShortSlotTime(pDevice); - vUpdateIFS((void *)pDevice); - } - } - - /* on/off barker long preamble mode */ - - if (uLongPreambleSTACnt > 0) { - if (!pDevice->bBarkerPreambleMd) { - MACvEnableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = true; - } - } else { - if (pDevice->bBarkerPreambleMd) { - MACvDisableBarkerPreambleMd(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = false; - } - } - - } - - /* check if any STA in PS mode, enable DTIM multicast deliver */ - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (uSleepySTACnt > 0) - pMgmt->sNodeDBTable[0].bPSEnable = true; - else - pMgmt->sNodeDBTable[0].bPSEnable = false; - } - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - - if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { - /* assoc with BSS */ - if (pMgmt->sNodeDBTable[0].bActive) { - if (pDevice->bUpdateBBVGA) - s_vCheckPreEDThreshold((void *)pDevice); - - if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && - (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) { - pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - } - - if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { - pMgmt->sNodeDBTable[0].bActive = false; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - pDevice->bRoaming = true; - pr_info("Lost AP beacon [%d] sec, disconnected !\n", - pMgmt->sNodeDBTable[0].uInActiveCount); - if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { - wpahdr = (viawget_wpa_header *)pDevice->skb->data; - wpahdr->type = VIAWGET_DISASSOC_MSG; - wpahdr->resp_ie_len = 0; - wpahdr->req_ie_len = 0; - skb_put(pDevice->skb, sizeof(viawget_wpa_header)); - pDevice->skb->dev = pDevice->wpadev; - skb_reset_mac_header(pDevice->skb); - pDevice->skb->pkt_type = PACKET_HOST; - pDevice->skb->protocol = htons(ETH_P_802_2); - memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); - netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); - } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - { - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } -#endif - } - } else if (pItemSSID->len != 0) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - /* - * network manager support need not do - * Roaming scan??? - */ - if (pDevice->bWPASuppWextEnabled) - pDevice->uAutoReConnectTime = 0; -#endif - } else { - /* - * mike use old encryption status - * for wpa reauthentication - */ - if (pDevice->bWPADEVUp) - pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; - - pr_debug("Roaming ...\n"); - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - pDevice->uAutoReConnectTime = 0; - } - } - } - - if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - /* if adhoc started which essid is NULL string, rescanning */ - if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) { - if (pDevice->uAutoReConnectTime < 10) { - pDevice->uAutoReConnectTime++; - } else { - pr_info("Adhoc re-scanning ...\n"); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - pDevice->uAutoReConnectTime = 0; - } - } - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (pDevice->bUpdateBBVGA) - s_vCheckPreEDThreshold((void *)pDevice); - if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) { - pr_info("Lost other STA beacon [%d] sec, started !\n", - pMgmt->sNodeDBTable[0].uInActiveCount); - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - pMgmt->eCurrState = WMAC_STATE_STARTED; - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - } - } - } - - spin_unlock_irq(&pDevice->lock); - - pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); - add_timer(&pMgmt->sTimerSecondCallback); -} - -/*+ - * - * Routine Description: - * - * - * Update Tx attemps, Tx failure counter in Node DB - * - * - * Return Value: - * none. - * - -*/ - -void -BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int uNodeIndex = 0; - unsigned char byTxRetry = (byTsr0 & TSR0_NCR); - PSTxBufHead pTxBufHead; - PS802_11Header pMACHeader; - unsigned short wRate; - unsigned short wFallBackRate = RATE_1M; - unsigned char byFallBack; - unsigned int ii; - - pTxBufHead = (PSTxBufHead) pbyBuffer; - if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) - byFallBack = AUTO_FB_0; - else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) - byFallBack = AUTO_FB_1; - else - byFallBack = AUTO_FB_NONE; - wRate = pTxBufHead->wReserved; - - /* Only Unicast using support rates */ - if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { - pr_debug("wRate %04X, byTsr0 %02X, byTsr1 %02X\n", - wRate, byTsr0, byTsr1); - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { - pMgmt->sNodeDBTable[0].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[0].uTxFailures++; - } - pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE] += byTxRetry; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry; - } else if (byFallBack == AUTO_FB_0) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; - } - } - } - } - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize); - - if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)) { - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; - if ((byTsr1 & TSR1_TERR) == 0) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - wFallBackRate = wRate; - } else if (byFallBack == AUTO_FB_0) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - } else if (byFallBack == AUTO_FB_1) { - if (byTxRetry < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry; - if (byTxRetry != 0) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE] += byTxRetry; - if ((byFallBack == AUTO_FB_NONE) || - (wRate < RATE_18M)) { - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate] += byTxRetry; - } else if (byFallBack == AUTO_FB_0) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry0[wRate - RATE_18M][ii]; - else - wFallBackRate = awHWRetry0[wRate - RATE_18M][4]; - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } else if (byFallBack == AUTO_FB_1) { - for (ii = 0; ii < byTxRetry; ii++) { - if (ii < 5) - wFallBackRate = awHWRetry1[wRate-RATE_18M][ii]; - else - wFallBackRate = awHWRetry1[wRate-RATE_18M][4]; - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++; - } - } - } - } - } - } -} - -/*+ - * - * Routine Description: - * Clear Nodes & skb in DB Table - * - * - * Parameters: - * In: - * hDeviceContext - The adapter context. - * uStartIndex - starting index - * Out: - * none - * - * Return Value: - * None. - * - -*/ - -void -BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex -) - -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - struct sk_buff *skb; - unsigned int ii; - - for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive) { - /* check if sTxPSQueue has been initial */ - if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - pr_debug("PS skb != NULL %d\n", ii); - dev_kfree_skb(skb); - } - } - memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB)); - } - } - - return; -}; - -void s_vCheckSensitivity( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = pDevice->pMgmt; - int ii; - - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) && - (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { - return; - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) { - /* Update BB Reg if RSSI is too strong */ - long LocalldBmAverage = 0; - long uNumofdBm = 0; - - for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) { - uNumofdBm++; - LocalldBmAverage += pBSSList->ldBmAverage[ii]; - } - } - if (uNumofdBm > 0) { - LocalldBmAverage = LocalldBmAverage/uNumofdBm; - for (ii = 0; ii < BB_VGA_LEVEL; ii++) { - pr_debug("LocalldBmAverage:%ld, %ld %02x\n", - LocalldBmAverage, - pDevice->ldBmThreshold[ii], - pDevice->abyBBVGA[ii]); - if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) { - pDevice->byBBVGANew = pDevice->abyBBVGA[ii]; - break; - } - } - if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { - pDevice->uBBVGADiffCount++; - } else { - pDevice->uBBVGADiffCount = 0; - } - } - } - } -} - -void -BSSvClearAnyBSSJoinRecord( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PSMgmtObject pMgmt = pDevice->pMgmt; - unsigned int ii; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) - pMgmt->sBSSList[ii].bSelected = false; -} - -#ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - unsigned long TxOkRatio, TxCnt; - unsigned long RxOkRatio, RxCnt; - unsigned long RssiRatio; - long ldBm; - - TxCnt = pDevice->scStatistic.TxNoRetryOkCount + - pDevice->scStatistic.TxRetryOkCount + - pDevice->scStatistic.TxFailCount; - RxCnt = pDevice->scStatistic.RxFcsErrCnt + - pDevice->scStatistic.RxOkCnt; - TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); - RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); - /* decide link quality */ - if (!pDevice->bLinkPass) { - pDevice->scStatistic.LinkQuality = 0; - pDevice->scStatistic.SignalStren = 0; - } else { - RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - if (-ldBm < 50) - RssiRatio = 4000; - else if (-ldBm > 90) - RssiRatio = 0; - else - RssiRatio = (40-(-ldBm-50))*4000/40; - pDevice->scStatistic.SignalStren = RssiRatio/40; - pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; - } - pDevice->scStatistic.RxFcsErrCnt = 0; - pDevice->scStatistic.RxOkCnt = 0; - pDevice->scStatistic.TxFailCount = 0; - pDevice->scStatistic.TxNoRetryOkCount = 0; - pDevice->scStatistic.TxRetryOkCount = 0; -} -#endif - -void s_vCheckPreEDThreshold( - void *hDeviceContext -) -{ - struct vnt_private *pDevice = hDeviceContext; - PKnownBSS pBSSList = NULL; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) - pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1); - } -} diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index 8a37a11809bb..511b7f907953 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -207,119 +207,4 @@ typedef struct tagKnownNodeDB { unsigned int uTimeCount; } KnownNodeDB, *PKnownNodeDB; -PKnownBSS -BSSpSearchBSSList( - void *hDeviceContext, - unsigned char *pbyDesireBSSID, - unsigned char *pbyDesireSSID, - CARD_PHY_TYPE ePhyType -); - -PKnownBSS -BSSpAddrIsInBSSList( - void *hDeviceContext, - unsigned char *abyBSSID, - PWLAN_IE_SSID pSSID -); - -void -BSSvClearBSSList( - void *hDeviceContext, - bool bKeepCurrBSSID -); - -bool -BSSbInsertToBSSList( - void *hDeviceContext, - unsigned char *abyBSSIDAddr, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -); - -bool -BSSbUpdateToBSSList( - void *hDeviceContext, - __le64 qwTimestamp, - unsigned short wBeaconInterval, - unsigned short wCapInfo, - unsigned char byCurrChannel, - bool bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - unsigned int uIELength, - unsigned char *pbyIEs, - void *pRxPacketContext -); - -bool -BSSDBbIsSTAInNodeDB(void *hDeviceContext, unsigned char *abyDstAddr, - unsigned int *puNodeIndex); - -void -BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex); - -void -BSSvUpdateAPNode( - void *hDeviceContext, - unsigned short *pwCapInfo, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pExtSuppRates -); - -void -BSSvSecondCallBack( - void *hDeviceContext -); - -void -BSSvUpdateNodeTxCounter( - void *hDeviceContext, - unsigned char byTsr0, - unsigned char byTsr1, - unsigned char *pbyBuffer, - unsigned int uFIFOHeaderSize -); - -void -BSSvRemoveOneNode( - void *hDeviceContext, - unsigned int uNodeIndex -); - -void -BSSvAddMulticastNode( - void *hDeviceContext -); - -void -BSSvClearNodeDBTable( - void *hDeviceContext, - unsigned int uStartIndex -); - -void -BSSvClearAnyBSSJoinRecord( - void *hDeviceContext -); - #endif /*__BSSDB_H__ */ diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 9cc3a67399ed..85374decaefa 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -488,8 +488,6 @@ VNTWIFIvUpdateNodeTxCounter( if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) - return; } pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; @@ -516,7 +514,6 @@ VNTWIFIvGetTxRate( ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; unsigned short wTxDataRate = RATE_1M; unsigned char byACKRate = RATE_1M; unsigned char byCCKBasicRate = RATE_1M; @@ -527,19 +524,6 @@ VNTWIFIvGetTxRate( if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { /* Adhoc Tx rate decided from node DB */ - if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) { - wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates); - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates); - } else { - if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) - wTxDataRate = RATE_2M; - else - wTxDataRate = RATE_24M; - - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } } else { /* Infrastructure: rate decided from AP Node, index = 0 */ wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate); -- GitLab From f3de0df9b01a45d0d95bb1e43750d895ef8d79db Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:33 +0000 Subject: [PATCH 2090/9457] staging: vt6655: dead code datarate.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/datarate.c | 410 --------------------------- drivers/staging/vt6655/datarate.h | 78 ----- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/vntwifi.c | 14 - 5 files changed, 504 deletions(-) delete mode 100644 drivers/staging/vt6655/datarate.c delete mode 100644 drivers/staging/vt6655/datarate.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 2c0b7932b297..3c993a86f745 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -12,7 +12,6 @@ vt6655_stage-y += device_main.o \ rxtx.o \ dpc.o \ power.o \ - datarate.o \ srom.o \ mib.o \ rc4.o \ diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c deleted file mode 100644 index 52907a4fae9d..000000000000 --- a/drivers/staging/vt6655/datarate.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: datarate.c - * - * Purpose: Handles the auto fallback & data rates functions - * - * Author: Lyndon Chen - * - * Date: July 17, 2002 - * - * Functions: - * RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame - * RATEvTxRateFallBack - Rate fallback Algorithm Implementaion - * RATEuSetIE- Set rate IE field. - * - * Revision History: - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "mac.h" -#include "80211mgr.h" -#include "bssdb.h" -#include "datarate.h" -#include "card.h" -#include "baseband.h" -#include "srom.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -extern unsigned short TxRate_iwconfig; /* 2008-5-8 by chester */ -/*--------------------- Static Variables --------------------------*/ -static const unsigned char acbyIERate[MAX_RATE] = { -0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C -}; - -#define AUTORATE_TXOK_CNT 0x0400 -#define AUTORATE_TXFAIL_CNT 0x0064 -#define AUTORATE_TIMEOUT 10 - -/*--------------------- Static Functions --------------------------*/ - -void s_vResetCounter( - PKnownNodeDB psNodeDBTable -); - -void -s_vResetCounter( - PKnownNodeDB psNodeDBTable -) -{ - unsigned char ii; - - /* clear statistic counter for auto_rate */ - for (ii = 0; ii <= MAX_RATE; ii++) { - psNodeDBTable->uTxOk[ii] = 0; - psNodeDBTable->uTxFail[ii] = 0; - } -} - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Get RateIdx from the value in SuppRates IE or ExtSuppRates IE - * - * Parameters: - * In: - * unsigned char - Rate value in SuppRates IE or ExtSuppRates IE - * Out: - * none - * - * Return Value: RateIdx - * - -*/ -unsigned char -DATARATEbyGetRateIdx( - unsigned char byRate -) -{ - unsigned char ii; - - /* Erase basicRate flag. */ - byRate = byRate & 0x7F;/* 0111 1111 */ - - for (ii = 0; ii < MAX_RATE; ii++) { - if (acbyIERate[ii] == byRate) - return ii; - } - return 0; -} - -/*+ - * - * Routine Description: - * Rate fallback Algorithm Implementation - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * psNodeDBTable - Pointer to Node Data Base - * Out: - * none - * - * Return Value: none - * - -*/ -#define AUTORATE_TXCNT_THRESHOLD 20 -#define AUTORATE_INC_THRESHOLD 30 - -/*+ - * - * Description: - * Get RateIdx from the value in SuppRates IE or ExtSuppRates IE - * - * Parameters: - * In: - * unsigned char - Rate value in SuppRates IE or ExtSuppRates IE - * Out: - * none - * - * Return Value: RateIdx - * - -*/ -unsigned short -wGetRateIdx( - unsigned char byRate -) -{ - unsigned short ii; - - /* Erase basicRate flag. */ - byRate = byRate & 0x7F;/* 0111 1111 */ - - for (ii = 0; ii < MAX_RATE; ii++) { - if (acbyIERate[ii] == byRate) - return ii; - } - - return 0; -} - -/*+ - * - * Description: - * Parsing the highest basic & support rate in rate field of frame. - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * pItemRates - Pointer to Rate field defined in 802.11 spec. - * pItemExtRates - Pointer to Extended Rate field defined in 802.11 spec. - * Out: - * pwMaxBasicRate - Maximum Basic Rate - * pwMaxSuppRate - Maximum Supported Rate - * pbyTopCCKRate - Maximum Basic Rate in CCK mode - * pbyTopOFDMRate - Maximum Basic Rate in OFDM mode - * - * Return Value: none - * - -*/ -void -RATEvParseMaxRate( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate -) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned int ii; - unsigned char byHighSuppRate = 0; - unsigned char byRate = 0; - unsigned short wOldBasicRate = pDevice->wBasicRate; - unsigned int uRateLen; - - if (pItemRates == NULL) - return; - - *pwSuppRate = 0; - uRateLen = pItemRates->len; - - pr_debug("ParseMaxRate Len: %d\n", uRateLen); - if (pDevice->eCurrentPHYType != PHY_TYPE_11B) { - if (uRateLen > WLAN_RATES_MAXLEN) - uRateLen = WLAN_RATES_MAXLEN; - } else { - if (uRateLen > WLAN_RATES_MAXLEN_11B) - uRateLen = WLAN_RATES_MAXLEN_11B; - } - - for (ii = 0; ii < uRateLen; ii++) { - byRate = (unsigned char)(pItemRates->abyRates[ii]); - if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate) { - /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - pr_debug("ParseMaxRate AddBasicRate: %d\n", - wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<byElementID == WLAN_EID_EXTSUPP_RATES) && - (pDevice->eCurrentPHYType != PHY_TYPE_11B)) { - unsigned int uExtRateLen = pItemExtRates->len; - - if (uExtRateLen > WLAN_RATES_MAXLEN) - uExtRateLen = WLAN_RATES_MAXLEN; - - for (ii = 0; ii < uExtRateLen; ii++) { - byRate = (unsigned char)(pItemExtRates->abyRates[ii]); - /* select highest basic rate */ - if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { - /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ - CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - pr_debug("ParseMaxRate AddBasicRate: %d\n", - wGetRateIdx(byRate)); - } - byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F); - if (byHighSuppRate == 0) - byHighSuppRate = byRate; - if (byRate > byHighSuppRate) - byHighSuppRate = byRate; - *pwSuppRate |= (1<byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice)) - pDevice->byPacketType = PK_TYPE_11GA; - - *pbyTopCCKRate = pDevice->byTopCCKBasicRate; - *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate; - *pwMaxSuppRate = wGetRateIdx(byHighSuppRate); - if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB)) - *pwMaxBasicRate = pDevice->byTopCCKBasicRate; - else - *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; - if (wOldBasicRate != pDevice->wBasicRate) - CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); - - pr_debug("Exit ParseMaxRate\n"); -} - -/*+ - * - * Routine Description: - * Rate fallback Algorithm Implementaion - * - * Parameters: - * In: - * pDevice - Pointer to the adapter - * psNodeDBTable - Pointer to Node Data Base - * Out: - * none - * - * Return Value: none - * - -*/ -#define AUTORATE_TXCNT_THRESHOLD 20 -#define AUTORATE_INC_THRESHOLD 30 - -void -RATEvTxRateFallBack( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable -) -{ - struct vnt_private *pDevice = pDeviceHandler; - unsigned short wIdxDownRate = 0; - unsigned int ii; - bool bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true, true, true, true, true, true}; - unsigned long dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540}; - unsigned long dwThroughput = 0; - unsigned short wIdxUpRate = 0; - unsigned long dwTxDiff = 0; - - if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) - /* Don't do Fallback when scanning Channel */ - return; - - psNodeDBTable->uTimeCount++; - - if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE]) - dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE]; - - if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) && - (dwTxDiff < AUTORATE_TXFAIL_CNT) && - (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) { - return; - } - - if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) - psNodeDBTable->uTimeCount = 0; - - for (ii = 0; ii < MAX_RATE; ii++) { - if (psNodeDBTable->wSuppRate & (0x0001<wTxDataRate; ii++) { - if ((psNodeDBTable->uTxOk[ii] != 0) || - (psNodeDBTable->uTxFail[ii] != 0)) { - dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii]; - if (ii < RATE_11M) - psNodeDBTable->uTxFail[ii] *= 4; - - dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]); - } - } - dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate]; - - wIdxDownRate = psNodeDBTable->wTxDataRate; - for (ii = psNodeDBTable->wTxDataRate; ii > 0;) { - ii--; - if ((dwThroughputTbl[ii] > dwThroughput) && bAutoRate[ii]) { - dwThroughput = dwThroughputTbl[ii]; - wIdxDownRate = (unsigned short) ii; - } - } - psNodeDBTable->wTxDataRate = wIdxDownRate; - if (psNodeDBTable->uTxOk[MAX_RATE]) { - if (psNodeDBTable->uTxOk[MAX_RATE] > - (psNodeDBTable->uTxFail[MAX_RATE] * 4)) { - psNodeDBTable->wTxDataRate = wIdxUpRate; - } - } else { - /* adhoc, if uTxOk =0 & uTxFail = 0 */ - if (psNodeDBTable->uTxFail[MAX_RATE] == 0) - psNodeDBTable->wTxDataRate = wIdxUpRate; - } - - /* 2008-5-8 by chester */ - TxRate_iwconfig = psNodeDBTable->wTxDataRate; - s_vResetCounter(psNodeDBTable); -} - -/*+ - * - * Description: - * This routine is used to assemble available Rate IE. - * - * Parameters: - * In: - * pDevice - * Out: - * - * Return Value: None - * - -*/ -unsigned char -RATEuSetIE( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen -) -{ - unsigned int ii, uu, uRateCnt = 0; - - if ((pSrcRates == NULL) || (pDstRates == NULL)) - return 0; - - if (pSrcRates->len == 0) - return 0; - - for (ii = 0; ii < uRateLen; ii++) { - for (uu = 0; uu < pSrcRates->len; uu++) { - if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) { - pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu]; - break; - } - } - } - return (unsigned char)uRateCnt; -} diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h deleted file mode 100644 index d55b07455cc2..000000000000 --- a/drivers/staging/vt6655/datarate.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: datarate.h - * - * Purpose: Handles the auto fallback & data rates functions - * - * Author: Lyndon Chen - * - * Date: July 16, 2002 - * - */ -#ifndef __DATARATE_H__ -#define __DATARATE_H__ - -#define FALLBACK_PKT_COLLECT_TR_H 50 -#define FALLBACK_PKT_COLLECT_TR_L 10 -#define FALLBACK_POLL_SECOND 5 -#define FALLBACK_RECOVER_SECOND 30 -#define FALLBACK_THRESHOLD 15 -#define UPGRADE_THRESHOLD 5 -#define UPGRADE_CNT_THRD 3 -#define RETRY_TIMES_THRD_H 2 -#define RETRY_TIMES_THRD_L 1 - -void -RATEvParseMaxRate( - void *pDeviceHandler, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pItemExtRates, - bool bUpdateBasicRate, - unsigned short *pwMaxBasicRate, - unsigned short *pwMaxSuppRate, - unsigned short *pwSuppRate, - unsigned char *pbyTopCCKRate, - unsigned char *pbyTopOFDMRate -); - -void -RATEvTxRateFallBack( - void *pDeviceHandler, - PKnownNodeDB psNodeDBTable -); - -unsigned char -RATEuSetIE( - PWLAN_IE_SUPP_RATES pSrcRates, - PWLAN_IE_SUPP_RATES pDstRates, - unsigned int uRateLen -); - -unsigned short -wGetRateIdx( - unsigned char byRate -); - -unsigned char -DATARATEbyGetRateIdx( - unsigned char byRate -); - -#endif /* __DATARATE_H__ */ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 991a276f1ecf..848c258119a6 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -69,7 +69,6 @@ #include "wroute.h" #include "bssdb.h" #include "dpc.h" -#include "datarate.h" #include "rf.h" #include "iowpa.h" #include diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 85374decaefa..27e055e89f7e 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -36,7 +36,6 @@ #include "country.h" #include "device.h" #include "wmgr.h" -#include "datarate.h" /*--------------------- Static Definitions -------------------------*/ @@ -210,7 +209,6 @@ VNTWIFIbyGetMaxSupportRate( if (pSupportRateIEs) { for (ii = 0; ii < pSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); if (bySupportRate > byMaxSupportRate) byMaxSupportRate = bySupportRate; @@ -218,7 +216,6 @@ VNTWIFIbyGetMaxSupportRate( } if (pExtSupportRateIEs) { for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - bySupportRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); if (bySupportRate > byMaxSupportRate) byMaxSupportRate = bySupportRate; @@ -252,7 +249,6 @@ VNTWIFIbyGetACKTxRate( ) { unsigned char byMaxAckRate; - unsigned char byBasicRate; unsigned int ii; if (byRxDataRate <= RATE_11M) { @@ -264,22 +260,12 @@ VNTWIFIbyGetACKTxRate( if (pSupportRateIEs) { for (ii = 0; ii < pSupportRateIEs->len; ii++) { if (pSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } } } } if (pExtSupportRateIEs) { for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { if (pExtSupportRateIEs->abyRates[ii] & 0x80) { - byBasicRate = DATARATEbyGetRateIdx(pExtSupportRateIEs->abyRates[ii]); - if ((byBasicRate <= byRxDataRate) && - (byBasicRate > byMaxAckRate)) { - byMaxAckRate = byBasicRate; - } } } } -- GitLab From 86b5afa757cddcf26b7ee6a2f21b70e313776faa Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:34 +0000 Subject: [PATCH 2091/9457] staging: vt6655: dead code remove IEEE11.h.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/IEEE11h.c | 139 ------------------------------- drivers/staging/vt6655/IEEE11h.h | 42 ---------- drivers/staging/vt6655/Makefile | 3 +- drivers/staging/vt6655/vntwifi.c | 3 - 4 files changed, 1 insertion(+), 186 deletions(-) delete mode 100644 drivers/staging/vt6655/IEEE11h.c delete mode 100644 drivers/staging/vt6655/IEEE11h.h diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c deleted file mode 100644 index 65eb4823a7f5..000000000000 --- a/drivers/staging/vt6655/IEEE11h.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: IEEE11h.c - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: Mar. 31, 2005 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "IEEE11h.h" -#include "device.h" -#include "wmgr.h" -#include "rxtx.h" -#include "channel.h" - -/*--------------------- Static Definitions -------------------------*/ - -#pragma pack(1) - -typedef struct _WLAN_FRAME_ACTION { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char abyVars[1]; -} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION; - -typedef struct _WLAN_FRAME_MSRREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; -} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ; - -typedef struct _WLAN_FRAME_MSRREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; -} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP; - -typedef struct _WLAN_FRAME_TPCREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REQ sTPCReqEIDs; -} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ; - -typedef struct _WLAN_FRAME_TPCREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REP sTPCRepEIDs; -} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP; - -#pragma pack() - -/* action field reference ieee 802.11h Table 20e */ -#define ACTION_MSRREQ 0 -#define ACTION_MSRREP 1 -#define ACTION_TPCREQ 2 -#define ACTION_TPCREP 3 -#define ACTION_CHSW 4 - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool IEEE11hbMSRRepTx(void *pMgmtHandle) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) - (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); - size_t uLength = 0; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + - sizeof(STxMgmtPacket)); - - pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) -); - - memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); - memcpy(pMSRRep->Header.abyAddr2, - CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); - memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - pMSRRep->byCategory = 0; - pMSRRep->byAction = 1; - pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) - (pMgmt->abyCurrentMSRReq))->byDialogToken; - - uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, - sMSRRepEIDs); - - pTxPacket->cbMPDULen = uLength; - pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; - return true; -} diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h deleted file mode 100644 index b3e318d7278f..000000000000 --- a/drivers/staging/vt6655/IEEE11h.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: IEEE11h.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with IEEE 802.11h. - * - * Author: Yiching Chen - * - * Date: Mar. 31, 2005 - * - */ - -#ifndef __IEEE11h_H__ -#define __IEEE11h_H__ - -#include "ttype.h" -#include "80211hdr.h" -#include "80211mgr.h" - -bool IEEE11hbMSRRepTx( - void *pMgmtHandle -); - -#endif /* __IEEE11h_H__ */ diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 3c993a86f745..141c0c11ee22 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -25,7 +25,6 @@ vt6655_stage-y += device_main.o \ rf.o \ wpa2.o \ aes_ccmp.o \ - vntwifi.o \ - IEEE11h.o + vntwifi.o obj-$(CONFIG_VT6655) += vt6655_stage.o diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 27e055e89f7e..a5eccf7cec8b 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -32,7 +32,6 @@ */ #include "vntwifi.h" -#include "IEEE11h.h" #include "country.h" #include "device.h" #include "wmgr.h" @@ -648,8 +647,6 @@ VNTWIFIbMeasureReport( pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; } - if (bEndOfReport) - IEEE11hbMSRRepTx(pMgmt); return true; } -- GitLab From dd1c689cec2dbfcb3910a002b39282efe10c29fe Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:35 +0000 Subject: [PATCH 2092/9457] staging: vt6655: card.c/h remove dead functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 724 ---------------------------------- drivers/staging/vt6655/card.h | 75 ---- 2 files changed, 799 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 72896c1b842d..bff77c88a792 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -34,8 +34,6 @@ * CARDvUpdateNextTBTT - Sync. NIC Beacon time * CARDbRadioPowerOff - Turn Off NIC Radio Power * CARDbRadioPowerOn - Turn On NIC Radio Power - * CARDbSetWEPMode - Set NIC Wep mode - * CARDbSetTxPower - Set NIC tx power * * Revision History: * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. @@ -50,12 +48,7 @@ #include "mac.h" #include "desc.h" #include "rf.h" -#include "vntwifi.h" #include "power.h" -#include "key.h" -#include "rc4.h" -#include "country.h" -#include "channel.h" /*--------------------- Static Definitions -------------------------*/ @@ -200,43 +193,6 @@ s_vCalculateOFDMRParameter( /*--------------------- Export Functions --------------------------*/ -/* - * Description: Get Card short preamble option value - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if short preamble; otherwise false - */ -bool CARDbIsShortPreamble(struct vnt_private *pDevice) -{ - - if (pDevice->byPreambleType == 0) - return false; - - return true; -} - -/* - * Description: Get Card short slot time option value - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if short slot time; otherwise false - */ -bool CARDbIsShorSlotTime(struct vnt_private *pDevice) -{ - - return pDevice->bShortSlotTime; -} - /* * Description: Update IFS * @@ -454,218 +410,6 @@ bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, return true; } -/* - * Description: Card Stop Hardware Tx - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * ePktType - Packet type to stop - * Out: - * none - * - * Return Value: true if all data packet complete; otherwise false. - */ -bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) -{ - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = true; - pDevice->bStopTx0Pkt = true; - pDevice->bStopDataPkt = true; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = true; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = true; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = true; - } - - if (pDevice->bStopBeacon == true) { - if (pDevice->bIsBeaconBufReadySet == true) { - if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) { - pDevice->cbBeaconBufReadySetCnt++; - return false; - } - } - pDevice->bIsBeaconBufReadySet = false; - pDevice->cbBeaconBufReadySetCnt = 0; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - /* wait all TD0 complete */ - if (pDevice->bStopTx0Pkt == true) { - if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) - return false; - } - /* wait all Data TD complete */ - if (pDevice->bStopDataPkt == true) { - if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) - return false; - } - - return true; -} - -/* - * Description: Card Start Hardware Tx - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * ePktType - Packet type to start - * Out: - * none - * - * Return Value: true if success; false if failed. - */ -bool CARDbStartTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) -{ - - if (ePktType == PKT_TYPE_802_11_ALL) { - pDevice->bStopBeacon = false; - pDevice->bStopTx0Pkt = false; - pDevice->bStopDataPkt = false; - } else if (ePktType == PKT_TYPE_802_11_BCN) { - pDevice->bStopBeacon = false; - } else if (ePktType == PKT_TYPE_802_11_MNG) { - pDevice->bStopTx0Pkt = false; - } else if (ePktType == PKT_TYPE_802_11_DATA) { - pDevice->bStopDataPkt = false; - } - - if ((pDevice->bStopBeacon == false) && - (pDevice->bBeaconBufReady == true) && - (pDevice->op_mode == NL80211_IFTYPE_ADHOC)) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); - } - - return true; -} - -/* - * Description: Card Set BSSID value - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * pbyBSSID - pointer to BSSID field - * bAdhoc - flag to indicate IBSS - * Out: - * none - * - * Return Value: true if success; false if failed. - */ -bool CARDbSetBSSID(struct vnt_private *pDevice, - unsigned char *pbyBSSID, enum nl80211_iftype op_mode) -{ - - MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID); - memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN); - if (op_mode == NL80211_IFTYPE_ADHOC) - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - else - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC); - - if (op_mode == NL80211_IFTYPE_AP) - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - else - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP); - - if (op_mode == NL80211_IFTYPE_UNSPECIFIED) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = false; - pDevice->byRxMode &= ~RCR_BSSID; - pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode); - } else { - if (is_zero_ether_addr(pDevice->abyBSSID) == false) { - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); - pDevice->bBSSIDFilter = true; - pDevice->byRxMode |= RCR_BSSID; - } - pr_debug("wmgr: rx_mode = %x\n", pDevice->byRxMode); - } - /* Adopt BSS state in Adapter Device Object */ - pDevice->op_mode = op_mode; - return true; -} - -/* - * Description: Card indicate status - * - * Parameters: - * In: - * pDeviceHandler - The adapter to be set - * eStatus - Status - * Out: - * none - * - * Return Value: true if success; false if failed. - */ - -/* - * Description: Save Assoc info. contain in assoc. response frame - * - * Parameters: - * In: - * pDevice - The adapter to be set - * wCapabilityInfo - Capability information - * wStatus - Status code - * wAID - Assoc. ID - * uLen - Length of IEs - * pbyIEs - pointer to IEs - * Out: - * none - * - * Return Value: true if succeed; otherwise false - */ -bool CARDbSetTxDataRate( - struct vnt_private *pDevice, - unsigned short wDataRate -) -{ - - pDevice->wCurrentRate = wDataRate; - return true; -} - -/* - * Routine Description: - * Consider to power down when no more packets to tx or rx. - * - * Parameters: - * In: - * pDevice - The adapter to be set - * Out: - * none - * - * Return Value: true if power down success; otherwise false - */ -bool -CARDbPowerDown( - struct vnt_private *pDevice -) -{ - unsigned int uIdx; - - /* check if already in Doze mode */ - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) - return true; - - /* Froce PSEN on */ - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); - - /* check if all TD are empty */ - - for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { - if (pDevice->iTDUsed[uIdx] != 0) - return false; - } - - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); - return true; -} - /* * Description: Turn off Radio power * @@ -761,474 +505,6 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) return bResult; } -bool CARDbRemoveKey(struct vnt_private *pDevice, unsigned char *pbyBSSID) -{ - - KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset); - return true; -} - -/* - * Description: - * Add BSSID in PMKID Candidate list. - * - * Parameters: - * In: - * hDeviceContext - device structure point - * pbyBSSID - BSSID address for adding - * wRSNCap - BSS's RSN capability - * Out: - * none - * - * Return Value: none. - */ -bool -CARDbAdd_PMKID_Candidate( - struct vnt_private *pDevice, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap -) -{ - struct pmkid_candidate *pCandidateList; - unsigned int ii = 0; - - pr_debug("bAdd_PMKID_Candidate START: (%d)\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - - if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) { - pr_debug("vFlush_PMKID_Candidate: 3\n"); - memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); - } - - for (ii = 0; ii < 6; ii++) - pr_debug("%02X ", *(pbyBSSID + ii)); - - pr_debug("\n"); - - /* Update Old Candidate */ - for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if (bRSNCapExist && (wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - return true; - } - } - - /* New Candidate */ - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if (bRSNCapExist && (wRSNCap & BIT0)) - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - else - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - - ether_addr_copy(pCandidateList->BSSID, pbyBSSID); - pDevice->gsPMKIDCandidate.NumCandidates++; - pr_debug("NumCandidates:%d\n", - (int)pDevice->gsPMKIDCandidate.NumCandidates); - return true; -} - -void * -CARDpGetCurrentAddress( - struct vnt_private *pDevice -) -{ - - return pDevice->abyCurrentNetAddr; -} - -/* - * Description: - * Start Spectrum Measure defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -bool -CARDbStartMeasure( - struct vnt_private *pDevice, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs -) -{ - PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; - u64 qwCurrTSF; - u64 qwStartTSF; - bool bExpired = true; - unsigned short wDuration = 0; - - if ((pEID == NULL) || - (uNumOfMeasureEIDs == 0)) { - return true; - } - CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF); - if (pDevice->bMeasureInProgress == true) { - pDevice->bMeasureInProgress = false; - VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR); - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4); - /* clear measure control */ - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - set_channel(pDevice, pDevice->byOrgChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs; - - do { - pDevice->pCurrMeasureEID = pEID; - pEID++; - pDevice->uNumOfMeasureEIDs--; - - if (pDevice->byLocalID > REV_ID_VT3253_B1) { - qwStartTSF = *((u64 *)(pDevice->pCurrMeasureEID->sReq.abyStartTime)); - wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); - wDuration += 1; /* 1 TU for channel switching */ - - if (qwStartTSF == 0) { - /* start immediately by setting start TSF == current TSF + 2 TU */ - qwStartTSF = qwCurrTSF + 2048; - - bExpired = false; - break; - } else { - /* start at setting start TSF - 1TU(for channel switching) */ - qwStartTSF -= 1024; - } - - if (qwCurrTSF < qwStartTSF) { - bExpired = false; - break; - } - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_LATE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } else { - /* hardware do not support measure */ - VNTWIFIbMeasureReport(pDevice->pMgmt, - false, - pDevice->pCurrMeasureEID, - MEASURE_MODE_INCAPABLE, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - } while (pDevice->uNumOfMeasureEIDs != 0); - - if (!bExpired) { - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, (u32)qwStartTSF); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, (u32)(qwStartTSF >> 32)); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN); - MACvSelectPage0(pDevice->PortOffset); - } else { - /* all measure start time expired we should complete action */ - VNTWIFIbMeasureReport(pDevice->pMgmt, - true, - NULL, - 0, - pDevice->byBasicMap, - pDevice->byCCAFraction, - pDevice->abyRPIs - ); - } - return true; -} - -/* - * Description: - * Do Channel Switch defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -bool -CARDbChannelSwitch( - struct vnt_private *pDevice, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount -) -{ - bool bResult = true; - - if (byCount == 0) { - bResult = set_channel(pDevice, byNewChannel); - VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel); - MACvSelectPage1(pDevice->PortOffset); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE); - MACvSelectPage0(pDevice->PortOffset); - return bResult; - } - pDevice->byChannelSwitchCount = byCount; - pDevice->byNewChannel = byNewChannel; - pDevice->bChannelSwitch = true; - if (byMode == 1) - bResult = CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL); - - return bResult; -} - -/* - * Description: - * Handle Quiet EID defined in 802.11h - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -bool -CARDbSetQuiet( - struct vnt_private *pDevice, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset -) -{ - unsigned int ii = 0; - - if (bResetQuiet) { - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) - pDevice->sQuiet[ii].bEnable = false; - - pDevice->uQuietEnqueue = 0; - pDevice->bEnableFirstQuiet = false; - pDevice->bQuietEnable = false; - pDevice->byQuietStartCount = byQuietCount; - } - if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) { - pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true; - pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod; - pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset; - pDevice->uQuietEnqueue++; - pDevice->uQuietEnqueue %= MAX_QUIET_COUNT; - if (pDevice->byQuietStartCount < byQuietCount) - pDevice->byQuietStartCount = byQuietCount; - } - return true; -} - -/* - * Description: - * Do Quiet, It will be called by either ISR(after start) - * or VNTWIFI(before start) so we do not need a SPINLOCK - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -bool -CARDbStartQuiet( - struct vnt_private *pDevice -) -{ - unsigned int ii = 0; - unsigned long dwStartTime = 0xFFFFFFFF; - unsigned int uCurrentQuietIndex = 0; - unsigned long dwNextTime = 0; - unsigned long dwGap = 0; - unsigned long dwDuration = 0; - - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { - if ((pDevice->sQuiet[ii].bEnable == true) && - (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) { - dwStartTime = pDevice->sQuiet[ii].dwStartTime; - uCurrentQuietIndex = ii; - } - } - if (dwStartTime == 0xFFFFFFFF) { - /* no more quiet */ - pDevice->bQuietEnable = false; - MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - if (pDevice->bQuietEnable == false) { - /* first quiet */ - pDevice->byQuietStartCount--; - dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - dwNextTime %= pDevice->wBeaconInterval; - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration); - if (pDevice->byQuietStartCount == 0) { - pDevice->bEnableFirstQuiet = false; - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); - } else { - pDevice->bEnableFirstQuiet = true; - } - MACvSelectPage0(pDevice->PortOffset); - } else { - if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) { - /* overlap with previous Quiet */ - dwGap = pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) { - /* - * return false to indicate next quiet - * expired, should call this function - * again - */ - return false; - } - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap; - dwGap = 0; - } else { - dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime; - dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration; - } - /* set GAP and Next duration */ - MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap); - VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration); - MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT); - MACvSelectPage0(pDevice->PortOffset); - } - pDevice->bQuietEnable = true; - pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime; - pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration; - if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) { - /* not period disable current quiet element */ - pDevice->sQuiet[uCurrentQuietIndex].bEnable = false; - } else { - /* set next period start time */ - dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod; - dwNextTime *= pDevice->wBeaconInterval; - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime; - } - if (pDevice->dwCurrentQuietEndTime > 0x80010000) { - /* decreament all time to avoid wrap around */ - for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { - if (pDevice->sQuiet[ii].bEnable == true) - pDevice->sQuiet[ii].dwStartTime -= 0x80000000; - - } - pDevice->dwCurrentQuietEndTime -= 0x80000000; - } - } - return true; -} - -/* - * Description: - * Set Local Power Constraint - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -void -CARDvSetPowerConstraint( - struct vnt_private *pDevice, - unsigned char byChannel, - char byPower -) -{ - - if (byChannel > CB_MAX_CHANNEL_24G) { - if (pDevice->bCountryInfo5G == true) - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - - } else { - if (pDevice->bCountryInfo24G == true) - pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower; - - } -} - -/* - * Description: - * Set Local Power Constraint - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -void -CARDvGetPowerCapability( - struct vnt_private *pDevice, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower -) -{ - unsigned char byDec = 0; - - *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh]; - byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh]; - if (pDevice->byRFType == RF_UW2452) { - byDec *= 3; - byDec >>= 1; - } else { - byDec <<= 1; - } - *pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec; -} - -/* - * Description: - * Get Current Tx Power - * - * Parameters: - * In: - * hDeviceContext - device structure point - * Out: - * none - * - * Return Value: none. - */ -char -CARDbyGetTransmitPower( - struct vnt_private *pDevice -) -{ - - return pDevice->byCurPwrdBm; -} - void CARDvSafeResetTx( struct vnt_private *pDevice diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index cb95a0de5bf6..fa1e692ca8a0 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -86,91 +86,16 @@ void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeac bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF); u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval); u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2); -bool CARDbSetTxPower(struct vnt_private *, unsigned long ulTxPower); unsigned char CARDbyGetPktType(struct vnt_private *); void CARDvSafeResetTx(struct vnt_private *); void CARDvSafeResetRx(struct vnt_private *); bool CARDbRadioPowerOff(struct vnt_private *); bool CARDbRadioPowerOn(struct vnt_private *); -bool CARDbIsShortPreamble(struct vnt_private *); -bool CARDbIsShorSlotTime(struct vnt_private *); bool CARDbSetPhyParameter(struct vnt_private *, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs); bool CARDbUpdateTSF(struct vnt_private *, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF); -bool CARDbStopTxPacket(struct vnt_private *, CARD_PKT_TYPE ePktType); -bool CARDbStartTxPacket(struct vnt_private *, CARD_PKT_TYPE ePktType); bool CARDbSetBeaconPeriod(struct vnt_private *, unsigned short wBeaconInterval); -bool CARDbSetBSSID(struct vnt_private *, - unsigned char *pbyBSSID, enum nl80211_iftype); - -bool CARDbPowerDown(struct vnt_private *); - -bool CARDbSetTxDataRate(struct vnt_private *, unsigned short wDataRate); - -bool CARDbRemoveKey(struct vnt_private *, unsigned char *pbyBSSID); - -bool -CARDbAdd_PMKID_Candidate( - struct vnt_private *, - unsigned char *pbyBSSID, - bool bRSNCapExist, - unsigned short wRSNCap -); - -void * -CARDpGetCurrentAddress( - struct vnt_private * -); - -bool -CARDbStartMeasure( - struct vnt_private *, - void *pvMeasureEIDs, - unsigned int uNumOfMeasureEIDs -); - -bool -CARDbChannelSwitch( - struct vnt_private *, - unsigned char byMode, - unsigned char byNewChannel, - unsigned char byCount -); - -bool -CARDbSetQuiet( - struct vnt_private *, - bool bResetQuiet, - unsigned char byQuietCount, - unsigned char byQuietPeriod, - unsigned short wQuietDuration, - unsigned short wQuietOffset -); - -bool -CARDbStartQuiet( - struct vnt_private * -); - -void -CARDvSetPowerConstraint( - struct vnt_private *, - unsigned char byChannel, - char byPower -); - -void -CARDvGetPowerCapability( - struct vnt_private *, - unsigned char *pbyMinPower, - unsigned char *pbyMaxPower -); - -char -CARDbyGetTransmitPower( - struct vnt_private * -); #endif /* __CARD_H__ */ -- GitLab From c49802bfb6f3aadc64360994e6500bd2e2f080b6 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:36 +0000 Subject: [PATCH 2093/9457] staging: vt6655: deadcode remove wroute.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/wroute.c | 177 --------------------------- drivers/staging/vt6655/wroute.h | 45 ------- 5 files changed, 225 deletions(-) delete mode 100644 drivers/staging/vt6655/wroute.c delete mode 100644 drivers/staging/vt6655/wroute.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 141c0c11ee22..e5ea1ea9beab 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -21,7 +21,6 @@ vt6655_stage-y += device_main.o \ key.o \ tkip.o \ michael.o \ - wroute.o \ rf.o \ wpa2.o \ aes_ccmp.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 848c258119a6..18dad0cb69a0 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -66,7 +66,6 @@ #include "iocmd.h" #include "tcrc.h" #include "rxtx.h" -#include "wroute.h" #include "bssdb.h" #include "dpc.h" #include "rf.h" diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index c47042c07aad..6ae859404553 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -59,7 +59,6 @@ #include "tkip.h" #include "tcrc.h" #include "wctl.h" -#include "wroute.h" #include "rf.h" /*--------------------- Static Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c deleted file mode 100644 index 430e9441bc9e..000000000000 --- a/drivers/staging/vt6655/wroute.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wroute.c - * - * Purpose: handle WMAC frame relay & filtering - * - * Author: Lyndon Chen - * - * Date: May 20, 2003 - * - * Functions: - * ROUTEbRelay - Relay packet - * - * Revision History: - * - */ - -#include "mac.h" -#include "tcrc.h" -#include "rxtx.h" -#include "wroute.h" -#include "card.h" -#include "baseband.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * Relay packet. Return true if packet is copy to DMA1 - * - * Parameters: - * In: - * pDevice - - * pbySkbData - rx packet skb data - * Out: - * true, false - * - * Return Value: true if packet duplicate; otherwise false - * - */ -bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, - unsigned int uDataLen, unsigned int uNodeIndex) -{ - PSMgmtObject pMgmt = pDevice->pMgmt; - PSTxDesc pHeadTD, pLastTD; - unsigned int cbFrameBodySize; - unsigned int uMACfragNum = 0; - unsigned char byPktType; - bool bNeedEncryption = false; - SKeyItem STempKey; - PSKeyItem pTransmitKey = NULL; - unsigned int ii; - unsigned char *pbyBSSID; - - if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { - pr_debug("Relay can't allocate TD1..\n"); - return false; - } - - pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; - - pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP); - - memcpy(pDevice->sTxEthHeader.abyDstAddr, pbySkbData, ETH_HLEN); - - cbFrameBodySize = uDataLen - ETH_HLEN; - - if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) - cbFrameBodySize += 8; - - if (pDevice->bEncryptionEnable == true) { - bNeedEncryption = true; - - /* get group key */ - pbyBSSID = pDevice->abyBroadcastAddr; - if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, - GROUP_KEY, &pTransmitKey) == false) { - pTransmitKey = NULL; - pr_debug("KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); - } else { - pr_debug("Get GTK\n"); - } - } - - if (pDevice->bEnableHostWEP) { - if (uNodeIndex < MAX_NODE_NUM + 1) { - pTransmitKey = &STempKey; - pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; - pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; - pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; - pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; - pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; - memcpy(pTransmitKey->abyKey, - &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], - pTransmitKey->uKeyLength); - } - } - - if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) - return false; - - byPktType = pDevice->byPacketType; - - if (pDevice->bFixRate) { - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { - if (pDevice->uConnectionRate >= RATE_11M) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = pDevice->uConnectionRate; - } else { - if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && - (pDevice->uConnectionRate <= RATE_6M)) { - pDevice->wCurrentRate = RATE_6M; - } else { - if (pDevice->uConnectionRate >= RATE_54M) - pDevice->wCurrentRate = RATE_54M; - else - pDevice->wCurrentRate = pDevice->uConnectionRate; - } - } - } else { - pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; - } - - if (pDevice->wCurrentRate <= RATE_11M) - byPktType = PK_TYPE_11B; - - if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { - /* Disable PS */ - MACbPSWakeup(pDevice->PortOffset); - } - - pDevice->bPWBitOn = false; - - pLastTD = pHeadTD; - for (ii = 0; ii < uMACfragNum; ii++) { - /* Poll Transmit the adapter */ - wmb(); - pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; - wmb(); - if (ii == (uMACfragNum - 1)) - pLastTD = pHeadTD; - pHeadTD = pHeadTD->next; - } - - pLastTD->pTDInfo->skb = NULL; - pLastTD->pTDInfo->byFlags = 0; - - pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; - - MACvTransmitAC0(pDevice->PortOffset); - - return true; -} diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h deleted file mode 100644 index e59eec955cac..000000000000 --- a/drivers/staging/vt6655/wroute.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wroute.h - * - * Purpose: - * - * Author: Lyndon Chen - * - * Date: May 21, 2003 - * - */ - -#ifndef __WROUTE_H__ -#define __WROUTE_H__ - -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, - unsigned int uDataLen, unsigned int uNodeIndex); - -#endif /* __WROUTE_H__ */ -- GitLab From 6bedc35b75e99ef66b42b40e23c3eaf3f76cf6d2 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:37 +0000 Subject: [PATCH 2094/9457] staging: vt6655: dead code remove wpa/wpa2 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 13 -- drivers/staging/vt6655/Makefile | 2 - drivers/staging/vt6655/vntwifi.c | 7 - drivers/staging/vt6655/vntwifi.h | 1 - drivers/staging/vt6655/wmgr.h | 2 - drivers/staging/vt6655/wpa.c | 300 ------------------------- drivers/staging/vt6655/wpa.h | 83 ------- drivers/staging/vt6655/wpa2.c | 359 ------------------------------ drivers/staging/vt6655/wpa2.h | 77 ------- 9 files changed, 844 deletions(-) delete mode 100644 drivers/staging/vt6655/wpa.c delete mode 100644 drivers/staging/vt6655/wpa.h delete mode 100644 drivers/staging/vt6655/wpa2.c delete mode 100644 drivers/staging/vt6655/wpa2.h diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index 7d2c6472ec9a..22ded38e6a2e 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -57,7 +57,6 @@ #include "80211mgr.h" #include "80211hdr.h" #include "device.h" -#include "wpa.h" /*--------------------- Static Definitions -------------------------*/ @@ -171,9 +170,6 @@ vMgrDecodeBeacon( break; case WLAN_EID_RSN_WPA: if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; } break; @@ -389,9 +385,6 @@ vMgrDecodeAssocRequest( break; case WLAN_EID_RSN_WPA: if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; } break; case WLAN_EID_EXTSUPP_RATES: @@ -574,9 +567,6 @@ vMgrDecodeReassocRequest( break; case WLAN_EID_RSN_WPA: if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; } break; @@ -767,9 +757,6 @@ vMgrDecodeProbeResponse( break; case WLAN_EID_RSN_WPA: if (pFrame->pRSNWPA == NULL) { - if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true) - pFrame->pRSNWPA = - (PWLAN_IE_RSN_EXT)pItem; } break; case WLAN_EID_ERP: diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index e5ea1ea9beab..7286e328a2a4 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -17,12 +17,10 @@ vt6655_stage-y += device_main.o \ rc4.o \ tether.o \ tcrc.o \ - wpa.o \ key.o \ tkip.o \ michael.o \ rf.o \ - wpa2.o \ aes_ccmp.o \ vntwifi.o diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index a5eccf7cec8b..54c65fca332d 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -557,13 +557,6 @@ VNTWIFIbSetPMKIDCache( void *pPMKIDInfo ) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - if (ulCount > MAX_PMKID_CACHE) - return false; - - pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount; - memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo))); return true; } diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index 880b8ab109be..9db734f00419 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -33,7 +33,6 @@ #include "ttype.h" #include "80211mgr.h" #include "card.h" -#include "wpa2.h" /*--------------------- Export Definitions -------------------------*/ #define RATE_1M 0 diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 4b7196bd1607..7df62bb6eafd 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -39,7 +39,6 @@ #include "80211hdr.h" #include "wcmd.h" #include "bssdb.h" -#include "wpa2.h" #include "vntwifi.h" #include "card.h" @@ -291,7 +290,6 @@ typedef struct tagSMgmtObject { KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1]; // WPA2 PMKID Cache - SPMKIDCache gsPMKIDCache; bool bRoaming; // rate fall back vars diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c deleted file mode 100644 index 5d4eca8512af..000000000000 --- a/drivers/staging/vt6655/wpa.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * WPA_ParseRSN - Parse RSN IE. - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: July 14, 2003 - * - */ - -#include "ttype.h" -#include "tmacro.h" -#include "tether.h" -#include "device.h" -#include "80211hdr.h" -#include "bssdb.h" -#include "wmgr.h" -#include "wpa.h" -#include "80211mgr.h" - -/*--------------------- Static Variables --------------------------*/ -static const unsigned char abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; -static const unsigned char abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; -static const unsigned char abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; -static const unsigned char abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; -static const unsigned char abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; -static const unsigned char abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; - -/*+ - * - * Description: - * Clear RSN information in BSSList. - * - * Parameters: - * In: - * pBSSList - BSS list. - * Out: - * none - * - * Return Value: none. - * - -*/ - -void -WPA_ClearRSN( - PKnownBSS pBSSList -) -{ - int ii; - - pBSSList->byGKType = WPA_TKIP; - for (ii = 0; ii < 4; ii++) - pBSSList->abyPKType[ii] = WPA_TKIP; - pBSSList->wPKCount = 0; - for (ii = 0; ii < 4; ii++) - pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X; - pBSSList->wAuthCount = 0; - pBSSList->byDefaultK_as_PK = 0; - pBSSList->byReplayIdx = 0; - pBSSList->sRSNCapObj.bRSNCapExist = false; - pBSSList->sRSNCapObj.wRSNCap = 0; - pBSSList->bWPAValid = false; -} - -/*+ - * - * Description: - * Parse RSN IE. - * - * Parameters: - * In: - * pBSSList - BSS list. - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA_ParseRSN( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN -) -{ - PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; - int i, j, m, n = 0; - unsigned char *pbyCaps; - - WPA_ClearRSN(pBSSList); - - pr_debug("WPA_ParseRSN: [%d]\n", pRSN->len); - - // information element header makes sense - if ((pRSN->len >= 6) // oui1(4)+ver(2) - && (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) - && (pRSN->wVersion == 1)) { - pr_debug("Legal RSN\n"); - // update each variable if pRSN is long enough to contain the variable - if (pRSN->len >= 10) { - //OUI1(4)+ver(2)+GKSuite(4) - if (!memcmp(pRSN->abyMulticast, abyOUI01, 4)) - pBSSList->byGKType = WPA_WEP40; - else if (!memcmp(pRSN->abyMulticast, abyOUI02, 4)) - pBSSList->byGKType = WPA_TKIP; - else if (!memcmp(pRSN->abyMulticast, abyOUI03, 4)) - pBSSList->byGKType = WPA_AESWRAP; - else if (!memcmp(pRSN->abyMulticast, abyOUI04, 4)) - pBSSList->byGKType = WPA_AESCCMP; - else if (!memcmp(pRSN->abyMulticast, abyOUI05, 4)) - pBSSList->byGKType = WPA_WEP104; - else - // any vendor checks here - pBSSList->byGKType = WPA_NONE; - - pr_debug("byGKType: %x\n", pBSSList->byGKType); - } - - if (pRSN->len >= 12) { - //oui1(4)+ver(2)+GKS(4)+PKSCnt(2) - j = 0; - pr_debug("wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", - pRSN->wPKCount, sizeof(pBSSList->abyPKType)); - for (i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { - if (pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) - if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) - pBSSList->abyPKType[j++] = WPA_NONE; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyPKType[j++] = WPA_TKIP; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4)) - pBSSList->abyPKType[j++] = WPA_AESWRAP; - else if (!memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4)) - pBSSList->abyPKType[j++] = WPA_AESCCMP; - else - // any vendor checks here - ; - } else - break; - } - pBSSList->wPKCount = (unsigned short)j; - pr_debug("wPKCount: %d\n", pBSSList->wPKCount); - } - - m = pRSN->wPKCount; - pr_debug("m: %d\n", m); - pr_debug("14+m*4: %d\n", 14+m*4); - - if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2) - // overlay IE_RSN_Auth structure into correct place - pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI; - j = 0; - pr_debug("wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", - pIE_RSN_Auth->wAuthCount, - sizeof(pBSSList->abyAuthType)); - for (i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { - if (pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) - if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; - else if (!memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4)) - pBSSList->abyAuthType[j++] = WPA_AUTH_PSK; - else - // any vendor checks here - ; - } else - break; - - } - if (j > 0) - pBSSList->wAuthCount = (unsigned short)j; - pr_debug("wAuthCount: %d\n", pBSSList->wAuthCount); - } - - if (pIE_RSN_Auth != NULL) { - n = pIE_RSN_Auth->wAuthCount; - - pr_debug("n: %d\n", n); - pr_debug("14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); - - if (pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2) - pbyCaps = (unsigned char *)pIE_RSN_Auth->AuthKSList[n].abyOUI; - pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG; - pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS); - pBSSList->sRSNCapObj.bRSNCapExist = true; - pBSSList->sRSNCapObj.wRSNCap = *(unsigned short *)pbyCaps; - } - } - pBSSList->bWPAValid = true; - } -} - -/*+ - * - * Description: - * Search RSN information in BSSList. - * - * Parameters: - * In: - * byCmd - Search type - * byEncrypt- Encrypt Type - * pBSSList - BSS list - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -WPA_SearchRSN( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList -) -{ - int ii; - unsigned char byPKType = WPA_NONE; - - if (!pBSSList->bWPAValid) - return false; - - switch (byCmd) { - case 0: - - if (byEncrypt != pBSSList->byGKType) - return false; - - if (pBSSList->wPKCount > 0) { - for (ii = 0; ii < pBSSList->wPKCount; ii++) { - if (pBSSList->abyPKType[ii] == WPA_AESCCMP) - byPKType = WPA_AESCCMP; - else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP)) - byPKType = WPA_TKIP; - else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP40; - else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP)) - byPKType = WPA_WEP104; - } - if (byEncrypt != byPKType) - return false; - } - return true; - - default: - break; - } - return false; -} - -/*+ - * - * Description: - * Check if RSN IE makes sense. - * - * Parameters: - * In: - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -bool -WPAb_Is_RSN( - PWLAN_IE_RSN_EXT pRSN -) -{ - if (pRSN == NULL) - return false; - - if ((pRSN->len >= 6) && // oui1(4)+ver(2) - (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) && - (pRSN->wVersion == 1)) { - return true; - } else - return false; -} diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h deleted file mode 100644 index d012cb97043f..000000000000 --- a/drivers/staging/vt6655/wpa.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with WPA informations. - * - * Author: Kyle Hsu - * - * Date: Jul 14, 2003 - * - */ - -#ifndef __WPA_H__ -#define __WPA_H__ - -#include "ttype.h" -#include "80211hdr.h" - -/*--------------------- Export Definitions -------------------------*/ - -#define WPA_NONE 0 -#define WPA_WEP40 1 -#define WPA_TKIP 2 -#define WPA_AESWRAP 3 -#define WPA_AESCCMP 4 -#define WPA_WEP104 5 -#define WPA_AUTH_IEEE802_1X 1 -#define WPA_AUTH_PSK 2 - -#define WPA_GROUPFLAG 0x02 -#define WPA_REPLAYBITSSHIFT 2 -#define WPA_REPLAYBITS 0x03 - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -WPA_ClearRSN( - PKnownBSS pBSSList -); - -void -WPA_ParseRSN( - PKnownBSS pBSSList, - PWLAN_IE_RSN_EXT pRSN -); - -bool -WPA_SearchRSN( - unsigned char byCmd, - unsigned char byEncrypt, - PKnownBSS pBSSList -); - -bool -WPAb_Is_RSN( - PWLAN_IE_RSN_EXT pRSN -); - -#endif /* __WPA_H__ */ diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c deleted file mode 100644 index bb335ef51172..000000000000 --- a/drivers/staging/vt6655/wpa2.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa2.c - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: Oct. 4, 2004 - * - */ - -#include "wpa2.h" -#include "device.h" -#include "wmgr.h" - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -static const unsigned char abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; -static const unsigned char abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -static const unsigned char abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; -static const unsigned char abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -static const unsigned char abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; - -static const unsigned char abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -static const unsigned char abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Clear RSN information in BSSList. - * - * Parameters: - * In: - * pBSSNode - BSS list. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA2_ClearRSN( - PKnownBSS pBSSNode -) -{ - int ii; - - pBSSNode->bWPA2Valid = false; - - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - for (ii = 0; ii < 4; ii++) - pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP; - pBSSNode->wCSSPKCount = 1; - for (ii = 0; ii < 4; ii++) - pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X; - pBSSNode->wAKMSSAuthCount = 1; - pBSSNode->sRSNCapObj.bRSNCapExist = false; - pBSSNode->sRSNCapObj.wRSNCap = 0; -} - -/*+ - * - * Description: - * Parse RSN IE. - * - * Parameters: - * In: - * pBSSNode - BSS list. - * pRSN - Pointer to the RSN IE. - * Out: - * none - * - * Return Value: none. - * - -*/ -void -WPA2vParseRSN( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN -) -{ - int i, j; - unsigned short m = 0, n = 0; - unsigned char *pbyOUI; - bool bUseGK = false; - - pr_debug("WPA2_ParseRSN: [%d]\n", pRSN->len); - - WPA2_ClearRSN(pBSSNode); - - if (pRSN->len == 2) { // ver(2) - if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) - pBSSNode->bWPA2Valid = true; - - return; - } - - if (pRSN->len < 6) { // ver(2) + GK(4) - // invalid CSS, P802.11i/D10.0, p31 - return; - } - - // information element header makes sense - if ((pRSN->byElementID == WLAN_EID_RSN) && - (pRSN->wVersion == 1)) { - pr_debug("Legal 802.11i RSN\n"); - - pbyOUI = &(pRSN->abyRSN[0]); - if (!memcmp(pbyOUI, abyOUIWEP40, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40; - else if (!memcmp(pbyOUI, abyOUITKIP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP; - else if (!memcmp(pbyOUI, abyOUICCMP, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP; - else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) - pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104; - else if (!memcmp(pbyOUI, abyOUIGK, 4)) { - // invalid CSS, P802.11i/D10.0, p32 - return; - } else - // any vendor checks here - pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN; - - pr_debug("802.11i CSS: %X\n", pBSSNode->byCSSGK); - - if (pRSN->len == 6) { - pBSSNode->bWPA2Valid = true; - return; - } - - if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2) - pBSSNode->wCSSPKCount = *((unsigned short *)&(pRSN->abyRSN[4])); - j = 0; - pbyOUI = &(pRSN->abyRSN[6]); - - for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(unsigned char)); i++) { - if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i) - if (!memcmp(pbyOUI, abyOUIGK, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP; - bUseGK = true; - } else if (!memcmp(pbyOUI, abyOUIWEP40, 4)) { - // Invalid CSS, continue to parsing - } else if (!memcmp(pbyOUI, abyOUITKIP, 4)) { - if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP) - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP; - else - ; // Invalid CSS, continue to parsing - } else if (!memcmp(pbyOUI, abyOUICCMP, 4)) { - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP; - } else if (!memcmp(pbyOUI, abyOUIWEP104, 4)) { - // Invalid CSS, continue to parsing - } else { - // any vendor checks here - pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; - } - pbyOUI += 4; - pr_debug("abyCSSPK[%d]: %X\n", - j-1, pBSSNode->abyCSSPK[j-1]); - } else - break; - } //for - - if (bUseGK) { - if (j != 1) { - // invalid CSS, This should be only PK CSS. - return; - } - if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) { - // invalid CSS, If CCMP is enable , PK can't be CSSGK. - return; - } - } - if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) { - // invalid CSS, No valid PK. - return; - } - pBSSNode->wCSSPKCount = (unsigned short)j; - pr_debug("wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); - } - - m = *((unsigned short *)&(pRSN->abyRSN[4])); - - if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); - j = 0; - pbyOUI = &(pRSN->abyRSN[8+4*m]); - for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) { - if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i) - if (!memcmp(pbyOUI, abyOUI8021X, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X; - else if (!memcmp(pbyOUI, abyOUIPSK, 4)) - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK; - else - // any vendor checks here - pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN; - pr_debug("abyAKMSSAuthType[%d]: %X\n", - j-1, - pBSSNode->abyAKMSSAuthType[j-1]); - } else - break; - } - pBSSNode->wAKMSSAuthCount = (unsigned short)j; - pr_debug("wAKMSSAuthCount: %d\n", - pBSSNode->wAKMSSAuthCount); - - n = *((unsigned short *)&(pRSN->abyRSN[6+4*m])); - if (pRSN->len >= 12 + 4 * m + 4 * n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) - pBSSNode->sRSNCapObj.bRSNCapExist = true; - pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *)&(pRSN->abyRSN[8+4*m+4*n])); - } - } - //ignore PMKID lists bcs only (Re)Assocrequest has this field - pBSSNode->bWPA2Valid = true; - } -} - -/*+ - * - * Description: - * Set WPA IEs - * - * Parameters: - * In: - * pMgmtHandle - Pointer to management object - * Out: - * pRSNIEs - Pointer to the RSN IE to set. - * - * Return Value: length of IEs. - * - -*/ -unsigned int -WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - unsigned char *pbyBuffer = NULL; - unsigned int ii = 0; - unsigned short *pwPMKID = NULL; - - if (pRSNIEs == NULL) - return 0; - - if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && - (pMgmt->pCurrBSS != NULL)) { - /* WPA2 IE */ - pbyBuffer = (unsigned char *)pRSNIEs; - pRSNIEs->byElementID = WLAN_EID_RSN; - pRSNIEs->len = 6; //Version(2)+GK(4) - pRSNIEs->wVersion = 1; - //Group Key Cipher Suite - pRSNIEs->abyRSN[0] = 0x00; - pRSNIEs->abyRSN[1] = 0x0F; - pRSNIEs->abyRSN[2] = 0xAC; - if (pMgmt->byCSSGK == KEY_CTL_WEP) - pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK; - else if (pMgmt->byCSSGK == KEY_CTL_TKIP) - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSGK == KEY_CTL_CCMP) - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP; - else - pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN; - - // Pairwise Key Cipher Suite - pRSNIEs->abyRSN[4] = 1; - pRSNIEs->abyRSN[5] = 0; - pRSNIEs->abyRSN[6] = 0x00; - pRSNIEs->abyRSN[7] = 0x0F; - pRSNIEs->abyRSN[8] = 0xAC; - if (pMgmt->byCSSPK == KEY_CTL_TKIP) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP; - else if (pMgmt->byCSSPK == KEY_CTL_CCMP) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP; - else if (pMgmt->byCSSPK == KEY_CTL_NONE) - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP; - else - pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN; - - pRSNIEs->len += 6; - - // Auth Key Management Suite - pRSNIEs->abyRSN[10] = 1; - pRSNIEs->abyRSN[11] = 0; - pRSNIEs->abyRSN[12] = 0x00; - pRSNIEs->abyRSN[13] = 0x0F; - pRSNIEs->abyRSN[14] = 0xAC; - if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK; - else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X; - else - pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN; - - pRSNIEs->len += 6; - - // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { - memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); - } else { - pRSNIEs->abyRSN[16] = 0; - pRSNIEs->abyRSN[17] = 0; - } - pRSNIEs->len += 2; - - if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && - pMgmt->bRoaming && - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]); // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list - for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { - if (!memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { - (*pwPMKID)++; - memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); - pbyBuffer += 16; - } - } - if (*pwPMKID != 0) - pRSNIEs->len += (2 + (*pwPMKID)*16); - else - pbyBuffer = &pRSNIEs->abyRSN[18]; - } - return pRSNIEs->len + WLAN_IEHDR_LEN; - } - return 0; -} diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h deleted file mode 100644 index 2d0bd2e515f3..000000000000 --- a/drivers/staging/vt6655/wpa2.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wpa2.h - * - * Purpose: Defines the macros, types, and functions for dealing - * with WPA2 informations. - * - * Author: Yiching Chen - * - * Date: Oct. 4, 2004 - * - */ - -#ifndef __WPA2_H__ -#define __WPA2_H__ - -#include "ttype.h" -#include "80211mgr.h" -#include "80211hdr.h" -#include "bssdb.h" - -/*--------------------- Export Definitions -------------------------*/ -#define MAX_PMKID_CACHE 16 - -typedef struct tagsPMKIDInfo { - unsigned char abyBSSID[6]; - unsigned char abyPMKID[16]; -} PMKIDInfo, *PPMKIDInfo; - -typedef struct tagSPMKIDCache { - unsigned long BSSIDInfoCount; - PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; -} SPMKIDCache, *PSPMKIDCache; - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -WPA2_ClearRSN( - PKnownBSS pBSSNode -); - -void -WPA2vParseRSN( - PKnownBSS pBSSNode, - PWLAN_IE_RSN pRSN -); - -unsigned int -WPA2uSetIEs( - void *pMgmtHandle, - PWLAN_IE_RSN pRSNIEs -); - -#endif // __WPA2_H__ -- GitLab From 7c23c2d25df818805e6754cd196076a52d84af39 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:38 +0000 Subject: [PATCH 2095/9457] staging: vt6655: deadcode remove aes_ccmp/rc4/tkip Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 3 - drivers/staging/vt6655/aes_ccmp.c | 374 ------------------------------ drivers/staging/vt6655/aes_ccmp.h | 37 --- drivers/staging/vt6655/device.h | 2 - drivers/staging/vt6655/rc4.c | 88 ------- drivers/staging/vt6655/rc4.h | 47 ---- drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/tkip.c | 268 --------------------- drivers/staging/vt6655/tkip.h | 57 ----- 9 files changed, 877 deletions(-) delete mode 100644 drivers/staging/vt6655/aes_ccmp.c delete mode 100644 drivers/staging/vt6655/aes_ccmp.h delete mode 100644 drivers/staging/vt6655/rc4.c delete mode 100644 drivers/staging/vt6655/rc4.h delete mode 100644 drivers/staging/vt6655/tkip.c delete mode 100644 drivers/staging/vt6655/tkip.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 7286e328a2a4..f49f12bc8b17 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -14,14 +14,11 @@ vt6655_stage-y += device_main.o \ power.o \ srom.o \ mib.o \ - rc4.o \ tether.o \ tcrc.o \ key.o \ - tkip.o \ michael.o \ rf.o \ - aes_ccmp.o \ vntwifi.o obj-$(CONFIG_VT6655) += vt6655_stage.o diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c deleted file mode 100644 index 1dfcfcb3c69c..000000000000 --- a/drivers/staging/vt6655/aes_ccmp.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: aes_ccmp.c - * - * Purpose: AES_CCMP decryption - * - * Author: Warren Hsu - * - * Date: Feb 15, 2005 - * - * Functions: - * AESbGenCCMP - Parsing RX-packet - * - * - * Revision History: - * - */ - -#include "device.h" -#include "80211hdr.h" -#include "aes_ccmp.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* - * SBOX Table - */ - -static unsigned char sbox_table[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -static unsigned char dot2_table[256] = { - 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, - 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, - 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, - 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, - 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, - 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, - 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, - 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, - 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, - 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, - 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, - 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, - 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, - 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, - 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 -}; - -static unsigned char dot3_table[256] = { - 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, - 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, - 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, - 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, - 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, - 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, - 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, - 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, - 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, - 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, - 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, - 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, - 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, - 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, - 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, - 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a -}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) -{ - unsigned long *dwPtrA = (unsigned long *)a; - unsigned long *dwPtrB = (unsigned long *)b; - unsigned long *dwPtrOut = (unsigned long *)out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); -} - -static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out) -{ - unsigned long *dwPtrA = (unsigned long *)a; - unsigned long *dwPtrB = (unsigned long *)b; - unsigned long *dwPtrOut = (unsigned long *)out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); -} - -static void AddRoundKey(unsigned char *key, int round) -{ - unsigned char sbox_key[4]; - unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - - sbox_key[0] = sbox_table[key[13]]; - sbox_key[1] = sbox_table[key[14]]; - sbox_key[2] = sbox_table[key[15]]; - sbox_key[3] = sbox_table[key[12]]; - - key[0] = key[0] ^ rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); - - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -static void SubBytes(unsigned char *in, unsigned char *out) -{ - int i; - - for (i = 0; i < 16; i++) - out[i] = sbox_table[in[i]]; -} - -static void ShiftRows(unsigned char *in, unsigned char *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -static void MixColumns(unsigned char *in, unsigned char *out) -{ - out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; - out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; - out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; - out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; -} - -static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext) -{ - int i; - int round; - unsigned char TmpdataA[16]; - unsigned char TmpdataB[16]; - unsigned char abyRoundKey[16]; - - for (i = 0; i < 16; i++) - abyRoundKey[i] = key[i]; - - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(abyRoundKey, data, ciphertext); - AddRoundKey(abyRoundKey, round); - } else if (round == 10) { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - xor_128(TmpdataB, abyRoundKey, ciphertext); - } else /* round 1 ~ 9 */{ - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - MixColumns(&TmpdataB[0], &TmpdataA[0]); - MixColumns(&TmpdataB[4], &TmpdataA[4]); - MixColumns(&TmpdataB[8], &TmpdataA[8]); - MixColumns(&TmpdataB[12], &TmpdataA[12]); - xor_128(TmpdataA, abyRoundKey, ciphertext); - AddRoundKey(abyRoundKey, round); - } - } -} - -/* - * Description: AES decryption - * - * Parameters: - * In: - * pbyRxKey - The key used to decrypt - * pbyFrame - Starting address of packet header - * wFrameSize - Total packet size including CRC - * Out: - * none - * - * Return Value: MIC compare result - * - */ -bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize) -{ - unsigned char abyNonce[13]; - unsigned char MIC_IV[16]; - unsigned char MIC_HDR1[16]; - unsigned char MIC_HDR2[16]; - unsigned char abyMIC[16]; - unsigned char abyCTRPLD[16]; - unsigned char abyTmp[16]; - unsigned char abyPlainText[16]; - unsigned char abyLastCipher[16]; - - PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; - unsigned char *pbyIV; - unsigned char *pbyPayload; - unsigned short wHLen = 22; - unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;/* 8 is IV, 8 is MIC, 4 is CRC */ - bool bA4 = false; - unsigned char byTmp; - unsigned short wCnt; - int ii, jj, kk; - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && - WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { - bA4 = true; - pbyIV += 6; /* 6 is 802.11 address4 */ - wHLen += 6; - wPayloadSize -= 6; - } - pbyPayload = pbyIV + 8; /* IV-length */ - - abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */ - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); - abyNonce[7] = pbyIV[7]; - abyNonce[8] = pbyIV[6]; - abyNonce[9] = pbyIV[5]; - abyNonce[10] = pbyIV[4]; - abyNonce[11] = pbyIV[1]; - abyNonce[12] = pbyIV[0]; - - /* MIC_IV */ - MIC_IV[0] = 0x59; - memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); - MIC_IV[14] = (unsigned char)(wPayloadSize >> 8); - MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff); - - /* MIC_HDR1 */ - MIC_HDR1[0] = (unsigned char)(wHLen >> 8); - MIC_HDR1[1] = (unsigned char)(wHLen & 0xff); - byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff); - MIC_HDR1[2] = byTmp & 0x8f; - byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8); - byTmp &= 0x87; - MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); - - /* MIC_HDR2 */ - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); - byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff); - MIC_HDR2[6] = byTmp & 0x0f; - MIC_HDR2[7] = 0; - if (bA4) { - memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); - } else { - MIC_HDR2[8] = 0x00; - MIC_HDR2[9] = 0x00; - MIC_HDR2[10] = 0x00; - MIC_HDR2[11] = 0x00; - MIC_HDR2[12] = 0x00; - MIC_HDR2[13] = 0x00; - } - MIC_HDR2[14] = 0x00; - MIC_HDR2[15] = 0x00; - - /* CCMP */ - AESv128(pbyRxKey, MIC_IV, abyMIC); - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - wCnt = 1; - abyCTRPLD[0] = 0x01; - memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); - - for (jj = wPayloadSize; jj > 16; jj = jj - 16) { - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - - for (kk = 0; kk < 16; kk++) - abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - memcpy(pbyPayload, abyPlainText, 16); - wCnt++; - pbyPayload += 16; - } /* for wPayloadSize */ - - /* last payload */ - memcpy(&(abyLastCipher[0]), pbyPayload, jj); - for (ii = jj; ii < 16; ii++) - abyLastCipher[ii] = 0x00; - - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - for (kk = 0; kk < 16; kk++) - abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; - memcpy(pbyPayload, abyPlainText, jj); - pbyPayload += jj; - - /* for MIC calculation */ - for (ii = jj; ii < 16; ii++) - abyPlainText[ii] = 0x00; - for (kk = 0; kk < 16; kk++) - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - AESv128(pbyRxKey, abyTmp, abyMIC); - - /* =>above is the calculate MIC */ - /* -------------------------------------------- */ - - wCnt = 0; - abyCTRPLD[14] = (unsigned char)(wCnt >> 8); - abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); - AESv128(pbyRxKey, abyCTRPLD, abyTmp); - for (kk = 0; kk < 8; kk++) - abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; - /* =>above is the dec-MIC from packet */ - /* -------------------------------------------- */ - - return !memcmp(abyMIC, abyTmp, 8); -} diff --git a/drivers/staging/vt6655/aes_ccmp.h b/drivers/staging/vt6655/aes_ccmp.h deleted file mode 100644 index fe0c506205d5..000000000000 --- a/drivers/staging/vt6655/aes_ccmp.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: aes_ccmp.h - * - * Purpose: AES_CCMP Decryption - * - * Author: Warren Hsu - * - * Date: Feb 15, 2005 - * - */ - -#ifndef __AES_H__ -#define __AES_H__ - -#include "ttype.h" - -bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize); - -#endif /* __AES_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 6729d237a6ae..4bea23799233 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -74,7 +74,6 @@ #include "wcmd.h" #include "mib.h" #include "srom.h" -#include "rc4.h" #include "desc.h" #include "key.h" #include "mac.h" @@ -546,7 +545,6 @@ struct vnt_private { u64 qwPacketNumber; /* For CCMP and TKIP as TSC(6 bytes) */ unsigned int uCurrentWEPMode; - RC4Ext SBox; unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3]; unsigned char byKeyIndex; unsigned int uKeyLength; diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c deleted file mode 100644 index b7819bc702de..000000000000 --- a/drivers/staging/vt6655/rc4.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: rc4.c - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - */ - -#include "rc4.h" - -void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len) -{ - unsigned int ust1, ust2; - unsigned int keyindex; - unsigned int stateindex; - unsigned char *pbyst; - unsigned int idx; - - pbyst = pRC4->abystate; - pRC4->ux = 0; - pRC4->uy = 0; - for (idx = 0; idx < 256; idx++) - pbyst[idx] = (unsigned char)idx; - keyindex = 0; - stateindex = 0; - for (idx = 0; idx < 256; idx++) { - ust1 = pbyst[idx]; - stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; - ust2 = pbyst[stateindex]; - pbyst[stateindex] = (unsigned char)ust1; - pbyst[idx] = (unsigned char)ust2; - if (++keyindex >= cbKey_len) - keyindex = 0; - } -} - -unsigned int rc4_byte(PRC4Ext pRC4) -{ - unsigned int ux; - unsigned int uy; - unsigned int ustx, usty; - unsigned char *pbyst; - - pbyst = pRC4->abystate; - ux = (pRC4->ux + 1) & 0xff; - ustx = pbyst[ux]; - uy = (ustx + pRC4->uy) & 0xff; - usty = pbyst[uy]; - pRC4->ux = ux; - pRC4->uy = uy; - pbyst[uy] = (unsigned char)ustx; - pbyst[ux] = (unsigned char)usty; - - return pbyst[(ustx + usty) & 0xff]; -} - -void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, - unsigned char *pbySrc, unsigned int cbData_len) -{ - unsigned int ii; - - for (ii = 0; ii < cbData_len; ii++) - pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4)); -} diff --git a/drivers/staging/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h deleted file mode 100644 index 74b2eed9bce3..000000000000 --- a/drivers/staging/vt6655/rc4.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * File: rc4.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Purpose: - * - * Functions: - * - * Revision History: - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - */ - -#ifndef __RC4_H__ -#define __RC4_H__ - -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ -/*--------------------- Export Types ------------------------------*/ -typedef struct { - unsigned int ux; - unsigned int uy; - unsigned char abystate[256]; -} RC4Ext, *PRC4Ext; - -void rc4_init(PRC4Ext pRC4, unsigned char *pbyKey, unsigned int cbKey_len); -unsigned int rc4_byte(PRC4Ext pRC4); -void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest, unsigned char *pbySrc, unsigned int cbData_len); - -#endif //__RC4_H__ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 6ae859404553..5ece2db9a2d4 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -56,7 +56,6 @@ #include "mac.h" #include "baseband.h" #include "michael.h" -#include "tkip.h" #include "tcrc.h" #include "wctl.h" #include "rf.h" diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c deleted file mode 100644 index f758d021c60e..000000000000 --- a/drivers/staging/vt6655/tkip.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tkip.c - * - * Purpose: Implement functions for 802.11i TKIP - * - * Author: Jerry Chen - * - * Date: Mar. 11, 2003 - * - * Functions: - * TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "tkip.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */ -/* The 2nd table is the same as the 1st but with the upper and lower */ -/* bytes swapped. To allow an endian tolerant implementation, the byte */ -/* halves have been expressed independently here. */ -static const unsigned char TKIP_Sbox_Lower[256] = { - 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54, - 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A, - 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B, - 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B, - 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F, - 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F, - 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5, - 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F, - 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB, - 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97, - 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED, - 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A, - 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94, - 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3, - 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04, - 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D, - 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39, - 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95, - 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83, - 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76, - 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4, - 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B, - 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0, - 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18, - 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51, - 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85, - 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12, - 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9, - 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7, - 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A, - 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8, - 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A -}; - -static const unsigned char TKIP_Sbox_Upper[256] = { - 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91, - 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC, - 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB, - 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B, - 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83, - 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A, - 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F, - 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA, - 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B, - 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13, - 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6, - 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85, - 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11, - 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B, - 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1, - 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF, - 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E, - 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6, - 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B, - 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD, - 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8, - 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2, - 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49, - 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10, - 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97, - 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F, - 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C, - 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27, - 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33, - 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5, - 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0, - 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C -}; - -//STKIPKeyManagement sTKIPKeyTable[MAX_TKIP_KEY]; - -/*--------------------- Static Functions --------------------------*/ -unsigned int tkip_sbox(unsigned int index); -unsigned int rotr1(unsigned int a); - -/*--------------------- Export Variables --------------------------*/ - -/************************************************************/ -/* tkip_sbox() */ -/* Returns a 16 bit value from a 64K entry table. The Table */ -/* is synthesized from two 256 entry byte wide tables. */ -/************************************************************/ -unsigned int tkip_sbox(unsigned int index) -{ - unsigned int index_low; - unsigned int index_high; - unsigned int left, right; - - index_low = (index % 256); - index_high = ((index >> 8) % 256); - - left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256); - right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256); - - return left ^ right; -}; - -unsigned int rotr1(unsigned int a) -{ - unsigned int b; - - if ((a & 0x01) == 0x01) - b = (a >> 1) | 0x8000; - else - b = (a >> 1) & 0x7fff; - - b = b % 65536; - return b; -} - -/* - * Description: Calculate RC4Key fom TK, TA, and TSC - * - * Parameters: - * In: - * pbyTKey - TKey - * pbyTA - TA - * dwTSC - TSC - * Out: - * pbyRC4Key - RC4Key - * - * Return Value: none - * - */ -void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key -) -{ - unsigned int p1k[5]; - unsigned int tsc0, tsc1, tsc2; - unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; - unsigned long int pnl, pnh; - - int i, j; - - pnl = wTSC15_0; - pnh = dwTSC47_16; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256)); - p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256)); - p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256)); - - /* Phase 1, step 2 */ - for (i = 0; i < 8; i++) { - j = 2 * (i & 1); - p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536; - p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536; - p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536; - p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536; - p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536; - p1k[4] = (p1k[4] + i) % 65536; - } - /* Phase 2, Step 1 */ - ppk0 = p1k[0]; - ppk1 = p1k[1]; - ppk2 = p1k[2]; - ppk3 = p1k[3]; - ppk4 = p1k[4]; - ppk5 = (p1k[4] + tsc2) % 65536; - - /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); - ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); - ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); - ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); - ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); - ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); - - /* Phase 2, Step 3 */ - pbyRC4Key[0] = (tsc2 >> 8) % 256; - pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; - pbyRC4Key[2] = tsc2 % 256; - pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256; - - pbyRC4Key[4] = ppk0 % 256; - pbyRC4Key[5] = (ppk0 >> 8) % 256; - - pbyRC4Key[6] = ppk1 % 256; - pbyRC4Key[7] = (ppk1 >> 8) % 256; - - pbyRC4Key[8] = ppk2 % 256; - pbyRC4Key[9] = (ppk2 >> 8) % 256; - - pbyRC4Key[10] = ppk3 % 256; - pbyRC4Key[11] = (ppk3 >> 8) % 256; - - pbyRC4Key[12] = ppk4 % 256; - pbyRC4Key[13] = (ppk4 >> 8) % 256; - - pbyRC4Key[14] = ppk5 % 256; - pbyRC4Key[15] = (ppk5 >> 8) % 256; -} diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h deleted file mode 100644 index 3b6357ac6dee..000000000000 --- a/drivers/staging/vt6655/tkip.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tkip.h - * - * Purpose: Implement functions for 802.11i TKIP - * - * Author: Jerry Chen - * - * Date: Mar. 11, 2003 - * - */ - -#ifndef __TKIP_H__ -#define __TKIP_H__ - -#include "ttype.h" -#include "tether.h" - -/*--------------------- Export Definitions -------------------------*/ -#define TKIP_KEY_LEN 16 - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void TKIPvMixKey( - unsigned char *pbyTKey, - unsigned char *pbyTA, - unsigned short wTSC15_0, - unsigned long dwTSC47_16, - unsigned char *pbyRC4Key -); - -#endif // __TKIP_H__ -- GitLab From e813580c36dc52c61a30dd2f71498fa1033df111 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:39 +0000 Subject: [PATCH 2096/9457] staging: vt6655: dead code remove michael.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/michael.c | 148 ------------------------------- drivers/staging/vt6655/michael.h | 52 ----------- drivers/staging/vt6655/rxtx.c | 1 - 4 files changed, 202 deletions(-) delete mode 100644 drivers/staging/vt6655/michael.c delete mode 100644 drivers/staging/vt6655/michael.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index f49f12bc8b17..5449cedefdba 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -17,7 +17,6 @@ vt6655_stage-y += device_main.o \ tether.o \ tcrc.o \ key.o \ - michael.o \ rf.o \ vntwifi.o diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c deleted file mode 100644 index edee48777aac..000000000000 --- a/drivers/staging/vt6655/michael.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: michael.cpp - * - * Purpose: The implementation of LIST data structure. - * - * Author: Kyle Hsu - * - * Date: Sep 4, 2002 - * - * Functions: - * s_dwGetUINT32 - Convert from unsigned char [] to unsigned long in a portable way - * s_vPutUINT32 - Convert from unsigned long to unsigned char [] in a portable way - * s_vClear - Reset the state to the empty message. - * s_vSetKey - Set the key. - * MIC_vInit - Set the key. - * s_vAppendByte - Append the byte to our word-sized buffer. - * MIC_vAppend - call s_vAppendByte. - * MIC_vGetMIC - Append the minimum padding and call s_vAppendByte. - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "michael.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -static void s_vClear(void); // Clear the internal message, -// resets the object to the state just after construction. -static void s_vSetKey(u32 dwK0, u32 dwK1); -static void s_vAppendByte(unsigned char b); // Add a single byte to the internal message - -/*--------------------- Export Variables --------------------------*/ -static u32 L, R; /* Current state */ - -static u32 K0, K1; /* Key */ -static u32 M; /* Message accumulator (single word) */ -static unsigned int nBytesInM; // # bytes in M - -/*--------------------- Export Functions --------------------------*/ - -static void s_vClear(void) -{ - // Reset the state to the empty message. - L = K0; - R = K1; - nBytesInM = 0; - M = 0; -} - -static void s_vSetKey(u32 dwK0, u32 dwK1) -{ - // Set the key - K0 = dwK0; - K1 = dwK1; - // and reset the message - s_vClear(); -} - -static void s_vAppendByte(unsigned char b) -{ - // Append the byte to our word-sized buffer - M |= b << (8*nBytesInM); - nBytesInM++; - // Process the word if it is full. - if (nBytesInM >= 4) { - L ^= M; - R ^= ROL32(L, 17); - L += R; - R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); - L += R; - R ^= ROL32(L, 3); - L += R; - R ^= ROR32(L, 2); - L += R; - // Clear the buffer - M = 0; - nBytesInM = 0; - } -} - -void MIC_vInit(u32 dwK0, u32 dwK1) -{ - // Set the key - s_vSetKey(dwK0, dwK1); -} - -void MIC_vUnInit(void) -{ - // Wipe the key material - K0 = 0; - K1 = 0; - - // And the other fields as well. - //Note that this sets (L,R) to (K0,K1) which is just fine. - s_vClear(); -} - -void MIC_vAppend(unsigned char *src, unsigned int nBytes) -{ - // This is simple - while (nBytes > 0) { - s_vAppendByte(*src++); - nBytes--; - } -} - -void MIC_vGetMIC(u32 *pdwL, u32 *pdwR) -{ - // Append the minimum padding - s_vAppendByte(0x5a); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - // and then zeroes until the length is a multiple of 4 - while (nBytesInM != 0) - s_vAppendByte(0); - - // The s_vAppendByte function has already computed the result. - *pdwL = L; - *pdwR = R; - // Reset to the empty message. - s_vClear(); -} diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h deleted file mode 100644 index 86cb140e3087..000000000000 --- a/drivers/staging/vt6655/michael.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: Michael.h - * - * Purpose: Reference implementation for Michael - * written by Niels Ferguson - * - * Author: Kyle Hsu - * - * Date: Jan 2, 2003 - * - */ - -#ifndef __MICHAEL_H__ -#define __MICHAEL_H__ - -#include - -void MIC_vInit(u32 dwK0, u32 dwK1); - -void MIC_vUnInit(void); - -/* Append bytes to the message to be MICed */ -void MIC_vAppend(unsigned char *src, unsigned int nBytes); - -/* Get the MIC result. Destination should accept 8 bytes of result. */ -/* This also resets the message to empty. */ -void MIC_vGetMIC(u32 *pdwL, u32 *pdwR); - -/* Rotation functions on 32 bit values */ -#define ROL32(A, n) \ - (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1))) -#define ROR32(A, n) ROL32((A), 32-(n)) - -#endif /*__MICHAEL_H__ */ diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 5ece2db9a2d4..4770b9cf622b 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -55,7 +55,6 @@ #include "bssdb.h" #include "mac.h" #include "baseband.h" -#include "michael.h" #include "tcrc.h" #include "wctl.h" #include "rf.h" -- GitLab From 610cc9d98b4335c7211207bd6c5c2254fcf43688 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:40 +0000 Subject: [PATCH 2097/9457] staging: vt6655: dead code remove vntwifi.c functions Header will be removed later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 3 +- drivers/staging/vt6655/vntwifi.c | 658 ------------------------------- drivers/staging/vt6655/vntwifi.h | 168 -------- 3 files changed, 1 insertion(+), 828 deletions(-) delete mode 100644 drivers/staging/vt6655/vntwifi.c diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 5449cedefdba..d571e6f46ade 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -17,7 +17,6 @@ vt6655_stage-y += device_main.o \ tether.o \ tcrc.o \ key.o \ - rf.o \ - vntwifi.o + rf.o obj-$(CONFIG_VT6655) += vt6655_stage.o diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c deleted file mode 100644 index 54c65fca332d..000000000000 --- a/drivers/staging/vt6655/vntwifi.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: vntwifi.c - * - * Purpose: export functions for vntwifi lib - * - * Functions: - * - * Revision History: - * - * Author: Yiching Chen - * - * Date: feb. 2, 2005 - * - */ - -#include "vntwifi.h" -#include "country.h" -#include "device.h" -#include "wmgr.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Description: - * Set Operation Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eOPMode - Operation Mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetOPMode( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eConfigMode = eOPMode; -} - -/*+ - * - * Description: - * Set Operation Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * wBeaconPeriod - Beacon Period - * wATIMWindow - ATIM window - * uChannel - channel number - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetIBSSParameter( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->wIBSSBeaconPeriod = wBeaconPeriod; - pMgmt->wIBSSATIMWindow = wATIMWindow; - pMgmt->uIBSSChannel = uChannel; -} - -/*+ - * - * Description: - * Get current SSID - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current SSID pointer. - * - -*/ -PWLAN_IE_SSID -VNTWIFIpGetCurrentSSID( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - return (PWLAN_IE_SSID) pMgmt->abyCurrSSID; -} - -/*+ - * - * Description: - * Get current link channel - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current Channel. - * - -*/ -unsigned int -VNTWIFIpGetCurrentChannel( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if (pMgmtHandle != NULL) - return pMgmt->uCurrChannel; - - return 0; -} - -/*+ - * - * Description: - * Get current Assoc ID - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * Out: - * none - * - * Return Value: current Assoc ID - * - -*/ -unsigned short -VNTWIFIwGetAssocID( - void *pMgmtHandle -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - return pMgmt->wCurrAID; -} - -/*+ - * - * Description: - * This routine return max support rate of IES - * - * Parameters: - * In: - * pSupportRateIEs - * pExtSupportRateIEs - * - * Out: - * - * Return Value: max support rate - * - -*/ -unsigned char -VNTWIFIbyGetMaxSupportRate( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -) -{ - unsigned char byMaxSupportRate = RATE_1M; - unsigned char bySupportRate = RATE_1M; - unsigned int ii = 0; - - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - if (bySupportRate > byMaxSupportRate) - byMaxSupportRate = bySupportRate; - - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - if (bySupportRate > byMaxSupportRate) - byMaxSupportRate = bySupportRate; - - } - } - - return byMaxSupportRate; -} - -/*+ - * - * Description: - * This routine return data rate of ACK packtet - * - * Parameters: - * In: - * byRxDataRate - * pSupportRateIEs - * pExtSupportRateIEs - * - * Out: - * - * Return Value: max support rate - * - -*/ -unsigned char -VNTWIFIbyGetACKTxRate( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -) -{ - unsigned char byMaxAckRate; - unsigned int ii; - - if (byRxDataRate <= RATE_11M) { - byMaxAckRate = RATE_1M; - } else { - /* 24M is mandatory for 802.11a and 802.11g */ - byMaxAckRate = RATE_24M; - } - if (pSupportRateIEs) { - for (ii = 0; ii < pSupportRateIEs->len; ii++) { - if (pSupportRateIEs->abyRates[ii] & 0x80) { - } - } - } - if (pExtSupportRateIEs) { - for (ii = 0; ii < pExtSupportRateIEs->len; ii++) { - if (pExtSupportRateIEs->abyRates[ii] & 0x80) { - } - } - } - - return byMaxAckRate; -} - -/*+ - * - * Description: - * Set Authentication Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eAuthMode - Authentication mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetAuthenticationMode( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eAuthenMode = eAuthMode; - if ((eAuthMode == WMAC_AUTH_SHAREKEY) || - (eAuthMode == WMAC_AUTH_AUTO)) { - pMgmt->bShareKeyAlgorithm = true; - } else { - pMgmt->bShareKeyAlgorithm = false; - } -} - -/*+ - * - * Description: - * Set Encryption Mode - * - * Parameters: - * In: - * pMgmtHandle - pointer to management object - * eAuthMode - Authentication mode - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvSetEncryptionMode( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - pMgmt->eEncryptionMode = eEncryptionMode; - if ((eEncryptionMode == WMAC_ENCRYPTION_WEPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_TKIPEnabled) || - (eEncryptionMode == WMAC_ENCRYPTION_AESEnabled)) { - pMgmt->bPrivacyInvoked = true; - } else { - pMgmt->bPrivacyInvoked = false; - } -} - -bool -VNTWIFIbConfigPhyMode( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if ((ePhyType != PHY_TYPE_AUTO) && - (ePhyType != pMgmt->eCurrentPHYMode)) { - if (CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, 0, 0, NULL, NULL) == true) - pMgmt->eCurrentPHYMode = ePhyType; - else - return false; - } - pMgmt->eConfigPHYMode = ePhyType; - return true; -} - -void -VNTWIFIbGetConfigPhyMode( - void *pMgmtHandle, - void *pePhyType -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if ((pMgmt != NULL) && (pePhyType != NULL)) - *(PCARD_PHY_TYPE)pePhyType = pMgmt->eConfigPHYMode; -} - -/*+ - * - * Description: - * Clear BSS List Database except current assoc BSS - * - * Parameters: - * In: - * pMgmtHandle - Management Object structure - * bLinkPass - Current Link status - * Out: - * - * Return Value: None. - * - -*/ - -/*+ - * - * Description: - * Query BSS List in management database - * - * Parameters: - * In: - * pMgmtHandle - Management Object structure - * Out: - * puBSSCount - BSS count - * pvFirstBSS - pointer to first BSS - * - * Return Value: None. - * - -*/ - -void -VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, void **pvFirstBSS) -{ - unsigned int ii = 0; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - PKnownBSS pBSS = NULL; - unsigned int uCount = 0; - - *pvFirstBSS = NULL; - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - - if (*pvFirstBSS == NULL) - *pvFirstBSS = &(pMgmt->sBSSList[ii]); - - uCount++; - } - *puBSSCount = uCount; -} - -void -VNTWIFIvGetNextBSS( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS -) -{ - PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - *pvNextBSS = NULL; - - while (*pvNextBSS == NULL) { - pBSS++; - if (pBSS > &(pMgmt->sBSSList[MAX_BSS_NUM])) - return; - - if (pBSS->bActive == true) { - *pvNextBSS = pBSS; - return; - } - } -} - -/*+ - * - * Description: - * Update Tx attemps, Tx failure counter in Node DB - * - * In: - * Out: - * none - * - * Return Value: none - * - -*/ -void -VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned int uNodeIndex = 0; - unsigned int ii; - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - } - - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; - if (bTxOk) { - /* transmit success, TxAttempts at least plus one */ - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; - pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; - } else { - pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; - } - pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; - for (ii = 0; ii < MAX_RATE; ii++) - pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; -} - -void -VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - unsigned short wTxDataRate = RATE_1M; - unsigned char byACKRate = RATE_1M; - unsigned char byCCKBasicRate = RATE_1M; - unsigned char byOFDMBasicRate = RATE_24M; - PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL; - PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL; - - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || - (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - /* Adhoc Tx rate decided from node DB */ - } else { /* Infrastructure: rate decided from AP Node, index = 0 */ - - wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate); - - pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; - pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; - } - byACKRate = VNTWIFIbyGetACKTxRate((unsigned char) wTxDataRate, - pSupportRateIEs, - pExtSupportRateIEs -); - if (byACKRate > (unsigned char) wTxDataRate) - byACKRate = (unsigned char) wTxDataRate; - - byCCKBasicRate = VNTWIFIbyGetACKTxRate(RATE_11M, - pSupportRateIEs, - pExtSupportRateIEs -); - byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M, - pSupportRateIEs, - pExtSupportRateIEs -); - *pwTxDataRate = wTxDataRate; - *pbyACKRate = byACKRate; - *pbyCCKBasicRate = byCCKBasicRate; - *pbyOFDMBasicRate = byOFDMBasicRate; -} - -unsigned char -VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey -) -{ - PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - - if (bGroupKey) - return pMgmt->byCSSGK; - return pMgmt->byCSSPK; -} - -bool -VNTWIFIbSetPMKIDCache( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo -) -{ - return true; -} - -unsigned short -VNTWIFIwGetMaxSupportRate( - void *pMgmtObject -) -{ - unsigned short wRate = RATE_54M; - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - for (wRate = RATE_54M; wRate > RATE_1M; wRate--) { - if (pMgmt->sNodeDBTable[0].wSuppRate & (1<eCurrentPHYMode == PHY_TYPE_11A) - return RATE_6M; - return RATE_1M; -} - -void -VNTWIFIvSet11h( - void *pMgmtObject, - bool b11hEnable -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - pMgmt->b11hEnable = b11hEnable; -} - -bool -VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - unsigned char *pbyCurrentEID = (unsigned char *)(pMgmt->pCurrMeasureEIDRep); - - if ((pvMeasureEID != NULL) && - (pMgmt->uLengthOfRepEIDs < (WLAN_A3FR_MAXLEN - sizeof(MEASEURE_REP) - sizeof(WLAN_80211HDR_A3) - 3)) -) { - pMgmt->pCurrMeasureEIDRep->byElementID = WLAN_EID_MEASURE_REP; - pMgmt->pCurrMeasureEIDRep->len = 3; - pMgmt->pCurrMeasureEIDRep->byToken = ((PWLAN_IE_MEASURE_REQ)pvMeasureEID)->byToken; - pMgmt->pCurrMeasureEIDRep->byMode = byReportMode; - pMgmt->pCurrMeasureEIDRep->byType = ((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->byType; - switch (pMgmt->pCurrMeasureEIDRep->byType) { - case MEASURE_TYPE_BASIC: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sBasic), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap; - break; - case MEASURE_TYPE_CCA: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sCCA), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction; - break; - case MEASURE_TYPE_RPI: - pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI); - memcpy(&(pMgmt->pCurrMeasureEIDRep->sRep.sRPI), - &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq), - sizeof(MEASEURE_REQ)); - memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8); - break; - default: - break; - } - pbyCurrentEID += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); - pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; - } - - return true; -} - -bool -VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel -) -{ - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; - - pMgmt->uCurrChannel = byNewChannel; - pMgmt->bSwitchChannel = false; - return true; -} diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index 9db734f00419..ad180e077e3f 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -100,173 +100,5 @@ typedef enum tagWMAC_POWER_MODE { WMAC_POWER_MAX } WMAC_POWER_MODE, *PWMAC_POWER_MODE; -#define VNTWIFIbIsShortSlotTime(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTSLOTTIME(wCapInfo) \ - -#define VNTWIFIbIsProtectMode(byERP) \ - ((byERP & WLAN_EID_ERP_USE_PROTECTION) != 0) \ - -#define VNTWIFIbIsBarkerMode(byERP) \ - ((byERP & WLAN_EID_ERP_BARKER_MODE) != 0) \ - -#define VNTWIFIbIsShortPreamble(wCapInfo) \ - WLAN_GET_CAP_INFO_SHORTPREAMBLE(wCapInfo) \ - -#define VNTWIFIbIsEncryption(wCapInfo) \ - WLAN_GET_CAP_INFO_PRIVACY(wCapInfo) \ - -#define VNTWIFIbIsESS(wCapInfo) \ - WLAN_GET_CAP_INFO_ESS(wCapInfo) \ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void -VNTWIFIvSetIBSSParameter( - void *pMgmtHandle, - unsigned short wBeaconPeriod, - unsigned short wATIMWindow, - unsigned int uChannel -); - -void -VNTWIFIvSetOPMode( - void *pMgmtHandle, - WMAC_CONFIG_MODE eOPMode -); - -PWLAN_IE_SSID -VNTWIFIpGetCurrentSSID( - void *pMgmtHandle -); - -unsigned int -VNTWIFIpGetCurrentChannel( - void *pMgmtHandle -); - -unsigned short -VNTWIFIwGetAssocID( - void *pMgmtHandle -); - -unsigned char -VNTWIFIbyGetMaxSupportRate( - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -); - -unsigned char -VNTWIFIbyGetACKTxRate( - unsigned char byRxDataRate, - PWLAN_IE_SUPP_RATES pSupportRateIEs, - PWLAN_IE_SUPP_RATES pExtSupportRateIEs -); - -void -VNTWIFIvSetAuthenticationMode( - void *pMgmtHandle, - WMAC_AUTHENTICATION_MODE eAuthMode -); - -void -VNTWIFIvSetEncryptionMode( - void *pMgmtHandle, - WMAC_ENCRYPTION_MODE eEncryptionMode -); - -bool -VNTWIFIbConfigPhyMode( - void *pMgmtHandle, - CARD_PHY_TYPE ePhyType -); - -void -VNTWIFIbGetConfigPhyMode( - void *pMgmtHandle, - void *pePhyType -); - -void -VNTWIFIvQueryBSSList(void *pMgmtHandle, unsigned int *puBSSCount, - void **pvFirstBSS); - -void -VNTWIFIvGetNextBSS( - void *pMgmtHandle, - void *pvCurrentBSS, - void **pvNextBSS -); - -void -VNTWIFIvUpdateNodeTxCounter( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - bool bTxOk, - unsigned short wRate, - unsigned char *pbyTxFailCount -); - -void -VNTWIFIvGetTxRate( - void *pMgmtHandle, - unsigned char *pbyDestAddress, - unsigned short *pwTxDataRate, - unsigned char *pbyACKRate, - unsigned char *pbyCCKBasicRate, - unsigned char *pbyOFDMBasicRate -); - -unsigned char -VNTWIFIbyGetKeyCypher( - void *pMgmtHandle, - bool bGroupKey -); - -bool -VNTWIFIbSetPMKIDCache( - void *pMgmtObject, - unsigned long ulCount, - void *pPMKIDInfo -); - -bool -VNTWIFIbCommandRunning( - void *pMgmtObject -); - -unsigned short -VNTWIFIwGetMaxSupportRate( - void *pMgmtObject -); - -// for 802.11h -void -VNTWIFIvSet11h( - void *pMgmtObject, - bool b11hEnable -); - -bool -VNTWIFIbMeasureReport( - void *pMgmtObject, - bool bEndOfReport, - void *pvMeasureEID, - unsigned char byReportMode, - unsigned char byBasicMap, - unsigned char byCCAFraction, - unsigned char *pbyRPIs -); - -bool -VNTWIFIbChannelSwitch( - void *pMgmtObject, - unsigned char byNewChannel -); #endif //__VNTWIFI_H__ -- GitLab From 77bb9975d445422c5b1acc5f5ca1355db87a843a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:41 +0000 Subject: [PATCH 2098/9457] staging: vt6655: key.c remove dead functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 1 - drivers/staging/vt6655/key.c | 760 -------------------------------- drivers/staging/vt6655/key.h | 120 ----- 3 files changed, 881 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 4bea23799233..a5e5a00743c6 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -539,7 +539,6 @@ struct vnt_private { bool bTransmitKey; NDIS_802_11_WEP_STATUS eOldEncryptionStatus; - SKeyManagement sKey; unsigned long dwIVCounter; u64 qwPacketNumber; /* For CCMP and TKIP as TSC(6 bytes) */ diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index b2fa8125e29d..f2b3fea90533 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -25,772 +25,12 @@ * * Date: May 29, 2003 * - * Functions: - * KeyvInitTable - Init Key management table - * KeybGetKey - Get Key from table - * KeybSetKey - Set Key to table - * KeybRemoveKey - Remove Key from table - * KeybGetTransmitKey - Get Transmit Key from table - * - * Revision History: - * */ #include "tmacro.h" #include "key.h" #include "mac.h" -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ -static void -s_vCheckKeyTableValid(PSKeyManagement pTable, void __iomem *dwIoBase) -{ - int i; - - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - !pTable->KeyTable[i].PairwiseKey.bKeyValid && - !pTable->KeyTable[i].GroupKey[0].bKeyValid && - !pTable->KeyTable[i].GroupKey[1].bKeyValid && - !pTable->KeyTable[i].GroupKey[2].bKeyValid && - !pTable->KeyTable[i].GroupKey[3].bKeyValid) { - pTable->KeyTable[i].bInUse = false; - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } - } -} - -/*--------------------- Export Functions --------------------------*/ - -/* - * Description: Init Key management table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: none - * - */ -void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase) -{ - int i; - int jj; - - for (i = 0; i < MAX_KEY_TABLE; i++) { - pTable->KeyTable[i].bInUse = false; - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i]; - for (jj = 0; jj < MAX_GROUP_KEY; jj++) { - pTable->KeyTable[i].GroupKey[jj].bKeyValid = false; - pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i]; - } - pTable->KeyTable[i].wKeyCtl = 0; - pTable->KeyTable[i].dwGTKeyIndex = 0; - pTable->KeyTable[i].bSoftWEP = false; - MACvDisableKeyEntry(dwIoBase, i); - } -} - -/* - * Description: Get Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key) - * Out: - * pKey - Key return - * - * Return Value: true if found otherwise false - * - */ -bool KeybGetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey -) -{ - int i; - - pr_debug("KeybGetKey()\n"); - - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if (dwKeyIndex == 0xFFFFFFFF) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return true; - } else { - return false; - } - } else if (dwKeyIndex < MAX_GROUP_KEY) { - if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid) { - *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]); - return true; - } else { - return false; - } - } else { - return false; - } - } - } - return false; -} - -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - int i, j; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - pr_debug("Enter KeybSetKey: %lX\n", dwKeyIndex); - - j = (MAX_KEY_TABLE-1); - for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { - if (!pTable->KeyTable[i].bInUse && (j == (MAX_KEY_TABLE-1))) { - // found empty table - j = i; - } - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - // found table already exist - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[i].PairwiseKey); - pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[i].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return true; - } - } - if (j < (MAX_KEY_TABLE-1)) { - ether_addr_copy(pTable->KeyTable[j].abyBSSID, pbyBSSID); - pTable->KeyTable[j].bInUse = true; - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - // Pairwise key - pKey = &(pTable->KeyTable[j].PairwiseKey); - pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed - pTable->KeyTable[j].wKeyCtl |= byKeyDecMode; - uKeyIdx = 4; // use HW key entry 4 for pairwise key - } else { - // Group key - if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(N)[%lX]: %d\n", - pTable->KeyTable[j].dwGTKeyIndex, j); - } - pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - } - pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(N):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); - - return true; - } - return false; -} - -/* - * Description: Remove Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * dwKeyIndex - Key Index (reference to NDIS DDK) - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybRemoveKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -) -{ - int i; - - if (is_broadcast_ether_addr(pbyBSSID)) { - // delete all keys - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - for (i = 0; i < MAX_KEY_TABLE; i++) - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - for (i = 0; i < MAX_KEY_TABLE; i++) { - pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - return false; - } - - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if ((dwKeyIndex & PAIRWISE_KEY) != 0) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = 0; - } - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - return false; - } - } - return false; -} - -/* - * Description: Remove Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybRemoveAllKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - void __iomem *dwIoBase -) -{ - int i, u; - - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - pTable->KeyTable[i].PairwiseKey.bKeyValid = false; - for (u = 0; u < MAX_GROUP_KEY; u++) - pTable->KeyTable[i].GroupKey[u].bKeyValid = false; - - pTable->KeyTable[i].dwGTKeyIndex = 0; - s_vCheckKeyTableValid(pTable, dwIoBase); - return true; - } - } - return false; -} - -/* - * Description: Remove WEP Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -void KeyvRemoveWEPKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -) -{ - if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) { - pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; - if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) { - // remove Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0; - } - } - } - s_vCheckKeyTableValid(pTable, dwIoBase); - } -} - -void KeyvRemoveAllWEPKey( - PSKeyManagement pTable, - void __iomem *dwIoBase -) -{ - int i; - - for (i = 0; i < MAX_GROUP_KEY; i++) - KeyvRemoveWEPKey(pTable, i, dwIoBase); -} - -/* - * Description: Get Transmit Key from table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * pbyBSSID - BSSID of Key - * Out: - * pKey - Key return - * - * Return Value: true if found otherwise false - * - */ -bool KeybGetTransmitKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyType, - PSKeyItem *pKey -) -{ - int i, ii; - - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { - if (dwKeyType == PAIRWISE_KEY) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - - pr_debug("KeybGetTransmitKey:"); - pr_debug("PAIRWISE_KEY: KeyTable.abyBSSID: "); - for (ii = 0; ii < 6; ii++) - pr_debug("%x ", - pTable->KeyTable[i].abyBSSID[ii]); - - pr_debug("\n"); - - return true; - } else { - pr_debug("PairwiseKey.bKeyValid == false\n"); - return false; - } - } // End of Type == PAIRWISE - else { - if (pTable->KeyTable[i].dwGTKeyIndex == 0) { - pr_debug("ERROR: dwGTKeyIndex == 0 !!!\n"); - return false; - } - if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid) { - *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]); - - pr_debug("KeybGetTransmitKey:"); - pr_debug("GROUP_KEY: KeyTable.abyBSSID\n"); - for (ii = 0; ii < 6; ii++) - pr_debug("%x ", - pTable->KeyTable[i].abyBSSID[ii]); - - pr_debug("\n"); - pr_debug("dwGTKeyIndex: %lX\n", - pTable->KeyTable[i].dwGTKeyIndex); - - return true; - } else { - pr_debug("GroupKey.bKeyValid == false\n"); - return false; - } - } // End of Type = GROUP - } // BSSID match - } - pr_debug("ERROR: NO Match BSSID !!! "); - for (ii = 0; ii < 6; ii++) - pr_debug("%02x ", *(pbyBSSID+ii)); - - pr_debug("\n"); - return false; -} - -/* - * Description: Check Pairewise Key - * - * Parameters: - * In: - * pTable - Pointer to Key table - * Out: - * none - * - * Return Value: true if found otherwise false - * - */ -bool KeybCheckPairewiseKey( - PSKeyManagement pTable, - PSKeyItem *pKey -) -{ - int i; - - *pKey = NULL; - for (i = 0; i < MAX_KEY_TABLE; i++) { - if (pTable->KeyTable[i].bInUse && - pTable->KeyTable[i].PairwiseKey.bKeyValid) { - *pKey = &(pTable->KeyTable[i].PairwiseKey); - return true; - } - } - return false; -} - -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetDefaultKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - pr_debug("Enter KeybSetDefaultKey: %1x, %d\n", - (int)dwKeyIndex, (int)uKeyLength); - - if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key - return false; - else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - - if (uKeyLength > MAX_KEY_LEN) - return false; - - pTable->KeyTable[MAX_KEY_TABLE - 1].bInUse = true; - for (ii = 0; ii < ETH_ALEN; ii++) - pTable->KeyTable[MAX_KEY_TABLE - 1].abyBSSID[ii] = 0xFF; - - // Group key - pKey = &(pTable->KeyTable[MAX_KEY_TABLE - 1].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, - MAX_KEY_TABLE-1); - - } - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode); - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address - uKeyIdx = (dwKeyIndex & 0x000000FF); - - if ((uKeyLength == WLAN_WEP232_KEYLEN) && - (byKeyDecMode == KEY_CTL_WEP)) { - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match - pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true; - } else { - if (!pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP) - pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match - } - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n", (int)pKey->uKeyLength); - pr_debug("pKey->abyKey:\n"); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%x", pKey->abyKey[ii]); - - pr_debug("\n"); - - pr_debug("pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); - pr_debug("pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - pr_debug("pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); - - return true; -} - -/* - * Description: Set Key to table - * - * Parameters: - * In: - * pTable - Pointer to Key table - * dwKeyIndex - Key index (reference to NDIS DDK) - * uKeyLength - Key length - * KeyRSC - Key RSC - * pbyKey - Pointer to key - * Out: - * none - * - * Return Value: true if success otherwise false - * - */ -bool KeybSetAllGroupKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -) -{ - int i; - unsigned int ii; - PSKeyItem pKey; - unsigned int uKeyIdx; - - pr_debug("Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); - - if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key - return false; - else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) - return false; - - for (i = 0; i < MAX_KEY_TABLE - 1; i++) { - if (pTable->KeyTable[i].bInUse) { - // found table already exist - // Group key - pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); - if ((dwKeyIndex & TRANSMIT_KEY) != 0) { - // Group transmit key - pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - pr_debug("Group transmit key(R)[%lX]: %d\n", - pTable->KeyTable[i].dwGTKeyIndex, i); - - } - pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed - pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); - pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address - uKeyIdx = (dwKeyIndex & 0x000000FF); - - pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly - - pKey->bKeyValid = true; - pKey->uKeyLength = uKeyLength; - pKey->dwKeyIndex = dwKeyIndex; - pKey->byCipherSuite = byKeyDecMode; - memcpy(pKey->abyKey, pbyKey, uKeyLength); - if (byKeyDecMode == KEY_CTL_WEP) { - if (uKeyLength == WLAN_WEP40_KEYLEN) - pKey->abyKey[15] &= 0x7F; - if (uKeyLength == WLAN_WEP104_KEYLEN) - pKey->abyKey[15] |= 0x80; - } - MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (u32 *)pKey->abyKey, byLocalID); - - if ((dwKeyIndex & USE_KEYRSC) == 0) { - // RSC set by NIC - pKey->KeyRSC = 0; - } else { - pKey->KeyRSC = *pKeyRSC; - } - pKey->dwTSC47_16 = 0; - pKey->wTSC15_0 = 0; - - pr_debug("KeybSetKey(R):\n"); - pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); - pr_debug("pKey->uKeyLength: %d\n ", - (int)pKey->uKeyLength); - pr_debug("pKey->abyKey: "); - for (ii = 0; ii < pKey->uKeyLength; ii++) - pr_debug("%02x ", pKey->abyKey[ii]); - - pr_debug("\n"); - - } // (pTable->KeyTable[i].bInUse == true) - } - return true; -} - int vnt_key_init_table(struct vnt_private *priv) { u32 i; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index d70ffd6fe728..56d1b05aad79 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -63,126 +63,6 @@ #define VNT_KEY_ONFLY 0x8000 #define VNT_KEY_ONFLY_ALL 0x4000 -typedef struct tagSKeyItem { - bool bKeyValid; - unsigned long uKeyLength; - unsigned char abyKey[MAX_KEY_LEN]; - u64 KeyRSC; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned char byCipherSuite; - unsigned char byReserved0; - unsigned long dwKeyIndex; - void *pvKeyTable; -} SKeyItem, *PSKeyItem; //64 - -typedef struct tagSKeyTable { - unsigned char abyBSSID[ETH_ALEN]; //6 - unsigned char byReserved0[2]; //8 - SKeyItem PairwiseKey; - SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 - unsigned long dwGTKeyIndex; // GroupTransmitKey Index - bool bInUse; - //2006-1116-01, by NomadZhao - bool bSoftWEP; - unsigned short wKeyCtl; // for address of wKeyCtl at align 4 - - unsigned char byReserved1[6]; -} SKeyTable, *PSKeyTable; //348 - -typedef struct tagSKeyManagement { - SKeyTable KeyTable[MAX_KEY_TABLE]; -} SKeyManagement, *PSKeyManagement; - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase); - -bool KeybGetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - PSKeyItem *pKey -); - -bool KeybSetKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); - -bool KeybSetDefaultKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); - -bool KeybRemoveKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -); - -bool KeybGetTransmitKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - unsigned long dwKeyType, - PSKeyItem *pKey -); - -bool KeybCheckPairewiseKey( - PSKeyManagement pTable, - PSKeyItem *pKey -); - -bool KeybRemoveAllKey( - PSKeyManagement pTable, - unsigned char *pbyBSSID, - void __iomem *dwIoBase -); - -void KeyvRemoveWEPKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - void __iomem *dwIoBase -); - -void KeyvRemoveAllWEPKey( - PSKeyManagement pTable, - void __iomem *dwIoBase -); - -bool KeybSetAllGroupKey( - PSKeyManagement pTable, - unsigned long dwKeyIndex, - unsigned long uKeyLength, - u64 *pKeyRSC, - unsigned char *pbyKey, - unsigned char byKeyDecMode, - void __iomem *dwIoBase, - unsigned char byLocalID -); - struct vnt_private; int vnt_key_init_table(struct vnt_private *); -- GitLab From 1243317b4670db31b12a9ed6364b0ffd0692c4d1 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:42 +0000 Subject: [PATCH 2099/9457] staging: vt6655: mib remove unused functions and structure members Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mib.c | 423 ----------------------------------- drivers/staging/vt6655/mib.h | 259 --------------------- 2 files changed, 682 deletions(-) diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index 111c01877086..d2f351d19ff8 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -25,24 +25,15 @@ * Date: May 21, 1996 * * Functions: - * STAvClearAllCounter - Clear All MIB Counter * STAvUpdateIstStatCounter - Update ISR statistic counter - * STAvUpdateRDStatCounter - Update Rx statistic counter - * STAvUpdateRDStatCounterEx - Update Rx statistic counter and copy rcv data - * STAvUpdateTDStatCounter - Update Tx statistic counter - * STAvUpdateTDStatCounterEx - Update Tx statistic counter and copy tx data * STAvUpdate802_11Counter - Update 802.11 mib counter * * Revision History: * */ -#include "upc.h" #include "mac.h" -#include "tether.h" #include "mib.h" -#include "wctl.h" -#include "baseband.h" /*--------------------- Static Classes ----------------------------*/ @@ -54,24 +45,6 @@ /*--------------------- Export Functions --------------------------*/ -/* - * Description: Clear All Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * Out: - * none - * - * Return Value: none - * - */ -void STAvClearAllCounter(PSStatCounter pStatistic) -{ - // set memory to zero - memset(pStatistic, 0, sizeof(SStatCounter)); -} - /* * Description: Update Isr Statistic Counter * @@ -138,373 +111,6 @@ void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr) pStatistic->ISRStat.dwIsrSTIMER1Int++; } -/* - * Description: Update Rx Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byRSR - Rx Status - * byNewRSR - Rx Status - * pbyBuffer - Rx Buffer - * cbFrameLength - Rx Length - * Out: - * none - * - * Return Value: none - * - */ -void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength) -{ - //need change - PS802_11Header pHeader = (PS802_11Header)pbyBuffer; - - if (byRSR & RSR_ADDROK) - pStatistic->dwRsrADDROk++; - if (byRSR & RSR_CRCOK) { - pStatistic->dwRsrCRCOk++; - - pStatistic->ullRsrOK++; - - if (cbFrameLength >= ETH_ALEN) { - // update counters in case of successful transmit - if (byRSR & RSR_ADDRBROAD) { - pStatistic->ullRxBroadcastFrames++; - pStatistic->ullRxBroadcastBytes += (unsigned long long) cbFrameLength; - } else if (byRSR & RSR_ADDRMULTI) { - pStatistic->ullRxMulticastFrames++; - pStatistic->ullRxMulticastBytes += (unsigned long long) cbFrameLength; - } else { - pStatistic->ullRxDirectedFrames++; - pStatistic->ullRxDirectedBytes += (unsigned long long) cbFrameLength; - } - } - } - - if (byRxRate == 22) { - pStatistic->CustomStat.ullRsr11M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr11MCRCOk++; - - pr_debug("11M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr11M, - (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); - } else if (byRxRate == 11) { - pStatistic->CustomStat.ullRsr5M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr5MCRCOk++; - - pr_debug(" 5M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr5M, - (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); - } else if (byRxRate == 4) { - pStatistic->CustomStat.ullRsr2M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr2MCRCOk++; - - pr_debug(" 2M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr2M, - (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); - } else if (byRxRate == 2) { - pStatistic->CustomStat.ullRsr1M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr1MCRCOk++; - - pr_debug(" 1M: ALL[%d], OK[%d]:[%02x]\n", - (int)pStatistic->CustomStat.ullRsr1M, - (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); - } else if (byRxRate == 12) { - pStatistic->CustomStat.ullRsr6M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr6MCRCOk++; - - pr_debug(" 6M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr6M, - (int)pStatistic->CustomStat.ullRsr6MCRCOk); - } else if (byRxRate == 18) { - pStatistic->CustomStat.ullRsr9M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr9MCRCOk++; - - pr_debug(" 9M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr9M, - (int)pStatistic->CustomStat.ullRsr9MCRCOk); - } else if (byRxRate == 24) { - pStatistic->CustomStat.ullRsr12M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr12MCRCOk++; - - pr_debug("12M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr12M, - (int)pStatistic->CustomStat.ullRsr12MCRCOk); - } else if (byRxRate == 36) { - pStatistic->CustomStat.ullRsr18M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr18MCRCOk++; - - pr_debug("18M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr18M, - (int)pStatistic->CustomStat.ullRsr18MCRCOk); - } else if (byRxRate == 48) { - pStatistic->CustomStat.ullRsr24M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr24MCRCOk++; - - pr_debug("24M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr24M, - (int)pStatistic->CustomStat.ullRsr24MCRCOk); - } else if (byRxRate == 72) { - pStatistic->CustomStat.ullRsr36M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr36MCRCOk++; - - pr_debug("36M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr36M, - (int)pStatistic->CustomStat.ullRsr36MCRCOk); - } else if (byRxRate == 96) { - pStatistic->CustomStat.ullRsr48M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr48MCRCOk++; - - pr_debug("48M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr48M, - (int)pStatistic->CustomStat.ullRsr48MCRCOk); - } else if (byRxRate == 108) { - pStatistic->CustomStat.ullRsr54M++; - if (byRSR & RSR_CRCOK) - pStatistic->CustomStat.ullRsr54MCRCOk++; - - pr_debug("54M: ALL[%d], OK[%d]\n", - (int)pStatistic->CustomStat.ullRsr54M, - (int)pStatistic->CustomStat.ullRsr54MCRCOk); - } else { - pr_debug("Unknown: Total[%d], CRCOK[%d]\n", - (int)pStatistic->dwRsrRxPacket+1, - (int)pStatistic->dwRsrCRCOk); - } - - if (byRSR & RSR_BSSIDOK) - pStatistic->dwRsrBSSIDOk++; - - if (byRSR & RSR_BCNSSIDOK) - pStatistic->dwRsrBCNSSIDOk++; - if (byRSR & RSR_IVLDLEN) //invalid len (> 2312 byte) - pStatistic->dwRsrLENErr++; - if (byRSR & RSR_IVLDTYP) //invalid packet type - pStatistic->dwRsrTYPErr++; - if (byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) - pStatistic->dwRsrErr++; - - if (byNewRSR & NEWRSR_DECRYPTOK) - pStatistic->dwNewRsrDECRYPTOK++; - if (byNewRSR & NEWRSR_CFPIND) - pStatistic->dwNewRsrCFP++; - if (byNewRSR & NEWRSR_HWUTSF) - pStatistic->dwNewRsrUTSF++; - if (byNewRSR & NEWRSR_BCNHITAID) - pStatistic->dwNewRsrHITAID++; - if (byNewRSR & NEWRSR_BCNHITAID0) - pStatistic->dwNewRsrHITAID0++; - - // increase rx packet count - pStatistic->dwRsrRxPacket++; - pStatistic->dwRsrRxOctet += cbFrameLength; - - if (IS_TYPE_DATA(pbyBuffer)) - pStatistic->dwRsrRxData++; - else if (IS_TYPE_MGMT(pbyBuffer)) - pStatistic->dwRsrRxManage++; - else if (IS_TYPE_CONTROL(pbyBuffer)) - pStatistic->dwRsrRxControl++; - - if (byRSR & RSR_ADDRBROAD) - pStatistic->dwRsrBroadcast++; - else if (byRSR & RSR_ADDRMULTI) - pStatistic->dwRsrMulticast++; - else - pStatistic->dwRsrDirected++; - - if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl)) - pStatistic->dwRsrRxFragment++; - - if (cbFrameLength < ETH_ZLEN + 4) - pStatistic->dwRsrRunt++; - else if (cbFrameLength == ETH_ZLEN + 4) - pStatistic->dwRsrRxFrmLen64++; - else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) - pStatistic->dwRsrRxFrmLen65_127++; - else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) - pStatistic->dwRsrRxFrmLen128_255++; - else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) - pStatistic->dwRsrRxFrmLen256_511++; - else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) - pStatistic->dwRsrRxFrmLen512_1023++; - else if ((1024 <= cbFrameLength) && (cbFrameLength <= ETH_FRAME_LEN + 4)) - pStatistic->dwRsrRxFrmLen1024_1518++; - else if (cbFrameLength > ETH_FRAME_LEN + 4) - pStatistic->dwRsrLong++; -} - -/* - * Description: Update Rx Statistic Counter and copy Rx buffer - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byRSR - Rx Status - * byNewRSR - Rx Status - * pbyBuffer - Rx Buffer - * cbFrameLength - Rx Length - * Out: - * none - * - * Return Value: none - * - */ - -void -STAvUpdateRDStatCounterEx( - PSStatCounter pStatistic, - unsigned char byRSR, - unsigned char byNewRSR, - unsigned char byRxRate, - unsigned char *pbyBuffer, - unsigned int cbFrameLength -) -{ - STAvUpdateRDStatCounter( - pStatistic, - byRSR, - byNewRSR, - byRxRate, - pbyBuffer, - cbFrameLength -); - - // rx length - pStatistic->dwCntRxFrmLength = cbFrameLength; - // rx pattern, we just see 10 bytes for sample - memcpy(pStatistic->abyCntRxPattern, (unsigned char *)pbyBuffer, 10); -} - -/* - * Description: Update Tx Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byTSR0 - Tx Status - * byTSR1 - Tx Status - * pbyBuffer - Tx Buffer - * cbFrameLength - Tx Length - * uIdx - Index of Tx DMA - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdateTDStatCounter( - PSStatCounter pStatistic, - unsigned char byTSR0, - unsigned char byTSR1, - unsigned char *pbyBuffer, - unsigned int cbFrameLength, - unsigned int uIdx -) -{ - PWLAN_80211HDR_A4 pHeader; - unsigned char *pbyDestAddr; - unsigned char byTSR0_NCR = byTSR0 & TSR0_NCR; - - pHeader = (PWLAN_80211HDR_A4) pbyBuffer; - if (WLAN_GET_FC_TODS(pHeader->wFrameCtl) == 0) - pbyDestAddr = &(pHeader->abyAddr1[0]); - else - pbyDestAddr = &(pHeader->abyAddr3[0]); - - // increase tx packet count - pStatistic->dwTsrTxPacket[uIdx]++; - pStatistic->dwTsrTxOctet[uIdx] += cbFrameLength; - - if (byTSR0_NCR != 0) { - pStatistic->dwTsrRetry[uIdx]++; - pStatistic->dwTsrTotalRetry[uIdx] += byTSR0_NCR; - - if (byTSR0_NCR == 1) - pStatistic->dwTsrOnceRetry[uIdx]++; - else - pStatistic->dwTsrMoreThanOnceRetry[uIdx]++; - } - - if ((byTSR1&(TSR1_TERR|TSR1_RETRYTMO|TSR1_TMO|ACK_DATA)) == 0) { - pStatistic->ullTsrOK[uIdx]++; - pStatistic->CustomStat.ullTsrAllOK = - (pStatistic->ullTsrOK[TYPE_AC0DMA] + pStatistic->ullTsrOK[TYPE_TXDMA0]); - // update counters in case that successful transmit - if (is_broadcast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxBroadcastFrames[uIdx]++; - pStatistic->ullTxBroadcastBytes[uIdx] += (unsigned long long) cbFrameLength; - } else if (is_multicast_ether_addr(pbyDestAddr)) { - pStatistic->ullTxMulticastFrames[uIdx]++; - pStatistic->ullTxMulticastBytes[uIdx] += (unsigned long long) cbFrameLength; - } else { - pStatistic->ullTxDirectedFrames[uIdx]++; - pStatistic->ullTxDirectedBytes[uIdx] += (unsigned long long) cbFrameLength; - } - } else { - if (byTSR1 & TSR1_TERR) - pStatistic->dwTsrErr[uIdx]++; - if (byTSR1 & TSR1_RETRYTMO) - pStatistic->dwTsrRetryTimeout[uIdx]++; - if (byTSR1 & TSR1_TMO) - pStatistic->dwTsrTransmitTimeout[uIdx]++; - if (byTSR1 & ACK_DATA) - pStatistic->dwTsrACKData[uIdx]++; - } - - if (is_broadcast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrBroadcast[uIdx]++; - else if (is_multicast_ether_addr(pbyDestAddr)) - pStatistic->dwTsrMulticast[uIdx]++; - else - pStatistic->dwTsrDirected[uIdx]++; -} - -/* - * Description: Update Tx Statistic Counter and copy Tx buffer - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * pbyBuffer - Tx Buffer - * cbFrameLength - Tx Length - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdateTDStatCounterEx( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength -) -{ - unsigned int uPktLength; - - uPktLength = (unsigned int)cbFrameLength; - - // tx length - pStatistic->dwCntTxBufLength = uPktLength; - // tx pattern, we just see 16 bytes for sample - memcpy(pStatistic->abyCntTxPattern, pbyBuffer, 16); -} - /* * Description: Update 802.11 mib counter * @@ -526,37 +132,8 @@ STAvUpdate802_11Counter( unsigned long dwCounter ) { - p802_11Counter->MulticastTransmittedFrameCount = (unsigned long long) (pStatistic->dwTsrBroadcast[TYPE_AC0DMA] + - pStatistic->dwTsrBroadcast[TYPE_TXDMA0] + - pStatistic->dwTsrMulticast[TYPE_AC0DMA] + - pStatistic->dwTsrMulticast[TYPE_TXDMA0]); - p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr[TYPE_AC0DMA] + pStatistic->dwTsrErr[TYPE_TXDMA0]); - p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry[TYPE_AC0DMA] + pStatistic->dwTsrRetry[TYPE_TXDMA0]); - p802_11Counter->MultipleRetryCount = (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry[TYPE_AC0DMA] + - pStatistic->dwTsrMoreThanOnceRetry[TYPE_TXDMA0]); p802_11Counter->RTSSuccessCount += (unsigned long long) (dwCounter & 0x000000ff); p802_11Counter->RTSFailureCount += (unsigned long long) ((dwCounter & 0x0000ff00) >> 8); p802_11Counter->ACKFailureCount += (unsigned long long) ((dwCounter & 0x00ff0000) >> 16); p802_11Counter->FCSErrorCount += (unsigned long long) ((dwCounter & 0xff000000) >> 24); - p802_11Counter->MulticastReceivedFrameCount = (unsigned long long) (pStatistic->dwRsrBroadcast + - pStatistic->dwRsrMulticast); -} - -/* - * Description: Clear 802.11 mib counter - * - * Parameters: - * In: - * p802_11Counter - Pointer to 802.11 mib counter - * Out: - * none - * - * Return Value: none - * - */ -void -STAvClear802_11Counter(PSDot11Counters p802_11Counter) -{ - // set memory to zero - memset(p802_11Counter, 0, sizeof(SDot11Counters)); } diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index 732bddaf5b91..fdb40f20d3e5 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -38,136 +38,16 @@ // typedef struct tagSDot11Counters { - unsigned long Length; - unsigned long long TransmittedFragmentCount; - unsigned long long MulticastTransmittedFrameCount; - unsigned long long FailedCount; - unsigned long long RetryCount; - unsigned long long MultipleRetryCount; unsigned long long RTSSuccessCount; unsigned long long RTSFailureCount; unsigned long long ACKFailureCount; - unsigned long long FrameDuplicateCount; - unsigned long long ReceivedFragmentCount; - unsigned long long MulticastReceivedFrameCount; unsigned long long FCSErrorCount; - unsigned long long TKIPLocalMICFailures; - unsigned long long TKIPRemoteMICFailures; - unsigned long long TKIPICVErrors; - unsigned long long TKIPCounterMeasuresInvoked; - unsigned long long TKIPReplays; - unsigned long long CCMPFormatErrors; - unsigned long long CCMPReplays; - unsigned long long CCMPDecryptErrors; - unsigned long long FourWayHandshakeFailures; } SDot11Counters, *PSDot11Counters; -// -// MIB2 counter -// -typedef struct tagSMib2Counter { - long ifIndex; - char ifDescr[256]; - long ifType; - long ifMtu; - unsigned long ifSpeed; - unsigned char ifPhysAddress[ETH_ALEN]; - long ifAdminStatus; - long ifOperStatus; - unsigned long ifLastChange; - unsigned long ifInOctets; - unsigned long ifInUcastPkts; - unsigned long ifInNUcastPkts; - unsigned long ifInDiscards; - unsigned long ifInErrors; - unsigned long ifInUnknownProtos; - unsigned long ifOutOctets; - unsigned long ifOutUcastPkts; - unsigned long ifOutNUcastPkts; - unsigned long ifOutDiscards; - unsigned long ifOutErrors; - unsigned long ifOutQLen; - unsigned long ifSpecific; -} SMib2Counter, *PSMib2Counter; - -// Value in the ifType entry -#define WIRELESSLANIEEE80211b 6 - -// Value in the ifAdminStatus/ifOperStatus entry -#define UP 1 -#define DOWN 2 -#define TESTING 3 - -// -// RMON counter -// -typedef struct tagSRmonCounter { - long etherStatsIndex; - unsigned long etherStatsDataSource; - unsigned long etherStatsDropEvents; - unsigned long etherStatsOctets; - unsigned long etherStatsPkts; - unsigned long etherStatsBroadcastPkts; - unsigned long etherStatsMulticastPkts; - unsigned long etherStatsCRCAlignErrors; - unsigned long etherStatsUndersizePkts; - unsigned long etherStatsOversizePkts; - unsigned long etherStatsFragments; - unsigned long etherStatsJabbers; - unsigned long etherStatsCollisions; - unsigned long etherStatsPkt64Octets; - unsigned long etherStatsPkt65to127Octets; - unsigned long etherStatsPkt128to255Octets; - unsigned long etherStatsPkt256to511Octets; - unsigned long etherStatsPkt512to1023Octets; - unsigned long etherStatsPkt1024to1518Octets; - unsigned long etherStatsOwners; - unsigned long etherStatsStatus; -} SRmonCounter, *PSRmonCounter; - -// -// Custom counter -// -typedef struct tagSCustomCounters { - unsigned long Length; - - unsigned long long ullTsrAllOK; - - unsigned long long ullRsr11M; - unsigned long long ullRsr5M; - unsigned long long ullRsr2M; - unsigned long long ullRsr1M; - - unsigned long long ullRsr11MCRCOk; - unsigned long long ullRsr5MCRCOk; - unsigned long long ullRsr2MCRCOk; - unsigned long long ullRsr1MCRCOk; - - unsigned long long ullRsr54M; - unsigned long long ullRsr48M; - unsigned long long ullRsr36M; - unsigned long long ullRsr24M; - unsigned long long ullRsr18M; - unsigned long long ullRsr12M; - unsigned long long ullRsr9M; - unsigned long long ullRsr6M; - - unsigned long long ullRsr54MCRCOk; - unsigned long long ullRsr48MCRCOk; - unsigned long long ullRsr36MCRCOk; - unsigned long long ullRsr24MCRCOk; - unsigned long long ullRsr18MCRCOk; - unsigned long long ullRsr12MCRCOk; - unsigned long long ullRsr9MCRCOk; - unsigned long long ullRsr6MCRCOk; -} SCustomCounters, *PSCustomCounters; - // // Custom counter // typedef struct tagSISRCounters { - unsigned long Length; - unsigned long dwIsrTx0OK; unsigned long dwIsrAC0TxOK; unsigned long dwIsrBeaconTxOK; @@ -183,161 +63,22 @@ typedef struct tagSISRCounters { unsigned long dwIsrUnknown; unsigned long dwIsrRx1OK; - unsigned long dwIsrATIMTxOK; - unsigned long dwIsrSYNCTxOK; - unsigned long dwIsrCFPEnd; - unsigned long dwIsrATIMEnd; - unsigned long dwIsrSYNCFlushOK; unsigned long dwIsrSTIMER1Int; } SISRCounters, *PSISRCounters; -// Value in the etherStatsStatus entry -#define VALID 1 -#define CREATE_REQUEST 2 -#define UNDER_CREATION 3 -#define INVALID 4 - // // statistic counter // typedef struct tagSStatCounter { - // RSR status count - // - unsigned long dwRsrFrmAlgnErr; - unsigned long dwRsrErr; - unsigned long dwRsrCRCErr; - unsigned long dwRsrCRCOk; - unsigned long dwRsrBSSIDOk; - unsigned long dwRsrADDROk; - unsigned long dwRsrBCNSSIDOk; - unsigned long dwRsrLENErr; - unsigned long dwRsrTYPErr; - - unsigned long dwNewRsrDECRYPTOK; - unsigned long dwNewRsrCFP; - unsigned long dwNewRsrUTSF; - unsigned long dwNewRsrHITAID; - unsigned long dwNewRsrHITAID0; - - unsigned long dwRsrLong; - unsigned long dwRsrRunt; - - unsigned long dwRsrRxControl; - unsigned long dwRsrRxData; - unsigned long dwRsrRxManage; - - unsigned long dwRsrRxPacket; - unsigned long dwRsrRxOctet; - unsigned long dwRsrBroadcast; - unsigned long dwRsrMulticast; - unsigned long dwRsrDirected; - // 64-bit OID - unsigned long long ullRsrOK; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullRxBroadcastBytes; - unsigned long long ullRxMulticastBytes; - unsigned long long ullRxDirectedBytes; - unsigned long long ullRxBroadcastFrames; - unsigned long long ullRxMulticastFrames; - unsigned long long ullRxDirectedFrames; - - unsigned long dwRsrRxFragment; - unsigned long dwRsrRxFrmLen64; - unsigned long dwRsrRxFrmLen65_127; - unsigned long dwRsrRxFrmLen128_255; - unsigned long dwRsrRxFrmLen256_511; - unsigned long dwRsrRxFrmLen512_1023; - unsigned long dwRsrRxFrmLen1024_1518; - - // TSR status count - // - unsigned long dwTsrTotalRetry[TYPE_MAXTD]; // total collision retry count - unsigned long dwTsrOnceRetry[TYPE_MAXTD]; // this packet only occur one collision - unsigned long dwTsrMoreThanOnceRetry[TYPE_MAXTD]; // this packet occur more than one collision - unsigned long dwTsrRetry[TYPE_MAXTD]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - unsigned long dwTsrACKData[TYPE_MAXTD]; - unsigned long dwTsrErr[TYPE_MAXTD]; - unsigned long dwAllTsrOK[TYPE_MAXTD]; - unsigned long dwTsrRetryTimeout[TYPE_MAXTD]; - unsigned long dwTsrTransmitTimeout[TYPE_MAXTD]; - - unsigned long dwTsrTxPacket[TYPE_MAXTD]; - unsigned long dwTsrTxOctet[TYPE_MAXTD]; - unsigned long dwTsrBroadcast[TYPE_MAXTD]; - unsigned long dwTsrMulticast[TYPE_MAXTD]; - unsigned long dwTsrDirected[TYPE_MAXTD]; - - // RD/TD count - unsigned long dwCntRxFrmLength; - unsigned long dwCntTxBufLength; - - unsigned char abyCntRxPattern[16]; - unsigned char abyCntTxPattern[16]; - - // Software check.... - unsigned long dwCntRxDataErr; // rx buffer data software compare CRC err count - unsigned long dwCntDecryptErr; // rx buffer data software compare CRC err count - unsigned long dwCntRxICVErr; // rx buffer data software compare CRC err count - unsigned int idxRxErrorDesc[TYPE_MAXRD]; // index for rx data error RD - - // 64-bit OID - unsigned long long ullTsrOK[TYPE_MAXTD]; - - // for some optional OIDs (64 bits) and DMI support - unsigned long long ullTxBroadcastFrames[TYPE_MAXTD]; - unsigned long long ullTxMulticastFrames[TYPE_MAXTD]; - unsigned long long ullTxDirectedFrames[TYPE_MAXTD]; - unsigned long long ullTxBroadcastBytes[TYPE_MAXTD]; - unsigned long long ullTxMulticastBytes[TYPE_MAXTD]; - unsigned long long ullTxDirectedBytes[TYPE_MAXTD]; - SISRCounters ISRStat; - - SCustomCounters CustomStat; - -#ifdef Calcu_LinkQual - //Tx count: - unsigned long TxNoRetryOkCount; - unsigned long TxRetryOkCount; - unsigned long TxFailCount; - //Rx count: - unsigned long RxOkCnt; - unsigned long RxFcsErrCnt; - //statistic - unsigned long SignalStren; - unsigned long LinkQuality; -#endif } SStatCounter, *PSStatCounter; -void STAvClearAllCounter(PSStatCounter pStatistic); - void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr); -void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRSR, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); - -void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic, - unsigned char byRSR, unsigned char byNewRsr, unsigned char byRxRate, - unsigned char *pbyBuffer, unsigned int cbFrameLength); - -void STAvUpdateTDStatCounter(PSStatCounter pStatistic, unsigned char byTSR0, unsigned char byTSR1, - unsigned char *pbyBuffer, unsigned int cbFrameLength, unsigned int uIdx); - -void STAvUpdateTDStatCounterEx( - PSStatCounter pStatistic, - unsigned char *pbyBuffer, - unsigned long cbFrameLength -); - void STAvUpdate802_11Counter( PSDot11Counters p802_11Counter, PSStatCounter pStatistic, unsigned long dwCounter ); -void STAvClear802_11Counter(PSDot11Counters p802_11Counter); - #endif // __MIB_H__ -- GitLab From 029c7d225aa431fa09af97e855e3d12d5aed8a6c Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:43 +0000 Subject: [PATCH 2100/9457] staging: vt6655L remove tether.c functions remove ETHbyGetHashIndexByCrc32 ETHbIsBufferCrc32Ok tether.h header will be removed later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/tether.c | 105 -------------------------------- drivers/staging/vt6655/tether.h | 4 -- 3 files changed, 110 deletions(-) delete mode 100644 drivers/staging/vt6655/tether.c diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index d571e6f46ade..1a5876deba8e 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -14,7 +14,6 @@ vt6655_stage-y += device_main.o \ power.o \ srom.o \ mib.o \ - tether.o \ tcrc.o \ key.o \ rf.o diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c deleted file mode 100644 index 1e7d3e2115a9..000000000000 --- a/drivers/staging/vt6655/tether.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tether.c - * - * Purpose: - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * ETHbyGetHashIndexByCrc32 - Calculate multicast hash value by CRC32 - * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not - * - * Revision History: - * - */ - -#include "device.h" -#include "tmacro.h" -#include "tcrc.h" -#include "tether.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: Calculate multicast hash value by CRC32 - * - * Parameters: - * In: - * pbyMultiAddr - Multicast Address - * Out: - * none - * - * Return Value: Hash value - * - */ -unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr) -{ - int ii; - unsigned char byTmpHash; - unsigned char byHash = 0; - - // get the least 6-bits from CRC generator - byTmpHash = (unsigned char)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, - 0xFFFFFFFFL) & 0x3F); - // reverse most bit to least bit - for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { - byHash <<= 1; - if (byTmpHash & 0x01) - byHash |= 1; - byTmpHash >>= 1; - } - - // adjust 6-bits to the right most - return byHash >> 2; -} - -/* - * Description: Check CRC value of the buffer if Ok or not - * - * Parameters: - * In: - * pbyBuffer - pointer of buffer (normally is rx buffer) - * cbFrameLength - length of buffer, including CRC portion - * Out: - * none - * - * Return Value: true if ok; false if error. - * - */ -bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength) -{ - unsigned long dwCRC; - - dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); - if (cpu_to_le32(*((unsigned long *)(pbyBuffer + cbFrameLength - 4))) != dwCRC) - return false; - - return true; -} diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index 94cc8830d8cc..850554c3e762 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -185,8 +185,4 @@ S802_11Header, *PS802_11Header; /*--------------------- Export Functions --------------------------*/ -unsigned char ETHbyGetHashIndexByCrc32(unsigned char *pbyMultiAddr); -//unsigned char ETHbyGetHashIndexByCrc(unsigned char *pbyMultiAddr); -bool ETHbIsBufferCrc32Ok(unsigned char *pbyBuffer, unsigned int cbFrameLength); - #endif // __TETHER_H__ -- GitLab From 5e6fc9d7e4f9573a3b110fff8eb3e82553e0c0b0 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:44 +0000 Subject: [PATCH 2101/9457] staging: vt6655: dead code remove tcrc.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/tcrc.c | 191 --------------------------- drivers/staging/vt6655/tcrc.h | 50 ------- 5 files changed, 244 deletions(-) delete mode 100644 drivers/staging/vt6655/tcrc.c delete mode 100644 drivers/staging/vt6655/tcrc.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 1a5876deba8e..390c23ef9f44 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -14,7 +14,6 @@ vt6655_stage-y += device_main.o \ power.o \ srom.o \ mib.o \ - tcrc.o \ key.o \ rf.o diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 18dad0cb69a0..2c2f42fe10af 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -64,7 +64,6 @@ #include "power.h" #include "wcmd.h" #include "iocmd.h" -#include "tcrc.h" #include "rxtx.h" #include "bssdb.h" #include "dpc.h" diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 4770b9cf622b..b8ff8c60a84a 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -55,7 +55,6 @@ #include "bssdb.h" #include "mac.h" #include "baseband.h" -#include "tcrc.h" #include "wctl.h" #include "rf.h" diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c deleted file mode 100644 index ddc5efd040f9..000000000000 --- a/drivers/staging/vt6655/tcrc.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tcrc.c - * - * Purpose: Implement functions to calculate CRC - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - * Functions: - * CRCdwCrc32 - - * CRCdwGetCrc32 - - * CRCdwGetCrc32Ex - - * - * Revision History: - * - */ - -#include "tcrc.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/* 32-bit CRC table */ -static const unsigned long s_adwCrc32Table[256] = { - 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, - 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, - 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, - 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, - 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, - 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, - 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, - 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, - 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, - 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, - 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, - 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, - 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, - 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, - 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, - 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, - 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, - 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, - 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, - 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, - 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, - 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, - 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, - 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, - 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, - 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, - 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, - 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, - 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, - 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, - 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, - 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, - 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, - 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, - 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, - 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, - 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, - 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, - 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, - 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, - 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, - 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, - 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, - 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, - 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, - 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, - 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, - 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, - 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, - 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, - 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, - 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, - 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, - 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, - 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, - 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, - 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, - 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, - 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, - 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, - 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, - 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, - 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, - 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL -}; - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*+ - * - * Description: - * Generate a CRC-32 from the data stream - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * dwCrcSeed - Seed for CRC32 - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed) -{ - unsigned long dwCrc; - - dwCrc = dwCrcSeed; - while (cbByte--) { - dwCrc = s_adwCrc32Table[(unsigned char)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); - pbyData++; - } - - return dwCrc; -} - -/*+ - * - * Description: - * To test CRC generator, input 8 bytes packet - * -- 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00 - * the generated CRC should be - * -- 0xff 0xff 0xff 0xff - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte) -{ - return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); -} - -/*+ - * - * Description: - * - * NOTE.... Because CRCdwGetCrc32Ex() is an iteration function, - * this means we will use the output of CRCdwGetCrc32Ex() - * to be a new argument to do next CRCdwGetCrc32Ex() calculation. - * Thus, the final result must be inverted to be the - * correct answer. - * - * Parameters: - * In: - * pbyData - the data stream - * cbByte - the length of the stream - * Out: - * none - * - * Return Value: CRC-32 - * - -*/ -unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC) -{ - return CRCdwCrc32(pbyData, cbByte, dwPreCRC); -} diff --git a/drivers/staging/vt6655/tcrc.h b/drivers/staging/vt6655/tcrc.h deleted file mode 100644 index 82b5ddafae55..000000000000 --- a/drivers/staging/vt6655/tcrc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2003 VIA Networking, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: tcrc.h - * - * Purpose: Implement functions to calculate CRC - * - * Author: Tevin Chen - * - * Date: Jan. 28, 1997 - * - */ - -#ifndef __TCRC_H__ -#define __TCRC_H__ - -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ - -/*--------------------- Export Types ------------------------------*/ - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -unsigned long CRCdwCrc32(unsigned char *pbyData, unsigned int cbByte, unsigned long dwCrcSeed); -unsigned long CRCdwGetCrc32(unsigned char *pbyData, unsigned int cbByte); -unsigned long CRCdwGetCrc32Ex(unsigned char *pbyData, unsigned int cbByte, unsigned long dwPreCRC); - -#endif // __TCRC_H__ -- GitLab From 7910356c7f7645a638ee3ba4b425ecc8c825760e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:45 +0000 Subject: [PATCH 2102/9457] staging: vt6655: dead code remove 80211mgr.c and functions 80211mgr.h header will be removed later Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 1006 ----------------------------- drivers/staging/vt6655/80211mgr.h | 110 ---- drivers/staging/vt6655/Makefile | 1 - 3 files changed, 1117 deletions(-) delete mode 100644 drivers/staging/vt6655/80211mgr.c diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c deleted file mode 100644 index 22ded38e6a2e..000000000000 --- a/drivers/staging/vt6655/80211mgr.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: 80211mgr.c - * - * Purpose: Handles the 802.11 management support functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - * Functions: - * vMgrEncodeBeacon - Encode the Beacon frame - * vMgrDecodeBeacon - Decode the Beacon frame - * vMgrEncodeIBSSATIM - Encode the IBSS ATIM frame - * vMgrDecodeIBSSATIM - Decode the IBSS ATIM frame - * vMgrEncodeDisassociation - Encode the Disassociation frame - * vMgrDecodeDisassociation - Decode the Disassociation frame - * vMgrEncodeAssocRequest - Encode the Association request frame - * vMgrDecodeAssocRequest - Decode the Association request frame - * vMgrEncodeAssocResponse - Encode the Association response frame - * vMgrDecodeAssocResponse - Decode the Association response frame - * vMgrEncodeReAssocRequest - Encode the ReAssociation request frame - * vMgrDecodeReAssocRequest - Decode the ReAssociation request frame - * vMgrEncodeProbeRequest - Encode the Probe request frame - * vMgrDecodeProbeRequest - Decode the Probe request frame - * vMgrEncodeProbeResponse - Encode the Probe response frame - * vMgrDecodeProbeResponse - Decode the Probe response frame - * vMgrEncodeAuthen - Encode the Authentication frame - * vMgrDecodeAuthen - Decode the Authentication frame - * vMgrEncodeDeauthen - Encode the DeAuthentication frame - * vMgrDecodeDeauthen - Decode the DeAuthentication frame - * vMgrEncodeReassocResponse - Encode the Reassociation response frame - * vMgrDecodeReassocResponse - Decode the Reassociation response frame - * - * Revision History: - * - */ - -#include "tmacro.h" -#include "tether.h" -#include "80211mgr.h" -#include "80211hdr.h" -#include "device.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -/*+ - * - * Routine Description: - * Encode Beacon frame body offset - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_CAPINFO); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID; -} - -/*+ - * - * Routine Description: - * Decode Beacon frame body offset - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_BEACON_OFF_CAPINFO); - - /* Information elements */ - pItem = (PWLAN_IE)((unsigned char *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))) + - WLAN_BEACON_OFF_SSID); - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - /* pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; */ - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem; - break; - case WLAN_EID_TIM: - if (pFrame->pTIM == NULL) - pFrame->pTIM = (PWLAN_IE_TIM)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - } - break; - - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: /* 7 */ - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: /* 32 */ - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = - (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: /* 37 */ - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: /* 40 */ - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - pr_debug("Unrecognized EID=%dd in beacon decode\n", - pItem->byElementID); - break; - - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode IBSS ATIM - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; -} - -/*+ - * - * Routine Description: - * Decode IBSS ATIM - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; -} - -/*+ - * - * Routine Description: - * Encode Disassociation - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DISASSOC_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + - sizeof(*(pFrame->pwReason)); -} - -/*+ - * - * Routine Description: - * Decode Disassociation - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DISASSOC_OFF_REASON); -} - -/*+ - * - * Routine Description: - * Encode Association Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_LISTEN_INT); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + - sizeof(*(pFrame->pwListenInterval)); -} - -/*+ - * - * Routine Description: (AP) - * Decode Association Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCREQ_OFF_LISTEN_INT); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_ASSOCREQ_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - } - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - default: - pr_debug("Unrecognized EID=%dd in assocreq decode\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: (AP) - * Encode Association Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_AID); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID + - sizeof(*(pFrame->pwAid)); -} - -/*+ - * - * Routine Description: - * Decode Association Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_AID); - - /* Information elements */ - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_ASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - pr_debug("pFrame->pExtSuppRates=[%p]\n", pItem); - } else { - pFrame->pExtSuppRates = NULL; - } -} - -/*+ - * - * Routine Description: - * Encode Reassociation Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CURR_AP); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + - sizeof(*(pFrame->pAddrCurrAP)); -} - -/*+ - * - * Routine Description: (AP) - * Decode Reassociation Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CAP_INFO); - pFrame->pwListenInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_LISTEN_INT); - pFrame->pAddrCurrAP = (PIEEE_ADDR) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCREQ_OFF_CURR_AP); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_REASSOCREQ_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - } - break; - - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - default: - pr_debug("Unrecognized EID=%dd in reassocreq decode\n", - pItem->byElementID); - break; - } - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Probe Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - pFrame->len = WLAN_HDR_ADDR3_LEN; -} - -/*+ - * - * Routine Description: - * Decode Probe Request - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - default: - pr_debug("Bad EID=%dd in probereq\n", - pItem->byElementID); - break; - } - - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Probe Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_CAP_INFO); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO + - sizeof(*(pFrame->pwCapInfo)); -} - -/*+ - * - * Routine Description: - * Decode Probe Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pqwTimestamp = (__le64 *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_TS); - pFrame->pwBeaconInterval = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_BCN_INT); - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_PROBERESP_OFF_CAP_INFO); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_PROBERESP_OFF_SSID); - - while (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) { - switch (pItem->byElementID) { - case WLAN_EID_SSID: - if (pFrame->pSSID == NULL) - pFrame->pSSID = (PWLAN_IE_SSID)pItem; - break; - case WLAN_EID_SUPP_RATES: - if (pFrame->pSuppRates == NULL) - pFrame->pSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - case WLAN_EID_FH_PARMS: - break; - case WLAN_EID_DS_PARMS: - if (pFrame->pDSParms == NULL) - pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem; - break; - case WLAN_EID_CF_PARMS: - if (pFrame->pCFParms == NULL) - pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem; - break; - case WLAN_EID_IBSS_PARMS: - if (pFrame->pIBSSParms == NULL) - pFrame->pIBSSParms = - (PWLAN_IE_IBSS_PARMS)pItem; - break; - - case WLAN_EID_RSN: - if (pFrame->pRSN == NULL) - pFrame->pRSN = (PWLAN_IE_RSN)pItem; - break; - case WLAN_EID_RSN_WPA: - if (pFrame->pRSNWPA == NULL) { - } - break; - case WLAN_EID_ERP: - if (pFrame->pERP == NULL) - pFrame->pERP = (PWLAN_IE_ERP)pItem; - break; - case WLAN_EID_EXTSUPP_RATES: - if (pFrame->pExtSuppRates == NULL) - pFrame->pExtSuppRates = - (PWLAN_IE_SUPP_RATES)pItem; - break; - - case WLAN_EID_COUNTRY: /* 7 */ - if (pFrame->pIE_Country == NULL) - pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem; - break; - - case WLAN_EID_PWR_CONSTRAINT: /* 32 */ - if (pFrame->pIE_PowerConstraint == NULL) - pFrame->pIE_PowerConstraint = - (PWLAN_IE_PW_CONST)pItem; - break; - - case WLAN_EID_CH_SWITCH: /* 37 */ - if (pFrame->pIE_CHSW == NULL) - pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem; - break; - - case WLAN_EID_QUIET: /* 40 */ - if (pFrame->pIE_Quiet == NULL) - pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem; - break; - - case WLAN_EID_IBSS_DFS: - if (pFrame->pIE_IBSSDFS == NULL) - pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem; - break; - - default: - pr_debug("Bad EID=%dd in proberesp\n", - pItem->byElementID); - break; - } - - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - } -} - -/*+ - * - * Routine Description: - * Encode Authentication frame - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_STATUS); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + - sizeof(*(pFrame->pwStatus)); -} - -/*+ - * - * Routine Description: - * Decode Authentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwAuthAlgorithm = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_ALG); - pFrame->pwAuthSequence = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_AUTH_SEQ); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_AUTHEN_OFF_STATUS); - - /* Information elements */ - pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) - + WLAN_AUTHEN_OFF_CHALLENGE); - - if (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) && - pItem->byElementID == WLAN_EID_CHALLENGE) - pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem; -} - -/*+ - * - * Routine Description: - * Encode Authentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DEAUTHEN_OFF_REASON); - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + - sizeof(*(pFrame->pwReason)); -} - -/*+ - * - * Routine Description: - * Decode Deauthentication - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwReason = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_DEAUTHEN_OFF_REASON); -} - -/*+ - * - * Routine Description: (AP) - * Encode Reassociation Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -) -{ - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_AID); - - pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + - sizeof(*(pFrame->pwAid)); -} - -/*+ - * - * Routine Description: - * Decode Reassociation Response - * - * - * Return Value: - * None. - * - -*/ - -void -vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -) -{ - PWLAN_IE pItem; - - pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; - - /* Fixed Fields */ - pFrame->pwCapInfo = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_CAP_INFO); - pFrame->pwStatus = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_STATUS); - pFrame->pwAid = (unsigned short *) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_AID); - - /* Information elements */ - pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES) - (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + - WLAN_REASSOCRESP_OFF_SUPP_RATES); - - pItem = (PWLAN_IE)(pFrame->pSuppRates); - pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); - - if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && - (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { - pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - } -} diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index d462a8af087b..94cff3b87cb1 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -612,114 +612,4 @@ typedef struct tagWLAN_FR_DEAUTHEN { unsigned short *pwReason; } WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN; -void -vMgrEncodeBeacon( - PWLAN_FR_BEACON pFrame -); - -void -vMgrDecodeBeacon( - PWLAN_FR_BEACON pFrame -); - -void -vMgrEncodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -); - -void -vMgrDecodeIBSSATIM( - PWLAN_FR_IBSSATIM pFrame -); - -void -vMgrEncodeDisassociation( - PWLAN_FR_DISASSOC pFrame -); - -void -vMgrDecodeDisassociation( - PWLAN_FR_DISASSOC pFrame -); - -void -vMgrEncodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -); - -void -vMgrDecodeAssocRequest( - PWLAN_FR_ASSOCREQ pFrame -); - -void -vMgrEncodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -); - -void -vMgrDecodeAssocResponse( - PWLAN_FR_ASSOCRESP pFrame -); - -void -vMgrEncodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -); - -void -vMgrDecodeReassocRequest( - PWLAN_FR_REASSOCREQ pFrame -); - -void -vMgrEncodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -); - -void -vMgrDecodeProbeRequest( - PWLAN_FR_PROBEREQ pFrame -); - -void -vMgrEncodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -); - -void -vMgrDecodeProbeResponse( - PWLAN_FR_PROBERESP pFrame -); - -void -vMgrEncodeAuthen( - PWLAN_FR_AUTHEN pFrame -); - -void -vMgrDecodeAuthen( - PWLAN_FR_AUTHEN pFrame -); - -void -vMgrEncodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -); - -void -vMgrDecodeDeauthen( - PWLAN_FR_DEAUTHEN pFrame -); - -void -vMgrEncodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -); - -void -vMgrDecodeReassocResponse( - PWLAN_FR_REASSOCRESP pFrame -); - #endif/* __80211MGR_H__ */ diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 390c23ef9f44..5f3c0192d0c2 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -8,7 +8,6 @@ vt6655_stage-y += device_main.o \ mac.o \ baseband.o \ wctl.o \ - 80211mgr.o \ rxtx.o \ dpc.o \ power.o \ -- GitLab From b4ba0cb10f5db831f0e7b9bb090411d53e1a9579 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:46 +0000 Subject: [PATCH 2103/9457] staging: vt6655: dead code remove wctl.c/h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/Makefile | 1 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/wctl.c | 233 --------------------------- drivers/staging/vt6655/wctl.h | 105 ------------ 5 files changed, 341 deletions(-) delete mode 100644 drivers/staging/vt6655/wctl.c delete mode 100644 drivers/staging/vt6655/wctl.h diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index 5f3c0192d0c2..115b951bf0d9 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -7,7 +7,6 @@ vt6655_stage-y += device_main.o \ channel.o \ mac.o \ baseband.o \ - wctl.o \ rxtx.o \ dpc.o \ power.o \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 2c2f42fe10af..1111d1eda359 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -60,7 +60,6 @@ #include "mac.h" #include "tether.h" #include "wmgr.h" -#include "wctl.h" #include "power.h" #include "wcmd.h" #include "iocmd.h" diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index b8ff8c60a84a..00ae6de05628 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -55,7 +55,6 @@ #include "bssdb.h" #include "mac.h" #include "baseband.h" -#include "wctl.h" #include "rf.h" /*--------------------- Static Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c deleted file mode 100644 index 5a54d98d985a..000000000000 --- a/drivers/staging/vt6655/wctl.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wctl.c - * - * Purpose: handle WMAC duplicate filter & defragment - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - * Functions: - * WCTLbIsDuplicate - Test if duplicate packet - * WCTLuSearchDFCB - Search DeFragment Control Database - * WCTLuInsertDFCB - Insert DeFragment Control Database - * WCTLbHandleFragment - Handle received fragment packet - * - * Revision History: - * - */ - -#include "wctl.h" -#include "device.h" -#include "card.h" - -/*--------------------- Static Definitions -------------------------*/ - -/*--------------------- Static Classes ----------------------------*/ - -/*--------------------- Static Variables --------------------------*/ - -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/* - * Description: - * Scan Rx cache. Return true if packet is duplicate, else - * inserts in receive cache and returns false. - * - * Parameters: - * In: - * pCache - Receive packets history - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: true if packet duplicate; otherwise false - * - */ - -bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader) -{ - unsigned int uIndex; - unsigned int ii; - PSCacheEntry pCacheEntry; - - if (IS_FC_RETRY(pMACHeader)) { - uIndex = pCache->uInPtr; - for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) { - pCacheEntry = &(pCache->asCacheEntry[uIndex]); - if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) && - ether_addr_equal(pCacheEntry->abyAddr2, - pMACHeader->abyAddr2)) { - /* Duplicate match */ - return true; - } - ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); - } - } - /* Not fount in cache - insert */ - pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; - pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; - memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); - return false; -} - -/* - * Description: - * Found if sequence number of received fragment packet in Defragment Database - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: index number in Defragment Database - * - */ -unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice, - PS802_11Header pMACHeader) -{ - unsigned int ii; - - for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if (pDevice->sRxDFCB[ii].bInUse && - ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2, - pMACHeader->abyAddr2)) { - return ii; - } - } - return pDevice->cbDFCB; -} - -/* - * Description: - * Insert received fragment packet in Defragment Database - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * Out: - * none - * - * Return Value: index number in Defragment Database - * - */ -unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice, PS802_11Header pMACHeader) -{ - unsigned int ii; - - if (pDevice->cbFreeDFCB == 0) - return pDevice->cbDFCB; - for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if (!pDevice->sRxDFCB[ii].bInUse) { - pDevice->cbFreeDFCB--; - pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[ii].bInUse = true; - pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); - return ii; - } - } - return pDevice->cbDFCB; -} - -/* - * Description: - * Handle received fragment packet - * - * Parameters: - * In: - * pDevice - Pointer to adapter - * pMACHeader - 802.11 MAC Header of received packet - * cbFrameLength - Frame length - * bWEP - is WEP packet - * Out: - * none - * - * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false - * - */ -bool WCTLbHandleFragment(struct vnt_private *pDevice, PS802_11Header pMACHeader, - unsigned int cbFrameLength, bool bWEP, bool bExtIV) -{ - unsigned int uHeaderSize; - - if (bWEP) { - uHeaderSize = 28; - if (bExtIV) - // ExtIV - uHeaderSize += 4; - } else { - uHeaderSize = 24; - } - - if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) { - // duplicate, we must flush previous DCB - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - } else { - pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) - return false; - } - // reserve 4 byte to match MAC RX Buffer - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (unsigned char *)(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - return false; - } else { - pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); - if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) { - if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) && - (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) && - ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { - memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((unsigned char *)(pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; - } else { - // seq error or frag # error flush DFCB - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - return false; - } - } else { - return false; - } - if (IS_LAST_FRAGMENT_PKT(pMACHeader)) { - //enq defragcontrolblock - pDevice->cbFreeDFCB++; - pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; - return true; - } - return false; - } -} diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h deleted file mode 100644 index f0995d86f71f..000000000000 --- a/drivers/staging/vt6655/wctl.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wctl.h - * - * Purpose: - * - * Author: Jerry Chen - * - * Date: Jun. 27, 2002 - * - */ - -#ifndef __WCTL_H__ -#define __WCTL_H__ - -#include "ttype.h" -#include "tether.h" -#include "device.h" - -/*--------------------- Export Definitions -------------------------*/ - -#define IS_TYPE_DATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA) - -#define IS_TYPE_MGMT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT) - -#define IS_TYPE_CONTROL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL) - -#define IS_FC_MOREDATA(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA) - -#define IS_FC_POWERMGT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT) - -#define IS_FC_RETRY(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY) - -#define IS_FC_WEP(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP) - -#ifdef __BIG_ENDIAN - -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0)) - -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0) - -#else - -#define IS_FRAGMENT_PKT(pMACHeader) \ - (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) | \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0)) - -#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0) - -#endif//#ifdef __BIG_ENDIAN - -#define IS_LAST_FRAGMENT_PKT(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0) - -#define IS_CTL_PSPOLL(pMACHeader) \ - ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) - -#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) \ -do { \ - if ((uVar) >= ((uModulo) - 1)) \ - (uVar) = 0; \ - else \ - (uVar)++; \ -} while (0) - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader); -bool WCTLbHandleFragment(struct vnt_private *, PS802_11Header pMACHeader, - unsigned int cbFrameLength, bool bWEP, bool bExtIV); -unsigned int WCTLuSearchDFCB(struct vnt_private *, PS802_11Header pMACHeader); -unsigned int WCTLuInsertDFCB(struct vnt_private *, PS802_11Header pMACHeader); - -#endif // __WCTL_H__ -- GitLab From d40c444668657b3467283ec6888276788ed88155 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:47 +0000 Subject: [PATCH 2104/9457] staging: vt6655: channel.c remove dead functions Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 113 ------------------------------- drivers/staging/vt6655/channel.h | 13 ---- 2 files changed, 126 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index a7b39d4c18c5..41146eb113ef 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -166,66 +166,6 @@ void vnt_init_bands(struct vnt_private *priv) } } -/** - * is_channel_valid() - Is Country Channel Valid - * @ChanneIndex: defined as VT3253 MAC channel: - * 1 = 2.4G channel 1 - * 2 = 2.4G channel 2 - * ... - * 14 = 2.4G channel 14 - * 15 = 4.9G channel 183 - * 16 = 4.9G channel 184 - * ..... - * Output: true if the specified 5GHz band is allowed to be used, - * false otherwise. - * 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22) - * - * 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64, - * 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) - */ - -bool is_channel_valid(unsigned int ChannelIndex) -{ - bool bValid; - - bValid = false; - /* If Channel Index is invalid, return invalid */ - if ((ChannelIndex > CB_MAX_CHANNEL) || - (ChannelIndex == 0)) { - bValid = false; - goto exit; - } -exit: - return bValid; -} - -/** - * channel_get_list() - Get Available Channel List for a given country - * @CountryCode: The country code defined in country.h - * - * Output: - * pbyChannelTable: (QWORD *) correspondent bit mask - * of available channels - * 0x0000000000000001 means channel 1 is supported - * 0x0000000000000003 means channel 1,2 are supported - * 0x000000000000000F means channel 1,2,..15 are supported - */ - -bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable) -{ - return true; -} - -unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType) -{ - return 0; -} - -unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex) -{ - return 0; -} - /** * set_channel() - Set NIC media channel * @@ -277,56 +217,3 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) return bResult; } - -/** - * set_country_info() - Set Channel Info of Country - * - * Return Value: none. - * - */ - -void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) -{ -} - -/** - * - * set_support_channels() - Set Support Channels IE defined in 802.11h - * - * @hDeviceContext: device structure point - * - * Return Value: none. - * - */ - -unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) -{ - unsigned char byLen = 0; - return byLen; -} - -void set_country_IE(void *pDeviceHandler, void *pIE) -{ -} - -bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap) -{ - return 0; -} - -void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap) -{ -} - -void clear_channel_map_info(void *pDeviceHandler) -{ - -} - -unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) -{ - unsigned char byOptionChannel = 0; - return byOptionChannel; -} diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 78ab642738ed..ee00f4e3d52f 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -28,19 +28,6 @@ void vnt_init_bands(struct vnt_private *); -bool is_channel_valid(unsigned int CountryCode); -unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType); -bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTable); -unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIndex); bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel); -void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE); -unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs); -void set_country_IE(void *pDeviceHandler, void *pIE); -bool get_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char *pbyChannelNumber, unsigned char *pbyMap); -void set_channel_map_info(void *pDeviceHandler, unsigned int uChannelIndex, - unsigned char byMap); -void clear_channel_map_info(void *pDeviceHandler); -unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType); #endif /* _CHANNEL_H_ */ -- GitLab From b0437f281ddc82b7ba421de304ec531dc5daea0c Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:48 +0000 Subject: [PATCH 2105/9457] staging: vt6655: move all RATE_* macros to device.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 15 +++++++++++++++ drivers/staging/vt6655/vntwifi.h | 14 -------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index a5e5a00743c6..b96d8328b466 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -80,6 +80,21 @@ /*--------------------- Export Definitions -------------------------*/ +#define RATE_1M 0 +#define RATE_2M 1 +#define RATE_5M 2 +#define RATE_11M 3 +#define RATE_6M 4 +#define RATE_9M 5 +#define RATE_12M 6 +#define RATE_18M 7 +#define RATE_24M 8 +#define RATE_36M 9 +#define RATE_48M 10 +#define RATE_54M 11 +#define RATE_AUTO 12 +#define MAX_RATE 12 + #define MAC_MAX_CONTEXT_REG (256+128) #define MAX_MULTICAST_ADDRESS_NUM 32 diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index ad180e077e3f..2ba7713d04a7 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -35,20 +35,6 @@ #include "card.h" /*--------------------- Export Definitions -------------------------*/ -#define RATE_1M 0 -#define RATE_2M 1 -#define RATE_5M 2 -#define RATE_11M 3 -#define RATE_6M 4 -#define RATE_9M 5 -#define RATE_12M 6 -#define RATE_18M 7 -#define RATE_24M 8 -#define RATE_36M 9 -#define RATE_48M 10 -#define RATE_54M 11 -#define RATE_AUTO 12 -#define MAX_RATE 12 // key CipherSuite #define KEY_CTL_WEP 0x00 -- GitLab From 8ec94797eb3aba4346fbc1c1f3181e8b6f9f21f9 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:49 +0000 Subject: [PATCH 2106/9457] staging: vt6655: dead code remove vntwifi.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 1 - drivers/staging/vt6655/device_main.c | 2 - drivers/staging/vt6655/vntwifi.h | 90 ---------------------------- drivers/staging/vt6655/wmgr.h | 5 -- 4 files changed, 98 deletions(-) delete mode 100644 drivers/staging/vt6655/vntwifi.h diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index b96d8328b466..5e48608a8744 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -507,7 +507,6 @@ struct vnt_private { bool bEnablePSMode; unsigned short wListenInterval; bool bPWBitOn; - WMAC_POWER_MODE ePSMode; /* GPIO Radio Control */ unsigned char byRadioCtl; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 1111d1eda359..d8fd44c88206 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -344,7 +344,6 @@ device_set_options(struct vnt_private *pDevice) pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME; pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0; pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0; - pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0; pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0; pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0; pDevice->uConnectionRate = pDevice->sOpts.data_rate; @@ -359,7 +358,6 @@ device_set_options(struct vnt_private *pDevice) pr_debug(" uChannel= %d\n", (int)pDevice->uChannel); pr_debug(" byOpMode= %d\n", (int)pDevice->byOpMode); - pr_debug(" ePSMode= %d\n", (int)pDevice->ePSMode); pr_debug(" wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold); pr_debug(" byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit); pr_debug(" byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit); diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h deleted file mode 100644 index 2ba7713d04a7..000000000000 --- a/drivers/staging/vt6655/vntwifi.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: vntwifi.h - * - * Purpose: export VNT Host WiFi library function - * - * Author: Yiching Chen - * - * Date: Jan 7, 2004 - * - */ - -#ifndef __VNTWIFI_H__ -#define __VNTWIFI_H__ - -#include "ttype.h" -#include "80211mgr.h" -#include "card.h" - -/*--------------------- Export Definitions -------------------------*/ - -// key CipherSuite -#define KEY_CTL_WEP 0x00 -#define KEY_CTL_NONE 0x01 -#define KEY_CTL_TKIP 0x02 -#define KEY_CTL_CCMP 0x03 -#define KEY_CTL_INVALID 0xFF - -#define CHANNEL_MAX_24G 14 - -#define MAX_BSS_NUM 42 - -// Pre-configured Authenticaiton Mode (from XP) -typedef enum tagWMAC_AUTHENTICATION_MODE { - WMAC_AUTH_OPEN, - WMAC_AUTH_SHAREKEY, - WMAC_AUTH_AUTO, - WMAC_AUTH_WPA, - WMAC_AUTH_WPAPSK, - WMAC_AUTH_WPANONE, - WMAC_AUTH_WPA2, - WMAC_AUTH_WPA2PSK, - WMAC_AUTH_MAX // Not a real mode, defined as upper bound -} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE; - -typedef enum tagWMAC_ENCRYPTION_MODE { - WMAC_ENCRYPTION_WEPEnabled, - WMAC_ENCRYPTION_WEPDisabled, - WMAC_ENCRYPTION_WEPKeyAbsent, - WMAC_ENCRYPTION_WEPNotSupported, - WMAC_ENCRYPTION_TKIPEnabled, - WMAC_ENCRYPTION_TKIPKeyAbsent, - WMAC_ENCRYPTION_AESEnabled, - WMAC_ENCRYPTION_AESKeyAbsent -} WMAC_ENCRYPTION_MODE, *PWMAC_ENCRYPTION_MODE; - -// Pre-configured Mode (from XP) - -typedef enum tagWMAC_CONFIG_MODE { - WMAC_CONFIG_ESS_STA = 0, - WMAC_CONFIG_IBSS_STA, - WMAC_CONFIG_AUTO, - WMAC_CONFIG_AP -} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE; - -typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX -} WMAC_POWER_MODE, *PWMAC_POWER_MODE; - - -#endif //__VNTWIFI_H__ diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 7df62bb6eafd..ecbb8d4b3154 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -39,7 +39,6 @@ #include "80211hdr.h" #include "wcmd.h" #include "bssdb.h" -#include "vntwifi.h" #include "card.h" /*--------------------- Export Definitions -------------------------*/ @@ -189,7 +188,6 @@ typedef struct tagSMgmtObject { unsigned char abyMACAddr[WLAN_ADDR_LEN]; // Configuration Mode - WMAC_CONFIG_MODE eConfigMode; // MAC pre-configed mode CARD_PHY_TYPE eCurrentPHYMode; CARD_PHY_TYPE eConfigPHYMode; @@ -245,8 +243,6 @@ typedef struct tagSMgmtObject { unsigned char abyScanBSSID[WLAN_BSSID_LEN]; // Privacy - WMAC_AUTHENTICATION_MODE eAuthenMode; - WMAC_ENCRYPTION_MODE eEncryptionMode; bool bShareKeyAlgorithm; unsigned char abyChallenge[WLAN_CHALLENGE_LEN]; bool bPrivacyInvoked; @@ -258,7 +254,6 @@ typedef struct tagSMgmtObject { unsigned char byDTIMPeriod; // Power saving state vars - WMAC_POWER_MODE ePSMode; unsigned short wListenInterval; unsigned short wCountToWakeUp; bool bInTIMWake; -- GitLab From ab2eb50af8ce07b2f81ccd30bd08ae67c5b614b0 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:50 +0000 Subject: [PATCH 2107/9457] staging: vt6655: wmgr.h remove management structures Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 5 - drivers/staging/vt6655/wmgr.h | 194 -------------------------------- 2 files changed, 199 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 5e48608a8744..d2779a30a23b 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -426,11 +426,6 @@ struct vnt_private { /* 802.11 counter */ SDot11Counters s802_11Counter; - /* 802.11 management */ - PSMgmtObject pMgmt; - SMgmtObject sMgmtObj; - - /* 802.11 MAC specific */ unsigned int uCurrRSSI; unsigned char byCurrSQ; diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index ecbb8d4b3154..1deedd8fbe77 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -112,199 +112,5 @@ typedef struct tagSAssocInfo { unsigned long RequestIELength; unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN]; } SAssocInfo, *PSAssocInfo; -//--- - -typedef enum tagWMAC_SCAN_TYPE { - WMAC_SCAN_ACTIVE, - WMAC_SCAN_PASSIVE, - WMAC_SCAN_HYBRID -} WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE; - -typedef enum tagWMAC_SCAN_STATE { - WMAC_NO_SCANNING, - WMAC_IS_SCANNING, - WMAC_IS_PROBEPENDING -} WMAC_SCAN_STATE, *PWMAC_SCAN_STATE; - -// Notes: -// Basic Service Set state explained as following: -// WMAC_STATE_IDLE : no BSS is selected (Adhoc or Infra) -// WMAC_STATE_STARTED : no BSS is selected, start own IBSS (Adhoc only) -// WMAC_STATE_JOINTED : BSS is selected and synchronized (Adhoc or Infra) -// WMAC_STATE_AUTHPENDING : Authentication pending (Infra) -// WMAC_STATE_AUTH : Authenticated (Infra) -// WMAC_STATE_ASSOCPENDING : Association pending (Infra) -// WMAC_STATE_ASSOC : Associated (Infra) - -typedef enum tagWMAC_BSS_STATE { - WMAC_STATE_IDLE, - WMAC_STATE_STARTED, - WMAC_STATE_JOINTED, - WMAC_STATE_AUTHPENDING, - WMAC_STATE_AUTH, - WMAC_STATE_ASSOCPENDING, - WMAC_STATE_ASSOC -} WMAC_BSS_STATE, *PWMAC_BSS_STATE; - -// WMAC selected running mode -typedef enum tagWMAC_CURRENT_MODE { - WMAC_MODE_STANDBY, - WMAC_MODE_ESS_STA, - WMAC_MODE_IBSS_STA, - WMAC_MODE_ESS_AP -} WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE; - -/* - typedef enum tagWMAC_POWER_MODE { - WMAC_POWER_CAM, - WMAC_POWER_FAST, - WMAC_POWER_MAX - - } WMAC_POWER_MODE, *PWMAC_POWER_MODE; -*/ - -// Tx Management Packet descriptor -typedef struct tagSTxMgmtPacket { - PUWLAN_80211HDR p80211Header; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; -} STxMgmtPacket, *PSTxMgmtPacket; - -// Rx Management Packet descriptor -typedef struct tagSRxMgmtPacket { - PUWLAN_80211HDR p80211Header; - u64 qwLocalTSF; - unsigned int cbMPDULen; - unsigned int cbPayloadLen; - unsigned int uRSSI; - unsigned char bySQ; - unsigned char byRxRate; - unsigned char byRxChannel; -} SRxMgmtPacket, *PSRxMgmtPacket; - -typedef struct tagSMgmtObject { - void *pAdapter; - // MAC address - unsigned char abyMACAddr[WLAN_ADDR_LEN]; - - // Configuration Mode - CARD_PHY_TYPE eCurrentPHYMode; - CARD_PHY_TYPE eConfigPHYMode; - - // Operation state variables - WMAC_CURRENT_MODE eCurrMode; // MAC current connection mode - WMAC_BSS_STATE eCurrState; // MAC current BSS state - - PKnownBSS pCurrBSS; - unsigned char byCSSGK; - unsigned char byCSSPK; - - // Current state vars - unsigned int uCurrChannel; - unsigned char abyCurrBSSID[WLAN_BSSID_LEN]; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned short wCurrCapInfo; - unsigned short wCurrAID; - unsigned short wCurrATIMWindow; - unsigned short wCurrBeaconPeriod; - bool bIsDS; - unsigned char byERPContext; - - CMD_STATE eCommandState; - unsigned int uScanChannel; - - // Desire joining BSS vars - unsigned char abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyDesireBSSID[WLAN_BSSID_LEN]; - - // Adhoc or AP configuration vars - unsigned short wIBSSBeaconPeriod; - unsigned short wIBSSATIMWindow; - unsigned int uIBSSChannel; - unsigned char abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char byAPBBType; - unsigned char abyWPAIE[MAX_WPA_IE_LEN]; - unsigned short wWPAIELen; - - unsigned int uAssocCount; - bool bMoreData; - - // Scan state vars - WMAC_SCAN_STATE eScanState; - WMAC_SCAN_TYPE eScanType; - unsigned int uScanStartCh; - unsigned int uScanEndCh; - unsigned short wScanSteps; - unsigned int uScanBSSType; - // Desire scanning vars - unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char abyScanBSSID[WLAN_BSSID_LEN]; - - // Privacy - bool bShareKeyAlgorithm; - unsigned char abyChallenge[WLAN_CHALLENGE_LEN]; - bool bPrivacyInvoked; - - // Received beacon state vars - bool bInTIM; - bool bMulticastTIM; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - - // Power saving state vars - unsigned short wListenInterval; - unsigned short wCountToWakeUp; - bool bInTIMWake; - unsigned char *pbyPSPacketPool; - unsigned char byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN]; - bool bRxBeaconInTBTTWake; - unsigned char abyPSTxMap[MAX_NODE_NUM + 1]; - - // management command related - unsigned int uCmdBusy; - unsigned int uCmdHostAPBusy; - - // management packet pool - unsigned char *pbyMgmtPacketPool; - unsigned char byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - - // One second callback timer - struct timer_list sTimerSecondCallback; - - // Temporarily Rx Mgmt Packet Descriptor - SRxMgmtPacket sRxPacket; - - // link list of known bss's (scan results) - KnownBSS sBSSList[MAX_BSS_NUM]; - - // table list of known node - // sNodeDBList[0] is reserved for AP under Infra mode - // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode - KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1]; - - // WPA2 PMKID Cache - bool bRoaming; - - // rate fall back vars - - // associate info - SAssocInfo sAssocInfo; - - // for 802.11h - bool b11hEnable; - bool bSwitchChannel; - unsigned char byNewChannel; - PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; - unsigned int uLengthOfRepEIDs; - unsigned char abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; - unsigned char abyIECountry[WLAN_A3FR_MAXLEN]; - unsigned char abyIBSSDFSOwner[6]; - unsigned char byIBSSDFSRecovery; - - struct sk_buff skb; -} SMgmtObject, *PSMgmtObject; #endif // __WMGR_H__ -- GitLab From 38ad4a00eb716da05859288e5ee1cee629ea02b2 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:51 +0000 Subject: [PATCH 2108/9457] staging: vt6655: dead code remove ndis and pmkid strutures. struct pmkid_candidate typedef struct _BSSID_INFO typedef struct tagSPMKID typedef struct tagSPMKIDCandidateEvent NDIS_802_11_MAC_ADDRESS typedef struct _NDIS_802_11_AI_REQFI typedef struct _NDIS_802_11_AI_RESFI typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION typedef struct tagSAssocInfo Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 26 ------------------------ drivers/staging/vt6655/wmgr.h | 35 --------------------------------- 2 files changed, 61 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index d2779a30a23b..0725d783d322 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -216,29 +216,6 @@ typedef enum _NDIS_802_11_STATUS_TYPE { Ndis802_11StatusTypeMax /* defined as an upper bound */ } NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; -/* Added new types for PMKID Candidate lists. */ -struct pmkid_candidate { - NDIS_802_11_MAC_ADDRESS BSSID; - unsigned long Flags; -}; - -typedef struct _BSSID_INFO { - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_PMKID_VALUE PMKID; -} BSSID_INFO, *PBSSID_INFO; - -typedef struct tagSPMKID { - unsigned long Length; - unsigned long BSSIDInfoCount; - BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID]; -} SPMKID, *PSPMKID; - -typedef struct tagSPMKIDCandidateEvent { - NDIS_802_11_STATUS_TYPE StatusType; - unsigned long Version; /* Version of the structure */ - unsigned long NumCandidates; /* No. of pmkid candidates */ - struct pmkid_candidate CandidateList[MAX_PMKIDLIST]; -} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent; /* 802.11h related */ #define MAX_QUIET_COUNT 8 @@ -667,9 +644,6 @@ struct vnt_private { unsigned char abySNAP_RFC1042[ETH_ALEN]; unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */ - /* Pre-Authentication & PMK cache */ - SPMKID gsPMKID; - SPMKIDCandidateEvent gsPMKIDCandidate; /* for 802.11h */ bool b11hEnable; diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 1deedd8fbe77..cc8662e52718 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -78,39 +78,4 @@ #define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick)) typedef void (*TimerFunction)(unsigned long); -//+++ NDIS related - -typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; -typedef struct _NDIS_802_11_AI_REQFI { - unsigned short Capabilities; - unsigned short ListenInterval; - NDIS_802_11_MAC_ADDRESS CurrentAPAddress; -} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; - -typedef struct _NDIS_802_11_AI_RESFI { - unsigned short Capabilities; - unsigned short StatusCode; - unsigned short AssociationId; -} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; - -typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION { - unsigned long Length; - unsigned short AvailableRequestFixedIEs; - NDIS_802_11_AI_REQFI RequestFixedIEs; - unsigned long RequestIELength; - unsigned long OffsetRequestIEs; - unsigned short AvailableResponseFixedIEs; - NDIS_802_11_AI_RESFI ResponseFixedIEs; - unsigned long ResponseIELength; - unsigned long OffsetResponseIEs; -} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; - -typedef struct tagSAssocInfo { - NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; - unsigned char abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; - // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION - unsigned long RequestIELength; - unsigned char abyReqIEs[WLAN_BEACON_FR_MAXLEN]; -} SAssocInfo, *PSAssocInfo; - #endif // __WMGR_H__ -- GitLab From 37cc22b1c4a542181db7b827136bcf63118d1346 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:52 +0000 Subject: [PATCH 2109/9457] staging: vt6655: dead remove wcmd.h and typedefs CMD_STATE CMD_CODE CMD_ITEM Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 5 -- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/power.c | 1 - drivers/staging/vt6655/rxtx.h | 1 - drivers/staging/vt6655/wcmd.h | 91 ---------------------------- drivers/staging/vt6655/wmgr.h | 1 - 6 files changed, 100 deletions(-) delete mode 100644 drivers/staging/vt6655/wcmd.h diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 0725d783d322..f73239fdc665 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -71,7 +71,6 @@ #include "80211hdr.h" #include "tether.h" #include "wmgr.h" -#include "wcmd.h" #include "mib.h" #include "srom.h" #include "desc.h" @@ -498,9 +497,6 @@ struct vnt_private { unsigned char byCurrentCh; unsigned int uScanTime; - CMD_STATE eCommandState; - - CMD_CODE eCommand; bool bBeaconTx; bool bStopBeacon; @@ -510,7 +506,6 @@ struct vnt_private { /* 802.11 counter */ - CMD_ITEM eCmdQueue[CMD_Q_SIZE]; unsigned int uCmdDequeueIdx; unsigned int uCmdEnqueueIdx; unsigned int cbFreeCmdQueue; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index d8fd44c88206..80bbe1dda05b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -61,7 +61,6 @@ #include "tether.h" #include "wmgr.h" #include "power.h" -#include "wcmd.h" #include "iocmd.h" #include "rxtx.h" #include "bssdb.h" diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 040484e204e3..6f83650db5a3 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -42,7 +42,6 @@ #include "device.h" #include "wmgr.h" #include "power.h" -#include "wcmd.h" #include "card.h" /*--------------------- Static Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 7b0566ce42a7..50d77a0f88ea 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -31,7 +31,6 @@ #include "ttype.h" #include "device.h" -#include "wcmd.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h deleted file mode 100644 index ae7ddeaeb014..000000000000 --- a/drivers/staging/vt6655/wcmd.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: wcmd.h - * - * Purpose: Handles the management command interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __WCMD_H__ -#define __WCMD_H__ - -#include "ttype.h" -#include "80211hdr.h" -#include "80211mgr.h" - -#define AUTHENTICATE_TIMEOUT 1000 -#define ASSOCIATE_TIMEOUT 1000 - -typedef enum tagCMD_CODE { - WLAN_CMD_BSSID_SCAN, - WLAN_CMD_SSID, - WLAN_CMD_DISASSOCIATE, - WLAN_CMD_DEAUTH, - WLAN_CMD_RX_PSPOLL, - WLAN_CMD_RADIO, - WLAN_CMD_CHANGE_BBSENSITIVITY, - WLAN_CMD_SETPOWER, - WLAN_CMD_TBTT_WAKEUP, - WLAN_CMD_BECON_SEND, - WLAN_CMD_CHANGE_ANTENNA, - WLAN_CMD_REMOVE_ALLKEY, - WLAN_CMD_MAC_DISPOWERSAVING, - WLAN_CMD_11H_CHSW, - WLAN_CMD_RUN_AP -} CMD_CODE, *PCMD_CODE; - -#define CMD_Q_SIZE 32 - -typedef enum tagCMD_STATUS { - CMD_STATUS_SUCCESS = 0, - CMD_STATUS_FAILURE, - CMD_STATUS_RESOURCES, - CMD_STATUS_TIMEOUT, - CMD_STATUS_PENDING -} CMD_STATUS, *PCMD_STATUS; - -typedef struct tagCMD_ITEM { - CMD_CODE eCmd; - unsigned char abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - bool bNeedRadioOFF; - unsigned short wDeAuthenReason; - bool bRadioCmd; - bool bForceSCAN; -} CMD_ITEM, *PCMD_ITEM; - -typedef enum tagCMD_STATE { - WLAN_CMD_SCAN_START, - WLAN_CMD_SCAN_END, - WLAN_CMD_DISASSOCIATE_START, - WLAN_CMD_SSID_START, - WLAN_AUTHENTICATE_WAIT, - WLAN_ASSOCIATE_WAIT, - WLAN_DISASSOCIATE_WAIT, - WLAN_CMD_TX_PSPACKET_START, - WLAN_CMD_AP_MODE_START, - WLAN_CMD_RADIO_START, - WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE, - WLAN_CMD_IDLE -} CMD_STATE, *PCMD_STATE; - -#endif //__WCMD_H__ diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index cc8662e52718..0e6a6f039aa1 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -37,7 +37,6 @@ #include "ttype.h" #include "80211mgr.h" #include "80211hdr.h" -#include "wcmd.h" #include "bssdb.h" #include "card.h" -- GitLab From d853ce22915ce8ac33695cea2f02ea38a9d38bc7 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:53 +0000 Subject: [PATCH 2110/9457] staging: vt6655: dead code remove bssdb.h header Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/bssdb.h | 210 --------------------------- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/wmgr.h | 1 - 4 files changed, 213 deletions(-) delete mode 100644 drivers/staging/vt6655/bssdb.h diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h deleted file mode 100644 index 511b7f907953..000000000000 --- a/drivers/staging/vt6655/bssdb.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: bssdb.h - * - * Purpose: Handles the Basic Service Set & Node Database functions - * - * Author: Lyndon Chen - * - * Date: July 16, 2002 - * - */ - -#ifndef __BSSDB_H__ -#define __BSSDB_H__ - -#include -#include "80211hdr.h" -#include "80211mgr.h" -#include "card.h" - -#define MAX_NODE_NUM 64 -#define MAX_BSS_NUM 42 -#define LOST_BEACON_COUNT 10 /* 10 sec, XP defined */ -#define MAX_PS_TX_BUF 32 /* sta max power saving tx buf */ -#define ADHOC_LOST_BEACON_COUNT 30 /* 30 sec, beacon lost for adhoc only */ -#define MAX_INACTIVE_COUNT 300 /* 300 sec, inactive STA node refresh */ - -#define USE_PROTECT_PERIOD 10 /*10 sec, Use protect mode check period*/ -#define ERP_RECOVER_COUNT 30 /* 30 sec, ERP support callback check */ -#define BSS_CLEAR_COUNT 1 - -#define RSSI_STAT_COUNT 10 -#define MAX_CHECK_RSSI_COUNT 8 - -/* STA dwflags */ -#define WLAN_STA_AUTH BIT0 -#define WLAN_STA_ASSOC BIT1 -#define WLAN_STA_PS BIT2 -#define WLAN_STA_TIM BIT3 -/* permanent; do not remove entry on expiration */ -#define WLAN_STA_PERM BIT4 -/* - * If 802.1X is used, this flag is controlling whether STA is authorized - * to send and receive non-IEEE 802.1X frames - */ -#define WLAN_STA_AUTHORIZED BIT5 - -#define MAX_RATE 12 - -#define MAX_WPA_IE_LEN 64 - -/* IEEE 802.11 Structures and definitions */ - -typedef enum _NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax /* defined as an upper bound */ -} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; - -typedef struct tagSERPObject { - bool bERPExist; - unsigned char byERP; -} ERPObject, *PERPObject; - -typedef struct tagSRSNCapObject { - bool bRSNCapExist; - unsigned short wRSNCap; -} SRSNCapObject, *PSRSNCapObject; - -/* BSS info(AP) */ -#pragma pack(1) -typedef struct tagKnownBSS { - bool bActive; - unsigned char abyBSSID[WLAN_BSSID_LEN]; - unsigned int uChannel; - unsigned char abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned char abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - unsigned int uRSSI; - unsigned char bySQ; - unsigned short wBeaconInterval; - unsigned short wCapInfo; - unsigned char abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - unsigned char byRxRate; - - unsigned char byRSSIStatCnt; - long ldBmMAX; - long ldBmAverage[RSSI_STAT_COUNT]; - long ldBmAverRange; - bool bSelected; - - bool bWPAValid; - unsigned char byGKType; - unsigned char abyPKType[4]; - unsigned short wPKCount; - unsigned char abyAuthType[4]; - unsigned short wAuthCount; - unsigned char byDefaultK_as_PK; - unsigned char byReplayIdx; - - bool bWPA2Valid; - unsigned char byCSSGK; - unsigned short wCSSPKCount; - unsigned char abyCSSPK[4]; - unsigned short wAKMSSAuthCount; - unsigned char abyAKMSSAuthType[4]; - - unsigned char byWPAIE[MAX_WPA_IE_LEN]; - unsigned char byRSNIE[MAX_WPA_IE_LEN]; - unsigned short wWPALen; - unsigned short wRSNLen; - - unsigned int uClearCount; - unsigned int uIELength; - u64 qwBSSTimestamp; - u64 qwLocalTSF; - - CARD_PHY_TYPE eNetworkTypeInUse; - - ERPObject sERP; - SRSNCapObject sRSNCapObj; - unsigned char abyIEs[1024]; -} __attribute__ ((__packed__)) -KnownBSS , *PKnownBSS; - -#pragma pack() - -typedef enum tagNODE_STATE { - NODE_FREE, - NODE_AGED, - NODE_KNOWN, - NODE_AUTH, - NODE_ASSOC -} NODE_STATE, *PNODE_STATE; - -/* STA node info */ -typedef struct tagKnownNodeDB { - bool bActive; - unsigned char abyMACAddr[WLAN_ADDR_LEN]; - unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN]; - unsigned short wTxDataRate; - bool bShortPreamble; - bool bERPExist; - bool bShortSlotTime; - unsigned int uInActiveCount; - unsigned short wMaxBasicRate; /* Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. */ - unsigned short wMaxSuppRate; /* Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. */ - unsigned short wSuppRate; - unsigned char byTopOFDMBasicRate; /* Records the highest basic rate in OFDM mode */ - unsigned char byTopCCKBasicRate; /* Records the highest basic rate in CCK mode */ - - /* For AP mode */ - struct sk_buff_head sTxPSQueue; - unsigned short wCapInfo; - unsigned short wListenInterval; - unsigned short wAID; - NODE_STATE eNodeState; - bool bPSEnable; - bool bRxPSPoll; - unsigned char byAuthSequence; - unsigned long ulLastRxJiffer; - unsigned char bySuppRate; - unsigned long dwFlags; - unsigned short wEnQueueCnt; - - bool bOnFly; - unsigned long long KeyRSC; - unsigned char byKeyIndex; - unsigned long dwKeyIndex; - unsigned char byCipherSuite; - unsigned long dwTSC47_16; - unsigned short wTSC15_0; - unsigned int uWepKeyLength; - unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN]; - /* Auto rate fallback vars */ - bool bIsInFallback; - unsigned int uAverageRSSI; - unsigned int uRateRecoveryTimeout; - unsigned int uRatePollTimeout; - unsigned int uTxFailures; - unsigned int uTxAttempts; - - unsigned int uTxRetry; - unsigned int uFailureRatio; - unsigned int uRetryRatio; - unsigned int uTxOk[MAX_RATE+1]; - unsigned int uTxFail[MAX_RATE+1]; - unsigned int uTimeCount; -} KnownNodeDB, *PKnownNodeDB; - -#endif /*__BSSDB_H__ */ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 80bbe1dda05b..dfaec046ef51 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -63,7 +63,6 @@ #include "power.h" #include "iocmd.h" #include "rxtx.h" -#include "bssdb.h" #include "dpc.h" #include "rf.h" #include "iowpa.h" diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 00ae6de05628..246a250cbb95 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -52,7 +52,6 @@ #include "rxtx.h" #include "tether.h" #include "card.h" -#include "bssdb.h" #include "mac.h" #include "baseband.h" #include "rf.h" diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 0e6a6f039aa1..9e983f6da41d 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -37,7 +37,6 @@ #include "ttype.h" #include "80211mgr.h" #include "80211hdr.h" -#include "bssdb.h" #include "card.h" /*--------------------- Export Definitions -------------------------*/ -- GitLab From d54435d3fb278e90f65f6033adbee89b23113229 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:54 +0000 Subject: [PATCH 2111/9457] staging: vt6655: dead code remove tether.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 1 - drivers/staging/vt6655/baseband.h | 1 - drivers/staging/vt6655/desc.h | 1 - drivers/staging/vt6655/device.h | 3 - drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/key.h | 1 - drivers/staging/vt6655/mac.c | 1 - drivers/staging/vt6655/mib.h | 1 - drivers/staging/vt6655/rxtx.c | 1 - drivers/staging/vt6655/srom.c | 1 - drivers/staging/vt6655/tether.h | 188 --------------------------- 11 files changed, 200 deletions(-) delete mode 100644 drivers/staging/vt6655/tether.h diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index c7ad927084d7..ed7850558c96 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -50,7 +50,6 @@ */ #include "tmacro.h" -#include "tether.h" #include "mac.h" #include "baseband.h" #include "srom.h" diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 31f2255519cf..2d7a3e236fd6 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -31,7 +31,6 @@ #define __BASEBAND_H__ #include "ttype.h" -#include "tether.h" #include "device.h" /* diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index b59405bca606..32dd1cab7dcf 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -35,7 +35,6 @@ #include #include "linux/ieee80211.h" #include "ttype.h" -#include "tether.h" #define B_OWNED_BY_CHIP 1 #define B_OWNED_BY_HOST 0 diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index f73239fdc665..4d9d60bc756a 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -69,7 +69,6 @@ #include "device_cfg.h" #include "ttype.h" #include "80211hdr.h" -#include "tether.h" #include "wmgr.h" #include "mib.h" #include "srom.h" @@ -633,8 +632,6 @@ struct vnt_private { unsigned long uNumSQ3[MAX_RATE]; unsigned short wAntDiversityMaxRate; - SEthernetHeader sTxEthHeader; - SEthernetHeader sRxEthHeader; unsigned char abyBroadcastAddr[ETH_ALEN]; unsigned char abySNAP_RFC1042[ETH_ALEN]; unsigned char abySNAP_Bridgetunnel[ETH_ALEN]; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index dfaec046ef51..2327369ba790 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -58,7 +58,6 @@ #include "channel.h" #include "baseband.h" #include "mac.h" -#include "tether.h" #include "wmgr.h" #include "power.h" #include "iocmd.h" diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 56d1b05aad79..53b46062765d 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -33,7 +33,6 @@ #include #include "ttype.h" -#include "tether.h" #include "80211mgr.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index a347f3963934..955dbfebe170 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -69,7 +69,6 @@ */ #include "tmacro.h" -#include "tether.h" #include "mac.h" unsigned short TxRate_iwconfig;//2008-5-8 by chester diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index fdb40f20d3e5..a2e6106b4570 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -30,7 +30,6 @@ #define __MIB_H__ #include "ttype.h" -#include "tether.h" #include "desc.h" // diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 246a250cbb95..f4da7e76f658 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -50,7 +50,6 @@ #include "device.h" #include "rxtx.h" -#include "tether.h" #include "card.h" #include "mac.h" #include "baseband.h" diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 5396e5832c22..1ac60fb4490f 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -44,7 +44,6 @@ #include "upc.h" #include "tmacro.h" -#include "tether.h" #include "mac.h" #include "srom.h" diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h deleted file mode 100644 index 850554c3e762..000000000000 --- a/drivers/staging/vt6655/tether.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: tether.h - * - * Purpose: - * - * Author: Tevin Chen - * - * Date: Jan. 28, 1997 - * - */ - -#ifndef __TETHER_H__ -#define __TETHER_H__ - -#include -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ -// -// constants -// -#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) -// Ethernet address string length - -#define MAX_LOOKAHEAD_SIZE ETH_FRAME_LEN - -#define U_MULTI_ADDR_LEN 8 // multicast address length - -#ifdef __BIG_ENDIAN - -#define TYPE_PKT_IP 0x0800 // -#define TYPE_PKT_ARP 0x0806 // -#define TYPE_PKT_RARP 0x8035 // -#define TYPE_PKT_IPX 0x8137 // -#define TYPE_PKT_802_1x 0x888e -#define TYPE_PKT_PreAuth 0x88C7 - -#define TYPE_PKT_PING_M_REQ 0x8011 // master reguest -#define TYPE_PKT_PING_S_GNT 0x8022 // slave grant -#define TYPE_PKT_PING_M 0x8077 // pingpong master packet -#define TYPE_PKT_PING_S 0x8088 // pingpong slave packet -#define TYPE_PKT_WOL_M_REQ 0x8033 // WOL waker request -#define TYPE_PKT_WOL_S_GNT 0x8044 // WOL sleeper grant -#define TYPE_MGMT_PROBE_RSP 0x5000 -#define TYPE_PKT_VNT_DIAG 0x8011 // Diag Pkt -#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt -// -// wFrameCtl field in the S802_11Header -// -// NOTE.... -// in network byte order, high byte is going first -#define FC_TODS 0x0001 -#define FC_FROMDS 0x0002 -#define FC_MOREFRAG 0x0004 -#define FC_RETRY 0x0008 -#define FC_POWERMGT 0x0010 -#define FC_MOREDATA 0x0020 -#define FC_WEP 0x0040 -#define TYPE_802_11_ATIM 0x9000 - -#define TYPE_802_11_DATA 0x0800 -#define TYPE_802_11_CTL 0x0400 -#define TYPE_802_11_MGMT 0x0000 -#define TYPE_802_11_MASK 0x0C00 -#define TYPE_SUBTYPE_MASK 0xFC00 -#define TYPE_802_11_NODATA 0x4000 -#define TYPE_DATE_NULL 0x4800 - -#define TYPE_CTL_PSPOLL 0xa400 -#define TYPE_CTL_RTS 0xb400 -#define TYPE_CTL_CTS 0xc400 -#define TYPE_CTL_ACK 0xd400 - -#else //if LITTLE_ENDIAN -// -// wType field in the SEthernetHeader -// -// NOTE.... -// in network byte order, high byte is going first -#define TYPE_PKT_IP 0x0008 // -#define TYPE_PKT_ARP 0x0608 // -#define TYPE_PKT_RARP 0x3580 // -#define TYPE_PKT_IPX 0x3781 // - -#define TYPE_PKT_802_1x 0x8e88 -#define TYPE_PKT_PreAuth 0xC788 - -#define TYPE_PKT_PING_M_REQ 0x1180 // master reguest -#define TYPE_PKT_PING_S_GNT 0x2280 // slave grant -#define TYPE_PKT_PING_M 0x7780 // pingpong master packet -#define TYPE_PKT_PING_S 0x8880 // pingpong slave packet -#define TYPE_PKT_WOL_M_REQ 0x3380 // WOL waker request -#define TYPE_PKT_WOL_S_GNT 0x4480 // WOL sleeper grant -#define TYPE_MGMT_PROBE_RSP 0x0050 -#define TYPE_PKT_VNT_DIAG 0x1180 // Diag Pkt -#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt -// -// wFrameCtl field in the S802_11Header -// -// NOTE.... -// in network byte order, high byte is going first -#define FC_TODS 0x0100 -#define FC_FROMDS 0x0200 -#define FC_MOREFRAG 0x0400 -#define FC_RETRY 0x0800 -#define FC_POWERMGT 0x1000 -#define FC_MOREDATA 0x2000 -#define FC_WEP 0x4000 -#define TYPE_802_11_ATIM 0x0090 - -#define TYPE_802_11_DATA 0x0008 -#define TYPE_802_11_CTL 0x0004 -#define TYPE_802_11_MGMT 0x0000 -#define TYPE_802_11_MASK 0x000C -#define TYPE_SUBTYPE_MASK 0x00FC -#define TYPE_802_11_NODATA 0x0040 -#define TYPE_DATE_NULL 0x0048 - -#define TYPE_CTL_PSPOLL 0x00a4 -#define TYPE_CTL_RTS 0x00b4 -#define TYPE_CTL_CTS 0x00c4 -#define TYPE_CTL_ACK 0x00d4 - -#endif //#ifdef __BIG_ENDIAN - -#define WEP_IV_MASK 0x00FFFFFF - -/*--------------------- Export Types ------------------------------*/ -// -// Ethernet packet -// -typedef struct tagSEthernetHeader { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wType; -} __attribute__ ((__packed__)) -SEthernetHeader, *PSEthernetHeader; - -// -// 802_3 packet -// -typedef struct tagS802_3Header { - unsigned char abyDstAddr[ETH_ALEN]; - unsigned char abySrcAddr[ETH_ALEN]; - unsigned short wLen; -} __attribute__ ((__packed__)) -S802_3Header, *PS802_3Header; - -// -// 802_11 packet -// -typedef struct tagS802_11Header { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[ETH_ALEN]; - unsigned char abyAddr2[ETH_ALEN]; - unsigned char abyAddr3[ETH_ALEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[ETH_ALEN]; -} __attribute__ ((__packed__)) -S802_11Header, *PS802_11Header; - -/*--------------------- Export Macros ------------------------------*/ - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -#endif // __TETHER_H__ -- GitLab From 8224e771ca32895bc244f5f61f978d20ecbb8af6 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:55 +0000 Subject: [PATCH 2112/9457] staging: vt6655: dead code remove 80211mgr.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.h | 615 ------------------------------ drivers/staging/vt6655/device.h | 1 - drivers/staging/vt6655/key.h | 1 - drivers/staging/vt6655/wmgr.h | 1 - 4 files changed, 618 deletions(-) delete mode 100644 drivers/staging/vt6655/80211mgr.h diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h deleted file mode 100644 index 94cff3b87cb1..000000000000 --- a/drivers/staging/vt6655/80211mgr.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: 80211mgr.h - * - * Purpose: 802.11 management frames pre-defines. - * - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __80211MGR_H__ -#define __80211MGR_H__ - -#include -#include "linux/ieee80211.h" - -#include "ttype.h" -#include "80211hdr.h" - -#define WLAN_MIN_ARRAY 1 - -/* Information Element ID value */ -#define WLAN_EID_FH_PARMS 2 -#define WLAN_EID_DS_PARMS 3 -#define WLAN_EID_CF_PARMS 4 -#define WLAN_EID_IBSS_PARMS 6 -#define WLAN_EID_TPC_REQ 34 -#define WLAN_EID_TPC_REP 35 -#define WLAN_EID_SUPP_CH 36 -#define WLAN_EID_CH_SWITCH 37 -#define WLAN_EID_MEASURE_REQ 38 -#define WLAN_EID_MEASURE_REP 39 -#define WLAN_EID_QUIET 40 -#define WLAN_EID_IBSS_DFS 41 -#define WLAN_EID_ERP 42 -/* reference 802.11i 7.3.2 table 20 */ -#define WLAN_EID_EXTSUPP_RATES 50 -/* reference WiFi WPA spec. */ -#define WLAN_EID_RSN_WPA 221 - -#define WLAN_EID_ERP_NONERP_PRESENT 0x01 -#define WLAN_EID_ERP_USE_PROTECTION 0x02 -#define WLAN_EID_ERP_BARKER_MODE 0x04 - -/* Reason Codes */ -#define WLAN_MGMT_REASON_RSVD 0 -#define WLAN_MGMT_REASON_UNSPEC 1 -#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 -#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 -#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 -#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 -#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 -#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 -#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 -#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 -#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT 10 -#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT 11 -#define WLAN_MGMT_REASON_INVALID_IE 13 -#define WLAN_MGMT_REASON_MIC_FAILURE 14 -#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT 15 -#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT 16 -#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT 17 -#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID 18 -#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID 19 -#define WLAN_MGMT_REASON_AKMP_INVALID 20 -#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED 21 -#define WLAN_MGMT_REASON_RSNE_CAP_INVALID 22 -#define WLAN_MGMT_REASON_80211X_AUTH_FAILED 23 - -/* Status Codes */ -#define WLAN_MGMT_STATUS_SUCCESS 0 -#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 -#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 -#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 -#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 -#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 -#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 -#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE 19 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC 20 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY 21 - -/* reference 802.11h 7.3.1.9 */ -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG 22 -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP 23 -#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH 24 -/* reference 802.11g 7.3.1.9 */ -#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED 25 -#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED 26 -/* reference 802.11i 3.7.1.9 table 19 */ -#define WLAN_MGMT_STATUS_INVALID_IE 40 -#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID 41 -#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID 42 -#define WLAN_MGMT_STATUS_AKMP_INVALID 43 -#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER 44 -#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP 45 -#define WLAN_MGMT_STATUS_CIPHER_REJECT 46 - -/* Auth Algorithm */ -#define WLAN_AUTH_ALG_OPENSYSTEM 0 -#define WLAN_AUTH_ALG_SHAREDKEY 1 - -/* Management Frame Field Offsets */ -/* Note: Not all fields are listed because of variable lengths. */ -/* Note: These offsets are from the start of the frame data */ - -#define WLAN_BEACON_OFF_TS 0 -#define WLAN_BEACON_OFF_BCN_INT 8 -#define WLAN_BEACON_OFF_CAPINFO 10 -#define WLAN_BEACON_OFF_SSID 12 - -#define WLAN_DISASSOC_OFF_REASON 0 - -#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 -#define WLAN_ASSOCREQ_OFF_SSID 4 - -#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_ASSOCRESP_OFF_STATUS 2 -#define WLAN_ASSOCRESP_OFF_AID 4 -#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 -#define WLAN_REASSOCREQ_OFF_CURR_AP 4 -#define WLAN_REASSOCREQ_OFF_SSID 10 - -#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_REASSOCRESP_OFF_STATUS 2 -#define WLAN_REASSOCRESP_OFF_AID 4 -#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_PROBEREQ_OFF_SSID 0 - -#define WLAN_PROBERESP_OFF_TS 0 -#define WLAN_PROBERESP_OFF_BCN_INT 8 -#define WLAN_PROBERESP_OFF_CAP_INFO 10 -#define WLAN_PROBERESP_OFF_SSID 12 - -#define WLAN_AUTHEN_OFF_AUTH_ALG 0 -#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 -#define WLAN_AUTHEN_OFF_STATUS 4 -#define WLAN_AUTHEN_OFF_CHALLENGE 6 - -#define WLAN_DEAUTHEN_OFF_REASON 0 - -/* Cipher Suite Selectors defined in 802.11i */ -#define WLAN_11i_CSS_USE_GROUP 0 -#define WLAN_11i_CSS_WEP40 1 -#define WLAN_11i_CSS_TKIP 2 -#define WLAN_11i_CSS_CCMP 4 -#define WLAN_11i_CSS_WEP104 5 -#define WLAN_11i_CSS_UNKNOWN 255 - -/* Authentication and Key Management Suite Selectors defined in 802.11i */ -#define WLAN_11i_AKMSS_802_1X 1 -#define WLAN_11i_AKMSS_PSK 2 -#define WLAN_11i_AKMSS_UNKNOWN 255 - -/* Measurement type definitions reference ieee 802.11h Table 20b */ -#define MEASURE_TYPE_BASIC 0 -#define MEASURE_TYPE_CCA 1 -#define MEASURE_TYPE_RPI 2 - -/* Measurement request mode definitions reference ieee 802.11h Figure 46h */ -#define MEASURE_MODE_ENABLE 0x02 -#define MEASURE_MODE_REQ 0x04 -#define MEASURE_MODE_REP 0x08 - -/* Measurement report mode definitions reference ieee 802.11h Figure 46m */ -#define MEASURE_MODE_LATE 0x01 -#define MEASURE_MODE_INCAPABLE 0x02 -#define MEASURE_MODE_REFUSED 0x04 - -/* Information Element Types */ - -#pragma pack(1) -typedef struct tagWLAN_IE { - unsigned char byElementID; - unsigned char len; -} __attribute__ ((__packed__)) -WLAN_IE, *PWLAN_IE; - -/* Service Set Identity (SSID) */ -#pragma pack(1) -typedef struct tagWLAN_IE_SSID { - unsigned char byElementID; - unsigned char len; - unsigned char abySSID[1]; -} __attribute__ ((__packed__)) -WLAN_IE_SSID, *PWLAN_IE_SSID; - -/* Supported Rates */ -#pragma pack(1) -typedef struct tagWLAN_IE_SUPP_RATES { - unsigned char byElementID; - unsigned char len; - unsigned char abyRates[1]; -} __attribute__ ((__packed__)) -WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES; - -/* FH Parameter Set */ -#pragma pack(1) -typedef struct _WLAN_IE_FH_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wDwellTime; - unsigned char byHopSet; - unsigned char byHopPattern; - unsigned char byHopIndex; -} WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS; - -/* DS Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_DS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCurrChannel; -} __attribute__ ((__packed__)) -WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS; - -/* CF Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_CF_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned char byCFPCount; - unsigned char byCFPPeriod; - unsigned short wCFPMaxDuration; - unsigned short wCFPDurRemaining; -} __attribute__ ((__packed__)) -WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS; - -/* TIM */ -#pragma pack(1) -typedef struct tagWLAN_IE_TIM { - unsigned char byElementID; - unsigned char len; - unsigned char byDTIMCount; - unsigned char byDTIMPeriod; - unsigned char byBitMapCtl; - unsigned char byVirtBitMap[1]; -} __attribute__ ((__packed__)) -WLAN_IE_TIM, *PWLAN_IE_TIM; - -/* IBSS Parameter Set */ -#pragma pack(1) -typedef struct tagWLAN_IE_IBSS_PARMS { - unsigned char byElementID; - unsigned char len; - unsigned short wATIMWindow; -} __attribute__ ((__packed__)) -WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS; - -/* Challenge Text */ -#pragma pack(1) -typedef struct tagWLAN_IE_CHALLENGE { - unsigned char byElementID; - unsigned char len; - unsigned char abyChallenge[1]; -} __attribute__ ((__packed__)) -WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE; - -#pragma pack(1) -typedef struct tagWLAN_IE_RSN_EXT { - unsigned char byElementID; - unsigned char len; - unsigned char abyOUI[4]; - unsigned short wVersion; - unsigned char abyMulticast[4]; - unsigned short wPKCount; - struct { - unsigned char abyOUI[4]; - } PKSList[1]; /* the rest is variable so need to */ - /* overlay ieauth structure */ -} WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT; - -#pragma pack(1) -typedef struct tagWLAN_IE_RSN_AUTH { - unsigned short wAuthCount; - struct { - unsigned char abyOUI[4]; - } AuthKSList[1]; -} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH; - -/* RSN Identity */ -#pragma pack(1) -typedef struct tagWLAN_IE_RSN { - unsigned char byElementID; - unsigned char len; - unsigned short wVersion; - unsigned char abyRSN[WLAN_MIN_ARRAY]; -} WLAN_IE_RSN, *PWLAN_IE_RSN; - -/* ERP */ -#pragma pack(1) -typedef struct tagWLAN_IE_ERP { - unsigned char byElementID; - unsigned char len; - unsigned char byContext; -} __attribute__ ((__packed__)) -WLAN_IE_ERP, *PWLAN_IE_ERP; - -#pragma pack(1) -typedef struct _MEASEURE_REQ { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; -} MEASEURE_REQ, *PMEASEURE_REQ, - MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC, - MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA, - MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI; - -typedef struct _MEASEURE_REP_BASIC { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byMap; -} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC; - -typedef struct _MEASEURE_REP_CCA { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char byCCABusyFraction; -} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA; - -typedef struct _MEASEURE_REP_RPI { - unsigned char byChannel; - unsigned char abyStartTime[8]; - unsigned char abyDuration[2]; - unsigned char abyRPIdensity[8]; -} MEASEURE_REP_RPI, *PMEASEURE_REP_RPI; - -typedef union _MEASEURE_REP { - MEASEURE_REP_BASIC sBasic; - MEASEURE_REP_CCA sCCA; - MEASEURE_REP_RPI sRPI; -} MEASEURE_REP, *PMEASEURE_REP; - -typedef struct _WLAN_IE_MEASURE_REQ { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REQ sReq; -} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ; - -typedef struct _WLAN_IE_MEASURE_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byToken; - unsigned char byMode; - unsigned char byType; - MEASEURE_REP sRep; -} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP; - -typedef struct _WLAN_IE_CH_SW { - unsigned char byElementID; - unsigned char len; - unsigned char byMode; - unsigned char byChannel; - unsigned char byCount; -} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW; - -typedef struct _WLAN_IE_QUIET { - unsigned char byElementID; - unsigned char len; - unsigned char byQuietCount; - unsigned char byQuietPeriod; - unsigned char abyQuietDuration[2]; - unsigned char abyQuietOffset[2]; -} WLAN_IE_QUIET, *PWLAN_IE_QUIET; - -typedef struct _WLAN_IE_COUNTRY { - unsigned char byElementID; - unsigned char len; - unsigned char abyCountryString[3]; - unsigned char abyCountryInfo[3]; -} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY; - -typedef struct _WLAN_IE_PW_CONST { - unsigned char byElementID; - unsigned char len; - unsigned char byPower; -} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST; - -typedef struct _WLAN_IE_PW_CAP { - unsigned char byElementID; - unsigned char len; - unsigned char byMinPower; - unsigned char byMaxPower; -} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP; - -typedef struct _WLAN_IE_SUPP_CH { - unsigned char byElementID; - unsigned char len; - unsigned char abyChannelTuple[2]; -} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH; - -typedef struct _WLAN_IE_TPC_REQ { - unsigned char byElementID; - unsigned char len; -} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ; - -typedef struct _WLAN_IE_TPC_REP { - unsigned char byElementID; - unsigned char len; - unsigned char byTxPower; - unsigned char byLinkMargin; -} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP; - -typedef struct _WLAN_IE_IBSS_DFS { - unsigned char byElementID; - unsigned char len; - unsigned char abyDFSOwner[6]; - unsigned char byDFSRecovery; - unsigned char abyChannelMap[2]; -} WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS; - -#pragma pack() - -/* Frame Types */ -/* prototype structure, all mgmt frame types will start with these members */ -typedef struct tagWLAN_FR_MGMT { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; -} WLAN_FR_MGMT, *PWLAN_FR_MGMT; - -/* Beacon frame */ -typedef struct tagWLAN_FR_BEACON { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - __le64 *pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_TIM pTIM; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; -} WLAN_FR_BEACON, *PWLAN_FR_BEACON; - -/* IBSS ATIM frame */ -typedef struct tagWLAN_FR_IBSSATIM { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; -} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM; - -/* Disassociation */ -typedef struct tagWLAN_FR_DISASSOC { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwReason; -} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC; - -/* Association Request */ -typedef struct tagWLAN_FR_ASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_PW_CAP pCurrPowerCap; - PWLAN_IE_SUPP_CH pCurrSuppCh; -} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ; - -/* Association Response */ -typedef struct tagWLAN_FR_ASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP; - -/* Reassociation Request */ -typedef struct tagWLAN_FR_REASSOCREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwListenInterval; - PIEEE_ADDR pAddrCurrAP; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ; - -/* Reassociation Response */ -typedef struct tagWLAN_FR_REASSOCRESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwCapInfo; - unsigned short *pwStatus; - unsigned short *pwAid; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP; - -/* Probe Request */ -typedef struct tagWLAN_FR_PROBEREQ { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_SUPP_RATES pExtSuppRates; -} WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ; - -/* Probe Response */ -typedef struct tagWLAN_FR_PROBERESP { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - __le64 *pqwTimestamp; - unsigned short *pwBeaconInterval; - unsigned short *pwCapInfo; - PWLAN_IE_SSID pSSID; - PWLAN_IE_SUPP_RATES pSuppRates; - PWLAN_IE_DS_PARMS pDSParms; - PWLAN_IE_CF_PARMS pCFParms; - PWLAN_IE_IBSS_PARMS pIBSSParms; - PWLAN_IE_RSN pRSN; - PWLAN_IE_RSN_EXT pRSNWPA; - PWLAN_IE_ERP pERP; - PWLAN_IE_SUPP_RATES pExtSuppRates; - PWLAN_IE_COUNTRY pIE_Country; - PWLAN_IE_PW_CONST pIE_PowerConstraint; - PWLAN_IE_CH_SW pIE_CHSW; - PWLAN_IE_IBSS_DFS pIE_IBSSDFS; - PWLAN_IE_QUIET pIE_Quiet; -} WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP; - -/* Authentication */ -typedef struct tagWLAN_FR_AUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwAuthAlgorithm; - unsigned short *pwAuthSequence; - unsigned short *pwStatus; - PWLAN_IE_CHALLENGE pChallenge; -} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN; - -/* Deauthenication */ -typedef struct tagWLAN_FR_DEAUTHEN { - unsigned int uType; - unsigned int len; - unsigned char *pBuf; - PUWLAN_80211HDR pHdr; - unsigned short *pwReason; -} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN; - -#endif/* __80211MGR_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 4d9d60bc756a..1816f3c2a502 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -642,7 +642,6 @@ struct vnt_private { unsigned char abyCountryCode[3]; /* for 802.11h DFS */ unsigned int uNumOfMeasureEIDs; - PWLAN_IE_MEASURE_REQ pCurrMeasureEID; bool bMeasureInProgress; unsigned char byOrgChannel; unsigned char byOrgRCR; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 53b46062765d..5615f397f6e7 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -33,7 +33,6 @@ #include #include "ttype.h" -#include "80211mgr.h" /*--------------------- Export Definitions -------------------------*/ #define MAX_GROUP_KEY 4 diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 9e983f6da41d..44976e0200bb 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -35,7 +35,6 @@ #define __WMGR_H__ #include "ttype.h" -#include "80211mgr.h" #include "80211hdr.h" #include "card.h" -- GitLab From 47a2a3cb758f6b44b0a6ce2a379f44b18666c125 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:56 +0000 Subject: [PATCH 2113/9457] staging: vt6655: dead code remove iowpa.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/iowpa.h | 130 --------------------------- 2 files changed, 131 deletions(-) delete mode 100644 drivers/staging/vt6655/iowpa.h diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 2327369ba790..d5ab7c4b6891 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -64,7 +64,6 @@ #include "rxtx.h" #include "dpc.h" #include "rf.h" -#include "iowpa.h" #include #include #include diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h deleted file mode 100644 index 7f79eaeecc9e..000000000000 --- a/drivers/staging/vt6655/iowpa.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iowpa.h - * - * Purpose: Handles wpa supplicant ioctl interface - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __IOWPA_H__ -#define __IOWPA_H__ - -#define WPA_IE_LEN 64 - -/* WPA related */ - -enum { - VIAWGET_SET_WPA = 1, - VIAWGET_SET_KEY = 2, - VIAWGET_SET_SCAN = 3, - VIAWGET_GET_SCAN = 4, - VIAWGET_GET_SSID = 5, - VIAWGET_GET_BSSID = 6, - VIAWGET_SET_DROP_UNENCRYPT = 7, - VIAWGET_SET_DEAUTHENTICATE = 8, - VIAWGET_SET_ASSOCIATE = 9, - VIAWGET_SET_DISASSOCIATE = 10 -}; - -enum { - VIAWGET_ASSOC_MSG = 1, - VIAWGET_DISASSOC_MSG = 2, - VIAWGET_PTK_MIC_MSG = 3, - VIAWGET_GTK_MIC_MSG = 4, - VIAWGET_CCKM_ROAM_MSG = 5, - VIAWGET_DEVICECLOSE_MSG = 6 -}; - -#pragma pack(1) -typedef struct viawget_wpa_header { - u8 type; - u16 req_ie_len; - u16 resp_ie_len; -} viawget_wpa_header; - -struct viawget_wpa_param { - u32 cmd; - u8 addr[6]; - union { - struct { - u8 len; - u8 data[0]; - } generic_elem; - - struct { - u8 bssid[6]; - u8 ssid[32]; - u8 ssid_len; - u8 __user *wpa_ie; - u16 wpa_ie_len; - int pairwise_suite; - int group_suite; - int key_mgmt_suite; - int auth_alg; - int mode; - - } wpa_associate; - - struct { - int alg_name; - u16 key_index; - u16 set_tx; - u8 *seq; - u16 seq_len; - u8 *key; - u16 key_len; - } wpa_key; - - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - - struct { - u16 scan_count; - u8 __user *buf; - } scan_results; - - } u; -}; - -#pragma pack(1) -struct viawget_scan_result { - u8 bssid[6]; - u8 ssid[32]; - u16 ssid_len; - u8 wpa_ie[WPA_IE_LEN]; - u16 wpa_ie_len; - u8 rsn_ie[WPA_IE_LEN]; - u16 rsn_ie_len; - int freq; /* MHz */ - int caps; /* e.g. privacy */ - int qual; /* signal quality */ - int noise; - int level; - int maxrate; -}; - -#pragma pack() - -#endif /* __IOWPA_H__ */ -- GitLab From 651a39cad5f3009e8aa80e3132ac34a9474ebf74 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:57 +0000 Subject: [PATCH 2114/9457] staging: vt6655: dead code remove iocmd.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/iocmd.h | 386 --------------------------- 2 files changed, 387 deletions(-) delete mode 100644 drivers/staging/vt6655/iocmd.h diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index d5ab7c4b6891..7892f861521e 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -60,7 +60,6 @@ #include "mac.h" #include "wmgr.h" #include "power.h" -#include "iocmd.h" #include "rxtx.h" #include "dpc.h" #include "rf.h" diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h deleted file mode 100644 index 804c903404a1..000000000000 --- a/drivers/staging/vt6655/iocmd.h +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: iocmd.h - * - * Purpose: Handles the viawget ioctl private interface functions - * - * Author: Lyndon Chen - * - * Date: May 8, 2002 - * - */ - -#ifndef __IOCMD_H__ -#define __IOCMD_H__ - -#include "ttype.h" - -/* ioctl Command code */ -#define MAGIC_CODE 0x3142 -#define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0) -#define IOCTL_CMD_SET (SIOCDEVPRIVATE + 1) -#define IOCTL_CMD_HOSTAPD (SIOCDEVPRIVATE + 2) -#define IOCTL_CMD_WPA (SIOCDEVPRIVATE + 3) - -typedef enum tagWMAC_CMD { - WLAN_CMD_BSS_SCAN, - WLAN_CMD_BSS_JOIN, - WLAN_CMD_DISASSOC, - WLAN_CMD_SET_WEP, - WLAN_CMD_GET_LINK, - WLAN_CMD_GET_LISTLEN, - WLAN_CMD_GET_LIST, - WLAN_CMD_GET_MIB, - WLAN_CMD_GET_STAT, - WLAN_CMD_STOP_MAC, - WLAN_CMD_START_MAC, - WLAN_CMD_AP_START, - WLAN_CMD_SET_HOSTAPD, - WLAN_CMD_SET_HOSTAPD_STA, - WLAN_CMD_SET_802_1X, - WLAN_CMD_SET_HOST_WEP, - WLAN_CMD_SET_WPA, - WLAN_CMD_GET_NODE_CNT, - WLAN_CMD_ZONETYPE_SET, - WLAN_CMD_GET_NODE_LIST -} WMAC_CMD, *PWMAC_CMD; - -typedef enum tagWZONETYPE { - ZoneType_USA = 0, - ZoneType_Japan = 1, - ZoneType_Europe = 2 -} WZONETYPE; - -#define ADHOC 0 -#define INFRA 1 -#define BOTH 2 -#define AP 3 - -#define ADHOC_STARTED 1 -#define ADHOC_JOINTED 2 - -#define PHY80211a 0 -#define PHY80211b 1 -#define PHY80211g 2 - -#define SSID_ID 0 -#define SSID_MAXLEN 32 -#define BSSID_LEN 6 -#define WEP_NKEYS 4 -#define WEP_KEYMAXLEN 29 -#define WEP_40BIT_LEN 5 -#define WEP_104BIT_LEN 13 -#define WEP_232BIT_LEN 16 - -/* Ioctl interface structure, Command structure */ -#pragma pack(1) -typedef struct tagSCmdRequest { - u8 name[16]; - void __user *data; - u16 wResult; - u16 wCmdCode; -} SCmdRequest, *PSCmdRequest; - -/* Scan */ -typedef struct tagSCmdScan { - u8 ssid[SSID_MAXLEN + 2]; -} SCmdScan, *PSCmdScan; - -/* BSS Join */ -typedef struct tagSCmdBSSJoin { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - bool bPSEnable; - bool bShareKeyAuth; -} SCmdBSSJoin, *PSCmdBSSJoin; - -/* Zonetype Setting */ -typedef struct tagSCmdZoneTypeSet { - bool bWrite; - WZONETYPE ZoneType; -} SCmdZoneTypeSet, *PSCmdZoneTypeSet; - -#ifdef WPA_SM_Transtatus -typedef struct tagSWPAResult { - char ifname[100]; - u8 proto; - u8 key_mgmt; - u8 eap_type; - bool authenticated; -} SWPAResult, *PSWPAResult; -#endif - -typedef struct tagSCmdStartAP { - u16 wBSSType; - u16 wBBPType; - u8 ssid[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uBeaconInt; - bool bShareKeyAuth; - u8 byBasicRate; -} SCmdStartAP, *PSCmdStartAP; - -typedef struct tagSCmdSetWEP { - bool bEnableWep; - u8 byKeyIndex; - u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; - bool bWepKeyAvailable[WEP_NKEYS]; - u32 auWepKeyLength[WEP_NKEYS]; -} SCmdSetWEP, *PSCmdSetWEP; - -typedef struct tagSBSSIDItem { - u32 uChannel; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 1]; - u8 byNetType; - u16 wBeaconInterval; - u16 wCapInfo; /* for address of byNetType at align 4 */ - - bool bWEPOn; - u32 uRSSI; -} SBSSIDItem; - -typedef struct tagSBSSIDList { - u32 uItem; - SBSSIDItem sBSSIDList[0]; -} SBSSIDList, *PSBSSIDList; - -typedef struct tagSCmdLinkStatus { - bool bLink; - u16 wBSSType; - u8 byState; - u8 abyBSSID[BSSID_LEN]; - u8 abySSID[SSID_MAXLEN + 2]; - u32 uChannel; - u32 uLinkRate; -} SCmdLinkStatus, *PSCmdLinkStatus; - -/* 802.11 counter */ -typedef struct tagSDot11MIBCount { - u32 TransmittedFragmentCount; - u32 MulticastTransmittedFrameCount; - u32 FailedCount; - u32 RetryCount; - u32 MultipleRetryCount; - u32 RTSSuccessCount; - u32 RTSFailureCount; - u32 ACKFailureCount; - u32 FrameDuplicateCount; - u32 ReceivedFragmentCount; - u32 MulticastReceivedFrameCount; - u32 FCSErrorCount; -} SDot11MIBCount, *PSDot11MIBCount; - -/* statistic counter */ -typedef struct tagSStatMIBCount { - /* ISR status count */ - u32 dwIsrTx0OK; - u32 dwIsrTx1OK; - u32 dwIsrBeaconTxOK; - u32 dwIsrRxOK; - u32 dwIsrTBTTInt; - u32 dwIsrSTIMERInt; - u32 dwIsrUnrecoverableError; - u32 dwIsrSoftInterrupt; - u32 dwIsrRxNoBuf; - - u32 dwIsrUnknown; - - /* RSR status count */ - u32 dwRsrFrmAlgnErr; - u32 dwRsrErr; - u32 dwRsrCRCErr; - u32 dwRsrCRCOk; - u32 dwRsrBSSIDOk; - u32 dwRsrADDROk; - u32 dwRsrICVOk; - u32 dwNewRsrShortPreamble; - u32 dwRsrLong; - u32 dwRsrRunt; - - u32 dwRsrRxControl; - u32 dwRsrRxData; - u32 dwRsrRxManage; - - u32 dwRsrRxPacket; - u32 dwRsrRxOctet; - u32 dwRsrBroadcast; - u32 dwRsrMulticast; - u32 dwRsrDirected; - /* 64-bit OID */ - u32 ullRsrOK; - - /* for some optional OIDs (64 bits) and DMI support */ - u32 ullRxBroadcastBytes; - u32 ullRxMulticastBytes; - u32 ullRxDirectedBytes; - u32 ullRxBroadcastFrames; - u32 ullRxMulticastFrames; - u32 ullRxDirectedFrames; - - u32 dwRsrRxFragment; - u32 dwRsrRxFrmLen64; - u32 dwRsrRxFrmLen65_127; - u32 dwRsrRxFrmLen128_255; - u32 dwRsrRxFrmLen256_511; - u32 dwRsrRxFrmLen512_1023; - u32 dwRsrRxFrmLen1024_1518; - - /* TSR0,1 status count */ - u32 dwTsrTotalRetry[2]; /* total collision retry count */ - u32 dwTsrOnceRetry[2]; /* this packet only occur one collision */ - u32 dwTsrMoreThanOnceRetry[2]; /* this packet occur more than one collision */ - u32 dwTsrRetry[2]; /* this packet has ever occur collision */ - /* that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) */ - u32 dwTsrACKData[2]; - u32 dwTsrErr[2]; - u32 dwAllTsrOK[2]; - u32 dwTsrRetryTimeout[2]; - u32 dwTsrTransmitTimeout[2]; - - u32 dwTsrTxPacket[2]; - u32 dwTsrTxOctet[2]; - u32 dwTsrBroadcast[2]; - u32 dwTsrMulticast[2]; - u32 dwTsrDirected[2]; - - /* RD/TD count */ - u32 dwCntRxFrmLength; - u32 dwCntTxBufLength; - - u8 abyCntRxPattern[16]; - u8 abyCntTxPattern[16]; - - /* Software check */ - u32 dwCntRxDataErr; /* rx buffer data software compare CRC err count */ - u32 dwCntDecryptErr; /* rx buffer data software compare CRC err count */ - u32 dwCntRxICVErr; /* rx buffer data software compare CRC err count */ - u32 idxRxErrorDesc; /* index for rx data error RD */ - - /* 64-bit OID */ - u32 ullTsrOK[2]; - - /* for some optional OIDs (64 bits) and DMI support */ - u32 ullTxBroadcastFrames[2]; - u32 ullTxMulticastFrames[2]; - u32 ullTxDirectedFrames[2]; - u32 ullTxBroadcastBytes[2]; - u32 ullTxMulticastBytes[2]; - u32 ullTxDirectedBytes[2]; -} SStatMIBCount, *PSStatMIBCount; - -typedef struct tagSNodeItem { - /* STA info */ - u16 wAID; - u8 abyMACAddr[6]; - u16 wTxDataRate; - u16 wInActiveCount; - u16 wEnQueueCnt; - u16 wFlags; - bool bPWBitOn; - u8 byKeyIndex; - u16 wWepKeyLength; - u8 abyWepKey[WEP_KEYMAXLEN]; - /* Auto rate fallback vars */ - bool bIsInFallback; - u32 uTxFailures; - u32 uTxAttempts; - u16 wFailureRatio; -} SNodeItem; - -typedef struct tagSNodeList { - u32 uItem; - SNodeItem sNodeList[0]; -} SNodeList, *PSNodeList; - -typedef struct tagSCmdValue { - u32 dwValue; -} SCmdValue, *PSCmdValue; - -/* hostapd & viawget ioctl related */ -enum { - VIAWGET_HOSTAPD_FLUSH = 1, - VIAWGET_HOSTAPD_ADD_STA = 2, - VIAWGET_HOSTAPD_REMOVE_STA = 3, - VIAWGET_HOSTAPD_GET_INFO_STA = 4, - VIAWGET_HOSTAPD_SET_ENCRYPTION = 5, - VIAWGET_HOSTAPD_GET_ENCRYPTION = 6, - VIAWGET_HOSTAPD_SET_FLAGS_STA = 7, - VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR = 8, - VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT = 9, - VIAWGET_HOSTAPD_MLME = 10, - VIAWGET_HOSTAPD_SCAN_REQ = 11, - VIAWGET_HOSTAPD_STA_CLEAR_STATS = 12, -}; - -#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ - ((int)(&((struct viawget_hostapd_param *)0)->u.generic_elem.data)) - -/*Maximum length for algorithm names (-1 for nul termination) used in ioctl()*/ - -struct viawget_hostapd_param { - u32 cmd; - u8 sta_addr[6]; - union { - struct { - u16 aid; - u16 capability; - u8 tx_supp_rates; - } add_sta; - struct { - u32 inactive_sec; - } get_info_sta; - struct { - u8 alg; - u32 flags; - u32 err; - u8 idx; - u8 seq[8]; - u16 key_len; - u8 key[0]; - } crypt; - struct { - u32 flags_and; - u32 flags_or; - } set_flags_sta; - struct { - u16 rid; - u16 len; - u8 data[0]; - } rid; - struct { - u8 len; - u8 data[0]; - } generic_elem; - struct { - u16 cmd; - u16 reason_code; - } mlme; - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - } u; -}; - -#pragma pack() - -#endif /* __IOCMD_H__ */ -- GitLab From 4cf8e50303c92333e1d2be838624f004e7371513 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:58 +0000 Subject: [PATCH 2115/9457] staging: vt6655: dead code remove country.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 1 - drivers/staging/vt6655/country.h | 161 ------------------------------- 2 files changed, 162 deletions(-) delete mode 100644 drivers/staging/vt6655/country.h diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 41146eb113ef..6bd5f161894d 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -21,7 +21,6 @@ */ #include "baseband.h" -#include "country.h" #include "channel.h" #include "device.h" #include "rf.h" diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h deleted file mode 100644 index 2365fb13b033..000000000000 --- a/drivers/staging/vt6655/country.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: country.h - * - * Purpose: Country Code information - * - * Author: Lucas Lin - * - * Date: Dec 23, 2004 - * - */ - -#ifndef __COUNTRY_H__ -#define __COUNTRY_H__ - -#include "ttype.h" - -/************************************************************************ - * The definition here should be complied with the INF country order - * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf - ************************************************************************/ -typedef enum _COUNTRY_CODE { - CCODE_FCC = 0, - CCODE_TELEC, - CCODE_ETSI, - CCODE_RESV3, - CCODE_RESV4, - CCODE_RESV5, - CCODE_RESV6, - CCODE_RESV7, - CCODE_RESV8, - CCODE_RESV9, - CCODE_RESVa, - CCODE_RESVb, - CCODE_RESVc, - CCODE_RESVd, - CCODE_RESVe, - CCODE_ALLBAND, - CCODE_ALBANIA, - CCODE_ALGERIA, - CCODE_ARGENTINA, - CCODE_ARMENIA, - CCODE_AUSTRALIA, - CCODE_AUSTRIA, - CCODE_AZERBAIJAN, - CCODE_BAHRAIN, - CCODE_BELARUS, - CCODE_BELGIUM, - CCODE_BELIZE, - CCODE_BOLIVIA, - CCODE_BRAZIL, - CCODE_BRUNEI_DARUSSALAM, - CCODE_BULGARIA, - CCODE_CANADA, - CCODE_CHILE, - CCODE_CHINA, - CCODE_COLOMBIA, - CCODE_COSTA_RICA, - CCODE_CROATIA, - CCODE_CYPRUS, - CCODE_CZECH, - CCODE_DENMARK, - CCODE_DOMINICAN_REPUBLIC, - CCODE_ECUADOR, - CCODE_EGYPT, - CCODE_EL_SALVADOR, - CCODE_ESTONIA, - CCODE_FINLAND, - CCODE_FRANCE, - CCODE_GERMANY, - CCODE_GREECE, - CCODE_GEORGIA, - CCODE_GUATEMALA, - CCODE_HONDURAS, - CCODE_HONG_KONG, - CCODE_HUNGARY, - CCODE_ICELAND, - CCODE_INDIA, - CCODE_INDONESIA, - CCODE_IRAN, - CCODE_IRELAND, - CCODE_ITALY, - CCODE_ISRAEL, - CCODE_JAPAN, - CCODE_JORDAN, - CCODE_KAZAKHSTAN, - CCODE_KUWAIT, - CCODE_LATVIA, - CCODE_LEBANON, - CCODE_LEICHTENSTEIN, - CCODE_LITHUANIA, - CCODE_LUXEMBURG, - CCODE_MACAU, - CCODE_MACEDONIA, - CCODE_MALTA, - CCODE_MALAYSIA, - CCODE_MEXICO, - CCODE_MONACO, - CCODE_MOROCCO, - CCODE_NETHERLANDS, - CCODE_NEW_ZEALAND, - CCODE_NORTH_KOREA, - CCODE_NORWAY, - CCODE_OMAN, - CCODE_PAKISTAN, - CCODE_PANAMA, - CCODE_PERU, - CCODE_PHILIPPINES, - CCODE_POLAND, - CCODE_PORTUGAL, - CCODE_PUERTO_RICO, - CCODE_QATAR, - CCODE_ROMANIA, - CCODE_RUSSIA, - CCODE_SAUDI_ARABIA, - CCODE_SINGAPORE, - CCODE_SLOVAKIA, - CCODE_SLOVENIA, - CCODE_SOUTH_AFRICA, - CCODE_SOUTH_KOREA, - CCODE_SPAIN, - CCODE_SWEDEN, - CCODE_SWITZERLAND, - CCODE_SYRIA, - CCODE_TAIWAN, - CCODE_THAILAND, - CCODE_TRINIDAD_TOBAGO, - CCODE_TUNISIA, - CCODE_TURKEY, - CCODE_UK, - CCODE_UKRAINE, - CCODE_UNITED_ARAB_EMIRATES, - CCODE_UNITED_STATES, - CCODE_URUGUAY, - CCODE_UZBEKISTAN, - CCODE_VENEZUELA, - CCODE_VIETNAM, - CCODE_YEMEN, - CCODE_ZIMBABWE, - CCODE_JAPAN_W52_W53, - CCODE_MAX -} COUNTRY_CODE; - -#endif /* __COUNTRY_H__ */ -- GitLab From 146761058f63d8530d150bef00c1d3daaa53dbba Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:55:59 +0000 Subject: [PATCH 2116/9457] staging: vt6655: struct vnt_private remove dead members Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 153 +------------------------------- 1 file changed, 1 insertion(+), 152 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 1816f3c2a502..bc33b2d8de4e 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -317,8 +317,6 @@ struct vnt_private { u16 current_aid; int mc_list_count; u8 mac_hw; -/* netdev */ - struct net_device *dev; /* dma addr, rx/tx pool */ dma_addr_t pool_dma; @@ -378,10 +376,6 @@ struct vnt_private { u8 rx_rate; int multicast_limit; - pid_t MLMEThr_pid; - struct completion notify; - struct semaphore mlme_semaphore; - u32 rx_bytes; /* Version control */ @@ -392,7 +386,7 @@ struct vnt_private { unsigned char byZoneType; bool bZoneRegExist; unsigned char byOriginalZonetype; - unsigned char abyMacContext[MAC_MAX_CONTEXT_REG]; + unsigned char abyCurrentNetAddr[ETH_ALEN]; bool bLinkPass; /* link status: OK or fail */ @@ -453,14 +447,6 @@ struct vnt_private { unsigned char byOpMode; bool bBSSIDFilter; unsigned short wMaxTransmitMSDULifetime; - unsigned char abyBSSID[ETH_ALEN]; - unsigned char abyDesireBSSID[ETH_ALEN]; - unsigned short wACKDuration; /* update while speed change */ - unsigned short wRTSTransmitLen; /* update while speed change */ - unsigned char byRTSServiceField; /* update while speed change */ - unsigned char byRTSSignalField; /* update while speed change */ - - unsigned long dwMaxReceiveLifetime; /* dot11MaxReceiveLifetime */ bool bEncryptionEnable; bool bLongHeader; @@ -469,9 +455,6 @@ struct vnt_private { bool bNonERPPresent; bool bBarkerPreambleMd; - unsigned char byERPFlag; - unsigned short wUseProtectCntDown; - bool bRadioControlOff; bool bRadioOff; bool bEnablePSMode; @@ -494,61 +477,11 @@ struct vnt_private { unsigned int cbBeaconBufReadySetCnt; bool bFixRate; unsigned char byCurrentCh; - unsigned int uScanTime; - - bool bBeaconTx; - - bool bStopBeacon; - bool bStopDataPkt; - bool bStopTx0Pkt; - unsigned int uAutoReConnectTime; - - /* 802.11 counter */ - - unsigned int uCmdDequeueIdx; - unsigned int uCmdEnqueueIdx; - unsigned int cbFreeCmdQueue; - bool bCmdRunning; - bool bCmdClear; - - bool bRoaming; - unsigned char abyIPAddr[4]; - - unsigned long ulTxPower; - NDIS_802_11_WEP_STATUS eEncryptionStatus; - bool bTransmitKey; - NDIS_802_11_WEP_STATUS eOldEncryptionStatus; - - unsigned long dwIVCounter; - - u64 qwPacketNumber; /* For CCMP and TKIP as TSC(6 bytes) */ - unsigned int uCurrentWEPMode; - - unsigned char abyPRNG[WLAN_WEPMAX_KEYLEN+3]; - unsigned char byKeyIndex; - unsigned int uKeyLength; - unsigned char abyKey[WLAN_WEP232_KEYLEN]; bool bAES; - unsigned char byCntMeasure; - - /* for AP mode */ - unsigned int uAssocCount; - bool bMoreData; - - /* QoS */ - bool bGrpAckPolicy; - - /* for OID_802_11_ASSOCIATION_INFORMATION */ - bool bAssocInfoSet; unsigned char byAutoFBCtrl; - bool bTxMICFail; - bool bRxMICFail; - - unsigned int uRATEIdx; - /* For Update BaseBand VGA Gain Offset */ bool bUpdateBBVGA; unsigned int uBBVGADiffCount; @@ -560,22 +493,11 @@ struct vnt_private { unsigned char byBBPreEDRSSI; unsigned char byBBPreEDIndex; - bool bRadioCmd; unsigned long dwDiagRefCount; /* For FOE Tuning */ unsigned char byFOETuning; - /* For Auto Power Tunning */ - unsigned char byAutoPwrTunning; - short sPSetPointCCK; - short sPSetPointOFDMG; - short sPSetPointOFDMA; - long lPFormulaOffset; - short sPThreshold; - char cAdjustStep; - char cMinTxAGC; - /* For RF Power table */ unsigned char byCCKPwr; unsigned char byOFDMPwrG; @@ -594,21 +516,6 @@ struct vnt_private { unsigned char byBBCR88; unsigned char byBBCR09; - /* command timer */ - struct timer_list sTimerCommand; - struct timer_list sTimerTxData; - unsigned long nTxDataTimeCout; - bool fTxDataInSleep; - bool IsTxDataTrigger; - -#ifdef WPA_SM_Transtatus - bool fWPA_Authened; /* is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */ -#endif - unsigned char byReAssocCount; - unsigned char byLinkWaitCount; - - unsigned char abyNodeName[17]; - bool bDiversityRegCtlON; bool bDiversityEnable; unsigned long ulDiversityNValue; @@ -639,72 +546,14 @@ struct vnt_private { /* for 802.11h */ bool b11hEnable; - unsigned char abyCountryCode[3]; - /* for 802.11h DFS */ - unsigned int uNumOfMeasureEIDs; - bool bMeasureInProgress; - unsigned char byOrgChannel; - unsigned char byOrgRCR; - unsigned long dwOrgMAR0; - unsigned long dwOrgMAR4; - unsigned char byBasicMap; - unsigned char byCCAFraction; - unsigned char abyRPIs[8]; - unsigned long dwRPIs[8]; - bool bChannelSwitch; - unsigned char byNewChannel; - unsigned char byChannelSwitchCount; - bool bQuietEnable; - bool bEnableFirstQuiet; - unsigned char byQuietStartCount; - unsigned int uQuietEnqueue; - unsigned long dwCurrentQuietEndTime; - SQuietControl sQuiet[MAX_QUIET_COUNT]; - /* for 802.11h TPC */ - bool bCountryInfo5G; - bool bCountryInfo24G; unsigned short wBeaconInterval; - /* WPA supplicant deamon */ - struct net_device *wpadev; - bool bWPADEVUp; - struct sk_buff *skb; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - unsigned int bwextcount; - bool bWPASuppWextEnabled; -#endif - -#ifdef HOSTAP - /* user space daemon: hostapd, is used for HOSTAP */ - bool bEnableHostapd; - bool bEnable8021x; - bool bEnableHostWEP; - struct net_device *apdev; - int (*tx_80211)(struct sk_buff *skb, struct net_device *dev); -#endif unsigned int uChannel; - bool bMACSuspend; struct iw_statistics wstats; /* wireless stats */ - bool bCommit; }; -static inline bool device_get_ip(struct vnt_private *pInfo) -{ - struct in_device *in_dev = (struct in_device *)pInfo->dev->ip_ptr; - struct in_ifaddr *ifa; - - if (in_dev != NULL) { - ifa = (struct in_ifaddr *)in_dev->ifa_list; - if (ifa != NULL) { - memcpy(pInfo->abyIPAddr, &ifa->ifa_address, 4); - return true; - } - } - return false; -} - static inline PDEVICE_RD_INFO alloc_rd_info(void) { return kzalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC); -- GitLab From 9c644a05c67d276e0cf2b7985b312cd64bbab92d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:00 +0000 Subject: [PATCH 2117/9457] staging: vt6655: device.h remove dead strutures and macros Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 76 --------------------------------- 1 file changed, 76 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index bc33b2d8de4e..79c4ae02832c 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -147,16 +147,6 @@ #define NUM 64 -#define PRIVATE_Message 0 - -/*--------------------- Export Types ------------------------------*/ - -#define PRINT_K(p, args...) \ -do { \ - if (PRIVATE_Message) \ - printk(p, ##args); \ -} while (0) - /* 0:11A 1:11B 2:11G */ typedef enum _VIA_BB_TYPE { @@ -174,57 +164,6 @@ typedef enum _VIA_PKT_TYPE PK_TYPE_11GA } VIA_PKT_TYPE, *PVIA_PKT_TYPE; -typedef enum __device_msg_level { - MSG_LEVEL_ERR = 0, /* Errors that will cause abnormal operation. */ - MSG_LEVEL_NOTICE = 1, /* Some errors need users to be notified. */ - MSG_LEVEL_INFO = 2, /* Normal message. */ - MSG_LEVEL_VERBOSE = 3, /* Will report all trival errors. */ - MSG_LEVEL_DEBUG = 4 /* Only for debug purpose. */ -} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL; - -/* NDIS related */ -#define MAX_BSSIDINFO_4_PMKID 16 -#define MAX_PMKIDLIST 5 -/* Flags for PMKID Candidate list structure */ -#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 - -/* PMKID Structures */ -typedef unsigned char NDIS_802_11_PMKID_VALUE[16]; - -typedef enum _NDIS_802_11_WEP_STATUS { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent -} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, - NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; - -typedef enum _NDIS_802_11_STATUS_TYPE { - Ndis802_11StatusType_Authentication, - Ndis802_11StatusType_MediaStreamMode, - Ndis802_11StatusType_PMKID_CandidateList, - Ndis802_11StatusTypeMax /* defined as an upper bound */ -} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; - - -/* 802.11h related */ -#define MAX_QUIET_COUNT 8 - -typedef struct tagSQuietControl { - bool bEnable; - unsigned long dwStartTime; - unsigned char byPeriod; - unsigned short wDuration; -} SQuietControl, *PSQuietControl; - typedef struct __chip_info_tbl { CHIP_TYPE chip_id; char *name; @@ -238,20 +177,6 @@ typedef enum { OWNED_BY_NIC = 1 } DEVICE_OWNER_TYPE, *PDEVICE_OWNER_TYPE; -/* The receive duplicate detection cache entry */ -typedef struct tagSCacheEntry { - unsigned short wFmSequence; - unsigned char abyAddr2[ETH_ALEN]; -} SCacheEntry, *PSCacheEntry; - -typedef struct tagSCache { -/* The receive cache is updated circularly. The next entry to be written is - * indexed by the "InPtr". - */ - unsigned int uInPtr; /* Place to use next */ - SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; -} SCache, *PSCache; - #define CB_MAX_RX_FRAG 64 /* DeFragment Control Block, used for collecting fragments prior to reassembly */ typedef struct tagSDeFragControlBlock { @@ -361,7 +286,6 @@ struct vnt_private { volatile PSRxDesc aRD0Ring; volatile PSRxDesc aRD1Ring; volatile PSRxDesc pCurrRD[TYPE_MAXRD]; - SCache sDupRxCache; SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG]; unsigned int cbDFCB; -- GitLab From dd46cf735d3c95c6f5996716e55934ed40ad4d01 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:01 +0000 Subject: [PATCH 2118/9457] staging: vt6655: dead code remove 80211hdr.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211hdr.h | 318 ------------------------------ drivers/staging/vt6655/device.h | 1 - drivers/staging/vt6655/wmgr.h | 1 - 3 files changed, 320 deletions(-) delete mode 100644 drivers/staging/vt6655/80211hdr.h diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h deleted file mode 100644 index 36e14ec50564..000000000000 --- a/drivers/staging/vt6655/80211hdr.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: 80211hdr.h - * - * Purpose: 802.11 MAC headers related pre-defines and macros. - * - * - * Author: Lyndon Chen - * - * Date: Apr 8, 2002 - * - */ - -#ifndef __80211HDR_H__ -#define __80211HDR_H__ - -#include "ttype.h" - -/* bit type */ -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -/* 802.11 frame related, defined as 802.11 spec */ -#define WLAN_ADDR_LEN 6 -#define WLAN_CRC_LEN 4 -#define WLAN_CRC32_LEN 4 -#define WLAN_FCS_LEN 4 -#define WLAN_BSSID_LEN 6 -#define WLAN_BSS_TS_LEN 8 -#define WLAN_HDR_ADDR2_LEN 16 -#define WLAN_HDR_ADDR3_LEN 24 -#define WLAN_HDR_ADDR4_LEN 30 -#define WLAN_IEHDR_LEN 2 -#define WLAN_SSID_MAXLEN 32 -#define WLAN_RATES_MAXLEN 16 -#define WLAN_RATES_MAXLEN_11B 4 -#define WLAN_RSN_MAXLEN 32 -#define WLAN_DATA_MAXLEN 2312 -#define WLAN_A3FR_MAXLEN (WLAN_HDR_ADDR3_LEN + WLAN_DATA_MAXLEN + \ - WLAN_CRC_LEN) - -#define WLAN_BEACON_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0) -#define WLAN_NULLDATA_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0) -#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2) -#define WLAN_ASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_ASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_REASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_REASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_PROBEREQ_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_PROBERESP_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_AUTHEN_FR_MAXLEN WLAN_A3FR_MAXLEN -#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2) - -#define WLAN_WEP_NKEYS 4 -#define WLAN_WEP40_KEYLEN 5 -#define WLAN_WEP104_KEYLEN 13 -#define WLAN_WEP232_KEYLEN 29 -#define WLAN_WEPMAX_KEYLEN 32 -#define WLAN_CHALLENGE_IE_MAXLEN 255 -#define WLAN_CHALLENGE_IE_LEN 130 -#define WLAN_CHALLENGE_LEN 128 -#define WLAN_WEP_IV_LEN 4 -#define WLAN_WEP_ICV_LEN 4 -#define WLAN_FRAGS_MAX 16 - -/* Frame Type */ -#define WLAN_TYPE_MGR 0x00 -#define WLAN_TYPE_CTL 0x01 -#define WLAN_TYPE_DATA 0x02 - -#define WLAN_FTYPE_MGMT 0x00 -#define WLAN_FTYPE_CTL 0x01 -#define WLAN_FTYPE_DATA 0x02 - -/* Frame Subtypes */ -#define WLAN_FSTYPE_ASSOCREQ 0x00 -#define WLAN_FSTYPE_ASSOCRESP 0x01 -#define WLAN_FSTYPE_REASSOCREQ 0x02 -#define WLAN_FSTYPE_REASSOCRESP 0x03 -#define WLAN_FSTYPE_PROBEREQ 0x04 -#define WLAN_FSTYPE_PROBERESP 0x05 -#define WLAN_FSTYPE_BEACON 0x08 -#define WLAN_FSTYPE_ATIM 0x09 -#define WLAN_FSTYPE_DISASSOC 0x0a -#define WLAN_FSTYPE_AUTHEN 0x0b -#define WLAN_FSTYPE_DEAUTHEN 0x0c -#define WLAN_FSTYPE_ACTION 0x0d - -/* Control */ -#define WLAN_FSTYPE_PSPOLL 0x0a -#define WLAN_FSTYPE_RTS 0x0b -#define WLAN_FSTYPE_CTS 0x0c -#define WLAN_FSTYPE_ACK 0x0d -#define WLAN_FSTYPE_CFEND 0x0e -#define WLAN_FSTYPE_CFENDCFACK 0x0f - -/* Data */ -#define WLAN_FSTYPE_DATAONLY 0x00 -#define WLAN_FSTYPE_DATA_CFACK 0x01 -#define WLAN_FSTYPE_DATA_CFPOLL 0x02 -#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 -#define WLAN_FSTYPE_NULL 0x04 -#define WLAN_FSTYPE_CFACK 0x05 -#define WLAN_FSTYPE_CFPOLL 0x06 -#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 - -#ifdef __BIG_ENDIAN - -/* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) (((unsigned short)(n) >> 8) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((unsigned short)(n) >> 8) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((unsigned short)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((unsigned short)(n) << 8) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((unsigned short)(n) << 8) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n) << 8) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((unsigned short)(n) << 8) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((unsigned short)(n) << 8) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n) << 8) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((unsigned short)(n) << 8) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((unsigned short)(n) << 8) & (BIT15)) >> 15) - -/* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - -/* Capability Field bit */ -#define WLAN_GET_CAP_INFO_ESS(n) (((n) >> 8) & BIT0) -#define WLAN_GET_CAP_INFO_IBSS(n) ((((n) >> 8) & BIT1) >> 1) -#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) ((((n) >> 8) & BIT2) >> 2) -#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) ((((n) >> 8) & BIT3) >> 3) -#define WLAN_GET_CAP_INFO_PRIVACY(n) ((((n) >> 8) & BIT4) >> 4) -#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) ((((n) >> 8) & BIT5) >> 5) -#define WLAN_GET_CAP_INFO_PBCC(n) ((((n) >> 8) & BIT6) >> 6) -#define WLAN_GET_CAP_INFO_AGILITY(n) ((((n) >> 8) & BIT7) >> 7) -#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) ((((n)) & BIT8) >> 10) -#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) ((((n)) & BIT10) >> 10) -#define WLAN_GET_CAP_INFO_DSSSOFDM(n) ((((n)) & BIT13) >> 13) -#define WLAN_GET_CAP_INFO_GRPACK(n) ((((n)) & BIT14) >> 14) - -#else - -/* GET & SET Frame Control bit */ -#define WLAN_GET_FC_PRVER(n) (((unsigned short)(n)) & (BIT0 | BIT1)) -#define WLAN_GET_FC_FTYPE(n) ((((unsigned short)(n)) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((unsigned short)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((unsigned short)(n)) & (BIT8)) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((unsigned short)(n)) & (BIT9)) >> 9) -#define WLAN_GET_FC_MOREFRAG(n) ((((unsigned short)(n)) & (BIT10)) >> 10) -#define WLAN_GET_FC_RETRY(n) ((((unsigned short)(n)) & (BIT11)) >> 11) -#define WLAN_GET_FC_PWRMGT(n) ((((unsigned short)(n)) & (BIT12)) >> 12) -#define WLAN_GET_FC_MOREDATA(n) ((((unsigned short)(n)) & (BIT13)) >> 13) -#define WLAN_GET_FC_ISWEP(n) ((((unsigned short)(n)) & (BIT14)) >> 14) -#define WLAN_GET_FC_ORDER(n) ((((unsigned short)(n)) & (BIT15)) >> 15) - -/* Sequence Field bit */ -#define WLAN_GET_SEQ_FRGNUM(n) (((unsigned short)(n)) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((unsigned short)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - -/* Capability Field bit */ -#define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0) -#define WLAN_GET_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) -#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) -#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3) -#define WLAN_GET_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4) -#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) (((n) & BIT5) >> 5) -#define WLAN_GET_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6) -#define WLAN_GET_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7) -#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) (((n) & BIT8) >> 10) -#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) (((n) & BIT10) >> 10) -#define WLAN_GET_CAP_INFO_DSSSOFDM(n) (((n) & BIT13) >> 13) -#define WLAN_GET_CAP_INFO_GRPACK(n) (((n) & BIT14) >> 14) - -#endif /*#ifdef __BIG_ENDIAN */ - -#define WLAN_SET_CAP_INFO_ESS(n) (n) -#define WLAN_SET_CAP_INFO_IBSS(n) ((n) << 1) -#define WLAN_SET_CAP_INFO_CFPOLLABLE(n) ((n) << 2) -#define WLAN_SET_CAP_INFO_CFPOLLREQ(n) ((n) << 3) -#define WLAN_SET_CAP_INFO_PRIVACY(n) ((n) << 4) -#define WLAN_SET_CAP_INFO_SHORTPREAMBLE(n) ((n) << 5) -#define WLAN_SET_CAP_INFO_SPECTRUMMNG(n) ((n) << 8) -#define WLAN_SET_CAP_INFO_PBCC(n) ((n) << 6) -#define WLAN_SET_CAP_INFO_AGILITY(n) ((n) << 7) -#define WLAN_SET_CAP_INFO_SHORTSLOTTIME(n) ((n) << 10) -#define WLAN_SET_CAP_INFO_DSSSOFDM(n) ((n) << 13) -#define WLAN_SET_CAP_INFO_GRPACK(n) ((n) << 14) - -#define WLAN_SET_FC_PRVER(n) ((unsigned short)(n)) -#define WLAN_SET_FC_FTYPE(n) (((unsigned short)(n)) << 2) -#define WLAN_SET_FC_FSTYPE(n) (((unsigned short)(n)) << 4) -#define WLAN_SET_FC_TODS(n) (((unsigned short)(n)) << 8) -#define WLAN_SET_FC_FROMDS(n) (((unsigned short)(n)) << 9) -#define WLAN_SET_FC_MOREFRAG(n) (((unsigned short)(n)) << 10) -#define WLAN_SET_FC_RETRY(n) (((unsigned short)(n)) << 11) -#define WLAN_SET_FC_PWRMGT(n) (((unsigned short)(n)) << 12) -#define WLAN_SET_FC_MOREDATA(n) (((unsigned short)(n)) << 13) -#define WLAN_SET_FC_ISWEP(n) (((unsigned short)(n)) << 14) -#define WLAN_SET_FC_ORDER(n) (((unsigned short)(n)) << 15) - -#define WLAN_SET_SEQ_FRGNUM(n) ((unsigned short)(n)) -#define WLAN_SET_SEQ_SEQNUM(n) (((unsigned short)(n)) << 4) - -/* ERP Field bit */ - -#define WLAN_GET_ERP_NONERP_PRESENT(n) ((n) & BIT0) -#define WLAN_GET_ERP_USE_PROTECTION(n) (((n) & BIT1) >> 1) -#define WLAN_GET_ERP_BARKER_MODE(n) (((n) & BIT2) >> 2) - -#define WLAN_SET_ERP_NONERP_PRESENT(n) (n) -#define WLAN_SET_ERP_USE_PROTECTION(n) ((n) << 1) -#define WLAN_SET_ERP_BARKER_MODE(n) ((n) << 2) - -/* Support & Basic Rates field */ -#define WLAN_MGMT_IS_BASICRATE(b) ((b) & BIT7) -#define WLAN_MGMT_GET_RATE(b) ((b) & ~BIT7) - -/* TIM field */ -#define WLAN_MGMT_IS_MULTICAST_TIM(b) ((b) & BIT0) -#define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1) - -/* 3-Addr & 4-Addr */ -#define WLAN_HDR_A3_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR3_LEN) -#define WLAN_HDR_A4_DATA_PTR(p) (((unsigned char *)(p)) + WLAN_HDR_ADDR4_LEN) - -/* IEEE ADDR */ -#define IEEE_ADDR_UNIVERSAL 0x02 -#define IEEE_ADDR_GROUP 0x01 - -typedef struct { - unsigned char abyAddr[6]; -} IEEE_ADDR, *PIEEE_ADDR; - -/* 802.11 Header Format */ - -typedef struct tagWLAN_80211HDR_A2 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; - -typedef struct tagWLAN_80211HDR_A3 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A3, *PWLAN_80211HDR_A3; - -typedef struct tagWLAN_80211HDR_A4 { - unsigned short wFrameCtl; - unsigned short wDurationID; - unsigned char abyAddr1[WLAN_ADDR_LEN]; - unsigned char abyAddr2[WLAN_ADDR_LEN]; - unsigned char abyAddr3[WLAN_ADDR_LEN]; - unsigned short wSeqCtl; - unsigned char abyAddr4[WLAN_ADDR_LEN]; -} __attribute__ ((__packed__)) -WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; - -typedef union tagUWLAN_80211HDR { - WLAN_80211HDR_A2 sA2; - WLAN_80211HDR_A3 sA3; - WLAN_80211HDR_A4 sA4; -} UWLAN_80211HDR, *PUWLAN_80211HDR; - -#endif /* __80211HDR_H__ */ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 79c4ae02832c..e0c40690a3eb 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -68,7 +68,6 @@ #include "device_cfg.h" #include "ttype.h" -#include "80211hdr.h" #include "wmgr.h" #include "mib.h" #include "srom.h" diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 44976e0200bb..8f9748bf569d 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -35,7 +35,6 @@ #define __WMGR_H__ #include "ttype.h" -#include "80211hdr.h" #include "card.h" /*--------------------- Export Definitions -------------------------*/ -- GitLab From e11cdc39f381e541fbdc2eccf2c4fce910a4f2bb Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:02 +0000 Subject: [PATCH 2119/9457] staging: vt6655: remove typedef void *TimerFunction Covert functions TimerSQ3CallBack and TimerState1CallBack to the correct type for struct timer_list.function to remove the cast altogether. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 8 ++++---- drivers/staging/vt6655/baseband.h | 4 ++-- drivers/staging/vt6655/device_main.c | 6 +++--- drivers/staging/vt6655/wmgr.h | 1 - 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index ed7850558c96..b04dfd945d41 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2781,10 +2781,10 @@ void BBvAntennaDiversity(struct vnt_private *pDevice, void TimerSQ3CallBack( - void *hDeviceContext + unsigned long data ) { - struct vnt_private *pDevice = hDeviceContext; + struct vnt_private *pDevice = (struct vnt_private *)data; unsigned long flags; pr_debug("TimerSQ3CallBack...\n"); @@ -2827,10 +2827,10 @@ TimerSQ3CallBack( void TimerState1CallBack( - void *hDeviceContext + unsigned long data ) { - struct vnt_private *pDevice = hDeviceContext; + struct vnt_private *pDevice = (struct vnt_private *)data; unsigned long flags; pr_debug("TimerState1CallBack...\n"); diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 2d7a3e236fd6..772ea0df84e2 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -103,12 +103,12 @@ void BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID); void TimerSQ3CallBack( - void *hDeviceContext + unsigned long ); void TimerState1CallBack( - void *hDeviceContext + unsigned long ); void BBvAntennaDiversity(struct vnt_private *pDevice, diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 7892f861521e..5c91c2ff1491 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -625,17 +625,17 @@ static void device_init_diversity_timer(struct vnt_private *pDevice) { init_timer(&pDevice->TimerSQ3Tmax1); pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax1.function = TimerSQ3CallBack; pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax2); pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack; + pDevice->TimerSQ3Tmax2.function = TimerSQ3CallBack; pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax3); pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice; - pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack; + pDevice->TimerSQ3Tmax3.function = TimerState1CallBack; pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); } diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 8f9748bf569d..74f1f16b915e 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -72,6 +72,5 @@ /*--------------------- Export Types ------------------------------*/ #define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick)) -typedef void (*TimerFunction)(unsigned long); #endif // __WMGR_H__ -- GitLab From 1903e6dd0552d15a39664d71e4ebb9f0769969cc Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:03 +0000 Subject: [PATCH 2120/9457] staging: vt6655: Move LIFETIME RES 64us macros to rxtx.h Used only by vnt_generate_fifo_header move these macros. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.h | 4 ++++ drivers/staging/vt6655/wmgr.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 50d77a0f88ea..cf0dfa6f0a07 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -32,6 +32,10 @@ #include "ttype.h" #include "device.h" +#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ +#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */ + + /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Variables --------------------------*/ diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 74f1f16b915e..daf996cc9f27 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -51,10 +51,8 @@ #define WCMD_PASSIVE_SCAN_TIME 100 //(ms) #define DEFAULT_MSDU_LIFETIME 512 // ms -#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us #define DEFAULT_MGN_LIFETIME 8 // ms -#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us #define MAKE_BEACON_RESERVED 10 //(us) -- GitLab From c3fb46429be7d1dcbb0f3fc0c7a73cfb2b18c6cb Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:04 +0000 Subject: [PATCH 2121/9457] staging: vt6655: move MAKE_BEACON_RESERVED to device.h Used only in function device_intr in device_main.c move macro. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 2 ++ drivers/staging/vt6655/wmgr.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index e0c40690a3eb..45181a8b8a86 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -137,6 +137,8 @@ #define RUN_AT(x) (jiffies+(x)) #endif +#define MAKE_BEACON_RESERVED 10 /* (us) */ + /* DMA related */ #define RESERV_AC0DMA 4 diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index daf996cc9f27..ea23c7902646 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -54,8 +54,6 @@ #define DEFAULT_MGN_LIFETIME 8 // ms -#define MAKE_BEACON_RESERVED 10 //(us) - #define TIM_MULTICAST_MASK 0x01 #define TIM_BITMAPOFFSET_MASK 0xFE #define DEFAULT_DTIM_PERIOD 1 -- GitLab From 33785983ca3364bafc1c1ec805560ff83c9fdb0c Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:05 +0000 Subject: [PATCH 2122/9457] staging: vt6655: dead code remove wmgr.h on removal needs to be replaced by card.h in device.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 2 +- drivers/staging/vt6655/device_main.c | 1 - drivers/staging/vt6655/power.c | 1 - drivers/staging/vt6655/wmgr.h | 72 ---------------------------- 4 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 drivers/staging/vt6655/wmgr.h diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 45181a8b8a86..d0855bd3937f 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -68,7 +68,7 @@ #include "device_cfg.h" #include "ttype.h" -#include "wmgr.h" +#include "card.h" #include "mib.h" #include "srom.h" #include "desc.h" diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 5c91c2ff1491..f0b336bb393d 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -58,7 +58,6 @@ #include "channel.h" #include "baseband.h" #include "mac.h" -#include "wmgr.h" #include "power.h" #include "rxtx.h" #include "dpc.h" diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 6f83650db5a3..a8aedee18b6b 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -40,7 +40,6 @@ #include "ttype.h" #include "mac.h" #include "device.h" -#include "wmgr.h" #include "power.h" #include "card.h" diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h deleted file mode 100644 index ea23c7902646..000000000000 --- a/drivers/staging/vt6655/wmgr.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * - * File: wmgr.h - * - * Purpose: - * - * Author: lyndon chen - * - * Date: Jan 2, 2003 - * - * Functions: - * - * Revision History: - * - */ - -#ifndef __WMGR_H__ -#define __WMGR_H__ - -#include "ttype.h" -#include "card.h" - -/*--------------------- Export Definitions -------------------------*/ - -// Scan time -#define PROBE_DELAY 100 // (us) -#define SWITCH_CHANNEL_DELAY 200 // (us) -#define WLAN_SCAN_MINITIME 25 // (ms) -#define WLAN_SCAN_MAXTIME 100 // (ms) -#define TRIVIAL_SYNC_DIFFERENCE 0 // (us) -#define DEFAULT_IBSS_BI 100 // (ms) - -#define WCMD_ACTIVE_SCAN_TIME 50 //(ms) -#define WCMD_PASSIVE_SCAN_TIME 100 //(ms) - -#define DEFAULT_MSDU_LIFETIME 512 // ms - -#define DEFAULT_MGN_LIFETIME 8 // ms - -#define TIM_MULTICAST_MASK 0x01 -#define TIM_BITMAPOFFSET_MASK 0xFE -#define DEFAULT_DTIM_PERIOD 1 - -#define AP_LONG_RETRY_LIMIT 4 - -#define DEFAULT_IBSS_CHANNEL 6 //2.4G - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Types ------------------------------*/ -#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick)) - -#endif // __WMGR_H__ -- GitLab From 0fbdd5ca6f83ca4c60f797b9900c3eb61386ae3a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 29 Oct 2014 17:56:06 +0000 Subject: [PATCH 2123/9457] staging: vt6655: dead code remove header type.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.h | 1 - drivers/staging/vt6655/card.h | 1 - drivers/staging/vt6655/channel.h | 1 - drivers/staging/vt6655/desc.h | 1 - drivers/staging/vt6655/device.h | 1 - drivers/staging/vt6655/device_cfg.h | 2 -- drivers/staging/vt6655/key.h | 2 -- drivers/staging/vt6655/mac.h | 1 - drivers/staging/vt6655/mib.h | 1 - drivers/staging/vt6655/power.c | 1 - drivers/staging/vt6655/rf.h | 1 - drivers/staging/vt6655/rxtx.h | 1 - drivers/staging/vt6655/srom.h | 2 -- drivers/staging/vt6655/tmacro.h | 2 -- drivers/staging/vt6655/ttype.h | 42 ----------------------------- drivers/staging/vt6655/upc.h | 1 - 16 files changed, 61 deletions(-) delete mode 100644 drivers/staging/vt6655/ttype.h diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 772ea0df84e2..bfdd422c490f 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -30,7 +30,6 @@ #ifndef __BASEBAND_H__ #define __BASEBAND_H__ -#include "ttype.h" #include "device.h" /* diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index fa1e692ca8a0..f12afefd7fd8 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -29,7 +29,6 @@ #ifndef __CARD_H__ #define __CARD_H__ -#include "ttype.h" #include #include diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index ee00f4e3d52f..4f4264e23462 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -23,7 +23,6 @@ #ifndef _CHANNEL_H_ #define _CHANNEL_H_ -#include "ttype.h" #include "card.h" void vnt_init_bands(struct vnt_private *); diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 32dd1cab7dcf..758eeb2afd51 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -34,7 +34,6 @@ #include #include #include "linux/ieee80211.h" -#include "ttype.h" #define B_OWNED_BY_CHIP 1 #define B_OWNED_BY_HOST 0 diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index d0855bd3937f..93d2ccb9ba67 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -67,7 +67,6 @@ /* device specific */ #include "device_cfg.h" -#include "ttype.h" #include "card.h" #include "mib.h" #include "srom.h" diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h index 7221824e4f23..a4a8a8489e0b 100644 --- a/drivers/staging/vt6655/device_cfg.h +++ b/drivers/staging/vt6655/device_cfg.h @@ -29,8 +29,6 @@ #include -#include "ttype.h" - typedef struct _version { unsigned char major; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 5615f397f6e7..c01d4afb6ab8 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -32,8 +32,6 @@ #include -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ #define MAX_GROUP_KEY 4 #define MAX_KEY_TABLE 11 diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index 0bf93759b6af..5391277a1a19 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -34,7 +34,6 @@ #ifndef __MAC_H__ #define __MAC_H__ -#include "ttype.h" #include "tmacro.h" #include "upc.h" diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index a2e6106b4570..5cb59b8a1c7c 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -29,7 +29,6 @@ #ifndef __MIB_H__ #define __MIB_H__ -#include "ttype.h" #include "desc.h" // diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index a8aedee18b6b..e826f07e91c0 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -37,7 +37,6 @@ * */ -#include "ttype.h" #include "mac.h" #include "device.h" #include "power.h" diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index be4ef88b7666..e8a7372e5483 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -30,7 +30,6 @@ #ifndef __RF_H__ #define __RF_H__ -#include "ttype.h" #include "device.h" /*--------------------- Export Definitions -------------------------*/ diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index cf0dfa6f0a07..b9bd1639b13e 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -29,7 +29,6 @@ #ifndef __RXTX_H__ #define __RXTX_H__ -#include "ttype.h" #include "device.h" #define DEFAULT_MSDU_LIFETIME_RES_64us 8000 /* 64us */ diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h index 3128e535bbd8..9f309c401770 100644 --- a/drivers/staging/vt6655/srom.h +++ b/drivers/staging/vt6655/srom.h @@ -30,8 +30,6 @@ #ifndef __SROM_H__ #define __SROM_H__ -#include "ttype.h" - /*--------------------- Export Definitions -------------------------*/ #define EEP_MAX_CONTEXT_SIZE 256 diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h index 59c6e72f993a..607b78f7a6a0 100644 --- a/drivers/staging/vt6655/tmacro.h +++ b/drivers/staging/vt6655/tmacro.h @@ -29,8 +29,6 @@ #ifndef __TMACRO_H__ #define __TMACRO_H__ -#include "ttype.h" - /****** Common helper macros ***********************************************/ #if !defined(LOBYTE) diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h deleted file mode 100644 index 747ef62ec9be..000000000000 --- a/drivers/staging/vt6655/ttype.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: ttype.h - * - * Purpose: define basic common types and macros - * - * Author: Tevin Chen - * - * Date: May 21, 1996 - * - */ - -#ifndef __TTYPE_H__ -#define __TTYPE_H__ - -/******* Common definitions and typedefs ***********************************/ - -#ifndef WPA_SM_Transtatus -#define WPA_SM_Transtatus -#endif - -#ifndef Calcu_LinkQual -#define Calcu_LinkQual -#endif - -#endif // __TTYPE_H__ diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index c5c889cade25..c53703a772f5 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -30,7 +30,6 @@ #define __UPC_H__ #include "device.h" -#include "ttype.h" /*--------------------- Export Definitions -------------------------*/ -- GitLab From 6b7b4b8941b727af5fdc73b6a0910ede4c06cf11 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 29 Oct 2014 17:40:41 +0000 Subject: [PATCH 2124/9457] ASoC: Intel: Add PM support to the HSW/BDW DSP core. Add support for PM wake, sleep and stall calls to the core HSW/BDW driver. This includes reworking the reset and boot code and adding new calls for setting D3/D0 state. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-dsp.c | 158 ++++++++++++++++++++++-------- 1 file changed, 119 insertions(+), 39 deletions(-) diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 5058dc8bfed0..86aea343bfec 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c @@ -247,8 +247,67 @@ static irqreturn_t hsw_irq(int irq, void *context) return ret; } -static void hsw_boot(struct sst_dsp *sst) +static void hsw_set_dsp_D3(struct sst_dsp *sst) +{ + u32 val; + + /* switch off audio PLL, DRAM & IRAM blocks */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + val |= SST_VDRTCL0_APLLSE_MASK | SST_VDRTCL0_DSRAMPGE_MASK | + SST_VDRTCL0_ISRAMPGE_MASK; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL0); + + /* Set D3 state */ + val = readl(sst->addr.pci_cfg + SST_PMCS); + val |= SST_PMCS_PS_MASK; + writel(val, sst->addr.pci_cfg + SST_PMCS); +} + +static void hsw_reset(struct sst_dsp *sst) +{ + /* put DSP into reset and stall */ + sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, + SST_CSR_RST | SST_CSR_STALL, + SST_CSR_RST | SST_CSR_STALL); + + /* keep in reset for 10ms */ + mdelay(10); + + /* take DSP out of reset and keep stalled for FW loading */ + sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, + SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL); +} + +static int hsw_set_dsp_D0(struct sst_dsp *sst) { + int tries = 10; + u32 reg; + + /* Set D0 state */ + reg = readl(sst->addr.pci_cfg + SST_PMCS); + reg &= ~SST_PMCS_PS_MASK; + writel(reg, sst->addr.pci_cfg + SST_PMCS); + + /* check that ADSP shim is enabled */ + while (tries--) { + reg = readl(sst->addr.pci_cfg + SST_PMCS) & SST_PMCS_PS_MASK; + if (reg == 0) + goto finish; + + msleep(1); + } + + return -ENODEV; + +finish: + hsw_reset(sst); + + /* switch on audio PLL, DRAM & IRAM blocks */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg &= ~(SST_VDRTCL0_APLLSE_MASK | SST_VDRTCL0_DSRAMPGE_MASK | + SST_VDRTCL0_ISRAMPGE_MASK); + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); + /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0); @@ -267,30 +326,73 @@ static void hsw_boot(struct sst_dsp *sst) sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1, SST_CSR2_SDFD_SSP1); - /* enable DMA engine 0,1 all channels to access host memory */ - sst_dsp_shim_update_bits_unlocked(sst, SST_HMDC, - SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff), - SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff)); + /* set on-demond mode on engine 0,1 for all channels */ + sst_dsp_shim_update_bits(sst, SST_HMDC, + SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH, + SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH); + + /* Enable Interrupt from both sides */ + sst_dsp_shim_update_bits(sst, SST_IMRX, (SST_IMRX_BUSY | SST_IMRX_DONE), + 0x0); + sst_dsp_shim_update_bits(sst, SST_IMRD, (SST_IMRD_DONE | SST_IMRD_BUSY | + SST_IMRD_SSP0 | SST_IMRD_DMAC), 0x0); + + /* clear IPC registers */ + sst_dsp_shim_write(sst, SST_IPCX, 0x0); + sst_dsp_shim_write(sst, SST_IPCD, 0x0); + sst_dsp_shim_write(sst, 0x80, 0x6); + sst_dsp_shim_write(sst, 0xe0, 0x300a); /* disable all clock gating */ writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL2); + return 0; +} + +static void hsw_boot(struct sst_dsp *sst) +{ + /* set oportunistic mode on engine 0,1 for all channels */ + sst_dsp_shim_update_bits(sst, SST_HMDC, + SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH, 0); + /* set DSP to RUN */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_STALL, 0x0); } -static void hsw_reset(struct sst_dsp *sst) +static void hsw_stall(struct sst_dsp *sst) { + /* stall DSP */ + sst_dsp_shim_update_bits(sst, SST_CSR, + SST_CSR_24MHZ_LPCS | SST_CSR_STALL, + SST_CSR_STALL | SST_CSR_24MHZ_LPCS); +} + +static void hsw_sleep(struct sst_dsp *sst) +{ + dev_dbg(sst->dev, "HSW_PM dsp runtime suspend\n"); + /* put DSP into reset and stall */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_RST | SST_CSR_STALL, SST_CSR_RST | SST_CSR_STALL); + sst_dsp_shim_update_bits(sst, SST_CSR, + SST_CSR_24MHZ_LPCS | SST_CSR_RST | SST_CSR_STALL, + SST_CSR_RST | SST_CSR_STALL | SST_CSR_24MHZ_LPCS); - /* keep in reset for 10ms */ - mdelay(10); + hsw_set_dsp_D3(sst); + dev_dbg(sst->dev, "HSW_PM dsp runtime suspend exit\n"); +} - /* take DSP out of reset and keep stalled for FW loading */ - sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, - SST_CSR_RST | SST_CSR_STALL, SST_CSR_STALL); +static int hsw_wake(struct sst_dsp *sst) +{ + int ret; + + dev_dbg(sst->dev, "HSW_PM dsp runtime resume\n"); + + ret = hsw_set_dsp_D0(sst); + if (ret < 0) + return ret; + + dev_dbg(sst->dev, "HSW_PM dsp runtime resume exit\n"); + + return 0; } struct sst_adsp_memregion { @@ -431,27 +533,6 @@ static struct sst_block_ops sst_hsw_ops = { .disable = hsw_block_disable, }; -static int hsw_enable_shim(struct sst_dsp *sst) -{ - int tries = 10; - u32 reg; - - /* enable shim */ - reg = readl(sst->addr.pci_cfg + SST_SHIM_PM_REG); - writel(reg & ~0x3, sst->addr.pci_cfg + SST_SHIM_PM_REG); - - /* check that ADSP shim is enabled */ - while (tries--) { - reg = sst_dsp_shim_read_unlocked(sst, SST_CSR); - if (reg != 0xffffffff) - return 0; - - msleep(1); - } - - return -ENODEV; -} - static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) { const struct sst_adsp_memregion *region; @@ -490,7 +571,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) } /* enable the DSP SHIM */ - ret = hsw_enable_shim(sst); + ret = hsw_set_dsp_D0(sst); if (ret < 0) { dev_err(dev, "error: failed to set DSP D0 and reset SHIM\n"); return ret; @@ -500,10 +581,6 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) if (ret) return ret; - /* Enable Interrupt from both sides */ - sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 0x3, 0x0); - sst_dsp_shim_update_bits_unlocked(sst, SST_IMRD, - (0x3 | 0x1 << 16 | 0x3 << 21), 0x0); /* register DSP memory blocks - ideally we should get this from ACPI */ for (i = 0; i < region_count; i++) { @@ -535,6 +612,9 @@ static void hsw_free(struct sst_dsp *sst) struct sst_ops haswell_ops = { .reset = hsw_reset, .boot = hsw_boot, + .stall = hsw_stall, + .wake = hsw_wake, + .sleep = hsw_sleep, .write = sst_shim32_write, .read = sst_shim32_read, .write64 = sst_shim32_write64, -- GitLab From aed3c7b77c85ed7060f1f56bfa909d2a86ab2a20 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 29 Oct 2014 17:40:42 +0000 Subject: [PATCH 2125/9457] ASoC: Intel: Add PM support to HSW/BDW IPC driver Add PM and RTD3 support to the HSW/BDW IPC driver. This patch saves and restores the DSP context, loads and unloads FW and drops any pending IPC messages after suspend. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 256 +++++++++++++++++++++++++++++- sound/soc/intel/sst-haswell-ipc.h | 7 + 2 files changed, 258 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 770d46708dcb..b37d3ee20dba 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "sst-haswell-ipc.h" #include "sst-dsp.h" @@ -276,6 +277,7 @@ struct sst_hsw { struct sst_hsw_ipc_fw_version version; struct sst_module *scratch; bool fw_done; + struct sst_fw *sst_fw; /* stream */ struct list_head stream_list; @@ -289,6 +291,8 @@ struct sst_hsw { /* DX */ struct sst_hsw_ipc_dx_reply dx; + void *dx_context; + dma_addr_t dx_context_paddr; /* boot */ wait_queue_head_t boot_wait; @@ -1707,6 +1711,237 @@ void sst_hsw_runtime_module_free(struct sst_module_runtime *runtime) sst_module_runtime_free(runtime); } +#ifdef CONFIG_PM_RUNTIME +static int sst_hsw_dx_state_dump(struct sst_hsw *hsw) +{ + struct sst_dsp *sst = hsw->dsp; + u32 item, offset, size; + int ret = 0; + + trace_ipc_request("PM state dump. Items #", SST_HSW_MAX_DX_REGIONS); + + if (hsw->dx.entries_no > SST_HSW_MAX_DX_REGIONS) { + dev_err(hsw->dev, + "error: number of FW context regions greater than %d\n", + SST_HSW_MAX_DX_REGIONS); + memset(&hsw->dx, 0, sizeof(hsw->dx)); + return -EINVAL; + } + + ret = sst_dsp_dma_get_channel(sst, 0); + if (ret < 0) { + dev_err(hsw->dev, "error: cant allocate dma channel %d\n", ret); + return ret; + } + + /* set on-demond mode on engine 0 channel 3 */ + sst_dsp_shim_update_bits(sst, SST_HMDC, + SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH, + SST_HMDC_HDDA_E0_ALLCH | SST_HMDC_HDDA_E1_ALLCH); + + for (item = 0; item < hsw->dx.entries_no; item++) { + if (hsw->dx.mem_info[item].source == SST_HSW_DX_TYPE_MEMORY_DUMP + && hsw->dx.mem_info[item].offset > DSP_DRAM_ADDR_OFFSET + && hsw->dx.mem_info[item].offset < + DSP_DRAM_ADDR_OFFSET + SST_HSW_DX_CONTEXT_SIZE) { + + offset = hsw->dx.mem_info[item].offset + - DSP_DRAM_ADDR_OFFSET; + size = (hsw->dx.mem_info[item].size + 3) & (~3); + + ret = sst_dsp_dma_copyfrom(sst, hsw->dx_context_paddr + offset, + sst->addr.lpe_base + offset, size); + if (ret < 0) { + dev_err(hsw->dev, + "error: FW context dump failed\n"); + memset(&hsw->dx, 0, sizeof(hsw->dx)); + goto out; + } + } + } + +out: + sst_dsp_dma_put_channel(sst); + return ret; +} + +static int sst_hsw_dx_state_restore(struct sst_hsw *hsw) +{ + struct sst_dsp *sst = hsw->dsp; + u32 item, offset, size; + int ret; + + for (item = 0; item < hsw->dx.entries_no; item++) { + if (hsw->dx.mem_info[item].source == SST_HSW_DX_TYPE_MEMORY_DUMP + && hsw->dx.mem_info[item].offset > DSP_DRAM_ADDR_OFFSET + && hsw->dx.mem_info[item].offset < + DSP_DRAM_ADDR_OFFSET + SST_HSW_DX_CONTEXT_SIZE) { + + offset = hsw->dx.mem_info[item].offset + - DSP_DRAM_ADDR_OFFSET; + size = (hsw->dx.mem_info[item].size + 3) & (~3); + + ret = sst_dsp_dma_copyto(sst, sst->addr.lpe_base + offset, + hsw->dx_context_paddr + offset, size); + if (ret < 0) { + dev_err(hsw->dev, + "error: FW context restore failed\n"); + return ret; + } + } + } + + return 0; +} + +static void sst_hsw_drop_all(struct sst_hsw *hsw) +{ + struct ipc_message *msg, *tmp; + unsigned long flags; + int tx_drop_cnt = 0, rx_drop_cnt = 0; + + /* drop all TX and Rx messages before we stall + reset DSP */ + spin_lock_irqsave(&hsw->dsp->spinlock, flags); + + list_for_each_entry_safe(msg, tmp, &hsw->tx_list, list) { + list_move(&msg->list, &hsw->empty_list); + tx_drop_cnt++; + } + + list_for_each_entry_safe(msg, tmp, &hsw->rx_list, list) { + list_move(&msg->list, &hsw->empty_list); + rx_drop_cnt++; + } + + spin_unlock_irqrestore(&hsw->dsp->spinlock, flags); + + if (tx_drop_cnt || rx_drop_cnt) + dev_err(hsw->dev, "dropped IPC msg RX=%d, TX=%d\n", + tx_drop_cnt, rx_drop_cnt); +} + +int sst_hsw_dsp_load(struct sst_hsw *hsw) +{ + struct sst_dsp *dsp = hsw->dsp; + int ret; + + dev_dbg(hsw->dev, "loading audio DSP...."); + + ret = sst_dsp_wake(dsp); + if (ret < 0) { + dev_err(hsw->dev, "error: failed to wake audio DSP\n"); + return -ENODEV; + } + + ret = sst_dsp_dma_get_channel(dsp, 0); + if (ret < 0) { + dev_err(hsw->dev, "error: cant allocate dma channel %d\n", ret); + return ret; + } + + ret = sst_fw_reload(hsw->sst_fw); + if (ret < 0) { + dev_err(hsw->dev, "error: SST FW reload failed\n"); + sst_dsp_dma_put_channel(dsp); + return -ENOMEM; + } + + sst_dsp_dma_put_channel(dsp); + return 0; +} + +static int sst_hsw_dsp_restore(struct sst_hsw *hsw) +{ + struct sst_dsp *dsp = hsw->dsp; + int ret; + + dev_dbg(hsw->dev, "restoring audio DSP...."); + + ret = sst_dsp_dma_get_channel(dsp, 0); + if (ret < 0) { + dev_err(hsw->dev, "error: cant allocate dma channel %d\n", ret); + return ret; + } + + ret = sst_hsw_dx_state_restore(hsw); + if (ret < 0) { + dev_err(hsw->dev, "error: SST FW context restore failed\n"); + sst_dsp_dma_put_channel(dsp); + return -ENOMEM; + } + sst_dsp_dma_put_channel(dsp); + + /* wait for DSP boot completion */ + sst_dsp_boot(dsp); + + return ret; +} + +int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw) +{ + int ret; + + dev_dbg(hsw->dev, "audio dsp runtime suspend\n"); + + ret = sst_hsw_dx_set_state(hsw, SST_HSW_DX_STATE_D3, &hsw->dx); + if (ret < 0) + return ret; + + sst_dsp_stall(hsw->dsp); + + ret = sst_hsw_dx_state_dump(hsw); + if (ret < 0) + return ret; + + sst_hsw_drop_all(hsw); + + return 0; +} + +int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw) +{ + sst_fw_unload(hsw->sst_fw); + sst_block_free_scratch(hsw->dsp); + + hsw->boot_complete = false; + + sst_dsp_sleep(hsw->dsp); + + return 0; +} + +int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw) +{ + struct device *dev = hsw->dev; + int ret; + + dev_dbg(dev, "audio dsp runtime resume\n"); + + if (hsw->boot_complete) + return 1; /* tell caller no action is required */ + + ret = sst_hsw_dsp_restore(hsw); + if (ret < 0) + dev_err(dev, "error: audio DSP boot failure\n"); + + ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, + msecs_to_jiffies(IPC_BOOT_MSECS)); + if (ret == 0) { + dev_err(hsw->dev, "error: audio DSP boot timeout\n"); + return -EIO; + } + + /* Set ADSP SSP port settings */ + ret = sst_hsw_device_set_config(hsw, SST_HSW_DEVICE_SSP_0, + SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, + SST_HSW_DEVICE_CLOCK_MASTER, 9); + if (ret < 0) + dev_err(dev, "error: SSP re-initialization failed\n"); + + return ret; +} +#endif + static int msg_empty_list_init(struct sst_hsw *hsw) { int i; @@ -1738,7 +1973,6 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) { struct sst_hsw_ipc_fw_version version; struct sst_hsw *hsw; - struct sst_fw *hsw_sst_fw; int ret; dev_dbg(dev, "initialising Audio DSP IPC\n"); @@ -1780,12 +2014,19 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) goto dsp_err; } + /* allocate DMA buffer for context storage */ + hsw->dx_context = dma_alloc_coherent(hsw->dsp->dma_dev, + SST_HSW_DX_CONTEXT_SIZE, &hsw->dx_context_paddr, GFP_KERNEL); + if (hsw->dx_context == NULL) { + ret = -ENOMEM; + goto dma_err; + } + /* keep the DSP in reset state for base FW loading */ sst_dsp_reset(hsw->dsp); - hsw_sst_fw = sst_fw_new(hsw->dsp, pdata->fw, hsw); - - if (hsw_sst_fw == NULL) { + hsw->sst_fw = sst_fw_new(hsw->dsp, pdata->fw, hsw); + if (hsw->sst_fw == NULL) { ret = -ENODEV; dev_err(dev, "error: failed to load firmware\n"); goto fw_err; @@ -1816,8 +2057,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) boot_err: sst_dsp_reset(hsw->dsp); - sst_fw_free(hsw_sst_fw); + sst_fw_free(hsw->sst_fw); fw_err: + dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, + hsw->dx_context, hsw->dx_context_paddr); +dma_err: sst_dsp_free(hsw->dsp); dsp_err: kthread_stop(hsw->tx_thread); @@ -1834,6 +2078,8 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata) sst_dsp_reset(hsw->dsp); sst_fw_free_all(hsw->dsp); + dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, + hsw->dx_context, hsw->dx_context_paddr); sst_dsp_free(hsw->dsp); kfree(hsw->scratch); kthread_stop(hsw->tx_thread); diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index fe6e63f6524a..afd0ae10e2db 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h @@ -23,6 +23,7 @@ #define SST_HSW_NO_CHANNELS 2 #define SST_HSW_MAX_DX_REGIONS 14 +#define SST_HSW_DX_CONTEXT_SIZE (640 * 1024) #define SST_HSW_FW_LOG_CONFIG_DWORDS 12 #define SST_HSW_GLOBAL_LOG 15 @@ -492,4 +493,10 @@ struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw, int mod_id, int offset); void sst_hsw_runtime_module_free(struct sst_module_runtime *runtime); +/* PM */ +int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw); +int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw); +int sst_hsw_dsp_load(struct sst_hsw *hsw); +int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw); + #endif -- GitLab From 2e4f75919e5a02d605b0d84425251654d48fb056 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Wed, 29 Oct 2014 17:40:43 +0000 Subject: [PATCH 2126/9457] ASoC: Intel: Add PM support to HSW/BDW PCM driver Add PM and RTD3 support to the HSW/BDW PCM driver. The PCM driver will now save DSP context and then power off the DSP when it's not in use. DSP power and context is then restored when it's next used. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-dsp.h | 3 + sound/soc/intel/sst-haswell-pcm.c | 271 ++++++++++++++++++++++++++++-- 2 files changed, 260 insertions(+), 14 deletions(-) diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h index 7bb482053489..2753b85ac863 100644 --- a/sound/soc/intel/sst-dsp.h +++ b/sound/soc/intel/sst-dsp.h @@ -30,6 +30,9 @@ #define SST_DMA_TYPE_DW 1 #define SST_DMA_TYPE_MID 2 +/* autosuspend delay 5s*/ +#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000) + /* SST Shim register map * The register naming can differ between products. Some products also * contain extra functionality. diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 522edef20c86..4489a35e691e 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,13 @@ static const u32 volume_map[] = { #define HSW_PCM_PERIODS_MAX 64 #define HSW_PCM_PERIODS_MIN 2 +#define HSW_PCM_DAI_ID_SYSTEM 0 +#define HSW_PCM_DAI_ID_OFFLOAD0 1 +#define HSW_PCM_DAI_ID_OFFLOAD1 2 +#define HSW_PCM_DAI_ID_LOOPBACK 3 +#define HSW_PCM_DAI_ID_CAPTURE 4 + + static const struct snd_pcm_hardware hsw_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -99,6 +107,8 @@ struct hsw_pcm_data { int dai_id; struct sst_hsw_stream *stream; struct sst_module_runtime *runtime; + struct sst_module_runtime_context context; + struct snd_pcm *hsw_pcm; u32 volume[2]; struct snd_pcm_substream *substream; struct snd_compr_stream *cstream; @@ -108,10 +118,18 @@ struct hsw_pcm_data { int persistent_offset; }; +enum hsw_pm_state { + HSW_PM_STATE_D3 = 0, + HSW_PM_STATE_D0 = 1, +}; + /* private data for the driver */ struct hsw_priv_data { /* runtime DSP */ struct sst_hsw *hsw; + struct device *dev; + enum hsw_pm_state pm_state; + struct snd_soc_card *soc_card; /* page tables */ struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; @@ -145,21 +163,25 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value) static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); - struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + struct hsw_priv_data *pdata = + snd_soc_platform_get_drvdata(platform); struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; struct sst_hsw *hsw = pdata->hsw; u32 volume; mutex_lock(&pcm_data->mutex); + pm_runtime_get_sync(pdata->dev); if (!pcm_data->stream) { pcm_data->volume[0] = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); pcm_data->volume[1] = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return 0; } @@ -175,6 +197,8 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume); } + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return 0; } @@ -182,21 +206,25 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); - struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + struct hsw_priv_data *pdata = + snd_soc_platform_get_drvdata(platform); struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; struct sst_hsw *hsw = pdata->hsw; u32 volume; mutex_lock(&pcm_data->mutex); + pm_runtime_get_sync(pdata->dev); if (!pcm_data->stream) { ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(pcm_data->volume[0]); ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(pcm_data->volume[1]); + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return 0; } @@ -205,6 +233,9 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume); ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); + + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return 0; @@ -213,11 +244,13 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, static int hsw_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); - struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); + struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; u32 volume; + pm_runtime_get_sync(pdata->dev); + if (ucontrol->value.integer.value[0] == ucontrol->value.integer.value[1]) { @@ -232,23 +265,28 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol, sst_hsw_mixer_set_volume(hsw, 0, 1, volume); } + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); return 0; } static int hsw_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); - struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); + struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; unsigned int volume = 0; + pm_runtime_get_sync(pdata->dev); sst_hsw_mixer_get_volume(hsw, 0, 0, &volume); ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); sst_hsw_mixer_get_volume(hsw, 0, 1, &volume); ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); return 0; } @@ -577,6 +615,7 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream) pcm_data = &pdata->pcm[rtd->cpu_dai->id]; mutex_lock(&pcm_data->mutex); + pm_runtime_get_sync(pdata->dev); snd_soc_pcm_set_drvdata(rtd, pcm_data); pcm_data->substream = substream; @@ -587,6 +626,8 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream) hsw_notify_pointer, pcm_data); if (pcm_data->stream == NULL) { dev_err(rtd->dev, "error: failed to create stream\n"); + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return -EINVAL; } @@ -626,6 +667,8 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream) pcm_data->stream = NULL; out: + pm_runtime_mark_last_busy(pdata->dev); + pm_runtime_put_autosuspend(pdata->dev); mutex_unlock(&pcm_data->mutex); return ret; } @@ -643,11 +686,11 @@ static struct snd_pcm_ops hsw_pcm_ops = { /* static mappings between PCMs and modules - may be dynamic in future */ static struct hsw_pcm_module_map mod_map[] = { - {0, SST_HSW_MODULE_PCM_SYSTEM}, /* "System Pin" */ - {1, SST_HSW_MODULE_PCM}, /* "Offload0 Pin" */ - {2, SST_HSW_MODULE_PCM}, /* "Offload1 Pin" */ - {3, SST_HSW_MODULE_PCM_REFERENCE}, /* "Loopback Pin" */ - {4, SST_HSW_MODULE_PCM_CAPTURE}, /* "Capture Pin" */ + {HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM}, + {HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM}, + {HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM}, + {HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE}, + {HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE}, }; static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) @@ -659,6 +702,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) for (i = 0; i < ARRAY_SIZE(mod_map); i++) { pcm_data = &pdata->pcm[i]; + /* create new runtime module, use same offset if recreated */ pcm_data->runtime = sst_hsw_runtime_module_create(hsw, mod_map[i].mod_id, pcm_data->persistent_offset); if (pcm_data->runtime == NULL) @@ -700,6 +744,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) struct snd_pcm *pcm = rtd->pcm; struct snd_soc_platform *platform = rtd->platform; struct sst_pdata *pdata = dev_get_platdata(platform->dev); + struct hsw_priv_data *priv_data = dev_get_drvdata(platform->dev); struct device *dev = pdata->dma_dev; int ret = 0; @@ -716,6 +761,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } } + priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm; return ret; } @@ -728,6 +774,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_dai_driver hsw_dais[] = { { .name = "System Pin", + .id = HSW_PCM_DAI_ID_SYSTEM, .playback = { .stream_name = "System Playback", .channels_min = 2, @@ -739,6 +786,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { { /* PCM */ .name = "Offload0 Pin", + .id = HSW_PCM_DAI_ID_OFFLOAD0, .playback = { .stream_name = "Offload0 Playback", .channels_min = 2, @@ -750,6 +798,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { { /* PCM */ .name = "Offload1 Pin", + .id = HSW_PCM_DAI_ID_OFFLOAD1, .playback = { .stream_name = "Offload1 Playback", .channels_min = 2, @@ -760,6 +809,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { }, { .name = "Loopback Pin", + .id = HSW_PCM_DAI_ID_LOOPBACK, .capture = { .stream_name = "Loopback Capture", .channels_min = 2, @@ -770,6 +820,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { }, { .name = "Capture Pin", + .id = HSW_PCM_DAI_ID_CAPTURE, .capture = { .stream_name = "Analog Capture", .channels_min = 2, @@ -808,9 +859,21 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) { struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform); struct sst_pdata *pdata = dev_get_platdata(platform->dev); - struct device *dma_dev = pdata->dma_dev; + struct device *dma_dev, *dev; int i, ret = 0; + if (!pdata) + return -ENODEV; + + dev = platform->dev; + dma_dev = pdata->dma_dev; + + priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL); + priv_data->hsw = pdata->dsp; + priv_data->dev = platform->dev; + priv_data->pm_state = HSW_PM_STATE_D0; + priv_data->soc_card = platform->component.card; + /* allocate DSP buffer page tables */ for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { @@ -836,6 +899,13 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) /* allocate runtime modules */ hsw_pcm_create_modules(priv_data); + /* enable runtime PM with auto suspend */ + pm_runtime_set_autosuspend_delay(platform->dev, + SST_RUNTIME_SUSPEND_DELAY); + pm_runtime_use_autosuspend(platform->dev); + pm_runtime_enable(platform->dev); + pm_runtime_idle(platform->dev); + return 0; err: @@ -854,6 +924,9 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform) snd_soc_platform_get_drvdata(platform); int i; + pm_runtime_disable(platform->dev); + hsw_pcm_free_modules(priv_data); + for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { if (hsw_dais[i].playback.channels_min) snd_dma_free_pages(&priv_data->dmab[i][0]); @@ -931,10 +1004,180 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +#ifdef CONFIG_PM_RUNTIME + +static int hsw_pcm_runtime_idle(struct device *dev) +{ + return 0; +} + +static int hsw_pcm_runtime_suspend(struct device *dev) +{ + struct hsw_priv_data *pdata = dev_get_drvdata(dev); + struct sst_hsw *hsw = pdata->hsw; + + if (pdata->pm_state == HSW_PM_STATE_D3) + return 0; + + sst_hsw_dsp_runtime_suspend(hsw); + sst_hsw_dsp_runtime_sleep(hsw); + pdata->pm_state = HSW_PM_STATE_D3; + + return 0; +} + +static int hsw_pcm_runtime_resume(struct device *dev) +{ + struct hsw_priv_data *pdata = dev_get_drvdata(dev); + struct sst_hsw *hsw = pdata->hsw; + int ret; + + if (pdata->pm_state == HSW_PM_STATE_D0) + return 0; + + ret = sst_hsw_dsp_load(hsw); + if (ret < 0) { + dev_err(dev, "failed to reload %d\n", ret); + return ret; + } + + ret = hsw_pcm_create_modules(pdata); + if (ret < 0) { + dev_err(dev, "failed to create modules %d\n", ret); + return ret; + } + + ret = sst_hsw_dsp_runtime_resume(hsw); + if (ret < 0) + return ret; + else if (ret == 1) /* no action required */ + return 0; + + pdata->pm_state = HSW_PM_STATE_D0; + return ret; +} + +static void hsw_pcm_complete(struct device *dev) +{ + struct hsw_priv_data *pdata = dev_get_drvdata(dev); + struct sst_hsw *hsw = pdata->hsw; + struct hsw_pcm_data *pcm_data; + int i, err; + + if (pdata->pm_state == HSW_PM_STATE_D0) + return; + + err = sst_hsw_dsp_load(hsw); + if (err < 0) { + dev_err(dev, "failed to reload %d\n", err); + return; + } + + err = hsw_pcm_create_modules(pdata); + if (err < 0) { + dev_err(dev, "failed to create modules %d\n", err); + return; + } + + for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { + pcm_data = &pdata->pcm[i]; + + if (!pcm_data->substream) + continue; + + err = sst_module_runtime_restore(pcm_data->runtime, + &pcm_data->context); + if (err < 0) + dev_err(dev, "failed to restore context for PCM %d\n", i); + } + + snd_soc_resume(pdata->soc_card->dev); + + err = sst_hsw_dsp_runtime_resume(hsw); + if (err < 0) + return; + else if (err == 1) /* no action required */ + return; + + pdata->pm_state = HSW_PM_STATE_D0; + return; +} + +static int hsw_pcm_prepare(struct device *dev) +{ + struct hsw_priv_data *pdata = dev_get_drvdata(dev); + struct sst_hsw *hsw = pdata->hsw; + struct hsw_pcm_data *pcm_data; + int i, err; + + if (pdata->pm_state == HSW_PM_STATE_D3) + return 0; + /* suspend all active streams */ + for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { + pcm_data = &pdata->pcm[i]; + + if (!pcm_data->substream) + continue; + dev_dbg(dev, "suspending pcm %d\n", i); + snd_pcm_suspend_all(pcm_data->hsw_pcm); + + /* We need to wait until the DSP FW stops the streams */ + msleep(2); + } + + snd_soc_suspend(pdata->soc_card->dev); + snd_soc_poweroff(pdata->soc_card->dev); + + /* enter D3 state and stall */ + sst_hsw_dsp_runtime_suspend(hsw); + + /* preserve persistent memory */ + for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { + pcm_data = &pdata->pcm[i]; + + if (!pcm_data->substream) + continue; + + dev_dbg(dev, "saving context pcm %d\n", i); + err = sst_module_runtime_save(pcm_data->runtime, + &pcm_data->context); + if (err < 0) + dev_err(dev, "failed to save context for PCM %d\n", i); + } + + /* put the DSP to sleep */ + sst_hsw_dsp_runtime_sleep(hsw); + pdata->pm_state = HSW_PM_STATE_D3; + + return 0; +} + +#else +#define hsw_pcm_runtime_idle NULL +#define hsw_pcm_runtime_suspend NULL +#define hsw_pcm_runtime_resume NULL +#define hsw_pcm_runtime_complete NULL +#define hsw_pcm_runtime_prepare NULL +#endif + +static const struct dev_pm_ops hsw_pcm_pm = { + .runtime_idle = hsw_pcm_runtime_idle, + .runtime_suspend = hsw_pcm_runtime_suspend, + .runtime_resume = hsw_pcm_runtime_resume, + .prepare = hsw_pcm_prepare, + .complete = hsw_pcm_complete, +}; +#else +#define hsw_pcm_pm NULL +#endif + static struct platform_driver hsw_pcm_driver = { .driver = { .name = "haswell-pcm-audio", .owner = THIS_MODULE, + .pm = &hsw_pcm_pm, + }, .probe = hsw_pcm_dev_probe, -- GitLab From 55a2d0651762eb6f70d48ff94d21bc5718d5e47d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:28 +0100 Subject: [PATCH 2127/9457] mac802154: main: remove unnecessary include This patch removes an unnecessary include of driver-ops header file. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 21dcc56930d1..86e533ed3775 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -28,7 +28,6 @@ #include #include "ieee802154_i.h" -#include "driver-ops.h" static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) -- GitLab From 90a6161df57e7943cdd575ce95c1c62b468407e3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:29 +0100 Subject: [PATCH 2128/9457] mac802154: remove tab after define This patch removes tabs after define in hardware flags declarations. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 85a4efca418b..fe1495796ce7 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -74,22 +74,22 @@ struct ieee802154_hw { */ /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ -#define IEEE802154_HW_OMIT_CKSUM 0x00000001 +#define IEEE802154_HW_OMIT_CKSUM 0x00000001 /* Indicates that receiver will autorespond with ACK frames. */ -#define IEEE802154_HW_AACK 0x00000002 +#define IEEE802154_HW_AACK 0x00000002 /* Indicates that transceiver will support transmit power setting. */ -#define IEEE802154_HW_TXPOWER 0x00000004 +#define IEEE802154_HW_TXPOWER 0x00000004 /* Indicates that transceiver will support listen before transmit. */ -#define IEEE802154_HW_LBT 0x00000008 +#define IEEE802154_HW_LBT 0x00000008 /* Indicates that transceiver will support cca mode setting. */ -#define IEEE802154_HW_CCA_MODE 0x00000010 +#define IEEE802154_HW_CCA_MODE 0x00000010 /* Indicates that transceiver will support cca ed level setting. */ -#define IEEE802154_HW_CCA_ED_LEVEL 0x00000020 +#define IEEE802154_HW_CCA_ED_LEVEL 0x00000020 /* Indicates that transceiver will support csma (max_be, min_be, csma retries) * settings. */ -#define IEEE802154_HW_CSMA_PARAMS 0x00000040 +#define IEEE802154_HW_CSMA_PARAMS 0x00000040 /* Indicates that transceiver will support ARET frame retries setting. */ -#define IEEE802154_HW_FRAME_RETRIES 0x00000080 +#define IEEE802154_HW_FRAME_RETRIES 0x00000080 /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ -- GitLab From ab79be3eebf28be5315e43d0002ebcc05858af0b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:30 +0100 Subject: [PATCH 2129/9457] mac802154: add IEEE802154_HW_ARET hw flag This patch adds a new IEEE802154_HW_ARET hardware flag for indicating that the transceiver supports ARET handling. Also remove the IEEE802154_HW_FRAME_RETRIES from IEEE802154_HW_CSMA flag. Frame retries handling is part of ARET. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- include/net/mac802154.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b83ad0b38688..005458821c5d 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1387,7 +1387,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->extra_tx_headroom = 0; lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | - IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA; + IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET; switch (part) { case 2: diff --git a/include/net/mac802154.h b/include/net/mac802154.h index fe1495796ce7..c5d79384847a 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -94,7 +94,10 @@ struct ieee802154_hw { /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ IEEE802154_HW_CCA_ED_LEVEL | \ - IEEE802154_HW_CSMA_PARAMS | \ + IEEE802154_HW_CSMA_PARAMS) + +/* This groups the most common ARET support fields into one. */ +#define IEEE802154_HW_ARET (IEEE802154_HW_CSMA | \ IEEE802154_HW_FRAME_RETRIES) /* struct ieee802154_ops - callbacks from mac802154 to the driver -- GitLab From c8fc84ed60f0ec85ab71f6026add1523523e4bd5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:31 +0100 Subject: [PATCH 2130/9457] mac802154: add hardware address filter flag Overdue introduction for address filtering hardware flag. Furthermore we will check and set address filtering on interface up. This patch prepares that we can check if an transceiver supports address filtering option. Currently all mainline driver supports hardware address filtering. Signed-off-by: Alexander Aring Cc: Alan Ott Cc: Varka Bhadram Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 3 ++- drivers/net/ieee802154/cc2520.c | 3 ++- drivers/net/ieee802154/mrf24j40.c | 3 ++- include/net/mac802154.h | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 005458821c5d..622c1b6f7fec 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1387,7 +1387,8 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->extra_tx_headroom = 0; lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | - IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET; + IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET | + IEEE802154_HW_AFILT; switch (part) { case 2: diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index c56d10c7ccfa..340671b747b1 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -654,7 +654,8 @@ static int cc2520_register(struct cc2520_private *priv) /* We do support only 2.4 Ghz */ priv->hw->phy->channels_supported[0] = 0x7FFF800; - priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; + priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | + IEEE802154_HW_AFILT; dev_vdbg(&priv->spi->dev, "registered cc2520\n"); ret = ieee802154_register_hw(priv->hw); diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 52b3d3116755..a200fa16beae 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -751,7 +751,8 @@ static int mrf24j40_probe(struct spi_device *spi) devrec->hw->priv = devrec; devrec->hw->parent = &devrec->spi->dev; devrec->hw->phy->channels_supported[0] = CHANNEL_MASK; - devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; + devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | + IEEE802154_HW_AFILT; dev_dbg(printdev(devrec), "registered mrf24j40\n"); ret = ieee802154_register_hw(devrec->hw); diff --git a/include/net/mac802154.h b/include/net/mac802154.h index c5d79384847a..2f523fc1bf80 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -90,6 +90,8 @@ struct ieee802154_hw { #define IEEE802154_HW_CSMA_PARAMS 0x00000040 /* Indicates that transceiver will support ARET frame retries setting. */ #define IEEE802154_HW_FRAME_RETRIES 0x00000080 +/* Indicates that transceiver will support hardware address filter setting. */ +#define IEEE802154_HW_AFILT 0x00000100 /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ -- GitLab From 94b792220ca9c080f4d1da8060f4c892c1b3b025 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:32 +0100 Subject: [PATCH 2131/9457] mac802154: add support for promiscuous mode This patch adds a new driver operation to bring the transceiver into promiscuous mode. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 7 +++++++ net/mac802154/driver-ops.h | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 2f523fc1bf80..166ef6c52180 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -92,6 +92,8 @@ struct ieee802154_hw { #define IEEE802154_HW_FRAME_RETRIES 0x00000080 /* Indicates that transceiver will support hardware address filter setting. */ #define IEEE802154_HW_AFILT 0x00000100 +/* Indicates that transceiver will support promiscuous mode setting. */ +#define IEEE802154_HW_PROMISCUOUS 0x00000200 /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ @@ -173,6 +175,9 @@ struct ieee802154_hw { * set_frame_retries * Sets the retransmission attempt limit. Called with pib_lock held. * Returns either zero, or negative errno. + * + * set_promiscuous_mode + * Enables or disable promiscuous mode. */ struct ieee802154_ops { struct module *owner; @@ -197,6 +202,8 @@ struct ieee802154_ops { u8 min_be, u8 max_be, u8 retries); int (*set_frame_retries)(struct ieee802154_hw *hw, s8 retries); + int (*set_promiscuous_mode)(struct ieee802154_hw *hw, + const bool on); }; /* Basic interface to register ieee802154 hwice */ diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index 4b820cfeb538..dfd29ffb8fee 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -210,4 +210,17 @@ static inline int drv_set_max_frame_retries(struct ieee802154_local *local, return local->ops->set_frame_retries(&local->hw, max_frame_retries); } +static inline int drv_set_promiscuous_mode(struct ieee802154_local *local, + const bool on) +{ + might_sleep(); + + if (!local->ops->set_promiscuous_mode) { + WARN_ON(1); + return -EOPNOTSUPP; + } + + return local->ops->set_promiscuous_mode(&local->hw, on); +} + #endif /* __MAC802154_DRVIER_OPS */ -- GitLab From 92f45f5466ce75944071ae5d23732648048fa12a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:33 +0100 Subject: [PATCH 2132/9457] at86rf230: add support for promiscuous mode This patch adds support for promiscuous mode setting for the at86rf230 driver. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 622c1b6f7fec..98c94374aa35 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1211,6 +1211,33 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) return rc; } +static int +at86rf230_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) +{ + struct at86rf230_local *lp = hw->priv; + int rc; + + if (on) { + rc = at86rf230_write_subreg(lp, SR_AACK_DIS_ACK, 1); + if (rc < 0) + return rc; + + rc = at86rf230_write_subreg(lp, SR_AACK_PROM_MODE, 1); + if (rc < 0) + return rc; + } else { + rc = at86rf230_write_subreg(lp, SR_AACK_PROM_MODE, 0); + if (rc < 0) + return rc; + + rc = at86rf230_write_subreg(lp, SR_AACK_DIS_ACK, 0); + if (rc < 0) + return rc; + } + + return 0; +} + static const struct ieee802154_ops at86rf230_ops = { .owner = THIS_MODULE, .xmit_async = at86rf230_xmit, @@ -1225,6 +1252,7 @@ static const struct ieee802154_ops at86rf230_ops = { .set_cca_ed_level = at86rf230_set_cca_ed_level, .set_csma_params = at86rf230_set_csma_params, .set_frame_retries = at86rf230_set_frame_retries, + .set_promiscuous_mode = at86rf230_set_promiscuous_mode, }; static struct at86rf2xx_chip_data at86rf233_data = { @@ -1388,7 +1416,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->extra_tx_headroom = 0; lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET | - IEEE802154_HW_AFILT; + IEEE802154_HW_AFILT | IEEE802154_HW_PROMISCUOUS; switch (part) { case 2: -- GitLab From 90386a7e3bcce60b6b83d0d1bd65d7b55a77fa60 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:34 +0100 Subject: [PATCH 2133/9457] mac802154: separate omit tx/rx flags This patch splits the IEEE802154_HW_OMIT_CKSUM hardware flag into IEEE802154_HW_TX_OMIT_CKSUM and IEEE802154_HW_RX_OMIT_CKSUM. This is useful to deliver the received crc from the driver layer to the monitor interface. At the moment we can't do that without change the xmit handling. The received checksum should be visible in monitor mode only. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 10 ++++++++-- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 166ef6c52180..bc1d40c826e3 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -73,8 +73,8 @@ struct ieee802154_hw { * however, so you are advised to review these flags carefully. */ -/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ -#define IEEE802154_HW_OMIT_CKSUM 0x00000001 +/* Indicates that xmitter will add FCS on it's own. */ +#define IEEE802154_HW_TX_OMIT_CKSUM 0x00000001 /* Indicates that receiver will autorespond with ACK frames. */ #define IEEE802154_HW_AACK 0x00000002 /* Indicates that transceiver will support transmit power setting. */ @@ -94,6 +94,12 @@ struct ieee802154_hw { #define IEEE802154_HW_AFILT 0x00000100 /* Indicates that transceiver will support promiscuous mode setting. */ #define IEEE802154_HW_PROMISCUOUS 0x00000200 +/* Indicates that receiver omits FCS. */ +#define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 + +/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ +#define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ + IEEE802154_HW_RX_OMIT_CKSUM) /* This groups the most common CSMA support fields into one. */ #define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \ diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 86394befbf88..2aa80bdcbacf 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -255,7 +255,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) { u16 crc; if (skb->len < 2) { diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 77973a84e9a2..cc37b77f2632 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -83,7 +83,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb) struct net_device *dev = skb->dev; int ret; - if (!(local->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { + if (!(local->hw.flags & IEEE802154_HW_TX_OMIT_CKSUM)) { u16 crc = crc_ccitt(0, skb->data, skb->len); put_unaligned_le16(crc, skb_put(skb, 2)); -- GitLab From 08c511a7331cf6edb28895d7f46c3039180b30cb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:35 +0100 Subject: [PATCH 2134/9457] mac802154: rx: remove unnecessary parameter This patch removes a not used parameter in ieee802154_deliver_skb. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 2aa80bdcbacf..51a55d9200cb 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -29,7 +29,7 @@ #include "ieee802154_i.h" -static int ieee802154_deliver_skb(struct net_device *dev, struct sk_buff *skb) +static int ieee802154_deliver_skb(struct sk_buff *skb) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = htons(ETH_P_IEEE802154); @@ -103,7 +103,7 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, switch (mac_cb(skb)->type) { case IEEE802154_FC_TYPE_DATA: - return ieee802154_deliver_skb(sdata->dev, skb); + return ieee802154_deliver_skb(skb); default: pr_warn("ieee802154: bad frame received (type = %d)\n", mac_cb(skb)->type); -- GitLab From b7889497d306df0be52300b3060ebc12b4194f9a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:36 +0100 Subject: [PATCH 2135/9457] mac802154: rx: simplify crc receive handling This patch change the actual crc handling while receive. Currently the IEEE802154_HW_RX_OMIT_CKSUM flag is used to filter a frame with a bad crc. This patch changes the behaviour of IEEE802154_HW_RX_OMIT_CKSUM to add a crc while receiving for the monitor interface. After monitor receiving we remove the crc for frame parsing. This affect the driver layer because all drivers sets IEEE802154_HW_RX_OMIT_CKSUM and deliver without checksum. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 51a55d9200cb..b6a4bbfdbf90 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -225,8 +226,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) { struct sk_buff *skb2; struct ieee802154_sub_if_data *sdata; - u16 crc = crc_ccitt(0, skb->data, skb->len); - u8 *data; skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -241,9 +240,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; skb2->pkt_type = PACKET_HOST; - data = skb_put(skb2, 2); - data[0] = crc & 0xff; - data[1] = crc >> 8; netif_rx_ni(skb2); } @@ -255,32 +251,26 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) { - u16 crc; + /* TODO: When a transceiver omits the checksum here, we + * add an own calculated one. This is currently an ugly + * solution because the monitor needs a crc here. + */ + if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { + u16 crc = crc_ccitt(0, skb->data, skb->len); - if (skb->len < 2) { - pr_debug("got invalid frame\n"); - goto fail; - } - crc = crc_ccitt(0, skb->data, skb->len); - if (crc) { - pr_debug("CRC mismatch\n"); - goto fail; - } - skb_trim(skb, skb->len - 2); /* CRC */ + put_unaligned_le16(crc, skb_put(skb, 2)); } rcu_read_lock(); ieee802154_monitors_rx(local, skb); - __ieee802154_rx_handle_packet(local, skb); - rcu_read_unlock(); + /* remove crc */ + skb_trim(skb, skb->len - 2); - return; + __ieee802154_rx_handle_packet(local, skb); -fail: - kfree_skb(skb); + rcu_read_unlock(); } EXPORT_SYMBOL(ieee802154_rx); -- GitLab From ec718f3db9b7968ca5dfb10c85c56ff27149df94 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:37 +0100 Subject: [PATCH 2136/9457] mac802154: rx: add software checksum filtering check This patch adds a new hardware flag which indicate that the transceiver doesn't support check for bad checksum via hardware. Also add a handling of this while receive. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 2 ++ net/mac802154/rx.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index bc1d40c826e3..8f1de6844cb0 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -96,6 +96,8 @@ struct ieee802154_hw { #define IEEE802154_HW_PROMISCUOUS 0x00000200 /* Indicates that receiver omits FCS. */ #define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 +/* Indicates that receiver will not filter frames with bad checksum. */ +#define IEEE802154_HW_RX_DROP_BAD_CKSUM 0x00000800 /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index b6a4bbfdbf90..c9f1c72a1afc 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -248,6 +248,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) { struct ieee802154_local *local = hw_to_local(hw); + u16 crc; WARN_ON_ONCE(softirq_count() == 0); @@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) * solution because the monitor needs a crc here. */ if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { - u16 crc = crc_ccitt(0, skb->data, skb->len); - + crc = crc_ccitt(0, skb->data, skb->len); put_unaligned_le16(crc, skb_put(skb, 2)); } @@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) ieee802154_monitors_rx(local, skb); + /* Check if transceiver doesn't validate the checksum. + * If not we validate the checksum here. + */ + if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) { + crc = crc_ccitt(0, skb->data, skb->len); + if (crc) { + rcu_read_unlock(); + kfree_skb(skb); + return; + } + } /* remove crc */ skb_trim(skb, skb->len - 2); -- GitLab From 1054ed81c4f5225d7a45fe5dec67430280bf3793 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:38 +0100 Subject: [PATCH 2137/9457] mac802154: rx: remove override pkt_type set to PACKET_HOST This patch removes pkt_type set to PACKET_HOST while monitor receiving. This should be PACKET_OTHERHOST on monitor mode which already set before. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index c9f1c72a1afc..f15c50b97c3c 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -239,7 +239,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; - skb2->pkt_type = PACKET_HOST; netif_rx_ni(skb2); } -- GitLab From 21fdf0a1c10719f6edbb5961f5b076f5575d4bce Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:39 +0100 Subject: [PATCH 2138/9457] mac802154: rx: use netif_receive_skb This patch removes netif_rx_ni call. Instead we call netif_receive_skb, we can do that since commit c5c47e67bcd24638a059b1b5e9ec18c95f8634ca ("mac802154: rx: use tasklet instead workqueue"). Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index f15c50b97c3c..7669cdbba526 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -240,7 +240,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); skb2->dev = sdata->dev; - netif_rx_ni(skb2); + ieee802154_deliver_skb(skb2); } } -- GitLab From 18460672e0651705ca557c94a369003553c3f9d6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:40 +0100 Subject: [PATCH 2139/9457] mac802154: rx: add rx stats incrementation This patch adds rx stats incrementation when the monitor interface recevied a frame. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 7669cdbba526..6ba2769f5fb4 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -241,6 +241,9 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb2->dev = sdata->dev; ieee802154_deliver_skb(skb2); + + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; } } -- GitLab From 20b48120c14fb4bf6ebe4ed4cfa1b828e5e1dff8 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:41 +0100 Subject: [PATCH 2140/9457] mac802154: rx: monitor receive cleanup This patch replace the !netif_running(sdata->dev) instead we doing a !ieee802154_sdata_running(sdata). Also move this in two separate if branches to compare with mac80211 code. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 6ba2769f5fb4..971a8553e9b6 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -233,8 +233,10 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb->protocol = htons(ETH_P_IEEE802154); list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->type != IEEE802154_DEV_MONITOR || - !netif_running(sdata->dev)) + if (sdata->type != IEEE802154_DEV_MONITOR) + continue; + + if (!ieee802154_sdata_running(sdata)) continue; skb2 = skb_clone(skb, GFP_ATOMIC); -- GitLab From 05f7de67921d8b382b14597c3955c5881d804d99 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:42 +0100 Subject: [PATCH 2141/9457] mac802154: rx: add error handling after skb_clone This patch adds error handling after skb_clone and deliver only if skb_clone was successful. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 971a8553e9b6..95961cccc253 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -240,12 +240,13 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) continue; skb2 = skb_clone(skb, GFP_ATOMIC); - skb2->dev = sdata->dev; + if (skb2) { + skb2->dev = sdata->dev; + ieee802154_deliver_skb(skb2); - ieee802154_deliver_skb(skb2); - - sdata->dev->stats.rx_packets++; - sdata->dev->stats.rx_bytes += skb->len; + sdata->dev->stats.rx_packets++; + sdata->dev->stats.rx_bytes += skb->len; + } } } -- GitLab From 2ac0f3a38ac4357c603052ba9769bdeaa4131ff1 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:43 +0100 Subject: [PATCH 2142/9457] at86rf230: deliver with checksum This patch indicates that the at86rf230 driver deliver with checksum instead drop the crc before delivering. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 98c94374aa35..9ad2d432ef43 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -819,7 +819,7 @@ at86rf230_rx_read_frame_complete(void *context) len = IEEE802154_MTU; } - at86rf230_rx(lp, buf + 2, len - 2, buf[2 + len]); + at86rf230_rx(lp, buf + 2, len, buf[2 + len]); } static void @@ -1414,7 +1414,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) } lp->hw->extra_tx_headroom = 0; - lp->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | + lp->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AACK | IEEE802154_HW_TXPOWER | IEEE802154_HW_ARET | IEEE802154_HW_AFILT | IEEE802154_HW_PROMISCUOUS; -- GitLab From 38130c31ef50de1999983601e448db2b1bc1057c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 29 Oct 2014 21:34:44 +0100 Subject: [PATCH 2143/9457] mac802154: add basic support for monitor This patch adds basic support for monitor mode. Also change the open call that we set the transceiver mac setting on an interface up. Futher patches will add a better handling while interface up an interface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 + net/mac802154/iface.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 7cebc9844c00..1086a9d96f8f 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -84,6 +84,7 @@ struct ieee802154_sub_if_data { __le16 pan_id; __le16 short_addr; __le64 extended_addr; + bool promisuous_mode; struct ieee802154_mac_params mac_params; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0bf5f9b9953..f7a6f83301e2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -196,6 +196,12 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); + if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { + rc = drv_set_promiscuous_mode(local, sdata->promisuous_mode); + if (rc < 0) + goto out; + } + if (local->hw.flags & IEEE802154_HW_TXPOWER) { rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) @@ -382,7 +388,7 @@ static const struct net_device_ops mac802154_wpan_ops = { }; static const struct net_device_ops mac802154_monitor_ops = { - .ndo_open = mac802154_slave_open, + .ndo_open = mac802154_wpan_open, .ndo_stop = mac802154_slave_close, .ndo_start_xmit = ieee802154_monitor_start_xmit, }; @@ -434,6 +440,8 @@ void mac802154_wpan_setup(struct net_device *dev) sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + sdata->promisuous_mode = false; + mac802154_llsec_init(&sdata->sec); } @@ -453,4 +461,6 @@ void mac802154_monitor_setup(struct net_device *dev) sdata = IEEE802154_DEV_TO_SUB_IF(dev); sdata->type = IEEE802154_DEV_MONITOR; + + sdata->promisuous_mode = true; } -- GitLab From 92be2d4d3ca4a086d295ddd5339587e675d46c0c Mon Sep 17 00:00:00 2001 From: Brian Vandre Date: Wed, 29 Oct 2014 07:02:23 -0500 Subject: [PATCH 2144/9457] Staging: xgifb: fix space before comma This fixes the checkpatch.pl error: ERROR: space prohibited before that ',' Signed-off-by: Brian Vandre Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index be7778b59118..709d49e7f3c9 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2012,7 +2012,7 @@ static int xgifb_probe(struct pci_dev *pdev, XGIfb_get_fix(&fb_info->fix, -1, fb_info); fb_info->pseudo_palette = xgifb_info->pseudo_palette; - fb_alloc_cmap(&fb_info->cmap, 256 , 0); + fb_alloc_cmap(&fb_info->cmap, 256, 0); #ifdef CONFIG_MTRR xgifb_info->mtrr = mtrr_add(xgifb_info->video_base, -- GitLab From c65a5a562e3b55297767a4022543867e01a66080 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Wed, 29 Oct 2014 19:30:41 +0530 Subject: [PATCH 2145/9457] Staging: rtl8192e: Revert one previous commit This patch reverts commit 450246465a76 ("Staging: rtl8192e: Fix incorrect type in assignment in rtl819x_BAProc.c") as it is changing code and introducing bug to skip the endian conversion. Here, tmp variable is used to hold the endian-corrected values and network-data requires fixed endianness. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 6da57847a533..946c1dc25de5 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -115,14 +115,14 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, if (ACT_ADDBARSP == type) { RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); - tmp = StatusCode; + tmp = cpu_to_le16(StatusCode); memcpy(tag, (u8 *)&tmp, 2); tag += 2; } - tmp = pBA->BaParamSet.shortData; + tmp = cpu_to_le16(pBA->BaParamSet.shortData); memcpy(tag, (u8 *)&tmp, 2); tag += 2; - tmp = pBA->BaTimeoutValue; + tmp = cpu_to_le16(pBA->BaTimeoutValue); memcpy(tag, (u8 *)&tmp, 2); tag += 2; @@ -178,10 +178,10 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, *tag++ = ACT_CAT_BA; *tag++ = ACT_DELBA; - tmp = DelbaParamSet.shortData; + tmp = cpu_to_le16(DelbaParamSet.shortData); memcpy(tag, (u8 *)&tmp, 2); tag += 2; - tmp = ReasonCode; + tmp = cpu_to_le16(ReasonCode); memcpy(tag, (u8 *)&tmp, 2); tag += 2; -- GitLab From b32af401fc9d79b920eb6cf2a5747c8baa6fde5f Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Wed, 29 Oct 2014 19:30:51 +0530 Subject: [PATCH 2146/9457] Staging: rtl8192e: Change variable type from u16 to __le16 This patch changes declaration of variable tmp from u16 to __le16 in order to remove following sparse warning at number of places: warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] tmp got restricted __le16 [usertype] Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 946c1dc25de5..2866c1237ae5 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -79,7 +79,7 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *BAReq = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; u16 len = ieee->tx_headroom + 9; RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)" @@ -143,7 +143,7 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *Delba = NULL; u8 *tag = NULL; - u16 tmp = 0; + __le16 tmp = 0; u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) -- GitLab From a58af1e1ce10b1a92221823aa8ab0de881d9a129 Mon Sep 17 00:00:00 2001 From: anuvazhayil Date: Thu, 30 Oct 2014 00:03:48 +0530 Subject: [PATCH 2147/9457] Staging: rtl8723au: rtw_cmd: Replace foo*bar to foo *bar Fixed the checkpatch.pl ERROR: "foo*bar" should be "foo *bar" Signed-off-by: anuvazhayil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_cmd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c index f80e81cd14e6..44eae8e6bd9d 100644 --- a/drivers/staging/rtl8723au/core/rtw_cmd.c +++ b/drivers/staging/rtl8723au/core/rtw_cmd.c @@ -601,7 +601,7 @@ int rtw_joinbss_cmd23a(struct rtw_adapter *padapter, return res; } -int rtw_disassoc_cmd23a(struct rtw_adapter*padapter, u32 deauth_timeout_ms, +int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms, bool enqueue) { struct cmd_obj *cmdobj = NULL; @@ -789,7 +789,7 @@ int rtw_clearstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 entry, return res; } -int rtw_addbareq_cmd23a(struct rtw_adapter*padapter, u8 tid, u8 *addr) +int rtw_addbareq_cmd23a(struct rtw_adapter *padapter, u8 tid, u8 *addr) { struct cmd_priv *pcmdpriv = &padapter->cmdpriv; struct cmd_obj *ph2c; @@ -825,7 +825,7 @@ int rtw_addbareq_cmd23a(struct rtw_adapter*padapter, u8 tid, u8 *addr) return res; } -int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter*padapter) +int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ph2c; struct drvextra_cmd_parm *pdrvextra_cmd_parm; @@ -862,7 +862,7 @@ int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter*padapter) * This is only ever called from on_action_spct23a_ch_switch () which isn't * called from anywhere itself */ -int rtw_set_ch_cmd23a(struct rtw_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, +int rtw_set_ch_cmd23a(struct rtw_adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) { struct cmd_obj *pcmdobj; @@ -1100,7 +1100,7 @@ int rtw_lps_ctrl_wk_cmd23a(struct rtw_adapter *padapter, return res; } -int rtw_ps_cmd23a(struct rtw_adapter*padapter) +int rtw_ps_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ppscmd; struct drvextra_cmd_parm *pdrvextra_cmd_parm; @@ -1170,7 +1170,7 @@ static void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter) } } -int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter) +int rtw_chk_hi_queue_cmd23a(struct rtw_adapter *padapter) { struct cmd_obj *ph2c; struct drvextra_cmd_parm *pdrvextra_cmd_parm; -- GitLab From 0d20dac3775ea61443dd52a8cf9c55e60b48e3a3 Mon Sep 17 00:00:00 2001 From: Gulsah Kose Date: Wed, 29 Oct 2014 21:29:56 +0200 Subject: [PATCH 2148/9457] staging: rtl8188eu: core: Removed unnecessary parenthesis. This patch removes unnecessarry parenthesis in rtw_security.c by using this coccinelle script: @r1@ expression e1,e2; @@ if - ((e1 == e2)) + (e1 == e2) {...} Signed-off-by: Gulsah Kose Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index f9096a512da5..1baa98e636e1 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -1219,7 +1219,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset; /* 4 start to encrypt each fragment */ - if ((pattrib->encrypt == _AES_)) { + if (pattrib->encrypt == _AES_) { if (pattrib->psta) stainfo = pattrib->psta; else @@ -1460,7 +1460,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) u32 res = _SUCCESS; pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data; /* 4 start to encrypt each fragment */ - if ((prxattrib->encrypt == _AES_)) { + if (prxattrib->encrypt == _AES_) { stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); if (stainfo != NULL) { RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n")); -- GitLab From 2d37545751f27e38aa6beb71564adc35cc2d79ea Mon Sep 17 00:00:00 2001 From: Mikael Svantesson Date: Wed, 29 Oct 2014 17:55:34 +0100 Subject: [PATCH 2149/9457] staging: skein: skein_api.c: removed space before ',' Signed-off-by: Mikael Svantesson Acked-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/skein/skein_api.c b/drivers/staging/skein/skein_api.c index 6e700eefc00c..5bfce076f7c8 100644 --- a/drivers/staging/skein/skein_api.c +++ b/drivers/staging/skein/skein_api.c @@ -31,7 +31,7 @@ int skein_ctx_prepare(struct skein_ctx *ctx, enum skein_size size) { skein_assert_ret(ctx && size, SKEIN_FAIL); - memset(ctx , 0, sizeof(struct skein_ctx)); + memset(ctx, 0, sizeof(struct skein_ctx)); ctx->skein_size = size; return SKEIN_SUCCESS; -- GitLab From 8d94b6d22403cf4aebfbd246bb781501366db005 Mon Sep 17 00:00:00 2001 From: Anton Saraev Date: Wed, 29 Oct 2014 23:41:49 +0400 Subject: [PATCH 2150/9457] staging:lustre:lnet:selftest: fix sparse warnings Fix sparse warnings: symbol X was not declared. Should it be static? Some functions used only in files where they are declared. They can be static. Signed-off-by: Anton Saraev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/conctl.c | 34 ++++++------- drivers/staging/lustre/lnet/selftest/conrpc.c | 20 ++++---- .../staging/lustre/lnet/selftest/framework.c | 50 +++++++++---------- drivers/staging/lustre/lnet/selftest/module.c | 4 +- drivers/staging/lustre/lnet/selftest/rpc.c | 34 ++++++------- drivers/staging/lustre/lnet/selftest/timer.c | 8 +-- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index ae7b0fcd818d..5bc615309e72 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -45,7 +45,7 @@ #include "../../include/linux/lnet/lnetst.h" #include "console.h" -int +static int lst_session_new_ioctl(lstio_session_new_args_t *args) { char *name; @@ -82,7 +82,7 @@ lst_session_new_ioctl(lstio_session_new_args_t *args) return rc; } -int +static int lst_session_end_ioctl(lstio_session_end_args_t *args) { if (args->lstio_ses_key != console_session.ses_key) @@ -91,7 +91,7 @@ lst_session_end_ioctl(lstio_session_end_args_t *args) return lstcon_session_end(); } -int +static int lst_session_info_ioctl(lstio_session_info_args_t *args) { /* no checking of key */ @@ -113,7 +113,7 @@ lst_session_info_ioctl(lstio_session_info_args_t *args) args->lstio_ses_nmlen); } -int +static int lst_debug_ioctl(lstio_debug_args_t *args) { char *name = NULL; @@ -194,7 +194,7 @@ lst_debug_ioctl(lstio_debug_args_t *args) return rc; } -int +static int lst_group_add_ioctl(lstio_group_add_args_t *args) { char *name; @@ -228,7 +228,7 @@ lst_group_add_ioctl(lstio_group_add_args_t *args) return rc; } -int +static int lst_group_del_ioctl(lstio_group_del_args_t *args) { int rc; @@ -262,7 +262,7 @@ lst_group_del_ioctl(lstio_group_del_args_t *args) return rc; } -int +static int lst_group_update_ioctl(lstio_group_update_args_t *args) { int rc; @@ -320,7 +320,7 @@ lst_group_update_ioctl(lstio_group_update_args_t *args) return rc; } -int +static int lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) { unsigned feats; @@ -365,7 +365,7 @@ lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) return rc; } -int +static int lst_group_list_ioctl(lstio_group_list_args_t *args) { if (args->lstio_grp_key != console_session.ses_key) @@ -382,7 +382,7 @@ lst_group_list_ioctl(lstio_group_list_args_t *args) args->lstio_grp_namep); } -int +static int lst_group_info_ioctl(lstio_group_info_args_t *args) { char *name; @@ -446,7 +446,7 @@ lst_group_info_ioctl(lstio_group_info_args_t *args) return 0; } -int +static int lst_batch_add_ioctl(lstio_batch_add_args_t *args) { int rc; @@ -480,7 +480,7 @@ lst_batch_add_ioctl(lstio_batch_add_args_t *args) return rc; } -int +static int lst_batch_run_ioctl(lstio_batch_run_args_t *args) { int rc; @@ -515,7 +515,7 @@ lst_batch_run_ioctl(lstio_batch_run_args_t *args) return rc; } -int +static int lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) { int rc; @@ -551,7 +551,7 @@ lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) return rc; } -int +static int lst_batch_query_ioctl(lstio_batch_query_args_t *args) { char *name; @@ -593,7 +593,7 @@ lst_batch_query_ioctl(lstio_batch_query_args_t *args) return rc; } -int +static int lst_batch_list_ioctl(lstio_batch_list_args_t *args) { if (args->lstio_bat_key != console_session.ses_key) @@ -610,7 +610,7 @@ lst_batch_list_ioctl(lstio_batch_list_args_t *args) args->lstio_bat_namep); } -int +static int lst_batch_info_ioctl(lstio_batch_info_args_t *args) { char *name; @@ -675,7 +675,7 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args) return rc; } -int +static int lst_stat_query_ioctl(lstio_stat_args_t *args) { int rc; diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index a3a60d6e9081..9999b0dc03e4 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -88,7 +88,7 @@ lstcon_rpc_done(srpc_client_rpc_t *rpc) spin_unlock(&rpc->crpc_lock); } -int +static int lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats, int bulk_npg, int bulk_len, int embedded, lstcon_rpc_t *crpc) { @@ -113,7 +113,7 @@ lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats, return 0; } -int +static int lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats, int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp) { @@ -182,7 +182,7 @@ lstcon_rpc_put(lstcon_rpc_t *crpc) atomic_dec(&console_session.ses_rpc_counter); } -void +static void lstcon_rpc_post(lstcon_rpc_t *crpc) { lstcon_rpc_trans_t *trans = crpc->crp_trans; @@ -383,7 +383,7 @@ lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout) return rc; } -int +static int lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp) { lstcon_node_t *nd = crpc->crp_node; @@ -718,7 +718,7 @@ lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov) return &pid[idx % SFW_ID_PER_PAGE]; } -int +static int lstcon_dstnodes_prep(lstcon_group_t *grp, int idx, int dist, int span, int nkiov, lnet_kiov_t *kiov) { @@ -772,7 +772,7 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx, return 0; } -int +static int lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req) { test_ping_req_t *prq = &req->tsr_u.ping; @@ -783,7 +783,7 @@ lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req) return 0; } -int +static int lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) { test_bulk_req_t *brq = &req->tsr_u.bulk_v0; @@ -795,7 +795,7 @@ lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) return 0; } -int +static int lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req) { test_bulk_req_v1_t *brq = &req->tsr_u.bulk_v1; @@ -915,7 +915,7 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats, return rc; } -int +static int lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans, lstcon_node_t *nd, srpc_msg_t *reply) { @@ -1162,7 +1162,7 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist, return rc; } -void +static void lstcon_rpc_pinger(void *arg) { stt_timer_t *ptimer = (stt_timer_t *)arg; diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index df04ab7de835..82cc94b9cef2 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -156,7 +156,7 @@ sfw_register_test (srpc_service_t *service, sfw_test_client_ops_t *cliops) return 0; } -void +static void sfw_add_session_timer (void) { sfw_session_t *sn = sfw_data.fw_session; @@ -176,7 +176,7 @@ sfw_add_session_timer (void) return; } -int +static int sfw_del_session_timer (void) { sfw_session_t *sn = sfw_data.fw_session; @@ -238,7 +238,7 @@ sfw_deactivate_session (void) } -void +static void sfw_session_expired (void *data) { sfw_session_t *sn = data; @@ -284,7 +284,7 @@ sfw_init_session(sfw_session_t *sn, lst_sid_t sid, } /* completion handler for incoming framework RPCs */ -void +static void sfw_server_rpc_done(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; @@ -302,7 +302,7 @@ sfw_server_rpc_done(struct srpc_server_rpc *rpc) return; } -void +static void sfw_client_rpc_fini (srpc_client_rpc_t *rpc) { LASSERT (rpc->crpc_bulk.bk_niov == 0); @@ -325,7 +325,7 @@ sfw_client_rpc_fini (srpc_client_rpc_t *rpc) spin_unlock(&sfw_data.fw_lock); } -sfw_batch_t * +static sfw_batch_t * sfw_find_batch (lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; @@ -341,7 +341,7 @@ sfw_find_batch (lst_bid_t bid) return NULL; } -sfw_batch_t * +static sfw_batch_t * sfw_bid2batch (lst_bid_t bid) { sfw_session_t *sn = sfw_data.fw_session; @@ -367,7 +367,7 @@ sfw_bid2batch (lst_bid_t bid) return bat; } -int +static int sfw_get_stats (srpc_stat_reqst_t *request, srpc_stat_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -479,7 +479,7 @@ sfw_make_session(srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply) return 0; } -int +static int sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -511,7 +511,7 @@ sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply) return 0; } -int +static int sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -532,7 +532,7 @@ sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply) return 0; } -void +static void sfw_test_rpc_fini (srpc_client_rpc_t *rpc) { sfw_test_unit_t *tsu = rpc->crpc_priv; @@ -554,7 +554,7 @@ sfw_test_buffers(sfw_test_instance_t *tsi) return max(SFW_TEST_WI_MIN, nbuf + SFW_TEST_WI_EXTRA); } -int +static int sfw_load_test(struct sfw_test_instance *tsi) { struct sfw_test_case *tsc; @@ -591,7 +591,7 @@ sfw_load_test(struct sfw_test_instance *tsi) return 0; } -void +static void sfw_unload_test(struct sfw_test_instance *tsi) { struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service); @@ -609,7 +609,7 @@ sfw_unload_test(struct sfw_test_instance *tsi) return; } -void +static void sfw_destroy_test_instance (sfw_test_instance_t *tsi) { srpc_client_rpc_t *rpc; @@ -643,7 +643,7 @@ sfw_destroy_test_instance (sfw_test_instance_t *tsi) return; } -void +static void sfw_destroy_batch (sfw_batch_t *tsb) { sfw_test_instance_t *tsi; @@ -682,7 +682,7 @@ sfw_destroy_session (sfw_session_t *sn) return; } -void +static void sfw_unpack_addtest_req(srpc_msg_t *msg) { srpc_test_reqst_t *req = &msg->msg_body.tes_reqst; @@ -727,7 +727,7 @@ sfw_unpack_addtest_req(srpc_msg_t *msg) return; } -int +static int sfw_add_test_instance (sfw_batch_t *tsb, srpc_server_rpc_t *rpc) { srpc_msg_t *msg = &rpc->srpc_reqstbuf->buf_msg; @@ -865,7 +865,7 @@ sfw_test_unit_done (sfw_test_unit_t *tsu) return; } -void +static void sfw_test_rpc_done (srpc_client_rpc_t *rpc) { sfw_test_unit_t *tsu = rpc->crpc_priv; @@ -944,7 +944,7 @@ sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer, return 0; } -int +static int sfw_run_test (swi_workitem_t *wi) { sfw_test_unit_t *tsu = wi->swi_workitem.wi_data; @@ -994,7 +994,7 @@ sfw_run_test (swi_workitem_t *wi) return 1; } -int +static int sfw_run_batch (sfw_batch_t *tsb) { swi_workitem_t *wi; @@ -1072,7 +1072,7 @@ sfw_stop_batch (sfw_batch_t *tsb, int force) return 0; } -int +static int sfw_query_batch (sfw_batch_t *tsb, int testidx, srpc_batch_reply_t *reply) { sfw_test_instance_t *tsi; @@ -1117,7 +1117,7 @@ sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len, return 0; } -int +static int sfw_add_test (srpc_server_rpc_t *rpc) { sfw_session_t *sn = sfw_data.fw_session; @@ -1187,7 +1187,7 @@ sfw_add_test (srpc_server_rpc_t *rpc) return 0; } -int +static int sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) { sfw_session_t *sn = sfw_data.fw_session; @@ -1228,7 +1228,7 @@ sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply) return 0; } -int +static int sfw_handle_server_rpc(struct srpc_server_rpc *rpc) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; @@ -1334,7 +1334,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) return rc; } -int +static int sfw_bulk_ready(struct srpc_server_rpc *rpc, int status) { struct srpc_service *sv = rpc->srpc_scd->scd_svc; diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 6dd4309dc5ea..b2dd891f3734 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -55,7 +55,7 @@ static int lst_init_step = LST_INIT_NONE; struct cfs_wi_sched *lst_sched_serial; struct cfs_wi_sched **lst_sched_test; -void +static void lnet_selftest_fini(void) { int i; @@ -101,7 +101,7 @@ lnet_selftest_structure_assertion(void) CLASSERT(sizeof(srpc_stat_reqst_t) == 28); } -int +static int lnet_selftest_init(void) { int nscheds; diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index a9f29d8833a9..c9a1a45923ed 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -87,7 +87,7 @@ void srpc_set_counters (const srpc_counters_t *cnt) spin_unlock(&srpc_data.rpc_glock); } -int +static int srpc_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i, int nob) { nob = min(nob, (int)PAGE_CACHE_SIZE); @@ -170,7 +170,7 @@ srpc_next_id (void) return id; } -void +static void srpc_init_server_rpc(struct srpc_server_rpc *rpc, struct srpc_service_cd *scd, struct srpc_buffer *buffer) @@ -351,7 +351,7 @@ srpc_remove_service (srpc_service_t *sv) return 0; } -int +static int srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_handle_md_t *mdh, srpc_event_t *ev) @@ -391,7 +391,7 @@ srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf, return 0; } -int +static int srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, int options, lnet_process_id_t peer, lnet_nid_t self, lnet_handle_md_t *mdh, srpc_event_t *ev) @@ -443,7 +443,7 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len, return 0; } -int +static int srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf, int len, lnet_handle_md_t *mdh, srpc_event_t *ev) { @@ -452,7 +452,7 @@ srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf, LNET_NID_ANY, mdh, ev); } -int +static int srpc_post_passive_rqtbuf(int service, int local, void *buf, int len, lnet_handle_md_t *mdh, srpc_event_t *ev) { @@ -466,7 +466,7 @@ srpc_post_passive_rqtbuf(int service, int local, void *buf, int len, LNET_MD_OP_PUT, any, mdh, ev); } -int +static int srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf) { struct srpc_service *sv = scd->scd_svc; @@ -697,7 +697,7 @@ srpc_finish_service(struct srpc_service *sv) } /* called with sv->sv_lock held */ -void +static void srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf) { if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) { @@ -787,7 +787,7 @@ srpc_shutdown_service(srpc_service_t *sv) } } -int +static int srpc_send_request (srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_reqstev; @@ -807,7 +807,7 @@ srpc_send_request (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_prepare_reply (srpc_client_rpc_t *rpc) { srpc_event_t *ev = &rpc->crpc_replyev; @@ -831,7 +831,7 @@ srpc_prepare_reply (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_prepare_bulk (srpc_client_rpc_t *rpc) { srpc_bulk_t *bk = &rpc->crpc_bulk; @@ -863,7 +863,7 @@ srpc_prepare_bulk (srpc_client_rpc_t *rpc) return rc; } -int +static int srpc_do_bulk (srpc_server_rpc_t *rpc) { srpc_event_t *ev = &rpc->srpc_ev; @@ -891,7 +891,7 @@ srpc_do_bulk (srpc_server_rpc_t *rpc) } /* only called from srpc_handle_rpc */ -void +static void srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status) { struct srpc_service_cd *scd = rpc->srpc_scd; @@ -1066,7 +1066,7 @@ srpc_handle_rpc(swi_workitem_t *wi) return 0; } -void +static void srpc_client_rpc_expired (void *data) { srpc_client_rpc_t *rpc = data; @@ -1108,7 +1108,7 @@ srpc_add_client_rpc_timer (srpc_client_rpc_t *rpc) * * Upon exit the RPC expiry timer is not queued and the handler is not * running on any CPU. */ -void +static void srpc_del_client_rpc_timer (srpc_client_rpc_t *rpc) { /* timer not planted or already exploded */ @@ -1129,7 +1129,7 @@ srpc_del_client_rpc_timer (srpc_client_rpc_t *rpc) } } -void +static void srpc_client_rpc_done (srpc_client_rpc_t *rpc, int status) { swi_workitem_t *wi = &rpc->crpc_wi; @@ -1393,7 +1393,7 @@ srpc_send_reply(struct srpc_server_rpc *rpc) } /* when in kernel always called with LNET_LOCK() held, and in thread context */ -void +static void srpc_lnet_ev_handler(lnet_event_t *ev) { struct srpc_service_cd *scd; diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index 91d4caa4edb0..f8352c2a7d37 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -121,7 +121,7 @@ stt_del_timer(stt_timer_t *timer) } /* called with stt_data.stt_lock held */ -int +static int stt_expire_list(struct list_head *slot, unsigned long now) { int expired = 0; @@ -145,7 +145,7 @@ stt_expire_list(struct list_head *slot, unsigned long now) return expired; } -int +static int stt_check_timers(unsigned long *last) { int expired = 0; @@ -168,7 +168,7 @@ stt_check_timers(unsigned long *last) } -int +static int stt_timer_main(void *arg) { cfs_block_allsigs(); @@ -187,7 +187,7 @@ stt_timer_main(void *arg) return 0; } -int +static int stt_start_timer_thread(void) { struct task_struct *task; -- GitLab From 553d8ae8056d13f1562a9c91714ccb2f9fb94339 Mon Sep 17 00:00:00 2001 From: Anton Saraev Date: Wed, 29 Oct 2014 23:41:50 +0400 Subject: [PATCH 2151/9457] staging:lustre:lnet:selftest: remove unused function Function lnet_selftest_structure_assertion is never used and can be removed. Signed-off-by: Anton Saraev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/selftest/module.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index b2dd891f3734..92520c2e08fd 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -90,17 +90,6 @@ lnet_selftest_fini(void) return; } -void -lnet_selftest_structure_assertion(void) -{ - CLASSERT(sizeof(srpc_msg_t) == 160); - CLASSERT(sizeof(srpc_test_reqst_t) == 70); - CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_concur) == 72); - CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_ndest) == 78); - CLASSERT(sizeof(srpc_stat_reply_t) == 136); - CLASSERT(sizeof(srpc_stat_reqst_t) == 28); -} - static int lnet_selftest_init(void) { -- GitLab From 6c3773defb993275e749c9f876b826af5f7605f3 Mon Sep 17 00:00:00 2001 From: Mariusz Gorski Date: Wed, 29 Oct 2014 23:32:30 +0100 Subject: [PATCH 2152/9457] staging: panel: Use designated initializers Fix "warning: missing initializer [-Wmissing-field-initializers]" by using designated struct initializers. Signed-off-by: Mariusz Gorski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 6d1a32097d3c..98556ce8af6a 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -1375,9 +1375,9 @@ static const struct file_operations lcd_fops = { }; static struct miscdevice lcd_dev = { - LCD_MINOR, - "lcd", - &lcd_fops + .minor = LCD_MINOR, + .name = "lcd", + .fops = &lcd_fops, }; /* public function usable from the kernel for any purpose */ @@ -1652,9 +1652,9 @@ static const struct file_operations keypad_fops = { }; static struct miscdevice keypad_dev = { - KEYPAD_MINOR, - "keypad", - &keypad_fops + .minor = KEYPAD_MINOR, + .name = "keypad", + .fops = &keypad_fops, }; static void keypad_send_key(const char *string, int max_len) -- GitLab From 33de8f24a70238984700229cac9095d111e6da91 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:38:42 -0700 Subject: [PATCH 2153/9457] staging, rts5208, LLVMLinux: Change extern inline to static inline With compilers which follow the C99 standard (like modern versions of gcc and clang), "extern inline" does the opposite thing from older versions of gcc (emits code for an externally linkable version of the inline function). "static inline" does the intended behavior in both gcc and clang. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx_transport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h index b4b112372776..899bc2079dbe 100644 --- a/drivers/staging/rts5208/rtsx_transport.h +++ b/drivers/staging/rts5208/rtsx_transport.h @@ -46,7 +46,7 @@ void rtsx_add_cmd(struct rtsx_chip *chip, void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); -extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) +static inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) { #ifdef CMD_USING_SG return (u8 *)(chip->host_sg_tbl_ptr); -- GitLab From 831115af5ca36d713355bf1b379081691eca8b3f Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 23 Oct 2014 10:16:06 -0400 Subject: [PATCH 2154/9457] eCryptfs: Remove unnecessary casts when parsing packet lengths The elements in the data array are already unsigned chars and do not need to be casted. Signed-off-by: Tyler Hicks Reported-by: Dan Carpenter --- fs/ecryptfs/keystore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 635e8e16a5b7..917bd5c9776a 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -100,12 +100,12 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, (*size) = 0; if (data[0] < 192) { /* One-byte length */ - (*size) = (unsigned char)data[0]; + (*size) = data[0]; (*length_size) = 1; } else if (data[0] < 224) { /* Two-byte length */ - (*size) = (((unsigned char)(data[0]) - 192) * 256); - (*size) += ((unsigned char)(data[1]) + 192); + (*size) = (data[0] - 192) * 256; + (*size) += data[1] + 192; (*length_size) = 2; } else if (data[0] == 255) { /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */ -- GitLab From 6d91857d4826b382b3fd4fad95f52713be646f96 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:20 -0700 Subject: [PATCH 2155/9457] staging, rtl8192e, LLVMLinux: Change extern inline to static inline With compilers which follow the C99 standard (like modern versions of gcc and clang), "extern inline" does the opposite thing from older versions of gcc (emits code for an externally linkable version of the inline function). "static inline" does the intended behavior in all cases instead. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 4 ++-- drivers/staging/rtl8192e/rtllib_softmac.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 2d82f8993ea1..33995ac49584 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2944,12 +2944,12 @@ void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); extern const long rtllib_wlan_frequencies[]; -extern inline void rtllib_increment_scans(struct rtllib_device *ieee) +static inline void rtllib_increment_scans(struct rtllib_device *ieee) { ieee->scans++; } -extern inline int rtllib_get_scans(struct rtllib_device *ieee) +static inline int rtllib_get_scans(struct rtllib_device *ieee) { return ieee->scans; } diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index abb6729ae279..067a45ab97dd 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -343,7 +343,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, } } -inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) +static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) { unsigned int len, rate_len; u8 *tag; -- GitLab From 62ec95f86d2850b7ce6d73fb236a6fcf48411aea Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:21 -0700 Subject: [PATCH 2156/9457] staging, rtl8192e, LLVMLinux: Remove unused inline prototype rtllib_probe_req is defined as "static inline" in rtllib_softmac.c however it is declared differently as "extern inline" in rtllib_softmac.h. Since it isn't used outside of the scope of rtllib_softmac, it makes sense to remove the incorrect declaration. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 33995ac49584..132278265396 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2762,7 +2762,6 @@ extern void rtllib_stop_scan(struct rtllib_device *ieee); extern bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); extern void rtllib_stop_scan_syncro(struct rtllib_device *ieee); extern void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); -extern inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee); extern u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee); extern void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); -- GitLab From d82f0029e03d8512ac523ac2e4caa5cecb989570 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:22 -0700 Subject: [PATCH 2157/9457] staging, rtl8192e, LLVMLinux: Remove unused prototype MgntQuery_MgntFrameTxRate is only used within rtllib_softmac.c, so it really should be static instead of extern. Since it is currently extern a warning is generated because a different function of the same name is defined staticlly in ieee80211_softmac.c Removing the incorrect extern declaration and defining the rtllib_softmac version of this routine static fixes the warning. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 1 - drivers/staging/rtl8192e/rtllib_softmac.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 132278265396..cef2dc27103f 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2762,7 +2762,6 @@ extern void rtllib_stop_scan(struct rtllib_device *ieee); extern bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); extern void rtllib_stop_scan_syncro(struct rtllib_device *ieee); extern void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); -extern u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee); extern void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr); extern void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 067a45ab97dd..089a058ad2ed 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -193,7 +193,7 @@ MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) return QueryRate; } -u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) +static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; u8 rate; -- GitLab From 16fc54ee26912d3f2450bc4832b19c943dbdff17 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Wed, 29 Oct 2014 15:42:23 -0700 Subject: [PATCH 2158/9457] staging, rtl8192e, LLVMLinux: Make static local in inline function const rtllib_association_req is a (large) inline function which defines 2 constant static arrays which aren't labelled as const. As a result clang complains with: non-constant static local variable in inline function may be different in different files [-Wstatic-local-in-inline] static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; ^ The solution is making them "static const". However doing so requires dropping const when being used with struct octet_string. However the value is used in a const fashion thereafter, so no harm done. Signed-off-by: Behan Webster Suggested-by: Arnd Bergmann Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_softmac.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 089a058ad2ed..e970db474470 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1311,7 +1311,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, } if (beacon->bCkipSupported) { - static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; + static const u8 AironetIeOui[] = {0x00, 0x01, 0x66}; u8 CcxAironetBuf[30]; struct octet_string osCcxAironetIE; @@ -1331,10 +1331,11 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, } if (beacon->bCcxRmEnable) { - static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; + static const u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, + 0x00}; struct octet_string osCcxRmCap; - osCcxRmCap.Octet = CcxRmCapBuf; + osCcxRmCap.Octet = (u8 *) CcxRmCapBuf; osCcxRmCap.Length = sizeof(CcxRmCapBuf); tag = skb_put(skb, ccxrm_ie_len); *tag++ = MFIE_TYPE_GENERIC; -- GitLab From 1f33c41c03daece85a84b8dcea5733f3efe3e2b0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Sep 2014 16:08:21 -0700 Subject: [PATCH 2159/9457] seq_file: Rename seq_overflow() to seq_has_overflowed() and make public The return values of seq_printf/puts/putc are frequently misused. Start down a path to remove all the return value uses of these functions. Move the seq_overflow() to a global inlined function called seq_has_overflowed() that can be used by the users of seq_file() calls. Update the documentation to not show return types for seq_printf et al. Add a description of seq_has_overflowed(). Link: http://lkml.kernel.org/p/848ac7e3d1c31cddf638a8526fa3c59fa6fdeb8a.1412031505.git.joe@perches.com Cc: Al Viro Signed-off-by: Joe Perches [ Reworked the original patch from Joe ] Signed-off-by: Steven Rostedt --- Documentation/filesystems/seq_file.txt | 22 +++++++++++++--------- fs/seq_file.c | 15 ++------------- include/linux/seq_file.h | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/Documentation/filesystems/seq_file.txt b/Documentation/filesystems/seq_file.txt index 8ea3e90ace07..b797ed38de46 100644 --- a/Documentation/filesystems/seq_file.txt +++ b/Documentation/filesystems/seq_file.txt @@ -180,23 +180,19 @@ output must be passed to the seq_file code. Some utility functions have been defined which make this task easy. Most code will simply use seq_printf(), which works pretty much like -printk(), but which requires the seq_file pointer as an argument. It is -common to ignore the return value from seq_printf(), but a function -producing complicated output may want to check that value and quit if -something non-zero is returned; an error return means that the seq_file -buffer has been filled and further output will be discarded. +printk(), but which requires the seq_file pointer as an argument. For straight character output, the following functions may be used: - int seq_putc(struct seq_file *m, char c); - int seq_puts(struct seq_file *m, const char *s); - int seq_escape(struct seq_file *m, const char *s, const char *esc); + seq_putc(struct seq_file *m, char c); + seq_puts(struct seq_file *m, const char *s); + seq_escape(struct seq_file *m, const char *s, const char *esc); The first two output a single character and a string, just like one would expect. seq_escape() is like seq_puts(), except that any character in s which is in the string esc will be represented in octal form in the output. -There is also a pair of functions for printing filenames: +There are also a pair of functions for printing filenames: int seq_path(struct seq_file *m, struct path *path, char *esc); int seq_path_root(struct seq_file *m, struct path *path, @@ -209,6 +205,14 @@ root is desired, it can be used with seq_path_root(). Note that, if it turns out that path cannot be reached from root, the value of root will be changed in seq_file_root() to a root which *does* work. +A function producing complicated output may want to check + bool seq_has_overflowed(struct seq_file *m); +and avoid further seq_ calls if true is returned. + +A true return from seq_has_overflowed means that the seq_file buffer will +be discarded and the seq_show function will attempt to allocate a larger +buffer and retry printing. + Making it all work diff --git a/fs/seq_file.c b/fs/seq_file.c index 3857b720cb1b..353948ba1c5b 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -16,17 +16,6 @@ #include #include - -/* - * seq_files have a buffer which can may overflow. When this happens a larger - * buffer is reallocated and all the data will be printed again. - * The overflow state is true when m->count == m->size. - */ -static bool seq_overflow(struct seq_file *m) -{ - return m->count == m->size; -} - static void seq_set_overflow(struct seq_file *m) { m->count = m->size; @@ -124,7 +113,7 @@ static int traverse(struct seq_file *m, loff_t offset) error = 0; m->count = 0; } - if (seq_overflow(m)) + if (seq_has_overflowed(m)) goto Eoverflow; if (pos + m->count > offset) { m->from = offset - pos; @@ -267,7 +256,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) break; } err = m->op->show(m, p); - if (seq_overflow(m) || err) { + if (seq_has_overflowed(m) || err) { m->count = offs; if (likely(err <= 0)) break; diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 52e0097f61f0..cf6a9daaaf6d 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -42,6 +42,21 @@ struct seq_operations { #define SEQ_SKIP 1 +/** + * seq_has_overflowed - check if the buffer has overflowed + * @m: the seq_file handle + * + * seq_files have a buffer which may overflow. When this happens a larger + * buffer is reallocated and all the data will be printed again. + * The overflow state is true when m->count == m->size. + * + * Returns true if the buffer received more than it can hold. + */ +static inline bool seq_has_overflowed(struct seq_file *m) +{ + return m->count == m->size; +} + /** * seq_get_buf - get buffer to write arbitrary data to * @m: the seq_file handle -- GitLab From dce4ec2e452fddb7542b5fc15d0e6b8531f6d5eb Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 28 Oct 2014 14:35:59 +0800 Subject: [PATCH 2160/9457] ACPI / video: Run _BCL before deciding registering backlight The ASUS K53SM's ACPI table queries _OSI("Windows 2012") in the video output device's _BCL and _BCM control method instead of the usual _INI functions of the _SB or PCI host bridge PCI0 devices. This made our video module thought this is a pre-Win8 system when deciding if we should register a backlight interface for it and the end result is that a non-working acpi_video interface is registered and user is unable to control backlight from GUI. Solve this problem by evaluating _BCL control method before doing the decision. Note that for some Thinkpad systems, the _BCL is also required to be evaluated for the hotkey event to be generated no matter if we will register an ACPI video backlight interface for it or not. Since the thinkpad_acpi module will do this anyway we didn't add such a thing in the video module previously. But now with this change here, the thinkpad_acpi module is no more necessary for those systems regarding backlight functionality. Link: https://bugzilla.kernel.org/show_bug.cgi?id=85051 Reported-and-tested-by: Ralf Jung Signed-off-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 807a88a0f394..41e6b977ceb2 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1680,6 +1680,19 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) printk(KERN_ERR PREFIX "Create sysfs link\n"); } +static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) +{ + struct acpi_video_device *dev; + union acpi_object *levels; + + mutex_lock(&video->device_list_lock); + list_for_each_entry(dev, &video->video_device_list, entry) { + if (!acpi_video_device_lcd_query_levels(dev, &levels)) + kfree(levels); + } + mutex_unlock(&video->device_list_lock); +} + static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) { struct acpi_video_device *dev; @@ -1687,6 +1700,8 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) if (video->backlight_registered) return 0; + acpi_video_run_bcl_for_osi(video); + if (!acpi_video_verify_backlight_support()) return 0; -- GitLab From eafe8404c103b3051b6421fc17e0e8b91d369f0b Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Wed, 29 Oct 2014 10:48:10 -0700 Subject: [PATCH 2161/9457] ALSA: es1968: Replace timeval with ktime_t es1968_measure_clock uses struct timeval, which on 32-bit systems will overflow in 2038, leading to incorrect interpretation of time.This patch changes the function to use ktime_t instead of struct timeval, which implies: - no y2038: ktime_t uses a 64-bit datatype explicitly. - efficent subtraction: The earlier version computes the difference in usecs while dealing with secs and nsecs. It requires checks to see if the nsecs of stop is less than start. This patch uses a direct subtract of ktime_t and converts to usecs. - use of monotonic clock (ktime_get) over real time (do_gettimeofday), which simplifies timekeeping, as it does not have to deal with cases where stop_time is less than start_time. Signed-off-by: Tina Ruchandani Reviewed-by: Arnd Bergmann Signed-off-by: Takashi Iwai --- sound/pci/es1968.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index a9956a7c5677..6039700f8579 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1710,7 +1710,8 @@ static void es1968_measure_clock(struct es1968 *chip) int i, apu; unsigned int pa, offset, t; struct esm_memory *memory; - struct timeval start_time, stop_time; + ktime_t start_time, stop_time; + ktime_t diff; if (chip->clock == 0) chip->clock = 48000; /* default clock value */ @@ -1761,12 +1762,12 @@ static void es1968_measure_clock(struct es1968 *chip) snd_es1968_bob_inc(chip, ESM_BOB_FREQ); __apu_set_register(chip, apu, 5, pa & 0xffff); snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); - do_gettimeofday(&start_time); + start_time = ktime_get(); spin_unlock_irq(&chip->reg_lock); msleep(50); spin_lock_irq(&chip->reg_lock); offset = __apu_get_register(chip, apu, 5); - do_gettimeofday(&stop_time); + stop_time = ktime_get(); snd_es1968_trigger_apu(chip, apu, 0); /* stop */ snd_es1968_bob_dec(chip); chip->in_measurement = 0; @@ -1777,12 +1778,8 @@ static void es1968_measure_clock(struct es1968 *chip) offset &= 0xfffe; offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2); - t = stop_time.tv_sec - start_time.tv_sec; - t *= 1000000; - if (stop_time.tv_usec < start_time.tv_usec) - t -= start_time.tv_usec - stop_time.tv_usec; - else - t += stop_time.tv_usec - start_time.tv_usec; + diff = ktime_sub(stop_time, start_time); + t = ktime_to_us(diff); if (t == 0) { dev_err(chip->card->dev, "?? calculation error..\n"); } else { -- GitLab From 986f168644491e835d446c04c5dc0c66777348b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 9 Oct 2014 10:29:35 -0300 Subject: [PATCH 2162/9457] [media] dib7000p: get rid of an unused argument dib7000p is for DVB, and not ISDB. So, there's no layer. That removes this compilation warning: drivers/media/dvb-frontends/dib7000p.c:1972: warning: 'i' is used uninitialized in this function Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib7000p.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 589134e95175..c505d696f92d 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -1780,7 +1780,7 @@ static u32 interpolate_value(u32 value, struct linear_segments *segments, } /* FIXME: may require changes - this one was borrowed from dib8000 */ -static u32 dib7000p_get_time_us(struct dvb_frontend *demod, int layer) +static u32 dib7000p_get_time_us(struct dvb_frontend *demod) { struct dtv_frontend_properties *c = &demod->dtv_property_cache; u64 time_us, tmp64; @@ -1881,7 +1881,6 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) { struct dib7000p_state *state = demod->demodulator_priv; struct dtv_frontend_properties *c = &demod->dtv_property_cache; - int i; int show_per_stats = 0; u32 time_us = 0, val, snr; u64 blocks, ucb; @@ -1935,7 +1934,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) /* Estimate the number of packets based on bitrate */ if (!time_us) - time_us = dib7000p_get_time_us(demod, -1); + time_us = dib7000p_get_time_us(demod); if (time_us) { blocks = 1250000ULL * 1000000ULL; @@ -1949,7 +1948,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) /* Get post-BER measures */ if (time_after(jiffies, state->ber_jiffies_stats)) { - time_us = dib7000p_get_time_us(demod, -1); + time_us = dib7000p_get_time_us(demod); state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); dprintk("Next all layers stats available in %u us.", time_us); @@ -1969,7 +1968,7 @@ static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat) c->block_error.stat[0].scale = FE_SCALE_COUNTER; c->block_error.stat[0].uvalue += val; - time_us = dib7000p_get_time_us(demod, i); + time_us = dib7000p_get_time_us(demod); if (time_us) { blocks = 1250000ULL * 1000000ULL; do_div(blocks, time_us * 8 * 204); -- GitLab From dda42bd0c3a4b7be1561546914eda59b68a58be4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 12:04:50 +0100 Subject: [PATCH 2163/9457] ALSA: hda - Add kerneldoc comments to hda_generic.c Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 164 +++++++++++++++++++++++++++++------- 1 file changed, 135 insertions(+), 29 deletions(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 06d721085e72..63b69f750d8e 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -40,7 +40,12 @@ #include "hda_generic.h" -/* initialize hda_gen_spec struct */ +/** + * snd_hda_gen_spec_init - initialize hda_gen_spec struct + * @spec: hda_gen_spec object to initialize + * + * Initialize the given hda_gen_spec object. + */ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) { snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); @@ -51,6 +56,17 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) } EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); +/** + * snd_hda_gen_add_kctl - Add a new kctl_new struct from the template + * @spec: hda_gen_spec object + * @name: name string to override the template, NULL if unchanged + * @temp: template for the new kctl + * + * Add a new kctl (actually snd_kcontrol_new to be instantiated later) + * element based on the given snd_kcontrol_new template @temp and the + * name string @name to the list in @spec. + * Returns the newly created object or NULL as error. + */ struct snd_kcontrol_new * snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, const struct snd_kcontrol_new *temp) @@ -259,8 +275,14 @@ static struct nid_path *get_nid_path(struct hda_codec *codec, return NULL; } -/* get the path between the given NIDs; - * passing 0 to either @pin or @dac behaves as a wildcard +/** + * snd_hda_get_nid_path - get the path between the given NIDs + * @codec: the HDA codec + * @from_nid: the NID where the path start from + * @to_nid: the NID where the path ends at + * + * Return the found nid_path object or NULL for error. + * Passing 0 to either @from_nid or @to_nid behaves as a wildcard. */ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, hda_nid_t from_nid, hda_nid_t to_nid) @@ -269,8 +291,14 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); -/* get the index number corresponding to the path instance; - * the index starts from 1, for easier checking the invalid value +/** + * snd_hda_get_path_idx - get the index number corresponding to the path + * instance + * @codec: the HDA codec + * @path: nid_path object + * + * The returned index starts from 1, i.e. the actual array index with offset 1, + * and zero is handled as an invalid path */ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) { @@ -287,7 +315,12 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) } EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); -/* get the path instance corresponding to the given index number */ +/** + * snd_hda_get_path_from_idx - get the path instance corresponding to the + * given index number + * @codec: the HDA codec + * @idx: the path index + */ struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) { struct hda_gen_spec *spec = codec->spec; @@ -415,7 +448,18 @@ static bool __parse_nid_path(struct hda_codec *codec, return true; } -/* parse the widget path from the given nid to the target nid; +/** + * snd_hda_parse_nid_path - parse the widget path from the given nid to + * the target nid + * @codec: the HDA codec + * @from_nid: the NID where the path start from + * @to_nid: the NID where the path ends at + * @anchor_nid: the anchor indication + * @path: the path object to store the result + * + * Returns true if a matching path is found. + * + * The parsing behavior depends on parameters: * when @from_nid is 0, try to find an empty DAC; * when @anchor_nid is set to a positive value, only paths through the widget * with the given value are evaluated. @@ -436,9 +480,15 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, } EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); -/* - * parse the path between the given NIDs and add to the path list. - * if no valid path is found, return NULL +/** + * snd_hda_add_new_path - parse the path between the given NIDs and + * add to the path list + * @codec: the HDA codec + * @from_nid: the NID where the path start from + * @to_nid: the NID where the path ends at + * @anchor_nid: the anchor indication, see snd_hda_parse_nid_path() + * + * If no valid path is found, returns NULL. */ struct nid_path * snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, @@ -724,8 +774,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, } } -/* activate or deactivate the given path - * if @add_aamix is set, enable the input from aa-mix NID as well (if any) +/** + * snd_hda_activate_path - activate or deactivate the given path + * @codec: the HDA codec + * @path: the path to activate/deactivate + * @enable: flag to activate or not + * @add_aamix: enable the input from aamix NID + * + * If @add_aamix is set, enable the input from aa-mix NID as well (if any). */ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, bool enable, bool add_aamix) @@ -3883,7 +3939,12 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, } } -/* Toggle outputs muting */ +/** + * snd_hda_gen_update_outputs - Toggle outputs muting + * @codec: the HDA codec + * + * Update the mute status of all outputs based on the current jack states. + */ void snd_hda_gen_update_outputs(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; @@ -3944,7 +4005,11 @@ static void call_update_outputs(struct hda_codec *codec) snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); } -/* standard HP-automute helper */ +/** + * snd_hda_gen_hp_automute - standard HP-automute helper + * @codec: the HDA codec + * @jack: jack object, NULL for the whole + */ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_callback *jack) { @@ -3965,7 +4030,11 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); -/* standard line-out-automute helper */ +/** + * snd_hda_gen_line_automute - standard line-out-automute helper + * @codec: the HDA codec + * @jack: jack object, NULL for the whole + */ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_callback *jack) { @@ -3986,7 +4055,11 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, } EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); -/* standard mic auto-switch helper */ +/** + * snd_hda_gen_mic_autoswitch - standard mic auto-switch helper + * @codec: the HDA codec + * @jack: jack object, NULL for the whole + */ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_callback *jack) { @@ -4318,7 +4391,13 @@ static int check_auto_mic_availability(struct hda_codec *codec) return 0; } -/* power_filter hook; make inactive widgets into power down */ +/** + * snd_hda_gen_path_power_filter - power_filter hook to make inactive widgets + * into power down + * @codec: the HDA codec + * @nid: NID to evalute + * @power_state: target power state + */ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state) @@ -4354,8 +4433,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) } } -/* - * Parse the given BIOS configuration and set up the hda_gen_spec +/** + * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and + * set up the hda_gen_spec + * @codec: the HDA codec + * @cfg: Parsed pin configuration * * return 1 if successful, 0 if the proper config is not found, * or a negative error code @@ -4541,6 +4623,12 @@ static const char * const slave_pfxs[] = { NULL, }; +/** + * snd_hda_gen_build_controls - Build controls from the parsed results + * @codec: the HDA codec + * + * Pass this to build_controls patch_ops. + */ int snd_hda_gen_build_controls(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; @@ -5018,7 +5106,12 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, strlcat(str, sfx, len); } -/* build PCM streams based on the parsed results */ +/** + * snd_hda_gen_build_pcms - build PCM streams based on the parsed results + * @codec: the HDA codec + * + * Pass this to build_pcms patch_ops. + */ int snd_hda_gen_build_pcms(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; @@ -5313,9 +5406,11 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) } } -/* - * initialize the generic spec; - * this can be put as patch_ops.init function +/** + * snd_hda_gen_init - initialize the generic spec + * @codec: the HDA codec + * + * This can be put as patch_ops init function. */ int snd_hda_gen_init(struct hda_codec *codec) { @@ -5351,9 +5446,11 @@ int snd_hda_gen_init(struct hda_codec *codec) } EXPORT_SYMBOL_GPL(snd_hda_gen_init); -/* - * free the generic spec; - * this can be put as patch_ops.free function +/** + * snd_hda_gen_free - free the generic spec + * @codec: the HDA codec + * + * This can be put as patch_ops free function. */ void snd_hda_gen_free(struct hda_codec *codec) { @@ -5365,9 +5462,12 @@ void snd_hda_gen_free(struct hda_codec *codec) EXPORT_SYMBOL_GPL(snd_hda_gen_free); #ifdef CONFIG_PM -/* - * check the loopback power save state; - * this can be put as patch_ops.check_power_status function +/** + * snd_hda_gen_check_power_status - check the loopback power save state + * @codec: the HDA codec + * @nid: NID to inspect + * + * This can be put as patch_ops check_power_status function. */ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) { @@ -5393,6 +5493,12 @@ static const struct hda_codec_ops generic_patch_ops = { #endif }; +/** + * snd_hda_parse_generic_codec - Generic codec parser + * @codec: the HDA codec + * + * This should be called from the HDA codec core. + */ int snd_hda_parse_generic_codec(struct hda_codec *codec) { struct hda_gen_spec *spec; -- GitLab From a47959fbd5808890963fe8475a7c436bfd60d8c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Sep 2014 15:37:38 -0300 Subject: [PATCH 2164/9457] [media] Documentation: FE_SET_PROPERTY requires R/W FE_SET_PROPERTY requires to open the devnode on R/W mode, or otherwise it will fail. Document it. Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/dvb/dvbproperty.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml index 948ddaab592e..3018564ddfd9 100644 --- a/Documentation/DocBook/media/dvb/dvbproperty.xml +++ b/Documentation/DocBook/media/dvb/dvbproperty.xml @@ -120,8 +120,8 @@ struct dtv_properties { -This ioctl call sets one or more frontend properties. This call only - requires read-only access to the device. +This ioctl call sets one or more frontend properties. This call + requires read/write access to the device. SYNOPSIS -- GitLab From 52ee29fe94ffb07b98bc31e018560b8fd3800904 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 28 Sep 2014 23:23:19 -0300 Subject: [PATCH 2165/9457] [media] drxk: Fix debug printks This patch partially reverts 0fb220f2a5cb. What happened is that the conversion of debug messages to use pr_debug() was a bad idea, because one needing to debug would need to both enable debug level via a modprobe parameter, and then to enable the dynamic printk's. So, for now, let's use printk() directly at dprintk(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drxk_hard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index 672195147d01..f140b835c414 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -166,9 +166,9 @@ static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); -#define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ - pr_debug(fmt, ##arg); \ +#define dprintk(level, fmt, arg...) do { \ +if (debug >= level) \ + printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \ } while (0) -- GitLab From 1b07a77f6e1ebaebe7601fa734ff415fdf568ebb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 28 Sep 2014 23:23:20 -0300 Subject: [PATCH 2166/9457] [media] em28xx-dvb: remove unused mfe_sharing This field is not used on this driver anymore. Remove it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 9682c52d67d1..65a456d2f454 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1047,7 +1047,7 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) static int em28xx_dvb_init(struct em28xx *dev) { - int result = 0, mfe_shared = 0; + int result = 0; struct em28xx_dvb *dvb; if (dev->is_audio_only) { @@ -1624,9 +1624,6 @@ static int em28xx_dvb_init(struct em28xx *dev) if (result < 0) goto out_free; - /* MFE lock */ - dvb->adapter.mfe_shared = mfe_shared; - em28xx_info("DVB extension successfully initialized\n"); kref_get(&dev->ref); -- GitLab From 0d1165fcafaf42b153857ba6e21200fdd8c9543a Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Thu, 30 Oct 2014 07:43:16 -0300 Subject: [PATCH 2167/9457] [media] si2157: add support for SYS_DVBC_ANNEX_B Set the property for delivery system also in case of SYS_DVBC_ANNEX_B. This behaviour is observed in the sniffs taken with Hauppauge HVR-955Q Windows driver. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/si2157.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index cf97142e01e6..b086b87d0890 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -250,6 +250,9 @@ static int si2157_set_params(struct dvb_frontend *fe) case SYS_ATSC: delivery_system = 0x00; break; + case SYS_DVBC_ANNEX_B: + delivery_system = 0x10; + break; case SYS_DVBT: case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */ delivery_system = 0x20; -- GitLab From 5d1f00a20d2d56ed480e64e938a2391353ee565b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Oct 2014 07:53:04 -0300 Subject: [PATCH 2168/9457] [media] sound: simplify au0828 quirk table Add a macro to simplify au0828 quirk table. That makes easier to check it against the USB IDs at drivers/media/usb/au0828/au0828-cards.c. Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-cards.c | 5 + sound/usb/quirks-table.h | 158 +++++------------------- 2 files changed, 36 insertions(+), 127 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c index 9eb77ac2153b..da87f1cc31a9 100644 --- a/drivers/media/usb/au0828/au0828-cards.c +++ b/drivers/media/usb/au0828/au0828-cards.c @@ -36,6 +36,11 @@ static void hvr950q_cs5340_audio(void *priv, int enable) au0828_clear(dev, REG_000, 0x10); } +/* + * WARNING: There's a quirks table at sound/usb/quirks-table.h + * that should also be updated every time a new device with V4L2 support + * is added here. + */ struct au0828_board au0828_boards[] = { [AU0828_BOARD_UNKNOWN] = { .name = "Unknown board", diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c657752a420c..8f3e2bf100eb 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2804,133 +2804,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, -/* Hauppauge HVR-950Q and HVR-850 */ -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7200), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-850", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, -{ - USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-950Q", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, +/* + * Auvitek au0828 devices with audio interface. + * This should be kept in sync with drivers/media/usb/au0828/au0828-cards.c + * Please notice that some drivers are DVB only, and don't need to be + * here. That's the case, for example, of DVICO_FUSIONHDTV7. + */ + +#define AU0828_DEVICE(vid, pid, vname, pname) { \ + USB_DEVICE_VENDOR_SPEC(vid, pid), \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_INT_CLASS | \ + USB_DEVICE_ID_MATCH_INT_SUBCLASS, \ + .bInterfaceClass = USB_CLASS_AUDIO, \ + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, \ + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { \ + .vendor_name = vname, \ + .product_name = pname, \ + .ifnum = QUIRK_ANY_INTERFACE, \ + .type = QUIRK_AUDIO_ALIGN_TRANSFER, \ + } \ +} + +AU0828_DEVICE(0x2040, 0x7200, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7210, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7217, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x721b, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x721e, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x721f, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7240, "Hauppauge", "HVR-850"), +AU0828_DEVICE(0x2040, 0x7280, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x0fd9, 0x0008, "Hauppauge", "HVR-950Q"), /* Digidesign Mbox */ { -- GitLab From 678fa12fb8e75c6dc1e781a02e3ddbbba7e1a904 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Oct 2014 07:53:05 -0300 Subject: [PATCH 2169/9457] [media] sound: Update au0828 quirks table The au0828 quirks table is currently not in sync with the au0828 media driver. Syncronize it and put them on the same order as found at au0828 driver, as all the au0828 devices with analog TV need the same quirks. Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- sound/usb/quirks-table.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8f3e2bf100eb..83bddbdb90e9 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2827,14 +2827,22 @@ YAMAHA_DEVICE(0x7010, "UB99"), } AU0828_DEVICE(0x2040, 0x7200, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7240, "Hauppauge", "HVR-850"), AU0828_DEVICE(0x2040, 0x7210, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x7217, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x721b, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x721e, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x2040, 0x721f, "Hauppauge", "HVR-950Q"), -AU0828_DEVICE(0x2040, 0x7240, "Hauppauge", "HVR-850"), AU0828_DEVICE(0x2040, 0x7280, "Hauppauge", "HVR-950Q"), AU0828_DEVICE(0x0fd9, 0x0008, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7201, "Hauppauge", "HVR-950Q-MXL"), +AU0828_DEVICE(0x2040, 0x7211, "Hauppauge", "HVR-950Q-MXL"), +AU0828_DEVICE(0x2040, 0x7281, "Hauppauge", "HVR-950Q-MXL"), +AU0828_DEVICE(0x05e1, 0x0480, "Hauppauge", "Woodbury"), +AU0828_DEVICE(0x2040, 0x8200, "Hauppauge", "Woodbury"), +AU0828_DEVICE(0x2040, 0x7260, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7213, "Hauppauge", "HVR-950Q"), +AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), /* Digidesign Mbox */ { -- GitLab From 438f4e2801d730442d6fc36ab2b265c4b54cff8b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 12:44:00 +0100 Subject: [PATCH 2170/9457] ALSA: doc: Add ASoC codes into API documentation Signed-off-by: Takashi Iwai --- Documentation/DocBook/alsa-driver-api.tmpl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl index 7bec270e2494..b2d2c3b74fb0 100644 --- a/Documentation/DocBook/alsa-driver-api.tmpl +++ b/Documentation/DocBook/alsa-driver-api.tmpl @@ -104,13 +104,30 @@ !Iinclude/sound/compress_driver.h + ASoC + ASoC Core API +!Iinclude/sound/soc.h +!Esound/soc/soc-core.c +!Esound/soc/soc-cache.c +!Esound/soc/soc-devres.c +!Esound/soc/soc-io.c +!Esound/soc/soc-pcm.c + + ASoC DAPM API +!Esound/soc/soc-dapm.c + + ASoC DMA Engine API +!Esound/soc/soc-generic-dmaengine-pcm.c + + Miscellaneous Functions Hardware-Dependent Devices API !Esound/core/hwdep.c Jack Abstraction Layer API -!Esound/core/jack.c !Iinclude/sound/jack.h +!Esound/core/jack.c +!Esound/soc/soc-jack.c ISA DMA Helpers !Esound/core/isadma.c -- GitLab From 12cddbd8696657ff405e054be48747b906731698 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 13:44:34 +0100 Subject: [PATCH 2171/9457] ALSA: control: Add missing kerneldoc comments to exported functions A few functions have no proper documentation yet, so let's add them. Along with it, remove superfluous blank line between the closing brace and EXPORT_SYMBOL() line. Signed-off-by: Takashi Iwai --- sound/core/control.c | 64 +++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index 5c35bbaf881e..99aa3aa157ba 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file) return 0; } +/** + * snd_ctl_notify - Send notification to user-space for a control change + * @card: the card to send notification + * @mask: the event mask, SNDRV_CTL_EVENT_* + * @id: the ctl element id to send notification + * + * This function adds an event record with the given id and mask, appends + * to the list and wakes up the user-space for notification. This can be + * called in the atomic context. + */ void snd_ctl_notify(struct snd_card *card, unsigned int mask, struct snd_ctl_elem_id *id) { @@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, } read_unlock(&card->ctl_files_rwlock); } - EXPORT_SYMBOL(snd_ctl_notify); /** @@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, kctl.private_data = private_data; return snd_ctl_new(&kctl, access); } - EXPORT_SYMBOL(snd_ctl_new1); /** @@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) kfree(kcontrol); } } - EXPORT_SYMBOL(snd_ctl_free_one); static bool snd_ctl_remove_numid_conflict(struct snd_card *card, @@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return err; } - EXPORT_SYMBOL(snd_ctl_add); /** @@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return 0; } - EXPORT_SYMBOL(snd_ctl_remove); /** @@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) up_write(&card->controls_rwsem); return ret; } - EXPORT_SYMBOL(snd_ctl_remove_id); /** @@ -617,7 +621,6 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, up_write(&card->controls_rwsem); return 0; } - EXPORT_SYMBOL(snd_ctl_rename_id); /** @@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi } return NULL; } - EXPORT_SYMBOL(snd_ctl_find_numid); /** @@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, } return NULL; } - EXPORT_SYMBOL(snd_ctl_find_id); static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, @@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * return 0; } +/** + * snd_ctl_register_ioctl - register the device-specific control-ioctls + * @fcn: ioctl callback function + * + * called from each device manager like pcm.c, hwdep.c, etc. + */ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) { return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); } - EXPORT_SYMBOL(snd_ctl_register_ioctl); #ifdef CONFIG_COMPAT +/** + * snd_ctl_register_ioctl_compat - register the device-specific 32bit compat + * control-ioctls + * @fcn: ioctl callback function + */ int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) { return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); } - EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); #endif @@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, return -EINVAL; } +/** + * snd_ctl_unregister_ioctl - de-register the device-specific control-ioctls + * @fcn: ioctl callback function to unregister + */ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); } - EXPORT_SYMBOL(snd_ctl_unregister_ioctl); #ifdef CONFIG_COMPAT +/** + * snd_ctl_unregister_ioctl - de-register the device-specific compat 32bit + * control-ioctls + * @fcn: ioctl callback function to unregister + */ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); } - EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); #endif @@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card) /* * Frequently used control callbacks/helpers */ + +/** + * snd_ctl_boolean_mono_info - Helper function for a standard boolean info + * callback with a mono channel + * @kcontrol: the kcontrol instance + * @uinfo: info to store + * + * This is a function that can be used as info callback for a standard + * boolean control with a single mono channel. + */ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } - EXPORT_SYMBOL(snd_ctl_boolean_mono_info); +/** + * snd_ctl_boolean_stereo_info - Helper function for a standard boolean info + * callback with stereo two channels + * @kcontrol: the kcontrol instance + * @uinfo: info to store + * + * This is a function that can be used as info callback for a standard + * boolean control with stereo two channels. + */ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } - EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); /** -- GitLab From 61110fbab1f083249ac0ac7090526798d8815210 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Fri, 26 Sep 2014 22:11:45 -0300 Subject: [PATCH 2172/9457] [media] ti-fpe: LLVMLinux: Remove nested function from ti-vpe Replace the use of nested functions where a normal function will suffice. Nested functions are not liked by upstream kernel developers in general. Their use breaks the use of clang as a compiler, and doesn't make the code any better. This code now works for both gcc and clang. Suggested-by: Arnd Bergmann Signed-off-by: Behan Webster Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/csc.c | 8 ++------ drivers/media/platform/ti-vpe/sc.c | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c index 940df4000c42..44fbf41fba7f 100644 --- a/drivers/media/platform/ti-vpe/csc.c +++ b/drivers/media/platform/ti-vpe/csc.c @@ -93,12 +93,8 @@ void csc_dump_regs(struct csc_data *csc) { struct device *dev = &csc->pdev->dev; - u32 read_reg(struct csc_data *csc, int offset) - { - return ioread32(csc->base + offset); - } - -#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(csc, CSC_##r)) +#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \ + ioread32(csc->base + CSC_##r)) DUMPREG(CSC00); DUMPREG(CSC01); diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c index 6314171ffe9b..1088381bd349 100644 --- a/drivers/media/platform/ti-vpe/sc.c +++ b/drivers/media/platform/ti-vpe/sc.c @@ -24,12 +24,8 @@ void sc_dump_regs(struct sc_data *sc) { struct device *dev = &sc->pdev->dev; - u32 read_reg(struct sc_data *sc, int offset) - { - return ioread32(sc->base + offset); - } - -#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(sc, CFG_##r)) +#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \ + ioread32(sc->base + CFG_##r)) DUMPREG(SC0); DUMPREG(SC1); -- GitLab From f213d8f79a3928eaa2e2936f8ab40761aac04b95 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 13:45:58 +0100 Subject: [PATCH 2173/9457] ALSA: pcm: Use static inline for snd_pcm_lib_alloc_vmalloc_buffer() ... instead of #if 0 hack. It's more straightforward and obvious. Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index e862497f7556..5c3310d7d4b8 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -942,7 +942,6 @@ int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream); struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, unsigned long offset); -#if 0 /* for kernel-doc */ /** * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer * @substream: the substream to allocate the buffer to @@ -955,8 +954,13 @@ struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, * Return: 1 if the buffer was changed, 0 if not changed, or a negative error * code. */ -static int snd_pcm_lib_alloc_vmalloc_buffer - (struct snd_pcm_substream *substream, size_t size); +static inline int snd_pcm_lib_alloc_vmalloc_buffer + (struct snd_pcm_substream *substream, size_t size) +{ + return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, + GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); +} + /** * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer * @substream: the substream to allocate the buffer to @@ -968,15 +972,12 @@ static int snd_pcm_lib_alloc_vmalloc_buffer * Return: 1 if the buffer was changed, 0 if not changed, or a negative error * code. */ -static int snd_pcm_lib_alloc_vmalloc_32_buffer - (struct snd_pcm_substream *substream, size_t size); -#endif -#define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ - _snd_pcm_lib_alloc_vmalloc_buffer \ - (subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO) -#define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \ - _snd_pcm_lib_alloc_vmalloc_buffer \ - (subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO) +static inline int snd_pcm_lib_alloc_vmalloc_32_buffer + (struct snd_pcm_substream *substream, size_t size) +{ + return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, + GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); +} #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) -- GitLab From 35c0a8c0178ad3f6f14e1dd76f0317156deaae51 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Thu, 30 Oct 2014 21:21:52 +0800 Subject: [PATCH 2174/9457] ASoC: Intel: Fix block is enabled multiple times issue During FW parsing and loading, block_list_prepare() may be called for each raw data block copying and this may made the hsw_block_enable() called mutiple times, which increase block->users many times. The result of this is hsw_block_disable() can't power gated the related block when trying to free the blocks during suspend, and the power gating status also confused. Here check the block user status, only calling enable() for those blocks who has no user yet. Remember that this works correctlly on current case, where there are enough SRAM memory so different module won't share a memory block. For further usage, we may need restructure the struct sst_mem_block to save the module list who is using it. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 35788ad4087e..c451398b058c 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -149,7 +149,7 @@ static int block_list_prepare(struct sst_dsp *dsp, /* enable each block so that's it'e ready for data */ list_for_each_entry(block, block_list, module_list) { - if (block->ops && block->ops->enable) { + if (block->ops && block->ops->enable && !block->users) { ret = block->ops->enable(block); if (ret < 0) { dev_err(dsp->dev, -- GitLab From 82c10276d4e86fa51b89cf62a1cf6ed12d543843 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 29 Sep 2014 04:44:16 -0300 Subject: [PATCH 2175/9457] [media] cx23855: add support for DVBSky T980C (no CI support) This patch adds basic support for DVBSky T980C card. CI interface is not supported. DVBSky T980C is a PCIe card with the following components: - CX23885 PCIe bridge - Si2168-A20 demodulator - Si2158-A20 tuner - CIMaX SP2 CI chip The demodulator and tuner need firmware. They're the same as used with TT CT2-4650 CI: https://www.mail-archive.com/linux-media@vger.kernel.org/msg78033.html Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 40 +++++++++++++++ drivers/media/pci/cx23885/cx23885-dvb.c | 61 +++++++++++++++++++++++ drivers/media/pci/cx23885/cx23885.h | 1 + 3 files changed, 102 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 88c257d1161b..e8965e63eb09 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -680,6 +680,10 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVBSKY_T980C] = { + .name = "DVBSky T980C", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -939,6 +943,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x4254, .subdevice = 0x9580, .card = CX23885_BOARD_DVBSKY_T9580, + }, { + .subvendor = 0x4254, + .subdevice = 0x980c, + .card = CX23885_BOARD_DVBSKY_T980C, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1541,6 +1549,36 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(100); cx23885_gpio_set(dev, GPIO_2 | GPIO_11); break; + case CX23885_BOARD_DVBSKY_T980C: + /* + * GPIO-0 INTA from CiMax, input + * GPIO-1 reset CiMax, output, high active + * GPIO-2 reset demod, output, low active + * GPIO-3 to GPIO-10 data/addr for CAM + * GPIO-11 ~CS0 to CiMax1 + * GPIO-12 ~CS1 to CiMax2 + * GPIO-13 ADL0 load LSB addr + * GPIO-14 ADL1 load MSB addr + * GPIO-15 ~RDY from CiMax + * GPIO-17 ~RD to CiMax + * GPIO-18 ~WR to CiMax + */ + + cx_set(GP0_IO, 0x00060002); /* GPIO 1/2 as output */ + cx_clear(GP0_IO, 0x00010004); /* GPIO 0 as input */ + mdelay(100); /* reset delay */ + cx_set(GP0_IO, 0x00060004); /* GPIO as out, reset high */ + cx_clear(GP0_IO, 0x00010002); + cx_write(MC417_CTL, 0x00000037); /* enable GPIO3-18 pins */ + + /* GPIO-15 IN as ~ACK, rest as OUT */ + cx_write(MC417_OEN, 0x00001000); + + /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ + cx_write(MC417_RWD, 0x0000c300); + + /* enable irq */ + cx_write(GPIO_ISM, 0x00000000); /* INTERRUPTS active low */ } } @@ -1817,6 +1855,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_TEVII_S471: case CX23885_BOARD_DVBWORLD_2005: case CX23885_BOARD_PROF_8000: + case CX23885_BOARD_DVBSKY_T980C: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -1935,6 +1974,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 4cb90317ff45..062854d30a75 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1680,6 +1680,52 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + case CX23885_BOARD_DVBSKY_T980C: + i2c_bus = &dev->i2c_bus[1]; + + /* attach frontend */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &fe0->dvb.frontend; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (client_demod == NULL || + client_demod->dev.driver == NULL) + goto frontend_detach; + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = fe0->dvb.frontend; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_tuner = client_tuner; + break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", @@ -1770,6 +1816,21 @@ static int dvb_register(struct cx23885_tsport *port) (port->nr-1) * 8, 6); break; } + case CX23885_BOARD_DVBSKY_T980C: { + u8 eeprom[256]; /* 24C02 i2c eeprom */ + + if (port->nr != 1) + break; + + /* Read entire EEPROM */ + dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; + tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, + sizeof(eeprom)); + printk(KERN_INFO "DVBSky T980C MAC address: %pM\n", + eeprom + 0xc0); + memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6); + break; + } } return ret; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 6c35e6115969..33b1e26847a2 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -93,6 +93,7 @@ #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43 #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44 #define CX23885_BOARD_DVBSKY_T9580 45 +#define CX23885_BOARD_DVBSKY_T980C 46 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From 9a25d410bbc84074578ff2fb3c39aa768c7d5555 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 29 Sep 2014 04:44:17 -0300 Subject: [PATCH 2176/9457] [media] sp2: fix incorrect struct Incorrect struct used in the SP2 driver. Reported-by: Max Nibble Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/sp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index 9b684d5c8f91..1f4f25004711 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c @@ -407,7 +407,7 @@ static int sp2_probe(struct i2c_client *client, static int sp2_remove(struct i2c_client *client) { - struct si2157 *s = i2c_get_clientdata(client); + struct sp2 *s = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); -- GitLab From b1cb7ad2d2ae4ea7c7dbde6c5f15102016e566d0 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 29 Sep 2014 04:44:18 -0300 Subject: [PATCH 2177/9457] [media] sp2: improve debug logging Improve debugging output. Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/sp2.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index 1f4f25004711..320cbe951790 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c @@ -92,6 +92,9 @@ static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len) return -EIO; } + dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n", + client->addr, reg, len, buf); + return 0; } @@ -103,9 +106,6 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs, int mem, ret; int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control; - dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x", - slot, acs, addr, data); - if (slot != 0) return -EINVAL; @@ -140,13 +140,16 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs, if (ret) return ret; - if (read) { - dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x", - addr, mem); + dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x", + (read) ? "read" : "write", slot, addr, + (acs == SP2_CI_ATTR_ACS) ? "attr" : "io", + (read) ? mem : data); + + if (read) return mem; - } else { + else return 0; - } + } int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, -- GitLab From e450de45f4ab9325c8d5d68f3984d6c4d8961d1a Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 29 Sep 2014 04:44:19 -0300 Subject: [PATCH 2178/9457] [media] cx23885: add I2C client for CI into state and handle unregistering If the CI chip has an I2C driver, we need to store I2C client into state. Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 7 +++++++ drivers/media/pci/cx23885/cx23885.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 062854d30a75..5ea1027878ba 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1914,6 +1914,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) struct vb2_dvb_frontend *fe0; struct i2c_client *client; + /* remove I2C client for CI */ + client = port->i2c_client_ci; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + /* remove I2C client for tuner */ client = port->i2c_client_tuner; if (client) { diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 33b1e26847a2..27ea249d07cf 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -297,6 +297,7 @@ struct cx23885_tsport { struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_ci; int (*set_frontend)(struct dvb_frontend *fe); int (*fe_set_voltage)(struct dvb_frontend *fe, -- GitLab From 24e774092fa639823f677f9f69ca0d9f3deb62f6 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sat, 4 Oct 2014 03:59:30 -0300 Subject: [PATCH 2179/9457] [media] cx23855: add CI support for DVBSky T980C Add CI support for DVBSky T980C card. The new host device independent CIMaX SP2 I2C driver was used to implement it. IRQ handling is not implemented at this point. It could be used to detect the CAM insertion/removal instantly. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 106 +++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 5ea1027878ba..757854914781 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -71,6 +71,7 @@ #include "si2165.h" #include "si2168.h" #include "si2157.h" +#include "sp2.h" #include "m88ds3103.h" #include "m88ts2022.h" @@ -616,6 +617,77 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe, return 0; } +static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr, + u8 data, int *mem) +{ + /* MC417 */ + #define SP2_DATA 0x000000ff + #define SP2_WR 0x00008000 + #define SP2_RD 0x00004000 + #define SP2_ACK 0x00001000 + #define SP2_ADHI 0x00000800 + #define SP2_ADLO 0x00000400 + #define SP2_CS1 0x00000200 + #define SP2_CS0 0x00000100 + #define SP2_EN_ALL 0x00001000 + #define SP2_CTRL_OFF (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD) + + struct cx23885_tsport *port = priv; + struct cx23885_dev *dev = port->dev; + int ret; + int tmp; + unsigned long timeout; + + mutex_lock(&dev->gpio_lock); + + /* write addr */ + cx_write(MC417_OEN, SP2_EN_ALL); + cx_write(MC417_RWD, SP2_CTRL_OFF | + SP2_ADLO | (0xff & addr)); + cx_clear(MC417_RWD, SP2_ADLO); + cx_write(MC417_RWD, SP2_CTRL_OFF | + SP2_ADHI | (0xff & (addr >> 8))); + cx_clear(MC417_RWD, SP2_ADHI); + + if (read) + /* data in */ + cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA); + else + /* data out */ + cx_write(MC417_RWD, SP2_CTRL_OFF | data); + + /* chip select 0 */ + cx_clear(MC417_RWD, SP2_CS0); + + /* read/write */ + cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR); + + /* wait for a maximum of 1 msec */ + timeout = jiffies + msecs_to_jiffies(1); + while (!time_after(jiffies, timeout)) { + tmp = cx_read(MC417_RWD); + if ((tmp & SP2_ACK) == 0) + break; + usleep_range(50, 100); + } + + cx_set(MC417_RWD, SP2_CTRL_OFF); + *mem = tmp & 0xff; + + mutex_unlock(&dev->gpio_lock); + + if (!read) { + if (*mem < 0) { + ret = -EREMOTEIO; + goto err; + } + } + + return 0; +err: + return ret; +} + static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *p = &fe->dtv_property_cache; @@ -944,11 +1016,11 @@ static int dvb_register(struct cx23885_tsport *port) struct vb2_dvb_frontend *fe0, *fe1 = NULL; struct si2168_config si2168_config; struct si2157_config si2157_config; + struct sp2_config sp2_config; struct m88ts2022_config m88ts2022_config; struct i2c_board_info info; struct i2c_adapter *adapter; - struct i2c_client *client_demod; - struct i2c_client *client_tuner; + struct i2c_client *client_demod, *client_tuner, *client_ci; int mfe_shared = 0; /* bus not shared by default */ int ret; @@ -1682,6 +1754,7 @@ static int dvb_register(struct cx23885_tsport *port) break; case CX23885_BOARD_DVBSKY_T980C: i2c_bus = &dev->i2c_bus[1]; + i2c_bus2 = &dev->i2c_bus[0]; /* attach frontend */ memset(&si2168_config, 0, sizeof(si2168_config)); @@ -1819,6 +1892,35 @@ static int dvb_register(struct cx23885_tsport *port) case CX23885_BOARD_DVBSKY_T980C: { u8 eeprom[256]; /* 24C02 i2c eeprom */ + /* attach CI */ + memset(&sp2_config, 0, sizeof(sp2_config)); + sp2_config.dvb_adap = &port->frontends.adapter; + sp2_config.priv = port; + sp2_config.ci_control = cx23885_sp2_ci_ctrl; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "sp2", I2C_NAME_SIZE); + info.addr = 0x40; + info.platform_data = &sp2_config; + request_module(info.type); + client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info); + if (client_ci == NULL || + client_ci->dev.driver == NULL) { + module_put(client_tuner->dev.driver->owner); + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + if (!try_module_get(client_ci->dev.driver->owner)) { + i2c_unregister_device(client_ci); + module_put(client_tuner->dev.driver->owner); + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_ci = client_ci; + if (port->nr != 1) break; -- GitLab From 30b771cf8c3120c5c946811ecc5a9b87a34003a2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 15:02:50 +0100 Subject: [PATCH 2180/9457] ALSA: pcm: More kerneldoc updates Add proper kerneldoc comments to the exported functions. Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 160 ++++++++++++++++++++++++++++++++++++++-- sound/core/pcm.c | 15 +++- sound/core/pcm_native.c | 53 +++++++++++++ 3 files changed, 219 insertions(+), 9 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 5c3310d7d4b8..f78a5722f5cc 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -533,6 +533,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) * PCM library */ +/** + * snd_pcm_stream_linked - Check whether the substream is linked with others + * @substream: substream to check + * + * Returns true if the given substream is being linked with others. + */ static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream) { return substream->group != &substream->self_group; @@ -543,6 +549,16 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream); void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream); void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream); unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); + +/** + * snd_pcm_stream_lock_irqsave - Lock the PCM stream + * @substream: PCM substream + * @flags: irq flags + * + * This locks the PCM stream like snd_pcm_stream_lock() but with the local + * IRQ (only when nonatomic is false). In nonatomic case, this is identical + * as snd_pcm_stream_lock(). + */ #define snd_pcm_stream_lock_irqsave(substream, flags) \ do { \ typecheck(unsigned long, flags); \ @@ -551,9 +567,25 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, unsigned long flags); +/** + * snd_pcm_group_for_each_entry - iterate over the linked substreams + * @s: the iterator + * @substream: the substream + * + * Iterate over the all linked substreams to the given @substream. + * When @substream isn't linked with any others, this gives returns @substream + * itself once. + */ #define snd_pcm_group_for_each_entry(s, substream) \ list_for_each_entry(s, &substream->group->substreams, link_list) +/** + * snd_pcm_running - Check whether the substream is in a running state + * @substream: substream to check + * + * Returns true if the given substream is in the state RUNNING, or in the + * state DRAINING for playback. + */ static inline int snd_pcm_running(struct snd_pcm_substream *substream) { return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || @@ -561,45 +593,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); } +/** + * bytes_to_samples - Unit conversion of the size from bytes to samples + * @runtime: PCM runtime instance + * @size: size in bytes + */ static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size) { return size * 8 / runtime->sample_bits; } +/** + * bytes_to_frames - Unit conversion of the size from bytes to frames + * @runtime: PCM runtime instance + * @size: size in bytes + */ static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size) { return size * 8 / runtime->frame_bits; } +/** + * samples_to_bytes - Unit conversion of the size from samples to bytes + * @runtime: PCM runtime instance + * @size: size in samples + */ static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size) { return size * runtime->sample_bits / 8; } +/** + * frames_to_bytes - Unit conversion of the size from frames to bytes + * @runtime: PCM runtime instance + * @size: size in frames + */ static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size) { return size * runtime->frame_bits / 8; } +/** + * frame_aligned - Check whether the byte size is aligned to frames + * @runtime: PCM runtime instance + * @bytes: size in bytes + */ static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) { return bytes % runtime->byte_align == 0; } +/** + * snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes + * @substream: PCM substream + */ static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; return frames_to_bytes(runtime, runtime->buffer_size); } +/** + * snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes + * @substream: PCM substream + */ static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; return frames_to_bytes(runtime, runtime->period_size); } -/* - * result is: 0 ... (boundary - 1) +/** + * snd_pcm_playback_avail - Get the available (writable) space for playback + * @runtime: PCM runtime instance + * + * Result is between 0 ... (boundary - 1) */ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) { @@ -611,8 +679,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r return avail; } -/* - * result is: 0 ... (boundary - 1) +/** + * snd_pcm_playback_avail - Get the available (readable) space for capture + * @runtime: PCM runtime instance + * + * Result is between 0 ... (boundary - 1) */ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime) { @@ -622,11 +693,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru return avail; } +/** + * snd_pcm_playback_hw_avail - Get the queued space for playback + * @runtime: PCM runtime instance + */ static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime) { return runtime->buffer_size - snd_pcm_playback_avail(runtime); } +/** + * snd_pcm_capture_hw_avail - Get the free space for capture + * @runtime: PCM runtime instance + */ static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime) { return runtime->buffer_size - snd_pcm_capture_avail(runtime); @@ -706,6 +785,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream) return snd_pcm_capture_avail(runtime) == 0; } +/** + * snd_pcm_trigger_done - Mark the master substream + * @substream: the pcm substream instance + * @master: the linked master substream + * + * When multiple substreams of the same card are linked and the hardware + * supports the single-shot operation, the driver calls this in the loop + * in snd_pcm_group_for_each_entry() for marking the substream as "done". + * Then most of trigger operations are performed only to the given master + * substream. + * + * The trigger_master mark is cleared at timestamp updates at the end + * of trigger operations. + */ static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, struct snd_pcm_substream *master) { @@ -881,6 +974,14 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, unsigned int rates_b); +/** + * snd_pcm_set_runtime_buffer - Set the PCM runtime buffer + * @substream: PCM substream to set + * @bufp: the buffer information, NULL to clear + * + * Copy the buffer information to runtime->dma_buffer when @bufp is non-NULL. + * Otherwise it clears the current buffer information. + */ static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, struct snd_dma_buffer *bufp) { @@ -906,6 +1007,11 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); void snd_pcm_timer_init(struct snd_pcm_substream *substream); void snd_pcm_timer_done(struct snd_pcm_substream *substream); +/** + * snd_pcm_gettime - Fill the timespec depending on the timestamp mode + * @runtime: PCM runtime instance + * @tv: timespec to fill + */ static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime, struct timespec *tv) { @@ -997,18 +1103,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, #define snd_pcm_sgbuf_ops_page NULL #endif /* SND_DMA_SGBUF */ +/** + * snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset + * @substream: PCM substream + * @ofs: byte offset + */ static inline dma_addr_t snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) { return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs); } +/** + * snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset + * @substream: PCM substream + * @ofs: byte offset + */ static inline void * snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) { return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs); } +/** + * snd_pcm_sgbuf_chunk_size - Compute the max size that fits within the contig. + * page from the given size + * @substream: PCM substream + * @ofs: byte offset + * @size: byte size to examine + */ static inline unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, unsigned int ofs, unsigned int size) @@ -1016,13 +1139,24 @@ snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size); } -/* handle mmap counter - PCM mmap callback should handle this counter properly */ +/** + * snd_pcm_mmap_data_open - increase the mmap counter + * @area: VMA + * + * PCM mmap callback should handle this counter properly + */ static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; atomic_inc(&substream->mmap_count); } +/** + * snd_pcm_mmap_data_close - decrease the mmap counter + * @area: VMA + * + * PCM mmap callback should handle this counter properly + */ static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; @@ -1042,6 +1176,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s #define snd_pcm_lib_mmap_vmalloc NULL +/** + * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer + * @dma: DMA number + * @max: pointer to store the max size + */ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) { *max = dma < 4 ? 64 * 1024 : 128 * 1024; @@ -1094,7 +1233,11 @@ struct snd_pcm_chmap { void *private_data; /* optional: private data pointer */ }; -/* get the PCM substream assigned to the given chmap info */ +/** + * snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info + * @info: chmap information + * @idx: the substream number index + */ static inline struct snd_pcm_substream * snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) { @@ -1121,7 +1264,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, unsigned long private_value, struct snd_pcm_chmap **info_ret); -/* Strong-typed conversion of pcm_format to bitwise */ +/** + * pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise + * @pcm_format: PCM format + */ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) { return 1ULL << (__force int) pcm_format; diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 42ded997b223..31acc3df62cd 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = { FORMAT(DSD_U32_LE), }; +/** + * snd_pcm_format_name - Return a name string for the given PCM format + * @format: PCM format + */ const char *snd_pcm_format_name(snd_pcm_format_t format) { if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) @@ -707,7 +711,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } return 0; } - EXPORT_SYMBOL(snd_pcm_new_stream); static int _snd_pcm_new(struct snd_card *card, const char *id, int device, @@ -1155,6 +1158,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) return 0; } +/** + * snd_pcm_notify - Add/remove the notify list + * @notify: PCM notify list + * @nfree: 0 = register, 1 = unregister + * + * This adds the given notifier to the global list so that the callback is + * called for each registered PCM devices. This exists only for PCM OSS + * emulation, so far. + */ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) { struct snd_pcm *pcm; @@ -1177,7 +1189,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) mutex_unlock(®ister_mutex); return 0; } - EXPORT_SYMBOL(snd_pcm_notify); #ifdef CONFIG_PROC_FS diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 2f7ad10ee7c3..4d5795d8b9f7 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -74,6 +74,14 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); static DEFINE_RWLOCK(snd_pcm_link_rwlock); static DECLARE_RWSEM(snd_pcm_link_rwsem); +/** + * snd_pcm_stream_lock - Lock the PCM stream + * @substream: PCM substream + * + * This locks the PCM stream's spinlock or mutex depending on the nonatomic + * flag of the given substream. This also takes the global link rw lock + * (or rw sem), too, for avoiding the race with linked streams. + */ void snd_pcm_stream_lock(struct snd_pcm_substream *substream) { if (substream->pcm->nonatomic) { @@ -86,6 +94,12 @@ void snd_pcm_stream_lock(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(snd_pcm_stream_lock); +/** + * snd_pcm_stream_lock - Unlock the PCM stream + * @substream: PCM substream + * + * This unlocks the PCM stream that has been locked via snd_pcm_stream_lock(). + */ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) { if (substream->pcm->nonatomic) { @@ -98,6 +112,14 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); +/** + * snd_pcm_stream_lock_irq - Lock the PCM stream + * @substream: PCM substream + * + * This locks the PCM stream like snd_pcm_stream_lock() and disables the local + * IRQ (only when nonatomic is false). In nonatomic case, this is identical + * as snd_pcm_stream_lock(). + */ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) { if (!substream->pcm->nonatomic) @@ -106,6 +128,12 @@ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); +/** + * snd_pcm_stream_unlock_irq - Unlock the PCM stream + * @substream: PCM substream + * + * This is a counter-part of snd_pcm_stream_lock_irq(). + */ void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) { snd_pcm_stream_unlock(substream); @@ -124,6 +152,13 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave); +/** + * snd_pcm_stream_unlock_irqrestore - Unlock the PCM stream + * @substream: PCM substream + * @flags: irq flags + * + * This is a counter-part of snd_pcm_stream_lock_irqsave(). + */ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, unsigned long flags) { @@ -3312,6 +3347,15 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { /* * mmap the DMA buffer on RAM */ + +/** + * snd_pcm_lib_default_mmap - Default PCM data mmap function + * @substream: PCM substream + * @area: VMA + * + * This is the default mmap handler for PCM data. When mmap pcm_ops is NULL, + * this function is invoked implicitly. + */ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *area) { @@ -3343,6 +3387,15 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); * mmap the DMA buffer on I/O memory area */ #if SNDRV_PCM_INFO_MMAP_IOMEM +/** + * snd_pcm_lib_mmap_iomem - Default PCM data mmap function for I/O mem + * @substream: PCM substream + * @area: VMA + * + * When your hardware uses the iomapped pages as the hardware buffer and + * wants to mmap it, pass this function as mmap pcm_ops. Note that this + * is supposed to work only on limited architectures. + */ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area) { -- GitLab From 85926e0fe8b48fe6227614ddc3a1cb41c0a3c51a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 15:06:13 +0100 Subject: [PATCH 2181/9457] ALSA: pcm: Convert params_*() with static inline functions ... and add proper kerneldoc comments. There is no big reason to keep them as macros. Static inline functions are safer in general, and suitable for kerneldoc, too. Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 65 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index f78a5722f5cc..29eb09ef2969 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -841,18 +841,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; } -#define params_channels(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min) -#define params_rate(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_RATE)->min) -#define params_period_size(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min) -#define params_periods(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIODS)->min) -#define params_buffer_size(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min) -#define params_buffer_bytes(p) \ - (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min) +/** + * params_channels - Get the number of channels from the hw params + * @p: hw params + */ +static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min; +} + +/** + * params_channels - Get the sample rate from the hw params + * @p: hw params + */ +static inline unsigned int params_rate(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_RATE)->min; +} + +/** + * params_channels - Get the period size (in frames) from the hw params + * @p: hw params + */ +static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min; +} + +/** + * params_channels - Get the number of periods from the hw params + * @p: hw params + */ +static inline unsigned int params_periods(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIODS)->min; +} + +/** + * params_channels - Get the buffer size (in frames) from the hw params + * @p: hw params + */ +static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min; +} + +/** + * params_channels - Get the buffer size (in bytes) from the hw params + * @p: hw params + */ +static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p) +{ + return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min; +} int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); -- GitLab From eb9c38d54c9cad72101dfe7fefe4a784dd67da86 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 15:19:43 +0100 Subject: [PATCH 2182/9457] ALSA: doc: More kerneldoc comments on core components Some functions missed the proper kerneldoc comments. Signed-off-by: Takashi Iwai --- sound/core/init.c | 33 ++++++++++++++++++++++----------- sound/core/sound.c | 9 +++++++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/sound/core/init.c b/sound/core/init.c index 7bdfd19e24a8..074875d68c15 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card) EXPORT_SYMBOL(snd_card_disconnect); -/** - * snd_card_free - frees given soundcard structure - * @card: soundcard structure - * - * This function releases the soundcard structure and the all assigned - * devices automatically. That is, you don't have to release the devices - * by yourself. - * - * Return: Zero. Frees all associated devices and frees the control - * interface associated to given soundcard. - */ static int snd_card_do_free(struct snd_card *card) { #if IS_ENABLED(CONFIG_SND_MIXER_OSS) @@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card) return 0; } +/** + * snd_card_free_when_closed - Disconnect the card, free it later eventually + * @card: soundcard structure + * + * Unlike snd_card_free(), this function doesn't try to release the card + * resource immediately, but tries to disconnect at first. When the card + * is still in use, the function returns before freeing the resources. + * The card resources will be freed when the refcount gets to zero. + */ int snd_card_free_when_closed(struct snd_card *card) { int ret = snd_card_disconnect(card); @@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card) } EXPORT_SYMBOL(snd_card_free_when_closed); +/** + * snd_card_free - frees given soundcard structure + * @card: soundcard structure + * + * This function releases the soundcard structure and the all assigned + * devices automatically. That is, you don't have to release the devices + * by yourself. + * + * This function waits until the all resources are properly released. + * + * Return: Zero. Frees all associated devices and frees the control + * interface associated to given soundcard. + */ int snd_card_free(struct snd_card *card) { struct completion released; diff --git a/sound/core/sound.c b/sound/core/sound.c index 38ad1a0dd3f7..f1333060bf1c 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -355,8 +355,13 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) EXPORT_SYMBOL(snd_unregister_device); -/* get the assigned device to the given type and device number; - * the caller needs to release it via put_device() after using it +/** + * snd_get_device - get the assigned device to the given type and device number + * @type: the device type, SNDRV_DEVICE_TYPE_XXX + * @card:the card instance + * @dev: the device index + * + * The caller needs to release it via put_device() after using it. */ struct device *snd_get_device(int type, struct snd_card *card, int dev) { -- GitLab From 67faa6ebd7fc0a811f6c1f3e3c113571953489ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 30 Oct 2014 15:37:37 +0100 Subject: [PATCH 2183/9457] ALSA: doc: Fix missing "I" for kerneldoc inclusion Fixes: 90446d0746c3 ('ALSA: doc: Add missing headers and compress stuff to alsa-driver-api.tmpl') Signed-off-by: Takashi Iwai --- Documentation/DocBook/alsa-driver-api.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl index b2d2c3b74fb0..71f9246127ec 100644 --- a/Documentation/DocBook/alsa-driver-api.tmpl +++ b/Documentation/DocBook/alsa-driver-api.tmpl @@ -57,7 +57,7 @@ !Esound/core/pcm.c !Esound/core/pcm_lib.c !Esound/core/pcm_native.c -!include/sound/pcm.h +!Iinclude/sound/pcm.h PCM Format Helpers !Esound/core/pcm_misc.c -- GitLab From fdaaf6d6609b0ddb65cd3211cc7ceb892d7a2550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 21 Oct 2014 11:40:45 +0200 Subject: [PATCH 2184/9457] pinctrl: mxs: warn if functions are not grouped by name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mxs pinctrl driver cannot handle when functions are not grouped by name (which IMO is a bug). This happens for example if a imx28-somemachine.dts provides a function that has the same name as a function defined in imx28.dtsi. The proper way to fix that would be to check for duplicates in the loops (which increases parsing time) or parse the groups first and sort the resulting array. Signed-off-by: Uwe Kleine-König Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-mxs.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index f98c6bb0f769..646d5c244af1 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -445,6 +445,31 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev, if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { + struct device_node *child2; + + /* + * This reference is dropped by + * of_get_next_child(np, * child) + */ + of_node_get(child); + + /* + * The logic parsing the functions from dt currently + * doesn't handle if functions with the same name are + * not grouped together. Only the first contiguous + * cluster is usable for each function name. This is a + * bug that is not trivial to fix, but at least warn + * about it. + */ + for (child2 = of_get_next_child(np, child); + child2 != NULL; + child2 = of_get_next_child(np, child2)) { + if (!strcmp(child2->name, fn)) + dev_warn(&pdev->dev, + "function nodes must be grouped by name (failed for: %s)", + fn); + } + f = &soc->functions[idxf++]; f->name = fn = child->name; } -- GitLab From 4f6bd5cfc6c8f2e8c2c38fdfea8e32f9a463cdbb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 28 Oct 2014 22:41:26 +0100 Subject: [PATCH 2185/9457] pinctrl: sunxi: Add PN bank base pin The A80 R-PIO controller has one more bank that what we've seen so far, add the PN pin bank. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index 4245b96c7996..5a51523a3459 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -27,6 +27,7 @@ #define PI_BASE 256 #define PL_BASE 352 #define PM_BASE 384 +#define PN_BASE 416 #define SUNXI_PINCTRL_PIN(bank, pin) \ PINCTRL_PIN(P ## bank ## _BASE + (pin), "P" #bank #pin) -- GitLab From d5e9fb31baa2b1fd6d2043c748e6ff9313dfa8b5 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 28 Oct 2014 22:41:27 +0100 Subject: [PATCH 2186/9457] pinctrl: sunxi: Add A80 pinctrl muxing options The A80 has a rather usual pin controller, the only thing out of the ordinary being that it has 5 interrupts banks, and that some pins have several options for the same functions. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/Kconfig | 4 + drivers/pinctrl/sunxi/Makefile | 1 + drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c | 749 ++++++++++++++++++++++ 3 files changed, 754 insertions(+) create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index a5e10f777ed2..230a952608cb 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -39,4 +39,8 @@ config PINCTRL_SUN8I_A23_R depends on RESET_CONTROLLER select PINCTRL_SUNXI_COMMON +config PINCTRL_SUN9I_A80 + def_bool MACH_SUN9I + select PINCTRL_SUNXI_COMMON + endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile index e797efb02901..c7d92e4673b5 100644 --- a/drivers/pinctrl/sunxi/Makefile +++ b/drivers/pinctrl/sunxi/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o +obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o diff --git a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c new file mode 100644 index 000000000000..adb29422efc9 --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c @@ -0,0 +1,749 @@ +/* + * Allwinner A80 SoCs pinctrl driver. + * + * Copyright (C) 2014 Maxime Ripard + * + * Maxime Ripard + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-sunxi.h" + +static const struct sunxi_desc_pin sun9i_a80_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */ + SUNXI_FUNCTION(0x4, "uart1"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */ + SUNXI_FUNCTION(0x4, "uart1"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */ + SUNXI_FUNCTION(0x4, "uart1"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */ + SUNXI_FUNCTION(0x4, "uart1"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXCK */ + SUNXI_FUNCTION(0x4, "uart1"), /* DTR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXCTL */ + SUNXI_FUNCTION(0x4, "uart1"), /* DSR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */ + SUNXI_FUNCTION(0x4, "uart1"), /* DCD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */ + SUNXI_FUNCTION(0x4, "uart1"), /* RING */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */ + SUNXI_FUNCTION(0x4, "eclk"), /* IN0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */ + SUNXI_FUNCTION(0x4, "eclk"), /* IN1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */ + SUNXI_FUNCTION(0x4, "clk_out_a"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* MII-CRS */ + SUNXI_FUNCTION(0x4, "clk_out_b"), + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* TXCK */ + SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_P */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-TXCK / GMII-TXEN */ + SUNXI_FUNCTION(0x4, "pwm3"), /* PWM_N */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* MII-TXERR */ + SUNXI_FUNCTION(0x4, "spi1"), /* CS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* RGMII-CLKIN / MII-COL */ + SUNXI_FUNCTION(0x4, "spi1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* EMDC */ + SUNXI_FUNCTION(0x4, "spi1"), /* MOSI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "gmac"), /* EMDIO */ + SUNXI_FUNCTION(0x4, "spi1"), /* MISO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "uart3"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "uart3"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "mcsi"), /* MCLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PB_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "mcsi"), /* SCK */ + SUNXI_FUNCTION(0x4, "i2c4"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PB_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "mcsi"), /* SDA */ + SUNXI_FUNCTION(0x4, "i2c4"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PB_EINT16 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* WE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* ALE */ + SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CLE */ + SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* CE1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0")), /* RE */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* RB1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ + SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ + SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CE2 */ + SUNXI_FUNCTION(0x3, "nand0_b")), /* RE */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "nand0"), /* CE3 */ + SUNXI_FUNCTION(0x3, "nand0_b")), /* DQS */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "spi0")), /* CS0 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D0 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D1 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */ + SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VPC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VP3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */ + SUNXI_FUNCTION(0x3, "lvds1")), /* VN3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D20 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D21 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D22 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* D23 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* CLK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* DE */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* HSYNC */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "lcd0")), /* VSYNC */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* PCLK */ + SUNXI_FUNCTION(0x3, "ts"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* MCLK */ + SUNXI_FUNCTION(0x3, "ts"), /* ERR */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */ + SUNXI_FUNCTION(0x3, "ts"), /* SYNC */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */ + SUNXI_FUNCTION(0x3, "ts"), /* DVLD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D0 */ + SUNXI_FUNCTION(0x3, "spi2"), /* CS0 */ + SUNXI_FUNCTION(0x4, "uart5"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D1 */ + SUNXI_FUNCTION(0x3, "spi2"), /* CLK */ + SUNXI_FUNCTION(0x4, "uart5"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D2 */ + SUNXI_FUNCTION(0x3, "spi2"), /* MOSI */ + SUNXI_FUNCTION(0x4, "uart5"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D3 */ + SUNXI_FUNCTION(0x3, "spi2"), /* MISO */ + SUNXI_FUNCTION(0x4, "uart5"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D4 */ + SUNXI_FUNCTION(0x3, "ts"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D5 */ + SUNXI_FUNCTION(0x3, "ts"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D6 */ + SUNXI_FUNCTION(0x3, "ts"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D7 */ + SUNXI_FUNCTION(0x3, "ts"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D8 */ + SUNXI_FUNCTION(0x3, "ts"), /* D4 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D9 */ + SUNXI_FUNCTION(0x3, "ts"), /* D5 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D10 */ + SUNXI_FUNCTION(0x3, "ts"), /* D6 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* D11 */ + SUNXI_FUNCTION(0x3, "ts"), /* D7 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* SCK */ + SUNXI_FUNCTION(0x3, "i2c4"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "csi"), /* SDA */ + SUNXI_FUNCTION(0x3, "i2c4"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)), /* PE_EINT17 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0")), /* D1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0")), /* D0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ + SUNXI_FUNCTION(0x4, "uart0")), /* TX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0")), /* CMD */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ + SUNXI_FUNCTION(0x4, "uart0")), /* RX */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc0")), /* D2 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* TX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* RX */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* RTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart4"), /* CTS */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */ + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SCK */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "i2c2")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "pwm0")), + + /* Hole */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "pwm1"), /* Positive */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 8)), /* PH_EINT8 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "pwm1"), /* Negative */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 9)), /* PH_EINT9 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "pwm2"), /* Positive */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 10)), /* PH_EINT10 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x3, "pwm2"), /* Negative */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 11)), /* PH_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 12), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart0"), /* TX */ + SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 12)), /* PH_EINT12 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 13), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "uart0"), /* RX */ + SUNXI_FUNCTION(0x3, "spi3"), /* CS2 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 13)), /* PH_EINT13 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 14), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi3"), /* CLK */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 14)), /* PH_EINT14 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 15), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi3"), /* MOSI */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 15)), /* PH_EINT15 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 16), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi3"), /* MISO */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 16)), /* PH_EINT16 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi3"), /* CS0 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 17)), /* PH_EINT17 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "spi3"), /* CS1 */ + SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 18)), /* PH_EINT18 */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "hdmi")), /* SCL */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 20), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "hdmi")), /* SDA */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 21), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), + SUNXI_FUNCTION(0x2, "hdmi")), /* CEC */ +}; + +static const struct sunxi_pinctrl_desc sun9i_a80_pinctrl_data = { + .pins = sun9i_a80_pins, + .npins = ARRAY_SIZE(sun9i_a80_pins), + .irq_banks = 5, +}; + +static int sun9i_a80_pinctrl_probe(struct platform_device *pdev) +{ + return sunxi_pinctrl_init(pdev, + &sun9i_a80_pinctrl_data); +} + +static struct of_device_id sun9i_a80_pinctrl_match[] = { + { .compatible = "allwinner,sun9i-a80-pinctrl", }, + {} +}; +MODULE_DEVICE_TABLE(of, sun9i_a80_pinctrl_match); + +static struct platform_driver sun9i_a80_pinctrl_driver = { + .probe = sun9i_a80_pinctrl_probe, + .driver = { + .name = "sun9i-a80-pinctrl", + .of_match_table = sun9i_a80_pinctrl_match, + }, +}; +module_platform_driver(sun9i_a80_pinctrl_driver); + +MODULE_AUTHOR("Maxime Ripard "); +MODULE_DESCRIPTION("Allwinner A80 pinctrl driver"); +MODULE_LICENSE("GPL"); -- GitLab From bd1dbc3b9d20f9fe43d7b06848fc821bc88124c3 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 24 Oct 2014 15:29:57 +0100 Subject: [PATCH 2187/9457] gpio: msm-v1: Fix typo in function argument irq_set_irq_wake() treats its second argument as a boolean. It is much easier to read code when constant booleans are either 0 or 1! This particular line of code distracted me somewhat when I was doing a bit of work in a code browser since it (spuriously) got me worried that I had misunderstood how irq_set_irq_wake() worked. Signed-off-by: Daniel Thompson Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-msm-v1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index 73b73969d361..997e61ef173c 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c @@ -686,7 +686,7 @@ static int gpio_msm_v1_probe(struct platform_device *pdev) irq_set_chained_handler(irq1, msm_gpio_irq_handler); irq_set_chained_handler(irq2, msm_gpio_irq_handler); irq_set_irq_wake(irq1, 1); - irq_set_irq_wake(irq2, 2); + irq_set_irq_wake(irq2, 1); return 0; } -- GitLab From 0c26ed1c07f13ca27e2638ffdd1951013ed96c48 Mon Sep 17 00:00:00 2001 From: Marcelo Leitner Date: Wed, 29 Oct 2014 10:04:51 -0200 Subject: [PATCH 2188/9457] netfilter: nf_log: Introduce nft_log_dereference() macro Wrap up a common call pattern in an easier to handle call. Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_log.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index d7197649dba6..5eaf047ed37f 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -19,6 +19,9 @@ static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly; static DEFINE_MUTEX(nf_log_mutex); +#define nft_log_dereference(logger) \ + rcu_dereference_protected(logger, lockdep_is_held(&nf_log_mutex)) + static struct nf_logger *__find_logger(int pf, const char *str_logger) { struct nf_logger *log; @@ -28,8 +31,7 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger) if (loggers[pf][i] == NULL) continue; - log = rcu_dereference_protected(loggers[pf][i], - lockdep_is_held(&nf_log_mutex)); + log = nft_log_dereference(loggers[pf][i]); if (!strncasecmp(str_logger, log->name, strlen(log->name))) return log; } @@ -45,8 +47,7 @@ void nf_log_set(struct net *net, u_int8_t pf, const struct nf_logger *logger) return; mutex_lock(&nf_log_mutex); - log = rcu_dereference_protected(net->nf.nf_loggers[pf], - lockdep_is_held(&nf_log_mutex)); + log = nft_log_dereference(net->nf.nf_loggers[pf]); if (log == NULL) rcu_assign_pointer(net->nf.nf_loggers[pf], logger); @@ -61,8 +62,7 @@ void nf_log_unset(struct net *net, const struct nf_logger *logger) mutex_lock(&nf_log_mutex); for (i = 0; i < NFPROTO_NUMPROTO; i++) { - log = rcu_dereference_protected(net->nf.nf_loggers[i], - lockdep_is_held(&nf_log_mutex)); + log = nft_log_dereference(net->nf.nf_loggers[i]); if (log == logger) RCU_INIT_POINTER(net->nf.nf_loggers[i], NULL); } @@ -297,8 +297,7 @@ static int seq_show(struct seq_file *s, void *v) int i, ret; struct net *net = seq_file_net(s); - logger = rcu_dereference_protected(net->nf.nf_loggers[*pos], - lockdep_is_held(&nf_log_mutex)); + logger = nft_log_dereference(net->nf.nf_loggers[*pos]); if (!logger) ret = seq_printf(s, "%2lld NONE (", *pos); @@ -312,8 +311,7 @@ static int seq_show(struct seq_file *s, void *v) if (loggers[*pos][i] == NULL) continue; - logger = rcu_dereference_protected(loggers[*pos][i], - lockdep_is_held(&nf_log_mutex)); + logger = nft_log_dereference(loggers[*pos][i]); ret = seq_printf(s, "%s", logger->name); if (ret < 0) return ret; @@ -385,8 +383,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write, mutex_unlock(&nf_log_mutex); } else { mutex_lock(&nf_log_mutex); - logger = rcu_dereference_protected(net->nf.nf_loggers[tindex], - lockdep_is_held(&nf_log_mutex)); + logger = nft_log_dereference(net->nf.nf_loggers[tindex]); if (!logger) table->data = "NONE"; else -- GitLab From 2071d0968e564b4b4a11d36dc58de6e57188edd4 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Wed, 29 Oct 2014 17:13:14 +0900 Subject: [PATCH 2189/9457] Documentation: gpio: guidelines for bindings Now that ACPI supports named GPIO properties, either through ACPI 5.1 or the per-driver ACPI GPIO mappings, we can be more narrow about the way GPIOs should be specified in Device Tree bindings. This patch updates the GPIO DT bindings documentation to highlight the following rules for new GPIO bindings: - All new bindings must have a meaningful name (e.g. the "gpios" property must not be used) - The only suffix allowed is "-gpios", no matter the number of descriptors in the property - GPIOs can only be grouped under the same property when they serve the same purpose, a case that should remain exceptional (e.g. bit-banged data lines). Signed-off-by: Alexandre Courbot Cc: Rafael J. Wysocki Acked-by: Arnd Bergmann Reviewed-by: Mika Westerberg Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/gpio.txt | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index 3fb8f53071b8..b9bd1d64cfa6 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt @@ -13,13 +13,22 @@ properties, each containing a 'gpio-list': gpio-specifier : Array of #gpio-cells specifying specific gpio (controller specific) -GPIO properties should be named "[-]gpios". The exact -meaning of each gpios property must be documented in the device tree -binding for each device. +GPIO properties should be named "[-]gpios", with being the purpose +of this GPIO for the device. While a non-existent is considered valid +for compatibility reasons (resolving to the "gpios" property), it is not allowed +for new bindings. -For example, the following could be used to describe GPIO pins used -as chip select lines; with chip selects 0, 1 and 3 populated, and chip -select 2 left empty: +GPIO properties can contain one or more GPIO phandles, but only in exceptional +cases should they contain more than one. If your device uses several GPIOs with +distinct functions, reference each of them under its own property, giving it a +meaningful name. The only case where an array of GPIOs is accepted is when +several GPIOs serve the same function (e.g. a parallel data line). + +The exact purpose of each gpios property must be documented in the device tree +binding of the device. + +The following example could be used to describe GPIO pins used as device enable +and bit-banged data signals: gpio1: gpio1 { gpio-controller @@ -30,10 +39,12 @@ select 2 left empty: #gpio-cells = <1>; }; [...] - chipsel-gpios = <&gpio1 12 0>, - <&gpio1 13 0>, - <0>, /* holes are permitted, means no GPIO 2 */ - <&gpio2 2>; + + enable-gpios = <&gpio2 2>; + data-gpios = <&gpio1 12 0>, + <&gpio1 13 0>, + <&gpio1 14 0>, + <&gpio1 15 0>; Note that gpio-specifier length is controller dependent. In the above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2 @@ -42,16 +53,17 @@ only uses one. gpio-specifier may encode: bank, pin position inside the bank, whether pin is open-drain and whether pin is logically inverted. Exact meaning of each specifier cell is controller specific, and must -be documented in the device tree binding for the device. +be documented in the device tree binding for the device. Use the macros +defined in include/dt-bindings/gpio/gpio.h whenever possible: Example of a node using GPIOs: node { - gpios = <&qe_pio_e 18 0>; + enable-gpios = <&qe_pio_e 18 GPIO_ACTIVE_HIGH>; }; -In this example gpio-specifier is "18 0" and encodes GPIO pin number, -and GPIO flags as accepted by the "qe_pio_e" gpio-controller. +GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes +GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller. 1.1) GPIO specifier best practices ---------------------------------- -- GitLab From 8ac2bde2a4a05c38e2bd733bea94507cb1461e06 Mon Sep 17 00:00:00 2001 From: Marcelo Leitner Date: Wed, 29 Oct 2014 10:51:13 -0200 Subject: [PATCH 2190/9457] netfilter: log: protect nf_log_register against double registering Currently, despite the comment right before the function, nf_log_register allows registering two loggers on with the same type and end up overwriting the previous register. Not a real issue today as current tree doesn't have two loggers for the same type but it's better to get this protected. Also make sure that all of its callers do error checking. Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/nf_log_arp.c | 12 +++++++++++- net/ipv4/netfilter/nf_log_ipv4.c | 12 +++++++++++- net/ipv6/netfilter/nf_log_ipv6.c | 12 +++++++++++- net/netfilter/nf_log.c | 16 +++++++++++++--- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c index ccfc78db12ee..0c8799a0c9e4 100644 --- a/net/ipv4/netfilter/nf_log_arp.c +++ b/net/ipv4/netfilter/nf_log_arp.c @@ -10,6 +10,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -130,8 +131,17 @@ static int __init nf_log_arp_init(void) if (ret < 0) return ret; - nf_log_register(NFPROTO_ARP, &nf_arp_logger); + ret = nf_log_register(NFPROTO_ARP, &nf_arp_logger); + if (ret < 0) { + pr_err("failed to register logger\n"); + goto err1; + } + return 0; + +err1: + unregister_pernet_subsys(&nf_log_arp_net_ops); + return ret; } static void __exit nf_log_arp_exit(void) diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c index 078bdca1b607..75101980eeee 100644 --- a/net/ipv4/netfilter/nf_log_ipv4.c +++ b/net/ipv4/netfilter/nf_log_ipv4.c @@ -5,6 +5,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -366,8 +367,17 @@ static int __init nf_log_ipv4_init(void) if (ret < 0) return ret; - nf_log_register(NFPROTO_IPV4, &nf_ip_logger); + ret = nf_log_register(NFPROTO_IPV4, &nf_ip_logger); + if (ret < 0) { + pr_err("failed to register logger\n"); + goto err1; + } + return 0; + +err1: + unregister_pernet_subsys(&nf_log_ipv4_net_ops); + return ret; } static void __exit nf_log_ipv4_exit(void) diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c index 7b17a0be93e7..7fc34d1681a1 100644 --- a/net/ipv6/netfilter/nf_log_ipv6.c +++ b/net/ipv6/netfilter/nf_log_ipv6.c @@ -5,6 +5,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -398,8 +399,17 @@ static int __init nf_log_ipv6_init(void) if (ret < 0) return ret; - nf_log_register(NFPROTO_IPV6, &nf_ip6_logger); + ret = nf_log_register(NFPROTO_IPV6, &nf_ip6_logger); + if (ret < 0) { + pr_err("failed to register logger\n"); + goto err1; + } + return 0; + +err1: + unregister_pernet_subsys(&nf_log_ipv6_net_ops); + return ret; } static void __exit nf_log_ipv6_exit(void) diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 5eaf047ed37f..9562e393fdf7 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -75,6 +75,7 @@ EXPORT_SYMBOL(nf_log_unset); int nf_log_register(u_int8_t pf, struct nf_logger *logger) { int i; + int ret = 0; if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers)) return -EINVAL; @@ -82,16 +83,25 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger) mutex_lock(&nf_log_mutex); if (pf == NFPROTO_UNSPEC) { + for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) { + if (rcu_access_pointer(loggers[i][logger->type])) { + ret = -EEXIST; + goto unlock; + } + } for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) rcu_assign_pointer(loggers[i][logger->type], logger); } else { - /* register at end of list to honor first register win */ + if (rcu_access_pointer(loggers[pf][logger->type])) { + ret = -EEXIST; + goto unlock; + } rcu_assign_pointer(loggers[pf][logger->type], logger); } +unlock: mutex_unlock(&nf_log_mutex); - - return 0; + return ret; } EXPORT_SYMBOL(nf_log_register); -- GitLab From b891f62fcd28a46ab0818cd9acbb5bbb20542ab6 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 30 Oct 2014 14:34:00 +0000 Subject: [PATCH 2191/9457] ASoC: Intel: Add debug output when boot fails. Add the debug output from IPCD and IPCX when booting fails. Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index b37d3ee20dba..0ea7c3dcc071 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1927,7 +1927,9 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw) ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, msecs_to_jiffies(IPC_BOOT_MSECS)); if (ret == 0) { - dev_err(hsw->dev, "error: audio DSP boot timeout\n"); + dev_err(hsw->dev, "error: audio DSP boot timeout IPCD 0x%x IPCX 0x%x\n", + sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCD), + sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX)); return -EIO; } @@ -2038,7 +2040,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) msecs_to_jiffies(IPC_BOOT_MSECS)); if (ret == 0) { ret = -EIO; - dev_err(hsw->dev, "error: ADSP boot timeout\n"); + dev_err(hsw->dev, "error: audio DSP boot timeout IPCD 0x%x IPCX 0x%x\n", + sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCD), + sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX)); goto boot_err; } -- GitLab From 35e03a884c41b8fecf77e20de89759deb7c9078a Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 30 Oct 2014 14:58:19 +0000 Subject: [PATCH 2192/9457] ASoC: Intel: fix build with runtime PM disabled. Fix the following errors: All error/warnings: >> sound/soc/intel/sst-haswell-pcm.c:1168:13: error: 'hsw_pcm_prepare' undeclared here (not in a function) .prepare = hsw_pcm_prepare, ^ >> sound/soc/intel/sst-haswell-pcm.c:1169:14: error: 'hsw_pcm_complete' undeclared here (not in a function) .complete = hsw_pcm_complete, ^ Reported-by: kbuild test robot Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 2 +- sound/soc/intel/sst-haswell-pcm.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 0ea7c3dcc071..ffd5728d55c3 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1711,7 +1711,7 @@ void sst_hsw_runtime_module_free(struct sst_module_runtime *runtime) sst_module_runtime_free(runtime); } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int sst_hsw_dx_state_dump(struct sst_hsw *hsw) { struct sst_dsp *sst = hsw->dsp; diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 4489a35e691e..cd54dd9967af 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -1058,6 +1058,12 @@ static int hsw_pcm_runtime_resume(struct device *dev) return ret; } +#else +#define hsw_pcm_runtime_idle NULL +#define hsw_pcm_runtime_suspend NULL +#define hsw_pcm_runtime_resume NULL +#endif + static void hsw_pcm_complete(struct device *dev) { struct hsw_priv_data *pdata = dev_get_drvdata(dev); @@ -1153,14 +1159,6 @@ static int hsw_pcm_prepare(struct device *dev) return 0; } -#else -#define hsw_pcm_runtime_idle NULL -#define hsw_pcm_runtime_suspend NULL -#define hsw_pcm_runtime_resume NULL -#define hsw_pcm_runtime_complete NULL -#define hsw_pcm_runtime_prepare NULL -#endif - static const struct dev_pm_ops hsw_pcm_pm = { .runtime_idle = hsw_pcm_runtime_idle, .runtime_suspend = hsw_pcm_runtime_suspend, -- GitLab From daac197ca9966eca3a6b07600e579756a9a1d447 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 19:10:57 +0300 Subject: [PATCH 2193/9457] Bluetooth: 6lowpan: use after free in disconnect_devices() This was accidentally changed from list_for_each_entry_safe() to list_for_each_entry() so now it has a use after free bug. I've changed it back. Fixes: 90305829635d ('Bluetooth: 6lowpan: Converting rwlocks to use RCU') Signed-off-by: Dan Carpenter Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 7254bddaca2f..eef298d17452 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -1383,7 +1383,7 @@ static const struct file_operations lowpan_control_fops = { static void disconnect_devices(void) { - struct lowpan_dev *entry, *new_dev; + struct lowpan_dev *entry, *tmp, *new_dev; struct list_head devices; INIT_LIST_HEAD(&devices); @@ -1408,7 +1408,7 @@ static void disconnect_devices(void) rcu_read_unlock(); - list_for_each_entry(entry, &devices, list) { + list_for_each_entry_safe(entry, tmp, &devices, list) { ifdown(entry->netdev); BT_DBG("Unregistering netdev %s %p", entry->netdev->name, entry->netdev); -- GitLab From 01cfa0a4ed82132abb6dc7bcb126eaf499cb8af0 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 29 Oct 2014 22:57:19 -0700 Subject: [PATCH 2194/9457] netfilter: fix spelling errors Signed-off-by: Stephen Hemminger Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_helper.c | 2 +- net/netfilter/nf_tables_api.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 5b3eae7d4c9a..bd9d31537905 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -250,7 +250,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, } EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper); -/* appropiate ct lock protecting must be taken by caller */ +/* appropriate ct lock protecting must be taken by caller */ static inline int unhelp(struct nf_conntrack_tuple_hash *i, const struct nf_conntrack_helper *me) { diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 65eb2a1160d5..1ffb253c6a77 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2477,7 +2477,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb, const struct nfgenmsg *nfmsg = nlmsg_data(nlh); int err; - /* Verify existance before starting dump */ + /* Verify existence before starting dump */ err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla); if (err < 0) return err; -- GitLab From a4d5504d5c39cc84f1f828e19967595597a8136e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Oct 2014 23:37:53 +0100 Subject: [PATCH 2195/9457] Bluetooth: Clear LE white list when resetting controller The internal representation of the LE white list needs to be cleared when receiving a successful HCI_Reset command. A reset of the controller is expected to start with an empty LE white list. When the LE white list is not cleared on controller reset, the passive background scanning might skip programming the remote devices. Only changes to the LE white list are programmed when passive background is started. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org # 3.17.x --- net/bluetooth/hci_event.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f5704bae67a2..aa152140c3e2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -205,6 +205,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) hdev->le_scan_type = LE_SCAN_PASSIVE; hdev->ssp_debug_mode = 0; + + hci_bdaddr_list_clear(&hdev->le_white_list); } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) -- GitLab From 0d2135ecadb0b2eec5338a7587ba29724ddf612b Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Thu, 30 Oct 2014 22:57:58 +0800 Subject: [PATCH 2196/9457] ASoC: Intel: Work around to fix HW D3 potential crash issue When using clock gatings to save power, there are some known issues: 1. core clock gating (DCLCGE) must be disabled during D0 and D3 entry and updating SRAM banks (VDRTCTL0). 2. DSP trunk clock gating (DTCGE) can cause FW crashes, disable it in D0. To align with the new W/A flow from FW team, we must set VDRTCTL0.D3PGD to 1 (D3 power gating disabled) at first startup and keep it all the time. ADSP will be in D0 on first boot by BIOS part of WA. Required delays must be preserved (waiting for HW to stabilize, after enabling CCG, changing SRAM PG, D3PG). D3->D0: 1. Disable core clock gating (VDRTCTL2.DCLCGE = 0) 2. Enable other CG apart from DTCG and DCLCG (VDRTCTL2. DCLCGE and DTCGE = 0) 3. Disable D3PG (VDRTCTL0.D3PGD = 1) 4. Power up necessary SRAM and wait at least for 18 clock cycles for every bank you have powered up 5. Set D0 state(PMCS.PS = 0), wait for HW 6. Restore MCLK (clkctl.smos, disabled in D3 entry point 4) 7. Stall and reset core, set CSR 8. Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us 9. Unreset core 10.Load FW, configure PLL and other necessary things 11.Unstall core Changing SRAM PG during D0: 1. Disable core clock gating (VDRTCTL2.DCLCGE = 0) 2. Set PG mask 3. Wait at least for 18 clock cycles for every bank you have powered up 4. Enable core clock gating, delay 50 us D0->D3: 1. Disable core clock gating (DCLCGE = 0) 2. Stall and reset core 3. Power down entire SRAM and wait at least for 18 clock cycles for every bank (Enable SRAM PG (ISRAMPGE = 0x3FF, DSRAMPGE = 0xFFFFF, D3SRAMPGD = 0), remember about preserving VDRTCTL0.D3PGD = 1) 4. Shutdown PLL, disable MCLK(clkctl.smos = 0), Enable DTCG to save power 5. Set D3 state(PMCS.PS = 3), delay 50 us 6. Enable core clock gating, delay 50 us Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-dsp.h | 14 ++-- sound/soc/intel/sst-haswell-dsp.c | 102 ++++++++++++++++++++++++++---- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/sst-dsp.h index 2753b85ac863..f291e32f0077 100644 --- a/sound/soc/intel/sst-dsp.h +++ b/sound/soc/intel/sst-dsp.h @@ -159,12 +159,18 @@ #define SST_VDRTCTL3 0xaC /* VDRTCTL0 */ -#define SST_VDRTCL0_APLLSE_MASK 1 -#define SST_VDRTCL0_DSRAMPGE_SHIFT 16 -#define SST_VDRTCL0_DSRAMPGE_MASK (0xffff << SST_VDRTCL0_DSRAMPGE_SHIFT) -#define SST_VDRTCL0_ISRAMPGE_SHIFT 6 +#define SST_VDRTCL0_D3PGD (1 << 0) +#define SST_VDRTCL0_D3SRAMPGD (1 << 1) +#define SST_VDRTCL0_DSRAMPGE_SHIFT 12 +#define SST_VDRTCL0_DSRAMPGE_MASK (0xfffff << SST_VDRTCL0_DSRAMPGE_SHIFT) +#define SST_VDRTCL0_ISRAMPGE_SHIFT 2 #define SST_VDRTCL0_ISRAMPGE_MASK (0x3ff << SST_VDRTCL0_ISRAMPGE_SHIFT) +/* VDRTCTL2 */ +#define SST_VDRTCL2_DCLCGE (1 << 1) +#define SST_VDRTCL2_DTCGE (1 << 10) +#define SST_VDRTCL2_APLLSE_MASK (1 << 31) + /* PMCS */ #define SST_PMCS 0x84 #define SST_PMCS_PS_MASK 0x3 diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 86aea343bfec..57039b00efc2 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c @@ -250,17 +250,42 @@ static irqreturn_t hsw_irq(int irq, void *context) static void hsw_set_dsp_D3(struct sst_dsp *sst) { u32 val; + u32 reg; + + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); - /* switch off audio PLL, DRAM & IRAM blocks */ + /* enable power gating and switch off DRAM & IRAM blocks */ val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - val |= SST_VDRTCL0_APLLSE_MASK | SST_VDRTCL0_DSRAMPGE_MASK | + val |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; + val &= ~(SST_VDRTCL0_D3PGD | SST_VDRTCL0_D3SRAMPGD); writel(val, sst->addr.pci_cfg + SST_VDRTCTL0); - /* Set D3 state */ + /* switch off audio PLL */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val |= SST_VDRTCL2_APLLSE_MASK; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); + + /* disable MCLK(clkctl.smos = 0) */ + sst_dsp_shim_update_bits_unlocked(sst, SST_CLKCTL, + SST_CLKCTL_MASK, 0); + + /* Set D3 state, delay 50 us */ val = readl(sst->addr.pci_cfg + SST_PMCS); val |= SST_PMCS_PS_MASK; writel(val, sst->addr.pci_cfg + SST_PMCS); + udelay(50); + + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + + udelay(50); + } static void hsw_reset(struct sst_dsp *sst) @@ -283,6 +308,16 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) int tries = 10; u32 reg; + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + reg &= ~(SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE); + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + + /* Disable D3PG (VDRTCTL0.D3PGD = 1) */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_D3PGD; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); + /* Set D0 state */ reg = readl(sst->addr.pci_cfg + SST_PMCS); reg &= ~SST_PMCS_PS_MASK; @@ -300,14 +335,6 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) return -ENODEV; finish: - hsw_reset(sst); - - /* switch on audio PLL, DRAM & IRAM blocks */ - reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); - reg &= ~(SST_VDRTCL0_APLLSE_MASK | SST_VDRTCL0_DSRAMPGE_MASK | - SST_VDRTCL0_ISRAMPGE_MASK); - writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); - /* select SSP1 19.2MHz base clock, SSP clock 0, turn off Low Power Clock */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR, SST_CSR_S1IOCS | SST_CSR_SBCS1 | SST_CSR_LPCS, 0x0); @@ -322,6 +349,28 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0, SST_CLKCTL_MASK | SST_CLKCTL_DCPLCG | SST_CLKCTL_SCOE0); + /* Stall and reset core, set CSR */ + hsw_reset(sst); + + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + reg |= SST_VDRTCL2_DCLCGE | SST_VDRTCL2_DTCGE; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + + udelay(50); + + /* switch on audio PLL */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + reg &= ~SST_VDRTCL2_APLLSE_MASK; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL2); + + /* set default power gating control, enable power gating control for all blocks. that is, + can't be accessed, please enable each block before accessing. */ + reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); + reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; + writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); + + /* disable DMA finish function for SSP0 & SSP1 */ sst_dsp_shim_update_bits_unlocked(sst, SST_CSR2, SST_CSR2_SDFD_SSP1, SST_CSR2_SDFD_SSP1); @@ -343,9 +392,6 @@ static int hsw_set_dsp_D0(struct sst_dsp *sst) sst_dsp_shim_write(sst, 0x80, 0x6); sst_dsp_shim_write(sst, 0xe0, 0x300a); - /* disable all clock gating */ - writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL2); - return 0; } @@ -497,6 +543,11 @@ static int hsw_block_enable(struct sst_mem_block *block) dev_dbg(block->dsp->dev, " enabled block %d:%d at offset 0x%x\n", block->type, block->index, block->offset); + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val &= ~SST_VDRTCL2_DCLCGE; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); + val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); bit = hsw_block_get_bit(block); writel(val & ~bit, sst->addr.pci_cfg + SST_VDRTCTL0); @@ -504,6 +555,13 @@ static int hsw_block_enable(struct sst_mem_block *block) /* wait 18 DSP clock ticks */ udelay(10); + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val |= SST_VDRTCL2_DCLCGE; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); + + udelay(50); + /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/ sst_mem_block_dummy_read(block); return 0; @@ -521,10 +579,26 @@ static int hsw_block_disable(struct sst_mem_block *block) dev_dbg(block->dsp->dev, " disabled block %d:%d at offset 0x%x\n", block->type, block->index, block->offset); + /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val &= ~SST_VDRTCL2_DCLCGE; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); + + val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); bit = hsw_block_get_bit(block); writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); + /* wait 18 DSP clock ticks */ + udelay(10); + + /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */ + val = readl(sst->addr.pci_cfg + SST_VDRTCTL2); + val |= SST_VDRTCL2_DCLCGE; + writel(val, sst->addr.pci_cfg + SST_VDRTCTL2); + + udelay(50); + return 0; } -- GitLab From 6233fe38048a80a9fa111ddb166ce9e8e0f5f1b3 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 27 Oct 2014 10:11:58 +0900 Subject: [PATCH 2197/9457] clk: samsung: Document binding for Exynos4415 clock controller This patch adds DT binding documentation for Exynos4415 SoC system clock controllers. Signed-off-by: Chanwoo Choi Acked-by: Kyungmin Park Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos4415-clock.txt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt diff --git a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt b/Documentation/devicetree/bindings/clock/exynos4415-clock.txt new file mode 100644 index 000000000000..847d98bae8cf --- /dev/null +++ b/Documentation/devicetree/bindings/clock/exynos4415-clock.txt @@ -0,0 +1,38 @@ +* Samsung Exynos4415 Clock Controller + +The Exynos4415 clock controller generates and supplies clock to various +consumer devices within the Exynos4415 SoC. + +Required properties: + +- compatible: should be one of the following: + - "samsung,exynos4415-cmu" - for the main system clocks controller + (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains). + - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory + Controller (DMC) domain clock controller. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. + +All available clocks are defined as preprocessor macros in +dt-bindings/clock/exynos4415.h header and can be used in device +tree sources. + +Example 1: An example of a clock controller node is listed below. + + cmu: clock-controller@10030000 { + compatible = "samsung,exynos4415-cmu"; + reg = <0x10030000 0x18000>; + #clock-cells = <1>; + }; + + cmu-dmc: clock-controller@105C0000 { + compatible = "samsung,exynos4415-cmu-dmc"; + reg = <0x105C0000 0x3000>; + #clock-cells = <1>; + }; -- GitLab From 384cb2ce819cf08fc8e7c3d306f180f0cefe4674 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 27 Oct 2014 10:11:57 +0900 Subject: [PATCH 2198/9457] clk: samsung: exynos4415: Add clocks using common clock framework This patch adds clock driver of Exynos4415 SoC based on Cortex-A9 using common clock framework. The CMU (Clock Management Unit) of Exynos4415 controls PLLs(Phase Locked Loops) and generates system clocks for CPU, busses and function clocks for individual IPs. Signed-off-by: Chanwoo Choi Signed-off-by: Tomasz Figa Signed-off-by: Seung-Woo Kim Acked-by: Kyungmin Park Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4415.c | 1142 ++++++++++++++++++++++++ include/dt-bindings/clock/exynos4415.h | 360 ++++++++ 3 files changed, 1503 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos4415.c create mode 100644 include/dt-bindings/clock/exynos4415.h diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 6fb4bc602e8a..d8535e6df1db 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o +obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c new file mode 100644 index 000000000000..c7208c7a3add --- /dev/null +++ b/drivers/clk/samsung/clk-exynos4415.c @@ -0,0 +1,1142 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Chanwoo Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos4415 SoC. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk.h" +#include "clk-pll.h" + +#define SRC_LEFTBUS 0x4200 +#define DIV_LEFTBUS 0x4500 +#define GATE_IP_LEFTBUS 0x4800 +#define GATE_IP_IMAGE 0x4930 +#define SRC_RIGHTBUS 0x8200 +#define DIV_RIGHTBUS 0x8500 +#define GATE_IP_RIGHTBUS 0x8800 +#define GATE_IP_PERIR 0x8960 +#define EPLL_LOCK 0xc010 +#define G3D_PLL_LOCK 0xc020 +#define DISP_PLL_LOCK 0xc030 +#define ISP_PLL_LOCK 0xc040 +#define EPLL_CON0 0xc110 +#define EPLL_CON1 0xc114 +#define EPLL_CON2 0xc118 +#define G3D_PLL_CON0 0xc120 +#define G3D_PLL_CON1 0xc124 +#define G3D_PLL_CON2 0xc128 +#define ISP_PLL_CON0 0xc130 +#define ISP_PLL_CON1 0xc134 +#define ISP_PLL_CON2 0xc138 +#define DISP_PLL_CON0 0xc140 +#define DISP_PLL_CON1 0xc144 +#define DISP_PLL_CON2 0xc148 +#define SRC_TOP0 0xc210 +#define SRC_TOP1 0xc214 +#define SRC_CAM 0xc220 +#define SRC_TV 0xc224 +#define SRC_MFC 0xc228 +#define SRC_G3D 0xc22c +#define SRC_LCD 0xc234 +#define SRC_ISP 0xc238 +#define SRC_MAUDIO 0xc23c +#define SRC_FSYS 0xc240 +#define SRC_PERIL0 0xc250 +#define SRC_PERIL1 0xc254 +#define SRC_CAM1 0xc258 +#define SRC_TOP_ISP0 0xc25c +#define SRC_TOP_ISP1 0xc260 +#define SRC_MASK_TOP 0xc310 +#define SRC_MASK_CAM 0xc320 +#define SRC_MASK_TV 0xc324 +#define SRC_MASK_LCD 0xc334 +#define SRC_MASK_ISP 0xc338 +#define SRC_MASK_MAUDIO 0xc33c +#define SRC_MASK_FSYS 0xc340 +#define SRC_MASK_PERIL0 0xc350 +#define SRC_MASK_PERIL1 0xc354 +#define DIV_TOP 0xc510 +#define DIV_CAM 0xc520 +#define DIV_TV 0xc524 +#define DIV_MFC 0xc528 +#define DIV_G3D 0xc52c +#define DIV_LCD 0xc534 +#define DIV_ISP 0xc538 +#define DIV_MAUDIO 0xc53c +#define DIV_FSYS0 0xc540 +#define DIV_FSYS1 0xc544 +#define DIV_FSYS2 0xc548 +#define DIV_PERIL0 0xc550 +#define DIV_PERIL1 0xc554 +#define DIV_PERIL2 0xc558 +#define DIV_PERIL3 0xc55c +#define DIV_PERIL4 0xc560 +#define DIV_PERIL5 0xc564 +#define DIV_CAM1 0xc568 +#define DIV_TOP_ISP1 0xc56c +#define DIV_TOP_ISP0 0xc570 +#define CLKDIV2_RATIO 0xc580 +#define GATE_SCLK_CAM 0xc820 +#define GATE_SCLK_TV 0xc824 +#define GATE_SCLK_MFC 0xc828 +#define GATE_SCLK_G3D 0xc82c +#define GATE_SCLK_LCD 0xc834 +#define GATE_SCLK_MAUDIO 0xc83c +#define GATE_SCLK_FSYS 0xc840 +#define GATE_SCLK_PERIL 0xc850 +#define GATE_IP_CAM 0xc920 +#define GATE_IP_TV 0xc924 +#define GATE_IP_MFC 0xc928 +#define GATE_IP_G3D 0xc92c +#define GATE_IP_LCD 0xc934 +#define GATE_IP_FSYS 0xc940 +#define GATE_IP_PERIL 0xc950 +#define GATE_BLOCK 0xc970 +#define APLL_LOCK 0x14000 +#define APLL_CON0 0x14100 +#define SRC_CPU 0x14200 +#define DIV_CPU0 0x14500 +#define DIV_CPU1 0x14504 + +enum exynos4415_plls { + apll, epll, g3d_pll, isp_pll, disp_pll, + nr_plls, +}; + +/* + * Support for CMU save/restore across system suspends + */ +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos4415_clk_regs; +static struct samsung_clk_provider *exynos4415_ctx; + +static unsigned long exynos4415_cmu_clk_regs[] __initdata = { + SRC_LEFTBUS, + DIV_LEFTBUS, + GATE_IP_LEFTBUS, + GATE_IP_IMAGE, + SRC_RIGHTBUS, + DIV_RIGHTBUS, + GATE_IP_RIGHTBUS, + GATE_IP_PERIR, + EPLL_LOCK, + G3D_PLL_LOCK, + DISP_PLL_LOCK, + ISP_PLL_LOCK, + EPLL_CON0, + EPLL_CON1, + EPLL_CON2, + G3D_PLL_CON0, + G3D_PLL_CON1, + G3D_PLL_CON2, + ISP_PLL_CON0, + ISP_PLL_CON1, + ISP_PLL_CON2, + DISP_PLL_CON0, + DISP_PLL_CON1, + DISP_PLL_CON2, + SRC_TOP0, + SRC_TOP1, + SRC_CAM, + SRC_TV, + SRC_MFC, + SRC_G3D, + SRC_LCD, + SRC_ISP, + SRC_MAUDIO, + SRC_FSYS, + SRC_PERIL0, + SRC_PERIL1, + SRC_CAM1, + SRC_TOP_ISP0, + SRC_TOP_ISP1, + SRC_MASK_TOP, + SRC_MASK_CAM, + SRC_MASK_TV, + SRC_MASK_LCD, + SRC_MASK_ISP, + SRC_MASK_MAUDIO, + SRC_MASK_FSYS, + SRC_MASK_PERIL0, + SRC_MASK_PERIL1, + DIV_TOP, + DIV_CAM, + DIV_TV, + DIV_MFC, + DIV_G3D, + DIV_LCD, + DIV_ISP, + DIV_MAUDIO, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_PERIL0, + DIV_PERIL1, + DIV_PERIL2, + DIV_PERIL3, + DIV_PERIL4, + DIV_PERIL5, + DIV_CAM1, + DIV_TOP_ISP1, + DIV_TOP_ISP0, + CLKDIV2_RATIO, + GATE_SCLK_CAM, + GATE_SCLK_TV, + GATE_SCLK_MFC, + GATE_SCLK_G3D, + GATE_SCLK_LCD, + GATE_SCLK_MAUDIO, + GATE_SCLK_FSYS, + GATE_SCLK_PERIL, + GATE_IP_CAM, + GATE_IP_TV, + GATE_IP_MFC, + GATE_IP_G3D, + GATE_IP_LCD, + GATE_IP_FSYS, + GATE_IP_PERIL, + GATE_BLOCK, + APLL_LOCK, + APLL_CON0, + SRC_CPU, + DIV_CPU0, + DIV_CPU1, +}; + +static int exynos4415_clk_suspend(void) +{ + samsung_clk_save(exynos4415_ctx->reg_base, exynos4415_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); + + return 0; +} + +static void exynos4415_clk_resume(void) +{ + samsung_clk_restore(exynos4415_ctx->reg_base, exynos4415_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); +} + +static struct syscore_ops exynos4415_clk_syscore_ops = { + .suspend = exynos4415_clk_suspend, + .resume = exynos4415_clk_resume, +}; + +static void exynos4415_clk_sleep_init(void) +{ + exynos4415_clk_regs = + samsung_clk_alloc_reg_dump(exynos4415_cmu_clk_regs, + ARRAY_SIZE(exynos4415_cmu_clk_regs)); + if (!exynos4415_clk_regs) { + pr_warn("%s: Failed to allocate sleep save data\n", __func__); + return; + } + + register_syscore_ops(&exynos4415_clk_syscore_ops); +} +#else +static inline void exynos4415_clk_sleep_init(void) { } +#endif + +/* list of all parent clock list */ +PNAME(mout_g3d_pllsrc_p) = { "fin_pll", }; + +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; +PNAME(mout_g3d_pll_p) = { "fin_pll", "fout_g3d_pll", }; +PNAME(mout_isp_pll_p) = { "fin_pll", "fout_isp_pll", }; +PNAME(mout_disp_pll_p) = { "fin_pll", "fout_disp_pll", }; + +PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", }; +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", }; +PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", }; +PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", }; + +PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", }; +PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_g3d_pll", }; + +PNAME(mout_gdl_p) = { "mout_mpll_user_l", }; +PNAME(mout_gdr_p) = { "mout_mpll_user_r", }; + +PNAME(mout_aclk_266_p) = { "mout_mpll_user_t", "mout_g3d_pll", }; + +PNAME(group_epll_g3dpll_p) = { "mout_epll", "mout_g3d_pll" }; +PNAME(group_sclk_p) = { "xxti", "xusbxti", + "none", "mout_isp_pll", + "none", "none", "div_mpll_pre", + "mout_epll", "mout_g3d_pll", }; +PNAME(group_spdif_p) = { "mout_audio0", "mout_audio1", + "mout_audio2", "spdif_extclk", }; +PNAME(group_sclk_audio2_p) = { "audiocdclk2", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_audio1_p) = { "audiocdclk1", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_audio0_p) = { "audiocdclk0", "none", + "none", "mout_isp_pll", + "mout_disp_pll", "xusbxti", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_fimc_lclk_p) = { "xxti", "xusbxti", + "none", "mout_isp_pll", + "none", "mout_disp_pll", + "mout_mpll_user_t", "mout_epll", + "mout_g3d_pll", }; +PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti", + "m_bitclkhsdiv4_4l", "mout_isp_pll", + "mout_disp_pll", "sclk_hdmiphy", + "div_mpll_pre", "mout_epll", + "mout_g3d_pll", }; +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy" }; +PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" }; +PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" }; +PNAME(mout_jpeg_p) = { "mout_jpeg_0", "mout_jpeg_1" }; +PNAME(mout_jpeg1_p) = { "mout_epll", "mout_g3d_pll" }; +PNAME(group_aclk_isp0_300_p) = { "mout_isp_pll", "div_mpll_pre" }; +PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" }; +PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" }; +PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" }; +PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" }; + +static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initdata = { + /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */ + FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0), +}; + +static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = { + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), +}; + +static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* SRC_LEFTBUS */ + MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p, + SRC_LEFTBUS, 4, 1), + MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1), + + /* SRC_RIGHTBUS */ + MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p, + SRC_RIGHTBUS, 4, 1), + MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1), + + /* SRC_TOP0 */ + MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1), + MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p, + SRC_TOP0, 24, 1), + MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p, + SRC_TOP0, 20, 1), + MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p, + SRC_TOP0, 16, 1), + MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p, + SRC_TOP0, 12, 1), + MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, + SRC_TOP0, 8, 1), + MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1), + MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1), + + /* SRC_TOP1 */ + MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p, + SRC_TOP1, 28, 1), + MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p, + SRC_TOP1, 16, 1), + MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p, + SRC_TOP1, 12, 1), + MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp", + group_mout_mpll_user_t_p, SRC_TOP1, 8, 1), + MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p, + SRC_TOP1, 0, 1), + + /* SRC_CAM */ + MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4), + MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4), + MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4), + MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM, + 12, 4), + MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM, + 8, 4), + MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM, + 4, 4), + MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM, + 0, 4), + + /* SRC_TV */ + MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), + + /* SRC_MFC */ + MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), + MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1), + MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0, + 1), + + /* SRC_G3D */ + MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), + MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1), + MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0, + 1), + + /* SRC_LCD */ + MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4), + MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4), + + /* SRC_ISP */ + MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP, + 16, 4), + MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP, + 12, 4), + MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP, + 8, 4), + MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP, + 4, 4), + MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP, + 0, 4), + + /* SRC_MAUDIO */ + MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO, + 0, 4), + + /* SRC_FSYS */ + MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4), + MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4), + MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4), + MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4), + + /* SRC_PERIL0 */ + MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4), + MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4), + MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4), + MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4), + + /* SRC_PERIL1 */ + MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4), + MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4), + MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4), + MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4), + MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1, + 4, 4), + MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1, + 0, 4), + + /* SRC_CPU */ + MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p, + SRC_CPU, 24, 1), + MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1), + MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0, + CLK_MUX_READ_ONLY), + MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, + CLK_SET_RATE_PARENT, 0), + + /* SRC_CAM1 */ + MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1", + group_fimc_lclk_p, SRC_CAM1, 20, 1), + MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0", + group_fimc_lclk_p, SRC_CAM1, 16, 1), + MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1), + MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1), + MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1, + 0, 1), + + /* SRC_TOP_ISP0 */ + MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300", + group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1), + MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user", + group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1), + MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user", + group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1), + + /* SRC_TOP_ISP1 */ + MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300", + group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1), + MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user", + group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1), +}; + +static struct samsung_div_clock exynos4415_div_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* DIV_LEFTBUS */ + DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3), + DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4), + + /* DIV_RIGHTBUS */ + DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3), + DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4), + + /* DIV_TOP */ + DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp", + "mout_aclk_400_mcuisp", DIV_TOP, 24, 3), + DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3), + DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3), + DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3), + DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4), + DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3), + + /* DIV_CAM */ + DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), + DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), + DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), + DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM, + 12, 4), + DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM, + 8, 4), + DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM, + 4, 4), + DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM, + 0, 4), + + /* DIV_TV */ + DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4), + + /* DIV_MFC */ + DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4), + + /* DIV_G3D */ + DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), + + /* DIV_LCD */ + DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4), + DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4), + + /* DIV_ISP */ + DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4), + DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp", + DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4), + DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp", + DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4), + DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4), + + /* DIV_MAUDIO */ + DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8), + DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), + + /* DIV_FSYS0 */ + DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4), + + /* DIV_FSYS1 */ + DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + + /* DIV_FSYS2 */ + DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4, + CLK_SET_RATE_PARENT, 0), + + /* DIV_PERIL0 */ + DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4), + DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4), + DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), + DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), + + /* DIV_PERIL1 */ + DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), + DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), + + /* DIV_PERIL2 */ + DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4), + + /* DIV_PERIL4 */ + DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8), + DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), + DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8), + DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), + + /* DIV_PERIL5 */ + DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6), + + /* DIV_CAM1 */ + DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc", + "mout_pxlasync_csis1", DIV_CAM1, 24, 4), + DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc", + "mout_pxlasync_csis0", DIV_CAM1, 20, 4), + DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4), + + /* DIV_CPU0 */ + DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3, + CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY), + DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3), + DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3), + DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3), + DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3), + DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3), + DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3, + CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY), + + /* DIV_CPU1 */ + DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3), + DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3), +}; + +static struct samsung_gate_clock exynos4415_gate_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* GATE_IP_LEFTBUS */ + GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_IMAGE */ + GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE, + 9, 0, 0), + GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE, + 8, 0, 0), + GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE, + 7, 0, 0), + GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE, + 5, 0, 0), + GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE, + 4, 0, 0), + GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0), + GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0), + + /* GATE_IP_RIGHTBUS */ + GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100", + GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100", + GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100", + GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100", + GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100", + GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100", + GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100", + GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100", + GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_PERIR */ + GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100", + GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0), + GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100", + GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0), + GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100", + GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100", + GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100", + GATE_IP_PERIR, 17, 0, 0), + GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0), + GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0), + GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0), + GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0), + GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_SCLK_CAM - non-completed */ + GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc", + "div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc", + "div_pxlasync_csis0_fimc", GATE_SCLK_CAM, + 10, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg", + GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1", + GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0", + GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1", + GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk", + GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk", + GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk", + GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk", + GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_TV */ + GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk", + GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", + GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk", + GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_MFC */ + GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc", + GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_G3D */ + GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", + GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_LCD */ + GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0", + GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre", + GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0", + GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0", + GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_MAUDIO */ + GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0", + GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0", + GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_FSYS */ + GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre", + GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi", + GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre", + GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre", + GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre", + GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_PERIL */ + GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1", + GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2", + GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1", + GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2", + GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1", + GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", + GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre", + GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre", + GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre", + GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3", + GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2", + GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1", + GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", + GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_IP_CAM */ + GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM, + 22, CLK_IGNORE_UNUSED, 0), + GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM, + 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM, + 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM, + 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM, + 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0), + GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0), + GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0), + GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0), + GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0), + GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0), + GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0), + GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0), + GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0), + GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0), + GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0), + GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0), + + /* GATE_IP_TV */ + GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0), + GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0), + GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0), + GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0), + GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0), + + /* GATE_IP_MFC */ + GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0), + GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0), + GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0), + + /* GATE_IP_G3D */ + GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0), + + /* GATE_IP_LCD */ + GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0), + GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0), + GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0), + GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0), + GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0), + + /* GATE_IP_FSYS */ + GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0), + GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0), + GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13, + 0, 0), + GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0), + GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0), + GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0), + GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0), + GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0), + GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0), + + /* GATE_IP_PERIL */ + GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0), + GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0), + GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0), + GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0), + GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0), + GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0), + GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0), + GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0), + GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0), + GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0), + GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0), + GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0), + GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0), + GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0), + GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0), + GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0), + GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0), + GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0), + GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0), + GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0), + GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0), +}; + +/* + * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL + */ +static struct samsung_pll_rate_table exynos4415_pll_rates[] = { + PLL_35XX_RATE(1600000000, 400, 3, 1), + PLL_35XX_RATE(1500000000, 250, 2, 1), + PLL_35XX_RATE(1400000000, 175, 3, 0), + PLL_35XX_RATE(1300000000, 325, 3, 1), + PLL_35XX_RATE(1200000000, 400, 4, 1), + PLL_35XX_RATE(1100000000, 275, 3, 1), + PLL_35XX_RATE(1066000000, 533, 6, 1), + PLL_35XX_RATE(1000000000, 250, 3, 1), + PLL_35XX_RATE(960000000, 320, 4, 1), + PLL_35XX_RATE(900000000, 300, 4, 1), + PLL_35XX_RATE(850000000, 425, 6, 1), + PLL_35XX_RATE(800000000, 200, 3, 1), + PLL_35XX_RATE(700000000, 175, 3, 1), + PLL_35XX_RATE(667000000, 667, 12, 1), + PLL_35XX_RATE(600000000, 400, 4, 2), + PLL_35XX_RATE(550000000, 275, 3, 2), + PLL_35XX_RATE(533000000, 533, 6, 2), + PLL_35XX_RATE(520000000, 260, 3, 2), + PLL_35XX_RATE(500000000, 250, 3, 2), + PLL_35XX_RATE(440000000, 220, 3, 2), + PLL_35XX_RATE(400000000, 200, 3, 2), + PLL_35XX_RATE(350000000, 175, 3, 2), + PLL_35XX_RATE(300000000, 300, 3, 3), + PLL_35XX_RATE(266000000, 266, 3, 3), + PLL_35XX_RATE(200000000, 200, 3, 3), + PLL_35XX_RATE(160000000, 160, 3, 3), + PLL_35XX_RATE(100000000, 200, 3, 4), + { /* sentinel */ } +}; + +/* EPLL */ +static struct samsung_pll_rate_table exynos4415_epll_rates[] = { + PLL_36XX_RATE(800000000, 200, 3, 1, 0), + PLL_36XX_RATE(288000000, 96, 2, 2, 0), + PLL_36XX_RATE(192000000, 128, 2, 3, 0), + PLL_36XX_RATE(144000000, 96, 2, 3, 0), + PLL_36XX_RATE(96000000, 128, 2, 4, 0), + PLL_36XX_RATE(84000000, 112, 2, 4, 0), + PLL_36XX_RATE(80750011, 107, 2, 4, 43691), + PLL_36XX_RATE(73728004, 98, 2, 4, 19923), + PLL_36XX_RATE(67987602, 271, 3, 5, 62285), + PLL_36XX_RATE(65911004, 175, 2, 5, 49982), + PLL_36XX_RATE(50000000, 200, 3, 5, 0), + PLL_36XX_RATE(49152003, 131, 2, 5, 4719), + PLL_36XX_RATE(48000000, 128, 2, 5, 0), + PLL_36XX_RATE(45250000, 181, 3, 5, 0), + { /* sentinel */ } +}; + +static struct samsung_pll_clock exynos4415_plls[nr_plls] __initdata = { + [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", + APLL_LOCK, APLL_CON0, NULL), + [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", + EPLL_LOCK, EPLL_CON0, NULL), + [g3d_pll] = PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", + "mout_g3d_pllsrc", G3D_PLL_LOCK, G3D_PLL_CON0, NULL), + [isp_pll] = PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll", + ISP_PLL_LOCK, ISP_PLL_CON0, NULL), + [disp_pll] = PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll", + "fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, NULL), +}; + +static void __init exynos4415_cmu_init(struct device_node *np) +{ + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + exynos4415_ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!exynos4415_ctx) + panic("%s: unable to allocate context.\n", __func__); + + exynos4415_plls[apll].rate_table = exynos4415_pll_rates; + exynos4415_plls[epll].rate_table = exynos4415_epll_rates; + exynos4415_plls[g3d_pll].rate_table = exynos4415_pll_rates; + exynos4415_plls[isp_pll].rate_table = exynos4415_pll_rates; + exynos4415_plls[disp_pll].rate_table = exynos4415_pll_rates; + + samsung_clk_register_fixed_factor(exynos4415_ctx, + exynos4415_fixed_factor_clks, + ARRAY_SIZE(exynos4415_fixed_factor_clks)); + samsung_clk_register_fixed_rate(exynos4415_ctx, + exynos4415_fixed_rate_clks, + ARRAY_SIZE(exynos4415_fixed_rate_clks)); + + samsung_clk_register_pll(exynos4415_ctx, exynos4415_plls, + ARRAY_SIZE(exynos4415_plls), reg_base); + samsung_clk_register_mux(exynos4415_ctx, exynos4415_mux_clks, + ARRAY_SIZE(exynos4415_mux_clks)); + samsung_clk_register_div(exynos4415_ctx, exynos4415_div_clks, + ARRAY_SIZE(exynos4415_div_clks)); + samsung_clk_register_gate(exynos4415_ctx, exynos4415_gate_clks, + ARRAY_SIZE(exynos4415_gate_clks)); + + exynos4415_clk_sleep_init(); + + samsung_clk_of_add_provider(np, exynos4415_ctx); +} +CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init); + +/* + * CMU DMC + */ + +#define MPLL_LOCK 0x008 +#define MPLL_CON0 0x108 +#define MPLL_CON1 0x10c +#define MPLL_CON2 0x110 +#define BPLL_LOCK 0x118 +#define BPLL_CON0 0x218 +#define BPLL_CON1 0x21c +#define BPLL_CON2 0x220 +#define SRC_DMC 0x300 +#define DIV_DMC1 0x504 + +enum exynos4415_dmc_plls { + mpll, bpll, + nr_dmc_plls, +}; + +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos4415_dmc_clk_regs; +static struct samsung_clk_provider *exynos4415_dmc_ctx; + +static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = { + MPLL_LOCK, + MPLL_CON0, + MPLL_CON1, + MPLL_CON2, + BPLL_LOCK, + BPLL_CON0, + BPLL_CON1, + BPLL_CON2, + SRC_DMC, + DIV_DMC1, +}; + +static int exynos4415_dmc_clk_suspend(void) +{ + samsung_clk_save(exynos4415_dmc_ctx->reg_base, + exynos4415_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); + return 0; +} + +static void exynos4415_dmc_clk_resume(void) +{ + samsung_clk_restore(exynos4415_dmc_ctx->reg_base, + exynos4415_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); +} + +static struct syscore_ops exynos4415_dmc_clk_syscore_ops = { + .suspend = exynos4415_dmc_clk_suspend, + .resume = exynos4415_dmc_clk_resume, +}; + +static void exynos4415_dmc_clk_sleep_init(void) +{ + exynos4415_dmc_clk_regs = + samsung_clk_alloc_reg_dump(exynos4415_cmu_dmc_clk_regs, + ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs)); + if (!exynos4415_dmc_clk_regs) { + pr_warn("%s: Failed to allocate sleep save data\n", __func__); + return; + } + + register_syscore_ops(&exynos4415_dmc_clk_syscore_ops); +} +#else +static inline void exynos4415_dmc_clk_sleep_init(void) { } +#endif /* CONFIG_PM_SLEEP */ + +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; +PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", }; +PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", }; + +static struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initdata = { + MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1), + MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1), + MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1), + MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1), +}; + +static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = { + DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3), + DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3), + DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus", + DIV_DMC1, 19, 2), + DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3), + DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3), + DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2), +}; + +static struct samsung_pll_clock exynos4415_dmc_plls[nr_dmc_plls] __initdata = { + [mpll] = PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll", + MPLL_LOCK, MPLL_CON0, NULL), + [bpll] = PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll", + BPLL_LOCK, BPLL_CON0, NULL), +}; + +static void __init exynos4415_cmu_dmc_init(struct device_node *np) +{ + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + exynos4415_dmc_ctx = samsung_clk_init(np, reg_base, NR_CLKS_DMC); + if (!exynos4415_dmc_ctx) + panic("%s: unable to allocate context.\n", __func__); + + exynos4415_dmc_plls[mpll].rate_table = exynos4415_pll_rates; + exynos4415_dmc_plls[bpll].rate_table = exynos4415_pll_rates; + + samsung_clk_register_pll(exynos4415_dmc_ctx, exynos4415_dmc_plls, + ARRAY_SIZE(exynos4415_dmc_plls), reg_base); + samsung_clk_register_mux(exynos4415_dmc_ctx, exynos4415_dmc_mux_clks, + ARRAY_SIZE(exynos4415_dmc_mux_clks)); + samsung_clk_register_div(exynos4415_dmc_ctx, exynos4415_dmc_div_clks, + ARRAY_SIZE(exynos4415_dmc_div_clks)); + + exynos4415_dmc_clk_sleep_init(); + + samsung_clk_of_add_provider(np, exynos4415_dmc_ctx); +} +CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc", + exynos4415_cmu_dmc_init); diff --git a/include/dt-bindings/clock/exynos4415.h b/include/dt-bindings/clock/exynos4415.h new file mode 100644 index 000000000000..7eed55100721 --- /dev/null +++ b/include/dt-bindings/clock/exynos4415.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Chanwoo Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Device Tree binding constants for Samsung Exynos4415 clock controllers. + */ + +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H +#define _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H + +/* + * Let each exported clock get a unique index, which is used on DT-enabled + * platforms to lookup the clock from a clock specifier. These indices are + * therefore considered an ABI and so must not be changed. This implies + * that new clocks should be added either in free spaces between clock groups + * or at the end. + */ + +/* + * Main CMU + */ + +#define CLK_OSCSEL 1 +#define CLK_FIN_PLL 2 +#define CLK_FOUT_APLL 3 +#define CLK_FOUT_MPLL 4 +#define CLK_FOUT_EPLL 5 +#define CLK_FOUT_G3D_PLL 6 +#define CLK_FOUT_ISP_PLL 7 +#define CLK_FOUT_DISP_PLL 8 + +/* Muxes */ +#define CLK_MOUT_MPLL_USER_L 16 +#define CLK_MOUT_GDL 17 +#define CLK_MOUT_MPLL_USER_R 18 +#define CLK_MOUT_GDR 19 +#define CLK_MOUT_EBI 20 +#define CLK_MOUT_ACLK_200 21 +#define CLK_MOUT_ACLK_160 22 +#define CLK_MOUT_ACLK_100 23 +#define CLK_MOUT_ACLK_266 24 +#define CLK_MOUT_G3D_PLL 25 +#define CLK_MOUT_EPLL 26 +#define CLK_MOUT_EBI_1 27 +#define CLK_MOUT_ISP_PLL 28 +#define CLK_MOUT_DISP_PLL 29 +#define CLK_MOUT_MPLL_USER_T 30 +#define CLK_MOUT_ACLK_400_MCUISP 31 +#define CLK_MOUT_G3D_PLLSRC 32 +#define CLK_MOUT_CSIS1 33 +#define CLK_MOUT_CSIS0 34 +#define CLK_MOUT_CAM1 35 +#define CLK_MOUT_FIMC3_LCLK 36 +#define CLK_MOUT_FIMC2_LCLK 37 +#define CLK_MOUT_FIMC1_LCLK 38 +#define CLK_MOUT_FIMC0_LCLK 39 +#define CLK_MOUT_MFC 40 +#define CLK_MOUT_MFC_1 41 +#define CLK_MOUT_MFC_0 42 +#define CLK_MOUT_G3D 43 +#define CLK_MOUT_G3D_1 44 +#define CLK_MOUT_G3D_0 45 +#define CLK_MOUT_MIPI0 46 +#define CLK_MOUT_FIMD0 47 +#define CLK_MOUT_TSADC_ISP 48 +#define CLK_MOUT_UART_ISP 49 +#define CLK_MOUT_SPI1_ISP 50 +#define CLK_MOUT_SPI0_ISP 51 +#define CLK_MOUT_PWM_ISP 52 +#define CLK_MOUT_AUDIO0 53 +#define CLK_MOUT_TSADC 54 +#define CLK_MOUT_MMC2 55 +#define CLK_MOUT_MMC1 56 +#define CLK_MOUT_MMC0 57 +#define CLK_MOUT_UART3 58 +#define CLK_MOUT_UART2 59 +#define CLK_MOUT_UART1 60 +#define CLK_MOUT_UART0 61 +#define CLK_MOUT_SPI2 62 +#define CLK_MOUT_SPI1 63 +#define CLK_MOUT_SPI0 64 +#define CLK_MOUT_SPDIF 65 +#define CLK_MOUT_AUDIO2 66 +#define CLK_MOUT_AUDIO1 67 +#define CLK_MOUT_MPLL_USER_C 68 +#define CLK_MOUT_HPM 69 +#define CLK_MOUT_CORE 70 +#define CLK_MOUT_APLL 71 +#define CLK_MOUT_PXLASYNC_CSIS1_FIMC 72 +#define CLK_MOUT_PXLASYNC_CSIS0_FIMC 73 +#define CLK_MOUT_JPEG 74 +#define CLK_MOUT_JPEG1 75 +#define CLK_MOUT_JPEG0 76 +#define CLK_MOUT_ACLK_ISP0_300 77 +#define CLK_MOUT_ACLK_ISP0_400 78 +#define CLK_MOUT_ACLK_ISP0_300_USER 79 +#define CLK_MOUT_ACLK_ISP1_300 80 +#define CLK_MOUT_ACLK_ISP1_300_USER 81 +#define CLK_MOUT_HDMI 82 + +/* Dividers */ +#define CLK_DIV_GPL 90 +#define CLK_DIV_GDL 91 +#define CLK_DIV_GPR 92 +#define CLK_DIV_GDR 93 +#define CLK_DIV_ACLK_400_MCUISP 94 +#define CLK_DIV_EBI 95 +#define CLK_DIV_ACLK_200 96 +#define CLK_DIV_ACLK_160 97 +#define CLK_DIV_ACLK_100 98 +#define CLK_DIV_ACLK_266 99 +#define CLK_DIV_CSIS1 100 +#define CLK_DIV_CSIS0 101 +#define CLK_DIV_CAM1 102 +#define CLK_DIV_FIMC3_LCLK 103 +#define CLK_DIV_FIMC2_LCLK 104 +#define CLK_DIV_FIMC1_LCLK 105 +#define CLK_DIV_FIMC0_LCLK 106 +#define CLK_DIV_TV_BLK 107 +#define CLK_DIV_MFC 108 +#define CLK_DIV_G3D 109 +#define CLK_DIV_MIPI0_PRE 110 +#define CLK_DIV_MIPI0 111 +#define CLK_DIV_FIMD0 112 +#define CLK_DIV_UART_ISP 113 +#define CLK_DIV_SPI1_ISP_PRE 114 +#define CLK_DIV_SPI1_ISP 115 +#define CLK_DIV_SPI0_ISP_PRE 116 +#define CLK_DIV_SPI0_ISP 117 +#define CLK_DIV_PWM_ISP 118 +#define CLK_DIV_PCM0 119 +#define CLK_DIV_AUDIO0 120 +#define CLK_DIV_TSADC_PRE 121 +#define CLK_DIV_TSADC 122 +#define CLK_DIV_MMC1_PRE 123 +#define CLK_DIV_MMC1 124 +#define CLK_DIV_MMC0_PRE 125 +#define CLK_DIV_MMC0 126 +#define CLK_DIV_MMC2_PRE 127 +#define CLK_DIV_MMC2 128 +#define CLK_DIV_UART3 129 +#define CLK_DIV_UART2 130 +#define CLK_DIV_UART1 131 +#define CLK_DIV_UART0 132 +#define CLK_DIV_SPI1_PRE 133 +#define CLK_DIV_SPI1 134 +#define CLK_DIV_SPI0_PRE 135 +#define CLK_DIV_SPI0 136 +#define CLK_DIV_SPI2_PRE 137 +#define CLK_DIV_SPI2 138 +#define CLK_DIV_PCM2 139 +#define CLK_DIV_AUDIO2 140 +#define CLK_DIV_PCM1 141 +#define CLK_DIV_AUDIO1 142 +#define CLK_DIV_I2S1 143 +#define CLK_DIV_PXLASYNC_CSIS1_FIMC 144 +#define CLK_DIV_PXLASYNC_CSIS0_FIMC 145 +#define CLK_DIV_JPEG 146 +#define CLK_DIV_CORE2 147 +#define CLK_DIV_APLL 148 +#define CLK_DIV_PCLK_DBG 149 +#define CLK_DIV_ATB 150 +#define CLK_DIV_PERIPH 151 +#define CLK_DIV_COREM1 152 +#define CLK_DIV_COREM0 153 +#define CLK_DIV_CORE 154 +#define CLK_DIV_HPM 155 +#define CLK_DIV_COPY 156 + +/* Gates */ +#define CLK_ASYNC_G3D 180 +#define CLK_ASYNC_MFCL 181 +#define CLK_ASYNC_TVX 182 +#define CLK_PPMULEFT 183 +#define CLK_GPIO_LEFT 184 +#define CLK_PPMUIMAGE 185 +#define CLK_QEMDMA2 186 +#define CLK_QEROTATOR 187 +#define CLK_SMMUMDMA2 188 +#define CLK_SMMUROTATOR 189 +#define CLK_MDMA2 190 +#define CLK_ROTATOR 191 +#define CLK_ASYNC_ISPMX 192 +#define CLK_ASYNC_MAUDIOX 193 +#define CLK_ASYNC_MFCR 194 +#define CLK_ASYNC_FSYSD 195 +#define CLK_ASYNC_LCD0X 196 +#define CLK_ASYNC_CAMX 197 +#define CLK_PPMURIGHT 198 +#define CLK_GPIO_RIGHT 199 +#define CLK_ANTIRBK_APBIF 200 +#define CLK_EFUSE_WRITER_APBIF 201 +#define CLK_MONOCNT 202 +#define CLK_TZPC6 203 +#define CLK_PROVISIONKEY1 204 +#define CLK_PROVISIONKEY0 205 +#define CLK_CMU_ISPPART 206 +#define CLK_TMU_APBIF 207 +#define CLK_KEYIF 208 +#define CLK_RTC 209 +#define CLK_WDT 210 +#define CLK_MCT 211 +#define CLK_SECKEY 212 +#define CLK_HDMI_CEC 213 +#define CLK_TZPC5 214 +#define CLK_TZPC4 215 +#define CLK_TZPC3 216 +#define CLK_TZPC2 217 +#define CLK_TZPC1 218 +#define CLK_TZPC0 219 +#define CLK_CMU_COREPART 220 +#define CLK_CMU_TOPPART 221 +#define CLK_PMU_APBIF 222 +#define CLK_SYSREG 223 +#define CLK_CHIP_ID 224 +#define CLK_SMMUFIMC_LITE2 225 +#define CLK_FIMC_LITE2 226 +#define CLK_PIXELASYNCM1 227 +#define CLK_PIXELASYNCM0 228 +#define CLK_PPMUCAMIF 229 +#define CLK_SMMUJPEG 230 +#define CLK_SMMUFIMC3 231 +#define CLK_SMMUFIMC2 232 +#define CLK_SMMUFIMC1 233 +#define CLK_SMMUFIMC0 234 +#define CLK_JPEG 235 +#define CLK_CSIS1 236 +#define CLK_CSIS0 237 +#define CLK_FIMC3 238 +#define CLK_FIMC2 239 +#define CLK_FIMC1 240 +#define CLK_FIMC0 241 +#define CLK_PPMUTV 242 +#define CLK_SMMUTV 243 +#define CLK_HDMI 244 +#define CLK_MIXER 245 +#define CLK_VP 246 +#define CLK_PPMUMFC_R 247 +#define CLK_PPMUMFC_L 248 +#define CLK_SMMUMFC_R 249 +#define CLK_SMMUMFC_L 250 +#define CLK_MFC 251 +#define CLK_PPMUG3D 252 +#define CLK_G3D 253 +#define CLK_PPMULCD0 254 +#define CLK_SMMUFIMD0 255 +#define CLK_DSIM0 256 +#define CLK_SMIES 257 +#define CLK_MIE0 258 +#define CLK_FIMD0 259 +#define CLK_TSADC 260 +#define CLK_PPMUFILE 261 +#define CLK_NFCON 262 +#define CLK_USBDEVICE 263 +#define CLK_USBHOST 264 +#define CLK_SROMC 265 +#define CLK_SDMMC2 266 +#define CLK_SDMMC1 267 +#define CLK_SDMMC0 268 +#define CLK_PDMA1 269 +#define CLK_PDMA0 270 +#define CLK_SPDIF 271 +#define CLK_PWM 272 +#define CLK_PCM2 273 +#define CLK_PCM1 274 +#define CLK_I2S1 275 +#define CLK_SPI2 276 +#define CLK_SPI1 277 +#define CLK_SPI0 278 +#define CLK_I2CHDMI 279 +#define CLK_I2C7 280 +#define CLK_I2C6 281 +#define CLK_I2C5 282 +#define CLK_I2C4 283 +#define CLK_I2C3 284 +#define CLK_I2C2 285 +#define CLK_I2C1 286 +#define CLK_I2C0 287 +#define CLK_UART3 288 +#define CLK_UART2 289 +#define CLK_UART1 290 +#define CLK_UART0 291 + +/* Special clocks */ +#define CLK_SCLK_PXLAYSNC_CSIS1_FIMC 330 +#define CLK_SCLK_PXLAYSNC_CSIS0_FIMC 331 +#define CLK_SCLK_JPEG 332 +#define CLK_SCLK_CSIS1 333 +#define CLK_SCLK_CSIS0 334 +#define CLK_SCLK_CAM1 335 +#define CLK_SCLK_FIMC3_LCLK 336 +#define CLK_SCLK_FIMC2_LCLK 337 +#define CLK_SCLK_FIMC1_LCLK 338 +#define CLK_SCLK_FIMC0_LCLK 339 +#define CLK_SCLK_PIXEL 340 +#define CLK_SCLK_HDMI 341 +#define CLK_SCLK_MIXER 342 +#define CLK_SCLK_MFC 343 +#define CLK_SCLK_G3D 344 +#define CLK_SCLK_MIPIDPHY4L 345 +#define CLK_SCLK_MIPI0 346 +#define CLK_SCLK_MDNIE0 347 +#define CLK_SCLK_FIMD0 348 +#define CLK_SCLK_PCM0 349 +#define CLK_SCLK_AUDIO0 350 +#define CLK_SCLK_TSADC 351 +#define CLK_SCLK_EBI 352 +#define CLK_SCLK_MMC2 353 +#define CLK_SCLK_MMC1 354 +#define CLK_SCLK_MMC0 355 +#define CLK_SCLK_I2S 356 +#define CLK_SCLK_PCM2 357 +#define CLK_SCLK_PCM1 358 +#define CLK_SCLK_AUDIO2 359 +#define CLK_SCLK_AUDIO1 360 +#define CLK_SCLK_SPDIF 361 +#define CLK_SCLK_SPI2 362 +#define CLK_SCLK_SPI1 363 +#define CLK_SCLK_SPI0 364 +#define CLK_SCLK_UART3 365 +#define CLK_SCLK_UART2 366 +#define CLK_SCLK_UART1 367 +#define CLK_SCLK_UART0 368 +#define CLK_SCLK_HDMIPHY 369 + +/* + * Total number of clocks of main CMU. + * NOTE: Must be equal to last clock ID increased by one. + */ +#define CLK_NR_CLKS 370 + +/* + * CMU DMC + */ +#define CLK_DMC_FOUT_MPLL 1 +#define CLK_DMC_FOUT_BPLL 2 + +#define CLK_DMC_MOUT_MPLL 3 +#define CLK_DMC_MOUT_BPLL 4 +#define CLK_DMC_MOUT_DPHY 5 +#define CLK_DMC_MOUT_DMC_BUS 6 + +#define CLK_DMC_DIV_DMC 7 +#define CLK_DMC_DIV_DPHY 8 +#define CLK_DMC_DIV_DMC_PRE 9 +#define CLK_DMC_DIV_DMCP 10 +#define CLK_DMC_DIV_DMCD 11 +#define CLK_DMC_DIV_MPLL_PRE 12 + +/* + * Total number of clocks of CMU_DMC. + * NOTE: Must be equal to highest clock ID increased by one. + */ +#define NR_CLKS_DMC 13 + +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H */ -- GitLab From 734cbb5b6bf9ee42ab4d71690fabf486b1f44502 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:53 -0700 Subject: [PATCH 2199/9457] net: dsa: Don't set skb->protocol on outgoing tagged packets Setting skb->protocol to a private protocol type may result in warning messages such as e1000e 0000:00:19.0 em1: checksum_partial proto=dada! This happens if the L3 protocol is IP or IPv6 and skb->ip_summed is set to CHECKSUM_PARTIAL. Looking through the code, it appears that changing skb->protocol for transmitted packets is not necessary and may actually be harmful. For example, it prevents purposely unmodified (from a DSA perspective) network drivers from properly setting up their transmit checksum offload pointers since they inspect skb->protocol to set up the IPv4 header or IPv6 header pointers. So don't unnecessarily change the protocol field. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- net/dsa/tag_dsa.c | 2 -- net/dsa/tag_edsa.c | 2 -- net/dsa/tag_trailer.c | 2 -- 3 files changed, 6 deletions(-) diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index ce90c8bdc658..2dab27063273 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -63,8 +63,6 @@ static netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev) dsa_header[3] = 0x00; } - skb->protocol = htons(ETH_P_DSA); - skb->dev = p->parent->dst->master_netdev; dev_queue_xmit(skb); diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index 94fcce778679..9aeda596f7ec 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c @@ -76,8 +76,6 @@ static netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev) edsa_header[7] = 0x00; } - skb->protocol = htons(ETH_P_EDSA); - skb->dev = p->parent->dst->master_netdev; dev_queue_xmit(skb); diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index 115fdca34077..e268f9db8893 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -57,8 +57,6 @@ static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev) trailer[2] = 0x10; trailer[3] = 0x00; - nskb->protocol = htons(ETH_P_TRAILER); - nskb->dev = p->parent->dst->master_netdev; dev_queue_xmit(nskb); -- GitLab From 3de6aa4c35eaa917b47a387a4092bd53f7afca4b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:54 -0700 Subject: [PATCH 2200/9457] net: dsa: Report known silicon revisions for Marvell 88E6060 Report known silicon revisions when probing Marvell 88E6060 switches. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6060.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c index 05b0ca3bf71d..c29aebe1e62b 100644 --- a/drivers/net/dsa/mv88e6060.c +++ b/drivers/net/dsa/mv88e6060.c @@ -69,8 +69,11 @@ static char *mv88e6060_probe(struct device *host_dev, int sw_addr) ret = mdiobus_read(bus, sw_addr + REG_PORT(0), 0x03); if (ret >= 0) { - ret &= 0xfff0; if (ret == 0x0600) + return "Marvell 88E6060 (A0)"; + if (ret == 0x0601 || ret == 0x0602) + return "Marvell 88E6060 (B0)"; + if ((ret & 0xfff0) == 0x0600) return "Marvell 88E6060"; } -- GitLab From a93e464a45827cbbbfc89183cf4a769b18f31535 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:55 -0700 Subject: [PATCH 2201/9457] net: dsa: Report known silicon revisions for Marvell 88E6131 Report known silicon revisions when probing Marvell 88E6131 switches. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6131.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 244c735014fa..1230f52aa70e 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -21,6 +21,7 @@ #define ID_6085 0x04a0 #define ID_6095 0x0950 #define ID_6131 0x1060 +#define ID_6131_B2 0x1066 static char *mv88e6131_probe(struct device *host_dev, int sw_addr) { @@ -32,12 +33,15 @@ static char *mv88e6131_probe(struct device *host_dev, int sw_addr) ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); if (ret >= 0) { - ret &= 0xfff0; - if (ret == ID_6085) + int ret_masked = ret & 0xfff0; + + if (ret_masked == ID_6085) return "Marvell 88E6085"; - if (ret == ID_6095) + if (ret_masked == ID_6095) return "Marvell 88E6095/88E6095F"; - if (ret == ID_6131) + if (ret == ID_6131_B2) + return "Marvell 88E6131 (B2)"; + if (ret_masked == ID_6131) return "Marvell 88E6131"; } -- GitLab From 3ad50cca3919c08472232a633806f591216732b9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:56 -0700 Subject: [PATCH 2202/9457] net: dsa: Add support for Marvell 88E6352 Marvell 88E6352 is mostly compatible to MV88E6123/61/65, but requires indirect phy access. Also, its configuration registers are a bit different. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- MAINTAINERS | 5 + drivers/net/dsa/Kconfig | 8 + drivers/net/dsa/Makefile | 3 + drivers/net/dsa/mv88e6352.c | 464 ++++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.c | 3 + drivers/net/dsa/mv88e6xxx.h | 7 + 6 files changed, 490 insertions(+) create mode 100644 drivers/net/dsa/mv88e6352.c diff --git a/MAINTAINERS b/MAINTAINERS index 43898b1a8a2d..e4082ec8daeb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5848,6 +5848,11 @@ M: Russell King S: Maintained F: drivers/gpu/drm/armada/ +MARVELL 88E6352 DSA support +M: Guenter Roeck +S: Maintained +F: drivers/net/dsa/mv88e6352.c + MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) M: Mirko Lindner M: Stephen Hemminger diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 9234d808cbb3..0987c336e517 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -45,6 +45,14 @@ config NET_DSA_MV88E6171 This enables support for the Marvell 88E6171 ethernet switch chip. +config NET_DSA_MV88E6352 + tristate "Marvell 88E6352 ethernet switch chip support" + select NET_DSA + select NET_DSA_MV88E6XXX + select NET_DSA_TAG_EDSA + ---help--- + This enables support for the Marvell 88E6352 ethernet switch chip. + config NET_DSA_BCM_SF2 tristate "Broadcom Starfighter 2 Ethernet switch support" depends on HAS_IOMEM diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile index 23a90de9830e..e2d51c4b9382 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -7,6 +7,9 @@ endif ifdef CONFIG_NET_DSA_MV88E6131 mv88e6xxx_drv-y += mv88e6131.o endif +ifdef CONFIG_NET_DSA_MV88E6352 +mv88e6xxx_drv-y += mv88e6352.o +endif ifdef CONFIG_NET_DSA_MV88E6171 mv88e6xxx_drv-y += mv88e6171.o endif diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c new file mode 100644 index 000000000000..43a58262a03d --- /dev/null +++ b/drivers/net/dsa/mv88e6352.c @@ -0,0 +1,464 @@ +/* + * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support + * + * Copyright (c) 2014 Guenter Roeck + * + * Derived from mv88e6123_61_65.c + * Copyright (c) 2008-2009 Marvell Semiconductor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mv88e6xxx.h" + +static int mv88e6352_phy_wait(struct dsa_switch *ds) +{ + unsigned long timeout = jiffies + HZ / 10; + + while (time_before(jiffies, timeout)) { + int ret; + + ret = REG_READ(REG_GLOBAL2, 0x18); + if (ret < 0) + return ret; + + if (!(ret & 0x8000)) + return 0; + + usleep_range(1000, 2000); + } + return -ETIMEDOUT; +} + +static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum) +{ + int ret; + + REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum); + + ret = mv88e6352_phy_wait(ds); + if (ret < 0) + return ret; + + return REG_READ(REG_GLOBAL2, 0x19); +} + +static int __mv88e6352_phy_write(struct dsa_switch *ds, int addr, int regnum, + u16 val) +{ + REG_WRITE(REG_GLOBAL2, 0x19, val); + REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum); + + return mv88e6352_phy_wait(ds); +} + +static char *mv88e6352_probe(struct device *host_dev, int sw_addr) +{ + struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); + int ret; + + if (bus == NULL) + return NULL; + + ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); + if (ret >= 0) { + if (ret == 0x3521) + return "Marvell 88E6352 (A0)"; + if (ret == 0x3522) + return "Marvell 88E6352 (A1)"; + if ((ret & 0xfff0) == 0x3520) + return "Marvell 88E6352"; + } + + return NULL; +} + +static int mv88e6352_switch_reset(struct dsa_switch *ds) +{ + unsigned long timeout; + int ret; + int i; + + /* Set all ports to the disabled state. */ + for (i = 0; i < 7; i++) { + ret = REG_READ(REG_PORT(i), 0x04); + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc); + } + + /* Wait for transmit queues to drain. */ + usleep_range(2000, 4000); + + /* Reset the switch. Keep PPU active (bit 14, undocumented). + * The PPU needs to be active to support indirect phy register + * accesses through global registers 0x18 and 0x19. + */ + REG_WRITE(REG_GLOBAL, 0x04, 0xc000); + + /* Wait up to one second for reset to complete. */ + timeout = jiffies + 1 * HZ; + while (time_before(jiffies, timeout)) { + ret = REG_READ(REG_GLOBAL, 0x00); + if ((ret & 0x8800) == 0x8800) + break; + usleep_range(1000, 2000); + } + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + return 0; +} + +static int mv88e6352_setup_global(struct dsa_switch *ds) +{ + int ret; + int i; + + /* Discard packets with excessive collisions, + * mask all interrupt sources, enable PPU (bit 14, undocumented). + */ + REG_WRITE(REG_GLOBAL, 0x04, 0x6000); + + /* Set the default address aging time to 5 minutes, and + * enable address learn messages to be sent to all message + * ports. + */ + REG_WRITE(REG_GLOBAL, 0x0a, 0x0148); + + /* Configure the priority mapping registers. */ + ret = mv88e6xxx_config_prio(ds); + if (ret < 0) + return ret; + + /* Configure the upstream port, and configure the upstream + * port as the port to which ingress and egress monitor frames + * are to be sent. + */ + REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110)); + + /* Disable remote management for now, and set the switch's + * DSA device number. + */ + REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f); + + /* Send all frames with destination addresses matching + * 01:80:c2:00:00:2x to the CPU port. + */ + REG_WRITE(REG_GLOBAL2, 0x02, 0xffff); + + /* Send all frames with destination addresses matching + * 01:80:c2:00:00:0x to the CPU port. + */ + REG_WRITE(REG_GLOBAL2, 0x03, 0xffff); + + /* Disable the loopback filter, disable flow control + * messages, disable flood broadcast override, disable + * removing of provider tags, disable ATU age violation + * interrupts, disable tag flow control, force flow + * control priority to the highest, and send all special + * multicast frames to the CPU at the highest priority. + */ + REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff); + + /* Program the DSA routing table. */ + for (i = 0; i < 32; i++) { + int nexthop = 0x1f; + + if (i != ds->index && i < ds->dst->pd->nr_chips) + nexthop = ds->pd->rtable[i] & 0x1f; + + REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop); + } + + /* Clear all trunk masks. */ + for (i = 0; i < 8; i++) + REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0x7f); + + /* Clear all trunk mappings. */ + for (i = 0; i < 16; i++) + REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11)); + + /* Disable ingress rate limiting by resetting all ingress + * rate limit registers to their initial state. + */ + for (i = 0; i < 7; i++) + REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8)); + + /* Initialise cross-chip port VLAN table to reset defaults. */ + REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000); + + /* Clear the priority override table. */ + for (i = 0; i < 16; i++) + REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8)); + + /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */ + + return 0; +} + +static int mv88e6352_setup_port(struct dsa_switch *ds, int p) +{ + int addr = REG_PORT(p); + u16 val; + + /* MAC Forcing register: don't force link, speed, duplex + * or flow control state to any particular values on physical + * ports, but force the CPU port and all DSA ports to 1000 Mb/s + * full duplex. + */ + if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p)) + REG_WRITE(addr, 0x01, 0x003e); + else + REG_WRITE(addr, 0x01, 0x0003); + + /* Do not limit the period of time that this port can be + * paused for by the remote end or the period of time that + * this port can pause the remote end. + */ + REG_WRITE(addr, 0x02, 0x0000); + + /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, + * disable Header mode, enable IGMP/MLD snooping, disable VLAN + * tunneling, determine priority by looking at 802.1p and IP + * priority fields (IP prio has precedence), and set STP state + * to Forwarding. + * + * If this is the CPU link, use DSA or EDSA tagging depending + * on which tagging mode was configured. + * + * If this is a link to another switch, use DSA tagging mode. + * + * If this is the upstream port for this switch, enable + * forwarding of unknown unicasts and multicasts. + */ + val = 0x0433; + if (dsa_is_cpu_port(ds, p)) { + if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) + val |= 0x3300; + else + val |= 0x0100; + } + if (ds->dsa_port_mask & (1 << p)) + val |= 0x0100; + if (p == dsa_upstream_port(ds)) + val |= 0x000c; + REG_WRITE(addr, 0x04, val); + + /* Port Control 1: disable trunking. Also, if this is the + * CPU port, enable learn messages to be sent to this port. + */ + REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000); + + /* Port based VLAN map: give each port its own address + * database, allow the CPU port to talk to each of the 'real' + * ports, and allow each of the 'real' ports to only talk to + * the upstream port. + */ + val = (p & 0xf) << 12; + if (dsa_is_cpu_port(ds, p)) + val |= ds->phys_port_mask; + else + val |= 1 << dsa_upstream_port(ds); + REG_WRITE(addr, 0x06, val); + + /* Default VLAN ID and priority: don't set a default VLAN + * ID, and set the default packet priority to zero. + */ + REG_WRITE(addr, 0x07, 0x0000); + + /* Port Control 2: don't force a good FCS, set the maximum + * frame size to 10240 bytes, don't let the switch add or + * strip 802.1q tags, don't discard tagged or untagged frames + * on this port, do a destination address lookup on all + * received packets as usual, disable ARP mirroring and don't + * send a copy of all transmitted/received frames on this port + * to the CPU. + */ + REG_WRITE(addr, 0x08, 0x2080); + + /* Egress rate control: disable egress rate control. */ + REG_WRITE(addr, 0x09, 0x0001); + + /* Egress rate control 2: disable egress rate control. */ + REG_WRITE(addr, 0x0a, 0x0000); + + /* Port Association Vector: when learning source addresses + * of packets, add the address to the address database using + * a port bitmap that has only the bit for this port set and + * the other bits clear. + */ + REG_WRITE(addr, 0x0b, 1 << p); + + /* Port ATU control: disable limiting the number of address + * database entries that this port is allowed to use. + */ + REG_WRITE(addr, 0x0c, 0x0000); + + /* Priority Override: disable DA, SA and VTU priority override. */ + REG_WRITE(addr, 0x0d, 0x0000); + + /* Port Ethertype: use the Ethertype DSA Ethertype value. */ + REG_WRITE(addr, 0x0f, ETH_P_EDSA); + + /* Tag Remap: use an identity 802.1p prio -> switch prio + * mapping. + */ + REG_WRITE(addr, 0x18, 0x3210); + + /* Tag Remap 2: use an identity 802.1p prio -> switch prio + * mapping. + */ + REG_WRITE(addr, 0x19, 0x7654); + + return 0; +} + +static int mv88e6352_setup(struct dsa_switch *ds) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + int i; + + mutex_init(&ps->smi_mutex); + mutex_init(&ps->stats_mutex); + mutex_init(&ps->phy_mutex); + + ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0; + + ret = mv88e6352_switch_reset(ds); + if (ret < 0) + return ret; + + /* @@@ initialise vtu and atu */ + + ret = mv88e6352_setup_global(ds); + if (ret < 0) + return ret; + + for (i = 0; i < 7; i++) { + ret = mv88e6352_setup_port(ds, i); + if (ret < 0) + return ret; + } + + return 0; +} + +static int mv88e6352_port_to_phy_addr(int port) +{ + if (port >= 0 && port <= 4) + return port; + return -EINVAL; +} + +static int +mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int addr = mv88e6352_port_to_phy_addr(port); + int ret; + + if (addr < 0) + return addr; + + mutex_lock(&ps->phy_mutex); + ret = __mv88e6352_phy_read(ds, addr, regnum); + mutex_unlock(&ps->phy_mutex); + + return ret; +} + +static int +mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int addr = mv88e6352_port_to_phy_addr(port); + int ret; + + if (addr < 0) + return addr; + + mutex_lock(&ps->phy_mutex); + ret = __mv88e6352_phy_write(ds, addr, regnum, val); + mutex_unlock(&ps->phy_mutex); + + return ret; +} + +static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = { + { "in_good_octets", 8, 0x00, }, + { "in_bad_octets", 4, 0x02, }, + { "in_unicast", 4, 0x04, }, + { "in_broadcasts", 4, 0x06, }, + { "in_multicasts", 4, 0x07, }, + { "in_pause", 4, 0x16, }, + { "in_undersize", 4, 0x18, }, + { "in_fragments", 4, 0x19, }, + { "in_oversize", 4, 0x1a, }, + { "in_jabber", 4, 0x1b, }, + { "in_rx_error", 4, 0x1c, }, + { "in_fcs_error", 4, 0x1d, }, + { "out_octets", 8, 0x0e, }, + { "out_unicast", 4, 0x10, }, + { "out_broadcasts", 4, 0x13, }, + { "out_multicasts", 4, 0x12, }, + { "out_pause", 4, 0x15, }, + { "excessive", 4, 0x11, }, + { "collisions", 4, 0x1e, }, + { "deferred", 4, 0x05, }, + { "single", 4, 0x14, }, + { "multiple", 4, 0x17, }, + { "out_fcs_error", 4, 0x03, }, + { "late", 4, 0x1f, }, + { "hist_64bytes", 4, 0x08, }, + { "hist_65_127bytes", 4, 0x09, }, + { "hist_128_255bytes", 4, 0x0a, }, + { "hist_256_511bytes", 4, 0x0b, }, + { "hist_512_1023bytes", 4, 0x0c, }, + { "hist_1024_max_bytes", 4, 0x0d, }, +}; + +static void +mv88e6352_get_strings(struct dsa_switch *ds, int port, uint8_t *data) +{ + mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6352_hw_stats), + mv88e6352_hw_stats, port, data); +} + +static void +mv88e6352_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) +{ + mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6352_hw_stats), + mv88e6352_hw_stats, port, data); +} + +static int mv88e6352_get_sset_count(struct dsa_switch *ds) +{ + return ARRAY_SIZE(mv88e6352_hw_stats); +} + +struct dsa_switch_driver mv88e6352_switch_driver = { + .tag_protocol = DSA_TAG_PROTO_EDSA, + .priv_size = sizeof(struct mv88e6xxx_priv_state), + .probe = mv88e6352_probe, + .setup = mv88e6352_setup, + .set_addr = mv88e6xxx_set_addr_indirect, + .phy_read = mv88e6352_phy_read, + .phy_write = mv88e6352_phy_write, + .poll_link = mv88e6xxx_poll_link, + .get_strings = mv88e6352_get_strings, + .get_ethtool_stats = mv88e6352_get_ethtool_stats, + .get_sset_count = mv88e6352_get_sset_count, +}; + +MODULE_ALIAS("platform:mv88e6352"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index a6c90cf5634d..8e1090ba3df3 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -507,6 +507,9 @@ static int __init mv88e6xxx_init(void) #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) register_switch_driver(&mv88e6123_61_65_switch_driver); #endif +#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) + register_switch_driver(&mv88e6352_switch_driver); +#endif #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) register_switch_driver(&mv88e6171_switch_driver); #endif diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 5e5145ad9525..c0ce133c756b 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -37,6 +37,12 @@ struct mv88e6xxx_priv_state { */ struct mutex stats_mutex; + /* This mutex serializes phy access for chips with + * indirect phy addressing. It is unused for chips + * with direct phy access. + */ + struct mutex phy_mutex; + int id; /* switch product id */ }; @@ -70,6 +76,7 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, extern struct dsa_switch_driver mv88e6131_switch_driver; extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; +extern struct dsa_switch_driver mv88e6352_switch_driver; extern struct dsa_switch_driver mv88e6171_switch_driver; #define REG_READ(addr, reg) \ -- GitLab From 2716777b4f21649fb907b4a4fb96e1c8d0a5ec16 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:57 -0700 Subject: [PATCH 2203/9457] net: dsa/mv88e6352: Add support for MV88E6176 MV88E6176 is mostly compatible to MV88E6352 and is documented in the same functional specification. Add support for it. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/Kconfig | 5 +++-- drivers/net/dsa/mv88e6352.c | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 0987c336e517..2d1a55e980da 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -46,12 +46,13 @@ config NET_DSA_MV88E6171 chip. config NET_DSA_MV88E6352 - tristate "Marvell 88E6352 ethernet switch chip support" + tristate "Marvell 88E6176/88E6352 ethernet switch chip support" select NET_DSA select NET_DSA_MV88E6XXX select NET_DSA_TAG_EDSA ---help--- - This enables support for the Marvell 88E6352 ethernet switch chip. + This enables support for the Marvell 88E6176 and 88E6352 ethernet + switch chips. config NET_DSA_BCM_SF2 tristate "Broadcom Starfighter 2 Ethernet switch support" diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 43a58262a03d..f17364ff8f3f 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -73,6 +73,8 @@ static char *mv88e6352_probe(struct device *host_dev, int sw_addr) ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); if (ret >= 0) { + if ((ret & 0xfff0) == 0x1760) + return "Marvell 88E6176"; if (ret == 0x3521) return "Marvell 88E6352 (A0)"; if (ret == 0x3522) -- GitLab From 51579c3f1a9192b75365576227d40c7619493285 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:58 -0700 Subject: [PATCH 2204/9457] net: dsa: Add support for reporting switch chip temperatures Some switches provide chip temperature data. Add support for reporting it through the hwmon subsystem. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- include/net/dsa.h | 16 ++++++ net/dsa/Kconfig | 11 ++++ net/dsa/dsa.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) diff --git a/include/net/dsa.h b/include/net/dsa.h index b76559293535..55e75e7e8d41 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -139,6 +139,14 @@ struct dsa_switch { */ struct device *master_dev; +#ifdef CONFIG_NET_DSA_HWMON + /* + * Hardware monitoring information + */ + char hwmon_name[IFNAMSIZ + 8]; + struct device *hwmon_dev; +#endif + /* * Slave mii_bus and devices for the individual ports. */ @@ -242,6 +250,14 @@ struct dsa_switch_driver { struct ethtool_eee *e); int (*get_eee)(struct dsa_switch *ds, int port, struct ethtool_eee *e); + +#ifdef CONFIG_NET_DSA_HWMON + /* Hardware monitoring */ + int (*get_temp)(struct dsa_switch *ds, int *temp); + int (*get_temp_limit)(struct dsa_switch *ds, int *temp); + int (*set_temp_limit)(struct dsa_switch *ds, int temp); + int (*get_temp_alarm)(struct dsa_switch *ds, bool *alarm); +#endif }; void register_switch_driver(struct dsa_switch_driver *type); diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index a585fd6352eb..5f8ac404535b 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -11,6 +11,17 @@ config NET_DSA if NET_DSA +config NET_DSA_HWMON + bool "Distributed Switch Architecture HWMON support" + default y + depends on HWMON && !(NET_DSA=y && HWMON=m) + ---help--- + Say Y if you want to expose thermal sensor data on switches supported + by the Distributed Switch Architecture. + + Some of those switches contain thermal sensors. This data is available + via the hwmon sysfs interface and exposes the onboard sensors. + # tagging formats config NET_DSA_TAG_BRCM bool diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 22f34cf4cb27..5edbbca89f1f 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -9,6 +9,9 @@ * (at your option) any later version. */ +#include +#include +#include #include #include #include @@ -17,6 +20,7 @@ #include #include #include +#include #include "dsa_priv.h" char dsa_driver_version[] = "0.1"; @@ -71,6 +75,104 @@ dsa_switch_probe(struct device *host_dev, int sw_addr, char **_name) return ret; } +/* hwmon support ************************************************************/ + +#ifdef CONFIG_NET_DSA_HWMON + +static ssize_t temp1_input_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsa_switch *ds = dev_get_drvdata(dev); + int temp, ret; + + ret = ds->drv->get_temp(ds, &temp); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", temp * 1000); +} +static DEVICE_ATTR_RO(temp1_input); + +static ssize_t temp1_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsa_switch *ds = dev_get_drvdata(dev); + int temp, ret; + + ret = ds->drv->get_temp_limit(ds, &temp); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", temp * 1000); +} + +static ssize_t temp1_max_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct dsa_switch *ds = dev_get_drvdata(dev); + int temp, ret; + + ret = kstrtoint(buf, 0, &temp); + if (ret < 0) + return ret; + + ret = ds->drv->set_temp_limit(ds, DIV_ROUND_CLOSEST(temp, 1000)); + if (ret < 0) + return ret; + + return count; +} +static DEVICE_ATTR(temp1_max, S_IRUGO, temp1_max_show, temp1_max_store); + +static ssize_t temp1_max_alarm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsa_switch *ds = dev_get_drvdata(dev); + bool alarm; + int ret; + + ret = ds->drv->get_temp_alarm(ds, &alarm); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", alarm); +} +static DEVICE_ATTR_RO(temp1_max_alarm); + +static struct attribute *dsa_hwmon_attrs[] = { + &dev_attr_temp1_input.attr, /* 0 */ + &dev_attr_temp1_max.attr, /* 1 */ + &dev_attr_temp1_max_alarm.attr, /* 2 */ + NULL +}; + +static umode_t dsa_hwmon_attrs_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct dsa_switch *ds = dev_get_drvdata(dev); + struct dsa_switch_driver *drv = ds->drv; + umode_t mode = attr->mode; + + if (index == 1) { + if (!drv->get_temp_limit) + mode = 0; + else if (drv->set_temp_limit) + mode |= S_IWUSR; + } else if (index == 2 && !drv->get_temp_alarm) { + mode = 0; + } + return mode; +} + +static const struct attribute_group dsa_hwmon_group = { + .attrs = dsa_hwmon_attrs, + .is_visible = dsa_hwmon_attrs_visible, +}; +__ATTRIBUTE_GROUPS(dsa_hwmon); + +#endif /* CONFIG_NET_DSA_HWMON */ /* basic switch operations **************************************************/ static struct dsa_switch * @@ -225,6 +327,31 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, ds->ports[i] = slave_dev; } +#ifdef CONFIG_NET_DSA_HWMON + /* If the switch provides a temperature sensor, + * register with hardware monitoring subsystem. + * Treat registration error as non-fatal and ignore it. + */ + if (drv->get_temp) { + const char *netname = netdev_name(dst->master_netdev); + char hname[IFNAMSIZ + 1]; + int i, j; + + /* Create valid hwmon 'name' attribute */ + for (i = j = 0; i < IFNAMSIZ && netname[i]; i++) { + if (isalnum(netname[i])) + hname[j++] = netname[i]; + } + hname[j] = '\0'; + scnprintf(ds->hwmon_name, sizeof(ds->hwmon_name), "%s_dsa%d", + hname, index); + ds->hwmon_dev = hwmon_device_register_with_groups(NULL, + ds->hwmon_name, ds, dsa_hwmon_groups); + if (IS_ERR(ds->hwmon_dev)) + ds->hwmon_dev = NULL; + } +#endif /* CONFIG_NET_DSA_HWMON */ + return ds; out_free: @@ -236,6 +363,10 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, static void dsa_switch_destroy(struct dsa_switch *ds) { +#ifdef CONFIG_NET_DSA_HWMON + if (ds->hwmon_dev) + hwmon_device_unregister(ds->hwmon_dev); +#endif } #ifdef CONFIG_PM_SLEEP -- GitLab From 276db3b15d859e0339baa256edce7b737cc0848f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:44:59 -0700 Subject: [PATCH 2205/9457] net: dsa/mv88e6352: Report chip temperature MV88E6352 supports reading the chip temperature from two PHY registers, 6:26 and 6:27. Report it using the more accurate register 6:27. Also report temperature limit and alarm. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6352.c | 101 ++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index f17364ff8f3f..744e6fac8023 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -325,6 +325,101 @@ static int mv88e6352_setup_port(struct dsa_switch *ds, int p) return 0; } +#ifdef CONFIG_NET_DSA_HWMON + +static int mv88e6352_phy_page_read(struct dsa_switch *ds, + int port, int page, int reg) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->phy_mutex); + ret = __mv88e6352_phy_write(ds, port, 0x16, page); + if (ret < 0) + goto error; + ret = __mv88e6352_phy_read(ds, port, reg); +error: + __mv88e6352_phy_write(ds, port, 0x16, 0x0); + mutex_unlock(&ps->phy_mutex); + return ret; +} + +static int mv88e6352_phy_page_write(struct dsa_switch *ds, + int port, int page, int reg, int val) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->phy_mutex); + ret = __mv88e6352_phy_write(ds, port, 0x16, page); + if (ret < 0) + goto error; + + ret = __mv88e6352_phy_write(ds, port, reg, val); +error: + __mv88e6352_phy_write(ds, port, 0x16, 0x0); + mutex_unlock(&ps->phy_mutex); + return ret; +} + +static int mv88e6352_get_temp(struct dsa_switch *ds, int *temp) +{ + int ret; + + *temp = 0; + + ret = mv88e6352_phy_page_read(ds, 0, 6, 27); + if (ret < 0) + return ret; + + *temp = (ret & 0xff) - 25; + + return 0; +} + +static int mv88e6352_get_temp_limit(struct dsa_switch *ds, int *temp) +{ + int ret; + + *temp = 0; + + ret = mv88e6352_phy_page_read(ds, 0, 6, 26); + if (ret < 0) + return ret; + + *temp = (((ret >> 8) & 0x1f) * 5) - 25; + + return 0; +} + +static int mv88e6352_set_temp_limit(struct dsa_switch *ds, int temp) +{ + int ret; + + ret = mv88e6352_phy_page_read(ds, 0, 6, 26); + if (ret < 0) + return ret; + temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f); + return mv88e6352_phy_page_write(ds, 0, 6, 26, + (ret & 0xe0ff) | (temp << 8)); +} + +static int mv88e6352_get_temp_alarm(struct dsa_switch *ds, bool *alarm) +{ + int ret; + + *alarm = false; + + ret = mv88e6352_phy_page_read(ds, 0, 6, 26); + if (ret < 0) + return ret; + + *alarm = !!(ret & 0x40); + + return 0; +} +#endif /* CONFIG_NET_DSA_HWMON */ + static int mv88e6352_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -461,6 +556,12 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .get_strings = mv88e6352_get_strings, .get_ethtool_stats = mv88e6352_get_ethtool_stats, .get_sset_count = mv88e6352_get_sset_count, +#ifdef CONFIG_NET_DSA_HWMON + .get_temp = mv88e6352_get_temp, + .get_temp_limit = mv88e6352_get_temp_limit, + .set_temp_limit = mv88e6352_set_temp_limit, + .get_temp_alarm = mv88e6352_get_temp_alarm, +#endif }; MODULE_ALIAS("platform:mv88e6352"); -- GitLab From 87e5f66b3723b2d912b565bf7100e5121f302cbf Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:00 -0700 Subject: [PATCH 2206/9457] net: dsa/mv88e6123_61_65: Report chip temperature MV88E6123 and compatible chips support reading the chip temperature from PHY register 6:26. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123_61_65.c | 68 ++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c index a332c53ff955..9f43c9b94150 100644 --- a/drivers/net/dsa/mv88e6123_61_65.c +++ b/drivers/net/dsa/mv88e6123_61_65.c @@ -291,6 +291,54 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p) return 0; } +#ifdef CONFIG_NET_DSA_HWMON + +static int mv88e6123_61_65_get_temp(struct dsa_switch *ds, int *temp) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + int val; + + *temp = 0; + + mutex_lock(&ps->phy_mutex); + + ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); + if (ret < 0) + goto error; + + /* Enable temperature sensor */ + ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a); + if (ret < 0) + goto error; + + ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); + if (ret < 0) + goto error; + + /* Wait for temperature to stabilize */ + usleep_range(10000, 12000); + + val = mv88e6xxx_phy_read(ds, 0x0, 0x1a); + if (val < 0) { + ret = val; + goto error; + } + + /* Disable temperature sensor */ + ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); + if (ret < 0) + goto error; + + *temp = ((val & 0x1f) - 5) * 5; + +error: + mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); + mutex_unlock(&ps->phy_mutex); + return ret; +} +#endif /* CONFIG_NET_DSA_HWMON */ + static int mv88e6123_61_65_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -299,6 +347,7 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds) mutex_init(&ps->smi_mutex); mutex_init(&ps->stats_mutex); + mutex_init(&ps->phy_mutex); ret = mv88e6123_61_65_switch_reset(ds); if (ret < 0) @@ -329,16 +378,28 @@ static int mv88e6123_61_65_port_to_phy_addr(int port) static int mv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int addr = mv88e6123_61_65_port_to_phy_addr(port); - return mv88e6xxx_phy_read(ds, addr, regnum); + int ret; + + mutex_lock(&ps->phy_mutex); + ret = mv88e6xxx_phy_read(ds, addr, regnum); + mutex_unlock(&ps->phy_mutex); + return ret; } static int mv88e6123_61_65_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int addr = mv88e6123_61_65_port_to_phy_addr(port); - return mv88e6xxx_phy_write(ds, addr, regnum, val); + int ret; + + mutex_lock(&ps->phy_mutex); + ret = mv88e6xxx_phy_write(ds, addr, regnum, val); + mutex_unlock(&ps->phy_mutex); + return ret; } static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = { @@ -406,6 +467,9 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = { .get_strings = mv88e6123_61_65_get_strings, .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats, .get_sset_count = mv88e6123_61_65_get_sset_count, +#ifdef CONFIG_NET_DSA_HWMON + .get_temp = mv88e6123_61_65_get_temp, +#endif }; MODULE_ALIAS("platform:mv88e6123"); -- GitLab From 6793abb4e8491b1d673ccfd09e1a73d1ff8b9386 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:01 -0700 Subject: [PATCH 2207/9457] net: dsa: Add support for switch EEPROM access On some chips it is possible to access the switch eeprom. Add infrastructure support for it. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- include/net/dsa.h | 10 ++++++++++ net/dsa/dsa.c | 4 ++++ net/dsa/slave.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/net/dsa.h b/include/net/dsa.h index 55e75e7e8d41..37856a28c8d3 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -38,6 +38,9 @@ struct dsa_chip_data { struct device *host_dev; int sw_addr; + /* set to size of eeprom if supported by the switch */ + int eeprom_len; + /* Device tree node pointer for this specific switch chip * used during switch setup in case additional properties * and resources needs to be used @@ -258,6 +261,13 @@ struct dsa_switch_driver { int (*set_temp_limit)(struct dsa_switch *ds, int temp); int (*get_temp_alarm)(struct dsa_switch *ds, bool *alarm); #endif + + /* EEPROM access */ + int (*get_eeprom_len)(struct dsa_switch *ds); + int (*get_eeprom)(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data); + int (*set_eeprom)(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data); }; void register_switch_driver(struct dsa_switch_driver *type); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 5edbbca89f1f..b51ef592f0a2 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -575,6 +575,7 @@ static int dsa_of_probe(struct platform_device *pdev) const char *port_name; int chip_index, port_index; const unsigned int *sw_addr, *port_reg; + u32 eeprom_len; int ret; mdio = of_parse_phandle(np, "dsa,mii-bus", 0); @@ -626,6 +627,9 @@ static int dsa_of_probe(struct platform_device *pdev) if (cd->sw_addr > PHY_MAX_ADDR) continue; + if (!of_property_read_u32(np, "eeprom-length", &eeprom_len)) + cd->eeprom_len = eeprom_len; + for_each_available_child_of_node(child, port) { port_reg = of_get_property(port, "reg", NULL); if (!port_reg) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 6d1817449c36..ff2fbe79bc57 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -271,6 +271,44 @@ static u32 dsa_slave_get_link(struct net_device *dev) return -EOPNOTSUPP; } +static int dsa_slave_get_eeprom_len(struct net_device *dev) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + if (ds->pd->eeprom_len) + return ds->pd->eeprom_len; + + if (ds->drv->get_eeprom_len) + return ds->drv->get_eeprom_len(ds); + + return 0; +} + +static int dsa_slave_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + if (ds->drv->get_eeprom) + return ds->drv->get_eeprom(ds, eeprom, data); + + return -EOPNOTSUPP; +} + +static int dsa_slave_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + if (ds->drv->set_eeprom) + return ds->drv->set_eeprom(ds, eeprom, data); + + return -EOPNOTSUPP; +} + static void dsa_slave_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { @@ -387,6 +425,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = { .get_drvinfo = dsa_slave_get_drvinfo, .nway_reset = dsa_slave_nway_reset, .get_link = dsa_slave_get_link, + .get_eeprom_len = dsa_slave_get_eeprom_len, + .get_eeprom = dsa_slave_get_eeprom, + .set_eeprom = dsa_slave_set_eeprom, .get_strings = dsa_slave_get_strings, .get_ethtool_stats = dsa_slave_get_ethtool_stats, .get_sset_count = dsa_slave_get_sset_count, -- GitLab From 06745729c48e3677a64db63481184cc7aef1ea69 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:02 -0700 Subject: [PATCH 2208/9457] dsa: Add new optional devicetree property to describe EEPROM size The dsa core now supports reading from and writing to a switch EEPROM if connected. Describe optional devicetree property indicating that an EEPROM is present and its size. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dsa/dsa.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt index a62c889aafca..e124847443f8 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa.txt +++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt @@ -10,7 +10,7 @@ Required properties: - dsa,ethernet : Should be a phandle to a valid Ethernet device node - dsa,mii-bus : Should be a phandle to a valid MDIO bus device node -Optionnal properties: +Optional properties: - interrupts : property with a value describing the switch interrupt number (not supported by the driver) @@ -23,6 +23,13 @@ Each of these switch child nodes should have the following required properties: - #address-cells : Must be 1 - #size-cells : Must be 0 +A switch child node has the following optional property: + +- eeprom-length : Set to the length of an EEPROM connected to the + switch. Must be set if the switch can not detect + the presence and/or size of a connected EEPROM, + otherwise optional. + A switch may have multiple "port" children nodes Each port children node must have the following mandatory properties: -- GitLab From 33b43df40a3827365ff80fae79f7c59c107508d3 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:03 -0700 Subject: [PATCH 2209/9457] net: dsa/mv88e6352: Implement EEPROM access functions MV88E6352 supports read and write access to its configuration eeprom. There is no means to detect if an EEPROM is connected to the switch. Also, the switch supports EEPROMs with different sizes, but can not detect or report the type or size of connected EEPROMs. Therefore, do not implement the get_eeprom_len callback but depend on platform or devicetree data to provide information about EEPROM presence and size. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6352.c | 222 +++++++++++++++++++++++++++++++++++- drivers/net/dsa/mv88e6xxx.h | 5 + 2 files changed, 224 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 744e6fac8023..8a956f9364a2 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -22,18 +22,18 @@ #include #include "mv88e6xxx.h" -static int mv88e6352_phy_wait(struct dsa_switch *ds) +static int mv88e6352_wait(struct dsa_switch *ds, int reg, u16 mask) { unsigned long timeout = jiffies + HZ / 10; while (time_before(jiffies, timeout)) { int ret; - ret = REG_READ(REG_GLOBAL2, 0x18); + ret = REG_READ(REG_GLOBAL2, reg); if (ret < 0) return ret; - if (!(ret & 0x8000)) + if (!(ret & mask)) return 0; usleep_range(1000, 2000); @@ -41,6 +41,21 @@ static int mv88e6352_phy_wait(struct dsa_switch *ds) return -ETIMEDOUT; } +static inline int mv88e6352_phy_wait(struct dsa_switch *ds) +{ + return mv88e6352_wait(ds, 0x18, 0x8000); +} + +static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds) +{ + return mv88e6352_wait(ds, 0x14, 0x0800); +} + +static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds) +{ + return mv88e6352_wait(ds, 0x14, 0x8000); +} + static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum) { int ret; @@ -429,6 +444,7 @@ static int mv88e6352_setup(struct dsa_switch *ds) mutex_init(&ps->smi_mutex); mutex_init(&ps->stats_mutex); mutex_init(&ps->phy_mutex); + mutex_init(&ps->eeprom_mutex); ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0; @@ -525,6 +541,204 @@ static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = { { "hist_1024_max_bytes", 4, 0x0d, }, }; +static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->eeprom_mutex); + + ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14, + 0xc000 | (addr & 0xff)); + if (ret < 0) + goto error; + + ret = mv88e6352_eeprom_busy_wait(ds); + if (ret < 0) + goto error; + + ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x15); +error: + mutex_unlock(&ps->eeprom_mutex); + return ret; +} + +static int mv88e6352_get_eeprom(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data) +{ + int offset; + int len; + int ret; + + offset = eeprom->offset; + len = eeprom->len; + eeprom->len = 0; + + eeprom->magic = 0xc3ec4951; + + ret = mv88e6352_eeprom_load_wait(ds); + if (ret < 0) + return ret; + + if (offset & 1) { + int word; + + word = mv88e6352_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = (word >> 8) & 0xff; + + offset++; + len--; + eeprom->len++; + } + + while (len >= 2) { + int word; + + word = mv88e6352_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = word & 0xff; + *data++ = (word >> 8) & 0xff; + + offset += 2; + len -= 2; + eeprom->len += 2; + } + + if (len) { + int word; + + word = mv88e6352_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + *data++ = word & 0xff; + + offset++; + len--; + eeprom->len++; + } + + return 0; +} + +static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds) +{ + int ret; + + ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x14); + if (ret < 0) + return ret; + + if (!(ret & 0x0400)) + return -EROFS; + + return 0; +} + +static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, + u16 data) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + + mutex_lock(&ps->eeprom_mutex); + + ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x15, data); + if (ret < 0) + goto error; + + ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14, + 0xb000 | (addr & 0xff)); + if (ret < 0) + goto error; + + ret = mv88e6352_eeprom_busy_wait(ds); +error: + mutex_unlock(&ps->eeprom_mutex); + return ret; +} + +static int mv88e6352_set_eeprom(struct dsa_switch *ds, + struct ethtool_eeprom *eeprom, u8 *data) +{ + int offset; + int ret; + int len; + + if (eeprom->magic != 0xc3ec4951) + return -EINVAL; + + ret = mv88e6352_eeprom_is_readonly(ds); + if (ret) + return ret; + + offset = eeprom->offset; + len = eeprom->len; + eeprom->len = 0; + + ret = mv88e6352_eeprom_load_wait(ds); + if (ret < 0) + return ret; + + if (offset & 1) { + int word; + + word = mv88e6352_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + word = (*data++ << 8) | (word & 0xff); + + ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset++; + len--; + eeprom->len++; + } + + while (len >= 2) { + int word; + + word = *data++; + word |= *data++ << 8; + + ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset += 2; + len -= 2; + eeprom->len += 2; + } + + if (len) { + int word; + + word = mv88e6352_read_eeprom_word(ds, offset >> 1); + if (word < 0) + return word; + + word = (word & 0xff00) | *data++; + + ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); + if (ret < 0) + return ret; + + offset++; + len--; + eeprom->len++; + } + + return 0; +} + static void mv88e6352_get_strings(struct dsa_switch *ds, int port, uint8_t *data) { @@ -562,6 +776,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .set_temp_limit = mv88e6352_set_temp_limit, .get_temp_alarm = mv88e6352_get_temp_alarm, #endif + .get_eeprom = mv88e6352_get_eeprom, + .set_eeprom = mv88e6352_set_eeprom, }; MODULE_ALIAS("platform:mv88e6352"); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index c0ce133c756b..29feed02f484 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -43,6 +43,11 @@ struct mv88e6xxx_priv_state { */ struct mutex phy_mutex; + /* This mutex serializes eeprom access for chips with + * eeprom support. + */ + struct mutex eeprom_mutex; + int id; /* switch product id */ }; -- GitLab From 3d762a0f0ab9cb4a6b5993db3ce56c92f9f90ab2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:04 -0700 Subject: [PATCH 2210/9457] net: dsa: Add support for reading switch registers with ethtool Add support for reading switch registers with 'ethtool -d'. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- include/net/dsa.h | 7 +++++++ net/dsa/slave.c | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/net/dsa.h b/include/net/dsa.h index 37856a28c8d3..ed3c34bbb67a 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -268,6 +268,13 @@ struct dsa_switch_driver { struct ethtool_eeprom *eeprom, u8 *data); int (*set_eeprom)(struct dsa_switch *ds, struct ethtool_eeprom *eeprom, u8 *data); + + /* + * Register access. + */ + int (*get_regs_len)(struct dsa_switch *ds, int port); + void (*get_regs)(struct dsa_switch *ds, int port, + struct ethtool_regs *regs, void *p); }; void register_switch_driver(struct dsa_switch_driver *type); diff --git a/net/dsa/slave.c b/net/dsa/slave.c index ff2fbe79bc57..474f2962590a 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -249,6 +249,27 @@ static void dsa_slave_get_drvinfo(struct net_device *dev, strlcpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info)); } +static int dsa_slave_get_regs_len(struct net_device *dev) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + if (ds->drv->get_regs_len) + return ds->drv->get_regs_len(ds, p->port); + + return -EOPNOTSUPP; +} + +static void +dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + if (ds->drv->get_regs) + ds->drv->get_regs(ds, p->port, regs, _p); +} + static int dsa_slave_nway_reset(struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); @@ -423,6 +444,8 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = { .get_settings = dsa_slave_get_settings, .set_settings = dsa_slave_set_settings, .get_drvinfo = dsa_slave_get_drvinfo, + .get_regs_len = dsa_slave_get_regs_len, + .get_regs = dsa_slave_get_regs, .nway_reset = dsa_slave_nway_reset, .get_link = dsa_slave_get_link, .get_eeprom_len = dsa_slave_get_eeprom_len, -- GitLab From a1ab91f3deadc398675de3b9ff297c1f66b5b1f9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:05 -0700 Subject: [PATCH 2211/9457] net: dsa/mv88e6123_61_65: Add support for reading switch registers The infrastructure can now report switch registers to ethtool. Add support for it to the mv88e6123_61_65 driver. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123_61_65.c | 2 ++ drivers/net/dsa/mv88e6xxx.c | 24 ++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 3 +++ 3 files changed, 29 insertions(+) diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c index 9f43c9b94150..e2d2e37e9497 100644 --- a/drivers/net/dsa/mv88e6123_61_65.c +++ b/drivers/net/dsa/mv88e6123_61_65.c @@ -470,6 +470,8 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = { #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6123_61_65_get_temp, #endif + .get_regs_len = mv88e6xxx_get_regs_len, + .get_regs = mv88e6xxx_get_regs, }; MODULE_ALIAS("platform:mv88e6123"); diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 8e1090ba3df3..c071fde21f4a 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -499,6 +499,30 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, mutex_unlock(&ps->stats_mutex); } +int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) +{ + return 32 * sizeof(u16); +} + +void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, + struct ethtool_regs *regs, void *_p) +{ + u16 *p = _p; + int i; + + regs->version = 0; + + memset(p, 0xff, 32 * sizeof(u16)); + + for (i = 0; i < 32; i++) { + int ret; + + ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i); + if (ret >= 0) + p[i] = ret; + } +} + static int __init mv88e6xxx_init(void) { #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 29feed02f484..a0780b08bb4c 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -78,6 +78,9 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds, void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int nr_stats, struct mv88e6xxx_hw_stat *stats, int port, uint64_t *data); +int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port); +void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, + struct ethtool_regs *regs, void *_p); extern struct dsa_switch_driver mv88e6131_switch_driver; extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; -- GitLab From 95d08b5a4a4c96daf6c464dcfd21fb18141846af Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:06 -0700 Subject: [PATCH 2212/9457] net: dsa/mv88e6352: Add support for reading switch registers Report switch register values to ethtool. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6352.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 8a956f9364a2..d5bbe497de9d 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -778,6 +778,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { #endif .get_eeprom = mv88e6352_get_eeprom, .set_eeprom = mv88e6352_set_eeprom, + .get_regs_len = mv88e6xxx_get_regs_len, + .get_regs = mv88e6xxx_get_regs, }; MODULE_ALIAS("platform:mv88e6352"); -- GitLab From 17ee3e04ddbf921e723fd0b0877220791f6f4c9a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 29 Oct 2014 10:45:07 -0700 Subject: [PATCH 2213/9457] net: dsa: Provide additional RMON statistics Display sw_in_discards, sw_in_filtered, and sw_out_filtered for chips supported by mv88e6123_61_65 and mv88e6352 drivers. The variables are provided in port registers, not the normal status registers. Mark by adding 0x100 to the register offset and add special handling code to mv88e6xxx_get_ethtool_stats. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123_61_65.c | 3 +++ drivers/net/dsa/mv88e6352.c | 3 +++ drivers/net/dsa/mv88e6xxx.c | 26 +++++++++++++++++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c index e2d2e37e9497..9a3f9e0b0532 100644 --- a/drivers/net/dsa/mv88e6123_61_65.c +++ b/drivers/net/dsa/mv88e6123_61_65.c @@ -433,6 +433,9 @@ static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = { { "hist_256_511bytes", 4, 0x0b, }, { "hist_512_1023bytes", 4, 0x0c, }, { "hist_1024_max_bytes", 4, 0x0d, }, + { "sw_in_discards", 4, 0x110, }, + { "sw_in_filtered", 2, 0x112, }, + { "sw_out_filtered", 2, 0x113, }, }; static void diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index d5bbe497de9d..258d9ef5ef25 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -539,6 +539,9 @@ static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = { { "hist_256_511bytes", 4, 0x0b, }, { "hist_512_1023bytes", 4, 0x0c, }, { "hist_1024_max_bytes", 4, 0x0d, }, + { "sw_in_discards", 4, 0x110, }, + { "sw_in_filtered", 2, 0x112, }, + { "sw_out_filtered", 2, 0x113, }, }; static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index c071fde21f4a..da558d887dad 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -485,17 +485,33 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, for (i = 0; i < nr_stats; i++) { struct mv88e6xxx_hw_stat *s = stats + i; u32 low; - u32 high; - + u32 high = 0; + + if (s->reg >= 0x100) { + int ret; + + ret = mv88e6xxx_reg_read(ds, REG_PORT(port), + s->reg - 0x100); + if (ret < 0) + goto error; + low = ret; + if (s->sizeof_stat == 4) { + ret = mv88e6xxx_reg_read(ds, REG_PORT(port), + s->reg - 0x100 + 1); + if (ret < 0) + goto error; + high = ret; + } + data[i] = (((u64)high) << 16) | low; + continue; + } mv88e6xxx_stats_read(ds, s->reg, &low); if (s->sizeof_stat == 8) mv88e6xxx_stats_read(ds, s->reg + 1, &high); - else - high = 0; data[i] = (((u64)high) << 32) | low; } - +error: mutex_unlock(&ps->stats_mutex); } -- GitLab From d11a383509032baced195e5812d035c4068ee60c Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Mon, 29 Sep 2014 11:17:36 -0300 Subject: [PATCH 2214/9457] [media] cx23885: add IR for DVBSky T9580 Dual DVB-S2/T2/C PCIe card DVBSky T9580 uses Integrated CX23885 IR controller to decode IR signal. The IR type of DVBSky remote control is RC5. Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 3 +++ drivers/media/pci/cx23885/cx23885-input.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index e8965e63eb09..c4a69e404c3b 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -1659,6 +1659,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: + case CX23885_BOARD_DVBSKY_T9580: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1705,6 +1706,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: + case CX23885_BOARD_DVBSKY_T9580: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1752,6 +1754,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: + case CX23885_BOARD_DVBSKY_T9580: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 9d37fe661691..f81c2f9f0e92 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -87,6 +87,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: + case CX23885_BOARD_DVBSKY_T9580: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -139,6 +140,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_MYGICA_X8507: + case CX23885_BOARD_DVBSKY_T9580: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -305,6 +307,12 @@ int cx23885_input_init(struct cx23885_dev *dev) /* A guess at the remote */ rc_map = RC_MAP_TBS_NEC; break; + case CX23885_BOARD_DVBSKY_T9580: + /* Integrated CX23885 IR controller */ + driver_type = RC_DRIVER_IR_RAW; + allowed_protos = RC_BIT_ALL; + rc_map = RC_MAP_DVBSKY; + break; default: return -ENODEV; } -- GitLab From 2279948735609d0d17d7384e776b674619f792ef Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Mon, 29 Sep 2014 15:17:35 -0300 Subject: [PATCH 2215/9457] [media] af9005: fix kernel panic on init if compiled without IR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patches fixes an ancient bug in the dvb_usb_af9005 driver, which has been reported at least in the following threads: https://lkml.org/lkml/2009/2/4/350 https://lkml.org/lkml/2014/9/18/558 If the driver is compiled in without any IR support (neither DVB_USB_AF9005_REMOTE nor custom symbols), the symbol_request calls in af9005_usb_module_init() return pointers != NULL although the IR symbols are not available. This leads to the following oops: ... [ 8.529751] usbcore: registered new interface driver dvb_usb_af9005 [ 8.531584] BUG: unable to handle kernel paging request at 02e00000 [ 8.533385] IP: [<7d9d67c6>] af9005_usb_module_init+0x6b/0x9d [ 8.535613] *pde = 00000000 [ 8.536416] Oops: 0000 [#1] PREEMPT PREEMPT DEBUG_PAGEALLOCDEBUG_PAGEALLOC [ 8.537863] CPU: 0 PID: 1 Comm: swapper Not tainted 3.15.0-rc6-00151-ga5c075c #1 [ 8.539827] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 [ 8.541519] task: 89c9a670 ti: 89c9c000 task.ti: 89c9c000 [ 8.541519] EIP: 0060:[<7d9d67c6>] EFLAGS: 00010206 CPU: 0 [ 8.541519] EIP is at af9005_usb_module_init+0x6b/0x9d [ 8.541519] EAX: 02e00000 EBX: 00000000 ECX: 00000006 EDX: 00000000 [ 8.541519] ESI: 00000000 EDI: 7da33ec8 EBP: 89c9df30 ESP: 89c9df2c [ 8.541519] DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 [ 8.541519] CR0: 8005003b CR2: 02e00000 CR3: 05a54000 CR4: 00000690 [ 8.541519] Stack: [ 8.541519] 7d9d675b 89c9df90 7d992a49 7d7d5914 89c9df4c 7be3a800 7d08c58c 8a4c3968 [ 8.541519] 89c9df80 7be3a966 00000192 00000006 00000006 7d7d3ff4 8a4c397a 00000200 [ 8.541519] 7d6b1280 8a4c3979 00000006 000009a6 7da32db8 b13eec81 00000006 000009a6 [ 8.541519] Call Trace: [ 8.541519] [<7d9d675b>] ? ttusb2_driver_init+0x16/0x16 [ 8.541519] [<7d992a49>] do_one_initcall+0x77/0x106 [ 8.541519] [<7be3a800>] ? parameqn+0x2/0x35 [ 8.541519] [<7be3a966>] ? parse_args+0x113/0x25c [ 8.541519] [<7d992bc2>] kernel_init_freeable+0xea/0x167 [ 8.541519] [<7cf01070>] kernel_init+0x8/0xb8 [ 8.541519] [<7cf27ec0>] ret_from_kernel_thread+0x20/0x30 [ 8.541519] [<7cf01068>] ? rest_init+0x10c/0x10c [ 8.541519] Code: 08 c2 c7 05 44 ed f9 7d 00 00 e0 02 c7 05 40 ed f9 7d 00 00 e0 02 c7 05 3c ed f9 7d 00 00 e0 02 75 1f b8 00 00 e0 02 85 c0 74 16 00 00 e0 02 c7 05 54 84 8e 7d 00 00 e0 02 a3 58 84 8e 7d eb [ 8.541519] EIP: [<7d9d67c6>] af9005_usb_module_init+0x6b/0x9d SS:ESP 0068:89c9df2c [ 8.541519] CR2: 0000000002e00000 [ 8.541519] ---[ end trace 768b6faf51370fc7 ]--- The prefered fix would be to convert the whole IR code to use the kernel IR infrastructure (which wasn't available at the time this driver had been created). Until anyone who still has this old hardware steps up an does the conversion, fix it by not calling the symbol_request calls if the driver is compiled in without the default IR symbols (CONFIG_DVB_USB_AF9005_REMOTE). Due to the IR related pointers beeing NULL by default, IR support will then be disabled. The downside of this solution is, that it will no longer be possible to compile custom IR symbols (not using CONFIG_DVB_USB_AF9005_REMOTE) in. Please note that this patch has NOT been tested with all possible cases. I don't have the hardware and could only verify that it fixes the reported bug. Reported-by: Fengguag Wu Signed-off-by: Frank Schäfer Cc: Acked-by: Luca Olivetti Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/af9005.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c index 3f4361e48a32..efa782ed6e2d 100644 --- a/drivers/media/usb/dvb-usb/af9005.c +++ b/drivers/media/usb/dvb-usb/af9005.c @@ -1081,9 +1081,12 @@ static int __init af9005_usb_module_init(void) err("usb_register failed. (%d)", result); return result; } +#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE) + /* FIXME: convert to todays kernel IR infrastructure */ rc_decode = symbol_request(af9005_rc_decode); rc_keys = symbol_request(rc_map_af9005_table); rc_keys_size = symbol_request(rc_map_af9005_table_size); +#endif if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { err("af9005_rc_decode function not found, disabling remote"); af9005_properties.rc.legacy.rc_query = NULL; -- GitLab From 37fa8716e2d4c4155205aa4a904835de09edbb88 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Tue, 30 Sep 2014 10:32:08 -0300 Subject: [PATCH 2216/9457] [media] rc-main: fix lockdep splash for rc-main lockdep reports a potential circular dependecy deadlock when registering input device. Unlock mutex rc_dev->lock prior to calling ir_raw_event_register to avoid the circular dependency since that function also calls input_register_device and rc_open. ====================================================== [ INFO: possible circular locking dependency detected ] 3.17.0-rc7+ #24 Not tainted ------------------------------------------------------- modprobe/647 is trying to acquire lock: (input_mutex){+.+.+.}, at: [] input_register_device+0x2ba/0x381 but task is already holding lock: (ir_raw_handler_lock){+.+.+.}, at: [] ir_raw_event_register+0x102/0x190 which lock already depends on the new lock. [cut text] other info that might help us debug this: Chain exists of: input_mutex --> &dev->lock --> ir_raw_handler_lock Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(ir_raw_handler_lock); lock(&dev->lock); lock(ir_raw_handler_lock); lock(input_mutex); *** DEADLOCK *** 4 locks held by modprobe/647: #0: (&dev->mutex){......}, at: [] device_lock+0xf/0x11 #1: (&dev->mutex){......}, at: [] device_lock+0xf/0x11 #2: (&dev->lock){+.+.+.}, at: [] rc_register_device+0x55d/0x58a #3: (ir_raw_handler_lock){+.+.+.}, at: [] ir_raw_event_register+0x102/0x190 stack backtrace: CPU: 0 PID: 647 Comm: modprobe Not tainted 3.17.0-rc7+ #24 Call Trace: [] dump_stack+0x46/0x58 [] print_circular_bug+0x1f8/0x209 [] __lock_acquire+0xb54/0xeda [] ? console_unlock+0x34d/0x399 [] lock_acquire+0xd9/0x111 [] ? input_register_device+0x2ba/0x381 [] mutex_lock_interruptible_nested+0x57/0x381 [] ? input_register_device+0x2ba/0x381 [] ? kfree+0x7c/0x96 [] ? input_register_device+0x2ba/0x381 [] ? trace_hardirqs_on+0xd/0xf [] input_register_device+0x2ba/0x381 [] ir_mce_kbd_register+0x109/0x139 [] ir_raw_event_register+0x13d/0x190 [] rc_register_device+0x39e/0x58a [] ? trace_hardirqs_on+0xd/0xf [] nvt_probe+0x5ad/0xd52 [nuvoton_cir] [] ? nvt_resume+0x80/0x80 [nuvoton_cir] [] pnp_device_probe+0x8c/0xa9 [] ? driver_sysfs_add+0x6e/0x93 [] driver_probe_device+0xa1/0x1e3 [] ? driver_probe_device+0x1e3/0x1e3 [] __driver_attach+0x4e/0x6f [] bus_for_each_dev+0x5a/0x8c [] driver_attach+0x19/0x1b [] bus_add_driver+0xf1/0x1d6 [] driver_register+0x87/0xbe [] ? 0xffffffffa0120000 [] pnp_register_driver+0x1c/0x1e [] nvt_init+0x10/0x1000 [nuvoton_cir] [] do_one_initcall+0xea/0x18c [] ? __vunmap+0x9d/0xc7 [] load_module+0x1c21/0x1f2c [] ? show_initstate+0x44/0x44 [] SyS_init_module+0xa2/0xb1 [] system_call_fastpath+0x16/0x1b Signed-off-by: Tomas Melin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a7991c7d010a..296de853a25d 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1414,7 +1414,10 @@ int rc_register_device(struct rc_dev *dev) ir_raw_init(); raw_init = true; } + /* calls ir_register_device so unlock mutex here*/ + mutex_unlock(&dev->lock); rc = ir_raw_event_register(dev); + mutex_lock(&dev->lock); if (rc < 0) goto out_input; } -- GitLab From 7c894a3b34abd6f8695fc68ff2b009172fb0fab2 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:53 -0300 Subject: [PATCH 2217/9457] [media] cx231xx: let i2c bus scanning use its own i2c_client This is a preparation for deleting the otherwise useless i2c_clients that are allocated for all the i2c master adapters. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 17 +++++++++++------ drivers/media/usb/cx231xx/cx231xx.h | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 7c0f797f1057..67a13912fbe8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -480,22 +480,27 @@ static char *i2c_devs[128] = { * cx231xx_do_i2c_scan() * check i2c address range for devices */ -void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c) +void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) { unsigned char buf; int i, rc; + struct i2c_client client; - cx231xx_info(": Checking for I2C devices ..\n"); + memset(&client, 0, sizeof(client)); + client.adapter = &dev->i2c_bus[i2c_port].i2c_adap; + + cx231xx_info(": Checking for I2C devices on port=%d ..\n", i2c_port); for (i = 0; i < 128; i++) { - c->addr = i; - rc = i2c_master_recv(c, &buf, 0); + client.addr = i; + rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } - cx231xx_info(": Completed Checking for I2C devices.\n"); + cx231xx_info(": Completed Checking for I2C devices on port=%d.\n", + i2c_port); } /* @@ -522,7 +527,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) if (0 == bus->i2c_rc) { if (i2c_scan) - cx231xx_do_i2c_scan(dev, &bus->i2c_client); + cx231xx_do_i2c_scan(dev, bus->nr); } else cx231xx_warn("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index aeb1bf42b88d..5efc93efe96d 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -751,7 +751,7 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq); int cx231xx_reset_analog_tuner(struct cx231xx *dev); /* Provided by cx231xx-i2c.c */ -void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c); +void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); -- GitLab From 9c672890619b9dbedb38d10575ad0c901c079231 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:54 -0300 Subject: [PATCH 2218/9457] [media] cx231xx: use own i2c_client for eeprom access This is a preparation for deleting the otherwise useless i2c_clients that are allocated for all the i2c master adapters. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 791f00c6276b..092fb85ae166 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -980,23 +980,20 @@ static void cx231xx_config_tuner(struct cx231xx *dev) } -static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len) +static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, + u8 *eedata, int len) { int ret = 0; - u8 addr = 0xa0 >> 1; u8 start_offset = 0; int len_todo = len; u8 *eedata_cur = eedata; int i; - struct i2c_msg msg_write = { .addr = addr, .flags = 0, + struct i2c_msg msg_write = { .addr = client->addr, .flags = 0, .buf = &start_offset, .len = 1 }; - struct i2c_msg msg_read = { .addr = addr, .flags = I2C_M_RD }; - - /* mutex_lock(&dev->i2c_lock); */ - cx231xx_enable_i2c_port_3(dev, false); + struct i2c_msg msg_read = { .addr = client->addr, .flags = I2C_M_RD }; /* start reading at offset 0 */ - ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_write, 1); + ret = i2c_transfer(client->adapter, &msg_write, 1); if (ret < 0) { cx231xx_err("Can't read eeprom\n"); return ret; @@ -1006,7 +1003,7 @@ static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len) msg_read.len = (len_todo > 64) ? 64 : len_todo; msg_read.buf = eedata_cur; - ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_read, 1); + ret = i2c_transfer(client->adapter, &msg_read, 1); if (ret < 0) { cx231xx_err("Can't read eeprom\n"); return ret; @@ -1062,9 +1059,14 @@ void cx231xx_card_setup(struct cx231xx *dev) { struct tveeprom tvee; static u8 eeprom[256]; + struct i2c_client client; + + memset(&client, 0, sizeof(client)); + client.adapter = &dev->i2c_bus[1].i2c_adap; + client.addr = 0xa0 >> 1; - read_eeprom(dev, eeprom, sizeof(eeprom)); - tveeprom_hauppauge_analog(&dev->i2c_bus[1].i2c_client, + read_eeprom(dev, &client, eeprom, sizeof(eeprom)); + tveeprom_hauppauge_analog(&client, &tvee, eeprom + 0xc0); break; } -- GitLab From 23b0e41b47328bf56ff4624f0451cbf17dc4e411 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:55 -0300 Subject: [PATCH 2219/9457] [media] cx231xx: delete i2c_client per bus For each i2c master there is a i2c_client allocated that could be deleted now that its only two users have been changed to use their own i2c_client. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 7 ------- drivers/media/usb/cx231xx/cx231xx.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 67a13912fbe8..a30d40082e5d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -455,10 +455,6 @@ static struct i2c_adapter cx231xx_adap_template = { .algo = &cx231xx_algo, }; -static struct i2c_client cx231xx_client_template = { - .name = "cx231xx internal", -}; - /* ----------------------------------------------------------- */ /* @@ -514,7 +510,6 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) BUG_ON(!dev->cx231xx_send_usb_command); bus->i2c_adap = cx231xx_adap_template; - bus->i2c_client = cx231xx_client_template; bus->i2c_adap.dev.parent = &dev->udev->dev; strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); @@ -523,8 +518,6 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); i2c_add_adapter(&bus->i2c_adap); - bus->i2c_client.adapter = &bus->i2c_adap; - if (0 == bus->i2c_rc) { if (i2c_scan) cx231xx_do_i2c_scan(dev, bus->nr); diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 5efc93efe96d..c92382f48671 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -472,7 +472,6 @@ struct cx231xx_i2c { /* i2c i/o */ struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; u32 i2c_rc; /* different settings for each bus */ -- GitLab From 8da4f2d58d53e74192ba0310e8cb10b7d495b26d Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:56 -0300 Subject: [PATCH 2220/9457] [media] cx231xx: give each master i2c bus a seperate name Instead of using the same name for all 3 i2c physical buses inside cx231xx, name them differently, adding a number to it. This helps to better deal with the logs. [mchehab@osg.samsung.com: removed an unused bus_name var from the original patch] Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index a30d40082e5d..45057167227c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -512,7 +512,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) bus->i2c_adap = cx231xx_adap_template; bus->i2c_adap.dev.parent = &dev->udev->dev; - strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); + snprintf(bus->i2c_adap.name, sizeof(bus->i2c_adap.name), "%s-%d", bus->dev->name, bus->nr); bus->i2c_adap.algo_data = bus; i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); -- GitLab From 9abe3b89f38312052b885311ce93b1a53627793c Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:57 -0300 Subject: [PATCH 2221/9457] [media] cx231xx: Modifiy the symbolic constants for i2c ports and describe Change to I2C_0 ... I2C_2 for the master ports and add I2C_1_MUX_1 and I2C_1_MUX_3 for the muxed ones. V2: Renamed mux adapters to seperate them from master adapters. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index c92382f48671..377216ba5e93 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -322,10 +322,11 @@ enum cx231xx_decoder { }; enum CX231XX_I2C_MASTER_PORT { - I2C_0 = 0, - I2C_1 = 1, - I2C_2 = 2, - I2C_3 = 3 + I2C_0 = 0, /* master 0 - internal connection */ + I2C_1 = 1, /* master 1 - used with mux */ + I2C_2 = 2, /* master 2 */ + I2C_1_MUX_1 = 3, /* master 1 - port 1 (I2C_DEMOD_EN = 0) */ + I2C_1_MUX_3 = 4 /* master 1 - port 3 (I2C_DEMOD_EN = 1) */ }; struct cx231xx_board { -- GitLab From d032ca1283b68446df0adbec4561463b3f0aa147 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:58 -0300 Subject: [PATCH 2222/9457] [media] cx231xx: Use symbolic constants for i2c ports instead of numbers Replace numbers by the constants of same value and same meaning. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 62 +++++++++++------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 092fb85ae166..2f027c70f786 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -104,8 +104,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -144,8 +144,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, .norm = V4L2_STD_NTSC, @@ -184,8 +184,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -225,8 +225,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -297,8 +297,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -325,8 +325,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, .norm = V4L2_STD_NTSC, @@ -353,8 +353,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_NTSC, @@ -418,9 +418,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1, + .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, .norm = V4L2_STD_PAL_M, @@ -456,9 +456,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1, + .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, .norm = V4L2_STD_NTSC_M, @@ -494,9 +494,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1, + .ir_i2c_master = I2C_2, .rc_map_name = RC_MAP_PIXELVIEW_002T, .has_dvb = 1, .demod_addr = 0x10, @@ -587,7 +587,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, + .tuner_i2c_master = I2C_1, .norm = V4L2_STD_PAL, .input = {{ @@ -622,7 +622,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, + .tuner_i2c_master = I2C_1, .norm = V4L2_STD_NTSC, .input = {{ @@ -718,8 +718,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_PAL, @@ -757,8 +757,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_PAL, @@ -1033,7 +1033,7 @@ void cx231xx_card_setup(struct cx231xx *dev) /* request some modules */ if (dev->board.decoder == CX231XX_AVDECODER) { dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[0].i2c_adap, + &dev->i2c_bus[I2C_0].i2c_adap, "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) cx231xx_info("cx25840 subdev registration failure\n"); @@ -1062,7 +1062,7 @@ void cx231xx_card_setup(struct cx231xx *dev) struct i2c_client client; memset(&client, 0, sizeof(client)); - client.adapter = &dev->i2c_bus[1].i2c_adap; + client.adapter = &dev->i2c_bus[I2C_1].i2c_adap; client.addr = 0xa0 >> 1; read_eeprom(dev, &client, eeprom, sizeof(eeprom)); -- GitLab From c3c3f1ae8bab74c99fa211c76b035a41523e83dd Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:20:59 -0300 Subject: [PATCH 2223/9457] [media] cx231xx: add wrapper to get the i2c_adapter pointer This is a preparation for mapping I2C_1_MUX_1 and I2C_1_MUX_3 later to the seperate muxed i2c adapters. Map mux adapters to I2C_1 for now. Add local variables for i2c_adapters in dvb_init to get line lengths shorter. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 8 +++-- drivers/media/usb/cx231xx/cx231xx-dvb.c | 42 +++++++++++++---------- drivers/media/usb/cx231xx/cx231xx-i2c.c | 20 ++++++++++- drivers/media/usb/cx231xx/cx231xx-input.c | 3 +- drivers/media/usb/cx231xx/cx231xx.h | 1 + 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 2f027c70f786..f5fb93a79a9f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1033,7 +1033,7 @@ void cx231xx_card_setup(struct cx231xx *dev) /* request some modules */ if (dev->board.decoder == CX231XX_AVDECODER) { dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[I2C_0].i2c_adap, + cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) cx231xx_info("cx25840 subdev registration failure\n"); @@ -1043,8 +1043,10 @@ void cx231xx_card_setup(struct cx231xx *dev) /* Initialize the tuner */ if (dev->board.tuner_type != TUNER_ABSENT) { + struct i2c_adapter *tuner_i2c = cx231xx_get_i2c_adap(dev, + dev->board.tuner_i2c_master); dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) @@ -1062,7 +1064,7 @@ void cx231xx_card_setup(struct cx231xx *dev) struct i2c_client client; memset(&client, 0, sizeof(client)); - client.adapter = &dev->i2c_bus[I2C_1].i2c_adap; + client.adapter = cx231xx_get_i2c_adap(dev, I2C_1); client.addr = 0xa0 >> 1; read_eeprom(dev, &client, eeprom, sizeof(eeprom)); diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 6c7b5e250eed..869c433fbbbf 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -378,7 +378,7 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) struct xc5000_config cfg; memset(&cfg, 0, sizeof(cfg)); - cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap; + cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); cfg.i2c_addr = addr; if (!dev->dvb->frontend) { @@ -583,6 +583,8 @@ static int dvb_init(struct cx231xx *dev) { int result = 0; struct cx231xx_dvb *dvb; + struct i2c_adapter *tuner_i2c; + struct i2c_adapter *demod_i2c; if (!dev->board.has_dvb) { /* This device does not support the extension */ @@ -599,6 +601,8 @@ static int dvb_init(struct cx231xx *dev) dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; + tuner_i2c = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); + demod_i2c = cx231xx_get_i2c_adap(dev, dev->board.demod_i2c_master); mutex_lock(&dev->lock); cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); cx231xx_demod_reset(dev); @@ -609,7 +613,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -622,7 +626,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &cnxt_rde250_tunerconfig)) { result = -EINVAL; goto out_free; @@ -634,7 +638,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1411_attach, &xc5000_s5h1411_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -647,7 +651,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &cnxt_rdu250_tunerconfig)) { result = -EINVAL; goto out_free; @@ -657,7 +661,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -670,7 +674,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; goto out_free; @@ -681,7 +685,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1411_attach, &tda18271_s5h1411_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -694,7 +698,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; goto out_free; @@ -703,11 +707,11 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_HAUPPAUGE_EXETER: printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n", - __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); + __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(lgdt3305_attach, &hcw_lgdt3305_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap); + tuner_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -720,7 +724,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &hcw_tda18271_config); break; @@ -728,7 +732,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(si2165_attach, &hauppauge_930C_HD_1113xx_si2165_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap + tuner_i2c ); if (dev->dvb->frontend == NULL) { @@ -745,7 +749,7 @@ static int dvb_init(struct cx231xx *dev) dvb_attach(tda18271_attach, dev->dvb->frontend, 0x60, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &hcw_tda18271_config); dev->cx231xx_reset_analog_tuner = NULL; @@ -761,7 +765,7 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(si2165_attach, &pctv_quatro_stick_1114xx_si2165_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap + tuner_i2c ); if (dev->dvb->frontend == NULL) { @@ -786,7 +790,7 @@ static int dvb_init(struct cx231xx *dev) request_module("si2157"); client = i2c_new_device( - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &info); if (client == NULL || client->dev.driver == NULL) { dvb_frontend_detach(dev->dvb->frontend); @@ -811,11 +815,11 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", - __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); + __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(mb86a20s_attach, &pv_mb86a20s_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME @@ -828,7 +832,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &pv_tda18271_config); break; diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 45057167227c..af9180f3bf30 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -483,7 +483,7 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) struct i2c_client client; memset(&client, 0, sizeof(client)); - client.adapter = &dev->i2c_bus[i2c_port].i2c_adap; + client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); cx231xx_info(": Checking for I2C devices on port=%d ..\n", i2c_port); for (i = 0; i < 128; i++) { @@ -537,3 +537,21 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) i2c_del_adapter(&bus->i2c_adap); return 0; } + +struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) +{ + switch (i2c_port) { + case I2C_0: + return &dev->i2c_bus[0].i2c_adap; + case I2C_1: + return &dev->i2c_bus[1].i2c_adap; + case I2C_2: + return &dev->i2c_bus[2].i2c_adap; + case I2C_1_MUX_1: + case I2C_1_MUX_3: + return &dev->i2c_bus[1].i2c_adap; + default: + return NULL; + } +} +EXPORT_SYMBOL_GPL(cx231xx_get_i2c_adap); diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c index 05f0434919d4..5ae2ce3f51b1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-input.c +++ b/drivers/media/usb/cx231xx/cx231xx-input.c @@ -100,7 +100,8 @@ int cx231xx_ir_init(struct cx231xx *dev) ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master; dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", ir_i2c_bus, info.addr); - dev->ir_i2c_client = i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info); + dev->ir_i2c_client = i2c_new_device( + cx231xx_get_i2c_adap(dev, ir_i2c_bus), &info); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 377216ba5e93..f03338bdb949 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -754,6 +754,7 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev); void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port); /* Internal block control functions */ int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, -- GitLab From 9d9921e93078075b9142b7e8d68a038416967d4c Mon Sep 17 00:00:00 2001 From: Gulsah Kose Date: Wed, 29 Oct 2014 06:06:57 +0200 Subject: [PATCH 2224/9457] staging: rtl8188eu: core: Removed unnecessary return keyword. This patch fixes WARNING: void function return statements are not generally useful checkpatch.pl warning in rtw_efuse.c by using this coccinelle script @r@ identifier i; @@ void i(...) { ... -return; } Signed-off-by: Gulsah Kose Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index e037c43c2837..bc897da8c103 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -322,7 +322,6 @@ void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _si iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf); iol_mode_enable(Adapter, 0); } - return; } /* Do not support BT */ -- GitLab From 04947c5be5ca3824586f94352293549b899b2d89 Mon Sep 17 00:00:00 2001 From: Gulsah Kose Date: Thu, 30 Oct 2014 02:28:03 +0200 Subject: [PATCH 2225/9457] staging: rtl8188eu: os_dep: Removed unnecessary return. This patch fixes WARNING: void function return statements are not generally useful checkpatch.pl warning in usb_intf.c by using this coccinelle script @r@ identifier i; @@ void i(...) { ... -return; } Signed-off-by: Gulsah Kose Reviewed-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 407a318b09db..65a257f1bd10 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -556,8 +556,6 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf) RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); DBG_88E("-r871xu_dev_remove, done\n"); - - return; } static struct usb_driver rtl8188e_usb_drv = { -- GitLab From 3fd511d98660cba235dfadf1f296a3246fbaea58 Mon Sep 17 00:00:00 2001 From: Gulsah Kose Date: Thu, 30 Oct 2014 03:03:46 +0200 Subject: [PATCH 2226/9457] staging: rtl8188eu: os_dep: Used min_t instead of min This patch fixes this checkpatch.pl warning: WARNING: min() should probably be min_t(int, req->essid_len, IW_ESSID_MAX_SIZE) by using this coccinelle script: @r@ identifier i; expression e1, e2; type t1, t2; @@ t1 i = - min((t2)e1, e2); + min_t(t2, e1, e2); Signed-off-by: Gulsah Kose Reviewed-by: Daniel Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 70b729f26613..08ba7d3e6c69 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -1134,7 +1134,8 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, struct iw_scan_req *req = (struct iw_scan_req *)extra; if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); + int len = min_t(int, req->essid_len, + IW_ESSID_MAX_SIZE); memcpy(ssid[0].Ssid, req->essid, len); ssid[0].SsidLength = len; -- GitLab From a1f267651f1f653c82f46bf1d7d108ad31926a10 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:00 -0300 Subject: [PATCH 2227/9457] [media] cx231xx: remember status of i2c port_3 switch This is used later for is_tuner function that switches i2c behaviour for some tuners. [mchehab@osg.samsung.com: Fix CodingStyle on a multi-line comment] Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 12 ++++++++++++ drivers/media/usb/cx231xx/cx231xx.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 40a69879fc0a..0a5fec47c08c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -1272,6 +1272,14 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) if (dev->board.dont_use_port_3) is_port_3 = false; + + /* + * Should this code check dev->port_3_switch_enabled first + * to skip unnecessary reading of the register? + * If yes, the flag dev->port_3_switch_enabled must be initialized + * correctly. + */ + status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); if (status < 0) @@ -1294,6 +1302,10 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN, value, 4); + /* remember status of the switch for usage in is_tuner */ + if (status >= 0) + dev->port_3_switch_enabled = is_port_3; + return status; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index f03338bdb949..8a3c97b4e895 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -629,6 +629,7 @@ struct cx231xx { /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ struct cx231xx_i2c i2c_bus[3]; unsigned int xc_fw_load_done:1; + unsigned int port_3_switch_enabled:1; /* locks */ struct mutex gpio_i2c_lock; struct mutex i2c_lock; -- GitLab From edad187380ca6649406a750ecbe55f170ed79676 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 28 Oct 2014 12:37:16 +0100 Subject: [PATCH 2228/9457] ath9k: set pulse_rssi threshold to 15 Reduce pulse_rssi threshold to 15 in order to improve radar pattern detection probability on ext channel Signed-off-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ba3d788c57d3..5829074208fa 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1228,7 +1228,7 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah) conf->fir_power = -33; conf->radar_rssi = 20; conf->pulse_height = 10; - conf->pulse_rssi = 24; + conf->pulse_rssi = 15; conf->pulse_inband = 15; conf->pulse_maxlen = 255; conf->pulse_inband_step = 12; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 30b2f95e926c..9bdaa0afc37f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1391,7 +1391,7 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah) conf->fir_power = -28; conf->radar_rssi = 0; conf->pulse_height = 10; - conf->pulse_rssi = 24; + conf->pulse_rssi = 15; conf->pulse_inband = 8; conf->pulse_maxlen = 255; conf->pulse_inband_step = 12; -- GitLab From 244b124c6a43eebaa746780d8390b93ec1519c8f Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:04 +0100 Subject: [PATCH 2229/9457] brcmfmac: Add wowl support for USB devices. This patch adds wowl support for USB bus devices. This feature requires FW which has support for wowl built in. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index dc135915470d..e533000787f3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -93,6 +93,8 @@ struct brcmf_usbdev_info { u8 ifnum; struct urb *bulk_urb; /* used for FW download */ + + bool wowl_enabled; }; static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, @@ -600,6 +602,16 @@ static int brcmf_usb_up(struct device *dev) return 0; } +static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo) +{ + if (devinfo->ctl_urb) + usb_kill_urb(devinfo->ctl_urb); + if (devinfo->bulk_urb) + usb_kill_urb(devinfo->bulk_urb); + brcmf_usb_free_q(&devinfo->tx_postq, true); + brcmf_usb_free_q(&devinfo->rx_postq, true); +} + static void brcmf_usb_down(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); @@ -613,14 +625,7 @@ static void brcmf_usb_down(struct device *dev) brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); - if (devinfo->ctl_urb) - usb_kill_urb(devinfo->ctl_urb); - - if (devinfo->bulk_urb) - usb_kill_urb(devinfo->bulk_urb); - brcmf_usb_free_q(&devinfo->tx_postq, true); - - brcmf_usb_free_q(&devinfo->rx_postq, true); + brcmf_cancel_all_urbs(devinfo); } static void @@ -1094,11 +1099,24 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, return NULL; } +static void brcmf_usb_wowl_config(struct device *dev, bool enabled) +{ + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + + brcmf_dbg(USB, "Configuring WOWL, enabled=%d\n", enabled); + devinfo->wowl_enabled = enabled; + if (enabled) + device_set_wakeup_enable(devinfo->dev, true); + else + device_set_wakeup_enable(devinfo->dev, false); +} + static struct brcmf_bus_ops brcmf_usb_bus_ops = { .txdata = brcmf_usb_tx, .stop = brcmf_usb_down, .txctl = brcmf_usb_tx_ctlpkt, .rxctl = brcmf_usb_rx_ctlpkt, + .wowl_config = brcmf_usb_wowl_config, }; static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) @@ -1186,6 +1204,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->ops = &brcmf_usb_bus_ops; bus->proto_type = BRCMF_PROTO_BCDC; bus->always_use_fws_queue = true; +#ifdef CONFIG_PM + bus->wowl_supported = true; +#endif if (!brcmf_usb_dlneeded(devinfo)) { ret = brcmf_usb_bus_setup(devinfo); @@ -1339,7 +1360,10 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) brcmf_dbg(USB, "Enter\n"); devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; - brcmf_detach(&usb->dev); + if (devinfo->wowl_enabled) + brcmf_cancel_all_urbs(devinfo); + else + brcmf_detach(&usb->dev); return 0; } @@ -1352,7 +1376,12 @@ static int brcmf_usb_resume(struct usb_interface *intf) struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); brcmf_dbg(USB, "Enter\n"); - return brcmf_usb_bus_setup(devinfo); + if (!devinfo->wowl_enabled) + return brcmf_usb_bus_setup(devinfo); + + devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; + brcmf_usb_rx_fill_all(devinfo); + return 0; } static int brcmf_usb_reset_resume(struct usb_interface *intf) -- GitLab From 330b4e4be937bf0ef126e01323f2756645b92c06 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:05 +0100 Subject: [PATCH 2230/9457] brcmfmac: Add wowl support for SDIO devices. This patch adds wowl support for SDIO bus devices. This feature requires FW which has support for wowl built in. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/bcmsdh.c | 45 +++++++++++++------ .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 1 + .../wireless/brcm80211/brcmfmac/sdio_host.h | 2 + 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 8dbd5dbb78fd..79b2c7e3f7e7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1064,6 +1064,16 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, if (!sdiodev->pdata) brcmf_of_probe(sdiodev); +#ifdef CONFIG_PM_SLEEP + /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ + * is true or when platform data OOB irq is true). + */ + if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && + ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || + (sdiodev->pdata->oob_irq_supported))) + bus_if->wowl_supported = true; +#endif + atomic_set(&sdiodev->suspend, false); init_waitqueue_head(&sdiodev->request_word_wait); init_waitqueue_head(&sdiodev->request_buffer_wait); @@ -1116,34 +1126,39 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) brcmf_dbg(SDIO, "Exit\n"); } +void brcmf_sdio_wowl_config(struct device *dev, bool enabled) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + + brcmf_dbg(SDIO, "Configuring WOWL, enabled=%d\n", enabled); + sdiodev->wowl_enabled = enabled; +} + #ifdef CONFIG_PM_SLEEP static int brcmf_ops_sdio_suspend(struct device *dev) { - mmc_pm_flag_t sdio_flags; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - int ret = 0; + mmc_pm_flag_t sdio_flags; brcmf_dbg(SDIO, "Enter\n"); - sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); - if (!(sdio_flags & MMC_PM_KEEP_POWER)) { - brcmf_err("Host can't keep power while suspended\n"); - return -EINVAL; - } - atomic_set(&sdiodev->suspend, true); - ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); - if (ret) { - brcmf_err("Failed to set pm_flags\n"); - atomic_set(&sdiodev->suspend, false); - return ret; + if (sdiodev->wowl_enabled) { + sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->pdata->oob_irq_supported) + enable_irq_wake(sdiodev->pdata->oob_irq_nr); + else + sdio_flags = MMC_PM_WAKE_SDIO_IRQ; + if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) + brcmf_err("Failed to set pm_flags %x\n", sdio_flags); } brcmf_sdio_wd_timer(sdiodev->bus, 0); - return ret; + return 0; } static int brcmf_ops_sdio_resume(struct device *dev) @@ -1152,6 +1167,8 @@ static int brcmf_ops_sdio_resume(struct device *dev) struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; brcmf_dbg(SDIO, "Enter\n"); + if (sdiodev->pdata->oob_irq_supported) + disable_irq_wake(sdiodev->pdata->oob_irq_nr); brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); atomic_set(&sdiodev->suspend, false); return 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f55f625fd06b..079187c51170 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3949,6 +3949,7 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .txctl = brcmf_sdio_bus_txctl, .rxctl = brcmf_sdio_bus_rxctl, .gettxq = brcmf_sdio_bus_gettxq, + .wowl_config = brcmf_sdio_wowl_config }; static void brcmf_sdio_firmware_callback(struct device *dev, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index f2d06cae366a..262aedfeaa30 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -186,6 +186,7 @@ struct brcmf_sdio_dev { struct sg_table sgtable; char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; + bool wowl_enabled; }; /* sdio core registers */ @@ -334,5 +335,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus); void brcmf_sdio_isr(struct brcmf_sdio *bus); void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); +void brcmf_sdio_wowl_config(struct device *dev, bool enabled); #endif /* _BRCM_SDH_H_ */ -- GitLab From b9a82f892e2a143788d6a4e9fa121837ae1c9a8d Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:06 +0100 Subject: [PATCH 2231/9457] brcmfmac: Add wowl patterns support. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/fwil_types.h | 89 +++++++++++++------ .../wireless/brcm80211/brcmfmac/wl_cfg80211.c | 66 ++++++++++++-- 2 files changed, 120 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h index 5ff5cd0bb032..ba64b292f7a5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h @@ -55,59 +55,63 @@ /* WOWL bits */ /* Wakeup on Magic packet: */ -#define WL_WOWL_MAGIC (1 << 0) +#define BRCMF_WOWL_MAGIC (1 << 0) /* Wakeup on Netpattern */ -#define WL_WOWL_NET (1 << 1) +#define BRCMF_WOWL_NET (1 << 1) /* Wakeup on loss-of-link due to Disassoc/Deauth: */ -#define WL_WOWL_DIS (1 << 2) +#define BRCMF_WOWL_DIS (1 << 2) /* Wakeup on retrograde TSF: */ -#define WL_WOWL_RETR (1 << 3) +#define BRCMF_WOWL_RETR (1 << 3) /* Wakeup on loss of beacon: */ -#define WL_WOWL_BCN (1 << 4) +#define BRCMF_WOWL_BCN (1 << 4) /* Wakeup after test: */ -#define WL_WOWL_TST (1 << 5) +#define BRCMF_WOWL_TST (1 << 5) /* Wakeup after PTK refresh: */ -#define WL_WOWL_M1 (1 << 6) +#define BRCMF_WOWL_M1 (1 << 6) /* Wakeup after receipt of EAP-Identity Req: */ -#define WL_WOWL_EAPID (1 << 7) +#define BRCMF_WOWL_EAPID (1 << 7) /* Wakeind via PME(0) or GPIO(1): */ -#define WL_WOWL_PME_GPIO (1 << 8) +#define BRCMF_WOWL_PME_GPIO (1 << 8) /* need tkip phase 1 key to be updated by the driver: */ -#define WL_WOWL_NEEDTKIP1 (1 << 9) +#define BRCMF_WOWL_NEEDTKIP1 (1 << 9) /* enable wakeup if GTK fails: */ -#define WL_WOWL_GTK_FAILURE (1 << 10) +#define BRCMF_WOWL_GTK_FAILURE (1 << 10) /* support extended magic packets: */ -#define WL_WOWL_EXTMAGPAT (1 << 11) +#define BRCMF_WOWL_EXTMAGPAT (1 << 11) /* support ARP/NS/keepalive offloading: */ -#define WL_WOWL_ARPOFFLOAD (1 << 12) +#define BRCMF_WOWL_ARPOFFLOAD (1 << 12) /* read protocol version for EAPOL frames: */ -#define WL_WOWL_WPA2 (1 << 13) +#define BRCMF_WOWL_WPA2 (1 << 13) /* If the bit is set, use key rotaton: */ -#define WL_WOWL_KEYROT (1 << 14) +#define BRCMF_WOWL_KEYROT (1 << 14) /* If the bit is set, frm received was bcast frame: */ -#define WL_WOWL_BCAST (1 << 15) +#define BRCMF_WOWL_BCAST (1 << 15) /* If the bit is set, scan offload is enabled: */ -#define WL_WOWL_SCANOL (1 << 16) +#define BRCMF_WOWL_SCANOL (1 << 16) /* Wakeup on tcpkeep alive timeout: */ -#define WL_WOWL_TCPKEEP_TIME (1 << 17) +#define BRCMF_WOWL_TCPKEEP_TIME (1 << 17) /* Wakeup on mDNS Conflict Resolution: */ -#define WL_WOWL_MDNS_CONFLICT (1 << 18) +#define BRCMF_WOWL_MDNS_CONFLICT (1 << 18) /* Wakeup on mDNS Service Connect: */ -#define WL_WOWL_MDNS_SERVICE (1 << 19) +#define BRCMF_WOWL_MDNS_SERVICE (1 << 19) /* tcp keepalive got data: */ -#define WL_WOWL_TCPKEEP_DATA (1 << 20) +#define BRCMF_WOWL_TCPKEEP_DATA (1 << 20) /* Firmware died in wowl mode: */ -#define WL_WOWL_FW_HALT (1 << 21) +#define BRCMF_WOWL_FW_HALT (1 << 21) /* Enable detection of radio button changes: */ -#define WL_WOWL_ENAB_HWRADIO (1 << 22) +#define BRCMF_WOWL_ENAB_HWRADIO (1 << 22) /* Offloads detected MIC failure(s): */ -#define WL_WOWL_MIC_FAIL (1 << 23) +#define BRCMF_WOWL_MIC_FAIL (1 << 23) /* Wakeup in Unassociated state (Net/Magic Pattern): */ -#define WL_WOWL_UNASSOC (1 << 24) +#define BRCMF_WOWL_UNASSOC (1 << 24) /* Wakeup if received matched secured pattern: */ -#define WL_WOWL_SECURE (1 << 25) +#define BRCMF_WOWL_SECURE (1 << 25) /* Link Down indication in WoWL mode: */ -#define WL_WOWL_LINKDOWN (1 << 31) +#define BRCMF_WOWL_LINKDOWN (1 << 31) + +#define BRCMF_WOWL_MAXPATTERNS 8 +#define BRCMF_WOWL_MAXPATTERNSIZE 128 + /* join preference types for join_pref iovar */ enum brcmf_join_pref_types { @@ -124,6 +128,12 @@ enum brcmf_fil_p2p_if_types { BRCMF_FIL_P2P_IF_DEV, }; +enum brcmf_wowl_pattern_type { + BRCMF_WOWL_PATTERN_TYPE_BITMAP = 0, + BRCMF_WOWL_PATTERN_TYPE_ARP, + BRCMF_WOWL_PATTERN_TYPE_NA +}; + struct brcmf_fil_p2p_if_le { u8 addr[ETH_ALEN]; __le16 type; @@ -484,4 +494,29 @@ struct brcmf_rx_mgmt_data { __be32 rate; }; +/** + * struct brcmf_fil_wowl_pattern_le - wowl pattern configuration struct. + * + * @cmd: "add", "del" or "clr". + * @masksize: Size of the mask in #of bytes + * @offset: Pattern byte offset in packet + * @patternoffset: Offset of start of pattern. Starting from field masksize. + * @patternsize: Size of the pattern itself in #of bytes + * @id: id + * @reasonsize: Size of the wakeup reason code + * @type: Type of pattern (enum brcmf_wowl_pattern_type) + */ +struct brcmf_fil_wowl_pattern_le { + u8 cmd[4]; + __le32 masksize; + __le32 offset; + __le32 patternoffset; + __le32 patternsize; + __le32 id; + __le32 reasonsize; + __le32 type; + /* u8 mask[] - Mask follows the structure above */ + /* u8 pattern[] - Pattern follows the mask is at 'patternoffset' */ +}; + #endif /* FWIL_TYPES_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28fa25b509db..fcadbe3c38d6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2779,6 +2779,44 @@ static __always_inline void brcmf_delay(u32 ms) } } +static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4], + u8 *pattern, u32 patternsize, u8 *mask, + u32 packet_offset) +{ + struct brcmf_fil_wowl_pattern_le *filter; + u32 masksize; + u32 patternoffset; + u8 *buf; + u32 bufsize; + s32 ret; + + masksize = (patternsize + 7) / 8; + patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize; + + bufsize = sizeof(*filter) + patternsize + masksize; + buf = kzalloc(bufsize, GFP_KERNEL); + if (!buf) + return -ENOMEM; + filter = (struct brcmf_fil_wowl_pattern_le *)buf; + + memcpy(filter->cmd, cmd, 4); + filter->masksize = cpu_to_le32(masksize); + filter->offset = cpu_to_le32(packet_offset); + filter->patternoffset = cpu_to_le32(patternoffset); + filter->patternsize = cpu_to_le32(patternsize); + filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP); + + if ((mask) && (masksize)) + memcpy(buf + sizeof(*filter), mask, masksize); + if ((pattern) && (patternsize)) + memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize); + + ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize); + + kfree(buf); + return ret; +} + static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); @@ -2788,10 +2826,11 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) brcmf_dbg(TRACE, "Enter\n"); if (cfg->wowl_enabled) { + brcmf_configure_arp_offload(ifp, true); brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, cfg->pre_wowl_pmmode); - brcmf_fil_iovar_data_set(ifp, "wowl_pattern", "clr", 4); brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); + brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); cfg->wowl_enabled = false; } return 0; @@ -2802,21 +2841,29 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg, struct cfg80211_wowlan *wowl) { u32 wowl_config; + u32 i; brcmf_dbg(TRACE, "Suspend, wowl config.\n"); + brcmf_configure_arp_offload(ifp, false); brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode); brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); wowl_config = 0; if (wowl->disconnect) - wowl_config |= WL_WOWL_DIS | WL_WOWL_BCN | WL_WOWL_RETR; - /* Note: if "wowl" target and not "wowlpf" then wowl_bcn_loss - * should be configured. This paramater is not supported by - * wowlpf. - */ + wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR; if (wowl->magic_pkt) - wowl_config |= WL_WOWL_MAGIC; + wowl_config |= BRCMF_WOWL_MAGIC; + if ((wowl->patterns) && (wowl->n_patterns)) { + wowl_config |= BRCMF_WOWL_NET; + for (i = 0; i < wowl->n_patterns; i++) { + brcmf_config_wowl_pattern(ifp, "add", + (u8 *)wowl->patterns[i].pattern, + wowl->patterns[i].pattern_len, + (u8 *)wowl->patterns[i].mask, + wowl->patterns[i].pkt_offset); + } + } brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); brcmf_bus_wowl_config(cfg->pub->bus_if, true); @@ -5440,10 +5487,13 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy) wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; } - #ifdef CONFIG_PM static const struct wiphy_wowlan_support brcmf_wowlan_support = { .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, + .n_patterns = BRCMF_WOWL_MAXPATTERNS, + .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE, + .pattern_min_len = 1, + .max_pkt_offset = 1500, }; #endif -- GitLab From a9a2808f05322fe152672b7e7d09759446947da8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 28 Oct 2014 14:56:07 +0100 Subject: [PATCH 2232/9457] brcmfmac: show firmware error as string in debug message Showing the firmware error allows to quickly give a clue what went wrong and directly look in the firmware code that gave us back the error. Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Hante Meuleman Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/fwil.c | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index ded328f80cd1..42da73e26142 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -32,6 +32,76 @@ #define MAX_HEX_DUMP_LEN 64 +#ifdef DEBUG +static const char * const brcmf_fil_errstr[] = { + "BCME_OK", + "BCME_ERROR", + "BCME_BADARG", + "BCME_BADOPTION", + "BCME_NOTUP", + "BCME_NOTDOWN", + "BCME_NOTAP", + "BCME_NOTSTA", + "BCME_BADKEYIDX", + "BCME_RADIOOFF", + "BCME_NOTBANDLOCKED", + "BCME_NOCLK", + "BCME_BADRATESET", + "BCME_BADBAND", + "BCME_BUFTOOSHORT", + "BCME_BUFTOOLONG", + "BCME_BUSY", + "BCME_NOTASSOCIATED", + "BCME_BADSSIDLEN", + "BCME_OUTOFRANGECHAN", + "BCME_BADCHAN", + "BCME_BADADDR", + "BCME_NORESOURCE", + "BCME_UNSUPPORTED", + "BCME_BADLEN", + "BCME_NOTREADY", + "BCME_EPERM", + "BCME_NOMEM", + "BCME_ASSOCIATED", + "BCME_RANGE", + "BCME_NOTFOUND", + "BCME_WME_NOT_ENABLED", + "BCME_TSPEC_NOTFOUND", + "BCME_ACM_NOTSUPPORTED", + "BCME_NOT_WME_ASSOCIATION", + "BCME_SDIO_ERROR", + "BCME_DONGLE_DOWN", + "BCME_VERSION", + "BCME_TXFAIL", + "BCME_RXFAIL", + "BCME_NODEVICE", + "BCME_NMODE_DISABLED", + "BCME_NONRESIDENT", + "BCME_SCANREJECT", + "BCME_USAGE_ERROR", + "BCME_IOCTL_ERROR", + "BCME_SERIAL_PORT_ERR", + "BCME_DISABLED", + "BCME_DECERR", + "BCME_ENCERR", + "BCME_MICERR", + "BCME_REPLAY", + "BCME_IE_NOTFOUND", +}; + +static const char *brcmf_fil_get_errstr(u32 err) +{ + if (err >= ARRAY_SIZE(brcmf_fil_errstr)) + return "(unknown)"; + + return brcmf_fil_errstr[err]; +} +#else +static const char *brcmf_fil_get_errstr(u32 err) +{ + return ""; +} +#endif /* DEBUG */ static s32 brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) @@ -54,7 +124,8 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) if (err >= 0) err = 0; else - brcmf_dbg(FIL, "Failed err=%d\n", err); + brcmf_dbg(FIL, "Failed: %s (%d)\n", + brcmf_fil_get_errstr((u32)(-err)), err); return err; } -- GitLab From a3e53bbfd91c155d06bb168ad7a830cdf21b500c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 28 Oct 2014 14:56:08 +0100 Subject: [PATCH 2233/9457] brcmfmac: remove unused defintion The define EBRCMF_UNSUPPORTED is not used in the source file so this patch removes it. Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Hante Meuleman Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/feature.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c index aed53acef456..4eb6a41e72c7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c @@ -23,11 +23,6 @@ #include "fwil.h" #include "feature.h" -/* - * firmware error code received if iovar is unsupported. - */ -#define EBRCMF_FEAT_UNSUPPORTED 23 - /* * expand feature list to array of feature strings. */ -- GitLab From 9c6476668025e76a8365be783f2649fe3259b91c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 28 Oct 2014 14:56:09 +0100 Subject: [PATCH 2234/9457] brcmfmac: do not use firmware error code in driver Passing the firmware error codes up the driver may be mapped to linux error numbers which may impact proper fault analysis. So better pass up a generic failure code, ie. -EBADE and only show firmware error code in FIL debug message. Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Hante Meuleman Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 42da73e26142..dccbdc1aae6d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -122,12 +122,11 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); if (err >= 0) - err = 0; - else - brcmf_dbg(FIL, "Failed: %s (%d)\n", - brcmf_fil_get_errstr((u32)(-err)), err); + return 0; - return err; + brcmf_dbg(FIL, "Failed: %s (%d)\n", + brcmf_fil_get_errstr((u32)(-err)), err); + return -EBADE; } s32 -- GitLab From ac83d0b0aae152385ae998c65fc03ea790d8c025 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:10 +0100 Subject: [PATCH 2235/9457] brcmfmac: (clean) Remove usb_rdl.h as it is not needed. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 88 +++++++++++++++---- .../net/wireless/brcm80211/brcmfmac/usb_rdl.h | 75 ---------------- 2 files changed, 69 insertions(+), 94 deletions(-) delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index e533000787f3..3f12b606839e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -27,9 +27,9 @@ #include #include "firmware.h" -#include "usb_rdl.h" #include "usb.h" + #define IOCTL_RESP_TIMEOUT 2000 #define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ @@ -49,6 +49,71 @@ #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" #define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin" +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_MAX_OFFSET 3 /* Max number of file offsets */ +#define TRX_UNCOMP_IMAGE 0x20 /* Trx holds uncompressed img */ +#define TRX_RDL_CHUNK 1500 /* size of each dl transfer */ +#define TRX_OFFSETS_DLFWLEN_IDX 0 + +/* Control messages: bRequest values */ +#define DL_GETSTATE 0 /* returns the rdl_state_t struct */ +#define DL_CHECK_CRC 1 /* currently unused */ +#define DL_GO 2 /* execute downloaded image */ +#define DL_START 3 /* initialize dl state */ +#define DL_REBOOT 4 /* reboot the device in 2 seconds */ +#define DL_GETVER 5 /* returns the bootrom_id_t struct */ +#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset + * event to occur in 2 seconds. It is the + * responsibility of the downloaded code to + * clear this event + */ +#define DL_EXEC 7 /* jump to a supplied address */ +#define DL_RESETCFG 8 /* To support single enum on dongle + * - Not used by bootloader + */ +#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup + * if resp unavailable + */ + +/* states */ +#define DL_WAITING 0 /* waiting to rx first pkt */ +#define DL_READY 1 /* hdr was good, waiting for more of the + * compressed image + */ +#define DL_BAD_HDR 2 /* hdr was corrupted */ +#define DL_BAD_CRC 3 /* compressed image was corrupted */ +#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */ +#define DL_START_FAIL 5 /* failed to initialize correctly */ +#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM + * value + */ +#define DL_IMAGE_TOOBIG 7 /* firmware image too big */ + + +struct trx_header_le { + __le32 magic; /* "HDR0" */ + __le32 len; /* Length of file including header */ + __le32 crc32; /* CRC from flag_version to end of file */ + __le32 flag_version; /* 0:15 flags, 16:31 version */ + __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of + * header + */ +}; + +struct rdl_state_le { + __le32 state; + __le32 bytes; +}; + +struct bootrom_id_le { + __le32 chip; /* Chip id */ + __le32 chiprev; /* Chip rev */ + __le32 ramsize; /* Size of RAM */ + __le32 remapbase; /* Current remap base address */ + __le32 boardtype; /* Type of board */ + __le32 boardrev; /* Board revision */ +}; + struct brcmf_usb_image { struct list_head list; s8 *fwname; @@ -788,7 +853,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); - bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); + bulkchunk = kmalloc(TRX_RDL_CHUNK, GFP_ATOMIC); if (bulkchunk == NULL) { err = -ENOMEM; goto fail; @@ -815,10 +880,10 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) /* Wait until the usb device reports it received all * the bytes we sent */ if ((rdlbytes == sent) && (rdlbytes != dllen)) { - if ((dllen-sent) < RDL_CHUNK) + if ((dllen-sent) < TRX_RDL_CHUNK) sendlen = dllen-sent; else - sendlen = RDL_CHUNK; + sendlen = TRX_RDL_CHUNK; /* simply avoid having to send a ZLP by ensuring we * never have an even @@ -983,21 +1048,6 @@ static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) kfree(devinfo->rx_reqs); } -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 /* Version 1 */ -#define TRX_MAX_LEN 0x3B0000 /* Max length */ -#define TRX_NO_HEADER 1 /* Do not write TRX header */ -#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed image */ - -struct trx_header_le { - __le32 magic; /* "HDR0" */ - __le32 len; /* Length of file including header */ - __le32 crc32; /* CRC from flag_version to end of file */ - __le32 flag_version; /* 0:15 flags, 16:31 version */ - __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of - * header */ -}; static int check_file(const u8 *headers) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h deleted file mode 100644 index 0a35c51c3da2..000000000000 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2011 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _USB_RDL_H -#define _USB_RDL_H - -/* Control messages: bRequest values */ -#define DL_GETSTATE 0 /* returns the rdl_state_t struct */ -#define DL_CHECK_CRC 1 /* currently unused */ -#define DL_GO 2 /* execute downloaded image */ -#define DL_START 3 /* initialize dl state */ -#define DL_REBOOT 4 /* reboot the device in 2 seconds */ -#define DL_GETVER 5 /* returns the bootrom_id_t struct */ -#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset - * event to occur in 2 seconds. It is the - * responsibility of the downloaded code to - * clear this event - */ -#define DL_EXEC 7 /* jump to a supplied address */ -#define DL_RESETCFG 8 /* To support single enum on dongle - * - Not used by bootloader - */ -#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup - * if resp unavailable - */ - -/* states */ -#define DL_WAITING 0 /* waiting to rx first pkt */ -#define DL_READY 1 /* hdr was good, waiting for more of the - * compressed image */ -#define DL_BAD_HDR 2 /* hdr was corrupted */ -#define DL_BAD_CRC 3 /* compressed image was corrupted */ -#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */ -#define DL_START_FAIL 5 /* failed to initialize correctly */ -#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM - * value */ -#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START - * for rdl) */ - -struct rdl_state_le { - __le32 state; - __le32 bytes; -}; - -struct bootrom_id_le { - __le32 chip; /* Chip id */ - __le32 chiprev; /* Chip rev */ - __le32 ramsize; /* Size of RAM */ - __le32 remapbase; /* Current remap base address */ - __le32 boardtype; /* Type of board */ - __le32 boardrev; /* Board revision */ -}; - -#define RDL_CHUNK 1500 /* size of each dl transfer */ - -#define TRX_OFFSETS_DLFWLEN_IDX 0 -#define TRX_OFFSETS_JUMPTO_IDX 1 -#define TRX_OFFSETS_NVM_LEN_IDX 2 - -#define TRX_OFFSETS_DLBASE_IDX 0 - -#endif /* _USB_RDL_H */ -- GitLab From d3c80372e00c792cbde42fa1abda3b8b08575d59 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:11 +0100 Subject: [PATCH 2236/9457] brcmfmac: (clean) Remove packet filter configuration. Packet filters got configured but never used. Reviewed-by: Franky Lin Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../wireless/brcm80211/brcmfmac/dhd_common.c | 166 ------------------ 1 file changed, 166 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index d991f8e3d9ec..6028fc466575 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -26,11 +26,9 @@ #include "fwil_types.h" #include "tracepoint.h" -#define PKTFILTER_BUF_SIZE 128 #define BRCMF_DEFAULT_BCN_TIMEOUT 3 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 -#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" /* boost value for RSSI_DELTA in preferred join selection */ #define BRCMF_JOIN_PREF_RSSI_BOOST 8 @@ -86,165 +84,6 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } -/* Convert user's input in hex pattern to byte-size mask */ -static int brcmf_c_pattern_atoh(char *src, char *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { - brcmf_err("Mask invalid format. Needs to start with 0x\n"); - return -EINVAL; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - brcmf_err("Mask invalid format. Length must be even.\n"); - return -EINVAL; - } - for (i = 0; *src != '\0'; i++) { - unsigned long res; - char num[3]; - strncpy(num, src, 2); - num[2] = '\0'; - if (kstrtoul(num, 16, &res)) - return -EINVAL; - dst[i] = (u8)res; - src += 2; - } - return i; -} - -static void -brcmf_c_pktfilter_offload_enable(struct brcmf_if *ifp, char *arg, int enable, - int master_mode) -{ - unsigned long res; - char *argv; - char *arg_save = NULL, *arg_org = NULL; - s32 err; - struct brcmf_pkt_filter_enable_le enable_parm; - - arg_save = kstrdup(arg, GFP_ATOMIC); - if (!arg_save) - goto fail; - - arg_org = arg_save; - - argv = strsep(&arg_save, " "); - - if (argv == NULL) { - brcmf_err("No args provided\n"); - goto fail; - } - - /* Parse packet filter id. */ - enable_parm.id = 0; - if (!kstrtoul(argv, 0, &res)) - enable_parm.id = cpu_to_le32((u32)res); - - /* Enable/disable the specified filter. */ - enable_parm.enable = cpu_to_le32(enable); - - err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable", &enable_parm, - sizeof(enable_parm)); - if (err) - brcmf_err("Set pkt_filter_enable error (%d)\n", err); - - /* Control the master mode */ - err = brcmf_fil_iovar_int_set(ifp, "pkt_filter_mode", master_mode); - if (err) - brcmf_err("Set pkt_filter_mode error (%d)\n", err); - -fail: - kfree(arg_org); -} - -static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) -{ - struct brcmf_pkt_filter_le *pkt_filter; - unsigned long res; - int buf_len; - s32 err; - u32 mask_size; - u32 pattern_size; - char *argv[8], *buf = NULL; - int i = 0; - char *arg_save = NULL, *arg_org = NULL; - - arg_save = kstrdup(arg, GFP_ATOMIC); - if (!arg_save) - goto fail; - - arg_org = arg_save; - - buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); - if (!buf) - goto fail; - - argv[i] = strsep(&arg_save, " "); - while (argv[i]) { - i++; - if (i >= 8) { - brcmf_err("Too many parameters\n"); - goto fail; - } - argv[i] = strsep(&arg_save, " "); - } - - if (i != 6) { - brcmf_err("Not enough args provided %d\n", i); - goto fail; - } - - pkt_filter = (struct brcmf_pkt_filter_le *)buf; - - /* Parse packet filter id. */ - pkt_filter->id = 0; - if (!kstrtoul(argv[0], 0, &res)) - pkt_filter->id = cpu_to_le32((u32)res); - - /* Parse filter polarity. */ - pkt_filter->negate_match = 0; - if (!kstrtoul(argv[1], 0, &res)) - pkt_filter->negate_match = cpu_to_le32((u32)res); - - /* Parse filter type. */ - pkt_filter->type = 0; - if (!kstrtoul(argv[2], 0, &res)) - pkt_filter->type = cpu_to_le32((u32)res); - - /* Parse pattern filter offset. */ - pkt_filter->u.pattern.offset = 0; - if (!kstrtoul(argv[3], 0, &res)) - pkt_filter->u.pattern.offset = cpu_to_le32((u32)res); - - /* Parse pattern filter mask. */ - mask_size = brcmf_c_pattern_atoh(argv[4], - (char *)pkt_filter->u.pattern.mask_and_pattern); - - /* Parse pattern filter pattern. */ - pattern_size = brcmf_c_pattern_atoh(argv[5], - (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]); - - if (mask_size != pattern_size) { - brcmf_err("Mask and pattern not the same size\n"); - goto fail; - } - - pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); - buf_len = offsetof(struct brcmf_pkt_filter_le, - u.pattern.mask_and_pattern); - buf_len += mask_size + pattern_size; - - err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, - buf_len); - if (err) - brcmf_err("Set pkt_filter_add error (%d)\n", err); - -fail: - kfree(arg_org); - - kfree(buf); -} - int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) { s8 eventmask[BRCMF_EVENTING_MASK_LEN]; @@ -356,11 +195,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) goto done; } - /* Setup packet filter */ - brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER); - brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, - 0, true); - /* do bus specific preinit here */ err = brcmf_bus_preinit(ifp->drvr->bus_if); done: -- GitLab From 4a1c61508b4830a3c36257a0995646d7b22b29a9 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:12 +0100 Subject: [PATCH 2237/9457] brcmfmac: (clean) Move tracepoint related function. __brcmf_err is a tracepoint specific function. Move it to tracepoint.c. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 15 --------------- .../net/wireless/brcm80211/brcmfmac/tracepoint.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 6028fc466575..98bc2226a119 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -201,21 +201,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) return err; } -#ifdef CONFIG_BRCM_TRACING -void __brcmf_err(const char *func, const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; - pr_err("%s: %pV", func, &vaf); - trace_brcmf_err(func, &vaf); - va_end(args); -} -#endif #if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG) void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c index b505db48c60d..a10f35c5eb3d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c @@ -19,4 +19,19 @@ #ifndef __CHECKER__ #define CREATE_TRACE_POINTS #include "tracepoint.h" + +void __brcmf_err(const char *func, const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + pr_err("%s: %pV", func, &vaf); + trace_brcmf_err(func, &vaf); + va_end(args); +} + #endif -- GitLab From a8e8ed3446a32a2323e70bc1cef05c5119d893e0 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:13 +0100 Subject: [PATCH 2238/9457] brcmfmac: (clean) Rename files dhd_dbg to debug Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/btcoex.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/chip.c | 2 +- .../net/wireless/brcm80211/brcmfmac/{dhd_dbg.c => debug.c} | 2 +- .../net/wireless/brcm80211/brcmfmac/{dhd_dbg.h => debug.h} | 6 +++--- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/feature.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/flowring.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fweh.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/of.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/proto.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/vendor.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 25 files changed, 27 insertions(+), 27 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_dbg.c => debug.c} (99%) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_dbg.h => debug.h} (98%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 90a977fe9a64..1da9042c8aba 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -50,7 +50,7 @@ brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \ pcie.o brcmfmac-$(CONFIG_BRCMDBG) += \ - dhd_dbg.o + debug.o brcmfmac-$(CONFIG_BRCM_TRACING) += \ tracepoint.o brcmfmac-$(CONFIG_OF) += \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index a159ff3427de..11d3dfae8bac 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -28,7 +28,7 @@ #include "dhd.h" #include "dhd_bus.h" #include "fwsignal.h" -#include "dhd_dbg.h" +#include "debug.h" #include "tracepoint.h" #include "proto.h" #include "bcdc.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 79b2c7e3f7e7..8c0dfea68eeb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -42,7 +42,7 @@ #include #include "chip.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "sdio_host.h" #include "of.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c index a29ac4977b3a..a2f7e2ccfc84 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include "debug.h" #include "fwil.h" #include "fwil_types.h" #include "btcoex.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c index 95efde868db8..ddae0b5e56ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c @@ -25,7 +25,7 @@ #include #include #include -#include "dhd_dbg.h" +#include "debug.h" #include "chip.h" /* SOC Interconnect types (aka chip types) */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c rename to drivers/net/wireless/brcm80211/brcmfmac/debug.c index be9f4f829192..27e51085d33a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c @@ -21,7 +21,7 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" static struct dentry *root_folder; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/debug.h similarity index 98% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h rename to drivers/net/wireless/brcm80211/brcmfmac/debug.h index dec40d316c82..eb0b8c47479d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _BRCMF_DBG_H_ -#define _BRCMF_DBG_H_ +#ifndef BRCMFMAC_DEBUG_H +#define BRCMFMAC_DEBUG_H /* message levels */ #define BRCMF_TRACE_VAL 0x00000002 @@ -133,4 +133,4 @@ int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, } #endif -#endif /* _BRCMF_DBG_H_ */ +#endif /* BRCMFMAC_DEBUG_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 80e73a1262be..0421cfea9a25 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -17,7 +17,7 @@ #ifndef _BRCMF_BUS_H_ #define _BRCMF_BUS_H_ -#include "dhd_dbg.h" +#include "debug.h" /* IDs of the 6 default common rings of msgbuf protocol */ #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 98bc2226a119..78ada880506f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -21,7 +21,7 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "fwil.h" #include "fwil_types.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index fb1043908a23..2522e684c66e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -24,7 +24,7 @@ #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "fwil_types.h" #include "p2p.h" #include "wl_cfg80211.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 079187c51170..4fc2f523af06 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -97,7 +97,7 @@ struct rte_console { #include #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "tracepoint.h" #define TXQLEN 2048 /* bulk tx queue length */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c index 4eb6a41e72c7..86b854e83f71 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c @@ -19,7 +19,7 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "fwil.h" #include "feature.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index 8ea9f283d2b8..0f157f151282 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -20,7 +20,7 @@ #include #include -#include "dhd_dbg.h" +#include "debug.h" #include "firmware.h" char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c index 1faa929f5fff..15a2cc56baf0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c @@ -20,7 +20,7 @@ #include #include "dhd.h" -#include "dhd_dbg.h" +#include "debug.h" #include "dhd_bus.h" #include "proto.h" #include "flowring.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c index 44fc85f68f7a..ce98ce55685b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c @@ -19,7 +19,7 @@ #include "brcmu_utils.h" #include "dhd.h" -#include "dhd_dbg.h" +#include "debug.h" #include "tracepoint.h" #include "fwsignal.h" #include "fweh.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index dccbdc1aae6d..424146c226aa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -24,7 +24,7 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "tracepoint.h" #include "fwil.h" #include "proto.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 183f08d7fc8c..5a3cf644af2f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -27,7 +27,7 @@ #include #include #include "dhd.h" -#include "dhd_dbg.h" +#include "debug.h" #include "dhd_bus.h" #include "fwil.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 11cc051f97cd..87924d32d540 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c @@ -25,7 +25,7 @@ #include #include "dhd.h" -#include "dhd_dbg.h" +#include "debug.h" #include "proto.h" #include "msgbuf.h" #include "commonring.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c index f05f5270fec1..875060c54a00 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c @@ -21,7 +21,7 @@ #include #include -#include "dhd_dbg.h" +#include "debug.h" #include "sdio_host.h" void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index d54c58a32faa..7459c252c1dd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include "debug.h" #include "fwil.h" #include "fwil_types.h" #include "p2p.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c index 8c0632ec9f7a..d8fe7abd96c8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c @@ -30,7 +30,7 @@ #include #include -#include "dhd_dbg.h" +#include "debug.h" #include "dhd_bus.h" #include "commonring.h" #include "msgbuf.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c index 62b940723339..f96b9326fe3d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c @@ -22,7 +22,7 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_dbg.h" +#include "debug.h" #include "proto.h" #include "bcdc.h" #include "msgbuf.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 3f12b606839e..4eb9b2c158b3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -24,8 +24,8 @@ #include #include #include -#include +#include "debug.h" #include "firmware.h" #include "usb.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c index 5960d827508c..f204c83cd61f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c @@ -22,7 +22,7 @@ #include "fwil_types.h" #include "dhd.h" #include "p2p.h" -#include "dhd_dbg.h" +#include "debug.h" #include "wl_cfg80211.h" #include "vendor.h" #include "fwil.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index fcadbe3c38d6..50bc6a0b9062 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -27,7 +27,7 @@ #include #include #include "dhd.h" -#include "dhd_dbg.h" +#include "debug.h" #include "tracepoint.h" #include "fwil_types.h" #include "p2p.h" -- GitLab From d14f78b990ec4d66e9509bc42a6fce2d217880ec Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:14 +0100 Subject: [PATCH 2239/9457] brcmfmac: (clean) Rename dhd_bus.h in bus.h Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 +- .../net/wireless/brcm80211/brcmfmac/{dhd_bus.h => bus.h} | 9 ++++----- drivers/net/wireless/brcm80211/brcmfmac/debug.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/feature.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/flowring.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/proto.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 3 +-- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 16 files changed, 19 insertions(+), 21 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_bus.h => bus.h} (98%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 11d3dfae8bac..d5a2d94ffde4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -26,7 +26,7 @@ #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "fwsignal.h" #include "debug.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 8c0dfea68eeb..969bdd655c7b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -41,7 +41,7 @@ #include #include #include "chip.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "sdio_host.h" #include "of.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h similarity index 98% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h rename to drivers/net/wireless/brcm80211/brcmfmac/bus.h index 0421cfea9a25..ef344e47218a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _BRCMF_BUS_H_ -#define _BRCMF_BUS_H_ +#ifndef BRCMFMAC_BUS_H +#define BRCMFMAC_BUS_H #include "debug.h" @@ -227,8 +227,7 @@ void brcmf_txflowblock(struct device *dev, bool state); void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); int brcmf_bus_start(struct device *dev); -s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, - u32 len); +s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); void brcmf_bus_add_txhdrlen(struct device *dev, uint len); #ifdef CONFIG_BRCMFMAC_SDIO @@ -241,4 +240,4 @@ void brcmf_usb_exit(void); void brcmf_usb_register(void); #endif -#endif /* _BRCMF_BUS_H_ */ +#endif /* BRCMFMAC_BUS_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c index 27e51085d33a..340b10447ab9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c @@ -20,7 +20,7 @@ #include #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" static struct dentry *root_folder; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 78ada880506f..7723994136a1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -20,7 +20,7 @@ #include #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "fwil.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 2522e684c66e..8dbf2c155b5b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -23,7 +23,7 @@ #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "fwil_types.h" #include "p2p.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4fc2f523af06..224e922d139a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -96,7 +96,7 @@ struct rte_console { #endif /* DEBUG */ #include -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c index 86b854e83f71..d4be4c416912 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c @@ -18,7 +18,7 @@ #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "fwil.h" #include "feature.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c index 15a2cc56baf0..e9cb550f5c5a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c @@ -21,7 +21,7 @@ #include "dhd.h" #include "debug.h" -#include "dhd_bus.h" +#include "bus.h" #include "proto.h" #include "flowring.h" #include "msgbuf.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 424146c226aa..70db41f51b7b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -23,7 +23,7 @@ #include #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "tracepoint.h" #include "fwil.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 5a3cf644af2f..dbd52ccbde56 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -28,7 +28,7 @@ #include #include "dhd.h" #include "debug.h" -#include "dhd_bus.h" +#include "bus.h" #include "fwil.h" #include "fwil_types.h" #include "fweh.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 87924d32d540..18e1770b8d8c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c @@ -30,7 +30,7 @@ #include "msgbuf.h" #include "commonring.h" #include "flowring.h" -#include "dhd_bus.h" +#include "bus.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c index d8fe7abd96c8..b0ae7993e2e8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c @@ -31,7 +31,7 @@ #include #include "debug.h" -#include "dhd_bus.h" +#include "bus.h" #include "commonring.h" #include "msgbuf.h" #include "pcie.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c index f96b9326fe3d..5e83b2bee9d8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c @@ -21,7 +21,7 @@ #include #include "dhd.h" -#include "dhd_bus.h" +#include "bus.h" #include "debug.h" #include "proto.h" #include "bcdc.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 4eb9b2c158b3..5265aa70b094 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -23,8 +23,7 @@ #include #include #include -#include - +#include "bus.h" #include "debug.h" #include "firmware.h" #include "usb.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 50bc6a0b9062..2560dff4151e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -37,7 +37,7 @@ #include "fwil.h" #include "proto.h" #include "vendor.h" -#include "dhd_bus.h" +#include "bus.h" #define BRCMF_SCAN_IE_LEN_MAX 2048 #define BRCMF_PNO_VERSION 2 -- GitLab From 76b5a96d1df10535c7e2e7f876f2230e243aa7b8 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:15 +0100 Subject: [PATCH 2240/9457] brcmfmac: (clean) Rename dhd_common.c in common.c Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- .../wireless/brcm80211/brcmfmac/{dhd_common.c => common.c} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_common.c => common.c} (99%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 1da9042c8aba..f6e35c95b829 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -30,7 +30,7 @@ brcmfmac-objs += \ fwsignal.o \ p2p.o \ proto.o \ - dhd_common.o \ + common.o \ dhd_linux.o \ firmware.o \ feature.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/common.c similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c rename to drivers/net/wireless/brcm80211/brcmfmac/common.c index 7723994136a1..75642e46c37a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c @@ -52,9 +52,9 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, } /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) + if (pktq_pfull(q, prec)) { eprec = prec; - else if (pktq_full(q)) { + } else if (pktq_full(q)) { p = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) return false; -- GitLab From bfe8197582f369dea55e1ef431a51d0b227704c8 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:16 +0100 Subject: [PATCH 2241/9457] brcmfmac: (clean) Rename files wl_cfg80211 to cfg80211 Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/btcoex.c | 2 +- .../brcm80211/brcmfmac/{wl_cfg80211.c => cfg80211.c} | 5 +++-- .../brcm80211/brcmfmac/{wl_cfg80211.h => cfg80211.h} | 9 +++++---- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/vendor.c | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{wl_cfg80211.c => cfg80211.c} (99%) rename drivers/net/wireless/brcm80211/brcmfmac/{wl_cfg80211.h => cfg80211.h} (98%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index f6e35c95b829..35b680550446 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -23,7 +23,7 @@ ccflags-y += -D__CHECK_ENDIAN__ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += \ - wl_cfg80211.o \ + cfg80211.o \ chip.o \ fwil.o \ fweh.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c index a2f7e2ccfc84..e324414fcf6d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c @@ -26,7 +26,7 @@ #include "fwil_types.h" #include "btcoex.h" #include "p2p.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" /* T1 start SCO/eSCO priority suppression */ #define BRCMF_BTCOEX_OPPR_WIN_TIME 2000 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c rename to drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index 2560dff4151e..0390e57613cd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c @@ -32,7 +32,7 @@ #include "fwil_types.h" #include "p2p.h" #include "btcoex.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" #include "feature.h" #include "fwil.h" #include "proto.h" @@ -5657,7 +5657,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp) return wdev->iftype; } -bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state) +bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, + unsigned long state) { struct brcmf_cfg80211_vif *vif; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h similarity index 98% rename from drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h rename to drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h index 6abf94e41d3d..2a5b22cb3fef 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wl_cfg80211_h_ -#define _wl_cfg80211_h_ +#ifndef BRCMFMAC_CFG80211_H +#define BRCMFMAC_CFG80211_H /* for brcmu_d11inf */ #include @@ -480,7 +480,8 @@ const struct brcmf_tlv * brcmf_parse_tlvs(const void *buf, int buflen, uint key); u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, struct ieee80211_channel *ch); -bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state); +bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, + unsigned long state); void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, struct brcmf_cfg80211_vif *vif); bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); @@ -493,4 +494,4 @@ void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); void brcmf_cfg80211_free_netdev(struct net_device *ndev); -#endif /* _wl_cfg80211_h_ */ +#endif /* BRCMFMAC_CFG80211_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 8dbf2c155b5b..53650b9cb768 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -27,7 +27,7 @@ #include "debug.h" #include "fwil_types.h" #include "p2p.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" #include "fwil.h" #include "fwsignal.h" #include "feature.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index dbd52ccbde56..6d33331dd2b0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -34,7 +34,7 @@ #include "fweh.h" #include "fwsignal.h" #include "p2p.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" #include "proto.h" /** diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index 7459c252c1dd..ae504b40e554 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -26,7 +26,7 @@ #include "fwil.h" #include "fwil_types.h" #include "p2p.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" /* parameters used for p2p escan */ #define P2PAPI_SCAN_NPROBES 1 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c index f204c83cd61f..b86a08369517 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c @@ -23,7 +23,7 @@ #include "dhd.h" #include "p2p.h" #include "debug.h" -#include "wl_cfg80211.h" +#include "cfg80211.h" #include "vendor.h" #include "fwil.h" -- GitLab From 888bf76e41119bf72256830bce0eb192a6a4033a Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:17 +0100 Subject: [PATCH 2242/9457] brcmfmac: (clean) Rename sdio related files. Rename sdio_host.h to sdio.h and dhd_sdio.c to sdio.c. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/of.c | 2 +- .../net/wireless/brcm80211/brcmfmac/{dhd_sdio.c => sdio.c} | 4 ++-- .../net/wireless/brcm80211/brcmfmac/{sdio_host.h => sdio.h} | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_sdio.c => sdio.c} (99%) rename drivers/net/wireless/brcm80211/brcmfmac/{sdio_host.h => sdio.h} (99%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 35b680550446..40ba46b4809d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -43,7 +43,7 @@ brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \ flowring.o \ msgbuf.o brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ - dhd_sdio.o \ + sdio.o \ bcmsdh.o brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 969bdd655c7b..f754ffcd0308 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -43,7 +43,7 @@ #include "chip.h" #include "bus.h" #include "debug.h" -#include "sdio_host.h" +#include "sdio.h" #include "of.h" #define SDIOH_API_ACCESS_RETRY_LIMIT 2 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c index 875060c54a00..eb3fce82a223 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c @@ -22,7 +22,7 @@ #include #include "debug.h" -#include "sdio_host.h" +#include "sdio.h" void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c rename to drivers/net/wireless/brcm80211/brcmfmac/sdio.c index 224e922d139a..73ac0c38a32a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c @@ -40,7 +40,7 @@ #include #include #include -#include "sdio_host.h" +#include "sdio.h" #include "chip.h" #include "firmware.h" @@ -4076,7 +4076,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) /* platform specific configuration: * alignments must be at least 4 bytes for ADMA - */ + */ bus->head_align = ALIGNMENT; bus->sgentry_align = ALIGNMENT; if (sdiodev->pdata) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h rename to drivers/net/wireless/brcm80211/brcmfmac/sdio.h index 262aedfeaa30..8eb42620129c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _BRCM_SDH_H_ -#define _BRCM_SDH_H_ +#ifndef BRCMFMAC_SDIO_H +#define BRCMFMAC_SDIO_H #include #include @@ -337,4 +337,4 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus); void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); void brcmf_sdio_wowl_config(struct device *dev, bool enabled); -#endif /* _BRCM_SDH_H_ */ +#endif /* BRCMFMAC_SDIO_H */ -- GitLab From 122d3d04d769455efba396f516f61c5a55791519 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:18 +0100 Subject: [PATCH 2243/9457] brcmfmac: (clean) Rename sdio related files. Rename sdio_host.h to sdio.h and dhd_sdio.c to sdio.c. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/btcoex.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/common.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/commonring.c | 2 +- .../net/wireless/brcm80211/brcmfmac/{dhd_linux.c => core.c} | 2 +- drivers/net/wireless/brcm80211/brcmfmac/{dhd.h => core.h} | 6 +++--- drivers/net/wireless/brcm80211/brcmfmac/debug.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/feature.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/flowring.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fweh.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/proto.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/vendor.c | 2 +- 18 files changed, 20 insertions(+), 20 deletions(-) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd_linux.c => core.c} (99%) rename drivers/net/wireless/brcm80211/brcmfmac/{dhd.h => core.h} (98%) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 40ba46b4809d..dc4c75083085 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -31,7 +31,7 @@ brcmfmac-objs += \ p2p.o \ proto.o \ common.o \ - dhd_linux.o \ + core.o \ firmware.o \ feature.o \ btcoex.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index d5a2d94ffde4..8e0e91c4a0b1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -25,7 +25,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "fwsignal.h" #include "debug.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c index e324414fcf6d..0445163991b7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include "core.h" #include "debug.h" #include "fwil.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index 0390e57613cd..8822f2b8d74d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c @@ -26,7 +26,7 @@ #include #include #include -#include "dhd.h" +#include "core.h" #include "debug.h" #include "tracepoint.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.c b/drivers/net/wireless/brcm80211/brcmfmac/common.c index 75642e46c37a..183cec9939ea 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c @@ -19,7 +19,7 @@ #include #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" #include "fwil.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c index c6d65b8e1e15..77656c711bed 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c @@ -19,7 +19,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "commonring.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c similarity index 99% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c rename to drivers/net/wireless/brcm80211/brcmfmac/core.c index 53650b9cb768..f407665cb1ea 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c @@ -22,7 +22,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h similarity index 98% rename from drivers/net/wireless/brcm80211/brcmfmac/dhd.h rename to drivers/net/wireless/brcm80211/brcmfmac/core.h index 5e4317dbc2b0..7df22bdb19a2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h @@ -18,8 +18,8 @@ * Common types * */ -#ifndef _BRCMF_H_ -#define _BRCMF_H_ +#ifndef BRCMFMAC_CORE_H +#define BRCMFMAC_CORE_H #include "fweh.h" @@ -186,4 +186,4 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); /* Sets dongle media info (drv_version, mac address). */ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); -#endif /* _BRCMF_H_ */ +#endif /* BRCMFMAC_CORE_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/brcm80211/brcmfmac/debug.c index 340b10447ab9..9b473d50b005 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c @@ -19,7 +19,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c index d4be4c416912..931f68aefaa4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c @@ -17,7 +17,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" #include "fwil.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c index e9cb550f5c5a..44f3a84d1999 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c @@ -19,7 +19,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "debug.h" #include "bus.h" #include "proto.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c index ce98ce55685b..7338b335e153 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c @@ -18,7 +18,7 @@ #include "brcmu_wifi.h" #include "brcmu_utils.h" -#include "dhd.h" +#include "core.h" #include "debug.h" #include "tracepoint.h" #include "fwsignal.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 70db41f51b7b..51f88c11e642 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -22,7 +22,7 @@ #include #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 6d33331dd2b0..f0dda0ecd23b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -26,7 +26,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "debug.h" #include "bus.h" #include "fwil.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 18e1770b8d8c..02d39ce8dbca 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c @@ -24,7 +24,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "debug.h" #include "proto.h" #include "msgbuf.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index ae504b40e554..effb48ebd864 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include "core.h" #include "debug.h" #include "fwil.h" #include "fwil_types.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c index 5e83b2bee9d8..26b68c367f57 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c @@ -20,7 +20,7 @@ #include #include -#include "dhd.h" +#include "core.h" #include "bus.h" #include "debug.h" #include "proto.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c index b86a08369517..222f26a39642 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c @@ -20,7 +20,7 @@ #include #include "fwil_types.h" -#include "dhd.h" +#include "core.h" #include "p2p.h" #include "debug.h" #include "cfg80211.h" -- GitLab From 84936626efbfacaf53505020610ae275fae2bf88 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Tue, 28 Oct 2014 14:56:19 +0100 Subject: [PATCH 2244/9457] brcmfmac: (clean) Move sdio related function. prec_enq is a sdio specific function. Move it to sdio.c. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/common.c | 51 ------------------- .../net/wireless/brcm80211/brcmfmac/core.h | 1 - .../net/wireless/brcm80211/brcmfmac/sdio.c | 46 ++++++++++++++++- 3 files changed, 44 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.c b/drivers/net/wireless/brcm80211/brcmfmac/common.c index 183cec9939ea..1861a13e8d03 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c @@ -33,57 +33,6 @@ /* boost value for RSSI_DELTA in preferred join selection */ #define BRCMF_JOIN_PREF_RSSI_BOOST 8 - -bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, - struct sk_buff *pkt, int prec) -{ - struct sk_buff *p; - int eprec = -1; /* precedence to evict from */ - bool discard_oldest; - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_pub *drvr = bus_if->drvr; - - /* Fast case, precedence queue is not full and we are also not - * exceeding total queue length - */ - if (!pktq_pfull(q, prec) && !pktq_full(q)) { - brcmu_pktq_penq(q, prec, pkt); - return true; - } - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) { - eprec = prec; - } else if (pktq_full(q)) { - p = brcmu_pktq_peek_tail(q, &eprec); - if (eprec > prec) - return false; - } - - /* Evict if needed */ - if (eprec >= 0) { - /* Detect queueing to unconfigured precedence */ - discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec); - if (eprec == prec && !discard_oldest) - return false; /* refuse newer (incoming) packet */ - /* Evict packet according to discard policy */ - p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : - brcmu_pktq_pdeq_tail(q, eprec); - if (p == NULL) - brcmf_err("brcmu_pktq_penq() failed, oldest %d\n", - discard_oldest); - - brcmu_pkt_buf_free_skb(p); - } - - /* Enqueue */ - p = brcmu_pktq_penq(q, prec, pkt); - if (p == NULL) - brcmf_err("brcmu_pktq_penq() failed\n"); - - return p != NULL; -} - int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) { s8 eventmask[BRCMF_EVENTING_MASK_LEN]; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h index 7df22bdb19a2..98228e922d3a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h @@ -83,7 +83,6 @@ struct brcmf_pub { /* Internal brcmf items */ uint hdrlen; /* Total BRCMF header length (proto + bus) */ uint rxsz; /* Rx buffer size bus module should use */ - u8 wme_dp; /* wme discard priority */ /* Dongle media info */ char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c index 73ac0c38a32a..72e87b51f999 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c @@ -2763,6 +2763,48 @@ static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev) return &bus->txq; } +static bool brcmf_sdio_prec_enq(struct pktq *q, struct sk_buff *pkt, int prec) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Fast case, precedence queue is not full and we are also not + * exceeding total queue length + */ + if (!pktq_pfull(q, prec) && !pktq_full(q)) { + brcmu_pktq_penq(q, prec, pkt); + return true; + } + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) { + eprec = prec; + } else if (pktq_full(q)) { + p = brcmu_pktq_peek_tail(q, &eprec); + if (eprec > prec) + return false; + } + + /* Evict if needed */ + if (eprec >= 0) { + /* Detect queueing to unconfigured precedence */ + if (eprec == prec) + return false; /* refuse newer (incoming) packet */ + /* Evict packet according to discard policy */ + p = brcmu_pktq_pdeq_tail(q, eprec); + if (p == NULL) + brcmf_err("brcmu_pktq_pdeq_tail() failed\n"); + brcmu_pkt_buf_free_skb(p); + } + + /* Enqueue */ + p = brcmu_pktq_penq(q, prec, pkt); + if (p == NULL) + brcmf_err("brcmu_pktq_penq() failed\n"); + + return p != NULL; +} + static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) { int ret = -EBADE; @@ -2788,7 +2830,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) spin_lock_bh(&bus->txq_lock); /* reset bus_flags in packet cb */ *(u16 *)(pkt->cb) = 0; - if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { + if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec)) { skb_pull(pkt, bus->tx_hdrlen); brcmf_err("out of bus->txq !!!\n"); ret = -ENOSR; @@ -2798,7 +2840,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) if (pktq_len(&bus->txq) >= TXHI) { bus->txoff = true; - brcmf_txflowblock(bus->sdiodev->dev, true); + brcmf_txflowblock(dev, true); } spin_unlock_bh(&bus->txq_lock); -- GitLab From cded936962a3be2f8fe1f0b4a4e3c45d8a8047ce Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Tue, 28 Oct 2014 16:50:06 +0200 Subject: [PATCH 2245/9457] wil6210: do not attempt FW recovery if interface is down When interface is down, recovery flow should not be attempted. Next ndo_open() will trigger target reset, that is FW recovery. Doing recovery while interface is down cause internal "up", leaving internal driver state in conflict with network stack. Then, when network stack will call ndo_open(), kernel oops will be triggered. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 6500caf8d609..79003844008a 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -223,6 +223,11 @@ static void wil_fw_error_worker(struct work_struct *work) wil_dbg_misc(wil, "fw error worker\n"); + if (!netif_running(wil_to_ndev(wil))) { + wil_info(wil, "No recovery - interface is down\n"); + return; + } + /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO * passed since last recovery attempt */ -- GitLab From 48516298edb4260748c52064f828319c3bb15536 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Tue, 28 Oct 2014 16:50:07 +0200 Subject: [PATCH 2246/9457] wil6210: reset flow updates As communicated with the firmware & hardware teams Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/main.c | 23 +++++++++++++++++----- drivers/net/wireless/ath/wil6210/wil6210.h | 6 ++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 79003844008a..0e95557e177f 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -400,7 +400,7 @@ static inline void wil_release_cpu(struct wil6210_priv *wil) static int wil_target_reset(struct wil6210_priv *wil) { int delay = 0; - u32 hw_state; + u32 x; u32 rev_id; bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW); @@ -415,9 +415,22 @@ static int wil_target_reset(struct wil6210_priv *wil) S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_CAR_PERST_RST); wil_halt_cpu(wil); - C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); /* 40 MHz */ if (is_sparrow) { + S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); + /* XTAL stabilization should take about 3ms */ + usleep_range(5000, 7000); + x = R(RGF_CAF_PLL_LOCK_STATUS); + if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) { + wil_err(wil, "Xtal stabilization timeout\n" + "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x); + return -ETIME; + } + /* switch 10k to XTAL*/ + C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF); + /* 40 MHz */ + C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); + W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf); } @@ -458,13 +471,13 @@ static int wil_target_reset(struct wil6210_priv *wil) /* wait until device ready. typical time is 200..250 msec */ do { msleep(RST_DELAY); - hw_state = R(RGF_USER_HW_MACHINE_STATE); + x = R(RGF_USER_HW_MACHINE_STATE); if (delay++ > RST_COUNT) { wil_err(wil, "Reset not completed, hw_state 0x%08x\n", - hw_state); + x); return -ETIME; } - } while (hw_state != HW_MACHINE_BOOT_DONE); + } while (x != HW_MACHINE_BOOT_DONE); /* TODO: Erez check rev_id != 1 */ if (!is_sparrow && (rev_id != 1)) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 7ffaf2fce097..18f8729a6b2c 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -117,6 +117,8 @@ struct RGF_ICR { #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18) #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c) +#define RGF_USER_SPARROW_M_4 (0x880c50) /* Sparrow */ + #define BIT_SPARROW_M_4_SEL_SLEEP_OR_REF BIT(2) #define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) @@ -152,6 +154,10 @@ struct RGF_ICR { #define RGF_MAC_MTRL_COUNTER_0 (0x886aa8) #define RGF_CAF_ICR (0x88946c) /* struct RGF_ICR */ +#define RGF_CAF_OSC_CONTROL (0x88afa4) + #define BIT_CAF_OSC_XTAL_EN BIT(0) +#define RGF_CAF_PLL_LOCK_STATUS (0x88afec) + #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) /* popular locations */ #define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) -- GitLab From b516fcc5542d41041156b8e5f93f47cbb603c4b7 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Tue, 28 Oct 2014 16:50:08 +0200 Subject: [PATCH 2247/9457] wil6210: prevent double disconnect command issuing Disconnect flow may be invoked either from upper layer request, or from event reported by the firmware. In case of firmware event, driver need to release resources for the station but not send another disconnect WMI command. In case of upper layer request, WMI_DISCONNECT_STA_CMDID command need to be issued for the firmware to perform disconnect on the MAC layer. Eventually, event is expected to confirm MAC disconnect, but it is better to not wait for firmware event and release station resources immediately. FW may fail to report disconnect for various reasons, so one could not rely on event always reported. Introduce parameter to distinguish 2 cases above to prevent double WMI command issuing. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/cfg80211.c | 2 +- drivers/net/wireless/ath/wil6210/main.c | 35 +++++++++++++++------ drivers/net/wireless/ath/wil6210/wil6210.h | 3 +- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index d9f4b30dd343..4248fb3352d2 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -797,7 +797,7 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy, struct wil6210_priv *wil = wiphy_to_wil(wiphy); mutex_lock(&wil->mutex); - wil6210_disconnect(wil, mac); + wil6210_disconnect(wil, mac, false); mutex_unlock(&wil->mutex); return 0; diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 0e95557e177f..b3a84ae04ce3 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -74,7 +74,8 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, __raw_writel(*s++, d++); } -static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) +static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, + bool from_event) { uint i; struct net_device *ndev = wil_to_ndev(wil); @@ -86,7 +87,10 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) sta->data_port_open = false; if (sta->status != wil_sta_unused) { - wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING); + if (!from_event) + wmi_disconnect_sta(wil, sta->addr, + WLAN_REASON_DEAUTH_LEAVING); + switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: @@ -118,7 +122,8 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) memset(&sta->stats, 0, sizeof(sta->stats)); } -static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) +static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, + bool from_event) { int cid = -ENOENT; struct net_device *ndev = wil_to_ndev(wil); @@ -133,10 +138,10 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) } if (cid >= 0) /* disconnect 1 peer */ - wil_disconnect_cid(wil, cid); + wil_disconnect_cid(wil, cid, from_event); else /* disconnect all */ for (cid = 0; cid < WIL6210_MAX_CID; cid++) - wil_disconnect_cid(wil, cid); + wil_disconnect_cid(wil, cid, from_event); /* link state */ switch (wdev->iftype) { @@ -166,7 +171,7 @@ static void wil_disconnect_worker(struct work_struct *work) struct wil6210_priv, disconnect_worker); mutex_lock(&wil->mutex); - _wil6210_disconnect(wil, NULL); + _wil6210_disconnect(wil, NULL, false); mutex_unlock(&wil->mutex); } @@ -351,12 +356,22 @@ int wil_priv_init(struct wil6210_priv *wil) return 0; } -void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) +/** + * wil6210_disconnect - disconnect one connection + * @wil: driver context + * @bssid: peer to disconnect, NULL to disconnect all + * @from_event: whether is invoked from FW event handler + * + * Disconnect and release associated resources. If invoked not from the + * FW event handler, issue WMI command(s) to trigger MAC disconnect. + */ +void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, + bool from_event) { wil_dbg_misc(wil, "%s()\n", __func__); del_timer_sync(&wil->connect_timer); - _wil6210_disconnect(wil, bssid); + _wil6210_disconnect(wil, bssid, from_event); } void wil_priv_deinit(struct wil6210_priv *wil) @@ -368,7 +383,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) cancel_work_sync(&wil->disconnect_worker); cancel_work_sync(&wil->fw_error_worker); mutex_lock(&wil->mutex); - wil6210_disconnect(wil, NULL); + wil6210_disconnect(wil, NULL, false); mutex_unlock(&wil->mutex); wmi_event_flush(wil); destroy_workqueue(wil->wmi_wq_conn); @@ -553,7 +568,7 @@ int wil_reset(struct wil6210_priv *wil) WARN_ON(test_bit(wil_status_napi_en, &wil->status)); cancel_work_sync(&wil->disconnect_worker); - wil6210_disconnect(wil, NULL); + wil6210_disconnect(wil, NULL, false); wil->status = 0; /* prevent NAPI from being scheduled */ diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 18f8729a6b2c..3674e2732192 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -584,7 +584,8 @@ void wil_wdev_free(struct wil6210_priv *wil); int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); int wmi_pcp_stop(struct wil6210_priv *wil); -void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid); +void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, + bool from_event); int wil_rx_init(struct wil6210_priv *wil); void wil_rx_fini(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 4311df982c60..9661fa150167 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -486,7 +486,7 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, wil->sinfo_gen++; mutex_lock(&wil->mutex); - wil6210_disconnect(wil, evt->bssid); + wil6210_disconnect(wil, evt->bssid, true); mutex_unlock(&wil->mutex); } -- GitLab From e240537b4c7303748fe44e03a6309d1d55893cd3 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Tue, 28 Oct 2014 16:50:09 +0200 Subject: [PATCH 2248/9457] wil6210: improve dmesg for fw error handling In case of FW error, make it clear (in dmesg) what branch is taken in the error recovery code. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index b3a84ae04ce3..92705c0d97a4 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -267,9 +267,12 @@ static void wil_fw_error_worker(struct work_struct *work) break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: + wil_info(wil, "No recovery for AP-like interface\n"); /* recovery in these modes is done by upper layers */ break; default: + wil_err(wil, "No recovery - unknown interface type %d\n", + wdev->iftype); break; } mutex_unlock(&wil->mutex); -- GitLab From 9a06bec9aee0ae54f175b20a8d4f5e14aef24a9f Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Tue, 28 Oct 2014 16:51:27 +0200 Subject: [PATCH 2249/9457] wil6210: Add support for large packets It is possible to configure driver using mtu_max module parameter by setting it to value in range of 68..7920 inclusive. This is sub-optimal performance-wise in case packet is larger than 1 page. mtu_max default value is 2228. Signed-off-by: Vladimir Kondratiev Signed-off-by: John W. Linville --- drivers/net/wireless/ath/wil6210/main.c | 29 ++++++++++++++++++++++ drivers/net/wireless/ath/wil6210/netdev.c | 2 +- drivers/net/wireless/ath/wil6210/txrx.c | 7 +++--- drivers/net/wireless/ath/wil6210/txrx.h | 4 +-- drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 2 +- 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 92705c0d97a4..6212983fede2 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -38,6 +38,35 @@ static unsigned int itr_trsh = WIL6210_ITR_TRSH_DEFAULT; module_param(itr_trsh, uint, S_IRUGO); MODULE_PARM_DESC(itr_trsh, " Interrupt moderation threshold, usecs."); +/* We allow allocation of more than 1 page buffers to support large packets. + * It is suboptimal behavior performance wise in case MTU above page size. + */ +unsigned int mtu_max = TXRX_BUF_LEN_DEFAULT - ETH_HLEN; +static int mtu_max_set(const char *val, const struct kernel_param *kp) +{ + int ret; + + /* sets mtu_max directly. no need to restore it in case of + * illegal value since we assume this will fail insmod + */ + ret = param_set_uint(val, kp); + if (ret) + return ret; + + if (mtu_max < 68 || mtu_max > IEEE80211_MAX_DATA_LEN_DMG) + ret = -EINVAL; + + return ret; +} + +static struct kernel_param_ops mtu_max_ops = { + .set = mtu_max_set, + .get = param_get_uint, +}; + +module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, S_IRUGO); +MODULE_PARM_DESC(mtu_max, " Max MTU value."); + #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 239965106c05..e81703ca7701 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -41,7 +41,7 @@ static int wil_change_mtu(struct net_device *ndev, int new_mtu) { struct wil6210_priv *wil = ndev_to_wil(ndev); - if (new_mtu < 68 || new_mtu > (TX_BUF_LEN - ETH_HLEN)) { + if (new_mtu < 68 || new_mtu > mtu_max) { wil_err(wil, "invalid MTU %d\n", new_mtu); return -EINVAL; } diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 2936ef0c18cb..c680906bc0dc 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -206,7 +206,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, u32 i, int headroom) { struct device *dev = wil_to_dev(wil); - unsigned int sz = RX_BUF_LEN; + unsigned int sz = mtu_max + ETH_HLEN; struct vring_rx_desc dd, *d = ⅆ volatile struct vring_rx_desc *_d = &vring->va[i].rx; dma_addr_t pa; @@ -385,7 +385,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, struct vring_rx_desc *d; struct sk_buff *skb; dma_addr_t pa; - unsigned int sz = RX_BUF_LEN; + unsigned int sz = mtu_max + ETH_HLEN; u16 dmalen; u8 ftype; u8 ds_bits; @@ -646,7 +646,8 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, .action = cpu_to_le32(WMI_VRING_CMD_ADD), .vring_cfg = { .tx_sw_ring = { - .max_mpdu_size = cpu_to_le16(TX_BUF_LEN), + .max_mpdu_size = + cpu_to_le16(mtu_max + ETH_HLEN), .ring_size = cpu_to_le16(size), }, .ringid = id, diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index de046716d2b7..630aeb5fa7f4 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -21,8 +21,8 @@ #define BUF_HW_OWNED (0) /* size of max. Tx/Rx buffers, as supported by FW */ -#define RX_BUF_LEN (2242) -#define TX_BUF_LEN (2242) +#define TXRX_BUF_LEN_DEFAULT (2242) + /* how many bytes to reserve for rtap header? */ #define WIL6210_RTAP_SIZE (128) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 3674e2732192..95d3a062d35c 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -24,6 +24,7 @@ #include "wil_platform.h" extern bool no_fw_recovery; +extern unsigned int mtu_max; #define WIL_NAME "wil6210" #define WIL_FW_NAME "wil6210.fw" diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 9661fa150167..bb1e066f756a 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -1025,7 +1025,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) struct wmi_cfg_rx_chain_cmd cmd = { .action = WMI_RX_CHAIN_ADD, .rx_sw_ring = { - .max_mpdu_size = cpu_to_le16(RX_BUF_LEN), + .max_mpdu_size = cpu_to_le16(mtu_max + ETH_HLEN), .ring_mem_base = cpu_to_le64(vring->pa), .ring_size = cpu_to_le16(vring->size), }, -- GitLab From 7a1283d8f5298437a454ec477384dcd9f9f88bac Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 28 Oct 2014 14:18:58 -0700 Subject: [PATCH 2250/9457] carl9170: Convert byte_rev_table uses to bitrev8 Use the inline function instead of directly indexing the array. This allows some architectures with hardware instructions for bit reversals to eliminate the array. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index b80b2138ce3c..dca6df13fd5b 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -994,7 +994,7 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, refsel0 = 0; refsel1 = 1; } - chansel = byte_rev_table[chansel]; + chansel = bitrev8(chansel); } else { if (freq == 2484) { chansel = 10 + (freq - 2274) / 5; @@ -1002,7 +1002,7 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, } else chansel = 16 + (freq - 2272) / 5; chansel *= 4; - chansel = byte_rev_table[chansel]; + chansel = bitrev8(chansel); } d1 = chansel; -- GitLab From 9146782b1bba3323ef492614402ab0805b597638 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 29 Oct 2014 16:02:50 +0100 Subject: [PATCH 2251/9457] brcmsmac: fix statistic counter update function The 802.11 core statistics are retrieved from the core registers but not stored. So the debug code was never triggered to give a warning message on tx underruns or rx overflows. This patch fixes this and assures the statistics are stored in the snapshot. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 1b474828d5b8..bc9be78faafa 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -3081,7 +3081,7 @@ static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) static void brcms_c_statsupd(struct brcms_c_info *wlc) { int i; - struct macstat macstats; + struct macstat *macstats; #ifdef DEBUG u16 delta; u16 rxf0ovfl; @@ -3092,31 +3092,31 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) if (!wlc->pub->up) return; + macstats = wlc->core->macstat_snapshot; + #ifdef DEBUG /* save last rx fifo 0 overflow count */ - rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; + rxf0ovfl = macstats->rxf0ovfl; /* save last tx fifo underflow count */ for (i = 0; i < NFIFO; i++) - txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; + txfunfl[i] = macstats->txfunfl[i]; #endif /* DEBUG */ /* Read mac stats from contiguous shared memory */ - brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats, - sizeof(struct macstat), OBJADDR_SHM_SEL); + brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, macstats, + sizeof(*macstats), OBJADDR_SHM_SEL); #ifdef DEBUG /* check for rx fifo 0 overflow */ - delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); + delta = (u16)(macstats->rxf0ovfl - rxf0ovfl); if (delta) brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", wlc->pub->unit, delta); /* check for tx fifo underflows */ for (i = 0; i < NFIFO; i++) { - delta = - (u16) (wlc->core->macstat_snapshot->txfunfl[i] - - txfunfl[i]); + delta = macstats->txfunfl[i] - txfunfl[i]; if (delta) brcms_err(wlc->hw->d11core, "wl%d: %u tx fifo %d underflows!\n", -- GitLab From 3fe33c4cec15c4dec7935c1f08811fab43343bf0 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 29 Oct 2014 16:02:51 +0100 Subject: [PATCH 2252/9457] brcmsmac: expose 802.11 core statistics in debugfs The 802.11 statistics obtained from the device can be retrieved dumping the 'macstat' file in debugfs folder. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/debug.c | 166 ++++++++++++++---- 1 file changed, 133 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c index a5d4add26f41..19740c1b1566 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/debug.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c @@ -71,48 +71,148 @@ struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) } static -ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) +int brcms_debugfs_hardware_read(struct seq_file *s, void *data) { - char buf[128]; - int res; - struct brcms_pub *drvr = f->private_data; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), - "board vendor: %x\n" - "board type: %x\n" - "board revision: %x\n" - "board flags: %x\n" - "board flags2: %x\n" - "firmware revision: %x\n", - drvr->wlc->hw->d11core->bus->boardinfo.vendor, - drvr->wlc->hw->d11core->bus->boardinfo.type, - drvr->wlc->hw->boardrev, - drvr->wlc->hw->boardflags, - drvr->wlc->hw->boardflags2, - drvr->wlc->ucode_rev - ); - - return simple_read_from_buffer(data, count, ppos, buf, res); + struct brcms_pub *drvr = s->private; + + seq_printf(s, "board vendor: %x\n" + "board type: %x\n" + "board revision: %x\n" + "board flags: %x\n" + "board flags2: %x\n" + "firmware revision: %x\n", + drvr->wlc->hw->d11core->bus->boardinfo.vendor, + drvr->wlc->hw->d11core->bus->boardinfo.type, + drvr->wlc->hw->boardrev, + drvr->wlc->hw->boardflags, + drvr->wlc->hw->boardflags2, + drvr->wlc->ucode_rev); + + return 0; +} + +static int brcms_debugfs_macstat_read(struct seq_file *s, void *data) +{ + struct brcms_pub *drvr = s->private; + struct brcms_info *wl = drvr->ieee_hw->priv; + struct macstat stats; + int i; + + spin_lock_bh(&wl->lock); + stats = *(drvr->wlc->core->macstat_snapshot); + spin_unlock_bh(&wl->lock); + + seq_printf(s, "txallfrm: %d\n", stats.txallfrm); + seq_printf(s, "txrtsfrm: %d\n", stats.txrtsfrm); + seq_printf(s, "txctsfrm: %d\n", stats.txctsfrm); + seq_printf(s, "txackfrm: %d\n", stats.txackfrm); + seq_printf(s, "txdnlfrm: %d\n", stats.txdnlfrm); + seq_printf(s, "txbcnfrm: %d\n", stats.txbcnfrm); + seq_printf(s, "txfunfl[8]:"); + for (i = 0; i < ARRAY_SIZE(stats.txfunfl); i++) + seq_printf(s, " %d", stats.txfunfl[i]); + seq_printf(s, "\ntxtplunfl: %d\n", stats.txtplunfl); + seq_printf(s, "txphyerr: %d\n", stats.txphyerr); + seq_printf(s, "pktengrxducast: %d\n", stats.pktengrxducast); + seq_printf(s, "pktengrxdmcast: %d\n", stats.pktengrxdmcast); + seq_printf(s, "rxfrmtoolong: %d\n", stats.rxfrmtoolong); + seq_printf(s, "rxfrmtooshrt: %d\n", stats.rxfrmtooshrt); + seq_printf(s, "rxinvmachdr: %d\n", stats.rxinvmachdr); + seq_printf(s, "rxbadfcs: %d\n", stats.rxbadfcs); + seq_printf(s, "rxbadplcp: %d\n", stats.rxbadplcp); + seq_printf(s, "rxcrsglitch: %d\n", stats.rxcrsglitch); + seq_printf(s, "rxstrt: %d\n", stats.rxstrt); + seq_printf(s, "rxdfrmucastmbss: %d\n", stats.rxdfrmucastmbss); + seq_printf(s, "rxmfrmucastmbss: %d\n", stats.rxmfrmucastmbss); + seq_printf(s, "rxcfrmucast: %d\n", stats.rxcfrmucast); + seq_printf(s, "rxrtsucast: %d\n", stats.rxrtsucast); + seq_printf(s, "rxctsucast: %d\n", stats.rxctsucast); + seq_printf(s, "rxackucast: %d\n", stats.rxackucast); + seq_printf(s, "rxdfrmocast: %d\n", stats.rxdfrmocast); + seq_printf(s, "rxmfrmocast: %d\n", stats.rxmfrmocast); + seq_printf(s, "rxcfrmocast: %d\n", stats.rxcfrmocast); + seq_printf(s, "rxrtsocast: %d\n", stats.rxrtsocast); + seq_printf(s, "rxctsocast: %d\n", stats.rxctsocast); + seq_printf(s, "rxdfrmmcast: %d\n", stats.rxdfrmmcast); + seq_printf(s, "rxmfrmmcast: %d\n", stats.rxmfrmmcast); + seq_printf(s, "rxcfrmmcast: %d\n", stats.rxcfrmmcast); + seq_printf(s, "rxbeaconmbss: %d\n", stats.rxbeaconmbss); + seq_printf(s, "rxdfrmucastobss: %d\n", stats.rxdfrmucastobss); + seq_printf(s, "rxbeaconobss: %d\n", stats.rxbeaconobss); + seq_printf(s, "rxrsptmout: %d\n", stats.rxrsptmout); + seq_printf(s, "bcntxcancl: %d\n", stats.bcntxcancl); + seq_printf(s, "rxf0ovfl: %d\n", stats.rxf0ovfl); + seq_printf(s, "rxf1ovfl: %d\n", stats.rxf1ovfl); + seq_printf(s, "rxf2ovfl: %d\n", stats.rxf2ovfl); + seq_printf(s, "txsfovfl: %d\n", stats.txsfovfl); + seq_printf(s, "pmqovfl: %d\n", stats.pmqovfl); + seq_printf(s, "rxcgprqfrm: %d\n", stats.rxcgprqfrm); + seq_printf(s, "rxcgprsqovfl: %d\n", stats.rxcgprsqovfl); + seq_printf(s, "txcgprsfail: %d\n", stats.txcgprsfail); + seq_printf(s, "txcgprssuc: %d\n", stats.txcgprssuc); + seq_printf(s, "prs_timeout: %d\n", stats.prs_timeout); + seq_printf(s, "rxnack: %d\n", stats.rxnack); + seq_printf(s, "frmscons: %d\n", stats.frmscons); + seq_printf(s, "txnack: %d\n", stats.txnack); + seq_printf(s, "txglitch_nack: %d\n", stats.txglitch_nack); + seq_printf(s, "txburst: %d\n", stats.txburst); + seq_printf(s, "bphy_rxcrsglitch: %d\n", stats.bphy_rxcrsglitch); + seq_printf(s, "phywatchdog: %d\n", stats.phywatchdog); + seq_printf(s, "bphy_badplcp: %d\n", stats.bphy_badplcp); + return 0; +} + +struct brcms_debugfs_entry { + int (*read)(struct seq_file *seq, void *data); + struct brcms_pub *drvr; +}; + +static int brcms_debugfs_entry_open(struct inode *inode, struct file *f) +{ + struct brcms_debugfs_entry *entry = inode->i_private; + + return single_open(f, entry->read, entry->drvr); } -static const struct file_operations brcms_debugfs_hardware_ops = { +static const struct file_operations brcms_debugfs_def_ops = { .owner = THIS_MODULE, - .open = simple_open, - .read = brcms_debugfs_hardware_read + .open = brcms_debugfs_entry_open, + .release = single_release, + .read = seq_read, + .llseek = seq_lseek }; +static int +brcms_debugfs_add_entry(struct brcms_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) +{ + struct device *dev = &drvr->wlc->hw->d11core->dev; + struct dentry *dentry = drvr->dbgfs_dir; + struct brcms_debugfs_entry *entry; + + if (IS_ERR_OR_NULL(dentry)) + return -ENOENT; + + entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + entry->read = read_fn; + entry->drvr = drvr; + + dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, + &brcms_debugfs_def_ops); + + return PTR_ERR_OR_ZERO(dentry); +} + void brcms_debugfs_create_files(struct brcms_pub *drvr) { - struct dentry *dentry = drvr->dbgfs_dir; + if (IS_ERR_OR_NULL(drvr->dbgfs_dir)) + return; - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("hardware", S_IRUGO, dentry, - drvr, &brcms_debugfs_hardware_ops); + brcms_debugfs_add_entry(drvr, "hardware", brcms_debugfs_hardware_read); + brcms_debugfs_add_entry(drvr, "macstat", brcms_debugfs_macstat_read); } #define __brcms_fn(fn) \ -- GitLab From 09fa9d87cace65ff4b30ad203ff32f305ee0489f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 29 Oct 2014 23:17:12 -0500 Subject: [PATCH 2253/9457] rtlwifi: rtl8821ae: Remove extra semicolons The kbuild test robot reports that there are extra semicolons in this driver. All of them are caused by using "};" rather than "}" at the end of a switch statement. This patch does not change any functionality. Signed-off-by: Larry Finger Cc: Murilo Opsfelder Araujo Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8821ae/phy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c index 9786313dc62f..4be278f7df51 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c @@ -800,7 +800,7 @@ static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", rate_section, path, txnum); break; - }; + } } else if (band == BAND_ON_5G) { switch (rate_section) { case OFDM: @@ -823,7 +823,7 @@ static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", rate_section, path, txnum); break; - }; + } } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band); @@ -870,7 +870,7 @@ static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", rate_section, path, txnum); break; - }; + } } else if (band == BAND_ON_5G) { switch (rate_section) { case OFDM: @@ -893,7 +893,7 @@ static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", rate_section, path, txnum); break; - }; + } } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band); @@ -3743,7 +3743,7 @@ static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw, break; default: break; - }; + } } static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw, @@ -3764,7 +3764,7 @@ static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw, break; default: break; - }; + } } #define cal_num 10 -- GitLab From 8a0253481c4db5e0790de16748435dbc06b63e65 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:01 -0300 Subject: [PATCH 2254/9457] [media] cx231xx: let is_tuner check the real i2c port and not the i2c master number Get used i2c port from bus_nr and status of port_3 switch. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index af9180f3bf30..9ade3acbc877 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -54,10 +54,19 @@ do { \ } \ } while (0) +static inline int get_real_i2c_port(struct cx231xx *dev, int bus_nr) +{ + if (bus_nr == 1) + return dev->port_3_switch_enabled ? I2C_1_MUX_3 : I2C_1_MUX_1; + return bus_nr; +} + static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus, const struct i2c_msg *msg, int tuner_type) { - if (bus->nr != dev->board.tuner_i2c_master) + int i2c_port = get_real_i2c_port(dev, bus->nr); + + if (i2c_port != dev->board.tuner_i2c_master) return false; if (msg->addr != dev->board.tuner_addr) -- GitLab From b9ce9dfd18eb30a2c57de6f410a749c58d47743f Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:02 -0300 Subject: [PATCH 2255/9457] [media] cx231xx: change usage of I2C_1 to the real i2c port change almost all instances of I2C_1 to I2C_1_MUX_3 Only these cases are changed to I2C_1_MUX_1: * All that have dont_use_port_3 set. * CX231XX_BOARD_HAUPPAUGE_EXETER, old code did explicitly not switch to port3. * eeprom access for 930C Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-cards.c | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index f5fb93a79a9f..4eb2057ab022 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -104,7 +104,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, @@ -144,7 +144,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, @@ -184,7 +184,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, @@ -225,7 +225,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, @@ -297,7 +297,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, @@ -325,7 +325,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, @@ -353,7 +353,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_1, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, @@ -419,7 +419,7 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, .tuner_i2c_master = I2C_2, - .demod_i2c_master = I2C_1, + .demod_i2c_master = I2C_1_MUX_3, .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, @@ -457,7 +457,7 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, .tuner_i2c_master = I2C_2, - .demod_i2c_master = I2C_1, + .demod_i2c_master = I2C_1_MUX_3, .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, @@ -495,7 +495,7 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, .tuner_i2c_master = I2C_2, - .demod_i2c_master = I2C_1, + .demod_i2c_master = I2C_1_MUX_3, .ir_i2c_master = I2C_2, .rc_map_name = RC_MAP_PIXELVIEW_002T, .has_dvb = 1, @@ -587,7 +587,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .norm = V4L2_STD_PAL, .input = {{ @@ -622,7 +622,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .norm = V4L2_STD_NTSC, .input = {{ @@ -718,7 +718,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, @@ -757,7 +757,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = I2C_1, + .tuner_i2c_master = I2C_1_MUX_3, .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, @@ -1064,7 +1064,7 @@ void cx231xx_card_setup(struct cx231xx *dev) struct i2c_client client; memset(&client, 0, sizeof(client)); - client.adapter = cx231xx_get_i2c_adap(dev, I2C_1); + client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); client.addr = 0xa0 >> 1; read_eeprom(dev, &client, eeprom, sizeof(eeprom)); -- GitLab From 15c212dd0f7af8650808ada802c9317b4b0ec5a7 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:03 -0300 Subject: [PATCH 2256/9457] [media] cx231xx: register i2c mux adapters for bus 1 I2C bus 1 has internally a switch. Use it as I2C_1_MUX_1 and I2C_1_MUX_3, letting the I2C core handling the switch. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/Kconfig | 1 + drivers/media/usb/cx231xx/cx231xx-core.c | 5 +++ drivers/media/usb/cx231xx/cx231xx-i2c.c | 44 +++++++++++++++++++++++- drivers/media/usb/cx231xx/cx231xx.h | 4 +++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 569aa298c03f..173c0e287a08 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig @@ -7,6 +7,7 @@ config VIDEO_CX231XX select VIDEOBUF_VMALLOC select VIDEO_CX25840 select VIDEO_CX2341X + select I2C_MUX ---help--- This is a video4linux driver for Conexant 231xx USB based TV cards. diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 180103e48036..c8a6d20c9a23 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1300,6 +1300,9 @@ int cx231xx_dev_init(struct cx231xx *dev) cx231xx_i2c_register(&dev->i2c_bus[1]); cx231xx_i2c_register(&dev->i2c_bus[2]); + cx231xx_i2c_mux_register(dev, 0); + cx231xx_i2c_mux_register(dev, 1); + /* init hardware */ /* Note : with out calling set power mode function, afe can not be set up correctly */ @@ -1414,6 +1417,8 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_init); void cx231xx_dev_uninit(struct cx231xx *dev) { /* Un Initialize I2C bus */ + cx231xx_i2c_mux_unregister(dev, 1); + cx231xx_i2c_mux_unregister(dev, 0); cx231xx_i2c_unregister(&dev->i2c_bus[2]); cx231xx_i2c_unregister(&dev->i2c_bus[1]); cx231xx_i2c_unregister(&dev->i2c_bus[0]); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 9ade3acbc877..3e9dfd808518 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -547,6 +548,46 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) return 0; } +/* + * cx231xx_i2c_mux_select() + * switch i2c master number 1 between port1 and port3 + */ +static int cx231xx_i2c_mux_select(struct i2c_adapter *adap, + void *mux_priv, u32 chan_id) +{ + struct cx231xx *dev = mux_priv; + + return cx231xx_enable_i2c_port_3(dev, chan_id); +} + +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) +{ + struct i2c_adapter *i2c_parent = &dev->i2c_bus[1].i2c_adap; + /* what is the correct mux_dev? */ + struct device *mux_dev = &dev->udev->dev; + + dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent, + mux_dev, + dev /* mux_priv */, + 0, + mux_no /* chan_id */, + 0 /* class */, + &cx231xx_i2c_mux_select, + NULL); + + if (!dev->i2c_mux_adap[mux_no]) + cx231xx_warn("%s: i2c mux %d register FAILED\n", + dev->name, mux_no); + + return 0; +} + +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no) +{ + i2c_del_mux_adapter(dev->i2c_mux_adap[mux_no]); + dev->i2c_mux_adap[mux_no] = NULL; +} + struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) { switch (i2c_port) { @@ -557,8 +598,9 @@ struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) case I2C_2: return &dev->i2c_bus[2].i2c_adap; case I2C_1_MUX_1: + return dev->i2c_mux_adap[0]; case I2C_1_MUX_3: - return &dev->i2c_bus[1].i2c_adap; + return dev->i2c_mux_adap[1]; default: return NULL; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 8a3c97b4e895..c90aa44a6826 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -628,6 +628,8 @@ struct cx231xx { /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ struct cx231xx_i2c i2c_bus[3]; + struct i2c_adapter *i2c_mux_adap[2]; + unsigned int xc_fw_load_done:1; unsigned int port_3_switch_enabled:1; /* locks */ @@ -755,6 +757,8 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev); void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no); +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no); struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port); /* Internal block control functions */ -- GitLab From 660acd54d1656f6361819d8d6b377a2aa2438748 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:04 -0300 Subject: [PATCH 2257/9457] [media] cx231xx: drop unconditional port3 switching All switching should be done by i2c mux adapters. Drop explicit dont_use_port_3 flag. Drop info message about switch. Only the removed code in start_streaming is questionable: It did switch the port_3 flag without accessing i2c in between. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 18 ------------------ drivers/media/usb/cx231xx/cx231xx-cards.c | 8 -------- drivers/media/usb/cx231xx/cx231xx-core.c | 4 +--- drivers/media/usb/cx231xx/cx231xx-dvb.c | 4 ---- drivers/media/usb/cx231xx/cx231xx.h | 1 - 5 files changed, 1 insertion(+), 34 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 0a5fec47c08c..b56bc8779074 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -1270,9 +1270,6 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) int status = 0; bool current_is_port_3; - if (dev->board.dont_use_port_3) - is_port_3 = false; - /* * Should this code check dev->port_3_switch_enabled first * to skip unnecessary reading of the register? @@ -1296,9 +1293,6 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) else value[0] &= ~I2C_DEMOD_EN; - cx231xx_info("Changing the i2c master port to %d\n", - is_port_3 ? 3 : 1); - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN, value, 4); @@ -2329,9 +2323,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } if (dev->board.tuner_type != TUNER_ABSENT) { - /* Enable tuner */ - cx231xx_enable_i2c_port_3(dev, true); - /* reset the Tuner */ if (dev->board.tuner_gpio) cx231xx_gpio_set(dev, dev->board.tuner_gpio); @@ -2396,15 +2387,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } if (dev->board.tuner_type != TUNER_ABSENT) { - /* - * Enable tuner - * Hauppauge Exeter seems to need to do something different! - */ - if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER) - cx231xx_enable_i2c_port_3(dev, false); - else - cx231xx_enable_i2c_port_3(dev, true); - /* reset the Tuner */ if (dev->board.tuner_gpio) cx231xx_gpio_set(dev, dev->board.tuner_gpio); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 4eb2057ab022..432cbcf8ce43 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -262,7 +262,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_PAL, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, /* Actually, it has a 417, but it isn't working correctly. * So set to 0 for now until someone can manage to get this * to work reliably. */ @@ -390,7 +389,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, .vmux = CX231XX_VIN_2_1, @@ -532,7 +530,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, @@ -656,7 +653,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, .vmux = CX231XX_VIN_2_1, @@ -683,7 +679,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, /*.has_417 = 1, */ /* This board is believed to have a hardware encoding chip * supporting mpeg1/2/4, but as the 417 is apparently not @@ -1012,9 +1007,6 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, len_todo -= msg_read.len; } - cx231xx_enable_i2c_port_3(dev, true); - /* mutex_unlock(&dev->i2c_lock); */ - for (i = 0; i + 15 < len; i += 16) cx231xx_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index c8a6d20c9a23..c49022f4525a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1407,9 +1407,7 @@ int cx231xx_dev_init(struct cx231xx *dev) if (dev->board.has_dvb) cx231xx_set_alt_setting(dev, INDEX_TS1, 0); - /* set the I2C master port to 3 on channel 1 */ - errCode = cx231xx_enable_i2c_port_3(dev, true); - + errCode = 0; return errCode; } EXPORT_SYMBOL_GPL(cx231xx_dev_init); diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 869c433fbbbf..2ea69469e74b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -266,11 +266,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) if (dev->USE_ISO) { cx231xx_info("DVB transfer mode is ISO.\n"); - mutex_lock(&dev->i2c_lock); - cx231xx_enable_i2c_port_3(dev, false); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); - cx231xx_enable_i2c_port_3(dev, true); - mutex_unlock(&dev->i2c_lock); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) return rc; diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index c90aa44a6826..a0ec24176522 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -368,7 +368,6 @@ struct cx231xx_board { unsigned int valid:1; unsigned int no_alt_vanc:1; unsigned int external_av:1; - unsigned int dont_use_port_3:1; unsigned char xclk, i2c_speed; -- GitLab From e4de03f26384452c47fe8b97838aeba3bec4122f Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 2 Oct 2014 02:21:05 -0300 Subject: [PATCH 2258/9457] [media] cx231xx: scan all four existing i2c busses instead of the 3 masters The scanning itself just fails (as before this series) but now the correct busses are scanned. Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-core.c | 6 ++++++ drivers/media/usb/cx231xx/cx231xx-i2c.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index c49022f4525a..9b5cd9e9b169 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1303,6 +1303,12 @@ int cx231xx_dev_init(struct cx231xx *dev) cx231xx_i2c_mux_register(dev, 0); cx231xx_i2c_mux_register(dev, 1); + /* scan the real bus segments in the order of physical port numbers */ + cx231xx_do_i2c_scan(dev, I2C_0); + cx231xx_do_i2c_scan(dev, I2C_1_MUX_1); + cx231xx_do_i2c_scan(dev, I2C_2); + cx231xx_do_i2c_scan(dev, I2C_1_MUX_3); + /* init hardware */ /* Note : with out calling set power mode function, afe can not be set up correctly */ diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 3e9dfd808518..d1003c703fb5 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -492,6 +492,9 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) int i, rc; struct i2c_client client; + if (!i2c_scan) + return; + memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); @@ -528,10 +531,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); i2c_add_adapter(&bus->i2c_adap); - if (0 == bus->i2c_rc) { - if (i2c_scan) - cx231xx_do_i2c_scan(dev, bus->nr); - } else + if (0 != bus->i2c_rc) cx231xx_warn("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); -- GitLab From 9c3997601d51069ec08d7d06cf31a17884056cc2 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 28 Oct 2014 15:11:41 -0700 Subject: [PATCH 2259/9457] bpf: reduce verifier memory consumption verifier keeps track of register state spilled to stack. registers are 8-byte wide and always aligned, so instead of tracking them in every byte-sized stack slot, use MAX_BPF_STACK / 8 array to track spilled register state. Though verifier runs in user context and its state freed immediately after verification, it makes sense to reduce its memory usage. This optimization reduces sizeof(struct verifier_state) from 12464 to 1712 on 64-bit and from 6232 to 1112 on 32-bit. Note, this patch doesn't change existing limits, which are there to bound time and memory during verification: 4k total number of insns in a program, 1k number of jumps (states to visit) and 32k number of processed insn (since an insn may be visited multiple times). Theoretical worst case memory during verification is 1712 * 1k = 17Mbyte. Out-of-memory situation triggers cleanup and rejects the program. Suggested-by: Andy Lutomirski Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- kernel/bpf/verifier.c | 101 ++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 9f81818f2941..b6a1f7c14a67 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -153,22 +153,19 @@ struct reg_state { enum bpf_stack_slot_type { STACK_INVALID, /* nothing was stored in this stack slot */ - STACK_SPILL, /* 1st byte of register spilled into stack */ - STACK_SPILL_PART, /* other 7 bytes of register spill */ + STACK_SPILL, /* register spilled into stack */ STACK_MISC /* BPF program wrote some data into this slot */ }; -struct bpf_stack_slot { - enum bpf_stack_slot_type stype; - struct reg_state reg_st; -}; +#define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ /* state of the program: * type of all registers and stack info */ struct verifier_state { struct reg_state regs[MAX_BPF_REG]; - struct bpf_stack_slot stack[MAX_BPF_STACK]; + u8 stack_slot_type[MAX_BPF_STACK]; + struct reg_state spilled_regs[MAX_BPF_STACK / BPF_REG_SIZE]; }; /* linked list of verifier states used to prune search */ @@ -259,10 +256,10 @@ static void print_verifier_state(struct verifier_env *env) env->cur_state.regs[i].map_ptr->key_size, env->cur_state.regs[i].map_ptr->value_size); } - for (i = 0; i < MAX_BPF_STACK; i++) { - if (env->cur_state.stack[i].stype == STACK_SPILL) + for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { + if (env->cur_state.stack_slot_type[i] == STACK_SPILL) verbose(" fp%d=%s", -MAX_BPF_STACK + i, - reg_type_str[env->cur_state.stack[i].reg_st.type]); + reg_type_str[env->cur_state.spilled_regs[i / BPF_REG_SIZE].type]); } verbose("\n"); } @@ -539,8 +536,10 @@ static int bpf_size_to_bytes(int bpf_size) static int check_stack_write(struct verifier_state *state, int off, int size, int value_regno) { - struct bpf_stack_slot *slot; int i; + /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, + * so it's aligned access and [off, off + size) are within stack limits + */ if (value_regno >= 0 && (state->regs[value_regno].type == PTR_TO_MAP_VALUE || @@ -548,30 +547,24 @@ static int check_stack_write(struct verifier_state *state, int off, int size, state->regs[value_regno].type == PTR_TO_CTX)) { /* register containing pointer is being spilled into stack */ - if (size != 8) { + if (size != BPF_REG_SIZE) { verbose("invalid size of register spill\n"); return -EACCES; } - slot = &state->stack[MAX_BPF_STACK + off]; - slot->stype = STACK_SPILL; /* save register state */ - slot->reg_st = state->regs[value_regno]; - for (i = 1; i < 8; i++) { - slot = &state->stack[MAX_BPF_STACK + off + i]; - slot->stype = STACK_SPILL_PART; - slot->reg_st.type = UNKNOWN_VALUE; - slot->reg_st.map_ptr = NULL; - } - } else { + state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = + state->regs[value_regno]; + for (i = 0; i < BPF_REG_SIZE; i++) + state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL; + } else { /* regular write of data into stack */ - for (i = 0; i < size; i++) { - slot = &state->stack[MAX_BPF_STACK + off + i]; - slot->stype = STACK_MISC; - slot->reg_st.type = UNKNOWN_VALUE; - slot->reg_st.map_ptr = NULL; - } + state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = + (struct reg_state) {}; + + for (i = 0; i < size; i++) + state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC; } return 0; } @@ -579,19 +572,18 @@ static int check_stack_write(struct verifier_state *state, int off, int size, static int check_stack_read(struct verifier_state *state, int off, int size, int value_regno) { + u8 *slot_type; int i; - struct bpf_stack_slot *slot; - slot = &state->stack[MAX_BPF_STACK + off]; + slot_type = &state->stack_slot_type[MAX_BPF_STACK + off]; - if (slot->stype == STACK_SPILL) { - if (size != 8) { + if (slot_type[0] == STACK_SPILL) { + if (size != BPF_REG_SIZE) { verbose("invalid size of register spill\n"); return -EACCES; } - for (i = 1; i < 8; i++) { - if (state->stack[MAX_BPF_STACK + off + i].stype != - STACK_SPILL_PART) { + for (i = 1; i < BPF_REG_SIZE; i++) { + if (slot_type[i] != STACK_SPILL) { verbose("corrupted spill memory\n"); return -EACCES; } @@ -599,12 +591,12 @@ static int check_stack_read(struct verifier_state *state, int off, int size, if (value_regno >= 0) /* restore register state from stack */ - state->regs[value_regno] = slot->reg_st; + state->regs[value_regno] = + state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE]; return 0; } else { for (i = 0; i < size; i++) { - if (state->stack[MAX_BPF_STACK + off + i].stype != - STACK_MISC) { + if (slot_type[i] != STACK_MISC) { verbose("invalid read from stack off %d+%d size %d\n", off, i, size); return -EACCES; @@ -747,7 +739,7 @@ static int check_stack_boundary(struct verifier_env *env, } for (i = 0; i < access_size; i++) { - if (state->stack[MAX_BPF_STACK + off + i].stype != STACK_MISC) { + if (state->stack_slot_type[MAX_BPF_STACK + off + i] != STACK_MISC) { verbose("invalid indirect read from stack off %d+%d size %d\n", off, i, access_size); return -EACCES; @@ -1417,12 +1409,33 @@ static bool states_equal(struct verifier_state *old, struct verifier_state *cur) } for (i = 0; i < MAX_BPF_STACK; i++) { - if (memcmp(&old->stack[i], &cur->stack[i], - sizeof(old->stack[0])) != 0) { - if (old->stack[i].stype == STACK_INVALID) - continue; + if (old->stack_slot_type[i] == STACK_INVALID) + continue; + if (old->stack_slot_type[i] != cur->stack_slot_type[i]) + /* Ex: old explored (safe) state has STACK_SPILL in + * this stack slot, but current has has STACK_MISC -> + * this verifier states are not equivalent, + * return false to continue verification of this path + */ return false; - } + if (i % BPF_REG_SIZE) + continue; + if (memcmp(&old->spilled_regs[i / BPF_REG_SIZE], + &cur->spilled_regs[i / BPF_REG_SIZE], + sizeof(old->spilled_regs[0]))) + /* when explored and current stack slot types are + * the same, check that stored pointers types + * are the same as well. + * Ex: explored safe path could have stored + * (struct reg_state) {.type = PTR_TO_STACK, .imm = -8} + * but current path has stored: + * (struct reg_state) {.type = PTR_TO_STACK, .imm = -16} + * such verifier states are not equivalent. + * return false to continue verification of this path + */ + return false; + else + continue; } return true; } -- GitLab From 342ded409608f84fe929216efe0ca2d45e2656be Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 28 Oct 2014 15:11:42 -0700 Subject: [PATCH 2260/9457] samples: bpf: add a verifier test and summary line - add a test specifically targeting verifier state pruning. It checks state propagation between registers, storing that state into stack and state pruning algorithm recognizing equivalent stack and register states. - add summary line to spot failures easier Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- samples/bpf/test_verifier.c | 46 ++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c index eb4bec0ad8af..63402742345e 100644 --- a/samples/bpf/test_verifier.c +++ b/samples/bpf/test_verifier.c @@ -602,6 +602,45 @@ static struct bpf_test tests[] = { }, .result = ACCEPT, }, + { + "jump test 5", + .insns = { + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_MOV64_REG(BPF_REG_3, BPF_REG_2), + BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 2), + BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, -8), + BPF_JMP_IMM(BPF_JA, 0, 0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .result = ACCEPT, + }, }; static int probe_filter_length(struct bpf_insn *fp) @@ -630,7 +669,7 @@ static int create_map(void) static int test(void) { - int prog_fd, i; + int prog_fd, i, pass_cnt = 0, err_cnt = 0; for (i = 0; i < ARRAY_SIZE(tests); i++) { struct bpf_insn *prog = tests[i].insns; @@ -657,21 +696,25 @@ static int test(void) printf("FAIL\nfailed to load prog '%s'\n", strerror(errno)); printf("%s", bpf_log_buf); + err_cnt++; goto fail; } } else { if (prog_fd >= 0) { printf("FAIL\nunexpected success to load\n"); printf("%s", bpf_log_buf); + err_cnt++; goto fail; } if (strstr(bpf_log_buf, tests[i].errstr) == 0) { printf("FAIL\nunexpected error message: %s", bpf_log_buf); + err_cnt++; goto fail; } } + pass_cnt++; printf("OK\n"); fail: if (map_fd >= 0) @@ -679,6 +722,7 @@ static int test(void) close(prog_fd); } + printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, err_cnt); return 0; } -- GitLab From e21ab36a80c2e011a14149fecdd654b8b47d3e8c Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 28 Oct 2014 15:11:43 -0700 Subject: [PATCH 2261/9457] test: bpf: add a testcase reduced from nmap nmap generates classic BPF programs to filter ARP packets with given target MAC which triggered a bug in eBPF x64 JIT. The bug was fixed in commit e0ee9c12157d ("x86: bpf_jit: fix two bugs in eBPF JIT compiler") This patch is adding a testcase in eBPF instructions (those that were generated by classic->eBPF converter) to be processed by JIT. The test is primarily targeting JIT compiler. Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- lib/test_bpf.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 23e070bcf72d..3f167d2eeb94 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -1756,6 +1756,49 @@ static struct bpf_test tests[] = { { }, { { 0, 1 } } }, + { + "nmap reduced", + .u.insns_int = { + BPF_MOV64_REG(R6, R1), + BPF_LD_ABS(BPF_H, 12), + BPF_JMP_IMM(BPF_JNE, R0, 0x806, 28), + BPF_LD_ABS(BPF_H, 12), + BPF_JMP_IMM(BPF_JNE, R0, 0x806, 26), + BPF_MOV32_IMM(R0, 18), + BPF_STX_MEM(BPF_W, R10, R0, -64), + BPF_LDX_MEM(BPF_W, R7, R10, -64), + BPF_LD_IND(BPF_W, R7, 14), + BPF_STX_MEM(BPF_W, R10, R0, -60), + BPF_MOV32_IMM(R0, 280971478), + BPF_STX_MEM(BPF_W, R10, R0, -56), + BPF_LDX_MEM(BPF_W, R7, R10, -56), + BPF_LDX_MEM(BPF_W, R0, R10, -60), + BPF_ALU32_REG(BPF_SUB, R0, R7), + BPF_JMP_IMM(BPF_JNE, R0, 0, 15), + BPF_LD_ABS(BPF_H, 12), + BPF_JMP_IMM(BPF_JNE, R0, 0x806, 13), + BPF_MOV32_IMM(R0, 22), + BPF_STX_MEM(BPF_W, R10, R0, -56), + BPF_LDX_MEM(BPF_W, R7, R10, -56), + BPF_LD_IND(BPF_H, R7, 14), + BPF_STX_MEM(BPF_W, R10, R0, -52), + BPF_MOV32_IMM(R0, 17366), + BPF_STX_MEM(BPF_W, R10, R0, -48), + BPF_LDX_MEM(BPF_W, R7, R10, -48), + BPF_LDX_MEM(BPF_W, R0, R10, -52), + BPF_ALU32_REG(BPF_SUB, R0, R7), + BPF_JMP_IMM(BPF_JNE, R0, 0, 2), + BPF_MOV32_IMM(R0, 256), + BPF_EXIT_INSN(), + BPF_MOV32_IMM(R0, 0), + BPF_EXIT_INSN(), + }, + INTERNAL, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6}, + { { 38, 256 } } + }, }; static struct net_device dev; -- GitLab From e7b6658ea8cae3b7ab86e2985011126d181128fb Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 29 Oct 2014 09:31:42 +0100 Subject: [PATCH 2262/9457] ipx: remove all unnecessary castings on ntohl Apply commit e0f36310f793 ("ipx: remove unnecessary casting on ntohl") to all seq_printf/08lX Inspired-by: "David S. Miller" Inspired-by: Joe Perches Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipx/ipx_proc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index 8391191d3d9c..c1d247ebe916 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c @@ -45,7 +45,7 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v) } i = list_entry(v, struct ipx_interface, node); - seq_printf(seq, "%08lX ", (unsigned long int)ntohl(i->if_netnum)); + seq_printf(seq, "%08X ", ntohl(i->if_netnum)); seq_printf(seq, "%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); @@ -87,7 +87,7 @@ static int ipx_seq_route_show(struct seq_file *seq, void *v) rt = list_entry(v, struct ipx_route, node); - seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net)); + seq_printf(seq, "%08X ", ntohl(rt->ir_net)); if (rt->ir_routed) seq_printf(seq, "%08X %02X%02X%02X%02X%02X%02X\n", ntohl(rt->ir_intrfc->if_netnum), @@ -194,19 +194,19 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) s = v; ipxs = ipx_sk(s); #ifdef CONFIG_IPX_INTERN - seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - (unsigned long)ntohl(ipxs->intrfc->if_netnum), + seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ", + ntohl(ipxs->intrfc->if_netnum), ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3], ipxs->node[4], ipxs->node[5], ntohs(ipxs->port)); #else - seq_printf(seq, "%08lX:%04X ", (unsigned long) ntohl(ipxs->intrfc->if_netnum), + seq_printf(seq, "%08X:%04X ", ntohl(ipxs->intrfc->if_netnum), ntohs(ipxs->port)); #endif /* CONFIG_IPX_INTERN */ if (s->sk_state != TCP_ESTABLISHED) seq_printf(seq, "%-28s", "Not_Connected"); else { - seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - (unsigned long)ntohl(ipxs->dest_addr.net), + seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ", + ntohl(ipxs->dest_addr.net), ipxs->dest_addr.node[0], ipxs->dest_addr.node[1], ipxs->dest_addr.node[2], ipxs->dest_addr.node[3], ipxs->dest_addr.node[4], ipxs->dest_addr.node[5], -- GitLab From 40dc2ca3cb22666ecf8715a8c4ca0529148ecac8 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 29 Oct 2014 10:00:26 +0100 Subject: [PATCH 2263/9457] ipv6: spelling s/incomming/incoming Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv6/ip6mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 0171f08325c3..467f310dbbb3 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -2090,7 +2090,7 @@ static void ip6_mr_forward(struct net *net, struct mr6_table *mrt, if (ipv6_addr_any(&cache->mf6c_origin) && true_vifi >= 0) { struct mfc6_cache *cache_proxy; - /* For an (*,G) entry, we only check that the incomming + /* For an (*,G) entry, we only check that the incoming * interface is part of the static tree. */ cache_proxy = ip6mr_cache_find_any_parent(mrt, vif); -- GitLab From fc08c258191f4acc79df232c0c65c857ee75e59f Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 29 Oct 2014 11:38:17 +0100 Subject: [PATCH 2264/9457] ipv6: remove inline on static in c file remove __inline__ / inline and let compiler decide what to do with static functions Inspired-by: "David S. Miller" Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv6/reassembly.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 1a157ca2ebc1..51ab096ae574 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -69,7 +69,7 @@ struct ip6frag_skb_cb { #define FRAG6_CB(skb) ((struct ip6frag_skb_cb *)((skb)->cb)) -static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) +static u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h) { return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK); } @@ -178,7 +178,7 @@ static void ip6_frag_expire(unsigned long data) ip6_expire_frag_queue(net, fq, &ip6_frags); } -static __inline__ struct frag_queue * +static struct frag_queue * fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst, u8 ecn) { @@ -684,21 +684,21 @@ static void ip6_frags_sysctl_unregister(void) unregister_net_sysctl_table(ip6_ctl_header); } #else -static inline int ip6_frags_ns_sysctl_register(struct net *net) +static int ip6_frags_ns_sysctl_register(struct net *net) { return 0; } -static inline void ip6_frags_ns_sysctl_unregister(struct net *net) +static void ip6_frags_ns_sysctl_unregister(struct net *net) { } -static inline int ip6_frags_sysctl_register(void) +static int ip6_frags_sysctl_register(void) { return 0; } -static inline void ip6_frags_sysctl_unregister(void) +static void ip6_frags_sysctl_unregister(void) { } #endif -- GitLab From 43728fa5c5e475e6f0059ec739e715fc49e4a478 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Wed, 29 Oct 2014 12:57:51 +0100 Subject: [PATCH 2265/9457] ipv6: remove assignment in if condition Do assignment before if condition and test !skb like in rawv6_recvmsg() Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv6/raw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 896af8807979..075a0fb400e7 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -548,7 +548,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, if (!rp->checksum) goto send; - if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + skb = skb_peek(&sk->sk_write_queue); + if (!skb) goto out; offset = rp->offset; -- GitLab From 12c492cf462704fcfc8c86046d539c16d57dfbe3 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:01:38 +0530 Subject: [PATCH 2266/9457] staging: cptm1217: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cptm1217/clearpad_tm1217.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index edf9ff2ea25b..7f265ce0dd13 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -278,7 +278,7 @@ static void cp_tm1217_get_data(struct cp_tm1217_device *ts) static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle) { - struct cp_tm1217_device *ts = (struct cp_tm1217_device *) handle; + struct cp_tm1217_device *ts = handle; u8 req[2]; int retval; -- GitLab From d591f5d0e548cb79a942be5fd86fbc714b530a39 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:01:52 +0530 Subject: [PATCH 2267/9457] staging: dgap: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index dfdf20969987..105c3b8f4024 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -1167,7 +1167,7 @@ static void dgap_poll_handler(ulong dummy) */ static irqreturn_t dgap_intr(int irq, void *voidbrd) { - struct board_t *brd = (struct board_t *) voidbrd; + struct board_t *brd = voidbrd; if (!brd) return IRQ_NONE; -- GitLab From fc33bd2921c27241f0b695bb265fa020c51d352b Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:04 +0530 Subject: [PATCH 2268/9457] staging: dgnc: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 2 +- drivers/staging/dgnc/dgnc_neo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 360fe258946d..bedc5221b6fc 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -792,7 +792,7 @@ static void cls_tasklet(unsigned long data) */ static irqreturn_t cls_intr(int irq, void *voidbrd) { - struct dgnc_board *brd = (struct dgnc_board *) voidbrd; + struct dgnc_board *brd = voidbrd; uint i = 0; unsigned char poll_reg; unsigned long flags; diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index cc6136418071..c9a8a9825cfb 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -944,7 +944,7 @@ static void neo_tasklet(unsigned long data) */ static irqreturn_t neo_intr(int irq, void *voidbrd) { - struct dgnc_board *brd = (struct dgnc_board *) voidbrd; + struct dgnc_board *brd = voidbrd; struct channel_t *ch; int port = 0; int type = 0; -- GitLab From edb3cc10e03874067c7e86107462a89b54bfdfc9 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:15 +0530 Subject: [PATCH 2269/9457] staging: gdm72xx: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index 5b7747f6b847..9cab54bfa6f4 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -115,7 +115,7 @@ static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg, { struct nic *nic = netdev_priv(dev); - u8 *buf = (u8 *)msg; + u8 *buf = msg; u16 hci_cmd = (buf[0]<<8) | buf[1]; u16 hci_len = (buf[2]<<8) | buf[3]; -- GitLab From 31f8f066f5bc8dc5ce1efbbdfddec401ed790a2b Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:25 +0530 Subject: [PATCH 2270/9457] staging: iio: adc: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_spi.c | 2 +- drivers/staging/iio/adc/lpc32xx_adc.c | 2 +- drivers/staging/iio/adc/spear_adc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index 6a8ecd73a1a7..7303983e64a7 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -23,7 +23,7 @@ static int ad7606_spi_read_block(struct device *dev, int i, ret; unsigned short *data = buf; - ret = spi_read(spi, (u8 *)buf, count * 2); + ret = spi_read(spi, buf, count * 2); if (ret < 0) { dev_err(&spi->dev, "SPI read error\n"); return ret; diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index a876ce755351..84a53a9430ef 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -116,7 +116,7 @@ static const struct iio_chan_spec lpc32xx_adc_iio_channels[] = { static irqreturn_t lpc32xx_adc_isr(int irq, void *dev_id) { - struct lpc32xx_adc_info *info = (struct lpc32xx_adc_info *) dev_id; + struct lpc32xx_adc_info *info = dev_id; /* Read value and clear irq */ info->value = __raw_readl(LPC32XX_ADC_VALUE(info->adc_base)) & diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 67a364c2e794..de37b35ea154 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -226,7 +226,7 @@ static const struct iio_chan_spec spear_adc_iio_channels[] = { static irqreturn_t spear_adc_isr(int irq, void *dev_id) { - struct spear_adc_state *st = (struct spear_adc_state *)dev_id; + struct spear_adc_state *st = dev_id; /* Read value to clear IRQ */ st->value = spear_adc_get_average(st); -- GitLab From ad1d2a4fc8676588f6fe9882235056f1c6d13b50 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:36 +0530 Subject: [PATCH 2271/9457] staging: media: davinci_vpfe: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | 4 ++-- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index 6d4893b44c1f..413acbb9e948 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -421,7 +421,7 @@ static int ipipeif_get_config(struct v4l2_subdev *sd, void __user *arg) { struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); - struct ipipeif_params *config = (struct ipipeif_params *)arg; + struct ipipeif_params *config = arg; struct device *dev = ipipeif->subdev.v4l2_dev->dev; if (!arg) { @@ -462,7 +462,7 @@ ipipeif_get_config(struct v4l2_subdev *sd, void __user *arg) static long ipipeif_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - struct ipipeif_params *config = (struct ipipeif_params *)arg; + struct ipipeif_params *config = arg; int ret = -ENOIOCTLCMD; switch (cmd) { diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 415502651033..36fc15ad190c 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -149,7 +149,7 @@ configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index, param->rsz_en[index] = DISABLE; return; } - output = (struct vpfe_rsz_output_spec *)output_spec; + output = output_spec; param->rsz_en[index] = ENABLE; if (partial) { param->rsz_rsc_param[index].h_flip = output->h_flip; @@ -1218,12 +1218,12 @@ static long resizer_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) switch (cmd) { case VIDIOC_VPFE_RSZ_S_CONFIG: - user_config = (struct vpfe_rsz_config *)arg; + user_config = arg; ret = resizer_set_configuration(resizer, user_config); break; case VIDIOC_VPFE_RSZ_G_CONFIG: - user_config = (struct vpfe_rsz_config *)arg; + user_config = arg; if (!user_config->config) { dev_err(dev, "error in VIDIOC_VPFE_RSZ_G_CONFIG\n"); return -EINVAL; -- GitLab From d82e62deb51b50b10736c71f06fa6ac26be3b5a3 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:48 +0530 Subject: [PATCH 2272/9457] staging: media: lirc: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_igorplugusb.c | 2 +- drivers/staging/media/lirc/lirc_imon.c | 4 ++-- drivers/staging/media/lirc/lirc_sasem.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c index 431d1e86ebf9..fd5d3d26b15d 100644 --- a/drivers/staging/media/lirc/lirc_igorplugusb.c +++ b/drivers/staging/media/lirc/lirc_igorplugusb.c @@ -282,7 +282,7 @@ static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf, static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) { int ret; - struct igorplug *ir = (struct igorplug *)data; + struct igorplug *ir = data; if (!ir || !ir->usbdev) /* Has the device been removed? */ return -ENODEV; diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index e3b1fa9fd2f4..f98418cd2305 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -495,7 +495,7 @@ static int ir_open(void *data) /* prevent races with disconnect */ mutex_lock(&driver_lock); - context = (struct imon_context *)data; + context = data; /* initial IR protocol decode variables */ context->rx.count = 0; @@ -516,7 +516,7 @@ static void ir_close(void *data) { struct imon_context *context; - context = (struct imon_context *)data; + context = data; if (!context) { pr_err("%s: no context for device\n", __func__); return; diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index 05969fb451ca..123ddf68b587 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -488,7 +488,7 @@ static int ir_open(void *data) /* prevent races with disconnect */ mutex_lock(&disconnect_lock); - context = (struct sasem_context *) data; + context = data; mutex_lock(&context->ctx_lock); @@ -530,7 +530,7 @@ static void ir_close(void *data) { struct sasem_context *context; - context = (struct sasem_context *)data; + context = data; if (!context) { pr_err("%s: no context for device\n", __func__); return; -- GitLab From b3d43a39104de1ed4278e85e16bd017c7ed73d91 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:02:57 +0530 Subject: [PATCH 2273/9457] staging: ozwpan: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 8 ++++---- drivers/staging/ozwpan/ozusbsvc1.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 3d03e9255831..27217d75f155 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -730,7 +730,7 @@ void oz_hcd_pd_reset(void *hpd, void *hport) { /* Cleanup the current configuration and report reset to the core. */ - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct oz_hcd *ozhcd = port->ozhcd; oz_dbg(ON, "PD Reset\n"); @@ -749,7 +749,7 @@ void oz_hcd_pd_reset(void *hpd, void *hport) void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc, int length, int offset, int total_size) { - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct urb *urb; int err = 0; @@ -889,7 +889,7 @@ static void oz_hcd_complete_set_interface(struct oz_port *port, struct urb *urb, void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode, const u8 *data, int data_len) { - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct urb *urb; struct usb_ctrlrequest *setup; struct usb_hcd *hcd = port->ozhcd->hcd; @@ -1036,7 +1036,7 @@ static inline int oz_usb_get_frame_number(void) int oz_hcd_heartbeat(void *hport) { int rc = 0; - struct oz_port *port = (struct oz_port *)hport; + struct oz_port *port = hport; struct oz_hcd *ozhcd = port->ozhcd; struct oz_urb_link *urbl, *n; LIST_HEAD(xfr_list); diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index be7ee01c50ab..d434d8c6fff6 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -56,7 +56,7 @@ static int oz_usb_submit_elt(struct oz_elt_buf *eb, struct oz_elt_info *ei, int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type, u8 index, __le16 windex, int offset, int len) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_get_desc_req *body; @@ -92,7 +92,7 @@ int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type, */ static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -115,7 +115,7 @@ static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index) */ static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -140,7 +140,7 @@ static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt) static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type, u8 recipient, u8 index, __le16 feature) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -166,7 +166,7 @@ static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type, static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type, u8 request, __le16 value, __le16 index, const u8 *data, int data_len) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt *elt; struct oz_elt_buf *eb = &pd->elt_buff; @@ -244,7 +244,7 @@ int oz_usb_control_req(void *hpd, u8 req_id, struct usb_ctrlrequest *setup, */ int oz_usb_send_isoc(void *hpd, u8 ep_num, struct urb *urb) { - struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd; + struct oz_usb_ctx *usb_ctx = hpd; struct oz_pd *pd = usb_ctx->pd; struct oz_elt_buf *eb; int i; -- GitLab From 60c8991148d8ad7cdbfd210a42db721eccd58d26 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:03:08 +0530 Subject: [PATCH 2274/9457] staging: rtl8188eu: core: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 2 +- drivers/staging/rtl8188eu/core/rtw_debug.c | 14 +++++++------- drivers/staging/rtl8188eu/core/rtw_efuse.c | 16 ++++++++-------- drivers/staging/rtl8188eu/core/rtw_led.c | 2 +- drivers/staging/rtl8188eu/core/rtw_mlme.c | 4 ++-- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 4 ++-- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 2 +- drivers/staging/rtl8188eu/core/rtw_recv.c | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 350d2e73b419..7731cdb72b22 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -167,7 +167,7 @@ int rtw_cmd_thread(void *context) struct cmd_obj *pcmd; u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); - struct adapter *padapter = (struct adapter *)context; + struct adapter *padapter = context; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); allow_signal(SIGTERM); diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index 1f72f7d8097e..bc3fe10ff247 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -45,7 +45,7 @@ int proc_get_write_reg(char *page, char **start, int proc_set_write_reg(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 addr, val, len; @@ -577,7 +577,7 @@ int proc_get_rx_signal(char *page, char **start, int proc_set_rx_signal(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 is_signal_dbg; @@ -627,7 +627,7 @@ int proc_get_ht_enable(char *page, char **start, int proc_set_ht_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -669,7 +669,7 @@ int proc_get_cbw40_enable(char *page, char **start, int proc_set_cbw40_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -710,7 +710,7 @@ int proc_get_ampdu_enable(char *page, char **start, int proc_set_ampdu_enable(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -771,7 +771,7 @@ int proc_get_rx_stbc(char *page, char **start, int proc_set_rx_stbc(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; char tmp[32]; @@ -800,7 +800,7 @@ int proc_get_rssi_disp(char *page, char **start, int proc_set_rssi_disp(struct file *file, const char __user *buffer, unsigned long count, void *data) { - struct net_device *dev = (struct net_device *)data; + struct net_device *dev = data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 enable = 0; diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index bc897da8c103..31986670b7f0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -331,56 +331,56 @@ void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, v case TYPE_EFUSE_MAX_SECTION: { u8 *pMax_section; - pMax_section = (u8 *)pOut; + pMax_section = pOut; *pMax_section = EFUSE_MAX_SECTION_88E; } break; case TYPE_EFUSE_REAL_CONTENT_LEN: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; } break; case TYPE_EFUSE_CONTENT_LEN_BANK: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E; } break; case TYPE_AVAILABLE_EFUSE_BYTES_BANK: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E); } break; case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E); } break; case TYPE_EFUSE_MAP_LEN: { u16 *pu2Tmp; - pu2Tmp = (u16 *)pOut; + pu2Tmp = pOut; *pu2Tmp = (u16)EFUSE_MAP_LEN_88E; } break; case TYPE_EFUSE_PROTECT_BYTES_BANK: { u8 *pu1Tmp; - pu1Tmp = (u8 *)pOut; + pu1Tmp = pOut; *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E); } break; default: { u8 *pu1Tmp; - pu1Tmp = (u8 *)pOut; + pu1Tmp = pOut; *pu1Tmp = 0; } break; diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c index 384be22052e5..2aa62517e4a2 100644 --- a/drivers/staging/rtl8188eu/core/rtw_led.c +++ b/drivers/staging/rtl8188eu/core/rtw_led.c @@ -28,7 +28,7 @@ /* */ void BlinkTimerCallback(void *data) { - struct LED_871x *pLed = (struct LED_871x *)data; + struct LED_871x *pLed = data; struct adapter *padapter = pLed->padapter; if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index b4e8504b34ed..dec26a89c356 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -1362,7 +1362,7 @@ void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf) */ void _rtw_join_timeout_handler (void *function_context) { - struct adapter *adapter = (struct adapter *)function_context; + struct adapter *adapter = function_context; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; int do_join_r; @@ -1404,7 +1404,7 @@ void _rtw_join_timeout_handler (void *function_context) */ void rtw_scan_timeout_handler (void *function_context) { - struct adapter *adapter = (struct adapter *)function_context; + struct adapter *adapter = function_context; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 5ba5099ec20d..8bb490820557 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -4835,7 +4835,7 @@ void linked_status_chk(struct adapter *padapter) void survey_timer_hdl(void *function_context) { - struct adapter *padapter = (struct adapter *)function_context; + struct adapter *padapter = function_context; struct cmd_obj *ph2c; struct sitesurvey_parm *psurveyPara; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; @@ -4912,7 +4912,7 @@ void link_timer_hdl(void *function_context) void addba_timer_hdl(void *function_context) { - struct sta_info *psta = (struct sta_info *)function_context; + struct sta_info *psta = function_context; struct ht_priv *phtpriv; if (!psta) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 27ed83cca193..768dbeee94c4 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -284,7 +284,7 @@ void rtw_ps_processor(struct adapter *padapter) static void pwr_state_check_handler(void *FunctionContext) { - struct adapter *padapter = (struct adapter *)FunctionContext; + struct adapter *padapter = FunctionContext; rtw_ps_cmd(padapter); } diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 4d56dbad2a7d..53a054c189e4 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -1949,7 +1949,7 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, void rtw_reordering_ctrl_timeout_handler(void *pcontext) { - struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; + struct recv_reorder_ctrl *preorder_ctrl = pcontext; struct adapter *padapter = preorder_ctrl->padapter; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; -- GitLab From 08a3d85a016467c68b224e1a4d9e844a397d92e2 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:03:19 +0530 Subject: [PATCH 2275/9457] staging: rtl8188eu: hal: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c | 2 +- drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index d6fe5e6aa4f4..68db5c99696f 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -181,7 +181,7 @@ static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable switch (eVariable) { case HAL_ODM_STA_INFO: { - struct sta_info *psta = (struct sta_info *)pValue1; + struct sta_info *psta = pValue1; if (bSet) { DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c index 7a4f754d86df..a6ba53b488e3 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c @@ -25,7 +25,7 @@ void dump_txrpt_ccx_88e(void *buf) { - struct txrpt_ccx_88e *txrpt_ccx = (struct txrpt_ccx_88e *)buf; + struct txrpt_ccx_88e *txrpt_ccx = buf; DBG_88E("%s:\n" "tag1:%u, pkt_num:%u, txdma_underflow:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n" -- GitLab From 037a449ac71fc5c70d2b0af28ce6792065daae55 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:03:31 +0530 Subject: [PATCH 2276/9457] staging: rtl8188eu: os_dep: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index ba1e178fb510..7da85f9c127b 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -843,7 +843,7 @@ void usb_write_port_cancel(struct adapter *padapter) void rtl8188eu_recv_tasklet(void *priv) { struct sk_buff *pskb; - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = priv; struct recv_priv *precvpriv = &adapt->recvpriv; while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { @@ -862,7 +862,7 @@ void rtl8188eu_recv_tasklet(void *priv) void rtl8188eu_xmit_tasklet(void *priv) { int ret = false; - struct adapter *adapt = (struct adapter *)priv; + struct adapter *adapt = priv; struct xmit_priv *pxmitpriv = &adapt->xmitpriv; if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY)) -- GitLab From ad6128a3a16627e6bfd3f34db371365f0d341c6f Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:03:55 +0530 Subject: [PATCH 2277/9457] staging: rtl8723au: core: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 799b9cf63263..81960e788f89 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -176,7 +176,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, switch (type) { case TYPE_EFUSE_MAX_SECTION: - pMax_section = (u8 *) pOut; + pMax_section = pOut; if (efuseType == EFUSE_WIFI) *pMax_section = EFUSE_MAX_SECTION_8723A; @@ -185,7 +185,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_REAL_CONTENT_LEN: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; @@ -194,7 +194,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_AVAILABLE_EFUSE_BYTES_BANK: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - @@ -205,7 +205,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - @@ -216,7 +216,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_MAP_LEN: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_MAP_LEN_8723A; @@ -225,7 +225,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_PROTECT_BYTES_BANK: - pu1Tmp = (u8 *) pOut; + pu1Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; @@ -234,7 +234,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; case TYPE_EFUSE_CONTENT_LEN_BANK: - pu2Tmp = (u16 *) pOut; + pu2Tmp = pOut; if (efuseType == EFUSE_WIFI) *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; @@ -243,7 +243,7 @@ EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, break; default: - pu1Tmp = (u8 *) pOut; + pu1Tmp = pOut; *pu1Tmp = 0; break; } -- GitLab From aa54b60d63abf51227336de9c1ec13bdbabfee88 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:04:05 +0530 Subject: [PATCH 2278/9457] staging: rts5208: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/rtsx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 2d2527c3aea2..c74f1b8108f6 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -418,7 +418,7 @@ static void rtsx_shutdown(struct pci_dev *pci) static int rtsx_control_thread(void *__dev) { - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_dev *dev = __dev; struct rtsx_chip *chip = dev->chip; struct Scsi_Host *host = rtsx_to_host(dev); @@ -527,7 +527,7 @@ static int rtsx_control_thread(void *__dev) static int rtsx_polling_thread(void *__dev) { - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_dev *dev = __dev; struct rtsx_chip *chip = dev->chip; struct sd_info *sd_card = &(chip->sd_card); struct xd_info *xd_card = &(chip->xd_card); -- GitLab From e3b6db3294b079b5bc986cceb465feddf3623906 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:04:15 +0530 Subject: [PATCH 2279/9457] staging: ft1000: ft1000-pcmcia: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 9de308906054..5a9d20bc4204 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -2002,7 +2002,7 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t ft1000_interrupt(int irq, void *dev_id) { - struct net_device *dev = (struct net_device *)dev_id; + struct net_device *dev = dev_id; struct ft1000_info *info = netdev_priv(dev); u16 tempword; u16 inttype; -- GitLab From 099e1f8f777f4f329181415fc405a3a2093a3e15 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:04:24 +0530 Subject: [PATCH 2280/9457] staging: ft1000: ft1000-usb: Remove useless cast on void pointer void pointers do not need to be cast to other pointer types. The semantic patch used to find this: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 7fb5c3f00632..fe882bd69e38 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -653,7 +653,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, state = STATE_START_DWNLD; - file_hdr = (struct dsp_file_hdr *)pFileStart; + file_hdr = pFileStart; ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); -- GitLab From f811be139e9bcf014049d7aa93225a4dbea33c53 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 17:04:36 +0530 Subject: [PATCH 2281/9457] staging: rtl8188eu: Remove double test Removed the duplicate test on memcmp(pIE->data, BROADCOM_OUI2, 3). The semantic that find this problem is // @@ expression E; @@ ( * E || ... || E | * E && ... && E ) // Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_wlan_util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 33ccbbbd8ed6..c495977c209e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c @@ -1394,7 +1394,6 @@ unsigned char check_assoc_AP(u8 *pframe, uint len) DBG_88E("link to Artheros AP\n"); return HT_IOT_PEER_ATHEROS; } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) || - (!memcmp(pIE->data, BROADCOM_OUI2, 3)) || (!memcmp(pIE->data, BROADCOM_OUI2, 3))) { DBG_88E("link to Broadcom AP\n"); return HT_IOT_PEER_BROADCOM; -- GitLab From d8d34a817bc0041ba2f0ee09e40c18c7161e2c2d Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 18:23:11 +0530 Subject: [PATCH 2282/9457] staging: dgap: Remove useless cast on NULL Cast on NULL to a pointer type is not required. This patch removes NULL casted to some pointer type. The sematic patch used is: @r@ type T; @@ - (T *)NULL + NULL Build tested it. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 105c3b8f4024..ed356f1bdece 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -7028,7 +7028,7 @@ static char *dgap_sindex(char *string, char *group) char *ptr; if (!string || !group) - return (char *) NULL; + return NULL; if (*group == '^') { group++; @@ -7049,7 +7049,7 @@ static char *dgap_sindex(char *string, char *group) } } - return (char *) NULL; + return NULL; } /* -- GitLab From 7499b702f0873b670cbd769c9bfeb437e9fa4c55 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 18:25:00 +0530 Subject: [PATCH 2283/9457] staging: rt18188eu: Remove useless cast on NULL Cast on NULL to a pointer type is not required. This patch removes NULL casted to some pointer type. The sematic patch used is: @r@ type T; @@ - (T *)NULL + NULL Build tested it. Signed-off-by: Tapasweni Pathak Reviewed-by: Josh Triplett Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 8bb490820557..a00ebcddc881 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -945,7 +945,7 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame } pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); - if (pstat == (struct sta_info *)NULL) { + if (pstat == NULL) { status = _RSON_CLS2_; goto asoc_class2_error; } -- GitLab From acf722f73499d85e959ce99cf22d1b827d0b273a Mon Sep 17 00:00:00 2001 From: Alexey Andriyanov Date: Wed, 29 Oct 2014 10:54:52 +0300 Subject: [PATCH 2284/9457] ip6_tunnel: allow to change mode for the ip6tnl0 The fallback device is in ipv6 mode by default. The mode can not be changed in runtime, so there is no way to decapsulate ip4in6 packets coming from various sources without creating the specific tunnel ifaces for each peer. This allows to update the fallback tunnel device, but only the mode could be changed. Usual command should work for the fallback device: `ip -6 tun change ip6tnl0 mode any` The fallback device can not be hidden from the packet receiver as a regular tunnel, but there is no need for synchronization as long as we do single assignment. Cc: David S. Miller Cc: Eric Dumazet Signed-off-by: Alexey Andriyanov Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9409887fb664..8c97cd1048c2 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -477,6 +477,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, int rel_msg = 0; u8 rel_type = ICMPV6_DEST_UNREACH; u8 rel_code = ICMPV6_ADDR_UNREACH; + u8 tproto; __u32 rel_info = 0; __u16 len; int err = -ENOENT; @@ -490,7 +491,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, &ipv6h->saddr)) == NULL) goto out; - if (t->parms.proto != ipproto && t->parms.proto != 0) + tproto = ACCESS_ONCE(t->parms.proto); + if (tproto != ipproto && tproto != 0) goto out; err = 0; @@ -791,6 +793,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, { struct ip6_tnl *t; const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + u8 tproto; int err; rcu_read_lock(); @@ -799,7 +802,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, &ipv6h->daddr)) != NULL) { struct pcpu_sw_netstats *tstats; - if (t->parms.proto != ipproto && t->parms.proto != 0) { + tproto = ACCESS_ONCE(t->parms.proto); + if (tproto != ipproto && tproto != 0) { rcu_read_unlock(); goto discard; } @@ -1078,9 +1082,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) struct flowi6 fl6; __u8 dsfield; __u32 mtu; + u8 tproto; int err; - if ((t->parms.proto != IPPROTO_IPIP && t->parms.proto != 0) || + tproto = ACCESS_ONCE(t->parms.proto); + if ((tproto != IPPROTO_IPIP && tproto != 0) || !ip6_tnl_xmit_ctl(t)) return -1; @@ -1120,9 +1126,11 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) struct flowi6 fl6; __u8 dsfield; __u32 mtu; + u8 tproto; int err; - if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || + tproto = ACCESS_ONCE(t->parms.proto); + if ((tproto != IPPROTO_IPV6 && tproto != 0) || !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h)) return -1; @@ -1285,6 +1293,14 @@ static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p) return err; } +static int ip6_tnl0_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p) +{ + /* for default tnl0 device allow to change only the proto */ + t->parms.proto = p->proto; + netdev_state_change(t->dev); + return 0; +} + static void ip6_tnl_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm *u) { @@ -1384,7 +1400,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; ip6_tnl_parm_from_user(&p1, &p); t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL); - if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) { + if (cmd == SIOCCHGTUNNEL) { if (t != NULL) { if (t->dev != dev) { err = -EEXIST; @@ -1392,8 +1408,10 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } } else t = netdev_priv(dev); - - err = ip6_tnl_update(t, &p1); + if (dev == ip6n->fb_tnl_dev) + err = ip6_tnl0_update(t, &p1); + else + err = ip6_tnl_update(t, &p1); } if (t) { err = 0; -- GitLab From 4c87454a475280aa140913a0bce48db43a52b2fc Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Thu, 30 Oct 2014 14:07:17 -0700 Subject: [PATCH 2285/9457] hyperv: Add IPv6 into the hash computation for vRSS This will allow the workload spreading via vRSS for IPv6. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 4 +++- drivers/net/hyperv/rndis_filter.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 78ec33f5100b..3295e4ee9dbb 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -193,7 +193,9 @@ static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb) struct flow_keys flow; int data_len; - if (!skb_flow_dissect(skb, &flow) || flow.n_proto != htons(ETH_P_IP)) + if (!skb_flow_dissect(skb, &flow) || + !(flow.n_proto == htons(ETH_P_IP) || + flow.n_proto == htons(ETH_P_IPV6))) return false; if (flow.ip_proto == IPPROTO_TCP) diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 2b86f0b6f6d1..ccce6f24b009 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -728,7 +728,8 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue) rssp->hdr.size = sizeof(struct ndis_recv_scale_param); rssp->flag = 0; rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 | - NDIS_HASH_TCP_IPV4; + NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 | + NDIS_HASH_TCP_IPV6; rssp->indirect_tabsize = 4*ITAB_NUM; rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param); rssp->hashkey_size = HASH_KEYLEN; -- GitLab From 7ede7af3fd5f92966d328586f7f42b378fa17d83 Mon Sep 17 00:00:00 2001 From: Aya Mahfouz Date: Thu, 30 Oct 2014 17:12:53 +0200 Subject: [PATCH 2286/9457] staging: media: lirc: lirc_zilog.c: remove unnecessary 'out of memory' message This patch fixes the following the following checkpatch.pl warning: Possible unnecessary 'out of memory' message The warning was issued for the file lirc_zilog.c after changing two custom printk messages to dev_err. The dev_err calls were simply removed. Signed-off-by: Aya Mahfouz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/lirc/lirc_zilog.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 11a7cb128d9e..52f8e91a6383 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -771,7 +771,6 @@ static int fw_load(struct IR_tx *tx) /* Parse the file */ tx_data = vmalloc(sizeof(*tx_data)); if (tx_data == NULL) { - dev_err(tx->ir->l.dev, "out of memory\n"); release_firmware(fw_entry); ret = -ENOMEM; goto out; @@ -781,7 +780,6 @@ static int fw_load(struct IR_tx *tx) /* Copy the data so hotplug doesn't get confused and timeout */ tx_data->datap = vmalloc(fw_entry->size); if (tx_data->datap == NULL) { - dev_err(tx->ir->l.dev, "out of memory\n"); release_firmware(fw_entry); vfree(tx_data); ret = -ENOMEM; -- GitLab From a055b3cbb72d2487938d3452c79e2a338088fbc1 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 21:08:09 +0530 Subject: [PATCH 2287/9457] staging: rtl8188eu: core: Remove null check before kfree kfree on NULL pointer is a no-op. This patch uses the following semantic patch to find such an instance where NULL check is present before kfree. // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // smpl> Build tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 7731cdb72b22..dd24138d13b1 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -433,8 +433,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; if (psecnetwork == NULL) { - if (pcmd != NULL) - kfree(pcmd); + kfree(pcmd); res = _FAIL; -- GitLab From 3cfab18ce55282a85e2c7e5db15c5daf065efdb4 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 21:11:57 +0530 Subject: [PATCH 2288/9457] staging: rtl8188eu: core: Improve cleanup code The code is restructured such that kfree(efuseTbl) is not called if the allocation of efuseTbl and such that kfree(eFuseWord) is not called if the allocation of eFuseWord has failed. To accomplish this a new label eFuseWord_failed has been added. Suggested by: Julia Lawall Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 31986670b7f0..c47b1573c6e8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -106,13 +106,13 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); if (efuseTbl == NULL) { DBG_88E("%s: alloc efuseTbl fail!\n", __func__); - goto exit; + return; } eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); if (eFuseWord == NULL) { DBG_88E("%s: alloc eFuseWord fail!\n", __func__); - goto exit; + goto eFuseWord_failed; } /* 0. Refresh efuse init map as all oxFF. */ @@ -210,10 +210,10 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf) /* */ exit: - kfree(efuseTbl); + kfree(eFuseWord); - if (eFuseWord) - kfree(eFuseWord); +eFuseWord_failed: + kfree(efuseTbl); } static void efuse_read_phymap_from_txpktbuf( -- GitLab From f4e715c3254e3c0167b5d4272901a2b248b65ad2 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 29 Oct 2014 16:05:06 -0700 Subject: [PATCH 2289/9457] ipv4: minor spelling fixes Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/ipv4/geneve.c | 2 +- net/ipv4/tcp_input.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 065cd94c640c..91861fe77ed1 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c @@ -104,7 +104,7 @@ static void geneve_build_header(struct genevehdr *geneveh, memcpy(geneveh->options, options, options_len); } -/* Transmit a fully formated Geneve frame. +/* Transmit a fully formatted Geneve frame. * * When calling this function. The skb->data should point * to the geneve header which is fully formed. diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9a18cdd633f3..df8b3c12a173 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5866,7 +5866,7 @@ static inline void pr_drop_req(struct request_sock *req, __u16 port, int family) * If we receive a SYN packet with these bits set, it means a * network is playing bad games with TOS bits. In order to * avoid possible false congestion notifications, we disable - * TCP ECN negociation. + * TCP ECN negotiation. * * Exception: tcp_ca wants ECN. This is required for DCTCP * congestion control; it requires setting ECT on all packets, -- GitLab From 3f3efca9c57fd5c12ac8d9e151db5bbbaec2d716 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Thu, 30 Oct 2014 22:03:36 +0530 Subject: [PATCH 2290/9457] staging: emxx_udc: use USB API functions rather than constants This patch introduces the use of the functions usb_endpoint_type and usb_endpoint_num. The Coccinelle semantic patch that makes these changes is as follows: @@ struct usb_endpoint_descriptor *epd; @@ - (epd->bEndpointAddress & \(USB_ENDPOINT_NUMBER_MASK\|0x0f\)) + usb_endpoint_num(epd) @@ struct usb_endpoint_descriptor *epd; @@ - (epd->bmAttributes & \(USB_ENDPOINT_XFERTYPE_MASK\|3\)) + usb_endpoint_type(epd) Build Tested it. Signed-off-by: Tapasweni Pathak Signed-off-by: Greg Kroah-Hartman --- drivers/staging/emxx_udc/emxx_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 77e4aee74fa1..0261d0b22ba7 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2622,7 +2622,7 @@ static int nbu2ss_ep_enable( return -EINVAL; } - ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + ep_type = usb_endpoint_type(desc); if ((ep_type == USB_ENDPOINT_XFER_CONTROL) || (ep_type == USB_ENDPOINT_XFER_ISOC)) { @@ -2644,7 +2644,7 @@ static int nbu2ss_ep_enable( spin_lock_irqsave(&udc->lock, flags); ep->desc = desc; - ep->epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep->epnum = usb_endpoint_num(desc); ep->direct = desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ep->ep_type = ep_type; ep->wedged = 0; -- GitLab From 35438c0011c3a3ba120ad78ea99bf38f009dc736 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 31 Oct 2014 01:32:38 +0530 Subject: [PATCH 2291/9457] Staging: ft1000: ft1000_hw.c: Removed some checkpatch errors and warnings. ERROR: space prohibited after that '&' (ctx:WxW) ERROR: "foo * bar" should be "foo *bar" ERROR: space prohibited after that open parenthesis '(' ERROR: space prohibited before that close parenthesis ')' Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 5a9d20bc4204..25b06d350f14 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -997,8 +997,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } else { tempword = FT1000_DPRAM_MAG_RX_BASE; - } - if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) { + } + if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) { /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; @@ -1224,7 +1224,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) for (i=1; i<7; i++) { ppseudo_hdr->checksum ^= *pmsg++; } - pmsg = (u16 *) & tempbuffer[16]; + pmsg = (u16 *) &tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1756,7 +1756,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) SUCCESS -------------------------------------------------------------------------*/ -static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) +static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) { struct ft1000_info *info = netdev_priv(dev); struct ft1000_pcmcia *pcmcia = info->priv; -- GitLab From ab784e5075698ed3b767d5e264a50aab39add209 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 29 Oct 2014 17:35:11 +0000 Subject: [PATCH 2292/9457] staging: comedi: das16: deschedule timer routine on detach The "das16" driver optionally uses a kernel timer and a DMA channel to support asynchronous data acquisition, but currently never calls `del_timer_sync()`. There is some possibility the timer routine could still be scheduled to run when the comedi "detach" handler is run to clean up the device and cause a certain amount of havoc. Avoid that by calling `del_time_sync()` in the comedi "detach" handler `das16_detach()` if the timer was initialized by the "attach" handler `das16_attach()`. Use the timer's `data` member to tell whether it was initialized or not. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index aa9e3e10d59d..4556af109eae 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1228,6 +1228,8 @@ static void das16_detach(struct comedi_device *dev) int i; if (devpriv) { + if (devpriv->timer.data) + del_timer_sync(&devpriv->timer); if (dev->iobase) das16_reset(dev); -- GitLab From 0a43f75ef57fcf20b9637fa49889e6721ceb5ea7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 29 Oct 2014 17:35:12 +0000 Subject: [PATCH 2293/9457] staging: comedi: das16: use spin-lock when setting timer "das16" sets a timer running in `das16_cmd_exec()` and sets `devpriv->timer_running` to indicate that it is running. The timer expiration routine `das16_timer_interrupt()` checks `devpriv->timer_running` to check whether it needs to reschedule the timer, but this is not synchronized with `das16_cmd_exec()`. Since `das16_cancel()` acquires the `dev->spinlock` spin-lock when clearing `devpriv->timer_running` and removing the timer from the queue, use the same spin-lock in `das16_cmd_exec()` and `das16_timer_interrupt()` around the setting and checking of `devpriv->timer_running`. Since `das16_interrupt()` (called from `das16_timer_interrupt()`) checks whether DMA is enabled in the device while holding `dev->spinlock`, and DMA is enabled by `das16_cmd_exec()` around the time it schedules the timer, enable the DMA in the device while holding the spin-lock. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 4556af109eae..8e512b241653 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -595,11 +595,14 @@ static void das16_timer_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; struct das16_private_struct *devpriv = dev->private; + unsigned long flags; das16_interrupt(dev); + spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->timer_running) mod_timer(&devpriv->timer, jiffies + timer_period()); + spin_unlock_irqrestore(&dev->spinlock, flags); } static int das16_ai_check_chanlist(struct comedi_device *dev, @@ -816,7 +819,8 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) enable_dma(devpriv->dma_chan); release_dma_lock(flags); - /* set up interrupt */ + /* set up timer */ + spin_lock_irqsave(&dev->spinlock, flags); devpriv->timer_running = 1; devpriv->timer.expires = jiffies + timer_period(); add_timer(&devpriv->timer); @@ -825,6 +829,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->can_burst) outb(0, dev->iobase + DAS1600_CONV_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } -- GitLab From 8369e382bd98ee5586928bed41992f8bd73d4cec Mon Sep 17 00:00:00 2001 From: Eric Rost Date: Wed, 29 Oct 2014 19:12:08 -0500 Subject: [PATCH 2294/9457] staging: skein: Removes skein_debug include Removes skein_debug.h include since skein_debug.h is nonexistent. Removes unneeded debug empty macro defines and their uses. Signed-off-by: Eric Rost Reviewed-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_base.c | 18 ---------- drivers/staging/skein/skein_base.h | 17 ---------- drivers/staging/skein/skein_block.c | 51 +---------------------------- 3 files changed, 1 insertion(+), 85 deletions(-) diff --git a/drivers/staging/skein/skein_base.c b/drivers/staging/skein/skein_base.c index ebc436a1098f..7e700a6b5788 100644 --- a/drivers/staging/skein/skein_base.c +++ b/drivers/staging/skein/skein_base.c @@ -124,8 +124,6 @@ int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(256, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -232,8 +230,6 @@ int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_256_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -353,8 +349,6 @@ int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(512, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -461,8 +455,6 @@ int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x, n); - skein_show_final(512, &ctx->h, n, - hash_val+i*SKEIN_512_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -577,8 +569,6 @@ int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len, /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */ cfg.w[2] = skein_swap64(tree_info); - skein_show_key(1024, &ctx->h, key, key_bytes); - /* compute the initial chaining values from config block */ skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN); @@ -685,8 +675,6 @@ int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x, n); - skein_show_final(1024, &ctx->h, n, - hash_val+i*SKEIN_1024_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -794,8 +782,6 @@ int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_256_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -833,8 +819,6 @@ int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_512_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } @@ -872,8 +856,6 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val) /* "output" the ctr mode bytes */ skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x, n); - skein_show_final(256, &ctx->h, n, - hash_val+i*SKEIN_1024_BLOCK_BYTES); /* restore the counter mode key for next time */ memcpy(ctx->x, x, sizeof(x)); } diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index 0111fa426b32..993b951172f6 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -15,10 +15,6 @@ ** ** The "default" note explains what happens when the switch is not defined. ** -** SKEIN_DEBUG -- make callouts from inside Skein code -** to examine/display intermediate values. -** [default: no callouts (no overhead)] -** ** SKEIN_ERR_CHECK -- how error checking is handled inside Skein ** code. If not defined, most error checking ** is disabled (for performance). Otherwise, @@ -279,19 +275,6 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val); (hdr).tweak[1] |= SKEIN_T1_TREE_LEVEL(height); \ } -/***************************************************************** -** "Internal" Skein definitions for debugging and error checking -******************************************************************/ -#ifdef SKEIN_DEBUG /* examine/display intermediate values? */ -#include "skein_debug.h" -#else /* default is no callouts */ -#define skein_show_block(bits, ctx, x, blk_ptr, w_ptr, ks_event_ptr, ks_odd_ptr) -#define skein_show_round(bits, ctx, r, x) -#define skein_show_r_ptr(bits, ctx, r, x_ptr) -#define skein_show_final(bits, ctx, cnt, out_ptr) -#define skein_show_key(bits, ctx, key, key_bytes) -#endif - /* ignore all asserts, for performance */ #define skein_assert_ret(x, ret_code) #define skein_assert(x) diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 36b0b400acf3..66261ab25c88 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -70,7 +70,6 @@ do { \ #define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ do { \ ROUND256(p0, p1, p2, p3, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ } while (0) #define I256(R) \ @@ -80,14 +79,12 @@ do { \ X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ X3 += ks[((R) + 4) % 5] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #else /* looping version */ #define R256(p0, p1, p2, p3, ROT, r_num) \ do { \ ROUND256(p0, p1, p2, p3, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ } while (0) #define I256(R) \ @@ -100,7 +97,6 @@ do { \ /* rotate key schedule */ \ ks[r + (R) + 4] = ks[r + (R) - 1]; \ ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #endif #define R256_8_ROUNDS(R) \ @@ -160,8 +156,7 @@ do { \ #if SKEIN_UNROLL_512 == 0 #define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ do { \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - skein_show_r_ptr(BLK_BITS, &ctx->h, r_num, X_ptr); \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ } while (0) #define I512(R) \ @@ -175,14 +170,12 @@ do { \ X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ X7 += ks[((R) + 8) % 9] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #else /* looping version */ #define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ do { \ ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + r_num, X_ptr); \ } while (0) #define I512(R) \ @@ -199,7 +192,6 @@ do { \ /* rotate key schedule */ \ ks[r + (R) + 8] = ks[r + (R) - 1]; \ ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #endif /* end of looped code definitions */ #define R512_8_ROUNDS(R) /* do 8 full rounds */ \ @@ -274,7 +266,6 @@ do { \ do { \ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, rn, X_ptr); \ } while (0) #define I1024(R) \ @@ -296,7 +287,6 @@ do { \ X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ X15 += ks[((R) + 16) % 17] + (R) + 1; \ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #else /* looping version */ #define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ @@ -304,7 +294,6 @@ do { \ do { \ ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ pF, ROT, rn); \ - skein_show_r_ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, X_ptr); \ } while (0) #define I1024(R) \ @@ -329,7 +318,6 @@ do { \ /* rotate key schedule */ \ ks[r + (R) + 16] = ks[r + (R) - 1]; \ ts[r + (R) + 2] = ts[r + (R) - 1]; \ - skein_show_r_ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, X_ptr); \ } while (0) #endif @@ -413,7 +401,6 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); /* do the first full key injection */ X0 = w[0] + ks[0]; @@ -421,10 +408,6 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, X2 = w[2] + ks[2] + ts[1]; X3 = w[3] + ks[3]; - /* show starting state values */ - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - x_ptr); - blk_ptr += SKEIN_256_BLOCK_BYTES; /* run the rounds */ @@ -481,8 +464,6 @@ void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, ctx->x[2] = X2 ^ w[2]; ctx->x[3] = X3 ^ w[3]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); - ts[1] &= ~SKEIN_T1_FLAG_FIRST; } while (--blk_cnt); ctx->h.tweak[0] = ts[0]; @@ -558,7 +539,6 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); /* do the first full key injection */ X0 = w[0] + ks[0]; @@ -572,8 +552,6 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, blk_ptr += SKEIN_512_BLOCK_BYTES; - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - X_ptr); /* run the rounds */ for (r = 1; r < (SKEIN_UNROLL_512 ? 2 * RCNT : 2); @@ -634,7 +612,6 @@ void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, ctx->x[5] = X5 ^ w[5]; ctx->x[6] = X6 ^ w[6]; ctx->x[7] = X7 ^ w[7]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); ts[1] &= ~SKEIN_T1_FLAG_FIRST; } while (--blk_cnt); @@ -674,26 +651,6 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, u64 X00, X01, X02, X03, X04, X05, X06, X07, X08, X09, X10, X11, X12, X13, X14, X15; u64 w[WCNT]; /* local copy of input block */ -#ifdef SKEIN_DEBUG - const u64 *X_ptr[16]; /* use for debugging (help cc put Xn in regs) */ - - X_ptr[0] = &X00; - X_ptr[1] = &X01; - X_ptr[2] = &X02; - X_ptr[3] = &X03; - X_ptr[4] = &X04; - X_ptr[5] = &X05; - X_ptr[6] = &X06; - X_ptr[7] = &X07; - X_ptr[8] = &X08; - X_ptr[9] = &X09; - X_ptr[10] = &X10; - X_ptr[11] = &X11; - X_ptr[12] = &X12; - X_ptr[13] = &X13; - X_ptr[14] = &X14; - X_ptr[15] = &X15; -#endif skein_assert(blk_cnt != 0); /* never call with blk_cnt == 0! */ ts[0] = ctx->h.tweak[0]; @@ -732,7 +689,6 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, /* get input block in little-endian format */ skein_get64_lsb_first(w, blk_ptr, WCNT); debug_save_tweak(ctx); - skein_show_block(BLK_BITS, &ctx->h, ctx->x, blk_ptr, w, ks, ts); /* do the first full key injection */ X00 = w[0] + ks[0]; @@ -752,9 +708,6 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, X14 = w[14] + ks[14] + ts[1]; X15 = w[15] + ks[15]; - skein_show_r_ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL, - X_ptr); - for (r = 1; r < (SKEIN_UNROLL_1024 ? 2 * RCNT : 2); r += (SKEIN_UNROLL_1024 ? 2 * SKEIN_UNROLL_1024 : 1)) { @@ -821,8 +774,6 @@ void skein_1024_process_block(struct skein_1024_ctx *ctx, const u8 *blk_ptr, ctx->x[14] = X14 ^ w[14]; ctx->x[15] = X15 ^ w[15]; - skein_show_round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->x); - ts[1] &= ~SKEIN_T1_FLAG_FIRST; blk_ptr += SKEIN_1024_BLOCK_BYTES; } while (--blk_cnt); -- GitLab From a6a39a7fcff597c4384a21922332ee513f33ccbf Mon Sep 17 00:00:00 2001 From: Eunbong Song Date: Thu, 30 Oct 2014 01:09:00 +0000 Subject: [PATCH 2295/9457] staging: octeon-ethernet: disable load balance for receiving packet when CONFIG_RPS is enabled. It's better disable load balance for receiving packet when CONFIG_RPS is enabled. If not, octeon-ethernet driver select CPU and then the rps select again CPU. It can be ipi interrupts overhead and packet reordering could be possible. Signed-off-by: Eunbong Song Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/ethernet-rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index b2b6c3cd2bed..44e372f09683 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -286,6 +286,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) did_work_request = 1; } +#ifndef CONFIG_RPS if (rx_count == 0) { /* * First time through, see if there is enough @@ -300,6 +301,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) if (backlog > budget * cores_in_use && napi != NULL) cvm_oct_enable_one_cpu(); } +#endif rx_count++; skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1; -- GitLab From 425ebd0aa35dcfc5fe2449ef3e1194e422f6f9b4 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:45 -0400 Subject: [PATCH 2296/9457] staging: unisys: virtpci: Add a blank line after the definition of driver_private Insert a blank line between the definition of the driver_private structure and the next statement. Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 52ec69f06b92..1f72103c7b9b 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -50,6 +50,7 @@ struct driver_private { struct module_kobject *mkobj; struct device_driver *driver; }; + #define to_driver(obj) container_of(obj, struct driver_private, kobj) /* bus_id went away in 2.6.30 - the size was 20 bytes, so we'll define -- GitLab From 65cfadc33ede24a62e793f75f23acffd1d2bbf9c Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:46 -0400 Subject: [PATCH 2297/9457] staging: unisys: virtpci: Remove extraneous blank lines Removed unnecessary blank lines from virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 1f72103c7b9b..7b00cef79110 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -177,7 +177,6 @@ int WAIT_FOR_IO_CHANNEL(struct spar_io_channel_protocol __iomem *chanptr) int count = 120; while (count > 0) { - if (SPAR_CHANNEL_SERVER_READY(&chanptr->channel_header)) return 1; UIS_THREAD_WAIT_SEC(1); @@ -348,7 +347,6 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_SEVERITY_INFO); } return i; - } /* for CHANSOCK macaddr is AUTO-GENERATED; for normal channels, @@ -1566,7 +1564,6 @@ static void __exit virtpci_mod_exit(void) bus_unregister(&virtpci_bus_type); debugfs_remove_recursive(virtpci_debugfs_dir); LOGINF("Leaving\n"); - } module_init(virtpci_mod_init); -- GitLab From 15c769671739919226bb8aa2b7e23c5df7603086 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:47 -0400 Subject: [PATCH 2298/9457] staging: unisys: virtpci: Remove space between cast and variable Remove the whitespace between a cast and a variable in virtpci.c. Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 7b00cef79110..560639a715ca 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -200,7 +200,7 @@ static int write_vbus_chpInfo(struct spar_vbus_channel_protocol *chan, LOGERR("vbus channel not used, because chp_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -219,7 +219,7 @@ static int write_vbus_busInfo(struct spar_vbus_channel_protocol *chan, LOGERR("vbus channel not used, because bus_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -244,7 +244,7 @@ write_vbus_devInfo(struct spar_vbus_channel_protocol *chan, LOGERR("vbus channel not used, because dev_info_offset == 0"); return -1; } - memcpy(((u8 *) (chan)) + off, info, sizeof(*info)); + memcpy(((u8 *)(chan)) + off, info, sizeof(*info)); return 0; } @@ -325,7 +325,7 @@ static int add_vhba(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((struct spar_io_channel_protocol __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { LOGERR("Timed out. Channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -355,16 +355,16 @@ static int add_vhba(struct add_virt_guestpart *addparams) #define GET_NETADAPINFO_FROM_CHANPTR(chanptr) { \ memcpy_fromio(net.mac_addr, \ ((struct spar_io_channel_protocol __iomem *) \ - chanptr)->vnic.macaddr, \ + chanptr)->vnic.macaddr, \ MAX_MACADDR_LEN); \ net.num_rcv_bufs = \ readl(&((struct spar_io_channel_protocol __iomem *)\ - chanptr)->vnic.num_rcv_bufs); \ + chanptr)->vnic.num_rcv_bufs); \ net.mtu = readl(&((struct spar_io_channel_protocol __iomem *) \ - chanptr)->vnic.mtu); \ + chanptr)->vnic.mtu); \ memcpy_fromio(&net.zone_uuid, \ &((struct spar_io_channel_protocol __iomem *)\ - chanptr)->vnic.zone_uuid, \ + chanptr)->vnic.zone_uuid, \ sizeof(uuid_le)); \ } @@ -381,7 +381,7 @@ add_vnic(struct add_virt_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!WAIT_FOR_IO_CHANNEL - ((struct spar_io_channel_protocol __iomem *) addparams->chanptr)) { + ((struct spar_io_channel_protocol __iomem *)addparams->chanptr)) { LOGERR("Timed out, channel not ready\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; @@ -431,7 +431,7 @@ delete_vbus_device(struct device *vbus, void *data) int checkforroot = (data != NULL); struct device *pDev = &virtpci_rootbus_device; - if ((checkforroot) && match_busid(vbus, (void *) BUS_ID(pDev))) { + if ((checkforroot) && match_busid(vbus, (void *)BUS_ID(pDev))) { /* skip it - don't delete root bus */ LOGINF("skipping root bus\n"); return 0; /* pretend no error */ @@ -606,7 +606,7 @@ static void delete_all(void) /* now delete each vbus */ if (bus_for_each_dev - (&virtpci_bus_type, NULL, (void *) 1, delete_vbus_device)) + (&virtpci_bus_type, NULL, (void *)1, delete_vbus_device)) LOGERR("delete of all vbus failed\n"); } @@ -1447,7 +1447,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, printparam.buf = vbuf; printparam.len = &len; if (bus_for_each_dev(&virtpci_bus_type, NULL, - (void *) &printparam, print_vbus)) + (void *)&printparam, print_vbus)) LOGERR("Failed to find bus\n"); str_pos += scnprintf(vbuf + str_pos, len - str_pos, @@ -1532,7 +1532,7 @@ static int __init virtpci_mod_init(void) } DBGINF("device_register successful ret:%x\n", ret); - if (!uisctrl_register_req_handler(2, (void *) &virtpci_ctrlchan_func, + if (!uisctrl_register_req_handler(2, (void *)&virtpci_ctrlchan_func, &Chipset_DriverInfo)) { LOGERR("uisctrl_register_req_handler ****FAILED.\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -1542,7 +1542,7 @@ static int __init virtpci_mod_init(void) } LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n", - (void *) &virtpci_ctrlchan_func); + (void *)&virtpci_ctrlchan_func); /* create debugfs directory and info file inside. */ virtpci_debugfs_dir = debugfs_create_dir("virtpci", NULL); debugfs_create_file("info", S_IRUSR, virtpci_debugfs_dir, -- GitLab From 732bf98833d8a3f13a658e24513ca5661a4be62f Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:48 -0400 Subject: [PATCH 2299/9457] staging: unisys: virtpci: Allocate memory using the size of the variable Change two instances of using the sizeof a structure to the size of a specific variable when allocating memory in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 560639a715ca..3cfa7671ec06 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -256,7 +256,7 @@ static int add_vbus(struct add_vbus_guestpart *addparams) int ret; struct device *vbus; - vbus = kzalloc(sizeof(struct device), GFP_ATOMIC); + vbus = kzalloc(sizeof(*vbus), GFP_ATOMIC); POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); if (!vbus) @@ -922,7 +922,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, } /* add a Virtual Device */ - virtpcidev = kzalloc(sizeof(struct virtpci_dev), GFP_ATOMIC); + virtpcidev = kzalloc(sizeof(*virtpcidev), GFP_ATOMIC); if (virtpcidev == NULL) { LOGERR("can't add device - malloc FALLED\n"); POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR); -- GitLab From 65b96899ce7f12711656f0b3203554fd99e074a0 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:49 -0400 Subject: [PATCH 2300/9457] staging: unisys: virtpci: Place logical continuation at the end of a line Move the && logical continuation from the start of the second line of an if statement to the end of the first line. Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 3cfa7671ec06..baf12e54b6d9 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -696,8 +696,8 @@ virtpci_match_device(const struct pci_device_id *ids, DBGINF("ids->vendor:%x dev->vendor:%x ids->device:%x dev->device:%x\n", ids->vendor, dev->vendor, ids->device, dev->device); - if ((ids->vendor == dev->vendor) - && (ids->device == dev->device)) + if ((ids->vendor == dev->vendor) && + (ids->device == dev->device)) return ids; ids++; -- GitLab From 5e7590ee82a211948da94392cbc580811dbc85b8 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:50 -0400 Subject: [PATCH 2301/9457] staging: unisys: virtpci: Add braces to if/else statements Update if/else blocks with braces on both the if and the else blocks in virtpci.c. Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index baf12e54b6d9..07d1966e8b35 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -847,8 +847,9 @@ static int virtpci_device_probe(struct device *dev) virtpcidev->mydriver = virtpcidrv; POSTCODE_LINUX_2(VPCI_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO); - } else + } else { put_device(dev); + } } POSTCODE_LINUX_2(VPCI_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return error; /* -ENODEV for probe failure */ @@ -992,9 +993,9 @@ static int virtpci_device_add(struct device *parentbus, int devtype, } /* add it at the head */ - if (!VpcidevListHead) + if (!VpcidevListHead) { VpcidevListHead = virtpcidev; - else { + } else { /* insert virtpcidev at the head of our linked list of * vpcidevs */ -- GitLab From fe3600f33814a05389b18bc368410913c8bd395d Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:51 -0400 Subject: [PATCH 2302/9457] staging: unisys: virtpci: Use a single blank line to separate code blocks Remove one blank line of two between function variable declaration and implementation in virt_pci_mod_init(). Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 07d1966e8b35..f13daab98e56 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -1502,7 +1502,6 @@ static int __init virtpci_mod_init(void) { int ret; - if (!unisys_spar_platform) return -ENODEV; -- GitLab From 197ac858ae982eac0d59e1d3e7e87bc1e2b2908a Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:52 -0400 Subject: [PATCH 2303/9457] staging: unisys: virtpci: Fix alignment issues Use the appropriate whitespace alignment for multiline statements in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index f13daab98e56..928f0fde11bd 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -110,7 +110,7 @@ static int virtpci_device_probe(struct device *dev); static int virtpci_device_remove(struct device *dev); static ssize_t info_debugfs_read(struct file *file, char __user *buf, - size_t len, loff_t *offset); + size_t len, loff_t *offset); static const struct file_operations debugfs_info_fops = { .read = info_debugfs_read, @@ -392,9 +392,9 @@ add_vnic(struct add_virt_guestpart *addparams) GET_BUS_DEV(addparams->bus_no); LOGINF("Adding vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x rcvbufs:%d mtu:%d chanptr:%p%pUL\n", - net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], net.mac_addr[3], - net.mac_addr[4], net.mac_addr[5], net.num_rcv_bufs, net.mtu, - addparams->chanptr, &net.zone_uuid); + net.mac_addr[0], net.mac_addr[1], net.mac_addr[2], + net.mac_addr[3], net.mac_addr[4], net.mac_addr[5], + net.num_rcv_bufs, net.mtu, addparams->chanptr, &net.zone_uuid); i = virtpci_device_add(vbus, VIRTNIC_TYPE, addparams, NULL, &net); if (i) { LOGINF("Added vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", @@ -624,7 +624,7 @@ static int delete_all_virt(enum virtpci_dev_type devtype, if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { LOGERR("**** FAILED to delete all devices; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); return 0; } @@ -694,7 +694,7 @@ virtpci_match_device(const struct pci_device_id *ids, { while (ids->vendor || ids->subvendor || ids->class_mask) { DBGINF("ids->vendor:%x dev->vendor:%x ids->device:%x dev->device:%x\n", - ids->vendor, dev->vendor, ids->device, dev->device); + ids->vendor, dev->vendor, ids->device, dev->device); if ((ids->vendor == dev->vendor) && (ids->device == dev->device)) @@ -793,9 +793,9 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, break; } bus_device_info_init(&devInfo, stype, - virtpcidrv->name, - virtpcidrv->version, - virtpcidrv->vertag); + virtpcidrv->name, + virtpcidrv->version, + virtpcidrv->vertag); write_vbus_devInfo(pChan, &devInfo, devNo); /* Re-write bus+chipset info, because it is possible that this @@ -916,7 +916,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, if ((devtype != VIRTHBA_TYPE) && (devtype != VIRTNIC_TYPE)) { LOGERR("**** FAILED to add device; devtype:%d not vhba:%d or vnic:%d\n", - devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); + devtype, VIRTHBA_TYPE, VIRTNIC_TYPE); POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC, devtype, POSTCODE_SEVERITY_ERR); return 0; @@ -1427,7 +1427,7 @@ static int print_vbus(struct device *vbus, void *data) } static ssize_t info_debugfs_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) + size_t len, loff_t *offset) { ssize_t bytes_read = 0; int str_pos = 0; @@ -1519,7 +1519,7 @@ static int __init virtpci_mod_init(void) } DBGINF("bus_register successful\n"); bus_device_info_init(&Bus_DriverInfo, "clientbus", "virtpci", - VERSION, NULL); + VERSION, NULL); /* create a root bus used to parent all the virtpci buses. */ ret = device_register(&virtpci_rootbus_device); @@ -1542,11 +1542,11 @@ static int __init virtpci_mod_init(void) } LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n", - (void *)&virtpci_ctrlchan_func); + (void *)&virtpci_ctrlchan_func); /* create debugfs directory and info file inside. */ virtpci_debugfs_dir = debugfs_create_dir("virtpci", NULL); debugfs_create_file("info", S_IRUSR, virtpci_debugfs_dir, - NULL, &debugfs_info_fops); + NULL, &debugfs_info_fops); LOGINF("Leaving\n"); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); return 0; -- GitLab From 60444139a0ae5c4c4a4f4a7494a8ec0a1785979a Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2014 16:18:53 -0400 Subject: [PATCH 2304/9457] staging: unisys: virtpci: Adjust lines to contain a maximum of 80 characters Update delete_all_virt function definition to two lines so each line is less than 80 characters long. Move comments on virtpci_device_add function parameters to a header block to contain each line to 80 characters. Signed-off-by: Bryan Thompson Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 928f0fde11bd..b6c313000899 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -897,10 +897,13 @@ static void virtpci_bus_release(struct device *dev) /* Adapter functions */ /*****************************************************/ +/* scsi is expected to be NULL for VNIC add + * net is expected to be NULL for VHBA add + */ static int virtpci_device_add(struct device *parentbus, int devtype, struct add_virt_guestpart *addparams, - struct scsi_adap_info *scsi, /* NULL for VNIC add */ - struct net_adap_info *net /* NULL for VHBA add */) + struct scsi_adap_info *scsi, + struct net_adap_info *net) { struct virtpci_dev *virtpcidev = NULL; struct virtpci_dev *tmpvpcidev = NULL, *prev; -- GitLab From 477b35b44febe2c972e35ca6517ea9c9768a2458 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Oct 2014 16:54:45 -0700 Subject: [PATCH 2305/9457] mlx4: use napi_schedule_irqoff() mlx4_en_rx_irq() and mlx4_en_tx_irq() run from hard interrupt context. They can use napi_schedule_irqoff() instead of napi_schedule() Signed-off-by: Eric Dumazet Acked-By: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index c8e75dab8055..c562c1468944 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -878,8 +878,8 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq) struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq); struct mlx4_en_priv *priv = netdev_priv(cq->dev); - if (priv->port_up) - napi_schedule(&cq->napi); + if (likely(priv->port_up)) + napi_schedule_irqoff(&cq->napi); else mlx4_en_arm_cq(priv, cq); } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 34c137878545..5c4062921cdf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -479,8 +479,8 @@ void mlx4_en_tx_irq(struct mlx4_cq *mcq) struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq); struct mlx4_en_priv *priv = netdev_priv(cq->dev); - if (priv->port_up) - napi_schedule(&cq->napi); + if (likely(priv->port_up)) + napi_schedule_irqoff(&cq->napi); else mlx4_en_arm_cq(priv, cq); } -- GitLab From f5fbf115691c350f88bae103f629503e201a7bff Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 29 Oct 2014 17:07:50 -0700 Subject: [PATCH 2306/9457] bnx2x: use napi_schedule_irqoff() bnx2x_msix_fp_int() and bnx2x_interrupt() run from hard interrupt context. They can use napi_schedule_irqoff() instead of napi_schedule() Signed-off-by: Eric Dumazet Cc: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 40beef5bca88..e9af4af5edba 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1139,7 +1139,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) prefetch(fp->txdata_ptr[cos]->tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); - napi_schedule(&bnx2x_fp(bp, fp->index, napi)); + napi_schedule_irqoff(&bnx2x_fp(bp, fp->index, napi)); return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 74fbf9ea7bd8..c4bd025c74c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1931,7 +1931,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) for_each_cos_in_tx_queue(fp, cos) prefetch(fp->txdata_ptr[cos]->tx_cons_sb); prefetch(&fp->sb_running_index[SM_RX_ID]); - napi_schedule(&bnx2x_fp(bp, fp->index, napi)); + napi_schedule_irqoff(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; } } -- GitLab From 646697b9e3fef913bb6393ebfb6115c442a96be7 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 30 Oct 2014 02:55:38 +0100 Subject: [PATCH 2307/9457] syncookies: only increment SYNCOOKIESFAILED on validation error Only count packets that failed cookie-authentication. We can get SYNCOOKIESFAILED > 0 while we never even sent a single cookie. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv4/syncookies.c | 7 +++++-- net/ipv6/syncookies.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 32b98d0207b4..4ac7bcaf2f46 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -275,8 +275,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; - if (tcp_synq_no_recent_overflow(sk) || - (mss = __cookie_v4_check(ip_hdr(skb), th, cookie)) == 0) { + if (tcp_synq_no_recent_overflow(sk)) + goto out; + + mss = __cookie_v4_check(ip_hdr(skb), th, cookie); + if (mss == 0) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); goto out; } diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 0e26e795b703..be291baa2ec2 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -171,8 +171,11 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; - if (tcp_synq_no_recent_overflow(sk) || - (mss = __cookie_v6_check(ipv6_hdr(skb), th, cookie)) == 0) { + if (tcp_synq_no_recent_overflow(sk)) + goto out; + + mss = __cookie_v6_check(ipv6_hdr(skb), th, cookie); + if (mss == 0) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); goto out; } -- GitLab From 6761049629402fc811961b4f996fec77169b5429 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 30 Oct 2014 11:46:40 +0800 Subject: [PATCH 2308/9457] r8152: set RTL8152_UNPLUG when finding -ENODEV Set RTL8152_UNPLUG when finding -ENODEV. This could accelerate unloading the driver when the device is unplugged. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e1810bc386b7..f11633588a0a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -690,6 +690,9 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, } } + if (ret == -ENODEV) + set_bit(RTL8152_UNPLUG, &tp->flags); + return ret; } @@ -757,6 +760,9 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, } error1: + if (ret == -ENODEV) + set_bit(RTL8152_UNPLUG, &tp->flags); + return ret; } @@ -1083,6 +1089,7 @@ static void read_bulk_callback(struct urb *urb) result = r8152_submit_rx(tp, agg, GFP_ATOMIC); if (result == -ENODEV) { + set_bit(RTL8152_UNPLUG, &tp->flags); netif_device_detach(tp->netdev); } else if (result) { spin_lock(&tp->rx_lock); @@ -1187,11 +1194,13 @@ static void intr_callback(struct urb *urb) resubmit: res = usb_submit_urb(urb, GFP_ATOMIC); - if (res == -ENODEV) + if (res == -ENODEV) { + set_bit(RTL8152_UNPLUG, &tp->flags); netif_device_detach(tp->netdev); - else if (res) + } else if (res) { netif_err(tp, intr, tp->netdev, "can't resubmit intr, status %d\n", res); + } } static inline void *rx_agg_align(void *data) @@ -1755,6 +1764,7 @@ static void tx_bottom(struct r8152 *tp) struct net_device *netdev = tp->netdev; if (res == -ENODEV) { + set_bit(RTL8152_UNPLUG, &tp->flags); netif_device_detach(netdev); } else { struct net_device_stats *stats = &netdev->stats; -- GitLab From b2ad5e5fcc7d2385ac7dcf0617a4b22f52245086 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 29 Oct 2014 22:58:51 -0700 Subject: [PATCH 2309/9457] tipc: spelling errors Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/tipc/msg.c | 4 ++-- net/tipc/socket.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 74745a47d72a..ec18076e81ec 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -91,7 +91,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, * @*headbuf: in: NULL for first frag, otherwise value returned from prev call * out: set when successful non-complete reassembly, otherwise NULL * @*buf: in: the buffer to append. Always defined - * out: head buf after sucessful complete reassembly, otherwise NULL + * out: head buf after successful complete reassembly, otherwise NULL * Returns 1 when reassembly complete, otherwise 0 */ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) @@ -311,7 +311,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu) * @mtu: max allowable size for the bundle buffer, inclusive header * @dnode: destination node for message. (Not always present in header) * Replaces buffer if successful - * Returns true if sucess, otherwise false + * Returns true if success, otherwise false */ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode) { diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 51bddc236a15..ad8a1a1e2275 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1556,7 +1556,7 @@ static void tipc_data_ready(struct sock *sk) * @tsk: TIPC socket * @msg: message * - * Returns 0 (TIPC_OK) if everyting ok, -TIPC_ERR_NO_PORT otherwise + * Returns 0 (TIPC_OK) if everything ok, -TIPC_ERR_NO_PORT otherwise */ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) { -- GitLab From 9056be30542bfff51190bdda67088f319cf4c9f5 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 30 Oct 2014 14:35:01 -0700 Subject: [PATCH 2310/9457] Staging: lustre: lnet: lnet: Better cookie gen api-ni.c uses do_gettimeofday to get a 'cookie' or timestamp. This patch replaces it with ktime_get_ns for the following reasons: 1. ktime_get_ns returns a __u64 which is safer than 'struct timeval' which will overflow on 32-bit systems in year 2038 and beyond. 2. Improved resolution: nsecs instead of usecs. 3. Reduced compute: ktime_get_ns is faster than the multiply/add combination used in this function Signed-off-by: Tina Ruchandani Suggested-by: Arnd Bergmann Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/api-ni.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 60bc2ae4fdf1..5e6e4e22ed31 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -37,6 +37,7 @@ #define DEBUG_SUBSYSTEM S_LNET #include "../../include/linux/lnet/lib-lnet.h" #include +#include #define D_LNI D_CONSOLE @@ -417,17 +418,9 @@ static __u64 lnet_create_interface_cookie(void) { /* NB the interface cookie in wire handles guards against delayed - * replies and ACKs appearing valid after reboot. Initialisation time, - * even if it's only implemented to millisecond resolution is probably - * easily good enough. */ - struct timeval tv; - __u64 cookie; - - do_gettimeofday(&tv); - cookie = tv.tv_sec; - cookie *= 1000000; - cookie += tv.tv_usec; - return cookie; + * replies and ACKs appearing valid after reboot. + */ + return ktime_get_ns(); } static char * -- GitLab From 891310d53dcf396d6a92987da265a5ffe6c09d71 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 30 Oct 2014 10:29:15 +0100 Subject: [PATCH 2311/9457] sctp: add transport state in /proc/net/sctp/remaddr It is often quite helpful to be able to know the state of a transport outside of the application itself (for troubleshooting purposes or for monitoring purposes). Add it under /proc/net/sctp/remaddr. Signed-off-by: Michele Baldessari Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/sctp/proc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 34229ee7f379..bfb242af06ab 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -417,7 +417,7 @@ static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos) if (*pos == 0) seq_printf(seq, "ADDR ASSOC_ID HB_ACT RTO MAX_PATH_RTX " - "REM_ADDR_RTX START\n"); + "REM_ADDR_RTX START STATE\n"); return (void *)pos; } @@ -497,7 +497,13 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) * currently implemented, but we can record it with a * jiffies marker in a subsequent patch */ - seq_printf(seq, "0"); + seq_printf(seq, "0 "); + + /* + * The current state of this destination. I.e. + * SCTP_ACTIVE, SCTP_INACTIVE, ... + */ + seq_printf(seq, "%d", tsp->state); seq_printf(seq, "\n"); } -- GitLab From afb6befce60e3a8b09f7633b9e34e702a72adc0e Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 30 Oct 2014 10:29:16 +0100 Subject: [PATCH 2312/9457] sctp: replace seq_printf with seq_puts Fixes checkpatch warning: "WARNING: Prefer seq_puts to seq_printf" Signed-off-by: Michele Baldessari Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/sctp/proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index bfb242af06ab..0697eda5aed8 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -490,14 +490,14 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) * Note: We don't have a way to tally this at the moment * so lets just leave it as zero for the moment */ - seq_printf(seq, "0 "); + seq_puts(seq, "0 "); /* * remote address start time (START). This is also not * currently implemented, but we can record it with a * jiffies marker in a subsequent patch */ - seq_printf(seq, "0 "); + seq_puts(seq, "0 "); /* * The current state of this destination. I.e. -- GitLab From cd2145358e7a5bb1798a185e5ef199ea49c69dd7 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Thu, 30 Oct 2014 12:48:08 -0400 Subject: [PATCH 2313/9457] tcp: Correction to RFC number in comment Challenge ACK is described in RFC 5961, fix typo. Signed-off-by: Sowmini Varadhan Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index df8b3c12a173..4e4617e90417 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5029,7 +5029,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, /* step 3: check security and precedence [ignored] */ /* step 4: Check for a SYN - * RFC 5691 4.2 : Send a challenge ack + * RFC 5961 4.2 : Send a challenge ack */ if (th->syn) { syn_challenge: -- GitLab From 7bd68bfd51f611ba61b3afdbd23ea9580c312bf5 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Thu, 30 Oct 2014 12:45:58 -0400 Subject: [PATCH 2314/9457] sunvnet: Reset LDC_EVENT_DATA_READY when napi completes. When vnet_event_napi re-enables interrupts, it should reset LDC_EVENT_DATA_READY as an optimization. Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index c390a2784546..7ada479f9604 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -760,6 +760,7 @@ static int vnet_poll(struct napi_struct *napi, int budget) if (processed < budget) { napi_complete(napi); + port->rx_event &= ~LDC_EVENT_DATA_READY; vio_set_intr(vio->vdev->rx_ino, HV_INTR_ENABLED); } return processed; -- GitLab From d51bffd16d39d7fe8b374a5fdebf16210ca41892 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Thu, 30 Oct 2014 12:46:09 -0400 Subject: [PATCH 2315/9457] sunvnet: Use one Tx queue per vnet_port Use multple Tx netdev queues for sunvnet by supporting a one-to-one mapping between vnet_port and Tx queue. Provide a ndo_select_queue indirection (vnet_select_queue()) which selects the queue based on the peer that would be selected in vnet_start_xmit() Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 94 ++++++++++++++++++++---------- drivers/net/ethernet/sun/sunvnet.h | 2 + 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 7ada479f9604..e7bb63b2d525 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -40,6 +40,8 @@ MODULE_DESCRIPTION("Sun LDOM virtual network driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); +#define VNET_MAX_TXQS 16 + /* Heuristic for the number of times to exponentially backoff and * retry sending an LDC trigger when EAGAIN is encountered */ @@ -551,6 +553,8 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) struct vnet *vp; u32 end; struct vio_net_desc *desc; + struct netdev_queue *txq; + if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) return 0; @@ -580,7 +584,8 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) } netif_tx_unlock(dev); - if (unlikely(netif_queue_stopped(dev) && + txq = netdev_get_tx_queue(dev, port->q_index); + if (unlikely(netif_tx_queue_stopped(txq) && vnet_tx_dring_avail(dr) >= VNET_TX_WAKEUP_THRESH(dr))) return 1; @@ -608,31 +613,23 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf) return 0; } -static void maybe_tx_wakeup(struct vnet *vp) +/* Got back a STOPPED LDC message on port. If the queue is stopped, + * wake it up so that we'll send out another START message at the + * next TX. + */ +static void maybe_tx_wakeup(struct vnet_port *port) { - struct net_device *dev = vp->dev; + struct netdev_queue *txq; - netif_tx_lock(dev); - if (likely(netif_queue_stopped(dev))) { - struct vnet_port *port; - int wake = 1; - - rcu_read_lock(); - list_for_each_entry_rcu(port, &vp->port_list, list) { - struct vio_dring_state *dr; - - dr = &port->vio.drings[VIO_DRIVER_TX_RING]; - if (vnet_tx_dring_avail(dr) < - VNET_TX_WAKEUP_THRESH(dr)) { - wake = 0; - break; - } - } - rcu_read_unlock(); - if (wake) - netif_wake_queue(dev); + txq = netdev_get_tx_queue(port->vp->dev, port->q_index); + __netif_tx_lock(txq, smp_processor_id()); + if (likely(netif_tx_queue_stopped(txq))) { + struct vio_dring_state *dr; + + dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + netif_tx_wake_queue(txq); } - netif_tx_unlock(dev); + __netif_tx_unlock(txq); } static inline bool port_is_up(struct vnet_port *vnet) @@ -748,7 +745,7 @@ static int vnet_event_napi(struct vnet_port *port, int budget) break; } if (unlikely(tx_wakeup && err != -ECONNRESET)) - maybe_tx_wakeup(port->vp); + maybe_tx_wakeup(port); return npkts; } @@ -953,6 +950,16 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, void **pstart, return skb; } +static u16 +vnet_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct vnet *vp = netdev_priv(dev); + struct vnet_port *port = __tx_port_find(vp, skb); + + return port->q_index; +} + static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vnet *vp = netdev_priv(dev); @@ -965,6 +972,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) void *start = NULL; int nlen = 0; unsigned pending = 0; + struct netdev_queue *txq; skb = vnet_skb_shape(skb, &start, &nlen); if (unlikely(!skb)) @@ -1008,9 +1016,11 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) } dr = &port->vio.drings[VIO_DRIVER_TX_RING]; + i = skb_get_queue_mapping(skb); + txq = netdev_get_tx_queue(dev, i); if (unlikely(vnet_tx_dring_avail(dr) < 1)) { - if (!netif_queue_stopped(dev)) { - netif_stop_queue(dev); + if (!netif_tx_queue_stopped(txq)) { + netif_tx_stop_queue(txq); /* This is a hard error, log it. */ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); @@ -1104,9 +1114,9 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1); if (unlikely(vnet_tx_dring_avail(dr) < 1)) { - netif_stop_queue(dev); + netif_tx_stop_queue(txq); if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr)) - netif_wake_queue(dev); + netif_tx_wake_queue(txq); } (void)mod_timer(&port->clean_timer, jiffies + VNET_CLEAN_TIMEOUT); @@ -1139,14 +1149,14 @@ static void vnet_tx_timeout(struct net_device *dev) static int vnet_open(struct net_device *dev) { netif_carrier_on(dev); - netif_start_queue(dev); + netif_tx_start_all_queues(dev); return 0; } static int vnet_close(struct net_device *dev) { - netif_stop_queue(dev); + netif_tx_stop_all_queues(dev); netif_carrier_off(dev); return 0; @@ -1420,6 +1430,7 @@ static const struct net_device_ops vnet_ops = { .ndo_tx_timeout = vnet_tx_timeout, .ndo_change_mtu = vnet_change_mtu, .ndo_start_xmit = vnet_start_xmit, + .ndo_select_queue = vnet_select_queue, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = vnet_poll_controller, #endif @@ -1431,7 +1442,7 @@ static struct vnet *vnet_new(const u64 *local_mac) struct vnet *vp; int err, i; - dev = alloc_etherdev(sizeof(*vp)); + dev = alloc_etherdev_mqs(sizeof(*vp), VNET_MAX_TXQS, 1); if (!dev) return ERR_PTR(-ENOMEM); dev->needed_headroom = VNET_PACKET_SKIP + 8; @@ -1556,6 +1567,25 @@ static void print_version(void) const char *remote_macaddr_prop = "remote-mac-address"; +static void +vnet_port_add_txq(struct vnet_port *port) +{ + struct vnet *vp = port->vp; + int n; + + n = vp->nports++; + n = n & (VNET_MAX_TXQS - 1); + port->q_index = n; + netif_tx_wake_queue(netdev_get_tx_queue(vp->dev, port->q_index)); +} + +static void +vnet_port_rm_txq(struct vnet_port *port) +{ + port->vp->nports--; + netif_tx_stop_queue(netdev_get_tx_queue(port->vp->dev, port->q_index)); +} + static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) { struct mdesc_handle *hp; @@ -1624,6 +1654,7 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) list_add_tail_rcu(&port->list, &vp->port_list); hlist_add_head_rcu(&port->hash, &vp->port_hash[vnet_hashfn(port->raddr)]); + vnet_port_add_txq(port); spin_unlock_irqrestore(&vp->lock, flags); dev_set_drvdata(&vdev->dev, port); @@ -1668,6 +1699,7 @@ static int vnet_port_remove(struct vio_dev *vdev) synchronize_rcu(); del_timer_sync(&port->clean_timer); + vnet_port_rm_txq(port); netif_napi_del(&port->napi); vnet_port_free_tx_bufs(port); vio_ldc_free(&port->vio); diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h index c8a862e471dd..cd5d343ea232 100644 --- a/drivers/net/ethernet/sun/sunvnet.h +++ b/drivers/net/ethernet/sun/sunvnet.h @@ -61,6 +61,7 @@ struct vnet_port { u32 napi_stop_idx; bool napi_resume; int rx_event; + u16 q_index; }; static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio) @@ -102,6 +103,7 @@ struct vnet { struct list_head list; u64 local_mac; + int nports; }; #endif /* _SUNVNET_H */ -- GitLab From 4eb2e164872a086f42fb9fe5dfe93856ad740932 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:23:09 +0100 Subject: [PATCH 2316/9457] ath10k: avoid possible deadlock with scan timeout This should prevent deadlock predicted by the following splat: ====================================================== [ INFO: possible circular locking dependency detected ] 3.17.0-wl-ath+ #67 Not tainted ------------------------------------------------------- kworker/u32:1/7230 is trying to acquire lock: (&ar->conf_mutex){+.+.+.}, at: [] ath10k_scan_timeout_work+0x2d/0x50 [ath10k_core] but task is already holding lock: ((&(&ar->scan.timeout)->work)){+.+...}, at: [] process_one_work+0x151/0x470 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 ((&(&ar->scan.timeout)->work)){+.+...}: [] lock_acquire+0x85/0x100 [] flush_work+0x3d/0x270 [] __cancel_work_timer+0x7d/0x110 [] cancel_delayed_work_sync+0x13/0x20 [] ath10k_cancel_remain_on_channel+0x36/0x60 [ath10k_core] [] ieee80211_cancel_roc+0x1cc/0x2f0 [mac80211] [] ieee80211_mgmt_tx_cancel_wait+0x22/0x30 [mac80211] [] nl80211_tx_mgmt_cancel_wait+0xa8/0x130 [cfg80211] [] genl_family_rcv_msg+0x1a5/0x3c0 [] genl_rcv_msg+0x89/0xc0 [] netlink_rcv_skb+0xb1/0xc0 [] genl_rcv+0x2c/0x40 [] netlink_unicast+0x18d/0x200 [] netlink_sendmsg+0x31d/0x430 [] sock_sendmsg+0x9c/0xd0 [] ___sys_sendmsg+0x389/0x3a0 [] __sys_sendmsg+0x49/0x90 [] SyS_sendmsg+0x12/0x20 [] system_call_fastpath+0x1a/0x1f -> #0 (&ar->conf_mutex){+.+.+.}: [] __lock_acquire+0x1b6e/0x1ce0 [] lock_acquire+0x85/0x100 [] mutex_lock_nested+0x4b/0x370 [] ath10k_scan_timeout_work+0x2d/0x50 [ath10k_core] [] process_one_work+0x1b1/0x470 [] worker_thread+0x123/0x460 [] kthread+0xe4/0x100 [] ret_from_fork+0x7c/0xb0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock((&(&ar->scan.timeout)->work)); lock(&ar->conf_mutex); lock((&(&ar->scan.timeout)->work)); lock(&ar->conf_mutex); *** DEADLOCK *** Reported-by: Marek Puzyniak Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 4f150ef84ea3..a7e55efaeb2d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3307,9 +3307,10 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; mutex_lock(&ar->conf_mutex); - cancel_delayed_work_sync(&ar->scan.timeout); ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); + + cancel_delayed_work_sync(&ar->scan.timeout); } static void ath10k_set_key_h_def_keyidx(struct ath10k *ar, @@ -3826,10 +3827,11 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) struct ath10k *ar = hw->priv; mutex_lock(&ar->conf_mutex); - cancel_delayed_work_sync(&ar->scan.timeout); ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); + cancel_delayed_work_sync(&ar->scan.timeout); + return 0; } -- GitLab From 099ac7ce2e23cc19382afbd3c192f2c6925851b9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:32:05 +0100 Subject: [PATCH 2317/9457] ath10k: change ce ring cleanup logic Make ath10k_pci_init_pipes() effectively only alter shared target-host data. The per_transfer_context is a host-only thing. It is necessary to preserve it's contents for a more robust ring cleanup. This is required for future warm reset fixes. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 6 -- drivers/net/wireless/ath/ath10k/pci.c | 82 +++++++++++++++------------ 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 9b89ac133946..878e1ec775da 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -835,9 +835,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, nentries = roundup_pow_of_two(attr->src_nentries); - memset(src_ring->per_transfer_context, 0, - nentries * sizeof(*src_ring->per_transfer_context)); - src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index &= src_ring->nentries_mask; src_ring->hw_index = src_ring->sw_index; @@ -872,9 +869,6 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, nentries = roundup_pow_of_two(attr->dest_nentries); - memset(dest_ring->per_transfer_context, 0, - nentries * sizeof(*dest_ring->per_transfer_context)); - dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 4a4740b4bdc0..a8a3e1bcf2d5 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1196,64 +1196,74 @@ static int ath10k_pci_hif_start(struct ath10k *ar) return 0; } -static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) +static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) { struct ath10k *ar; - struct ath10k_pci *ar_pci; - struct ath10k_ce_pipe *ce_hdl; - u32 buf_sz; - struct sk_buff *netbuf; - u32 ce_data; + struct ath10k_ce_pipe *ce_pipe; + struct ath10k_ce_ring *ce_ring; + struct sk_buff *skb; + int i; - buf_sz = pipe_info->buf_sz; + ar = pci_pipe->hif_ce_state; + ce_pipe = pci_pipe->ce_hdl; + ce_ring = ce_pipe->dest_ring; - /* Unused Copy Engine */ - if (buf_sz == 0) + if (!ce_ring) return; - ar = pipe_info->hif_ce_state; - ar_pci = ath10k_pci_priv(ar); - ce_hdl = pipe_info->ce_hdl; + if (!pci_pipe->buf_sz) + return; - while (ath10k_ce_revoke_recv_next(ce_hdl, (void **)&netbuf, - &ce_data) == 0) { - dma_unmap_single(ar->dev, ATH10K_SKB_CB(netbuf)->paddr, - netbuf->len + skb_tailroom(netbuf), + for (i = 0; i < ce_ring->nentries; i++) { + skb = ce_ring->per_transfer_context[i]; + if (!skb) + continue; + + ce_ring->per_transfer_context[i] = NULL; + + dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, + skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); - dev_kfree_skb_any(netbuf); + dev_kfree_skb_any(skb); } } -static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) +static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) { struct ath10k *ar; struct ath10k_pci *ar_pci; - struct ath10k_ce_pipe *ce_hdl; - struct sk_buff *netbuf; - u32 ce_data; - unsigned int nbytes; + struct ath10k_ce_pipe *ce_pipe; + struct ath10k_ce_ring *ce_ring; + struct ce_desc *ce_desc; + struct sk_buff *skb; unsigned int id; - u32 buf_sz; + int i; - buf_sz = pipe_info->buf_sz; + ar = pci_pipe->hif_ce_state; + ar_pci = ath10k_pci_priv(ar); + ce_pipe = pci_pipe->ce_hdl; + ce_ring = ce_pipe->src_ring; - /* Unused Copy Engine */ - if (buf_sz == 0) + if (!ce_ring) return; - ar = pipe_info->hif_ce_state; - ar_pci = ath10k_pci_priv(ar); - ce_hdl = pipe_info->ce_hdl; + if (!pci_pipe->buf_sz) + return; - while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf, - &ce_data, &nbytes, &id) == 0) { - /* no need to call tx completion for NULL pointers */ - if (!netbuf) + ce_desc = ce_ring->shadow_base; + if (WARN_ON(!ce_desc)) + return; + + for (i = 0; i < ce_ring->nentries; i++) { + skb = ce_ring->per_transfer_context[i]; + if (!skb) continue; - ar_pci->msg_callbacks_current.tx_completion(ar, - netbuf, - id); + ce_ring->per_transfer_context[i] = NULL; + id = MS(__le16_to_cpu(ce_desc[i].flags), + CE_DESC_FLAGS_META_DATA); + + ar_pci->msg_callbacks_current.tx_completion(ar, skb, id); } } -- GitLab From 61c1648bd7478a9c73d37dedc91b37cccde69176 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:32:06 +0100 Subject: [PATCH 2318/9457] ath10k: make warm reset a bit safer and faster One of the problems with warm reset I've found is that it must be guaranteed that copy engine registers are not being accessed while being reset. Otherwise in worst case scenario the host may lock up. Instead of using sleeps and hoping the device is operational in some arbitrary timeframes use firmware indication register. As a side effect this makes driver boot/stop/recovery faster. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 110 +++++++++++--------------- 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index a8a3e1bcf2d5..af36730e95df 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1717,89 +1717,75 @@ static void ath10k_pci_warm_reset_si0(struct ath10k *ar) msleep(10); } -static int ath10k_pci_warm_reset(struct ath10k *ar) +static void ath10k_pci_warm_reset_cpu(struct ath10k *ar) { u32 val; - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset\n"); - - spin_lock_bh(&ar->data_lock); - - ar->stats.fw_warm_reset_counter++; - - spin_unlock_bh(&ar->data_lock); - - /* debug */ - val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - PCIE_INTR_CAUSE_ADDRESS); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", - val); - - val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - CPU_INTR_ADDRESS); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", - val); - - /* disable pending irqs */ - ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + - PCIE_INTR_ENABLE_ADDRESS, 0); - - ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + - PCIE_INTR_CLR_ADDRESS, ~0); - - msleep(100); - - /* clear fw indicator */ ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0); - /* clear target LF timer interrupts */ val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + - SOC_LF_TIMER_CONTROL0_ADDRESS); - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + - SOC_LF_TIMER_CONTROL0_ADDRESS, - val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); + SOC_RESET_CONTROL_ADDRESS); + ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, + val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); +} + +static void ath10k_pci_warm_reset_ce(struct ath10k *ar) +{ + u32 val; - /* reset CE */ val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS); + ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, val | SOC_RESET_CONTROL_CE_RST_MASK); - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + - SOC_RESET_CONTROL_ADDRESS); msleep(10); - - /* unreset CE */ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, val & ~SOC_RESET_CONTROL_CE_RST_MASK); +} + +static void ath10k_pci_warm_reset_clear_lf(struct ath10k *ar) +{ + u32 val; + val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + - SOC_RESET_CONTROL_ADDRESS); - msleep(10); + SOC_LF_TIMER_CONTROL0_ADDRESS); + ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + + SOC_LF_TIMER_CONTROL0_ADDRESS, + val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); +} - ath10k_pci_warm_reset_si0(ar); +static int ath10k_pci_warm_reset(struct ath10k *ar) +{ + int ret; + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset\n"); - /* debug */ - val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - PCIE_INTR_CAUSE_ADDRESS); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", - val); + spin_lock_bh(&ar->data_lock); + ar->stats.fw_warm_reset_counter++; + spin_unlock_bh(&ar->data_lock); - val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - CPU_INTR_ADDRESS); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", - val); + ath10k_pci_irq_disable(ar); - /* CPU warm reset */ - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + - SOC_RESET_CONTROL_ADDRESS); - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, - val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); + /* Make sure the target CPU is not doing anything dangerous, e.g. if it + * were to access copy engine while host performs copy engine reset + * then it is possible for the device to confuse pci-e controller to + * the point of bringing host system to a complete stop (i.e. hang). + */ + ath10k_pci_warm_reset_si0(ar); + ath10k_pci_warm_reset_cpu(ar); + ath10k_pci_init_pipes(ar); + ath10k_pci_wait_for_target_init(ar); - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + - SOC_RESET_CONTROL_ADDRESS); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target reset state: 0x%08x\n", - val); + ath10k_pci_warm_reset_clear_lf(ar); + ath10k_pci_warm_reset_ce(ar); + ath10k_pci_warm_reset_cpu(ar); + ath10k_pci_init_pipes(ar); - msleep(100); + ret = ath10k_pci_wait_for_target_init(ar); + if (ret) { + ath10k_warn(ar, "failed to wait for target init: %d\n", ret); + return ret; + } ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset complete\n"); -- GitLab From 0bc14d061bd8836eeff956cfbbcb53266af793ef Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:32:07 +0100 Subject: [PATCH 2319/9457] ath10k: split reset logic from power up The power up procedure was overly complex due to warm/cold reset workarounds and issues. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 151 ++++++++++++++------------ 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index af36730e95df..117e14d27c62 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1792,10 +1792,86 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) return 0; } -static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) +static int ath10k_pci_chip_reset(struct ath10k *ar) +{ + int i, ret; + u32 val; + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset\n"); + + /* Some hardware revisions (e.g. CUS223v2) has issues with cold reset. + * It is thus preferred to use warm reset which is safer but may not be + * able to recover the device from all possible fail scenarios. + * + * Warm reset doesn't always work on first try so attempt it a few + * times before giving up. + */ + for (i = 0; i < ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS; i++) { + ret = ath10k_pci_warm_reset(ar); + if (ret) { + ath10k_warn(ar, "failed to warm reset attempt %d of %d: %d\n", + i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, + ret); + continue; + } + + /* FIXME: Sometimes copy engine doesn't recover after warm + * reset. In most cases this needs cold reset. In some of these + * cases the device is in such a state that a cold reset may + * lock up the host. + * + * Reading any host interest register via copy engine is + * sufficient to verify if device is capable of booting + * firmware blob. + */ + ret = ath10k_pci_init_pipes(ar); + if (ret) { + ath10k_warn(ar, "failed to init copy engine: %d\n", + ret); + continue; + } + + ret = ath10k_pci_diag_read32(ar, QCA988X_HOST_INTEREST_ADDRESS, + &val); + if (ret) { + ath10k_warn(ar, "failed to poke copy engine: %d\n", + ret); + continue; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset complete (warm)\n"); + return 0; + } + + if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) { + ath10k_warn(ar, "refusing cold reset as requested\n"); + return -EPERM; + } + + ret = ath10k_pci_cold_reset(ar); + if (ret) { + ath10k_warn(ar, "failed to cold reset: %d\n", ret); + return ret; + } + + ret = ath10k_pci_wait_for_target_init(ar); + if (ret) { + ath10k_warn(ar, "failed to wait for target after cold reset: %d\n", + ret); + return ret; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset complete (cold)\n"); + + return 0; +} + +static int ath10k_pci_hif_power_up(struct ath10k *ar) { int ret; + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); + /* * Bring the target up cleanly. * @@ -1806,13 +1882,9 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) * is in an unexpected state. We try to catch that here in order to * reset the Target and retry the probe. */ - if (cold_reset) - ret = ath10k_pci_cold_reset(ar); - else - ret = ath10k_pci_warm_reset(ar); - + ret = ath10k_pci_chip_reset(ar); if (ret) { - ath10k_err(ar, "failed to reset target: %d\n", ret); + ath10k_err(ar, "failed to reset chip: %d\n", ret); goto err; } @@ -1822,12 +1894,6 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) goto err; } - ret = ath10k_pci_wait_for_target_init(ar); - if (ret) { - ath10k_err(ar, "failed to wait for target to init: %d\n", ret); - goto err_ce; - } - ret = ath10k_pci_init_config(ar); if (ret) { ath10k_err(ar, "failed to setup init config: %d\n", ret); @@ -1844,68 +1910,11 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) err_ce: ath10k_pci_ce_deinit(ar); - ath10k_pci_warm_reset(ar); -err: - return ret; -} - -static int ath10k_pci_hif_power_up_warm(struct ath10k *ar) -{ - int i, ret; - - /* - * Sometime warm reset succeeds after retries. - * - * FIXME: It might be possible to tune ath10k_pci_warm_reset() to work - * at first try. - */ - for (i = 0; i < ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS; i++) { - ret = __ath10k_pci_hif_power_up(ar, false); - if (ret == 0) - break; - - ath10k_warn(ar, "failed to warm reset (attempt %d out of %d): %d\n", - i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, ret); - } +err: return ret; } -static int ath10k_pci_hif_power_up(struct ath10k *ar) -{ - int ret; - - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); - - /* - * Hardware CUS232 version 2 has some issues with cold reset and the - * preferred (and safer) way to perform a device reset is through a - * warm reset. - * - * Warm reset doesn't always work though so fall back to cold reset may - * be necessary. - */ - ret = ath10k_pci_hif_power_up_warm(ar); - if (ret) { - ath10k_warn(ar, "failed to power up target using warm reset: %d\n", - ret); - - if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) - return ret; - - ath10k_warn(ar, "trying cold reset\n"); - - ret = __ath10k_pci_hif_power_up(ar, true); - if (ret) { - ath10k_err(ar, "failed to power up target using cold reset too (%d)\n", - ret); - return ret; - } - } - - return 0; -} - static void ath10k_pci_hif_power_down(struct ath10k *ar) { ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); -- GitLab From c011b281591bb21e4006200a1f51ec4f67b46a74 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:32:08 +0100 Subject: [PATCH 2320/9457] ath10k: don't reset chip on power_down Currently hif_power_up performs effectively a reset and hif_stop resets the chip as well so there's no point in resetting here. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 117e14d27c62..63f374ed6f6a 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1919,7 +1919,9 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar) { ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); - ath10k_pci_warm_reset(ar); + /* Currently hif_power_up performs effectively a reset and hif_stop + * resets the chip as well so there's no point in resetting here. + */ } #ifdef CONFIG_PM -- GitLab From 04ed9dfe499965b641b69575137af9f41a78e609 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:34:36 +0100 Subject: [PATCH 2321/9457] ath10k: fix possible bmi crash While testing other things I've found that CE items aren't cleared properly. This could lead to null dereferences in BMI. To prevent that make sure CE revoking clears the nbytes value (which is used as a buffer completion indication) and memset the entire CE ring data shared between host and target when (re)initializing. Also make sure to check BMI xfer pointer and print a splat instead of crashing the kernel. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 7 +++++++ drivers/net/wireless/ath/ath10k/pci.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 878e1ec775da..a156e6e48708 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -558,6 +558,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, /* sanity */ dest_ring->per_transfer_context[sw_index] = NULL; + desc->nbytes = 0; /* Update sw_index */ sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); @@ -835,6 +836,9 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, nentries = roundup_pow_of_two(attr->src_nentries); + memset(src_ring->base_addr_owner_space, 0, + nentries * sizeof(struct ce_desc)); + src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index &= src_ring->nentries_mask; src_ring->hw_index = src_ring->sw_index; @@ -869,6 +873,9 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, nentries = roundup_pow_of_two(attr->dest_nentries); + memset(dest_ring->base_addr_owner_space, 0, + nentries * sizeof(struct ce_desc)); + dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 63f374ed6f6a..f5e426ea2570 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1442,6 +1442,9 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) &nbytes, &transfer_id, &flags)) return; + if (WARN_ON_ONCE(!xfer)) + return; + if (!xfer->wait_for_resp) { ath10k_warn(ar, "unexpected: BMI data received; ignoring\n"); return; -- GitLab From 605cdba1c92308fc39b5e1a0f226c14a7769889a Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:34:37 +0100 Subject: [PATCH 2322/9457] ath10k: expose hw restart via debugfs Until now it was possible to simulate soft and hard fw crashes but it wasn't possible to trigger an immediately hw restart itself (without the fw crash). This can be useful when stress testing hw restarting stability, e.g. during heavy tx/rx traffic. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 9147dd36dcdd..a8f5a72ba259 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -695,7 +695,8 @@ static ssize_t ath10k_read_simulate_fw_crash(struct file *file, "To simulate firmware crash write one of the keywords to this file:\n" "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n" "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n" - "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n"; + "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n" + "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); } @@ -748,6 +749,10 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, } else if (!strcmp(buf, "assert")) { ath10k_info(ar, "simulating firmware assert crash\n"); ret = ath10k_debug_fw_assert(ar); + } else if (!strcmp(buf, "hw-restart")) { + ath10k_info(ar, "user requested hw restart\n"); + queue_work(ar->workqueue, &ar->restart_work); + ret = 0; } else { ret = -EINVAL; goto exit; -- GitLab From 7962b0d898accdc683955af495528d4d6d24e0b3 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 28 Oct 2014 10:34:38 +0100 Subject: [PATCH 2323/9457] ath10k: speed up hw recovery In some cases hw recovery was taking an absurdly long time due to ath10k waiting for things that would never really complete. Instead of waiting for inevitable timeouts poke all completions and wakequeues and check if it's still worth waiting. Reading/writing ar->state requires conf_mutex. Since waiters might be holding it introduce a new flag CRASH_FLUSH so it's possible to tell waiters to abort whatever they were waiting for. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 23 +++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/core.h | 5 +++++ drivers/net/wireless/ath/ath10k/htt_tx.c | 1 - drivers/net/wireless/ath/ath10k/mac.c | 14 ++++++++++++-- drivers/net/wireless/ath/ath10k/mac.h | 1 + drivers/net/wireless/ath/ath10k/txrx.c | 3 ++- drivers/net/wireless/ath/ath10k/wmi.c | 5 ++++- 7 files changed, 47 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 5c23d00f7d60..6f2c459160f0 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -744,6 +744,25 @@ static void ath10k_core_restart(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, restart_work); + set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); + + /* Place a barrier to make sure the compiler doesn't reorder + * CRASH_FLUSH and calling other functions. + */ + barrier(); + + ieee80211_stop_queues(ar->hw); + ath10k_drain_tx(ar); + complete_all(&ar->scan.started); + complete_all(&ar->scan.completed); + complete_all(&ar->scan.on_channel); + complete_all(&ar->offchan_tx_completed); + complete_all(&ar->install_key_done); + complete_all(&ar->vdev_setup_done); + wake_up(&ar->htt.empty_tx_wq); + wake_up(&ar->wmi.tx_credits_wq); + wake_up(&ar->peer_mapping_wq); + mutex_lock(&ar->conf_mutex); switch (ar->state) { @@ -781,6 +800,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) lockdep_assert_held(&ar->conf_mutex); + clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); + ath10k_bmi_start(ar); if (ath10k_init_configure_target(ar)) { @@ -1185,6 +1206,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, INIT_LIST_HEAD(&ar->peers); init_waitqueue_head(&ar->peer_mapping_wq); + init_waitqueue_head(&ar->htt.empty_tx_wq); + init_waitqueue_head(&ar->wmi.tx_credits_wq); init_completion(&ar->offchan_tx_completed); INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 1e3fd1013b70..114bac029f05 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -386,6 +386,11 @@ enum ath10k_dev_flags { /* Indicates that ath10k device is during CAC phase of DFS */ ATH10K_CAC_RUNNING, ATH10K_FLAG_CORE_REGISTERED, + + /* Device has crashed and needs to restart. This indicates any pending + * waiters should immediately cancel instead of waiting for a time out. + */ + ATH10K_FLAG_CRASH_FLUSH, }; enum ath10k_cal_mode { diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index b0df470250a2..1702c97b5ca5 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -92,7 +92,6 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt) struct ath10k *ar = htt->ar; spin_lock_init(&htt->tx_lock); - init_waitqueue_head(&htt->empty_tx_wq); if (test_bit(ATH10K_FW_FEATURE_WMI_10X, htt->ar->fw_features)) htt->max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a7e55efaeb2d..9e4748fbcf8a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -519,6 +519,9 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) lockdep_assert_held(&ar->conf_mutex); + if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) + return -ESHUTDOWN; + ret = wait_for_completion_timeout(&ar->vdev_setup_done, ATH10K_VDEV_SETUP_TIMEOUT_HZ); if (ret == 0) @@ -551,6 +554,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) arg.channel.max_reg_power = channel->max_reg_power * 2; arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; + reinit_completion(&ar->vdev_setup_done); + ret = ath10k_wmi_vdev_start(ar, &arg); if (ret) { ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n", @@ -598,6 +603,8 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar) ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n", ar->monitor_vdev_id, ret); + reinit_completion(&ar->vdev_setup_done); + ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); if (ret) ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n", @@ -2350,7 +2357,7 @@ static void ath10k_tx(struct ieee80211_hw *hw, } /* Must not be called with conf_mutex held as workers can use that also. */ -static void ath10k_drain_tx(struct ath10k *ar) +void ath10k_drain_tx(struct ath10k *ar) { /* make sure rcu-protected mac80211 tx path itself is drained */ synchronize_net(); @@ -3910,7 +3917,9 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, empty = (ar->htt.num_pending_tx == 0); spin_unlock_bh(&ar->htt.tx_lock); - skip = (ar->state == ATH10K_STATE_WEDGED); + skip = (ar->state == ATH10K_STATE_WEDGED) || + test_bit(ATH10K_FLAG_CRASH_FLUSH, + &ar->dev_flags); (empty || skip); }), ATH10K_FLUSH_TIMEOUT_HZ); @@ -4007,6 +4016,7 @@ static void ath10k_restart_complete(struct ieee80211_hw *hw) if (ar->state == ATH10K_STATE_RESTARTED) { ath10k_info(ar, "device successfully recovered\n"); ar->state = ATH10K_STATE_ON; + ieee80211_wake_queues(ar->hw); } mutex_unlock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index 965c51117499..4e3c989aa841 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -40,6 +40,7 @@ void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_halt(struct ath10k *ar); void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif); +void ath10k_drain_tx(struct ath10k *ar); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index f9c90e37bc7c..7579de8e7a8c 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -146,7 +146,8 @@ static int ath10k_wait_for_peer_common(struct ath10k *ar, int vdev_id, mapped = !!ath10k_peer_find(ar, vdev_id, addr); spin_unlock_bh(&ar->data_lock); - mapped == expect_mapped; + (mapped == expect_mapped || + test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)); }), 3*HZ); if (ret <= 0) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ae746cece211..5592844ce54b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -779,6 +779,10 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id) ath10k_wmi_tx_beacons_nowait(ar); ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id); + + if (ret && test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) + ret = -ESHUTDOWN; + (ret != -EAGAIN); }), 3*HZ); @@ -4398,7 +4402,6 @@ int ath10k_wmi_attach(struct ath10k *ar) init_completion(&ar->wmi.service_ready); init_completion(&ar->wmi.unified_ready); - init_waitqueue_head(&ar->wmi.tx_credits_wq); return 0; } -- GitLab From d070f9137af960abd78525440684421fd5e0c0e7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 29 Oct 2014 22:55:58 -0700 Subject: [PATCH 2324/9457] mac80211: fix spelling errors Use codespell to find spelling errors. Signed-off-by: Stephen Hemminger Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 2 +- net/mac80211/chan.c | 2 +- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/rc80211_minstrel.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d6b01ad2f7d7..fbcc209687c8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -191,7 +191,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, * receive the key. When wpa_supplicant has roamed * using FT, it attempts to set the key before * association has completed, this rejects that attempt - * so it will set the key again after assocation. + * so it will set the key again after association. * * TODO: accept the key if we have a station entry and * add it to the device after the station. diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 4c74e8da64b9..ee71bb6f64f7 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1634,7 +1634,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, } break; case IEEE80211_CHANCTX_WILL_BE_REPLACED: - /* TODO: Perhaps the bandwith change could be treated as a + /* TODO: Perhaps the bandwidth change could be treated as a * reservation itself? */ ret = -EBUSY; goto out; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 146a818e52b5..eb425298fe69 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -131,7 +131,7 @@ enum ieee80211_bss_corrupt_data_flags { * * These are bss flags that are attached to a bss in the * @valid_data field of &struct ieee80211_bss. They show which parts - * of the data structure were recieved as a result of an un-corrupted + * of the data structure were received as a result of an un-corrupted * beacon/probe response. */ enum ieee80211_bss_valid_data_flags { diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 2baa7ed8789d..c2b91bf47f6d 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -191,7 +191,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) * (1) if any success probabilitiy >= 95%, out of those rates * choose the maximum throughput rate as max_prob_rate * (2) if all success probabilities < 95%, the rate with - * highest success probability is choosen as max_prob_rate */ + * highest success probability is chosen as max_prob_rate */ if (mrs->probability >= MINSTREL_FRAC(95, 100)) { if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) tmp_prob_rate = i; -- GitLab From 5bb5428956d3eecb428e72e7f521ff6ac767384b Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 28 Oct 2014 12:07:05 +0530 Subject: [PATCH 2325/9457] gpio: gpio-davinci: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-davinci.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 9f0682534e2f..3faf5f944ccc 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -234,11 +234,6 @@ static int davinci_gpio_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "Invalid memory resource\n"); - return -EBUSY; - } - gpio_base = devm_ioremap_resource(dev, res); if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); -- GitLab From de29eda892ce9d5a3b11d5467b30de140f251573 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 31 Oct 2014 09:25:43 +0100 Subject: [PATCH 2326/9457] mac80211-hwsim: add missing policy entries A few recent additions to the netlink attributes neglected to add policy entries, fix that now. Reported-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index a24b7f5aea9f..5dbaee36c607 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -508,6 +508,9 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG }, [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG }, [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG }, + [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING }, + [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG }, + [HWSIM_ATTR_FREQ] = { .type = NLA_U32 }, }; static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, -- GitLab From 0c23e2af6792d7b71d79dd4052c5c93512c5c84d Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Mon, 22 Sep 2014 10:17:01 +0530 Subject: [PATCH 2327/9457] clk: samsung: add support for 145xx and 1460x PLLs PLL145xx is similar to PLL35xx and PLL1460x is almost similar to PLL46xx with minor differences in bit positions. Hence, reuse the functions defined for pll_35xx and pll_46xx to support 145xx and 1460x PLLs respectively. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-pll.c | 25 ++++++++++++++++++++----- drivers/clk/samsung/clk-pll.h | 4 ++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index b07fad2a9167..9d70e5c03804 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -482,6 +482,8 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = { #define PLL46XX_VSEL_MASK (1) #define PLL46XX_MDIV_MASK (0x1FF) +#define PLL1460X_MDIV_MASK (0x3FF) + #define PLL46XX_PDIV_MASK (0x3F) #define PLL46XX_SDIV_MASK (0x7) #define PLL46XX_VSEL_SHIFT (27) @@ -511,13 +513,15 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, pll_con0 = __raw_readl(pll->con_reg); pll_con1 = __raw_readl(pll->con_reg + 4); - mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; + mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ? + PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK); pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : pll_con1 & PLL46XX_KDIV_MASK; - shift = pll->type == pll_4600 ? 16 : 10; + shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10; + fvco *= (mdiv << shift) + kdiv; do_div(fvco, (pdiv << sdiv)); fvco >>= shift; @@ -573,14 +577,21 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, lock = 0xffff; /* Set PLL PMS and VSEL values. */ - con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | + if (pll->type == pll_1460x) { + con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) | + (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | + (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT)); + } else { + con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) | (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) | (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) | (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT)); + con0 |= rate->vsel << PLL46XX_VSEL_SHIFT; + } + con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) | (rate->pdiv << PLL46XX_PDIV_SHIFT) | - (rate->sdiv << PLL46XX_SDIV_SHIFT) | - (rate->vsel << PLL46XX_VSEL_SHIFT); + (rate->sdiv << PLL46XX_SDIV_SHIFT); /* Set PLL K, MFR and MRR values. */ con1 = __raw_readl(pll->con_reg + 0x4); @@ -1190,6 +1201,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, /* clk_ops for 35xx and 2550 are similar */ case pll_35xx: case pll_2550: + case pll_1450x: + case pll_1451x: + case pll_1452x: if (!pll->rate_table) init.ops = &samsung_pll35xx_clk_min_ops; else @@ -1223,6 +1237,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_4600: case pll_4650: case pll_4650c: + case pll_1460x: if (!pll->rate_table) init.ops = &samsung_pll46xx_clk_min_ops; else diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index c0ed4d41fd90..213de9af8b4f 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -33,6 +33,10 @@ enum samsung_pll_type { pll_s3c2440_mpll, pll_2550xx, pll_2650xx, + pll_1450x, + pll_1451x, + pll_1452x, + pll_1460x, }; #define PLL_35XX_RATE(_rate, _m, _p, _s) \ -- GitLab From 16a9013b83b5106c83cf3caf9ba0d94e54dbebba Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Mon, 22 Sep 2014 10:17:02 +0530 Subject: [PATCH 2328/9457] clk: samsung: Factor out the common code to clk.c While adding clock support for Exynos5260, the infrastructure to register multiple clock controllers was introduced. Factor out the support for registering multiple clock controller from Exynos5260 clock code to common samsung clock code so that it can be used by other Exynos SoC which have multiple clock controllers. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5260.c | 185 ++++----------------------- drivers/clk/samsung/clk.c | 95 ++++++++++++++ drivers/clk/samsung/clk.h | 34 +++++ 3 files changed, 155 insertions(+), 159 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index 2527e39aadcf..e2e5193d1049 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -11,10 +11,8 @@ #include #include -#include #include #include -#include #include "clk-exynos5260.h" #include "clk.h" @@ -22,39 +20,6 @@ #include -static LIST_HEAD(clock_reg_cache_list); - -struct exynos5260_clock_reg_cache { - struct list_head node; - void __iomem *reg_base; - struct samsung_clk_reg_dump *rdump; - unsigned int rd_num; -}; - -struct exynos5260_cmu_info { - /* list of pll clocks and respective count */ - struct samsung_pll_clock *pll_clks; - unsigned int nr_pll_clks; - /* list of mux clocks and respective count */ - struct samsung_mux_clock *mux_clks; - unsigned int nr_mux_clks; - /* list of div clocks and respective count */ - struct samsung_div_clock *div_clks; - unsigned int nr_div_clks; - /* list of gate clocks and respective count */ - struct samsung_gate_clock *gate_clks; - unsigned int nr_gate_clks; - /* list of fixed clocks and respective count */ - struct samsung_fixed_rate_clock *fixed_clks; - unsigned int nr_fixed_clks; - /* total number of clocks with IDs assigned*/ - unsigned int nr_clk_ids; - - /* list and number of clocks registers */ - unsigned long *clk_regs; - unsigned int nr_clk_regs; -}; - /* * Applicable for all 2550 Type PLLS for Exynos5260, listed below * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. @@ -113,104 +78,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { PLL_36XX_RATE(66000000, 176, 2, 5, 0), }; -#ifdef CONFIG_PM_SLEEP - -static int exynos5260_clk_suspend(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_save(cache->reg_base, cache->rdump, - cache->rd_num); - - return 0; -} - -static void exynos5260_clk_resume(void) -{ - struct exynos5260_clock_reg_cache *cache; - - list_for_each_entry(cache, &clock_reg_cache_list, node) - samsung_clk_restore(cache->reg_base, cache->rdump, - cache->rd_num); -} - -static struct syscore_ops exynos5260_clk_syscore_ops = { - .suspend = exynos5260_clk_suspend, - .resume = exynos5260_clk_resume, -}; - -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump) -{ - struct exynos5260_clock_reg_cache *reg_cache; - - reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), - GFP_KERNEL); - if (!reg_cache) - panic("could not allocate register cache.\n"); - - reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); - - if (!reg_cache->rdump) - panic("could not allocate register dump storage.\n"); - - if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&exynos5260_clk_syscore_ops); - - reg_cache->rd_num = nr_rdump; - reg_cache->reg_base = reg_base; - list_add_tail(®_cache->node, &clock_reg_cache_list); -} - -#else -static void exynos5260_clk_sleep_init(void __iomem *reg_base, - unsigned long *rdump, - unsigned long nr_rdump){} -#endif - -/* - * Common function which registers plls, muxes, dividers and gates - * for each CMU. It also add CMU register list to register cache. - */ - -void __init exynos5260_cmu_register_one(struct device_node *np, - struct exynos5260_cmu_info *cmu) -{ - void __iomem *reg_base; - struct samsung_clk_provider *ctx; - - reg_base = of_iomap(np, 0); - if (!reg_base) - panic("%s: failed to map registers\n", __func__); - - ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) - panic("%s: unable to alllocate ctx\n", __func__); - - if (cmu->pll_clks) - samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, - reg_base); - if (cmu->mux_clks) - samsung_clk_register_mux(ctx, cmu->mux_clks, - cmu->nr_mux_clks); - if (cmu->div_clks) - samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); - if (cmu->gate_clks) - samsung_clk_register_gate(ctx, cmu->gate_clks, - cmu->nr_gate_clks); - if (cmu->fixed_clks) - samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, - cmu->nr_fixed_clks); - if (cmu->clk_regs) - exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, - cmu->nr_clk_regs); - - samsung_clk_of_add_provider(np, ctx); -} - - /* CMU_AUD */ static unsigned long aud_clk_regs[] __initdata = { @@ -268,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = { static void __init exynos5260_clk_aud_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = aud_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); @@ -280,7 +147,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np) cmu.clk_regs = aud_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", @@ -458,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = { static void __init exynos5260_clk_disp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = disp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); @@ -470,7 +337,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np) cmu.clk_regs = disp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", @@ -522,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = { static void __init exynos5260_clk_egl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = egl_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); @@ -534,7 +401,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np) cmu.clk_regs = egl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", @@ -624,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = { static void __init exynos5260_clk_fsys_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = fsys_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); @@ -634,7 +501,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np) cmu.clk_regs = fsys_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", @@ -713,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = { static void __init exynos5260_clk_g2d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = g2d_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); @@ -725,7 +592,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np) cmu.clk_regs = g2d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", @@ -774,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = { static void __init exynos5260_clk_g3d_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = g3d_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); @@ -788,7 +655,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np) cmu.clk_regs = g3d_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", @@ -909,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = { static void __init exynos5260_clk_gscl_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = gscl_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); @@ -921,7 +788,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np) cmu.clk_regs = gscl_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", @@ -1028,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = { static void __init exynos5260_clk_isp_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = isp_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); @@ -1040,7 +907,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np) cmu.clk_regs = isp_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", @@ -1092,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = { static void __init exynos5260_clk_kfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = kfc_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); @@ -1104,7 +971,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np) cmu.clk_regs = kfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", @@ -1148,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = { static void __init exynos5260_clk_mfc_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = mfc_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); @@ -1160,7 +1027,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np) cmu.clk_regs = mfc_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", @@ -1295,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = { static void __init exynos5260_clk_mif_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = mif_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); @@ -1309,7 +1176,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np) cmu.clk_regs = mif_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", @@ -1503,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = { static void __init exynos5260_clk_peri_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.mux_clks = peri_mux_clks; cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); @@ -1515,7 +1382,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np) cmu.clk_regs = peri_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", @@ -1959,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = { static void __init exynos5260_clk_top_init(struct device_node *np) { - struct exynos5260_cmu_info cmu = {0}; + struct samsung_cmu_info cmu = {0}; cmu.pll_clks = top_pll_clks; cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); @@ -1975,7 +1842,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np) cmu.clk_regs = top_clk_regs; cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); - exynos5260_cmu_register_one(np, &cmu); + samsung_cmu_register_one(np, &cmu); } CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index deab84d9f37d..a64823627d3a 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -14,6 +14,8 @@ #include #include "clk.h" +static LIST_HEAD(clock_reg_cache_list); + void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -313,3 +315,96 @@ unsigned long _get_rate(const char *clk_name) return clk_get_rate(clk); } + +#ifdef CONFIG_PM_SLEEP +static int samsung_clk_suspend(void) +{ + struct samsung_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); + return 0; +} + +static void samsung_clk_resume(void) +{ + struct samsung_clock_reg_cache *reg_cache; + + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, + reg_cache->rd_num); +} + +static struct syscore_ops samsung_clk_syscore_ops = { + .suspend = samsung_clk_suspend, + .resume = samsung_clk_resume, +}; + +static void samsung_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) +{ + struct samsung_clock_reg_cache *reg_cache; + + reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache), + GFP_KERNEL); + if (!reg_cache) + panic("could not allocate register reg_cache.\n"); + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); + + if (!reg_cache->rdump) + panic("could not allocate register dump storage.\n"); + + if (list_empty(&clock_reg_cache_list)) + register_syscore_ops(&samsung_clk_syscore_ops); + + reg_cache->reg_base = reg_base; + reg_cache->rd_num = nr_rdump; + list_add_tail(®_cache->node, &clock_reg_cache_list); +} + +#else +static void samsung_clk_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump) {} +#endif + +/* + * Common function which registers plls, muxes, dividers and gates + * for each CMU. It also add CMU register list to register cache. + */ +void __init samsung_cmu_register_one(struct device_node *np, + struct samsung_cmu_info *cmu) +{ + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); + if (!ctx) + panic("%s: unable to alllocate ctx\n", __func__); + + if (cmu->pll_clks) + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, + reg_base); + if (cmu->mux_clks) + samsung_clk_register_mux(ctx, cmu->mux_clks, + cmu->nr_mux_clks); + if (cmu->div_clks) + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); + if (cmu->gate_clks) + samsung_clk_register_gate(ctx, cmu->gate_clks, + cmu->nr_gate_clks); + if (cmu->fixed_clks) + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, + cmu->nr_fixed_clks); + if (cmu->clk_regs) + samsung_clk_sleep_init(reg_base, cmu->clk_regs, + cmu->nr_clk_regs); + + samsung_clk_of_add_provider(np, ctx); +} diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 66ab36b5cef1..b3d0f4d97f97 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -324,6 +324,37 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) +struct samsung_clock_reg_cache { + struct list_head node; + void __iomem *reg_base; + struct samsung_clk_reg_dump *rdump; + unsigned int rd_num; +}; + +struct samsung_cmu_info { + /* list of pll clocks and respective count */ + struct samsung_pll_clock *pll_clks; + unsigned int nr_pll_clks; + /* list of mux clocks and respective count */ + struct samsung_mux_clock *mux_clks; + unsigned int nr_mux_clks; + /* list of div clocks and respective count */ + struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + /* list of gate clocks and respective count */ + struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + /* list of fixed clocks and respective count */ + struct samsung_fixed_rate_clock *fixed_clks; + unsigned int nr_fixed_clks; + /* total number of clocks with IDs assigned*/ + unsigned int nr_clk_ids; + + /* list and number of clocks registers */ + unsigned long *clk_regs; + unsigned int nr_clk_regs; +}; + extern struct samsung_clk_provider *__init samsung_clk_init( struct device_node *np, void __iomem *base, unsigned long nr_clks); @@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_list, unsigned int nr_clk, void __iomem *base); +extern void __init samsung_cmu_register_one(struct device_node *, + struct samsung_cmu_info *); + extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base, -- GitLab From 0e5af27008f947fe983004d502c3b2c1ddde1029 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Mon, 22 Sep 2014 10:17:03 +0530 Subject: [PATCH 2329/9457] clk: samsung: Add fixed_factor_clocks field to struct exynos_cmu_info Add the fields "fixed_factor_clks" and "nr_fixed_factor_clks" to "struct exynos_cmu_info" to allow registering of fixed factor clocks as well with exynos_cmu_register_one(). Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk.c | 3 +++ drivers/clk/samsung/clk.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index a64823627d3a..dd1f7c977b6b 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -402,6 +402,9 @@ void __init samsung_cmu_register_one(struct device_node *np, if (cmu->fixed_clks) samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, cmu->nr_fixed_clks); + if (cmu->fixed_factor_clks) + samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks, + cmu->nr_fixed_factor_clks); if (cmu->clk_regs) samsung_clk_sleep_init(reg_base, cmu->clk_regs, cmu->nr_clk_regs); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index b3d0f4d97f97..3f471e958cb0 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -347,6 +347,9 @@ struct samsung_cmu_info { /* list of fixed clocks and respective count */ struct samsung_fixed_rate_clock *fixed_clks; unsigned int nr_fixed_clks; + /* list of fixed factor clocks and respective count */ + struct samsung_fixed_factor_clock *fixed_factor_clks; + unsigned int nr_fixed_factor_clks; /* total number of clocks with IDs assigned*/ unsigned int nr_clk_ids; -- GitLab From 532abc3a4a4502e13315d246c545d7567c80b03e Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Mon, 22 Sep 2014 10:17:04 +0530 Subject: [PATCH 2330/9457] clk: samsung: add initial clock support for Exynos7 SoC Add initial clock support for Exynos7 SoC which is required to bring up platforms based on Exynos7. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos7-clock.txt | 67 +++ drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos7.c | 425 ++++++++++++++++++ include/dt-bindings/clock/exynos7-clk.h | 49 ++ 4 files changed, 542 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/exynos7-clock.txt create mode 100644 drivers/clk/samsung/clk-exynos7.c create mode 100644 include/dt-bindings/clock/exynos7-clk.h diff --git a/Documentation/devicetree/bindings/clock/exynos7-clock.txt b/Documentation/devicetree/bindings/clock/exynos7-clock.txt new file mode 100644 index 000000000000..789f76132a85 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/exynos7-clock.txt @@ -0,0 +1,67 @@ +* Samsung Exynos7 Clock Controller + +Exynos7 clock controller has various blocks which are instantiated +independently from the device-tree. These clock controllers +generate and supply clocks to various hardware blocks within +the SoC. + +Each clock is assigned an identifier and client nodes can use +this identifier to specify the clock which they consume. All +available clocks are defined as preprocessor macros in +dt-bindings/clock/exynos7-clk.h header and can be used in +device tree sources. + +External clocks: + +There are several clocks that are generated outside the SoC. It +is expected that they are defined using standard clock bindings +with following clock-output-names: + + - "fin_pll" - PLL input clock from XXTI + +Required Properties for Clock Controller: + + - compatible: clock controllers will use one of the following + compatible strings to indicate the clock controller + functionality. + + - "samsung,exynos7-clock-topc" + - "samsung,exynos7-clock-top0" + - "samsung,exynos7-clock-peric0" + - "samsung,exynos7-clock-peric1" + - "samsung,exynos7-clock-peris" + + - reg: physical base address of the controller and the length of + memory mapped region. + + - #clock-cells: should be 1. + + - clocks: list of clock identifiers which are fed as the input to + the given clock controller. Please refer the next section to + find the input clocks for a given controller. + +- clock-names: list of names of clocks which are fed as the input + to the given clock controller. + +Input clocks for top0 clock controller: + - fin_pll + - dout_sclk_bus0_pll + - dout_sclk_bus1_pll + - dout_sclk_cc_pll + - dout_sclk_mfc_pll + +Input clocks for peric0 clock controller: + - fin_pll + - dout_aclk_peric0_66 + - sclk_uart0 + +Input clocks for peric1 clock controller: + - fin_pll + - dout_aclk_peric1_66 + - sclk_uart1 + - sclk_uart2 + - sclk_uart3 + +Input clocks for peris clock controller: + - fin_pll + - dout_aclk_peris_66 diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index d8535e6df1db..006c6f294310 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o +obj-$(CONFIG_ARCH_EXYNOS7) += clk-exynos7.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c new file mode 100644 index 000000000000..54206d4d408a --- /dev/null +++ b/drivers/clk/samsung/clk-exynos7.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Naveen Krishna Ch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#include +#include +#include +#include + +#include "clk.h" +#include + +/* Register Offset definitions for CMU_TOPC (0x10570000) */ +#define CC_PLL_LOCK 0x0000 +#define BUS0_PLL_LOCK 0x0004 +#define BUS1_DPLL_LOCK 0x0008 +#define MFC_PLL_LOCK 0x000C +#define AUD_PLL_LOCK 0x0010 +#define CC_PLL_CON0 0x0100 +#define BUS0_PLL_CON0 0x0110 +#define BUS1_DPLL_CON0 0x0120 +#define MFC_PLL_CON0 0x0130 +#define AUD_PLL_CON0 0x0140 +#define MUX_SEL_TOPC0 0x0200 +#define MUX_SEL_TOPC1 0x0204 +#define MUX_SEL_TOPC3 0x020C +#define DIV_TOPC1 0x0604 +#define DIV_TOPC3 0x060C + +static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_bus0_pll_div4", + "ffac_topc_bus0_pll_div2", 1, 2, 0), + FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0), + FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0), +}; + +/* List of parent clocks for Muxes in CMU_TOPC */ +PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" }; +PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" }; +PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" }; +PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" }; + +PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc", + "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc", + "mout_sclk_mfc_pll_cmuc" }; + +PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl", + "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"}; +PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl", + "ffac_topc_bus1_pll_div2"}; +PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl", + "ffac_topc_cc_pll_div2"}; +PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl", + "ffac_topc_mfc_pll_div2"}; + + +PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl", + "ffac_topc_bus0_pll_div2"}; + +static unsigned long topc_clk_regs[] __initdata = { + CC_PLL_LOCK, + BUS0_PLL_LOCK, + BUS1_DPLL_LOCK, + MFC_PLL_LOCK, + AUD_PLL_LOCK, + CC_PLL_CON0, + BUS0_PLL_CON0, + BUS1_DPLL_CON0, + MFC_PLL_CON0, + AUD_PLL_CON0, + MUX_SEL_TOPC0, + MUX_SEL_TOPC1, + MUX_SEL_TOPC3, + DIV_TOPC1, + DIV_TOPC3, +}; + +static struct samsung_mux_clock topc_mux_clks[] __initdata = { + MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1), + MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1), + MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1), + MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1), + + MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p, + MUX_SEL_TOPC0, 16, 2), + MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p, + MUX_SEL_TOPC0, 20, 1), + MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p, + MUX_SEL_TOPC0, 24, 1), + MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p, + MUX_SEL_TOPC0, 28, 1), + + MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p, + MUX_SEL_TOPC1, 16, 1), + + MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2), +}; + +static struct samsung_div_clock topc_div_clks[] __initdata = { + DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", + DIV_TOPC1, 24, 4), + + DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out", + DIV_TOPC3, 0, 3), + DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl", + DIV_TOPC3, 8, 3), + DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl", + DIV_TOPC3, 12, 3), + DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl", + DIV_TOPC3, 16, 3), +}; + +static struct samsung_pll_clock topc_pll_clks[] __initdata = { + PLL(pll_1451x, 0, "fout_bus0_pll", "fin_pll", BUS0_PLL_LOCK, + BUS0_PLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_cc_pll", "fin_pll", CC_PLL_LOCK, + CC_PLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_bus1_pll", "fin_pll", BUS1_DPLL_LOCK, + BUS1_DPLL_CON0, NULL), + PLL(pll_1452x, 0, "fout_mfc_pll", "fin_pll", MFC_PLL_LOCK, + MFC_PLL_CON0, NULL), + PLL(pll_1460x, 0, "fout_aud_pll", "fin_pll", AUD_PLL_LOCK, + AUD_PLL_CON0, NULL), +}; + +static struct samsung_cmu_info topc_cmu_info __initdata = { + .pll_clks = topc_pll_clks, + .nr_pll_clks = ARRAY_SIZE(topc_pll_clks), + .mux_clks = topc_mux_clks, + .nr_mux_clks = ARRAY_SIZE(topc_mux_clks), + .div_clks = topc_div_clks, + .nr_div_clks = ARRAY_SIZE(topc_div_clks), + .fixed_factor_clks = topc_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(topc_fixed_factor_clks), + .nr_clk_ids = TOPC_NR_CLK, + .clk_regs = topc_clk_regs, + .nr_clk_regs = ARRAY_SIZE(topc_clk_regs), +}; + +static void __init exynos7_clk_topc_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &topc_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc", + exynos7_clk_topc_init); + +/* Register Offset definitions for CMU_TOP0 (0x105D0000) */ +#define MUX_SEL_TOP00 0x0200 +#define MUX_SEL_TOP01 0x0204 +#define MUX_SEL_TOP03 0x020C +#define MUX_SEL_TOP0_PERIC3 0x023C +#define DIV_TOP03 0x060C +#define DIV_TOP0_PERIC3 0x063C +#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C + +/* List of parent clocks for Muxes in CMU_TOP0 */ +PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; +PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" }; +PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" }; +PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" }; + +PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll", + "ffac_top0_bus0_pll_div2"}; +PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll", + "ffac_top0_bus1_pll_div2"}; +PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll", + "ffac_top0_cc_pll_div2"}; +PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll", + "ffac_top0_mfc_pll_div2"}; + +PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll", + "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll", + "mout_top0_half_mfc_pll"}; + +static unsigned long top0_clk_regs[] __initdata = { + MUX_SEL_TOP00, + MUX_SEL_TOP01, + MUX_SEL_TOP03, + MUX_SEL_TOP0_PERIC3, + DIV_TOP03, + DIV_TOP0_PERIC3, + ENABLE_SCLK_TOP0_PERIC3, +}; + +static struct samsung_mux_clock top0_mux_clks[] __initdata = { + MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1), + MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1), + MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1), + MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1), + + MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p, + MUX_SEL_TOP01, 4, 1), + MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p, + MUX_SEL_TOP01, 8, 1), + MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p, + MUX_SEL_TOP01, 12, 1), + MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p, + MUX_SEL_TOP01, 16, 1), + + MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2), + MUX(0, "mout_aclk_peric0_66", mout_top0_group1, MUX_SEL_TOP03, 20, 2), + + MUX(0, "mout_sclk_uart3", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 4, 2), + MUX(0, "mout_sclk_uart2", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 8, 2), + MUX(0, "mout_sclk_uart1", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 12, 2), + MUX(0, "mout_sclk_uart0", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 16, 2), +}; + +static struct samsung_div_clock top0_div_clks[] __initdata = { + DIV(DOUT_ACLK_PERIC1, "dout_aclk_peric1_66", "mout_aclk_peric1_66", + DIV_TOP03, 12, 6), + DIV(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66", + DIV_TOP03, 20, 6), + + DIV(0, "dout_sclk_uart3", "mout_sclk_uart3", DIV_TOP0_PERIC3, 4, 4), + DIV(0, "dout_sclk_uart2", "mout_sclk_uart2", DIV_TOP0_PERIC3, 8, 4), + DIV(0, "dout_sclk_uart1", "mout_sclk_uart1", DIV_TOP0_PERIC3, 12, 4), + DIV(0, "dout_sclk_uart0", "mout_sclk_uart0", DIV_TOP0_PERIC3, 16, 4), +}; + +static struct samsung_gate_clock top0_gate_clks[] __initdata = { + GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_sclk_uart3", + ENABLE_SCLK_TOP0_PERIC3, 4, 0, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_sclk_uart2", + ENABLE_SCLK_TOP0_PERIC3, 8, 0, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "dout_sclk_uart1", + ENABLE_SCLK_TOP0_PERIC3, 12, 0, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_sclk_uart0", + ENABLE_SCLK_TOP0_PERIC3, 16, 0, 0), +}; + +static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0), + FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0), +}; + +static struct samsung_cmu_info top0_cmu_info __initdata = { + .mux_clks = top0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top0_mux_clks), + .div_clks = top0_div_clks, + .nr_div_clks = ARRAY_SIZE(top0_div_clks), + .gate_clks = top0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top0_gate_clks), + .fixed_factor_clks = top0_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top0_fixed_factor_clks), + .nr_clk_ids = TOP0_NR_CLK, + .clk_regs = top0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top0_clk_regs), +}; + +static void __init exynos7_clk_top0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &top0_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0", + exynos7_clk_top0_init); + +/* Register Offset definitions for CMU_PERIC0 (0x13610000) */ +#define MUX_SEL_PERIC0 0x0200 +#define ENABLE_PCLK_PERIC0 0x0900 +#define ENABLE_SCLK_PERIC0 0x0A00 + +/* List of parent clocks for Muxes in CMU_PERIC0 */ +PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" }; +PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" }; + +static unsigned long peric0_clk_regs[] __initdata = { + MUX_SEL_PERIC0, + ENABLE_PCLK_PERIC0, + ENABLE_SCLK_PERIC0, +}; + +static struct samsung_mux_clock peric0_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p, + MUX_SEL_PERIC0, 0, 1), + MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p, + MUX_SEL_PERIC0, 16, 1), +}; + +static struct samsung_gate_clock peric0_gate_clks[] __initdata = { + GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 16, 0, 0), + + GATE(SCLK_UART0, "sclk_uart0_user", "mout_sclk_uart0_user", + ENABLE_SCLK_PERIC0, 16, 0, 0), +}; + +static struct samsung_cmu_info peric0_cmu_info __initdata = { + .mux_clks = peric0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks), + .gate_clks = peric0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric0_gate_clks), + .nr_clk_ids = PERIC0_NR_CLK, + .clk_regs = peric0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs), +}; + +static void __init exynos7_clk_peric0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peric0_cmu_info); +} + +/* Register Offset definitions for CMU_PERIC1 (0x14C80000) */ +#define MUX_SEL_PERIC10 0x0200 +#define MUX_SEL_PERIC11 0x0204 +#define ENABLE_PCLK_PERIC1 0x0900 +#define ENABLE_SCLK_PERIC10 0x0A00 + +CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0", + exynos7_clk_peric0_init); + +/* List of parent clocks for Muxes in CMU_PERIC1 */ +PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" }; +PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" }; +PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" }; +PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" }; + +static unsigned long peric1_clk_regs[] __initdata = { + MUX_SEL_PERIC10, + MUX_SEL_PERIC11, + ENABLE_PCLK_PERIC1, + ENABLE_SCLK_PERIC10, +}; + +static struct samsung_mux_clock peric1_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p, + MUX_SEL_PERIC10, 0, 1), + + MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p, + MUX_SEL_PERIC11, 20, 1), + MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p, + MUX_SEL_PERIC11, 24, 1), + MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p, + MUX_SEL_PERIC11, 28, 1), +}; + +static struct samsung_gate_clock peric1_gate_clks[] __initdata = { + GATE(PCLK_UART1, "pclk_uart1", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 9, 0, 0), + GATE(PCLK_UART2, "pclk_uart2", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 10, 0, 0), + GATE(PCLK_UART3, "pclk_uart3", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 11, 0, 0), + + GATE(SCLK_UART1, "sclk_uart1_user", "mout_sclk_uart1_user", + ENABLE_SCLK_PERIC10, 9, 0, 0), + GATE(SCLK_UART2, "sclk_uart2_user", "mout_sclk_uart2_user", + ENABLE_SCLK_PERIC10, 10, 0, 0), + GATE(SCLK_UART3, "sclk_uart3_user", "mout_sclk_uart3_user", + ENABLE_SCLK_PERIC10, 11, 0, 0), +}; + +static struct samsung_cmu_info peric1_cmu_info __initdata = { + .mux_clks = peric1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric1_mux_clks), + .gate_clks = peric1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric1_gate_clks), + .nr_clk_ids = PERIC1_NR_CLK, + .clk_regs = peric1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs), +}; + +static void __init exynos7_clk_peric1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peric1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1", + exynos7_clk_peric1_init); + +/* Register Offset definitions for CMU_PERIS (0x10040000) */ +#define MUX_SEL_PERIS 0x0200 +#define ENABLE_PCLK_PERIS_SECURE_CHIPID 0x0910 +#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 + +/* List of parent clocks for Muxes in CMU_PERIS */ +PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" }; + +static unsigned long peris_clk_regs[] __initdata = { + MUX_SEL_PERIS, + ENABLE_PCLK_PERIS_SECURE_CHIPID, + ENABLE_SCLK_PERIS_SECURE_CHIPID, +}; + +static struct samsung_mux_clock peris_mux_clks[] __initdata = { + MUX(0, "mout_aclk_peris_66_user", + mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1), +}; + +static struct samsung_gate_clock peris_gate_clks[] __initdata = { + GATE(PCLK_CHIPID, "pclk_chipid", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS_SECURE_CHIPID, 0, 0, 0), + GATE(SCLK_CHIPID, "sclk_chipid", "fin_pll", + ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0), +}; + +static struct samsung_cmu_info peris_cmu_info __initdata = { + .mux_clks = peris_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peris_mux_clks), + .gate_clks = peris_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peris_gate_clks), + .nr_clk_ids = PERIS_NR_CLK, + .clk_regs = peris_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peris_clk_regs), +}; + +static void __init exynos7_clk_peris_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &peris_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris", + exynos7_clk_peris_init); diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h new file mode 100644 index 000000000000..00fd6de1cb25 --- /dev/null +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Naveen Krishna Ch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _DT_BINDINGS_CLOCK_EXYNOS7_H +#define _DT_BINDINGS_CLOCK_EXYNOS7_H + +/* TOPC */ +#define DOUT_ACLK_PERIS 1 +#define DOUT_SCLK_BUS0_PLL 2 +#define DOUT_SCLK_BUS1_PLL 3 +#define DOUT_SCLK_CC_PLL 4 +#define DOUT_SCLK_MFC_PLL 5 +#define TOPC_NR_CLK 6 + +/* TOP0 */ +#define DOUT_ACLK_PERIC1 1 +#define DOUT_ACLK_PERIC0 2 +#define CLK_SCLK_UART0 3 +#define CLK_SCLK_UART1 4 +#define CLK_SCLK_UART2 5 +#define CLK_SCLK_UART3 6 +#define TOP0_NR_CLK 7 + +/* PERIC0 */ +#define PCLK_UART0 1 +#define SCLK_UART0 2 +#define PERIC0_NR_CLK 3 + +/* PERIC1 */ +#define PCLK_UART1 1 +#define PCLK_UART2 2 +#define PCLK_UART3 3 +#define SCLK_UART1 4 +#define SCLK_UART2 5 +#define SCLK_UART3 6 +#define PERIC1_NR_CLK 7 + +/* PERIS */ +#define PCLK_CHIPID 1 +#define SCLK_CHIPID 2 +#define PERIS_NR_CLK 3 + +#endif /* _DT_BINDINGS_CLOCK_EXYNOS7_H */ -- GitLab From 57a2b485fa512be47b479077b5f89e1bfe536709 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Tue, 21 Oct 2014 11:13:51 +0530 Subject: [PATCH 2331/9457] clk: samsung: exynos7: add clocks for I2C block Exynos7 supports 12 I2C channels, add the I2C gate clocks to support them. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos7.c | 24 ++++++++++++++++++++++++ include/dt-bindings/clock/exynos7-clk.h | 16 ++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 54206d4d408a..c700f654289e 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -290,6 +290,20 @@ static struct samsung_mux_clock peric0_mux_clks[] __initdata = { }; static struct samsung_gate_clock peric0_gate_clks[] __initdata = { + GATE(PCLK_HSI2C0, "pclk_hsi2c0", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 8, 0, 0), + GATE(PCLK_HSI2C1, "pclk_hsi2c1", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 9, 0, 0), + GATE(PCLK_HSI2C4, "pclk_hsi2c4", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 10, 0, 0), + GATE(PCLK_HSI2C5, "pclk_hsi2c5", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 11, 0, 0), + GATE(PCLK_HSI2C9, "pclk_hsi2c9", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 12, 0, 0), + GATE(PCLK_HSI2C10, "pclk_hsi2c10", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 13, 0, 0), + GATE(PCLK_HSI2C11, "pclk_hsi2c11", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 14, 0, 0), GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user", ENABLE_PCLK_PERIC0, 16, 0, 0), @@ -347,6 +361,16 @@ static struct samsung_mux_clock peric1_mux_clks[] __initdata = { }; static struct samsung_gate_clock peric1_gate_clks[] __initdata = { + GATE(PCLK_HSI2C2, "pclk_hsi2c2", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 4, 0, 0), + GATE(PCLK_HSI2C3, "pclk_hsi2c3", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 5, 0, 0), + GATE(PCLK_HSI2C6, "pclk_hsi2c6", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 6, 0, 0), + GATE(PCLK_HSI2C7, "pclk_hsi2c7", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 7, 0, 0), + GATE(PCLK_HSI2C8, "pclk_hsi2c8", "mout_aclk_peric1_66_user", + ENABLE_PCLK_PERIC1, 8, 0, 0), GATE(PCLK_UART1, "pclk_uart1", "mout_aclk_peric1_66_user", ENABLE_PCLK_PERIC1, 9, 0, 0), GATE(PCLK_UART2, "pclk_uart2", "mout_aclk_peric1_66_user", diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index 00fd6de1cb25..6d07b6f1d615 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -30,7 +30,14 @@ /* PERIC0 */ #define PCLK_UART0 1 #define SCLK_UART0 2 -#define PERIC0_NR_CLK 3 +#define PCLK_HSI2C0 3 +#define PCLK_HSI2C1 4 +#define PCLK_HSI2C4 5 +#define PCLK_HSI2C5 6 +#define PCLK_HSI2C9 7 +#define PCLK_HSI2C10 8 +#define PCLK_HSI2C11 9 +#define PERIC0_NR_CLK 10 /* PERIC1 */ #define PCLK_UART1 1 @@ -39,7 +46,12 @@ #define SCLK_UART1 4 #define SCLK_UART2 5 #define SCLK_UART3 6 -#define PERIC1_NR_CLK 7 +#define PCLK_HSI2C2 7 +#define PCLK_HSI2C3 8 +#define PCLK_HSI2C6 9 +#define PCLK_HSI2C7 10 +#define PCLK_HSI2C8 11 +#define PERIC1_NR_CLK 12 /* PERIS */ #define PCLK_CHIPID 1 -- GitLab From 6d0c8c723f0b886f58263c089831fd2bee0b3b57 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Tue, 21 Oct 2014 11:13:52 +0530 Subject: [PATCH 2332/9457] clk: samsung: exynos7: add clocks for MMC block Exynos7 supports 3 MMC channels, add the MMC gate clocks to support them. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos7-clock.txt | 21 ++ drivers/clk/samsung/clk-exynos7.c | 224 ++++++++++++++++++ include/dt-bindings/clock/exynos7-clk.h | 20 ++ 3 files changed, 265 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/exynos7-clock.txt b/Documentation/devicetree/bindings/clock/exynos7-clock.txt index 789f76132a85..b29cb50048c6 100644 --- a/Documentation/devicetree/bindings/clock/exynos7-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos7-clock.txt @@ -27,9 +27,12 @@ Required Properties for Clock Controller: - "samsung,exynos7-clock-topc" - "samsung,exynos7-clock-top0" + - "samsung,exynos7-clock-top1" - "samsung,exynos7-clock-peric0" - "samsung,exynos7-clock-peric1" - "samsung,exynos7-clock-peris" + - "samsung,exynos7-clock-fsys0" + - "samsung,exynos7-clock-fsys1" - reg: physical base address of the controller and the length of memory mapped region. @@ -50,6 +53,13 @@ Input clocks for top0 clock controller: - dout_sclk_cc_pll - dout_sclk_mfc_pll +Input clocks for top1 clock controller: + - fin_pll + - dout_sclk_bus0_pll + - dout_sclk_bus1_pll + - dout_sclk_cc_pll + - dout_sclk_mfc_pll + Input clocks for peric0 clock controller: - fin_pll - dout_aclk_peric0_66 @@ -65,3 +75,14 @@ Input clocks for peric1 clock controller: Input clocks for peris clock controller: - fin_pll - dout_aclk_peris_66 + +Input clocks for fsys0 clock controller: + - fin_pll + - dout_aclk_fsys0_200 + - dout_sclk_mmc2 + +Input clocks for fsys1 clock controller: + - fin_pll + - dout_aclk_fsys1_200 + - dout_sclk_mmc0 + - dout_sclk_mmc1 diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index c700f654289e..f5e43fab1951 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -267,6 +267,132 @@ static void __init exynos7_clk_top0_init(struct device_node *np) CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0", exynos7_clk_top0_init); +/* Register Offset definitions for CMU_TOP1 (0x105E0000) */ +#define MUX_SEL_TOP10 0x0200 +#define MUX_SEL_TOP11 0x0204 +#define MUX_SEL_TOP13 0x020C +#define MUX_SEL_TOP1_FSYS0 0x0224 +#define MUX_SEL_TOP1_FSYS1 0x0228 +#define DIV_TOP13 0x060C +#define DIV_TOP1_FSYS0 0x0624 +#define DIV_TOP1_FSYS1 0x0628 +#define ENABLE_ACLK_TOP13 0x080C +#define ENABLE_SCLK_TOP1_FSYS0 0x0A24 +#define ENABLE_SCLK_TOP1_FSYS1 0x0A28 + +/* List of parent clocks for Muxes in CMU_TOP1 */ +PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; +PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" }; +PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" }; +PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" }; + +PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll", + "ffac_top1_bus0_pll_div2"}; +PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll", + "ffac_top1_bus1_pll_div2"}; +PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll", + "ffac_top1_cc_pll_div2"}; +PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll", + "ffac_top1_mfc_pll_div2"}; + +PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll", + "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll", + "mout_top1_half_mfc_pll"}; + +static unsigned long top1_clk_regs[] __initdata = { + MUX_SEL_TOP10, + MUX_SEL_TOP11, + MUX_SEL_TOP13, + MUX_SEL_TOP1_FSYS0, + MUX_SEL_TOP1_FSYS1, + DIV_TOP13, + DIV_TOP1_FSYS0, + DIV_TOP1_FSYS1, + ENABLE_ACLK_TOP13, + ENABLE_SCLK_TOP1_FSYS0, + ENABLE_SCLK_TOP1_FSYS1, +}; + +static struct samsung_mux_clock top1_mux_clks[] __initdata = { + MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1), + MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1), + MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p, + MUX_SEL_TOP10, 12, 1), + MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p, + MUX_SEL_TOP10, 16, 1), + + MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p, + MUX_SEL_TOP11, 4, 1), + MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p, + MUX_SEL_TOP11, 8, 1), + MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p, + MUX_SEL_TOP11, 12, 1), + MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p, + MUX_SEL_TOP11, 16, 1), + + MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2), + MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2), + + MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2), + + MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2), + MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2), +}; + +static struct samsung_div_clock top1_div_clks[] __initdata = { + DIV(DOUT_ACLK_FSYS1_200, "dout_aclk_fsys1_200", "mout_aclk_fsys1_200", + DIV_TOP13, 24, 4), + DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200", + DIV_TOP13, 28, 4), + + DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2", + DIV_TOP1_FSYS0, 24, 4), + + DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1", + DIV_TOP1_FSYS1, 24, 4), + DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0", + DIV_TOP1_FSYS1, 28, 4), +}; + +static struct samsung_gate_clock top1_gate_clks[] __initdata = { + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2", + ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0), + + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1", + ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0", + ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0), + FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0), +}; + +static struct samsung_cmu_info top1_cmu_info __initdata = { + .mux_clks = top1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top1_mux_clks), + .div_clks = top1_div_clks, + .nr_div_clks = ARRAY_SIZE(top1_div_clks), + .gate_clks = top1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top1_gate_clks), + .fixed_factor_clks = top1_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(top1_fixed_factor_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = top1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top1_clk_regs), +}; + +static void __init exynos7_clk_top1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &top1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1", + exynos7_clk_top1_init); + /* Register Offset definitions for CMU_PERIC0 (0x13610000) */ #define MUX_SEL_PERIC0 0x0200 #define ENABLE_PCLK_PERIC0 0x0900 @@ -447,3 +573,101 @@ static void __init exynos7_clk_peris_init(struct device_node *np) CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris", exynos7_clk_peris_init); + +/* Register Offset definitions for CMU_FSYS0 (0x10E90000) */ +#define MUX_SEL_FSYS00 0x0200 +#define MUX_SEL_FSYS01 0x0204 +#define ENABLE_ACLK_FSYS01 0x0804 + +/* + * List of parent clocks for Muxes in CMU_FSYS0 + */ +PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" }; +PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" }; + +static unsigned long fsys0_clk_regs[] __initdata = { + MUX_SEL_FSYS00, + MUX_SEL_FSYS01, + ENABLE_ACLK_FSYS01, +}; + +static struct samsung_mux_clock fsys0_mux_clks[] __initdata = { + MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p, + MUX_SEL_FSYS00, 24, 1), + + MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1), +}; + +static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { + GATE(ACLK_MMC2, "aclk_mmc2", "mout_aclk_fsys0_200_user", + ENABLE_ACLK_FSYS01, 31, 0, 0), +}; + +static struct samsung_cmu_info fsys0_cmu_info __initdata = { + .mux_clks = fsys0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), + .gate_clks = fsys0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = fsys0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), +}; + +static void __init exynos7_clk_fsys0_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &fsys0_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0", + exynos7_clk_fsys0_init); + +/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */ +#define MUX_SEL_FSYS10 0x0200 +#define MUX_SEL_FSYS11 0x0204 +#define ENABLE_ACLK_FSYS1 0x0800 + +/* + * List of parent clocks for Muxes in CMU_FSYS1 + */ +PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" }; +PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" }; +PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" }; + +static unsigned long fsys1_clk_regs[] __initdata = { + MUX_SEL_FSYS10, + MUX_SEL_FSYS11, + ENABLE_ACLK_FSYS1, +}; + +static struct samsung_mux_clock fsys1_mux_clks[] __initdata = { + MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p, + MUX_SEL_FSYS10, 28, 1), + + MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1), + MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1), +}; + +static struct samsung_gate_clock fsys1_gate_clks[] __initdata = { + GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user", + ENABLE_ACLK_FSYS1, 29, 0, 0), + GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user", + ENABLE_ACLK_FSYS1, 30, 0, 0), +}; + +static struct samsung_cmu_info fsys1_cmu_info __initdata = { + .mux_clks = fsys1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), + .gate_clks = fsys1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), + .nr_clk_ids = TOP1_NR_CLK, + .clk_regs = fsys1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), +}; + +static void __init exynos7_clk_fsys1_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &fsys1_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1", + exynos7_clk_fsys1_init); diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index 6d07b6f1d615..ff63c4e15cc5 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -27,6 +27,17 @@ #define CLK_SCLK_UART3 6 #define TOP0_NR_CLK 7 +/* TOP1 */ +#define DOUT_ACLK_FSYS1_200 1 +#define DOUT_ACLK_FSYS0_200 2 +#define DOUT_SCLK_MMC2 3 +#define DOUT_SCLK_MMC1 4 +#define DOUT_SCLK_MMC0 5 +#define CLK_SCLK_MMC2 6 +#define CLK_SCLK_MMC1 7 +#define CLK_SCLK_MMC0 8 +#define TOP1_NR_CLK 9 + /* PERIC0 */ #define PCLK_UART0 1 #define SCLK_UART0 2 @@ -58,4 +69,13 @@ #define SCLK_CHIPID 2 #define PERIS_NR_CLK 3 +/* FSYS0 */ +#define ACLK_MMC2 1 +#define FSYS0_NR_CLK 2 + +/* FSYS1 */ +#define ACLK_MMC1 1 +#define ACLK_MMC0 2 +#define FSYS1_NR_CLK 3 + #endif /* _DT_BINDINGS_CLOCK_EXYNOS7_H */ -- GitLab From f5e127cd5ee52b3f0edaeeb7a40c0b9599f4e691 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Tue, 28 Oct 2014 16:48:53 +0530 Subject: [PATCH 2333/9457] clk: samsung: exynos7: add clocks for RTC block Add clock support for the RTC block in Exynos7. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Signed-off-by: Sylwester Nawrocki --- .../bindings/clock/exynos7-clock.txt | 5 ++ drivers/clk/samsung/clk-exynos7.c | 54 +++++++++++++++++++ include/dt-bindings/clock/exynos7-clk.h | 7 ++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/exynos7-clock.txt b/Documentation/devicetree/bindings/clock/exynos7-clock.txt index b29cb50048c6..6d3d5f80c1c3 100644 --- a/Documentation/devicetree/bindings/clock/exynos7-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos7-clock.txt @@ -28,6 +28,7 @@ Required Properties for Clock Controller: - "samsung,exynos7-clock-topc" - "samsung,exynos7-clock-top0" - "samsung,exynos7-clock-top1" + - "samsung,exynos7-clock-ccore" - "samsung,exynos7-clock-peric0" - "samsung,exynos7-clock-peric1" - "samsung,exynos7-clock-peris" @@ -60,6 +61,10 @@ Input clocks for top1 clock controller: - dout_sclk_cc_pll - dout_sclk_mfc_pll +Input clocks for ccore clock controller: + - fin_pll + - dout_aclk_ccore_133 + Input clocks for peric0 clock controller: - fin_pll - dout_aclk_peric0_66 diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index f5e43fab1951..3a30f43fa925 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -29,7 +29,9 @@ #define AUD_PLL_CON0 0x0140 #define MUX_SEL_TOPC0 0x0200 #define MUX_SEL_TOPC1 0x0204 +#define MUX_SEL_TOPC2 0x0208 #define MUX_SEL_TOPC3 0x020C +#define DIV_TOPC0 0x0600 #define DIV_TOPC1 0x0604 #define DIV_TOPC3 0x060C @@ -78,7 +80,9 @@ static unsigned long topc_clk_regs[] __initdata = { AUD_PLL_CON0, MUX_SEL_TOPC0, MUX_SEL_TOPC1, + MUX_SEL_TOPC2, MUX_SEL_TOPC3, + DIV_TOPC0, DIV_TOPC1, DIV_TOPC3, }; @@ -101,10 +105,15 @@ static struct samsung_mux_clock topc_mux_clks[] __initdata = { MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p, MUX_SEL_TOPC1, 16, 1), + MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2), + MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2), }; static struct samsung_div_clock topc_div_clks[] __initdata = { + DIV(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133", + DIV_TOPC0, 4, 4), + DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", DIV_TOPC1, 24, 4), @@ -393,6 +402,51 @@ static void __init exynos7_clk_top1_init(struct device_node *np) CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1", exynos7_clk_top1_init); +/* Register Offset definitions for CMU_CCORE (0x105B0000) */ +#define MUX_SEL_CCORE 0x0200 +#define DIV_CCORE 0x0600 +#define ENABLE_ACLK_CCORE0 0x0800 +#define ENABLE_ACLK_CCORE1 0x0804 +#define ENABLE_PCLK_CCORE 0x0900 + +/* + * List of parent clocks for Muxes in CMU_CCORE + */ +PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" }; + +static unsigned long ccore_clk_regs[] __initdata = { + MUX_SEL_CCORE, + ENABLE_PCLK_CCORE, +}; + +static struct samsung_mux_clock ccore_mux_clks[] __initdata = { + MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p, + MUX_SEL_CCORE, 1, 1), +}; + +static struct samsung_gate_clock ccore_gate_clks[] __initdata = { + GATE(PCLK_RTC, "pclk_rtc", "mout_aclk_ccore_133_user", + ENABLE_PCLK_CCORE, 8, 0, 0), +}; + +static struct samsung_cmu_info ccore_cmu_info __initdata = { + .mux_clks = ccore_mux_clks, + .nr_mux_clks = ARRAY_SIZE(ccore_mux_clks), + .gate_clks = ccore_gate_clks, + .nr_gate_clks = ARRAY_SIZE(ccore_gate_clks), + .nr_clk_ids = CCORE_NR_CLK, + .clk_regs = ccore_clk_regs, + .nr_clk_regs = ARRAY_SIZE(ccore_clk_regs), +}; + +static void __init exynos7_clk_ccore_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &ccore_cmu_info); +} + +CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore", + exynos7_clk_ccore_init); + /* Register Offset definitions for CMU_PERIC0 (0x13610000) */ #define MUX_SEL_PERIC0 0x0200 #define ENABLE_PCLK_PERIC0 0x0900 diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index ff63c4e15cc5..dd89aa0f84e1 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -16,7 +16,8 @@ #define DOUT_SCLK_BUS1_PLL 3 #define DOUT_SCLK_CC_PLL 4 #define DOUT_SCLK_MFC_PLL 5 -#define TOPC_NR_CLK 6 +#define DOUT_ACLK_CCORE_133 6 +#define TOPC_NR_CLK 7 /* TOP0 */ #define DOUT_ACLK_PERIC1 1 @@ -38,6 +39,10 @@ #define CLK_SCLK_MMC0 8 #define TOP1_NR_CLK 9 +/* CCORE */ +#define PCLK_RTC 1 +#define CCORE_NR_CLK 2 + /* PERIC0 */ #define PCLK_UART0 1 #define SCLK_UART0 2 -- GitLab From 2ab2dfe5d4eef6bad8cdd90dc6bba5a7660273d4 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Tue, 28 Oct 2014 16:48:54 +0530 Subject: [PATCH 2334/9457] clk: samsung: exynos7: add gate clocks for WDT, TMU and PWM blocks Add clock support for the watchdog timer, pwm timer and thermal management unit IPs in Exynos7. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos7.c | 14 ++++++++++++++ include/dt-bindings/clock/exynos7-clk.h | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 3a30f43fa925..17e5cf4d2248 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -486,9 +486,12 @@ static struct samsung_gate_clock peric0_gate_clks[] __initdata = { ENABLE_PCLK_PERIC0, 14, 0, 0), GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user", ENABLE_PCLK_PERIC0, 16, 0, 0), + GATE(PCLK_PWM, "pclk_pwm", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 21, 0, 0), GATE(SCLK_UART0, "sclk_uart0_user", "mout_sclk_uart0_user", ENABLE_SCLK_PERIC0, 16, 0, 0), + GATE(SCLK_PWM, "sclk_pwm", "fin_pll", ENABLE_SCLK_PERIC0, 21, 0, 0), }; static struct samsung_cmu_info peric0_cmu_info __initdata = { @@ -586,7 +589,9 @@ CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1", /* Register Offset definitions for CMU_PERIS (0x10040000) */ #define MUX_SEL_PERIS 0x0200 +#define ENABLE_PCLK_PERIS 0x0900 #define ENABLE_PCLK_PERIS_SECURE_CHIPID 0x0910 +#define ENABLE_SCLK_PERIS 0x0A00 #define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 /* List of parent clocks for Muxes in CMU_PERIS */ @@ -594,7 +599,9 @@ PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" }; static unsigned long peris_clk_regs[] __initdata = { MUX_SEL_PERIS, + ENABLE_PCLK_PERIS, ENABLE_PCLK_PERIS_SECURE_CHIPID, + ENABLE_SCLK_PERIS, ENABLE_SCLK_PERIS_SECURE_CHIPID, }; @@ -604,10 +611,17 @@ static struct samsung_mux_clock peris_mux_clks[] __initdata = { }; static struct samsung_gate_clock peris_gate_clks[] __initdata = { + GATE(PCLK_WDT, "pclk_wdt", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS, 6, 0, 0), + GATE(PCLK_TMU, "pclk_tmu_apbif", "mout_aclk_peris_66_user", + ENABLE_PCLK_PERIS, 10, 0, 0), + GATE(PCLK_CHIPID, "pclk_chipid", "mout_aclk_peris_66_user", ENABLE_PCLK_PERIS_SECURE_CHIPID, 0, 0, 0), GATE(SCLK_CHIPID, "sclk_chipid", "fin_pll", ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0), + + GATE(SCLK_TMU, "sclk_tmu", "fin_pll", ENABLE_SCLK_PERIS, 10, 0, 0), }; static struct samsung_cmu_info peris_cmu_info __initdata = { diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index dd89aa0f84e1..f255bb7c64b3 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -53,7 +53,9 @@ #define PCLK_HSI2C9 7 #define PCLK_HSI2C10 8 #define PCLK_HSI2C11 9 -#define PERIC0_NR_CLK 10 +#define PCLK_PWM 10 +#define SCLK_PWM 11 +#define PERIC0_NR_CLK 12 /* PERIC1 */ #define PCLK_UART1 1 @@ -72,7 +74,10 @@ /* PERIS */ #define PCLK_CHIPID 1 #define SCLK_CHIPID 2 -#define PERIS_NR_CLK 3 +#define PCLK_WDT 3 +#define PCLK_TMU 4 +#define SCLK_TMU 5 +#define PERIS_NR_CLK 6 /* FSYS0 */ #define ACLK_MMC2 1 -- GitLab From 932e98224d5602be17ed61d0e057e9326f12b59d Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Tue, 28 Oct 2014 16:48:55 +0530 Subject: [PATCH 2335/9457] clk: samsung: exynos7: add gate clock for ADC block Add clock support for the ADC interface in Exynos7. Signed-off-by: Abhilash Kesavan Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos7.c | 2 ++ include/dt-bindings/clock/exynos7-clk.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 17e5cf4d2248..ea4483b8d62e 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -486,6 +486,8 @@ static struct samsung_gate_clock peric0_gate_clks[] __initdata = { ENABLE_PCLK_PERIC0, 14, 0, 0), GATE(PCLK_UART0, "pclk_uart0", "mout_aclk_peric0_66_user", ENABLE_PCLK_PERIC0, 16, 0, 0), + GATE(PCLK_ADCIF, "pclk_adcif", "mout_aclk_peric0_66_user", + ENABLE_PCLK_PERIC0, 20, 0, 0), GATE(PCLK_PWM, "pclk_pwm", "mout_aclk_peric0_66_user", ENABLE_PCLK_PERIC0, 21, 0, 0), diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index f255bb7c64b3..8e4681b07ae7 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -55,7 +55,8 @@ #define PCLK_HSI2C11 9 #define PCLK_PWM 10 #define SCLK_PWM 11 -#define PERIC0_NR_CLK 12 +#define PCLK_ADCIF 12 +#define PERIC0_NR_CLK 13 /* PERIC1 */ #define PCLK_UART1 1 -- GitLab From 0c49e2f668a50783519ed7de8f938ad12746cdc2 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 21 Oct 2014 14:36:58 +0530 Subject: [PATCH 2336/9457] pinctrl-bcm281xx: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-bcm281xx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c index a26e0c2ba33e..2b25047fef8d 100644 --- a/drivers/pinctrl/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/pinctrl-bcm281xx.c @@ -1404,11 +1404,6 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) /* So far We can assume there is only 1 bank of registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Missing MEM resource\n"); - return -ENODEV; - } - pdata->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(pdata->reg_base)) { dev_err(&pdev->dev, "Failed to ioremap MEM resource\n"); -- GitLab From 6879db7648b6b995122afa98df31778c7af0855d Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 31 Oct 2014 14:52:16 +0800 Subject: [PATCH 2337/9457] ASoC: rt286: reduce power consumption This patch will optimize the power consumption of rt286. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 211 ++++++++++++++++++++++++++++----------- 1 file changed, 155 insertions(+), 56 deletions(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 4aa555cbcca8..97daa80e9104 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -36,11 +36,13 @@ struct rt286_priv { struct regmap *regmap; + struct snd_soc_codec *codec; struct rt286_platform_data pdata; struct i2c_client *i2c; struct snd_soc_jack *jack; struct delayed_work jack_detect_work; int sys_clk; + int clk_id; struct reg_default *index_cache; }; @@ -298,7 +300,6 @@ static int rt286_support_power_controls[] = { static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) { unsigned int val, buf; - int i; *hp = false; *mic = false; @@ -309,67 +310,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) if (*hp) { /* power on HV,VERF */ regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL1, 0x1001, 0x0); + RT286_DC_GAIN, 0x200, 0x200); + + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "HV"); + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "VREF"); /* power LDO1 */ - regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL2, 0x4, 0x4); - regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); - regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); + snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, + "LDO1"); + snd_soc_dapm_sync(&rt286->codec->dapm); - msleep(200); - i = 40; - while (((val & 0x0800) == 0) && (i > 0)) { - regmap_read(rt286->regmap, - RT286_CBJ_CTRL2, &val); - i--; - msleep(20); - } + regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); + msleep(50); - if (0x0400 == (val & 0x0700)) { - *mic = false; + regmap_update_bits(rt286->regmap, + RT286_CBJ_CTRL1, 0xfcc0, 0xd400); + msleep(300); + regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); - regmap_write(rt286->regmap, - RT286_SET_MIC1, 0x20); - /* power off HV,VERF */ - regmap_update_bits(rt286->regmap, - RT286_POWER_CTRL1, 0x1001, 0x1001); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, 0xc000, 0x0000); - regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, 0x0030, 0x0000); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, 0xc000, 0x0000); - } else if ((0x0200 == (val & 0x0700)) || - (0x0100 == (val & 0x0700))) { + if (0x0070 == (val & 0x0070)) { *mic = true; - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, 0xc000, 0x8000); - regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, 0x0030, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, 0xc000, 0x8000); } else { - *mic = false; + regmap_update_bits(rt286->regmap, + RT286_CBJ_CTRL1, 0xfcc0, 0xe400); + msleep(300); + regmap_read(rt286->regmap, + RT286_CBJ_CTRL2, &val); + if (0x0070 == (val & 0x0070)) + *mic = true; + else + *mic = false; } - - regmap_update_bits(rt286->regmap, - RT286_MISC_CTRL1, - 0x0060, 0x0000); - } else { - regmap_update_bits(rt286->regmap, - RT286_MISC_CTRL1, - 0x0060, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL3, - 0xc000, 0x8000); regmap_update_bits(rt286->regmap, - RT286_CBJ_CTRL1, - 0x0030, 0x0020); - regmap_update_bits(rt286->regmap, - RT286_A_BIAS_CTRL2, - 0xc000, 0x8000); + RT286_DC_GAIN, 0x200, 0x0); + } else { *mic = false; + regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); } } else { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); @@ -378,6 +356,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) *mic = buf & 0x80000000; } + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV"); + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF"); + if (!*hp) + snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1"); + snd_soc_dapm_sync(&rt286->codec->dapm); + return 0; } @@ -415,6 +399,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) } EXPORT_SYMBOL_GPL(rt286_mic_detect); +static int is_mclk_mode(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); + + if (rt286->clk_id == RT286_SCLK_S_MCLK) + return 1; + else + return 0; +} + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); @@ -568,7 +563,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt286_vref_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + RT286_CBJ_CTRL1, 0x0400, 0x0000); + mdelay(50); + break; + default: + return 0; + } + + return 0; +} + +static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30); + break; + default: + return 0; + } + + return 0; +} + +static int rt286_mic1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL3, 0xc000, 0x8000); + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL2, 0xc000, 0x8000); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL3, 0xc000, 0x0000); + snd_soc_update_bits(codec, + RT286_A_BIAS_CTRL2, 0xc000, 0x0000); + break; + default: + return 0; + } + + return 0; +} + static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1, + 12, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1, + 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2, + 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1, + 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1, + 5, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM, + 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + /* Input Lines */ SND_SOC_DAPM_INPUT("DMIC1 Pin"), SND_SOC_DAPM_INPUT("DMIC2 Pin"), @@ -642,6 +714,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt286_dapm_routes[] = { + {"ADC 0", NULL, "MCLK MODE", is_mclk_mode}, + {"ADC 1", NULL, "MCLK MODE", is_mclk_mode}, + {"Front", NULL, "MCLK MODE", is_mclk_mode}, + {"Surround", NULL, "MCLK MODE", is_mclk_mode}, + + {"HP Power", NULL, "LDO1"}, + {"HP Power", NULL, "LDO2"}, + + {"MIC1", NULL, "LDO1"}, + {"MIC1", NULL, "LDO2"}, + {"MIC1", NULL, "HV"}, + {"MIC1", NULL, "VREF"}, + {"MIC1", NULL, "MIC1 Input Buffer"}, + + {"SPO", NULL, "LDO1"}, + {"SPO", NULL, "LDO2"}, + {"SPO", NULL, "HV"}, + {"SPO", NULL, "VREF"}, + {"DMIC1", NULL, "DMIC1 Pin"}, {"DMIC2", NULL, "DMIC2 Pin"}, {"DMIC1", NULL, "DMIC Receiver"}, @@ -880,6 +971,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai, } rt286->sys_clk = freq; + rt286->clk_id = clk_id; return 0; } @@ -915,13 +1007,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: mdelay(10); + snd_soc_update_bits(codec, + RT286_CBJ_CTRL1, 0x0400, 0x0400); + snd_soc_update_bits(codec, + RT286_DC_GAIN, 0x200, 0x0); + break; case SND_SOC_BIAS_STANDBY: snd_soc_write(codec, RT286_SET_AUDIO_POWER, AC_PWRST_D3); snd_soc_update_bits(codec, - RT286_DC_GAIN, 0x200, 0x0); + RT286_CBJ_CTRL1, 0x0400, 0x0000); break; default: @@ -962,6 +1059,7 @@ static int rt286_probe(struct snd_soc_codec *codec) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); + rt286->codec = codec; codec->dapm.bias_level = SND_SOC_BIAS_OFF; if (rt286->i2c->irq) { @@ -1152,7 +1250,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (!rt286->pdata.cbj_en) { regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); - regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xf000, 0xb000); } else { @@ -1169,8 +1266,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c, mdelay(10); - /*Power down LDO2*/ - regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); + regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); + /*Power down LDO, VREF*/ + regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0); + regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); /*Set depop parameter*/ regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); -- GitLab From 3e4b1b4a91be447511a7a2e8f3b5b2942328e97c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 31 Oct 2014 13:08:50 +0200 Subject: [PATCH 2338/9457] iwlwfifi: fix WANT_DEV_COREDUMP selection in Kconfig Fix my mistake while sending Johannes's commit aadede6e9f4c8ee46808b2f697b714ee50810e23 Author: Johannes Berg Date: Thu Oct 9 17:01:36 2014 +0200 iwlwifi: mvm: port to devcoredump framework Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 139de90c2aaf..ab019b45551b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -59,7 +59,7 @@ config IWLDVM config IWLMVM tristate "Intel Wireless WiFi MVM Firmware support" - select BACKPORT_WANT_DEV_COREDUMP + select WANT_DEV_COREDUMP help This is the driver that supports the MVM firmware which is currently only available for 7260 and 3160 devices. -- GitLab From d004ebbef7292848f5f7ecae50824c04780baaac Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 29 Oct 2014 16:25:38 +0300 Subject: [PATCH 2339/9457] ASoC: tlv320aic23: make codecs selectable in Kconfig Now that manual selection of drivers for audio subsystem components is preferred AIC23 codec must be selectable in Kconfig to make it possible. Signed-off-by: Max Filippov Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..7881b3c35b4d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -581,11 +581,11 @@ config SND_SOC_TLV320AIC23 tristate config SND_SOC_TLV320AIC23_I2C - tristate + tristate "Texas Instruments TLV320AIC23 audio CODEC - I2C" select SND_SOC_TLV320AIC23 config SND_SOC_TLV320AIC23_SPI - tristate + tristate "Texas Instruments TLV320AIC23 audio CODEC - SPI" select SND_SOC_TLV320AIC23 config SND_SOC_TLV320AIC26 -- GitLab From 1a6db0bd26a72027d6a5ea006d64d4021fd0326e Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 10:38:54 +0530 Subject: [PATCH 2340/9457] ASoC: Intel: mrfld: Fix runtime pm calls in sst_open_pcm_stream It's already done in open/close. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_drv_interface.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c index 183b1eb95c0e..4187057fb933 100644 --- a/sound/soc/intel/sst/sst_drv_interface.c +++ b/sound/soc/intel/sst/sst_drv_interface.c @@ -163,16 +163,11 @@ static int sst_open_pcm_stream(struct device *dev, if (!str_param) return -EINVAL; - retval = pm_runtime_get_sync(ctx->dev); - if (retval < 0) - return retval; retval = sst_get_stream(ctx, str_param); - if (retval > 0) { + if (retval > 0) ctx->stream_cnt++; - } else { + else dev_err(ctx->dev, "sst_get_stream returned err %d\n", retval); - sst_pm_runtime_put(ctx); - } return retval; } @@ -212,7 +207,8 @@ static int sst_close_pcm_stream(struct device *dev, unsigned int str_id) stream->period_elapsed = NULL; ctx->stream_cnt--; - sst_pm_runtime_put(ctx); + if (retval) + dev_err(ctx->dev, "free stream returned err %d\n", retval); dev_dbg(ctx->dev, "Exit\n"); return 0; -- GitLab From d62f2a08b9d657344b2e271e8274f9d8f746e543 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 31 Oct 2014 12:38:20 +0530 Subject: [PATCH 2341/9457] ASoC: Intel: sst: add runtime power management handling This patch adds the runtime pm handlers, the driver already has code for get/put for runtime pm and only these handlers being missing. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index fa3421706e4e..7b8a110b213d 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -152,6 +152,23 @@ static irqreturn_t intel_sst_irq_thread_mrfld(int irq, void *context) return IRQ_HANDLED; } +static int sst_save_dsp_context_v2(struct intel_sst_drv *sst) +{ + int ret = 0; + + ret = sst_prepare_and_post_msg(sst, SST_TASK_ID_MEDIA, IPC_CMD, + IPC_PREP_D3, PIPE_RSVD, 0, NULL, NULL, + true, true, false, true); + + if (ret < 0) { + dev_err(sst->dev, "not suspending FW!!, Err: %d\n", ret); + return -EIO; + } + + return 0; +} + + static struct intel_sst_ops mrfld_ops = { .interrupt = intel_sst_interrupt_mrfld, .irq_thread = intel_sst_irq_thread_mrfld, @@ -160,6 +177,7 @@ static struct intel_sst_ops mrfld_ops = { .reset = intel_sst_reset_dsp_mrfld, .post_message = sst_post_message_mrfld, .process_reply = sst_process_reply_mrfld, + .save_dsp_context = sst_save_dsp_context_v2, .alloc_stream = sst_alloc_stream_mrfld, .post_download = sst_post_download_mrfld, }; @@ -418,6 +436,50 @@ static void intel_sst_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } +static int intel_sst_runtime_suspend(struct device *dev) +{ + int ret = 0; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + if (ctx->sst_state == SST_RESET) { + dev_dbg(dev, "LPE is already in RESET state, No action\n"); + return 0; + } + /* save fw context */ + if (ctx->ops->save_dsp_context(ctx)) + return -EBUSY; + + /* Move the SST state to Reset */ + sst_set_fw_state_locked(ctx, SST_RESET); + + synchronize_irq(ctx->irq_num); + flush_workqueue(ctx->post_msg_wq); + + return ret; +} + +static int intel_sst_runtime_resume(struct device *dev) +{ + int ret = 0; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + mutex_lock(&ctx->sst_lock); + if (ctx->sst_state == SST_RESET) { + ret = sst_load_fw(ctx); + if (ret) { + dev_err(dev, "FW download fail %d\n", ret); + ctx->sst_state = SST_RESET; + } + } + mutex_unlock(&ctx->sst_lock); + return ret; +} + +static const struct dev_pm_ops intel_sst_pm = { + .runtime_suspend = intel_sst_runtime_suspend, + .runtime_resume = intel_sst_runtime_resume, +}; + /* PCI Routines */ static struct pci_device_id intel_sst_ids[] = { { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, @@ -429,6 +491,11 @@ static struct pci_driver sst_driver = { .id_table = intel_sst_ids, .probe = intel_sst_probe, .remove = intel_sst_remove, +#ifdef CONFIG_PM + .driver = { + .pm = &intel_sst_pm, + }, +#endif }; module_pci_driver(sst_driver); -- GitLab From 45f31bfcda0c6e5f11168de10c85f3dd20337bdf Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 31 Oct 2014 12:38:21 +0530 Subject: [PATCH 2342/9457] ASoC: Intel: use lock when changing SST state. SST state change should be done under sst_lock Signed-off-by: Mythri P K Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 4 +--- sound/soc/intel/sst/sst_ipc.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 7b8a110b213d..04af2460f9cc 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -463,15 +463,13 @@ static int intel_sst_runtime_resume(struct device *dev) int ret = 0; struct intel_sst_drv *ctx = dev_get_drvdata(dev); - mutex_lock(&ctx->sst_lock); if (ctx->sst_state == SST_RESET) { ret = sst_load_fw(ctx); if (ret) { dev_err(dev, "FW download fail %d\n", ret); - ctx->sst_state = SST_RESET; + sst_set_fw_state_locked(ctx, SST_RESET); } } - mutex_unlock(&ctx->sst_lock); return ret; } diff --git a/sound/soc/intel/sst/sst_ipc.c b/sound/soc/intel/sst/sst_ipc.c index 2126f5bb2813..484e60978477 100644 --- a/sound/soc/intel/sst/sst_ipc.c +++ b/sound/soc/intel/sst/sst_ipc.c @@ -230,7 +230,7 @@ static void process_fw_init(struct intel_sst_drv *sst_drv_ctx, dev_dbg(sst_drv_ctx->dev, "*** FW Init msg came***\n"); if (init->result) { - sst_drv_ctx->sst_state = SST_RESET; + sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); dev_err(sst_drv_ctx->dev, "FW Init failed, Error %x\n", init->result); retval = init->result; -- GitLab From 6e9b05607fe896627ab7c15efff01b6dcae71a56 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 30 Oct 2014 16:20:56 +0530 Subject: [PATCH 2343/9457] ASoC: Intel: sst: load firmware using async callback We would like the DSP firmware to be available in driver as soon as possible. So use the async callback in driver to probe to load the firmware as soon as usermode is up Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 04af2460f9cc..fdada405eda7 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -364,6 +364,21 @@ static int intel_sst_probe(struct pci_dev *pci, sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); + snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), + "%s%04x%s", "fw_sst_", + sst_drv_ctx->dev_id, ".bin"); + dev_dbg(sst_drv_ctx->dev, + "Requesting FW %s now...\n", sst_drv_ctx->firmware_name); + ret = request_firmware_nowait(THIS_MODULE, 1, + sst_drv_ctx->firmware_name, sst_drv_ctx->dev, + GFP_KERNEL, sst_drv_ctx, sst_firmware_load_cb); + + if (ret) { + dev_err(sst_drv_ctx->dev, + "Firmware load failed with error: %d\n", ret); + goto do_release_regions; + } + sst_drv_ctx->irq_num = pci->irq; /* Register the ISR */ ret = devm_request_threaded_irq(&pci->dev, pci->irq, -- GitLab From 5794b7ec62d85700d372b07d88eaf71e807f542f Mon Sep 17 00:00:00 2001 From: "Fang, Yang A" Date: Thu, 30 Oct 2014 16:20:57 +0530 Subject: [PATCH 2344/9457] ASoC: Intel: use correct firmware name The firmware name was used worngly, so fix it up Signed-off-by: Fang, Yang A Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_loader.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c index 00f60c1e9fda..b580f96e25e5 100644 --- a/sound/soc/intel/sst/sst_loader.c +++ b/sound/soc/intel/sst/sst_loader.c @@ -344,12 +344,9 @@ void sst_firmware_load_cb(const struct firmware *fw, void *context) static int sst_request_fw(struct intel_sst_drv *sst) { int retval = 0; - char name[20]; const struct firmware *fw; - dev_dbg(sst->dev, "Requesting FW %s now...\n", name); - - retval = request_firmware(&fw, name, sst->dev); + retval = request_firmware(&fw, sst->firmware_name, sst->dev); if (fw == NULL) { dev_err(sst->dev, "fw is returning as null\n"); return -EINVAL; -- GitLab From fdcc4a039f0263f4674e363ebed14783b2f0543d Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:20:58 +0530 Subject: [PATCH 2345/9457] ASoC: mfld-compress: implement .power callback .power callback is required to invoked for compressed audio as well to turn on/off sst, so invoke them Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform-compress.c | 8 +++++++- sound/soc/intel/sst-mfld-platform.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/sst-mfld-platform-compress.c index 59467775c9b8..395168986462 100644 --- a/sound/soc/intel/sst-mfld-platform-compress.c +++ b/sound/soc/intel/sst-mfld-platform-compress.c @@ -67,8 +67,11 @@ static int sst_platform_compr_open(struct snd_compr_stream *cstream) goto out_ops; } stream->compr_ops = sst->compr_ops; - stream->id = 0; + + /* Turn on LPE */ + sst->compr_ops->power(sst->dev, true); + sst_set_stream_status(stream, SST_PLATFORM_INIT); runtime->private_data = stream; return 0; @@ -83,6 +86,9 @@ static int sst_platform_compr_free(struct snd_compr_stream *cstream) int ret_val = 0, str_id; stream = cstream->runtime->private_data; + /* Turn off LPE */ + sst->compr_ops->power(sst->dev, false); + /*need to check*/ str_id = stream->id; if (str_id) diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index d41d1c36031a..79c8d1246a8f 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -117,6 +117,7 @@ struct compress_sst_ops { int (*get_codec_caps)(struct snd_compr_codec_caps *codec); int (*set_metadata)(struct device *dev, unsigned int str_id, struct snd_compr_metadata *mdata); + int (*power)(struct device *dev, bool state); }; struct sst_ops { -- GitLab From 7adab122a57c5ade8efc2e4de67c72b084c31cda Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 30 Oct 2014 16:20:59 +0530 Subject: [PATCH 2346/9457] ASoC: Intel: sst - add compressed ops handling This patch add low level IPC handling for compressed stream operations Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_drv_interface.c | 285 ++++++++++++++++++++++++ 1 file changed, 285 insertions(+) diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c index 4187057fb933..5f75ef3cdd22 100644 --- a/sound/soc/intel/sst/sst_drv_interface.c +++ b/sound/soc/intel/sst/sst_drv_interface.c @@ -172,6 +172,273 @@ static int sst_open_pcm_stream(struct device *dev, return retval; } +static int sst_cdev_open(struct device *dev, + struct snd_sst_params *str_params, struct sst_compress_cb *cb) +{ + int str_id, retval; + struct stream_info *stream; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + retval = pm_runtime_get_sync(ctx->dev); + if (retval < 0) + return retval; + + str_id = sst_get_stream(ctx, str_params); + if (str_id > 0) { + dev_dbg(dev, "stream allocated in sst_cdev_open %d\n", str_id); + stream = &ctx->streams[str_id]; + stream->compr_cb = cb->compr_cb; + stream->compr_cb_param = cb->param; + stream->drain_notify = cb->drain_notify; + stream->drain_cb_param = cb->drain_cb_param; + } else { + dev_err(dev, "stream encountered error during alloc %d\n", str_id); + str_id = -EINVAL; + sst_pm_runtime_put(ctx); + } + return str_id; +} + +static int sst_cdev_close(struct device *dev, unsigned int str_id) +{ + int retval; + struct stream_info *stream; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + stream = get_stream_info(ctx, str_id); + if (!stream) { + dev_err(dev, "stream info is NULL for str %d!!!\n", str_id); + return -EINVAL; + } + + if (stream->status == STREAM_RESET) { + dev_dbg(dev, "stream in reset state...\n"); + stream->status = STREAM_UN_INIT; + + retval = 0; + goto put; + } + + retval = sst_free_stream(ctx, str_id); +put: + stream->compr_cb_param = NULL; + stream->compr_cb = NULL; + + if (retval) + dev_err(dev, "free stream returned err %d\n", retval); + + dev_dbg(dev, "End\n"); + return retval; + +} + +static int sst_cdev_ack(struct device *dev, unsigned int str_id, + unsigned long bytes) +{ + struct stream_info *stream; + struct snd_sst_tstamp fw_tstamp = {0,}; + int offset; + void __iomem *addr; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + stream = get_stream_info(ctx, str_id); + if (!stream) + return -EINVAL; + + /* update bytes sent */ + stream->cumm_bytes += bytes; + dev_dbg(dev, "bytes copied %d inc by %ld\n", stream->cumm_bytes, bytes); + + memcpy_fromio(&fw_tstamp, + ((void *)(ctx->mailbox + ctx->tstamp) + +(str_id * sizeof(fw_tstamp))), + sizeof(fw_tstamp)); + + fw_tstamp.bytes_copied = stream->cumm_bytes; + dev_dbg(dev, "bytes sent to fw %llu inc by %ld\n", + fw_tstamp.bytes_copied, bytes); + + addr = ((void *)(ctx->mailbox + ctx->tstamp)) + + (str_id * sizeof(fw_tstamp)); + offset = offsetof(struct snd_sst_tstamp, bytes_copied); + sst_shim_write(addr, offset, fw_tstamp.bytes_copied); + return 0; +} + +static int sst_cdev_set_metadata(struct device *dev, + unsigned int str_id, struct snd_compr_metadata *metadata) +{ + int retval = 0; + struct stream_info *str_info; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + dev_dbg(dev, "set metadata for stream %d\n", str_id); + + str_info = get_stream_info(ctx, str_id); + if (!str_info) + return -EINVAL; + + dev_dbg(dev, "pipe id = %d\n", str_info->pipe_id); + retval = sst_prepare_and_post_msg(ctx, str_info->task_id, IPC_CMD, + IPC_IA_SET_STREAM_PARAMS_MRFLD, str_info->pipe_id, + sizeof(*metadata), metadata, NULL, + true, true, true, false); + + return retval; +} + +static int sst_cdev_stream_pause(struct device *dev, unsigned int str_id) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + return sst_pause_stream(ctx, str_id); +} + +static int sst_cdev_stream_pause_release(struct device *dev, + unsigned int str_id) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + return sst_resume_stream(ctx, str_id); +} + +static int sst_cdev_stream_start(struct device *dev, unsigned int str_id) +{ + struct stream_info *str_info; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + str_info = get_stream_info(ctx, str_id); + if (!str_info) + return -EINVAL; + str_info->prev = str_info->status; + str_info->status = STREAM_RUNNING; + return sst_start_stream(ctx, str_id); +} + +static int sst_cdev_stream_drop(struct device *dev, unsigned int str_id) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + return sst_drop_stream(ctx, str_id); +} + +static int sst_cdev_stream_drain(struct device *dev, unsigned int str_id) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + return sst_drain_stream(ctx, str_id, false); +} + +static int sst_cdev_stream_partial_drain(struct device *dev, + unsigned int str_id) +{ + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + return sst_drain_stream(ctx, str_id, true); +} + +static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, + struct snd_compr_tstamp *tstamp) +{ + struct snd_sst_tstamp fw_tstamp = {0,}; + struct stream_info *stream; + struct intel_sst_drv *ctx = dev_get_drvdata(dev); + + memcpy_fromio(&fw_tstamp, + ((void *)(ctx->mailbox + ctx->tstamp) + +(str_id * sizeof(fw_tstamp))), + sizeof(fw_tstamp)); + + stream = get_stream_info(ctx, str_id); + if (!stream) + return -EINVAL; + dev_dbg(dev, "rb_counter %llu in bytes\n", fw_tstamp.ring_buffer_counter); + + tstamp->copied_total = fw_tstamp.ring_buffer_counter; + tstamp->pcm_frames = fw_tstamp.frames_decoded; + tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter, + (u64)((stream->num_ch) * SST_GET_BYTES_PER_SAMPLE(24))); + tstamp->sampling_rate = fw_tstamp.sampling_frequency; + + dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames); + dev_dbg(dev, "Ptr Query on strid = %d copied_total %d, decodec %d\n", + str_id, tstamp->copied_total, tstamp->pcm_frames); + dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames); + + return 0; +} + +static int sst_cdev_caps(struct snd_compr_caps *caps) +{ + caps->num_codecs = NUM_CODEC; + caps->min_fragment_size = MIN_FRAGMENT_SIZE; /* 50KB */ + caps->max_fragment_size = MAX_FRAGMENT_SIZE; /* 1024KB */ + caps->min_fragments = MIN_FRAGMENT; + caps->max_fragments = MAX_FRAGMENT; + caps->codecs[0] = SND_AUDIOCODEC_MP3; + caps->codecs[1] = SND_AUDIOCODEC_AAC; + return 0; +} + +static struct snd_compr_codec_caps caps_mp3 = { + .num_descriptors = 1, + .descriptor[0].max_ch = 2, + .descriptor[0].sample_rates[0] = 48000, + .descriptor[0].sample_rates[1] = 44100, + .descriptor[0].sample_rates[2] = 32000, + .descriptor[0].sample_rates[3] = 16000, + .descriptor[0].sample_rates[4] = 8000, + .descriptor[0].num_sample_rates = 5, + .descriptor[0].bit_rate[0] = 320, + .descriptor[0].bit_rate[1] = 192, + .descriptor[0].num_bitrates = 2, + .descriptor[0].profiles = 0, + .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, + .descriptor[0].formats = 0, +}; + +static struct snd_compr_codec_caps caps_aac = { + .num_descriptors = 2, + .descriptor[1].max_ch = 2, + .descriptor[0].sample_rates[0] = 48000, + .descriptor[0].sample_rates[1] = 44100, + .descriptor[0].sample_rates[2] = 32000, + .descriptor[0].sample_rates[3] = 16000, + .descriptor[0].sample_rates[4] = 8000, + .descriptor[0].num_sample_rates = 5, + .descriptor[1].bit_rate[0] = 320, + .descriptor[1].bit_rate[1] = 192, + .descriptor[1].num_bitrates = 2, + .descriptor[1].profiles = 0, + .descriptor[1].modes = 0, + .descriptor[1].formats = + (SND_AUDIOSTREAMFORMAT_MP4ADTS | + SND_AUDIOSTREAMFORMAT_RAW), +}; + +static int sst_cdev_codec_caps(struct snd_compr_codec_caps *codec) +{ + if (codec->codec == SND_AUDIOCODEC_MP3) + *codec = caps_mp3; + else if (codec->codec == SND_AUDIOCODEC_AAC) + *codec = caps_aac; + else + return -EINVAL; + + return 0; +} + +void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id) +{ + struct stream_info *stream; + + dev_dbg(ctx->dev, "fragment elapsed from firmware for str_id %d\n", + str_id); + stream = &ctx->streams[str_id]; + if (stream->compr_cb) + stream->compr_cb(stream->compr_cb_param); +} + /* * sst_close_pcm_stream - Close PCM interface * @@ -372,10 +639,28 @@ static struct sst_ops pcm_ops = { .power = sst_power_control, }; +static struct compress_sst_ops compr_ops = { + .open = sst_cdev_open, + .close = sst_cdev_close, + .stream_pause = sst_cdev_stream_pause, + .stream_pause_release = sst_cdev_stream_pause_release, + .stream_start = sst_cdev_stream_start, + .stream_drop = sst_cdev_stream_drop, + .stream_drain = sst_cdev_stream_drain, + .stream_partial_drain = sst_cdev_stream_partial_drain, + .tstamp = sst_cdev_tstamp, + .ack = sst_cdev_ack, + .get_caps = sst_cdev_caps, + .get_codec_caps = sst_cdev_codec_caps, + .set_metadata = sst_cdev_set_metadata, + .power = sst_power_control, +}; + static struct sst_device sst_dsp_device = { .name = "Intel(R) SST LPE", .dev = NULL, .ops = &pcm_ops, + .compr_ops = &compr_ops, }; /* -- GitLab From 62759361eb4929ffe692639176887020c76234a2 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 31 Oct 2014 14:48:47 +0200 Subject: [PATCH 2347/9457] mac80211-hwsim: Provide multicast event for HWSIM_CMD_NEW_RADIO When adding new radio via HWSIM_CMD_NEW_RADIO then listeners on the multicast group "config" are informed. While at it, refactor the configuration parameters to be able to pass them directly and have fewer function arguments. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 275 ++++++++++++++++++-------- 1 file changed, 198 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 5dbaee36c607..476c89cb06c9 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -487,6 +487,14 @@ static struct genl_family hwsim_genl_family = { .maxattr = HWSIM_ATTR_MAX, }; +enum hwsim_multicast_groups { + HWSIM_MCGRP_CONFIG, +}; + +static const struct genl_multicast_group hwsim_mcgrps[] = { + [HWSIM_MCGRP_CONFIG] = { .name = "config", }, +}; + /* MAC80211_HWSIM netlink policy */ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { @@ -2025,12 +2033,124 @@ static const struct ieee80211_ops mac80211_hwsim_ops = { static struct ieee80211_ops mac80211_hwsim_mchan_ops; -static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, - const struct ieee80211_regdomain *regd, - bool reg_strict, bool p2p_device, - bool use_chanctx, bool destroy_on_close, - u32 portid, const char *hwname, - bool no_vif) +struct hwsim_new_radio_params { + unsigned int channels; + const char *reg_alpha2; + const struct ieee80211_regdomain *regd; + bool reg_strict; + bool p2p_device; + bool use_chanctx; + bool destroy_on_close; + const char *hwname; + bool no_vif; +}; + +static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb, + struct genl_info *info) +{ + if (info) + genl_notify(&hwsim_genl_family, mcast_skb, + genl_info_net(info), info->snd_portid, + HWSIM_MCGRP_CONFIG, info->nlhdr, GFP_KERNEL); + else + genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0, + HWSIM_MCGRP_CONFIG, GFP_KERNEL); +} + +static struct sk_buff *build_radio_msg(int cmd, int id, + struct hwsim_new_radio_params *param) +{ + struct sk_buff *skb; + void *data; + int ret; + + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return NULL; + + data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, cmd); + if (!data) + goto error; + + ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id); + if (ret < 0) + goto error; + + if (param->channels) { + ret = nla_put_u32(skb, HWSIM_ATTR_CHANNELS, param->channels); + if (ret < 0) + goto error; + } + + if (param->reg_alpha2) { + ret = nla_put(skb, HWSIM_ATTR_REG_HINT_ALPHA2, 2, + param->reg_alpha2); + if (ret < 0) + goto error; + } + + if (param->regd) { + int i; + + for (i = 0; hwsim_world_regdom_custom[i] != param->regd && + i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) + ; + + if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) { + ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); + if (ret < 0) + goto error; + } + } + + if (param->reg_strict) { + ret = nla_put_flag(skb, HWSIM_ATTR_REG_STRICT_REG); + if (ret < 0) + goto error; + } + + if (param->p2p_device) { + ret = nla_put_flag(skb, HWSIM_ATTR_SUPPORT_P2P_DEVICE); + if (ret < 0) + goto error; + } + + if (param->use_chanctx) { + ret = nla_put_flag(skb, HWSIM_ATTR_USE_CHANCTX); + if (ret < 0) + goto error; + } + + if (param->hwname) { + ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, + strlen(param->hwname), param->hwname); + if (ret < 0) + goto error; + } + + genlmsg_end(skb, data); + + return skb; + +error: + nlmsg_free(skb); + return NULL; +} + +static void hswim_mcast_new_radio(int id, struct genl_info *info, + struct hwsim_new_radio_params *param) +{ + struct sk_buff *mcast_skb; + + mcast_skb = build_radio_msg(HWSIM_CMD_NEW_RADIO, id, param); + if (!mcast_skb) + return; + + hwsim_mcast_config_msg(mcast_skb, info); +} + +static int mac80211_hwsim_new_radio(struct genl_info *info, + struct hwsim_new_radio_params *param) { int err; u8 addr[ETH_ALEN]; @@ -2040,16 +2160,16 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, const struct ieee80211_ops *ops = &mac80211_hwsim_ops; int idx; - if (WARN_ON(channels > 1 && !use_chanctx)) + if (WARN_ON(param->channels > 1 && !param->use_chanctx)) return -EINVAL; spin_lock_bh(&hwsim_radio_lock); idx = hwsim_radio_idx++; spin_unlock_bh(&hwsim_radio_lock); - if (use_chanctx) + if (param->use_chanctx) ops = &mac80211_hwsim_mchan_ops; - hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, hwname); + hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname); if (!hw) { printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n"); err = -ENOMEM; @@ -2087,11 +2207,12 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, hw->wiphy->n_addresses = 2; hw->wiphy->addresses = data->addresses; - data->channels = channels; - data->use_chanctx = use_chanctx; + data->channels = param->channels; + data->use_chanctx = param->use_chanctx; data->idx = idx; - data->destroy_on_close = destroy_on_close; - data->portid = portid; + data->destroy_on_close = param->destroy_on_close; + if (info) + data->portid = info->snd_portid; if (data->use_chanctx) { hw->wiphy->max_scan_ssids = 255; @@ -2100,12 +2221,12 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, /* For channels > 1 DFS is not allowed */ hw->wiphy->n_iface_combinations = 1; hw->wiphy->iface_combinations = &data->if_combination; - if (p2p_device) + if (param->p2p_device) data->if_combination = hwsim_if_comb_p2p_dev[0]; else data->if_combination = hwsim_if_comb[0]; data->if_combination.num_different_channels = data->channels; - } else if (p2p_device) { + } else if (param->p2p_device) { hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev; hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb_p2p_dev); @@ -2126,7 +2247,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - if (p2p_device) + if (param->p2p_device) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_DEVICE); hw->flags = IEEE80211_HW_MFP_CAPABLE | @@ -2229,16 +2350,16 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, hw->max_rates = 4; hw->max_rate_tries = 11; - if (reg_strict) + if (param->reg_strict) hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; - if (regd) { + if (param->regd) { hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; - wiphy_apply_custom_regulatory(hw->wiphy, regd); + wiphy_apply_custom_regulatory(hw->wiphy, param->regd); /* give the regulatory workqueue a chance to run */ schedule_timeout_interruptible(1); } - if (no_vif) + if (param->no_vif) hw->flags |= IEEE80211_HW_NO_AUTO_VIF; err = ieee80211_register_hw(hw); @@ -2250,8 +2371,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); - if (reg_alpha2) - regulatory_hint(hw->wiphy, reg_alpha2); + if (param->reg_alpha2) + regulatory_hint(hw->wiphy, param->reg_alpha2); data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); @@ -2270,6 +2391,9 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, list_add_tail(&data->list, &hwsim_radios); spin_unlock_bh(&hwsim_radio_lock); + if (idx > 0) + hswim_mcast_new_radio(idx, info, param); + return idx; failed_hw: @@ -2520,47 +2644,43 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2, return 0; } -static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) +static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) { - unsigned int chans = channels; - const char *alpha2 = NULL; - const struct ieee80211_regdomain *regd = NULL; - bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; - bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; - bool destroy_on_close = info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; - bool use_chanctx; - bool no_vif = false; - const char *hwname = NULL; + struct hwsim_new_radio_params param = { 0 }; + + param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; + param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; + param.channels = channels; + param.destroy_on_close = + info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; if (info->attrs[HWSIM_ATTR_CHANNELS]) - chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); + param.channels = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); if (info->attrs[HWSIM_ATTR_NO_VIF]) - no_vif = true; + param.no_vif = true; if (info->attrs[HWSIM_ATTR_RADIO_NAME]) - hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); + param.hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) - use_chanctx = true; + param.use_chanctx = true; else - use_chanctx = (chans > 1); + param.use_chanctx = (param.channels > 1); if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) - alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); + param.reg_alpha2 = + nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) { u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]); if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom)) return -EINVAL; - regd = hwsim_world_regdom_custom[idx]; + param.regd = hwsim_world_regdom_custom[idx]; } - return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, - p2p_device, use_chanctx, - destroy_on_close, info->snd_portid, - hwname, no_vif); + return mac80211_hwsim_new_radio(info, ¶m); } static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) @@ -2616,9 +2736,9 @@ static const struct genl_ops hwsim_ops[] = { .doit = hwsim_tx_info_frame_received_nl, }, { - .cmd = HWSIM_CMD_CREATE_RADIO, + .cmd = HWSIM_CMD_NEW_RADIO, .policy = hwsim_genl_policy, - .doit = hwsim_create_radio_nl, + .doit = hwsim_new_radio_nl, .flags = GENL_ADMIN_PERM, }, { @@ -2682,7 +2802,9 @@ static int hwsim_init_netlink(void) printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); - rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops); + rc = genl_register_family_with_ops_groups(&hwsim_genl_family, + hwsim_ops, + hwsim_mcgrps); if (rc) goto failure; @@ -2743,69 +2865,73 @@ static int __init init_mac80211_hwsim(void) goto out_unregister_driver; } + err = hwsim_init_netlink(); + if (err < 0) + goto out_unregister_driver; + for (i = 0; i < radios; i++) { - const char *reg_alpha2 = NULL; - const struct ieee80211_regdomain *regd = NULL; - bool reg_strict = false; + struct hwsim_new_radio_params param = { 0 }; + + param.channels = channels; switch (regtest) { case HWSIM_REGTEST_DIFF_COUNTRY: if (i < ARRAY_SIZE(hwsim_alpha2s)) - reg_alpha2 = hwsim_alpha2s[i]; + param.reg_alpha2 = hwsim_alpha2s[i]; break; case HWSIM_REGTEST_DRIVER_REG_FOLLOW: if (!i) - reg_alpha2 = hwsim_alpha2s[0]; + param.reg_alpha2 = hwsim_alpha2s[0]; break; case HWSIM_REGTEST_STRICT_ALL: - reg_strict = true; + param.reg_strict = true; case HWSIM_REGTEST_DRIVER_REG_ALL: - reg_alpha2 = hwsim_alpha2s[0]; + param.reg_alpha2 = hwsim_alpha2s[0]; break; case HWSIM_REGTEST_WORLD_ROAM: if (i == 0) - regd = &hwsim_world_regdom_custom_01; + param.regd = &hwsim_world_regdom_custom_01; break; case HWSIM_REGTEST_CUSTOM_WORLD: - regd = &hwsim_world_regdom_custom_01; + param.regd = &hwsim_world_regdom_custom_01; break; case HWSIM_REGTEST_CUSTOM_WORLD_2: if (i == 0) - regd = &hwsim_world_regdom_custom_01; + param.regd = &hwsim_world_regdom_custom_01; else if (i == 1) - regd = &hwsim_world_regdom_custom_02; + param.regd = &hwsim_world_regdom_custom_02; break; case HWSIM_REGTEST_STRICT_FOLLOW: if (i == 0) { - reg_strict = true; - reg_alpha2 = hwsim_alpha2s[0]; + param.reg_strict = true; + param.reg_alpha2 = hwsim_alpha2s[0]; } break; case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: if (i == 0) { - reg_strict = true; - reg_alpha2 = hwsim_alpha2s[0]; + param.reg_strict = true; + param.reg_alpha2 = hwsim_alpha2s[0]; } else if (i == 1) { - reg_alpha2 = hwsim_alpha2s[1]; + param.reg_alpha2 = hwsim_alpha2s[1]; } break; case HWSIM_REGTEST_ALL: switch (i) { case 0: - regd = &hwsim_world_regdom_custom_01; + param.regd = &hwsim_world_regdom_custom_01; break; case 1: - regd = &hwsim_world_regdom_custom_02; + param.regd = &hwsim_world_regdom_custom_02; break; case 2: - reg_alpha2 = hwsim_alpha2s[0]; + param.reg_alpha2 = hwsim_alpha2s[0]; break; case 3: - reg_alpha2 = hwsim_alpha2s[1]; + param.reg_alpha2 = hwsim_alpha2s[1]; break; case 4: - reg_strict = true; - reg_alpha2 = hwsim_alpha2s[2]; + param.reg_strict = true; + param.reg_alpha2 = hwsim_alpha2s[2]; break; } break; @@ -2813,11 +2939,10 @@ static int __init init_mac80211_hwsim(void) break; } - err = mac80211_hwsim_create_radio(channels, reg_alpha2, - regd, reg_strict, - support_p2p_device, - channels > 1, false, 0, NULL, - false); + param.p2p_device = support_p2p_device; + param.use_chanctx = channels > 1; + + err = mac80211_hwsim_new_radio(NULL, ¶m); if (err < 0) goto out_free_radios; } @@ -2843,10 +2968,6 @@ static int __init init_mac80211_hwsim(void) } rtnl_unlock(); - err = hwsim_init_netlink(); - if (err < 0) - goto out_free_mon; - return 0; out_free_mon: -- GitLab From 579a05f29611dcef94b6bda21f1d059ab189a263 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 31 Oct 2014 14:48:48 +0200 Subject: [PATCH 2348/9457] mac80211-hwsim: Provide multicast event for HWSIM_CMD_DEL_RADIO When deleting old radio via HWSIM_CMD_DEL_RADIO then listeners on the multicast group "config" are informed. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 54 +++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 476c89cb06c9..209db62ee627 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2404,8 +2404,48 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, return err; } -static void mac80211_hwsim_destroy_radio(struct mac80211_hwsim_data *data) +static void hwsim_mcast_del_radio(int id, const char *hwname, + struct genl_info *info) { + struct sk_buff *skb; + void *data; + int ret; + + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return; + + data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, + HWSIM_CMD_DEL_RADIO); + if (!data) + goto error; + + ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id); + if (ret < 0) + goto error; + + if (hwname) { + ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(hwname), + hwname); + if (ret < 0) + goto error; + } + + genlmsg_end(skb, data); + + hwsim_mcast_config_msg(skb, info); + + return; + +error: + nlmsg_free(skb); +} + +static void mac80211_hwsim_del_radio(struct mac80211_hwsim_data *data, + const char *hwname, + struct genl_info *info) +{ + hwsim_mcast_del_radio(data->idx, hwname, info); debugfs_remove_recursive(data->debugfs); ieee80211_unregister_hw(data->hw); device_release_driver(data->dev); @@ -2423,7 +2463,7 @@ static void mac80211_hwsim_free(void) list))) { list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); - mac80211_hwsim_destroy_radio(data); + mac80211_hwsim_del_radio(data, NULL, NULL); spin_lock_bh(&hwsim_radio_lock); } spin_unlock_bh(&hwsim_radio_lock); @@ -2683,7 +2723,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) return mac80211_hwsim_new_radio(info, ¶m); } -static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) +static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) { struct mac80211_hwsim_data *data; s64 idx = -1; @@ -2709,7 +2749,7 @@ static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); - mac80211_hwsim_destroy_radio(data); + mac80211_hwsim_del_radio(data, hwname, info); return 0; } spin_unlock_bh(&hwsim_radio_lock); @@ -2742,9 +2782,9 @@ static const struct genl_ops hwsim_ops[] = { .flags = GENL_ADMIN_PERM, }, { - .cmd = HWSIM_CMD_DESTROY_RADIO, + .cmd = HWSIM_CMD_DEL_RADIO, .policy = hwsim_genl_policy, - .doit = hwsim_destroy_radio_nl, + .doit = hwsim_del_radio_nl, .flags = GENL_ADMIN_PERM, }, }; @@ -2754,7 +2794,7 @@ static void destroy_radio(struct work_struct *work) struct mac80211_hwsim_data *data = container_of(work, struct mac80211_hwsim_data, destroy_work); - mac80211_hwsim_destroy_radio(data); + mac80211_hwsim_del_radio(data, NULL, NULL); } static void remove_user_radios(u32 portid) -- GitLab From de4fcbadde68e3429cc533c29abf6fbceda4628f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 31 Oct 2014 14:16:12 +0100 Subject: [PATCH 2349/9457] cfg80211: avoid using default in interface type switch Most code avoids having a default case in interface type switch statements already, to make it easier to find places that need to be extended. Change the code in the __cfg80211_leave() and nl80211_key_allowed() functions to not have a default case. Signed-off-by: Johannes Berg --- net/wireless/core.c | 14 +++++++++++++- net/wireless/nl80211.c | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 87bb502bc8de..da4dcb65ade4 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -869,7 +869,19 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_P2P_GO: __cfg80211_stop_ap(rdev, dev, true); break; - default: + case NL80211_IFTYPE_WDS: + /* must be handled by mac80211/driver, has no APIs */ + break; + case NL80211_IFTYPE_P2P_DEVICE: + /* cannot happen, has no netdev */ + break; + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MONITOR: + /* nothing to do */ + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NUM_NL80211_IFTYPES: + /* invalid */ break; } } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 33aff7466f2f..f7d918858d32 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -884,7 +884,11 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) if (!wdev->current_bss) return -ENOLINK; break; - default: + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_WDS: + case NUM_NL80211_IFTYPES: return -EINVAL; } -- GitLab From e3a4bd5eec52912108e287146052f2624acbec7a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2014 14:45:04 +0100 Subject: [PATCH 2350/9457] ALSA: pcm: Simplify snd_pcm_action_lock_irq() The function snd_pcm_action_lock_irq() can be much simplified by simply wrapping snd_pcm_action() with the stream lock. This was rather the original idea, but later it was open coded for optimization. However, looking at the optimization part closely, one notices that the probability of the optimized path is quite low; in normal situations, the linked stream action happens only for the triggered substream, thus the operation becomes identical. So the code simplification has a clear win, especially because we have now doubly codes for both atomic and non-atomic locks. Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 4d5795d8b9f7..b92b605fc784 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -947,28 +947,6 @@ static int snd_pcm_action(struct action_ops *ops, return res; } -static int snd_pcm_action_lock_mutex(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - down_read(&snd_pcm_link_rwsem); - if (snd_pcm_stream_linked(substream)) { - mutex_lock(&substream->group->mutex); - mutex_lock(&substream->self_group.mutex); - res = snd_pcm_action_group(ops, substream, state, 1); - mutex_unlock(&substream->self_group.mutex); - mutex_unlock(&substream->group->mutex); - } else { - mutex_lock(&substream->self_group.mutex); - res = snd_pcm_action_single(ops, substream, state); - mutex_unlock(&substream->self_group.mutex); - } - up_read(&snd_pcm_link_rwsem); - return res; -} - /* * Note: don't use any locks before */ @@ -978,22 +956,9 @@ static int snd_pcm_action_lock_irq(struct action_ops *ops, { int res; - if (substream->pcm->nonatomic) - return snd_pcm_action_lock_mutex(ops, substream, state); - - read_lock_irq(&snd_pcm_link_rwlock); - if (snd_pcm_stream_linked(substream)) { - spin_lock(&substream->group->lock); - spin_lock(&substream->self_group.lock); - res = snd_pcm_action_group(ops, substream, state, 1); - spin_unlock(&substream->self_group.lock); - spin_unlock(&substream->group->lock); - } else { - spin_lock(&substream->self_group.lock); - res = snd_pcm_action_single(ops, substream, state); - spin_unlock(&substream->self_group.lock); - } - read_unlock_irq(&snd_pcm_link_rwlock); + snd_pcm_stream_lock_irq(substream); + res = snd_pcm_action(ops, substream, state); + snd_pcm_stream_unlock_irq(substream); return res; } -- GitLab From aa8edd8ca6a110349b00e360823c64e8cd106289 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2014 15:19:36 +0100 Subject: [PATCH 2351/9457] ALSA: pcm: Refactoring snd_pcm_action() Just a small code refactoring to reduce more lines. Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index b92b605fc784..ca224fa2a33a 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -900,14 +900,19 @@ static int snd_pcm_action_single(struct action_ops *ops, return res; } -/* call in mutex-protected context */ -static int snd_pcm_action_mutex(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) +/* + * Note: call with stream lock + */ +static int snd_pcm_action(struct action_ops *ops, + struct snd_pcm_substream *substream, + int state) { int res; - if (snd_pcm_stream_linked(substream)) { + if (!snd_pcm_stream_linked(substream)) + return snd_pcm_action_single(ops, substream, state); + + if (substream->pcm->nonatomic) { if (!mutex_trylock(&substream->group->mutex)) { mutex_unlock(&substream->self_group.mutex); mutex_lock(&substream->group->mutex); @@ -916,24 +921,6 @@ static int snd_pcm_action_mutex(struct action_ops *ops, res = snd_pcm_action_group(ops, substream, state, 1); mutex_unlock(&substream->group->mutex); } else { - res = snd_pcm_action_single(ops, substream, state); - } - return res; -} - -/* - * Note: call with stream lock - */ -static int snd_pcm_action(struct action_ops *ops, - struct snd_pcm_substream *substream, - int state) -{ - int res; - - if (substream->pcm->nonatomic) - return snd_pcm_action_mutex(ops, substream, state); - - if (snd_pcm_stream_linked(substream)) { if (!spin_trylock(&substream->group->lock)) { spin_unlock(&substream->self_group.lock); spin_lock(&substream->group->lock); @@ -941,8 +928,6 @@ static int snd_pcm_action(struct action_ops *ops, } res = snd_pcm_action_group(ops, substream, state, 1); spin_unlock(&substream->group->lock); - } else { - res = snd_pcm_action_single(ops, substream, state); } return res; } -- GitLab From f3bea49115b21e0995abf41402ad2f4d9c69eda4 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 2 Jul 2014 23:23:31 -0400 Subject: [PATCH 2352/9457] ftrace/x86: Add dynamic allocated trampoline for ftrace_ops The current method of handling multiple function callbacks is to register a list function callback that calls all the other callbacks based on their hash tables and compare it to the function that the callback was called on. But this is very inefficient. For example, if you are tracing all functions in the kernel and then add a kprobe to a function such that the kprobe uses ftrace, the mcount trampoline will switch from calling the function trace callback to calling the list callback that will iterate over all registered ftrace_ops (in this case, the function tracer and the kprobes callback). That means for every function being traced it checks the hash of the ftrace_ops for function tracing and kprobes, even though the kprobes is only set at a single function. The kprobes ftrace_ops is checked for every function being traced! Instead of calling the list function for functions that are only being traced by a single callback, we can call a dynamically allocated trampoline that calls the callback directly. The function graph tracer already uses a direct call trampoline when it is being traced by itself but it is not dynamically allocated. It's trampoline is static in the kernel core. The infrastructure that called the function graph trampoline can also be used to call a dynamically allocated one. For now, only ftrace_ops that are not dynamically allocated can have a trampoline. That is, users such as function tracer or stack tracer. kprobes and perf allocate their ftrace_ops, and until there's a safe way to free the trampoline, it can not be used. The dynamically allocated ftrace_ops may, although, use the trampoline if the kernel is not compiled with CONFIG_PREEMPT. But that will come later. Tested-by: Masami Hiramatsu Tested-by: Jiri Kosina Signed-off-by: Steven Rostedt --- arch/x86/kernel/ftrace.c | 195 ++++++++++++++++++++++++++++++++++-- arch/x86/kernel/mcount_64.S | 25 ++++- include/linux/ftrace.h | 8 ++ kernel/trace/ftrace.c | 40 +++++++- 4 files changed, 254 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 3386dc9aa333..e4d48f6cad86 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -644,13 +645,8 @@ int __init ftrace_dyn_arch_init(void) { return 0; } -#endif - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - -#ifdef CONFIG_DYNAMIC_FTRACE -extern void ftrace_graph_call(void); +#if defined(CONFIG_X86_64) || defined(CONFIG_FUNCTION_GRAPH_TRACER) static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr) { static union ftrace_code_union calc; @@ -664,6 +660,193 @@ static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr) */ return calc.code; } +#endif + +/* Currently only x86_64 supports dynamic trampolines */ +#ifdef CONFIG_X86_64 + +#ifdef CONFIG_MODULES +#include +/* Module allocation simplifies allocating memory for code */ +static inline void *alloc_tramp(unsigned long size) +{ + return module_alloc(size); +} +static inline void tramp_free(void *tramp) +{ + module_free(NULL, tramp); +} +#else +/* Trampolines can only be created if modules are supported */ +static inline void *alloc_tramp(unsigned long size) +{ + return NULL; +} +static inline void tramp_free(void *tramp) { } +#endif + +/* Defined as markers to the end of the ftrace default trampolines */ +extern void ftrace_caller_end(void); +extern void ftrace_regs_caller_end(void); +extern void ftrace_return(void); +extern void ftrace_caller_op_ptr(void); +extern void ftrace_regs_caller_op_ptr(void); + +/* movq function_trace_op(%rip), %rdx */ +/* 0x48 0x8b 0x15 */ +#define OP_REF_SIZE 7 + +/* + * The ftrace_ops is passed to the function callback. Since the + * trampoline only services a single ftrace_ops, we can pass in + * that ops directly. + * + * The ftrace_op_code_union is used to create a pointer to the + * ftrace_ops that will be passed to the callback function. + */ +union ftrace_op_code_union { + char code[OP_REF_SIZE]; + struct { + char op[3]; + int offset; + } __attribute__((packed)); +}; + +static unsigned long create_trampoline(struct ftrace_ops *ops) +{ + unsigned const char *jmp; + unsigned long start_offset; + unsigned long end_offset; + unsigned long op_offset; + unsigned long offset; + unsigned long size; + unsigned long ip; + unsigned long *ptr; + void *trampoline; + /* 48 8b 15 is movq (%rip), %rdx */ + unsigned const char op_ref[] = { 0x48, 0x8b, 0x15 }; + union ftrace_op_code_union op_ptr; + int ret; + + if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { + start_offset = (unsigned long)ftrace_regs_caller; + end_offset = (unsigned long)ftrace_regs_caller_end; + op_offset = (unsigned long)ftrace_regs_caller_op_ptr; + } else { + start_offset = (unsigned long)ftrace_caller; + end_offset = (unsigned long)ftrace_caller_end; + op_offset = (unsigned long)ftrace_caller_op_ptr; + } + + size = end_offset - start_offset; + + /* + * Allocate enough size to store the ftrace_caller code, + * the jmp to ftrace_return, as well as the address of + * the ftrace_ops this trampoline is used for. + */ + trampoline = alloc_tramp(size + MCOUNT_INSN_SIZE + sizeof(void *)); + if (!trampoline) + return 0; + + /* Copy ftrace_caller onto the trampoline memory */ + ret = probe_kernel_read(trampoline, (void *)start_offset, size); + if (WARN_ON(ret < 0)) { + tramp_free(trampoline); + return 0; + } + + ip = (unsigned long)trampoline + size; + + /* The trampoline ends with a jmp to ftrace_return */ + jmp = ftrace_jmp_replace(ip, (unsigned long)ftrace_return); + memcpy(trampoline + size, jmp, MCOUNT_INSN_SIZE); + + /* + * The address of the ftrace_ops that is used for this trampoline + * is stored at the end of the trampoline. This will be used to + * load the third parameter for the callback. Basically, that + * location at the end of the trampoline takes the place of + * the global function_trace_op variable. + */ + + ptr = (unsigned long *)(trampoline + size + MCOUNT_INSN_SIZE); + *ptr = (unsigned long)ops; + + op_offset -= start_offset; + memcpy(&op_ptr, trampoline + op_offset, OP_REF_SIZE); + + /* Are we pointing to the reference? */ + if (WARN_ON(memcmp(op_ptr.op, op_ref, 3) != 0)) { + tramp_free(trampoline); + return 0; + } + + /* Load the contents of ptr into the callback parameter */ + offset = (unsigned long)ptr; + offset -= (unsigned long)trampoline + op_offset + OP_REF_SIZE; + + op_ptr.offset = offset; + + /* put in the new offset to the ftrace_ops */ + memcpy(trampoline + op_offset, &op_ptr, OP_REF_SIZE); + + /* ALLOC_TRAMP flags lets us know we created it */ + ops->flags |= FTRACE_OPS_FL_ALLOC_TRAMP; + + return (unsigned long)trampoline; +} + +void arch_ftrace_update_trampoline(struct ftrace_ops *ops) +{ + ftrace_func_t func; + unsigned char *new; + unsigned long start_offset; + unsigned long call_offset; + unsigned long offset; + unsigned long ip; + int ret; + + if (ops->trampoline) { + /* + * The ftrace_ops caller may set up its own trampoline. + * In such a case, this code must not modify it. + */ + if (!(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP)) + return; + } else { + ops->trampoline = create_trampoline(ops); + if (!ops->trampoline) + return; + } + + if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { + start_offset = (unsigned long)ftrace_regs_caller; + call_offset = (unsigned long)ftrace_regs_call; + } else { + start_offset = (unsigned long)ftrace_caller; + call_offset = (unsigned long)ftrace_call; + } + + offset = call_offset - start_offset; + ip = ops->trampoline + offset; + + func = ftrace_ops_get_func(ops); + + /* Do a safe modify in case the trampoline is executing */ + new = ftrace_call_replace(ip, (unsigned long)func); + ret = update_ftrace_func(ip, new); + + /* The update should never fail */ + WARN_ON(ret); +} +#endif /* CONFIG_X86_64 */ +#endif /* CONFIG_DYNAMIC_FTRACE */ + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +#ifdef CONFIG_DYNAMIC_FTRACE +extern void ftrace_graph_call(void); static int ftrace_mod_jmp(unsigned long ip, void *func) { diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S index c73aecf10d34..42f0cdd20baf 100644 --- a/arch/x86/kernel/mcount_64.S +++ b/arch/x86/kernel/mcount_64.S @@ -28,9 +28,11 @@ ENTRY(function_hook) END(function_hook) /* skip is set if stack has been adjusted */ -.macro ftrace_caller_setup skip=0 +.macro ftrace_caller_setup trace_label skip=0 MCOUNT_SAVE_FRAME \skip + /* Save this location */ +GLOBAL(\trace_label) /* Load the ftrace_ops into the 3rd parameter */ movq function_trace_op(%rip), %rdx @@ -46,7 +48,7 @@ END(function_hook) .endm ENTRY(ftrace_caller) - ftrace_caller_setup + ftrace_caller_setup ftrace_caller_op_ptr /* regs go into 4th parameter (but make it NULL) */ movq $0, %rcx @@ -54,7 +56,14 @@ GLOBAL(ftrace_call) call ftrace_stub MCOUNT_RESTORE_FRAME -ftrace_return: + + /* + * The copied trampoline must call ftrace_return as it + * still may need to call the function graph tracer. + */ +GLOBAL(ftrace_caller_end) + +GLOBAL(ftrace_return) #ifdef CONFIG_FUNCTION_GRAPH_TRACER GLOBAL(ftrace_graph_call) @@ -70,7 +79,7 @@ ENTRY(ftrace_regs_caller) pushfq /* skip=8 to skip flags saved in SS */ - ftrace_caller_setup 8 + ftrace_caller_setup ftrace_regs_caller_op_ptr 8 /* Save the rest of pt_regs */ movq %r15, R15(%rsp) @@ -122,6 +131,14 @@ GLOBAL(ftrace_regs_call) /* Restore flags */ popfq + /* + * As this jmp to ftrace_return can be a short jump + * it must not be copied into the trampoline. + * The trampoline will add the code to jump + * to the return. + */ +GLOBAL(ftrace_regs_caller_end) + jmp ftrace_return popfq diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 662697babd48..06e3ca5a5083 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -94,6 +94,13 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops); * ADDING - The ops is in the process of being added. * REMOVING - The ops is in the process of being removed. * MODIFYING - The ops is in the process of changing its filter functions. + * ALLOC_TRAMP - A dynamic trampoline was allocated by the core code. + * The arch specific code sets this flag when it allocated a + * trampoline. This lets the arch know that it can update the + * trampoline in case the callback function changes. + * The ftrace_ops trampoline can be set by the ftrace users, and + * in such cases the arch must not modify it. Only the arch ftrace + * core code should set this flag. */ enum { FTRACE_OPS_FL_ENABLED = 1 << 0, @@ -108,6 +115,7 @@ enum { FTRACE_OPS_FL_ADDING = 1 << 9, FTRACE_OPS_FL_REMOVING = 1 << 10, FTRACE_OPS_FL_MODIFYING = 1 << 11, + FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12, }; #ifdef CONFIG_DYNAMIC_FTRACE diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 31c90fec4158..15f85eac7e95 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -387,6 +387,8 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list, return ret; } +static void ftrace_update_trampoline(struct ftrace_ops *ops); + static int __register_ftrace_function(struct ftrace_ops *ops) { if (ops->flags & FTRACE_OPS_FL_DELETED) @@ -419,6 +421,8 @@ static int __register_ftrace_function(struct ftrace_ops *ops) } else add_ftrace_ops(&ftrace_ops_list, ops); + ftrace_update_trampoline(ops); + if (ftrace_enabled) update_ftrace_function(); @@ -3020,9 +3024,6 @@ ftrace_enabled_open(struct inode *inode, struct file *file) { struct ftrace_iterator *iter; - if (unlikely(ftrace_disabled)) - return -ENODEV; - iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); if (iter) { iter->pg = ftrace_pages_start; @@ -3975,6 +3976,9 @@ static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; static char ftrace_graph_notrace_buf[FTRACE_FILTER_SIZE] __initdata; static int ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer); +static unsigned long save_global_trampoline; +static unsigned long save_global_flags; + static int __init set_graph_function(char *str) { strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE); @@ -4696,6 +4700,20 @@ void __init ftrace_init(void) ftrace_disabled = 1; } +/* Do nothing if arch does not support this */ +void __weak arch_ftrace_update_trampoline(struct ftrace_ops *ops) +{ +} + +static void ftrace_update_trampoline(struct ftrace_ops *ops) +{ + /* Currently, only non dynamic ops can have a trampoline */ + if (ops->flags & FTRACE_OPS_FL_DYNAMIC) + return; + + arch_ftrace_update_trampoline(ops); +} + #else static struct ftrace_ops global_ops = { @@ -4738,6 +4756,10 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) return 1; } +static void ftrace_update_trampoline(struct ftrace_ops *ops) +{ +} + #endif /* CONFIG_DYNAMIC_FTRACE */ __init void ftrace_init_global_array_ops(struct trace_array *tr) @@ -5522,7 +5544,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, update_function_graph_func(); ret = ftrace_startup(&graph_ops, FTRACE_START_FUNC_RET); - out: mutex_unlock(&ftrace_lock); return ret; @@ -5543,6 +5564,17 @@ void unregister_ftrace_graph(void) unregister_pm_notifier(&ftrace_suspend_notifier); unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); +#ifdef CONFIG_DYNAMIC_FTRACE + /* + * Function graph does not allocate the trampoline, but + * other global_ops do. We need to reset the ALLOC_TRAMP flag + * if one was used. + */ + global_ops.trampoline = save_global_trampoline; + if (save_global_flags & FTRACE_OPS_FL_ALLOC_TRAMP) + global_ops.flags |= FTRACE_OPS_FL_ALLOC_TRAMP; +#endif + out: mutex_unlock(&ftrace_lock); } -- GitLab From 15d5b02cc575e5b20ddfa1645fc1242f0b0ba1c8 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 3 Jul 2014 14:51:36 -0400 Subject: [PATCH 2353/9457] ftrace/x86: Show trampoline call function in enabled_functions The file /sys/kernel/debug/tracing/eneabled_functions is used to debug ftrace function hooks. Add to the output what function is being called by the trampoline if the arch supports it. Add support for this feature in x86_64. Cc: H. Peter Anvin Tested-by: Masami Hiramatsu Tested-by: Jiri Kosina Signed-off-by: Steven Rostedt --- arch/x86/kernel/ftrace.c | 98 +++++++++++++++++++++++++++++++++++----- kernel/trace/ftrace.c | 22 ++++++++- 2 files changed, 106 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index e4d48f6cad86..ca17c20a1010 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -48,7 +48,7 @@ int ftrace_arch_code_modify_post_process(void) union ftrace_code_union { char code[MCOUNT_INSN_SIZE]; struct { - char e8; + unsigned char e8; int offset; } __attribute__((packed)); }; @@ -797,12 +797,26 @@ static unsigned long create_trampoline(struct ftrace_ops *ops) return (unsigned long)trampoline; } +static unsigned long calc_trampoline_call_offset(bool save_regs) +{ + unsigned long start_offset; + unsigned long call_offset; + + if (save_regs) { + start_offset = (unsigned long)ftrace_regs_caller; + call_offset = (unsigned long)ftrace_regs_call; + } else { + start_offset = (unsigned long)ftrace_caller; + call_offset = (unsigned long)ftrace_call; + } + + return call_offset - start_offset; +} + void arch_ftrace_update_trampoline(struct ftrace_ops *ops) { ftrace_func_t func; unsigned char *new; - unsigned long start_offset; - unsigned long call_offset; unsigned long offset; unsigned long ip; int ret; @@ -820,15 +834,7 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops) return; } - if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { - start_offset = (unsigned long)ftrace_regs_caller; - call_offset = (unsigned long)ftrace_regs_call; - } else { - start_offset = (unsigned long)ftrace_caller; - call_offset = (unsigned long)ftrace_call; - } - - offset = call_offset - start_offset; + offset = calc_trampoline_call_offset(ops->flags & FTRACE_OPS_FL_SAVE_REGS); ip = ops->trampoline + offset; func = ftrace_ops_get_func(ops); @@ -840,6 +846,74 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops) /* The update should never fail */ WARN_ON(ret); } + +/* Return the address of the function the trampoline calls */ +static void *addr_from_call(void *ptr) +{ + union ftrace_code_union calc; + int ret; + + ret = probe_kernel_read(&calc, ptr, MCOUNT_INSN_SIZE); + if (WARN_ON_ONCE(ret < 0)) + return NULL; + + /* Make sure this is a call */ + if (WARN_ON_ONCE(calc.e8 != 0xe8)) { + pr_warn("Expected e8, got %x\n", calc.e8); + return NULL; + } + + return ptr + MCOUNT_INSN_SIZE + calc.offset; +} + +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer); + +/* + * If the ops->trampoline was not allocated, then it probably + * has a static trampoline func, or is the ftrace caller itself. + */ +static void *static_tramp_func(struct ftrace_ops *ops, struct dyn_ftrace *rec) +{ + unsigned long offset; + bool save_regs = rec->flags & FTRACE_FL_REGS_EN; + void *ptr; + + if (ops && ops->trampoline) { +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + /* + * We only know about function graph tracer setting as static + * trampoline. + */ + if (ops->trampoline == FTRACE_GRAPH_ADDR) + return (void *)prepare_ftrace_return; +#endif + return NULL; + } + + offset = calc_trampoline_call_offset(save_regs); + + if (save_regs) + ptr = (void *)FTRACE_REGS_ADDR + offset; + else + ptr = (void *)FTRACE_ADDR + offset; + + return addr_from_call(ptr); +} + +void *arch_ftrace_trampoline_func(struct ftrace_ops *ops, struct dyn_ftrace *rec) +{ + unsigned long offset; + + /* If we didn't allocate this trampoline, consider it static */ + if (!ops || !(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP)) + return static_tramp_func(ops, rec); + + offset = calc_trampoline_call_offset(ops->flags & FTRACE_OPS_FL_SAVE_REGS); + return addr_from_call((void *)ops->trampoline + offset); +} + + #endif /* CONFIG_X86_64 */ #endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 15f85eac7e95..422e1f8300b1 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2952,6 +2952,22 @@ static void t_stop(struct seq_file *m, void *p) mutex_unlock(&ftrace_lock); } +void * __weak +arch_ftrace_trampoline_func(struct ftrace_ops *ops, struct dyn_ftrace *rec) +{ + return NULL; +} + +static void add_trampoline_func(struct seq_file *m, struct ftrace_ops *ops, + struct dyn_ftrace *rec) +{ + void *ptr; + + ptr = arch_ftrace_trampoline_func(ops, rec); + if (ptr) + seq_printf(m, " ->%pS", ptr); +} + static int t_show(struct seq_file *m, void *v) { struct ftrace_iterator *iter = m->private; @@ -2975,19 +2991,21 @@ static int t_show(struct seq_file *m, void *v) seq_printf(m, "%ps", (void *)rec->ip); if (iter->flags & FTRACE_ITER_ENABLED) { + struct ftrace_ops *ops = NULL; + seq_printf(m, " (%ld)%s", ftrace_rec_count(rec), rec->flags & FTRACE_FL_REGS ? " R" : " "); if (rec->flags & FTRACE_FL_TRAMP_EN) { - struct ftrace_ops *ops; - ops = ftrace_find_tramp_ops_any(rec); if (ops) seq_printf(m, "\ttramp: %pS", (void *)ops->trampoline); else seq_printf(m, "\ttramp: ERROR!"); + } + add_trampoline_func(m, ops, rec); } seq_printf(m, "\n"); -- GitLab From ca96ea86eed4b2645637dfe3d38b7d05191a79fe Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 31 Oct 2014 09:26:16 -0700 Subject: [PATCH 2354/9457] Input: add driver for the Goodix touchpanel Add a driver for the Goodix touchscreen panel found in Onda v975w tablets. The driver is based off the Android driver gt9xx.c found in some Android code dumps, but now bears no resemblance to the original driver. The driver was tested on the aforementioned tablet. Signed-off-by: Bastien Nocera Tested-by: Bastien Nocera Signed-off-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 6 + drivers/input/touchscreen/Kconfig | 13 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/goodix.c | 395 +++++++++++++++++++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 drivers/input/touchscreen/goodix.c diff --git a/MAINTAINERS b/MAINTAINERS index f10ed3914ea8..f73bb4179832 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4062,6 +4062,12 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/usb/go7007/ +GOODIX TOUCHSCREEN +M: Bastien Nocera +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/input/touchscreen/goodix.c + GPIO SUBSYSTEM M: Linus Walleij M: Alexandre Courbot diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index e1d8003d01f8..568a0200fbc2 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -295,6 +295,19 @@ config TOUCHSCREEN_FUJITSU To compile this driver as a module, choose M here: the module will be called fujitsu-ts. +config TOUCHSCREEN_GOODIX + tristate "Goodix I2C touchscreen" + depends on I2C && ACPI + help + Say Y here if you have the Goodix touchscreen (such as one + installed in Onda v975w tablets) connected to your + system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called goodix. + config TOUCHSCREEN_ILI210X tristate "Ilitek ILI210X based touchscreen" depends on I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 090e61cc9171..dab4a56ac98e 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o +obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c new file mode 100644 index 000000000000..ca196689f025 --- /dev/null +++ b/drivers/input/touchscreen/goodix.c @@ -0,0 +1,395 @@ +/* + * Driver for Goodix Touchscreens + * + * Copyright (c) 2014 Red Hat Inc. + * + * This code is based on gt9xx.c authored by andrew@goodix.com: + * + * 2010 - 2012 Goodix Technology. + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct goodix_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + int abs_x_max; + int abs_y_max; + unsigned int max_touch_num; + unsigned int int_trigger_type; +}; + +#define GOODIX_MAX_HEIGHT 4096 +#define GOODIX_MAX_WIDTH 4096 +#define GOODIX_INT_TRIGGER 1 +#define GOODIX_CONTACT_SIZE 8 +#define GOODIX_MAX_CONTACTS 10 + +#define GOODIX_CONFIG_MAX_LENGTH 240 + +/* Register defines */ +#define GOODIX_READ_COOR_ADDR 0x814E +#define GOODIX_REG_CONFIG_DATA 0x8047 +#define GOODIX_REG_VERSION 0x8140 + +#define RESOLUTION_LOC 1 +#define TRIGGER_LOC 6 + +static const unsigned long goodix_irq_flags[] = { + IRQ_TYPE_EDGE_RISING, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_LEVEL_LOW, + IRQ_TYPE_LEVEL_HIGH, +}; + +/** + * goodix_i2c_read - read data from a register of the i2c slave device. + * + * @client: i2c device. + * @reg: the register to read from. + * @buf: raw write data buffer. + * @len: length of the buffer to write + */ +static int goodix_i2c_read(struct i2c_client *client, + u16 reg, u8 *buf, int len) +{ + struct i2c_msg msgs[2]; + u16 wbuf = cpu_to_be16(reg); + int ret; + + msgs[0].flags = 0; + msgs[0].addr = client->addr; + msgs[0].len = 2; + msgs[0].buf = (u8 *) &wbuf; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len; + msgs[1].buf = buf; + + ret = i2c_transfer(client->adapter, msgs, 2); + return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); +} + +static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) +{ + int touch_num; + int error; + + error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data, + GOODIX_CONTACT_SIZE + 1); + if (error) { + dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); + return error; + } + + touch_num = data[0] & 0x0f; + if (touch_num > GOODIX_MAX_CONTACTS) + return -EPROTO; + + if (touch_num > 1) { + data += 1 + GOODIX_CONTACT_SIZE; + error = goodix_i2c_read(ts->client, + GOODIX_READ_COOR_ADDR + + 1 + GOODIX_CONTACT_SIZE, + data, + GOODIX_CONTACT_SIZE * (touch_num - 1)); + if (error) + return error; + } + + return touch_num; +} + +static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) +{ + int id = coor_data[0] & 0x0F; + int input_x = get_unaligned_le16(&coor_data[1]); + int input_y = get_unaligned_le16(&coor_data[3]); + int input_w = get_unaligned_le16(&coor_data[5]); + + input_mt_slot(ts->input_dev, id); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); +} + +/** + * goodix_process_events - Process incoming events + * + * @ts: our goodix_ts_data pointer + * + * Called when the IRQ is triggered. Read the current device state, and push + * the input events to the user space. + */ +static void goodix_process_events(struct goodix_ts_data *ts) +{ + u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; + int touch_num; + int i; + + touch_num = goodix_ts_read_input_report(ts, point_data); + if (touch_num < 0) + return; + + for (i = 0; i < touch_num; i++) + goodix_ts_report_touch(ts, + &point_data[1 + GOODIX_CONTACT_SIZE * i]); + + input_mt_sync_frame(ts->input_dev); + input_sync(ts->input_dev); +} + +/** + * goodix_ts_irq_handler - The IRQ handler + * + * @irq: interrupt number. + * @dev_id: private data pointer. + */ +static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +{ + static const u8 end_cmd[] = { + GOODIX_READ_COOR_ADDR >> 8, + GOODIX_READ_COOR_ADDR & 0xff, + 0 + }; + struct goodix_ts_data *ts = dev_id; + + goodix_process_events(ts); + + if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0) + dev_err(&ts->client->dev, "I2C write end_cmd error\n"); + + return IRQ_HANDLED; +} + +/** + * goodix_read_config - Read the embedded configuration of the panel + * + * @ts: our goodix_ts_data pointer + * + * Must be called during probe + */ +static void goodix_read_config(struct goodix_ts_data *ts) +{ + u8 config[GOODIX_CONFIG_MAX_LENGTH]; + int error; + + error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA, + config, + GOODIX_CONFIG_MAX_LENGTH); + if (error) { + dev_warn(&ts->client->dev, + "Error reading config (%d), using defaults\n", + error); + ts->abs_x_max = GOODIX_MAX_WIDTH; + ts->abs_y_max = GOODIX_MAX_HEIGHT; + ts->int_trigger_type = GOODIX_INT_TRIGGER; + return; + } + + ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); + ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); + ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; + if (!ts->abs_x_max || !ts->abs_y_max) { + dev_err(&ts->client->dev, + "Invalid config, using defaults\n"); + ts->abs_x_max = GOODIX_MAX_WIDTH; + ts->abs_y_max = GOODIX_MAX_HEIGHT; + } +} + + +/** + * goodix_read_version - Read goodix touchscreen version + * + * @client: the i2c client + * @version: output buffer containing the version on success + */ +static int goodix_read_version(struct i2c_client *client, u16 *version) +{ + int error; + u8 buf[6]; + + error = goodix_i2c_read(client, GOODIX_REG_VERSION, buf, sizeof(buf)); + if (error) { + dev_err(&client->dev, "read version failed: %d\n", error); + return error; + } + + if (version) + *version = get_unaligned_le16(&buf[4]); + + dev_info(&client->dev, "IC VERSION: %6ph\n", buf); + + return 0; +} + +/** + * goodix_i2c_test - I2C test function to check if the device answers. + * + * @client: the i2c client + */ +static int goodix_i2c_test(struct i2c_client *client) +{ + int retry = 0; + int error; + u8 test; + + while (retry++ < 2) { + error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA, + &test, 1); + if (!error) + return 0; + + dev_err(&client->dev, "i2c test failed attempt %d: %d\n", + retry, error); + msleep(20); + } + + return error; +} + +/** + * goodix_request_input_dev - Allocate, populate and register the input device + * + * @ts: our goodix_ts_data pointer + * + * Must be called during probe + */ +static int goodix_request_input_dev(struct goodix_ts_data *ts) +{ + int error; + + ts->input_dev = devm_input_allocate_device(&ts->client->dev); + if (!ts->input_dev) { + dev_err(&ts->client->dev, "Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | + BIT_MASK(EV_KEY) | + BIT_MASK(EV_ABS); + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, + ts->abs_x_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, + ts->abs_y_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + + input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + + ts->input_dev->name = "Goodix Capacitive TouchScreen"; + ts->input_dev->phys = "input/ts"; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0x0416; + ts->input_dev->id.product = 0x1001; + ts->input_dev->id.version = 10427; + + error = input_register_device(ts->input_dev); + if (error) { + dev_err(&ts->client->dev, + "Failed to register input device: %d", error); + return error; + } + + return 0; +} + +static int goodix_ts_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct goodix_ts_data *ts; + unsigned long irq_flags; + int error; + u16 version_info; + + dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C check functionality failed.\n"); + return -ENXIO; + } + + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + ts->client = client; + i2c_set_clientdata(client, ts); + + error = goodix_i2c_test(client); + if (error) { + dev_err(&client->dev, "I2C communication failure: %d\n", error); + return error; + } + + error = goodix_read_version(client, &version_info); + if (error) { + dev_err(&client->dev, "Read version failed.\n"); + return error; + } + + goodix_read_config(ts); + + error = goodix_request_input_dev(ts); + if (error) + return error; + + irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; + error = devm_request_threaded_irq(&ts->client->dev, client->irq, + NULL, goodix_ts_irq_handler, + irq_flags, client->name, ts); + if (error) { + dev_err(&client->dev, "request IRQ failed: %d\n", error); + return error; + } + + return 0; +} + +static const struct i2c_device_id goodix_ts_id[] = { + { "GDIX1001:00", 0 }, + { } +}; + +static const struct acpi_device_id goodix_acpi_match[] = { + { "GDIX1001", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); + +static struct i2c_driver goodix_ts_driver = { + .probe = goodix_ts_probe, + .id_table = goodix_ts_id, + .driver = { + .name = "Goodix-TS", + .owner = THIS_MODULE, + .acpi_match_table = goodix_acpi_match, + }, +}; +module_i2c_driver(goodix_ts_driver); + +MODULE_AUTHOR("Benjamin Tissoires "); +MODULE_AUTHOR("Bastien Nocera "); +MODULE_DESCRIPTION("Goodix touchscreen driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From a823c26790467da8504f116c725d092d7ac88588 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 31 Oct 2014 09:16:51 -0700 Subject: [PATCH 2355/9457] Input: altera_ps2 - switch to using managed resources Use them devm_ managed resources API to simplify error handling in altera_ps2_probe() and to reduce the size of altera_ps2_remove() and the ps2if struct. Signed-off-by: Tobias Klauser Signed-off-by: Dmitry Torokhov --- drivers/input/serio/altera_ps2.c | 81 ++++++++++---------------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index cce69d6b9587..b74fc2fef869 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -24,9 +24,7 @@ struct ps2if { struct serio *io; - struct resource *iomem_res; void __iomem *base; - unsigned irq; }; /* @@ -83,16 +81,34 @@ static void altera_ps2_close(struct serio *io) static int altera_ps2_probe(struct platform_device *pdev) { struct ps2if *ps2if; + struct resource *res; struct serio *serio; int error, irq; - ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); - if (!ps2if || !serio) { - error = -ENOMEM; - goto err_free_mem; + ps2if = devm_kzalloc(&pdev->dev, sizeof(struct ps2if), GFP_KERNEL); + if (!ps2if) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ps2if->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ps2if->base)) + return PTR_ERR(ps2if->base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENXIO; + + error = devm_request_irq(&pdev->dev, irq, altera_ps2_rxint, 0, + pdev->name, ps2if); + if (error) { + dev_err(&pdev->dev, "could not request IRQ %d\n", irq); + return error; } + serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!serio) + return -ENOMEM; + serio->id.type = SERIO_8042; serio->write = altera_ps2_write; serio->open = altera_ps2_open; @@ -103,56 +119,12 @@ static int altera_ps2_probe(struct platform_device *pdev) serio->dev.parent = &pdev->dev; ps2if->io = serio; - ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (ps2if->iomem_res == NULL) { - error = -ENOENT; - goto err_free_mem; - } - - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - error = -ENXIO; - goto err_free_mem; - } - ps2if->irq = irq; - - if (!request_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res), pdev->name)) { - error = -EBUSY; - goto err_free_mem; - } - - ps2if->base = ioremap(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - if (!ps2if->base) { - error = -ENOMEM; - goto err_free_res; - } - - error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if); - if (error) { - dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n", - ps2if->irq, error); - goto err_unmap; - } - - dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq); + dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, irq); serio_register_port(ps2if->io); platform_set_drvdata(pdev, ps2if); return 0; - - err_unmap: - iounmap(ps2if->base); - err_free_res: - release_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - err_free_mem: - kfree(ps2if); - kfree(serio); - return error; } /* @@ -163,11 +135,6 @@ static int altera_ps2_remove(struct platform_device *pdev) struct ps2if *ps2if = platform_get_drvdata(pdev); serio_unregister_port(ps2if->io); - free_irq(ps2if->irq, ps2if); - iounmap(ps2if->base); - release_mem_region(ps2if->iomem_res->start, - resource_size(ps2if->iomem_res)); - kfree(ps2if); return 0; } -- GitLab From 3172fcddcea230f129e8916628672617ef3c836c Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:44 +0530 Subject: [PATCH 2356/9457] ASoC: Intel: mfld-pcm: Fix to Store device context in sst_data Some debug prints use dev context in sst_data. Store the device context for the same. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform-pcm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index e7cf18d1d421..6032f18693be 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -706,6 +706,7 @@ static int sst_platform_probe(struct platform_device *pdev) pdata->pdev_strm_map = dpcm_strm_map; pdata->strm_map_size = ARRAY_SIZE(dpcm_strm_map); drv->pdata = pdata; + drv->pdev = pdev; mutex_init(&drv->lock); dev_set_drvdata(&pdev->dev, drv); -- GitLab From 7e73e4d80539d0392010dfac3116307e7c9cf33d Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:45 +0530 Subject: [PATCH 2357/9457] ASoC: Intel: move the driver wq init to a routine This will be used by ACPI code as well, so moving to common routine helps Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index fdada405eda7..f9a6d6d117d6 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -206,6 +206,22 @@ void sst_process_pending_msg(struct work_struct *work) ctx->ops->post_message(ctx, NULL, false); } +static int sst_workqueue_init(struct intel_sst_drv *ctx) +{ + INIT_LIST_HEAD(&ctx->memcpy_list); + INIT_LIST_HEAD(&ctx->rx_list); + INIT_LIST_HEAD(&ctx->ipc_dispatch_list); + INIT_LIST_HEAD(&ctx->block_list); + INIT_WORK(&ctx->ipc_post_msg_wq, sst_process_pending_msg); + init_waitqueue_head(&ctx->wait_queue); + + ctx->post_msg_wq = + create_singlethread_workqueue("sst_post_msg_wq"); + if (!ctx->post_msg_wq) + return -EBUSY; + return 0; +} + /* * intel_sst_probe - PCI probe function * @@ -254,24 +270,13 @@ static int intel_sst_probe(struct pci_dev *pci, sst_drv_ctx->use_dma = 0; sst_drv_ctx->use_lli = 0; - INIT_LIST_HEAD(&sst_drv_ctx->memcpy_list); - INIT_LIST_HEAD(&sst_drv_ctx->ipc_dispatch_list); - INIT_LIST_HEAD(&sst_drv_ctx->block_list); - INIT_LIST_HEAD(&sst_drv_ctx->rx_list); - - sst_drv_ctx->post_msg_wq = - create_singlethread_workqueue("sst_post_msg_wq"); - if (!sst_drv_ctx->post_msg_wq) { - ret = -EINVAL; - goto do_free_drv_ctx; - } - INIT_WORK(&sst_drv_ctx->ipc_post_msg_wq, sst_process_pending_msg); - init_waitqueue_head(&sst_drv_ctx->wait_queue); - spin_lock_init(&sst_drv_ctx->ipc_spin_lock); spin_lock_init(&sst_drv_ctx->block_lock); spin_lock_init(&sst_drv_ctx->rx_msg_lock); + if (sst_workqueue_init(sst_drv_ctx)) + return -EINVAL; + dev_info(sst_drv_ctx->dev, "Got drv data max stream %d\n", sst_drv_ctx->info.max_streams); for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) { @@ -414,7 +419,6 @@ static int intel_sst_probe(struct pci_dev *pci, pci_release_regions(pci); do_free_mem: destroy_workqueue(sst_drv_ctx->post_msg_wq); -do_free_drv_ctx: dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); return ret; } -- GitLab From 54adc0ad647792b3a8557520477a40f76d99a007 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:46 +0530 Subject: [PATCH 2358/9457] ASoC: Intel: move the lock and wq initialization to routine This will be used by ACPI code as well, so moving to common routine helps Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index f9a6d6d117d6..0863471a2c86 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -222,6 +222,14 @@ static int sst_workqueue_init(struct intel_sst_drv *ctx) return 0; } +static void sst_init_locks(struct intel_sst_drv *ctx) +{ + mutex_init(&ctx->sst_lock); + spin_lock_init(&ctx->rx_msg_lock); + spin_lock_init(&ctx->ipc_spin_lock); + spin_lock_init(&ctx->block_lock); +} + /* * intel_sst_probe - PCI probe function * @@ -259,7 +267,7 @@ static int intel_sst_probe(struct pci_dev *pci, return -EINVAL; ops = sst_drv_ctx->ops; - mutex_init(&sst_drv_ctx->sst_lock); + sst_init_locks(sst_drv_ctx); /* pvt_id 0 reserved for async messages */ sst_drv_ctx->pvt_id = 1; @@ -270,10 +278,6 @@ static int intel_sst_probe(struct pci_dev *pci, sst_drv_ctx->use_dma = 0; sst_drv_ctx->use_lli = 0; - spin_lock_init(&sst_drv_ctx->ipc_spin_lock); - spin_lock_init(&sst_drv_ctx->block_lock); - spin_lock_init(&sst_drv_ctx->rx_msg_lock); - if (sst_workqueue_init(sst_drv_ctx)) return -EINVAL; -- GitLab From 2559d9928f36f3c0bfb4ded9bb47d47b36337b09 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:47 +0530 Subject: [PATCH 2359/9457] ASoC: Intel: move the driver context allocation to routine This will be used by ACPI code as well, so moving to common routine helps Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 0863471a2c86..55bb1f7764f9 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -230,6 +230,20 @@ static void sst_init_locks(struct intel_sst_drv *ctx) spin_lock_init(&ctx->block_lock); } +int sst_alloc_drv_context(struct intel_sst_drv **ctx, + struct device *dev, unsigned int dev_id) +{ + *ctx = devm_kzalloc(dev, sizeof(struct intel_sst_drv), GFP_KERNEL); + if (!(*ctx)) + return -ENOMEM; + + (*ctx)->dev = dev; + (*ctx)->dev_id = dev_id; + + return 0; +} + + /* * intel_sst_probe - PCI probe function * @@ -247,12 +261,11 @@ static int intel_sst_probe(struct pci_dev *pci, int ddr_base; dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); - sst_drv_ctx = devm_kzalloc(&pci->dev, sizeof(*sst_drv_ctx), GFP_KERNEL); - if (!sst_drv_ctx) - return -ENOMEM; - sst_drv_ctx->dev = &pci->dev; - sst_drv_ctx->dev_id = pci->device; + ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); + if (ret < 0) + return ret; + if (!sst_pdata) return -EINVAL; -- GitLab From 250454d8fe65680b26f2917b806e2caf49126a01 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:48 +0530 Subject: [PATCH 2360/9457] ASoC: Intel: modularize driver probe and remove The driver probe which initializes driver and remove which cleans up can be shared with APCI as well, so move them to common init_context and cleanup_context routines which can be used by ACPI as well Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 165 ++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 71 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 55bb1f7764f9..09d367aeaa15 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -243,6 +243,94 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx, return 0; } +int sst_context_init(struct intel_sst_drv *ctx) +{ + int ret = 0, i; + + if (!ctx->pdata) + return -EINVAL; + + if (!ctx->pdata->probe_data) + return -EINVAL; + + memcpy(&ctx->info, ctx->pdata->probe_data, sizeof(ctx->info)); + + ret = sst_driver_ops(ctx); + if (ret != 0) + return -EINVAL; + + sst_init_locks(ctx); + + /* pvt_id 0 reserved for async messages */ + ctx->pvt_id = 1; + ctx->stream_cnt = 0; + ctx->fw_in_mem = NULL; + /* we use memcpy, so set to 0 */ + ctx->use_dma = 0; + ctx->use_lli = 0; + + if (sst_workqueue_init(ctx)) + return -EINVAL; + + ctx->mailbox_recv_offset = ctx->pdata->ipc_info->mbox_recv_off; + ctx->ipc_reg.ipcx = SST_IPCX + ctx->pdata->ipc_info->ipc_offset; + ctx->ipc_reg.ipcd = SST_IPCD + ctx->pdata->ipc_info->ipc_offset; + + dev_info(ctx->dev, "Got drv data max stream %d\n", + ctx->info.max_streams); + + for (i = 1; i <= ctx->info.max_streams; i++) { + struct stream_info *stream = &ctx->streams[i]; + + memset(stream, 0, sizeof(*stream)); + stream->pipe_id = PIPE_RSVD; + mutex_init(&stream->lock); + } + + /* Register the ISR */ + ret = devm_request_threaded_irq(ctx->dev, ctx->irq_num, ctx->ops->interrupt, + ctx->ops->irq_thread, 0, SST_DRV_NAME, + ctx); + if (ret) + goto do_free_mem; + + dev_dbg(ctx->dev, "Registered IRQ %#x\n", ctx->irq_num); + + /* default intr are unmasked so set this as masked */ + sst_shim_write64(ctx->shim, SST_IMRX, 0xFFFF0038); + + ctx->qos = devm_kzalloc(ctx->dev, + sizeof(struct pm_qos_request), GFP_KERNEL); + if (!ctx->qos) { + ret = -ENOMEM; + goto do_free_mem; + } + pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + return 0; + +do_free_mem: + destroy_workqueue(ctx->post_msg_wq); + return ret; +} + +void sst_context_cleanup(struct intel_sst_drv *ctx) +{ + pm_runtime_get_noresume(ctx->dev); + pm_runtime_forbid(ctx->dev); + sst_unregister(ctx->dev); + sst_set_fw_state_locked(ctx, SST_SHUTDOWN); + flush_scheduled_work(); + destroy_workqueue(ctx->post_msg_wq); + pm_qos_remove_request(ctx->qos); + kfree(ctx->fw_sg_list.src); + kfree(ctx->fw_sg_list.dst); + ctx->fw_sg_list.list_len = 0; + kfree(ctx->fw_in_mem); + ctx->fw_in_mem = NULL; + sst_memcpy_free_resources(ctx); + ctx = NULL; +} /* * intel_sst_probe - PCI probe function @@ -254,9 +342,8 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx, static int intel_sst_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { - int i, ret = 0; + int ret = 0; struct intel_sst_drv *sst_drv_ctx; - struct intel_sst_ops *ops; struct sst_platform_info *sst_pdata = pci->dev.platform_data; int ddr_base; @@ -266,43 +353,12 @@ static int intel_sst_probe(struct pci_dev *pci, if (ret < 0) return ret; - if (!sst_pdata) - return -EINVAL; - sst_drv_ctx->pdata = sst_pdata; - if (!sst_drv_ctx->pdata->probe_data) - return -EINVAL; - - memcpy(&sst_drv_ctx->info, sst_drv_ctx->pdata->probe_data, - sizeof(sst_drv_ctx->info)); - - if (0 != sst_driver_ops(sst_drv_ctx)) - return -EINVAL; - - ops = sst_drv_ctx->ops; - sst_init_locks(sst_drv_ctx); - - /* pvt_id 0 reserved for async messages */ - sst_drv_ctx->pvt_id = 1; - sst_drv_ctx->stream_cnt = 0; - sst_drv_ctx->fw_in_mem = NULL; - - /* we use memcpy, so set to 0 */ - sst_drv_ctx->use_dma = 0; - sst_drv_ctx->use_lli = 0; - - if (sst_workqueue_init(sst_drv_ctx)) - return -EINVAL; - dev_info(sst_drv_ctx->dev, "Got drv data max stream %d\n", - sst_drv_ctx->info.max_streams); - for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) { - struct stream_info *stream = &sst_drv_ctx->streams[i]; + ret = sst_context_init(sst_drv_ctx); + if (ret < 0) + goto do_free_drv_ctx; - memset(stream, 0, sizeof(*stream)); - stream->pipe_id = PIPE_RSVD; - mutex_init(&stream->lock); - } /* Init the device */ ret = pcim_enable_device(pci); @@ -402,18 +458,6 @@ static int intel_sst_probe(struct pci_dev *pci, } sst_drv_ctx->irq_num = pci->irq; - /* Register the ISR */ - ret = devm_request_threaded_irq(&pci->dev, pci->irq, - sst_drv_ctx->ops->interrupt, - sst_drv_ctx->ops->irq_thread, 0, SST_DRV_NAME, - sst_drv_ctx); - if (ret) - goto do_release_regions; - dev_dbg(sst_drv_ctx->dev, "Registered IRQ 0x%x\n", pci->irq); - - /* default intr are unmasked so set this as masked */ - if (sst_drv_ctx->dev_id == SST_MRFLD_PCI_ID) - sst_shim_write64(sst_drv_ctx->shim, SST_IMRX, 0xFFFF0038); pci_set_drvdata(pci, sst_drv_ctx); pm_runtime_set_autosuspend_delay(sst_drv_ctx->dev, SST_SUSPEND_DELAY); @@ -421,14 +465,6 @@ static int intel_sst_probe(struct pci_dev *pci, pm_runtime_allow(sst_drv_ctx->dev); pm_runtime_put_noidle(sst_drv_ctx->dev); sst_register(sst_drv_ctx->dev); - sst_drv_ctx->qos = devm_kzalloc(&pci->dev, - sizeof(struct pm_qos_request), GFP_KERNEL); - if (!sst_drv_ctx->qos) { - ret = -ENOMEM; - goto do_release_regions; - } - pm_qos_add_request(sst_drv_ctx->qos, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); return ret; @@ -436,6 +472,7 @@ static int intel_sst_probe(struct pci_dev *pci, pci_release_regions(pci); do_free_mem: destroy_workqueue(sst_drv_ctx->post_msg_wq); +do_free_drv_ctx: dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); return ret; } @@ -452,22 +489,8 @@ static void intel_sst_remove(struct pci_dev *pci) { struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); - pm_runtime_get_noresume(sst_drv_ctx->dev); - pm_runtime_forbid(sst_drv_ctx->dev); - sst_unregister(sst_drv_ctx->dev); + sst_context_cleanup(sst_drv_ctx); pci_dev_put(sst_drv_ctx->pci); - sst_set_fw_state_locked(sst_drv_ctx, SST_SHUTDOWN); - - flush_scheduled_work(); - destroy_workqueue(sst_drv_ctx->post_msg_wq); - pm_qos_remove_request(sst_drv_ctx->qos); - kfree(sst_drv_ctx->fw_sg_list.src); - kfree(sst_drv_ctx->fw_sg_list.dst); - sst_drv_ctx->fw_sg_list.list_len = 0; - kfree(sst_drv_ctx->fw_in_mem); - sst_drv_ctx->fw_in_mem = NULL; - sst_memcpy_free_resources(sst_drv_ctx); - sst_drv_ctx = NULL; pci_release_regions(pci); pci_set_drvdata(pci, NULL); } -- GitLab From 7fb73c74ffee65bda3b6d3b00c1b841f557a1191 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Thu, 30 Oct 2014 16:21:49 +0530 Subject: [PATCH 2361/9457] ASoC: Intel: more probe modularization for sst Move the PCI BAR and resource initialization to a separate routine Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 158 +++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 72 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 09d367aeaa15..2bfb404ea7c1 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -332,114 +332,132 @@ void sst_context_cleanup(struct intel_sst_drv *ctx) ctx = NULL; } -/* -* intel_sst_probe - PCI probe function -* -* @pci: PCI device structure -* @pci_id: PCI device ID structure -* -*/ -static int intel_sst_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +void sst_configure_runtime_pm(struct intel_sst_drv *ctx) { - int ret = 0; - struct intel_sst_drv *sst_drv_ctx; - struct sst_platform_info *sst_pdata = pci->dev.platform_data; - int ddr_base; - - dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); - - ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); - if (ret < 0) - return ret; - - sst_drv_ctx->pdata = sst_pdata; - - ret = sst_context_init(sst_drv_ctx); - if (ret < 0) - goto do_free_drv_ctx; - + pm_runtime_set_autosuspend_delay(ctx->dev, SST_SUSPEND_DELAY); + pm_runtime_use_autosuspend(ctx->dev); + pm_runtime_allow(ctx->dev); + pm_runtime_put_noidle(ctx->dev); +} - /* Init the device */ - ret = pcim_enable_device(pci); - if (ret) { - dev_err(sst_drv_ctx->dev, - "device can't be enabled. Returned err: %d\n", ret); - goto do_free_mem; - } - sst_drv_ctx->pci = pci_dev_get(pci); +static int sst_platform_get_resources(struct intel_sst_drv *ctx) +{ + int ddr_base, ret = 0; + struct pci_dev *pci = ctx->pci; ret = pci_request_regions(pci, SST_DRV_NAME); if (ret) - goto do_free_mem; + return ret; /* map registers */ /* DDR base */ - if (sst_drv_ctx->dev_id == SST_MRFLD_PCI_ID) { - sst_drv_ctx->ddr_base = pci_resource_start(pci, 0); + if (ctx->dev_id == SST_MRFLD_PCI_ID) { + ctx->ddr_base = pci_resource_start(pci, 0); /* check that the relocated IMR base matches with FW Binary */ - ddr_base = relocate_imr_addr_mrfld(sst_drv_ctx->ddr_base); - if (!sst_drv_ctx->pdata->lib_info) { - dev_err(sst_drv_ctx->dev, "lib_info pointer NULL\n"); + ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base); + if (!ctx->pdata->lib_info) { + dev_err(ctx->dev, "lib_info pointer NULL\n"); ret = -EINVAL; goto do_release_regions; } - if (ddr_base != sst_drv_ctx->pdata->lib_info->mod_base) { - dev_err(sst_drv_ctx->dev, + if (ddr_base != ctx->pdata->lib_info->mod_base) { + dev_err(ctx->dev, "FW LSP DDR BASE does not match with IFWI\n"); ret = -EINVAL; goto do_release_regions; } - sst_drv_ctx->ddr_end = pci_resource_end(pci, 0); + ctx->ddr_end = pci_resource_end(pci, 0); - sst_drv_ctx->ddr = pcim_iomap(pci, 0, + ctx->ddr = pcim_iomap(pci, 0, pci_resource_len(pci, 0)); - if (!sst_drv_ctx->ddr) { + if (!ctx->ddr) { ret = -EINVAL; goto do_release_regions; } - dev_dbg(sst_drv_ctx->dev, "sst: DDR Ptr %p\n", sst_drv_ctx->ddr); + dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr); } else { - sst_drv_ctx->ddr = NULL; + ctx->ddr = NULL; } - /* SHIM */ - sst_drv_ctx->shim_phy_add = pci_resource_start(pci, 1); - sst_drv_ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); - if (!sst_drv_ctx->shim) { + ctx->shim_phy_add = pci_resource_start(pci, 1); + ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); + if (!ctx->shim) { ret = -EINVAL; goto do_release_regions; } - dev_dbg(sst_drv_ctx->dev, "SST Shim Ptr %p\n", sst_drv_ctx->shim); + dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim); /* Shared SRAM */ - sst_drv_ctx->mailbox_add = pci_resource_start(pci, 2); - sst_drv_ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); - if (!sst_drv_ctx->mailbox) { + ctx->mailbox_add = pci_resource_start(pci, 2); + ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); + if (!ctx->mailbox) { ret = -EINVAL; goto do_release_regions; } - dev_dbg(sst_drv_ctx->dev, "SRAM Ptr %p\n", sst_drv_ctx->mailbox); + dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox); /* IRAM */ - sst_drv_ctx->iram_end = pci_resource_end(pci, 3); - sst_drv_ctx->iram_base = pci_resource_start(pci, 3); - sst_drv_ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); - if (!sst_drv_ctx->iram) { + ctx->iram_end = pci_resource_end(pci, 3); + ctx->iram_base = pci_resource_start(pci, 3); + ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); + if (!ctx->iram) { ret = -EINVAL; goto do_release_regions; } - dev_dbg(sst_drv_ctx->dev, "IRAM Ptr %p\n", sst_drv_ctx->iram); + dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram); /* DRAM */ - sst_drv_ctx->dram_end = pci_resource_end(pci, 4); - sst_drv_ctx->dram_base = pci_resource_start(pci, 4); - sst_drv_ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); - if (!sst_drv_ctx->dram) { + ctx->dram_end = pci_resource_end(pci, 4); + ctx->dram_base = pci_resource_start(pci, 4); + ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); + if (!ctx->dram) { ret = -EINVAL; goto do_release_regions; } - dev_dbg(sst_drv_ctx->dev, "DRAM Ptr %p\n", sst_drv_ctx->dram); + dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); +do_release_regions: + pci_release_regions(pci); + return 0; +} +/* +* intel_sst_probe - PCI probe function +* +* @pci: PCI device structure +* @pci_id: PCI device ID structure +* +*/ +static int intel_sst_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + int ret = 0; + struct intel_sst_drv *sst_drv_ctx; + struct sst_platform_info *sst_pdata = pci->dev.platform_data; + + dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); + + ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); + if (ret < 0) + return ret; + + sst_drv_ctx->pdata = sst_pdata; + sst_drv_ctx->irq_num = pci->irq; + + ret = sst_context_init(sst_drv_ctx); + if (ret < 0) + goto do_free_drv_ctx; + + + /* Init the device */ + ret = pcim_enable_device(pci); + if (ret) { + dev_err(sst_drv_ctx->dev, + "device can't be enabled. Returned err: %d\n", ret); + goto do_destroy_wq; + } + sst_drv_ctx->pci = pci_dev_get(pci); + ret = sst_platform_get_resources(sst_drv_ctx); + if (ret < 0) + goto do_destroy_wq; sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), @@ -457,20 +475,16 @@ static int intel_sst_probe(struct pci_dev *pci, goto do_release_regions; } - sst_drv_ctx->irq_num = pci->irq; pci_set_drvdata(pci, sst_drv_ctx); - pm_runtime_set_autosuspend_delay(sst_drv_ctx->dev, SST_SUSPEND_DELAY); - pm_runtime_use_autosuspend(sst_drv_ctx->dev); - pm_runtime_allow(sst_drv_ctx->dev); - pm_runtime_put_noidle(sst_drv_ctx->dev); + sst_configure_runtime_pm(sst_drv_ctx); sst_register(sst_drv_ctx->dev); return ret; do_release_regions: pci_release_regions(pci); -do_free_mem: +do_destroy_wq: destroy_workqueue(sst_drv_ctx->post_msg_wq); do_free_drv_ctx: dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); -- GitLab From c1e99c913be4294e63b5e74b197b8a8c86e6e67b Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Thu, 30 Oct 2014 21:16:23 +0800 Subject: [PATCH 2362/9457] ASoC: Intel: Add jack detection for Broadwell Add jack dectection and event reporting for Broadwell. It use combo jack on BDW platform, which including Mic Jack pin and Headphone jack pin. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/broadwell.c | 49 ++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c index 0e550f14028f..52cb7645fa83 100644 --- a/sound/soc/intel/broadwell.c +++ b/sound/soc/intel/broadwell.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "sst-dsp.h" @@ -26,8 +27,26 @@ #include "../codecs/rt286.h" +static struct snd_soc_jack broadwell_headset; +/* Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin broadwell_headset_pins[] = { + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static const struct snd_kcontrol_new broadwell_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Headphone Jack"), +}; + static const struct snd_soc_dapm_widget broadwell_widgets[] = { - SND_SOC_DAPM_HP("Headphones", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_MIC("Mic Jack", NULL), SND_SOC_DAPM_MIC("DMIC1", NULL), @@ -42,7 +61,7 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = { {"Speaker", NULL, "SPOL"}, /* HP jack connectors - unknown if we have jack deteck */ - {"Headphones", NULL, "HPO Pin"}, + {"Headphone Jack", NULL, "HPO Pin"}, /* other jacks */ {"MIC1", NULL, "Mic Jack"}, @@ -57,6 +76,27 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = { {"AIF1 Playback", NULL, "SSP0 CODEC OUT"}, }; +static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + int ret = 0; + ret = snd_soc_jack_new(codec, "Headset", + SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset); + + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&broadwell_headset, + ARRAY_SIZE(broadwell_headset_pins), + broadwell_headset_pins); + if (ret) + return ret; + + rt286_mic_detect(codec, &broadwell_headset); + return 0; +} + + static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -116,7 +156,7 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) } /* always connected - check HP for jack detect */ - snd_soc_dapm_enable_pin(dapm, "Headphones"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); snd_soc_dapm_enable_pin(dapm, "Speaker"); snd_soc_dapm_enable_pin(dapm, "Mic Jack"); snd_soc_dapm_enable_pin(dapm, "Line Jack"); @@ -196,6 +236,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { .no_pcm = 1, .codec_name = "i2c-INT343A:00", .codec_dai_name = "rt286-aif1", + .init = broadwell_rt286_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_suspend = 1, @@ -213,6 +254,8 @@ static struct snd_soc_card broadwell_rt286 = { .owner = THIS_MODULE, .dai_link = broadwell_rt286_dais, .num_links = ARRAY_SIZE(broadwell_rt286_dais), + .controls = broadwell_controls, + .num_controls = ARRAY_SIZE(broadwell_controls), .dapm_widgets = broadwell_widgets, .num_dapm_widgets = ARRAY_SIZE(broadwell_widgets), .dapm_routes = broadwell_rt286_map, -- GitLab From 16af0ee16ca9391ef82e1c74c362d80551e769fe Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:00:58 +0100 Subject: [PATCH 2363/9457] ASoC: ad1980: Remove unused header The constants defined in the ad1980 header are not used. So remove the file. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ad1980.c | 2 -- sound/soc/codecs/ad1980.c | 2 -- sound/soc/codecs/ad1980.h | 26 -------------------------- 3 files changed, 30 deletions(-) delete mode 100644 sound/soc/codecs/ad1980.h diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index 3450e8f9080d..0fa81a523b8a 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -46,8 +46,6 @@ #include #include -#include "../codecs/ad1980.h" - #include "bf5xx-ac97.h" static struct snd_soc_card bf5xx_board; diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 304d3003339a..cc28dbae8315 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -30,8 +30,6 @@ #include #include -#include "ad1980.h" - /* * AD1980 register cache */ diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h deleted file mode 100644 index eb0af44ad3df..000000000000 --- a/sound/soc/codecs/ad1980.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ad1980.h -- ad1980 Soc Audio driver - * - * WARNING: - * - * Because Analog Devices Inc. discontinued the ad1980 sound chip since - * Sep. 2009, this ad1980 driver is not maintained, tested and supported - * by ADI now. - */ - -#ifndef _AD1980_H -#define _AD1980_H -/* Bit definition of Power-Down Control/Status Register */ -#define ADC 0x0001 -#define DAC 0x0002 -#define ANL 0x0004 -#define REF 0x0008 -#define PR0 0x0100 -#define PR1 0x0200 -#define PR2 0x0400 -#define PR3 0x0800 -#define PR4 0x1000 -#define PR5 0x2000 -#define PR6 0x4000 - -#endif -- GitLab From e5adb6cddb17f8e76be404f23a2e0db102ee1bd1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:00:59 +0100 Subject: [PATCH 2364/9457] ASoC: ad1980: Cleanup printk usage Use dev_err()/dev_warn() instead of printk(KERN_ERR/KERN_WARNING. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers. Also remove the info message that is printed when the driver is probed, this is just noise in bootlog. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ad1980.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index cc28dbae8315..5f076c24d062 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -209,7 +209,8 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) return 0; } while (retry_cnt++ < 10); - printk(KERN_ERR "AD1980 AC97 reset failed\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); + return -EIO; } @@ -219,19 +220,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) u16 vendor_id2; u16 ext_status; - printk(KERN_INFO "AD1980 SoC Audio Codec\n"); - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; } ret = ad1980_reset(codec, 0); - if (ret < 0) { - printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); + if (ret < 0) goto reset_err; - } /* Read out vendor ID to make sure it is ad1980 */ if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) { @@ -246,9 +243,8 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) ret = -ENODEV; goto reset_err; } else { - printk(KERN_WARNING "ad1980: " - "Found AD1981 - only 2/2 IN/OUT Channels " - "supported\n"); + dev_warn(codec->dev, + "Found AD1981 - only 2/2 IN/OUT Channels supported\n"); } } -- GitLab From 6ce13d61dc6cfc3cf6be6bd12faf75bfbc12ea91 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:00 +0100 Subject: [PATCH 2365/9457] ASoC: ad1980: Use table based control setup Makes the code a bit cleaner. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ad1980.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 5f076c24d062..9ed4e12c26d1 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -259,9 +259,6 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); - snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls, - ARRAY_SIZE(ad1980_snd_ac97_controls)); - return 0; reset_err: @@ -285,6 +282,8 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .write = ac97_write, .read = ac97_read, + .controls = ad1980_snd_ac97_controls, + .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), .dapm_widgets = ad1980_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), .dapm_routes = ad1980_dapm_routes, -- GitLab From 93932abaa3c84c2d76ce713bbbad08bad9162483 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:01 +0100 Subject: [PATCH 2366/9457] ASoC: stac9766: Cleanup printk usage Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/stac9766.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 9878534ccd16..e88d9ac9cbab 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -262,7 +262,7 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec) /* give the codec an AC97 warm reset to start the link */ reset: if (reset > 5) { - printk(KERN_ERR "stac9766 failed to resume"); + dev_err(codec->dev, "Failed to resume\n"); return -EIO; } codec->ac97->bus->ops->warm_reset(codec->ac97); @@ -338,7 +338,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) stac9766_reset(codec, 0); ret = stac9766_reset(codec, 1); if (ret < 0) { - printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); goto codec_err; } -- GitLab From 8865051d9941de905432f59f7a88662e824d5df9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:02 +0100 Subject: [PATCH 2367/9457] ASoC: stac9766: Use table based control setup Makes the code a bit cleaner. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/stac9766.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index e88d9ac9cbab..6c62d291cde7 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -342,9 +342,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) goto codec_err; } - snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls, - ARRAY_SIZE(stac9766_snd_ac97_controls)); - return 0; codec_err: @@ -359,6 +356,8 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) } static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { + .controls = stac9766_snd_ac97_controls, + .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), .write = stac9766_ac97_write, .read = stac9766_ac97_read, .set_bias_level = stac9766_set_bias_level, -- GitLab From 9cf766f666cc4518e22f185159f285f4e3183230 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:03 +0100 Subject: [PATCH 2368/9457] ASoC: wm9705: Cleanup printk usage Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9705.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index c0b7f45dfa37..355b28dd6ac9 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -300,6 +300,8 @@ static int wm9705_reset(struct snd_soc_codec *codec) return 0; /* Success */ } + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); + return -EIO; } @@ -317,10 +319,8 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache; ret = wm9705_reset(codec); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - } for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); @@ -339,7 +339,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; } -- GitLab From d7cabb08ba23c87757fb3be01e82f755aad426d1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:04 +0100 Subject: [PATCH 2369/9457] ASoC: wm9705: Use table based control setup Makes the code a bit cleaner. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9705.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 355b28dd6ac9..1650195f6c84 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -347,9 +347,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) if (ret) goto reset_err; - snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls, - ARRAY_SIZE(wm9705_snd_ac97_controls)); - return 0; reset_err: @@ -374,6 +371,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9705_reg, + + .controls = wm9705_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), .dapm_widgets = wm9705_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), .dapm_routes = wm9705_audio_map, -- GitLab From 12ced338ab8858d11ef5b11b65c3dc612d9551c9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:05 +0100 Subject: [PATCH 2370/9457] ASoC: wm9712: Cleanup printk usage Use dev_err() instead of printk(KERN_ERR. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers. Also avoid printing two error messages when the reset fails. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c5eb746087b4..c389e5607ab6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -595,7 +595,7 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) return 0; err: - printk(KERN_ERR "WM9712 AC97 reset failed\n"); + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); return -EIO; } @@ -611,10 +611,8 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache; ret = wm9712_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - } wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -637,15 +635,13 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) { - printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); + dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; } ret = wm9712_reset(codec, 0); - if (ret < 0) { - printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n"); + if (ret < 0) goto reset_err; - } /* set alc mux to none */ ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); -- GitLab From 9a812c6b7a2092e20b4b78ed0ec6614a89e96dfd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:06 +0100 Subject: [PATCH 2371/9457] ASoC: wm9712: Use table based control setup Makes the code a bit cleaner. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index c389e5607ab6..f3aab6e1d92a 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -647,8 +647,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls, - ARRAY_SIZE(wm9712_snd_ac97_controls)); return 0; @@ -675,6 +673,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9712_reg, + + .controls = wm9712_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), .dapm_widgets = wm9712_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), .dapm_routes = wm9712_audio_map, -- GitLab From a6c2b07f11beaf5719f03c70a9c9597534b297a5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:07 +0100 Subject: [PATCH 2372/9457] ASoC: wm9713: Cleanup printk usage Use dev_err()/dev_warn() instead of printk(KERN_ERR/KERN_WARNING. This is common practice and makes it easy to find out which device generated the message. While we are at it also align the error messages with the other AC'97 drivers. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index bddee30a4bc7..38e17d45cfef 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -689,7 +689,8 @@ struct _pll_div { * to allow rounding later */ #define FIXED_PLL_SIZE ((1 << 22) * 10) -static void pll_factors(struct _pll_div *pll_div, unsigned int source) +static void pll_factors(struct snd_soc_codec *codec, + struct _pll_div *pll_div, unsigned int source) { u64 Kpart; unsigned int K, Ndiv, Nmod, target; @@ -724,7 +725,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source) Ndiv = target / source; if ((Ndiv < 5) || (Ndiv > 12)) - printk(KERN_WARNING + dev_warn(codec->dev, "WM9713 PLL N value %u out of recommended range!\n", Ndiv); @@ -768,7 +769,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, return 0; } - pll_factors(&pll_div, freq_in); + pll_factors(codec, &pll_div, freq_in); if (pll_div.k == 0) { reg = (pll_div.n << 12) | (pll_div.lf << 11) | @@ -1104,8 +1105,11 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm) soc_ac97_ops->reset(codec->ac97); if (soc_ac97_ops->warm_reset) soc_ac97_ops->warm_reset(codec->ac97); - if (ac97_read(codec, 0) != wm9713_reg[0]) + if (ac97_read(codec, 0) != wm9713_reg[0]) { + dev_err(codec->dev, "Failed to reset: AC97 link error\n"); return -EIO; + } + return 0; } EXPORT_SYMBOL_GPL(wm9713_reset); @@ -1163,10 +1167,8 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec) u16 *cache = codec->reg_cache; ret = wm9713_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "could not reset AC97 codec\n"); + if (ret < 0) return ret; - } wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1205,10 +1207,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) * a warm reset followed by an optional cold reset for codec */ wm9713_reset(codec, 0); ret = wm9713_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n"); + if (ret < 0) goto reset_err; - } wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -- GitLab From c1359ca303ee5125827c0d2a65f0c86d491dc993 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:08 +0100 Subject: [PATCH 2373/9457] ASoC: wm9713: Use table based control setup Makes the code a bit cleaner. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 38e17d45cfef..ba8c276b9dcf 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1216,9 +1216,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) reg = ac97_read(codec, AC97_CD) & 0x7fff; ac97_write(codec, AC97_CD, reg); - snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls, - ARRAY_SIZE(wm9713_snd_ac97_controls)); - return 0; reset_err: @@ -1248,6 +1245,9 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9713_reg, + + .controls = wm9713_snd_ac97_controls, + .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), .dapm_widgets = wm9713_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), .dapm_routes = wm9713_audio_map, -- GitLab From 5efe89d9525f24f607079307d2d9510e30ba8590 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:09 +0100 Subject: [PATCH 2374/9457] ASoC: wm9713: Move driver state struct allocation to driver probe Resources for the device should be allocated in the device driver probe callback, rather than in the ASoC CODEC probe callback. E.g. one advantage is that we can use device managed allocations. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ba8c276b9dcf..27047839172d 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1191,17 +1191,11 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec) static int wm9713_soc_probe(struct snd_soc_codec *codec) { - struct wm9713_priv *wm9713; int ret = 0, reg; - wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL); - if (wm9713 == NULL) - return -ENOMEM; - snd_soc_codec_set_drvdata(codec, wm9713); - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); if (ret < 0) - goto codec_err; + return ret; /* do a cold reset for the controller and then try * a warm reset followed by an optional cold reset for codec */ @@ -1220,16 +1214,12 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) reset_err: snd_soc_free_ac97_codec(codec); -codec_err: - kfree(wm9713); return ret; } static int wm9713_soc_remove(struct snd_soc_codec *codec) { - struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); snd_soc_free_ac97_codec(codec); - kfree(wm9713); return 0; } @@ -1256,6 +1246,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { static int wm9713_probe(struct platform_device *pdev) { + struct wm9713_priv *wm9713; + + wm9713 = devm_kzalloc(&pdev->dev, sizeof(*wm9713), GFP_KERNEL); + if (wm9713 == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, wm9713); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai)); } -- GitLab From 5bc39b50fd3f9e3585e0cb1cf7d7da979a063848 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 30 Oct 2014 21:01:10 +0100 Subject: [PATCH 2375/9457] ASoC: wm9713: Use virtual control instead of virtual register The wm9713 currently implements the virtual control for the Mic B Source MUX using a virtual register. Replace this by using SOC_ENUM_SINGLE_VIRT(). Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 27047839172d..ac13fc8f5c70 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -59,13 +59,12 @@ static const u16 wm9713_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0001, 0x0000, 0x574d, 0x4c13, - 0x0000, 0x0000, 0x0000 + 0x0000, 0x0000 }; /* virtual HP mixers regs */ #define HPL_MIXER 0x80 #define HPR_MIXER 0x82 -#define MICB_MUX 0x82 static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; @@ -110,7 +109,7 @@ SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 10, 8, wm9713_dac_inv), /* dac invert 2 15 */ SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_bass), /* bass control 16 */ SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), /* noise gate type 17 */ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18 */ -SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ +SOC_ENUM_SINGLE_VIRT(2, wm9713_micb_select), /* mic selection 19 */ }; static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0); -- GitLab From 3b5b9932fb547a7c89169a1c43a73beee7183ed0 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 31 Oct 2014 14:39:11 +0000 Subject: [PATCH 2376/9457] drm: Add a note to drm_property_create() about property lifetime Cc: Chandra Konduru Cc: Daniel Vetter Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4081d7ab8407..0f3c24c0981b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3417,6 +3417,10 @@ void drm_fb_release(struct drm_file *priv) * object with drm_object_attach_property. The returned property object must be * freed with drm_property_destroy. * + * Note that the DRM core keeps a per-device list of properties and that, if + * drm_mode_config_cleanup() is called, it will destroy all properties created + * by the driver. + * * Returns: * A pointer to the newly created property on success, NULL on failure. */ -- GitLab From 9d5fab402d3b6fc3d4b895fbb0bde4e4f2378167 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 31 Oct 2014 14:39:12 +0000 Subject: [PATCH 2377/9457] drm/i915: Don't destroy DRM properties in the driver When drm properties are created, they are added to mode_config.property_list, which is then used in drm_mode_config_cleanup() to destroy every single property created by the driver. Cc: Chandra Konduru Cc: Daniel Vetter Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 47 ------------------------------- 1 file changed, 47 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9350edd6728d..6d7a277458b5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1991,57 +1991,10 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) return !list_empty(&connector->probed_modes); } -static void -intel_sdvo_destroy_enhance_property(struct drm_connector *connector) -{ - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - struct drm_device *dev = connector->dev; - - if (intel_sdvo_connector->left) - drm_property_destroy(dev, intel_sdvo_connector->left); - if (intel_sdvo_connector->right) - drm_property_destroy(dev, intel_sdvo_connector->right); - if (intel_sdvo_connector->top) - drm_property_destroy(dev, intel_sdvo_connector->top); - if (intel_sdvo_connector->bottom) - drm_property_destroy(dev, intel_sdvo_connector->bottom); - if (intel_sdvo_connector->hpos) - drm_property_destroy(dev, intel_sdvo_connector->hpos); - if (intel_sdvo_connector->vpos) - drm_property_destroy(dev, intel_sdvo_connector->vpos); - if (intel_sdvo_connector->saturation) - drm_property_destroy(dev, intel_sdvo_connector->saturation); - if (intel_sdvo_connector->contrast) - drm_property_destroy(dev, intel_sdvo_connector->contrast); - if (intel_sdvo_connector->hue) - drm_property_destroy(dev, intel_sdvo_connector->hue); - if (intel_sdvo_connector->sharpness) - drm_property_destroy(dev, intel_sdvo_connector->sharpness); - if (intel_sdvo_connector->flicker_filter) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); - if (intel_sdvo_connector->flicker_filter_2d) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); - if (intel_sdvo_connector->flicker_filter_adaptive) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); - if (intel_sdvo_connector->tv_luma_filter) - drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); - if (intel_sdvo_connector->tv_chroma_filter) - drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); - if (intel_sdvo_connector->dot_crawl) - drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); - if (intel_sdvo_connector->brightness) - drm_property_destroy(dev, intel_sdvo_connector->brightness); -} - static void intel_sdvo_destroy(struct drm_connector *connector) { struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - if (intel_sdvo_connector->tv_format) - drm_property_destroy(connector->dev, - intel_sdvo_connector->tv_format); - - intel_sdvo_destroy_enhance_property(connector); drm_connector_cleanup(connector); kfree(intel_sdvo_connector); } -- GitLab From ba8ce31f438c6bdd1d37b07cfea36d248c7f64d0 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 31 Oct 2014 14:39:13 +0000 Subject: [PATCH 2378/9457] drm/gma500: Don't destroy DRM properties in the driver When drm properties are created, they are added to mode_config.property_list which is then used in drm_mode_config_cleanup() to destroy every single property created by the driver. Cc: Patrik Jakobsson Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 49 ------------------------- 1 file changed, 49 deletions(-) diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 0be96fdb5e28..58529cea575d 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1631,57 +1631,8 @@ static int psb_intel_sdvo_get_modes(struct drm_connector *connector) return !list_empty(&connector->probed_modes); } -static void -psb_intel_sdvo_destroy_enhance_property(struct drm_connector *connector) -{ - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - struct drm_device *dev = connector->dev; - - if (psb_intel_sdvo_connector->left) - drm_property_destroy(dev, psb_intel_sdvo_connector->left); - if (psb_intel_sdvo_connector->right) - drm_property_destroy(dev, psb_intel_sdvo_connector->right); - if (psb_intel_sdvo_connector->top) - drm_property_destroy(dev, psb_intel_sdvo_connector->top); - if (psb_intel_sdvo_connector->bottom) - drm_property_destroy(dev, psb_intel_sdvo_connector->bottom); - if (psb_intel_sdvo_connector->hpos) - drm_property_destroy(dev, psb_intel_sdvo_connector->hpos); - if (psb_intel_sdvo_connector->vpos) - drm_property_destroy(dev, psb_intel_sdvo_connector->vpos); - if (psb_intel_sdvo_connector->saturation) - drm_property_destroy(dev, psb_intel_sdvo_connector->saturation); - if (psb_intel_sdvo_connector->contrast) - drm_property_destroy(dev, psb_intel_sdvo_connector->contrast); - if (psb_intel_sdvo_connector->hue) - drm_property_destroy(dev, psb_intel_sdvo_connector->hue); - if (psb_intel_sdvo_connector->sharpness) - drm_property_destroy(dev, psb_intel_sdvo_connector->sharpness); - if (psb_intel_sdvo_connector->flicker_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter); - if (psb_intel_sdvo_connector->flicker_filter_2d) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_2d); - if (psb_intel_sdvo_connector->flicker_filter_adaptive) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_adaptive); - if (psb_intel_sdvo_connector->tv_luma_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->tv_luma_filter); - if (psb_intel_sdvo_connector->tv_chroma_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->tv_chroma_filter); - if (psb_intel_sdvo_connector->dot_crawl) - drm_property_destroy(dev, psb_intel_sdvo_connector->dot_crawl); - if (psb_intel_sdvo_connector->brightness) - drm_property_destroy(dev, psb_intel_sdvo_connector->brightness); -} - static void psb_intel_sdvo_destroy(struct drm_connector *connector) { - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - - if (psb_intel_sdvo_connector->tv_format) - drm_property_destroy(connector->dev, - psb_intel_sdvo_connector->tv_format); - - psb_intel_sdvo_destroy_enhance_property(connector); drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); -- GitLab From b509c02d0f31639dda90f9b7269668b86c9b25ef Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Wed, 8 Oct 2014 16:54:28 +0200 Subject: [PATCH 2379/9457] Bluetooth: HCI H5 peer reset detection H5 Specification says: If a SYNC message is received while in the Active State, it is assumed that the peer device has reset. The local device should therefore perform a full reset of the upper stack, and start Link Establishment again at the Uninitialized State. Upon entering the Active State, the first packet sent shall have its SEQ and ACK numbers set to zero. This patch resets the HCI H5 driver data/state to unitialized and reports an HCI hardware error event to notify the upper stack that HCI synchronization has been lost. H5 will be re-synchronized and upper stack should generate an HCI Reset command. Signed-off-by: Loic Poulain Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci_h5.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index a22838669b4e..20bdd71559b1 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -168,6 +168,36 @@ static void h5_timed_event(unsigned long arg) hci_uart_tx_wakeup(hu); } +static void h5_peer_reset(struct hci_uart *hu) +{ + struct h5 *h5 = hu->priv; + struct sk_buff *skb; + const unsigned char hard_err[] = { 0x10, 0x01, 0x00 }; + + BT_ERR("Peer device has reset"); + + h5->state = H5_UNINITIALIZED; + + del_timer(&h5->timer); + + skb_queue_purge(&h5->rel); + skb_queue_purge(&h5->unrel); + skb_queue_purge(&h5->unack); + + h5->tx_seq = 0; + h5->tx_ack = 0; + + skb = bt_skb_alloc(3, GFP_ATOMIC); + if (!skb) + return; + + bt_cb(skb)->pkt_type = HCI_EVENT_PKT; + memcpy(skb_put(skb, 3), hard_err, 3); + + /* Send Hardware Error to upper stack */ + hci_recv_frame(hu->hdev, skb); +} + static int h5_open(struct hci_uart *hu) { struct h5 *h5; @@ -283,8 +313,12 @@ static void h5_handle_internal_rx(struct hci_uart *hu) conf_req[2] = h5_cfg_field(h5); if (memcmp(data, sync_req, 2) == 0) { + if (h5->state == H5_ACTIVE) + h5_peer_reset(hu); h5_link_control(hu, sync_rsp, 2); } else if (memcmp(data, sync_rsp, 2) == 0) { + if (h5->state == H5_ACTIVE) + h5_peer_reset(hu); h5->state = H5_INITIALIZED; h5_link_control(hu, conf_req, 3); } else if (memcmp(data, conf_req, 2) == 0) { -- GitLab From e894beb8183dd9e3834983440900ceb632823676 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 31 Oct 2014 10:54:23 -0700 Subject: [PATCH 2380/9457] ASoC: cs42l51: depends on I2C Fix build errors when CONFIG_I2C is not enabled by making the driver depend on I2C. ../sound/soc/codecs/cs42l51-i2c.c:55:1: warning: data definition has no type or storage class [enabled by default] module_i2c_driver(cs42l51_i2c_driver); ^ ../sound/soc/codecs/cs42l51-i2c.c:55:1: error: type defaults to 'int' in declaration of 'module_i2c_driver' [-Werror=implicit-int] ../sound/soc/codecs/cs42l51-i2c.c:55:1: warning: parameter names (without types) in function declaration [enabled by default] ../sound/soc/codecs/cs42l51-i2c.c:45:26: warning: 'cs42l51_i2c_driver' defined but not used [-Wunused-variable] static struct i2c_driver cs42l51_i2c_driver = { ^ Signed-off-by: Randy Dunlap Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f4fb12fab166..02a36b0b7f54 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -337,6 +337,7 @@ config SND_SOC_CS42L51 config SND_SOC_CS42L51_I2C tristate "Cirrus Logic CS42L51 CODEC (I2C)" + depends on I2C select SND_SOC_CS42L51 config SND_SOC_CS42L52 -- GitLab From bf35443314acb43fa8a3f9f8046e14cbe178762b Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 31 Oct 2014 16:08:26 +0530 Subject: [PATCH 2381/9457] mwifiex: channel statistics support for mwifiex This patch adds support to record channel statistics during scan. With extended scan, scan results are returned as events from FW while channel statistics are part of scan command response. We store these channel statistics in adapter. Signed-off-by: Avinash Patil Signed-off-by: Xinmin Hu Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 19 ++++++ drivers/net/wireless/mwifiex/decl.h | 10 +++ drivers/net/wireless/mwifiex/fw.h | 16 +++++ drivers/net/wireless/mwifiex/main.c | 6 ++ drivers/net/wireless/mwifiex/main.h | 6 +- drivers/net/wireless/mwifiex/scan.c | 76 +++++++++++++++++++++- drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 +- 7 files changed, 132 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 0dd672954ad1..80b1a54e7792 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2840,6 +2840,25 @@ static const struct wiphy_coalesce_support mwifiex_coalesce_support = { .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN, }; +int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter) +{ + u32 n_channels_bg, n_channels_a = 0; + + n_channels_bg = mwifiex_band_2ghz.n_channels; + + if (adapter->config_bands & BAND_A) + n_channels_a = mwifiex_band_5ghz.n_channels; + + adapter->num_in_chan_stats = max_t(u32, n_channels_bg, n_channels_a); + adapter->chan_stats = vmalloc(sizeof(*adapter->chan_stats) * + adapter->num_in_chan_stats); + + if (!adapter->chan_stats) + return -ENOMEM; + + return 0; +} + /* * This function registers the device with CFG802.11 subsystem. * diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index e0d00a7f0ec3..f53e5b50d3d8 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -185,4 +185,14 @@ struct mwifiex_arp_eth_header { u8 ar_tha[ETH_ALEN]; u8 ar_tip[4]; } __packed; + +struct mwifiex_chan_stats { + u8 chan_num; + u8 bandcfg; + u8 flags; + s8 noise; + u16 total_bss; + u16 cca_scan_dur; + u16 cca_busy_dur; +} __packed; #endif /* !_MWIFIEX_DECL_H_ */ diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 1eb61739071f..7f922a882c13 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -172,6 +172,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) #define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197) #define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) +#define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 @@ -611,6 +612,16 @@ struct uap_rxpd { u8 reserved1; }; +struct mwifiex_fw_chan_stats { + u8 chan_num; + u8 bandcfg; + u8 flags; + s8 noise; + __le16 total_bss; + __le16 cca_scan_dur; + __le16 cca_busy_dur; +} __packed; + enum mwifiex_chan_scan_mode_bitmasks { MWIFIEX_PASSIVE_SCAN = BIT(0), MWIFIEX_DISABLE_CHAN_FILT = BIT(1), @@ -660,6 +671,11 @@ struct mwifiex_ie_types_scan_chan_gap { __le16 chan_gap; } __packed; +struct mwifiex_ietypes_chanstats { + struct mwifiex_ie_types_header header; + struct mwifiex_fw_chan_stats chanstats[0]; +} __packed; + struct mwifiex_ie_types_wildcard_ssid_params { struct mwifiex_ie_types_header header; u8 max_ssid_length; diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index d5070c444fe1..f26420dbab6f 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -122,6 +122,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter) } } + vfree(adapter->chan_stats); kfree(adapter); return 0; } @@ -447,6 +448,11 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto err_init_fw; } + if (mwifiex_init_channel_scan_gap(adapter)) { + dev_err(adapter->dev, "could not init channel stats table\n"); + goto err_init_fw; + } + rtnl_lock(); /* Create station interface by default */ wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index e2635747d966..fb47731d45a6 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -844,6 +844,9 @@ struct mwifiex_adapter { u8 curr_mem_idx; bool scan_chan_gap_enabled; struct sk_buff_head rx_data_q; + struct mwifiex_chan_stats *chan_stats; + u32 num_in_chan_stats; + int survey_idx; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); @@ -1030,7 +1033,8 @@ void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv); int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); -int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv); +int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp); int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv, void *buf); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index ca64d4c94112..3a17821157d7 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1755,6 +1755,7 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; + adapter->survey_idx = 0; if (adapter->curr_cmd->wait_q_enabled) { adapter->cmd_wait_q.status = 0; if (!priv->scan_request) { @@ -1976,10 +1977,53 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv, return 0; } +static void +mwifiex_update_chan_statistics(struct mwifiex_private *priv, + struct mwifiex_ietypes_chanstats *tlv_stat) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u8 i, num_chan; + struct mwifiex_fw_chan_stats *fw_chan_stats; + struct mwifiex_chan_stats chan_stats; + + fw_chan_stats = (void *)((u8 *)tlv_stat + + sizeof(struct mwifiex_ie_types_header)); + num_chan = le16_to_cpu(tlv_stat->header.len) / + sizeof(struct mwifiex_chan_stats); + + for (i = 0 ; i < num_chan; i++) { + chan_stats.chan_num = fw_chan_stats->chan_num; + chan_stats.bandcfg = fw_chan_stats->bandcfg; + chan_stats.flags = fw_chan_stats->flags; + chan_stats.noise = fw_chan_stats->noise; + chan_stats.total_bss = le16_to_cpu(fw_chan_stats->total_bss); + chan_stats.cca_scan_dur = + le16_to_cpu(fw_chan_stats->cca_scan_dur); + chan_stats.cca_busy_dur = + le16_to_cpu(fw_chan_stats->cca_busy_dur); + dev_dbg(adapter->dev, + "chan=%d, noise=%d, total_network=%d scan_duration=%d, busy_duration=%d\n", + chan_stats.chan_num, + chan_stats.noise, + chan_stats.total_bss, + chan_stats.cca_scan_dur, + chan_stats.cca_busy_dur); + memcpy(&adapter->chan_stats[adapter->survey_idx++], &chan_stats, + sizeof(struct mwifiex_chan_stats)); + fw_chan_stats++; + } +} + /* This function handles the command response of extended scan */ -int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) +int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) { struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_scan_ext *ext_scan_resp; + struct mwifiex_ie_types_header *tlv; + struct mwifiex_ietypes_chanstats *tlv_stat; + u16 buf_left, type, len; + struct host_cmd_ds_command *cmd_ptr; struct cmd_ctrl_node *cmd_node; unsigned long cmd_flags, scan_flags; @@ -1987,6 +2031,36 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); + ext_scan_resp = &resp->params.ext_scan; + + tlv = (void *)ext_scan_resp->tlv_buffer; + buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN + - 1); + + while (buf_left >= sizeof(struct mwifiex_ie_types_header)) { + type = le16_to_cpu(tlv->type); + len = le16_to_cpu(tlv->len); + + if (buf_left < (sizeof(struct mwifiex_ie_types_header) + len)) { + dev_err(adapter->dev, + "error processing scan response TLVs"); + break; + } + + switch (type) { + case TLV_TYPE_CHANNEL_STATS: + tlv_stat = (void *)tlv; + mwifiex_update_chan_statistics(priv, tlv_stat); + break; + default: + break; + } + + buf_left -= len + sizeof(struct mwifiex_ie_types_header); + tlv = (void *)((u8 *)tlv + len + + sizeof(struct mwifiex_ie_types_header)); + } + spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags); spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags); if (list_empty(&adapter->scan_pending_q)) { diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 4aad44685f8d..b65e1014b0fc 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -983,7 +983,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, adapter->curr_cmd->wait_q_enabled = false; break; case HostCmd_CMD_802_11_SCAN_EXT: - ret = mwifiex_ret_802_11_scan_ext(priv); + ret = mwifiex_ret_802_11_scan_ext(priv, resp); adapter->curr_cmd->wait_q_enabled = false; break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: -- GitLab From 6bc6c49f1e2f3ab1bec05d1c08aad219ab4eb5d0 Mon Sep 17 00:00:00 2001 From: Xinming Hu Date: Fri, 31 Oct 2014 16:08:27 +0530 Subject: [PATCH 2382/9457] mwifiex: add cfg80211 dump_survey handler This patch add cfg80211 dump_survey handler for mwifiex. This handler will be called to report channel statistics to cfg80211. This in turn adds ACS support for mwifiex AP. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 80b1a54e7792..b3c763525cc0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -992,6 +992,52 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, return mwifiex_dump_station_info(priv, sinfo); } +static int +mwifiex_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev, + int idx, struct survey_info *survey) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct mwifiex_chan_stats *pchan_stats = priv->adapter->chan_stats; + enum ieee80211_band band; + + dev_dbg(priv->adapter->dev, "dump_survey idx=%d\n", idx); + + memset(survey, 0, sizeof(struct survey_info)); + + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + priv->media_connected && idx == 0) { + u8 curr_bss_band = priv->curr_bss_params.band; + u32 chan = priv->curr_bss_params.bss_descriptor.channel; + + band = mwifiex_band_to_radio_type(curr_bss_band); + survey->channel = ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(chan, band)); + + if (priv->bcn_nf_last) { + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = priv->bcn_nf_last; + } + return 0; + } + + if (idx >= priv->adapter->num_in_chan_stats) + return -ENOENT; + + if (!pchan_stats[idx].cca_scan_dur) + return 0; + + band = pchan_stats[idx].bandcfg; + survey->channel = ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band)); + survey->filled = SURVEY_INFO_NOISE_DBM | + SURVEY_INFO_CHANNEL_TIME | SURVEY_INFO_CHANNEL_TIME_BUSY; + survey->noise = pchan_stats[idx].noise; + survey->channel_time = pchan_stats[idx].cca_scan_dur; + survey->channel_time_busy = pchan_stats[idx].cca_busy_dur; + + return 0; +} + /* Supported rates to be advertised to the cfg80211 */ static struct ieee80211_rate mwifiex_rates[] = { {.bitrate = 10, .hw_value = 2, }, @@ -2779,6 +2825,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .disconnect = mwifiex_cfg80211_disconnect, .get_station = mwifiex_cfg80211_get_station, .dump_station = mwifiex_cfg80211_dump_station, + .dump_survey = mwifiex_cfg80211_dump_survey, .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, .join_ibss = mwifiex_cfg80211_join_ibss, .leave_ibss = mwifiex_cfg80211_leave_ibss, -- GitLab From 31aa860e0aafd3a7c5a31c2aae67b6534115ea41 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 31 Oct 2014 11:47:54 -0700 Subject: [PATCH 2383/9457] bonding: add bond_tx_drop() helper Because bonding stats are usually sum of slave stats, it was not easy to account for tx drops at bonding layer. We can use dev->tx_dropped for this, as this counter is later added to the device stats (in dev_get_stats()) This extends the idea we had in commit ee6377147409a ("bonding: Simplify the xmit function for modes that use xmit_hash") for bond_3ad_xor_xmit() to other bonding modes. Signed-off-by: Eric Dumazet Cc: Mahesh Bandewar Reviewed-by: Nikolay Aleksandrov Acked-by: Mahesh Bandewar Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 2 +- drivers/net/bonding/bond_main.c | 15 +++++++-------- drivers/net/bonding/bonding.h | 6 ++++++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index d2eadab787c5..baa58e79256a 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1326,7 +1326,7 @@ static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond, } /* no suitable interface, frame not sent */ - dev_kfree_skb_any(skb); + bond_tx_drop(bond->dev, skb); out: return NETDEV_TX_OK; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c9ac06cfe6b7..c7520082fb0d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3522,7 +3522,7 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl } } /* no slave that can tx has been found */ - dev_kfree_skb_any(skb); + bond_tx_drop(bond->dev, skb); } /** @@ -3584,7 +3584,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev slave_id = bond_rr_gen_slave_id(bond); bond_xmit_slave_id(bond, skb, slave_id % slave_cnt); } else { - dev_kfree_skb_any(skb); + bond_tx_drop(bond_dev, skb); } } @@ -3603,7 +3603,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d if (slave) bond_dev_queue_xmit(bond, skb, slave->dev); else - dev_kfree_skb_any(skb); + bond_tx_drop(bond_dev, skb); return NETDEV_TX_OK; } @@ -3747,8 +3747,7 @@ int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev) slave = slaves->arr[bond_xmit_hash(bond, skb) % count]; bond_dev_queue_xmit(bond, skb, slave->dev); } else { - dev_kfree_skb_any(skb); - atomic_long_inc(&dev->tx_dropped); + bond_tx_drop(dev, skb); } return NETDEV_TX_OK; @@ -3778,7 +3777,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) if (slave && bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) bond_dev_queue_xmit(bond, skb, slave->dev); else - dev_kfree_skb_any(skb); + bond_tx_drop(bond_dev, skb); return NETDEV_TX_OK; } @@ -3858,7 +3857,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev /* Should never happen, mode already checked */ netdev_err(dev, "Unknown bonding mode %d\n", BOND_MODE(bond)); WARN_ON_ONCE(1); - dev_kfree_skb_any(skb); + bond_tx_drop(dev, skb); return NETDEV_TX_OK; } } @@ -3878,7 +3877,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) if (bond_has_slaves(bond)) ret = __bond_start_xmit(skb, dev); else - dev_kfree_skb_any(skb); + bond_tx_drop(dev, skb); rcu_read_unlock(); return ret; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 10920f0686e2..bfb0b51c081a 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -645,4 +645,10 @@ extern struct bond_parm_tbl ad_select_tbl[]; /* exported from bond_netlink.c */ extern struct rtnl_link_ops bond_link_ops; +static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb) +{ + atomic_long_inc(&dev->tx_dropped); + dev_kfree_skb_any(skb); +} + #endif /* _LINUX_BONDING_H */ -- GitLab From 0089b745df2e1b0bee0b1bb1a7f62a7cec961066 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 31 Oct 2014 12:57:20 -0300 Subject: [PATCH 2384/9457] ethernet: mvneta: Use PHY status standard message Use phy_print_status() to report a change in the PHY status. The current message is not verbose enough, so this commit improves it by using the generic status message. After this change, the kernel reports PHY status down and up events as: mvneta f1070000.ethernet eth0: Link is Down mvneta f1070000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx Signed-off-by: Ezequiel Garcia Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index ade067de1689..ccc3ce2e8c8c 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -2558,11 +2558,10 @@ static void mvneta_adjust_link(struct net_device *ndev) MVNETA_GMAC_FORCE_LINK_DOWN); mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); mvneta_port_up(pp); - netdev_info(pp->dev, "link up\n"); } else { mvneta_port_down(pp); - netdev_info(pp->dev, "link down\n"); } + phy_print_status(phydev); } } -- GitLab From 35532c211b1feda52078685bef0bf9b5f3b0991c Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Fri, 31 Oct 2014 13:28:54 -0400 Subject: [PATCH 2385/9457] drivers: net: cpsw: Fix broken loop condition in switch mode 0d961b3b52f566f823070ce2366511a7f64b928c (drivers: net: cpsw: fix buggy loop condition) accidentally fixed a loop comparison in too many places while fixing a real bug. It was correct to fix the dual_emac mode section since there 'i' is used as an index into priv->slaves which is a 0 based array. However the other two changes (which are only used in switch mode) are wrong since there 'i' is actually the ALE port number, and port 0 is the host port, while port 1 and up are the slave ports. Putting the loop condition back in the switch mode section fixes it. A comment has been added to point out the intent clearly to avoid future confusion. Also a comment is fixed that said the opposite of what was actually happening. Signed-off-by: Len Sorensen Acked-by: Heiko Schocher Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 952e1e4764b7..4683196c6592 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -591,8 +591,8 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) if (enable) { unsigned long timeout = jiffies + HZ; - /* Disable Learn for all ports */ - for (i = 0; i < priv->data.slaves; i++) { + /* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */ + for (i = 0; i <= priv->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 1); cpsw_ale_control_set(ale, i, @@ -616,11 +616,11 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); dev_dbg(&ndev->dev, "promiscuity enabled\n"); } else { - /* Flood All Unicast Packets to Host port */ + /* Don't Flood All Unicast Packets to Host port */ cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); - /* Enable Learn for all ports */ - for (i = 0; i < priv->data.slaves; i++) { + /* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */ + for (i = 0; i <= priv->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 0); cpsw_ale_control_set(ale, i, -- GitLab From 10738eeaf4ab3de092586cefcc082e7d43ca0044 Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Fri, 31 Oct 2014 13:38:52 -0400 Subject: [PATCH 2386/9457] drivers: net: cpsw: Support ALLMULTI and fix IFF_PROMISC in switch mode The cpsw driver did not support the IFF_ALLMULTI flag which makes dynamic multicast routing not work. Related to this, when enabling IFF_PROMISC in switch mode, all registered multicast addresses are flushed, resulting in only broadcast and unicast traffic being received. A new cpsw_ale_set_allmulti function now scans through the ALE entry table and adds/removes the host port from the unregistered multicast port mask of each vlan entry depending on the state of IFF_ALLMULTI. In promiscious mode, cpsw_ale_set_allmulti is used to force reception of all multicast traffic in addition to the unicast and broadcast traffic. With this change dynamic multicast and promiscious mode both work in switch mode. Signed-off-by: Len Sorensen Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 20 ++++++++++++++++++-- drivers/net/ethernet/ti/cpsw_ale.c | 29 +++++++++++++++++++++++++++++ drivers/net/ethernet/ti/cpsw_ale.h | 2 ++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 4683196c6592..96a61d169215 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -638,12 +638,16 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ cpsw_set_promiscious(ndev, true); + cpsw_ale_set_allmulti(priv->ale, IFF_ALLMULTI); return; } else { /* Disable promiscuous mode */ cpsw_set_promiscious(ndev, false); } + /* Restore allmulti on vlans if necessary */ + cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); + /* Clear all mcast from ALE */ cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); @@ -1149,6 +1153,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) const int port = priv->host_port; u32 reg; int i; + int unreg_mcast_mask; reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : CPSW2_PORT_VLAN; @@ -1158,9 +1163,14 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) for (i = 0; i < priv->data.slaves; i++) slave_write(priv->slaves + i, vlan, reg); + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port, ALE_ALL_PORTS << port, ALE_ALL_PORTS << port, - (ALE_PORT_1 | ALE_PORT_2) << port); + unreg_mcast_mask << port); } static void cpsw_init_host_port(struct cpsw_priv *priv) @@ -1620,11 +1630,17 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, unsigned short vid) { int ret; + int unreg_mcast_mask; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; ret = cpsw_ale_add_vlan(priv->ale, vid, ALE_ALL_PORTS << priv->host_port, 0, ALE_ALL_PORTS << priv->host_port, - (ALE_PORT_1 | ALE_PORT_2) << priv->host_port); + unreg_mcast_mask << priv->host_port); if (ret != 0) return ret; diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 0579b2243bb6..3ae83879a75f 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -443,6 +443,35 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) return 0; } +void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti) +{ + u32 ale_entry[ALE_ENTRY_WORDS]; + int type, idx; + int unreg_mcast = 0; + + /* Only bother doing the work if the setting is actually changing */ + if (ale->allmulti == allmulti) + return; + + /* Remember the new setting to check against next time */ + ale->allmulti = allmulti; + + for (idx = 0; idx < ale->params.ale_entries; idx++) { + cpsw_ale_read(ale, idx, ale_entry); + type = cpsw_ale_get_entry_type(ale_entry); + if (type != ALE_TYPE_VLAN) + continue; + + unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry); + if (allmulti) + unreg_mcast |= 1; + else + unreg_mcast &= ~1; + cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast); + cpsw_ale_write(ale, idx, ale_entry); + } +} + struct ale_control_info { const char *name; int offset, port_offset; diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index 31cf43cab42e..c0d4127aa549 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h @@ -27,6 +27,7 @@ struct cpsw_ale { struct cpsw_ale_params params; struct timer_list timer; unsigned long ageout; + int allmulti; }; enum cpsw_ale_control { @@ -103,6 +104,7 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, int reg_mcast, int unreg_mcast); int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port); +void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti); int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control); int cpsw_ale_control_set(struct cpsw_ale *ale, int port, -- GitLab From 1a5b472bde752783e0a31b59c61c9ff5b37a0983 Mon Sep 17 00:00:00 2001 From: Rohit Date: Wed, 15 Oct 2014 17:40:41 +0530 Subject: [PATCH 2387/9457] Security: smack: replace kzalloc with kmem_cache for inode_smack The patch use kmem_cache to allocate/free inode_smack since they are alloced in high volumes making it a perfect case for kmem_cache. As per analysis, 24 bytes of memory is wasted per allocation due to internal fragmentation. With kmem_cache, this can be avoided. Accounting of memory allocation is below : total slack net count-alloc/free caller Before (with kzalloc) 1919872 719952 1919872 29998/0 new_inode_smack+0x14 After (with kmem_cache) 1201680 0 1201680 30042/0 new_inode_smack+0x18 >From above data, we found that 719952 bytes(~700 KB) of memory is saved on allocation of 29998 smack inodes. Signed-off-by: Rohit --- security/smack/smack_lsm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 93dc876734a4..2717cdd7872c 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -53,6 +53,7 @@ #define SMK_SENDING 2 LIST_HEAD(smk_ipv6_port_list); +static struct kmem_cache *smack_inode_cache; #ifdef CONFIG_SECURITY_SMACK_BRINGUP static void smk_bu_mode(int mode, char *s) @@ -240,7 +241,7 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) { struct inode_smack *isp; - isp = kzalloc(sizeof(struct inode_smack), GFP_NOFS); + isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS); if (isp == NULL) return NULL; @@ -767,7 +768,7 @@ static int smack_inode_alloc_security(struct inode *inode) */ static void smack_inode_free_security(struct inode *inode) { - kfree(inode->i_security); + kmem_cache_free(smack_inode_cache, inode->i_security); inode->i_security = NULL; } @@ -4265,10 +4266,16 @@ static __init int smack_init(void) if (!security_module_enable(&smack_ops)) return 0; + smack_inode_cache = KMEM_CACHE(inode_smack, 0); + if (!smack_inode_cache) + return -ENOMEM; + tsp = new_task_smack(&smack_known_floor, &smack_known_floor, GFP_KERNEL); - if (tsp == NULL) + if (tsp == NULL) { + kmem_cache_destroy(smack_inode_cache); return -ENOMEM; + } printk(KERN_INFO "Smack: Initializing.\n"); -- GitLab From ac7576f4b1da8c9c6bc1ae026c2b9e86ae617ba5 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 30 Oct 2014 17:37:34 +0100 Subject: [PATCH 2388/9457] vfs: make first argument of dir_context.actor typed Signed-off-by: Miklos Szeredi Signed-off-by: Al Viro --- arch/alpha/kernel/osf_sys.c | 7 ++++--- arch/parisc/hpux/fs.c | 7 ++++--- .../staging/lustre/lustre/llite/llite_nfs.c | 8 ++++--- fs/afs/dir.c | 9 ++++---- fs/compat.c | 21 ++++++++++++------- fs/ecryptfs/file.c | 6 +++--- fs/exportfs/expfs.c | 5 +++-- fs/fat/dir.c | 5 +++-- fs/gfs2/export.c | 8 ++++--- fs/hppfs/hppfs.c | 5 +++-- fs/nfsd/nfs4recover.c | 5 +++-- fs/nfsd/vfs.c | 12 ++++++----- fs/nfsd/vfs.h | 4 ++-- fs/ocfs2/dir.c | 8 ++++--- fs/ocfs2/journal.c | 8 ++++--- fs/overlayfs/readdir.c | 8 ++++--- fs/readdir.c | 21 +++++++++++-------- fs/reiserfs/xattr.c | 15 +++++++------ include/linux/fs.h | 5 ++++- 19 files changed, 100 insertions(+), 67 deletions(-) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index f9c732e18284..e51f578636a5 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -104,11 +104,12 @@ struct osf_dirent_callback { }; static int -osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) +osf_filldir(struct dir_context *ctx, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { struct osf_dirent __user *dirent; - struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; + struct osf_dirent_callback *buf = + container_of(ctx, struct osf_dirent_callback, ctx); unsigned int reclen = ALIGN(NAME_OFFSET + namlen + 1, sizeof(u32)); unsigned int d_ino; diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 2bedafea3d94..97a7bf8df348 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -56,11 +56,12 @@ struct getdents_callback { #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -static int filldir(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned d_type) +static int filldir(struct dir_context *ctx, const char *name, int namlen, + loff_t offset, u64 ino, unsigned d_type) { struct hpux_dirent __user * dirent; - struct getdents_callback * buf = (struct getdents_callback *) __buf; + struct getdents_callback *buf = + container_of(ctx, struct getdents_callback, ctx); ino_t d_ino; int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(long)); diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c index ae3a12ab7fa1..243a7840457f 100644 --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c @@ -207,13 +207,15 @@ static int ll_encode_fh(struct inode *inode, __u32 *fh, int *plen, return LUSTRE_NFS_FID; } -static int ll_nfs_get_name_filldir(void *cookie, const char *name, int namelen, - loff_t hash, u64 ino, unsigned type) +static int ll_nfs_get_name_filldir(struct dir_context *ctx, const char *name, + int namelen, loff_t hash, u64 ino, + unsigned type) { /* It is hack to access lde_fid for comparison with lgd_fid. * So the input 'name' must be part of the 'lu_dirent'. */ struct lu_dirent *lde = container_of0(name, struct lu_dirent, lde_name); - struct ll_getname_data *lgd = cookie; + struct ll_getname_data *lgd = + container_of(ctx, struct ll_getname_data, ctx); struct lu_fid fid; fid_le_to_cpu(&fid, &lde->lde_fid); diff --git a/fs/afs/dir.c b/fs/afs/dir.c index a1645b88fe8a..d452f3de5434 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -26,7 +26,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx); static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); static int afs_d_delete(const struct dentry *dentry); static void afs_d_release(struct dentry *dentry); -static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, +static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, loff_t fpos, u64 ino, unsigned dtype); static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl); @@ -391,10 +391,11 @@ static int afs_readdir(struct file *file, struct dir_context *ctx) * - if afs_dir_iterate_block() spots this function, it'll pass the FID * uniquifier through dtype */ -static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, - loff_t fpos, u64 ino, unsigned dtype) +static int afs_lookup_filldir(struct dir_context *ctx, const char *name, + int nlen, loff_t fpos, u64 ino, unsigned dtype) { - struct afs_lookup_cookie *cookie = _cookie; + struct afs_lookup_cookie *cookie = + container_of(ctx, struct afs_lookup_cookie, ctx); _enter("{%s,%u},%s,%u,,%llu,%u", cookie->name.name, cookie->name.len, name, nlen, diff --git a/fs/compat.c b/fs/compat.c index b13df99f3534..6fd272d455e4 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -847,10 +847,12 @@ struct compat_readdir_callback { int result; }; -static int compat_fillonedir(void *__buf, const char *name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) +static int compat_fillonedir(struct dir_context *ctx, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int d_type) { - struct compat_readdir_callback *buf = __buf; + struct compat_readdir_callback *buf = + container_of(ctx, struct compat_readdir_callback, ctx); struct compat_old_linux_dirent __user *dirent; compat_ulong_t d_ino; @@ -915,11 +917,12 @@ struct compat_getdents_callback { int error; }; -static int compat_filldir(void *__buf, const char *name, int namlen, +static int compat_filldir(struct dir_context *ctx, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { struct compat_linux_dirent __user * dirent; - struct compat_getdents_callback *buf = __buf; + struct compat_getdents_callback *buf = + container_of(ctx, struct compat_getdents_callback, ctx); compat_ulong_t d_ino; int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + namlen + 2, sizeof(compat_long_t)); @@ -1001,11 +1004,13 @@ struct compat_getdents_callback64 { int error; }; -static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) +static int compat_filldir64(struct dir_context *ctx, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int d_type) { struct linux_dirent64 __user *dirent; - struct compat_getdents_callback64 *buf = __buf; + struct compat_getdents_callback64 *buf = + container_of(ctx, struct compat_getdents_callback64, ctx); int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, sizeof(u64)); u64 off; diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index f5bce9096555..80154ec4f8c2 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -75,11 +75,11 @@ struct ecryptfs_getdents_callback { /* Inspired by generic filldir in fs/readdir.c */ static int -ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, - loff_t offset, u64 ino, unsigned int d_type) +ecryptfs_filldir(struct dir_context *ctx, const char *lower_name, + int lower_namelen, loff_t offset, u64 ino, unsigned int d_type) { struct ecryptfs_getdents_callback *buf = - (struct ecryptfs_getdents_callback *)dirent; + container_of(ctx, struct ecryptfs_getdents_callback, ctx); size_t name_size; char *name; int rc; diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index b01fbfb51f43..a2b350ddd402 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -241,10 +241,11 @@ struct getdents_callback { * A rather strange filldir function to capture * the name matching the specified inode number. */ -static int filldir_one(void * __buf, const char * name, int len, +static int filldir_one(struct dir_context *ctx, const char *name, int len, loff_t pos, u64 ino, unsigned int d_type) { - struct getdents_callback *buf = __buf; + struct getdents_callback *buf = + container_of(ctx, struct getdents_callback, ctx); int result = 0; buf->sequence++; diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3963ede84eb0..c5d6bb939d19 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -702,10 +702,11 @@ static int fat_readdir(struct file *file, struct dir_context *ctx) } #define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \ -static int func(void *__buf, const char *name, int name_len, \ +static int func(struct dir_context *ctx, const char *name, int name_len, \ loff_t offset, u64 ino, unsigned int d_type) \ { \ - struct fat_ioctl_filldir_callback *buf = __buf; \ + struct fat_ioctl_filldir_callback *buf = \ + container_of(ctx, struct fat_ioctl_filldir_callback, ctx); \ struct dirent_type __user *d1 = buf->dirent; \ struct dirent_type __user *d2 = d1 + 1; \ \ diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 8b9b3775e2e7..c41d255b6a7b 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c @@ -69,10 +69,12 @@ struct get_name_filldir { char *name; }; -static int get_name_filldir(void *opaque, const char *name, int length, - loff_t offset, u64 inum, unsigned int type) +static int get_name_filldir(struct dir_context *ctx, const char *name, + int length, loff_t offset, u64 inum, + unsigned int type) { - struct get_name_filldir *gnfd = opaque; + struct get_name_filldir *gnfd = + container_of(ctx, struct get_name_filldir, ctx); if (inum != gnfd->inum.no_addr) return 0; diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 4338ff32959d..5f2755117ce7 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c @@ -548,10 +548,11 @@ struct hppfs_dirent { struct dentry *dentry; }; -static int hppfs_filldir(void *d, const char *name, int size, +static int hppfs_filldir(struct dir_context *ctx, const char *name, int size, loff_t offset, u64 inode, unsigned int type) { - struct hppfs_dirent *dirent = d; + struct hppfs_dirent *dirent = + container_of(ctx, struct hppfs_dirent, ctx); if (file_removed(dirent->dentry, name)) return 0; diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index a25490ae6c62..0e71a0dd58ca 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -245,10 +245,11 @@ struct nfs4_dir_ctx { }; static int -nfsd4_build_namelist(void *arg, const char *name, int namlen, +nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { - struct nfs4_dir_ctx *ctx = arg; + struct nfs4_dir_ctx *ctx = + container_of(__ctx, struct nfs4_dir_ctx, ctx); struct name_list *entry; if (namlen != HEXDIR_LEN - 1) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 989129e2d6ea..161d2d51b6f2 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1819,10 +1819,12 @@ struct readdir_data { int full; }; -static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) +static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int d_type) { - struct readdir_data *buf = __buf; + struct readdir_data *buf = + container_of(ctx, struct readdir_data, ctx); struct buffered_dirent *de = (void *)(buf->dirent + buf->used); unsigned int reclen; @@ -1842,7 +1844,7 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen, return 0; } -static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func, +static __be32 nfsd_buffered_readdir(struct file *file, nfsd_filldir_t func, struct readdir_cd *cdp, loff_t *offsetp) { struct buffered_dirent *de; @@ -1926,7 +1928,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func, */ __be32 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, - struct readdir_cd *cdp, filldir_t func) + struct readdir_cd *cdp, nfsd_filldir_t func) { __be32 err; struct file *file; diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index c2ff3f14e5f6..b1796d6ee538 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -36,7 +36,7 @@ /* * Callback function for readdir */ -typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); +typedef int (*nfsd_filldir_t)(void *, const char *, int, loff_t, u64, unsigned); /* nfsd/vfs.c */ int nfsd_racache_init(int); @@ -95,7 +95,7 @@ __be32 nfsd_rename(struct svc_rqst *, __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, char *name, int len); __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, - loff_t *, struct readdir_cd *, filldir_t); + loff_t *, struct readdir_cd *, nfsd_filldir_t); __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, struct kstatfs *, int access); diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 0717662b4aef..c43d9b4a1ec0 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -2073,10 +2073,12 @@ struct ocfs2_empty_dir_priv { unsigned seen_other; unsigned dx_dir; }; -static int ocfs2_empty_dir_filldir(void *priv, const char *name, int name_len, - loff_t pos, u64 ino, unsigned type) +static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name, + int name_len, loff_t pos, u64 ino, + unsigned type) { - struct ocfs2_empty_dir_priv *p = priv; + struct ocfs2_empty_dir_priv *p = + container_of(ctx, struct ocfs2_empty_dir_priv, ctx); /* * Check the positions of "." and ".." records to be sure diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 4b0c68849b36..4f502382180f 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1982,10 +1982,12 @@ struct ocfs2_orphan_filldir_priv { struct ocfs2_super *osb; }; -static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len, - loff_t pos, u64 ino, unsigned type) +static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name, + int name_len, loff_t pos, u64 ino, + unsigned type) { - struct ocfs2_orphan_filldir_priv *p = priv; + struct ocfs2_orphan_filldir_priv *p = + container_of(ctx, struct ocfs2_orphan_filldir_priv, ctx); struct inode *iter; if (name_len == 1 && !strncmp(".", name, 1)) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 4e9d7c1fea52..301f64aa8a45 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -180,10 +180,12 @@ static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry) } } -static int ovl_fill_merge(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) +static int ovl_fill_merge(struct dir_context *ctx, const char *name, + int namelen, loff_t offset, u64 ino, + unsigned int d_type) { - struct ovl_readdir_data *rdd = buf; + struct ovl_readdir_data *rdd = + container_of(ctx, struct ovl_readdir_data, ctx); rdd->count++; if (!rdd->is_merge) diff --git a/fs/readdir.c b/fs/readdir.c index 33fd92208cb7..ced679179cac 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -74,10 +74,11 @@ struct readdir_callback { int result; }; -static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) +static int fillonedir(struct dir_context *ctx, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { - struct readdir_callback *buf = (struct readdir_callback *) __buf; + struct readdir_callback *buf = + container_of(ctx, struct readdir_callback, ctx); struct old_linux_dirent __user * dirent; unsigned long d_ino; @@ -148,11 +149,12 @@ struct getdents_callback { int error; }; -static int filldir(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) +static int filldir(struct dir_context *ctx, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { struct linux_dirent __user * dirent; - struct getdents_callback * buf = (struct getdents_callback *) __buf; + struct getdents_callback *buf = + container_of(ctx, struct getdents_callback, ctx); unsigned long d_ino; int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2, sizeof(long)); @@ -232,11 +234,12 @@ struct getdents_callback64 { int error; }; -static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) +static int filldir64(struct dir_context *ctx, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { struct linux_dirent64 __user *dirent; - struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; + struct getdents_callback64 *buf = + container_of(ctx, struct getdents_callback64, ctx); int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, sizeof(u64)); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 7c36898af402..628248ce2f8b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -188,10 +188,11 @@ struct reiserfs_dentry_buf { }; static int -fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset, - u64 ino, unsigned int d_type) +fill_with_dentries(struct dir_context *ctx, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) { - struct reiserfs_dentry_buf *dbuf = buf; + struct reiserfs_dentry_buf *dbuf = + container_of(ctx, struct reiserfs_dentry_buf, ctx); struct dentry *dentry; WARN_ON_ONCE(!mutex_is_locked(&dbuf->xadir->d_inode->i_mutex)); @@ -824,10 +825,12 @@ struct listxattr_buf { struct dentry *dentry; }; -static int listxattr_filler(void *buf, const char *name, int namelen, - loff_t offset, u64 ino, unsigned int d_type) +static int listxattr_filler(struct dir_context *ctx, const char *name, + int namelen, loff_t offset, u64 ino, + unsigned int d_type) { - struct listxattr_buf *b = (struct listxattr_buf *)buf; + struct listxattr_buf *b = + container_of(ctx, struct listxattr_buf, ctx); size_t size; if (name[0] != '.' || diff --git a/include/linux/fs.h b/include/linux/fs.h index 9ab779e8a63c..00c8e4f65cb6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1467,7 +1467,10 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); * This allows the kernel to read directories into kernel space or * to have different dirent layouts depending on the binary type. */ -typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); +struct dir_context; +typedef int (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64, + unsigned); + struct dir_context { const filldir_t actor; loff_t pos; -- GitLab From a7400222e3eb7d5ce3820d2234905bbeafabd171 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Oct 2014 15:20:42 -0400 Subject: [PATCH 2389/9457] new helper: is_root_inode() replace open-coded instances Signed-off-by: Al Viro --- fs/coda/coda_linux.c | 6 ------ fs/coda/coda_linux.h | 1 - fs/coda/dir.c | 12 ++++++------ fs/ncpfs/dir.c | 4 ++-- include/linux/fs.h | 5 +++++ 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index 1326d38960db..f1714cfb589c 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c @@ -40,12 +40,6 @@ int coda_iscontrol(const char *name, size_t length) (strncmp(name, CODA_CONTROL, CODA_CONTROLLEN) == 0)); } -/* recognize /coda inode */ -int coda_isroot(struct inode *i) -{ - return ( i->i_sb->s_root->d_inode == i ); -} - unsigned short coda_flags_to_cflags(unsigned short flags) { unsigned short coda_flags = 0; diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h index d42b725b1d21..d6f7a76a1f5b 100644 --- a/fs/coda/coda_linux.h +++ b/fs/coda/coda_linux.h @@ -52,7 +52,6 @@ int coda_setattr(struct dentry *, struct iattr *); /* this file: heloers */ char *coda_f2s(struct CodaFid *f); -int coda_isroot(struct inode *i); int coda_iscontrol(const char *name, size_t length); void coda_vattr_to_iattr(struct inode *, struct coda_vattr *); diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 9c3dedc000d1..7ff025966e4f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -107,7 +107,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig } /* control object, create inode on the fly */ - if (coda_isroot(dir) && coda_iscontrol(name, length)) { + if (is_root_inode(dir) && coda_iscontrol(name, length)) { inode = coda_cnode_makectl(sb); type = CODA_NOCACHE; } else { @@ -195,7 +195,7 @@ static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool struct CodaFid newfid; struct coda_vattr attrs; - if (coda_isroot(dir) && coda_iscontrol(name, length)) + if (is_root_inode(dir) && coda_iscontrol(name, length)) return -EPERM; error = venus_create(dir->i_sb, coda_i2f(dir), name, length, @@ -227,7 +227,7 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode) int error; struct CodaFid newfid; - if (coda_isroot(dir) && coda_iscontrol(name, len)) + if (is_root_inode(dir) && coda_iscontrol(name, len)) return -EPERM; attrs.va_mode = mode; @@ -261,7 +261,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, int len = de->d_name.len; int error; - if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) + if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) return -EPERM; error = venus_link(dir_inode->i_sb, coda_i2f(inode), @@ -287,7 +287,7 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de, int symlen; int error; - if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) + if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) return -EPERM; symlen = strlen(symname); @@ -507,7 +507,7 @@ static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) return -ECHILD; inode = de->d_inode; - if (!inode || coda_isroot(inode)) + if (!inode || is_root_inode(inode)) goto out; if (is_bad_inode(inode)) goto bad; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 7cb751dfbeef..461f6be5df20 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -198,8 +198,8 @@ ncp_single_volume(struct ncp_server *server) static inline int ncp_is_server_root(struct inode *inode) { - return (!ncp_single_volume(NCP_SERVER(inode)) && - inode == inode->i_sb->s_root->d_inode); + return !ncp_single_volume(NCP_SERVER(inode)) && + is_root_inode(inode); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 00c8e4f65cb6..1c12c681803f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2789,6 +2789,11 @@ static inline void inode_has_no_xattr(struct inode *inode) inode->i_flags |= S_NOSEC; } +static inline bool is_root_inode(struct inode *inode) +{ + return inode == inode->i_sb->s_root->d_inode; +} + static inline bool dir_emit(struct dir_context *ctx, const char *name, int namelen, u64 ino, unsigned type) -- GitLab From 9198f509c888f1ca8f5a50047d702b1ab29459a5 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Wed, 29 Oct 2014 19:51:59 +0800 Subject: [PATCH 2390/9457] pinctrl: rockchip: add suspend/resume functions support suspend/resume of pinctrl, it allows handling sleep mode for hogged pins in pinctrl Signed-off-by: Chris Zhong Tested-by: Doug Anderson Reviewed-by: Doug Anderson Tested-by: Heiko Stuebner Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 59a54617bf75..28b12187c2c1 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1796,6 +1796,23 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( return ctrl; } +static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) +{ + struct rockchip_pinctrl *info = dev_get_drvdata(dev); + + return pinctrl_force_sleep(info->pctl_dev); +} + +static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) +{ + struct rockchip_pinctrl *info = dev_get_drvdata(dev); + + return pinctrl_force_default(info->pctl_dev); +} + +static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, + rockchip_pinctrl_resume); + static int rockchip_pinctrl_probe(struct platform_device *pdev) { struct rockchip_pinctrl *info; @@ -2009,6 +2026,7 @@ static struct platform_driver rockchip_pinctrl_driver = { .driver = { .name = "rockchip-pinctrl", .owner = THIS_MODULE, + .pm = &rockchip_pinctrl_dev_pm_ops, .of_match_table = rockchip_pinctrl_dt_match, }, }; -- GitLab From 8dca9331270240125fedbe83e0a2cd5750ed9fff Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Wed, 29 Oct 2014 19:52:00 +0800 Subject: [PATCH 2391/9457] pinctrl: rockchip: save and restore gpio6_c6 pinmux in suspend/resume Save and restore the gpio6_c6 pinmux setting, since Maskrom of RK3288 would modify it to sdmmc0_det, so it need to be restored to the correct setting after resume from Maskrom. Signed-off-by: Chris Zhong Tested-by: Doug Anderson Reviewed-by: Doug Anderson Tested-by: Heiko Stuebner Signed-off-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 28b12187c2c1..40970c305dd0 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1796,16 +1796,44 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( return ctrl; } +#define RK3288_GRF_GPIO6C_IOMUX 0x64 +#define GPIO6C6_SEL_WRITE_ENABLE BIT(28) + +static u32 rk3288_grf_gpio6c_iomux; + static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) { struct rockchip_pinctrl *info = dev_get_drvdata(dev); + int ret = pinctrl_force_sleep(info->pctl_dev); + + if (ret) + return ret; + + /* + * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save + * the setting here, and restore it at resume. + */ + if (info->ctrl->type == RK3288) { + ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, + &rk3288_grf_gpio6c_iomux); + if (ret) { + pinctrl_force_default(info->pctl_dev); + return ret; + } + } - return pinctrl_force_sleep(info->pctl_dev); + return 0; } static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) { struct rockchip_pinctrl *info = dev_get_drvdata(dev); + int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, + rk3288_grf_gpio6c_iomux | + GPIO6C6_SEL_WRITE_ENABLE); + + if (ret) + return ret; return pinctrl_force_default(info->pctl_dev); } -- GitLab From 082417d10fafe7be835d143ade7114b5ce26cb50 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Thu, 30 Oct 2014 19:43:55 -0300 Subject: [PATCH 2392/9457] [media] cx231xx: remove direct register PWR_CTL_EN modification that switches port3 The only remaining place that modifies the relevant bit is in function cx231xx_set_Colibri_For_LowIF Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index b56bc8779074..781908b5a1a3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2270,7 +2270,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) case POLARIS_AVMODE_ANALOGT_TV: tmp |= PWR_DEMOD_EN; - tmp |= (I2C_DEMOD_EN); value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); value[2] = (u8) (tmp >> 16); @@ -2366,7 +2365,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } tmp &= (~PWR_AV_MODE); - tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN; + tmp |= POLARIS_AVMODE_DIGITAL; value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); value[2] = (u8) (tmp >> 16); -- GitLab From 039fada5cd1963c32ed13d18d0dd467fdf966b66 Mon Sep 17 00:00:00 2001 From: Chan-yeol Park Date: Fri, 31 Oct 2014 14:23:06 +0900 Subject: [PATCH 2393/9457] Bluetooth: Fix hci_sync missing wakeup interrupt __hci_cmd_sync_ev(), __hci_req_sync() could miss wake_up_interrupt from hci_req_sync_complete() because hci_cmd_work() workqueue and its response could be completed before they are ready to get the signal through add_wait_queue(), set_current_state(TASK_INTERRUPTIBLE). Signed-off-by: Chan-yeol Park Signed-off-by: Kyungmin Park Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 91995f8ab0a0..41b147c36d11 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1147,13 +1147,15 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, hdev->req_status = HCI_REQ_PEND; - err = hci_req_run(&req, hci_req_sync_complete); - if (err < 0) - return ERR_PTR(err); - add_wait_queue(&hdev->req_wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); + err = hci_req_run(&req, hci_req_sync_complete); + if (err < 0) { + remove_wait_queue(&hdev->req_wait_q, &wait); + return ERR_PTR(err); + } + schedule_timeout(timeout); remove_wait_queue(&hdev->req_wait_q, &wait); @@ -1211,10 +1213,15 @@ static int __hci_req_sync(struct hci_dev *hdev, func(&req, opt); + add_wait_queue(&hdev->req_wait_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + err = hci_req_run(&req, hci_req_sync_complete); if (err < 0) { hdev->req_status = 0; + remove_wait_queue(&hdev->req_wait_q, &wait); + /* ENODATA means the HCI request command queue is empty. * This can happen when a request with conditionals doesn't * trigger any commands to be sent. This is normal behavior @@ -1226,9 +1233,6 @@ static int __hci_req_sync(struct hci_dev *hdev, return err; } - add_wait_queue(&hdev->req_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); remove_wait_queue(&hdev->req_wait_q, &wait); -- GitLab From fe23bcd920015bfb655f4b3d129a9368ce8e660c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:32 +0100 Subject: [PATCH 2394/9457] at86rf230: fix page parameter constraints Since commit e37d2ec82a222f1819e7793a27bc052999a379fb ("mac802154: ops: declare channel and page as u8") the page parameter can't be below zero. This patch fix a kbuild test robot warning. Furthermore this check should be removed and handled by netlink 802.15.4 interface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 9ad2d432ef43..624080d97209 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1047,7 +1047,7 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel) struct at86rf230_local *lp = hw->priv; int rc; - if (page < 0 || page > 31 || + if (page > 31 || !(lp->hw->phy->channels_supported[page] & BIT(channel))) { WARN_ON(1); return -EINVAL; -- GitLab From ff4e65581eb5349b7cefeda4083abe6eba44378a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:33 +0100 Subject: [PATCH 2395/9457] ieee802154: remove default channel settings This patch removes the default channel setting. A channel is always set and there is no default channel setting according 802.15.4. Drivers should set the default channel and page in probing routine. This behaviour is currently a lack of all 802.15.4 drivers. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 620abc2ba5fc..dc294a415d05 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -100,9 +100,6 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size) phy->dev.class = &wpan_phy_class; - phy->current_channel = -1; /* not initialised */ - phy->current_page = 0; /* for compatibility */ - return phy; out: -- GitLab From fe58d016e396fc685364b5a1743faf83c1fb8103 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:34 +0100 Subject: [PATCH 2396/9457] at86rf230: add default channel settings This patch sets the reset state channels accoridng at86rf2xx datasheets. We don't need to set the default page here which is zero on all chips. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 624080d97209..f68ebba91b10 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1427,6 +1427,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) chip = "at86rf231"; lp->data = &at86rf231_data; lp->hw->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->current_channel = 11; break; case 7: chip = "at86rf212"; @@ -1435,6 +1436,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) lp->hw->flags |= IEEE802154_HW_LBT; lp->hw->phy->channels_supported[0] = 0x00007FF; lp->hw->phy->channels_supported[2] = 0x00007FF; + lp->hw->phy->current_channel = 5; } else { rc = -ENOTSUPP; } @@ -1443,6 +1445,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) chip = "at86rf233"; lp->data = &at86rf233_data; lp->hw->phy->channels_supported[0] = 0x7FFF800; + lp->hw->phy->current_channel = 13; break; default: chip = "unkown"; -- GitLab From a5dd1d72d868ec9c8f44d60ca29900b6a38321b4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:35 +0100 Subject: [PATCH 2397/9457] cfg802154: introduce cfg802154_registered_device This patch introduce the cfg802154_registered_device struct. Like cfg80211_registered_device in wireless this should contain similar functionality for cfg802154. This patch should not change any behaviour. We just adds cfg802154_registered_device as container for wpan_phy struct. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 8 +++++++- net/ieee802154/core.c | 39 ++++++++++++++++++++++++++------------- net/ieee802154/core.h | 18 ++++++++++++++++++ net/ieee802154/sysfs.c | 15 ++++++++++++--- net/mac802154/main.c | 2 +- 5 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 net/ieee802154/core.h diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 440b9bece9c6..12de66bda9a5 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -29,6 +29,11 @@ #define WPAN_NUM_CHANNELS 27 #define WPAN_NUM_PAGES 32 +struct wpan_phy; + +struct cfg802154_ops { +}; + struct wpan_phy { struct mutex pib_lock; @@ -62,7 +67,8 @@ struct wpan_phy { #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) -struct wpan_phy *wpan_phy_alloc(size_t priv_size); +struct wpan_phy * +wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size); static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) { phy->dev.parent = dev; diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index dc294a415d05..ed5b014dbec7 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -21,6 +21,7 @@ #include "ieee802154.h" #include "sysfs.h" +#include "core.h" static DEFINE_MUTEX(wpan_phy_mutex); static int wpan_phy_idx; @@ -76,31 +77,38 @@ static int wpan_phy_idx_valid(int idx) return idx >= 0; } -struct wpan_phy *wpan_phy_alloc(size_t priv_size) +struct wpan_phy * +wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size) { - struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size, - GFP_KERNEL); + struct cfg802154_registered_device *rdev; + size_t alloc_size; + + alloc_size = sizeof(*rdev) + priv_size; + rdev = kzalloc(alloc_size, GFP_KERNEL); + if (!rdev) + return NULL; + + rdev->ops = ops; - if (!phy) - goto out; mutex_lock(&wpan_phy_mutex); - phy->idx = wpan_phy_idx++; - if (unlikely(!wpan_phy_idx_valid(phy->idx))) { + rdev->wpan_phy.idx = wpan_phy_idx++; + if (unlikely(!wpan_phy_idx_valid(rdev->wpan_phy.idx))) { wpan_phy_idx--; mutex_unlock(&wpan_phy_mutex); - kfree(phy); + kfree(rdev); goto out; } mutex_unlock(&wpan_phy_mutex); - mutex_init(&phy->pib_lock); + mutex_init(&rdev->wpan_phy.pib_lock); - device_initialize(&phy->dev); - dev_set_name(&phy->dev, "wpan-phy%d", phy->idx); + device_initialize(&rdev->wpan_phy.dev); + dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy.idx); - phy->dev.class = &wpan_phy_class; + rdev->wpan_phy.dev.class = &wpan_phy_class; + rdev->wpan_phy.dev.platform_data = rdev; - return phy; + return &rdev->wpan_phy; out: return NULL; @@ -125,6 +133,11 @@ void wpan_phy_free(struct wpan_phy *phy) } EXPORT_SYMBOL(wpan_phy_free); +void cfg802154_dev_free(struct cfg802154_registered_device *rdev) +{ + kfree(rdev); +} + static int __init wpan_phy_class_init(void) { int rc; diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h new file mode 100644 index 000000000000..26752ca54b4f --- /dev/null +++ b/net/ieee802154/core.h @@ -0,0 +1,18 @@ +#ifndef __IEEE802154_CORE_H +#define __IEEE802154_CORE_H + +#include + +struct cfg802154_registered_device { + const struct cfg802154_ops *ops; + + /* must be last because of the way we do wpan_phy_priv(), + * and it should at least be aligned to NETDEV_ALIGN + */ + struct wpan_phy wpan_phy __aligned(NETDEV_ALIGN); +}; + +/* free object */ +void cfg802154_dev_free(struct cfg802154_registered_device *rdev); + +#endif /* __IEEE802154_CORE_H */ diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c index eb9ca6f99122..c6e038099e07 100644 --- a/net/ieee802154/sysfs.c +++ b/net/ieee802154/sysfs.c @@ -17,6 +17,15 @@ #include +#include "core.h" + +static inline struct cfg802154_registered_device * +dev_to_rdev(struct device *dev) +{ + return container_of(dev, struct cfg802154_registered_device, + wpan_phy.dev); +} + #define MASTER_SHOW_COMPLEX(name, format_string, args...) \ static ssize_t name ## _show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -60,11 +69,11 @@ static ssize_t channels_supported_show(struct device *dev, } static DEVICE_ATTR_RO(channels_supported); -static void wpan_phy_release(struct device *d) +static void wpan_phy_release(struct device *dev) { - struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); + struct cfg802154_registered_device *rdev = dev_to_rdev(dev); - kfree(phy); + cfg802154_dev_free(rdev); } static struct attribute *pmib_attrs[] = { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 86e533ed3775..ebc2bb123cfe 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -169,7 +169,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; - phy = wpan_phy_alloc(priv_size); + phy = wpan_phy_alloc(NULL, priv_size); if (!phy) { pr_err("failure to allocate master IEEE802.15.4 device\n"); return NULL; -- GitLab From 1201cd22fd1f4579a888c0f7abc65627d5962f29 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:36 +0100 Subject: [PATCH 2398/9457] mac802154: introduce mac802154_config_ops This patch introduces mac802154_config_ops struct. Like wireless this struct should be the only one interface between ieee802154 to mac802154 or possible HardMAC drivers. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/Makefile | 2 +- net/mac802154/cfg.c | 19 +++++++++++++++++++ net/mac802154/cfg.h | 9 +++++++++ net/mac802154/main.c | 3 ++- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 net/mac802154/cfg.c create mode 100644 net/mac802154/cfg.h diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile index 2e497d0c829a..702d8b466317 100644 --- a/net/mac802154/Makefile +++ b/net/mac802154/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_MAC802154) += mac802154.o mac802154-objs := main.o rx.o tx.o mac_cmd.o mib.o \ - iface.o llsec.o util.o + iface.o llsec.o util.o cfg.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c new file mode 100644 index 000000000000..105468ec8f26 --- /dev/null +++ b/net/mac802154/cfg.c @@ -0,0 +1,19 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/mac80211/cfg.c + */ + +#include + +const struct cfg802154_ops mac802154_config_ops = { +}; diff --git a/net/mac802154/cfg.h b/net/mac802154/cfg.h new file mode 100644 index 000000000000..e2718f981e82 --- /dev/null +++ b/net/mac802154/cfg.h @@ -0,0 +1,9 @@ +/* mac802154 configuration hooks for cfg802154 + */ + +#ifndef __CFG_H +#define __CFG_H + +extern const struct cfg802154_ops mac802154_config_ops; + +#endif /* __CFG_H */ diff --git a/net/mac802154/main.c b/net/mac802154/main.c index ebc2bb123cfe..785abb1aafb4 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "cfg.h" static int mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) @@ -169,7 +170,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; - phy = wpan_phy_alloc(NULL, priv_size); + phy = wpan_phy_alloc(&mac802154_config_ops, priv_size); if (!phy) { pr_err("failure to allocate master IEEE802.15.4 device\n"); return NULL; -- GitLab From ea4dcd32a445908c12e04b3b879c57ec5b3e659a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:37 +0100 Subject: [PATCH 2399/9457] ieee802154: add helper wpan_phy_to_rdev function This patch introduce a function to get the cfg802154_registered_device from a wpan_phy. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/core.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index 26752ca54b4f..1bc172587157 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -12,6 +12,14 @@ struct cfg802154_registered_device { struct wpan_phy wpan_phy __aligned(NETDEV_ALIGN); }; +static inline struct cfg802154_registered_device * +wpan_phy_to_rdev(struct wpan_phy *wpan_phy) +{ + BUG_ON(!wpan_phy); + return container_of(wpan_phy, struct cfg802154_registered_device, + wpan_phy); +} + /* free object */ void cfg802154_dev_free(struct cfg802154_registered_device *rdev); -- GitLab From 4a9a816a4f8c79260446811bdf80615b36539949 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:38 +0100 Subject: [PATCH 2400/9457] cfg802154: convert deprecated iface add and del This patch removes the wpan_phy callbacks for add and del an interface on a phy. Instead we introduce deprecated cfg802154 callbacks for this. Furthermore we introduce a new netlink interface nl802154 which use different callbacks. The deprecated function is to have a backwards compatibility with the current netlink interface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 9 +++++---- net/ieee802154/nl-phy.c | 19 ++++++------------- net/ieee802154/rdev-ops.h | 23 +++++++++++++++++++++++ net/mac802154/cfg.c | 17 +++++++++++++++++ net/mac802154/ieee802154_i.h | 4 ++++ net/mac802154/main.c | 8 ++------ 6 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 net/ieee802154/rdev-ops.h diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 12de66bda9a5..864bce2b0728 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -32,6 +32,11 @@ struct wpan_phy; struct cfg802154_ops { + struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, + const char *name, + int type); + void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, + struct net_device *dev); }; struct wpan_phy { @@ -58,10 +63,6 @@ struct wpan_phy { struct device dev; int idx; - struct net_device *(*add_iface)(struct wpan_phy *phy, - const char *name, int type); - void (*del_iface)(struct wpan_phy *phy, struct net_device *dev); - char priv[0] __aligned(NETDEV_ALIGN); }; diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 0afe760ff512..5d914d30e0b1 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -30,6 +30,8 @@ #include #include "ieee802154.h" +#include "rdev-ops.h" +#include "core.h" static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid, u32 seq, int flags, struct wpan_phy *phy) @@ -203,11 +205,6 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) if (!msg) goto out_dev; - if (!phy->add_iface) { - rc = -EINVAL; - goto nla_put_failure; - } - if (info->attrs[IEEE802154_ATTR_HW_ADDR] && nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) != IEEE802154_ADDR_LEN) { @@ -223,7 +220,8 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) } } - dev = phy->add_iface(phy, devname, type); + dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname, + type); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; @@ -257,7 +255,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) dev_unregister: rtnl_lock(); /* del_iface must be called with RTNL lock */ - phy->del_iface(phy, dev); + rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev); dev_put(dev); rtnl_unlock(); nla_put_failure: @@ -319,13 +317,8 @@ int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info) if (!msg) goto out_dev; - if (!phy->del_iface) { - rc = -EINVAL; - goto nla_put_failure; - } - rtnl_lock(); - phy->del_iface(phy, dev); + rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev); /* We don't have device anymore */ dev_put(dev); diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h new file mode 100644 index 000000000000..ac8824ec168c --- /dev/null +++ b/net/ieee802154/rdev-ops.h @@ -0,0 +1,23 @@ +#ifndef __CFG802154_RDEV_OPS +#define __CFG802154_RDEV_OPS + +#include + +#include "core.h" + +static inline struct net_device * +rdev_add_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, + const char *name, int type) +{ + return rdev->ops->add_virtual_intf_deprecated(&rdev->wpan_phy, name, + type); +} + +static inline void +rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, + struct net_device *dev) +{ + rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev); +} + +#endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 105468ec8f26..75a5d258ac24 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -15,5 +15,22 @@ #include +#include "ieee802154_i.h" + +static struct net_device * +ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, + const char *name, int type) +{ + return mac802154_add_iface(wpan_phy, name, type); +} + +static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, + struct net_device *dev) +{ + mac802154_del_iface(wpan_phy, dev); +} + const struct cfg802154_ops mac802154_config_ops = { + .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, + .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, }; diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 1086a9d96f8f..39af6eaec410 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -174,4 +174,8 @@ void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t); void mac802154_unlock_table(struct net_device *dev); +struct net_device * +mac802154_add_iface(struct wpan_phy *phy, const char *name, int type); +void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev); + #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 785abb1aafb4..b34ddbf43c3d 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -59,8 +59,7 @@ mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev) return 0; } -static void -mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) +void mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); @@ -76,7 +75,7 @@ mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev) unregister_netdevice(sdata->dev); } -static struct net_device * +struct net_device * mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) { struct net_device *dev; @@ -221,9 +220,6 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) wpan_phy_set_dev(local->phy, local->hw.parent); - local->phy->add_iface = mac802154_add_iface; - local->phy->del_iface = mac802154_del_iface; - rc = wpan_phy_register(local->phy); if (rc < 0) goto out_wq; -- GitLab From 8f499f991c275d5251a427c424360a9c60f549e4 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:39 +0100 Subject: [PATCH 2401/9457] ieee802154: don't allow to change addr while netif_running This patch changes the actual behaviour for setting address attributes. We should not change addresses while netif_running is true. Furthermore when netif_running is running the address attributes becomes read only and we can remove locking mechanism in receive and transmit hothpaths of 802.15.4 subsystem. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/nl-mac.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index abd0f31bdc66..cc2919dbe5e0 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -477,7 +477,7 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) u8 channel, bcn_ord, sf_ord; u8 page; int pan_coord, blx, coord_realign; - int ret = -EOPNOTSUPP; + int ret = -EBUSY; if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] || @@ -493,9 +493,15 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) dev = ieee802154_nl_get_dev(info); if (!dev) return -ENODEV; - if (!ieee802154_mlme_ops(dev)->start_req) + + if (netif_running(dev)) goto out; + if (!ieee802154_mlme_ops(dev)->start_req) { + ret = -EOPNOTSUPP; + goto out; + } + addr.mode = IEEE802154_ADDR_SHORT; addr.short_addr = nla_get_shortaddr( info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); -- GitLab From ab24f50f2a3e3f6a38b4852530534aa99d86b4d1 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:40 +0100 Subject: [PATCH 2402/9457] mac802154: add helper for converting dev_addr This patch adds a helper for converting the dev_addr attribute in netdevice to __le64 type. The dev_addr attribute is a char pointer and contains the extended address in big endian byte order. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 8f1de6844cb0..c17acbd0dadc 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -214,6 +214,15 @@ struct ieee802154_ops { const bool on); }; +/** + * ieee802154_netdev_to_extended_addr - convert __be64 u8 pointer to __le64 + * @dev_addr: big endian address pointer like netdevice dev_addr attribute + */ +static inline __le64 ieee802154_netdev_to_extended_addr(const u8 *dev_addr) +{ + return (__le64)swab64(*((__be64 *)dev_addr)); +} + /* Basic interface to register ieee802154 hwice */ struct ieee802154_hw * ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops); -- GitLab From 776e59de46b5db368e1bd0a4ec5c4feaa740a3d1 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:41 +0100 Subject: [PATCH 2403/9457] mac802154: set extended address filter on ifup This patch moves the setting of hardware extended address filtering inside of interface up instead doing it directly inside of netlink interface. Also we don't need to set the sdata extended attribute in netlink. This is already done by ndo_set_mac_address of net_device_ops. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 - net/mac802154/iface.c | 10 +++++++++- net/mac802154/mac_cmd.c | 1 - net/mac802154/mib.c | 14 -------------- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 39af6eaec410..27e17e6bcf18 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -135,7 +135,6 @@ ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); /* MIB callbacks */ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); __le16 mac802154_dev_get_short_addr(const struct net_device *dev); -void mac802154_dev_set_ieee_addr(struct net_device *dev); __le16 mac802154_dev_get_pan_id(const struct net_device *dev); void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index f7a6f83301e2..a509a7151be9 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -110,6 +110,7 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) { + struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct sockaddr *addr = p; if (netif_running(dev)) @@ -117,7 +118,8 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) /* FIXME: validate addr */ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - mac802154_dev_set_ieee_addr(dev); + sdata->extended_addr = ieee802154_netdev_to_extended_addr(dev->dev_addr); + return mac802154_wpan_update_llsec(dev); } @@ -202,6 +204,12 @@ static int mac802154_wpan_open(struct net_device *dev) goto out; } + if (local->hw.flags & IEEE802154_HW_AFILT) { + rc = drv_set_extended_addr(local, sdata->extended_addr); + if (rc < 0) + goto out; + } + if (local->hw.flags & IEEE802154_HW_TXPOWER) { rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); if (rc < 0) diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index fc261ab33347..90c1ad80a67d 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -43,7 +43,6 @@ static int mac802154_mlme_start_req(struct net_device *dev, mac802154_dev_set_pan_id(dev, addr->pan_id); mac802154_dev_set_short_addr(dev, addr->short_addr); - mac802154_dev_set_ieee_addr(dev); mac802154_dev_set_page_channel(dev, page, channel); if (ops->llsec) { diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 0184fced2f62..cfd4f657a24e 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -102,20 +102,6 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) return ret; } -void mac802154_dev_set_ieee_addr(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct ieee802154_local *local = sdata->local; - - sdata->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); - - if (local->ops->set_hw_addr_filt && - local->hw.hw_filt.ieee_addr != sdata->extended_addr) { - local->hw.hw_filt.ieee_addr = sdata->extended_addr; - set_hw_addr_filt(dev, IEEE802154_AFILT_IEEEADDR_CHANGED); - } -} - __le16 mac802154_dev_get_pan_id(const struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); -- GitLab From 78b4bad16ec41e1d3d5575ff9aca29aab2f831bc Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:42 +0100 Subject: [PATCH 2404/9457] mac802154: set short address filter on ifup This patch moves the setting of hardware short address filtering inside of interface up instead doing it it directly inside of netlink interface. The netlink call which can only be called when netif isn't running sets only the necessary short_addr value in sdata. After an interface up the address filter will be set with this value. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 4 ++++ net/mac802154/mib.c | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index a509a7151be9..1bae29dff082 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -208,6 +208,10 @@ static int mac802154_wpan_open(struct net_device *dev) rc = drv_set_extended_addr(local, sdata->extended_addr); if (rc < 0) goto out; + + rc = drv_set_short_addr(local, sdata->short_addr); + if (rc < 0) + goto out; } if (local->hw.flags & IEEE802154_HW_TXPOWER) { diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index cfd4f657a24e..755befde6a17 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -80,12 +80,6 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) spin_lock_bh(&sdata->mib_lock); sdata->short_addr = val; spin_unlock_bh(&sdata->mib_lock); - - if ((sdata->local->ops->set_hw_addr_filt) && - (sdata->local->hw.hw_filt.short_addr != sdata->short_addr)) { - sdata->local->hw.hw_filt.short_addr = sdata->short_addr; - set_hw_addr_filt(dev, IEEE802154_AFILT_SADDR_CHANGED); - } } __le16 mac802154_dev_get_short_addr(const struct net_device *dev) -- GitLab From 50c79075019e7b952327cfebf0681548573fd8e5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:43 +0100 Subject: [PATCH 2405/9457] mac802154: set panid address filter on ifup This patch moves the setting of hardware panid address filtering inside of interface up instead doing it it directly inside of netlink interface. The netlink call which can only be called when netif isn't running sets only the necessary panid value in sdata. After an interface up the address filter will be set with this value. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 4 ++++ net/mac802154/mib.c | 51 ------------------------------------------- 2 files changed, 4 insertions(+), 51 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 1bae29dff082..5f94c70478f9 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -205,6 +205,10 @@ static int mac802154_wpan_open(struct net_device *dev) } if (local->hw.flags & IEEE802154_HW_AFILT) { + rc = drv_set_pan_id(local, sdata->pan_id); + if (rc < 0) + goto out; + rc = drv_set_extended_addr(local, sdata->extended_addr); if (rc < 0) goto out; diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 755befde6a17..6fa749154baf 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -26,51 +26,6 @@ #include "ieee802154_i.h" #include "driver-ops.h" -struct hw_addr_filt_notify_work { - struct work_struct work; - struct net_device *dev; - unsigned long changed; -}; - -static struct ieee802154_local *mac802154_slave_get_priv(struct net_device *dev) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return sdata->local; -} - -static void hw_addr_notify(struct work_struct *work) -{ - struct hw_addr_filt_notify_work *nw = container_of(work, - struct hw_addr_filt_notify_work, work); - struct ieee802154_local *local = mac802154_slave_get_priv(nw->dev); - int res; - - res = local->ops->set_hw_addr_filt(&local->hw, &local->hw.hw_filt, - nw->changed); - if (res) - pr_debug("failed changed mask %lx\n", nw->changed); - - kfree(nw); -} - -static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - struct hw_addr_filt_notify_work *work; - - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) - return; - - INIT_WORK(&work->work, hw_addr_notify); - work->dev = dev; - work->changed = changed; - queue_work(sdata->local->workqueue, &work->work); -} - void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); @@ -119,12 +74,6 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) spin_lock_bh(&sdata->mib_lock); sdata->pan_id = val; spin_unlock_bh(&sdata->mib_lock); - - if ((sdata->local->ops->set_hw_addr_filt) && - (sdata->local->hw.hw_filt.pan_id != sdata->pan_id)) { - sdata->local->hw.hw_filt.pan_id = sdata->pan_id; - set_hw_addr_filt(dev, IEEE802154_AFILT_PANID_CHANGED); - } } u8 mac802154_dev_get_dsn(const struct net_device *dev) -- GitLab From f59f419d31ee27c131b44beda5b14b8ce0aaf519 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:44 +0100 Subject: [PATCH 2406/9457] mac802154: move phy settings into netlink receive All PHY attributes should be directly set to the transceiver after netlink. MAC attributes should be set by interface up. Currently the macparams netlink cmd contains mixed attributes of phy and mac settings. This patch moves all phy settings to the netlink receive function for setting macparams. This is the only way which doesn't change the userspace API and keep the deprecated netlink interface alive. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 19 ------------------- net/mac802154/mac_cmd.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 5f94c70478f9..eaad66590f10 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -218,31 +218,12 @@ static int mac802154_wpan_open(struct net_device *dev) goto out; } - if (local->hw.flags & IEEE802154_HW_TXPOWER) { - rc = drv_set_tx_power(local, sdata->mac_params.transmit_power); - if (rc < 0) - goto out; - } - if (local->hw.flags & IEEE802154_HW_LBT) { rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); if (rc < 0) goto out; } - if (local->hw.flags & IEEE802154_HW_CCA_MODE) { - rc = drv_set_cca_mode(local, sdata->mac_params.cca_mode); - if (rc < 0) - goto out; - } - - if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) { - rc = drv_set_cca_ed_level(local, - sdata->mac_params.cca_ed_level); - if (rc < 0) - goto out; - } - if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { rc = drv_set_csma_params(local, sdata->mac_params.min_be, sdata->mac_params.max_be, diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 90c1ad80a67d..9c2d6f61f194 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -28,6 +28,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" static int mac802154_mlme_start_req(struct net_device *dev, struct ieee802154_addr *addr, @@ -85,11 +86,31 @@ static int mac802154_set_mac_params(struct net_device *dev, const struct ieee802154_mac_params *params) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct ieee802154_local *local = sdata->local; + int ret; mutex_lock(&sdata->local->iflist_mtx); sdata->mac_params = *params; mutex_unlock(&sdata->local->iflist_mtx); + if (local->hw.flags & IEEE802154_HW_TXPOWER) { + ret = drv_set_tx_power(local, params->transmit_power); + if (ret < 0) + return ret; + } + + if (local->hw.flags & IEEE802154_HW_CCA_MODE) { + ret = drv_set_cca_mode(local, params->cca_mode); + if (ret < 0) + return ret; + } + + if (local->hw.flags & IEEE802154_HW_CCA_ED_LEVEL) { + ret = drv_set_cca_ed_level(local, params->cca_ed_level); + if (ret < 0) + return ret; + } + return 0; } -- GitLab From cb904b0a16305f9b2a98200cc6eb9dc3610278b0 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:45 +0100 Subject: [PATCH 2407/9457] ieee802154: add extended address validation helper This patch introduce an extended address validation helper to check if an extended address is valid or not. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 6e50a2a1d485..9bba5ca7f0ad 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -197,4 +197,18 @@ static inline bool ieee802154_is_valid_psdu_len(const u8 len) return (len >= IEEE802154_MIN_PSDU_LEN && len <= IEEE802154_MTU); } +/** + * ieee802154_is_valid_psdu_len - check if extended addr is valid + * @addr: extended addr to check + */ +static inline bool ieee802154_is_valid_extended_addr(const __le64 addr) +{ + /* These EUI-64 addresses are reserved by IEEE. 0xffffffffffffffff + * is used internally as extended to short address broadcast mapping. + * This is currently a workaround because neighbor discovery can't + * deal with short addresses types right now. + */ + return ((addr != 0x0000000000000000) || (addr != 0xffffffffffffffff)); +} + #endif /* LINUX_IEEE802154_H */ -- GitLab From ea7053c1df41689dea0db2c49dc9d25dbe8fcf33 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:46 +0100 Subject: [PATCH 2408/9457] mac802154: iface: add validation for extended address This patch use the validation function to check if an extended address is valid or not while set the extended address. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index eaad66590f10..ceedf3ef1ce2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -112,13 +112,17 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct sockaddr *addr = p; + __le64 extended_addr; if (netif_running(dev)) return -EBUSY; - /* FIXME: validate addr */ + extended_addr = ieee802154_netdev_to_extended_addr(addr->sa_data); + if (!ieee802154_is_valid_extended_addr(extended_addr)) + return -EINVAL; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - sdata->extended_addr = ieee802154_netdev_to_extended_addr(dev->dev_addr); + sdata->extended_addr = extended_addr; return mac802154_wpan_update_llsec(dev); } -- GitLab From 62906710182a7d079a69932a93ebd003caaa7135 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 04:18:47 +0100 Subject: [PATCH 2409/9457] ieee802154: 6lowpan: remove set of mac address Currently the ieee802154 6lowpan interface operates on wpan interfaces only. Setting the wpan mac address over 6lowpan interface is complex and maybe we can't never do this. This patch removes the set of mac address handling in ieee802154 6lowpan interface for now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 519a65452d90..659f7b25ea1a 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -206,19 +206,6 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) return -EINVAL; } -static int lowpan_set_address(struct net_device *dev, void *p) -{ - struct sockaddr *sa = p; - - if (netif_running(dev)) - return -EBUSY; - - /* TODO: validate addr */ - memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); - - return 0; -} - static struct sk_buff* lowpan_alloc_frag(struct sk_buff *skb, int size, const struct ieee802154_hdr *master_hdr) @@ -474,7 +461,6 @@ static int lowpan_dev_init(struct net_device *dev) static const struct net_device_ops lowpan_netdev_ops = { .ndo_init = lowpan_dev_init, .ndo_start_xmit = lowpan_xmit, - .ndo_set_mac_address = lowpan_set_address, }; static struct ieee802154_mlme_ops lowpan_mlme = { -- GitLab From c77fd0a42b24acc2d6cc466e73dcb67d50177df6 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Fri, 31 Oct 2014 20:00:13 -0700 Subject: [PATCH 2410/9457] Input: rename cap1106 driver to cap11xx There are several devices in cap11xx family besides cap1106. The driver can be made to support all of them, so let's give it more generic name. Signed-off-by: Matt Ranostay Reviewed-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- .../input/{cap1106.txt => cap11xx.txt} | 19 +- drivers/input/keyboard/Kconfig | 8 +- drivers/input/keyboard/Makefile | 2 +- drivers/input/keyboard/cap1106.c | 341 ------------------ drivers/input/keyboard/cap11xx.c | 340 +++++++++++++++++ 5 files changed, 355 insertions(+), 355 deletions(-) rename Documentation/devicetree/bindings/input/{cap1106.txt => cap11xx.txt} (74%) delete mode 100644 drivers/input/keyboard/cap1106.c create mode 100644 drivers/input/keyboard/cap11xx.c diff --git a/Documentation/devicetree/bindings/input/cap1106.txt b/Documentation/devicetree/bindings/input/cap11xx.txt similarity index 74% rename from Documentation/devicetree/bindings/input/cap1106.txt rename to Documentation/devicetree/bindings/input/cap11xx.txt index 4b463904cba0..51649203658a 100644 --- a/Documentation/devicetree/bindings/input/cap1106.txt +++ b/Documentation/devicetree/bindings/input/cap11xx.txt @@ -1,11 +1,12 @@ -Device tree bindings for Microchip CAP1106, 6 channel capacitive touch sensor +Device tree bindings for Microchip CAP11xx based capacitive touch sensors -The node for this driver must be a child of a I2C controller node, as the +The node for this device must be a child of a I2C controller node, as the device communication via I2C only. Required properties: - compatible: Must be "microchip,cap1106" + compatible: Must contain one of: + "microchip,cap1106" reg: The I2C slave address of the device. Only 0x28 is valid. @@ -43,11 +44,11 @@ i2c_controller { autorepeat; microchip,sensor-gain = <2>; - linux,keycodes = <103 /* KEY_UP */ - 106 /* KEY_RIGHT */ - 108 /* KEY_DOWN */ - 105 /* KEY_LEFT */ - 109 /* KEY_PAGEDOWN */ - 104>; /* KEY_PAGEUP */ + linux,keycodes = <103>, /* KEY_UP */ + <106>, /* KEY_RIGHT */ + <108>, /* KEY_DOWN */ + <105>, /* KEY_LEFT */ + <109>, /* KEY_PAGEDOWN */ + <104>; /* KEY_PAGEUP */ }; } diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a3958c63d7d5..96ee26c555e0 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -665,14 +665,14 @@ config KEYBOARD_CROS_EC To compile this driver as a module, choose M here: the module will be called cros_ec_keyb. -config KEYBOARD_CAP1106 - tristate "Microchip CAP1106 touch sensor" +config KEYBOARD_CAP11XX + tristate "Microchip CAP11XX based touch sensors" depends on OF && I2C select REGMAP_I2C help - Say Y here to enable the CAP1106 touch sensor driver. + Say Y here to enable the CAP11XX touch sensor driver. To compile this driver as a module, choose M here: the - module will be called cap1106. + module will be called cap11xx. endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 0a3345634d79..febafa527eb6 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o -obj-$(CONFIG_KEYBOARD_CAP1106) += cap1106.o +obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c deleted file mode 100644 index d70b65a14ced..000000000000 --- a/drivers/input/keyboard/cap1106.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Input driver for Microchip CAP1106, 6 channel capacitive touch sensor - * - * http://www.microchip.com/wwwproducts/Devices.aspx?product=CAP1106 - * - * (c) 2014 Daniel Mack - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define CAP1106_REG_MAIN_CONTROL 0x00 -#define CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT (6) -#define CAP1106_REG_MAIN_CONTROL_GAIN_MASK (0xc0) -#define CAP1106_REG_MAIN_CONTROL_DLSEEP BIT(4) -#define CAP1106_REG_GENERAL_STATUS 0x02 -#define CAP1106_REG_SENSOR_INPUT 0x03 -#define CAP1106_REG_NOISE_FLAG_STATUS 0x0a -#define CAP1106_REG_SENOR_DELTA(X) (0x10 + (X)) -#define CAP1106_REG_SENSITIVITY_CONTROL 0x1f -#define CAP1106_REG_CONFIG 0x20 -#define CAP1106_REG_SENSOR_ENABLE 0x21 -#define CAP1106_REG_SENSOR_CONFIG 0x22 -#define CAP1106_REG_SENSOR_CONFIG2 0x23 -#define CAP1106_REG_SAMPLING_CONFIG 0x24 -#define CAP1106_REG_CALIBRATION 0x26 -#define CAP1106_REG_INT_ENABLE 0x27 -#define CAP1106_REG_REPEAT_RATE 0x28 -#define CAP1106_REG_MT_CONFIG 0x2a -#define CAP1106_REG_MT_PATTERN_CONFIG 0x2b -#define CAP1106_REG_MT_PATTERN 0x2d -#define CAP1106_REG_RECALIB_CONFIG 0x2f -#define CAP1106_REG_SENSOR_THRESH(X) (0x30 + (X)) -#define CAP1106_REG_SENSOR_NOISE_THRESH 0x38 -#define CAP1106_REG_STANDBY_CHANNEL 0x40 -#define CAP1106_REG_STANDBY_CONFIG 0x41 -#define CAP1106_REG_STANDBY_SENSITIVITY 0x42 -#define CAP1106_REG_STANDBY_THRESH 0x43 -#define CAP1106_REG_CONFIG2 0x44 -#define CAP1106_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) -#define CAP1106_REG_SENSOR_CALIB (0xb1 + (X)) -#define CAP1106_REG_SENSOR_CALIB_LSB1 0xb9 -#define CAP1106_REG_SENSOR_CALIB_LSB2 0xba -#define CAP1106_REG_PRODUCT_ID 0xfd -#define CAP1106_REG_MANUFACTURER_ID 0xfe -#define CAP1106_REG_REVISION 0xff - -#define CAP1106_NUM_CHN 6 -#define CAP1106_PRODUCT_ID 0x55 -#define CAP1106_MANUFACTURER_ID 0x5d - -struct cap1106_priv { - struct regmap *regmap; - struct input_dev *idev; - - /* config */ - unsigned short keycodes[CAP1106_NUM_CHN]; -}; - -static const struct reg_default cap1106_reg_defaults[] = { - { CAP1106_REG_MAIN_CONTROL, 0x00 }, - { CAP1106_REG_GENERAL_STATUS, 0x00 }, - { CAP1106_REG_SENSOR_INPUT, 0x00 }, - { CAP1106_REG_NOISE_FLAG_STATUS, 0x00 }, - { CAP1106_REG_SENSITIVITY_CONTROL, 0x2f }, - { CAP1106_REG_CONFIG, 0x20 }, - { CAP1106_REG_SENSOR_ENABLE, 0x3f }, - { CAP1106_REG_SENSOR_CONFIG, 0xa4 }, - { CAP1106_REG_SENSOR_CONFIG2, 0x07 }, - { CAP1106_REG_SAMPLING_CONFIG, 0x39 }, - { CAP1106_REG_CALIBRATION, 0x00 }, - { CAP1106_REG_INT_ENABLE, 0x3f }, - { CAP1106_REG_REPEAT_RATE, 0x3f }, - { CAP1106_REG_MT_CONFIG, 0x80 }, - { CAP1106_REG_MT_PATTERN_CONFIG, 0x00 }, - { CAP1106_REG_MT_PATTERN, 0x3f }, - { CAP1106_REG_RECALIB_CONFIG, 0x8a }, - { CAP1106_REG_SENSOR_THRESH(0), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(1), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(2), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(3), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(4), 0x40 }, - { CAP1106_REG_SENSOR_THRESH(5), 0x40 }, - { CAP1106_REG_SENSOR_NOISE_THRESH, 0x01 }, - { CAP1106_REG_STANDBY_CHANNEL, 0x00 }, - { CAP1106_REG_STANDBY_CONFIG, 0x39 }, - { CAP1106_REG_STANDBY_SENSITIVITY, 0x02 }, - { CAP1106_REG_STANDBY_THRESH, 0x40 }, - { CAP1106_REG_CONFIG2, 0x40 }, - { CAP1106_REG_SENSOR_CALIB_LSB1, 0x00 }, - { CAP1106_REG_SENSOR_CALIB_LSB2, 0x00 }, -}; - -static bool cap1106_volatile_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case CAP1106_REG_MAIN_CONTROL: - case CAP1106_REG_SENSOR_INPUT: - case CAP1106_REG_SENOR_DELTA(0): - case CAP1106_REG_SENOR_DELTA(1): - case CAP1106_REG_SENOR_DELTA(2): - case CAP1106_REG_SENOR_DELTA(3): - case CAP1106_REG_SENOR_DELTA(4): - case CAP1106_REG_SENOR_DELTA(5): - case CAP1106_REG_PRODUCT_ID: - case CAP1106_REG_MANUFACTURER_ID: - case CAP1106_REG_REVISION: - return true; - } - - return false; -} - -static const struct regmap_config cap1106_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - - .max_register = CAP1106_REG_REVISION, - .reg_defaults = cap1106_reg_defaults, - - .num_reg_defaults = ARRAY_SIZE(cap1106_reg_defaults), - .cache_type = REGCACHE_RBTREE, - .volatile_reg = cap1106_volatile_reg, -}; - -static irqreturn_t cap1106_thread_func(int irq_num, void *data) -{ - struct cap1106_priv *priv = data; - unsigned int status; - int ret, i; - - /* - * Deassert interrupt. This needs to be done before reading the status - * registers, which will not carry valid values otherwise. - */ - ret = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, 1, 0); - if (ret < 0) - goto out; - - ret = regmap_read(priv->regmap, CAP1106_REG_SENSOR_INPUT, &status); - if (ret < 0) - goto out; - - for (i = 0; i < CAP1106_NUM_CHN; i++) - input_report_key(priv->idev, priv->keycodes[i], - status & (1 << i)); - - input_sync(priv->idev); - -out: - return IRQ_HANDLED; -} - -static int cap1106_set_sleep(struct cap1106_priv *priv, bool sleep) -{ - return regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, - CAP1106_REG_MAIN_CONTROL_DLSEEP, - sleep ? CAP1106_REG_MAIN_CONTROL_DLSEEP : 0); -} - -static int cap1106_input_open(struct input_dev *idev) -{ - struct cap1106_priv *priv = input_get_drvdata(idev); - - return cap1106_set_sleep(priv, false); -} - -static void cap1106_input_close(struct input_dev *idev) -{ - struct cap1106_priv *priv = input_get_drvdata(idev); - - cap1106_set_sleep(priv, true); -} - -static int cap1106_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) -{ - struct device *dev = &i2c_client->dev; - struct cap1106_priv *priv; - struct device_node *node; - int i, error, irq, gain = 0; - unsigned int val, rev; - u32 gain32, keycodes[CAP1106_NUM_CHN]; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->regmap = devm_regmap_init_i2c(i2c_client, &cap1106_regmap_config); - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - - error = regmap_read(priv->regmap, CAP1106_REG_PRODUCT_ID, &val); - if (error) - return error; - - if (val != CAP1106_PRODUCT_ID) { - dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", - val, CAP1106_PRODUCT_ID); - return -ENODEV; - } - - error = regmap_read(priv->regmap, CAP1106_REG_MANUFACTURER_ID, &val); - if (error) - return error; - - if (val != CAP1106_MANUFACTURER_ID) { - dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", - val, CAP1106_MANUFACTURER_ID); - return -ENODEV; - } - - error = regmap_read(priv->regmap, CAP1106_REG_REVISION, &rev); - if (error < 0) - return error; - - dev_info(dev, "CAP1106 detected, revision 0x%02x\n", rev); - i2c_set_clientdata(i2c_client, priv); - node = dev->of_node; - - if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { - if (is_power_of_2(gain32) && gain32 <= 8) - gain = ilog2(gain32); - else - dev_err(dev, "Invalid sensor-gain value %d\n", gain32); - } - - BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); - - /* Provide some useful defaults */ - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - keycodes[i] = KEY_A + i; - - of_property_read_u32_array(node, "linux,keycodes", - keycodes, ARRAY_SIZE(keycodes)); - - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - priv->keycodes[i] = keycodes[i]; - - error = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, - CAP1106_REG_MAIN_CONTROL_GAIN_MASK, - gain << CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT); - if (error) - return error; - - /* Disable autorepeat. The Linux input system has its own handling. */ - error = regmap_write(priv->regmap, CAP1106_REG_REPEAT_RATE, 0); - if (error) - return error; - - priv->idev = devm_input_allocate_device(dev); - if (!priv->idev) - return -ENOMEM; - - priv->idev->name = "CAP1106 capacitive touch sensor"; - priv->idev->id.bustype = BUS_I2C; - priv->idev->evbit[0] = BIT_MASK(EV_KEY); - - if (of_property_read_bool(node, "autorepeat")) - __set_bit(EV_REP, priv->idev->evbit); - - for (i = 0; i < CAP1106_NUM_CHN; i++) - __set_bit(priv->keycodes[i], priv->idev->keybit); - - __clear_bit(KEY_RESERVED, priv->idev->keybit); - - priv->idev->keycode = priv->keycodes; - priv->idev->keycodesize = sizeof(priv->keycodes[0]); - priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); - - priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; - priv->idev->id.product = CAP1106_PRODUCT_ID; - priv->idev->id.version = rev; - - priv->idev->open = cap1106_input_open; - priv->idev->close = cap1106_input_close; - - input_set_drvdata(priv->idev, priv); - - /* - * Put the device in deep sleep mode for now. - * ->open() will bring it back once the it is actually needed. - */ - cap1106_set_sleep(priv, true); - - error = input_register_device(priv->idev); - if (error) - return error; - - irq = irq_of_parse_and_map(node, 0); - if (!irq) { - dev_err(dev, "Unable to parse or map IRQ\n"); - return -ENXIO; - } - - error = devm_request_threaded_irq(dev, irq, NULL, cap1106_thread_func, - IRQF_ONESHOT, dev_name(dev), priv); - if (error) - return error; - - return 0; -} - -static const struct of_device_id cap1106_dt_ids[] = { - { .compatible = "microchip,cap1106", }, - {} -}; -MODULE_DEVICE_TABLE(of, cap1106_dt_ids); - -static const struct i2c_device_id cap1106_i2c_ids[] = { - { "cap1106", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, cap1106_i2c_ids); - -static struct i2c_driver cap1106_i2c_driver = { - .driver = { - .name = "cap1106", - .owner = THIS_MODULE, - .of_match_table = cap1106_dt_ids, - }, - .id_table = cap1106_i2c_ids, - .probe = cap1106_i2c_probe, -}; - -module_i2c_driver(cap1106_i2c_driver); - -MODULE_ALIAS("platform:cap1106"); -MODULE_DESCRIPTION("Microchip CAP1106 driver"); -MODULE_AUTHOR("Daniel Mack "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c new file mode 100644 index 000000000000..0da2e838e788 --- /dev/null +++ b/drivers/input/keyboard/cap11xx.c @@ -0,0 +1,340 @@ +/* + * Input driver for Microchip CAP11xx based capacitive touch sensors + * + * + * (c) 2014 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CAP11XX_REG_MAIN_CONTROL 0x00 +#define CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT (6) +#define CAP11XX_REG_MAIN_CONTROL_GAIN_MASK (0xc0) +#define CAP11XX_REG_MAIN_CONTROL_DLSEEP BIT(4) +#define CAP11XX_REG_GENERAL_STATUS 0x02 +#define CAP11XX_REG_SENSOR_INPUT 0x03 +#define CAP11XX_REG_NOISE_FLAG_STATUS 0x0a +#define CAP11XX_REG_SENOR_DELTA(X) (0x10 + (X)) +#define CAP11XX_REG_SENSITIVITY_CONTROL 0x1f +#define CAP11XX_REG_CONFIG 0x20 +#define CAP11XX_REG_SENSOR_ENABLE 0x21 +#define CAP11XX_REG_SENSOR_CONFIG 0x22 +#define CAP11XX_REG_SENSOR_CONFIG2 0x23 +#define CAP11XX_REG_SAMPLING_CONFIG 0x24 +#define CAP11XX_REG_CALIBRATION 0x26 +#define CAP11XX_REG_INT_ENABLE 0x27 +#define CAP11XX_REG_REPEAT_RATE 0x28 +#define CAP11XX_REG_MT_CONFIG 0x2a +#define CAP11XX_REG_MT_PATTERN_CONFIG 0x2b +#define CAP11XX_REG_MT_PATTERN 0x2d +#define CAP11XX_REG_RECALIB_CONFIG 0x2f +#define CAP11XX_REG_SENSOR_THRESH(X) (0x30 + (X)) +#define CAP11XX_REG_SENSOR_NOISE_THRESH 0x38 +#define CAP11XX_REG_STANDBY_CHANNEL 0x40 +#define CAP11XX_REG_STANDBY_CONFIG 0x41 +#define CAP11XX_REG_STANDBY_SENSITIVITY 0x42 +#define CAP11XX_REG_STANDBY_THRESH 0x43 +#define CAP11XX_REG_CONFIG2 0x44 +#define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) +#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) +#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 +#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba +#define CAP11XX_REG_PRODUCT_ID 0xfd +#define CAP11XX_REG_MANUFACTURER_ID 0xfe +#define CAP11XX_REG_REVISION 0xff + +#define CAP11XX_NUM_CHN 6 +#define CAP11XX_PRODUCT_ID 0x55 +#define CAP11XX_MANUFACTURER_ID 0x5d + +struct cap11xx_priv { + struct regmap *regmap; + struct input_dev *idev; + + /* config */ + unsigned short keycodes[CAP11XX_NUM_CHN]; +}; + +static const struct reg_default cap11xx_reg_defaults[] = { + { CAP11XX_REG_MAIN_CONTROL, 0x00 }, + { CAP11XX_REG_GENERAL_STATUS, 0x00 }, + { CAP11XX_REG_SENSOR_INPUT, 0x00 }, + { CAP11XX_REG_NOISE_FLAG_STATUS, 0x00 }, + { CAP11XX_REG_SENSITIVITY_CONTROL, 0x2f }, + { CAP11XX_REG_CONFIG, 0x20 }, + { CAP11XX_REG_SENSOR_ENABLE, 0x3f }, + { CAP11XX_REG_SENSOR_CONFIG, 0xa4 }, + { CAP11XX_REG_SENSOR_CONFIG2, 0x07 }, + { CAP11XX_REG_SAMPLING_CONFIG, 0x39 }, + { CAP11XX_REG_CALIBRATION, 0x00 }, + { CAP11XX_REG_INT_ENABLE, 0x3f }, + { CAP11XX_REG_REPEAT_RATE, 0x3f }, + { CAP11XX_REG_MT_CONFIG, 0x80 }, + { CAP11XX_REG_MT_PATTERN_CONFIG, 0x00 }, + { CAP11XX_REG_MT_PATTERN, 0x3f }, + { CAP11XX_REG_RECALIB_CONFIG, 0x8a }, + { CAP11XX_REG_SENSOR_THRESH(0), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(1), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(2), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(3), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(4), 0x40 }, + { CAP11XX_REG_SENSOR_THRESH(5), 0x40 }, + { CAP11XX_REG_SENSOR_NOISE_THRESH, 0x01 }, + { CAP11XX_REG_STANDBY_CHANNEL, 0x00 }, + { CAP11XX_REG_STANDBY_CONFIG, 0x39 }, + { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, + { CAP11XX_REG_STANDBY_THRESH, 0x40 }, + { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, + { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, +}; + +static bool cap11xx_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CAP11XX_REG_MAIN_CONTROL: + case CAP11XX_REG_SENSOR_INPUT: + case CAP11XX_REG_SENOR_DELTA(0): + case CAP11XX_REG_SENOR_DELTA(1): + case CAP11XX_REG_SENOR_DELTA(2): + case CAP11XX_REG_SENOR_DELTA(3): + case CAP11XX_REG_SENOR_DELTA(4): + case CAP11XX_REG_SENOR_DELTA(5): + case CAP11XX_REG_PRODUCT_ID: + case CAP11XX_REG_MANUFACTURER_ID: + case CAP11XX_REG_REVISION: + return true; + } + + return false; +} + +static const struct regmap_config cap11xx_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = CAP11XX_REG_REVISION, + .reg_defaults = cap11xx_reg_defaults, + + .num_reg_defaults = ARRAY_SIZE(cap11xx_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .volatile_reg = cap11xx_volatile_reg, +}; + +static irqreturn_t cap11xx_thread_func(int irq_num, void *data) +{ + struct cap11xx_priv *priv = data; + unsigned int status; + int ret, i; + + /* + * Deassert interrupt. This needs to be done before reading the status + * registers, which will not carry valid values otherwise. + */ + ret = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, 1, 0); + if (ret < 0) + goto out; + + ret = regmap_read(priv->regmap, CAP11XX_REG_SENSOR_INPUT, &status); + if (ret < 0) + goto out; + + for (i = 0; i < CAP11XX_NUM_CHN; i++) + input_report_key(priv->idev, priv->keycodes[i], + status & (1 << i)); + + input_sync(priv->idev); + +out: + return IRQ_HANDLED; +} + +static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep) +{ + return regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, + CAP11XX_REG_MAIN_CONTROL_DLSEEP, + sleep ? CAP11XX_REG_MAIN_CONTROL_DLSEEP : 0); +} + +static int cap11xx_input_open(struct input_dev *idev) +{ + struct cap11xx_priv *priv = input_get_drvdata(idev); + + return cap11xx_set_sleep(priv, false); +} + +static void cap11xx_input_close(struct input_dev *idev) +{ + struct cap11xx_priv *priv = input_get_drvdata(idev); + + cap11xx_set_sleep(priv, true); +} + +static int cap11xx_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + struct device *dev = &i2c_client->dev; + struct cap11xx_priv *priv; + struct device_node *node; + int i, error, irq, gain = 0; + unsigned int val, rev; + u32 gain32, keycodes[CAP11XX_NUM_CHN]; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + error = regmap_read(priv->regmap, CAP11XX_REG_PRODUCT_ID, &val); + if (error) + return error; + + if (val != CAP11XX_PRODUCT_ID) { + dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", + val, CAP11XX_PRODUCT_ID); + return -ENODEV; + } + + error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); + if (error) + return error; + + if (val != CAP11XX_MANUFACTURER_ID) { + dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", + val, CAP11XX_MANUFACTURER_ID); + return -ENODEV; + } + + error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); + if (error < 0) + return error; + + dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev); + i2c_set_clientdata(i2c_client, priv); + node = dev->of_node; + + if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { + if (is_power_of_2(gain32) && gain32 <= 8) + gain = ilog2(gain32); + else + dev_err(dev, "Invalid sensor-gain value %d\n", gain32); + } + + BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); + + /* Provide some useful defaults */ + for (i = 0; i < ARRAY_SIZE(keycodes); i++) + keycodes[i] = KEY_A + i; + + of_property_read_u32_array(node, "linux,keycodes", + keycodes, ARRAY_SIZE(keycodes)); + + for (i = 0; i < ARRAY_SIZE(keycodes); i++) + priv->keycodes[i] = keycodes[i]; + + error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, + CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, + gain << CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT); + if (error) + return error; + + /* Disable autorepeat. The Linux input system has its own handling. */ + error = regmap_write(priv->regmap, CAP11XX_REG_REPEAT_RATE, 0); + if (error) + return error; + + priv->idev = devm_input_allocate_device(dev); + if (!priv->idev) + return -ENOMEM; + + priv->idev->name = "CAP11XX capacitive touch sensor"; + priv->idev->id.bustype = BUS_I2C; + priv->idev->evbit[0] = BIT_MASK(EV_KEY); + + if (of_property_read_bool(node, "autorepeat")) + __set_bit(EV_REP, priv->idev->evbit); + + for (i = 0; i < CAP11XX_NUM_CHN; i++) + __set_bit(priv->keycodes[i], priv->idev->keybit); + + __clear_bit(KEY_RESERVED, priv->idev->keybit); + + priv->idev->keycode = priv->keycodes; + priv->idev->keycodesize = sizeof(priv->keycodes[0]); + priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); + + priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; + priv->idev->id.product = CAP11XX_PRODUCT_ID; + priv->idev->id.version = rev; + + priv->idev->open = cap11xx_input_open; + priv->idev->close = cap11xx_input_close; + + input_set_drvdata(priv->idev, priv); + + /* + * Put the device in deep sleep mode for now. + * ->open() will bring it back once the it is actually needed. + */ + cap11xx_set_sleep(priv, true); + + error = input_register_device(priv->idev); + if (error) + return error; + + irq = irq_of_parse_and_map(node, 0); + if (!irq) { + dev_err(dev, "Unable to parse or map IRQ\n"); + return -ENXIO; + } + + error = devm_request_threaded_irq(dev, irq, NULL, cap11xx_thread_func, + IRQF_ONESHOT, dev_name(dev), priv); + if (error) + return error; + + return 0; +} + +static const struct of_device_id cap11xx_dt_ids[] = { + { .compatible = "microchip,cap1106", }, + {} +}; +MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); + +static const struct i2c_device_id cap11xx_i2c_ids[] = { + { "cap1106", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); + +static struct i2c_driver cap11xx_i2c_driver = { + .driver = { + .name = "cap11xx", + .owner = THIS_MODULE, + .of_match_table = cap11xx_dt_ids, + }, + .id_table = cap11xx_i2c_ids, + .probe = cap11xx_i2c_probe, +}; + +module_i2c_driver(cap11xx_i2c_driver); + +MODULE_ALIAS("platform:cap11xx"); +MODULE_DESCRIPTION("Microchip CAP11XX driver"); +MODULE_AUTHOR("Daniel Mack "); +MODULE_LICENSE("GPL v2"); -- GitLab From 7609a5e973c43a647c4e40184fc8404311fdb97c Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Fri, 31 Oct 2014 20:01:37 -0700 Subject: [PATCH 2411/9457] Input: cap11xx - add support for various cap11xx devices There are variants of the cap11xx device with a varying number of capacitance detection channels. Signed-off-by: Matt Ranostay Reviewed-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/cap11xx.txt | 3 +- drivers/input/keyboard/cap11xx.c | 74 +++++++++++++------ 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt b/Documentation/devicetree/bindings/input/cap11xx.txt index 51649203658a..61d20d8d97e2 100644 --- a/Documentation/devicetree/bindings/input/cap11xx.txt +++ b/Documentation/devicetree/bindings/input/cap11xx.txt @@ -7,9 +7,10 @@ Required properties: compatible: Must contain one of: "microchip,cap1106" + "microchip,cap1126" + "microchip,cap1188" reg: The I2C slave address of the device. - Only 0x28 is valid. interrupts: Property describing the interrupt line the device's ALERT#/CM_IRQ# pin is connected to. diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 0da2e838e788..eeda1f9359cd 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -1,7 +1,6 @@ /* * Input driver for Microchip CAP11xx based capacitive touch sensors * - * * (c) 2014 Daniel Mack * * This program is free software; you can redistribute it and/or modify @@ -54,8 +53,6 @@ #define CAP11XX_REG_MANUFACTURER_ID 0xfe #define CAP11XX_REG_REVISION 0xff -#define CAP11XX_NUM_CHN 6 -#define CAP11XX_PRODUCT_ID 0x55 #define CAP11XX_MANUFACTURER_ID 0x5d struct cap11xx_priv { @@ -63,7 +60,24 @@ struct cap11xx_priv { struct input_dev *idev; /* config */ - unsigned short keycodes[CAP11XX_NUM_CHN]; + u32 keycodes[]; +}; + +struct cap11xx_hw_model { + u8 product_id; + unsigned int num_channels; +}; + +enum { + CAP1106, + CAP1126, + CAP1188, +}; + +static const struct cap11xx_hw_model cap11xx_devices[] = { + [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, + [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, + [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, }; static const struct reg_default cap11xx_reg_defaults[] = { @@ -150,7 +164,7 @@ static irqreturn_t cap11xx_thread_func(int irq_num, void *data) if (ret < 0) goto out; - for (i = 0; i < CAP11XX_NUM_CHN; i++) + for (i = 0; i < priv->idev->keycodemax; i++) input_report_key(priv->idev, priv->keycodes[i], status & (1 << i)); @@ -187,11 +201,26 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, struct device *dev = &i2c_client->dev; struct cap11xx_priv *priv; struct device_node *node; + const struct cap11xx_hw_model *cap; int i, error, irq, gain = 0; unsigned int val, rev; - u32 gain32, keycodes[CAP11XX_NUM_CHN]; + u32 gain32; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (id->driver_data >= ARRAY_SIZE(cap11xx_devices)) { + dev_err(dev, "Invalid device ID %lu\n", id->driver_data); + return -EINVAL; + } + + cap = &cap11xx_devices[id->driver_data]; + if (!cap || !cap->num_channels) { + dev_err(dev, "Invalid device configuration\n"); + return -EINVAL; + } + + priv = devm_kzalloc(dev, + sizeof(*priv) + + cap->num_channels * sizeof(priv->keycodes[0]), + GFP_KERNEL); if (!priv) return -ENOMEM; @@ -203,10 +232,10 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, if (error) return error; - if (val != CAP11XX_PRODUCT_ID) { + if (val != cap->product_id) { dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", - val, CAP11XX_PRODUCT_ID); - return -ENODEV; + val, cap->product_id); + return -ENXIO; } error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); @@ -216,7 +245,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, if (val != CAP11XX_MANUFACTURER_ID) { dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", val, CAP11XX_MANUFACTURER_ID); - return -ENODEV; + return -ENXIO; } error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); @@ -234,17 +263,12 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, dev_err(dev, "Invalid sensor-gain value %d\n", gain32); } - BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); - /* Provide some useful defaults */ - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - keycodes[i] = KEY_A + i; + for (i = 0; i < cap->num_channels; i++) + priv->keycodes[i] = KEY_A + i; of_property_read_u32_array(node, "linux,keycodes", - keycodes, ARRAY_SIZE(keycodes)); - - for (i = 0; i < ARRAY_SIZE(keycodes); i++) - priv->keycodes[i] = keycodes[i]; + priv->keycodes, cap->num_channels); error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, @@ -268,17 +292,17 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, if (of_property_read_bool(node, "autorepeat")) __set_bit(EV_REP, priv->idev->evbit); - for (i = 0; i < CAP11XX_NUM_CHN; i++) + for (i = 0; i < cap->num_channels; i++) __set_bit(priv->keycodes[i], priv->idev->keybit); __clear_bit(KEY_RESERVED, priv->idev->keybit); priv->idev->keycode = priv->keycodes; priv->idev->keycodesize = sizeof(priv->keycodes[0]); - priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); + priv->idev->keycodemax = cap->num_channels; priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; - priv->idev->id.product = CAP11XX_PRODUCT_ID; + priv->idev->id.product = cap->product_id; priv->idev->id.version = rev; priv->idev->open = cap11xx_input_open; @@ -312,12 +336,16 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, static const struct of_device_id cap11xx_dt_ids[] = { { .compatible = "microchip,cap1106", }, + { .compatible = "microchip,cap1126", }, + { .compatible = "microchip,cap1188", }, {} }; MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); static const struct i2c_device_id cap11xx_i2c_ids[] = { - { "cap1106", 0 }, + { "cap1106", CAP1106 }, + { "cap1126", CAP1126 }, + { "cap1188", CAP1188 }, {} }; MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); -- GitLab From 6bdd2fd1ed6f66597f3cff75c1bb1569beec2fc9 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Fri, 31 Oct 2014 20:02:08 -0700 Subject: [PATCH 2412/9457] Input: cap11xx - support for irq-active-high option Some applications need to use the irq-active-high push-pull option. This allows it be enabled in the device tree child node. Signed-off-by: Matt Ranostay Reviewed-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/cap11xx.txt | 4 ++++ drivers/input/keyboard/cap11xx.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt b/Documentation/devicetree/bindings/input/cap11xx.txt index 61d20d8d97e2..7d0a3009771b 100644 --- a/Documentation/devicetree/bindings/input/cap11xx.txt +++ b/Documentation/devicetree/bindings/input/cap11xx.txt @@ -28,6 +28,10 @@ Optional properties: Valid values are 1, 2, 4, and 8. By default, a gain of 1 is set. + microchip,irq-active-high: By default the interrupt pin is active low + open drain. This property allows using the active + high push-pull output. + linux,keycodes: Specifies an array of numeric keycode values to be used for the channels. If this property is omitted, KEY_A, KEY_B, etc are used as diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index eeda1f9359cd..4f59f0bab28f 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -45,6 +45,7 @@ #define CAP11XX_REG_STANDBY_SENSITIVITY 0x42 #define CAP11XX_REG_STANDBY_THRESH 0x43 #define CAP11XX_REG_CONFIG2 0x44 +#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6) #define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) #define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) #define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 @@ -263,6 +264,13 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, dev_err(dev, "Invalid sensor-gain value %d\n", gain32); } + if (of_property_read_bool(node, "microchip,irq-active-high")) { + error = regmap_update_bits(priv->regmap, CAP11XX_REG_CONFIG2, + CAP11XX_REG_CONFIG2_ALT_POL, 0); + if (error) + return error; + } + /* Provide some useful defaults */ for (i = 0; i < cap->num_channels; i++) priv->keycodes[i] = KEY_A + i; -- GitLab From 97a652a852b821dd2a95b54da8c870b7b38df0e8 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Sun, 2 Nov 2014 00:02:46 -0700 Subject: [PATCH 2413/9457] Input: misc - use __maybe_unused instead of ifdef around suspend/resume Use __maybe_unused instead of ifdef guards around suspend/resume functions, in order to increase build coverage and fix build warnings. Signed-off-by: Jingoo Han Signed-off-by: Dmitry Torokhov --- drivers/input/misc/88pm860x_onkey.c | 6 ++---- drivers/input/misc/ad714x-i2c.c | 6 ++---- drivers/input/misc/ad714x-spi.c | 6 ++---- drivers/input/misc/adxl34x-i2c.c | 6 ++---- drivers/input/misc/adxl34x-spi.c | 6 ++---- drivers/input/misc/drv260x.c | 6 ++---- drivers/input/misc/drv2667.c | 6 ++---- drivers/input/misc/gp2ap002a00f.c | 6 ++---- drivers/input/misc/kxtj9.c | 6 ++---- drivers/input/misc/max77693-haptic.c | 6 ++---- drivers/input/misc/max8925_onkey.c | 6 ++---- drivers/input/misc/max8997_haptic.c | 4 +--- drivers/input/misc/palmas-pwrbutton.c | 6 ++---- drivers/input/misc/pm8xxx-vibrator.c | 4 +--- drivers/input/misc/pmic8xxx-pwrkey.c | 6 ++---- drivers/input/misc/pwm-beeper.c | 6 +++--- drivers/input/misc/sirfsoc-onkey.c | 4 +--- drivers/input/misc/twl4030-vibra.c | 6 ++---- drivers/input/misc/twl6040-vibra.c | 4 +--- 19 files changed, 35 insertions(+), 71 deletions(-) diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index 220ce0fa15d9..3cbd1b309220 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c @@ -112,8 +112,7 @@ static int pm860x_onkey_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pm860x_onkey_suspend(struct device *dev) +static int __maybe_unused pm860x_onkey_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -122,7 +121,7 @@ static int pm860x_onkey_suspend(struct device *dev) chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY; return 0; } -static int pm860x_onkey_resume(struct device *dev) +static int __maybe_unused pm860x_onkey_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -131,7 +130,6 @@ static int pm860x_onkey_resume(struct device *dev) chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY); return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume); diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index e0f522516ef5..189bdc8e91a5 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c @@ -13,17 +13,15 @@ #include #include "ad714x.h" -#ifdef CONFIG_PM_SLEEP -static int ad714x_i2c_suspend(struct device *dev) +static int __maybe_unused ad714x_i2c_suspend(struct device *dev) { return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev))); } -static int ad714x_i2c_resume(struct device *dev) +static int __maybe_unused ad714x_i2c_resume(struct device *dev) { return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev))); } -#endif static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 3a90b710e309..a79e50b58bf5 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c @@ -16,17 +16,15 @@ #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ #define AD714x_SPI_READ BIT(10) -#ifdef CONFIG_PM_SLEEP -static int ad714x_spi_suspend(struct device *dev) +static int __maybe_unused ad714x_spi_suspend(struct device *dev) { return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); } -static int ad714x_spi_resume(struct device *dev) +static int __maybe_unused ad714x_spi_resume(struct device *dev) { return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); } -#endif static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 416f47ddcc90..470bfd6f0830 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c @@ -105,8 +105,7 @@ static int adxl34x_i2c_remove(struct i2c_client *client) return adxl34x_remove(ac); } -#ifdef CONFIG_PM_SLEEP -static int adxl34x_i2c_suspend(struct device *dev) +static int __maybe_unused adxl34x_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adxl34x *ac = i2c_get_clientdata(client); @@ -116,7 +115,7 @@ static int adxl34x_i2c_suspend(struct device *dev) return 0; } -static int adxl34x_i2c_resume(struct device *dev) +static int __maybe_unused adxl34x_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adxl34x *ac = i2c_get_clientdata(client); @@ -125,7 +124,6 @@ static int adxl34x_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend, adxl34x_i2c_resume); diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index 76dc0679d3b1..da6e76b58dab 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c @@ -94,8 +94,7 @@ static int adxl34x_spi_remove(struct spi_device *spi) return adxl34x_remove(ac); } -#ifdef CONFIG_PM_SLEEP -static int adxl34x_spi_suspend(struct device *dev) +static int __maybe_unused adxl34x_spi_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct adxl34x *ac = spi_get_drvdata(spi); @@ -105,7 +104,7 @@ static int adxl34x_spi_suspend(struct device *dev) return 0; } -static int adxl34x_spi_resume(struct device *dev) +static int __maybe_unused adxl34x_spi_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct adxl34x *ac = spi_get_drvdata(spi); @@ -114,7 +113,6 @@ static int adxl34x_spi_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, adxl34x_spi_resume); diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index cab87f5ce6d3..a364e109ca7c 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -639,8 +639,7 @@ static int drv260x_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int drv260x_suspend(struct device *dev) +static int __maybe_unused drv260x_suspend(struct device *dev) { struct drv260x_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -672,7 +671,7 @@ static int drv260x_suspend(struct device *dev) return ret; } -static int drv260x_resume(struct device *dev) +static int __maybe_unused drv260x_resume(struct device *dev) { struct drv260x_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -702,7 +701,6 @@ static int drv260x_resume(struct device *dev) mutex_unlock(&haptics->input_dev->mutex); return ret; } -#endif static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume); diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c index 0f437581cc04..a021744e608c 100644 --- a/drivers/input/misc/drv2667.c +++ b/drivers/input/misc/drv2667.c @@ -406,8 +406,7 @@ static int drv2667_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int drv2667_suspend(struct device *dev) +static int __maybe_unused drv2667_suspend(struct device *dev) { struct drv2667_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -436,7 +435,7 @@ static int drv2667_suspend(struct device *dev) return ret; } -static int drv2667_resume(struct device *dev) +static int __maybe_unused drv2667_resume(struct device *dev) { struct drv2667_data *haptics = dev_get_drvdata(dev); int ret = 0; @@ -464,7 +463,6 @@ static int drv2667_resume(struct device *dev) mutex_unlock(&haptics->input_dev->mutex); return ret; } -#endif static SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume); diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c index de21e317da32..0ac176d66a6f 100644 --- a/drivers/input/misc/gp2ap002a00f.c +++ b/drivers/input/misc/gp2ap002a00f.c @@ -225,8 +225,7 @@ static int gp2a_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int gp2a_suspend(struct device *dev) +static int __maybe_unused gp2a_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct gp2a_data *dt = i2c_get_clientdata(client); @@ -244,7 +243,7 @@ static int gp2a_suspend(struct device *dev) return retval; } -static int gp2a_resume(struct device *dev) +static int __maybe_unused gp2a_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct gp2a_data *dt = i2c_get_clientdata(client); @@ -261,7 +260,6 @@ static int gp2a_resume(struct device *dev) return retval; } -#endif static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume); diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c index d708478bc5b5..6e29349da537 100644 --- a/drivers/input/misc/kxtj9.c +++ b/drivers/input/misc/kxtj9.c @@ -615,8 +615,7 @@ static int kxtj9_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int kxtj9_suspend(struct device *dev) +static int __maybe_unused kxtj9_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct kxtj9_data *tj9 = i2c_get_clientdata(client); @@ -631,7 +630,7 @@ static int kxtj9_suspend(struct device *dev) return 0; } -static int kxtj9_resume(struct device *dev) +static int __maybe_unused kxtj9_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct kxtj9_data *tj9 = i2c_get_clientdata(client); @@ -646,7 +645,6 @@ static int kxtj9_resume(struct device *dev) mutex_unlock(&input_dev->mutex); return retval; } -#endif static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index d605db4d2f39..0ee3e8b45e8b 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -310,8 +310,7 @@ static int max77693_haptic_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max77693_haptic_suspend(struct device *dev) +static int __maybe_unused max77693_haptic_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max77693_haptic *haptic = platform_get_drvdata(pdev); @@ -324,7 +323,7 @@ static int max77693_haptic_suspend(struct device *dev) return 0; } -static int max77693_haptic_resume(struct device *dev) +static int __maybe_unused max77693_haptic_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max77693_haptic *haptic = platform_get_drvdata(pdev); @@ -336,7 +335,6 @@ static int max77693_haptic_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops, max77693_haptic_suspend, max77693_haptic_resume); diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 3809618e6a5d..11d0d3770239 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c @@ -133,8 +133,7 @@ static int max8925_onkey_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max8925_onkey_suspend(struct device *dev) +static int __maybe_unused max8925_onkey_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8925_onkey_info *info = platform_get_drvdata(pdev); @@ -148,7 +147,7 @@ static int max8925_onkey_suspend(struct device *dev) return 0; } -static int max8925_onkey_resume(struct device *dev) +static int __maybe_unused max8925_onkey_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8925_onkey_info *info = platform_get_drvdata(pdev); @@ -161,7 +160,6 @@ static int max8925_onkey_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max8925_onkey_pm_ops, max8925_onkey_suspend, max8925_onkey_resume); diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index a363ebbd9cc0..980437ac314d 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -378,8 +378,7 @@ static int max8997_haptic_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max8997_haptic_suspend(struct device *dev) +static int __maybe_unused max8997_haptic_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct max8997_haptic *chip = platform_get_drvdata(pdev); @@ -388,7 +387,6 @@ static int max8997_haptic_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, max8997_haptic_suspend, NULL); diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c index f505ac3a8d87..2c4d6ca5faab 100644 --- a/drivers/input/misc/palmas-pwrbutton.c +++ b/drivers/input/misc/palmas-pwrbutton.c @@ -260,7 +260,6 @@ static int palmas_pwron_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP /** * palmas_pwron_suspend() - suspend handler * @dev: power button device @@ -269,7 +268,7 @@ static int palmas_pwron_remove(struct platform_device *pdev) * * Return: 0 */ -static int palmas_pwron_suspend(struct device *dev) +static int __maybe_unused palmas_pwron_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct palmas_pwron *pwron = platform_get_drvdata(pdev); @@ -290,7 +289,7 @@ static int palmas_pwron_suspend(struct device *dev) * * Return: 0 */ -static int palmas_pwron_resume(struct device *dev) +static int __maybe_unused palmas_pwron_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct palmas_pwron *pwron = platform_get_drvdata(pdev); @@ -300,7 +299,6 @@ static int palmas_pwron_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(palmas_pwron_pm, palmas_pwron_suspend, palmas_pwron_resume); diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index 6a915ba31bba..e5266cd9acc0 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -199,8 +199,7 @@ static int pm8xxx_vib_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pm8xxx_vib_suspend(struct device *dev) +static int __maybe_unused pm8xxx_vib_suspend(struct device *dev) { struct pm8xxx_vib *vib = dev_get_drvdata(dev); @@ -209,7 +208,6 @@ static int pm8xxx_vib_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL); diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index c91e3d33aea9..28999455c752 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -53,8 +53,7 @@ static irqreturn_t pwrkey_release_irq(int irq, void *_pwr) return IRQ_HANDLED; } -#ifdef CONFIG_PM_SLEEP -static int pmic8xxx_pwrkey_suspend(struct device *dev) +static int __maybe_unused pmic8xxx_pwrkey_suspend(struct device *dev) { struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); @@ -64,7 +63,7 @@ static int pmic8xxx_pwrkey_suspend(struct device *dev) return 0; } -static int pmic8xxx_pwrkey_resume(struct device *dev) +static int __maybe_unused pmic8xxx_pwrkey_resume(struct device *dev) { struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); @@ -73,7 +72,6 @@ static int pmic8xxx_pwrkey_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 8ef288e7c971..93f640a38d94 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -144,8 +144,7 @@ static int pwm_beeper_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int pwm_beeper_suspend(struct device *dev) +static int __maybe_unused pwm_beeper_suspend(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); @@ -155,7 +154,7 @@ static int pwm_beeper_suspend(struct device *dev) return 0; } -static int pwm_beeper_resume(struct device *dev) +static int __maybe_unused pwm_beeper_resume(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); @@ -170,6 +169,7 @@ static int pwm_beeper_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, pwm_beeper_suspend, pwm_beeper_resume); +#ifdef CONFIG_PM_SLEEP #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) #else #define PWM_BEEPER_PM_OPS NULL diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index fed5102e1802..151f169afb7f 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -179,8 +179,7 @@ static int sirfsoc_pwrc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_pwrc_resume(struct device *dev) +static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev) { struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev); struct input_dev *input = pwrcdrv->input; @@ -196,7 +195,6 @@ static int sirfsoc_pwrc_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume); diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 960ef2a70910..c802c4af480c 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -157,8 +157,7 @@ static void twl4030_vibra_close(struct input_dev *input) } /*** Module ***/ -#ifdef CONFIG_PM_SLEEP -static int twl4030_vibra_suspend(struct device *dev) +static int __maybe_unused twl4030_vibra_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct vibra_info *info = platform_get_drvdata(pdev); @@ -169,12 +168,11 @@ static int twl4030_vibra_suspend(struct device *dev) return 0; } -static int twl4030_vibra_resume(struct device *dev) +static int __maybe_unused twl4030_vibra_resume(struct device *dev) { vibra_disable_leds(); return 0; } -#endif static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, twl4030_vibra_suspend, twl4030_vibra_resume); diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 6d26eecc278c..190fdef06e8f 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -236,8 +236,7 @@ static void twl6040_vibra_close(struct input_dev *input) mutex_unlock(&info->mutex); } -#ifdef CONFIG_PM_SLEEP -static int twl6040_vibra_suspend(struct device *dev) +static int __maybe_unused twl6040_vibra_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct vibra_info *info = platform_get_drvdata(pdev); @@ -251,7 +250,6 @@ static int twl6040_vibra_suspend(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); -- GitLab From 572081a431196f15206c6314381af4829ae3382d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Sun, 2 Nov 2014 00:03:37 -0700 Subject: [PATCH 2414/9457] Input: mouse - use __maybe_unused instead of ifdef around suspend/resume Use __maybe_unused instead of ifdef guards around suspend/resume functions, in order to increase build coverage and fix build warnings. Signed-off-by: Jingoo Han Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cyapa.c | 6 ++---- drivers/input/mouse/navpoint.c | 6 ++---- drivers/input/mouse/synaptics_i2c.c | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index b409c3d7d4fb..1d978c7289b4 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -905,8 +905,7 @@ static int cyapa_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int cyapa_suspend(struct device *dev) +static int __maybe_unused cyapa_suspend(struct device *dev) { int ret; u8 power_mode; @@ -929,7 +928,7 @@ static int cyapa_suspend(struct device *dev) return 0; } -static int cyapa_resume(struct device *dev) +static int __maybe_unused cyapa_resume(struct device *dev) { int ret; struct cyapa *cyapa = dev_get_drvdata(dev); @@ -944,7 +943,6 @@ static int cyapa_resume(struct device *dev) enable_irq(cyapa->irq); return 0; } -#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c index 1ccc88af1f0b..69017279e8d7 100644 --- a/drivers/input/mouse/navpoint.c +++ b/drivers/input/mouse/navpoint.c @@ -318,8 +318,7 @@ static int navpoint_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int navpoint_suspend(struct device *dev) +static int __maybe_unused navpoint_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct navpoint *navpoint = platform_get_drvdata(pdev); @@ -333,7 +332,7 @@ static int navpoint_suspend(struct device *dev) return 0; } -static int navpoint_resume(struct device *dev) +static int __maybe_unused navpoint_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct navpoint *navpoint = platform_get_drvdata(pdev); @@ -346,7 +345,6 @@ static int navpoint_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index ad822608f6ee..878f18498f3b 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -614,8 +614,7 @@ static int synaptics_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int synaptics_i2c_suspend(struct device *dev) +static int __maybe_unused synaptics_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct synaptics_i2c *touch = i2c_get_clientdata(client); @@ -628,7 +627,7 @@ static int synaptics_i2c_suspend(struct device *dev) return 0; } -static int synaptics_i2c_resume(struct device *dev) +static int __maybe_unused synaptics_i2c_resume(struct device *dev) { int ret; struct i2c_client *client = to_i2c_client(dev); @@ -643,7 +642,6 @@ static int synaptics_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, synaptics_i2c_resume); -- GitLab From 02b6a58b83b2f3d97addaf96ef60ad6596bf715f Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Sun, 2 Nov 2014 00:04:14 -0700 Subject: [PATCH 2415/9457] Input: touchscreen - use __maybe_unused instead of ifdef around suspend/resume Use __maybe_unused instead of ifdef guards around suspend/resume functions, in order to increase build coverage and fix build warnings. Signed-off-by: Jingoo Han Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ad7877.c | 6 ++---- drivers/input/touchscreen/ad7879.c | 6 ++---- drivers/input/touchscreen/ads7846.c | 6 ++---- drivers/input/touchscreen/atmel_mxt_ts.c | 6 ++---- drivers/input/touchscreen/auo-pixcir-ts.c | 6 ++---- drivers/input/touchscreen/cy8ctmg110_ts.c | 6 ++---- drivers/input/touchscreen/cyttsp_core.c | 7 ++----- drivers/input/touchscreen/edt-ft5x06.c | 6 ++---- drivers/input/touchscreen/eeti_ts.c | 6 ++---- drivers/input/touchscreen/egalax_ts.c | 6 ++---- drivers/input/touchscreen/ili210x.c | 6 ++---- drivers/input/touchscreen/ipaq-micro-ts.c | 6 ++---- drivers/input/touchscreen/mms114.c | 6 ++---- drivers/input/touchscreen/pixcir_i2c_ts.c | 6 ++---- drivers/input/touchscreen/st1232.c | 7 ++----- drivers/input/touchscreen/tsc2005.c | 6 ++---- drivers/input/touchscreen/ucb1400_ts.c | 6 ++---- drivers/input/touchscreen/wacom_i2c.c | 6 ++---- drivers/input/touchscreen/zforce_ts.c | 6 ++---- 19 files changed, 38 insertions(+), 78 deletions(-) diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 523865daa1d3..da4e5bb5e045 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -820,8 +820,7 @@ static int ad7877_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ad7877_suspend(struct device *dev) +static int __maybe_unused ad7877_suspend(struct device *dev) { struct ad7877 *ts = dev_get_drvdata(dev); @@ -830,7 +829,7 @@ static int ad7877_suspend(struct device *dev) return 0; } -static int ad7877_resume(struct device *dev) +static int __maybe_unused ad7877_resume(struct device *dev) { struct ad7877 *ts = dev_get_drvdata(dev); @@ -838,7 +837,6 @@ static int ad7877_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index fce590677b7b..927feec1e856 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c @@ -284,8 +284,7 @@ static void ad7879_close(struct input_dev* input) __ad7879_disable(ts); } -#ifdef CONFIG_PM_SLEEP -static int ad7879_suspend(struct device *dev) +static int __maybe_unused ad7879_suspend(struct device *dev) { struct ad7879 *ts = dev_get_drvdata(dev); @@ -301,7 +300,7 @@ static int ad7879_suspend(struct device *dev) return 0; } -static int ad7879_resume(struct device *dev) +static int __maybe_unused ad7879_resume(struct device *dev) { struct ad7879 *ts = dev_get_drvdata(dev); @@ -316,7 +315,6 @@ static int ad7879_resume(struct device *dev) return 0; } -#endif SIMPLE_DEV_PM_OPS(ad7879_pm_ops, ad7879_suspend, ad7879_resume); EXPORT_SYMBOL(ad7879_pm_ops); diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index e57ba52bf484..e4eb8a6c658f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -883,8 +883,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle) return IRQ_HANDLED; } -#ifdef CONFIG_PM_SLEEP -static int ads7846_suspend(struct device *dev) +static int __maybe_unused ads7846_suspend(struct device *dev) { struct ads7846 *ts = dev_get_drvdata(dev); @@ -906,7 +905,7 @@ static int ads7846_suspend(struct device *dev) return 0; } -static int ads7846_resume(struct device *dev) +static int __maybe_unused ads7846_resume(struct device *dev) { struct ads7846 *ts = dev_get_drvdata(dev); @@ -927,7 +926,6 @@ static int ads7846_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index aaacf8bfa61f..bb070206223c 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2244,8 +2244,7 @@ static int mxt_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int mxt_suspend(struct device *dev) +static int __maybe_unused mxt_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); @@ -2261,7 +2260,7 @@ static int mxt_suspend(struct device *dev) return 0; } -static int mxt_resume(struct device *dev) +static int __maybe_unused mxt_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mxt_data *data = i2c_get_clientdata(client); @@ -2276,7 +2275,6 @@ static int mxt_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 7f3c94787787..40e02dd5b2f9 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -417,8 +417,7 @@ static void auo_pixcir_input_close(struct input_dev *dev) return; } -#ifdef CONFIG_PM_SLEEP -static int auo_pixcir_suspend(struct device *dev) +static int __maybe_unused auo_pixcir_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct auo_pixcir_ts *ts = i2c_get_clientdata(client); @@ -450,7 +449,7 @@ static int auo_pixcir_suspend(struct device *dev) return ret; } -static int auo_pixcir_resume(struct device *dev) +static int __maybe_unused auo_pixcir_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct auo_pixcir_ts *ts = i2c_get_clientdata(client); @@ -479,7 +478,6 @@ static int auo_pixcir_resume(struct device *dev) return ret; } -#endif static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, auo_pixcir_resume); diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5bf1aeeea825..f2119ee0e21b 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -291,8 +291,7 @@ static int cy8ctmg110_probe(struct i2c_client *client, return err; } -#ifdef CONFIG_PM_SLEEP -static int cy8ctmg110_suspend(struct device *dev) +static int __maybe_unused cy8ctmg110_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct cy8ctmg110 *ts = i2c_get_clientdata(client); @@ -306,7 +305,7 @@ static int cy8ctmg110_suspend(struct device *dev) return 0; } -static int cy8ctmg110_resume(struct device *dev) +static int __maybe_unused cy8ctmg110_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct cy8ctmg110 *ts = i2c_get_clientdata(client); @@ -319,7 +318,6 @@ static int cy8ctmg110_resume(struct device *dev) } return 0; } -#endif static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index eee656f77a2e..5b74e8b84e79 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c @@ -472,8 +472,7 @@ static int cyttsp_disable(struct cyttsp *ts) return 0; } -#ifdef CONFIG_PM_SLEEP -static int cyttsp_suspend(struct device *dev) +static int __maybe_unused cyttsp_suspend(struct device *dev) { struct cyttsp *ts = dev_get_drvdata(dev); int retval = 0; @@ -491,7 +490,7 @@ static int cyttsp_suspend(struct device *dev) return retval; } -static int cyttsp_resume(struct device *dev) +static int __maybe_unused cyttsp_resume(struct device *dev) { struct cyttsp *ts = dev_get_drvdata(dev); @@ -507,8 +506,6 @@ static int cyttsp_resume(struct device *dev) return 0; } -#endif - SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); EXPORT_SYMBOL_GPL(cyttsp_pm_ops); diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 8857d5b9be71..2e4d90919f4b 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1092,8 +1092,7 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int edt_ft5x06_ts_suspend(struct device *dev) +static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1103,7 +1102,7 @@ static int edt_ft5x06_ts_suspend(struct device *dev) return 0; } -static int edt_ft5x06_ts_resume(struct device *dev) +static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -1112,7 +1111,6 @@ static int edt_ft5x06_ts_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops, edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume); diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index b1884ddd7a84..09be6ced7151 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -264,8 +264,7 @@ static int eeti_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int eeti_ts_suspend(struct device *dev) +static int __maybe_unused eeti_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct eeti_ts_priv *priv = i2c_get_clientdata(client); @@ -284,7 +283,7 @@ static int eeti_ts_suspend(struct device *dev) return 0; } -static int eeti_ts_resume(struct device *dev) +static int __maybe_unused eeti_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct eeti_ts_priv *priv = i2c_get_clientdata(client); @@ -302,7 +301,6 @@ static int eeti_ts_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index c8057847d71d..4c56299284ef 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -239,8 +239,7 @@ static const struct i2c_device_id egalax_ts_id[] = { }; MODULE_DEVICE_TABLE(i2c, egalax_ts_id); -#ifdef CONFIG_PM_SLEEP -static int egalax_ts_suspend(struct device *dev) +static int __maybe_unused egalax_ts_suspend(struct device *dev) { static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = { 0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0 @@ -252,13 +251,12 @@ static int egalax_ts_suspend(struct device *dev) return ret > 0 ? 0 : ret; } -static int egalax_ts_resume(struct device *dev) +static int __maybe_unused egalax_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); return egalax_wake_up_device(client); } -#endif static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 2a5089139818..da6dc819c846 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -311,8 +311,7 @@ static int ili210x_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ili210x_i2c_suspend(struct device *dev) +static int __maybe_unused ili210x_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -322,7 +321,7 @@ static int ili210x_i2c_suspend(struct device *dev) return 0; } -static int ili210x_i2c_resume(struct device *dev) +static int __maybe_unused ili210x_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -331,7 +330,6 @@ static int ili210x_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, ili210x_i2c_suspend, ili210x_i2c_resume); diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c index 62c8976e616f..33c134820ef9 100644 --- a/drivers/input/touchscreen/ipaq-micro-ts.c +++ b/drivers/input/touchscreen/ipaq-micro-ts.c @@ -122,8 +122,7 @@ static int micro_ts_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int micro_ts_suspend(struct device *dev) +static int __maybe_unused micro_ts_suspend(struct device *dev) { struct touchscreen_data *ts = dev_get_drvdata(dev); @@ -132,7 +131,7 @@ static int micro_ts_suspend(struct device *dev) return 0; } -static int micro_ts_resume(struct device *dev) +static int __maybe_unused micro_ts_resume(struct device *dev) { struct touchscreen_data *ts = dev_get_drvdata(dev); struct input_dev *input = ts->input; @@ -146,7 +145,6 @@ static int micro_ts_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops micro_ts_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume) diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 372bbf7658fe..67c0d31613d8 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -515,8 +515,7 @@ static int mms114_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int mms114_suspend(struct device *dev) +static int __maybe_unused mms114_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mms114_data *data = i2c_get_clientdata(client); @@ -540,7 +539,7 @@ static int mms114_suspend(struct device *dev) return 0; } -static int mms114_resume(struct device *dev) +static int __maybe_unused mms114_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mms114_data *data = i2c_get_clientdata(client); @@ -559,7 +558,6 @@ static int mms114_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume); diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index fc49c75317d1..4fb5537fdd42 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -347,8 +347,7 @@ static void pixcir_input_close(struct input_dev *dev) pixcir_stop(ts); } -#ifdef CONFIG_PM_SLEEP -static int pixcir_i2c_ts_suspend(struct device *dev) +static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); @@ -377,7 +376,7 @@ static int pixcir_i2c_ts_suspend(struct device *dev) return ret; } -static int pixcir_i2c_ts_resume(struct device *dev) +static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); @@ -405,7 +404,6 @@ static int pixcir_i2c_ts_resume(struct device *dev) return ret; } -#endif static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 3c0f57efe7b1..697e26e52d54 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -243,8 +243,7 @@ static int st1232_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int st1232_ts_suspend(struct device *dev) +static int __maybe_unused st1232_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); @@ -259,7 +258,7 @@ static int st1232_ts_suspend(struct device *dev) return 0; } -static int st1232_ts_resume(struct device *dev) +static int __maybe_unused st1232_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); @@ -274,8 +273,6 @@ static int st1232_ts_resume(struct device *dev) return 0; } -#endif - static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, st1232_ts_suspend, st1232_ts_resume); diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 52380b68ebdf..72657c579430 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -773,8 +773,7 @@ static int tsc2005_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_PM_SLEEP -static int tsc2005_suspend(struct device *dev) +static int __maybe_unused tsc2005_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct tsc2005 *ts = spi_get_drvdata(spi); @@ -791,7 +790,7 @@ static int tsc2005_suspend(struct device *dev) return 0; } -static int tsc2005_resume(struct device *dev) +static int __maybe_unused tsc2005_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct tsc2005 *ts = spi_get_drvdata(spi); @@ -807,7 +806,6 @@ static int tsc2005_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index b46c55cd1bbb..bf132c45af1a 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -406,8 +406,7 @@ static int ucb1400_ts_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int ucb1400_ts_suspend(struct device *dev) +static int __maybe_unused ucb1400_ts_suspend(struct device *dev) { struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; @@ -421,7 +420,7 @@ static int ucb1400_ts_suspend(struct device *dev) return 0; } -static int ucb1400_ts_resume(struct device *dev) +static int __maybe_unused ucb1400_ts_resume(struct device *dev) { struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; @@ -434,7 +433,6 @@ static int ucb1400_ts_resume(struct device *dev) mutex_unlock(&idev->mutex); return 0; } -#endif static SIMPLE_DEV_PM_OPS(ucb1400_ts_pm_ops, ucb1400_ts_suspend, ucb1400_ts_resume); diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index 7ccaa1b12b05..32f8ac003936 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -242,8 +242,7 @@ static int wacom_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int wacom_i2c_suspend(struct device *dev) +static int __maybe_unused wacom_i2c_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -252,7 +251,7 @@ static int wacom_i2c_suspend(struct device *dev) return 0; } -static int wacom_i2c_resume(struct device *dev) +static int __maybe_unused wacom_i2c_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -260,7 +259,6 @@ static int wacom_i2c_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 8ba48f5eff7b..19880c7385e3 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -602,8 +602,7 @@ static void zforce_input_close(struct input_dev *dev) return; } -#ifdef CONFIG_PM_SLEEP -static int zforce_suspend(struct device *dev) +static int __maybe_unused zforce_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct zforce_ts *ts = i2c_get_clientdata(client); @@ -648,7 +647,7 @@ static int zforce_suspend(struct device *dev) return ret; } -static int zforce_resume(struct device *dev) +static int __maybe_unused zforce_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct zforce_ts *ts = i2c_get_clientdata(client); @@ -685,7 +684,6 @@ static int zforce_resume(struct device *dev) return ret; } -#endif static SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); -- GitLab From 8761f9d6620b0be6b08f21807568fbbfcbb128d2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 02:45:58 +0100 Subject: [PATCH 2416/9457] Bluetooth: Check status of command complete for HCI_Reset When the HCI_Reset command returns, the status needs to be checked. It is unlikely that HCI_Reset actually fails, but when it fails, it is a bad idea to reset all values since the controller will have not reset its values in that case. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index aa152140c3e2..3dd2550b4c07 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -189,6 +189,9 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) clear_bit(HCI_RESET, &hdev->flags); + if (status) + return; + /* Reset all non-persistent flags */ hdev->dev_flags &= ~HCI_PERSISTENT_MASK; -- GitLab From 24dfa343716a493472db0555342bb88678efa444 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 02:56:41 +0100 Subject: [PATCH 2417/9457] Bluetooth: Print error message for HCI_Hardware_Error event When the HCI_Hardware_Error event is send by the controller or injected by the driver, then at least print an error message. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 5 +++++ net/bluetooth/hci_event.c | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 6e8f24967308..ecfa306e1375 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1463,6 +1463,11 @@ struct hci_ev_cmd_status { __le16 opcode; } __packed; +#define HCI_EV_HARDWARE_ERROR 0x10 +struct hci_ev_hardware_error { + __u8 code; +} __packed; + #define HCI_EV_ROLE_CHANGE 0x12 struct hci_ev_role_change { __u8 status; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3dd2550b4c07..2f02ff0ed781 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2925,6 +2925,13 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) } } +static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct hci_ev_hardware_error *ev = (void *) skb->data; + + BT_ERR("%s hardware error 0x%2.2x", hdev->name, ev->code); +} + static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; @@ -4746,6 +4753,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_cmd_status_evt(hdev, skb); break; + case HCI_EV_HARDWARE_ERROR: + hci_hardware_error_evt(hdev, skb); + break; + case HCI_EV_ROLE_CHANGE: hci_role_change_evt(hdev, skb); break; -- GitLab From b34490011d0d1a08124ffd6c4d5814ec94cd8f8f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 03:02:01 +0100 Subject: [PATCH 2418/9457] Bluetooth: Use HCI_EV_HARDWARE_ERROR define for event payload When constructing the event payload for the HCI_Hardware_Error event message, use the HCI_EV_HARDWARE_ERROR define. In addition rename the variables from hard_err to hw_err to clearly indicate that this is about the hardware error and not a hard error. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci_h5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index 20bdd71559b1..bd1fe37a7993 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -172,7 +172,7 @@ static void h5_peer_reset(struct hci_uart *hu) { struct h5 *h5 = hu->priv; struct sk_buff *skb; - const unsigned char hard_err[] = { 0x10, 0x01, 0x00 }; + const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; BT_ERR("Peer device has reset"); @@ -192,7 +192,7 @@ static void h5_peer_reset(struct hci_uart *hu) return; bt_cb(skb)->pkt_type = HCI_EVENT_PKT; - memcpy(skb_put(skb, 3), hard_err, 3); + memcpy(skb_put(skb, 3), hw_err, 3); /* Send Hardware Error to upper stack */ hci_recv_frame(hu->hdev, skb); -- GitLab From 65efd2bf4885312b42de9829159789199221cc60 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 03:32:25 +0100 Subject: [PATCH 2419/9457] Bluetooth: Introduce BT_BREDR and BT_LE config options The current kernel options do not make it clear which modules are for Bluetooth Classic (BR/EDR) and which are for Bluetooth Low Energy (LE). To make it really clear, introduce BT_BREDR and BT_LE options with proper dependencies into the different modules. Both new options default to y to not create a regression with previous kernel config files. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/Kconfig | 20 +++++++++++++++----- net/bluetooth/bnep/Kconfig | 2 +- net/bluetooth/cmtp/Kconfig | 2 +- net/bluetooth/hidp/Kconfig | 2 +- net/bluetooth/rfcomm/Kconfig | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 600fb29288f4..5e97a8ff850b 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -39,11 +39,10 @@ menuconfig BT to Bluetooth kernel modules are provided in the BlueZ packages. For more information, see . -config BT_6LOWPAN - tristate "Bluetooth 6LoWPAN support" - depends on BT && 6LOWPAN - help - IPv6 compression over Bluetooth Low Energy. +config BT_BREDR + bool "Bluetooth Classic (BR/EDR) features" + depends on BT + default y source "net/bluetooth/rfcomm/Kconfig" @@ -53,4 +52,15 @@ source "net/bluetooth/cmtp/Kconfig" source "net/bluetooth/hidp/Kconfig" +config BT_LE + bool "Bluetooth Low Energy (LE) features" + depends on BT + default y + +config BT_6LOWPAN + tristate "Bluetooth 6LoWPAN support" + depends on BT_LE && 6LOWPAN + help + IPv6 compression over Bluetooth Low Energy. + source "drivers/bluetooth/Kconfig" diff --git a/net/bluetooth/bnep/Kconfig b/net/bluetooth/bnep/Kconfig index 71791fc9f6b1..9b70317c49dc 100644 --- a/net/bluetooth/bnep/Kconfig +++ b/net/bluetooth/bnep/Kconfig @@ -1,6 +1,6 @@ config BT_BNEP tristate "BNEP protocol support" - depends on BT + depends on BT_BREDR select CRC32 help BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet diff --git a/net/bluetooth/cmtp/Kconfig b/net/bluetooth/cmtp/Kconfig index 94cbf42ce155..939da0fbdd88 100644 --- a/net/bluetooth/cmtp/Kconfig +++ b/net/bluetooth/cmtp/Kconfig @@ -1,6 +1,6 @@ config BT_CMTP tristate "CMTP protocol support" - depends on BT && ISDN_CAPI + depends on BT_BREDR && ISDN_CAPI help CMTP (CAPI Message Transport Protocol) is a transport layer for CAPI messages. CMTP is required for the Bluetooth Common diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 9332bc7aa851..bc8610b24077 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig @@ -1,6 +1,6 @@ config BT_HIDP tristate "HIDP protocol support" - depends on BT && INPUT + depends on BT_BREDR && INPUT select HID help HIDP (Human Interface Device Protocol) is a transport layer diff --git a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig index 18d352ea2bc7..335df7515220 100644 --- a/net/bluetooth/rfcomm/Kconfig +++ b/net/bluetooth/rfcomm/Kconfig @@ -1,6 +1,6 @@ config BT_RFCOMM tristate "RFCOMM protocol support" - depends on BT + depends on BT_BREDR help RFCOMM provides connection oriented stream transport. RFCOMM support is required for Dialup Networking, OBEX and other Bluetooth -- GitLab From 75e0569f7fc22272ec5e3b99bf94c6f0ad43b35f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 08:15:38 +0100 Subject: [PATCH 2420/9457] Bluetooth: Add hci_reset_dev() for driver triggerd stack reset Some Bluetooth drivers require to reset the upper stack. To avoid having all drivers send HCI Hardware Error events, provide a generic function to wrap the reset functionality. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b8685a77a15e..27ddb905b351 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -856,6 +856,7 @@ int hci_register_dev(struct hci_dev *hdev); void hci_unregister_dev(struct hci_dev *hdev); int hci_suspend_dev(struct hci_dev *hdev); int hci_resume_dev(struct hci_dev *hdev); +int hci_reset_dev(struct hci_dev *hdev); int hci_dev_open(__u16 dev); int hci_dev_close(__u16 dev); int hci_dev_reset(__u16 dev); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 41b147c36d11..a12e018ee21c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4248,6 +4248,24 @@ int hci_resume_dev(struct hci_dev *hdev) } EXPORT_SYMBOL(hci_resume_dev); +/* Reset HCI device */ +int hci_reset_dev(struct hci_dev *hdev) +{ + const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; + struct sk_buff *skb; + + skb = bt_skb_alloc(3, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + bt_cb(skb)->pkt_type = HCI_EVENT_PKT; + memcpy(skb_put(skb, 3), hw_err, 3); + + /* Send Hardware Error to upper stack */ + return hci_recv_frame(hdev, skb); +} +EXPORT_SYMBOL(hci_reset_dev); + /* Receive frame from HCI drivers */ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) { -- GitLab From 882809fb724c46b8ebc4de0944e94914ceb94e1c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 08:15:39 +0100 Subject: [PATCH 2421/9457] Bluetooth: Switch HCI H5 driver to use hci_reset_dev() function Instead of having the driver generate the HCI Hardware Error event manually, just call hci_reset_dev() to trigger the upper stack reset. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci_h5.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index bd1fe37a7993..ec0fa7732c0d 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -171,8 +171,6 @@ static void h5_timed_event(unsigned long arg) static void h5_peer_reset(struct hci_uart *hu) { struct h5 *h5 = hu->priv; - struct sk_buff *skb; - const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 }; BT_ERR("Peer device has reset"); @@ -187,15 +185,8 @@ static void h5_peer_reset(struct hci_uart *hu) h5->tx_seq = 0; h5->tx_ack = 0; - skb = bt_skb_alloc(3, GFP_ATOMIC); - if (!skb) - return; - - bt_cb(skb)->pkt_type = HCI_EVENT_PKT; - memcpy(skb_put(skb, 3), hw_err, 3); - - /* Send Hardware Error to upper stack */ - hci_recv_frame(hu->hdev, skb); + /* Send reset request to upper stack */ + hci_reset_dev(hu->hdev); } static int h5_open(struct hci_uart *hu) -- GitLab From ecd5c9821c39626fa7c03e9c397586b24cb11b79 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Sun, 2 Nov 2014 12:18:29 +0200 Subject: [PATCH 2422/9457] amdkfd: Implement the Get Version IOCTL Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 3130265e6827..64c73bae960d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -123,7 +123,16 @@ static int kfd_open(struct inode *inode, struct file *filep) static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, void __user *arg) { - return -ENODEV; + struct kfd_ioctl_get_version_args args; + int err = 0; + + args.major_version = KFD_IOCTL_MAJOR_VERSION; + args.minor_version = KFD_IOCTL_MINOR_VERSION; + + if (copy_to_user(arg, &args, sizeof(args))) + err = -EFAULT; + + return err; } static int set_queue_properties_from_user(struct queue_properties *q_properties, -- GitLab From 22a236b4d07b5c5cfdc5db9e87d479d32281cfe6 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Sun, 2 Nov 2014 12:04:41 +0530 Subject: [PATCH 2423/9457] ASoC: Intel: fix missing mutex on error in block prepare, we were returning the error code while still holding the mutex. We are releasing the mutex in this patch before return. Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index c451398b058c..4a5bde9c686b 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -1120,6 +1120,7 @@ int sst_block_alloc_scratch(struct sst_dsp *dsp) ret = block_list_prepare(dsp, &dsp->scratch_block_list); if (ret < 0) { dev_err(dsp->dev, "error: scratch block prepare failed\n"); + mutex_unlock(&dsp->mutex); return ret; } -- GitLab From a4164eb4dd3f4f2a22f8bf7b26394e8384f3d9a2 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:01 +0100 Subject: [PATCH 2424/9457] ieee802154: add missing ULL definition Running make C=2 occurs warning: constant 0xffffffffffffffff is so big it is unsigned long This patch fix this warning by adding a ULL to the constant definitions. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 9bba5ca7f0ad..9da7c011fbba 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -208,7 +208,8 @@ static inline bool ieee802154_is_valid_extended_addr(const __le64 addr) * This is currently a workaround because neighbor discovery can't * deal with short addresses types right now. */ - return ((addr != 0x0000000000000000) || (addr != 0xffffffffffffffff)); + return ((addr != 0x0000000000000000ULL) || + (addr != 0xffffffffffffffffULL)); } #endif /* LINUX_IEEE802154_H */ -- GitLab From c28bee84c5c49312befe1b442e1044ac2392d80d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:02 +0100 Subject: [PATCH 2425/9457] ieee802154: fix byteorder issues This patch fix byteorder issues which occurs because we compare __le64 with an host byteorder value. Simple add a cpu_to_le64 to convert the host byteorder values to __le64. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 9da7c011fbba..5d9e7459d94b 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -24,6 +24,7 @@ #define LINUX_IEEE802154_H #include +#include #define IEEE802154_MTU 127 #define IEEE802154_MIN_PSDU_LEN 5 @@ -208,8 +209,8 @@ static inline bool ieee802154_is_valid_extended_addr(const __le64 addr) * This is currently a workaround because neighbor discovery can't * deal with short addresses types right now. */ - return ((addr != 0x0000000000000000ULL) || - (addr != 0xffffffffffffffffULL)); + return ((addr != cpu_to_le64(0x0000000000000000ULL)) || + (addr != cpu_to_le64(0xffffffffffffffffULL))); } #endif /* LINUX_IEEE802154_H */ -- GitLab From f753f7eeb4178ab8eeaf513a4fdf1c20ddf40474 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:03 +0100 Subject: [PATCH 2426/9457] mac802154: fix byteorder issues Running make C=2 occurs these warnings: cast from restricted __be64 incorrect type in argument 1 (different base types) expected unsigned long long[unsigned] [usertype] val got restricted __be64 [usertype] cast from restricted __be64 cast to restricted __le64 This patch fix these warnings by forcing to __le64 type and using swabp64 instead swab64. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- include/net/mac802154.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/mac802154.h b/include/net/mac802154.h index c17acbd0dadc..8b0c26bc0762 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -215,12 +215,12 @@ struct ieee802154_ops { }; /** - * ieee802154_netdev_to_extended_addr - convert __be64 u8 pointer to __le64 + * ieee802154_netdev_to_extended_addr - convert big endian 64 byte void pointer to __le64 * @dev_addr: big endian address pointer like netdevice dev_addr attribute */ -static inline __le64 ieee802154_netdev_to_extended_addr(const u8 *dev_addr) +static inline __le64 ieee802154_netdev_to_extended_addr(const void *dev_addr) { - return (__le64)swab64(*((__be64 *)dev_addr)); + return (__force __le64)swab64p(dev_addr); } /* Basic interface to register ieee802154 hwice */ -- GitLab From c5fbbc4683276598ca1bfca95c90c35d1a3d962f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:04 +0100 Subject: [PATCH 2427/9457] ieee802154: sysfs: add missing include Running make C=2 occurs in warnings: symbol 'wpan_phy_class' was not declared. Should it be static? symbol 'wpan_phy_sysfs_init' was not declared. Should it be static? symbol 'wpan_phy_sysfs_exit' wasnot declared. Should it be static? This patch adds a missing include "sysfs.h" to solve these warnings. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/ieee802154/sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c index c6e038099e07..88199980dae9 100644 --- a/net/ieee802154/sysfs.c +++ b/net/ieee802154/sysfs.c @@ -18,6 +18,7 @@ #include #include "core.h" +#include "sysfs.h" static inline struct cfg802154_registered_device * dev_to_rdev(struct device *dev) -- GitLab From fdd2068ab7574d9d9b966a97cc7af296a4232694 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:05 +0100 Subject: [PATCH 2428/9457] mac802154: cfg: add missing include Running make C=2 occurs warning: symbol 'mac802154_config_ops' was not declared. Should it be static? This patch adds a missing include in cfg.c to solve this warning. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/mac802154/cfg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 75a5d258ac24..0c69b44ba312 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -16,6 +16,7 @@ #include #include "ieee802154_i.h" +#include "cfg.h" static struct net_device * ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, -- GitLab From 868ed8e06a35ea2e73dfe4cb81d96dc85f545a8e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 21:43:06 +0100 Subject: [PATCH 2429/9457] ieee802154: remove unnecessary functions This patch fixes commit c7420c367d63a7e1414e010afb52c3837fd9134e ("mac802154: move mac_params functions into mac_cmd"). The mac_params functions wasn't deleted by this commit. Signed-off-by: Alexander Aring Reported-by: Marcel Holtmann Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index ceedf3ef1ce2..0c9d00c83654 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -127,28 +127,6 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) return mac802154_wpan_update_llsec(dev); } -int mac802154_set_mac_params(struct net_device *dev, - const struct ieee802154_mac_params *params) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - mutex_lock(&sdata->local->iflist_mtx); - sdata->mac_params = *params; - mutex_unlock(&sdata->local->iflist_mtx); - - return 0; -} - -void mac802154_get_mac_params(struct net_device *dev, - struct ieee802154_mac_params *params) -{ - struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); - - mutex_lock(&sdata->local->iflist_mtx); - *params = sdata->mac_params; - mutex_unlock(&sdata->local->iflist_mtx); -} - static int mac802154_slave_open(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); -- GitLab From db597605821fccc49876705aea5db5443d67e53e Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 30 Oct 2014 11:04:53 -0700 Subject: [PATCH 2430/9457] PM / Hibernate: Migrate to ktime_t This patch migrates swsusp_show_speed and its callers to using ktime_t instead of 'struct timeval' which suffers from the y2038 problem. Changes to swsusp_show_speed: - use ktime_t for start and stop times - pass start and stop times by value Calling functions affected: - load_image - load_image_lzo - save_image - save_image_lzo - hibernate_preallocate_memory Design decisions: - use ktime_t to preserve same granularity of reporting as before - use centisecs logic as before to avoid 'div by zero' issues caused by using seconds and nanoseconds directly - use monotonic time (ktime_get()) since we only care about elapsed time. Signed-off-by: Tina Ruchandani Suggested-by: Arnd Bergmann Reviewed-by: Arnd Bergmann Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- kernel/power/hibernate.c | 14 ++++++-------- kernel/power/power.h | 3 +-- kernel/power/snapshot.c | 9 +++++---- kernel/power/swap.c | 41 ++++++++++++++++++++-------------------- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 1f35a3478f3c..2329daae5255 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "power.h" @@ -232,20 +233,17 @@ static void platform_recover(int platform_mode) * @nr_pages: Number of memory pages processed between @start and @stop. * @msg: Additional diagnostic message to print. */ -void swsusp_show_speed(struct timeval *start, struct timeval *stop, - unsigned nr_pages, char *msg) +void swsusp_show_speed(ktime_t start, ktime_t stop, + unsigned nr_pages, char *msg) { + ktime_t diff; u64 elapsed_centisecs64; unsigned int centisecs; unsigned int k; unsigned int kps; - elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); - /* - * If "(s64)elapsed_centisecs64 < 0", it will print long elapsed time, - * it is obvious enough for what went wrong. - */ - do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); + diff = ktime_sub(stop, start); + elapsed_centisecs64 = ktime_divns(diff, 10*NSEC_PER_MSEC); centisecs = elapsed_centisecs64; if (centisecs == 0) centisecs = 1; /* avoid div-by-zero */ diff --git a/kernel/power/power.h b/kernel/power/power.h index 2df883a9d3cb..ce9b8328a689 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -174,8 +174,7 @@ extern int hib_wait_on_bio_chain(struct bio **bio_chain); struct timeval; /* kernel/power/swsusp.c */ -extern void swsusp_show_speed(struct timeval *, struct timeval *, - unsigned int, char *); +extern void swsusp_show_speed(ktime_t, ktime_t, unsigned int, char *); #ifdef CONFIG_SUSPEND /* kernel/power/suspend.c */ diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 791a61892bb5..0c40c16174b4 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1576,11 +1577,11 @@ int hibernate_preallocate_memory(void) struct zone *zone; unsigned long saveable, size, max_size, count, highmem, pages = 0; unsigned long alloc, save_highmem, pages_highmem, avail_normal; - struct timeval start, stop; + ktime_t start, stop; int error; printk(KERN_INFO "PM: Preallocating image memory... "); - do_gettimeofday(&start); + start = ktime_get(); error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY); if (error) @@ -1709,9 +1710,9 @@ int hibernate_preallocate_memory(void) free_unnecessary_pages(); out: - do_gettimeofday(&stop); + stop = ktime_get(); printk(KERN_CONT "done (allocated %lu pages)\n", pages); - swsusp_show_speed(&start, &stop, pages, "Allocated"); + swsusp_show_speed(start, stop, pages, "Allocated"); return 0; diff --git a/kernel/power/swap.c b/kernel/power/swap.c index aaa3261dea5d..2c9d6d50a816 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "power.h" @@ -445,8 +446,8 @@ static int save_image(struct swap_map_handle *handle, int nr_pages; int err2; struct bio *bio; - struct timeval start; - struct timeval stop; + ktime_t start; + ktime_t stop; printk(KERN_INFO "PM: Saving image data pages (%u pages)...\n", nr_to_write); @@ -455,7 +456,7 @@ static int save_image(struct swap_map_handle *handle, m = 1; nr_pages = 0; bio = NULL; - do_gettimeofday(&start); + start = ktime_get(); while (1) { ret = snapshot_read_next(snapshot); if (ret <= 0) @@ -469,12 +470,12 @@ static int save_image(struct swap_map_handle *handle, nr_pages++; } err2 = hib_wait_on_bio_chain(&bio); - do_gettimeofday(&stop); + stop = ktime_get(); if (!ret) ret = err2; if (!ret) printk(KERN_INFO "PM: Image saving done.\n"); - swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); + swsusp_show_speed(start, stop, nr_to_write, "Wrote"); return ret; } @@ -580,8 +581,8 @@ static int save_image_lzo(struct swap_map_handle *handle, int nr_pages; int err2; struct bio *bio; - struct timeval start; - struct timeval stop; + ktime_t start; + ktime_t stop; size_t off; unsigned thr, run_threads, nr_threads; unsigned char *page = NULL; @@ -674,7 +675,7 @@ static int save_image_lzo(struct swap_map_handle *handle, m = 1; nr_pages = 0; bio = NULL; - do_gettimeofday(&start); + start = ktime_get(); for (;;) { for (thr = 0; thr < nr_threads; thr++) { for (off = 0; off < LZO_UNC_SIZE; off += PAGE_SIZE) { @@ -759,12 +760,12 @@ static int save_image_lzo(struct swap_map_handle *handle, out_finish: err2 = hib_wait_on_bio_chain(&bio); - do_gettimeofday(&stop); + stop = ktime_get(); if (!ret) ret = err2; if (!ret) printk(KERN_INFO "PM: Image saving done.\n"); - swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); + swsusp_show_speed(start, stop, nr_to_write, "Wrote"); out_clean: if (crc) { if (crc->thr) @@ -965,8 +966,8 @@ static int load_image(struct swap_map_handle *handle, { unsigned int m; int ret = 0; - struct timeval start; - struct timeval stop; + ktime_t start; + ktime_t stop; struct bio *bio; int err2; unsigned nr_pages; @@ -978,7 +979,7 @@ static int load_image(struct swap_map_handle *handle, m = 1; nr_pages = 0; bio = NULL; - do_gettimeofday(&start); + start = ktime_get(); for ( ; ; ) { ret = snapshot_write_next(snapshot); if (ret <= 0) @@ -996,7 +997,7 @@ static int load_image(struct swap_map_handle *handle, nr_pages++; } err2 = hib_wait_on_bio_chain(&bio); - do_gettimeofday(&stop); + stop = ktime_get(); if (!ret) ret = err2; if (!ret) { @@ -1005,7 +1006,7 @@ static int load_image(struct swap_map_handle *handle, if (!snapshot_image_loaded(snapshot)) ret = -ENODATA; } - swsusp_show_speed(&start, &stop, nr_to_read, "Read"); + swsusp_show_speed(start, stop, nr_to_read, "Read"); return ret; } @@ -1067,8 +1068,8 @@ static int load_image_lzo(struct swap_map_handle *handle, int ret = 0; int eof = 0; struct bio *bio; - struct timeval start; - struct timeval stop; + ktime_t start; + ktime_t stop; unsigned nr_pages; size_t off; unsigned i, thr, run_threads, nr_threads; @@ -1190,7 +1191,7 @@ static int load_image_lzo(struct swap_map_handle *handle, m = 1; nr_pages = 0; bio = NULL; - do_gettimeofday(&start); + start = ktime_get(); ret = snapshot_write_next(snapshot); if (ret <= 0) @@ -1343,7 +1344,7 @@ static int load_image_lzo(struct swap_map_handle *handle, wait_event(crc->done, atomic_read(&crc->stop)); atomic_set(&crc->stop, 0); } - do_gettimeofday(&stop); + stop = ktime_get(); if (!ret) { printk(KERN_INFO "PM: Image loading done.\n"); snapshot_write_finalize(snapshot); @@ -1359,7 +1360,7 @@ static int load_image_lzo(struct swap_map_handle *handle, } } } - swsusp_show_speed(&start, &stop, nr_to_read, "Read"); + swsusp_show_speed(start, stop, nr_to_read, "Read"); out_clean: for (i = 0; i < ring_size; i++) free_page((unsigned long)page[i]); -- GitLab From 69111bac42f5ceacdd22e30947837ceb2c4493ed Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 21 Oct 2014 15:23:25 -0500 Subject: [PATCH 2431/9457] powerpc: Replace __get_cpu_var uses This still has not been merged and now powerpc is the only arch that does not have this change. Sorry about missing linuxppc-dev before. V2->V2 - Fix up to work against 3.18-rc1 __get_cpu_var() is used for multiple purposes in the kernel source. One of them is address calculation via the form &__get_cpu_var(x). This calculates the address for the instance of the percpu variable of the current processor based on an offset. Other use cases are for storing and retrieving data from the current processors percpu area. __get_cpu_var() can be used as an lvalue when writing data or on the right side of an assignment. __get_cpu_var() is defined as : __get_cpu_var() always only does an address determination. However, store and retrieve operations could use a segment prefix (or global register on other platforms) to avoid the address calculation. this_cpu_write() and this_cpu_read() can directly take an offset into a percpu area and use optimized assembly code to read and write per cpu variables. This patch converts __get_cpu_var into either an explicit address calculation using this_cpu_ptr() or into a use of this_cpu operations that use the offset. Thereby address calculations are avoided and less registers are used when code is generated. At the end of the patch set all uses of __get_cpu_var have been removed so the macro is removed too. The patch set includes passes over all arches as well. Once these operations are used throughout then specialized macros can be defined in non -x86 arches as well in order to optimize per cpu access by f.e. using a global register that may be set to the per cpu base. Transformations done to __get_cpu_var() 1. Determine the address of the percpu instance of the current processor. DEFINE_PER_CPU(int, y); int *x = &__get_cpu_var(y); Converts to int *x = this_cpu_ptr(&y); 2. Same as #1 but this time an array structure is involved. DEFINE_PER_CPU(int, y[20]); int *x = __get_cpu_var(y); Converts to int *x = this_cpu_ptr(y); 3. Retrieve the content of the current processors instance of a per cpu variable. DEFINE_PER_CPU(int, y); int x = __get_cpu_var(y) Converts to int x = __this_cpu_read(y); 4. Retrieve the content of a percpu struct DEFINE_PER_CPU(struct mystruct, y); struct mystruct x = __get_cpu_var(y); Converts to memcpy(&x, this_cpu_ptr(&y), sizeof(x)); 5. Assignment to a per cpu variable DEFINE_PER_CPU(int, y) __get_cpu_var(y) = x; Converts to __this_cpu_write(y, x); 6. Increment/Decrement etc of a per cpu variable DEFINE_PER_CPU(int, y); __get_cpu_var(y)++ Converts to __this_cpu_inc(y) Cc: Benjamin Herrenschmidt CC: Paul Mackerras Signed-off-by: Christoph Lameter [mpe: Fix build errors caused by set/or_softirq_pending(), and rework assignment in __set_breakpoint() to use memcpy().] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/hardirq.h | 7 +++++- arch/powerpc/include/asm/tlbflush.h | 4 ++-- arch/powerpc/include/asm/xics.h | 8 +++---- arch/powerpc/kernel/dbell.c | 2 +- arch/powerpc/kernel/hw_breakpoint.c | 6 ++--- arch/powerpc/kernel/iommu.c | 2 +- arch/powerpc/kernel/irq.c | 4 ++-- arch/powerpc/kernel/kgdb.c | 2 +- arch/powerpc/kernel/kprobes.c | 6 ++--- arch/powerpc/kernel/mce.c | 24 +++++++++---------- arch/powerpc/kernel/process.c | 10 ++++---- arch/powerpc/kernel/smp.c | 6 ++--- arch/powerpc/kernel/sysfs.c | 4 ++-- arch/powerpc/kernel/time.c | 22 ++++++++--------- arch/powerpc/kernel/traps.c | 8 +++---- arch/powerpc/kvm/e500.c | 14 +++++------ arch/powerpc/kvm/e500mc.c | 4 ++-- arch/powerpc/mm/hash_native_64.c | 2 +- arch/powerpc/mm/hash_utils_64.c | 2 +- arch/powerpc/mm/hugetlbpage-book3e.c | 6 ++--- arch/powerpc/mm/hugetlbpage.c | 2 +- arch/powerpc/perf/core-book3s.c | 22 ++++++++--------- arch/powerpc/perf/core-fsl-emb.c | 6 ++--- arch/powerpc/platforms/cell/interrupt.c | 6 ++--- .../platforms/powernv/opal-tracepoints.c | 4 ++-- arch/powerpc/platforms/ps3/interrupt.c | 2 +- arch/powerpc/platforms/pseries/dtl.c | 2 +- arch/powerpc/platforms/pseries/hvCall_inst.c | 4 ++-- arch/powerpc/platforms/pseries/iommu.c | 8 +++---- arch/powerpc/platforms/pseries/lpar.c | 6 ++--- arch/powerpc/platforms/pseries/ras.c | 4 ++-- arch/powerpc/sysdev/xics/xics-common.c | 2 +- 32 files changed, 108 insertions(+), 103 deletions(-) diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index 1bbb3013d6aa..8add8b861e8d 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h @@ -21,7 +21,12 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #define __ARCH_IRQ_STAT -#define local_softirq_pending() __get_cpu_var(irq_stat).__softirq_pending +#define local_softirq_pending() __this_cpu_read(irq_stat.__softirq_pending) + +#define __ARCH_SET_SOFTIRQ_PENDING + +#define set_softirq_pending(x) __this_cpu_write(irq_stat.__softirq_pending, (x)) +#define or_softirq_pending(x) __this_cpu_or(irq_stat.__softirq_pending, (x)) static inline void ack_bad_irq(unsigned int irq) { diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h index 2def01ed0cb2..cd7c2719d3ef 100644 --- a/arch/powerpc/include/asm/tlbflush.h +++ b/arch/powerpc/include/asm/tlbflush.h @@ -107,14 +107,14 @@ extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); static inline void arch_enter_lazy_mmu_mode(void) { - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); batch->active = 1; } static inline void arch_leave_lazy_mmu_mode(void) { - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); if (batch->index) __flush_tlb_pending(batch); diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 0d050ea37a04..6997f4a271df 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -98,7 +98,7 @@ DECLARE_PER_CPU(struct xics_cppr, xics_cppr); static inline void xics_push_cppr(unsigned int vec) { - struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr); if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1)) return; @@ -111,7 +111,7 @@ static inline void xics_push_cppr(unsigned int vec) static inline unsigned char xics_pop_cppr(void) { - struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr); if (WARN_ON(os_cppr->index < 1)) return LOWEST_PRIORITY; @@ -121,7 +121,7 @@ static inline unsigned char xics_pop_cppr(void) static inline void xics_set_base_cppr(unsigned char cppr) { - struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr); /* we only really want to set the priority when there's * just one cppr value on the stack @@ -133,7 +133,7 @@ static inline void xics_set_base_cppr(unsigned char cppr) static inline unsigned char xics_cppr_top(void) { - struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr); return os_cppr->stack[os_cppr->index]; } diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index d55c76c571f3..f4217819cc31 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c @@ -41,7 +41,7 @@ void doorbell_exception(struct pt_regs *regs) may_hard_irq_enable(); - __get_cpu_var(irq_stat).doorbell_irqs++; + __this_cpu_inc(irq_stat.doorbell_irqs); smp_ipi_demux(); diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 1f7d84e2e8b2..05e804cdecaa 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -63,7 +63,7 @@ int hw_breakpoint_slots(int type) int arch_install_hw_breakpoint(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); - struct perf_event **slot = &__get_cpu_var(bp_per_reg); + struct perf_event **slot = this_cpu_ptr(&bp_per_reg); *slot = bp; @@ -88,7 +88,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) */ void arch_uninstall_hw_breakpoint(struct perf_event *bp) { - struct perf_event **slot = &__get_cpu_var(bp_per_reg); + struct perf_event **slot = this_cpu_ptr(&bp_per_reg); if (*slot != bp) { WARN_ONCE(1, "Can't find the breakpoint"); @@ -226,7 +226,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) */ rcu_read_lock(); - bp = __get_cpu_var(bp_per_reg); + bp = __this_cpu_read(bp_per_reg); if (!bp) goto out; info = counter_arch_bp(bp); diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index a10642a0d861..71e60bfb89e2 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -208,7 +208,7 @@ static unsigned long iommu_range_alloc(struct device *dev, * We don't need to disable preemption here because any CPU can * safely use any IOMMU pool. */ - pool_nr = __raw_get_cpu_var(iommu_pool_hash) & (tbl->nr_pools - 1); + pool_nr = __this_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1); if (largealloc) pool = &(tbl->large_pool); diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index c14383575fe8..8d87bb162ecd 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -114,7 +114,7 @@ static inline notrace void set_soft_enabled(unsigned long enable) static inline notrace int decrementer_check_overflow(void) { u64 now = get_tb_or_rtc(); - u64 *next_tb = &__get_cpu_var(decrementers_next_tb); + u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); return now >= *next_tb; } @@ -499,7 +499,7 @@ void __do_irq(struct pt_regs *regs) /* And finally process it */ if (unlikely(irq == NO_IRQ)) - __get_cpu_var(irq_stat).spurious_irqs++; + __this_cpu_inc(irq_stat.spurious_irqs); else generic_handle_irq(irq); diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 8504657379f1..e77c3ccf8dcf 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -155,7 +155,7 @@ static int kgdb_singlestep(struct pt_regs *regs) { struct thread_info *thread_info, *exception_thread_info; struct thread_info *backup_current_thread_info = - &__get_cpu_var(kgdb_thread_info); + this_cpu_ptr(&kgdb_thread_info); if (user_mode(regs)) return 0; diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 2f72af82513c..7c053f281406 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -119,7 +119,7 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) { - __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; + __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; } @@ -127,7 +127,7 @@ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { - __get_cpu_var(current_kprobe) = p; + __this_cpu_write(current_kprobe, p); kcb->kprobe_saved_msr = regs->msr; } @@ -192,7 +192,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) ret = 1; goto no_kprobe; } - p = __get_cpu_var(current_kprobe); + p = __this_cpu_read(current_kprobe); if (p->break_handler && p->break_handler(p, regs)) { goto ss_probe; } diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index a7fd4cb78b78..15c99b649b04 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -73,8 +73,8 @@ void save_mce_event(struct pt_regs *regs, long handled, uint64_t nip, uint64_t addr) { uint64_t srr1; - int index = __get_cpu_var(mce_nest_count)++; - struct machine_check_event *mce = &__get_cpu_var(mce_event[index]); + int index = __this_cpu_inc_return(mce_nest_count); + struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]); /* * Return if we don't have enough space to log mce event. @@ -143,7 +143,7 @@ void save_mce_event(struct pt_regs *regs, long handled, */ int get_mce_event(struct machine_check_event *mce, bool release) { - int index = __get_cpu_var(mce_nest_count) - 1; + int index = __this_cpu_read(mce_nest_count) - 1; struct machine_check_event *mc_evt; int ret = 0; @@ -153,7 +153,7 @@ int get_mce_event(struct machine_check_event *mce, bool release) /* Check if we have MCE info to process. */ if (index < MAX_MC_EVT) { - mc_evt = &__get_cpu_var(mce_event[index]); + mc_evt = this_cpu_ptr(&mce_event[index]); /* Copy the event structure and release the original */ if (mce) *mce = *mc_evt; @@ -163,7 +163,7 @@ int get_mce_event(struct machine_check_event *mce, bool release) } /* Decrement the count to free the slot. */ if (release) - __get_cpu_var(mce_nest_count)--; + __this_cpu_dec(mce_nest_count); return ret; } @@ -184,13 +184,13 @@ void machine_check_queue_event(void) if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) return; - index = __get_cpu_var(mce_queue_count)++; + index = __this_cpu_inc_return(mce_queue_count); /* If queue is full, just return for now. */ if (index >= MAX_MC_EVT) { - __get_cpu_var(mce_queue_count)--; + __this_cpu_dec(mce_queue_count); return; } - __get_cpu_var(mce_event_queue[index]) = evt; + memcpy(this_cpu_ptr(&mce_event_queue[index]), &evt, sizeof(evt)); /* Queue irq work to process this event later. */ irq_work_queue(&mce_event_process_work); @@ -208,11 +208,11 @@ static void machine_check_process_queued_event(struct irq_work *work) * For now just print it to console. * TODO: log this error event to FSP or nvram. */ - while (__get_cpu_var(mce_queue_count) > 0) { - index = __get_cpu_var(mce_queue_count) - 1; + while (__this_cpu_read(mce_queue_count) > 0) { + index = __this_cpu_read(mce_queue_count) - 1; machine_check_print_event_info( - &__get_cpu_var(mce_event_queue[index])); - __get_cpu_var(mce_queue_count)--; + this_cpu_ptr(&mce_event_queue[index])); + __this_cpu_dec(mce_queue_count); } } diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 923cd2daba89..91e132b495bf 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -499,7 +499,7 @@ static inline int set_dawr(struct arch_hw_breakpoint *brk) void __set_breakpoint(struct arch_hw_breakpoint *brk) { - __get_cpu_var(current_brk) = *brk; + memcpy(this_cpu_ptr(¤t_brk), brk, sizeof(*brk)); if (cpu_has_feature(CPU_FTR_DAWR)) set_dawr(brk); @@ -842,7 +842,7 @@ struct task_struct *__switch_to(struct task_struct *prev, * schedule DABR */ #ifndef CONFIG_HAVE_HW_BREAKPOINT - if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk))) + if (unlikely(!hw_brk_match(this_cpu_ptr(¤t_brk), &new->thread.hw_brk))) __set_breakpoint(&new->thread.hw_brk); #endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif @@ -856,7 +856,7 @@ struct task_struct *__switch_to(struct task_struct *prev, * Collect processor utilization data per process */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); + struct cpu_usage *cu = this_cpu_ptr(&cpu_usage_array); long unsigned start_tb, current_tb; start_tb = old_thread->start_tb; cu->current_tb = current_tb = mfspr(SPRN_PURR); @@ -866,7 +866,7 @@ struct task_struct *__switch_to(struct task_struct *prev, #endif /* CONFIG_PPC64 */ #ifdef CONFIG_PPC_BOOK3S_64 - batch = &__get_cpu_var(ppc64_tlb_batch); + batch = this_cpu_ptr(&ppc64_tlb_batch); if (batch->active) { current_thread_info()->local_flags |= _TLF_LAZY_MMU; if (batch->index) @@ -889,7 +889,7 @@ struct task_struct *__switch_to(struct task_struct *prev, #ifdef CONFIG_PPC_BOOK3S_64 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; - batch = &__get_cpu_var(ppc64_tlb_batch); + batch = this_cpu_ptr(&ppc64_tlb_batch); batch->active = 1; } #endif /* CONFIG_PPC_BOOK3S_64 */ diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 71e186d5f331..8b2d2dc8ef10 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -243,7 +243,7 @@ void smp_muxed_ipi_message_pass(int cpu, int msg) irqreturn_t smp_ipi_demux(void) { - struct cpu_messages *info = &__get_cpu_var(ipi_message); + struct cpu_messages *info = this_cpu_ptr(&ipi_message); unsigned int all; mb(); /* order any irq clear */ @@ -442,9 +442,9 @@ void generic_mach_cpu_die(void) idle_task_exit(); cpu = smp_processor_id(); printk(KERN_DEBUG "CPU%d offline\n", cpu); - __get_cpu_var(cpu_state) = CPU_DEAD; + __this_cpu_write(cpu_state, CPU_DEAD); smp_wmb(); - while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) + while (__this_cpu_read(cpu_state) != CPU_UP_PREPARE) cpu_relax(); } diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 67fd2fd2620a..fa1fd8a0c867 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -394,10 +394,10 @@ void ppc_enable_pmcs(void) ppc_set_pmu_inuse(1); /* Only need to enable them once */ - if (__get_cpu_var(pmcs_enabled)) + if (__this_cpu_read(pmcs_enabled)) return; - __get_cpu_var(pmcs_enabled) = 1; + __this_cpu_write(pmcs_enabled, 1); if (ppc_md.enable_pmcs) ppc_md.enable_pmcs(); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 7505599c2593..9f8ea617ff2c 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -458,9 +458,9 @@ static inline void clear_irq_work_pending(void) DEFINE_PER_CPU(u8, irq_work_pending); -#define set_irq_work_pending_flag() __get_cpu_var(irq_work_pending) = 1 -#define test_irq_work_pending() __get_cpu_var(irq_work_pending) -#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 +#define set_irq_work_pending_flag() __this_cpu_write(irq_work_pending, 1) +#define test_irq_work_pending() __this_cpu_read(irq_work_pending) +#define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0) #endif /* 32 vs 64 bit */ @@ -482,8 +482,8 @@ void arch_irq_work_raise(void) static void __timer_interrupt(void) { struct pt_regs *regs = get_irq_regs(); - u64 *next_tb = &__get_cpu_var(decrementers_next_tb); - struct clock_event_device *evt = &__get_cpu_var(decrementers); + u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); + struct clock_event_device *evt = this_cpu_ptr(&decrementers); u64 now; trace_timer_interrupt_entry(regs); @@ -498,7 +498,7 @@ static void __timer_interrupt(void) *next_tb = ~(u64)0; if (evt->event_handler) evt->event_handler(evt); - __get_cpu_var(irq_stat).timer_irqs_event++; + __this_cpu_inc(irq_stat.timer_irqs_event); } else { now = *next_tb - now; if (now <= DECREMENTER_MAX) @@ -506,13 +506,13 @@ static void __timer_interrupt(void) /* We may have raced with new irq work */ if (test_irq_work_pending()) set_dec(1); - __get_cpu_var(irq_stat).timer_irqs_others++; + __this_cpu_inc(irq_stat.timer_irqs_others); } #ifdef CONFIG_PPC64 /* collect purr register values often, for accurate calculations */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); + struct cpu_usage *cu = this_cpu_ptr(&cpu_usage_array); cu->current_tb = mfspr(SPRN_PURR); } #endif @@ -527,7 +527,7 @@ static void __timer_interrupt(void) void timer_interrupt(struct pt_regs * regs) { struct pt_regs *old_regs; - u64 *next_tb = &__get_cpu_var(decrementers_next_tb); + u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); /* Ensure a positive value is written to the decrementer, or else * some CPUs will continue to take decrementer exceptions. @@ -813,7 +813,7 @@ static void __init clocksource_init(void) static int decrementer_set_next_event(unsigned long evt, struct clock_event_device *dev) { - __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; + __this_cpu_write(decrementers_next_tb, get_tb_or_rtc() + evt); set_dec(evt); /* We may have raced with new irq work */ @@ -833,7 +833,7 @@ static void decrementer_set_mode(enum clock_event_mode mode, /* Interrupt handler for the timer broadcast IPI */ void tick_broadcast_ipi_handler(void) { - u64 *next_tb = &__get_cpu_var(decrementers_next_tb); + u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); *next_tb = get_tb_or_rtc(); __timer_interrupt(); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0dc43f9932cf..e6595b72269b 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -295,7 +295,7 @@ long machine_check_early(struct pt_regs *regs) { long handled = 0; - __get_cpu_var(irq_stat).mce_exceptions++; + __this_cpu_inc(irq_stat.mce_exceptions); if (cur_cpu_spec && cur_cpu_spec->machine_check_early) handled = cur_cpu_spec->machine_check_early(regs); @@ -304,7 +304,7 @@ long machine_check_early(struct pt_regs *regs) long hmi_exception_realmode(struct pt_regs *regs) { - __get_cpu_var(irq_stat).hmi_exceptions++; + __this_cpu_inc(irq_stat.hmi_exceptions); if (ppc_md.hmi_exception_early) ppc_md.hmi_exception_early(regs); @@ -700,7 +700,7 @@ void machine_check_exception(struct pt_regs *regs) enum ctx_state prev_state = exception_enter(); int recover = 0; - __get_cpu_var(irq_stat).mce_exceptions++; + __this_cpu_inc(irq_stat.mce_exceptions); /* See if any machine dependent calls. In theory, we would want * to call the CPU first, and call the ppc_md. one if the CPU @@ -1519,7 +1519,7 @@ void vsx_unavailable_tm(struct pt_regs *regs) void performance_monitor_exception(struct pt_regs *regs) { - __get_cpu_var(irq_stat).pmu_irqs++; + __this_cpu_inc(irq_stat.pmu_irqs); perf_irq(regs); } diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 2e02ed849f36..16095841afe1 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -76,11 +76,11 @@ static inline int local_sid_setup_one(struct id *entry) unsigned long sid; int ret = -1; - sid = ++(__get_cpu_var(pcpu_last_used_sid)); + sid = __this_cpu_inc_return(pcpu_last_used_sid); if (sid < NUM_TIDS) { - __get_cpu_var(pcpu_sids).entry[sid] = entry; + __this_cpu_write(pcpu_sids)entry[sid], entry); entry->val = sid; - entry->pentry = &__get_cpu_var(pcpu_sids).entry[sid]; + entry->pentry = this_cpu_ptr(&pcpu_sids.entry[sid]); ret = sid; } @@ -108,8 +108,8 @@ static inline int local_sid_setup_one(struct id *entry) static inline int local_sid_lookup(struct id *entry) { if (entry && entry->val != 0 && - __get_cpu_var(pcpu_sids).entry[entry->val] == entry && - entry->pentry == &__get_cpu_var(pcpu_sids).entry[entry->val]) + __this_cpu_read(pcpu_sids.entry[entry->val]) == entry && + entry->pentry == this_cpu_ptr(&pcpu_sids.entry[entry->val])) return entry->val; return -1; } @@ -117,8 +117,8 @@ static inline int local_sid_lookup(struct id *entry) /* Invalidate all id mappings on local core -- call with preempt disabled */ static inline void local_sid_destroy_all(void) { - __get_cpu_var(pcpu_last_used_sid) = 0; - memset(&__get_cpu_var(pcpu_sids), 0, sizeof(__get_cpu_var(pcpu_sids))); + __this_cpu_write(pcpu_last_used_sid, 0); + memset(this_cpu_ptr(&pcpu_sids), 0, sizeof(pcpu_sids)); } static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500) diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 2fdc8722e324..cda695de8aa7 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -144,9 +144,9 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu) mtspr(SPRN_GESR, vcpu->arch.shared->esr); if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || - __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] != vcpu) { + __this_cpu_read(last_vcpu_of_lpid[get_lpid(vcpu)]) != vcpu) { kvmppc_e500_tlbil_all(vcpu_e500); - __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] = vcpu; + __this_cpu_write(last_vcpu_of_lpid[get_lpid(vcpu)], vcpu); } } diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index ae4962a06476..d53288a08c37 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -629,7 +629,7 @@ static void native_flush_hash_range(unsigned long number, int local) unsigned long want_v; unsigned long flags; real_pte_t pte; - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); unsigned long psize = batch->psize; int ssize = batch->ssize; int i; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d5339a3b9945..f01027731e23 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1322,7 +1322,7 @@ void flush_hash_range(unsigned long number, int local) else { int i; struct ppc64_tlb_batch *batch = - &__get_cpu_var(ppc64_tlb_batch); + this_cpu_ptr(&ppc64_tlb_batch); for (i = 0; i < number; i++) flush_hash_page(batch->vpn[i], batch->pte[i], diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index 5e4ee2573903..ba47aaf33a4b 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -33,13 +33,13 @@ static inline int tlb1_next(void) ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY; - index = __get_cpu_var(next_tlbcam_idx); + index = this_cpu_read(next_tlbcam_idx); /* Just round-robin the entries and wrap when we hit the end */ if (unlikely(index == ncams - 1)) - __get_cpu_var(next_tlbcam_idx) = tlbcam_index; + __this_cpu_write(next_tlbcam_idx, tlbcam_index); else - __get_cpu_var(next_tlbcam_idx)++; + __this_cpu_inc(next_tlbcam_idx); return index; } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 7e70ae968e5f..8aa04f03fd31 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -462,7 +462,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) { struct hugepd_freelist **batchp; - batchp = &get_cpu_var(hugepd_freelist_cur); + batchp = this_cpu_ptr(&hugepd_freelist_cur); if (atomic_read(&tlb->mm->mm_users) < 2 || cpumask_equal(mm_cpumask(tlb->mm), diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index a6995d4e93d4..7c4f6690533a 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -339,7 +339,7 @@ static void power_pmu_bhrb_reset(void) static void power_pmu_bhrb_enable(struct perf_event *event) { - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); if (!ppmu->bhrb_nr) return; @@ -354,7 +354,7 @@ static void power_pmu_bhrb_enable(struct perf_event *event) static void power_pmu_bhrb_disable(struct perf_event *event) { - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); if (!ppmu->bhrb_nr) return; @@ -1144,7 +1144,7 @@ static void power_pmu_disable(struct pmu *pmu) if (!ppmu) return; local_irq_save(flags); - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); if (!cpuhw->disabled) { /* @@ -1211,7 +1211,7 @@ static void power_pmu_enable(struct pmu *pmu) return; local_irq_save(flags); - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); if (!cpuhw->disabled) goto out; @@ -1403,7 +1403,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags) * Add the event to the list (if there is room) * and check whether the total set is still feasible. */ - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); n0 = cpuhw->n_events; if (n0 >= ppmu->n_counter) goto out; @@ -1469,7 +1469,7 @@ static void power_pmu_del(struct perf_event *event, int ef_flags) power_pmu_read(event); - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); for (i = 0; i < cpuhw->n_events; ++i) { if (event == cpuhw->event[i]) { while (++i < cpuhw->n_events) { @@ -1575,7 +1575,7 @@ static void power_pmu_stop(struct perf_event *event, int ef_flags) */ static void power_pmu_start_txn(struct pmu *pmu) { - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); perf_pmu_disable(pmu); cpuhw->group_flag |= PERF_EVENT_TXN; @@ -1589,7 +1589,7 @@ static void power_pmu_start_txn(struct pmu *pmu) */ static void power_pmu_cancel_txn(struct pmu *pmu) { - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); cpuhw->group_flag &= ~PERF_EVENT_TXN; perf_pmu_enable(pmu); @@ -1607,7 +1607,7 @@ static int power_pmu_commit_txn(struct pmu *pmu) if (!ppmu) return -EAGAIN; - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); n = cpuhw->n_events; if (check_excludes(cpuhw->event, cpuhw->flags, 0, n)) return -EAGAIN; @@ -1964,7 +1964,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val, if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) { struct cpu_hw_events *cpuhw; - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); power_pmu_bhrb_read(cpuhw); data.br_stack = &cpuhw->bhrb_stack; } @@ -2037,7 +2037,7 @@ static bool pmc_overflow(unsigned long val) static void perf_event_interrupt(struct pt_regs *regs) { int i, j; - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); struct perf_event *event; unsigned long val[8]; int found, active; diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c index d35ae52c69dc..4acaea01fe03 100644 --- a/arch/powerpc/perf/core-fsl-emb.c +++ b/arch/powerpc/perf/core-fsl-emb.c @@ -210,7 +210,7 @@ static void fsl_emb_pmu_disable(struct pmu *pmu) unsigned long flags; local_irq_save(flags); - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); if (!cpuhw->disabled) { cpuhw->disabled = 1; @@ -249,7 +249,7 @@ static void fsl_emb_pmu_enable(struct pmu *pmu) unsigned long flags; local_irq_save(flags); - cpuhw = &__get_cpu_var(cpu_hw_events); + cpuhw = this_cpu_ptr(&cpu_hw_events); if (!cpuhw->disabled) goto out; @@ -653,7 +653,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val, static void perf_event_interrupt(struct pt_regs *regs) { int i; - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); struct perf_event *event; unsigned long val; int found = 0; diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 8a106b4172e0..4c11421847be 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -82,7 +82,7 @@ static void iic_unmask(struct irq_data *d) static void iic_eoi(struct irq_data *d) { - struct iic *iic = &__get_cpu_var(cpu_iic); + struct iic *iic = this_cpu_ptr(&cpu_iic); out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]); BUG_ON(iic->eoi_ptr < 0); } @@ -148,7 +148,7 @@ static unsigned int iic_get_irq(void) struct iic *iic; unsigned int virq; - iic = &__get_cpu_var(cpu_iic); + iic = this_cpu_ptr(&cpu_iic); *(unsigned long *) &pending = in_be64((u64 __iomem *) &iic->regs->pending_destr); if (!(pending.flags & CBE_IIC_IRQ_VALID)) @@ -163,7 +163,7 @@ static unsigned int iic_get_irq(void) void iic_setup_cpu(void) { - out_be64(&__get_cpu_var(cpu_iic).regs->prio, 0xff); + out_be64(this_cpu_ptr(&cpu_iic.regs->prio), 0xff); } u8 iic_get_target_id(int cpu) diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c index ae14c40b4b1c..e11273b2386d 100644 --- a/arch/powerpc/platforms/powernv/opal-tracepoints.c +++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c @@ -48,7 +48,7 @@ void __trace_opal_entry(unsigned long opcode, unsigned long *args) local_irq_save(flags); - depth = &__get_cpu_var(opal_trace_depth); + depth = this_cpu_ptr(&opal_trace_depth); if (*depth) goto out; @@ -69,7 +69,7 @@ void __trace_opal_exit(long opcode, unsigned long retval) local_irq_save(flags); - depth = &__get_cpu_var(opal_trace_depth); + depth = this_cpu_ptr(&opal_trace_depth); if (*depth) goto out; diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 5f3b23220b8e..a6c42f34303a 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -711,7 +711,7 @@ void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) static unsigned int ps3_get_irq(void) { - struct ps3_private *pd = &__get_cpu_var(ps3_private); + struct ps3_private *pd = this_cpu_ptr(&ps3_private); u64 x = (pd->bmp.status & pd->bmp.mask); unsigned int plug; diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index 1062f71f5a85..39049e4884fb 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -75,7 +75,7 @@ static atomic_t dtl_count; */ static void consume_dtle(struct dtl_entry *dtle, u64 index) { - struct dtl_ring *dtlr = &__get_cpu_var(dtl_rings); + struct dtl_ring *dtlr = this_cpu_ptr(&dtl_rings); struct dtl_entry *wp = dtlr->write_ptr; struct lppaca *vpa = local_paca->lppaca_ptr; diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 4575f0c9e521..f02ec3ab428c 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -110,7 +110,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long if (opcode > MAX_HCALL_OPCODE) return; - h = &__get_cpu_var(hcall_stats)[opcode / 4]; + h = this_cpu_ptr(&hcall_stats[opcode / 4]); h->tb_start = mftb(); h->purr_start = mfspr(SPRN_PURR); } @@ -123,7 +123,7 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long if (opcode > MAX_HCALL_OPCODE) return; - h = &__get_cpu_var(hcall_stats)[opcode / 4]; + h = this_cpu_ptr(&hcall_stats[opcode / 4]); h->num_calls++; h->tb_total += mftb() - h->tb_start; h->purr_total += mfspr(SPRN_PURR) - h->purr_start; diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index e32e00976a94..49bcf7c09c49 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -199,7 +199,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, local_irq_save(flags); /* to protect tcep and the page behind it */ - tcep = __get_cpu_var(tce_page); + tcep = __this_cpu_read(tce_page); /* This is safe to do since interrupts are off when we're called * from iommu_alloc{,_sg}() @@ -212,7 +212,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction, attrs); } - __get_cpu_var(tce_page) = tcep; + __this_cpu_write(tce_page, tcep); } rpn = __pa(uaddr) >> TCE_SHIFT; @@ -398,7 +398,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, long l, limit; local_irq_disable(); /* to protect tcep and the page behind it */ - tcep = __get_cpu_var(tce_page); + tcep = __this_cpu_read(tce_page); if (!tcep) { tcep = (__be64 *)__get_free_page(GFP_ATOMIC); @@ -406,7 +406,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, local_irq_enable(); return -ENOMEM; } - __get_cpu_var(tce_page) = tcep; + __this_cpu_write(tce_page, tcep); } proto_tce = TCE_PCI_READ | TCE_PCI_WRITE; diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 8c509d5397c6..87d8792f906c 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -505,7 +505,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) unsigned long vpn; unsigned long i, pix, rc; unsigned long flags = 0; - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); unsigned long param[9]; unsigned long hash, index, shift, hidx, slot; @@ -695,7 +695,7 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args) local_irq_save(flags); - depth = &__get_cpu_var(hcall_trace_depth); + depth = this_cpu_ptr(&hcall_trace_depth); if (*depth) goto out; @@ -720,7 +720,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval, local_irq_save(flags); - depth = &__get_cpu_var(hcall_trace_depth); + depth = this_cpu_ptr(&hcall_trace_depth); if (*depth) goto out; diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 5a4d0fc03b03..c3b2a7e81ddb 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -302,8 +302,8 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs) /* If it isn't an extended log we can use the per cpu 64bit buffer */ h = (struct rtas_error_log *)&savep[1]; if (!rtas_error_extended(h)) { - memcpy(&__get_cpu_var(mce_data_buf), h, sizeof(__u64)); - errhdr = (struct rtas_error_log *)&__get_cpu_var(mce_data_buf); + memcpy(this_cpu_ptr(&mce_data_buf), h, sizeof(__u64)); + errhdr = (struct rtas_error_log *)this_cpu_ptr(&mce_data_buf); } else { int len, error_log_length; diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index fe0cca477164..365249cd346b 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -155,7 +155,7 @@ int __init xics_smp_probe(void) void xics_teardown_cpu(void) { - struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr); /* * we have to reset the cppr index to 0 because we're -- GitLab From 9178ba294b6839eeff1a91bed95515d783f3ee6c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 13 Oct 2014 16:01:09 +0200 Subject: [PATCH 2432/9457] powerpc: Convert power off logic to pm_power_off The generic Linux framework to power off the machine is a function pointer called pm_power_off. The trick about this pointer is that device drivers can potentially implement it rather than board files. Today on powerpc we set pm_power_off to invoke our generic full machine power off logic which then calls ppc_md.power_off to invoke machine specific power off. However, when we want to add a power off GPIO via the "gpio-poweroff" driver, this card house falls apart. That driver only registers itself if pm_power_off is NULL to ensure it doesn't override board specific logic. However, since we always set pm_power_off to the generic power off logic (which will just not power off the machine if no ppc_md.power_off call is implemented), we can't implement power off via the generic GPIO power off driver. To fix this up, let's get rid of the ppc_md.power_off logic and just always use pm_power_off as was intended. Then individual drivers such as the GPIO power off driver can implement power off logic via that function pointer. With this patch set applied and a few patches on top of QEMU that implement a power off GPIO on the virt e500 machine, I can successfully turn off my virtual machine after halt. Signed-off-by: Alexander Graf [mpe: Squash into one patch and update changelog based on cover letter] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/machdep.h | 1 - arch/powerpc/kernel/setup-common.c | 6 +- arch/powerpc/platforms/44x/ppc476.c | 2 +- arch/powerpc/platforms/52xx/efika.c | 3 +- .../powerpc/platforms/83xx/mcu_mpc8349emitx.c | 8 +-- arch/powerpc/platforms/85xx/corenet_generic.c | 2 +- arch/powerpc/platforms/85xx/sgy_cts1000.c | 4 +- arch/powerpc/platforms/cell/celleb_setup.c | 4 +- arch/powerpc/platforms/cell/qpace_setup.c | 2 +- arch/powerpc/platforms/cell/setup.c | 2 +- arch/powerpc/platforms/chrp/setup.c | 3 +- arch/powerpc/platforms/embedded6xx/gamecube.c | 3 +- .../platforms/embedded6xx/linkstation.c | 4 +- arch/powerpc/platforms/embedded6xx/wii.c | 3 +- arch/powerpc/platforms/maple/setup.c | 4 +- arch/powerpc/platforms/powermac/setup.c | 3 +- arch/powerpc/platforms/powernv/setup.c | 4 +- arch/powerpc/platforms/ps3/setup.c | 2 +- arch/powerpc/platforms/pseries/setup.c | 59 ++++++++++--------- arch/powerpc/sysdev/fsl_soc.c | 2 +- arch/powerpc/xmon/xmon.c | 3 +- 21 files changed, 66 insertions(+), 58 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 307347f8ddbd..f15f15c92544 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -142,7 +142,6 @@ struct machdep_calls { #endif void (*restart)(char *cmd); - void (*power_off)(void); void (*halt)(void); void (*panic)(char *str); void (*cpu_die)(void); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 1362cd62b3fa..44c8d03558ac 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -139,8 +139,8 @@ void machine_restart(char *cmd) void machine_power_off(void) { machine_shutdown(); - if (ppc_md.power_off) - ppc_md.power_off(); + if (pm_power_off) + pm_power_off(); #ifdef CONFIG_SMP smp_send_stop(); #endif @@ -151,7 +151,7 @@ void machine_power_off(void) /* Used by the G5 thermal driver */ EXPORT_SYMBOL_GPL(machine_power_off); -void (*pm_power_off)(void) = machine_power_off; +void (*pm_power_off)(void); EXPORT_SYMBOL_GPL(pm_power_off); void machine_halt(void) diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c index 58db9d083969..c11ce6516c8f 100644 --- a/arch/powerpc/platforms/44x/ppc476.c +++ b/arch/powerpc/platforms/44x/ppc476.c @@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client, { avr_i2c_client = client; ppc_md.restart = avr_reset_system; - ppc_md.power_off = avr_power_off_system; + pm_power_off = avr_power_off_system; return 0; } diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 3feffde9128d..6af651e69129 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -212,6 +212,8 @@ static int __init efika_probe(void) DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + pm_power_off = rtas_power_off; + return 1; } @@ -225,7 +227,6 @@ define_machine(efika) .init_IRQ = mpc52xx_init_irq, .get_irq = mpc52xx_get_irq, .restart = rtas_restart, - .power_off = rtas_power_off, .halt = rtas_halt, .set_rtc_time = rtas_set_rtc_time, .get_rtc_time = rtas_get_rtc_time, diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 463fa91ee5b6..15e8021ddef9 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -167,10 +167,10 @@ static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id) if (ret) goto err; - /* XXX: this is potentially racy, but there is no lock for ppc_md */ - if (!ppc_md.power_off) { + /* XXX: this is potentially racy, but there is no lock for pm_power_off */ + if (!pm_power_off) { glob_mcu = mcu; - ppc_md.power_off = mcu_power_off; + pm_power_off = mcu_power_off; dev_info(&client->dev, "will provide power-off service\n"); } @@ -197,7 +197,7 @@ static int mcu_remove(struct i2c_client *client) device_remove_file(&client->dev, &dev_attr_status); if (glob_mcu == mcu) { - ppc_md.power_off = NULL; + pm_power_off = NULL; glob_mcu = NULL; } diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index e56b89a792ed..1f309ccb096e 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -170,7 +170,7 @@ static int __init corenet_generic_probe(void) ppc_md.get_irq = ehv_pic_get_irq; ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; + pm_power_off = fsl_hv_halt; ppc_md.halt = fsl_hv_halt; #ifdef CONFIG_SMP /* diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c index 8162b0412117..e149c9ec26ae 100644 --- a/arch/powerpc/platforms/85xx/sgy_cts1000.c +++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c @@ -120,7 +120,7 @@ static int gpio_halt_probe(struct platform_device *pdev) /* Register our halt function */ ppc_md.halt = gpio_halt_cb; - ppc_md.power_off = gpio_halt_cb; + pm_power_off = gpio_halt_cb; printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" " irq).\n", gpio, trigger, irq); @@ -137,7 +137,7 @@ static int gpio_halt_remove(struct platform_device *pdev) free_irq(irq, halt_node); ppc_md.halt = NULL; - ppc_md.power_off = NULL; + pm_power_off = NULL; gpio_free(gpio); diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c index 34e8ce2976aa..90be8ec51686 100644 --- a/arch/powerpc/platforms/cell/celleb_setup.c +++ b/arch/powerpc/platforms/cell/celleb_setup.c @@ -142,6 +142,7 @@ static int __init celleb_probe_beat(void) powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS | FW_FEATURE_BEAT | FW_FEATURE_LPAR; hpte_init_beat_v3(); + pm_power_off = beat_power_off; return 1; } @@ -190,6 +191,7 @@ static int __init celleb_probe_native(void) powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS; hpte_init_native(); + pm_power_off = rtas_power_off; return 1; } @@ -204,7 +206,6 @@ define_machine(celleb_beat) { .setup_arch = celleb_setup_arch_beat, .show_cpuinfo = celleb_show_cpuinfo, .restart = beat_restart, - .power_off = beat_power_off, .halt = beat_halt, .get_rtc_time = beat_get_rtc_time, .set_rtc_time = beat_set_rtc_time, @@ -230,7 +231,6 @@ define_machine(celleb_native) { .setup_arch = celleb_setup_arch_native, .show_cpuinfo = celleb_show_cpuinfo, .restart = rtas_restart, - .power_off = rtas_power_off, .halt = rtas_halt, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c index 6e3409d590ac..d328140dc6f5 100644 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ b/arch/powerpc/platforms/cell/qpace_setup.c @@ -127,6 +127,7 @@ static int __init qpace_probe(void) return 0; hpte_init_native(); + pm_power_off = rtas_power_off; return 1; } @@ -137,7 +138,6 @@ define_machine(qpace) { .setup_arch = qpace_setup_arch, .show_cpuinfo = qpace_show_cpuinfo, .restart = rtas_restart, - .power_off = rtas_power_off, .halt = rtas_halt, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 6ae25fb62015..d62aa982d530 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -259,6 +259,7 @@ static int __init cell_probe(void) return 0; hpte_init_native(); + pm_power_off = rtas_power_off; return 1; } @@ -269,7 +270,6 @@ define_machine(cell) { .setup_arch = cell_setup_arch, .show_cpuinfo = cell_show_cpuinfo, .restart = rtas_restart, - .power_off = rtas_power_off, .halt = rtas_halt, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 5b77b1919fd2..860a59eb8ea2 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -585,6 +585,8 @@ static int __init chrp_probe(void) DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + pm_power_off = rtas_power_off; + return 1; } @@ -597,7 +599,6 @@ define_machine(chrp) { .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, .restart = rtas_restart, - .power_off = rtas_power_off, .halt = rtas_halt, .time_init = chrp_time_init, .set_rtc_time = chrp_set_rtc_time, diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c index bd4ba5d7d568..fe0ed6ee285e 100644 --- a/arch/powerpc/platforms/embedded6xx/gamecube.c +++ b/arch/powerpc/platforms/embedded6xx/gamecube.c @@ -67,6 +67,8 @@ static int __init gamecube_probe(void) if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube")) return 0; + pm_power_off = gamecube_power_off; + return 1; } @@ -80,7 +82,6 @@ define_machine(gamecube) { .probe = gamecube_probe, .init_early = gamecube_init_early, .restart = gamecube_restart, - .power_off = gamecube_power_off, .halt = gamecube_halt, .init_IRQ = flipper_pic_probe, .get_irq = flipper_pic_get_irq, diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index 168e1d80b2e5..540eeb58d3f0 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -147,6 +147,9 @@ static int __init linkstation_probe(void) if (!of_flat_dt_is_compatible(root, "linkstation")) return 0; + + pm_power_off = linkstation_power_off; + return 1; } @@ -158,7 +161,6 @@ define_machine(linkstation){ .show_cpuinfo = linkstation_show_cpuinfo, .get_irq = mpic_get_irq, .restart = linkstation_restart, - .power_off = linkstation_power_off, .halt = linkstation_halt, .calibrate_decr = generic_calibrate_decr, }; diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index 388e29bab8f6..352592d3e44e 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -211,6 +211,8 @@ static int __init wii_probe(void) if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii")) return 0; + pm_power_off = wii_power_off; + return 1; } @@ -226,7 +228,6 @@ define_machine(wii) { .init_early = wii_init_early, .setup_arch = wii_setup_arch, .restart = wii_restart, - .power_off = wii_power_off, .halt = wii_halt, .init_IRQ = wii_pic_probe, .get_irq = flipper_pic_get_irq, diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index cb1b0b35a0c6..56b85cd61aaf 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -169,7 +169,7 @@ static void __init maple_use_rtas_reboot_and_halt_if_present(void) if (rtas_service_present("system-reboot") && rtas_service_present("power-off")) { ppc_md.restart = rtas_restart; - ppc_md.power_off = rtas_power_off; + pm_power_off = rtas_power_off; ppc_md.halt = rtas_halt; } } @@ -312,6 +312,7 @@ static int __init maple_probe(void) alloc_dart_table(); hpte_init_native(); + pm_power_off = maple_power_off; return 1; } @@ -325,7 +326,6 @@ define_machine(maple) { .pci_irq_fixup = maple_pci_irq_fixup, .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, .restart = maple_restart, - .power_off = maple_power_off, .halt = maple_halt, .get_boot_time = maple_get_boot_time, .set_rtc_time = maple_set_rtc_time, diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index b127a29ac526..713d36d45d1d 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -632,6 +632,8 @@ static int __init pmac_probe(void) smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL); #endif /* CONFIG_PMAC_SMU */ + pm_power_off = pmac_power_off; + return 1; } @@ -663,7 +665,6 @@ define_machine(powermac) { .get_irq = NULL, /* changed later */ .pci_irq_fixup = pmac_pci_irq_fixup, .restart = pmac_restart, - .power_off = pmac_power_off, .halt = pmac_halt, .time_init = pmac_time_init, .get_boot_time = pmac_get_boot_time, diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 3f9546d8a51f..941831d67cb2 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -268,7 +268,7 @@ static void __init pnv_setup_machdep_opal(void) ppc_md.get_rtc_time = opal_get_rtc_time; ppc_md.set_rtc_time = opal_set_rtc_time; ppc_md.restart = pnv_restart; - ppc_md.power_off = pnv_power_off; + pm_power_off = pnv_power_off; ppc_md.halt = pnv_halt; ppc_md.machine_check_exception = opal_machine_check; ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery; @@ -285,7 +285,7 @@ static void __init pnv_setup_machdep_rtas(void) ppc_md.set_rtc_time = rtas_set_rtc_time; } ppc_md.restart = rtas_restart; - ppc_md.power_off = rtas_power_off; + pm_power_off = rtas_power_off; ppc_md.halt = rtas_halt; } #endif /* CONFIG_PPC_POWERNV_RTAS */ diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 3f509f86432c..009a2004b876 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -248,6 +248,7 @@ static int __init ps3_probe(void) ps3_mm_init(); ps3_mm_vas_create(&htab_size); ps3_hpte_init(htab_size); + pm_power_off = ps3_power_off; DBG(" <- %s:%d\n", __func__, __LINE__); return 1; @@ -278,7 +279,6 @@ define_machine(ps3) { .calibrate_decr = ps3_calibrate_decr, .progress = ps3_progress, .restart = ps3_restart, - .power_off = ps3_power_off, .halt = ps3_halt, #if defined(CONFIG_KEXEC) .kexec_cpu_down = ps3_kexec_cpu_down, diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 125c589eeef5..db0fc0c07568 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -659,6 +659,34 @@ static void __init pSeries_init_early(void) pr_debug(" <- pSeries_init_early()\n"); } +/** + * pseries_power_off - tell firmware about how to power off the system. + * + * This function calls either the power-off rtas token in normal cases + * or the ibm,power-off-ups token (if present & requested) in case of + * a power failure. If power-off token is used, power on will only be + * possible with power button press. If ibm,power-off-ups token is used + * it will allow auto poweron after power is restored. + */ +static void pseries_power_off(void) +{ + int rc; + int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); + + if (rtas_flash_term_hook) + rtas_flash_term_hook(SYS_POWER_OFF); + + if (rtas_poweron_auto == 0 || + rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) { + rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1); + printk(KERN_INFO "RTAS power-off returned %d\n", rc); + } else { + rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL); + printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc); + } + for (;;); +} + /* * Called very early, MMU is off, device-tree isn't unflattened */ @@ -741,6 +769,8 @@ static int __init pSeries_probe(void) else hpte_init_native(); + pm_power_off = pseries_power_off; + pr_debug("Machine is%s LPAR !\n", (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); @@ -754,34 +784,6 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) return PCI_PROBE_NORMAL; } -/** - * pSeries_power_off - tell firmware about how to power off the system. - * - * This function calls either the power-off rtas token in normal cases - * or the ibm,power-off-ups token (if present & requested) in case of - * a power failure. If power-off token is used, power on will only be - * possible with power button press. If ibm,power-off-ups token is used - * it will allow auto poweron after power is restored. - */ -static void pSeries_power_off(void) -{ - int rc; - int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); - - if (rtas_flash_term_hook) - rtas_flash_term_hook(SYS_POWER_OFF); - - if (rtas_poweron_auto == 0 || - rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) { - rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1); - printk(KERN_INFO "RTAS power-off returned %d\n", rc); - } else { - rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL); - printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc); - } - for (;;); -} - #ifndef CONFIG_PCI void pSeries_final_fixup(void) { } #endif @@ -796,7 +798,6 @@ define_machine(pseries) { .pcibios_fixup = pSeries_final_fixup, .pci_probe_mode = pSeries_pci_probe_mode, .restart = rtas_restart, - .power_off = pSeries_power_off, .halt = rtas_halt, .panic = rtas_os_term, .get_boot_time = rtas_get_boot_time, diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ffd1169ebaab..1e04568da3b9 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -238,7 +238,7 @@ void fsl_hv_restart(char *cmd) /* * Halt the current partition * - * This function should be assigned to the ppc_md.power_off and ppc_md.halt + * This function should be assigned to the pm_power_off and ppc_md.halt * function pointers, to shut down the partition when we're running under * the Freescale hypervisor. */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index b988b5addf86..506d25681fe3 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -981,7 +981,8 @@ static void bootcmds(void) else if (cmd == 'h') ppc_md.halt(); else if (cmd == 'p') - ppc_md.power_off(); + if (pm_power_off) + pm_power_off(); } static int cpu_cmd(void) -- GitLab From f293a5e33e084ef84b802e3002e5fe3eef086171 Mon Sep 17 00:00:00 2001 From: dingzhi Date: Thu, 30 Oct 2014 09:39:36 +0100 Subject: [PATCH 2433/9457] xfrm: add XFRMA_REPLAY_VAL attribute to SA messages After this commit, the attribute XFRMA_REPLAY_VAL is added when no ESN replay value is defined. Thus sequence number values are always notified to userspace. Signed-off-by: dingzhi Signed-off-by: Adrien Mazarguil Signed-off-by: Nicolas Dichtel Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e812e988c111..8128594ab379 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -824,13 +824,15 @@ static int copy_to_user_state_extra(struct xfrm_state *x, ret = xfrm_mark_put(skb, &x->mark); if (ret) goto out; - if (x->replay_esn) { + if (x->replay_esn) ret = nla_put(skb, XFRMA_REPLAY_ESN_VAL, xfrm_replay_state_esn_len(x->replay_esn), x->replay_esn); - if (ret) - goto out; - } + else + ret = nla_put(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), + &x->replay); + if (ret) + goto out; if (x->security) ret = copy_sec_ctx(x->security, skb); out: @@ -2569,6 +2571,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) l += nla_total_size(sizeof(x->tfcpad)); if (x->replay_esn) l += nla_total_size(xfrm_replay_state_esn_len(x->replay_esn)); + else + l += nla_total_size(sizeof(struct xfrm_replay_state)); if (x->security) l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) + x->security->ctx_len); -- GitLab From 43d6bc46e2d342204693d24ce1c607305d93d8fb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 20:52:23 +0100 Subject: [PATCH 2434/9457] Bluetooth: Introduce HCI_QUIRK_STRICT_DUPLICATE_FILTER Some vendors decide to use a strict duplicate filter policy that only filters on Bluetooth device addresses. This means that when the RSSI changes, these devices are not reported again. During discovery it is useful to actually get the RSSI updates. Since this is specific to each controller, add a new quirk setting that allows drivers to tell the core what kind of filtering policy the controller uses. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ecfa306e1375..2e08f5a89463 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -129,6 +129,15 @@ enum { * during the hdev->setup vendor callback. */ HCI_QUIRK_INVALID_BDADDR, + + /* When this quirk is set, the duplicate filtering during + * scanning is based on Bluetooth devices addresses. To allow + * RSSI based updates, restart scanning if needed. + * + * This quirk can be set before hci_register_dev is called or + * during the hdev->setup vendor callback. + */ + HCI_QUIRK_STRICT_DUPLICATE_FILTER, }; /* HCI device flags */ -- GitLab From 27c3fbe00b4beb373f1460b745164d699de94247 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 20:52:24 +0100 Subject: [PATCH 2435/9457] Bluetooth: Set HCI_QUIRK_STRICT_DUPLICATE_FILTER for Broadcom devices The Bluetooth controllers from Broadcom use a strict scanning filter policy that filters based on Bluetooth device addresses and not on RSSI. So tell the core about this. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/btusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 03ce301fca92..c85426d6e33d 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2035,6 +2035,7 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_BCM_PATCHRAM) { hdev->setup = btusb_setup_bcm_patchram; hdev->set_bdaddr = btusb_set_bdaddr_bcm; + set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); } if (id->driver_info & BTUSB_INTEL) { -- GitLab From 40f4938aa6bfe2d792c0665c16d9dd15a5c1b119 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Nov 2014 21:46:52 +0100 Subject: [PATCH 2436/9457] Bluetooth: Consolidate whitelist debugfs entry into device_list The debufs entry for the BR/EDR whitelist is confusing since there is a controller debugfs entry with the name white_list and both are two different things. With the BR/EDR whitelist, the actual interface in use is the device list and thus just include all values from the internal BR/EDR whitelist in the device_list debugfs entry. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a12e018ee21c..6c162c8809cf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -200,31 +200,6 @@ static const struct file_operations blacklist_fops = { .release = single_release, }; -static int whitelist_show(struct seq_file *f, void *p) -{ - struct hci_dev *hdev = f->private; - struct bdaddr_list *b; - - hci_dev_lock(hdev); - list_for_each_entry(b, &hdev->whitelist, list) - seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); - hci_dev_unlock(hdev); - - return 0; -} - -static int whitelist_open(struct inode *inode, struct file *file) -{ - return single_open(file, whitelist_show, inode->i_private); -} - -static const struct file_operations whitelist_fops = { - .open = whitelist_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int uuids_show(struct seq_file *f, void *p) { struct hci_dev *hdev = f->private; @@ -1030,10 +1005,13 @@ static int device_list_show(struct seq_file *f, void *ptr) { struct hci_dev *hdev = f->private; struct hci_conn_params *p; + struct bdaddr_list *b; hci_dev_lock(hdev); + list_for_each_entry(b, &hdev->whitelist, list) + seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); list_for_each_entry(p, &hdev->le_conn_params, list) { - seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type, + seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type, p->auto_connect); } hci_dev_unlock(hdev); @@ -1815,10 +1793,10 @@ static int __hci_init(struct hci_dev *hdev) &hdev->manufacturer); debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); + debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, + &device_list_fops); debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, &blacklist_fops); - debugfs_create_file("whitelist", 0444, hdev->debugfs, hdev, - &whitelist_fops); debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, @@ -1897,8 +1875,6 @@ static int __hci_init(struct hci_dev *hdev) hdev, &adv_min_interval_fops); debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, hdev, &adv_max_interval_fops); - debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, - &device_list_fops); debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs, &hdev->discov_interleaved_timeout); -- GitLab From 2cbd3f5ccd43ba823e183f98a798d4b23cfb12b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 3 Nov 2014 05:16:07 +0100 Subject: [PATCH 2437/9457] Bluetooth: btusb: Add internal callback for USB bulk rx data Some vendors require special handling of the rx data from the USB bulk endpoints. For that case provide an internal callback that can overwrite it with a custom receive function. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/btusb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c85426d6e33d..cd634f3b76d3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -299,6 +299,8 @@ struct btusb_data { unsigned int sco_num; int isoc_altsetting; int suspend_count; + + int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); }; static inline void btusb_free_frags(struct btusb_data *data) @@ -590,7 +592,7 @@ static void btusb_bulk_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; - if (btusb_recv_bulk(data, urb->transfer_buffer, + if (data->recv_bulk(data, urb->transfer_buffer, urb->actual_length) < 0) { BT_ERR("%s corrupted ACL packet", hdev->name); hdev->stat.err_rx++; @@ -2012,6 +2014,8 @@ static int btusb_probe(struct usb_interface *intf, init_usb_anchor(&data->isoc_anchor); spin_lock_init(&data->rxlock); + data->recv_bulk = btusb_recv_bulk; + hdev = hci_alloc_dev(); if (!hdev) return -ENOMEM; -- GitLab From 845472e8d50c898c73b4f69f4edad5249b13d6a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 3 Nov 2014 05:16:08 +0100 Subject: [PATCH 2438/9457] Bluetooth: Add hci_conn_lookup_type() helper function Some drivers require knowledge of what connection handle is assigned to what connection link type (ACL or SCO/eSCO). Instead of having each driver implement connection tracking, provide a simple helper function for lookup of the link type. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci.h | 1 + include/net/bluetooth/hci_core.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 2e08f5a89463..d5f85d7746bc 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -274,6 +274,7 @@ enum { /* Low Energy links do not have defined link type. Use invented one */ #define LE_LINK 0x80 #define AMP_LINK 0x81 +#define INVALID_LINK 0xff /* LMP features */ #define LMP_3SLOT 0x01 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 27ddb905b351..4e39a5adfcab 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -646,6 +646,26 @@ static inline unsigned int hci_conn_count(struct hci_dev *hdev) return c->acl_num + c->amp_num + c->sco_num + c->le_num; } +static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + struct hci_conn *c; + __u8 type = INVALID_LINK; + + rcu_read_lock(); + + list_for_each_entry_rcu(c, &h->list, list) { + if (c->handle == handle) { + type = c->type; + break; + } + } + + rcu_read_unlock(); + + return type; +} + static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, __u16 handle) { -- GitLab From 811c37078042980b5b9ed6845303a3cc9e6d48e3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 29 Oct 2014 09:07:32 +0100 Subject: [PATCH 2439/9457] USB: kobil_sct: replace unnecessary atomic allocation Use GFP_KERNEL instead of GFP_ATOMIC for allocation in open(), which may sleep. Signed-off-by: Johan Hovold --- drivers/usb/serial/kobil_sct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 078f9ed419c8..a65042cc31a7 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -244,7 +244,7 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { /* start reading (Adapter B 'cause PNP string) */ - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); dev_dbg(dev, "%s - Send read URB returns: %i\n", __func__, result); } -- GitLab From 1dbd11be69927d2d119e900f5487a01ad09a26b8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 29 Oct 2014 09:07:33 +0100 Subject: [PATCH 2440/9457] USB: mos7720: replace unnecessary atomic allocations Use GFP_KERNEL instead of GFP_ATOMIC for allocations in set_termios and port-setting helper which both may and do sleep. Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7720.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index dfd728a263d2..312b0fee8d54 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1657,7 +1657,7 @@ static void change_port_settings(struct tty_struct *tty, write_mos_reg(serial, port_number, IER, 0x0c); if (port->read_urb->status != -EINPROGRESS) { - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); + status = usb_submit_urb(port->read_urb, GFP_KERNEL); if (status) dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status); } @@ -1702,7 +1702,7 @@ static void mos7720_set_termios(struct tty_struct *tty, change_port_settings(tty, mos7720_port, old_termios); if (port->read_urb->status != -EINPROGRESS) { - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); + status = usb_submit_urb(port->read_urb, GFP_KERNEL); if (status) dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status); } -- GitLab From 9d3801903851a2be51f0b2d85f25f952a7da9969 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 29 Oct 2014 09:07:34 +0100 Subject: [PATCH 2441/9457] USB: mos7840: replace unnecessary atomic allocations Use GFP_KERNEL instead of GFP_ATOMIC for allocations in set_termios and port-setting helper which both may and do sleep. Signed-off-by: Johan Hovold --- drivers/usb/serial/mos7840.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 3d88eefdf1d1..220b4be89641 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1904,7 +1904,7 @@ static void mos7840_change_port_settings(struct tty_struct *tty, if (mos7840_port->read_urb_busy == false) { mos7840_port->read_urb_busy = true; - status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); + status = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); if (status) { dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status); @@ -1968,7 +1968,7 @@ static void mos7840_set_termios(struct tty_struct *tty, if (mos7840_port->read_urb_busy == false) { mos7840_port->read_urb_busy = true; - status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); + status = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); if (status) { dev_dbg(&port->dev, "usb_submit_urb(read bulk) failed, status = %d\n", status); -- GitLab From 1790ed0c65c114b6d262963bb054526697728815 Mon Sep 17 00:00:00 2001 From: Akeem G Abodunrin Date: Fri, 17 Oct 2014 03:14:41 +0000 Subject: [PATCH 2442/9457] i40e: Add condition to enter fdir flush and reinit When FD_SB/ATR are not enabled, do not allow flow director flush and reinit. Change-ID: Iafe261c1862992981615815551abd1ed9fada0a8 Signed-off-by: Akeem G Abodunrin Signed-off-by: Patrick Lu Tested-by: Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 834c9ffc6267..0eccd8222727 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5211,6 +5211,9 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) int flush_wait_retry = 50; int reg; + if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) + return; + if (time_after(jiffies, pf->fd_flush_timestamp + (I40E_MIN_FD_FLUSH_INTERVAL * HZ))) { set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); @@ -5272,6 +5275,9 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf) if (test_bit(__I40E_DOWN, &pf->state)) return; + if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) + return; + if ((pf->fd_add_err >= I40E_MAX_FD_PROGRAM_ERROR) && (i40e_get_current_atr_cnt(pf) >= pf->fd_atr_cnt) && (i40e_get_current_atr_cnt(pf) > pf->fdir_pf_filter_count)) -- GitLab From 7bdd6f74876e1bf4fc9849fe872000ecc944e71d Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 17 Oct 2014 03:14:42 +0000 Subject: [PATCH 2443/9457] i40evf: properly handle multiple AQ messages When we receive an admin queue message, the msg_size field in the event struct gets overwritten. Because of this, we need to reinit the field each time we go through the loop. Without this we may receive truncated messages due to the firmware thinking we have insufficient buffer size. Change-ID: I21dcca5114d91365d731169965ce3ffec0e4a190 Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index dabe6a4220c6..b2f01eb2f9e5 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1647,10 +1647,8 @@ static void i40evf_adminq_task(struct work_struct *work) v_msg->v_retval, event.msg_buf, event.msg_size); if (pending != 0) { - dev_info(&adapter->pdev->dev, - "%s: ARQ: Pending events %d\n", - __func__, pending); memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); + event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; } } while (pending); -- GitLab From 320684cd53e44b3ac856024c2de02bc2b882096a Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 17 Oct 2014 03:14:43 +0000 Subject: [PATCH 2444/9457] i40e: fix link checking logic If the interface is closed, but VFs exist, current code will spam all the VFs with link messages every second. This is because the link event code was looking at netif_carrier_ok() without checking to see if the interface was actually open. Refactor the logic to only check the carrier state if the interface is actually open. This allows link changes to be reported correctly without spamming the VFs. Change-ID: If136e79bb3820d21ea4e39e332e8a9604efc2b2a Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0eccd8222727..f95c04a906dd 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5358,6 +5358,7 @@ static void i40e_veb_link_event(struct i40e_veb *veb, bool link_up) static void i40e_link_event(struct i40e_pf *pf) { bool new_link, old_link; + struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; /* set this to force the get_link_status call to refresh state */ pf->hw.phy.get_link_info = true; @@ -5366,10 +5367,12 @@ static void i40e_link_event(struct i40e_pf *pf) new_link = i40e_get_link_status(&pf->hw); if (new_link == old_link && - new_link == netif_carrier_ok(pf->vsi[pf->lan_vsi]->netdev)) + (test_bit(__I40E_DOWN, &vsi->state) || + new_link == netif_carrier_ok(vsi->netdev))) return; - if (!test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state)) - i40e_print_link_message(pf->vsi[pf->lan_vsi], new_link); + + if (!test_bit(__I40E_DOWN, &vsi->state)) + i40e_print_link_message(vsi, new_link); /* Notify the base of the switch tree connected to * the link. Floating VEBs are not notified. @@ -5377,7 +5380,7 @@ static void i40e_link_event(struct i40e_pf *pf) if (pf->lan_veb != I40E_NO_VEB && pf->veb[pf->lan_veb]) i40e_veb_link_event(pf->veb[pf->lan_veb], new_link); else - i40e_vsi_link_event(pf->vsi[pf->lan_vsi], new_link); + i40e_vsi_link_event(vsi, new_link); if (pf->vf) i40e_vc_notify_link_state(pf); -- GitLab From 1ac1e7643ca68d86d3e1432e974294bf4038cb44 Mon Sep 17 00:00:00 2001 From: Paul M Stillwell Jr Date: Fri, 17 Oct 2014 03:14:44 +0000 Subject: [PATCH 2445/9457] i40evf: Add support for 10G base T parts Add 10G-Base-T support in i40evf. Change-ID: I98a1c3138d7d6572fe7903a7c1c4692cae3260d5 Signed-off-by: Paul M Stillwell Jr Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40e_common.c | 1 + drivers/net/ethernet/intel/i40evf/i40e_type.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c index 952560551964..28c40c57d4f5 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_common.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c @@ -50,6 +50,7 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_QSFP_A: case I40E_DEV_ID_QSFP_B: case I40E_DEV_ID_QSFP_C: + case I40E_DEV_ID_10G_BASE_T: hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_VF: diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h index 15376436cead..8fe34fc5c469 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_type.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h @@ -43,6 +43,7 @@ #define I40E_DEV_ID_QSFP_A 0x1583 #define I40E_DEV_ID_QSFP_B 0x1584 #define I40E_DEV_ID_QSFP_C 0x1585 +#define I40E_DEV_ID_10G_BASE_T 0x1586 #define I40E_DEV_ID_VF 0x154C #define I40E_DEV_ID_VF_HV 0x1571 -- GitLab From a282babcfd922f27e59b7ce7d046a310123a8220 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Oct 2014 03:14:46 +0000 Subject: [PATCH 2446/9457] i40e: avoid disable of interrupt when changing ITR The call to irq_dynamic_disable was turning off the interrupt completely when trying to set ITR to 0 (for lowest moderation). Just remove the call as setting the values to 0 later in this function will suffice. Change-ID: I47caf1ecbe65653cf63ec833db93094cd83fd84d Signed-off-by: Jesse Brandeburg Signed-off-by: Patrick Lu Tested-By: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 12adc08c54dc..b6e745f277cc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1574,7 +1574,6 @@ static int i40e_set_coalesce(struct net_device *netdev, vsi->rx_itr_setting = ec->rx_coalesce_usecs; } else if (ec->rx_coalesce_usecs == 0) { vsi->rx_itr_setting = ec->rx_coalesce_usecs; - i40e_irq_dynamic_disable(vsi, vector); if (ec->use_adaptive_rx_coalesce) netif_info(pf, drv, netdev, "Rx-secs=0, need to disable adaptive-Rx for a complete disable\n"); @@ -1589,7 +1588,6 @@ static int i40e_set_coalesce(struct net_device *netdev, vsi->tx_itr_setting = ec->tx_coalesce_usecs; } else if (ec->tx_coalesce_usecs == 0) { vsi->tx_itr_setting = ec->tx_coalesce_usecs; - i40e_irq_dynamic_disable(vsi, vector); if (ec->use_adaptive_tx_coalesce) netif_info(pf, drv, netdev, "Tx-secs=0, need to disable adaptive-Tx for a complete disable\n"); -- GitLab From 637bc2079678e08476d884f02a5d5d3208b5c018 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 03:46:05 -0300 Subject: [PATCH 2447/9457] [media] cx88: remove fmt from the buffer struct This is a duplicate of dev->fmt and can be removed. As a consequence a lot of tests that check if the format has changed midstream can be removed as well: the format cannot change midstream, so this is a bogus check. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-mpeg.c | 6 +- drivers/media/pci/cx88/cx88-video.c | 116 +++++++++++----------------- drivers/media/pci/cx88/cx88.h | 1 - 3 files changed, 46 insertions(+), 77 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 74b7b8614c23..2803b6f17646 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -229,17 +229,13 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, dprintk(1,"[%p/%d] restart_queue - first active\n", buf,buf->vb.i); - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { + } else { list_move_tail(&buf->vb.queue, &q->active); buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(1,"[%p/%d] restart_queue - move to active\n", buf,buf->vb.i); - } else { - return 0; } prev = buf; } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index ce27e6d4f16e..095542316917 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -420,7 +420,7 @@ static int start_video_dma(struct cx8800_dev *dev, cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], buf->bpl, buf->risc.dma); cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field); - cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); + cx_write(MO_COLOR_CTRL, dev->fmt->cxformat | ColorFormatGamma); /* reset counter */ cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET); @@ -497,17 +497,13 @@ static int restart_video_queue(struct cx8800_dev *dev, dprintk(2,"[%p/%d] restart_queue - first active\n", buf,buf->vb.i); - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { + } else { list_move_tail(&buf->vb.queue, &q->active); buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] restart_queue - move to active\n", buf,buf->vb.i); - } else { - return 0; } prev = buf; } @@ -538,7 +534,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, struct cx88_core *core = dev->core; struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - int rc, init_buffer = 0; + int rc; BUG_ON(NULL == dev->fmt); if (dev->width < 48 || dev->width > norm_maxw(core->tvnorm) || @@ -548,59 +544,47 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; - if (buf->fmt != dev->fmt || - buf->vb.width != dev->width || - buf->vb.height != dev->height || - buf->vb.field != field) { - buf->fmt = dev->fmt; - buf->vb.width = dev->width; - buf->vb.height = dev->height; - buf->vb.field = field; - init_buffer = 1; - } - + buf->vb.width = dev->width; + buf->vb.height = dev->height; + buf->vb.field = field; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - init_buffer = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) goto fail; } - if (init_buffer) { - buf->bpl = buf->vb.width * buf->fmt->depth >> 3; - switch (buf->vb.field) { - case V4L2_FIELD_TOP: - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, UNSET, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_BOTTOM: - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, UNSET, 0, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_INTERLACED: - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, buf->bpl, - buf->bpl, buf->bpl, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_TB: - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->bpl * (buf->vb.height >> 1), - buf->bpl, 0, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_BT: - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - buf->bpl * (buf->vb.height >> 1), 0, - buf->bpl, 0, - buf->vb.height >> 1); - break; - default: - BUG(); - } + buf->bpl = buf->vb.width * dev->fmt->depth >> 3; + switch (buf->vb.field) { + case V4L2_FIELD_TOP: + cx88_risc_buffer(dev->pci, &buf->risc, + dma->sglist, 0, UNSET, + buf->bpl, 0, buf->vb.height); + break; + case V4L2_FIELD_BOTTOM: + cx88_risc_buffer(dev->pci, &buf->risc, + dma->sglist, UNSET, 0, + buf->bpl, 0, buf->vb.height); + break; + case V4L2_FIELD_SEQ_TB: + cx88_risc_buffer(dev->pci, &buf->risc, + dma->sglist, + 0, buf->bpl * (buf->vb.height >> 1), + buf->bpl, 0, + buf->vb.height >> 1); + break; + case V4L2_FIELD_SEQ_BT: + cx88_risc_buffer(dev->pci, &buf->risc, + dma->sglist, + buf->bpl * (buf->vb.height >> 1), 0, + buf->bpl, 0, + buf->vb.height >> 1); + break; + case V4L2_FIELD_INTERLACED: + default: + cx88_risc_buffer(dev->pci, &buf->risc, + dma->sglist, 0, buf->bpl, + buf->bpl, buf->bpl, + buf->vb.height >> 1); + break; } dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", buf, buf->vb.i, @@ -646,22 +630,12 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else { prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); - if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(2,"[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - - } else { - list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2,"[%p/%d] buffer_queue - first queued\n", - buf, buf->vb.i); - } + list_add_tail(&buf->vb.queue, &q->active); + buf->vb.state = VIDEOBUF_ACTIVE; + buf->count = q->count++; + prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); + dprintk(2, "[%p/%d] buffer_queue - append to active\n", + buf, buf->vb.i); } } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 28893a6b249e..ddc7991723eb 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -319,7 +319,6 @@ struct cx88_buffer { /* cx88 specific */ unsigned int bpl; struct btcx_riscmem risc; - const struct cx8800_fmt *fmt; u32 count; }; -- GitLab From 6f11adc6a5e3378aeb13d9a19c427cbec05805be Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 10 Aug 2014 11:56:14 -0300 Subject: [PATCH 2448/9457] [media] cx88: drop the bogus 'queue' list in dmaqueue This list is only used if the width, height and/or format of a buffer has changed, but that can never happen. Remove it and all associated code. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-mpeg.c | 31 ----------------------- drivers/media/pci/cx88/cx88-video.c | 39 +++-------------------------- drivers/media/pci/cx88/cx88.h | 1 - 3 files changed, 3 insertions(+), 68 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 2803b6f17646..5f59901b2460 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -210,37 +210,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, dprintk( 1, "cx8802_restart_queue\n" ); if (list_empty(&q->active)) - { - struct cx88_buffer *prev; - prev = NULL; - - dprintk(1, "cx8802_restart_queue: queue is empty\n" ); - - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); - if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); - cx8802_start_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(1,"[%p/%d] restart_queue - first active\n", - buf,buf->vb.i); - - } else { - list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(1,"[%p/%d] restart_queue - move to active\n", - buf,buf->vb.i); - } - prev = buf; - } return 0; - } buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); dprintk(2,"restart_queue [%p/%d]: restart dma\n", @@ -486,7 +456,6 @@ static int cx8802_init_common(struct cx8802_dev *dev) /* init dma queue */ INIT_LIST_HEAD(&dev->mpegq.active); - INIT_LIST_HEAD(&dev->mpegq.queued); dev->mpegq.timeout.function = cx8802_timeout; dev->mpegq.timeout.data = (unsigned long)dev; init_timer(&dev->mpegq.timeout); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 095542316917..a1d704235478 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -470,7 +470,7 @@ static int restart_video_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q) { struct cx88_core *core = dev->core; - struct cx88_buffer *buf, *prev; + struct cx88_buffer *buf; if (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); @@ -480,33 +480,8 @@ static int restart_video_queue(struct cx8800_dev *dev, list_for_each_entry(buf, &q->active, vb.queue) buf->count = q->count++; mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - return 0; - } - - prev = NULL; - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); - if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); - start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2,"[%p/%d] restart_queue - first active\n", - buf,buf->vb.i); - - } else { - list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(2,"[%p/%d] restart_queue - move to active\n", - buf,buf->vb.i); - } - prev = buf; } + return 0; } /* ------------------------------------------------------------------ */ @@ -613,13 +588,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - if (!list_empty(&q->queued)) { - list_add_tail(&buf->vb.queue,&q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2,"[%p/%d] buffer_queue - append to queued\n", - buf, buf->vb.i); - - } else if (list_empty(&q->active)) { + if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue,&q->active); start_video_dma(dev, q, buf); buf->vb.state = VIDEOBUF_ACTIVE; @@ -1691,7 +1660,6 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); dev->vidq.timeout.function = cx8800_vid_timeout; dev->vidq.timeout.data = (unsigned long)dev; init_timer(&dev->vidq.timeout); @@ -1700,7 +1668,6 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* init vbi dma queues */ INIT_LIST_HEAD(&dev->vbiq.active); - INIT_LIST_HEAD(&dev->vbiq.queued); dev->vbiq.timeout.function = cx8800_vbi_timeout; dev->vbiq.timeout.data = (unsigned long)dev; init_timer(&dev->vbiq.timeout); diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index ddc7991723eb..77ec5427a986 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -324,7 +324,6 @@ struct cx88_buffer { struct cx88_dmaqueue { struct list_head active; - struct list_head queued; struct timer_list timeout; struct btcx_riscmem stopper; u32 count; -- GitLab From b2c75abde0debfb824f72845c3ed77d4b66798a0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:25:30 -0300 Subject: [PATCH 2449/9457] [media] cx88: drop videobuf abuse in cx88-alsa The alsa driver uses videobuf low-level functions that are not available in vb2, so replace them by driver-specific functions. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 107 ++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 18 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index a72579a9f67f..73021a22de1b 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -62,7 +62,10 @@ struct cx88_audio_buffer { unsigned int bpl; struct btcx_riscmem risc; - struct videobuf_dmabuf dma; + void *vaddr; + struct scatterlist *sglist; + int sglen; + int nr_pages; }; struct cx88_audio_dev { @@ -84,8 +87,6 @@ struct cx88_audio_dev { unsigned int period_size; unsigned int num_periods; - struct videobuf_dmabuf *dma_risc; - struct cx88_audio_buffer *buf; struct snd_pcm_substream *substream; @@ -290,19 +291,94 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id) return IRQ_RETVAL(handled); } +static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) +{ + struct cx88_audio_buffer *buf = chip->buf; + struct page *pg; + int i; + + buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); + if (NULL == buf->vaddr) { + dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); + return -ENOMEM; + } + + dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n", + (unsigned long)buf->vaddr, + nr_pages << PAGE_SHIFT); + + memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); + buf->nr_pages = nr_pages; + + buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); + if (NULL == buf->sglist) + goto vzalloc_err; + + sg_init_table(buf->sglist, buf->nr_pages); + for (i = 0; i < buf->nr_pages; i++) { + pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); + if (NULL == pg) + goto vmalloc_to_page_err; + sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); + } + return 0; + +vmalloc_to_page_err: + vfree(buf->sglist); + buf->sglist = NULL; +vzalloc_err: + vfree(buf->vaddr); + buf->vaddr = NULL; + return -ENOMEM; +} + +static int cx88_alsa_dma_map(struct cx88_audio_dev *dev) +{ + struct cx88_audio_buffer *buf = dev->buf; + + buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist, + buf->nr_pages, PCI_DMA_FROMDEVICE); + + if (0 == buf->sglen) { + pr_warn("%s: cx88_alsa_map_sg failed\n", __func__); + return -ENOMEM; + } + return 0; +} + +static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev) +{ + struct cx88_audio_buffer *buf = dev->buf; + + if (!buf->sglen) + return 0; + + dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE); + buf->sglen = 0; + return 0; +} + +static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf) +{ + vfree(buf->sglist); + buf->sglist = NULL; + vfree(buf->vaddr); + buf->vaddr = NULL; + return 0; +} + static int dsp_buffer_free(snd_cx88_card_t *chip) { BUG_ON(!chip->dma_size); dprintk(2,"Freeing buffer\n"); - videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc); - videobuf_dma_free(chip->dma_risc); - btcx_riscmem_free(chip->pci,&chip->buf->risc); + cx88_alsa_dma_unmap(chip); + cx88_alsa_dma_free(chip->buf); + btcx_riscmem_free(chip->pci, &chip->buf->risc); kfree(chip->buf); - chip->dma_risc = NULL; - chip->dma_size = 0; + chip->buf = NULL; return 0; } @@ -387,7 +463,6 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) { snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - struct videobuf_dmabuf *dma; struct cx88_audio_buffer *buf; int ret; @@ -408,20 +483,19 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, if (NULL == buf) return -ENOMEM; + chip->buf = buf; buf->bpl = chip->period_size; - dma = &buf->dma; - videobuf_dma_init(dma); - ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, + ret = cx88_alsa_dma_init(chip, (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); if (ret < 0) goto error; - ret = videobuf_dma_map(&chip->pci->dev, dma); + ret = cx88_alsa_dma_map(chip); if (ret < 0) goto error; - ret = cx88_risc_databuffer(chip->pci, &buf->risc, dma->sglist, + ret = cx88_risc_databuffer(chip->pci, &buf->risc, buf->sglist, chip->period_size, chip->num_periods, 1); if (ret < 0) goto error; @@ -430,10 +504,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream, buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - chip->buf = buf; - chip->dma_risc = dma; - - substream->runtime->dma_area = chip->dma_risc->vaddr; + substream->runtime->dma_area = chip->buf->vaddr; substream->runtime->dma_bytes = chip->dma_size; substream->runtime->dma_addr = 0; return 0; -- GitLab From 0b6b6302d983236f8b5d6d6602b91a6d1e144896 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 20 Sep 2014 09:22:18 -0300 Subject: [PATCH 2450/9457] [media] cx88: convert to vb2 As usual, this patch is very large due to the fact that half a vb2 conversion isn't possible. And since this affects blackbird, alsa, core, dvb, vbi and video the changes are all over. What made this more difficult was the peculiar way the risc program was setup. The driver allowed for running out of buffers in which case the DMA would stop and restart when the next buffer was queued. There was also a complicated timeout system for when buffers weren't filled. This was replaced by a much simpler scheme where there is always one buffer around and the DMA will just cycle that buffer until a new buffer is queued. In that case the previous buffer will be chained to the new buffer. An interrupt is generated at the start of the new buffer telling the driver that the previous buffer can be passed on to userspace. Much simpler and more robust. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/Kconfig | 4 +- drivers/media/pci/cx88/cx88-blackbird.c | 438 ++++++--------- drivers/media/pci/cx88/cx88-core.c | 83 +-- drivers/media/pci/cx88/cx88-dvb.c | 155 ++++-- drivers/media/pci/cx88/cx88-mpeg.c | 117 ++-- drivers/media/pci/cx88/cx88-vbi.c | 193 +++---- drivers/media/pci/cx88/cx88-video.c | 694 +++++++----------------- drivers/media/pci/cx88/cx88.h | 64 +-- 8 files changed, 651 insertions(+), 1097 deletions(-) diff --git a/drivers/media/pci/cx88/Kconfig b/drivers/media/pci/cx88/Kconfig index a63a9ad163b2..d5b125e4ab02 100644 --- a/drivers/media/pci/cx88/Kconfig +++ b/drivers/media/pci/cx88/Kconfig @@ -3,7 +3,7 @@ config VIDEO_CX88 depends on VIDEO_DEV && PCI && I2C && RC_CORE select I2C_ALGOBIT select VIDEO_BTCX - select VIDEOBUF_DMA_SG + select VIDEOBUF2_DMA_SG select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_WM8775 if MEDIA_SUBDRV_AUTOSELECT @@ -45,7 +45,7 @@ config VIDEO_CX88_BLACKBIRD config VIDEO_CX88_DVB tristate "DVB/ATSC Support for cx2388x based TV cards" depends on VIDEO_CX88 && DVB_CORE - select VIDEOBUF_DVB + select VIDEOBUF2_DVB select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 150bb76e7839..25d06f36e0ef 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -45,10 +45,6 @@ MODULE_AUTHOR("Jelle Foks , Gerd Knorr [SuSE MODULE_LICENSE("GPL"); MODULE_VERSION(CX88_VERSION); -static unsigned int mpegbufs = 32; -module_param(mpegbufs,int,0644); -MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); - static unsigned int debug; module_param(debug,int,0644); MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); @@ -589,9 +585,8 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) return 0; } -static int blackbird_start_codec(struct file *file, void *priv) +static int blackbird_start_codec(struct cx8802_dev *dev) { - struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; struct cx88_core *core = dev->core; /* start capturing to the host interface */ u32 reg; @@ -647,45 +642,131 @@ static int blackbird_stop_codec(struct cx8802_dev *dev) /* ------------------------------------------------------------------ */ -static int bb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) { - struct cx8802_fh *fh = q->priv_data; - - fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ - fh->dev->ts_packet_count = mpegbufs; /* was: 100 */ + struct cx8802_dev *dev = q->drv_priv; - *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; - *count = fh->dev->ts_packet_count; + *num_planes = 1; + dev->ts_packet_size = 188 * 4; + dev->ts_packet_count = 32; + sizes[0] = dev->ts_packet_size * dev->ts_packet_count; return 0; } -static int -bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) +static int buffer_prepare(struct vb2_buffer *vb) { - struct cx8802_fh *fh = q->priv_data; - return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field); + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + + return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field); } -static void -bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +static void buffer_finish(struct vb2_buffer *vb) { - struct cx8802_fh *fh = q->priv_data; - cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb); + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + + cx88_free_buffer(vb->vb2_queue, buf); + + dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } -static void -bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +static void buffer_queue(struct vb2_buffer *vb) { - cx88_free_buffer(q, (struct cx88_buffer*)vb); + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + + cx8802_buf_queue(dev, buf); } -static struct videobuf_queue_ops blackbird_qops = { - .buf_setup = bb_buf_setup, - .buf_prepare = bb_buf_prepare, - .buf_queue = bb_buf_queue, - .buf_release = bb_buf_release, +static int start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct cx8802_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->mpegq; + struct cx8802_driver *drv; + struct cx88_buffer *buf; + unsigned long flags; + int err; + + /* Make sure we can acquire the hardware */ + drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); + if (!drv) { + dprintk(1, "%s: blackbird driver is not loaded\n", __func__); + err = -ENODEV; + goto fail; + } + + err = drv->request_acquire(drv); + if (err != 0) { + dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__, err); + goto fail; + } + + if (blackbird_initialize_codec(dev) < 0) { + drv->request_release(drv); + err = -EINVAL; + goto fail; + } + + err = blackbird_start_codec(dev); + if (err == 0) { + buf = list_entry(dmaq->active.next, struct cx88_buffer, list); + cx8802_start_dma(dev, dmaq, buf); + return 0; + } + +fail: + spin_lock_irqsave(&dev->slock, flags); + while (!list_empty(&dmaq->active)) { + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); + } + spin_unlock_irqrestore(&dev->slock, flags); + return err; +} + +static void stop_streaming(struct vb2_queue *q) +{ + struct cx8802_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->mpegq; + struct cx8802_driver *drv = NULL; + unsigned long flags; + + cx8802_cancel_buffers(dev); + blackbird_stop_codec(dev); + + /* Make sure we release the hardware */ + drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); + WARN_ON(!drv); + if (drv) + drv->request_release(drv); + + spin_lock_irqsave(&dev->slock, flags); + while (!list_empty(&dmaq->active)) { + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&dev->slock, flags); +} + +static struct vb2_ops blackbird_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_finish = buffer_finish, + .buf_queue = buffer_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, }; /* ------------------------------------------------------------------ */ @@ -693,8 +774,8 @@ static struct videobuf_queue_ops blackbird_qops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; - struct cx88_core *core = dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; strcpy(cap->driver, "cx88_blackbird"); sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); @@ -717,50 +798,47 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; + struct cx8802_dev *dev = video_drvdata(file); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; - f->fmt.pix.field = fh->mpegq.field; + f->fmt.pix.field = dev->field; dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->width, dev->height, fh->mpegq.field ); + dev->width, dev->height, dev->field); return 0; } static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; + struct cx8802_dev *dev = video_drvdata(file); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->width, dev->height, fh->mpegq.field ); + dev->width, dev->height, dev->field); return 0; } static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; + struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ + f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; dev->width = f->fmt.pix.width; dev->height = f->fmt.pix.height; - fh->mpegq.field = f->fmt.pix.field; + dev->field = f->fmt.pix.field; cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, f->fmt.pix.height, f->fmt.pix.width); @@ -769,57 +847,11 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, return 0; } -static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) -{ - struct cx8802_fh *fh = priv; - return (videobuf_reqbufs(&fh->mpegq, p)); -} - -static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct cx8802_fh *fh = priv; - return (videobuf_querybuf(&fh->mpegq, p)); -} - -static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct cx8802_fh *fh = priv; - return (videobuf_qbuf(&fh->mpegq, p)); -} - -static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct cx8802_fh *fh = priv; - return (videobuf_dqbuf(&fh->mpegq, p, - file->f_flags & O_NONBLOCK)); -} - -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; - - if (!dev->mpeg_active) - blackbird_start_codec(file, fh); - return videobuf_streamon(&fh->mpegq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; - - if (dev->mpeg_active) - blackbird_stop_codec(dev); - return videobuf_streamoff(&fh->mpegq); -} - static int vidioc_s_frequency (struct file *file, void *priv, const struct v4l2_frequency *f) { - struct cx8802_fh *fh = priv; - struct cx8802_dev *dev = fh->dev; - struct cx88_core *core = dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; @@ -831,14 +863,14 @@ static int vidioc_s_frequency (struct file *file, void *priv, cx88_set_freq (core,f); blackbird_initialize_codec(dev); cx88_set_scale(dev->core, dev->width, dev->height, - fh->mpegq.field); + dev->field); return 0; } static int vidioc_log_status (struct file *file, void *priv) { - struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; - struct cx88_core *core = dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; char name[32 + 2]; snprintf(name, sizeof(name), "%s/2", core->name); @@ -850,15 +882,16 @@ static int vidioc_log_status (struct file *file, void *priv) static int vidioc_enum_input (struct file *file, void *priv, struct v4l2_input *i) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; return cx88_enum_input (core,i); } static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct cx8802_fh *fh = priv; - struct cx88_core *core = fh->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; @@ -873,7 +906,8 @@ static int vidioc_g_frequency (struct file *file, void *priv, static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; *i = core->input; return 0; @@ -881,24 +915,24 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) static int vidioc_s_input (struct file *file, void *priv, unsigned int i) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (i >= 4) return -EINVAL; if (0 == INPUT(i).type) return -EINVAL; - mutex_lock(&core->lock); cx88_newstation(core); cx88_video_mux(core,i); - mutex_unlock(&core->lock); return 0; } static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; u32 reg; if (unlikely(UNSET == core->board.tuner_type)) @@ -920,7 +954,8 @@ static int vidioc_g_tuner (struct file *file, void *priv, static int vidioc_s_tuner (struct file *file, void *priv, const struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (UNSET == core->board.tuner_type) return -EINVAL; @@ -933,7 +968,8 @@ static int vidioc_s_tuner (struct file *file, void *priv, static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; + struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; *tvnorm = core->tvnorm; return 0; @@ -941,155 +977,21 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) { - struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; - - mutex_lock(&core->lock); - cx88_set_tvnorm(core, id); - mutex_unlock(&core->lock); - return 0; -} - -/* FIXME: cx88_ioctl_hook not implemented */ - -static int mpeg_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); struct cx8802_dev *dev = video_drvdata(file); - struct cx8802_fh *fh; - struct cx8802_driver *drv = NULL; - int err; - - dprintk( 1, "%s\n", __func__); - - mutex_lock(&dev->core->lock); - - /* Make sure we can acquire the hardware */ - drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); - if (!drv) { - dprintk(1, "%s: blackbird driver is not loaded\n", __func__); - mutex_unlock(&dev->core->lock); - return -ENODEV; - } - - err = drv->request_acquire(drv); - if (err != 0) { - dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); - mutex_unlock(&dev->core->lock); - return err; - } - - if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) { - drv->request_release(drv); - mutex_unlock(&dev->core->lock); - return -EINVAL; - } - dprintk(1, "open dev=%s\n", video_device_node_name(vdev)); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - drv->request_release(drv); - mutex_unlock(&dev->core->lock); - return -ENOMEM; - } - v4l2_fh_init(&fh->fh, vdev); - file->private_data = fh; - fh->dev = dev; - - videobuf_queue_sg_init(&fh->mpegq, &blackbird_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx88_buffer), - fh, NULL); - - /* FIXME: locking against other video device */ - cx88_set_scale(dev->core, dev->width, dev->height, - fh->mpegq.field); - - dev->core->mpeg_users++; - mutex_unlock(&dev->core->lock); - v4l2_fh_add(&fh->fh); - return 0; -} - -static int mpeg_release(struct file *file) -{ - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; - struct cx8802_driver *drv = NULL; - - mutex_lock(&dev->core->lock); - - if (dev->mpeg_active && dev->core->mpeg_users == 1) - blackbird_stop_codec(dev); - - cx8802_cancel_buffers(fh->dev); - /* stop mpeg capture */ - videobuf_stop(&fh->mpegq); - - videobuf_mmap_free(&fh->mpegq); - - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - file->private_data = NULL; - kfree(fh); - - /* Make sure we release the hardware */ - drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); - WARN_ON(!drv); - if (drv) - drv->request_release(drv); - - dev->core->mpeg_users--; - - mutex_unlock(&dev->core->lock); + struct cx88_core *core = dev->core; + cx88_set_tvnorm(core, id); return 0; } -static ssize_t -mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; - - if (!dev->mpeg_active) - blackbird_start_codec(file, fh); - - return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static unsigned int -mpeg_poll(struct file *file, struct poll_table_struct *wait) -{ - unsigned long req_events = poll_requested_events(wait); - struct cx8802_fh *fh = file->private_data; - struct cx8802_dev *dev = fh->dev; - - if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM))) - blackbird_start_codec(file, fh); - - return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait); -} - -static int -mpeg_mmap(struct file *file, struct vm_area_struct * vma) -{ - struct cx8802_fh *fh = file->private_data; - - return videobuf_mmap_mapper(&fh->mpegq, vma); -} - static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, - .open = mpeg_open, - .release = mpeg_release, - .read = mpeg_read, - .poll = mpeg_poll, - .mmap = mpeg_mmap, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; @@ -1099,12 +1001,12 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_log_status = vidioc_log_status, .vidioc_enum_input = vidioc_enum_input, @@ -1189,11 +1091,12 @@ static int blackbird_register_video(struct cx8802_dev *dev) { int err; - dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, - &cx8802_mpeg_template,"mpeg"); + dev->mpeg_dev = cx88_vdev_init(dev->core, dev->pci, + &cx8802_mpeg_template, "mpeg"); dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl; video_set_drvdata(dev->mpeg_dev, dev); - err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); + dev->mpeg_dev->queue = &dev->vb2_mpegq; + err = video_register_device(dev->mpeg_dev, VFL_TYPE_GRABBER, -1); if (err < 0) { printk(KERN_INFO "%s/2: can't register mpeg device\n", dev->core->name); @@ -1210,6 +1113,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = core->dvbdev; + struct vb2_queue *q; int err; dprintk( 1, "%s\n", __func__); @@ -1229,6 +1133,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) } else { dev->height = 576; } + dev->field = V4L2_FIELD_INTERLACED; dev->cxhdl.port = CX2341X_PORT_STREAMING; dev->cxhdl.width = dev->width; dev->cxhdl.height = dev->height; @@ -1252,11 +1157,28 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) cx88_video_mux(core,0); cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576); cx2341x_handler_setup(&dev->cxhdl); + + q = &dev->vb2_mpegq; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->gfp_flags = GFP_DMA32; + q->min_buffers_needed = 2; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx88_buffer); + q->ops = &blackbird_qops; + q->mem_ops = &vb2_dma_sg_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &core->lock; + + err = vb2_queue_init(q); + if (err < 0) + goto fail_core; + blackbird_register_video(dev); return 0; - fail_core: +fail_core: return err; } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 71630238027b..f02740860970 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -76,11 +76,16 @@ static DEFINE_MUTEX(devlist); static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, - unsigned int lines, unsigned int lpi) + unsigned int lines, unsigned int lpi, bool jump) { struct scatterlist *sg; unsigned int line,todo,sol; + if (jump) { + (*rp++) = cpu_to_le32(RISC_JUMP); + (*rp++) = 0; + } + /* sync instruction */ if (sync_line != NO_SYNC_LINE) *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); @@ -147,7 +152,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, can cause next bpl to start close to a page border. First DMA region may be smaller than PAGE_SIZE */ instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); - instructions += 2; + instructions += 4; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; @@ -155,10 +160,10 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, rp = risc->cpu; if (UNSET != top_offset) rp = cx88_risc_field(rp, sglist, top_offset, 0, - bpl, padding, lines, 0); + bpl, padding, lines, 0, true); if (UNSET != bottom_offset) rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200, - bpl, padding, lines, 0); + bpl, padding, lines, 0, top_offset == UNSET); /* save pointer to jmp instruction address */ risc->jmp = rp; @@ -179,13 +184,13 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, there is no padding and no sync. First DMA region may be smaller than PAGE_SIZE */ instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; - instructions += 1; + instructions += 3; if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) return rc; /* write risc instructions */ rp = risc->cpu; - rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi); + rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi, !lpi); /* save pointer to jmp instruction address */ risc->jmp = rp; @@ -193,37 +198,10 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, return 0; } -int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value) -{ - __le32 *rp; - int rc; - - if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM); - *(rp++) = cpu_to_le32(reg); - *(rp++) = cpu_to_le32(value); - *(rp++) = cpu_to_le32(mask); - *(rp++) = cpu_to_le32(RISC_JUMP); - *(rp++) = cpu_to_le32(risc->dma); - return 0; -} - void -cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf) +cx88_free_buffer(struct vb2_queue *q, struct cx88_buffer *buf) { - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - - BUG_ON(in_interrupt()); - videobuf_waiton(q, &buf->vb, 0, 0); - videobuf_dma_unmap(q->dev, dma); - videobuf_dma_free(dma); - btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); - buf->vb.state = VIDEOBUF_NEEDS_INIT; + btcx_riscmem_free(to_pci_dev(q->drv_priv), &buf->risc); } /* ------------------------------------------------------------------ */ @@ -539,33 +517,12 @@ void cx88_wakeup(struct cx88_core *core, struct cx88_dmaqueue *q, u32 count) { struct cx88_buffer *buf; - int bc; - - for (bc = 0;; bc++) { - if (list_empty(&q->active)) - break; - buf = list_entry(q->active.next, - struct cx88_buffer, vb.queue); - /* count comes from the hw and is is 16bit wide -- - * this trick handles wrap-arounds correctly for - * up to 32767 buffers in flight... */ - if ((s16) (count - buf->count) < 0) - break; - v4l2_get_timestamp(&buf->vb.ts); - dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i, - count, buf->count); - buf->vb.state = VIDEOBUF_DONE; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - } - if (list_empty(&q->active)) { - del_timer(&q->timeout); - } else { - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - } - if (bc != 1) - dprintk(2, "%s: %d buffers handled (should be 1)\n", - __func__, bc); + + buf = list_entry(q->active.next, + struct cx88_buffer, list); + v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); } void cx88_shutdown(struct cx88_core *core) @@ -1043,6 +1000,7 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, vfd->v4l2_dev = &core->v4l2_dev; vfd->dev_parent = &pci->dev; vfd->release = video_device_release; + vfd->lock = &core->lock; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); return vfd; @@ -1114,7 +1072,6 @@ EXPORT_SYMBOL(cx88_shutdown); EXPORT_SYMBOL(cx88_risc_buffer); EXPORT_SYMBOL(cx88_risc_databuffer); -EXPORT_SYMBOL(cx88_risc_stopper); EXPORT_SYMBOL(cx88_free_buffer); EXPORT_SYMBOL(cx88_sram_channels); diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 053ed1ba1d85..d7e5c45022c9 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -82,43 +82,86 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* ------------------------------------------------------------------ */ -static int dvb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) { - struct cx8802_dev *dev = q->priv_data; + struct cx8802_dev *dev = q->drv_priv; + *num_planes = 1; dev->ts_packet_size = 188 * 4; dev->ts_packet_count = dvb_buf_tscnt; - - *size = dev->ts_packet_size * dev->ts_packet_count; - *count = dvb_buf_tscnt; + sizes[0] = dev->ts_packet_size * dev->ts_packet_count; + *num_buffers = dvb_buf_tscnt; return 0; } -static int dvb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) +static int buffer_prepare(struct vb2_buffer *vb) +{ + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + + return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field); +} + +static void buffer_finish(struct vb2_buffer *vb) +{ + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + + cx88_free_buffer(vb->vb2_queue, buf); + + dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); +} + +static void buffer_queue(struct vb2_buffer *vb) { - struct cx8802_dev *dev = q->priv_data; - return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); + struct cx8802_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + + cx8802_buf_queue(dev, buf); } -static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +static int start_streaming(struct vb2_queue *q, unsigned int count) { - struct cx8802_dev *dev = q->priv_data; - cx8802_buf_queue(dev, (struct cx88_buffer*)vb); + struct cx8802_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->mpegq; + struct cx88_buffer *buf; + + buf = list_entry(dmaq->active.next, struct cx88_buffer, list); + cx8802_start_dma(dev, dmaq, buf); + return 0; } -static void dvb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static void stop_streaming(struct vb2_queue *q) { - cx88_free_buffer(q, (struct cx88_buffer*)vb); + struct cx8802_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->mpegq; + unsigned long flags; + + cx8802_cancel_buffers(dev); + + spin_lock_irqsave(&dev->slock, flags); + while (!list_empty(&dmaq->active)) { + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&dev->slock, flags); } -static const struct videobuf_queue_ops dvb_qops = { - .buf_setup = dvb_buf_setup, - .buf_prepare = dvb_buf_prepare, - .buf_queue = dvb_buf_queue, - .buf_release = dvb_buf_release, +static struct vb2_ops dvb_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_finish = buffer_finish, + .buf_queue = buffer_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, }; /* ------------------------------------------------------------------ */ @@ -130,7 +173,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) int ret = 0; int fe_id; - fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe); + fe_id = vb2_dvb_find_frontend(&dev->frontends, fe); if (!fe_id) { printk(KERN_ERR "%s() No frontend found\n", __func__); return -EINVAL; @@ -154,8 +197,8 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) { - struct videobuf_dvb_frontends *f; - struct videobuf_dvb_frontend *fe; + struct vb2_dvb_frontends *f; + struct vb2_dvb_frontend *fe; if (!core->dvbdev) return; @@ -166,9 +209,9 @@ static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) return; if (f->gate <= 1) /* undefined or fe0 */ - fe = videobuf_dvb_get_frontend(f, 1); + fe = vb2_dvb_get_frontend(f, 1); else - fe = videobuf_dvb_get_frontend(f, f->gate); + fe = vb2_dvb_get_frontend(f, f->gate); if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); @@ -565,7 +608,7 @@ static const struct xc5000_config dvico_fusionhdtv7_tuner_config = { static int attach_xc3028(u8 addr, struct cx8802_dev *dev) { struct dvb_frontend *fe; - struct videobuf_dvb_frontend *fe0 = NULL; + struct vb2_dvb_frontend *fe0 = NULL; struct xc2028_ctrl ctl; struct xc2028_config cfg = { .i2c_adap = &dev->core->i2c_adap, @@ -574,7 +617,7 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) }; /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); + fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); if (!fe0) return -EINVAL; @@ -611,10 +654,10 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev) static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) { struct dvb_frontend *fe; - struct videobuf_dvb_frontend *fe0 = NULL; + struct vb2_dvb_frontend *fe0 = NULL; /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); + fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); if (!fe0) return -EINVAL; @@ -745,7 +788,7 @@ static const struct stv0288_config tevii_tuner_earda_config = { static int cx8802_alloc_frontends(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - struct videobuf_dvb_frontend *fe = NULL; + struct vb2_dvb_frontend *fe = NULL; int i; mutex_init(&dev->frontends.lock); @@ -757,10 +800,10 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev) printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); for (i = 1; i <= core->board.num_frontends; i++) { - fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); + fe = vb2_dvb_alloc_frontend(&dev->frontends, i); if (!fe) { printk(KERN_ERR "%s() failed to alloc\n", __func__); - videobuf_dvb_dealloc_frontends(&dev->frontends); + vb2_dvb_dealloc_frontends(&dev->frontends); return -ENOMEM; } } @@ -958,7 +1001,7 @@ static const struct stv0299_config samsung_stv0299_config = { static int dvb_register(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; - struct videobuf_dvb_frontend *fe0, *fe1 = NULL; + struct vb2_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ int res = -EINVAL; @@ -968,7 +1011,7 @@ static int dvb_register(struct cx8802_dev *dev) } /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); + fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); if (!fe0) goto frontend_detach; @@ -1046,7 +1089,7 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; } /* MFE frontend 2 */ - fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); + fe1 = vb2_dvb_get_frontend(&dev->frontends, 2); if (!fe1) goto frontend_detach; /* DVB-T init */ @@ -1415,7 +1458,7 @@ static int dvb_register(struct cx8802_dev *dev) goto frontend_detach; } /* MFE frontend 2 */ - fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); + fe1 = vb2_dvb_get_frontend(&dev->frontends, 2); if (!fe1) goto frontend_detach; /* DVB-T Init */ @@ -1594,7 +1637,7 @@ static int dvb_register(struct cx8802_dev *dev) call_all(core, core, s_power, 0); /* register everything */ - res = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, + res = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, &dev->pci->dev, adapter_nr, mfe_shared); if (res) goto frontend_detach; @@ -1602,7 +1645,7 @@ static int dvb_register(struct cx8802_dev *dev) frontend_detach: core->gate_ctrl = NULL; - videobuf_dvb_dealloc_frontends(&dev->frontends); + vb2_dvb_dealloc_frontends(&dev->frontends); return res; } @@ -1697,7 +1740,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; - struct videobuf_dvb_frontend *fe; + struct vb2_dvb_frontend *fe; int i; dprintk( 1, "%s\n", __func__); @@ -1726,19 +1769,31 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) err = -ENODEV; for (i = 1; i <= core->board.num_frontends; i++) { - fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); + struct vb2_queue *q; + + fe = vb2_dvb_get_frontend(&core->dvbdev->frontends, i); if (fe == NULL) { printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i); goto fail_probe; } - videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_TOP, - sizeof(struct cx88_buffer), - dev, NULL); - /* init struct videobuf_dvb */ + q = &fe->dvb.dvbq; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->gfp_flags = GFP_DMA32; + q->min_buffers_needed = 2; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx88_buffer); + q->ops = &dvb_qops; + q->mem_ops = &vb2_dma_sg_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &core->lock; + + err = vb2_queue_init(q); + if (err < 0) + goto fail_probe; + + /* init struct vb2_dvb */ fe->dvb.name = dev->core->name; } @@ -1749,7 +1804,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) core->name, err); return err; fail_probe: - videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends); + vb2_dvb_dealloc_frontends(&core->dvbdev->frontends); fail_core: return err; } @@ -1761,7 +1816,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) dprintk( 1, "%s\n", __func__); - videobuf_dvb_unregister_bus(&dev->frontends); + vb2_dvb_unregister_bus(&dev->frontends); vp3054_i2c_remove(dev); diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 5f59901b2460..7986ee037b83 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -86,21 +86,21 @@ static LIST_HEAD(cx8802_devlist); static DEFINE_MUTEX(cx8802_mutex); /* ------------------------------------------------------------------ */ -static int cx8802_start_dma(struct cx8802_dev *dev, +int cx8802_start_dma(struct cx8802_dev *dev, struct cx88_dmaqueue *q, struct cx88_buffer *buf) { struct cx88_core *core = dev->core; dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", - buf->vb.width, buf->vb.height, buf->vb.field); + dev->width, dev->height, dev->field); /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], dev->ts_packet_size, buf->risc.dma); /* write TS length to chip */ - cx_write(MO_TS_LNGTH, buf->vb.width); + cx_write(MO_TS_LNGTH, dev->ts_packet_size); /* FIXME: this needs a review. * also: move to cx88-blackbird + cx88-dvb source files? */ @@ -212,47 +212,35 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, if (list_empty(&q->active)) return 0; - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx88_buffer, list); dprintk(2,"restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); cx8802_start_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) + list_for_each_entry(buf, &q->active, list) buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); return 0; } /* ------------------------------------------------------------------ */ -int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, +int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, struct cx88_buffer *buf, enum v4l2_field field) { int size = dev->ts_packet_size * dev->ts_packet_count; - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0); int rc; - dprintk(1, "%s: %p\n", __func__, buf); - if (0 != buf->vb.baddr && buf->vb.bsize < size) + if (vb2_plane_size(&buf->vb, 0) < size) return -EINVAL; + vb2_set_plane_payload(&buf->vb, 0, size); - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = dev->ts_packet_size; - buf->vb.height = dev->ts_packet_count; - buf->vb.size = size; - buf->vb.field = field /*V4L2_FIELD_TOP*/; - - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) - goto fail; - cx88_risc_databuffer(dev->pci, &buf->risc, - dma->sglist, - buf->vb.width, buf->vb.height, 0); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; + rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); + if (!rc) + return -EIO; - fail: - cx88_free_buffer(q,buf); - return rc; + cx88_risc_databuffer(dev->pci, &buf->risc, sgt->sgl, + dev->ts_packet_size, dev->ts_packet_count, 0); + return 0; } void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) @@ -261,35 +249,33 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) struct cx88_dmaqueue *cx88q = &dev->mpegq; dprintk( 1, "cx8802_buf_queue\n" ); - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); + /* add jump to start */ + buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); + buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); + buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); if (list_empty(&cx88q->active)) { dprintk( 1, "queue is empty - first active\n" ); - list_add_tail(&buf->vb.queue,&cx88q->active); - cx8802_start_dma(dev, cx88q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; + list_add_tail(&buf->list, &cx88q->active); buf->count = cx88q->count++; - mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] %s - first active\n", - buf, buf->vb.i, __func__); + buf, buf->vb.v4l2_buf.index, __func__); } else { + buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); dprintk( 1, "queue is not empty - append to active\n" ); - prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue); - list_add_tail(&buf->vb.queue,&cx88q->active); - buf->vb.state = VIDEOBUF_ACTIVE; + prev = list_entry(cx88q->active.prev, struct cx88_buffer, list); + list_add_tail(&buf->list, &cx88q->active); buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __func__); + buf, buf->vb.v4l2_buf.index, __func__); } } /* ----------------------------------------------------------- */ -static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart) +static void do_cancel_buffers(struct cx8802_dev *dev) { struct cx88_dmaqueue *q = &dev->mpegq; struct cx88_buffer *buf; @@ -297,41 +283,18 @@ static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int re spin_lock_irqsave(&dev->slock,flags); while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - dprintk(1,"[%p/%d] %s - dma=0x%08lx\n", - buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); - } - if (restart) - { - dprintk(1, "restarting queue\n" ); - cx8802_restart_queue(dev,q); + buf = list_entry(q->active.next, struct cx88_buffer, list); + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } spin_unlock_irqrestore(&dev->slock,flags); } void cx8802_cancel_buffers(struct cx8802_dev *dev) { - struct cx88_dmaqueue *q = &dev->mpegq; - dprintk( 1, "cx8802_cancel_buffers" ); - del_timer_sync(&q->timeout); - cx8802_stop_dma(dev); - do_cancel_buffers(dev,"cancel",0); -} - -static void cx8802_timeout(unsigned long data) -{ - struct cx8802_dev *dev = (struct cx8802_dev*)data; - - dprintk(1, "%s\n",__func__); - - if (debug) - cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); cx8802_stop_dma(dev); - do_cancel_buffers(dev,"timeout",1); + do_cancel_buffers(dev); } static const char * cx88_mpeg_irqs[32] = { @@ -377,19 +340,11 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) spin_unlock(&dev->slock); } - /* risc2 y */ - if (status & 0x10) { - spin_lock(&dev->slock); - cx8802_restart_queue(dev,&dev->mpegq); - spin_unlock(&dev->slock); - } - /* other general errors */ if (status & 0x1f0100) { dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); spin_lock(&dev->slock); cx8802_stop_dma(dev); - cx8802_restart_queue(dev,&dev->mpegq); spin_unlock(&dev->slock); } } @@ -456,11 +411,6 @@ static int cx8802_init_common(struct cx8802_dev *dev) /* init dma queue */ INIT_LIST_HEAD(&dev->mpegq.active); - dev->mpegq.timeout.function = cx8802_timeout; - dev->mpegq.timeout.data = (unsigned long)dev; - init_timer(&dev->mpegq.timeout); - cx88_risc_stopper(dev->pci,&dev->mpegq.stopper, - MO_TS_DMACNTRL,0x11,0x00); /* get irq */ err = request_irq(dev->pci->irq, cx8802_irq, @@ -485,9 +435,6 @@ static void cx8802_fini_common(struct cx8802_dev *dev) /* unregister stuff */ free_irq(dev->pci->irq, dev); - - /* free memory */ - btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); } /* ----------------------------------------------------------- */ @@ -504,7 +451,6 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) dprintk( 2, "suspend\n" ); printk("%s: suspend mpeg\n", core->name); cx8802_stop_dma(dev); - del_timer(&dev->mpegq.timeout); } spin_unlock_irqrestore(&dev->slock, flags); @@ -872,6 +818,7 @@ module_pci_driver(cx8802_pci_driver); EXPORT_SYMBOL(cx8802_buf_prepare); EXPORT_SYMBOL(cx8802_buf_queue); EXPORT_SYMBOL(cx8802_cancel_buffers); +EXPORT_SYMBOL(cx8802_start_dma); EXPORT_SYMBOL(cx8802_register_driver); EXPORT_SYMBOL(cx8802_unregister_driver); diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index f8f8389c0362..26a15331cc10 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -6,10 +6,6 @@ #include "cx88.h" -static unsigned int vbibufs = 4; -module_param(vbibufs,int,0644); -MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); - static unsigned int vbi_debug; module_param(vbi_debug,int,0644); MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); @@ -22,8 +18,7 @@ MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); int cx8800_vbi_fmt (struct file *file, void *priv, struct v4l2_format *f) { - struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; + struct cx8800_dev *dev = video_drvdata(file); f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; @@ -54,7 +49,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, /* setup fifo + format */ cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24], - buf->vb.width, buf->risc.dma); + VBI_LINE_LENGTH, buf->risc.dma); cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup (1 << 15) | // enable vbi capture @@ -78,7 +73,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev *dev, return 0; } -int cx8800_stop_vbi_dma(struct cx8800_dev *dev) +void cx8800_stop_vbi_dma(struct cx8800_dev *dev) { struct cx88_core *core = dev->core; @@ -91,7 +86,6 @@ int cx8800_stop_vbi_dma(struct cx8800_dev *dev) /* disable irqs */ cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT); cx_clear(MO_VID_INTMSK, 0x0f0088); - return 0; } int cx8800_restart_vbi_queue(struct cx8800_dev *dev, @@ -102,144 +96,133 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev, if (list_empty(&q->active)) return 0; - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx88_buffer, list); dprintk(2,"restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); cx8800_start_vbi_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) + list_for_each_entry(buf, &q->active, list) buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); return 0; } -void cx8800_vbi_timeout(unsigned long data) -{ - struct cx8800_dev *dev = (struct cx8800_dev*)data; - struct cx88_core *core = dev->core; - struct cx88_dmaqueue *q = &dev->vbiq; - struct cx88_buffer *buf; - unsigned long flags; - - cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH24]); - - cx_clear(MO_VID_DMACNTRL, 0x88); - cx_clear(VID_CAPTURE_CONTROL, 0x18); - - spin_lock_irqsave(&dev->slock,flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name, - buf, buf->vb.i, (unsigned long)buf->risc.dma); - } - cx8800_restart_vbi_queue(dev,q); - spin_unlock_irqrestore(&dev->slock,flags); -} - /* ------------------------------------------------------------------ */ -static int -vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) { - *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 == *count) - *count = vbibufs; - if (*count < 2) - *count = 2; - if (*count > 32) - *count = 32; + *num_planes = 1; + sizes[0] = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; return 0; } -static int -vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) + +static int buffer_prepare(struct vb2_buffer *vb) { - struct cx8800_fh *fh = q->priv_data; - struct cx8800_dev *dev = fh->dev; - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); unsigned int size; int rc; size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 != buf->vb.baddr && buf->vb.bsize < size) + if (vb2_plane_size(vb, 0) < size) return -EINVAL; + vb2_set_plane_payload(vb, 0, size); - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - buf->vb.width = VBI_LINE_LENGTH; - buf->vb.height = VBI_LINE_COUNT; - buf->vb.size = size; - buf->vb.field = V4L2_FIELD_SEQ_TB; - - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) - goto fail; - cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->vb.width * buf->vb.height, - buf->vb.width, 0, - buf->vb.height); - } - buf->vb.state = VIDEOBUF_PREPARED; + rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); + if (!rc) + return -EIO; + + cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, + 0, VBI_LINE_LENGTH * VBI_LINE_COUNT, + VBI_LINE_LENGTH, 0, + VBI_LINE_COUNT); return 0; +} - fail: - cx88_free_buffer(q,buf); - return rc; +static void buffer_finish(struct vb2_buffer *vb) +{ + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + + cx88_free_buffer(vb->vb2_queue, buf); + + dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } -static void -vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +static void buffer_queue(struct vb2_buffer *vb) { - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct cx88_buffer *prev; - struct cx8800_fh *fh = vq->priv_data; - struct cx8800_dev *dev = fh->dev; struct cx88_dmaqueue *q = &dev->vbiq; - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); + /* add jump to start */ + buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); + buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); + buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue,&q->active); + list_add_tail(&buf->list, &q->active); cx8800_start_vbi_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] vbi_queue - first active\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); } else { - prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); - list_add_tail(&buf->vb.queue,&q->active); - buf->vb.state = VIDEOBUF_ACTIVE; + buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); + prev = list_entry(q->active.prev, struct cx88_buffer, list); + list_add_tail(&buf->list, &q->active); buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2,"[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); } } -static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +static int start_streaming(struct vb2_queue *q, unsigned int count) { - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->vbiq; + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); - cx88_free_buffer(q,buf); + cx8800_start_vbi_dma(dev, dmaq, buf); + return 0; } -const struct videobuf_queue_ops cx8800_vbi_qops = { - .buf_setup = vbi_setup, - .buf_prepare = vbi_prepare, - .buf_queue = vbi_queue, - .buf_release = vbi_release, -}; +static void stop_streaming(struct vb2_queue *q) +{ + struct cx8800_dev *dev = q->drv_priv; + struct cx88_core *core = dev->core; + struct cx88_dmaqueue *dmaq = &dev->vbiq; + unsigned long flags; -/* ------------------------------------------------------------------ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ + cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); + + cx_clear(MO_VID_DMACNTRL, 0x11); + cx_clear(VID_CAPTURE_CONTROL, 0x06); + cx8800_stop_vbi_dma(dev); + spin_lock_irqsave(&dev->slock, flags); + while (!list_empty(&dmaq->active)) { + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&dev->slock, flags); +} + +const struct vb2_ops cx8800_vbi_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_finish = buffer_finish, + .buf_queue = buffer_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, +}; diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index a1d704235478..9887da52c455 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -70,10 +70,6 @@ static unsigned int irq_debug; module_param(irq_debug,int,0644); MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]"); -static unsigned int vid_limit = 16; -module_param(vid_limit,int,0644); -MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); - #define dprintk(level,fmt, arg...) if (video_debug >= level) \ printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) @@ -297,56 +293,6 @@ enum { CX8800_AUD_CTLS = ARRAY_SIZE(cx8800_aud_ctls), }; -/* ------------------------------------------------------------------- */ -/* resource management */ - -static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) -{ - struct cx88_core *core = dev->core; - if (fh->resources & bit) - /* have it already allocated */ - return 1; - - /* is it free? */ - mutex_lock(&core->lock); - if (dev->resources & bit) { - /* no, someone else uses it */ - mutex_unlock(&core->lock); - return 0; - } - /* it's free, grab it */ - fh->resources |= bit; - dev->resources |= bit; - dprintk(1,"res: get %d\n",bit); - mutex_unlock(&core->lock); - return 1; -} - -static -int res_check(struct cx8800_fh *fh, unsigned int bit) -{ - return (fh->resources & bit); -} - -static -int res_locked(struct cx8800_dev *dev, unsigned int bit) -{ - return (dev->resources & bit); -} - -static -void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) -{ - struct cx88_core *core = dev->core; - BUG_ON((fh->resources & bits) != bits); - - mutex_lock(&core->lock); - fh->resources &= ~bits; - dev->resources &= ~bits; - dprintk(1,"res: put %d\n",bits); - mutex_unlock(&core->lock); -} - /* ------------------------------------------------------------------ */ int cx88_video_mux(struct cx88_core *core, unsigned int input) @@ -419,7 +365,7 @@ static int start_video_dma(struct cx8800_dev *dev, /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], buf->bpl, buf->risc.dma); - cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field); + cx88_set_scale(core, dev->width, dev->height, dev->field); cx_write(MO_COLOR_CTRL, dev->fmt->cxformat | ColorFormatGamma); /* reset counter */ @@ -473,373 +419,206 @@ static int restart_video_queue(struct cx8800_dev *dev, struct cx88_buffer *buf; if (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx88_buffer, list); dprintk(2,"restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); start_video_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) + list_for_each_entry(buf, &q->active, list) buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); } return 0; } /* ------------------------------------------------------------------ */ -static int -buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]) { - struct cx8800_fh *fh = q->priv_data; - struct cx8800_dev *dev = fh->dev; - - *size = dev->fmt->depth * dev->width * dev->height >> 3; - if (0 == *count) - *count = 32; - if (*size * *count > vid_limit * 1024 * 1024) - *count = (vid_limit * 1024 * 1024) / *size; + struct cx8800_dev *dev = q->drv_priv; + + *num_planes = 1; + sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3; return 0; } -static int -buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) +static int buffer_prepare(struct vb2_buffer *vb) { - struct cx8800_fh *fh = q->priv_data; - struct cx8800_dev *dev = fh->dev; + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_core *core = dev->core; - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); int rc; - BUG_ON(NULL == dev->fmt); - if (dev->width < 48 || dev->width > norm_maxw(core->tvnorm) || - dev->height < 32 || dev->height > norm_maxh(core->tvnorm)) - return -EINVAL; - buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) + buf->bpl = dev->width * dev->fmt->depth >> 3; + + if (vb2_plane_size(vb, 0) < dev->height * buf->bpl) return -EINVAL; + vb2_set_plane_payload(vb, 0, dev->height * buf->bpl); - buf->vb.width = dev->width; - buf->vb.height = dev->height; - buf->vb.field = field; - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) - goto fail; - } + rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); + if (!rc) + return -EIO; - buf->bpl = buf->vb.width * dev->fmt->depth >> 3; - switch (buf->vb.field) { + switch (dev->field) { case V4L2_FIELD_TOP: cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, UNSET, - buf->bpl, 0, buf->vb.height); + sgt->sgl, 0, UNSET, + buf->bpl, 0, dev->height); break; case V4L2_FIELD_BOTTOM: cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, UNSET, 0, - buf->bpl, 0, buf->vb.height); + sgt->sgl, UNSET, 0, + buf->bpl, 0, dev->height); break; case V4L2_FIELD_SEQ_TB: cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->bpl * (buf->vb.height >> 1), + sgt->sgl, + 0, buf->bpl * (dev->height >> 1), buf->bpl, 0, - buf->vb.height >> 1); + dev->height >> 1); break; case V4L2_FIELD_SEQ_BT: cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - buf->bpl * (buf->vb.height >> 1), 0, + sgt->sgl, + buf->bpl * (dev->height >> 1), 0, buf->bpl, 0, - buf->vb.height >> 1); + dev->height >> 1); break; case V4L2_FIELD_INTERLACED: default: cx88_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, buf->bpl, + sgt->sgl, 0, buf->bpl, buf->bpl, buf->bpl, - buf->vb.height >> 1); + dev->height >> 1); break; } dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", - buf, buf->vb.i, + buf, buf->vb.v4l2_buf.index, dev->width, dev->height, dev->fmt->depth, dev->fmt->name, (unsigned long)buf->risc.dma); - - buf->vb.state = VIDEOBUF_PREPARED; return 0; +} + +static void buffer_finish(struct vb2_buffer *vb) +{ + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + + cx88_free_buffer(vb->vb2_queue, buf); - fail: - cx88_free_buffer(q,buf); - return rc; + dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } -static void -buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +static void buffer_queue(struct vb2_buffer *vb) { - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_dev *dev = vb->vb2_queue->drv_priv; + struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct cx88_buffer *prev; - struct cx8800_fh *fh = vq->priv_data; - struct cx8800_dev *dev = fh->dev; struct cx88_core *core = dev->core; struct cx88_dmaqueue *q = &dev->vidq; - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); + /* add jump to start */ + buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); + buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); + buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue,&q->active); + list_add_tail(&buf->list, &q->active); start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(2,"[%p/%d] buffer_queue - first active\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); } else { - prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; + buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); + prev = list_entry(q->active.prev, struct cx88_buffer, list); + list_add_tail(&buf->list, &q->active); buf->count = q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk(2, "[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); + buf, buf->vb.v4l2_buf.index); } } -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +static int start_streaming(struct vb2_queue *q, unsigned int count) { - struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); + struct cx8800_dev *dev = q->drv_priv; + struct cx88_dmaqueue *dmaq = &dev->vidq; + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); - cx88_free_buffer(q,buf); + start_video_dma(dev, dmaq, buf); + return 0; } -static const struct videobuf_queue_ops cx8800_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -/* ------------------------------------------------------------------ */ - +static void stop_streaming(struct vb2_queue *q) +{ + struct cx8800_dev *dev = q->drv_priv; + struct cx88_core *core = dev->core; + struct cx88_dmaqueue *dmaq = &dev->vidq; + unsigned long flags; -/* ------------------------------------------------------------------ */ + cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); -static struct videobuf_queue *get_queue(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = file->private_data; + cx_clear(MO_VID_DMACNTRL, 0x11); + cx_clear(VID_CAPTURE_CONTROL, 0x06); + spin_lock_irqsave(&dev->slock, flags); + while (!list_empty(&dmaq->active)) { + struct cx88_buffer *buf = list_entry(dmaq->active.next, + struct cx88_buffer, list); - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - return &fh->vidq; - case VFL_TYPE_VBI: - return &fh->vbiq; - default: - BUG(); + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } + spin_unlock_irqrestore(&dev->slock, flags); } -static int get_resource(struct file *file) -{ - struct video_device *vdev = video_devdata(file); +static struct vb2_ops cx8800_video_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_finish = buffer_finish, + .buf_queue = buffer_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, +}; - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - return RESOURCE_VIDEO; - case VFL_TYPE_VBI: - return RESOURCE_VBI; - default: - BUG(); - } -} +/* ------------------------------------------------------------------ */ -static int video_open(struct file *file) +static int radio_open(struct file *file) { - struct video_device *vdev = video_devdata(file); struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - struct cx8800_fh *fh; - enum v4l2_buf_type type = 0; - int radio = 0; - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - break; - case VFL_TYPE_VBI: - type = V4L2_BUF_TYPE_VBI_CAPTURE; - break; - case VFL_TYPE_RADIO: - radio = 1; - break; - } - - dprintk(1, "open dev=%s radio=%d type=%s\n", - video_device_node_name(vdev), radio, v4l2_type_names[type]); + int ret = v4l2_fh_open(file); - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (unlikely(!fh)) - return -ENOMEM; - - v4l2_fh_init(&fh->fh, vdev); - file->private_data = fh; - fh->dev = dev; - - mutex_lock(&core->lock); + if (ret) + return ret; - videobuf_queue_sg_init(&fh->vidq, &cx8800_video_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx88_buffer), - fh, NULL); - videobuf_queue_sg_init(&fh->vbiq, &cx8800_vbi_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VBI_CAPTURE, - V4L2_FIELD_SEQ_TB, - sizeof(struct cx88_buffer), - fh, NULL); - - if (vdev->vfl_type == VFL_TYPE_RADIO) { - dprintk(1,"video_open: setting radio device\n"); - cx_write(MO_GP3_IO, core->board.radio.gpio3); - cx_write(MO_GP0_IO, core->board.radio.gpio0); - cx_write(MO_GP1_IO, core->board.radio.gpio1); - cx_write(MO_GP2_IO, core->board.radio.gpio2); - if (core->board.radio.audioroute) { - if (core->sd_wm8775) { - call_all(core, audio, s_routing, + cx_write(MO_GP3_IO, core->board.radio.gpio3); + cx_write(MO_GP0_IO, core->board.radio.gpio0); + cx_write(MO_GP1_IO, core->board.radio.gpio1); + cx_write(MO_GP2_IO, core->board.radio.gpio2); + if (core->board.radio.audioroute) { + if (core->sd_wm8775) { + call_all(core, audio, s_routing, core->board.radio.audioroute, 0, 0); - } - /* "I2S ADC mode" */ - core->tvaudio = WW_I2SADC; - cx88_set_tvaudio(core); - } else { - /* FM Mode */ - core->tvaudio = WW_FM; - cx88_set_tvaudio(core); - cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); } - call_all(core, tuner, s_radio); - } - - core->users++; - mutex_unlock(&core->lock); - v4l2_fh_add(&fh->fh); - - return 0; -} - -static ssize_t -video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = file->private_data; - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - if (res_locked(fh->dev,RESOURCE_VIDEO)) - return -EBUSY; - return videobuf_read_one(&fh->vidq, data, count, ppos, - file->f_flags & O_NONBLOCK); - case VFL_TYPE_VBI: - if (!res_get(fh->dev,fh,RESOURCE_VBI)) - return -EBUSY; - return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, - file->f_flags & O_NONBLOCK); - default: - BUG(); - } -} - -static unsigned int -video_poll(struct file *file, struct poll_table_struct *wait) -{ - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = file->private_data; - struct cx88_buffer *buf; - unsigned int rc = v4l2_ctrl_poll(file, wait); - - if (vdev->vfl_type == VFL_TYPE_VBI) { - if (!res_get(fh->dev,fh,RESOURCE_VBI)) - return rc | POLLERR; - return rc | videobuf_poll_stream(file, &fh->vbiq, wait); - } - mutex_lock(&fh->vidq.vb_lock); - if (res_check(fh,RESOURCE_VIDEO)) { - /* streaming capture */ - if (list_empty(&fh->vidq.stream)) - goto done; - buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); + /* "I2S ADC mode" */ + core->tvaudio = WW_I2SADC; + cx88_set_tvaudio(core); } else { - /* read() capture */ - buf = (struct cx88_buffer*)fh->vidq.read_buf; - if (NULL == buf) - goto done; + /* FM Mode */ + core->tvaudio = WW_FM; + cx88_set_tvaudio(core); + cx88_set_stereo(core, V4L2_TUNER_MODE_STEREO, 1); } - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || - buf->vb.state == VIDEOBUF_ERROR) - rc |= POLLIN|POLLRDNORM; -done: - mutex_unlock(&fh->vidq.vb_lock); - return rc; -} - -static int video_release(struct file *file) -{ - struct cx8800_fh *fh = file->private_data; - struct cx8800_dev *dev = fh->dev; - - /* turn off overlay */ - if (res_check(fh, RESOURCE_OVERLAY)) { - /* FIXME */ - res_free(dev,fh,RESOURCE_OVERLAY); - } - - /* stop video capture */ - if (res_check(fh, RESOURCE_VIDEO)) { - videobuf_queue_cancel(&fh->vidq); - res_free(dev,fh,RESOURCE_VIDEO); - } - if (fh->vidq.read_buf) { - buffer_release(&fh->vidq,fh->vidq.read_buf); - kfree(fh->vidq.read_buf); - } - - /* stop vbi capture */ - if (res_check(fh, RESOURCE_VBI)) { - videobuf_stop(&fh->vbiq); - res_free(dev,fh,RESOURCE_VBI); - } - - videobuf_mmap_free(&fh->vidq); - videobuf_mmap_free(&fh->vbiq); - - mutex_lock(&dev->core->lock); - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - file->private_data = NULL; - kfree(fh); - - dev->core->users--; - if (!dev->core->users) - call_all(dev->core, core, s_power, 0); - mutex_unlock(&dev->core->lock); - + call_all(core, tuner, s_radio); return 0; } -static int -video_mmap(struct file *file, struct vm_area_struct * vma) -{ - return videobuf_mmap_mapper(get_queue(file), vma); -} - /* ------------------------------------------------------------------ */ /* VIDEO CTRL IOCTLS */ @@ -942,12 +721,11 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; + struct cx8800_dev *dev = video_drvdata(file); f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; - f->fmt.pix.field = fh->vidq.field; + f->fmt.pix.field = dev->field; f->fmt.pix.pixelformat = dev->fmt->fourcc; f->fmt.pix.bytesperline = (f->fmt.pix.width * dev->fmt->depth) >> 3; @@ -960,7 +738,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; const struct cx8800_fmt *fmt; enum v4l2_field field; unsigned int maxw, maxh; @@ -1004,8 +783,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; + struct cx8800_dev *dev = video_drvdata(file); int err = vidioc_try_fmt_vid_cap (file,priv,f); if (0 != err) @@ -1013,7 +791,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); dev->width = f->fmt.pix.width; dev->height = f->fmt.pix.height; - fh->vidq.field = f->fmt.pix.field; + dev->field = f->fmt.pix.field; return 0; } @@ -1047,8 +825,8 @@ EXPORT_SYMBOL(cx88_querycap); static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct cx8800_dev *dev = ((struct cx8800_fh *)priv)->dev; - struct cx88_core *core = dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; strcpy(cap->driver, "cx8800"); sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); @@ -1068,64 +846,10 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, return 0; } -static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p) -{ - return videobuf_reqbufs(get_queue(file), p); -} - -static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - return videobuf_querybuf(get_queue(file), p); -} - -static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - return videobuf_qbuf(get_queue(file), p); -} - -static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) -{ - return videobuf_dqbuf(get_queue(file), p, - file->f_flags & O_NONBLOCK); -} - -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; - - if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) || - (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - if (unlikely(!res_get(dev, fh, get_resource(file)))) - return -EBUSY; - return videobuf_streamon(get_queue(file)); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct video_device *vdev = video_devdata(file); - struct cx8800_fh *fh = priv; - struct cx8800_dev *dev = fh->dev; - int err, res; - - if ((vdev->vfl_type == VFL_TYPE_GRABBER && i != V4L2_BUF_TYPE_VIDEO_CAPTURE) || - (vdev->vfl_type == VFL_TYPE_VBI && i != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - res = get_resource(file); - err = videobuf_streamoff(get_queue(file)); - if (err < 0) - return err; - res_free(dev,fh,res); - return 0; -} - static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; *tvnorm = core->tvnorm; return 0; @@ -1133,11 +857,10 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; - mutex_lock(&core->lock); cx88_set_tvnorm(core, tvnorms); - mutex_unlock(&core->lock); return 0; } @@ -1176,13 +899,15 @@ EXPORT_SYMBOL(cx88_enum_input); static int vidioc_enum_input (struct file *file, void *priv, struct v4l2_input *i) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; return cx88_enum_input (core,i); } static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; *i = core->input; return 0; @@ -1190,24 +915,24 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) static int vidioc_s_input (struct file *file, void *priv, unsigned int i) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (i >= 4) return -EINVAL; if (0 == INPUT(i).type) return -EINVAL; - mutex_lock(&core->lock); cx88_newstation(core); cx88_video_mux(core,i); - mutex_unlock(&core->lock); return 0; } static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; u32 reg; if (unlikely(UNSET == core->board.tuner_type)) @@ -1229,7 +954,8 @@ static int vidioc_g_tuner (struct file *file, void *priv, static int vidioc_s_tuner (struct file *file, void *priv, const struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (UNSET == core->board.tuner_type) return -EINVAL; @@ -1243,8 +969,8 @@ static int vidioc_s_tuner (struct file *file, void *priv, static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct cx8800_fh *fh = priv; - struct cx88_core *core = fh->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; @@ -1268,7 +994,6 @@ int cx88_set_freq (struct cx88_core *core, if (unlikely(f->tuner != 0)) return -EINVAL; - mutex_lock(&core->lock); cx88_newstation(core); call_all(core, tuner, s_frequency, f); call_all(core, tuner, g_frequency, &new_freq); @@ -1278,8 +1003,6 @@ int cx88_set_freq (struct cx88_core *core, msleep (10); cx88_set_tvaudio(core); - mutex_unlock(&core->lock); - return 0; } EXPORT_SYMBOL(cx88_set_freq); @@ -1287,8 +1010,8 @@ EXPORT_SYMBOL(cx88_set_freq); static int vidioc_s_frequency (struct file *file, void *priv, const struct v4l2_frequency *f) { - struct cx8800_fh *fh = priv; - struct cx88_core *core = fh->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; return cx88_set_freq(core, f); } @@ -1297,7 +1020,8 @@ static int vidioc_s_frequency (struct file *file, void *priv, static int vidioc_g_register (struct file *file, void *fh, struct v4l2_dbg_register *reg) { - struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; /* cx2388x has a 24-bit register space */ reg->val = cx_read(reg->reg & 0xfffffc); @@ -1308,7 +1032,8 @@ static int vidioc_g_register (struct file *file, void *fh, static int vidioc_s_register (struct file *file, void *fh, const struct v4l2_dbg_register *reg) { - struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; cx_write(reg->reg & 0xfffffc, reg->val); return 0; @@ -1322,7 +1047,8 @@ static int vidioc_s_register (struct file *file, void *fh, static int radio_g_tuner (struct file *file, void *priv, struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (unlikely(t->index > 0)) return -EINVAL; @@ -1336,7 +1062,8 @@ static int radio_g_tuner (struct file *file, void *priv, static int radio_s_tuner (struct file *file, void *priv, const struct v4l2_tuner *t) { - struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; + struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; if (0 != t->index) return -EINVAL; @@ -1347,32 +1074,6 @@ static int radio_s_tuner (struct file *file, void *priv, /* ----------------------------------------------------------- */ -static void cx8800_vid_timeout(unsigned long data) -{ - struct cx8800_dev *dev = (struct cx8800_dev*)data; - struct cx88_core *core = dev->core; - struct cx88_dmaqueue *q = &dev->vidq; - struct cx88_buffer *buf; - unsigned long flags; - - cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); - - cx_clear(MO_VID_DMACNTRL, 0x11); - cx_clear(VID_CAPTURE_CONTROL, 0x06); - - spin_lock_irqsave(&dev->slock,flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name, - buf, buf->vb.i, (unsigned long)buf->risc.dma); - } - restart_video_queue(dev,q); - spin_unlock_irqrestore(&dev->slock,flags); -} - static const char *cx88_vid_irqs[32] = { "y_risci1", "u_risci1", "v_risci1", "vbi_risc1", "y_risci2", "u_risci2", "v_risci2", "vbi_risc2", @@ -1419,22 +1120,6 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) cx88_wakeup(core, &dev->vbiq, count); spin_unlock(&dev->slock); } - - /* risc2 y */ - if (status & 0x10) { - dprintk(2,"stopper video\n"); - spin_lock(&dev->slock); - restart_video_queue(dev,&dev->vidq); - spin_unlock(&dev->slock); - } - - /* risc2 vbi */ - if (status & 0x80) { - dprintk(2,"stopper vbi\n"); - spin_lock(&dev->slock); - cx8800_restart_vbi_queue(dev,&dev->vbiq); - spin_unlock(&dev->slock); - } } static irqreturn_t cx8800_irq(int irq, void *dev_id) @@ -1473,11 +1158,11 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id) static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .read = video_read, - .poll = video_poll, - .mmap = video_mmap, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; @@ -1487,17 +1172,17 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_g_std = vidioc_g_std, .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, @@ -1522,17 +1207,17 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = { .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt, .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt, .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_g_std = vidioc_g_std, .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, @@ -1553,9 +1238,9 @@ static const struct video_device cx8800_vbi_template = { static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, - .open = video_open, + .open = radio_open, .poll = v4l2_ctrl_poll, - .release = video_release, + .release = v4l2_fh_release, .unlocked_ioctl = video_ioctl2, }; @@ -1619,6 +1304,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, { struct cx8800_dev *dev; struct cx88_core *core; + struct vb2_queue *q; int err; int i; @@ -1660,19 +1346,9 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); - dev->vidq.timeout.function = cx8800_vid_timeout; - dev->vidq.timeout.data = (unsigned long)dev; - init_timer(&dev->vidq.timeout); - cx88_risc_stopper(dev->pci,&dev->vidq.stopper, - MO_VID_DMACNTRL,0x11,0x00); /* init vbi dma queues */ INIT_LIST_HEAD(&dev->vbiq.active); - dev->vbiq.timeout.function = cx8800_vbi_timeout; - dev->vbiq.timeout.data = (unsigned long)dev; - init_timer(&dev->vbiq.timeout); - cx88_risc_stopper(dev->pci,&dev->vbiq.stopper, - MO_VID_DMACNTRL,0x88,0x00); /* get irq */ err = request_irq(pci_dev->irq, cx8800_irq, @@ -1763,6 +1439,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, dev->width = 320; dev->height = 240; + dev->field = V4L2_FIELD_INTERLACED; dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); /* initial device configuration */ @@ -1772,11 +1449,44 @@ static int cx8800_initdev(struct pci_dev *pci_dev, v4l2_ctrl_handler_setup(&core->audio_hdl); cx88_video_mux(core, 0); + q = &dev->vb2_vidq; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->gfp_flags = GFP_DMA32; + q->min_buffers_needed = 2; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx88_buffer); + q->ops = &cx8800_video_qops; + q->mem_ops = &vb2_dma_sg_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &core->lock; + + err = vb2_queue_init(q); + if (err < 0) + goto fail_unreg; + + q = &dev->vb2_vbiq; + q->type = V4L2_BUF_TYPE_VBI_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->gfp_flags = GFP_DMA32; + q->min_buffers_needed = 2; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx88_buffer); + q->ops = &cx8800_vbi_qops; + q->mem_ops = &vb2_dma_sg_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &core->lock; + + err = vb2_queue_init(q); + if (err < 0) + goto fail_unreg; + /* register v4l devices */ dev->video_dev = cx88_vdev_init(core,dev->pci, &cx8800_video_template,"video"); video_set_drvdata(dev->video_dev, dev); dev->video_dev->ctrl_handler = &core->video_hdl; + dev->video_dev->queue = &dev->vb2_vidq; err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[core->nr]); if (err < 0) { @@ -1789,6 +1499,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); video_set_drvdata(dev->vbi_dev, dev); + dev->vbi_dev->queue = &dev->vb2_vbiq; err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[core->nr]); if (err < 0) { @@ -1862,7 +1573,6 @@ static void cx8800_finidev(struct pci_dev *pci_dev) cx8800_unregister_video(dev); /* free memory */ - btcx_riscmem_free(dev->pci,&dev->vidq.stopper); cx88_core_put(core,dev->pci); kfree(dev); } @@ -1879,12 +1589,10 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) if (!list_empty(&dev->vidq.active)) { printk("%s/0: suspend video\n", core->name); stop_video_dma(dev); - del_timer(&dev->vidq.timeout); } if (!list_empty(&dev->vbiq.active)) { printk("%s/0: suspend vbi\n", core->name); cx8800_stop_vbi_dma(dev); - del_timer(&dev->vbiq.timeout); } spin_unlock_irqrestore(&dev->slock, flags); diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 77ec5427a986..2dadaa6f0d95 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -29,9 +29,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include @@ -41,7 +41,7 @@ #include -#define CX88_VERSION "0.0.9" +#define CX88_VERSION "1.0.0" #define UNSET (-1U) @@ -95,13 +95,13 @@ enum cx8802_board_access { static inline unsigned int norm_maxw(v4l2_std_id norm) { - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; + return 720; } static inline unsigned int norm_maxh(v4l2_std_id norm) { - return (norm & V4L2_STD_625_50) ? 576 : 480; + return (norm & V4L2_STD_525_60) ? 480 : 576; } /* ----------------------------------------------------------- */ @@ -314,7 +314,8 @@ enum cx88_tvaudio { /* buffer for one video frame */ struct cx88_buffer { /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; + struct vb2_buffer vb; + struct list_head list; /* cx88 specific */ unsigned int bpl; @@ -324,8 +325,6 @@ struct cx88_buffer { struct cx88_dmaqueue { struct list_head active; - struct timer_list timeout; - struct btcx_riscmem stopper; u32 count; }; @@ -393,8 +392,6 @@ struct cx88_core { struct mutex lock; /* various v4l controls */ u32 freq; - int users; - int mpeg_users; /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ struct cx8802_dev *dvbdev; @@ -457,18 +454,6 @@ struct cx8802_dev; /* ----------------------------------------------------------- */ /* function 0: video stuff */ -struct cx8800_fh { - struct v4l2_fh fh; - struct cx8800_dev *dev; - unsigned int resources; - - /* video capture */ - struct videobuf_queue vidq; - - /* vbi capture */ - struct videobuf_queue vbiq; -}; - struct cx8800_suspend_state { int disabled; }; @@ -489,10 +474,13 @@ struct cx8800_dev { const struct cx8800_fmt *fmt; unsigned int width, height; + unsigned field; /* capture queues */ struct cx88_dmaqueue vidq; + struct vb2_queue vb2_vidq; struct cx88_dmaqueue vbiq; + struct vb2_queue vb2_vbiq; /* various v4l controls */ @@ -508,12 +496,6 @@ struct cx8800_dev { /* ----------------------------------------------------------- */ /* function 2: mpeg stuff */ -struct cx8802_fh { - struct v4l2_fh fh; - struct cx8802_dev *dev; - struct videobuf_queue mpegq; -}; - struct cx8802_suspend_state { int disabled; }; @@ -557,6 +539,7 @@ struct cx8802_dev { /* dma queues */ struct cx88_dmaqueue mpegq; + struct vb2_queue vb2_mpegq; u32 ts_packet_size; u32 ts_packet_count; @@ -570,6 +553,7 @@ struct cx8802_dev { u32 mailbox; int width; int height; + unsigned field; unsigned char mpeg_active; /* nonzero if mpeg encoder is active */ /* mpeg params */ @@ -578,7 +562,7 @@ struct cx8802_dev { #if IS_ENABLED(CONFIG_VIDEO_CX88_DVB) /* for dvb only */ - struct videobuf_dvb_frontends frontends; + struct vb2_dvb_frontends frontends; #endif #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) @@ -640,11 +624,8 @@ extern int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, unsigned int lines, unsigned int lpi); -extern int -cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value); extern void -cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf); +cx88_free_buffer(struct vb2_queue *q, struct cx88_buffer *buf); extern void cx88_risc_disasm(struct cx88_core *core, struct btcx_riscmem *risc); @@ -662,7 +643,7 @@ extern struct video_device *cx88_vdev_init(struct cx88_core *core, struct pci_dev *pci, const struct video_device *template_, const char *type); -extern struct cx88_core* cx88_core_get(struct pci_dev *pci); +extern struct cx88_core *cx88_core_get(struct pci_dev *pci); extern void cx88_core_put(struct cx88_core *core, struct pci_dev *pci); @@ -682,12 +663,10 @@ int cx8800_start_vbi_dma(struct cx8800_dev *dev, struct cx88_dmaqueue *q, struct cx88_buffer *buf); */ -int cx8800_stop_vbi_dma(struct cx8800_dev *dev); -int cx8800_restart_vbi_queue(struct cx8800_dev *dev, - struct cx88_dmaqueue *q); -void cx8800_vbi_timeout(unsigned long data); +void cx8800_stop_vbi_dma(struct cx8800_dev *dev); +int cx8800_restart_vbi_queue(struct cx8800_dev *dev, struct cx88_dmaqueue *q); -extern const struct videobuf_queue_ops cx8800_vbi_qops; +extern const struct vb2_ops cx8800_vbi_qops; /* ----------------------------------------------------------- */ /* cx88-i2c.c */ @@ -737,14 +716,17 @@ extern void cx88_i2c_init_ir(struct cx88_core *core); /* ----------------------------------------------------------- */ /* cx88-mpeg.c */ -int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev, +int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, struct cx88_buffer *buf, enum v4l2_field field); void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); void cx8802_cancel_buffers(struct cx8802_dev *dev); +int cx8802_start_dma(struct cx8802_dev *dev, + struct cx88_dmaqueue *q, + struct cx88_buffer *buf); /* ----------------------------------------------------------- */ /* cx88-video.c*/ -int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i); +int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i); int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f); int cx88_video_mux(struct cx88_core *core, unsigned int input); void cx88_querycap(struct file *file, struct cx88_core *core, -- GitLab From c79a23f33dc1868a90ca6cb0bee0228c751bb7ea Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:20:44 -0300 Subject: [PATCH 2451/9457] [media] cx88: fix sparse warning drivers/media/pci/cx88/cx88-blackbird.c:476:25: warning: cast to restricted __le32 Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 25d06f36e0ef..32abba47a937 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -428,7 +428,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) int i, retval = 0; u32 value = 0; u32 checksum = 0; - u32 *dataptr; + __le32 *dataptr; retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); @@ -467,7 +467,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) /* transfer to the chip */ dprintk(1,"Loading firmware ...\n"); - dataptr = (u32*)firmware->data; + dataptr = (__le32 *)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { value = le32_to_cpu(*dataptr); checksum += ~value; -- GitLab From eddd3263208e3e4f80665bbec9d16f02c98986e8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:29:19 -0300 Subject: [PATCH 2452/9457] [media] cx88: return proper errors during fw load Don't return -1, return a proper error. Replace dprintk(0, ...) by pr_err since firmware load errors should just be reported as an error. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 32abba47a937..11054cd903af 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -322,13 +322,13 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat memory_read(dev->core, dev->mailbox - 4, &value); if (value != 0x12345678) { dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n"); - return -1; + return -EIO; } memory_read(dev->core, dev->mailbox, &flag); if (flag) { dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag); - return -1; + return -EIO; } flag |= 1; /* tell 'em we're working on it */ @@ -354,8 +354,8 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat if (0 != (flag & 4)) break; if (time_after(jiffies,timeout)) { - dprintk(0, "ERROR: API Mailbox timeout\n"); - return -1; + dprintk(0, "ERROR: API Mailbox timeout %x\n", command); + return -EIO; } udelay(10); } @@ -416,7 +416,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev) } } dprintk(0, "Mailbox signature values not found!\n"); - return -1; + return -EIO; } static int blackbird_load_firmware(struct cx8802_dev *dev) @@ -445,24 +445,23 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) if (retval != 0) { - dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", + pr_err("Hotplug firmware request failed (%s).\n", CX2341X_FIRM_ENC_FILENAME); - dprintk(0, "Please fix your hotplug setup, the board will " - "not work without firmware loaded!\n"); - return -1; + pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + return -EIO; } if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { - dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", + pr_err("Firmware size mismatch (have %zd, expected %d)\n", firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); release_firmware(firmware); - return -1; + return -EINVAL; } if (0 != memcmp(firmware->data, magic, 8)) { - dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); + pr_err("Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); - return -1; + return -EINVAL; } /* transfer to the chip */ @@ -480,12 +479,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) memory_read(dev->core, i, &value); checksum -= ~value; } + release_firmware(firmware); if (checksum) { - dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n"); - release_firmware(firmware); - return -1; + pr_err("Firmware load might have failed (checksum mismatch).\n"); + return -EIO; } - release_firmware(firmware); dprintk(0, "Firmware upload successful.\n"); retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); -- GitLab From 999b3ceb849b5b9ed25739fea2e69adef09845c7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:40:47 -0300 Subject: [PATCH 2453/9457] [media] cx88: drop cx88_free_buffer Remove this function. This makes all vb2 queues behave the same, which simplifies comparing the various vb2 queue op implementations. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 2 +- drivers/media/pci/cx88/cx88-core.c | 7 ------- drivers/media/pci/cx88/cx88-dvb.c | 2 +- drivers/media/pci/cx88/cx88-mpeg.c | 6 +++++- drivers/media/pci/cx88/cx88-vbi.c | 2 +- drivers/media/pci/cx88/cx88-video.c | 2 +- drivers/media/pci/cx88/cx88.h | 2 -- 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 11054cd903af..b24266ec2b5d 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -667,7 +667,7 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - cx88_free_buffer(vb->vb2_queue, buf); + btcx_riscmem_free(dev->pci, &buf->risc); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index f02740860970..902b662be2ff 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -198,12 +198,6 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, return 0; } -void -cx88_free_buffer(struct vb2_queue *q, struct cx88_buffer *buf) -{ - btcx_riscmem_free(to_pci_dev(q->drv_priv), &buf->risc); -} - /* ------------------------------------------------------------------ */ /* our SRAM memory layout */ @@ -1072,7 +1066,6 @@ EXPORT_SYMBOL(cx88_shutdown); EXPORT_SYMBOL(cx88_risc_buffer); EXPORT_SYMBOL(cx88_risc_databuffer); -EXPORT_SYMBOL(cx88_free_buffer); EXPORT_SYMBOL(cx88_sram_channels); EXPORT_SYMBOL(cx88_sram_channel_setup); diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index d7e5c45022c9..b5b88a64ad7f 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -110,7 +110,7 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - cx88_free_buffer(vb->vb2_queue, buf); + btcx_riscmem_free(dev->pci, &buf->risc); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 7986ee037b83..0589dccae3bd 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -238,8 +238,12 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, if (!rc) return -EIO; - cx88_risc_databuffer(dev->pci, &buf->risc, sgt->sgl, + rc = cx88_risc_databuffer(dev->pci, &buf->risc, sgt->sgl, dev->ts_packet_size, dev->ts_packet_count, 0); + if (rc) { + btcx_riscmem_free(dev->pci, &buf->risc); + return rc; + } return 0; } diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 26a15331cc10..8f20612c5853 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -147,7 +147,7 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - cx88_free_buffer(vb->vb2_queue, buf); + btcx_riscmem_free(dev->pci, &buf->risc); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 9887da52c455..c64f8f48850f 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -506,7 +506,7 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); - cx88_free_buffer(vb->vb2_queue, buf); + btcx_riscmem_free(dev->pci, &buf->risc); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 2dadaa6f0d95..16965c84090b 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -624,8 +624,6 @@ extern int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, unsigned int lines, unsigned int lpi); -extern void -cx88_free_buffer(struct vb2_queue *q, struct cx88_buffer *buf); extern void cx88_risc_disasm(struct cx88_core *core, struct btcx_riscmem *risc); -- GitLab From 5e7045e3fa4976a37c6bbf337729ea47d0c886d0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 04:11:54 -0300 Subject: [PATCH 2454/9457] [media] cx88: remove dependency on btcx-risc btcx-risc is for the bt8xx driver and other drivers shouldn't depend on it. There is no benefit to use that module just to do a pci_zalloc_consistent. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/Kconfig | 1 - drivers/media/pci/cx88/Makefile | 1 - drivers/media/pci/cx88/cx88-alsa.c | 7 +++++-- drivers/media/pci/cx88/cx88-blackbird.c | 5 ++++- drivers/media/pci/cx88/cx88-core.c | 20 ++++++++++++-------- drivers/media/pci/cx88/cx88-dvb.c | 5 ++++- drivers/media/pci/cx88/cx88-mpeg.c | 7 +++++-- drivers/media/pci/cx88/cx88-vbi.c | 5 ++++- drivers/media/pci/cx88/cx88-video.c | 5 ++++- drivers/media/pci/cx88/cx88.h | 16 +++++++++++----- 10 files changed, 49 insertions(+), 23 deletions(-) diff --git a/drivers/media/pci/cx88/Kconfig b/drivers/media/pci/cx88/Kconfig index d5b125e4ab02..14b813d634a8 100644 --- a/drivers/media/pci/cx88/Kconfig +++ b/drivers/media/pci/cx88/Kconfig @@ -2,7 +2,6 @@ config VIDEO_CX88 tristate "Conexant 2388x (bt878 successor) support" depends on VIDEO_DEV && PCI && I2C && RC_CORE select I2C_ALGOBIT - select VIDEO_BTCX select VIDEOBUF2_DMA_SG select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/pci/cx88/Makefile b/drivers/media/pci/cx88/Makefile index 8619c1becee2..d3679c3ee248 100644 --- a/drivers/media/pci/cx88/Makefile +++ b/drivers/media/pci/cx88/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o ccflags-y += -Idrivers/media/i2c -ccflags-y += -Idrivers/media/common ccflags-y += -Idrivers/media/tuners ccflags-y += -Idrivers/media/dvb-core ccflags-y += -Idrivers/media/dvb-frontends diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 73021a22de1b..7f8dc60028d5 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -61,7 +61,7 @@ struct cx88_audio_buffer { unsigned int bpl; - struct btcx_riscmem risc; + struct cx88_riscmem risc; void *vaddr; struct scatterlist *sglist; int sglen; @@ -370,12 +370,15 @@ static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf) static int dsp_buffer_free(snd_cx88_card_t *chip) { + struct cx88_riscmem *risc = &chip->buf->risc; + BUG_ON(!chip->dma_size); dprintk(2,"Freeing buffer\n"); cx88_alsa_dma_unmap(chip); cx88_alsa_dma_free(chip->buf); - btcx_riscmem_free(chip->pci, &chip->buf->risc); + if (risc->cpu) + pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma); kfree(chip->buf); chip->buf = NULL; diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index b24266ec2b5d..f27a3f134025 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -666,8 +666,11 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + struct cx88_riscmem *risc = &buf->risc; - btcx_riscmem_free(dev->pci, &buf->risc); + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 902b662be2ff..bbdbb58576ef 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -132,14 +132,13 @@ static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, return rp; } -int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, +int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int top_offset, unsigned int bottom_offset, unsigned int bpl, unsigned int padding, unsigned int lines) { u32 instructions,fields; __le32 *rp; - int rc; fields = 0; if (UNSET != top_offset) @@ -153,8 +152,11 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, region may be smaller than PAGE_SIZE */ instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines); instructions += 4; - if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) - return rc; + risc->size = instructions * 8; + risc->dma = 0; + risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); + if (NULL == risc->cpu) + return -ENOMEM; /* write risc instructions */ rp = risc->cpu; @@ -171,13 +173,12 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, return 0; } -int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, +int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, unsigned int lines, unsigned int lpi) { u32 instructions; __le32 *rp; - int rc; /* estimate risc mem: worst case is one write per page border + one write per scan line + syncs + jump (all 2 dwords). Here @@ -185,8 +186,11 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, than PAGE_SIZE */ instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; instructions += 3; - if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) - return rc; + risc->size = instructions * 8; + risc->dma = 0; + risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); + if (NULL == risc->cpu) + return -ENOMEM; /* write risc instructions */ rp = risc->cpu; diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index b5b88a64ad7f..dd0deb1c87ce 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -109,8 +109,11 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + struct cx88_riscmem *risc = &buf->risc; - btcx_riscmem_free(dev->pci, &buf->risc); + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 0589dccae3bd..746c0ea13035 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -228,6 +228,7 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, { int size = dev->ts_packet_size * dev->ts_packet_count; struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0); + struct cx88_riscmem *risc = &buf->risc; int rc; if (vb2_plane_size(&buf->vb, 0) < size) @@ -238,10 +239,12 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, if (!rc) return -EIO; - rc = cx88_risc_databuffer(dev->pci, &buf->risc, sgt->sgl, + rc = cx88_risc_databuffer(dev->pci, risc, sgt->sgl, dev->ts_packet_size, dev->ts_packet_count, 0); if (rc) { - btcx_riscmem_free(dev->pci, &buf->risc); + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); return rc; } return 0; diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 8f20612c5853..4e0747a6a9c2 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -146,8 +146,11 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + struct cx88_riscmem *risc = &buf->risc; - btcx_riscmem_free(dev->pci, &buf->risc); + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index c64f8f48850f..a74e21dd4aad 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -505,8 +505,11 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + struct cx88_riscmem *risc = &buf->risc; - btcx_riscmem_free(dev->pci, &buf->risc); + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 16965c84090b..dd50177cea1e 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -35,7 +35,6 @@ #include #include -#include "btcx-risc.h" #include "cx88-reg.h" #include "tuner-xc2028.h" @@ -311,6 +310,13 @@ enum cx88_tvaudio { #define BUFFER_TIMEOUT msecs_to_jiffies(2000) +struct cx88_riscmem { + unsigned int size; + __le32 *cpu; + __le32 *jmp; + dma_addr_t dma; +}; + /* buffer for one video frame */ struct cx88_buffer { /* common v4l buffer stuff -- must be first */ @@ -319,7 +325,7 @@ struct cx88_buffer { /* cx88 specific */ unsigned int bpl; - struct btcx_riscmem risc; + struct cx88_riscmem risc; u32 count; }; @@ -616,17 +622,17 @@ extern void cx88_shutdown(struct cx88_core *core); extern int cx88_reset(struct cx88_core *core); extern int -cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, +cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int top_offset, unsigned int bottom_offset, unsigned int bpl, unsigned int padding, unsigned int lines); extern int -cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, +cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, unsigned int lines, unsigned int lpi); extern void cx88_risc_disasm(struct cx88_core *core, - struct btcx_riscmem *risc); + struct cx88_riscmem *risc); extern int cx88_sram_channel_setup(struct cx88_core *core, const struct sram_channel *ch, unsigned int bpl, u32 risc); -- GitLab From b8f884164bdfbcecf61e891b52d8a03fec9ed461 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:45:59 -0300 Subject: [PATCH 2455/9457] [media] cx88: increase API command timeout The timeout is way too small. Especially complicated command like CX2341X_ENC_STOP_CAPTURE takes much more time than 10 ms. Increase the timeout to 1 second, just as ivtv does (the cx88-blackbird has the same IP core for MPEG compression as ivtv). This solves a nasty issue where STOP_CAPTURE would timeout and the mailbox is left in a busy state, making it impossible to start streaming a second time without reloading the driver first. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index f27a3f134025..32fb9355c9f6 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -348,7 +348,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat memory_write(dev->core, dev->mailbox, flag); /* wait for firmware to handle the API command */ - timeout = jiffies + msecs_to_jiffies(10); + timeout = jiffies + msecs_to_jiffies(1000); for (;;) { memory_read(dev->core, dev->mailbox, &flag); if (0 != (flag & 4)) -- GitLab From d386259f8ee95d260ecb99aad3afc434819491ec Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 05:50:26 -0300 Subject: [PATCH 2456/9457] [media] cx88: don't pollute the kernel log There is no reason to dump the sram code to the kernel log when you stop streaming. Remove those calls to cx88_sram_channel_dump. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-vbi.c | 2 -- drivers/media/pci/cx88/cx88-video.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 4e0747a6a9c2..042f54597a9b 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -203,8 +203,6 @@ static void stop_streaming(struct vb2_queue *q) struct cx88_dmaqueue *dmaq = &dev->vbiq; unsigned long flags; - cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); - cx_clear(MO_VID_DMACNTRL, 0x11); cx_clear(VID_CAPTURE_CONTROL, 0x06); cx8800_stop_vbi_dma(dev); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index a74e21dd4aad..85c3d0c4df97 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -563,8 +563,6 @@ static void stop_streaming(struct vb2_queue *q) struct cx88_dmaqueue *dmaq = &dev->vidq; unsigned long flags; - cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); - cx_clear(MO_VID_DMACNTRL, 0x11); cx_clear(VID_CAPTURE_CONTROL, 0x06); spin_lock_irqsave(&dev->slock, flags); -- GitLab From ccd6f1d488e7e49ca90d4255cb3f8a2f61951e55 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 20 Sep 2014 09:23:44 -0300 Subject: [PATCH 2457/9457] [media] cx88: move width, height and field to core struct The width, height and field values are core fields since both vbi, video and blackbird use the same video input. Move those fields to the correct struct. Also fix the field checks in the try_fmt functions: add V4L2_FIELD_SEQ_BT/TB support and map incorrect field values to a correct field value instead of returning an error. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 85 +++++++++++++++---------- drivers/media/pci/cx88/cx88-cards.c | 5 ++ drivers/media/pci/cx88/cx88-dvb.c | 2 +- drivers/media/pci/cx88/cx88-mpeg.c | 4 +- drivers/media/pci/cx88/cx88-video.c | 75 +++++++++++----------- drivers/media/pci/cx88/cx88.h | 9 +-- 6 files changed, 98 insertions(+), 82 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 32fb9355c9f6..58e5254e154a 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -515,12 +515,14 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M static void blackbird_codec_settings(struct cx8802_dev *dev) { + struct cx88_core *core = dev->core; + /* assign frame size */ blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - dev->height, dev->width); + core->height, core->width); - dev->cxhdl.width = dev->width; - dev->cxhdl.height = dev->height; + dev->cxhdl.width = core->width; + dev->cxhdl.height = core->height; cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50); cx2341x_handler_setup(&dev->cxhdl); } @@ -658,7 +660,7 @@ static int buffer_prepare(struct vb2_buffer *vb) struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field); + return cx8802_buf_prepare(vb->vb2_queue, dev, buf); } static void buffer_finish(struct vb2_buffer *vb) @@ -796,55 +798,75 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - f->fmt.pix.width = dev->width; - f->fmt.pix.height = dev->height; - f->fmt.pix.field = dev->field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->width, dev->height, dev->field); + f->fmt.pix.width = core->width; + f->fmt.pix.height = core->height; + f->fmt.pix.field = core->field; return 0; } -static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; + unsigned maxw, maxh; + enum v4l2_field field; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->width, dev->height, dev->field); + + maxw = norm_maxw(core->tvnorm); + maxh = norm_maxh(core->tvnorm); + + field = f->fmt.pix.field; + + switch (field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_BT: + case V4L2_FIELD_SEQ_TB: + break; + default: + field = (f->fmt.pix.height > maxh / 2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_BOTTOM; + break; + } + if (V4L2_FIELD_HAS_T_OR_B(field)) + maxh /= 2; + + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); + f->fmt.pix.field = field; return 0; } -static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - dev->width = f->fmt.pix.width; - dev->height = f->fmt.pix.height; - dev->field = f->fmt.pix.field; + vidioc_try_fmt_vid_cap(file, priv, f); + core->width = f->fmt.pix.width; + core->height = f->fmt.pix.height; + core->field = f->fmt.pix.field; cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, f->fmt.pix.height, f->fmt.pix.width); - dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field ); return 0; } @@ -863,8 +885,8 @@ static int vidioc_s_frequency (struct file *file, void *priv, cx88_set_freq (core,f); blackbird_initialize_codec(dev); - cx88_set_scale(dev->core, dev->width, dev->height, - dev->field); + cx88_set_scale(core, core->width, core->height, + core->field); return 0; } @@ -1128,16 +1150,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD)) goto fail_core; - dev->width = 720; - if (core->tvnorm & V4L2_STD_525_60) { - dev->height = 480; - } else { - dev->height = 576; - } - dev->field = V4L2_FIELD_INTERLACED; dev->cxhdl.port = CX2341X_PORT_STREAMING; - dev->cxhdl.width = dev->width; - dev->cxhdl.height = dev->height; + dev->cxhdl.width = core->width; + dev->cxhdl.height = core->height; dev->cxhdl.func = blackbird_mbox_func; dev->cxhdl.priv = dev; err = cx2341x_handler_init(&dev->cxhdl, 36); @@ -1156,7 +1171,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) // init_controls(core); cx88_set_tvnorm(core,core->tvnorm); cx88_video_mux(core,0); - cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576); + cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576); cx2341x_handler_setup(&dev->cxhdl); q = &dev->vb2_mpegq; diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 851754bf1291..6db654990263 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -3691,6 +3691,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) core->nr = nr; sprintf(core->name, "cx88[%d]", core->nr); + core->tvnorm = V4L2_STD_NTSC_M; + core->width = 320; + core->height = 240; + core->field = V4L2_FIELD_INTERLACED; + strcpy(core->v4l2_dev.name, core->name); if (v4l2_device_register(NULL, &core->v4l2_dev)) { kfree(core); diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index dd0deb1c87ce..c344bfd0b896 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -101,7 +101,7 @@ static int buffer_prepare(struct vb2_buffer *vb) struct cx8802_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); - return cx8802_buf_prepare(vb->vb2_queue, dev, buf, dev->field); + return cx8802_buf_prepare(vb->vb2_queue, dev, buf); } static void buffer_finish(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 746c0ea13035..f181a3a10389 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -93,7 +93,7 @@ int cx8802_start_dma(struct cx8802_dev *dev, struct cx88_core *core = dev->core; dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", - dev->width, dev->height, dev->field); + core->width, core->height, core->field); /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], @@ -224,7 +224,7 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, /* ------------------------------------------------------------------ */ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf, enum v4l2_field field) + struct cx88_buffer *buf) { int size = dev->ts_packet_size * dev->ts_packet_count; struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0); diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 85c3d0c4df97..eadceebfed8e 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -365,7 +365,7 @@ static int start_video_dma(struct cx8800_dev *dev, /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], buf->bpl, buf->risc.dma); - cx88_set_scale(core, dev->width, dev->height, dev->field); + cx88_set_scale(core, core->width, core->height, core->field); cx_write(MO_COLOR_CTRL, dev->fmt->cxformat | ColorFormatGamma); /* reset counter */ @@ -436,9 +436,10 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int sizes[], void *alloc_ctxs[]) { struct cx8800_dev *dev = q->drv_priv; + struct cx88_core *core = dev->core; *num_planes = 1; - sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3; + sizes[0] = (dev->fmt->depth * core->width * core->height) >> 3; return 0; } @@ -450,52 +451,52 @@ static int buffer_prepare(struct vb2_buffer *vb) struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); int rc; - buf->bpl = dev->width * dev->fmt->depth >> 3; + buf->bpl = core->width * dev->fmt->depth >> 3; - if (vb2_plane_size(vb, 0) < dev->height * buf->bpl) + if (vb2_plane_size(vb, 0) < core->height * buf->bpl) return -EINVAL; - vb2_set_plane_payload(vb, 0, dev->height * buf->bpl); + vb2_set_plane_payload(vb, 0, core->height * buf->bpl); rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); if (!rc) return -EIO; - switch (dev->field) { + switch (core->field) { case V4L2_FIELD_TOP: cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, 0, UNSET, - buf->bpl, 0, dev->height); + buf->bpl, 0, core->height); break; case V4L2_FIELD_BOTTOM: cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, UNSET, 0, - buf->bpl, 0, dev->height); + buf->bpl, 0, core->height); break; case V4L2_FIELD_SEQ_TB: cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, - 0, buf->bpl * (dev->height >> 1), + 0, buf->bpl * (core->height >> 1), buf->bpl, 0, - dev->height >> 1); + core->height >> 1); break; case V4L2_FIELD_SEQ_BT: cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, - buf->bpl * (dev->height >> 1), 0, + buf->bpl * (core->height >> 1), 0, buf->bpl, 0, - dev->height >> 1); + core->height >> 1); break; case V4L2_FIELD_INTERLACED: default: cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, 0, buf->bpl, buf->bpl, buf->bpl, - dev->height >> 1); + core->height >> 1); break; } dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", buf, buf->vb.v4l2_buf.index, - dev->width, dev->height, dev->fmt->depth, dev->fmt->name, + core->width, core->height, dev->fmt->depth, dev->fmt->name, (unsigned long)buf->risc.dma); return 0; } @@ -723,10 +724,11 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; - f->fmt.pix.width = dev->width; - f->fmt.pix.height = dev->height; - f->fmt.pix.field = dev->field; + f->fmt.pix.width = core->width; + f->fmt.pix.height = core->height; + f->fmt.pix.field = core->field; f->fmt.pix.pixelformat = dev->fmt->fourcc; f->fmt.pix.bytesperline = (f->fmt.pix.width * dev->fmt->depth) >> 3; @@ -749,30 +751,30 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, if (NULL == fmt) return -EINVAL; - field = f->fmt.pix.field; - maxw = norm_maxw(core->tvnorm); - maxh = norm_maxh(core->tvnorm); + maxw = norm_maxw(core->tvnorm); + maxh = norm_maxh(core->tvnorm); - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } + field = f->fmt.pix.field; switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; case V4L2_FIELD_INTERLACED: + case V4L2_FIELD_SEQ_BT: + case V4L2_FIELD_SEQ_TB: break; default: - return -EINVAL; + field = (f->fmt.pix.height > maxh / 2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_BOTTOM; + break; } + if (V4L2_FIELD_HAS_T_OR_B(field)) + maxh /= 2; - f->fmt.pix.field = field; v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, &f->fmt.pix.height, 32, maxh, 0, 0); + f->fmt.pix.field = field; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = @@ -785,14 +787,15 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_dev *dev = video_drvdata(file); + struct cx88_core *core = dev->core; int err = vidioc_try_fmt_vid_cap (file,priv,f); if (0 != err) return err; - dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - dev->width = f->fmt.pix.width; - dev->height = f->fmt.pix.height; - dev->field = f->fmt.pix.field; + dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); + core->width = f->fmt.pix.width; + core->height = f->fmt.pix.height; + core->field = f->fmt.pix.field; return 0; } @@ -1343,7 +1346,6 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* initialize driver struct */ spin_lock_init(&dev->slock); - core->tvnorm = V4L2_STD_NTSC_M; /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); @@ -1438,10 +1440,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, /* Sets device info at pci_dev */ pci_set_drvdata(pci_dev, dev); - dev->width = 320; - dev->height = 240; - dev->field = V4L2_FIELD_INTERLACED; - dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); + dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); /* initial device configuration */ mutex_lock(&core->lock); diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index dd50177cea1e..862c60938663 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -379,6 +379,8 @@ struct cx88_core { /* state info */ struct task_struct *kthread; v4l2_std_id tvnorm; + unsigned width, height; + unsigned field; enum cx88_tvaudio tvaudio; u32 audiomode_manual; u32 audiomode_current; @@ -479,8 +481,6 @@ struct cx8800_dev { unsigned char pci_rev,pci_lat; const struct cx8800_fmt *fmt; - unsigned int width, height; - unsigned field; /* capture queues */ struct cx88_dmaqueue vidq; @@ -557,9 +557,6 @@ struct cx8802_dev { #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) struct video_device *mpeg_dev; u32 mailbox; - int width; - int height; - unsigned field; unsigned char mpeg_active; /* nonzero if mpeg encoder is active */ /* mpeg params */ @@ -721,7 +718,7 @@ extern void cx88_i2c_init_ir(struct cx88_core *core); /* cx88-mpeg.c */ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf, enum v4l2_field field); + struct cx88_buffer *buf); void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); void cx8802_cancel_buffers(struct cx8802_dev *dev); int cx8802_start_dma(struct cx8802_dev *dev, -- GitLab From fb37ab3e788c698bf889e70335d5d1ccb6de2373 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 06:06:37 -0300 Subject: [PATCH 2458/9457] [media] cx88: drop mpeg_active field The vb2 framework knows if streaming is in progress, no need to use a separate field for that. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 11 +++++------ drivers/media/pci/cx88/cx88.h | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 58e5254e154a..13b8ed322693 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -536,9 +536,6 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev) dprintk(1,"Initialize codec\n"); retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ if (retval < 0) { - - dev->mpeg_active = 0; - /* ping was not successful, reset and upload firmware */ cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */ @@ -622,7 +619,6 @@ static int blackbird_start_codec(struct cx8802_dev *dev) BLACKBIRD_RAW_BITS_NONE ); - dev->mpeg_active = 1; return 0; } @@ -636,7 +632,6 @@ static int blackbird_stop_codec(struct cx8802_dev *dev) cx2341x_handler_set_busy(&dev->cxhdl, 0); - dev->mpeg_active = 0; return 0; } @@ -875,18 +870,22 @@ static int vidioc_s_frequency (struct file *file, void *priv, { struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; + bool streaming; if (unlikely(UNSET == core->board.tuner_type)) return -EINVAL; if (unlikely(f->tuner != 0)) return -EINVAL; - if (dev->mpeg_active) + streaming = dev->vb2_mpegq.start_streaming_called; + if (streaming) blackbird_stop_codec(dev); cx88_set_freq (core,f); blackbird_initialize_codec(dev); cx88_set_scale(core, core->width, core->height, core->field); + if (streaming) + blackbird_start_codec(dev); return 0; } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 862c60938663..93bc7cf7d39b 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -557,7 +557,6 @@ struct cx8802_dev { #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) struct video_device *mpeg_dev; u32 mailbox; - unsigned char mpeg_active; /* nonzero if mpeg encoder is active */ /* mpeg params */ struct cx2341x_handler cxhdl; -- GitLab From 078859a3230c123ed9cb798fb1cd7f89b4fde102 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 06:08:07 -0300 Subject: [PATCH 2459/9457] [media] cx88: don't allow changes while vb2_is_busy Make sure that changing the standard or format is not allowed while one or more of the video, vbi or mpeg vb2 queues are busy. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 8 ++++++-- drivers/media/pci/cx88/cx88-core.c | 7 +++++++ drivers/media/pci/cx88/cx88-video.c | 14 +++++++++++--- drivers/media/pci/cx88/cx88.h | 13 +++++++++---- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index 13b8ed322693..ff7978212e9d 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -855,6 +855,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; + if (vb2_is_busy(&dev->vb2_mpegq)) + return -EBUSY; + if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) || + vb2_is_busy(&core->v4ldev->vb2_vbiq))) + return -EBUSY; vidioc_try_fmt_vid_cap(file, priv, f); core->width = f->fmt.pix.width; core->height = f->fmt.pix.height; @@ -1002,8 +1007,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) struct cx8802_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - cx88_set_tvnorm(core, id); - return 0; + return cx88_set_tvnorm(core, id); } static const struct v4l2_file_operations mpeg_fops = diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index bbdbb58576ef..9fa4acbdcab8 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -864,6 +864,13 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) u32 bdelay,agcdelay,htotal; u32 cxiformat, cxoformat; + if (norm == core->tvnorm) + return 0; + if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) || + vb2_is_busy(&core->v4ldev->vb2_vbiq))) + return -EBUSY; + if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq)) + return -EBUSY; core->tvnorm = norm; fsc8 = norm_fsc8(norm); adc_clock = xtal; diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index eadceebfed8e..64d6a722654c 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -792,6 +792,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, if (0 != err) return err; + if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq)) + return -EBUSY; + if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq)) + return -EBUSY; dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); core->width = f->fmt.pix.width; core->height = f->fmt.pix.height; @@ -864,9 +868,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) struct cx8800_dev *dev = video_drvdata(file); struct cx88_core *core = dev->core; - cx88_set_tvnorm(core, tvnorms); - - return 0; + return cx88_set_tvnorm(core, tvnorms); } /* only one input in this sample driver */ @@ -1442,6 +1444,9 @@ static int cx8800_initdev(struct pci_dev *pci_dev, dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); + /* Maintain a reference so cx88-blackbird can query the 8800 device. */ + core->v4ldev = dev; + /* initial device configuration */ mutex_lock(&core->lock); cx88_set_tvnorm(core, core->tvnorm); @@ -1544,6 +1549,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, free_irq(pci_dev->irq, dev); mutex_unlock(&core->lock); fail_core: + core->v4ldev = NULL; cx88_core_put(core,dev->pci); fail_free: kfree(dev); @@ -1572,6 +1578,8 @@ static void cx8800_finidev(struct pci_dev *pci_dev) free_irq(pci_dev->irq, dev); cx8800_unregister_video(dev); + core->v4ldev = NULL; + /* free memory */ cx88_core_put(core,dev->pci); kfree(dev); diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 93bc7cf7d39b..2fa4aa93e503 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -334,6 +334,9 @@ struct cx88_dmaqueue { u32 count; }; +struct cx8800_dev; +struct cx8802_dev; + struct cx88_core { struct list_head devlist; atomic_t refcount; @@ -401,8 +404,13 @@ struct cx88_core { /* various v4l controls */ u32 freq; - /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ + /* + * cx88-video needs to access cx8802 for hybrid tuner pll access and + * for vb2_is_busy() checks. + */ struct cx8802_dev *dvbdev; + /* cx88-blackbird needs to access cx8800 for vb2_is_busy() checks */ + struct cx8800_dev *v4ldev; enum cx88_board_type active_type_id; int active_ref; int active_fe_id; @@ -456,9 +464,6 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) val; \ }) -struct cx8800_dev; -struct cx8802_dev; - /* ----------------------------------------------------------- */ /* function 0: video stuff */ -- GitLab From c39ba330322ba087f4c814f641d1818137c98e95 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 29 Aug 2014 07:45:00 -0300 Subject: [PATCH 2460/9457] [media] cx88: consistently use UNSET for absent tuner Don't mix UNSET and TUNER_ABSENT: you have to pick one or the other. For this driver selecting UNSET to represent an absent tuner resulting in the fewest changes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-cards.c | 66 ++++++++++++++--------------- drivers/media/pci/cx88/cx88-video.c | 2 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 6db654990263..8f2556ec3971 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -347,7 +347,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_IODATA_GVVCP3PCI] = { .name = "IODATA GV-VCP3/PCI", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -436,7 +436,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_KWORLD_DVB_T] = { .name = "KWorld/VStream XPert DVB-T", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -455,7 +455,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { .name = "DViCO FusionHDTV DVB-T1", - .tuner_type = TUNER_ABSENT, /* No analog tuner */ + .tuner_type = UNSET, /* No analog tuner */ .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -542,7 +542,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_HAUPPAUGE_DVB_T1] = { .name = "Hauppauge Nova-T DVB-T", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -554,7 +554,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_CONEXANT_DVB_T1] = { .name = "Conexant DVB-T reference design", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -579,7 +579,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = { .name = "DViCO FusionHDTV DVB-T Plus", - .tuner_type = TUNER_ABSENT, /* No analog tuner */ + .tuner_type = UNSET, /* No analog tuner */ .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -596,7 +596,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DNTV_LIVE_DVB_T] = { .name = "digitalnow DNTV Live! DVB-T", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -787,7 +787,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_ADSTECH_DVB_T_PCI] = { .name = "ADS Tech Instant TV DVB-T PCI", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -806,7 +806,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { .name = "TerraTec Cinergy 1400 DVB-T", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .input = { { .type = CX88_VMUX_DVB, .vmux = 0, @@ -924,7 +924,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_WINFAST_DTV1000] = { .name = "WinFast DTV1000-T", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -972,7 +972,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = { .name = "Hauppauge Nova-S-Plus DVB-S", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -998,7 +998,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = { .name = "Hauppauge Nova-SE2 DVB-S", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1010,7 +1010,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_KWORLD_DVBS_100] = { .name = "KWorld DVB-S 100", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1102,7 +1102,7 @@ static const struct cx88_board cx88_boards[] = { /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */ /* Manenti Marco */ .name = "KWorld/VStream XPert DVB-T with cx22702", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1121,7 +1121,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = { .name = "DViCO FusionHDTV DVB-T Dual Digital", - .tuner_type = TUNER_ABSENT, /* No analog tuner */ + .tuner_type = UNSET, /* No analog tuner */ .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1356,7 +1356,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_GENIATECH_DVBS] = { .name = "Geniatech DVB-S", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1494,7 +1494,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_SAMSUNG_SMT_7020] = { .name = "Samsung SMT 7020 DVB-S", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1506,7 +1506,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_ADSTECH_PTV_390] = { .name = "ADS Tech Instant Video PCI", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -1553,7 +1553,7 @@ static const struct cx88_board cx88_boards[] = { [CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO] = { .name = "DViCO FusionHDTV 5 PCI nano", /* xc3008 tuner, digital only for now */ - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2069,7 +2069,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_TBS_8920] = { .name = "TBS 8920 DVB-S/S2", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2304,7 +2304,7 @@ static const struct cx88_board cx88_boards[] = { }, [CX88_BOARD_TWINHAN_VP1027_DVBS] = { .name = "Twinhan VP-1027 DVB-S", - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -2921,33 +2921,33 @@ static const struct { int fm; const char *name; } gdi_tuner[] = { - [ 0x01 ] = { .id = TUNER_ABSENT, + [ 0x01 ] = { .id = UNSET, .name = "NTSC_M" }, - [ 0x02 ] = { .id = TUNER_ABSENT, + [ 0x02 ] = { .id = UNSET, .name = "PAL_B" }, - [ 0x03 ] = { .id = TUNER_ABSENT, + [ 0x03 ] = { .id = UNSET, .name = "PAL_I" }, - [ 0x04 ] = { .id = TUNER_ABSENT, + [ 0x04 ] = { .id = UNSET, .name = "PAL_D" }, - [ 0x05 ] = { .id = TUNER_ABSENT, + [ 0x05 ] = { .id = UNSET, .name = "SECAM" }, - [ 0x10 ] = { .id = TUNER_ABSENT, + [ 0x10 ] = { .id = UNSET, .fm = 1, .name = "TEMIC_4049" }, [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5, .name = "TEMIC_4136" }, - [ 0x12 ] = { .id = TUNER_ABSENT, + [ 0x12 ] = { .id = UNSET, .name = "TEMIC_4146" }, [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME, .fm = 1, .name = "PHILIPS_FQ1216_MK3" }, - [ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1, + [ 0x21 ] = { .id = UNSET, .fm = 1, .name = "PHILIPS_FQ1236_MK3" }, - [ 0x22 ] = { .id = TUNER_ABSENT, + [ 0x22 ] = { .id = UNSET, .name = "PHILIPS_FI1236_MK3" }, - [ 0x23 ] = { .id = TUNER_ABSENT, + [ 0x23 ] = { .id = UNSET, .name = "PHILIPS_FI1216_MK3" }, }; @@ -3564,7 +3564,7 @@ static void cx88_card_setup(struct cx88_core *core) mode_mask &= ~T_RADIO; } - if (core->board.tuner_type != TUNER_ABSENT) { + if (core->board.tuner_type != UNSET) { tun_setup.mode_mask = mode_mask; tun_setup.type = core->board.tuner_type; tun_setup.addr = core->board.tuner_addr; @@ -3777,7 +3777,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) cx88_i2c_init(core, pci); /* load tuner module, if needed */ - if (TUNER_ABSENT != core->board.tuner_type) { + if (UNSET != core->board.tuner_type) { /* Ignore 0x6b and 0x6f on cx88 boards. * FusionHDTV5 RT Gold has an ir receiver at 0x6b * and an RTC at 0x6f which can get corrupted if probed. */ diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 64d6a722654c..d8a86cd4e455 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1532,7 +1532,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, } /* start tvaudio thread */ - if (core->board.tuner_type != TUNER_ABSENT) { + if (core->board.tuner_type != UNSET) { core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); if (IS_ERR(core->kthread)) { err = PTR_ERR(core->kthread); -- GitLab From 98822de9ae22083658104e43d52f2cb0f3df1138 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 5 Sep 2014 09:37:09 -0300 Subject: [PATCH 2461/9457] [media] cx88: pci_disable_device comes after free_irq Move pci_disable_device() down otherwise it will complain about an unfreed irq. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index d8a86cd4e455..a64ae31ae142 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1571,12 +1571,12 @@ static void cx8800_finidev(struct pci_dev *pci_dev) cx88_ir_stop(core); cx88_shutdown(core); /* FIXME */ - pci_disable_device(pci_dev); /* unregister stuff */ free_irq(pci_dev->irq, dev); cx8800_unregister_video(dev); + pci_disable_device(pci_dev); core->v4ldev = NULL; -- GitLab From c0d5b5fbbe1b13c5d474b58bf89dd7ff2e6eb6e1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 20 Sep 2014 09:24:58 -0300 Subject: [PATCH 2462/9457] [media] cx88: fix VBI support Now works with both NTSC and PAL. Tested with CC/XDS for NTSC and teletext/WSS for PAL. The start lines were wrong, the WSS signal wasn't captured and there was no difference between NTSC and PAL w.r.t. the count[] values so NTSC returned way too many lines. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-vbi.c | 28 ++++++++++++++++++++-------- drivers/media/pci/cx88/cx88.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 042f54597a9b..6ab6e27648f6 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -23,20 +23,22 @@ int cx8800_vbi_fmt (struct file *file, void *priv, f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; f->fmt.vbi.offset = 244; - f->fmt.vbi.count[0] = VBI_LINE_COUNT; - f->fmt.vbi.count[1] = VBI_LINE_COUNT; if (dev->core->tvnorm & V4L2_STD_525_60) { /* ntsc */ f->fmt.vbi.sampling_rate = 28636363; f->fmt.vbi.start[0] = 10; f->fmt.vbi.start[1] = 273; + f->fmt.vbi.count[0] = VBI_LINE_NTSC_COUNT; + f->fmt.vbi.count[1] = VBI_LINE_NTSC_COUNT; } else if (dev->core->tvnorm & V4L2_STD_625_50) { /* pal */ f->fmt.vbi.sampling_rate = 35468950; - f->fmt.vbi.start[0] = 7 -1; - f->fmt.vbi.start[1] = 319 -1; + f->fmt.vbi.start[0] = V4L2_VBI_ITU_625_F1_START + 5; + f->fmt.vbi.start[1] = V4L2_VBI_ITU_625_F2_START + 5; + f->fmt.vbi.count[0] = VBI_LINE_PAL_COUNT; + f->fmt.vbi.count[1] = VBI_LINE_PAL_COUNT; } return 0; } @@ -111,8 +113,13 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *alloc_ctxs[]) { + struct cx8800_dev *dev = q->drv_priv; + *num_planes = 1; - sizes[0] = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; + if (dev->core->tvnorm & V4L2_STD_525_60) + sizes[0] = VBI_LINE_NTSC_COUNT * VBI_LINE_LENGTH * 2; + else + sizes[0] = VBI_LINE_PAL_COUNT * VBI_LINE_LENGTH * 2; return 0; } @@ -122,10 +129,15 @@ static int buffer_prepare(struct vb2_buffer *vb) struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); + unsigned int lines; unsigned int size; int rc; - size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; + if (dev->core->tvnorm & V4L2_STD_525_60) + lines = VBI_LINE_NTSC_COUNT; + else + lines = VBI_LINE_PAL_COUNT; + size = lines * VBI_LINE_LENGTH * 2; if (vb2_plane_size(vb, 0) < size) return -EINVAL; vb2_set_plane_payload(vb, 0, size); @@ -135,9 +147,9 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EIO; cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, - 0, VBI_LINE_LENGTH * VBI_LINE_COUNT, + 0, VBI_LINE_LENGTH * lines, VBI_LINE_LENGTH, 0, - VBI_LINE_COUNT); + lines); return 0; } diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 2fa4aa93e503..3b0ae754f165 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -61,7 +61,8 @@ #define FORMAT_FLAGS_PACKED 0x01 #define FORMAT_FLAGS_PLANAR 0x02 -#define VBI_LINE_COUNT 17 +#define VBI_LINE_PAL_COUNT 18 +#define VBI_LINE_NTSC_COUNT 12 #define VBI_LINE_LENGTH 2048 #define AUD_RDS_LINES 4 -- GitLab From f3a75505ab5f50c6af8a69c025aaf77375929217 Mon Sep 17 00:00:00 2001 From: Amber Thrall Date: Thu, 2 Oct 2014 23:33:30 -0300 Subject: [PATCH 2463/9457] [media] Staging: media: lirc: cleaned up packet dump in 2 files lirc_imon.c and lirc_sasem.c contain an incoming_packet method that is using deprecated printk's. Removed blocks replacing with single dev_info with a %*ph format instead. Signed-off-by: Amber Thrall Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_imon.c | 10 ++-------- drivers/staging/media/lirc/lirc_sasem.c | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 7aca44f28c5a..232edd5b1742 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -606,7 +606,6 @@ static void imon_incoming_packet(struct imon_context *context, struct device *dev = context->driver->dev; int octet, bit; unsigned char mask; - int i; /* * just bail out if no listening IR client @@ -620,13 +619,8 @@ static void imon_incoming_packet(struct imon_context *context, return; } - if (debug) { - dev_info(dev, "raw packet: "); - for (i = 0; i < len; ++i) - printk("%02x ", buf[i]); - printk("\n"); - } - + if (debug) + dev_info(dev, "raw packet: %*ph\n", len, buf); /* * Translate received data to pulse and space lengths. * Received data is active low, i.e. pulses are 0 and diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c index c20ef56202bf..2f0463eb9887 100644 --- a/drivers/staging/media/lirc/lirc_sasem.c +++ b/drivers/staging/media/lirc/lirc_sasem.c @@ -573,7 +573,6 @@ static void incoming_packet(struct sasem_context *context, unsigned char *buf = urb->transfer_buffer; long ms; struct timeval tv; - int i; if (len != 8) { dev_warn(&context->dev->dev, @@ -582,13 +581,8 @@ static void incoming_packet(struct sasem_context *context, return; } - if (debug) { - printk(KERN_INFO "Incoming data: "); - for (i = 0; i < 8; ++i) - printk(KERN_CONT "%02x ", buf[i]); - printk(KERN_CONT "\n"); - } - + if (debug) + dev_info(&context->dev->dev, "Incoming data: %*ph\n", len, buf); /* * Lirc could deal with the repeat code, but we really need to block it * if it arrives too late. Otherwise we could repeat the wrong code. -- GitLab From 30934dd3e8f8b51bdfbc5ca1dfb0cc41bc22a1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=BB=E3=81=A1?= Date: Mon, 6 Oct 2014 03:21:27 -0300 Subject: [PATCH 2464/9457] [media] dvb-frontends/Kconfig: better describe Toshiba TC90522 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Toshiba TC90522 is wrongly categorized, fix it Signed-off-by: ほち, AreMa Inc Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 5a134547e325..6c75418222e2 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -648,12 +648,15 @@ config DVB_MB86A20S A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator. Say Y when you want to support this frontend. +comment "ISDB-S (satellite) & ISDB-T (terrestrial) frontends" + depends on DVB_CORE + config DVB_TC90522 tristate "Toshiba TC90522" depends on DVB_CORE && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help - A Toshiba TC90522 2xISDB-T + 2xISDB-S demodulator. + Toshiba TC90522 2xISDB-S 8PSK + 2xISDB-T OFDM demodulator. Say Y when you want to support this frontend. comment "Digital terrestrial only tuners/PLL" -- GitLab From d09155d2f39ebf2cce29c49f085fe43b1d66fbef Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 27 Oct 2014 14:54:44 +0100 Subject: [PATCH 2465/9457] KVM: emulator: always inline __linearize The two callers have a lot of constant arguments that can be optimized out. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5edf088ca51e..07e9913d6bbb 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -641,11 +641,11 @@ static bool insn_aligned(struct x86_emulate_ctxt *ctxt, unsigned size) return true; } -static int __linearize(struct x86_emulate_ctxt *ctxt, - struct segmented_address addr, - unsigned *max_size, unsigned size, - bool write, bool fetch, - ulong *linear) +static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, + struct segmented_address addr, + unsigned *max_size, unsigned size, + bool write, bool fetch, + ulong *linear) { struct desc_struct desc; bool usable; -- GitLab From 4be4de7ef9fd3a4d77320d4713970299ffecd286 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 18 Sep 2014 22:39:40 +0300 Subject: [PATCH 2466/9457] KVM: x86: Use new is_noncanonical_address in _linearize Replace the current canonical address check with the new function which is identical. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 07e9913d6bbb..77041d494052 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -658,7 +658,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, *max_size = 0; switch (ctxt->mode) { case X86EMUL_MODE_PROT64: - if (((signed long)la << 16) >> 16 != la) + if (is_noncanonical_address(la)) return emulate_gp(ctxt, 0); *max_size = min_t(u64, ~0u, (1ull << 48) - la); -- GitLab From f7784046ab7cfc1645f4110b6ed14fbdffc2abee Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 18 Sep 2014 22:39:41 +0300 Subject: [PATCH 2467/9457] KVM: x86: Getting rid of grp45 in emulator Breaking grp45 to the relevant functions to speed up the emulation and simplify the code. In addition, it is necassary the next patch will distinguish between far and near branches according to the flags. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 45 +++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 77041d494052..147f3fdfb5ce 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2045,31 +2045,22 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) return rc; } -static int em_grp45(struct x86_emulate_ctxt *ctxt) +static int em_jmp_abs(struct x86_emulate_ctxt *ctxt) { - int rc = X86EMUL_CONTINUE; + return assign_eip_near(ctxt, ctxt->src.val); +} - switch (ctxt->modrm_reg) { - case 2: /* call near abs */ { - long int old_eip; - old_eip = ctxt->_eip; - rc = assign_eip_near(ctxt, ctxt->src.val); - if (rc != X86EMUL_CONTINUE) - break; - ctxt->src.val = old_eip; - rc = em_push(ctxt); - break; - } - case 4: /* jmp abs */ - rc = assign_eip_near(ctxt, ctxt->src.val); - break; - case 5: /* jmp far */ - rc = em_jmp_far(ctxt); - break; - case 6: /* push */ - rc = em_push(ctxt); - break; - } +static int em_call_near_abs(struct x86_emulate_ctxt *ctxt) +{ + int rc; + long int old_eip; + + old_eip = ctxt->_eip; + rc = assign_eip_near(ctxt, ctxt->src.val); + if (rc != X86EMUL_CONTINUE) + return rc; + ctxt->src.val = old_eip; + rc = em_push(ctxt); return rc; } @@ -3780,11 +3771,11 @@ static const struct opcode group4[] = { static const struct opcode group5[] = { F(DstMem | SrcNone | Lock, em_inc), F(DstMem | SrcNone | Lock, em_dec), - I(SrcMem | Stack, em_grp45), + I(SrcMem | Stack, em_call_near_abs), I(SrcMemFAddr | ImplicitOps | Stack, em_call_far), - I(SrcMem | Stack, em_grp45), - I(SrcMemFAddr | ImplicitOps, em_grp45), - I(SrcMem | Stack, em_grp45), D(Undefined), + I(SrcMem | Stack, em_jmp_abs), + I(SrcMemFAddr | ImplicitOps, em_jmp_far), + I(SrcMem | Stack, em_push), D(Undefined), }; static const struct opcode group6[] = { -- GitLab From 58b7075d059f7d37ca86c76fb1446fa3447b9f4f Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 24 Oct 2014 11:35:09 +0300 Subject: [PATCH 2468/9457] KVM: x86: Distinguish between stack operation and near branches In 64-bit, stack operations default to 64-bits, but can be overriden (to 16-bit) using opsize override prefix. In contrast, near-branches are always 64-bit. This patch distinguish between the different behaviors. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 147f3fdfb5ce..a90fa188aeea 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -166,6 +166,7 @@ #define CheckPerm ((u64)1 << 49) /* Has valid check_perm field */ #define NoBigReal ((u64)1 << 50) /* No big real mode */ #define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ +#define NearBranch ((u64)1 << 52) /* Near branches */ #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) @@ -3771,9 +3772,9 @@ static const struct opcode group4[] = { static const struct opcode group5[] = { F(DstMem | SrcNone | Lock, em_inc), F(DstMem | SrcNone | Lock, em_dec), - I(SrcMem | Stack, em_call_near_abs), + I(SrcMem | NearBranch, em_call_near_abs), I(SrcMemFAddr | ImplicitOps | Stack, em_call_far), - I(SrcMem | Stack, em_jmp_abs), + I(SrcMem | NearBranch, em_jmp_abs), I(SrcMemFAddr | ImplicitOps, em_jmp_far), I(SrcMem | Stack, em_push), D(Undefined), }; @@ -3955,7 +3956,7 @@ static const struct opcode opcode_table[256] = { I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */ I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */ /* 0x70 - 0x7F */ - X16(D(SrcImmByte)), + X16(D(SrcImmByte | NearBranch)), /* 0x80 - 0x87 */ G(ByteOp | DstMem | SrcImm, group1), G(DstMem | SrcImm, group1), @@ -3994,8 +3995,8 @@ static const struct opcode opcode_table[256] = { X8(I(DstReg | SrcImm64 | Mov, em_mov)), /* 0xC0 - 0xC7 */ G(ByteOp | Src2ImmByte, group2), G(Src2ImmByte, group2), - I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), - I(ImplicitOps | Stack, em_ret), + I(ImplicitOps | NearBranch | SrcImmU16, em_ret_near_imm), + I(ImplicitOps | NearBranch, em_ret), I(DstReg | SrcMemFAddr | ModRM | No64 | Src2ES, em_lseg), I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg), G(ByteOp, group11), G(0, group11), @@ -4015,13 +4016,14 @@ static const struct opcode opcode_table[256] = { /* 0xD8 - 0xDF */ N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N, /* 0xE0 - 0xE7 */ - X3(I(SrcImmByte, em_loop)), - I(SrcImmByte, em_jcxz), + X3(I(SrcImmByte | NearBranch, em_loop)), + I(SrcImmByte | NearBranch, em_jcxz), I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in), I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out), /* 0xE8 - 0xEF */ - I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps), - I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), + I(SrcImm | NearBranch, em_call), D(SrcImm | ImplicitOps | NearBranch), + I(SrcImmFAddr | No64, em_jmp_far), + D(SrcImmByte | ImplicitOps | NearBranch), I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in), I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out), /* 0xF0 - 0xF7 */ @@ -4081,7 +4083,7 @@ static const struct opcode twobyte_table[256] = { N, N, N, N, N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f), /* 0x80 - 0x8F */ - X16(D(SrcImm)), + X16(D(SrcImm | NearBranch)), /* 0x90 - 0x9F */ X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), /* 0xA0 - 0xA7 */ @@ -4550,7 +4552,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) return EMULATION_FAILED; if (unlikely(ctxt->d & - (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm))) { + (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch))) { /* * These are copied unconditionally here, and checked unconditionally * in x86_emulate_insn. @@ -4561,8 +4563,12 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) if (ctxt->d & NotImpl) return EMULATION_FAILED; - if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack)) - ctxt->op_bytes = 8; + if (mode == X86EMUL_MODE_PROT64) { + if (ctxt->op_bytes == 4 && (ctxt->d & Stack)) + ctxt->op_bytes = 8; + else if (ctxt->d & NearBranch) + ctxt->op_bytes = 8; + } if (ctxt->d & Op3264) { if (mode == X86EMUL_MODE_PROT64) -- GitLab From bf0b682c9b6a6d6d54adf439bfe953feef7be2e8 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 18 Sep 2014 22:39:45 +0300 Subject: [PATCH 2469/9457] KVM: x86: Sysexit emulation does not mask RIP/RSP If the operand size is not 64-bit, then the sysexit instruction should assign ECX to RSP and EDX to RIP. The current code assigns the full 64-bits. Fix it by masking. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a90fa188aeea..058aff86cfba 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2417,6 +2417,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) if ((msr_data & 0xfffc) == 0x0) return emulate_gp(ctxt, 0); ss_sel = (u16)(msr_data + 24); + rcx = (u32)rcx; + rdx = (u32)rdx; break; case X86EMUL_MODE_PROT64: cs_sel = (u16)(msr_data + 32); -- GitLab From 52ce3c21aec30d9dd99a89662ae87c657636787b Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 7 Oct 2014 17:16:21 -0700 Subject: [PATCH 2470/9457] x86,kvm,vmx: Don't trap writes to CR4.TSD CR4.TSD is guest-owned; don't trap writes to it in VMX guests. This avoids a VM exit on context switches into or out of a PR_TSC_SIGSEGV task. I think that this fixes an unintentional side-effect of: 4c38609ac569 KVM: VMX: Make guest cr4 mask more conservative Signed-off-by: Andy Lutomirski Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3e556c68351b..2627ffae919b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -105,7 +105,7 @@ module_param(nested, bool, S_IRUGO); (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) #define KVM_CR4_GUEST_OWNED_BITS \ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ - | X86_CR4_OSXMMEXCPT) + | X86_CR4_OSXMMEXCPT | X86_CR4_TSD) #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) -- GitLab From 394457a928e0f7ff121c375966f5ec1980dabc09 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 3 Oct 2014 00:30:52 +0300 Subject: [PATCH 2471/9457] KVM: x86: some apic broadcast modes does not work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KVM does not deliver x2APIC broadcast messages with physical mode. Intel SDM (10.12.9 ICR Operation in x2APIC Mode) states: "A destination ID value of FFFF_FFFFH is used for broadcast of interrupts in both logical destination and physical destination modes." In addition, the local-apic enables cluster mode broadcast. As Intel SDM 10.6.2.2 says: "Broadcast to all local APICs is achieved by setting all destination bits to one." This patch enables cluster mode broadcast. The fix tries to combine broadcast in different modes through a unified code. One rare case occurs when the source of IPI has its APIC disabled. In such case, the source can still issue IPIs, but since the source is not obliged to have the same LAPIC mode as the enabled ones, we cannot rely on it. Since it is a rare case, it is unoptimized and done on the slow-path. Signed-off-by: Nadav Amit Reviewed-by: Radim Krčmář Reviewed-by: Wanpeng Li [As per Radim's review, use unsigned int for X2APIC_BROADCAST, return bool from kvm_apic_broadcast. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/lapic.c | 28 ++++++++++++++++++++++------ arch/x86/kvm/lapic.h | 4 ++-- virt/kvm/ioapic.h | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6ed0c30d6a0c..dd7cfc6de4a3 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -542,7 +542,7 @@ struct kvm_apic_map { struct rcu_head rcu; u8 ldr_bits; /* fields bellow are used to decode ldr values in different modes */ - u32 cid_shift, cid_mask, lid_mask; + u32 cid_shift, cid_mask, lid_mask, broadcast; struct kvm_lapic *phys_map[256]; /* first index is cluster id second is cpu id in a cluster */ struct kvm_lapic *logical_map[16][16]; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index b8345dd41b25..ee04adf6c73a 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -68,6 +68,9 @@ #define MAX_APIC_VECTOR 256 #define APIC_VECTORS_PER_REG 32 +#define APIC_BROADCAST 0xFF +#define X2APIC_BROADCAST 0xFFFFFFFFul + #define VEC_POS(v) ((v) & (32 - 1)) #define REG_POS(v) (((v) >> 5) << 4) @@ -149,6 +152,7 @@ static void recalculate_apic_map(struct kvm *kvm) new->cid_shift = 8; new->cid_mask = 0; new->lid_mask = 0xff; + new->broadcast = APIC_BROADCAST; kvm_for_each_vcpu(i, vcpu, kvm) { struct kvm_lapic *apic = vcpu->arch.apic; @@ -170,6 +174,7 @@ static void recalculate_apic_map(struct kvm *kvm) new->cid_shift = 16; new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; new->lid_mask = 0xffff; + new->broadcast = X2APIC_BROADCAST; } else if (kvm_apic_sw_enabled(apic) && !new->cid_mask /* flat mode */ && kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { @@ -558,16 +563,25 @@ static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) apic_update_ppr(apic); } -int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) +static int kvm_apic_broadcast(struct kvm_lapic *apic, u32 dest) +{ + return dest == (apic_x2apic_mode(apic) ? + X2APIC_BROADCAST : APIC_BROADCAST); +} + +int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest) { - return dest == 0xff || kvm_apic_id(apic) == dest; + return kvm_apic_id(apic) == dest || kvm_apic_broadcast(apic, dest); } -int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) +int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda) { int result = 0; u32 logical_id; + if (kvm_apic_broadcast(apic, mda)) + return 1; + if (apic_x2apic_mode(apic)) { logical_id = kvm_apic_get_reg(apic, APIC_LDR); return logical_id & mda; @@ -595,7 +609,7 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) } int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, - int short_hand, int dest, int dest_mode) + int short_hand, unsigned int dest, int dest_mode) { int result = 0; struct kvm_lapic *target = vcpu->arch.apic; @@ -657,9 +671,11 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, if (!map) goto out; + if (irq->dest_id == map->broadcast) + goto out; + if (irq->dest_mode == 0) { /* physical mode */ - if (irq->delivery_mode == APIC_DM_LOWEST || - irq->dest_id == 0xff) + if (irq->delivery_mode == APIC_DM_LOWEST) goto out; dst = &map->phys_map[irq->dest_id & 0xff]; } else { diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6a11845fd8b9..3fd6c22d187d 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -55,8 +55,8 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu); void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr); void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); -int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); -int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); +int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u32 dest); +int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u32 mda); int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, unsigned long *dest_map); int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index e23b70634f1e..31725a3a93b8 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h @@ -83,7 +83,7 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu); int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, - int short_hand, int dest, int dest_mode); + int short_hand, unsigned int dest, int dest_mode); int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode); -- GitLab From 6bdf06625d240361e92254143a123ab432e337f8 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Tue, 30 Sep 2014 20:49:14 +0300 Subject: [PATCH 2472/9457] KVM: x86: DR7.GD should be cleared upon any #DB exception Intel SDM 17.2.4 (Debug Control Register (DR7)) says: "The processor clears the GD flag upon entering to the debug exception handler." This sentence may be misunderstood as if it happens only on #DB due to debug-register protection, but it happens regardless to the cause of the #DB. Fix the behavior to match both real hardware and Bochs. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 2 -- arch/x86/kvm/x86.c | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2627ffae919b..63e7cf18c1c8 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5185,9 +5185,7 @@ static int handle_dr(struct kvm_vcpu *vcpu) vcpu->run->exit_reason = KVM_EXIT_DEBUG; return 0; } else { - vcpu->arch.dr7 &= ~DR7_GD; vcpu->arch.dr6 |= DR6_BD | DR6_RTM; - vmcs_writel(GUEST_DR7, vcpu->arch.dr7); kvm_queue_exception(vcpu, DB_VECTOR); return 1; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0033df32a745..1ab7361594d5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5965,6 +5965,12 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win) __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) | X86_EFLAGS_RF); + if (vcpu->arch.exception.nr == DB_VECTOR && + (vcpu->arch.dr7 & DR7_GD)) { + vcpu->arch.dr7 &= ~DR7_GD; + kvm_update_dr7(vcpu); + } + kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, vcpu->arch.exception.has_error_code, vcpu->arch.exception.error_code, -- GitLab From 518547b32ab41b12c1303d12e6e15fb1621dca4c Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Tue, 30 Sep 2014 20:49:19 +0300 Subject: [PATCH 2473/9457] KVM: x86: Emulator does not calculate address correctly In long-mode, when the address size is 4 bytes, the linear address is not truncated as the emulator mistakenly does. Instead, the offset within the segment (the ea field) should be truncated according to the address size. As Intel SDM says: "In 64-bit mode, the effective address components are added and the effective address is truncated ... before adding the full 64-bit segment base." Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 058aff86cfba..bdd4197e31fa 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -655,7 +655,8 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, u16 sel; unsigned cpl; - la = seg_base(ctxt, addr.seg) + addr.ea; + la = seg_base(ctxt, addr.seg) + + (fetch || ctxt->ad_bytes == 8 ? addr.ea : (u32)addr.ea); *max_size = 0; switch (ctxt->mode) { case X86EMUL_MODE_PROT64: @@ -717,7 +718,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, } break; } - if (fetch ? ctxt->mode != X86EMUL_MODE_PROT64 : ctxt->ad_bytes != 8) + if (ctxt->mode != X86EMUL_MODE_PROT64) la &= (u32)-1; if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0)) return emulate_gp(ctxt, 0); -- GitLab From 0e8a09969afb56b6bcdfe159f90a5fa20f831e85 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 3 Oct 2014 01:10:02 +0300 Subject: [PATCH 2474/9457] KVM: x86: Clear DR7.LE during task-switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DR7.LE should be cleared during task-switch. This feature is poorly documented. For reference, see: http://pdos.csail.mit.edu/6.828/2005/readings/i386/s12_02.htm SDM [17.2.4]: This feature is not supported in the P6 family processors, later IA-32 processors, and Intel 64 processors. AMD [2:13.1.1.4]: This bit is ignored by implementations of the AMD64 architecture. Intel's formulation could mean that it isn't even zeroed, but current hardware indeed does not behave like that. Signed-off-by: Nadav Amit Reviewed-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 63e7cf18c1c8..30e6e184ff09 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5490,7 +5490,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) } /* clear all local breakpoint enable flags */ - vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x55); + vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~0x155); /* * TODO: What about debug traps on tss switch? -- GitLab From c49c759f7a68b70d2fed019760a66843b3df39b8 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 3 Oct 2014 01:10:03 +0300 Subject: [PATCH 2475/9457] KVM: x86: Emulator performs code segment checks on read access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When read access is performed using a readable code segment, the "conforming" and "non-conforming" checks should not be done. As a result, read using non-conforming readable code segment fails. This is according to Intel SDM 5.6.1 ("Accessing Data in Code Segments"). The fix is not to perform the "non-conforming" checks if the access is not a fetch; the relevant checks are already done when loading the segment. Signed-off-by: Nadav Amit Reviewed-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index bdd4197e31fa..cd2029bbab48 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -703,8 +703,8 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, if (size > *max_size) goto bad; cpl = ctxt->ops->cpl(ctxt); - if (!(desc.type & 8)) { - /* data segment */ + if (!fetch) { + /* data segment or readable code segment */ if (cpl > desc.dpl) goto bad; } else if ((desc.type & 8) && !(desc.type & 4)) { -- GitLab From 16f8a6f9798ab9a1fd593b06b78925d02525ab81 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 3 Oct 2014 01:10:05 +0300 Subject: [PATCH 2476/9457] KVM: vmx: Unavailable DR4/5 is checked before CPL If DR4/5 is accessed when it is unavailable (since CR4.DE is set), then #UD should be generated even if CPL>0. This is according to Intel SDM Table 6-2: "Priority Among Simultaneous Exceptions and Interrupts". Note, that this may happen on the first DR access, even if the host does not sets debug breakpoints. Obviously, it occurs when the host debugs the guest. This patch moves the DR4/5 checks from __kvm_set_dr/_kvm_get_dr to handle_dr. The emulator already checks DR4/5 availability in check_dr_read. Nested virutalization related calls to kvm_set_dr/kvm_get_dr would not like to inject exceptions to the guest. As for SVM, the patch follows the previous logic as much as possible. Anyhow, it appears the DR interception code might be buggy - even if the DR access may cause an exception, the instruction is skipped. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm.c | 10 ++++--- arch/x86/kvm/vmx.c | 17 +++++++----- arch/x86/kvm/x86.c | 46 ++++++++++++--------------------- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index dd7cfc6de4a3..3ac807646911 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -895,6 +895,7 @@ int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gfn_t gfn, void *data, int offset, int len, u32 access); bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); +bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr); static inline int __kvm_irq_line_state(unsigned long *irq_state, int irq_source_id, int level) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 7527cefc5a43..d4f3aaa2df7c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2999,7 +2999,6 @@ static int dr_interception(struct vcpu_svm *svm) { int reg, dr; unsigned long val; - int err; if (svm->vcpu.guest_debug == 0) { /* @@ -3019,12 +3018,15 @@ static int dr_interception(struct vcpu_svm *svm) dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0; if (dr >= 16) { /* mov to DRn */ + if (!kvm_require_dr(&svm->vcpu, dr - 16)) + return 1; val = kvm_register_read(&svm->vcpu, reg); kvm_set_dr(&svm->vcpu, dr - 16, val); } else { - err = kvm_get_dr(&svm->vcpu, dr, &val); - if (!err) - kvm_register_write(&svm->vcpu, reg, val); + if (!kvm_require_dr(&svm->vcpu, dr)) + return 1; + kvm_get_dr(&svm->vcpu, dr, &val); + kvm_register_write(&svm->vcpu, reg, val); } skip_emulated_instruction(&svm->vcpu); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 30e6e184ff09..0cd99d8405f8 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5163,13 +5163,20 @@ static int handle_cr(struct kvm_vcpu *vcpu) static int handle_dr(struct kvm_vcpu *vcpu) { unsigned long exit_qualification; - int dr, reg; + int dr, dr7, reg; + + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + dr = exit_qualification & DEBUG_REG_ACCESS_NUM; + + /* First, if DR does not exist, trigger UD */ + if (!kvm_require_dr(vcpu, dr)) + return 1; /* Do not handle if the CPL > 0, will trigger GP on re-entry */ if (!kvm_require_cpl(vcpu, 0)) return 1; - dr = vmcs_readl(GUEST_DR7); - if (dr & DR7_GD) { + dr7 = vmcs_readl(GUEST_DR7); + if (dr7 & DR7_GD) { /* * As the vm-exit takes precedence over the debug trap, we * need to emulate the latter, either for the host or the @@ -5177,7 +5184,7 @@ static int handle_dr(struct kvm_vcpu *vcpu) */ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; - vcpu->run->debug.arch.dr7 = dr; + vcpu->run->debug.arch.dr7 = dr7; vcpu->run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + vmcs_readl(GUEST_RIP); @@ -5207,8 +5214,6 @@ static int handle_dr(struct kvm_vcpu *vcpu) return 1; } - exit_qualification = vmcs_readl(EXIT_QUALIFICATION); - dr = exit_qualification & DEBUG_REG_ACCESS_NUM; reg = DEBUG_REG_ACCESS_REG(exit_qualification); if (exit_qualification & TYPE_MOV_FROM_DR) { unsigned long val; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1ab7361594d5..7a9cb56407bd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -455,6 +455,16 @@ bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl) } EXPORT_SYMBOL_GPL(kvm_require_cpl); +bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr) +{ + if ((dr != 4 && dr != 5) || !kvm_read_cr4_bits(vcpu, X86_CR4_DE)) + return true; + + kvm_queue_exception(vcpu, UD_VECTOR); + return false; +} +EXPORT_SYMBOL_GPL(kvm_require_dr); + /* * This function will be used to read from the physical memory of the currently * running guest. The difference to kvm_read_guest_page is that this function @@ -811,8 +821,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) vcpu->arch.eff_db[dr] = val; break; case 4: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return 1; /* #UD */ /* fall through */ case 6: if (val & 0xffffffff00000000ULL) @@ -821,8 +829,6 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) kvm_update_dr6(vcpu); break; case 5: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return 1; /* #UD */ /* fall through */ default: /* 7 */ if (val & 0xffffffff00000000ULL) @@ -837,27 +843,21 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) { - int res; - - res = __kvm_set_dr(vcpu, dr, val); - if (res > 0) - kvm_queue_exception(vcpu, UD_VECTOR); - else if (res < 0) + if (__kvm_set_dr(vcpu, dr, val)) { kvm_inject_gp(vcpu, 0); - - return res; + return 1; + } + return 0; } EXPORT_SYMBOL_GPL(kvm_set_dr); -static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) +int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) { switch (dr) { case 0 ... 3: *val = vcpu->arch.db[dr]; break; case 4: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return 1; /* fall through */ case 6: if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) @@ -866,23 +866,11 @@ static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) *val = kvm_x86_ops->get_dr6(vcpu); break; case 5: - if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) - return 1; /* fall through */ default: /* 7 */ *val = vcpu->arch.dr7; break; } - - return 0; -} - -int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) -{ - if (_kvm_get_dr(vcpu, dr, val)) { - kvm_queue_exception(vcpu, UD_VECTOR); - return 1; - } return 0; } EXPORT_SYMBOL_GPL(kvm_get_dr); @@ -3106,7 +3094,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, unsigned long val; memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); - _kvm_get_dr(vcpu, 6, &val); + kvm_get_dr(vcpu, 6, &val); dbgregs->dr6 = val; dbgregs->dr7 = vcpu->arch.dr7; dbgregs->flags = 0; @@ -4667,7 +4655,7 @@ static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt) int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) { - return _kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); + return kvm_get_dr(emul_to_vcpu(ctxt), dr, dest); } int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) -- GitLab From 91690bf32ee12a85caf497ec01cfb47c0b298bac Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Sat, 11 Oct 2014 09:19:54 +0800 Subject: [PATCH 2477/9457] Documentation: virtual: kvm: correct one bit description in APF case When commit 6adba5274206 (KVM: Let host know whether the guest can handle async PF in non-userspace context.) is introduced, actually bit 2 still is reserved and should be zero. Instead, bit 1 is 1 to indicate if asynchronous page faults can be injected when vcpu is in cpl == 0, and also please see this, in the file kvm_para.h, #define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1). Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- Documentation/virtual/kvm/msr.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt index 6d470ae7b073..2a71c8f29f68 100644 --- a/Documentation/virtual/kvm/msr.txt +++ b/Documentation/virtual/kvm/msr.txt @@ -168,7 +168,7 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02 64 byte memory area which must be in guest RAM and must be zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1 when asynchronous page faults are enabled on the vcpu 0 when - disabled. Bit 2 is 1 if asynchronous page faults can be injected + disabled. Bit 1 is 1 if asynchronous page faults can be injected when vcpu is in cpl == 0. First 4 byte of 64 byte memory location will be written to by -- GitLab From 5d87db711937019cb8eba1137c37573d7a604be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Fri, 10 Oct 2014 19:15:08 +0200 Subject: [PATCH 2478/9457] KVM: x86: add apic_timer_expired() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the code reusable. If the timer was already pending, we shouldn't be waiting in a queue, so wake_up can be skipped, simplifying the path. There is no 'reinject' case => the comment is removed. Current race behaves correctly. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ee04adf6c73a..1ebd7ff33ac7 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1050,6 +1050,26 @@ static void update_divide_count(struct kvm_lapic *apic) apic->divide_count); } +static void apic_timer_expired(struct kvm_lapic *apic) +{ + struct kvm_vcpu *vcpu = apic->vcpu; + wait_queue_head_t *q = &vcpu->wq; + + /* + * Note: KVM_REQ_PENDING_TIMER is implicitly checked in + * vcpu_enter_guest. + */ + if (atomic_read(&apic->lapic_timer.pending)) + return; + + atomic_inc(&apic->lapic_timer.pending); + /* FIXME: this code should not know anything about vcpus */ + kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); + + if (waitqueue_active(q)) + wake_up_interruptible(q); +} + static void start_apic_timer(struct kvm_lapic *apic) { ktime_t now; @@ -1554,23 +1574,8 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) { struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer); - struct kvm_vcpu *vcpu = apic->vcpu; - wait_queue_head_t *q = &vcpu->wq; - - /* - * There is a race window between reading and incrementing, but we do - * not care about potentially losing timer events in the !reinject - * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked - * in vcpu_enter_guest. - */ - if (!atomic_read(&ktimer->pending)) { - atomic_inc(&ktimer->pending); - /* FIXME: this code should not know anything about vcpus */ - kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); - } - if (waitqueue_active(q)) - wake_up_interruptible(q); + apic_timer_expired(apic); if (lapic_is_periodic(apic)) { hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); -- GitLab From 1e0ad70cc1957b9050368e433b1061a2cd1ce543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Fri, 10 Oct 2014 19:15:09 +0200 Subject: [PATCH 2479/9457] KVM: x86: fix deadline tsc interrupt injection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check in kvm_set_lapic_tscdeadline_msr() was trying to prevent a situation where we lose a pending deadline timer in a MSR write. Losing it is fine, because it effectively occurs before the timer fired, so we should be able to cancel or postpone it. Another problem comes from interaction with QEMU, or other userspace that can set deadline MSR without a good reason, when timer is already pending: one guest's deadline request results in more than one interrupt because one is injected immediately on MSR write from userspace and one through hrtimer later. The solution is to remove the injection when replacing a pending timer and to improve the usual QEMU path, we inject without a hrtimer when the deadline has already passed. Signed-off-by: Radim Krčmář Reported-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 1ebd7ff33ac7..66dd1731ab99 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1132,9 +1132,10 @@ static void start_apic_timer(struct kvm_lapic *apic) if (likely(tscdeadline > guest_tsc)) { ns = (tscdeadline - guest_tsc) * 1000000ULL; do_div(ns, this_tsc_khz); - } - hrtimer_start(&apic->lapic_timer.timer, - ktime_add_ns(now, ns), HRTIMER_MODE_ABS); + hrtimer_start(&apic->lapic_timer.timer, + ktime_add_ns(now, ns), HRTIMER_MODE_ABS); + } else + apic_timer_expired(apic); local_irq_restore(flags); } @@ -1391,9 +1392,6 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) return; hrtimer_cancel(&apic->lapic_timer.timer); - /* Inject here so clearing tscdeadline won't override new value */ - if (apic_has_pending_timer(vcpu)) - kvm_inject_apic_timer_irqs(vcpu); apic->lapic_timer.tscdeadline = data; start_apic_timer(apic); } -- GitLab From 7f05db6a20fe4d85bada20d365c78029831b9de1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 12 Oct 2014 11:34:00 +0300 Subject: [PATCH 2480/9457] kvm: drop unsupported capabilities, fix documentation No kernel ever reported KVM_CAP_DEVICE_MSIX, KVM_CAP_DEVICE_MSI, KVM_CAP_DEVICE_ASSIGNMENT, KVM_CAP_DEVICE_DEASSIGNMENT. This makes the documentation wrong, and no application ever written to use these capabilities has a chance to work correctly. The only way to detect support is to try, and test errno for ENOTTY. That's unfortunate, but we can't fix the past. Document the actual semantics, and drop the definitions from the exported header to make it easier for application developers to note and fix the bug. Signed-off-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- Documentation/virtual/kvm/api.txt | 40 +++++++++++++++++++++++++------ include/uapi/linux/kvm.h | 8 ------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 7610eaa4d491..7a943c23db1c 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -68,9 +68,12 @@ description: Capability: which KVM extension provides this ioctl. Can be 'basic', which means that is will be provided by any kernel that supports - API version 12 (see section 4.1), or a KVM_CAP_xyz constant, which + API version 12 (see section 4.1), a KVM_CAP_xyz constant, which means availability needs to be checked with KVM_CHECK_EXTENSION - (see section 4.4). + (see section 4.4), or 'none' which means that while not all kernels + support this ioctl, there's no capability bit to check its + availability: for kernels that don't support the ioctl, + the ioctl returns -ENOTTY. Architectures: which instruction set architectures provide this ioctl. x86 includes both i386 and x86_64. @@ -1257,7 +1260,7 @@ The flags bitmap is defined as: 4.48 KVM_ASSIGN_PCI_DEVICE -Capability: KVM_CAP_DEVICE_ASSIGNMENT +Capability: none Architectures: x86 ia64 Type: vm ioctl Parameters: struct kvm_assigned_pci_dev (in) @@ -1298,10 +1301,16 @@ Only PCI header type 0 devices with PCI BAR resources are supported by device assignment. The user requesting this ioctl must have read/write access to the PCI sysfs resource files associated with the device. +Errors: + ENOTTY: kernel does not support this ioctl + + Other error conditions may be defined by individual device types or + have their standard meanings. + 4.49 KVM_DEASSIGN_PCI_DEVICE -Capability: KVM_CAP_DEVICE_DEASSIGNMENT +Capability: none Architectures: x86 ia64 Type: vm ioctl Parameters: struct kvm_assigned_pci_dev (in) @@ -1309,9 +1318,14 @@ Returns: 0 on success, -1 on error Ends PCI device assignment, releasing all associated resources. -See KVM_CAP_DEVICE_ASSIGNMENT for the data structure. Only assigned_dev_id is +See KVM_ASSIGN_PCI_DEVICE for the data structure. Only assigned_dev_id is used in kvm_assigned_pci_dev to identify the device. +Errors: + ENOTTY: kernel does not support this ioctl + + Other error conditions may be defined by individual device types or + have their standard meanings. 4.50 KVM_ASSIGN_DEV_IRQ @@ -1346,6 +1360,12 @@ The following flags are defined: It is not valid to specify multiple types per host or guest IRQ. However, the IRQ type of host and guest can differ or can even be null. +Errors: + ENOTTY: kernel does not support this ioctl + + Other error conditions may be defined by individual device types or + have their standard meanings. + 4.51 KVM_DEASSIGN_DEV_IRQ @@ -1423,7 +1443,7 @@ struct kvm_irq_routing_s390_adapter { 4.53 KVM_ASSIGN_SET_MSIX_NR -Capability: KVM_CAP_DEVICE_MSIX +Capability: none Architectures: x86 ia64 Type: vm ioctl Parameters: struct kvm_assigned_msix_nr (in) @@ -1445,7 +1465,7 @@ struct kvm_assigned_msix_nr { 4.54 KVM_ASSIGN_SET_MSIX_ENTRY -Capability: KVM_CAP_DEVICE_MSIX +Capability: none Architectures: x86 ia64 Type: vm ioctl Parameters: struct kvm_assigned_msix_entry (in) @@ -1461,6 +1481,12 @@ struct kvm_assigned_msix_entry { __u16 padding[3]; }; +Errors: + ENOTTY: kernel does not support this ioctl + + Other error conditions may be defined by individual device types or + have their standard meanings. + 4.55 KVM_SET_TSC_KHZ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 60768822b140..6d59e5b39c9c 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -647,11 +647,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ -#define KVM_CAP_DEVICE_ASSIGNMENT 17 #define KVM_CAP_IOMMU 18 -#ifdef __KVM_HAVE_MSI -#define KVM_CAP_DEVICE_MSI 20 -#endif /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 #define KVM_CAP_USER_NMI 22 @@ -663,10 +659,6 @@ struct kvm_ppc_smmu_info { #endif #define KVM_CAP_IRQ_ROUTING 25 #define KVM_CAP_IRQ_INJECT_STATUS 26 -#define KVM_CAP_DEVICE_DEASSIGNMENT 27 -#ifdef __KVM_HAVE_MSIX -#define KVM_CAP_DEVICE_MSIX 28 -#endif #define KVM_CAP_ASSIGN_DEV_IRQ 29 /* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30 -- GitLab From 612263b30c900b534fa76609d314ed55c255a94e Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Wed, 22 Oct 2014 17:35:24 +0800 Subject: [PATCH 2481/9457] KVM: x86: Enable Intel AVX-512 for guest Expose Intel AVX-512 feature bits to guest. Also add checks for xcr0 AVX512 related bits according to spec: http://download-software.intel.com/sites/default/files/managed/71/2e/319433-017.pdf Signed-off-by: Chao Peng Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/xsave.h | 1 + arch/x86/kvm/cpuid.c | 3 ++- arch/x86/kvm/x86.c | 6 ++++++ arch/x86/kvm/x86.h | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 7e7a79ada658..5fa9770035dc 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -16,6 +16,7 @@ #define XSTATE_Hi16_ZMM 0x80 #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) +#define XSTATE_AVX512 (XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) /* Bit 63 of XCR0 is reserved for future expansion */ #define XSTATE_EXTEND_MASK (~(XSTATE_FPSSE | (1ULL << 63))) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 976e3a57f9ea..20d83217fb1d 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -317,7 +317,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, const u32 kvm_supported_word9_x86_features = F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | - F(ADX) | F(SMAP); + F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) | + F(AVX512CD); /* all calls to cpuid_count() should be made on the same cpu */ get_cpu(); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7a9cb56407bd..14c49cf3f77f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -666,6 +666,12 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) if ((!(xcr0 & XSTATE_BNDREGS)) != (!(xcr0 & XSTATE_BNDCSR))) return 1; + if (xcr0 & XSTATE_AVX512) { + if (!(xcr0 & XSTATE_YMM)) + return 1; + if ((xcr0 & XSTATE_AVX512) != XSTATE_AVX512) + return 1; + } kvm_put_guest_xcr0(vcpu); vcpu->arch.xcr0 = xcr0; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 7cb9c45a5fe0..cc1d61af6140 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -162,7 +162,8 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data); #define KVM_SUPPORTED_XCR0 (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ - | XSTATE_BNDREGS | XSTATE_BNDCSR) + | XSTATE_BNDREGS | XSTATE_BNDCSR \ + | XSTATE_AVX512) extern u64 host_xcr0; extern u64 kvm_supported_xcr0(void); -- GitLab From 02d5d55b7e39b63feb71bc49a75f58d342527d16 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Mon, 27 Oct 2014 16:22:56 +0100 Subject: [PATCH 2482/9457] KVM: trivial fix comment regarding __kvm_set_memory_region commit 72dc67a69690 ("KVM: remove the usage of the mmap_sem for the protection of the memory slots.") changed the lock which will be taken. This should be reflected in the function commentary. Signed-off-by: Dominik Dingel Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 25ffac9e947d..3a31ec6e396b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -760,7 +760,7 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, * * Discontiguous memory is allowed, mostly for framebuffers. * - * Must be called holding mmap_sem for write. + * Must be called holding kvm->slots_lock for write. */ int __kvm_set_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem) -- GitLab From e462755cae2bf8297a663278935ad4d59812d2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 30 Oct 2014 15:06:45 +0100 Subject: [PATCH 2483/9457] KVM: x86: detect SPIV changes under APICv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit APIC-write VM exits are "trap-like": they save CS:RIP values for the instruction after the write, and more importantly, the handler will already see the new value in the virtual-APIC page. This caused a bug if you used KVM_SET_IRQCHIP to set the SW-enabled bit in the SPIV register. The chain of events is as follows: * When the irqchip is added to the destination VM, the apic_sw_disabled static key is incremented (1) * When the KVM_SET_IRQCHIP ioctl is invoked, it is decremented (0) * When the guest disables the bit in the SPIV register, e.g. as part of shutdown, apic_set_spiv does not notice the change and the static key is _not_ incremented. * When the guest is destroyed, the static key is decremented (-1), resulting in this trace: WARNING: at kernel/jump_label.c:81 __static_key_slow_dec+0xa6/0xb0() jump label: negative count! [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x61/0x80 [] warn_slowpath_fmt+0x5c/0x80 [] __static_key_slow_dec+0xa6/0xb0 [] static_key_slow_dec_deferred+0x16/0x20 [] kvm_free_lapic+0x88/0xa0 [kvm] [] kvm_arch_vcpu_uninit+0x2e/0xe0 [kvm] [] kvm_vcpu_uninit+0x21/0x40 [kvm] [] vmx_free_vcpu+0x47/0x70 [kvm_intel] [] kvm_arch_vcpu_free+0x50/0x60 [kvm] [] kvm_arch_destroy_vm+0x102/0x260 [kvm] [] ? synchronize_srcu+0x1d/0x20 [] kvm_put_kvm+0xe1/0x1c0 [kvm] [] kvm_vcpu_release+0x18/0x20 [kvm] [] __fput+0x102/0x310 [] ____fput+0xe/0x10 [] task_work_run+0xb4/0xe0 [] do_exit+0x304/0xc60 [] ? _raw_spin_unlock_irq+0x2c/0x50 [] ? trace_hardirqs_on_caller+0xfd/0x1c0 [] do_group_exit+0x4c/0xc0 [] SyS_exit_group+0x14/0x20 [] system_call_fastpath+0x16/0x1b Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 10 ++++++---- arch/x86/kvm/lapic.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 66dd1731ab99..80df439d4086 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -206,11 +206,13 @@ static void recalculate_apic_map(struct kvm *kvm) static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) { - u32 prev = kvm_apic_get_reg(apic, APIC_SPIV); + bool enabled = val & APIC_SPIV_APIC_ENABLED; apic_set_reg(apic, APIC_SPIV, val); - if ((prev ^ val) & APIC_SPIV_APIC_ENABLED) { - if (val & APIC_SPIV_APIC_ENABLED) { + + if (enabled != apic->sw_enabled) { + apic->sw_enabled = enabled; + if (enabled) { static_key_slow_dec_deferred(&apic_sw_disabled); recalculate_apic_map(apic->vcpu->kvm); } else @@ -1357,7 +1359,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu) if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) static_key_slow_dec_deferred(&apic_hw_disabled); - if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED)) + if (!apic->sw_enabled) static_key_slow_dec_deferred(&apic_sw_disabled); if (apic->regs) diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 3fd6c22d187d..87e0fae1f4c6 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -22,6 +22,7 @@ struct kvm_lapic { struct kvm_timer lapic_timer; u32 divide_count; struct kvm_vcpu *vcpu; + bool sw_enabled; bool irr_pending; /* Number of bits set in ISR. */ s16 isr_count; -- GitLab From a323b409820c8afd33fbd841f5534eb84b406e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 30 Oct 2014 15:06:46 +0100 Subject: [PATCH 2484/9457] KVM: x86: detect LVTT changes under APICv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit APIC-write VM exits are "trap-like": they save CS:RIP values for the instruction after the write, and more importantly, the handler will already see the new value in the virtual-APIC page. This means that apic_reg_write cannot use kvm_apic_get_reg to omit timer cancelation when mode changes. timer_mode_mask shouldn't be changing as it depends on cpuid. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 12 ++++++++---- arch/x86/kvm/lapic.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 80df439d4086..fa3c6f7fdca4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1242,17 +1242,20 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) break; - case APIC_LVTT: - if ((kvm_apic_get_reg(apic, APIC_LVTT) & - apic->lapic_timer.timer_mode_mask) != - (val & apic->lapic_timer.timer_mode_mask)) + case APIC_LVTT: { + u32 timer_mode = val & apic->lapic_timer.timer_mode_mask; + + if (apic->lapic_timer.timer_mode != timer_mode) { + apic->lapic_timer.timer_mode = timer_mode; hrtimer_cancel(&apic->lapic_timer.timer); + } if (!kvm_apic_sw_enabled(apic)) val |= APIC_LVT_MASKED; val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); apic_set_reg(apic, APIC_LVTT, val); break; + } case APIC_TMICT: if (apic_lvtt_tscdeadline(apic)) @@ -1483,6 +1486,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) for (i = 0; i < APIC_LVT_NUM; i++) apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); + apic->lapic_timer.timer_mode = 0; apic_set_reg(apic, APIC_LVT0, SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 87e0fae1f4c6..35d83dcae8f9 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -11,6 +11,7 @@ struct kvm_timer { struct hrtimer timer; s64 period; /* unit: ns */ + u32 timer_mode; u32 timer_mode_mask; u64 tscdeadline; atomic_t pending; /* accumulated triggered timers */ -- GitLab From f30ebc312ca9def25650b4e1d01cdb425c310dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 30 Oct 2014 15:06:47 +0100 Subject: [PATCH 2485/9457] KVM: x86: optimize some accesses to LVTT and SPIV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We mirror a subset of these registers in separate variables. Using them directly should be faster. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 10 +++------- arch/x86/kvm/lapic.h | 6 +++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index fa3c6f7fdca4..5f574b4add90 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -244,21 +244,17 @@ static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) { - return ((kvm_apic_get_reg(apic, APIC_LVTT) & - apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT); + return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_ONESHOT; } static inline int apic_lvtt_period(struct kvm_lapic *apic) { - return ((kvm_apic_get_reg(apic, APIC_LVTT) & - apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC); + return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_PERIODIC; } static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic) { - return ((kvm_apic_get_reg(apic, APIC_LVTT) & - apic->lapic_timer.timer_mode_mask) == - APIC_LVT_TIMER_TSCDEADLINE); + return apic->lapic_timer.timer_mode == APIC_LVT_TIMER_TSCDEADLINE; } static inline int apic_lvt_nmi_mode(u32 lvt_val) diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 35d83dcae8f9..d4365f21ea2e 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -121,11 +121,11 @@ static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic) extern struct static_key_deferred apic_sw_disabled; -static inline int kvm_apic_sw_enabled(struct kvm_lapic *apic) +static inline bool kvm_apic_sw_enabled(struct kvm_lapic *apic) { if (static_key_false(&apic_sw_disabled.key)) - return kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED; - return APIC_SPIV_APIC_ENABLED; + return apic->sw_enabled; + return true; } static inline bool kvm_apic_present(struct kvm_vcpu *vcpu) -- GitLab From c6338ce494456ed9c92ef10f63c0a8408bfeac6d Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Fri, 26 Sep 2014 14:00:04 +0800 Subject: [PATCH 2486/9457] kvm: kvmclock: use get_cpu() and put_cpu() We can use get_cpu() and put_cpu() to replace preempt_disable()/cpu = smp_processor_id() and preempt_enable() for slightly better code. Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kernel/kvmclock.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index d9156ceecdff..0bf3467d7f30 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -59,13 +59,12 @@ static void kvm_get_wallclock(struct timespec *now) native_write_msr(msr_kvm_wall_clock, low, high); - preempt_disable(); - cpu = smp_processor_id(); + cpu = get_cpu(); vcpu_time = &hv_clock[cpu].pvti; pvclock_read_wallclock(&wall_clock, vcpu_time, now); - preempt_enable(); + put_cpu(); } static int kvm_set_wallclock(const struct timespec *now) @@ -107,11 +106,10 @@ static unsigned long kvm_get_tsc_khz(void) int cpu; unsigned long tsc_khz; - preempt_disable(); - cpu = smp_processor_id(); + cpu = get_cpu(); src = &hv_clock[cpu].pvti; tsc_khz = pvclock_tsc_khz(src); - preempt_enable(); + put_cpu(); return tsc_khz; } @@ -284,23 +282,22 @@ int __init kvm_setup_vsyscall_timeinfo(void) size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS); - preempt_disable(); - cpu = smp_processor_id(); + cpu = get_cpu(); vcpu_time = &hv_clock[cpu].pvti; flags = pvclock_read_flags(vcpu_time); if (!(flags & PVCLOCK_TSC_STABLE_BIT)) { - preempt_enable(); + put_cpu(); return 1; } if ((ret = pvclock_init_vsyscall(hv_clock, size))) { - preempt_enable(); + put_cpu(); return ret; } - preempt_enable(); + put_cpu(); kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK; #endif -- GitLab From bf9706fe958469e7dfc6a9e16d9240892f055e62 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 3 Nov 2014 13:10:53 +0300 Subject: [PATCH 2487/9457] ASoC: tlv320aic23: add dependencies on I2C/SPI_MASTER This fixes build errors in configurations with I2C/SPI master disabled. Reported-by: Fengguang Wu Signed-off-by: Max Filippov Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 7881b3c35b4d..1e7a4173a3f9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -582,10 +582,12 @@ config SND_SOC_TLV320AIC23 config SND_SOC_TLV320AIC23_I2C tristate "Texas Instruments TLV320AIC23 audio CODEC - I2C" + depends on I2C select SND_SOC_TLV320AIC23 config SND_SOC_TLV320AIC23_SPI tristate "Texas Instruments TLV320AIC23 audio CODEC - SPI" + depends on SPI_MASTER select SND_SOC_TLV320AIC23 config SND_SOC_TLV320AIC26 -- GitLab From 7204a785e70cdc5bb5abae5342f179ede5322260 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 17 Oct 2014 03:14:47 +0000 Subject: [PATCH 2488/9457] i40e: remove debugfs dump stats The debugfs dump stats wasn't being kept up-to-date, was redundant with the ethtool output, and didn't offer any useful additional info. Rather than continue trying to keep them aligned, just remove the debugfs command. Change-ID: Id130ed9aef01c6369ab662c7b4c5ec5b1dbc5b40 Signed-off-by: Shannon Nelson Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/i40e/i40e_debugfs.c | 93 +------------------ 1 file changed, 2 insertions(+), 91 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 7067f4b9159c..a03f4590cb0f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -894,90 +894,6 @@ static void i40e_dbg_dump_eth_stats(struct i40e_pf *pf, estats->tx_discards, estats->tx_errors); } -/** - * i40e_dbg_dump_stats - handles dump stats write into command datum - * @pf: the i40e_pf created in command write - * @stats: the stats structure to be dumped - **/ -static void i40e_dbg_dump_stats(struct i40e_pf *pf, - struct i40e_hw_port_stats *stats) -{ - int i; - - dev_info(&pf->pdev->dev, " stats:\n"); - dev_info(&pf->pdev->dev, - " crc_errors = \t\t%lld \tillegal_bytes = \t%lld \terror_bytes = \t\t%lld\n", - stats->crc_errors, stats->illegal_bytes, stats->error_bytes); - dev_info(&pf->pdev->dev, - " mac_local_faults = \t%lld \tmac_remote_faults = \t%lld \trx_length_errors = \t%lld\n", - stats->mac_local_faults, stats->mac_remote_faults, - stats->rx_length_errors); - dev_info(&pf->pdev->dev, - " link_xon_rx = \t\t%lld \tlink_xoff_rx = \t\t%lld \tlink_xon_tx = \t\t%lld\n", - stats->link_xon_rx, stats->link_xoff_rx, stats->link_xon_tx); - dev_info(&pf->pdev->dev, - " link_xoff_tx = \t\t%lld \trx_size_64 = \t\t%lld \trx_size_127 = \t\t%lld\n", - stats->link_xoff_tx, stats->rx_size_64, stats->rx_size_127); - dev_info(&pf->pdev->dev, - " rx_size_255 = \t\t%lld \trx_size_511 = \t\t%lld \trx_size_1023 = \t\t%lld\n", - stats->rx_size_255, stats->rx_size_511, stats->rx_size_1023); - dev_info(&pf->pdev->dev, - " rx_size_big = \t\t%lld \trx_undersize = \t\t%lld \trx_jabber = \t\t%lld\n", - stats->rx_size_big, stats->rx_undersize, stats->rx_jabber); - dev_info(&pf->pdev->dev, - " rx_fragments = \t\t%lld \trx_oversize = \t\t%lld \ttx_size_64 = \t\t%lld\n", - stats->rx_fragments, stats->rx_oversize, stats->tx_size_64); - dev_info(&pf->pdev->dev, - " tx_size_127 = \t\t%lld \ttx_size_255 = \t\t%lld \ttx_size_511 = \t\t%lld\n", - stats->tx_size_127, stats->tx_size_255, stats->tx_size_511); - dev_info(&pf->pdev->dev, - " tx_size_1023 = \t\t%lld \ttx_size_big = \t\t%lld \tmac_short_packet_dropped = \t%lld\n", - stats->tx_size_1023, stats->tx_size_big, - stats->mac_short_packet_dropped); - for (i = 0; i < 8; i += 4) { - dev_info(&pf->pdev->dev, - " priority_xon_rx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", - i, stats->priority_xon_rx[i], - i+1, stats->priority_xon_rx[i+1], - i+2, stats->priority_xon_rx[i+2], - i+3, stats->priority_xon_rx[i+3]); - } - for (i = 0; i < 8; i += 4) { - dev_info(&pf->pdev->dev, - " priority_xoff_rx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", - i, stats->priority_xoff_rx[i], - i+1, stats->priority_xoff_rx[i+1], - i+2, stats->priority_xoff_rx[i+2], - i+3, stats->priority_xoff_rx[i+3]); - } - for (i = 0; i < 8; i += 4) { - dev_info(&pf->pdev->dev, - " priority_xon_tx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", - i, stats->priority_xon_tx[i], - i+1, stats->priority_xon_tx[i+1], - i+2, stats->priority_xon_tx[i+2], - i+3, stats->priority_xon_rx[i+3]); - } - for (i = 0; i < 8; i += 4) { - dev_info(&pf->pdev->dev, - " priority_xoff_tx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", - i, stats->priority_xoff_tx[i], - i+1, stats->priority_xoff_tx[i+1], - i+2, stats->priority_xoff_tx[i+2], - i+3, stats->priority_xoff_tx[i+3]); - } - for (i = 0; i < 8; i += 4) { - dev_info(&pf->pdev->dev, - " priority_xon_2_xoff[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", - i, stats->priority_xon_2_xoff[i], - i+1, stats->priority_xon_2_xoff[i+1], - i+2, stats->priority_xon_2_xoff[i+2], - i+3, stats->priority_xon_2_xoff[i+3]); - } - - i40e_dbg_dump_eth_stats(pf, &stats->eth); -} - /** * i40e_dbg_dump_veb_seid - handles dump stats of a single given veb * @pf: the i40e_pf created in command write @@ -1342,11 +1258,6 @@ static ssize_t i40e_dbg_command_write(struct file *filp, "dump desc rx []\n"); dev_info(&pf->pdev->dev, "dump desc aq\n"); } - } else if (strncmp(&cmd_buf[5], "stats", 5) == 0) { - dev_info(&pf->pdev->dev, "pf stats:\n"); - i40e_dbg_dump_stats(pf, &pf->stats); - dev_info(&pf->pdev->dev, "pf stats_offsets:\n"); - i40e_dbg_dump_stats(pf, &pf->stats_offsets); } else if (strncmp(&cmd_buf[5], "reset stats", 11) == 0) { dev_info(&pf->pdev->dev, "core reset count: %d\n", pf->corer_count); @@ -1464,8 +1375,8 @@ static ssize_t i40e_dbg_command_write(struct file *filp, } else { dev_info(&pf->pdev->dev, "dump desc tx [], dump desc rx [],\n"); - dev_info(&pf->pdev->dev, "dump switch, dump vsi [seid] or\n"); - dev_info(&pf->pdev->dev, "dump stats\n"); + dev_info(&pf->pdev->dev, "dump switch\n"); + dev_info(&pf->pdev->dev, "dump vsi [seid]\n"); dev_info(&pf->pdev->dev, "dump reset stats\n"); dev_info(&pf->pdev->dev, "dump port\n"); dev_info(&pf->pdev->dev, -- GitLab From c135b0de9b853c5cd910b3b461356fedeffca2fa Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 17 Oct 2014 03:14:49 +0000 Subject: [PATCH 2489/9457] i40e: scale msix vector use when more cores than vectors When there are more cores than vectors available to the PF, scale back the LAN msix usage to force queue/vector sharing and leave some vectors for Flow Director, VMDq, etc. Change-ID: Ie0317732eb85ad8d851d7da7d9af86b1bf8c21ad Signed-off-by: Shannon Nelson Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f95c04a906dd..83fee7ffce07 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6699,6 +6699,7 @@ static int i40e_init_msix(struct i40e_pf *pf) { i40e_status err = 0; struct i40e_hw *hw = &pf->hw; + int other_vecs = 0; int v_budget, i; int vec; @@ -6724,10 +6725,10 @@ static int i40e_init_msix(struct i40e_pf *pf) */ pf->num_lan_msix = pf->num_lan_qps - (pf->rss_size_max - pf->rss_size); pf->num_vmdq_msix = pf->num_vmdq_qps; - v_budget = 1 + pf->num_lan_msix; - v_budget += (pf->num_vmdq_vsis * pf->num_vmdq_msix); + other_vecs = 1; + other_vecs += (pf->num_vmdq_vsis * pf->num_vmdq_msix); if (pf->flags & I40E_FLAG_FD_SB_ENABLED) - v_budget++; + other_vecs++; #ifdef I40E_FCOE if (pf->flags & I40E_FLAG_FCOE_ENABLED) { @@ -6737,7 +6738,9 @@ static int i40e_init_msix(struct i40e_pf *pf) #endif /* Scale down if necessary, and the rings will share vectors */ - v_budget = min_t(int, v_budget, hw->func_caps.num_msix_vectors); + pf->num_lan_msix = min_t(int, pf->num_lan_msix, + (hw->func_caps.num_msix_vectors - other_vecs)); + v_budget = pf->num_lan_msix + other_vecs; pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), GFP_KERNEL); -- GitLab From 049a2be828e5a48a4183aae19e5586fa661439d8 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 17 Oct 2014 03:14:50 +0000 Subject: [PATCH 2490/9457] i40e: better wording for resource tracking errors Tweak and homogenize the error reporting for get_lump() resource tracking errors. Change-ID: I11330161cc6ad8d04371c499c63071c816171c3b Signed-off-by: Shannon Nelson Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 83fee7ffce07..6a481bfeb09d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7957,8 +7957,8 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi) vsi->num_q_vectors, vsi->idx); if (vsi->base_vector < 0) { dev_info(&pf->pdev->dev, - "failed to get queue tracking for VSI %d, err=%d\n", - vsi->seid, vsi->base_vector); + "failed to get tracking for %d vectors for VSI %d, err=%d\n", + vsi->num_q_vectors, vsi->seid, vsi->base_vector); i40e_vsi_free_q_vectors(vsi); ret = -ENOENT; goto vector_setup_out; @@ -7994,8 +7994,9 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi) ret = i40e_get_lump(pf, pf->qp_pile, vsi->alloc_queue_pairs, vsi->idx); if (ret < 0) { - dev_info(&pf->pdev->dev, "VSI %d get_lump failed %d\n", - vsi->seid, ret); + dev_info(&pf->pdev->dev, + "failed to get tracking for %d queues for VSI %d err=%d\n", + vsi->alloc_queue_pairs, vsi->seid, ret); goto err_vsi; } vsi->base_queue = ret; @@ -8124,8 +8125,9 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, ret = i40e_get_lump(pf, pf->qp_pile, vsi->alloc_queue_pairs, vsi->idx); if (ret < 0) { - dev_info(&pf->pdev->dev, "VSI %d get_lump failed %d\n", - vsi->seid, ret); + dev_info(&pf->pdev->dev, + "failed to get tracking for %d queues for VSI %d err=%d\n", + vsi->alloc_queue_pairs, vsi->seid, ret); goto err_vsi; } vsi->base_queue = ret; -- GitLab From 9ce63dbd5d2671a209a859ee90f7dc6b8f22f28e Mon Sep 17 00:00:00 2001 From: Jianqun Date: Sat, 1 Nov 2014 10:58:18 +0800 Subject: [PATCH 2491/9457] ASoC: rockchip: i2s: add text after tristate for SND_SOC_ROCKCHIP_I2S For SND_SOC_ROCKCHIP_I2S, adding some text after the tristate to make this directly user selectable. Signed-off-by: Jianqun Signed-off-by: Mark Brown --- sound/soc/rockchip/Kconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index 78fc159559b0..b1fc0ca3e617 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -8,4 +8,9 @@ config SND_SOC_ROCKCHIP select the audio interfaces to support below. config SND_SOC_ROCKCHIP_I2S - tristate + tristate "Rockchip I2S Device Driver" + depends on CLKDEV_LOOKUP + help + Say Y or M if you want to add support for I2S driver for + Rockchip I2S device. The device supports upto maximum of + 8 channels each for play and record. -- GitLab From 5b5faa434a008e41edcba6d00add5fd591287a54 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 17 Oct 2014 03:14:51 +0000 Subject: [PATCH 2492/9457] i40e: enable debug earlier Check the debug module parameter earlier to be able to catch the early configuration phase adminq messages. Change-ID: Ic84fabd72393489bbf96042de770790a80fd8468 Signed-off-by: Shannon Nelson Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 6a481bfeb09d..ea622676ebe7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9023,6 +9023,11 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw->bus.func = PCI_FUNC(pdev->devfn); pf->instance = pfs_found; + if (debug != -1) { + pf->msg_enable = pf->hw.debug_mask; + pf->msg_enable = debug; + } + /* do a special CORER for clearing PXE mode once at init */ if (hw->revision_id == 0 && (rd32(hw, I40E_GLLAN_RCTL_0) & I40E_GLLAN_RCTL_0_PXE_MODE_MASK)) { -- GitLab From dd63a9c2952ed142c64fd68c1a74d0d6fcac586f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Nov 2014 10:31:47 +0100 Subject: [PATCH 2493/9457] ASoC: Remove snd_soc_platform_driver suspend/resume callbacks Those are unused and new drivers should use device driver suspend/resume. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ---- sound/soc/soc-core.c | 10 ---------- 2 files changed, 14 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index ad47e9660b22..edbb07ba4cb5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -857,8 +857,6 @@ struct snd_soc_platform_driver { int (*probe)(struct snd_soc_platform *); int (*remove)(struct snd_soc_platform *); - int (*suspend)(struct snd_soc_dai *dai); - int (*resume)(struct snd_soc_dai *dai); struct snd_soc_component_driver component_driver; /* pcm creation and destruction */ @@ -891,8 +889,6 @@ struct snd_soc_platform { struct device *dev; const struct snd_soc_platform_driver *driver; - unsigned int suspended:1; /* platform is suspended */ - struct list_head list; struct snd_soc_component component; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a2b51edf6d83..0509d726759d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -592,17 +592,12 @@ int snd_soc_suspend(struct device *dev) for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; - struct snd_soc_platform *platform = card->rtd[i].platform; if (card->rtd[i].dai_link->ignore_suspend) continue; if (cpu_dai->driver->suspend && !cpu_dai->driver->ac97_control) cpu_dai->driver->suspend(cpu_dai); - if (platform->driver->suspend && !platform->suspended) { - platform->driver->suspend(cpu_dai); - platform->suspended = 1; - } } /* close any waiting streams and save state */ @@ -775,17 +770,12 @@ static void soc_resume_deferred(struct work_struct *work) for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; - struct snd_soc_platform *platform = card->rtd[i].platform; if (card->rtd[i].dai_link->ignore_suspend) continue; if (cpu_dai->driver->resume && !cpu_dai->driver->ac97_control) cpu_dai->driver->resume(cpu_dai); - if (platform->driver->resume && platform->suspended) { - platform->driver->resume(cpu_dai); - platform->suspended = 0; - } } if (card->resume_post) -- GitLab From 2a374b78f5c2b5f31d35f8a7cd004989d6936756 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Nov 2014 10:31:48 +0100 Subject: [PATCH 2494/9457] ASoC: Remove platform field from snd_soc_dai Typically a DAI does not need direct access to the platform. Currently the only user of this field is in a platform driver where we have a more direct way of getting a pointer to the platform. This patch updates the driver to use the more direct way and then removes the platform field from the snd_soc_dai struct. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 1 - sound/soc/soc-core.c | 2 -- sound/soc/txx9/txx9aclc.c | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index e8b3080d196a..45d0fa10ab9e 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -268,7 +268,6 @@ struct snd_soc_dai { unsigned int sample_bits; /* parent platform/codec */ - struct snd_soc_platform *platform; struct snd_soc_codec *codec; struct snd_soc_component *component; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0509d726759d..e20bb65a1634 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1309,7 +1309,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int i, ret; @@ -1317,7 +1316,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) card->name, num, order); /* config components */ - cpu_dai->platform = platform; cpu_dai->card = card; for (i = 0; i < rtd->num_codecs; i++) rtd->codec_dais[i]->card = card; diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index cd71fd889d8b..00b7e2d02690 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -292,7 +292,7 @@ static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd) struct snd_card *card = rtd->card->snd_card; struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; - struct platform_device *pdev = to_platform_device(dai->platform->dev); + struct platform_device *pdev = to_platform_device(rtd->platform->dev); struct txx9aclc_soc_device *dev; struct resource *r; int i; -- GitLab From 7a28d8857ddc3986b62ae1a41dc551453718b4b3 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 17 Oct 2014 03:14:52 +0000 Subject: [PATCH 2495/9457] i40e: configure VM ID in qtx_ctl We must insert the VSI ID in the QTX_CTL register when configuring queues for VMDQ VSIs. Change-ID: Iedfe36bd42ca0adc90a7cc2b7cf04795a98f4761 Reported-by: Marc Neustadter Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ea622676ebe7..1b0c437dae21 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2462,10 +2462,14 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring) } /* Now associate this queue with this PCI function */ - if (vsi->type == I40E_VSI_VMDQ2) + if (vsi->type == I40E_VSI_VMDQ2) { qtx_ctl = I40E_QTX_CTL_VM_QUEUE; - else + qtx_ctl |= ((vsi->id) << I40E_QTX_CTL_VFVM_INDX_SHIFT) & + I40E_QTX_CTL_VFVM_INDX_MASK; + } else { qtx_ctl = I40E_QTX_CTL_PF_QUEUE; + } + qtx_ctl |= ((hw->pf_id << I40E_QTX_CTL_PF_INDX_SHIFT) & I40E_QTX_CTL_PF_INDX_MASK); wr32(hw, I40E_QTX_CTL(pf_q), qtx_ctl); -- GitLab From 4476159f0b73e58e8c4d750ce03843d70c13994c Mon Sep 17 00:00:00 2001 From: Jianqun Date: Sat, 1 Nov 2014 11:22:18 +0800 Subject: [PATCH 2496/9457] ASoC: simple-card: add "invert" property for detect GPIOs Since hardware may invert detect GPIO of headphone or mic, add one property to support software invert. Signed-off-by: Jianqun Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index cac95d79fc8f..cd49d5010e14 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -29,7 +29,9 @@ struct simple_card_data { } *dai_props; unsigned int mclk_fs; int gpio_hp_det; + int gpio_hp_det_invert; int gpio_mic_det; + int gpio_mic_det_invert; struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ }; @@ -148,6 +150,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) simple_card_hp_jack_pins); simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; + simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert; snd_soc_jack_add_gpios(&simple_card_hp_jack, 1, &simple_card_hp_jack_gpio); } @@ -159,6 +162,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(simple_card_mic_jack_pins), simple_card_mic_jack_pins); simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; + simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert; snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, &simple_card_mic_jack_gpio); } @@ -374,6 +378,7 @@ static int asoc_simple_card_parse_of(struct device_node *node, struct simple_card_data *priv) { struct device *dev = simple_priv_to_dev(priv); + enum of_gpio_flags flags; u32 val; int ret; @@ -429,13 +434,15 @@ static int asoc_simple_card_parse_of(struct device_node *node, return ret; } - priv->gpio_hp_det = of_get_named_gpio(node, - "simple-audio-card,hp-det-gpio", 0); + priv->gpio_hp_det = of_get_named_gpio_flags(node, + "simple-audio-card,hp-det-gpio", 0, &flags); + priv->gpio_hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); if (priv->gpio_hp_det == -EPROBE_DEFER) return -EPROBE_DEFER; - priv->gpio_mic_det = of_get_named_gpio(node, - "simple-audio-card,mic-det-gpio", 0); + priv->gpio_mic_det = of_get_named_gpio_flags(node, + "simple-audio-card,mic-det-gpio", 0, &flags); + priv->gpio_mic_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); if (priv->gpio_mic_det == -EPROBE_DEFER) return -EPROBE_DEFER; -- GitLab From f318a1229bd8d377282ddb37158812073701a22b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 29 Oct 2014 12:50:31 +0100 Subject: [PATCH 2497/9457] s390/cmpxchg: use compiler builtins The kernel build for s390 fails for gcc compilers with version 3.x, set the minimum required version of gcc to version 4.3. As the atomic builtins are available with all gcc 4.x compilers, use the __sync_val_compare_and_swap and __sync_bool_compare_and_swap functions to replace the complex macro and inline assembler magic in include/asm/cmpxchg.h. The compiler can just-do-it and generates better code with the builtins. While we are at it use __sync_bool_compare_and_swap for the _raw_compare_and_swap function in the spinlock code as well. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cmpxchg.h | 240 +++---------------------------- arch/s390/include/asm/spinlock.h | 9 +- arch/s390/kernel/asm-offsets.c | 4 +- 3 files changed, 19 insertions(+), 234 deletions(-) diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h index 4236408070e5..6259895fcd97 100644 --- a/arch/s390/include/asm/cmpxchg.h +++ b/arch/s390/include/asm/cmpxchg.h @@ -11,200 +11,28 @@ #include #include -extern void __xchg_called_with_bad_pointer(void); - -static inline unsigned long __xchg(unsigned long x, void *ptr, int size) -{ - unsigned long addr, old; - int shift; - - switch (size) { - case 1: - addr = (unsigned long) ptr; - shift = (3 ^ (addr & 3)) << 3; - addr ^= addr & 3; - asm volatile( - " l %0,%4\n" - "0: lr 0,%0\n" - " nr 0,%3\n" - " or 0,%2\n" - " cs %0,0,%4\n" - " jl 0b\n" - : "=&d" (old), "=Q" (*(int *) addr) - : "d" ((x & 0xff) << shift), "d" (~(0xff << shift)), - "Q" (*(int *) addr) : "memory", "cc", "0"); - return old >> shift; - case 2: - addr = (unsigned long) ptr; - shift = (2 ^ (addr & 2)) << 3; - addr ^= addr & 2; - asm volatile( - " l %0,%4\n" - "0: lr 0,%0\n" - " nr 0,%3\n" - " or 0,%2\n" - " cs %0,0,%4\n" - " jl 0b\n" - : "=&d" (old), "=Q" (*(int *) addr) - : "d" ((x & 0xffff) << shift), "d" (~(0xffff << shift)), - "Q" (*(int *) addr) : "memory", "cc", "0"); - return old >> shift; - case 4: - asm volatile( - " l %0,%3\n" - "0: cs %0,%2,%3\n" - " jl 0b\n" - : "=&d" (old), "=Q" (*(int *) ptr) - : "d" (x), "Q" (*(int *) ptr) - : "memory", "cc"); - return old; -#ifdef CONFIG_64BIT - case 8: - asm volatile( - " lg %0,%3\n" - "0: csg %0,%2,%3\n" - " jl 0b\n" - : "=&d" (old), "=m" (*(long *) ptr) - : "d" (x), "Q" (*(long *) ptr) - : "memory", "cc"); - return old; -#endif /* CONFIG_64BIT */ - } - __xchg_called_with_bad_pointer(); - return x; -} - -#define xchg(ptr, x) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\ - __ret; \ +#define cmpxchg(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) __o = (o); \ + __typeof__(*(ptr)) __n = (n); \ + (__typeof__(*(ptr))) __sync_val_compare_and_swap((ptr),__o,__n);\ }) -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - */ - -#define __HAVE_ARCH_CMPXCHG - -extern void __cmpxchg_called_with_bad_pointer(void); - -static inline unsigned long __cmpxchg(void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long addr, prev, tmp; - int shift; - - switch (size) { - case 1: - addr = (unsigned long) ptr; - shift = (3 ^ (addr & 3)) << 3; - addr ^= addr & 3; - asm volatile( - " l %0,%2\n" - "0: nr %0,%5\n" - " lr %1,%0\n" - " or %0,%3\n" - " or %1,%4\n" - " cs %0,%1,%2\n" - " jnl 1f\n" - " xr %1,%0\n" - " nr %1,%5\n" - " jnz 0b\n" - "1:" - : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) - : "d" ((old & 0xff) << shift), - "d" ((new & 0xff) << shift), - "d" (~(0xff << shift)) - : "memory", "cc"); - return prev >> shift; - case 2: - addr = (unsigned long) ptr; - shift = (2 ^ (addr & 2)) << 3; - addr ^= addr & 2; - asm volatile( - " l %0,%2\n" - "0: nr %0,%5\n" - " lr %1,%0\n" - " or %0,%3\n" - " or %1,%4\n" - " cs %0,%1,%2\n" - " jnl 1f\n" - " xr %1,%0\n" - " nr %1,%5\n" - " jnz 0b\n" - "1:" - : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) - : "d" ((old & 0xffff) << shift), - "d" ((new & 0xffff) << shift), - "d" (~(0xffff << shift)) - : "memory", "cc"); - return prev >> shift; - case 4: - asm volatile( - " cs %0,%3,%1\n" - : "=&d" (prev), "=Q" (*(int *) ptr) - : "0" (old), "d" (new), "Q" (*(int *) ptr) - : "memory", "cc"); - return prev; -#ifdef CONFIG_64BIT - case 8: - asm volatile( - " csg %0,%3,%1\n" - : "=&d" (prev), "=Q" (*(long *) ptr) - : "0" (old), "d" (new), "Q" (*(long *) ptr) - : "memory", "cc"); - return prev; -#endif /* CONFIG_64BIT */ - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#define cmpxchg(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \ - sizeof(*(ptr))); \ - __ret; \ -}) +#define cmpxchg64 cmpxchg +#define cmpxchg_local cmpxchg +#define cmpxchg64_local cmpxchg -#ifdef CONFIG_64BIT -#define cmpxchg64(ptr, o, n) \ +#define xchg(ptr, x) \ ({ \ - cmpxchg((ptr), (o), (n)); \ + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(*(ptr)) __old; \ + do { \ + __old = *__ptr; \ + } while (!__sync_bool_compare_and_swap(__ptr, __old, x)); \ + __old; \ }) -#else /* CONFIG_64BIT */ -static inline unsigned long long __cmpxchg64(void *ptr, - unsigned long long old, - unsigned long long new) -{ - register_pair rp_old = {.pair = old}; - register_pair rp_new = {.pair = new}; - unsigned long long *ullptr = ptr; - asm volatile( - " cds %0,%2,%1" - : "+d" (rp_old), "+Q" (*ullptr) - : "d" (rp_new) - : "memory", "cc"); - return rp_old.pair; -} - -#define cmpxchg64(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg64((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n)); \ - __ret; \ -}) -#endif /* CONFIG_64BIT */ +#define __HAVE_ARCH_CMPXCHG #define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \ ({ \ @@ -265,40 +93,4 @@ extern void __cmpxchg_double_called_with_bad_pointer(void); #define system_has_cmpxchg_double() 1 -#include - -static inline unsigned long __cmpxchg_local(void *ptr, - unsigned long old, - unsigned long new, int size) -{ - switch (size) { - case 1: - case 2: - case 4: -#ifdef CONFIG_64BIT - case 8: -#endif - return __cmpxchg(ptr, old, new, size); - default: - return __cmpxchg_local_generic(ptr, old, new, size); - } - - return old; -} - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg_local((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr))); \ - __ret; \ -}) - -#define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n)) - #endif /* __ASM_CMPXCHG_H */ diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index d6bdf906caa5..0e37cd041241 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -18,14 +18,7 @@ extern int spin_retry; static inline int _raw_compare_and_swap(unsigned int *lock, unsigned int old, unsigned int new) { - unsigned int old_expected = old; - - asm volatile( - " cs %0,%3,%1" - : "=d" (old), "=Q" (*lock) - : "0" (old), "d" (new), "Q" (*lock) - : "cc", "memory" ); - return old == old_expected; + return __sync_bool_compare_and_swap(lock, old, new); } /* diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index f3a78337ca86..e07e91605353 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -17,8 +17,8 @@ * Make sure that the compiler is new enough. We want a compiler that * is known to work with the "Q" assembler constraint. */ -#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) -#error Your compiler is too old; please use version 3.3.3 or newer +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +#error Your compiler is too old; please use version 4.3 or newer #endif int main(void) -- GitLab From b19148f6e2d90738ecf0c2eeeb9bdbae25c59e9b Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 29 Oct 2014 19:12:04 +0100 Subject: [PATCH 2498/9457] s390/pci: improve irq number check for msix s390s arch_setup_msi_irqs function ensures that we don't return with more irqs than the PCI architecture allows and that a single PCI function doesn't consume more irqs than the kernel is configured for. At least the last check doesn't help much and should take the sum of all irqs into account. Since that's already done by irq_alloc_desc we can remove this check. As for the first check we should use the value provided by the firmware which can be less than what the PCI architecture allows. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci.h | 5 +---- arch/s390/pci/pci.c | 3 +-- arch/s390/pci/pci_clp.c | 1 + 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index c030900320e0..ef803c202d42 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -50,10 +50,6 @@ struct zpci_fmb { atomic64_t unmapped_pages; } __packed __aligned(16); -#define ZPCI_MSI_VEC_BITS 11 -#define ZPCI_MSI_VEC_MAX (1 << ZPCI_MSI_VEC_BITS) -#define ZPCI_MSI_VEC_MASK (ZPCI_MSI_VEC_MAX - 1) - enum zpci_state { ZPCI_FN_STATE_RESERVED, ZPCI_FN_STATE_STANDBY, @@ -90,6 +86,7 @@ struct zpci_dev { /* IRQ stuff */ u64 msi_addr; /* MSI address */ + unsigned int max_msi; /* maximum number of MSI's */ struct airq_iv *aibv; /* adapter interrupt bit vector */ unsigned int aisb; /* number of the summary bit */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 2fa7b14b9c08..47a4568e141d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -369,8 +369,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; - msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); - msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); + msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); /* Allocate adapter summary indicator bit */ rc = -EIO; diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 6e22a247de9b..d6e411ed8b1f 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -62,6 +62,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, zdev->tlb_refresh = response->refresh; zdev->dma_mask = response->dasm; zdev->msi_addr = response->msia; + zdev->max_msi = response->noi; zdev->fmb_update = response->mui; switch (response->version) { -- GitLab From 5b9f2081e0844581cc94384eb052007002b2bfa8 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 30 Oct 2014 10:30:45 +0100 Subject: [PATCH 2499/9457] s390/pci: add sparse annotations Fix the following warnings from the sparse code checker: arch/s390/include/asm/pci_io.h:165:49: warning: cast removes address space of expression arch/s390/pci/pci.c:476:44: warning: cast removes address space of expression arch/s390/pci/pci.c:491:36: warning: incorrect type in argument 2 (different address spaces) arch/s390/pci/pci.c:491:36: expected void [noderef] *addr arch/s390/pci/pci.c:491:36: got void * Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci_io.h | 6 ++++-- arch/s390/pci/pci.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index d194d544d694..f664e96f48c7 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h @@ -139,7 +139,8 @@ static inline int zpci_memcpy_fromio(void *dst, int size, rc = 0; while (n > 0) { - size = zpci_get_max_write_size((u64) src, (u64) dst, n, 8); + size = zpci_get_max_write_size((u64 __force) src, + (u64) dst, n, 8); req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); rc = zpci_read_single(req, dst, offset, size); if (rc) @@ -162,7 +163,8 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst, return -EINVAL; while (n > 0) { - size = zpci_get_max_write_size((u64) dst, (u64) src, n, 128); + size = zpci_get_max_write_size((u64 __force) dst, + (u64) src, n, 128); req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); if (size > 8) /* main path */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 47a4568e141d..ed3725e2d16e 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -473,7 +473,8 @@ static void zpci_map_resources(struct zpci_dev *zdev) len = pci_resource_len(pdev, i); if (!len) continue; - pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); + pdev->resource[i].start = + (resource_size_t __force) pci_iomap(pdev, i, 0); pdev->resource[i].end = pdev->resource[i].start + len - 1; } } @@ -488,7 +489,8 @@ static void zpci_unmap_resources(struct zpci_dev *zdev) len = pci_resource_len(pdev, i); if (!len) continue; - pci_iounmap(pdev, (void *) pdev->resource[i].start); + pci_iounmap(pdev, (void __iomem __force *) + pdev->resource[i].start); } } -- GitLab From a697e051160390065393e2926d9d080077239e9e Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 30 Oct 2014 10:55:37 +0100 Subject: [PATCH 2500/9457] s390/mm: use correct unlock function in gmap_ipte_notify The page table lock is acquired with a call to get_locked_pte, replace the plain spin_unlock with the correct unlock function pte_unmap_unlock. Signed-off-by: Martin Schwidefsky --- arch/s390/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 9c8a6dd8a49c..71c7eff2c89f 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -762,7 +762,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len) gaddr += PAGE_SIZE; len -= PAGE_SIZE; } - spin_unlock(ptl); + pte_unmap_unlock(ptep, ptl); } up_read(&gmap->mm->mmap_sem); return rc; -- GitLab From 37d2cd9d84851a2bd4a4bcc0157880ee4d8b5803 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 30 Oct 2014 13:45:43 +0100 Subject: [PATCH 2501/9457] s390/signal: add sparse annotations Fix the following warnings from the sparse code checker: arch/s390/kernel/signal.c:374:38: warning: cast removes address space of expression arch/s390/kernel/signal.c:374:65: warning: incorrect type in initializer (different address spaces) arch/s390/kernel/signal.c:374:65: expected unsigned short [noderef] [usertype] *svc arch/s390/kernel/signal.c:374:65: got void * arch/s390/kernel/compat_signal.c:437:38: warning: cast removes address space of expression arch/s390/kernel/compat_signal.c:437:65: warning: incorrect type in initializer (different address spaces) arch/s390/kernel/compat_signal.c:437:65: expected unsigned short [noderef] [usertype] *svc arch/s390/kernel/compat_signal.c:437:65: got void * Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_signal.c | 2 +- arch/s390/kernel/signal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 009f5eb11125..34d5fa7b01b5 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -434,7 +434,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set, ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE; } else { /* Signal frames without vectors registers are short ! */ - __u16 __user *svc = (void *) frame + frame_size - 2; + __u16 __user *svc = (void __user *) frame + frame_size - 2; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) return -EFAULT; restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE; diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 0c1a0ff0a558..6a2ac257d98f 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -371,7 +371,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE; } else { /* Signal frame without vector registers are short ! */ - __u16 __user *svc = (void *) frame + frame_size - 2; + __u16 __user *svc = (void __user *) frame + frame_size - 2; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) return -EFAULT; restorer = (unsigned long) svc | PSW_ADDR_AMODE; -- GitLab From eaf785d51dc6782da4cc87b5e891c8a9f8fa2c27 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 20 Oct 2014 15:41:39 +0200 Subject: [PATCH 2502/9457] s390/cpum_sf: Remove initialization of PMU event index The git commit c719f56092add9b3d4192f57c64ce7af11105130 "perf: Fix and clean up initialization of pmu::event_idx" removed the PMU event index callback for all architectures but x86, remove the initialization of the event index as well. Signed-off-by: Hendrik Brueckner Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_cpum_sf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 08e761318c17..8e1b77530060 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1383,7 +1383,6 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags) cpuhw->lsctl.ed = 1; /* Set in_use flag and store event */ - event->hw.idx = 0; /* only one sampling event per CPU supported */ cpuhw->event = event; cpuhw->flags |= PMU_F_IN_USE; -- GitLab From 2089ad03b200fca3b2193a2f6f9779c38f62f9d6 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 17 Oct 2014 03:14:53 +0000 Subject: [PATCH 2503/9457] i40e: properly parse MDET registers Fix a few problems with our parsing of the MDET registers: * Queue IDs are longer than 8 bits * Queue IDs are absolute for the device and the base queue must be subtracted out. * VF IDs are longer than 8 bits * Use the MASK define to mask the event value, instead of the SHIFT define. Change-ID: I3dc7237f480c02e1192a2a8ea782f8a02ab2a8b7 Reported-by: Marc Neustadter Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 1b0c437dae21..1a98e2384b3b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6174,12 +6174,13 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) if (reg & I40E_GL_MDET_TX_VALID_MASK) { u8 pf_num = (reg & I40E_GL_MDET_TX_PF_NUM_MASK) >> I40E_GL_MDET_TX_PF_NUM_SHIFT; - u8 vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >> + u16 vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >> I40E_GL_MDET_TX_VF_NUM_SHIFT; u8 event = (reg & I40E_GL_MDET_TX_EVENT_MASK) >> I40E_GL_MDET_TX_EVENT_SHIFT; - u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >> - I40E_GL_MDET_TX_QUEUE_SHIFT; + u16 queue = ((reg & I40E_GL_MDET_TX_QUEUE_MASK) >> + I40E_GL_MDET_TX_QUEUE_SHIFT) - + pf->hw.func_caps.base_queue; if (netif_msg_tx_err(pf)) dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on TX queue %d pf number 0x%02x vf number 0x%02x\n", event, queue, pf_num, vf_num); @@ -6192,8 +6193,9 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) I40E_GL_MDET_RX_FUNCTION_SHIFT; u8 event = (reg & I40E_GL_MDET_RX_EVENT_MASK) >> I40E_GL_MDET_RX_EVENT_SHIFT; - u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >> - I40E_GL_MDET_RX_QUEUE_SHIFT; + u16 queue = ((reg & I40E_GL_MDET_RX_QUEUE_MASK) >> + I40E_GL_MDET_RX_QUEUE_SHIFT) - + pf->hw.func_caps.base_queue; if (netif_msg_rx_err(pf)) dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on RX queue %d of function 0x%02x\n", event, queue, func); -- GitLab From 996bad6cb3510d726d435c6802294ac289418608 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 29 Oct 2014 15:26:25 +0300 Subject: [PATCH 2504/9457] ARC: add power management options Even though ARC cores itself don't have any power management except SLEEP state it's possible to use power management features of selected peripherals. For example USB OTG requires PM_RUNTIME which is only available if kernel/power/Kconfig is sourced by architecture. Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index fe44b2494609..df94ac1f75b6 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -428,3 +428,4 @@ source "arch/arc/Kconfig.debug" source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" +source "kernel/power/Kconfig" -- GitLab From eb58960e9ebf15cde8ca1248e15ecb0c8f3a28bd Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Fri, 24 Oct 2014 21:25:59 +0200 Subject: [PATCH 2505/9457] ASoC: atmel_ssc_dai: Match the CMR divider only in full duplex. The CMR divider register is shared by playback and capture. The SSC driver therefore tries to enforce rules so that the needed register content do not conflict during simultaneous playback/capture. However, the implementation also prevents changing the register content in half-duplex scenarios, which is needed when using the OSS API. Thus, only lock the divider if there is a stream in the other direction. Fixes the below program to not fail with the atmel ssc dai in master mode. int main(void) { int fd; int format; int channels; int speed; if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) { perror("open"); return 1; } format = AFMT_S16_LE; if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) { perror("SNDCTL_DSP_SETFMT"); return 1; } channels = 2; if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { perror("SNDCTL_DSP_CHANNELS"); return 1; } speed = 22025; if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) { perror("SNDCTL_DSP_SPEED"); return 1; } return 0; } Signed-off-by: Peter Rosin Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index f403f399808a..b1cc2a4a7fc0 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -310,7 +310,10 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, * transmit and receive, so if a value has already * been set, it must match this value. */ - if (ssc_p->cmr_div == 0) + if (ssc_p->dir_mask != + (SSC_DIR_MASK_PLAYBACK | SSC_DIR_MASK_CAPTURE)) + ssc_p->cmr_div = div; + else if (ssc_p->cmr_div == 0) ssc_p->cmr_div = div; else if (div != ssc_p->cmr_div) -- GitLab From 509cd82619877b35dd5f5b4e6fde679d0c473e78 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 10 Oct 2014 18:10:49 -0300 Subject: [PATCH 2506/9457] [media] media: earthsoft: logging neatening Use dev_err instead of pt1_printk o reduce object code size o remove now unused pt1_printk macro Neaten dev_ uses in pt3 o add missing newlines o align arguments o remove unnecessary OOM messages as there's a generic one o typo fixes in messages Signed-off-by: Joe Perches Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pt1/pt1.c | 13 +++---- drivers/media/pci/pt3/pt3.c | 75 ++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index db887b0c37b1..acc35b42e53c 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -109,9 +109,6 @@ struct pt1_adapter { int sleep; }; -#define pt1_printk(level, pt1, format, arg...) \ - dev_printk(level, &(pt1)->pdev->dev, format, ##arg) - static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data) { writel(data, pt1->regs + reg * 4); @@ -154,7 +151,7 @@ static int pt1_sync(struct pt1 *pt1) return 0; pt1_write_reg(pt1, 0, 0x00000008); } - pt1_printk(KERN_ERR, pt1, "could not sync\n"); + dev_err(&pt1->pdev->dev, "could not sync\n"); return -EIO; } @@ -179,7 +176,7 @@ static int pt1_unlock(struct pt1 *pt1) return 0; schedule_timeout_uninterruptible((HZ + 999) / 1000); } - pt1_printk(KERN_ERR, pt1, "could not unlock\n"); + dev_err(&pt1->pdev->dev, "could not unlock\n"); return -EIO; } @@ -193,7 +190,7 @@ static int pt1_reset_pci(struct pt1 *pt1) return 0; schedule_timeout_uninterruptible((HZ + 999) / 1000); } - pt1_printk(KERN_ERR, pt1, "could not reset PCI\n"); + dev_err(&pt1->pdev->dev, "could not reset PCI\n"); return -EIO; } @@ -207,7 +204,7 @@ static int pt1_reset_ram(struct pt1 *pt1) return 0; schedule_timeout_uninterruptible((HZ + 999) / 1000); } - pt1_printk(KERN_ERR, pt1, "could not reset RAM\n"); + dev_err(&pt1->pdev->dev, "could not reset RAM\n"); return -EIO; } @@ -224,7 +221,7 @@ static int pt1_do_enable_ram(struct pt1 *pt1) } schedule_timeout_uninterruptible((HZ + 999) / 1000); } - pt1_printk(KERN_ERR, pt1, "could not enable RAM\n"); + dev_err(&pt1->pdev->dev, "could not enable RAM\n"); return -EIO; } diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c index 1fdeac11501a..7a37e8fe2ee2 100644 --- a/drivers/media/pci/pt3/pt3.c +++ b/drivers/media/pci/pt3/pt3.c @@ -255,7 +255,7 @@ static int pt3_fe_init(struct pt3_board *pt3) pt3_i2c_reset(pt3); ret = pt3_init_all_demods(pt3); if (ret < 0) { - dev_warn(&pt3->pdev->dev, "Failed to init demod chips."); + dev_warn(&pt3->pdev->dev, "Failed to init demod chips\n"); return ret; } @@ -271,7 +271,7 @@ static int pt3_fe_init(struct pt3_board *pt3) init0_ter, ARRAY_SIZE(init0_ter)); if (ret < 0) { dev_warn(&pt3->pdev->dev, - "demod[%d] faild in init sequence0.", i); + "demod[%d] failed in init sequence0\n", i); return ret; } ret = fe->ops.init(fe); @@ -282,7 +282,7 @@ static int pt3_fe_init(struct pt3_board *pt3) usleep_range(2000, 4000); ret = pt3_set_tuner_power(pt3, true, false); if (ret < 0) { - dev_warn(&pt3->pdev->dev, "Failed to control tuner module."); + dev_warn(&pt3->pdev->dev, "Failed to control tuner module\n"); return ret; } @@ -297,7 +297,7 @@ static int pt3_fe_init(struct pt3_board *pt3) cfg_ter, ARRAY_SIZE(cfg_ter)); if (ret < 0) { dev_warn(&pt3->pdev->dev, - "demod[%d] faild in init sequence1.", i); + "demod[%d] failed in init sequence1\n", i); return ret; } } @@ -311,19 +311,19 @@ static int pt3_fe_init(struct pt3_board *pt3) ret = fe->ops.tuner_ops.init(fe); if (ret < 0) { dev_warn(&pt3->pdev->dev, - "Failed to init SAT-tuner[%d].", i); + "Failed to init SAT-tuner[%d]\n", i); return ret; } } ret = pt3_init_all_mxl301rf(pt3); if (ret < 0) { - dev_warn(&pt3->pdev->dev, "Failed to init TERR-tuners."); + dev_warn(&pt3->pdev->dev, "Failed to init TERR-tuners\n"); return ret; } ret = pt3_set_tuner_power(pt3, true, true); if (ret < 0) { - dev_warn(&pt3->pdev->dev, "Failed to control tuner module."); + dev_warn(&pt3->pdev->dev, "Failed to control tuner module\n"); return ret; } @@ -344,7 +344,7 @@ static int pt3_fe_init(struct pt3_board *pt3) } if (ret < 0) { dev_warn(&pt3->pdev->dev, - "Failed in initial tuning of tuner[%d].", i); + "Failed in initial tuning of tuner[%d]\n", i); return ret; } } @@ -366,7 +366,7 @@ static int pt3_fe_init(struct pt3_board *pt3) fe->ops.set_lna = &pt3_set_lna; } if (i < PT3_NUM_FE) { - dev_warn(&pt3->pdev->dev, "FE[%d] failed to standby.", i); + dev_warn(&pt3->pdev->dev, "FE[%d] failed to standby\n", i); return ret; } return 0; @@ -453,8 +453,8 @@ static int pt3_fetch_thread(void *data) pt3_init_dmabuf(adap); adap->num_discard = PT3_INITIAL_BUF_DROPS; - dev_dbg(adap->dvb_adap.device, - "PT3: [%s] started.\n", adap->thread->comm); + dev_dbg(adap->dvb_adap.device, "PT3: [%s] started\n", + adap->thread->comm); set_freezable(); while (!kthread_freezable_should_stop(&was_frozen)) { if (was_frozen) @@ -468,8 +468,8 @@ static int pt3_fetch_thread(void *data) PT3_FETCH_DELAY_DELTA * NSEC_PER_MSEC, HRTIMER_MODE_REL); } - dev_dbg(adap->dvb_adap.device, - "PT3: [%s] exited.\n", adap->thread->comm); + dev_dbg(adap->dvb_adap.device, "PT3: [%s] exited\n", + adap->thread->comm); adap->thread = NULL; return 0; } @@ -485,8 +485,8 @@ static int pt3_start_streaming(struct pt3_adapter *adap) int ret = PTR_ERR(thread); dev_warn(adap->dvb_adap.device, - "PT3 (adap:%d, dmx:%d): failed to start kthread.\n", - adap->dvb_adap.num, adap->dmxdev.dvbdev->id); + "PT3 (adap:%d, dmx:%d): failed to start kthread\n", + adap->dvb_adap.num, adap->dmxdev.dvbdev->id); return ret; } adap->thread = thread; @@ -501,8 +501,8 @@ static int pt3_stop_streaming(struct pt3_adapter *adap) ret = pt3_stop_dma(adap); if (ret) dev_warn(adap->dvb_adap.device, - "PT3: failed to stop streaming of adap:%d/FE:%d\n", - adap->dvb_adap.num, adap->fe->id); + "PT3: failed to stop streaming of adap:%d/FE:%d\n", + adap->dvb_adap.num, adap->fe->id); /* kill the fetching thread */ ret = kthread_stop(adap->thread); @@ -522,8 +522,8 @@ static int pt3_start_feed(struct dvb_demux_feed *feed) return 0; if (adap->num_feeds != 1) { dev_warn(adap->dvb_adap.device, - "%s: unmatched start/stop_feed in adap:%i/dmx:%i.\n", - __func__, adap->dvb_adap.num, adap->dmxdev.dvbdev->id); + "%s: unmatched start/stop_feed in adap:%i/dmx:%i\n", + __func__, adap->dvb_adap.num, adap->dmxdev.dvbdev->id); adap->num_feeds = 1; } @@ -553,10 +553,9 @@ static int pt3_alloc_adapter(struct pt3_board *pt3, int index) struct dvb_adapter *da; adap = kzalloc(sizeof(*adap), GFP_KERNEL); - if (!adap) { - dev_err(&pt3->pdev->dev, "failed to alloc mem for adapter.\n"); + if (!adap) return -ENOMEM; - } + pt3->adaps[index] = adap; adap->adap_idx = index; @@ -565,7 +564,7 @@ static int pt3_alloc_adapter(struct pt3_board *pt3, int index) THIS_MODULE, &pt3->pdev->dev, adapter_nr); if (ret < 0) { dev_err(&pt3->pdev->dev, - "failed to register adapter dev.\n"); + "failed to register adapter dev\n"); goto err_mem; } da = &adap->dvb_adap; @@ -581,7 +580,7 @@ static int pt3_alloc_adapter(struct pt3_board *pt3, int index) adap->demux.stop_feed = pt3_stop_feed; ret = dvb_dmx_init(&adap->demux); if (ret < 0) { - dev_err(&pt3->pdev->dev, "failed to init dmx dev.\n"); + dev_err(&pt3->pdev->dev, "failed to init dmx dev\n"); goto err_adap; } @@ -589,13 +588,13 @@ static int pt3_alloc_adapter(struct pt3_board *pt3, int index) adap->dmxdev.demux = &adap->demux.dmx; ret = dvb_dmxdev_init(&adap->dmxdev, da); if (ret < 0) { - dev_err(&pt3->pdev->dev, "failed to init dmxdev.\n"); + dev_err(&pt3->pdev->dev, "failed to init dmxdev\n"); goto err_demux; } ret = pt3_alloc_dmabuf(adap); if (ret) { - dev_err(&pt3->pdev->dev, "failed to alloc DMA buffers.\n"); + dev_err(&pt3->pdev->dev, "failed to alloc DMA buffers\n"); goto err_dmabuf; } @@ -695,7 +694,7 @@ static int pt3_resume(struct device *dev) dvb_frontend_resume(adap->fe); ret = pt3_alloc_dmabuf(adap); if (ret) { - dev_err(&pt3->pdev->dev, "failed to alloc DMA bufs.\n"); + dev_err(&pt3->pdev->dev, "failed to alloc DMA bufs\n"); continue; } if (adap->num_feeds > 0) @@ -753,15 +752,14 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret == 0) dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); else { - dev_err(&pdev->dev, "Failed to set DMA mask.\n"); + dev_err(&pdev->dev, "Failed to set DMA mask\n"); goto err_release_regions; } - dev_info(&pdev->dev, "Use 32bit DMA.\n"); + dev_info(&pdev->dev, "Use 32bit DMA\n"); } pt3 = kzalloc(sizeof(*pt3), GFP_KERNEL); if (!pt3) { - dev_err(&pdev->dev, "Failed to alloc mem for this dev.\n"); ret = -ENOMEM; goto err_release_regions; } @@ -771,15 +769,15 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pt3->regs[0] = pci_ioremap_bar(pdev, 0); pt3->regs[1] = pci_ioremap_bar(pdev, 2); if (pt3->regs[0] == NULL || pt3->regs[1] == NULL) { - dev_err(&pdev->dev, "Failed to ioremap.\n"); + dev_err(&pdev->dev, "Failed to ioremap\n"); ret = -ENOMEM; goto err_kfree; } ver = ioread32(pt3->regs[0] + REG_VERSION); if ((ver >> 16) != 0x0301) { - dev_warn(&pdev->dev, "PT%d, I/F-ver.:%d not supported", - ver >> 24, (ver & 0x00ff0000) >> 16); + dev_warn(&pdev->dev, "PT%d, I/F-ver.:%d not supported\n", + ver >> 24, (ver & 0x00ff0000) >> 16); ret = -ENODEV; goto err_iounmap; } @@ -788,7 +786,6 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pt3->i2c_buf = kmalloc(sizeof(*pt3->i2c_buf), GFP_KERNEL); if (pt3->i2c_buf == NULL) { - dev_err(&pdev->dev, "Failed to alloc mem for i2c.\n"); ret = -ENOMEM; goto err_iounmap; } @@ -801,7 +798,7 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) i2c_set_adapdata(i2c, pt3); ret = i2c_add_adapter(i2c); if (ret < 0) { - dev_err(&pdev->dev, "Failed to add i2c adapter.\n"); + dev_err(&pdev->dev, "Failed to add i2c adapter\n"); goto err_i2cbuf; } @@ -815,20 +812,20 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } if (i < PT3_NUM_FE) { - dev_err(&pdev->dev, "Failed to create FE%d.\n", i); + dev_err(&pdev->dev, "Failed to create FE%d\n", i); goto err_cleanup_adapters; } ret = pt3_fe_init(pt3); if (ret < 0) { - dev_err(&pdev->dev, "Failed to init frontends.\n"); + dev_err(&pdev->dev, "Failed to init frontends\n"); i = PT3_NUM_FE - 1; goto err_cleanup_adapters; } dev_info(&pdev->dev, - "successfully init'ed PT%d (fw:0x%02x, I/F:0x%02x).\n", - ver >> 24, (ver >> 8) & 0xff, (ver >> 16) & 0xff); + "successfully init'ed PT%d (fw:0x%02x, I/F:0x%02x)\n", + ver >> 24, (ver >> 8) & 0xff, (ver >> 16) & 0xff); return 0; err_cleanup_adapters: -- GitLab From e369086968157415aeb11af3b57cd998c6721603 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 3 Nov 2014 16:04:12 +0530 Subject: [PATCH 2507/9457] ALSA: echoaudio: add reference of struct echoaudio added reference of struct echoaudio to free_firmware function. this structure will be later used to get a reference of the card when converting snd_printk to dev_* in the next patch of the series. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/echoaudio/echoaudio.c | 3 ++- sound/pci/echoaudio/echoaudio.h | 3 ++- sound/pci/echoaudio/echoaudio_dsp.c | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index d82321ff549b..db1b247d8587 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -69,7 +69,8 @@ static int get_firmware(const struct firmware **fw_entry, -static void free_firmware(const struct firmware *fw_entry) +static void free_firmware(const struct firmware *fw_entry, + struct echoaudio *chip) { #ifdef CONFIG_PM_SLEEP DE_ACT(("firmware not released (kept in cache)\n")); diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index b86b88da81cd..a4f112aa78e2 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -468,7 +468,8 @@ static int wait_handshake(struct echoaudio *chip); static int send_vector(struct echoaudio *chip, u32 command); static int get_firmware(const struct firmware **fw_entry, struct echoaudio *chip, const short fw_index); -static void free_firmware(const struct firmware *fw_entry); +static void free_firmware(const struct firmware *fw_entry, + struct echoaudio *chip); #ifdef ECHOCARD_HAS_MIDI static int enable_midi_input(struct echoaudio *chip, char enable); diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 5a6a217b82e0..977b2bd2e72f 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -206,12 +206,12 @@ static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) } DE_INIT(("ASIC loaded\n")); - free_firmware(fw); + free_firmware(fw, chip); return 0; la_error: DE_INIT(("failed on write_dsp\n")); - free_firmware(fw); + free_firmware(fw, chip); return -EIO; } @@ -317,11 +317,11 @@ static int install_resident_loader(struct echoaudio *chip) } DE_INIT(("Resident loader successfully installed\n")); - free_firmware(fw); + free_firmware(fw, chip); return 0; irl_error: - free_firmware(fw); + free_firmware(fw, chip); return -EIO; } @@ -491,7 +491,7 @@ static int load_firmware(struct echoaudio *chip) if (err < 0) return err; err = load_dsp(chip, (u16 *)fw->data); - free_firmware(fw); + free_firmware(fw, chip); if (err < 0) return err; -- GitLab From 49141aa249aebce263c5d2daa79d81ef548ab3eb Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 12 Oct 2014 07:03:08 -0300 Subject: [PATCH 2508/9457] [media] dvbsky: don't print MAC address from read_mac_address The dvb-usb-v2 already prints out the MAC address, no need to print it out also here. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvbsky.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 34688c89df11..502b52ca89d1 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -265,8 +265,6 @@ static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6]) if (i2c_transfer(&d->i2c_adap, msg, 2) == 2) memcpy(mac, ibuf, 6); - dev_info(&d->udev->dev, "dvbsky_usb MAC address=%pM\n", mac); - return 0; } -- GitLab From 40bba097ef234f7187a36335d5e5c500861182ef Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 12 Oct 2014 07:03:10 -0300 Subject: [PATCH 2509/9457] [media] dvbsky: clean logging dev_err includes the function name in the log printout, so there is no need to include it manually. While here, fix a small grammatical error in the i2c error message. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvbsky.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 502b52ca89d1..f390a046d39d 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -96,8 +96,7 @@ static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value) obuf[2] = value; ret = dvbsky_usb_generic_rw(d, obuf, 3, ibuf, 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); return ret; } @@ -114,7 +113,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], if (num > 2) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c messages[%d] than 2.", num); + "too many i2c messages[%d], max 2.", num); ret = -EOPNOTSUPP; goto i2c_error; } @@ -122,7 +121,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], if (num == 1) { if (msg[0].len > 60) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c bytes[%d] than 60.", + "too many i2c bytes[%d], max 60.", msg[0].len); ret = -EOPNOTSUPP; goto i2c_error; @@ -136,8 +135,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, 4, ibuf, msg[0].len + 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[0].buf, &ibuf[1], msg[0].len); } else { @@ -149,13 +147,12 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 3, ibuf, 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); } } else { if ((msg[0].len > 60) || (msg[1].len > 60)) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c bytes[w-%d][r-%d] than 60.", + "too many i2c bytes[w-%d][r-%d], max 60.", msg[0].len, msg[1].len); ret = -EOPNOTSUPP; goto i2c_error; @@ -169,8 +166,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 4, ibuf, msg[1].len + 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[1].buf, &ibuf[1], msg[1].len); @@ -201,8 +197,7 @@ static int dvbsky_rc_query(struct dvb_usb_device *d) obuf[0] = 0x10; ret = dvbsky_usb_generic_rw(d, obuf, 1, ibuf, 2); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (ret == 0) code = (ibuf[0] << 8) | ibuf[1]; if (code != 0xffff) { -- GitLab From 69e7b6503ee415a95cdc71b7811722e53a370712 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 12 Oct 2014 08:31:38 -0300 Subject: [PATCH 2510/9457] [media] dvbsky: add option to disable IR receiver Add an option to disable remote controller for DVBSky devices by specifying the disable_rc option at modprobe. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvbsky.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index f390a046d39d..2499635df52f 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -25,6 +25,10 @@ #define DVBSKY_MSG_DELAY 0/*2000*/ #define DVBSKY_BUF_LEN 64 +static int dvb_usb_dvbsky_disable_rc; +module_param_named(disable_rc, dvb_usb_dvbsky_disable_rc, int, 0644); +MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver."); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct dvbsky_state { @@ -213,6 +217,11 @@ static int dvbsky_rc_query(struct dvb_usb_device *d) static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { + if (dvb_usb_dvbsky_disable_rc) { + rc->map_name = NULL; + return 0; + } + rc->allowed_protos = RC_BIT_RC5; rc->query = dvbsky_rc_query; rc->interval = 300; -- GitLab From b5b4a41b392960010fccf1f9ccf8334d612bd450 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 3 Nov 2014 16:04:13 +0530 Subject: [PATCH 2511/9457] ALSA: echoaudio: remove all snd_printk removed all references of snd_printk with the standard dev_* macro. [a few places degraded to dev_dbg(), too -- tiwai] Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/echoaudio/darla20_dsp.c | 7 +- sound/pci/echoaudio/darla24_dsp.c | 15 ++- sound/pci/echoaudio/echo3g_dsp.c | 7 +- sound/pci/echoaudio/echoaudio.c | 137 ++++++++++++----------- sound/pci/echoaudio/echoaudio.h | 28 ----- sound/pci/echoaudio/echoaudio_3g.c | 32 +++--- sound/pci/echoaudio/echoaudio_dsp.c | 111 ++++++++++-------- sound/pci/echoaudio/echoaudio_gml.c | 11 +- sound/pci/echoaudio/gina20_dsp.c | 15 +-- sound/pci/echoaudio/gina24_dsp.c | 39 ++++--- sound/pci/echoaudio/indigo_dsp.c | 13 ++- sound/pci/echoaudio/indigo_express_dsp.c | 6 +- sound/pci/echoaudio/indigodj_dsp.c | 13 ++- sound/pci/echoaudio/indigodjx_dsp.c | 7 +- sound/pci/echoaudio/indigoio_dsp.c | 10 +- sound/pci/echoaudio/indigoiox_dsp.c | 7 +- sound/pci/echoaudio/layla20_dsp.c | 37 +++--- sound/pci/echoaudio/layla24_dsp.c | 34 +++--- sound/pci/echoaudio/mia_dsp.c | 17 +-- sound/pci/echoaudio/midi.c | 29 ++--- sound/pci/echoaudio/mona_dsp.c | 35 +++--- 21 files changed, 327 insertions(+), 283 deletions(-) diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c index 20c7cbc89bb3..c94e92e31ae6 100644 --- a/sound/pci/echoaudio/darla20_dsp.c +++ b/sound/pci/echoaudio/darla20_dsp.c @@ -33,12 +33,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Darla20\n")); + dev_dbg(chip->card->dev, "init_hw() - Darla20\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw: could not initialize DSP comm page\n"); return err; } @@ -57,7 +58,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw: done\n"); return err; } diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c index 6da6663e9176..b1272f88d59d 100644 --- a/sound/pci/echoaudio/darla24_dsp.c +++ b/sound/pci/echoaudio/darla24_dsp.c @@ -33,12 +33,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Darla24\n")); + dev_dbg(chip->card->dev, "init_hw() - Darla24\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw: could not initialize DSP comm page\n"); return err; } @@ -56,7 +57,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw: done\n"); return err; } @@ -128,15 +129,17 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) clock = GD24_8000; break; default: - DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", - rate)); + dev_err(chip->card->dev, + "set_sample_rate: Error, invalid sample rate %d\n", + rate); return -EINVAL; } if (wait_handshake(chip)) return -EIO; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + dev_dbg(chip->card->dev, + "set_sample_rate: %d clock %d\n", rate, clock); chip->sample_rate = rate; /* Override the sample rate if this card is set to Echo sync. */ diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c index 3cdc2ee2d1dd..bc3716895fc8 100644 --- a/sound/pci/echoaudio/echo3g_dsp.c +++ b/sound/pci/echoaudio/echo3g_dsp.c @@ -46,12 +46,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; local_irq_enable(); - DE_INIT(("init_hw() - Echo3G\n")); + dev_dbg(chip->card->dev, "init_hw() - Echo3G\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -98,7 +99,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index db1b247d8587..1ef29e5b53a7 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -48,13 +48,16 @@ static int get_firmware(const struct firmware **fw_entry, #ifdef CONFIG_PM_SLEEP if (chip->fw_cache[fw_index]) { - DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); + dev_dbg(chip->card->dev, + "firmware requested: %s is cached\n", + card_fw[fw_index].data); *fw_entry = chip->fw_cache[fw_index]; return 0; } #endif - DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); + dev_dbg(chip->card->dev, + "firmware requested: %s\n", card_fw[fw_index].data); snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); err = request_firmware(fw_entry, name, pci_device(chip)); if (err < 0) @@ -73,10 +76,10 @@ static void free_firmware(const struct firmware *fw_entry, struct echoaudio *chip) { #ifdef CONFIG_PM_SLEEP - DE_ACT(("firmware not released (kept in cache)\n")); + dev_dbg(chip->card->dev, "firmware not released (kept in cache)\n"); #else release_firmware(fw_entry); - DE_ACT(("firmware released\n")); + dev_dbg(chip->card->dev, "firmware released\n"); #endif } @@ -90,10 +93,10 @@ static void free_firmware_cache(struct echoaudio *chip) for (i = 0; i < 8 ; i++) if (chip->fw_cache[i]) { release_firmware(chip->fw_cache[i]); - DE_ACT(("release_firmware(%d)\n", i)); + dev_dbg(chip->card->dev, "release_firmware(%d)\n", i); } - DE_ACT(("firmware_cache released\n")); + dev_dbg(chip->card->dev, "firmware_cache released\n"); #endif } @@ -287,7 +290,7 @@ static int pcm_open(struct snd_pcm_substream *substream, /* Set up hw capabilities and contraints */ memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); - DE_HWP(("max_channels=%d\n", max_channels)); + dev_dbg(chip->card->dev, "max_channels=%d\n", max_channels); pipe->constr.list = channels_list; pipe->constr.mask = 0; for (i = 0; channels_list[i] <= max_channels; i++); @@ -337,7 +340,7 @@ static int pcm_open(struct snd_pcm_substream *substream, if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &pipe->sgpage)) < 0) { - DE_HWP(("s-g list allocation failed\n")); + dev_err(chip->card->dev, "s-g list allocation failed\n"); return err; } @@ -351,7 +354,7 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream) struct echoaudio *chip = snd_pcm_substream_chip(substream); int err; - DE_ACT(("pcm_analog_in_open\n")); + dev_dbg(chip->card->dev, "pcm_analog_in_open\n"); if ((err = pcm_open(substream, num_analog_busses_in(chip) - substream->number)) < 0) return err; @@ -368,9 +371,9 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream) atomic_inc(&chip->opencount); if (atomic_read(&chip->opencount) > 1 && chip->rate_set) chip->can_set_rate=0; - DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", + dev_dbg(chip->card->dev, "pcm_analog_in_open cs=%d oc=%d r=%d\n", chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate)); + chip->sample_rate); return 0; } @@ -386,7 +389,7 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream) #else max_channels = num_analog_busses_out(chip); #endif - DE_ACT(("pcm_analog_out_open\n")); + dev_dbg(chip->card->dev, "pcm_analog_out_open\n"); if ((err = pcm_open(substream, max_channels - substream->number)) < 0) return err; if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, @@ -404,9 +407,9 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream) atomic_inc(&chip->opencount); if (atomic_read(&chip->opencount) > 1 && chip->rate_set) chip->can_set_rate=0; - DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", + dev_dbg(chip->card->dev, "pcm_analog_out_open cs=%d oc=%d r=%d\n", chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate)); + chip->sample_rate); return 0; } @@ -419,7 +422,7 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream) struct echoaudio *chip = snd_pcm_substream_chip(substream); int err, max_channels; - DE_ACT(("pcm_digital_in_open\n")); + dev_dbg(chip->card->dev, "pcm_digital_in_open\n"); max_channels = num_digital_busses_in(chip) - substream->number; mutex_lock(&chip->mode_mutex); if (chip->digital_mode == DIGITAL_MODE_ADAT) @@ -461,7 +464,7 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream) struct echoaudio *chip = snd_pcm_substream_chip(substream); int err, max_channels; - DE_ACT(("pcm_digital_out_open\n")); + dev_dbg(chip->card->dev, "pcm_digital_out_open\n"); max_channels = num_digital_busses_out(chip) - substream->number; mutex_lock(&chip->mode_mutex); if (chip->digital_mode == DIGITAL_MODE_ADAT) @@ -508,18 +511,18 @@ static int pcm_close(struct snd_pcm_substream *substream) /* Nothing to do here. Audio is already off and pipe will be * freed by its callback */ - DE_ACT(("pcm_close\n")); + dev_dbg(chip->card->dev, "pcm_close\n"); atomic_dec(&chip->opencount); oc = atomic_read(&chip->opencount); - DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate, chip->rate_set)); + dev_dbg(chip->card->dev, "pcm_close oc=%d cs=%d rs=%d\n", oc, + chip->can_set_rate, chip->rate_set); if (oc < 2) chip->can_set_rate = 1; if (oc == 0) chip->rate_set = 0; - DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate,chip->rate_set)); + dev_dbg(chip->card->dev, "pcm_close2 oc=%d cs=%d rs=%d\n", oc, + chip->can_set_rate, chip->rate_set); return 0; } @@ -543,7 +546,7 @@ static int init_engine(struct snd_pcm_substream *substream, */ spin_lock_irq(&chip->lock); if (pipe->index >= 0) { - DE_HWP(("hwp_ie free(%d)\n", pipe->index)); + dev_dbg(chip->card->dev, "hwp_ie free(%d)\n", pipe->index); err = free_pipes(chip, pipe); snd_BUG_ON(err); chip->substream[pipe->index] = NULL; @@ -552,16 +555,17 @@ static int init_engine(struct snd_pcm_substream *substream, err = allocate_pipes(chip, pipe, pipe_index, interleave); if (err < 0) { spin_unlock_irq(&chip->lock); - DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", - pipe_index, err)); + dev_err(chip->card->dev, "allocate_pipes(%d) err=%d\n", + pipe_index, err); return err; } spin_unlock_irq(&chip->lock); - DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); + dev_dbg(chip->card->dev, "allocate_pipes()=%d\n", pipe_index); - DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", + dev_dbg(chip->card->dev, + "pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", params_buffer_bytes(hw_params), params_periods(hw_params), - params_period_bytes(hw_params))); + params_period_bytes(hw_params)); err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) { @@ -616,7 +620,7 @@ static int init_engine(struct snd_pcm_substream *substream, spin_lock_irq(&chip->lock); set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); spin_unlock_irq(&chip->lock); - DE_HWP(("pcm_hw_params ok\n")); + dev_dbg(chip->card->dev, "pcm_hw_params ok\n"); return 0; } @@ -680,14 +684,14 @@ static int pcm_hw_free(struct snd_pcm_substream *substream) spin_lock_irq(&chip->lock); if (pipe->index >= 0) { - DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); + dev_dbg(chip->card->dev, "pcm_hw_free(%d)\n", pipe->index); free_pipes(chip, pipe); chip->substream[pipe->index] = NULL; pipe->index = -1; } spin_unlock_irq(&chip->lock); - DE_HWP(("pcm_hw_freed\n")); + dev_dbg(chip->card->dev, "pcm_hw_freed\n"); snd_pcm_lib_free_pages(substream); return 0; } @@ -701,8 +705,8 @@ static int pcm_prepare(struct snd_pcm_substream *substream) struct audioformat format; int pipe_index = ((struct audiopipe *)runtime->private_data)->index; - DE_HWP(("Prepare rate=%d format=%d channels=%d\n", - runtime->rate, runtime->format, runtime->channels)); + dev_dbg(chip->card->dev, "Prepare rate=%d format=%d channels=%d\n", + runtime->rate, runtime->format, runtime->channels); format.interleave = runtime->channels; format.data_are_bigendian = 0; format.mono_to_stereo = 0; @@ -722,8 +726,9 @@ static int pcm_prepare(struct snd_pcm_substream *substream) format.bits_per_sample = 32; break; default: - DE_HWP(("Prepare error: unsupported format %d\n", - runtime->format)); + dev_err(chip->card->dev, + "Prepare error: unsupported format %d\n", + runtime->format); return -EINVAL; } @@ -758,10 +763,10 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&chip->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: - DE_ACT(("pcm_trigger resume\n")); + dev_dbg(chip->card->dev, "pcm_trigger resume\n"); case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - DE_ACT(("pcm_trigger start\n")); + dev_dbg(chip->card->dev, "pcm_trigger start\n"); for (i = 0; i < DSP_MAXPIPES; i++) { if (channelmask & (1 << i)) { pipe = chip->substream[i]->runtime->private_data; @@ -783,9 +788,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) chip->pipe_cyclic_mask); break; case SNDRV_PCM_TRIGGER_SUSPEND: - DE_ACT(("pcm_trigger suspend\n")); + dev_dbg(chip->card->dev, "pcm_trigger suspend\n"); case SNDRV_PCM_TRIGGER_STOP: - DE_ACT(("pcm_trigger stop\n")); + dev_dbg(chip->card->dev, "pcm_trigger stop\n"); for (i = 0; i < DSP_MAXPIPES; i++) { if (channelmask & (1 << i)) { pipe = chip->substream[i]->runtime->private_data; @@ -795,7 +800,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) err = stop_transport(chip, channelmask); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - DE_ACT(("pcm_trigger pause\n")); + dev_dbg(chip->card->dev, "pcm_trigger pause\n"); for (i = 0; i < DSP_MAXPIPES; i++) { if (channelmask & (1 << i)) { pipe = chip->substream[i]->runtime->private_data; @@ -932,7 +937,7 @@ static int snd_echo_new_pcm(struct echoaudio *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) return err; - DE_INIT(("Analog PCM ok\n")); + dev_dbg(chip->card->dev, "Analog PCM ok\n"); #ifdef ECHOCARD_HAS_DIGITAL_IO /* PCM#1 Digital inputs, no outputs */ @@ -945,7 +950,7 @@ static int snd_echo_new_pcm(struct echoaudio *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) return err; - DE_INIT(("Digital PCM ok\n")); + dev_dbg(chip->card->dev, "Digital PCM ok\n"); #endif /* ECHOCARD_HAS_DIGITAL_IO */ #else /* ECHOCARD_HAS_VMIXER */ @@ -967,7 +972,7 @@ static int snd_echo_new_pcm(struct echoaudio *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) return err; - DE_INIT(("Analog PCM ok\n")); + dev_dbg(chip->card->dev, "Analog PCM ok\n"); #ifdef ECHOCARD_HAS_DIGITAL_IO /* PCM#1 Digital i/o */ @@ -982,7 +987,7 @@ static int snd_echo_new_pcm(struct echoaudio *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) return err; - DE_INIT(("Digital PCM ok\n")); + dev_dbg(chip->card->dev, "Digital PCM ok\n"); #endif /* ECHOCARD_HAS_DIGITAL_IO */ #endif /* ECHOCARD_HAS_VMIXER */ @@ -1475,7 +1480,8 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->clock_src_ctl->id); - DE_ACT(("SDM() =%d\n", changed)); + dev_dbg(chip->card->dev, + "SDM() =%d\n", changed); } if (changed >= 0) changed = 1; /* No errors */ @@ -1602,7 +1608,8 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, } if (changed < 0) - DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); + dev_dbg(chip->card->dev, + "seticlk val%d err 0x%x\n", dclock, changed); return changed; } @@ -1859,7 +1866,7 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) #ifdef ECHOCARD_HAS_MIDI if (st > 0 && chip->midi_in) { snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); - DE_MID(("rawmidi_iread=%d\n", st)); + dev_dbg(chip->card->dev, "rawmidi_iread=%d\n", st); } #endif return IRQ_HANDLED; @@ -1874,10 +1881,10 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) static int snd_echo_free(struct echoaudio *chip) { - DE_INIT(("Stop DSP...\n")); + dev_dbg(chip->card->dev, "Stop DSP...\n"); if (chip->comm_page) rest_in_peace(chip); - DE_INIT(("Stopped.\n")); + dev_dbg(chip->card->dev, "Stopped.\n"); if (chip->irq >= 0) free_irq(chip->irq, chip); @@ -1891,14 +1898,14 @@ static int snd_echo_free(struct echoaudio *chip) if (chip->iores) release_and_free_resource(chip->iores); - DE_INIT(("MMIO freed.\n")); + dev_dbg(chip->card->dev, "MMIO freed.\n"); pci_disable_device(chip->pci); /* release chip data */ free_firmware_cache(chip); kfree(chip); - DE_INIT(("Chip freed.\n")); + dev_dbg(chip->card->dev, "Chip freed.\n"); return 0; } @@ -1908,7 +1915,7 @@ static int snd_echo_dev_free(struct snd_device *device) { struct echoaudio *chip = device->device_data; - DE_INIT(("snd_echo_dev_free()...\n")); + dev_dbg(chip->card->dev, "snd_echo_dev_free()...\n"); return snd_echo_free(chip); } @@ -1941,7 +1948,7 @@ static int snd_echo_create(struct snd_card *card, pci_disable_device(pci); return -ENOMEM; } - DE_INIT(("chip=%p\n", chip)); + dev_dbg(card->dev, "chip=%p\n", chip); spin_lock_init(&chip->lock); chip->card = card; chip->pci = pci; @@ -1978,8 +1985,8 @@ static int snd_echo_create(struct snd_card *card, return -EBUSY; } chip->irq = pci->irq; - DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", - chip->pci, chip->irq, chip->pci->subsystem_device)); + dev_dbg(card->dev, "pci=%p irq=%d subdev=%04x Init hardware...\n", + chip->pci, chip->irq, chip->pci->subsystem_device); /* Create the DSP comm page - this is the area of memory used for most of the communication with the DSP, which accesses it via bus mastering */ @@ -1997,11 +2004,11 @@ static int snd_echo_create(struct snd_card *card, if (err >= 0) err = set_mixer_defaults(chip); if (err < 0) { - DE_INIT(("init_hw err=%d\n", err)); + dev_err(card->dev, "init_hw err=%d\n", err); snd_echo_free(chip); return err; } - DE_INIT(("Card init OK\n")); + dev_dbg(card->dev, "Card init OK\n"); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_echo_free(chip); @@ -2031,7 +2038,7 @@ static int snd_echo_probe(struct pci_dev *pci, return -ENOENT; } - DE_INIT(("Echoaudio driver starting...\n")); + dev_dbg(&pci->dev, "Echoaudio driver starting...\n"); i = 0; err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 0, &card); @@ -2184,7 +2191,7 @@ static int snd_echo_suspend(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct echoaudio *chip = dev_get_drvdata(dev); - DE_INIT(("suspend start\n")); + dev_dbg(dev, "suspend start\n"); snd_pcm_suspend_all(chip->analog_pcm); snd_pcm_suspend_all(chip->digital_pcm); @@ -2211,7 +2218,7 @@ static int snd_echo_suspend(struct device *dev) pci_save_state(pci); pci_disable_device(pci); - DE_INIT(("suspend done\n")); + dev_dbg(dev, "suspend done\n"); return 0; } @@ -2225,7 +2232,7 @@ static int snd_echo_resume(struct device *dev) u32 pipe_alloc_mask; int err; - DE_INIT(("resume start\n")); + dev_dbg(dev, "resume start\n"); pci_restore_state(pci); commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); if (commpage_bak == NULL) @@ -2236,11 +2243,11 @@ static int snd_echo_resume(struct device *dev) err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); if (err < 0) { kfree(commpage_bak); - DE_INIT(("resume init_hw err=%d\n", err)); + dev_err(dev, "resume init_hw err=%d\n", err); snd_echo_free(chip); return err; } - DE_INIT(("resume init OK\n")); + dev_dbg(dev, "resume init OK\n"); /* Temporarily set chip->pipe_alloc_mask=0 otherwise * restore_dsp_settings() fails. @@ -2253,7 +2260,7 @@ static int snd_echo_resume(struct device *dev) kfree(commpage_bak); return err; } - DE_INIT(("resume restore OK\n")); + dev_dbg(dev, "resume restore OK\n"); memcpy(&commpage->audio_format, &commpage_bak->audio_format, sizeof(commpage->audio_format)); @@ -2270,7 +2277,7 @@ static int snd_echo_resume(struct device *dev) return -EBUSY; } chip->irq = pci->irq; - DE_INIT(("resume irq=%d\n", chip->irq)); + dev_dbg(dev, "resume irq=%d\n", chip->irq); #ifdef ECHOCARD_HAS_MIDI if (chip->midi_input_enabled) @@ -2279,7 +2286,7 @@ static int snd_echo_resume(struct device *dev) snd_echo_midi_output_trigger(chip->midi_out, 1); #endif - DE_INIT(("resume done\n")); + dev_dbg(dev, "resume done\n"); return 0; } diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index a4f112aa78e2..32515227a692 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -295,34 +295,6 @@ #define PIPE_STATE_PENDING 3 /* Pipe has pending start */ -/* Debug initialization */ -#ifdef CONFIG_SND_DEBUG -#define DE_INIT(x) snd_printk x -#else -#define DE_INIT(x) -#endif - -/* Debug hw_params callbacks */ -#ifdef CONFIG_SND_DEBUG -#define DE_HWP(x) snd_printk x -#else -#define DE_HWP(x) -#endif - -/* Debug normal activity (open, start, stop...) */ -#ifdef CONFIG_SND_DEBUG -#define DE_ACT(x) snd_printk x -#else -#define DE_ACT(x) -#endif - -/* Debug midi activity */ -#ifdef CONFIG_SND_DEBUG -#define DE_MID(x) snd_printk x -#else -#define DE_MID(x) -#endif - struct audiopipe { volatile u32 *dma_counter; /* Commpage register that contains diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 658db44ef746..50a21690447d 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -51,7 +51,7 @@ static int check_asic_status(struct echoaudio *chip) } box_status = le32_to_cpu(chip->comm_page->ext_box_status); - DE_INIT(("box_status=%x\n", box_status)); + dev_dbg(chip->card->dev, "box_status=%x\n", box_status); if (box_status == E3G_ASIC_NOT_LOADED) return -ENODEV; @@ -76,7 +76,8 @@ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, if (wait_handshake(chip)) return -EIO; - DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); + dev_dbg(chip->card->dev, + "WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq); ctl = cpu_to_le32(ctl); frq = cpu_to_le32(frq); @@ -89,7 +90,7 @@ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); } - DE_ACT(("WriteControlReg: not written, no change\n")); + dev_dbg(chip->card->dev, "WriteControlReg: not written, no change\n"); return 0; } @@ -258,8 +259,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); + dev_warn(chip->card->dev, + "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); /* Save the rate anyhow */ chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; @@ -313,7 +314,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ chip->sample_rate = rate; - DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); + dev_dbg(chip->card->dev, + "SetSampleRate: %d clock %x\n", rate, control_reg); /* Tell the DSP about it - DSP reads both control reg & freq reg */ return write_control_reg(chip, control_reg, frq_reg, 0); @@ -326,7 +328,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) { u32 control_reg, clocks_from_dsp; - DE_ACT(("set_input_clock:\n")); + dev_dbg(chip->card->dev, "set_input_clock:\n"); /* Mask off the clock select bits */ control_reg = le32_to_cpu(chip->comm_page->control_register) & @@ -335,13 +337,13 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) switch (clock) { case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Echo3G clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Echo3G clock to INTERNAL\n"); chip->input_clock = ECHO_CLOCK_INTERNAL; return set_sample_rate(chip, chip->sample_rate); case ECHO_CLOCK_SPDIF: if (chip->digital_mode == DIGITAL_MODE_ADAT) return -EAGAIN; - DE_ACT(("Set Echo3G clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Echo3G clock to SPDIF\n"); control_reg |= E3G_SPDIF_CLOCK; if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) control_reg |= E3G_DOUBLE_SPEED_MODE; @@ -351,12 +353,12 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) case ECHO_CLOCK_ADAT: if (chip->digital_mode != DIGITAL_MODE_ADAT) return -EAGAIN; - DE_ACT(("Set Echo3G clock to ADAT\n")); + dev_dbg(chip->card->dev, "Set Echo3G clock to ADAT\n"); control_reg |= E3G_ADAT_CLOCK; control_reg &= ~E3G_DOUBLE_SPEED_MODE; break; case ECHO_CLOCK_WORD: - DE_ACT(("Set Echo3G clock to WORD\n")); + dev_dbg(chip->card->dev, "Set Echo3G clock to WORD\n"); control_reg |= E3G_WORD_CLOCK; if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) control_reg |= E3G_DOUBLE_SPEED_MODE; @@ -364,7 +366,8 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) control_reg &= ~E3G_DOUBLE_SPEED_MODE; break; default: - DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); + dev_err(chip->card->dev, + "Input clock 0x%x not supported for Echo3G\n", clock); return -EINVAL; } @@ -392,7 +395,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) incompatible_clock = TRUE; break; default: - DE_ACT(("Digital mode not supported: %d\n", mode)); + dev_err(chip->card->dev, + "Digital mode not supported: %d\n", mode); return -EINVAL; } @@ -427,6 +431,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) return err; chip->digital_mode = mode; - DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); + dev_dbg(chip->card->dev, "set_digital_mode(%d)\n", chip->digital_mode); return incompatible_clock; } diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 977b2bd2e72f..ba9d4f16cbb3 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -80,7 +80,7 @@ static int send_vector(struct echoaudio *chip, u32 command) udelay(1); } - DE_ACT((KERN_ERR "timeout on send_vector\n")); + dev_err(chip->card->dev, "timeout on send_vector\n"); return -EBUSY; } @@ -104,7 +104,7 @@ static int write_dsp(struct echoaudio *chip, u32 data) } chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ - DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n")); + dev_dbg(chip->card->dev, "write_dsp: Set bad_board to TRUE\n"); return -EIO; } @@ -127,7 +127,7 @@ static int read_dsp(struct echoaudio *chip, u32 *data) } chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ - DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n")); + dev_err(chip->card->dev, "read_dsp: Set bad_board to TRUE\n"); return -EIO; } @@ -154,8 +154,9 @@ static int read_sn(struct echoaudio *chip) return -EIO; } } - DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", - sn[0], sn[1], sn[2], sn[3], sn[4])); + dev_dbg(chip->card->dev, + "Read serial number %08x %08x %08x %08x %08x\n", + sn[0], sn[1], sn[2], sn[3], sn[4]); return 0; } @@ -205,12 +206,12 @@ static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) goto la_error; } - DE_INIT(("ASIC loaded\n")); + dev_dbg(chip->card->dev, "ASIC loaded\n"); free_firmware(fw, chip); return 0; la_error: - DE_INIT(("failed on write_dsp\n")); + dev_err(chip->card->dev, "failed on write_dsp\n"); free_firmware(fw, chip); return -EIO; } @@ -241,8 +242,9 @@ static int install_resident_loader(struct echoaudio *chip) loader is already installed, host flag 5 will be on. */ status = get_dsp_register(chip, CHI32_STATUS_REG); if (status & CHI32_STATUS_REG_HF5) { - DE_INIT(("Resident loader already installed; status is 0x%x\n", - status)); + dev_dbg(chip->card->dev, + "Resident loader already installed; status is 0x%x\n", + status); return 0; } @@ -283,12 +285,14 @@ static int install_resident_loader(struct echoaudio *chip) /* Write the count to the DSP */ if (write_dsp(chip, words)) { - DE_INIT(("install_resident_loader: Failed to write word count!\n")); + dev_err(chip->card->dev, + "install_resident_loader: Failed to write word count!\n"); goto irl_error; } /* Write the DSP address */ if (write_dsp(chip, address)) { - DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); + dev_err(chip->card->dev, + "install_resident_loader: Failed to write DSP address!\n"); goto irl_error; } /* Write out this block of code to the DSP */ @@ -297,7 +301,8 @@ static int install_resident_loader(struct echoaudio *chip) data = ((u32)code[index] << 16) + code[index + 1]; if (write_dsp(chip, data)) { - DE_INIT(("install_resident_loader: Failed to write DSP code\n")); + dev_err(chip->card->dev, + "install_resident_loader: Failed to write DSP code\n"); goto irl_error; } index += 2; @@ -312,11 +317,11 @@ static int install_resident_loader(struct echoaudio *chip) } if (i == 200) { - DE_INIT(("Resident loader failed to set HF5\n")); + dev_err(chip->card->dev, "Resident loader failed to set HF5\n"); goto irl_error; } - DE_INIT(("Resident loader successfully installed\n")); + dev_dbg(chip->card->dev, "Resident loader successfully installed\n"); free_firmware(fw, chip); return 0; @@ -334,14 +339,14 @@ static int load_dsp(struct echoaudio *chip, u16 *code) int index, words, i; if (chip->dsp_code == code) { - DE_INIT(("DSP is already loaded!\n")); + dev_warn(chip->card->dev, "DSP is already loaded!\n"); return 0; } chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ chip->dsp_code = NULL; /* Current DSP code not loaded */ chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ - DE_INIT(("load_dsp: Set bad_board to TRUE\n")); + dev_dbg(chip->card->dev, "load_dsp: Set bad_board to TRUE\n"); /* If this board requires a resident loader, install it. */ #ifdef DSP_56361 @@ -351,7 +356,8 @@ static int load_dsp(struct echoaudio *chip, u16 *code) /* Send software reset command */ if (send_vector(chip, DSP_VC_RESET) < 0) { - DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); + dev_err(chip->card->dev, + "LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n"); return -EIO; } /* Delay 10us */ @@ -366,7 +372,8 @@ static int load_dsp(struct echoaudio *chip, u16 *code) } if (i == 1000) { - DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); + dev_err(chip->card->dev, + "load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n"); return -EIO; } @@ -403,29 +410,34 @@ static int load_dsp(struct echoaudio *chip, u16 *code) index += 2; if (write_dsp(chip, words) < 0) { - DE_INIT(("load_dsp: failed to write number of DSP words\n")); + dev_err(chip->card->dev, + "load_dsp: failed to write number of DSP words\n"); return -EIO; } if (write_dsp(chip, address) < 0) { - DE_INIT(("load_dsp: failed to write DSP address\n")); + dev_err(chip->card->dev, + "load_dsp: failed to write DSP address\n"); return -EIO; } if (write_dsp(chip, mem_type) < 0) { - DE_INIT(("load_dsp: failed to write DSP memory type\n")); + dev_err(chip->card->dev, + "load_dsp: failed to write DSP memory type\n"); return -EIO; } /* Code */ for (i = 0; i < words; i++, index+=2) { data = ((u32)code[index] << 16) + code[index + 1]; if (write_dsp(chip, data) < 0) { - DE_INIT(("load_dsp: failed to write DSP data\n")); + dev_err(chip->card->dev, + "load_dsp: failed to write DSP data\n"); return -EIO; } } } if (write_dsp(chip, 0) < 0) { /* We're done!!! */ - DE_INIT(("load_dsp: Failed to write final zero\n")); + dev_err(chip->card->dev, + "load_dsp: Failed to write final zero\n"); return -EIO; } udelay(10); @@ -438,12 +450,14 @@ static int load_dsp(struct echoaudio *chip, u16 *code) get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { - DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); + dev_err(chip->card->dev, + "load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n"); return -EIO; } if (write_dsp(chip, chip->comm_page_phys) < 0) { - DE_INIT(("load_dsp: Failed to write comm page address\n")); + dev_err(chip->card->dev, + "load_dsp: Failed to write comm page address\n"); return -EIO; } @@ -452,19 +466,21 @@ static int load_dsp(struct echoaudio *chip, u16 *code) We don't actually use the serial number but we have to get it as part of the DSP init voodoo. */ if (read_sn(chip) < 0) { - DE_INIT(("load_dsp: Failed to read serial number\n")); + dev_err(chip->card->dev, + "load_dsp: Failed to read serial number\n"); return -EIO; } chip->dsp_code = code; /* Show which DSP code loaded */ chip->bad_board = FALSE; /* DSP OK */ - DE_INIT(("load_dsp: OK!\n")); + dev_dbg(chip->card->dev, "load_dsp: OK!\n"); return 0; } udelay(100); } - DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); + dev_err(chip->card->dev, + "load_dsp: DSP load timed out waiting for HF4\n"); return -EIO; } @@ -658,7 +674,7 @@ static void get_audio_meters(struct echoaudio *chip, long *meters) static int restore_dsp_rettings(struct echoaudio *chip) { int i, o, err; - DE_INIT(("restore_dsp_settings\n")); + dev_dbg(chip->card->dev, "restore_dsp_settings\n"); if ((err = check_asic_status(chip)) < 0) return err; @@ -755,7 +771,7 @@ static int restore_dsp_rettings(struct echoaudio *chip) if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) return -EIO; - DE_INIT(("restore_dsp_rettings done\n")); + dev_dbg(chip->card->dev, "restore_dsp_rettings done\n"); return 0; } @@ -835,7 +851,8 @@ static void set_audio_format(struct echoaudio *chip, u16 pipe_index, break; } } - DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); + dev_dbg(chip->card->dev, + "set_audio_format[%d] = %x\n", pipe_index, dsp_format); chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); } @@ -848,7 +865,7 @@ Same thing for pause_ and stop_ -trasport below. */ static int start_transport(struct echoaudio *chip, u32 channel_mask, u32 cyclic_mask) { - DE_ACT(("start_transport %x\n", channel_mask)); + dev_dbg(chip->card->dev, "start_transport %x\n", channel_mask); if (wait_handshake(chip)) return -EIO; @@ -866,7 +883,7 @@ static int start_transport(struct echoaudio *chip, u32 channel_mask, return 0; } - DE_ACT(("start_transport: No pipes to start!\n")); + dev_err(chip->card->dev, "start_transport: No pipes to start!\n"); return -EINVAL; } @@ -874,7 +891,7 @@ static int start_transport(struct echoaudio *chip, u32 channel_mask, static int pause_transport(struct echoaudio *chip, u32 channel_mask) { - DE_ACT(("pause_transport %x\n", channel_mask)); + dev_dbg(chip->card->dev, "pause_transport %x\n", channel_mask); if (wait_handshake(chip)) return -EIO; @@ -893,7 +910,7 @@ static int pause_transport(struct echoaudio *chip, u32 channel_mask) return 0; } - DE_ACT(("pause_transport: No pipes to stop!\n")); + dev_warn(chip->card->dev, "pause_transport: No pipes to stop!\n"); return 0; } @@ -901,7 +918,7 @@ static int pause_transport(struct echoaudio *chip, u32 channel_mask) static int stop_transport(struct echoaudio *chip, u32 channel_mask) { - DE_ACT(("stop_transport %x\n", channel_mask)); + dev_dbg(chip->card->dev, "stop_transport %x\n", channel_mask); if (wait_handshake(chip)) return -EIO; @@ -920,7 +937,7 @@ static int stop_transport(struct echoaudio *chip, u32 channel_mask) return 0; } - DE_ACT(("stop_transport: No pipes to stop!\n")); + dev_warn(chip->card->dev, "stop_transport: No pipes to stop!\n"); return 0; } @@ -937,7 +954,8 @@ static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) stopped and unallocated. */ static int rest_in_peace(struct echoaudio *chip) { - DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); + dev_dbg(chip->card->dev, + "rest_in_peace() open=%x\n", chip->pipe_alloc_mask); /* Stops all active pipes (just to be sure) */ stop_transport(chip, chip->active_mask); @@ -965,7 +983,8 @@ static int init_dsp_comm_page(struct echoaudio *chip) { /* Check if the compiler added extra padding inside the structure */ if (offsetof(struct comm_page, midi_output) != 0xbe0) { - DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); + dev_err(chip->card->dev, + "init_dsp_comm_page() - Invalid struct comm_page structure\n"); return -EPERM; } @@ -999,7 +1018,7 @@ static int init_dsp_comm_page(struct echoaudio *chip) */ static int init_line_levels(struct echoaudio *chip) { - DE_INIT(("init_line_levels\n")); + dev_dbg(chip->card->dev, "init_line_levels\n"); memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); @@ -1051,7 +1070,8 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, u32 channel_mask; char is_cyclic; - DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); + dev_dbg(chip->card->dev, + "allocate_pipes: ch=%d int=%d\n", pipe_index, interleave); if (chip->bad_board) return -EIO; @@ -1061,7 +1081,8 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, for (channel_mask = i = 0; i < interleave; i++) channel_mask |= 1 << (pipe_index + i); if (chip->pipe_alloc_mask & channel_mask) { - DE_ACT(("allocate_pipes: channel already open\n")); + dev_err(chip->card->dev, + "allocate_pipes: channel already open\n"); return -EAGAIN; } @@ -1078,7 +1099,7 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, it moves data. The DMA counter is in units of bytes, not samples. */ pipe->dma_counter = &chip->comm_page->position[pipe_index]; *pipe->dma_counter = 0; - DE_ACT(("allocate_pipes: ok\n")); + dev_dbg(chip->card->dev, "allocate_pipes: ok\n"); return pipe_index; } @@ -1089,7 +1110,7 @@ static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) u32 channel_mask; int i; - DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); + dev_dbg(chip->card->dev, "free_pipes: Pipe %d\n", pipe->index); if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index))) return -EINVAL; if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED)) @@ -1131,7 +1152,7 @@ static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, list[head].size = cpu_to_le32(length); pipe->sglist_head++; } else { - DE_ACT(("SGlist: too many fragments\n")); + dev_err(chip->card->dev, "SGlist: too many fragments\n"); return -ENOMEM; } return 0; diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c index afa273330e8a..23a099425834 100644 --- a/sound/pci/echoaudio/echoaudio_gml.c +++ b/sound/pci/echoaudio/echoaudio_gml.c @@ -46,7 +46,8 @@ static int check_asic_status(struct echoaudio *chip) /* The DSP will return a value to indicate whether or not the ASIC is currently loaded */ if (read_dsp(chip, &asic_status) < 0) { - DE_INIT(("check_asic_status: failed on read_dsp\n")); + dev_err(chip->card->dev, + "check_asic_status: failed on read_dsp\n"); chip->asic_loaded = FALSE; return -EIO; } @@ -68,7 +69,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force) else value &= ~GML_DIGITAL_IN_AUTO_MUTE; - DE_ACT(("write_control_reg: 0x%x\n", value)); + dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value); /* Write the control register */ value = cpu_to_le32(value); @@ -91,7 +92,7 @@ If the auto-mute is disabled, the digital inputs are enabled regardless of what the input clock is set or what is connected. */ static int set_input_auto_mute(struct echoaudio *chip, int automute) { - DE_ACT(("set_input_auto_mute %d\n", automute)); + dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute); chip->digital_in_automute = automute; @@ -194,7 +195,7 @@ static int set_professional_spdif(struct echoaudio *chip, char prof) if ((err = write_control_reg(chip, control_reg, FALSE))) return err; chip->professional_spdif = prof; - DE_ACT(("set_professional_spdif to %s\n", - prof ? "Professional" : "Consumer")); + dev_dbg(chip->card->dev, "set_professional_spdif to %s\n", + prof ? "Professional" : "Consumer"); return 0; } diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c index d1615a0579d1..a959eae95e0d 100644 --- a/sound/pci/echoaudio/gina20_dsp.c +++ b/sound/pci/echoaudio/gina20_dsp.c @@ -37,12 +37,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Gina20\n")); + dev_dbg(chip->card->dev, "init_hw() - Gina20\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -62,7 +63,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -149,7 +150,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) static int set_input_clock(struct echoaudio *chip, u16 clock) { - DE_ACT(("set_input_clock:\n")); + dev_dbg(chip->card->dev, "set_input_clock:\n"); switch (clock) { case ECHO_CLOCK_INTERNAL: @@ -158,7 +159,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) chip->spdif_status = GD_SPDIF_STATUS_UNDEF; set_sample_rate(chip, chip->sample_rate); chip->input_clock = clock; - DE_ACT(("Set Gina clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Gina clock to INTERNAL\n"); break; case ECHO_CLOCK_SPDIF: chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; @@ -166,7 +167,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) clear_handshake(chip); send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); chip->clock_state = GD_CLOCK_SPDIFIN; - DE_ACT(("Set Gina20 clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Gina20 clock to SPDIF\n"); chip->input_clock = clock; break; default: @@ -208,7 +209,7 @@ static int update_flags(struct echoaudio *chip) static int set_professional_spdif(struct echoaudio *chip, char prof) { - DE_ACT(("set_professional_spdif %d\n", prof)); + dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof); if (prof) chip->comm_page->flags |= cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c index 98f7cfa81b5f..c8ea57612d22 100644 --- a/sound/pci/echoaudio/gina24_dsp.c +++ b/sound/pci/echoaudio/gina24_dsp.c @@ -41,12 +41,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Gina24\n")); + dev_dbg(chip->card->dev, "init_hw() - Gina24\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -78,7 +79,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -155,7 +156,7 @@ static int load_asic(struct echoaudio *chip) control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; err = write_control_reg(chip, control_reg, TRUE); } - DE_INIT(("load_asic() done\n")); + dev_dbg(chip->card->dev, "load_asic() done\n"); return err; } @@ -171,8 +172,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); + dev_warn(chip->card->dev, + "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); /* Save the rate anyhow */ chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; @@ -217,7 +218,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) clock = GML_8KHZ; break; default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + dev_err(chip->card->dev, + "set_sample_rate: %d invalid!\n", rate); return -EINVAL; } @@ -225,7 +227,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock); return write_control_reg(chip, control_reg, FALSE); } @@ -236,7 +238,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) { u32 control_reg, clocks_from_dsp; - DE_ACT(("set_input_clock:\n")); + dev_dbg(chip->card->dev, "set_input_clock:\n"); /* Mask off the clock select bits */ control_reg = le32_to_cpu(chip->comm_page->control_register) & @@ -245,13 +247,13 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) switch (clock) { case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Gina24 clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Gina24 clock to INTERNAL\n"); chip->input_clock = ECHO_CLOCK_INTERNAL; return set_sample_rate(chip, chip->sample_rate); case ECHO_CLOCK_SPDIF: if (chip->digital_mode == DIGITAL_MODE_ADAT) return -EAGAIN; - DE_ACT(("Set Gina24 clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Gina24 clock to SPDIF\n"); control_reg |= GML_SPDIF_CLOCK; if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) control_reg |= GML_DOUBLE_SPEED_MODE; @@ -261,21 +263,22 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) case ECHO_CLOCK_ADAT: if (chip->digital_mode != DIGITAL_MODE_ADAT) return -EAGAIN; - DE_ACT(("Set Gina24 clock to ADAT\n")); + dev_dbg(chip->card->dev, "Set Gina24 clock to ADAT\n"); control_reg |= GML_ADAT_CLOCK; control_reg &= ~GML_DOUBLE_SPEED_MODE; break; case ECHO_CLOCK_ESYNC: - DE_ACT(("Set Gina24 clock to ESYNC\n")); + dev_dbg(chip->card->dev, "Set Gina24 clock to ESYNC\n"); control_reg |= GML_ESYNC_CLOCK; control_reg &= ~GML_DOUBLE_SPEED_MODE; break; case ECHO_CLOCK_ESYNC96: - DE_ACT(("Set Gina24 clock to ESYNC96\n")); + dev_dbg(chip->card->dev, "Set Gina24 clock to ESYNC96\n"); control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; break; default: - DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); + dev_err(chip->card->dev, + "Input clock 0x%x not supported for Gina24\n", clock); return -EINVAL; } @@ -304,7 +307,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) incompatible_clock = TRUE; break; default: - DE_ACT(("Digital mode not supported: %d\n", mode)); + dev_err(chip->card->dev, + "Digital mode not supported: %d\n", mode); return -EINVAL; } @@ -344,6 +348,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) return err; chip->digital_mode = mode; - DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); + dev_dbg(chip->card->dev, + "set_digital_mode to %d\n", chip->digital_mode); return incompatible_clock; } diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c index 5e85f14fe5a8..cdeb073fad85 100644 --- a/sound/pci/echoaudio/indigo_dsp.c +++ b/sound/pci/echoaudio/indigo_dsp.c @@ -38,12 +38,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Indigo\n")); + dev_dbg(chip->card->dev, "init_hw() - Indigo\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -60,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -109,7 +110,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) control_reg = MIA_32000; break; default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + dev_err(chip->card->dev, + "set_sample_rate: %d invalid!\n", rate); return -EINVAL; } @@ -147,7 +149,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, index = output * num_pipes_out(chip) + pipe; chip->comm_page->vmixer[index] = gain; - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + dev_dbg(chip->card->dev, + "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); return 0; } diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c index 2e4ab3e34a74..ceda2d7046ac 100644 --- a/sound/pci/echoaudio/indigo_express_dsp.c +++ b/sound/pci/echoaudio/indigo_express_dsp.c @@ -61,7 +61,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) control_reg |= clock; if (control_reg != old_control_reg) { - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + dev_dbg(chip->card->dev, + "set_sample_rate: %d clock %d\n", rate, clock); chip->comm_page->control_register = cpu_to_le32(control_reg); chip->sample_rate = rate; clear_handshake(chip); @@ -89,7 +90,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, index = output * num_pipes_out(chip) + pipe; chip->comm_page->vmixer[index] = gain; - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + dev_dbg(chip->card->dev, + "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); return 0; } diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c index 68f3c8ccc1bf..133915ca6438 100644 --- a/sound/pci/echoaudio/indigodj_dsp.c +++ b/sound/pci/echoaudio/indigodj_dsp.c @@ -38,12 +38,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Indigo DJ\n")); + dev_dbg(chip->card->dev, "init_hw() - Indigo DJ\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -60,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -109,7 +110,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) control_reg = MIA_32000; break; default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + dev_err(chip->card->dev, + "set_sample_rate: %d invalid!\n", rate); return -EINVAL; } @@ -147,7 +149,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, index = output * num_pipes_out(chip) + pipe; chip->comm_page->vmixer[index] = gain; - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + dev_dbg(chip->card->dev, + "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); return 0; } diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c index bb9632c752a9..26cdfcfc5553 100644 --- a/sound/pci/echoaudio/indigodjx_dsp.c +++ b/sound/pci/echoaudio/indigodjx_dsp.c @@ -35,13 +35,14 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Indigo DJx\n")); + dev_dbg(chip->card->dev, "init_hw() - Indigo DJx\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJX)) return -ENODEV; err = init_dsp_comm_page(chip); if (err < 0) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -59,7 +60,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c index beb9a5b69892..5e6df7c25055 100644 --- a/sound/pci/echoaudio/indigoio_dsp.c +++ b/sound/pci/echoaudio/indigoio_dsp.c @@ -38,12 +38,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Indigo IO\n")); + dev_dbg(chip->card->dev, "init_hw() - Indigo IO\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -60,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -118,7 +119,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, index = output * num_pipes_out(chip) + pipe; chip->comm_page->vmixer[index] = gain; - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + dev_dbg(chip->card->dev, + "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); return 0; } diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c index 394c6e76bcbc..90cdd271d9fc 100644 --- a/sound/pci/echoaudio/indigoiox_dsp.c +++ b/sound/pci/echoaudio/indigoiox_dsp.c @@ -35,13 +35,14 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Indigo IOx\n")); + dev_dbg(chip->card->dev, "init_hw() - Indigo IOx\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IOX)) return -ENODEV; err = init_dsp_comm_page(chip); if (err < 0) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -59,7 +60,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c index 53ce94605044..7f0f6ea08ca7 100644 --- a/sound/pci/echoaudio/layla20_dsp.c +++ b/sound/pci/echoaudio/layla20_dsp.c @@ -40,12 +40,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Layla20\n")); + dev_dbg(chip->card->dev, "init_hw() - Layla20\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -64,7 +65,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -121,7 +122,8 @@ static int check_asic_status(struct echoaudio *chip) /* The DSP will return a value to indicate whether or not the ASIC is currently loaded */ if (read_dsp(chip, &asic_status) < 0) { - DE_ACT(("check_asic_status: failed on read_dsp\n")); + dev_err(chip->card->dev, + "check_asic_status: failed on read_dsp\n"); return -EIO; } @@ -164,8 +166,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) /* Only set the clock for internal mode. Do not return failure, simply treat it as a non-event. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); + dev_warn(chip->card->dev, + "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; return 0; @@ -174,7 +176,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) if (wait_handshake(chip)) return -EIO; - DE_ACT(("set_sample_rate(%d)\n", rate)); + dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate); chip->sample_rate = rate; chip->comm_page->sample_rate = cpu_to_le32(rate); clear_handshake(chip); @@ -188,29 +190,30 @@ static int set_input_clock(struct echoaudio *chip, u16 clock_source) u16 clock; u32 rate; - DE_ACT(("set_input_clock:\n")); + dev_dbg(chip->card->dev, "set_input_clock:\n"); rate = 0; switch (clock_source) { case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Layla20 clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Layla20 clock to INTERNAL\n"); rate = chip->sample_rate; clock = LAYLA20_CLOCK_INTERNAL; break; case ECHO_CLOCK_SPDIF: - DE_ACT(("Set Layla20 clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Layla20 clock to SPDIF\n"); clock = LAYLA20_CLOCK_SPDIF; break; case ECHO_CLOCK_WORD: - DE_ACT(("Set Layla20 clock to WORD\n")); + dev_dbg(chip->card->dev, "Set Layla20 clock to WORD\n"); clock = LAYLA20_CLOCK_WORD; break; case ECHO_CLOCK_SUPER: - DE_ACT(("Set Layla20 clock to SUPER\n")); + dev_dbg(chip->card->dev, "Set Layla20 clock to SUPER\n"); clock = LAYLA20_CLOCK_SUPER; break; default: - DE_ACT(("Input clock 0x%x not supported for Layla24\n", - clock_source)); + dev_err(chip->card->dev, + "Input clock 0x%x not supported for Layla24\n", + clock_source); return -EINVAL; } chip->input_clock = clock_source; @@ -229,7 +232,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock_source) static int set_output_clock(struct echoaudio *chip, u16 clock) { - DE_ACT(("set_output_clock: %d\n", clock)); + dev_dbg(chip->card->dev, "set_output_clock: %d\n", clock); switch (clock) { case ECHO_CLOCK_SUPER: clock = LAYLA20_OUTPUT_CLOCK_SUPER; @@ -238,7 +241,7 @@ static int set_output_clock(struct echoaudio *chip, u16 clock) clock = LAYLA20_OUTPUT_CLOCK_WORD; break; default: - DE_ACT(("set_output_clock wrong clock\n")); + dev_err(chip->card->dev, "set_output_clock wrong clock\n"); return -EINVAL; } @@ -283,7 +286,7 @@ static int update_flags(struct echoaudio *chip) static int set_professional_spdif(struct echoaudio *chip, char prof) { - DE_ACT(("set_professional_spdif %d\n", prof)); + dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof); if (prof) chip->comm_page->flags |= cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c index 8c041647f285..eb8f218f79fe 100644 --- a/sound/pci/echoaudio/layla24_dsp.c +++ b/sound/pci/echoaudio/layla24_dsp.c @@ -40,12 +40,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Layla24\n")); + dev_dbg(chip->card->dev, "init_hw() - Layla24\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -69,7 +70,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) if ((err = init_line_levels(chip)) < 0) return err; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -117,7 +118,7 @@ static int load_asic(struct echoaudio *chip) if (chip->asic_loaded) return 1; - DE_INIT(("load_asic\n")); + dev_dbg(chip->card->dev, "load_asic\n"); /* Give the DSP a few milliseconds to settle down */ mdelay(10); @@ -151,7 +152,7 @@ static int load_asic(struct echoaudio *chip) err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, TRUE); - DE_INIT(("load_asic() done\n")); + dev_dbg(chip->card->dev, "load_asic() done\n"); return err; } @@ -167,8 +168,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); + dev_warn(chip->card->dev, + "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); /* Save the rate anyhow */ chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; @@ -241,7 +242,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); + dev_dbg(chip->card->dev, + "set_sample_rate: %d clock %d\n", rate, control_reg); return write_control_reg(chip, control_reg, FALSE); } @@ -260,7 +262,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) /* Pick the new clock */ switch (clock) { case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Layla24 clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Layla24 clock to INTERNAL\n"); chip->input_clock = ECHO_CLOCK_INTERNAL; return set_sample_rate(chip, chip->sample_rate); case ECHO_CLOCK_SPDIF: @@ -269,7 +271,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) control_reg |= GML_SPDIF_CLOCK; /* Layla24 doesn't support 96KHz S/PDIF */ control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Layla24 clock to SPDIF\n"); break; case ECHO_CLOCK_WORD: control_reg |= GML_WORD_CLOCK; @@ -277,17 +279,18 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) control_reg |= GML_DOUBLE_SPEED_MODE; else control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to WORD\n")); + dev_dbg(chip->card->dev, "Set Layla24 clock to WORD\n"); break; case ECHO_CLOCK_ADAT: if (chip->digital_mode != DIGITAL_MODE_ADAT) return -EAGAIN; control_reg |= GML_ADAT_CLOCK; control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to ADAT\n")); + dev_dbg(chip->card->dev, "Set Layla24 clock to ADAT\n"); break; default: - DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); + dev_err(chip->card->dev, + "Input clock 0x%x not supported for Layla24\n", clock); return -EINVAL; } @@ -353,7 +356,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) asic = FW_LAYLA24_2A_ASIC; break; default: - DE_ACT(("Digital mode not supported: %d\n", mode)); + dev_err(chip->card->dev, + "Digital mode not supported: %d\n", mode); return -EINVAL; } @@ -393,6 +397,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) return err; chip->digital_mode = mode; - DE_ACT(("set_digital_mode to %d\n", mode)); + dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode); return incompatible_clock; } diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c index 6ebfa6e7ab9e..ed2f21dcd1c9 100644 --- a/sound/pci/echoaudio/mia_dsp.c +++ b/sound/pci/echoaudio/mia_dsp.c @@ -41,12 +41,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Mia\n")); + dev_dbg(chip->card->dev, "init_hw() - Mia\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -66,7 +67,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -126,7 +127,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) control_reg = MIA_32000; break; default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + dev_err(chip->card->dev, + "set_sample_rate: %d invalid!\n", rate); return -EINVAL; } @@ -153,7 +155,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) static int set_input_clock(struct echoaudio *chip, u16 clock) { - DE_ACT(("set_input_clock(%d)\n", clock)); + dev_dbg(chip->card->dev, "set_input_clock(%d)\n", clock); if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && clock != ECHO_CLOCK_SPDIF)) return -EINVAL; @@ -181,7 +183,8 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, index = output * num_pipes_out(chip) + pipe; chip->comm_page->vmixer[index] = gain; - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); + dev_dbg(chip->card->dev, + "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain); return 0; } @@ -211,7 +214,7 @@ static int update_flags(struct echoaudio *chip) static int set_professional_spdif(struct echoaudio *chip, char prof) { - DE_ACT(("set_professional_spdif %d\n", prof)); + dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof); if (prof) chip->comm_page->flags |= cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c index 7f4dfae0323a..8d43c5a4976b 100644 --- a/sound/pci/echoaudio/midi.c +++ b/sound/pci/echoaudio/midi.c @@ -36,7 +36,7 @@ /* Start and stop Midi input */ static int enable_midi_input(struct echoaudio *chip, char enable) { - DE_MID(("enable_midi_input(%d)\n", enable)); + dev_dbg(chip->card->dev, "enable_midi_input(%d)\n", enable); if (wait_handshake(chip)) return -EIO; @@ -74,7 +74,7 @@ static int write_midi(struct echoaudio *chip, u8 *data, int bytes) chip->comm_page->midi_out_free_count = 0; clear_handshake(chip); send_vector(chip, DSP_VC_MIDI_WRITE); - DE_MID(("write_midi: %d\n", bytes)); + dev_dbg(chip->card->dev, "write_midi: %d\n", bytes); return bytes; } @@ -157,7 +157,7 @@ static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) struct echoaudio *chip = substream->rmidi->private_data; chip->midi_in = substream; - DE_MID(("rawmidi_iopen\n")); + dev_dbg(chip->card->dev, "rawmidi_iopen\n"); return 0; } @@ -183,7 +183,7 @@ static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) struct echoaudio *chip = substream->rmidi->private_data; chip->midi_in = NULL; - DE_MID(("rawmidi_iclose\n")); + dev_dbg(chip->card->dev, "rawmidi_iclose\n"); return 0; } @@ -196,7 +196,7 @@ static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) chip->tinuse = 0; chip->midi_full = 0; chip->midi_out = substream; - DE_MID(("rawmidi_oopen\n")); + dev_dbg(chip->card->dev, "rawmidi_open\n"); return 0; } @@ -209,7 +209,7 @@ static void snd_echo_midi_output_write(unsigned long data) int bytes, sent, time; unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; - DE_MID(("snd_echo_midi_output_write\n")); + dev_dbg(chip->card->dev, "snd_echo_midi_output_write\n"); /* No interrupts are involved: we have to check at regular intervals if the card's output buffer has room for new data. */ sent = bytes = 0; @@ -218,7 +218,7 @@ static void snd_echo_midi_output_write(unsigned long data) if (!snd_rawmidi_transmit_empty(chip->midi_out)) { bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, MIDI_OUT_BUFFER_SIZE - 1); - DE_MID(("Try to send %d bytes...\n", bytes)); + dev_dbg(chip->card->dev, "Try to send %d bytes...\n", bytes); sent = write_midi(chip, buf, bytes); if (sent < 0) { dev_err(chip->card->dev, @@ -227,12 +227,12 @@ static void snd_echo_midi_output_write(unsigned long data) sent = 9000; chip->midi_full = 1; } else if (sent > 0) { - DE_MID(("%d bytes sent\n", sent)); + dev_dbg(chip->card->dev, "%d bytes sent\n", sent); snd_rawmidi_transmit_ack(chip->midi_out, sent); } else { /* Buffer is full. DSP's internal buffer is 64 (128 ?) bytes long. Let's wait until half of them are sent */ - DE_MID(("Full\n")); + dev_dbg(chip->card->dev, "Full\n"); sent = 32; chip->midi_full = 1; } @@ -244,7 +244,8 @@ static void snd_echo_midi_output_write(unsigned long data) sent */ time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); - DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); + dev_dbg(chip->card->dev, + "Timer armed(%d)\n", ((time * HZ + 999) / 1000)); } spin_unlock_irqrestore(&chip->lock, flags); } @@ -256,7 +257,7 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream { struct echoaudio *chip = substream->rmidi->private_data; - DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); + dev_dbg(chip->card->dev, "snd_echo_midi_output_trigger(%d)\n", up); spin_lock_irq(&chip->lock); if (up) { if (!chip->tinuse) { @@ -270,7 +271,7 @@ static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream chip->tinuse = 0; spin_unlock_irq(&chip->lock); del_timer_sync(&chip->timer); - DE_MID(("Timer removed\n")); + dev_dbg(chip->card->dev, "Timer removed\n"); return; } } @@ -287,7 +288,7 @@ static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) struct echoaudio *chip = substream->rmidi->private_data; chip->midi_out = NULL; - DE_MID(("rawmidi_oclose\n")); + dev_dbg(chip->card->dev, "rawmidi_oclose\n"); return 0; } @@ -327,6 +328,6 @@ static int snd_echo_midi_create(struct snd_card *card, chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; - DE_INIT(("MIDI ok\n")); + dev_dbg(chip->card->dev, "MIDI ok\n"); return 0; } diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index 6e6a7eb555b8..cc46a8c8e3dd 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c @@ -41,12 +41,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { int err; - DE_INIT(("init_hw() - Mona\n")); + dev_dbg(chip->card->dev, "init_hw() - Mona\n"); if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) return -ENODEV; if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); + dev_err(chip->card->dev, + "init_hw - could not initialize DSP comm page\n"); return err; } @@ -71,7 +72,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; chip->bad_board = FALSE; - DE_INIT(("init_hw done\n")); + dev_dbg(chip->card->dev, "init_hw done\n"); return err; } @@ -202,8 +203,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); + dev_dbg(chip->card->dev, + "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); /* Save the rate anyhow */ chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; @@ -279,7 +280,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) clock = GML_8KHZ; break; default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); + dev_err(chip->card->dev, + "set_sample_rate: %d invalid!\n", rate); return -EINVAL; } @@ -287,7 +289,8 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); + dev_dbg(chip->card->dev, + "set_sample_rate: %d clock %d\n", rate, clock); return write_control_reg(chip, control_reg, force_write); } @@ -299,7 +302,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) u32 control_reg, clocks_from_dsp; int err; - DE_ACT(("set_input_clock:\n")); + dev_dbg(chip->card->dev, "set_input_clock:\n"); /* Prevent two simultaneous calls to switch_asic() */ if (atomic_read(&chip->opencount)) @@ -312,7 +315,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) switch (clock) { case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Mona clock to INTERNAL\n")); + dev_dbg(chip->card->dev, "Set Mona clock to INTERNAL\n"); chip->input_clock = ECHO_CLOCK_INTERNAL; return set_sample_rate(chip, chip->sample_rate); case ECHO_CLOCK_SPDIF: @@ -324,7 +327,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) spin_lock_irq(&chip->lock); if (err < 0) return err; - DE_ACT(("Set Mona clock to SPDIF\n")); + dev_dbg(chip->card->dev, "Set Mona clock to SPDIF\n"); control_reg |= GML_SPDIF_CLOCK; if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) control_reg |= GML_DOUBLE_SPEED_MODE; @@ -332,7 +335,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) control_reg &= ~GML_DOUBLE_SPEED_MODE; break; case ECHO_CLOCK_WORD: - DE_ACT(("Set Mona clock to WORD\n")); + dev_dbg(chip->card->dev, "Set Mona clock to WORD\n"); spin_unlock_irq(&chip->lock); err = switch_asic(chip, clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96); @@ -346,14 +349,15 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) control_reg &= ~GML_DOUBLE_SPEED_MODE; break; case ECHO_CLOCK_ADAT: - DE_ACT(("Set Mona clock to ADAT\n")); + dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n"); if (chip->digital_mode != DIGITAL_MODE_ADAT) return -EAGAIN; control_reg |= GML_ADAT_CLOCK; control_reg &= ~GML_DOUBLE_SPEED_MODE; break; default: - DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); + dev_err(chip->card->dev, + "Input clock 0x%x not supported for Mona\n", clock); return -EINVAL; } @@ -381,7 +385,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) incompatible_clock = TRUE; break; default: - DE_ACT(("Digital mode not supported: %d\n", mode)); + dev_err(chip->card->dev, + "Digital mode not supported: %d\n", mode); return -EINVAL; } @@ -422,6 +427,6 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) return err; chip->digital_mode = mode; - DE_ACT(("set_digital_mode to %d\n", mode)); + dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode); return incompatible_clock; } -- GitLab From 1a3f83f6493f9d78aa0fe31401fd530b0fe296da Mon Sep 17 00:00:00 2001 From: JD Cole Date: Fri, 31 Oct 2014 17:34:42 -0700 Subject: [PATCH 2512/9457] HID: plantronics: fix errant mouse events This version of the driver prevents Telephony pages which are not mapped as Consumer Control applications AND are not on the Consumer Page from being registered by the hid-input driver. Signed-off-by: JD Cole Reviewed-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 ++++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 2 + drivers/hid/hid-plantronics.c | 78 +++++++++++++++++++++++++++++++++++ include/linux/hid.h | 3 ++ 6 files changed, 92 insertions(+) create mode 100644 drivers/hid/hid-plantronics.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index f42df4dd58d2..bf1c74e19c75 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -613,6 +613,13 @@ config HID_PICOLCD_CIR ---help--- Provide access to PicoLCD's CIR interface via remote control (LIRC). +config HID_PLANTRONICS + tristate "Plantronics USB HID Driver" + default !EXPERT + depends on HID + ---help--- + Provides HID support for Plantronics telephony devices. + config HID_PRIMAX tristate "Primax non-fully HID-compliant devices" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index e2850d8af9ca..5e7ac59447d8 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -94,6 +94,7 @@ ifdef CONFIG_DEBUG_FS hid-picolcd-y += hid-picolcd_debugfs.o endif +obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o obj-$(CONFIG_HID_PRIMAX) += hid-primax.o obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 73bd9e2e42bc..d50313ca64a6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1886,6 +1886,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) }, { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, #if IS_ENABLED(CONFIG_HID_ROCCAT) { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e23ab8b30626..f9f476db671c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -715,6 +715,8 @@ #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 +#define USB_VENDOR_ID_PLANTRONICS 0x047f + #define USB_VENDOR_ID_PANASONIC 0x04da #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 #define USB_DEVICE_ID_PANABOARD_UBT880 0x104d diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c new file mode 100644 index 000000000000..215cdbd10dea --- /dev/null +++ b/drivers/hid/hid-plantronics.c @@ -0,0 +1,78 @@ +/* + * Plantronics USB HID Driver + * + * Copyright (c) 2014 JD Cole + * Copyright (c) 2014 Terry Junge + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include "hid-ids.h" + +#include +#include + +static int plantronics_input_mapping(struct hid_device *hdev, + struct hid_input *hi, + struct hid_field *field, + struct hid_usage *usage, + unsigned long **bit, int *max) +{ + if (field->application == HID_CP_CONSUMERCONTROL + && (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { + hid_dbg(hdev, "usage: %08x (appl: %08x) - defaulted\n", + usage->hid, field->application); + return 0; + } + + hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n", + usage->hid, field->application); + + return -1; +} + +static int plantronics_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto err; + } + + return 0; + err: + return ret; +} + +static const struct hid_device_id plantronics_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, + { } +}; +MODULE_DEVICE_TABLE(hid, plantronics_devices); + +static struct hid_driver plantronics_driver = { + .name = "plantronics", + .id_table = plantronics_devices, + .input_mapping = plantronics_input_mapping, + .probe = plantronics_probe, +}; +module_hid_driver(plantronics_driver); + +MODULE_AUTHOR("JD Cole "); +MODULE_AUTHOR("Terry Junge "); +MODULE_DESCRIPTION("Plantronics USB HID Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/hid.h b/include/linux/hid.h index 78ea9bf941cd..a63f2aaed646 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -234,6 +234,9 @@ struct hid_item { #define HID_DG_BARRELSWITCH 0x000d0044 #define HID_DG_ERASER 0x000d0045 #define HID_DG_TABLETPICK 0x000d0046 + +#define HID_CP_CONSUMERCONTROL 0x000c0001 + #define HID_DG_CONFIDENCE 0x000d0047 #define HID_DG_WIDTH 0x000d0048 #define HID_DG_HEIGHT 0x000d0049 -- GitLab From 1e48d542e751f766d0ff03aa97bef22d90a98041 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 3 Nov 2014 14:19:14 +0100 Subject: [PATCH 2513/9457] HID: plantronics: remove superfluous .probe() Remove redundanct probe() callback, as it isn't doing anything extra that HID core wouldn't do by default. Reported-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-plantronics.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c index 215cdbd10dea..2180e0789b76 100644 --- a/drivers/hid/hid-plantronics.c +++ b/drivers/hid/hid-plantronics.c @@ -36,28 +36,6 @@ static int plantronics_input_mapping(struct hid_device *hdev, return -1; } -static int plantronics_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - hid_err(hdev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto err; - } - - return 0; - err: - return ret; -} - static const struct hid_device_id plantronics_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, { } @@ -68,7 +46,6 @@ static struct hid_driver plantronics_driver = { .name = "plantronics", .id_table = plantronics_devices, .input_mapping = plantronics_input_mapping, - .probe = plantronics_probe, }; module_hid_driver(plantronics_driver); -- GitLab From a45c30ec59342c47604ea074bcf56a43a8cde8aa Mon Sep 17 00:00:00 2001 From: JD Cole Date: Fri, 31 Oct 2014 17:44:42 -0700 Subject: [PATCH 2514/9457] HID: added missing HID Consumer Page identifiers Adds CA and NAry usage type identifiers. Signed-off-by: JD Cole Signed-off-by: Jiri Kosina --- include/linux/hid.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index a63f2aaed646..58a89ed86acc 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -236,6 +236,30 @@ struct hid_item { #define HID_DG_TABLETPICK 0x000d0046 #define HID_CP_CONSUMERCONTROL 0x000c0001 +#define HID_CP_NUMERICKEYPAD 0x000c0002 +#define HID_CP_PROGRAMMABLEBUTTONS 0x000c0003 +#define HID_CP_MICROPHONE 0x000c0004 +#define HID_CP_HEADPHONE 0x000c0005 +#define HID_CP_GRAPHICEQUALIZER 0x000c0006 +#define HID_CP_FUNCTIONBUTTONS 0x000c0036 +#define HID_CP_SELECTION 0x000c0080 +#define HID_CP_MEDIASELECTION 0x000c0087 +#define HID_CP_SELECTDISC 0x000c00ba +#define HID_CP_PLAYBACKSPEED 0x000c00f1 +#define HID_CP_PROXIMITY 0x000c0109 +#define HID_CP_SPEAKERSYSTEM 0x000c0160 +#define HID_CP_CHANNELLEFT 0x000c0161 +#define HID_CP_CHANNELRIGHT 0x000c0162 +#define HID_CP_CHANNELCENTER 0x000c0163 +#define HID_CP_CHANNELFRONT 0x000c0164 +#define HID_CP_CHANNELCENTERFRONT 0x000c0165 +#define HID_CP_CHANNELSIDE 0x000c0166 +#define HID_CP_CHANNELSURROUND 0x000c0167 +#define HID_CP_CHANNELLOWFREQUENCYENHANCEMENT 0x000c0168 +#define HID_CP_CHANNELTOP 0x000c0169 +#define HID_CP_CHANNELUNKNOWN 0x000c016a +#define HID_CP_APPLICATIONLAUNCHBUTTONS 0x000c0180 +#define HID_CP_GENERICGUIAPPLICATIONCONTROLS 0x000c0200 #define HID_DG_CONFIDENCE 0x000d0047 #define HID_DG_WIDTH 0x000d0048 -- GitLab From 3e7830ceb94cd06c05832a0d53cf324db3792418 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 31 Oct 2014 12:14:39 +0300 Subject: [PATCH 2515/9457] HID: logitech-hidpp: leaks and NULL dereferences Shift the allocation down a few lines to avoid a memory leak and also add a check for allocation failure. Fixes: 2f31c5252910 ('HID: Introduce hidpp, a module to handle Logitech hid++ devices') Signed-off-by: Dan Carpenter Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 361e97da1169..8d2d54b527b0 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -200,13 +200,15 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count, struct hidpp_report *response) { - struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report), - GFP_KERNEL); + struct hidpp_report *message; int ret; if (param_count > sizeof(message->fap.params)) return -EINVAL; + message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); + if (!message) + return -ENOMEM; message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; @@ -221,8 +223,7 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count, struct hidpp_report *response) { - struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report), - GFP_KERNEL); + struct hidpp_report *message; int ret; if ((report_id != REPORT_ID_HIDPP_SHORT) && @@ -232,6 +233,9 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, if (param_count > sizeof(message->rap.params)) return -EINVAL; + message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); + if (!message) + return -ENOMEM; message->report_id = report_id; message->rap.sub_id = sub_id; message->rap.reg_address = reg_address; -- GitLab From b5b7b487431b01619f2947d91dadd7c7a233692e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 24 Oct 2014 13:59:19 +0200 Subject: [PATCH 2516/9457] gpio: mvebu: add suspend/resume support This commit adds the implementation of ->suspend() and ->resume() platform_driver hooks in order to save and restore the state of the GPIO configuration. In order to achieve that, additional fields are added to the mvebu_gpio_chip structure. Signed-off-by: Thomas Petazzoni Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 418e38650363..dd5545c293d4 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -83,6 +83,14 @@ struct mvebu_gpio_chip { int irqbase; struct irq_domain *domain; int soc_variant; + + /* Used to preserve GPIO registers accross suspend/resume */ + u32 out_reg; + u32 io_conf_reg; + u32 blink_en_reg; + u32 in_pol_reg; + u32 edge_mask_regs[4]; + u32 level_mask_regs[4]; }; /* @@ -554,6 +562,93 @@ static const struct of_device_id mvebu_gpio_of_match[] = { }; MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match); +static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mvebu_gpio_chip *mvchip = platform_get_drvdata(pdev); + int i; + + mvchip->out_reg = readl(mvebu_gpioreg_out(mvchip)); + mvchip->io_conf_reg = readl(mvebu_gpioreg_io_conf(mvchip)); + mvchip->blink_en_reg = readl(mvebu_gpioreg_blink(mvchip)); + mvchip->in_pol_reg = readl(mvebu_gpioreg_in_pol(mvchip)); + + switch (mvchip->soc_variant) { + case MVEBU_GPIO_SOC_VARIANT_ORION: + mvchip->edge_mask_regs[0] = + readl(mvchip->membase + GPIO_EDGE_MASK_OFF); + mvchip->level_mask_regs[0] = + readl(mvchip->membase + GPIO_LEVEL_MASK_OFF); + break; + case MVEBU_GPIO_SOC_VARIANT_MV78200: + for (i = 0; i < 2; i++) { + mvchip->edge_mask_regs[i] = + readl(mvchip->membase + + GPIO_EDGE_MASK_MV78200_OFF(i)); + mvchip->level_mask_regs[i] = + readl(mvchip->membase + + GPIO_LEVEL_MASK_MV78200_OFF(i)); + } + break; + case MVEBU_GPIO_SOC_VARIANT_ARMADAXP: + for (i = 0; i < 4; i++) { + mvchip->edge_mask_regs[i] = + readl(mvchip->membase + + GPIO_EDGE_MASK_ARMADAXP_OFF(i)); + mvchip->level_mask_regs[i] = + readl(mvchip->membase + + GPIO_LEVEL_MASK_ARMADAXP_OFF(i)); + } + break; + default: + BUG(); + } + + return 0; +} + +static int mvebu_gpio_resume(struct platform_device *pdev) +{ + struct mvebu_gpio_chip *mvchip = platform_get_drvdata(pdev); + int i; + + writel(mvchip->out_reg, mvebu_gpioreg_out(mvchip)); + writel(mvchip->io_conf_reg, mvebu_gpioreg_io_conf(mvchip)); + writel(mvchip->blink_en_reg, mvebu_gpioreg_blink(mvchip)); + writel(mvchip->in_pol_reg, mvebu_gpioreg_in_pol(mvchip)); + + switch (mvchip->soc_variant) { + case MVEBU_GPIO_SOC_VARIANT_ORION: + writel(mvchip->edge_mask_regs[0], + mvchip->membase + GPIO_EDGE_MASK_OFF); + writel(mvchip->level_mask_regs[0], + mvchip->membase + GPIO_LEVEL_MASK_OFF); + break; + case MVEBU_GPIO_SOC_VARIANT_MV78200: + for (i = 0; i < 2; i++) { + writel(mvchip->edge_mask_regs[i], + mvchip->membase + GPIO_EDGE_MASK_MV78200_OFF(i)); + writel(mvchip->level_mask_regs[i], + mvchip->membase + + GPIO_LEVEL_MASK_MV78200_OFF(i)); + } + break; + case MVEBU_GPIO_SOC_VARIANT_ARMADAXP: + for (i = 0; i < 4; i++) { + writel(mvchip->edge_mask_regs[i], + mvchip->membase + + GPIO_EDGE_MASK_ARMADAXP_OFF(i)); + writel(mvchip->level_mask_regs[i], + mvchip->membase + + GPIO_LEVEL_MASK_ARMADAXP_OFF(i)); + } + break; + default: + BUG(); + } + + return 0; +} + static int mvebu_gpio_probe(struct platform_device *pdev) { struct mvebu_gpio_chip *mvchip; @@ -577,6 +672,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) if (!mvchip) return -ENOMEM; + platform_set_drvdata(pdev, mvchip); + if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) { dev_err(&pdev->dev, "Missing ngpios OF property\n"); return -ENODEV; @@ -735,5 +832,7 @@ static struct platform_driver mvebu_gpio_driver = { .of_match_table = mvebu_gpio_of_match, }, .probe = mvebu_gpio_probe, + .suspend = mvebu_gpio_suspend, + .resume = mvebu_gpio_resume, }; module_platform_driver(mvebu_gpio_driver); -- GitLab From eace972103923a5391bf34cf3ee67e009d88b785 Mon Sep 17 00:00:00 2001 From: Witold Krecicki Date: Sun, 19 Oct 2014 19:25:59 -0300 Subject: [PATCH 2517/9457] [media] em28xx: add support for Leadtek VC100 USB capture device Leadtek VC100 is a simple USB capture stick, similar to Yakumo Movie Mixer. Signed-off-by: Witold Krecicki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 16 ++++++++++++++++ drivers/media/usb/em28xx/em28xx.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 71fa51e7984e..3c97bf106442 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2243,6 +2243,20 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, }, + [EM2861_BOARD_LEADTEK_VC100] = { + .name = "Leadtek VC100", + .tuner_type = TUNER_ABSENT, /* Capture only device */ + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2424,6 +2438,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PCTV_461E }, { USB_DEVICE(0x2013, 0x025f), .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x0413, 0x6f07), + .driver_info = EM2861_BOARD_LEADTEK_VC100 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index a21a7463b557..05e7f7c77ea1 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -141,6 +141,7 @@ #define EM28178_BOARD_PCTV_461E 92 #define EM2874_BOARD_KWORLD_UB435Q_V3 93 #define EM28178_BOARD_PCTV_292E 94 +#define EM2861_BOARD_LEADTEK_VC100 95 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- GitLab From 8d6d514941d37bd3625bc8ab99a042fbccdaa0da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Nov 2014 11:35:01 -0200 Subject: [PATCH 2518/9457] [media] Update Documentation cardlist Some new devices got added. Update cardlists. Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.cx23885 | 2 ++ Documentation/video4linux/CARDLIST.em28xx | 1 + Documentation/video4linux/CARDLIST.saa7134 | 1 + 3 files changed, 4 insertions(+) diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index a74eeccfe700..4c84ec853265 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -43,3 +43,5 @@ 42 -> Leadtek Winfast PxPVR2200 [107d:6f21] 43 -> Hauppauge ImpactVCB-e [0070:7133] 44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98] + 45 -> DVBSky T9580 [4254:9580] + 46 -> DVBSky T980C [4254:980c] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index bc3351bb48b4..3700edb81db2 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -93,3 +93,4 @@ 92 -> PCTV DVB-S2 Stick (461e) (em28178) 93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c] 94 -> PCTV tripleStick (292e) (em28178) + 95 -> Leadtek VC100 (em2861) [0413:6f07] diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 8df17d063499..a93d86455233 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -191,3 +191,4 @@ 190 -> Asus My Cinema PS3-100 [1043:48cd] 191 -> Hawell HW-9004V1 192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055] +193 -> WIS Voyager or compatible [1905:7007] -- GitLab From 24d333f387e457a98d1551dd43d716700218f6b5 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Mon, 20 Oct 2014 07:05:47 -0300 Subject: [PATCH 2519/9457] [media] dvb-usb-dvbsky: add s960ci dvb-s/s2 usb ci box support DVBSky s960ci dvb-s/s2 usb ci box: 1>dvb frontend: M88TS2022(tuner),M88DS3103(demod) 2>usb controller: CY7C86013A 3>ci controller: CIMAX SP2 or its clone. Signed-off-by: Nibble Max Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/Kconfig | 1 + drivers/media/usb/dvb-usb-v2/dvbsky.c | 188 ++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 5b34323ad207..74230339f62b 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -146,5 +146,6 @@ config DVB_USB_DVBSKY depends on DVB_USB_V2 select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT help Say Y here to support the USB receivers from DVBSky. diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 2499635df52f..c67a118ef219 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -21,6 +21,7 @@ #include "dvb_usb.h" #include "m88ds3103.h" #include "m88ts2022.h" +#include "sp2.h" #define DVBSKY_MSG_DELAY 0/*2000*/ #define DVBSKY_BUF_LEN 64 @@ -37,6 +38,7 @@ struct dvbsky_state { u8 obuf[DVBSKY_BUF_LEN]; u8 last_lock; struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_ci; /* fe hook functions*/ int (*fe_set_voltage)(struct dvb_frontend *fe, @@ -364,6 +366,157 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap) return ret; } +static int dvbsky_usb_ci_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct dvb_usb_device *d = fe_to_d(fe); + struct dvbsky_state *state = d_to_priv(d); + u8 value; + + if (voltage == SEC_VOLTAGE_OFF) + value = 0; + else + value = 1; + dvbsky_gpio_ctrl(d, 0x00, value); + + return state->fe_set_voltage(fe, voltage); +} + +static int dvbsky_ci_ctrl(void *priv, u8 read, int addr, + u8 data, int *mem) +{ + struct dvb_usb_device *d = priv; + int ret = 0; + u8 command[4], respond[2], command_size, respond_size; + + command[1] = (u8)((addr >> 8) & 0xff); /*high part of address*/ + command[2] = (u8)(addr & 0xff); /*low part of address*/ + if (read) { + command[0] = 0x71; + command_size = 3; + respond_size = 2; + } else { + command[0] = 0x70; + command[3] = data; + command_size = 4; + respond_size = 1; + } + ret = dvbsky_usb_generic_rw(d, command, command_size, + respond, respond_size); + if (ret) + goto err; + if (read) + *mem = respond[1]; + return ret; +err: + dev_err(&d->udev->dev, "ci control failed=%d\n", ret); + return ret; +} + +static const struct m88ds3103_config dvbsky_s960c_m88ds3103_config = { + .i2c_addr = 0x68, + .clock = 27000000, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_CI, + .ts_clk = 10000, + .ts_clk_pol = 1, + .agc = 0x99, + .lnb_hv_pol = 0, + .lnb_en_pol = 1, +}; + +static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) +{ + struct dvbsky_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + int ret = 0; + /* demod I2C adapter */ + struct i2c_adapter *i2c_adapter; + struct i2c_client *client_tuner, *client_ci; + struct i2c_board_info info; + struct sp2_config sp2_config; + struct m88ts2022_config m88ts2022_config = { + .clock = 27000000, + }; + memset(&info, 0, sizeof(struct i2c_board_info)); + + /* attach demod */ + adap->fe[0] = dvb_attach(m88ds3103_attach, + &dvbsky_s960c_m88ds3103_config, + &d->i2c_adap, + &i2c_adapter); + if (!adap->fe[0]) { + dev_err(&d->udev->dev, "dvbsky_s960ci_attach fail.\n"); + ret = -ENODEV; + goto fail_attach; + } + + /* attach tuner */ + m88ts2022_config.fe = adap->fe[0]; + strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &m88ts2022_config; + request_module("m88ts2022"); + client_tuner = i2c_new_device(i2c_adapter, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + ret = -ENODEV; + goto fail_tuner_device; + } + + if (!try_module_get(client_tuner->dev.driver->owner)) { + ret = -ENODEV; + goto fail_tuner_module; + } + + /* attach ci controller */ + memset(&sp2_config, 0, sizeof(sp2_config)); + sp2_config.dvb_adap = &adap->dvb_adap; + sp2_config.priv = d; + sp2_config.ci_control = dvbsky_ci_ctrl; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "sp2", I2C_NAME_SIZE); + info.addr = 0x40; + info.platform_data = &sp2_config; + request_module("sp2"); + client_ci = i2c_new_device(i2c_adapter, &info); + if (client_ci == NULL || client_ci->dev.driver == NULL) { + ret = -ENODEV; + goto fail_ci_device; + } + + if (!try_module_get(client_ci->dev.driver->owner)) { + ret = -ENODEV; + goto fail_ci_module; + } + + /* delegate signal strength measurement to tuner */ + adap->fe[0]->ops.read_signal_strength = + adap->fe[0]->ops.tuner_ops.get_rf_strength; + + /* hook fe: need to resync the slave fifo when signal locks. */ + state->fe_read_status = adap->fe[0]->ops.read_status; + adap->fe[0]->ops.read_status = dvbsky_usb_read_status; + + /* hook fe: LNB off/on is control by Cypress usb chip. */ + state->fe_set_voltage = adap->fe[0]->ops.set_voltage; + adap->fe[0]->ops.set_voltage = dvbsky_usb_ci_set_voltage; + + state->i2c_client_tuner = client_tuner; + state->i2c_client_ci = client_ci; + return ret; +fail_ci_module: + i2c_unregister_device(client_ci); +fail_ci_device: + module_put(client_tuner->dev.driver->owner); +fail_tuner_module: + i2c_unregister_device(client_tuner); +fail_tuner_device: + dvb_frontend_detach(adap->fe[0]); +fail_attach: + return ret; +} + static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name) { dvbsky_gpio_ctrl(d, 0x04, 1); @@ -406,6 +559,12 @@ static void dvbsky_exit(struct dvb_usb_device *d) module_put(client->dev.driver->owner); i2c_unregister_device(client); } + client = state->i2c_client_ci; + /* remove I2C ci */ + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } } /* DVB USB Driver stuff */ @@ -436,9 +595,38 @@ static struct dvb_usb_device_properties dvbsky_s960_props = { } }; +static struct dvb_usb_device_properties dvbsky_s960c_props = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct dvbsky_state), + + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY, + + .i2c_algo = &dvbsky_i2c_algo, + .frontend_attach = dvbsky_s960c_attach, + .init = dvbsky_init, + .get_rc_config = dvbsky_get_rc_config, + .streaming_ctrl = dvbsky_streaming_ctrl, + .identify_state = dvbsky_identify_state, + .exit = dvbsky_exit, + .read_mac_address = dvbsky_read_mac_addr, + + .num_adapters = 1, + .adapter = { + { + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096), + } + } +}; + static const struct usb_device_id dvbsky_id_table[] = { { DVB_USB_DEVICE(0x0572, 0x6831, &dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(0x0572, 0x960c, + &dvbsky_s960c_props, "DVBSky S960CI", RC_MAP_DVBSKY) }, { } }; MODULE_DEVICE_TABLE(usb, dvbsky_id_table); -- GitLab From a736abc1ac09b824387fb75b2aa7887c6e3ed68a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Nov 2014 14:20:56 +0100 Subject: [PATCH 2520/9457] Bluetooth: Fix invalid response for 'Start Discovery' command According to Management Interface API 'Start Discovery' command should generate a Command Complete event on failure. Currently kernel is sending Command Status on early errors. This results in userspace ignoring such event due to invalid size. bluetoothd[28499]: src/adapter.c:trigger_start_discovery() bluetoothd[28499]: src/adapter.c:cancel_passive_scanning() bluetoothd[28499]: src/adapter.c:start_discovery_timeout() bluetoothd[28499]: src/adapter.c:start_discovery_complete() status 0x0a bluetoothd[28499]: Wrong size of start discovery return parameters Reported-by: Jukka Taimisto Signed-off-by: Szymon Janc Signed-off-by: Johan Hedberg --- net/bluetooth/mgmt.c | 56 +++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 9c4daf715cf8..ce0272c6f71f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3727,20 +3727,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_NOT_POWERED); + err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_NOT_POWERED, + &cp->type, sizeof(cp->type)); goto failed; } if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_BUSY); + err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_BUSY, &cp->type, + sizeof(cp->type)); goto failed; } if (hdev->discovery.state != DISCOVERY_STOPPED) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_BUSY); + err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_BUSY, &cp->type, + sizeof(cp->type)); goto failed; } @@ -3758,15 +3761,18 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, case DISCOV_TYPE_BREDR: status = mgmt_bredr_support(hdev); if (status) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - status); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, status, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } if (test_bit(HCI_INQUIRY, &hdev->flags)) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_BUSY); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, + MGMT_STATUS_BUSY, &cp->type, + sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -3783,16 +3789,19 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, case DISCOV_TYPE_INTERLEAVED: status = mgmt_le_support(hdev); if (status) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - status); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, status, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_NOT_SUPPORTED); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, + MGMT_STATUS_NOT_SUPPORTED, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -3804,9 +3813,11 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, */ if (hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { - err = cmd_status(sk, hdev->id, - MGMT_OP_START_DISCOVERY, - MGMT_STATUS_REJECTED); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, + MGMT_STATUS_REJECTED, + &cp->type, + sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -3829,8 +3840,10 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, */ err = hci_update_random_address(&req, true, &own_addr_type); if (err < 0) { - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_FAILED); + err = cmd_complete(sk, hdev->id, + MGMT_OP_START_DISCOVERY, + MGMT_STATUS_FAILED, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } @@ -3850,8 +3863,9 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, break; default: - err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, - MGMT_STATUS_INVALID_PARAMS); + err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY, + MGMT_STATUS_INVALID_PARAMS, + &cp->type, sizeof(cp->type)); mgmt_pending_remove(cmd); goto failed; } -- GitLab From 0e6c7b0117214295c8abe05985a146faa914fcc4 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Thu, 23 Oct 2014 07:01:44 -0300 Subject: [PATCH 2521/9457] [media] cx23885: add DVBSky S950C dvb-s/s2 ci PCIe card support(no RC) DVBSky s950ci dvb-s/s2 ci PCIe card: 1>dvb frontend: M88TS2022(tuner),M88DS3103(demod) 2>ci controller: CIMAX SP2 or its clone. 3>PCIe bridge: CX23885 The patchs are based on the following patchs. Olli Salonen submit: https://patchwork.linuxtv.org/patch/26180/ https://patchwork.linuxtv.org/patch/26183/ https://patchwork.linuxtv.org/patch/26324/ Nibble Max submit: https://patchwork.linuxtv.org/patch/26207/ Signed-off-by: Nibble Max Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 11 ++++ drivers/media/pci/cx23885/cx23885-dvb.c | 79 +++++++++++++++++++---- drivers/media/pci/cx23885/cx23885.h | 1 + 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index c4a69e404c3b..ac34c27c8205 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -684,6 +684,10 @@ struct cx23885_board cx23885_boards[] = { .name = "DVBSky T980C", .portb = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVBSKY_S950C] = { + .name = "DVBSky S950C", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -947,6 +951,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x4254, .subdevice = 0x980c, .card = CX23885_BOARD_DVBSKY_T980C, + }, { + .subvendor = 0x4254, + .subdevice = 0x950c, + .card = CX23885_BOARD_DVBSKY_S950C, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1550,6 +1558,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx23885_gpio_set(dev, GPIO_2 | GPIO_11); break; case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: /* * GPIO-0 INTA from CiMax, input * GPIO-1 reset CiMax, output, high active @@ -1859,6 +1868,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_DVBWORLD_2005: case CX23885_BOARD_PROF_8000: case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -1978,6 +1988,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 757854914781..f82eb1881ac2 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -635,7 +635,7 @@ static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr, struct cx23885_tsport *port = priv; struct cx23885_dev *dev = port->dev; int ret; - int tmp; + int tmp = 0; unsigned long timeout; mutex_lock(&dev->gpio_lock); @@ -865,6 +865,19 @@ static const struct m88ds3103_config dvbsky_t9580_m88ds3103_config = { .agc = 0x99, }; +static const struct m88ds3103_config dvbsky_s950c_m88ds3103_config = { + .i2c_addr = 0x68, + .clock = 27000000, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_CI, + .ts_clk = 10000, + .ts_clk_pol = 1, + .lnb_en_pol = 1, + .lnb_hv_pol = 0, + .agc = 0x99, +}; + static int netup_altera_fpga_rw(void *device, int flag, int data, int read) { struct cx23885_dev *dev = (struct cx23885_dev *)device; @@ -1020,7 +1033,7 @@ static int dvb_register(struct cx23885_tsport *port) struct m88ts2022_config m88ts2022_config; struct i2c_board_info info; struct i2c_adapter *adapter; - struct i2c_client *client_demod, *client_tuner, *client_ci; + struct i2c_client *client_demod = NULL, *client_tuner = NULL, *client_ci = NULL; int mfe_shared = 0; /* bus not shared by default */ int ret; @@ -1797,6 +1810,41 @@ static int dvb_register(struct cx23885_tsport *port) i2c_unregister_device(client_demod); goto frontend_detach; } + port->i2c_client_tuner = client_tuner; + break; + case CX23885_BOARD_DVBSKY_S950C: + i2c_bus = &dev->i2c_bus[1]; + i2c_bus2 = &dev->i2c_bus[0]; + + /* attach frontend */ + fe0->dvb.frontend = dvb_attach(m88ds3103_attach, + &dvbsky_s950c_m88ds3103_config, + &i2c_bus->i2c_adap, &adapter); + if (fe0->dvb.frontend == NULL) + break; + + /* attach tuner */ + memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); + m88ts2022_config.fe = fe0->dvb.frontend; + m88ts2022_config.clock = 27000000; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &m88ts2022_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) + goto frontend_detach; + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + goto frontend_detach; + } + + /* delegate signal strength measurement to tuner */ + fe0->dvb.frontend->ops.read_signal_strength = + fe0->dvb.frontend->ops.tuner_ops.get_rf_strength; + port->i2c_client_tuner = client_tuner; break; default: @@ -1889,6 +1937,7 @@ static int dvb_register(struct cx23885_tsport *port) (port->nr-1) * 8, 6); break; } + case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_DVBSKY_T980C: { u8 eeprom[256]; /* 24C02 i2c eeprom */ @@ -1905,18 +1954,26 @@ static int dvb_register(struct cx23885_tsport *port) client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info); if (client_ci == NULL || client_ci->dev.driver == NULL) { - module_put(client_tuner->dev.driver->owner); - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); + if (client_tuner) { + module_put(client_tuner->dev.driver->owner); + i2c_unregister_device(client_tuner); + } + if (client_demod) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + } goto frontend_detach; } if (!try_module_get(client_ci->dev.driver->owner)) { i2c_unregister_device(client_ci); - module_put(client_tuner->dev.driver->owner); - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); + if (client_tuner) { + module_put(client_tuner->dev.driver->owner); + i2c_unregister_device(client_tuner); + } + if (client_demod) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + } goto frontend_detach; } port->i2c_client_ci = client_ci; @@ -1928,7 +1985,7 @@ static int dvb_register(struct cx23885_tsport *port) dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "DVBSky T980C MAC address: %pM\n", + printk(KERN_INFO "DVBSky T980C/S950C MAC address: %pM\n", eeprom + 0xc0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6); break; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 27ea249d07cf..f6f6974ee824 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -94,6 +94,7 @@ #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44 #define CX23885_BOARD_DVBSKY_T9580 45 #define CX23885_BOARD_DVBSKY_T980C 46 +#define CX23885_BOARD_DVBSKY_S950C 47 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From 070e66611d6f33125204fc7869459d7e141dae31 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Thu, 23 Oct 2014 07:02:16 -0300 Subject: [PATCH 2522/9457] [media] cx23885: add DVBSky S950C and T980C RC support DVBSky s950ci dvb-s/s2 ci PCIe card: 1>dvb frontend: M88TS2022(tuner),M88DS3103(demod) 2>ci controller: CIMAX SP2 or its clone. 3>PCIe bridge: CX23885 The patchs are based on the following patchs. Olli Salonen submit: https://patchwork.linuxtv.org/patch/26180/ https://patchwork.linuxtv.org/patch/26183/ https://patchwork.linuxtv.org/patch/26324/ Nibble Max submit: https://patchwork.linuxtv.org/patch/26207/ Signed-off-by: Nibble Max Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 6 ++++++ drivers/media/pci/cx23885/cx23885-input.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index ac34c27c8205..d9ba48cfb41f 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -1669,6 +1669,8 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1716,6 +1718,8 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1764,6 +1768,8 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index f81c2f9f0e92..0bf6839cb04d 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -88,6 +88,8 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -141,6 +143,8 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -308,6 +312,8 @@ int cx23885_input_init(struct cx23885_dev *dev) rc_map = RC_MAP_TBS_NEC; break; case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_DVBSKY_S950C: /* Integrated CX23885 IR controller */ driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; -- GitLab From 4954578efb5fd91dd6432ecf7f04ba1b82a60693 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Thu, 23 Oct 2014 10:36:49 -0300 Subject: [PATCH 2523/9457] [media] m88ts2022: return the err code in its probe function when error occurs if "chip_id" is wrong or "dev->cfg.clock_out" is invalid, the i2c model is still loaded. It will cause "kernel NULL pointer dereference" oops when the i2c model remove. returning the err code will prevent the i2c model load. Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/m88ts2022.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c index caa542346891..066e5431da93 100644 --- a/drivers/media/tuners/m88ts2022.c +++ b/drivers/media/tuners/m88ts2022.c @@ -488,6 +488,7 @@ static int m88ts2022_probe(struct i2c_client *client, case 0x83: break; default: + ret = -ENODEV; goto err; } @@ -505,6 +506,7 @@ static int m88ts2022_probe(struct i2c_client *client, u8tmp = 0x6c; break; default: + ret = -EINVAL; goto err; } -- GitLab From 31604d35db18c1382c7ee9fa836ff9ab0b4d2751 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 3 Nov 2014 14:54:36 +0100 Subject: [PATCH 2524/9457] ALSA: emu10k1: Deletion of unnecessary checks before three function calls The functions kfree(), release_firmware() and snd_util_memhdr_free() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emu10k1_main.c | 9 +++------ sound/pci/emu10k1/emufx.c | 3 +-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 229269788023..b4458a630a7c 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1289,10 +1289,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) } if (emu->emu1010.firmware_thread) kthread_stop(emu->emu1010.firmware_thread); - if (emu->firmware) - release_firmware(emu->firmware); - if (emu->dock_fw) - release_firmware(emu->dock_fw); + release_firmware(emu->firmware); + release_firmware(emu->dock_fw); if (emu->irq >= 0) free_irq(emu->irq, emu); /* remove reserved page */ @@ -1301,8 +1299,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) (struct snd_util_memblk *)emu->reserved_page); emu->reserved_page = NULL; } - if (emu->memhdr) - snd_util_memhdr_free(emu->memhdr); + snd_util_memhdr_free(emu->memhdr); if (emu->silent_page.area) snd_dma_free_pages(&emu->silent_page); if (emu->ptb_pages.area) diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 745f0627c634..eb5c0aba41c1 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -777,8 +777,7 @@ static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl) kctl->private_value = 0; list_del(&ctl->list); kfree(ctl); - if (kctl->tlv.p) - kfree(kctl->tlv.p); + kfree(kctl->tlv.p); } static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, -- GitLab From b1c97193c6437a6083da67f8e97c8ee29b2f1989 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 23 Oct 2014 17:58:22 -0300 Subject: [PATCH 2525/9457] [media] rc: port IgorPlug-USB to rc-core This is a complete re-write inspired by the original lirc driver. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 6 + drivers/media/rc/Kconfig | 15 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/igorplugusb.c | 261 +++++++++++++++++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 drivers/media/rc/igorplugusb.c diff --git a/MAINTAINERS b/MAINTAINERS index dab92a78d1d5..1629341dcd9e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4695,6 +4695,12 @@ F: net/mac802154/ F: drivers/net/ieee802154/ F: Documentation/networking/ieee802154.txt +IGORPLUG-USB IR RECEIVER +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/igorplugusb.c + IGUANAWORKS USB IR TRANSCEIVER M: Sean Young L: linux-media@vger.kernel.org diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 8ce08107a69d..1aea7320f52a 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -277,6 +277,21 @@ config IR_WINBOND_CIR To compile this driver as a module, choose M here: the module will be called winbond_cir. +config IR_IGORPLUGUSB + tristate "IgorPlug-USB IR Receiver" + depends on USB_ARCH_HAS_HCD + depends on RC_CORE + select USB + ---help--- + Say Y here if you want to use the IgorPlug-USB IR Receiver by + Igor Cesko. This device is included on the Fit-PC2. + + Note that this device can only record bursts of 36 IR pulses and + spaces, which is not enough for the NEC, Sanyo and RC-6 protocol. + + To compile this driver as a module, choose M here: the module will + be called igorplugusb. + config IR_IGUANA tristate "IguanaWorks USB IR Transceiver" depends on USB_ARCH_HAS_HCD diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 0989f940e9cf..8f509e0d92cf 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o +obj-$(CONFIG_IR_IGORPLUGUSB) += igorplugusb.o obj-$(CONFIG_IR_IGUANA) += iguanair.o obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o obj-$(CONFIG_RC_ST) += st_rc.o diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c new file mode 100644 index 000000000000..b36e51576f8e --- /dev/null +++ b/drivers/media/rc/igorplugusb.c @@ -0,0 +1,261 @@ +/* + * IgorPlug-USB IR Receiver + * + * Copyright (C) 2014 Sean Young + * + * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. + * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm + * + * Based on the lirc_igorplugusb.c driver: + * Copyright (C) 2004 Jan M. Hochstein + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "IgorPlug-USB IR Receiver" +#define DRIVER_NAME "igorplugusb" + +#define HEADERLEN 3 +#define BUFLEN 36 +#define MAX_PACKET (HEADERLEN + BUFLEN) + +#define SET_INFRABUFFER_EMPTY 1 +#define GET_INFRACODE 2 + + +struct igorplugusb { + struct rc_dev *rc; + struct device *dev; + + struct urb *urb; + struct usb_ctrlrequest request; + + struct timer_list timer; + + uint8_t buf_in[MAX_PACKET]; + + char phys[64]; +}; + +static void igorplugusb_cmd(struct igorplugusb *ir, int cmd); + +static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len) +{ + DEFINE_IR_RAW_EVENT(rawir); + unsigned i, start, overflow; + + dev_dbg(ir->dev, "irdata: %*ph (len=%u)", len, ir->buf_in, len); + + /* + * If more than 36 pulses and spaces follow each other, the igorplugusb + * overwrites its buffer from the beginning. The overflow value is the + * last offset which was not overwritten. Everything from this offset + * onwards occurred before everything until this offset. + */ + overflow = ir->buf_in[2]; + i = start = overflow + HEADERLEN; + + if (start >= len) { + dev_err(ir->dev, "receive overflow invalid: %u", overflow); + } else { + if (overflow > 0) + dev_warn(ir->dev, "receive overflow, at least %u lost", + overflow); + + do { + rawir.duration = ir->buf_in[i] * 85333; + rawir.pulse = i & 1; + + ir_raw_event_store_with_filter(ir->rc, &rawir); + + if (++i == len) + i = HEADERLEN; + } while (i != start); + + /* add a trailing space */ + rawir.duration = ir->rc->timeout; + rawir.pulse = false; + ir_raw_event_store_with_filter(ir->rc, &rawir); + + ir_raw_event_handle(ir->rc); + } + + igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); +} + +static void igorplugusb_callback(struct urb *urb) +{ + struct usb_ctrlrequest *req; + struct igorplugusb *ir = urb->context; + + req = (struct usb_ctrlrequest *)urb->setup_packet; + + switch (urb->status) { + case 0: + if (req->bRequest == GET_INFRACODE && + urb->actual_length > HEADERLEN) + igorplugusb_irdata(ir, urb->actual_length); + else /* request IR */ + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(50)); + break; + case -EPROTO: + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + usb_unlink_urb(urb); + return; + default: + dev_warn(ir->dev, "Error: urb status = %d\n", urb->status); + igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); + break; + } +} + +static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) +{ + int ret; + + ir->request.bRequest = cmd; + ir->urb->transfer_flags = 0; + ret = usb_submit_urb(ir->urb, GFP_ATOMIC); + if (ret) + dev_err(ir->dev, "submit urb failed: %d", ret); +} + +static void igorplugusb_timer(unsigned long data) +{ + struct igorplugusb *ir = (struct igorplugusb *)data; + + igorplugusb_cmd(ir, GET_INFRACODE); +} + +static int igorplugusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev; + struct usb_host_interface *idesc; + struct usb_endpoint_descriptor *ep; + struct igorplugusb *ir; + struct rc_dev *rc; + int ret; + + udev = interface_to_usbdev(intf); + idesc = intf->cur_altsetting; + + if (idesc->desc.bNumEndpoints != 1) { + dev_err(&intf->dev, "incorrect number of endpoints"); + return -ENODEV; + } + + ep = &idesc->endpoint[0].desc; + if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) { + dev_err(&intf->dev, "endpoint incorrect"); + return -ENODEV; + } + + ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; + + ir->dev = &intf->dev; + + setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir); + + ir->request.bRequest = GET_INFRACODE; + ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; + ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in)); + + ir->urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ir->urb) + return -ENOMEM; + + usb_fill_control_urb(ir->urb, udev, + usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request, + ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir); + + usb_make_path(udev, ir->phys, sizeof(ir->phys)); + + rc = rc_allocate_device(); + rc->input_name = DRIVER_DESC; + rc->input_phys = ir->phys; + usb_to_input_id(udev, &rc->input_id); + rc->dev.parent = &intf->dev; + rc->driver_type = RC_DRIVER_IR_RAW; + /* + * This device can only store 36 pulses + spaces, which is not enough + * for the NEC protocol and many others. + */ + rc->allowed_protocols = RC_BIT_ALL & ~(RC_BIT_NEC | RC_BIT_RC6_6A_20 | + RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | + RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO); + + rc->priv = ir; + rc->driver_name = DRIVER_NAME; + rc->map_name = RC_MAP_HAUPPAUGE; + rc->timeout = MS_TO_NS(100); + rc->rx_resolution = 85333; + + ir->rc = rc; + ret = rc_register_device(rc); + if (ret) { + dev_err(&intf->dev, "failed to register rc device: %d", ret); + rc_free_device(rc); + usb_free_urb(ir->urb); + return ret; + } + + usb_set_intfdata(intf, ir); + + igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); + + return 0; +} + +static void igorplugusb_disconnect(struct usb_interface *intf) +{ + struct igorplugusb *ir = usb_get_intfdata(intf); + + rc_unregister_device(ir->rc); + del_timer_sync(&ir->timer); + usb_set_intfdata(intf, NULL); + usb_kill_urb(ir->urb); + usb_free_urb(ir->urb); +} + +static struct usb_device_id igorplugusb_table[] = { + /* Igor Plug USB (Atmel's Manufact. ID) */ + { USB_DEVICE(0x03eb, 0x0002) }, + /* Fit PC2 Infrared Adapter */ + { USB_DEVICE(0x03eb, 0x21fe) }, + /* Terminating entry */ + { } +}; + +static struct usb_driver igorplugusb_driver = { + .name = DRIVER_NAME, + .probe = igorplugusb_probe, + .disconnect = igorplugusb_disconnect, + .id_table = igorplugusb_table +}; + +module_usb_driver(igorplugusb_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Sean Young "); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, igorplugusb_table); -- GitLab From 3e5907e695f2f6e1ba622dc37b12b6bddb6295b1 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 23 Oct 2014 17:58:23 -0300 Subject: [PATCH 2526/9457] [media] lirc_igorplugusb: remove This driver has been replaced by an rc-core driver for the same hardware. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/Kconfig | 6 - drivers/staging/media/lirc/Makefile | 1 - drivers/staging/media/lirc/lirc_igorplugusb.c | 508 ------------------ 3 files changed, 515 deletions(-) delete mode 100644 drivers/staging/media/lirc/lirc_igorplugusb.c diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig index e60a59fc252b..6879c4651b46 100644 --- a/drivers/staging/media/lirc/Kconfig +++ b/drivers/staging/media/lirc/Kconfig @@ -18,12 +18,6 @@ config LIRC_BT829 help Driver for the IR interface on BT829-based hardware -config LIRC_IGORPLUGUSB - tristate "Igor Cesko's USB IR Receiver" - depends on LIRC && USB - help - Driver for Igor Cesko's USB IR Receiver - config LIRC_IMON tristate "Legacy SoundGraph iMON Receiver and Display" depends on LIRC && USB diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile index b90fcabddab6..5430adf0475d 100644 --- a/drivers/staging/media/lirc/Makefile +++ b/drivers/staging/media/lirc/Makefile @@ -4,7 +4,6 @@ # Each configuration option enables a list of files. obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o -obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o obj-$(CONFIG_LIRC_IMON) += lirc_imon.o obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c deleted file mode 100644 index 431d1e86ebf9..000000000000 --- a/drivers/staging/media/lirc/lirc_igorplugusb.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * lirc_igorplugusb - USB remote support for LIRC - * - * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. - * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm - * - * The device can only record bursts of up to 36 pulses/spaces. - * Works fine with RC5. Longer commands lead to device buffer overrun. - * (Maybe a better firmware or a microcontroller with more ram can help?) - * - * Version 0.1 [beta status] - * - * Copyright (C) 2004 Jan M. Hochstein - * - * - * This driver was derived from: - * Paul Miller - * "lirc_atiusb" module - * Vladimir Dergachev 's 2002 - * "USB ATI Remote support" (input device) - * Adrian Dewhurst 's 2002 - * "USB StreamZap remote driver" (LIRC) - * Artur Lipowski 's 2002 - * "lirc_dev" and "lirc_gpio" LIRC modules - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -/* module identification */ -#define DRIVER_VERSION "0.2" -#define DRIVER_AUTHOR \ - "Jan M. Hochstein " -#define DRIVER_DESC "Igorplug USB remote driver for LIRC" -#define DRIVER_NAME "lirc_igorplugusb" - -/* One mode2 pulse/space has 4 bytes. */ -#define CODE_LENGTH sizeof(int) - -/* Igor's firmware cannot record bursts longer than 36. */ -#define DEVICE_BUFLEN 36 - -/* - * Header at the beginning of the device's buffer: - * unsigned char data_length - * unsigned char data_start (!=0 means ring-buffer overrun) - * unsigned char counter (incremented by each burst) - */ -#define DEVICE_HEADERLEN 3 - -/* This is for the gap */ -#define ADDITIONAL_LIRC_BYTES 2 - -/* times to poll per second */ -#define SAMPLE_RATE 100 -static int sample_rate = SAMPLE_RATE; - - -/**** Igor's USB Request Codes */ - -#define SET_INFRABUFFER_EMPTY 1 -/** - * Params: none - * Answer: empty - */ - -#define GET_INFRACODE 2 -/** - * Params: - * wValue: offset to begin reading infra buffer - * - * Answer: infra data - */ - -#define SET_DATAPORT_DIRECTION 3 -/** - * Params: - * wValue: (byte) 1 bit for each data port pin (0=in, 1=out) - * - * Answer: empty - */ - -#define GET_DATAPORT_DIRECTION 4 -/** - * Params: none - * - * Answer: (byte) 1 bit for each data port pin (0=in, 1=out) - */ - -#define SET_OUT_DATAPORT 5 -/** - * Params: - * wValue: byte to write to output data port - * - * Answer: empty - */ - -#define GET_OUT_DATAPORT 6 -/** - * Params: none - * - * Answer: least significant 3 bits read from output data port - */ - -#define GET_IN_DATAPORT 7 -/** - * Params: none - * - * Answer: least significant 3 bits read from input data port - */ - -#define READ_EEPROM 8 -/** - * Params: - * wValue: offset to begin reading EEPROM - * - * Answer: EEPROM bytes - */ - -#define WRITE_EEPROM 9 -/** - * Params: - * wValue: offset to EEPROM byte - * wIndex: byte to write - * - * Answer: empty - */ - -#define SEND_RS232 10 -/** - * Params: - * wValue: byte to send - * - * Answer: empty - */ - -#define RECV_RS232 11 -/** - * Params: none - * - * Answer: byte received - */ - -#define SET_RS232_BAUD 12 -/** - * Params: - * wValue: byte to write to UART bit rate register (UBRR) - * - * Answer: empty - */ - -#define GET_RS232_BAUD 13 -/** - * Params: none - * - * Answer: byte read from UART bit rate register (UBRR) - */ - - -/* data structure for each usb remote */ -struct igorplug { - - /* usb */ - struct usb_device *usbdev; - int devnum; - - unsigned char *buf_in; - unsigned int len_in; - int in_space; - struct timeval last_time; - - dma_addr_t dma_in; - - /* lirc */ - struct lirc_driver *d; - - /* handle sending (init strings) */ - int send_flags; -}; - -static int unregister_from_lirc(struct igorplug *ir) -{ - struct lirc_driver *d; - int devnum; - - devnum = ir->devnum; - d = ir->d; - - if (!d) { - dev_err(&ir->usbdev->dev, - "%s: called with NULL lirc driver struct!\n", __func__); - return -EINVAL; - } - - dev_dbg(&ir->usbdev->dev, "calling lirc_unregister_driver\n"); - lirc_unregister_driver(d->minor); - - return devnum; -} - -static int set_use_inc(void *data) -{ - struct igorplug *ir = data; - - if (!ir) { - printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); - return -EIO; - } - - dev_dbg(&ir->usbdev->dev, "set use inc\n"); - - if (!ir->usbdev) - return -ENODEV; - - return 0; -} - -static void set_use_dec(void *data) -{ - struct igorplug *ir = data; - - if (!ir) { - printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); - return; - } - - dev_dbg(&ir->usbdev->dev, "set use dec\n"); -} - -static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf, - int i, int max) -{ - int code; - - /* MODE2: pulse/space (PULSE_BIT) in 1us units */ - while (i < max) { - /* 1 Igor-tick = 85.333333 us */ - code = (unsigned int)ir->buf_in[i] * 85 + - (unsigned int)ir->buf_in[i] / 3; - ir->last_time.tv_usec += code; - if (ir->in_space) - code |= PULSE_BIT; - lirc_buffer_write(buf, (unsigned char *)&code); - /* 1 chunk = CODE_LENGTH bytes */ - ir->in_space ^= 1; - ++i; - } -} - -/** - * Called in user context. - * return 0 if data was added to the buffer and - * -ENODATA if none was available. This should add some number of bits - * evenly divisible by code_length to the buffer - */ -static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) -{ - int ret; - struct igorplug *ir = (struct igorplug *)data; - - if (!ir || !ir->usbdev) /* Has the device been removed? */ - return -ENODEV; - - memset(ir->buf_in, 0, ir->len_in); - - ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), - GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN, - 0/* offset */, /*unused*/0, - ir->buf_in, ir->len_in, - /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); - if (ret > 0) { - int code, timediff; - struct timeval now; - - /* ACK packet has 1 byte --> ignore */ - if (ret < DEVICE_HEADERLEN) - return -ENODATA; - - dev_dbg(&ir->usbdev->dev, "Got %d bytes. Header: %*ph\n", - ret, 3, ir->buf_in); - - do_gettimeofday(&now); - timediff = now.tv_sec - ir->last_time.tv_sec; - if (timediff + 1 > PULSE_MASK / 1000000) - timediff = PULSE_MASK; - else { - timediff *= 1000000; - timediff += now.tv_usec - ir->last_time.tv_usec; - } - ir->last_time.tv_sec = now.tv_sec; - ir->last_time.tv_usec = now.tv_usec; - - /* create leading gap */ - code = timediff; - lirc_buffer_write(buf, (unsigned char *)&code); - ir->in_space = 1; /* next comes a pulse */ - - if (ir->buf_in[2] == 0) - send_fragment(ir, buf, DEVICE_HEADERLEN, ret); - else { - dev_warn(&ir->usbdev->dev, - "[%d]: Device buffer overrun.\n", ir->devnum); - /* HHHNNNNNNNNNNNOOOOOOOO H = header - <---[2]---> N = newer - <---------ret--------> O = older */ - ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */ - /* keep even-ness to not desync pulse/pause */ - send_fragment(ir, buf, DEVICE_HEADERLEN + - ir->buf_in[2] - (ir->buf_in[2] & 1), ret); - send_fragment(ir, buf, DEVICE_HEADERLEN, - DEVICE_HEADERLEN + ir->buf_in[2]); - } - - ret = usb_control_msg( - ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), - SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, - /*unused*/0, /*unused*/0, - /*dummy*/ir->buf_in, /*dummy*/ir->len_in, - /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); - if (ret < 0) - printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", - ir->devnum, ret); - return 0; - } else if (ret < 0) - printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", - ir->devnum, ret); - - return -ENODATA; -} - -static int igorplugusb_remote_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *dev; - struct usb_host_interface *idesc = NULL; - struct usb_endpoint_descriptor *ep; - struct igorplug *ir = NULL; - struct lirc_driver *driver = NULL; - int devnum, pipe, maxp; - char buf[63], name[128] = ""; - int ret; - - dev_dbg(&intf->dev, "%s: usb probe called.\n", __func__); - - dev = interface_to_usbdev(intf); - - idesc = intf->cur_altsetting; - - if (idesc->desc.bNumEndpoints != 1) - return -ENODEV; - - ep = &idesc->endpoint->desc; - if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - != USB_DIR_IN) - || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - != USB_ENDPOINT_XFER_CONTROL) - return -ENODEV; - - pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress); - devnum = dev->devnum; - maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - - dev_dbg(&intf->dev, "%s: bytes_in_key=%zu maxp=%d\n", - __func__, CODE_LENGTH, maxp); - - ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL); - if (!ir) - return -ENOMEM; - - driver = devm_kzalloc(&intf->dev, sizeof(*driver), GFP_KERNEL); - if (!driver) - return -ENOMEM; - - ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, - GFP_ATOMIC, &ir->dma_in); - if (!ir->buf_in) - return -ENOMEM; - - strcpy(driver->name, DRIVER_NAME " "); - driver->minor = -1; - driver->code_length = CODE_LENGTH * 8; /* in bits */ - driver->features = LIRC_CAN_REC_MODE2; - driver->data = ir; - driver->chunk_size = CODE_LENGTH; - driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES; - driver->set_use_inc = &set_use_inc; - driver->set_use_dec = &set_use_dec; - driver->sample_rate = sample_rate; /* per second */ - driver->add_to_buf = &igorplugusb_remote_poll; - driver->dev = &intf->dev; - driver->owner = THIS_MODULE; - - ret = lirc_register_driver(driver); - if (ret < 0) { - usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, - ir->buf_in, ir->dma_in); - return ret; - } - - driver->minor = ret; - ir->d = driver; - ir->devnum = devnum; - ir->usbdev = dev; - ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN; - ir->in_space = 1; /* First mode2 event is a space. */ - do_gettimeofday(&ir->last_time); - - if (dev->descriptor.iManufacturer - && usb_string(dev, dev->descriptor.iManufacturer, - buf, sizeof(buf)) > 0) - strlcpy(name, buf, sizeof(name)); - if (dev->descriptor.iProduct - && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) - snprintf(name + strlen(name), sizeof(name) - strlen(name), - " %s", buf); - printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, - dev->bus->busnum, devnum); - - /* clear device buffer */ - ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), - SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, - /*unused*/0, /*unused*/0, - /*dummy*/ir->buf_in, /*dummy*/ir->len_in, - /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); - if (ret < 0) - printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", - devnum, ret); - - usb_set_intfdata(intf, ir); - return 0; -} - -static void igorplugusb_remote_disconnect(struct usb_interface *intf) -{ - struct usb_device *usbdev = interface_to_usbdev(intf); - struct igorplug *ir = usb_get_intfdata(intf); - struct device *dev = &intf->dev; - int devnum; - - usb_set_intfdata(intf, NULL); - - if (!ir || !ir->d) - return; - - ir->usbdev = NULL; - - usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in); - - devnum = unregister_from_lirc(ir); - - dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__); -} - -static struct usb_device_id igorplugusb_remote_id_table[] = { - /* Igor Plug USB (Atmel's Manufact. ID) */ - { USB_DEVICE(0x03eb, 0x0002) }, - /* Fit PC2 Infrared Adapter */ - { USB_DEVICE(0x03eb, 0x21fe) }, - - /* Terminating entry */ - { } -}; - -static struct usb_driver igorplugusb_remote_driver = { - .name = DRIVER_NAME, - .probe = igorplugusb_remote_probe, - .disconnect = igorplugusb_remote_disconnect, - .id_table = igorplugusb_remote_id_table -}; - -module_usb_driver(igorplugusb_remote_driver); - -#include -MODULE_INFO(vermagic, VERMAGIC_STRING); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table); - -module_param(sample_rate, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); -- GitLab From 52e269b133d167a345758cb9d76d6348b3c66ebb Mon Sep 17 00:00:00 2001 From: Richard Vollkommer Date: Sat, 25 Oct 2014 17:17:22 -0300 Subject: [PATCH 2527/9457] [media] xc5000: add IF output level control Adds control of the IF output level to the xc5000 tuner configuration structure. Increases the IF level to the demodulator to fix failure to lock and picture breakup issues (with the au8522 demodulator, in the case of the Hauppauge HVR950Q). This patch works with all XC5000 firmware versions. Signed-off-by: Richard Vollkommer Signed-off-by: Michael Ira Krufky Reviewed-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/xc5000.c | 14 +++++++++++++- drivers/media/tuners/xc5000.h | 1 + drivers/media/usb/au0828/au0828-dvb.c | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 803a0e63d47e..705c258d1101 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -62,6 +62,7 @@ struct xc5000_priv { unsigned int mode; u8 rf_mode; u8 radio_input; + u16 output_amp; int chip_id; u16 pll_register_no; @@ -744,7 +745,9 @@ static int xc5000_tune_digital(struct dvb_frontend *fe) return -EIO; } - xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a); + dprintk(1, "%s() setting OUTPUT_AMP to 0x%x\n", + __func__, priv->output_amp); + xc_write_reg(priv, XREG_OUTPUT_AMP, priv->output_amp); xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); @@ -1358,6 +1361,9 @@ static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg) if (p->radio_input) priv->radio_input = p->radio_input; + if (p->output_amp) + priv->output_amp = p->output_amp; + return 0; } @@ -1438,6 +1444,12 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, it can be overridden if this is a hybrid driver */ priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0; + /* don't override output_amp if it's already been set + unless explicitly specified */ + if ((priv->output_amp == 0) || (cfg->output_amp)) + /* use default output_amp value if none specified */ + priv->output_amp = (cfg->output_amp) ? cfg->output_amp : 0x8a; + /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. */ diff --git a/drivers/media/tuners/xc5000.h b/drivers/media/tuners/xc5000.h index 7245cae19f0c..6aa534f17a30 100644 --- a/drivers/media/tuners/xc5000.h +++ b/drivers/media/tuners/xc5000.h @@ -36,6 +36,7 @@ struct xc5000_config { u32 if_khz; u8 radio_input; u16 xtal_khz; + u16 output_amp; int chip_id; }; diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index 00ab1563d142..c267d76f5b3c 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -88,12 +88,14 @@ static struct xc5000_config hauppauge_xc5000a_config = { .i2c_address = 0x61, .if_khz = 6000, .chip_id = XC5000A, + .output_amp = 0x8f, }; static struct xc5000_config hauppauge_xc5000c_config = { .i2c_address = 0x61, .if_khz = 6000, .chip_id = XC5000C, + .output_amp = 0x8f, }; static struct mxl5007t_config mxl5007t_hvr950q_config = { -- GitLab From dcc33cc57d4ad095df694a102c54b8342b814582 Mon Sep 17 00:00:00 2001 From: Richard Vollkommer Date: Sat, 25 Oct 2014 17:17:23 -0300 Subject: [PATCH 2528/9457] [media] au8522: improve lock performance with ZeeVee modulators Improves lock performance with signals from the ZeeVee family of modulators. Signed-off-by: Richard Vollkommer Cc: Devin Heitmueller Signed-off-by: Michael Ira Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/au8522_dig.c | 117 +++++++++++++++++++++-- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index a68974f6d708..5d06c99b0e97 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -29,6 +29,7 @@ #include "au8522_priv.h" static int debug; +static int zv_mode = 1; /* default to on */ #define dprintk(arg...)\ do { if (debug)\ @@ -469,6 +470,87 @@ static struct { { 0x8526, 0x01 }, }; +static struct { + u16 reg; + u16 data; +} QAM256_mod_tab_zv_mode[] = { + { 0x80a3, 0x09 }, + { 0x80a4, 0x00 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80b5, 0xfb }, + { 0x80b6, 0x8e }, + { 0x80b7, 0x39 }, + { 0x80aa, 0x77 }, + { 0x80ad, 0x77 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80b8, 0x3e }, + { 0x80b9, 0xf0 }, + { 0x80ba, 0x01 }, + { 0x80bb, 0x18 }, + { 0x80bc, 0x50 }, + { 0x80bd, 0x00 }, + { 0x80be, 0xea }, + { 0x80bf, 0xef }, + { 0x80c0, 0xfc }, + { 0x80c1, 0xbd }, + { 0x80c2, 0x1f }, + { 0x80c3, 0xfc }, + { 0x80c4, 0xdd }, + { 0x80c5, 0xaf }, + { 0x80c6, 0x00 }, + { 0x80c7, 0x38 }, + { 0x80c8, 0x30 }, + { 0x80c9, 0x05 }, + { 0x80ca, 0x4a }, + { 0x80cb, 0xd0 }, + { 0x80cc, 0x01 }, + { 0x80cd, 0xd9 }, + { 0x80ce, 0x6f }, + { 0x80cf, 0xf9 }, + { 0x80d0, 0x70 }, + { 0x80d1, 0xdf }, + { 0x80d2, 0xf7 }, + { 0x80d3, 0xc2 }, + { 0x80d4, 0xdf }, + { 0x80d5, 0x02 }, + { 0x80d6, 0x9a }, + { 0x80d7, 0xd0 }, + { 0x8250, 0x0d }, + { 0x8251, 0xcd }, + { 0x8252, 0xe0 }, + { 0x8253, 0x05 }, + { 0x8254, 0xa7 }, + { 0x8255, 0xff }, + { 0x8256, 0xed }, + { 0x8257, 0x5b }, + { 0x8258, 0xae }, + { 0x8259, 0xe6 }, + { 0x825a, 0x3d }, + { 0x825b, 0x0f }, + { 0x825c, 0x0d }, + { 0x825d, 0xea }, + { 0x825e, 0xf2 }, + { 0x825f, 0x51 }, + { 0x8260, 0xf5 }, + { 0x8261, 0x06 }, + { 0x821a, 0x01 }, + { 0x8546, 0x40 }, + { 0x8210, 0x26 }, + { 0x8211, 0xf6 }, + { 0x8212, 0x84 }, + { 0x8213, 0x02 }, + { 0x8502, 0x01 }, + { 0x8121, 0x04 }, + { 0x8122, 0x04 }, + { 0x852e, 0x10 }, + { 0x80a4, 0xca }, + { 0x80a7, 0x40 }, + { 0x8526, 0x01 }, +}; + static int au8522_enable_modulation(struct dvb_frontend *fe, fe_modulation_t m) { @@ -495,12 +577,23 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_set_if(fe, state->config->qam_if); break; case QAM_256: - dprintk("%s() QAM 256\n", __func__); - for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++) - au8522_writereg(state, - QAM256_mod_tab[i].reg, - QAM256_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); + if (zv_mode) { + dprintk("%s() QAM 256 (zv_mode)\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab_zv_mode); i++) + au8522_writereg(state, + QAM256_mod_tab_zv_mode[i].reg, + QAM256_mod_tab_zv_mode[i].data); + au8522_set_if(fe, state->config->qam_if); + msleep(100); + au8522_writereg(state, 0x821a, 0x00); + } else { + dprintk("%s() QAM 256\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++) + au8522_writereg(state, + QAM256_mod_tab[i].reg, + QAM256_mod_tab[i].data); + au8522_set_if(fe, state->config->qam_if); + } break; default: dprintk("%s() Invalid modulation\n", __func__); @@ -537,7 +630,12 @@ static int au8522_set_frontend(struct dvb_frontend *fe) return ret; /* Allow the tuner to settle */ - msleep(100); + if (zv_mode) { + dprintk("%s() increase tuner settling time for zv_mode\n", + __func__); + msleep(250); + } else + msleep(100); au8522_enable_modulation(fe, c->modulation); @@ -823,6 +921,11 @@ static struct dvb_frontend_ops au8522_ops = { module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Enable verbose debug messages"); +module_param(zv_mode, int, 0644); +MODULE_PARM_DESC(zv_mode, "Turn on/off ZeeVee modulator compatability mode (default:on).\n" + "\t\ton - modified AU8522 QAM256 initialization.\n" + "\t\tProvides faster lock when using ZeeVee modulator based sources"); + MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); -- GitLab From e5f3d00c243177f4d7a0e86d17b7eaefd4a0c908 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 26 Oct 2014 04:56:12 -0300 Subject: [PATCH 2529/9457] [media] cxusb: TS mode setting for TT CT2-4400 There is a new version of the TechnoTrend CT2-4400 USB tuner. The difference is the demodulator that is used (Si2168-B40 instead of -A30). For TT CT2-4400v2 a TS stream related parameter needs to be set, otherwise the stream becomes corrupted. The Windows driver for both CT2-4400 and CT2-4400v2 sets this as well. After this patch the driver works for both versions. Signed-off-by: Olli Salonen Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cxusb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 356abb369c20..8925b3946994 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1438,6 +1438,12 @@ static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) si2168_config.i2c_adapter = &adapter; si2168_config.fe = &adap->fe_adap[0].fe; si2168_config.ts_mode = SI2168_TS_PARALLEL; + + /* CT2-4400v2 TS gets corrupted without this */ + if (d->udev->descriptor.idProduct == + USB_PID_TECHNOTREND_TVSTICK_CT2_4400) + si2168_config.ts_mode |= 0x40; + memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2168", I2C_NAME_SIZE); info.addr = 0x64; -- GitLab From f491dbe049cc7d8fb4c1cdc7d9fdfac0d1d99869 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 27 Oct 2014 02:25:00 -0300 Subject: [PATCH 2530/9457] [media] dvb-net: Fix probable mask then right shift defects Precedence of & and >> is not the same and is not left to right. shift has higher precedence and should be done after the mask. Add parentheses around the mask. Signed-off-by: Joe Perches Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 059e6117f22b..441814b94eb8 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -379,7 +379,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */ if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) { printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", - priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6); + priv->ts_count, ts[0], + (ts[1] & TS_TEI) >> 7, + (ts[3] & 0xC0) >> 6); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { -- GitLab From fab9d30b7b4216affd1708f0bcf93c746cc428bd Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 28 Oct 2014 20:35:04 -0300 Subject: [PATCH 2531/9457] [media] media: Print information on failed link validation The Media controller doesn't tell much to the user in cases such as pipeline startup failure. The link validation is the most common media graph (or in V4L2's case, format) related reason for the failure. In more complex pipelines the reason may not always be obvious to the user, so point them to look at the right direction. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 37c334edc7e8..4122d7f42e10 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -279,8 +279,14 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, continue; ret = entity->ops->link_validate(link); - if (ret < 0 && ret != -ENOIOCTLCMD) + if (ret < 0 && ret != -ENOIOCTLCMD) { + dev_dbg(entity->parent->dev, + "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n", + entity->name, link->source->index, + link->sink->entity->name, + link->sink->index, ret); goto error; + } } /* Either no links or validated links are fine. */ @@ -288,6 +294,10 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, if (!bitmap_full(active, entity->num_pads)) { ret = -EPIPE; + dev_dbg(entity->parent->dev, + "\"%s\":%u must be connected by an enabled link\n", + entity->name, + find_first_zero_bit(active, entity->num_pads)); goto error; } } -- GitLab From 373145282ea61c2a01980914ee5bbff7cf62afd6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 12:47:41 -0300 Subject: [PATCH 2532/9457] [media] media: dvb_core: replace a magic number by a macro It's better to use TS_SC instead of magic number 0xC0. [m.chehab@samsung.com: patch rebased and message rewritten, as this patch conflicted with an already applied patch] Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 441814b94eb8..e4041f074909 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -381,7 +381,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", priv->ts_count, ts[0], (ts[1] & TS_TEI) >> 7, - (ts[3] & 0xC0) >> 6); + (ts[3] & TS_SC) >> 6); /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { -- GitLab From 77d381af73e905c48b992d5d8426376469bc9576 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 28 Oct 2014 18:51:01 -0300 Subject: [PATCH 2533/9457] [media] lirc: use kfifo_initialized() on lirc_buffer's fifo We can use kfifo_initialized() to check if the fifo in lirc_buffer is initialized or not. There's no need to have a dedicated fifo status variable in lirc_buffer. [m.chehab@samsung.com: add the same change to lirc_zilog, to avoid breaking compilation of staging drivers] Signed-off-by: Martin Kaiser Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_zilog.c | 2 +- include/media/lirc_dev.h | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 567feba0011c..1ccf6262ab36 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -199,7 +199,7 @@ static void release_ir_device(struct kref *ref) lirc_unregister_driver(ir->l.minor); ir->l.minor = MAX_IRCTL_DEVICES; } - if (ir->rbuf.fifo_initialized) + if (kfifo_initialized(&ir->rbuf.fifo)) lirc_buffer_free(&ir->rbuf); list_del(&ir->list); kfree(ir); diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index 78f0637ca68d..05e7ad5d2c8b 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h @@ -29,14 +29,13 @@ struct lirc_buffer { /* Using chunks instead of bytes pretends to simplify boundary checking * And should allow for some performance fine tunning later */ struct kfifo fifo; - u8 fifo_initialized; }; static inline void lirc_buffer_clear(struct lirc_buffer *buf) { unsigned long flags; - if (buf->fifo_initialized) { + if (kfifo_initialized(&buf->fifo)) { spin_lock_irqsave(&buf->fifo_lock, flags); kfifo_reset(&buf->fifo); spin_unlock_irqrestore(&buf->fifo_lock, flags); @@ -56,17 +55,14 @@ static inline int lirc_buffer_init(struct lirc_buffer *buf, buf->chunk_size = chunk_size; buf->size = size; ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); - if (ret == 0) - buf->fifo_initialized = 1; return ret; } static inline void lirc_buffer_free(struct lirc_buffer *buf) { - if (buf->fifo_initialized) { + if (kfifo_initialized(&buf->fifo)) { kfifo_free(&buf->fifo); - buf->fifo_initialized = 0; } else WARN(1, "calling %s on an uninitialized lirc_buffer\n", __func__); -- GitLab From fa0ea13e9f1c2b4707879ca3dbe4cf29c741857a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 19 Sep 2014 15:51:11 -0500 Subject: [PATCH 2534/9457] usb: dwc3: core: write LINUX_VERSION_CODE to our GUID register DWC3's GUID register is supposed to be used to write any sort of version we might want. It helps when getting bug reports for platforms you don't have HW to know which kernel version of the driver was running on the platform. Because we don't really track driver version, but we _do_ track the kernel version, let's write LINUX_VERSION_CODE to that register and use it for debugging. Reviewed-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b0f4d52b7f04..ddfe7718e4a3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -19,6 +19,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -384,6 +385,12 @@ static int dwc3_core_init(struct dwc3 *dwc) } dwc->revision = reg; + /* + * Write Linux Version Code to our GUID register so it's easy to figure + * out which kernel version a bug was found. + */ + dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); + /* Handle USB2.0-only core configuration */ if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { -- GitLab From dab716cd9aeea6f2b2524523461326aefa219291 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 24 Sep 2014 11:22:23 -0500 Subject: [PATCH 2535/9457] usb: dwc3: trace: remove unnecessary newline character tracing infrastructure already adds those for us. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 18 +++++++++--------- drivers/usb/dwc3/trace.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 711b23019d54..df964d8f3bf0 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -700,35 +700,35 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) switch (ctrl->bRequest) { case USB_REQ_GET_STATUS: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS"); ret = dwc3_ep0_handle_status(dwc, ctrl); break; case USB_REQ_CLEAR_FEATURE: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE"); ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); break; case USB_REQ_SET_FEATURE: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE"); ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); break; case USB_REQ_SET_ADDRESS: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS"); ret = dwc3_ep0_set_address(dwc, ctrl); break; case USB_REQ_SET_CONFIGURATION: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION"); ret = dwc3_ep0_set_config(dwc, ctrl); break; case USB_REQ_SET_SEL: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL"); ret = dwc3_ep0_set_sel(dwc, ctrl); break; case USB_REQ_SET_ISOCH_DELAY: - dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY\n"); + dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY"); ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); break; default: - dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver\n"); + dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver"); ret = dwc3_ep0_delegate_req(dwc, ctrl); break; } @@ -875,7 +875,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, status = DWC3_TRB_SIZE_TRBSTS(trb->size); if (status == DWC3_TRBSTS_SETUP_PENDING) - dwc3_trace(trace_dwc3_ep0, "Setup Pending received\n"); + dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_out_start(dwc); diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 60b0f41eafc4..7a9d7804193c 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -61,7 +61,7 @@ DECLARE_EVENT_CLASS(dwc3_log_event, TP_fast_assign( __entry->event = event; ), - TP_printk("event %08x\n", __entry->event) + TP_printk("event %08x", __entry->event) ); DEFINE_EVENT(dwc3_log_event, dwc3_event, @@ -157,7 +157,7 @@ DECLARE_EVENT_CLASS(dwc3_log_generic_cmd, __entry->cmd = cmd; __entry->param = param; ), - TP_printk("cmd '%s' [%d] param %08x\n", + TP_printk("cmd '%s' [%d] param %08x", dwc3_gadget_generic_cmd_string(__entry->cmd), __entry->cmd, __entry->param ) @@ -182,7 +182,7 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, __entry->cmd = cmd; __entry->params = params; ), - TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x\n", + TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x", __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), __entry->cmd, __entry->params->param0, __entry->params->param1, __entry->params->param2 @@ -214,7 +214,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __entry->size = trb->size; __entry->ctrl = trb->ctrl; ), - TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x\n", + TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x", __get_str(name), __entry->trb, __entry->bph, __entry->bpl, __entry->size, __entry->ctrl ) -- GitLab From 19bacdc925055f020ad36da04bd72dc8b28637b8 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 24 Sep 2014 11:00:38 +0300 Subject: [PATCH 2536/9457] usb: dwc3: core: only setting the dma_mask when needed If the probe drivers have already set the dma_mask, not replacing the value. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ddfe7718e4a3..13843004815c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -715,9 +715,11 @@ static int dwc3_probe(struct platform_device *pdev) spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); - dev->dma_mask = dev->parent->dma_mask; - dev->dma_parms = dev->parent->dma_parms; - dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); + if (!dev->dma_mask) { + dev->dma_mask = dev->parent->dma_mask; + dev->dma_parms = dev->parent->dma_parms; + dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); + } pm_runtime_enable(dev); pm_runtime_get_sync(dev); -- GitLab From 404905a604d8565b62a2889c5045acf57aa434be Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 25 Sep 2014 10:57:02 +0300 Subject: [PATCH 2537/9457] usb: dwc3: add ACPI support Adding ACPI ID used on newer Intel SoCs. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 13843004815c..4d4e854f99aa 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -967,12 +968,24 @@ static const struct of_device_id of_dwc3_match[] = { MODULE_DEVICE_TABLE(of, of_dwc3_match); #endif +#ifdef CONFIG_ACPI + +#define ACPI_ID_INTEL_BSW "808622B7" + +static const struct acpi_device_id dwc3_acpi_match[] = { + { ACPI_ID_INTEL_BSW, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match); +#endif + static struct platform_driver dwc3_driver = { .probe = dwc3_probe, .remove = dwc3_remove, .driver = { .name = "dwc3", .of_match_table = of_match_ptr(of_dwc3_match), + .acpi_match_table = ACPI_PTR(dwc3_acpi_match), .pm = DWC3_PM_OPS, }, }; -- GitLab From 6c93b5342374b3ff2a8beac050ed6e07373cbe95 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 18 Sep 2014 09:51:23 -0500 Subject: [PATCH 2538/9457] usb: gadget: composite: introduce setup and os_desc pending flags These flags we be set to true whenever their matching request is queued. They will be cleared to false when that request completes. Signed-off-by: Felipe Balbi --- include/linux/usb/composite.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index c330f5ef42cf..ed3811c09ec1 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -427,6 +427,8 @@ static inline struct usb_composite_driver *to_cdriver( * @b_vendor_code: bMS_VendorCode part of the OS string * @use_os_string: false by default, interested gadgets set it * @os_desc_config: the configuration to be used with OS descriptors + * @setup_pending: true when setup request is queued but not completed + * @os_desc_pending: true when os_desc request is queued but not completed * * One of these devices is allocated and initialized before the * associated device driver's bind() is called. @@ -488,6 +490,9 @@ struct usb_composite_dev { /* protects deactivations and delayed_status counts*/ spinlock_t lock; + + unsigned setup_pending:1; + unsigned os_desc_pending:1; }; extern int usb_string_id(struct usb_composite_dev *c); -- GitLab From 57943716ff1b0733ab0d9879e572bad04166660a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 18 Sep 2014 09:54:54 -0500 Subject: [PATCH 2539/9457] usb: gadget: composite: set our req->context to cdev by doing that we will be able to match our requests against req and os_desc_req and also clear our pending flags from complete callback. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f6a51fddd5b5..09602dc90205 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1428,6 +1428,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * when we delegate to it. */ req->zero = 0; + req->context = cdev; req->complete = composite_setup_complete; req->length = 0; gadget->ep0->driver_data = cdev; @@ -1624,6 +1625,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) int count = 0; req = cdev->os_desc_req; + req->context = cdev; req->complete = composite_setup_complete; buf = req->buf; os_desc_cfg = cdev->os_desc_config; @@ -1686,6 +1688,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; } req->length = value; + req->context = cdev; req->zero = value < w_length; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (value < 0) { @@ -1757,6 +1760,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) /* respond with data transfer before status phase? */ if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { req->length = value; + req->context = cdev; req->zero = value < w_length; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (value < 0) { @@ -1893,6 +1897,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite, goto fail_dev; cdev->req->complete = composite_setup_complete; + cdev->req->context = cdev; gadget->ep0->driver_data = cdev; cdev->driver = composite; @@ -1937,6 +1942,7 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, kfree(cdev->os_desc_req); goto end; } + cdev->os_desc_req->context = cdev; cdev->os_desc_req->complete = composite_setup_complete; end: return ret; @@ -2158,6 +2164,7 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) } else if (--cdev->delayed_status == 0) { DBG(cdev, "%s: Completing delayed status\n", __func__); req->length = 0; + req->context = cdev; value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG(cdev, "ep_queue --> %d\n", value); -- GitLab From a7c12eaf2e5eea0c15242ebb7d1d3b6e7fcb62bb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 18 Sep 2014 10:01:55 -0500 Subject: [PATCH 2540/9457] usb: gadget: composite: conditionally dequeue os_desc and setup requests In case we unload a gadget driver while any of os_desc_req or req are still pending, we need to make sure to dequeue them. By using our setup_pending and os_desc_pending flags we achieve that in a way that doesn't cause any regressions because we won't dequeue a request which was already completed. The original idea came from Li Jun's commit f2267089ea17fa97b796b1b4247e3f8957655df3 (usb: gadget: composite: dequeue cdev->req before free it in composite_dev_cleanup) which, unfortunately, caused two regressions (kfree() being called before usb_ep_dequeue() and calling usb_ep_dequeue() when the request was already completed). That commit also didn't take care of os_desc_req which can fall into the same situation so we must care for that one too. Note that in order to make code slightly easier to read, we introduce composite_ep_queue() which hides details about how to fiddle with our pending flags. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 09602dc90205..e071d580346e 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1246,10 +1246,49 @@ EXPORT_SYMBOL_GPL(usb_string_ids_n); static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) { + struct usb_composite_dev *cdev; + if (req->status || req->actual != req->length) DBG((struct usb_composite_dev *) ep->driver_data, "setup complete --> %d, %d/%d\n", req->status, req->actual, req->length); + + /* + * REVIST The same ep0 requests are shared with function drivers + * so they don't have to maintain the same ->complete() stubs. + * + * Because of that, we need to check for the validity of ->context + * here, even though we know we've set it to something useful. + */ + if (!req->context) + return; + + cdev = req->context; + + if (cdev->req == req) + cdev->setup_pending = false; + else if (cdev->os_desc_req == req) + cdev->os_desc_pending = false; + else + WARN(1, "unknown request %p\n", req); +} + +static int composite_ep0_queue(struct usb_composite_dev *cdev, + struct usb_request *req, gfp_t gfp_flags) +{ + int ret; + + ret = usb_ep_queue(cdev->gadget->ep0, req, gfp_flags); + if (ret == 0) { + if (cdev->req == req) + cdev->setup_pending = true; + else if (cdev->os_desc_req == req) + cdev->os_desc_pending = true; + else + WARN(1, "unknown request %p\n", req); + } + + return ret; } static int count_ext_compat(struct usb_configuration *c) @@ -1690,7 +1729,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->length = value; req->context = cdev; req->zero = value < w_length; - value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + value = composite_ep0_queue(cdev, req, GFP_ATOMIC); if (value < 0) { DBG(cdev, "ep_queue --> %d\n", value); req->status = 0; @@ -1762,7 +1801,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->length = value; req->context = cdev; req->zero = value < w_length; - value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + value = composite_ep0_queue(cdev, req, GFP_ATOMIC); if (value < 0) { DBG(cdev, "ep_queue --> %d\n", value); req->status = 0; @@ -1957,10 +1996,16 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) kfree(uc); } if (cdev->os_desc_req) { + if (cdev->os_desc_pending) + usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req); + kfree(cdev->os_desc_req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); } if (cdev->req) { + if (cdev->setup_pending) + usb_ep_dequeue(cdev->gadget->ep0, cdev->req); + kfree(cdev->req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->req); } @@ -2165,7 +2210,7 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) DBG(cdev, "%s: Completing delayed status\n", __func__); req->length = 0; req->context = cdev; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + value = composite_ep0_queue(cdev, req, GFP_ATOMIC); if (value < 0) { DBG(cdev, "ep_queue --> %d\n", value); req->status = 0; -- GitLab From ccb072de5702a50270172e8613db186d136fce16 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 1 Oct 2014 12:20:29 -0500 Subject: [PATCH 2541/9457] usb: dwc3: ep0: trace ep0 TRBs too Add TRB tracepoints for ep0 TRBs as that might help finding bugs with ep0 handling. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index df964d8f3bf0..4c86772126ed 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -86,6 +86,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); + trace_dwc3_prepare_trb(dep, trb); + ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) { @@ -791,6 +793,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, trb = dwc->ep0_trb; + trace_dwc3_complete_trb(ep0, trb); + status = DWC3_TRB_SIZE_TRBSTS(trb->size); if (status == DWC3_TRBSTS_SETUP_PENDING) { dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); @@ -855,6 +859,8 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, dep = dwc->eps[0]; trb = dwc->ep0_trb; + trace_dwc3_complete_trb(dep, trb); + if (!list_empty(&dep->request_list)) { r = next_request(&dep->request_list); -- GitLab From c042b85a2cbb0c612e9ed3c7ea1af684bba5dcd3 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 7 Oct 2014 12:43:04 +0900 Subject: [PATCH 2542/9457] usb: renesas_usbhs: rename phy to usb_phy in usbhs_priv To support a generic phy driver in this driver later, this patch renames "struct usb_phy *phy" to "struct usb_phy *usb_phy". Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.h | 2 +- drivers/usb/renesas_usbhs/rcar2.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index a7996da6a1bd..e0d53c51c260 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -269,7 +269,7 @@ struct usbhs_priv { */ struct usbhs_fifo_info fifo_info; - struct usb_phy *phy; + struct usb_phy *usb_phy; }; /* diff --git a/drivers/usb/renesas_usbhs/rcar2.c b/drivers/usb/renesas_usbhs/rcar2.c index e6b9dcc1c289..f264cadc12cd 100644 --- a/drivers/usb/renesas_usbhs/rcar2.c +++ b/drivers/usb/renesas_usbhs/rcar2.c @@ -20,13 +20,13 @@ static int usbhs_rcar2_hardware_init(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - struct usb_phy *phy; + struct usb_phy *usb_phy; - phy = usb_get_phy_dev(&pdev->dev, 0); - if (IS_ERR(phy)) - return PTR_ERR(phy); + usb_phy = usb_get_phy_dev(&pdev->dev, 0); + if (IS_ERR(usb_phy)) + return PTR_ERR(usb_phy); - priv->phy = phy; + priv->usb_phy = usb_phy; return 0; } @@ -34,11 +34,11 @@ static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - if (!priv->phy) + if (!priv->usb_phy) return 0; - usb_put_phy(priv->phy); - priv->phy = NULL; + usb_put_phy(priv->usb_phy); + priv->usb_phy = NULL; return 0; } @@ -48,19 +48,19 @@ static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - if (!priv->phy) + if (!priv->usb_phy) return -ENODEV; if (enable) { - int retval = usb_phy_init(priv->phy); + int retval = usb_phy_init(priv->usb_phy); if (!retval) - retval = usb_phy_set_suspend(priv->phy, 0); + retval = usb_phy_set_suspend(priv->usb_phy, 0); return retval; } - usb_phy_set_suspend(priv->phy, 1); - usb_phy_shutdown(priv->phy); + usb_phy_set_suspend(priv->usb_phy, 1); + usb_phy_shutdown(priv->usb_phy); return 0; } -- GitLab From 5f6aea3453ccafc0c3e16f9f7db79ce91b377e9a Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 7 Oct 2014 12:43:05 +0900 Subject: [PATCH 2543/9457] usb: renesas_usbhs: clean up rcar2.c to support a generic PHY To support both usb PHY and generic PHY, this patch cleans up rcar2.c. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/rcar2.c | 48 +++++++++++++++++-------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/drivers/usb/renesas_usbhs/rcar2.c b/drivers/usb/renesas_usbhs/rcar2.c index f264cadc12cd..485b88957a2f 100644 --- a/drivers/usb/renesas_usbhs/rcar2.c +++ b/drivers/usb/renesas_usbhs/rcar2.c @@ -20,25 +20,28 @@ static int usbhs_rcar2_hardware_init(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - struct usb_phy *usb_phy; - usb_phy = usb_get_phy_dev(&pdev->dev, 0); - if (IS_ERR(usb_phy)) - return PTR_ERR(usb_phy); + if (IS_ENABLED(CONFIG_USB_PHY)) { + struct usb_phy *usb_phy = usb_get_phy_dev(&pdev->dev, 0); - priv->usb_phy = usb_phy; - return 0; + if (IS_ERR(usb_phy)) + return PTR_ERR(usb_phy); + + priv->usb_phy = usb_phy; + return 0; + } + + return -ENXIO; } static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); - if (!priv->usb_phy) - return 0; - - usb_put_phy(priv->usb_phy); - priv->usb_phy = NULL; + if (priv->usb_phy) { + usb_put_phy(priv->usb_phy); + priv->usb_phy = NULL; + } return 0; } @@ -47,21 +50,22 @@ static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, void __iomem *base, int enable) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); + int retval = -ENODEV; - if (!priv->usb_phy) - return -ENODEV; + if (priv->usb_phy) { + if (enable) { + retval = usb_phy_init(priv->usb_phy); - if (enable) { - int retval = usb_phy_init(priv->usb_phy); - - if (!retval) - retval = usb_phy_set_suspend(priv->usb_phy, 0); - return retval; + if (!retval) + retval = usb_phy_set_suspend(priv->usb_phy, 0); + } else { + usb_phy_set_suspend(priv->usb_phy, 1); + usb_phy_shutdown(priv->usb_phy); + retval = 0; + } } - usb_phy_set_suspend(priv->usb_phy, 1); - usb_phy_shutdown(priv->usb_phy); - return 0; + return retval; } static int usbhs_rcar2_get_id(struct platform_device *pdev) -- GitLab From 420974a0ed2d9da76637c2c2dc9324850e4f9a24 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 7 Oct 2014 12:43:06 +0900 Subject: [PATCH 2544/9457] usb: renesas_usbhs: add support for generic PHY This patch adds support for the generic PHY. The generic PHY will be used in multiplatform environment. Acked-by: Kishon Vijay Abraham I Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/rcar2.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index e0d53c51c260..c45667f942b6 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -270,6 +270,7 @@ struct usbhs_priv { struct usbhs_fifo_info fifo_info; struct usb_phy *usb_phy; + struct phy *phy; }; /* diff --git a/drivers/usb/renesas_usbhs/rcar2.c b/drivers/usb/renesas_usbhs/rcar2.c index 485b88957a2f..8fc15c0ba339 100644 --- a/drivers/usb/renesas_usbhs/rcar2.c +++ b/drivers/usb/renesas_usbhs/rcar2.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include "common.h" @@ -21,6 +22,16 @@ static int usbhs_rcar2_hardware_init(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); + if (IS_ENABLED(CONFIG_GENERIC_PHY)) { + struct phy *phy = phy_get(&pdev->dev, "usb"); + + if (IS_ERR(phy)) + return PTR_ERR(phy); + + priv->phy = phy; + return 0; + } + if (IS_ENABLED(CONFIG_USB_PHY)) { struct usb_phy *usb_phy = usb_get_phy_dev(&pdev->dev, 0); @@ -38,6 +49,11 @@ static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); + if (priv->phy) { + phy_put(priv->phy); + priv->phy = NULL; + } + if (priv->usb_phy) { usb_put_phy(priv->usb_phy); priv->usb_phy = NULL; @@ -52,6 +68,19 @@ static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); int retval = -ENODEV; + if (priv->phy) { + if (enable) { + retval = phy_init(priv->phy); + + if (!retval) + retval = phy_power_on(priv->phy); + } else { + phy_power_off(priv->phy); + phy_exit(priv->phy); + retval = 0; + } + } + if (priv->usb_phy) { if (enable) { retval = usb_phy_init(priv->usb_phy); -- GitLab From 2db88a76960747fb1af3757a81b94451c4bdfc49 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 1 Oct 2014 22:06:14 +0200 Subject: [PATCH 2545/9457] usb: gadget: pxa27x_udc: prepare device-tree support For this preparation, a preliminary cleanup is done : - convert the probing of pxa27x_udc to gpio_desc. The conversion is partial because : - the platform data still provides a gpio number, not a gpio desc Signed-off-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 55 +++++++++++++++-------------- drivers/usb/gadget/udc/pxa27x_udc.h | 2 ++ 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 4868369eeec6..d58319765021 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1507,17 +1508,12 @@ static struct usb_ep_ops pxa_ep_ops = { */ static void dplus_pullup(struct pxa_udc *udc, int on) { - if (on) { - if (gpio_is_valid(udc->mach->gpio_pullup)) - gpio_set_value(udc->mach->gpio_pullup, - !udc->mach->gpio_pullup_inverted); - if (udc->mach->udc_command) + if (udc->gpiod) { + gpiod_set_value(udc->gpiod, on); + } else if (udc->mach && udc->mach->udc_command) { + if (on) udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); - } else { - if (gpio_is_valid(udc->mach->gpio_pullup)) - gpio_set_value(udc->mach->gpio_pullup, - udc->mach->gpio_pullup_inverted); - if (udc->mach->udc_command) + else udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); } udc->pullup_on = on; @@ -1609,7 +1605,7 @@ static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) { struct pxa_udc *udc = to_gadget_udc(_gadget); - if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) + if (!udc->gpiod && !udc->mach->udc_command) return -EOPNOTSUPP; dplus_pullup(udc, is_active); @@ -2416,6 +2412,22 @@ static int pxa_udc_probe(struct platform_device *pdev) struct resource *regs; struct pxa_udc *udc = &memory; int retval = 0, gpio; + struct pxa2xx_udc_mach_info *mach = dev_get_platdata(&pdev->dev); + unsigned long gpio_flags; + + if (mach) { + gpio_flags = mach->gpio_pullup_inverted ? GPIOF_ACTIVE_LOW : 0; + gpio = mach->gpio_pullup; + if (gpio_is_valid(gpio)) { + retval = devm_gpio_request_one(&pdev->dev, gpio, + gpio_flags, + "USB D+ pullup"); + if (retval) + return retval; + udc->gpiod = gpio_to_desc(mach->gpio_pullup); + } + udc->mach = mach; + } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) @@ -2425,21 +2437,15 @@ static int pxa_udc_probe(struct platform_device *pdev) return udc->irq; udc->dev = &pdev->dev; - udc->mach = dev_get_platdata(&pdev->dev); udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); - gpio = udc->mach->gpio_pullup; - if (gpio_is_valid(gpio)) { - retval = gpio_request(gpio, "USB D+ pullup"); - if (retval == 0) - gpio_direction_output(gpio, - udc->mach->gpio_pullup_inverted); - } - if (retval) { - dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", - gpio, retval); - return retval; + if (IS_ERR(udc->gpiod)) { + dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n", + PTR_ERR(udc->gpiod)); + return PTR_ERR(udc->gpiod); } + if (udc->gpiod) + gpiod_direction_output(udc->gpiod, 0); udc->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(udc->clk)) { @@ -2501,14 +2507,11 @@ static int pxa_udc_probe(struct platform_device *pdev) static int pxa_udc_remove(struct platform_device *_dev) { struct pxa_udc *udc = platform_get_drvdata(_dev); - int gpio = udc->mach->gpio_pullup; usb_del_gadget_udc(&udc->gadget); usb_gadget_unregister_driver(udc->driver); free_irq(udc->irq, udc); pxa_cleanup_debugfs(udc); - if (gpio_is_valid(gpio)) - gpio_free(gpio); usb_put_phy(udc->transceiver); diff --git a/drivers/usb/gadget/udc/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index 28f2b53530f5..f02569324ee6 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h @@ -421,6 +421,7 @@ struct udc_stats { * @driver: bound gadget (zero, g_ether, g_mass_storage, ...) * @dev: device * @mach: machine info, used to activate specific GPIO + * @gpiod: gpio descriptor of gpio for D+ pullup (or NULL if none) * @transceiver: external transceiver to handle vbus sense and D+ pullup * @ep0state: control endpoint state machine state * @stats: statistics on udc usage @@ -447,6 +448,7 @@ struct pxa_udc { struct usb_gadget_driver *driver; struct device *dev; struct pxa2xx_udc_mach_info *mach; + struct gpio_desc *gpiod; struct usb_phy *transceiver; enum ep0_state ep0state; -- GitLab From 3ec8347bfa6e671666d04fc62c8302f5ffa344ba Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 1 Oct 2014 22:06:15 +0200 Subject: [PATCH 2546/9457] usb: gadget: pxa27x_udc: transfer mach_info into pxa_udc Convert the mach info, and store the udc_command in the pxa_udc control structure. It is to be noticed that the udc_is_connected() in mach info is not transfered. This was not used, as mioa701 machine doesn't need it, balloon3 doesn't really use it, and most importantly the current driver never uses it. Signed-off-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 10 +++++----- drivers/usb/gadget/udc/pxa27x_udc.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index d58319765021..5280f64683fb 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -1510,11 +1510,11 @@ static void dplus_pullup(struct pxa_udc *udc, int on) { if (udc->gpiod) { gpiod_set_value(udc->gpiod, on); - } else if (udc->mach && udc->mach->udc_command) { + } else if (udc->udc_command) { if (on) - udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); + udc->udc_command(PXA2XX_UDC_CMD_CONNECT); else - udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); + udc->udc_command(PXA2XX_UDC_CMD_DISCONNECT); } udc->pullup_on = on; } @@ -1605,7 +1605,7 @@ static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) { struct pxa_udc *udc = to_gadget_udc(_gadget); - if (!udc->gpiod && !udc->mach->udc_command) + if (!udc->gpiod && !udc->udc_command) return -EOPNOTSUPP; dplus_pullup(udc, is_active); @@ -2426,7 +2426,7 @@ static int pxa_udc_probe(struct platform_device *pdev) return retval; udc->gpiod = gpio_to_desc(mach->gpio_pullup); } - udc->mach = mach; + udc->udc_command = mach->udc_command; } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/gadget/udc/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index f02569324ee6..11e14232794b 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h @@ -420,7 +420,7 @@ struct udc_stats { * @usb_gadget: udc gadget structure * @driver: bound gadget (zero, g_ether, g_mass_storage, ...) * @dev: device - * @mach: machine info, used to activate specific GPIO + * @udc_command: machine specific function to activate D+ pullup * @gpiod: gpio descriptor of gpio for D+ pullup (or NULL if none) * @transceiver: external transceiver to handle vbus sense and D+ pullup * @ep0state: control endpoint state machine state @@ -447,7 +447,7 @@ struct pxa_udc { struct usb_gadget gadget; struct usb_gadget_driver *driver; struct device *dev; - struct pxa2xx_udc_mach_info *mach; + void (*udc_command)(int); struct gpio_desc *gpiod; struct usb_phy *transceiver; -- GitLab From 1803fe15ad54e68aae8b2b44e04a635e9b5d52f2 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 1 Oct 2014 22:06:16 +0200 Subject: [PATCH 2547/9457] usb: gadget: pxa27x_udc: add devicetree support Add support for device-tree device discovery. If devicetree is not provided, fallback to legacy platform data "discovery". Signed-off-by: Robert Jarzmik Cc: devicetree@vger.kernel.org Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 5280f64683fb..55598c0d083c 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -2400,6 +2402,12 @@ static struct pxa_udc memory = { } }; +static struct of_device_id udc_pxa_dt_ids[] = { + { .compatible = "marvell,pxa270-udc" }, + {} +}; +MODULE_DEVICE_TABLE(of, udc_pxa_dt_ids); + /** * pxa_udc_probe - probes the udc device * @_dev: platform device @@ -2427,6 +2435,8 @@ static int pxa_udc_probe(struct platform_device *pdev) udc->gpiod = gpio_to_desc(mach->gpio_pullup); } udc->udc_command = mach->udc_command; + } else { + udc->gpiod = devm_gpiod_get(&pdev->dev, NULL); } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2618,6 +2628,7 @@ static struct platform_driver udc_driver = { .driver = { .name = "pxa27x-udc", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(udc_pxa_dt_ids), }, .probe = pxa_udc_probe, .remove = pxa_udc_remove, -- GitLab From 7ee2566ff53e0620a80548689c74505fe8f10ec8 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Tue, 17 Dec 2013 18:47:54 +0530 Subject: [PATCH 2548/9457] usb: dwc3: dwc3-omap: get rid of ->prepare()/->complete() Enabling the core interrupts in complete is too late for XHCI, and stops it from proper operation. The root of the problem is due to a disagreement between dwc3-omap and XHCI about when IRQs should be enabled. As it turns out, ->resume's documentation states that: "... generally the driver is expected to start working again, responding to hardware events and software requests (the device itself may be left in a low-power state, waiting for a runtime resume to occur) ..." From that we infer that IRQs must be unmasked by the end of ->resume(). Due to that, we will remove ->prepare() and ->complete() and disable/enable interrupts in ->suspend()/->resume(). Acked-by: Roger Quadros Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index a0aa9f3da441..172d64e585b6 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -593,27 +593,12 @@ static const struct of_device_id of_dwc3_match[] = { MODULE_DEVICE_TABLE(of, of_dwc3_match); #ifdef CONFIG_PM_SLEEP -static int dwc3_omap_prepare(struct device *dev) -{ - struct dwc3_omap *omap = dev_get_drvdata(dev); - - dwc3_omap_disable_irqs(omap); - - return 0; -} - -static void dwc3_omap_complete(struct device *dev) -{ - struct dwc3_omap *omap = dev_get_drvdata(dev); - - dwc3_omap_enable_irqs(omap); -} - static int dwc3_omap_suspend(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); omap->utmi_otg_status = dwc3_omap_read_utmi_status(omap); + dwc3_omap_disable_irqs(omap); return 0; } @@ -623,6 +608,7 @@ static int dwc3_omap_resume(struct device *dev) struct dwc3_omap *omap = dev_get_drvdata(dev); dwc3_omap_write_utmi_status(omap, omap->utmi_otg_status); + dwc3_omap_enable_irqs(omap); pm_runtime_disable(dev); pm_runtime_set_active(dev); @@ -632,8 +618,6 @@ static int dwc3_omap_resume(struct device *dev) } static const struct dev_pm_ops dwc3_omap_dev_pm_ops = { - .prepare = dwc3_omap_prepare, - .complete = dwc3_omap_complete, SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume) }; -- GitLab From 0b0231aa246cbfdcf0a07f5e8914c0f1b80002f6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 7 Oct 2014 10:19:23 -0500 Subject: [PATCH 2549/9457] usb: dwc3: get rid of ->prepare()/->complete() Using ->prepare()/->complete() to mask/unmask IRQs is wrong at least for dwc3. We need to make sure that by the end of ->resume(), IRQs are working and ready to fire because a child device may need working IRQs for its own ->resume() method. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 50 ++------------------------------------- drivers/usb/dwc3/core.h | 11 --------- drivers/usb/dwc3/gadget.c | 20 +++++----------- 3 files changed, 8 insertions(+), 73 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 4d4e854f99aa..fa396fc57a85 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -825,50 +825,6 @@ static int dwc3_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int dwc3_prepare(struct device *dev) -{ - struct dwc3 *dwc = dev_get_drvdata(dev); - unsigned long flags; - - spin_lock_irqsave(&dwc->lock, flags); - - switch (dwc->dr_mode) { - case USB_DR_MODE_PERIPHERAL: - case USB_DR_MODE_OTG: - dwc3_gadget_prepare(dwc); - /* FALLTHROUGH */ - case USB_DR_MODE_HOST: - default: - dwc3_event_buffers_cleanup(dwc); - break; - } - - spin_unlock_irqrestore(&dwc->lock, flags); - - return 0; -} - -static void dwc3_complete(struct device *dev) -{ - struct dwc3 *dwc = dev_get_drvdata(dev); - unsigned long flags; - - spin_lock_irqsave(&dwc->lock, flags); - - dwc3_event_buffers_setup(dwc); - switch (dwc->dr_mode) { - case USB_DR_MODE_PERIPHERAL: - case USB_DR_MODE_OTG: - dwc3_gadget_complete(dwc); - /* FALLTHROUGH */ - case USB_DR_MODE_HOST: - default: - break; - } - - spin_unlock_irqrestore(&dwc->lock, flags); -} - static int dwc3_suspend(struct device *dev) { struct dwc3 *dwc = dev_get_drvdata(dev); @@ -883,7 +839,7 @@ static int dwc3_suspend(struct device *dev) /* FALLTHROUGH */ case USB_DR_MODE_HOST: default: - /* do nothing */ + dwc3_event_buffers_cleanup(dwc); break; } @@ -916,6 +872,7 @@ static int dwc3_resume(struct device *dev) spin_lock_irqsave(&dwc->lock, flags); + dwc3_event_buffers_setup(dwc); dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl); switch (dwc->dr_mode) { @@ -944,9 +901,6 @@ static int dwc3_resume(struct device *dev) } static const struct dev_pm_ops dwc3_dev_pm_ops = { - .prepare = dwc3_prepare, - .complete = dwc3_complete, - SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) }; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 66f62563bcf9..a715ee1f3c06 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -964,20 +964,9 @@ static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc, /* power management interface */ #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) -int dwc3_gadget_prepare(struct dwc3 *dwc); -void dwc3_gadget_complete(struct dwc3 *dwc); int dwc3_gadget_suspend(struct dwc3 *dwc); int dwc3_gadget_resume(struct dwc3 *dwc); #else -static inline int dwc3_gadget_prepare(struct dwc3 *dwc) -{ - return 0; -} - -static inline void dwc3_gadget_complete(struct dwc3 *dwc) -{ -} - static inline int dwc3_gadget_suspend(struct dwc3 *dwc) { return 0; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 546ea5431b8c..748b87b3f98a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2744,26 +2744,13 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dwc->ctrl_req, dwc->ctrl_req_addr); } -int dwc3_gadget_prepare(struct dwc3 *dwc) +int dwc3_gadget_suspend(struct dwc3 *dwc) { if (dwc->pullups_connected) { dwc3_gadget_disable_irq(dwc); dwc3_gadget_run_stop(dwc, true, true); } - return 0; -} - -void dwc3_gadget_complete(struct dwc3 *dwc) -{ - if (dwc->pullups_connected) { - dwc3_gadget_enable_irq(dwc); - dwc3_gadget_run_stop(dwc, true, false); - } -} - -int dwc3_gadget_suspend(struct dwc3 *dwc) -{ __dwc3_gadget_ep_disable(dwc->eps[0]); __dwc3_gadget_ep_disable(dwc->eps[1]); @@ -2798,6 +2785,11 @@ int dwc3_gadget_resume(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DCFG, dwc->dcfg); + if (dwc->pullups_connected) { + dwc3_gadget_enable_irq(dwc); + dwc3_gadget_run_stop(dwc, true, false); + } + return 0; err1: -- GitLab From 0abd0696982534a5cf75e8129989fa3d4b734797 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 9 Oct 2014 10:12:24 -0500 Subject: [PATCH 2550/9457] usb: gadget: udc-core: call ->disconnect() when soft disconnecting when disconnecting from host using our soft_connect sysfs interface, also let the gadget driver know about it by calling the gadget driver's ->disconnect() method. No problems have been found while not calling ->disconnect() so far, it's just good convention. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f2054659f25b..ddc6f577adb1 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -517,6 +517,7 @@ static ssize_t usb_udc_softconn_store(struct device *dev, usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); + udc->driver->disconnect(udc->gadget); usb_gadget_udc_stop(udc->gadget, udc->driver); } else { dev_err(dev, "unsupported command '%s'\n", buf); -- GitLab From 60b388befb42d1e90a8594cdcfe80dbf57542ac0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 Oct 2014 13:40:37 +0300 Subject: [PATCH 2551/9457] usb: gadget: f_uac1: remove an unneeded NULL check This NULL check sets off a static checker warning because we already dereferenced "card" earlier in the function. However, since "card" is never NULL so we can just remove the check. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_uac1.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index a44a07f30281..53842a1b947f 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c @@ -213,9 +213,6 @@ static int gaudio_open_snd_dev(struct gaudio *card) fn_cap = opts->fn_cap; fn_cntl = opts->fn_cntl; - if (!card) - return -ENODEV; - /* Open control device */ snd = &card->control; snd->filp = filp_open(fn_cntl, O_RDWR, 0); -- GitLab From 3a571870856f63064a3a45d7ffa2526d597b7fbe Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 8 Oct 2014 12:03:36 +0200 Subject: [PATCH 2552/9457] usb: gadget: configfs: add suspend/resume USB gadgets composed with configfs lack suspend and resume methods. This patch uses composite_suspend()/composite_resume() the same way e.g. composite_setup() or composite_disconnect() are used in a configfs-based gadget. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 6 ++---- drivers/usb/gadget/configfs.c | 3 +++ include/linux/usb/composite.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index e071d580346e..617835348569 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2064,8 +2064,7 @@ static int composite_bind(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ -static void -composite_suspend(struct usb_gadget *gadget) +void composite_suspend(struct usb_gadget *gadget) { struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_function *f; @@ -2088,8 +2087,7 @@ composite_suspend(struct usb_gadget *gadget) usb_gadget_vbus_draw(gadget, 2); } -static void -composite_resume(struct usb_gadget *gadget) +void composite_resume(struct usb_gadget *gadget) { struct usb_composite_dev *cdev = get_gadget_data(gadget); struct usb_function *f; diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 34034333f7f6..d25f9f3dfea0 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1453,6 +1453,9 @@ static const struct usb_gadget_driver configfs_driver_template = { .reset = composite_disconnect, .disconnect = composite_disconnect, + .suspend = composite_suspend, + .resume = composite_resume, + .max_speed = USB_SPEED_SUPER, .driver = { .owner = THIS_MODULE, diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index ed3811c09ec1..3d87defcc527 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -506,6 +506,8 @@ extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n); extern void composite_disconnect(struct usb_gadget *gadget); extern int composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl); +extern void composite_suspend(struct usb_gadget *gadget); +extern void composite_resume(struct usb_gadget *gadget); /* * Some systems will need runtime overrides for the product identifiers -- GitLab From f2918ad89df5a5deb4773e13b5f6e21eabfce282 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 10 Oct 2014 15:21:56 -0500 Subject: [PATCH 2553/9457] usb: gadget: udc: document our sysfs ABI I noticed that this has been missing for quite some time so I decided it was about time to document it. Signed-off-by: Felipe Balbi --- Documentation/ABI/stable/sysfs-class-udc | 93 ++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-class-udc diff --git a/Documentation/ABI/stable/sysfs-class-udc b/Documentation/ABI/stable/sysfs-class-udc new file mode 100644 index 000000000000..85d3dac2e204 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-class-udc @@ -0,0 +1,93 @@ +What: /sys/class/udc//a_alt_hnp_support +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host supports HNP at an alternate port. +Users: + +What: /sys/class/udc//a_hnp_support +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host supports HNP at this port. +Users: + +What: /sys/class/udc//b_hnp_enable +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host enabled HNP support. +Users: + +What: /sys/class/udc//current_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the current negotiated speed at this port. +Users: + +What: /sys/class/udc//is_a_peripheral +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates that this port is the default Host on an OTG session + but HNP was used to switch roles. +Users: + +What: /sys/class/udc//is_otg +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates that this port support OTG. +Users: + +What: /sys/class/udc//maximum_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the maximum USB speed supported by this port. +Users: + +What: /sys/class/udc//maximum_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the maximum USB speed supported by this port. +Users: + +What: /sys/class/udc//soft_connect +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Allows users to disconnect data pullup resistors thus causing a + logical disconnection from the USB Host. +Users: + +What: /sys/class/udc//srp +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Allows users to manually start Session Request Protocol. +Users: + +What: /sys/class/udc//state +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates current state of the USB Device Controller. Valid + states are: 'not-attached', 'attached', 'powered', + 'reconnecting', 'unauthenticated', 'default', 'addressed', + 'configured', and 'suspended'; however not all USB Device + Controllers support reporting all states. +Users: -- GitLab From 06a374ed13fdb7c6b2edd8cbdcf52bd1b0cc67b9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 10 Oct 2014 15:24:00 -0500 Subject: [PATCH 2554/9457] usb: dwc3: gadget: set state to NOT_ATTACHED on disconnect_irq whenever we get a Disconnect Interrupt, we should make sure to update out udc state to NOT_ATTACHED, otherwise sysfs will show wrong values. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 748b87b3f98a..12f42842da10 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2140,6 +2140,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->setup_packet_pending = false; + usb_gadget_set_state(&dwc->gadget, USB_STATE_NOTATTACHED); } static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) -- GitLab From 73359cef4fcc322c96019b2a5c1e99b08f3bbb57 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 13 Oct 2014 15:36:16 -0500 Subject: [PATCH 2555/9457] usb: dwc3: gadget: WARN() on bogus usb_ep_queue() Some gadget/function drivers might want to do improper request recycling by allocating a single request from one particular endpoint and queueing it to another completely unrelated endpoint. One such case was found with f_loopback.c. To prevent such cases from happening again, let's WARN() so we get a loud enough failure and persuade users to report errors. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 12f42842da10..20e4ee922c47 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1140,8 +1140,14 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, if (!dep->endpoint.desc) { dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", request, ep->name); - spin_unlock_irqrestore(&dwc->lock, flags); - return -ESHUTDOWN; + ret = -ESHUTDOWN; + goto out; + } + + if (WARN(req->dep != dep, "request %p belongs to '%s'\n", + request, req->dep->name)) { + ret = -EINVAL; + goto out; } dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", @@ -1149,6 +1155,8 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, trace_dwc3_ep_queue(req); ret = __dwc3_gadget_ep_queue(dep, req); + +out: spin_unlock_irqrestore(&dwc->lock, flags); return ret; -- GitLab From d6163f2ca5a4f1cd8a577db68a9c59f78b30a99b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:57 +0800 Subject: [PATCH 2556/9457] usb: gadget: mv_udc_core: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/mv_udc_core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 3c5db80ae325..cebb948f7155 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -2107,10 +2107,8 @@ static int mv_udc_probe(struct platform_device *pdev) } udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); - if (udc == NULL) { - dev_err(&pdev->dev, "failed to allocate memory for udc\n"); + if (udc == NULL) return -ENOMEM; - } udc->done = &release_done; udc->pdata = dev_get_platdata(&pdev->dev); @@ -2207,7 +2205,6 @@ static int mv_udc_probe(struct platform_device *pdev) size = udc->max_eps * sizeof(struct mv_ep) *2; udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (udc->eps == NULL) { - dev_err(&pdev->dev, "allocate ep memory failed\n"); retval = -ENOMEM; goto err_destroy_dma; } @@ -2216,7 +2213,6 @@ static int mv_udc_probe(struct platform_device *pdev) udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), GFP_KERNEL); if (!udc->status_req) { - dev_err(&pdev->dev, "allocate status_req memory failed\n"); retval = -ENOMEM; goto err_destroy_dma; } -- GitLab From 3efe90e995e72084505ee49680f698e8d5730b48 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:58 +0800 Subject: [PATCH 2557/9457] usb: gadget: fsl_qe_udc: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_qe_udc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index dd18ea38e391..6601b0fc097a 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2538,7 +2538,6 @@ static int qe_udc_probe(struct platform_device *ofdev) /* create a buf for ZLP send, need to remain zeroed */ udc->nullbuf = devm_kzalloc(&ofdev->dev, 256, GFP_KERNEL); if (udc->nullbuf == NULL) { - dev_err(udc->dev, "cannot alloc nullbuf\n"); ret = -ENOMEM; goto err3; } -- GitLab From 0590c4bf4bbbc608cf963dbf7d5aa4f202c8cf71 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:59 +0800 Subject: [PATCH 2558/9457] usb: gadget: bcm63xx_udc: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/bcm63xx_udc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 2235b8808700..485c8c2bddc1 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -2324,10 +2324,8 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) int rc = -ENOMEM, i, irq; udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); - if (!udc) { - dev_err(dev, "cannot allocate memory\n"); + if (!udc) return -ENOMEM; - } platform_set_drvdata(pdev, udc); udc->dev = dev; -- GitLab From 3dc3b4e15e09d785f06c7122a9d3e564e7065119 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:00 +0800 Subject: [PATCH 2559/9457] usb: gadget: s3c-hsudc: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/s3c-hsudc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index dfbf55797360..f658f69567bd 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1267,10 +1267,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev) hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + sizeof(struct s3c_hsudc_ep) * pd->epnum, GFP_KERNEL); - if (!hsudc) { - dev_err(dev, "cannot allocate memory\n"); + if (!hsudc) return -ENOMEM; - } platform_set_drvdata(pdev, dev); hsudc->dev = dev; -- GitLab From 26c07010c4ba82b52627ff18deacbee8900d868d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:06 +0800 Subject: [PATCH 2560/9457] usb: musb: davinci: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/davinci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 110b78415bf0..04de3aca938d 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -520,10 +520,8 @@ static int davinci_probe(struct platform_device *pdev) int ret = -ENOMEM; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + if (!glue) goto err0; - } clk = devm_clk_get(&pdev->dev, "usb"); if (IS_ERR(clk)) { -- GitLab From 24c611b925b79e64d396265ae1853f3bbb0656db Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:07 +0800 Subject: [PATCH 2561/9457] usb: musb: ux500: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index dc666e96f45f..d0180a70051d 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -247,10 +247,8 @@ static int ux500_probe(struct platform_device *pdev) } glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + if (!glue) goto err0; - } musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { -- GitLab From af1bdfc999e7690a3b47c75c43a238f6c619a170 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:08 +0800 Subject: [PATCH 2562/9457] usb: musb: omap2430: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index d369bf1f3936..6669f2611e91 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -518,10 +518,8 @@ static int omap2430_probe(struct platform_device *pdev) int ret = -ENOMEM; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + if (!glue) goto err0; - } musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { @@ -543,25 +541,16 @@ static int omap2430_probe(struct platform_device *pdev) struct platform_device *control_pdev; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(&pdev->dev, - "failed to allocate musb platform data\n"); + if (!pdata) goto err2; - } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(&pdev->dev, - "failed to allocate musb board data\n"); + if (!data) goto err2; - } config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); - if (!config) { - dev_err(&pdev->dev, - "failed to allocate musb hdrc config\n"); + if (!config) goto err2; - } of_property_read_u32(np, "mode", (u32 *)&pdata->mode); of_property_read_u32(np, "interface-type", -- GitLab From 65469790c6b060113f7438470fceeb2ae3cfba91 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:09 +0800 Subject: [PATCH 2563/9457] usb: musb: blackfin: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/blackfin.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index ac4422b33dcd..8554c6f7ab72 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -456,16 +456,12 @@ static int bfin_probe(struct platform_device *pdev) int ret = -ENOMEM; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + if (!glue) goto err0; - } musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); - if (!musb) { - dev_err(&pdev->dev, "failed to allocate musb device\n"); + if (!musb) goto err0; - } musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &bfin_dmamask; -- GitLab From 6a58856f25e1fedd7362a1ee598d5c890c3ed334 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:10 +0800 Subject: [PATCH 2564/9457] usb: musb: tusb6010: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 2daa779f1382..25f02dfc8955 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1164,10 +1164,8 @@ static int tusb_probe(struct platform_device *pdev) int ret; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + if (!glue) return -ENOMEM; - } glue->dev = &pdev->dev; -- GitLab From 0816ea2fa3c046b8c867aadbaadf19eb2fc3ac87 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:11 +0800 Subject: [PATCH 2565/9457] usb: musb: musb_dsps: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 48bc09e7b83b..6209456861b6 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -729,7 +729,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, config = devm_kzalloc(&parent->dev, sizeof(*config), GFP_KERNEL); if (!config) { - dev_err(dev, "failed to allocate musb hdrc config\n"); ret = -ENOMEM; goto err; } @@ -781,10 +780,8 @@ static int dsps_probe(struct platform_device *pdev) /* allocate glue */ glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "unable to allocate glue memory\n"); + if (!glue) return -ENOMEM; - } glue->dev = &pdev->dev; glue->wrp = wrp; -- GitLab From 87fb3dec36bc1823b810107b69435dc66f763543 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:12 +0800 Subject: [PATCH 2566/9457] usb: phy: phy-rcar-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-rcar-usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c index 33265a5b2cdf..487959620141 100644 --- a/drivers/usb/phy/phy-rcar-usb.c +++ b/drivers/usb/phy/phy-rcar-usb.c @@ -202,10 +202,8 @@ static int rcar_usb_phy_probe(struct platform_device *pdev) } priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "priv data allocation error\n"); + if (!priv) return -ENOMEM; - } priv->reg0 = reg0; priv->reg1 = reg1; -- GitLab From 01ad32d5b5289b00d03a94dd9f6d975f1314a541 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:13 +0800 Subject: [PATCH 2567/9457] usb: phy: phy-tegra-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-tegra-usb.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 886f1807a67b..fa2bfa4ee34e 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -880,11 +880,8 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, tegra_phy->config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); - if (!tegra_phy->config) { - dev_err(&pdev->dev, - "unable to allocate memory for USB UTMIP config\n"); + if (!tegra_phy->config) return -ENOMEM; - } config = tegra_phy->config; @@ -979,10 +976,8 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) int err; tegra_phy = devm_kzalloc(&pdev->dev, sizeof(*tegra_phy), GFP_KERNEL); - if (!tegra_phy) { - dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); + if (!tegra_phy) return -ENOMEM; - } match = of_match_device(tegra_usb_phy_id_table, &pdev->dev); if (!match) { -- GitLab From 9aabd03272c8dc0b91341da865ae742fe0ecb2c3 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:14 +0800 Subject: [PATCH 2568/9457] usb: phy: phy-am335x-control: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-am335x-control.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 35b6083b7999..2e923c581809 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -147,10 +147,8 @@ static int am335x_control_usb_probe(struct platform_device *pdev) phy_ctrl = of_id->data; ctrl_usb = devm_kzalloc(&pdev->dev, sizeof(*ctrl_usb), GFP_KERNEL); - if (!ctrl_usb) { - dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); + if (!ctrl_usb) return -ENOMEM; - } ctrl_usb->dev = &pdev->dev; -- GitLab From 3f8acf35b019aa996cc16b3658b72ad361cc7931 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:15 +0800 Subject: [PATCH 2569/9457] usb: phy: phy-rcar-gen2-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-rcar-gen2-usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c index 388d89f6b141..f83808413ba2 100644 --- a/drivers/usb/phy/phy-rcar-gen2-usb.c +++ b/drivers/usb/phy/phy-rcar-gen2-usb.c @@ -195,10 +195,8 @@ static int rcar_gen2_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(base); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "Memory allocation failed\n"); + if (!priv) return -ENOMEM; - } spin_lock_init(&priv->lock); priv->clk = clk; -- GitLab From c62fe55648702c5e736861a4238a58b92072202b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:16 +0800 Subject: [PATCH 2570/9457] usb: phy: phy-mxs-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-mxs-usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 0e0c41587a08..a55dadcd47f3 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -390,10 +390,8 @@ static int mxs_phy_probe(struct platform_device *pdev) } mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL); - if (!mxs_phy) { - dev_err(&pdev->dev, "Failed to allocate USB PHY structure!\n"); + if (!mxs_phy) return -ENOMEM; - } /* Some SoCs don't have anatop registers */ if (of_get_property(np, "fsl,anatop", NULL)) { -- GitLab From 9da22206c2dad28f4a1dd8c6d9f66030524965b2 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:17 +0800 Subject: [PATCH 2571/9457] usb: phy: phy-msm-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 7843ef7dd0ff..471e69dbcca0 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1505,10 +1505,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) } pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); - if (!pdata->phy_init_seq) { - dev_warn(&pdev->dev, "No space for PHY init sequence\n"); + if (!pdata->phy_init_seq) return 0; - } ret = of_property_read_u32_array(node, "qcom,phy-init-sequence", pdata->phy_init_seq, words); @@ -1530,10 +1528,8 @@ static int msm_otg_probe(struct platform_device *pdev) void __iomem *phy_select; motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); - if (!motg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + if (!motg) return -ENOMEM; - } pdata = dev_get_platdata(&pdev->dev); if (!pdata) { @@ -1546,10 +1542,8 @@ static int msm_otg_probe(struct platform_device *pdev) motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); - if (!motg->phy.otg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + if (!motg->phy.otg) return -ENOMEM; - } phy = &motg->phy; phy->dev = &pdev->dev; -- GitLab From aa10c7b00eff826bceee2b9f9cd005efc028d881 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:18 +0800 Subject: [PATCH 2572/9457] usb: phy: phy-mv-usb: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-mv-usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 7d80c54f0ac6..c9517d8bda8d 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -686,10 +686,8 @@ static int mv_otg_probe(struct platform_device *pdev) } mvotg = devm_kzalloc(&pdev->dev, sizeof(*mvotg), GFP_KERNEL); - if (!mvotg) { - dev_err(&pdev->dev, "failed to allocate memory!\n"); + if (!mvotg) return -ENOMEM; - } otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); if (!otg) -- GitLab From b1cb07cdee8f0247b1a6b3ba63ad4214ee2032a4 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:19 +0800 Subject: [PATCH 2573/9457] usb: renesas_usbhs: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index b3b6813ab270..6dae1151569b 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -505,10 +505,8 @@ static int usbhs_probe(struct platform_device *pdev) /* usb private data */ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "Could not allocate priv\n"); + if (!priv) return -ENOMEM; - } priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) -- GitLab From 3da6702f577be7249ece5799fb91cf2bf5e243fd Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sat, 11 Oct 2014 21:10:38 +0530 Subject: [PATCH 2574/9457] usb: musb: ux500_dma: use dmaengine_xxx() APIs The drivers should use dmaengine_terminate_all() or dmaengine_slave_config() API instead of accessing the device_control which will be deprecated soon Signed-off-by: Vinod Koul Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500_dma.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 221faed9f074..734dc8408d54 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -121,8 +121,7 @@ static bool ux500_configure_channel(struct dma_channel *channel, slave_conf.dst_maxburst = 16; slave_conf.device_fc = false; - dma_chan->device->device_control(dma_chan, DMA_SLAVE_CONFIG, - (unsigned long) &slave_conf); + dmaengine_slave_config(dma_chan, &slave_conf); dma_desc = dmaengine_prep_slave_sg(dma_chan, &sg, 1, direction, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -246,9 +245,7 @@ static int ux500_dma_channel_abort(struct dma_channel *channel) musb_writew(epio, MUSB_RXCSR, csr); } - ux500_channel->dma_chan->device-> - device_control(ux500_channel->dma_chan, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(ux500_channel->dma_chan); channel->status = MUSB_DMA_STATUS_FREE; } return 0; -- GitLab From 21090f06f09f72f2806c19f0bdcd4fde622c2676 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:16:04 -0500 Subject: [PATCH 2575/9457] usb: gadget: udc: amd5536: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 3b9d13848a4f..7d0e0b8a9606 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -1971,7 +1971,7 @@ static int amd5536_udc_stop(struct usb_gadget *g, spin_lock_irqsave(&dev->lock, flags); udc_mask_unused_interrupts(dev); - shutdown(dev, driver); + shutdown(dev, NULL); spin_unlock_irqrestore(&dev->lock, flags); dev->driver = NULL; -- GitLab From af9501f656d2250dbf04e48f77025b3783cc0505 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:17:08 -0500 Subject: [PATCH 2576/9457] usb: gadget: udc: at91: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 9968f5331fe4..cffd2a22dca0 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1657,9 +1657,9 @@ static int at91_stop(struct usb_gadget *gadget, at91_udp_write(udc, AT91_UDP_IDR, ~0); spin_unlock_irqrestore(&udc->lock, flags); + DBG("unbound from %s\n", udc->driver->driver.name); udc->driver = NULL; - DBG("unbound from %s\n", driver->driver.name); return 0; } -- GitLab From 96a5361aab7a89cf80cb4fe03966f55f00b0d91f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:18:29 -0500 Subject: [PATCH 2577/9457] usb: gadget: udc: dummy: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 81dc5959e36b..32bdd788c05a 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -921,9 +921,8 @@ static int dummy_udc_stop(struct usb_gadget *g, struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; - if (driver) - dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", - driver->driver.name); + dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", + dum->driver->driver.name); dum->driver = NULL; -- GitLab From 5d82ff915f019bb4f479914e4a43de00ef38da8a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:20:10 -0500 Subject: [PATCH 2578/9457] usb: gadget: udc: fsl_qe: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_qe_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 6601b0fc097a..be788572014b 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2334,10 +2334,10 @@ static int fsl_qe_stop(struct usb_gadget *gadget, nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc->lock, flags); + dev_info(udc->dev, "unregistered gadget driver '%s'\r\n", + udc->driver->driver.name); udc->driver = NULL; - dev_info(udc->dev, "unregistered gadget driver '%s'\r\n", - driver->driver.name); return 0; } -- GitLab From d3cb25bfcdf6806dccd154ca2d62f9f447fdad5a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:21:03 -0500 Subject: [PATCH 2579/9457] usb: gadget: udc: lpc32xx: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/lpc32xx_udc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index feab0bac8fdc..cef64b98b6e5 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -2967,9 +2967,6 @@ static int lpc32xx_stop(struct usb_gadget *gadget, int i; struct lpc32xx_udc *udc = to_udc(gadget); - if (!driver || driver != udc->driver) - return -EINVAL; - for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) disable_irq(udc->udp_irq[i]); -- GitLab From a19f378772ffdc18962a76102a424c21b79348a9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:21:34 -0500 Subject: [PATCH 2580/9457] usb: gadget: udc: mv_u3d: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/mv_u3d_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 046a1f808b0d..e3ef744c4ff9 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -1284,7 +1284,7 @@ static int mv_u3d_stop(struct usb_gadget *g, mv_u3d_controller_stop(u3d); /* stop all usb activities */ u3d->gadget.speed = USB_SPEED_UNKNOWN; - mv_u3d_stop_activity(u3d, driver); + mv_u3d_stop_activity(u3d, NULL); mv_u3d_disable(u3d); if (pdata->phy_deinit) -- GitLab From 2f1ae5010861b92d665d11e1069566fc4c28689b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:22:11 -0500 Subject: [PATCH 2581/9457] usb: gadget: udc: mv_udc: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index cebb948f7155..32d24ff2c4cd 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -1386,7 +1386,7 @@ static int mv_udc_stop(struct usb_gadget *gadget, /* stop all usb activities */ udc->gadget.speed = USB_SPEED_UNKNOWN; - stop_activity(udc, driver); + stop_activity(udc, NULL); mv_udc_disable(udc); spin_unlock_irqrestore(&udc->lock, flags); -- GitLab From 5baca5cf255d9a9d2bc97fe2531e12e37ebdd77d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:22:52 -0500 Subject: [PATCH 2582/9457] usb: gadget: udc: net2272: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2272.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 84d7162a8022..6fb54f5848b5 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1511,12 +1511,13 @@ static int net2272_stop(struct usb_gadget *_gadget, dev = container_of(_gadget, struct net2272, gadget); spin_lock_irqsave(&dev->lock, flags); - stop_activity(dev, driver); + stop_activity(dev, NULL); spin_unlock_irqrestore(&dev->lock, flags); + dev_dbg(dev->dev, "unregistered driver '%s'\n", + dev->driver->driver.name); dev->driver = NULL; - dev_dbg(dev->dev, "unregistered driver '%s'\n", driver->driver.name); return 0; } -- GitLab From bfd0ed576dbf9cc71af7dbe42841fc9246524961 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:23:33 -0500 Subject: [PATCH 2583/9457] usb: gadget: udc: net2280: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 8d13337e2dde..ee74b9dfb757 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -2446,11 +2446,9 @@ static int net2280_stop(struct usb_gadget *_gadget, dev = container_of(_gadget, struct net2280, gadget); spin_lock_irqsave(&dev->lock, flags); - stop_activity(dev, driver); + stop_activity(dev, NULL); spin_unlock_irqrestore(&dev->lock, flags); - dev->driver = NULL; - net2280_led_active(dev, 0); /* Disable full-speed test mode */ @@ -2460,8 +2458,8 @@ static int net2280_stop(struct usb_gadget *_gadget, device_remove_file(&dev->pdev->dev, &dev_attr_function); device_remove_file(&dev->pdev->dev, &dev_attr_queues); - ep_dbg(dev, "unregistered driver '%s'\n", - driver ? driver->driver.name : ""); + ep_dbg(dev, "unregistered driver '%s'\n", dev->driver->driver.name); + dev->driver = NULL; return 0; } -- GitLab From d7343161fd1250a8c4eadf98a0db690f3257f0c5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:24:37 -0500 Subject: [PATCH 2584/9457] usb: gadget: udc: pxa25x: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa25x_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 42f7eeb8ff6f..098fa57c3b80 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1319,7 +1319,7 @@ static int pxa25x_udc_stop(struct usb_gadget*g, local_irq_disable(); dev->pullup = 0; pullup(dev); - stop_activity(dev, driver); + stop_activity(dev, NULL); local_irq_enable(); if (!IS_ERR_OR_NULL(dev->transceiver)) -- GitLab From c3d84dfb7f6027fff4723330620f63c08ab0e253 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:25:04 -0500 Subject: [PATCH 2585/9457] usb: gadget: udc: pxa27x: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 55598c0d083c..b90b1f308992 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -1862,7 +1862,7 @@ static int pxa27x_udc_stop(struct usb_gadget *g, { struct pxa_udc *udc = to_pxa(g); - stop_activity(udc, driver); + stop_activity(udc, NULL); udc_disable(udc); dplus_pullup(udc, 0); -- GitLab From 82891b959cbb2cd1827bc2713d46840fcf8dbe14 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:25:50 -0500 Subject: [PATCH 2586/9457] usb: gadget: udc: s3c-hsudc: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/s3c-hsudc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index f658f69567bd..f3bb2fa25115 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1199,11 +1199,7 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, if (!hsudc) return -ENODEV; - if (!driver || driver != hsudc->driver) - return -EINVAL; - spin_lock_irqsave(&hsudc->lock, flags); - hsudc->driver = NULL; hsudc->gadget.speed = USB_SPEED_UNKNOWN; s3c_hsudc_uninit_phy(); @@ -1222,7 +1218,9 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", - driver->driver.name); + hsudc->driver->driver.name); + hsudc->driver = NULL; + return 0; } -- GitLab From 69e28882dc7a4ad80f1a0de1a2e7f346a15b6564 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:26:46 -0500 Subject: [PATCH 2587/9457] usb: musb: gadget: do not rely on 'driver' argument future patches will remove the extra 'driver' argument to ->udc_stop(), in order to do that, we must make sure that our UDC does not rely on it first. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 24c8c0219790..fdb8b3111b5a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1946,11 +1946,11 @@ static int musb_gadget_stop(struct usb_gadget *g, (void) musb_gadget_vbus_draw(&musb->g, 0); musb->xceiv->state = OTG_STATE_UNDEFINED; - stop_activity(musb, driver); + stop_activity(musb, NULL); otg_set_peripheral(musb->xceiv->otg, NULL); dev_dbg(musb->controller, "unregistering driver %s\n", - driver ? driver->function : "(removed)"); + musb->gadget_driver->function); musb->is_active = 0; musb->gadget_driver = NULL; -- GitLab From 2c683347f5be4efee5b8abba84f9bad6ed4fe47d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:34:07 -0500 Subject: [PATCH 2588/9457] usb: gadget: udc: pass a single argument to usb_gadget_udc_start/stop We know that our udc points to our gadget and our gadget_driver, simplify the interface by passing a single argument. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index ddc6f577adb1..3fed7a2742a0 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -174,8 +174,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset); /** * usb_gadget_udc_start - tells usb device controller to start up - * @gadget: The gadget we want to get started - * @driver: The driver we want to bind to @gadget + * @udc: The UDC to be started * * This call is issued by the UDC Class driver when it's about * to register a gadget driver to the device controller, before @@ -186,10 +185,9 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset); * * Returns zero on success, else negative errno. */ -static inline int usb_gadget_udc_start(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static inline int usb_gadget_udc_start(struct usb_udc *udc) { - return gadget->ops->udc_start(gadget, driver); + return udc->gadget->ops->udc_start(udc->gadget, udc->driver); } /** @@ -204,10 +202,9 @@ static inline int usb_gadget_udc_start(struct usb_gadget *gadget, * far as powering off UDC completely and disable its data * line pullups. */ -static inline void usb_gadget_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static inline void usb_gadget_udc_stop(struct usb_udc *udc) { - gadget->ops->udc_stop(gadget, driver); + udc->gadget->ops->udc_stop(udc->gadget, udc->driver); } /** @@ -335,7 +332,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, NULL); + usb_gadget_udc_stop(udc); udc->driver = NULL; udc->dev.driver = NULL; @@ -395,7 +392,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri ret = driver->bind(udc->gadget, driver); if (ret) goto err1; - ret = usb_gadget_udc_start(udc->gadget, driver); + ret = usb_gadget_udc_start(udc); if (ret) { driver->unbind(udc->gadget); goto err1; @@ -513,12 +510,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } if (sysfs_streq(buf, "connect")) { - usb_gadget_udc_start(udc->gadget, udc->driver); + usb_gadget_udc_start(udc); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); + usb_gadget_udc_stop(udc); } else { dev_err(dev, "unsupported command '%s'\n", buf); return -EINVAL; -- GitLab From dea87f9d13615c03b7160be0b108d92da9a111cd Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:35:52 -0500 Subject: [PATCH 2589/9457] usb: gadget: udc: at91: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index cffd2a22dca0..5c4cede5365d 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1641,7 +1641,6 @@ static int at91_start(struct usb_gadget *gadget, udc->enabled = 1; udc->selfpowered = 1; - DBG("bound to %s\n", driver->driver.name); return 0; } @@ -1657,7 +1656,6 @@ static int at91_stop(struct usb_gadget *gadget, at91_udp_write(udc, AT91_UDP_IDR, ~0); spin_unlock_irqrestore(&udc->lock, flags); - DBG("unbound from %s\n", udc->driver->driver.name); udc->driver = NULL; return 0; -- GitLab From 3364aecc8c72e4e2f4957fce45b97fbf35b87c3a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:37:04 -0500 Subject: [PATCH 2590/9457] usb: gadget: udc: atmel_usba: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/atmel_usba_udc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 1529926e20a0..eaee5f90e9fd 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1791,8 +1791,6 @@ static int atmel_usba_start(struct usb_gadget *gadget, return ret; } - DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); - udc->vbus_prev = 0; if (gpio_is_valid(udc->vbus_pin)) enable_irq(gpio_to_irq(udc->vbus_pin)); @@ -1830,8 +1828,6 @@ static int atmel_usba_stop(struct usb_gadget *gadget, clk_disable_unprepare(udc->hclk); clk_disable_unprepare(udc->pclk); - DBG(DBG_GADGET, "unregistered driver `%s'\n", udc->driver->driver.name); - udc->driver = NULL; return 0; -- GitLab From dd7e6dd546c69b6166268dedb787b0839c1fd4d5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:37:38 -0500 Subject: [PATCH 2591/9457] usb: gadget: udc: dummy: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 32bdd788c05a..5c72ade61aa6 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -908,10 +908,8 @@ static int dummy_udc_start(struct usb_gadget *g, */ dum->devstatus = 0; - dum->driver = driver; - dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", - driver->driver.name); + return 0; } @@ -921,9 +919,6 @@ static int dummy_udc_stop(struct usb_gadget *g, struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; - dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", - dum->driver->driver.name); - dum->driver = NULL; return 0; -- GitLab From 703584768ae4dc6bab3872a36b873a01c62eb045 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:38:09 -0500 Subject: [PATCH 2592/9457] usb: gadget: udc: fsl_qe: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_qe_udc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index be788572014b..6ca61e6b72e5 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2305,8 +2305,6 @@ static int fsl_qe_start(struct usb_gadget *gadget, udc->ep0_dir = USB_DIR_OUT; spin_unlock_irqrestore(&udc->lock, flags); - dev_info(udc->dev, "%s bind to driver %s\n", udc->gadget.name, - driver->driver.name); return 0; } @@ -2334,8 +2332,6 @@ static int fsl_qe_stop(struct usb_gadget *gadget, nuke(loop_ep, -ESHUTDOWN); spin_unlock_irqrestore(&udc->lock, flags); - dev_info(udc->dev, "unregistered gadget driver '%s'\r\n", - udc->driver->driver.name); udc->driver = NULL; return 0; -- GitLab From 70bbd56b7d456adc686873e548c5690b1b01856f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:38:39 -0500 Subject: [PATCH 2593/9457] usb: gadget: udc: gr_udc: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/gr_udc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 1b3048a6a2a3..bde989f566c3 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1932,9 +1932,6 @@ static int gr_udc_start(struct usb_gadget *gadget, spin_unlock(&dev->lock); - dev_info(dev->dev, "Started with gadget driver '%s'\n", - driver->driver.name); - return 0; } @@ -1951,8 +1948,6 @@ static int gr_udc_stop(struct usb_gadget *gadget, spin_unlock_irqrestore(&dev->lock, flags); - dev_info(dev->dev, "Stopped\n"); - return 0; } -- GitLab From 812a40bee7b7e121f492ec9cd2f5cfafc086e70d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:39:29 -0500 Subject: [PATCH 2594/9457] usb: gadget: udc: net2272: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2272.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 6fb54f5848b5..4641df5a8175 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1471,8 +1471,6 @@ static int net2272_start(struct usb_gadget *_gadget, */ net2272_ep0_start(dev); - dev_dbg(dev->dev, "%s ready\n", driver->driver.name); - return 0; } @@ -1514,8 +1512,6 @@ static int net2272_stop(struct usb_gadget *_gadget, stop_activity(dev, NULL); spin_unlock_irqrestore(&dev->lock, flags); - dev_dbg(dev->dev, "unregistered driver '%s'\n", - dev->driver->driver.name); dev->driver = NULL; return 0; -- GitLab From 1ca12b24087666959f166f24cca5bbaf5d74be78 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:40:05 -0500 Subject: [PATCH 2595/9457] usb: gadget: udc: net2280: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index ee74b9dfb757..a30df8efa2d8 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -2397,11 +2397,6 @@ static int net2280_start(struct usb_gadget *_gadget, ep0_start(dev); - ep_dbg(dev, "%s ready, usbctl %08x stdrsp %08x\n", - driver->driver.name, - readl(&dev->usb->usbctl), - readl(&dev->usb->stdrsp)); - /* pci writes may still be posted */ return 0; @@ -2458,7 +2453,6 @@ static int net2280_stop(struct usb_gadget *_gadget, device_remove_file(&dev->pdev->dev, &dev_attr_function); device_remove_file(&dev->pdev->dev, &dev_attr_queues); - ep_dbg(dev, "unregistered driver '%s'\n", dev->driver->driver.name); dev->driver = NULL; return 0; -- GitLab From 6ce372fed2cb67a7e27400b0c96df161189e0407 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:40:56 -0500 Subject: [PATCH 2596/9457] usb: gadget: udc: s3c-hsudc: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/s3c-hsudc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index f3bb2fa25115..de95e9dd957f 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1172,8 +1172,6 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, } enable_irq(hsudc->irq); - dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); - s3c_hsudc_reconfig(hsudc); pm_runtime_get_sync(hsudc->dev); @@ -1216,9 +1214,6 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, disable_irq(hsudc->irq); regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); - - dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", - hsudc->driver->driver.name); hsudc->driver = NULL; return 0; -- GitLab From fae5afb98d88108a188e57c035834e3fc2bdbf80 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:41:33 -0500 Subject: [PATCH 2597/9457] usb: musb: gadget: remove bind/unbind messages now that we provide generic register/unregister debugging messages from udc-core, we can remove the same messages from this driver. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index fdb8b3111b5a..88d63e0c79f5 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1851,8 +1851,6 @@ static int musb_gadget_start(struct usb_gadget *g, pm_runtime_get_sync(musb->controller); - dev_dbg(musb->controller, "registering driver %s\n", driver->function); - musb->softconnect = 0; musb->gadget_driver = driver; @@ -1949,9 +1947,6 @@ static int musb_gadget_stop(struct usb_gadget *g, stop_activity(musb, NULL); otg_set_peripheral(musb->xceiv->otg, NULL); - dev_dbg(musb->controller, "unregistering driver %s\n", - musb->gadget_driver->function); - musb->is_active = 0; musb->gadget_driver = NULL; musb_platform_try_idle(musb, 0); -- GitLab From 8da9fe8af8e3fd953b346c800976a5db6c0115a4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 11:54:46 -0500 Subject: [PATCH 2598/9457] usb: gadget: udc: core: fix unregistering message Currently, we're printing gadget driver name when registering and UDC name when unregistering. Standardize on always printing gadget driver name. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 3fed7a2742a0..52f457bb0bbc 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -325,7 +325,7 @@ EXPORT_SYMBOL_GPL(usb_add_gadget_udc); static void usb_gadget_remove_driver(struct usb_udc *udc) { dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", - udc->gadget->name); + udc->driver->function); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); -- GitLab From 22835b807e7ca946a4d1fbd4c7af56aa09cd273e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 12:05:12 -0500 Subject: [PATCH 2599/9457] usb: gadget: remove unnecessary 'driver' argument now that no UDC driver relies on the extra 'driver' argument to ->udc_stop(), we can safely remove it. This commit is based on previous work by Robert Baldyga which can be found at [1]; however that patch turned out to have a high probability of regressing many UDC drivers because of a blind search & replace s/driver/$udc->driver/ which caused the 'driver' argument to stop_activity() to be a valid non-NULL pointer when it should be NULL, thus causing UDCs to mistakenly call gadget driver's ->disconnect() callback. [1] http://markmail.org/message/x5zneg4xea4zntab Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 6 ++---- drivers/usb/dwc2/gadget.c | 3 +-- drivers/usb/dwc3/gadget.c | 3 +-- drivers/usb/gadget/udc/amd5536udc.c | 8 +++----- drivers/usb/gadget/udc/at91_udc.c | 7 +++---- drivers/usb/gadget/udc/atmel_usba_udc.c | 7 +++---- drivers/usb/gadget/udc/bcm63xx_udc.c | 3 +-- drivers/usb/gadget/udc/dummy_hcd.c | 6 ++---- drivers/usb/gadget/udc/fotg210-udc.c | 3 +-- drivers/usb/gadget/udc/fsl_qe_udc.c | 6 ++---- drivers/usb/gadget/udc/fsl_udc_core.c | 8 +++----- drivers/usb/gadget/udc/fusb300_udc.c | 3 +-- drivers/usb/gadget/udc/goku_udc.c | 6 ++---- drivers/usb/gadget/udc/gr_udc.c | 3 +-- drivers/usb/gadget/udc/lpc32xx_udc.c | 5 ++--- drivers/usb/gadget/udc/m66592-udc.c | 3 +-- drivers/usb/gadget/udc/mv_u3d_core.c | 3 +-- drivers/usb/gadget/udc/mv_udc_core.c | 5 ++--- drivers/usb/gadget/udc/net2272.c | 6 ++---- drivers/usb/gadget/udc/net2280.c | 6 ++---- drivers/usb/gadget/udc/omap_udc.c | 6 ++---- drivers/usb/gadget/udc/pch_udc.c | 7 +++---- drivers/usb/gadget/udc/pxa25x_udc.c | 6 ++---- drivers/usb/gadget/udc/pxa27x_udc.c | 6 ++---- drivers/usb/gadget/udc/r8a66597-udc.c | 3 +-- drivers/usb/gadget/udc/s3c-hsudc.c | 3 +-- drivers/usb/gadget/udc/s3c2410_udc.c | 6 ++---- drivers/usb/gadget/udc/udc-core.c | 2 +- drivers/usb/gadget/udc/udc-xilinx.c | 3 +-- drivers/usb/musb/musb_gadget.c | 6 ++---- drivers/usb/renesas_usbhs/mod_gadget.c | 3 +-- include/linux/usb/gadget.h | 3 +-- 32 files changed, 55 insertions(+), 99 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0444d3f8971a..f4397b29891f 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1544,8 +1544,7 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) static int ci_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int ci_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver); +static int ci_udc_stop(struct usb_gadget *gadget); /** * Device operations part of the API to the USB controller hardware, * which don't involve endpoints (or i/o) @@ -1682,8 +1681,7 @@ static int ci_udc_start(struct usb_gadget *gadget, /** * ci_udc_stop: unregister a gadget driver */ -static int ci_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int ci_udc_stop(struct usb_gadget *gadget) { struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); unsigned long flags; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index eee87098bb8b..441f1c4b8eb4 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2921,8 +2921,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, * * Stop udc hw block and stay tunned for future transmissions */ -static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) { struct s3c_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 20e4ee922c47..20dda60b27c3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1630,8 +1630,7 @@ static int dwc3_gadget_start(struct usb_gadget *g, return ret; } -static int dwc3_gadget_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int dwc3_gadget_stop(struct usb_gadget *g) { struct dwc3 *dwc = gadget_to_dwc(g); unsigned long flags; diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 7d0e0b8a9606..606b9009861a 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -1401,9 +1401,8 @@ static int udc_wakeup(struct usb_gadget *gadget) static int amd5536_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int amd5536_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); -/* gadget operations */ +static int amd5536_udc_stop(struct usb_gadget *g); + static const struct usb_gadget_ops udc_ops = { .wakeup = udc_wakeup, .get_frame = udc_get_frame, @@ -1962,8 +1961,7 @@ __acquires(dev->lock) } /* Called by gadget driver to unregister itself */ -static int amd5536_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int amd5536_udc_stop(struct usb_gadget *g) { struct udc *dev = to_amd5536_udc(g); unsigned long flags; diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 5c4cede5365d..f47f16c25f15 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -984,8 +984,8 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on) static int at91_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int at91_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver); +static int at91_stop(struct usb_gadget *gadget); + static const struct usb_gadget_ops at91_udc_ops = { .get_frame = at91_get_frame, .wakeup = at91_wakeup, @@ -1644,8 +1644,7 @@ static int at91_start(struct usb_gadget *gadget, return 0; } -static int at91_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int at91_stop(struct usb_gadget *gadget) { struct at91_udc *udc; unsigned long flags; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index eaee5f90e9fd..c537a6604b46 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -987,8 +987,8 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) static int atmel_usba_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int atmel_usba_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver); +static int atmel_usba_stop(struct usb_gadget *gadget); + static const struct usb_gadget_ops usba_udc_ops = { .get_frame = usba_udc_get_frame, .wakeup = usba_udc_wakeup, @@ -1807,8 +1807,7 @@ static int atmel_usba_start(struct usb_gadget *gadget, return 0; } -static int atmel_usba_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int atmel_usba_stop(struct usb_gadget *gadget) { struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); unsigned long flags; diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 485c8c2bddc1..9319ff27c73f 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1836,8 +1836,7 @@ static int bcm63xx_udc_start(struct usb_gadget *gadget, * @gadget: USB slave device. * @driver: Driver for USB slave devices. */ -static int bcm63xx_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int bcm63xx_udc_stop(struct usb_gadget *gadget) { struct bcm63xx_udc *udc = gadget_to_udc(gadget); unsigned long flags; diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 5c72ade61aa6..5bffb75922f8 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -851,8 +851,7 @@ static int dummy_pullup(struct usb_gadget *_gadget, int value) static int dummy_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int dummy_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int dummy_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops dummy_ops = { .get_frame = dummy_g_get_frame, @@ -913,8 +912,7 @@ static int dummy_udc_start(struct usb_gadget *g, return 0; } -static int dummy_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int dummy_udc_stop(struct usb_gadget *g) { struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index 1d315921bf34..1ca52e11eb98 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c @@ -1053,8 +1053,7 @@ static void fotg210_init(struct fotg210_udc *fotg210) iowrite32(value, fotg210->reg + FOTG210_DMISGR0); } -static int fotg210_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int fotg210_udc_stop(struct usb_gadget *g) { struct fotg210_udc *fotg210 = gadget_to_fotg210(g); unsigned long flags; diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 6ca61e6b72e5..01f29ef622bc 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -1887,8 +1887,7 @@ static int qe_get_frame(struct usb_gadget *gadget) static int fsl_qe_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int fsl_qe_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver); +static int fsl_qe_stop(struct usb_gadget *gadget); /* defined in usb_gadget.h */ static const struct usb_gadget_ops qe_gadget_ops = { @@ -2308,8 +2307,7 @@ static int fsl_qe_start(struct usb_gadget *gadget, return 0; } -static int fsl_qe_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int fsl_qe_stop(struct usb_gadget *gadget) { struct qe_udc *udc; struct qe_ep *loop_ep; diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index c3620791a315..b184ed3ef37a 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1236,9 +1236,8 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) static int fsl_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int fsl_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); -/* defined in gadget.h */ +static int fsl_udc_stop(struct usb_gadget *g); + static const struct usb_gadget_ops fsl_gadget_ops = { .get_frame = fsl_get_frame, .wakeup = fsl_wakeup, @@ -1975,8 +1974,7 @@ static int fsl_udc_start(struct usb_gadget *g, } /* Disconnect from gadget driver */ -static int fsl_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int fsl_udc_stop(struct usb_gadget *g) { struct fsl_ep *loop_ep; unsigned long flags; diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 8286df72add4..a1b33f534b52 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1320,8 +1320,7 @@ static int fusb300_udc_start(struct usb_gadget *g, return 0; } -static int fusb300_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int fusb300_udc_stop(struct usb_gadget *g) { struct fusb300 *fusb300 = to_fusb300(g); diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index bf9c5ef8b56b..5b9176e7202a 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -992,8 +992,7 @@ static int goku_get_frame(struct usb_gadget *_gadget) static int goku_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int goku_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int goku_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops goku_ops = { .get_frame = goku_get_frame, @@ -1364,8 +1363,7 @@ static void stop_activity(struct goku_udc *dev) udc_enable(dev); } -static int goku_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int goku_udc_stop(struct usb_gadget *g) { struct goku_udc *dev = to_goku_udc(g); unsigned long flags; diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index bde989f566c3..320df9a250ff 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1935,8 +1935,7 @@ static int gr_udc_start(struct usb_gadget *gadget, return 0; } -static int gr_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int gr_udc_stop(struct usb_gadget *gadget) { struct gr_udc *dev = to_gr_udc(gadget); unsigned long flags; diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index cef64b98b6e5..4be497d39d91 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -2559,7 +2559,7 @@ static int lpc32xx_pullup(struct usb_gadget *gadget, int is_on) } static int lpc32xx_start(struct usb_gadget *, struct usb_gadget_driver *); -static int lpc32xx_stop(struct usb_gadget *, struct usb_gadget_driver *); +static int lpc32xx_stop(struct usb_gadget *); static const struct usb_gadget_ops lpc32xx_udc_ops = { .get_frame = lpc32xx_get_frame, @@ -2961,8 +2961,7 @@ static int lpc32xx_start(struct usb_gadget *gadget, return 0; } -static int lpc32xx_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int lpc32xx_stop(struct usb_gadget *gadget) { int i; struct lpc32xx_udc *udc = to_udc(gadget); diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 898565687a8c..311ec5f1cbfe 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1485,8 +1485,7 @@ static int m66592_udc_start(struct usb_gadget *g, return 0; } -static int m66592_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int m66592_udc_stop(struct usb_gadget *g) { struct m66592 *m66592 = to_m66592(g); diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index e3ef744c4ff9..ea422ac79990 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -1266,8 +1266,7 @@ static int mv_u3d_start(struct usb_gadget *g, return 0; } -static int mv_u3d_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int mv_u3d_stop(struct usb_gadget *g) { struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); struct mv_usb_platform_data *pdata = dev_get_platdata(u3d->dev); diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 32d24ff2c4cd..f104ac090a99 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -1223,7 +1223,7 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) } static int mv_udc_start(struct usb_gadget *, struct usb_gadget_driver *); -static int mv_udc_stop(struct usb_gadget *, struct usb_gadget_driver *); +static int mv_udc_stop(struct usb_gadget *); /* device controller usb_gadget_ops structure */ static const struct usb_gadget_ops mv_ops = { @@ -1371,8 +1371,7 @@ static int mv_udc_start(struct usb_gadget *gadget, return 0; } -static int mv_udc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int mv_udc_stop(struct usb_gadget *gadget) { struct mv_udc *udc; unsigned long flags; diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 4641df5a8175..887bea42e5aa 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1169,8 +1169,7 @@ net2272_pullup(struct usb_gadget *_gadget, int is_on) static int net2272_start(struct usb_gadget *_gadget, struct usb_gadget_driver *driver); -static int net2272_stop(struct usb_gadget *_gadget, - struct usb_gadget_driver *driver); +static int net2272_stop(struct usb_gadget *_gadget); static const struct usb_gadget_ops net2272_ops = { .get_frame = net2272_get_frame, @@ -1500,8 +1499,7 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) net2272_usb_reinit(dev); } -static int net2272_stop(struct usb_gadget *_gadget, - struct usb_gadget_driver *driver) +static int net2272_stop(struct usb_gadget *_gadget) { struct net2272 *dev; unsigned long flags; diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index a30df8efa2d8..bd03a1b4192d 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1548,8 +1548,7 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on) static int net2280_start(struct usb_gadget *_gadget, struct usb_gadget_driver *driver); -static int net2280_stop(struct usb_gadget *_gadget, - struct usb_gadget_driver *driver); +static int net2280_stop(struct usb_gadget *_gadget); static const struct usb_gadget_ops net2280_ops = { .get_frame = net2280_get_frame, @@ -2432,8 +2431,7 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) usb_reinit(dev); } -static int net2280_stop(struct usb_gadget *_gadget, - struct usb_gadget_driver *driver) +static int net2280_stop(struct usb_gadget *_gadget) { struct net2280 *dev; unsigned long flags; diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index dcdfea46003b..534b85c07feb 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -1311,8 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) static int omap_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int omap_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int omap_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops omap_gadget_ops = { .get_frame = omap_get_frame, @@ -2102,8 +2101,7 @@ static int omap_udc_start(struct usb_gadget *g, return status; } -static int omap_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int omap_udc_stop(struct usb_gadget *g) { unsigned long flags; int status = -ENODEV; diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index ccbe3d4a2a50..6534f36866dc 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -1240,8 +1240,8 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) static int pch_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int pch_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int pch_udc_stop(struct usb_gadget *g); + static const struct usb_gadget_ops pch_udc_ops = { .get_frame = pch_udc_pcd_get_frame, .wakeup = pch_udc_pcd_wakeup, @@ -3008,8 +3008,7 @@ static int pch_udc_start(struct usb_gadget *g, return 0; } -static int pch_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int pch_udc_stop(struct usb_gadget *g) { struct pch_udc_dev *dev = to_pch_udc(g); diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 098fa57c3b80..2944092cd92e 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -998,8 +998,7 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) static int pxa25x_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int pxa25x_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int pxa25x_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops pxa25x_udc_ops = { .get_frame = pxa25x_udc_get_frame, @@ -1311,8 +1310,7 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) udc_reinit(dev); } -static int pxa25x_udc_stop(struct usb_gadget*g, - struct usb_gadget_driver *driver) +static int pxa25x_udc_stop(struct usb_gadget*g) { struct pxa25x_udc *dev = to_pxa25x(g); diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index b90b1f308992..17a0193b5e01 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -1669,8 +1669,7 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) static int pxa27x_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int pxa27x_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int pxa27x_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops pxa_udc_ops = { .get_frame = pxa_udc_get_frame, @@ -1857,8 +1856,7 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) * * Returns 0 if no error, -ENODEV, -EINVAL otherwise */ -static int pxa27x_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int pxa27x_udc_stop(struct usb_gadget *g) { struct pxa_udc *udc = to_pxa(g); diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index f8186613b53e..b63a527baf13 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1763,8 +1763,7 @@ static int r8a66597_start(struct usb_gadget *gadget, return 0; } -static int r8a66597_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int r8a66597_stop(struct usb_gadget *gadget) { struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); unsigned long flags; diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index de95e9dd957f..97d3a9144381 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1188,8 +1188,7 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, return ret; } -static int s3c_hsudc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int s3c_hsudc_stop(struct usb_gadget *gadget) { struct s3c_hsudc *hsudc = to_hsudc(gadget); unsigned long flags; diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index ff423d15beff..2a8e36d31488 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -1541,8 +1541,7 @@ static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) static int s3c2410_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int s3c2410_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int s3c2410_udc_stop(struct usb_gadget *g); static const struct usb_gadget_ops s3c2410_ops = { .get_frame = s3c2410_udc_get_frame, @@ -1683,8 +1682,7 @@ static int s3c2410_udc_start(struct usb_gadget *g, return 0; } -static int s3c2410_udc_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int s3c2410_udc_stop(struct usb_gadget *g) { struct s3c2410_udc *udc = to_s3c2410(g); diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 52f457bb0bbc..135504b60425 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -204,7 +204,7 @@ static inline int usb_gadget_udc_start(struct usb_udc *udc) */ static inline void usb_gadget_udc_stop(struct usb_udc *udc) { - udc->gadget->ops->udc_stop(udc->gadget, udc->driver); + udc->gadget->ops->udc_stop(udc->gadget); } /** diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index ed27e1687a4e..1eac56fc384d 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -1403,8 +1403,7 @@ static int xudc_start(struct usb_gadget *gadget, * * Return: zero always */ -static int xudc_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int xudc_stop(struct usb_gadget *gadget) { struct xusb_udc *udc = to_udc(gadget); unsigned long flags; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 88d63e0c79f5..4ab1896957e1 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1684,8 +1684,7 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) static int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver); -static int musb_gadget_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver); +static int musb_gadget_stop(struct usb_gadget *g); static const struct usb_gadget_ops musb_gadget_operations = { .get_frame = musb_gadget_get_frame, @@ -1923,8 +1922,7 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) * * @param driver the gadget driver to unregister */ -static int musb_gadget_stop(struct usb_gadget *g, - struct usb_gadget_driver *driver) +static int musb_gadget_stop(struct usb_gadget *g) { struct musb *musb = gadget_to_musb(g); unsigned long flags; diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 2d17c10a0428..7a4521030505 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -851,8 +851,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); } -static int usbhsg_gadget_stop(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) +static int usbhsg_gadget_stop(struct usb_gadget *gadget) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 522cafe26790..70965fc829d3 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -490,8 +490,7 @@ struct usb_gadget_ops { void (*get_config_params)(struct usb_dcd_config_params *); int (*udc_start)(struct usb_gadget *, struct usb_gadget_driver *); - int (*udc_stop)(struct usb_gadget *, - struct usb_gadget_driver *); + int (*udc_stop)(struct usb_gadget *); }; /** -- GitLab From 02e8c966274f1049cca8d3f17092f8275979b8eb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 18:57:06 -0500 Subject: [PATCH 2600/9457] usb: gadget: udc: core: prepend udc_attach_driver with usb_ No functional changes, just adding a prefix which should have been there from the start. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 2 +- drivers/usb/gadget/udc/udc-core.c | 4 ++-- include/linux/usb/gadget.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index d25f9f3dfea0..75648145dc1b 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -271,7 +271,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct gadget_info *gi, ret = -EBUSY; goto err; } - ret = udc_attach_driver(name, &gi->composite.gadget_driver); + ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver); if (ret) goto err; gi->udc_name = name; diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 135504b60425..e31d574d8860 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -411,7 +411,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri return ret; } -int udc_attach_driver(const char *name, struct usb_gadget_driver *driver) +int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; int ret = -ENODEV; @@ -435,7 +435,7 @@ int udc_attach_driver(const char *name, struct usb_gadget_driver *driver) mutex_unlock(&udc_lock); return ret; } -EXPORT_SYMBOL_GPL(udc_attach_driver); +EXPORT_SYMBOL_GPL(usb_udc_attach_driver); int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 70965fc829d3..70ddb3943b62 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -924,7 +924,7 @@ extern int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)); extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); -extern int udc_attach_driver(const char *name, +extern int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver); /*-------------------------------------------------------------------------*/ -- GitLab From 545d64a46c1ed04eb96802a3bf5b6627c4d28dbd Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Fri, 17 Oct 2014 22:43:04 +0200 Subject: [PATCH 2601/9457] usb: gadget: pxa27x_udc device-tree documentation Add documentation for device-tree binding of arm PXA 27x udc (usb device) driver. Signed-off-by: Robert Jarzmik Cc: devicetree@vger.kernel.org Acked-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/pxa-usb.txt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/pxa-usb.txt b/Documentation/devicetree/bindings/usb/pxa-usb.txt index 79729a948d5a..9c331799b87c 100644 --- a/Documentation/devicetree/bindings/usb/pxa-usb.txt +++ b/Documentation/devicetree/bindings/usb/pxa-usb.txt @@ -29,3 +29,25 @@ Example: marvell,port-mode = <2>; /* PMM_GLOBAL_MODE */ }; +UDC + +Required properties: + - compatible: Should be "marvell,pxa270-udc" for USB controllers + used in device mode. + - reg: usb device MMIO address space + - interrupts: single interrupt generated by the UDC IP + - clocks: input clock of the UDC IP (see clock-bindings.txt) + +Optional properties: + - gpios: + - gpio activated to control the USB D+ pullup (see gpio.txt) + +Example: + + pxa27x_udc: udc@40600000 { + compatible = "marvell,pxa270-udc"; + reg = <0x40600000 0x10000>; + interrupts = <11>; + clocks = <&pxa2xx_clks 11>; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + }; -- GitLab From 95fcc6a9014f1ea6419d1e8ce796173410c5ad63 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Fri, 17 Oct 2014 22:43:05 +0200 Subject: [PATCH 2602/9457] usb: gadget: pxa27x_udc: use devm_* helpers Use devm_* helpers in the probe function to simplify the error path and the remove path. Signed-off-by: Robert Jarzmik Cc: Sergei Shtylyov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 45 +++++++++-------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 17a0193b5e01..c7deac4a3aa9 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2438,8 +2438,9 @@ static int pxa_udc_probe(struct platform_device *pdev) } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; + udc->regs = devm_ioremap_resource(&pdev->dev, regs); + if (IS_ERR(udc->regs)) + return PTR_ERR(udc->regs); udc->irq = platform_get_irq(pdev, 0); if (udc->irq < 0) return udc->irq; @@ -2455,21 +2456,13 @@ static int pxa_udc_probe(struct platform_device *pdev) if (udc->gpiod) gpiod_direction_output(udc->gpiod, 0); - udc->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(udc->clk)) { - retval = PTR_ERR(udc->clk); - goto err_clk; - } + udc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(udc->clk)) + return PTR_ERR(udc->clk); + retval = clk_prepare(udc->clk); if (retval) - goto err_clk_prepare; - - retval = -ENOMEM; - udc->regs = ioremap(regs->start, resource_size(regs)); - if (!udc->regs) { - dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); - goto err_map; - } + return retval; udc->vbus_sensed = 0; @@ -2479,32 +2472,23 @@ static int pxa_udc_probe(struct platform_device *pdev) pxa_eps_setup(udc); /* irq setup after old hardware state is cleaned up */ - retval = request_irq(udc->irq, pxa_udc_irq, - IRQF_SHARED, driver_name, udc); + retval = devm_request_irq(&pdev->dev, udc->irq, pxa_udc_irq, + IRQF_SHARED, driver_name, udc); if (retval != 0) { dev_err(udc->dev, "%s: can't get irq %i, err %d\n", driver_name, udc->irq, retval); - goto err_irq; + goto err; } retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (retval) - goto err_add_udc; + goto err; pxa_init_debugfs(udc); return 0; - -err_add_udc: - free_irq(udc->irq, udc); -err_irq: - iounmap(udc->regs); -err_map: +err: clk_unprepare(udc->clk); -err_clk_prepare: - clk_put(udc->clk); - udc->clk = NULL; -err_clk: return retval; } @@ -2518,7 +2502,6 @@ static int pxa_udc_remove(struct platform_device *_dev) usb_del_gadget_udc(&udc->gadget); usb_gadget_unregister_driver(udc->driver); - free_irq(udc->irq, udc); pxa_cleanup_debugfs(udc); usb_put_phy(udc->transceiver); @@ -2526,8 +2509,6 @@ static int pxa_udc_remove(struct platform_device *_dev) udc->transceiver = NULL; the_controller = NULL; clk_unprepare(udc->clk); - clk_put(udc->clk); - iounmap(udc->regs); return 0; } -- GitLab From f4fd094cdfd124d7653a500e81ec3bb7ae3e9919 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Fri, 17 Oct 2014 22:43:06 +0200 Subject: [PATCH 2603/9457] usb: gadget: pxa27x_udc: fix clock prepare and enable As the udc clock controls both the output signals and the internal IP, it must be enabled before any UDC register is touched. The bug is revealed when the clock framework disables the clock for a couple of milliseconds during the boot sequence, and the endpoint configuration is lost. The bug is hidden when clock framework is not used, because no "unused clocks disable" occurs. This patch fixes the wrong behaviour by ensuring that : - whenever a UDC register is read or written, the clock is enabled - reworks the endpoints programming to have it done under running clock - reworks suspend/resume to ensure the same thing Signed-off-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index c7deac4a3aa9..dd6890d918b6 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -1698,10 +1698,10 @@ static void udc_disable(struct pxa_udc *udc) udc_writel(udc, UDCICR1, 0); udc_clear_mask_UDCCR(udc, UDCCR_UDE); - clk_disable(udc->clk); ep0_idle(udc); udc->gadget.speed = USB_SPEED_UNKNOWN; + clk_disable(udc->clk); udc->enabled = 0; } @@ -1754,16 +1754,16 @@ static void udc_enable(struct pxa_udc *udc) if (udc->enabled) return; + clk_enable(udc->clk); udc_writel(udc, UDCICR0, 0); udc_writel(udc, UDCICR1, 0); udc_clear_mask_UDCCR(udc, UDCCR_UDE); - clk_enable(udc->clk); - ep0_idle(udc); udc->gadget.speed = USB_SPEED_FULL; memset(&udc->stats, 0, sizeof(udc->stats)); + pxa_eps_setup(udc); udc_set_mask_UDCCR(udc, UDCCR_UDE); ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_ACM); udelay(2); @@ -2469,7 +2469,6 @@ static int pxa_udc_probe(struct platform_device *pdev) the_controller = udc; platform_set_drvdata(pdev, udc); udc_init_data(udc); - pxa_eps_setup(udc); /* irq setup after old hardware state is cleaned up */ retval = devm_request_irq(&pdev->dev, udc->irq, pxa_udc_irq, @@ -2485,7 +2484,8 @@ static int pxa_udc_probe(struct platform_device *pdev) goto err; pxa_init_debugfs(udc); - + if (should_enable_udc(udc)) + udc_enable(udc); return 0; err: clk_unprepare(udc->clk); @@ -2538,19 +2538,11 @@ extern void pxa27x_clear_otgph(void); */ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) { - int i; struct pxa_udc *udc = platform_get_drvdata(_dev); struct pxa_ep *ep; ep = &udc->pxa_ep[0]; udc->udccsr0 = udc_ep_readl(ep, UDCCSR); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - ep->udccsr_value = udc_ep_readl(ep, UDCCSR); - ep->udccr_value = udc_ep_readl(ep, UDCCR); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } udc_disable(udc); udc->pullup_resume = udc->pullup_on; @@ -2568,19 +2560,11 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) */ static int pxa_udc_resume(struct platform_device *_dev) { - int i; struct pxa_udc *udc = platform_get_drvdata(_dev); struct pxa_ep *ep; ep = &udc->pxa_ep[0]; udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - udc_ep_writel(ep, UDCCSR, ep->udccsr_value); - udc_ep_writel(ep, UDCCR, ep->udccr_value); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } dplus_pullup(udc, udc->pullup_resume); if (should_enable_udc(udc)) -- GitLab From 0d3ca262699fd6d7c5dcc25ff29a711851797117 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 20:15:08 -0500 Subject: [PATCH 2604/9457] usb: dwc2: gadget: do not call usb_gadget_unregister_driver() that call is completely unnecessary because usb_del_gadget_udc() already makes sure the gadget driver is properly unregistered from the UDC. Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 441f1c4b8eb4..701d3e142bbf 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3605,14 +3605,7 @@ static int s3c_hsotg_remove(struct platform_device *pdev) struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); usb_del_gadget_udc(&hsotg->gadget); - s3c_hsotg_delete_debug(hsotg); - - if (hsotg->driver) { - /* should have been done already by driver model core */ - usb_gadget_unregister_driver(hsotg->driver); - } - clk_disable_unprepare(hsotg->clk); return 0; -- GitLab From c77f570fe2ec9d205cdd90805dd78fcd70b860ec Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 20:18:23 -0500 Subject: [PATCH 2605/9457] usb: gadget: udc: dummy: do not call usb_gadget_unregister_driver() that call is completely unnecessary because usb_del_gadget_udc() already makes sure the gadget driver is properly unregistered from the UDC. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 5bffb75922f8..254b9e7659f3 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -2362,7 +2362,6 @@ static void dummy_stop(struct usb_hcd *hcd) dum = hcd_to_dummy_hcd(hcd)->dum; device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); - usb_gadget_unregister_driver(dum->driver); dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); } -- GitLab From 7fd1f9d6663fa20997d2d951ef7ee7e2cd0d266e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 20:19:02 -0500 Subject: [PATCH 2606/9457] usb: gadget: udc: net2272: do not call usb_gadget_unregister_driver() that call is completely unnecessary because usb_del_gadget_udc() already makes sure the gadget driver is properly unregistered from the UDC. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2272.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 887bea42e5aa..ab3a73950d8f 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -2195,18 +2195,8 @@ static void net2272_remove(struct net2272 *dev) { usb_del_gadget_udc(&dev->gadget); - - /* start with the driver above us */ - if (dev->driver) { - /* should have been done already by driver model core */ - dev_warn(dev->dev, "pci remove, driver '%s' is still registered\n", - dev->driver->driver.name); - usb_gadget_unregister_driver(dev->driver); - } - free_irq(dev->irq, dev); iounmap(dev->base_addr); - device_remove_file(dev->dev, &dev_attr_registers); dev_info(dev->dev, "unbind\n"); -- GitLab From 76bfa95eab10f6bfd7e7d33a9b7cccbefa036f5c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 17 Oct 2014 20:19:41 -0500 Subject: [PATCH 2607/9457] usb: gadget: udc: pxa27x: do not call usb_gadget_unregister_driver() that call is completely unnecessary because usb_del_gadget_udc() already makes sure the gadget driver is properly unregistered from the UDC. Acked-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index dd6890d918b6..69e7b816d880 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2501,7 +2501,6 @@ static int pxa_udc_remove(struct platform_device *_dev) struct pxa_udc *udc = platform_get_drvdata(_dev); usb_del_gadget_udc(&udc->gadget); - usb_gadget_unregister_driver(udc->driver); pxa_cleanup_debugfs(udc); usb_put_phy(udc->transceiver); -- GitLab From 5a8053099c4a3fb47189575be34350ac40fb6080 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 24 Oct 2014 00:34:12 +0400 Subject: [PATCH 2608/9457] usb: musb: omap2430: use MUSB_DEVCTL_BDEVICE The OMAP2+ MUSB glue layer still uses a bare number for the DEVCTL.B-Device bit in one place, while there's #define MUSB_DEVCTL_BDEVICE for that. Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 6669f2611e91..20fc2a532a24 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -162,7 +162,8 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) * Wait for the musb to set as A device to enable the * VBUS */ - while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { + while (musb_readb(musb->mregs, MUSB_DEVCTL) & + MUSB_DEVCTL_BDEVICE) { mdelay(5); cpu_relax(); -- GitLab From 4d852011a505005aab50250b211c132a654cb507 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 21:30:15 +0530 Subject: [PATCH 2609/9457] usb: dwc3: keystone: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-keystone.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 7ec8495f4523..dd8d2df6db31 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -104,11 +104,6 @@ static int kdwc3_probe(struct platform_device *pdev) kdwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing usbss resource\n"); - return -EINVAL; - } - kdwc->usbss = devm_ioremap_resource(dev, res); if (IS_ERR(kdwc->usbss)) return PTR_ERR(kdwc->usbss); -- GitLab From 687f16b8599bed84dc4484a70509b9443dfc3baa Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 21:30:16 +0530 Subject: [PATCH 2610/9457] usb: renesas_usbhs: common: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 6dae1151569b..169307ba08b7 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -496,9 +496,8 @@ static int usbhs_probe(struct platform_device *pdev) } /* platform data */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res || !irq_res) { + if (!irq_res) { dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); return -ENODEV; } @@ -508,6 +507,7 @@ static int usbhs_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); -- GitLab From 28a26945df3ac3a4c80eef48b73be88fb53744ae Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 21:30:17 +0530 Subject: [PATCH 2611/9457] usb: phy: rcar-usb: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-rcar-usb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c index 487959620141..1e09b8377885 100644 --- a/drivers/usb/phy/phy-rcar-usb.c +++ b/drivers/usb/phy/phy-rcar-usb.c @@ -195,11 +195,9 @@ static int rcar_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(reg0); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (res1) { - reg1 = devm_ioremap_resource(dev, res1); - if (IS_ERR(reg1)) - return PTR_ERR(reg1); - } + reg1 = devm_ioremap_resource(dev, res1); + if (IS_ERR(reg1)) + return PTR_ERR(reg1); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) -- GitLab From 768330756d9bbfee6eca573b96c828adb1ba9058 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 21:30:18 +0530 Subject: [PATCH 2612/9457] usb: musb: dsps: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 6209456861b6..759ef1d236b2 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -447,9 +447,6 @@ static int dsps_musb_init(struct musb *musb) int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); - if (!r) - return -EINVAL; - reg_base = devm_ioremap_resource(dev, r); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); -- GitLab From 1f79b26cf3090f024b3a02cfc3b692bc6482c576 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Wed, 29 Oct 2014 21:30:19 +0530 Subject: [PATCH 2613/9457] usb: musb: core: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b841ee0bff06..55ebd4b1daac 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2080,10 +2080,10 @@ static int musb_probe(struct platform_device *pdev) struct resource *iomem; void __iomem *base; - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iomem || irq <= 0) + if (irq <= 0) return -ENODEV; + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, iomem); if (IS_ERR(base)) return PTR_ERR(base); -- GitLab From ac3c81f3e8dcb435a92e03e2fa069d1e60687cfe Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Oct 2014 12:45:35 +0200 Subject: [PATCH 2614/9457] usb: dwc2: gadget: move setting last reset time to s3c_hsotg_core_init This patch removes duplicated code and sets last_rst variable in the function which does the hardware reset. Acked-by: Paul Zimmerman Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 701d3e142bbf..f1cde255570a 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2247,6 +2247,8 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) /* must be at-least 3ms to allow bus to see disconnect */ mdelay(3); + hsotg->last_rst = jiffies; + /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); } @@ -2341,7 +2343,6 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) -ECONNRESET, true); s3c_hsotg_core_init(hsotg); - hsotg->last_rst = jiffies; } } } @@ -2905,7 +2906,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, goto err; } - hsotg->last_rst = jiffies; dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); return 0; @@ -3656,7 +3656,6 @@ static int s3c_hsotg_resume(struct platform_device *pdev) } spin_lock_irqsave(&hsotg->lock, flags); - hsotg->last_rst = jiffies; s3c_hsotg_phy_enable(hsotg); s3c_hsotg_core_init(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); -- GitLab From ad38dc5dac5d8df80c0c394459f950eed1dccbcd Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Oct 2014 12:45:36 +0200 Subject: [PATCH 2615/9457] usb: dwc2: gadget: decouple setting soft-disconnect from s3c_hsotg_core_init This patch changes s3c_hsotg_core_init function to leave hardware in soft disconnect mode, so the moment of coupling the hardware to the usb bus can be later controlled by the separate functions for enabling and disabling soft disconnect mode. This patch is a preparation to rework pullup() method. Acked-by: Paul Zimmerman Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index f1cde255570a..5109936c4f33 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2124,7 +2124,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) +static void s3c_hsotg_core_init_disconnected(struct s3c_hsotg *hsotg) { s3c_hsotg_corereset(hsotg); @@ -2241,14 +2241,23 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) readl(hsotg->regs + DOEPCTL0)); /* clear global NAKs */ - writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK, + writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON, hsotg->regs + DCTL); /* must be at-least 3ms to allow bus to see disconnect */ mdelay(3); hsotg->last_rst = jiffies; +} + +static void s3c_hsotg_core_disconnect(struct s3c_hsotg *hsotg) +{ + /* set the soft-disconnect bit */ + __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); +} +static void s3c_hsotg_core_connect(struct s3c_hsotg *hsotg) +{ /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); } @@ -2342,7 +2351,8 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); - s3c_hsotg_core_init(hsotg); + s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_connect(hsotg); } } } @@ -2977,7 +2987,8 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) if (is_on) { s3c_hsotg_phy_enable(hsotg); clk_enable(hsotg->clk); - s3c_hsotg_core_init(hsotg); + s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_connect(hsotg); } else { clk_disable(hsotg->clk); s3c_hsotg_phy_disable(hsotg); @@ -3657,7 +3668,8 @@ static int s3c_hsotg_resume(struct platform_device *pdev) spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_phy_enable(hsotg); - s3c_hsotg_core_init(hsotg); + s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); return ret; -- GitLab From c816c47fe6205b18ff6f8843c258ca35c1536dac Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Oct 2014 12:45:37 +0200 Subject: [PATCH 2616/9457] usb: dwc2: gadget: move phy control calls out of pullup() method This patch moves phy enable/disable calls from pullup() method to udc_start/stop functions. This solves the issue related to limited caller context for PHY functions, because they cannot be called from non-sleeping context. This is also a preparation for using soft-disconnect feature of udc controller in pullup() method. Acked-by: Paul Zimmerman Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5109936c4f33..68865e5f759b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2916,6 +2916,8 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, goto err; } + s3c_hsotg_phy_enable(hsotg); + dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); return 0; @@ -2951,6 +2953,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) spin_unlock_irqrestore(&hsotg->lock, flags); + s3c_hsotg_phy_disable(hsotg); + regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); clk_disable(hsotg->clk); @@ -2985,13 +2989,11 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { - s3c_hsotg_phy_enable(hsotg); clk_enable(hsotg->clk); s3c_hsotg_core_init_disconnected(hsotg); s3c_hsotg_core_connect(hsotg); } else { clk_disable(hsotg->clk); - s3c_hsotg_phy_disable(hsotg); } hsotg->gadget.speed = USB_SPEED_UNKNOWN; -- GitLab From 5b9451f8c4fbaf0549139755fb45ff2b57975b7f Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Oct 2014 12:45:38 +0200 Subject: [PATCH 2617/9457] usb: dwc2: gadget: use soft-disconnect udc feature in pullup() method This patch moves udc initialization from pullup() method to s3c_hsotg_udc_start(), so that method ends with hardware fully initialized and left in soft-disconnected state. After this change, the pullup() method simply clears soft-disconnect start() when called with is_on=1. For completeness, a call to s3c_hsotg_core_disconnect() has been added when pullup() method is called with is_on=0, what puts the udc hardware back to soft-disconnected state. Acked-by: Paul Zimmerman Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 68865e5f759b..5872db97699f 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2880,6 +2880,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct s3c_hsotg *hsotg = to_hsotg(gadget); + unsigned long flags; int ret; if (!hsotg) { @@ -2918,7 +2919,13 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, s3c_hsotg_phy_enable(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); + s3c_hsotg_init(hsotg); + s3c_hsotg_core_init_disconnected(hsotg); + spin_unlock_irqrestore(&hsotg->lock, flags); + dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); + return 0; err: @@ -2990,9 +2997,9 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { clk_enable(hsotg->clk); - s3c_hsotg_core_init_disconnected(hsotg); s3c_hsotg_core_connect(hsotg); } else { + s3c_hsotg_core_disconnect(hsotg); clk_disable(hsotg->clk); } -- GitLab From 7b093f773b85dd816c5717193ec94a7cfec73a09 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Oct 2014 12:45:39 +0200 Subject: [PATCH 2618/9457] usb: dwc2: gadget: fix calls to phy control functions in suspend/resume code This patch moves calls to phy enable/disable out of spinlock protected blocks in device suspend/resume to fix incorrect caller context. Phy related functions must not be called from atomic context. To protect device internal state from a race during suspend, a call to s3c_hsotg_core_disconnect() is added under a spinlock, what prevents any further activity on the usb bus. Acked-by: Paul Zimmerman Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5872db97699f..fcd2bb55ccca 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3642,11 +3642,13 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) hsotg->driver->driver.name); spin_lock_irqsave(&hsotg->lock, flags); + s3c_hsotg_core_disconnect(hsotg); s3c_hsotg_disconnect(hsotg); - s3c_hsotg_phy_disable(hsotg); hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); + s3c_hsotg_phy_disable(hsotg); + if (hsotg->driver) { int ep; for (ep = 0; ep < hsotg->num_of_eps; ep++) @@ -3675,8 +3677,9 @@ static int s3c_hsotg_resume(struct platform_device *pdev) hsotg->supplies); } - spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_phy_enable(hsotg); + + spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_core_init_disconnected(hsotg); s3c_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); -- GitLab From 3e87d9a3dee0ad5416c3fb599a6019a24bfe6e64 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 27 Oct 2014 10:49:42 +0100 Subject: [PATCH 2619/9457] usb: musb: core: use ->resume instead ->resume_noirq In commit 0ec8fd70fb ("USB: musb: fix possible panic while resuming") musb_resume() became musb_resume_early() in order to enable the clocks early on resume. This piece of the resume code was removed later in commit 034917612 ("usb: musb: move clock handling to glue layer"). In between the function was renamed from musb_resume_early() to musb_resume_noirq() by commit commit 48fea9659e ("USB: Rework musb suspend()/resume_early()"). Now I see that first musb_core is resumed followed by phy and glue layer and I ask myself is this really what we intend to do? This kind of revoked the purpose of the first commit (0ec8fd70fb). Because of this and because it looks wrong to resume (core) before the glue layer I push it to the ->resume callback. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 55ebd4b1daac..e46e295a383a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2297,7 +2297,7 @@ static int musb_suspend(struct device *dev) return 0; } -static int musb_resume_noirq(struct device *dev) +static int musb_resume(struct device *dev) { struct musb *musb = dev_to_musb(dev); @@ -2348,7 +2348,7 @@ static int musb_runtime_resume(struct device *dev) static const struct dev_pm_ops musb_dev_pm_ops = { .suspend = musb_suspend, - .resume_noirq = musb_resume_noirq, + .resume = musb_resume, .runtime_suspend = musb_runtime_suspend, .runtime_resume = musb_runtime_resume, }; -- GitLab From 8b920f16e69550d3f6c7c67dc3cef42aafca498d Mon Sep 17 00:00:00 2001 From: Pavitrakumar Managutte Date: Mon, 27 Oct 2014 22:49:26 +0530 Subject: [PATCH 2620/9457] usb: gadget: function: Added usb_assign_descriptors failure check Added failure check for usb_assign_descriptors call in bind function. Acked-By: Sebastian Andrzej Siewior Signed-off-by: Pavitrakumar Managutte Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_ncm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 16361b0a8b46..bdcda9f5148e 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1441,6 +1441,9 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, NULL); + if (status) + goto fail; + /* * NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code -- GitLab From a2655e4a8edb66d21b0967940172e83a51d30ef3 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Wed, 29 Oct 2014 22:18:55 +0800 Subject: [PATCH 2621/9457] usb: gadget: fix ptr_ret.cocci warnings drivers/usb/gadget/udc/r8a66597-udc.c:1849:1-3: WARNING: PTR_ERR_OR_ZERO can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: scripts/coccinelle/api/ptr_ret.cocci Signed-off-by: Fengguang Wu Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/r8a66597-udc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index b63a527baf13..be31b57a8ba1 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1845,10 +1845,7 @@ static int r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); r8a66597->sudmac_reg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(r8a66597->sudmac_reg)) - return PTR_ERR(r8a66597->sudmac_reg); - - return 0; + return PTR_ERR_OR_ZERO(r8a66597->sudmac_reg); } static int r8a66597_probe(struct platform_device *pdev) -- GitLab From e47d92545c2972bcf3711e7db80f481e402163c7 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:13 +0100 Subject: [PATCH 2622/9457] usb: move the OTG state from the USB PHY to the OTG structure Before using the PHY framework instead of the USB PHY one, we need to move the OTG state into another place, since it won't be available when USB PHY isn't used. This patch moves the OTG state into the OTG structure, and makes all the needed modifications in the drivers using the OTG state. [ balbi@ti.com : fix build regressions with phy-tahvo.c, musb_dsps.c, phy-isp1301-omap, and chipidea's debug.c ] Acked-by: Kishon Vijay Abraham I Acked-by: Peter Chen Signed-off-by: Antoine Tenart Signed-off-by: Felipe Balbi --- drivers/phy/phy-omap-usb2.c | 8 +-- drivers/usb/chipidea/debug.c | 2 +- drivers/usb/chipidea/otg_fsm.c | 12 ++-- drivers/usb/common/usb-otg-fsm.c | 8 +-- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/musb/am35x.c | 28 ++++----- drivers/usb/musb/blackfin.c | 18 +++--- drivers/usb/musb/da8xx.c | 28 ++++----- drivers/usb/musb/davinci.c | 18 +++--- drivers/usb/musb/musb_core.c | 94 ++++++++++++++--------------- drivers/usb/musb/musb_dsps.c | 28 ++++----- drivers/usb/musb/musb_gadget.c | 36 +++++------ drivers/usb/musb/musb_host.c | 8 +-- drivers/usb/musb/musb_virthub.c | 22 +++---- drivers/usb/musb/omap2430.c | 30 ++++----- drivers/usb/musb/tusb6010.c | 40 ++++++------ drivers/usb/musb/ux500.c | 10 +-- drivers/usb/phy/phy-ab8500-usb.c | 10 +-- drivers/usb/phy/phy-fsl-usb.c | 10 +-- drivers/usb/phy/phy-generic.c | 4 +- drivers/usb/phy/phy-gpio-vbus-usb.c | 10 +-- drivers/usb/phy/phy-isp1301-omap.c | 94 ++++++++++++++--------------- drivers/usb/phy/phy-msm-usb.c | 34 +++++------ drivers/usb/phy/phy-mv-usb.c | 46 +++++++------- drivers/usb/phy/phy-tahvo.c | 24 ++++---- include/linux/usb/otg.h | 2 + include/linux/usb/phy.h | 1 - 27 files changed, 312 insertions(+), 315 deletions(-) diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 8c842980834a..9f4093590f4c 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -80,11 +80,9 @@ static int omap_usb_start_srp(struct usb_otg *otg) static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) { - struct usb_phy *phy = otg->phy; - otg->host = host; if (!host) - phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; return 0; } @@ -92,11 +90,9 @@ static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) static int omap_usb_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { - struct usb_phy *phy = otg->phy; - otg->gadget = gadget; if (!gadget) - phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; return 0; } diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 795d6538d630..f038804d13dd 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused) /* ------ State ----- */ seq_printf(s, "OTG state: %s\n\n", - usb_otg_state_string(ci->transceiver->state)); + usb_otg_state_string(ci->transceiver->otg->state)); /* ------ State Machine Variables ----- */ seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop); diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index caaabc58021e..8cb2508a6b71 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -328,7 +328,7 @@ static void b_ssend_srp_tmout_func(void *ptr, unsigned long indicator) set_tmout(ci, indicator); /* only vbus fall below B_sess_vld in b_idle state */ - if (ci->transceiver->state == OTG_STATE_B_IDLE) + if (ci->fsm.otg->state == OTG_STATE_B_IDLE) ci_otg_queue_work(ci); } @@ -582,11 +582,11 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) * when there is no gadget class driver */ if (ci->fsm.id && !(ci->driver) && - ci->transceiver->state < OTG_STATE_A_IDLE) + ci->fsm.otg->state < OTG_STATE_A_IDLE) return 0; if (otg_statemachine(&ci->fsm)) { - if (ci->transceiver->state == OTG_STATE_A_IDLE) { + if (ci->fsm.otg->state == OTG_STATE_A_IDLE) { /* * Further state change for cases: * a_idle to b_idle; or @@ -600,7 +600,7 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) ci_otg_queue_work(ci); if (ci->id_event) ci->id_event = false; - } else if (ci->transceiver->state == OTG_STATE_B_IDLE) { + } else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) { if (ci->fsm.b_sess_vld) { ci->fsm.power_up = 0; /* @@ -627,7 +627,7 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci) otg_bsess_vld = hw_read_otgsc(ci, OTGSC_BSV); port_conn = hw_read(ci, OP_PORTSC, PORTSC_CCS); - switch (ci->transceiver->state) { + switch (ci->fsm.otg->state) { case OTG_STATE_A_WAIT_BCON: if (port_conn) { fsm->b_conn = 1; @@ -794,7 +794,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) ci->transceiver->otg = ci->fsm.otg; ci->fsm.power_up = 1; ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; - ci->transceiver->state = OTG_STATE_UNDEFINED; + ci->fsm.otg->state = OTG_STATE_UNDEFINED; ci->fsm.ops = &ci_otg_ops; mutex_init(&ci->fsm.lock); diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c index 98e8340a5bb1..c6b35b77dab7 100644 --- a/drivers/usb/common/usb-otg-fsm.c +++ b/drivers/usb/common/usb-otg-fsm.c @@ -124,10 +124,10 @@ static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) { state_changed = 1; - if (fsm->otg->phy->state == new_state) + if (fsm->otg->state == new_state) return 0; VDBG("Set state: %s\n", usb_otg_state_string(new_state)); - otg_leave_state(fsm, fsm->otg->phy->state); + otg_leave_state(fsm, fsm->otg->state); switch (new_state) { case OTG_STATE_B_IDLE: otg_drv_vbus(fsm, 0); @@ -236,7 +236,7 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) break; } - fsm->otg->phy->state = new_state; + fsm->otg->state = new_state; return 0; } @@ -247,7 +247,7 @@ int otg_statemachine(struct otg_fsm *fsm) mutex_lock(&fsm->lock); - state = fsm->otg->phy->state; + state = fsm->otg->state; state_changed = 0; /* State machine state change judgement */ diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 0231606d47c2..cf89b4b17f14 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -183,7 +183,7 @@ static void start_hnp(struct ohci_hcd *ohci) otg_start_hnp(hcd->usb_phy->otg); local_irq_save(flags); - hcd->usb_phy->state = OTG_STATE_A_SUSPEND; + hcd->usb_phy->otg.state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); l = omap_readl(OTG_CTRL); l &= ~OTG_A_BUSREQ; diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index a2735df24cc6..d836a3e1f8ec 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -149,25 +149,25 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: devctl &= ~MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } else { - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } break; case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG, MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT); break; @@ -176,7 +176,7 @@ static void otg_timer(unsigned long _musb) if (devctl & MUSB_DEVCTL_BDEVICE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); else - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; break; default: break; @@ -193,9 +193,9 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || (musb->a_wait_bcon == 0 && - musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { + musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -208,7 +208,7 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -278,27 +278,27 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) * devctl. */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; portstate(musb->port1_status |= USB_PORT_STAT_POWER); del_timer(&otg_workaround); } else { musb->is_active = 0; MUSB_DEV_MODE(musb); otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); } /* NOTE: this must complete power-on within 100 ms. */ dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; @@ -324,7 +324,7 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) } /* Poll for ID change */ - if (musb->xceiv->state == OTG_STATE_B_IDLE) + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); spin_unlock_irqrestore(&musb->lock, flags); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 8554c6f7ab72..f23ce40b4d64 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -185,8 +185,8 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) } /* Start sampling ID pin, when plug is removed from MUSB */ - if ((musb->xceiv->state == OTG_STATE_B_IDLE - || musb->xceiv->state == OTG_STATE_A_WAIT_BCON) || + if ((musb->xceiv->otg->state == OTG_STATE_B_IDLE + || musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON) || (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); musb->a_wait_bcon = TIMER_DELAY; @@ -205,7 +205,7 @@ static void musb_conn_timer_handler(unsigned long _musb) static u8 toggle; spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_IDLE: case OTG_STATE_A_WAIT_BCON: /* Start a new session */ @@ -219,7 +219,7 @@ static void musb_conn_timer_handler(unsigned long _musb) if (!(val & MUSB_DEVCTL_BDEVICE)) { gpio_set_value(musb->config->gpio_vrsel, 1); - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; } else { gpio_set_value(musb->config->gpio_vrsel, 0); /* Ignore VBUSERROR and SUSPEND IRQ */ @@ -229,7 +229,7 @@ static void musb_conn_timer_handler(unsigned long _musb) val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; musb_writeb(musb->mregs, MUSB_INTRUSB, val); - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; } mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); break; @@ -245,7 +245,7 @@ static void musb_conn_timer_handler(unsigned long _musb) if (!(val & MUSB_DEVCTL_BDEVICE)) { gpio_set_value(musb->config->gpio_vrsel, 1); - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; } else { gpio_set_value(musb->config->gpio_vrsel, 0); @@ -280,13 +280,13 @@ static void musb_conn_timer_handler(unsigned long _musb) break; default: dev_dbg(musb->controller, "%s state not handled\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); break; } spin_unlock_irqrestore(&musb->lock, flags); dev_dbg(musb->controller, "state is %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } static void bfin_musb_enable(struct musb *musb) @@ -307,7 +307,7 @@ static void bfin_musb_set_vbus(struct musb *musb, int is_on) dev_dbg(musb->controller, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 058775e647ad..527c7fe60ece 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -198,20 +198,20 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: devctl &= ~MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } else { - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } break; @@ -226,7 +226,7 @@ static void otg_timer(unsigned long _musb) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); break; } - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG, MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT); break; @@ -248,7 +248,7 @@ static void otg_timer(unsigned long _musb) if (devctl & MUSB_DEVCTL_BDEVICE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); else - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; break; default: break; @@ -265,9 +265,9 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || (musb->a_wait_bcon == 0 && - musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { + musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -280,7 +280,7 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -341,26 +341,26 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) * devctl. */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; portstate(musb->port1_status |= USB_PORT_STAT_POWER); del_timer(&otg_workaround); } else { musb->is_active = 0; MUSB_DEV_MODE(musb); otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); } dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; @@ -375,7 +375,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); /* Poll for ID change */ - if (musb->xceiv->state == OTG_STATE_B_IDLE) + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); spin_unlock_irqrestore(&musb->lock, flags); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 04de3aca938d..3c1d9b211b51 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -214,10 +214,10 @@ static void otg_timer(unsigned long _musb) */ devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_VFALL: /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL * seems to mis-handle session "start" otherwise (or in our @@ -228,7 +228,7 @@ static void otg_timer(unsigned long _musb) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); break; } - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); break; @@ -251,7 +251,7 @@ static void otg_timer(unsigned long _musb) if (devctl & MUSB_DEVCTL_BDEVICE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); else - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; break; default: break; @@ -325,20 +325,20 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) * to stop registering in devctl. */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; portstate(musb->port1_status |= USB_PORT_STAT_POWER); del_timer(&otg_workaround); } else { musb->is_active = 0; MUSB_DEV_MODE(musb); otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); } @@ -348,7 +348,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) davinci_musb_source_power(musb, drvvbus, 0); dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), err ? " ERROR" : "", devctl); retval = IRQ_HANDLED; @@ -361,7 +361,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) musb_writel(tibase, DAVINCI_USB_EOI_REG, 0); /* poll for ID change */ - if (musb->xceiv->state == OTG_STATE_B_IDLE) + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); spin_unlock_irqrestore(&musb->lock, flags); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e46e295a383a..df9c5fa2772e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -360,23 +360,23 @@ static void musb_otg_timer_func(unsigned long data) unsigned long flags; spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_B_WAIT_ACON: dev_dbg(musb->controller, "HNP: b_wait_acon timeout; back to b_peripheral\n"); musb_g_disconnect(musb); - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb->is_active = 0; break; case OTG_STATE_A_SUSPEND: case OTG_STATE_A_WAIT_BCON: dev_dbg(musb->controller, "HNP: %s timeout\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); musb_platform_set_vbus(musb, 0); - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; break; default: dev_dbg(musb->controller, "HNP: Unhandled mode %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } spin_unlock_irqrestore(&musb->lock, flags); } @@ -391,19 +391,19 @@ void musb_hnp_stop(struct musb *musb) u8 reg; dev_dbg(musb->controller, "HNP: stop from %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); dev_dbg(musb->controller, "HNP: back to %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); break; case OTG_STATE_B_HOST: dev_dbg(musb->controller, "HNP: Disabling HR\n"); if (hcd) hcd->self.is_b_host = 0; - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; MUSB_DEV_MODE(musb); reg = musb_readb(mbase, MUSB_POWER); reg |= MUSB_POWER_SUSPENDM; @@ -412,7 +412,7 @@ void musb_hnp_stop(struct musb *musb) break; default: dev_dbg(musb->controller, "HNP: Stopping in unknown state %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } /* @@ -449,13 +449,13 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ if (int_usb & MUSB_INTR_RESUME) { handled = IRQ_HANDLED; - dev_dbg(musb->controller, "RESUME (%s)\n", usb_otg_state_string(musb->xceiv->state)); + dev_dbg(musb->controller, "RESUME (%s)\n", usb_otg_state_string(musb->xceiv->otg->state)); if (devctl & MUSB_DEVCTL_HM) { void __iomem *mbase = musb->mregs; u8 power; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: /* remote wakeup? later, GetPortStatus * will stop RESUME signaling @@ -482,25 +482,25 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, &musb->finish_resume_work, msecs_to_jiffies(20)); - musb->xceiv->state = OTG_STATE_A_HOST; + musb->xceiv->otg->state = OTG_STATE_A_HOST; musb->is_active = 1; musb_host_resume_root_hub(musb); break; case OTG_STATE_B_WAIT_ACON: - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb->is_active = 1; MUSB_DEV_MODE(musb); break; default: WARNING("bogus %s RESUME (%s)\n", "host", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } else { - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: /* possibly DISCONNECT is upcoming */ - musb->xceiv->state = OTG_STATE_A_HOST; + musb->xceiv->otg->state = OTG_STATE_A_HOST; musb_host_resume_root_hub(musb); break; case OTG_STATE_B_WAIT_ACON: @@ -523,7 +523,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: WARNING("bogus %s RESUME (%s)\n", "peripheral", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } } @@ -539,7 +539,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } dev_dbg(musb->controller, "SESSION_REQUEST (%s)\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); /* IRQ arrives from ID pin sense or (later, if VBUS power * is removed) SRP. responses are time critical: @@ -550,7 +550,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); musb->ep0_stage = MUSB_EP0_START; - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); musb_platform_set_vbus(musb, 1); @@ -576,7 +576,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, * REVISIT: do delays from lots of DEBUG_KERNEL checks * make trouble here, keeping VBUS < 4.4V ? */ - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_HOST: /* recovery is dicey once we've gotten past the * initial stages of enumeration, but if VBUS @@ -605,7 +605,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, dev_printk(ignore ? KERN_DEBUG : KERN_ERR, musb->controller, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), devctl, ({ char *s; switch (devctl & MUSB_DEVCTL_VBUS) { @@ -630,10 +630,10 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_SUSPEND) { dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n", - usb_otg_state_string(musb->xceiv->state), devctl); + usb_otg_state_string(musb->xceiv->otg->state), devctl); handled = IRQ_HANDLED; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_PERIPHERAL: /* We also come here if the cable is removed, since * this silicon doesn't report ID-no-longer-grounded. @@ -657,7 +657,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb_g_suspend(musb); musb->is_active = musb->g.b_hnp_enable; if (musb->is_active) { - musb->xceiv->state = OTG_STATE_B_WAIT_ACON; + musb->xceiv->otg->state = OTG_STATE_B_WAIT_ACON; dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies( @@ -670,7 +670,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, + msecs_to_jiffies(musb->a_wait_bcon)); break; case OTG_STATE_A_HOST: - musb->xceiv->state = OTG_STATE_A_SUSPEND; + musb->xceiv->otg->state = OTG_STATE_A_SUSPEND; musb->is_active = musb->hcd->self.b_hnp_enable; break; case OTG_STATE_B_HOST: @@ -713,7 +713,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->port1_status |= USB_PORT_STAT_LOW_SPEED; /* indicate new connection to OTG machine */ - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_B_PERIPHERAL: if (int_usb & MUSB_INTR_SUSPEND) { dev_dbg(musb->controller, "HNP: SUSPEND+CONNECT, now b_host\n"); @@ -725,7 +725,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, case OTG_STATE_B_WAIT_ACON: dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n"); b_host: - musb->xceiv->state = OTG_STATE_B_HOST; + musb->xceiv->otg->state = OTG_STATE_B_HOST; if (musb->hcd) musb->hcd->self.is_b_host = 1; del_timer(&musb->otg_timer); @@ -733,7 +733,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: if ((devctl & MUSB_DEVCTL_VBUS) == (3 << MUSB_DEVCTL_VBUS_SHIFT)) { - musb->xceiv->state = OTG_STATE_A_HOST; + musb->xceiv->otg->state = OTG_STATE_A_HOST; if (hcd) hcd->self.is_b_host = 0; } @@ -743,16 +743,16 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb_host_poke_root_hub(musb); dev_dbg(musb->controller, "CONNECT (%s) devctl %02x\n", - usb_otg_state_string(musb->xceiv->state), devctl); + usb_otg_state_string(musb->xceiv->otg->state), devctl); } if (int_usb & MUSB_INTR_DISCONNECT) { dev_dbg(musb->controller, "DISCONNECT (%s) as %s, devctl %02x\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), MUSB_MODE(musb), devctl); handled = IRQ_HANDLED; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_HOST: case OTG_STATE_A_SUSPEND: musb_host_resume_root_hub(musb); @@ -770,7 +770,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb_root_disconnect(musb); if (musb->hcd) musb->hcd->self.is_b_host = 0; - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; MUSB_DEV_MODE(musb); musb_g_disconnect(musb); break; @@ -786,7 +786,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; default: WARNING("unhandled DISCONNECT transition (%s)\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); break; } } @@ -812,15 +812,15 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } } else { dev_dbg(musb->controller, "BUS RESET as %s\n", - usb_otg_state_string(musb->xceiv->state)); - switch (musb->xceiv->state) { + usb_otg_state_string(musb->xceiv->otg->state)); + switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: musb_g_reset(musb); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ /* never use invalid T(a_wait_bcon) */ dev_dbg(musb->controller, "HNP: in %s, %d msec timeout\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), TA_WAIT_BCON(musb)); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies(TA_WAIT_BCON(musb))); @@ -831,19 +831,19 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_B_WAIT_ACON: dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n", - usb_otg_state_string(musb->xceiv->state)); - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + usb_otg_state_string(musb->xceiv->otg->state)); + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); break; case OTG_STATE_B_IDLE: - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; /* FALLTHROUGH */ case OTG_STATE_B_PERIPHERAL: musb_g_reset(musb); break; default: dev_dbg(musb->controller, "Unhandled BUS RESET as %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } } @@ -1630,7 +1630,7 @@ musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) int ret = -EINVAL; spin_lock_irqsave(&musb->lock, flags); - ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->state)); + ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->otg->state)); spin_unlock_irqrestore(&musb->lock, flags); return ret; @@ -1675,7 +1675,7 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, spin_lock_irqsave(&musb->lock, flags); /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; - if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) + if (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON) musb->is_active = 0; musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); spin_unlock_irqrestore(&musb->lock, flags); @@ -1743,8 +1743,8 @@ static void musb_irq_work(struct work_struct *data) { struct musb *musb = container_of(data, struct musb, irq_work); - if (musb->xceiv->state != musb->xceiv_old_state) { - musb->xceiv_old_state = musb->xceiv->state; + if (musb->xceiv->otg->state != musb->xceiv_old_state) { + musb->xceiv_old_state = musb->xceiv->otg->state; sysfs_notify(&musb->controller->kobj, NULL, "mode"); } } @@ -1983,10 +1983,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (musb->xceiv->otg->default_a) { MUSB_HST_MODE(musb); - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; } else { MUSB_DEV_MODE(musb); - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; } switch (musb->port_mode) { diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 759ef1d236b2..440333fcf3a7 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -179,9 +179,9 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || (musb->a_wait_bcon == 0 && - musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { + musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); del_timer(&glue->timer); glue->last_timer = jiffies; return; @@ -201,7 +201,7 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) glue->last_timer = timeout; dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), jiffies_to_msecs(timeout - jiffies)); mod_timer(&glue->timer, timeout); } @@ -265,10 +265,10 @@ static void otg_timer(unsigned long _musb) */ devctl = dsps_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); skip_session = 1; @@ -277,10 +277,10 @@ static void otg_timer(unsigned long _musb) case OTG_STATE_A_IDLE: case OTG_STATE_B_IDLE: if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } else { - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) @@ -288,7 +288,7 @@ static void otg_timer(unsigned long _musb) mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); break; case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; dsps_writel(musb->ctrl_base, wrp->coreintr_set, MUSB_INTR_VBUSERROR << wrp->usb_shift); break; @@ -373,26 +373,26 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) * devctl. */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); musb->xceiv->otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; del_timer(&glue->timer); } else { musb->is_active = 0; MUSB_DEV_MODE(musb); musb->xceiv->otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; } /* NOTE: this must complete power-on within 100 ms. */ dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; @@ -402,7 +402,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) ret |= musb_interrupt(musb); /* Poll for ID change in OTG port mode */ - if (musb->xceiv->state == OTG_STATE_B_IDLE && + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); out: @@ -900,7 +900,7 @@ static int dsps_resume(struct device *dev) dsps_writel(mbase, wrp->mode, glue->context.mode); dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode); dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); - if (musb->xceiv->state == OTG_STATE_B_IDLE && + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 4ab1896957e1..56c31b769a54 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1546,7 +1546,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_B_PERIPHERAL: /* NOTE: OTG state machine doesn't include B_SUSPENDED; * that's part of the standard usb 1.1 state machine, and @@ -1587,7 +1587,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) goto done; default: dev_dbg(musb->controller, "Unhandled wake: %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); goto done; } @@ -1791,7 +1791,7 @@ int musb_gadget_setup(struct musb *musb) MUSB_DEV_MODE(musb); musb->xceiv->otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; /* this "gadget" abstracts/virtualizes the controller */ musb->g.name = musb_driver_name; @@ -1857,7 +1857,7 @@ static int musb_gadget_start(struct usb_gadget *g, musb->is_active = 1; otg_set_peripheral(otg, &musb->g); - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; spin_unlock_irqrestore(&musb->lock, flags); musb_start(musb); @@ -1941,7 +1941,7 @@ static int musb_gadget_stop(struct usb_gadget *g) (void) musb_gadget_vbus_draw(&musb->g, 0); - musb->xceiv->state = OTG_STATE_UNDEFINED; + musb->xceiv->otg->state = OTG_STATE_UNDEFINED; stop_activity(musb, NULL); otg_set_peripheral(musb->xceiv->otg, NULL); @@ -1968,7 +1968,7 @@ static int musb_gadget_stop(struct usb_gadget *g) void musb_g_resume(struct musb *musb) { musb->is_suspended = 0; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_B_IDLE: break; case OTG_STATE_B_WAIT_ACON: @@ -1982,7 +1982,7 @@ void musb_g_resume(struct musb *musb) break; default: WARNING("unhandled RESUME transition (%s)\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } @@ -1994,10 +1994,10 @@ void musb_g_suspend(struct musb *musb) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "devctl %02x\n", devctl); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_B_IDLE: if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; break; case OTG_STATE_B_PERIPHERAL: musb->is_suspended = 1; @@ -2012,7 +2012,7 @@ void musb_g_suspend(struct musb *musb) * A_PERIPHERAL may need care too */ WARNING("unhandled SUSPEND transition (%s)\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } @@ -2043,22 +2043,22 @@ void musb_g_disconnect(struct musb *musb) spin_lock(&musb->lock); } - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { default: dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", - usb_otg_state_string(musb->xceiv->state)); - musb->xceiv->state = OTG_STATE_A_IDLE; + usb_otg_state_string(musb->xceiv->otg->state)); + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); break; case OTG_STATE_A_PERIPHERAL: - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; MUSB_HST_MODE(musb); break; case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_IDLE: - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; break; case OTG_STATE_B_SRP_INIT: break; @@ -2118,13 +2118,13 @@ __acquires(musb->lock) * In that case, do not rely on devctl for setting * peripheral mode. */ - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb->g.is_a_peripheral = 0; } else if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb->g.is_a_peripheral = 0; } else { - musb->xceiv->state = OTG_STATE_A_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_A_PERIPHERAL; musb->g.is_a_peripheral = 1; } diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 855793d701bb..23d474d3d7f4 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2463,7 +2463,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (!is_host_active(musb)) return 0; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: return 0; case OTG_STATE_A_WAIT_VRISE: @@ -2473,7 +2473,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) */ devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; break; default: break; @@ -2481,7 +2481,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (musb->is_active) { WARNING("trying to suspend as %s while active\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); return -EBUSY; } else return 0; @@ -2678,7 +2678,7 @@ int musb_host_setup(struct musb *musb, int power_budget) MUSB_HST_MODE(musb); musb->xceiv->otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; otg_set_host(musb->xceiv->otg, &hcd->self); hcd->self.otg_port = 1; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index e2d2d8c9891b..a133bd8c5dc7 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -69,7 +69,7 @@ void musb_host_finish_resume(struct work_struct *work) musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; usb_hcd_poll_rh_status(musb->hcd); /* NOTE: it might really be A_WAIT_BCON ... */ - musb->xceiv->state = OTG_STATE_A_HOST; + musb->xceiv->otg->state = OTG_STATE_A_HOST; spin_unlock_irqrestore(&musb->lock, flags); } @@ -107,9 +107,9 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) dev_dbg(musb->controller, "Root port suspended, power %02x\n", power); musb->port1_status |= USB_PORT_STAT_SUSPEND; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_HOST: - musb->xceiv->state = OTG_STATE_A_SUSPEND; + musb->xceiv->otg->state = OTG_STATE_A_SUSPEND; musb->is_active = otg->host->b_hnp_enable; if (musb->is_active) mod_timer(&musb->otg_timer, jiffies @@ -118,13 +118,13 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) musb_platform_try_idle(musb, 0); break; case OTG_STATE_B_HOST: - musb->xceiv->state = OTG_STATE_B_WAIT_ACON; + musb->xceiv->otg->state = OTG_STATE_B_WAIT_ACON; musb->is_active = otg->host->b_hnp_enable; musb_platform_try_idle(musb, 0); break; default: dev_dbg(musb->controller, "bogus rh suspend? %s\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } else if (power & MUSB_POWER_SUSPENDM) { power &= ~MUSB_POWER_SUSPENDM; @@ -145,7 +145,7 @@ void musb_port_reset(struct musb *musb, bool do_reset) u8 power; void __iomem *mbase = musb->mregs; - if (musb->xceiv->state == OTG_STATE_B_IDLE) { + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) { dev_dbg(musb->controller, "HNP: Returning from HNP; no hub reset from b_idle\n"); musb->port1_status &= ~USB_PORT_STAT_RESET; return; @@ -224,24 +224,24 @@ void musb_root_disconnect(struct musb *musb) usb_hcd_poll_rh_status(musb->hcd); musb->is_active = 0; - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: if (otg->host->b_hnp_enable) { - musb->xceiv->state = OTG_STATE_A_PERIPHERAL; + musb->xceiv->otg->state = OTG_STATE_A_PERIPHERAL; musb->g.is_a_peripheral = 1; break; } /* FALLTHROUGH */ case OTG_STATE_A_HOST: - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; musb->is_active = 0; break; case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; break; default: dev_dbg(musb->controller, "host disconnect (%s)\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 20fc2a532a24..763649eb4987 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -65,15 +65,15 @@ static void musb_do_idle(unsigned long _musb) spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } else { - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } break; @@ -90,15 +90,15 @@ static void musb_do_idle(unsigned long _musb) musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; usb_hcd_poll_rh_status(musb->hcd); /* NOTE: it might really be A_WAIT_BCON ... */ - musb->xceiv->state = OTG_STATE_A_HOST; + musb->xceiv->otg->state = OTG_STATE_A_HOST; } break; case OTG_STATE_A_HOST: devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (devctl & MUSB_DEVCTL_BDEVICE) - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; else - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; default: break; } @@ -116,9 +116,9 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || ((musb->a_wait_bcon == 0) - && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { + && (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) { dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -135,7 +135,7 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -153,7 +153,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (is_on) { - if (musb->xceiv->state == OTG_STATE_A_IDLE) { + if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) { int loops = 100; /* start the session */ devctl |= MUSB_DEVCTL_SESSION; @@ -180,7 +180,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) } else { musb->is_active = 1; otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; devctl |= MUSB_DEVCTL_SESSION; MUSB_HST_MODE(musb); } @@ -192,7 +192,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) */ otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; devctl &= ~MUSB_DEVCTL_SESSION; MUSB_DEV_MODE(musb); @@ -201,7 +201,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) dev_dbg(musb->controller, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } @@ -266,7 +266,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) dev_dbg(dev, "ID GND\n"); otg->default_a = true; - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; musb->xceiv->last_event = USB_EVENT_ID; if (musb->gadget_driver) { pm_runtime_get_sync(dev); @@ -280,7 +280,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) dev_dbg(dev, "VBUS Connect\n"); otg->default_a = false; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; musb->xceiv->last_event = USB_EVENT_VBUS; if (musb->gadget_driver) pm_runtime_get_sync(dev); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 25f02dfc8955..69ca92d6032f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -415,13 +415,13 @@ static void musb_do_idle(unsigned long _musb) spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: if ((musb->a_wait_bcon != 0) && (musb->idle_timeout == 0 || time_after(jiffies, musb->idle_timeout))) { dev_dbg(musb->controller, "Nothing connected %s, turning off VBUS\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); } /* FALLTHROUGH */ case OTG_STATE_A_IDLE: @@ -474,9 +474,9 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || ((musb->a_wait_bcon == 0) - && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { + && (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) { dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); + usb_otg_state_string(musb->xceiv->otg->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -493,7 +493,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -524,7 +524,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) if (is_on) { timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; devctl |= MUSB_DEVCTL_SESSION; conf |= TUSB_DEV_CONF_USB_HOST_MODE; @@ -537,16 +537,16 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) /* If ID pin is grounded, we want to be a_idle */ otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_VRISE: case OTG_STATE_A_WAIT_BCON: - musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; break; case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; break; default: - musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_IDLE; } musb->is_active = 0; otg->default_a = 1; @@ -554,7 +554,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) } else { musb->is_active = 0; otg->default_a = 0; - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); } @@ -569,7 +569,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); dev_dbg(musb->controller, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), musb_readb(musb->mregs, MUSB_DEVCTL), musb_readl(tbase, TUSB_DEV_OTG_STAT), conf, prcm); @@ -668,23 +668,23 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) { dev_dbg(musb->controller, "Forcing disconnect (no interrupt)\n"); - if (musb->xceiv->state != OTG_STATE_B_IDLE) { + if (musb->xceiv->otg->state != OTG_STATE_B_IDLE) { /* INTR_DISCONNECT can hide... */ - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; musb->int_usb |= MUSB_INTR_DISCONNECT; } musb->is_active = 0; } dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", - usb_otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->otg->state), otg_stat); idle_timeout = jiffies + (1 * HZ); schedule_work(&musb->irq_work); } else /* A-dev state machine */ { dev_dbg(musb->controller, "vbus change, %s, otg %03x\n", - usb_otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->otg->state), otg_stat); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_IDLE: dev_dbg(musb->controller, "Got SRP, turning on VBUS\n"); musb_platform_set_vbus(musb, 1); @@ -731,9 +731,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) u8 devctl; dev_dbg(musb->controller, "%s timer, %03x\n", - usb_otg_state_string(musb->xceiv->state), otg_stat); + usb_otg_state_string(musb->xceiv->otg->state), otg_stat); - switch (musb->xceiv->state) { + switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_VRISE: /* VBUS has probably been valid for a while now, * but may well have bounced out of range a bit @@ -745,7 +745,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) dev_dbg(musb->controller, "devctl %02x\n", devctl); break; } - musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; musb->is_active = 0; idle_timeout = jiffies + msecs_to_jiffies(musb->a_wait_bcon); diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d0180a70051d..1d631d5f4a27 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -56,7 +56,7 @@ static void ux500_musb_set_vbus(struct musb *musb, int is_on) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); if (is_on) { - if (musb->xceiv->state == OTG_STATE_A_IDLE) { + if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) { /* start the session */ devctl |= MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); @@ -76,7 +76,7 @@ static void ux500_musb_set_vbus(struct musb *musb, int is_on) } else { musb->is_active = 1; musb->xceiv->otg->default_a = 1; - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; devctl |= MUSB_DEVCTL_SESSION; MUSB_HST_MODE(musb); } @@ -102,7 +102,7 @@ static void ux500_musb_set_vbus(struct musb *musb, int is_on) mdelay(200); dev_dbg(musb->controller, "VBUS %s, devctl %02x\n", - usb_otg_state_string(musb->xceiv->state), + usb_otg_state_string(musb->xceiv->otg->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } @@ -112,7 +112,7 @@ static int musb_otg_notifications(struct notifier_block *nb, struct musb *musb = container_of(nb, struct musb, nb); dev_dbg(musb->controller, "musb_otg_notifications %ld %s\n", - event, usb_otg_state_string(musb->xceiv->state)); + event, usb_otg_state_string(musb->xceiv->otg->state)); switch (event) { case UX500_MUSB_ID: @@ -127,7 +127,7 @@ static int musb_otg_notifications(struct notifier_block *nb, if (is_host_active(musb)) ux500_musb_set_vbus(musb, 0); else - musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->otg->state = OTG_STATE_B_IDLE; break; default: dev_dbg(musb->controller, "ID float\n"); diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 11ab2c45e462..2d5250143ce1 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -446,7 +446,7 @@ static int ab9540_usb_link_status_update(struct ab8500_usb *ab, if (event != UX500_MUSB_RIDB) event = UX500_MUSB_NONE; /* Fallback to default B_IDLE as nothing is connected. */ - ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->state = OTG_STATE_B_IDLE; break; case USB_LINK_ACA_RID_C_NM_9540: @@ -584,7 +584,7 @@ static int ab8540_usb_link_status_update(struct ab8500_usb *ab, * Fallback to default B_IDLE as nothing * is connected */ - ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->state = OTG_STATE_B_IDLE; break; case USB_LINK_ACA_RID_C_NM_8540: @@ -693,7 +693,7 @@ static int ab8505_usb_link_status_update(struct ab8500_usb *ab, * Fallback to default B_IDLE as nothing * is connected */ - ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->state = OTG_STATE_B_IDLE; break; case USB_LINK_ACA_RID_C_NM_8505: @@ -776,7 +776,7 @@ static int ab8500_usb_link_status_update(struct ab8500_usb *ab, if (event != UX500_MUSB_RIDB) event = UX500_MUSB_NONE; /* Fallback to default B_IDLE as nothing is connected */ - ab->phy.state = OTG_STATE_B_IDLE; + ab->phy.otg->state = OTG_STATE_B_IDLE; break; case USB_LINK_ACA_RID_C_NM_8500: @@ -1380,7 +1380,7 @@ static int ab8500_usb_probe(struct platform_device *pdev) ab->phy.label = "ab8500"; ab->phy.set_suspend = ab8500_usb_set_suspend; ab->phy.set_power = ab8500_usb_set_power; - ab->phy.state = OTG_STATE_UNDEFINED; + ab->phy.otg->state = OTG_STATE_UNDEFINED; otg->phy = &ab->phy; otg->set_host = ab8500_usb_set_host; diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index f1ea5990a50a..15d7a81eece5 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -623,7 +623,7 @@ static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) /* Mini-A cable connected */ struct otg_fsm *fsm = &otg_dev->fsm; - otg->phy->state = OTG_STATE_UNDEFINED; + otg.state = OTG_STATE_UNDEFINED; fsm->protocol = PROTO_UNDEF; } } @@ -681,7 +681,7 @@ static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA) { if (!fsl_otg_dev) return -ENODEV; - if (phy->state == OTG_STATE_B_PERIPHERAL) + if (phy->otg.state == OTG_STATE_B_PERIPHERAL) pr_info("FSL OTG: Draw %d mA\n", mA); return 0; @@ -714,7 +714,7 @@ static int fsl_otg_start_srp(struct usb_otg *otg) { struct fsl_otg *otg_dev; - if (!otg || otg->phy->state != OTG_STATE_B_IDLE) + if (!otg || otg.state != OTG_STATE_B_IDLE) return -ENODEV; otg_dev = container_of(otg->phy, struct fsl_otg, phy); @@ -989,10 +989,10 @@ int usb_otg_start(struct platform_device *pdev) * Also: record initial state of ID pin */ if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { - p_otg->phy.state = OTG_STATE_UNDEFINED; + p_otg->phy->otg.state = OTG_STATE_UNDEFINED; p_otg->fsm.id = 1; } else { - p_otg->phy.state = OTG_STATE_A_IDLE; + p_otg->phy->otg.state = OTG_STATE_A_IDLE; p_otg->fsm.id = 0; } diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 7594e5069ae5..280a3458ff6b 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -123,7 +123,7 @@ static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) } otg->gadget = gadget; - otg->phy->state = OTG_STATE_B_IDLE; + otg->state = OTG_STATE_B_IDLE; return 0; } @@ -225,9 +225,9 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; - nop->phy.state = OTG_STATE_UNDEFINED; nop->phy.type = type; + nop->phy.otg->state = OTG_STATE_UNDEFINED; nop->phy.otg->phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index f4b14bd97e14..7a6be3e5dc23 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -121,7 +121,7 @@ static void gpio_vbus_work(struct work_struct *work) if (vbus) { status = USB_EVENT_VBUS; - gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; + gpio_vbus->phy.otg->state = OTG_STATE_B_PERIPHERAL; gpio_vbus->phy.last_event = status; usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); @@ -143,7 +143,7 @@ static void gpio_vbus_work(struct work_struct *work) usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); status = USB_EVENT_NONE; - gpio_vbus->phy.state = OTG_STATE_B_IDLE; + gpio_vbus->phy.otg->state = OTG_STATE_B_IDLE; gpio_vbus->phy.last_event = status; atomic_notifier_call_chain(&gpio_vbus->phy.notifier, @@ -196,7 +196,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(otg->gadget); - otg->phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; otg->gadget = NULL; return 0; @@ -218,7 +218,7 @@ static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - if (phy->state == OTG_STATE_B_PERIPHERAL) + if (phy->otg->state == OTG_STATE_B_PERIPHERAL) set_vbus_draw(gpio_vbus, mA); return 0; } @@ -269,8 +269,8 @@ static int gpio_vbus_probe(struct platform_device *pdev) gpio_vbus->phy.dev = gpio_vbus->dev; gpio_vbus->phy.set_power = gpio_vbus_set_power; gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; - gpio_vbus->phy.state = OTG_STATE_UNDEFINED; + gpio_vbus->phy.otg->state = OTG_STATE_UNDEFINED; gpio_vbus->phy.otg->phy = &gpio_vbus->phy; gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 8eea56d3ded6..24f84cbbed57 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -234,7 +234,7 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) static inline const char *state_name(struct isp1301 *isp) { - return usb_otg_state_string(isp->phy.state); + return usb_otg_state_string(isp->phy.otg->state); } /*-------------------------------------------------------------------------*/ @@ -249,7 +249,7 @@ static inline const char *state_name(struct isp1301 *isp) static void power_down(struct isp1301 *isp) { - isp->phy.state = OTG_STATE_UNDEFINED; + isp->phy.otg->state = OTG_STATE_UNDEFINED; // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); @@ -339,7 +339,7 @@ static void a_idle(struct isp1301 *isp, const char *tag) { u32 l; - if (isp->phy.state == OTG_STATE_A_IDLE) + if (isp->phy.otg->state == OTG_STATE_A_IDLE) return; isp->phy.otg->default_a = 1; @@ -351,7 +351,7 @@ static void a_idle(struct isp1301 *isp, const char *tag) isp->phy.otg->gadget->is_a_peripheral = 1; gadget_suspend(isp); } - isp->phy.state = OTG_STATE_A_IDLE; + isp->phy.otg->state = OTG_STATE_A_IDLE; l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; omap_writel(l, OTG_CTRL); isp->last_otg_ctrl = l; @@ -363,7 +363,7 @@ static void b_idle(struct isp1301 *isp, const char *tag) { u32 l; - if (isp->phy.state == OTG_STATE_B_IDLE) + if (isp->phy.otg->state == OTG_STATE_B_IDLE) return; isp->phy.otg->default_a = 0; @@ -375,7 +375,7 @@ static void b_idle(struct isp1301 *isp, const char *tag) isp->phy.otg->gadget->is_a_peripheral = 0; gadget_suspend(isp); } - isp->phy.state = OTG_STATE_B_IDLE; + isp->phy.otg->state = OTG_STATE_B_IDLE; l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; omap_writel(l, OTG_CTRL); isp->last_otg_ctrl = l; @@ -474,7 +474,7 @@ static void check_state(struct isp1301 *isp, const char *tag) default: break; } - if (isp->phy.state == state && !extra) + if (isp->phy.otg->state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, usb_otg_state_string(state), fsm, state_name(isp), @@ -498,23 +498,23 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) if (int_src & INTR_SESS_VLD) otg_ctrl |= OTG_ASESSVLD; - else if (isp->phy.state == OTG_STATE_A_WAIT_VFALL) { + else if (isp->phy.otg->state == OTG_STATE_A_WAIT_VFALL) { a_idle(isp, "vfall"); otg_ctrl &= ~OTG_CTRL_BITS; } if (int_src & INTR_VBUS_VLD) otg_ctrl |= OTG_VBUSVLD; if (int_src & INTR_ID_GND) { /* default-A */ - if (isp->phy.state == OTG_STATE_B_IDLE - || isp->phy.state + if (isp->phy.otg->state == OTG_STATE_B_IDLE + || isp->phy.otg->state == OTG_STATE_UNDEFINED) { a_idle(isp, "init"); return; } } else { /* default-B */ otg_ctrl |= OTG_ID; - if (isp->phy.state == OTG_STATE_A_IDLE - || isp->phy.state == OTG_STATE_UNDEFINED) { + if (isp->phy.otg->state == OTG_STATE_A_IDLE + || isp->phy.otg->state == OTG_STATE_UNDEFINED) { b_idle(isp, "init"); return; } @@ -548,14 +548,14 @@ static void otg_update_isp(struct isp1301 *isp) isp->last_otg_ctrl = otg_ctrl; otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_B_IDLE: case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_SRP_INIT: if (!(otg_ctrl & OTG_PULLUP)) { // if (otg_ctrl & OTG_B_HNPEN) { if (isp->phy.otg->gadget->b_hnp_enable) { - isp->phy.state = OTG_STATE_B_WAIT_ACON; + isp->phy.otg->state = OTG_STATE_B_WAIT_ACON; pr_debug(" --> b_wait_acon\n"); } goto pulldown; @@ -585,7 +585,7 @@ static void otg_update_isp(struct isp1301 *isp) if (!(isp->phy.otg->host)) otg_ctrl &= ~OTG_DRV_VBUS; - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_A_SUSPEND: if (otg_ctrl & OTG_DRV_VBUS) { set |= OTG1_VBUS_DRV; @@ -596,7 +596,7 @@ static void otg_update_isp(struct isp1301 *isp) /* FALLTHROUGH */ case OTG_STATE_A_VBUS_ERR: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; + isp->phy.otg->state = OTG_STATE_A_WAIT_VFALL; pr_debug(" --> a_wait_vfall\n"); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_VFALL: @@ -605,7 +605,7 @@ static void otg_update_isp(struct isp1301 *isp) break; case OTG_STATE_A_IDLE: if (otg_ctrl & OTG_DRV_VBUS) { - isp->phy.state = OTG_STATE_A_WAIT_VRISE; + isp->phy.otg->state = OTG_STATE_A_WAIT_VRISE; pr_debug(" --> a_wait_vrise\n"); } /* FALLTHROUGH */ @@ -625,17 +625,17 @@ static void otg_update_isp(struct isp1301 *isp) if (otg_change & OTG_PULLUP) { u32 l; - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_B_IDLE: if (clr & OTG1_DP_PULLUP) break; - isp->phy.state = OTG_STATE_B_PERIPHERAL; + isp->phy.otg->state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); break; case OTG_STATE_A_SUSPEND: if (clr & OTG1_DP_PULLUP) break; - isp->phy.state = OTG_STATE_A_PERIPHERAL; + isp->phy.otg->state = OTG_STATE_A_PERIPHERAL; pr_debug(" --> a_peripheral\n"); break; default: @@ -673,7 +673,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) * remote wakeup (SRP, normal) using their own timer * to give "check cable and A-device" messages. */ - if (isp->phy.state == OTG_STATE_B_SRP_INIT) + if (isp->phy.otg->state == OTG_STATE_B_SRP_INIT) b_idle(isp, "srp_timeout"); omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); @@ -691,7 +691,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) omap_writel(otg_ctrl, OTG_CTRL); /* subset of b_peripheral()... */ - isp->phy.state = OTG_STATE_B_PERIPHERAL; + isp->phy.otg->state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); @@ -703,7 +703,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) state_name(isp), omap_readl(OTG_CTRL)); isp1301_defer_work(isp, WORK_UPDATE_OTG); - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_A_IDLE: if (!otg->host) break; @@ -734,7 +734,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_WAIT_VFALL; + isp->phy.otg->state = OTG_STATE_A_WAIT_VFALL; omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); ret = IRQ_HANDLED; @@ -748,7 +748,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_A_VBUS_ERR; + isp->phy.otg->state = OTG_STATE_A_VBUS_ERR; omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); ret = IRQ_HANDLED; @@ -769,7 +769,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) /* role is peripheral */ if (otg_ctrl & OTG_DRIVER_SEL) { - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_A_IDLE: b_idle(isp, __func__); break; @@ -786,18 +786,18 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } if (otg->host) { - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; + isp->phy.otg->state = OTG_STATE_B_HOST; pr_debug(" --> b_host\n"); kick = 1; break; case OTG_STATE_A_WAIT_BCON: - isp->phy.state = OTG_STATE_A_HOST; + isp->phy.otg->state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); break; case OTG_STATE_A_PERIPHERAL: - isp->phy.state = OTG_STATE_A_WAIT_BCON; + isp->phy.otg->state = OTG_STATE_A_WAIT_BCON; pr_debug(" --> a_wait_bcon\n"); break; default: @@ -937,7 +937,7 @@ static void b_peripheral(struct isp1301 *isp) /* UDC driver just set OTG_BSESSVLD */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); - isp->phy.state = OTG_STATE_B_PERIPHERAL; + isp->phy.otg->state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); dump_regs(isp, "2periph"); #endif @@ -947,7 +947,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) { struct usb_otg *otg = isp->phy.otg; u8 isp_stat, isp_bstat; - enum usb_otg_state state = isp->phy.state; + enum usb_otg_state state = isp->phy.otg->state; if (stat & INTR_BDIS_ACON) pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp)); @@ -970,7 +970,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) * when HNP is used. */ if (isp_stat & INTR_VBUS_VLD) - isp->phy.state = OTG_STATE_A_HOST; + isp->phy.otg->state = OTG_STATE_A_HOST; break; case OTG_STATE_A_WAIT_VFALL: if (!(isp_stat & INTR_SESS_VLD)) @@ -978,7 +978,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) break; default: if (!(isp_stat & INTR_VBUS_VLD)) - isp->phy.state = OTG_STATE_A_VBUS_ERR; + isp->phy.otg->state = OTG_STATE_A_VBUS_ERR; break; } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); @@ -1007,7 +1007,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) if (otg->default_a) { switch (state) { default: - isp->phy.state = OTG_STATE_A_WAIT_VFALL; + isp->phy.otg->state = OTG_STATE_A_WAIT_VFALL; break; case OTG_STATE_A_WAIT_VFALL: state = OTG_STATE_A_IDLE; @@ -1020,7 +1020,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) host_suspend(isp); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_BDIS_ACON_EN); - isp->phy.state = OTG_STATE_B_IDLE; + isp->phy.otg->state = OTG_STATE_B_IDLE; l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; l &= ~OTG_CTRL_BITS; omap_writel(l, OTG_CTRL); @@ -1031,7 +1031,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) } isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS); - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: @@ -1071,7 +1071,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) } } - if (state != isp->phy.state) + if (state != isp->phy.otg->state) pr_debug(" isp, %s -> %s\n", usb_otg_state_string(state), state_name(isp)); @@ -1129,10 +1129,10 @@ isp1301_work(struct work_struct *work) * skip A_WAIT_VRISE; hc transitions invisibly * skip A_WAIT_BCON; same. */ - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: - isp->phy.state = OTG_STATE_A_HOST; + isp->phy.otg->state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; @@ -1141,7 +1141,7 @@ isp1301_work(struct work_struct *work) omap_writel(otg_ctrl, OTG_CTRL); break; case OTG_STATE_B_WAIT_ACON: - isp->phy.state = OTG_STATE_B_HOST; + isp->phy.otg->state = OTG_STATE_B_HOST; pr_debug(" --> b_host (acon)\n"); break; case OTG_STATE_B_HOST: @@ -1368,7 +1368,7 @@ isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) } power_up(isp); - isp->phy.state = OTG_STATE_B_IDLE; + isp->phy.otg->state = OTG_STATE_B_IDLE; if (machine_is_omap_h2() || machine_is_omap_h3()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); @@ -1403,7 +1403,7 @@ isp1301_set_power(struct usb_phy *dev, unsigned mA) { if (!the_transceiver) return -ENODEV; - if (dev->state == OTG_STATE_B_PERIPHERAL) + if (dev->otg->state == OTG_STATE_B_PERIPHERAL) enable_vbus_draw(the_transceiver, mA); return 0; } @@ -1414,7 +1414,7 @@ isp1301_start_srp(struct usb_otg *otg) struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); u32 otg_ctrl; - if (isp != the_transceiver || isp->phy.state != OTG_STATE_B_IDLE) + if (isp != the_transceiver || isp->phy.otg->state != OTG_STATE_B_IDLE) return -ENODEV; otg_ctrl = omap_readl(OTG_CTRL); @@ -1424,7 +1424,7 @@ isp1301_start_srp(struct usb_otg *otg) otg_ctrl |= OTG_B_BUSREQ; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; omap_writel(otg_ctrl, OTG_CTRL); - isp->phy.state = OTG_STATE_B_SRP_INIT; + isp->phy.otg->state = OTG_STATE_B_SRP_INIT; pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), omap_readl(OTG_CTRL)); @@ -1452,9 +1452,9 @@ isp1301_start_hnp(struct usb_otg *otg) /* We want hardware to manage most HNP protocol timings. * So do this part as early as possible... */ - switch (isp->phy.state) { + switch (isp->phy.otg->state) { case OTG_STATE_B_HOST: - isp->phy.state = OTG_STATE_B_PERIPHERAL; + isp->phy.otg->state = OTG_STATE_B_PERIPHERAL; /* caller will suspend next */ break; case OTG_STATE_A_HOST: diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 471e69dbcca0..18015b7c8afc 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -721,11 +721,11 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) } if (!host) { - if (otg->phy->state == OTG_STATE_A_HOST) { + if (otg->state == OTG_STATE_A_HOST) { pm_runtime_get_sync(otg->phy->dev); msm_otg_start_host(otg->phy, 0); otg->host = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; schedule_work(&motg->sm_work); } else { otg->host = NULL; @@ -794,11 +794,11 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, } if (!gadget) { - if (otg->phy->state == OTG_STATE_B_PERIPHERAL) { + if (otg->state == OTG_STATE_B_PERIPHERAL) { pm_runtime_get_sync(otg->phy->dev); msm_otg_start_peripheral(otg->phy, 0); otg->gadget = NULL; - otg->phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; schedule_work(&motg->sm_work); } else { otg->gadget = NULL; @@ -1170,12 +1170,12 @@ static void msm_otg_sm_work(struct work_struct *w) struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); struct usb_otg *otg = motg->phy.otg; - switch (otg->phy->state) { + switch (otg->state) { case OTG_STATE_UNDEFINED: dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); msm_otg_reset(otg->phy); msm_otg_init_sm(motg); - otg->phy->state = OTG_STATE_B_IDLE; + otg->state = OTG_STATE_B_IDLE; /* FALL THROUGH */ case OTG_STATE_B_IDLE: dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); @@ -1183,7 +1183,7 @@ static void msm_otg_sm_work(struct work_struct *w) /* disable BSV bit */ writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); msm_otg_start_host(otg->phy, 1); - otg->phy->state = OTG_STATE_A_HOST; + otg->state = OTG_STATE_A_HOST; } else if (test_bit(B_SESS_VLD, &motg->inputs)) { switch (motg->chg_state) { case USB_CHG_STATE_UNDEFINED: @@ -1199,13 +1199,13 @@ static void msm_otg_sm_work(struct work_struct *w) msm_otg_notify_charger(motg, IDEV_CHG_MAX); msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state + otg->state = OTG_STATE_B_PERIPHERAL; break; case USB_SDP_CHARGER: msm_otg_notify_charger(motg, IUNIT); msm_otg_start_peripheral(otg->phy, 1); - otg->phy->state + otg->state = OTG_STATE_B_PERIPHERAL; break; default: @@ -1230,7 +1230,7 @@ static void msm_otg_sm_work(struct work_struct *w) motg->chg_type = USB_INVALID_CHARGER; } - if (otg->phy->state == OTG_STATE_B_IDLE) + if (otg->state == OTG_STATE_B_IDLE) pm_runtime_put_sync(otg->phy->dev); break; case OTG_STATE_B_PERIPHERAL: @@ -1241,7 +1241,7 @@ static void msm_otg_sm_work(struct work_struct *w) msm_otg_start_peripheral(otg->phy, 0); motg->chg_state = USB_CHG_STATE_UNDEFINED; motg->chg_type = USB_INVALID_CHARGER; - otg->phy->state = OTG_STATE_B_IDLE; + otg->state = OTG_STATE_B_IDLE; msm_otg_reset(otg->phy); schedule_work(w); } @@ -1250,7 +1250,7 @@ static void msm_otg_sm_work(struct work_struct *w) dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); if (test_bit(ID, &motg->inputs)) { msm_otg_start_host(otg->phy, 0); - otg->phy->state = OTG_STATE_B_IDLE; + otg->state = OTG_STATE_B_IDLE; msm_otg_reset(otg->phy); schedule_work(w); } @@ -1303,7 +1303,7 @@ static int msm_otg_mode_show(struct seq_file *s, void *unused) struct msm_otg *motg = s->private; struct usb_otg *otg = motg->phy.otg; - switch (otg->phy->state) { + switch (otg->state) { case OTG_STATE_A_HOST: seq_puts(s, "host\n"); break; @@ -1353,7 +1353,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, switch (req_mode) { case USB_DR_MODE_UNKNOWN: - switch (otg->phy->state) { + switch (otg->state) { case OTG_STATE_A_HOST: case OTG_STATE_B_PERIPHERAL: set_bit(ID, &motg->inputs); @@ -1364,7 +1364,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, } break; case USB_DR_MODE_PERIPHERAL: - switch (otg->phy->state) { + switch (otg->state) { case OTG_STATE_B_IDLE: case OTG_STATE_A_HOST: set_bit(ID, &motg->inputs); @@ -1375,7 +1375,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, } break; case USB_DR_MODE_HOST: - switch (otg->phy->state) { + switch (otg->state) { case OTG_STATE_B_IDLE: case OTG_STATE_B_PERIPHERAL: clear_bit(ID, &motg->inputs); @@ -1769,7 +1769,7 @@ static int msm_otg_runtime_idle(struct device *dev) * This 1 sec delay also prevents entering into LPM immediately * after asynchronous interrupt. */ - if (otg->phy->state != OTG_STATE_UNDEFINED) + if (otg->state != OTG_STATE_UNDEFINED) pm_schedule_suspend(dev, 1000); return -EAGAIN; diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index c9517d8bda8d..ee87aa7144db 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -339,68 +339,68 @@ static void mv_otg_update_state(struct mv_otg *mvotg) { struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; struct usb_phy *phy = &mvotg->phy; - int old_state = phy->state; + int old_state = mvotg->phy.otg->state; switch (old_state) { case OTG_STATE_UNDEFINED: - phy->state = OTG_STATE_B_IDLE; + mvotg->phy.otg->state = OTG_STATE_B_IDLE; /* FALL THROUGH */ case OTG_STATE_B_IDLE: if (otg_ctrl->id == 0) - phy->state = OTG_STATE_A_IDLE; + mvotg->phy.otg->state = OTG_STATE_A_IDLE; else if (otg_ctrl->b_sess_vld) - phy->state = OTG_STATE_B_PERIPHERAL; + mvotg->phy.otg->state = OTG_STATE_B_PERIPHERAL; break; case OTG_STATE_B_PERIPHERAL: if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0) - phy->state = OTG_STATE_B_IDLE; + mvotg->phy.otg->state = OTG_STATE_B_IDLE; break; case OTG_STATE_A_IDLE: if (otg_ctrl->id) - phy->state = OTG_STATE_B_IDLE; + mvotg->phy.otg->state = OTG_STATE_B_IDLE; else if (!(otg_ctrl->a_bus_drop) && (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det)) - phy->state = OTG_STATE_A_WAIT_VRISE; + mvotg->phy.otg->state = OTG_STATE_A_WAIT_VRISE; break; case OTG_STATE_A_WAIT_VRISE: if (otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_WAIT_BCON; + mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON; break; case OTG_STATE_A_WAIT_BCON: if (otg_ctrl->id || otg_ctrl->a_bus_drop || otg_ctrl->a_wait_bcon_timeout) { mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; + mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL; otg_ctrl->a_bus_req = 0; } else if (!otg_ctrl->a_vbus_vld) { mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_VBUS_ERR; + mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR; } else if (otg_ctrl->b_conn) { mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER); mvotg->otg_ctrl.a_wait_bcon_timeout = 0; - phy->state = OTG_STATE_A_HOST; + mvotg->phy.otg->state = OTG_STATE_A_HOST; } break; case OTG_STATE_A_HOST: if (otg_ctrl->id || !otg_ctrl->b_conn || otg_ctrl->a_bus_drop) - phy->state = OTG_STATE_A_WAIT_BCON; + mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON; else if (!otg_ctrl->a_vbus_vld) - phy->state = OTG_STATE_A_VBUS_ERR; + mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR; break; case OTG_STATE_A_WAIT_VFALL: if (otg_ctrl->id || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld) || otg_ctrl->a_bus_req) - phy->state = OTG_STATE_A_IDLE; + mvotg->phy.otg->state = OTG_STATE_A_IDLE; break; case OTG_STATE_A_VBUS_ERR: if (otg_ctrl->id || otg_ctrl->a_clr_err || otg_ctrl->a_bus_drop) { otg_ctrl->a_clr_err = 0; - phy->state = OTG_STATE_A_WAIT_VFALL; + mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL; } break; default: @@ -420,8 +420,8 @@ static void mv_otg_work(struct work_struct *work) run: /* work queue is single thread, or we need spin_lock to protect */ phy = &mvotg->phy; - otg = phy->otg; - old_state = phy->state; + otg = mvotg->phy.otg; + old_state = otg->state; if (!mvotg->active) return; @@ -429,12 +429,12 @@ static void mv_otg_work(struct work_struct *work) mv_otg_update_inputs(mvotg); mv_otg_update_state(mvotg); - if (old_state != phy->state) { + if (old_state != mvotg->phy.otg->state) { dev_info(&mvotg->pdev->dev, "change from state %s to %s\n", state_string[old_state], - state_string[phy->state]); + state_string[mvotg->phy.otg->state]); - switch (phy->state) { + switch (mvotg->phy.otg->state) { case OTG_STATE_B_IDLE: otg->default_a = 0; if (old_state == OTG_STATE_B_PERIPHERAL) @@ -545,8 +545,8 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr, return -1; /* We will use this interface to change to A device */ - if (mvotg->phy.state != OTG_STATE_B_IDLE - && mvotg->phy.state != OTG_STATE_A_IDLE) + if (mvotg->phy.otg->state != OTG_STATE_B_IDLE + && mvotg->phy.otg->state != OTG_STATE_A_IDLE) return -1; /* The clock may disabled and we need to set irq for ID detected */ @@ -715,9 +715,9 @@ static int mv_otg_probe(struct platform_device *pdev) mvotg->phy.dev = &pdev->dev; mvotg->phy.otg = otg; mvotg->phy.label = driver_name; - mvotg->phy.state = OTG_STATE_UNDEFINED; otg->phy = &mvotg->phy; + otg->state = OTG_STATE_UNDEFINED; otg->set_host = mv_otg_set_host; otg->set_peripheral = mv_otg_set_peripheral; otg->set_vbus = mv_otg_set_vbus; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index cc61ee44b911..04ece535c2f8 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -81,33 +81,33 @@ static void check_vbus_state(struct tahvo_usb *tu) reg = retu_read(rdev, TAHVO_REG_IDSR); if (reg & TAHVO_STAT_VBUS) { - switch (tu->phy.state) { + switch (tu->phy.otg->state) { case OTG_STATE_B_IDLE: /* Enable the gadget driver */ if (tu->phy.otg->gadget) usb_gadget_vbus_connect(tu->phy.otg->gadget); - tu->phy.state = OTG_STATE_B_PERIPHERAL; + tu->phy.otg->state = OTG_STATE_B_PERIPHERAL; break; case OTG_STATE_A_IDLE: /* * Session is now valid assuming the USB hub is driving * Vbus. */ - tu->phy.state = OTG_STATE_A_HOST; + tu->phy.otg->state = OTG_STATE_A_HOST; break; default: break; } dev_info(&tu->pt_dev->dev, "USB cable connected\n"); } else { - switch (tu->phy.state) { + switch (tu->phy.otg->state) { case OTG_STATE_B_PERIPHERAL: if (tu->phy.otg->gadget) usb_gadget_vbus_disconnect(tu->phy.otg->gadget); - tu->phy.state = OTG_STATE_B_IDLE; + tu->phy.otg->state = OTG_STATE_B_IDLE; break; case OTG_STATE_A_HOST: - tu->phy.state = OTG_STATE_A_IDLE; + tu->phy.otg->state = OTG_STATE_A_IDLE; break; default: break; @@ -132,14 +132,14 @@ static void tahvo_usb_become_host(struct tahvo_usb *tu) /* Power up the transceiver in USB host mode */ retu_write(rdev, TAHVO_REG_USBR, USBR_REGOUT | USBR_NSUSPEND | USBR_MASTER_SW2 | USBR_MASTER_SW1); - tu->phy.state = OTG_STATE_A_IDLE; + tu->phy.otg->state = OTG_STATE_A_IDLE; check_vbus_state(tu); } static void tahvo_usb_stop_host(struct tahvo_usb *tu) { - tu->phy.state = OTG_STATE_A_IDLE; + tu->phy.otg->state = OTG_STATE_A_IDLE; } static void tahvo_usb_become_peripheral(struct tahvo_usb *tu) @@ -151,7 +151,7 @@ static void tahvo_usb_become_peripheral(struct tahvo_usb *tu) /* Power up transceiver and set it in USB peripheral mode */ retu_write(rdev, TAHVO_REG_USBR, USBR_SLAVE_CONTROL | USBR_REGOUT | USBR_NSUSPEND | USBR_SLAVE_SW); - tu->phy.state = OTG_STATE_B_IDLE; + tu->phy.otg->state = OTG_STATE_B_IDLE; check_vbus_state(tu); } @@ -160,7 +160,7 @@ static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu) { if (tu->phy.otg->gadget) usb_gadget_vbus_disconnect(tu->phy.otg->gadget); - tu->phy.state = OTG_STATE_B_IDLE; + tu->phy.otg->state = OTG_STATE_B_IDLE; } static void tahvo_usb_power_off(struct tahvo_usb *tu) @@ -173,7 +173,7 @@ static void tahvo_usb_power_off(struct tahvo_usb *tu) /* Power off transceiver */ retu_write(rdev, TAHVO_REG_USBR, 0); - tu->phy.state = OTG_STATE_UNDEFINED; + tu->phy.otg->state = OTG_STATE_UNDEFINED; } static int tahvo_usb_set_suspend(struct usb_phy *dev, int suspend) @@ -379,7 +379,7 @@ static int tahvo_usb_probe(struct platform_device *pdev) /* Create OTG interface */ tahvo_usb_power_off(tu); tu->phy.dev = &pdev->dev; - tu->phy.state = OTG_STATE_UNDEFINED; + tu->phy.otg->state = OTG_STATE_UNDEFINED; tu->phy.label = DRIVER_NAME; tu->phy.set_suspend = tahvo_usb_set_suspend; diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 154332b7c8c0..33d3480c9cda 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -18,6 +18,8 @@ struct usb_otg { struct usb_bus *host; struct usb_gadget *gadget; + enum usb_otg_state state; + /* bind/unbind the host controller */ int (*set_host)(struct usb_otg *otg, struct usb_bus *host); diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 353053a33f21..ac7d7913694f 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -77,7 +77,6 @@ struct usb_phy { unsigned int flags; enum usb_phy_type type; - enum usb_otg_state state; enum usb_phy_events last_event; struct usb_otg *otg; -- GitLab From 19c1eac2685b62640ca2386a0a885ac2152668c8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:14 +0100 Subject: [PATCH 2623/9457] usb: rename phy to usb_phy in OTG This patch prepares the introduction of the generic PHY support in the USB OTG common functions. The USB PHY member of the OTG structure is renamed to 'usb_phy' and modifications are done in all drivers accessing it. Renaming this pointer will allow to keep the compatibility for USB PHY drivers. Signed-off-by: Antoine Tenart Signed-off-by: Felipe Balbi --- drivers/phy/phy-omap-usb2.c | 6 +-- drivers/usb/chipidea/otg_fsm.c | 2 +- drivers/usb/phy/phy-ab8500-usb.c | 6 +-- drivers/usb/phy/phy-fsl-usb.c | 13 +++--- drivers/usb/phy/phy-generic.c | 2 +- drivers/usb/phy/phy-gpio-vbus-usb.c | 4 +- drivers/usb/phy/phy-isp1301-omap.c | 10 ++--- drivers/usb/phy/phy-msm-usb.c | 61 +++++++++++++++-------------- drivers/usb/phy/phy-mv-usb.c | 4 +- drivers/usb/phy/phy-tahvo.c | 8 ++-- drivers/usb/phy/phy-ulpi.c | 6 +-- include/linux/usb/otg.h | 2 +- 12 files changed, 65 insertions(+), 59 deletions(-) diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 9f4093590f4c..32c3e86b4935 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -60,7 +60,7 @@ EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) { - struct omap_usb *phy = phy_to_omapusb(otg->phy); + struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); if (!phy->comparator) return -ENODEV; @@ -70,7 +70,7 @@ static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) static int omap_usb_start_srp(struct usb_otg *otg) { - struct omap_usb *phy = phy_to_omapusb(otg->phy); + struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); if (!phy->comparator) return -ENODEV; @@ -251,7 +251,7 @@ static int omap_usb2_probe(struct platform_device *pdev) otg->set_vbus = omap_usb_set_vbus; if (phy_data->flags & OMAP_USB2_HAS_START_SRP) otg->start_srp = omap_usb_start_srp; - otg->phy = &phy->phy; + otg->usb_phy = &phy->phy; platform_set_drvdata(pdev, phy); diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 8cb2508a6b71..d8490e758a74 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -788,7 +788,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) return -ENOMEM; } - otg->phy = ci->transceiver; + otg->usb_phy = ci->transceiver; otg->gadget = &ci->gadget; ci->fsm.otg = otg; ci->transceiver->otg = ci->fsm.otg; diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 2d5250143ce1..3a802fa7dae2 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -1056,7 +1056,7 @@ static int ab8500_usb_set_peripheral(struct usb_otg *otg, if (!otg) return -ENODEV; - ab = phy_to_ab(otg->phy); + ab = phy_to_ab(otg->usb_phy); ab->phy.otg->gadget = gadget; @@ -1080,7 +1080,7 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) if (!otg) return -ENODEV; - ab = phy_to_ab(otg->phy); + ab = phy_to_ab(otg->usb_phy); ab->phy.otg->host = host; @@ -1382,7 +1382,7 @@ static int ab8500_usb_probe(struct platform_device *pdev) ab->phy.set_power = ab8500_usb_set_power; ab->phy.otg->state = OTG_STATE_UNDEFINED; - otg->phy = &ab->phy; + otg->usb_phy = &ab->phy; otg->set_host = ab8500_usb_set_host; otg->set_peripheral = ab8500_usb_set_peripheral; diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index 15d7a81eece5..b7f36b212422 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -499,7 +499,8 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on) { struct usb_otg *otg = fsm->otg; struct device *dev; - struct fsl_otg *otg_dev = container_of(otg->phy, struct fsl_otg, phy); + struct fsl_otg *otg_dev = + container_of(otg->usb_phy, struct fsl_otg, phy); u32 retval = 0; if (!otg->host) @@ -594,7 +595,7 @@ static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) if (!otg) return -ENODEV; - otg_dev = container_of(otg->phy, struct fsl_otg, phy); + otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); if (otg_dev != fsl_otg_dev) return -ENODEV; @@ -644,7 +645,7 @@ static int fsl_otg_set_peripheral(struct usb_otg *otg, if (!otg) return -ENODEV; - otg_dev = container_of(otg->phy, struct fsl_otg, phy); + otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); VDBG("otg_dev 0x%x\n", (int)otg_dev); VDBG("fsl_otg_dev 0x%x\n", (int)fsl_otg_dev); if (otg_dev != fsl_otg_dev) @@ -717,7 +718,7 @@ static int fsl_otg_start_srp(struct usb_otg *otg) if (!otg || otg.state != OTG_STATE_B_IDLE) return -ENODEV; - otg_dev = container_of(otg->phy, struct fsl_otg, phy); + otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); if (otg_dev != fsl_otg_dev) return -ENODEV; @@ -735,7 +736,7 @@ static int fsl_otg_start_hnp(struct usb_otg *otg) if (!otg) return -ENODEV; - otg_dev = container_of(otg->phy, struct fsl_otg, phy); + otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); if (otg_dev != fsl_otg_dev) return -ENODEV; @@ -857,7 +858,7 @@ static int fsl_otg_conf(struct platform_device *pdev) fsl_otg_tc->phy.dev = &pdev->dev; fsl_otg_tc->phy.set_power = fsl_otg_set_power; - fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; + fsl_otg_tc->phy.otg->usb_phy = &fsl_otg_tc->phy; fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 280a3458ff6b..0c01bd12cabc 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -228,7 +228,7 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, nop->phy.type = type; nop->phy.otg->state = OTG_STATE_UNDEFINED; - nop->phy.otg->phy = &nop->phy; + nop->phy.otg->usb_phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index 7a6be3e5dc23..9fcf19ba1416 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -180,7 +180,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, struct platform_device *pdev; int gpio; - gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); + gpio_vbus = container_of(otg->usb_phy, struct gpio_vbus_data, phy); pdev = to_platform_device(gpio_vbus->dev); pdata = dev_get_platdata(gpio_vbus->dev); gpio = pdata->gpio_pullup; @@ -271,7 +271,7 @@ static int gpio_vbus_probe(struct platform_device *pdev) gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; gpio_vbus->phy.otg->state = OTG_STATE_UNDEFINED; - gpio_vbus->phy.otg->phy = &gpio_vbus->phy; + gpio_vbus->phy.otg->usb_phy = &gpio_vbus->phy; gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; err = devm_gpio_request(&pdev->dev, gpio, "vbus_detect"); diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 24f84cbbed57..a2dfb2ae520e 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -1275,7 +1275,7 @@ static int isp1301_otg_enable(struct isp1301 *isp) static int isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) { - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + struct isp1301 *isp = container_of(otg->usb_phy, struct isp1301, phy); if (isp != the_transceiver) return -ENODEV; @@ -1331,7 +1331,7 @@ isp1301_set_host(struct usb_otg *otg, struct usb_bus *host) static int isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + struct isp1301 *isp = container_of(otg->usb_phy, struct isp1301, phy); if (isp != the_transceiver) return -ENODEV; @@ -1411,7 +1411,7 @@ isp1301_set_power(struct usb_phy *dev, unsigned mA) static int isp1301_start_srp(struct usb_otg *otg) { - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + struct isp1301 *isp = container_of(otg->usb_phy, struct isp1301, phy); u32 otg_ctrl; if (isp != the_transceiver || isp->phy.otg->state != OTG_STATE_B_IDLE) @@ -1438,7 +1438,7 @@ static int isp1301_start_hnp(struct usb_otg *otg) { #ifdef CONFIG_USB_OTG - struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); + struct isp1301 *isp = container_of(otg->usb_phy, struct isp1301, phy); u32 l; if (isp != the_transceiver) @@ -1583,7 +1583,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) isp->phy.label = DRIVER_NAME; isp->phy.set_power = isp1301_set_power, - isp->phy.otg->phy = &isp->phy; + isp->phy.otg->usb_phy = &isp->phy; isp->phy.otg->set_host = isp1301_set_host, isp->phy.otg->set_peripheral = isp1301_set_peripheral, isp->phy.otg->start_srp = isp1301_start_srp, diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 18015b7c8afc..e120d87778b2 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -708,7 +708,7 @@ static void msm_otg_start_host(struct usb_phy *phy, int on) static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) { - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + struct msm_otg *motg = container_of(otg->usb_phy, struct msm_otg, phy); struct usb_hcd *hcd; /* @@ -716,14 +716,14 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) * only peripheral configuration. */ if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) { - dev_info(otg->phy->dev, "Host mode is not supported\n"); + dev_info(otg->usb_phy->dev, "Host mode is not supported\n"); return -ENODEV; } if (!host) { if (otg->state == OTG_STATE_A_HOST) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_host(otg->phy, 0); + pm_runtime_get_sync(otg->usb_phy->dev); + msm_otg_start_host(otg->usb_phy, 0); otg->host = NULL; otg->state = OTG_STATE_UNDEFINED; schedule_work(&motg->sm_work); @@ -738,14 +738,14 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) hcd->power_budget = motg->pdata->power_budget; otg->host = host; - dev_dbg(otg->phy->dev, "host driver registered w/ tranceiver\n"); + dev_dbg(otg->usb_phy->dev, "host driver registered w/ tranceiver\n"); /* * Kick the state machine work, if peripheral is not supported * or peripheral is already registered with us. */ if (motg->pdata->mode == USB_DR_MODE_HOST || otg->gadget) { - pm_runtime_get_sync(otg->phy->dev); + pm_runtime_get_sync(otg->usb_phy->dev); schedule_work(&motg->sm_work); } @@ -782,21 +782,21 @@ static void msm_otg_start_peripheral(struct usb_phy *phy, int on) static int msm_otg_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { - struct msm_otg *motg = container_of(otg->phy, struct msm_otg, phy); + struct msm_otg *motg = container_of(otg->usb_phy, struct msm_otg, phy); /* * Fail peripheral registration if this board can support * only host configuration. */ if (motg->pdata->mode == USB_DR_MODE_HOST) { - dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); + dev_info(otg->usb_phy->dev, "Peripheral mode is not supported\n"); return -ENODEV; } if (!gadget) { if (otg->state == OTG_STATE_B_PERIPHERAL) { - pm_runtime_get_sync(otg->phy->dev); - msm_otg_start_peripheral(otg->phy, 0); + pm_runtime_get_sync(otg->usb_phy->dev); + msm_otg_start_peripheral(otg->usb_phy, 0); otg->gadget = NULL; otg->state = OTG_STATE_UNDEFINED; schedule_work(&motg->sm_work); @@ -807,14 +807,15 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, return 0; } otg->gadget = gadget; - dev_dbg(otg->phy->dev, "peripheral driver registered w/ tranceiver\n"); + dev_dbg(otg->usb_phy->dev, + "peripheral driver registered w/ tranceiver\n"); /* * Kick the state machine work, if host is not supported * or host is already registered with us. */ if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL || otg->host) { - pm_runtime_get_sync(otg->phy->dev); + pm_runtime_get_sync(otg->usb_phy->dev); schedule_work(&motg->sm_work); } @@ -1172,17 +1173,17 @@ static void msm_otg_sm_work(struct work_struct *w) switch (otg->state) { case OTG_STATE_UNDEFINED: - dev_dbg(otg->phy->dev, "OTG_STATE_UNDEFINED state\n"); - msm_otg_reset(otg->phy); + dev_dbg(otg->usb_phy->dev, "OTG_STATE_UNDEFINED state\n"); + msm_otg_reset(otg->usb_phy); msm_otg_init_sm(motg); otg->state = OTG_STATE_B_IDLE; /* FALL THROUGH */ case OTG_STATE_B_IDLE: - dev_dbg(otg->phy->dev, "OTG_STATE_B_IDLE state\n"); + dev_dbg(otg->usb_phy->dev, "OTG_STATE_B_IDLE state\n"); if (!test_bit(ID, &motg->inputs) && otg->host) { /* disable BSV bit */ writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); - msm_otg_start_host(otg->phy, 1); + msm_otg_start_host(otg->usb_phy, 1); otg->state = OTG_STATE_A_HOST; } else if (test_bit(B_SESS_VLD, &motg->inputs)) { switch (motg->chg_state) { @@ -1198,13 +1199,15 @@ static void msm_otg_sm_work(struct work_struct *w) case USB_CDP_CHARGER: msm_otg_notify_charger(motg, IDEV_CHG_MAX); - msm_otg_start_peripheral(otg->phy, 1); + msm_otg_start_peripheral(otg->usb_phy, + 1); otg->state = OTG_STATE_B_PERIPHERAL; break; case USB_SDP_CHARGER: msm_otg_notify_charger(motg, IUNIT); - msm_otg_start_peripheral(otg->phy, 1); + msm_otg_start_peripheral(otg->usb_phy, + 1); otg->state = OTG_STATE_B_PERIPHERAL; break; @@ -1222,8 +1225,8 @@ static void msm_otg_sm_work(struct work_struct *w) * is incremented in charger detection work. */ if (cancel_delayed_work_sync(&motg->chg_work)) { - pm_runtime_put_sync(otg->phy->dev); - msm_otg_reset(otg->phy); + pm_runtime_put_sync(otg->usb_phy->dev); + msm_otg_reset(otg->usb_phy); } msm_otg_notify_charger(motg, 0); motg->chg_state = USB_CHG_STATE_UNDEFINED; @@ -1231,27 +1234,27 @@ static void msm_otg_sm_work(struct work_struct *w) } if (otg->state == OTG_STATE_B_IDLE) - pm_runtime_put_sync(otg->phy->dev); + pm_runtime_put_sync(otg->usb_phy->dev); break; case OTG_STATE_B_PERIPHERAL: - dev_dbg(otg->phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); + dev_dbg(otg->usb_phy->dev, "OTG_STATE_B_PERIPHERAL state\n"); if (!test_bit(B_SESS_VLD, &motg->inputs) || !test_bit(ID, &motg->inputs)) { msm_otg_notify_charger(motg, 0); - msm_otg_start_peripheral(otg->phy, 0); + msm_otg_start_peripheral(otg->usb_phy, 0); motg->chg_state = USB_CHG_STATE_UNDEFINED; motg->chg_type = USB_INVALID_CHARGER; otg->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); + msm_otg_reset(otg->usb_phy); schedule_work(w); } break; case OTG_STATE_A_HOST: - dev_dbg(otg->phy->dev, "OTG_STATE_A_HOST state\n"); + dev_dbg(otg->usb_phy->dev, "OTG_STATE_A_HOST state\n"); if (test_bit(ID, &motg->inputs)) { - msm_otg_start_host(otg->phy, 0); + msm_otg_start_host(otg->usb_phy, 0); otg->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg->phy); + msm_otg_reset(otg->usb_phy); schedule_work(w); } break; @@ -1388,7 +1391,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, goto out; } - pm_runtime_get_sync(otg->phy->dev); + pm_runtime_get_sync(otg->usb_phy->dev); schedule_work(&motg->sm_work); out: return status; @@ -1668,7 +1671,7 @@ static int msm_otg_probe(struct platform_device *pdev) phy->io_ops = &msm_otg_io_ops; - phy->otg->phy = &motg->phy; + phy->otg->usb_phy = &motg->phy; phy->otg->set_host = msm_otg_set_host; phy->otg->set_peripheral = msm_otg_set_peripheral; diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index ee87aa7144db..81d934fdd0c3 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -56,7 +56,7 @@ static char *state_string[] = { static int mv_otg_set_vbus(struct usb_otg *otg, bool on) { - struct mv_otg *mvotg = container_of(otg->phy, struct mv_otg, phy); + struct mv_otg *mvotg = container_of(otg->usb_phy, struct mv_otg, phy); if (mvotg->pdata->set_vbus == NULL) return -ENODEV; @@ -716,8 +716,8 @@ static int mv_otg_probe(struct platform_device *pdev) mvotg->phy.otg = otg; mvotg->phy.label = driver_name; - otg->phy = &mvotg->phy; otg->state = OTG_STATE_UNDEFINED; + otg->usb_phy = &mvotg->phy; otg->set_host = mv_otg_set_host; otg->set_peripheral = mv_otg_set_peripheral; otg->set_vbus = mv_otg_set_vbus; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index 04ece535c2f8..9cabc1a20d1c 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -196,7 +196,8 @@ static int tahvo_usb_set_suspend(struct usb_phy *dev, int suspend) static int tahvo_usb_set_host(struct usb_otg *otg, struct usb_bus *host) { - struct tahvo_usb *tu = container_of(otg->phy, struct tahvo_usb, phy); + struct tahvo_usb *tu = container_of(otg->usb_phy, struct tahvo_usb, + phy); dev_dbg(&tu->pt_dev->dev, "%s %p\n", __func__, host); @@ -225,7 +226,8 @@ static int tahvo_usb_set_host(struct usb_otg *otg, struct usb_bus *host) static int tahvo_usb_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { - struct tahvo_usb *tu = container_of(otg->phy, struct tahvo_usb, phy); + struct tahvo_usb *tu = container_of(otg->usb_phy, struct tahvo_usb, + phy); dev_dbg(&tu->pt_dev->dev, "%s %p\n", __func__, gadget); @@ -383,7 +385,7 @@ static int tahvo_usb_probe(struct platform_device *pdev) tu->phy.label = DRIVER_NAME; tu->phy.set_suspend = tahvo_usb_set_suspend; - tu->phy.otg->phy = &tu->phy; + tu->phy.otg->usb_phy = &tu->phy; tu->phy.otg->set_host = tahvo_usb_set_host; tu->phy.otg->set_peripheral = tahvo_usb_set_peripheral; diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 4e3877c329f2..f48a7a21e3c2 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c @@ -211,7 +211,7 @@ static int ulpi_init(struct usb_phy *phy) static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) { - struct usb_phy *phy = otg->phy; + struct usb_phy *phy = otg->usb_phy; unsigned int flags = usb_phy_io_read(phy, ULPI_IFC_CTRL); if (!host) { @@ -237,7 +237,7 @@ static int ulpi_set_host(struct usb_otg *otg, struct usb_bus *host) static int ulpi_set_vbus(struct usb_otg *otg, bool on) { - struct usb_phy *phy = otg->phy; + struct usb_phy *phy = otg->usb_phy; unsigned int flags = usb_phy_io_read(phy, ULPI_OTG_CTRL); flags &= ~(ULPI_OTG_CTRL_DRVVBUS | ULPI_OTG_CTRL_DRVVBUS_EXT); @@ -276,7 +276,7 @@ otg_ulpi_create(struct usb_phy_io_ops *ops, phy->otg = otg; phy->init = ulpi_init; - otg->phy = phy; + otg->usb_phy = phy; otg->set_host = ulpi_set_host; otg->set_vbus = ulpi_set_vbus; diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 33d3480c9cda..978fbbb0e266 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -14,7 +14,7 @@ struct usb_otg { u8 default_a; - struct usb_phy *phy; + struct usb_phy *usb_phy; struct usb_bus *host; struct usb_gadget *gadget; -- GitLab From 48bcc18076df4e07ef86226ac6ce795f64c84f7f Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:15 +0100 Subject: [PATCH 2624/9457] usb: add support to the generic PHY framework in OTG This patch adds support of the PHY framework in OTG and keeps the USB PHY compatibility. Here the only modification is to add PHY member in the OTG structure, along with the USB PHY one. Signed-off-by: Antoine Tenart Signed-off-by: Felipe Balbi --- include/linux/usb/otg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 978fbbb0e266..52661c5da690 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -9,11 +9,14 @@ #ifndef __LINUX_USB_OTG_H #define __LINUX_USB_OTG_H +#include #include struct usb_otg { u8 default_a; + struct phy *phy; + /* old usb_phy interface */ struct usb_phy *usb_phy; struct usb_bus *host; struct usb_gadget *gadget; -- GitLab From ef44cb4226d132146e44f8ea562a16b27ff61126 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:16 +0100 Subject: [PATCH 2625/9457] usb: allow to supply the PHY in the drivers when using HCD This patch modify the generic code handling PHYs to allow them to be supplied from the drivers. This adds checks to ensure no PHY was already there when looking for one in the generic code. This also makes sure we do not modify its state in the generic HCD functions, it was provided by the driver. Signed-off-by: Antoine Tenart Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/ci.h | 5 +++-- drivers/usb/chipidea/ci_hdrc_imx.c | 2 +- drivers/usb/chipidea/ci_hdrc_msm.c | 8 ++++---- drivers/usb/chipidea/core.c | 20 ++++++++++---------- drivers/usb/chipidea/debug.c | 2 +- drivers/usb/chipidea/host.c | 7 ++++--- drivers/usb/chipidea/otg_fsm.c | 16 +++------------- drivers/usb/chipidea/udc.c | 4 ++-- drivers/usb/core/hcd.c | 7 ++++--- include/linux/usb/chipidea.h | 2 +- 10 files changed, 33 insertions(+), 40 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index ea40626e0246..9015139a8027 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -161,7 +161,7 @@ struct hw_bank { * @test_mode: the selected test mode * @platdata: platform specific information supplied by parent device * @vbus_active: is VBUS active - * @transceiver: pointer to USB PHY, if any + * @usb_phy: pointer to USB PHY, if any * @hcd: pointer to usb_hcd for ehci host driver * @debugfs: root dentry for this controller in debugfs * @id_event: indicates there is an id event, and handled at ci_otg_work @@ -177,6 +177,7 @@ struct ci_hdrc { struct ci_role_driver *roles[CI_ROLE_END]; enum ci_role role; bool is_otg; + struct usb_otg otg; struct otg_fsm fsm; struct ci_otg_fsm_timer_list *fsm_timer; struct work_struct work; @@ -201,7 +202,7 @@ struct ci_hdrc { struct ci_hdrc_platform_data *platdata; int vbus_active; - struct usb_phy *transceiver; + struct usb_phy *usb_phy; struct usb_hcd *hcd; struct dentry *debugfs; bool id_event; diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index a7ab0f15926e..6f8b1b1045b5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -147,7 +147,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - pdata.phy = data->phy; + pdata.usb_phy = data->phy; if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX) pdata.flags |= CI_HDRC_IMX28_WRITE_FIX; diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 4935ac38fd00..3edf969ed797 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -26,15 +26,15 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); writel(0, USB_AHBBURST); writel(0, USB_AHBMODE); - usb_phy_init(ci->transceiver); + usb_phy_init(ci->usb_phy); break; case CI_HDRC_CONTROLLER_STOPPED_EVENT: dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n"); /* - * Put the transceiver in non-driving mode. Otherwise host + * Put the phy in non-driving mode. Otherwise host * may not detect soft-disconnection. */ - usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN); + usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN); break; default: dev_dbg(dev, "unknown ci_hdrc event\n"); @@ -68,7 +68,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (IS_ERR(phy)) return PTR_ERR(phy); - ci_hdrc_msm_platdata.phy = phy; + ci_hdrc_msm_platdata.usb_phy = phy; plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource, pdev->num_resources, diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9bdc6bd73432..30f89426bf05 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -312,7 +312,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMI: case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); if (ret) return ret; hw_phymode_configure(ci); @@ -320,12 +320,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_ULPI: case USBPHY_INTERFACE_MODE_SERIAL: hw_phymode_configure(ci); - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); if (ret) return ret; break; default: - ret = usb_phy_init(ci->transceiver); + ret = usb_phy_init(ci->usb_phy); } return ret; @@ -605,13 +605,13 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - if (ci->platdata->phy) - ci->transceiver = ci->platdata->phy; + if (ci->platdata->usb_phy) + ci->usb_phy = ci->platdata->usb_phy; else - ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR(ci->transceiver)) { - ret = PTR_ERR(ci->transceiver); + if (IS_ERR(ci->usb_phy)) { + ret = PTR_ERR(ci->usb_phy); /* * if -ENXIO is returned, it means PHY layer wasn't * enabled, so it makes no sense to return -EPROBE_DEFER @@ -728,7 +728,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) stop: ci_role_destroy(ci); deinit_phy: - usb_phy_shutdown(ci->transceiver); + usb_phy_shutdown(ci->usb_phy); return ret; } @@ -741,7 +741,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); - usb_phy_shutdown(ci->transceiver); + usb_phy_shutdown(ci->usb_phy); return 0; } diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index f038804d13dd..268e4236e84c 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused) /* ------ State ----- */ seq_printf(s, "OTG state: %s\n\n", - usb_otg_state_string(ci->transceiver->otg->state)); + usb_otg_state_string(ci->otg.state)); /* ------ State Machine Variables ----- */ seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop); diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebde7b6ce687..789809f680aa 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -59,7 +59,7 @@ static int host_start(struct ci_hdrc *ci) hcd->has_tt = 1; hcd->power_budget = ci->platdata->power_budget; - hcd->usb_phy = ci->transceiver; + hcd->usb_phy = ci->usb_phy; hcd->tpl_support = ci->platdata->tpl_support; ehci = hcd_to_ehci(hcd); @@ -86,10 +86,11 @@ static int host_start(struct ci_hdrc *ci) if (ret) { goto disable_reg; } else { - struct usb_otg *otg = ci->transceiver->otg; + struct usb_otg *otg = &ci->otg; ci->hcd = hcd; - if (otg) { + + if (ci_otg_is_fsm_mode(ci)) { otg->host = &hcd->self; hcd->self.otg_port = 1; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index d8490e758a74..862d7cb01b92 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -778,20 +778,10 @@ void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci) int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) { int retval = 0; - struct usb_otg *otg; - otg = devm_kzalloc(ci->dev, - sizeof(struct usb_otg), GFP_KERNEL); - if (!otg) { - dev_err(ci->dev, - "Failed to allocate usb_otg structure for ci hdrc otg!\n"); - return -ENOMEM; - } - - otg->usb_phy = ci->transceiver; - otg->gadget = &ci->gadget; - ci->fsm.otg = otg; - ci->transceiver->otg = ci->fsm.otg; + ci->otg.usb_phy = ci->usb_phy; + ci->otg.gadget = &ci->gadget; + ci->fsm.otg = &ci->otg; ci->fsm.power_up = 1; ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; ci->fsm.otg->state = OTG_STATE_UNDEFINED; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index f4397b29891f..a2d80ab3d9c4 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1519,8 +1519,8 @@ static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); - if (ci->transceiver) - return usb_phy_set_power(ci->transceiver, ma); + if (ci->usb_phy) + return usb_phy_set_power(ci->usb_phy, ma); return -ENOTSUPP; } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index b84fb141e122..6a2a2fd990ab 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2648,7 +2648,7 @@ int usb_add_hcd(struct usb_hcd *hcd, } } - if (IS_ENABLED(CONFIG_GENERIC_PHY)) { + if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) { struct phy *phy = phy_get(hcd->self.controller, "usb"); if (IS_ERR(phy)) { @@ -2668,6 +2668,7 @@ int usb_add_hcd(struct usb_hcd *hcd, goto err_phy; } hcd->phy = phy; + hcd->remove_phy = 1; } } @@ -2814,7 +2815,7 @@ int usb_add_hcd(struct usb_hcd *hcd, err_register_bus: hcd_buffer_destroy(hcd); err_create_buf: - if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) { + if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); phy_put(hcd->phy); @@ -2898,7 +2899,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) usb_deregister_bus(&hcd->self); hcd_buffer_destroy(hcd); - if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) { + if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->remove_phy && hcd->phy) { phy_power_off(hcd->phy); phy_exit(hcd->phy); phy_put(hcd->phy); diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index e14c09a45c5a..4fe161a84c7d 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -13,7 +13,7 @@ struct ci_hdrc_platform_data { /* offset of the capability registers */ uintptr_t capoffset; unsigned power_budget; - struct usb_phy *phy; + struct usb_phy *usb_phy; enum usb_phy_interface phy_mode; unsigned long flags; #define CI_HDRC_REGS_SHARED BIT(0) -- GitLab From 1e5e2d3d055436c114e2f16145b83339aed024ff Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 30 Oct 2014 18:41:19 +0100 Subject: [PATCH 2626/9457] usb: chipidea: add support to the generic PHY framework This patch adds support of the PHY framework for ChipIdea drivers. Changes are done in both the ChipIdea common code and in the drivers accessing the PHY. This is done by adding a new PHY member in ChipIdea's structures and by taking care of it in the code. Signed-off-by: Antoine Tenart Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/ci.h | 5 +- drivers/usb/chipidea/core.c | 83 ++++++++++++++++++++++++++-------- drivers/usb/chipidea/host.c | 5 +- drivers/usb/chipidea/otg_fsm.c | 6 ++- include/linux/usb/chipidea.h | 2 + 5 files changed, 80 insertions(+), 21 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 9015139a8027..5bbfcc73cf70 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -161,7 +161,8 @@ struct hw_bank { * @test_mode: the selected test mode * @platdata: platform specific information supplied by parent device * @vbus_active: is VBUS active - * @usb_phy: pointer to USB PHY, if any + * @phy: pointer to PHY, if any + * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework * @hcd: pointer to usb_hcd for ehci host driver * @debugfs: root dentry for this controller in debugfs * @id_event: indicates there is an id event, and handled at ci_otg_work @@ -202,6 +203,8 @@ struct ci_hdrc { struct ci_hdrc_platform_data *platdata; int vbus_active; + struct phy *phy; + /* old usb_phy interface */ struct usb_phy *usb_phy; struct usb_hcd *hcd; struct dentry *debugfs; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 30f89426bf05..60578d9c896d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,49 @@ static void hw_phymode_configure(struct ci_hdrc *ci) } } +/** + * _ci_usb_phy_init: initialize phy taking in account both phy and usb_phy + * interfaces + * @ci: the controller + * + * This function returns an error code if the phy failed to init + */ +static int _ci_usb_phy_init(struct ci_hdrc *ci) +{ + int ret; + + if (ci->phy) { + ret = phy_init(ci->phy); + if (ret) + return ret; + + ret = phy_power_on(ci->phy); + if (ret) { + phy_exit(ci->phy); + return ret; + } + } else { + ret = usb_phy_init(ci->usb_phy); + } + + return ret; +} + +/** + * _ci_usb_phy_exit: deinitialize phy taking in account both phy and usb_phy + * interfaces + * @ci: the controller + */ +static void ci_usb_phy_exit(struct ci_hdrc *ci) +{ + if (ci->phy) { + phy_power_off(ci->phy); + phy_exit(ci->phy); + } else { + usb_phy_shutdown(ci->usb_phy); + } +} + /** * ci_usb_phy_init: initialize phy according to different phy type * @ci: the controller @@ -312,7 +356,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMI: case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); if (ret) return ret; hw_phymode_configure(ci); @@ -320,12 +364,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_ULPI: case USBPHY_INTERFACE_MODE_SERIAL: hw_phymode_configure(ci); - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); if (ret) return ret; break; default: - ret = usb_phy_init(ci->usb_phy); + ret = _ci_usb_phy_init(ci); } return ret; @@ -605,23 +649,26 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - if (ci->platdata->usb_phy) + if (ci->platdata->phy) { + ci->phy = ci->platdata->phy; + } else if (ci->platdata->usb_phy) { ci->usb_phy = ci->platdata->usb_phy; - else + } else { + ci->phy = devm_phy_get(dev, "usb-phy"); ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); - if (IS_ERR(ci->usb_phy)) { - ret = PTR_ERR(ci->usb_phy); - /* - * if -ENXIO is returned, it means PHY layer wasn't - * enabled, so it makes no sense to return -EPROBE_DEFER - * in that case, since no PHY driver will ever probe. - */ - if (ret == -ENXIO) - return ret; + /* if both generic PHY and USB PHY layers aren't enabled */ + if (PTR_ERR(ci->phy) == -ENOSYS && + PTR_ERR(ci->usb_phy) == -ENXIO) + return -ENXIO; + + if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) + return -EPROBE_DEFER; - dev_err(dev, "no usb2 phy configured\n"); - return -EPROBE_DEFER; + if (IS_ERR(ci->phy)) + ci->phy = NULL; + else if (IS_ERR(ci->usb_phy)) + ci->usb_phy = NULL; } ret = ci_usb_phy_init(ci); @@ -728,7 +775,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) stop: ci_role_destroy(ci); deinit_phy: - usb_phy_shutdown(ci->usb_phy); + ci_usb_phy_exit(ci); return ret; } @@ -741,7 +788,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); - usb_phy_shutdown(ci->usb_phy); + ci_usb_phy_exit(ci); return 0; } diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 789809f680aa..4f8eb40ad93a 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -59,8 +59,11 @@ static int host_start(struct ci_hdrc *ci) hcd->has_tt = 1; hcd->power_budget = ci->platdata->power_budget; - hcd->usb_phy = ci->usb_phy; hcd->tpl_support = ci->platdata->tpl_support; + if (ci->phy) + hcd->phy = ci->phy; + else + hcd->usb_phy = ci->usb_phy; ehci = hcd_to_ehci(hcd); ehci->caps = ci->hw_bank.cap; diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 862d7cb01b92..3c2ab1ae00fc 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -779,7 +779,11 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) { int retval = 0; - ci->otg.usb_phy = ci->usb_phy; + if (ci->phy) + ci->otg.phy = ci->phy; + else + ci->otg.usb_phy = ci->usb_phy; + ci->otg.gadget = &ci->gadget; ci->fsm.otg = &ci->otg; ci->fsm.power_up = 1; diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 4fe161a84c7d..c01bf4ea27b9 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -13,6 +13,8 @@ struct ci_hdrc_platform_data { /* offset of the capability registers */ uintptr_t capoffset; unsigned power_budget; + struct phy *phy; + /* old usb_phy interface */ struct usb_phy *usb_phy; enum usb_phy_interface phy_mode; unsigned long flags; -- GitLab From 2eac3992897e3e1be40e518032dbfd6aeca1932b Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:22 +0800 Subject: [PATCH 2627/9457] usb: dwc3: enable hibernation if to be supported It enables hibernation if the function is set in coreConsultant. Suggested-by: Felipe Balbi Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fa396fc57a85..2f7aecc620e7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -449,6 +449,12 @@ static int dwc3_core_init(struct dwc3 *dwc) case DWC3_GHWPARAMS1_EN_PWROPT_HIB: /* enable hibernation here */ dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); + + /* + * REVISIT Enabling this bit so that host-mode hibernation + * will work. Device-mode hibernation is not yet implemented. + */ + reg |= DWC3_GCTL_GBLHIBERNATIONEN; break; default: dev_dbg(dwc->dev, "No power optimization available\n"); -- GitLab From 946bd579a6385508bd93c9d453916c1a06c548ae Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:23 +0800 Subject: [PATCH 2628/9457] usb: dwc3: add a flag to check if it is fpga board Some chip vendor is on pre-silicon phase, which needs to use the simulation board. It should have the same product and vendor id with the true soc, but might have some minor different configurations. Below thread discussion proposes to find a method to distinguish between simulation board and soc. http://marc.info/?l=linux-usb&m=141194772206369&w=2 In Andvanced Configuration of coreConsultant, there is the parameter of DWC_USB_EN_FPGA. This bit has the function we need. And it would response as 7 bit of GHWPARAMS6 register. So it's able to check this functional bit to confirm if works on FPGA board. Reported-by: Felipe Balbi Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 2f7aecc620e7..9830f87b6940 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -460,6 +460,12 @@ static int dwc3_core_init(struct dwc3 *dwc) dev_dbg(dwc->dev, "No power optimization available\n"); } + /* check if current dwc3 is on simulation board */ + if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { + dev_dbg(dwc->dev, "it is on FPGA board\n"); + dwc->is_fpga = true; + } + /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index a715ee1f3c06..f6ee623e2d1b 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -210,6 +210,9 @@ #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) #define DWC3_MAX_HIBER_SCRATCHBUFS 15 +/* Global HWPARAMS6 Register */ +#define DWC3_GHWPARAMS6_EN_FPGA (1 << 7) + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) @@ -662,6 +665,7 @@ struct dwc3_scratchpad_array { * @ep0_expect_in: true when we expect a DATA IN transfer * @has_hibernation: true when dwc3 was configured with Hibernation * @is_selfpowered: true when we are selfpowered + * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it * @pullups_connected: true when Run/Stop bit is set * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. @@ -765,6 +769,7 @@ struct dwc3 { unsigned ep0_expect_in:1; unsigned has_hibernation:1; unsigned is_selfpowered:1; + unsigned is_fpga:1; unsigned needs_fifo_resize:1; unsigned pullups_connected:1; unsigned resize_fifos:1; -- GitLab From 8f317b47140ddbce831176db9669d2100030d18a Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:24 +0800 Subject: [PATCH 2629/9457] usb: dwc3: initialize platform data at pci glue layer This patch initializes platform data at pci glue layer, and SoCs x86-based platform vendor is able to define their flags in platform data at bus glue layer. Then do some independent behaviors at dwc3 core level. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index a36cf66302fb..ada975f0b365 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -25,6 +25,8 @@ #include #include +#include "platform_data.h" + /* FIXME define these in */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd @@ -102,6 +104,9 @@ static int dwc3_pci_probe(struct pci_dev *pci, struct dwc3_pci *glue; int ret; struct device *dev = &pci->dev; + struct dwc3_platform_data dwc3_pdata; + + memset(&dwc3_pdata, 0x00, sizeof(dwc3_pdata)); glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); if (!glue) @@ -148,6 +153,10 @@ static int dwc3_pci_probe(struct pci_dev *pci, pci_set_drvdata(pci, glue); + ret = platform_device_add_data(dwc3, &dwc3_pdata, sizeof(dwc3_pdata)); + if (ret) + goto err3; + dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); dwc3->dev.dma_mask = dev->dma_mask; -- GitLab From 3b81221a529c087171557d7c4aec02b0ba029bb1 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:25 +0800 Subject: [PATCH 2630/9457] usb: dwc3: add disscramble quirk This patch adds disscramble quirk, and it only needs to be enabled at fpga board on some vendor platforms. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 14 +++++++++++++- drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 471366d6a129..8ec2256a4a09 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -14,6 +14,8 @@ Optional properties: - phys: from the *Generic PHY* bindings - phy-names: from the *Generic PHY* bindings - tx-fifo-resize: determines if the FIFO *has* to be reallocated. + - snps,disable_scramble_quirk: true when SW should disable data scrambling. + Only really useful for FPGA builds. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 9830f87b6940..a0ae1326b7e3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -422,7 +422,6 @@ static int dwc3_core_init(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; - reg &= ~DWC3_GCTL_DISSCRAMBLE; switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { case DWC3_GHWPARAMS1_EN_PWROPT_CLK: @@ -466,6 +465,14 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc->is_fpga = true; } + WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga, + "disable_scramble cannot be used on non-FPGA builds\n"); + + if (dwc->disable_scramble_quirk && dwc->is_fpga) + reg |= DWC3_GCTL_DISSCRAMBLE; + else + reg &= ~DWC3_GCTL_DISSCRAMBLE; + /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed @@ -710,11 +717,16 @@ static int dwc3_probe(struct platform_device *pdev) dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); + + dwc->disable_scramble_quirk = of_property_read_bool(node, + "snps,disable_scramble_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; + + dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f6ee623e2d1b..56bada6c8604 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -672,6 +672,7 @@ struct dwc3_scratchpad_array { * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup + * @disable_scramble_quirk: set if we enable the disable scramble quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -776,6 +777,8 @@ struct dwc3 { unsigned setup_packet_pending:1; unsigned start_config_issued:1; unsigned three_stage_setup:1; + + unsigned disable_scramble_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 7db34f00b89a..9209d025597b 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -24,4 +24,6 @@ struct dwc3_platform_data { enum usb_device_speed maximum_speed; enum usb_dr_mode dr_mode; bool tx_fifo_resize; + + unsigned disable_scramble_quirk:1; }; -- GitLab From 80caf7d21adca10c4621d511f6eb01f7ed2b342c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:26 +0800 Subject: [PATCH 2631/9457] usb: dwc3: add lpm erratum support When parameter DWC_USB3_LPM_ERRATA_ENABLE is enabled in Andvanced Configuration of coreConsultant, it supports of xHCI BESL Errata Dated 10/19/2011 is enabled in host mode. In device mode it adds the capability to send NYET response threshold based on the BESL value received in the LPM token, and the threhold is configurable for each soc platform. This patch adds an entry that soc platform is able to define the lpm capacity with their own device tree or bus glue layer. [ balbi@ti.com : added devicetree documentation, spelled threshold completely, made sure threshold is only applied to proper core revisions. ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 16 +++++++++++- drivers/usb/dwc3/core.h | 26 ++++++++++++------- drivers/usb/dwc3/gadget.c | 13 ++++++++++ drivers/usb/dwc3/platform_data.h | 3 +++ 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 8ec2256a4a09..2b0c1f2e6e27 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -16,6 +16,8 @@ Optional properties: - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - snps,disable_scramble_quirk: true when SW should disable data scrambling. Only really useful for FPGA builds. + - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled + - snps,lpm-nyet-threshold: LPM NYET threshold This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a0ae1326b7e3..6f9e5b85977a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -657,6 +657,7 @@ static int dwc3_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct resource *res; struct dwc3 *dwc; + u8 lpm_nyet_threshold; int ret; @@ -712,16 +713,27 @@ static int dwc3_probe(struct platform_device *pdev) */ res->start -= DWC3_GLOBALS_REGS_START; + /* default to highest possible threshold */ + lpm_nyet_threshold = 0xff; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); + dwc->has_lpm_erratum = of_property_read_bool(node, + "snps,has-lpm-erratum"); + of_property_read_u8(node, "snps,lpm-nyet-threshold", + &lpm_nyet_threshold); - dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); + dwc->needs_fifo_resize = of_property_read_bool(node, + "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); dwc->disable_scramble_quirk = of_property_read_bool(node, "snps,disable_scramble_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; + dwc->has_lpm_erratum = pdata->has_lpm_erratum; + if (pdata->lpm_nyet_threshold) + lpm_nyet_threshold = pdata->lpm_nyet_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; @@ -733,6 +745,8 @@ static int dwc3_probe(struct platform_device *pdev) if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; + dwc->lpm_nyet_threshold = lpm_nyet_threshold; + ret = dwc3_core_get_phy(dwc); if (ret) return ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 56bada6c8604..34f1e08988fe 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -246,16 +246,19 @@ #define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) /* These apply for core versions 1.94a and later */ -#define DWC3_DCTL_KEEP_CONNECT (1 << 19) -#define DWC3_DCTL_L1_HIBER_EN (1 << 18) -#define DWC3_DCTL_CRS (1 << 17) -#define DWC3_DCTL_CSS (1 << 16) +#define DWC3_DCTL_LPM_ERRATA_MASK DWC3_DCTL_LPM_ERRATA(0xf) +#define DWC3_DCTL_LPM_ERRATA(n) ((n) << 20) -#define DWC3_DCTL_INITU2ENA (1 << 12) -#define DWC3_DCTL_ACCEPTU2ENA (1 << 11) -#define DWC3_DCTL_INITU1ENA (1 << 10) -#define DWC3_DCTL_ACCEPTU1ENA (1 << 9) -#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) +#define DWC3_DCTL_KEEP_CONNECT (1 << 19) +#define DWC3_DCTL_L1_HIBER_EN (1 << 18) +#define DWC3_DCTL_CRS (1 << 17) +#define DWC3_DCTL_CSS (1 << 16) + +#define DWC3_DCTL_INITU2ENA (1 << 12) +#define DWC3_DCTL_ACCEPTU2ENA (1 << 11) +#define DWC3_DCTL_INITU1ENA (1 << 10) +#define DWC3_DCTL_ACCEPTU1ENA (1 << 9) +#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) #define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5) #define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK) @@ -660,10 +663,13 @@ struct dwc3_scratchpad_array { * @regset: debugfs pointer to regdump file * @test_mode: true when we're entering a USB test mode * @test_mode_nr: test feature selector + * @lpm_nyet_threshold: LPM NYET response threshold * @delayed_status: true when gadget driver asks for delayed status * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @has_hibernation: true when dwc3 was configured with Hibernation + * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that + * there's now way for software to detect this in runtime. * @is_selfpowered: true when we are selfpowered * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it @@ -764,11 +770,13 @@ struct dwc3 { u8 test_mode; u8 test_mode_nr; + u8 lpm_nyet_threshold; unsigned delayed_status:1; unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned has_hibernation:1; + unsigned has_lpm_erratum:1; unsigned is_selfpowered:1; unsigned is_fpga:1; unsigned needs_fifo_resize:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 20dda60b27c3..88a065f61150 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2301,6 +2301,19 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) */ reg |= DWC3_DCTL_HIRD_THRES(12); + /* + * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and + * DCFG.LPMCap is set, core responses with an ACK and the + * BESL value in the LPM token is less than or equal to LPM + * NYET threshold. + */ + WARN_ONCE(dwc->revision < DWC3_REVISION_240A + && dwc->has_lpm_erratum, + "LPM Erratum not available on dwc3 revisisions < 2.40a\n"); + + if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A) + reg |= DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold); + dwc3_writel(dwc->regs, DWC3_DCTL, reg); } else { reg = dwc3_readl(dwc->regs, DWC3_DCTL); diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 9209d025597b..e1283080a49f 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -25,5 +25,8 @@ struct dwc3_platform_data { enum usb_dr_mode dr_mode; bool tx_fifo_resize; + u8 lpm_nyet_threshold; + unsigned disable_scramble_quirk:1; + unsigned has_lpm_erratum:1; }; -- GitLab From 9a5b2f3167c1f98b879d6a800ab138f04e34f9d5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:27 +0800 Subject: [PATCH 2632/9457] usb: dwc3: add u2exit lfps quirk This patch adds u2exit lfps quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 2b0c1f2e6e27..5fcd68008945 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -18,6 +18,7 @@ Optional properties: Only really useful for FPGA builds. - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - snps,lpm-nyet-threshold: LPM NYET threshold + - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 6f9e5b85977a..33cbea5c6dda 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -473,6 +473,9 @@ static int dwc3_core_init(struct dwc3 *dwc) else reg &= ~DWC3_GCTL_DISSCRAMBLE; + if (dwc->u2exit_lfps_quirk) + reg |= DWC3_GCTL_U2EXIT_LFPS; + /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed @@ -729,6 +732,8 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = of_property_read_bool(node, "snps,disable_scramble_quirk"); + dwc->u2exit_lfps_quirk = of_property_read_bool(node, + "snps,u2exit_lfps_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -739,6 +744,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->dr_mode = pdata->dr_mode; dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; + dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 34f1e08988fe..f93145cb52f5 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -166,6 +166,7 @@ #define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) #define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) #define DWC3_GCTL_DISSCRAMBLE (1 << 3) +#define DWC3_GCTL_U2EXIT_LFPS (1 << 2) #define DWC3_GCTL_GBLHIBERNATIONEN (1 << 1) #define DWC3_GCTL_DSBLCLKGTNG (1 << 0) @@ -679,6 +680,7 @@ struct dwc3_scratchpad_array { * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup * @disable_scramble_quirk: set if we enable the disable scramble quirk + * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -787,6 +789,7 @@ struct dwc3 { unsigned three_stage_setup:1; unsigned disable_scramble_quirk:1; + unsigned u2exit_lfps_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index e1283080a49f..3f2159108f7d 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -29,4 +29,5 @@ struct dwc3_platform_data { unsigned disable_scramble_quirk:1; unsigned has_lpm_erratum:1; + unsigned u2exit_lfps_quirk:1; }; -- GitLab From b5a65c406367e3e79ece6f687c83d4ffce4c174c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:28 +0800 Subject: [PATCH 2633/9457] usb: dwc3: add P3 in U2 SS inactive quirk This patch adds P3 in U2 SS inactive quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 23 +++++++++++++++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 28 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 5fcd68008945..36e4287c40f5 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -19,6 +19,7 @@ Optional properties: - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - snps,lpm-nyet-threshold: LPM NYET threshold - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk + - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 33cbea5c6dda..7c54da187062 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -364,6 +364,24 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); } +/** + * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core + * @dwc: Pointer to our controller context structure + */ +static void dwc3_phy_setup(struct dwc3 *dwc) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + + if (dwc->u2ss_inp3_quirk) + reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; + + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + + mdelay(100); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -489,6 +507,8 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_phy_setup(dwc); + ret = dwc3_alloc_scratch_buffers(dwc); if (ret) goto err1; @@ -734,6 +754,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = of_property_read_bool(node, "snps,u2exit_lfps_quirk"); + dwc->u2ss_inp3_quirk = of_property_read_bool(node, + "snps,u2ss_inp3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -745,6 +767,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; + dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f93145cb52f5..66fd26bfdbfa 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -176,6 +176,7 @@ /* Global USB3 PIPE Control Register */ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) +#define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -681,6 +682,7 @@ struct dwc3_scratchpad_array { * @three_stage_setup: set if we perform a three phase setup * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk + * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -790,6 +792,7 @@ struct dwc3 { unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; + unsigned u2ss_inp3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 3f2159108f7d..cf92c81e2e22 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -30,4 +30,5 @@ struct dwc3_platform_data { unsigned disable_scramble_quirk:1; unsigned has_lpm_erratum:1; unsigned u2exit_lfps_quirk:1; + unsigned u2ss_inp3_quirk:1; }; -- GitLab From df31f5b3a6d3ef0bb692edff13167e9a1c5aa25e Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:29 +0800 Subject: [PATCH 2634/9457] usb: dwc3: add request p1p2p3 quirk This patch adds request P1/P2/P3 quirk for U2/U2/U3, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 36e4287c40f5..40edc78ca602 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -20,6 +20,8 @@ Optional properties: - snps,lpm-nyet-threshold: LPM NYET threshold - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk + - snps,req_p1p2p3_quirk: when set, the core will always request for + P1/P2/P3 transition sequence. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7c54da187062..600d3bc8d04d 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -377,6 +377,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->u2ss_inp3_quirk) reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; + if (dwc->req_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_REQP1P2P3; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -756,6 +759,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,u2exit_lfps_quirk"); dwc->u2ss_inp3_quirk = of_property_read_bool(node, "snps,u2ss_inp3_quirk"); + dwc->req_p1p2p3_quirk = of_property_read_bool(node, + "snps,req_p1p2p3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -768,6 +773,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; + dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 66fd26bfdbfa..ce331630fad9 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -177,6 +177,7 @@ /* Global USB3 PIPE Control Register */ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) +#define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -683,6 +684,7 @@ struct dwc3_scratchpad_array { * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk + * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -793,6 +795,7 @@ struct dwc3 { unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; + unsigned req_p1p2p3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index cf92c81e2e22..d3e6ec210ef3 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -31,4 +31,5 @@ struct dwc3_platform_data { unsigned has_lpm_erratum:1; unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; + unsigned req_p1p2p3_quirk:1; }; -- GitLab From a2a1d0f5838d6aa0d1306ef9bb1011f501faa695 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:30 +0800 Subject: [PATCH 2635/9457] usb: dwc3: add delay p1p2p3 quirk This patch adds delay P0 to P1/P2/P3 quirk for U2/U2/U3, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 5 +++++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 40edc78ca602..4c77ed6e7c07 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -22,6 +22,8 @@ Optional properties: - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk - snps,req_p1p2p3_quirk: when set, the core will always request for P1/P2/P3 transition sequence. + - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain + amount of 8B10B errors occur. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 600d3bc8d04d..c07651484c60 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -380,6 +380,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->req_p1p2p3_quirk) reg |= DWC3_GUSB3PIPECTL_REQP1P2P3; + if (dwc->del_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -761,6 +764,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,u2ss_inp3_quirk"); dwc->req_p1p2p3_quirk = of_property_read_bool(node, "snps,req_p1p2p3_quirk"); + dwc->del_p1p2p3_quirk = of_property_read_bool(node, + "snps,del_p1p2p3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -774,6 +779,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; + dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ce331630fad9..b8fbc4a1ee4a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -178,6 +178,9 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) #define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24) +#define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19) +#define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7) +#define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -685,6 +688,7 @@ struct dwc3_scratchpad_array { * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk + * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -796,6 +800,7 @@ struct dwc3 { unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; + unsigned del_p1p2p3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3e6ec210ef3..a421cecd6c16 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -32,4 +32,5 @@ struct dwc3_platform_data { unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; + unsigned del_p1p2p3_quirk:1; }; -- GitLab From 41c06ffdf9cc63edd875cc8ff8ae002cd9b14f96 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:31 +0800 Subject: [PATCH 2636/9457] usb: dwc3: add delay phy power change quirk This patch adds delay PHY power change from P0 to P1/P2/P3 when link state changing from U0 to U1/U2/U3 respectively, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 4c77ed6e7c07..a2598d3c7c12 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -24,6 +24,8 @@ Optional properties: P1/P2/P3 transition sequence. - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain amount of 8B10B errors occur. + - snps,del_phy_power_chg_quirk: when set core will delay PHY power change + from P0 to P1/P2/P3. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c07651484c60..de6a00969bc7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -383,6 +383,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->del_p1p2p3_quirk) reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN; + if (dwc->del_phy_power_chg_quirk) + reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -766,6 +769,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,req_p1p2p3_quirk"); dwc->del_p1p2p3_quirk = of_property_read_bool(node, "snps,del_p1p2p3_quirk"); + dwc->del_phy_power_chg_quirk = of_property_read_bool(node, + "snps,del_phy_power_chg_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -780,6 +785,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; + dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b8fbc4a1ee4a..5e8a75c3f3c8 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -181,6 +181,7 @@ #define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19) #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7) #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) +#define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -689,6 +690,7 @@ struct dwc3_scratchpad_array { * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk + * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -801,6 +803,7 @@ struct dwc3 { unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; + unsigned del_phy_power_chg_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index a421cecd6c16..ae67151dc870 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -33,4 +33,5 @@ struct dwc3_platform_data { unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; + unsigned del_phy_power_chg_quirk:1; }; -- GitLab From fb67afca177a215684d6124137f61e639c5483d4 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:32 +0800 Subject: [PATCH 2637/9457] usb: dwc3: add lfps filter quirk This patch adds LFPS filter quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index a2598d3c7c12..4edd29a24e74 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -26,6 +26,7 @@ Optional properties: amount of 8B10B errors occur. - snps,del_phy_power_chg_quirk: when set core will delay PHY power change from P0 to P1/P2/P3. + - snps,lfps_filter_quirk: when set core will filter LFPS reception. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index de6a00969bc7..29a7da0c3178 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -386,6 +386,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->del_phy_power_chg_quirk) reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE; + if (dwc->lfps_filter_quirk) + reg |= DWC3_GUSB3PIPECTL_LFPSFILT; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -771,6 +774,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,del_p1p2p3_quirk"); dwc->del_phy_power_chg_quirk = of_property_read_bool(node, "snps,del_phy_power_chg_quirk"); + dwc->lfps_filter_quirk = of_property_read_bool(node, + "snps,lfps_filter_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -786,6 +791,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; + dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5e8a75c3f3c8..368d32948e27 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -183,6 +183,7 @@ #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) #define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) +#define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -691,6 +692,7 @@ struct dwc3_scratchpad_array { * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk + * @lfps_filter_quirk: set if we enable LFPS filter quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -804,6 +806,7 @@ struct dwc3 { unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; + unsigned lfps_filter_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index ae67151dc870..dad0211e8743 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -34,4 +34,5 @@ struct dwc3_platform_data { unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; + unsigned lfps_filter_quirk:1; }; -- GitLab From 14f4ac53dfb2321b07a0e690df797fba61102fa6 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:33 +0800 Subject: [PATCH 2638/9457] usb: dwc3: add rx_detect to polling lfps quirk This patch adds RX_DETECT to Polling.LFPS control quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 4edd29a24e74..1ecc33315e1f 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -27,6 +27,8 @@ Optional properties: - snps,del_phy_power_chg_quirk: when set core will delay PHY power change from P0 to P1/P2/P3. - snps,lfps_filter_quirk: when set core will filter LFPS reception. + - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start + Polling LFPS after RX.Detect. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 29a7da0c3178..b440b2b29872 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -389,6 +389,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->lfps_filter_quirk) reg |= DWC3_GUSB3PIPECTL_LFPSFILT; + if (dwc->rx_detect_poll_quirk) + reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -776,6 +779,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,del_phy_power_chg_quirk"); dwc->lfps_filter_quirk = of_property_read_bool(node, "snps,lfps_filter_quirk"); + dwc->rx_detect_poll_quirk = of_property_read_bool(node, + "snps,rx_detect_poll_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -792,6 +797,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; + dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 368d32948e27..8953d739b73d 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -184,6 +184,7 @@ #define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) +#define DWC3_GUSB3PIPECTL_RX_DETOPOLL (1 << 8) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -693,6 +694,7 @@ struct dwc3_scratchpad_array { * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk + * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -807,6 +809,7 @@ struct dwc3 { unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; + unsigned rx_detect_poll_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index dad0211e8743..4a0f06b2a6c7 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -35,4 +35,5 @@ struct dwc3_platform_data { unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; + unsigned rx_detect_poll_quirk:1; }; -- GitLab From 2164a476205ccc62c5874f95f3504b657fff5c04 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:35 +0800 Subject: [PATCH 2639/9457] usb: dwc3: set SUSPHY bit for all cores It is recommended to set USB3 and USB2 SUSPHY bits to '1' after the core initialization is completed above the dwc3 revision 1.94a. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b440b2b29872..aefb59d6db8f 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -374,6 +374,15 @@ static void dwc3_phy_setup(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + /* + * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY + * to '0' during coreConsultant configuration. So default value + * will be '0' when the core is reset. Application needs to set it + * to '1' after the core initialization is completed. + */ + if (dwc->revision > DWC3_REVISION_194A) + reg |= DWC3_GUSB3PIPECTL_SUSPHY; + if (dwc->u2ss_inp3_quirk) reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; @@ -395,6 +404,21 @@ static void dwc3_phy_setup(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); + + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + + /* + * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to + * '0' during coreConsultant configuration. So default value will + * be '0' when the core is reset. Application needs to set it to + * '1' after the core initialization is completed. + */ + if (dwc->revision > DWC3_REVISION_194A) + reg |= DWC3_GUSB2PHYCFG_SUSPHY; + + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + + mdelay(100); } /** -- GitLab From 6b6a0c9a3ffa3107994d92d5758cbe274c5a97b6 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:12 +0800 Subject: [PATCH 2640/9457] usb: dwc3: add Tx de-emphasis quirk This patch adds Tx de-emphasis quirk, and the Tx de-emphasis value is configurable according to PIPE3 specification. Value Description 0 -6dB de-emphasis 1 -3.5dB de-emphasis 2 No de-emphasis 3 Reserved It can be configured on DT or platform data. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++ drivers/usb/dwc3/core.c | 17 +++++++++++++++++ drivers/usb/dwc3/core.h | 11 +++++++++++ drivers/usb/dwc3/platform_data.h | 3 +++ 4 files changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 1ecc33315e1f..b724b2e78549 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -29,6 +29,9 @@ Optional properties: - snps,lfps_filter_quirk: when set core will filter LFPS reception. - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start Polling LFPS after RX.Detect. + - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. + - snps,tx_de_emphasis: the value driven to the PHY is controlled by the + LTSSM during USB3 Compliance mode. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index aefb59d6db8f..c3dfb195f79c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -401,6 +401,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->rx_detect_poll_quirk) reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL; + if (dwc->tx_de_emphasis_quirk) + reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -720,6 +723,7 @@ static int dwc3_probe(struct platform_device *pdev) struct resource *res; struct dwc3 *dwc; u8 lpm_nyet_threshold; + u8 tx_de_emphasis; int ret; @@ -778,6 +782,9 @@ static int dwc3_probe(struct platform_device *pdev) /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; + /* default to -3.5dB de-emphasis */ + tx_de_emphasis = 1; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->has_lpm_erratum = of_property_read_bool(node, @@ -805,6 +812,11 @@ static int dwc3_probe(struct platform_device *pdev) "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = of_property_read_bool(node, "snps,rx_detect_poll_quirk"); + + dwc->tx_de_emphasis_quirk = of_property_read_bool(node, + "snps,tx_de_emphasis_quirk"); + of_property_read_u8(node, "snps,tx_de_emphasis", + &tx_de_emphasis); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -822,6 +834,10 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; + + dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; + if (pdata->tx_de_emphasis) + tx_de_emphasis = pdata->tx_de_emphasis; } /* default to superspeed if no maximum_speed passed */ @@ -829,6 +845,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->maximum_speed = USB_SPEED_SUPER; dwc->lpm_nyet_threshold = lpm_nyet_threshold; + dwc->tx_de_emphasis = tx_de_emphasis; ret = dwc3_core_get_phy(dwc); if (ret) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 8953d739b73d..cf9aaca6add0 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -185,6 +185,8 @@ #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) #define DWC3_GUSB3PIPECTL_RX_DETOPOLL (1 << 8) +#define DWC3_GUSB3PIPECTL_TX_DEEPH_MASK DWC3_GUSB3PIPECTL_TX_DEEPH(3) +#define DWC3_GUSB3PIPECTL_TX_DEEPH(n) ((n) << 1) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -695,6 +697,12 @@ struct dwc3_scratchpad_array { * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk + * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk + * @tx_de_emphasis: Tx de-emphasis value + * 0 - -6dB de-emphasis + * 1 - -3.5dB de-emphasis + * 2 - No de-emphasis + * 3 - Reserved */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -810,6 +818,9 @@ struct dwc3 { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + + unsigned tx_de_emphasis_quirk:1; + unsigned tx_de_emphasis:2; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 4a0f06b2a6c7..e1ab900a8623 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -36,4 +36,7 @@ struct dwc3_platform_data { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + + unsigned tx_de_emphasis_quirk:1; + unsigned tx_de_emphasis:2; }; -- GitLab From 59acfa208164205f94a11f454d08cd88f06b9908 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:13 +0800 Subject: [PATCH 2641/9457] usb: dwc3: add disable usb3 suspend phy quirk This patch adds disable usb3 suspend phy quirk, and some special platforms can configure that if it is needed. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index b724b2e78549..08b394ebeb3e 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -32,6 +32,7 @@ Optional properties: - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. - snps,tx_de_emphasis: the value driven to the PHY is controlled by the LTSSM during USB3 Compliance mode. + - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c3dfb195f79c..87ffb86bc2f2 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -404,6 +404,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->tx_de_emphasis_quirk) reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); + if (dwc->dis_u3_susphy_quirk && dwc->is_fpga) + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -812,6 +815,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = of_property_read_bool(node, "snps,rx_detect_poll_quirk"); + dwc->dis_u3_susphy_quirk = of_property_read_bool(node, + "snps,dis_u3_susphy_quirk"); dwc->tx_de_emphasis_quirk = of_property_read_bool(node, "snps,tx_de_emphasis_quirk"); @@ -834,6 +839,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; + dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cf9aaca6add0..fa778b0a5ab7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -697,6 +697,7 @@ struct dwc3_scratchpad_array { * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk + * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -818,6 +819,7 @@ struct dwc3 { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + unsigned dis_u3_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index e1ab900a8623..0f1d5adc657d 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -36,6 +36,7 @@ struct dwc3_platform_data { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + unsigned dis_u3_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; -- GitLab From 0effe0a3e741c0e2318f541ce207c9bd6cfe985c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:14 +0800 Subject: [PATCH 2642/9457] usb: dwc3: add disable usb2 suspend phy quirk This patch adds disable usb2 suspend phy quirk, and some special platforms can configure that if it is needed. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 08b394ebeb3e..f200ecc1f0dc 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -33,6 +33,7 @@ Optional properties: - snps,tx_de_emphasis: the value driven to the PHY is controlled by the LTSSM during USB3 Compliance mode. - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. + - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 87ffb86bc2f2..3ea55f214439 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -422,6 +422,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB2PHYCFG_SUSPHY; + if (dwc->dis_u2_susphy_quirk && dwc->is_fpga) + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); @@ -817,6 +820,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,rx_detect_poll_quirk"); dwc->dis_u3_susphy_quirk = of_property_read_bool(node, "snps,dis_u3_susphy_quirk"); + dwc->dis_u2_susphy_quirk = of_property_read_bool(node, + "snps,dis_u2_susphy_quirk"); dwc->tx_de_emphasis_quirk = of_property_read_bool(node, "snps,tx_de_emphasis_quirk"); @@ -840,6 +845,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; + dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fa778b0a5ab7..cf86d3022b52 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -698,6 +698,7 @@ struct dwc3_scratchpad_array { * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy + * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -820,6 +821,7 @@ struct dwc3 { unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; + unsigned dis_u2_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 0f1d5adc657d..245300be057a 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -37,6 +37,7 @@ struct dwc3_platform_data { unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; + unsigned dis_u2_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; -- GitLab From c53a2b512b6f2b9b1b6353c1587b8b069997852f Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:15 +0800 Subject: [PATCH 2643/9457] PCI: Add support for AMD Nolan USB3 DRD This patch adds PCI id for USB3 Dual-Role Device of AMD Nolan (NL) SoC. It will be used for PCI quirks and DWC3 device driver. Signed-off-by: Jason Chang Signed-off-by: Huang Rui Acked-by: Bjorn Helgaas Signed-off-by: Felipe Balbi --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1fa99a301817..5decad77d8ed 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -562,6 +562,7 @@ #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 #define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 +#define PCI_DEVICE_ID_AMD_NL_USB 0x7912 #define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 -- GitLab From be6646bfbaec7af72ddf3fc98050ca6f19dc2b79 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:16 +0800 Subject: [PATCH 2644/9457] PCI: Prevent xHCI driver from claiming AMD Nolan USB3 DRD device The AMD Nolan (NL) SoC contains a DesignWare USB3 Dual-Role Device that can be operated either as a USB Host or a USB Device. In the AMD NL platform, this device ([1022:7912]) has a class code of PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will claim it. But the dwc3 driver is a more specific driver for this device, and we'd prefer to use it instead of xhci. To prevent xhci from claiming the device, change the class code to 0x0c03fe, which the PCI r3.0 spec defines as "USB device (not host controller)". The dwc3 driver can then claim it based on its Vendor and Device ID. Suggested-by: Heikki Krogerus Acked-by: Bjorn Helgaas Cc: Jason Chang Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/pci/quirks.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 90acb32c85b1..ed6f89b6efe5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -378,6 +378,26 @@ static void quirk_ati_exploding_mce(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce); +/* + * In the AMD NL platform, this device ([1022:7912]) has a class code of + * PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will + * claim it. + * But the dwc3 driver is a more specific driver for this device, and we'd + * prefer to use it instead of xhci. To prevent xhci from claiming the + * device, change the class code to 0x0c03fe, which the PCI r3.0 spec + * defines as "USB device (not host controller)". The dwc3 driver can then + * claim it based on its Vendor and Device ID. + */ +static void quirk_amd_nl_class(struct pci_dev *pdev) +{ + /* + * Use 'USB Device' (0x0c03fe) instead of PCI header provided + */ + pdev->class = 0x0c03fe; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, + quirk_amd_nl_class); + /* * Let's make the southbridge information explicit instead * of having to worry about people probing the ACPI areas, -- GitLab From 9755449d568b3c2745fc9c7075a7d7833c4528bd Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:17 +0800 Subject: [PATCH 2645/9457] usb: dwc3: add support for AMD Nolan platform This patch adds support for AMD Nolan (NL) FPGA and SoC platform. Cc: Jason Chang Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index ada975f0b365..7c4faf738747 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -145,6 +145,31 @@ static int dwc3_pci_probe(struct pci_dev *pci, res[1].name = "dwc_usb3"; res[1].flags = IORESOURCE_IRQ; + if (pci->vendor == PCI_VENDOR_ID_AMD && + pci->device == PCI_DEVICE_ID_AMD_NL_USB) { + dwc3_pdata.has_lpm_erratum = true; + dwc3_pdata.lpm_nyet_threshold = 0xf; + + dwc3_pdata.u2exit_lfps_quirk = true; + dwc3_pdata.u2ss_inp3_quirk = true; + dwc3_pdata.req_p1p2p3_quirk = true; + dwc3_pdata.del_p1p2p3_quirk = true; + dwc3_pdata.del_phy_power_chg_quirk = true; + dwc3_pdata.lfps_filter_quirk = true; + dwc3_pdata.rx_detect_poll_quirk = true; + + dwc3_pdata.tx_de_emphasis_quirk = true; + dwc3_pdata.tx_de_emphasis = 1; + + /* + * FIXME these quirks should be removed when AMD NL + * taps out + */ + dwc3_pdata.disable_scramble_quirk = true; + dwc3_pdata.dis_u3_susphy_quirk = true; + dwc3_pdata.dis_u2_susphy_quirk = true; + } + ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); @@ -194,6 +219,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); -- GitLab From 460d098cb6728134e0e4ba3d58e10bb43032daa5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:18 +0800 Subject: [PATCH 2646/9457] usb: dwc3: make HIRD threshold configurable HIRD threshold should be configurable by different platforms. From DesignWare databook: When HIRD_Threshold[4] is set to 1b1 and HIRD value is greater than or equal to the value in HIRD_Threshold[3:0], dwc3 asserts output signals utmi_l1_suspend_n to put PHY into Deep Low-Power mode in L1. When HIRD_Threshold[4] is set to 1b0 or the HIRD value is less than HIRD_Threshold[3:0], dwc3 asserts output signals utmi_sleep_n on L1. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++ drivers/usb/dwc3/core.c | 17 +++++++++++++++++ drivers/usb/dwc3/core.h | 6 ++++++ drivers/usb/dwc3/gadget.c | 6 +----- drivers/usb/dwc3/platform_data.h | 3 +++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index f200ecc1f0dc..cd7f0454e13a 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -34,6 +34,9 @@ Optional properties: LTSSM during USB3 Compliance mode. - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. + - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal + utmi_l1_suspend_n, false when asserts utmi_sleep_n + - snps,hird-threshold: HIRD threshold This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3ea55f214439..8ae42b8db02b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -730,6 +730,7 @@ static int dwc3_probe(struct platform_device *pdev) struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 tx_de_emphasis; + u8 hird_threshold; int ret; @@ -791,12 +792,22 @@ static int dwc3_probe(struct platform_device *pdev) /* default to -3.5dB de-emphasis */ tx_de_emphasis = 1; + /* + * default to assert utmi_sleep_n and use maximum allowed HIRD + * threshold value of 0b1100 + */ + hird_threshold = 12; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->has_lpm_erratum = of_property_read_bool(node, "snps,has-lpm-erratum"); of_property_read_u8(node, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); + dwc->is_utmi_l1_suspend = of_property_read_bool(node, + "snps,is-utmi-l1-suspend"); + of_property_read_u8(node, "snps,hird-threshold", + &hird_threshold); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); @@ -832,6 +843,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc->has_lpm_erratum = pdata->has_lpm_erratum; if (pdata->lpm_nyet_threshold) lpm_nyet_threshold = pdata->lpm_nyet_threshold; + dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend; + if (pdata->hird_threshold) + hird_threshold = pdata->hird_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; @@ -859,6 +873,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; + dwc->hird_threshold = hird_threshold + | (dwc->is_utmi_l1_suspend << 4); + ret = dwc3_core_get_phy(dwc); if (ret) return ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cf86d3022b52..4bb9aa696ede 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -675,12 +675,16 @@ struct dwc3_scratchpad_array { * @test_mode: true when we're entering a USB test mode * @test_mode_nr: test feature selector * @lpm_nyet_threshold: LPM NYET response threshold + * @hird_threshold: HIRD threshold * @delayed_status: true when gadget driver asks for delayed status * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @has_hibernation: true when dwc3 was configured with Hibernation * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that * there's now way for software to detect this in runtime. + * @is_utmi_l1_suspend: the core asserts output signal + * 0 - utmi_sleep_n + * 1 - utmi_l1_suspend_n * @is_selfpowered: true when we are selfpowered * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it @@ -797,12 +801,14 @@ struct dwc3 { u8 test_mode; u8 test_mode_nr; u8 lpm_nyet_threshold; + u8 hird_threshold; unsigned delayed_status:1; unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned has_hibernation:1; unsigned has_lpm_erratum:1; + unsigned is_utmi_l1_suspend:1; unsigned is_selfpowered:1; unsigned is_fpga:1; unsigned needs_fifo_resize:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 88a065f61150..398c12f5efe3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2295,11 +2295,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); - /* - * TODO: This should be configurable. For now using - * maximum allowed HIRD threshold value of 0b1100 - */ - reg |= DWC3_DCTL_HIRD_THRES(12); + reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold); /* * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 245300be057a..a3a3b6d5668c 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -25,6 +25,9 @@ struct dwc3_platform_data { enum usb_dr_mode dr_mode; bool tx_fifo_resize; + unsigned is_utmi_l1_suspend:1; + u8 hird_threshold; + u8 lpm_nyet_threshold; unsigned disable_scramble_quirk:1; -- GitLab From c3761a79c14da73edfaaffb6bf24a87535bf20a8 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 21 Oct 2014 15:31:42 -0500 Subject: [PATCH 2647/9457] usb: dwc2: allow dwc2 to get built when USB_GADGET=m This patch allows the gadget portion of the DWC2 driver to get built when (!USB && USB_GADGET) condition is encountered. Acked-by: Paul Zimmerman Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index f93807b3631a..4d027180cea1 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,6 +1,6 @@ config USB_DWC2 bool "DesignWare USB2 DRD Core Support" - depends on USB + depends on USB || USB_GADGET help Say Y here if your system has a Dual Role Hi-Speed USB controller based on the DesignWare HSOTG IP Core. -- GitLab From f74e2c9cb03076d11e807088d2120a8a381a6f3c Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Mon, 3 Nov 2014 21:59:37 +0800 Subject: [PATCH 2648/9457] ASoC: Intel: Correct a macro for FW message For the broadwell official released FW(Since 8.4.1.43), the macro SST_HSW_NO_CHANNELS is changed and fixed to 4, so here change it to 4. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index afd0ae10e2db..387511f12d85 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h @@ -21,7 +21,7 @@ #include #include -#define SST_HSW_NO_CHANNELS 2 +#define SST_HSW_NO_CHANNELS 4 #define SST_HSW_MAX_DX_REGIONS 14 #define SST_HSW_DX_CONTEXT_SIZE (640 * 1024) -- GitLab From c68a292152d322b2d03f88d7f1d91d6bfa9d22bc Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Mon, 3 Nov 2014 10:53:27 +0800 Subject: [PATCH 2649/9457] iommu/rockchip: rk3288 iommu driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rk3288 has several iommus. Each iommu belongs to a single master device. There is one device (ISP) that has two slave iommus, but that case is not yet supported by this driver. At subsys init, the iommu driver registers itself as the iommu driver for the platform bus. The master devices find their slave iommus using the "iommus" field in their devicetree description. Since each slave iommu belongs to exactly one master, their is no additional data needed at probe to associate a slave with its master. An iommu device's power domain, clock and irq are all shared with its master device, and the master device must be careful to attach from the iommu only after powering and clocking it (and leave it powered and clocked before detaching). Because their is no guarantee what the status of the iommu is at probe, and since the driver does not even know if the device is powered, we delay requesting its irq until the master device attaches, at which point we have a guarantee that the device is powered and clocked and we can reset it and disable its interrupt mask. An iommu_domain describes a virtual iova address space. Each iommu_domain has a corresponding page table that lists the mappings from iova to physical address. For the rk3288 iommu, the page table has two levels: The Level 1 "directory_table" has 1024 4-byte dte entries. Each dte points to a level 2 "page_table". Each level 2 page_table has 1024 4-byte pte entries. Each pte points to a 4 KiB page of memory. An iommu_domain is created when a dma_iommu_mapping is created via arm_iommu_create_mapping. Master devices can then attach themselves to this mapping (or attach the mapping to themselves?) by calling arm_iommu_attach_device(). This in turn instructs the iommu driver to write the page table's physical address into the slave iommu's "Directory Table Entry" (DTE) register. In fact multiple master devices, each with their own slave iommu device, can all attach to the same mapping. The iommus for these devices will share the same iommu_domain and therefore point to the same page table. Thus, the iommu domain maintains a list of iommu devices which are attached. This driver relies on the iommu core to ensure that all devices have detached before destroying a domain. v6: - add .add/remove_device() callbacks. - parse platform_device device tree nodes for "iommus" property - store platform device pointer as group iommudata - Check for existence of iommu group instead of relying on a dev_get_drvdata() to return NULL for a NULL device. v7: - fixup some strings. - In rk_iommu_disable_paging() # and % were reversed. Signed-off-by: Daniel Kurtz Signed-off-by: Simon Xue Reviewed-by: Grant Grundler Reviewed-by: Stéphane Marchesin Tested-by: Heiko Stuebner Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 12 + drivers/iommu/Makefile | 1 + drivers/iommu/rockchip-iommu.c | 1038 ++++++++++++++++++++++++++++++++ 3 files changed, 1051 insertions(+) create mode 100644 drivers/iommu/rockchip-iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index dd5112265cc9..d0a1261eb1ba 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG Say N unless you know you need this. +config ROCKCHIP_IOMMU + bool "Rockchip IOMMU Support" + depends on ARCH_ROCKCHIP + select IOMMU_API + select ARM_DMA_USE_IOMMU + help + Support for IOMMUs found on Rockchip rk32xx SOCs. + These IOMMUs allow virtualization of the address space used by most + cores within the multimedia subsystem. + Say Y here if you are using a Rockchip SoC that includes an IOMMU + device. + config TEGRA_IOMMU_GART bool "Tegra GART IOMMU Support" depends on ARCH_TEGRA_2x_SOC diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 16edef74b8ee..3e47ef35a35f 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o +obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c new file mode 100644 index 000000000000..b2023af384b9 --- /dev/null +++ b/drivers/iommu/rockchip-iommu.c @@ -0,0 +1,1038 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** MMU register offsets */ +#define RK_MMU_DTE_ADDR 0x00 /* Directory table address */ +#define RK_MMU_STATUS 0x04 +#define RK_MMU_COMMAND 0x08 +#define RK_MMU_PAGE_FAULT_ADDR 0x0C /* IOVA of last page fault */ +#define RK_MMU_ZAP_ONE_LINE 0x10 /* Shootdown one IOTLB entry */ +#define RK_MMU_INT_RAWSTAT 0x14 /* IRQ status ignoring mask */ +#define RK_MMU_INT_CLEAR 0x18 /* Acknowledge and re-arm irq */ +#define RK_MMU_INT_MASK 0x1C /* IRQ enable */ +#define RK_MMU_INT_STATUS 0x20 /* IRQ status after masking */ +#define RK_MMU_AUTO_GATING 0x24 + +#define DTE_ADDR_DUMMY 0xCAFEBABE +#define FORCE_RESET_TIMEOUT 100 /* ms */ + +/* RK_MMU_STATUS fields */ +#define RK_MMU_STATUS_PAGING_ENABLED BIT(0) +#define RK_MMU_STATUS_PAGE_FAULT_ACTIVE BIT(1) +#define RK_MMU_STATUS_STALL_ACTIVE BIT(2) +#define RK_MMU_STATUS_IDLE BIT(3) +#define RK_MMU_STATUS_REPLAY_BUFFER_EMPTY BIT(4) +#define RK_MMU_STATUS_PAGE_FAULT_IS_WRITE BIT(5) +#define RK_MMU_STATUS_STALL_NOT_ACTIVE BIT(31) + +/* RK_MMU_COMMAND command values */ +#define RK_MMU_CMD_ENABLE_PAGING 0 /* Enable memory translation */ +#define RK_MMU_CMD_DISABLE_PAGING 1 /* Disable memory translation */ +#define RK_MMU_CMD_ENABLE_STALL 2 /* Stall paging to allow other cmds */ +#define RK_MMU_CMD_DISABLE_STALL 3 /* Stop stall re-enables paging */ +#define RK_MMU_CMD_ZAP_CACHE 4 /* Shoot down entire IOTLB */ +#define RK_MMU_CMD_PAGE_FAULT_DONE 5 /* Clear page fault */ +#define RK_MMU_CMD_FORCE_RESET 6 /* Reset all registers */ + +/* RK_MMU_INT_* register fields */ +#define RK_MMU_IRQ_PAGE_FAULT 0x01 /* page fault */ +#define RK_MMU_IRQ_BUS_ERROR 0x02 /* bus read error */ +#define RK_MMU_IRQ_MASK (RK_MMU_IRQ_PAGE_FAULT | RK_MMU_IRQ_BUS_ERROR) + +#define NUM_DT_ENTRIES 1024 +#define NUM_PT_ENTRIES 1024 + +#define SPAGE_ORDER 12 +#define SPAGE_SIZE (1 << SPAGE_ORDER) + + /* + * Support mapping any size that fits in one page table: + * 4 KiB to 4 MiB + */ +#define RK_IOMMU_PGSIZE_BITMAP 0x007ff000 + +#define IOMMU_REG_POLL_COUNT_FAST 1000 + +struct rk_iommu_domain { + struct list_head iommus; + u32 *dt; /* page directory table */ + spinlock_t iommus_lock; /* lock for iommus list */ + spinlock_t dt_lock; /* lock for modifying page directory table */ +}; + +struct rk_iommu { + struct device *dev; + void __iomem *base; + int irq; + struct list_head node; /* entry in rk_iommu_domain.iommus */ + struct iommu_domain *domain; /* domain to which iommu is attached */ +}; + +static inline void rk_table_flush(u32 *va, unsigned int count) +{ + phys_addr_t pa_start = virt_to_phys(va); + phys_addr_t pa_end = virt_to_phys(va + count); + size_t size = pa_end - pa_start; + + __cpuc_flush_dcache_area(va, size); + outer_flush_range(pa_start, pa_end); +} + +/** + * Inspired by _wait_for in intel_drv.h + * This is NOT safe for use in interrupt context. + * + * Note that it's important that we check the condition again after having + * timed out, since the timeout could be due to preemption or similar and + * we've never had a chance to check the condition before the timeout. + */ +#define rk_wait_for(COND, MS) ({ \ + unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \ + int ret__ = 0; \ + while (!(COND)) { \ + if (time_after(jiffies, timeout__)) { \ + ret__ = (COND) ? 0 : -ETIMEDOUT; \ + break; \ + } \ + usleep_range(50, 100); \ + } \ + ret__; \ +}) + +/* + * The Rockchip rk3288 iommu uses a 2-level page table. + * The first level is the "Directory Table" (DT). + * The DT consists of 1024 4-byte Directory Table Entries (DTEs), each pointing + * to a "Page Table". + * The second level is the 1024 Page Tables (PT). + * Each PT consists of 1024 4-byte Page Table Entries (PTEs), each pointing to + * a 4 KB page of physical memory. + * + * The DT and each PT fits in a single 4 KB page (4-bytes * 1024 entries). + * Each iommu device has a MMU_DTE_ADDR register that contains the physical + * address of the start of the DT page. + * + * The structure of the page table is as follows: + * + * DT + * MMU_DTE_ADDR -> +-----+ + * | | + * +-----+ PT + * | DTE | -> +-----+ + * +-----+ | | Memory + * | | +-----+ Page + * | | | PTE | -> +-----+ + * +-----+ +-----+ | | + * | | | | + * | | | | + * +-----+ | | + * | | + * | | + * +-----+ + */ + +/* + * Each DTE has a PT address and a valid bit: + * +---------------------+-----------+-+ + * | PT address | Reserved |V| + * +---------------------+-----------+-+ + * 31:12 - PT address (PTs always starts on a 4 KB boundary) + * 11: 1 - Reserved + * 0 - 1 if PT @ PT address is valid + */ +#define RK_DTE_PT_ADDRESS_MASK 0xfffff000 +#define RK_DTE_PT_VALID BIT(0) + +static inline phys_addr_t rk_dte_pt_address(u32 dte) +{ + return (phys_addr_t)dte & RK_DTE_PT_ADDRESS_MASK; +} + +static inline bool rk_dte_is_pt_valid(u32 dte) +{ + return dte & RK_DTE_PT_VALID; +} + +static u32 rk_mk_dte(u32 *pt) +{ + phys_addr_t pt_phys = virt_to_phys(pt); + return (pt_phys & RK_DTE_PT_ADDRESS_MASK) | RK_DTE_PT_VALID; +} + +/* + * Each PTE has a Page address, some flags and a valid bit: + * +---------------------+---+-------+-+ + * | Page address |Rsv| Flags |V| + * +---------------------+---+-------+-+ + * 31:12 - Page address (Pages always start on a 4 KB boundary) + * 11: 9 - Reserved + * 8: 1 - Flags + * 8 - Read allocate - allocate cache space on read misses + * 7 - Read cache - enable cache & prefetch of data + * 6 - Write buffer - enable delaying writes on their way to memory + * 5 - Write allocate - allocate cache space on write misses + * 4 - Write cache - different writes can be merged together + * 3 - Override cache attributes + * if 1, bits 4-8 control cache attributes + * if 0, the system bus defaults are used + * 2 - Writable + * 1 - Readable + * 0 - 1 if Page @ Page address is valid + */ +#define RK_PTE_PAGE_ADDRESS_MASK 0xfffff000 +#define RK_PTE_PAGE_FLAGS_MASK 0x000001fe +#define RK_PTE_PAGE_WRITABLE BIT(2) +#define RK_PTE_PAGE_READABLE BIT(1) +#define RK_PTE_PAGE_VALID BIT(0) + +static inline phys_addr_t rk_pte_page_address(u32 pte) +{ + return (phys_addr_t)pte & RK_PTE_PAGE_ADDRESS_MASK; +} + +static inline bool rk_pte_is_page_valid(u32 pte) +{ + return pte & RK_PTE_PAGE_VALID; +} + +/* TODO: set cache flags per prot IOMMU_CACHE */ +static u32 rk_mk_pte(phys_addr_t page, int prot) +{ + u32 flags = 0; + flags |= (prot & IOMMU_READ) ? RK_PTE_PAGE_READABLE : 0; + flags |= (prot & IOMMU_WRITE) ? RK_PTE_PAGE_WRITABLE : 0; + page &= RK_PTE_PAGE_ADDRESS_MASK; + return page | flags | RK_PTE_PAGE_VALID; +} + +static u32 rk_mk_pte_invalid(u32 pte) +{ + return pte & ~RK_PTE_PAGE_VALID; +} + +/* + * rk3288 iova (IOMMU Virtual Address) format + * 31 22.21 12.11 0 + * +-----------+-----------+-------------+ + * | DTE index | PTE index | Page offset | + * +-----------+-----------+-------------+ + * 31:22 - DTE index - index of DTE in DT + * 21:12 - PTE index - index of PTE in PT @ DTE.pt_address + * 11: 0 - Page offset - offset into page @ PTE.page_address + */ +#define RK_IOVA_DTE_MASK 0xffc00000 +#define RK_IOVA_DTE_SHIFT 22 +#define RK_IOVA_PTE_MASK 0x003ff000 +#define RK_IOVA_PTE_SHIFT 12 +#define RK_IOVA_PAGE_MASK 0x00000fff +#define RK_IOVA_PAGE_SHIFT 0 + +static u32 rk_iova_dte_index(dma_addr_t iova) +{ + return (u32)(iova & RK_IOVA_DTE_MASK) >> RK_IOVA_DTE_SHIFT; +} + +static u32 rk_iova_pte_index(dma_addr_t iova) +{ + return (u32)(iova & RK_IOVA_PTE_MASK) >> RK_IOVA_PTE_SHIFT; +} + +static u32 rk_iova_page_offset(dma_addr_t iova) +{ + return (u32)(iova & RK_IOVA_PAGE_MASK) >> RK_IOVA_PAGE_SHIFT; +} + +static u32 rk_iommu_read(struct rk_iommu *iommu, u32 offset) +{ + return readl(iommu->base + offset); +} + +static void rk_iommu_write(struct rk_iommu *iommu, u32 offset, u32 value) +{ + writel(value, iommu->base + offset); +} + +static void rk_iommu_command(struct rk_iommu *iommu, u32 command) +{ + writel(command, iommu->base + RK_MMU_COMMAND); +} + +static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova, + size_t size) +{ + dma_addr_t iova_end = iova + size; + /* + * TODO(djkurtz): Figure out when it is more efficient to shootdown the + * entire iotlb rather than iterate over individual iovas. + */ + for (; iova < iova_end; iova += SPAGE_SIZE) + rk_iommu_write(iommu, RK_MMU_ZAP_ONE_LINE, iova); +} + +static bool rk_iommu_is_stall_active(struct rk_iommu *iommu) +{ + return rk_iommu_read(iommu, RK_MMU_STATUS) & RK_MMU_STATUS_STALL_ACTIVE; +} + +static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu) +{ + return rk_iommu_read(iommu, RK_MMU_STATUS) & + RK_MMU_STATUS_PAGING_ENABLED; +} + +static int rk_iommu_enable_stall(struct rk_iommu *iommu) +{ + int ret; + + if (rk_iommu_is_stall_active(iommu)) + return 0; + + /* Stall can only be enabled if paging is enabled */ + if (!rk_iommu_is_paging_enabled(iommu)) + return 0; + + rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL); + + ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1); + if (ret) + dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n", + rk_iommu_read(iommu, RK_MMU_STATUS)); + + return ret; +} + +static int rk_iommu_disable_stall(struct rk_iommu *iommu) +{ + int ret; + + if (!rk_iommu_is_stall_active(iommu)) + return 0; + + rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL); + + ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1); + if (ret) + dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n", + rk_iommu_read(iommu, RK_MMU_STATUS)); + + return ret; +} + +static int rk_iommu_enable_paging(struct rk_iommu *iommu) +{ + int ret; + + if (rk_iommu_is_paging_enabled(iommu)) + return 0; + + rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING); + + ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1); + if (ret) + dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n", + rk_iommu_read(iommu, RK_MMU_STATUS)); + + return ret; +} + +static int rk_iommu_disable_paging(struct rk_iommu *iommu) +{ + int ret; + + if (!rk_iommu_is_paging_enabled(iommu)) + return 0; + + rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING); + + ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1); + if (ret) + dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n", + rk_iommu_read(iommu, RK_MMU_STATUS)); + + return ret; +} + +static int rk_iommu_force_reset(struct rk_iommu *iommu) +{ + int ret; + u32 dte_addr; + + /* + * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY + * and verifying that upper 5 nybbles are read back. + */ + rk_iommu_write(iommu, RK_MMU_DTE_ADDR, DTE_ADDR_DUMMY); + + dte_addr = rk_iommu_read(iommu, RK_MMU_DTE_ADDR); + if (dte_addr != (DTE_ADDR_DUMMY & RK_DTE_PT_ADDRESS_MASK)) { + dev_err(iommu->dev, "Error during raw reset. MMU_DTE_ADDR is not functioning\n"); + return -EFAULT; + } + + rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET); + + ret = rk_wait_for(rk_iommu_read(iommu, RK_MMU_DTE_ADDR) == 0x00000000, + FORCE_RESET_TIMEOUT); + if (ret) + dev_err(iommu->dev, "FORCE_RESET command timed out\n"); + + return ret; +} + +static void log_iova(struct rk_iommu *iommu, dma_addr_t iova) +{ + u32 dte_index, pte_index, page_offset; + u32 mmu_dte_addr; + phys_addr_t mmu_dte_addr_phys, dte_addr_phys; + u32 *dte_addr; + u32 dte; + phys_addr_t pte_addr_phys = 0; + u32 *pte_addr = NULL; + u32 pte = 0; + phys_addr_t page_addr_phys = 0; + u32 page_flags = 0; + + dte_index = rk_iova_dte_index(iova); + pte_index = rk_iova_pte_index(iova); + page_offset = rk_iova_page_offset(iova); + + mmu_dte_addr = rk_iommu_read(iommu, RK_MMU_DTE_ADDR); + mmu_dte_addr_phys = (phys_addr_t)mmu_dte_addr; + + dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index); + dte_addr = phys_to_virt(dte_addr_phys); + dte = *dte_addr; + + if (!rk_dte_is_pt_valid(dte)) + goto print_it; + + pte_addr_phys = rk_dte_pt_address(dte) + (pte_index * 4); + pte_addr = phys_to_virt(pte_addr_phys); + pte = *pte_addr; + + if (!rk_pte_is_page_valid(pte)) + goto print_it; + + page_addr_phys = rk_pte_page_address(pte) + page_offset; + page_flags = pte & RK_PTE_PAGE_FLAGS_MASK; + +print_it: + dev_err(iommu->dev, "iova = %pad: dte_index: %#03x pte_index: %#03x page_offset: %#03x\n", + &iova, dte_index, pte_index, page_offset); + dev_err(iommu->dev, "mmu_dte_addr: %pa dte@%pa: %#08x valid: %u pte@%pa: %#08x valid: %u page@%pa flags: %#03x\n", + &mmu_dte_addr_phys, &dte_addr_phys, dte, + rk_dte_is_pt_valid(dte), &pte_addr_phys, pte, + rk_pte_is_page_valid(pte), &page_addr_phys, page_flags); +} + +static irqreturn_t rk_iommu_irq(int irq, void *dev_id) +{ + struct rk_iommu *iommu = dev_id; + u32 status; + u32 int_status; + dma_addr_t iova; + + int_status = rk_iommu_read(iommu, RK_MMU_INT_STATUS); + if (int_status == 0) + return IRQ_NONE; + + iova = rk_iommu_read(iommu, RK_MMU_PAGE_FAULT_ADDR); + + if (int_status & RK_MMU_IRQ_PAGE_FAULT) { + int flags; + + status = rk_iommu_read(iommu, RK_MMU_STATUS); + flags = (status & RK_MMU_STATUS_PAGE_FAULT_IS_WRITE) ? + IOMMU_FAULT_WRITE : IOMMU_FAULT_READ; + + dev_err(iommu->dev, "Page fault at %pad of type %s\n", + &iova, + (flags == IOMMU_FAULT_WRITE) ? "write" : "read"); + + log_iova(iommu, iova); + + /* + * Report page fault to any installed handlers. + * Ignore the return code, though, since we always zap cache + * and clear the page fault anyway. + */ + if (iommu->domain) + report_iommu_fault(iommu->domain, iommu->dev, iova, + flags); + else + dev_err(iommu->dev, "Page fault while iommu not attached to domain?\n"); + + rk_iommu_command(iommu, RK_MMU_CMD_ZAP_CACHE); + rk_iommu_command(iommu, RK_MMU_CMD_PAGE_FAULT_DONE); + } + + if (int_status & RK_MMU_IRQ_BUS_ERROR) + dev_err(iommu->dev, "BUS_ERROR occurred at %pad\n", &iova); + + if (int_status & ~RK_MMU_IRQ_MASK) + dev_err(iommu->dev, "unexpected int_status: %#08x\n", + int_status); + + rk_iommu_write(iommu, RK_MMU_INT_CLEAR, int_status); + + return IRQ_HANDLED; +} + +static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain, + dma_addr_t iova) +{ + struct rk_iommu_domain *rk_domain = domain->priv; + unsigned long flags; + phys_addr_t pt_phys, phys = 0; + u32 dte, pte; + u32 *page_table; + + spin_lock_irqsave(&rk_domain->dt_lock, flags); + + dte = rk_domain->dt[rk_iova_dte_index(iova)]; + if (!rk_dte_is_pt_valid(dte)) + goto out; + + pt_phys = rk_dte_pt_address(dte); + page_table = (u32 *)phys_to_virt(pt_phys); + pte = page_table[rk_iova_pte_index(iova)]; + if (!rk_pte_is_page_valid(pte)) + goto out; + + phys = rk_pte_page_address(pte) + rk_iova_page_offset(iova); +out: + spin_unlock_irqrestore(&rk_domain->dt_lock, flags); + + return phys; +} + +static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain, + dma_addr_t iova, size_t size) +{ + struct list_head *pos; + unsigned long flags; + + /* shootdown these iova from all iommus using this domain */ + spin_lock_irqsave(&rk_domain->iommus_lock, flags); + list_for_each(pos, &rk_domain->iommus) { + struct rk_iommu *iommu; + iommu = list_entry(pos, struct rk_iommu, node); + rk_iommu_zap_lines(iommu, iova, size); + } + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags); +} + +static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain, + dma_addr_t iova) +{ + u32 *page_table, *dte_addr; + u32 dte; + phys_addr_t pt_phys; + + assert_spin_locked(&rk_domain->dt_lock); + + dte_addr = &rk_domain->dt[rk_iova_dte_index(iova)]; + dte = *dte_addr; + if (rk_dte_is_pt_valid(dte)) + goto done; + + page_table = (u32 *)get_zeroed_page(GFP_ATOMIC | GFP_DMA32); + if (!page_table) + return ERR_PTR(-ENOMEM); + + dte = rk_mk_dte(page_table); + *dte_addr = dte; + + rk_table_flush(page_table, NUM_PT_ENTRIES); + rk_table_flush(dte_addr, 1); + + /* + * Zap the first iova of newly allocated page table so iommu evicts + * old cached value of new dte from the iotlb. + */ + rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE); + +done: + pt_phys = rk_dte_pt_address(dte); + return (u32 *)phys_to_virt(pt_phys); +} + +static size_t rk_iommu_unmap_iova(struct rk_iommu_domain *rk_domain, + u32 *pte_addr, dma_addr_t iova, size_t size) +{ + unsigned int pte_count; + unsigned int pte_total = size / SPAGE_SIZE; + + assert_spin_locked(&rk_domain->dt_lock); + + for (pte_count = 0; pte_count < pte_total; pte_count++) { + u32 pte = pte_addr[pte_count]; + if (!rk_pte_is_page_valid(pte)) + break; + + pte_addr[pte_count] = rk_mk_pte_invalid(pte); + } + + rk_table_flush(pte_addr, pte_count); + + return pte_count * SPAGE_SIZE; +} + +static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr, + dma_addr_t iova, phys_addr_t paddr, size_t size, + int prot) +{ + unsigned int pte_count; + unsigned int pte_total = size / SPAGE_SIZE; + phys_addr_t page_phys; + + assert_spin_locked(&rk_domain->dt_lock); + + for (pte_count = 0; pte_count < pte_total; pte_count++) { + u32 pte = pte_addr[pte_count]; + + if (rk_pte_is_page_valid(pte)) + goto unwind; + + pte_addr[pte_count] = rk_mk_pte(paddr, prot); + + paddr += SPAGE_SIZE; + } + + rk_table_flush(pte_addr, pte_count); + + return 0; +unwind: + /* Unmap the range of iovas that we just mapped */ + rk_iommu_unmap_iova(rk_domain, pte_addr, iova, pte_count * SPAGE_SIZE); + + iova += pte_count * SPAGE_SIZE; + page_phys = rk_pte_page_address(pte_addr[pte_count]); + pr_err("iova: %pad already mapped to %pa cannot remap to phys: %pa prot: %#x\n", + &iova, &page_phys, &paddr, prot); + + return -EADDRINUSE; +} + +static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova, + phys_addr_t paddr, size_t size, int prot) +{ + struct rk_iommu_domain *rk_domain = domain->priv; + unsigned long flags; + dma_addr_t iova = (dma_addr_t)_iova; + u32 *page_table, *pte_addr; + int ret; + + spin_lock_irqsave(&rk_domain->dt_lock, flags); + + /* + * pgsize_bitmap specifies iova sizes that fit in one page table + * (1024 4-KiB pages = 4 MiB). + * So, size will always be 4096 <= size <= 4194304. + * Since iommu_map() guarantees that both iova and size will be + * aligned, we will always only be mapping from a single dte here. + */ + page_table = rk_dte_get_page_table(rk_domain, iova); + if (IS_ERR(page_table)) { + spin_unlock_irqrestore(&rk_domain->dt_lock, flags); + return PTR_ERR(page_table); + } + + pte_addr = &page_table[rk_iova_pte_index(iova)]; + ret = rk_iommu_map_iova(rk_domain, pte_addr, iova, paddr, size, prot); + spin_unlock_irqrestore(&rk_domain->dt_lock, flags); + + return ret; +} + +static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova, + size_t size) +{ + struct rk_iommu_domain *rk_domain = domain->priv; + unsigned long flags; + dma_addr_t iova = (dma_addr_t)_iova; + phys_addr_t pt_phys; + u32 dte; + u32 *pte_addr; + size_t unmap_size; + + spin_lock_irqsave(&rk_domain->dt_lock, flags); + + /* + * pgsize_bitmap specifies iova sizes that fit in one page table + * (1024 4-KiB pages = 4 MiB). + * So, size will always be 4096 <= size <= 4194304. + * Since iommu_unmap() guarantees that both iova and size will be + * aligned, we will always only be unmapping from a single dte here. + */ + dte = rk_domain->dt[rk_iova_dte_index(iova)]; + /* Just return 0 if iova is unmapped */ + if (!rk_dte_is_pt_valid(dte)) { + spin_unlock_irqrestore(&rk_domain->dt_lock, flags); + return 0; + } + + pt_phys = rk_dte_pt_address(dte); + pte_addr = (u32 *)phys_to_virt(pt_phys) + rk_iova_pte_index(iova); + unmap_size = rk_iommu_unmap_iova(rk_domain, pte_addr, iova, size); + + spin_unlock_irqrestore(&rk_domain->dt_lock, flags); + + /* Shootdown iotlb entries for iova range that was just unmapped */ + rk_iommu_zap_iova(rk_domain, iova, unmap_size); + + return unmap_size; +} + +static struct rk_iommu *rk_iommu_from_dev(struct device *dev) +{ + struct iommu_group *group; + struct device *iommu_dev; + struct rk_iommu *rk_iommu; + + group = iommu_group_get(dev); + if (!group) + return NULL; + iommu_dev = iommu_group_get_iommudata(group); + rk_iommu = dev_get_drvdata(iommu_dev); + iommu_group_put(group); + + return rk_iommu; +} + +static int rk_iommu_attach_device(struct iommu_domain *domain, + struct device *dev) +{ + struct rk_iommu *iommu; + struct rk_iommu_domain *rk_domain = domain->priv; + unsigned long flags; + int ret; + phys_addr_t dte_addr; + + /* + * Allow 'virtual devices' (e.g., drm) to attach to domain. + * Such a device does not belong to an iommu group. + */ + iommu = rk_iommu_from_dev(dev); + if (!iommu) + return 0; + + ret = rk_iommu_enable_stall(iommu); + if (ret) + return ret; + + ret = rk_iommu_force_reset(iommu); + if (ret) + return ret; + + iommu->domain = domain; + + ret = devm_request_irq(dev, iommu->irq, rk_iommu_irq, + IRQF_SHARED, dev_name(dev), iommu); + if (ret) + return ret; + + dte_addr = virt_to_phys(rk_domain->dt); + rk_iommu_write(iommu, RK_MMU_DTE_ADDR, dte_addr); + rk_iommu_command(iommu, RK_MMU_CMD_ZAP_CACHE); + rk_iommu_write(iommu, RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); + + ret = rk_iommu_enable_paging(iommu); + if (ret) + return ret; + + spin_lock_irqsave(&rk_domain->iommus_lock, flags); + list_add_tail(&iommu->node, &rk_domain->iommus); + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags); + + dev_info(dev, "Attached to iommu domain\n"); + + rk_iommu_disable_stall(iommu); + + return 0; +} + +static void rk_iommu_detach_device(struct iommu_domain *domain, + struct device *dev) +{ + struct rk_iommu *iommu; + struct rk_iommu_domain *rk_domain = domain->priv; + unsigned long flags; + + /* Allow 'virtual devices' (eg drm) to detach from domain */ + iommu = rk_iommu_from_dev(dev); + if (!iommu) + return; + + spin_lock_irqsave(&rk_domain->iommus_lock, flags); + list_del_init(&iommu->node); + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags); + + /* Ignore error while disabling, just keep going */ + rk_iommu_enable_stall(iommu); + rk_iommu_disable_paging(iommu); + rk_iommu_write(iommu, RK_MMU_INT_MASK, 0); + rk_iommu_write(iommu, RK_MMU_DTE_ADDR, 0); + rk_iommu_disable_stall(iommu); + + devm_free_irq(dev, iommu->irq, iommu); + + iommu->domain = NULL; + + dev_info(dev, "Detached from iommu domain\n"); +} + +static int rk_iommu_domain_init(struct iommu_domain *domain) +{ + struct rk_iommu_domain *rk_domain; + + rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL); + if (!rk_domain) + return -ENOMEM; + + /* + * rk32xx iommus use a 2 level pagetable. + * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries. + * Allocate one 4 KiB page for each table. + */ + rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32); + if (!rk_domain->dt) + goto err_dt; + + rk_table_flush(rk_domain->dt, NUM_DT_ENTRIES); + + spin_lock_init(&rk_domain->iommus_lock); + spin_lock_init(&rk_domain->dt_lock); + INIT_LIST_HEAD(&rk_domain->iommus); + + domain->priv = rk_domain; + + return 0; +err_dt: + kfree(rk_domain); + return -ENOMEM; +} + +static void rk_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct rk_iommu_domain *rk_domain = domain->priv; + int i; + + WARN_ON(!list_empty(&rk_domain->iommus)); + + for (i = 0; i < NUM_DT_ENTRIES; i++) { + u32 dte = rk_domain->dt[i]; + if (rk_dte_is_pt_valid(dte)) { + phys_addr_t pt_phys = rk_dte_pt_address(dte); + u32 *page_table = phys_to_virt(pt_phys); + free_page((unsigned long)page_table); + } + } + + free_page((unsigned long)rk_domain->dt); + kfree(domain->priv); + domain->priv = NULL; +} + +static bool rk_iommu_is_dev_iommu_master(struct device *dev) +{ + struct device_node *np = dev->of_node; + int ret; + + /* + * An iommu master has an iommus property containing a list of phandles + * to iommu nodes, each with an #iommu-cells property with value 0. + */ + ret = of_count_phandle_with_args(np, "iommus", "#iommu-cells"); + return (ret > 0); +} + +static int rk_iommu_group_set_iommudata(struct iommu_group *group, + struct device *dev) +{ + struct device_node *np = dev->of_node; + struct platform_device *pd; + int ret; + struct of_phandle_args args; + + /* + * An iommu master has an iommus property containing a list of phandles + * to iommu nodes, each with an #iommu-cells property with value 0. + */ + ret = of_parse_phandle_with_args(np, "iommus", "#iommu-cells", 0, + &args); + if (ret) { + dev_err(dev, "of_parse_phandle_with_args(%s) => %d\n", + np->full_name, ret); + return ret; + } + if (args.args_count != 0) { + dev_err(dev, "incorrect number of iommu params found for %s (found %d, expected 0)\n", + args.np->full_name, args.args_count); + return -EINVAL; + } + + pd = of_find_device_by_node(args.np); + of_node_put(args.np); + if (!pd) { + dev_err(dev, "iommu %s not found\n", args.np->full_name); + return -EPROBE_DEFER; + } + + /* TODO(djkurtz): handle multiple slave iommus for a single master */ + iommu_group_set_iommudata(group, &pd->dev, NULL); + + return 0; +} + +static int rk_iommu_add_device(struct device *dev) +{ + struct iommu_group *group; + int ret; + + if (!rk_iommu_is_dev_iommu_master(dev)) + return -ENODEV; + + group = iommu_group_get(dev); + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) { + dev_err(dev, "Failed to allocate IOMMU group\n"); + return PTR_ERR(group); + } + } + + ret = iommu_group_add_device(group, dev); + if (ret) + goto err_put_group; + + ret = rk_iommu_group_set_iommudata(group, dev); + if (ret) + goto err_remove_device; + + iommu_group_put(group); + + return 0; + +err_remove_device: + iommu_group_remove_device(dev); +err_put_group: + iommu_group_put(group); + return ret; +} + +static void rk_iommu_remove_device(struct device *dev) +{ + if (!rk_iommu_is_dev_iommu_master(dev)) + return; + + iommu_group_remove_device(dev); +} + +static const struct iommu_ops rk_iommu_ops = { + .domain_init = rk_iommu_domain_init, + .domain_destroy = rk_iommu_domain_destroy, + .attach_dev = rk_iommu_attach_device, + .detach_dev = rk_iommu_detach_device, + .map = rk_iommu_map, + .unmap = rk_iommu_unmap, + .add_device = rk_iommu_add_device, + .remove_device = rk_iommu_remove_device, + .iova_to_phys = rk_iommu_iova_to_phys, + .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, +}; + +static int rk_iommu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rk_iommu *iommu; + struct resource *res; + + iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); + if (!iommu) + return -ENOMEM; + + platform_set_drvdata(pdev, iommu); + iommu->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + iommu->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(iommu->base)) + return PTR_ERR(iommu->base); + + iommu->irq = platform_get_irq(pdev, 0); + if (iommu->irq < 0) { + dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq); + return -ENXIO; + } + + return 0; +} + +static int rk_iommu_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id rk_iommu_dt_ids[] = { + { .compatible = "rockchip,iommu" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids); +#endif + +static struct platform_driver rk_iommu_driver = { + .probe = rk_iommu_probe, + .remove = rk_iommu_remove, + .driver = { + .name = "rk_iommu", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rk_iommu_dt_ids), + }, +}; + +static int __init rk_iommu_init(void) +{ + int ret; + + ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops); + if (ret) + return ret; + + return platform_driver_register(&rk_iommu_driver); +} +static void __exit rk_iommu_exit(void) +{ + platform_driver_unregister(&rk_iommu_driver); +} + +subsys_initcall(rk_iommu_init); +module_exit(rk_iommu_exit); + +MODULE_DESCRIPTION("IOMMU API for Rockchip"); +MODULE_AUTHOR("Simon Xue and Daniel Kurtz "); +MODULE_ALIAS("platform:rockchip-iommu"); +MODULE_LICENSE("GPL v2"); -- GitLab From 656d7077d8ffd1c2492d4a0a354367ab2e545059 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Mon, 3 Nov 2014 10:53:28 +0800 Subject: [PATCH 2650/9457] dt-bindings: iommu: Add documentation for rockchip iommu Add binding documentation for Rockchip IOMMU. Signed-off-by: Daniel Kurtz Signed-off-by: Simon Xue Reviewed-by: Heiko Stuebner Signed-off-by: Joerg Roedel --- .../bindings/iommu/rockchip,iommu.txt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/rockchip,iommu.txt diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt new file mode 100644 index 000000000000..9a55ac3735e5 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt @@ -0,0 +1,26 @@ +Rockchip IOMMU +============== + +A Rockchip DRM iommu translates io virtual addresses to physical addresses for +its master device. Each slave device is bound to a single master device, and +shares its clocks, power domain and irq. + +Required properties: +- compatible : Should be "rockchip,iommu" +- reg : Address space for the configuration registers +- interrupts : Interrupt specifier for the IOMMU instance +- interrupt-names : Interrupt name for the IOMMU instance +- #iommu-cells : Should be <0>. This indicates the iommu is a + "single-master" device, and needs no additional information + to associate with its master device. See: + Documentation/devicetree/bindings/iommu/iommu.txt + +Example: + + vopl_mmu: iommu@ff940300 { + compatible = "rockchip,iommu"; + reg = <0xff940300 0x100>; + interrupts = ; + interrupt-names = "vopl_mmu"; + #iommu-cells = <0>; + }; -- GitLab From 847713ea4fc10b3e5f36b5e9f4aadb4155a7f90e Mon Sep 17 00:00:00 2001 From: Johann Klammer Date: Mon, 27 Oct 2014 10:44:55 -0300 Subject: [PATCH 2651/9457] [media] saa7146: turn bothersome error into a debug message After updating the kernel to 3.14.15 I am seeing these messages: [273684.964081] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273690.020061] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273695.076082] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273700.132077] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273705.188070] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273710.244066] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273715.300187] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273720.356068] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273725.412188] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273730.468094] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273735.524070] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed [273740.580176] saa7146: saa7146 (0): saa7146_wait_for_debi_done_sleep timed out while waiting for registers getting programmed filling up the logs(one about every 5 seconds). Other posts suggests that it is not actually an error on cards without a CI interface. Here's a patch that turns it into a debug message, so it does not clobber the logs. Signed-off-by: Johann Klammer Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146/saa7146_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c index 4418119cf707..1ff9f5323bc3 100644 --- a/drivers/media/common/saa7146/saa7146_core.c +++ b/drivers/media/common/saa7146/saa7146_core.c @@ -71,7 +71,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, if (saa7146_read(dev, MC2) & 2) break; if (err) { - pr_err("%s: %s timed out while waiting for registers getting programmed\n", + pr_debug("%s: %s timed out while waiting for registers getting programmed\n", dev->name, __func__); return -ETIMEDOUT; } -- GitLab From 21228a1868692c34ade648dbb0bc3db0069ab551 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 29 Oct 2014 11:15:17 -0700 Subject: [PATCH 2652/9457] CodingStyle: Add a chapter on conditional compilation Document several common practices and conventions regarding conditional compilation, most notably the preference for ifdefs in headers rather than .c files. Signed-off-by: Josh Triplett Acked-by: Geert Uytterhoeven Signed-off-by: Jonathan Corbet --- Documentation/CodingStyle | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle index 3171822c22a5..9f28b140dc89 100644 --- a/Documentation/CodingStyle +++ b/Documentation/CodingStyle @@ -845,6 +845,49 @@ next instruction in the assembly output: : /* outputs */ : /* inputs */ : /* clobbers */); + Chapter 20: Conditional Compilation + +Wherever possible, don't use preprocessor conditionals (#if, #ifdef) in .c +files; doing so makes code harder to read and logic harder to follow. Instead, +use such conditionals in a header file defining functions for use in those .c +files, providing no-op stub versions in the #else case, and then call those +functions unconditionally from .c files. The compiler will avoid generating +any code for the stub calls, producing identical results, but the logic will +remain easy to follow. + +Prefer to compile out entire functions, rather than portions of functions or +portions of expressions. Rather than putting an ifdef in an expression, factor +out part or all of the expression into a separate helper function and apply the +conditional to that function. + +If you have a function or variable which may potentially go unused in a +particular configuration, and the compiler would warn about its definition +going unused, mark the definition as __maybe_unused rather than wrapping it in +a preprocessor conditional. (However, if a function or variable *always* goes +unused, delete it.) + +Within code, where possible, use the IS_ENABLED macro to convert a Kconfig +symbol into a C boolean expression, and use it in a normal C conditional: + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +The compiler will constant-fold the conditional away, and include or exclude +the block of code just as with an #ifdef, so this will not add any runtime +overhead. However, this approach still allows the C compiler to see the code +inside the block, and check it for correctness (syntax, types, symbol +references, etc). Thus, you still have to use an #ifdef if the code inside the +block references symbols that will not exist if the condition is not met. + +At the end of any non-trivial #if or #ifdef block (more than a few lines), +place a comment after the #endif on the same line, noting the conditional +expression used. For instance: + +#ifdef CONFIG_SOMETHING +... +#endif /* CONFIG_SOMETHING */ + Appendix I: References -- GitLab From 9fd1f310a13ab16034cbda4f874eafadc8f80caf Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Fri, 31 Oct 2014 12:48:42 -0300 Subject: [PATCH 2653/9457] [media] DocBook media: Clarify V4L2_FIELD_ANY for drivers Documentation for enum v4l2_field did not make it clear that V4L2_FIELD_ANY is only acceptable as input to the kernel, not as a response from the driver. Make it clear, to stop userspace developers like me assuming it can be returned by the driver. Signed-off-by: Simon Farnsworth Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/io.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index e5e8325aa3d7..1c17f802b471 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml @@ -1422,7 +1422,10 @@ one of the V4L2_FIELD_NONE, V4L2_FIELD_BOTTOM, or V4L2_FIELD_INTERLACED formats is acceptable. Drivers choose depending on hardware capabilities or e. g. the -requested image size, and return the actual field order. &v4l2-buffer; +requested image size, and return the actual field order. Drivers must +never return V4L2_FIELD_ANY. If multiple +field orders are possible the driver must choose one of the possible +field orders during &VIDIOC-S-FMT; or &VIDIOC-TRY-FMT;. &v4l2-buffer; field can never be V4L2_FIELD_ANY. -- GitLab From 66ae9fc237c1192414c12094443521d956199be8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Feb 2014 05:50:01 -0300 Subject: [PATCH 2654/9457] [media] stv090x: remove indent levels in stv090x_get_coldlock() This code is needlessly complicated and checkpatch.pl complains that we go over the 80 characters per line limit. If we flip the "if (!lock) {" test to "if (lock) return;" then we can remove an indent level from the rest of the function. We can add two returns in the "if (state->srate >= 10000000) {" condition and move the else statement back an additional indent level. There is another "if (!lock) {" check which can be removed since we have already checked "lock" and know it is zero at this point. This second check on "lock" is also a problem because it sets off a static checker warning. I have reviewed this code for some time to see if something else was intended, but have concluded that it was simply an oversight and should be removed. Removing this duplicative check gains us an third indent level. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv090x.c | 162 +++++++++++++------------- 1 file changed, 80 insertions(+), 82 deletions(-) diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 23e872f84742..93f4979ea6e9 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -2146,7 +2146,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) u32 reg; s32 car_step, steps, cur_step, dir, freq, timeout_lock; - int lock = 0; + int lock; if (state->srate >= 10000000) timeout_lock = timeout_dmd / 3; @@ -2154,98 +2154,96 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) timeout_lock = timeout_dmd / 2; lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ - if (!lock) { - if (state->srate >= 10000000) { - if (stv090x_chk_tmg(state)) { - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) - goto err; - lock = stv090x_get_dmdlock(state, timeout_dmd); - } else { - lock = 0; - } - } else { - if (state->srate <= 4000000) - car_step = 1000; - else if (state->srate <= 7000000) - car_step = 2000; - else if (state->srate <= 10000000) - car_step = 3000; - else - car_step = 5000; - - steps = (state->search_range / 1000) / car_step; - steps /= 2; - steps = 2 * (steps + 1); - if (steps < 0) - steps = 2; - else if (steps > 12) - steps = 12; - - cur_step = 1; - dir = 1; - - if (!lock) { - freq = state->frequency; - state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; - while ((cur_step <= steps) && (!lock)) { - if (dir > 0) - freq += cur_step * car_step; - else - freq -= cur_step * car_step; - - /* Setup tuner */ - if (stv090x_i2c_gate_ctrl(state, 1) < 0) - goto err; + if (lock) + return lock; - if (state->config->tuner_set_frequency) { - if (state->config->tuner_set_frequency(fe, freq) < 0) - goto err_gateoff; - } + if (state->srate >= 10000000) { + if (stv090x_chk_tmg(state)) { + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) + goto err; + return stv090x_get_dmdlock(state, timeout_dmd); + } + return 0; + } - if (state->config->tuner_set_bandwidth) { - if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) - goto err_gateoff; - } + if (state->srate <= 4000000) + car_step = 1000; + else if (state->srate <= 7000000) + car_step = 2000; + else if (state->srate <= 10000000) + car_step = 3000; + else + car_step = 5000; - if (stv090x_i2c_gate_ctrl(state, 0) < 0) - goto err; + steps = (state->search_range / 1000) / car_step; + steps /= 2; + steps = 2 * (steps + 1); + if (steps < 0) + steps = 2; + else if (steps > 12) + steps = 12; - msleep(50); + cur_step = 1; + dir = 1; - if (stv090x_i2c_gate_ctrl(state, 1) < 0) - goto err; + freq = state->frequency; + state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; + while ((cur_step <= steps) && (!lock)) { + if (dir > 0) + freq += cur_step * car_step; + else + freq -= cur_step * car_step; - if (state->config->tuner_get_status) { - if (state->config->tuner_get_status(fe, ®) < 0) - goto err_gateoff; - } + /* Setup tuner */ + if (stv090x_i2c_gate_ctrl(state, 1) < 0) + goto err; - if (reg) - dprintk(FE_DEBUG, 1, "Tuner phase locked"); - else - dprintk(FE_DEBUG, 1, "Tuner unlocked"); + if (state->config->tuner_set_frequency) { + if (state->config->tuner_set_frequency(fe, freq) < 0) + goto err_gateoff; + } - if (stv090x_i2c_gate_ctrl(state, 0) < 0) - goto err; + if (state->config->tuner_set_bandwidth) { + if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) + goto err_gateoff; + } - STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); - if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) - goto err; - if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) - goto err; - lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); + if (stv090x_i2c_gate_ctrl(state, 0) < 0) + goto err; - dir *= -1; - cur_step++; - } - } + msleep(50); + + if (stv090x_i2c_gate_ctrl(state, 1) < 0) + goto err; + + if (state->config->tuner_get_status) { + if (state->config->tuner_get_status(fe, ®) < 0) + goto err_gateoff; } + + if (reg) + dprintk(FE_DEBUG, 1, "Tuner phase locked"); + else + dprintk(FE_DEBUG, 1, "Tuner unlocked"); + + if (stv090x_i2c_gate_ctrl(state, 0) < 0) + goto err; + + STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); + if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) + goto err; + if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) + goto err; + lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); + + dir *= -1; + cur_step++; } return lock; -- GitLab From f353d71f75394e518b4d939aea2030d8e239dd41 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 22 Oct 2014 00:00:14 +0900 Subject: [PATCH 2655/9457] treewide: Fix typo in Documentation/DocBook/device-drivers This patch fix speeling typo found in html files within Documentation/DocBook/device-drivers. It is because html files are generated from comments in source, so I have to fix comments in the source. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Acked-by: Wolfram Sang Signed-off-by: Jonathan Corbet --- drivers/dma-buf/fence.c | 2 +- include/linux/fence.h | 4 ++-- include/linux/i2c.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c index 7bb9d65d9a2c..e5541117b3e9 100644 --- a/drivers/dma-buf/fence.c +++ b/drivers/dma-buf/fence.c @@ -283,7 +283,7 @@ EXPORT_SYMBOL(fence_add_callback); * @cb: [in] the callback to remove * * Remove a previously queued callback from the fence. This function returns - * true if the callback is succesfully removed, or false if the fence has + * true if the callback is successfully removed, or false if the fence has * already been signaled. * * *WARNING*: diff --git a/include/linux/fence.h b/include/linux/fence.h index d174585b874b..39efee130d2b 100644 --- a/include/linux/fence.h +++ b/include/linux/fence.h @@ -128,8 +128,8 @@ struct fence_cb { * from irq context, so normal spinlocks can be used. * * A return value of false indicates the fence already passed, - * or some failure occured that made it impossible to enable - * signaling. True indicates succesful enabling. + * or some failure occurred that made it impossible to enable + * signaling. True indicates successful enabling. * * fence->status may be set in enable_signaling, but only when false is * returned. diff --git a/include/linux/i2c.h b/include/linux/i2c.h index b556e0ab946f..70ee0d3a2be3 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -359,7 +359,7 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info, * to name two of the most common. * * The return codes from the @master_xfer field should indicate the type of - * error code that occured during the transfer, as documented in the kernel + * error code that occurred during the transfer, as documented in the kernel * Documentation file Documentation/i2c/fault-codes. */ struct i2c_algorithm { -- GitLab From 70c036347fe6675dcd87fd9c2f3159f90233a0ed Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 22 Oct 2014 08:36:07 +0900 Subject: [PATCH 2656/9457] Documentation: Fix a typo in mailbox.txt This patch fix a typo in Documentation/mailbox.txt "bool async" is defined in struct demo_client. Signed-off-by: Masanari Iida Signed-off-by: Jonathan Corbet --- Documentation/mailbox.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/mailbox.txt b/Documentation/mailbox.txt index 60f43ff629aa..1092ad9578da 100644 --- a/Documentation/mailbox.txt +++ b/Documentation/mailbox.txt @@ -53,7 +53,7 @@ static void message_from_remote(struct mbox_client *cl, void *mssg) { struct demo_client *dc = container_of(mbox_client, struct demo_client, cl); - if (dc->aysnc) { + if (dc->async) { if (is_an_ack(mssg)) { /* An ACK to our last sample sent */ return; /* Or do something else here */ -- GitLab From 6ed9b28504326f8cf542e6b68245b2f7ce009216 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 30 May 2014 20:26:38 -0300 Subject: [PATCH 2657/9457] [media] V4L2: fix VIDIOC_CREATE_BUFS 32-bit compatibility mode data copy-back Similar to an earlier patch, fixing reading user-space data for the VIDIOC_CREATE_BUFS ioctl() in 32-bit compatibility mode, this patch fixes writing back of the possibly modified struct to the user. However, unlike the former bug, this one is much less harmful, because it only results in the kernel failing to write the .type field back to the user, but in fact this is likely unneeded, because the kernel will hardly want to change that field. Therefore this bug is more of a theoretical nature. Signed-off-by: Guennadi Liakhovetski Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index e502a5fb2994..af635430524e 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -222,6 +222,9 @@ static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) { + if (put_user(kp->type, &up->type)) + return -EFAULT; + switch (kp->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: @@ -248,8 +251,7 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) { - if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) || - put_user(kp->type, &up->type)) + if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32))) return -EFAULT; return __put_v4l2_format32(kp, up); } @@ -257,8 +259,8 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up) { if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) || - copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt))) - return -EFAULT; + copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format))) + return -EFAULT; return __put_v4l2_format32(&kp->format, &up->format); } -- GitLab From 4cdb1e2e3d3495423db558d3bb7ed11d66aabce7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 2 Nov 2014 06:00:12 -0800 Subject: [PATCH 2658/9457] net: shrink struct softnet_data flow_limit in struct softnet_data is only read from local cpu and can be moved to fill a hole, reducing softnet_data size by 64 bytes on x86_64 While we are at it, move output_queue, output_queue_tailp and completion_queue, so that rx / tx paths touch a single cache line. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c85e06512246..5ed05bd764dc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2329,10 +2329,7 @@ extern int netdev_flow_limit_table_len; * Incoming packets are placed on per-cpu queues */ struct softnet_data { - struct Qdisc *output_queue; - struct Qdisc **output_queue_tailp; struct list_head poll_list; - struct sk_buff *completion_queue; struct sk_buff_head process_queue; /* stats */ @@ -2340,10 +2337,17 @@ struct softnet_data { unsigned int time_squeeze; unsigned int cpu_collision; unsigned int received_rps; - #ifdef CONFIG_RPS struct softnet_data *rps_ipi_list; +#endif +#ifdef CONFIG_NET_FLOW_LIMIT + struct sd_flow_limit __rcu *flow_limit; +#endif + struct Qdisc *output_queue; + struct Qdisc **output_queue_tailp; + struct sk_buff *completion_queue; +#ifdef CONFIG_RPS /* Elements below can be accessed between CPUs for RPS */ struct call_single_data csd ____cacheline_aligned_in_smp; struct softnet_data *rps_ipi_next; @@ -2355,9 +2359,6 @@ struct softnet_data { struct sk_buff_head input_pkt_queue; struct napi_struct backlog; -#ifdef CONFIG_NET_FLOW_LIMIT - struct sd_flow_limit __rcu *flow_limit; -#endif }; static inline void input_queue_head_incr(struct softnet_data *sd) -- GitLab From d75b1ade567ffab085e8adbbdacf0092d10cd09c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 2 Nov 2014 06:19:33 -0800 Subject: [PATCH 2659/9457] net: less interrupt masking in NAPI net_rx_action() can mask irqs a single time to transfert sd->poll_list into a private list, for a very short duration. Then, napi_complete() can avoid masking irqs again, and net_rx_action() only needs to mask irq again in slow path. This patch removes 2 couples of irq mask/unmask per typical NAPI run, more if multiple napi were triggered. Note this also allows to give control back to caller (do_softirq()) more often, so that other softirq handlers can be called a bit earlier, or ksoftirqd can be wakeup earlier under pressure. This was developed while testing an alternative to RX interrupt mitigation to reduce latencies while keeping or improving GRO aggregation on fast NIC. Idea is to test napi->gro_list at the end of a napi->poll() and reschedule one NAPI poll, but after servicing a full round of softirqs (timers, TX, rcu, ...). This will be allowed only if softirq is currently serviced by idle task or ksoftirqd, and resched not needed. Signed-off-by: Eric Dumazet Cc: Willem de Bruijn Signed-off-by: David S. Miller --- net/core/dev.c | 68 +++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index ebf778df58cd..40be481268de 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4316,20 +4316,28 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) local_irq_enable(); } +static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) +{ +#ifdef CONFIG_RPS + return sd->rps_ipi_list != NULL; +#else + return false; +#endif +} + static int process_backlog(struct napi_struct *napi, int quota) { int work = 0; struct softnet_data *sd = container_of(napi, struct softnet_data, backlog); -#ifdef CONFIG_RPS /* Check if we have pending ipi, its better to send them now, * not waiting net_rx_action() end. */ - if (sd->rps_ipi_list) { + if (sd_has_rps_ipi_waiting(sd)) { local_irq_disable(); net_rps_action_and_irq_enable(sd); } -#endif + napi->weight = weight_p; local_irq_disable(); while (1) { @@ -4356,7 +4364,6 @@ static int process_backlog(struct napi_struct *napi, int quota) * We can use a plain write instead of clear_bit(), * and we dont need an smp_mb() memory barrier. */ - list_del(&napi->poll_list); napi->state = 0; rps_unlock(sd); @@ -4406,7 +4413,7 @@ void __napi_complete(struct napi_struct *n) BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); BUG_ON(n->gro_list); - list_del(&n->poll_list); + list_del_init(&n->poll_list); smp_mb__before_atomic(); clear_bit(NAPI_STATE_SCHED, &n->state); } @@ -4424,9 +4431,15 @@ void napi_complete(struct napi_struct *n) return; napi_gro_flush(n, false); - local_irq_save(flags); - __napi_complete(n); - local_irq_restore(flags); + + if (likely(list_empty(&n->poll_list))) { + WARN_ON_ONCE(!test_and_clear_bit(NAPI_STATE_SCHED, &n->state)); + } else { + /* If n->poll_list is not empty, we need to mask irqs */ + local_irq_save(flags); + __napi_complete(n); + local_irq_restore(flags); + } } EXPORT_SYMBOL(napi_complete); @@ -4520,29 +4533,28 @@ static void net_rx_action(struct softirq_action *h) struct softnet_data *sd = this_cpu_ptr(&softnet_data); unsigned long time_limit = jiffies + 2; int budget = netdev_budget; + LIST_HEAD(list); + LIST_HEAD(repoll); void *have; local_irq_disable(); + list_splice_init(&sd->poll_list, &list); + local_irq_enable(); - while (!list_empty(&sd->poll_list)) { + while (!list_empty(&list)) { struct napi_struct *n; int work, weight; - /* If softirq window is exhuasted then punt. + /* If softirq window is exhausted then punt. * Allow this to run for 2 jiffies since which will allow * an average latency of 1.5/HZ. */ if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit))) goto softnet_break; - local_irq_enable(); - /* Even though interrupts have been re-enabled, this - * access is safe because interrupts can only add new - * entries to the tail of this list, and only ->poll() - * calls can remove this head entry from the list. - */ - n = list_first_entry(&sd->poll_list, struct napi_struct, poll_list); + n = list_first_entry(&list, struct napi_struct, poll_list); + list_del_init(&n->poll_list); have = netpoll_poll_lock(n); @@ -4564,8 +4576,6 @@ static void net_rx_action(struct softirq_action *h) budget -= work; - local_irq_disable(); - /* Drivers must not modify the NAPI state if they * consume the entire weight. In such cases this code * still "owns" the NAPI instance and therefore can @@ -4573,32 +4583,40 @@ static void net_rx_action(struct softirq_action *h) */ if (unlikely(work == weight)) { if (unlikely(napi_disable_pending(n))) { - local_irq_enable(); napi_complete(n); - local_irq_disable(); } else { if (n->gro_list) { /* flush too old packets * If HZ < 1000, flush all packets. */ - local_irq_enable(); napi_gro_flush(n, HZ >= 1000); - local_irq_disable(); } - list_move_tail(&n->poll_list, &sd->poll_list); + list_add_tail(&n->poll_list, &repoll); } } netpoll_poll_unlock(have); } + + if (!sd_has_rps_ipi_waiting(sd) && + list_empty(&list) && + list_empty(&repoll)) + return; out: + local_irq_disable(); + + list_splice_tail_init(&sd->poll_list, &list); + list_splice_tail(&repoll, &list); + list_splice(&list, &sd->poll_list); + if (!list_empty(&sd->poll_list)) + __raise_softirq_irqoff(NET_RX_SOFTIRQ); + net_rps_action_and_irq_enable(sd); return; softnet_break: sd->time_squeeze++; - __raise_softirq_irqoff(NET_RX_SOFTIRQ); goto out; } -- GitLab From 6e8066999800d90d52af5c84ac49ebf683d14cdc Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Sun, 2 Nov 2014 16:26:13 +0200 Subject: [PATCH 2660/9457] net/mlx4_core: Prevent VF from changing port configuration Added wrapper to the ACCESS_REG command for handling guest HW registers access, preventing write operations, but do allow reads. This will prevent SRIOV guests to change port PTYS configuration, such as speed/advertised link modes. Fixes: adbc7ac5c15e ('net/mlx4_core: Introduce ACCESS_REG CMD [...]') Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 2 +- drivers/net/ethernet/mellanox/mlx4/fw.c | 30 ++++++++++++++++++++++- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 5 ++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 916459effcfa..1312ccf8b83a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1345,7 +1345,7 @@ static struct mlx4_cmd_info cmd_info[] = { .out_is_imm = false, .encode_slave_id = false, .verify = NULL, - .wrapper = NULL, + .wrapper = mlx4_ACCESS_REG_wrapper, }, /* Native multicast commands are not available for guests */ { diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 72289ef5ebbe..e7639e31fc8a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -2220,7 +2220,7 @@ static int mlx4_ACCESS_REG(struct mlx4_dev *dev, u16 reg_id, memcpy(inbuf->reg_data, reg_data, reg_len); err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 0, 0, MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, - MLX4_CMD_NATIVE); + MLX4_CMD_WRAPPED); if (err) goto out; @@ -2263,3 +2263,31 @@ int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev, method, sizeof(*ptys_reg), ptys_reg); } EXPORT_SYMBOL_GPL(mlx4_ACCESS_PTYS_REG); + +int mlx4_ACCESS_REG_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd) +{ + struct mlx4_access_reg *inbuf = inbox->buf; + u8 method = inbuf->method & MLX4_ACCESS_REG_METHOD_MASK; + u16 reg_id = be16_to_cpu(inbuf->reg_id); + + if (slave != mlx4_master_func_num(dev) && + method == MLX4_ACCESS_REG_WRITE) + return -EPERM; + + if (reg_id == MLX4_REG_ID_PTYS) { + struct mlx4_ptys_reg *ptys_reg = + (struct mlx4_ptys_reg *)inbuf->reg_data; + + ptys_reg->local_port = + mlx4_slave_convert_port(dev, slave, + ptys_reg->local_port); + } + + return mlx4_cmd_box(dev, inbox->dma, outbox->dma, vhcr->in_modifier, + 0, MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); +} diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index de10dbb2e6ed..254ec7b1ca2f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -1273,6 +1273,11 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd); +int mlx4_ACCESS_REG_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd); int mlx4_get_mgm_entry_size(struct mlx4_dev *dev); int mlx4_get_qp_per_mgm(struct mlx4_dev *dev); -- GitLab From 0a98455666ec87378148a1dde97f1ce5baf75a64 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Sun, 2 Nov 2014 16:26:14 +0200 Subject: [PATCH 2661/9457] net/mlx4_core: Protect port type setting by mutex We need to protect set_port_type() for concurrency, as the sysfs code could call it from mutliple contexts in parallel. The port_mutex is not enough because we need to protect from concurrent modification of 'info' and stopping of the port sensing work. Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 90de6e1ad06e..9f821964a1b9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -901,9 +901,12 @@ static ssize_t set_port_type(struct device *dev, struct mlx4_priv *priv = mlx4_priv(mdev); enum mlx4_port_type types[MLX4_MAX_PORTS]; enum mlx4_port_type new_types[MLX4_MAX_PORTS]; + static DEFINE_MUTEX(set_port_type_mutex); int i; int err = 0; + mutex_lock(&set_port_type_mutex); + if (!strcmp(buf, "ib\n")) info->tmp_type = MLX4_PORT_TYPE_IB; else if (!strcmp(buf, "eth\n")) @@ -912,7 +915,8 @@ static ssize_t set_port_type(struct device *dev, info->tmp_type = MLX4_PORT_TYPE_AUTO; else { mlx4_err(mdev, "%s is not supported port type\n", buf); - return -EINVAL; + err = -EINVAL; + goto err_out; } mlx4_stop_sense(mdev); @@ -958,6 +962,9 @@ static ssize_t set_port_type(struct device *dev, out: mlx4_start_sense(mdev); mutex_unlock(&priv->port_mutex); +err_out: + mutex_unlock(&set_port_type_mutex); + return err ? err : count; } -- GitLab From 5f6e9800804758de367132a0fe9b85865d24f89b Mon Sep 17 00:00:00 2001 From: Ido Shamay Date: Sun, 2 Nov 2014 16:26:15 +0200 Subject: [PATCH 2662/9457] net/mlx4_en: Remove RX buffers alignment to IP_ALIGN When IP_ALIGN has a non zero value, hardware will write to a non aligned address. The only reader from this address is when copying the header from the first frag into the linear buffer (further access to the IP address will be from the linear buffer, in which the headers are aligned). Since the penalty of non align access by the hardware is greater than the software memcpy, changing the frag_align to always be 0. Signed-off-by: Ido Shamay Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 16 ++++------------ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index c562c1468944..2ce3f00fbf38 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -74,7 +74,7 @@ static int mlx4_alloc_pages(struct mlx4_en_priv *priv, page_alloc->page_size = PAGE_SIZE << order; page_alloc->page = page; page_alloc->dma = dma; - page_alloc->page_offset = frag_info->frag_align; + page_alloc->page_offset = 0; /* Not doing get_page() for each frag is a big win * on asymetric workloads. Note we can not use atomic_set(). */ @@ -945,15 +945,8 @@ void mlx4_en_calc_rx_buf(struct net_device *dev) (eff_mtu > buf_size + frag_sizes[i]) ? frag_sizes[i] : eff_mtu - buf_size; priv->frag_info[i].frag_prefix_size = buf_size; - if (!i) { - priv->frag_info[i].frag_align = NET_IP_ALIGN; - priv->frag_info[i].frag_stride = - ALIGN(frag_sizes[i] + NET_IP_ALIGN, SMP_CACHE_BYTES); - } else { - priv->frag_info[i].frag_align = 0; - priv->frag_info[i].frag_stride = - ALIGN(frag_sizes[i], SMP_CACHE_BYTES); - } + priv->frag_info[i].frag_stride = ALIGN(frag_sizes[i], + SMP_CACHE_BYTES); buf_size += priv->frag_info[i].frag_size; i++; } @@ -966,11 +959,10 @@ void mlx4_en_calc_rx_buf(struct net_device *dev) eff_mtu, priv->num_frags); for (i = 0; i < priv->num_frags; i++) { en_err(priv, - " frag:%d - size:%d prefix:%d align:%d stride:%d\n", + " frag:%d - size:%d prefix:%d stride:%d\n", i, priv->frag_info[i].frag_size, priv->frag_info[i].frag_prefix_size, - priv->frag_info[i].frag_align, priv->frag_info[i].frag_stride); } } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 6beb4d34dce0..ef83d127f406 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -481,7 +481,6 @@ struct mlx4_en_frag_info { u16 frag_size; u16 frag_prefix_size; u16 frag_stride; - u16 frag_align; }; #ifdef CONFIG_MLX4_EN_DCB -- GitLab From 1ab25f86c418b04189c25117090d2b4dc60df417 Mon Sep 17 00:00:00 2001 From: Ido Shamay Date: Sun, 2 Nov 2014 16:26:16 +0200 Subject: [PATCH 2663/9457] net/mlx4_en: Add __GFP_COLD gfp flags in alloc_pages Needed in order to get cache cold pages (L3 flushed) for HW scatter. Otherwise memory may flush those entries when the packet comes from PCI, causing back pressure resulting in BW decrease. Signed-off-by: Ido Shamay Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 2ce3f00fbf38..b173a0cf44e0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -156,7 +156,7 @@ static int mlx4_en_init_allocator(struct mlx4_en_priv *priv, const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i]; if (mlx4_alloc_pages(priv, &ring->page_alloc[i], - frag_info, GFP_KERNEL)) + frag_info, GFP_KERNEL | __GFP_COLD)) goto out; } return 0; @@ -268,7 +268,7 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) if (mlx4_en_prepare_rx_desc(priv, ring, ring->actual_size, - GFP_KERNEL)) { + GFP_KERNEL | __GFP_COLD)) { if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) { en_err(priv, "Failed to allocate enough rx buffers\n"); return -ENOMEM; @@ -635,7 +635,8 @@ static void mlx4_en_refill_rx_buffers(struct mlx4_en_priv *priv, int index = ring->prod & ring->size_mask; while ((u32) (ring->prod - ring->cons) < ring->actual_size) { - if (mlx4_en_prepare_rx_desc(priv, ring, index, GFP_ATOMIC)) + if (mlx4_en_prepare_rx_desc(priv, ring, index, + GFP_ATOMIC | __GFP_COLD)) break; ring->prod++; index = ring->prod & ring->size_mask; -- GitLab From d475c95b4bcff983ac76e8522bfd2d29bcc567d0 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Sun, 2 Nov 2014 16:26:17 +0200 Subject: [PATCH 2664/9457] net/mlx4_core: Add retrieval of CONFIG_DEV parameters Add code to issue CONFIG_DEV "get" firmware command. This command is used in order to obtain certain parameters used for supporting various RX checksumming options and vxlan UDP port. The GET operation is allowed for VFs too. Signed-off-by: Matan Barak Signed-off-by: Shani Michaeli Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 4 +- drivers/net/ethernet/mellanox/mlx4/fw.c | 88 ++++++++++++++++++- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 5 ++ .../ethernet/mellanox/mlx4/resource_tracker.c | 17 ++++ include/linux/mlx4/cmd.h | 29 ++++++ include/linux/mlx4/device.h | 3 +- 6 files changed, 139 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 1312ccf8b83a..3c05e5878b49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -990,11 +990,11 @@ static struct mlx4_cmd_info cmd_info[] = { { .opcode = MLX4_CMD_CONFIG_DEV, .has_inbox = false, - .has_outbox = false, + .has_outbox = true, .out_is_imm = false, .encode_slave_id = false, .verify = NULL, - .wrapper = mlx4_CMD_EPERM_wrapper + .wrapper = mlx4_CONFIG_DEV_wrapper }, { .opcode = MLX4_CMD_ALLOC_RES, diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index e7639e31fc8a..d6dba77ae4ba 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -141,7 +141,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [12] = "Large cache line (>64B) CQE stride support", [13] = "Large cache line (>64B) EQE stride support", [14] = "Ethernet protocol control support", - [15] = "Ethernet Backplane autoneg support" + [15] = "Ethernet Backplane autoneg support", + [16] = "CONFIG DEV support" }; int i; @@ -574,6 +575,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MTT_ENTRY_SZ_OFFSET 0x90 #define QUERY_DEV_CAP_D_MPT_ENTRY_SZ_OFFSET 0x92 #define QUERY_DEV_CAP_BMME_FLAGS_OFFSET 0x94 +#define QUERY_DEV_CAP_CONFIG_DEV_OFFSET 0x94 #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 #define QUERY_DEV_CAP_ETH_BACKPL_OFFSET 0x9c @@ -749,6 +751,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE; MLX4_GET(dev_cap->bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); + MLX4_GET(field, outbox, QUERY_DEV_CAP_CONFIG_DEV_OFFSET); + if (field & 0x20) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CONFIG_DEV; MLX4_GET(dev_cap->reserved_lkey, outbox, QUERY_DEV_CAP_RSVD_LKEY_OFFSET); MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET); @@ -1849,14 +1854,18 @@ int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic) struct mlx4_config_dev { __be32 update_flags; - __be32 rsdv1[3]; + __be32 rsvd1[3]; __be16 vxlan_udp_dport; __be16 rsvd2; + __be32 rsvd3[27]; + __be16 rsvd4; + u8 rsvd5; + u8 rx_checksum_val; }; #define MLX4_VXLAN_UDP_DPORT (1 << 0) -static int mlx4_CONFIG_DEV(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) +static int mlx4_CONFIG_DEV_set(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) { int err; struct mlx4_cmd_mailbox *mailbox; @@ -1874,6 +1883,77 @@ static int mlx4_CONFIG_DEV(struct mlx4_dev *dev, struct mlx4_config_dev *config_ return err; } +static int mlx4_CONFIG_DEV_get(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) +{ + int err; + struct mlx4_cmd_mailbox *mailbox; + + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + + err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 1, MLX4_CMD_CONFIG_DEV, + MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); + + if (!err) + memcpy(config_dev, mailbox->buf, sizeof(*config_dev)); + + mlx4_free_cmd_mailbox(dev, mailbox); + return err; +} + +/* Conversion between the HW values and the actual functionality. + * The value represented by the array index, + * and the functionality determined by the flags. + */ +static const u8 config_dev_csum_flags[] = { + [0] = 0, + [1] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP, + [2] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP | + MLX4_RX_CSUM_MODE_L4, + [3] = MLX4_RX_CSUM_MODE_L4 | + MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP | + MLX4_RX_CSUM_MODE_MULTI_VLAN +}; + +int mlx4_config_dev_retrieval(struct mlx4_dev *dev, + struct mlx4_config_dev_params *params) +{ + struct mlx4_config_dev config_dev; + int err; + u8 csum_mask; + +#define CONFIG_DEV_RX_CSUM_MODE_MASK 0x7 +#define CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET 0 +#define CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET 4 + + if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CONFIG_DEV)) + return -ENOTSUPP; + + err = mlx4_CONFIG_DEV_get(dev, &config_dev); + if (err) + return err; + + csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET) & + CONFIG_DEV_RX_CSUM_MODE_MASK; + + if (csum_mask >= sizeof(config_dev_csum_flags)/sizeof(config_dev_csum_flags[0])) + return -EINVAL; + params->rx_csum_flags_port_1 = config_dev_csum_flags[csum_mask]; + + csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET) & + CONFIG_DEV_RX_CSUM_MODE_MASK; + + if (csum_mask >= sizeof(config_dev_csum_flags)/sizeof(config_dev_csum_flags[0])) + return -EINVAL; + params->rx_csum_flags_port_2 = config_dev_csum_flags[csum_mask]; + + params->vxlan_udp_dport = be16_to_cpu(config_dev.vxlan_udp_dport); + + return 0; +} +EXPORT_SYMBOL_GPL(mlx4_config_dev_retrieval); + int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port) { struct mlx4_config_dev config_dev; @@ -1882,7 +1962,7 @@ int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port) config_dev.update_flags = cpu_to_be32(MLX4_VXLAN_UDP_DPORT); config_dev.vxlan_udp_dport = udp_port; - return mlx4_CONFIG_DEV(dev, &config_dev); + return mlx4_CONFIG_DEV_set(dev, &config_dev); } EXPORT_SYMBOL_GPL(mlx4_config_vxlan_port); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 254ec7b1ca2f..f8fc7bd6f48b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -947,6 +947,11 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd); +int mlx4_CONFIG_DEV_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd); int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 5d2498dcf536..d718ca0f88da 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2872,6 +2872,23 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave, return err; } +int mlx4_CONFIG_DEV_wrapper(struct mlx4_dev *dev, int slave, + struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox, + struct mlx4_cmd_info *cmd) +{ + int err; + u8 get = vhcr->op_modifier; + + if (get != 1) + return -EPERM; + + err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); + + return err; +} + static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start, int len, struct res_mtt **res) { diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index ff5f5deb3dcf..64d25941b329 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -199,6 +199,33 @@ enum { MLX4_CMD_NATIVE }; +/* + * MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP - + * Receive checksum value is reported in CQE also for non TCP/UDP packets. + * + * MLX4_RX_CSUM_MODE_L4 - + * L4_CSUM bit in CQE, which indicates whether or not L4 checksum + * was validated correctly, is supported. + * + * MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP - + * IP_OK CQE's field is supported also for non TCP/UDP IP packets. + * + * MLX4_RX_CSUM_MODE_MULTI_VLAN - + * Receive Checksum offload is supported for packets with more than 2 vlan headers. + */ +enum mlx4_rx_csum_mode { + MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP = 1UL << 0, + MLX4_RX_CSUM_MODE_L4 = 1UL << 1, + MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP = 1UL << 2, + MLX4_RX_CSUM_MODE_MULTI_VLAN = 1UL << 3 +}; + +struct mlx4_config_dev_params { + u16 vxlan_udp_dport; + u8 rx_csum_flags_port_1; + u8 rx_csum_flags_port_2; +}; + struct mlx4_dev; struct mlx4_cmd_mailbox { @@ -250,6 +277,8 @@ int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf); int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state); +int mlx4_config_dev_retrieval(struct mlx4_dev *dev, + struct mlx4_config_dev_params *params); /* * mlx4_get_slave_default_vlan - * return true if VST ( default vlan) diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index e4c136ebe79b..5cc5eac47d1b 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -188,7 +188,8 @@ enum { MLX4_DEV_CAP_FLAG2_CQE_STRIDE = 1LL << 12, MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, - MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15 + MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, + MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16 }; enum { -- GitLab From f2dd851ff19412bdc80471048283edbb465f812e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Oct 2014 07:16:57 -0300 Subject: [PATCH 2665/9457] [media] fix a warning on avr32 arch X-Patchwork-Delegate: m.chehab@samsung.com on avr32 arch, those warnings happen: drivers/media/firewire/firedtv-fw.c: In function 'node_update': drivers/media/firewire/firedtv-fw.c:329: warning: comparison is always true due to limited range of data type In this particular case, the signal is desired, as the isochannel var can be initalized with -1 inside the driver. So, change the type to s8, to avoid issues on archs where char is unsigned. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/firewire/firedtv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/firewire/firedtv.h b/drivers/media/firewire/firedtv.h index c2ba085e0d20..346a85be6de2 100644 --- a/drivers/media/firewire/firedtv.h +++ b/drivers/media/firewire/firedtv.h @@ -96,7 +96,7 @@ struct firedtv { enum model_type type; char subunit; - char isochannel; + s8 isochannel; struct fdtv_ir_context *ir_context; fe_sec_voltage_t voltage; -- GitLab From 589dadf299bc8dab27589ecd62024c96a3812505 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 08:09:44 -0300 Subject: [PATCH 2666/9457] [media] cx231xx: get rid of driver-defined printk macros It currently does just like what pr_foo() macros do. So, replace them. A deeper cleanup is needed, as there are lots of debug macros printed with pr_info. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 6 +- drivers/media/usb/cx231xx/cx231xx-audio.c | 30 ++--- drivers/media/usb/cx231xx/cx231xx-avcore.c | 126 ++++++++++---------- drivers/media/usb/cx231xx/cx231xx-cards.c | 72 +++++------ drivers/media/usb/cx231xx/cx231xx-core.c | 54 ++++----- drivers/media/usb/cx231xx/cx231xx-dvb.c | 12 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 12 +- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | 24 ++-- drivers/media/usb/cx231xx/cx231xx-vbi.c | 28 ++--- drivers/media/usb/cx231xx/cx231xx-video.c | 52 ++++---- drivers/media/usb/cx231xx/cx231xx.h | 19 +-- 11 files changed, 210 insertions(+), 225 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 459bb0e98971..d678f4587ab4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -24,6 +24,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" + #include #include #include @@ -39,8 +41,6 @@ #include #include -#include "cx231xx.h" - #define CX231xx_FIRM_IMAGE_SIZE 376836 #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -1416,7 +1416,7 @@ static int bb_buf_prepare(struct videobuf_queue *q, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", + /*pr_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", urb_init, dev->video_mode.max_pkt_size);*/ dev->mode_tv = 1; diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 9b925874d392..8312388edabb 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -20,6 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include "cx231xx.h" static int debug; module_param(debug, int, 0644); @@ -182,7 +182,7 @@ static void cx231xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", + pr_err("resubmit of audio urb failed (error=%i)\n", status); } return; @@ -266,7 +266,7 @@ static void cx231xx_audio_bulkirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", + pr_err("resubmit of audio urb failed (error=%i)\n", status); } return; @@ -277,7 +277,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) int i, errCode; int sb_size; - cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__); + pr_info("%s: Starting ISO AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -295,7 +295,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - cx231xx_errdev("usb_alloc_urb failed!\n"); + pr_err("usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -338,7 +338,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) int i, errCode; int sb_size; - cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__); + pr_info("%s: Starting BULK AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -356,7 +356,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - cx231xx_errdev("usb_alloc_urb failed!\n"); + pr_err("usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -439,13 +439,13 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); if (!dev) { - cx231xx_errdev("BUG: cx231xx can't find device struct." + pr_err("BUG: cx231xx can't find device struct." " Can't proceed with open\n"); return -ENODEV; } if (dev->state & DEV_DISCONNECTED) { - cx231xx_errdev("Can't open. the device was removed.\n"); + pr_err("Can't open. the device was removed.\n"); return -ENODEV; } @@ -458,7 +458,7 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); mutex_unlock(&dev->lock); if (ret < 0) { - cx231xx_errdev("failed to set alternate setting !\n"); + pr_err("failed to set alternate setting !\n"); return ret; } @@ -494,7 +494,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); if (ret < 0) { - cx231xx_errdev("failed to set alternate setting !\n"); + pr_err("failed to set alternate setting !\n"); mutex_unlock(&dev->lock); return ret; @@ -662,7 +662,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) return 0; } - cx231xx_info("cx231xx-audio.c: probing for cx231xx " + pr_info("cx231xx-audio.c: probing for cx231xx " "non standard usbaudio\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio", @@ -707,12 +707,12 @@ static int cx231xx_audio_init(struct cx231xx *dev) bEndpointAddress; adev->num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", adev->end_point_addr, adev->num_alt); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); if (adev->alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + pr_err("out of memory!\n"); return -ENOMEM; } @@ -722,7 +722,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) wMaxPacketSize); adev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, + pr_info("Alternate setting %i, max size= %i\n", i, adev->alt_max_pkt_size[i]); } diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 781908b5a1a3..9185b05b4fbe 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -36,7 +37,6 @@ #include #include -#include "cx231xx.h" #include "cx231xx-dif.h" #define TUNER_MODE_FM_RADIO 0 @@ -83,10 +83,10 @@ void initGPIO(struct cx231xx *dev) cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); verve_read_byte(dev, 0x07, &val); - cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); + pr_info(" verve_read_byte address0x07=0x%x\n", val); verve_write_byte(dev, 0x07, 0xF4); verve_read_byte(dev, 0x07, &val); - cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); + pr_info(" verve_read_byte address0x07=0x%x\n", val); cx231xx_capture_start(dev, 1, Vbi); @@ -156,7 +156,7 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) while (afe_power_status != 0x18) { status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18); if (status < 0) { - cx231xx_info( + pr_info( ": Init Super Block failed in send cmd\n"); break; } @@ -164,13 +164,13 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status); afe_power_status &= 0xff; if (status < 0) { - cx231xx_info( + pr_info( ": Init Super Block failed in receive cmd\n"); break; } i++; if (i == 10) { - cx231xx_info( + pr_info( ": Init Super Block force break in loop !!!!\n"); status = -1; break; @@ -410,7 +410,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00); } else { - cx231xx_info("Invalid AV mode input\n"); + pr_info("Invalid AV mode input\n"); status = -1; } break; @@ -467,7 +467,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x40); } else { - cx231xx_info("Invalid AV mode input\n"); + pr_info("Invalid AV mode input\n"); status = -1; } } /* switch */ @@ -573,7 +573,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (status < 0) { - cx231xx_errdev("%s: set_power_mode : Failed to" + pr_err("%s: set_power_mode : Failed to" " set Power - errCode [%d]!\n", __func__, status); return status; @@ -591,7 +591,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (status < 0) { - cx231xx_errdev("%s: set_power_mode:Failed" + pr_err("%s: set_power_mode:Failed" " to set Power - errCode [%d]!\n", __func__, status); return status; @@ -608,7 +608,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) break; default: - cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n", + pr_err("%s: set_power_mode : Unknown Input %d !\n", __func__, INPUT(input)->type); break; } @@ -628,7 +628,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, if (pin_type != dev->video_input) { status = cx231xx_afe_adjust_ref_count(dev, pin_type); if (status < 0) { - cx231xx_errdev("%s: adjust_ref_count :Failed to set" + pr_err("%s: adjust_ref_count :Failed to set" "AFE input mux - errCode [%d]!\n", __func__, status); return status; @@ -638,7 +638,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* call afe block to set video inputs */ status = cx231xx_afe_set_input_mux(dev, input); if (status < 0) { - cx231xx_errdev("%s: set_input_mux :Failed to set" + pr_err("%s: set_input_mux :Failed to set" " AFE input mux - errCode [%d]!\n", __func__, status); return status; @@ -670,7 +670,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" + pr_err("%s: cx231xx_dif set to By pass" " mode- errCode [%d]!\n", __func__, status); return status; @@ -715,7 +715,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" + pr_err("%s: cx231xx_dif set to By pass" " mode- errCode [%d]!\n", __func__, status); return status; @@ -790,7 +790,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" + pr_err("%s: cx231xx_dif set to By pass" " mode- errCode [%d]!\n", __func__, status); return status; @@ -826,7 +826,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Reinitialize the DIF */ status = cx231xx_dif_set_standard(dev, dev->norm); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" + pr_err("%s: cx231xx_dif set to By pass" " mode- errCode [%d]!\n", __func__, status); return status; @@ -970,14 +970,14 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) { int status = 0; - cx231xx_info("do_mode_ctrl_overrides : 0x%x\n", + pr_info("do_mode_ctrl_overrides : 0x%x\n", (unsigned int)dev->norm); /* Change the DFE_CTRL3 bp_percent to fix flagging */ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280); if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { - cx231xx_info("do_mode_ctrl_overrides NTSC\n"); + pr_info("do_mode_ctrl_overrides NTSC\n"); /* Move the close caption lines out of active video, adjust the active video start point */ @@ -1004,7 +1004,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) (FLD_HBLANK_CNT, 0x79)); } else if (dev->norm & V4L2_STD_SECAM) { - cx231xx_info("do_mode_ctrl_overrides SECAM\n"); + pr_info("do_mode_ctrl_overrides SECAM\n"); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1031,7 +1031,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) cx231xx_set_field (FLD_HBLANK_CNT, 0x85)); } else { - cx231xx_info("do_mode_ctrl_overrides PAL\n"); + pr_info("do_mode_ctrl_overrides PAL\n"); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1331,109 +1331,109 @@ void cx231xx_dump_HH_reg(struct cx231xx *dev) for (i = 0x100; i < 0x140; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + pr_info("reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x300; i < 0x400; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + pr_info("reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x400; i < 0x440; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + pr_info("reg0x%x=0x%x\n", i, value); i = i+3; } vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + pr_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + pr_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); } void cx231xx_dump_SC_reg(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - cx231xx_info("cx231xx_dump_SC_reg!\n"); + pr_info("cx231xx_dump_SC_reg!\n"); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], + pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], value[1], value[2], value[3]); @@ -1503,7 +1503,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, u32 standard = 0; u8 value[4] = { 0, 0, 0, 0 }; - cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n"); + pr_info("Enter cx231xx_set_Colibri_For_LowIF()\n"); value[0] = (u8) 0x6F; value[1] = (u8) 0x6F; value[2] = (u8) 0x6F; @@ -1523,7 +1523,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, standard); - cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n", + pr_info("colibri_carrier_offset=%d, standard=0x%x\n", colibri_carrier_offset, standard); /* Set the band Pass filter for DIF*/ @@ -1557,7 +1557,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, u64 pll_freq_u64 = 0; u32 i = 0; - cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", + pr_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", if_freq, spectral_invert, mode); @@ -1601,7 +1601,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, if_freq = 16000000; } - cx231xx_info("Enter IF=%zu\n", + pr_info("Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) { if (Dif_set_array[i].if_freq == if_freq) { @@ -1714,7 +1714,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) u32 dif_misc_ctrl_value = 0; u32 func_mode = 0; - cx231xx_info("%s: setStandard to %x\n", __func__, standard); + pr_info("%s: setStandard to %x\n", __func__, standard); status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value); if (standard != DIF_USE_BASEBAND) @@ -2117,7 +2117,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) { int status = 0; u32 dwval; - cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n", + pr_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n", dev->tuner_type); /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for * SECAM L/B/D standards */ @@ -2219,7 +2219,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (dev->power_mode != mode) dev->power_mode = mode; else { - cx231xx_info(" setPowerMode::mode = %d, No Change req.\n", + pr_info(" setPowerMode::mode = %d, No Change req.\n", mode); return 0; } @@ -2459,7 +2459,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask); + pr_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2484,7 +2484,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask); + pr_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2512,32 +2512,32 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { case Audio: - cx231xx_info("%s: Audio enter HANC\n", __func__); + pr_info("%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; case Vbi: - cx231xx_info("%s: set vanc registers\n", __func__); + pr_info("%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; case Sliced_cc: - cx231xx_info("%s: set hanc registers\n", __func__); + pr_info("%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; case Raw_Video: - cx231xx_info("%s: set video registers\n", __func__); + pr_info("%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; case TS1_serial_mode: - cx231xx_info("%s: set ts1 registers", __func__); + pr_info("%s: set ts1 registers", __func__); if (dev->board.has_417) { - cx231xx_info(" MPEG\n"); + pr_info(" MPEG\n"); value &= 0xFFFFFFFC; value |= 0x3; @@ -2558,14 +2558,14 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) TS1_LENGTH_REG, val, 4); } else { - cx231xx_info(" BDA\n"); + pr_info(" BDA\n"); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010); } break; case TS1_parallel_mode: - cx231xx_info("%s: set ts1 parallel mode registers\n", + pr_info("%s: set ts1 parallel mode registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); @@ -2919,7 +2919,7 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) (nCnt > 0)); if (nCnt == 0) - cx231xx_info("No ACK after %d msec -GPIO I2C failed!", + pr_info("No ACK after %d msec -GPIO I2C failed!", nInit * 10); /* diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 432cbcf8ce43..375fd85447f8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -35,7 +36,6 @@ #include "xc5000.h" #include "tda18271.h" -#include "cx231xx.h" static int tuner = -1; module_param(tuner, int, 0444); @@ -673,7 +673,7 @@ struct cx231xx_board cx231xx_boards[] = { .decoder = CX231XX_AVDECODER, .output_mode = OUT_MODE_VIP11, .ctl_pin_status_mask = 0xFFFFFFC4, - .agc_analog_digital_select_gpio = 0x0c, + .agc_analog_digital_select_gpio = 0x0c, /* According with PV CxPlrCAP.inf file */ .gpio_pin_status_mask = 0x4001000, .norm = V4L2_STD_NTSC, @@ -856,7 +856,7 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) if (dev->tuner_type == TUNER_XC5000) { if (command == XC5000_TUNER_RESET) { - cx231xx_info + pr_info ("Tuner CB: RESET: cmd %d : tuner type %d \n", command, dev->tuner_type); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, @@ -916,7 +916,7 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) cx231xx_set_model(dev); - cx231xx_info("Identified as %s (card=%d)\n", + pr_info("Identified as %s (card=%d)\n", dev->board.name, dev->model); /* set the direction for GPIO pins */ @@ -990,7 +990,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, /* start reading at offset 0 */ ret = i2c_transfer(client->adapter, &msg_write, 1); if (ret < 0) { - cx231xx_err("Can't read eeprom\n"); + pr_err("Can't read eeprom\n"); return ret; } @@ -1000,7 +1000,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, ret = i2c_transfer(client->adapter, &msg_read, 1); if (ret < 0) { - cx231xx_err("Can't read eeprom\n"); + pr_err("Can't read eeprom\n"); return ret; } eedata_cur += msg_read.len; @@ -1008,7 +1008,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, } for (i = 0; i + 15 < len; i += 16) - cx231xx_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); + pr_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); return 0; } @@ -1028,7 +1028,7 @@ void cx231xx_card_setup(struct cx231xx *dev) cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) - cx231xx_info("cx25840 subdev registration failure\n"); + pr_info("cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); } @@ -1042,7 +1042,7 @@ void cx231xx_card_setup(struct cx231xx *dev) "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) - cx231xx_info("tuner subdev registration failure\n"); + pr_info("tuner subdev registration failure\n"); else cx231xx_config_tuner(dev); } @@ -1148,7 +1148,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* Query cx231xx to find what pcb config it is related to */ retval = initialize_cx231xx(dev); if (retval < 0) { - cx231xx_errdev("Failed to read PCB config\n"); + pr_err("Failed to read PCB config\n"); return retval; } @@ -1164,7 +1164,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - cx231xx_errdev("error configuring device\n"); + pr_err("error configuring device\n"); return -ENOMEM; } @@ -1174,7 +1174,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* register i2c bus */ retval = cx231xx_dev_init(dev); if (retval) { - cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", + pr_err("%s: cx231xx_i2c_register - errCode [%d]!\n", __func__, retval); goto err_dev_init; } @@ -1196,7 +1196,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", + pr_err("%s: cx231xx_config - errCode [%d]!\n", __func__, retval); goto err_dev_init; } @@ -1281,7 +1281,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for video */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("Video PCB interface #%d doesn't exist\n", idx); + pr_err("Video PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1290,20 +1290,20 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", dev->video_mode.end_point_addr, dev->video_mode.num_alt); dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); if (dev->video_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + pr_err("out of memory!\n"); return -ENOMEM; } for (i = 0; i < dev->video_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, + pr_info("Alternate setting %i, max size= %i\n", i, dev->video_mode.alt_max_pkt_size[i]); } @@ -1311,7 +1311,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("VBI PCB interface #%d doesn't exist\n", idx); + pr_err("VBI PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1321,14 +1321,14 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", dev->vbi_mode.end_point_addr, dev->vbi_mode.num_alt); /* compute alternate max packet sizes for vbi */ dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); if (dev->vbi_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + pr_err("out of memory!\n"); return -ENOMEM; } @@ -1338,7 +1338,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, + pr_info("Alternate setting %i, max size= %i\n", i, dev->vbi_mode.alt_max_pkt_size[i]); } @@ -1347,7 +1347,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for sliced CC */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("Sliced CC PCB interface #%d doesn't exist\n", idx); + pr_err("Sliced CC PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1357,13 +1357,13 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", dev->sliced_cc_mode.end_point_addr, dev->sliced_cc_mode.num_alt); dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + pr_err("out of memory!\n"); return -ENOMEM; } @@ -1372,7 +1372,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->sliced_cc_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, + pr_info("Alternate setting %i, max size= %i\n", i, dev->sliced_cc_mode.alt_max_pkt_size[i]); } @@ -1410,7 +1410,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); if (nr >= CX231XX_MAXBOARDS) { /* No free device slots */ - cx231xx_err(DRIVER_NAME ": Supports only %i devices.\n", + pr_err(DRIVER_NAME ": Supports only %i devices.\n", CX231XX_MAXBOARDS); return -ENOMEM; } @@ -1421,7 +1421,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - cx231xx_err(DRIVER_NAME ": out of memory!\n"); + pr_err(DRIVER_NAME ": out of memory!\n"); clear_bit(nr, &cx231xx_devused); return -ENOMEM; } @@ -1468,7 +1468,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - cx231xx_info("New device %s %s @ %s Mbps " + pr_info("New device %s %s @ %s Mbps " "(%04x:%04x) with %d interfaces\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", @@ -1485,13 +1485,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, assoc_desc = udev->actconfig->intf_assoc[0]; if (assoc_desc->bFirstInterface != ifnum) { - cx231xx_err(DRIVER_NAME ": Not found " + pr_err(DRIVER_NAME ": Not found " "matching IAD interface\n"); retval = -ENODEV; goto err_if; } - cx231xx_info("registering interface %d\n", ifnum); + pr_info("registering interface %d\n", ifnum); /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); @@ -1499,7 +1499,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* Create v4l2 device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { - cx231xx_errdev("v4l2_device_register failed\n"); + pr_err("v4l2_device_register failed\n"); goto err_v4l2; } @@ -1516,7 +1516,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes for TS1 */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("TS1 PCB interface #%d doesn't exist\n", idx); + pr_err("TS1 PCB interface #%d doesn't exist\n", idx); retval = -ENODEV; goto err_video_alt; } @@ -1527,13 +1527,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", dev->ts1_mode.end_point_addr, dev->ts1_mode.num_alt); dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); if (dev->ts1_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + pr_err("out of memory!\n"); retval = -ENOMEM; goto err_video_alt; } @@ -1544,7 +1544,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->ts1_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, + pr_info("Alternate setting %i, max size= %i\n", i, dev->ts1_mode.alt_max_pkt_size[i]); } } @@ -1609,7 +1609,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) wake_up_interruptible_all(&dev->open); if (dev->users) { - cx231xx_warn + pr_warn ("device %s is open! Deregistration and memory " "deallocation are deferred on close.\n", video_device_node_name(dev->vdev)); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 9b5cd9e9b169..229e855fc7f2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -29,7 +30,6 @@ #include #include -#include "cx231xx.h" #include "cx231xx-reg.h" /* #define ENABLE_DEBUG_ISOC_FRAMES */ @@ -228,7 +228,7 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - cx231xx_info + pr_info ("UsbInterface::sendCommand, failed with status -%d\n", status); } @@ -524,7 +524,7 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); if (errCode < 0) { - cx231xx_errdev + pr_err ("cannot change alt number to %d (error=%i)\n", dev->video_mode.alt, errCode); return errCode; @@ -600,7 +600,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) } if (alt > 0 && max_pkt_size == 0) { - cx231xx_errdev + pr_err ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", usb_interface_index, alt); /*To workaround error number=-71 on EP0 for videograbber, @@ -616,7 +616,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) if (usb_interface_index > 0) { status = usb_set_interface(dev->udev, usb_interface_index, alt); if (status < 0) { - cx231xx_errdev + pr_err ("can't change interface %d alt no. to %d (err=%i)\n", usb_interface_index, alt, status); return status; @@ -768,7 +768,7 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) buffer = kzalloc(4096, GFP_KERNEL); if (buffer == NULL) { - cx231xx_info("out of mem\n"); + pr_info("out of mem\n"); return -ENOMEM; } memcpy(&buffer[0], firmware, 4096); @@ -777,7 +777,7 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) buffer, 4096, &actlen, 2000); if (ret) - cx231xx_info("bulk message failed: %d (%d/%d)", ret, + pr_info("bulk message failed: %d (%d/%d)", ret, size, actlen); else { errCode = actlen != size ? -1 : 0; @@ -988,7 +988,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dma_q->p_left_data = kzalloc(4096, GFP_KERNEL); if (dma_q->p_left_data == NULL) { - cx231xx_info("out of mem\n"); + pr_info("out of mem\n"); return -ENOMEM; } @@ -1018,14 +1018,14 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dev->video_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + pr_err("cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + pr_err("cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); return -ENOMEM; } @@ -1045,7 +1045,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { urb = usb_alloc_urb(max_packets, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc isoc_ctl.urb %i\n", i); + pr_err("cannot alloc isoc_ctl.urb %i\n", i); cx231xx_uninit_isoc(dev); return -ENOMEM; } @@ -1055,7 +1055,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" + pr_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -1090,7 +1090,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, + pr_err("submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_isoc(dev); return rc; @@ -1151,14 +1151,14 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dev->video_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + pr_err("cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + pr_err("cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.bulk_ctl.urb); return -ENOMEM; } @@ -1178,7 +1178,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); + pr_err("cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_bulk(dev); return -ENOMEM; } @@ -1189,7 +1189,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" + pr_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -1212,7 +1212,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, + pr_err("submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_bulk(dev); return rc; @@ -1316,7 +1316,7 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1325,7 +1325,7 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1340,14 +1340,14 @@ int cx231xx_dev_init(struct cx231xx *dev) /* initialize Colibri block */ errCode = cx231xx_afe_init_super_block(dev, 0x23c); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: cx231xx_afe init super block - errCode [%d]!\n", __func__, errCode); return errCode; } errCode = cx231xx_afe_init_channels(dev); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: cx231xx_afe init channels - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1356,7 +1356,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* Set DIF in By pass mode */ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1365,7 +1365,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* I2S block related functions */ errCode = cx231xx_i2s_blk_initialize(dev); if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: cx231xx_i2s block initialize - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1374,7 +1374,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* init control pins */ errCode = cx231xx_init_ctrl_pin_status(dev); if (errCode < 0) { - cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n", + pr_err("%s: cx231xx_init ctrl pins - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1400,7 +1400,7 @@ int cx231xx_dev_init(struct cx231xx *dev) break; } if (errCode < 0) { - cx231xx_errdev + pr_err ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1477,7 +1477,7 @@ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - cx231xx_info + pr_info ("UsbInterface::sendCommand, failed with status -%d\n", status); } diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 2ea69469e74b..a743865b40c0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -19,11 +19,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include -#include "cx231xx.h" #include #include @@ -265,7 +265,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) struct cx231xx *dev = dvb->adapter.priv; if (dev->USE_ISO) { - cx231xx_info("DVB transfer mode is ISO.\n"); + pr_info("DVB transfer mode is ISO.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -276,7 +276,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) dev->ts1_mode.max_pkt_size, dvb_isoc_copy); } else { - cx231xx_info("DVB transfer mode is BULK.\n"); + pr_info("DVB transfer mode is BULK.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 0); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -430,15 +430,15 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) if (dops->init != NULL && !dev->xc_fw_load_done) { - cx231xx_info("Reloading firmware for XC5000\n"); + pr_info("Reloading firmware for XC5000\n"); status = dops->init(dev->dvb->frontend); if (status == 0) { dev->xc_fw_load_done = 1; - cx231xx_info + pr_info ("XC5000 firmware download completed\n"); } else { dev->xc_fw_load_done = 0; - cx231xx_info + pr_info ("XC5000 firmware download failed !!!\n"); } } diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index d1003c703fb5..d4a468a60bd0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -28,7 +29,6 @@ #include #include -#include "cx231xx.h" /* ----------------------------------------------------------- */ @@ -498,17 +498,17 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); - cx231xx_info(": Checking for I2C devices on port=%d ..\n", i2c_port); + pr_info(": Checking for I2C devices on port=%d ..\n", i2c_port); for (i = 0; i < 128; i++) { client.addr = i; rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; - cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", + pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } - cx231xx_info(": Completed Checking for I2C devices on port=%d.\n", + pr_info(": Completed Checking for I2C devices on port=%d.\n", i2c_port); } @@ -532,7 +532,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_add_adapter(&bus->i2c_adap); if (0 != bus->i2c_rc) - cx231xx_warn("%s: i2c bus %d register FAILED\n", + pr_warn("%s: i2c bus %d register FAILED\n", dev->name, bus->nr); return bus->i2c_rc; @@ -576,7 +576,7 @@ int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) NULL); if (!dev->i2c_mux_adap[mux_no]) - cx231xx_warn("%s: i2c mux %d register FAILED\n", + pr_warn("%s: i2c mux %d register FAILED\n", dev->name, mux_no); return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index 3052c4c20229..4666e533fe0a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -703,8 +703,8 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY; break; default: - cx231xx_info("bad config in buspower!!!!\n"); - cx231xx_info("config_info=%x\n", + pr_info("bad config in buspower!!!!\n"); + pr_info("config_info=%x\n", (config_info & BUSPOWER_MASK)); return 1; } @@ -768,8 +768,8 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR; break; default: - cx231xx_info("bad senario!!!!!\n"); - cx231xx_info("config_info=%x\n", + pr_info("bad senario!!!!!\n"); + pr_info("config_info=%x\n", (config_info & SELFPOWER_MASK)); return -ENODEV; } @@ -781,17 +781,17 @@ int initialize_cx231xx(struct cx231xx *dev) sizeof(struct pcb_config)); if (pcb_debug) { - cx231xx_info("SC(0x00) register = 0x%x\n", config_info); - cx231xx_info("scenario %d\n", + pr_info("SC(0x00) register = 0x%x\n", config_info); + pr_info("scenario %d\n", (dev->current_pcb_config.index) + 1); - cx231xx_info("type=%x\n", dev->current_pcb_config.type); - cx231xx_info("mode=%x\n", dev->current_pcb_config.mode); - cx231xx_info("speed=%x\n", dev->current_pcb_config.speed); - cx231xx_info("ts1_source=%x\n", + pr_info("type=%x\n", dev->current_pcb_config.type); + pr_info("mode=%x\n", dev->current_pcb_config.mode); + pr_info("speed=%x\n", dev->current_pcb_config.speed); + pr_info("ts1_source=%x\n", dev->current_pcb_config.ts1_source); - cx231xx_info("ts2_source=%x\n", + pr_info("ts2_source=%x\n", dev->current_pcb_config.ts2_source); - cx231xx_info("analog_source=%x\n", + pr_info("analog_source=%x\n", dev->current_pcb_config.analog_source); } diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index c02794274f51..f80126d3525a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -35,7 +36,6 @@ #include #include -#include "cx231xx.h" #include "cx231xx-vbi.h" static inline void print_err_status(struct cx231xx *dev, int packet, int status) @@ -69,10 +69,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - cx231xx_err("URB status %d [%s].\n", status, + pr_err("URB status %d [%s].\n", status, errmsg); } else { - cx231xx_err("URB packet %d, status %d [%s].\n", + pr_err("URB packet %d, status %d [%s].\n", packet, status, errmsg); } } @@ -316,7 +316,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - cx231xx_err("urb completition error %d.\n", + pr_err("urb completition error %d.\n", urb->status); break; } @@ -331,7 +331,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { - cx231xx_err("urb resubmit failed (error=%i)\n", + pr_err("urb resubmit failed (error=%i)\n", urb->status); } } @@ -344,7 +344,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - cx231xx_info("called cx231xx_uninit_vbi_isoc\n"); + pr_info("called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -393,7 +393,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - cx231xx_info("called cx231xx_vbi_isoc\n"); + pr_info("called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -419,14 +419,14 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + pr_err("cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->vbi_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + pr_err("cannot allocate memory for usbtransfer\n"); kfree(dev->vbi_mode.bulk_ctl.urb); return -ENOMEM; } @@ -441,7 +441,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); + pr_err("cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -451,7 +451,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" + pr_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); cx231xx_uninit_vbi_isoc(dev); @@ -470,7 +470,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, + pr_err("submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; @@ -522,7 +522,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* cx231xx_info("[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* pr_info("[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; @@ -614,7 +614,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, char *outp; if (list_empty(&dma_q->active)) { - cx231xx_err("No active queue to serve\n"); + pr_err("No active queue to serve\n"); dev->vbi_mode.bulk_ctl.buf = NULL; *buf = NULL; return; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 3b3ada6562ca..bda5597b5eff 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include #include #include @@ -41,7 +42,6 @@ #include "dvb_frontend.h" -#include "cx231xx.h" #include "cx231xx-vbi.h" #define CX231XX_VERSION "0.0.2" @@ -737,7 +737,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", + /*pr_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", urb_init, dev->video_mode.max_pkt_size);*/ if (urb_init) { dev->mode_tv = 0; @@ -809,7 +809,7 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_set_audio_input(dev, dev->ctl_ainput); - cx231xx_info("video_mux : %d\n", index); + pr_info("video_mux : %d\n", index); /* do mode control overrides if required */ cx231xx_do_mode_ctrl_overrides(dev); @@ -861,7 +861,7 @@ static void res_free(struct cx231xx_fh *fh) static int check_dev(struct cx231xx *dev) { if (dev->state & DEV_DISCONNECTED) { - cx231xx_errdev("v4l2 ioctl: device not present\n"); + pr_err("v4l2 ioctl: device not present\n"); return -ENODEV; } return 0; @@ -953,12 +953,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; if (videobuf_queue_is_busy(&fh->vb_vidq)) { - cx231xx_errdev("%s queue busy\n", __func__); + pr_err("%s queue busy\n", __func__); return -EBUSY; } if (dev->stream_on && !fh->stream_on) { - cx231xx_errdev("%s device in use by another fh\n", __func__); + pr_err("%s device in use by another fh\n", __func__); return -EBUSY; } @@ -1176,9 +1176,9 @@ int cx231xx_s_frequency(struct file *file, void *priv, int rc; u32 if_frequency = 5400000; - cx231xx_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", + pr_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", f->frequency, f->type); - /*cx231xx_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/ + /*pr_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/ rc = check_dev(dev); if (rc < 0) @@ -1213,13 +1213,13 @@ int cx231xx_s_frequency(struct file *file, void *priv, else if (dev->norm & V4L2_STD_SECAM_LC) if_frequency = 1250000; /*1.25MHz */ - cx231xx_info("if_frequency is set to %d\n", if_frequency); + pr_info("if_frequency is set to %d\n", if_frequency); cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); update_HH_register_after_set_DIF(dev); } - cx231xx_info("Set New FREQUENCY to %d\n", f->frequency); + pr_info("Set New FREQUENCY to %d\n", f->frequency); return rc; } @@ -1523,7 +1523,7 @@ static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; if (dev->vbi_stream_on && !fh->stream_on) { - cx231xx_errdev("%s device in use by another fh\n", __func__); + pr_err("%s device in use by another fh\n", __func__); return -EBUSY; } return vidioc_try_fmt_vbi_cap(file, priv, f); @@ -1642,7 +1642,7 @@ static int cx231xx_v4l2_open(struct file *filp) #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); if (errCode < 0) { - cx231xx_errdev + pr_err ("Device locked on digital mode. Can't open analog\n"); return -EBUSY; } @@ -1650,7 +1650,7 @@ static int cx231xx_v4l2_open(struct file *filp) fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); if (!fh) { - cx231xx_errdev("cx231xx-video.c: Out of memory?!\n"); + pr_err("cx231xx-video.c: Out of memory?!\n"); return -ENOMEM; } if (mutex_lock_interruptible(&dev->lock)) { @@ -1736,7 +1736,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - cx231xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vbi_dev)); if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); @@ -1745,7 +1745,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - cx231xx_info("V4L2 device %s deregistered\n", + pr_info("V4L2 device %s deregistered\n", video_device_node_name(dev->vdev)); if (dev->board.has_417) @@ -2080,7 +2080,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) { int ret; - cx231xx_info("%s: v4l2 driver version %s\n", + pr_info("%s: v4l2 driver version %s\n", dev->name, CX231XX_VERSION); /* set default norm */ @@ -2119,7 +2119,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* allocate and fill video video_device struct */ dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); if (!dev->vdev) { - cx231xx_errdev("cannot allocate video_device.\n"); + pr_err("cannot allocate video_device.\n"); return -ENODEV; } @@ -2128,12 +2128,12 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - cx231xx_errdev("unable to register video device (error=%i).\n", + pr_err("unable to register video device (error=%i).\n", ret); return ret; } - cx231xx_info("%s/0: registered device %s [v4l2]\n", + pr_info("%s/0: registered device %s [v4l2]\n", dev->name, video_device_node_name(dev->vdev)); /* Initialize VBI template */ @@ -2144,7 +2144,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); if (!dev->vbi_dev) { - cx231xx_errdev("cannot allocate video_device.\n"); + pr_err("cannot allocate video_device.\n"); return -ENODEV; } dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; @@ -2152,32 +2152,32 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - cx231xx_errdev("unable to register vbi device\n"); + pr_err("unable to register vbi device\n"); return ret; } - cx231xx_info("%s/0: registered device %s\n", + pr_info("%s/0: registered device %s\n", dev->name, video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio"); if (!dev->radio_dev) { - cx231xx_errdev("cannot allocate video_device.\n"); + pr_err("cannot allocate video_device.\n"); return -ENODEV; } dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - cx231xx_errdev("can't register radio device\n"); + pr_err("can't register radio device\n"); return ret; } - cx231xx_info("Registered radio device as %s\n", + pr_info("Registered radio device as %s\n", video_device_node_name(dev->radio_dev)); } - cx231xx_info("V4L2 device registered as %s and %s\n", + pr_info("V4L2 device registered as %s and %s\n", video_device_node_name(dev->vdev), video_device_node_name(dev->vbi_dev)); diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index a0ec24176522..fa27e0c2accb 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -22,6 +22,8 @@ #ifndef _CX231XX_H #define _CX231XX_H +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -981,23 +983,6 @@ void cx231xx_ir_exit(struct cx231xx *dev); #define cx231xx_ir_exit(dev) (0) #endif - -/* printk macros */ - -#define cx231xx_err(fmt, arg...) do {\ - printk(KERN_ERR fmt , ##arg); } while (0) - -#define cx231xx_errdev(fmt, arg...) do {\ - printk(KERN_ERR "%s: "fmt,\ - dev->name , ##arg); } while (0) - -#define cx231xx_info(fmt, arg...) do {\ - printk(KERN_INFO "%s: "fmt,\ - dev->name , ##arg); } while (0) -#define cx231xx_warn(fmt, arg...) do {\ - printk(KERN_WARNING "%s: "fmt,\ - dev->name , ##arg); } while (0) - static inline unsigned int norm_maxw(struct cx231xx *dev) { if (dev->board.max_range_640_480) -- GitLab From 88538bb5449caef8347a2785f7ac32c0b8d5858c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 08:45:36 -0300 Subject: [PATCH 2667/9457] [media] cx231xx: Fix identation One of the identation blocks is wrong. Fix it. While here, replace pr_info by pr_debug inside such block and add the function name to the print messages, as otherwise they will not help much. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 60 ++++++++++++---------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 9185b05b4fbe..58b42e63405c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2534,34 +2534,38 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) break; case TS1_serial_mode: - pr_info("%s: set ts1 registers", __func__); - - if (dev->board.has_417) { - pr_info(" MPEG\n"); - value &= 0xFFFFFFFC; - value |= 0x3; - - status = cx231xx_mode_register(dev, TS_MODE_REG, value); - - val[0] = 0x04; - val[1] = 0xA3; - val[2] = 0x3B; - val[3] = 0x00; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - TS1_CFG_REG, val, 4); - - val[0] = 0x00; - val[1] = 0x08; - val[2] = 0x00; - val[3] = 0x08; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - TS1_LENGTH_REG, val, 4); - - } else { - pr_info(" BDA\n"); - status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); - status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010); - } + pr_debug("%s: set ts1 registers", __func__); + + if (dev->board.has_417) { + pr_debug("%s: MPEG\n", __func__); + value &= 0xFFFFFFFC; + value |= 0x3; + + status = cx231xx_mode_register(dev, + TS_MODE_REG, value); + + val[0] = 0x04; + val[1] = 0xA3; + val[2] = 0x3B; + val[3] = 0x00; + status = cx231xx_write_ctrl_reg(dev, + VRT_SET_REGISTER, + TS1_CFG_REG, val, 4); + + val[0] = 0x00; + val[1] = 0x08; + val[2] = 0x00; + val[3] = 0x08; + status = cx231xx_write_ctrl_reg(dev, + VRT_SET_REGISTER, + TS1_LENGTH_REG, val, 4); + } else { + pr_debug("%s: BDA\n", __func__); + status = cx231xx_mode_register(dev, + TS_MODE_REG, 0x101); + status = cx231xx_mode_register(dev, + TS1_CFG_REG, 0x010); + } break; case TS1_parallel_mode: -- GitLab From ed0e3729c9d790d17688083f070da3674088ea9c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 08:59:03 -0300 Subject: [PATCH 2668/9457] [media] cx231xx: Cleanup printk at the driver There are lots of debug printks printed with pr_info. Also, the printk's data are not too coherent: - there are duplicated driver name at the print format; - function name format string differs from function to function; - long strings broken into multiple lines; - some printks just produce ugly reports, being almost useless as-is. Do a cleanup on that. Still, there are much to be done in order to do a better printk job on this driver, but, at least it will now be a way less verbose, if debug printks are disabled, and some logs might actually be useful. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 15 +-- drivers/media/usb/cx231xx/cx231xx-audio.c | 20 ++- drivers/media/usb/cx231xx/cx231xx-avcore.c | 142 ++++++++++---------- drivers/media/usb/cx231xx/cx231xx-cards.c | 81 +++++------ drivers/media/usb/cx231xx/cx231xx-core.c | 93 +++++-------- drivers/media/usb/cx231xx/cx231xx-dvb.c | 12 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 17 ++- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | 12 +- drivers/media/usb/cx231xx/cx231xx-vbi.c | 24 ++-- drivers/media/usb/cx231xx/cx231xx-video.c | 41 +++--- drivers/media/usb/cx231xx/cx231xx.h | 1 - 11 files changed, 199 insertions(+), 259 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index d678f4587ab4..a0d1156d1df1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -90,10 +90,10 @@ static unsigned int v4l_debug = 1; module_param(v4l_debug, int, 0644); MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); -#define dprintk(level, fmt, arg...)\ - do { if (v4l_debug >= level) \ - pr_info("%s: " fmt, \ - (dev) ? dev->name : "cx231xx[?]", ## arg); \ +#define dprintk(level, fmt, arg...) \ + do { \ + if (v4l_debug >= level) \ + printk(KERN_DEBUG pr_fmt(fmt), ## arg); \ } while (0) static struct cx231xx_tvnorm cx231xx_tvnorms[] = { @@ -1114,15 +1114,15 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) cx231xx_disable656(dev); retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ if (retval < 0) { - dprintk(2, "%s() PING OK\n", __func__); + dprintk(2, "%s: PING OK\n", __func__); retval = cx231xx_load_firmware(dev); if (retval < 0) { - pr_err("%s() f/w load failed\n", __func__); + pr_err("%s: f/w load failed\n", __func__); return retval; } retval = cx231xx_find_mailbox(dev); if (retval < 0) { - pr_err("%s() mailbox < 0, error\n", + pr_err("%s: mailbox < 0, error\n", __func__); return -1; } @@ -1798,7 +1798,6 @@ static unsigned int mpeg_poll(struct file *file, static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) { struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; dprintk(2, "%s()\n", __func__); diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 8312388edabb..e96703180c0c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -277,7 +277,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) int i, errCode; int sb_size; - pr_info("%s: Starting ISO AUDIO transfers\n", __func__); + pr_debug("%s: Starting ISO AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -338,7 +338,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) int i, errCode; int sb_size; - pr_info("%s: Starting BULK AUDIO transfers\n", __func__); + pr_debug("%s: Starting BULK AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -439,8 +439,7 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); if (!dev) { - pr_err("BUG: cx231xx can't find device struct." - " Can't proceed with open\n"); + pr_err("BUG: cx231xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } @@ -662,8 +661,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) return 0; } - pr_info("cx231xx-audio.c: probing for cx231xx " - "non standard usbaudio\n"); + pr_debug("probing for cx231xx non standard usbaudio\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio", THIS_MODULE, 0, &card); @@ -707,14 +705,12 @@ static int cx231xx_audio_init(struct cx231xx *dev) bEndpointAddress; adev->num_alt = uif->num_altsetting; - pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - adev->end_point_addr, adev->num_alt); + pr_info("audio EndPoint Addr 0x%x, Alternate settings: %i\n", + adev->end_point_addr, adev->num_alt); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); - if (adev->alt_max_pkt_size == NULL) { - pr_err("out of memory!\n"); + if (adev->alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < adev->num_alt; i++) { u16 tmp = @@ -722,7 +718,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) wMaxPacketSize); adev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_info("Alternate setting %i, max size= %i\n", i, + pr_debug("audio alternate setting %i, max size= %i\n", i, adev->alt_max_pkt_size[i]); } diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 58b42e63405c..62c63b9e2291 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -83,10 +83,10 @@ void initGPIO(struct cx231xx *dev) cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); verve_read_byte(dev, 0x07, &val); - pr_info(" verve_read_byte address0x07=0x%x\n", val); + pr_debug("verve_read_byte address0x07=0x%x\n", val); verve_write_byte(dev, 0x07, 0xF4); verve_read_byte(dev, 0x07, &val); - pr_info(" verve_read_byte address0x07=0x%x\n", val); + pr_debug("verve_read_byte address0x07=0x%x\n", val); cx231xx_capture_start(dev, 1, Vbi); @@ -156,22 +156,22 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) while (afe_power_status != 0x18) { status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18); if (status < 0) { - pr_info( - ": Init Super Block failed in send cmd\n"); + pr_debug("%s: Init Super Block failed in send cmd\n", + __func__); break; } status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status); afe_power_status &= 0xff; if (status < 0) { - pr_info( - ": Init Super Block failed in receive cmd\n"); + pr_debug("%s: Init Super Block failed in receive cmd\n", + __func__); break; } i++; if (i == 10) { - pr_info( - ": Init Super Block force break in loop !!!!\n"); + pr_debug("%s: Init Super Block force break in loop !!!!\n", + __func__); status = -1; break; } @@ -410,7 +410,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00); } else { - pr_info("Invalid AV mode input\n"); + pr_debug("Invalid AV mode input\n"); status = -1; } break; @@ -467,7 +467,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x40); } else { - pr_info("Invalid AV mode input\n"); + pr_debug("Invalid AV mode input\n"); status = -1; } } /* switch */ @@ -628,8 +628,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, if (pin_type != dev->video_input) { status = cx231xx_afe_adjust_ref_count(dev, pin_type); if (status < 0) { - pr_err("%s: adjust_ref_count :Failed to set" - "AFE input mux - errCode [%d]!\n", + pr_err("%s: adjust_ref_count :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; } @@ -638,9 +637,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* call afe block to set video inputs */ status = cx231xx_afe_set_input_mux(dev, input); if (status < 0) { - pr_err("%s: set_input_mux :Failed to set" - " AFE input mux - errCode [%d]!\n", - __func__, status); + pr_err("%s: set_input_mux :Failed to set AFE input mux - errCode [%d]!\n", + __func__, status); return status; } @@ -670,8 +668,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", + pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -715,8 +712,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", + pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -790,9 +786,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", - __func__, status); + pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + __func__, status); return status; } @@ -826,9 +821,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Reinitialize the DIF */ status = cx231xx_dif_set_standard(dev, dev->norm); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", - __func__, status); + pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + __func__, status); return status; } @@ -970,14 +964,14 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) { int status = 0; - pr_info("do_mode_ctrl_overrides : 0x%x\n", - (unsigned int)dev->norm); + pr_debug("%s: 0x%x\n", + __func__, (unsigned int)dev->norm); /* Change the DFE_CTRL3 bp_percent to fix flagging */ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280); if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { - pr_info("do_mode_ctrl_overrides NTSC\n"); + pr_debug("%s: NTSC\n", __func__); /* Move the close caption lines out of active video, adjust the active video start point */ @@ -1004,7 +998,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) (FLD_HBLANK_CNT, 0x79)); } else if (dev->norm & V4L2_STD_SECAM) { - pr_info("do_mode_ctrl_overrides SECAM\n"); + pr_debug("%s: SECAM\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1031,7 +1025,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) cx231xx_set_field (FLD_HBLANK_CNT, 0x85)); } else { - pr_info("do_mode_ctrl_overrides PAL\n"); + pr_debug("%s: PAL\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1331,113 +1325,113 @@ void cx231xx_dump_HH_reg(struct cx231xx *dev) for (i = 0x100; i < 0x140; i++) { vid_blk_read_word(dev, i, &value); - pr_info("reg0x%x=0x%x\n", i, value); + pr_debug("reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x300; i < 0x400; i++) { vid_blk_read_word(dev, i, &value); - pr_info("reg0x%x=0x%x\n", i, value); + pr_debug("reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x400; i < 0x440; i++) { vid_blk_read_word(dev, i, &value); - pr_info("reg0x%x=0x%x\n", i, value); + pr_debug("reg0x%x=0x%x\n", i, value); i = i+3; } vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - pr_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + pr_debug("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - pr_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + pr_debug("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); } -void cx231xx_dump_SC_reg(struct cx231xx *dev) +#if 0 +static void cx231xx_dump_SC_reg(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - pr_info("cx231xx_dump_SC_reg!\n"); + pr_debug("%s!\n", __func__); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); - pr_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], + pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], value[1], value[2], value[3]); - - } +#endif void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev) @@ -1503,7 +1497,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, u32 standard = 0; u8 value[4] = { 0, 0, 0, 0 }; - pr_info("Enter cx231xx_set_Colibri_For_LowIF()\n"); + pr_debug("Enter cx231xx_set_Colibri_For_LowIF()\n"); value[0] = (u8) 0x6F; value[1] = (u8) 0x6F; value[2] = (u8) 0x6F; @@ -1523,7 +1517,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, standard); - pr_info("colibri_carrier_offset=%d, standard=0x%x\n", + pr_debug("colibri_carrier_offset=%d, standard=0x%x\n", colibri_carrier_offset, standard); /* Set the band Pass filter for DIF*/ @@ -1557,7 +1551,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, u64 pll_freq_u64 = 0; u32 i = 0; - pr_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", + pr_debug("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", if_freq, spectral_invert, mode); @@ -1601,7 +1595,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, if_freq = 16000000; } - pr_info("Enter IF=%zu\n", + pr_debug("Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) { if (Dif_set_array[i].if_freq == if_freq) { @@ -1714,7 +1708,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) u32 dif_misc_ctrl_value = 0; u32 func_mode = 0; - pr_info("%s: setStandard to %x\n", __func__, standard); + pr_debug("%s: setStandard to %x\n", __func__, standard); status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value); if (standard != DIF_USE_BASEBAND) @@ -2117,8 +2111,8 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) { int status = 0; u32 dwval; - pr_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n", - dev->tuner_type); + pr_debug("%s: dev->tuner_type =0%d\n", + __func__, dev->tuner_type); /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for * SECAM L/B/D standards */ status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval); @@ -2219,8 +2213,8 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (dev->power_mode != mode) dev->power_mode = mode; else { - pr_info(" setPowerMode::mode = %d, No Change req.\n", - mode); + pr_debug("%s: mode = %d, No Change req.\n", + __func__, mode); return 0; } @@ -2459,7 +2453,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - pr_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask); + pr_debug("%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2484,7 +2478,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - pr_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask); + pr_debug("%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2512,24 +2506,24 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { case Audio: - pr_info("%s: Audio enter HANC\n", __func__); + pr_debug("%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; case Vbi: - pr_info("%s: set vanc registers\n", __func__); + pr_debug("%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; case Sliced_cc: - pr_info("%s: set hanc registers\n", __func__); + pr_debug("%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; case Raw_Video: - pr_info("%s: set video registers\n", __func__); + pr_debug("%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; @@ -2569,7 +2563,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) break; case TS1_parallel_mode: - pr_info("%s: set ts1 parallel mode registers\n", + pr_debug("%s: set ts1 parallel mode registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); @@ -2923,7 +2917,7 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) (nCnt > 0)); if (nCnt == 0) - pr_info("No ACK after %d msec -GPIO I2C failed!", + pr_debug("No ACK after %d msec -GPIO I2C failed!", nInit * 10); /* diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 375fd85447f8..d59f483102d2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -856,8 +856,7 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) if (dev->tuner_type == TUNER_XC5000) { if (command == XC5000_TUNER_RESET) { - pr_info - ("Tuner CB: RESET: cmd %d : tuner type %d \n", + pr_debug("Tuner CB: RESET: cmd %d : tuner type %d \n", command, dev->tuner_type); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); @@ -917,7 +916,7 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) cx231xx_set_model(dev); pr_info("Identified as %s (card=%d)\n", - dev->board.name, dev->model); + dev->board.name, dev->model); /* set the direction for GPIO pins */ if (dev->board.tuner_gpio) { @@ -1008,7 +1007,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, } for (i = 0; i + 15 < len; i += 16) - pr_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); + pr_debug("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); return 0; } @@ -1028,7 +1027,7 @@ void cx231xx_card_setup(struct cx231xx *dev) cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) - pr_info("cx25840 subdev registration failure\n"); + pr_err("cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); } @@ -1042,7 +1041,7 @@ void cx231xx_card_setup(struct cx231xx *dev) "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) - pr_info("tuner subdev registration failure\n"); + pr_err("tuner subdev registration failure\n"); else cx231xx_config_tuner(dev); } @@ -1290,21 +1289,19 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; - pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("video EndPoint Addr 0x%x, Alternate settings: %i\n", dev->video_mode.end_point_addr, dev->video_mode.num_alt); dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); - if (dev->video_mode.alt_max_pkt_size == NULL) { - pr_err("out of memory!\n"); + if (dev->video_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->video_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_info("Alternate setting %i, max size= %i\n", i, - dev->video_mode.alt_max_pkt_size[i]); + pr_debug("Alternate setting %i, max size= %i\n", i, + dev->video_mode.alt_max_pkt_size[i]); } /* VBI Init */ @@ -1321,16 +1318,14 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; - pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("VBI EndPoint Addr 0x%x, Alternate settings: %i\n", dev->vbi_mode.end_point_addr, dev->vbi_mode.num_alt); /* compute alternate max packet sizes for vbi */ dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); - if (dev->vbi_mode.alt_max_pkt_size == NULL) { - pr_err("out of memory!\n"); + if (dev->vbi_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->vbi_mode.num_alt; i++) { u16 tmp = @@ -1338,8 +1333,8 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_info("Alternate setting %i, max size= %i\n", i, - dev->vbi_mode.alt_max_pkt_size[i]); + pr_debug("Alternate setting %i, max size= %i\n", i, + dev->vbi_mode.alt_max_pkt_size[i]); } /* Sliced CC VBI init */ @@ -1357,23 +1352,20 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; - pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->sliced_cc_mode.end_point_addr, - dev->sliced_cc_mode.num_alt); + pr_info("sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->sliced_cc_mode.end_point_addr, + dev->sliced_cc_mode.num_alt); dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); - - if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { - pr_err("out of memory!\n"); + if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. desc.wMaxPacketSize); dev->sliced_cc_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_info("Alternate setting %i, max size= %i\n", i, - dev->sliced_cc_mode.alt_max_pkt_size[i]); + pr_debug("Alternate setting %i, max size= %i\n", i, + dev->sliced_cc_mode.alt_max_pkt_size[i]); } return 0; @@ -1410,8 +1402,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); if (nr >= CX231XX_MAXBOARDS) { /* No free device slots */ - pr_err(DRIVER_NAME ": Supports only %i devices.\n", - CX231XX_MAXBOARDS); + pr_err("Supports only %i devices.\n", CX231XX_MAXBOARDS); return -ENOMEM; } } while (test_and_set_bit(nr, &cx231xx_devused)); @@ -1421,7 +1412,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - pr_err(DRIVER_NAME ": out of memory!\n"); clear_bit(nr, &cx231xx_devused); return -ENOMEM; } @@ -1468,14 +1458,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - pr_info("New device %s %s @ %s Mbps " - "(%04x:%04x) with %d interfaces\n", - udev->manufacturer ? udev->manufacturer : "", - udev->product ? udev->product : "", - speed, - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - dev->max_iad_interface_count); + pr_info("New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", + udev->manufacturer ? udev->manufacturer : "", + udev->product ? udev->product : "", + speed, + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + dev->max_iad_interface_count); /* increment interface count */ dev->interface_count++; @@ -1485,13 +1474,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, assoc_desc = udev->actconfig->intf_assoc[0]; if (assoc_desc->bFirstInterface != ifnum) { - pr_err(DRIVER_NAME ": Not found " - "matching IAD interface\n"); + pr_err("Not found matching IAD interface\n"); retval = -ENODEV; goto err_if; } - pr_info("registering interface %d\n", ifnum); + pr_debug("registering interface %d\n", ifnum); /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); @@ -1527,13 +1515,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; - pr_info("EndPoint Addr 0x%x, Alternate settings: %i\n", + pr_info("TS EndPoint Addr 0x%x, Alternate settings: %i\n", dev->ts1_mode.end_point_addr, dev->ts1_mode.num_alt); dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); if (dev->ts1_mode.alt_max_pkt_size == NULL) { - pr_err("out of memory!\n"); retval = -ENOMEM; goto err_video_alt; } @@ -1544,7 +1531,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->ts1_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_info("Alternate setting %i, max size= %i\n", i, + pr_debug("Alternate setting %i, max size= %i\n", i, dev->ts1_mode.alt_max_pkt_size[i]); } } @@ -1609,10 +1596,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) wake_up_interruptible_all(&dev->open); if (dev->users) { - pr_warn - ("device %s is open! Deregistration and memory " - "deallocation are deferred on close.\n", - video_device_node_name(dev->vdev)); + pr_warn("device %s is open! Deregistration and memory deallocation are deferred on close.\n", + video_device_node_name(dev->vdev)); /* Even having users, it is safe to remove the RC i2c driver */ cx231xx_ir_exit(dev); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 229e855fc7f2..c5842a1ea104 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -228,9 +228,8 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - pr_info - ("UsbInterface::sendCommand, failed with status -%d\n", - status); + pr_err("%s: failed with status -%d\n", + __func__, status); } return status; @@ -524,9 +523,8 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); if (errCode < 0) { - pr_err - ("cannot change alt number to %d (error=%i)\n", - dev->video_mode.alt, errCode); + pr_err("cannot change alt number to %d (error=%i)\n", + dev->video_mode.alt, errCode); return errCode; } } @@ -600,9 +598,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) } if (alt > 0 && max_pkt_size == 0) { - pr_err - ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", - usb_interface_index, alt); + pr_err("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", + usb_interface_index, alt); /*To workaround error number=-71 on EP0 for videograbber, need add following codes.*/ if (dev->board.no_alt_vanc) @@ -616,9 +613,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) if (usb_interface_index > 0) { status = usb_set_interface(dev->udev, usb_interface_index, alt); if (status < 0) { - pr_err - ("can't change interface %d alt no. to %d (err=%i)\n", - usb_interface_index, alt, status); + pr_err("can't change interface %d alt no. to %d (err=%i)\n", + usb_interface_index, alt, status); return status; } } @@ -767,17 +763,15 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) u32 *buffer; buffer = kzalloc(4096, GFP_KERNEL); - if (buffer == NULL) { - pr_info("out of mem\n"); + if (buffer == NULL) return -ENOMEM; - } memcpy(&buffer[0], firmware, 4096); ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5), buffer, 4096, &actlen, 2000); if (ret) - pr_info("bulk message failed: %d (%d/%d)", ret, + pr_err("bulk message failed: %d (%d/%d)", ret, size, actlen); else { errCode = actlen != size ? -1 : 0; @@ -987,12 +981,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, cx231xx_uninit_isoc(dev); dma_q->p_left_data = kzalloc(4096, GFP_KERNEL); - if (dma_q->p_left_data == NULL) { - pr_info("out of mem\n"); + if (dma_q->p_left_data == NULL) return -ENOMEM; - } - - dev->video_mode.isoc_ctl.isoc_copy = isoc_copy; dev->video_mode.isoc_ctl.num_bufs = num_bufs; @@ -1055,10 +1045,9 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_isoc(dev); return -ENOMEM; } @@ -1091,7 +1080,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, GFP_ATOMIC); if (rc) { pr_err("submit of urb %i failed (error=%i)\n", i, - rc); + rc); cx231xx_uninit_isoc(dev); return rc; } @@ -1189,10 +1178,9 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_bulk(dev); return -ENOMEM; } @@ -1212,8 +1200,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, - rc); + pr_err("submit of urb %i failed (error=%i)\n", i,rc); cx231xx_uninit_bulk(dev); return rc; } @@ -1316,18 +1303,16 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (errCode < 0) { - pr_err - ("%s: Failed to set Power - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: Failed to set Power - errCode [%d]!\n", + __func__, errCode); return errCode; } } else { errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (errCode < 0) { - pr_err - ("%s: Failed to set Power - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: Failed to set Power - errCode [%d]!\n", + __func__, errCode); return errCode; } } @@ -1340,34 +1325,30 @@ int cx231xx_dev_init(struct cx231xx *dev) /* initialize Colibri block */ errCode = cx231xx_afe_init_super_block(dev, 0x23c); if (errCode < 0) { - pr_err - ("%s: cx231xx_afe init super block - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: cx231xx_afe init super block - errCode [%d]!\n", + __func__, errCode); return errCode; } errCode = cx231xx_afe_init_channels(dev); if (errCode < 0) { - pr_err - ("%s: cx231xx_afe init channels - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: cx231xx_afe init channels - errCode [%d]!\n", + __func__, errCode); return errCode; } /* Set DIF in By pass mode */ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (errCode < 0) { - pr_err - ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", + __func__, errCode); return errCode; } /* I2S block related functions */ errCode = cx231xx_i2s_blk_initialize(dev); if (errCode < 0) { - pr_err - ("%s: cx231xx_i2s block initialize - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: cx231xx_i2s block initialize - errCode [%d]!\n", + __func__, errCode); return errCode; } @@ -1375,7 +1356,7 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_init_ctrl_pin_status(dev); if (errCode < 0) { pr_err("%s: cx231xx_init ctrl pins - errCode [%d]!\n", - __func__, errCode); + __func__, errCode); return errCode; } @@ -1400,9 +1381,8 @@ int cx231xx_dev_init(struct cx231xx *dev) break; } if (errCode < 0) { - pr_err - ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", - __func__, errCode); + pr_err("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", + __func__, errCode); return errCode; } @@ -1477,9 +1457,8 @@ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - pr_info - ("UsbInterface::sendCommand, failed with status -%d\n", - status); + pr_err("%s: failed with status -%d\n", + __func__, status); } return status; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index a743865b40c0..b6af923eb5a3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -265,7 +265,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) struct cx231xx *dev = dvb->adapter.priv; if (dev->USE_ISO) { - pr_info("DVB transfer mode is ISO.\n"); + pr_debug("DVB transfer mode is ISO.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -276,7 +276,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) dev->ts1_mode.max_pkt_size, dvb_isoc_copy); } else { - pr_info("DVB transfer mode is BULK.\n"); + pr_debug("DVB transfer mode is BULK.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 0); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -430,16 +430,14 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) if (dops->init != NULL && !dev->xc_fw_load_done) { - pr_info("Reloading firmware for XC5000\n"); + pr_debug("Reloading firmware for XC5000\n"); status = dops->init(dev->dvb->frontend); if (status == 0) { dev->xc_fw_load_done = 1; - pr_info - ("XC5000 firmware download completed\n"); + pr_debug("XC5000 firmware download completed\n"); } else { dev->xc_fw_load_done = 0; - pr_info - ("XC5000 firmware download failed !!!\n"); + pr_debug("XC5000 firmware download failed !!!\n"); } } diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index d4a468a60bd0..1a0d9efeb209 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -498,17 +498,18 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); - pr_info(": Checking for I2C devices on port=%d ..\n", i2c_port); + pr_info("i2c_scan: checking for I2C devices on port=%d ..\n", + i2c_port); for (i = 0; i < 128; i++) { client.addr = i; rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; - pr_info("%s: i2c scan: found device @ 0x%x [%s]\n", - dev->name, i << 1, - i2c_devs[i] ? i2c_devs[i] : "???"); + pr_info("i2c scan: found device @ 0x%x [%s]\n", + i << 1, + i2c_devs[i] ? i2c_devs[i] : "???"); } - pr_info(": Completed Checking for I2C devices on port=%d.\n", + pr_info("i2c scan: Completed Checking for I2C devices on port=%d.\n", i2c_port); } @@ -532,8 +533,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_add_adapter(&bus->i2c_adap); if (0 != bus->i2c_rc) - pr_warn("%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); + pr_warn("i2c bus %d register FAILED\n", bus->nr); return bus->i2c_rc; } @@ -576,8 +576,7 @@ int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) NULL); if (!dev->i2c_mux_adap[mux_no]) - pr_warn("%s: i2c mux %d register FAILED\n", - dev->name, mux_no); + pr_warn("i2c mux %d register FAILED\n", mux_no); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index 4666e533fe0a..2f8dc6afac54 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -703,9 +703,9 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY; break; default: - pr_info("bad config in buspower!!!!\n"); - pr_info("config_info=%x\n", - (config_info & BUSPOWER_MASK)); + pr_err("bad config in buspower!!!!\n"); + pr_err("config_info=%x\n", + config_info & BUSPOWER_MASK); return 1; } } else { /* self-power */ @@ -768,9 +768,9 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR; break; default: - pr_info("bad senario!!!!!\n"); - pr_info("config_info=%x\n", - (config_info & SELFPOWER_MASK)); + pr_err("bad senario!!!!!\n"); + pr_err("config_info=%x\n", + config_info & SELFPOWER_MASK); return -ENODEV; } } diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index f80126d3525a..14e1eb7f2128 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -69,11 +69,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - pr_err("URB status %d [%s].\n", status, - errmsg); + pr_err("URB status %d [%s].\n", status, errmsg); } else { pr_err("URB packet %d, status %d [%s].\n", - packet, status, errmsg); + packet, status, errmsg); } } @@ -317,7 +316,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) return; default: /* error */ pr_err("urb completition error %d.\n", - urb->status); + urb->status); break; } @@ -332,7 +331,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { pr_err("urb resubmit failed (error=%i)\n", - urb->status); + urb->status); } } @@ -344,7 +343,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - pr_info("called cx231xx_uninit_vbi_isoc\n"); + pr_debug("called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -393,7 +392,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - pr_info("called cx231xx_vbi_isoc\n"); + pr_debug("called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -451,9 +450,9 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", sb_size, i, - in_interrupt() ? " while in int" : ""); + pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -470,8 +469,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, - rc); + pr_err("submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; } @@ -522,7 +520,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* pr_info("[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* pr_debug("[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index bda5597b5eff..4d1d750ab38d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -737,7 +737,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*pr_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", + /*pr_debug("urb_init=%d dev->video_mode.max_pkt_size=%d\n", urb_init, dev->video_mode.max_pkt_size);*/ if (urb_init) { dev->mode_tv = 0; @@ -809,7 +809,7 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_set_audio_input(dev, dev->ctl_ainput); - pr_info("video_mux : %d\n", index); + pr_debug("video_mux : %d\n", index); /* do mode control overrides if required */ cx231xx_do_mode_ctrl_overrides(dev); @@ -953,12 +953,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; if (videobuf_queue_is_busy(&fh->vb_vidq)) { - pr_err("%s queue busy\n", __func__); + pr_err("%s: queue busy\n", __func__); return -EBUSY; } if (dev->stream_on && !fh->stream_on) { - pr_err("%s device in use by another fh\n", __func__); + pr_err("%s: device in use by another fh\n", __func__); return -EBUSY; } @@ -1176,9 +1176,8 @@ int cx231xx_s_frequency(struct file *file, void *priv, int rc; u32 if_frequency = 5400000; - pr_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", + pr_debug("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", f->frequency, f->type); - /*pr_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/ rc = check_dev(dev); if (rc < 0) @@ -1213,13 +1212,13 @@ int cx231xx_s_frequency(struct file *file, void *priv, else if (dev->norm & V4L2_STD_SECAM_LC) if_frequency = 1250000; /*1.25MHz */ - pr_info("if_frequency is set to %d\n", if_frequency); + pr_debug("if_frequency is set to %d\n", if_frequency); cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); update_HH_register_after_set_DIF(dev); } - pr_info("Set New FREQUENCY to %d\n", f->frequency); + pr_debug("Set New FREQUENCY to %d\n", f->frequency); return rc; } @@ -1642,8 +1641,7 @@ static int cx231xx_v4l2_open(struct file *filp) #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); if (errCode < 0) { - pr_err - ("Device locked on digital mode. Can't open analog\n"); + pr_err("Device locked on digital mode. Can't open analog\n"); return -EBUSY; } #endif @@ -1737,7 +1735,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) } if (dev->vbi_dev) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(dev->vbi_dev)); + video_device_node_name(dev->vbi_dev)); if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else @@ -1746,7 +1744,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) } if (dev->vdev) { pr_info("V4L2 device %s deregistered\n", - video_device_node_name(dev->vdev)); + video_device_node_name(dev->vdev)); if (dev->board.has_417) cx231xx_417_unregister(dev); @@ -2080,8 +2078,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) { int ret; - pr_info("%s: v4l2 driver version %s\n", - dev->name, CX231XX_VERSION); + pr_info("v4l2 driver version %s\n", CX231XX_VERSION); /* set default norm */ dev->norm = V4L2_STD_PAL; @@ -2129,12 +2126,12 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) video_nr[dev->devno]); if (ret) { pr_err("unable to register video device (error=%i).\n", - ret); + ret); return ret; } - pr_info("%s/0: registered device %s [v4l2]\n", - dev->name, video_device_node_name(dev->vdev)); + pr_info("Registered video device %s [v4l2]\n", + video_device_node_name(dev->vdev)); /* Initialize VBI template */ cx231xx_vbi_template = cx231xx_video_template; @@ -2156,8 +2153,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) return ret; } - pr_info("%s/0: registered device %s\n", - dev->name, video_device_node_name(dev->vbi_dev)); + pr_info("Registered VBI device %s\n", + video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, @@ -2174,12 +2171,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) return ret; } pr_info("Registered radio device as %s\n", - video_device_node_name(dev->radio_dev)); + video_device_node_name(dev->radio_dev)); } - pr_info("V4L2 device registered as %s and %s\n", - video_device_node_name(dev->vdev), - video_device_node_name(dev->vbi_dev)); - return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index fa27e0c2accb..aeee721a8eef 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -809,7 +809,6 @@ void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev); void reset_s5h1432_demod(struct cx231xx *dev); void cx231xx_dump_HH_reg(struct cx231xx *dev); void update_HH_register_after_set_DIF(struct cx231xx *dev); -void cx231xx_dump_SC_reg(struct cx231xx *dev); -- GitLab From a7119f8629fbdb100a383b7351e1bd85274d8093 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 09:11:20 -0300 Subject: [PATCH 2669/9457] [media] cx25840: Don't report an error if max size is adjusted There's no reason to report: cx25840 7-0044: Firmware download size changed to 16 bytes max length If the driver needs to adjust the buffer's maximum size. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/cx25840/cx25840-firmware.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/cx25840/cx25840-firmware.c b/drivers/media/i2c/cx25840/cx25840-firmware.c index b3169f94ece8..6092bf71300f 100644 --- a/drivers/media/i2c/cx25840/cx25840-firmware.c +++ b/drivers/media/i2c/cx25840/cx25840-firmware.c @@ -122,10 +122,9 @@ int cx25840_loadfw(struct i2c_client *client) gpio_da = cx25840_read(client, 0x164); } - if (is_cx231xx(state) && MAX_BUF_SIZE > 16) { - v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); - MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ - } + /* cx231xx cannot accept more than 16 bytes at a time */ + if (is_cx231xx(state) && MAX_BUF_SIZE > 16) + MAX_BUF_SIZE = 16; if (request_firmware(&fw, fwname, FWDEV(client)) != 0) { v4l_err(client, "unable to open firmware %s\n", fwname); -- GitLab From 6ac825cb3e64c4831d9efa93d3497b104c42c84e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 09:12:58 -0300 Subject: [PATCH 2670/9457] [media] cx25840: convert max_buf_size var to lowercase CodingStyle fix: vars should be in lowercase. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/cx25840/cx25840-firmware.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/cx25840/cx25840-firmware.c b/drivers/media/i2c/cx25840/cx25840-firmware.c index 6092bf71300f..9bbb31adc29d 100644 --- a/drivers/media/i2c/cx25840/cx25840-firmware.c +++ b/drivers/media/i2c/cx25840/cx25840-firmware.c @@ -113,7 +113,7 @@ int cx25840_loadfw(struct i2c_client *client) const u8 *ptr; const char *fwname = get_fw_name(client); int size, retval; - int MAX_BUF_SIZE = FWSEND; + int max_buf_size = FWSEND; u32 gpio_oe = 0, gpio_da = 0; if (is_cx2388x(state)) { @@ -123,8 +123,8 @@ int cx25840_loadfw(struct i2c_client *client) } /* cx231xx cannot accept more than 16 bytes at a time */ - if (is_cx231xx(state) && MAX_BUF_SIZE > 16) - MAX_BUF_SIZE = 16; + if (is_cx231xx(state) && max_buf_size > 16) + max_buf_size = 16; if (request_firmware(&fw, fwname, FWDEV(client)) != 0) { v4l_err(client, "unable to open firmware %s\n", fwname); @@ -139,7 +139,7 @@ int cx25840_loadfw(struct i2c_client *client) size = fw->size; ptr = fw->data; while (size > 0) { - int len = min(MAX_BUF_SIZE - 2, size); + int len = min(max_buf_size - 2, size); memcpy(buffer + 2, ptr, len); -- GitLab From 0d88d0916b988d37edac35407688bc4b009c916b Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Sat, 1 Nov 2014 17:19:21 -0300 Subject: [PATCH 2671/9457] [media] cx231xx: use 1 byte read for i2c scan Now cx231xx_i2c_check_for_device works like i2c_check_for_device of em28xx driver. For me this fixes scanning of all ports but port 2. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 1a0d9efeb209..5a0604711be0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -350,14 +350,15 @@ static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, struct cx231xx *dev = bus->dev; struct cx231xx_i2c_xfer_data req_data; int status = 0; + u8 buf[1]; /* prepare xfer_data struct */ req_data.dev_addr = msg->addr; - req_data.direction = msg->flags; + req_data.direction = I2C_M_RD; req_data.saddr_len = 0; req_data.saddr_dat = 0; - req_data.buf_size = 0; - req_data.p_buffer = NULL; + req_data.buf_size = 1; + req_data.p_buffer = buf; /* usb send command */ status = dev->cx231xx_send_usb_command(bus, &req_data); -- GitLab From 77e97ba2da47fe75bb9a835bb43a29e046c60f99 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 1 Nov 2014 10:06:12 -0300 Subject: [PATCH 2672/9457] [media] cx231xx: disable I2C errors during i2c_scan Otherwise, it would produce lots of useless messages like: cx231xx: cx231xx_send_usb_command: failed with status --32 After this patch, I2C scan will produce an useful report: [ 9494.050807] cx231xx: i2c_scan: checking for I2C devices on port=0 .. [ 9494.074928] cx231xx: i2c scan: Completed Checking for I2C devices on port=0. [ 9494.074936] cx231xx: i2c_scan: checking for I2C devices on port=3 .. [ 9494.098934] cx231xx: i2c scan: Completed Checking for I2C devices on port=3. [ 9494.098942] cx231xx: i2c_scan: checking for I2C devices on port=2 .. [ 9494.118440] cx231xx: i2c scan: Completed Checking for I2C devices on port=2. [ 9494.118448] cx231xx: i2c_scan: checking for I2C devices on port=4 .. [ 9494.141889] cx231xx: i2c scan: Completed Checking for I2C devices on port=4. [ 9494.060182] cx231xx: i2c scan: found device @ 0x40 [???] [ 9494.062953] cx231xx: i2c scan: found device @ 0x60 [colibri] [ 9494.066071] cx231xx: i2c scan: found device @ 0x88 [hammerhead] [ 9494.067383] cx231xx: i2c scan: found device @ 0x98 [???] [ 9494.090113] cx231xx: i2c scan: found device @ 0xa0 [eeprom] [ 9494.106463] cx231xx: i2c scan: found device @ 0x60 [colibri] [ 9494.113762] cx231xx: i2c scan: found device @ 0xc0 [tuner] [ 9494.121882] cx231xx: i2c scan: found device @ 0x20 [???] Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-core.c | 2 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 5 +++++ drivers/media/usb/cx231xx/cx231xx.h | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index c5842a1ea104..66e8f8ae9be4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -227,7 +227,7 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); - if (status < 0) { + if (status < 0 && !dev->i2c_scan_running) { pr_err("%s: failed with status -%d\n", __func__, status); } diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 5a0604711be0..f99857e6c842 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -496,6 +496,9 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) if (!i2c_scan) return; + /* Don't generate I2C errors during scan */ + dev->i2c_scan_running = true; + memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); @@ -512,6 +515,8 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) } pr_info("i2c scan: Completed Checking for I2C devices on port=%d.\n", i2c_port); + + dev->i2c_scan_running = false; } /* diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index aeee721a8eef..253f2437c0f1 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -610,6 +610,8 @@ struct cx231xx { unsigned int has_audio_class:1; unsigned int has_alsa_audio:1; + unsigned int i2c_scan_running:1; /* true only during i2c_scan */ + struct cx231xx_fmt *format; struct v4l2_device v4l2_dev; -- GitLab From b7085c08647598aafbf8f6223ebcdd413745449c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 07:21:44 -0300 Subject: [PATCH 2673/9457] [media] cx231xx: convert from pr_foo to dev_foo Replace all pr_foo occurrences by dev_foo, as this is the recommended way for drivers. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 38 ++-- drivers/media/usb/cx231xx/cx231xx-audio.c | 44 ++-- drivers/media/usb/cx231xx/cx231xx-avcore.c | 213 +++++++++++--------- drivers/media/usb/cx231xx/cx231xx-cards.c | 125 +++++++----- drivers/media/usb/cx231xx/cx231xx-core.c | 73 ++++--- drivers/media/usb/cx231xx/cx231xx-dvb.c | 14 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 19 +- drivers/media/usb/cx231xx/cx231xx-input.c | 1 - drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | 43 ++-- drivers/media/usb/cx231xx/cx231xx-vbi.c | 36 ++-- drivers/media/usb/cx231xx/cx231xx-video.c | 62 +++--- drivers/media/usb/cx231xx/cx231xx.h | 3 +- 12 files changed, 395 insertions(+), 276 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index a0d1156d1df1..0773da4dc29b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -39,7 +39,6 @@ #include #include #include -#include #define CX231xx_FIRM_IMAGE_SIZE 376836 #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -988,7 +987,8 @@ static int cx231xx_load_firmware(struct cx231xx *dev) IVTV_REG_APU, 0); if (retval != 0) { - pr_err("%s: Error with mc417_register_write\n", __func__); + dev_err(&dev->udev->dev, + "%s: Error with mc417_register_write\n", __func__); return -1; } @@ -996,21 +996,25 @@ static int cx231xx_load_firmware(struct cx231xx *dev) &dev->udev->dev); if (retval != 0) { - pr_err("ERROR: Hotplug firmware request failed (%s).\n", + dev_err(&dev->udev->dev, + "ERROR: Hotplug firmware request failed (%s).\n", CX231xx_FIRM_IMAGE_NAME); - pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + dev_err(&dev->udev->dev, + "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { - pr_err("ERROR: Firmware size mismatch (have %zd, expected %d)\n", + dev_err(&dev->udev->dev, + "ERROR: Firmware size mismatch (have %zd, expected %d)\n", firmware->size, CX231xx_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; } if (0 != memcmp(firmware->data, magic, 8)) { - pr_err("ERROR: Firmware magic mismatch, wrong file?\n"); + dev_err(&dev->udev->dev, + "ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -1; } @@ -1057,7 +1061,8 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); if (retval < 0) { - pr_err("%s: Error with mc417_register_write\n", + dev_err(&dev->udev->dev, + "%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1069,7 +1074,8 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); if (retval < 0) { - pr_err("%s: Error with mc417_register_write\n", + dev_err(&dev->udev->dev, + "%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1117,25 +1123,28 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) dprintk(2, "%s: PING OK\n", __func__); retval = cx231xx_load_firmware(dev); if (retval < 0) { - pr_err("%s: f/w load failed\n", __func__); + dev_err(&dev->udev->dev, + "%s: f/w load failed\n", __func__); return retval; } retval = cx231xx_find_mailbox(dev); if (retval < 0) { - pr_err("%s: mailbox < 0, error\n", + dev_err(&dev->udev->dev, "%s: mailbox < 0, error\n", __func__); return -1; } dev->cx23417_mailbox = retval; retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { - pr_err("ERROR: cx23417 firmware ping failed!\n"); + dev_err(&dev->udev->dev, + "ERROR: cx23417 firmware ping failed!\n"); return -1; } retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - pr_err("ERROR: cx23417 firmware get encoder: version failed!\n"); + dev_err(&dev->udev->dev, + "ERROR: cx23417 firmware get encoder: version failed!\n"); return -1; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); @@ -1416,8 +1425,9 @@ static int bb_buf_prepare(struct videobuf_queue *q, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*pr_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size);*/ + dev_dbg(&dev->udev->dev, + "urb_init=%d dev->video_mode.max_pkt_size=%d\n", + urb_init, dev->video_mode.max_pkt_size); dev->mode_tv = 1; if (urb_init) { diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index e96703180c0c..1c3f68179fc9 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -22,7 +22,6 @@ #include "cx231xx.h" #include -#include #include #include #include @@ -182,8 +181,9 @@ static void cx231xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - pr_err("resubmit of audio urb failed (error=%i)\n", - status); + dev_err(&dev->udev->dev, + "resubmit of audio urb failed (error=%i)\n", + status); } return; } @@ -266,8 +266,9 @@ static void cx231xx_audio_bulkirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - pr_err("resubmit of audio urb failed (error=%i)\n", - status); + dev_err(&dev->udev->dev, + "resubmit of audio urb failed (error=%i)\n", + status); } return; } @@ -277,7 +278,8 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) int i, errCode; int sb_size; - pr_debug("%s: Starting ISO AUDIO transfers\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: Starting ISO AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -295,7 +297,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - pr_err("usb_alloc_urb failed!\n"); + dev_err(&dev->udev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -338,7 +340,8 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) int i, errCode; int sb_size; - pr_debug("%s: Starting BULK AUDIO transfers\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: Starting BULK AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -356,7 +359,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - pr_err("usb_alloc_urb failed!\n"); + dev_err(&dev->udev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -439,12 +442,14 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); if (!dev) { - pr_err("BUG: cx231xx can't find device struct. Can't proceed with open\n"); + dev_err(&dev->udev->dev, + "BUG: cx231xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } if (dev->state & DEV_DISCONNECTED) { - pr_err("Can't open. the device was removed.\n"); + dev_err(&dev->udev->dev, + "Can't open. the device was removed.\n"); return -ENODEV; } @@ -457,7 +462,8 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); mutex_unlock(&dev->lock); if (ret < 0) { - pr_err("failed to set alternate setting !\n"); + dev_err(&dev->udev->dev, + "failed to set alternate setting !\n"); return ret; } @@ -493,7 +499,8 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); if (ret < 0) { - pr_err("failed to set alternate setting !\n"); + dev_err(&dev->udev->dev, + "failed to set alternate setting !\n"); mutex_unlock(&dev->lock); return ret; @@ -661,7 +668,8 @@ static int cx231xx_audio_init(struct cx231xx *dev) return 0; } - pr_debug("probing for cx231xx non standard usbaudio\n"); + dev_dbg(&dev->udev->dev, + "probing for cx231xx non standard usbaudio\n"); err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio", THIS_MODULE, 0, &card); @@ -705,7 +713,8 @@ static int cx231xx_audio_init(struct cx231xx *dev) bEndpointAddress; adev->num_alt = uif->num_altsetting; - pr_info("audio EndPoint Addr 0x%x, Alternate settings: %i\n", + dev_info(&dev->udev->dev, + "audio EndPoint Addr 0x%x, Alternate settings: %i\n", adev->end_point_addr, adev->num_alt); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); @@ -718,8 +727,9 @@ static int cx231xx_audio_init(struct cx231xx *dev) wMaxPacketSize); adev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_debug("audio alternate setting %i, max size= %i\n", i, - adev->alt_max_pkt_size[i]); + dev_dbg(&dev->udev->dev, + "audio alternate setting %i, max size= %i\n", i, + adev->alt_max_pkt_size[i]); } return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 62c63b9e2291..9088a32db2d1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -83,10 +82,10 @@ void initGPIO(struct cx231xx *dev) cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); verve_read_byte(dev, 0x07, &val); - pr_debug("verve_read_byte address0x07=0x%x\n", val); + dev_dbg(&dev->udev->dev, "verve_read_byte address0x07=0x%x\n", val); verve_write_byte(dev, 0x07, 0xF4); verve_read_byte(dev, 0x07, &val); - pr_debug("verve_read_byte address0x07=0x%x\n", val); + dev_dbg(&dev->udev->dev, "verve_read_byte address0x07=0x%x\n", val); cx231xx_capture_start(dev, 1, Vbi); @@ -156,7 +155,8 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) while (afe_power_status != 0x18) { status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18); if (status < 0) { - pr_debug("%s: Init Super Block failed in send cmd\n", + dev_dbg(&dev->udev->dev, + "%s: Init Super Block failed in send cmd\n", __func__); break; } @@ -164,13 +164,15 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status); afe_power_status &= 0xff; if (status < 0) { - pr_debug("%s: Init Super Block failed in receive cmd\n", + dev_dbg(&dev->udev->dev, + "%s: Init Super Block failed in receive cmd\n", __func__); break; } i++; if (i == 10) { - pr_debug("%s: Init Super Block force break in loop !!!!\n", + dev_dbg(&dev->udev->dev, + "%s: Init Super Block force break in loop !!!!\n", __func__); status = -1; break; @@ -410,7 +412,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00); } else { - pr_debug("Invalid AV mode input\n"); + dev_dbg(&dev->udev->dev, "Invalid AV mode input\n"); status = -1; } break; @@ -467,7 +469,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x40); } else { - pr_debug("Invalid AV mode input\n"); + dev_dbg(&dev->udev->dev, "Invalid AV mode input\n"); status = -1; } } /* switch */ @@ -573,9 +575,9 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (status < 0) { - pr_err("%s: set_power_mode : Failed to" - " set Power - errCode [%d]!\n", - __func__, status); + dev_err(&dev->udev->dev, + "%s: Failed to set Power - errCode [%d]!\n", + __func__, status); return status; } } @@ -591,8 +593,8 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (status < 0) { - pr_err("%s: set_power_mode:Failed" - " to set Power - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: Failed to set Power - errCode [%d]!\n", __func__, status); return status; } @@ -608,8 +610,8 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) break; default: - pr_err("%s: set_power_mode : Unknown Input %d !\n", - __func__, INPUT(input)->type); + dev_err(&dev->udev->dev, "%s: Unknown Input %d !\n", + __func__, INPUT(input)->type); break; } @@ -628,7 +630,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, if (pin_type != dev->video_input) { status = cx231xx_afe_adjust_ref_count(dev, pin_type); if (status < 0) { - pr_err("%s: adjust_ref_count :Failed to set AFE input mux - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: adjust_ref_count :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; } @@ -637,7 +640,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* call afe block to set video inputs */ status = cx231xx_afe_set_input_mux(dev, input); if (status < 0) { - pr_err("%s: set_input_mux :Failed to set AFE input mux - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: set_input_mux :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; } @@ -668,7 +672,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -712,7 +717,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -786,7 +792,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -821,7 +828,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Reinitialize the DIF */ status = cx231xx_dif_set_standard(dev, dev->norm); if (status < 0) { - pr_err("%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -964,14 +972,14 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) { int status = 0; - pr_debug("%s: 0x%x\n", + dev_dbg(&dev->udev->dev, "%s: 0x%x\n", __func__, (unsigned int)dev->norm); /* Change the DFE_CTRL3 bp_percent to fix flagging */ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280); if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { - pr_debug("%s: NTSC\n", __func__); + dev_dbg(&dev->udev->dev, "%s: NTSC\n", __func__); /* Move the close caption lines out of active video, adjust the active video start point */ @@ -998,7 +1006,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) (FLD_HBLANK_CNT, 0x79)); } else if (dev->norm & V4L2_STD_SECAM) { - pr_debug("%s: SECAM\n", __func__); + dev_dbg(&dev->udev->dev, "%s: SECAM\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1025,7 +1033,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) cx231xx_set_field (FLD_HBLANK_CNT, 0x85)); } else { - pr_debug("%s: PAL\n", __func__); + dev_dbg(&dev->udev->dev, "%s: PAL\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1325,111 +1333,129 @@ void cx231xx_dump_HH_reg(struct cx231xx *dev) for (i = 0x100; i < 0x140; i++) { vid_blk_read_word(dev, i, &value); - pr_debug("reg0x%x=0x%x\n", i, value); + dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x300; i < 0x400; i++) { vid_blk_read_word(dev, i, &value); - pr_debug("reg0x%x=0x%x\n", i, value); + dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x400; i < 0x440; i++) { vid_blk_read_word(dev, i, &value); - pr_debug("reg0x%x=0x%x\n", i, value); + dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - pr_debug("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(&dev->udev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - pr_debug("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(&dev->udev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); } #if 0 static void cx231xx_dump_SC_reg(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - pr_debug("%s!\n", __func__); + dev_dbg(&dev->udev->dev, "%s!\n", __func__); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); - pr_debug("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], - value[1], value[2], value[3]); + dev_dbg(&dev->udev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], + value[1], value[2], value[3]); } #endif @@ -1497,7 +1523,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, u32 standard = 0; u8 value[4] = { 0, 0, 0, 0 }; - pr_debug("Enter cx231xx_set_Colibri_For_LowIF()\n"); + dev_dbg(&dev->udev->dev, "Enter cx231xx_set_Colibri_For_LowIF()\n"); value[0] = (u8) 0x6F; value[1] = (u8) 0x6F; value[2] = (u8) 0x6F; @@ -1517,7 +1543,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, standard); - pr_debug("colibri_carrier_offset=%d, standard=0x%x\n", + dev_dbg(&dev->udev->dev, "colibri_carrier_offset=%d, standard=0x%x\n", colibri_carrier_offset, standard); /* Set the band Pass filter for DIF*/ @@ -1551,8 +1577,8 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, u64 pll_freq_u64 = 0; u32 i = 0; - pr_debug("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", - if_freq, spectral_invert, mode); + dev_dbg(&dev->udev->dev, "if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", + if_freq, spectral_invert, mode); if (mode == TUNER_MODE_FM_RADIO) { @@ -1595,8 +1621,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, if_freq = 16000000; } - pr_debug("Enter IF=%zu\n", - ARRAY_SIZE(Dif_set_array)); + dev_dbg(&dev->udev->dev, "Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) { if (Dif_set_array[i].if_freq == if_freq) { vid_blk_write_word(dev, @@ -1708,7 +1733,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) u32 dif_misc_ctrl_value = 0; u32 func_mode = 0; - pr_debug("%s: setStandard to %x\n", __func__, standard); + dev_dbg(&dev->udev->dev, "%s: setStandard to %x\n", __func__, standard); status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value); if (standard != DIF_USE_BASEBAND) @@ -2111,8 +2136,8 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) { int status = 0; u32 dwval; - pr_debug("%s: dev->tuner_type =0%d\n", - __func__, dev->tuner_type); + dev_dbg(&dev->udev->dev, "%s: dev->tuner_type =0%d\n", + __func__, dev->tuner_type); /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for * SECAM L/B/D standards */ status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval); @@ -2213,7 +2238,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (dev->power_mode != mode) dev->power_mode = mode; else { - pr_debug("%s: mode = %d, No Change req.\n", + dev_dbg(&dev->udev->dev, "%s: mode = %d, No Change req.\n", __func__, mode); return 0; } @@ -2453,7 +2478,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - pr_debug("%s: ep_mask = %x\n", __func__, ep_mask); + dev_dbg(&dev->udev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2478,7 +2503,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - pr_debug("%s: ep_mask = %x\n", __func__, ep_mask); + dev_dbg(&dev->udev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2506,32 +2531,38 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { case Audio: - pr_debug("%s: Audio enter HANC\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; case Vbi: - pr_debug("%s: set vanc registers\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; case Sliced_cc: - pr_debug("%s: set hanc registers\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; case Raw_Video: - pr_debug("%s: set video registers\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; case TS1_serial_mode: - pr_debug("%s: set ts1 registers", __func__); + dev_dbg(&dev->udev->dev, + "%s: set ts1 registers", __func__); if (dev->board.has_417) { - pr_debug("%s: MPEG\n", __func__); + dev_dbg(&dev->udev->dev, + "%s: MPEG\n", __func__); value &= 0xFFFFFFFC; value |= 0x3; @@ -2554,7 +2585,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) VRT_SET_REGISTER, TS1_LENGTH_REG, val, 4); } else { - pr_debug("%s: BDA\n", __func__); + dev_dbg(&dev->udev->dev, "%s: BDA\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); status = cx231xx_mode_register(dev, @@ -2563,8 +2594,9 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) break; case TS1_parallel_mode: - pr_debug("%s: set ts1 parallel mode registers\n", - __func__); + dev_dbg(&dev->udev->dev, + "%s: set ts1 parallel mode registers\n", + __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); break; @@ -2917,8 +2949,9 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) (nCnt > 0)); if (nCnt == 0) - pr_debug("No ACK after %d msec -GPIO I2C failed!", - nInit * 10); + dev_dbg(&dev->udev->dev, + "No ACK after %d msec -GPIO I2C failed!", + nInit * 10); /* * readAck diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index d59f483102d2..2e8741314bce 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -856,8 +855,9 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) if (dev->tuner_type == TUNER_XC5000) { if (command == XC5000_TUNER_RESET) { - pr_debug("Tuner CB: RESET: cmd %d : tuner type %d \n", - command, dev->tuner_type); + dev_dbg(&dev->udev->dev, + "Tuner CB: RESET: cmd %d : tuner type %d\n", + command, dev->tuner_type); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); msleep(10); @@ -915,7 +915,7 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) cx231xx_set_model(dev); - pr_info("Identified as %s (card=%d)\n", + dev_info(&dev->udev->dev, "Identified as %s (card=%d)\n", dev->board.name, dev->model); /* set the direction for GPIO pins */ @@ -989,7 +989,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, /* start reading at offset 0 */ ret = i2c_transfer(client->adapter, &msg_write, 1); if (ret < 0) { - pr_err("Can't read eeprom\n"); + dev_err(&dev->udev->dev, "Can't read eeprom\n"); return ret; } @@ -999,7 +999,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, ret = i2c_transfer(client->adapter, &msg_read, 1); if (ret < 0) { - pr_err("Can't read eeprom\n"); + dev_err(&dev->udev->dev, "Can't read eeprom\n"); return ret; } eedata_cur += msg_read.len; @@ -1007,7 +1007,8 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, } for (i = 0; i + 15 < len; i += 16) - pr_debug("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); + dev_dbg(&dev->udev->dev, "i2c eeprom %02x: %*ph\n", + i, 16, &eedata[i]); return 0; } @@ -1027,7 +1028,8 @@ void cx231xx_card_setup(struct cx231xx *dev) cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) - pr_err("cx25840 subdev registration failure\n"); + dev_err(&dev->udev->dev, + "cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); } @@ -1041,7 +1043,8 @@ void cx231xx_card_setup(struct cx231xx *dev) "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) - pr_err("tuner subdev registration failure\n"); + dev_err(&dev->udev->dev, + "tuner subdev registration failure\n"); else cx231xx_config_tuner(dev); } @@ -1147,7 +1150,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* Query cx231xx to find what pcb config it is related to */ retval = initialize_cx231xx(dev); if (retval < 0) { - pr_err("Failed to read PCB config\n"); + dev_err(&udev->dev, "Failed to read PCB config\n"); return retval; } @@ -1163,7 +1166,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - pr_err("error configuring device\n"); + dev_err(&udev->dev, "error configuring device\n"); return -ENOMEM; } @@ -1173,8 +1176,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* register i2c bus */ retval = cx231xx_dev_init(dev); if (retval) { - pr_err("%s: cx231xx_i2c_register - errCode [%d]!\n", - __func__, retval); + dev_err(&udev->dev, + "%s: cx231xx_i2c_register - errCode [%d]!\n", + __func__, retval); goto err_dev_init; } @@ -1195,7 +1199,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - pr_err("%s: cx231xx_config - errCode [%d]!\n", + dev_err(&udev->dev, "%s: cx231xx_config - errCode [%d]!\n", __func__, retval); goto err_dev_init; } @@ -1280,7 +1284,8 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for video */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; if (idx >= dev->max_iad_interface_count) { - pr_err("Video PCB interface #%d doesn't exist\n", idx); + dev_err(&dev->udev->dev, + "Video PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1289,9 +1294,10 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; - pr_info("video EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->video_mode.end_point_addr, - dev->video_mode.num_alt); + dev_info(&dev->udev->dev, + "video EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->video_mode.end_point_addr, + dev->video_mode.num_alt); dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); if (dev->video_mode.alt_max_pkt_size == NULL) @@ -1300,15 +1306,17 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, for (i = 0; i < dev->video_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_debug("Alternate setting %i, max size= %i\n", i, - dev->video_mode.alt_max_pkt_size[i]); + dev_dbg(&dev->udev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->video_mode.alt_max_pkt_size[i]); } /* VBI Init */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; if (idx >= dev->max_iad_interface_count) { - pr_err("VBI PCB interface #%d doesn't exist\n", idx); + dev_err(&dev->udev->dev, + "VBI PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1318,9 +1326,10 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; - pr_info("VBI EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->vbi_mode.end_point_addr, - dev->vbi_mode.num_alt); + dev_info(&dev->udev->dev, + "VBI EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->vbi_mode.end_point_addr, + dev->vbi_mode.num_alt); /* compute alternate max packet sizes for vbi */ dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); @@ -1333,8 +1342,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_debug("Alternate setting %i, max size= %i\n", i, - dev->vbi_mode.alt_max_pkt_size[i]); + dev_dbg(&dev->udev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->vbi_mode.alt_max_pkt_size[i]); } /* Sliced CC VBI init */ @@ -1342,7 +1352,8 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for sliced CC */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; if (idx >= dev->max_iad_interface_count) { - pr_err("Sliced CC PCB interface #%d doesn't exist\n", idx); + dev_err(&dev->udev->dev, + "Sliced CC PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1352,9 +1363,10 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; - pr_info("sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->sliced_cc_mode.end_point_addr, - dev->sliced_cc_mode.num_alt); + dev_info(&dev->udev->dev, + "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->sliced_cc_mode.end_point_addr, + dev->sliced_cc_mode.num_alt); dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) return -ENOMEM; @@ -1364,8 +1376,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->sliced_cc_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_debug("Alternate setting %i, max size= %i\n", i, - dev->sliced_cc_mode.alt_max_pkt_size[i]); + dev_dbg(&dev->udev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->sliced_cc_mode.alt_max_pkt_size[i]); } return 0; @@ -1389,6 +1402,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, struct usb_interface_assoc_descriptor *assoc_desc; ifnum = interface->altsetting[0].desc.bInterfaceNumber; + udev = usb_get_dev(interface_to_usbdev(interface)); /* * Interface number 0 - IR interface (handled by mceusb driver) @@ -1402,13 +1416,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); if (nr >= CX231XX_MAXBOARDS) { /* No free device slots */ - pr_err("Supports only %i devices.\n", CX231XX_MAXBOARDS); + dev_err(&udev->dev, + "Supports only %i devices.\n", + CX231XX_MAXBOARDS); return -ENOMEM; } } while (test_and_set_bit(nr, &cx231xx_devused)); - udev = usb_get_dev(interface_to_usbdev(interface)); - /* allocate memory for our device state and initialize it */ dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); if (dev == NULL) { @@ -1458,13 +1472,14 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - pr_info("New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", - udev->manufacturer ? udev->manufacturer : "", - udev->product ? udev->product : "", - speed, - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - dev->max_iad_interface_count); + dev_info(&udev->dev, + "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", + udev->manufacturer ? udev->manufacturer : "", + udev->product ? udev->product : "", + speed, + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + dev->max_iad_interface_count); /* increment interface count */ dev->interface_count++; @@ -1474,12 +1489,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, assoc_desc = udev->actconfig->intf_assoc[0]; if (assoc_desc->bFirstInterface != ifnum) { - pr_err("Not found matching IAD interface\n"); + dev_err(&udev->dev, "Not found matching IAD interface\n"); retval = -ENODEV; goto err_if; } - pr_debug("registering interface %d\n", ifnum); + dev_dbg(&udev->dev, "registering interface %d\n", ifnum); /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); @@ -1487,7 +1502,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* Create v4l2 device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { - pr_err("v4l2_device_register failed\n"); + dev_err(&udev->dev, "v4l2_device_register failed\n"); goto err_v4l2; } @@ -1504,7 +1519,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes for TS1 */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; if (idx >= dev->max_iad_interface_count) { - pr_err("TS1 PCB interface #%d doesn't exist\n", idx); + dev_err(&udev->dev, + "TS1 PCB interface #%d doesn't exist\n", idx); retval = -ENODEV; goto err_video_alt; } @@ -1515,9 +1531,10 @@ static int cx231xx_usb_probe(struct usb_interface *interface, desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; - pr_info("TS EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->ts1_mode.end_point_addr, - dev->ts1_mode.num_alt); + dev_info(&udev->dev, + "TS EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->ts1_mode.end_point_addr, + dev->ts1_mode.num_alt); dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); if (dev->ts1_mode.alt_max_pkt_size == NULL) { @@ -1531,8 +1548,9 @@ static int cx231xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->ts1_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - pr_debug("Alternate setting %i, max size= %i\n", i, - dev->ts1_mode.alt_max_pkt_size[i]); + dev_dbg(&udev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->ts1_mode.alt_max_pkt_size[i]); } } @@ -1596,8 +1614,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) wake_up_interruptible_all(&dev->open); if (dev->users) { - pr_warn("device %s is open! Deregistration and memory deallocation are deferred on close.\n", - video_device_node_name(dev->vdev)); + dev_warn(&dev->udev->dev, + "device %s is open! Deregistration and memory deallocation are deferred on close.\n", + video_device_node_name(dev->vdev)); /* Even having users, it is safe to remove the RC i2c driver */ cx231xx_ir_exit(dev); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 66e8f8ae9be4..36c3ecf204c1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -228,7 +227,7 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0 && !dev->i2c_scan_running) { - pr_err("%s: failed with status -%d\n", + dev_err(&dev->udev->dev, "%s: failed with status -%d\n", __func__, status); } @@ -523,7 +522,8 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); if (errCode < 0) { - pr_err("cannot change alt number to %d (error=%i)\n", + dev_err(&dev->udev->dev, + "cannot change alt number to %d (error=%i)\n", dev->video_mode.alt, errCode); return errCode; } @@ -598,7 +598,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) } if (alt > 0 && max_pkt_size == 0) { - pr_err("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", + dev_err(&dev->udev->dev, + "can't change interface %d alt no. to %d: Max. Pkt size = 0\n", usb_interface_index, alt); /*To workaround error number=-71 on EP0 for videograbber, need add following codes.*/ @@ -613,7 +614,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) if (usb_interface_index > 0) { status = usb_set_interface(dev->udev, usb_interface_index, alt); if (status < 0) { - pr_err("can't change interface %d alt no. to %d (err=%i)\n", + dev_err(&dev->udev->dev, + "can't change interface %d alt no. to %d (err=%i)\n", usb_interface_index, alt, status); return status; } @@ -771,8 +773,9 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) buffer, 4096, &actlen, 2000); if (ret) - pr_err("bulk message failed: %d (%d/%d)", ret, - size, actlen); + dev_err(&dev->udev->dev, + "bulk message failed: %d (%d/%d)", ret, + size, actlen); else { errCode = actlen != size ? -1 : 0; } @@ -1008,14 +1011,16 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dev->video_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.urb) { - pr_err("cannot alloc memory for usb buffers\n"); + dev_err(&dev->udev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.transfer_buffer) { - pr_err("cannot allocate memory for usbtransfer\n"); + dev_err(&dev->udev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); return -ENOMEM; } @@ -1035,7 +1040,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { urb = usb_alloc_urb(max_packets, GFP_KERNEL); if (!urb) { - pr_err("cannot alloc isoc_ctl.urb %i\n", i); + dev_err(&dev->udev->dev, + "cannot alloc isoc_ctl.urb %i\n", i); cx231xx_uninit_isoc(dev); return -ENOMEM; } @@ -1045,7 +1051,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + dev_err(&dev->udev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); cx231xx_uninit_isoc(dev); @@ -1079,7 +1086,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, + dev_err(&dev->udev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_isoc(dev); return rc; @@ -1140,14 +1148,16 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dev->video_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.urb) { - pr_err("cannot alloc memory for usb buffers\n"); + dev_err(&dev->udev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.transfer_buffer) { - pr_err("cannot allocate memory for usbtransfer\n"); + dev_err(&dev->udev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.bulk_ctl.urb); return -ENOMEM; } @@ -1167,7 +1177,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - pr_err("cannot alloc bulk_ctl.urb %i\n", i); + dev_err(&dev->udev->dev, + "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_bulk(dev); return -ENOMEM; } @@ -1178,7 +1189,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + dev_err(&dev->udev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); cx231xx_uninit_bulk(dev); @@ -1200,7 +1212,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i,rc); + dev_err(&dev->udev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_bulk(dev); return rc; } @@ -1303,7 +1316,8 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (errCode < 0) { - pr_err("%s: Failed to set Power - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1311,7 +1325,8 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (errCode < 0) { - pr_err("%s: Failed to set Power - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1325,13 +1340,15 @@ int cx231xx_dev_init(struct cx231xx *dev) /* initialize Colibri block */ errCode = cx231xx_afe_init_super_block(dev, 0x23c); if (errCode < 0) { - pr_err("%s: cx231xx_afe init super block - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_afe init super block - errCode [%d]!\n", __func__, errCode); return errCode; } errCode = cx231xx_afe_init_channels(dev); if (errCode < 0) { - pr_err("%s: cx231xx_afe init channels - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_afe init channels - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1339,7 +1356,8 @@ int cx231xx_dev_init(struct cx231xx *dev) /* Set DIF in By pass mode */ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (errCode < 0) { - pr_err("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1347,7 +1365,8 @@ int cx231xx_dev_init(struct cx231xx *dev) /* I2S block related functions */ errCode = cx231xx_i2s_blk_initialize(dev); if (errCode < 0) { - pr_err("%s: cx231xx_i2s block initialize - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_i2s block initialize - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1355,7 +1374,8 @@ int cx231xx_dev_init(struct cx231xx *dev) /* init control pins */ errCode = cx231xx_init_ctrl_pin_status(dev); if (errCode < 0) { - pr_err("%s: cx231xx_init ctrl pins - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_init ctrl pins - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1381,7 +1401,8 @@ int cx231xx_dev_init(struct cx231xx *dev) break; } if (errCode < 0) { - pr_err("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", + dev_err(&dev->udev->dev, + "%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", __func__, errCode); return errCode; } @@ -1457,7 +1478,7 @@ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - pr_err("%s: failed with status -%d\n", + dev_err(&dev->udev->dev, "%s: failed with status -%d\n", __func__, status); } diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index b6af923eb5a3..044ad353d09b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -22,7 +22,6 @@ #include "cx231xx.h" #include #include -#include #include #include @@ -265,7 +264,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) struct cx231xx *dev = dvb->adapter.priv; if (dev->USE_ISO) { - pr_debug("DVB transfer mode is ISO.\n"); + dev_dbg(&dev->udev->dev, "DVB transfer mode is ISO.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -276,7 +275,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) dev->ts1_mode.max_pkt_size, dvb_isoc_copy); } else { - pr_debug("DVB transfer mode is BULK.\n"); + dev_dbg(&dev->udev->dev, "DVB transfer mode is BULK.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 0); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -430,14 +429,17 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) if (dops->init != NULL && !dev->xc_fw_load_done) { - pr_debug("Reloading firmware for XC5000\n"); + dev_dbg(&dev->udev->dev, + "Reloading firmware for XC5000\n"); status = dops->init(dev->dvb->frontend); if (status == 0) { dev->xc_fw_load_done = 1; - pr_debug("XC5000 firmware download completed\n"); + dev_dbg(&dev->udev->dev, + "XC5000 firmware download completed\n"); } else { dev->xc_fw_load_done = 0; - pr_debug("XC5000 firmware download failed !!!\n"); + dev_dbg(&dev->udev->dev, + "XC5000 firmware download failed !!!\n"); } } diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index f99857e6c842..c4dc13afbe05 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -23,7 +23,6 @@ #include "cx231xx.h" #include #include -#include #include #include #include @@ -502,18 +501,20 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); - pr_info("i2c_scan: checking for I2C devices on port=%d ..\n", + dev_info(&dev->udev->dev, + "i2c_scan: checking for I2C devices on port=%d ..\n", i2c_port); for (i = 0; i < 128; i++) { client.addr = i; rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; - pr_info("i2c scan: found device @ 0x%x [%s]\n", - i << 1, - i2c_devs[i] ? i2c_devs[i] : "???"); + dev_info(&dev->udev->dev, + "i2c scan: found device @ 0x%x [%s]\n", + i << 1, + i2c_devs[i] ? i2c_devs[i] : "???"); } - pr_info("i2c scan: Completed Checking for I2C devices on port=%d.\n", + dev_info(&dev->udev->dev, "i2c scan: Completed Checking for I2C devices on port=%d.\n", i2c_port); dev->i2c_scan_running = false; @@ -539,7 +540,8 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_add_adapter(&bus->i2c_adap); if (0 != bus->i2c_rc) - pr_warn("i2c bus %d register FAILED\n", bus->nr); + dev_warn(&dev->udev->dev, + "i2c bus %d register FAILED\n", bus->nr); return bus->i2c_rc; } @@ -582,7 +584,8 @@ int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) NULL); if (!dev->i2c_mux_adap[mux_no]) - pr_warn("i2c mux %d register FAILED\n", mux_no); + dev_warn(&dev->udev->dev, + "i2c mux %d register FAILED\n", mux_no); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c index 5ae2ce3f51b1..f954da6abf31 100644 --- a/drivers/media/usb/cx231xx/cx231xx-input.c +++ b/drivers/media/usb/cx231xx/cx231xx-input.c @@ -19,7 +19,6 @@ */ #include "cx231xx.h" -#include #include #include diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index 2f8dc6afac54..ee9d6225236a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -703,8 +703,8 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY; break; default: - pr_err("bad config in buspower!!!!\n"); - pr_err("config_info=%x\n", + dev_err(&dev->udev->dev, + "bad config in buspower!!!!\nconfig_info=%x\n", config_info & BUSPOWER_MASK); return 1; } @@ -768,8 +768,8 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR; break; default: - pr_err("bad senario!!!!!\n"); - pr_err("config_info=%x\n", + dev_err(&dev->udev->dev, + "bad senario!!!!!\nconfig_info=%x\n", config_info & SELFPOWER_MASK); return -ENODEV; } @@ -781,18 +781,29 @@ int initialize_cx231xx(struct cx231xx *dev) sizeof(struct pcb_config)); if (pcb_debug) { - pr_info("SC(0x00) register = 0x%x\n", config_info); - pr_info("scenario %d\n", - (dev->current_pcb_config.index) + 1); - pr_info("type=%x\n", dev->current_pcb_config.type); - pr_info("mode=%x\n", dev->current_pcb_config.mode); - pr_info("speed=%x\n", dev->current_pcb_config.speed); - pr_info("ts1_source=%x\n", - dev->current_pcb_config.ts1_source); - pr_info("ts2_source=%x\n", - dev->current_pcb_config.ts2_source); - pr_info("analog_source=%x\n", - dev->current_pcb_config.analog_source); + dev_info(&dev->udev->dev, + "SC(0x00) register = 0x%x\n", config_info); + dev_info(&dev->udev->dev, + "scenario %d\n", + (dev->current_pcb_config.index) + 1); + dev_info(&dev->udev->dev, + "type=%x\n", + dev->current_pcb_config.type); + dev_info(&dev->udev->dev, + "mode=%x\n", + dev->current_pcb_config.mode); + dev_info(&dev->udev->dev, + "speed=%x\n", + dev->current_pcb_config.speed); + dev_info(&dev->udev->dev, + "ts1_source=%x\n", + dev->current_pcb_config.ts1_source); + dev_info(&dev->udev->dev, + "ts2_source=%x\n", + dev->current_pcb_config.ts2_source); + dev_info(&dev->udev->dev, + "analog_source=%x\n", + dev->current_pcb_config.analog_source); } return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 14e1eb7f2128..9a562c80e0b1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -69,9 +68,11 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - pr_err("URB status %d [%s].\n", status, errmsg); + dev_err(&dev->udev->dev, + "URB status %d [%s].\n", status, errmsg); } else { - pr_err("URB packet %d, status %d [%s].\n", + dev_err(&dev->udev->dev, + "URB packet %d, status %d [%s].\n", packet, status, errmsg); } } @@ -315,8 +316,8 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - pr_err("urb completition error %d.\n", - urb->status); + dev_err(&dev->udev->dev, + "urb completition error %d.\n", urb->status); break; } @@ -330,7 +331,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { - pr_err("urb resubmit failed (error=%i)\n", + dev_err(&dev->udev->dev, "urb resubmit failed (error=%i)\n", urb->status); } } @@ -343,7 +344,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - pr_debug("called cx231xx_uninit_vbi_isoc\n"); + dev_dbg(&dev->udev->dev, "called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -392,7 +393,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - pr_debug("called cx231xx_vbi_isoc\n"); + dev_dbg(&dev->udev->dev, "called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -418,14 +419,16 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.urb) { - pr_err("cannot alloc memory for usb buffers\n"); + dev_err(&dev->udev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->vbi_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { - pr_err("cannot allocate memory for usbtransfer\n"); + dev_err(&dev->udev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->vbi_mode.bulk_ctl.urb); return -ENOMEM; } @@ -440,7 +443,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - pr_err("cannot alloc bulk_ctl.urb %i\n", i); + dev_err(&dev->udev->dev, + "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -450,7 +454,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - pr_err("unable to allocate %i bytes for transfer buffer %i%s\n", + dev_err(&dev->udev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); cx231xx_uninit_vbi_isoc(dev); @@ -469,7 +474,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - pr_err("submit of urb %i failed (error=%i)\n", i, rc); + dev_err(&dev->udev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; } @@ -520,7 +526,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* pr_debug("[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* dev_dbg(&dev->udev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; @@ -612,7 +618,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, char *outp; if (list_empty(&dma_q->active)) { - pr_err("No active queue to serve\n"); + dev_err(&dev->udev->dev, "No active queue to serve\n"); dev->vbi_mode.bulk_ctl.buf = NULL; *buf = NULL; return; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 4d1d750ab38d..5ea8124f5d20 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -737,8 +736,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*pr_debug("urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size);*/ + dev_dbg(&dev->udev->dev, + "urb_init=%d dev->video_mode.max_pkt_size=%d\n", + urb_init, dev->video_mode.max_pkt_size); if (urb_init) { dev->mode_tv = 0; if (dev->USE_ISO) @@ -809,7 +809,7 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_set_audio_input(dev, dev->ctl_ainput); - pr_debug("video_mux : %d\n", index); + dev_dbg(&dev->udev->dev, "video_mux : %d\n", index); /* do mode control overrides if required */ cx231xx_do_mode_ctrl_overrides(dev); @@ -861,7 +861,7 @@ static void res_free(struct cx231xx_fh *fh) static int check_dev(struct cx231xx *dev) { if (dev->state & DEV_DISCONNECTED) { - pr_err("v4l2 ioctl: device not present\n"); + dev_err(&dev->udev->dev, "v4l2 ioctl: device not present\n"); return -ENODEV; } return 0; @@ -953,12 +953,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; if (videobuf_queue_is_busy(&fh->vb_vidq)) { - pr_err("%s: queue busy\n", __func__); + dev_err(&dev->udev->dev, "%s: queue busy\n", __func__); return -EBUSY; } if (dev->stream_on && !fh->stream_on) { - pr_err("%s: device in use by another fh\n", __func__); + dev_err(&dev->udev->dev, + "%s: device in use by another fh\n", __func__); return -EBUSY; } @@ -1176,8 +1177,9 @@ int cx231xx_s_frequency(struct file *file, void *priv, int rc; u32 if_frequency = 5400000; - pr_debug("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", - f->frequency, f->type); + dev_dbg(&dev->udev->dev, + "Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", + f->frequency, f->type); rc = check_dev(dev); if (rc < 0) @@ -1212,13 +1214,14 @@ int cx231xx_s_frequency(struct file *file, void *priv, else if (dev->norm & V4L2_STD_SECAM_LC) if_frequency = 1250000; /*1.25MHz */ - pr_debug("if_frequency is set to %d\n", if_frequency); + dev_dbg(&dev->udev->dev, + "if_frequency is set to %d\n", if_frequency); cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); update_HH_register_after_set_DIF(dev); } - pr_debug("Set New FREQUENCY to %d\n", f->frequency); + dev_dbg(&dev->udev->dev, "Set New FREQUENCY to %d\n", f->frequency); return rc; } @@ -1522,7 +1525,8 @@ static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; if (dev->vbi_stream_on && !fh->stream_on) { - pr_err("%s device in use by another fh\n", __func__); + dev_err(&dev->udev->dev, + "%s device in use by another fh\n", __func__); return -EBUSY; } return vidioc_try_fmt_vbi_cap(file, priv, f); @@ -1641,16 +1645,15 @@ static int cx231xx_v4l2_open(struct file *filp) #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); if (errCode < 0) { - pr_err("Device locked on digital mode. Can't open analog\n"); + dev_err(&dev->udev->dev, + "Device locked on digital mode. Can't open analog\n"); return -EBUSY; } #endif fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); - if (!fh) { - pr_err("cx231xx-video.c: Out of memory?!\n"); + if (!fh) return -ENOMEM; - } if (mutex_lock_interruptible(&dev->lock)) { kfree(fh); return -ERESTARTSYS; @@ -1734,7 +1737,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - pr_info("V4L2 device %s deregistered\n", + dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", video_device_node_name(dev->vbi_dev)); if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); @@ -1743,7 +1746,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - pr_info("V4L2 device %s deregistered\n", + dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", video_device_node_name(dev->vdev)); if (dev->board.has_417) @@ -2078,7 +2081,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) { int ret; - pr_info("v4l2 driver version %s\n", CX231XX_VERSION); + dev_info(&dev->udev->dev, "v4l2 driver version %s\n", CX231XX_VERSION); /* set default norm */ dev->norm = V4L2_STD_PAL; @@ -2116,7 +2119,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* allocate and fill video video_device struct */ dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); if (!dev->vdev) { - pr_err("cannot allocate video_device.\n"); + dev_err(&dev->udev->dev, "cannot allocate video_device.\n"); return -ENODEV; } @@ -2125,12 +2128,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - pr_err("unable to register video device (error=%i).\n", + dev_err(&dev->udev->dev, + "unable to register video device (error=%i).\n", ret); return ret; } - pr_info("Registered video device %s [v4l2]\n", + dev_info(&dev->udev->dev, "Registered video device %s [v4l2]\n", video_device_node_name(dev->vdev)); /* Initialize VBI template */ @@ -2141,7 +2145,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); if (!dev->vbi_dev) { - pr_err("cannot allocate video_device.\n"); + dev_err(&dev->udev->dev, "cannot allocate video_device.\n"); return -ENODEV; } dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; @@ -2149,28 +2153,30 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - pr_err("unable to register vbi device\n"); + dev_err(&dev->udev->dev, "unable to register vbi device\n"); return ret; } - pr_info("Registered VBI device %s\n", + dev_info(&dev->udev->dev, "Registered VBI device %s\n", video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio"); if (!dev->radio_dev) { - pr_err("cannot allocate video_device.\n"); + dev_err(&dev->udev->dev, + "cannot allocate video_device.\n"); return -ENODEV; } dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - pr_err("can't register radio device\n"); + dev_err(&dev->udev->dev, + "can't register radio device\n"); return ret; } - pr_info("Registered radio device as %s\n", + dev_info(&dev->udev->dev, "Registered radio device as %s\n", video_device_node_name(dev->radio_dev)); } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 253f2437c0f1..1a850da4e8c0 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -22,14 +22,13 @@ #ifndef _CX231XX_H #define _CX231XX_H -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include #include #include #include +#include #include -- GitLab From 56d8a3b06816f740d83f8c8c5dfc7774ae86c1f1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 07:44:47 -0300 Subject: [PATCH 2674/9457] [media] cx231xx: get rid of audio debug parameter There's just one debug level on cx231xx-audio. So, converting it to dev_dbg() is easy. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-audio.c | 39 +++++++++++------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 1c3f68179fc9..a05ae02e5245 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -42,19 +42,13 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "activates debug info"); -#define dprintk(fmt, arg...) do { \ - if (debug) \ - printk(KERN_INFO "cx231xx-audio %s: " fmt, \ - __func__, ##arg); \ - } while (0) - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) { int i; - dprintk("Stopping isoc\n"); + dev_dbg(&dev->udev->dev, "Stopping isoc\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -78,7 +72,7 @@ static int cx231xx_bulk_audio_deinit(struct cx231xx *dev) { int i; - dprintk("Stopping bulk\n"); + dev_dbg(&dev->udev->dev, "Stopping bulk\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -122,7 +116,8 @@ static void cx231xx_audio_isocirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dprintk("urb completition error %d.\n", urb->status); + dev_dbg(&dev->udev->dev, "urb completition error %d.\n", + urb->status); break; } @@ -211,7 +206,8 @@ static void cx231xx_audio_bulkirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dprintk("urb completition error %d.\n", urb->status); + dev_dbg(&dev->udev->dev, "urb completition error %d.\n", + urb->status); break; } @@ -395,8 +391,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size) { struct snd_pcm_runtime *runtime = subs->runtime; + struct cx231xx *dev = snd_pcm_substream_chip(subs); - dprintk("Allocating vbuffer\n"); + dev_dbg(&dev->udev->dev, "Allocating vbuffer\n"); if (runtime->dma_area) { if (runtime->dma_bytes > size) return 0; @@ -439,7 +436,8 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int ret = 0; - dprintk("opening device and trying to acquire exclusive lock\n"); + dev_dbg(&dev->udev->dev, + "opening device and trying to acquire exclusive lock\n"); if (!dev) { dev_err(&dev->udev->dev, @@ -489,7 +487,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) int ret; struct cx231xx *dev = snd_pcm_substream_chip(substream); - dprintk("closing device\n"); + dev_dbg(&dev->udev->dev, "closing device\n"); /* inform hardware to stop streaming */ mutex_lock(&dev->lock); @@ -510,10 +508,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) mutex_unlock(&dev->lock); if (dev->adev.users == 0 && dev->adev.shutdown == 1) { - dprintk("audio users: %d\n", dev->adev.users); - dprintk("disabling audio stream!\n"); + dev_dbg(&dev->udev->dev, "audio users: %d\n", dev->adev.users); + dev_dbg(&dev->udev->dev, "disabling audio stream!\n"); dev->adev.shutdown = 0; - dprintk("released lock\n"); + dev_dbg(&dev->udev->dev, "released lock\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); schedule_work(&dev->wq_trigger); @@ -525,9 +523,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { + struct cx231xx *dev = snd_pcm_substream_chip(substream); int ret; - dprintk("Setting capture parameters\n"); + dev_dbg(&dev->udev->dev, "Setting capture parameters\n"); ret = snd_pcm_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); @@ -549,7 +548,7 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) { struct cx231xx *dev = snd_pcm_substream_chip(substream); - dprintk("Stop capture, if needed\n"); + dev_dbg(&dev->udev->dev, "Stop capture, if needed\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); @@ -574,7 +573,7 @@ static void audio_trigger(struct work_struct *work) struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger); if (atomic_read(&dev->stream_started)) { - dprintk("starting capture"); + dev_dbg(&dev->udev->dev, "starting capture"); if (is_fw_load(dev) == 0) cx25840_call(dev, core, load_fw); if (dev->USE_ISO) @@ -582,7 +581,7 @@ static void audio_trigger(struct work_struct *work) else cx231xx_init_audio_bulk(dev); } else { - dprintk("stopping capture"); + dev_dbg(&dev->udev->dev, "stopping capture"); cx231xx_isoc_audio_deinit(dev); } } -- GitLab From 3b795d01c29c94bf1acd019ee6c7ba6b780406b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 07:45:56 -0300 Subject: [PATCH 2675/9457] [media] cx231xx: use dev_foo instead of printk There are several places at cx231xx that uses printk without any special reason. Change all of them to use dev_foo(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-avcore.c | 3 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 6 +- drivers/media/usb/cx231xx/cx231xx-dvb.c | 96 +++++++++++----------- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 9088a32db2d1..b299242a63dd 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -1208,7 +1208,8 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, /* This is just a casual suggestion to people adding new boards in case they use a tuner type we don't currently know about */ - printk(KERN_INFO "Unknown tuner type configuring SIF"); + dev_info(&dev->udev->dev, + "Unknown tuner type configuring SIF"); break; } break; diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 2e8741314bce..7156344e7022 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1216,11 +1216,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, cx231xx_add_into_devlist(dev); if (dev->board.has_417) { - printk(KERN_INFO "attach 417 %d\n", dev->model); + dev_info(&udev->dev, "attach 417 %d\n", dev->model); if (cx231xx_417_register(dev) < 0) { - printk(KERN_ERR + dev_err(&udev->dev, "%s() Failed to register 417 on VID_B\n", - __func__); + __func__); } } diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 044ad353d09b..a0d40bda718d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -45,11 +45,6 @@ MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ - printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ -} while (0) - #define CX231XX_DVB_NUM_BUFS 5 #define CX231XX_DVB_MAX_PACKETSIZE 564 #define CX231XX_DVB_MAX_PACKETS 64 @@ -196,9 +191,11 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - dprintk(1, "URB status %d [%s].\n", status, errmsg); + dev_dbg(&dev->udev->dev, + "URB status %d [%s].\n", status, errmsg); } else { - dprintk(1, "URB packet %d, status %d [%s].\n", + dev_dbg(&dev->udev->dev, + "URB packet %d, status %d [%s].\n", packet, status, errmsg); } } @@ -377,20 +374,21 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) cfg.i2c_addr = addr; if (!dev->dvb->frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. " + dev_err(&dev->udev->dev, "%s/2: dvb frontend not attached. " "Can't attach xc5000\n", dev->name); return -EINVAL; } fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name); + dev_err(&dev->udev->dev, + "%s/2: xc5000 attach failed\n", dev->name); dvb_frontend_detach(dev->dvb->frontend); dev->dvb->frontend = NULL; return -EINVAL; } - printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name); + dev_info(&dev->udev->dev, "%s/2: xc5000 attached\n", dev->name); return 0; } @@ -462,7 +460,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, adapter_nr); if (result < 0) { - printk(KERN_WARNING + dev_warn(&dev->udev->dev, "%s: dvb_register_adapter failed (errno = %d)\n", dev->name, result); goto fail_adapter; @@ -476,7 +474,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (result < 0) { - printk(KERN_WARNING + dev_warn(&dev->udev->dev, "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); goto fail_frontend; @@ -494,7 +492,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", + dev_warn(&dev->udev->dev, + "%s: dvb_dmx_init failed (errno = %d)\n", dev->name, result); goto fail_dmx; } @@ -504,15 +503,16 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", - dev->name, result); + dev_warn(&dev->udev->dev, + "%s: dvb_dmxdev_init failed (errno = %d)\n", + dev->name, result); goto fail_dmxdev; } dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING + dev_warn(&dev->udev->dev, "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", dev->name, result); goto fail_fe_hw; @@ -521,17 +521,17 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - printk(KERN_WARNING - "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", - dev->name, result); + dev_warn(&dev->udev->dev, + "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + dev->name, result); goto fail_fe_mem; } result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING - "%s: connect_frontend failed (errno = %d)\n", dev->name, - result); + dev_warn(&dev->udev->dev, + "%s: connect_frontend failed (errno = %d)\n", + dev->name, result); goto fail_fe_conn; } @@ -590,7 +590,8 @@ static int dvb_init(struct cx231xx *dev) dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); if (dvb == NULL) { - printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n"); + dev_info(&dev->udev->dev, + "cx231xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; @@ -612,8 +613,8 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1432 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; } @@ -637,8 +638,8 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1411 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } @@ -660,8 +661,8 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1432 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; } @@ -684,8 +685,8 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1411 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } @@ -702,7 +703,8 @@ static int dvb_init(struct cx231xx *dev) break; case CX231XX_BOARD_HAUPPAUGE_EXETER: - printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n", + dev_info(&dev->udev->dev, + "%s: looking for tuner / demod on i2c bus: %d\n", __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(lgdt3305_attach, @@ -710,8 +712,8 @@ static int dvb_init(struct cx231xx *dev) tuner_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach LG3305 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach LG3305 front end\n"); result = -EINVAL; goto out_free; } @@ -732,8 +734,8 @@ static int dvb_init(struct cx231xx *dev) ); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach SI2165 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; } @@ -765,8 +767,8 @@ static int dvb_init(struct cx231xx *dev) ); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach SI2165 front end\n"); + dev_err(&dev->udev->dev, + "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; } @@ -810,16 +812,17 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: - printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", - __func__, i2c_adapter_id(tuner_i2c)); + dev_info(&dev->udev->dev, + "%s: looking for demod on i2c bus: %d\n", + __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(mb86a20s_attach, &pv_mb86a20s_config, demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach mb86a20s demod\n"); + dev_err(&dev->udev->dev, + "Failed to attach mb86a20s demod\n"); result = -EINVAL; goto out_free; } @@ -833,12 +836,13 @@ static int dvb_init(struct cx231xx *dev) break; default: - printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" - " isn't supported yet\n", dev->name); + dev_err(&dev->udev->dev, + "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", + dev->name); break; } if (NULL == dvb->frontend) { - printk(KERN_ERR + dev_err(&dev->udev->dev, "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; @@ -851,7 +855,7 @@ static int dvb_init(struct cx231xx *dev) goto out_free; - printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); + dev_info(&dev->udev->dev, "Successfully loaded cx231xx-dvb\n"); ret: cx231xx_set_mode(dev, CX231XX_SUSPEND); -- GitLab From ec2a387eaf859415038fce698d5954c8ae437854 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 07:53:25 -0300 Subject: [PATCH 2676/9457] [media] cx231xx: add addr for demod and make i2c_devs const I2C address 0x10 is the demod. While here, make the array const. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index c4dc13afbe05..87b26157cad0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -471,7 +471,8 @@ static struct i2c_adapter cx231xx_adap_template = { * i2c_devs * incomplete list of known devices */ -static char *i2c_devs[128] = { +static const char *i2c_devs[128] = { + [0x20 >> 1] = "demod", [0x60 >> 1] = "colibri", [0x88 >> 1] = "hammerhead", [0x8e >> 1] = "CIR", -- GitLab From fb1817e48f49b0c4a9da262d9f3db5299dfd9a1c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 08:13:54 -0300 Subject: [PATCH 2677/9457] [media] cx231xx: use dev_info() for extension load/unload Now that we're using dev_foo, the logs become like: usb 1-2: DVB: registering adapter 0 frontend 0 (Fujitsu mb86A20s)... usb 1-2: Successfully loaded cx231xx-dvb cx231xx: Cx231xx dvb Extension initialized It is not clear, by the logs, that usb 1-2 name is an alias for cx231xx. So, we also need to use dvb_info() at extension load/unload. After the patch, it will print: usb 1-2: Cx231xx dvb Extension initialized With is coherent with the other logs. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 36c3ecf204c1..64e907f02a02 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -98,10 +98,10 @@ int cx231xx_register_extension(struct cx231xx_ops *ops) mutex_lock(&cx231xx_devlist_mutex); list_add_tail(&ops->next, &cx231xx_extension_devlist); - list_for_each_entry(dev, &cx231xx_devlist, devlist) + list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->init(dev); - - printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); + dev_info(&dev->udev->dev, "%s initialized\n", ops->name); + } mutex_unlock(&cx231xx_devlist_mutex); return 0; } @@ -112,11 +112,11 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops) struct cx231xx *dev = NULL; mutex_lock(&cx231xx_devlist_mutex); - list_for_each_entry(dev, &cx231xx_devlist, devlist) + list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->fini(dev); + dev_info(&dev->udev->dev, "%s removed\n", ops->name); + } - - printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); list_del(&ops->next); mutex_unlock(&cx231xx_devlist_mutex); } -- GitLab From 3d28cf3ee6e7f8f1d43aaf42a79fe39ddd6350bf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 08:35:46 -0300 Subject: [PATCH 2678/9457] [media] cx231xx: too much changes. Bump version number The I2C mux changes are significant. Bump version number. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 5ea8124f5d20..c5b5e9541669 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -43,7 +43,7 @@ #include "cx231xx-vbi.h" -#define CX231XX_VERSION "0.0.2" +#define CX231XX_VERSION "0.0.3" #define DRIVER_AUTHOR "Srinivasa Deevi " #define DRIVER_DESC "Conexant cx231xx based USB video device driver" -- GitLab From ac550faabd7cc63f3726e21063931cb0d286c59d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Nov 2014 08:34:34 -0300 Subject: [PATCH 2679/9457] [media] cx231xx: simplify I2C scan debug messages Don't need to show when it starts or stops. Just print lines when devices are found. After the changes, the output for i2c scan will be like: usb 1-2: i2c scan: found device @ port 0 addr 0x40 [???] usb 1-2: i2c scan: found device @ port 0 addr 0x60 [colibri] usb 1-2: i2c scan: found device @ port 0 addr 0x88 [hammerhead] usb 1-2: i2c scan: found device @ port 0 addr 0x98 [???] usb 1-2: i2c scan: found device @ port 3 addr 0xa0 [eeprom] usb 1-2: i2c scan: found device @ port 2 addr 0x60 [colibri] usb 1-2: i2c scan: found device @ port 2 addr 0xc0 [tuner] usb 1-2: i2c scan: found device @ port 4 addr 0x20 [demod] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 87b26157cad0..7ccc33d33664 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -502,21 +502,17 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) memset(&client, 0, sizeof(client)); client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); - dev_info(&dev->udev->dev, - "i2c_scan: checking for I2C devices on port=%d ..\n", - i2c_port); for (i = 0; i < 128; i++) { client.addr = i; rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; dev_info(&dev->udev->dev, - "i2c scan: found device @ 0x%x [%s]\n", + "i2c scan: found device @ port %d addr 0x%x [%s]\n", + i2c_port, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); } - dev_info(&dev->udev->dev, "i2c scan: Completed Checking for I2C devices on port=%d.\n", - i2c_port); dev->i2c_scan_running = false; } -- GitLab From 336fea922936c114f68b8c0bcbff5fcfac3507d9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Nov 2014 06:07:38 -0300 Subject: [PATCH 2680/9457] [media] cx231xx: Improve the log message Unfortunately, on devices that have multiple interfaces, udev->dev points to the parent device (usb) instead of the cx231xx specific one. Due to that the logs don't look too nice, as they'll print messages as if they were produced by USB core: usb-1-2: New device Conexant Corporation Polaris AV Capturb @ 480 Mbps (1554:5010) with 7 interfaces Instead of using the name of the parent device, let's use the name of the first cx231xx interface for all cx231xx sub-modules. With this path, the logs will be nicer: cx231xx 1-2:1.1: New device Conexant Corporation Polaris AV Capturb @ 480 Mbps (1554:5010) with 7 interfaces Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 28 ++--- drivers/media/usb/cx231xx/cx231xx-audio.c | 56 ++++----- drivers/media/usb/cx231xx/cx231xx-avcore.c | 126 ++++++++++---------- drivers/media/usb/cx231xx/cx231xx-cards.c | 71 +++++------ drivers/media/usb/cx231xx/cx231xx-core.c | 52 ++++---- drivers/media/usb/cx231xx/cx231xx-dvb.c | 65 +++++----- drivers/media/usb/cx231xx/cx231xx-i2c.c | 10 +- drivers/media/usb/cx231xx/cx231xx-input.c | 4 +- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c | 20 ++-- drivers/media/usb/cx231xx/cx231xx-vbi.c | 26 ++-- drivers/media/usb/cx231xx/cx231xx-video.c | 44 +++---- drivers/media/usb/cx231xx/cx231xx.h | 1 + 12 files changed, 252 insertions(+), 251 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 0773da4dc29b..8998fa4a43f6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -987,25 +987,25 @@ static int cx231xx_load_firmware(struct cx231xx *dev) IVTV_REG_APU, 0); if (retval != 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Error with mc417_register_write\n", __func__); return -1; } retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME, - &dev->udev->dev); + dev->dev); if (retval != 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "ERROR: Hotplug firmware request failed (%s).\n", CX231xx_FIRM_IMAGE_NAME); - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", firmware->size, CX231xx_FIRM_IMAGE_SIZE); release_firmware(firmware); @@ -1013,7 +1013,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) } if (0 != memcmp(firmware->data, magic, 8)) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -1; @@ -1061,7 +1061,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Error with mc417_register_write\n", __func__); return retval; @@ -1074,7 +1074,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Error with mc417_register_write\n", __func__); return retval; @@ -1123,27 +1123,27 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) dprintk(2, "%s: PING OK\n", __func__); retval = cx231xx_load_firmware(dev); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: f/w load failed\n", __func__); return retval; } retval = cx231xx_find_mailbox(dev); if (retval < 0) { - dev_err(&dev->udev->dev, "%s: mailbox < 0, error\n", + dev_err(dev->dev, "%s: mailbox < 0, error\n", __func__); return -1; } dev->cx23417_mailbox = retval; retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "ERROR: cx23417 firmware ping failed!\n"); return -1; } retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "ERROR: cx23417 firmware get encoder: version failed!\n"); return -1; } @@ -1425,7 +1425,7 @@ static int bb_buf_prepare(struct videobuf_queue *q, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "urb_init=%d dev->video_mode.max_pkt_size=%d\n", urb_init, dev->video_mode.max_pkt_size); dev->mode_tv = 1; @@ -1698,7 +1698,7 @@ static int mpeg_open(struct file *file) sizeof(struct cx231xx_buffer), fh, &dev->lock); /* videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops, - &dev->udev->dev, &dev->ts1.slock, + dev->dev, &dev->ts1.slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct cx231xx_buffer), diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index a05ae02e5245..6d9a03402faf 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -48,7 +48,7 @@ static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) { int i; - dev_dbg(&dev->udev->dev, "Stopping isoc\n"); + dev_dbg(dev->dev, "Stopping isoc\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -72,7 +72,7 @@ static int cx231xx_bulk_audio_deinit(struct cx231xx *dev) { int i; - dev_dbg(&dev->udev->dev, "Stopping bulk\n"); + dev_dbg(dev->dev, "Stopping bulk\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -116,7 +116,7 @@ static void cx231xx_audio_isocirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dev_dbg(&dev->udev->dev, "urb completition error %d.\n", + dev_dbg(dev->dev, "urb completition error %d.\n", urb->status); break; } @@ -176,7 +176,7 @@ static void cx231xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "resubmit of audio urb failed (error=%i)\n", status); } @@ -206,7 +206,7 @@ static void cx231xx_audio_bulkirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dev_dbg(&dev->udev->dev, "urb completition error %d.\n", + dev_dbg(dev->dev, "urb completition error %d.\n", urb->status); break; } @@ -262,7 +262,7 @@ static void cx231xx_audio_bulkirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "resubmit of audio urb failed (error=%i)\n", status); } @@ -274,7 +274,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) int i, errCode; int sb_size; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Starting ISO AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) @@ -293,7 +293,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - dev_err(&dev->udev->dev, "usb_alloc_urb failed!\n"); + dev_err(dev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -336,7 +336,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) int i, errCode; int sb_size; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Starting BULK AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) @@ -355,7 +355,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - dev_err(&dev->udev->dev, "usb_alloc_urb failed!\n"); + dev_err(dev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -393,7 +393,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, struct snd_pcm_runtime *runtime = subs->runtime; struct cx231xx *dev = snd_pcm_substream_chip(subs); - dev_dbg(&dev->udev->dev, "Allocating vbuffer\n"); + dev_dbg(dev->dev, "Allocating vbuffer\n"); if (runtime->dma_area) { if (runtime->dma_bytes > size) return 0; @@ -436,17 +436,17 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int ret = 0; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "opening device and trying to acquire exclusive lock\n"); if (!dev) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "BUG: cx231xx can't find device struct. Can't proceed with open\n"); return -ENODEV; } if (dev->state & DEV_DISCONNECTED) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Can't open. the device was removed.\n"); return -ENODEV; } @@ -460,7 +460,7 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); mutex_unlock(&dev->lock); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "failed to set alternate setting !\n"); return ret; @@ -487,7 +487,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) int ret; struct cx231xx *dev = snd_pcm_substream_chip(substream); - dev_dbg(&dev->udev->dev, "closing device\n"); + dev_dbg(dev->dev, "closing device\n"); /* inform hardware to stop streaming */ mutex_lock(&dev->lock); @@ -497,7 +497,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "failed to set alternate setting !\n"); mutex_unlock(&dev->lock); @@ -508,10 +508,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) mutex_unlock(&dev->lock); if (dev->adev.users == 0 && dev->adev.shutdown == 1) { - dev_dbg(&dev->udev->dev, "audio users: %d\n", dev->adev.users); - dev_dbg(&dev->udev->dev, "disabling audio stream!\n"); + dev_dbg(dev->dev, "audio users: %d\n", dev->adev.users); + dev_dbg(dev->dev, "disabling audio stream!\n"); dev->adev.shutdown = 0; - dev_dbg(&dev->udev->dev, "released lock\n"); + dev_dbg(dev->dev, "released lock\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); schedule_work(&dev->wq_trigger); @@ -526,7 +526,7 @@ static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, struct cx231xx *dev = snd_pcm_substream_chip(substream); int ret; - dev_dbg(&dev->udev->dev, "Setting capture parameters\n"); + dev_dbg(dev->dev, "Setting capture parameters\n"); ret = snd_pcm_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); @@ -548,7 +548,7 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) { struct cx231xx *dev = snd_pcm_substream_chip(substream); - dev_dbg(&dev->udev->dev, "Stop capture, if needed\n"); + dev_dbg(dev->dev, "Stop capture, if needed\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); @@ -573,7 +573,7 @@ static void audio_trigger(struct work_struct *work) struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger); if (atomic_read(&dev->stream_started)) { - dev_dbg(&dev->udev->dev, "starting capture"); + dev_dbg(dev->dev, "starting capture"); if (is_fw_load(dev) == 0) cx25840_call(dev, core, load_fw); if (dev->USE_ISO) @@ -581,7 +581,7 @@ static void audio_trigger(struct work_struct *work) else cx231xx_init_audio_bulk(dev); } else { - dev_dbg(&dev->udev->dev, "stopping capture"); + dev_dbg(dev->dev, "stopping capture"); cx231xx_isoc_audio_deinit(dev); } } @@ -667,10 +667,10 @@ static int cx231xx_audio_init(struct cx231xx *dev) return 0; } - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "probing for cx231xx non standard usbaudio\n"); - err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio", + err = snd_card_new(dev->dev, index[devnr], "Cx231xx Audio", THIS_MODULE, 0, &card); if (err < 0) return err; @@ -712,7 +712,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) bEndpointAddress; adev->num_alt = uif->num_altsetting; - dev_info(&dev->udev->dev, + dev_info(dev->dev, "audio EndPoint Addr 0x%x, Alternate settings: %i\n", adev->end_point_addr, adev->num_alt); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); @@ -726,7 +726,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) wMaxPacketSize); adev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "audio alternate setting %i, max size= %i\n", i, adev->alt_max_pkt_size[i]); } diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index b299242a63dd..39e887925e3d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -82,10 +82,10 @@ void initGPIO(struct cx231xx *dev) cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); verve_read_byte(dev, 0x07, &val); - dev_dbg(&dev->udev->dev, "verve_read_byte address0x07=0x%x\n", val); + dev_dbg(dev->dev, "verve_read_byte address0x07=0x%x\n", val); verve_write_byte(dev, 0x07, 0xF4); verve_read_byte(dev, 0x07, &val); - dev_dbg(&dev->udev->dev, "verve_read_byte address0x07=0x%x\n", val); + dev_dbg(dev->dev, "verve_read_byte address0x07=0x%x\n", val); cx231xx_capture_start(dev, 1, Vbi); @@ -155,7 +155,7 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) while (afe_power_status != 0x18) { status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18); if (status < 0) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Init Super Block failed in send cmd\n", __func__); break; @@ -164,14 +164,14 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status); afe_power_status &= 0xff; if (status < 0) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Init Super Block failed in receive cmd\n", __func__); break; } i++; if (i == 10) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Init Super Block force break in loop !!!!\n", __func__); status = -1; @@ -412,7 +412,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00); } else { - dev_dbg(&dev->udev->dev, "Invalid AV mode input\n"); + dev_dbg(dev->dev, "Invalid AV mode input\n"); status = -1; } break; @@ -469,7 +469,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x40); } else { - dev_dbg(&dev->udev->dev, "Invalid AV mode input\n"); + dev_dbg(dev->dev, "Invalid AV mode input\n"); status = -1; } } /* switch */ @@ -575,7 +575,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Failed to set Power - errCode [%d]!\n", __func__, status); return status; @@ -593,7 +593,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Failed to set Power - errCode [%d]!\n", __func__, status); return status; @@ -610,7 +610,7 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) break; default: - dev_err(&dev->udev->dev, "%s: Unknown Input %d !\n", + dev_err(dev->dev, "%s: Unknown Input %d !\n", __func__, INPUT(input)->type); break; } @@ -630,7 +630,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, if (pin_type != dev->video_input) { status = cx231xx_afe_adjust_ref_count(dev, pin_type); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: adjust_ref_count :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; @@ -640,7 +640,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* call afe block to set video inputs */ status = cx231xx_afe_set_input_mux(dev, input); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: set_input_mux :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; @@ -672,7 +672,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; @@ -717,7 +717,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; @@ -792,7 +792,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; @@ -828,7 +828,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Reinitialize the DIF */ status = cx231xx_dif_set_standard(dev, dev->norm); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; @@ -972,14 +972,14 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) { int status = 0; - dev_dbg(&dev->udev->dev, "%s: 0x%x\n", + dev_dbg(dev->dev, "%s: 0x%x\n", __func__, (unsigned int)dev->norm); /* Change the DFE_CTRL3 bp_percent to fix flagging */ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280); if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { - dev_dbg(&dev->udev->dev, "%s: NTSC\n", __func__); + dev_dbg(dev->dev, "%s: NTSC\n", __func__); /* Move the close caption lines out of active video, adjust the active video start point */ @@ -1006,7 +1006,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) (FLD_HBLANK_CNT, 0x79)); } else if (dev->norm & V4L2_STD_SECAM) { - dev_dbg(&dev->udev->dev, "%s: SECAM\n", __func__); + dev_dbg(dev->dev, "%s: SECAM\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1033,7 +1033,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) cx231xx_set_field (FLD_HBLANK_CNT, 0x85)); } else { - dev_dbg(&dev->udev->dev, "%s: PAL\n", __func__); + dev_dbg(dev->dev, "%s: PAL\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1208,7 +1208,7 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, /* This is just a casual suggestion to people adding new boards in case they use a tuner type we don't currently know about */ - dev_info(&dev->udev->dev, + dev_info(dev->dev, "Unknown tuner type configuring SIF"); break; } @@ -1334,127 +1334,127 @@ void cx231xx_dump_HH_reg(struct cx231xx *dev) for (i = 0x100; i < 0x140; i++) { vid_blk_read_word(dev, i, &value); - dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x300; i < 0x400; i++) { vid_blk_read_word(dev, i, &value); - dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x400; i < 0x440; i++) { vid_blk_read_word(dev, i, &value); - dev_dbg(&dev->udev->dev, "reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - dev_dbg(&dev->udev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(dev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - dev_dbg(&dev->udev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(dev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); } #if 0 static void cx231xx_dump_SC_reg(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - dev_dbg(&dev->udev->dev, "%s!\n", __func__); + dev_dbg(dev->dev, "%s!\n", __func__); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], value[1], value[2], value[3]); } @@ -1524,7 +1524,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, u32 standard = 0; u8 value[4] = { 0, 0, 0, 0 }; - dev_dbg(&dev->udev->dev, "Enter cx231xx_set_Colibri_For_LowIF()\n"); + dev_dbg(dev->dev, "Enter cx231xx_set_Colibri_For_LowIF()\n"); value[0] = (u8) 0x6F; value[1] = (u8) 0x6F; value[2] = (u8) 0x6F; @@ -1544,7 +1544,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, standard); - dev_dbg(&dev->udev->dev, "colibri_carrier_offset=%d, standard=0x%x\n", + dev_dbg(dev->dev, "colibri_carrier_offset=%d, standard=0x%x\n", colibri_carrier_offset, standard); /* Set the band Pass filter for DIF*/ @@ -1578,7 +1578,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, u64 pll_freq_u64 = 0; u32 i = 0; - dev_dbg(&dev->udev->dev, "if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", + dev_dbg(dev->dev, "if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", if_freq, spectral_invert, mode); @@ -1622,7 +1622,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, if_freq = 16000000; } - dev_dbg(&dev->udev->dev, "Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); + dev_dbg(dev->dev, "Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) { if (Dif_set_array[i].if_freq == if_freq) { vid_blk_write_word(dev, @@ -1734,7 +1734,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) u32 dif_misc_ctrl_value = 0; u32 func_mode = 0; - dev_dbg(&dev->udev->dev, "%s: setStandard to %x\n", __func__, standard); + dev_dbg(dev->dev, "%s: setStandard to %x\n", __func__, standard); status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value); if (standard != DIF_USE_BASEBAND) @@ -2137,7 +2137,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) { int status = 0; u32 dwval; - dev_dbg(&dev->udev->dev, "%s: dev->tuner_type =0%d\n", + dev_dbg(dev->dev, "%s: dev->tuner_type =0%d\n", __func__, dev->tuner_type); /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for * SECAM L/B/D standards */ @@ -2239,7 +2239,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (dev->power_mode != mode) dev->power_mode = mode; else { - dev_dbg(&dev->udev->dev, "%s: mode = %d, No Change req.\n", + dev_dbg(dev->dev, "%s: mode = %d, No Change req.\n", __func__, mode); return 0; } @@ -2479,7 +2479,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - dev_dbg(&dev->udev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); + dev_dbg(dev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2504,7 +2504,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - dev_dbg(&dev->udev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); + dev_dbg(dev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2532,37 +2532,37 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { case Audio: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; case Vbi: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; case Sliced_cc: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; case Raw_Video: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; case TS1_serial_mode: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: set ts1 registers", __func__); if (dev->board.has_417) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: MPEG\n", __func__); value &= 0xFFFFFFFC; value |= 0x3; @@ -2586,7 +2586,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) VRT_SET_REGISTER, TS1_LENGTH_REG, val, 4); } else { - dev_dbg(&dev->udev->dev, "%s: BDA\n", __func__); + dev_dbg(dev->dev, "%s: BDA\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); status = cx231xx_mode_register(dev, @@ -2595,7 +2595,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) break; case TS1_parallel_mode: - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "%s: set ts1 parallel mode registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); @@ -2950,7 +2950,7 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) (nCnt > 0)); if (nCnt == 0) - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "No ACK after %d msec -GPIO I2C failed!", nInit * 10); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 7156344e7022..ae05d591f228 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -855,7 +855,7 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) if (dev->tuner_type == TUNER_XC5000) { if (command == XC5000_TUNER_RESET) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Tuner CB: RESET: cmd %d : tuner type %d\n", command, dev->tuner_type); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, @@ -915,7 +915,7 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) cx231xx_set_model(dev); - dev_info(&dev->udev->dev, "Identified as %s (card=%d)\n", + dev_info(dev->dev, "Identified as %s (card=%d)\n", dev->board.name, dev->model); /* set the direction for GPIO pins */ @@ -989,7 +989,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, /* start reading at offset 0 */ ret = i2c_transfer(client->adapter, &msg_write, 1); if (ret < 0) { - dev_err(&dev->udev->dev, "Can't read eeprom\n"); + dev_err(dev->dev, "Can't read eeprom\n"); return ret; } @@ -999,7 +999,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, ret = i2c_transfer(client->adapter, &msg_read, 1); if (ret < 0) { - dev_err(&dev->udev->dev, "Can't read eeprom\n"); + dev_err(dev->dev, "Can't read eeprom\n"); return ret; } eedata_cur += msg_read.len; @@ -1007,7 +1007,7 @@ static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, } for (i = 0; i + 15 < len; i += 16) - dev_dbg(&dev->udev->dev, "i2c eeprom %02x: %*ph\n", + dev_dbg(dev->dev, "i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); return 0; @@ -1028,7 +1028,7 @@ void cx231xx_card_setup(struct cx231xx *dev) cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); @@ -1043,7 +1043,7 @@ void cx231xx_card_setup(struct cx231xx *dev) "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) - dev_err(&dev->udev->dev, + dev_err(dev->dev, "tuner subdev registration failure\n"); else cx231xx_config_tuner(dev); @@ -1150,7 +1150,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* Query cx231xx to find what pcb config it is related to */ retval = initialize_cx231xx(dev); if (retval < 0) { - dev_err(&udev->dev, "Failed to read PCB config\n"); + dev_err(dev->dev, "Failed to read PCB config\n"); return retval; } @@ -1166,7 +1166,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - dev_err(&udev->dev, "error configuring device\n"); + dev_err(dev->dev, "error configuring device\n"); return -ENOMEM; } @@ -1176,7 +1176,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* register i2c bus */ retval = cx231xx_dev_init(dev); if (retval) { - dev_err(&udev->dev, + dev_err(dev->dev, "%s: cx231xx_i2c_register - errCode [%d]!\n", __func__, retval); goto err_dev_init; @@ -1199,8 +1199,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - dev_err(&udev->dev, "%s: cx231xx_config - errCode [%d]!\n", - __func__, retval); + dev_err(dev->dev, "%s: cx231xx_config - errCode [%d]!\n", + __func__, retval); goto err_dev_init; } @@ -1216,9 +1216,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, cx231xx_add_into_devlist(dev); if (dev->board.has_417) { - dev_info(&udev->dev, "attach 417 %d\n", dev->model); + dev_info(dev->dev, "attach 417 %d\n", dev->model); if (cx231xx_417_register(dev) < 0) { - dev_err(&udev->dev, + dev_err(dev->dev, "%s() Failed to register 417 on VID_B\n", __func__); } @@ -1284,7 +1284,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for video */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; if (idx >= dev->max_iad_interface_count) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Video PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1294,7 +1294,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; - dev_info(&dev->udev->dev, + dev_info(dev->dev, "video EndPoint Addr 0x%x, Alternate settings: %i\n", dev->video_mode.end_point_addr, dev->video_mode.num_alt); @@ -1306,7 +1306,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, for (i = 0; i < dev->video_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Alternate setting %i, max size= %i\n", i, dev->video_mode.alt_max_pkt_size[i]); } @@ -1315,7 +1315,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; if (idx >= dev->max_iad_interface_count) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "VBI PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1326,7 +1326,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; - dev_info(&dev->udev->dev, + dev_info(dev->dev, "VBI EndPoint Addr 0x%x, Alternate settings: %i\n", dev->vbi_mode.end_point_addr, dev->vbi_mode.num_alt); @@ -1342,7 +1342,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Alternate setting %i, max size= %i\n", i, dev->vbi_mode.alt_max_pkt_size[i]); } @@ -1352,7 +1352,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for sliced CC */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; if (idx >= dev->max_iad_interface_count) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Sliced CC PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1363,7 +1363,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; - dev_info(&dev->udev->dev, + dev_info(dev->dev, "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", dev->sliced_cc_mode.end_point_addr, dev->sliced_cc_mode.num_alt); @@ -1376,7 +1376,7 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->sliced_cc_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Alternate setting %i, max size= %i\n", i, dev->sliced_cc_mode.alt_max_pkt_size[i]); } @@ -1392,6 +1392,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev; + struct device *d = &interface->dev; struct usb_interface *uif; struct cx231xx *dev = NULL; int retval = -ENODEV; @@ -1416,7 +1417,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); if (nr >= CX231XX_MAXBOARDS) { /* No free device slots */ - dev_err(&udev->dev, + dev_err(d, "Supports only %i devices.\n", CX231XX_MAXBOARDS); return -ENOMEM; @@ -1434,6 +1435,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, dev->devno = nr; dev->model = id->driver_info; dev->video_mode.alt = -1; + dev->dev = d; dev->interface_count++; /* reset gpio dir and value */ @@ -1472,7 +1474,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - dev_info(&udev->dev, + dev_info(d, "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", udev->manufacturer ? udev->manufacturer : "", udev->product ? udev->product : "", @@ -1489,12 +1491,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, assoc_desc = udev->actconfig->intf_assoc[0]; if (assoc_desc->bFirstInterface != ifnum) { - dev_err(&udev->dev, "Not found matching IAD interface\n"); + dev_err(d, "Not found matching IAD interface\n"); retval = -ENODEV; goto err_if; } - dev_dbg(&udev->dev, "registering interface %d\n", ifnum); + dev_dbg(d, "registering interface %d\n", ifnum); /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); @@ -1502,7 +1504,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* Create v4l2 device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { - dev_err(&udev->dev, "v4l2_device_register failed\n"); + dev_err(d, "v4l2_device_register failed\n"); goto err_v4l2; } @@ -1519,8 +1521,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes for TS1 */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; if (idx >= dev->max_iad_interface_count) { - dev_err(&udev->dev, - "TS1 PCB interface #%d doesn't exist\n", idx); + dev_err(d, "TS1 PCB interface #%d doesn't exist\n", + idx); retval = -ENODEV; goto err_video_alt; } @@ -1531,7 +1533,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; - dev_info(&udev->dev, + dev_info(d, "TS EndPoint Addr 0x%x, Alternate settings: %i\n", dev->ts1_mode.end_point_addr, dev->ts1_mode.num_alt); @@ -1548,9 +1550,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->ts1_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - dev_dbg(&udev->dev, - "Alternate setting %i, max size= %i\n", i, - dev->ts1_mode.alt_max_pkt_size[i]); + dev_dbg(d, "Alternate setting %i, max size= %i\n", + i, dev->ts1_mode.alt_max_pkt_size[i]); } } @@ -1614,7 +1615,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) wake_up_interruptible_all(&dev->open); if (dev->users) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "device %s is open! Deregistration and memory deallocation are deferred on close.\n", video_device_node_name(dev->vdev)); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 64e907f02a02..4a3f28c4e8d3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -100,7 +100,7 @@ int cx231xx_register_extension(struct cx231xx_ops *ops) list_add_tail(&ops->next, &cx231xx_extension_devlist); list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->init(dev); - dev_info(&dev->udev->dev, "%s initialized\n", ops->name); + dev_info(dev->dev, "%s initialized\n", ops->name); } mutex_unlock(&cx231xx_devlist_mutex); return 0; @@ -114,7 +114,7 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops) mutex_lock(&cx231xx_devlist_mutex); list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->fini(dev); - dev_info(&dev->udev->dev, "%s removed\n", ops->name); + dev_info(dev->dev, "%s removed\n", ops->name); } list_del(&ops->next); @@ -227,7 +227,7 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0 && !dev->i2c_scan_running) { - dev_err(&dev->udev->dev, "%s: failed with status -%d\n", + dev_err(dev->dev, "%s: failed with status -%d\n", __func__, status); } @@ -522,7 +522,7 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot change alt number to %d (error=%i)\n", dev->video_mode.alt, errCode); return errCode; @@ -598,7 +598,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) } if (alt > 0 && max_pkt_size == 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "can't change interface %d alt no. to %d: Max. Pkt size = 0\n", usb_interface_index, alt); /*To workaround error number=-71 on EP0 for videograbber, @@ -614,7 +614,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) if (usb_interface_index > 0) { status = usb_set_interface(dev->udev, usb_interface_index, alt); if (status < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "can't change interface %d alt no. to %d (err=%i)\n", usb_interface_index, alt, status); return status; @@ -773,7 +773,7 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) buffer, 4096, &actlen, 2000); if (ret) - dev_err(&dev->udev->dev, + dev_err(dev->dev, "bulk message failed: %d (%d/%d)", ret, size, actlen); else { @@ -1011,7 +1011,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dev->video_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); return -ENOMEM; } @@ -1019,7 +1019,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dev->video_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.transfer_buffer) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); return -ENOMEM; @@ -1040,7 +1040,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { urb = usb_alloc_urb(max_packets, GFP_KERNEL); if (!urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc isoc_ctl.urb %i\n", i); cx231xx_uninit_isoc(dev); return -ENOMEM; @@ -1051,7 +1051,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -1086,7 +1086,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i], GFP_ATOMIC); if (rc) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_isoc(dev); @@ -1148,7 +1148,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dev->video_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); return -ENOMEM; } @@ -1156,7 +1156,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dev->video_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.transfer_buffer) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.bulk_ctl.urb); return -ENOMEM; @@ -1177,7 +1177,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_bulk(dev); return -ENOMEM; @@ -1189,7 +1189,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -1212,7 +1212,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_bulk(dev); return rc; @@ -1316,7 +1316,7 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1325,7 +1325,7 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: Failed to set Power - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1340,14 +1340,14 @@ int cx231xx_dev_init(struct cx231xx *dev) /* initialize Colibri block */ errCode = cx231xx_afe_init_super_block(dev, 0x23c); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_afe init super block - errCode [%d]!\n", __func__, errCode); return errCode; } errCode = cx231xx_afe_init_channels(dev); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_afe init channels - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1356,7 +1356,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* Set DIF in By pass mode */ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1365,7 +1365,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* I2S block related functions */ errCode = cx231xx_i2s_blk_initialize(dev); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_i2s block initialize - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1374,7 +1374,7 @@ int cx231xx_dev_init(struct cx231xx *dev) /* init control pins */ errCode = cx231xx_init_ctrl_pin_status(dev); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_init ctrl pins - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1401,7 +1401,7 @@ int cx231xx_dev_init(struct cx231xx *dev) break; } if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", __func__, errCode); return errCode; @@ -1478,7 +1478,7 @@ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - dev_err(&dev->udev->dev, "%s: failed with status -%d\n", + dev_err(dev->dev, "%s: failed with status -%d\n", __func__, status); } diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index a0d40bda718d..dd600b994e69 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -191,10 +191,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "URB status %d [%s].\n", status, errmsg); } else { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "URB packet %d, status %d [%s].\n", packet, status, errmsg); } @@ -261,7 +261,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) struct cx231xx *dev = dvb->adapter.priv; if (dev->USE_ISO) { - dev_dbg(&dev->udev->dev, "DVB transfer mode is ISO.\n"); + dev_dbg(dev->dev, "DVB transfer mode is ISO.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -272,7 +272,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) dev->ts1_mode.max_pkt_size, dvb_isoc_copy); } else { - dev_dbg(&dev->udev->dev, "DVB transfer mode is BULK.\n"); + dev_dbg(dev->dev, "DVB transfer mode is BULK.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 0); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -374,21 +374,20 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) cfg.i2c_addr = addr; if (!dev->dvb->frontend) { - dev_err(&dev->udev->dev, "%s/2: dvb frontend not attached. " + dev_err(dev->dev, "%s/2: dvb frontend not attached. " "Can't attach xc5000\n", dev->name); return -EINVAL; } fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); if (!fe) { - dev_err(&dev->udev->dev, - "%s/2: xc5000 attach failed\n", dev->name); + dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); dvb_frontend_detach(dev->dvb->frontend); dev->dvb->frontend = NULL; return -EINVAL; } - dev_info(&dev->udev->dev, "%s/2: xc5000 attached\n", dev->name); + dev_info(dev->dev, "%s/2: xc5000 attached\n", dev->name); return 0; } @@ -427,16 +426,16 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) if (dops->init != NULL && !dev->xc_fw_load_done) { - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Reloading firmware for XC5000\n"); status = dops->init(dev->dvb->frontend); if (status == 0) { dev->xc_fw_load_done = 1; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "XC5000 firmware download completed\n"); } else { dev->xc_fw_load_done = 0; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "XC5000 firmware download failed !!!\n"); } } @@ -460,7 +459,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, adapter_nr); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: dvb_register_adapter failed (errno = %d)\n", dev->name, result); goto fail_adapter; @@ -474,7 +473,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); goto fail_frontend; @@ -492,7 +491,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: dvb_dmx_init failed (errno = %d)\n", dev->name, result); goto fail_dmx; @@ -503,7 +502,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: dvb_dmxdev_init failed (errno = %d)\n", dev->name, result); goto fail_dmxdev; @@ -512,7 +511,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", dev->name, result); goto fail_fe_hw; @@ -521,7 +520,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", dev->name, result); goto fail_fe_mem; @@ -529,7 +528,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "%s: connect_frontend failed (errno = %d)\n", dev->name, result); goto fail_fe_conn; @@ -590,7 +589,7 @@ static int dvb_init(struct cx231xx *dev) dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); if (dvb == NULL) { - dev_info(&dev->udev->dev, + dev_info(dev->dev, "cx231xx_dvb: memory allocation failed\n"); return -ENOMEM; } @@ -613,7 +612,7 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; @@ -638,7 +637,7 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; @@ -661,7 +660,7 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; @@ -685,7 +684,7 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; @@ -703,7 +702,7 @@ static int dvb_init(struct cx231xx *dev) break; case CX231XX_BOARD_HAUPPAUGE_EXETER: - dev_info(&dev->udev->dev, + dev_info(dev->dev, "%s: looking for tuner / demod on i2c bus: %d\n", __func__, i2c_adapter_id(tuner_i2c)); @@ -712,7 +711,7 @@ static int dvb_init(struct cx231xx *dev) tuner_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach LG3305 front end\n"); result = -EINVAL; goto out_free; @@ -734,7 +733,7 @@ static int dvb_init(struct cx231xx *dev) ); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; @@ -767,7 +766,7 @@ static int dvb_init(struct cx231xx *dev) ); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; @@ -812,7 +811,7 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: - dev_info(&dev->udev->dev, + dev_info(dev->dev, "%s: looking for demod on i2c bus: %d\n", __func__, i2c_adapter_id(tuner_i2c)); @@ -821,7 +820,7 @@ static int dvb_init(struct cx231xx *dev) demod_i2c); if (dev->dvb->frontend == NULL) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Failed to attach mb86a20s demod\n"); result = -EINVAL; goto out_free; @@ -836,26 +835,26 @@ static int dvb_init(struct cx231xx *dev) break; default: - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); break; } if (NULL == dvb->frontend) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; } /* register everything */ - result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); + result = register_dvb(dvb, THIS_MODULE, dev, dev->dev); if (result < 0) goto out_free; - dev_info(&dev->udev->dev, "Successfully loaded cx231xx-dvb\n"); + dev_info(dev->dev, "Successfully loaded cx231xx-dvb\n"); ret: cx231xx_set_mode(dev, CX231XX_SUSPEND); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 7ccc33d33664..a29c345b027d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -507,7 +507,7 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; - dev_info(&dev->udev->dev, + dev_info(dev->dev, "i2c scan: found device @ port %d addr 0x%x [%s]\n", i2c_port, i << 1, @@ -528,7 +528,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) BUG_ON(!dev->cx231xx_send_usb_command); bus->i2c_adap = cx231xx_adap_template; - bus->i2c_adap.dev.parent = &dev->udev->dev; + bus->i2c_adap.dev.parent = dev->dev; snprintf(bus->i2c_adap.name, sizeof(bus->i2c_adap.name), "%s-%d", bus->dev->name, bus->nr); @@ -537,7 +537,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) i2c_add_adapter(&bus->i2c_adap); if (0 != bus->i2c_rc) - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "i2c bus %d register FAILED\n", bus->nr); return bus->i2c_rc; @@ -569,7 +569,7 @@ int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) { struct i2c_adapter *i2c_parent = &dev->i2c_bus[1].i2c_adap; /* what is the correct mux_dev? */ - struct device *mux_dev = &dev->udev->dev; + struct device *mux_dev = dev->dev; dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent, mux_dev, @@ -581,7 +581,7 @@ int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) NULL); if (!dev->i2c_mux_adap[mux_no]) - dev_warn(&dev->udev->dev, + dev_warn(dev->dev, "i2c mux %d register FAILED\n", mux_no); return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c index f954da6abf31..15d8d1b5f05c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-input.c +++ b/drivers/media/usb/cx231xx/cx231xx-input.c @@ -62,7 +62,7 @@ int cx231xx_ir_init(struct cx231xx *dev) struct i2c_board_info info; u8 ir_i2c_bus; - dev_dbg(&dev->udev->dev, "%s\n", __func__); + dev_dbg(dev->dev, "%s\n", __func__); /* Only initialize if a rc keycode map is defined */ if (!cx231xx_boards[dev->model].rc_map_name) @@ -97,7 +97,7 @@ int cx231xx_ir_init(struct cx231xx *dev) /* Load and bind ir-kbd-i2c */ ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master; - dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", + dev_dbg(dev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", ir_i2c_bus, info.addr); dev->ir_i2c_client = i2c_new_device( cx231xx_get_i2c_adap(dev, ir_i2c_bus), &info); diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index ee9d6225236a..5bc74149fcb9 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -703,7 +703,7 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY; break; default: - dev_err(&dev->udev->dev, + dev_err(dev->dev, "bad config in buspower!!!!\nconfig_info=%x\n", config_info & BUSPOWER_MASK); return 1; @@ -768,7 +768,7 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR; break; default: - dev_err(&dev->udev->dev, + dev_err(dev->dev, "bad senario!!!!!\nconfig_info=%x\n", config_info & SELFPOWER_MASK); return -ENODEV; @@ -781,27 +781,27 @@ int initialize_cx231xx(struct cx231xx *dev) sizeof(struct pcb_config)); if (pcb_debug) { - dev_info(&dev->udev->dev, + dev_info(dev->dev, "SC(0x00) register = 0x%x\n", config_info); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "scenario %d\n", (dev->current_pcb_config.index) + 1); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "type=%x\n", dev->current_pcb_config.type); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "mode=%x\n", dev->current_pcb_config.mode); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "speed=%x\n", dev->current_pcb_config.speed); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "ts1_source=%x\n", dev->current_pcb_config.ts1_source); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "ts2_source=%x\n", dev->current_pcb_config.ts2_source); - dev_info(&dev->udev->dev, + dev_info(dev->dev, "analog_source=%x\n", dev->current_pcb_config.analog_source); } diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 9a562c80e0b1..80261ac40208 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -68,10 +68,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "URB status %d [%s].\n", status, errmsg); } else { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "URB packet %d, status %d [%s].\n", packet, status, errmsg); } @@ -316,7 +316,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dev_err(&dev->udev->dev, + dev_err(dev->dev, "urb completition error %d.\n", urb->status); break; } @@ -331,7 +331,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { - dev_err(&dev->udev->dev, "urb resubmit failed (error=%i)\n", + dev_err(dev->dev, "urb resubmit failed (error=%i)\n", urb->status); } } @@ -344,7 +344,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - dev_dbg(&dev->udev->dev, "called cx231xx_uninit_vbi_isoc\n"); + dev_dbg(dev->dev, "called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -393,7 +393,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - dev_dbg(&dev->udev->dev, "called cx231xx_vbi_isoc\n"); + dev_dbg(dev->dev, "called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -419,7 +419,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); return -ENOMEM; } @@ -427,7 +427,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); kfree(dev->vbi_mode.bulk_ctl.urb); return -ENOMEM; @@ -443,7 +443,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; @@ -454,7 +454,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); @@ -474,7 +474,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; @@ -526,7 +526,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* dev_dbg(&dev->udev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; @@ -618,7 +618,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, char *outp; if (list_empty(&dma_q->active)) { - dev_err(&dev->udev->dev, "No active queue to serve\n"); + dev_err(dev->dev, "No active queue to serve\n"); dev->vbi_mode.bulk_ctl.buf = NULL; *buf = NULL; return; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index c5b5e9541669..4c5bba2e89f4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -736,7 +736,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "urb_init=%d dev->video_mode.max_pkt_size=%d\n", urb_init, dev->video_mode.max_pkt_size); if (urb_init) { @@ -809,7 +809,7 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_set_audio_input(dev, dev->ctl_ainput); - dev_dbg(&dev->udev->dev, "video_mux : %d\n", index); + dev_dbg(dev->dev, "video_mux : %d\n", index); /* do mode control overrides if required */ cx231xx_do_mode_ctrl_overrides(dev); @@ -861,7 +861,7 @@ static void res_free(struct cx231xx_fh *fh) static int check_dev(struct cx231xx *dev) { if (dev->state & DEV_DISCONNECTED) { - dev_err(&dev->udev->dev, "v4l2 ioctl: device not present\n"); + dev_err(dev->dev, "v4l2 ioctl: device not present\n"); return -ENODEV; } return 0; @@ -953,12 +953,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; if (videobuf_queue_is_busy(&fh->vb_vidq)) { - dev_err(&dev->udev->dev, "%s: queue busy\n", __func__); + dev_err(dev->dev, "%s: queue busy\n", __func__); return -EBUSY; } if (dev->stream_on && !fh->stream_on) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s: device in use by another fh\n", __func__); return -EBUSY; } @@ -1177,7 +1177,7 @@ int cx231xx_s_frequency(struct file *file, void *priv, int rc; u32 if_frequency = 5400000; - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", f->frequency, f->type); @@ -1214,14 +1214,14 @@ int cx231xx_s_frequency(struct file *file, void *priv, else if (dev->norm & V4L2_STD_SECAM_LC) if_frequency = 1250000; /*1.25MHz */ - dev_dbg(&dev->udev->dev, + dev_dbg(dev->dev, "if_frequency is set to %d\n", if_frequency); cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); update_HH_register_after_set_DIF(dev); } - dev_dbg(&dev->udev->dev, "Set New FREQUENCY to %d\n", f->frequency); + dev_dbg(dev->dev, "Set New FREQUENCY to %d\n", f->frequency); return rc; } @@ -1525,7 +1525,7 @@ static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; if (dev->vbi_stream_on && !fh->stream_on) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "%s device in use by another fh\n", __func__); return -EBUSY; } @@ -1645,7 +1645,7 @@ static int cx231xx_v4l2_open(struct file *filp) #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); if (errCode < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "Device locked on digital mode. Can't open analog\n"); return -EBUSY; } @@ -1737,7 +1737,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", + dev_info(dev->dev, "V4L2 device %s deregistered\n", video_device_node_name(dev->vbi_dev)); if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); @@ -1746,7 +1746,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - dev_info(&dev->udev->dev, "V4L2 device %s deregistered\n", + dev_info(dev->dev, "V4L2 device %s deregistered\n", video_device_node_name(dev->vdev)); if (dev->board.has_417) @@ -2081,7 +2081,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) { int ret; - dev_info(&dev->udev->dev, "v4l2 driver version %s\n", CX231XX_VERSION); + dev_info(dev->dev, "v4l2 driver version %s\n", CX231XX_VERSION); /* set default norm */ dev->norm = V4L2_STD_PAL; @@ -2119,7 +2119,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* allocate and fill video video_device struct */ dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); if (!dev->vdev) { - dev_err(&dev->udev->dev, "cannot allocate video_device.\n"); + dev_err(dev->dev, "cannot allocate video_device.\n"); return -ENODEV; } @@ -2128,13 +2128,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "unable to register video device (error=%i).\n", ret); return ret; } - dev_info(&dev->udev->dev, "Registered video device %s [v4l2]\n", + dev_info(dev->dev, "Registered video device %s [v4l2]\n", video_device_node_name(dev->vdev)); /* Initialize VBI template */ @@ -2145,7 +2145,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); if (!dev->vbi_dev) { - dev_err(&dev->udev->dev, "cannot allocate video_device.\n"); + dev_err(dev->dev, "cannot allocate video_device.\n"); return -ENODEV; } dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; @@ -2153,18 +2153,18 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - dev_err(&dev->udev->dev, "unable to register vbi device\n"); + dev_err(dev->dev, "unable to register vbi device\n"); return ret; } - dev_info(&dev->udev->dev, "Registered VBI device %s\n", + dev_info(dev->dev, "Registered VBI device %s\n", video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio"); if (!dev->radio_dev) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "cannot allocate video_device.\n"); return -ENODEV; } @@ -2172,11 +2172,11 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - dev_err(&dev->udev->dev, + dev_err(dev->dev, "can't register radio device\n"); return ret; } - dev_info(&dev->udev->dev, "Registered radio device as %s\n", + dev_info(dev->dev, "Registered radio device as %s\n", video_device_node_name(dev->radio_dev)); } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 1a850da4e8c0..f9e262eb0db9 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -597,6 +597,7 @@ struct cx231xx { char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ int devno; /* marks the number of this device */ + struct device *dev; /* pointer to USB interface's dev */ struct cx231xx_board board; -- GitLab From 82e8aea03f2f5dd2bc5c7e68dc2647b7c6cb4dd7 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 19 Oct 2014 14:56:40 +0300 Subject: [PATCH 2681/9457] iwlwifi: mvm: handle error from iwl_trans_update_sf iwl_trans_update_sf can fail and this wasn't handled. Fix this. Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index e0d9f19650b0..8c96e5af75f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -227,6 +227,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, st_fwrd_space.addr = mvm->sf_space.addr; st_fwrd_space.size = mvm->sf_space.size; ret = iwl_trans_update_sf(mvm->trans, &st_fwrd_space); + if (ret) { + IWL_ERR(mvm, "Failed to update SF size. ret %d\n", ret); + return ret; + } iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr); -- GitLab From c4e7b893a59b8ec3c24c15ff2b73e334d13047d2 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Fri, 31 Oct 2014 04:26:18 -0300 Subject: [PATCH 2682/9457] [media] tveeprom: Update list of chips and extend serial number to 32bits The update was supplied directly by PCTV. Add tuner ids 182-188. Add audproc ids 45-52. Add decoder chip ids 43-53. Use 32bits for the serial number. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tveeprom.c | 36 ++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c index c7dace671a9d..47da0378cad8 100644 --- a/drivers/media/common/tveeprom.c +++ b/drivers/media/common/tveeprom.c @@ -286,9 +286,17 @@ static const struct { { TUNER_ABSENT, "Xceive XC5200C"}, { TUNER_ABSENT, "NXP 18273"}, { TUNER_ABSENT, "Montage M88TS2022"}, - /* 180-189 */ + /* 180-188 */ { TUNER_ABSENT, "NXP 18272M"}, { TUNER_ABSENT, "NXP 18272S"}, + + { TUNER_ABSENT, "Mirics MSi003"}, + { TUNER_ABSENT, "MaxLinear MxL256"}, + { TUNER_ABSENT, "SiLabs Si2158"}, + { TUNER_ABSENT, "SiLabs Si2178"}, + { TUNER_ABSENT, "SiLabs Si2157"}, + { TUNER_ABSENT, "SiLabs Si2177"}, + { TUNER_ABSENT, "ITE IT9137FN"}, }; /* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are @@ -351,6 +359,16 @@ static const struct { { TVEEPROM_AUDPROC_INTERNAL, "CX23887" }, { TVEEPROM_AUDPROC_INTERNAL, "SAA7164" }, { TVEEPROM_AUDPROC_INTERNAL, "AU8522" }, + /* 45-49 */ + { TVEEPROM_AUDPROC_INTERNAL, "AVF4910B" }, + { TVEEPROM_AUDPROC_INTERNAL, "SAA7231" }, + { TVEEPROM_AUDPROC_INTERNAL, "CX23102" }, + { TVEEPROM_AUDPROC_INTERNAL, "SAA7163" }, + { TVEEPROM_AUDPROC_OTHER, "AK4113" }, + /* 50-52 */ + { TVEEPROM_AUDPROC_OTHER, "CS5340" }, + { TVEEPROM_AUDPROC_OTHER, "CS8416" }, + { TVEEPROM_AUDPROC_OTHER, "CX20810" }, }; /* This list is supplied by Hauppauge. Thanks! */ @@ -371,8 +389,12 @@ static const char *decoderIC[] = { "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888", /* 35-39 */ "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A", - /* 40-42 */ - "SAA7164", "CX23885B", "AU8522" + /* 40-44 */ + "SAA7164", "CX23885B", "AU8522", "ADV7401", "AVF4910B", + /* 45-49 */ + "SAA7231", "CX23102", "SAA7163", "ADV7441A", "ADV7181C", + /* 50-53 */ + "CX25836", "TDA9955", "TDA19977", "ADV7842" }; static int hasRadioTuner(int tunerType) @@ -548,10 +570,10 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, tvee->serial_number = eeprom_data[i+5] + (eeprom_data[i+6] << 8) + - (eeprom_data[i+7] << 16); + (eeprom_data[i+7] << 16)+ + (eeprom_data[i+8] << 24); - if ((eeprom_data[i + 8] & 0xf0) && - (tvee->serial_number < 0xffffff)) { + if (eeprom_data[i + 8] == 0xf0) { tvee->MAC_address[0] = 0x00; tvee->MAC_address[1] = 0x0D; tvee->MAC_address[2] = 0xFE; @@ -696,7 +718,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, } } - tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", + tveeprom_info("Hauppauge model %d, rev %s, serial# %u\n", tvee->model, tvee->rev_str, tvee->serial_number); if (tvee->has_MAC_address == 1) tveeprom_info("MAC address is %pM\n", tvee->MAC_address); -- GitLab From 61b103e85a87a5106833fea7b9a21637d9ba2d47 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Thu, 30 Oct 2014 17:48:27 -0300 Subject: [PATCH 2683/9457] [media] cx23885: add support for TechnoTrend CT2-4500 CI TechnoTrend CT2-4500 CI is a PCIe device with DVB-T2/C tuner. It is similar to DVBSky T980C, just with different PCI ID and remote controller. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 14 ++++++++++++++ drivers/media/pci/cx23885/cx23885-dvb.c | 8 +++++--- drivers/media/pci/cx23885/cx23885-input.c | 8 ++++++++ drivers/media/pci/cx23885/cx23885.h | 1 + 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index d9ba48cfb41f..9c7e8ac31cce 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -688,6 +688,10 @@ struct cx23885_board cx23885_boards[] = { .name = "DVBSky S950C", .portb = CX23885_MPEG_DVB, }, + [CX23885_BOARD_TT_CT2_4500_CI] = { + .name = "Technotrend TT-budget CT2-4500 CI", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -955,6 +959,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x4254, .subdevice = 0x950c, .card = CX23885_BOARD_DVBSKY_S950C, + }, { + .subvendor = 0x13c2, + .subdevice = 0x3013, + .card = CX23885_BOARD_TT_CT2_4500_CI, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1559,6 +1567,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: /* * GPIO-0 INTA from CiMax, input * GPIO-1 reset CiMax, output, high active @@ -1671,6 +1680,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1720,6 +1730,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1770,6 +1781,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; @@ -1875,6 +1887,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_PROF_8000: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -1995,6 +2008,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index f82eb1881ac2..5e6caed6e389 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1766,6 +1766,7 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_TT_CT2_4500_CI: i2c_bus = &dev->i2c_bus[1]; i2c_bus2 = &dev->i2c_bus[0]; @@ -1938,7 +1939,8 @@ static int dvb_register(struct cx23885_tsport *port) break; } case CX23885_BOARD_DVBSKY_S950C: - case CX23885_BOARD_DVBSKY_T980C: { + case CX23885_BOARD_DVBSKY_T980C: + case CX23885_BOARD_TT_CT2_4500_CI: { u8 eeprom[256]; /* 24C02 i2c eeprom */ /* attach CI */ @@ -1985,8 +1987,8 @@ static int dvb_register(struct cx23885_tsport *port) dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "DVBSky T980C/S950C MAC address: %pM\n", - eeprom + 0xc0); + printk(KERN_INFO "%s MAC address: %pM\n", + cx23885_boards[dev->board].name, eeprom + 0xc0); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6); break; } diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 0bf6839cb04d..12d8a3de7df4 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -90,6 +90,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -145,6 +146,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_TT_CT2_4500_CI: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -319,6 +321,12 @@ int cx23885_input_init(struct cx23885_dev *dev) allowed_protos = RC_BIT_ALL; rc_map = RC_MAP_DVBSKY; break; + case CX23885_BOARD_TT_CT2_4500_CI: + /* Integrated CX23885 IR controller */ + driver_type = RC_DRIVER_IR_RAW; + allowed_protos = RC_BIT_ALL; + rc_map = RC_MAP_TT_1500; + break; default: return -ENODEV; } diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f6f6974ee824..7eee2ea18ede 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -95,6 +95,7 @@ #define CX23885_BOARD_DVBSKY_T9580 45 #define CX23885_BOARD_DVBSKY_T980C 46 #define CX23885_BOARD_DVBSKY_S950C 47 +#define CX23885_BOARD_TT_CT2_4500_CI 48 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From ed3da2bf2e1800e7c6e31e7d31917dacce599458 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Oct 2014 11:15:53 -0300 Subject: [PATCH 2684/9457] [media] cx23885-dvb: Fix some issues at the DVB error handling X-Patchwork-Delegate: m.chehab@samsung.com As pointed by smatch: drivers/media/pci/cx23885/cx23885-dvb.c:1066 dvb_register() error: we previously assumed 'fe0->dvb.frontend' could be null (see line 1060) drivers/media/pci/cx23885/cx23885-dvb.c:1990 cx23885_dvb_register() error: we previously assumed 'fe0' could be null (see line 1975) What happens is that the error handling logic when a frontend register fails sometimes keep doing the work, as if it didn't fail. This could potentially cause an OOPS. So, simplify the logic a little bit and return an error if frontend fails before trying to setup VB2 queue. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 290 ++++++++++++------------ 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 5e6caed6e389..9da5cf3cea8c 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1058,11 +1058,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(mt2131_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_generic_tunerconfig, 0); break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: @@ -1070,11 +1070,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(lgdt3305_attach, &hauppauge_lgdt3305_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr127x_config); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_hvr127x_config); if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1275) cx23885_set_frontend_hook(port, fe0->dvb.frontend); break; @@ -1084,11 +1084,12 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - } + if (fe0->dvb.frontend == NULL) + break; + + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_tda18271_config); tda18271_attach(&dev->ts1.analog_fe, 0x60, &dev->i2c_bus[1].i2c_adap, @@ -1103,14 +1104,15 @@ static int dvb_register(struct cx23885_tsport *port) dvb_attach(s5h1409_attach, &hauppauge_ezqam_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - } + if (fe0->dvb.frontend == NULL) + break; + + dvb_attach(tda829x_attach, fe0->dvb.frontend, + &dev->i2c_bus[1].i2c_adap, 0x42, + &tda829x_no_probe); + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_tda18271_config); break; case 0: default: @@ -1118,11 +1120,11 @@ static int dvb_register(struct cx23885_tsport *port) dvb_attach(s5h1409_attach, &hauppauge_generic_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - break; + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(mt2131_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_generic_tunerconfig, 0); } break; case CX23885_BOARD_HAUPPAUGE_HVR1800lp: @@ -1130,32 +1132,33 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1800lp_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(mt2131_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_generic_tunerconfig, 0); break; case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(simple_tuner_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, 0x61, + TUNER_LG_TDVS_H06XF); break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: i2c_bus = &dev->i2c_bus[1]; fe0->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_hvr1500q_config, &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig); + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(xc5000_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_hvr1500q_tunerconfig); break; case CX23885_BOARD_HAUPPAUGE_HVR1500: i2c_bus = &dev->i2c_bus[1]; @@ -1186,14 +1189,14 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(tda10048_attach, &hauppauge_hvr1200_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr1200_tuner_config); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(tda829x_attach, fe0->dvb.frontend, + &dev->i2c_bus[1].i2c_adap, 0x42, + &tda829x_no_probe); + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_hvr1200_tuner_config); break; case CX23885_BOARD_HAUPPAUGE_HVR1210: i2c_bus = &dev->i2c_bus[0]; @@ -1452,12 +1455,10 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &mygica_x8506_lgs8gl5_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus2->i2c_adap, - &mygica_x8506_xc5000_config); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(xc5000_attach, fe0->dvb.frontend, + &i2c_bus2->i2c_adap, &mygica_x8506_xc5000_config); cx23885_set_frontend_hook(port, fe0->dvb.frontend); break; case CX23885_BOARD_MYGICA_X8507: @@ -1466,12 +1467,12 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(mb86a20s_attach, &mygica_x8507_mb86a20s_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus2->i2c_adap, - &mygica_x8507_xc5000_config); - } + if (fe0->dvb.frontend == NULL) + break; + + dvb_attach(xc5000_attach, fe0->dvb.frontend, + &i2c_bus2->i2c_adap, + &mygica_x8507_xc5000_config); cx23885_set_frontend_hook(port, fe0->dvb.frontend); break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: @@ -1480,12 +1481,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, &magicpro_prohdtve2_lgs8g75_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus2->i2c_adap, - &magicpro_prohdtve2_xc5000_config); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(xc5000_attach, fe0->dvb.frontend, + &i2c_bus2->i2c_adap, + &magicpro_prohdtve2_xc5000_config); cx23885_set_frontend_hook(port, fe0->dvb.frontend); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: @@ -1493,10 +1493,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[0].i2c_adap, - &hauppauge_tda18271_config); + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[0].i2c_adap, + &hauppauge_tda18271_config); tda18271_attach(&dev->ts1.analog_fe, 0x60, &dev->i2c_bus[1].i2c_adap, @@ -1508,10 +1509,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[0].i2c_adap, - &hauppauge_tda18271_config); + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(tda18271_attach, fe0->dvb.frontend, + 0x60, &dev->i2c_bus[0].i2c_adap, + &hauppauge_tda18271_config); break; case CX23885_BOARD_MYGICA_X8558PRO: switch (port->nr) { @@ -1521,12 +1523,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg1, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(max2165_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &mygic_x8558pro_max2165_cfg1); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(max2165_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &mygic_x8558pro_max2165_cfg1); break; /* port C */ case 2: @@ -1534,13 +1535,11 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(atbm8830_attach, &mygica_x8558pro_atbm8830_cfg2, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(max2165_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &mygic_x8558pro_max2165_cfg2); - } - break; + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(max2165_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &mygic_x8558pro_max2165_cfg2); } break; case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: @@ -1552,15 +1551,15 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(stv0367ter_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (NULL == dvb_attach(xc5000_attach, - fe0->dvb.frontend, + if (fe0->dvb.frontend == NULL) + break; + if (NULL == dvb_attach(xc5000_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, &netup_xc5000_config[port->nr - 1])) - goto frontend_detach; - /* load xc5000 firmware */ - fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); - } + goto frontend_detach; + /* load xc5000 firmware */ + fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); + /* MFE frontend 2 */ fe1 = vb2_dvb_get_frontend(&port->frontends, 2); if (fe1 == NULL) @@ -1569,14 +1568,15 @@ static int dvb_register(struct cx23885_tsport *port) fe1->dvb.frontend = dvb_attach(stv0367cab_attach, &netup_stv0367_config[port->nr - 1], &i2c_bus->i2c_adap); - if (fe1->dvb.frontend != NULL) { - fe1->dvb.frontend->id = 1; - if (NULL == dvb_attach(xc5000_attach, - fe1->dvb.frontend, - &i2c_bus->i2c_adap, - &netup_xc5000_config[port->nr - 1])) - goto frontend_detach; - } + if (fe1->dvb.frontend == NULL) + break; + + fe1->dvb.frontend->id = 1; + if (NULL == dvb_attach(xc5000_attach, + fe1->dvb.frontend, + &i2c_bus->i2c_adap, + &netup_xc5000_config[port->nr - 1])) + goto frontend_detach; break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: i2c_bus = &dev->i2c_bus[0]; @@ -1588,26 +1588,26 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[0], &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(mt2063_attach, - fe0->dvb.frontend, - &terratec_mt2063_config[0], - &i2c_bus2->i2c_adap)) - goto frontend_detach; - } + if (fe0->dvb.frontend == NULL) + break; + if (!dvb_attach(mt2063_attach, + fe0->dvb.frontend, + &terratec_mt2063_config[0], + &i2c_bus2->i2c_adap)) + goto frontend_detach; break; /* port c */ case 2: fe0->dvb.frontend = dvb_attach(drxk_attach, &terratec_drxk_config[1], &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(mt2063_attach, - fe0->dvb.frontend, - &terratec_mt2063_config[1], - &i2c_bus2->i2c_adap)) - goto frontend_detach; - } + if (fe0->dvb.frontend == NULL) + break; + if (!dvb_attach(mt2063_attach, + fe0->dvb.frontend, + &terratec_mt2063_config[1], + &i2c_bus2->i2c_adap)) + goto frontend_detach; break; } break; @@ -1617,10 +1617,10 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(ds3000_attach, &tevii_ds3000_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(ts2020_attach, fe0->dvb.frontend, - &tevii_ts2020_config, &i2c_bus->i2c_adap); - } + if (fe0->dvb.frontend == NULL) + break; + dvb_attach(ts2020_attach, fe0->dvb.frontend, + &tevii_ts2020_config, &i2c_bus->i2c_adap); break; case CX23885_BOARD_PROF_8000: i2c_bus = &dev->i2c_bus[0]; @@ -1629,15 +1629,15 @@ static int dvb_register(struct cx23885_tsport *port) &prof_8000_stv090x_config, &i2c_bus->i2c_adap, STV090x_DEMODULATOR_0); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(stb6100_attach, - fe0->dvb.frontend, - &prof_8000_stb6100_config, - &i2c_bus->i2c_adap)) - goto frontend_detach; + if (fe0->dvb.frontend == NULL) + break; + if (!dvb_attach(stb6100_attach, + fe0->dvb.frontend, + &prof_8000_stb6100_config, + &i2c_bus->i2c_adap)) + goto frontend_detach; - fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage; - } + fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage; break; case CX23885_BOARD_HAUPPAUGE_HVR4400: i2c_bus = &dev->i2c_bus[0]; @@ -1648,26 +1648,26 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend = dvb_attach(tda10071_attach, &hauppauge_tda10071_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(a8293_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_a8293_config)) - goto frontend_detach; - } + if (fe0->dvb.frontend == NULL) + break; + if (!dvb_attach(a8293_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_a8293_config)) + goto frontend_detach; break; /* port c */ case 2: fe0->dvb.frontend = dvb_attach(si2165_attach, &hauppauge_hvr4400_si2165_config, &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; - if (!dvb_attach(tda18271_attach, - fe0->dvb.frontend, - 0x60, &i2c_bus2->i2c_adap, - &hauppauge_hvr4400_tuner_config)) - goto frontend_detach; - } + if (fe0->dvb.frontend == NULL) + break; + fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; + if (!dvb_attach(tda18271_attach, + fe0->dvb.frontend, + 0x60, &i2c_bus2->i2c_adap, + &hauppauge_hvr4400_tuner_config)) + goto frontend_detach; break; } break; @@ -2032,7 +2032,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) fe0 = vb2_dvb_get_frontend(&port->frontends, i); if (!fe0) - err = -EINVAL; + return -EINVAL; dprintk(1, "%s\n", __func__); dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", -- GitLab From d20058f67405981a81344e6fec93f6f557fb96a2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 20 Oct 2014 12:52:02 +0200 Subject: [PATCH 2685/9457] ftracetest: Add kprobes on ftrace testcase Add a kprobes on ftrace testcase. The testcase verifies that - enabling and disabling function tracing works on a function which already contains a dynamic kprobe - adding and removing a dynamic kprobe works on a function which is already enabled for function tracing Link: http://lkml.kernel.org/p/1413802323-5297-2-git-send-email-heiko.carstens@de.ibm.com Acked-by: Masami Hiramatsu Signed-off-by: Heiko Carstens Signed-off-by: Steven Rostedt --- .../ftrace/test.d/kprobe/kprobe_ftrace.tc | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc new file mode 100644 index 000000000000..ab41d2b29841 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc @@ -0,0 +1,55 @@ +#!/bin/sh +# description: Kprobe dynamic event with function tracer + +[ -f kprobe_events ] || exit_unsupported # this is configurable +grep function available_tracers || exit_unsupported # this is configurable + +# prepare +echo nop > current_tracer +echo do_fork > set_ftrace_filter +echo 0 > events/enable +echo > kprobe_events +echo 'p:testprobe do_fork' > kprobe_events + +# kprobe on / ftrace off +echo 1 > events/kprobes/testprobe/enable +echo > trace +( echo "forked") +grep testprobe trace +! grep 'do_fork <-' trace + +# kprobe on / ftrace on +echo function > current_tracer +echo > trace +( echo "forked") +grep testprobe trace +grep 'do_fork <-' trace + +# kprobe off / ftrace on +echo 0 > events/kprobes/testprobe/enable +echo > trace +( echo "forked") +! grep testprobe trace +grep 'do_fork <-' trace + +# kprobe on / ftrace on +echo 1 > events/kprobes/testprobe/enable +echo function > current_tracer +echo > trace +( echo "forked") +grep testprobe trace +grep 'do_fork <-' trace + +# kprobe on / ftrace off +echo nop > current_tracer +echo > trace +( echo "forked") +grep testprobe trace +! grep 'do_fork <-' trace + +# cleanup +echo nop > current_tracer +echo > set_ftrace_filter +echo 0 > events/kprobes/testprobe/enable +echo > kprobe_events +echo > trace -- GitLab From 52100d7f1c35e5b8c4f3017d36f378372f67f87d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 20 Oct 2014 12:52:03 +0200 Subject: [PATCH 2686/9457] ftracetest: Sort testcases Make sure the order of the executed testcases is always the same. Link: http://lkml.kernel.org/p/1413802323-5297-3-git-send-email-heiko.carstens@de.ibm.com Acked-by: Masami Hiramatsu Signed-off-by: Heiko Carstens Signed-off-by: Steven Rostedt --- tools/testing/selftests/ftrace/ftracetest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest index 515247601df4..f15c0da07aca 100755 --- a/tools/testing/selftests/ftrace/ftracetest +++ b/tools/testing/selftests/ftrace/ftracetest @@ -37,7 +37,7 @@ abspath() { } find_testcases() { #directory - echo `find $1 -name \*.tc` + echo `find $1 -name \*.tc | sort` } parse_opts() { # opts -- GitLab From 37975f1503715c51c1a2484b8aba2700a23e6b56 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 9 Oct 2014 22:49:21 +0200 Subject: [PATCH 2687/9457] GFS2: directly return gfs2_dir_check() No need to store gfs2_dir_check result and test it before returning. Signed-off-by: Fabian Frederick Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c4ed823d150e..b41b5c7898da 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1045,11 +1045,7 @@ static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, if (error) return error; - error = gfs2_dir_check(&dip->i_inode, name, ip); - if (error) - return error; - - return 0; + return gfs2_dir_check(&dip->i_inode, name, ip); } /** -- GitLab From 0e27c18c30f6850ecd0fb67143f202f0426d76d7 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 29 Oct 2014 08:02:28 -0500 Subject: [PATCH 2688/9457] GFS2: Set of distributed preferences for rgrps This patch tries to use the journal numbers to evenly distribute which node prefers which resource group for block allocations. This is to help performance. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 1 + fs/gfs2/rgrp.c | 66 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 39e7e9959b74..1b899187be5a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -97,6 +97,7 @@ struct gfs2_rgrpd { #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ +#define GFS2_RDF_PREFERRED 0x80000000 /* This rgrp is preferred */ #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ spinlock_t rd_rsspin; /* protects reservation related vars */ struct rb_root rd_rstree; /* multi-block reservation tree */ diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7474c413ffd1..f4e4a0c5babe 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -936,7 +936,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize; rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1; rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr; - rgd->rd_flags &= ~GFS2_RDF_UPTODATE; + rgd->rd_flags &= ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED); if (rgd->rd_data > sdp->sd_max_rg_data) sdp->sd_max_rg_data = rgd->rd_data; spin_lock(&sdp->sd_rindex_spin); @@ -954,6 +954,36 @@ static int read_rindex_entry(struct gfs2_inode *ip) return error; } +/** + * set_rgrp_preferences - Run all the rgrps, selecting some we prefer to use + * @sdp: the GFS2 superblock + * + * The purpose of this function is to select a subset of the resource groups + * and mark them as PREFERRED. We do it in such a way that each node prefers + * to use a unique set of rgrps to minimize glock contention. + */ +static void set_rgrp_preferences(struct gfs2_sbd *sdp) +{ + struct gfs2_rgrpd *rgd, *first; + int i; + + /* Skip an initial number of rgrps, based on this node's journal ID. + That should start each node out on its own set. */ + rgd = gfs2_rgrpd_get_first(sdp); + for (i = 0; i < sdp->sd_lockstruct.ls_jid; i++) + rgd = gfs2_rgrpd_get_next(rgd); + first = rgd; + + do { + rgd->rd_flags |= GFS2_RDF_PREFERRED; + for (i = 0; i < sdp->sd_journals; i++) { + rgd = gfs2_rgrpd_get_next(rgd); + if (rgd == first) + break; + } + } while (rgd != first); +} + /** * gfs2_ri_update - Pull in a new resource index from the disk * @ip: pointer to the rindex inode @@ -973,6 +1003,8 @@ static int gfs2_ri_update(struct gfs2_inode *ip) if (error < 0) return error; + set_rgrp_preferences(sdp); + sdp->sd_rindex_uptodate = 1; return 0; } @@ -1890,6 +1922,25 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b return false; } +/** + * fast_to_acquire - determine if a resource group will be fast to acquire + * + * If this is one of our preferred rgrps, it should be quicker to acquire, + * because we tried to set ourselves up as dlm lock master. + */ +static inline int fast_to_acquire(struct gfs2_rgrpd *rgd) +{ + struct gfs2_glock *gl = rgd->rd_gl; + + if (gl->gl_state != LM_ST_UNLOCKED && list_empty(&gl->gl_holders) && + !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags) && + !test_bit(GLF_DEMOTE, &gl->gl_flags)) + return 1; + if (rgd->rd_flags & GFS2_RDF_PREFERRED) + return 1; + return 0; +} + /** * gfs2_inplace_reserve - Reserve space in the filesystem * @ip: the inode to reserve space for @@ -1932,10 +1983,15 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a rg_locked = 0; if (skip && skip--) goto next_rgrp; - if (!gfs2_rs_active(rs) && (loops < 2) && - gfs2_rgrp_used_recently(rs, 1000) && - gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) - goto next_rgrp; + if (!gfs2_rs_active(rs)) { + if (loops == 0 && + !fast_to_acquire(rs->rs_rbm.rgd)) + goto next_rgrp; + if ((loops < 2) && + gfs2_rgrp_used_recently(rs, 1000) && + gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) + goto next_rgrp; + } error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, LM_ST_EXCLUSIVE, flags, &rs->rs_rgd_gh); -- GitLab From 33ad5d54284adf110f6e78aa9c4f42d3d17d7f68 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 29 Oct 2014 08:02:29 -0500 Subject: [PATCH 2689/9457] GFS2: Only increase rs_sizehint If an application does a sequence of (1) big write, (2) little write we don't necessarily want to reset the size hint based on the smaller size. The fact that they did any big writes implies they may do more, and therefore we should try to allocate bigger block reservations, even if the last few were small writes. Therefore this patch changes function gfs2_size_hint so that the size hint can only grow; it cannot shrink. This is especially important where there are multiple writers. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 80dd44dca028..5ebe56831794 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -337,7 +337,8 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; int hint = min_t(size_t, INT_MAX, blks); - atomic_set(&ip->i_res->rs_sizehint, hint); + if (hint > atomic_read(&ip->i_res->rs_sizehint)) + atomic_set(&ip->i_res->rs_sizehint, hint); } /** -- GitLab From 1a8550332a7f0111306b6b34e44a7c696ef68c4d Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 29 Oct 2014 08:02:30 -0500 Subject: [PATCH 2690/9457] GFS2: If we use up our block reservation, request more next time If we run out of blocks for a given multi-block allocation, we obviously did not reserve enough. We should reserve more blocks for the next reservation to reduce fragmentation. This patch increases the size hint for reservations when they run out. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 3 +++ fs/gfs2/rgrp.h | 1 + 2 files changed, 4 insertions(+) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index f4e4a0c5babe..9150207f365c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -2251,6 +2251,9 @@ static void gfs2_adjust_reservation(struct gfs2_inode *ip, trace_gfs2_rs(rs, TRACE_RS_CLAIM); if (rs->rs_free && !ret) goto out; + /* We used up our block reservation, so we should + reserve more blocks next time. */ + atomic_add(RGRP_RSRV_ADDBLKS, &rs->rs_sizehint); } __rs_deltree(rs); } diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 5d8f085f7ade..b104f4af3afd 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -20,6 +20,7 @@ */ #define RGRP_RSRV_MINBYTES 8 #define RGRP_RSRV_MINBLKS ((u32)(RGRP_RSRV_MINBYTES * GFS2_NBBY)) +#define RGRP_RSRV_ADDBLKS 64 struct gfs2_rgrpd; struct gfs2_sbd; -- GitLab From b7bd660a51f0cef91d8d544192a5b96c8854e775 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 4 Oct 2014 16:40:50 -0300 Subject: [PATCH 2691/9457] [media] coda: Call v4l2_device_unregister() from a single location Instead of calling v4l2_device_unregister() in multiple locations within the error paths, let's call it from a single location to make the error handling simpler. Signed-off-by: Fabio Estevam Acked-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index c588fad0f1fd..1871f0502f42 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2035,12 +2035,14 @@ static int coda_probe(struct platform_device *pdev) pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); - if (of_id) + if (of_id) { dev->devtype = of_id->data; - else if (pdev_id) + } else if (pdev_id) { dev->devtype = &coda_devdata[pdev_id->driver_data]; - else - return -EINVAL; + } else { + ret = -EINVAL; + goto err_v4l2_register; + } spin_lock_init(&dev->irqlock); INIT_LIST_HEAD(&dev->instances); @@ -2120,8 +2122,7 @@ static int coda_probe(struct platform_device *pdev) dev->debugfs_root); if (ret < 0) { dev_err(&pdev->dev, "failed to allocate work buffer\n"); - v4l2_device_unregister(&dev->v4l2_dev); - return ret; + goto err_v4l2_register; } } @@ -2131,8 +2132,7 @@ static int coda_probe(struct platform_device *pdev) dev->debugfs_root); if (ret < 0) { dev_err(&pdev->dev, "failed to allocate temp buffer\n"); - v4l2_device_unregister(&dev->v4l2_dev); - return ret; + goto err_v4l2_register; } } @@ -2167,6 +2167,10 @@ static int coda_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); return coda_firmware_request(dev); + +err_v4l2_register: + v4l2_device_unregister(&dev->v4l2_dev); + return ret; } static int coda_remove(struct platform_device *pdev) -- GitLab From 74d08d55ed978bd60d4774083f700e6630fe42a5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 4 Oct 2014 16:40:51 -0300 Subject: [PATCH 2692/9457] [media] coda: Unregister v4l2 upon alloc_workqueue() error If alloc_workqueue() fails, we should go to the 'err_v4l2_register' label, which will unregister the v4l2 device. Signed-off-by: Fabio Estevam Acked-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 1871f0502f42..42b46301eff2 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2152,7 +2152,8 @@ static int coda_probe(struct platform_device *pdev) dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1); if (!dev->workqueue) { dev_err(&pdev->dev, "unable to alloc workqueue\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_v4l2_register; } platform_set_drvdata(pdev, dev); -- GitLab From d32f9ff7376c4298799e1532efb307026108f53a Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Wed, 8 Oct 2014 04:31:10 -0300 Subject: [PATCH 2693/9457] [media] smipcie: SMI pcie bridge driver for DVBSky S950 V3 dvb-s/s2 cards There is a new PCIe bridge chip(from SMI) used in DVBSky V3 seris cards, include S950 V3 and S952 V3 cards. SMI pcie bridge chip is PCIe 1.1 compliant, supports MSI feature. Main interface blocks: 1>Two DVB transport stream input ports(ts0,ts1). 2>Two I2C master bus(i2c0, i2c1). 3>IR controller. 4>reset pins and other GPIOs. DVBSky S950 V3 card has a single channel of dvb-s/s2. 1>Frontend: tuner: M88TS2022, demod: M88DS3103 2>PCIe bridge: SMI PCIe The current driver does not support SMI IR function. [mchehab@osg.samsung.com: fix Makefile to find m88ts2022.h] Signed-off-by: Max nibble Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/Kconfig | 1 + drivers/media/pci/Makefile | 3 +- drivers/media/pci/smipcie/Kconfig | 11 + drivers/media/pci/smipcie/Makefile | 6 + drivers/media/pci/smipcie/smipcie.c | 943 ++++++++++++++++++++++++++++ drivers/media/pci/smipcie/smipcie.h | 299 +++++++++ 6 files changed, 1262 insertions(+), 1 deletion(-) create mode 100644 drivers/media/pci/smipcie/Kconfig create mode 100644 drivers/media/pci/smipcie/Makefile create mode 100644 drivers/media/pci/smipcie/smipcie.c create mode 100644 drivers/media/pci/smipcie/smipcie.h diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig index f8cec8e8cf82..218144a99016 100644 --- a/drivers/media/pci/Kconfig +++ b/drivers/media/pci/Kconfig @@ -46,6 +46,7 @@ source "drivers/media/pci/pt3/Kconfig" source "drivers/media/pci/mantis/Kconfig" source "drivers/media/pci/ngene/Kconfig" source "drivers/media/pci/ddbridge/Kconfig" +source "drivers/media/pci/smipcie/Kconfig" endif endif #MEDIA_PCI_SUPPORT diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile index a12926e4b51f..0baf0d2967ee 100644 --- a/drivers/media/pci/Makefile +++ b/drivers/media/pci/Makefile @@ -11,7 +11,8 @@ obj-y += ttpci/ \ mantis/ \ ngene/ \ ddbridge/ \ - saa7146/ + saa7146/ \ + smipcie/ obj-$(CONFIG_VIDEO_IVTV) += ivtv/ obj-$(CONFIG_VIDEO_ZORAN) += zoran/ diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig new file mode 100644 index 000000000000..78b76ca85ed4 --- /dev/null +++ b/drivers/media/pci/smipcie/Kconfig @@ -0,0 +1,11 @@ +config DVB_SMIPCIE + tristate "SMI PCIe DVBSky cards" + depends on DVB_CORE && PCI && I2C + select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + help + Support for cards with SMI PCIe bridge: + - DVBSky S950 V3 + + Say Y or M if you own such a device and want to use it. + If unsure say N. diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile new file mode 100644 index 000000000000..be55481a6e95 --- /dev/null +++ b/drivers/media/pci/smipcie/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o + +ccflags-y += -Idrivers/media/tuners +ccflags-y += -Idrivers/media/dvb-core +ccflags-y += -Idrivers/media/dvb-frontends + diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c new file mode 100644 index 000000000000..3522da4fa5d9 --- /dev/null +++ b/drivers/media/pci/smipcie/smipcie.c @@ -0,0 +1,943 @@ +/* + * SMI PCIe driver for DVBSky cards. + * + * Copyright (C) 2014 Max nibble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "smipcie.h" +#include "m88ds3103.h" +#include "m88ts2022.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static int smi_hw_init(struct smi_dev *dev) +{ + u32 port_mux, port_ctrl, int_stat; + + /* set port mux.*/ + port_mux = smi_read(MUX_MODE_CTRL); + port_mux &= ~(rbPaMSMask); + port_mux |= rbPaMSDtvNoGpio; + port_mux &= ~(rbPbMSMask); + port_mux |= rbPbMSDtvNoGpio; + port_mux &= ~(0x0f0000); + port_mux |= 0x50000; + smi_write(MUX_MODE_CTRL, port_mux); + + /* set DTV register.*/ + /* Port A */ + port_ctrl = smi_read(VIDEO_CTRL_STATUS_A); + port_ctrl &= ~0x01; + smi_write(VIDEO_CTRL_STATUS_A, port_ctrl); + port_ctrl = smi_read(MPEG2_CTRL_A); + port_ctrl &= ~0x40; + port_ctrl |= 0x80; + smi_write(MPEG2_CTRL_A, port_ctrl); + /* Port B */ + port_ctrl = smi_read(VIDEO_CTRL_STATUS_B); + port_ctrl &= ~0x01; + smi_write(VIDEO_CTRL_STATUS_B, port_ctrl); + port_ctrl = smi_read(MPEG2_CTRL_B); + port_ctrl &= ~0x40; + port_ctrl |= 0x80; + smi_write(MPEG2_CTRL_B, port_ctrl); + + /* disable and clear interrupt.*/ + smi_write(MSI_INT_ENA_CLR, ALL_INT); + int_stat = smi_read(MSI_INT_STATUS); + smi_write(MSI_INT_STATUS_CLR, int_stat); + + /* reset demod.*/ + smi_clear(PERIPHERAL_CTRL, 0x0303); + msleep(50); + smi_set(PERIPHERAL_CTRL, 0x0101); + return 0; +} + +/* i2c bit bus.*/ +static void smi_i2c_cfg(struct smi_dev *dev, u32 sw_ctl) +{ + u32 dwCtrl; + + dwCtrl = smi_read(sw_ctl); + dwCtrl &= ~0x18; /* disable output.*/ + dwCtrl |= 0x21; /* reset and software mode.*/ + dwCtrl &= ~0xff00; + dwCtrl |= 0x6400; + smi_write(sw_ctl, dwCtrl); + msleep(20); + dwCtrl = smi_read(sw_ctl); + dwCtrl &= ~0x20; + smi_write(sw_ctl, dwCtrl); +} + +static void smi_i2c_setsda(struct smi_dev *dev, int state, u32 sw_ctl) +{ + if (state) { + /* set as input.*/ + smi_clear(sw_ctl, SW_I2C_MSK_DAT_EN); + } else { + smi_clear(sw_ctl, SW_I2C_MSK_DAT_OUT); + /* set as output.*/ + smi_set(sw_ctl, SW_I2C_MSK_DAT_EN); + } +} + +static void smi_i2c_setscl(void *data, int state, u32 sw_ctl) +{ + struct smi_dev *dev = data; + + if (state) { + /* set as input.*/ + smi_clear(sw_ctl, SW_I2C_MSK_CLK_EN); + } else { + smi_clear(sw_ctl, SW_I2C_MSK_CLK_OUT); + /* set as output.*/ + smi_set(sw_ctl, SW_I2C_MSK_CLK_EN); + } +} + +static int smi_i2c_getsda(void *data, u32 sw_ctl) +{ + struct smi_dev *dev = data; + /* set as input.*/ + smi_clear(sw_ctl, SW_I2C_MSK_DAT_EN); + udelay(1); + return (smi_read(sw_ctl) & SW_I2C_MSK_DAT_IN) ? 1 : 0; +} + +static int smi_i2c_getscl(void *data, u32 sw_ctl) +{ + struct smi_dev *dev = data; + /* set as input.*/ + smi_clear(sw_ctl, SW_I2C_MSK_CLK_EN); + udelay(1); + return (smi_read(sw_ctl) & SW_I2C_MSK_CLK_IN) ? 1 : 0; +} +/* i2c 0.*/ +static void smi_i2c0_setsda(void *data, int state) +{ + struct smi_dev *dev = data; + + smi_i2c_setsda(dev, state, I2C_A_SW_CTL); +} + +static void smi_i2c0_setscl(void *data, int state) +{ + struct smi_dev *dev = data; + + smi_i2c_setscl(dev, state, I2C_A_SW_CTL); +} + +static int smi_i2c0_getsda(void *data) +{ + struct smi_dev *dev = data; + + return smi_i2c_getsda(dev, I2C_A_SW_CTL); +} + +static int smi_i2c0_getscl(void *data) +{ + struct smi_dev *dev = data; + + return smi_i2c_getscl(dev, I2C_A_SW_CTL); +} +/* i2c 1.*/ +static void smi_i2c1_setsda(void *data, int state) +{ + struct smi_dev *dev = data; + + smi_i2c_setsda(dev, state, I2C_B_SW_CTL); +} + +static void smi_i2c1_setscl(void *data, int state) +{ + struct smi_dev *dev = data; + + smi_i2c_setscl(dev, state, I2C_B_SW_CTL); +} + +static int smi_i2c1_getsda(void *data) +{ + struct smi_dev *dev = data; + + return smi_i2c_getsda(dev, I2C_B_SW_CTL); +} + +static int smi_i2c1_getscl(void *data) +{ + struct smi_dev *dev = data; + + return smi_i2c_getscl(dev, I2C_B_SW_CTL); +} + +static int smi_i2c_init(struct smi_dev *dev) +{ + int ret; + + /* i2c bus 0 */ + smi_i2c_cfg(dev, I2C_A_SW_CTL); + i2c_set_adapdata(&dev->i2c_bus[0], dev); + strcpy(dev->i2c_bus[0].name, "SMI-I2C0"); + dev->i2c_bus[0].owner = THIS_MODULE; + dev->i2c_bus[0].dev.parent = &dev->pci_dev->dev; + dev->i2c_bus[0].algo_data = &dev->i2c_bit[0]; + dev->i2c_bit[0].data = dev; + dev->i2c_bit[0].setsda = smi_i2c0_setsda; + dev->i2c_bit[0].setscl = smi_i2c0_setscl; + dev->i2c_bit[0].getsda = smi_i2c0_getsda; + dev->i2c_bit[0].getscl = smi_i2c0_getscl; + dev->i2c_bit[0].udelay = 12; + dev->i2c_bit[0].timeout = 10; + /* Raise SCL and SDA */ + smi_i2c0_setsda(dev, 1); + smi_i2c0_setscl(dev, 1); + + ret = i2c_bit_add_bus(&dev->i2c_bus[0]); + if (ret < 0) + return ret; + + /* i2c bus 1 */ + smi_i2c_cfg(dev, I2C_B_SW_CTL); + i2c_set_adapdata(&dev->i2c_bus[1], dev); + strcpy(dev->i2c_bus[1].name, "SMI-I2C1"); + dev->i2c_bus[1].owner = THIS_MODULE; + dev->i2c_bus[1].dev.parent = &dev->pci_dev->dev; + dev->i2c_bus[1].algo_data = &dev->i2c_bit[1]; + dev->i2c_bit[1].data = dev; + dev->i2c_bit[1].setsda = smi_i2c1_setsda; + dev->i2c_bit[1].setscl = smi_i2c1_setscl; + dev->i2c_bit[1].getsda = smi_i2c1_getsda; + dev->i2c_bit[1].getscl = smi_i2c1_getscl; + dev->i2c_bit[1].udelay = 12; + dev->i2c_bit[1].timeout = 10; + /* Raise SCL and SDA */ + smi_i2c1_setsda(dev, 1); + smi_i2c1_setscl(dev, 1); + + ret = i2c_bit_add_bus(&dev->i2c_bus[1]); + if (ret < 0) + i2c_del_adapter(&dev->i2c_bus[0]); + + return ret; +} + +static void smi_i2c_exit(struct smi_dev *dev) +{ + i2c_del_adapter(&dev->i2c_bus[0]); + i2c_del_adapter(&dev->i2c_bus[1]); +} + +static int smi_read_eeprom(struct i2c_adapter *i2c, u16 reg, u8 *data, u16 size) +{ + int ret; + u8 b0[2] = { (reg >> 8) & 0xff, reg & 0xff }; + + struct i2c_msg msg[] = { + { .addr = 0x50, .flags = 0, + .buf = b0, .len = 2 }, + { .addr = 0x50, .flags = I2C_M_RD, + .buf = data, .len = size } + }; + + ret = i2c_transfer(i2c, msg, 2); + + if (ret != 2) { + dev_err(&i2c->dev, "%s: reg=0x%x (error=%d)\n", + __func__, reg, ret); + return ret; + } + return ret; +} + +/* ts port interrupt operations */ +static void smi_port_disableInterrupt(struct smi_port *port) +{ + struct smi_dev *dev = port->dev; + + smi_write(MSI_INT_ENA_CLR, + (port->_dmaInterruptCH0 | port->_dmaInterruptCH1)); +} + +static void smi_port_enableInterrupt(struct smi_port *port) +{ + struct smi_dev *dev = port->dev; + + smi_write(MSI_INT_ENA_SET, + (port->_dmaInterruptCH0 | port->_dmaInterruptCH1)); +} + +static void smi_port_clearInterrupt(struct smi_port *port) +{ + struct smi_dev *dev = port->dev; + + smi_write(MSI_INT_STATUS_CLR, + (port->_dmaInterruptCH0 | port->_dmaInterruptCH1)); +} + +/* tasklet handler: DMA data to dmx.*/ +static void smi_dma_xfer(unsigned long data) +{ + struct smi_port *port = (struct smi_port *) data; + struct smi_dev *dev = port->dev; + u32 intr_status, finishedData, dmaManagement; + u8 dmaChan0State, dmaChan1State; + + intr_status = port->_int_status; + dmaManagement = smi_read(port->DMA_MANAGEMENT); + dmaChan0State = (u8)((dmaManagement & 0x00000030) >> 4); + dmaChan1State = (u8)((dmaManagement & 0x00300000) >> 20); + + /* CH-0 DMA interrupt.*/ + if ((intr_status & port->_dmaInterruptCH0) && (dmaChan0State == 0x01)) { + dev_dbg(&dev->pci_dev->dev, + "Port[%d]-DMA CH0 engine complete successful !\n", + port->idx); + finishedData = smi_read(port->DMA_CHAN0_TRANS_STATE); + finishedData &= 0x003FFFFF; + /* value of DMA_PORT0_CHAN0_TRANS_STATE register [21:0] + * indicate dma total transfer length and + * zero of [21:0] indicate dma total transfer length + * equal to 0x400000 (4MB)*/ + if (finishedData == 0) + finishedData = 0x00400000; + if (finishedData != SMI_TS_DMA_BUF_SIZE) { + dev_dbg(&dev->pci_dev->dev, + "DMA CH0 engine complete length mismatched, finish data=%d !\n", + finishedData); + } + dvb_dmx_swfilter_packets(&port->demux, + port->cpu_addr[0], (finishedData / 188)); + /*dvb_dmx_swfilter(&port->demux, + port->cpu_addr[0], finishedData);*/ + } + /* CH-1 DMA interrupt.*/ + if ((intr_status & port->_dmaInterruptCH1) && (dmaChan1State == 0x01)) { + dev_dbg(&dev->pci_dev->dev, + "Port[%d]-DMA CH1 engine complete successful !\n", + port->idx); + finishedData = smi_read(port->DMA_CHAN1_TRANS_STATE); + finishedData &= 0x003FFFFF; + /* value of DMA_PORT0_CHAN0_TRANS_STATE register [21:0] + * indicate dma total transfer length and + * zero of [21:0] indicate dma total transfer length + * equal to 0x400000 (4MB)*/ + if (finishedData == 0) + finishedData = 0x00400000; + if (finishedData != SMI_TS_DMA_BUF_SIZE) { + dev_dbg(&dev->pci_dev->dev, + "DMA CH1 engine complete length mismatched, finish data=%d !\n", + finishedData); + } + dvb_dmx_swfilter_packets(&port->demux, + port->cpu_addr[1], (finishedData / 188)); + /*dvb_dmx_swfilter(&port->demux, + port->cpu_addr[1], finishedData);*/ + } + /* restart DMA.*/ + if (intr_status & port->_dmaInterruptCH0) + dmaManagement |= 0x00000002; + if (intr_status & port->_dmaInterruptCH1) + dmaManagement |= 0x00020000; + smi_write(port->DMA_MANAGEMENT, dmaManagement); + /* Re-enable interrupts */ + smi_port_enableInterrupt(port); +} + +static void smi_port_dma_free(struct smi_port *port) +{ + if (port->cpu_addr[0]) { + pci_free_consistent(port->dev->pci_dev, SMI_TS_DMA_BUF_SIZE, + port->cpu_addr[0], port->dma_addr[0]); + port->cpu_addr[0] = NULL; + } + if (port->cpu_addr[1]) { + pci_free_consistent(port->dev->pci_dev, SMI_TS_DMA_BUF_SIZE, + port->cpu_addr[1], port->dma_addr[1]); + port->cpu_addr[1] = NULL; + } +} + +static int smi_port_init(struct smi_port *port, int dmaChanUsed) +{ + dev_dbg(&port->dev->pci_dev->dev, + "%s, port %d, dmaused %d\n", __func__, port->idx, dmaChanUsed); + port->enable = 0; + if (port->idx == 0) { + /* Port A */ + port->_dmaInterruptCH0 = dmaChanUsed & 0x01; + port->_dmaInterruptCH1 = dmaChanUsed & 0x02; + + port->DMA_CHAN0_ADDR_LOW = DMA_PORTA_CHAN0_ADDR_LOW; + port->DMA_CHAN0_ADDR_HI = DMA_PORTA_CHAN0_ADDR_HI; + port->DMA_CHAN0_TRANS_STATE = DMA_PORTA_CHAN0_TRANS_STATE; + port->DMA_CHAN0_CONTROL = DMA_PORTA_CHAN0_CONTROL; + port->DMA_CHAN1_ADDR_LOW = DMA_PORTA_CHAN1_ADDR_LOW; + port->DMA_CHAN1_ADDR_HI = DMA_PORTA_CHAN1_ADDR_HI; + port->DMA_CHAN1_TRANS_STATE = DMA_PORTA_CHAN1_TRANS_STATE; + port->DMA_CHAN1_CONTROL = DMA_PORTA_CHAN1_CONTROL; + port->DMA_MANAGEMENT = DMA_PORTA_MANAGEMENT; + } else { + /* Port B */ + port->_dmaInterruptCH0 = (dmaChanUsed << 2) & 0x04; + port->_dmaInterruptCH1 = (dmaChanUsed << 2) & 0x08; + + port->DMA_CHAN0_ADDR_LOW = DMA_PORTB_CHAN0_ADDR_LOW; + port->DMA_CHAN0_ADDR_HI = DMA_PORTB_CHAN0_ADDR_HI; + port->DMA_CHAN0_TRANS_STATE = DMA_PORTB_CHAN0_TRANS_STATE; + port->DMA_CHAN0_CONTROL = DMA_PORTB_CHAN0_CONTROL; + port->DMA_CHAN1_ADDR_LOW = DMA_PORTB_CHAN1_ADDR_LOW; + port->DMA_CHAN1_ADDR_HI = DMA_PORTB_CHAN1_ADDR_HI; + port->DMA_CHAN1_TRANS_STATE = DMA_PORTB_CHAN1_TRANS_STATE; + port->DMA_CHAN1_CONTROL = DMA_PORTB_CHAN1_CONTROL; + port->DMA_MANAGEMENT = DMA_PORTB_MANAGEMENT; + } + + if (port->_dmaInterruptCH0) { + port->cpu_addr[0] = pci_alloc_consistent(port->dev->pci_dev, + SMI_TS_DMA_BUF_SIZE, + &port->dma_addr[0]); + if (!port->cpu_addr[0]) { + dev_err(&port->dev->pci_dev->dev, + "Port[%d] DMA CH0 memory allocation failed!\n", + port->idx); + goto err; + } + } + + if (port->_dmaInterruptCH1) { + port->cpu_addr[1] = pci_alloc_consistent(port->dev->pci_dev, + SMI_TS_DMA_BUF_SIZE, + &port->dma_addr[1]); + if (!port->cpu_addr[1]) { + dev_err(&port->dev->pci_dev->dev, + "Port[%d] DMA CH1 memory allocation failed!\n", + port->idx); + goto err; + } + } + + smi_port_disableInterrupt(port); + tasklet_init(&port->tasklet, smi_dma_xfer, (unsigned long)port); + tasklet_disable(&port->tasklet); + port->enable = 1; + return 0; +err: + smi_port_dma_free(port); + return -ENOMEM; +} + +static void smi_port_exit(struct smi_port *port) +{ + smi_port_disableInterrupt(port); + tasklet_kill(&port->tasklet); + smi_port_dma_free(port); + port->enable = 0; +} + +static void smi_port_irq(struct smi_port *port, u32 int_status) +{ + u32 port_req_irq = port->_dmaInterruptCH0 | port->_dmaInterruptCH1; + + if (int_status & port_req_irq) { + smi_port_disableInterrupt(port); + port->_int_status = int_status; + smi_port_clearInterrupt(port); + tasklet_schedule(&port->tasklet); + } +} + +static irqreturn_t smi_irq_handler(int irq, void *dev_id) +{ + struct smi_dev *dev = dev_id; + struct smi_port *port0 = &dev->ts_port[0]; + struct smi_port *port1 = &dev->ts_port[1]; + + u32 intr_status = smi_read(MSI_INT_STATUS); + + /* ts0 interrupt.*/ + if (dev->info->ts_0) + smi_port_irq(port0, intr_status); + + /* ts1 interrupt.*/ + if (dev->info->ts_1) + smi_port_irq(port1, intr_status); + + return IRQ_HANDLED; +} + +static const struct m88ds3103_config smi_dvbsky_m88ds3103_cfg = { + .i2c_addr = 0x68, + .clock = 27000000, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_PARALLEL, + .ts_clk = 16000, + .ts_clk_pol = 1, + .agc = 0x99, + .lnb_hv_pol = 0, + .lnb_en_pol = 1, +}; + +static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) +{ + int ret = 0; + struct smi_dev *dev = port->dev; + struct i2c_adapter *i2c; + /* tuner I2C module */ + struct i2c_adapter *tuner_i2c_adapter; + struct i2c_client *tuner_client; + struct i2c_board_info tuner_info; + struct m88ts2022_config m88ts2022_config = { + .clock = 27000000, + }; + memset(&tuner_info, 0, sizeof(struct i2c_board_info)); + i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; + + /* attach demod */ + port->fe = dvb_attach(m88ds3103_attach, + &smi_dvbsky_m88ds3103_cfg, i2c, &tuner_i2c_adapter); + if (!port->fe) { + ret = -ENODEV; + return ret; + } + /* attach tuner */ + m88ts2022_config.fe = port->fe; + strlcpy(tuner_info.type, "m88ts2022", I2C_NAME_SIZE); + tuner_info.addr = 0x60; + tuner_info.platform_data = &m88ts2022_config; + request_module("m88ts2022"); + tuner_client = i2c_new_device(tuner_i2c_adapter, &tuner_info); + if (tuner_client == NULL || tuner_client->dev.driver == NULL) { + ret = -ENODEV; + goto err_tuner_i2c_device; + } + + if (!try_module_get(tuner_client->dev.driver->owner)) { + ret = -ENODEV; + goto err_tuner_i2c_module; + } + + /* delegate signal strength measurement to tuner */ + port->fe->ops.read_signal_strength = + port->fe->ops.tuner_ops.get_rf_strength; + + port->i2c_client_tuner = tuner_client; + return ret; + +err_tuner_i2c_module: + i2c_unregister_device(tuner_client); +err_tuner_i2c_device: + dvb_frontend_detach(port->fe); + return ret; +} + +static int smi_fe_init(struct smi_port *port) +{ + int ret = 0; + struct smi_dev *dev = port->dev; + struct dvb_adapter *adap = &port->dvb_adapter; + u8 mac_ee[16]; + + dev_dbg(&port->dev->pci_dev->dev, + "%s: port %d, fe_type = %d\n", + __func__, port->idx, port->fe_type); + switch (port->fe_type) { + case DVBSKY_FE_M88DS3103: + ret = smi_dvbsky_m88ds3103_fe_attach(port); + break; + } + if (ret < 0) + return ret; + + /* register dvb frontend */ + ret = dvb_register_frontend(adap, port->fe); + if (ret < 0) { + i2c_unregister_device(port->i2c_client_tuner); + dvb_frontend_detach(port->fe); + return ret; + } + /* init MAC.*/ + ret = smi_read_eeprom(&dev->i2c_bus[0], 0xc0, mac_ee, 16); + dev_info(&port->dev->pci_dev->dev, + "DVBSky SMI PCIe MAC= %pM\n", mac_ee + (port->idx)*8); + memcpy(adap->proposed_mac, mac_ee + (port->idx)*8, 6); + return ret; +} + +static void smi_fe_exit(struct smi_port *port) +{ + struct i2c_client *tuner_client; + + dvb_unregister_frontend(port->fe); + /* remove I2C tuner */ + tuner_client = port->i2c_client_tuner; + if (tuner_client) { + module_put(tuner_client->dev.driver->owner); + i2c_unregister_device(tuner_client); + } + dvb_frontend_detach(port->fe); +} + +static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, + int (*start_feed)(struct dvb_demux_feed *), + int (*stop_feed)(struct dvb_demux_feed *), + void *priv) +{ + dvbdemux->priv = priv; + + dvbdemux->filternum = 256; + dvbdemux->feednum = 256; + dvbdemux->start_feed = start_feed; + dvbdemux->stop_feed = stop_feed; + dvbdemux->write_to_decoder = NULL; + dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | + DMX_SECTION_FILTERING | + DMX_MEMORY_BASED_FILTERING); + return dvb_dmx_init(dvbdemux); +} + +static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, + struct dvb_demux *dvbdemux, + struct dmx_frontend *hw_frontend, + struct dmx_frontend *mem_frontend, + struct dvb_adapter *dvb_adapter) +{ + int ret; + + dmxdev->filternum = 256; + dmxdev->demux = &dvbdemux->dmx; + dmxdev->capabilities = 0; + ret = dvb_dmxdev_init(dmxdev, dvb_adapter); + if (ret < 0) + return ret; + + hw_frontend->source = DMX_FRONTEND_0; + dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); + mem_frontend->source = DMX_MEMORY_FE; + dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); + return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); +} + +static u32 smi_config_DMA(struct smi_port *port) +{ + struct smi_dev *dev = port->dev; + u32 totalLength = 0, dmaMemPtrLow, dmaMemPtrHi, dmaCtlReg; + u8 chanLatencyTimer = 0, dmaChanEnable = 1, dmaTransStart = 1; + u32 dmaManagement = 0, tlpTransUnit = DMA_TRANS_UNIT_188; + u8 tlpTc = 0, tlpTd = 1, tlpEp = 0, tlpAttr = 0; + u64 mem; + + dmaManagement = smi_read(port->DMA_MANAGEMENT); + /* Setup Channel-0 */ + if (port->_dmaInterruptCH0) { + totalLength = SMI_TS_DMA_BUF_SIZE; + mem = port->dma_addr[0]; + dmaMemPtrLow = mem & 0xffffffff; + dmaMemPtrHi = mem >> 32; + dmaCtlReg = (totalLength) | (tlpTransUnit << 22) | (tlpTc << 25) + | (tlpTd << 28) | (tlpEp << 29) | (tlpAttr << 30); + dmaManagement |= dmaChanEnable | (dmaTransStart << 1) + | (chanLatencyTimer << 8); + /* write DMA register, start DMA engine */ + smi_write(port->DMA_CHAN0_ADDR_LOW, dmaMemPtrLow); + smi_write(port->DMA_CHAN0_ADDR_HI, dmaMemPtrHi); + smi_write(port->DMA_CHAN0_CONTROL, dmaCtlReg); + } + /* Setup Channel-1 */ + if (port->_dmaInterruptCH1) { + totalLength = SMI_TS_DMA_BUF_SIZE; + mem = port->dma_addr[1]; + dmaMemPtrLow = mem & 0xffffffff; + dmaMemPtrHi = mem >> 32; + dmaCtlReg = (totalLength) | (tlpTransUnit << 22) | (tlpTc << 25) + | (tlpTd << 28) | (tlpEp << 29) | (tlpAttr << 30); + dmaManagement |= (dmaChanEnable << 16) | (dmaTransStart << 17) + | (chanLatencyTimer << 24); + /* write DMA register, start DMA engine */ + smi_write(port->DMA_CHAN1_ADDR_LOW, dmaMemPtrLow); + smi_write(port->DMA_CHAN1_ADDR_HI, dmaMemPtrHi); + smi_write(port->DMA_CHAN1_CONTROL, dmaCtlReg); + } + return dmaManagement; +} + +static int smi_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct smi_port *port = dvbdmx->priv; + struct smi_dev *dev = port->dev; + u32 dmaManagement; + + if (port->users++ == 0) { + dmaManagement = smi_config_DMA(port); + smi_port_clearInterrupt(port); + smi_port_enableInterrupt(port); + smi_write(port->DMA_MANAGEMENT, dmaManagement); + tasklet_enable(&port->tasklet); + } + return port->users; +} + +static int smi_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct smi_port *port = dvbdmx->priv; + struct smi_dev *dev = port->dev; + + if (--port->users) + return port->users; + + tasklet_disable(&port->tasklet); + smi_port_disableInterrupt(port); + smi_clear(port->DMA_MANAGEMENT, 0x30003); + return 0; +} + +static int smi_dvb_init(struct smi_port *port) +{ + int ret; + struct dvb_adapter *adap = &port->dvb_adapter; + struct dvb_demux *dvbdemux = &port->demux; + + dev_dbg(&port->dev->pci_dev->dev, + "%s, port %d\n", __func__, port->idx); + + ret = dvb_register_adapter(adap, "SMI_DVB", THIS_MODULE, + &port->dev->pci_dev->dev, + adapter_nr); + if (ret < 0) { + dev_err(&port->dev->pci_dev->dev, "Fail to register DVB adapter.\n"); + return ret; + } + ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", + smi_start_feed, + smi_stop_feed, port); + if (ret < 0) + goto err_del_dvb_register_adapter; + + ret = my_dvb_dmxdev_ts_card_init(&port->dmxdev, &port->demux, + &port->hw_frontend, + &port->mem_frontend, adap); + if (ret < 0) + goto err_del_dvb_dmx; + + ret = dvb_net_init(adap, &port->dvbnet, port->dmxdev.demux); + if (ret < 0) + goto err_del_dvb_dmxdev; + return 0; +err_del_dvb_dmxdev: + dvbdemux->dmx.close(&dvbdemux->dmx); + dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &port->hw_frontend); + dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &port->mem_frontend); + dvb_dmxdev_release(&port->dmxdev); +err_del_dvb_dmx: + dvb_dmx_release(&port->demux); +err_del_dvb_register_adapter: + dvb_unregister_adapter(&port->dvb_adapter); + return ret; +} + +static void smi_dvb_exit(struct smi_port *port) +{ + struct dvb_demux *dvbdemux = &port->demux; + + dvb_net_release(&port->dvbnet); + + dvbdemux->dmx.close(&dvbdemux->dmx); + dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &port->hw_frontend); + dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &port->mem_frontend); + dvb_dmxdev_release(&port->dmxdev); + dvb_dmx_release(&port->demux); + + dvb_unregister_adapter(&port->dvb_adapter); +} + +static int smi_port_attach(struct smi_dev *dev, + struct smi_port *port, int index) +{ + int ret, dmachs; + + port->dev = dev; + port->idx = index; + port->fe_type = (index == 0) ? dev->info->fe_0 : dev->info->fe_1; + dmachs = (index == 0) ? dev->info->ts_0 : dev->info->ts_1; + /* port init.*/ + ret = smi_port_init(port, dmachs); + if (ret < 0) + return ret; + /* dvb init.*/ + ret = smi_dvb_init(port); + if (ret < 0) + goto err_del_port_init; + /* fe init.*/ + ret = smi_fe_init(port); + if (ret < 0) + goto err_del_dvb_init; + return 0; +err_del_dvb_init: + smi_dvb_exit(port); +err_del_port_init: + smi_port_exit(port); + return ret; +} + +static void smi_port_detach(struct smi_port *port) +{ + smi_fe_exit(port); + smi_dvb_exit(port); + smi_port_exit(port); +} + +static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct smi_dev *dev; + int ret = -ENOMEM; + + if (pci_enable_device(pdev) < 0) + return -ENODEV; + + dev = kzalloc(sizeof(struct smi_dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err_pci_disable_device; + } + + dev->pci_dev = pdev; + pci_set_drvdata(pdev, dev); + dev->info = (struct smi_cfg_info *) id->driver_data; + dev_info(&dev->pci_dev->dev, + "card detected: %s\n", dev->info->name); + + dev->nr = dev->info->type; + dev->lmmio = ioremap(pci_resource_start(dev->pci_dev, 0), + pci_resource_len(dev->pci_dev, 0)); + if (!dev->lmmio) { + ret = -ENOMEM; + goto err_kfree; + } + + /* should we set to 32bit DMA? */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret < 0) + goto err_pci_iounmap; + + pci_set_master(pdev); + + ret = smi_hw_init(dev); + if (ret < 0) + goto err_pci_iounmap; + + ret = smi_i2c_init(dev); + if (ret < 0) + goto err_pci_iounmap; + + if (dev->info->ts_0) { + ret = smi_port_attach(dev, &dev->ts_port[0], 0); + if (ret < 0) + goto err_del_i2c_adaptor; + } + + if (dev->info->ts_1) { + ret = smi_port_attach(dev, &dev->ts_port[1], 1); + if (ret < 0) + goto err_del_port0_attach; + } + +#ifdef CONFIG_PCI_MSI /* to do msi interrupt.???*/ + if (pci_msi_enabled()) + ret = pci_enable_msi(dev->pci_dev); + if (ret) + dev_info(&dev->pci_dev->dev, "MSI not available.\n"); +#endif + + ret = request_irq(dev->pci_dev->irq, smi_irq_handler, + IRQF_SHARED, "SMI_PCIE", dev); + if (ret < 0) + goto err_del_port1_attach; + + return 0; + +err_del_port1_attach: + if (dev->info->ts_1) + smi_port_detach(&dev->ts_port[1]); +err_del_port0_attach: + if (dev->info->ts_0) + smi_port_detach(&dev->ts_port[0]); +err_del_i2c_adaptor: + smi_i2c_exit(dev); +err_pci_iounmap: + iounmap(dev->lmmio); +err_kfree: + pci_set_drvdata(pdev, 0); + kfree(dev); +err_pci_disable_device: + pci_disable_device(pdev); + return ret; +} + +static void smi_remove(struct pci_dev *pdev) +{ + struct smi_dev *dev = pci_get_drvdata(pdev); + + smi_write(MSI_INT_ENA_CLR, ALL_INT); + free_irq(dev->pci_dev->irq, dev); +#ifdef CONFIG_PCI_MSI + pci_disable_msi(dev->pci_dev); +#endif + if (dev->info->ts_1) + smi_port_detach(&dev->ts_port[1]); + if (dev->info->ts_0) + smi_port_detach(&dev->ts_port[0]); + + smi_i2c_exit(dev); + iounmap(dev->lmmio); + pci_set_drvdata(pdev, 0); + pci_disable_device(pdev); + kfree(dev); +} + +/* DVBSky cards */ +static struct smi_cfg_info dvbsky_s950_cfg = { + .type = SMI_DVBSKY_S950, + .name = "DVBSky S950 V3", + .ts_0 = SMI_TS_NULL, + .ts_1 = SMI_TS_DMA_BOTH, + .fe_0 = DVBSKY_FE_NULL, + .fe_1 = DVBSKY_FE_M88DS3103, +}; + +/* PCI IDs */ +#define SMI_ID(_subvend, _subdev, _driverdata) { \ + .vendor = SMI_VID, .device = SMI_PID, \ + .subvendor = _subvend, .subdevice = _subdev, \ + .driver_data = (unsigned long)&_driverdata } + +static const struct pci_device_id smi_id_table[] = { + SMI_ID(0x4254, 0x0550, dvbsky_s950_cfg), + {0} +}; +MODULE_DEVICE_TABLE(pci, smi_id_table); + +static struct pci_driver smipcie_driver = { + .name = "SMI PCIe driver", + .id_table = smi_id_table, + .probe = smi_probe, + .remove = smi_remove, +}; + +module_pci_driver(smipcie_driver); + +MODULE_AUTHOR("Max nibble "); +MODULE_DESCRIPTION("SMI PCIe driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h new file mode 100644 index 000000000000..10cdf20f4839 --- /dev/null +++ b/drivers/media/pci/smipcie/smipcie.h @@ -0,0 +1,299 @@ +/* + * SMI PCIe driver for DVBSky cards. + * + * Copyright (C) 2014 Max nibble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SMI_PCIE_H_ +#define _SMI_PCIE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "demux.h" +#include "dmxdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" +#include "dvb_net.h" +#include "dvbdev.h" + +/* -------- Register Base -------- */ +#define MSI_CONTROL_REG_BASE 0x0800 +#define SYSTEM_CONTROL_REG_BASE 0x0880 +#define PCIE_EP_DEBUG_REG_BASE 0x08C0 +#define IR_CONTROL_REG_BASE 0x0900 +#define I2C_A_CONTROL_REG_BASE 0x0940 +#define I2C_B_CONTROL_REG_BASE 0x0980 +#define ATV_PORTA_CONTROL_REG_BASE 0x09C0 +#define DTV_PORTA_CONTROL_REG_BASE 0x0A00 +#define AES_PORTA_CONTROL_REG_BASE 0x0A80 +#define DMA_PORTA_CONTROL_REG_BASE 0x0AC0 +#define ATV_PORTB_CONTROL_REG_BASE 0x0B00 +#define DTV_PORTB_CONTROL_REG_BASE 0x0B40 +#define AES_PORTB_CONTROL_REG_BASE 0x0BC0 +#define DMA_PORTB_CONTROL_REG_BASE 0x0C00 +#define UART_A_REGISTER_BASE 0x0C40 +#define UART_B_REGISTER_BASE 0x0C80 +#define GPS_CONTROL_REG_BASE 0x0CC0 +#define DMA_PORTC_CONTROL_REG_BASE 0x0D00 +#define DMA_PORTD_CONTROL_REG_BASE 0x0D00 +#define AES_RANDOM_DATA_BASE 0x0D80 +#define AES_KEY_IN_BASE 0x0D90 +#define RANDOM_DATA_LIB_BASE 0x0E00 +#define IR_DATA_BUFFER_BASE 0x0F00 +#define PORTA_TS_BUFFER_BASE 0x1000 +#define PORTA_I2S_BUFFER_BASE 0x1400 +#define PORTB_TS_BUFFER_BASE 0x1800 +#define PORTB_I2S_BUFFER_BASE 0x1C00 + +/* -------- MSI control and state register -------- */ +#define MSI_DELAY_TIMER (MSI_CONTROL_REG_BASE + 0x00) +#define MSI_INT_STATUS (MSI_CONTROL_REG_BASE + 0x08) +#define MSI_INT_STATUS_CLR (MSI_CONTROL_REG_BASE + 0x0C) +#define MSI_INT_STATUS_SET (MSI_CONTROL_REG_BASE + 0x10) +#define MSI_INT_ENA (MSI_CONTROL_REG_BASE + 0x14) +#define MSI_INT_ENA_CLR (MSI_CONTROL_REG_BASE + 0x18) +#define MSI_INT_ENA_SET (MSI_CONTROL_REG_BASE + 0x1C) +#define MSI_SOFT_RESET (MSI_CONTROL_REG_BASE + 0x20) +#define MSI_CFG_SRC0 (MSI_CONTROL_REG_BASE + 0x24) + +/* -------- Hybird Controller System Control register -------- */ +#define MUX_MODE_CTRL (SYSTEM_CONTROL_REG_BASE + 0x00) + #define rbPaMSMask 0x07 + #define rbPaMSDtvNoGpio 0x00 /*[2:0], DTV Simple mode */ + #define rbPaMSDtv4bitGpio 0x01 /*[2:0], DTV TS2 Serial mode)*/ + #define rbPaMSDtv7bitGpio 0x02 /*[2:0], DTV TS0 Serial mode*/ + #define rbPaMS8bitGpio 0x03 /*[2:0], GPIO mode selected;(8bit GPIO)*/ + #define rbPaMSAtv 0x04 /*[2:0], 3'b1xx: ATV mode select*/ + #define rbPbMSMask 0x38 + #define rbPbMSDtvNoGpio 0x00 /*[5:3], DTV Simple mode */ + #define rbPbMSDtv4bitGpio 0x08 /*[5:3], DTV TS2 Serial mode*/ + #define rbPbMSDtv7bitGpio 0x10 /*[5:3], DTV TS0 Serial mode*/ + #define rbPbMS8bitGpio 0x18 /*[5:3], GPIO mode selected;(8bit GPIO)*/ + #define rbPbMSAtv 0x20 /*[5:3], 3'b1xx: ATV mode select*/ + #define rbPaAESEN 0x40 /*[6], port A AES enable bit*/ + #define rbPbAESEN 0x80 /*[7], port B AES enable bit*/ + +#define INTERNAL_RST (SYSTEM_CONTROL_REG_BASE + 0x04) +#define PERIPHERAL_CTRL (SYSTEM_CONTROL_REG_BASE + 0x08) +#define GPIO_0to7_CTRL (SYSTEM_CONTROL_REG_BASE + 0x0C) +#define GPIO_8to15_CTRL (SYSTEM_CONTROL_REG_BASE + 0x10) +#define GPIO_16to24_CTRL (SYSTEM_CONTROL_REG_BASE + 0x14) +#define GPIO_INT_SRC_CFG (SYSTEM_CONTROL_REG_BASE + 0x18) +#define SYS_BUF_STATUS (SYSTEM_CONTROL_REG_BASE + 0x1C) +#define PCIE_IP_REG_ACS (SYSTEM_CONTROL_REG_BASE + 0x20) +#define PCIE_IP_REG_ACS_ADDR (SYSTEM_CONTROL_REG_BASE + 0x24) +#define PCIE_IP_REG_ACS_DATA (SYSTEM_CONTROL_REG_BASE + 0x28) + +/* -------- IR Control register -------- */ +#define IR_Init_Reg (IR_CONTROL_REG_BASE + 0x00) +#define IR_Idle_Cnt_Low (IR_CONTROL_REG_BASE + 0x04) +#define IR_Idle_Cnt_High (IR_CONTROL_REG_BASE + 0x05) +#define IR_Unit_Cnt_Low (IR_CONTROL_REG_BASE + 0x06) +#define IR_Unit_Cnt_High (IR_CONTROL_REG_BASE + 0x07) +#define IR_Data_Cnt (IR_CONTROL_REG_BASE + 0x08) +#define rbIRen 0x80 +#define rbIRhighidle 0x10 +#define rbIRlowidle 0x00 +#define rbIRVld 0x04 + +/* -------- I2C A control and state register -------- */ +#define I2C_A_CTL_STATUS (I2C_A_CONTROL_REG_BASE + 0x00) +#define I2C_A_ADDR (I2C_A_CONTROL_REG_BASE + 0x04) +#define I2C_A_SW_CTL (I2C_A_CONTROL_REG_BASE + 0x08) +#define I2C_A_TIME_OUT_CNT (I2C_A_CONTROL_REG_BASE + 0x0C) +#define I2C_A_FIFO_STATUS (I2C_A_CONTROL_REG_BASE + 0x10) +#define I2C_A_FS_EN (I2C_A_CONTROL_REG_BASE + 0x14) +#define I2C_A_FIFO_DATA (I2C_A_CONTROL_REG_BASE + 0x20) + +/* -------- I2C B control and state register -------- */ +#define I2C_B_CTL_STATUS (I2C_B_CONTROL_REG_BASE + 0x00) +#define I2C_B_ADDR (I2C_B_CONTROL_REG_BASE + 0x04) +#define I2C_B_SW_CTL (I2C_B_CONTROL_REG_BASE + 0x08) +#define I2C_B_TIME_OUT_CNT (I2C_B_CONTROL_REG_BASE + 0x0C) +#define I2C_B_FIFO_STATUS (I2C_B_CONTROL_REG_BASE + 0x10) +#define I2C_B_FS_EN (I2C_B_CONTROL_REG_BASE + 0x14) +#define I2C_B_FIFO_DATA (I2C_B_CONTROL_REG_BASE + 0x20) + +#define VIDEO_CTRL_STATUS_A (ATV_PORTA_CONTROL_REG_BASE + 0x04) + +/* -------- Digital TV control register, Port A -------- */ +#define MPEG2_CTRL_A (DTV_PORTA_CONTROL_REG_BASE + 0x00) +#define SERIAL_IN_ADDR_A (DTV_PORTA_CONTROL_REG_BASE + 0x4C) +#define VLD_CNT_ADDR_A (DTV_PORTA_CONTROL_REG_BASE + 0x60) +#define ERR_CNT_ADDR_A (DTV_PORTA_CONTROL_REG_BASE + 0x64) +#define BRD_CNT_ADDR_A (DTV_PORTA_CONTROL_REG_BASE + 0x68) + +/* -------- DMA Control Register, Port A -------- */ +#define DMA_PORTA_CHAN0_ADDR_LOW (DMA_PORTA_CONTROL_REG_BASE + 0x00) +#define DMA_PORTA_CHAN0_ADDR_HI (DMA_PORTA_CONTROL_REG_BASE + 0x04) +#define DMA_PORTA_CHAN0_TRANS_STATE (DMA_PORTA_CONTROL_REG_BASE + 0x08) +#define DMA_PORTA_CHAN0_CONTROL (DMA_PORTA_CONTROL_REG_BASE + 0x0C) +#define DMA_PORTA_CHAN1_ADDR_LOW (DMA_PORTA_CONTROL_REG_BASE + 0x10) +#define DMA_PORTA_CHAN1_ADDR_HI (DMA_PORTA_CONTROL_REG_BASE + 0x14) +#define DMA_PORTA_CHAN1_TRANS_STATE (DMA_PORTA_CONTROL_REG_BASE + 0x18) +#define DMA_PORTA_CHAN1_CONTROL (DMA_PORTA_CONTROL_REG_BASE + 0x1C) +#define DMA_PORTA_MANAGEMENT (DMA_PORTA_CONTROL_REG_BASE + 0x20) +#define VIDEO_CTRL_STATUS_B (ATV_PORTB_CONTROL_REG_BASE + 0x04) + +/* -------- Digital TV control register, Port B -------- */ +#define MPEG2_CTRL_B (DTV_PORTB_CONTROL_REG_BASE + 0x00) +#define SERIAL_IN_ADDR_B (DTV_PORTB_CONTROL_REG_BASE + 0x4C) +#define VLD_CNT_ADDR_B (DTV_PORTB_CONTROL_REG_BASE + 0x60) +#define ERR_CNT_ADDR_B (DTV_PORTB_CONTROL_REG_BASE + 0x64) +#define BRD_CNT_ADDR_B (DTV_PORTB_CONTROL_REG_BASE + 0x68) + +/* -------- AES control register, Port B -------- */ +#define AES_CTRL_B (AES_PORTB_CONTROL_REG_BASE + 0x00) +#define AES_KEY_BASE_B (AES_PORTB_CONTROL_REG_BASE + 0x04) + +/* -------- DMA Control Register, Port B -------- */ +#define DMA_PORTB_CHAN0_ADDR_LOW (DMA_PORTB_CONTROL_REG_BASE + 0x00) +#define DMA_PORTB_CHAN0_ADDR_HI (DMA_PORTB_CONTROL_REG_BASE + 0x04) +#define DMA_PORTB_CHAN0_TRANS_STATE (DMA_PORTB_CONTROL_REG_BASE + 0x08) +#define DMA_PORTB_CHAN0_CONTROL (DMA_PORTB_CONTROL_REG_BASE + 0x0C) +#define DMA_PORTB_CHAN1_ADDR_LOW (DMA_PORTB_CONTROL_REG_BASE + 0x10) +#define DMA_PORTB_CHAN1_ADDR_HI (DMA_PORTB_CONTROL_REG_BASE + 0x14) +#define DMA_PORTB_CHAN1_TRANS_STATE (DMA_PORTB_CONTROL_REG_BASE + 0x18) +#define DMA_PORTB_CHAN1_CONTROL (DMA_PORTB_CONTROL_REG_BASE + 0x1C) +#define DMA_PORTB_MANAGEMENT (DMA_PORTB_CONTROL_REG_BASE + 0x20) + +#define DMA_TRANS_UNIT_188 (0x00000007) + +/* -------- Macro define of 24 interrupt resource --------*/ +#define DMA_A_CHAN0_DONE_INT (0x00000001) +#define DMA_A_CHAN1_DONE_INT (0x00000002) +#define DMA_B_CHAN0_DONE_INT (0x00000004) +#define DMA_B_CHAN1_DONE_INT (0x00000008) +#define DMA_C_CHAN0_DONE_INT (0x00000010) +#define DMA_C_CHAN1_DONE_INT (0x00000020) +#define DMA_D_CHAN0_DONE_INT (0x00000040) +#define DMA_D_CHAN1_DONE_INT (0x00000080) +#define DATA_BUF_OVERFLOW_INT (0x00000100) +#define UART_0_X_INT (0x00000200) +#define UART_1_X_INT (0x00000400) +#define IR_X_INT (0x00000800) +#define GPIO_0_INT (0x00001000) +#define GPIO_1_INT (0x00002000) +#define GPIO_2_INT (0x00004000) +#define GPIO_3_INT (0x00008000) +#define ALL_INT (0x0000FFFF) + +/* software I2C bit mask */ +#define SW_I2C_MSK_MODE 0x01 +#define SW_I2C_MSK_CLK_OUT 0x02 +#define SW_I2C_MSK_DAT_OUT 0x04 +#define SW_I2C_MSK_CLK_EN 0x08 +#define SW_I2C_MSK_DAT_EN 0x10 +#define SW_I2C_MSK_DAT_IN 0x40 +#define SW_I2C_MSK_CLK_IN 0x80 + +#define SMI_VID 0x1ADE +#define SMI_PID 0x3038 +#define SMI_TS_DMA_BUF_SIZE (1024 * 188) + +struct smi_cfg_info { +#define SMI_DVBSKY_S952 0 +#define SMI_DVBSKY_S950 1 +#define SMI_DVBSKY_T9580 2 +#define SMI_DVBSKY_T982 3 + int type; + char *name; +#define SMI_TS_NULL 0 +#define SMI_TS_DMA_SINGLE 1 +#define SMI_TS_DMA_BOTH 3 +/* SMI_TS_NULL: not use; + * SMI_TS_DMA_SINGLE: use DMA 0 only; + * SMI_TS_DMA_BOTH:use DMA 0 and 1.*/ + int ts_0; + int ts_1; +#define DVBSKY_FE_NULL 0 +#define DVBSKY_FE_M88RS6000 1 +#define DVBSKY_FE_M88DS3103 2 +#define DVBSKY_FE_SIT2 3 + int fe_0; + int fe_1; +}; + +struct smi_port { + struct smi_dev *dev; + int idx; + int enable; + int fe_type; + /* regs */ + u32 DMA_CHAN0_ADDR_LOW; + u32 DMA_CHAN0_ADDR_HI; + u32 DMA_CHAN0_TRANS_STATE; + u32 DMA_CHAN0_CONTROL; + u32 DMA_CHAN1_ADDR_LOW; + u32 DMA_CHAN1_ADDR_HI; + u32 DMA_CHAN1_TRANS_STATE; + u32 DMA_CHAN1_CONTROL; + u32 DMA_MANAGEMENT; + /* dma */ + dma_addr_t dma_addr[2]; + u8 *cpu_addr[2]; + u32 _dmaInterruptCH0; + u32 _dmaInterruptCH1; + u32 _int_status; + struct tasklet_struct tasklet; + /* dvb */ + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; + struct dmxdev dmxdev; + struct dvb_adapter dvb_adapter; + struct dvb_demux demux; + struct dvb_net dvbnet; + int users; + struct dvb_frontend *fe; + /* frontend i2c module */ + struct i2c_client *i2c_client_demod; + struct i2c_client *i2c_client_tuner; +}; + +struct smi_dev { + int nr; + struct smi_cfg_info *info; + + /* pcie */ + struct pci_dev *pci_dev; + u32 __iomem *lmmio; + + /* ts port */ + struct smi_port ts_port[2]; + + /* i2c */ + struct i2c_adapter i2c_bus[2]; + struct i2c_algo_bit_data i2c_bit[2]; +}; + +#define smi_read(reg) readl(dev->lmmio + ((reg)>>2)) +#define smi_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) + +#define smi_andor(reg, mask, value) \ + writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ + ((value) & (mask)), dev->lmmio+((reg)>>2)) + +#define smi_set(reg, bit) smi_andor((reg), (bit), (bit)) +#define smi_clear(reg, bit) smi_andor((reg), (bit), 0) + +#endif /* #ifndef _SMI_PCIE_H_ */ -- GitLab From 232228763bccffef3d1d40c03ee691e713b81120 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Nov 2014 18:13:33 -0200 Subject: [PATCH 2694/9457] [media] smipcie: fix two small CodingStyle issues Fix two small CodingStyle issues Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/smipcie/smipcie.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 3522da4fa5d9..6ad6cc5c33b1 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -499,8 +499,8 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) struct i2c_client *tuner_client; struct i2c_board_info tuner_info; struct m88ts2022_config m88ts2022_config = { - .clock = 27000000, - }; + .clock = 27000000, + }; memset(&tuner_info, 0, sizeof(struct i2c_board_info)); i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; @@ -639,7 +639,7 @@ static u32 smi_config_DMA(struct smi_port *port) u64 mem; dmaManagement = smi_read(port->DMA_MANAGEMENT); - /* Setup Channel-0 */ + /* Setup Channel-0 */ if (port->_dmaInterruptCH0) { totalLength = SMI_TS_DMA_BUF_SIZE; mem = port->dma_addr[0]; -- GitLab From 946e51f2bf37f1656916eb75bd0742ba33983c28 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Oct 2014 19:19:16 -0400 Subject: [PATCH 2695/9457] move d_rcu from overlapping d_child to overlapping d_alias Signed-off-by: Al Viro --- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- drivers/staging/lustre/lustre/llite/dcache.c | 2 +- .../staging/lustre/lustre/llite/llite_lib.c | 2 +- drivers/staging/lustre/lustre/llite/namei.c | 8 +-- fs/affs/amigaffs.c | 2 +- fs/autofs4/expire.c | 12 ++--- fs/autofs4/root.c | 2 +- fs/ceph/dir.c | 8 +-- fs/ceph/inode.c | 2 +- fs/cifs/inode.c | 2 +- fs/coda/cache.c | 2 +- fs/dcache.c | 53 +++++++++---------- fs/debugfs/inode.c | 2 +- fs/exportfs/expfs.c | 2 +- fs/libfs.c | 12 ++--- fs/ncpfs/dir.c | 2 +- fs/ncpfs/ncplib_kernel.h | 4 +- fs/nfs/getroot.c | 2 +- fs/notify/fsnotify.c | 4 +- fs/ocfs2/dcache.c | 2 +- include/linux/dcache.h | 8 +-- kernel/trace/trace.c | 4 +- kernel/trace/trace_events.c | 2 +- security/selinux/selinuxfs.c | 6 +-- 24 files changed, 73 insertions(+), 74 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 87ba7cf99cd7..65d633f20d37 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentry *dir) struct dentry *dentry, *tmp; mutex_lock(&dir->d_inode->i_mutex); - list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { + list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { spin_lock(&dentry->d_lock); if (!(d_unhashed(dentry)) && dentry->d_inode) { dget_dlock(dentry); diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 439e4875b05c..311907b762bd 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -258,7 +258,7 @@ void ll_invalidate_aliases(struct inode *inode) inode->i_ino, inode->i_generation, inode); ll_lock_dcache(inode); - ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) { CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p " "inode %p flags %d\n", dentry->d_name.len, dentry->d_name.name, dentry, dentry->d_parent, diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index a8bcc51057f1..f4ca7b753021 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -711,7 +711,7 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) return; list_for_each(tmp, &dentry->d_subdirs) { - struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child); + struct dentry *d = list_entry(tmp, struct dentry, d_child); lustre_dump_dentry(d, recur - 1); } } diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 7a68c1e027e0..6dfd98509268 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -167,14 +167,14 @@ static void ll_invalidate_negative_children(struct inode *dir) struct ll_d_hlist_node *p; ll_lock_dcache(dir); - ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_u.d_alias) { spin_lock(&dentry->d_lock); if (!list_empty(&dentry->d_subdirs)) { struct dentry *child; list_for_each_entry_safe(child, tmp_subdir, &dentry->d_subdirs, - d_u.d_child) { + d_child) { if (child->d_inode == NULL) d_lustre_invalidate(child, 1); } @@ -362,7 +362,7 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry) discon_alias = invalid_alias = NULL; ll_lock_dcache(inode); - ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_u.d_alias) { LASSERT(alias != dentry); spin_lock(&alias->d_lock); @@ -953,7 +953,7 @@ static void ll_get_child_fid(struct inode * dir, struct qstr *name, { struct dentry *parent, *child; - parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias); + parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_u.d_alias); child = d_lookup(parent, name); if (child) { if (child->d_inode) diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index abc853968fed..937ce8754b24 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c @@ -125,7 +125,7 @@ affs_fix_dcache(struct inode *inode, u32 entry_ino) { struct dentry *dentry; spin_lock(&inode->i_lock); - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { if (entry_ino == (u32)(long)dentry->d_fsdata) { dentry->d_fsdata = (void *)inode->i_ino; break; diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 683a5b9ce22a..dcdec6fd33c6 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -85,7 +85,7 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev, spin_lock(&root->d_lock); if (prev) - next = prev->d_u.d_child.next; + next = prev->d_child.next; else { prev = dget_dlock(root); next = prev->d_subdirs.next; @@ -99,13 +99,13 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev, return NULL; } - q = list_entry(next, struct dentry, d_u.d_child); + q = list_entry(next, struct dentry, d_child); spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); /* Already gone or negative dentry (under construction) - try next */ if (!d_count(q) || !simple_positive(q)) { spin_unlock(&q->d_lock); - next = q->d_u.d_child.next; + next = q->d_child.next; goto cont; } dget_dlock(q); @@ -155,13 +155,13 @@ static struct dentry *get_next_positive_dentry(struct dentry *prev, goto relock; } spin_unlock(&p->d_lock); - next = p->d_u.d_child.next; + next = p->d_child.next; p = parent; if (next != &parent->d_subdirs) break; } } - ret = list_entry(next, struct dentry, d_u.d_child); + ret = list_entry(next, struct dentry, d_child); spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED); /* Negative dentry - try next */ @@ -489,7 +489,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, spin_lock(&sbi->lookup_lock); spin_lock(&expired->d_parent->d_lock); spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); - list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); + list_move(&expired->d_parent->d_subdirs, &expired->d_child); spin_unlock(&expired->d_lock); spin_unlock(&expired->d_parent->d_lock); spin_unlock(&sbi->lookup_lock); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index d76d083f2f06..0822c9eacc56 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -687,7 +687,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry) /* only consider parents below dentrys in the root */ if (IS_ROOT(parent->d_parent)) return; - d_child = &dentry->d_u.d_child; + d_child = &dentry->d_child; /* Set parent managed if it's becoming empty */ if (d_child->next == &parent->d_subdirs && d_child->prev == &parent->d_subdirs) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index e6d63f8f98c0..695e7888fef8 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -111,7 +111,7 @@ static int fpos_cmp(loff_t l, loff_t r) /* * When possible, we try to satisfy a readdir by peeking at the * dcache. We make this work by carefully ordering dentries on - * d_u.d_child when we initially get results back from the MDS, and + * d_child when we initially get results back from the MDS, and * falling back to a "normal" sync readdir if any dentries in the dir * are dropped. * @@ -147,11 +147,11 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, p = parent->d_subdirs.prev; dout(" initial p %p/%p\n", p->prev, p->next); } else { - p = last->d_u.d_child.prev; + p = last->d_child.prev; } more: - dentry = list_entry(p, struct dentry, d_u.d_child); + dentry = list_entry(p, struct dentry, d_child); di = ceph_dentry(dentry); while (1) { dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next, @@ -174,7 +174,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, !dentry->d_inode ? " null" : ""); spin_unlock(&dentry->d_lock); p = p->prev; - dentry = list_entry(p, struct dentry, d_u.d_child); + dentry = list_entry(p, struct dentry, d_child); di = ceph_dentry(dentry); } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 7b6139004401..7a1df90c7771 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1399,7 +1399,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, /* reorder parent's d_subdirs */ spin_lock(&parent->d_lock); spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); - list_move(&dn->d_u.d_child, &parent->d_subdirs); + list_move(&dn->d_child, &parent->d_subdirs); spin_unlock(&dn->d_lock); spin_unlock(&parent->d_lock); } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 197cb503d528..0c3ce464cae4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -895,7 +895,7 @@ inode_has_hashed_dentries(struct inode *inode) struct dentry *dentry; spin_lock(&inode->i_lock); - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { if (!d_unhashed(dentry) || IS_ROOT(dentry)) { spin_unlock(&inode->i_lock); return true; diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 278f8fdeb9ef..46ee6f238985 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -92,7 +92,7 @@ static void coda_flag_children(struct dentry *parent, int flag) struct dentry *de; spin_lock(&parent->d_lock); - list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) { + list_for_each_entry(de, &parent->d_subdirs, d_child) { /* don't know what to do with negative dentries */ if (de->d_inode ) coda_flag_inode(de->d_inode, flag); diff --git a/fs/dcache.c b/fs/dcache.c index 3ffef7f4e5cd..8b4c45e40834 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -44,7 +44,7 @@ /* * Usage: * dcache->d_inode->i_lock protects: - * - i_dentry, d_alias, d_inode of aliases + * - i_dentry, d_u.d_alias, d_inode of aliases * dcache_hash_bucket lock protects: * - the dcache hash table * s_anon bl list spinlock protects: @@ -59,7 +59,7 @@ * - d_unhashed() * - d_parent and d_subdirs * - childrens' d_child and d_parent - * - d_alias, d_inode + * - d_u.d_alias, d_inode * * Ordering: * dentry->d_inode->i_lock @@ -252,14 +252,12 @@ static void __d_free(struct rcu_head *head) { struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); - WARN_ON(!hlist_unhashed(&dentry->d_alias)); kmem_cache_free(dentry_cache, dentry); } static void __d_free_external(struct rcu_head *head) { struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); - WARN_ON(!hlist_unhashed(&dentry->d_alias)); kfree(external_name(dentry)); kmem_cache_free(dentry_cache, dentry); } @@ -271,6 +269,7 @@ static inline int dname_external(const struct dentry *dentry) static void dentry_free(struct dentry *dentry) { + WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias)); if (unlikely(dname_external(dentry))) { struct external_name *p = external_name(dentry); if (likely(atomic_dec_and_test(&p->u.count))) { @@ -311,7 +310,7 @@ static void dentry_iput(struct dentry * dentry) struct inode *inode = dentry->d_inode; if (inode) { dentry->d_inode = NULL; - hlist_del_init(&dentry->d_alias); + hlist_del_init(&dentry->d_u.d_alias); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); if (!inode->i_nlink) @@ -336,7 +335,7 @@ static void dentry_unlink_inode(struct dentry * dentry) struct inode *inode = dentry->d_inode; __d_clear_type(dentry); dentry->d_inode = NULL; - hlist_del_init(&dentry->d_alias); + hlist_del_init(&dentry->d_u.d_alias); dentry_rcuwalk_barrier(dentry); spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); @@ -496,7 +495,7 @@ static void __dentry_kill(struct dentry *dentry) } /* if it was on the hash then remove it */ __d_drop(dentry); - list_del(&dentry->d_u.d_child); + list_del(&dentry->d_child); /* * Inform d_walk() that we are no longer attached to the * dentry tree @@ -722,7 +721,7 @@ static struct dentry *__d_find_alias(struct inode *inode) again: discon_alias = NULL; - hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { + hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { spin_lock(&alias->d_lock); if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { if (IS_ROOT(alias) && @@ -772,7 +771,7 @@ void d_prune_aliases(struct inode *inode) struct dentry *dentry; restart: spin_lock(&inode->i_lock); - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { spin_lock(&dentry->d_lock); if (!dentry->d_lockref.count) { struct dentry *parent = lock_parent(dentry); @@ -1050,7 +1049,7 @@ static void d_walk(struct dentry *parent, void *data, resume: while (next != &this_parent->d_subdirs) { struct list_head *tmp = next; - struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); + struct dentry *dentry = list_entry(tmp, struct dentry, d_child); next = tmp->next; spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); @@ -1102,7 +1101,7 @@ static void d_walk(struct dentry *parent, void *data, goto rename_retry; } rcu_read_unlock(); - next = child->d_u.d_child.next; + next = child->d_child.next; goto resume; } if (need_seqretry(&rename_lock, seq)) { @@ -1454,8 +1453,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) INIT_HLIST_BL_NODE(&dentry->d_hash); INIT_LIST_HEAD(&dentry->d_lru); INIT_LIST_HEAD(&dentry->d_subdirs); - INIT_HLIST_NODE(&dentry->d_alias); - INIT_LIST_HEAD(&dentry->d_u.d_child); + INIT_HLIST_NODE(&dentry->d_u.d_alias); + INIT_LIST_HEAD(&dentry->d_child); d_set_d_op(dentry, dentry->d_sb->s_d_op); this_cpu_inc(nr_dentry); @@ -1485,7 +1484,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) */ __dget_dlock(parent); dentry->d_parent = parent; - list_add(&dentry->d_u.d_child, &parent->d_subdirs); + list_add(&dentry->d_child, &parent->d_subdirs); spin_unlock(&parent->d_lock); return dentry; @@ -1578,7 +1577,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) spin_lock(&dentry->d_lock); __d_set_type(dentry, add_flags); if (inode) - hlist_add_head(&dentry->d_alias, &inode->i_dentry); + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); dentry->d_inode = inode; dentry_rcuwalk_barrier(dentry); spin_unlock(&dentry->d_lock); @@ -1602,7 +1601,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) void d_instantiate(struct dentry *entry, struct inode * inode) { - BUG_ON(!hlist_unhashed(&entry->d_alias)); + BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); if (inode) spin_lock(&inode->i_lock); __d_instantiate(entry, inode); @@ -1641,7 +1640,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, return NULL; } - hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { + hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { /* * Don't need alias->d_lock here, because aliases with * d_parent == entry->d_parent are not subject to name or @@ -1667,7 +1666,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) { struct dentry *result; - BUG_ON(!hlist_unhashed(&entry->d_alias)); + BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); if (inode) spin_lock(&inode->i_lock); @@ -1698,7 +1697,7 @@ EXPORT_SYMBOL(d_instantiate_unique); */ int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) { - BUG_ON(!hlist_unhashed(&entry->d_alias)); + BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); spin_lock(&inode->i_lock); if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { @@ -1737,7 +1736,7 @@ static struct dentry * __d_find_any_alias(struct inode *inode) if (hlist_empty(&inode->i_dentry)) return NULL; - alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); + alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); __dget(alias); return alias; } @@ -1799,7 +1798,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) spin_lock(&tmp->d_lock); tmp->d_inode = inode; tmp->d_flags |= add_flags; - hlist_add_head(&tmp->d_alias, &inode->i_dentry); + hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); hlist_bl_lock(&tmp->d_sb->s_anon); hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); hlist_bl_unlock(&tmp->d_sb->s_anon); @@ -2234,7 +2233,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent) struct dentry *child; spin_lock(&dparent->d_lock); - list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { + list_for_each_entry(child, &dparent->d_subdirs, d_child) { if (dentry == child) { spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); __dget_dlock(dentry); @@ -2525,13 +2524,13 @@ static void __d_move(struct dentry *dentry, struct dentry *target, /* splicing a tree */ dentry->d_parent = target->d_parent; target->d_parent = target; - list_del_init(&target->d_u.d_child); - list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); + list_del_init(&target->d_child); + list_move(&dentry->d_child, &dentry->d_parent->d_subdirs); } else { /* swapping two dentries */ swap(dentry->d_parent, target->d_parent); - list_move(&target->d_u.d_child, &target->d_parent->d_subdirs); - list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); + list_move(&target->d_child, &target->d_parent->d_subdirs); + list_move(&dentry->d_child, &dentry->d_parent->d_subdirs); if (exchange) fsnotify_d_move(target); fsnotify_d_move(dentry); @@ -3320,7 +3319,7 @@ void d_tmpfile(struct dentry *dentry, struct inode *inode) { inode_dec_link_count(inode); BUG_ON(dentry->d_name.name != dentry->d_iname || - !hlist_unhashed(&dentry->d_alias) || + !hlist_unhashed(&dentry->d_u.d_alias) || !d_unlinked(dentry)); spin_lock(&dentry->d_parent->d_lock); spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 1e3b99d3db0d..05f2960ed7c3 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -553,7 +553,7 @@ void debugfs_remove_recursive(struct dentry *dentry) * use the d_u.d_child as the rcu head and corrupt this list. */ spin_lock(&parent->d_lock); - list_for_each_entry(child, &parent->d_subdirs, d_u.d_child) { + list_for_each_entry(child, &parent->d_subdirs, d_child) { if (!debugfs_positive(child)) continue; diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index a2b350ddd402..fdfd206c737a 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -50,7 +50,7 @@ find_acceptable_alias(struct dentry *result, inode = result->d_inode; spin_lock(&inode->i_lock); - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { dget(dentry); spin_unlock(&inode->i_lock); if (toput) diff --git a/fs/libfs.c b/fs/libfs.c index 171d2846f2a3..005843ce5dbd 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -114,18 +114,18 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence) spin_lock(&dentry->d_lock); /* d_lock not required for cursor */ - list_del(&cursor->d_u.d_child); + list_del(&cursor->d_child); p = dentry->d_subdirs.next; while (n && p != &dentry->d_subdirs) { struct dentry *next; - next = list_entry(p, struct dentry, d_u.d_child); + next = list_entry(p, struct dentry, d_child); spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(next)) n--; spin_unlock(&next->d_lock); p = p->next; } - list_add_tail(&cursor->d_u.d_child, p); + list_add_tail(&cursor->d_child, p); spin_unlock(&dentry->d_lock); } } @@ -150,7 +150,7 @@ int dcache_readdir(struct file *file, struct dir_context *ctx) { struct dentry *dentry = file->f_path.dentry; struct dentry *cursor = file->private_data; - struct list_head *p, *q = &cursor->d_u.d_child; + struct list_head *p, *q = &cursor->d_child; if (!dir_emit_dots(file, ctx)) return 0; @@ -159,7 +159,7 @@ int dcache_readdir(struct file *file, struct dir_context *ctx) list_move(q, &dentry->d_subdirs); for (p = q->next; p != &dentry->d_subdirs; p = p->next) { - struct dentry *next = list_entry(p, struct dentry, d_u.d_child); + struct dentry *next = list_entry(p, struct dentry, d_child); spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); if (!simple_positive(next)) { spin_unlock(&next->d_lock); @@ -287,7 +287,7 @@ int simple_empty(struct dentry *dentry) int ret = 0; spin_lock(&dentry->d_lock); - list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) { + list_for_each_entry(child, &dentry->d_subdirs, d_child) { spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); if (simple_positive(child)) { spin_unlock(&child->d_lock); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 461f6be5df20..865d578704c8 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -403,7 +403,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) /* If a pointer is invalid, we search the dentry. */ spin_lock(&parent->d_lock); - list_for_each_entry(dent, &parent->d_subdirs, d_u.d_child) { + list_for_each_entry(dent, &parent->d_subdirs, d_child) { if ((unsigned long)dent->d_fsdata == fpos) { if (dent->d_inode) dget(dent); diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 52cb19d66ecb..b785f74bfe3c 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -191,7 +191,7 @@ ncp_renew_dentries(struct dentry *parent) struct dentry *dentry; spin_lock(&parent->d_lock); - list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { + list_for_each_entry(dentry, &parent->d_subdirs, d_child) { if (dentry->d_fsdata == NULL) ncp_age_dentry(server, dentry); else @@ -207,7 +207,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent) struct dentry *dentry; spin_lock(&parent->d_lock); - list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { + list_for_each_entry(dentry, &parent->d_subdirs, d_child) { dentry->d_fsdata = NULL; ncp_age_dentry(server, dentry); } diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 880618a8b048..ebc6a0add5ae 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -58,7 +58,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i */ spin_lock(&sb->s_root->d_inode->i_lock); spin_lock(&sb->s_root->d_lock); - hlist_del_init(&sb->s_root->d_alias); + hlist_del_init(&sb->s_root->d_u.d_alias); spin_unlock(&sb->s_root->d_lock); spin_unlock(&sb->s_root->d_inode->i_lock); } diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 9d3e9c50066a..700129940c6e 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) spin_lock(&inode->i_lock); /* run all of the dentries associated with this inode. Since this is a * directory, there damn well better only be one item on this list */ - hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { + hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { struct dentry *child; /* run all of the children of the original inode and fix their * d_flags to indicate parental interest (their parent is the * original inode) */ spin_lock(&alias->d_lock); - list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { + list_for_each_entry(child, &alias->d_subdirs, d_child) { if (!child->d_inode) continue; diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index e2e05a106beb..92edcfc23c1c 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c @@ -172,7 +172,7 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, struct dentry *dentry; spin_lock(&inode->i_lock); - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { spin_lock(&dentry->d_lock); if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { trace_ocfs2_find_local_alias(dentry->d_name.len, diff --git a/include/linux/dcache.h b/include/linux/dcache.h index b2a2a08523bf..1c2f1b84468b 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -124,15 +124,15 @@ struct dentry { void *d_fsdata; /* fs-specific data */ struct list_head d_lru; /* LRU list */ + struct list_head d_child; /* child of parent list */ + struct list_head d_subdirs; /* our children */ /* - * d_child and d_rcu can share memory + * d_alias and d_rcu can share memory */ union { - struct list_head d_child; /* child of parent list */ + struct hlist_node d_alias; /* inode alias list */ struct rcu_head d_rcu; } d_u; - struct list_head d_subdirs; /* our children */ - struct hlist_node d_alias; /* inode alias list */ }; /* diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8a528392b1f4..459a7b1251e5 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6420,7 +6420,7 @@ static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t m int ret; /* Paranoid: Make sure the parent is the "instances" directory */ - parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); + parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); if (WARN_ON_ONCE(parent != trace_instance_dir)) return -ENOENT; @@ -6447,7 +6447,7 @@ static int instance_rmdir(struct inode *inode, struct dentry *dentry) int ret; /* Paranoid: Make sure the parent is the "instances" directory */ - parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); + parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); if (WARN_ON_ONCE(parent != trace_instance_dir)) return -ENOENT; diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 0cc51edde3a8..1b0df1e504f0 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -461,7 +461,7 @@ static void remove_event_file_dir(struct ftrace_event_file *file) if (dir) { spin_lock(&dir->d_lock); /* probably unneeded */ - list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) { + list_for_each_entry(child, &dir->d_subdirs, d_child) { if (child->d_inode) /* probably unneeded */ child->d_inode->i_private = NULL; } diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index c71737f6d1cc..33db1ad4fd10 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -1200,7 +1200,7 @@ static void sel_remove_entries(struct dentry *de) spin_lock(&de->d_lock); node = de->d_subdirs.next; while (node != &de->d_subdirs) { - struct dentry *d = list_entry(node, struct dentry, d_u.d_child); + struct dentry *d = list_entry(node, struct dentry, d_child); spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); list_del_init(node); @@ -1674,12 +1674,12 @@ static void sel_remove_classes(void) list_for_each(class_node, &class_dir->d_subdirs) { struct dentry *class_subdir = list_entry(class_node, - struct dentry, d_u.d_child); + struct dentry, d_child); struct list_head *class_subdir_node; list_for_each(class_subdir_node, &class_subdir->d_subdirs) { struct dentry *d = list_entry(class_subdir_node, - struct dentry, d_u.d_child); + struct dentry, d_child); if (d->d_inode) if (d->d_inode->i_mode & S_IFDIR) -- GitLab From 48eddfd5ca591d2bd97594afd58cffa6b5a48ef4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 7 May 2014 21:24:47 -0400 Subject: [PATCH 2696/9457] lustre: switch ll_intent_file_open() to struct dentry * ... because fake struct file is wrong. ll_prep_inode() in there is an atrocity - despite passing a pointer to inode by address, it actually only uses the value when that value is non-NULL, as it will be here. Oh, and ->d_parent of anything is never NULL. Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/file.c | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index c99b74117152..382b53a8ce62 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -394,21 +394,19 @@ int ll_file_release(struct inode *inode, struct file *file) return rc; } -static int ll_intent_file_open(struct file *file, void *lmm, +static int ll_intent_file_open(struct dentry *dentry, void *lmm, int lmmsize, struct lookup_intent *itp) { - struct ll_sb_info *sbi = ll_i2sbi(file->f_dentry->d_inode); - struct dentry *parent = file->f_dentry->d_parent; - const char *name = file->f_dentry->d_name.name; - const int len = file->f_dentry->d_name.len; + struct inode *inode = dentry->d_inode; + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct dentry *parent = dentry->d_parent; + const char *name = dentry->d_name.name; + const int len = dentry->d_name.len; struct md_op_data *op_data; struct ptlrpc_request *req; __u32 opc = LUSTRE_OPC_ANY; int rc; - if (!parent) - return -ENOENT; - /* Usually we come here only for NFSD, and we want open lock. But we can also get here with pre 2.6.15 patchless kernels, and in that case that lock is also ok */ @@ -425,7 +423,7 @@ static int ll_intent_file_open(struct file *file, void *lmm, } op_data = ll_prep_md_op_data(NULL, parent->d_inode, - file->f_dentry->d_inode, name, len, + inode, name, len, O_RDWR, opc, NULL); if (IS_ERR(op_data)) return PTR_ERR(op_data); @@ -441,7 +439,7 @@ static int ll_intent_file_open(struct file *file, void *lmm, if (!it_disposition(itp, DISP_OPEN_OPEN) || it_open_error(DISP_OPEN_OPEN, itp)) goto out; - ll_release_openhandle(file->f_dentry, itp); + ll_release_openhandle(dentry, itp); goto out; } @@ -456,10 +454,9 @@ static int ll_intent_file_open(struct file *file, void *lmm, goto out; } - rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL, itp); + rc = ll_prep_inode(&inode, req, NULL, itp); if (!rc && itp->d.lustre.it_lock_mode) - ll_set_lock_data(sbi->ll_md_exp, file->f_dentry->d_inode, - itp, NULL); + ll_set_lock_data(sbi->ll_md_exp, inode, itp, NULL); out: ptlrpc_req_finished(req); @@ -652,7 +649,7 @@ int ll_file_open(struct inode *inode, struct file *file) result in a deadlock */ mutex_unlock(&lli->lli_och_mutex); it->it_create_mode |= M_CHECK_STALE; - rc = ll_intent_file_open(file, NULL, 0, it); + rc = ll_intent_file_open(file->f_path.dentry, NULL, 0, it); it->it_create_mode &= ~M_CHECK_STALE; if (rc) goto out_openerr; @@ -1371,7 +1368,7 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file, } ll_inode_size_lock(inode); - rc = ll_intent_file_open(file, lum, lum_size, &oit); + rc = ll_intent_file_open(file->f_path.dentry, lum, lum_size, &oit); if (rc) goto out_unlock; rc = oit.d.lustre.it_status; -- GitLab From c139f3cef36291902d7a29a334acd25a1251cd9d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 May 2014 10:05:18 -0400 Subject: [PATCH 2697/9457] ll_setxattr(): get rid of struct file on stack Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/file.c | 15 +++++++++------ .../staging/lustre/lustre/llite/llite_internal.h | 2 +- drivers/staging/lustre/lustre/llite/xattr.c | 5 +---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 382b53a8ce62..3f00a40cf387 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1351,7 +1351,7 @@ static int ll_lov_recreate_fid(struct inode *inode, unsigned long arg) return ll_lov_recreate(inode, &oi, ost_idx); } -int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file, +int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, int flags, struct lov_user_md *lum, int lum_size) { struct lov_stripe_md *lsm = NULL; @@ -1368,21 +1368,20 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file, } ll_inode_size_lock(inode); - rc = ll_intent_file_open(file->f_path.dentry, lum, lum_size, &oit); + rc = ll_intent_file_open(dentry, lum, lum_size, &oit); if (rc) goto out_unlock; rc = oit.d.lustre.it_status; if (rc < 0) goto out_req_free; - ll_release_openhandle(file->f_dentry, &oit); + ll_release_openhandle(dentry, &oit); out_unlock: ll_inode_size_unlock(inode); ll_intent_release(&oit); ccc_inode_lsm_put(inode, lsm); out: - cl_lov_delay_create_clear(&file->f_flags); return rc; out_req_free: ptlrpc_req_finished((struct ptlrpc_request *) oit.d.lustre.it_data); @@ -1496,7 +1495,9 @@ static int ll_lov_setea(struct inode *inode, struct file *file, return -EFAULT; } - rc = ll_lov_setstripe_ea_info(inode, file, flags, lump, lum_size); + rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, lump, + lum_size); + cl_lov_delay_create_clear(&file->f_flags); OBD_FREE_LARGE(lump, lum_size); return rc; @@ -1523,7 +1524,9 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file, return -EFAULT; } - rc = ll_lov_setstripe_ea_info(inode, file, flags, lumv1, lum_size); + rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, lumv1, + lum_size); + cl_lov_delay_create_clear(&file->f_flags); if (rc == 0) { struct lov_stripe_md *lsm; __u32 gen; diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 36aa0fd147f2..4b80a6f0c2f7 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -763,7 +763,7 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type); int ll_inode_permission(struct inode *inode, int mask); -int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file, +int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, int flags, struct lov_user_md *lum, int lum_size); int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 252a6194ed9b..5ad5e7b310c4 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -241,14 +241,11 @@ int ll_setxattr(struct dentry *dentry, const char *name, lump->lmm_stripe_offset = -1; if (lump != NULL && S_ISREG(inode->i_mode)) { - struct file f; int flags = FMODE_WRITE; int lum_size = (lump->lmm_magic == LOV_USER_MAGIC_V1) ? sizeof(*lump) : sizeof(struct lov_user_md_v3); - memset(&f, 0, sizeof(f)); /* f.f_flags is used below */ - f.f_dentry = dentry; - rc = ll_lov_setstripe_ea_info(inode, &f, flags, lump, + rc = ll_lov_setstripe_ea_info(inode, dentry, flags, lump, lum_size); /* b10667: rc always be 0 here for now */ rc = 0; -- GitLab From 74d01958a7ebca8c018ce03090eccb3b15ae8635 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 7 May 2014 20:55:28 -0400 Subject: [PATCH 2698/9457] lustre: opened file can't have negative dentry ... and ll_md_close() gets inode already equal to file_inode(file), along with ll_file_release() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/file.c | 51 +++++++++------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 3f00a40cf387..c3be2f26dfa3 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -266,6 +266,10 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode, { struct ll_file_data *fd = LUSTRE_FPRIVATE(file); struct ll_inode_info *lli = ll_i2info(inode); + int lockmode; + __u64 flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK; + struct lustre_handle lockh; + ldlm_policy_data_t policy = {.l_inodebits={MDS_INODELOCK_OPEN}}; int rc = 0; /* clear group lock, if present */ @@ -292,39 +296,26 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode, /* Let's see if we have good enough OPEN lock on the file and if we can skip talking to MDS */ - if (file->f_dentry->d_inode) { /* Can this ever be false? */ - int lockmode; - __u64 flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK; - struct lustre_handle lockh; - struct inode *inode = file->f_dentry->d_inode; - ldlm_policy_data_t policy = {.l_inodebits={MDS_INODELOCK_OPEN}}; - - mutex_lock(&lli->lli_och_mutex); - if (fd->fd_omode & FMODE_WRITE) { - lockmode = LCK_CW; - LASSERT(lli->lli_open_fd_write_count); - lli->lli_open_fd_write_count--; - } else if (fd->fd_omode & FMODE_EXEC) { - lockmode = LCK_PR; - LASSERT(lli->lli_open_fd_exec_count); - lli->lli_open_fd_exec_count--; - } else { - lockmode = LCK_CR; - LASSERT(lli->lli_open_fd_read_count); - lli->lli_open_fd_read_count--; - } - mutex_unlock(&lli->lli_och_mutex); - if (!md_lock_match(md_exp, flags, ll_inode2fid(inode), - LDLM_IBITS, &policy, lockmode, - &lockh)) { - rc = ll_md_real_close(file->f_dentry->d_inode, - fd->fd_omode); - } + mutex_lock(&lli->lli_och_mutex); + if (fd->fd_omode & FMODE_WRITE) { + lockmode = LCK_CW; + LASSERT(lli->lli_open_fd_write_count); + lli->lli_open_fd_write_count--; + } else if (fd->fd_omode & FMODE_EXEC) { + lockmode = LCK_PR; + LASSERT(lli->lli_open_fd_exec_count); + lli->lli_open_fd_exec_count--; } else { - CERROR("Releasing a file %p with negative dentry %p. Name %s", - file, file->f_dentry, file->f_dentry->d_name.name); + lockmode = LCK_CR; + LASSERT(lli->lli_open_fd_read_count); + lli->lli_open_fd_read_count--; } + mutex_unlock(&lli->lli_och_mutex); + + if (!md_lock_match(md_exp, flags, ll_inode2fid(inode), + LDLM_IBITS, &policy, lockmode, &lockh)) + rc = ll_md_real_close(inode, fd->fd_omode); out: LUSTRE_FPRIVATE(file) = NULL; -- GitLab From 09561a53b50d34af4a6a701c8199d915da2cec66 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 7 May 2014 21:10:24 -0400 Subject: [PATCH 2699/9457] lustre: use %p[dD] Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/dcache.c | 19 +++++------ drivers/staging/lustre/lustre/llite/file.c | 8 ++--- .../lustre/lustre/llite/llite_internal.h | 4 +-- .../staging/lustre/lustre/llite/llite_lib.c | 6 ++-- drivers/staging/lustre/lustre/llite/namei.c | 24 +++++++------- .../staging/lustre/lustre/llite/statahead.c | 33 +++++++++---------- drivers/staging/lustre/lustre/llite/xattr.c | 4 +-- 7 files changed, 47 insertions(+), 51 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 311907b762bd..f692261e9b5c 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -151,10 +151,10 @@ static int ll_ddelete(const struct dentry *de) { LASSERT(de); - CDEBUG(D_DENTRY, "%s dentry %.*s (%p, parent %p, inode %p) %s%s\n", + CDEBUG(D_DENTRY, "%s dentry %pd (%p, parent %p, inode %p) %s%s\n", d_lustre_invalid((struct dentry *)de) ? "deleting" : "keeping", - de->d_name.len, de->d_name.name, de, de->d_parent, de->d_inode, - d_unhashed((struct dentry *)de) ? "" : "hashed,", + de, de, de->d_parent, de->d_inode, + d_unhashed(de) ? "" : "hashed,", list_empty(&de->d_subdirs) ? "" : "subdirs"); /* kernel >= 2.6.38 last refcount is decreased after this function. */ @@ -180,8 +180,8 @@ int ll_d_init(struct dentry *de) { LASSERT(de != NULL); - CDEBUG(D_DENTRY, "ldd on dentry %.*s (%p) parent %p inode %p refc %d\n", - de->d_name.len, de->d_name.name, de, de->d_parent, de->d_inode, + CDEBUG(D_DENTRY, "ldd on dentry %pd (%p) parent %p inode %p refc %d\n", + de, de, de->d_parent, de->d_inode, d_count(de)); if (de->d_fsdata == NULL) { @@ -259,9 +259,8 @@ void ll_invalidate_aliases(struct inode *inode) ll_lock_dcache(inode); ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) { - CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p " - "inode %p flags %d\n", dentry->d_name.len, - dentry->d_name.name, dentry, dentry->d_parent, + CDEBUG(D_DENTRY, "dentry in drop %pd (%p) parent %p " + "inode %p flags %d\n", dentry, dentry, dentry->d_parent, dentry->d_inode, dentry->d_flags); if (unlikely(dentry == dentry->d_sb->s_root)) { @@ -352,8 +351,8 @@ static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags) { int rc; - CDEBUG(D_VFSTRACE, "VFS Op:name=%s, flags=%u\n", - dentry->d_name.name, flags); + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, flags=%u\n", + dentry, flags); rc = ll_revalidate_dentry(dentry, flags); return rc; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index c3be2f26dfa3..1fdc2fda6812 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1166,9 +1166,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, /* If any bit been read/written (result != 0), we just return * short read/write instead of restart io. */ if ((result == 0 || result == -ENODATA) && io->ci_need_restart) { - CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n", + CDEBUG(D_VFSTRACE, "Restart %s on %pD from %lld, count:%zd\n", iot == CIT_READ ? "read" : "write", - file->f_dentry->d_name.name, *ppos, count); + file, *ppos, count); LASSERTF(io->ci_nob == 0, "%zd", io->ci_nob); goto restart; } @@ -2899,8 +2899,8 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits) LASSERT(inode != NULL); - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),name=%s\n", - inode->i_ino, inode->i_generation, inode, dentry->d_name.name); + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),name=%pd\n", + inode->i_ino, inode->i_generation, inode, dentry); exp = ll_i2mdexp(inode); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 4b80a6f0c2f7..3c9e9803eac1 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1489,8 +1489,8 @@ static inline void __d_lustre_invalidate(struct dentry *dentry) */ static inline void d_lustre_invalidate(struct dentry *dentry, int nested) { - CDEBUG(D_DENTRY, "invalidate dentry %.*s (%p) parent %p inode %p " - "refc %d\n", dentry->d_name.len, dentry->d_name.name, dentry, + CDEBUG(D_DENTRY, "invalidate dentry %pd (%p) parent %p inode %p " + "refc %d\n", dentry, dentry, dentry->d_parent, dentry->d_inode, d_count(dentry)); spin_lock_nested(&dentry->d_lock, diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index f4ca7b753021..7b6b9e2e0102 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -698,10 +698,8 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) list_for_each(tmp, &dentry->d_subdirs) subdirs++; - CERROR("dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u," - " flags=0x%x, fsdata=%p, %d subdirs\n", dentry, - dentry->d_name.len, dentry->d_name.name, - dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, + CERROR("dentry %p dump: name=%pd parent=%p, inode=%p, count=%u," + " flags=0x%x, fsdata=%p, %d subdirs\n", dentry, dentry, dentry->d_parent, dentry->d_inode, d_count(dentry), dentry->d_flags, dentry->d_fsdata, subdirs); if (dentry->d_inode != NULL) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 6dfd98509268..2d134831f44a 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -509,8 +509,8 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, if (dentry->d_name.len > ll_i2sbi(parent)->ll_namelen) return ERR_PTR(-ENAMETOOLONG); - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n", - dentry->d_name.len, dentry->d_name.name, parent->i_ino, + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),intent=%s\n", + dentry, parent->i_ino, parent->i_generation, parent, LL_IT2STR(it)); if (d_mountpoint(dentry)) @@ -586,8 +586,8 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, struct lookup_intent *itp, it = { .it_op = IT_GETATTR }; struct dentry *de; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),flags=%u\n", - dentry->d_name.len, dentry->d_name.name, parent->i_ino, + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),flags=%u\n", + dentry, parent->i_ino, parent->i_generation, parent, flags); /* Optimize away (CREATE && !OPEN). Let .create handle the race. */ @@ -619,9 +619,9 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, long long lookup_flags = LOOKUP_OPEN; int rc = 0; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),file %p," + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),file %p," "open_flags %x,mode %x opened %d\n", - dentry->d_name.len, dentry->d_name.name, dir->i_ino, + dentry, dir->i_ino, dir->i_generation, dir, file, open_flags, mode, *opened); it = kzalloc(sizeof(*it), GFP_NOFS); @@ -741,8 +741,8 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode, struct inode *inode; int rc = 0; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),intent=%s\n", - dentry->d_name.len, dentry->d_name.name, dir->i_ino, + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),intent=%s\n", + dentry, dir->i_ino, dir->i_generation, dir, LL_IT2STR(it)); rc = it_open_error(DISP_OPEN_CREATE, it); @@ -863,17 +863,17 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, { int rc; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)," + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)," "flags=%u, excl=%d\n", - dentry->d_name.len, dentry->d_name.name, dir->i_ino, + dentry, dir->i_ino, dir->i_generation, dir, mode, want_excl); rc = ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry); ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_CREATE, 1); - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s, unhashed %d\n", - dentry->d_name.len, dentry->d_name.name, d_unhashed(dentry)); + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, unhashed %d\n", + dentry, d_unhashed(dentry)); return rc; } diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 06b71bcf97a7..09d965e76842 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -969,8 +969,8 @@ static int ll_agl_thread(void *arg) struct l_wait_info lwi = { 0 }; thread->t_pid = current_pid(); - CDEBUG(D_READA, "agl thread started: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "agl thread started: sai %p, parent %pd\n", + sai, parent); atomic_inc(&sbi->ll_agl_total); spin_lock(&plli->lli_agl_lock); @@ -1019,8 +1019,8 @@ static int ll_agl_thread(void *arg) spin_unlock(&plli->lli_agl_lock); wake_up(&thread->t_ctl_waitq); ll_sai_put(sai); - CDEBUG(D_READA, "agl thread stopped: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "agl thread stopped: sai %p, parent %pd\n", + sai, parent); return 0; } @@ -1031,8 +1031,8 @@ static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai) struct ll_inode_info *plli; struct task_struct *task; - CDEBUG(D_READA, "start agl thread: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "start agl thread: sai %p, parent %pd\n", + sai, parent); plli = ll_i2info(parent->d_inode); task = kthread_run(ll_agl_thread, parent, @@ -1066,8 +1066,8 @@ static int ll_statahead_thread(void *arg) struct l_wait_info lwi = { 0 }; thread->t_pid = current_pid(); - CDEBUG(D_READA, "statahead thread starting: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "statahead thread starting: sai %p, parent %pd\n", + sai, parent); if (sbi->ll_flags & LL_SBI_AGL_ENABLED) ll_start_agl(parent, sai); @@ -1288,8 +1288,8 @@ static int ll_statahead_thread(void *arg) wake_up(&thread->t_ctl_waitq); ll_sai_put(sai); dput(parent); - CDEBUG(D_READA, "statahead thread stopped: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "statahead thread stopped: sai %p, parent %pd\n", + sai, parent); return rc; } @@ -1612,10 +1612,9 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, } else if ((*dentryp)->d_inode != inode) { /* revalidate, but inode is recreated */ CDEBUG(D_READA, - "stale dentry %.*s inode %lu/%u, " + "stale dentry %pd inode %lu/%u, " "statahead inode %lu/%u\n", - (*dentryp)->d_name.len, - (*dentryp)->d_name.name, + *dentryp, (*dentryp)->d_inode->i_ino, (*dentryp)->d_inode->i_generation, inode->i_ino, @@ -1666,9 +1665,9 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, if (unlikely(sai->sai_inode != parent->d_inode)) { struct ll_inode_info *nlli = ll_i2info(parent->d_inode); - CWARN("Race condition, someone changed %.*s just now: " + CWARN("Race condition, someone changed %pd just now: " "old parent "DFID", new parent "DFID"\n", - (*dentryp)->d_name.len, (*dentryp)->d_name.name, + *dentryp, PFID(&lli->lli_fid), PFID(&nlli->lli_fid)); dput(parent); iput(sai->sai_inode); @@ -1676,8 +1675,8 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, goto out; } - CDEBUG(D_READA, "start statahead thread: sai %p, parent %.*s\n", - sai, parent->d_name.len, parent->d_name.name); + CDEBUG(D_READA, "start statahead thread: sai %p, parent %pd\n", + sai, parent); /* The sai buffer already has one reference taken at allocation time, * but as soon as we expose the sai by attaching it to the lli that diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 5ad5e7b310c4..3151baf5585c 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -516,8 +516,8 @@ ssize_t ll_getxattr(struct dentry *dentry, const char *name, } if (size < lmmsize) { - CERROR("server bug: replied size %d > %d for %s (%s)\n", - lmmsize, (int)size, dentry->d_name.name, name); + CERROR("server bug: replied size %d > %d for %pd (%s)\n", + lmmsize, (int)size, dentry, name); rc = -ERANGE; goto out; } -- GitLab From 2a8a3597aa588d3c01868f8034429a2860d5a785 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 18:02:33 -0400 Subject: [PATCH 2700/9457] lustre: use file_inode() Signed-off-by: Al Viro --- .../staging/lustre/lustre/libcfs/tracefile.c | 4 +-- drivers/staging/lustre/lustre/llite/dir.c | 4 +-- drivers/staging/lustre/lustre/llite/file.c | 27 +++++++++---------- .../lustre/lustre/llite/llite_internal.h | 2 +- .../staging/lustre/lustre/llite/llite_mmap.c | 12 ++++----- drivers/staging/lustre/lustre/llite/lloop.c | 7 +++-- drivers/staging/lustre/lustre/llite/vvp_io.c | 4 +-- 7 files changed, 29 insertions(+), 31 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index 7e3f6a45da00..7561030c96e6 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -1025,8 +1025,8 @@ static int tracefiled(void *arg) if (f_pos >= (off_t)cfs_tracefile_size) f_pos = 0; - else if (f_pos > i_size_read(filp->f_dentry->d_inode)) - f_pos = i_size_read(filp->f_dentry->d_inode); + else if (f_pos > i_size_read(file_inode(filp))) + f_pos = i_size_read(file_inode(filp)); buf = kmap(tage->page); rc = vfs_write(filp, (__force const char __user *)buf, diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index b0bb7095dde5..fa639407fde7 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -593,7 +593,7 @@ int ll_dir_read(struct inode *inode, struct dir_context *ctx) static int ll_readdir(struct file *filp, struct dir_context *ctx) { - struct inode *inode = filp->f_dentry->d_inode; + struct inode *inode = file_inode(filp); struct ll_file_data *lfd = LUSTRE_FPRIVATE(filp); struct ll_sb_info *sbi = ll_i2sbi(inode); int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; @@ -1242,7 +1242,7 @@ ll_getname(const char __user *filename) static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_sb_info *sbi = ll_i2sbi(inode); struct obd_ioctl_data *data; int rc = 0; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 1fdc2fda6812..dd8e505defa5 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -489,7 +489,7 @@ static int ll_och_fill(struct obd_export *md_exp, struct lookup_intent *it, static int ll_local_open(struct file *file, struct lookup_intent *it, struct ll_file_data *fd, struct obd_client_handle *och) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_inode_info *lli = ll_i2info(inode); LASSERT(!LUSTRE_FPRIVATE(file)); @@ -1053,7 +1053,7 @@ int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm, static bool file_is_noatime(const struct file *file) { const struct vfsmount *mnt = file->f_path.mnt; - const struct inode *inode = file->f_path.dentry->d_inode; + const struct inode *inode = file_inode(file); /* Adapted from file_accessed() and touch_atime().*/ if (file->f_flags & O_NOATIME) @@ -1079,7 +1079,7 @@ static bool file_is_noatime(const struct file *file) void ll_io_init(struct cl_io *io, const struct file *file, int write) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); io->u.ci_rw.crw_nonblock = file->f_flags & O_NONBLOCK; if (write) { @@ -1105,7 +1105,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, struct file *file, enum cl_io_type iot, loff_t *ppos, size_t count) { - struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode); + struct ll_inode_info *lli = ll_i2info(file_inode(file)); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); struct cl_io *io; ssize_t result; @@ -1175,11 +1175,11 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, if (iot == CIT_READ) { if (result >= 0) - ll_stats_ops_tally(ll_i2sbi(file->f_dentry->d_inode), + ll_stats_ops_tally(ll_i2sbi(file_inode(file)), LPROC_LL_READ_BYTES, result); } else if (iot == CIT_WRITE) { if (result >= 0) { - ll_stats_ops_tally(ll_i2sbi(file->f_dentry->d_inode), + ll_stats_ops_tally(ll_i2sbi(file_inode(file)), LPROC_LL_WRITE_BYTES, result); fd->fd_write_failed = false; } else if (result != -ERESTARTSYS) { @@ -1950,8 +1950,8 @@ static int ll_swap_layouts(struct file *file1, struct file *file2, if (!llss) return -ENOMEM; - llss->inode1 = file1->f_dentry->d_inode; - llss->inode2 = file2->f_dentry->d_inode; + llss->inode1 = file_inode(file1); + llss->inode2 = file_inode(file2); if (!S_ISREG(llss->inode2->i_mode)) { rc = -EINVAL; @@ -2195,7 +2195,7 @@ static int ll_hsm_import(struct inode *inode, struct file *file, static long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); int flags, rc; @@ -2514,7 +2514,7 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static loff_t ll_file_seek(struct file *file, loff_t offset, int origin) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); loff_t retval, eof = 0; retval = offset + ((origin == SEEK_END) ? i_size_read(inode) : @@ -2538,7 +2538,7 @@ static loff_t ll_file_seek(struct file *file, loff_t offset, int origin) static int ll_flush(struct file *file, fl_owner_t id) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_inode_info *lli = ll_i2info(inode); struct ll_file_data *fd = LUSTRE_FPRIVATE(file); int rc, err; @@ -2621,8 +2621,7 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end, int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_inode_info *lli = ll_i2info(inode); struct ptlrpc_request *req; struct obd_capa *oc; @@ -2675,7 +2674,7 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync) static int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct ll_sb_info *sbi = ll_i2sbi(inode); struct ldlm_enqueue_info einfo = { .ei_type = LDLM_FLOCK, diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 3c9e9803eac1..40dd3b50c478 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1413,7 +1413,7 @@ extern ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, static inline int ll_file_nolock(const struct file *file) { struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); LASSERT(fd != NULL); return ((fd->fd_flags & LL_FILE_IGNORE_LOCK) || diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index ae605a6d9dc2..ba1c047ae927 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -100,7 +100,7 @@ ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret, unsigned long *ra_flags) { struct file *file = vma->vm_file; - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); struct cl_io *io; struct cl_fault_io *fio; struct lu_env *env; @@ -213,7 +213,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, cfs_restore_sigs(set); if (result == 0) { - struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct inode *inode = file_inode(vma->vm_file); struct ll_inode_info *lli = ll_i2info(inode); lock_page(vmpage); @@ -396,7 +396,7 @@ static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) CWARN("app(%s): the page %lu of file %lu is under heavy" " contention.\n", current->comm, vmf->pgoff, - vma->vm_file->f_dentry->d_inode->i_ino); + file_inode(vma->vm_file)->i_ino); printed = true; } } while (retry); @@ -430,7 +430,7 @@ static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) */ static void ll_vm_open(struct vm_area_struct *vma) { - struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct inode *inode = file_inode(vma->vm_file); struct ccc_object *vob = cl_inode2ccc(inode); LASSERT(vma->vm_file); @@ -443,7 +443,7 @@ static void ll_vm_open(struct vm_area_struct *vma) */ static void ll_vm_close(struct vm_area_struct *vma) { - struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct inode *inode = file_inode(vma->vm_file); struct ccc_object *vob = cl_inode2ccc(inode); LASSERT(vma->vm_file); @@ -476,7 +476,7 @@ static const struct vm_operations_struct ll_file_vm_ops = { int ll_file_mmap(struct file *file, struct vm_area_struct *vma) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file_inode(file); int rc; if (ll_file_nolock(file)) diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index 264e5ec3fed6..9e31b789b790 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -187,7 +187,7 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head) { const struct lu_env *env = lo->lo_env; struct cl_io *io = &lo->lo_io; - struct inode *inode = lo->lo_backing_file->f_dentry->d_inode; + struct inode *inode = file_inode(lo->lo_backing_file); struct cl_object *obj = ll_i2info(inode)->lli_clob; pgoff_t offset; int ret; @@ -626,7 +626,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, break; } if (inode == NULL) - inode = lo->lo_backing_file->f_dentry->d_inode; + inode = file_inode(lo->lo_backing_file); if (lo->lo_state == LLOOP_BOUND) fid = ll_i2info(inode)->lli_fid; else @@ -692,8 +692,7 @@ static enum llioc_iter lloop_ioctl(struct inode *unused, struct file *file, lo_free = lo; continue; } - if (lo->lo_backing_file->f_dentry->d_inode == - file->f_dentry->d_inode) + if (file_inode(lo->lo_backing_file) == file_inode(file)) break; } if (lo || !lo_free) { diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index d3f967a78138..e540a6d286f8 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -108,7 +108,7 @@ static int vvp_io_fault_iter_init(const struct lu_env *env, struct inode *inode = ccc_object_inode(ios->cis_obj); LASSERT(inode == - cl2ccc_io(env, ios)->cui_fd->fd_file->f_dentry->d_inode); + file_inode(cl2ccc_io(env, ios)->cui_fd->fd_file)); vio->u.fault.ft_mtime = LTIME_S(inode->i_mtime); return 0; } @@ -239,7 +239,7 @@ static int vvp_mmap_locks(const struct lu_env *env, down_read(&mm->mmap_sem); while ((vma = our_vma(mm, addr, count)) != NULL) { - struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct inode *inode = file_inode(vma->vm_file); int flags = CEF_MUST; if (ll_file_nolock(vma->vm_file)) { -- GitLab From e22fdcc8d75a5ff8ec3020157d9a7a53220c07ef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 20:39:57 -0400 Subject: [PATCH 2701/9457] lustre: switch ll_release_openhandle() to struct inode * Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/file.c | 13 ++++++------- .../staging/lustre/lustre/llite/llite_internal.h | 2 +- drivers/staging/lustre/lustre/llite/namei.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index dd8e505defa5..567874fc5f47 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -430,7 +430,7 @@ static int ll_intent_file_open(struct dentry *dentry, void *lmm, if (!it_disposition(itp, DISP_OPEN_OPEN) || it_open_error(DISP_OPEN_OPEN, itp)) goto out; - ll_release_openhandle(dentry, itp); + ll_release_openhandle(inode, itp); goto out; } @@ -620,7 +620,7 @@ int ll_file_open(struct inode *inode, struct file *file) goto out_openerr; } - ll_release_openhandle(file->f_dentry, it); + ll_release_openhandle(inode, it); } (*och_usecount)++; @@ -1366,7 +1366,7 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, if (rc < 0) goto out_req_free; - ll_release_openhandle(dentry, &oit); + ll_release_openhandle(inode, &oit); out_unlock: ll_inode_size_unlock(inode); @@ -1622,22 +1622,21 @@ int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg) /** * Close inode open handle * - * \param dentry [in] dentry which contains the inode + * \param inode [in] inode in question * \param it [in,out] intent which contains open info and result * * \retval 0 success * \retval <0 failure */ -int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it) +int ll_release_openhandle(struct inode *inode, struct lookup_intent *it) { - struct inode *inode = dentry->d_inode; struct obd_client_handle *och; int rc; LASSERT(inode); /* Root ? Do nothing. */ - if (dentry->d_inode->i_sb->s_root == dentry) + if (inode->i_sb->s_root->d_inode == inode) return 0; /* No open handle to close? Move away */ diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 40dd3b50c478..77d1c12704b4 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -748,7 +748,7 @@ int ll_file_release(struct inode *inode, struct file *file); int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm, lstat_t *st); void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch); -int ll_release_openhandle(struct dentry *, struct lookup_intent *); +int ll_release_openhandle(struct inode *, struct lookup_intent *); int ll_md_real_close(struct inode *inode, fmode_t fmode); void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data, struct obd_client_handle **och, unsigned long flags); diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 2d134831f44a..016ed2de4630 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -563,7 +563,7 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, if ((it->it_op & IT_OPEN) && dentry->d_inode && !S_ISREG(dentry->d_inode->i_mode) && !S_ISDIR(dentry->d_inode->i_mode)) { - ll_release_openhandle(dentry, it); + ll_release_openhandle(dentry->d_inode, it); } ll_lookup_finish_locks(it, dentry); -- GitLab From d6689e5ffebdc8360b9c2e7c33a1acb4aff3850f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:19:53 -0400 Subject: [PATCH 2702/9457] kill ll_mknod_generic() just fold into ll_mknod() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 22 ++++++++------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 016ed2de4630..f5d4475b1df2 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -819,14 +819,14 @@ static int ll_new_node(struct inode *dir, struct qstr *name, return err; } -static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode, - unsigned rdev, struct dentry *dchild) +static int ll_mknod(struct inode *dir, struct dentry *dchild, + umode_t mode, dev_t rdev) { int err; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p) mode %o dev %x\n", - name->len, name->name, dir->i_ino, dir->i_generation, dir, - mode, rdev); + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p) mode %o dev %x\n", + dchild, dir->i_ino, dir->i_generation, dir, + mode, old_encode_dev(rdev)); if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) mode &= ~current_umask(); @@ -839,7 +839,8 @@ static int ll_mknod_generic(struct inode *dir, struct qstr *name, int mode, case S_IFBLK: case S_IFIFO: case S_IFSOCK: - err = ll_new_node(dir, name, NULL, mode, rdev, dchild, + err = ll_new_node(dir, &dchild->d_name, NULL, mode, + old_encode_dev(rdev), dchild, LUSTRE_OPC_MKNOD); break; case S_IFDIR: @@ -868,7 +869,7 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, dentry, dir->i_ino, dir->i_generation, dir, mode, want_excl); - rc = ll_mknod_generic(dir, &dentry->d_name, mode, 0, dentry); + rc = ll_mknod(dir, dentry, mode, 0); ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_CREATE, 1); @@ -1183,13 +1184,6 @@ static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, return err; } -static int ll_mknod(struct inode *dir, struct dentry *dchild, ll_umode_t mode, - dev_t rdev) -{ - return ll_mknod_generic(dir, &dchild->d_name, mode, - old_encode_dev(rdev), dchild); -} - static int ll_unlink(struct inode * dir, struct dentry *dentry) { return ll_unlink_generic(dir, NULL, dentry, &dentry->d_name); -- GitLab From 7c2f909400a4b1067df11a038b11f8a75a64365d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:22:38 -0400 Subject: [PATCH 2703/9457] kill ll_mkdir_generic() fold into ll_mkdir() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 35 +++++++++------------ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index f5d4475b1df2..aa76d52fb92b 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -927,26 +927,6 @@ static int ll_link_generic(struct inode *src, struct inode *dir, return err; } -static int ll_mkdir_generic(struct inode *dir, struct qstr *name, - int mode, struct dentry *dchild) - -{ - int err; - - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", - name->len, name->name, dir->i_ino, dir->i_generation, dir); - - if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) - mode &= ~current_umask(); - mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR; - err = ll_new_node(dir, name, NULL, mode, 0, dchild, LUSTRE_OPC_MKDIR); - - if (!err) - ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKDIR, 1); - - return err; -} - /* Try to find the child dentry by its name. If found, put the result fid into @fid. */ static void ll_get_child_fid(struct inode * dir, struct qstr *name, @@ -1191,7 +1171,20 @@ static int ll_unlink(struct inode * dir, struct dentry *dentry) static int ll_mkdir(struct inode *dir, struct dentry *dentry, ll_umode_t mode) { - return ll_mkdir_generic(dir, &dentry->d_name, mode, dentry); + int err; + + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)\n", + dentry, dir->i_ino, dir->i_generation, dir); + + if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) + mode &= ~current_umask(); + mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR; + err = ll_new_node(dir, &dentry->d_name, NULL, mode, 0, dentry, LUSTRE_OPC_MKDIR); + + if (!err) + ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKDIR, 1); + + return err; } static int ll_rmdir(struct inode *dir, struct dentry *dentry) -- GitLab From 60dd654e337f0e81c995e3e25a571460dc339dcd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:26:04 -0400 Subject: [PATCH 2704/9457] kill ll_symlink_generic() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 32 +++++++++------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index aa76d52fb92b..974d2d0dcc5b 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -879,24 +879,6 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, return rc; } -static int ll_symlink_generic(struct inode *dir, struct qstr *name, - const char *tgt, struct dentry *dchild) -{ - int err; - - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),target=%.*s\n", - name->len, name->name, dir->i_ino, dir->i_generation, - dir, 3000, tgt); - - err = ll_new_node(dir, name, (char *)tgt, S_IFLNK | S_IRWXUGO, - 0, dchild, LUSTRE_OPC_SYMLINK); - - if (!err) - ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_SYMLINK, 1); - - return err; -} - static int ll_link_generic(struct inode *src, struct inode *dir, struct qstr *name, struct dentry *dchild) { @@ -1195,7 +1177,19 @@ static int ll_rmdir(struct inode *dir, struct dentry *dentry) static int ll_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - return ll_symlink_generic(dir, &dentry->d_name, oldname, dentry); + int err; + + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p),target=%.*s\n", + dentry, dir->i_ino, dir->i_generation, + dir, 3000, oldname); + + err = ll_new_node(dir, &dentry->d_name, oldname, S_IFLNK | S_IRWXUGO, + 0, dentry, LUSTRE_OPC_SYMLINK); + + if (!err) + ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_SYMLINK, 1); + + return err; } static int ll_link(struct dentry *old_dentry, struct inode *dir, -- GitLab From b2037bb62b97015222a58506d1f58bcd596ab895 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:29:54 -0400 Subject: [PATCH 2705/9457] ll_new_inode(): don't bother with name - it's always &dentry->d_name Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 974d2d0dcc5b..510ac8246991 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -775,9 +775,9 @@ static void ll_update_times(struct ptlrpc_request *request, LTIME_S(inode->i_ctime) = body->ctime; } -static int ll_new_node(struct inode *dir, struct qstr *name, +static int ll_new_node(struct inode *dir, struct dentry *dentry, const char *tgt, int mode, int rdev, - struct dentry *dchild, __u32 opc) + __u32 opc) { struct ptlrpc_request *request = NULL; struct md_op_data *op_data; @@ -789,8 +789,10 @@ static int ll_new_node(struct inode *dir, struct qstr *name, if (unlikely(tgt != NULL)) tgt_len = strlen(tgt) + 1; - op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, - name->len, 0, opc, NULL); + op_data = ll_prep_md_op_data(NULL, dir, NULL, + dentry->d_name.name, + dentry->d_name.len, + 0, opc, NULL); if (IS_ERR(op_data)) { err = PTR_ERR(op_data); goto err_exit; @@ -806,13 +808,11 @@ static int ll_new_node(struct inode *dir, struct qstr *name, ll_update_times(request, dir); - if (dchild) { - err = ll_prep_inode(&inode, request, dchild->d_sb, NULL); - if (err) - goto err_exit; + err = ll_prep_inode(&inode, request, dir->i_sb, NULL); + if (err) + goto err_exit; - d_instantiate(dchild, inode); - } + d_instantiate(dentry, inode); err_exit: ptlrpc_req_finished(request); @@ -839,8 +839,8 @@ static int ll_mknod(struct inode *dir, struct dentry *dchild, case S_IFBLK: case S_IFIFO: case S_IFSOCK: - err = ll_new_node(dir, &dchild->d_name, NULL, mode, - old_encode_dev(rdev), dchild, + err = ll_new_node(dir, dchild, NULL, mode, + old_encode_dev(rdev), LUSTRE_OPC_MKNOD); break; case S_IFDIR: @@ -1161,7 +1161,7 @@ static int ll_mkdir(struct inode *dir, struct dentry *dentry, ll_umode_t mode) if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir))) mode &= ~current_umask(); mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR; - err = ll_new_node(dir, &dentry->d_name, NULL, mode, 0, dentry, LUSTRE_OPC_MKDIR); + err = ll_new_node(dir, dentry, NULL, mode, 0, LUSTRE_OPC_MKDIR); if (!err) ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKDIR, 1); @@ -1183,8 +1183,8 @@ static int ll_symlink(struct inode *dir, struct dentry *dentry, dentry, dir->i_ino, dir->i_generation, dir, 3000, oldname); - err = ll_new_node(dir, &dentry->d_name, oldname, S_IFLNK | S_IRWXUGO, - 0, dentry, LUSTRE_OPC_SYMLINK); + err = ll_new_node(dir, dentry, oldname, S_IFLNK | S_IRWXUGO, + 0, LUSTRE_OPC_SYMLINK); if (!err) ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_SYMLINK, 1); -- GitLab From 55dec6171f86742e8299d5baa7fbeb93ff4b1040 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:36:22 -0400 Subject: [PATCH 2706/9457] kill ll_rmdir_generic() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 60 ++++++++++----------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 510ac8246991..c3bd7e41c954 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -925,37 +925,6 @@ static void ll_get_child_fid(struct inode * dir, struct qstr *name, } } -static int ll_rmdir_generic(struct inode *dir, struct dentry *dparent, - struct dentry *dchild, struct qstr *name) -{ - struct ptlrpc_request *request = NULL; - struct md_op_data *op_data; - int rc; - - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", - name->len, name->name, dir->i_ino, dir->i_generation, dir); - - if (unlikely(ll_d_mountpoint(dparent, dchild, name))) - return -EBUSY; - - op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, name->len, - S_IFDIR, LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - ll_get_child_fid(dir, name, &op_data->op_fid3); - op_data->op_fid2 = op_data->op_fid3; - rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); - ll_finish_md_op_data(op_data); - if (rc == 0) { - ll_update_times(request, dir); - ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_RMDIR, 1); - } - - ptlrpc_req_finished(request); - return rc; -} - /** * Remove dir entry **/ @@ -1171,7 +1140,34 @@ static int ll_mkdir(struct inode *dir, struct dentry *dentry, ll_umode_t mode) static int ll_rmdir(struct inode *dir, struct dentry *dentry) { - return ll_rmdir_generic(dir, NULL, dentry, &dentry->d_name); + struct ptlrpc_request *request = NULL; + struct md_op_data *op_data; + int rc; + + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)\n", + dentry, dir->i_ino, dir->i_generation, dir); + + if (unlikely(ll_d_mountpoint(NULL, dentry, &dentry->d_name))) + return -EBUSY; + + op_data = ll_prep_md_op_data(NULL, dir, NULL, + dentry->d_name.name, + dentry->d_name.len, + S_IFDIR, LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + return PTR_ERR(op_data); + + ll_get_child_fid(dir, &dentry->d_name, &op_data->op_fid3); + op_data->op_fid2 = op_data->op_fid3; + rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); + ll_finish_md_op_data(op_data); + if (rc == 0) { + ll_update_times(request, dir); + ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_RMDIR, 1); + } + + ptlrpc_req_finished(request); + return rc; } static int ll_symlink(struct inode *dir, struct dentry *dentry, -- GitLab From 521f2ad7b674cbb1eaf3b143c30fdf03c2cac7b8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 22:38:51 -0400 Subject: [PATCH 2707/9457] kill ll_unlink_generic() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 80 ++++++++++----------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index c3bd7e41c954..b4cc9247c0dd 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -1031,47 +1031,6 @@ int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir) return rc; } -/* ll_unlink_generic() doesn't update the inode with the new link count. - * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there - * is any lock existing. They will recycle dentries and inodes based upon locks - * too. b=20433 */ -static int ll_unlink_generic(struct inode *dir, struct dentry *dparent, - struct dentry *dchild, struct qstr *name) -{ - struct ptlrpc_request *request = NULL; - struct md_op_data *op_data; - int rc; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", - name->len, name->name, dir->i_ino, dir->i_generation, dir); - - /* - * XXX: unlink bind mountpoint maybe call to here, - * just check it as vfs_unlink does. - */ - if (unlikely(ll_d_mountpoint(dparent, dchild, name))) - return -EBUSY; - - op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, - name->len, 0, LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - ll_get_child_fid(dir, name, &op_data->op_fid3); - op_data->op_fid2 = op_data->op_fid3; - rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); - ll_finish_md_op_data(op_data); - if (rc) - goto out; - - ll_update_times(request, dir); - ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_UNLINK, 1); - - rc = ll_objects_destroy(request, dir); - out: - ptlrpc_req_finished(request); - return rc; -} - static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, struct dentry *src_dchild, struct qstr *src_name, struct inode *tgt, struct dentry *tgt_dparent, @@ -1115,9 +1074,46 @@ static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, return err; } +/* ll_unlink() doesn't update the inode with the new link count. + * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there + * is any lock existing. They will recycle dentries and inodes based upon locks + * too. b=20433 */ static int ll_unlink(struct inode * dir, struct dentry *dentry) { - return ll_unlink_generic(dir, NULL, dentry, &dentry->d_name); + struct ptlrpc_request *request = NULL; + struct md_op_data *op_data; + int rc; + CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)\n", + dentry, dir->i_ino, dir->i_generation, dir); + + /* + * XXX: unlink bind mountpoint maybe call to here, + * just check it as vfs_unlink does. + */ + if (unlikely(ll_d_mountpoint(NULL, dentry, &dentry->d_name))) + return -EBUSY; + + op_data = ll_prep_md_op_data(NULL, dir, NULL, + dentry->d_name.name, + dentry->d_name.len, + 0, LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + return PTR_ERR(op_data); + + ll_get_child_fid(dir, &dentry->d_name, &op_data->op_fid3); + op_data->op_fid2 = op_data->op_fid3; + rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); + ll_finish_md_op_data(op_data); + if (rc) + goto out; + + ll_update_times(request, dir); + ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_UNLINK, 1); + + rc = ll_objects_destroy(request, dir); + out: + ptlrpc_req_finished(request); + return rc; } static int ll_mkdir(struct inode *dir, struct dentry *dentry, ll_umode_t mode) -- GitLab From 78851093c032b4c622377b430c815f1836bfec4e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 23:27:44 -0400 Subject: [PATCH 2708/9457] kill ll_rename_generic() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 83 +++++++++------------ 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index b4cc9247c0dd..e1434bb55822 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -1031,49 +1031,6 @@ int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir) return rc; } -static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, - struct dentry *src_dchild, struct qstr *src_name, - struct inode *tgt, struct dentry *tgt_dparent, - struct dentry *tgt_dchild, struct qstr *tgt_name) -{ - struct ptlrpc_request *request = NULL; - struct ll_sb_info *sbi = ll_i2sbi(src); - struct md_op_data *op_data; - int err; - - CDEBUG(D_VFSTRACE, - "VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s," - "tgt_dir=%lu/%u(%p)\n", src_name->len, src_name->name, - src->i_ino, src->i_generation, src, tgt_name->len, - tgt_name->name, tgt->i_ino, tgt->i_generation, tgt); - - if (unlikely(ll_d_mountpoint(src_dparent, src_dchild, src_name) || - ll_d_mountpoint(tgt_dparent, tgt_dchild, tgt_name))) - return -EBUSY; - - op_data = ll_prep_md_op_data(NULL, src, tgt, NULL, 0, 0, - LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - ll_get_child_fid(src, src_name, &op_data->op_fid3); - ll_get_child_fid(tgt, tgt_name, &op_data->op_fid4); - err = md_rename(sbi->ll_md_exp, op_data, - src_name->name, src_name->len, - tgt_name->name, tgt_name->len, &request); - ll_finish_md_op_data(op_data); - if (!err) { - ll_update_times(request, src); - ll_update_times(request, tgt); - ll_stats_ops_tally(sbi, LPROC_LL_RENAME, 1); - err = ll_objects_destroy(request, src); - } - - ptlrpc_req_finished(request); - - return err; -} - /* ll_unlink() doesn't update the inode with the new link count. * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there * is any lock existing. They will recycle dentries and inodes based upon locks @@ -1194,14 +1151,44 @@ static int ll_link(struct dentry *old_dentry, struct inode *dir, static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { + struct ptlrpc_request *request = NULL; + struct ll_sb_info *sbi = ll_i2sbi(old_dir); + struct md_op_data *op_data; int err; - err = ll_rename_generic(old_dir, NULL, - old_dentry, &old_dentry->d_name, - new_dir, NULL, new_dentry, - &new_dentry->d_name); + + CDEBUG(D_VFSTRACE, + "VFS Op:oldname=%pd,src_dir=%lu/%u(%p),newname=%pd," + "tgt_dir=%lu/%u(%p)\n", old_dentry, + old_dir->i_ino, old_dir->i_generation, old_dir, new_dentry, + new_dir->i_ino, new_dir->i_generation, new_dir); + + if (unlikely(ll_d_mountpoint(NULL, old_dentry, &old_dentry->d_name) || + ll_d_mountpoint(NULL, new_dentry, &new_dentry->d_name))) + return -EBUSY; + + op_data = ll_prep_md_op_data(NULL, old_dir, new_dir, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + return PTR_ERR(op_data); + + ll_get_child_fid(old_dir, &old_dentry->d_name, &op_data->op_fid3); + ll_get_child_fid(new_dir, &new_dentry->d_name, &op_data->op_fid4); + err = md_rename(sbi->ll_md_exp, op_data, + old_dentry->d_name.name, + old_dentry->d_name.len, + new_dentry->d_name.name, + new_dentry->d_name.len, &request); + ll_finish_md_op_data(op_data); if (!err) { - d_move(old_dentry, new_dentry); + ll_update_times(request, old_dir); + ll_update_times(request, new_dir); + ll_stats_ops_tally(sbi, LPROC_LL_RENAME, 1); + err = ll_objects_destroy(request, old_dir); } + + ptlrpc_req_finished(request); + if (!err) + d_move(old_dentry, new_dentry); return err; } -- GitLab From ea4df502dcee1d7ff394282f81c640e6a14e1997 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 23:31:54 -0400 Subject: [PATCH 2709/9457] ll_get_child_fid(): callers already have the child no need to bother with d_lookup() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 24 ++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index e1434bb55822..572e7f7ce6a0 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -909,20 +909,10 @@ static int ll_link_generic(struct inode *src, struct inode *dir, return err; } -/* Try to find the child dentry by its name. - If found, put the result fid into @fid. */ -static void ll_get_child_fid(struct inode * dir, struct qstr *name, - struct lu_fid *fid) +static inline void ll_get_child_fid(struct dentry *child, struct lu_fid *fid) { - struct dentry *parent, *child; - - parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_u.d_alias); - child = d_lookup(parent, name); - if (child) { - if (child->d_inode) - *fid = *ll_inode2fid(child->d_inode); - dput(child); - } + if (child->d_inode) + *fid = *ll_inode2fid(child->d_inode); } /** @@ -1057,7 +1047,7 @@ static int ll_unlink(struct inode * dir, struct dentry *dentry) if (IS_ERR(op_data)) return PTR_ERR(op_data); - ll_get_child_fid(dir, &dentry->d_name, &op_data->op_fid3); + ll_get_child_fid(dentry, &op_data->op_fid3); op_data->op_fid2 = op_data->op_fid3; rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); ll_finish_md_op_data(op_data); @@ -1110,7 +1100,7 @@ static int ll_rmdir(struct inode *dir, struct dentry *dentry) if (IS_ERR(op_data)) return PTR_ERR(op_data); - ll_get_child_fid(dir, &dentry->d_name, &op_data->op_fid3); + ll_get_child_fid(dentry, &op_data->op_fid3); op_data->op_fid2 = op_data->op_fid3; rc = md_unlink(ll_i2sbi(dir)->ll_md_exp, op_data, &request); ll_finish_md_op_data(op_data); @@ -1171,8 +1161,8 @@ static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, if (IS_ERR(op_data)) return PTR_ERR(op_data); - ll_get_child_fid(old_dir, &old_dentry->d_name, &op_data->op_fid3); - ll_get_child_fid(new_dir, &new_dentry->d_name, &op_data->op_fid4); + ll_get_child_fid(old_dentry, &op_data->op_fid3); + ll_get_child_fid(new_dentry, &op_data->op_fid4); err = md_rename(sbi->ll_md_exp, op_data, old_dentry->d_name.name, old_dentry->d_name.len, -- GitLab From 59cc93ef27cd6acec0f67e5f185ff21efbcaabcb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 23:35:36 -0400 Subject: [PATCH 2710/9457] kill ll_link_generic() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 59 ++++++++++----------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 572e7f7ce6a0..9ea878238b62 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -879,36 +879,6 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, return rc; } -static int ll_link_generic(struct inode *src, struct inode *dir, - struct qstr *name, struct dentry *dchild) -{ - struct ll_sb_info *sbi = ll_i2sbi(dir); - struct ptlrpc_request *request = NULL; - struct md_op_data *op_data; - int err; - - CDEBUG(D_VFSTRACE, - "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%.*s\n", - src->i_ino, src->i_generation, src, dir->i_ino, - dir->i_generation, dir, name->len, name->name); - - op_data = ll_prep_md_op_data(NULL, src, dir, name->name, name->len, - 0, LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - err = md_link(sbi->ll_md_exp, op_data, &request); - ll_finish_md_op_data(op_data); - if (err) - goto out; - - ll_update_times(request, dir); - ll_stats_ops_tally(sbi, LPROC_LL_LINK, 1); -out: - ptlrpc_req_finished(request); - return err; -} - static inline void ll_get_child_fid(struct dentry *child, struct lu_fid *fid) { if (child->d_inode) @@ -1134,8 +1104,33 @@ static int ll_symlink(struct inode *dir, struct dentry *dentry, static int ll_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { - return ll_link_generic(old_dentry->d_inode, dir, &new_dentry->d_name, - new_dentry); + struct inode *src = old_dentry->d_inode; + struct ll_sb_info *sbi = ll_i2sbi(dir); + struct ptlrpc_request *request = NULL; + struct md_op_data *op_data; + int err; + + CDEBUG(D_VFSTRACE, + "VFS Op: inode=%lu/%u(%p), dir=%lu/%u(%p), target=%pd\n", + src->i_ino, src->i_generation, src, dir->i_ino, + dir->i_generation, dir, new_dentry); + + op_data = ll_prep_md_op_data(NULL, src, dir, new_dentry->d_name.name, + new_dentry->d_name.len, + 0, LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + return PTR_ERR(op_data); + + err = md_link(sbi->ll_md_exp, op_data, &request); + ll_finish_md_op_data(op_data); + if (err) + goto out; + + ll_update_times(request, dir); + ll_stats_ops_tally(sbi, LPROC_LL_LINK, 1); +out: + ptlrpc_req_finished(request); + return err; } static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, -- GitLab From fd5c6c36a288cc15bd43f37c2be4787c41bc928f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Oct 2014 23:36:49 -0400 Subject: [PATCH 2711/9457] lustre: get rid of duplicate mountpoint checks VFS has already done them Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/namei.c | 35 --------------------- 1 file changed, 35 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 9ea878238b62..02283c533f5b 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -54,27 +54,6 @@ static int ll_create_it(struct inode *, struct dentry *, int, struct lookup_intent *); -/* - * Check if we have something mounted at the named dchild. - * In such a case there would always be dentry present. - */ -static int ll_d_mountpoint(struct dentry *dparent, struct dentry *dchild, - struct qstr *name) -{ - int mounted = 0; - - if (unlikely(dchild)) { - mounted = d_mountpoint(dchild); - } else if (dparent) { - dchild = d_lookup(dparent, name); - if (dchild) { - mounted = d_mountpoint(dchild); - dput(dchild); - } - } - return mounted; -} - /* called from iget5_locked->find_inode() under inode_hash_lock spinlock */ static int ll_test_inode(struct inode *inode, void *opaque) { @@ -1003,13 +982,6 @@ static int ll_unlink(struct inode * dir, struct dentry *dentry) CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)\n", dentry, dir->i_ino, dir->i_generation, dir); - /* - * XXX: unlink bind mountpoint maybe call to here, - * just check it as vfs_unlink does. - */ - if (unlikely(ll_d_mountpoint(NULL, dentry, &dentry->d_name))) - return -EBUSY; - op_data = ll_prep_md_op_data(NULL, dir, NULL, dentry->d_name.name, dentry->d_name.len, @@ -1060,9 +1032,6 @@ static int ll_rmdir(struct inode *dir, struct dentry *dentry) CDEBUG(D_VFSTRACE, "VFS Op:name=%pd,dir=%lu/%u(%p)\n", dentry, dir->i_ino, dir->i_generation, dir); - if (unlikely(ll_d_mountpoint(NULL, dentry, &dentry->d_name))) - return -EBUSY; - op_data = ll_prep_md_op_data(NULL, dir, NULL, dentry->d_name.name, dentry->d_name.len, @@ -1147,10 +1116,6 @@ static int ll_rename(struct inode *old_dir, struct dentry *old_dentry, old_dir->i_ino, old_dir->i_generation, old_dir, new_dentry, new_dir->i_ino, new_dir->i_generation, new_dir); - if (unlikely(ll_d_mountpoint(NULL, old_dentry, &old_dentry->d_name) || - ll_d_mountpoint(NULL, new_dentry, &new_dentry->d_name))) - return -EBUSY; - op_data = ll_prep_md_op_data(NULL, old_dir, new_dir, NULL, 0, 0, LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) -- GitLab From f76c23daacce0ed3da4abad9f2f421aae5108f93 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Oct 2014 15:20:42 -0400 Subject: [PATCH 2712/9457] lustre: use is_root_inode() Signed-off-by: Al Viro --- drivers/staging/lustre/lustre/llite/dir.c | 5 ++--- drivers/staging/lustre/lustre/llite/file.c | 13 ++++++------- drivers/staging/lustre/lustre/llite/namei.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index fa639407fde7..a79fd65ec4c6 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1389,7 +1389,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return -EFAULT; } - if (inode->i_sb->s_root == file->f_dentry) + if (is_root_inode(inode)) set_default = 1; /* in v1 and v3 cases lumv1 points to data */ @@ -1780,8 +1780,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ll_flush_ctx(inode); #ifdef CONFIG_FS_POSIX_ACL case LL_IOC_RMTACL: { - if (sbi->ll_flags & LL_SBI_RMT_CLIENT && - inode == inode->i_sb->s_root->d_inode) { + if (sbi->ll_flags & LL_SBI_RMT_CLIENT && is_root_inode(inode)) { struct ll_file_data *fd = LUSTRE_FPRIVATE(file); LASSERT(fd != NULL); diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 567874fc5f47..37b7c93717a1 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -341,8 +341,7 @@ int ll_file_release(struct inode *inode, struct file *file) inode->i_generation, inode); #ifdef CONFIG_FS_POSIX_ACL - if (sbi->ll_flags & LL_SBI_RMT_CLIENT && - inode == inode->i_sb->s_root->d_inode) { + if (sbi->ll_flags & LL_SBI_RMT_CLIENT && is_root_inode(inode)) { struct ll_file_data *fd = LUSTRE_FPRIVATE(file); LASSERT(fd != NULL); @@ -354,7 +353,7 @@ int ll_file_release(struct inode *inode, struct file *file) } #endif - if (inode->i_sb->s_root != file->f_dentry) + if (!is_root_inode(inode)) ll_stats_ops_tally(sbi, LPROC_LL_RELEASE, 1); fd = LUSTRE_FPRIVATE(file); LASSERT(fd != NULL); @@ -366,7 +365,7 @@ int ll_file_release(struct inode *inode, struct file *file) lli->lli_opendir_pid != 0) ll_stop_statahead(inode, lli->lli_opendir_key); - if (inode->i_sb->s_root == file->f_dentry) { + if (is_root_inode(inode)) { LUSTRE_FPRIVATE(file) = NULL; ll_file_data_put(fd); return 0; @@ -562,7 +561,7 @@ int ll_file_open(struct inode *inode, struct file *file) spin_unlock(&lli->lli_sa_lock); } - if (inode->i_sb->s_root == file->f_dentry) { + if (is_root_inode(inode)) { LUSTRE_FPRIVATE(file) = fd; return 0; } @@ -1636,7 +1635,7 @@ int ll_release_openhandle(struct inode *inode, struct lookup_intent *it) LASSERT(inode); /* Root ? Do nothing. */ - if (inode->i_sb->s_root->d_inode == inode) + if (is_root_inode(inode)) return 0; /* No open handle to close? Move away */ @@ -3108,7 +3107,7 @@ int ll_inode_permission(struct inode *inode, int mask) /* as root inode are NOT getting validated in lookup operation, * need to do it before permission check. */ - if (inode == inode->i_sb->s_root->d_inode) { + if (is_root_inode(inode)) { rc = __ll_inode_revalidate(inode->i_sb->s_root, MDS_INODELOCK_LOOKUP); if (rc) diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 02283c533f5b..8e926b385a60 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -264,7 +264,7 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) && inode->i_sb->s_root != NULL && - inode != inode->i_sb->s_root->d_inode) + is_root_inode(inode)) ll_invalidate_aliases(inode); iput(inode); -- GitLab From ca5358ef75fc69fee5322a38a340f5739d997c10 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Oct 2014 19:31:10 -0400 Subject: [PATCH 2713/9457] deal with deadlock in d_walk() ... by not hitting rename_retry for reasons other than rename having happened. In other words, do _not_ restart when finding that between unlocking the child and locking the parent the former got into __dentry_kill(). Skip the killed siblings instead... Signed-off-by: Al Viro --- fs/dcache.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 8b4c45e40834..e90aa825cc03 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -495,7 +495,7 @@ static void __dentry_kill(struct dentry *dentry) } /* if it was on the hash then remove it */ __d_drop(dentry); - list_del(&dentry->d_child); + __list_del_entry(&dentry->d_child); /* * Inform d_walk() that we are no longer attached to the * dentry tree @@ -1081,33 +1081,31 @@ static void d_walk(struct dentry *parent, void *data, /* * All done at this level ... ascend and resume the search. */ + rcu_read_lock(); +ascend: if (this_parent != parent) { struct dentry *child = this_parent; this_parent = child->d_parent; - rcu_read_lock(); spin_unlock(&child->d_lock); spin_lock(&this_parent->d_lock); - /* - * might go back up the wrong parent if we have had a rename - * or deletion - */ - if (this_parent != child->d_parent || - (child->d_flags & DCACHE_DENTRY_KILLED) || - need_seqretry(&rename_lock, seq)) { - spin_unlock(&this_parent->d_lock); - rcu_read_unlock(); + /* might go back up the wrong parent if we have had a rename. */ + if (need_seqretry(&rename_lock, seq)) goto rename_retry; + next = child->d_child.next; + while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { + if (next == &this_parent->d_subdirs) + goto ascend; + child = list_entry(next, struct dentry, d_child); + next = next->next; } rcu_read_unlock(); - next = child->d_child.next; goto resume; } - if (need_seqretry(&rename_lock, seq)) { - spin_unlock(&this_parent->d_lock); + if (need_seqretry(&rename_lock, seq)) goto rename_retry; - } + rcu_read_unlock(); if (finish) finish(data); @@ -1117,6 +1115,9 @@ static void d_walk(struct dentry *parent, void *data, return; rename_retry: + spin_unlock(&this_parent->d_lock); + rcu_read_unlock(); + BUG_ON(seq & 1); if (!retry) return; seq = 1; -- GitLab From 333829110f1d871df8ad9404833ecf49fc29aa34 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Thu, 30 Oct 2014 05:01:51 -0300 Subject: [PATCH 2714/9457] [media] m88rs6000t: add new dvb-s/s2 tuner for integrated chip M88RS6000 M88RS6000 is the integrated chip, which includes tuner and demod. Here splite its tuner as a standalone driver. .set_config is used to config its demod clock, which sits inside tuner die. Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/Kconfig | 8 + drivers/media/tuners/Makefile | 1 + drivers/media/tuners/m88rs6000t.c | 744 ++++++++++++++++++++++++++++++ drivers/media/tuners/m88rs6000t.h | 29 ++ 4 files changed, 782 insertions(+) create mode 100644 drivers/media/tuners/m88rs6000t.c create mode 100644 drivers/media/tuners/m88rs6000t.h diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index f039dc2a21cf..42e5a01b9192 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig @@ -232,6 +232,14 @@ config MEDIA_TUNER_M88TS2022 help Montage M88TS2022 silicon tuner driver. +config MEDIA_TUNER_M88RS6000T + tristate "Montage M88RS6000 internal tuner" + depends on MEDIA_SUPPORT && I2C + select REGMAP_I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Montage M88RS6000 internal tuner. + config MEDIA_TUNER_TUA9001 tristate "Infineon TUA 9001 silicon tuner" depends on MEDIA_SUPPORT && I2C diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile index 49fcf8033848..da4fe6ef73e7 100644 --- a/drivers/media/tuners/Makefile +++ b/drivers/media/tuners/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_MEDIA_TUNER_IT913X) += it913x.o obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o +obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o ccflags-y += -I$(srctree)/drivers/media/dvb-core ccflags-y += -I$(srctree)/drivers/media/dvb-frontends diff --git a/drivers/media/tuners/m88rs6000t.c b/drivers/media/tuners/m88rs6000t.c new file mode 100644 index 000000000000..d4c13fe6e7b3 --- /dev/null +++ b/drivers/media/tuners/m88rs6000t.c @@ -0,0 +1,744 @@ +/* + * Driver for the internal tuner of Montage M88RS6000 + * + * Copyright (C) 2014 Max nibble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "m88rs6000t.h" +#include + +struct m88rs6000t_dev { + struct m88rs6000t_config cfg; + struct i2c_client *client; + struct regmap *regmap; + u32 frequency_khz; +}; + +struct m88rs6000t_reg_val { + u8 reg; + u8 val; +}; + +/* set demod main mclk and ts mclk */ +static int m88rs6000t_set_demod_mclk(struct dvb_frontend *fe) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 reg11, reg15, reg16, reg1D, reg1E, reg1F; + u8 N, f0 = 0, f1 = 0, f2 = 0, f3 = 0; + u16 pll_div_fb; + u32 div, ts_mclk; + unsigned int utmp; + int ret; + + /* select demod main mclk */ + ret = regmap_read(dev->regmap, 0x15, &utmp); + if (ret) + goto err; + reg15 = utmp; + if (c->symbol_rate > 45010000) { + reg11 = 0x0E; + reg15 |= 0x02; + reg16 = 115; /* mclk = 110.25MHz */ + } else { + reg11 = 0x0A; + reg15 &= ~0x02; + reg16 = 96; /* mclk = 96MHz */ + } + + /* set ts mclk */ + if (c->delivery_system == SYS_DVBS) + ts_mclk = 96000; + else + ts_mclk = 144000; + + pll_div_fb = (reg15 & 0x01) << 8; + pll_div_fb += reg16; + pll_div_fb += 32; + + div = 36000 * pll_div_fb; + div /= ts_mclk; + + if (div <= 32) { + N = 2; + f0 = 0; + f1 = div / 2; + f2 = div - f1; + f3 = 0; + } else if (div <= 48) { + N = 3; + f0 = div / 3; + f1 = (div - f0) / 2; + f2 = div - f0 - f1; + f3 = 0; + } else if (div <= 64) { + N = 4; + f0 = div / 4; + f1 = (div - f0) / 3; + f2 = (div - f0 - f1) / 2; + f3 = div - f0 - f1 - f2; + } else { + N = 4; + f0 = 16; + f1 = 16; + f2 = 16; + f3 = 16; + } + + if (f0 == 16) + f0 = 0; + if (f1 == 16) + f1 = 0; + if (f2 == 16) + f2 = 0; + if (f3 == 16) + f3 = 0; + + ret = regmap_read(dev->regmap, 0x1D, &utmp); + if (ret) + goto err; + reg1D = utmp; + reg1D &= ~0x03; + reg1D |= N - 1; + reg1E = ((f3 << 4) + f2) & 0xFF; + reg1F = ((f1 << 4) + f0) & 0xFF; + + /* program and recalibrate demod PLL */ + ret = regmap_write(dev->regmap, 0x05, 0x40); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x11, 0x08); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x15, reg15); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x16, reg16); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x1D, reg1D); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x1E, reg1E); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x1F, reg1F); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x17, 0xc1); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x17, 0x81); + if (ret) + goto err; + usleep_range(5000, 50000); + ret = regmap_write(dev->regmap, 0x05, 0x00); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x11, reg11); + if (ret) + goto err; + usleep_range(5000, 50000); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static int m88rs6000t_set_pll_freq(struct m88rs6000t_dev *dev, + u32 tuner_freq_MHz) +{ + u32 fcry_KHz, ulNDiv1, ulNDiv2, ulNDiv; + u8 refDiv, ucLoDiv1, ucLomod1, ucLoDiv2, ucLomod2, ucLoDiv, ucLomod; + u8 reg27, reg29, reg42, reg42buf; + unsigned int utmp; + int ret; + + fcry_KHz = 27000; /* in kHz */ + refDiv = 27; + + ret = regmap_write(dev->regmap, 0x36, (refDiv - 8)); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x31, 0x00); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x2c, 0x02); + if (ret) + goto err; + + if (tuner_freq_MHz >= 1550) { + ucLoDiv1 = 2; + ucLomod1 = 0; + ucLoDiv2 = 2; + ucLomod2 = 0; + } else if (tuner_freq_MHz >= 1380) { + ucLoDiv1 = 3; + ucLomod1 = 16; + ucLoDiv2 = 2; + ucLomod2 = 0; + } else if (tuner_freq_MHz >= 1070) { + ucLoDiv1 = 3; + ucLomod1 = 16; + ucLoDiv2 = 3; + ucLomod2 = 16; + } else if (tuner_freq_MHz >= 1000) { + ucLoDiv1 = 3; + ucLomod1 = 16; + ucLoDiv2 = 4; + ucLomod2 = 64; + } else if (tuner_freq_MHz >= 775) { + ucLoDiv1 = 4; + ucLomod1 = 64; + ucLoDiv2 = 4; + ucLomod2 = 64; + } else if (tuner_freq_MHz >= 700) { + ucLoDiv1 = 6; + ucLomod1 = 48; + ucLoDiv2 = 4; + ucLomod2 = 64; + } else if (tuner_freq_MHz >= 520) { + ucLoDiv1 = 6; + ucLomod1 = 48; + ucLoDiv2 = 6; + ucLomod2 = 48; + } else { + ucLoDiv1 = 8; + ucLomod1 = 96; + ucLoDiv2 = 8; + ucLomod2 = 96; + } + + ulNDiv1 = ((tuner_freq_MHz * ucLoDiv1 * 1000) * refDiv + / fcry_KHz - 1024) / 2; + ulNDiv2 = ((tuner_freq_MHz * ucLoDiv2 * 1000) * refDiv + / fcry_KHz - 1024) / 2; + + reg27 = (((ulNDiv1 >> 8) & 0x0F) + ucLomod1) & 0x7F; + ret = regmap_write(dev->regmap, 0x27, reg27); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv1 & 0xFF)); + if (ret) + goto err; + reg29 = (((ulNDiv2 >> 8) & 0x0F) + ucLomod2) & 0x7f; + ret = regmap_write(dev->regmap, 0x29, reg29); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x2a, (u8)(ulNDiv2 & 0xFF)); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x2F, 0xf5); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x30, 0x05); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x1f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x3f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x20); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x00); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x3e, 0x11); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x2f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x3f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x10); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x00); + if (ret) + goto err; + usleep_range(2000, 50000); + + ret = regmap_read(dev->regmap, 0x42, &utmp); + if (ret) + goto err; + reg42 = utmp; + + ret = regmap_write(dev->regmap, 0x3e, 0x10); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x2f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x08, 0x3f); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x10); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x09, 0x00); + if (ret) + goto err; + usleep_range(2000, 50000); + + ret = regmap_read(dev->regmap, 0x42, &utmp); + if (ret) + goto err; + reg42buf = utmp; + if (reg42buf < reg42) { + ret = regmap_write(dev->regmap, 0x3e, 0x11); + if (ret) + goto err; + } + usleep_range(5000, 50000); + + ret = regmap_read(dev->regmap, 0x2d, &utmp); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x2d, utmp); + if (ret) + goto err; + ret = regmap_read(dev->regmap, 0x2e, &utmp); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x2e, utmp); + if (ret) + goto err; + + ret = regmap_read(dev->regmap, 0x27, &utmp); + if (ret) + goto err; + reg27 = utmp & 0x70; + ret = regmap_read(dev->regmap, 0x83, &utmp); + if (ret) + goto err; + if (reg27 == (utmp & 0x70)) { + ucLoDiv = ucLoDiv1; + ulNDiv = ulNDiv1; + ucLomod = ucLomod1 / 16; + } else { + ucLoDiv = ucLoDiv2; + ulNDiv = ulNDiv2; + ucLomod = ucLomod2 / 16; + } + + if ((ucLoDiv == 3) || (ucLoDiv == 6)) { + refDiv = 18; + ret = regmap_write(dev->regmap, 0x36, (refDiv - 8)); + if (ret) + goto err; + ulNDiv = ((tuner_freq_MHz * ucLoDiv * 1000) * refDiv + / fcry_KHz - 1024) / 2; + } + + reg27 = (0x80 + ((ucLomod << 4) & 0x70) + + ((ulNDiv >> 8) & 0x0F)) & 0xFF; + ret = regmap_write(dev->regmap, 0x27, reg27); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv & 0xFF)); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x29, 0x80); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x31, 0x03); + if (ret) + goto err; + + if (ucLoDiv == 3) + utmp = 0xCE; + else + utmp = 0x8A; + ret = regmap_write(dev->regmap, 0x3b, utmp); + if (ret) + goto err; + + dev->frequency_khz = fcry_KHz * (ulNDiv * 2 + 1024) / refDiv / ucLoDiv; + + dev_dbg(&dev->client->dev, + "actual tune frequency=%d\n", dev->frequency_khz); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static int m88rs6000t_set_bb(struct m88rs6000t_dev *dev, + u32 symbol_rate_KSs, s32 lpf_offset_KHz) +{ + u32 f3dB; + u8 reg40; + + f3dB = symbol_rate_KSs * 9 / 14 + 2000; + f3dB += lpf_offset_KHz; + f3dB = clamp_val(f3dB, 6000U, 43000U); + reg40 = f3dB / 1000; + return regmap_write(dev->regmap, 0x40, reg40); +} + +static int m88rs6000t_set_params(struct dvb_frontend *fe) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + s32 lpf_offset_KHz; + u32 realFreq, freq_MHz; + + dev_dbg(&dev->client->dev, + "frequency=%d symbol_rate=%d\n", + c->frequency, c->symbol_rate); + + if (c->symbol_rate < 5000000) + lpf_offset_KHz = 3000; + else + lpf_offset_KHz = 0; + + realFreq = c->frequency + lpf_offset_KHz; + /* set tuner pll.*/ + freq_MHz = (realFreq + 500) / 1000; + ret = m88rs6000t_set_pll_freq(dev, freq_MHz); + if (ret) + goto err; + ret = m88rs6000t_set_bb(dev, c->symbol_rate / 1000, lpf_offset_KHz); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x00, 0x01); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x00, 0x00); + if (ret) + goto err; + /* set demod mlck */ + ret = m88rs6000t_set_demod_mclk(fe); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static int m88rs6000t_init(struct dvb_frontend *fe) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + int ret; + + dev_dbg(&dev->client->dev, "%s:\n", __func__); + + ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08); + if (ret) + goto err; + usleep_range(5000, 50000); + ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01); + if (ret) + goto err; + usleep_range(10000, 50000); + ret = regmap_write(dev->regmap, 0x07, 0x7d); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static int m88rs6000t_sleep(struct dvb_frontend *fe) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + int ret; + + dev_dbg(&dev->client->dev, "%s:\n", __func__); + + ret = regmap_write(dev->regmap, 0x07, 0x6d); + if (ret) + goto err; + usleep_range(5000, 10000); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + + dev_dbg(&dev->client->dev, "\n"); + + *frequency = dev->frequency_khz; + return 0; +} + +static int m88rs6000t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + + dev_dbg(&dev->client->dev, "\n"); + + *frequency = 0; /* Zero-IF */ + return 0; +} + + +static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct m88rs6000t_dev *dev = fe->tuner_priv; + unsigned int val, i; + int ret; + u16 gain; + u32 PGA2_cri_GS = 46, PGA2_crf_GS = 290, TIA_GS = 290; + u32 RF_GC = 1200, IF_GC = 1100, BB_GC = 300; + u32 PGA2_GC = 300, TIA_GC = 300, PGA2_cri = 0, PGA2_crf = 0; + u32 RFG = 0, IFG = 0, BBG = 0, PGA2G = 0, TIAG = 0; + u32 RFGS[13] = {0, 245, 266, 268, 270, 285, + 298, 295, 283, 285, 285, 300, 300}; + u32 IFGS[12] = {0, 300, 230, 270, 270, 285, + 295, 285, 290, 295, 295, 310}; + u32 BBGS[14] = {0, 286, 275, 290, 294, 300, 290, + 290, 285, 283, 260, 295, 290, 260}; + + ret = regmap_read(dev->regmap, 0x5A, &val); + if (ret) + goto err; + RF_GC = val & 0x0f; + + ret = regmap_read(dev->regmap, 0x5F, &val); + if (ret) + goto err; + IF_GC = val & 0x0f; + + ret = regmap_read(dev->regmap, 0x3F, &val); + if (ret) + goto err; + TIA_GC = (val >> 4) & 0x07; + + ret = regmap_read(dev->regmap, 0x77, &val); + if (ret) + goto err; + BB_GC = (val >> 4) & 0x0f; + + ret = regmap_read(dev->regmap, 0x76, &val); + if (ret) + goto err; + PGA2_GC = val & 0x3f; + PGA2_cri = PGA2_GC >> 2; + PGA2_crf = PGA2_GC & 0x03; + + for (i = 0; i <= RF_GC; i++) + RFG += RFGS[i]; + + if (RF_GC == 0) + RFG += 400; + if (RF_GC == 1) + RFG += 300; + if (RF_GC == 2) + RFG += 200; + if (RF_GC == 3) + RFG += 100; + + for (i = 0; i <= IF_GC; i++) + IFG += IFGS[i]; + + TIAG = TIA_GC * TIA_GS; + + for (i = 0; i <= BB_GC; i++) + BBG += BBGS[i]; + + PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS; + + gain = RFG + IFG - TIAG + BBG + PGA2G; + + /* scale value to 0x0000-0xffff */ + gain = clamp_val(gain, 1000U, 10500U); + *strength = (10500 - gain) * 0xffff / (10500 - 1000); +err: + if (ret) + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + return ret; +} + +static const struct dvb_tuner_ops m88rs6000t_tuner_ops = { + .info = { + .name = "Montage M88RS6000 Internal Tuner", + .frequency_min = 950000, + .frequency_max = 2150000, + }, + + .init = m88rs6000t_init, + .sleep = m88rs6000t_sleep, + .set_params = m88rs6000t_set_params, + .get_frequency = m88rs6000t_get_frequency, + .get_if_frequency = m88rs6000t_get_if_frequency, + .get_rf_strength = m88rs6000t_get_rf_strength, +}; + +static int m88rs6000t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct m88rs6000t_config *cfg = client->dev.platform_data; + struct dvb_frontend *fe = cfg->fe; + struct m88rs6000t_dev *dev; + int ret, i; + unsigned int utmp; + static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; + static const struct m88rs6000t_reg_val reg_vals[] = { + {0x10, 0xfb}, + {0x24, 0x38}, + {0x11, 0x0a}, + {0x12, 0x00}, + {0x2b, 0x1c}, + {0x44, 0x48}, + {0x54, 0x24}, + {0x55, 0x06}, + {0x59, 0x00}, + {0x5b, 0x4c}, + {0x60, 0x8b}, + {0x61, 0xf4}, + {0x65, 0x07}, + {0x6d, 0x6f}, + {0x6e, 0x31}, + {0x3c, 0xf3}, + {0x37, 0x0f}, + {0x48, 0x28}, + {0x49, 0xd8}, + {0x70, 0x66}, + {0x71, 0xCF}, + {0x72, 0x81}, + {0x73, 0xA7}, + {0x74, 0x4F}, + {0x75, 0xFC}, + }; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + dev_err(&client->dev, "kzalloc() failed\n"); + goto err; + } + + memcpy(&dev->cfg, cfg, sizeof(struct m88rs6000t_config)); + dev->client = client; + dev->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(dev->regmap)) { + ret = PTR_ERR(dev->regmap); + goto err; + } + + ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08); + if (ret) + goto err; + usleep_range(5000, 50000); + ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01); + if (ret) + goto err; + usleep_range(10000, 50000); + ret = regmap_write(dev->regmap, 0x07, 0x7d); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x04, 0x01); + if (ret) + goto err; + + /* check tuner chip id */ + ret = regmap_read(dev->regmap, 0x01, &utmp); + if (ret) + goto err; + dev_info(&dev->client->dev, "chip_id=%02x\n", utmp); + if (utmp != 0x64) { + ret = -ENODEV; + goto err; + } + + /* tuner init. */ + ret = regmap_write(dev->regmap, 0x05, 0x40); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x11, 0x08); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x15, 0x6c); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x17, 0xc1); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x17, 0x81); + if (ret) + goto err; + usleep_range(10000, 50000); + ret = regmap_write(dev->regmap, 0x05, 0x00); + if (ret) + goto err; + ret = regmap_write(dev->regmap, 0x11, 0x0a); + if (ret) + goto err; + + for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { + ret = regmap_write(dev->regmap, + reg_vals[i].reg, reg_vals[i].val); + if (ret) + goto err; + } + + dev_info(&dev->client->dev, "Montage M88RS6000 internal tuner successfully identified\n"); + + fe->tuner_priv = dev; + memcpy(&fe->ops.tuner_ops, &m88rs6000t_tuner_ops, + sizeof(struct dvb_tuner_ops)); + i2c_set_clientdata(client, dev); + return 0; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + kfree(dev); + return ret; +} + +static int m88rs6000t_remove(struct i2c_client *client) +{ + struct m88rs6000t_dev *dev = i2c_get_clientdata(client); + struct dvb_frontend *fe = dev->cfg.fe; + + dev_dbg(&client->dev, "\n"); + + memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = NULL; + kfree(dev); + + return 0; +} + +static const struct i2c_device_id m88rs6000t_id[] = { + {"m88rs6000t", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, m88rs6000t_id); + +static struct i2c_driver m88rs6000t_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "m88rs6000t", + }, + .probe = m88rs6000t_probe, + .remove = m88rs6000t_remove, + .id_table = m88rs6000t_id, +}; + +module_i2c_driver(m88rs6000t_driver); + +MODULE_AUTHOR("Max nibble "); +MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/tuners/m88rs6000t.h b/drivers/media/tuners/m88rs6000t.h new file mode 100644 index 000000000000..264c13e2cd39 --- /dev/null +++ b/drivers/media/tuners/m88rs6000t.h @@ -0,0 +1,29 @@ +/* + * Driver for the internal tuner of Montage M88RS6000 + * + * Copyright (C) 2014 Max nibble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _M88RS6000T_H_ +#define _M88RS6000T_H_ + +#include "dvb_frontend.h" + +struct m88rs6000t_config { + /* + * pointer to DVB frontend + */ + struct dvb_frontend *fe; +}; + +#endif -- GitLab From f4df95bcbb7b142bdb4cf201f5e1bd3985f8c804 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Thu, 30 Oct 2014 05:01:14 -0300 Subject: [PATCH 2715/9457] [media] m88ds3103: add support for the demod of M88RS6000 M88RS6000 is the integrated chip, which includes tuner and demod. Its internal demod is similar with M88DS3103 except some registers definition. The main different part of this internal demod from others is its clock/pll generation IP block sitting inside the tuner die. So clock/pll functions should be configed through its tuner i2c bus, NOT its demod i2c bus. The demod of M88RS6000 need the firmware: dvb-demod-m88rs6000.fw firmware download link: http://www.dvbsky.net/download/linux/dvbsky-firmware.tar.gz Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 242 +++++++++++++------ drivers/media/dvb-frontends/m88ds3103_priv.h | 181 ++++++++++++++ 2 files changed, 345 insertions(+), 78 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 81657e94c5a4..621d20fde2ab 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1,5 +1,5 @@ /* - * Montage M88DS3103 demodulator driver + * Montage M88DS3103/M88RS6000 demodulator driver * * Copyright (C) 2013 Antti Palosaari * @@ -162,7 +162,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv, dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len); - if (tab_len > 83) { + if (tab_len > 86) { ret = -EINVAL; goto err; } @@ -246,7 +246,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) int ret, len; const struct m88ds3103_reg_val *init; u8 u8tmp, u8tmp1, u8tmp2; - u8 buf[2]; + u8 buf[3]; u16 u16tmp, divide_ratio; u32 tuner_frequency, target_mclk; s32 s32tmp; @@ -262,6 +262,22 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) goto err; } + /* reset */ + ret = m88ds3103_wr_reg(priv, 0x07, 0x80); + if (ret) + goto err; + + ret = m88ds3103_wr_reg(priv, 0x07, 0x00); + if (ret) + goto err; + + /* Disable demod clock path */ + if (priv->chip_id == M88RS6000_CHIP_ID) { + ret = m88ds3103_wr_reg(priv, 0x06, 0xe0); + if (ret) + goto err; + } + /* program tuner */ if (fe->ops.tuner_ops.set_params) { ret = fe->ops.tuner_ops.set_params(fe); @@ -282,14 +298,76 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) tuner_frequency = c->frequency; } - /* reset */ - ret = m88ds3103_wr_reg(priv, 0x07, 0x80); - if (ret) - goto err; + /* select M88RS6000 demod main mclk and ts mclk from tuner die. */ + if (priv->chip_id == M88RS6000_CHIP_ID) { + if (c->symbol_rate > 45010000) + priv->mclk_khz = 110250; + else + priv->mclk_khz = 96000; - ret = m88ds3103_wr_reg(priv, 0x07, 0x00); - if (ret) - goto err; + if (c->delivery_system == SYS_DVBS) + target_mclk = 96000; + else + target_mclk = 144000; + + /* Enable demod clock path */ + ret = m88ds3103_wr_reg(priv, 0x06, 0x00); + if (ret) + goto err; + usleep_range(10000, 20000); + } else { + /* set M88DS3103 mclk and ts mclk. */ + priv->mclk_khz = 96000; + + if (c->delivery_system == SYS_DVBS) + target_mclk = 96000; + else { + switch (priv->cfg->ts_mode) { + case M88DS3103_TS_SERIAL: + case M88DS3103_TS_SERIAL_D7: + if (c->symbol_rate < 18000000) + target_mclk = 96000; + else + target_mclk = 144000; + break; + case M88DS3103_TS_PARALLEL: + case M88DS3103_TS_CI: + if (c->symbol_rate < 18000000) + target_mclk = 96000; + else if (c->symbol_rate < 28000000) + target_mclk = 144000; + else + target_mclk = 192000; + break; + default: + dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", + __func__); + ret = -EINVAL; + goto err; + } + } + + switch (target_mclk) { + case 96000: + u8tmp1 = 0x02; /* 0b10 */ + u8tmp2 = 0x01; /* 0b01 */ + break; + case 144000: + u8tmp1 = 0x00; /* 0b00 */ + u8tmp2 = 0x01; /* 0b01 */ + break; + case 192000: + u8tmp1 = 0x03; /* 0b11 */ + u8tmp2 = 0x00; /* 0b00 */ + break; + } + ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0); + if (ret) + goto err; + ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0); + if (ret) + goto err; + } ret = m88ds3103_wr_reg(priv, 0xb2, 0x01); if (ret) @@ -301,36 +379,21 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) switch (c->delivery_system) { case SYS_DVBS: - len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals); - init = m88ds3103_dvbs_init_reg_vals; - target_mclk = 96000; + if (priv->chip_id == M88RS6000_CHIP_ID) { + len = ARRAY_SIZE(m88rs6000_dvbs_init_reg_vals); + init = m88rs6000_dvbs_init_reg_vals; + } else { + len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals); + init = m88ds3103_dvbs_init_reg_vals; + } break; case SYS_DVBS2: - len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals); - init = m88ds3103_dvbs2_init_reg_vals; - - switch (priv->cfg->ts_mode) { - case M88DS3103_TS_SERIAL: - case M88DS3103_TS_SERIAL_D7: - if (c->symbol_rate < 18000000) - target_mclk = 96000; - else - target_mclk = 144000; - break; - case M88DS3103_TS_PARALLEL: - case M88DS3103_TS_CI: - if (c->symbol_rate < 18000000) - target_mclk = 96000; - else if (c->symbol_rate < 28000000) - target_mclk = 144000; - else - target_mclk = 192000; - break; - default: - dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", - __func__); - ret = -EINVAL; - goto err; + if (priv->chip_id == M88RS6000_CHIP_ID) { + len = ARRAY_SIZE(m88rs6000_dvbs2_init_reg_vals); + init = m88rs6000_dvbs2_init_reg_vals; + } else { + len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals); + init = m88ds3103_dvbs2_init_reg_vals; } break; default: @@ -347,6 +410,30 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) goto err; } + if (priv->chip_id == M88RS6000_CHIP_ID) { + if ((c->delivery_system == SYS_DVBS2) + && ((c->symbol_rate / 1000) <= 5000)) { + ret = m88ds3103_wr_reg(priv, 0xc0, 0x04); + if (ret) + goto err; + buf[0] = 0x09; + buf[1] = 0x22; + buf[2] = 0x88; + ret = m88ds3103_wr_regs(priv, 0x8a, buf, 3); + if (ret) + goto err; + } + ret = m88ds3103_wr_reg_mask(priv, 0x9d, 0x08, 0x08); + if (ret) + goto err; + ret = m88ds3103_wr_reg(priv, 0xf1, 0x01); + if (ret) + goto err; + ret = m88ds3103_wr_reg_mask(priv, 0x30, 0x80, 0x80); + if (ret) + goto err; + } + u8tmp1 = 0; /* silence compiler warning */ switch (priv->cfg->ts_mode) { case M88DS3103_TS_SERIAL: @@ -420,29 +507,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - switch (target_mclk) { - case 96000: - u8tmp1 = 0x02; /* 0b10 */ - u8tmp2 = 0x01; /* 0b01 */ - break; - case 144000: - u8tmp1 = 0x00; /* 0b00 */ - u8tmp2 = 0x01; /* 0b01 */ - break; - case 192000: - u8tmp1 = 0x03; /* 0b11 */ - u8tmp2 = 0x00; /* 0b00 */ - break; - } - - ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0); - if (ret) - goto err; - - ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0); - if (ret) - goto err; - if (c->symbol_rate <= 3000000) u8tmp = 0x20; else if (c->symbol_rate <= 10000000) @@ -466,7 +530,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, M88DS3103_MCLK_KHZ / 2); + u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, priv->mclk_khz / 2); buf[0] = (u16tmp >> 0) & 0xff; buf[1] = (u16tmp >> 8) & 0xff; ret = m88ds3103_wr_regs(priv, 0x61, buf, 2); @@ -489,7 +553,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) (tuner_frequency - c->frequency)); s32tmp = 0x10000 * (tuner_frequency - c->frequency); - s32tmp = DIV_ROUND_CLOSEST(s32tmp, M88DS3103_MCLK_KHZ); + s32tmp = DIV_ROUND_CLOSEST(s32tmp, priv->mclk_khz); if (s32tmp < 0) s32tmp += 0x10000; @@ -520,7 +584,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) struct m88ds3103_priv *priv = fe->demodulator_priv; int ret, len, remaining; const struct firmware *fw = NULL; - u8 *fw_file = M88DS3103_FIRMWARE; + u8 *fw_file; u8 u8tmp; dev_dbg(&priv->i2c->dev, "%s:\n", __func__); @@ -541,15 +605,6 @@ static int m88ds3103_init(struct dvb_frontend *fe) if (ret) goto err; - /* reset */ - ret = m88ds3103_wr_reg(priv, 0x07, 0x60); - if (ret) - goto err; - - ret = m88ds3103_wr_reg(priv, 0x07, 0x00); - if (ret) - goto err; - /* firmware status */ ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp); if (ret) @@ -560,10 +615,23 @@ static int m88ds3103_init(struct dvb_frontend *fe) if (u8tmp) goto skip_fw_download; + /* global reset, global diseqc reset, golbal fec reset */ + ret = m88ds3103_wr_reg(priv, 0x07, 0xe0); + if (ret) + goto err; + + ret = m88ds3103_wr_reg(priv, 0x07, 0x00); + if (ret) + goto err; + /* cold state - try to download firmware */ dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n", KBUILD_MODNAME, m88ds3103_ops.info.name); + if (priv->chip_id == M88RS6000_CHIP_ID) + fw_file = M88RS6000_FIRMWARE; + else + fw_file = M88DS3103_FIRMWARE; /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); if (ret) { @@ -635,13 +703,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe) { struct m88ds3103_priv *priv = fe->demodulator_priv; int ret; + u8 u8tmp; dev_dbg(&priv->i2c->dev, "%s:\n", __func__); priv->delivery_system = SYS_UNDEFINED; /* TS Hi-Z */ - ret = m88ds3103_wr_reg_mask(priv, 0x27, 0x00, 0x01); + if (priv->chip_id == M88RS6000_CHIP_ID) + u8tmp = 0x29; + else + u8tmp = 0x27; + ret = m88ds3103_wr_reg_mask(priv, u8tmp, 0x00, 0x01); if (ret) goto err; @@ -830,7 +903,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe) goto err; c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) * - M88DS3103_MCLK_KHZ * 1000 / 0x10000; + priv->mclk_khz * 1000 / 0x10000; return 0; err: @@ -1310,18 +1383,22 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, priv->i2c = i2c; mutex_init(&priv->i2c_mutex); - ret = m88ds3103_rd_reg(priv, 0x01, &chip_id); + /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */ + ret = m88ds3103_rd_reg(priv, 0x00, &chip_id); if (ret) goto err; - dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); + chip_id >>= 1; + dev_info(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); switch (chip_id) { - case 0xd0: + case M88RS6000_CHIP_ID: + case M88DS3103_CHIP_ID: break; default: goto err; } + priv->chip_id = chip_id; switch (priv->cfg->clock_out) { case M88DS3103_CLOCK_OUT_DISABLED: @@ -1337,6 +1414,11 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, goto err; } + /* 0x29 register is defined differently for m88rs6000. */ + /* set internal tuner address to 0x21 */ + if (chip_id == M88RS6000_CHIP_ID) + u8tmp = 0x00; + ret = m88ds3103_wr_reg(priv, 0x29, u8tmp); if (ret) goto err; @@ -1364,6 +1446,9 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, /* create dvb_frontend */ memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); + if (priv->chip_id == M88RS6000_CHIP_ID) + strncpy(priv->fe.ops.info.name, + "Montage M88RS6000", sizeof(priv->fe.ops.info.name)); priv->fe.demodulator_priv = priv; return &priv->fe; @@ -1423,3 +1508,4 @@ MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(M88DS3103_FIRMWARE); +MODULE_FIRMWARE(M88RS6000_FIRMWARE); diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index 9169fdd143cf..a2c0958111f8 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -25,7 +25,10 @@ #include #define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw" +#define M88RS6000_FIRMWARE "dvb-demod-m88rs6000.fw" #define M88DS3103_MCLK_KHZ 96000 +#define M88RS6000_CHIP_ID 0x74 +#define M88DS3103_CHIP_ID 0x70 struct m88ds3103_priv { struct i2c_adapter *i2c; @@ -38,6 +41,10 @@ struct m88ds3103_priv { u32 ber; bool warm; /* FW running */ struct i2c_adapter *i2c_adapter; + /* auto detect chip id to do different config */ + u8 chip_id; + /* main mclk is calculated for M88RS6000 dynamically */ + u32 mclk_khz; }; struct m88ds3103_reg_val { @@ -214,4 +221,178 @@ static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = { {0xb8, 0x00}, }; +static const struct m88ds3103_reg_val m88rs6000_dvbs_init_reg_vals[] = { + {0x23, 0x07}, + {0x08, 0x03}, + {0x0c, 0x02}, + {0x20, 0x00}, + {0x21, 0x54}, + {0x25, 0x82}, + {0x27, 0x31}, + {0x30, 0x08}, + {0x31, 0x40}, + {0x32, 0x32}, + {0x33, 0x35}, + {0x35, 0xff}, + {0x3a, 0x00}, + {0x37, 0x10}, + {0x38, 0x10}, + {0x39, 0x02}, + {0x42, 0x60}, + {0x4a, 0x80}, + {0x4b, 0x04}, + {0x4d, 0x91}, + {0x5d, 0xc8}, + {0x50, 0x36}, + {0x51, 0x36}, + {0x52, 0x36}, + {0x53, 0x36}, + {0x63, 0x0f}, + {0x64, 0x30}, + {0x65, 0x40}, + {0x68, 0x26}, + {0x69, 0x4c}, + {0x70, 0x20}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x40}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x60}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x80}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0xa0}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x1f}, + {0x76, 0x38}, + {0x77, 0xa6}, + {0x78, 0x0c}, + {0x79, 0x80}, + {0x7f, 0x14}, + {0x7c, 0x00}, + {0xae, 0x82}, + {0x80, 0x64}, + {0x81, 0x66}, + {0x82, 0x44}, + {0x85, 0x04}, + {0xcd, 0xf4}, + {0x90, 0x33}, + {0xa0, 0x44}, + {0xbe, 0x00}, + {0xc0, 0x08}, + {0xc3, 0x10}, + {0xc4, 0x08}, + {0xc5, 0xf0}, + {0xc6, 0xff}, + {0xc7, 0x00}, + {0xc8, 0x1a}, + {0xc9, 0x80}, + {0xe0, 0xf8}, + {0xe6, 0x8b}, + {0xd0, 0x40}, + {0xf8, 0x20}, + {0xfa, 0x0f}, + {0x00, 0x00}, + {0xbd, 0x01}, + {0xb8, 0x00}, + {0x29, 0x11}, +}; + +static const struct m88ds3103_reg_val m88rs6000_dvbs2_init_reg_vals[] = { + {0x23, 0x07}, + {0x08, 0x07}, + {0x0c, 0x02}, + {0x20, 0x00}, + {0x21, 0x54}, + {0x25, 0x82}, + {0x27, 0x31}, + {0x30, 0x08}, + {0x32, 0x32}, + {0x33, 0x35}, + {0x35, 0xff}, + {0x3a, 0x00}, + {0x37, 0x10}, + {0x38, 0x10}, + {0x39, 0x02}, + {0x42, 0x60}, + {0x4a, 0x80}, + {0x4b, 0x04}, + {0x4d, 0x91}, + {0x5d, 0xc8}, + {0x50, 0x36}, + {0x51, 0x36}, + {0x52, 0x36}, + {0x53, 0x36}, + {0x63, 0x0f}, + {0x64, 0x10}, + {0x65, 0x20}, + {0x68, 0x46}, + {0x69, 0xcd}, + {0x70, 0x20}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x40}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x60}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x80}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0xa0}, + {0x71, 0x70}, + {0x72, 0x04}, + {0x73, 0x00}, + {0x70, 0x1f}, + {0x76, 0x38}, + {0x77, 0xa6}, + {0x78, 0x0c}, + {0x79, 0x80}, + {0x7f, 0x14}, + {0x85, 0x08}, + {0xcd, 0xf4}, + {0x90, 0x33}, + {0x86, 0x00}, + {0x87, 0x0f}, + {0x89, 0x00}, + {0x8b, 0x44}, + {0x8c, 0x66}, + {0x9d, 0xc1}, + {0x8a, 0x10}, + {0xad, 0x40}, + {0xa0, 0x44}, + {0xbe, 0x00}, + {0xc0, 0x08}, + {0xc1, 0x10}, + {0xc2, 0x08}, + {0xc3, 0x10}, + {0xc4, 0x08}, + {0xc5, 0xf0}, + {0xc6, 0xff}, + {0xc7, 0x00}, + {0xc8, 0x1a}, + {0xc9, 0x80}, + {0xca, 0x23}, + {0xcb, 0x24}, + {0xcc, 0xf4}, + {0xce, 0x74}, + {0x00, 0x00}, + {0xbd, 0x01}, + {0xb8, 0x00}, + {0x29, 0x01}, +}; #endif -- GitLab From 4e2357611323d562fe255d9d71309b3ece30b8cd Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Thu, 30 Oct 2014 09:12:15 +0300 Subject: [PATCH 2716/9457] PPC: bpf_jit_comp: add SKF_AD_PKTTYPE instruction Add BPF extension SKF_AD_PKTTYPE to ppc JIT to load skb->pkt_type field. Before: [ 88.262622] test_bpf: #11 LD_IND_NET 86 97 99 PASS [ 88.265740] test_bpf: #12 LD_PKTTYPE 109 107 PASS After: [ 80.605964] test_bpf: #11 LD_IND_NET 44 40 39 PASS [ 80.607370] test_bpf: #12 LD_PKTTYPE 9 9 PASS CC: Alexei Starovoitov CC: Michael Ellerman Cc: Matt Evans Signed-off-by: Denis Kirjanov v2: Added test rusults Signed-off-by: David S. Miller --- arch/powerpc/include/asm/ppc-opcode.h | 1 + arch/powerpc/net/bpf_jit.h | 7 +++++++ arch/powerpc/net/bpf_jit_comp.c | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 6f8536208049..1a5287759fc8 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -204,6 +204,7 @@ #define PPC_INST_ERATSX_DOT 0x7c000127 /* Misc instructions for BPF compiler */ +#define PPC_INST_LBZ 0x88000000 #define PPC_INST_LD 0xe8000000 #define PPC_INST_LHZ 0xa0000000 #define PPC_INST_LHBRX 0x7c00062c diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 9aee27c582dc..c406aa95b2bc 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -87,6 +87,9 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); #define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \ ___PPC_RA(base) | ((i) & 0xfffc)) + +#define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \ + ___PPC_RA(base) | IMM_L(i)) #define PPC_LD(r, base, i) EMIT(PPC_INST_LD | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) #define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | ___PPC_RT(r) | \ @@ -96,6 +99,10 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ ___PPC_RA(base) | ___PPC_RB(b)) /* Convenience helpers for the above with 'far' offsets: */ +#define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \ + else { PPC_ADDIS(r, base, IMM_HA(i)); \ + PPC_LBZ(r, r, IMM_L(i)); } } while(0) + #define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \ else { PPC_ADDIS(r, base, IMM_HA(i)); \ PPC_LD(r, r, IMM_L(i)); } } while(0) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index cbae2dfd053c..d110e288d7ac 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -407,6 +407,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, queue_mapping)); break; + case BPF_ANC | SKF_AD_PKTTYPE: + PPC_LBZ_OFFS(r_A, r_skb, PKT_TYPE_OFFSET()); + PPC_ANDI(r_A, r_A, PKT_TYPE_MAX); + PPC_SRWI(r_A, r_A, 5); + break; case BPF_ANC | SKF_AD_CPU: #ifdef CONFIG_SMP /* -- GitLab From ec5a0ec1a4b0a065148905340cd5f0e2a4425b6f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 3 Nov 2014 17:42:29 +0530 Subject: [PATCH 2717/9457] hamradio: 6pack: remove unnecessary check this is check for dev is unnecessary, as we are already checking dev after allocating it via alloc_netdev, and jumping to label: out if it is NULL. Signed-off-by: Sudip Mukherjee Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index c3c4051a089d..daca0dee88f3 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -675,8 +675,7 @@ static int sixpack_open(struct tty_struct *tty) kfree(xbuff); kfree(rbuff); - if (dev) - free_netdev(dev); + free_netdev(dev); out: return err; -- GitLab From 7e16e3fe1b3a6ae88e403e6898ddc46be063dbef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 3 Nov 2014 18:28:32 -0200 Subject: [PATCH 2718/9457] [media] cx231xx: Remove a bogus check for NULL As reported by kbuild test robot: drivers/media/usb/cx231xx/cx231xx-audio.c:445:16-20: ERROR: dev is NULL but dereferenced. Reported-by: kbuild test robot Reported-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-audio.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 6d9a03402faf..de4ae5eb4830 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -439,12 +439,6 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) dev_dbg(dev->dev, "opening device and trying to acquire exclusive lock\n"); - if (!dev) { - dev_err(dev->dev, - "BUG: cx231xx can't find device struct. Can't proceed with open\n"); - return -ENODEV; - } - if (dev->state & DEV_DISCONNECTED) { dev_err(dev->dev, "Can't open. the device was removed.\n"); -- GitLab From 094f1ca516cd32ecda8b99821a316cb4e0f367cd Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 3 Nov 2014 17:55:51 -0300 Subject: [PATCH 2719/9457] [media] media: Fix a compiler warning in media_entity_pipeline_start() Patch "[media] media: Print information on failed link validation" cause a harmless compiler warning in printing a debug message. Fix this. The type casting is done do ensure the type really is suitable for printing as %u, as find_first_zero_bit() does return int on some architectures and unsigned long on others. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4122d7f42e10..4d8e01c7b1b2 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -297,7 +297,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, dev_dbg(entity->parent->dev, "\"%s\":%u must be connected by an enabled link\n", entity->name, - find_first_zero_bit(active, entity->num_pads)); + (unsigned)find_first_zero_bit( + active, entity->num_pads)); goto error; } } -- GitLab From 56b174256b6936ec4c1ed8f3407109ac6929d3ca Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 3 Nov 2014 08:19:53 -0800 Subject: [PATCH 2720/9457] net: add rbnode to struct sk_buff Yaogong replaces TCP out of order receive queue by an RB tree. As netem already does a private skb->{next/prev/tstamp} union with a 'struct rb_node', lets do this in a cleaner way. Signed-off-by: Eric Dumazet Cc: Yaogong Wang Signed-off-by: David S. Miller --- include/linux/skbuff.h | 20 +++++++++++++------- net/sched/sch_netem.c | 27 +++++++-------------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6c8b6f604e76..5ad9675b6fe1 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -440,6 +441,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, * @next: Next buffer in list * @prev: Previous buffer in list * @tstamp: Time we arrived/left + * @rbnode: RB tree node, alternative to next/prev for netem/tcp * @sk: Socket we are owned by * @dev: Device we arrived on/are leaving by * @cb: Control buffer. Free for use by every layer. Put private vars here @@ -504,15 +506,19 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, */ struct sk_buff { - /* These two members must be first. */ - struct sk_buff *next; - struct sk_buff *prev; - union { - ktime_t tstamp; - struct skb_mstamp skb_mstamp; + struct { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + union { + ktime_t tstamp; + struct skb_mstamp skb_mstamp; + }; + }; + struct rb_node rbnode; /* used in netem & tcp stack */ }; - struct sock *sk; struct net_device *dev; diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index b34331967e02..179f1c8c0d8b 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -139,33 +139,20 @@ struct netem_sched_data { /* Time stamp put into socket buffer control block * Only valid when skbs are in our internal t(ime)fifo queue. + * + * As skb->rbnode uses same storage than skb->next, skb->prev and skb->tstamp, + * and skb->next & skb->prev are scratch space for a qdisc, + * we save skb->tstamp value in skb->cb[] before destroying it. */ struct netem_skb_cb { psched_time_t time_to_send; ktime_t tstamp_save; }; -/* Because space in skb->cb[] is tight, netem overloads skb->next/prev/tstamp - * to hold a rb_node structure. - * - * If struct sk_buff layout is changed, the following checks will complain. - */ -static struct rb_node *netem_rb_node(struct sk_buff *skb) -{ - BUILD_BUG_ON(offsetof(struct sk_buff, next) != 0); - BUILD_BUG_ON(offsetof(struct sk_buff, prev) != - offsetof(struct sk_buff, next) + sizeof(skb->next)); - BUILD_BUG_ON(offsetof(struct sk_buff, tstamp) != - offsetof(struct sk_buff, prev) + sizeof(skb->prev)); - BUILD_BUG_ON(sizeof(struct rb_node) > sizeof(skb->next) + - sizeof(skb->prev) + - sizeof(skb->tstamp)); - return (struct rb_node *)&skb->next; -} static struct sk_buff *netem_rb_to_skb(struct rb_node *rb) { - return (struct sk_buff *)rb; + return container_of(rb, struct sk_buff, rbnode); } static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb) @@ -403,8 +390,8 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) else p = &parent->rb_left; } - rb_link_node(netem_rb_node(nskb), parent, p); - rb_insert_color(netem_rb_node(nskb), &q->t_root); + rb_link_node(&nskb->rbnode, parent, p); + rb_insert_color(&nskb->rbnode, &q->t_root); sch->q.qlen++; } -- GitLab From 98a18b6ffc79baa69f4a0d1bae58faf2a8aef4c8 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 2 Nov 2014 06:44:54 +0100 Subject: [PATCH 2721/9457] netdevice: add ieee802154_ptr to net_device This patch adds an ieee802154_ptr to the net_device structure. Furthermore the 802.15.4 subsystem will introduce a nl802154 framework which is similar like the nl80211 framework and a wpan_dev structure. The wpan_dev structure will hold additional net_device attributes like address options which are 802.15.4 specific. In the upcoming nl802154 implementation we will introduce a NL802154_FLAG_NEED_WPAN_DEV like NL80211_FLAG_NEED_WDEV. For this flag an ieee802154_ptr in net_device is needed. Additional we can access the wpan_dev attributes in upper layers like IEEE 802.15.4 6LoWPAN easily. Current solution is a complicated callback interface and getting these values over subif data structure in mac802154. Signed-off-by: Alexander Aring Acked-by: David S. Miller Signed-off-by: Marcel Holtmann --- include/linux/netdevice.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 74fd5d37f15a..c9bcf33efb47 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -57,6 +57,8 @@ struct device; struct phy_device; /* 802.11 specific */ struct wireless_dev; +/* 802.15.4 specific */ +struct wpan_dev; void netdev_set_default_ethtool_ops(struct net_device *dev, const struct ethtool_ops *ops); @@ -1572,6 +1574,7 @@ struct net_device { struct inet6_dev __rcu *ip6_ptr; void *ax25_ptr; struct wireless_dev *ieee80211_ptr; + struct wpan_dev *ieee802154_ptr; /* * Cache lines mostly used on receive path (including eth_type_trans()) -- GitLab From aa292fa4093d7afab513fee77e3f78229968b931 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Fri, 31 Oct 2014 02:45:37 +0200 Subject: [PATCH 2722/9457] ath6kl: remove incorrect reset_resume handler Existing implementation of reset_resume handler just calls ath6kl_usb_remove() that deallocates all resources. It can lead to double free, etc. on disconnect. The patch removes reset_resume handler, so usb core could conservatively reset the driver. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/usb.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index a6a5e40b3e98..9da3594fd010 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -1193,18 +1193,10 @@ static int ath6kl_usb_pm_resume(struct usb_interface *interface) return 0; } -static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf) -{ - if (usb_get_intfdata(intf)) - ath6kl_usb_remove(intf); - return 0; -} - #else #define ath6kl_usb_pm_suspend NULL #define ath6kl_usb_pm_resume NULL -#define ath6kl_usb_pm_reset_resume NULL #endif @@ -1222,7 +1214,6 @@ static struct usb_driver ath6kl_usb_driver = { .probe = ath6kl_usb_probe, .suspend = ath6kl_usb_pm_suspend, .resume = ath6kl_usb_pm_resume, - .reset_resume = ath6kl_usb_pm_reset_resume, .disconnect = ath6kl_usb_remove, .id_table = ath6kl_usb_ids, .supports_autosuspend = true, -- GitLab From 707b1bbd7e6ec533cfa027054ccbeb90113a40b0 Mon Sep 17 00:00:00 2001 From: Bartosz Markowski Date: Fri, 31 Oct 2014 09:03:43 +0100 Subject: [PATCH 2723/9457] ath10k: fix pm resume after suspend Firmware was crashing when we were trying to warm reset it after suspend. This was due to the fact that target registeres can be accessed only if the hardware is awaken. This patch makes sure to awake the device also on the hif up, not only in case of probe call. Signed-off-by: Bartosz Markowski Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index f5e426ea2570..3a6b8a5ca96c 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1875,6 +1875,12 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); + ret = ath10k_pci_wake(ar); + if (ret) { + ath10k_err(ar, "failed to wake up target: %d\n", ret); + return ret; + } + /* * Bring the target up cleanly. * @@ -1888,13 +1894,13 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) ret = ath10k_pci_chip_reset(ar); if (ret) { ath10k_err(ar, "failed to reset chip: %d\n", ret); - goto err; + goto err_sleep; } ret = ath10k_pci_init_pipes(ar); if (ret) { ath10k_err(ar, "failed to initialize CE: %d\n", ret); - goto err; + goto err_sleep; } ret = ath10k_pci_init_config(ar); @@ -1914,7 +1920,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) err_ce: ath10k_pci_ce_deinit(ar); -err: +err_sleep: + ath10k_pci_sleep(ar); return ret; } @@ -1925,6 +1932,8 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar) /* Currently hif_power_up performs effectively a reset and hif_stop * resets the chip as well so there's no point in resetting here. */ + + ath10k_pci_sleep(ar); } #ifdef CONFIG_PM @@ -2526,6 +2535,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_deinit_irq; } + ath10k_pci_sleep(ar); + ret = ath10k_core_register(ar, chip_id); if (ret) { ath10k_err(ar, "failed to register driver core: %d\n", ret); @@ -2577,7 +2588,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev) ath10k_pci_deinit_irq(ar); ath10k_pci_ce_deinit(ar); ath10k_pci_free_pipes(ar); - ath10k_pci_sleep(ar); ath10k_pci_release(ar); ath10k_core_destroy(ar); } -- GitLab From 61fbe96c8b131dcf246030c72dfe97a2cbfb247b Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 28 Oct 2014 10:20:29 +0100 Subject: [PATCH 2724/9457] cdc-acm: Drop the warning for unusual capabilities Let's drop the warning for modems with unusual capabilities, the associated quirk and blacklist. They made little sense. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 7 ------- drivers/usb/class/cdc-acm.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e934e19f49f5..a78a7a4560c8 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1144,8 +1144,6 @@ static int acm_probe(struct usb_interface *intf, case USB_CDC_CALL_MANAGEMENT_TYPE: call_management_function = buffer[3]; call_interface_num = buffer[4]; - if ((quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) - dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); break; default: /* there are LOTS more CDC descriptors that @@ -1796,11 +1794,6 @@ static const struct usb_device_id acm_ids[] = { /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ - /* Support Lego NXT using pbLua firmware */ - { USB_DEVICE(0x0694, 0xff00), - .driver_info = NOT_A_MODEM, - }, - /* Support for Droids MuIn LCD */ { USB_DEVICE(0x04d8, 0x000b), .driver_info = NO_DATA_INTERFACE, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index fc75651afe1c..8cd2c4b0b8ff 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -129,6 +129,5 @@ struct acm { #define NO_UNION_NORMAL BIT(0) #define SINGLE_RX_URB BIT(1) #define NO_CAP_LINE BIT(2) -#define NOT_A_MODEM BIT(3) #define NO_DATA_INTERFACE BIT(4) #define IGNORE_DEVICE BIT(5) -- GitLab From 6d40500ac9b69b78dace3a498bc1690200682789 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Mon, 6 Oct 2014 11:51:10 +0530 Subject: [PATCH 2725/9457] usb: ehci/ohci-exynos: Fix of_node_put() for child when getting PHYs On enabling CONFIG_OF_SELFTEST which enables CONFIG_OF_DYNAMIC, we found out that while getting PHYs for the controller we were doing an extra of_node_put on the child node in our routines - exynos_e/ohci_get_phy(). This child is however already put by of_get_next_available_child() which does a of_node_put() on the "prev" node. So there's no point in putting the same node again in our routine. Reported-by: Daniel Drake Signed-off-by: Vivek Gautam Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-exynos.c | 1 - drivers/usb/host/ohci-exynos.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 7189f2e32ac2..1b726bfdcbea 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -74,7 +74,6 @@ static int exynos_ehci_get_phy(struct device *dev, phy = devm_of_phy_get(dev, child, NULL); exynos_ehci->phy[phy_number] = phy; - of_node_put(child); if (IS_ERR(phy)) { ret = PTR_ERR(phy); if (ret == -EPROBE_DEFER) { diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index d28b6583ba02..39f366b6b1a7 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -63,7 +63,6 @@ static int exynos_ohci_get_phy(struct device *dev, phy = devm_of_phy_get(dev, child, NULL); exynos_ohci->phy[phy_number] = phy; - of_node_put(child); if (IS_ERR(phy)) { ret = PTR_ERR(phy); if (ret == -EPROBE_DEFER) { -- GitLab From dd3cf17488b102092014e517b4f18f24e5e3d4aa Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 6 Oct 2014 11:10:46 +0200 Subject: [PATCH 2726/9457] usb: host: Remove optional dependencies on PLAT_S5P Commit d78c16ccde96 ("ARM: SAMSUNG: Remove remaining legacy code") removed the Kconfig symbol PLAT_S5P. Remove two optional dependencies on that symbol from this Kconfig file too. Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a8a30b1d4167..ef0447489f13 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -234,7 +234,7 @@ config USB_EHCI_SH config USB_EHCI_EXYNOS tristate "EHCI support for Samsung S5P/EXYNOS SoC Series" - depends on PLAT_S5P || ARCH_EXYNOS + depends on ARCH_EXYNOS help Enable support for the Samsung Exynos SOC's on-chip EHCI controller. @@ -550,7 +550,7 @@ config USB_OHCI_SH config USB_OHCI_EXYNOS tristate "OHCI support for Samsung S5P/EXYNOS SoC Series" - depends on PLAT_S5P || ARCH_EXYNOS + depends on ARCH_EXYNOS help Enable support for the Samsung Exynos SOC's on-chip OHCI controller. -- GitLab From e50a322e517731de5d1f6f3aad0a73f3b506c5ea Mon Sep 17 00:00:00 2001 From: Josef Gajdusek Date: Thu, 9 Oct 2014 15:47:54 +0200 Subject: [PATCH 2727/9457] usb: Do not re-read descriptors for wired devices in usb_authorize_device() This patch modifies the usb_authorize_device() function such as that it does not reload the device descriptor for wired devices. The reasons for this are as follows: * Some devices dislike the master requesting the descriptor from them twice, failing on the usb_get_device_descriptor() call with -ETIMEOUT. Observed this on my Pretec 16GB flash drive (4146:ba65). * Malicious device could send two different descriptors - one before authorization, used by userspace to determine whether to authorize it and second to be actually used by the kernel when determining which drivers to bind. Signed-off-by: Josef Gajdusek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 11e80ac31324..c096a1a135cc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2543,11 +2543,14 @@ int usb_authorize_device(struct usb_device *usb_dev) "can't autoresume for authorization: %d\n", result); goto error_autoresume; } - result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); - if (result < 0) { - dev_err(&usb_dev->dev, "can't re-read device descriptor for " - "authorization: %d\n", result); - goto error_device_descriptor; + + if (usb_dev->wusb) { + result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); + if (result < 0) { + dev_err(&usb_dev->dev, "can't re-read device descriptor for " + "authorization: %d\n", result); + goto error_device_descriptor; + } } usb_dev->authorized = 1; -- GitLab From 1cc373c654acde47d78da9cccb5732dab2cc584f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 10 Oct 2014 18:19:45 +0530 Subject: [PATCH 2728/9457] usb: yurex: fixed sparse warning of incorrect type fixed sparse warning of 1) incorrect type (different address spaces) 2) incorrect type in initializer Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/yurex.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index c3a45da11610..343fa6ff9f4b 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -410,7 +410,8 @@ static int yurex_release(struct inode *inode, struct file *file) return 0; } -static ssize_t yurex_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, + loff_t *ppos) { struct usb_yurex *dev; int retval = 0; @@ -444,7 +445,8 @@ static ssize_t yurex_read(struct file *file, char *buffer, size_t count, loff_t return retval; } -static ssize_t yurex_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) +static ssize_t yurex_write(struct file *file, const char __user *user_buffer, + size_t count, loff_t *ppos) { struct usb_yurex *dev; int i, set = 0, retval = 0; -- GitLab From e28e2f2f7c42e5b9dd4c965a0245267e44a8a7ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Oct 2014 12:19:40 +0200 Subject: [PATCH 2729/9457] uas: Make uas work with blk-mq With uas over usb-3 the tags inside the uas iu-s must match the usb-3 stream ids, and those go from 1 - qdepth. Before blk-mq calling scsi_activate_tcq(sdev, qdepth) guaranteed that we would only get cmnd->request->tag from 0 - (qdepth - 1), and we used those as uas-tags / stream-ids. With blk-mq however we are guaranteed to never get more then qdepth commands queued at the same time, but the cmnd->request->tag values may be much larger, which breaks uas. This commit fixes this by generating uas tags in the 1 - qdepth range ourselves instead of using cmnd->request->tag. While touching all involved code anyways also rename the uas_cmd_info stream field to uas_tag, because when using uas over usb-2 streams are not used. Cc: Christoph Hellwig Reported-by: Douglas Gilbert Signed-off-by: Hans de Goede Reviewed-by: Christoph Hellwig -- Changes in v2: -Remove ".disable_blk_mq = true" from uas_host_template Changes in v3: -Rebased on top of Linus' current master branch Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 64 ++++++++++++++------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 89b24349269e..004ebc12bc21 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -66,7 +66,7 @@ enum { /* Overrides scsi_pointer */ struct uas_cmd_info { unsigned int state; - unsigned int stream; + unsigned int uas_tag; struct urb *cmd_urb; struct urb *data_in_urb; struct urb *data_out_urb; @@ -173,30 +173,15 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; } -/* - * scsi-tags go from 0 - (nr_tags - 1), uas tags need to match stream-ids, - * which go from 1 - nr_streams. And we use 1 for untagged commands. - */ -static int uas_get_tag(struct scsi_cmnd *cmnd) -{ - int tag; - - if (blk_rq_tagged(cmnd->request)) - tag = cmnd->request->tag + 2; - else - tag = 1; - - return tag; -} - static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix, int status) { struct uas_cmd_info *ci = (void *)&cmnd->SCp; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; scmd_printk(KERN_INFO, cmnd, - "%s %d tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ", - prefix, status, uas_get_tag(cmnd), + "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ", + prefix, status, cmdinfo->uas_tag, (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", (ci->state & SUBMIT_DATA_IN_URB) ? " s-in" : "", @@ -242,7 +227,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) DATA_OUT_URB_INFLIGHT | COMMAND_ABORTED)) return -EBUSY; - devinfo->cmnd[uas_get_tag(cmnd) - 1] = NULL; + devinfo->cmnd[cmdinfo->uas_tag - 1] = NULL; uas_free_unsubmitted_urbs(cmnd); cmnd->scsi_done(cmnd); return 0; @@ -289,7 +274,7 @@ static void uas_stat_cmplt(struct urb *urb) idx = be16_to_cpup(&iu->tag) - 1; if (idx >= MAX_CMNDS || !devinfo->cmnd[idx]) { dev_err(&urb->dev->dev, - "stat urb: no pending cmd for tag %d\n", idx + 1); + "stat urb: no pending cmd for uas-tag %d\n", idx + 1); goto out; } @@ -427,7 +412,8 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto out; usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, cmnd); - urb->stream_id = cmdinfo->stream; + if (devinfo->use_streams) + urb->stream_id = cmdinfo->uas_tag; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; urb->sg = sdb->table.sgl; out: @@ -451,7 +437,8 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), uas_stat_cmplt, cmnd->device->host); - urb->stream_id = cmdinfo->stream; + if (devinfo->use_streams) + urb->stream_id = cmdinfo->uas_tag; urb->transfer_flags |= URB_FREE_BUFFER; out: return urb; @@ -465,6 +452,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, { struct usb_device *udev = devinfo->udev; struct scsi_device *sdev = cmnd->device; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct urb *urb = usb_alloc_urb(0, gfp); struct command_iu *iu; int len; @@ -481,7 +469,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; iu->iu_id = IU_ID_COMMAND; - iu->tag = cpu_to_be16(uas_get_tag(cmnd)); + iu->tag = cpu_to_be16(cmdinfo->uas_tag); iu->prio_attr = UAS_SIMPLE_TAG; iu->len = len; int_to_scsilun(sdev->lun, &iu->lun); @@ -608,8 +596,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, struct uas_dev_info *devinfo = sdev->hostdata; struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; unsigned long flags; - unsigned int stream; - int err; + int idx, err; BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); @@ -635,8 +622,12 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, return 0; } - stream = uas_get_tag(cmnd); - if (devinfo->cmnd[stream - 1]) { + /* Find a free uas-tag */ + for (idx = 0; idx < devinfo->qdepth; idx++) { + if (!devinfo->cmnd[idx]) + break; + } + if (idx == devinfo->qdepth) { spin_unlock_irqrestore(&devinfo->lock, flags); return SCSI_MLQUEUE_DEVICE_BUSY; } @@ -644,7 +635,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, cmnd->scsi_done = done; memset(cmdinfo, 0, sizeof(*cmdinfo)); - cmdinfo->stream = stream; + cmdinfo->uas_tag = idx + 1; /* uas-tag == usb-stream-id, so 1 based */ cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB; switch (cmnd->sc_data_direction) { @@ -659,10 +650,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, break; } - if (!devinfo->use_streams) { + if (!devinfo->use_streams) cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); - cmdinfo->stream = 0; - } err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); if (err) { @@ -674,7 +663,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, uas_add_work(cmdinfo); } - devinfo->cmnd[stream - 1] = cmnd; + devinfo->cmnd[idx] = cmnd; spin_unlock_irqrestore(&devinfo->lock, flags); return 0; } @@ -702,7 +691,7 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) cmdinfo->state |= COMMAND_ABORTED; /* Drop all refs to this cmnd, kill data urbs to break their ref */ - devinfo->cmnd[uas_get_tag(cmnd) - 1] = NULL; + devinfo->cmnd[cmdinfo->uas_tag - 1] = NULL; if (cmdinfo->state & DATA_IN_URB_INFLIGHT) data_in_urb = usb_get_urb(cmdinfo->data_in_urb); if (cmdinfo->state & DATA_OUT_URB_INFLIGHT) @@ -818,13 +807,6 @@ static struct scsi_host_template uas_host_template = { .cmd_per_lun = 1, /* until we override it */ .skip_settle_delay = 1, .ordered_tag = 1, - - /* - * The uas drivers expects tags not to be bigger than the maximum - * per-device queue depth, which is not true with the blk-mq tag - * allocator. - */ - .disable_blk_mq = true, }; #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ -- GitLab From 11a7e59405148c855e0a9d13588930ccec02c150 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Mon, 13 Oct 2014 09:53:03 +0800 Subject: [PATCH 2730/9457] usb: ehci: add ehci_port_power interface The current EHCI implementation is prepared to toggle the PORT_POWER bit to enable or disable a USB-Port. In some cases this port power can not be just toggled by the PORT_POWER bit, and the gpio-regulator is needed to be toggled too. This patch defines a port power control interface ehci_port_power for ehci core use, it toggles PORT_POWER bit as well as calls platform defined .port_power if it is defined. Signed-off-by: Michael Grzeschik Signed-off-by: Peter Chen Acked-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 9 +++++++- drivers/usb/host/ehci-hub.c | 45 ++++++++++++++++++++++++++----------- drivers/usb/host/ehci.h | 2 ++ include/linux/usb/hcd.h | 3 +++ 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 15feaf924b71..df75b8e7d157 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -311,6 +311,7 @@ static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable); #include "ehci-timer.c" #include "ehci-hub.c" @@ -329,9 +330,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) { int port = HCS_N_PORTS(ehci->hcs_params); - while (port--) + while (port--) { ehci_writel(ehci, PORT_RWC_BITS, &ehci->regs->port_status[port]); + spin_unlock_irq(&ehci->lock); + ehci_port_power(ehci, port, false); + spin_lock_irq(&ehci->lock); + } } /* @@ -1233,6 +1238,8 @@ void ehci_init_driver(struct hc_driver *drv, drv->hcd_priv_size += over->extra_priv_size; if (over->reset) drv->reset = over->reset; + if (over->port_power) + drv->port_power = over->port_power; } } EXPORT_SYMBOL_GPL(ehci_init_driver); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 5728829cf6ef..118edb7bdca2 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -69,10 +69,8 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) if (test_bit(port, &ehci->owned_ports)) { reg = &ehci->regs->port_status[port]; status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; - if (!(status & PORT_POWER)) { - status |= PORT_POWER; - ehci_writel(ehci, status, reg); - } + if (!(status & PORT_POWER)) + ehci_port_power(ehci, port, true); } } @@ -952,9 +950,11 @@ int ehci_hub_control( clear_bit(wIndex, &ehci->port_c_suspend); break; case USB_PORT_FEAT_POWER: - if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, temp & ~PORT_POWER, - status_reg); + if (HCS_PPC(ehci->hcs_params)) { + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, false); + spin_lock_irqsave(&ehci->lock, flags); + } break; case USB_PORT_FEAT_C_CONNECTION: ehci_writel(ehci, temp | PORT_CSC, status_reg); @@ -1004,9 +1004,9 @@ int ehci_hub_control( */ if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle)) && HCS_PPC(ehci->hcs_params)) { - ehci_writel(ehci, - temp & ~(PORT_RWC_BITS | PORT_POWER), - status_reg); + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, false); + spin_lock_irqsave(&ehci->lock, flags); temp = ehci_readl(ehci, status_reg); } } @@ -1187,9 +1187,11 @@ int ehci_hub_control( set_bit(wIndex, &ehci->suspended_ports); break; case USB_PORT_FEAT_POWER: - if (HCS_PPC (ehci->hcs_params)) - ehci_writel(ehci, temp | PORT_POWER, - status_reg); + if (HCS_PPC(ehci->hcs_params)) { + spin_unlock_irqrestore(&ehci->lock, flags); + ehci_port_power(ehci, wIndex, true); + spin_lock_irqsave(&ehci->lock, flags); + } break; case USB_PORT_FEAT_RESET: if (temp & (PORT_SUSPEND|PORT_RESUME)) @@ -1297,3 +1299,20 @@ static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) reg = &ehci->regs->port_status[portnum - 1]; return ehci_readl(ehci, reg) & PORT_OWNER; } + +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable) +{ + struct usb_hcd *hcd = ehci_to_hcd(ehci); + u32 __iomem *status_reg = &ehci->regs->port_status[portnum]; + u32 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; + + if (enable) + ehci_writel(ehci, temp | PORT_POWER, status_reg); + else + ehci_writel(ehci, temp & ~PORT_POWER, status_reg); + + if (hcd->driver->port_power) + hcd->driver->port_power(hcd, portnum, enable); + + return 0; +} diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index eee228a26a0e..6f0577b0a5ae 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -859,6 +859,8 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) struct ehci_driver_overrides { size_t extra_priv_size; int (*reset)(struct usb_hcd *hcd); + int (*port_power)(struct usb_hcd *hcd, + int portnum, bool enable); }; extern void ehci_init_driver(struct hc_driver *drv, diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index cd96a2bc3388..9cf7e3594609 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -379,6 +379,9 @@ struct hc_driver { int (*disable_usb3_lpm_timeout)(struct usb_hcd *, struct usb_device *, enum usb3_link_state state); int (*find_raw_port_number)(struct usb_hcd *, int); + /* Call for power on/off the port if necessary */ + int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable); + }; static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd) -- GitLab From c8679a2fb8decc949c848ca58f93ff7fb619931a Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Mon, 13 Oct 2014 09:53:04 +0800 Subject: [PATCH 2731/9457] usb: chipidea: host: add portpower override This patch adds an external portpower override callback, only single port regulator control is supported now. Signed-off-by: Michael Grzeschik Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/host.c | 67 +++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebde7b6ce687..33027abb5349 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -34,6 +34,44 @@ static struct hc_driver __read_mostly ci_ehci_hc_driver; +struct ehci_ci_priv { + struct regulator *reg_vbus; +}; + +static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; + struct device *dev = hcd->self.controller; + struct ci_hdrc *ci = dev_get_drvdata(dev); + int ret = 0; + int port = HCS_N_PORTS(ehci->hcs_params); + + if (priv->reg_vbus && !ci_otg_is_fsm_mode(ci)) { + if (port > 1) { + dev_warn(dev, + "Not support multi-port regulator control\n"); + return 0; + } + if (enable) + ret = regulator_enable(priv->reg_vbus); + else + ret = regulator_disable(priv->reg_vbus); + if (ret) { + dev_err(dev, + "Failed to %s vbus regulator, ret=%d\n", + enable ? "enable" : "disable", ret); + return ret; + } + } + return 0; +}; + +static const struct ehci_driver_overrides ehci_ci_overrides = { + .extra_priv_size = sizeof(struct ehci_ci_priv), + .port_power = ehci_ci_portpower, +}; + static irqreturn_t host_irq(struct ci_hdrc *ci) { return usb_hcd_irq(ci->irq, ci->hcd); @@ -43,6 +81,7 @@ static int host_start(struct ci_hdrc *ci) { struct usb_hcd *hcd; struct ehci_hcd *ehci; + struct ehci_ci_priv *priv; int ret; if (usb_disabled()) @@ -68,23 +107,15 @@ static int host_start(struct ci_hdrc *ci) ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; ehci->imx28_write_fix = ci->imx28_write_fix; - /* - * vbus is always on if host is not in OTG FSM mode, - * otherwise should be controlled by OTG FSM - */ - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { - ret = regulator_enable(ci->platdata->reg_vbus); - if (ret) { - dev_err(ci->dev, - "Failed to enable vbus regulator, ret=%d\n", - ret); - goto put_hcd; - } - } + priv = (struct ehci_ci_priv *)ehci->priv; + priv->reg_vbus = NULL; + + if (ci->platdata->reg_vbus) + priv->reg_vbus = ci->platdata->reg_vbus; ret = usb_add_hcd(hcd, 0, 0); if (ret) { - goto disable_reg; + goto put_hcd; } else { struct usb_otg *otg = ci->transceiver->otg; @@ -100,10 +131,6 @@ static int host_start(struct ci_hdrc *ci) return ret; -disable_reg: - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) - regulator_disable(ci->platdata->reg_vbus); - put_hcd: usb_put_hcd(hcd); @@ -117,8 +144,6 @@ static void host_stop(struct ci_hdrc *ci) if (hcd) { usb_remove_hcd(hcd); usb_put_hcd(hcd); - if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) - regulator_disable(ci->platdata->reg_vbus); } } @@ -146,7 +171,7 @@ int ci_hdrc_host_init(struct ci_hdrc *ci) rdrv->name = "host"; ci->roles[CI_ROLE_HOST] = rdrv; - ehci_init_driver(&ci_ehci_hc_driver, NULL); + ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides); return 0; } -- GitLab From a4760b3413732bccac2795b6aed28e2ff99c8ef4 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 11 Oct 2014 11:10:47 -0700 Subject: [PATCH 2732/9457] USB: OHCI: Eliminate platform-specific test in ohci.h The bcm63xx and bcm3384 platforms need to set OHCI_QUIRK_FRAME_NO, but they are non-PPC platforms and don't enable CONFIG_PPC_MPC52xx. Therefore this patch changes the code that uses OHCI_QUIRK_FRAME_NO, making it not depend on CONFIG_PPC_MPC52xx. Also, rephrase the comments describing OHCI_QUIRK_FRAME_NO and the related PSW endian swap. Signed-off-by: Kevin Cernekee Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 59f424567a8d..bc462288cfb0 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -647,23 +647,22 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) /*-------------------------------------------------------------------------*/ -/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all - * hardware handles 16 bit reads. That creates a different confusion on - * some big-endian SOC implementations. Same thing happens with PSW access. +/* + * The HCCA frame number is 16 bits, but is accessed as 32 bits since not all + * hardware handles 16 bit reads. Depending on the SoC implementation, the + * frame number can wind up in either bits [31:16] (default) or + * [15:0] (OHCI_QUIRK_FRAME_NO) on big endian hosts. + * + * Somewhat similarly, the 16-bit PSW fields in a transfer descriptor are + * reordered on BE. */ -#ifdef CONFIG_PPC_MPC52xx -#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) -#else -#define big_endian_frame_no_quirk(ohci) 0 -#endif - static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) { u32 tmp; if (big_endian_desc(ohci)) { tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); - if (!big_endian_frame_no_quirk(ohci)) + if (!(ohci->flags & OHCI_QUIRK_FRAME_NO)) tmp >>= 16; } else tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); -- GitLab From c4b8692a0520331a0ede604e20a0a52b96a98607 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 11 Oct 2014 11:10:48 -0700 Subject: [PATCH 2733/9457] USB: ohci-platform: Expose no_big_frame_no and num_ports in DT These quirks are currently set through platform_data; allow DT-based SoCs to use them too. Signed-off-by: Kevin Cernekee Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-ohci.txt | 2 ++ drivers/usb/host/ohci-platform.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt index b968a1aea995..19233b7365e1 100644 --- a/Documentation/devicetree/bindings/usb/usb-ohci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt @@ -9,6 +9,8 @@ Optional properties: - big-endian-regs : boolean, set this for hcds with big-endian registers - big-endian-desc : boolean, set this for hcds with big-endian descriptors - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc +- no-big-frame-no : boolean, set if frame_no lives in bits [15:0] of HCCA +- num-ports : u32, to override the detected port count - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4369299064c7..6fb03f88b51d 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -175,6 +175,12 @@ static int ohci_platform_probe(struct platform_device *dev) if (of_property_read_bool(dev->dev.of_node, "big-endian")) ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; + if (of_property_read_bool(dev->dev.of_node, "no-big-frame-no")) + ohci->flags |= OHCI_QUIRK_FRAME_NO; + + of_property_read_u32(dev->dev.of_node, "num-ports", + &ohci->num_ports); + priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); -- GitLab From 46f21949eb77a9dfc14a00071539929d11bcf69b Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 11 Oct 2014 11:10:49 -0700 Subject: [PATCH 2734/9457] USB: ohci-platform: Move platform_data checks into the probe function This puts all of the platform_data checks in the same place, and removes the need for a custom drv->reset() callback. Signed-off-by: Kevin Cernekee Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 6fb03f88b51d..7793c3cfcf1f 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -43,20 +43,6 @@ struct ohci_platform_priv { static const char hcd_name[] = "ohci-platform"; -static int ohci_platform_reset(struct usb_hcd *hcd) -{ - struct platform_device *pdev = to_platform_device(hcd->self.controller); - struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - if (pdata->no_big_frame_no) - ohci->flags |= OHCI_QUIRK_FRAME_NO; - if (pdata->num_ports) - ohci->num_ports = pdata->num_ports; - - return ohci_setup(hcd); -} - static int ohci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); @@ -110,7 +96,6 @@ static struct hc_driver __read_mostly ohci_platform_hc_driver; static const struct ohci_driver_overrides platform_overrides __initconst = { .product_desc = "Generic Platform OHCI controller", - .reset = ohci_platform_reset, .extra_priv_size = sizeof(struct ohci_platform_priv), }; @@ -218,6 +203,10 @@ static int ohci_platform_probe(struct platform_device *dev) ohci->flags |= OHCI_QUIRK_BE_DESC; if (pdata->big_endian_mmio) ohci->flags |= OHCI_QUIRK_BE_MMIO; + if (pdata->no_big_frame_no) + ohci->flags |= OHCI_QUIRK_FRAME_NO; + if (pdata->num_ports) + ohci->num_ports = pdata->num_ports; #ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO if (ohci->flags & OHCI_QUIRK_BE_MMIO) { -- GitLab From 474fe70bcf04b4d99867bc214c70d45624ab6f6f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 16 Oct 2014 17:52:38 +0200 Subject: [PATCH 2735/9457] USB: OHCI: ohci-at91: remove unnecessary headers Remove unnecessary mach/* headers to be able to converge to a multiplatform kernel. Signed-off-by: Alexandre Belloni Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e49eb4f90f5d..6181549883af 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -24,12 +24,8 @@ #include #include -#include #include -#include - - #include "ohci.h" #define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) -- GitLab From e5283626f5d535c54cbcc3ec4a60a4746578a4c2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 20 Oct 2014 20:51:00 -0700 Subject: [PATCH 2736/9457] usb: storage: Convert usb_stor_dbg to return void No caller or macro uses the return value so make it void. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/debug.c | 7 ++----- drivers/usb/storage/debug.h | 10 ++++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index e08f64780e30..05bc379b9e62 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -179,17 +179,14 @@ void usb_stor_show_sense(const struct us_data *us, US_DEBUGPX("\n"); } -int usb_stor_dbg(const struct us_data *us, const char *fmt, ...) +void usb_stor_dbg(const struct us_data *us, const char *fmt, ...) { va_list args; - int r; va_start(args, fmt); - r = dev_vprintk_emit(7, &us->pusb_dev->dev, fmt, args); + dev_vprintk_emit(7, &us->pusb_dev->dev, fmt, args); va_end(args); - - return r; } EXPORT_SYMBOL_GPL(usb_stor_dbg); diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index b1273f03e223..f52520306e1a 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -50,15 +50,17 @@ void usb_stor_show_command(const struct us_data *us, struct scsi_cmnd *srb); void usb_stor_show_sense(const struct us_data *us, unsigned char key, unsigned char asc, unsigned char ascq); -__printf(2, 3) int usb_stor_dbg(const struct us_data *us, - const char *fmt, ...); +__printf(2, 3) void usb_stor_dbg(const struct us_data *us, + const char *fmt, ...); #define US_DEBUGPX(fmt, ...) printk(fmt, ##__VA_ARGS__) #define US_DEBUG(x) x #else __printf(2, 3) -static inline int _usb_stor_dbg(const struct us_data *us, - const char *fmt, ...) {return 1;} +static inline void _usb_stor_dbg(const struct us_data *us, + const char *fmt, ...) +{ +} #define usb_stor_dbg(us, fmt, ...) \ do { if (0) _usb_stor_dbg(us, fmt, ##__VA_ARGS__); } while (0) #define US_DEBUGPX(fmt, ...) \ -- GitLab From 527307eacb014ba903b80694e6855fbdf20c89df Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 21 Oct 2014 15:51:34 +0530 Subject: [PATCH 2737/9457] usb: hub: remove unused variable the integer variable 'feature' was not being used anywhere in the function. so it is safe to remove the variable. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c096a1a135cc..89e9e2ca46fa 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3910,14 +3910,9 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, static int usb_disable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { - int feature; - switch (state) { case USB3_LPM_U1: - feature = USB_PORT_FEAT_U1_TIMEOUT; - break; case USB3_LPM_U2: - feature = USB_PORT_FEAT_U2_TIMEOUT; break; default: dev_warn(&udev->dev, "%s: Can't disable non-U1 or U2 state.\n", -- GitLab From a57971bfa1e9aa9b42ed72df027d5b985b31b56b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 22 Oct 2014 11:52:01 +0900 Subject: [PATCH 2738/9457] USB: imx21-hcd: use %pad for dma_addr_t Use %pad for dma_addr_t, because a dma_addr_t type can vary based on build options. So, it prevents the following build warnings in printks. drivers/usb/host/imx21-hcd.c:1175:2: warning: format '%X' expects argument of type 'unsigned int', but argument 8 has type 'dma_addr_t' [-Wformat] drivers/usb/host/imx21-hcd.c:1175:2: warning: format '%X' expects argument of type 'unsigned int', but argument 10 has type 'dma_addr_t' [-Wformat] Signed-off-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/imx21-hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 207bad99301f..eb4efba9f1ad 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1174,11 +1174,11 @@ static int imx21_hc_urb_enqueue(struct usb_hcd *hcd, dev_vdbg(imx21->dev, "enqueue urb=%p ep=%p len=%d " - "buffer=%p dma=%08X setupBuf=%p setupDma=%08X\n", + "buffer=%p dma=%pad setupBuf=%p setupDma=%pad\n", urb, ep, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma, - urb->setup_packet, urb->setup_dma); + urb->transfer_buffer, &urb->transfer_dma, + urb->setup_packet, &urb->setup_dma); if (usb_pipeisoc(urb->pipe)) return imx21_hc_urb_enqueue_isoc(hcd, ep, urb, mem_flags); -- GitLab From 5e4ccd9ee2508d04a39fa27de9eb7bf65bad7594 Mon Sep 17 00:00:00 2001 From: Wonhong Kwon Date: Fri, 24 Oct 2014 13:45:47 +0900 Subject: [PATCH 2739/9457] usb: ehci/ohci-platform: use SIMPLE_DEV_PM_OPS to support hibernation ehci/ohci-platform just define .suspend/.resume functions for dev_pm_ops, but in order to support both STR(suspend-to-ram) and hibernation, other callbacks such as .freeze/.thaw are also required. Registering all required callbacks for both STR and hibernation can be done by SIMPLE_DEV_PM_OPS macro function. Signed-off-by: Wonhong Kwon Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 15 ++++----------- drivers/usb/host/ohci-platform.c | 15 ++++----------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 2f5b9ce3e042..da056fe9d15b 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -311,8 +311,7 @@ static int ehci_platform_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -348,11 +347,7 @@ static int ehci_platform_resume(struct device *dev) ehci_resume(hcd, false); return 0; } - -#else /* !CONFIG_PM */ -#define ehci_platform_suspend NULL -#define ehci_platform_resume NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static const struct of_device_id vt8500_ehci_ids[] = { { .compatible = "via,vt8500-ehci", }, @@ -368,10 +363,8 @@ static const struct platform_device_id ehci_platform_table[] = { }; MODULE_DEVICE_TABLE(platform, ehci_platform_table); -static const struct dev_pm_ops ehci_platform_pm_ops = { - .suspend = ehci_platform_suspend, - .resume = ehci_platform_resume, -}; +static SIMPLE_DEV_PM_OPS(ehci_platform_pm_ops, ehci_platform_suspend, + ehci_platform_resume); static struct platform_driver ehci_platform_driver = { .id_table = ehci_platform_table, diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 7793c3cfcf1f..adb691d3087c 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -293,8 +293,7 @@ static int ohci_platform_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int ohci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -330,11 +329,7 @@ static int ohci_platform_resume(struct device *dev) ohci_resume(hcd, false); return 0; } - -#else /* !CONFIG_PM */ -#define ohci_platform_suspend NULL -#define ohci_platform_resume NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static const struct of_device_id ohci_platform_ids[] = { { .compatible = "generic-ohci", }, @@ -348,10 +343,8 @@ static const struct platform_device_id ohci_platform_table[] = { }; MODULE_DEVICE_TABLE(platform, ohci_platform_table); -static const struct dev_pm_ops ohci_platform_pm_ops = { - .suspend = ohci_platform_suspend, - .resume = ohci_platform_resume, -}; +static SIMPLE_DEV_PM_OPS(ohci_platform_pm_ops, ohci_platform_suspend, + ohci_platform_resume); static struct platform_driver ohci_platform_driver = { .id_table = ohci_platform_table, -- GitLab From 51f1741fcc166dd93d38c7a3212f195d84aa67df Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:55 +0800 Subject: [PATCH 2740/9457] usb: chipidea: otg_fsm: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/otg_fsm.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index caaabc58021e..e683595f9e69 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -782,11 +782,8 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) otg = devm_kzalloc(ci->dev, sizeof(struct usb_otg), GFP_KERNEL); - if (!otg) { - dev_err(ci->dev, - "Failed to allocate usb_otg structure for ci hdrc otg!\n"); + if (!otg) return -ENOMEM; - } otg->phy = ci->transceiver; otg->gadget = &ci->gadget; @@ -801,11 +798,8 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci) ci->fsm_timer = devm_kzalloc(ci->dev, sizeof(struct ci_otg_fsm_timer_list), GFP_KERNEL); - if (!ci->fsm_timer) { - dev_err(ci->dev, - "Failed to allocate timer structure for ci hdrc otg!\n"); + if (!ci->fsm_timer) return -ENOMEM; - } INIT_LIST_HEAD(&ci->fsm_timer->active_timers); retval = ci_otg_init_timers(ci); -- GitLab From b8f2854b06fad0ff3bb3eb0fa76813f50e03da64 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:55:56 +0800 Subject: [PATCH 2741/9457] usb: class: usbtmc: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index ec978408a2ee..960bc089111b 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1104,10 +1104,8 @@ static int usbtmc_probe(struct usb_interface *intf, dev_dbg(&intf->dev, "%s called\n", __func__); data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(&intf->dev, "Unable to allocate kernel memory\n"); + if (!data) return -ENOMEM; - } data->intf = intf; data->id = id; -- GitLab From 03cfba992ddaf92a026548f3b5ad565425253f27 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:01 +0800 Subject: [PATCH 2742/9457] usb: host: ehci-mv: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 08147c35f836..b1855c1b6cd4 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -153,7 +153,6 @@ static int mv_ehci_probe(struct platform_device *pdev) ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); if (ehci_mv == NULL) { - dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } -- GitLab From 25f852a5e142ae25bab81c084dc96e174355cc49 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:02 +0800 Subject: [PATCH 2743/9457] usb: host: ehci-sh: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sh.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 9b9b9f5b016e..f9ebf8af99b9 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -126,7 +126,6 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) priv = devm_kzalloc(&pdev->dev, sizeof(struct ehci_sh_priv), GFP_KERNEL); if (!priv) { - dev_dbg(&pdev->dev, "error allocating priv data\n"); ret = -ENOMEM; goto fail_request_resource; } -- GitLab From a41e4db0aaac75ab5db15185947c166412066cd6 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:03 +0800 Subject: [PATCH 2744/9457] usb: host: ehci-tegra: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index aaa01971efe9..3e6f685a00ff 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -484,7 +484,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) u_phy->otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!u_phy->otg) { - dev_err(&pdev->dev, "Failed to alloc memory for otg\n"); err = -ENOMEM; goto cleanup_phy; } -- GitLab From 58f7e76f7ce37417bd30f427168f75a9d84991ee Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:04 +0800 Subject: [PATCH 2745/9457] usb: host: oxu210hp-hcd: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/oxu210hp-hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 4fe79a2d71a9..75811dd5a9d7 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -3846,7 +3846,6 @@ static int oxu_drv_probe(struct platform_device *pdev) */ info = devm_kzalloc(&pdev->dev, sizeof(struct oxu_info), GFP_KERNEL); if (!info) { - dev_dbg(&pdev->dev, "error allocating memory\n"); ret = -EFAULT; goto error; } -- GitLab From 39d98bdc108b0d00be4318735384e03aed4f0466 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:05 +0800 Subject: [PATCH 2746/9457] usb: misc: usb3503: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb3503.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index ae7e1206ca54..b9af8cb19215 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -314,10 +314,8 @@ static int usb3503_i2c_probe(struct i2c_client *i2c, int err; hub = devm_kzalloc(&i2c->dev, sizeof(struct usb3503), GFP_KERNEL); - if (!hub) { - dev_err(&i2c->dev, "private data alloc fail\n"); + if (!hub) return -ENOMEM; - } i2c_set_clientdata(i2c, hub); hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config); @@ -336,10 +334,8 @@ static int usb3503_platform_probe(struct platform_device *pdev) struct usb3503 *hub; hub = devm_kzalloc(&pdev->dev, sizeof(struct usb3503), GFP_KERNEL); - if (!hub) { - dev_err(&pdev->dev, "private data alloc fail\n"); + if (!hub) return -ENOMEM; - } hub->dev = &pdev->dev; return usb3503_probe(hub); -- GitLab From 88538be35bc9d66bb425c431e30b3614482a840d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 14 Oct 2014 15:56:19 +0800 Subject: [PATCH 2747/9457] usb: renesas_usbhs: delete unnecessary 'out of memory' messages The memory subsystem has already had similar message for it. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index b3b6813ab270..6dae1151569b 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -505,10 +505,8 @@ static int usbhs_probe(struct platform_device *pdev) /* usb private data */ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "Could not allocate priv\n"); + if (!priv) return -ENOMEM; - } priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) -- GitLab From d9c3ae28bd6b72803e266eb384e0ba312f9ff837 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Oct 2014 11:52:57 +0200 Subject: [PATCH 2748/9457] uwb: Remove bogus colon after newline from debug message Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/rsv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 0887ae982783..536ad42b0a4b 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -213,7 +213,7 @@ void uwb_rsv_backoff_win_timer(unsigned long arg) bow->total_expired = 0; bow->window = UWB_DRP_BACKOFF_WIN_MIN >> 1; } - dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n: ", bow->total_expired, bow->n); + dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n", bow->total_expired, bow->n); /* try to relocate all the "to be moved" relocations */ uwb_rsv_handle_drp_avail_change(rc); @@ -234,7 +234,7 @@ void uwb_rsv_backoff_win_increment(struct uwb_rc *rc) bow->window <<= 1; bow->n = prandom_u32() & (bow->window - 1); - dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n); + dev_dbg(dev, "new_window=%d, n=%d\n", bow->window, bow->n); /* reset the timer associated variables */ timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US; -- GitLab From 140c7553231dcd119ebda8c27dec7f06aef7e323 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 2 Oct 2014 13:39:31 +0300 Subject: [PATCH 2749/9457] mei: drop unneeded client NULL check in cb structure The pointer to client in the callback structure (cb->cl) can't be NULL with current locking. We can drop check and warnings as in some cases this just uselessly complicates the code flow. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 24 +++++++++--------------- drivers/misc/mei/client.c | 2 +- drivers/misc/mei/hbm.c | 5 ----- drivers/misc/mei/interrupt.c | 12 +----------- 4 files changed, 11 insertions(+), 32 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 6cdce8477f57..0b5a3156917c 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -360,8 +360,7 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) void mei_amthif_run_next_cmd(struct mei_device *dev) { struct mei_cl_cb *cb; - struct mei_cl_cb *next; - int status; + int ret; if (!dev) return; @@ -376,16 +375,14 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) dev_dbg(dev->dev, "complete amthif cmd_list cb.\n"); - list_for_each_entry_safe(cb, next, &dev->amthif_cmd_list.list, list) { - list_del(&cb->list); - if (!cb->cl) - continue; - status = mei_amthif_send_cmd(dev, cb); - if (status) - dev_warn(dev->dev, "amthif write failed status = %d\n", - status); - break; - } + cb = list_first_entry_or_null(&dev->amthif_cmd_list.list, + typeof(*cb), list); + if (!cb) + return; + list_del(&cb->list); + ret = mei_amthif_send_cmd(dev, cb); + if (ret) + dev_warn(dev->dev, "amthif write failed status = %d\n", ret); } @@ -536,9 +533,6 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, cb = dev->iamthif_current_cb; dev->iamthif_current_cb = NULL; - if (!cb->cl) - return -ENODEV; - dev->iamthif_stall_timer = 0; cb->buf_idx = dev->iamthif_msg_buf_index; cb->read_time = jiffies; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index bc9ba5359bc6..1382d551d7ed 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -146,7 +146,7 @@ static void __mei_io_list_flush(struct mei_cl_cb *list, /* enable removing everything if no cl is specified */ list_for_each_entry_safe(cb, next, &list->list, list) { - if (!cl || (cb->cl && mei_cl_cmp_id(cl, cb->cl))) { + if (!cl || mei_cl_cmp_id(cl, cb->cl)) { list_del(&cb->list); if (free) mei_io_cb_free(cb); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 49a2653d91a5..57c1bde9b2b8 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -637,11 +637,6 @@ static void mei_hbm_cl_res(struct mei_device *dev, list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { cl = cb->cl; - /* this should not happen */ - if (WARN_ON(!cl)) { - list_del_init(&cb->list); - continue; - } if (cb->fop_type != fop_type) continue; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 20c6c511f438..711cddfa9c99 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -44,8 +44,6 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) list_for_each_entry_safe(cb, next, &compl_list->list, list) { cl = cb->cl; list_del(&cb->list); - if (!cl) - continue; dev_dbg(dev->dev, "completing call back.\n"); if (cl == &dev->iamthif_cl) @@ -105,7 +103,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, list_for_each_entry_safe(cb, next, &dev->read_list.list, list) { cl = cb->cl; - if (!cl || !mei_cl_is_reading(cl, mei_hdr)) + if (!mei_cl_is_reading(cl, mei_hdr)) continue; cl->reading_state = MEI_READING; @@ -449,8 +447,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) list = &dev->write_waiting_list; list_for_each_entry_safe(cb, next, &list->list, list) { cl = cb->cl; - if (cl == NULL) - continue; cl->status = 0; list_del(&cb->list); @@ -489,10 +485,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) dev_dbg(dev->dev, "complete control write list cb.\n"); list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) { cl = cb->cl; - if (!cl) { - list_del(&cb->list); - return -ENODEV; - } switch (cb->fop_type) { case MEI_FOP_DISCONNECT: /* send disconnect message */ @@ -530,8 +522,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) dev_dbg(dev->dev, "complete write list cb.\n"); list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { cl = cb->cl; - if (cl == NULL) - continue; if (cl == &dev->iamthif_cl) ret = mei_amthif_irq_write(cl, cb, cmpl_list); else -- GitLab From 3d32cf02241e307d3be92046a8cbd3deb8cda307 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 2 Oct 2014 13:39:32 +0300 Subject: [PATCH 2750/9457] mei: use local cl variables in wd and amthif Use local cl variable instead of dev->iamthif_cl and dev->wd_cl as the first step to use dynamic allocation of these clients as their are not supported on all platforms Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 10 ++++++---- drivers/misc/mei/wd.c | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 0b5a3156917c..79f53941779d 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -262,6 +262,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) { struct mei_msg_hdr mei_hdr; + struct mei_cl *cl; int ret; if (!dev || !cb) @@ -277,8 +278,9 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) dev->iamthif_msg_buf_size = cb->request_buffer.size; memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, cb->request_buffer.size); + cl = &dev->iamthif_cl; - ret = mei_cl_flow_ctrl_creds(&dev->iamthif_cl); + ret = mei_cl_flow_ctrl_creds(cl); if (ret < 0) return ret; @@ -292,8 +294,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) mei_hdr.msg_complete = 1; } - mei_hdr.host_addr = dev->iamthif_cl.host_client_id; - mei_hdr.me_addr = dev->iamthif_cl.me_client_id; + mei_hdr.host_addr = cl->host_client_id; + mei_hdr.me_addr = cl->me_client_id; mei_hdr.reserved = 0; mei_hdr.internal = 0; dev->iamthif_msg_buf_index += mei_hdr.length; @@ -302,7 +304,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) return ret; if (mei_hdr.msg_complete) { - if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) + if (mei_cl_flow_ctrl_reduce(cl)) return -EIO; dev->iamthif_flow_control_pending = true; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index b836dfffceb5..b1d892cea94d 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -270,15 +270,18 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev) static int mei_wd_ops_ping(struct watchdog_device *wd_dev) { struct mei_device *dev; + struct mei_cl *cl; int ret; dev = watchdog_get_drvdata(wd_dev); if (!dev) return -ENODEV; + cl = &dev->wd_cl; + mutex_lock(&dev->device_lock); - if (dev->wd_cl.state != MEI_FILE_CONNECTED) { + if (cl->state != MEI_FILE_CONNECTED) { dev_err(dev->dev, "wd: not connected.\n"); ret = -ENODEV; goto end; @@ -286,12 +289,12 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) dev->wd_state = MEI_WD_RUNNING; - ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); + ret = mei_cl_flow_ctrl_creds(cl); if (ret < 0) goto end; + /* Check if we can send the ping to HW*/ if (ret && mei_hbuf_acquire(dev)) { - dev_dbg(dev->dev, "wd: sending ping\n"); ret = mei_wd_send(dev); -- GitLab From 4ade435214a59ac1f7b3dc97fb5486c74bd37c79 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 28 Oct 2014 09:39:39 +0200 Subject: [PATCH 2751/9457] mei: debugfs: display also connectionless clients meiX/meclients: display also fixed/connectionless clients Use better name for fixed client field: fixed_address is boolean and indicates whether a client is fixed or dynamic. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/debugfs.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index ce1566715f80..b60b4263cf0f 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -34,7 +34,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, int pos = 0; int ret; -#define HDR " |id|addr| UUID |con|msg len|sb|\n" +#define HDR " |id|fix| UUID |con|msg len|sb|\n" mutex_lock(&dev->device_lock); @@ -56,12 +56,8 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, list_for_each_entry(me_cl, &dev->me_clients, list) { - /* skip me clients that cannot be connected */ - if (me_cl->props.max_number_of_connections == 0) - continue; - pos += scnprintf(buf + pos, bufsz - pos, - "%2d|%2d|%4d|%pUl|%3d|%7d|%2d|\n", + "%2d|%2d|%3d|%pUl|%3d|%7d|%2d|\n", i++, me_cl->client_id, me_cl->props.fixed_address, &me_cl->props.protocol_name, -- GitLab From d512c2098b1af6069e47ca457d7034d7cc82d420 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 29 Oct 2014 23:50:58 +0200 Subject: [PATCH 2752/9457] mei: hbm: use client specific print functions We have host client in connect/disconnect response processors, so use client print functions to simplify and unify code. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 57c1bde9b2b8..256fc4673782 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -562,17 +562,17 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) * mei_hbm_cl_disconnect_res - update the client state according * disconnect response * + * @dev: the device structure * @cl: mei host client * @cmd: disconnect client response host bus message */ -static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, +static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) { struct hbm_client_connect_response *rs = (struct hbm_client_connect_response *)cmd; - dev_dbg(cl->dev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", - rs->me_addr, rs->host_addr, rs->status); + cl_dbg(dev, cl, "hbm: disconnect response status=%d\n", rs->status); if (rs->status == MEI_CL_DISCONN_SUCCESS) cl->state = MEI_FILE_DISCONNECTED; @@ -598,17 +598,17 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) * mei_hbm_cl_connect_res - update the client state according * connection response * + * @dev: the device structure * @cl: mei host client * @cmd: connect client response host bus message */ -static void mei_hbm_cl_connect_res(struct mei_cl *cl, +static void mei_hbm_cl_connect_res(struct mei_device *dev, struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) { struct hbm_client_connect_response *rs = (struct hbm_client_connect_response *)cmd; - dev_dbg(cl->dev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", - rs->me_addr, rs->host_addr, + cl_dbg(dev, cl, "hbm: connect response status=%s\n", mei_cl_conn_status_str(rs->status)); if (rs->status == MEI_CL_CONN_SUCCESS) @@ -652,10 +652,10 @@ static void mei_hbm_cl_res(struct mei_device *dev, switch (fop_type) { case MEI_FOP_CONNECT: - mei_hbm_cl_connect_res(cl, rs); + mei_hbm_cl_connect_res(dev, cl, rs); break; case MEI_FOP_DISCONNECT: - mei_hbm_cl_disconnect_res(cl, rs); + mei_hbm_cl_disconnect_res(dev, cl, rs); break; default: return; -- GitLab From 37951dabd899587afc31ddd508b9cdddc9c24524 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:20 -0400 Subject: [PATCH 2753/9457] staging: unisys: get rid of VISORCHIPSET_STATE typedef Remove the typedef for VISORCHIPSET_STATE and replace it with enum visorchipset_state. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index feae36885376..ef62f3a54184 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -31,14 +31,14 @@ /** Describes the state from the perspective of which controlvm messages have * been received for a bus or device. */ -typedef struct { +struct visorchipset_state { u32 created:1; u32 attached:1; u32 configured:1; u32 running:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ -} VISORCHIPSET_STATE; +}; typedef enum { /** address is guest physical, but outside of the physical memory @@ -80,7 +80,7 @@ typedef struct { u32 busNo; u32 devNo; uuid_le devInstGuid; - VISORCHIPSET_STATE state; + struct visorchipset_state state; VISORCHIPSET_CHANNEL_INFO chanInfo; u32 Reserved1; /* control_vm_id */ u64 Reserved2; @@ -125,7 +125,7 @@ static inline void delbusdevices(struct list_head *list, u32 busNo) typedef struct { struct list_head entry; u32 busNo; - VISORCHIPSET_STATE state; + struct visorchipset_state state; VISORCHIPSET_CHANNEL_INFO chanInfo; uuid_le partitionGuid; u64 partitionHandle; @@ -162,7 +162,7 @@ findbus(struct list_head *list, u32 busNo) */ typedef struct { u32 switchNo; - VISORCHIPSET_STATE state; + struct visorchipset_state state; uuid_le switchTypeGuid; u8 *authService1; u8 *authService2; @@ -182,7 +182,7 @@ typedef struct { typedef struct { u32 switchNo; u32 externalPortNo; - VISORCHIPSET_STATE state; + struct visorchipset_state state; uuid_le networkZoneGuid; int pdPort; u8 *ip; @@ -205,7 +205,7 @@ typedef struct { typedef struct { u32 switchNo; u32 internalPortNo; - VISORCHIPSET_STATE state; + struct visorchipset_state state; u32 busNo; /* valid only when state.attached == 1 */ u32 devNo; /* valid only when state.attached == 1 */ u64 Reserved1; -- GitLab From 6fb23e18944adaec20bd38caf5703271875cede5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:21 -0400 Subject: [PATCH 2754/9457] staging: unisys: refactor VISORCHIPSET_ADDRESSTYPE Get rid of VISORCHIPSET_ADDRESSTYPE and replace it with enum visorchipset_addresstype. Fix CamelCase names: ADDRTYPE_localPhysical => ADDRTYPE_LOCALPHYSICAL ADDRTYPE_localTest => ADDRTYPE_LOCALTEST Update all references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 10 +++++----- .../staging/unisys/visorchipset/visorchipset_main.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index ef62f3a54184..6ca6580583b5 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -40,18 +40,18 @@ struct visorchipset_state { /* Remaining bits in this 32-bit word are unused. */ }; -typedef enum { +enum visorchipset_addresstype { /** address is guest physical, but outside of the physical memory * region that is controlled by the running OS (this is the normal * address type for Supervisor channels) */ - ADDRTYPE_localPhysical, + ADDRTYPE_LOCALPHYSICAL, /** address is guest physical, and withIN the confines of the * physical memory controlled by the running OS. */ - ADDRTYPE_localTest, -} VISORCHIPSET_ADDRESSTYPE; + ADDRTYPE_LOCALTEST, +}; typedef enum { CRASH_dev, @@ -61,7 +61,7 @@ typedef enum { /** Attributes for a particular Supervisor channel. */ typedef struct { - VISORCHIPSET_ADDRESSTYPE addrType; + enum visorchipset_addresstype addrType; HOSTADDRESS channelAddr; struct irq_info intr; u64 nChannelBytes; diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 392e046be359..70a54899fca6 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1130,9 +1130,9 @@ bus_create(struct controlvm_message *inmsg) POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pBusInfo->chanInfo.addrType = ADDRTYPE_localTest; + pBusInfo->chanInfo.addrType = ADDRTYPE_LOCALTEST; else - pBusInfo->chanInfo.addrType = ADDRTYPE_localPhysical; + pBusInfo->chanInfo.addrType = ADDRTYPE_LOCALPHYSICAL; pBusInfo->flags.server = inmsg->hdr.flags.server; pBusInfo->chanInfo.channelAddr = cmd->create_bus.channel_addr; @@ -1280,9 +1280,9 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pDevInfo->chanInfo.addrType = ADDRTYPE_localTest; + pDevInfo->chanInfo.addrType = ADDRTYPE_LOCALTEST; else - pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical; + pDevInfo->chanInfo.addrType = ADDRTYPE_LOCALPHYSICAL; pDevInfo->chanInfo.channelAddr = cmd->create_device.channel_addr; pDevInfo->chanInfo.nChannelBytes = cmd->create_device.channel_bytes; pDevInfo->chanInfo.channelTypeGuid = cmd->create_device.data_type_uuid; -- GitLab From 2c683cde06c1d57a9ecbacc484540e259e7255fa Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:22 -0400 Subject: [PATCH 2755/9457] staging: unisys: refactor CRASH_OBJ_TYPE Remove the typedef from the enumeration and replace references to it with enum crash_obj_type. Fix CamelCase names: CRASH_dev => CRASH_DEV CRASH_bus => CRASH_BUS Update all references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 10 +++++----- .../staging/unisys/visorchipset/visorchipset_main.c | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 6ca6580583b5..75f20f068225 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -53,10 +53,10 @@ enum visorchipset_addresstype { ADDRTYPE_LOCALTEST, }; -typedef enum { - CRASH_dev, - CRASH_bus, -} CRASH_OBJ_TYPE; +enum crash_obj_type { + CRASH_DEV, + CRASH_BUS, +}; /** Attributes for a particular Supervisor channel. */ @@ -288,7 +288,7 @@ int visorchipset_chipset_notready(void); void visorchipset_controlvm_respond_reportEvent(struct controlvm_message *msg, void *payload); void visorchipset_save_message(struct controlvm_message *msg, - CRASH_OBJ_TYPE type); + enum crash_obj_type type); void *visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, char *fn, int ln); void visorchipset_cache_free(struct kmem_cache *pool, void *p, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 70a54899fca6..229c75881c5a 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -760,7 +760,8 @@ static void controlvm_respond_physdev_changestate( } void -visorchipset_save_message(struct controlvm_message *msg, CRASH_OBJ_TYPE type) +visorchipset_save_message(struct controlvm_message *msg, + enum crash_obj_type type) { u32 localSavedCrashMsgOffset; u16 localSavedCrashMsgCount; @@ -796,7 +797,7 @@ visorchipset_save_message(struct controlvm_message *msg, CRASH_OBJ_TYPE type) return; } - if (type == CRASH_bus) { + if (type == CRASH_BUS) { if (visorchannel_write(ControlVm_channel, localSavedCrashMsgOffset, msg, -- GitLab From 9b1caee7170b9078f39c2f4c7a33334ad40cd47b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:23 -0400 Subject: [PATCH 2756/9457] staging: unisys: refactor VISORCHIPSET_CHANNEL_INFO Remove the typedef from this type and use struct visorchipset_channel_info instead. Fix CamelCase member names: addrType => addr_type channelAddr => channel_addr nChannelBytes => n_channel_bytes channelTypeGuid => channel_type_uuid channelInstGuid => channel_inst_uuid Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchipset/visorchipset.h | 18 ++++----- .../unisys/visorchipset/visorchipset_main.c | 38 ++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 75f20f068225..c8a936684cfb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -60,15 +60,15 @@ enum crash_obj_type { /** Attributes for a particular Supervisor channel. */ -typedef struct { - enum visorchipset_addresstype addrType; - HOSTADDRESS channelAddr; +struct visorchipset_channel_info { + enum visorchipset_addresstype addr_type; + HOSTADDRESS channel_addr; struct irq_info intr; - u64 nChannelBytes; - uuid_le channelTypeGuid; - uuid_le channelInstGuid; + u64 n_channel_bytes; + uuid_le channel_type_uuid; + uuid_le channel_inst_uuid; -} VISORCHIPSET_CHANNEL_INFO; +}; /** Attributes for a particular Supervisor device. * Any visorchipset client can query these attributes using @@ -81,7 +81,7 @@ typedef struct { u32 devNo; uuid_le devInstGuid; struct visorchipset_state state; - VISORCHIPSET_CHANNEL_INFO chanInfo; + struct visorchipset_channel_info chanInfo; u32 Reserved1; /* control_vm_id */ u64 Reserved2; u32 switchNo; /* when devState.attached==1 */ @@ -126,7 +126,7 @@ typedef struct { struct list_head entry; u32 busNo; struct visorchipset_state state; - VISORCHIPSET_CHANNEL_INFO chanInfo; + struct visorchipset_channel_info chanInfo; uuid_le partitionGuid; u64 partitionHandle; u8 *name; /* UTF8 */ diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 229c75881c5a..00a3445c3ce2 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1131,15 +1131,16 @@ bus_create(struct controlvm_message *inmsg) POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pBusInfo->chanInfo.addrType = ADDRTYPE_LOCALTEST; + pBusInfo->chanInfo.addr_type = ADDRTYPE_LOCALTEST; else - pBusInfo->chanInfo.addrType = ADDRTYPE_LOCALPHYSICAL; + pBusInfo->chanInfo.addr_type = ADDRTYPE_LOCALPHYSICAL; pBusInfo->flags.server = inmsg->hdr.flags.server; - pBusInfo->chanInfo.channelAddr = cmd->create_bus.channel_addr; - pBusInfo->chanInfo.nChannelBytes = cmd->create_bus.channel_bytes; - pBusInfo->chanInfo.channelTypeGuid = cmd->create_bus.bus_data_type_uuid; - pBusInfo->chanInfo.channelInstGuid = cmd->create_bus.bus_inst_uuid; + pBusInfo->chanInfo.channel_addr = cmd->create_bus.channel_addr; + pBusInfo->chanInfo.n_channel_bytes = cmd->create_bus.channel_bytes; + pBusInfo->chanInfo.channel_type_uuid = + cmd->create_bus.bus_data_type_uuid; + pBusInfo->chanInfo.channel_inst_uuid = cmd->create_bus.bus_inst_uuid; list_add(&pBusInfo->entry, &BusInfoList); @@ -1281,19 +1282,20 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pDevInfo->chanInfo.addrType = ADDRTYPE_LOCALTEST; + pDevInfo->chanInfo.addr_type = ADDRTYPE_LOCALTEST; else - pDevInfo->chanInfo.addrType = ADDRTYPE_LOCALPHYSICAL; - pDevInfo->chanInfo.channelAddr = cmd->create_device.channel_addr; - pDevInfo->chanInfo.nChannelBytes = cmd->create_device.channel_bytes; - pDevInfo->chanInfo.channelTypeGuid = cmd->create_device.data_type_uuid; + pDevInfo->chanInfo.addr_type = ADDRTYPE_LOCALPHYSICAL; + pDevInfo->chanInfo.channel_addr = cmd->create_device.channel_addr; + pDevInfo->chanInfo.n_channel_bytes = cmd->create_device.channel_bytes; + pDevInfo->chanInfo.channel_type_uuid = + cmd->create_device.data_type_uuid; pDevInfo->chanInfo.intr = cmd->create_device.intr; list_add(&pDevInfo->entry, &DevInfoList); POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); Away: /* get the bus and devNo for DiagPool channel */ - if (is_diagpool_channel(pDevInfo->chanInfo.channelTypeGuid)) { + if (is_diagpool_channel(pDevInfo->chanInfo.channel_type_uuid)) { g_diagpoolBusNo = busNo; g_diagpoolDevNo = devNo; LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", @@ -1302,7 +1304,7 @@ my_device_create(struct controlvm_message *inmsg) device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + FOR_VISORBUS(pDevInfo->chanInfo.channel_type_uuid)); } static void @@ -1336,7 +1338,8 @@ my_device_changestate(struct controlvm_message *inmsg) device_epilog(busNo, devNo, state, CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + FOR_VISORBUS( + pDevInfo->chanInfo.channel_type_uuid)); } static void @@ -1366,7 +1369,8 @@ my_device_destroy(struct controlvm_message *inmsg) device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid)); + FOR_VISORBUS( + pDevInfo->chanInfo.channel_type_uuid)); } /* When provided with the physical address of the controlvm channel @@ -1932,7 +1936,7 @@ static HOSTADDRESS controlvm_get_channel_address(void) static void controlvm_periodic_work(struct work_struct *work) { - VISORCHIPSET_CHANNEL_INFO chanInfo; + struct visorchipset_channel_info chanInfo; struct controlvm_message inmsg; BOOL gotACommand = FALSE; BOOL handle_command_failed = FALSE; @@ -1947,7 +1951,7 @@ controlvm_periodic_work(struct work_struct *work) if (visorchipset_clientregwait && !clientregistered) goto Away; - memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO)); + memset(&chanInfo, 0, sizeof(struct visorchipset_channel_info)); Poll_Count++; if (Poll_Count >= 250) -- GitLab From 246e0cd0985e3cf5ec316cd62dbb8bc9b3a93582 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:24 -0400 Subject: [PATCH 2757/9457] staging: unisys: refactor VISORCHIPSET_DEVICE_INFO Remove the typedef and use struct visorchipset_device_info instead. Fix CamelCase names: busNo => bus_no devNo => dev_no devInstGuid => dev_inst_guid chanInfo => chan_info Reserved1 => reserved1 Reserved2 => reserved2 switchNo => switch_no internalPortNo => internal_port_no pendingMsgHdr => pending_msg_hdr Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchipset/visorchipset.h | 34 ++++---- .../unisys/visorchipset/visorchipset_main.c | 78 ++++++++++--------- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index c8a936684cfb..a792cf263adb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -75,30 +75,30 @@ struct visorchipset_channel_info { * visorchipset_get_client_device_info() or * visorchipset_get_server_device_info(). */ -typedef struct { +struct visorchipset_device_info { struct list_head entry; - u32 busNo; - u32 devNo; - uuid_le devInstGuid; + u32 bus_no; + u32 dev_no; + uuid_le dev_inst_uuid; struct visorchipset_state state; - struct visorchipset_channel_info chanInfo; - u32 Reserved1; /* control_vm_id */ - u64 Reserved2; - u32 switchNo; /* when devState.attached==1 */ - u32 internalPortNo; /* when devState.attached==1 */ - struct controlvm_message_header pendingMsgHdr; /* CONTROLVM_MESSAGE */ + struct visorchipset_channel_info chan_info; + u32 reserved1; /* control_vm_id */ + u64 reserved2; + u32 switch_no; /* when devState.attached==1 */ + u32 internal_port_no; /* when devState.attached==1 */ + struct controlvm_message_header pending_msg_hdr;/* CONTROLVM_MESSAGE */ /** For private use by the bus driver */ void *bus_driver_context; -} VISORCHIPSET_DEVICE_INFO; +}; -static inline VISORCHIPSET_DEVICE_INFO * +static inline struct visorchipset_device_info * finddevice(struct list_head *list, u32 busNo, u32 devNo) { - VISORCHIPSET_DEVICE_INFO *p; + struct visorchipset_device_info *p; list_for_each_entry(p, list, entry) { - if (p->busNo == busNo && p->devNo == devNo) + if (p->bus_no == busNo && p->dev_no == devNo) return p; } return NULL; @@ -106,10 +106,10 @@ finddevice(struct list_head *list, u32 busNo, u32 devNo) static inline void delbusdevices(struct list_head *list, u32 busNo) { - VISORCHIPSET_DEVICE_INFO *p, *tmp; + struct visorchipset_device_info *p, *tmp; list_for_each_entry_safe(p, tmp, list, entry) { - if (p->busNo == busNo) { + if (p->bus_no == busNo) { list_del(&p->entry); kfree(p); } @@ -274,7 +274,7 @@ void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response); BOOL visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo); BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, - VISORCHIPSET_DEVICE_INFO *devInfo); + struct visorchipset_device_info *devInfo); BOOL visorchipset_get_switch_info(ulong switchNo, VISORCHIPSET_SWITCH_INFO *switchInfo); BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 00a3445c3ce2..ba74bf5dcc01 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -561,10 +561,11 @@ busInfo_clear(void *v) static void devInfo_clear(void *v) { - VISORCHIPSET_DEVICE_INFO *p = (VISORCHIPSET_DEVICE_INFO *) (v); + struct visorchipset_device_info *p = + (struct visorchipset_device_info *)(v); p->state.created = 0; - memset(p, 0, sizeof(VISORCHIPSET_DEVICE_INFO)); + memset(p, 0, sizeof(struct visorchipset_device_info)); } static u8 @@ -638,7 +639,7 @@ static void cleanup_controlvm_structures(void) { VISORCHIPSET_BUS_INFO *bi, *tmp_bi; - VISORCHIPSET_DEVICE_INFO *di, *tmp_di; + struct visorchipset_device_info *di, *tmp_di; list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) { busInfo_clear(bi); @@ -865,7 +866,7 @@ device_changestate_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, int response, struct spar_segment_state responseState) { - VISORCHIPSET_DEVICE_INFO *p = NULL; + struct visorchipset_device_info *p = NULL; struct controlvm_message outmsg; p = finddevice(&DevInfoList, busNo, devNo); @@ -873,16 +874,16 @@ device_changestate_responder(enum controlvm_id cmdId, LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); return; } - if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.id != cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); + if (p->pending_msg_hdr.id != cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_init_response(&outmsg, &p->pendingMsgHdr, response); + controlvm_init_response(&outmsg, &p->pending_msg_hdr, response); outmsg.cmd.device_change_state.bus_no = busNo; outmsg.cmd.device_change_state.dev_no = devNo; @@ -894,14 +895,14 @@ device_changestate_responder(enum controlvm_id cmdId, return; } - p->pendingMsgHdr.id = CONTROLVM_INVALID; + p->pending_msg_hdr.id = CONTROLVM_INVALID; } static void device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, int response) { - VISORCHIPSET_DEVICE_INFO *p = NULL; + struct visorchipset_device_info *p = NULL; BOOL need_clear = FALSE; p = finddevice(&DevInfoList, busNo, devNo); @@ -916,16 +917,16 @@ device_responder(enum controlvm_id cmdId, ulong busNo, ulong devNo, need_clear = TRUE; } - if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("device_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); + if (p->pending_msg_hdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.id = CONTROLVM_INVALID; + controlvm_respond(&p->pending_msg_hdr, response); + p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) devInfo_clear(p); } @@ -1005,7 +1006,7 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers = NULL; BOOL notified = FALSE; - VISORCHIPSET_DEVICE_INFO *pDevInfo = + struct visorchipset_device_info *pDevInfo = finddevice(&DevInfoList, busNo, devNo); char *envp[] = { "SPARSP_DIAGPOOL_PAUSED_STATE = 1", @@ -1021,10 +1022,10 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, else notifiers = &BusDev_Client_Notifiers; if (needResponse) { - memcpy(&pDevInfo->pendingMsgHdr, msgHdr, + memcpy(&pDevInfo->pending_msg_hdr, msgHdr, sizeof(struct controlvm_message_header)); } else - pDevInfo->pendingMsgHdr.id = CONTROLVM_INVALID; + pDevInfo->pending_msg_hdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response >= 0) { @@ -1234,7 +1235,7 @@ my_device_create(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->create_device.bus_no; ulong devNo = cmd->create_device.dev_no; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; + struct visorchipset_device_info *pDevInfo = NULL; VISORCHIPSET_BUS_INFO *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; @@ -1264,7 +1265,7 @@ my_device_create(struct controlvm_message *inmsg) rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto Away; } - pDevInfo = kzalloc(sizeof(VISORCHIPSET_DEVICE_INFO), GFP_KERNEL); + pDevInfo = kzalloc(sizeof(struct visorchipset_device_info), GFP_KERNEL); if (pDevInfo == NULL) { LOGERR("CONTROLVM_DEVICE_CREATE Failed: busNo=%lu, devNo=%lu kmaloc failed", busNo, devNo); @@ -1275,27 +1276,27 @@ my_device_create(struct controlvm_message *inmsg) } INIT_LIST_HEAD(&pDevInfo->entry); - pDevInfo->busNo = busNo; - pDevInfo->devNo = devNo; - pDevInfo->devInstGuid = cmd->create_device.dev_inst_uuid; + pDevInfo->bus_no = busNo; + pDevInfo->dev_no = devNo; + pDevInfo->dev_inst_uuid = cmd->create_device.dev_inst_uuid; POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pDevInfo->chanInfo.addr_type = ADDRTYPE_LOCALTEST; + pDevInfo->chan_info.addr_type = ADDRTYPE_LOCALTEST; else - pDevInfo->chanInfo.addr_type = ADDRTYPE_LOCALPHYSICAL; - pDevInfo->chanInfo.channel_addr = cmd->create_device.channel_addr; - pDevInfo->chanInfo.n_channel_bytes = cmd->create_device.channel_bytes; - pDevInfo->chanInfo.channel_type_uuid = + pDevInfo->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; + pDevInfo->chan_info.channel_addr = cmd->create_device.channel_addr; + pDevInfo->chan_info.n_channel_bytes = cmd->create_device.channel_bytes; + pDevInfo->chan_info.channel_type_uuid = cmd->create_device.data_type_uuid; - pDevInfo->chanInfo.intr = cmd->create_device.intr; + pDevInfo->chan_info.intr = cmd->create_device.intr; list_add(&pDevInfo->entry, &DevInfoList); POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo, POSTCODE_SEVERITY_INFO); Away: /* get the bus and devNo for DiagPool channel */ - if (is_diagpool_channel(pDevInfo->chanInfo.channel_type_uuid)) { + if (is_diagpool_channel(pDevInfo->chan_info.channel_type_uuid)) { g_diagpoolBusNo = busNo; g_diagpoolDevNo = devNo; LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", @@ -1304,7 +1305,7 @@ my_device_create(struct controlvm_message *inmsg) device_epilog(busNo, devNo, segment_state_running, CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, - FOR_VISORBUS(pDevInfo->chanInfo.channel_type_uuid)); + FOR_VISORBUS(pDevInfo->chan_info.channel_type_uuid)); } static void @@ -1314,7 +1315,7 @@ my_device_changestate(struct controlvm_message *inmsg) ulong busNo = cmd->device_change_state.bus_no; ulong devNo = cmd->device_change_state.dev_no; struct spar_segment_state state = cmd->device_change_state.state; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; + struct visorchipset_device_info *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -1339,7 +1340,7 @@ my_device_changestate(struct controlvm_message *inmsg) &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, FOR_VISORBUS( - pDevInfo->chanInfo.channel_type_uuid)); + pDevInfo->chan_info.channel_type_uuid)); } static void @@ -1348,7 +1349,7 @@ my_device_destroy(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->destroy_device.bus_no; ulong devNo = cmd->destroy_device.dev_no; - VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL; + struct visorchipset_device_info *pDevInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -1370,7 +1371,7 @@ my_device_destroy(struct controlvm_message *inmsg) CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, inmsg->hdr.flags.response_expected == 1, FOR_VISORBUS( - pDevInfo->chanInfo.channel_type_uuid)); + pDevInfo->chan_info.channel_type_uuid)); } /* When provided with the physical address of the controlvm channel @@ -2228,7 +2229,7 @@ EXPORT_SYMBOL_GPL(visorchipset_set_bus_context); BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, - VISORCHIPSET_DEVICE_INFO *devInfo) + struct visorchipset_device_info *devInfo) { void *p = finddevice(&DevInfoList, busNo, devNo); @@ -2236,7 +2237,7 @@ visorchipset_get_device_info(ulong busNo, ulong devNo, LOGERR("(%lu,%lu) failed", busNo, devNo); return FALSE; } - memcpy(devInfo, p, sizeof(VISORCHIPSET_DEVICE_INFO)); + memcpy(devInfo, p, sizeof(struct visorchipset_device_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_device_info); @@ -2244,7 +2245,8 @@ EXPORT_SYMBOL_GPL(visorchipset_get_device_info); BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context) { - VISORCHIPSET_DEVICE_INFO *p = finddevice(&DevInfoList, busNo, devNo); + struct visorchipset_device_info *p = + finddevice(&DevInfoList, busNo, devNo); if (!p) { LOGERR("(%lu,%lu) failed", busNo, devNo); -- GitLab From 0a96ec728e71d5c170b2dcb3949e10ccab86cf0d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:25 -0400 Subject: [PATCH 2758/9457] staging: unisys: fix CamelCase parameters in finddevice() Fix CamelCase names in finddevice(): busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index a792cf263adb..d2bb9f02b2ec 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -92,13 +92,13 @@ struct visorchipset_device_info { }; -static inline struct visorchipset_device_info * -finddevice(struct list_head *list, u32 busNo, u32 devNo) +static inline struct visorchipset_device_info *finddevice( + struct list_head *list, u32 bus_no, u32 dev_no) { struct visorchipset_device_info *p; list_for_each_entry(p, list, entry) { - if (p->bus_no == busNo && p->dev_no == devNo) + if (p->bus_no == bus_no && p->dev_no == dev_no) return p; } return NULL; -- GitLab From 8f67b5bc068b0ab8da6512d4ddb2f4806653bf6f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:26 -0400 Subject: [PATCH 2759/9457] staging: unisys: fix CamelCase parameters in delbusdevices() Fix the CamelCase parameter in delbusdevices() in visorchipset.h: busNo => bus_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index d2bb9f02b2ec..c36c08f9eb7d 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -104,12 +104,12 @@ static inline struct visorchipset_device_info *finddevice( return NULL; } -static inline void delbusdevices(struct list_head *list, u32 busNo) +static inline void delbusdevices(struct list_head *list, u32 bus_no) { struct visorchipset_device_info *p, *tmp; list_for_each_entry_safe(p, tmp, list, entry) { - if (p->bus_no == busNo) { + if (p->bus_no == bus_no) { list_del(&p->entry); kfree(p); } -- GitLab From 33192fa1d173b91ba98c29cb8ab414c76ae3ff0b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:27 -0400 Subject: [PATCH 2760/9457] staging: unisys: refactor VISORCHIPSET_BUS_INFO Remove the typedef and use the name struct visorchipset_bus_info instead. Fix CamelCase member names in the structure: busNo => bus_no chanInfo => chan_info partitionGuid => partition_uuid partitionHandle => partition_handle Reserved1 => reserved1 Reserved2 => reserved2 procObject => proc_object Update references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchipset/visorchipset.h | 31 ++++---- .../unisys/visorchipset/visorchipset_main.c | 72 +++++++++---------- 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index c36c08f9eb7d..b93174d73671 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -122,37 +122,37 @@ static inline void delbusdevices(struct list_head *list, u32 bus_no) * Any visorchipset client can query these attributes using * visorchipset_get_client_bus_info() or visorchipset_get_bus_info(). */ -typedef struct { +struct visorchipset_bus_info { struct list_head entry; - u32 busNo; + u32 bus_no; struct visorchipset_state state; - struct visorchipset_channel_info chanInfo; - uuid_le partitionGuid; - u64 partitionHandle; + struct visorchipset_channel_info chan_info; + uuid_le partition_uuid; + u64 partition_handle; u8 *name; /* UTF8 */ u8 *description; /* UTF8 */ - u64 Reserved1; - u32 Reserved2; - MYPROCOBJECT *procObject; + u64 reserved1; + u32 reserved2; + MYPROCOBJECT *proc_object; struct { u32 server:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ } flags; - struct controlvm_message_header pendingMsgHdr; /* CONTROLVM MsgHdr */ + struct controlvm_message_header pending_msg_hdr;/* CONTROLVM MsgHdr */ /** For private use by the bus driver */ void *bus_driver_context; - u64 devNo; + u64 dev_no; -} VISORCHIPSET_BUS_INFO; +}; -static inline VISORCHIPSET_BUS_INFO * +static inline struct visorchipset_bus_info * findbus(struct list_head *list, u32 busNo) { - VISORCHIPSET_BUS_INFO *p; + struct visorchipset_bus_info *p; list_for_each_entry(p, list, entry) { - if (p->busNo == busNo) + if (p->bus_no == busNo) return p; } return NULL; @@ -272,7 +272,8 @@ typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response); -BOOL visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo); +BOOL visorchipset_get_bus_info(ulong busNo, + struct visorchipset_bus_info *busInfo); BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, struct visorchipset_device_info *devInfo); BOOL visorchipset_get_switch_info(ulong switchNo, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index ba74bf5dcc01..5f3d6cd52dc3 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -542,11 +542,11 @@ testUnicode(void) static void busInfo_clear(void *v) { - VISORCHIPSET_BUS_INFO *p = (VISORCHIPSET_BUS_INFO *) (v); + struct visorchipset_bus_info *p = (struct visorchipset_bus_info *) (v); - if (p->procObject) { - visor_proc_DestroyObject(p->procObject); - p->procObject = NULL; + if (p->proc_object) { + visor_proc_DestroyObject(p->proc_object); + p->proc_object = NULL; } kfree(p->name); p->name = NULL; @@ -555,7 +555,7 @@ busInfo_clear(void *v) p->description = NULL; p->state.created = 0; - memset(p, 0, sizeof(VISORCHIPSET_BUS_INFO)); + memset(p, 0, sizeof(struct visorchipset_bus_info)); } static void @@ -638,7 +638,7 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); static void cleanup_controlvm_structures(void) { - VISORCHIPSET_BUS_INFO *bi, *tmp_bi; + struct visorchipset_bus_info *bi, *tmp_bi; struct visorchipset_device_info *di, *tmp_di; list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) { @@ -825,7 +825,7 @@ EXPORT_SYMBOL_GPL(visorchipset_save_message); static void bus_responder(enum controlvm_id cmdId, ulong busNo, int response) { - VISORCHIPSET_BUS_INFO *p = NULL; + struct visorchipset_bus_info *p = NULL; BOOL need_clear = FALSE; p = findbus(&BusInfoList, busNo); @@ -845,16 +845,16 @@ bus_responder(enum controlvm_id cmdId, ulong busNo, int response) need_clear = TRUE; } - if (p->pendingMsgHdr.id == CONTROLVM_INVALID) { + if (p->pending_msg_hdr.id == CONTROLVM_INVALID) { LOGERR("bus_responder no pending msg"); return; /* no controlvm response needed */ } - if (p->pendingMsgHdr.id != (u32) cmdId) { - LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.id); + if (p->pending_msg_hdr.id != (u32) cmdId) { + LOGERR("expected=%d, found=%d", cmdId, p->pending_msg_hdr.id); return; } - controlvm_respond(&p->pendingMsgHdr, response); - p->pendingMsgHdr.id = CONTROLVM_INVALID; + controlvm_respond(&p->pending_msg_hdr, response); + p->pending_msg_hdr.id = CONTROLVM_INVALID; if (need_clear) { busInfo_clear(p); delbusdevices(&DevInfoList, busNo); @@ -938,17 +938,17 @@ bus_epilog(u32 busNo, { BOOL notified = FALSE; - VISORCHIPSET_BUS_INFO *pBusInfo = findbus(&BusInfoList, busNo); + struct visorchipset_bus_info *pBusInfo = findbus(&BusInfoList, busNo); if (!pBusInfo) { LOGERR("HUH? bad busNo=%d", busNo); return; } if (needResponse) { - memcpy(&pBusInfo->pendingMsgHdr, msgHdr, + memcpy(&pBusInfo->pending_msg_hdr, msgHdr, sizeof(struct controlvm_message_header)); } else - pBusInfo->pendingMsgHdr.id = CONTROLVM_INVALID; + pBusInfo->pending_msg_hdr.id = CONTROLVM_INVALID; down(&NotifierLock); if (response == CONTROLVM_RESP_SUCCESS) { @@ -1103,7 +1103,7 @@ bus_create(struct controlvm_message *inmsg) struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->create_bus.bus_no; int rc = CONTROLVM_RESP_SUCCESS; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct visorchipset_bus_info *pBusInfo = NULL; pBusInfo = findbus(&BusInfoList, busNo); @@ -1115,7 +1115,7 @@ bus_create(struct controlvm_message *inmsg) rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto Away; } - pBusInfo = kzalloc(sizeof(VISORCHIPSET_BUS_INFO), GFP_KERNEL); + pBusInfo = kzalloc(sizeof(struct visorchipset_bus_info), GFP_KERNEL); if (pBusInfo == NULL) { LOGERR("CONTROLVM_BUS_CREATE Failed: bus %lu kzalloc failed", busNo); @@ -1126,22 +1126,22 @@ bus_create(struct controlvm_message *inmsg) } INIT_LIST_HEAD(&pBusInfo->entry); - pBusInfo->busNo = busNo; - pBusInfo->devNo = cmd->create_bus.dev_count; + pBusInfo->bus_no = busNo; + pBusInfo->dev_no = cmd->create_bus.dev_count; POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO); if (inmsg->hdr.flags.test_message == 1) - pBusInfo->chanInfo.addr_type = ADDRTYPE_LOCALTEST; + pBusInfo->chan_info.addr_type = ADDRTYPE_LOCALTEST; else - pBusInfo->chanInfo.addr_type = ADDRTYPE_LOCALPHYSICAL; + pBusInfo->chan_info.addr_type = ADDRTYPE_LOCALPHYSICAL; pBusInfo->flags.server = inmsg->hdr.flags.server; - pBusInfo->chanInfo.channel_addr = cmd->create_bus.channel_addr; - pBusInfo->chanInfo.n_channel_bytes = cmd->create_bus.channel_bytes; - pBusInfo->chanInfo.channel_type_uuid = + pBusInfo->chan_info.channel_addr = cmd->create_bus.channel_addr; + pBusInfo->chan_info.n_channel_bytes = cmd->create_bus.channel_bytes; + pBusInfo->chan_info.channel_type_uuid = cmd->create_bus.bus_data_type_uuid; - pBusInfo->chanInfo.channel_inst_uuid = cmd->create_bus.bus_inst_uuid; + pBusInfo->chan_info.channel_inst_uuid = cmd->create_bus.bus_inst_uuid; list_add(&pBusInfo->entry, &BusInfoList); @@ -1157,7 +1157,7 @@ bus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->destroy_bus.bus_no; - VISORCHIPSET_BUS_INFO *pBusInfo; + struct visorchipset_bus_info *pBusInfo; int rc = CONTROLVM_RESP_SUCCESS; pBusInfo = findbus(&BusInfoList, busNo); @@ -1183,7 +1183,7 @@ bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; ulong busNo = cmd->configure_bus.bus_no; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct visorchipset_bus_info *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; char s[99]; @@ -1208,21 +1208,21 @@ bus_configure(struct controlvm_message *inmsg, PARSER_CONTEXT *parser_ctx) goto Away; } /* TBD - add this check to other commands also... */ - if (pBusInfo->pendingMsgHdr.id != CONTROLVM_INVALID) { + if (pBusInfo->pending_msg_hdr.id != CONTROLVM_INVALID) { LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu MsgId=%u outstanding", - busNo, (uint) pBusInfo->pendingMsgHdr.id); + busNo, (uint) pBusInfo->pending_msg_hdr.id); POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo, POSTCODE_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; goto Away; } - pBusInfo->partitionHandle = cmd->configure_bus.guest_handle; - pBusInfo->partitionGuid = parser_id_get(parser_ctx); + pBusInfo->partition_handle = cmd->configure_bus.guest_handle; + pBusInfo->partition_uuid = parser_id_get(parser_ctx); parser_param_start(parser_ctx, PARSERSTRING_NAME); pBusInfo->name = parser_string_get(parser_ctx); - visorchannel_uuid_id(&pBusInfo->partitionGuid, s); + visorchannel_uuid_id(&pBusInfo->partition_uuid, s); POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO); Away: bus_epilog(busNo, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, @@ -1236,7 +1236,7 @@ my_device_create(struct controlvm_message *inmsg) ulong busNo = cmd->create_device.bus_no; ulong devNo = cmd->create_device.dev_no; struct visorchipset_device_info *pDevInfo = NULL; - VISORCHIPSET_BUS_INFO *pBusInfo = NULL; + struct visorchipset_bus_info *pBusInfo = NULL; int rc = CONTROLVM_RESP_SUCCESS; pDevInfo = finddevice(&DevInfoList, busNo, devNo); @@ -2200,7 +2200,7 @@ device_resume_response(ulong busNo, ulong devNo, int response) } BOOL -visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo) +visorchipset_get_bus_info(ulong busNo, struct visorchipset_bus_info *busInfo) { void *p = findbus(&BusInfoList, busNo); @@ -2208,7 +2208,7 @@ visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo) LOGERR("(%lu) failed", busNo); return FALSE; } - memcpy(busInfo, p, sizeof(VISORCHIPSET_BUS_INFO)); + memcpy(busInfo, p, sizeof(struct visorchipset_bus_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); @@ -2216,7 +2216,7 @@ EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); BOOL visorchipset_set_bus_context(ulong busNo, void *context) { - VISORCHIPSET_BUS_INFO *p = findbus(&BusInfoList, busNo); + struct visorchipset_bus_info *p = findbus(&BusInfoList, busNo); if (!p) { LOGERR("(%lu) failed", busNo); -- GitLab From b4d55e39a34bf93d307965b8d340a80170cea535 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:28 -0400 Subject: [PATCH 2761/9457] staging: unisys: fix CamelCase in findbus() Fix the CamelCase parameter name in findbus() in visorchipset.h. busNo => bus_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index b93174d73671..a578d0a0714b 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -147,12 +147,12 @@ struct visorchipset_bus_info { }; static inline struct visorchipset_bus_info * -findbus(struct list_head *list, u32 busNo) +findbus(struct list_head *list, u32 bus_no) { struct visorchipset_bus_info *p; list_for_each_entry(p, list, entry) { - if (p->bus_no == busNo) + if (p->bus_no == bus_no) return p; } return NULL; -- GitLab From e2320e653e99d70bd58e61344f2d472d5dac3126 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:29 -0400 Subject: [PATCH 2762/9457] staging: unisys: refactor VISORCHIPSET_SWITCH_INFO Remove the typedef and use struct visorchipset_switch_info instead. Fix all CamelCase member names: switchNo => switch_no switchTypeGuid => switch_type_uuid authService1 => authservice1 authService2 => authservice2 authService3 => authservice3 securityContext => security_context Reserved => reserved Reserved2 => reserved2 pendingMsgHdr => pending_msg_hdr Signed-off-by: Benjamin Romer --- .../unisys/visorchipset/visorchipset.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index a578d0a0714b..762bc1380085 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -160,21 +160,20 @@ findbus(struct list_head *list, u32 bus_no) /** Attributes for a particular Supervisor switch. */ -typedef struct { - u32 switchNo; +struct visorchipset_switch_info { + u32 switch_no; struct visorchipset_state state; - uuid_le switchTypeGuid; - u8 *authService1; - u8 *authService2; - u8 *authService3; - u8 *securityContext; - u64 Reserved; - u32 Reserved2; /* control_vm_id */ + uuid_le switch_type_uuid; + u8 *authservice1; + u8 *authservice2; + u8 *authservice3; + u8 *security_context; + u64 reserved; + u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - struct controlvm_message_header pendingMsgHdr; - -} VISORCHIPSET_SWITCH_INFO; + struct controlvm_message_header pending_msg_hdr; +}; /** Attributes for a particular Supervisor external port, which is connected * to a specific switch. @@ -277,7 +276,7 @@ BOOL visorchipset_get_bus_info(ulong busNo, BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, struct visorchipset_device_info *devInfo); BOOL visorchipset_get_switch_info(ulong switchNo, - VISORCHIPSET_SWITCH_INFO *switchInfo); + struct visorchipset_switch_info *switchInfo); BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, VISORCHIPSET_EXTERNALPORT_INFO *externalPortInfo); -- GitLab From 53414833fe7979153cd238a8829e0fea01eb1e7b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:30 -0400 Subject: [PATCH 2763/9457] staging: unisys: refactor VISORCHIPSET_EXTERNALPORT_INFO Remove the typedef and just use struct visorchipset_externalport_info instead. Fix all CamelCase names: switchNo => switch_no externalPortNo => external_port_no networkZoneGuid => network_zone_uuid pdPort => pd_port ipNetmask => ip_netmask ipBroadcast => ip_broadcast ipNetwork => ip_network ipGateway => ip_gateway ipDNS => ip_dns Reserved1 => reserved1 Reserved2 => reserved2 pendingMsgHdr => pending_msg_hdr Signed-off-by: Benjamin Romer --- .../unisys/visorchipset/visorchipset.h | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 762bc1380085..e20eb10e4250 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -178,25 +178,24 @@ struct visorchipset_switch_info { /** Attributes for a particular Supervisor external port, which is connected * to a specific switch. */ -typedef struct { - u32 switchNo; - u32 externalPortNo; +struct visorchipset_externalport_info { + u32 switch_no; + u32 external_port_no; struct visorchipset_state state; - uuid_le networkZoneGuid; - int pdPort; + uuid_le network_zone_uuid; + int pd_port; u8 *ip; - u8 *ipNetmask; - u8 *ipBroadcast; - u8 *ipNetwork; - u8 *ipGateway; - u8 *ipDNS; - u64 Reserved1; - u32 Reserved2; /* control_vm_id */ + u8 *ip_netmask; + u8 *ip_broadcast; + u8 *ip_network; + u8 *ip_gateway; + u8 *ip_dns; + u64 reserved1; + u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; - struct controlvm_message_header pendingMsgHdr; - -} VISORCHIPSET_EXTERNALPORT_INFO; + struct controlvm_message_header pending_msg_hdr; +}; /** Attributes for a particular Supervisor internal port, which is how a * device connects to a particular switch. @@ -278,7 +277,7 @@ BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, BOOL visorchipset_get_switch_info(ulong switchNo, struct visorchipset_switch_info *switchInfo); BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, - VISORCHIPSET_EXTERNALPORT_INFO + struct visorchipset_externalport_info *externalPortInfo); BOOL visorchipset_set_bus_context(ulong busNo, void *context); BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); -- GitLab From 2924bbc97f63bd166f6f97c0bf71656eabab5a87 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:31 -0400 Subject: [PATCH 2764/9457] staging: unisys: refactor VISORCHIPSET_INTERNALPORT_INFO Get rid of the typedef and use struct visorchipset_internalport_info and fix CamelCase member names: switchNo => switch_no internalPortNo => internal_port_no busNo => bus_no devNo => dev_no Reserved1 => reserved1 Reserved2 => reserved2 pendingMsgHdr => pending_msg_hdr procObject => proc_object Signed-off-by: Benjamin Romer --- .../unisys/visorchipset/visorchipset.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index e20eb10e4250..7d3b2c1db045 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -200,18 +200,18 @@ struct visorchipset_externalport_info { /** Attributes for a particular Supervisor internal port, which is how a * device connects to a particular switch. */ -typedef struct { - u32 switchNo; - u32 internalPortNo; +struct visorchipset_internalport_info { + u32 switch_no; + u32 internal_port_no; struct visorchipset_state state; - u32 busNo; /* valid only when state.attached == 1 */ - u32 devNo; /* valid only when state.attached == 1 */ - u64 Reserved1; - u32 Reserved2; /* CONTROLVM_ID */ - struct controlvm_message_header pendingMsgHdr; - MYPROCOBJECT *procObject; - -} VISORCHIPSET_INTERNALPORT_INFO; + u32 bus_no; /* valid only when state.attached == 1 */ + u32 dev_no; /* valid only when state.attached == 1 */ + u64 reserved1; + u32 reserved2; /* CONTROLVM_ID */ + struct controlvm_message_header pending_msg_hdr; + MYPROCOBJECT *proc_object; + +}; /* These functions will be called from within visorchipset when certain * events happen. (The implementation of these functions is outside of -- GitLab From fe90d8926c93601b739f7cdd39fcf445c8687709 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:32 -0400 Subject: [PATCH 2765/9457] staging: unisys: refactor VISORCHIPSET_BUSDEV_NOTIFIERS Get rid of the typedef and just use struct visorchipset_busdev_notifiers instead. Fix CamelCase names in parameters for the function pointers: busNo => bus_no devNo => dev_no typeGuid => type_uuid minSize => min_size maxSize => max_size Update references. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchipset/visorchipset.h | 34 ++++++++++--------- .../unisys/visorchipset/visorchipset_main.c | 20 ++++++----- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 7d3b2c1db045..da14ef73f850 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -217,16 +217,16 @@ struct visorchipset_internalport_info { * events happen. (The implementation of these functions is outside of * visorchipset.) */ -typedef struct { - void (*bus_create)(ulong busNo); - void (*bus_destroy)(ulong busNo); - void (*device_create)(ulong busNo, ulong devNo); - void (*device_destroy)(ulong busNo, ulong devNo); - void (*device_pause)(ulong busNo, ulong devNo); - void (*device_resume)(ulong busNo, ulong devNo); - int (*get_channel_info)(uuid_le typeGuid, ulong *minSize, - ulong *maxSize); -} VISORCHIPSET_BUSDEV_NOTIFIERS; +struct visorchipset_busdev_notifiers { + void (*bus_create)(ulong bus_no); + void (*bus_destroy)(ulong bus_no); + void (*device_create)(ulong bus_no, ulong dev_no); + void (*device_destroy)(ulong bus_no, ulong dev_no); + void (*device_pause)(ulong bus_no, ulong dev_no); + void (*device_resume)(ulong bus_no, ulong dev_no); + int (*get_channel_info)(uuid_le type_uuid, ulong *min_size, + ulong *max_size); +}; /* These functions live inside visorchipset, and will be called to indicate * responses to specific events (by code outside of visorchipset). @@ -250,9 +250,10 @@ typedef struct { * responses. */ void -visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - struct ultra_vbus_deviceinfo *driverInfo); +visorchipset_register_busdev_client( + struct visorchipset_busdev_notifiers *notifiers, + VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct ultra_vbus_deviceinfo *driverInfo); /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is @@ -261,9 +262,10 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, * responses. */ void -visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - struct ultra_vbus_deviceinfo *driverInfo); +visorchipset_register_busdev_server( + struct visorchipset_busdev_notifiers *notifiers, + VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct ultra_vbus_deviceinfo *driverInfo); typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 5f3d6cd52dc3..ee0c88af11f0 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -230,8 +230,8 @@ static void parahotplug_process_list(void); /* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE / * CONTROLVM_REPORTEVENT. */ -static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Server_Notifiers; -static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Client_Notifiers; +static struct visorchipset_busdev_notifiers BusDev_Server_Notifiers; +static struct visorchipset_busdev_notifiers BusDev_Client_Notifiers; static void bus_create_response(ulong busNo, int response); static void bus_destroy_response(ulong busNo, int response); @@ -589,9 +589,10 @@ clear_chipset_events(void) } void -visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - struct ultra_vbus_deviceinfo *driverInfo) +visorchipset_register_busdev_server( + struct visorchipset_busdev_notifiers *notifiers, + VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); if (notifiers == NULL) { @@ -613,9 +614,10 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server); void -visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, - struct ultra_vbus_deviceinfo *driverInfo) +visorchipset_register_busdev_client( + struct visorchipset_busdev_notifiers *notifiers, + VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); if (notifiers == NULL) { @@ -1003,7 +1005,7 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, struct controlvm_message_header *msgHdr, int response, BOOL needResponse, BOOL for_visorbus) { - VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers = NULL; + struct visorchipset_busdev_notifiers *notifiers = NULL; BOOL notified = FALSE; struct visorchipset_device_info *pDevInfo = -- GitLab From 929aa8ae2f14ecf3cdae4c3124ebe119f83d0224 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:33 -0400 Subject: [PATCH 2766/9457] staging: unisys: refactor VISORCHIPSET_BUSDEV_RESPONDERS Get rid of the typedef and just use struct visorchipset_busdev_responders instead. Fix CamelCase parameter names in the function pointer definitions for the structure: busNo => bus_no devNo => dev_no Update references to changed names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchipset/visorchipset.h | 20 +++++++++---------- .../unisys/visorchipset/visorchipset_main.c | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index da14ef73f850..f4c6ff1d9c39 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -234,14 +234,14 @@ struct visorchipset_busdev_notifiers { * 0 = it worked * -1 = it failed */ -typedef struct { - void (*bus_create)(ulong busNo, int response); - void (*bus_destroy)(ulong busNo, int response); - void (*device_create)(ulong busNo, ulong devNo, int response); - void (*device_destroy)(ulong busNo, ulong devNo, int response); - void (*device_pause)(ulong busNo, ulong devNo, int response); - void (*device_resume)(ulong busNo, ulong devNo, int response); -} VISORCHIPSET_BUSDEV_RESPONDERS; +struct visorchipset_busdev_responders { + void (*bus_create)(ulong bus_no, int response); + void (*bus_destroy)(ulong bus_no, int response); + void (*device_create)(ulong bus_no, ulong dev_no, int response); + void (*device_destroy)(ulong bus_no, ulong dev_no, int response); + void (*device_pause)(ulong bus_no, ulong dev_no, int response); + void (*device_resume)(ulong bus_no, ulong dev_no, int response); +}; /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is @@ -252,7 +252,7 @@ typedef struct { void visorchipset_register_busdev_client( struct visorchipset_busdev_notifiers *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driverInfo); /** Register functions (in the bus driver) to get called by visorchipset @@ -264,7 +264,7 @@ visorchipset_register_busdev_client( void visorchipset_register_busdev_server( struct visorchipset_busdev_notifiers *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driverInfo); typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index ee0c88af11f0..12746e0a4e86 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -239,7 +239,7 @@ static void device_create_response(ulong busNo, ulong devNo, int response); static void device_destroy_response(ulong busNo, ulong devNo, int response); static void device_resume_response(ulong busNo, ulong devNo, int response); -static VISORCHIPSET_BUSDEV_RESPONDERS BusDev_Responders = { +static struct visorchipset_busdev_responders BusDev_Responders = { .bus_create = bus_create_response, .bus_destroy = bus_destroy_response, .device_create = device_create_response, @@ -591,7 +591,7 @@ clear_chipset_events(void) void visorchipset_register_busdev_server( struct visorchipset_busdev_notifiers *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); @@ -616,7 +616,7 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server); void visorchipset_register_busdev_client( struct visorchipset_busdev_notifiers *notifiers, - VISORCHIPSET_BUSDEV_RESPONDERS *responders, + struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driverInfo) { down(&NotifierLock); @@ -991,7 +991,7 @@ bus_epilog(u32 busNo, } if (notified) /* The callback function just called above is responsible - * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS + * for calling the appropriate visorchipset_busdev_responders * function, which will call bus_responder() */ ; @@ -1090,7 +1090,7 @@ device_epilog(u32 busNo, u32 devNo, struct spar_segment_state state, u32 cmd, } if (notified) /* The callback function just called above is responsible - * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS + * for calling the appropriate visorchipset_busdev_responders * function, which will call device_responder() */ ; -- GitLab From 43fce019e90fbe4283ac26b3e9f8445ae7533c1e Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:34 -0400 Subject: [PATCH 2767/9457] staging: unisys: fix CamelCase name in visorchipset_register_busdev_client() Fix CamelCase parameter: driverInfo => driver_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset_main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index f4c6ff1d9c39..e8687ad9dda5 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -253,7 +253,7 @@ void visorchipset_register_busdev_client( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, - struct ultra_vbus_deviceinfo *driverInfo); + struct ultra_vbus_deviceinfo *driver_info); /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 12746e0a4e86..0dfd8f4b78bb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -617,7 +617,7 @@ void visorchipset_register_busdev_client( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, - struct ultra_vbus_deviceinfo *driverInfo) + struct ultra_vbus_deviceinfo *driver_info) { down(&NotifierLock); if (notifiers == NULL) { @@ -630,9 +630,9 @@ visorchipset_register_busdev_client( } if (responders) *responders = BusDev_Responders; - if (driverInfo) - bus_device_info_init(driverInfo, "chipset(bolts)", "visorchipset", - VERSION, NULL); + if (driver_info) + bus_device_info_init(driver_info, "chipset(bolts)", + "visorchipset", VERSION, NULL); up(&NotifierLock); } EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); -- GitLab From 1e7a59c1464eb0bb2bc6940ba963845fa246fa61 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:35 -0400 Subject: [PATCH 2768/9457] staging: unisys: fix CamelCase name in visorchipset_register_busdev_server() Fix CamelCase name: driverInfo => driver_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset_main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index e8687ad9dda5..4bafcf2ecd1d 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -265,7 +265,7 @@ void visorchipset_register_busdev_server( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, - struct ultra_vbus_deviceinfo *driverInfo); + struct ultra_vbus_deviceinfo *driver_info); typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 0dfd8f4b78bb..95545b9e2d50 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -592,7 +592,7 @@ void visorchipset_register_busdev_server( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, - struct ultra_vbus_deviceinfo *driverInfo) + struct ultra_vbus_deviceinfo *driver_info) { down(&NotifierLock); if (notifiers == NULL) { @@ -605,8 +605,8 @@ visorchipset_register_busdev_server( } if (responders) *responders = BusDev_Responders; - if (driverInfo) - bus_device_info_init(driverInfo, "chipset", "visorchipset", + if (driver_info) + bus_device_info_init(driver_info, "chipset", "visorchipset", VERSION, NULL); up(&NotifierLock); -- GitLab From 8420f417e52682bb828dc7d7fd19b7c58b89d658 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:36 -0400 Subject: [PATCH 2769/9457] staging: unisys: fix CamelCase in visorchipset_device_pause_response() Fix CamelCase parameters: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 3 ++- drivers/staging/unisys/visorchipset/visorchipset_main.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 4bafcf2ecd1d..8ed92f0d73c5 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -270,7 +270,8 @@ visorchipset_register_busdev_server( typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); -void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response); +void visorchipset_device_pause_response(ulong bus_no, ulong dev_no, + int response); BOOL visorchipset_get_bus_info(ulong busNo, struct visorchipset_bus_info *busInfo); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 95545b9e2d50..8c6e73024bbe 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2184,11 +2184,11 @@ device_destroy_response(ulong busNo, ulong devNo, int response) } void -visorchipset_device_pause_response(ulong busNo, ulong devNo, int response) +visorchipset_device_pause_response(ulong bus_no, ulong dev_no, int response) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - busNo, devNo, response, + bus_no, dev_no, response, segment_state_standby); } EXPORT_SYMBOL_GPL(visorchipset_device_pause_response); -- GitLab From 77db7127c7e63a642525114d80ca350ce1eabf39 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:37 -0400 Subject: [PATCH 2770/9457] staging: unisys: fix CamelCase in visorchipset_get_bus_info Fix CamelCase names: busNo => bus_no busInfo => bus_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 4 ++-- drivers/staging/unisys/visorchipset/visorchipset_main.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 8ed92f0d73c5..6f42712dfcd1 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -273,8 +273,8 @@ typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, void visorchipset_device_pause_response(ulong bus_no, ulong dev_no, int response); -BOOL visorchipset_get_bus_info(ulong busNo, - struct visorchipset_bus_info *busInfo); +BOOL visorchipset_get_bus_info(ulong bus_no, + struct visorchipset_bus_info *bus_info); BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, struct visorchipset_device_info *devInfo); BOOL visorchipset_get_switch_info(ulong switchNo, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 8c6e73024bbe..041dba0d9e06 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2202,15 +2202,15 @@ device_resume_response(ulong busNo, ulong devNo, int response) } BOOL -visorchipset_get_bus_info(ulong busNo, struct visorchipset_bus_info *busInfo) +visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info) { - void *p = findbus(&BusInfoList, busNo); + void *p = findbus(&BusInfoList, bus_no); if (!p) { - LOGERR("(%lu) failed", busNo); + LOGERR("(%lu) failed", bus_no); return FALSE; } - memcpy(busInfo, p, sizeof(struct visorchipset_bus_info)); + memcpy(bus_info, p, sizeof(struct visorchipset_bus_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); -- GitLab From b486df191c629718bb64d6e2ae8d78b8a4de9276 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:38 -0400 Subject: [PATCH 2771/9457] staging: unisys: fix CamelCase in visorchipset_get_device_info() Fix CamelCase names: busNo => bus_no devNo => dev_no devInfo => dev_info Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 4 ++-- .../staging/unisys/visorchipset/visorchipset_main.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 6f42712dfcd1..7265e2ffc8a8 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -275,8 +275,8 @@ void visorchipset_device_pause_response(ulong bus_no, ulong dev_no, BOOL visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info); -BOOL visorchipset_get_device_info(ulong busNo, ulong devNo, - struct visorchipset_device_info *devInfo); +BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, + struct visorchipset_device_info *dev_info); BOOL visorchipset_get_switch_info(ulong switchNo, struct visorchipset_switch_info *switchInfo); BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 041dba0d9e06..bebd0e4a3b94 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2230,16 +2230,16 @@ visorchipset_set_bus_context(ulong busNo, void *context) EXPORT_SYMBOL_GPL(visorchipset_set_bus_context); BOOL -visorchipset_get_device_info(ulong busNo, ulong devNo, - struct visorchipset_device_info *devInfo) +visorchipset_get_device_info(ulong bus_no, ulong dev_no, + struct visorchipset_device_info *dev_info) { - void *p = finddevice(&DevInfoList, busNo, devNo); + void *p = finddevice(&DevInfoList, bus_no, dev_no); if (!p) { - LOGERR("(%lu,%lu) failed", busNo, devNo); + LOGERR("(%lu,%lu) failed", bus_no, dev_no); return FALSE; } - memcpy(devInfo, p, sizeof(struct visorchipset_device_info)); + memcpy(dev_info, p, sizeof(struct visorchipset_device_info)); return TRUE; } EXPORT_SYMBOL_GPL(visorchipset_get_device_info); -- GitLab From 5c01b454d828098421c9c93b42dc338037b47c10 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:39 -0400 Subject: [PATCH 2772/9457] staging: unisys: remove unused definitions from visorchipset.h Delete visorchipset_get_switch_info() and visorchipset_get_externalport_info() as these functions were declared but not defined, or used. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 7265e2ffc8a8..ac8f44db449c 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -277,11 +277,6 @@ BOOL visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info); BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, struct visorchipset_device_info *dev_info); -BOOL visorchipset_get_switch_info(ulong switchNo, - struct visorchipset_switch_info *switchInfo); -BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo, - struct visorchipset_externalport_info - *externalPortInfo); BOOL visorchipset_set_bus_context(ulong busNo, void *context); BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); int visorchipset_chipset_ready(void); -- GitLab From 58dd8f2d79549b53f49b9198bbddb3de94b49760 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:40 -0400 Subject: [PATCH 2773/9457] staging: unisys: fix CamelCase in visorchipset_set_bus_context() Fix CamelCase parameter: busNo => bus_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset_main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index ac8f44db449c..9302036c6ecd 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -277,7 +277,7 @@ BOOL visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info); BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, struct visorchipset_device_info *dev_info); -BOOL visorchipset_set_bus_context(ulong busNo, void *context); +BOOL visorchipset_set_bus_context(ulong bus_no, void *context); BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index bebd0e4a3b94..873b9ea875fb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2216,12 +2216,12 @@ visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info) EXPORT_SYMBOL_GPL(visorchipset_get_bus_info); BOOL -visorchipset_set_bus_context(ulong busNo, void *context) +visorchipset_set_bus_context(ulong bus_no, void *context) { - struct visorchipset_bus_info *p = findbus(&BusInfoList, busNo); + struct visorchipset_bus_info *p = findbus(&BusInfoList, bus_no); if (!p) { - LOGERR("(%lu) failed", busNo); + LOGERR("(%lu) failed", bus_no); return FALSE; } p->bus_driver_context = context; -- GitLab From cf0bd0b5794ba4832cd482d60edf0c32bb060745 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:41 -0400 Subject: [PATCH 2774/9457] staging: unisys: fix CamelCase in visorchipset_set_device_context() Fix CamelCase parameter names: busNo => bus_no devNo => dev_no Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 2 +- drivers/staging/unisys/visorchipset/visorchipset_main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 9302036c6ecd..5efc2d6dc57b 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -278,7 +278,7 @@ BOOL visorchipset_get_bus_info(ulong bus_no, BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, struct visorchipset_device_info *dev_info); BOOL visorchipset_set_bus_context(ulong bus_no, void *context); -BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context); +BOOL visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); int visorchipset_chipset_notready(void); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 873b9ea875fb..b5a0e460da07 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -2245,13 +2245,13 @@ visorchipset_get_device_info(ulong bus_no, ulong dev_no, EXPORT_SYMBOL_GPL(visorchipset_get_device_info); BOOL -visorchipset_set_device_context(ulong busNo, ulong devNo, void *context) +visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context) { struct visorchipset_device_info *p = - finddevice(&DevInfoList, busNo, devNo); + finddevice(&DevInfoList, bus_no, dev_no); if (!p) { - LOGERR("(%lu,%lu) failed", busNo, devNo); + LOGERR("(%lu,%lu) failed", bus_no, dev_no); return FALSE; } p->bus_driver_context = context; -- GitLab From 60f4cf035e232e06f9f1895bb0b6cee4eaa41bfb Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:42 -0400 Subject: [PATCH 2775/9457] staging: unisys: remove visorchipset_controlvm_respond_reportEvent() No one is using this definition so remove it. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 5efc2d6dc57b..4963cbccdc2b 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -282,8 +282,6 @@ BOOL visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); int visorchipset_chipset_notready(void); -void visorchipset_controlvm_respond_reportEvent(struct controlvm_message *msg, - void *payload); void visorchipset_save_message(struct controlvm_message *msg, enum crash_obj_type type); void *visorchipset_cache_alloc(struct kmem_cache *pool, -- GitLab From 10c295a1d20c493d06d910ff2a244bdbb1c223cc Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 31 Oct 2014 09:57:43 -0400 Subject: [PATCH 2776/9457] staging: unisys: remove unused macros from visorchipset.h Delete the macros and related preprocessor code for DBG_GETFILE_PAYLOAD(), DBG_GETFILE(), and DBG_PUTFILE(). Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index 4963cbccdc2b..46dad63fa2c8 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -289,17 +289,4 @@ void *visorchipset_cache_alloc(struct kmem_cache *pool, void visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln); -#if defined(TRANSMITFILE_DEBUG) || defined(DEBUG) -#define DBG_GETFILE_PAYLOAD(msg, controlvm_header) \ - LOGINF(msg, \ - (ulong)controlvm_header.PayloadVmOffset, \ - (ulong)controlvm_header.PayloadMaxBytes) -#define DBG_GETFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__) -#define DBG_PUTFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__) -#else -#define DBG_GETFILE_PAYLOAD(msg, controlvm_header) -#define DBG_GETFILE(fmt, ...) -#define DBG_PUTFILE(fmt, ...) -#endif - #endif -- GitLab From 09b0e27621ad8eed4fd48a5fb2d177834b1cb142 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:00 -0500 Subject: [PATCH 2777/9457] staging: unisys: virtpci: Fix CamelCase Chipset_DriverInfo Rename Chipset_DriverInfo to chipset_driver_info in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index b6c313000899..6b4d94cae1fc 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -138,7 +138,7 @@ static struct device virtpci_rootbus_device = { }; /* filled in with info about parent chipset driver when we register with it */ -static struct ultra_vbus_deviceinfo Chipset_DriverInfo; +static struct ultra_vbus_deviceinfo chipset_driver_info; static const struct sysfs_ops virtpci_driver_sysfs_ops = { .show = virtpci_driver_attr_show, @@ -280,7 +280,7 @@ static int add_vbus(struct add_vbus_guestpart *addparams) return 0; } write_vbus_chpInfo(vbus->platform_data /* chanptr */ , - &Chipset_DriverInfo); + &chipset_driver_info); write_vbus_busInfo(vbus->platform_data /* chanptr */ , &Bus_DriverInfo); LOGINF("Added vbus %d; device %s created successfully\n", addparams->bus_no, BUS_ID(vbus)); @@ -801,7 +801,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. */ - write_vbus_chpInfo(pChan, &Chipset_DriverInfo); + write_vbus_chpInfo(pChan, &chipset_driver_info); write_vbus_busInfo(pChan, &Bus_DriverInfo); } @@ -1536,7 +1536,7 @@ static int __init virtpci_mod_init(void) DBGINF("device_register successful ret:%x\n", ret); if (!uisctrl_register_req_handler(2, (void *)&virtpci_ctrlchan_func, - &Chipset_DriverInfo)) { + &chipset_driver_info)) { LOGERR("uisctrl_register_req_handler ****FAILED.\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); device_unregister(&virtpci_rootbus_device); -- GitLab From 8a7281b21b6e78717a74ebac4ed0a1e3446973df Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:01 -0500 Subject: [PATCH 2778/9457] staging: unisys: virtpci: Fix CamelCase virtpci device list head Rename VpcidevListHead to vpcidev_list_head in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 6b4d94cae1fc..383be50f6a3d 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -149,7 +149,7 @@ static struct kobj_type virtpci_driver_kobj_type = { .sysfs_ops = &virtpci_driver_sysfs_ops, }; -static struct virtpci_dev *VpcidevListHead; +static struct virtpci_dev *vpcidev_list_head; static DEFINE_RWLOCK(VpcidevListLock); /* filled in with info about this driver, wrt it servicing client busses */ @@ -590,8 +590,8 @@ static void delete_all(void) /* delete the entire vhba/vnic list in one shot */ write_lock_irqsave(&VpcidevListLock, flags); - tmpvpcidev = VpcidevListHead; - VpcidevListHead = NULL; + tmpvpcidev = vpcidev_list_head; + vpcidev_list_head = NULL; write_unlock_irqrestore(&VpcidevListLock, flags); /* delete one vhba/vnic at a time */ @@ -967,7 +967,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, * duplicate wwnn/macaddr first */ write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead; tmpvpcidev; + for (tmpvpcidev = vpcidev_list_head; tmpvpcidev; tmpvpcidev = tmpvpcidev->next) { if (devtype == VIRTHBA_TYPE) { if ((tmpvpcidev->scsi.wwnn.wwnn1 == scsi->wwnn.wwnn1) && @@ -996,14 +996,14 @@ static int virtpci_device_add(struct device *parentbus, int devtype, } /* add it at the head */ - if (!VpcidevListHead) { - VpcidevListHead = virtpcidev; + if (!vpcidev_list_head) { + vpcidev_list_head = virtpcidev; } else { /* insert virtpcidev at the head of our linked list of * vpcidevs */ - virtpcidev->next = VpcidevListHead; - VpcidevListHead = virtpcidev; + virtpcidev->next = vpcidev_list_head; + vpcidev_list_head = virtpcidev; } write_unlock_irqrestore(&VpcidevListLock, flags); @@ -1041,14 +1041,14 @@ static int virtpci_device_add(struct device *parentbus, int devtype, CHANNELCLI_DETACHED, NULL); /* remove virtpcidev, the one we just added, from the list */ write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prev = NULL; + for (tmpvpcidev = vpcidev_list_head, prev = NULL; tmpvpcidev; prev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev == virtpcidev) { if (prev) prev->next = tmpvpcidev->next; else - VpcidevListHead = tmpvpcidev->next; + vpcidev_list_head = tmpvpcidev->next; break; } } @@ -1086,7 +1086,7 @@ static int virtpci_device_serverdown(struct device *parentbus, /* find the vhba or vnic in virtpci device list */ write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); prevvpcidev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev->devtype != devtype) @@ -1145,7 +1145,7 @@ static int virtpci_device_serverup(struct device *parentbus, /* find the vhba or vnic in virtpci device list */ write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); prevvpcidev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { if (tmpvpcidev->devtype != devtype) @@ -1224,7 +1224,7 @@ static int virtpci_device_del(struct device *parentbus, * encounter "schedule while atomic" */ write_lock_irqsave(&VpcidevListLock, flags); - for (tmpvpcidev = VpcidevListHead, prevvpcidev = NULL; tmpvpcidev;) { + for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; tmpvpcidev;) { if (tmpvpcidev->devtype != devtype) DEL_CONTINUE; @@ -1258,7 +1258,7 @@ static int virtpci_device_del(struct device *parentbus, /* not at head */ prevvpcidev->next = tmpvpcidev->next; else - VpcidevListHead = tmpvpcidev->next; + vpcidev_list_head = tmpvpcidev->next; /* add it to our deletelist */ tmpvpcidev->next = dellist; @@ -1273,7 +1273,7 @@ static int virtpci_device_del(struct device *parentbus, if (prevvpcidev) tmpvpcidev = prevvpcidev->next; else - tmpvpcidev = VpcidevListHead; + tmpvpcidev = vpcidev_list_head; } write_unlock_irqrestore(&VpcidevListLock, flags); @@ -1457,7 +1457,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n Virtual PCI devices\n"); read_lock_irqsave(&VpcidevListLock, flags); - tmpvpcidev = VpcidevListHead; + tmpvpcidev = vpcidev_list_head; while (tmpvpcidev) { if (tmpvpcidev->devtype == VIRTHBA_TYPE) { str_pos += scnprintf(vbuf + str_pos, len - str_pos, -- GitLab From 4ecd8281b2fa6fc49927a22e95ddb859d40a20b4 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:02 -0500 Subject: [PATCH 2779/9457] staging: unisys: virtpci: Fix CamelCase virtpci device list lock Rename VpcidevListLock to vpcidev_list_lock in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 383be50f6a3d..143bb0028981 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -150,7 +150,7 @@ static struct kobj_type virtpci_driver_kobj_type = { }; static struct virtpci_dev *vpcidev_list_head; -static DEFINE_RWLOCK(VpcidevListLock); +static DEFINE_RWLOCK(vpcidev_list_lock); /* filled in with info about this driver, wrt it servicing client busses */ static struct ultra_vbus_deviceinfo Bus_DriverInfo; @@ -589,10 +589,10 @@ static void delete_all(void) struct virtpci_dev *tmpvpcidev, *nextvpcidev; /* delete the entire vhba/vnic list in one shot */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); tmpvpcidev = vpcidev_list_head; vpcidev_list_head = NULL; - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); /* delete one vhba/vnic at a time */ while (tmpvpcidev) { @@ -966,7 +966,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, /* add the vhba/vnic to virtpci device list - but check for * duplicate wwnn/macaddr first */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); for (tmpvpcidev = vpcidev_list_head; tmpvpcidev; tmpvpcidev = tmpvpcidev->next) { if (devtype == VIRTHBA_TYPE) { @@ -988,7 +988,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, /* found a vhba/vnic already in the list with same * wwnn or macaddr - reject add */ - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); kfree(virtpcidev); LOGERR("**** FAILED vhba/vnic already exists in the list\n"); POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); @@ -1006,7 +1006,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, vpcidev_list_head = virtpcidev; } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); /* Must transition channel to ATTACHED state BEFORE * registering the device, because polling of the channel @@ -1040,7 +1040,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, BUS_ID(pDev), CHANNELCLI_DETACHED, NULL); /* remove virtpcidev, the one we just added, from the list */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); for (tmpvpcidev = vpcidev_list_head, prev = NULL; tmpvpcidev; prev = tmpvpcidev, tmpvpcidev = tmpvpcidev->next) { @@ -1052,7 +1052,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, break; } } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); kfree(virtpcidev); return 0; } @@ -1084,7 +1084,7 @@ static int virtpci_device_serverdown(struct device *parentbus, } /* find the vhba or vnic in virtpci device list */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); @@ -1114,7 +1114,7 @@ static int virtpci_device_serverdown(struct device *parentbus, vpcidriver = tmpvpcidev->mydriver; rc = vpcidriver->suspend(tmpvpcidev, 0); } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!found) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1143,7 +1143,7 @@ static int virtpci_device_serverup(struct device *parentbus, } /* find the vhba or vnic in virtpci device list */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; (tmpvpcidev && !found); @@ -1182,7 +1182,7 @@ static int virtpci_device_serverup(struct device *parentbus, rc = vpcidriver->resume(tmpvpcidev); } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!found) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1223,7 +1223,7 @@ static int virtpci_device_del(struct device *parentbus, * device_unregister after we release the lock; otherwise we * encounter "schedule while atomic" */ - write_lock_irqsave(&VpcidevListLock, flags); + write_lock_irqsave(&vpcidev_list_lock, flags); for (tmpvpcidev = vpcidev_list_head, prevvpcidev = NULL; tmpvpcidev;) { if (tmpvpcidev->devtype != devtype) DEL_CONTINUE; @@ -1275,7 +1275,7 @@ static int virtpci_device_del(struct device *parentbus, else tmpvpcidev = vpcidev_list_head; } - write_unlock_irqrestore(&VpcidevListLock, flags); + write_unlock_irqrestore(&vpcidev_list_lock, flags); if (!all && (count == 0)) { LOGERR("**** FAILED to find vhba/vnic in the list\n"); @@ -1456,7 +1456,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n Virtual PCI devices\n"); - read_lock_irqsave(&VpcidevListLock, flags); + read_lock_irqsave(&vpcidev_list_lock, flags); tmpvpcidev = vpcidev_list_head; while (tmpvpcidev) { if (tmpvpcidev->devtype == VIRTHBA_TYPE) { @@ -1489,7 +1489,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, tmpvpcidev->queueinfo.chan); tmpvpcidev = tmpvpcidev->next; } - read_unlock_irqrestore(&VpcidevListLock, flags); + read_unlock_irqrestore(&vpcidev_list_lock, flags); str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n"); bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos); -- GitLab From e322528dca1ead8f254a302a77af72ed20efcc55 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:03 -0500 Subject: [PATCH 2780/9457] staging: unisys: virtpci: Fix CamelCase vbus driver info variable Rename BusDriverInfo variable to bus_driver_info in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 143bb0028981..7d997fd432e3 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -153,7 +153,7 @@ static struct virtpci_dev *vpcidev_list_head; static DEFINE_RWLOCK(vpcidev_list_lock); /* filled in with info about this driver, wrt it servicing client busses */ -static struct ultra_vbus_deviceinfo Bus_DriverInfo; +static struct ultra_vbus_deviceinfo bus_driver_info; /*****************************************************/ /* debugfs entries */ @@ -281,7 +281,8 @@ static int add_vbus(struct add_vbus_guestpart *addparams) } write_vbus_chpInfo(vbus->platform_data /* chanptr */ , &chipset_driver_info); - write_vbus_busInfo(vbus->platform_data /* chanptr */ , &Bus_DriverInfo); + write_vbus_busInfo(vbus->platform_data /* chanptr */ , + &bus_driver_info); LOGINF("Added vbus %d; device %s created successfully\n", addparams->bus_no, BUS_ID(vbus)); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -802,7 +803,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, * was previously written by our good counterpart, visorbus. */ write_vbus_chpInfo(pChan, &chipset_driver_info); - write_vbus_busInfo(pChan, &Bus_DriverInfo); + write_vbus_busInfo(pChan, &bus_driver_info); } /* This function is called to query the existence of a specific device @@ -1521,7 +1522,7 @@ static int __init virtpci_mod_init(void) return ret; } DBGINF("bus_register successful\n"); - bus_device_info_init(&Bus_DriverInfo, "clientbus", "virtpci", + bus_device_info_init(&bus_driver_info, "clientbus", "virtpci", VERSION, NULL); /* create a root bus used to parent all the virtpci buses. */ -- GitLab From 442ab1dfcf8e3d5613e7992649196f0205cc4ee9 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:04 -0500 Subject: [PATCH 2781/9457] staging: unisys: virtpci: Fix CamelCase write_vbus_chpInfo() Rename write_vbus_chpInfo() to write_vbus_chp_info() in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 7d997fd432e3..5e1a7ebdbb31 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -186,8 +186,8 @@ int WAIT_FOR_IO_CHANNEL(struct spar_io_channel_protocol __iomem *chanptr) } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */ -static int write_vbus_chpInfo(struct spar_vbus_channel_protocol *chan, - struct ultra_vbus_deviceinfo *info) +static int write_vbus_chp_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info) { int off; @@ -279,8 +279,8 @@ static int add_vbus(struct add_vbus_guestpart *addparams) POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR); return 0; } - write_vbus_chpInfo(vbus->platform_data /* chanptr */ , - &chipset_driver_info); + write_vbus_chp_info(vbus->platform_data /* chanptr */ , + &chipset_driver_info); write_vbus_busInfo(vbus->platform_data /* chanptr */ , &bus_driver_info); LOGINF("Added vbus %d; device %s created successfully\n", @@ -802,7 +802,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. */ - write_vbus_chpInfo(pChan, &chipset_driver_info); + write_vbus_chp_info(pChan, &chipset_driver_info); write_vbus_busInfo(pChan, &bus_driver_info); } -- GitLab From b820d030b0eb2fab5a80f1c491540bf802d05ae6 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:05 -0500 Subject: [PATCH 2782/9457] staging: unisys: virtpci: Fix CamelCase write_vbus_busInfo() Rename write_vbus_busInfo() to write_vbus_bus_info() in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 5e1a7ebdbb31..c992b9fd4ad0 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -205,8 +205,8 @@ static int write_vbus_chp_info(struct spar_vbus_channel_protocol *chan, } /* Write the contents of to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */ -static int write_vbus_busInfo(struct spar_vbus_channel_protocol *chan, - struct ultra_vbus_deviceinfo *info) +static int write_vbus_bus_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info) { int off; @@ -281,8 +281,8 @@ static int add_vbus(struct add_vbus_guestpart *addparams) } write_vbus_chp_info(vbus->platform_data /* chanptr */ , &chipset_driver_info); - write_vbus_busInfo(vbus->platform_data /* chanptr */ , - &bus_driver_info); + write_vbus_bus_info(vbus->platform_data /* chanptr */ , + &bus_driver_info); LOGINF("Added vbus %d; device %s created successfully\n", addparams->bus_no, BUS_ID(vbus)); POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -803,7 +803,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, * was previously written by our good counterpart, visorbus. */ write_vbus_chp_info(pChan, &chipset_driver_info); - write_vbus_busInfo(pChan, &bus_driver_info); + write_vbus_bus_info(pChan, &bus_driver_info); } /* This function is called to query the existence of a specific device -- GitLab From 57fd91999195029d3ae0dc9af7ddfcf85207d379 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:06 -0500 Subject: [PATCH 2783/9457] staging: unisys: virtpci: Fix CamelCase write_vbus_devInfo() Rename write_vbus_devInfo() to write_vbus_dev_info() in virtpci.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index c992b9fd4ad0..a299b32a3b95 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -227,8 +227,8 @@ static int write_vbus_bus_info(struct spar_vbus_channel_protocol *chan, * ULTRA_VBUS_CHANNEL_PROTOCOL.DevInfo[]. */ static int -write_vbus_devInfo(struct spar_vbus_channel_protocol *chan, - struct ultra_vbus_deviceinfo *info, int devix) +write_vbus_dev_info(struct spar_vbus_channel_protocol *chan, + struct ultra_vbus_deviceinfo *info, int devix) { int off; @@ -797,7 +797,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, virtpcidrv->name, virtpcidrv->version, virtpcidrv->vertag); - write_vbus_devInfo(pChan, &devInfo, devNo); + write_vbus_dev_info(pChan, &devInfo, devNo); /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. -- GitLab From 865cde938ee6ab758fd47d1a36150aee20371b85 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:07 -0500 Subject: [PATCH 2784/9457] staging: unisys: virtpci: Fix CamelCase in delete_vbus_device() Rename pDev to dev in delete_vbus_device() Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index a299b32a3b95..b6e508f99136 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -430,9 +430,9 @@ static int delete_vbus_device(struct device *vbus, void *data) { int checkforroot = (data != NULL); - struct device *pDev = &virtpci_rootbus_device; + struct device *dev = &virtpci_rootbus_device; - if ((checkforroot) && match_busid(vbus, (void *)BUS_ID(pDev))) { + if ((checkforroot) && match_busid(vbus, (void *)BUS_ID(dev))) { /* skip it - don't delete root bus */ LOGINF("skipping root bus\n"); return 0; /* pretend no error */ -- GitLab From d13b23b8c933902c58559df6e4eb541135959e4a Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:08 -0500 Subject: [PATCH 2785/9457] staging: unisys: virtpci: Fix CamelCase name fix_vbus_devInfo() Rename fix_vbus_devInfo() to fix_vbus_dev_info(). Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index b6e508f99136..b4eaca2f4129 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -756,8 +756,8 @@ static int virtpci_device_resume(struct device *dev) * the appropriate slot within the vbus channel of the bus * instance. */ -static void fix_vbus_devInfo(struct device *dev, int devNo, int devType, - struct virtpci_driver *virtpcidrv) +static void fix_vbus_dev_info(struct device *dev, int devNo, int devType, + struct virtpci_driver *virtpcidrv) { struct device *vbus; void *pChan; @@ -843,8 +843,8 @@ static int virtpci_device_probe(struct device *dev) */ error = virtpcidrv->probe(virtpcidev, id); if (!error) { - fix_vbus_devInfo(dev, virtpcidev->device_no, - virtpcidev->device, virtpcidrv); + fix_vbus_dev_info(dev, virtpcidev->device_no, + virtpcidev->device, virtpcidrv); virtpcidev->mydriver = virtpcidrv; POSTCODE_LINUX_2(VPCI_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO); @@ -1177,9 +1177,9 @@ static int virtpci_device_serverup(struct device *parentbus, * ever have a bus that contains NO devices, since we * would never even get here in that case. */ - fix_vbus_devInfo(&tmpvpcidev->generic_dev, - tmpvpcidev->device_no, - tmpvpcidev->device, vpcidriver); + fix_vbus_dev_info(&tmpvpcidev->generic_dev, + tmpvpcidev->device_no, + tmpvpcidev->device, vpcidriver); rc = vpcidriver->resume(tmpvpcidev); } -- GitLab From ceddd0b31949a59ff4faf2c154430833765ab9a8 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:09 -0500 Subject: [PATCH 2786/9457] staging: unisys: virtpci: Fix CamelCase parameters of fix_vbus_dev_info() Rename the following fix_vbus_dev_info() parameters devNo changed to dev_no devType changed to dev_type Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index b4eaca2f4129..80be2335c990 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -756,7 +756,7 @@ static int virtpci_device_resume(struct device *dev) * the appropriate slot within the vbus channel of the bus * instance. */ -static void fix_vbus_dev_info(struct device *dev, int devNo, int devType, +static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, struct virtpci_driver *virtpcidrv) { struct device *vbus; @@ -782,7 +782,7 @@ static void fix_vbus_dev_info(struct device *dev, int devNo, int devType, LOGERR("%s dev bus has no channel", __func__); return; } - switch (devType) { + switch (dev_type) { case PCI_DEVICE_ID_VIRTHBA: stype = "vHBA"; break; @@ -797,7 +797,7 @@ static void fix_vbus_dev_info(struct device *dev, int devNo, int devType, virtpcidrv->name, virtpcidrv->version, virtpcidrv->vertag); - write_vbus_dev_info(pChan, &devInfo, devNo); + write_vbus_dev_info(pChan, &devInfo, dev_no); /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. -- GitLab From a87606c76f7e2a7ad8d5cdbc68417e5772fb8dc6 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:10 -0500 Subject: [PATCH 2787/9457] staging: unisys: virtpci: Fix CamelCase local variables in fix_vbus_dev_info() Rename the following local variables in fix_vbus_dev_info() Change pChan to chan Change devInfo to dev_info Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index 80be2335c990..bfcc0271df79 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -760,8 +760,8 @@ static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, struct virtpci_driver *virtpcidrv) { struct device *vbus; - void *pChan; - struct ultra_vbus_deviceinfo devInfo; + void *chan; + struct ultra_vbus_deviceinfo dev_info; const char *stype; if (!dev) { @@ -777,8 +777,8 @@ static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, LOGERR("%s dev has no parent bus", __func__); return; } - pChan = vbus->platform_data; - if (!pChan) { + chan = vbus->platform_data; + if (!chan) { LOGERR("%s dev bus has no channel", __func__); return; } @@ -793,17 +793,17 @@ static void fix_vbus_dev_info(struct device *dev, int dev_no, int dev_type, stype = "unknown"; break; } - bus_device_info_init(&devInfo, stype, + bus_device_info_init(&dev_info, stype, virtpcidrv->name, virtpcidrv->version, virtpcidrv->vertag); - write_vbus_dev_info(pChan, &devInfo, dev_no); + write_vbus_dev_info(chan, &dev_info, dev_no); /* Re-write bus+chipset info, because it is possible that this * was previously written by our good counterpart, visorbus. */ - write_vbus_chp_info(pChan, &chipset_driver_info); - write_vbus_bus_info(pChan, &bus_driver_info); + write_vbus_chp_info(chan, &chipset_driver_info); + write_vbus_bus_info(chan, &bus_driver_info); } /* This function is called to query the existence of a specific device -- GitLab From c159921f7eca8ca323316e7c0ad64d0e073b2ded Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Mon, 3 Nov 2014 14:21:11 -0500 Subject: [PATCH 2788/9457] staging: unisys: virtpci: Fix CamelCase local variables in virtpci_device_add() Rename the following local variables in virtpci_device_add() pIoChan changed to io_chan pDev changed to dev Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/virtpci/virtpci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index bfcc0271df79..e212c7afb468 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -910,8 +910,8 @@ static int virtpci_device_add(struct device *parentbus, int devtype, struct virtpci_dev *tmpvpcidev = NULL, *prev; unsigned long flags; int ret; - struct spar_io_channel_protocol __iomem *pIoChan = NULL; - struct device *pDev; + struct spar_io_channel_protocol __iomem *io_chan = NULL; + struct device *dev; LOGINF("virtpci_device_add parentbus:%p chanptr:%p\n", parentbus, addparams->chanptr); @@ -951,7 +951,7 @@ static int virtpci_device_add(struct device *parentbus, int devtype, virtpcidev->queueinfo.send_int_if_needed = NULL; /* Set up safe queue... */ - pIoChan = (struct spar_io_channel_protocol __iomem *) + io_chan = (struct spar_io_channel_protocol __iomem *) virtpcidev->queueinfo.chan; virtpcidev->intr = addparams->intr; @@ -1013,9 +1013,9 @@ static int virtpci_device_add(struct device *parentbus, int devtype, * registering the device, because polling of the channel * queues can begin at any time after device_register(). */ - pDev = &virtpcidev->generic_dev; + dev = &virtpcidev->generic_dev; SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), + BUS_ID(dev), CHANNELCLI_ATTACHED, NULL); /* don't register until device has been added to @@ -1036,9 +1036,9 @@ static int virtpci_device_add(struct device *parentbus, int devtype, */ if (ret) { LOGERR("device_register returned %d\n", ret); - pDev = &virtpcidev->generic_dev; + dev = &virtpcidev->generic_dev; SPAR_CHANNEL_CLIENT_TRANSITION(addparams->chanptr, - BUS_ID(pDev), + BUS_ID(dev), CHANNELCLI_DETACHED, NULL); /* remove virtpcidev, the one we just added, from the list */ write_lock_irqsave(&vpcidev_list_lock, flags); -- GitLab From 5519b5f5514ee8282044bf0d5a30481fb5c1b3bb Mon Sep 17 00:00:00 2001 From: Ken Depro Date: Mon, 3 Nov 2014 14:56:32 -0500 Subject: [PATCH 2789/9457] staging: unisys: Remove unneeded spaces from channel.c This patch removes some unneeded white space after casts within the channel.c file. The checkpatch script was run after these changes, and no further checks or warnings were seen. Signed-off-by: Ken Depro Signed-off-by: Ben Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index 2fc61a74ee54..74cc4d6b515f 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -51,7 +51,7 @@ unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue, struct signal_queue_header __iomem *pqhdr = (struct signal_queue_header __iomem *) - ((char __iomem *) ch + readq(&ch->ch_space_offset)) + ((char __iomem *)ch + readq(&ch->ch_space_offset)) + queue; /* capture current head and tail */ @@ -107,7 +107,7 @@ spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig) void __iomem *psource; unsigned int head, tail; struct signal_queue_header __iomem *pqhdr = - (struct signal_queue_header __iomem *) ((char __iomem *) ch + + (struct signal_queue_header __iomem *)((char __iomem *)ch + readq(&ch->ch_space_offset)) + queue; /* capture current head and tail */ @@ -124,7 +124,7 @@ spar_signal_remove(struct channel_header __iomem *ch, u32 queue, void *sig) tail = (tail + 1) % readl(&pqhdr->max_slots); /* copy signal from tail location to the area pointed to by pSignal */ - psource = (char __iomem *) pqhdr + readq(&pqhdr->sig_base_offset) + + psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) + (tail * readl(&pqhdr->signal_size)); memcpy_fromio(sig, psource, readl(&pqhdr->signal_size)); @@ -162,7 +162,7 @@ unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, void *psource; unsigned int head, tail, count = 0; struct signal_queue_header *pqhdr = - (struct signal_queue_header *) ((char *) ch + + (struct signal_queue_header *)((char *)ch + ch->ch_space_offset) + queue; /* capture current head and tail */ @@ -181,9 +181,9 @@ unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue, * to by pSignal */ psource = - (char *) pqhdr + pqhdr->sig_base_offset + + (char *)pqhdr + pqhdr->sig_base_offset + (tail * pqhdr->signal_size); - memcpy((char *) sig + (pqhdr->signal_size * count), + memcpy((char *)sig + (pqhdr->signal_size * count), psource, pqhdr->signal_size); mb(); /* channel synch */ @@ -211,7 +211,7 @@ unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch, u32 queue) { struct signal_queue_header __iomem *pqhdr = - (struct signal_queue_header __iomem *) ((char __iomem *) ch + + (struct signal_queue_header __iomem *)((char __iomem *)ch + readq(&ch->ch_space_offset)) + queue; return readl(&pqhdr->head) == readl(&pqhdr->tail); } -- GitLab From 34ba94bac938be14ffe2a639a4688b81a37d0f58 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 9 Oct 2014 13:19:53 -0700 Subject: [PATCH 2790/9457] f2fs: do not make dirty any inmemory pages This patch let inmemory pages be clean all the time. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 11 +++++++---- fs/f2fs/f2fs.h | 1 + fs/f2fs/segment.c | 14 +++++++++++++- fs/f2fs/super.c | 1 + 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8e58c4cc2cb9..84f20e932499 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1052,10 +1052,7 @@ static int f2fs_write_end(struct file *file, trace_f2fs_write_end(inode, pos, len, copied); - if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) - register_inmem_page(inode, page); - else - set_page_dirty(page); + set_page_dirty(page); if (pos + copied > i_size_read(inode)) { i_size_write(inode, pos + copied); @@ -1138,6 +1135,12 @@ static int f2fs_set_data_page_dirty(struct page *page) trace_f2fs_set_page_dirty(page, DATA); SetPageUptodate(page); + + if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) { + register_inmem_page(inode, page); + return 1; + } + mark_inode_dirty(inode); if (!PageDirty(page)) { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 8171e80b2ee9..28f24ea13cb2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -269,6 +269,7 @@ struct f2fs_inode_info { struct extent_info ext; /* in-memory extent cache entry */ struct dir_inode_entry *dirty_dir; /* the pointer of dirty dir */ + struct radix_tree_root inmem_root; /* radix tree for inmem pages */ struct list_head inmem_pages; /* inmemory pages managed by f2fs */ struct mutex inmem_lock; /* lock for inmemory pages */ }; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 923cb76fdc46..9d4a7ab33b06 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -178,7 +178,8 @@ void register_inmem_page(struct inode *inode, struct page *page) { struct f2fs_inode_info *fi = F2FS_I(inode); struct inmem_pages *new; - + int err; +retry: new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS); /* add atomic page indices to the list */ @@ -187,6 +188,16 @@ void register_inmem_page(struct inode *inode, struct page *page) /* increase reference count with clean state */ mutex_lock(&fi->inmem_lock); + err = radix_tree_insert(&fi->inmem_root, page->index, new); + if (err == -EEXIST) { + mutex_unlock(&fi->inmem_lock); + kmem_cache_free(inmem_entry_slab, new); + return; + } else if (err) { + mutex_unlock(&fi->inmem_lock); + kmem_cache_free(inmem_entry_slab, new); + goto retry; + } get_page(page); list_add_tail(&new->list, &fi->inmem_pages); mutex_unlock(&fi->inmem_lock); @@ -216,6 +227,7 @@ void commit_inmem_pages(struct inode *inode, bool abort) do_write_data_page(cur->page, &fio); submit_bio = true; } + radix_tree_delete(&fi->inmem_root, cur->page->index); f2fs_put_page(cur->page, 1); list_del(&cur->list); kmem_cache_free(inmem_entry_slab, cur); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 41d6f700f4ee..76b14c8c7e16 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -373,6 +373,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) fi->i_advise = 0; rwlock_init(&fi->ext.ext_lock); init_rwsem(&fi->i_sem); + INIT_RADIX_TREE(&fi->inmem_root, GFP_NOFS); INIT_LIST_HEAD(&fi->inmem_pages); mutex_init(&fi->inmem_lock); -- GitLab From cbcb2872e37ba0511f21b3ab5d65973b2055440c Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 9 Oct 2014 13:39:06 -0700 Subject: [PATCH 2791/9457] f2fs: invalidate inmemory page If user truncates file's data, we should truncate inmemory pages too. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 3 +++ fs/f2fs/f2fs.h | 1 + fs/f2fs/segment.c | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 84f20e932499..5b80adac8985 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1116,6 +1116,9 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset, if (offset % PAGE_CACHE_SIZE || length != PAGE_CACHE_SIZE) return; + if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode)) + invalidate_inmem_page(inode, page); + if (PageDirty(page)) inode_dec_dirty_pages(inode); ClearPagePrivate(page); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 28f24ea13cb2..d41d1b725919 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1297,6 +1297,7 @@ void destroy_node_manager_caches(void); * segment.c */ void register_inmem_page(struct inode *, struct page *); +void invalidate_inmem_page(struct inode *, struct page *); void commit_inmem_pages(struct inode *, bool); void f2fs_balance_fs(struct f2fs_sb_info *); void f2fs_balance_fs_bg(struct f2fs_sb_info *); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9d4a7ab33b06..902c4c3f6b70 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -203,6 +203,22 @@ void register_inmem_page(struct inode *inode, struct page *page) mutex_unlock(&fi->inmem_lock); } +void invalidate_inmem_page(struct inode *inode, struct page *page) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + struct inmem_pages *cur; + + mutex_lock(&fi->inmem_lock); + cur = radix_tree_lookup(&fi->inmem_root, page->index); + if (cur) { + radix_tree_delete(&fi->inmem_root, cur->page->index); + f2fs_put_page(cur->page, 0); + list_del(&cur->list); + kmem_cache_free(inmem_entry_slab, cur); + } + mutex_unlock(&fi->inmem_lock); +} + void commit_inmem_pages(struct inode *inode, bool abort) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); -- GitLab From c08a690b46919e6b531c1a2bb74389323e5f5b1c Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 15 Oct 2014 10:16:54 -0700 Subject: [PATCH 2792/9457] f2fs: should truncate any allocated block for inline_data write When trying to write inline_data, we should truncate any data block allocated and pointed by the inode block. We should consider the data index is not 0. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 88036fd75797..e3abcfb54374 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -166,6 +166,14 @@ int f2fs_write_inline_data(struct inode *inode, return err; ipage = dn.inode_page; + /* Release any data block if it is allocated */ + if (!f2fs_has_inline_data(inode)) { + int count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); + truncate_data_blocks_range(&dn, count); + set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); + stat_inc_inline_inode(inode); + } + f2fs_wait_on_page_writeback(ipage, NODE); zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); @@ -174,13 +182,6 @@ int f2fs_write_inline_data(struct inode *inode, memcpy(dst_addr, src_addr, size); kunmap(page); - /* Release the first data block if it is allocated */ - if (!f2fs_has_inline_data(inode)) { - truncate_data_blocks_range(&dn, 1); - set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); - stat_inc_inline_inode(inode); - } - set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); sync_inode_page(&dn); f2fs_put_dnode(&dn); -- GitLab From 1ce86bf6f882381013e12b16bbb3921608c0f238 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 15 Oct 2014 10:24:34 -0700 Subject: [PATCH 2793/9457] f2fs: fix race conditon on truncation with inline_data Let's consider the following scenario. blkaddr[0] inline_data i_size i_blocks writepage truncate NEW X 4096 2 dirty page #0 NEW X 0 change i_size NEW X 0 2 f2fs_write_inline_data NEW X 0 2 get_dnode_of_data NEW X 0 2 truncate_data_blocks_range NULL O 0 1 memcpy(inline_data) NULL O 0 1 f2fs_put_dnode NULL O 0 1 f2fs_truncate NULL O 0 1 get_dnode_of_data NULL O 0 1 *invalid block addr* This patch adds checking inline_data flag during f2fs_truncate not to refer corrupted block indices. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 8e68bb64f835..543d8c630345 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -473,6 +473,12 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) return err; } + /* writepage can convert inline_data under get_donde_of_data */ + if (f2fs_has_inline_data(inode)) { + f2fs_put_dnode(&dn); + goto done; + } + count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); count -= dn.ofs_in_node; -- GitLab From a78186ebe516b6d7df43636603f0998803ab356a Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 17 Oct 2014 17:57:29 -0700 Subject: [PATCH 2794/9457] f2fs: use highmem for directory pages This patch fixes to use highmem for directory pages. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inode.c | 2 +- include/linux/f2fs_fs.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 0deead4505e7..52d6f54664f6 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -156,7 +156,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); + mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO); } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &f2fs_symlink_inode_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 860313a33a43..6d7381b41304 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -33,7 +33,8 @@ #define F2FS_META_INO(sbi) (sbi->meta_ino_num) /* This flag is used by node and meta inodes, and by recovery */ -#define GFP_F2FS_ZERO (GFP_NOFS | __GFP_ZERO) +#define GFP_F2FS_ZERO (GFP_NOFS | __GFP_ZERO) +#define GFP_F2FS_HIGH_ZERO (GFP_NOFS | __GFP_ZERO | __GFP_HIGHMEM) /* * For further optimization on multi-head logs, on-disk layout supports maximum -- GitLab From 9ba69cf9877384baebd16c6fb51ceccd13677b37 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 17 Oct 2014 20:33:55 -0700 Subject: [PATCH 2795/9457] f2fs: avoid to allocate when inline_data was written The sceanrio is like this. inline_data i_size page write_begin/vm_page_mkwrite X 30 dirty_page X 30 write to #4096 position X 30 get_dnode_of_data wait for get_dnode_of_data O 30 write inline_data O 30 get_dnode_of_data O 30 reserve data block .. In this case, we have #0 = NEW_ADDR and inline_data as well. We should not allow this condition for further access. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 32 +++++++++++++++++++++++--------- fs/f2fs/file.c | 26 ++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 5b80adac8985..973fd7770d56 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -257,9 +257,6 @@ int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index) bool need_put = dn->inode_page ? false : true; int err; - /* if inode_page exists, index should be zero */ - f2fs_bug_on(F2FS_I_SB(dn->inode), !need_put && index); - err = get_dnode_of_data(dn, index, ALLOC_NODE); if (err) return err; @@ -951,7 +948,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, { struct inode *inode = mapping->host; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - struct page *page; + struct page *page, *ipage; pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; struct dnode_of_data dn; int err = 0; @@ -979,13 +976,26 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, goto inline_data; f2fs_lock_op(sbi); - set_new_dnode(&dn, inode, NULL, NULL, 0); - err = f2fs_reserve_block(&dn, index); - f2fs_unlock_op(sbi); - if (err) { + + /* check inline_data */ + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) + goto unlock_fail; + + if (f2fs_has_inline_data(inode)) { + f2fs_put_page(ipage, 1); + f2fs_unlock_op(sbi); f2fs_put_page(page, 0); - goto fail; + goto repeat; } + + set_new_dnode(&dn, inode, ipage, NULL, 0); + err = f2fs_reserve_block(&dn, index); + if (err) + goto unlock_fail; + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); + inline_data: lock_page(page); if (unlikely(page->mapping != mapping)) { @@ -1038,6 +1048,10 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, SetPageUptodate(page); clear_cold_data(page); return 0; + +unlock_fail: + f2fs_unlock_op(sbi); + f2fs_put_page(page, 0); fail: f2fs_write_failed(mapping, pos + len); return err; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 543d8c630345..456df07f19cb 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -35,12 +35,13 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, struct inode *inode = file_inode(vma->vm_file); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; + struct page *ipage; int err; f2fs_balance_fs(sbi); sb_start_pagefault(inode->i_sb); - +retry: /* force to convert with normal data indices */ err = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1, page); if (err) @@ -48,11 +49,28 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, /* block allocation */ f2fs_lock_op(sbi); - set_new_dnode(&dn, inode, NULL, NULL, 0); + + /* check inline_data */ + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + f2fs_unlock_op(sbi); + goto out; + } + + if (f2fs_has_inline_data(inode)) { + f2fs_put_page(ipage, 1); + f2fs_unlock_op(sbi); + goto retry; + } + + set_new_dnode(&dn, inode, ipage, NULL, 0); err = f2fs_reserve_block(&dn, page->index); - f2fs_unlock_op(sbi); - if (err) + if (err) { + f2fs_unlock_op(sbi); goto out; + } + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); file_update_time(vma->vm_file); lock_page(page); -- GitLab From 13fd8f89f6623b348dfb7ed6dce50fab733f4c91 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sun, 19 Oct 2014 01:43:23 -0700 Subject: [PATCH 2796/9457] f2fs: fix to call f2fs_unlock_op This patch fixes to call f2fs_unlock_op, which was missing before. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 456df07f19cb..80d9a0482e7d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -494,7 +494,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) /* writepage can convert inline_data under get_donde_of_data */ if (f2fs_has_inline_data(inode)) { f2fs_put_dnode(&dn); - goto done; + goto unlock_done; } count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); @@ -510,6 +510,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) f2fs_put_dnode(&dn); free_next: err = truncate_inode_blocks(inode, free_from); +unlock_done: if (lock) f2fs_unlock_op(sbi); done: -- GitLab From 4a257ed677cb68a2096358e58b61efacf85d5f16 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 16 Oct 2014 11:43:30 -0700 Subject: [PATCH 2797/9457] f2fs: avoid build warning This patch removes build warning. Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 902c4c3f6b70..2c1e60893ef2 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1715,7 +1715,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) * #2, flush sit entries to sit page. */ list_for_each_entry_safe(ses, tmp, head, set_list) { - struct page *page; + struct page *page = NULL; struct f2fs_sit_block *raw_sit = NULL; unsigned int start_segno = ses->start_segno; unsigned int end = min(start_segno + SIT_ENTRY_PER_BLOCK, -- GitLab From af41d3ee00bf97bfc3bd64bce6d7a92e85955e98 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 17 Oct 2014 14:14:16 -0700 Subject: [PATCH 2798/9457] f2fs: avoid infinite loop at cp_error This patch avoids an infinite loop in sync_dirty_inode_page when -EIO was detected. Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index dd10a031c052..ca514d599b79 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -731,6 +731,9 @@ void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) struct dir_inode_entry *entry; struct inode *inode; retry: + if (unlikely(f2fs_cp_error(sbi))) + return; + spin_lock(&sbi->dir_inode_lock); head = &sbi->dir_inode_list; -- GitLab From 34d67debe02b3b2b035b5bdce0fab75800f9a344 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:15:19 +0800 Subject: [PATCH 2799/9457] f2fs: add infra struct and helper for inline dir This patch defines macro/inline dentry structure, and adds some helpers for inline dir infrastructure. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 21 +++++++++++++++++++-- include/linux/f2fs_fs.h | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d41d1b725919..4fa0df5f54ea 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -46,8 +46,9 @@ #define F2FS_MOUNT_DISABLE_EXT_IDENTIFY 0x00000040 #define F2FS_MOUNT_INLINE_XATTR 0x00000080 #define F2FS_MOUNT_INLINE_DATA 0x00000100 -#define F2FS_MOUNT_FLUSH_MERGE 0x00000200 -#define F2FS_MOUNT_NOBARRIER 0x00000400 +#define F2FS_MOUNT_INLINE_DENTRY 0x00000200 +#define F2FS_MOUNT_FLUSH_MERGE 0x00000400 +#define F2FS_MOUNT_NOBARRIER 0x00000800 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) @@ -1058,6 +1059,7 @@ enum { FI_NO_EXTENT, /* not to use the extent cache */ FI_INLINE_XATTR, /* used for inline xattr */ FI_INLINE_DATA, /* used for inline data*/ + FI_INLINE_DENTRY, /* used for inline dentry */ FI_APPEND_WRITE, /* inode has appended data */ FI_UPDATE_WRITE, /* inode has in-place-update data */ FI_NEED_IPU, /* used for ipu per file */ @@ -1104,6 +1106,8 @@ static inline void get_inline_info(struct f2fs_inode_info *fi, set_inode_flag(fi, FI_INLINE_XATTR); if (ri->i_inline & F2FS_INLINE_DATA) set_inode_flag(fi, FI_INLINE_DATA); + if (ri->i_inline & F2FS_INLINE_DENTRY) + set_inode_flag(fi, FI_INLINE_DENTRY); } static inline void set_raw_inline(struct f2fs_inode_info *fi, @@ -1115,6 +1119,8 @@ static inline void set_raw_inline(struct f2fs_inode_info *fi, ri->i_inline |= F2FS_INLINE_XATTR; if (is_inode_flag_set(fi, FI_INLINE_DATA)) ri->i_inline |= F2FS_INLINE_DATA; + if (is_inode_flag_set(fi, FI_INLINE_DENTRY)) + ri->i_inline |= F2FS_INLINE_DENTRY; } static inline int f2fs_has_inline_xattr(struct inode *inode) @@ -1165,6 +1171,17 @@ static inline void *inline_data_addr(struct page *page) return (void *)&(ri->i_addr[1]); } +static inline int f2fs_has_inline_dentry(struct inode *inode) +{ + return is_inode_flag_set(F2FS_I(inode), FI_INLINE_DENTRY); +} + +static inline void *inline_dentry_addr(struct page *page) +{ + struct f2fs_inode *ri = F2FS_INODE(page); + return (void *)&(ri->i_addr[1]); +} + static inline int f2fs_readonly(struct super_block *sb) { return sb->s_flags & MS_RDONLY; diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 6d7381b41304..63f8303b79ba 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -171,6 +171,7 @@ struct f2fs_extent { #define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ #define F2FS_INLINE_DATA 0x02 /* file inline data flag */ +#define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ #define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \ F2FS_INLINE_XATTR_ADDRS - 1)) @@ -436,6 +437,24 @@ struct f2fs_dentry_block { __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; } __packed; +/* for inline dir */ +#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + BITS_PER_BYTE + 1)) +#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + \ + BITS_PER_BYTE - 1) / BITS_PER_BYTE) +#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_INLINE_DENTRY + INLINE_DENTRY_BITMAP_SIZE)) + +/* inline directory entry structure */ +struct f2fs_inline_dentry { + __u8 dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; + __u8 reserved[INLINE_RESERVED_SIZE]; + struct f2fs_dir_entry dentry[NR_INLINE_DENTRY]; + __u8 filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; +} __packed; + /* file types used in inode_info->flags */ enum { F2FS_FT_UNKNOWN, -- GitLab From 5efd3c6f1be9cfbc621c9445cedd159998ed3ea6 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:16:13 +0800 Subject: [PATCH 2800/9457] f2fs: add a new mount option for inline dir Adds a new mount option 'inline_dentry' for inline dir. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 76b14c8c7e16..73993a9e86be 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -51,6 +51,7 @@ enum { Opt_disable_ext_identify, Opt_inline_xattr, Opt_inline_data, + Opt_inline_dentry, Opt_flush_merge, Opt_nobarrier, Opt_err, @@ -69,6 +70,7 @@ static match_table_t f2fs_tokens = { {Opt_disable_ext_identify, "disable_ext_identify"}, {Opt_inline_xattr, "inline_xattr"}, {Opt_inline_data, "inline_data"}, + {Opt_inline_dentry, "inline_dentry"}, {Opt_flush_merge, "flush_merge"}, {Opt_nobarrier, "nobarrier"}, {Opt_err, NULL}, @@ -340,6 +342,9 @@ static int parse_options(struct super_block *sb, char *options) case Opt_inline_data: set_opt(sbi, INLINE_DATA); break; + case Opt_inline_dentry: + set_opt(sbi, INLINE_DENTRY); + break; case Opt_flush_merge: set_opt(sbi, FLUSH_MERGE); break; @@ -563,6 +568,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) seq_puts(seq, ",disable_ext_identify"); if (test_opt(sbi, INLINE_DATA)) seq_puts(seq, ",inline_data"); + if (test_opt(sbi, INLINE_DENTRY)) + seq_puts(seq, ",inline_dentry"); if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE)) seq_puts(seq, ",flush_merge"); if (test_opt(sbi, NOBARRIER)) -- GitLab From dbeacf02ebfed8161ac0b9379892262593c9a734 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:17:04 +0800 Subject: [PATCH 2801/9457] f2fs: export dir operations for inline dir This patch exports some dir operations for inline dir, additionally introduces f2fs_drop_nlink from f2fs_delete_entry for reusing by inline dir function. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 71 +++++++++++++++++++++++++--------------------- fs/f2fs/f2fs.h | 10 ++++++- fs/f2fs/namei.c | 4 +-- fs/f2fs/recovery.c | 2 +- 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index b54f87149c09..99e944e1dd01 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -37,7 +37,7 @@ static unsigned int bucket_blocks(unsigned int level) return 4; } -static unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { +unsigned char f2fs_filetype_table[F2FS_FT_MAX] = { [F2FS_FT_UNKNOWN] = DT_UNKNOWN, [F2FS_FT_REG_FILE] = DT_REG, [F2FS_FT_DIR] = DT_DIR, @@ -59,7 +59,7 @@ static unsigned char f2fs_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFLNK >> S_SHIFT] = F2FS_FT_SYMLINK, }; -static void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) +void set_de_type(struct f2fs_dir_entry *de, struct inode *inode) { umode_t mode = inode->i_mode; de->file_type = f2fs_type_by_mode[(mode & S_IFMT) >> S_SHIFT]; @@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level, return bidx; } -static bool early_match_name(size_t namelen, f2fs_hash_t namehash, +bool early_match_name(size_t namelen, f2fs_hash_t namehash, struct f2fs_dir_entry *de) { if (le16_to_cpu(de->name_len) != namelen) @@ -307,7 +307,6 @@ static int make_empty_dir(struct inode *inode, if (IS_ERR(dentry_page)) return PTR_ERR(dentry_page); - dentry_blk = kmap_atomic(dentry_page); de = &dentry_blk->dentry[0]; @@ -333,7 +332,7 @@ static int make_empty_dir(struct inode *inode, return 0; } -static struct page *init_inode_metadata(struct inode *inode, +struct page *init_inode_metadata(struct inode *inode, struct inode *dir, const struct qstr *name) { struct page *page; @@ -395,7 +394,7 @@ static struct page *init_inode_metadata(struct inode *inode, return ERR_PTR(err); } -static void update_parent_metadata(struct inode *dir, struct inode *inode, +void update_parent_metadata(struct inode *dir, struct inode *inode, unsigned int current_depth) { if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { @@ -560,16 +559,44 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) return err; } +void f2fs_drop_nlink(struct inode *dir, struct inode *inode, struct page *page) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + + down_write(&F2FS_I(inode)->i_sem); + + if (S_ISDIR(inode->i_mode)) { + drop_nlink(dir); + if (page) + update_inode(dir, page); + else + update_inode_page(dir); + } + inode->i_ctime = CURRENT_TIME; + + drop_nlink(inode); + if (S_ISDIR(inode->i_mode)) { + drop_nlink(inode); + i_size_write(inode, 0); + } + up_write(&F2FS_I(inode)->i_sem); + update_inode_page(inode); + + if (inode->i_nlink == 0) + add_orphan_inode(sbi, inode->i_ino); + else + release_orphan_inode(sbi); +} + /* * It only removes the dentry from the dentry page, corresponding name * entry in name page does not need to be touched during deletion. */ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, - struct inode *inode) + struct inode *dir, struct inode *inode) { struct f2fs_dentry_block *dentry_blk; unsigned int bit_pos; - struct inode *dir = page->mapping->host; int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); int i; @@ -590,29 +617,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, dir->i_ctime = dir->i_mtime = CURRENT_TIME; - if (inode) { - struct f2fs_sb_info *sbi = F2FS_I_SB(dir); - - down_write(&F2FS_I(inode)->i_sem); - - if (S_ISDIR(inode->i_mode)) { - drop_nlink(dir); - update_inode_page(dir); - } - inode->i_ctime = CURRENT_TIME; - drop_nlink(inode); - if (S_ISDIR(inode->i_mode)) { - drop_nlink(inode); - i_size_write(inode, 0); - } - up_write(&F2FS_I(inode)->i_sem); - update_inode_page(inode); - - if (inode->i_nlink == 0) - add_orphan_inode(sbi, inode->i_ino); - else - release_orphan_inode(sbi); - } + if (inode) + f2fs_drop_nlink(dir, inode, NULL); if (bit_pos == NR_DENTRY_IN_BLOCK) { truncate_hole(dir, page->index, page->index + 1); @@ -628,7 +634,7 @@ bool f2fs_empty_dir(struct inode *dir) unsigned long bidx; struct page *dentry_page; unsigned int bit_pos; - struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_block *dentry_blk; unsigned long nblock = dir_blocks(dir); for (bidx = 0; bidx < nblock; bidx++) { @@ -640,7 +646,6 @@ bool f2fs_empty_dir(struct inode *dir) return false; } - dentry_blk = kmap_atomic(dentry_page); if (bidx == 0) bit_pos = 2; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4fa0df5f54ea..97d90ed1d67b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1242,6 +1242,13 @@ struct dentry *f2fs_get_parent(struct dentry *child); /* * dir.c */ +extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; +bool early_match_name(size_t, f2fs_hash_t, struct f2fs_dir_entry *); +void set_de_type(struct f2fs_dir_entry *, struct inode *); +struct page *init_inode_metadata(struct inode *, struct inode *, + const struct qstr *); +void update_parent_metadata(struct inode *, struct inode *, unsigned int); +void f2fs_drop_nlink(struct inode *, struct inode *, struct page *); struct f2fs_dir_entry *f2fs_find_entry(struct inode *, struct qstr *, struct page **); struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **); @@ -1250,7 +1257,8 @@ void f2fs_set_link(struct inode *, struct f2fs_dir_entry *, struct page *, struct inode *); int update_dent_inode(struct inode *, const struct qstr *); int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *); -void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *); +void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *, + struct inode *); int f2fs_do_tmpfile(struct inode *, struct inode *); int f2fs_make_empty(struct inode *, struct inode *); bool f2fs_empty_dir(struct inode *); diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 0d2526e5aa11..6e67f2b6fce1 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -223,7 +223,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) f2fs_put_page(page, 0); goto fail; } - f2fs_delete_entry(de, page, inode); + f2fs_delete_entry(de, page, dir, inode); f2fs_unlock_op(sbi); /* In order to evict this inode, we set it dirty */ @@ -435,7 +435,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, old_inode->i_ctime = CURRENT_TIME; mark_inode_dirty(old_inode); - f2fs_delete_entry(old_entry, old_page, NULL); + f2fs_delete_entry(old_entry, old_page, old_dir, NULL); if (old_dir_entry) { if (old_dir != new_dir) { diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index ebd013225788..843da53ed7d5 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -111,7 +111,7 @@ static int recover_dentry(struct inode *inode, struct page *ipage) iput(einode); goto out_unmap_put; } - f2fs_delete_entry(de, page, einode); + f2fs_delete_entry(de, page, dir, einode); iput(einode); goto retry; } -- GitLab From 201a05be9628ae58efe7638e0c7ae3937ec85273 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:17:53 +0800 Subject: [PATCH 2802/9457] f2fs: add key function to handle inline dir Adds Functions to implement inline dir init/lookup/insert/delete/convert ops. Signed-off-by: Chao Yu [Jaegeuk Kim: remove needless reserved area copy, pointed by Dan Carpenter] Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 9 ++ fs/f2fs/inline.c | 346 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 97d90ed1d67b..c537699d0182 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1551,4 +1551,13 @@ int f2fs_convert_inline_data(struct inode *, pgoff_t, struct page *); int f2fs_write_inline_data(struct inode *, struct page *, unsigned int); void truncate_inline_data(struct inode *, u64); bool recover_inline_data(struct inode *, struct page *); +struct f2fs_dir_entry *find_in_inline_dir(struct inode *, struct qstr *, + struct page **); +struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *, struct page **); +int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *); +int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *); +void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *, + struct inode *, struct inode *); +bool f2fs_empty_inline_dir(struct inode *); +int f2fs_read_inline_dir(struct file *, struct dir_context *); #endif diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index e3abcfb54374..b3be96ba585c 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -258,3 +258,349 @@ bool recover_inline_data(struct inode *inode, struct page *npage) } return false; } + +struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, + struct qstr *name, struct page **res_page) +{ + struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct page *ipage; + struct f2fs_dir_entry *de; + f2fs_hash_t namehash; + unsigned long bit_pos = 0; + struct f2fs_inline_dentry *dentry_blk; + const void *dentry_bits; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return NULL; + + namehash = f2fs_dentry_hash(name); + + dentry_blk = inline_data_addr(ipage); + dentry_bits = &dentry_blk->dentry_bitmap; + + while (bit_pos < NR_INLINE_DENTRY) { + if (!test_bit_le(bit_pos, dentry_bits)) { + bit_pos++; + continue; + } + de = &dentry_blk->dentry[bit_pos]; + if (early_match_name(name->len, namehash, de)) { + if (!memcmp(dentry_blk->filename[bit_pos], + name->name, + name->len)) { + *res_page = ipage; + goto found; + } + } + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs are occurred. + */ + f2fs_bug_on(F2FS_P_SB(ipage), !de->name_len); + + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); + } + + de = NULL; +found: + unlock_page(ipage); + return de; +} + +struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir, + struct page **p) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + struct f2fs_dir_entry *de; + struct f2fs_inline_dentry *dentry_blk; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return NULL; + + dentry_blk = inline_data_addr(ipage); + de = &dentry_blk->dentry[1]; + *p = ipage; + unlock_page(ipage); + return de; +} + +int make_empty_inline_dir(struct inode *inode, struct inode *parent, + struct page *ipage) +{ + struct f2fs_inline_dentry *dentry_blk; + struct f2fs_dir_entry *de; + + dentry_blk = inline_data_addr(ipage); + + de = &dentry_blk->dentry[0]; + de->name_len = cpu_to_le16(1); + de->hash_code = 0; + de->ino = cpu_to_le32(inode->i_ino); + memcpy(dentry_blk->filename[0], ".", 1); + set_de_type(de, inode); + + de = &dentry_blk->dentry[1]; + de->hash_code = 0; + de->name_len = cpu_to_le16(2); + de->ino = cpu_to_le32(parent->i_ino); + memcpy(dentry_blk->filename[1], "..", 2); + set_de_type(de, inode); + + test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); + test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); + + set_page_dirty(ipage); + + /* update i_size to MAX_INLINE_DATA */ + if (i_size_read(inode) < MAX_INLINE_DATA) { + i_size_write(inode, MAX_INLINE_DATA); + set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); + } + return 0; +} + +int room_in_inline_dir(struct f2fs_inline_dentry *dentry_blk, int slots) +{ + int bit_start = 0; + int zero_start, zero_end; +next: + zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, + NR_INLINE_DENTRY, + bit_start); + if (zero_start >= NR_INLINE_DENTRY) + return NR_INLINE_DENTRY; + + zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, + NR_INLINE_DENTRY, + zero_start); + if (zero_end - zero_start >= slots) + return zero_start; + + bit_start = zero_end + 1; + + if (zero_end + 1 >= NR_INLINE_DENTRY) + return NR_INLINE_DENTRY; + goto next; +} + +int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, + struct f2fs_inline_dentry *inline_dentry) +{ + struct page *page; + struct dnode_of_data dn; + struct f2fs_dentry_block *dentry_blk; + int err; + + page = grab_cache_page(dir->i_mapping, 0); + if (!page) + return -ENOMEM; + + set_new_dnode(&dn, dir, ipage, NULL, 0); + err = f2fs_reserve_block(&dn, 0); + if (err) + goto out; + + f2fs_wait_on_page_writeback(page, DATA); + zero_user_segment(page, 0, PAGE_CACHE_SIZE); + + dentry_blk = kmap(page); + + /* copy data from inline dentry block to new dentry block */ + memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, + INLINE_DENTRY_BITMAP_SIZE); + memcpy(dentry_blk->dentry, inline_dentry->dentry, + sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY); + memcpy(dentry_blk->filename, inline_dentry->filename, + NR_INLINE_DENTRY * F2FS_SLOT_LEN); + + kunmap(page); + SetPageUptodate(page); + set_page_dirty(page); + + /* clear inline dir and flag after data writeback */ + zero_user_segment(ipage, INLINE_DATA_OFFSET, + INLINE_DATA_OFFSET + MAX_INLINE_DATA); + + stat_dec_inline_inode(dir); + + if (i_size_read(dir) < PAGE_CACHE_SIZE) { + i_size_write(dir, PAGE_CACHE_SIZE); + set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); + } + + sync_inode_page(&dn); +out: + f2fs_put_page(page, 1); + return err; +} + +int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, + struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + unsigned int bit_pos; + f2fs_hash_t name_hash; + struct f2fs_dir_entry *de; + size_t namelen = name->len; + struct f2fs_inline_dentry *dentry_blk = NULL; + int slots = GET_DENTRY_SLOTS(namelen); + struct page *page; + int err = 0; + int i; + + name_hash = f2fs_dentry_hash(name); + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return PTR_ERR(ipage); + + dentry_blk = inline_data_addr(ipage); + bit_pos = room_in_inline_dir(dentry_blk, slots); + if (bit_pos >= NR_INLINE_DENTRY) { + err = f2fs_convert_inline_dir(dir, ipage, dentry_blk); + if (!err) + err = -EAGAIN; + goto out; + } + + f2fs_wait_on_page_writeback(ipage, DATA); + + down_write(&F2FS_I(inode)->i_sem); + page = init_inode_metadata(inode, dir, name); + if (IS_ERR(page)) { + err = PTR_ERR(page); + goto fail; + } + de = &dentry_blk->dentry[bit_pos]; + de->hash_code = name_hash; + de->name_len = cpu_to_le16(namelen); + memcpy(dentry_blk->filename[bit_pos], name->name, name->len); + de->ino = cpu_to_le32(inode->i_ino); + set_de_type(de, inode); + for (i = 0; i < slots; i++) + test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); + set_page_dirty(ipage); + + /* we don't need to mark_inode_dirty now */ + F2FS_I(inode)->i_pino = dir->i_ino; + update_inode(inode, page); + f2fs_put_page(page, 1); + + update_parent_metadata(dir, inode, 0); +fail: + up_write(&F2FS_I(inode)->i_sem); + + if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR)) { + update_inode(dir, ipage); + clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR); + } +out: + f2fs_put_page(ipage, 1); + return err; +} + +void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, + struct inode *dir, struct inode *inode) +{ + struct f2fs_inline_dentry *inline_dentry; + int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); + unsigned int bit_pos; + int i; + + lock_page(page); + f2fs_wait_on_page_writeback(page, DATA); + + inline_dentry = inline_data_addr(page); + bit_pos = dentry - inline_dentry->dentry; + for (i = 0; i < slots; i++) + test_and_clear_bit_le(bit_pos + i, + &inline_dentry->dentry_bitmap); + + set_page_dirty(page); + + dir->i_ctime = dir->i_mtime = CURRENT_TIME; + + if (inode) + f2fs_drop_nlink(dir, inode, page); + + f2fs_put_page(page, 1); +} + +bool f2fs_empty_inline_dir(struct inode *dir) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct page *ipage; + unsigned int bit_pos = 2; + struct f2fs_inline_dentry *dentry_blk; + + ipage = get_node_page(sbi, dir->i_ino); + if (IS_ERR(ipage)) + return false; + + dentry_blk = inline_data_addr(ipage); + bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, + NR_INLINE_DENTRY, + bit_pos); + + f2fs_put_page(ipage, 1); + + if (bit_pos < NR_INLINE_DENTRY) + return false; + + return true; +} + +int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) +{ + struct inode *inode = file_inode(file); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + unsigned int bit_pos = 0; + struct f2fs_inline_dentry *inline_dentry = NULL; + struct f2fs_dir_entry *de = NULL; + struct page *ipage = NULL; + unsigned char d_type = DT_UNKNOWN; + + if (ctx->pos == NR_INLINE_DENTRY) + return 0; + + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) + return PTR_ERR(ipage); + + bit_pos = ((unsigned long)ctx->pos % NR_INLINE_DENTRY); + + inline_dentry = inline_data_addr(ipage); + while (bit_pos < NR_INLINE_DENTRY) { + bit_pos = find_next_bit_le(&inline_dentry->dentry_bitmap, + NR_INLINE_DENTRY, + bit_pos); + if (bit_pos >= NR_INLINE_DENTRY) + break; + + de = &inline_dentry->dentry[bit_pos]; + if (de->file_type < F2FS_FT_MAX) + d_type = f2fs_filetype_table[de->file_type]; + else + d_type = DT_UNKNOWN; + + if (!dir_emit(ctx, + inline_dentry->filename[bit_pos], + le16_to_cpu(de->name_len), + le32_to_cpu(de->ino), d_type)) + goto out; + + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); + ctx->pos = bit_pos; + } + + ctx->pos = NR_INLINE_DENTRY; +out: + f2fs_put_page(ipage, 1); + + return 0; +} -- GitLab From 622f28ae9ba4fa89b4ff0f4a6cf75d153ea838ce Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:19:10 +0800 Subject: [PATCH 2803/9457] f2fs: enable inline dir handling Add inline dir functions into normal dir ops' function to handle inline ops. Besides, we enable inline dir mode when a new dir inode is created if inline_data option is on. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 32 ++++++++++++++++++++++++++++++-- fs/f2fs/file.c | 2 +- fs/f2fs/inline.c | 2 +- fs/f2fs/namei.c | 34 ++++++++++++++++++++++++---------- fs/f2fs/recovery.c | 3 ++- 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 99e944e1dd01..cc6474a85d6c 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -201,6 +201,9 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, unsigned int max_depth; unsigned int level; + if (f2fs_has_inline_dentry(dir)) + return find_in_inline_dir(dir, child, res_page); + if (npages == 0) return NULL; @@ -227,6 +230,9 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) struct f2fs_dir_entry *de; struct f2fs_dentry_block *dentry_blk; + if (f2fs_has_inline_dentry(dir)) + return f2fs_parent_inline_dir(dir, p); + page = get_lock_data_page(dir, 0); if (IS_ERR(page)) return NULL; @@ -247,7 +253,8 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) de = f2fs_find_entry(dir, qstr, &page); if (de) { res = le32_to_cpu(de->ino); - kunmap(page); + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); f2fs_put_page(page, 0); } @@ -261,7 +268,8 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, f2fs_wait_on_page_writeback(page, DATA); de->ino = cpu_to_le32(inode->i_ino); set_de_type(de, inode); - kunmap(page); + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); set_page_dirty(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME; mark_inode_dirty(dir); @@ -303,6 +311,9 @@ static int make_empty_dir(struct inode *inode, struct f2fs_dentry_block *dentry_blk; struct f2fs_dir_entry *de; + if (f2fs_has_inline_dentry(inode)) + return make_empty_inline_dir(inode, parent, page); + dentry_page = get_new_data_page(inode, page, 0, true); if (IS_ERR(dentry_page)) return PTR_ERR(dentry_page); @@ -462,6 +473,14 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, int err = 0; int i; + if (f2fs_has_inline_dentry(dir)) { + err = f2fs_add_inline_entry(dir, name, inode); + if (!err || err != -EAGAIN) + return err; + else + err = 0; + } + dentry_hash = f2fs_dentry_hash(name); level = 0; current_depth = F2FS_I(dir)->i_current_depth; @@ -600,6 +619,9 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len)); int i; + if (f2fs_has_inline_dentry(dir)) + return f2fs_delete_inline_entry(dentry, page, dir, inode); + lock_page(page); f2fs_wait_on_page_writeback(page, DATA); @@ -637,6 +659,9 @@ bool f2fs_empty_dir(struct inode *dir) struct f2fs_dentry_block *dentry_blk; unsigned long nblock = dir_blocks(dir); + if (f2fs_has_inline_dentry(dir)) + return f2fs_empty_inline_dir(dir); + for (bidx = 0; bidx < nblock; bidx++) { dentry_page = get_lock_data_page(dir, bidx); if (IS_ERR(dentry_page)) { @@ -676,6 +701,9 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); unsigned char d_type = DT_UNKNOWN; + if (f2fs_has_inline_dentry(inode)) + return f2fs_read_inline_dir(file, ctx); + bit_pos = ((unsigned long)ctx->pos % NR_DENTRY_IN_BLOCK); /* readahead for multi pages of dir */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 80d9a0482e7d..d054e0ebfe24 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -314,7 +314,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) goto fail; /* handle inline data case */ - if (f2fs_has_inline_data(inode)) { + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) { if (whence == SEEK_HOLE) data_ofs = isize; goto found; diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index b3be96ba585c..1fafc8561542 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -424,7 +424,7 @@ int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, /* clear inline dir and flag after data writeback */ zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); - + clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); stat_dec_inline_inode(dir); if (i_size_read(dir) < PAGE_CACHE_SIZE) { diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 6e67f2b6fce1..c8290da8e941 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -54,6 +54,10 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode) nid_free = true; goto out; } + + if (test_opt(sbi, INLINE_DENTRY) && S_ISDIR(inode->i_mode)) + set_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); + trace_f2fs_new_inode(inode, 0); mark_inode_dirty(inode); return inode; @@ -187,7 +191,8 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, de = f2fs_find_entry(dir, &dentry->d_name, &page); if (de) { nid_t ino = le32_to_cpu(de->ino); - kunmap(page); + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); f2fs_put_page(page, 0); inode = f2fs_iget(dir->i_sb, ino); @@ -219,7 +224,8 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) err = acquire_orphan_inode(sbi); if (err) { f2fs_unlock_op(sbi); - kunmap(page); + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); f2fs_put_page(page, 0); goto fail; } @@ -443,7 +449,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, old_dir_page, new_dir); update_inode_page(old_inode); } else { - kunmap(old_dir_page); + if (!f2fs_has_inline_dentry(old_inode)) + kunmap(old_dir_page); f2fs_put_page(old_dir_page, 0); } drop_nlink(old_dir); @@ -456,15 +463,18 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, put_out_dir: f2fs_unlock_op(sbi); - kunmap(new_page); + if (!f2fs_has_inline_dentry(new_dir)) + kunmap(new_page); f2fs_put_page(new_page, 0); out_dir: if (old_dir_entry) { - kunmap(old_dir_page); + if (!f2fs_has_inline_dentry(old_inode)) + kunmap(old_dir_page); f2fs_put_page(old_dir_page, 0); } out_old: - kunmap(old_page); + if (!f2fs_has_inline_dentry(old_dir)) + kunmap(old_page); f2fs_put_page(old_page, 0); out: return err; @@ -596,19 +606,23 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, f2fs_unlock_op(sbi); out_new_dir: if (new_dir_entry) { - kunmap(new_dir_page); + if (!f2fs_has_inline_dentry(new_inode)) + kunmap(new_dir_page); f2fs_put_page(new_dir_page, 0); } out_old_dir: if (old_dir_entry) { - kunmap(old_dir_page); + if (!f2fs_has_inline_dentry(old_inode)) + kunmap(old_dir_page); f2fs_put_page(old_dir_page, 0); } out_new: - kunmap(new_page); + if (!f2fs_has_inline_dentry(new_dir)) + kunmap(new_page); f2fs_put_page(new_page, 0); out_old: - kunmap(old_page); + if (!f2fs_has_inline_dentry(old_dir)) + kunmap(old_page); f2fs_put_page(old_page, 0); out: return err; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 843da53ed7d5..4b180bbc3a21 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -129,7 +129,8 @@ static int recover_dentry(struct inode *inode, struct page *ipage) goto out; out_unmap_put: - kunmap(page); + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); f2fs_put_page(page, 0); out_err: iput(dir); -- GitLab From d37a868ffca325509af87f59c142d9dc717772bd Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 24 Sep 2014 18:20:23 +0800 Subject: [PATCH 2804/9457] f2fs: update f2fs documentation for inline dir support This patch adds descriptions for the inline dir support in f2fs document. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 2cca5a25ef89..4bb9f278c031 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -122,6 +122,10 @@ disable_ext_identify Disable the extension list configured by mkfs, so f2fs inline_xattr Enable the inline xattrs feature. inline_data Enable the inline data feature: New created small(<~3.4k) files can be written into inode block. +inline_dentry Enable the inline dir feature: data in new created + directory entries can be written into inode block. The + space of inode block which is used to store inline + dentries is limited to ~3.4k. flush_merge Merge concurrent cache_flush commands as much as possible to eliminate redundant command issues. If the underlying device handles the cache_flush command relatively slowly, -- GitLab From a82afa20197a2ed289dd8fd18208a9e8b9af0130 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Oct 2014 16:28:13 -0700 Subject: [PATCH 2805/9457] f2fs: reuse room_for_filename for inline dentry operation This patch introduces to reuse the existing room_for_filename for inline dentry operation. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 21 +++++++++------------ fs/f2fs/f2fs.h | 1 + fs/f2fs/inline.c | 27 ++------------------------- 3 files changed, 12 insertions(+), 37 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index cc6474a85d6c..164c6c911bf8 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -427,27 +427,23 @@ void update_parent_metadata(struct inode *dir, struct inode *inode, clear_inode_flag(F2FS_I(inode), FI_INC_LINK); } -static int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) +int room_for_filename(const void *bitmap, int slots, int max_slots) { int bit_start = 0; int zero_start, zero_end; next: - zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - bit_start); - if (zero_start >= NR_DENTRY_IN_BLOCK) - return NR_DENTRY_IN_BLOCK; + zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start); + if (zero_start >= max_slots) + return max_slots; - zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - zero_start); + zero_end = find_next_bit_le(bitmap, max_slots, zero_start); if (zero_end - zero_start >= slots) return zero_start; bit_start = zero_end + 1; - if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) - return NR_DENTRY_IN_BLOCK; + if (zero_end + 1 >= max_slots) + return max_slots; goto next; } @@ -509,7 +505,8 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, return PTR_ERR(dentry_page); dentry_blk = kmap(dentry_page); - bit_pos = room_for_filename(dentry_blk, slots); + bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, + slots, NR_DENTRY_IN_BLOCK); if (bit_pos < NR_DENTRY_IN_BLOCK) goto add_dentry; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c537699d0182..aa055e3fbd67 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1248,6 +1248,7 @@ void set_de_type(struct f2fs_dir_entry *, struct inode *); struct page *init_inode_metadata(struct inode *, struct inode *, const struct qstr *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); +int room_for_filename(const void *, int, int); void f2fs_drop_nlink(struct inode *, struct inode *, struct page *); struct f2fs_dir_entry *f2fs_find_entry(struct inode *, struct qstr *, struct page **); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 1fafc8561542..29090b34c768 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -363,30 +363,6 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent, return 0; } -int room_in_inline_dir(struct f2fs_inline_dentry *dentry_blk, int slots) -{ - int bit_start = 0; - int zero_start, zero_end; -next: - zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, - NR_INLINE_DENTRY, - bit_start); - if (zero_start >= NR_INLINE_DENTRY) - return NR_INLINE_DENTRY; - - zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_INLINE_DENTRY, - zero_start); - if (zero_end - zero_start >= slots) - return zero_start; - - bit_start = zero_end + 1; - - if (zero_end + 1 >= NR_INLINE_DENTRY) - return NR_INLINE_DENTRY; - goto next; -} - int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, struct f2fs_inline_dentry *inline_dentry) { @@ -460,7 +436,8 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, return PTR_ERR(ipage); dentry_blk = inline_data_addr(ipage); - bit_pos = room_in_inline_dir(dentry_blk, slots); + bit_pos = room_for_filename(&dentry_blk->dentry_bitmap, + slots, NR_INLINE_DENTRY); if (bit_pos >= NR_INLINE_DENTRY) { err = f2fs_convert_inline_dir(dir, ipage, dentry_blk); if (!err) -- GitLab From 4e6ebf6d493591403237400e94e6fc17b7cb1c62 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Oct 2014 17:26:14 -0700 Subject: [PATCH 2806/9457] f2fs: reuse find_in_block code for find_in_inline_dir This patch removes redundant copied code in find_in_inline_dir. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 73 ++++++++++++++++++++++++++++++------------------ fs/f2fs/f2fs.h | 3 +- fs/f2fs/inline.c | 52 +++++++++++----------------------- 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 164c6c911bf8..0b97b1921504 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level, return bidx; } -bool early_match_name(size_t namelen, f2fs_hash_t namehash, +static bool early_match_name(size_t namelen, f2fs_hash_t namehash, struct f2fs_dir_entry *de) { if (le16_to_cpu(de->name_len) != namelen) @@ -90,49 +90,69 @@ bool early_match_name(size_t namelen, f2fs_hash_t namehash, } static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, - struct qstr *name, int *max_slots, - f2fs_hash_t namehash, struct page **res_page) + struct qstr *name, int *max_slots, + struct page **res_page) +{ + struct f2fs_dentry_block *dentry_blk; + struct f2fs_dir_entry *de; + + *max_slots = NR_DENTRY_IN_BLOCK; + + dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page); + de = find_target_dentry(name, max_slots, &dentry_blk->dentry_bitmap, + dentry_blk->dentry, + dentry_blk->filename); + if (de) + *res_page = dentry_page; + else + kunmap(dentry_page); + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs has occurred. + */ + f2fs_bug_on(F2FS_P_SB(dentry_page), *max_slots < 0); + return de; +} + +struct f2fs_dir_entry *find_target_dentry(struct qstr *name, int *max_slots, + const void *bitmap, struct f2fs_dir_entry *dentry, + __u8 (*filenames)[F2FS_SLOT_LEN]) { struct f2fs_dir_entry *de; unsigned long bit_pos = 0; - struct f2fs_dentry_block *dentry_blk = kmap(dentry_page); - const void *dentry_bits = &dentry_blk->dentry_bitmap; + f2fs_hash_t namehash = f2fs_dentry_hash(name); + int max_bits = *max_slots; int max_len = 0; - while (bit_pos < NR_DENTRY_IN_BLOCK) { - if (!test_bit_le(bit_pos, dentry_bits)) { + *max_slots = 0; + while (bit_pos < max_bits) { + if (!test_bit_le(bit_pos, bitmap)) { if (bit_pos == 0) max_len = 1; - else if (!test_bit_le(bit_pos - 1, dentry_bits)) + else if (!test_bit_le(bit_pos - 1, bitmap)) max_len++; bit_pos++; continue; } - de = &dentry_blk->dentry[bit_pos]; - if (early_match_name(name->len, namehash, de)) { - if (!memcmp(dentry_blk->filename[bit_pos], - name->name, - name->len)) { - *res_page = dentry_page; - goto found; - } - } - if (max_len > *max_slots) { + de = &dentry[bit_pos]; + if (early_match_name(name->len, namehash, de) && + !memcmp(filenames[bit_pos], name->name, name->len)) + goto found; + + if (*max_slots >= 0 && max_len > *max_slots) { *max_slots = max_len; max_len = 0; } - /* - * For the most part, it should be a bug when name_len is zero. - * We stop here for figuring out where the bugs has occurred. - */ - f2fs_bug_on(F2FS_P_SB(dentry_page), !de->name_len); + /* remain bug on condition */ + if (unlikely(!de->name_len)) + *max_slots = -1; bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); } de = NULL; - kunmap(dentry_page); found: if (max_len > *max_slots) *max_slots = max_len; @@ -149,7 +169,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, struct page *dentry_page; struct f2fs_dir_entry *de = NULL; bool room = false; - int max_slots = 0; + int max_slots; f2fs_bug_on(F2FS_I_SB(dir), level > MAX_DIR_HASH_DEPTH); @@ -168,8 +188,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, continue; } - de = find_in_block(dentry_page, name, &max_slots, - namehash, res_page); + de = find_in_block(dentry_page, name, &max_slots, res_page); if (de) break; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index aa055e3fbd67..6aad6e03d621 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1243,8 +1243,9 @@ struct dentry *f2fs_get_parent(struct dentry *child); * dir.c */ extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; -bool early_match_name(size_t, f2fs_hash_t, struct f2fs_dir_entry *); void set_de_type(struct f2fs_dir_entry *, struct inode *); +struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, const void *, + struct f2fs_dir_entry *, __u8 (*)[F2FS_SLOT_LEN]); struct page *init_inode_metadata(struct inode *, struct inode *, const struct qstr *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 29090b34c768..4cdce00ed537 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -263,49 +263,31 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, struct qstr *name, struct page **res_page) { struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); - struct page *ipage; + struct f2fs_inline_dentry *inline_dentry; struct f2fs_dir_entry *de; - f2fs_hash_t namehash; - unsigned long bit_pos = 0; - struct f2fs_inline_dentry *dentry_blk; - const void *dentry_bits; + struct page *ipage; + int max_slots = NR_INLINE_DENTRY; ipage = get_node_page(sbi, dir->i_ino); if (IS_ERR(ipage)) return NULL; - namehash = f2fs_dentry_hash(name); - - dentry_blk = inline_data_addr(ipage); - dentry_bits = &dentry_blk->dentry_bitmap; - - while (bit_pos < NR_INLINE_DENTRY) { - if (!test_bit_le(bit_pos, dentry_bits)) { - bit_pos++; - continue; - } - de = &dentry_blk->dentry[bit_pos]; - if (early_match_name(name->len, namehash, de)) { - if (!memcmp(dentry_blk->filename[bit_pos], - name->name, - name->len)) { - *res_page = ipage; - goto found; - } - } - - /* - * For the most part, it should be a bug when name_len is zero. - * We stop here for figuring out where the bugs are occurred. - */ - f2fs_bug_on(F2FS_P_SB(ipage), !de->name_len); - - bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - } + inline_dentry = inline_data_addr(ipage); - de = NULL; -found: + de = find_target_dentry(name, &max_slots, &inline_dentry->dentry_bitmap, + inline_dentry->dentry, + inline_dentry->filename); unlock_page(ipage); + if (de) + *res_page = ipage; + else + f2fs_put_page(ipage, 0); + + /* + * For the most part, it should be a bug when name_len is zero. + * We stop here for figuring out where the bugs has occurred. + */ + f2fs_bug_on(sbi, max_slots < 0); return de; } -- GitLab From 59a0615540812297e4ff9673de5c1269413d0c40 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Oct 2014 19:34:26 -0700 Subject: [PATCH 2807/9457] f2fs: fix to wait correct block type The inode page needs to wait NODE block io. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 3 ++- fs/f2fs/inline.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 0b97b1921504..35cb1b3d94b9 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -283,8 +283,9 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, struct page *page, struct inode *inode) { + enum page_type type = f2fs_has_inline_dentry(dir) ? NODE : DATA; lock_page(page); - f2fs_wait_on_page_writeback(page, DATA); + f2fs_wait_on_page_writeback(page, type); de->ino = cpu_to_le32(inode->i_ino); set_de_type(de, inode); if (!f2fs_has_inline_dentry(dir)) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 4cdce00ed537..175f38a96700 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -427,7 +427,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, goto out; } - f2fs_wait_on_page_writeback(ipage, DATA); + f2fs_wait_on_page_writeback(ipage, NODE); down_write(&F2FS_I(inode)->i_sem); page = init_inode_metadata(inode, dir, name); @@ -472,7 +472,7 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *dentry, struct page *page, int i; lock_page(page); - f2fs_wait_on_page_writeback(page, DATA); + f2fs_wait_on_page_writeback(page, NODE); inline_dentry = inline_data_addr(page); bit_pos = dentry - inline_dentry->dentry; -- GitLab From bce8d1120707c06088928b2ee52a58703d74ac29 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Oct 2014 19:42:53 -0700 Subject: [PATCH 2808/9457] f2fs: avoid deadlock on init_inode_metadata Previously, init_inode_metadata does not hold any parent directory's inode page. So, f2fs_init_acl can grab its parent inode page without any problem. But, when we use inline_dentry, that page is grabbed during f2fs_add_link, so that we can fall into deadlock condition like below. INFO: task mknod:11006 blocked for more than 120 seconds. Tainted: G OE 3.17.0-rc1+ #13 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. mknod D ffff88003fc94580 0 11006 11004 0x00000000 ffff880007717b10 0000000000000002 ffff88003c323220 ffff880007717fd8 0000000000014580 0000000000014580 ffff88003daecb30 ffff88003c323220 ffff88003fc94e80 ffff88003ffbb4e8 ffff880007717ba0 0000000000000002 Call Trace: [] ? bit_wait+0x50/0x50 [] io_schedule+0x9d/0x130 [] bit_wait_io+0x2c/0x50 [] __wait_on_bit_lock+0x4b/0xb0 [] __lock_page+0x67/0x70 [] ? autoremove_wake_function+0x40/0x40 [] pagecache_get_page+0x14c/0x1e0 [] get_node_page+0x59/0x130 [f2fs] [] read_all_xattrs+0x24d/0x430 [f2fs] [] f2fs_getxattr+0x52/0xe0 [f2fs] [] f2fs_get_acl+0x41/0x2d0 [f2fs] [] get_acl+0x47/0x70 [] posix_acl_create+0x5a/0x150 [] f2fs_init_acl+0x29/0xcb [f2fs] [] init_inode_metadata+0x5d/0x340 [f2fs] [] f2fs_add_inline_entry+0x12a/0x2e0 [f2fs] [] __f2fs_add_link+0x45/0x4a0 [f2fs] [] ? f2fs_new_inode+0x146/0x220 [f2fs] [] f2fs_mknod+0x86/0xf0 [f2fs] [] vfs_mknod+0xe1/0x160 [] SyS_mknod+0x1f6/0x200 [] tracesys+0xe1/0xe6 Signed-off-by: Jaegeuk Kim --- fs/f2fs/acl.c | 144 +++++++++++++++++++++++++++++++++++++++++++++-- fs/f2fs/acl.h | 5 +- fs/f2fs/dir.c | 10 ++-- fs/f2fs/f2fs.h | 2 +- fs/f2fs/inline.c | 6 +- fs/f2fs/xattr.c | 6 +- fs/f2fs/xattr.h | 6 +- 7 files changed, 157 insertions(+), 22 deletions(-) diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 83b9b5a8d112..620745556828 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -162,7 +162,8 @@ static void *f2fs_acl_to_disk(const struct posix_acl *acl, size_t *size) return ERR_PTR(-EINVAL); } -struct posix_acl *f2fs_get_acl(struct inode *inode, int type) +static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type, + struct page *dpage) { int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT; void *value = NULL; @@ -172,12 +173,13 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) if (type == ACL_TYPE_ACCESS) name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; - retval = f2fs_getxattr(inode, name_index, "", NULL, 0); + retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage); if (retval > 0) { value = kmalloc(retval, GFP_F2FS_ZERO); if (!value) return ERR_PTR(-ENOMEM); - retval = f2fs_getxattr(inode, name_index, "", value, retval); + retval = f2fs_getxattr(inode, name_index, "", value, + retval, dpage); } if (retval > 0) @@ -194,6 +196,11 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) return acl; } +struct posix_acl *f2fs_get_acl(struct inode *inode, int type) +{ + return __f2fs_get_acl(inode, type, NULL); +} + static int __f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl, struct page *ipage) { @@ -249,12 +256,137 @@ int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type) return __f2fs_set_acl(inode, type, acl, NULL); } -int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage) +/* + * Most part of f2fs_acl_clone, f2fs_acl_create_masq, f2fs_acl_create + * are copied from posix_acl.c + */ +static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, + gfp_t flags) +{ + struct posix_acl *clone = NULL; + + if (acl) { + int size = sizeof(struct posix_acl) + acl->a_count * + sizeof(struct posix_acl_entry); + clone = kmemdup(acl, size, flags); + if (clone) + atomic_set(&clone->a_refcount, 1); + } + return clone; +} + +static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) +{ + struct posix_acl_entry *pa, *pe; + struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; + umode_t mode = *mode_p; + int not_equiv = 0; + + /* assert(atomic_read(acl->a_refcount) == 1); */ + + FOREACH_ACL_ENTRY(pa, acl, pe) { + switch(pa->e_tag) { + case ACL_USER_OBJ: + pa->e_perm &= (mode >> 6) | ~S_IRWXO; + mode &= (pa->e_perm << 6) | ~S_IRWXU; + break; + + case ACL_USER: + case ACL_GROUP: + not_equiv = 1; + break; + + case ACL_GROUP_OBJ: + group_obj = pa; + break; + + case ACL_OTHER: + pa->e_perm &= mode | ~S_IRWXO; + mode &= pa->e_perm | ~S_IRWXO; + break; + + case ACL_MASK: + mask_obj = pa; + not_equiv = 1; + break; + + default: + return -EIO; + } + } + + if (mask_obj) { + mask_obj->e_perm &= (mode >> 3) | ~S_IRWXO; + mode &= (mask_obj->e_perm << 3) | ~S_IRWXG; + } else { + if (!group_obj) + return -EIO; + group_obj->e_perm &= (mode >> 3) | ~S_IRWXO; + mode &= (group_obj->e_perm << 3) | ~S_IRWXG; + } + + *mode_p = (*mode_p & ~S_IRWXUGO) | mode; + return not_equiv; +} + +static int f2fs_acl_create(struct inode *dir, umode_t *mode, + struct posix_acl **default_acl, struct posix_acl **acl, + struct page *dpage) +{ + struct posix_acl *p; + int ret; + + if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) + goto no_acl; + + p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); + if (IS_ERR(p)) { + if (p == ERR_PTR(-EOPNOTSUPP)) + goto apply_umask; + return PTR_ERR(p); + } + + if (!p) + goto apply_umask; + + *acl = f2fs_acl_clone(p, GFP_NOFS); + if (!*acl) + return -ENOMEM; + + ret = f2fs_acl_create_masq(*acl, mode); + if (ret < 0) { + posix_acl_release(*acl); + return -ENOMEM; + } + + if (ret == 0) { + posix_acl_release(*acl); + *acl = NULL; + } + + if (!S_ISDIR(*mode)) { + posix_acl_release(p); + *default_acl = NULL; + } else { + *default_acl = p; + } + return 0; + +apply_umask: + *mode &= ~current_umask(); +no_acl: + *default_acl = NULL; + *acl = NULL; + return 0; +} + +int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage, + struct page *dpage) { - struct posix_acl *default_acl, *acl; + struct posix_acl *default_acl = NULL, *acl = NULL; int error = 0; - error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); + error = f2fs_acl_create(dir, &inode->i_mode, &default_acl, &acl, dpage); if (error) return error; diff --git a/fs/f2fs/acl.h b/fs/f2fs/acl.h index e0864651cdc1..997ca8edb6cb 100644 --- a/fs/f2fs/acl.h +++ b/fs/f2fs/acl.h @@ -38,14 +38,15 @@ struct f2fs_acl_header { extern struct posix_acl *f2fs_get_acl(struct inode *, int); extern int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -extern int f2fs_init_acl(struct inode *, struct inode *, struct page *); +extern int f2fs_init_acl(struct inode *, struct inode *, struct page *, + struct page *); #else #define f2fs_check_acl NULL #define f2fs_get_acl NULL #define f2fs_set_acl NULL static inline int f2fs_init_acl(struct inode *inode, struct inode *dir, - struct page *page) + struct page *ipage, struct page *dpage) { return 0; } diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 35cb1b3d94b9..e5439dd67f4e 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -363,8 +363,8 @@ static int make_empty_dir(struct inode *inode, return 0; } -struct page *init_inode_metadata(struct inode *inode, - struct inode *dir, const struct qstr *name) +struct page *init_inode_metadata(struct inode *inode, struct inode *dir, + const struct qstr *name, struct page *dpage) { struct page *page; int err; @@ -380,7 +380,7 @@ struct page *init_inode_metadata(struct inode *inode, goto error; } - err = f2fs_init_acl(inode, dir, page); + err = f2fs_init_acl(inode, dir, page, dpage); if (err) goto put_error; @@ -541,7 +541,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, f2fs_wait_on_page_writeback(dentry_page, DATA); down_write(&F2FS_I(inode)->i_sem); - page = init_inode_metadata(inode, dir, name); + page = init_inode_metadata(inode, dir, name, NULL); if (IS_ERR(page)) { err = PTR_ERR(page); goto fail; @@ -580,7 +580,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) int err = 0; down_write(&F2FS_I(inode)->i_sem); - page = init_inode_metadata(inode, dir, NULL); + page = init_inode_metadata(inode, dir, NULL, NULL); if (IS_ERR(page)) { err = PTR_ERR(page); goto fail; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6aad6e03d621..d4dcd934756e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1247,7 +1247,7 @@ void set_de_type(struct f2fs_dir_entry *, struct inode *); struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, const void *, struct f2fs_dir_entry *, __u8 (*)[F2FS_SLOT_LEN]); struct page *init_inode_metadata(struct inode *, struct inode *, - const struct qstr *); + const struct qstr *, struct page *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); int room_for_filename(const void *, int, int); void f2fs_drop_nlink(struct inode *, struct inode *, struct page *); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 175f38a96700..46c554224276 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -427,14 +427,14 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name, goto out; } - f2fs_wait_on_page_writeback(ipage, NODE); - down_write(&F2FS_I(inode)->i_sem); - page = init_inode_metadata(inode, dir, name); + page = init_inode_metadata(inode, dir, name, ipage); if (IS_ERR(page)) { err = PTR_ERR(page); goto fail; } + + f2fs_wait_on_page_writeback(ipage, NODE); de = &dentry_blk->dentry[bit_pos]; de->hash_code = name_hash; de->name_len = cpu_to_le16(namelen); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index deca8728117b..5072bf9ae0ef 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -83,7 +83,7 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, } if (strcmp(name, "") == 0) return -EINVAL; - return f2fs_getxattr(dentry->d_inode, type, name, buffer, size); + return f2fs_getxattr(dentry->d_inode, type, name, buffer, size, NULL); } static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, @@ -398,7 +398,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, } int f2fs_getxattr(struct inode *inode, int index, const char *name, - void *buffer, size_t buffer_size) + void *buffer, size_t buffer_size, struct page *ipage) { struct f2fs_xattr_entry *entry; void *base_addr; @@ -412,7 +412,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, if (len > F2FS_NAME_LEN) return -ERANGE; - base_addr = read_all_xattrs(inode, NULL); + base_addr = read_all_xattrs(inode, ipage); if (!base_addr) return -ENOMEM; diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 34ab7dbcf5e3..969d792ca362 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h @@ -115,7 +115,8 @@ extern const struct xattr_handler *f2fs_xattr_handlers[]; extern int f2fs_setxattr(struct inode *, int, const char *, const void *, size_t, struct page *, int); -extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t); +extern int f2fs_getxattr(struct inode *, int, const char *, void *, + size_t, struct page *); extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); #else @@ -126,7 +127,8 @@ static inline int f2fs_setxattr(struct inode *inode, int index, return -EOPNOTSUPP; } static inline int f2fs_getxattr(struct inode *inode, int index, - const char *name, void *buffer, size_t buffer_size) + const char *name, void *buffer, + size_t buffer_size, struct page *dpage) { return -EOPNOTSUPP; } -- GitLab From 3289c061c5aaf914c6eb7bdfadb58a7fdd611d30 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Oct 2014 20:00:16 -0700 Subject: [PATCH 2809/9457] f2fs: add stat info for inline_dentry inodes This patch adds status information for inline_dentry inodes. Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 3 +++ fs/f2fs/f2fs.h | 16 ++++++++++++++-- fs/f2fs/inline.c | 2 +- fs/f2fs/inode.c | 3 +++ fs/f2fs/namei.c | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 0a91ab813a9e..86e6e926278d 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -46,6 +46,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->valid_node_count = valid_node_count(sbi); si->valid_inode_count = valid_inode_count(sbi); si->inline_inode = sbi->inline_inode; + si->inline_dir = sbi->inline_dir; si->utilization = utilization(sbi); si->free_segs = free_segments(sbi); @@ -200,6 +201,8 @@ static int stat_show(struct seq_file *s, void *v) si->valid_count - si->valid_node_count); seq_printf(s, " - Inline_data Inode: %u\n", si->inline_inode); + seq_printf(s, " - Inline_dentry Inode: %u\n", + si->inline_dir); seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n", si->main_area_segs, si->main_area_sections, si->main_area_zones); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d4dcd934756e..9c4c8d154e95 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -560,6 +560,7 @@ struct f2fs_sb_info { unsigned int block_count[2]; /* # of allocated blocks */ int total_hit_ext, read_hit_ext; /* extent cache hit ratio */ int inline_inode; /* # of inline_data inodes */ + int inline_dir; /* # of inline_dentry inodes */ int bg_gc; /* background gc calls */ unsigned int n_dirty_dirs; /* # of dir inodes */ #endif @@ -1434,7 +1435,7 @@ struct f2fs_stat_info { int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; int nats, sits, fnids; int total_count, utilization; - int bg_gc, inline_inode; + int bg_gc, inline_inode, inline_dir; unsigned int valid_count, valid_node_count, valid_inode_count; unsigned int bimodal, avg_vblocks; int util_free, util_valid, util_invalid; @@ -1474,7 +1475,16 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) if (f2fs_has_inline_data(inode)) \ ((F2FS_I_SB(inode))->inline_inode--); \ } while (0) - +#define stat_inc_inline_dir(inode) \ + do { \ + if (f2fs_has_inline_dentry(inode)) \ + ((F2FS_I_SB(inode))->inline_dir++); \ + } while (0) +#define stat_dec_inline_dir(inode) \ + do { \ + if (f2fs_has_inline_dentry(inode)) \ + ((F2FS_I_SB(inode))->inline_dir--); \ + } while (0) #define stat_inc_seg_type(sbi, curseg) \ ((sbi)->segment_count[(curseg)->alloc_type]++) #define stat_inc_block_count(sbi, curseg) \ @@ -1521,6 +1531,8 @@ void f2fs_destroy_root_stats(void); #define stat_inc_read_hit(sb) #define stat_inc_inline_inode(inode) #define stat_dec_inline_inode(inode) +#define stat_inc_inline_dir(inode) +#define stat_dec_inline_dir(inode) #define stat_inc_seg_type(sbi, curseg) #define stat_inc_block_count(sbi, curseg) #define stat_inc_seg_count(si, type) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 46c554224276..4219bf475d72 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -382,8 +382,8 @@ int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, /* clear inline dir and flag after data writeback */ zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); + stat_dec_inline_dir(dir); clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY); - stat_dec_inline_inode(dir); if (i_size_read(dir) < PAGE_CACHE_SIZE) { i_size_write(dir, PAGE_CACHE_SIZE); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 52d6f54664f6..b9b1d6b147e8 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -169,6 +169,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) goto bad_inode; } unlock_new_inode(inode); + stat_inc_inline_dir(inode); trace_f2fs_iget(inode); return inode; @@ -300,6 +301,7 @@ void f2fs_evict_inode(struct inode *inode) sb_end_intwrite(inode->i_sb); no_delete: + stat_dec_inline_dir(inode); invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); if (xnid) invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); @@ -327,6 +329,7 @@ void handle_failed_inode(struct inode *inode) remove_inode_page(inode); stat_dec_inline_inode(inode); + clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); alloc_nid_failed(sbi, inode->i_ino); f2fs_unlock_op(sbi); diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index c8290da8e941..94ba2912ee05 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -297,6 +297,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) goto out_fail; f2fs_unlock_op(sbi); + stat_inc_inline_dir(inode); alloc_nid_done(sbi, inode->i_ino); d_instantiate(dentry, inode); -- GitLab From e7a2bf2283d368ada40ae52152b7ab2304a76d95 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 14 Oct 2014 10:29:50 -0700 Subject: [PATCH 2810/9457] f2fs: fix counting inline_data inode numbers This patch fixes wrongly counting inline_data inode numbers. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inode.c | 4 ++-- fs/f2fs/namei.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index b9b1d6b147e8..4131e3cfd1cf 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -169,6 +169,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) goto bad_inode; } unlock_new_inode(inode); + stat_inc_inline_inode(inode); stat_inc_inline_dir(inode); trace_f2fs_iget(inode); return inode; @@ -296,12 +297,12 @@ void f2fs_evict_inode(struct inode *inode) f2fs_lock_op(sbi); remove_inode_page(inode); - stat_dec_inline_inode(inode); f2fs_unlock_op(sbi); sb_end_intwrite(inode->i_sb); no_delete: stat_dec_inline_dir(inode); + stat_dec_inline_inode(inode); invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); if (xnid) invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); @@ -327,7 +328,6 @@ void handle_failed_inode(struct inode *inode) f2fs_truncate(inode); remove_inode_page(inode); - stat_dec_inline_inode(inode); clear_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY); alloc_nid_failed(sbi, inode->i_ino); diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 94ba2912ee05..a004a978096f 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -198,8 +198,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, inode = f2fs_iget(dir->i_sb, ino); if (IS_ERR(inode)) return ERR_CAST(inode); - - stat_inc_inline_inode(inode); } return d_splice_alias(inode, dentry); -- GitLab From 38594de767b32db62b7213631772d050690d3803 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 15 Oct 2014 21:29:51 -0700 Subject: [PATCH 2811/9457] f2fs: reuse core function in f2fs_readdir for inline_dentry This patch introduces a core function, f2fs_fill_dentries, to remove redundant code in f2fs_readdir and f2fs_read_inline_dir. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 64 ++++++++++++++++++++++++++++-------------------- fs/f2fs/f2fs.h | 3 +++ fs/f2fs/inline.c | 39 ++++++----------------------- 3 files changed, 48 insertions(+), 58 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index e5439dd67f4e..23a5da88ba66 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -706,23 +706,50 @@ bool f2fs_empty_dir(struct inode *dir) return true; } +bool f2fs_fill_dentries(struct dir_context *ctx, + const void *bitmap, struct f2fs_dir_entry *dentry, + __u8 (*filenames)[F2FS_SLOT_LEN], int max, + unsigned int start_pos) +{ + unsigned char d_type = DT_UNKNOWN; + unsigned int bit_pos; + struct f2fs_dir_entry *de = NULL; + + bit_pos = ((unsigned long)ctx->pos % max); + + while (bit_pos < max) { + bit_pos = find_next_bit_le(bitmap, max, bit_pos); + if (bit_pos >= max) + break; + + de = &dentry[bit_pos]; + if (de->file_type < F2FS_FT_MAX) + d_type = f2fs_filetype_table[de->file_type]; + else + d_type = DT_UNKNOWN; + if (!dir_emit(ctx, filenames[bit_pos], + le16_to_cpu(de->name_len), + le32_to_cpu(de->ino), d_type)) + return true; + + bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); + ctx->pos = start_pos + bit_pos; + } + return false; +} + static int f2fs_readdir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); unsigned long npages = dir_blocks(inode); - unsigned int bit_pos = 0; struct f2fs_dentry_block *dentry_blk = NULL; - struct f2fs_dir_entry *de = NULL; struct page *dentry_page = NULL; struct file_ra_state *ra = &file->f_ra; unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); - unsigned char d_type = DT_UNKNOWN; if (f2fs_has_inline_dentry(inode)) return f2fs_read_inline_dir(file, ctx); - bit_pos = ((unsigned long)ctx->pos % NR_DENTRY_IN_BLOCK); - /* readahead for multi pages of dir */ if (npages - n > 1 && !ra_has_index(ra, n)) page_cache_sync_readahead(inode->i_mapping, ra, file, n, @@ -734,28 +761,13 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) continue; dentry_blk = kmap(dentry_page); - while (bit_pos < NR_DENTRY_IN_BLOCK) { - bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, - NR_DENTRY_IN_BLOCK, - bit_pos); - if (bit_pos >= NR_DENTRY_IN_BLOCK) - break; - - de = &dentry_blk->dentry[bit_pos]; - if (de->file_type < F2FS_FT_MAX) - d_type = f2fs_filetype_table[de->file_type]; - else - d_type = DT_UNKNOWN; - if (!dir_emit(ctx, - dentry_blk->filename[bit_pos], - le16_to_cpu(de->name_len), - le32_to_cpu(de->ino), d_type)) - goto stop; - bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - ctx->pos = n * NR_DENTRY_IN_BLOCK + bit_pos; - } - bit_pos = 0; + if (f2fs_fill_dentries(ctx, + &dentry_blk->dentry_bitmap, dentry_blk->dentry, + dentry_blk->filename, + NR_DENTRY_IN_BLOCK, n * NR_DENTRY_IN_BLOCK)) + goto stop; + ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK; kunmap(dentry_page); f2fs_put_page(dentry_page, 1); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9c4c8d154e95..3b0f490646af 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1247,6 +1247,9 @@ extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; void set_de_type(struct f2fs_dir_entry *, struct inode *); struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, const void *, struct f2fs_dir_entry *, __u8 (*)[F2FS_SLOT_LEN]); +bool f2fs_fill_dentries(struct dir_context *, + const void *, struct f2fs_dir_entry *, + __u8 (*)[F2FS_SLOT_LEN], int, unsigned int); struct page *init_inode_metadata(struct inode *, struct inode *, const struct qstr *, struct page *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 4219bf475d72..38a6aa792534 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -517,49 +517,24 @@ bool f2fs_empty_inline_dir(struct inode *dir) int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) { struct inode *inode = file_inode(file); - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - unsigned int bit_pos = 0; struct f2fs_inline_dentry *inline_dentry = NULL; - struct f2fs_dir_entry *de = NULL; struct page *ipage = NULL; - unsigned char d_type = DT_UNKNOWN; if (ctx->pos == NR_INLINE_DENTRY) return 0; - ipage = get_node_page(sbi, inode->i_ino); + ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); if (IS_ERR(ipage)) return PTR_ERR(ipage); - bit_pos = ((unsigned long)ctx->pos % NR_INLINE_DENTRY); - inline_dentry = inline_data_addr(ipage); - while (bit_pos < NR_INLINE_DENTRY) { - bit_pos = find_next_bit_le(&inline_dentry->dentry_bitmap, - NR_INLINE_DENTRY, - bit_pos); - if (bit_pos >= NR_INLINE_DENTRY) - break; - - de = &inline_dentry->dentry[bit_pos]; - if (de->file_type < F2FS_FT_MAX) - d_type = f2fs_filetype_table[de->file_type]; - else - d_type = DT_UNKNOWN; - - if (!dir_emit(ctx, - inline_dentry->filename[bit_pos], - le16_to_cpu(de->name_len), - le32_to_cpu(de->ino), d_type)) - goto out; - - bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); - ctx->pos = bit_pos; - } - ctx->pos = NR_INLINE_DENTRY; -out: - f2fs_put_page(ipage, 1); + if (!f2fs_fill_dentries(ctx, &inline_dentry->dentry_bitmap, + inline_dentry->dentry, + inline_dentry->filename, + NR_INLINE_DENTRY, 0)) + ctx->pos = NR_INLINE_DENTRY; + f2fs_put_page(ipage, 1); return 0; } -- GitLab From 5ab18570b85cf3071875a36b88bc5ed27d0b6ef7 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 16 Oct 2014 12:24:14 -0700 Subject: [PATCH 2812/9457] f2fs: should not truncate any inline_dentry If the inode has inline_dentry, we should not truncate any block indices. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index d054e0ebfe24..402e38185b8c 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -471,7 +471,7 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) trace_f2fs_truncate_blocks_enter(inode, from); - if (f2fs_has_inline_data(inode)) + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) goto done; free_from = (pgoff_t) -- GitLab From 7b3cd7d6f026784b1a2a74b6e207b26253d9d780 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 18 Oct 2014 22:52:52 -0700 Subject: [PATCH 2813/9457] f2fs: introduce f2fs_dentry_ptr structure for code clean-up This patch introduces f2fs_dentry_ptr structure for the use of a function parameter in inline_dentry operations. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 61 +++++++++++++++++++++++------------------------- fs/f2fs/f2fs.h | 35 +++++++++++++++++++++++---- fs/f2fs/inline.c | 18 +++++++------- 3 files changed, 68 insertions(+), 46 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 23a5da88ba66..4f029a1b0cf0 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -95,13 +95,13 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, { struct f2fs_dentry_block *dentry_blk; struct f2fs_dir_entry *de; - - *max_slots = NR_DENTRY_IN_BLOCK; + struct f2fs_dentry_ptr d; dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page); - de = find_target_dentry(name, max_slots, &dentry_blk->dentry_bitmap, - dentry_blk->dentry, - dentry_blk->filename); + + make_dentry_ptr(&d, (void *)dentry_blk, 1); + de = find_target_dentry(name, max_slots, &d); + if (de) *res_page = dentry_page; else @@ -111,50 +111,49 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, * For the most part, it should be a bug when name_len is zero. * We stop here for figuring out where the bugs has occurred. */ - f2fs_bug_on(F2FS_P_SB(dentry_page), *max_slots < 0); + f2fs_bug_on(F2FS_P_SB(dentry_page), d.max < 0); return de; } struct f2fs_dir_entry *find_target_dentry(struct qstr *name, int *max_slots, - const void *bitmap, struct f2fs_dir_entry *dentry, - __u8 (*filenames)[F2FS_SLOT_LEN]) + struct f2fs_dentry_ptr *d) { struct f2fs_dir_entry *de; unsigned long bit_pos = 0; f2fs_hash_t namehash = f2fs_dentry_hash(name); - int max_bits = *max_slots; int max_len = 0; - *max_slots = 0; - while (bit_pos < max_bits) { - if (!test_bit_le(bit_pos, bitmap)) { + if (max_slots) + *max_slots = 0; + while (bit_pos < d->max) { + if (!test_bit_le(bit_pos, d->bitmap)) { if (bit_pos == 0) max_len = 1; - else if (!test_bit_le(bit_pos - 1, bitmap)) + else if (!test_bit_le(bit_pos - 1, d->bitmap)) max_len++; bit_pos++; continue; } - de = &dentry[bit_pos]; + de = &d->dentry[bit_pos]; if (early_match_name(name->len, namehash, de) && - !memcmp(filenames[bit_pos], name->name, name->len)) + !memcmp(d->filename[bit_pos], name->name, name->len)) goto found; - if (*max_slots >= 0 && max_len > *max_slots) { + if (max_slots && *max_slots >= 0 && max_len > *max_slots) { *max_slots = max_len; max_len = 0; } /* remain bug on condition */ if (unlikely(!de->name_len)) - *max_slots = -1; + d->max = -1; bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len)); } de = NULL; found: - if (max_len > *max_slots) + if (max_slots && max_len > *max_slots) *max_slots = max_len; return de; } @@ -706,28 +705,26 @@ bool f2fs_empty_dir(struct inode *dir) return true; } -bool f2fs_fill_dentries(struct dir_context *ctx, - const void *bitmap, struct f2fs_dir_entry *dentry, - __u8 (*filenames)[F2FS_SLOT_LEN], int max, - unsigned int start_pos) +bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, + unsigned int start_pos) { unsigned char d_type = DT_UNKNOWN; unsigned int bit_pos; struct f2fs_dir_entry *de = NULL; - bit_pos = ((unsigned long)ctx->pos % max); + bit_pos = ((unsigned long)ctx->pos % d->max); - while (bit_pos < max) { - bit_pos = find_next_bit_le(bitmap, max, bit_pos); - if (bit_pos >= max) + while (bit_pos < d->max) { + bit_pos = find_next_bit_le(d->bitmap, d->max, bit_pos); + if (bit_pos >= d->max) break; - de = &dentry[bit_pos]; + de = &d->dentry[bit_pos]; if (de->file_type < F2FS_FT_MAX) d_type = f2fs_filetype_table[de->file_type]; else d_type = DT_UNKNOWN; - if (!dir_emit(ctx, filenames[bit_pos], + if (!dir_emit(ctx, d->filename[bit_pos], le16_to_cpu(de->name_len), le32_to_cpu(de->ino), d_type)) return true; @@ -746,6 +743,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) struct page *dentry_page = NULL; struct file_ra_state *ra = &file->f_ra; unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); + struct f2fs_dentry_ptr d; if (f2fs_has_inline_dentry(inode)) return f2fs_read_inline_dir(file, ctx); @@ -762,10 +760,9 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) dentry_blk = kmap(dentry_page); - if (f2fs_fill_dentries(ctx, - &dentry_blk->dentry_bitmap, dentry_blk->dentry, - dentry_blk->filename, - NR_DENTRY_IN_BLOCK, n * NR_DENTRY_IN_BLOCK)) + make_dentry_ptr(&d, (void *)dentry_blk, 1); + + if (f2fs_fill_dentries(ctx, &d, n * NR_DENTRY_IN_BLOCK)) goto stop; ctx->pos = (n + 1) * NR_DENTRY_IN_BLOCK; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3b0f490646af..f7bbfc7d06b8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -212,6 +212,32 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, /* * For INODE and NODE manager */ +/* for directory operations */ +struct f2fs_dentry_ptr { + const void *bitmap; + struct f2fs_dir_entry *dentry; + __u8 (*filename)[F2FS_SLOT_LEN]; + int max; +}; + +static inline void make_dentry_ptr(struct f2fs_dentry_ptr *d, + void *src, int type) +{ + if (type == 1) { + struct f2fs_dentry_block *t = (struct f2fs_dentry_block *)src; + d->max = NR_DENTRY_IN_BLOCK; + d->bitmap = &t->dentry_bitmap; + d->dentry = t->dentry; + d->filename = t->filename; + } else { + struct f2fs_inline_dentry *t = (struct f2fs_inline_dentry *)src; + d->max = NR_INLINE_DENTRY; + d->bitmap = &t->dentry_bitmap; + d->dentry = t->dentry; + d->filename = t->filename; + } +} + /* * XATTR_NODE_OFFSET stores xattrs to one node block per file keeping -1 * as its node offset to distinguish from index node blocks. @@ -1245,11 +1271,10 @@ struct dentry *f2fs_get_parent(struct dentry *child); */ extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; void set_de_type(struct f2fs_dir_entry *, struct inode *); -struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, const void *, - struct f2fs_dir_entry *, __u8 (*)[F2FS_SLOT_LEN]); -bool f2fs_fill_dentries(struct dir_context *, - const void *, struct f2fs_dir_entry *, - __u8 (*)[F2FS_SLOT_LEN], int, unsigned int); +struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, + struct f2fs_dentry_ptr *); +bool f2fs_fill_dentries(struct dir_context *, struct f2fs_dentry_ptr *, + unsigned int); struct page *init_inode_metadata(struct inode *, struct inode *, const struct qstr *, struct page *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 38a6aa792534..445e99d6f6ee 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -265,8 +265,8 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); struct f2fs_inline_dentry *inline_dentry; struct f2fs_dir_entry *de; + struct f2fs_dentry_ptr d; struct page *ipage; - int max_slots = NR_INLINE_DENTRY; ipage = get_node_page(sbi, dir->i_ino); if (IS_ERR(ipage)) @@ -274,9 +274,9 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, inline_dentry = inline_data_addr(ipage); - de = find_target_dentry(name, &max_slots, &inline_dentry->dentry_bitmap, - inline_dentry->dentry, - inline_dentry->filename); + make_dentry_ptr(&d, (void *)inline_dentry, 2); + de = find_target_dentry(name, NULL, &d); + unlock_page(ipage); if (de) *res_page = ipage; @@ -287,7 +287,7 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, * For the most part, it should be a bug when name_len is zero. * We stop here for figuring out where the bugs has occurred. */ - f2fs_bug_on(sbi, max_slots < 0); + f2fs_bug_on(sbi, d.max < 0); return de; } @@ -519,6 +519,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) struct inode *inode = file_inode(file); struct f2fs_inline_dentry *inline_dentry = NULL; struct page *ipage = NULL; + struct f2fs_dentry_ptr d; if (ctx->pos == NR_INLINE_DENTRY) return 0; @@ -529,10 +530,9 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx) inline_dentry = inline_data_addr(ipage); - if (!f2fs_fill_dentries(ctx, &inline_dentry->dentry_bitmap, - inline_dentry->dentry, - inline_dentry->filename, - NR_INLINE_DENTRY, 0)) + make_dentry_ptr(&d, (void *)inline_dentry, 2); + + if (!f2fs_fill_dentries(ctx, &d, 0)) ctx->pos = NR_INLINE_DENTRY; f2fs_put_page(ipage, 1); -- GitLab From 062a3e7ba7eebcd7d44e49e9510135f901f93f48 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 18 Oct 2014 23:06:41 -0700 Subject: [PATCH 2814/9457] f2fs: reuse make_empty_dir code for inline_dentry This patch introduces do_make_empty_dir to mitigate code redundancy for inline_dentry. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 42 ++++++++++++++++++++++++++---------------- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/inline.c | 20 +++----------------- 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4f029a1b0cf0..4e62bdeb253d 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -323,12 +323,35 @@ int update_dent_inode(struct inode *inode, const struct qstr *name) return 0; } +void do_make_empty_dir(struct inode *inode, struct inode *parent, + struct f2fs_dentry_ptr *d) +{ + struct f2fs_dir_entry *de; + + de = &d->dentry[0]; + de->name_len = cpu_to_le16(1); + de->hash_code = 0; + de->ino = cpu_to_le32(inode->i_ino); + memcpy(d->filename[0], ".", 1); + set_de_type(de, inode); + + de = &d->dentry[1]; + de->hash_code = 0; + de->name_len = cpu_to_le16(2); + de->ino = cpu_to_le32(parent->i_ino); + memcpy(d->filename[1], "..", 2); + set_de_type(de, inode); + + test_and_set_bit_le(0, (void *)d->bitmap); + test_and_set_bit_le(1, (void *)d->bitmap); +} + static int make_empty_dir(struct inode *inode, struct inode *parent, struct page *page) { struct page *dentry_page; struct f2fs_dentry_block *dentry_blk; - struct f2fs_dir_entry *de; + struct f2fs_dentry_ptr d; if (f2fs_has_inline_dentry(inode)) return make_empty_inline_dir(inode, parent, page); @@ -339,22 +362,9 @@ static int make_empty_dir(struct inode *inode, dentry_blk = kmap_atomic(dentry_page); - de = &dentry_blk->dentry[0]; - de->name_len = cpu_to_le16(1); - de->hash_code = 0; - de->ino = cpu_to_le32(inode->i_ino); - memcpy(dentry_blk->filename[0], ".", 1); - set_de_type(de, inode); - - de = &dentry_blk->dentry[1]; - de->hash_code = 0; - de->name_len = cpu_to_le16(2); - de->ino = cpu_to_le32(parent->i_ino); - memcpy(dentry_blk->filename[1], "..", 2); - set_de_type(de, inode); + make_dentry_ptr(&d, (void *)dentry_blk, 1); + do_make_empty_dir(inode, parent, &d); - test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); - test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); kunmap_atomic(dentry_blk); set_page_dirty(dentry_page); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f7bbfc7d06b8..cb59ebbf0f38 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1275,6 +1275,8 @@ struct f2fs_dir_entry *find_target_dentry(struct qstr *, int *, struct f2fs_dentry_ptr *); bool f2fs_fill_dentries(struct dir_context *, struct f2fs_dentry_ptr *, unsigned int); +void do_make_empty_dir(struct inode *, struct inode *, + struct f2fs_dentry_ptr *); struct page *init_inode_metadata(struct inode *, struct inode *, const struct qstr *, struct page *); void update_parent_metadata(struct inode *, struct inode *, unsigned int); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 445e99d6f6ee..a30984505f16 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -314,26 +314,12 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent, struct page *ipage) { struct f2fs_inline_dentry *dentry_blk; - struct f2fs_dir_entry *de; + struct f2fs_dentry_ptr d; dentry_blk = inline_data_addr(ipage); - de = &dentry_blk->dentry[0]; - de->name_len = cpu_to_le16(1); - de->hash_code = 0; - de->ino = cpu_to_le32(inode->i_ino); - memcpy(dentry_blk->filename[0], ".", 1); - set_de_type(de, inode); - - de = &dentry_blk->dentry[1]; - de->hash_code = 0; - de->name_len = cpu_to_le16(2); - de->ino = cpu_to_le32(parent->i_ino); - memcpy(dentry_blk->filename[1], "..", 2); - set_de_type(de, inode); - - test_and_set_bit_le(0, &dentry_blk->dentry_bitmap); - test_and_set_bit_le(1, &dentry_blk->dentry_bitmap); + make_dentry_ptr(&d, (void *)dentry_blk, 2); + do_make_empty_dir(inode, parent, &d); set_page_dirty(ipage); -- GitLab From f1e33a041e39535571cd19f4799c3673868f2118 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sat, 18 Oct 2014 23:41:38 -0700 Subject: [PATCH 2815/9457] f2fs: use kmap_atomic instead of kmap For better performance, we need to use kmap_atomic instead of kmap. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index a30984505f16..024546b80fd0 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -55,11 +55,10 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) /* Copy the whole inline data block */ src_addr = inline_data_addr(ipage); - dst_addr = kmap(page); + dst_addr = kmap_atomic(page); memcpy(dst_addr, src_addr, MAX_INLINE_DATA); - kunmap(page); + kunmap_atomic(dst_addr); f2fs_put_page(ipage, 1); - out: SetPageUptodate(page); unlock_page(page); @@ -105,9 +104,9 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) /* Copy the whole inline data block */ src_addr = inline_data_addr(ipage); - dst_addr = kmap(page); + dst_addr = kmap_atomic(page); memcpy(dst_addr, src_addr, MAX_INLINE_DATA); - kunmap(page); + kunmap_atomic(dst_addr); SetPageUptodate(page); /* write data page to try to make data consistent */ @@ -177,10 +176,10 @@ int f2fs_write_inline_data(struct inode *inode, f2fs_wait_on_page_writeback(ipage, NODE); zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); - src_addr = kmap(page); + src_addr = kmap_atomic(page); dst_addr = inline_data_addr(ipage); memcpy(dst_addr, src_addr, size); - kunmap(page); + kunmap_atomic(src_addr); set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE); sync_inode_page(&dn); @@ -351,7 +350,7 @@ int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, f2fs_wait_on_page_writeback(page, DATA); zero_user_segment(page, 0, PAGE_CACHE_SIZE); - dentry_blk = kmap(page); + dentry_blk = kmap_atomic(page); /* copy data from inline dentry block to new dentry block */ memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap, @@ -361,7 +360,7 @@ int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, memcpy(dentry_blk->filename, inline_dentry->filename, NR_INLINE_DENTRY * F2FS_SLOT_LEN); - kunmap(page); + kunmap_atomic(dentry_blk); SetPageUptodate(page); set_page_dirty(page); -- GitLab From d64948a4df9f5571b0efa81f71a59bc86d7056a7 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 20 Oct 2014 20:28:49 -0700 Subject: [PATCH 2816/9457] f2fs: declare f2fs_convert_inline_dir as a static function This patch declares f2fs_convert_inline_dir as a static function, which was reported by kbuild test robot. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 024546b80fd0..d9daf76aa9cd 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -330,7 +330,7 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent, return 0; } -int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, +static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage, struct f2fs_inline_dentry *inline_dentry) { struct page *page; -- GitLab From 9bd27ae4aafc9bfee6c8791f7d801ea16cc5622b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 21 Oct 2014 14:07:33 +0200 Subject: [PATCH 2817/9457] f2fs: avoid returning uninitialized value to userspace from f2fs_trim_fs() If user specifies too low end sector for trimming, f2fs_trim_fs() will use uninitialized value as a number of trimmed blocks and returns it to userspace. Initialize number of trimmed blocks early to avoid the problem. Coverity-id: 1248809 CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 2c1e60893ef2..6b0850487aa2 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1032,6 +1032,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) range->len < sbi->blocksize) return -EINVAL; + cpc.trimmed = 0; if (end <= MAIN_BLKADDR(sbi)) goto out; @@ -1043,7 +1044,6 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) cpc.trim_start = start_segno; cpc.trim_end = end_segno; cpc.trim_minlen = range->minlen >> sbi->log_blocksize; - cpc.trimmed = 0; /* do checkpoint to issue discard commands safely */ write_checkpoint(sbi, &cpc); -- GitLab From 8a2d0ace3af74825e4f1e6fb962f7ee8ef4d9281 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:48 +0800 Subject: [PATCH 2818/9457] f2fs: remove the seems unneeded argument 'type' from __get_victim Remove the unneeded argument 'type' from __get_victim, use NO_CHECK_TYPE directly when calling v_ops->get_victim(). Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 2a8f4acdb86b..7151d7de7d95 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -646,12 +646,14 @@ static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, - int gc_type, int type) + int gc_type) { struct sit_info *sit_i = SIT_I(sbi); int ret; + mutex_lock(&sit_i->sentry_lock); - ret = DIRTY_I(sbi)->v_ops->get_victim(sbi, victim, gc_type, type, LFS); + ret = DIRTY_I(sbi)->v_ops->get_victim(sbi, victim, gc_type, + NO_CHECK_TYPE, LFS); mutex_unlock(&sit_i->sentry_lock); return ret; } @@ -709,7 +711,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) write_checkpoint(sbi, &cpc); } - if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) + if (!__get_victim(sbi, &segno, gc_type)) goto stop; ret = 0; -- GitLab From fa528722d06ecbee9d918b9eec58c5d4c2978839 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:52 +0800 Subject: [PATCH 2819/9457] f2fs: remove the redundant function cond_clear_inode_flag Use clear_inode_flag to replace the redundant cond_clear_inode_flag. Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/acl.c | 4 ++-- fs/f2fs/f2fs.h | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 620745556828..1ccb26bc2a0b 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -236,7 +236,7 @@ static int __f2fs_set_acl(struct inode *inode, int type, if (acl) { value = f2fs_acl_to_disk(acl, &size); if (IS_ERR(value)) { - cond_clear_inode_flag(fi, FI_ACL_MODE); + clear_inode_flag(fi, FI_ACL_MODE); return (int)PTR_ERR(value); } } @@ -247,7 +247,7 @@ static int __f2fs_set_acl(struct inode *inode, int type, if (!error) set_cached_acl(inode, type, acl); - cond_clear_inode_flag(fi, FI_ACL_MODE); + clear_inode_flag(fi, FI_ACL_MODE); return error; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index cb59ebbf0f38..3608c13aa7a2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1117,15 +1117,6 @@ static inline void set_acl_inode(struct f2fs_inode_info *fi, umode_t mode) set_inode_flag(fi, FI_ACL_MODE); } -static inline int cond_clear_inode_flag(struct f2fs_inode_info *fi, int flag) -{ - if (is_inode_flag_set(fi, FI_ACL_MODE)) { - clear_inode_flag(fi, FI_ACL_MODE); - return 1; - } - return 0; -} - static inline void get_inline_info(struct f2fs_inode_info *fi, struct f2fs_inode *ri) { -- GitLab From c6ac4c0ec416e77cab09cac6cee2d100fbd7fc82 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:50 +0800 Subject: [PATCH 2820/9457] f2fs: introduce f2fs_change_bit to simplify the change bit logic Introduce f2fs_change_bit to simplify the change bit logic in function set_to_next_nat{sit}. Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 9 +++++++++ fs/f2fs/node.h | 5 +---- fs/f2fs/segment.h | 5 +---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3608c13aa7a2..60045a24f0d5 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1073,6 +1073,15 @@ static inline int f2fs_clear_bit(unsigned int nr, char *addr) return ret; } +static inline void f2fs_change_bit(unsigned int nr, char *addr) +{ + int mask; + + addr += (nr >> 3); + mask = 1 << (7 - (nr & 0x07)); + *addr ^= mask; +} + /* used for f2fs_inode_info->flags */ enum { FI_NEW_INODE, /* indicate newly allocated inode */ diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 8d5e6e0dd840..acb71e507a7a 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -192,10 +192,7 @@ static inline void set_to_next_nat(struct f2fs_nm_info *nm_i, nid_t start_nid) { unsigned int block_off = NAT_BLOCK_OFFSET(start_nid); - if (f2fs_test_bit(block_off, nm_i->nat_bitmap)) - f2fs_clear_bit(block_off, nm_i->nat_bitmap); - else - f2fs_set_bit(block_off, nm_i->nat_bitmap); + f2fs_change_bit(block_off, nm_i->nat_bitmap); } static inline void fill_node_footer(struct page *page, nid_t nid, diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 2495bec1c621..6723ccc17585 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -657,10 +657,7 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start) { unsigned int block_off = SIT_BLOCK_OFFSET(start); - if (f2fs_test_bit(block_off, sit_i->sit_bitmap)) - f2fs_clear_bit(block_off, sit_i->sit_bitmap); - else - f2fs_set_bit(block_off, sit_i->sit_bitmap); + f2fs_change_bit(block_off, sit_i->sit_bitmap); } static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi) -- GitLab From 1730663cb7f368ecc2aea36fd8c533b5b0a91980 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:53 +0800 Subject: [PATCH 2821/9457] f2fs: set raw_super default to NULL to avoid compile warning Set raw_super default to NULL to avoid the possibly used uninitialized warning, though we may never hit it in fact. Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 73993a9e86be..6c5fc7605109 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -930,7 +930,7 @@ static int read_raw_super_block(struct super_block *sb, static int f2fs_fill_super(struct super_block *sb, void *data, int silent) { struct f2fs_sb_info *sbi; - struct f2fs_super_block *raw_super; + struct f2fs_super_block *raw_super = NULL; struct buffer_head *raw_super_buf; struct inode *root; long err = -EINVAL; -- GitLab From 52aca07425088954384eb503d8e3442d81b9d18c Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:51 +0800 Subject: [PATCH 2822/9457] f2fs: rename f2fs_set/clear_bit to f2fs_test_and_set/clear_bit Rename f2fs_set/clear_bit to f2fs_test_and_set/clear_bit, which mean set/clear bit and return the old value, for better readability. Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 4 ++-- fs/f2fs/segment.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 60045a24f0d5..2e9d2e3051f7 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1049,7 +1049,7 @@ static inline int f2fs_test_bit(unsigned int nr, char *addr) return mask & *addr; } -static inline int f2fs_set_bit(unsigned int nr, char *addr) +static inline int f2fs_test_and_set_bit(unsigned int nr, char *addr) { int mask; int ret; @@ -1061,7 +1061,7 @@ static inline int f2fs_set_bit(unsigned int nr, char *addr) return ret; } -static inline int f2fs_clear_bit(unsigned int nr, char *addr) +static inline int f2fs_test_and_clear_bit(unsigned int nr, char *addr) { int mask; int ret; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 6b0850487aa2..19de23b119fa 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -648,10 +648,10 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) /* Update valid block bitmap */ if (del > 0) { - if (f2fs_set_bit(offset, se->cur_valid_map)) + if (f2fs_test_and_set_bit(offset, se->cur_valid_map)) f2fs_bug_on(sbi, 1); } else { - if (!f2fs_clear_bit(offset, se->cur_valid_map)) + if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) f2fs_bug_on(sbi, 1); } if (!f2fs_test_bit(offset, se->ckpt_valid_map)) -- GitLab From 2cc221861132e0ca54e3f52d506520ded8520e80 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 20 Oct 2014 17:45:49 +0800 Subject: [PATCH 2823/9457] f2fs: use current_sit_addr to replace the open code Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 19de23b119fa..21ccc4816474 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1552,17 +1552,7 @@ int lookup_journal_in_cursum(struct f2fs_summary_block *sum, int type, static struct page *get_current_sit_page(struct f2fs_sb_info *sbi, unsigned int segno) { - struct sit_info *sit_i = SIT_I(sbi); - unsigned int offset = SIT_BLOCK_OFFSET(segno); - block_t blk_addr = sit_i->sit_base_addr + offset; - - check_seg_range(sbi, segno); - - /* calculate sit block address */ - if (f2fs_test_bit(offset, sit_i->sit_bitmap)) - blk_addr += sit_i->sit_blocks; - - return get_meta_page(sbi, blk_addr); + return get_meta_page(sbi, current_sit_addr(sbi, segno)); } static struct page *get_next_sit_page(struct f2fs_sb_info *sbi, -- GitLab From 9234f3190bf8b25b11b105191d408ac50a107948 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 22 Oct 2014 15:21:47 +0200 Subject: [PATCH 2824/9457] f2fs: fix possible data corruption in f2fs_write_begin() f2fs_write_begin() doesn't initialize the 'dn' variable if the inode has inline data. However it uses its contents to decide whether it should just zero out the page or load data to it. Thus if we are unlucky we can zero out page contents instead of loading inline data into a page. CC: stable@vger.kernel.org CC: Changman Lee Signed-off-by: Jan Kara Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 973fd7770d56..e3788bd206d8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1017,21 +1017,19 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, goto out; } - if (dn.data_blkaddr == NEW_ADDR) { + if (f2fs_has_inline_data(inode)) { + err = f2fs_read_inline_data(inode, page); + if (err) { + page_cache_release(page); + goto fail; + } + } else if (dn.data_blkaddr == NEW_ADDR) { zero_user_segment(page, 0, PAGE_CACHE_SIZE); } else { - if (f2fs_has_inline_data(inode)) { - err = f2fs_read_inline_data(inode, page); - if (err) { - page_cache_release(page); - goto fail; - } - } else { - err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr, - READ_SYNC); - if (err) - goto fail; - } + err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr, + READ_SYNC); + if (err) + goto fail; lock_page(page); if (unlikely(!PageUptodate(page))) { -- GitLab From ca4b02eeed752c02da0df9da6f9d3c978f9fa9e1 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 27 Oct 2014 11:04:35 -0700 Subject: [PATCH 2825/9457] f2fs: call write_checkpoint under disabled gc During the write_checkpoint, we should avoid f2fs_gc trigger to avoid any filesystem consistency. Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 21ccc4816474..d391a5913c79 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1046,7 +1046,9 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) cpc.trim_minlen = range->minlen >> sbi->log_blocksize; /* do checkpoint to issue discard commands safely */ + mutex_lock(&sbi->gc_mutex); write_checkpoint(sbi, &cpc); + mutex_unlock(&sbi->gc_mutex); out: range->len = cpc.trimmed << sbi->log_blocksize; return 0; -- GitLab From 427a45c8e2395e0d24cb7fecc2ebf6e5e84e59fd Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sun, 26 Oct 2014 22:59:27 -0700 Subject: [PATCH 2826/9457] f2fs: flush_dcache_page for inline data When reading inline data, we should call flush_dcache_page. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index d9daf76aa9cd..d6677d6bbd89 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -57,6 +57,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) src_addr = inline_data_addr(ipage); dst_addr = kmap_atomic(page); memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + flush_dcache_page(page); kunmap_atomic(dst_addr); f2fs_put_page(ipage, 1); out: -- GitLab From e3fb1b794b5f0c9f9b65707ce4e6be264a9c60f8 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 27 Oct 2014 13:54:27 -0700 Subject: [PATCH 2827/9457] f2fs: do not discard data protected by the previous checkpoint We should not discard any data protected by the previous checkpoint all the time. Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d391a5913c79..06dda733f958 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -517,7 +517,7 @@ static void add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* SIT_VBLOCK_MAP_SIZE should be multiple of sizeof(unsigned long) */ for (i = 0; i < entries; i++) - dmap[i] = (cur_map[i] ^ ckpt_map[i]) & ckpt_map[i]; + dmap[i] = ~(cur_map[i] | ckpt_map[i]); while (force || SM_I(sbi)->nr_discards <= SM_I(sbi)->max_discards) { start = __find_rev_next_bit(dmap, max_blocks, end + 1); -- GitLab From 1f7732fe6cc0c37befc74cef1d289cd2272b7a5c Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 23 Oct 2014 14:40:20 +0200 Subject: [PATCH 2828/9457] f2fs: remove pointless bit testing in f2fs_delete_entry() There's no point in using test_and_clear_bit_le() when we don't use the return value of the function. Just use clear_bit_le() instead. Coverity-id: 1016434 Signed-off-by: Jan Kara Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4e62bdeb253d..5a49995a666e 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -654,7 +654,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, dentry_blk = page_address(page); bit_pos = dentry - dentry_blk->dentry; for (i = 0; i < slots; i++) - test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); + clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); /* Let's check and deallocate this dentry page */ bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, -- GitLab From b7c12ca4df9dc69e4d8dd4468d3b5b780de1ae36 Mon Sep 17 00:00:00 2001 From: Dilek Uzulmez Date: Thu, 30 Oct 2014 23:20:46 +0200 Subject: [PATCH 2829/9457] staging: rtl8188eu: Remove unnecessary else after return This patch fixes checkpatch.pl warning in files of rtl8188eu WARNING: else is not generally useful after a break or return Signed-off-by: Dilek Uzulmez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index c47b1573c6e8..8816d116a8b8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -637,10 +637,9 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { return false; - } else { - efuse_addr++; - continue; } + efuse_addr++; + continue; } else if (pg_header != tmp_header) { /* offset PG fail */ struct pgpkt fixPkt; fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); @@ -707,14 +706,13 @@ static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u if (badworden == 0x0F) { /* write ok */ return true; - } else { - /* reorganize other pg packet */ - PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data); - if (!PgWriteSuccess) - return false; - else - return true; } + /* reorganize other pg packet */ + PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data); + if (!PgWriteSuccess) + return false; + else + return true; } static bool -- GitLab From 11dd2a979a5b81d69d6c877f94541987b19c54b5 Mon Sep 17 00:00:00 2001 From: Tina Ruchandani Date: Thu, 30 Oct 2014 17:45:22 -0700 Subject: [PATCH 2830/9457] Staging: lustre: lnet: Improve 'incarnation' stamp ksock_net_t uses a __u64 quantity as an 'incarnation' timestamp. This is also passed on in hello messages and used to detect if a reboot has occurred. This 'incarnation' is obtained using do_gettimeofday.It is only used in equality checks, so the absolute value does not matter. This patch replaces do_gettimeofday with ktime_get_ns for the following reasons: 1. ktime_get_ns returns a __u64 which is safer than 'struct timeval' which will overflow on 32-bit systems in year 2038 and beyond. 2. Reduced compute: ktime_get_ns is faster than the multiply/add combination used in this function Signed-off-by: Tina Ruchandani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 038854e8302f..8ac6410e2ae2 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2348,16 +2348,11 @@ ksocknal_base_shutdown(void) static __u64 ksocknal_new_incarnation (void) { - struct timeval tv; /* The incarnation number is the time this module loaded and it - * identifies this particular instance of the socknal. Hopefully - * we won't be able to reboot more frequently than 1MHz for the - * foreseeable future :) */ - - do_gettimeofday(&tv); - - return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec; + * identifies this particular instance of the socknal. + */ + return ktime_get_ns(); } static int -- GitLab From 8c4f13649731576d5f82dfffff465041feae8d60 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 31 Oct 2014 07:56:29 +0530 Subject: [PATCH 2831/9457] Staging: lustre: Use put_unaligned_le64 This patch introduces the use of function put_unaligned_le64. This is done using Coccinelle and semantic patch used is as follows: @@ identifier tmp; expression ptr; expression y,e; type T; @@ - tmp = cpu_to_le64(y); <+... when != tmp - memcpy(ptr, (T)&tmp, ...); + put_unaligned_le64(y,ptr); ...+> ? tmp = e @@ type T; identifier tmp; @@ - T tmp; ...when != tmp Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/debug.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c index d0f8f875ddd6..9c934e6d2ea1 100644 --- a/drivers/staging/lustre/lustre/obdclass/debug.c +++ b/drivers/staging/lustre/lustre/obdclass/debug.c @@ -40,6 +40,7 @@ #define DEBUG_SUBSYSTEM D_OTHER +#include #include "../include/obd_support.h" #include "../include/lustre_debug.h" @@ -60,14 +61,11 @@ int block_debug_setup(void *addr, int len, __u64 off, __u64 id) { LASSERT(addr); - off = cpu_to_le64 (off); - id = cpu_to_le64 (id); - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); - + put_unaligned_le64(off, addr); + put_unaligned_le64(id, addr+LPDS); addr += len - LPDS - LPDS; - memcpy(addr, (char *)&off, LPDS); - memcpy(addr + LPDS, (char *)&id, LPDS); + put_unaligned_le64(off, addr); + put_unaligned_le64(id, addr+LPDS); return 0; } -- GitLab From f5333f8982c2fe95b04c8f1bce64fed691b47eec Mon Sep 17 00:00:00 2001 From: Roberta Dobrescu Date: Fri, 31 Oct 2014 00:01:20 +0200 Subject: [PATCH 2832/9457] staging: rtl8723au: Remove useless static functions This patch removes the static functions bthci_CmdSetEventFilter, bthci_CmdReadRSSI and bthci_CmdHostNumberOfCompletedPackets, since their body only consists of 'return HCI_STATUS_SUCCESS'. Signed-off-by: Roberta Dobrescu Signed-off-by: Greg Kroah-Hartman --- .../rtl8723au/hal/rtl8723a_bt-coexist.c | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c index 5de806e45c3b..d80ea4ee39e9 100644 --- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c +++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c @@ -1759,16 +1759,6 @@ static enum hci_status bthci_CmdReadConnectionAcceptTimeout(struct rtw_adapter * return status; } -/* 7.3.3 */ -static enum hci_status -bthci_CmdSetEventFilter( - struct rtw_adapter *padapter, - struct packet_irp_hcicmd_data *pHciCmd - ) -{ - return HCI_STATUS_SUCCESS; -} - /* 7.3.14 */ static enum hci_status bthci_CmdWriteConnectionAcceptTimeout( @@ -2980,11 +2970,6 @@ bthci_CmdReadLinkQuality( return status; } -static enum hci_status bthci_CmdReadRSSI(struct rtw_adapter *padapter) -{ - return HCI_STATUS_SUCCESS; -} - static enum hci_status bthci_CmdCreateLogicalLink( struct rtw_adapter *padapter, @@ -4132,13 +4117,6 @@ bthci_CmdHostBufferSize(struct rtw_adapter *padapter, return status; } -static enum hci_status -bthci_CmdHostNumberOfCompletedPackets(struct rtw_adapter *padapter, - struct packet_irp_hcicmd_data *pHciCmd) -{ - return HCI_STATUS_SUCCESS; -} - static enum hci_status bthci_UnknownCMD(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd) { @@ -4212,7 +4190,6 @@ bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter, break; case HCI_SET_EVENT_FILTER: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_FILTER\n")); - status = bthci_CmdSetEventFilter(padapter, pHciCmd); break; case HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT\n")); @@ -4228,7 +4205,6 @@ bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter, break; case HCI_HOST_NUMBER_OF_COMPLETED_PACKETS: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_NUMBER_OF_COMPLETED_PACKETS\n")); - status = bthci_CmdHostNumberOfCompletedPackets(padapter, pHciCmd); break; case HCI_READ_LINK_SUPERVISION_TIMEOUT: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_SUPERVISION_TIMEOUT\n")); @@ -4316,7 +4292,6 @@ bthci_HandleOGFStatusParameters(struct rtw_adapter *padapter, break; case HCI_READ_RSSI: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_RSSI\n")); - status = bthci_CmdReadRSSI(padapter); break; case HCI_READ_LOCAL_AMP_INFO: RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_INFO\n")); -- GitLab From 0f24cd7062cdb9e45cb05265fa1b9fc619c56084 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 31 Oct 2014 08:41:42 +0530 Subject: [PATCH 2833/9457] Staging: rtl8192e: Use put_unaligned_le16 This patch introduces the use of function put_unaligned_le16. This is done using Coccinelle and semantic patch used is as follows: @@ identifier tmp; expression ptr; expression y,e; type T; @@ - tmp = cpu_to_le16(y); <+... when != tmp - memcpy(ptr, (T)&tmp, ...); + put_unaligned_le16(y,ptr); ...+> ? tmp = e @@ type T; identifier tmp; @@ - T tmp; ...when != tmp Here, to be compatible with the change header file is added too. Signed-off-by: Vaishali Thakkar Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl819x_BAProc.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 2866c1237ae5..66ea79198892 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -16,6 +16,7 @@ * Contact Information: * wlanfae ******************************************************************************/ +#include #include "rtllib.h" #include "rtl819x_BA.h" @@ -79,7 +80,6 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *BAReq = NULL; u8 *tag = NULL; - __le16 tmp = 0; u16 len = ieee->tx_headroom + 9; RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)" @@ -115,15 +115,15 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, if (ACT_ADDBARSP == type) { RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); - tmp = cpu_to_le16(StatusCode); - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(StatusCode, tag); tag += 2; } - tmp = cpu_to_le16(pBA->BaParamSet.shortData); - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(pBA->BaParamSet.shortData, tag); tag += 2; - tmp = cpu_to_le16(pBA->BaTimeoutValue); - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(pBA->BaTimeoutValue, tag); tag += 2; if (ACT_ADDBAREQ == type) { @@ -143,7 +143,6 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *Delba = NULL; u8 *tag = NULL; - __le16 tmp = 0; u16 len = 6 + ieee->tx_headroom; if (net_ratelimit()) @@ -178,11 +177,11 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, *tag++ = ACT_CAT_BA; *tag++ = ACT_DELBA; - tmp = cpu_to_le16(DelbaParamSet.shortData); - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(DelbaParamSet.shortData, tag); tag += 2; - tmp = cpu_to_le16(ReasonCode); - memcpy(tag, (u8 *)&tmp, 2); + + put_unaligned_le16(ReasonCode, tag); tag += 2; RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); -- GitLab From 19e016c39967e23d127517b1d4baf00927870639 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 31 Oct 2014 16:36:18 +0530 Subject: [PATCH 2834/9457] Staging: rtl8192u: Use put_unaligned_le16 This patch introduces the use of function put_unaligned_le16. This is done using Coccinelle and semantic patch used is as follows: @@ identifier tmp; expression ptr; expression y,e; type T; @@ - tmp = cpu_to_le16(y); <+... when != tmp - memcpy(ptr, (T)&tmp, ...); + put_unaligned_le16(y,ptr); ...+> ? tmp = e @@ type T; identifier tmp; @@ - T tmp; ...when != tmp Here, unnecessory comment after change is removed too. This patch also fixes sparse warnings in file ieeee80211_softmac.c. Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 9b874086766f..d1471877e19d 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -804,12 +804,11 @@ static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d *(tag++) = ieee->current_network.channel; if(atim_len){ - u16 val16; *(tag++) = MFIE_TYPE_IBSS_SET; *(tag++) = 2; - //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); - val16 = cpu_to_le16(ieee->current_network.atim_window); - memcpy((u8 *)tag, (u8 *)&val16, 2); + + put_unaligned_le16(ieee->current_network.atim_window, + (u8 *)tag); tag+=2; } -- GitLab From 86ca02dae72562bbd95b21dfc884a9a7d82ac387 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 31 Oct 2014 17:27:54 +0530 Subject: [PATCH 2835/9457] Staging: rtl8188eu: rtw_pwrctrl: fixed checkpatch warning. WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 768dbeee94c4..044d849d10aa 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -577,7 +577,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal if (pwrpriv->ps_processing) { DBG_88E("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) - msleep(10); + usleep_range(1000, 3000); if (pwrpriv->ps_processing) DBG_88E("%s wait ps_processing timeout\n", __func__); else -- GitLab From 1e39898b66b5f3eb515fa8c2cf9ebde6dff8310b Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 31 Oct 2014 17:39:54 +0530 Subject: [PATCH 2836/9457] Staging: rtl8188eu: rtw_pwrctrl: removed a checkpatch warning. WARNING: void function return statements are not generally useful Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 044d849d10aa..8ebef8456f3f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -279,7 +279,6 @@ void rtw_ps_processor(struct adapter *padapter) exit: rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); pwrpriv->ps_processing = false; - return; } static void pwr_state_check_handler(void *FunctionContext) -- GitLab From 2adc8c46b4266bed15c240b6d2721b84734e77ea Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 31 Oct 2014 17:54:12 +0530 Subject: [PATCH 2837/9457] Staging: rtl8188eu: rtw_pwrctrl: removed space before semicolon. WARNING: space prohibited before semicolon Signed-off-by: Surya Seetharaman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_pwrctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c index 8ebef8456f3f..df463a29b641 100644 --- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c @@ -526,7 +526,7 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter) pwrctrlpriv->LpsIdleCount = 0; if (padapter->registrypriv.mp_mode == 1) - pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ; + pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE; else pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false; -- GitLab From 74d443bb2d7b9ca387de3c598962be0d4a46b33d Mon Sep 17 00:00:00 2001 From: Somya Anand Date: Fri, 31 Oct 2014 18:30:32 +0530 Subject: [PATCH 2838/9457] staging: android: logger: Add a TODO A comment about a pre-existing bug data structure definition is added. This bug was evidently introduced by Xiong Zhou in the patch bd471258f2e09 ("staging: android: logger: use kuid_t instead of uid_t") where the code was changed to hide a valid build warning instead of solving the bug that was identified by it. Signed-off-by: Somya Anand Reviewed-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/TODO | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index b15fb0d6b152..06954cdf3dba 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -5,6 +5,13 @@ TODO: - make sure things build as modules properly - add proper arch dependencies as needed - audit userspace interfaces to make sure they are sane + - kuid_t should never be exposed to user space as it is + kernel internal type. Data structure for this kuid_t is: + typedef struct { + uid_t val; + } kuid_t; + - This bug is introduced by Xiong Zhou in the patch bd471258f2e09 + - ("staging: android: logger: use kuid_t instead of uid_t") Please send patches to Greg Kroah-Hartman and Cc: Brian Swetland -- GitLab From 85ebbcca8ac2014d439fd90764e334924ca33ed3 Mon Sep 17 00:00:00 2001 From: Sarah Khan Date: Sat, 1 Nov 2014 04:32:45 +0530 Subject: [PATCH 2839/9457] staging: xgifb: Removed a definition which was not used in driver This patch removes a definition that was not used in driver xgifb Signed-off-by: Sarah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 481eb174fdf0..d9524a2e9ce4 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -7,7 +7,6 @@ #define SupportCRT2in301C 0x0100 /* for 301C */ #define SetCHTVOverScan 0x8000 -#define Panel_320x480 0x07 /*fstn*/ #define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ #define Panel_1024x768x75 0x22 #define Panel_1280x1024x75 0x23 -- GitLab From 2b365fa9d9264faa7ebccf313899d096b228c65a Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 31 Oct 2014 23:39:14 +0530 Subject: [PATCH 2840/9457] Staging: rtl8188eu: Use put_unaligned_le32 This patch introduces the use of function put_unaligned_le32. This is done using Coccinelle and semantic patch used is as follows: @@ identifier tmp; expression ptr; expression y,e; type T; @@ - tmp = cpu_to_le32(y); <+... when != tmp - memcpy(ptr, (T)&tmp, ...); + put_unaligned_le32(y,ptr); ...+> ? tmp = e @@ type T; identifier tmp; @@ - T tmp; ...when != tmp Signed-off-by: Vaishali Thakkar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index 023a3d84ee8b..ce55d9d9f0f6 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -150,11 +150,9 @@ u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) struct hal_data_8188e *haldata = GET_HAL_DATA(adapt); if (haldata->fw_ractrl) { - __le32 lmask; memset(buf, 0, 3); - lmask = cpu_to_le32(mask); - memcpy(buf, &lmask, 3); + put_unaligned_le32(mask, buf); FillH2CCmd_88E(adapt, H2C_DM_MACID_CFG, 3, buf); } else { -- GitLab From eb3a13230b78c3dc580b509e370862c632c90dae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:10:50 -0700 Subject: [PATCH 2841/9457] staging: comedi: comedi_buf: make comedi_buf_write_samples() add samples that fit This function currently fails if the number of samples to add would overflow the async buffer. Modify it to add the samples that fit so at least some of the sample data is returned to the user. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 6dd87cb2a8af..b43424d611ad 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -484,12 +484,16 @@ unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, unsigned int max_samples; unsigned int nbytes; - /* make sure there is enought room in the buffer for all the samples */ + /* + * Make sure there is enough room in the buffer for all the samples. + * If not, clamp the nsamples to the number that will fit, flag the + * buffer overrun and add the samples that fit. + */ max_samples = comedi_buf_write_n_available(s) / bytes_per_sample(s); if (nsamples > max_samples) { dev_warn(s->device->class_dev, "buffer overrun\n"); s->async->events |= COMEDI_CB_OVERFLOW; - return 0; + nsamples = max_samples; } if (nsamples == 0) -- GitLab From e6245fc78b65a5492c7480d665cebb89082824f9 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 17:19:12 +0200 Subject: [PATCH 2842/9457] imx-drm: ipuv3-plane: allow local alpha in ipu_plane_mode_set() For the overlay plane scanning out a framebuffer with an alpha component, enable the DP local alpha feature on the partial plane. Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-plane.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 944962b692bb..48cbeef73934 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -148,14 +148,22 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, ret); return ret; } - ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1); + ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); break; case IPU_DP_FLOW_SYNC_FG: ipu_dp_setup_channel(ipu_plane->dp, ipu_drm_fourcc_to_colorspace(fb->pixel_format), IPUV3_COLORSPACE_UNKNOWN); ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y); - break; + /* Enable local alpha on partial plane */ + switch (fb->pixel_format) { + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false); + break; + default: + break; + } } ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w); -- GitLab From 7cd9bebee609c4a2e382ad5089f1c24e6098f493 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 17:19:13 +0200 Subject: [PATCH 2843/9457] imx-drm: ipuv3-plane: move stride setting out of base setup Setting the stride can only be done on inactive channels, while the buffer base address can also be updated for running channels using the hardware double buffering feature. Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-plane.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 48cbeef73934..85f49e6fdee9 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -74,8 +74,6 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", &cma_obj->paddr, x, y); - ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); - eba = cma_obj->paddr + fb->offsets[0] + fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); @@ -189,6 +187,7 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, return ret; } ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); + ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y); if (ret < 0) -- GitLab From 356f952472f24b3677f191f534479d7d1be0183e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 17:19:14 +0200 Subject: [PATCH 2844/9457] imx-drm: ipuv3-plane: enable double buffering This allows to update the buffer base address while the DMA channel is running. It is needed to flip the frame buffer of an active plane. Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-plane.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 85f49e6fdee9..16134d9c4054 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -64,6 +64,7 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, { struct drm_gem_cma_object *cma_obj; unsigned long eba; + int active; cma_obj = drm_fb_cma_get_gem_obj(fb, 0); if (!cma_obj) { @@ -76,8 +77,15 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, eba = cma_obj->paddr + fb->offsets[0] + fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; - ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); - ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); + + if (ipu_plane->enabled) { + active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); + ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); + } else { + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); + ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); + } /* cache offsets for subsequent pageflips */ ipu_plane->x = x; @@ -187,6 +195,7 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, return ret; } ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); + ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1); ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y); -- GitLab From 9a6660308c44a4fb8f7d6bcec6e4fb4c9afa4750 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 8 Oct 2014 17:19:15 +0200 Subject: [PATCH 2845/9457] imx-drm: ipuv3-plane: fix plane updates for active planes While the DMA channel is running, it is not allowed to change anything but the inactive (double) buffer base address, so resizing a plane or changing to a frame buffer with different pixel format is not possible. Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-plane.c | 15 +++++++++++++++ drivers/staging/imx-drm/ipuv3-plane.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 16134d9c4054..6987e16fe99b 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -143,6 +143,18 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, if (crtc_h < 2) return -EINVAL; + /* + * since we cannot touch active IDMAC channels, we do not support + * resizing the enabled plane or changing its format + */ + if (ipu_plane->enabled) { + if (src_w != ipu_plane->w || src_h != ipu_plane->h || + fb->pixel_format != ipu_plane->base.fb->pixel_format) + return -EINVAL; + + return ipu_plane_set_base(ipu_plane, fb, src_x, src_y); + } + switch (ipu_plane->dp_flow) { case IPU_DP_FLOW_SYNC_BG: ret = ipu_dp_setup_channel(ipu_plane->dp, @@ -202,6 +214,9 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, if (ret < 0) return ret; + ipu_plane->w = src_w; + ipu_plane->h = src_h; + return 0; } diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/staging/imx-drm/ipuv3-plane.h index c0aae5bcb5d4..af125fb40ef5 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.h +++ b/drivers/staging/imx-drm/ipuv3-plane.h @@ -26,6 +26,8 @@ struct ipu_plane { int x; int y; + int w; + int h; bool enabled; }; -- GitLab From 161f6d8ff31e232dbc915c5ea51cb72b4676219a Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 9 Oct 2014 15:21:17 +0200 Subject: [PATCH 2846/9457] imx-drm: currently only IPUv3 is supported, make it mandatory As long as only IPUv3 is supported in imx-drm, hide the separate DRM_IMX_IPUV3 option and make DRM_IMX depend on IMX_IPUV3_CORE. Reported-by: Michael Olbrich Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 82fb758a29bc..ab31848e92cf 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -6,6 +6,7 @@ config DRM_IMX select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) + depends on IMX_IPUV3_CORE help enable i.MX graphics support @@ -40,11 +41,11 @@ config DRM_IMX_LDB found on i.MX53 and i.MX6 processors. config DRM_IMX_IPUV3 - tristate "DRM Support for i.MX IPUv3" + tristate depends on DRM_IMX depends on IMX_IPUV3_CORE - help - Choose this if you have a i.MX5 or i.MX6 processor. + default y if DRM_IMX=y + default m if DRM_IMX=m config DRM_IMX_HDMI tristate "Freescale i.MX DRM HDMI" -- GitLab From ad92c8bfff579165739705235d0909ebc94de2cd Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 3 Nov 2014 15:54:47 +0100 Subject: [PATCH 2847/9457] imx-drm: parallel-display: Fix drm_panel support Call drm_panel_enable/disable in reaction to encoder_commit and encoder_disable callbacks. Signed-off-by: Philipp Zabel Signed-off-by: Markus Pargmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/parallel-display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 015a454b87e1..ac89a18b8332 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -128,6 +128,10 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder) static void imx_pd_encoder_commit(struct drm_encoder *encoder) { + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + drm_panel_prepare(imxpd->panel); + drm_panel_enable(imxpd->panel); } static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, @@ -138,6 +142,10 @@ static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, static void imx_pd_encoder_disable(struct drm_encoder *encoder) { + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + drm_panel_disable(imxpd->panel); + drm_panel_unprepare(imxpd->panel); } static struct drm_connector_funcs imx_pd_connector_funcs = { -- GitLab From f8e4df53c785a3c19650e57b5c514a4b50d82078 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Oct 2014 21:42:19 -0300 Subject: [PATCH 2848/9457] imx-drm: imx-drm-core: Remove unneeded forward declaration There is no need to forward declare 'struct imx_drm_crtc' because the "imx-drm.h" header file already includes it. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/imx-drm-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 3ca1acdae72b..8510937ff6fc 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -29,8 +29,6 @@ #define MAX_CRTC 4 -struct imx_drm_crtc; - struct imx_drm_component { struct device_node *of_node; struct list_head list; -- GitLab From d0915b2255bfbdd537fd6a52f9a0a7037ecbe2d5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 31 Oct 2014 13:40:39 +0300 Subject: [PATCH 2849/9457] staging: r8188eu: get a string from the user correctly The original code had two bugs: 1) It didn't check if the string was zero length so it could oops when it tried to dereference the ZERO_SIZE_PTR. 2) It didn't enforce that the string was NUL terminated. It was also messy as pants. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/os_dep/rtw_android.c | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index d9d55d12fd5f..b40317822aed 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -162,22 +162,12 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) ret = -EFAULT; goto exit; } - command = kmalloc(priv_cmd.total_len, GFP_KERNEL); - if (!command) { - DBG_88E("%s: failed to allocate memory\n", __func__); - ret = -ENOMEM; - goto exit; - } - if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) { - DBG_88E("%s: failed to access memory\n", __func__); - ret = -EFAULT; - goto exit; - } - if (copy_from_user(command, (char __user *)priv_cmd.buf, - priv_cmd.total_len)) { - ret = -EFAULT; - goto exit; - } + if (priv_cmd.total_len < 1) + return -EINVAL; + command = memdup_user(priv_cmd.buf, priv_cmd.total_len); + if (IS_ERR(command)) + return PTR_ERR(command); + command[priv_cmd.total_len - 1] = 0; DBG_88E("%s: Android private cmd \"%s\" on %s\n", __func__, command, ifr->ifr_name); cmd_num = rtw_android_cmdstr_to_num(command); -- GitLab From 85e1c554f4c80d1afec6069b4dad0a7bf6ce9b3d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 31 Oct 2014 13:41:05 +0300 Subject: [PATCH 2850/9457] staging: r8188eu: cleanups in rtw_android_set_block() 1) We can tighten up the code a little by returning directly and it makes the code more future proof and easier to read. 2) "free" is a better name than "exit". 3) sizeof(priv_cmd) is shorter and more clear than sizeof(struct android_wifi_priv_cmd). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/os_dep/rtw_android.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index b40317822aed..99ce077007f4 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c @@ -148,20 +148,15 @@ static int rtw_android_set_block(struct net_device *net, char *command, int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { int ret = 0; - char *command = NULL; + char *command; int cmd_num; int bytes_written = 0; struct android_wifi_priv_cmd priv_cmd; - if (!ifr->ifr_data) { - ret = -EINVAL; - goto exit; - } - if (copy_from_user(&priv_cmd, ifr->ifr_data, - sizeof(struct android_wifi_priv_cmd))) { - ret = -EFAULT; - goto exit; - } + if (!ifr->ifr_data) + return -EINVAL; + if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(priv_cmd))) + return -EFAULT; if (priv_cmd.total_len < 1) return -EINVAL; command = memdup_user(priv_cmd.buf, priv_cmd.total_len); @@ -181,7 +176,7 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) DBG_88E("%s: Ignore private cmd \"%s\" - iface %s is down\n", __func__, command, ifr->ifr_name); ret = 0; - goto exit; + goto free; } switch (cmd_num) { case ANDROID_WIFI_CMD_STOP: @@ -269,7 +264,7 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) } else { ret = bytes_written; } -exit: +free: kfree(command); return ret; } -- GitLab From dafe271690457f3c44844c0da0942d282c73e58f Mon Sep 17 00:00:00 2001 From: Mariusz Gorski Date: Sat, 1 Nov 2014 11:52:11 +0100 Subject: [PATCH 2851/9457] staging: panel: Remove outdated TODO task Remove Lindent task from TODO file as it's obsolete. Signed-off-by: Mariusz Gorski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/panel/TODO b/drivers/staging/panel/TODO index a4be749bcdfc..2db3f994b632 100644 --- a/drivers/staging/panel/TODO +++ b/drivers/staging/panel/TODO @@ -1,6 +1,5 @@ TODO: - checkpatch.pl cleanups - - Lindent - review major/minor usages - review userspace api - see if all of this could be easier done in userspace instead. -- GitLab From bc47e7d97666ad32993abe0ea924ffa81a8356e7 Mon Sep 17 00:00:00 2001 From: Tristan Lelong Date: Fri, 31 Oct 2014 16:31:31 -0700 Subject: [PATCH 2852/9457] Staging: android: ion: fix typos in comments s/comming/coming/ in drivers/staging/android/ion/ion.c s/specfic/specific/ in drivers/staging/android/ion/ion.h s/peformance/performance/ in drivers/staging/android/ion/ion_priv.h Signed-off-by: Tristan Lelong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion.c | 2 +- drivers/staging/android/ion/ion.h | 2 +- drivers/staging/android/ion/ion_priv.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 290d4d22c102..8724ef89ce94 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -250,7 +250,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, our systems the only dma_address space is physical addresses. Additionally, we can't afford the overhead of invalidating every allocation via dma_map_sg. The implicit contract here is that - memory comming from the heaps is ready for dma, ie if it has a + memory coming from the heaps is ready for dma, ie if it has a cached mapping that mapping has been invalidated */ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) sg_dma_address(sg) = sg_phys(sg); diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index d305bb7e9a74..443db8459a9e 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -76,7 +76,7 @@ struct ion_platform_data { * size * * Calls memblock reserve to set aside memory for heaps that are - * located at specific memory addresses or of specfic sizes not + * located at specific memory addresses or of specific sizes not * managed by the kernel */ void ion_reserve(struct ion_platform_data *data); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index c8f01757abfa..18a5f93e13b7 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -345,7 +345,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, * functions for creating and destroying a heap pool -- allows you * to keep a pool of pre allocated memory to use from your heap. Keeping * a pool of memory that is ready for dma, ie any cached mapping have been - * invalidated from the cache, provides a significant peformance benefit on + * invalidated from the cache, provides a significant performance benefit on * many systems */ /** @@ -362,7 +362,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, * * Allows you to keep a pool of pre allocated pages to use from your heap. * Keeping a pool of pages that is ready for dma, ie any cached mapping have - * been invalidated from the cache, provides a significant peformance benefit + * been invalidated from the cache, provides a significant performance benefit * on many systems */ struct ion_page_pool { -- GitLab From 769971b2a45400a3c18632979dce30c6f9d3892a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Oct 2014 21:41:30 +0200 Subject: [PATCH 2853/9457] stating: rtl8723au: Eliminate write-only struct xmit_priv->txirp_cnt Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_xmit.c | 2 -- drivers/staging/rtl8723au/include/rtw_xmit.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c index 4c2f0a1201bf..a0f7e2787afe 100644 --- a/drivers/staging/rtl8723au/core/rtw_xmit.c +++ b/drivers/staging/rtl8723au/core/rtw_xmit.c @@ -180,8 +180,6 @@ int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv, for (i = 0; i < 4; i ++) pxmitpriv->wmm_para_seq[i] = i; - pxmitpriv->txirp_cnt = 1; - sema_init(&pxmitpriv->tx_retevt, 0); pxmitpriv->ack_tx = false; diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h index abe4316b9124..73e5f9cbfac0 100644 --- a/drivers/staging/rtl8723au/include/rtw_xmit.h +++ b/drivers/staging/rtl8723au/include/rtw_xmit.h @@ -312,7 +312,6 @@ struct xmit_priv { */ struct semaphore tx_retevt;/* all tx return event; */ - u8 txirp_cnt;/* */ struct tasklet_struct xmit_tasklet; -- GitLab From 0b2cf5c8402bb313c0054b2cd7df5ca50f250a1d Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Fri, 31 Oct 2014 10:20:37 +0900 Subject: [PATCH 2854/9457] staging: dgap: re-arrange functions for removing forward declarations Re-arrange the functions for removing forward declarations. Signed-off-by: Daeseok Youn Tested-by: Mark Hounschell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 10805 +++++++++++++++++----------------- 1 file changed, 5340 insertions(+), 5465 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index ed356f1bdece..293dc3320b3a 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -65,145 +65,6 @@ #include "dgap.h" -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Digi International, http://www.digi.com"); -MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line"); -MODULE_SUPPORTED_DEVICE("dgap"); - -static int dgap_start(void); -static void dgap_stop(void); -static void dgap_init_globals(void); -static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, - int boardnum); -static void dgap_cleanup_board(struct board_t *brd); -static void dgap_poll_handler(ulong dummy); -static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void dgap_remove_one(struct pci_dev *dev); -static int dgap_remap(struct board_t *brd); -static void dgap_unmap(struct board_t *brd); -static irqreturn_t dgap_intr(int irq, void *voidbrd); - -static int dgap_tty_open(struct tty_struct *tty, struct file *file); -static void dgap_tty_close(struct tty_struct *tty, struct file *file); -static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, - struct channel_t *ch); -static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg); -static int dgap_tty_digigeta(struct channel_t *ch, - struct digi_t __user *retinfo); -static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd, - struct un_t *un, struct digi_t __user *new_info); -static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo); -static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info); -static int dgap_tty_write_room(struct tty_struct *tty); -static int dgap_tty_chars_in_buffer(struct tty_struct *tty); -static void dgap_tty_start(struct tty_struct *tty); -static void dgap_tty_stop(struct tty_struct *tty); -static void dgap_tty_throttle(struct tty_struct *tty); -static void dgap_tty_unthrottle(struct tty_struct *tty); -static void dgap_tty_flush_chars(struct tty_struct *tty); -static void dgap_tty_flush_buffer(struct tty_struct *tty); -static void dgap_tty_hangup(struct tty_struct *tty); -static int dgap_wait_for_drain(struct tty_struct *tty); -static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, - struct un_t *un, unsigned int command, - unsigned int __user *value); -static int dgap_get_modem_info(struct channel_t *ch, - unsigned int __user *value); -static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info); -static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un, - int __user *retinfo); -static int dgap_tty_tiocmget(struct tty_struct *tty); -static int dgap_tty_tiocmset(struct tty_struct *tty, unsigned int set, - unsigned int clear); -static int dgap_tty_send_break(struct tty_struct *tty, int msec); -static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout); -static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count); -static void dgap_tty_set_termios(struct tty_struct *tty, - struct ktermios *old_termios); -static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c); -static void dgap_tty_send_xchar(struct tty_struct *tty, char ch); - -static int dgap_tty_register(struct board_t *brd); -static void dgap_tty_unregister(struct board_t *brd); -static int dgap_tty_init(struct board_t *); -static void dgap_tty_free(struct board_t *); -static void dgap_cleanup_tty(struct board_t *); -static void dgap_carrier(struct channel_t *ch); -static void dgap_input(struct channel_t *ch); - -/* - * Our function prototypes from dgap_fep5 - */ -static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds); -static int dgap_event(struct board_t *bd); - -static void dgap_poll_tasklet(unsigned long data); -static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, - u8 byte2, uint ncmds); -static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds); -static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt); -static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type); -static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, - unsigned char *fbuf, int *len); -static uint dgap_get_custom_baud(struct channel_t *ch); -static void dgap_firmware_reset_port(struct channel_t *ch); - -/* - * Function prototypes from dgap_parse.c. - */ -static int dgap_gettok(char **in); -static char *dgap_getword(char **in); -static int dgap_checknode(struct cnode *p); - -/* - * Function prototypes from dgap_sysfs.h - */ -static void dgap_create_ports_sysfiles(struct board_t *bd); -static void dgap_remove_ports_sysfiles(struct board_t *bd); - -static int dgap_create_driver_sysfiles(struct pci_driver *); -static void dgap_remove_driver_sysfiles(struct pci_driver *); - -static void dgap_create_tty_sysfs(struct un_t *un, struct device *c); -static void dgap_remove_tty_sysfs(struct device *c); - -/* - * Function prototypes from dgap_parse.h - */ -static int dgap_parsefile(char **in); -static struct cnode *dgap_find_config(int type, int bus, int slot); -static uint dgap_config_get_num_prts(struct board_t *bd); -static char *dgap_create_config_string(struct board_t *bd, char *string); -static uint dgap_config_get_useintr(struct board_t *bd); -static uint dgap_config_get_altpin(struct board_t *bd); - -static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len); -static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len); -#ifdef DIGI_CONCENTRATORS_SUPPORTED -static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len); -#endif -static int dgap_alloc_flipbuf(struct board_t *brd); -static void dgap_free_flipbuf(struct board_t *brd); -static int dgap_request_irq(struct board_t *brd); -static void dgap_free_irq(struct board_t *brd); - -static void dgap_get_vpd(struct board_t *brd); -static void dgap_do_reset_board(struct board_t *brd); -static int dgap_test_bios(struct board_t *brd); -static int dgap_test_fep(struct board_t *brd); -static int dgap_tty_register_ports(struct board_t *brd); -static int dgap_firmware_load(struct pci_dev *pdev, int card_type, - struct board_t *brd); -static void dgap_cleanup_nodes(void); - -static void dgap_cleanup_module(void); - -module_exit(dgap_cleanup_module); - /* * File operations permitted on Control/Management major. */ @@ -298,13 +159,6 @@ static struct board_id dgap_ids[] = { {0,} /* 0 terminated list. */ }; -static struct pci_driver dgap_driver = { - .name = "dgap", - .probe = dgap_init_one, - .id_table = dgap_pci_tbl, - .remove = dgap_remove_one, -}; - struct firmware_info { u8 *conf_name; /* dgap.conf */ u8 *bios_name; /* BIOS filename */ @@ -367,29 +221,6 @@ static struct ktermios dgap_default_termios = { .c_line = 0, }; -static const struct tty_operations dgap_tty_ops = { - .open = dgap_tty_open, - .close = dgap_tty_close, - .write = dgap_tty_write, - .write_room = dgap_tty_write_room, - .flush_buffer = dgap_tty_flush_buffer, - .chars_in_buffer = dgap_tty_chars_in_buffer, - .flush_chars = dgap_tty_flush_chars, - .ioctl = dgap_tty_ioctl, - .set_termios = dgap_tty_set_termios, - .stop = dgap_tty_stop, - .start = dgap_tty_start, - .throttle = dgap_tty_throttle, - .unthrottle = dgap_tty_unthrottle, - .hangup = dgap_tty_hangup, - .put_char = dgap_tty_put_char, - .tiocmget = dgap_tty_tiocmget, - .tiocmset = dgap_tty_tiocmset, - .break_ctl = dgap_tty_send_break, - .wait_until_sent = dgap_tty_wait_until_sent, - .send_xchar = dgap_tty_send_xchar -}; - /* * Our needed internal static variables from dgap_parse.c */ @@ -457,3104 +288,2909 @@ static struct toklist dgap_tlist[] = { { 0, NULL } }; -/************************************************************************ - * - * Driver load/unload functions - * - ************************************************************************/ /* - * init_module() - * - * Module load. This is where it all starts. + * dgap_sindex: much like index(), but it looks for a match of any character in + * the group, and returns that position. If the first character is a ^, then + * this will match the first occurrence not in that group. */ -static int dgap_init_module(void) +static char *dgap_sindex(char *string, char *group) { - int rc; - - pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART); - - rc = dgap_start(); - if (rc) - return rc; - - rc = pci_register_driver(&dgap_driver); - if (rc) - goto err_stop; - - rc = dgap_create_driver_sysfiles(&dgap_driver); - if (rc) - goto err_unregister; - - dgap_driver_state = DRIVER_READY; + char *ptr; - return 0; + if (!string || !group) + return NULL; -err_unregister: - pci_unregister_driver(&dgap_driver); -err_stop: - dgap_stop(); + if (*group == '^') { + group++; + for (; *string; string++) { + for (ptr = group; *ptr; ptr++) { + if (*ptr == *string) + break; + } + if (*ptr == '\0') + return string; + } + } else { + for (; *string; string++) { + for (ptr = group; *ptr; ptr++) { + if (*ptr == *string) + return string; + } + } + } - return rc; + return NULL; } -module_init(dgap_init_module); /* - * Start of driver. + * get a word from the input stream, also keep track of current line number. + * words are separated by whitespace. */ -static int dgap_start(void) +static char *dgap_getword(char **in) { - int rc; - unsigned long flags; - struct device *device; - - /* - * make sure that the globals are - * init'd before we do anything else - */ - dgap_init_globals(); - - dgap_numboards = 0; - - pr_info("For the tools package please visit http://www.digi.com\n"); + char *ret_ptr = *in; - /* - * Register our base character device into the kernel. - */ + char *ptr = dgap_sindex(*in, " \t\n"); - /* - * Register management/dpa devices - */ - rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops); - if (rc < 0) - return rc; + /* If no word found, return null */ + if (!ptr) + return NULL; - dgap_class = class_create(THIS_MODULE, "dgap_mgmt"); - if (IS_ERR(dgap_class)) { - rc = PTR_ERR(dgap_class); - goto failed_class; - } + /* Mark new location for our buffer */ + *ptr = '\0'; + *in = ptr + 1; - device = device_create(dgap_class, NULL, - MKDEV(DIGI_DGAP_MAJOR, 0), - NULL, "dgap_mgmt"); - if (IS_ERR(device)) { - rc = PTR_ERR(device); - goto failed_device; + /* Eat any extra spaces/tabs/newlines that might be present */ + while (*in && **in && ((**in == ' ') || + (**in == '\t') || + (**in == '\n'))) { + **in = '\0'; + *in = *in + 1; } - /* Start the poller */ - spin_lock_irqsave(&dgap_poll_lock, flags); - init_timer(&dgap_poll_timer); - dgap_poll_timer.function = dgap_poll_handler; - dgap_poll_timer.data = 0; - dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick); - dgap_poll_timer.expires = dgap_poll_time; - spin_unlock_irqrestore(&dgap_poll_lock, flags); - - add_timer(&dgap_poll_timer); - - return rc; - -failed_device: - class_destroy(dgap_class); -failed_class: - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); - return rc; + return ret_ptr; } -static void dgap_stop(void) -{ - unsigned long lock_flags; - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_stop = 1; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); +/* + * Get a token from the input file; return 0 if end of file is reached + */ +static int dgap_gettok(char **in) +{ + char *w; + struct toklist *t; - del_timer_sync(&dgap_poll_timer); + if (strstr(dgap_cword, "board")) { + w = dgap_getword(in); + snprintf(dgap_cword, MAXCWORD, "%s", w); + for (t = dgap_brdtype; t->token != 0; t++) { + if (!strcmp(w, t->string)) + return t->token; + } + } else { + while ((w = dgap_getword(in))) { + snprintf(dgap_cword, MAXCWORD, "%s", w); + for (t = dgap_tlist; t->token != 0; t++) { + if (!strcmp(w, t->string)) + return t->token; + } + } + } - device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); - class_destroy(dgap_class); - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + return 0; } -static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +/* + * dgap_checknode: see if all the necessary info has been supplied for a node + * before creating the next node. + */ +static int dgap_checknode(struct cnode *p) { - int rc; - struct board_t *brd; - - if (dgap_numboards >= MAXBOARDS) - return -EPERM; + switch (p->type) { + case LNODE: + if (p->u.line.v_speed == 0) { + pr_err("line speed not specified"); + return 1; + } + return 0; - rc = pci_enable_device(pdev); - if (rc) - return -EIO; - - brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards); - if (IS_ERR(brd)) - return PTR_ERR(brd); - - rc = dgap_firmware_load(pdev, ent->driver_data, brd); - if (rc) - goto cleanup_brd; - - rc = dgap_alloc_flipbuf(brd); - if (rc) - goto cleanup_brd; - - rc = dgap_tty_register(brd); - if (rc) - goto free_flipbuf; - - rc = dgap_request_irq(brd); - if (rc) - goto unregister_tty; + case CNODE: + if (p->u.conc.v_speed == 0) { + pr_err("concentrator line speed not specified"); + return 1; + } + if (p->u.conc.v_nport == 0) { + pr_err("number of ports on concentrator not specified"); + return 1; + } + if (p->u.conc.v_id == 0) { + pr_err("concentrator id letter not specified"); + return 1; + } + return 0; - /* - * Do tty device initialization. - */ - rc = dgap_tty_init(brd); - if (rc < 0) - goto free_irq; + case MNODE: + if (p->u.module.v_nport == 0) { + pr_err("number of ports on EBI module not specified"); + return 1; + } + if (p->u.module.v_id == 0) { + pr_err("EBI module id letter not specified"); + return 1; + } + return 0; + } + return 0; +} - rc = dgap_tty_register_ports(brd); - if (rc) - goto tty_free; +/* + * Given a board pointer, returns whether we should use interrupts or not. + */ +static uint dgap_config_get_useintr(struct board_t *bd) +{ + struct cnode *p; - brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; + if (!bd) + return 0; - dgap_board[dgap_numboards++] = brd; + for (p = bd->bd_config; p; p = p->next) { + if (p->type == INTRNODE) { + /* + * check for pcxr types. + */ + return p->u.useintr; + } + } + /* If not found, then don't turn on interrupts. */ return 0; - -tty_free: - dgap_tty_free(brd); -free_irq: - dgap_free_irq(brd); -unregister_tty: - dgap_tty_unregister(brd); -free_flipbuf: - dgap_free_flipbuf(brd); -cleanup_brd: - dgap_cleanup_nodes(); - dgap_unmap(brd); - kfree(brd); - - return rc; -} - -static void dgap_remove_one(struct pci_dev *dev) -{ - /* Do Nothing */ } /* - * dgap_cleanup_module() - * - * Module unload. This is where it all ends. + * Given a board pointer, returns whether we turn on altpin or not. */ -static void dgap_cleanup_module(void) +static uint dgap_config_get_altpin(struct board_t *bd) { - unsigned int i; - ulong lock_flags; - - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_stop = 1; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgap_poll_timer); - - dgap_remove_driver_sysfiles(&dgap_driver); + struct cnode *p; - device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); - class_destroy(dgap_class); - unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + if (!bd) + return 0; - for (i = 0; i < dgap_numboards; ++i) { - dgap_remove_ports_sysfiles(dgap_board[i]); - dgap_cleanup_tty(dgap_board[i]); - dgap_cleanup_board(dgap_board[i]); + for (p = bd->bd_config; p; p = p->next) { + if (p->type == ANODE) { + /* + * check for pcxr types. + */ + return p->u.altpin; + } } - dgap_cleanup_nodes(); - - if (dgap_numboards) - pci_unregister_driver(&dgap_driver); + /* If not found, then don't turn on interrupts. */ + return 0; } /* - * dgap_cleanup_board() - * - * Free all the memory associated with a board + * Given a specific type of board, if found, detached link and + * returns the first occurrence in the list. */ -static void dgap_cleanup_board(struct board_t *brd) +static struct cnode *dgap_find_config(int type, int bus, int slot) { - unsigned int i; + struct cnode *p, *prev, *prev2, *found; - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return; + p = &dgap_head; - dgap_free_irq(brd); + while (p->next) { + prev = p; + p = p->next; - tasklet_kill(&brd->helper_tasklet); + if (p->type != BNODE) + continue; - dgap_unmap(brd); + if (p->u.board.type != type) + continue; - /* Free all allocated channels structs */ - for (i = 0; i < MAXPORTS ; i++) - kfree(brd->channels[i]); + if (p->u.board.v_pcibus && + p->u.board.pcibus != bus) + continue; - kfree(brd->flipbuf); - kfree(brd->flipflagbuf); + if (p->u.board.v_pcislot && + p->u.board.pcislot != slot) + continue; - dgap_board[brd->boardnum] = NULL; + found = p; + /* + * Keep walking thru the list till we + * find the next board. + */ + while (p->next) { + prev2 = p; + p = p->next; - kfree(brd); + if (p->type != BNODE) + continue; + + /* + * Mark the end of our 1 board + * chain of configs. + */ + prev2->next = NULL; + + /* + * Link the "next" board to the + * previous board, effectively + * "unlinking" our board from + * the main config. + */ + prev->next = p; + + return found; + } + /* + * It must be the last board in the list. + */ + prev->next = NULL; + return found; + } + return NULL; } /* - * dgap_found_board() - * - * A board has been found, init it. + * Given a board pointer, walks the config link, counting up + * all ports user specified should be on the board. + * (This does NOT mean they are all actually present right now tho) */ -static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, - int boardnum) +static uint dgap_config_get_num_prts(struct board_t *bd) { - struct board_t *brd; - unsigned int pci_irq; - int i; - int ret; - - /* get the board structure and prep it */ - brd = kzalloc(sizeof(struct board_t), GFP_KERNEL); - if (!brd) - return ERR_PTR(-ENOMEM); - - /* store the info for the board we've found */ - brd->magic = DGAP_BOARD_MAGIC; - brd->boardnum = boardnum; - brd->vendor = dgap_pci_tbl[id].vendor; - brd->device = dgap_pci_tbl[id].device; - brd->pdev = pdev; - brd->pci_bus = pdev->bus->number; - brd->pci_slot = PCI_SLOT(pdev->devfn); - brd->name = dgap_ids[id].name; - brd->maxports = dgap_ids[id].maxports; - brd->type = dgap_ids[id].config_type; - brd->dpatype = dgap_ids[id].dpatype; - brd->dpastatus = BD_NOFEP; - init_waitqueue_head(&brd->state_wait); - - spin_lock_init(&brd->bd_lock); - - brd->inhibit_poller = FALSE; - brd->wait_for_bios = 0; - brd->wait_for_fep = 0; + int count = 0; + struct cnode *p; - for (i = 0; i < MAXPORTS; i++) - brd->channels[i] = NULL; + if (!bd) + return 0; - /* store which card & revision we have */ - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice); - pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); + for (p = bd->bd_config; p; p = p->next) { - pci_irq = pdev->irq; - brd->irq = pci_irq; - - /* get the PCI Base Address Registers */ - - /* Xr Jupiter and EPC use BAR 2 */ - if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) { - brd->membase = pci_resource_start(pdev, 2); - brd->membase_end = pci_resource_end(pdev, 2); - } - /* Everyone else uses BAR 0 */ - else { - brd->membase = pci_resource_start(pdev, 0); - brd->membase_end = pci_resource_end(pdev, 0); - } - - if (!brd->membase) { - ret = -ENODEV; - goto free_brd; + switch (p->type) { + case BNODE: + /* + * check for pcxr types. + */ + if (p->u.board.type > EPCFE) + count += p->u.board.nport; + break; + case CNODE: + count += p->u.conc.nport; + break; + case MNODE: + count += p->u.module.nport; + break; + } } + return count; +} - if (brd->membase & 1) - brd->membase &= ~3; - else - brd->membase &= ~15; - - /* - * On the PCI boards, there is no IO space allocated - * The I/O registers will be in the first 3 bytes of the - * upper 2MB of the 4MB memory space. The board memory - * will be mapped into the low 2MB of the 4MB memory space - */ - brd->port = brd->membase + PCI_IO_OFFSET; - brd->port_end = brd->port + PCI_IO_SIZE; - - /* - * Special initialization for non-PLX boards - */ - if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) { - unsigned short cmd; - - pci_write_config_byte(pdev, 0x40, 0); - pci_write_config_byte(pdev, 0x46, 0); - - /* Limit burst length to 2 doubleword transactions */ - pci_write_config_byte(pdev, 0x42, 1); +static char *dgap_create_config_string(struct board_t *bd, char *string) +{ + char *ptr = string; + struct cnode *p; + struct cnode *q; + int speed; - /* - * Enable IO and mem if not already done. - * This was needed for support on Itanium. - */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(pdev, PCI_COMMAND, cmd); + if (!bd) { + *ptr = 0xff; + return string; } - /* init our poll helper tasklet */ - tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet, - (unsigned long) brd); - - ret = dgap_remap(brd); - if (ret) - goto free_brd; - - pr_info("dgap: board %d: %s (rev %d), irq %ld\n", - boardnum, brd->name, brd->rev, brd->irq); + for (p = bd->bd_config; p; p = p->next) { - return brd; + switch (p->type) { + case LNODE: + *ptr = '\0'; + ptr++; + *ptr = p->u.line.speed; + ptr++; + break; + case CNODE: + /* + * Because the EPC/con concentrators can have EM modules + * hanging off of them, we have to walk ahead in the + * list and keep adding the number of ports on each EM + * to the config. UGH! + */ + speed = p->u.conc.speed; + q = p->next; + if (q && (q->type == MNODE)) { + *ptr = (p->u.conc.nport + 0x80); + ptr++; + p = q; + while (q->next && (q->next->type) == MNODE) { + *ptr = (q->u.module.nport + 0x80); + ptr++; + p = q; + q = q->next; + } + *ptr = q->u.module.nport; + ptr++; + } else { + *ptr = p->u.conc.nport; + ptr++; + } -free_brd: - kfree(brd); + *ptr = speed; + ptr++; + break; + } + } - return ERR_PTR(ret); + *ptr = 0xff; + return string; } - -static int dgap_request_irq(struct board_t *brd) +/* + * Parse a configuration file read into memory as a string. + */ +static int dgap_parsefile(char **in) { + struct cnode *p, *brd, *line, *conc; int rc; + char *s; + int linecnt = 0; - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return -ENODEV; - - /* - * Set up our interrupt handler if we are set to do interrupts. - */ - if (dgap_config_get_useintr(brd) && brd->irq) { + p = &dgap_head; + brd = line = conc = NULL; - rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd); + /* perhaps we are adding to an existing list? */ + while (p->next) + p = p->next; - if (!rc) - brd->intr_used = 1; + /* file must start with a BEGIN */ + while ((rc = dgap_gettok(in)) != BEGIN) { + if (rc == 0) { + pr_err("unexpected EOF"); + return -1; + } } - return 0; -} -static void dgap_free_irq(struct board_t *brd) -{ - if (brd->intr_used && brd->irq) - free_irq(brd->irq, brd); -} + for (; ;) { + int board_type = 0; + int conc_type = 0; + int module_type = 0; -static int dgap_firmware_load(struct pci_dev *pdev, int card_type, - struct board_t *brd) -{ - const struct firmware *fw; - char *tmp_ptr; - int ret; - char *dgap_config_buf; + rc = dgap_gettok(in); + if (rc == 0) { + pr_err("unexpected EOF"); + return -1; + } - dgap_get_vpd(brd); - dgap_do_reset_board(brd); + switch (rc) { + case BEGIN: /* should only be 1 begin */ + pr_err("unexpected config_begin\n"); + return -1; - if (fw_info[card_type].conf_name) { - ret = request_firmware(&fw, fw_info[card_type].conf_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "config file %s not found\n", - fw_info[card_type].conf_name); - return ret; - } + case END: + return 0; - dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL); - if (!dgap_config_buf) { - release_firmware(fw); - return -ENOMEM; - } + case BOARD: /* board info */ + if (dgap_checknode(p)) + return -1; - memcpy(dgap_config_buf, fw->data, fw->size); - release_firmware(fw); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * preserve dgap_config_buf - * as dgap_parsefile would - * otherwise alter it. - */ - tmp_ptr = dgap_config_buf; + p = p->next; - if (dgap_parsefile(&tmp_ptr) != 0) { - kfree(dgap_config_buf); - return -EINVAL; - } - kfree(dgap_config_buf); - } + p->type = BNODE; + p->u.board.status = kstrdup("No", GFP_KERNEL); + line = conc = NULL; + brd = p; + linecnt = -1; - /* - * Match this board to a config the user created for us. - */ - brd->bd_config = - dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot); + board_type = dgap_gettok(in); + if (board_type == 0) { + pr_err("board !!type not specified"); + return -1; + } - /* - * Because the 4 port Xr products share the same PCI ID - * as the 8 port Xr products, if we receive a NULL config - * back, and this is a PAPORT8 board, retry with a - * PAPORT4 attempt as well. - */ - if (brd->type == PAPORT8 && !brd->bd_config) - brd->bd_config = - dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot); + p->u.board.type = board_type; - if (!brd->bd_config) { - dev_err(&pdev->dev, "No valid configuration found\n"); - return -EINVAL; - } + break; - if (fw_info[card_type].bios_name) { - ret = request_firmware(&fw, fw_info[card_type].bios_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "bios file %s not found\n", - fw_info[card_type].bios_name); - return ret; - } - dgap_do_bios_load(brd, fw->data, fw->size); - release_firmware(fw); - - /* Wait for BIOS to test board... */ - ret = dgap_test_bios(brd); - if (ret) - return ret; - } - - if (fw_info[card_type].fep_name) { - ret = request_firmware(&fw, fw_info[card_type].fep_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "dgap: fep file %s not found\n", - fw_info[card_type].fep_name); - return ret; - } - dgap_do_fep_load(brd, fw->data, fw->size); - release_firmware(fw); - - /* Wait for FEP to load on board... */ - ret = dgap_test_fep(brd); - if (ret) - return ret; - } - -#ifdef DIGI_CONCENTRATORS_SUPPORTED - /* - * If this is a CX or EPCX, we need to see if the firmware - * is requesting a concentrator image from us. - */ - if ((bd->type == PCX) || (bd->type == PEPC)) { - chk_addr = (u16 *) (vaddr + DOWNREQ); - /* Nonzero if FEP is requesting concentrator image. */ - check = readw(chk_addr); - vaddr = brd->re_map_membase; - } - - if (fw_info[card_type].con_name && check && vaddr) { - ret = request_firmware(&fw, fw_info[card_type].con_name, - &pdev->dev); - if (ret) { - dev_err(&pdev->dev, "conc file %s not found\n", - fw_info[card_type].con_name); - return ret; - } - /* Put concentrator firmware loading code here */ - offset = readw((u16 *) (vaddr + DOWNREQ)); - memcpy_toio(offset, fw->data, fw->size); - - dgap_do_conc_load(brd, (char *)fw->data, fw->size) - release_firmware(fw); - } -#endif - - return 0; -} - -/* - * Remap PCI memory. - */ -static int dgap_remap(struct board_t *brd) -{ - if (!brd || brd->magic != DGAP_BOARD_MAGIC) - return -EIO; - - if (!request_mem_region(brd->membase, 0x200000, "dgap")) - return -ENOMEM; - - if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, - "dgap")) { - release_mem_region(brd->membase, 0x200000); - return -ENOMEM; - } - - brd->re_map_membase = ioremap(brd->membase, 0x200000); - if (!brd->re_map_membase) { - release_mem_region(brd->membase, 0x200000); - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - return -ENOMEM; - } - - brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000); - if (!brd->re_map_port) { - release_mem_region(brd->membase, 0x200000); - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - iounmap(brd->re_map_membase); - return -ENOMEM; - } - - return 0; -} - -static void dgap_unmap(struct board_t *brd) -{ - iounmap(brd->re_map_port); - iounmap(brd->re_map_membase); - release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); - release_mem_region(brd->membase, 0x200000); -} -/***************************************************************************** -* -* Function: -* -* dgap_poll_handler -* -* Author: -* -* Scott H Kilau -* -* Parameters: -* -* dummy -- ignored -* -* Return Values: -* -* none -* -* Description: -* -* As each timer expires, it determines (a) whether the "transmit" -* waiter needs to be woken up, and (b) whether the poller needs to -* be rescheduled. -* -******************************************************************************/ - -static void dgap_poll_handler(ulong dummy) -{ - unsigned int i; - struct board_t *brd; - unsigned long lock_flags; - ulong new_time; - - dgap_poll_counter++; - - /* - * Do not start the board state machine until - * driver tells us its up and running, and has - * everything it needs. - */ - if (dgap_driver_state != DRIVER_READY) - goto schedule_poller; - - /* - * If we have just 1 board, or the system is not SMP, - * then use the typical old style poller. - * Otherwise, use our new tasklet based poller, which should - * speed things up for multiple boards. - */ - if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) { - for (i = 0; i < dgap_numboards; i++) { - - brd = dgap_board[i]; - - if (brd->state == BOARD_FAILED) - continue; - if (!brd->intr_running) - /* Call the real board poller directly */ - dgap_poll_tasklet((unsigned long) brd); - } - } else { - /* - * Go thru each board, kicking off a - * tasklet for each if needed - */ - for (i = 0; i < dgap_numboards; i++) { - brd = dgap_board[i]; - - /* - * Attempt to grab the board lock. - * - * If we can't get it, no big deal, the next poll - * will get it. Basically, I just really don't want - * to spin in here, because I want to kick off my - * tasklets as fast as I can, and then get out the - * poller. - */ - if (!spin_trylock(&brd->bd_lock)) - continue; + case IO: /* i/o port */ + if (p->type != BNODE) { + pr_err("IO port only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.portstr = kstrdup(s, GFP_KERNEL); + if (kstrtol(s, 0, &p->u.board.port)) { + pr_err("bad number for IO port"); + return -1; + } + p->u.board.v_port = 1; + break; - /* - * If board is in a failed state, don't bother - * scheduling a tasklet - */ - if (brd->state == BOARD_FAILED) { - spin_unlock(&brd->bd_lock); - continue; + case MEM: /* memory address */ + if (p->type != BNODE) { + pr_err("memory address only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.addrstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.addr)) { + pr_err("bad number for memory address"); + return -1; } + p->u.board.v_addr = 1; + break; - /* Schedule a poll helper task */ - if (!brd->intr_running) - tasklet_schedule(&brd->helper_tasklet); + case PCIINFO: /* pci information */ + if (p->type != BNODE) { + pr_err("memory address only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.pcibus)) { + pr_err("bad number for pci bus"); + return -1; + } + p->u.board.v_pcibus = 1; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL); + if (kstrtoul(s, 0, &p->u.board.pcislot)) { + pr_err("bad number for pci slot"); + return -1; + } + p->u.board.v_pcislot = 1; + break; - /* - * Can't do DGAP_UNLOCK here, as we don't have - * lock_flags because we did a trylock above. - */ - spin_unlock(&brd->bd_lock); - } - } - -schedule_poller: - - /* - * Schedule ourself back at the nominal wakeup interval. - */ - spin_lock_irqsave(&dgap_poll_lock, lock_flags); - dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick); - - new_time = dgap_poll_time - jiffies; - - if ((ulong) new_time >= 2 * dgap_poll_tick) { - dgap_poll_time = - jiffies + dgap_jiffies_from_ms(dgap_poll_tick); - } - - dgap_poll_timer.function = dgap_poll_handler; - dgap_poll_timer.data = 0; - dgap_poll_timer.expires = dgap_poll_time; - spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - - if (!dgap_poll_stop) - add_timer(&dgap_poll_timer); -} - -/* - * dgap_intr() - * - * Driver interrupt handler. - */ -static irqreturn_t dgap_intr(int irq, void *voidbrd) -{ - struct board_t *brd = voidbrd; - - if (!brd) - return IRQ_NONE; - - /* - * Check to make sure its for us. - */ - if (brd->magic != DGAP_BOARD_MAGIC) - return IRQ_NONE; - - brd->intr_count++; - - /* - * Schedule tasklet to run at a better time. - */ - tasklet_schedule(&brd->helper_tasklet); - return IRQ_HANDLED; -} - -/* - * dgap_init_globals() - * - * This is where we initialize the globals from the static insmod - * configuration variables. These are declared near the head of - * this file. - */ -static void dgap_init_globals(void) -{ - unsigned int i; - - for (i = 0; i < MAXBOARDS; i++) - dgap_board[i] = NULL; - - init_timer(&dgap_poll_timer); -} - -/************************************************************************ - * - * TTY Initialization/Cleanup Functions - * - ************************************************************************/ - -/* - * dgap_tty_register() - * - * Init the tty subsystem for this board. - */ -static int dgap_tty_register(struct board_t *brd) -{ - int rc; - - brd->serial_driver = tty_alloc_driver(MAXPORTS, 0); - if (IS_ERR(brd->serial_driver)) - return PTR_ERR(brd->serial_driver); - - snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_", - brd->boardnum); - brd->serial_driver->name = brd->serial_name; - brd->serial_driver->name_base = 0; - brd->serial_driver->major = 0; - brd->serial_driver->minor_start = 0; - brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; - brd->serial_driver->init_termios = dgap_default_termios; - brd->serial_driver->driver_name = DRVSTR; - brd->serial_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); - - /* The kernel wants space to store pointers to tty_structs */ - brd->serial_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->serial_driver->ttys) { - rc = -ENOMEM; - goto free_serial_drv; - } - - /* - * Entry points for driver. Called by the kernel from - * tty_io.c and n_tty.c. - */ - tty_set_operations(brd->serial_driver, &dgap_tty_ops); - - /* - * If we're doing transparent print, we have to do all of the above - * again, separately so we don't get the LD confused about what major - * we are when we get into the dgap_tty_open() routine. - */ - brd->print_driver = tty_alloc_driver(MAXPORTS, 0); - if (IS_ERR(brd->print_driver)) { - rc = PTR_ERR(brd->print_driver); - goto free_serial_drv; - } - - snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_", - brd->boardnum); - brd->print_driver->name = brd->print_name; - brd->print_driver->name_base = 0; - brd->print_driver->major = 0; - brd->print_driver->minor_start = 0; - brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL; - brd->print_driver->subtype = SERIAL_TYPE_NORMAL; - brd->print_driver->init_termios = dgap_default_termios; - brd->print_driver->driver_name = DRVSTR; - brd->print_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); - - /* The kernel wants space to store pointers to tty_structs */ - brd->print_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->print_driver->ttys) { - rc = -ENOMEM; - goto free_print_drv; - } - - /* - * Entry points for driver. Called by the kernel from - * tty_io.c and n_tty.c. - */ - tty_set_operations(brd->print_driver, &dgap_tty_ops); - - /* Register tty devices */ - rc = tty_register_driver(brd->serial_driver); - if (rc < 0) - goto free_print_drv; - - /* Register Transparent Print devices */ - rc = tty_register_driver(brd->print_driver); - if (rc < 0) - goto unregister_serial_drv; - - dgap_boards_by_major[brd->serial_driver->major] = brd; - brd->dgap_serial_major = brd->serial_driver->major; - - dgap_boards_by_major[brd->print_driver->major] = brd; - brd->dgap_transparent_print_major = brd->print_driver->major; - - return 0; - -unregister_serial_drv: - tty_unregister_driver(brd->serial_driver); -free_print_drv: - put_tty_driver(brd->print_driver); -free_serial_drv: - put_tty_driver(brd->serial_driver); - - return rc; -} - -static void dgap_tty_unregister(struct board_t *brd) -{ - tty_unregister_driver(brd->print_driver); - tty_unregister_driver(brd->serial_driver); - put_tty_driver(brd->print_driver); - put_tty_driver(brd->serial_driver); -} - -/* - * dgap_tty_init() - * - * Init the tty subsystem. Called once per board after board has been - * downloaded and init'ed. - */ -static int dgap_tty_init(struct board_t *brd) -{ - int i; - int tlw; - uint true_count; - u8 __iomem *vaddr; - u8 modem; - struct channel_t *ch; - struct bs_t __iomem *bs; - struct cm_t __iomem *cm; - int ret; - - /* - * Initialize board structure elements. - */ - - vaddr = brd->re_map_membase; - true_count = readw((vaddr + NCHAN)); - - brd->nasync = dgap_config_get_num_prts(brd); - - if (!brd->nasync) - brd->nasync = brd->maxports; - - if (brd->nasync > brd->maxports) - brd->nasync = brd->maxports; - - if (true_count != brd->nasync) { - dev_warn(&brd->pdev->dev, - "%s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); - - if ((brd->type == PPCM) && - (true_count == 64 || true_count == 0)) { - dev_warn(&brd->pdev->dev, - "Please make SURE the EBI cable running from the card\n"); - dev_warn(&brd->pdev->dev, - "to each EM module is plugged into EBI IN!\n"); - } - - brd->nasync = true_count; - - /* If no ports, don't bother going any further */ - if (!brd->nasync) { - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - return -EIO; - } - } - - /* - * Allocate channel memory that might not have been allocated - * when the driver was first loaded. - */ - for (i = 0; i < brd->nasync; i++) { - brd->channels[i] = - kzalloc(sizeof(struct channel_t), GFP_KERNEL); - if (!brd->channels[i]) { - ret = -ENOMEM; - goto free_chan; - } - } - - ch = brd->channels[0]; - vaddr = brd->re_map_membase; - - bs = (struct bs_t __iomem *) ((ulong) vaddr + CHANBUF); - cm = (struct cm_t __iomem *) ((ulong) vaddr + CMDBUF); - - brd->bd_bs = bs; - - /* Set up channel variables */ - for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) { - - spin_lock_init(&ch->ch_lock); - - /* Store all our magic numbers */ - ch->magic = DGAP_CHANNEL_MAGIC; - ch->ch_tun.magic = DGAP_UNIT_MAGIC; - ch->ch_tun.un_type = DGAP_SERIAL; - ch->ch_tun.un_ch = ch; - ch->ch_tun.un_dev = i; - - ch->ch_pun.magic = DGAP_UNIT_MAGIC; - ch->ch_pun.un_type = DGAP_PRINT; - ch->ch_pun.un_ch = ch; - ch->ch_pun.un_dev = i; - - ch->ch_vaddr = vaddr; - ch->ch_bs = bs; - ch->ch_cm = cm; - ch->ch_bd = brd; - ch->ch_portnum = i; - ch->ch_digi = dgap_digi_init; - - /* - * Set up digi dsr and dcd bits based on altpin flag. - */ - if (dgap_config_get_altpin(brd)) { - ch->ch_dsr = DM_CD; - ch->ch_cd = DM_DSR; - ch->ch_digi.digi_flags |= DIGI_ALTPIN; - } else { - ch->ch_cd = DM_CD; - ch->ch_dsr = DM_DSR; - } - - ch->ch_taddr = vaddr + (ioread16(&(ch->ch_bs->tx_seg)) << 4); - ch->ch_raddr = vaddr + (ioread16(&(ch->ch_bs->rx_seg)) << 4); - ch->ch_tx_win = 0; - ch->ch_rx_win = 0; - ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1; - ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1; - ch->ch_tstart = 0; - ch->ch_rstart = 0; - - /* - * Set queue water marks, interrupt mask, - * and general tty parameters. - */ - tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : - ch->ch_tsize / 2; - ch->ch_tlw = tlw; - - dgap_cmdw(ch, STLOW, tlw, 0); - - dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0); - - dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0); - - ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); - - init_waitqueue_head(&ch->ch_flags_wait); - init_waitqueue_head(&ch->ch_tun.un_flags_wait); - init_waitqueue_head(&ch->ch_pun.un_flags_wait); - - /* Turn on all modem interrupts for now */ - modem = (DM_CD | DM_DSR | DM_CTS | DM_RI); - writeb(modem, &(ch->ch_bs->m_int)); - - /* - * Set edelay to 0 if interrupts are turned on, - * otherwise set edelay to the usual 100. - */ - if (brd->intr_used) - writew(0, &(ch->ch_bs->edelay)); - else - writew(100, &(ch->ch_bs->edelay)); - - writeb(1, &(ch->ch_bs->idata)); - } - - return 0; - -free_chan: - while (--i >= 0) { - kfree(brd->channels[i]); - brd->channels[i] = NULL; - } - return ret; -} - -/* - * dgap_tty_free() - * - * Free the channles which are allocated in dgap_tty_init(). - */ -static void dgap_tty_free(struct board_t *brd) -{ - int i; - - for (i = 0; i < brd->nasync; i++) - kfree(brd->channels[i]); -} -/* - * dgap_cleanup_tty() - * - * Uninitialize the TTY portion of this driver. Free all memory and - * resources. - */ -static void dgap_cleanup_tty(struct board_t *brd) -{ - struct device *dev; - unsigned int i; - - dgap_boards_by_major[brd->serial_driver->major] = NULL; - brd->dgap_serial_major = 0; - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->serial_ports[i]); - dev = brd->channels[i]->ch_tun.un_sysfs; - dgap_remove_tty_sysfs(dev); - tty_unregister_device(brd->serial_driver, i); - } - tty_unregister_driver(brd->serial_driver); - put_tty_driver(brd->serial_driver); - kfree(brd->serial_ports); - - dgap_boards_by_major[brd->print_driver->major] = NULL; - brd->dgap_transparent_print_major = 0; - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->printer_ports[i]); - dev = brd->channels[i]->ch_pun.un_sysfs; - dgap_remove_tty_sysfs(dev); - tty_unregister_device(brd->print_driver, i); - } - tty_unregister_driver(brd->print_driver); - put_tty_driver(brd->print_driver); - kfree(brd->printer_ports); -} - -/*======================================================================= - * - * dgap_input - Process received data. - * - * ch - Pointer to channel structure. - * - *=======================================================================*/ - -static void dgap_input(struct channel_t *ch) -{ - struct board_t *bd; - struct bs_t __iomem *bs; - struct tty_struct *tp; - struct tty_ldisc *ld; - uint rmask; - uint head; - uint tail; - int data_len; - ulong lock_flags; - ulong lock_flags2; - int flip_len; - int len; - int n; - u8 *buf; - u8 tmpchar; - int s; - - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - - tp = ch->ch_tun.un_tty; - - bs = ch->ch_bs; - if (!bs) - return; - - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + case METHOD: + if (p->type != BNODE) { + pr_err("install method only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.method = kstrdup(s, GFP_KERNEL); + p->u.board.v_method = 1; + break; - /* - * Figure the number of characters in the buffer. - * Exit immediately if none. - */ + case STATUS: + if (p->type != BNODE) { + pr_err("config status only valid for boards"); + return -1; + } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.board.status = kstrdup(s, GFP_KERNEL); + break; - rmask = ch->ch_rsize - 1; + case NPORTS: /* number of ports */ + if (p->type == BNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.board.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.board.v_nport = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.conc.v_nport = 1; + } else if (p->type == MNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.module.nport)) { + pr_err("bad number for number of ports"); + return -1; + } + p->u.module.v_nport = 1; + } else { + pr_err("nports only valid for concentrators or modules"); + return -1; + } + break; - head = readw(&(bs->rx_head)); - head &= rmask; - tail = readw(&(bs->rx_tail)); - tail &= rmask; + case ID: /* letter ID used in tty name */ + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } - data_len = (head - tail) & rmask; + p->u.board.status = kstrdup(s, GFP_KERNEL); - if (data_len == 0) { - writeb(1, &(bs->idata)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } + if (p->type == CNODE) { + p->u.conc.id = kstrdup(s, GFP_KERNEL); + p->u.conc.v_id = 1; + } else if (p->type == MNODE) { + p->u.module.id = kstrdup(s, GFP_KERNEL); + p->u.module.v_id = 1; + } else { + pr_err("id only valid for concentrators or modules"); + return -1; + } + break; - /* - * If the device is not open, or CREAD is off, flush - * input data and return immediately. - */ - if ((bd->state != BOARD_READY) || !tp || - (tp->magic != TTY_MAGIC) || - !(ch->ch_tun.un_flags & UN_ISOPEN) || - !(tp->termios.c_cflag & CREAD) || - (ch->ch_tun.un_flags & UN_CLOSING)) { + case STARTO: /* start offset of ID */ + if (p->type == BNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.board.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.board.v_start = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.conc.v_start = 1; + } else if (p->type == MNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.module.start)) { + pr_err("bad number for start of tty count"); + return -1; + } + p->u.module.v_start = 1; + } else { + pr_err("start only valid for concentrators or modules"); + return -1; + } + break; - writew(head, &(bs->rx_tail)); - writeb(1, &(bs->idata)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } + case TTYN: /* tty name prefix */ + if (dgap_checknode(p)) + return -1; - /* - * If we are throttled, simply don't read any data. - */ - if (ch->ch_flags & CH_RXBLOCK) { - writeb(1, &(bs->idata)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Ignore oruns. - */ - tmpchar = readb(&(bs->orun)); - if (tmpchar) { - ch->ch_err_overrun++; - writeb(0, &(bs->orun)); - } + p = p->next; + p->type = TNODE; - /* Decide how much data we can send into the tty layer */ - flip_len = TTY_FLIPBUF_SIZE; + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.ttyname = kstrdup(s, GFP_KERNEL); + if (!p->u.ttyname) + return -1; - /* Chop down the length, if needed */ - len = min(data_len, flip_len); - len = min(len, (N_TTY_BUF_SIZE - 1)); + break; - ld = tty_ldisc_ref(tp); + case CU: /* cu name prefix */ + if (dgap_checknode(p)) + return -1; -#ifdef TTY_DONT_FLIP - /* - * If the DONT_FLIP flag is on, don't flush our buffer, and act - * like the ld doesn't have any space to put the data right now. - */ - if (test_bit(TTY_DONT_FLIP, &tp->flags)) - len = 0; -#endif + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * If we were unable to get a reference to the ld, - * don't flush our buffer, and act like the ld doesn't - * have any space to put the data right now. - */ - if (!ld) { - len = 0; - } else { - /* - * If ld doesn't have a pointer to a receive_buf function, - * flush the data, then act like the ld doesn't have any - * space to put the data right now. - */ - if (!ld->ops->receive_buf) { - writew(head, &(bs->rx_tail)); - len = 0; - } - } + p = p->next; + p->type = CUNODE; - if (len <= 0) { - writeb(1, &(bs->idata)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (ld) - tty_ldisc_deref(ld); - return; - } + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.cuname = kstrdup(s, GFP_KERNEL); + if (!p->u.cuname) + return -1; - buf = ch->ch_bd->flipbuf; - n = len; + break; - /* - * n now contains the most amount of data we can copy, - * bounded either by our buffer size or the amount - * of data the card actually has pending... - */ - while (n) { + case LINE: /* line information */ + if (dgap_checknode(p)) + return -1; + if (!brd) { + pr_err("must specify board before line info"); + return -1; + } + switch (brd->u.board.type) { + case PPCM: + pr_err("line not valid for PC/em"); + return -1; + } - s = ((head >= tail) ? head : ch->ch_rsize) - tail; - s = min(s, n); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (s <= 0) + p = p->next; + p->type = LNODE; + conc = NULL; + line = p; + linecnt++; break; - memcpy_fromio(buf, ch->ch_raddr + tail, s); - - tail += s; - buf += s; + case CONC: /* concentrator information */ + if (dgap_checknode(p)) + return -1; + if (!line) { + pr_err("must specify line info before concentrator"); + return -1; + } - n -= s; - /* Flip queue if needed */ - tail &= rmask; - } + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - writew(tail, &(bs->rx_tail)); - writeb(1, &(bs->idata)); - ch->ch_rxcount += len; + p = p->next; + p->type = CNODE; + conc = p; - /* - * If we are completely raw, we don't need to go through a lot - * of the tty layers that exist. - * In this case, we take the shortest and fastest route we - * can to relay the data to the user. - * - * On the other hand, if we are not raw, we need to go through - * the tty layer, which has its API more well defined. - */ - if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { - dgap_parity_scan(ch, ch->ch_bd->flipbuf, - ch->ch_bd->flipflagbuf, &len); + if (linecnt) + brd->u.board.conc2++; + else + brd->u.board.conc1++; - len = tty_buffer_request_room(tp->port, len); - tty_insert_flip_string_flags(tp->port, ch->ch_bd->flipbuf, - ch->ch_bd->flipflagbuf, len); - } else { - len = tty_buffer_request_room(tp->port, len); - tty_insert_flip_string(tp->port, ch->ch_bd->flipbuf, len); - } + conc_type = dgap_gettok(in); + if (conc_type == 0 || conc_type != CX || + conc_type != EPC) { + pr_err("failed to set a type of concentratros"); + return -1; + } - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + p->u.conc.type = conc_type; - /* Tell the tty layer its okay to "eat" the data now */ - tty_flip_buffer_push(tp->port); + break; - if (ld) - tty_ldisc_deref(ld); + case MOD: /* EBI module */ + if (dgap_checknode(p)) + return -1; + if (!brd) { + pr_err("must specify board info before EBI modules"); + return -1; + } + switch (brd->u.board.type) { + case PPCM: + linecnt = 0; + break; + default: + if (!conc) { + pr_err("must specify concentrator info before EBI module"); + return -1; + } + } -} + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; -/************************************************************************ - * Determines when CARRIER changes state and takes appropriate - * action. - ************************************************************************/ -static void dgap_carrier(struct channel_t *ch) -{ - struct board_t *bd; + p = p->next; + p->type = MNODE; - int virt_carrier = 0; - int phys_carrier = 0; + if (linecnt) + brd->u.board.module2++; + else + brd->u.board.module1++; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + module_type = dgap_gettok(in); + if (module_type == 0 || module_type != PORTS || + module_type != MODEM) { + pr_err("failed to set a type of module"); + return -1; + } - bd = ch->ch_bd; + p->u.module.type = module_type; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + break; - /* Make sure altpin is always set correctly */ - if (ch->ch_digi.digi_flags & DIGI_ALTPIN) { - ch->ch_dsr = DM_CD; - ch->ch_cd = DM_DSR; - } else { - ch->ch_dsr = DM_DSR; - ch->ch_cd = DM_CD; - } + case CABLE: + if (p->type == LNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.line.cable = kstrdup(s, GFP_KERNEL); + p->u.line.v_cable = 1; + } + break; - if (ch->ch_mistat & D_CD(ch)) - phys_carrier = 1; + case SPEED: /* sync line speed indication */ + if (p->type == LNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.line.speed)) { + pr_err("bad number for line speed"); + return -1; + } + p->u.line.v_speed = 1; + } else if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.conc.speed)) { + pr_err("bad number for line speed"); + return -1; + } + p->u.conc.v_speed = 1; + } else { + pr_err("speed valid only for lines or concentrators."); + return -1; + } + break; - if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) - virt_carrier = 1; + case CONNECT: + if (p->type == CNODE) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + p->u.conc.connect = kstrdup(s, GFP_KERNEL); + p->u.conc.v_connect = 1; + } + break; + case PRINT: /* transparent print name prefix */ + if (dgap_checknode(p)) + return -1; - if (ch->ch_c_cflag & CLOCAL) - virt_carrier = 1; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* - * Test for a VIRTUAL carrier transition to HIGH. - */ - if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) { + p = p->next; + p->type = PNODE; - /* - * When carrier rises, wake any threads waiting - * for carrier in the open routine. - */ + s = dgap_getword(in); + if (!s) { + pr_err("unexpeced end of file"); + return -1; + } + p->u.printname = kstrdup(s, GFP_KERNEL); + if (!p->u.printname) + return -1; - if (waitqueue_active(&(ch->ch_flags_wait))) - wake_up_interruptible(&ch->ch_flags_wait); - } + break; - /* - * Test for a PHYSICAL carrier transition to HIGH. - */ - if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) { + case CMAJOR: /* major number */ + if (dgap_checknode(p)) + return -1; - /* - * When carrier rises, wake any threads waiting - * for carrier in the open routine. - */ + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (waitqueue_active(&(ch->ch_flags_wait))) - wake_up_interruptible(&ch->ch_flags_wait); - } + p = p->next; + p->type = JNODE; - /* - * Test for a PHYSICAL transition to low, so long as we aren't - * currently ignoring physical transitions (which is what "virtual - * carrier" indicates). - * - * The transition of the virtual carrier to low really doesn't - * matter... it really only means "ignore carrier state", not - * "make pretend that carrier is there". - */ - if ((virt_carrier == 0) && - ((ch->ch_flags & CH_CD) != 0) && - (phys_carrier == 0)) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.majornumber)) { + pr_err("bad number for major number"); + return -1; + } + break; - /* - * When carrier drops: - * - * Drop carrier on all open units. - * - * Flush queues, waking up any task waiting in the - * line discipline. - * - * Send a hangup to the control terminal. - * - * Enable all select calls. - */ - if (waitqueue_active(&(ch->ch_flags_wait))) - wake_up_interruptible(&ch->ch_flags_wait); + case ALTPIN: /* altpin setting */ + if (dgap_checknode(p)) + return -1; - if (ch->ch_tun.un_open_count > 0) - tty_hangup(ch->ch_tun.un_tty); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - if (ch->ch_pun.un_open_count > 0) - tty_hangup(ch->ch_pun.un_tty); - } + p = p->next; + p->type = ANODE; - /* - * Make sure that our cached values reflect the current reality. - */ - if (virt_carrier == 1) - ch->ch_flags |= CH_FCAR; - else - ch->ch_flags &= ~CH_FCAR; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.altpin)) { + pr_err("bad number for altpin"); + return -1; + } + break; - if (phys_carrier == 1) - ch->ch_flags |= CH_CD; - else - ch->ch_flags &= ~CH_CD; -} + case USEINTR: /* enable interrupt setting */ + if (dgap_checknode(p)) + return -1; -/************************************************************************ - * - * TTY Entry points and helper functions - * - ************************************************************************/ + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; -/* - * dgap_tty_open() - * - */ -static int dgap_tty_open(struct tty_struct *tty, struct file *file) -{ - struct board_t *brd; - struct channel_t *ch; - struct un_t *un; - struct bs_t __iomem *bs; - uint major; - uint minor; - int rc; - ulong lock_flags; - ulong lock_flags2; - u16 head; + p = p->next; + p->type = INTRNODE; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.useintr)) { + pr_err("bad number for useintr"); + return -1; + } + break; - major = MAJOR(tty_devnum(tty)); - minor = MINOR(tty_devnum(tty)); + case TTSIZ: /* size of tty structure */ + if (dgap_checknode(p)) + return -1; - if (major > 255) - return -EIO; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* Get board pointer from our array of majors we have allocated */ - brd = dgap_boards_by_major[major]; - if (!brd) - return -EIO; + p = p->next; + p->type = TSNODE; - /* - * If board is not yet up to a state of READY, go to - * sleep waiting for it to happen or they cancel the open. - */ - rc = wait_event_interruptible(brd->state_wait, - (brd->state & BOARD_READY)); + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.ttysize)) { + pr_err("bad number for ttysize"); + return -1; + } + break; - if (rc) - return rc; + case CHSIZ: /* channel structure size */ + if (dgap_checknode(p)) + return -1; - spin_lock_irqsave(&brd->bd_lock, lock_flags); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* The wait above should guarantee this cannot happen */ - if (brd->state != BOARD_READY) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; - } + p = p->next; + p->type = CSNODE; - /* If opened device is greater than our number of ports, bail. */ - if (MINOR(tty_devnum(tty)) > brd->nasync) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; - } + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.chsize)) { + pr_err("bad number for chsize"); + return -1; + } + break; - ch = brd->channels[minor]; - if (!ch) { - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; - } + case BSSIZ: /* board structure size */ + if (dgap_checknode(p)) + return -1; - /* Grab channel lock */ - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* Figure out our type */ - if (major == brd->dgap_serial_major) { - un = &brd->channels[minor]->ch_tun; - un->un_type = DGAP_SERIAL; - } else if (major == brd->dgap_transparent_print_major) { - un = &brd->channels[minor]->ch_pun; - un->un_type = DGAP_PRINT; - } else { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; - } + p = p->next; + p->type = BSNODE; - /* Store our unit into driver_data, so we always have it available. */ - tty->driver_data = un; + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.bssize)) { + pr_err("bad number for bssize"); + return -1; + } + break; - /* - * Error if channel info pointer is NULL. - */ - bs = ch->ch_bs; - if (!bs) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); - return -EIO; - } + case UNTSIZ: /* sched structure size */ + if (dgap_checknode(p)) + return -1; - /* - * Initialize tty's - */ - if (!(un->un_flags & UN_ISOPEN)) { - /* Store important variables. */ - un->un_tty = tty; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* Maybe do something here to the TTY struct as well? */ - } + p = p->next; + p->type = USNODE; - /* - * Initialize if neither terminal or printer is open. - */ - if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) { + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.unsize)) { + pr_err("bad number for schedsize"); + return -1; + } + break; - ch->ch_mforce = 0; - ch->ch_mval = 0; + case F2SIZ: /* f2200 structure size */ + if (dgap_checknode(p)) + return -1; - /* - * Flush input queue. - */ - head = readw(&(bs->rx_head)); - writew(head, &(bs->rx_tail)); + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; + + p = p->next; + p->type = FSNODE; + + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.f2size)) { + pr_err("bad number for f2200size"); + return -1; + } + break; - ch->ch_flags = 0; - ch->pscan_state = 0; - ch->pscan_savechar = 0; + case VPSIZ: /* vpix structure size */ + if (dgap_checknode(p)) + return -1; - ch->ch_c_cflag = tty->termios.c_cflag; - ch->ch_c_iflag = tty->termios.c_iflag; - ch->ch_c_oflag = tty->termios.c_oflag; - ch->ch_c_lflag = tty->termios.c_lflag; - ch->ch_startc = tty->termios.c_cc[VSTART]; - ch->ch_stopc = tty->termios.c_cc[VSTOP]; + p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); + if (!p->next) + return -1; - /* TODO: flush our TTY struct here? */ - } + p = p->next; + p->type = VSNODE; - dgap_carrier(ch); - /* - * Run param in case we changed anything - */ - dgap_param(ch, brd, un->un_type); + s = dgap_getword(in); + if (!s) { + pr_err("unexpected end of file"); + return -1; + } + if (kstrtol(s, 0, &p->u.vpixsize)) { + pr_err("bad number for vpixsize"); + return -1; + } + break; + } + } +} - /* - * follow protocol for opening port - */ +static void dgap_cleanup_nodes(void) +{ + struct cnode *p; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + p = &dgap_head; - rc = dgap_block_til_ready(tty, file, ch); + while (p) { + struct cnode *tmp = p->next; - if (!un->un_tty) - return -ENODEV; + if (p->type == NULLNODE) { + p = tmp; + continue; + } - /* No going back now, increment our unit and channel counters */ - spin_lock_irqsave(&ch->ch_lock, lock_flags); - ch->ch_open_count++; - un->un_open_count++; - un->un_flags |= (UN_ISOPEN); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + switch (p->type) { + case BNODE: + kfree(p->u.board.portstr); + kfree(p->u.board.addrstr); + kfree(p->u.board.pcibusstr); + kfree(p->u.board.pcislotstr); + kfree(p->u.board.method); + break; + case CNODE: + kfree(p->u.conc.id); + kfree(p->u.conc.connect); + break; + case MNODE: + kfree(p->u.module.id); + break; + case TNODE: + kfree(p->u.ttyname); + break; + case CUNODE: + kfree(p->u.cuname); + break; + case LNODE: + kfree(p->u.line.cable); + break; + case PNODE: + kfree(p->u.printname); + break; + } - return rc; + kfree(p->u.board.status); + kfree(p); + p = tmp; + } } /* - * dgap_block_til_ready() - * - * Wait for DCD, if needed. + * Retrives the current custom baud rate from FEP memory, + * and returns it back to the user. + * Returns 0 on error. */ -static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, - struct channel_t *ch) +static uint dgap_get_custom_baud(struct channel_t *ch) { - int retval = 0; - struct un_t *un; - ulong lock_flags; - uint old_flags; - int sleep_on_un_flags; + u8 __iomem *vaddr; + ulong offset; + uint value; - if (!tty || tty->magic != TTY_MAGIC || !file || !ch || - ch->magic != DGAP_CHANNEL_MAGIC) - return -EIO; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EIO; + if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) + return 0; - spin_lock_irqsave(&ch->ch_lock, lock_flags); + if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS)) + return 0; - ch->ch_wopen++; + vaddr = ch->ch_bd->re_map_membase; - /* Loop forever */ - while (1) { + if (!vaddr) + return 0; - sleep_on_un_flags = 0; + /* + * Go get from fep mem, what the fep + * believes the custom baud rate is. + */ + offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28) + + LINE_SPEED; - /* - * If board has failed somehow during our sleep, - * bail with error. - */ - if (ch->ch_bd->state == BOARD_FAILED) { - retval = -EIO; - break; - } + value = readw(vaddr + offset); + return value; +} - /* If tty was hung up, break out of loop and set error. */ - if (tty_hung_up_p(file)) { - retval = -EAGAIN; - break; - } +/* + * Remap PCI memory. + */ +static int dgap_remap(struct board_t *brd) +{ + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return -EIO; - /* - * If either unit is in the middle of the fragile part of close, - * we just cannot touch the channel safely. - * Go back to sleep, knowing that when the channel can be - * touched safely, the close routine will signal the - * ch_wait_flags to wake us back up. - */ - if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & - UN_CLOSING)) { + if (!request_mem_region(brd->membase, 0x200000, "dgap")) + return -ENOMEM; - /* - * Our conditions to leave cleanly and happily: - * 1) NONBLOCKING on the tty is set. - * 2) CLOCAL is set. - * 3) DCD (fake or real) is active. - */ + if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, + "dgap")) { + release_mem_region(brd->membase, 0x200000); + return -ENOMEM; + } - if (file->f_flags & O_NONBLOCK) - break; + brd->re_map_membase = ioremap(brd->membase, 0x200000); + if (!brd->re_map_membase) { + release_mem_region(brd->membase, 0x200000); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + return -ENOMEM; + } - if (tty->flags & (1 << TTY_IO_ERROR)) - break; + brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000); + if (!brd->re_map_port) { + release_mem_region(brd->membase, 0x200000); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + iounmap(brd->re_map_membase); + return -ENOMEM; + } - if (ch->ch_flags & CH_CD) - break; + return 0; +} - if (ch->ch_flags & CH_FCAR) - break; - } else { - sleep_on_un_flags = 1; - } +static void dgap_unmap(struct board_t *brd) +{ + iounmap(brd->re_map_port); + iounmap(brd->re_map_membase); + release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000); + release_mem_region(brd->membase, 0x200000); +} - /* - * If there is a signal pending, the user probably - * interrupted (ctrl-c) us. - * Leave loop with error set. - */ - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } +/* + * dgap_parity_scan() + * + * Convert the FEP5 way of reporting parity errors and breaks into + * the Linux line discipline way. + */ +static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, + unsigned char *fbuf, int *len) +{ + int l = *len; + int count = 0; + unsigned char *in, *cout, *fout; + unsigned char c; - /* - * Store the flags before we let go of channel lock - */ - if (sleep_on_un_flags) - old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags; - else - old_flags = ch->ch_flags; + in = cbuf; + cout = cbuf; + fout = fbuf; + + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + while (l--) { + c = *in++; + switch (ch->pscan_state) { + default: + /* reset to sanity and fall through */ + ch->pscan_state = 0; - /* - * Let go of channel lock before calling schedule. - * Our poller will get any FEP events and wake us up when DCD - * eventually goes active. - */ + case 0: + /* No FF seen yet */ + if (c == (unsigned char) '\377') + /* delete this character from stream */ + ch->pscan_state = 1; + else { + *cout++ = c; + *fout++ = TTY_NORMAL; + count += 1; + } + break; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + case 1: + /* first FF seen */ + if (c == (unsigned char) '\377') { + /* doubled ff, transform to single ff */ + *cout++ = c; + *fout++ = TTY_NORMAL; + count += 1; + ch->pscan_state = 0; + } else { + /* save value examination in next state */ + ch->pscan_savechar = c; + ch->pscan_state = 2; + } + break; - /* - * Wait for something in the flags to change - * from the current value. - */ - if (sleep_on_un_flags) { - retval = wait_event_interruptible(un->un_flags_wait, - (old_flags != (ch->ch_tun.un_flags | - ch->ch_pun.un_flags))); - } else { - retval = wait_event_interruptible(ch->ch_flags_wait, - (old_flags != ch->ch_flags)); - } + case 2: + /* third character of ff sequence */ - /* - * We got woken up for some reason. - * Before looping around, grab our channel lock. - */ - spin_lock_irqsave(&ch->ch_lock, lock_flags); - } + *cout++ = c; - ch->ch_wopen--; + if (ch->pscan_savechar == 0x0) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + if (c == 0x0) { + ch->ch_err_break++; + *fout++ = TTY_BREAK; + } else { + ch->ch_err_parity++; + *fout++ = TTY_PARITY; + } + } - return retval; + count += 1; + ch->pscan_state = 0; + } + } + *len = count; } -/* - * dgap_tty_hangup() +/*======================================================================= * - * Hangup the port. Like a close, but don't wait for output to drain. - */ -static void dgap_tty_hangup(struct tty_struct *tty) + * dgap_input - Process received data. + * + * ch - Pointer to channel structure. + * + *=======================================================================*/ + +static void dgap_input(struct channel_t *ch) { struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + struct bs_t __iomem *bs; + struct tty_struct *tp; + struct tty_ldisc *ld; + uint rmask; + uint head; + uint tail; + int data_len; + ulong lock_flags; + ulong lock_flags2; + int flip_len; + int len; + int n; + u8 *buf; + u8 tmpchar; + int s; - if (!tty || tty->magic != TTY_MAGIC) + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + tp = ch->ch_tun.un_tty; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + bs = ch->ch_bs; + if (!bs) return; bd = ch->ch_bd; if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - /* flush the transmit queues */ - dgap_tty_flush_buffer(tty); -} + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); -/* - * dgap_tty_close() - * - */ -static void dgap_tty_close(struct tty_struct *tty, struct file *file) -{ - struct ktermios *ts; - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; + /* + * Figure the number of characters in the buffer. + * Exit immediately if none. + */ - if (!tty || tty->magic != TTY_MAGIC) - return; + rmask = ch->ch_rsize - 1; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) + head = readw(&(bs->rx_head)); + head &= rmask; + tail = readw(&(bs->rx_tail)); + tail &= rmask; + + data_len = (head - tail) & rmask; + + if (data_len == 0) { + writeb(1, &(bs->idata)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return; + } - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + /* + * If the device is not open, or CREAD is off, flush + * input data and return immediately. + */ + if ((bd->state != BOARD_READY) || !tp || + (tp->magic != TTY_MAGIC) || + !(ch->ch_tun.un_flags & UN_ISOPEN) || + !(tp->termios.c_cflag & CREAD) || + (ch->ch_tun.un_flags & UN_CLOSING)) { + + writew(head, &(bs->rx_tail)); + writeb(1, &(bs->idata)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return; + } - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) + /* + * If we are throttled, simply don't read any data. + */ + if (ch->ch_flags & CH_RXBLOCK) { + writeb(1, &(bs->idata)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return; + } - ts = &tty->termios; + /* + * Ignore oruns. + */ + tmpchar = readb(&(bs->orun)); + if (tmpchar) { + ch->ch_err_overrun++; + writeb(0, &(bs->orun)); + } - spin_lock_irqsave(&ch->ch_lock, lock_flags); + /* Decide how much data we can send into the tty layer */ + flip_len = TTY_FLIPBUF_SIZE; + + /* Chop down the length, if needed */ + len = min(data_len, flip_len); + len = min(len, (N_TTY_BUF_SIZE - 1)); + + ld = tty_ldisc_ref(tp); +#ifdef TTY_DONT_FLIP /* - * Determine if this is the last close or not - and if we agree about - * which type of close it is with the Line Discipline + * If the DONT_FLIP flag is on, don't flush our buffer, and act + * like the ld doesn't have any space to put the data right now. */ - if ((tty->count == 1) && (un->un_open_count != 1)) { + if (test_bit(TTY_DONT_FLIP, &tp->flags)) + len = 0; +#endif + + /* + * If we were unable to get a reference to the ld, + * don't flush our buffer, and act like the ld doesn't + * have any space to put the data right now. + */ + if (!ld) { + len = 0; + } else { /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. un_open_count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. + * If ld doesn't have a pointer to a receive_buf function, + * flush the data, then act like the ld doesn't have any + * space to put the data right now. */ - un->un_open_count = 1; + if (!ld->ops->receive_buf) { + writew(head, &(bs->rx_tail)); + len = 0; + } } - if (--un->un_open_count < 0) - un->un_open_count = 0; - - ch->ch_open_count--; - - if (ch->ch_open_count && un->un_open_count) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + if (len <= 0) { + writeb(1, &(bs->idata)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (ld) + tty_ldisc_deref(ld); return; } - /* OK, its the last close on the unit */ + buf = ch->ch_bd->flipbuf; + n = len; + + /* + * n now contains the most amount of data we can copy, + * bounded either by our buffer size or the amount + * of data the card actually has pending... + */ + while (n) { + + s = ((head >= tail) ? head : ch->ch_rsize) - tail; + s = min(s, n); + + if (s <= 0) + break; + + memcpy_fromio(buf, ch->ch_raddr + tail, s); + + tail += s; + buf += s; - un->un_flags |= UN_CLOSING; + n -= s; + /* Flip queue if needed */ + tail &= rmask; + } - tty->closing = 1; + writew(tail, &(bs->rx_tail)); + writeb(1, &(bs->idata)); + ch->ch_rxcount += len; /* - * Only officially close channel if count is 0 and - * DIGI_PRINTER bit is not set. + * If we are completely raw, we don't need to go through a lot + * of the tty layers that exist. + * In this case, we take the shortest and fastest route we + * can to relay the data to the user. + * + * On the other hand, if we are not raw, we need to go through + * the tty layer, which has its API more well defined. */ - if ((ch->ch_open_count == 0) && - !(ch->ch_digi.digi_flags & DIGI_PRINTER)) { - - ch->ch_flags &= ~(CH_RXBLOCK); - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - - /* wait for output to drain */ - /* This will also return if we take an interrupt */ + if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { + dgap_parity_scan(ch, ch->ch_bd->flipbuf, + ch->ch_bd->flipflagbuf, &len); - dgap_wait_for_drain(tty); + len = tty_buffer_request_room(tp->port, len); + tty_insert_flip_string_flags(tp->port, ch->ch_bd->flipbuf, + ch->ch_bd->flipflagbuf, len); + } else { + len = tty_buffer_request_room(tp->port, len); + tty_insert_flip_string(tp->port, ch->ch_bd->flipbuf, len); + } - dgap_tty_flush_buffer(tty); - tty_ldisc_flush(tty); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags); + /* Tell the tty layer its okay to "eat" the data now */ + tty_flip_buffer_push(tp->port); - tty->closing = 0; + if (ld) + tty_ldisc_deref(ld); - /* - * If we have HUPCL set, lower DTR and RTS - */ - if (ch->ch_c_cflag & HUPCL) { - ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch)); - dgap_cmdb(ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0); +} - /* - * Go to sleep to ensure RTS/DTR - * have been dropped for modems to see it. - */ - spin_unlock_irqrestore(&ch->ch_lock, - lock_flags); +static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, + struct un_t *un, u32 mask, + unsigned long *irq_flags1, + unsigned long *irq_flags2) +{ + if (!(un->un_flags & mask)) + return; - /* .25 second delay for dropping RTS/DTR */ - schedule_timeout_interruptible(msecs_to_jiffies(250)); + un->un_flags &= ~mask; - spin_lock_irqsave(&ch->ch_lock, lock_flags); - } + if (!(un->un_flags & UN_ISOPEN)) + return; - ch->pscan_state = 0; - ch->pscan_savechar = 0; - ch->ch_baud_info = 0; + if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + un->un_tty->ldisc->ops->write_wakeup) { + spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2); + spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1); - } + (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty); - /* - * turn off print device when closing print device. - */ - if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { - dgap_wmove(ch, ch->ch_digi.digi_offstr, - (int) ch->ch_digi.digi_offlen); - ch->ch_flags &= ~CH_PRON; + spin_lock_irqsave(&bd->bd_lock, *irq_flags1); + spin_lock_irqsave(&ch->ch_lock, *irq_flags2); } - - un->un_tty = NULL; - un->un_flags &= ~(UN_ISOPEN | UN_CLOSING); - tty->driver_data = NULL; - - wake_up_interruptible(&ch->ch_flags_wait); + wake_up_interruptible(&un->un_tty->write_wait); wake_up_interruptible(&un->un_flags_wait); - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } -/* - * dgap_tty_chars_in_buffer() - * - * Return number of characters that have not been transmitted yet. - * - * This routine is used by the line discipline to determine if there - * is data waiting to be transmitted/drained/flushed or not. - */ -static int dgap_tty_chars_in_buffer(struct tty_struct *tty) +/************************************************************************ + * Determines when CARRIER changes state and takes appropriate + * action. + ************************************************************************/ +static void dgap_carrier(struct channel_t *ch) { struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - struct bs_t __iomem *bs; - u8 tbusy; - uint chars; - u16 thead, ttail, tmask, chead, ctail; - ulong lock_flags = 0; - ulong lock_flags2 = 0; - - if (!tty) - return 0; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; + int virt_carrier = 0; + int phys_carrier = 0; - ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; + return; bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; + return; - bs = ch->ch_bs; - if (!bs) - return 0; + /* Make sure altpin is always set correctly */ + if (ch->ch_digi.digi_flags & DIGI_ALTPIN) { + ch->ch_dsr = DM_CD; + ch->ch_cd = DM_DSR; + } else { + ch->ch_dsr = DM_DSR; + ch->ch_cd = DM_CD; + } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + if (ch->ch_mistat & D_CD(ch)) + phys_carrier = 1; - tmask = (ch->ch_tsize - 1); + if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) + virt_carrier = 1; - /* Get Transmit queue pointers */ - thead = readw(&(bs->tx_head)) & tmask; - ttail = readw(&(bs->tx_tail)) & tmask; + if (ch->ch_c_cflag & CLOCAL) + virt_carrier = 1; - /* Get tbusy flag */ - tbusy = readb(&(bs->tbusy)); + /* + * Test for a VIRTUAL carrier transition to HIGH. + */ + if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) { - /* Get Command queue pointers */ - chead = readw(&(ch->ch_cm->cm_head)); - ctail = readw(&(ch->ch_cm->cm_tail)); + /* + * When carrier rises, wake any threads waiting + * for carrier in the open routine. + */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (waitqueue_active(&(ch->ch_flags_wait))) + wake_up_interruptible(&ch->ch_flags_wait); + } /* - * The only way we know for sure if there is no pending - * data left to be transferred, is if: - * 1) Transmit head and tail are equal (empty). - * 2) Command queue head and tail are equal (empty). - * 3) The "TBUSY" flag is 0. (Transmitter not busy). + * Test for a PHYSICAL carrier transition to HIGH. */ + if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) { - if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) { - chars = 0; - } else { - if (thead >= ttail) - chars = thead - ttail; - else - chars = thead - ttail + ch->ch_tsize; /* - * Fudge factor here. - * If chars is zero, we know that the command queue had - * something in it or tbusy was set. Because we cannot - * be sure if there is still some data to be transmitted, - * lets lie, and tell ld we have 1 byte left. + * When carrier rises, wake any threads waiting + * for carrier in the open routine. */ - if (chars == 0) { - /* - * If TBUSY is still set, and our tx buffers are empty, - * force the firmware to send me another wakeup after - * TBUSY has been cleared. - */ - if (tbusy != 0) { - spin_lock_irqsave(&ch->ch_lock, lock_flags); - un->un_flags |= UN_EMPTY; - writeb(1, &(bs->iempty)); - spin_unlock_irqrestore(&ch->ch_lock, - lock_flags); - } - chars = 1; - } + + if (waitqueue_active(&(ch->ch_flags_wait))) + wake_up_interruptible(&ch->ch_flags_wait); + } + + /* + * Test for a PHYSICAL transition to low, so long as we aren't + * currently ignoring physical transitions (which is what "virtual + * carrier" indicates). + * + * The transition of the virtual carrier to low really doesn't + * matter... it really only means "ignore carrier state", not + * "make pretend that carrier is there". + */ + if ((virt_carrier == 0) && + ((ch->ch_flags & CH_CD) != 0) && + (phys_carrier == 0)) { + + /* + * When carrier drops: + * + * Drop carrier on all open units. + * + * Flush queues, waking up any task waiting in the + * line discipline. + * + * Send a hangup to the control terminal. + * + * Enable all select calls. + */ + if (waitqueue_active(&(ch->ch_flags_wait))) + wake_up_interruptible(&ch->ch_flags_wait); + + if (ch->ch_tun.un_open_count > 0) + tty_hangup(ch->ch_tun.un_tty); + + if (ch->ch_pun.un_open_count > 0) + tty_hangup(ch->ch_pun.un_tty); } - return chars; + /* + * Make sure that our cached values reflect the current reality. + */ + if (virt_carrier == 1) + ch->ch_flags |= CH_FCAR; + else + ch->ch_flags &= ~CH_FCAR; + + if (phys_carrier == 1) + ch->ch_flags |= CH_CD; + else + ch->ch_flags &= ~CH_CD; } -static int dgap_wait_for_drain(struct tty_struct *tty) +/*======================================================================= + * + * dgap_event - FEP to host event processing routine. + * + * bd - Board of current event. + * + *=======================================================================*/ +static int dgap_event(struct board_t *bd) { struct channel_t *ch; - struct un_t *un; + ulong lock_flags; + ulong lock_flags2; struct bs_t __iomem *bs; - int ret = 0; - uint count = 1; - ulong lock_flags = 0; + u8 __iomem *event; + u8 __iomem *vaddr; + struct ev_t __iomem *eaddr; + uint head; + uint tail; + int port; + int reason; + int modem; + int b1; - if (!tty || tty->magic != TTY_MAGIC) + if (!bd || bd->magic != DGAP_BOARD_MAGIC) return -EIO; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EIO; + spin_lock_irqsave(&bd->bd_lock, lock_flags); - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -EIO; + vaddr = bd->re_map_membase; - bs = ch->ch_bs; - if (!bs) + if (!vaddr) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); return -EIO; + } - /* Loop until data is drained */ - while (count != 0) { - - count = dgap_tty_chars_in_buffer(tty); + eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); - if (count == 0) - break; + /* Get our head and tail */ + head = readw(&(eaddr->ev_head)); + tail = readw(&(eaddr->ev_tail)); - /* Set flag waiting for drain */ - spin_lock_irqsave(&ch->ch_lock, lock_flags); - un->un_flags |= UN_EMPTY; - writeb(1, &(bs->iempty)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + /* + * Forget it if pointers out of range. + */ - /* Go to sleep till we get woken up */ - ret = wait_event_interruptible(un->un_flags_wait, - ((un->un_flags & UN_EMPTY) == 0)); - /* If ret is non-zero, user ctrl-c'ed us */ - if (ret) - break; + if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART || + (head | tail) & 03) { + /* Let go of board lock */ + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return -EIO; } - spin_lock_irqsave(&ch->ch_lock, lock_flags); - un->un_flags &= ~(UN_EMPTY); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - - return ret; -} - -/* - * dgap_maxcps_room - * - * Reduces bytes_available to the max number of characters - * that can be sent currently given the maxcps value, and - * returns the new bytes_available. This only affects printer - * output. - */ -static int dgap_maxcps_room(struct channel_t *ch, struct un_t *un, - int bytes_available) -{ /* - * If its not the Transparent print device, return - * the full data amount. + * Loop to process all the events in the buffer. */ - if (un->un_type != DGAP_PRINT) - return bytes_available; + while (tail != head) { - if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) { - int cps_limit = 0; - unsigned long current_time = jiffies; - unsigned long buffer_time = current_time + - (HZ * ch->ch_digi.digi_bufsize) / - ch->ch_digi.digi_maxcps; + /* + * Get interrupt information. + */ - if (ch->ch_cpstime < current_time) { - /* buffer is empty */ - ch->ch_cpstime = current_time; /* reset ch_cpstime */ - cps_limit = ch->ch_digi.digi_bufsize; - } else if (ch->ch_cpstime < buffer_time) { - /* still room in the buffer */ - cps_limit = ((buffer_time - ch->ch_cpstime) * - ch->ch_digi.digi_maxcps) / HZ; - } else { - /* no room in the buffer */ - cps_limit = 0; - } + event = bd->re_map_membase + tail + EVSTART; - bytes_available = min(cps_limit, bytes_available); - } + port = ioread8(event); + reason = ioread8(event + 1); + modem = ioread8(event + 2); + b1 = ioread8(event + 3); - return bytes_available; -} + /* + * Make sure the interrupt is valid. + */ + if (port >= bd->nasync) + goto next; -static inline void dgap_set_firmware_event(struct un_t *un, unsigned int event) -{ - struct channel_t *ch; - struct bs_t __iomem *bs; + if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) + goto next; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; - bs = ch->ch_bs; - if (!bs) - return; + ch = bd->channels[port]; - if ((event & UN_LOW) != 0) { - if ((un->un_flags & UN_LOW) == 0) { - un->un_flags |= UN_LOW; - writeb(1, &(bs->ilow)); - } - } - if ((event & UN_LOW) != 0) { - if ((un->un_flags & UN_EMPTY) == 0) { - un->un_flags |= UN_EMPTY; - writeb(1, &(bs->iempty)); + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + goto next; + + /* + * If we have made it here, the event was valid. + * Lock down the channel. + */ + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + bs = ch->ch_bs; + + if (!bs) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + goto next; } - } -} -/* - * dgap_tty_write_room() - * - * Return space available in Tx buffer - */ -static int dgap_tty_write_room(struct tty_struct *tty) -{ - struct channel_t *ch; - struct un_t *un; - struct bs_t __iomem *bs; - u16 head, tail, tmask; - int ret; - ulong lock_flags = 0; + /* + * Process received data. + */ + if (reason & IFDATA) { - if (!tty) - return 0; + /* + * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT! + * input could send some data to ld, which in turn + * could do a callback to one of our other functions. + */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; + dgap_input(ch); - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - bs = ch->ch_bs; - if (!bs) - return 0; + if (ch->ch_flags & CH_RACTIVE) + ch->ch_flags |= CH_RENABLE; + else + writeb(1, &(bs->idata)); - spin_lock_irqsave(&ch->ch_lock, lock_flags); + if (ch->ch_flags & CH_RWAIT) { + ch->ch_flags &= ~CH_RWAIT; - tmask = ch->ch_tsize - 1; - head = readw(&(bs->tx_head)) & tmask; - tail = readw(&(bs->tx_tail)) & tmask; + wake_up_interruptible + (&ch->ch_tun.un_flags_wait); + } + } - ret = tail - head - 1; - if (ret < 0) - ret += ch->ch_tsize; + /* + * Process Modem change signals. + */ + if (reason & IFMODEM) { + ch->ch_mistat = modem; + dgap_carrier(ch); + } + + /* + * Process break. + */ + if (reason & IFBREAK) { + + if (ch->ch_tun.un_tty) { + /* A break has been indicated */ + ch->ch_err_break++; + tty_buffer_request_room + (ch->ch_tun.un_tty->port, 1); + tty_insert_flip_char(ch->ch_tun.un_tty->port, + 0, TTY_BREAK); + tty_flip_buffer_push(ch->ch_tun.un_tty->port); + } + } - /* Limit printer to maxcps */ - ret = dgap_maxcps_room(ch, un, ret); + /* + * Process Transmit low. + */ + if (reason & IFTLW) { + dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW, + &lock_flags, &lock_flags2); + dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW, + &lock_flags, &lock_flags2); + if (ch->ch_flags & CH_WLOW) { + ch->ch_flags &= ~CH_WLOW; + wake_up_interruptible(&ch->ch_flags_wait); + } + } - /* - * If we are printer device, leave space for - * possibly both the on and off strings. - */ - if (un->un_type == DGAP_PRINT) { - if (!(ch->ch_flags & CH_PRON)) - ret -= ch->ch_digi.digi_onlen; - ret -= ch->ch_digi.digi_offlen; - } else { - if (ch->ch_flags & CH_PRON) - ret -= ch->ch_digi.digi_offlen; - } + /* + * Process Transmit empty. + */ + if (reason & IFTEM) { + dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY, + &lock_flags, &lock_flags2); + dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY, + &lock_flags, &lock_flags2); + if (ch->ch_flags & CH_WEMPTY) { + ch->ch_flags &= ~CH_WEMPTY; + wake_up_interruptible(&ch->ch_flags_wait); + } + } - if (ret < 0) - ret = 0; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - /* - * Schedule FEP to wake us up if needed. - * - * TODO: This might be overkill... - * Do we really need to schedule callbacks from the FEP - * in every case? Can we get smarter based on ret? - */ - dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); +next: + tail = (tail + 4) & (EVMAX - EVSTART - 4); + } - return ret; -} + writew(tail, &(eaddr->ev_tail)); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -/* - * dgap_tty_put_char() - * - * Put a character into ch->ch_buf - * - * - used by the line discipline for OPOST processing - */ -static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c) -{ - /* - * Simply call tty_write. - */ - dgap_tty_write(tty, &c, 1); - return 1; + return 0; } /* - * dgap_tty_write() - * - * Take data from the user or kernel and send it out to the FEP. - * In here exists all the Transparent Print magic as well. + * Our board poller function. */ -static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static void dgap_poll_tasklet(unsigned long data) { - struct channel_t *ch; - struct un_t *un; - struct bs_t __iomem *bs; - char __iomem *vaddr; - u16 head, tail, tmask, remain; - int bufcount, n; + struct board_t *bd = (struct board_t *) data; ulong lock_flags; + char __iomem *vaddr; + u16 head, tail; - if (!tty) - return 0; + if (!bd || (bd->magic != DGAP_BOARD_MAGIC)) + return; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; + if (bd->inhibit_poller) + return; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; + spin_lock_irqsave(&bd->bd_lock, lock_flags); - bs = ch->ch_bs; - if (!bs) - return 0; + vaddr = bd->re_map_membase; - if (!count) - return 0; + /* + * If board is ready, parse deeper to see if there is anything to do. + */ + if (bd->state == BOARD_READY) { - spin_lock_irqsave(&ch->ch_lock, lock_flags); + struct ev_t __iomem *eaddr; - /* Get our space available for the channel from the board */ - tmask = ch->ch_tsize - 1; - head = readw(&(bs->tx_head)) & tmask; - tail = readw(&(bs->tx_tail)) & tmask; + if (!bd->re_map_membase) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; + } + if (!bd->re_map_port) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; + } - bufcount = tail - head - 1; - if (bufcount < 0) - bufcount += ch->ch_tsize; + if (!bd->nasync) + goto out; - /* - * Limit printer output to maxcps overall, with bursts allowed - * up to bufsize characters. - */ - bufcount = dgap_maxcps_room(ch, un, bufcount); + eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); - /* - * Take minimum of what the user wants to send, and the - * space available in the FEP buffer. - */ - count = min(count, bufcount); + /* Get our head and tail */ + head = readw(&(eaddr->ev_head)); + tail = readw(&(eaddr->ev_tail)); - /* - * Bail if no space left. - */ - if (count <= 0) { - dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - return 0; - } + /* + * If there is an event pending. Go service it. + */ + if (head != tail) { + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_event(bd); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + } - /* - * Output the printer ON string, if we are in terminal mode, but - * need to be in printer mode. - */ - if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) { - dgap_wmove(ch, ch->ch_digi.digi_onstr, - (int) ch->ch_digi.digi_onlen); - head = readw(&(bs->tx_head)) & tmask; - ch->ch_flags |= CH_PRON; - } +out: + /* + * If board is doing interrupts, ACK the interrupt. + */ + if (bd && bd->intr_running) + readb(bd->re_map_port + 2); - /* - * On the other hand, output the printer OFF string, if we are - * currently in printer mode, but need to output to the terminal. - */ - if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { - dgap_wmove(ch, ch->ch_digi.digi_offstr, - (int) ch->ch_digi.digi_offlen); - head = readw(&(bs->tx_head)) & tmask; - ch->ch_flags &= ~CH_PRON; + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return; } - n = count; + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); +} - /* - * If the write wraps over the top of the circular buffer, - * move the portion up to the wrap point, and reset the - * pointers to the bottom. - */ - remain = ch->ch_tstart + ch->ch_tsize - head; +/* + * dgap_found_board() + * + * A board has been found, init it. + */ +static struct board_t *dgap_found_board(struct pci_dev *pdev, int id, + int boardnum) +{ + struct board_t *brd; + unsigned int pci_irq; + int i; + int ret; - if (n >= remain) { - n -= remain; - vaddr = ch->ch_taddr + head; + /* get the board structure and prep it */ + brd = kzalloc(sizeof(struct board_t), GFP_KERNEL); + if (!brd) + return ERR_PTR(-ENOMEM); - memcpy_toio(vaddr, (u8 *) buf, remain); + /* store the info for the board we've found */ + brd->magic = DGAP_BOARD_MAGIC; + brd->boardnum = boardnum; + brd->vendor = dgap_pci_tbl[id].vendor; + brd->device = dgap_pci_tbl[id].device; + brd->pdev = pdev; + brd->pci_bus = pdev->bus->number; + brd->pci_slot = PCI_SLOT(pdev->devfn); + brd->name = dgap_ids[id].name; + brd->maxports = dgap_ids[id].maxports; + brd->type = dgap_ids[id].config_type; + brd->dpatype = dgap_ids[id].dpatype; + brd->dpastatus = BD_NOFEP; + init_waitqueue_head(&brd->state_wait); - head = ch->ch_tstart; - buf += remain; - } + spin_lock_init(&brd->bd_lock); - if (n > 0) { + brd->inhibit_poller = FALSE; + brd->wait_for_bios = 0; + brd->wait_for_fep = 0; - /* - * Move rest of data. - */ - vaddr = ch->ch_taddr + head; - remain = n; + for (i = 0; i < MAXPORTS; i++) + brd->channels[i] = NULL; + + /* store which card & revision we have */ + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor); + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice); + pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); + + pci_irq = pdev->irq; + brd->irq = pci_irq; - memcpy_toio(vaddr, (u8 *) buf, remain); - head += remain; + /* get the PCI Base Address Registers */ + /* Xr Jupiter and EPC use BAR 2 */ + if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) { + brd->membase = pci_resource_start(pdev, 2); + brd->membase_end = pci_resource_end(pdev, 2); + } + /* Everyone else uses BAR 0 */ + else { + brd->membase = pci_resource_start(pdev, 0); + brd->membase_end = pci_resource_end(pdev, 0); } - if (count) { - ch->ch_txcount += count; - head &= tmask; - writew(head, &(bs->tx_head)); + if (!brd->membase) { + ret = -ENODEV; + goto free_brd; } - dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); + if (brd->membase & 1) + brd->membase &= ~3; + else + brd->membase &= ~15; /* - * If this is the print device, and the - * printer is still on, we need to turn it - * off before going idle. If the buffer is - * non-empty, wait until it goes empty. - * Otherwise turn it off right now. + * On the PCI boards, there is no IO space allocated + * The I/O registers will be in the first 3 bytes of the + * upper 2MB of the 4MB memory space. The board memory + * will be mapped into the low 2MB of the 4MB memory space */ - if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { - tail = readw(&(bs->tx_tail)) & tmask; - - if (tail != head) { - un->un_flags |= UN_EMPTY; - writeb(1, &(bs->iempty)); - } else { - dgap_wmove(ch, ch->ch_digi.digi_offstr, - (int) ch->ch_digi.digi_offlen); - head = readw(&(bs->tx_head)) & tmask; - ch->ch_flags &= ~CH_PRON; - } - } - - /* Update printer buffer empty time. */ - if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0) - && (ch->ch_digi.digi_bufsize > 0)) { - ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps; - } - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - - return count; -} + brd->port = brd->membase + PCI_IO_OFFSET; + brd->port_end = brd->port + PCI_IO_SIZE; -/* - * Return modem signals to ld. - */ -static int dgap_tty_tiocmget(struct tty_struct *tty) -{ - struct channel_t *ch; - struct un_t *un; - int result; - u8 mstat; - ulong lock_flags; + /* + * Special initialization for non-PLX boards + */ + if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) { + unsigned short cmd; - if (!tty || tty->magic != TTY_MAGIC) - return -EIO; + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x46, 0); - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EIO; + /* Limit burst length to 2 doubleword transactions */ + pci_write_config_byte(pdev, 0x42, 1); - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -EIO; + /* + * Enable IO and mem if not already done. + * This was needed for support on Itanium. + */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_write_config_word(pdev, PCI_COMMAND, cmd); + } - spin_lock_irqsave(&ch->ch_lock, lock_flags); + /* init our poll helper tasklet */ + tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet, + (unsigned long) brd); - mstat = readb(&(ch->ch_bs->m_stat)); - /* Append any outbound signals that might be pending... */ - mstat |= ch->ch_mostat; + ret = dgap_remap(brd); + if (ret) + goto free_brd; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + pr_info("dgap: board %d: %s (rev %d), irq %ld\n", + boardnum, brd->name, brd->rev, brd->irq); - result = 0; + return brd; - if (mstat & D_DTR(ch)) - result |= TIOCM_DTR; - if (mstat & D_RTS(ch)) - result |= TIOCM_RTS; - if (mstat & D_CTS(ch)) - result |= TIOCM_CTS; - if (mstat & D_DSR(ch)) - result |= TIOCM_DSR; - if (mstat & D_RI(ch)) - result |= TIOCM_RI; - if (mstat & D_CD(ch)) - result |= TIOCM_CD; +free_brd: + kfree(brd); - return result; + return ERR_PTR(ret); } /* - * dgap_tty_tiocmset() + * dgap_intr() * - * Set modem signals, called by ld. + * Driver interrupt handler. */ -static int dgap_tty_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) +static irqreturn_t dgap_intr(int irq, void *voidbrd) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + struct board_t *brd = voidbrd; - if (!tty || tty->magic != TTY_MAGIC) - return -EIO; + if (!brd) + return IRQ_NONE; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EIO; + /* + * Check to make sure its for us. + */ + if (brd->magic != DGAP_BOARD_MAGIC) + return IRQ_NONE; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -EIO; + brd->intr_count++; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return -EIO; + /* + * Schedule tasklet to run at a better time. + */ + tasklet_schedule(&brd->helper_tasklet); + return IRQ_HANDLED; +} - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); +/***************************************************************************** +* +* Function: +* +* dgap_poll_handler +* +* Author: +* +* Scott H Kilau +* +* Parameters: +* +* dummy -- ignored +* +* Return Values: +* +* none +* +* Description: +* +* As each timer expires, it determines (a) whether the "transmit" +* waiter needs to be woken up, and (b) whether the poller needs to +* be rescheduled. +* +******************************************************************************/ - if (set & TIOCM_RTS) { - ch->ch_mforce |= D_RTS(ch); - ch->ch_mval |= D_RTS(ch); - } +static void dgap_poll_handler(ulong dummy) +{ + unsigned int i; + struct board_t *brd; + unsigned long lock_flags; + ulong new_time; - if (set & TIOCM_DTR) { - ch->ch_mforce |= D_DTR(ch); - ch->ch_mval |= D_DTR(ch); - } + dgap_poll_counter++; - if (clear & TIOCM_RTS) { - ch->ch_mforce |= D_RTS(ch); - ch->ch_mval &= ~(D_RTS(ch)); - } + /* + * Do not start the board state machine until + * driver tells us its up and running, and has + * everything it needs. + */ + if (dgap_driver_state != DRIVER_READY) + goto schedule_poller; - if (clear & TIOCM_DTR) { - ch->ch_mforce |= D_DTR(ch); - ch->ch_mval &= ~(D_DTR(ch)); - } + /* + * If we have just 1 board, or the system is not SMP, + * then use the typical old style poller. + * Otherwise, use our new tasklet based poller, which should + * speed things up for multiple boards. + */ + if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) { + for (i = 0; i < dgap_numboards; i++) { - dgap_param(ch, bd, un->un_type); + brd = dgap_board[i]; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (brd->state == BOARD_FAILED) + continue; + if (!brd->intr_running) + /* Call the real board poller directly */ + dgap_poll_tasklet((unsigned long) brd); + } + } else { + /* + * Go thru each board, kicking off a + * tasklet for each if needed + */ + for (i = 0; i < dgap_numboards; i++) { + brd = dgap_board[i]; + + /* + * Attempt to grab the board lock. + * + * If we can't get it, no big deal, the next poll + * will get it. Basically, I just really don't want + * to spin in here, because I want to kick off my + * tasklets as fast as I can, and then get out the + * poller. + */ + if (!spin_trylock(&brd->bd_lock)) + continue; - return 0; -} + /* + * If board is in a failed state, don't bother + * scheduling a tasklet + */ + if (brd->state == BOARD_FAILED) { + spin_unlock(&brd->bd_lock); + continue; + } -/* - * dgap_tty_send_break() - * - * Send a Break, called by ld. - */ -static int dgap_tty_send_break(struct tty_struct *tty, int msec) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + /* Schedule a poll helper task */ + if (!brd->intr_running) + tasklet_schedule(&brd->helper_tasklet); - if (!tty || tty->magic != TTY_MAGIC) - return -EIO; + /* + * Can't do DGAP_UNLOCK here, as we don't have + * lock_flags because we did a trylock above. + */ + spin_unlock(&brd->bd_lock); + } + } - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EIO; +schedule_poller: - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -EIO; + /* + * Schedule ourself back at the nominal wakeup interval. + */ + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick); - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return -EIO; + new_time = dgap_poll_time - jiffies; - switch (msec) { - case -1: - msec = 0xFFFF; - break; - case 0: - msec = 1; - break; - default: - msec /= 10; - break; + if ((ulong) new_time >= 2 * dgap_poll_tick) { + dgap_poll_time = + jiffies + dgap_jiffies_from_ms(dgap_poll_tick); } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); -#if 0 - dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); -#endif - dgap_cmdw(ch, SBREAK, (u16) msec, 0); - - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_poll_timer.function = dgap_poll_handler; + dgap_poll_timer.data = 0; + dgap_poll_timer.expires = dgap_poll_time; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - return 0; + if (!dgap_poll_stop) + add_timer(&dgap_poll_timer); } -/* - * dgap_tty_wait_until_sent() +/*======================================================================= * - * wait until data has been transmitted, called by ld. - */ -static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout) -{ - dgap_wait_for_drain(tty); -} - -/* - * dgap_send_xchar() + * dgap_cmdb - Sends a 2 byte command to the FEP. * - * send a high priority character, called by ld. - */ -static void dgap_tty_send_xchar(struct tty_struct *tty, char c) + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * byte1 - Integer containing first byte to be sent. + * byte2 - Integer containing second byte to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, + u8 byte2, uint ncmds) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; - if (!tty || tty->magic != TTY_MAGIC) + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) + /* + * Check if board is still alive. + */ + if (ch->ch_bd->state == BOARD_FAILED) return; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + + if (!vaddr) return; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); + + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; return; + } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* + * Put the data in the circular command buffer. + */ + writeb(cmd, (vaddr + head + CMDSTART + 0)); + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writeb(byte1, (vaddr + head + CMDSTART + 2)); + writeb(byte2, (vaddr + head + CMDSTART + 3)); + + head = (head + 4) & (CMDMAX - CMDSTART - 4); + + writew(head, &(cm_addr->cm_head)); /* - * This is technically what we should do. - * However, the NIST tests specifically want - * to see each XON or XOFF character that it - * sends, so lets just send each character - * by hand... + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. */ -#if 0 - if (c == STOP_CHAR(tty)) - dgap_cmdw(ch, RPAUSE, 0, 0); - else if (c == START_CHAR(tty)) - dgap_cmdw(ch, RRESUME, 0, 0); - else - dgap_wmove(ch, &c, 1); -#else - dgap_wmove(ch, &c, 1); -#endif + for (count = dgap_count ;;) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -} + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); -/* - * Return modem signals to ld. - */ -static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value) -{ - int result; - u8 mstat; - ulong lock_flags; - int rc; + n = (head - tail) & (CMDMAX - CMDSTART - 4); - spin_lock_irqsave(&ch->ch_lock, lock_flags); + if (n <= ncmds * sizeof(struct cm_t)) + break; - mstat = readb(&(ch->ch_bs->m_stat)); - /* Append any outbound signals that might be pending... */ - mstat |= ch->ch_mostat; + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + udelay(10); + } +} - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); +/*======================================================================= + * + * dgap_cmdw - Sends a 1 word command to the FEP. + * + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * word - Integer containing word to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds) +{ + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; - result = 0; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - if (mstat & D_DTR(ch)) - result |= TIOCM_DTR; - if (mstat & D_RTS(ch)) - result |= TIOCM_RTS; - if (mstat & D_CTS(ch)) - result |= TIOCM_CTS; - if (mstat & D_DSR(ch)) - result |= TIOCM_DSR; - if (mstat & D_RI(ch)) - result |= TIOCM_RI; - if (mstat & D_CD(ch)) - result |= TIOCM_CD; + /* + * Check if board is still alive. + */ + if (ch->ch_bd->state == BOARD_FAILED) + return; + + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + if (!vaddr) + return; - rc = put_user(result, value); + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); - return rc; -} + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; + return; + } -/* - * dgap_set_modem_info() - * - * Set modem signals, called by ld. - */ -static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, - struct un_t *un, unsigned int command, - unsigned int __user *value) -{ - int ret; - unsigned int arg; - ulong lock_flags; - ulong lock_flags2; + /* + * Put the data in the circular command buffer. + */ + writeb(cmd, (vaddr + head + CMDSTART + 0)); + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writew((u16) word, (vaddr + head + CMDSTART + 2)); - ret = get_user(arg, value); - if (ret) - return ret; + head = (head + 4) & (CMDMAX - CMDSTART - 4); - switch (command) { - case TIOCMBIS: - if (arg & TIOCM_RTS) { - ch->ch_mforce |= D_RTS(ch); - ch->ch_mval |= D_RTS(ch); - } + writew(head, &(cm_addr->cm_head)); - if (arg & TIOCM_DTR) { - ch->ch_mforce |= D_DTR(ch); - ch->ch_mval |= D_DTR(ch); - } + /* + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. + */ + for (count = dgap_count ;;) { - break; + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); - case TIOCMBIC: - if (arg & TIOCM_RTS) { - ch->ch_mforce |= D_RTS(ch); - ch->ch_mval &= ~(D_RTS(ch)); - } + n = (head - tail) & (CMDMAX - CMDSTART - 4); - if (arg & TIOCM_DTR) { - ch->ch_mforce |= D_DTR(ch); - ch->ch_mval &= ~(D_DTR(ch)); + if (n <= ncmds * sizeof(struct cm_t)) + break; + + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; } + udelay(10); + } +} - break; +/*======================================================================= + * + * dgap_cmdw_ext - Sends a extended word command to the FEP. + * + * ch - Pointer to channel structure. + * cmd - Command to be sent. + * word - Integer containing word to be sent. + * ncmds - Wait until ncmds or fewer cmds are left + * in the cmd buffer before returning. + * + *=======================================================================*/ +static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) +{ + char __iomem *vaddr; + struct __iomem cm_t *cm_addr; + uint count; + uint n; + u16 head; + u16 tail; - case TIOCMSET: - ch->ch_mforce = D_DTR(ch)|D_RTS(ch); + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - if (arg & TIOCM_RTS) - ch->ch_mval |= D_RTS(ch); - else - ch->ch_mval &= ~(D_RTS(ch)); + /* + * Check if board is still alive. + */ + if (ch->ch_bd->state == BOARD_FAILED) + return; - if (arg & TIOCM_DTR) - ch->ch_mval |= (D_DTR(ch)); - else - ch->ch_mval &= ~(D_DTR(ch)); + /* + * Make sure the pointers are in range before + * writing to the FEP memory. + */ + vaddr = ch->ch_bd->re_map_membase; + if (!vaddr) + return; - break; + cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); + head = readw(&(cm_addr->cm_head)); - default: - return -EINVAL; + /* + * Forget it if pointers out of range. + */ + if (head >= (CMDMAX - CMDSTART) || (head & 03)) { + ch->ch_bd->state = BOARD_FAILED; + return; } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* + * Put the data in the circular command buffer. + */ - dgap_param(ch, bd, un->un_type); + /* Write an FF to tell the FEP that we want an extended command */ + writeb((u8) 0xff, (vaddr + head + CMDSTART + 0)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); + writew((u16) cmd, (vaddr + head + CMDSTART + 2)); - return 0; -} + /* + * If the second part of the command won't fit, + * put it at the beginning of the circular buffer. + */ + if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03))) + writew((u16) word, (vaddr + CMDSTART)); + else + writew((u16) word, (vaddr + head + CMDSTART + 4)); -/* - * dgap_tty_digigeta() - * - * Ioctl to get the information for ditty. - * - * - * - */ -static int dgap_tty_digigeta(struct channel_t *ch, - struct digi_t __user *retinfo) -{ - struct digi_t tmp; - ulong lock_flags; + head = (head + 8) & (CMDMAX - CMDSTART - 4); - if (!retinfo) - return -EFAULT; + writew(head, &(cm_addr->cm_head)); - memset(&tmp, 0, sizeof(tmp)); + /* + * Wait if necessary before updating the head + * pointer to limit the number of outstanding + * commands to the FEP. If the time spent waiting + * is outlandish, declare the FEP dead. + */ + for (count = dgap_count ;;) { - spin_lock_irqsave(&ch->ch_lock, lock_flags); - memcpy(&tmp, &ch->ch_digi, sizeof(tmp)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + head = readw(&(cm_addr->cm_head)); + tail = readw(&(cm_addr->cm_tail)); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + n = (head - tail) & (CMDMAX - CMDSTART - 4); - return 0; + if (n <= ncmds * sizeof(struct cm_t)) + break; + + if (--count == 0) { + ch->ch_bd->state = BOARD_FAILED; + return; + } + udelay(10); + } } -/* - * dgap_tty_digiseta() - * - * Ioctl to set the information for ditty. +/*======================================================================= * + * dgap_wmove - Write data to FEP buffer. * + * ch - Pointer to channel structure. + * buf - Poiter to characters to be moved. + * cnt - Number of characters to move. * - */ -static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd, - struct un_t *un, struct digi_t __user *new_info) + *=======================================================================*/ +static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt) { - struct digi_t new_digi; - ulong lock_flags = 0; - unsigned long lock_flags2; - - if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) - return -EFAULT; - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - - memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t)); - - if (ch->ch_digi.digi_maxcps < 1) - ch->ch_digi.digi_maxcps = 1; - - if (ch->ch_digi.digi_maxcps > 10000) - ch->ch_digi.digi_maxcps = 10000; - - if (ch->ch_digi.digi_bufsize < 10) - ch->ch_digi.digi_bufsize = 10; + int n; + char __iomem *taddr; + struct bs_t __iomem *bs; + u16 head; - if (ch->ch_digi.digi_maxchar < 1) - ch->ch_digi.digi_maxchar = 1; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize) - ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize; + /* + * Check parameters. + */ + bs = ch->ch_bs; + head = readw(&(bs->tx_head)); - if (ch->ch_digi.digi_onlen > DIGI_PLEN) - ch->ch_digi.digi_onlen = DIGI_PLEN; + /* + * If pointers are out of range, just return. + */ + if ((cnt > ch->ch_tsize) || + (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) + return; - if (ch->ch_digi.digi_offlen > DIGI_PLEN) - ch->ch_digi.digi_offlen = DIGI_PLEN; + /* + * If the write wraps over the top of the circular buffer, + * move the portion up to the wrap point, and reset the + * pointers to the bottom. + */ + n = ch->ch_tstart + ch->ch_tsize - head; - dgap_param(ch, bd, un->un_type); + if (cnt >= n) { + cnt -= n; + taddr = ch->ch_taddr + head; + memcpy_toio(taddr, buf, n); + head = ch->ch_tstart; + buf += n; + } - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* + * Move rest of data. + */ + taddr = ch->ch_taddr + head; + n = cnt; + memcpy_toio(taddr, buf, n); + head += cnt; - return 0; + writew(head, &(bs->tx_head)); } /* - * dgap_tty_digigetedelay() - * - * Ioctl to get the current edelay setting. - * - * - * + * Calls the firmware to reset this channel. */ -static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo) +static void dgap_firmware_reset_port(struct channel_t *ch) { - struct channel_t *ch; - struct un_t *un; - int tmp; - ulong lock_flags; - - if (!retinfo) - return -EFAULT; - - if (!tty || tty->magic != TTY_MAGIC) - return -EFAULT; + dgap_cmdb(ch, CHRESET, 0, 0, 0); - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return -EFAULT; + /* + * Now that the channel is reset, we need to make sure + * all the current settings get reapplied to the port + * in the firmware. + * + * So we will set the driver's cache of firmware + * settings all to 0, and then call param. + */ + ch->ch_fepiflag = 0; + ch->ch_fepcflag = 0; + ch->ch_fepoflag = 0; + ch->ch_fepstartc = 0; + ch->ch_fepstopc = 0; + ch->ch_fepastartc = 0; + ch->ch_fepastopc = 0; + ch->ch_mostat = 0; + ch->ch_hflow = 0; +} - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -EFAULT; +/*======================================================================= + * + * dgap_param - Set Digi parameters. + * + * struct tty_struct * - TTY for port. + * + *=======================================================================*/ +static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type) +{ + u16 head; + u16 cflag; + u16 iflag; + u8 mval; + u8 hflow; - memset(&tmp, 0, sizeof(tmp)); + /* + * If baud rate is zero, flush queues, and set mval to drop DTR. + */ + if ((ch->ch_c_cflag & (CBAUD)) == 0) { - spin_lock_irqsave(&ch->ch_lock, lock_flags); - tmp = readw(&(ch->ch_bs->edelay)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + /* flush rx */ + head = readw(&(ch->ch_bs->rx_head)); + writew(head, &(ch->ch_bs->rx_tail)); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + /* flush tx */ + head = readw(&(ch->ch_bs->tx_head)); + writew(head, &(ch->ch_bs->tx_tail)); - return 0; -} + ch->ch_flags |= (CH_BAUD0); -/* - * dgap_tty_digisetedelay() - * - * Ioctl to set the EDELAY setting - * - */ -static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info) -{ - int new_digi; - ulong lock_flags; - ulong lock_flags2; + /* Drop RTS and DTR */ + ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch)); + mval = D_DTR(ch) | D_RTS(ch); + ch->ch_baud_info = 0; - if (copy_from_user(&new_digi, new_info, sizeof(int))) - return -EFAULT; + } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) { + /* + * Tell the fep to do the command + */ - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0); - writew((u16) new_digi, &(ch->ch_bs->edelay)); + /* + * Now go get from fep mem, what the fep + * believes the custom baud rate is. + */ + ch->ch_custom_speed = dgap_get_custom_baud(ch); + ch->ch_baud_info = ch->ch_custom_speed; - dgap_param(ch, bd, un->un_type); + /* Handle transition from B0 */ + if (ch->ch_flags & CH_BAUD0) { + ch->ch_flags &= ~(CH_BAUD0); + ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); + } + mval = D_DTR(ch) | D_RTS(ch); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + } else { + /* + * Set baud rate, character size, and parity. + */ - return 0; -} -/* - * dgap_tty_digigetcustombaud() - * - * Ioctl to get the current custom baud rate setting. - */ -static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un, - int __user *retinfo) -{ - int tmp; - ulong lock_flags; + int iindex = 0; + int jindex = 0; + int baud = 0; - if (!retinfo) - return -EFAULT; + ulong bauds[4][16] = { + { /* slowbaud */ + 0, 50, 75, 110, + 134, 150, 200, 300, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 }, + { /* slowbaud & CBAUDEX */ + 0, 57600, 115200, 230400, + 460800, 150, 200, 921600, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 }, + { /* fastbaud */ + 0, 57600, 76800, 115200, + 14400, 57600, 230400, 76800, + 115200, 230400, 28800, 460800, + 921600, 9600, 19200, 38400 }, + { /* fastbaud & CBAUDEX */ + 0, 57600, 115200, 230400, + 460800, 150, 200, 921600, + 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400 } + }; - memset(&tmp, 0, sizeof(tmp)); + /* + * Only use the TXPrint baud rate if the + * terminal unit is NOT open + */ + if (!(ch->ch_tun.un_flags & UN_ISOPEN) && + un_type == DGAP_PRINT) + baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; + else + baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; - spin_lock_irqsave(&ch->ch_lock, lock_flags); - tmp = dgap_get_custom_baud(ch); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + if (ch->ch_c_cflag & CBAUDEX) + iindex = 1; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; + if (ch->ch_digi.digi_flags & DIGI_FAST) + iindex += 2; - return 0; -} + jindex = baud; -/* - * dgap_tty_digisetcustombaud() - * - * Ioctl to set the custom baud rate setting - */ -static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd, - struct un_t *un, int __user *new_info) -{ - uint new_rate; - ulong lock_flags; - ulong lock_flags2; + if ((iindex >= 0) && (iindex < 4) && + (jindex >= 0) && (jindex < 16)) + baud = bauds[iindex][jindex]; + else + baud = 0; - if (copy_from_user(&new_rate, new_info, sizeof(unsigned int))) - return -EFAULT; + if (baud == 0) + baud = 9600; - if (bd->bd_flags & BD_FEP5PLUS) { + ch->ch_baud_info = baud; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* + * CBAUD has bit position 0x1000 set these days to + * indicate Linux baud rate remap. + * We use a different bit assignment for high speed. + * Clear this bit out while grabbing the parts of + * "cflag" we want. + */ + cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | + CSTOPB | CSIZE); - ch->ch_custom_speed = new_rate; + /* + * HUPCL bit is used by FEP to indicate fast baud + * table is to be used. + */ + if ((ch->ch_digi.digi_flags & DIGI_FAST) || + (ch->ch_c_cflag & CBAUDEX)) + cflag |= HUPCL; - dgap_param(ch, bd, un->un_type); + if ((ch->ch_c_cflag & CBAUDEX) && + !(ch->ch_digi.digi_flags & DIGI_FAST)) { + /* + * The below code is trying to guarantee that only + * baud rates 115200, 230400, 460800, 921600 are + * remapped. We use exclusive or because the various + * baud rates share common bit positions and therefore + * can't be tested for easily. + */ + tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX; + int baudpart = 0; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - } + /* + * Map high speed requests to index + * into FEP's baud table + */ + switch (tcflag) { + case B57600: + baudpart = 1; + break; +#ifdef B76800 + case B76800: + baudpart = 2; + break; +#endif + case B115200: + baudpart = 3; + break; + case B230400: + baudpart = 9; + break; + case B460800: + baudpart = 11; + break; +#ifdef B921600 + case B921600: + baudpart = 12; + break; +#endif + default: + baudpart = 0; + } - return 0; -} + if (baudpart) + cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart; + } -/* - * dgap_set_termios() - */ -static void dgap_tty_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - unsigned long lock_flags; - unsigned long lock_flags2; + cflag &= 0xffff; - if (!tty || tty->magic != TTY_MAGIC) - return; + if (cflag != ch->ch_fepcflag) { + ch->ch_fepcflag = (u16) (cflag & 0xffff); - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + /* + * Okay to have channel and board + * locks held calling this + */ + dgap_cmdw(ch, SCFLAG, (u16) cflag, 0); + } - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + /* Handle transition from B0 */ + if (ch->ch_flags & CH_BAUD0) { + ch->ch_flags &= ~(CH_BAUD0); + ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); + } + mval = D_DTR(ch) | D_RTS(ch); + } - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + /* + * Get input flags. + */ + iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | + INPCK | ISTRIP | IXON | IXANY | IXOFF); - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) { + iflag &= ~(IXON | IXOFF); + ch->ch_c_iflag &= ~(IXON | IXOFF); + } - ch->ch_c_cflag = tty->termios.c_cflag; - ch->ch_c_iflag = tty->termios.c_iflag; - ch->ch_c_oflag = tty->termios.c_oflag; - ch->ch_c_lflag = tty->termios.c_lflag; - ch->ch_startc = tty->termios.c_cc[VSTART]; - ch->ch_stopc = tty->termios.c_cc[VSTOP]; + /* + * Only the IBM Xr card can switch between + * 232 and 422 modes on the fly + */ + if (bd->device == PCI_DEV_XR_IBM_DID) { + if (ch->ch_digi.digi_flags & DIGI_422) + dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0); + else + dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0); + } - dgap_carrier(ch); - dgap_param(ch, bd, un->un_type); + if (ch->ch_digi.digi_flags & DIGI_ALTPIN) + iflag |= IALTPIN; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -} + if (iflag != ch->ch_fepiflag) { + ch->ch_fepiflag = iflag; -static void dgap_tty_throttle(struct tty_struct *tty) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + /* Okay to have channel and board locks held calling this */ + dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0); + } - if (!tty || tty->magic != TTY_MAGIC) - return; + /* + * Select hardware handshaking. + */ + hflow = 0; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + if (ch->ch_c_cflag & CRTSCTS) + hflow |= (D_RTS(ch) | D_CTS(ch)); + if (ch->ch_digi.digi_flags & RTSPACE) + hflow |= D_RTS(ch); + if (ch->ch_digi.digi_flags & DTRPACE) + hflow |= D_DTR(ch); + if (ch->ch_digi.digi_flags & CTSPACE) + hflow |= D_CTS(ch); + if (ch->ch_digi.digi_flags & DSRPACE) + hflow |= D_DSR(ch); + if (ch->ch_digi.digi_flags & DCDPACE) + hflow |= D_CD(ch); - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + if (hflow != ch->ch_hflow) { + ch->ch_hflow = hflow; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0); + } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* + * Set RTS and/or DTR Toggle if needed, + * but only if product is FEP5+ based. + */ + if (bd->bd_flags & BD_FEP5PLUS) { + u16 hflow2 = 0; - ch->ch_flags |= (CH_RXBLOCK); -#if 1 - dgap_cmdw(ch, RPAUSE, 0, 0); -#endif + if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) + hflow2 |= (D_RTS(ch)); + if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) + hflow2 |= (D_DTR(ch)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_cmdw_ext(ch, 0xff03, hflow2, 0); + } -} + /* + * Set modem control lines. + */ -static void dgap_tty_unthrottle(struct tty_struct *tty) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + mval ^= ch->ch_mforce & (mval ^ ch->ch_mval); - if (!tty || tty->magic != TTY_MAGIC) - return; + if (ch->ch_mostat ^ mval) { + ch->ch_mostat = mval; - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0); + } - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + /* + * Read modem signals, and then call carrier function. + */ + ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); + dgap_carrier(ch); - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + /* + * Set the start and stop characters. + */ + if (ch->ch_startc != ch->ch_fepstartc || + ch->ch_stopc != ch->ch_fepstopc) { + ch->ch_fepstartc = ch->ch_startc; + ch->ch_fepstopc = ch->ch_stopc; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0); + } - ch->ch_flags &= ~(CH_RXBLOCK); + /* + * Set the Auxiliary start and stop characters. + */ + if (ch->ch_astartc != ch->ch_fepastartc || + ch->ch_astopc != ch->ch_fepastopc) { + ch->ch_fepastartc = ch->ch_astartc; + ch->ch_fepastopc = ch->ch_astopc; -#if 1 - dgap_cmdw(ch, RRESUME, 0, 0); -#endif + /* Okay to have channel and board locks held calling this */ + dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0); + } - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return 0; } -static void dgap_tty_start(struct tty_struct *tty) +/* + * dgap_block_til_ready() + * + * Wait for DCD, if needed. + */ +static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, + struct channel_t *ch) { - struct board_t *bd; - struct channel_t *ch; + int retval = 0; struct un_t *un; ulong lock_flags; - ulong lock_flags2; + uint old_flags; + int sleep_on_un_flags; - if (!tty || tty->magic != TTY_MAGIC) - return; + if (!tty || tty->magic != TTY_MAGIC || !file || !ch || + ch->magic != DGAP_CHANNEL_MAGIC) + return -EIO; un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + return -EIO; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + spin_lock_irqsave(&ch->ch_lock, lock_flags); - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + ch->ch_wopen++; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* Loop forever */ + while (1) { - dgap_cmdw(ch, RESUMETX, 0, 0); + sleep_on_un_flags = 0; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -} + /* + * If board has failed somehow during our sleep, + * bail with error. + */ + if (ch->ch_bd->state == BOARD_FAILED) { + retval = -EIO; + break; + } -static void dgap_tty_stop(struct tty_struct *tty) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + /* If tty was hung up, break out of loop and set error. */ + if (tty_hung_up_p(file)) { + retval = -EAGAIN; + break; + } - if (!tty || tty->magic != TTY_MAGIC) - return; + /* + * If either unit is in the middle of the fragile part of close, + * we just cannot touch the channel safely. + * Go back to sleep, knowing that when the channel can be + * touched safely, the close routine will signal the + * ch_wait_flags to wake us back up. + */ + if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & + UN_CLOSING)) { - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + /* + * Our conditions to leave cleanly and happily: + * 1) NONBLOCKING on the tty is set. + * 2) CLOCAL is set. + * 3) DCD (fake or real) is active. + */ - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + if (file->f_flags & O_NONBLOCK) + break; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + if (tty->flags & (1 << TTY_IO_ERROR)) + break; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + if (ch->ch_flags & CH_CD) + break; - dgap_cmdw(ch, PAUSETX, 0, 0); + if (ch->ch_flags & CH_FCAR) + break; + } else { + sleep_on_un_flags = 1; + } - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); -} + /* + * If there is a signal pending, the user probably + * interrupted (ctrl-c) us. + * Leave loop with error set. + */ + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } -/* - * dgap_tty_flush_chars() - * - * Flush the cook buffer - * - * Note to self, and any other poor souls who venture here: - * - * flush in this case DOES NOT mean dispose of the data. - * instead, it means "stop buffering and send it if you - * haven't already." Just guess how I figured that out... SRW 2-Jun-98 - * - * It is also always called in interrupt context - JAR 8-Sept-99 - */ -static void dgap_tty_flush_chars(struct tty_struct *tty) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - ulong lock_flags; - ulong lock_flags2; + /* + * Store the flags before we let go of channel lock + */ + if (sleep_on_un_flags) + old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags; + else + old_flags = ch->ch_flags; - if (!tty || tty->magic != TTY_MAGIC) - return; + /* + * Let go of channel lock before calling schedule. + * Our poller will get any FEP events and wake us up when DCD + * eventually goes active. + */ - un = tty->driver_data; - if (!un || un->magic != DGAP_UNIT_MAGIC) - return; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + /* + * Wait for something in the flags to change + * from the current value. + */ + if (sleep_on_un_flags) { + retval = wait_event_interruptible(un->un_flags_wait, + (old_flags != (ch->ch_tun.un_flags | + ch->ch_pun.un_flags))); + } else { + retval = wait_event_interruptible(ch->ch_flags_wait, + (old_flags != ch->ch_flags)); + } - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return; + /* + * We got woken up for some reason. + * Before looping around, grab our channel lock. + */ + spin_lock_irqsave(&ch->ch_lock, lock_flags); + } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + ch->ch_wopen--; - /* TODO: Do something here */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return retval; } /* @@ -3609,2005 +3245,2126 @@ static void dgap_tty_flush_buffer(struct tty_struct *tty) tty_wakeup(tty); } -/***************************************************************************** - * - * The IOCTL function and all of its helpers - * - *****************************************************************************/ - /* - * dgap_tty_ioctl() + * dgap_tty_hangup() * - * The usual assortment of ioctl's + * Hangup the port. Like a close, but don't wait for output to drain. */ -static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg) +static void dgap_tty_hangup(struct tty_struct *tty) { struct board_t *bd; struct channel_t *ch; struct un_t *un; - int rc; - u16 head; - ulong lock_flags = 0; - ulong lock_flags2 = 0; - void __user *uarg = (void __user *) arg; if (!tty || tty->magic != TTY_MAGIC) - return -ENODEV; + return; un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) - return -ENODEV; + return; ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return -ENODEV; + return; bd = ch->ch_bd; if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return -ENODEV; - - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - - if (un->un_open_count <= 0) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EIO; - } - - switch (cmd) { - - /* Here are all the standard ioctl's that we MUST implement */ + return; - case TCSBRK: - /* - * TCSBRK is SVID version: non-zero arg --> no break - * this behaviour is exploited by tcdrain(). - * - * According to POSIX.1 spec (7.2.2.1.2) breaks should be - * between 0.25 and 0.5 seconds so we'll ask for something - * in the middle: 0.375 seconds. - */ - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (rc) - return rc; + /* flush the transmit queues */ + dgap_tty_flush_buffer(tty); +} - rc = dgap_wait_for_drain(tty); +/* + * dgap_tty_chars_in_buffer() + * + * Return number of characters that have not been transmitted yet. + * + * This routine is used by the line discipline to determine if there + * is data waiting to be transmitted/drained/flushed or not. + */ +static int dgap_tty_chars_in_buffer(struct tty_struct *tty) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + struct bs_t __iomem *bs; + u8 tbusy; + uint chars; + u16 thead, ttail, tmask, chead, ctail; + ulong lock_flags = 0; + ulong lock_flags2 = 0; - if (rc) - return -EINTR; + if (!tty) + return 0; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; - if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) - dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + bs = ch->ch_bs; + if (!bs) return 0; - case TCSBRKP: - /* support for POSIX tcsendbreak() + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - * According to POSIX.1 spec (7.2.2.1.2) breaks should be - * between 0.25 and 0.5 seconds so we'll ask for something - * in the middle: 0.375 seconds. - */ - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (rc) - return rc; + tmask = (ch->ch_tsize - 1); - rc = dgap_wait_for_drain(tty); - if (rc) - return -EINTR; + /* Get Transmit queue pointers */ + thead = readw(&(bs->tx_head)) & tmask; + ttail = readw(&(bs->tx_tail)) & tmask; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + /* Get tbusy flag */ + tbusy = readb(&(bs->tbusy)); - dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); + /* Get Command queue pointers */ + chead = readw(&(ch->ch_cm->cm_head)); + ctail = readw(&(ch->ch_cm->cm_tail)); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return 0; + /* + * The only way we know for sure if there is no pending + * data left to be transferred, is if: + * 1) Transmit head and tail are equal (empty). + * 2) Command queue head and tail are equal (empty). + * 3) The "TBUSY" flag is 0. (Transmitter not busy). + */ - case TIOCSBRK: + if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) { + chars = 0; + } else { + if (thead >= ttail) + chars = thead - ttail; + else + chars = thead - ttail + ch->ch_tsize; /* - * FEP5 doesn't support turning on a break unconditionally. - * The FEP5 device will stop sending a break automatically - * after the specified time value that was sent when turning on - * the break. + * Fudge factor here. + * If chars is zero, we know that the command queue had + * something in it or tbusy was set. Because we cannot + * be sure if there is still some data to be transmitted, + * lets lie, and tell ld we have 1 byte left. */ - rc = tty_check_change(tty); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (rc) - return rc; - - rc = dgap_wait_for_drain(tty); - if (rc) - return -EINTR; + if (chars == 0) { + /* + * If TBUSY is still set, and our tx buffers are empty, + * force the firmware to send me another wakeup after + * TBUSY has been cleared. + */ + if (tbusy != 0) { + spin_lock_irqsave(&ch->ch_lock, lock_flags); + un->un_flags |= UN_EMPTY; + writeb(1, &(bs->iempty)); + spin_unlock_irqrestore(&ch->ch_lock, + lock_flags); + } + chars = 1; + } + } - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + return chars; +} - dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); +static int dgap_wait_for_drain(struct tty_struct *tty) +{ + struct channel_t *ch; + struct un_t *un; + struct bs_t __iomem *bs; + int ret = 0; + uint count = 1; + ulong lock_flags = 0; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (!tty || tty->magic != TTY_MAGIC) + return -EIO; - return 0; + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -EIO; - case TIOCCBRK: - /* - * FEP5 doesn't support turning off a break unconditionally. - * The FEP5 device will stop sending a break automatically - * after the specified time value that was sent when turning on - * the break. - */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return -EIO; - case TIOCGSOFTCAR: + bs = ch->ch_bs; + if (!bs) + return -EIO; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* Loop until data is drained */ + while (count != 0) { - rc = put_user(C_CLOCAL(tty) ? 1 : 0, - (unsigned long __user *) arg); - return rc; + count = dgap_tty_chars_in_buffer(tty); - case TIOCSSOFTCAR: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (count == 0) + break; - rc = get_user(arg, (unsigned long __user *) arg); - if (rc) - return rc; + /* Set flag waiting for drain */ + spin_lock_irqsave(&ch->ch_lock, lock_flags); + un->un_flags |= UN_EMPTY; + writeb(1, &(bs->iempty)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - dgap_param(ch, bd, un->un_type); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* Go to sleep till we get woken up */ + ret = wait_event_interruptible(un->un_flags_wait, + ((un->un_flags & UN_EMPTY) == 0)); + /* If ret is non-zero, user ctrl-c'ed us */ + if (ret) + break; + } - return 0; + spin_lock_irqsave(&ch->ch_lock, lock_flags); + un->un_flags &= ~(UN_EMPTY); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - case TIOCMGET: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_get_modem_info(ch, uarg); + return ret; +} - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_set_modem_info(ch, bd, un, cmd, uarg); +/* + * dgap_maxcps_room + * + * Reduces bytes_available to the max number of characters + * that can be sent currently given the maxcps value, and + * returns the new bytes_available. This only affects printer + * output. + */ +static int dgap_maxcps_room(struct channel_t *ch, struct un_t *un, + int bytes_available) +{ + /* + * If its not the Transparent print device, return + * the full data amount. + */ + if (un->un_type != DGAP_PRINT) + return bytes_available; - /* - * Here are any additional ioctl's that we want to implement - */ + if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) { + int cps_limit = 0; + unsigned long current_time = jiffies; + unsigned long buffer_time = current_time + + (HZ * ch->ch_digi.digi_bufsize) / + ch->ch_digi.digi_maxcps; - case TCFLSH: - /* - * The linux tty driver doesn't have a flush - * input routine for the driver, assuming all backed - * up data is in the line disc. buffers. However, - * we all know that's not the case. Here, we - * act on the ioctl, but then lie and say we didn't - * so the line discipline will process the flush - * also. - */ - rc = tty_check_change(tty); - if (rc) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return rc; + if (ch->ch_cpstime < current_time) { + /* buffer is empty */ + ch->ch_cpstime = current_time; /* reset ch_cpstime */ + cps_limit = ch->ch_digi.digi_bufsize; + } else if (ch->ch_cpstime < buffer_time) { + /* still room in the buffer */ + cps_limit = ((buffer_time - ch->ch_cpstime) * + ch->ch_digi.digi_maxcps) / HZ; + } else { + /* no room in the buffer */ + cps_limit = 0; } - if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) { - if (!(un->un_type == DGAP_PRINT)) { - head = readw(&(ch->ch_bs->rx_head)); - writew(head, &(ch->ch_bs->rx_tail)); - writeb(0, &(ch->ch_bs->orun)); - } - } + bytes_available = min(cps_limit, bytes_available); + } - if ((arg != TCOFLUSH) && (arg != TCIOFLUSH)) { - /* pretend we didn't recognize this IOCTL */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return bytes_available; +} - return -ENOIOCTLCMD; - } +static inline void dgap_set_firmware_event(struct un_t *un, unsigned int event) +{ + struct channel_t *ch; + struct bs_t __iomem *bs; + + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + bs = ch->ch_bs; + if (!bs) + return; - ch->ch_flags &= ~CH_STOP; - head = readw(&(ch->ch_bs->tx_head)); - dgap_cmdw(ch, FLUSHTX, (u16) head, 0); - dgap_cmdw(ch, RESUMETX, 0, 0); - if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) { - ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY); - wake_up_interruptible(&ch->ch_tun.un_flags_wait); + if ((event & UN_LOW) != 0) { + if ((un->un_flags & UN_LOW) == 0) { + un->un_flags |= UN_LOW; + writeb(1, &(bs->ilow)); } - if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) { - ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY); - wake_up_interruptible(&ch->ch_pun.un_flags_wait); + } + if ((event & UN_LOW) != 0) { + if ((un->un_flags & UN_EMPTY) == 0) { + un->un_flags |= UN_EMPTY; + writeb(1, &(bs->iempty)); } - if (waitqueue_active(&tty->write_wait)) - wake_up_interruptible(&tty->write_wait); + } +} - /* Can't hold any locks when calling tty_wakeup! */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - tty_wakeup(tty); +/* + * dgap_tty_write_room() + * + * Return space available in Tx buffer + */ +static int dgap_tty_write_room(struct tty_struct *tty) +{ + struct channel_t *ch; + struct un_t *un; + struct bs_t __iomem *bs; + u16 head, tail, tmask; + int ret; + ulong lock_flags = 0; - /* pretend we didn't recognize this IOCTL */ - return -ENOIOCTLCMD; + if (!tty) + return 0; - case TCSETSF: - case TCSETSW: - /* - * The linux tty driver doesn't have a flush - * input routine for the driver, assuming all backed - * up data is in the line disc. buffers. However, - * we all know that's not the case. Here, we - * act on the ioctl, but then lie and say we didn't - * so the line discipline will process the flush - * also. - */ - if (cmd == TCSETSF) { - /* flush rx */ - ch->ch_flags &= ~CH_STOP; - head = readw(&(ch->ch_bs->rx_head)); - writew(head, &(ch->ch_bs->rx_tail)); - } + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; - /* now wait for all the output to drain */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - rc = dgap_wait_for_drain(tty); - if (rc) - return -EINTR; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; - /* pretend we didn't recognize this */ - return -ENOIOCTLCMD; + bs = ch->ch_bs; + if (!bs) + return 0; - case TCSETAW: + spin_lock_irqsave(&ch->ch_lock, lock_flags); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - rc = dgap_wait_for_drain(tty); - if (rc) - return -EINTR; + tmask = ch->ch_tsize - 1; + head = readw(&(bs->tx_head)) & tmask; + tail = readw(&(bs->tx_tail)) & tmask; - /* pretend we didn't recognize this */ - return -ENOIOCTLCMD; + ret = tail - head - 1; + if (ret < 0) + ret += ch->ch_tsize; - case TCXONC: - /* - * The Linux Line Discipline (LD) would do this for us if we - * let it, but we have the special firmware options to do this - * the "right way" regardless of hardware or software flow - * control so we'll do it outselves instead of letting the LD - * do it. - */ - rc = tty_check_change(tty); - if (rc) { - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return rc; - } + /* Limit printer to maxcps */ + ret = dgap_maxcps_room(ch, un, ret); - switch (arg) { + /* + * If we are printer device, leave space for + * possibly both the on and off strings. + */ + if (un->un_type == DGAP_PRINT) { + if (!(ch->ch_flags & CH_PRON)) + ret -= ch->ch_digi.digi_onlen; + ret -= ch->ch_digi.digi_offlen; + } else { + if (ch->ch_flags & CH_PRON) + ret -= ch->ch_digi.digi_offlen; + } - case TCOON: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - dgap_tty_start(tty); - return 0; - case TCOOFF: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - dgap_tty_stop(tty); - return 0; - case TCION: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - /* Make the ld do it */ - return -ENOIOCTLCMD; - case TCIOFF: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - /* Make the ld do it */ - return -ENOIOCTLCMD; - default: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EINVAL; - } + if (ret < 0) + ret = 0; - case DIGI_GETA: - /* get information for ditty */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digigeta(ch, uarg); + /* + * Schedule FEP to wake us up if needed. + * + * TODO: This might be overkill... + * Do we really need to schedule callbacks from the FEP + * in every case? Can we get smarter based on ret? + */ + dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - case DIGI_SETAW: - case DIGI_SETAF: + return ret; +} - /* set information for ditty */ - if (cmd == (DIGI_SETAW)) { +/* + * dgap_tty_write() + * + * Take data from the user or kernel and send it out to the FEP. + * In here exists all the Transparent Print magic as well. + */ +static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, + int count) +{ + struct channel_t *ch; + struct un_t *un; + struct bs_t __iomem *bs; + char __iomem *vaddr; + u16 head, tail, tmask, remain; + int bufcount, n; + ulong lock_flags; - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - rc = dgap_wait_for_drain(tty); - if (rc) - return -EINTR; - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); - } else - tty_ldisc_flush(tty); - /* fall thru */ + if (!tty) + return 0; - case DIGI_SETA: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digiseta(ch, bd, un, uarg); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; - case DIGI_GEDELAY: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digigetedelay(tty, uarg); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; - case DIGI_SEDELAY: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digisetedelay(ch, bd, un, uarg); + bs = ch->ch_bs; + if (!bs) + return 0; - case DIGI_GETCUSTOMBAUD: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digigetcustombaud(ch, un, uarg); + if (!count) + return 0; - case DIGI_SETCUSTOMBAUD: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return dgap_tty_digisetcustombaud(ch, bd, un, uarg); + spin_lock_irqsave(&ch->ch_lock, lock_flags); - case DIGI_RESET_PORT: - dgap_firmware_reset_port(ch); - dgap_param(ch, bd, un->un_type); - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return 0; + /* Get our space available for the channel from the board */ + tmask = ch->ch_tsize - 1; + head = readw(&(bs->tx_head)) & tmask; + tail = readw(&(bs->tx_tail)) & tmask; - default: - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + bufcount = tail - head - 1; + if (bufcount < 0) + bufcount += ch->ch_tsize; + + /* + * Limit printer output to maxcps overall, with bursts allowed + * up to bufsize characters. + */ + bufcount = dgap_maxcps_room(ch, un, bufcount); + + /* + * Take minimum of what the user wants to send, and the + * space available in the FEP buffer. + */ + count = min(count, bufcount); - return -ENOIOCTLCMD; + /* + * Bail if no space left. + */ + if (count <= 0) { + dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + return 0; } -} -static int dgap_alloc_flipbuf(struct board_t *brd) -{ /* - * allocate flip buffer for board. + * Output the printer ON string, if we are in terminal mode, but + * need to be in printer mode. */ - brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); - if (!brd->flipbuf) - return -ENOMEM; - - brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); - if (!brd->flipflagbuf) { - kfree(brd->flipbuf); - return -ENOMEM; + if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) { + dgap_wmove(ch, ch->ch_digi.digi_onstr, + (int) ch->ch_digi.digi_onlen); + head = readw(&(bs->tx_head)) & tmask; + ch->ch_flags |= CH_PRON; } - return 0; -} + /* + * On the other hand, output the printer OFF string, if we are + * currently in printer mode, but need to output to the terminal. + */ + if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { + dgap_wmove(ch, ch->ch_digi.digi_offstr, + (int) ch->ch_digi.digi_offlen); + head = readw(&(bs->tx_head)) & tmask; + ch->ch_flags &= ~CH_PRON; + } -static void dgap_free_flipbuf(struct board_t *brd) -{ - kfree(brd->flipbuf); - kfree(brd->flipflagbuf); -} + n = count; -/* - * Create pr and tty device entries - */ -static int dgap_tty_register_ports(struct board_t *brd) -{ - struct channel_t *ch; - int i; - int ret; + /* + * If the write wraps over the top of the circular buffer, + * move the portion up to the wrap point, and reset the + * pointers to the bottom. + */ + remain = ch->ch_tstart + ch->ch_tsize - head; - brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports), - GFP_KERNEL); - if (!brd->serial_ports) - return -ENOMEM; + if (n >= remain) { + n -= remain; + vaddr = ch->ch_taddr + head; - brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports), - GFP_KERNEL); - if (!brd->printer_ports) { - ret = -ENOMEM; - goto free_serial_ports; - } + memcpy_toio(vaddr, (u8 *) buf, remain); - for (i = 0; i < brd->nasync; i++) { - tty_port_init(&brd->serial_ports[i]); - tty_port_init(&brd->printer_ports[i]); + head = ch->ch_tstart; + buf += remain; } - ch = brd->channels[0]; - for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) { - - struct device *classp; - - classp = tty_port_register_device(&brd->serial_ports[i], - brd->serial_driver, - i, NULL); - - if (IS_ERR(classp)) { - ret = PTR_ERR(classp); - goto unregister_ttys; - } + if (n > 0) { - dgap_create_tty_sysfs(&ch->ch_tun, classp); - ch->ch_tun.un_sysfs = classp; + /* + * Move rest of data. + */ + vaddr = ch->ch_taddr + head; + remain = n; - classp = tty_port_register_device(&brd->printer_ports[i], - brd->print_driver, - i, NULL); + memcpy_toio(vaddr, (u8 *) buf, remain); + head += remain; - if (IS_ERR(classp)) { - ret = PTR_ERR(classp); - goto unregister_ttys; - } + } - dgap_create_tty_sysfs(&ch->ch_pun, classp); - ch->ch_pun.un_sysfs = classp; + if (count) { + ch->ch_txcount += count; + head &= tmask; + writew(head, &(bs->tx_head)); } - dgap_create_ports_sysfiles(brd); - return 0; + dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); -unregister_ttys: - while (i >= 0) { - ch = brd->channels[i]; - if (ch->ch_tun.un_sysfs) { - dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs); - tty_unregister_device(brd->serial_driver, i); - } + /* + * If this is the print device, and the + * printer is still on, we need to turn it + * off before going idle. If the buffer is + * non-empty, wait until it goes empty. + * Otherwise turn it off right now. + */ + if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { + tail = readw(&(bs->tx_tail)) & tmask; - if (ch->ch_pun.un_sysfs) { - dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs); - tty_unregister_device(brd->print_driver, i); + if (tail != head) { + un->un_flags |= UN_EMPTY; + writeb(1, &(bs->iempty)); + } else { + dgap_wmove(ch, ch->ch_digi.digi_offstr, + (int) ch->ch_digi.digi_offlen); + head = readw(&(bs->tx_head)) & tmask; + ch->ch_flags &= ~CH_PRON; } - i--; } - for (i = 0; i < brd->nasync; i++) { - tty_port_destroy(&brd->serial_ports[i]); - tty_port_destroy(&brd->printer_ports[i]); + /* Update printer buffer empty time. */ + if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0) + && (ch->ch_digi.digi_bufsize > 0)) { + ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps; } - kfree(brd->printer_ports); - brd->printer_ports = NULL; - -free_serial_ports: - kfree(brd->serial_ports); - brd->serial_ports = NULL; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - return ret; + return count; } /* - * Copies the BIOS code from the user to the board, - * and starts the BIOS running. + * dgap_tty_put_char() + * + * Put a character into ch->ch_buf + * + * - used by the line discipline for OPOST processing */ -static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len) +static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c) { - u8 __iomem *addr; - uint offset; - unsigned int i; - - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; - - addr = brd->re_map_membase; - - /* - * clear POST area - */ - for (i = 0; i < 16; i++) - writeb(0, addr + POSTAREA + i); - /* - * Download bios + * Simply call tty_write. */ - offset = 0x1000; - memcpy_toio(addr + offset, ubios, len); - - writel(0x0bf00401, addr); - writel(0, (addr + 4)); - - /* Clear the reset, and change states. */ - writeb(FEPCLR, brd->re_map_port); + dgap_tty_write(tty, &c, 1); + return 1; } /* - * Checks to see if the BIOS completed running on the card. + * Return modem signals to ld. */ -static int dgap_test_bios(struct board_t *brd) +static int dgap_tty_tiocmget(struct tty_struct *tty) { - u8 __iomem *addr; - u16 word; - u16 err1; - u16 err2; + struct channel_t *ch; + struct un_t *un; + int result; + u8 mstat; + ulong lock_flags; - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return -EINVAL; + if (!tty || tty->magic != TTY_MAGIC) + return -EIO; - addr = brd->re_map_membase; - word = readw(addr + POSTAREA); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -EIO; - /* - * It can take 5-6 seconds for a board to - * pass the bios self test and post results. - * Give it 10 seconds. - */ - brd->wait_for_bios = 0; - while (brd->wait_for_bios < 1000) { - /* Check to see if BIOS thinks board is good. (GD). */ - if (word == *(u16 *) "GD") - return 0; - msleep_interruptible(10); - brd->wait_for_bios++; - word = readw(addr + POSTAREA); - } + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return -EIO; - /* Gave up on board after too long of time taken */ - err1 = readw(addr + SEQUENCE); - err2 = readw(addr + ERROR); - dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n", - brd->name, err1, err2); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOBIOS; + spin_lock_irqsave(&ch->ch_lock, lock_flags); + + mstat = readb(&(ch->ch_bs->m_stat)); + /* Append any outbound signals that might be pending... */ + mstat |= ch->ch_mostat; + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + + result = 0; + + if (mstat & D_DTR(ch)) + result |= TIOCM_DTR; + if (mstat & D_RTS(ch)) + result |= TIOCM_RTS; + if (mstat & D_CTS(ch)) + result |= TIOCM_CTS; + if (mstat & D_DSR(ch)) + result |= TIOCM_DSR; + if (mstat & D_RI(ch)) + result |= TIOCM_RI; + if (mstat & D_CD(ch)) + result |= TIOCM_CD; - return -EIO; + return result; } /* - * Copies the FEP code from the user to the board, - * and starts the FEP running. + * dgap_tty_tiocmset() + * + * Set modem signals, called by ld. */ -static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len) +static int dgap_tty_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { - u8 __iomem *addr; - uint offset; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; + if (!tty || tty->magic != TTY_MAGIC) + return -EIO; - addr = brd->re_map_membase; + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -EIO; - /* - * Download FEP - */ - offset = 0x1000; - memcpy_toio(addr + offset, ufep, len); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return -EIO; - /* - * If board is a concentrator product, we need to give - * it its config string describing how the concentrators look. - */ - if ((brd->type == PCX) || (brd->type == PEPC)) { - u8 string[100]; - u8 __iomem *config; - u8 *xconfig; - unsigned int i = 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return -EIO; - xconfig = dgap_create_config_string(brd, string); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - /* Write string to board memory */ - config = addr + CONFIG; - for (; i < CONFIGSIZE; i++, config++, xconfig++) { - writeb(*xconfig, config); - if ((*xconfig & 0xff) == 0xff) - break; - } + if (set & TIOCM_RTS) { + ch->ch_mforce |= D_RTS(ch); + ch->ch_mval |= D_RTS(ch); } - writel(0xbfc01004, (addr + 0xc34)); - writel(0x3, (addr + 0xc30)); + if (set & TIOCM_DTR) { + ch->ch_mforce |= D_DTR(ch); + ch->ch_mval |= D_DTR(ch); + } + + if (clear & TIOCM_RTS) { + ch->ch_mforce |= D_RTS(ch); + ch->ch_mval &= ~(D_RTS(ch)); + } + + if (clear & TIOCM_DTR) { + ch->ch_mforce |= D_DTR(ch); + ch->ch_mval &= ~(D_DTR(ch)); + } + + dgap_param(ch, bd, un->un_type); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; } /* - * Waits for the FEP to report thats its ready for us to use. + * dgap_tty_send_break() + * + * Send a Break, called by ld. */ -static int dgap_test_fep(struct board_t *brd) +static int dgap_tty_send_break(struct tty_struct *tty, int msec) { - u8 __iomem *addr; - u16 word; - u16 err1; - u16 err2; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return -EINVAL; + if (!tty || tty->magic != TTY_MAGIC) + return -EIO; - addr = brd->re_map_membase; - word = readw(addr + FEPSTAT); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -EIO; - /* - * It can take 2-3 seconds for the FEP to - * be up and running. Give it 5 secs. - */ - brd->wait_for_fep = 0; - while (brd->wait_for_fep < 500) { - /* Check to see if FEP is up and running now. */ - if (word == *(u16 *) "OS") { - /* - * Check to see if the board can support FEP5+ commands. - */ - word = readw(addr + FEP5_PLUS); - if (word == *(u16 *) "5A") - brd->bd_flags |= BD_FEP5PLUS; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return -EIO; - return 0; - } - msleep_interruptible(10); - brd->wait_for_fep++; - word = readw(addr + FEPSTAT); + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return -EIO; + + switch (msec) { + case -1: + msec = 0xFFFF; + break; + case 0: + msec = 1; + break; + default: + msec /= 10; + break; } - /* Gave up on board after too long of time taken */ - err1 = readw(addr + SEQUENCE); - err2 = readw(addr + ERROR); - dev_warn(&brd->pdev->dev, - "FEPOS for %s not functioning. Error #(%x,%x).\n", - brd->name, err1, err2); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); +#if 0 + dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); +#endif + dgap_cmdw(ch, SBREAK, (u16) msec, 0); - return -EIO; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; } /* - * Physically forces the FEP5 card to reset itself. + * dgap_tty_wait_until_sent() + * + * wait until data has been transmitted, called by ld. */ -static void dgap_do_reset_board(struct board_t *brd) +static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout) { - u8 check; - u32 check1; - u32 check2; - unsigned int i; + dgap_wait_for_drain(tty); +} - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || - !brd->re_map_membase || !brd->re_map_port) +/* + * dgap_send_xchar() + * + * send a high priority character, called by ld. + */ +static void dgap_tty_send_xchar(struct tty_struct *tty, char c) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; + + if (!tty || tty->magic != TTY_MAGIC) return; - /* FEPRST does not vary among supported boards */ - writeb(FEPRST, brd->re_map_port); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - for (i = 0; i <= 1000; i++) { - check = readb(brd->re_map_port) & 0xe; - if (check == FEPRST) - break; - udelay(10); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - } - if (i > 1000) { - dev_warn(&brd->pdev->dev, - "dgap: Board not resetting... Failing board.\n"); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - } + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); /* - * Make sure there really is memory out there. + * This is technically what we should do. + * However, the NIST tests specifically want + * to see each XON or XOFF character that it + * sends, so lets just send each character + * by hand... */ - writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM)); - writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM)); - check1 = readl(brd->re_map_membase + LOWMEM); - check2 = readl(brd->re_map_membase + HIGHMEM); +#if 0 + if (c == STOP_CHAR(tty)) + dgap_cmdw(ch, RPAUSE, 0, 0); + else if (c == START_CHAR(tty)) + dgap_cmdw(ch, RRESUME, 0, 0); + else + dgap_wmove(ch, &c, 1); +#else + dgap_wmove(ch, &c, 1); +#endif - if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) { - dev_warn(&brd->pdev->dev, - "No memory at %p for board.\n", - brd->re_map_membase); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; - return; - } + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } -#ifdef DIGI_CONCENTRATORS_SUPPORTED /* - * Sends a concentrator image into the FEP5 board. + * Return modem signals to ld. */ -static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len) +static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value) { - char __iomem *vaddr; - u16 offset; - struct downld_t *to_dp; + int result; + u8 mstat; + ulong lock_flags; + int rc; - if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) - return; + spin_lock_irqsave(&ch->ch_lock, lock_flags); - vaddr = brd->re_map_membase; + mstat = readb(&(ch->ch_bs->m_stat)); + /* Append any outbound signals that might be pending... */ + mstat |= ch->ch_mostat; - offset = readw((u16 *) (vaddr + DOWNREQ)); - to_dp = (struct downld_t *) (vaddr + (int) offset); - memcpy_toio(to_dp, uaddr, len); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - /* Tell card we have data for it */ - writew(0, vaddr + (DOWNREQ)); + result = 0; - brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS; -} -#endif + if (mstat & D_DTR(ch)) + result |= TIOCM_DTR; + if (mstat & D_RTS(ch)) + result |= TIOCM_RTS; + if (mstat & D_CTS(ch)) + result |= TIOCM_CTS; + if (mstat & D_DSR(ch)) + result |= TIOCM_DSR; + if (mstat & D_RI(ch)) + result |= TIOCM_RI; + if (mstat & D_CD(ch)) + result |= TIOCM_CD; -#define EXPANSION_ROM_SIZE (64 * 1024) -#define FEP5_ROM_MAGIC (0xFEFFFFFF) + rc = put_user(result, value); -static void dgap_get_vpd(struct board_t *brd) -{ - u32 magic; - u32 base_offset; - u16 rom_offset; - u16 vpd_offset; - u16 image_length; - u16 i; - u8 byte1; - u8 byte2; + return rc; +} - /* - * Poke the magic number at the PCI Rom Address location. - * If VPD is supported, the value read from that address - * will be non-zero. - */ - magic = FEP5_ROM_MAGIC; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); - pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); +/* + * dgap_set_modem_info() + * + * Set modem signals, called by ld. + */ +static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, + struct un_t *un, unsigned int command, + unsigned int __user *value) +{ + int ret; + unsigned int arg; + ulong lock_flags; + ulong lock_flags2; - /* VPD not supported, bail */ - if (!magic) - return; + ret = get_user(arg, value); + if (ret) + return ret; - /* - * To get to the OTPROM memory, we have to send the boards base - * address or'ed with 1 into the PCI Rom Address location. - */ - magic = brd->membase | 0x01; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); - pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); + switch (command) { + case TIOCMBIS: + if (arg & TIOCM_RTS) { + ch->ch_mforce |= D_RTS(ch); + ch->ch_mval |= D_RTS(ch); + } - byte1 = readb(brd->re_map_membase); - byte2 = readb(brd->re_map_membase + 1); + if (arg & TIOCM_DTR) { + ch->ch_mforce |= D_DTR(ch); + ch->ch_mval |= D_DTR(ch); + } - /* - * If the board correctly swapped to the OTPROM memory, - * the first 2 bytes (header) should be 0x55, 0xAA - */ - if (byte1 == 0x55 && byte2 == 0xAA) { + break; - base_offset = 0; + case TIOCMBIC: + if (arg & TIOCM_RTS) { + ch->ch_mforce |= D_RTS(ch); + ch->ch_mval &= ~(D_RTS(ch)); + } - /* - * We have to run through all the OTPROM memory looking - * for the VPD offset. - */ - while (base_offset <= EXPANSION_ROM_SIZE) { + if (arg & TIOCM_DTR) { + ch->ch_mforce |= D_DTR(ch); + ch->ch_mval &= ~(D_DTR(ch)); + } - /* - * Lots of magic numbers here. - * - * The VPD offset is located inside the ROM Data - * Structure. - * - * We also have to remember the length of each - * ROM Data Structure, so we can "hop" to the next - * entry if the VPD isn't in the current - * ROM Data Structure. - */ - rom_offset = readw(brd->re_map_membase + - base_offset + 0x18); - image_length = readw(brd->re_map_membase + - rom_offset + 0x10) * 512; - vpd_offset = readw(brd->re_map_membase + - rom_offset + 0x08); + break; - /* Found the VPD entry */ - if (vpd_offset) - break; + case TIOCMSET: + ch->ch_mforce = D_DTR(ch)|D_RTS(ch); - /* We didn't find a VPD entry, go to next ROM entry. */ - base_offset += image_length; + if (arg & TIOCM_RTS) + ch->ch_mval |= D_RTS(ch); + else + ch->ch_mval &= ~(D_RTS(ch)); - byte1 = readb(brd->re_map_membase + base_offset); - byte2 = readb(brd->re_map_membase + base_offset + 1); + if (arg & TIOCM_DTR) + ch->ch_mval |= (D_DTR(ch)); + else + ch->ch_mval &= ~(D_DTR(ch)); - /* - * If the new ROM offset doesn't have 0x55, 0xAA - * as its header, we have run out of ROM. - */ - if (byte1 != 0x55 || byte2 != 0xAA) - break; - } + break; - /* - * If we have a VPD offset, then mark the board - * as having a valid VPD, and copy VPDSIZE (512) bytes of - * that VPD to the buffer we have in our board structure. - */ - if (vpd_offset) { - brd->bd_flags |= BD_HAS_VPD; - for (i = 0; i < VPDSIZE; i++) { - brd->vpd[i] = readb(brd->re_map_membase + - vpd_offset + i); - } - } + default: + return -EINVAL; } - /* - * We MUST poke the magic number at the PCI Rom Address location again. - * This makes the card report the regular board memory back to us, - * rather than the OTPROM memory. - */ - magic = FEP5_ROM_MAGIC; - pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + dgap_param(ch, bd, un->un_type); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; } /* - * Our board poller function. + * dgap_tty_digigeta() + * + * Ioctl to get the information for ditty. + * + * + * */ -static void dgap_poll_tasklet(unsigned long data) +static int dgap_tty_digigeta(struct channel_t *ch, + struct digi_t __user *retinfo) { - struct board_t *bd = (struct board_t *) data; + struct digi_t tmp; ulong lock_flags; - char __iomem *vaddr; - u16 head, tail; - if (!bd || (bd->magic != DGAP_BOARD_MAGIC)) - return; + if (!retinfo) + return -EFAULT; - if (bd->inhibit_poller) - return; + memset(&tmp, 0, sizeof(tmp)); - spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags); + memcpy(&tmp, &ch->ch_digi, sizeof(tmp)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - vaddr = bd->re_map_membase; + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; - /* - * If board is ready, parse deeper to see if there is anything to do. - */ - if (bd->state == BOARD_READY) { + return 0; +} - struct ev_t __iomem *eaddr; +/* + * dgap_tty_digiseta() + * + * Ioctl to set the information for ditty. + * + * + * + */ +static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd, + struct un_t *un, struct digi_t __user *new_info) +{ + struct digi_t new_digi; + ulong lock_flags = 0; + unsigned long lock_flags2; - if (!bd->re_map_membase) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } - if (!bd->re_map_port) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } + if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) + return -EFAULT; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - if (!bd->nasync) - goto out; + memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t)); - eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); + if (ch->ch_digi.digi_maxcps < 1) + ch->ch_digi.digi_maxcps = 1; - /* Get our head and tail */ - head = readw(&(eaddr->ev_head)); - tail = readw(&(eaddr->ev_tail)); + if (ch->ch_digi.digi_maxcps > 10000) + ch->ch_digi.digi_maxcps = 10000; - /* - * If there is an event pending. Go service it. - */ - if (head != tail) { - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - dgap_event(bd); - spin_lock_irqsave(&bd->bd_lock, lock_flags); - } + if (ch->ch_digi.digi_bufsize < 10) + ch->ch_digi.digi_bufsize = 10; -out: - /* - * If board is doing interrupts, ACK the interrupt. - */ - if (bd && bd->intr_running) - readb(bd->re_map_port + 2); + if (ch->ch_digi.digi_maxchar < 1) + ch->ch_digi.digi_maxchar = 1; - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return; - } + if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize) + ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize; + + if (ch->ch_digi.digi_onlen > DIGI_PLEN) + ch->ch_digi.digi_onlen = DIGI_PLEN; + + if (ch->ch_digi.digi_offlen > DIGI_PLEN) + ch->ch_digi.digi_offlen = DIGI_PLEN; + dgap_param(ch, bd, un->un_type); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; } -/*======================================================================= +/* + * dgap_tty_digigetedelay() * - * dgap_cmdb - Sends a 2 byte command to the FEP. + * Ioctl to get the current edelay setting. * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * byte1 - Integer containing first byte to be sent. - * byte2 - Integer containing second byte to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. * - *=======================================================================*/ -static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1, - u8 byte2, uint ncmds) + * + */ +static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo) { - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; + struct channel_t *ch; + struct un_t *un; + int tmp; + ulong lock_flags; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + if (!retinfo) + return -EFAULT; - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) - return; + if (!tty || tty->magic != TTY_MAGIC) + return -EFAULT; - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -EFAULT; - if (!vaddr) - return; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return -EFAULT; - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); + memset(&tmp, 0, sizeof(tmp)); - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; - return; - } + spin_lock_irqsave(&ch->ch_lock, lock_flags); + tmp = readw(&(ch->ch_bs->edelay)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - /* - * Put the data in the circular command buffer. - */ - writeb(cmd, (vaddr + head + CMDSTART + 0)); - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writeb(byte1, (vaddr + head + CMDSTART + 2)); - writeb(byte2, (vaddr + head + CMDSTART + 3)); + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; - head = (head + 4) & (CMDMAX - CMDSTART - 4); + return 0; +} - writew(head, &(cm_addr->cm_head)); +/* + * dgap_tty_digisetedelay() + * + * Ioctl to set the EDELAY setting + * + */ +static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd, + struct un_t *un, int __user *new_info) +{ + int new_digi; + ulong lock_flags; + ulong lock_flags2; - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { + if (copy_from_user(&new_digi, new_info, sizeof(int))) + return -EFAULT; - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - n = (head - tail) & (CMDMAX - CMDSTART - 4); + writew((u16) new_digi, &(ch->ch_bs->edelay)); - if (n <= ncmds * sizeof(struct cm_t)) - break; + dgap_param(ch, bd, un->un_type); - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; } -/*======================================================================= - * - * dgap_cmdw - Sends a 1 word command to the FEP. +/* + * dgap_tty_digigetcustombaud() * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * word - Integer containing word to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. + * Ioctl to get the current custom baud rate setting. + */ +static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un, + int __user *retinfo) +{ + int tmp; + ulong lock_flags; + + if (!retinfo) + return -EFAULT; + + memset(&tmp, 0, sizeof(tmp)); + + spin_lock_irqsave(&ch->ch_lock, lock_flags); + tmp = dgap_get_custom_baud(ch); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + + return 0; +} + +/* + * dgap_tty_digisetcustombaud() * - *=======================================================================*/ -static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds) + * Ioctl to set the custom baud rate setting + */ +static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd, + struct un_t *un, int __user *new_info) { - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; + uint new_rate; + ulong lock_flags; + ulong lock_flags2; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + if (copy_from_user(&new_rate, new_info, sizeof(unsigned int))) + return -EFAULT; - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) - return; + if (bd->bd_flags & BD_FEP5PLUS) { - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; - if (!vaddr) - return; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); + ch->ch_custom_speed = new_rate; - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; - return; + dgap_param(ch, bd, un->un_type); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } - /* - * Put the data in the circular command buffer. - */ - writeb(cmd, (vaddr + head + CMDSTART + 0)); - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writew((u16) word, (vaddr + head + CMDSTART + 2)); + return 0; +} + +/* + * dgap_set_termios() + */ +static void dgap_tty_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + unsigned long lock_flags; + unsigned long lock_flags2; + + if (!tty || tty->magic != TTY_MAGIC) + return; - head = (head + 4) & (CMDMAX - CMDSTART - 4); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - writew(head, &(cm_addr->cm_head)); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - n = (head - tail) & (CMDMAX - CMDSTART - 4); + ch->ch_c_cflag = tty->termios.c_cflag; + ch->ch_c_iflag = tty->termios.c_iflag; + ch->ch_c_oflag = tty->termios.c_oflag; + ch->ch_c_lflag = tty->termios.c_lflag; + ch->ch_startc = tty->termios.c_cc[VSTART]; + ch->ch_stopc = tty->termios.c_cc[VSTOP]; - if (n <= ncmds * sizeof(struct cm_t)) - break; + dgap_carrier(ch); + dgap_param(ch, bd, un->un_type); - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } -/*======================================================================= - * - * dgap_cmdw_ext - Sends a extended word command to the FEP. - * - * ch - Pointer to channel structure. - * cmd - Command to be sent. - * word - Integer containing word to be sent. - * ncmds - Wait until ncmds or fewer cmds are left - * in the cmd buffer before returning. - * - *=======================================================================*/ -static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) +static void dgap_tty_throttle(struct tty_struct *tty) { - char __iomem *vaddr; - struct __iomem cm_t *cm_addr; - uint count; - uint n; - u16 head; - u16 tail; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + if (!tty || tty->magic != TTY_MAGIC) return; - /* - * Check if board is still alive. - */ - if (ch->ch_bd->state == BOARD_FAILED) + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) return; - /* - * Make sure the pointers are in range before - * writing to the FEP memory. - */ - vaddr = ch->ch_bd->re_map_membase; - if (!vaddr) + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; - cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF); - head = readw(&(cm_addr->cm_head)); - - /* - * Forget it if pointers out of range. - */ - if (head >= (CMDMAX - CMDSTART) || (head & 03)) { - ch->ch_bd->state = BOARD_FAILED; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) return; - } - /* - * Put the data in the circular command buffer. - */ + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - /* Write an FF to tell the FEP that we want an extended command */ - writeb((u8) 0xff, (vaddr + head + CMDSTART + 0)); + ch->ch_flags |= (CH_RXBLOCK); +#if 1 + dgap_cmdw(ch, RPAUSE, 0, 0); +#endif - writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1)); - writew((u16) cmd, (vaddr + head + CMDSTART + 2)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - /* - * If the second part of the command won't fit, - * put it at the beginning of the circular buffer. - */ - if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03))) - writew((u16) word, (vaddr + CMDSTART)); - else - writew((u16) word, (vaddr + head + CMDSTART + 4)); +} - head = (head + 8) & (CMDMAX - CMDSTART - 4); +static void dgap_tty_unthrottle(struct tty_struct *tty) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - writew(head, &(cm_addr->cm_head)); + if (!tty || tty->magic != TTY_MAGIC) + return; - /* - * Wait if necessary before updating the head - * pointer to limit the number of outstanding - * commands to the FEP. If the time spent waiting - * is outlandish, declare the FEP dead. - */ - for (count = dgap_count ;;) { + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - head = readw(&(cm_addr->cm_head)); - tail = readw(&(cm_addr->cm_tail)); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - n = (head - tail) & (CMDMAX - CMDSTART - 4); + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; - if (n <= ncmds * sizeof(struct cm_t)) - break; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - if (--count == 0) { - ch->ch_bd->state = BOARD_FAILED; - return; - } - udelay(10); - } + ch->ch_flags &= ~(CH_RXBLOCK); + +#if 1 + dgap_cmdw(ch, RRESUME, 0, 0); +#endif + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } -/*======================================================================= +/************************************************************************ * - * dgap_wmove - Write data to FEP buffer. + * TTY Entry points and helper functions * - * ch - Pointer to channel structure. - * buf - Poiter to characters to be moved. - * cnt - Number of characters to move. + ************************************************************************/ + +/* + * dgap_tty_open() * - *=======================================================================*/ -static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt) + */ +static int dgap_tty_open(struct tty_struct *tty, struct file *file) { - int n; - char __iomem *taddr; + struct board_t *brd; + struct channel_t *ch; + struct un_t *un; struct bs_t __iomem *bs; + uint major; + uint minor; + int rc; + ulong lock_flags; + ulong lock_flags2; u16 head; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + major = MAJOR(tty_devnum(tty)); + minor = MINOR(tty_devnum(tty)); + + if (major > 255) + return -EIO; + + /* Get board pointer from our array of majors we have allocated */ + brd = dgap_boards_by_major[major]; + if (!brd) + return -EIO; /* - * Check parameters. + * If board is not yet up to a state of READY, go to + * sleep waiting for it to happen or they cancel the open. */ - bs = ch->ch_bs; - head = readw(&(bs->tx_head)); + rc = wait_event_interruptible(brd->state_wait, + (brd->state & BOARD_READY)); + + if (rc) + return rc; + + spin_lock_irqsave(&brd->bd_lock, lock_flags); + + /* The wait above should guarantee this cannot happen */ + if (brd->state != BOARD_READY) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* If opened device is greater than our number of ports, bail. */ + if (MINOR(tty_devnum(tty)) > brd->nasync) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + ch = brd->channels[minor]; + if (!ch) { + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* Grab channel lock */ + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + /* Figure out our type */ + if (major == brd->dgap_serial_major) { + un = &brd->channels[minor]->ch_tun; + un->un_type = DGAP_SERIAL; + } else if (major == brd->dgap_transparent_print_major) { + un = &brd->channels[minor]->ch_pun; + un->un_type = DGAP_PRINT; + } else { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } + + /* Store our unit into driver_data, so we always have it available. */ + tty->driver_data = un; /* - * If pointers are out of range, just return. + * Error if channel info pointer is NULL. */ - if ((cnt > ch->ch_tsize) || - (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) - return; + bs = ch->ch_bs; + if (!bs) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); + return -EIO; + } /* - * If the write wraps over the top of the circular buffer, - * move the portion up to the wrap point, and reset the - * pointers to the bottom. + * Initialize tty's */ - n = ch->ch_tstart + ch->ch_tsize - head; + if (!(un->un_flags & UN_ISOPEN)) { + /* Store important variables. */ + un->un_tty = tty; - if (cnt >= n) { - cnt -= n; - taddr = ch->ch_taddr + head; - memcpy_toio(taddr, buf, n); - head = ch->ch_tstart; - buf += n; + /* Maybe do something here to the TTY struct as well? */ } /* - * Move rest of data. + * Initialize if neither terminal or printer is open. */ - taddr = ch->ch_taddr + head; - n = cnt; - memcpy_toio(taddr, buf, n); - head += cnt; - - writew(head, &(bs->tx_head)); -} + if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) { -/* - * Retrives the current custom baud rate from FEP memory, - * and returns it back to the user. - * Returns 0 on error. - */ -static uint dgap_get_custom_baud(struct channel_t *ch) -{ - u8 __iomem *vaddr; - ulong offset; - uint value; + ch->ch_mforce = 0; + ch->ch_mval = 0; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; + /* + * Flush input queue. + */ + head = readw(&(bs->rx_head)); + writew(head, &(bs->rx_tail)); - if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) - return 0; + ch->ch_flags = 0; + ch->pscan_state = 0; + ch->pscan_savechar = 0; - if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS)) - return 0; + ch->ch_c_cflag = tty->termios.c_cflag; + ch->ch_c_iflag = tty->termios.c_iflag; + ch->ch_c_oflag = tty->termios.c_oflag; + ch->ch_c_lflag = tty->termios.c_lflag; + ch->ch_startc = tty->termios.c_cc[VSTART]; + ch->ch_stopc = tty->termios.c_cc[VSTOP]; - vaddr = ch->ch_bd->re_map_membase; + /* TODO: flush our TTY struct here? */ + } - if (!vaddr) - return 0; + dgap_carrier(ch); + /* + * Run param in case we changed anything + */ + dgap_param(ch, brd, un->un_type); /* - * Go get from fep mem, what the fep - * believes the custom baud rate is. + * follow protocol for opening port */ - offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28) - + LINE_SPEED; - value = readw(vaddr + offset); - return value; -} + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&brd->bd_lock, lock_flags); -/* - * Calls the firmware to reset this channel. - */ -static void dgap_firmware_reset_port(struct channel_t *ch) -{ - dgap_cmdb(ch, CHRESET, 0, 0, 0); + rc = dgap_block_til_ready(tty, file, ch); - /* - * Now that the channel is reset, we need to make sure - * all the current settings get reapplied to the port - * in the firmware. - * - * So we will set the driver's cache of firmware - * settings all to 0, and then call param. - */ - ch->ch_fepiflag = 0; - ch->ch_fepcflag = 0; - ch->ch_fepoflag = 0; - ch->ch_fepstartc = 0; - ch->ch_fepstopc = 0; - ch->ch_fepastartc = 0; - ch->ch_fepastopc = 0; - ch->ch_mostat = 0; - ch->ch_hflow = 0; + if (!un->un_tty) + return -ENODEV; + + /* No going back now, increment our unit and channel counters */ + spin_lock_irqsave(&ch->ch_lock, lock_flags); + ch->ch_open_count++; + un->un_open_count++; + un->un_flags |= (UN_ISOPEN); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + + return rc; } -/*======================================================================= - * - * dgap_param - Set Digi parameters. - * - * struct tty_struct * - TTY for port. +/* + * dgap_tty_close() * - *=======================================================================*/ -static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type) + */ +static void dgap_tty_close(struct tty_struct *tty, struct file *file) { - u16 head; - u16 cflag; - u16 iflag; - u8 mval; - u8 hflow; - - /* - * If baud rate is zero, flush queues, and set mval to drop DTR. - */ - if ((ch->ch_c_cflag & (CBAUD)) == 0) { + struct ktermios *ts; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; - /* flush rx */ - head = readw(&(ch->ch_bs->rx_head)); - writew(head, &(ch->ch_bs->rx_tail)); + if (!tty || tty->magic != TTY_MAGIC) + return; - /* flush tx */ - head = readw(&(ch->ch_bs->tx_head)); - writew(head, &(ch->ch_bs->tx_tail)); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - ch->ch_flags |= (CH_BAUD0); + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - /* Drop RTS and DTR */ - ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch)); - mval = D_DTR(ch) | D_RTS(ch); - ch->ch_baud_info = 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; - } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) { - /* - * Tell the fep to do the command - */ + ts = &tty->termios; - dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0); + spin_lock_irqsave(&ch->ch_lock, lock_flags); + /* + * Determine if this is the last close or not - and if we agree about + * which type of close it is with the Line Discipline + */ + if ((tty->count == 1) && (un->un_open_count != 1)) { /* - * Now go get from fep mem, what the fep - * believes the custom baud rate is. + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. un_open_count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. */ - ch->ch_custom_speed = dgap_get_custom_baud(ch); - ch->ch_baud_info = ch->ch_custom_speed; + un->un_open_count = 1; + } - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); - } - mval = D_DTR(ch) | D_RTS(ch); + if (--un->un_open_count < 0) + un->un_open_count = 0; - } else { - /* - * Set baud rate, character size, and parity. - */ + ch->ch_open_count--; + if (ch->ch_open_count && un->un_open_count) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); + return; + } - int iindex = 0; - int jindex = 0; - int baud = 0; + /* OK, its the last close on the unit */ - ulong bauds[4][16] = { - { /* slowbaud */ - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* slowbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* fastbaud */ - 0, 57600, 76800, 115200, - 14400, 57600, 230400, 76800, - 115200, 230400, 28800, 460800, - 921600, 9600, 19200, 38400 }, - { /* fastbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 } - }; + un->un_flags |= UN_CLOSING; - /* - * Only use the TXPrint baud rate if the - * terminal unit is NOT open - */ - if (!(ch->ch_tun.un_flags & UN_ISOPEN) && - un_type == DGAP_PRINT) - baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; - else - baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; + tty->closing = 1; + + /* + * Only officially close channel if count is 0 and + * DIGI_PRINTER bit is not set. + */ + if ((ch->ch_open_count == 0) && + !(ch->ch_digi.digi_flags & DIGI_PRINTER)) { - if (ch->ch_c_cflag & CBAUDEX) - iindex = 1; + ch->ch_flags &= ~(CH_RXBLOCK); - if (ch->ch_digi.digi_flags & DIGI_FAST) - iindex += 2; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - jindex = baud; + /* wait for output to drain */ + /* This will also return if we take an interrupt */ - if ((iindex >= 0) && (iindex < 4) && - (jindex >= 0) && (jindex < 16)) - baud = bauds[iindex][jindex]; - else - baud = 0; + dgap_wait_for_drain(tty); - if (baud == 0) - baud = 9600; + dgap_tty_flush_buffer(tty); + tty_ldisc_flush(tty); - ch->ch_baud_info = baud; + spin_lock_irqsave(&ch->ch_lock, lock_flags); - /* - * CBAUD has bit position 0x1000 set these days to - * indicate Linux baud rate remap. - * We use a different bit assignment for high speed. - * Clear this bit out while grabbing the parts of - * "cflag" we want. - */ - cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | - CSTOPB | CSIZE); + tty->closing = 0; /* - * HUPCL bit is used by FEP to indicate fast baud - * table is to be used. + * If we have HUPCL set, lower DTR and RTS */ - if ((ch->ch_digi.digi_flags & DIGI_FAST) || - (ch->ch_c_cflag & CBAUDEX)) - cflag |= HUPCL; + if (ch->ch_c_cflag & HUPCL) { + ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch)); + dgap_cmdb(ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0); - if ((ch->ch_c_cflag & CBAUDEX) && - !(ch->ch_digi.digi_flags & DIGI_FAST)) { /* - * The below code is trying to guarantee that only - * baud rates 115200, 230400, 460800, 921600 are - * remapped. We use exclusive or because the various - * baud rates share common bit positions and therefore - * can't be tested for easily. + * Go to sleep to ensure RTS/DTR + * have been dropped for modems to see it. */ - tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX; - int baudpart = 0; + spin_unlock_irqrestore(&ch->ch_lock, + lock_flags); - /* - * Map high speed requests to index - * into FEP's baud table - */ - switch (tcflag) { - case B57600: - baudpart = 1; - break; -#ifdef B76800 - case B76800: - baudpart = 2; - break; -#endif - case B115200: - baudpart = 3; - break; - case B230400: - baudpart = 9; - break; - case B460800: - baudpart = 11; - break; -#ifdef B921600 - case B921600: - baudpart = 12; - break; -#endif - default: - baudpart = 0; - } + /* .25 second delay for dropping RTS/DTR */ + schedule_timeout_interruptible(msecs_to_jiffies(250)); - if (baudpart) - cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart; + spin_lock_irqsave(&ch->ch_lock, lock_flags); } - cflag &= 0xffff; - - if (cflag != ch->ch_fepcflag) { - ch->ch_fepcflag = (u16) (cflag & 0xffff); - - /* - * Okay to have channel and board - * locks held calling this - */ - dgap_cmdw(ch, SCFLAG, (u16) cflag, 0); - } + ch->pscan_state = 0; + ch->pscan_savechar = 0; + ch->ch_baud_info = 0; - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); - } - mval = D_DTR(ch) | D_RTS(ch); } /* - * Get input flags. + * turn off print device when closing print device. */ - iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | - INPCK | ISTRIP | IXON | IXANY | IXOFF); - - if ((ch->ch_startc == _POSIX_VDISABLE) || - (ch->ch_stopc == _POSIX_VDISABLE)) { - iflag &= ~(IXON | IXOFF); - ch->ch_c_iflag &= ~(IXON | IXOFF); + if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) { + dgap_wmove(ch, ch->ch_digi.digi_offstr, + (int) ch->ch_digi.digi_offlen); + ch->ch_flags &= ~CH_PRON; } - /* - * Only the IBM Xr card can switch between - * 232 and 422 modes on the fly - */ - if (bd->device == PCI_DEV_XR_IBM_DID) { - if (ch->ch_digi.digi_flags & DIGI_422) - dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0); - else - dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0); - } + un->un_tty = NULL; + un->un_flags &= ~(UN_ISOPEN | UN_CLOSING); + tty->driver_data = NULL; - if (ch->ch_digi.digi_flags & DIGI_ALTPIN) - iflag |= IALTPIN; + wake_up_interruptible(&ch->ch_flags_wait); + wake_up_interruptible(&un->un_flags_wait); - if (iflag != ch->ch_fepiflag) { - ch->ch_fepiflag = iflag; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); +} - /* Okay to have channel and board locks held calling this */ - dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0); - } +static void dgap_tty_start(struct tty_struct *tty) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - /* - * Select hardware handshaking. - */ - hflow = 0; + if (!tty || tty->magic != TTY_MAGIC) + return; - if (ch->ch_c_cflag & CRTSCTS) - hflow |= (D_RTS(ch) | D_CTS(ch)); - if (ch->ch_digi.digi_flags & RTSPACE) - hflow |= D_RTS(ch); - if (ch->ch_digi.digi_flags & DTRPACE) - hflow |= D_DTR(ch); - if (ch->ch_digi.digi_flags & CTSPACE) - hflow |= D_CTS(ch); - if (ch->ch_digi.digi_flags & DSRPACE) - hflow |= D_DSR(ch); - if (ch->ch_digi.digi_flags & DCDPACE) - hflow |= D_CD(ch); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - if (hflow != ch->ch_hflow) { - ch->ch_hflow = hflow; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0); - } + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; - /* - * Set RTS and/or DTR Toggle if needed, - * but only if product is FEP5+ based. - */ - if (bd->bd_flags & BD_FEP5PLUS) { - u16 hflow2 = 0; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) - hflow2 |= (D_RTS(ch)); - if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) - hflow2 |= (D_DTR(ch)); + dgap_cmdw(ch, RESUMETX, 0, 0); - dgap_cmdw_ext(ch, 0xff03, hflow2, 0); - } + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); +} - /* - * Set modem control lines. - */ +static void dgap_tty_stop(struct tty_struct *tty) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - mval ^= ch->ch_mforce & (mval ^ ch->ch_mval); + if (!tty || tty->magic != TTY_MAGIC) + return; - if (ch->ch_mostat ^ mval) { - ch->ch_mostat = mval; + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; + + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; + + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + dgap_cmdw(ch, PAUSETX, 0, 0); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); +} + +/* + * dgap_tty_flush_chars() + * + * Flush the cook buffer + * + * Note to self, and any other poor souls who venture here: + * + * flush in this case DOES NOT mean dispose of the data. + * instead, it means "stop buffering and send it if you + * haven't already." Just guess how I figured that out... SRW 2-Jun-98 + * + * It is also always called in interrupt context - JAR 8-Sept-99 + */ +static void dgap_tty_flush_chars(struct tty_struct *tty) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + ulong lock_flags; + ulong lock_flags2; - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0); - } + if (!tty || tty->magic != TTY_MAGIC) + return; - /* - * Read modem signals, and then call carrier function. - */ - ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); - dgap_carrier(ch); + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return; - /* - * Set the start and stop characters. - */ - if (ch->ch_startc != ch->ch_fepstartc || - ch->ch_stopc != ch->ch_fepstopc) { - ch->ch_fepstartc = ch->ch_startc; - ch->ch_fepstopc = ch->ch_stopc; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return; - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0); - } + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return; - /* - * Set the Auxiliary start and stop characters. - */ - if (ch->ch_astartc != ch->ch_fepastartc || - ch->ch_astopc != ch->ch_fepastopc) { - ch->ch_fepastartc = ch->ch_astartc; - ch->ch_fepastopc = ch->ch_astopc; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - /* Okay to have channel and board locks held calling this */ - dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0); - } + /* TODO: Do something here */ - return 0; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } +/***************************************************************************** + * + * The IOCTL function and all of its helpers + * + *****************************************************************************/ + /* - * dgap_parity_scan() + * dgap_tty_ioctl() * - * Convert the FEP5 way of reporting parity errors and breaks into - * the Linux line discipline way. + * The usual assortment of ioctl's */ -static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, - unsigned char *fbuf, int *len) +static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, + unsigned long arg) { - int l = *len; - int count = 0; - unsigned char *in, *cout, *fout; - unsigned char c; + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + int rc; + u16 head; + ulong lock_flags = 0; + ulong lock_flags2 = 0; + void __user *uarg = (void __user *) arg; - in = cbuf; - cout = cbuf; - fout = fbuf; + if (!tty || tty->magic != TTY_MAGIC) + return -ENODEV; + + un = tty->driver_data; + if (!un || un->magic != DGAP_UNIT_MAGIC) + return -ENODEV; + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return; + return -ENODEV; - while (l--) { - c = *in++; - switch (ch->pscan_state) { - default: - /* reset to sanity and fall through */ - ch->pscan_state = 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return -ENODEV; - case 0: - /* No FF seen yet */ - if (c == (unsigned char) '\377') - /* delete this character from stream */ - ch->pscan_state = 1; - else { - *cout++ = c; - *fout++ = TTY_NORMAL; - count += 1; - } - break; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - case 1: - /* first FF seen */ - if (c == (unsigned char) '\377') { - /* doubled ff, transform to single ff */ - *cout++ = c; - *fout++ = TTY_NORMAL; - count += 1; - ch->pscan_state = 0; - } else { - /* save value examination in next state */ - ch->pscan_savechar = c; - ch->pscan_state = 2; - } - break; + if (un->un_open_count <= 0) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return -EIO; + } - case 2: - /* third character of ff sequence */ + switch (cmd) { - *cout++ = c; + /* Here are all the standard ioctl's that we MUST implement */ - if (ch->pscan_savechar == 0x0) { + case TCSBRK: + /* + * TCSBRK is SVID version: non-zero arg --> no break + * this behaviour is exploited by tcdrain(). + * + * According to POSIX.1 spec (7.2.2.1.2) breaks should be + * between 0.25 and 0.5 seconds so we'll ask for something + * in the middle: 0.375 seconds. + */ + rc = tty_check_change(tty); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (rc) + return rc; - if (c == 0x0) { - ch->ch_err_break++; - *fout++ = TTY_BREAK; - } else { - ch->ch_err_parity++; - *fout++ = TTY_PARITY; - } - } + rc = dgap_wait_for_drain(tty); - count += 1; - ch->pscan_state = 0; - } - } - *len = count; -} + if (rc) + return -EINTR; -static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch, - struct un_t *un, u32 mask, - unsigned long *irq_flags1, - unsigned long *irq_flags2) -{ - if (!(un->un_flags & mask)) - return; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - un->un_flags &= ~mask; + if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) + dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); - if (!(un->un_flags & UN_ISOPEN)) - return; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - un->un_tty->ldisc->ops->write_wakeup) { - spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2); - spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1); + return 0; - (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty); + case TCSBRKP: + /* support for POSIX tcsendbreak() - spin_lock_irqsave(&bd->bd_lock, *irq_flags1); - spin_lock_irqsave(&ch->ch_lock, *irq_flags2); - } - wake_up_interruptible(&un->un_tty->write_wait); - wake_up_interruptible(&un->un_flags_wait); -} + * According to POSIX.1 spec (7.2.2.1.2) breaks should be + * between 0.25 and 0.5 seconds so we'll ask for something + * in the middle: 0.375 seconds. + */ + rc = tty_check_change(tty); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (rc) + return rc; -/*======================================================================= - * - * dgap_event - FEP to host event processing routine. - * - * bd - Board of current event. - * - *=======================================================================*/ -static int dgap_event(struct board_t *bd) -{ - struct channel_t *ch; - ulong lock_flags; - ulong lock_flags2; - struct bs_t __iomem *bs; - u8 __iomem *event; - u8 __iomem *vaddr; - struct ev_t __iomem *eaddr; - uint head; - uint tail; - int port; - int reason; - int modem; - int b1; + rc = dgap_wait_for_drain(tty); + if (rc) + return -EINTR; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + + dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; + + case TIOCSBRK: + /* + * FEP5 doesn't support turning on a break unconditionally. + * The FEP5 device will stop sending a break automatically + * after the specified time value that was sent when turning on + * the break. + */ + rc = tty_check_change(tty); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + if (rc) + return rc; + + rc = dgap_wait_for_drain(tty); + if (rc) + return -EINTR; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return -EIO; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); - spin_lock_irqsave(&bd->bd_lock, lock_flags); + dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0); - vaddr = bd->re_map_membase; + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (!vaddr) { + return 0; + + case TIOCCBRK: + /* + * FEP5 doesn't support turning off a break unconditionally. + * The FEP5 device will stop sending a break automatically + * after the specified time value that was sent when turning on + * the break. + */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EIO; - } + return 0; - eaddr = (struct ev_t __iomem *) (vaddr + EVBUF); + case TIOCGSOFTCAR: - /* Get our head and tail */ - head = readw(&(eaddr->ev_head)); - tail = readw(&(eaddr->ev_tail)); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - /* - * Forget it if pointers out of range. - */ + rc = put_user(C_CLOCAL(tty) ? 1 : 0, + (unsigned long __user *) arg); + return rc; - if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART || - (head | tail) & 03) { - /* Let go of board lock */ + case TIOCSSOFTCAR: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - return -EIO; - } - /* - * Loop to process all the events in the buffer. - */ - while (tail != head) { + rc = get_user(arg, (unsigned long __user *) arg); + if (rc) + return rc; + + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | + (arg ? CLOCAL : 0)); + dgap_param(ch, bd, un->un_type); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return 0; + + case TIOCMGET: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_get_modem_info(ch, uarg); + + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_set_modem_info(ch, bd, un, cmd, uarg); /* - * Get interrupt information. + * Here are any additional ioctl's that we want to implement */ - event = bd->re_map_membase + tail + EVSTART; + case TCFLSH: + /* + * The linux tty driver doesn't have a flush + * input routine for the driver, assuming all backed + * up data is in the line disc. buffers. However, + * we all know that's not the case. Here, we + * act on the ioctl, but then lie and say we didn't + * so the line discipline will process the flush + * also. + */ + rc = tty_check_change(tty); + if (rc) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return rc; + } - port = ioread8(event); - reason = ioread8(event + 1); - modem = ioread8(event + 2); - b1 = ioread8(event + 3); + if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) { + if (!(un->un_type == DGAP_PRINT)) { + head = readw(&(ch->ch_bs->rx_head)); + writew(head, &(ch->ch_bs->rx_tail)); + writeb(0, &(ch->ch_bs->orun)); + } + } + + if ((arg != TCOFLUSH) && (arg != TCIOFLUSH)) { + /* pretend we didn't recognize this IOCTL */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + + return -ENOIOCTLCMD; + } + + ch->ch_flags &= ~CH_STOP; + head = readw(&(ch->ch_bs->tx_head)); + dgap_cmdw(ch, FLUSHTX, (u16) head, 0); + dgap_cmdw(ch, RESUMETX, 0, 0); + if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) { + ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY); + wake_up_interruptible(&ch->ch_tun.un_flags_wait); + } + if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) { + ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY); + wake_up_interruptible(&ch->ch_pun.un_flags_wait); + } + if (waitqueue_active(&tty->write_wait)) + wake_up_interruptible(&tty->write_wait); + /* Can't hold any locks when calling tty_wakeup! */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + tty_wakeup(tty); + + /* pretend we didn't recognize this IOCTL */ + return -ENOIOCTLCMD; + + case TCSETSF: + case TCSETSW: /* - * Make sure the interrupt is valid. + * The linux tty driver doesn't have a flush + * input routine for the driver, assuming all backed + * up data is in the line disc. buffers. However, + * we all know that's not the case. Here, we + * act on the ioctl, but then lie and say we didn't + * so the line discipline will process the flush + * also. */ - if (port >= bd->nasync) - goto next; + if (cmd == TCSETSF) { + /* flush rx */ + ch->ch_flags &= ~CH_STOP; + head = readw(&(ch->ch_bs->rx_head)); + writew(head, &(ch->ch_bs->rx_tail)); + } - if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) - goto next; + /* now wait for all the output to drain */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + rc = dgap_wait_for_drain(tty); + if (rc) + return -EINTR; - ch = bd->channels[port]; + /* pretend we didn't recognize this */ + return -ENOIOCTLCMD; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - goto next; + case TCSETAW: + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + rc = dgap_wait_for_drain(tty); + if (rc) + return -EINTR; + + /* pretend we didn't recognize this */ + return -ENOIOCTLCMD; + case TCXONC: /* - * If we have made it here, the event was valid. - * Lock down the channel. + * The Linux Line Discipline (LD) would do this for us if we + * let it, but we have the special firmware options to do this + * the "right way" regardless of hardware or software flow + * control so we'll do it outselves instead of letting the LD + * do it. */ - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + rc = tty_check_change(tty); + if (rc) { + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return rc; + } - bs = ch->ch_bs; + switch (arg) { - if (!bs) { + case TCOON: spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - goto next; + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_tty_start(tty); + return 0; + case TCOOFF: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + dgap_tty_stop(tty); + return 0; + case TCION: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* Make the ld do it */ + return -ENOIOCTLCMD; + case TCIOFF: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + /* Make the ld do it */ + return -ENOIOCTLCMD; + default: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return -EINVAL; } - /* - * Process received data. - */ - if (reason & IFDATA) { + case DIGI_GETA: + /* get information for ditty */ + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digigeta(ch, uarg); + + case DIGI_SETAW: + case DIGI_SETAF: + + /* set information for ditty */ + if (cmd == (DIGI_SETAW)) { + + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + rc = dgap_wait_for_drain(tty); + if (rc) + return -EINTR; + spin_lock_irqsave(&bd->bd_lock, lock_flags); + spin_lock_irqsave(&ch->ch_lock, lock_flags2); + } else + tty_ldisc_flush(tty); + /* fall thru */ + + case DIGI_SETA: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digiseta(ch, bd, un, uarg); + + case DIGI_GEDELAY: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digigetedelay(tty, uarg); + + case DIGI_SEDELAY: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digisetedelay(ch, bd, un, uarg); - /* - * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT! - * input could send some data to ld, which in turn - * could do a callback to one of our other functions. - */ - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + case DIGI_GETCUSTOMBAUD: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digigetcustombaud(ch, un, uarg); - dgap_input(ch); + case DIGI_SETCUSTOMBAUD: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return dgap_tty_digisetcustombaud(ch, bd, un, uarg); - spin_lock_irqsave(&bd->bd_lock, lock_flags); - spin_lock_irqsave(&ch->ch_lock, lock_flags2); + case DIGI_RESET_PORT: + dgap_firmware_reset_port(ch); + dgap_param(ch, bd, un->un_type); + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + return 0; - if (ch->ch_flags & CH_RACTIVE) - ch->ch_flags |= CH_RENABLE; - else - writeb(1, &(bs->idata)); + default: + spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + spin_unlock_irqrestore(&bd->bd_lock, lock_flags); - if (ch->ch_flags & CH_RWAIT) { - ch->ch_flags &= ~CH_RWAIT; + return -ENOIOCTLCMD; + } +} - wake_up_interruptible - (&ch->ch_tun.un_flags_wait); - } - } +static const struct tty_operations dgap_tty_ops = { + .open = dgap_tty_open, + .close = dgap_tty_close, + .write = dgap_tty_write, + .write_room = dgap_tty_write_room, + .flush_buffer = dgap_tty_flush_buffer, + .chars_in_buffer = dgap_tty_chars_in_buffer, + .flush_chars = dgap_tty_flush_chars, + .ioctl = dgap_tty_ioctl, + .set_termios = dgap_tty_set_termios, + .stop = dgap_tty_stop, + .start = dgap_tty_start, + .throttle = dgap_tty_throttle, + .unthrottle = dgap_tty_unthrottle, + .hangup = dgap_tty_hangup, + .put_char = dgap_tty_put_char, + .tiocmget = dgap_tty_tiocmget, + .tiocmset = dgap_tty_tiocmset, + .break_ctl = dgap_tty_send_break, + .wait_until_sent = dgap_tty_wait_until_sent, + .send_xchar = dgap_tty_send_xchar +}; - /* - * Process Modem change signals. - */ - if (reason & IFMODEM) { - ch->ch_mistat = modem; - dgap_carrier(ch); - } +/************************************************************************ + * + * TTY Initialization/Cleanup Functions + * + ************************************************************************/ - /* - * Process break. - */ - if (reason & IFBREAK) { +/* + * dgap_tty_register() + * + * Init the tty subsystem for this board. + */ +static int dgap_tty_register(struct board_t *brd) +{ + int rc; - if (ch->ch_tun.un_tty) { - /* A break has been indicated */ - ch->ch_err_break++; - tty_buffer_request_room - (ch->ch_tun.un_tty->port, 1); - tty_insert_flip_char(ch->ch_tun.un_tty->port, - 0, TTY_BREAK); - tty_flip_buffer_push(ch->ch_tun.un_tty->port); - } - } + brd->serial_driver = tty_alloc_driver(MAXPORTS, 0); + if (IS_ERR(brd->serial_driver)) + return PTR_ERR(brd->serial_driver); - /* - * Process Transmit low. - */ - if (reason & IFTLW) { - dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW, - &lock_flags, &lock_flags2); - dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW, - &lock_flags, &lock_flags2); - if (ch->ch_flags & CH_WLOW) { - ch->ch_flags &= ~CH_WLOW; - wake_up_interruptible(&ch->ch_flags_wait); - } - } + snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_", + brd->boardnum); + brd->serial_driver->name = brd->serial_name; + brd->serial_driver->name_base = 0; + brd->serial_driver->major = 0; + brd->serial_driver->minor_start = 0; + brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; + brd->serial_driver->init_termios = dgap_default_termios; + brd->serial_driver->driver_name = DRVSTR; + brd->serial_driver->flags = (TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); - /* - * Process Transmit empty. - */ - if (reason & IFTEM) { - dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY, - &lock_flags, &lock_flags2); - dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY, - &lock_flags, &lock_flags2); - if (ch->ch_flags & CH_WEMPTY) { - ch->ch_flags &= ~CH_WEMPTY; - wake_up_interruptible(&ch->ch_flags_wait); - } - } + /* The kernel wants space to store pointers to tty_structs */ + brd->serial_driver->ttys = + kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); + if (!brd->serial_driver->ttys) { + rc = -ENOMEM; + goto free_serial_drv; + } - spin_unlock_irqrestore(&ch->ch_lock, lock_flags2); + /* + * Entry points for driver. Called by the kernel from + * tty_io.c and n_tty.c. + */ + tty_set_operations(brd->serial_driver, &dgap_tty_ops); -next: - tail = (tail + 4) & (EVMAX - EVSTART - 4); + /* + * If we're doing transparent print, we have to do all of the above + * again, separately so we don't get the LD confused about what major + * we are when we get into the dgap_tty_open() routine. + */ + brd->print_driver = tty_alloc_driver(MAXPORTS, 0); + if (IS_ERR(brd->print_driver)) { + rc = PTR_ERR(brd->print_driver); + goto free_serial_drv; } - writew(tail, &(eaddr->ev_tail)); - spin_unlock_irqrestore(&bd->bd_lock, lock_flags); + snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_", + brd->boardnum); + brd->print_driver->name = brd->print_name; + brd->print_driver->name_base = 0; + brd->print_driver->major = 0; + brd->print_driver->minor_start = 0; + brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL; + brd->print_driver->subtype = SERIAL_TYPE_NORMAL; + brd->print_driver->init_termios = dgap_default_termios; + brd->print_driver->driver_name = DRVSTR; + brd->print_driver->flags = (TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); - return 0; -} + /* The kernel wants space to store pointers to tty_structs */ + brd->print_driver->ttys = + kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); + if (!brd->print_driver->ttys) { + rc = -ENOMEM; + goto free_print_drv; + } -static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART); -} -static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL); + /* + * Entry points for driver. Called by the kernel from + * tty_io.c and n_tty.c. + */ + tty_set_operations(brd->print_driver, &dgap_tty_ops); + /* Register tty devices */ + rc = tty_register_driver(brd->serial_driver); + if (rc < 0) + goto free_print_drv; -static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards); -} -static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL); + /* Register Transparent Print devices */ + rc = tty_register_driver(brd->print_driver); + if (rc < 0) + goto unregister_serial_drv; + dgap_boards_by_major[brd->serial_driver->major] = brd; + brd->dgap_serial_major = brd->serial_driver->major; -static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS); -} -static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL); + dgap_boards_by_major[brd->print_driver->major] = brd; + brd->dgap_transparent_print_major = brd->print_driver->major; + return 0; -static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter); -} -static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL); +unregister_serial_drv: + tty_unregister_driver(brd->serial_driver); +free_print_drv: + put_tty_driver(brd->print_driver); +free_serial_drv: + put_tty_driver(brd->serial_driver); -static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick); + return rc; } -static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp, - const char *buf, size_t count) +static void dgap_tty_unregister(struct board_t *brd) { - if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1) - return -EINVAL; - return count; + tty_unregister_driver(brd->print_driver); + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->print_driver); + put_tty_driver(brd->serial_driver); } -static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show, - dgap_driver_pollrate_store); -static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver) -{ - int rc = 0; - struct device_driver *driverfs = &dgap_driver->driver; +static int dgap_alloc_flipbuf(struct board_t *brd) +{ + /* + * allocate flip buffer for board. + */ + brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); + if (!brd->flipbuf) + return -ENOMEM; - rc |= driver_create_file(driverfs, &driver_attr_version); - rc |= driver_create_file(driverfs, &driver_attr_boards); - rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_pollrate); - rc |= driver_create_file(driverfs, &driver_attr_pollcounter); + brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL); + if (!brd->flipflagbuf) { + kfree(brd->flipbuf); + return -ENOMEM; + } - return rc; + return 0; } -static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver) +static void dgap_free_flipbuf(struct board_t *brd) { - struct device_driver *driverfs = &dgap_driver->driver; - - driver_remove_file(driverfs, &driver_attr_version); - driver_remove_file(driverfs, &driver_attr_boards); - driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_pollrate); - driver_remove_file(driverfs, &driver_attr_pollcounter); + kfree(brd->flipbuf); + kfree(brd->flipflagbuf); } static struct board_t *dgap_verify_board(struct device *p) @@ -5843,42 +5600,227 @@ static ssize_t dgap_ports_txcount_show(struct device *p, } static DEVICE_ATTR(ports_txcount, S_IRUSR, dgap_ports_txcount_show, NULL); -/* this function creates the sys files that will export each signal status - * to sysfs each value will be put in a separate filename - */ -static void dgap_create_ports_sysfiles(struct board_t *bd) +static ssize_t dgap_tty_state_show(struct device *d, + struct device_attribute *attr, + char *buf) { - dev_set_drvdata(&bd->pdev->dev, bd); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_state); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); - device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount); + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? + "Open" : "Closed"); +} +static DEVICE_ATTR(state, S_IRUSR, dgap_tty_state_show, NULL); + +static ssize_t dgap_tty_baud_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_baud_info); +} +static DEVICE_ATTR(baud, S_IRUSR, dgap_tty_baud_show, NULL); + +static ssize_t dgap_tty_msignals_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + if (ch->ch_open_count) { + return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n", + (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "", + (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "", + (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "", + (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "", + (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "", + (ch->ch_mistat & UART_MSR_RI) ? "RI" : ""); + } + return 0; +} +static DEVICE_ATTR(msignals, S_IRUSR, dgap_tty_msignals_show, NULL); + +static ssize_t dgap_tty_iflag_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag); +} +static DEVICE_ATTR(iflag, S_IRUSR, dgap_tty_iflag_show, NULL); + +static ssize_t dgap_tty_cflag_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag); +} +static DEVICE_ATTR(cflag, S_IRUSR, dgap_tty_cflag_show, NULL); + +static ssize_t dgap_tty_oflag_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag); +} +static DEVICE_ATTR(oflag, S_IRUSR, dgap_tty_oflag_show, NULL); + +static ssize_t dgap_tty_lflag_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; + + return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag); } +static DEVICE_ATTR(lflag, S_IRUSR, dgap_tty_lflag_show, NULL); + +static ssize_t dgap_tty_digi_flag_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct board_t *bd; + struct channel_t *ch; + struct un_t *un; + + if (!d) + return 0; + un = dev_get_drvdata(d); + if (!un || un->magic != DGAP_UNIT_MAGIC) + return 0; + ch = un->un_ch; + if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) + return 0; + bd = ch->ch_bd; + if (!bd || bd->magic != DGAP_BOARD_MAGIC) + return 0; + if (bd->state != BOARD_READY) + return 0; -/* removes all the sys files created for that port */ -static void dgap_remove_ports_sysfiles(struct board_t *bd) -{ - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); - device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount); + return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags); } +static DEVICE_ATTR(digi_flag, S_IRUSR, dgap_tty_digi_flag_show, NULL); -static ssize_t dgap_tty_state_show(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t dgap_tty_rxcount_show(struct device *d, + struct device_attribute *attr, + char *buf) { struct board_t *bd; struct channel_t *ch; @@ -5898,14 +5840,13 @@ static ssize_t dgap_tty_state_show(struct device *d, if (bd->state != BOARD_READY) return 0; - return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? - "Open" : "Closed"); + return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount); } -static DEVICE_ATTR(state, S_IRUSR, dgap_tty_state_show, NULL); +static DEVICE_ATTR(rxcount, S_IRUSR, dgap_tty_rxcount_show, NULL); -static ssize_t dgap_tty_baud_show(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t dgap_tty_txcount_show(struct device *d, + struct device_attribute *attr, + char *buf) { struct board_t *bd; struct channel_t *ch; @@ -5925,17 +5866,24 @@ static ssize_t dgap_tty_baud_show(struct device *d, if (bd->state != BOARD_READY) return 0; - return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_baud_info); + return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount); } -static DEVICE_ATTR(baud, S_IRUSR, dgap_tty_baud_show, NULL); +static DEVICE_ATTR(txcount, S_IRUSR, dgap_tty_txcount_show, NULL); -static ssize_t dgap_tty_msignals_show(struct device *d, - struct device_attribute *attr, - char *buf) +static ssize_t dgap_tty_name_show(struct device *d, + struct device_attribute *attr, + char *buf) { struct board_t *bd; struct channel_t *ch; struct un_t *un; + int cn; + int bn; + struct cnode *cptr; + int found = FALSE; + int ncount = 0; + int starto = 0; + int i; if (!d) return 0; @@ -5951,324 +5899,562 @@ static ssize_t dgap_tty_msignals_show(struct device *d, if (bd->state != BOARD_READY) return 0; - if (ch->ch_open_count) { - return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n", - (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "", - (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "", - (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "", - (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "", - (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "", - (ch->ch_mistat & UART_MSR_RI) ? "RI" : ""); + bn = bd->boardnum; + cn = ch->ch_portnum; + + for (cptr = bd->bd_config; cptr; cptr = cptr->next) { + + if ((cptr->type == BNODE) && + ((cptr->u.board.type == APORT2_920P) || + (cptr->u.board.type == APORT4_920P) || + (cptr->u.board.type == APORT8_920P) || + (cptr->u.board.type == PAPORT4) || + (cptr->u.board.type == PAPORT8))) { + + found = TRUE; + if (cptr->u.board.v_start) + starto = cptr->u.board.start; + else + starto = 1; + } + + if (cptr->type == TNODE && found == TRUE) { + char *ptr1; + + if (strstr(cptr->u.ttyname, "tty")) { + ptr1 = cptr->u.ttyname; + ptr1 += 3; + } else + ptr1 = cptr->u.ttyname; + + for (i = 0; i < dgap_config_get_num_prts(bd); i++) { + if (cn != i) + continue; + + return snprintf(buf, PAGE_SIZE, "%s%s%02d\n", + (un->un_type == DGAP_PRINT) ? + "pr" : "tty", + ptr1, i + starto); + } + } + + if (cptr->type == CNODE) { + + for (i = 0; i < cptr->u.conc.nport; i++) { + if (cn != (i + ncount)) + continue; + + return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n", + (un->un_type == DGAP_PRINT) ? + "pr" : "tty", + cptr->u.conc.id, + i + (cptr->u.conc.v_start ? + cptr->u.conc.start : 1)); + } + + ncount += cptr->u.conc.nport; + } + + if (cptr->type == MNODE) { + + for (i = 0; i < cptr->u.module.nport; i++) { + if (cn != (i + ncount)) + continue; + + return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n", + (un->un_type == DGAP_PRINT) ? + "pr" : "tty", + cptr->u.module.id, + i + (cptr->u.module.v_start ? + cptr->u.module.start : 1)); + } + + ncount += cptr->u.module.nport; + } } - return 0; + + return snprintf(buf, PAGE_SIZE, "%s_dgap_%d_%d\n", + (un->un_type == DGAP_PRINT) ? "pr" : "tty", bn, cn); +} +static DEVICE_ATTR(custom_name, S_IRUSR, dgap_tty_name_show, NULL); + +static struct attribute *dgap_sysfs_tty_entries[] = { + &dev_attr_state.attr, + &dev_attr_baud.attr, + &dev_attr_msignals.attr, + &dev_attr_iflag.attr, + &dev_attr_cflag.attr, + &dev_attr_oflag.attr, + &dev_attr_lflag.attr, + &dev_attr_digi_flag.attr, + &dev_attr_rxcount.attr, + &dev_attr_txcount.attr, + &dev_attr_custom_name.attr, + NULL +}; + + +/* this function creates the sys files that will export each signal status + * to sysfs each value will be put in a separate filename + */ +static void dgap_create_ports_sysfiles(struct board_t *bd) +{ + dev_set_drvdata(&bd->pdev->dev, bd); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_state); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); + device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount); +} + +/* removes all the sys files created for that port */ +static void dgap_remove_ports_sysfiles(struct board_t *bd) +{ + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount); + device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount); +} + +/* + * Copies the BIOS code from the user to the board, + * and starts the BIOS running. + */ +static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len) +{ + u8 __iomem *addr; + uint offset; + unsigned int i; + + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; + + addr = brd->re_map_membase; + + /* + * clear POST area + */ + for (i = 0; i < 16; i++) + writeb(0, addr + POSTAREA + i); + + /* + * Download bios + */ + offset = 0x1000; + memcpy_toio(addr + offset, ubios, len); + + writel(0x0bf00401, addr); + writel(0, (addr + 4)); + + /* Clear the reset, and change states. */ + writeb(FEPCLR, brd->re_map_port); +} + +/* + * Checks to see if the BIOS completed running on the card. + */ +static int dgap_test_bios(struct board_t *brd) +{ + u8 __iomem *addr; + u16 word; + u16 err1; + u16 err2; + + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return -EINVAL; + + addr = brd->re_map_membase; + word = readw(addr + POSTAREA); + + /* + * It can take 5-6 seconds for a board to + * pass the bios self test and post results. + * Give it 10 seconds. + */ + brd->wait_for_bios = 0; + while (brd->wait_for_bios < 1000) { + /* Check to see if BIOS thinks board is good. (GD). */ + if (word == *(u16 *) "GD") + return 0; + msleep_interruptible(10); + brd->wait_for_bios++; + word = readw(addr + POSTAREA); + } + + /* Gave up on board after too long of time taken */ + err1 = readw(addr + SEQUENCE); + err2 = readw(addr + ERROR); + dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n", + brd->name, err1, err2); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOBIOS; + + return -EIO; } -static DEVICE_ATTR(msignals, S_IRUSR, dgap_tty_msignals_show, NULL); -static ssize_t dgap_tty_iflag_show(struct device *d, - struct device_attribute *attr, - char *buf) +/* + * Copies the FEP code from the user to the board, + * and starts the FEP running. + */ +static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + u8 __iomem *addr; + uint offset; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag); -} -static DEVICE_ATTR(iflag, S_IRUSR, dgap_tty_iflag_show, NULL); + addr = brd->re_map_membase; -static ssize_t dgap_tty_cflag_show(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + /* + * Download FEP + */ + offset = 0x1000; + memcpy_toio(addr + offset, ufep, len); - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + /* + * If board is a concentrator product, we need to give + * it its config string describing how the concentrators look. + */ + if ((brd->type == PCX) || (brd->type == PEPC)) { + u8 string[100]; + u8 __iomem *config; + u8 *xconfig; + unsigned int i = 0; - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag); -} -static DEVICE_ATTR(cflag, S_IRUSR, dgap_tty_cflag_show, NULL); + xconfig = dgap_create_config_string(brd, string); -static ssize_t dgap_tty_oflag_show(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + /* Write string to board memory */ + config = addr + CONFIG; + for (; i < CONFIGSIZE; i++, config++, xconfig++) { + writeb(*xconfig, config); + if ((*xconfig & 0xff) == 0xff) + break; + } + } - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + writel(0xbfc01004, (addr + 0xc34)); + writel(0x3, (addr + 0xc30)); - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag); } -static DEVICE_ATTR(oflag, S_IRUSR, dgap_tty_oflag_show, NULL); -static ssize_t dgap_tty_lflag_show(struct device *d, - struct device_attribute *attr, - char *buf) +/* + * Waits for the FEP to report thats its ready for us to use. + */ +static int dgap_test_fep(struct board_t *brd) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + u8 __iomem *addr; + u16 word; + u16 err1; + u16 err2; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return -EINVAL; - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag); -} -static DEVICE_ATTR(lflag, S_IRUSR, dgap_tty_lflag_show, NULL); + addr = brd->re_map_membase; + word = readw(addr + FEPSTAT); -static ssize_t dgap_tty_digi_flag_show(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + /* + * It can take 2-3 seconds for the FEP to + * be up and running. Give it 5 secs. + */ + brd->wait_for_fep = 0; + while (brd->wait_for_fep < 500) { + /* Check to see if FEP is up and running now. */ + if (word == *(u16 *) "OS") { + /* + * Check to see if the board can support FEP5+ commands. + */ + word = readw(addr + FEP5_PLUS); + if (word == *(u16 *) "5A") + brd->bd_flags |= BD_FEP5PLUS; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + return 0; + } + msleep_interruptible(10); + brd->wait_for_fep++; + word = readw(addr + FEPSTAT); + } - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags); + /* Gave up on board after too long of time taken */ + err1 = readw(addr + SEQUENCE); + err2 = readw(addr + ERROR); + dev_warn(&brd->pdev->dev, + "FEPOS for %s not functioning. Error #(%x,%x).\n", + brd->name, err1, err2); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + + return -EIO; } -static DEVICE_ATTR(digi_flag, S_IRUSR, dgap_tty_digi_flag_show, NULL); -static ssize_t dgap_tty_rxcount_show(struct device *d, - struct device_attribute *attr, - char *buf) +/* + * Physically forces the FEP5 card to reset itself. + */ +static void dgap_do_reset_board(struct board_t *brd) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + u8 check; + u32 check1; + u32 check2; + unsigned int i; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || + !brd->re_map_membase || !brd->re_map_port) + return; - return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount); + /* FEPRST does not vary among supported boards */ + writeb(FEPRST, brd->re_map_port); + + for (i = 0; i <= 1000; i++) { + check = readb(brd->re_map_port) & 0xe; + if (check == FEPRST) + break; + udelay(10); + + } + if (i > 1000) { + dev_warn(&brd->pdev->dev, + "dgap: Board not resetting... Failing board.\n"); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return; + } + + /* + * Make sure there really is memory out there. + */ + writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM)); + writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM)); + check1 = readl(brd->re_map_membase + LOWMEM); + check2 = readl(brd->re_map_membase + HIGHMEM); + + if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) { + dev_warn(&brd->pdev->dev, + "No memory at %p for board.\n", + brd->re_map_membase); + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return; + } } -static DEVICE_ATTR(rxcount, S_IRUSR, dgap_tty_rxcount_show, NULL); -static ssize_t dgap_tty_txcount_show(struct device *d, - struct device_attribute *attr, - char *buf) +#ifdef DIGI_CONCENTRATORS_SUPPORTED +/* + * Sends a concentrator image into the FEP5 board. + */ +static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; + char __iomem *vaddr; + u16 offset; + struct downld_t *to_dp; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase) + return; - return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount); + vaddr = brd->re_map_membase; + + offset = readw((u16 *) (vaddr + DOWNREQ)); + to_dp = (struct downld_t *) (vaddr + (int) offset); + memcpy_toio(to_dp, uaddr, len); + + /* Tell card we have data for it */ + writew(0, vaddr + (DOWNREQ)); + + brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS; } -static DEVICE_ATTR(txcount, S_IRUSR, dgap_tty_txcount_show, NULL); +#endif -static ssize_t dgap_tty_name_show(struct device *d, - struct device_attribute *attr, - char *buf) +#define EXPANSION_ROM_SIZE (64 * 1024) +#define FEP5_ROM_MAGIC (0xFEFFFFFF) + +static void dgap_get_vpd(struct board_t *brd) { - struct board_t *bd; - struct channel_t *ch; - struct un_t *un; - int cn; - int bn; - struct cnode *cptr; - int found = FALSE; - int ncount = 0; - int starto = 0; - int i; + u32 magic; + u32 base_offset; + u16 rom_offset; + u16 vpd_offset; + u16 image_length; + u16 i; + u8 byte1; + u8 byte2; - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGAP_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGAP_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; + /* + * Poke the magic number at the PCI Rom Address location. + * If VPD is supported, the value read from that address + * will be non-zero. + */ + magic = FEP5_ROM_MAGIC; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); + pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - bn = bd->boardnum; - cn = ch->ch_portnum; + /* VPD not supported, bail */ + if (!magic) + return; - for (cptr = bd->bd_config; cptr; cptr = cptr->next) { + /* + * To get to the OTPROM memory, we have to send the boards base + * address or'ed with 1 into the PCI Rom Address location. + */ + magic = brd->membase | 0x01; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); + pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic); - if ((cptr->type == BNODE) && - ((cptr->u.board.type == APORT2_920P) || - (cptr->u.board.type == APORT4_920P) || - (cptr->u.board.type == APORT8_920P) || - (cptr->u.board.type == PAPORT4) || - (cptr->u.board.type == PAPORT8))) { + byte1 = readb(brd->re_map_membase); + byte2 = readb(brd->re_map_membase + 1); - found = TRUE; - if (cptr->u.board.v_start) - starto = cptr->u.board.start; - else - starto = 1; - } + /* + * If the board correctly swapped to the OTPROM memory, + * the first 2 bytes (header) should be 0x55, 0xAA + */ + if (byte1 == 0x55 && byte2 == 0xAA) { - if (cptr->type == TNODE && found == TRUE) { - char *ptr1; + base_offset = 0; - if (strstr(cptr->u.ttyname, "tty")) { - ptr1 = cptr->u.ttyname; - ptr1 += 3; - } else - ptr1 = cptr->u.ttyname; + /* + * We have to run through all the OTPROM memory looking + * for the VPD offset. + */ + while (base_offset <= EXPANSION_ROM_SIZE) { - for (i = 0; i < dgap_config_get_num_prts(bd); i++) { - if (cn != i) - continue; + /* + * Lots of magic numbers here. + * + * The VPD offset is located inside the ROM Data + * Structure. + * + * We also have to remember the length of each + * ROM Data Structure, so we can "hop" to the next + * entry if the VPD isn't in the current + * ROM Data Structure. + */ + rom_offset = readw(brd->re_map_membase + + base_offset + 0x18); + image_length = readw(brd->re_map_membase + + rom_offset + 0x10) * 512; + vpd_offset = readw(brd->re_map_membase + + rom_offset + 0x08); - return snprintf(buf, PAGE_SIZE, "%s%s%02d\n", - (un->un_type == DGAP_PRINT) ? - "pr" : "tty", - ptr1, i + starto); + /* Found the VPD entry */ + if (vpd_offset) + break; + + /* We didn't find a VPD entry, go to next ROM entry. */ + base_offset += image_length; + + byte1 = readb(brd->re_map_membase + base_offset); + byte2 = readb(brd->re_map_membase + base_offset + 1); + + /* + * If the new ROM offset doesn't have 0x55, 0xAA + * as its header, we have run out of ROM. + */ + if (byte1 != 0x55 || byte2 != 0xAA) + break; + } + + /* + * If we have a VPD offset, then mark the board + * as having a valid VPD, and copy VPDSIZE (512) bytes of + * that VPD to the buffer we have in our board structure. + */ + if (vpd_offset) { + brd->bd_flags |= BD_HAS_VPD; + for (i = 0; i < VPDSIZE; i++) { + brd->vpd[i] = readb(brd->re_map_membase + + vpd_offset + i); } } + } - if (cptr->type == CNODE) { + /* + * We MUST poke the magic number at the PCI Rom Address location again. + * This makes the card report the regular board memory back to us, + * rather than the OTPROM memory. + */ + magic = FEP5_ROM_MAGIC; + pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); +} - for (i = 0; i < cptr->u.conc.nport; i++) { - if (cn != (i + ncount)) - continue; - return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n", - (un->un_type == DGAP_PRINT) ? - "pr" : "tty", - cptr->u.conc.id, - i + (cptr->u.conc.v_start ? - cptr->u.conc.start : 1)); - } +static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART); +} +static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL); - ncount += cptr->u.conc.nport; - } - if (cptr->type == MNODE) { +static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards); +} +static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL); - for (i = 0; i < cptr->u.module.nport; i++) { - if (cn != (i + ncount)) - continue; - return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n", - (un->un_type == DGAP_PRINT) ? - "pr" : "tty", - cptr->u.module.id, - i + (cptr->u.module.v_start ? - cptr->u.module.start : 1)); - } +static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS); +} +static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL); + + +static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter); +} +static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL); + +static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick); +} + +static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp, + const char *buf, size_t count) +{ + if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1) + return -EINVAL; + return count; +} +static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show, + dgap_driver_pollrate_store); - ncount += cptr->u.module.nport; - } - } +static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver) +{ + int rc = 0; + struct device_driver *driverfs = &dgap_driver->driver; - return snprintf(buf, PAGE_SIZE, "%s_dgap_%d_%d\n", - (un->un_type == DGAP_PRINT) ? "pr" : "tty", bn, cn); + rc |= driver_create_file(driverfs, &driver_attr_version); + rc |= driver_create_file(driverfs, &driver_attr_boards); + rc |= driver_create_file(driverfs, &driver_attr_maxboards); + rc |= driver_create_file(driverfs, &driver_attr_pollrate); + rc |= driver_create_file(driverfs, &driver_attr_pollcounter); + + return rc; } -static DEVICE_ATTR(custom_name, S_IRUSR, dgap_tty_name_show, NULL); -static struct attribute *dgap_sysfs_tty_entries[] = { - &dev_attr_state.attr, - &dev_attr_baud.attr, - &dev_attr_msignals.attr, - &dev_attr_iflag.attr, - &dev_attr_cflag.attr, - &dev_attr_oflag.attr, - &dev_attr_lflag.attr, - &dev_attr_digi_flag.attr, - &dev_attr_rxcount.attr, - &dev_attr_txcount.attr, - &dev_attr_custom_name.attr, - NULL -}; +static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver) +{ + struct device_driver *driverfs = &dgap_driver->driver; + + driver_remove_file(driverfs, &driver_attr_version); + driver_remove_file(driverfs, &driver_attr_boards); + driver_remove_file(driverfs, &driver_attr_maxboards); + driver_remove_file(driverfs, &driver_attr_pollrate); + driver_remove_file(driverfs, &driver_attr_pollcounter); +} static struct attribute_group dgap_tty_attribute_group = { .name = NULL, @@ -6292,1064 +6478,753 @@ static void dgap_remove_tty_sysfs(struct device *c) sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group); } -static void dgap_cleanup_nodes(void) -{ - struct cnode *p; - - p = &dgap_head; - - while (p) { - struct cnode *tmp = p->next; - - if (p->type == NULLNODE) { - p = tmp; - continue; - } - - switch (p->type) { - case BNODE: - kfree(p->u.board.portstr); - kfree(p->u.board.addrstr); - kfree(p->u.board.pcibusstr); - kfree(p->u.board.pcislotstr); - kfree(p->u.board.method); - break; - case CNODE: - kfree(p->u.conc.id); - kfree(p->u.conc.connect); - break; - case MNODE: - kfree(p->u.module.id); - break; - case TNODE: - kfree(p->u.ttyname); - break; - case CUNODE: - kfree(p->u.cuname); - break; - case LNODE: - kfree(p->u.line.cable); - break; - case PNODE: - kfree(p->u.printname); - break; - } - - kfree(p->u.board.status); - kfree(p); - p = tmp; - } -} /* - * Parse a configuration file read into memory as a string. + * Create pr and tty device entries */ -static int dgap_parsefile(char **in) +static int dgap_tty_register_ports(struct board_t *brd) { - struct cnode *p, *brd, *line, *conc; - int rc; - char *s; - int linecnt = 0; - - p = &dgap_head; - brd = line = conc = NULL; + struct channel_t *ch; + int i; + int ret; - /* perhaps we are adding to an existing list? */ - while (p->next) - p = p->next; + brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports), + GFP_KERNEL); + if (!brd->serial_ports) + return -ENOMEM; - /* file must start with a BEGIN */ - while ((rc = dgap_gettok(in)) != BEGIN) { - if (rc == 0) { - pr_err("unexpected EOF"); - return -1; - } + brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports), + GFP_KERNEL); + if (!brd->printer_ports) { + ret = -ENOMEM; + goto free_serial_ports; } - for (; ;) { - int board_type = 0; - int conc_type = 0; - int module_type = 0; - - rc = dgap_gettok(in); - if (rc == 0) { - pr_err("unexpected EOF"); - return -1; - } - - switch (rc) { - case BEGIN: /* should only be 1 begin */ - pr_err("unexpected config_begin\n"); - return -1; - - case END: - return 0; - - case BOARD: /* board info */ - if (dgap_checknode(p)) - return -1; - - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; - - p = p->next; - - p->type = BNODE; - p->u.board.status = kstrdup("No", GFP_KERNEL); - line = conc = NULL; - brd = p; - linecnt = -1; + for (i = 0; i < brd->nasync; i++) { + tty_port_init(&brd->serial_ports[i]); + tty_port_init(&brd->printer_ports[i]); + } - board_type = dgap_gettok(in); - if (board_type == 0) { - pr_err("board !!type not specified"); - return -1; - } + ch = brd->channels[0]; + for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) { - p->u.board.type = board_type; + struct device *classp; - break; + classp = tty_port_register_device(&brd->serial_ports[i], + brd->serial_driver, + i, NULL); - case IO: /* i/o port */ - if (p->type != BNODE) { - pr_err("IO port only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.portstr = kstrdup(s, GFP_KERNEL); - if (kstrtol(s, 0, &p->u.board.port)) { - pr_err("bad number for IO port"); - return -1; - } - p->u.board.v_port = 1; - break; + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } - case MEM: /* memory address */ - if (p->type != BNODE) { - pr_err("memory address only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.addrstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.addr)) { - pr_err("bad number for memory address"); - return -1; - } - p->u.board.v_addr = 1; - break; + dgap_create_tty_sysfs(&ch->ch_tun, classp); + ch->ch_tun.un_sysfs = classp; - case PCIINFO: /* pci information */ - if (p->type != BNODE) { - pr_err("memory address only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.pcibus)) { - pr_err("bad number for pci bus"); - return -1; - } - p->u.board.v_pcibus = 1; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL); - if (kstrtoul(s, 0, &p->u.board.pcislot)) { - pr_err("bad number for pci slot"); - return -1; - } - p->u.board.v_pcislot = 1; - break; + classp = tty_port_register_device(&brd->printer_ports[i], + brd->print_driver, + i, NULL); - case METHOD: - if (p->type != BNODE) { - pr_err("install method only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.method = kstrdup(s, GFP_KERNEL); - p->u.board.v_method = 1; - break; + if (IS_ERR(classp)) { + ret = PTR_ERR(classp); + goto unregister_ttys; + } - case STATUS: - if (p->type != BNODE) { - pr_err("config status only vaild for boards"); - return -1; - } - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.board.status = kstrdup(s, GFP_KERNEL); - break; + dgap_create_tty_sysfs(&ch->ch_pun, classp); + ch->ch_pun.un_sysfs = classp; + } + dgap_create_ports_sysfiles(brd); - case NPORTS: /* number of ports */ - if (p->type == BNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.board.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.board.v_nport = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.conc.v_nport = 1; - } else if (p->type == MNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.module.nport)) { - pr_err("bad number for number of ports"); - return -1; - } - p->u.module.v_nport = 1; - } else { - pr_err("nports only valid for concentrators or modules"); - return -1; - } - break; + return 0; - case ID: /* letter ID used in tty name */ - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } +unregister_ttys: + while (i >= 0) { + ch = brd->channels[i]; + if (ch->ch_tun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs); + tty_unregister_device(brd->serial_driver, i); + } - p->u.board.status = kstrdup(s, GFP_KERNEL); + if (ch->ch_pun.un_sysfs) { + dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs); + tty_unregister_device(brd->print_driver, i); + } + i--; + } - if (p->type == CNODE) { - p->u.conc.id = kstrdup(s, GFP_KERNEL); - p->u.conc.v_id = 1; - } else if (p->type == MNODE) { - p->u.module.id = kstrdup(s, GFP_KERNEL); - p->u.module.v_id = 1; - } else { - pr_err("id only valid for concentrators or modules"); - return -1; - } - break; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->serial_ports[i]); + tty_port_destroy(&brd->printer_ports[i]); + } - case STARTO: /* start offset of ID */ - if (p->type == BNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.board.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.board.v_start = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.conc.v_start = 1; - } else if (p->type == MNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.module.start)) { - pr_err("bad number for start of tty count"); - return -1; - } - p->u.module.v_start = 1; - } else { - pr_err("start only valid for concentrators or modules"); - return -1; - } - break; + kfree(brd->printer_ports); + brd->printer_ports = NULL; - case TTYN: /* tty name prefix */ - if (dgap_checknode(p)) - return -1; +free_serial_ports: + kfree(brd->serial_ports); + brd->serial_ports = NULL; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + return ret; +} - p = p->next; - p->type = TNODE; +/* + * dgap_cleanup_tty() + * + * Uninitialize the TTY portion of this driver. Free all memory and + * resources. + */ +static void dgap_cleanup_tty(struct board_t *brd) +{ + struct device *dev; + unsigned int i; - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.ttyname = kstrdup(s, GFP_KERNEL); - if (!p->u.ttyname) - return -1; + dgap_boards_by_major[brd->serial_driver->major] = NULL; + brd->dgap_serial_major = 0; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->serial_ports[i]); + dev = brd->channels[i]->ch_tun.un_sysfs; + dgap_remove_tty_sysfs(dev); + tty_unregister_device(brd->serial_driver, i); + } + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->serial_driver); + kfree(brd->serial_ports); - break; + dgap_boards_by_major[brd->print_driver->major] = NULL; + brd->dgap_transparent_print_major = 0; + for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->printer_ports[i]); + dev = brd->channels[i]->ch_pun.un_sysfs; + dgap_remove_tty_sysfs(dev); + tty_unregister_device(brd->print_driver, i); + } + tty_unregister_driver(brd->print_driver); + put_tty_driver(brd->print_driver); + kfree(brd->printer_ports); +} - case CU: /* cu name prefix */ - if (dgap_checknode(p)) - return -1; +static int dgap_request_irq(struct board_t *brd) +{ + int rc; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return -ENODEV; - p = p->next; - p->type = CUNODE; + /* + * Set up our interrupt handler if we are set to do interrupts. + */ + if (dgap_config_get_useintr(brd) && brd->irq) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.cuname = kstrdup(s, GFP_KERNEL); - if (!p->u.cuname) - return -1; + rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd); - break; + if (!rc) + brd->intr_used = 1; + } + return 0; +} - case LINE: /* line information */ - if (dgap_checknode(p)) - return -1; - if (!brd) { - pr_err("must specify board before line info"); - return -1; - } - switch (brd->u.board.type) { - case PPCM: - pr_err("line not vaild for PC/em"); - return -1; - } +static void dgap_free_irq(struct board_t *brd) +{ + if (brd->intr_used && brd->irq) + free_irq(brd->irq, brd); +} + +static int dgap_firmware_load(struct pci_dev *pdev, int card_type, + struct board_t *brd) +{ + const struct firmware *fw; + char *tmp_ptr; + int ret; + char *dgap_config_buf; + + dgap_get_vpd(brd); + dgap_do_reset_board(brd); + + if (fw_info[card_type].conf_name) { + ret = request_firmware(&fw, fw_info[card_type].conf_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "config file %s not found\n", + fw_info[card_type].conf_name); + return ret; + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL); + if (!dgap_config_buf) { + release_firmware(fw); + return -ENOMEM; + } - p = p->next; - p->type = LNODE; - conc = NULL; - line = p; - linecnt++; - break; + memcpy(dgap_config_buf, fw->data, fw->size); + release_firmware(fw); - case CONC: /* concentrator information */ - if (dgap_checknode(p)) - return -1; - if (!line) { - pr_err("must specify line info before concentrator"); - return -1; - } + /* + * preserve dgap_config_buf + * as dgap_parsefile would + * otherwise alter it. + */ + tmp_ptr = dgap_config_buf; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + if (dgap_parsefile(&tmp_ptr) != 0) { + kfree(dgap_config_buf); + return -EINVAL; + } + kfree(dgap_config_buf); + } - p = p->next; - p->type = CNODE; - conc = p; + /* + * Match this board to a config the user created for us. + */ + brd->bd_config = + dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot); - if (linecnt) - brd->u.board.conc2++; - else - brd->u.board.conc1++; + /* + * Because the 4 port Xr products share the same PCI ID + * as the 8 port Xr products, if we receive a NULL config + * back, and this is a PAPORT8 board, retry with a + * PAPORT4 attempt as well. + */ + if (brd->type == PAPORT8 && !brd->bd_config) + brd->bd_config = + dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot); - conc_type = dgap_gettok(in); - if (conc_type == 0 || conc_type != CX || - conc_type != EPC) { - pr_err("failed to set a type of concentratros"); - return -1; - } + if (!brd->bd_config) { + dev_err(&pdev->dev, "No valid configuration found\n"); + return -EINVAL; + } - p->u.conc.type = conc_type; + if (fw_info[card_type].bios_name) { + ret = request_firmware(&fw, fw_info[card_type].bios_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "bios file %s not found\n", + fw_info[card_type].bios_name); + return ret; + } + dgap_do_bios_load(brd, fw->data, fw->size); + release_firmware(fw); - break; + /* Wait for BIOS to test board... */ + ret = dgap_test_bios(brd); + if (ret) + return ret; + } - case MOD: /* EBI module */ - if (dgap_checknode(p)) - return -1; - if (!brd) { - pr_err("must specify board info before EBI modules"); - return -1; - } - switch (brd->u.board.type) { - case PPCM: - linecnt = 0; - break; - default: - if (!conc) { - pr_err("must specify concentrator info before EBI module"); - return -1; - } - } + if (fw_info[card_type].fep_name) { + ret = request_firmware(&fw, fw_info[card_type].fep_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "dgap: fep file %s not found\n", + fw_info[card_type].fep_name); + return ret; + } + dgap_do_fep_load(brd, fw->data, fw->size); + release_firmware(fw); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* Wait for FEP to load on board... */ + ret = dgap_test_fep(brd); + if (ret) + return ret; + } - p = p->next; - p->type = MNODE; +#ifdef DIGI_CONCENTRATORS_SUPPORTED + /* + * If this is a CX or EPCX, we need to see if the firmware + * is requesting a concentrator image from us. + */ + if ((bd->type == PCX) || (bd->type == PEPC)) { + chk_addr = (u16 *) (vaddr + DOWNREQ); + /* Nonzero if FEP is requesting concentrator image. */ + check = readw(chk_addr); + vaddr = brd->re_map_membase; + } - if (linecnt) - brd->u.board.module2++; - else - brd->u.board.module1++; + if (fw_info[card_type].con_name && check && vaddr) { + ret = request_firmware(&fw, fw_info[card_type].con_name, + &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "conc file %s not found\n", + fw_info[card_type].con_name); + return ret; + } + /* Put concentrator firmware loading code here */ + offset = readw((u16 *) (vaddr + DOWNREQ)); + memcpy_toio(offset, fw->data, fw->size); - module_type = dgap_gettok(in); - if (module_type == 0 || module_type != PORTS || - module_type != MODEM) { - pr_err("failed to set a type of module"); - return -1; - } + dgap_do_conc_load(brd, (char *)fw->data, fw->size) + release_firmware(fw); + } +#endif - p->u.module.type = module_type; + return 0; +} - break; +/* + * dgap_tty_init() + * + * Init the tty subsystem. Called once per board after board has been + * downloaded and init'ed. + */ +static int dgap_tty_init(struct board_t *brd) +{ + int i; + int tlw; + uint true_count; + u8 __iomem *vaddr; + u8 modem; + struct channel_t *ch; + struct bs_t __iomem *bs; + struct cm_t __iomem *cm; + int ret; - case CABLE: - if (p->type == LNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.line.cable = kstrdup(s, GFP_KERNEL); - p->u.line.v_cable = 1; - } - break; + /* + * Initialize board structure elements. + */ - case SPEED: /* sync line speed indication */ - if (p->type == LNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.line.speed)) { - pr_err("bad number for line speed"); - return -1; - } - p->u.line.v_speed = 1; - } else if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.conc.speed)) { - pr_err("bad number for line speed"); - return -1; - } - p->u.conc.v_speed = 1; - } else { - pr_err("speed valid only for lines or concentrators."); - return -1; - } - break; + vaddr = brd->re_map_membase; + true_count = readw((vaddr + NCHAN)); - case CONNECT: - if (p->type == CNODE) { - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - p->u.conc.connect = kstrdup(s, GFP_KERNEL); - p->u.conc.v_connect = 1; - } - break; - case PRINT: /* transparent print name prefix */ - if (dgap_checknode(p)) - return -1; + brd->nasync = dgap_config_get_num_prts(brd); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + if (!brd->nasync) + brd->nasync = brd->maxports; - p = p->next; - p->type = PNODE; + if (brd->nasync > brd->maxports) + brd->nasync = brd->maxports; + + if (true_count != brd->nasync) { + dev_warn(&brd->pdev->dev, + "%s configured for %d ports, has %d ports.\n", + brd->name, brd->nasync, true_count); + + if ((brd->type == PPCM) && + (true_count == 64 || true_count == 0)) { + dev_warn(&brd->pdev->dev, + "Please make SURE the EBI cable running from the card\n"); + dev_warn(&brd->pdev->dev, + "to each EM module is plugged into EBI IN!\n"); + } - s = dgap_getword(in); - if (!s) { - pr_err("unexpeced end of file"); - return -1; - } - p->u.printname = kstrdup(s, GFP_KERNEL); - if (!p->u.printname) - return -1; + brd->nasync = true_count; - break; + /* If no ports, don't bother going any further */ + if (!brd->nasync) { + brd->state = BOARD_FAILED; + brd->dpastatus = BD_NOFEP; + return -EIO; + } + } - case CMAJOR: /* major number */ - if (dgap_checknode(p)) - return -1; + /* + * Allocate channel memory that might not have been allocated + * when the driver was first loaded. + */ + for (i = 0; i < brd->nasync; i++) { + brd->channels[i] = + kzalloc(sizeof(struct channel_t), GFP_KERNEL); + if (!brd->channels[i]) { + ret = -ENOMEM; + goto free_chan; + } + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + ch = brd->channels[0]; + vaddr = brd->re_map_membase; - p = p->next; - p->type = JNODE; + bs = (struct bs_t __iomem *) ((ulong) vaddr + CHANBUF); + cm = (struct cm_t __iomem *) ((ulong) vaddr + CMDBUF); - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.majornumber)) { - pr_err("bad number for major number"); - return -1; - } - break; + brd->bd_bs = bs; - case ALTPIN: /* altpin setting */ - if (dgap_checknode(p)) - return -1; + /* Set up channel variables */ + for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) { - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + spin_lock_init(&ch->ch_lock); - p = p->next; - p->type = ANODE; + /* Store all our magic numbers */ + ch->magic = DGAP_CHANNEL_MAGIC; + ch->ch_tun.magic = DGAP_UNIT_MAGIC; + ch->ch_tun.un_type = DGAP_SERIAL; + ch->ch_tun.un_ch = ch; + ch->ch_tun.un_dev = i; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.altpin)) { - pr_err("bad number for altpin"); - return -1; - } - break; + ch->ch_pun.magic = DGAP_UNIT_MAGIC; + ch->ch_pun.un_type = DGAP_PRINT; + ch->ch_pun.un_ch = ch; + ch->ch_pun.un_dev = i; - case USEINTR: /* enable interrupt setting */ - if (dgap_checknode(p)) - return -1; + ch->ch_vaddr = vaddr; + ch->ch_bs = bs; + ch->ch_cm = cm; + ch->ch_bd = brd; + ch->ch_portnum = i; + ch->ch_digi = dgap_digi_init; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * Set up digi dsr and dcd bits based on altpin flag. + */ + if (dgap_config_get_altpin(brd)) { + ch->ch_dsr = DM_CD; + ch->ch_cd = DM_DSR; + ch->ch_digi.digi_flags |= DIGI_ALTPIN; + } else { + ch->ch_cd = DM_CD; + ch->ch_dsr = DM_DSR; + } - p = p->next; - p->type = INTRNODE; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.useintr)) { - pr_err("bad number for useintr"); - return -1; - } - break; + ch->ch_taddr = vaddr + (ioread16(&(ch->ch_bs->tx_seg)) << 4); + ch->ch_raddr = vaddr + (ioread16(&(ch->ch_bs->rx_seg)) << 4); + ch->ch_tx_win = 0; + ch->ch_rx_win = 0; + ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1; + ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1; + ch->ch_tstart = 0; + ch->ch_rstart = 0; - case TTSIZ: /* size of tty structure */ - if (dgap_checknode(p)) - return -1; + /* + * Set queue water marks, interrupt mask, + * and general tty parameters. + */ + tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : + ch->ch_tsize / 2; + ch->ch_tlw = tlw; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + dgap_cmdw(ch, STLOW, tlw, 0); - p = p->next; - p->type = TSNODE; + dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0); - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.ttysize)) { - pr_err("bad number for ttysize"); - return -1; - } - break; + dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0); - case CHSIZ: /* channel structure size */ - if (dgap_checknode(p)) - return -1; + ch->ch_mistat = readb(&(ch->ch_bs->m_stat)); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + init_waitqueue_head(&ch->ch_flags_wait); + init_waitqueue_head(&ch->ch_tun.un_flags_wait); + init_waitqueue_head(&ch->ch_pun.un_flags_wait); - p = p->next; - p->type = CSNODE; + /* Turn on all modem interrupts for now */ + modem = (DM_CD | DM_DSR | DM_CTS | DM_RI); + writeb(modem, &(ch->ch_bs->m_int)); - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.chsize)) { - pr_err("bad number for chsize"); - return -1; - } - break; + /* + * Set edelay to 0 if interrupts are turned on, + * otherwise set edelay to the usual 100. + */ + if (brd->intr_used) + writew(0, &(ch->ch_bs->edelay)); + else + writew(100, &(ch->ch_bs->edelay)); - case BSSIZ: /* board structure size */ - if (dgap_checknode(p)) - return -1; + writeb(1, &(ch->ch_bs->idata)); + } - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + return 0; - p = p->next; - p->type = BSNODE; +free_chan: + while (--i >= 0) { + kfree(brd->channels[i]); + brd->channels[i] = NULL; + } + return ret; +} - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.bssize)) { - pr_err("bad number for bssize"); - return -1; - } - break; +/* + * dgap_tty_free() + * + * Free the channles which are allocated in dgap_tty_init(). + */ +static void dgap_tty_free(struct board_t *brd) +{ + int i; - case UNTSIZ: /* sched structure size */ - if (dgap_checknode(p)) - return -1; + for (i = 0; i < brd->nasync; i++) + kfree(brd->channels[i]); +} - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; +static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int rc; + struct board_t *brd; - p = p->next; - p->type = USNODE; + if (dgap_numboards >= MAXBOARDS) + return -EPERM; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.unsize)) { - pr_err("bad number for schedsize"); - return -1; - } - break; + rc = pci_enable_device(pdev); + if (rc) + return -EIO; - case F2SIZ: /* f2200 structure size */ - if (dgap_checknode(p)) - return -1; + brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards); + if (IS_ERR(brd)) + return PTR_ERR(brd); - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + rc = dgap_firmware_load(pdev, ent->driver_data, brd); + if (rc) + goto cleanup_brd; - p = p->next; - p->type = FSNODE; + rc = dgap_alloc_flipbuf(brd); + if (rc) + goto cleanup_brd; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.f2size)) { - pr_err("bad number for f2200size"); - return -1; - } - break; + rc = dgap_tty_register(brd); + if (rc) + goto free_flipbuf; - case VPSIZ: /* vpix structure size */ - if (dgap_checknode(p)) - return -1; + rc = dgap_request_irq(brd); + if (rc) + goto unregister_tty; - p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) - return -1; + /* + * Do tty device initialization. + */ + rc = dgap_tty_init(brd); + if (rc < 0) + goto free_irq; - p = p->next; - p->type = VSNODE; + rc = dgap_tty_register_ports(brd); + if (rc) + goto tty_free; - s = dgap_getword(in); - if (!s) { - pr_err("unexpected end of file"); - return -1; - } - if (kstrtol(s, 0, &p->u.vpixsize)) { - pr_err("bad number for vpixsize"); - return -1; - } - break; - } - } -} + brd->state = BOARD_READY; + brd->dpastatus = BD_RUNNING; -/* - * dgap_sindex: much like index(), but it looks for a match of any character in - * the group, and returns that position. If the first character is a ^, then - * this will match the first occurrence not in that group. - */ -static char *dgap_sindex(char *string, char *group) -{ - char *ptr; + dgap_board[dgap_numboards++] = brd; - if (!string || !group) - return NULL; + return 0; - if (*group == '^') { - group++; - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - break; - } - if (*ptr == '\0') - return string; - } - } else { - for (; *string; string++) { - for (ptr = group; *ptr; ptr++) { - if (*ptr == *string) - return string; - } - } - } +tty_free: + dgap_tty_free(brd); +free_irq: + dgap_free_irq(brd); +unregister_tty: + dgap_tty_unregister(brd); +free_flipbuf: + dgap_free_flipbuf(brd); +cleanup_brd: + dgap_cleanup_nodes(); + dgap_unmap(brd); + kfree(brd); - return NULL; + return rc; +} + +static void dgap_remove_one(struct pci_dev *dev) +{ + /* Do Nothing */ } +static struct pci_driver dgap_driver = { + .name = "dgap", + .probe = dgap_init_one, + .id_table = dgap_pci_tbl, + .remove = dgap_remove_one, +}; + /* - * Get a token from the input file; return 0 if end of file is reached + * dgap_init_globals() + * + * This is where we initialize the globals from the static insmod + * configuration variables. These are declared near the head of + * this file. */ -static int dgap_gettok(char **in) +static void dgap_init_globals(void) { - char *w; - struct toklist *t; + unsigned int i; - if (strstr(dgap_cword, "board")) { - w = dgap_getword(in); - snprintf(dgap_cword, MAXCWORD, "%s", w); - for (t = dgap_brdtype; t->token != 0; t++) { - if (!strcmp(w, t->string)) - return t->token; - } - } else { - while ((w = dgap_getword(in))) { - snprintf(dgap_cword, MAXCWORD, "%s", w); - for (t = dgap_tlist; t->token != 0; t++) { - if (!strcmp(w, t->string)) - return t->token; - } - } - } + for (i = 0; i < MAXBOARDS; i++) + dgap_board[i] = NULL; - return 0; + init_timer(&dgap_poll_timer); } /* - * get a word from the input stream, also keep track of current line number. - * words are separated by whitespace. + * Start of driver. */ -static char *dgap_getword(char **in) +static int dgap_start(void) { - char *ret_ptr = *in; + int rc; + unsigned long flags; + struct device *device; - char *ptr = dgap_sindex(*in, " \t\n"); + /* + * make sure that the globals are + * init'd before we do anything else + */ + dgap_init_globals(); - /* If no word found, return null */ - if (!ptr) - return NULL; + dgap_numboards = 0; - /* Mark new location for our buffer */ - *ptr = '\0'; - *in = ptr + 1; + pr_info("For the tools package please visit http://www.digi.com\n"); - /* Eat any extra spaces/tabs/newlines that might be present */ - while (*in && **in && ((**in == ' ') || - (**in == '\t') || - (**in == '\n'))) { - **in = '\0'; - *in = *in + 1; + /* + * Register our base character device into the kernel. + */ + + /* + * Register management/dpa devices + */ + rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops); + if (rc < 0) + return rc; + + dgap_class = class_create(THIS_MODULE, "dgap_mgmt"); + if (IS_ERR(dgap_class)) { + rc = PTR_ERR(dgap_class); + goto failed_class; } - return ret_ptr; -} + device = device_create(dgap_class, NULL, + MKDEV(DIGI_DGAP_MAJOR, 0), + NULL, "dgap_mgmt"); + if (IS_ERR(device)) { + rc = PTR_ERR(device); + goto failed_device; + } -/* - * dgap_checknode: see if all the necessary info has been supplied for a node - * before creating the next node. - */ -static int dgap_checknode(struct cnode *p) -{ - switch (p->type) { - case LNODE: - if (p->u.line.v_speed == 0) { - pr_err("line speed not specified"); - return 1; - } - return 0; + /* Start the poller */ + spin_lock_irqsave(&dgap_poll_lock, flags); + init_timer(&dgap_poll_timer); + dgap_poll_timer.function = dgap_poll_handler; + dgap_poll_timer.data = 0; + dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick); + dgap_poll_timer.expires = dgap_poll_time; + spin_unlock_irqrestore(&dgap_poll_lock, flags); - case CNODE: - if (p->u.conc.v_speed == 0) { - pr_err("concentrator line speed not specified"); - return 1; - } - if (p->u.conc.v_nport == 0) { - pr_err("number of ports on concentrator not specified"); - return 1; - } - if (p->u.conc.v_id == 0) { - pr_err("concentrator id letter not specified"); - return 1; - } - return 0; + add_timer(&dgap_poll_timer); - case MNODE: - if (p->u.module.v_nport == 0) { - pr_err("number of ports on EBI module not specified"); - return 1; - } - if (p->u.module.v_id == 0) { - pr_err("EBI module id letter not specified"); - return 1; - } - return 0; - } - return 0; + return rc; + +failed_device: + class_destroy(dgap_class); +failed_class: + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); + return rc; } -/* - * Given a board pointer, returns whether we should use interrupts or not. - */ -static uint dgap_config_get_useintr(struct board_t *bd) +static void dgap_stop(void) { - struct cnode *p; + unsigned long lock_flags; - if (!bd) - return 0; + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - for (p = bd->bd_config; p; p = p->next) { - if (p->type == INTRNODE) { - /* - * check for pcxr types. - */ - return p->u.useintr; - } - } + del_timer_sync(&dgap_poll_timer); - /* If not found, then don't turn on interrupts. */ - return 0; + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); } /* - * Given a board pointer, returns whether we turn on altpin or not. + * dgap_cleanup_board() + * + * Free all the memory associated with a board */ -static uint dgap_config_get_altpin(struct board_t *bd) +static void dgap_cleanup_board(struct board_t *brd) { - struct cnode *p; + unsigned int i; - if (!bd) - return 0; + if (!brd || brd->magic != DGAP_BOARD_MAGIC) + return; - for (p = bd->bd_config; p; p = p->next) { - if (p->type == ANODE) { - /* - * check for pcxr types. - */ - return p->u.altpin; - } - } + dgap_free_irq(brd); - /* If not found, then don't turn on interrupts. */ - return 0; + tasklet_kill(&brd->helper_tasklet); + + dgap_unmap(brd); + + /* Free all allocated channels structs */ + for (i = 0; i < MAXPORTS ; i++) + kfree(brd->channels[i]); + + kfree(brd->flipbuf); + kfree(brd->flipflagbuf); + + dgap_board[brd->boardnum] = NULL; + + kfree(brd); } + +/************************************************************************ + * + * Driver load/unload functions + * + ************************************************************************/ + /* - * Given a specific type of board, if found, detached link and - * returns the first occurrence in the list. + * init_module() + * + * Module load. This is where it all starts. */ -static struct cnode *dgap_find_config(int type, int bus, int slot) +static int dgap_init_module(void) { - struct cnode *p, *prev, *prev2, *found; - - p = &dgap_head; - - while (p->next) { - prev = p; - p = p->next; - - if (p->type != BNODE) - continue; + int rc; - if (p->u.board.type != type) - continue; + pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART); - if (p->u.board.v_pcibus && - p->u.board.pcibus != bus) - continue; + rc = dgap_start(); + if (rc) + return rc; - if (p->u.board.v_pcislot && - p->u.board.pcislot != slot) - continue; + rc = pci_register_driver(&dgap_driver); + if (rc) + goto err_stop; - found = p; - /* - * Keep walking thru the list till we - * find the next board. - */ - while (p->next) { - prev2 = p; - p = p->next; + rc = dgap_create_driver_sysfiles(&dgap_driver); + if (rc) + goto err_unregister; - if (p->type != BNODE) - continue; + dgap_driver_state = DRIVER_READY; - /* - * Mark the end of our 1 board - * chain of configs. - */ - prev2->next = NULL; + return 0; - /* - * Link the "next" board to the - * previous board, effectively - * "unlinking" our board from - * the main config. - */ - prev->next = p; +err_unregister: + pci_unregister_driver(&dgap_driver); +err_stop: + dgap_stop(); - return found; - } - /* - * It must be the last board in the list. - */ - prev->next = NULL; - return found; - } - return NULL; + return rc; } /* - * Given a board pointer, walks the config link, counting up - * all ports user specified should be on the board. - * (This does NOT mean they are all actually present right now tho) + * dgap_cleanup_module() + * + * Module unload. This is where it all ends. */ -static uint dgap_config_get_num_prts(struct board_t *bd) +static void dgap_cleanup_module(void) { - int count = 0; - struct cnode *p; + unsigned int i; + ulong lock_flags; - if (!bd) - return 0; + spin_lock_irqsave(&dgap_poll_lock, lock_flags); + dgap_poll_stop = 1; + spin_unlock_irqrestore(&dgap_poll_lock, lock_flags); - for (p = bd->bd_config; p; p = p->next) { + /* Turn off poller right away. */ + del_timer_sync(&dgap_poll_timer); - switch (p->type) { - case BNODE: - /* - * check for pcxr types. - */ - if (p->u.board.type > EPCFE) - count += p->u.board.nport; - break; - case CNODE: - count += p->u.conc.nport; - break; - case MNODE: - count += p->u.module.nport; - break; - } - } - return count; -} + dgap_remove_driver_sysfiles(&dgap_driver); -static char *dgap_create_config_string(struct board_t *bd, char *string) -{ - char *ptr = string; - struct cnode *p; - struct cnode *q; - int speed; + device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0)); + class_destroy(dgap_class); + unregister_chrdev(DIGI_DGAP_MAJOR, "dgap"); - if (!bd) { - *ptr = 0xff; - return string; + for (i = 0; i < dgap_numboards; ++i) { + dgap_remove_ports_sysfiles(dgap_board[i]); + dgap_cleanup_tty(dgap_board[i]); + dgap_cleanup_board(dgap_board[i]); } - for (p = bd->bd_config; p; p = p->next) { + dgap_cleanup_nodes(); - switch (p->type) { - case LNODE: - *ptr = '\0'; - ptr++; - *ptr = p->u.line.speed; - ptr++; - break; - case CNODE: - /* - * Because the EPC/con concentrators can have EM modules - * hanging off of them, we have to walk ahead in the - * list and keep adding the number of ports on each EM - * to the config. UGH! - */ - speed = p->u.conc.speed; - q = p->next; - if (q && (q->type == MNODE)) { - *ptr = (p->u.conc.nport + 0x80); - ptr++; - p = q; - while (q->next && (q->next->type) == MNODE) { - *ptr = (q->u.module.nport + 0x80); - ptr++; - p = q; - q = q->next; - } - *ptr = q->u.module.nport; - ptr++; - } else { - *ptr = p->u.conc.nport; - ptr++; - } + if (dgap_numboards) + pci_unregister_driver(&dgap_driver); +} - *ptr = speed; - ptr++; - break; - } - } +module_init(dgap_init_module); +module_exit(dgap_cleanup_module); - *ptr = 0xff; - return string; -} +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Digi International, http://www.digi.com"); +MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line"); +MODULE_SUPPORTED_DEVICE("dgap"); -- GitLab From 5d070cf25c4ecefaaa845ee7c1c3719c90f1c370 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:26 +0000 Subject: [PATCH 2855/9457] staging: comedi: maybe force CMDF_WRITE command flag Most comedi subdevices that support asynchronous commands only support data transfer in either the "read" or "write" direction, as indicated by the `SDF_CMD_READ` and `SDF_CMD_WRITE` subdevice flags, although a few support both directions on the same subdevice (though not simultaneously). The `struct comedi_cmd` structure passed via ioctl call to set up the command contains a `CMDF_WRITE` flag that can be used to choose the direction if the subdevice supports both directions, but the flag is optional if the subdevice only supports data transfer in one direction. If the subdevice only supports asynchronous data transfer in a sing direction, set the `CMDF_WRITE` flag to the correct state so that Comedi can make use of it later. In the case of the `COMEDI_CMDTEST` ioctl, the updated flag will be written back to the `struct comedi_cmd` in user-space. In the case of the `COMEDI_CMD` ioctl, the flag only gets written back if an error is detected while testing the command, or if the `CMDF_BOGUS` command flag is set. Since `__comedi_get_user_cmd()` is called for both ioctls, that's a good place to set the flag. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index c1fe9e0e46d1..b489d9481a69 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1451,6 +1451,21 @@ static int __comedi_get_user_cmd(struct comedi_device *dev, return -EINVAL; } + /* + * Set the CMDF_WRITE flag to the correct state if the subdevice + * supports only "read" commands or only "write" commands. + */ + switch (s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) { + case SDF_CMD_READ: + cmd->flags &= ~CMDF_WRITE; + break; + case SDF_CMD_WRITE: + cmd->flags |= CMDF_WRITE; + break; + default: + break; + } + return 0; } -- GitLab From 8986d37ace6aed435c29084756923bdbb5148624 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:27 +0000 Subject: [PATCH 2856/9457] staging: comedi: me4000: don't clobber command flags The low-level Comedi drivers shouldn't change the `flags` member of `struct comedi_cmd` as the Comedi core also uses some of those flags. They should just ignore the flags they don't understand. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b5115d8d6170..728447123b4c 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -833,9 +833,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, unsigned int scan_ticks; int err = 0; - /* Only rounding flags are implemented */ - cmd->flags &= CMDF_ROUND_NEAREST | CMDF_ROUND_UP | CMDF_ROUND_DOWN; - /* Round the timer arguments */ ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks); -- GitLab From fb5a88eb9c2e20e2a68caea7ebebab65d2a13cd1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:28 +0000 Subject: [PATCH 2857/9457] staging: comedi: ni_mio_common: don't change CMDF_WRITE flag There is no need for `ni_ai_cmdtest()` or `ni_ao_cmdtest()` to set the `CMDF_WRITE` flag to the correct state as it has already been done by the core comedi module. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 18e68cd3ac53..fd61d24bc3a4 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -2237,9 +2237,6 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE)) - cmd->flags &= ~CMDF_WRITE; - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, @@ -3272,9 +3269,6 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* Step 1 : check if triggers are trivially valid */ - if ((cmd->flags & CMDF_WRITE) == 0) - cmd->flags |= CMDF_WRITE; - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER | TRIG_EXT); -- GitLab From f025ab9eb73e46f761f469a2bb7c26a159b3e6c9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:29 +0000 Subject: [PATCH 2858/9457] staging: comedi: don't allow read() on async command set up for "write" If a Comedi asynchronous command has been set up for data transfer in the "write" direction on the current "read" subdevice (for those subdevices that support both directions), don't allow the "read" file operation as that would mess with the data in the comedi data buffer that is read by the low-level comedi hardware driver. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index b489d9481a69..452121b6a604 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2210,6 +2210,10 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EACCES; goto out; } + if (async->cmd.flags & CMDF_WRITE) { + retval = -EINVAL; + goto out; + } add_wait_queue(&async->wait_head, &wait); while (nbytes > 0 && !retval) { @@ -2249,6 +2253,10 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, retval = -EACCES; break; } + if (async->cmd.flags & CMDF_WRITE) { + retval = -EINVAL; + break; + } continue; } m = copy_to_user(buf, async->prealloc_buf + -- GitLab From f739850941bc300ed4dc18e22d42cbb670bf69b6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:30 +0000 Subject: [PATCH 2859/9457] staging: comedi: don't allow write() on async command set up for "read" If a Comedi asynchronous command has been set up for data transfer in the "read" direction on the current "write" subdevice (for those subdevices that support both directions), don't allow the "write" file operation as that would mess with the data in the comedi data buffer that is written by the low-level comedi hardware driver. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 452121b6a604..0ed6f1f00e7f 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2075,6 +2075,10 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -EACCES; goto out; } + if (!(async->cmd.flags & CMDF_WRITE)) { + retval = -EINVAL; + goto out; + } add_wait_queue(&async->wait_head, &wait); on_wait_queue = true; @@ -2146,6 +2150,10 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, retval = -EACCES; break; } + if (!(async->cmd.flags & CMDF_WRITE)) { + retval = -EINVAL; + break; + } continue; } -- GitLab From 662c722b645b22782eecdddf324c3a64d303baf3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:31 +0000 Subject: [PATCH 2860/9457] staging: comedi: check command direction in poll() file operation `comedi_poll()` handles the poll() file operation for comedi devices. If no asynchronous command has been set up on the current "read" subdevice, it sets the `POLLIN` and `POLLRDNORM` bits in the return value to indicate that the read() file operation would not block as it would return an error. Add a check so it also does that if the asynchronous command has been set up in the "write" direction as that also causes the read() file operation to return an error. Similarly, if no asynchronous command has need set up on the current "write" subdevice, it sets the `POLLOUT` and `POLLWRNORM` bits in the return value to indicate that the write() file operation would not block as it would return an error. Add a check so it also does that if the asynchronous command has been set up in the "read" direction as that also causes the write() file operation to return an error. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 0ed6f1f00e7f..63afd78441f1 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2017,6 +2017,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) if (s && s->async) { poll_wait(file, &s->async->wait_head, wait); if (!s->busy || !comedi_is_subdevice_running(s) || + (s->async->cmd.flags & CMDF_WRITE) || comedi_buf_read_n_available(s) > 0) mask |= POLLIN | POLLRDNORM; } @@ -2028,6 +2029,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) poll_wait(file, &s->async->wait_head, wait); comedi_buf_write_alloc(s, s->async->prealloc_bufsz); if (!s->busy || !comedi_is_subdevice_running(s) || + !(s->async->cmd.flags & CMDF_WRITE) || comedi_buf_write_n_allocated(s) >= bps) mask |= POLLOUT | POLLWRNORM; } -- GitLab From 75f6108fa91bb80e9f7e8ead81f0cedf171d00a2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 30 Oct 2014 12:42:32 +0000 Subject: [PATCH 2861/9457] staging: comedi: check actual data direction for COMEDI_BUFINFO ioctl `do_bufinfo_ioctl()` handled the `COMEDI_BUFINFO` ioctl. It is supposed to update the read or write positions in the buffer depending on the direction of data transfer set up by the asynchronous command. Currently it checks the `SDF_CMD_READ` and `SDF_CMD_WRITE` subdevice flags. That's fine for most subdevices - the ones that only support one direction, but is incorrect for those subdevices that allow the command to be set up in either direction. Since we now set the `CMDF_WRITE` flag according to the data transfer direction of the current command running on the subdevice, check that flag instead. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 63afd78441f1..704ae25c5710 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -991,7 +991,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (s->busy != file) return -EACCES; - if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) { + if (bi.bytes_read && !(async->cmd.flags & CMDF_WRITE)) { bi.bytes_read = comedi_buf_read_alloc(s, bi.bytes_read); comedi_buf_read_free(s, bi.bytes_read); @@ -1001,7 +1001,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, } } - if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) { + if (bi.bytes_written && (async->cmd.flags & CMDF_WRITE)) { bi.bytes_written = comedi_buf_write_alloc(s, bi.bytes_written); comedi_buf_write_free(s, bi.bytes_written); -- GitLab From ef49d8329e25ee1686520315713b86419cddcb45 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:19:34 -0700 Subject: [PATCH 2862/9457] staging: comedi: drivers: replace SDF_WRITEABLE with SDF_WRITABLE As indicated in the comedi.h uapi header, SDF_WRITEABLE was a spelling error in the API, SDF_WRITABLE is prefered. For aesthetics, replace all the SDF_WRITEABLE uses with SDF_WRITABLE. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1500.c | 5 ++--- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 6 +++--- drivers/staging/comedi/drivers/addi_apci_3501.c | 6 +++--- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 6 +++--- drivers/staging/comedi/drivers/addi_watchdog.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/c6xdigio.c | 2 +- drivers/staging/comedi/drivers/comedi_test.c | 2 +- drivers/staging/comedi/drivers/das6402.c | 4 ++-- drivers/staging/comedi/drivers/dt9812.c | 4 ++-- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 4 ++-- drivers/staging/comedi/drivers/ni_usb6501.c | 2 +- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 4 ++-- drivers/staging/comedi/drivers/serial2002.c | 4 ++-- drivers/staging/comedi/drivers/vmk80xx.c | 8 ++++---- 22 files changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index de8d74fc6335..d43129c9fda0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -66,8 +66,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; @@ -78,7 +77,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 55d00fd94c91..d8410415cc90 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -163,7 +163,7 @@ static int apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (this_board->do_nchan) { s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = this_board->do_nchan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index c328230b85ec..aa908a4a24cf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -403,7 +403,7 @@ static int apci1564_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; @@ -431,7 +431,7 @@ static int apci1564_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 3; s->maxdata = 0; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 4162e2dc2860..a1248dab369f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -140,7 +140,7 @@ static int apci16xx_auto_attach(struct comedi_device *dev, for (i = 0; i < n_subdevs; i++) { s = &dev->subdevices[i]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITEABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = ((i * 32) < board->n_chan) ? 32 : last; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 7a5659fafbb3..fb20c5ea90b8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -267,7 +267,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 51ab1f937bae..1f9d13661ac9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -98,7 +98,7 @@ static int apci2200_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e5dbbdf33b40..e8da15cf4e2a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -192,7 +192,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (this_board->has_ao) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; s->maxdata = 0x3fff; s->range_table = &range_bipolar10; @@ -218,7 +218,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, /* Digital Output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; @@ -227,7 +227,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, /* Timer subdevice */ s = &dev->subdevices[4]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 1; s->maxdata = 0x00ffffff; s->insn_write = apci3120_write_insn_timer; diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 010efa3fed6c..992ac8ddbe64 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -357,7 +357,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; if (ao_n_chan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = ao_n_chan; s->maxdata = 0x3fff; s->range_table = &apci3501_ao_range; @@ -383,7 +383,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, /* Initialize the digital output subdevice */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 1; s->range_table = &range_digital; @@ -392,7 +392,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, /* Initialize the timer/watchdog subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index db3ee9c429ad..630d778df2c5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -849,7 +849,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_ao) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 4; s->maxdata = 0x0fff; s->range_table = &apci3xxx_ao_range; @@ -880,7 +880,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_dig_out) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; @@ -893,7 +893,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev, if (board->has_ttl_io) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; s->maxdata = 1; s->io_bits = 0xff; /* channels 0-7 are always outputs */ diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c index 23031feaa095..0af141ab39fc 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.c +++ b/drivers/staging/comedi/drivers/addi_watchdog.c @@ -134,7 +134,7 @@ int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase) spriv->iobase = iobase; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0xff; s->insn_config = addi_watchdog_insn_config; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 1610e2b406f3..1b54716994c5 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -241,7 +241,7 @@ static int pci1723_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; dev->write_subdev = s; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 8; s->maxdata = 0xffff; s->len_chanlist = 8; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index e03dd6e71415..e7cb7032a910 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -265,7 +265,7 @@ static int c6xdigio_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 500; s->range_table = &range_unknown; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 8c348bbf9e71..1b1399bcda5c 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -423,7 +423,7 @@ static int waveform_attach(struct comedi_device *dev, dev->write_subdev = s; /* analog output subdevice (loopback) */ s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = N_CHANS; s->maxdata = 0xffff; s->range_table = &waveform_ai_ranges; diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index ab6e40608885..f3909f3f755e 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -497,7 +497,7 @@ static int das6402_attach(struct comedi_device *dev, /* Analog Output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = board->maxdata; s->range_table = &das6402_ao_ranges; @@ -520,7 +520,7 @@ static int das6402_attach(struct comedi_device *dev, /* Digital Input subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 77bb89fee327..06c601d8fdff 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -804,7 +804,7 @@ static int dt9812_auto_attach(struct comedi_device *dev, /* Digital Output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; @@ -822,7 +822,7 @@ static int dt9812_auto_attach(struct comedi_device *dev, /* Analog Output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10; diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 58a99e812818..0979f536ed39 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -689,7 +689,7 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ; s->n_chan = 32; s->len_chanlist = 32; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 728447123b4c..ae6ac49e730e 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1421,7 +1421,7 @@ static int me4000_auto_attach(struct comedi_device *dev, if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND; s->n_chan = thisboard->ao_nchan; s->maxdata = 0xFFFF; /* 16 bit DAC */ s->range_table = &range_bipolar10; diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 00eaaf8ac148..9dec9c175877 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -511,7 +511,7 @@ static int me_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (board->has_ao) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE | SDF_COMMON; s->n_chan = 4; s->maxdata = 0x0fff; s->len_chanlist = 4; @@ -528,7 +528,7 @@ static int me_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 32; s->maxdata = 1; s->len_chanlist = 32; diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c index df7ada8611f4..3b5a1b90366d 100644 --- a/drivers/staging/comedi/drivers/ni_usb6501.c +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -561,7 +561,7 @@ static int ni6501_auto_attach(struct comedi_device *dev, /* Counter subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; s->n_chan = 1; s->maxdata = 0xffffffff; s->insn_read = ni6501_cnt_insn_read; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index f6c678eef8d5..0630df367494 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -734,7 +734,7 @@ static int daqp_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &range_bipolar5; @@ -754,7 +754,7 @@ static int daqp_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 1; s->insn_bits = daqp_do_insn_bits; diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 167f82418cb4..71226ee9064e 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -742,7 +742,7 @@ static int serial2002_attach(struct comedi_device *dev, /* digital output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = &range_digital; @@ -760,7 +760,7 @@ static int serial2002_attach(struct comedi_device *dev, /* analog output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 0; s->maxdata = 1; s->range_table = NULL; diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 71003416edcf..a19a56ee0eef 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -797,7 +797,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) /* Analog output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = boardinfo->ao_nchans; s->maxdata = 0x00ff; s->range_table = boardinfo->range; @@ -819,7 +819,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) /* Digital output subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; @@ -834,7 +834,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) s->insn_read = vmk80xx_cnt_insn_read; s->insn_config = vmk80xx_cnt_insn_config; if (devpriv->model == VMK8055_MODEL) { - s->subdev_flags |= SDF_WRITEABLE; + s->subdev_flags |= SDF_WRITABLE; s->insn_write = vmk80xx_cnt_insn_write; } @@ -842,7 +842,7 @@ static int vmk80xx_init_subdevices(struct comedi_device *dev) if (devpriv->model == VMK8061_MODEL) { s = &dev->subdevices[5]; s->type = COMEDI_SUBD_PWM; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = boardinfo->pwm_nchans; s->maxdata = boardinfo->pwm_maxdata; s->insn_read = vmk80xx_pwm_insn_read; -- GitLab From e00259182063cccbcee85315d978b8b93d5298e3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:19:35 -0700 Subject: [PATCH 2863/9457] staging: comedi: drivers: remove inappropriate SDF_* flags from subdevices The SDF_GROUND, SDF_COMMON, SDF_DIFF, and SDF_OTHER flags are only useful with the analog input and output subdevices. Remove these flags from the other subdevice types in the comedi drivers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1500.c | 6 +++--- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 8 ++++---- drivers/staging/comedi/drivers/dyna_pci10xx.c | 4 ++-- drivers/staging/comedi/drivers/icp_multi.c | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index d43129c9fda0..30b132c3d092 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -54,7 +54,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; @@ -66,7 +66,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; @@ -77,7 +77,7 @@ static int apci1500_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 992ac8ddbe64..79245236be78 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -392,7 +392,7 @@ static int apci3501_auto_attach(struct comedi_device *dev, /* Initialize the timer/watchdog subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index c5422f376927..e05f4b5444e1 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1210,7 +1210,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_dichan) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = this_board->n_dichan; s->maxdata = 1; s->len_chanlist = this_board->n_dichan; @@ -1222,7 +1222,7 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_dochan) { s = &dev->subdevices[subdev]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = this_board->n_dochan; s->maxdata = 1; s->len_chanlist = this_board->n_dochan; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index f2e2d7e163bf..09609d6d02da 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -930,7 +930,7 @@ static int pci1760_attach(struct comedi_device *dev) s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; @@ -939,7 +939,7 @@ static int pci1760_attach(struct comedi_device *dev) s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; @@ -978,7 +978,7 @@ static int pci_dio_add_di(struct comedi_device *dev, const struct dio_boardtype *this_board = dev->board_ptr; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags; + s->subdev_flags = SDF_READABLE | d->specflags; if (d->chans > 16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; @@ -1008,7 +1008,7 @@ static int pci_dio_add_do(struct comedi_device *dev, const struct dio_boardtype *this_board = dev->board_ptr; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; if (d->chans > 16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 608aee0c3a15..1b6324c6eb29 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -218,7 +218,7 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, /* digital input */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; @@ -228,7 +228,7 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev, /* digital output */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index f4e1c1cf4178..f9aa6a59c9a8 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -521,7 +521,7 @@ static int icp_multi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[4]; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 0xffff; s->len_chanlist = 4; -- GitLab From 453fd2b395799fa2e83e3e926ff7fee810d26f92 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:19:36 -0700 Subject: [PATCH 2864/9457] staging: comedi: drivers: digital output subdevices do not need SDF_READABLE The SDF_READABLE flag is not necessary for digital output subdevices. For consistency, remove this flag from the comedi drivers that set it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/amplc_pci263.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/das1800.c | 2 +- drivers/staging/comedi/drivers/das800.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 18f5f7fc1bc8..1fd082bf757d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -767,7 +767,7 @@ static int pci9111_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index f8e551d8fd9e..b1946ce6ecc1 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -83,7 +83,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index 2259bee98d48..0d2224b832ac 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -71,7 +71,7 @@ static int pci263_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 9196680581b8..c8515d7f249b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3868,7 +3868,7 @@ static int setup_subdevices(struct comedi_device *dev) if (thisboard->layout == LAYOUT_64XX) { s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index bdb671a66e22..cdf71f9f199c 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -507,7 +507,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* do */ if (thisboard->do_nchan) { s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->do_nchan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 54ccffca8497..80f41b7e8273 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -597,7 +597,7 @@ static int das16m1_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* do */ s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 246a18648223..bf8bfcf7034d 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1513,7 +1513,7 @@ static int das1800_attach(struct comedi_device *dev, /* do */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->do_n_chan; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 6013099891c0..55bc494838b5 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -737,7 +737,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Digital Output subdevice */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index f9aa6a59c9a8..a412394bcdc9 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -512,7 +512,7 @@ static int icp_multi_auto_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; -- GitLab From a7d3de75cf00574f8d360d51d0e1beb3c561cc89 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:21:54 -0700 Subject: [PATCH 2865/9457] staging: comedi: drivers do not need to reset the async->cur_chan The comedi core calls comedi_buf_reset() before starting an async command (*do_cmd) and after returning a subdevice to an idle state (*cancel). The drivers do not need to reset the async->cur_chan in those functions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 -- drivers/staging/comedi/drivers/adl_pci9118.c | 2 -- drivers/staging/comedi/drivers/adv_pci1710.c | 2 -- drivers/staging/comedi/drivers/ni_atmio16d.c | 1 - drivers/staging/comedi/drivers/pcl812.c | 1 - drivers/staging/comedi/drivers/pcl816.c | 1 - drivers/staging/comedi/drivers/usbdux.c | 6 ------ drivers/staging/comedi/drivers/usbduxfast.c | 2 -- drivers/staging/comedi/drivers/usbduxsigma.c | 5 ----- 9 files changed, 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 975ee5fc93dc..6b65ce69c213 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -629,7 +629,6 @@ static int apci3120_cancel(struct comedi_device *dev, inb(dev->iobase + APCI3120_RESET_FIFO); inw(dev->iobase + APCI3120_RD_STATUS); devpriv->ui_AiActualScan = 0; - s->async->cur_chan = 0; devpriv->ui_DmaActualBuffer = 0; devpriv->ai_running = 0; @@ -758,7 +757,6 @@ static int apci3120_cyclic_ai(int mode, /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ devpriv->ui_AiActualScan = 0; - s->async->cur_chan = 0; devpriv->ui_DmaActualBuffer = 0; /* value for timer2 minus -2 has to be done */ diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index cb2c48522efd..83c381357c14 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -575,7 +575,6 @@ static int pci9118_ai_cancel(struct comedi_device *dev, devpriv->ai_act_scan = 0; devpriv->ai_act_dmapos = 0; - s->async->cur_chan = 0; s->async->inttrig = NULL; devpriv->ai_neverending = 0; devpriv->dma_actbuf = 0; @@ -1120,7 +1119,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_act_scan = 0; devpriv->ai_act_dmapos = 0; - s->async->cur_chan = 0; if (devpriv->usedma) { Compute_and_setup_dma(dev, s); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index e05f4b5444e1..075df1ccb853 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -731,7 +731,6 @@ static int pci171x_ai_cancel(struct comedi_device *dev, } devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; return 0; } @@ -931,7 +930,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(0, dev->iobase + PCI171x_CLRINT); devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; devpriv->CntrlReg &= Control_CNT0; if ((cmd->flags & CMDF_WAKE_EOS) == 0) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 2bac69339202..d0ac49eaab06 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -300,7 +300,6 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, * It is still uber-experimental */ reset_counters(dev); - s->async->cur_chan = 0; /* check if scanning multiple channels */ if (cmd->chanlist_len < 2) { diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index eef646253bf9..10886070f48c 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -809,7 +809,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_act_scan = 0; devpriv->ai_poll_ptr = 0; - s->async->cur_chan = 0; /* don't we want wake up every scan? */ if (cmd->flags & CMDF_WAKE_EOS) { diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index a471c3df12b4..053eed047490 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -509,7 +509,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) udelay(1); devpriv->ai_act_scan = 0; - s->async->cur_chan = 0; devpriv->ai_cmd_running = 1; devpriv->ai_poll_ptr = 0; devpriv->ai_cmd_canceled = 0; diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 579e6bce529d..40f5cd03651d 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -698,9 +698,6 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ai_cmd_running) goto ai_cmd_exit; - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - devpriv->dux_commands[1] = len; for (i = 0; i < len; ++i) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); @@ -996,9 +993,6 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ao_cmd_running) goto ao_cmd_exit; - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - /* we count in steps of 1ms (125us) */ /* 125us mode not used yet */ if (0) { /* (devpriv->high_speed) */ diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 70ec2f552dfc..3bc9013006a0 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -479,8 +479,6 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, up(&devpriv->sem); return -EBUSY; } - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; /* * ignore the first buffers from the device if there diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 7b7698c3ccd2..9ee6e0a78578 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -689,8 +689,6 @@ static int usbduxsigma_ai_cmd(struct comedi_device *dev, down(&devpriv->sem); - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; for (i = 0; i < len; i++) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); @@ -988,9 +986,6 @@ static int usbduxsigma_ao_cmd(struct comedi_device *dev, down(&devpriv->sem); - /* set current channel of the running acquisition to zero */ - s->async->cur_chan = 0; - devpriv->ao_counter = devpriv->ao_timer; if (cmd->start_src == TRIG_NOW) { -- GitLab From 0c8c1c0ad8edce6c0d0a7d78b5ab6cb2ee4722f1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:32:28 -0700 Subject: [PATCH 2866/9457] staging: comedi: rtd520: fix ai_read_n() async->cur_chan use This functions uses the async->cur_chan to determine if the current channel is using a bipolar range and the sample needs to be munged. The cur_chan is never incremented so all the samples are munged based on the fist channel in the cmd->chanlist. Bump the cur_chan after writing each sample. This fixes the code so that the munging will be done correctly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 888238e26073..8e87655be7bb 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -606,6 +606,8 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count) { struct rtd_private *devpriv = dev->private; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; int ii; for (ii = 0; ii < count; ii++) { @@ -618,7 +620,7 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar)) + if (test_bit(async->cur_chan, devpriv->chan_is_bipolar)) /* convert to comedi unsigned data */ d = comedi_offset_munge(s, d); d &= s->maxdata; @@ -626,6 +628,9 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, if (!comedi_buf_write_samples(s, &d, 1)) return -1; + async->cur_chan++; + async->cur_chan %= cmd->chanlist_len; + if (devpriv->ai_count > 0) /* < 0, means read forever */ devpriv->ai_count--; } -- GitLab From c234566f776464594f6b73022497d4f5efd83e46 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 30 Oct 2014 11:32:29 -0700 Subject: [PATCH 2867/9457] staging: comedi: rtd520: remove private data 'chan_is_bipolar' member Currently this driver uses a bitmap in the private data to keep track of the unipolar/bipolar range for each channel. This is needed to determine if the data needs to be munged for bipolar samples. Remove this member from the private data and use the comedi core helper function comedi_range_is_bipolar() to determine if the data needs to be munged. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 8e87655be7bb..19596756864d 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -379,7 +379,6 @@ struct rtd_private { long ai_count; /* total transfer size (samples) */ int xfer_count; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ - DECLARE_BITMAP(chan_is_bipolar, RTD_MAX_CHANLIST); unsigned fifosz; }; @@ -438,7 +437,6 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, unsigned int chanspec, int index) { const struct rtd_boardinfo *board = dev->board_ptr; - struct rtd_private *devpriv = dev->private; unsigned int chan = CR_CHAN(chanspec); unsigned int range = CR_RANGE(chanspec); unsigned int aref = CR_AREF(chanspec); @@ -451,17 +449,14 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, /* +-5 range */ r |= 0x000; r |= (range & 0x7) << 4; - __set_bit(index, devpriv->chan_is_bipolar); } else if (range < board->range_uni10) { /* +-10 range */ r |= 0x100; r |= ((range - board->range_bip10) & 0x7) << 4; - __set_bit(index, devpriv->chan_is_bipolar); } else { /* +10 range */ r |= 0x200; r |= ((range - board->range_uni10) & 0x7) << 4; - __clear_bit(index, devpriv->chan_is_bipolar); } switch (aref) { @@ -561,6 +556,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev, unsigned int *data) { struct rtd_private *devpriv = dev->private; + unsigned int range = CR_RANGE(insn->chanspec); int ret; int n; @@ -586,9 +582,11 @@ static int rtd_ai_rinsn(struct comedi_device *dev, /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(0, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ + + /* convert bipolar data to comedi unsigned data */ + if (comedi_range_is_bipolar(s, range)) d = comedi_offset_munge(s, d); + data[n] = d & s->maxdata; } @@ -611,6 +609,7 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int ii; for (ii = 0; ii < count; ii++) { + unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]); unsigned short d; if (0 == devpriv->ai_count) { /* done */ @@ -620,8 +619,9 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ - if (test_bit(async->cur_chan, devpriv->chan_is_bipolar)) - /* convert to comedi unsigned data */ + + /* convert bipolar data to comedi unsigned data */ + if (comedi_range_is_bipolar(s, range)) d = comedi_offset_munge(s, d); d &= s->maxdata; -- GitLab From cf5d2af6839deb2e7765648ce139dc9677db0c18 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 14:32:27 +0000 Subject: [PATCH 2868/9457] staging: comedi: icp_multi: correct insn_bits returned data for DO For some unfathomable reason, the Comedi `insn_bits` handler for the digital output subdevice (`icp_multi_insn_bits_do()`) writes the digital output register and reads back the unrelated digital input register. Read back the current state of the outputs (held in `s->state`) instead. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/icp_multi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index a412394bcdc9..fbbcab20a48b 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -53,7 +53,7 @@ Configuration options: not applicable, uses PCI auto config #define ICP_MULTI_AI 2 /* R: Analogue input data */ #define ICP_MULTI_DAC_CSR 4 /* R/W: DAC command/status register */ #define ICP_MULTI_AO 6 /* R/W: Analogue output data */ -#define ICP_MULTI_DI 8 /* R/W: Digital inouts */ +#define ICP_MULTI_DI 8 /* R/W: Digital inputs */ #define ICP_MULTI_DO 0x0A /* R/W: Digital outputs */ #define ICP_MULTI_INT_EN 0x0C /* R/W: Interrupt enable register */ #define ICP_MULTI_INT_STAT 0x0E /* R/W: Interrupt status register */ @@ -319,7 +319,7 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, if (comedi_dio_update_state(s, data)) writew(s->state, dev->mmio + ICP_MULTI_DO); - data[1] = readw(dev->mmio + ICP_MULTI_DI); + data[1] = s->state; return insn->n; } -- GitLab From c1b617e017f858505ce639a8dee4d096fbcb7b6b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 09:49:30 -0700 Subject: [PATCH 2869/9457] staging: comedi: ni_mio_common: remove unused variable in ni_ao_fifo_load() The local variable 'range' is set but never used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index fd61d24bc3a4..32236ef587f5 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1131,14 +1131,11 @@ static void ni_ao_fifo_load(struct comedi_device *dev, int i; unsigned short d; u32 packed_data; - int range; chan = async->cur_chan; for (i = 0; i < n; i++) { comedi_buf_read_samples(s, &d, 1); - range = CR_RANGE(cmd->chanlist[chan]); - if (devpriv->is_6xxx) { packed_data = d & 0xffff; /* 6711 only has 16 bit wide ao fifo */ -- GitLab From f8736ca466e2014d6e8bad478fcc5e5cb0105af0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 09:49:31 -0700 Subject: [PATCH 2870/9457] staging: comedi: drivers: move comedi_async 'cur_chan' tracking into the core The commedi_async 'cur_chan' member is used to track the current position in the chanlist for a scan. Currently only a couple comedi drivers use this member. For aeshtetics, move the 'cur_chan' tracking into the core for non-SDF_PACKED subdevices. The 'cur_chan' will be updated after reading or writing samples to the async buffer by comedi_inc_scan_progress(). All non-SDF_PACKED subdevices will then automatiaclly track the 'cur_chan'. Some of the drivers use the 'cur_chan' to detect the end of scan event when counting scans. The COMEDI_CB_EOS event is automatically added by the core when the end of scan is detected. The drivers just need to check if the 'cur_chan' is 0 to count the number of scans completed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 7 +++++++ .../comedi/drivers/addi-data/hwdrv_apci3120.c | 2 -- drivers/staging/comedi/drivers/adl_pci9118.c | 8 ++------ drivers/staging/comedi/drivers/adv_pci1710.c | 11 +---------- drivers/staging/comedi/drivers/ni_mio_common.c | 8 -------- drivers/staging/comedi/drivers/pcl812.c | 13 ++++--------- drivers/staging/comedi/drivers/pcl816.c | 6 +----- drivers/staging/comedi/drivers/pcl818.c | 6 +----- drivers/staging/comedi/drivers/rtd520.c | 3 --- 9 files changed, 16 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index ff2df8587eca..9c55dc759af8 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -341,8 +341,15 @@ void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes) { struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; unsigned int scan_length = comedi_bytes_per_scan(s); + /* track the 'cur_chan' for non-SDF_PACKED subdevices */ + if (!(s->subdev_flags & SDF_PACKED)) { + async->cur_chan += comedi_bytes_to_samples(s, num_bytes); + async->cur_chan %= cmd->chanlist_len; + } + async->scan_progress += num_bytes; if (async->scan_progress >= scan_length) { async->scan_progress %= scan_length; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 6b65ce69c213..facd2c4b922d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1167,8 +1167,6 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, devpriv->ui_AiActualScan += (s->async->cur_chan + num_samples) / cmd->scan_end_arg; - s->async->cur_chan += num_samples; - s->async->cur_chan %= cmd->scan_end_arg; comedi_buf_write_samples(s, dma_buffer, num_samples); } diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 83c381357c14..93b41e6712a6 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -483,8 +483,6 @@ static void move_block_from_dma(struct comedi_device *dev, num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples); devpriv->ai_act_scan += (s->async->cur_chan + num_samples) / cmd->scan_end_arg; - s->async->cur_chan += num_samples; - s->async->cur_chan %= cmd->scan_end_arg; comedi_buf_write_samples(s, dma_buffer, num_samples); } @@ -612,10 +610,8 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG); comedi_buf_write_samples(s, &sampl, 1); - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->scan_end_arg) { - /* one scan done */ - s->async->cur_chan %= cmd->scan_end_arg; + + if (s->async->cur_chan == 0) { devpriv->ai_act_scan++; if (!devpriv->ai_neverending) { /* all data sampled? */ diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 075df1ccb853..420554f79b02 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -772,11 +772,6 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, val &= s->maxdata; comedi_buf_write_samples(s, &val, 1); - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) - s->async->cur_chan = 0; - - if (s->async->cur_chan == 0) { /* one scan done */ devpriv->ai_act_scan++; if (cmd->stop_src == TRIG_COUNT && @@ -800,7 +795,6 @@ static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevice *s, int n, int turn) { struct pci1710_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; unsigned int val; int ret; int i; @@ -817,11 +811,8 @@ static int move_block_from_fifo(struct comedi_device *dev, val &= s->maxdata; comedi_buf_write_samples(s, &val, 1); - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; + if (s->async->cur_chan == 0) devpriv->ai_act_scan++; - } } return 0; } diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 32236ef587f5..2dfd95126fa3 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1125,14 +1125,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev, struct comedi_subdevice *s, int n) { struct ni_private *devpriv = dev->private; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - int chan; int i; unsigned short d; u32 packed_data; - chan = async->cur_chan; for (i = 0; i < n; i++) { comedi_buf_read_samples(s, &d, 1); @@ -1141,7 +1137,6 @@ static void ni_ao_fifo_load(struct comedi_device *dev, /* 6711 only has 16 bit wide ao fifo */ if (!devpriv->is_6711) { comedi_buf_read_samples(s, &d, 1); - chan++; i++; packed_data |= (d << 16) & 0xffff0000; } @@ -1149,10 +1144,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev, } else { ni_writew(dev, d, DAC_FIFO_Data); } - chan++; - chan %= cmd->chanlist_len; } - async->cur_chan = chan; } /* diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 10886070f48c..b13e9fb7a12e 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -843,12 +843,8 @@ static bool pcl812_ai_next_chan(struct comedi_device *dev, struct pcl812_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; + if (s->async->cur_chan == 0) devpriv->ai_act_scan++; - s->async->events |= COMEDI_CB_EOS; - } if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan >= cmd->stop_arg) { @@ -864,6 +860,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan = s->async->cur_chan; unsigned int next_chan; unsigned short val; @@ -877,10 +874,8 @@ static void pcl812_handle_eoc(struct comedi_device *dev, comedi_buf_write_samples(s, &val, 1); /* Set up next channel. Added by abbotti 2010-01-20, but untested. */ - next_chan = s->async->cur_chan + 1; - if (next_chan >= cmd->chanlist_len) - next_chan = 0; - if (cmd->chanlist[s->async->cur_chan] != cmd->chanlist[next_chan]) + next_chan = s->async->cur_chan; + if (cmd->chanlist[chan] != cmd->chanlist[next_chan]) pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0); pcl812_ai_next_chan(dev, s); diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 053eed047490..7cdb79826213 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -289,12 +289,8 @@ static bool pcl816_ai_next_chan(struct comedi_device *dev, struct pcl816_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; + if (s->async->cur_chan == 0) devpriv->ai_act_scan++; - s->async->events |= COMEDI_CB_EOS; - } if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan >= cmd->stop_arg) { diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index e6d897bf5714..dc2715ae6b18 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -525,12 +525,8 @@ static bool pcl818_ai_next_chan(struct comedi_device *dev, if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) devpriv->act_chanlist_pos = 0; - s->async->cur_chan++; - if (s->async->cur_chan >= cmd->chanlist_len) { - s->async->cur_chan = 0; + if (s->async->cur_chan == 0) devpriv->ai_act_scan--; - s->async->events |= COMEDI_CB_EOS; - } if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) { /* all data sampled */ diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 19596756864d..fb71fd60bc4e 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -628,9 +628,6 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, if (!comedi_buf_write_samples(s, &d, 1)) return -1; - async->cur_chan++; - async->cur_chan %= cmd->chanlist_len; - if (devpriv->ai_count > 0) /* < 0, means read forever */ devpriv->ai_count--; } -- GitLab From 272fe8f51fd8b8cd1637c8d2ca868cbff725405e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 09:49:32 -0700 Subject: [PATCH 2871/9457] staging: comedi: amplc_pci230: remove private data 'ai_scan_pos' This member of the private data is replicating what the comedi_async 'cur_chan' member is used for. Use that instead and remove the private data member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 44c967f43d9a..a46fffd28a3e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -491,7 +491,6 @@ struct pci230_private { spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ unsigned long daqio; /* PCI230's DAQ I/O space */ unsigned int ai_scan_count; /* Number of AI scans remaining */ - unsigned int ai_scan_pos; /* Current position within AI scan */ unsigned int ao_scan_count; /* Number of AO scans remaining. */ int intr_cpuid; /* ID of CPU running ISR */ unsigned short hwver; /* Hardware version (for '+' models) */ @@ -1748,13 +1747,13 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, unsigned short adccon; if (cmd->flags & CMDF_WAKE_EOS) - wake = scanlen - devpriv->ai_scan_pos; + wake = scanlen - s->async->cur_chan; else if (cmd->stop_src != TRIG_COUNT || devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL || scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) wake = PCI230_ADC_FIFOLEVEL_HALFFULL; else - wake = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; + wake = devpriv->ai_scan_count * scanlen - s->async->cur_chan; if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) { triglev = PCI230_ADC_INT_FIFO_HALF; } else if (wake > 1 && devpriv->hwver > 0) { @@ -2064,7 +2063,7 @@ static void pci230_handle_ai(struct comedi_device *dev, scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL) { todo = PCI230_ADC_FIFOLEVEL_HALFFULL; } else { - todo = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; + todo = devpriv->ai_scan_count * scanlen - async->cur_chan; if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) todo = PCI230_ADC_FIFOLEVEL_HALFFULL; } @@ -2105,13 +2104,8 @@ static void pci230_handle_ai(struct comedi_device *dev, comedi_buf_write_samples(s, &val, 1); fifoamount--; - devpriv->ai_scan_pos++; - if (devpriv->ai_scan_pos == scanlen) { - /* End of scan. */ - devpriv->ai_scan_pos = 0; + if (async->cur_chan == 0) devpriv->ai_scan_count--; - async->events |= COMEDI_CB_EOS; - } } if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) { /* End of acquisition. */ @@ -2158,7 +2152,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; devpriv->ai_scan_count = cmd->stop_arg; - devpriv->ai_scan_pos = 0; /* Position within scan. */ /* * Steps: -- GitLab From c39e050d21d107d26183be0f22b89eccccdbe61c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:28 -0700 Subject: [PATCH 2872/9457] staging: comedi: remove use of 'bytes_per_sample()' This inline helper function has been replaced with comedi_bytes_per_sample(). The same commit (bf33eb4b4f57) introduced a couple other related helper functions a manipulate the sample size. Use the new helper functions to remove the use of 'bytes_per_sample()' and remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 14 +++++++++----- drivers/staging/comedi/comedi_fops.c | 2 +- drivers/staging/comedi/comedidev.h | 6 ------ drivers/staging/comedi/drivers.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 +++--- drivers/staging/comedi/drivers/das16.c | 2 +- drivers/staging/comedi/drivers/dt282x.c | 4 ++-- drivers/staging/comedi/drivers/ni_mio_common.c | 8 ++++---- drivers/staging/comedi/drivers/usbduxfast.c | 4 ++-- 10 files changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index b43424d611ad..eb3fecf85b6d 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -283,7 +283,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, { struct comedi_async *async = s->async; unsigned int count = 0; - const unsigned num_sample_bytes = bytes_per_sample(s); + const unsigned num_sample_bytes = comedi_bytes_per_sample(s); if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { async->munge_count += num_bytes; @@ -489,7 +489,8 @@ unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, * If not, clamp the nsamples to the number that will fit, flag the * buffer overrun and add the samples that fit. */ - max_samples = comedi_buf_write_n_available(s) / bytes_per_sample(s); + max_samples = comedi_bytes_to_samples(s, + comedi_buf_write_n_available(s)); if (nsamples > max_samples) { dev_warn(s->device->class_dev, "buffer overrun\n"); s->async->events |= COMEDI_CB_OVERFLOW; @@ -499,7 +500,8 @@ unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, if (nsamples == 0) return 0; - nbytes = comedi_buf_write_alloc(s, nsamples * bytes_per_sample(s)); + nbytes = comedi_buf_write_alloc(s, + comedi_samples_to_bytes(s, nsamples)); comedi_buf_memcpy_to(s, data, nbytes); comedi_buf_write_free(s, nbytes); comedi_inc_scan_progress(s, nbytes); @@ -527,14 +529,16 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, unsigned int nbytes; /* clamp nsamples to the number of full samples available */ - max_samples = comedi_buf_read_n_available(s) / bytes_per_sample(s); + max_samples = comedi_bytes_to_samples(s, + comedi_buf_read_n_available(s)); if (nsamples > max_samples) nsamples = max_samples; if (nsamples == 0) return 0; - nbytes = comedi_buf_read_alloc(s, nsamples * bytes_per_sample(s)); + nbytes = comedi_buf_read_alloc(s, + comedi_samples_to_bytes(s, nsamples)); comedi_buf_memcpy_from(s, data, nbytes); comedi_buf_read_free(s, nbytes); comedi_inc_scan_progress(s, nbytes); diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 704ae25c5710..65894fd8b67b 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2024,7 +2024,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) s = comedi_write_subdevice(dev, minor); if (s && s->async) { - unsigned int bps = bytes_per_sample(s); + unsigned int bps = comedi_bytes_per_sample(s); poll_wait(file, &s->async->wait_head, wait); comedi_buf_write_alloc(s, s->async->prealloc_bufsz); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index d18f70203422..90af11aaef7e 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -427,12 +427,6 @@ static inline unsigned int comedi_bytes_per_sample(struct comedi_subdevice *s) return s->subdev_flags & SDF_LSAMPL ? sizeof(int) : sizeof(short); } -/* to be removed */ -static inline unsigned int bytes_per_sample(struct comedi_subdevice *s) -{ - return comedi_bytes_per_sample(s); -} - /** * comedi_sample_shift - determine log2 of subdevice sample size * @s: comedi_subdevice struct diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 9c55dc759af8..9a8c5fc8e8fe 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -316,14 +316,14 @@ unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s) case COMEDI_SUBD_DI: case COMEDI_SUBD_DO: case COMEDI_SUBD_DIO: - bits_per_sample = 8 * bytes_per_sample(s); + bits_per_sample = 8 * comedi_bytes_per_sample(s); num_samples = DIV_ROUND_UP(cmd->chanlist_len, bits_per_sample); break; default: num_samples = cmd->chanlist_len; break; } - return num_samples * bytes_per_sample(s); + return comedi_samples_to_bytes(s, num_samples); } EXPORT_SYMBOL_GPL(comedi_bytes_per_scan); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 53afae093c4c..1c38cd5f846c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1146,7 +1146,7 @@ static void cb_pcidas_ao_load_fifo(struct comedi_device *dev, nsamples = devpriv->ao_count; nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples); - nsamples = nbytes / bytes_per_sample(s); + nsamples = comedi_bytes_to_samples(s, nbytes); if (cmd->stop_src == TRIG_COUNT) devpriv->ao_count -= nsamples; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index c8515d7f249b..d7b61ba6b284 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2923,14 +2923,14 @@ static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int nsamples = max_bytes / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, max_bytes); unsigned int actual_bytes; if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples) nsamples = devpriv->ao_count; actual_bytes = comedi_buf_read_samples(s, dest, nsamples); - nsamples = actual_bytes / bytes_per_sample(s); + nsamples = comedi_bytes_to_samples(s, actual_bytes); if (cmd->stop_src == TRIG_COUNT) devpriv->ao_count -= nsamples; @@ -2954,7 +2954,7 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, if (nsamples == 0) return 0; - nbytes = nsamples * bytes_per_sample(s); + nbytes = comedi_samples_to_bytes(s, nsamples); devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes); /* set end of chain bit so we catch underruns */ next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 8e512b241653..26f54aa9d41c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -584,7 +584,7 @@ static void das16_interrupt(struct comedi_device *dev) spin_unlock_irqrestore(&dev->spinlock, spin_flags); - nsamples = num_bytes / bytes_per_sample(s); + nsamples = comedi_bytes_to_samples(s, num_bytes); comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index], nsamples); diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 1d9fa371d03c..674e03eb1601 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -455,7 +455,7 @@ static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev, { struct dt282x_private *devpriv = dev->private; void *ptr = devpriv->dma[cur_dma].buf; - unsigned int nsamples = devpriv->dma_maxsize / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, devpriv->dma_maxsize); unsigned int nbytes; nbytes = comedi_buf_read_samples(s, ptr, nsamples); @@ -491,7 +491,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev, int cur_dma = devpriv->current_dma_index; void *ptr = devpriv->dma[cur_dma].buf; int size = devpriv->dma[cur_dma].size; - unsigned int nsamples = size / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, size); int ret; outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE, diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 2dfd95126fa3..63312ff42b35 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1618,12 +1618,12 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int length = num_bytes / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes); unsigned short *array = data; unsigned int *larray = data; unsigned int i; - for (i = 0; i < length; i++) { + for (i = 0; i < nsamples; i++) { #ifdef PCIDMA if (s->subdev_flags & SDF_LSAMPL) larray[i] = le32_to_cpu(larray[i]); @@ -2732,11 +2732,11 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int chan_index) { struct comedi_cmd *cmd = &s->async->cmd; - unsigned int length = num_bytes / bytes_per_sample(s); + unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes); unsigned short *array = data; unsigned int i; - for (i = 0; i < length; i++) { + for (i = 0; i < nsamples; i++) { unsigned int range = CR_RANGE(cmd->chanlist[chan_index]); unsigned short val = array[i]; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 3bc9013006a0..5de76aba8fd9 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -248,9 +248,9 @@ static void usbduxfast_ai_handle_urb(struct comedi_device *dev, if (devpriv->ignore) { devpriv->ignore--; } else { - unsigned int nbytes = urb->actual_length; - unsigned int nsamples = nbytes / bytes_per_sample(s); + unsigned int nsamples; + nsamples = comedi_bytes_to_samples(s, urb->actual_length); if (cmd->stop_src == TRIG_COUNT) { if (devpriv->ai_sample_count < nsamples) { nsamples = devpriv->ai_sample_count; -- GitLab From 836b571df7bc0bd921c503d467fd6b6d002457ec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:29 -0700 Subject: [PATCH 2873/9457] staging: comedi: ni_mio_common: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/ni_mio_common.c | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 63312ff42b35..97869ce463b7 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1167,19 +1167,20 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, struct comedi_subdevice *s) { const struct ni_board_struct *board = dev->board_ptr; - int n; + unsigned int nbytes; + unsigned int nsamples; - n = comedi_buf_read_n_available(s); - if (n == 0) { + nbytes = comedi_buf_read_n_available(s); + if (nbytes == 0) { s->async->events |= COMEDI_CB_OVERFLOW; return 0; } - n /= sizeof(short); - if (n > board->ao_fifo_depth / 2) - n = board->ao_fifo_depth / 2; + nsamples = comedi_bytes_to_samples(s, nbytes); + if (nsamples > board->ao_fifo_depth / 2) + nsamples = board->ao_fifo_depth / 2; - ni_ao_fifo_load(dev, s, n); + ni_ao_fifo_load(dev, s, nsamples); return 1; } @@ -1189,7 +1190,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, { const struct ni_board_struct *board = dev->board_ptr; struct ni_private *devpriv = dev->private; - int n; + unsigned int nbytes; + unsigned int nsamples; /* reset fifo */ ni_stc_writew(dev, 1, DAC_FIFO_Clear); @@ -1197,17 +1199,17 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x); /* load some data */ - n = comedi_buf_read_n_available(s); - if (n == 0) + nbytes = comedi_buf_read_n_available(s); + if (nbytes == 0) return 0; - n /= sizeof(short); - if (n > board->ao_fifo_depth) - n = board->ao_fifo_depth; + nsamples = comedi_bytes_to_samples(s, nbytes); + if (nsamples > board->ao_fifo_depth) + nsamples = board->ao_fifo_depth; - ni_ao_fifo_load(dev, s, n); + ni_ao_fifo_load(dev, s, nsamples); - return n; + return nsamples; } static void ni_ai_fifo_read(struct comedi_device *dev, @@ -2951,12 +2953,15 @@ static int ni_ao_insn_config(struct comedi_device *dev, { const struct ni_board_struct *board = dev->board_ptr; struct ni_private *devpriv = dev->private; + unsigned int nbytes; switch (data[0]) { case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE: switch (data[1]) { case COMEDI_OUTPUT: - data[2] = 1 + board->ao_fifo_depth * sizeof(short); + nbytes = comedi_samples_to_bytes(s, + board->ao_fifo_depth); + data[2] = 1 + nbytes; if (devpriv->mite) data[2] += devpriv->mite->fifo_size; break; -- GitLab From 5035a96f3640ee4705f69287726bfcc598212717 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:30 -0700 Subject: [PATCH 2874/9457] staging: comedi: das1800: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index bf8bfcf7034d..03b1ff9de92c 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -535,7 +535,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, /* figure out how many points to read */ num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); - num_samples = num_bytes / sizeof(short); + num_samples = comedi_bytes_to_samples(s, num_bytes); /* if we only need some of the points */ if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) -- GitLab From bd508fffda8fc3dbcabab9bc31817c588f7938c2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:31 -0700 Subject: [PATCH 2875/9457] staging: comedi: das16: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 26f54aa9d41c..8de27053666f 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -863,8 +863,9 @@ static void das16_ai_munge(struct comedi_device *dev, unsigned int num_bytes, unsigned int start_chan_index) { - unsigned int i, num_samples = num_bytes / sizeof(short); unsigned short *data = array; + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); + unsigned int i; for (i = 0; i < num_samples; i++) { data[i] = le16_to_cpu(data[i]); -- GitLab From b7f9eb054994dbbceb40d376ad6f5701d9d31b4d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:32 -0700 Subject: [PATCH 2876/9457] staging: comedi: adv_pci1710: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 420554f79b02..107a0f137eaf 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -823,7 +823,8 @@ static void pci1710_handle_fifo(struct comedi_device *dev, const struct boardtype *this_board = dev->board_ptr; struct pci1710_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - int m, samplesinbuf; + unsigned int nsamples; + unsigned int m; m = inw(dev->iobase + PCI171x_STATUS); if (!(m & Status_FH)) { @@ -840,16 +841,16 @@ static void pci1710_handle_fifo(struct comedi_device *dev, return; } - samplesinbuf = this_board->fifo_half_size; - if (samplesinbuf * sizeof(short) >= s->async->prealloc_bufsz) { - m = s->async->prealloc_bufsz / sizeof(short); + nsamples = this_board->fifo_half_size; + if (comedi_samples_to_bytes(s, nsamples) >= s->async->prealloc_bufsz) { + m = comedi_bytes_to_samples(s, s->async->prealloc_bufsz); if (move_block_from_fifo(dev, s, m, 0)) return; - samplesinbuf -= m; + nsamples -= m; } - if (samplesinbuf) { - if (move_block_from_fifo(dev, s, samplesinbuf, 1)) + if (nsamples) { + if (move_block_from_fifo(dev, s, nsamples, 1)) return; } -- GitLab From 1d3d32a7525bbc9c989f8c3e592dc206ee8b145a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:33 -0700 Subject: [PATCH 2877/9457] staging: comedi: adl_pci9118: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 93b41e6712a6..2aef881b6ee4 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -586,8 +586,9 @@ static void pci9118_ai_munge(struct comedi_device *dev, unsigned int start_chan_index) { struct pci9118_private *devpriv = dev->private; - unsigned int i, num_samples = num_bytes / sizeof(short); unsigned short *array = data; + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); + unsigned int i; for (i = 0; i < num_samples; i++) { if (devpriv->usedma) -- GitLab From 287a143ab42b8d2aa3421e70192895188a23dd3e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:34 -0700 Subject: [PATCH 2878/9457] staging: comedi: adl_pci9111: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 1fd082bf757d..47934c938a4b 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -452,7 +452,7 @@ static void pci9111_ai_munge(struct comedi_device *dev, unsigned int maxdata = s->maxdata; unsigned int invert = (maxdata + 1) >> 1; unsigned int shift = (maxdata == 0xffff) ? 0 : 4; - unsigned int num_samples = num_bytes / sizeof(short); + unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes); unsigned int i; for (i = 0; i < num_samples; i++) @@ -501,7 +501,7 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, if (to_read > samples - pos) to_read = samples - pos; - total += to_read * sizeof(short); + total += comedi_samples_to_bytes(s, to_read); } pos += to_read; @@ -513,7 +513,7 @@ static void pci9111_handle_fifo_half_full(struct comedi_device *dev, } } - devpriv->stop_counter -= total / sizeof(short); + devpriv->stop_counter -= comedi_bytes_to_samples(s, total); } static irqreturn_t pci9111_interrupt(int irq, void *p_device) -- GitLab From 14f7b68058184910794a9f54898e8228855f50f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:35 -0700 Subject: [PATCH 2879/9457] staging: comedi: hwdrv_apci3120: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index facd2c4b922d..917076632433 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -947,7 +947,9 @@ static int apci3120_cyclic_ai(int mode, /* If DMA Enabled */ struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; - unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short); + unsigned int scan_bytes; + + scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); devpriv->b_InterruptMode = APCI3120_DMA_MODE; -- GitLab From 26561101b8c82a9eaf5656e3109b0d94f790fcdb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 31 Oct 2014 12:04:36 -0700 Subject: [PATCH 2880/9457] staging: comedi: ni_at_a2150: use sample manipulation helpers Use the recently added sample manipulation helpers to remove the hardcoded assumption of the sample size. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 5c17def29f8d..69e543a0bf22 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -168,7 +168,6 @@ static irqreturn_t a2150_interrupt(int irq, void *d) struct comedi_cmd *cmd; unsigned int max_points, num_points, residue, leftover; unsigned short dpnt; - static const int sample_size = sizeof(devpriv->dma_buffer[0]); if (!dev->attached) { dev_err(dev->class_dev, "premature interrupt\n"); @@ -206,12 +205,12 @@ static irqreturn_t a2150_interrupt(int irq, void *d) clear_dma_ff(devpriv->dma); /* figure out how many points to read */ - max_points = devpriv->dma_transfer_size / sample_size; + max_points = comedi_bytes_to_samples(s, devpriv->dma_transfer_size); /* residue is the number of points left to be done on the dma * transfer. It should always be zero at this point unless * the stop_src is set to external triggering. */ - residue = get_dma_residue(devpriv->dma) / sample_size; + residue = comedi_bytes_to_samples(s, get_dma_residue(devpriv->dma)); num_points = max_points - residue; if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT) num_points = devpriv->count; @@ -219,7 +218,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d) /* figure out how many points will be stored next time */ leftover = 0; if (cmd->stop_src == TRIG_NONE) { - leftover = devpriv->dma_transfer_size / sample_size; + leftover = comedi_bytes_to_samples(s, + devpriv->dma_transfer_size); } else if (devpriv->count > max_points) { leftover = devpriv->count - max_points; if (leftover > max_points) @@ -248,7 +248,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d) /* re-enable dma */ if (leftover) { set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); - set_dma_count(devpriv->dma, leftover * sample_size); + set_dma_count(devpriv->dma, + comedi_samples_to_bytes(s, leftover)); enable_dma(devpriv->dma); } release_dma_lock(flags); -- GitLab From 4884434c0390a8b2e76d02c126932537093c87f4 Mon Sep 17 00:00:00 2001 From: Rickard Strandqvist Date: Sun, 2 Nov 2014 23:12:04 +0100 Subject: [PATCH 2881/9457] staging: comedi: drivers: comedi_bond.c: Remove unneeded #define Remove unneeded #define. This was previously included in a patch set two but patchset one was taken by mistake. Signed-off-by: Rickard Strandqvist Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_bond.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 5d19861fbabc..85b2f4ab1ba4 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -61,8 +61,7 @@ struct bonded_device { }; struct comedi_bond_private { -# define MAX_BOARD_NAME 256 - char name[MAX_BOARD_NAME]; + char name[256]; struct bonded_device **devs; unsigned ndevs; unsigned nchans; -- GitLab From ecdd21c7b982b0c65250e1b2e7a34eb7054b3c8a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 3 Nov 2014 16:25:43 -0800 Subject: [PATCH 2882/9457] staging: ft1000: Whitespace neatening Use normal kernel style, indentation and alignment. git diff -w shows no difference Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/boot.h | 34 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000.h | 30 +- .../staging/ft1000/ft1000-pcmcia/ft1000_cs.c | 50 +- .../ft1000/ft1000-pcmcia/ft1000_dnld.c | 204 +-- .../staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 686 +++++----- .../staging/ft1000/ft1000-usb/ft1000_debug.c | 1190 ++++++++--------- .../ft1000/ft1000-usb/ft1000_download.c | 300 ++--- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 244 ++-- .../staging/ft1000/ft1000-usb/ft1000_ioctl.h | 60 +- .../staging/ft1000/ft1000-usb/ft1000_usb.c | 14 +- .../staging/ft1000/ft1000-usb/ft1000_usb.h | 2 +- 11 files changed, 1407 insertions(+), 1407 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/boot.h b/drivers/staging/ft1000/ft1000-pcmcia/boot.h index 60c015c1c28a..e4a698528520 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/boot.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/boot.h @@ -1,28 +1,28 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- - File: boot.h + File: boot.h - Description: boatloader + Description: boatloader - History: - 1/11/05 Whc Ported to Linux. + History: + 1/11/05 Whc Ported to Linux. ----------------------------------------------------------------------------*/ + ---------------------------------------------------------------------------*/ #ifndef _BOOTH_ #define _BOOTH_ diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h index 1d52738fff49..5992670f7747 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h @@ -1,21 +1,21 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - Description: Common structures and defines ----------------------------------------------------------------------------*/ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + --------------------------------------------------------------------------- + Description: Common structures and defines + ---------------------------------------------------------------------------*/ #ifndef _FT1000H_ #define _FT1000H_ diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 1f8b3ca35c69..922478e1cb57 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -1,30 +1,30 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device + FT1000 driver for Flarion Flash OFDM NIC Device - Copyright (C) 1999 David A. Hinds. All Rights Reserved. - Copyright (C) 2002 Flarion Technologies, All rights reserved. - Copyright (C) 2006 Patrik Ostrihon, All rights reserved. - Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. + Copyright (C) 1999 David A. Hinds. All Rights Reserved. + Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2006 Patrik Ostrihon, All rights reserved. + Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. - The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds. + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds. - This file was modified to support the Flarion Flash OFDM NIC Device - by Wai Chan (w.chan@flarion.com). + This file was modified to support the Flarion Flash OFDM NIC Device + by Wai Chan (w.chan@flarion.com). - Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk) + Port for kernel 2.6 created by Patrik Ostrihon (patrik.ostrihon@pwc.sk) - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------*/ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + -----------------------------------------------------------------------------*/ #include #include @@ -80,11 +80,11 @@ static int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) /*====================================================================== - ft1000_config() is scheduled to run after a CARD_INSERTION event - is received, to configure the PCMCIA socket, and to make the - device available to the system. + ft1000_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + device available to the system. -======================================================================*/ + ======================================================================*/ static int ft1000_config(struct pcmcia_device *link) { diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index c1856f7d1e26..deb12560dc09 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -1,24 +1,24 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device - - Copyright (C) 2002 Flarion Technologies, All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------- - Description: This module will handshake with the DSP bootloader to - download the DSP runtime image. + Description: This module will handshake with the DSP bootloader to + download the DSP runtime image. ----------------------------------------------------------------------------*/ + ---------------------------------------------------------------------------*/ #define __KERNEL_SYSCALLS__ @@ -114,7 +114,7 @@ struct dsp_image_info { void card_bootload(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); unsigned long flags; u32 *pdata; u32 size; @@ -123,7 +123,7 @@ void card_bootload(struct net_device *dev) netdev_dbg(dev, "card_bootload is called\n"); - pdata = (u32 *) bootimage; + pdata = (u32 *)bootimage; size = sizeof(bootimage); /* check for odd word */ @@ -146,7 +146,7 @@ void card_bootload(struct net_device *dev) u16 get_handshake(struct net_device *dev, u16 expected_value) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 handshake; u32 tempx; int loopcnt; @@ -161,12 +161,12 @@ u16 get_handshake(struct net_device *dev, u16 expected_value) } else { tempx = ntohl(ft1000_read_dpram_mag_32 - (dev, DWNLD_MAG_HANDSHAKE_LOC)); - handshake = (u16) tempx; + (dev, DWNLD_MAG_HANDSHAKE_LOC)); + handshake = (u16)tempx; } if ((handshake == expected_value) - || (handshake == HANDSHAKE_RESET_VALUE)) { + || (handshake == HANDSHAKE_RESET_VALUE)) { return handshake; } loopcnt++; @@ -180,7 +180,7 @@ u16 get_handshake(struct net_device *dev, u16 expected_value) void put_handshake(struct net_device *dev, u16 handshake_value) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u32 tempx; if (info->AsicID == ELECTRABUZZ_ID) { @@ -188,7 +188,7 @@ void put_handshake(struct net_device *dev, u16 handshake_value) DWNLD_HANDSHAKE_LOC); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, handshake_value); /* Handshake */ } else { - tempx = (u32) handshake_value; + tempx = (u32)handshake_value; tempx = ntohl(tempx); ft1000_write_dpram_mag_32(dev, DWNLD_MAG_HANDSHAKE_LOC, tempx); /* Handshake */ } @@ -196,7 +196,7 @@ void put_handshake(struct net_device *dev, u16 handshake_value) u16 get_request_type(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 request_type; u32 tempx; @@ -206,7 +206,7 @@ u16 get_request_type(struct net_device *dev) } else { tempx = ft1000_read_dpram_mag_32(dev, DWNLD_MAG_TYPE_LOC); tempx = ntohl(tempx); - request_type = (u16) tempx; + request_type = (u16)tempx; } return request_type; @@ -215,7 +215,7 @@ u16 get_request_type(struct net_device *dev) long get_request_value(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); long value; u16 w_val; @@ -244,7 +244,7 @@ long get_request_value(struct net_device *dev) void put_request_value(struct net_device *dev, long lvalue) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); u16 size; u32 tempx; @@ -271,11 +271,11 @@ void put_request_value(struct net_device *dev, long lvalue) u16 hdr_checksum(struct pseudo_hdr *pHdr) { - u16 *usPtr = (u16 *) pHdr; + u16 *usPtr = (u16 *)pHdr; u16 chksum; chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ - usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); + usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); return chksum; } @@ -283,7 +283,7 @@ u16 hdr_checksum(struct pseudo_hdr *pHdr) int card_download(struct net_device *dev, const u8 *pFileStart, size_t FileLength) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *)netdev_priv(dev); int Status = SUCCESS; u32 uiState; u16 handshake; @@ -322,7 +322,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, uiState = STATE_START_DWNLD; - pFileHdr5 = (struct dsp_file_hdr *) pFileStart; + pFileHdr5 = (struct dsp_file_hdr *)pFileStart; pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->loader_offset); pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->loader_offset); @@ -376,7 +376,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; } if ((word_length * 2 + (long)pUcFile) > - (long)pBootEnd) { + (long)pBootEnd) { /* * Error, beyond boot code range. */ @@ -390,8 +390,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -402,12 +402,12 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (*pUsFile++ << 16); pUcFile += 4; outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; default: Status = FAILURE; @@ -430,7 +430,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, switch (request) { case REQUEST_FILE_CHECKSUM: netdev_dbg(dev, - "ft1000_dnld: REQUEST_FOR_CHECKSUM\n"); + "ft1000_dnld: REQUEST_FOR_CHECKSUM\n"); put_request_value(dev, image_chksum); break; case REQUEST_RUN_ADDRESS: @@ -468,7 +468,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; } if ((word_length * 2 + (long)pUcFile) > - (long)pCodeEnd) { + (long)pCodeEnd) { /* * Error, beyond boot code range. */ @@ -479,8 +479,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -491,8 +491,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (*pUsFile++ << 16); pUcFile += 4; outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } break; @@ -502,9 +502,9 @@ int card_download(struct net_device *dev, const u8 *pFileStart, (long)(info->DSPInfoBlklen + 1) / 2; put_request_value(dev, word_length); pMailBoxData = - (struct drv_msg *) &info->DSPInfoBlk[0]; + (struct drv_msg *)&info->DSPInfoBlk[0]; pUsData = - (u16 *) &pMailBoxData->data[0]; + (u16 *)&pMailBoxData->data[0]; /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); @@ -528,8 +528,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; @@ -540,13 +540,13 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (*pUsData++ << 16); outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; case REQUEST_VERSION_INFO: @@ -555,8 +555,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, put_request_value(dev, word_length); pUsFile = (u16 *) ((long)pFileStart + - pFileHdr5-> - version_data_offset); + pFileHdr5-> + version_data_offset); /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); @@ -564,8 +564,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ outw(DWNLD_MAG_PS_HDR_LOC, - dev->base_addr + - FT1000_REG_DPRAM_ADDR); + dev->base_addr + + FT1000_REG_DPRAM_ADDR); if (word_length & 0x01) word_length++; word_length = word_length / 2; @@ -578,12 +578,12 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (temp << 16); outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); + dev->base_addr + + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> - dpram_lock, - flags); + dpram_lock, + flags); break; case REQUEST_CODE_BY_VERSION: @@ -592,14 +592,14 @@ int card_download(struct net_device *dev, const u8 *pFileStart, get_request_value(dev); pDspImageInfoV6 = (struct dsp_image_info *) ((long) - pFileStart - + - sizeof - (struct dsp_file_hdr)); + pFileStart + + + sizeof + (struct dsp_file_hdr)); for (imageN = 0; - imageN < - pFileHdr5->nDspImages; - imageN++) { + imageN < + pFileHdr5->nDspImages; + imageN++) { temp = (u16) (pDspImageInfoV6-> version); @@ -610,30 +610,30 @@ int card_download(struct net_device *dev, const u8 *pFileStart, templong |= (temp << 16); if (templong == - requested_version) { + requested_version) { bGoodVersion = true; pUsFile = (u16 *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); + pFileStart + + + pDspImageInfoV6-> + begin_offset); pUcFile = (u8 *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); + pFileStart + + + pDspImageInfoV6-> + begin_offset); pCodeEnd = (u8 *) ((long) - pFileStart - + - pDspImageInfoV6-> - end_offset); + pFileStart + + + pDspImageInfoV6-> + end_offset); run_address = pDspImageInfoV6-> run_address; @@ -645,10 +645,10 @@ int card_download(struct net_device *dev, const u8 *pFileStart, pDspImageInfoV6-> checksum; netdev_dbg(dev, - "ft1000_dnld: image_chksum = 0x%8x\n", - (unsigned - int) - image_chksum); + "ft1000_dnld: image_chksum = 0x%8x\n", + (unsigned + int) + image_chksum); break; } pDspImageInfoV6++; @@ -674,25 +674,25 @@ int card_download(struct net_device *dev, const u8 *pFileStart, break; case STATE_DONE_DWNLD: - if (((unsigned long) (pUcFile) - (unsigned long) pFileStart) >= - (unsigned long) FileLength) { + if (((unsigned long)(pUcFile) - (unsigned long) pFileStart) >= + (unsigned long)FileLength) { uiState = STATE_DONE_FILE; break; } - pHdr = (struct pseudo_hdr *) pUsFile; + pHdr = (struct pseudo_hdr *)pUsFile; if (pHdr->portdest == 0x80 /* DspOAM */ - && (pHdr->portsrc == 0x00 /* Driver */ + && (pHdr->portsrc == 0x00 /* Driver */ || pHdr->portsrc == 0x10 /* FMM */)) { uiState = STATE_SECTION_PROV; } else { netdev_dbg(dev, - "FT1000:download:Download error: Bad Port IDs in Pseudo Record\n"); + "FT1000:download:Download error: Bad Port IDs in Pseudo Record\n"); netdev_dbg(dev, "\t Port Source = 0x%2.2x\n", - pHdr->portsrc); + pHdr->portsrc); netdev_dbg(dev, "\t Port Destination = 0x%2.2x\n", - pHdr->portdest); + pHdr->portdest); Status = FAILURE; } @@ -700,7 +700,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, case STATE_SECTION_PROV: - pHdr = (struct pseudo_hdr *) pUcFile; + pHdr = (struct pseudo_hdr *)pUcFile; if (pHdr->checksum == hdr_checksum(pHdr)) { if (pHdr->portdest != 0x80 /* Dsp OAM */) { @@ -715,8 +715,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, GFP_ATOMIC); if (pbuffer) { memcpy(pbuffer, (void *)pUcFile, - (u32) (usHdrLength + - sizeof(struct pseudo_hdr))); + (u32) (usHdrLength + + sizeof(struct pseudo_hdr))); /* link provisioning data */ pprov_record = kmalloc(sizeof(struct prov_record), @@ -725,15 +725,15 @@ int card_download(struct net_device *dev, const u8 *pFileStart, pprov_record->pprov_data = pbuffer; list_add_tail(&pprov_record-> - list, - &info->prov_list); + list, + &info->prov_list); /* Move to next entry if available */ pUcFile = - (u8 *) ((unsigned long) pUcFile + - (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + (u8 *)((unsigned long) pUcFile + + (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ((unsigned long) (pUcFile) - - (unsigned long) (pFileStart) >= - (unsigned long) FileLength) { + (unsigned long) (pFileStart) >= + (unsigned long)FileLength) { uiState = STATE_DONE_FILE; } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 25b06d350f14..c6bee28cad73 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -1,20 +1,20 @@ /*--------------------------------------------------------------------------- - FT1000 driver for Flarion Flash OFDM NIC Device - - Copyright (C) 2002 Flarion Technologies, All rights reserved. - Copyright (C) 2006 Patrik Ostrihon, All rights reserved. - Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - - Suite 330, Boston, MA 02111-1307, USA. + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + Copyright (C) 2006 Patrik Ostrihon, All rights reserved. + Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------*/ #include @@ -57,7 +57,7 @@ static const struct firmware *fw_entry; static void ft1000_hbchk(u_long data); static struct timer_list poll_timer = { - .function = ft1000_hbchk + .function = ft1000_hbchk }; static u16 cmdbuffer[1024]; @@ -72,7 +72,7 @@ static void ft1000_disable_interrupts(struct net_device *dev); /* new kernel */ MODULE_AUTHOR(""); MODULE_DESCRIPTION - ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs."); +("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs."); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("FT1000"); @@ -80,15 +80,15 @@ MODULE_SUPPORTED_DEVICE("FT1000"); /*--------------------------------------------------------------------------- - Function: ft1000_read_fifo_len - Description: This function will read the ASIC Uplink FIFO status register - which will return the number of bytes remaining in the Uplink FIFO. - Sixteen bytes are subtracted to make sure that the ASIC does not - reach its threshold. - Input: - dev - network device structure - Output: - value - number of bytes available in the ASIC Uplink FIFO. + Function: ft1000_read_fifo_len + Description: This function will read the ASIC Uplink FIFO status register + which will return the number of bytes remaining in the Uplink FIFO. + Sixteen bytes are subtracted to make sure that the ASIC does not + reach its threshold. + Input: + dev - network device structure + Output: + value - number of bytes available in the ASIC Uplink FIFO. -------------------------------------------------------------------------*/ static inline u16 ft1000_read_fifo_len(struct net_device *dev) @@ -103,14 +103,14 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram - Description: This function will read the specific area of dpram - (Electrabuzz ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram + Description: This function will read the specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u16 ft1000_read_dpram(struct net_device *dev, int offset) @@ -130,19 +130,19 @@ u16 ft1000_read_dpram(struct net_device *dev, int offset) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram - Description: This function will write to a specific area of dpram - (Electrabuzz ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram + Description: This function will write to a specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram(struct net_device *dev, - int offset, u16 value) + int offset, u16 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; @@ -156,14 +156,14 @@ static inline void ft1000_write_dpram(struct net_device *dev, /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram_mag_16 - Description: This function will read the specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram_mag_16 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) @@ -188,19 +188,19 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram_mag_16 - Description: This function will write to a specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram_mag_16 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, - int offset, u16 value, int Index) + int offset, u16 value, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; @@ -218,14 +218,14 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, /*--------------------------------------------------------------------------- - Function: ft1000_read_dpram_mag_32 - Description: This function will read the specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - Output: - value - value of dpram + Function: ft1000_read_dpram_mag_32 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram -------------------------------------------------------------------------*/ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) @@ -245,15 +245,15 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) /*--------------------------------------------------------------------------- - Function: ft1000_write_dpram_mag_32 - Description: This function will write to a specific area of dpram - (Magnemite ASIC only) - Input: - dev - device structure - offset - index of dpram - value - value to write - Output: - none. + Function: ft1000_write_dpram_mag_32 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. -------------------------------------------------------------------------*/ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) @@ -270,12 +270,12 @@ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) /*--------------------------------------------------------------------------- - Function: ft1000_enable_interrupts - Description: This function will enable interrupts base on the current interrupt mask. - Input: - dev - device structure - Output: - None. + Function: ft1000_enable_interrupts + Description: This function will enable interrupts base on the current interrupt mask. + Input: + dev - device structure + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_enable_interrupts(struct net_device *dev) @@ -286,18 +286,18 @@ static void ft1000_enable_interrupts(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); DEBUG(1, - "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n", + tempword); } /*--------------------------------------------------------------------------- - Function: ft1000_disable_interrupts - Description: This function will disable all interrupts. - Input: - dev - device structure - Output: - None. + Function: ft1000_disable_interrupts + Description: This function will disable all interrupts. + Input: + dev - device structure + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_disable_interrupts(struct net_device *dev) @@ -308,19 +308,19 @@ static void ft1000_disable_interrupts(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); DEBUG(1, - "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n", + tempword); } /*--------------------------------------------------------------------------- - Function: ft1000_reset_asic - Description: This function will call the Card Service function to reset the - ASIC. - Input: - dev - device structure - Output: - none + Function: ft1000_reset_asic + Description: This function will call the Card Service function to reset the + ASIC. + Input: + dev - device structure + Output: + none -------------------------------------------------------------------------*/ static void ft1000_reset_asic(struct net_device *dev) @@ -360,13 +360,13 @@ static void ft1000_reset_asic(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_reset_card - Description: This function will reset the card - Input: - dev - device structure - Output: - status - false (card reset fail) - true (card reset successful) + Function: ft1000_reset_card + Description: This function will reset the card + Input: + dev - device structure + Output: + status - false (card reset fail) + true (card reset successful) -------------------------------------------------------------------------*/ static int ft1000_reset_card(struct net_device *dev) @@ -389,7 +389,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { DEBUG(0, - "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); + "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); @@ -401,7 +401,7 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); } else { DEBUG(1, - "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n"); + "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n"); ft1000_write_reg(dev, FT1000_REG_RESET, (DSP_RESET_BIT | ASIC_RESET_BIT)); } @@ -438,7 +438,7 @@ static int ft1000_reset_card(struct net_device *dev) if (info->AsicID == MAGNEMITE_ID) { /* Put dsp in reset and take ASIC out of reset */ DEBUG(0, - "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); + "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); /* Setting MAGNEMITE ASIC to big endian mode */ @@ -465,7 +465,7 @@ static int ft1000_reset_card(struct net_device *dev) if (i == 50) { DEBUG(0, - "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n"); + "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n"); return false; } @@ -495,7 +495,7 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_write_dpram(dev, FT1000_HI_HO, ho); tempword = ft1000_read_dpram(dev, FT1000_HI_HO); DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n", - tempword); + tempword); } else { /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag, @@ -504,7 +504,7 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX); DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", - tempword); + tempword); } info->CardReady = 1; @@ -521,14 +521,14 @@ static int ft1000_reset_card(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_chkcard - Description: This function will check if the device is presently available on - the system. - Input: - dev - device structure - Output: - status - false (device is not present) - true (device is present) + Function: ft1000_chkcard + Description: This function will check if the device is presently available on + the system. + Input: + dev - device structure + Output: + status - false (device is not present) + true (device is present) -------------------------------------------------------------------------*/ static int ft1000_chkcard(struct net_device *dev) @@ -542,7 +542,7 @@ static int ft1000_chkcard(struct net_device *dev) tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); if (tempword == 0) { DEBUG(1, - "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); return false; } /* @@ -552,7 +552,7 @@ static int ft1000_chkcard(struct net_device *dev) tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (tempword == 0xffff) { DEBUG(1, - "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); return false; } return true; @@ -561,13 +561,13 @@ static int ft1000_chkcard(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_hbchk - Description: This function will perform the heart beat check of the DSP as - well as the ASIC. - Input: - dev - device structure - Output: - none + Function: ft1000_hbchk + Description: This function will perform the heart beat check of the DSP as + well as the ASIC. + Input: + dev - device structure + Output: + none -------------------------------------------------------------------------*/ static void ft1000_hbchk(u_long data) @@ -586,11 +586,11 @@ static void ft1000_hbchk(u_long data) } else { tempword = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_HI_HO, - FT1000_MAG_HI_HO_INDX)); + (dev, FT1000_MAG_HI_HO, + FT1000_MAG_HI_HO_INDX)); } DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n", - tempword); + tempword); /* Let's perform another check if ho is not detected */ if (tempword != ho) { if (info->AsicID == ELECTRABUZZ_ID) { @@ -602,7 +602,7 @@ static void ft1000_hbchk(u_long data) } if (tempword != ho) { printk(KERN_INFO - "ft1000: heartbeat failed - no ho detected\n"); + "ft1000: heartbeat failed - no ho detected\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -633,7 +633,7 @@ static void ft1000_hbchk(u_long data) info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + "ft1000: Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -651,7 +651,7 @@ static void ft1000_hbchk(u_long data) } if (tempword & FT1000_DB_HB) { printk(KERN_INFO - "ft1000: heartbeat doorbell not clear by firmware\n"); + "ft1000: heartbeat doorbell not clear by firmware\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -682,7 +682,7 @@ static void ft1000_hbchk(u_long data) info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + "ft1000: Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -708,8 +708,8 @@ static void ft1000_hbchk(u_long data) } else { tempword = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_HI_HO, - FT1000_MAG_HI_HO_INDX)); + (dev, FT1000_MAG_HI_HO, + FT1000_MAG_HI_HO_INDX)); } /* Let's write hi again if fail */ if (tempword != hi) { @@ -731,7 +731,7 @@ static void ft1000_hbchk(u_long data) if (tempword != hi) { printk(KERN_INFO - "ft1000: heartbeat failed - cannot write hi into DPRAM\n"); + "ft1000: heartbeat failed - cannot write hi into DPRAM\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -762,7 +762,7 @@ static void ft1000_hbchk(u_long data) info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + "ft1000: Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -778,19 +778,19 @@ static void ft1000_hbchk(u_long data) /* Schedule this module to run every 2 seconds */ poll_timer.expires = jiffies + (2 * HZ); - poll_timer.data = (u_long) dev; + poll_timer.data = (u_long)dev; add_timer(&poll_timer); } /*--------------------------------------------------------------------------- - Function: ft1000_send_cmd - Description: - Input: - Output: + Function: ft1000_send_cmd + Description: + Input: + Output: -------------------------------------------------------------------------*/ -static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) +static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { struct ft1000_info *info = netdev_priv(dev); int i; @@ -831,7 +831,7 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, /* Write pseudo header and messgae body */ for (i = 0; i < (size >> 1); i++) { DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i, - *ptempbuffer); + *ptempbuffer); tempword = htons(*ptempbuffer++); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword); } @@ -845,13 +845,13 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, FT1000_DPRAM_MAG_TX_BASE + 1); for (i = 0; i < (size >> 2); i++) { DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + *ptempbuffer); outw(*ptempbuffer++, - dev->base_addr + FT1000_REG_MAG_DPDATAL); + dev->base_addr + FT1000_REG_MAG_DPDATAL); DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + *ptempbuffer); outw(*ptempbuffer++, - dev->base_addr + FT1000_REG_MAG_DPDATAH); + dev->base_addr + FT1000_REG_MAG_DPDATAH); } DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL); @@ -866,19 +866,19 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, /*--------------------------------------------------------------------------- - Function: ft1000_receive_cmd - Description: This function will read a message from the dpram area. - Input: - dev - network device structure - pbuffer - caller supply address to buffer - pnxtph - pointer to next pseudo header - Output: - Status = 0 (unsuccessful) - = 1 (successful) + Function: ft1000_receive_cmd + Description: This function will read a message from the dpram area. + Input: + dev - network device structure + pbuffer - caller supply address to buffer + pnxtph - pointer to next pseudo header + Output: + Status = 0 (unsuccessful) + = 1 (successful) -------------------------------------------------------------------------*/ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, - int maxsz, u16 *pnxtph) + int maxsz, u16 *pnxtph) { struct ft1000_info *info = netdev_priv(dev); u16 size; @@ -888,20 +888,20 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, unsigned long flags; if (info->AsicID == ELECTRABUZZ_ID) { - size = ( ft1000_read_dpram(dev, *pnxtph) ) + sizeof(struct pseudo_hdr); + size = (ft1000_read_dpram(dev, *pnxtph)) + sizeof(struct pseudo_hdr); } else { size = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_PH_LEN, - FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); + (dev, FT1000_MAG_PH_LEN, + FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); } if (size > maxsz) { DEBUG(1, - "FT1000:ft1000_receive_cmd:Invalid command length = %d\n", - size); + "FT1000:ft1000_receive_cmd:Invalid command length = %d\n", + size); return false; } else { - ppseudohdr = (u16 *) pbuffer; + ppseudohdr = (u16 *)pbuffer; spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -922,11 +922,11 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, for (i = 0; i <= (size >> 2); i++) { *pbuffer = inw(dev->base_addr + - FT1000_REG_MAG_DPDATAL); + FT1000_REG_MAG_DPDATAL); pbuffer++; *pbuffer = inw(dev->base_addr + - FT1000_REG_MAG_DPDATAH); + FT1000_REG_MAG_DPDATAH); pbuffer++; } /* copy odd aligned word */ @@ -954,7 +954,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, } if ((tempword != *ppseudohdr)) { DEBUG(1, - "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); + "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); /* Drop this message */ return false; } @@ -964,13 +964,13 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, /*--------------------------------------------------------------------------- - Function: ft1000_proc_drvmsg - Description: This function will process the various driver messages. - Input: - dev - device structure - pnxtph - pointer to next pseudo header - Output: - none + Function: ft1000_proc_drvmsg + Description: This function will process the various driver messages. + Input: + dev - device structure + pnxtph - pointer to next pseudo header + Output: + none -------------------------------------------------------------------------*/ static void ft1000_proc_drvmsg(struct net_device *dev) @@ -992,22 +992,22 @@ static void ft1000_proc_drvmsg(struct net_device *dev) u16 wrd; } convert; - if (info->AsicID == ELECTRABUZZ_ID) { - tempword = FT1000_DPRAM_RX_BASE+2; - } - else { - tempword = FT1000_DPRAM_MAG_RX_BASE; - } - if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) { + if (info->AsicID == ELECTRABUZZ_ID) { + tempword = FT1000_DPRAM_RX_BASE+2; + } + else { + tempword = FT1000_DPRAM_MAG_RX_BASE; + } + if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) { /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ - pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; + pdrvmsg = (struct drv_msg *)&cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); DEBUG(1, "Command message type = 0x%x\n", msgtype); switch (msgtype) { case DSP_PROVISION: DEBUG(0, - "Got a provisioning request message from DSP\n"); + "Got a provisioning request message from DSP\n"); mdelay(25); while (list_empty(&info->prov_list) == 0) { DEBUG(0, "Sending a provisioning message\n"); @@ -1025,25 +1025,25 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ptr = list_entry(info->prov_list.next, struct prov_record, list); - len = *(u16 *) ptr->pprov_data; + len = *(u16 *)ptr->pprov_data; len = htons(len); - pmsg = (u16 *) ptr->pprov_data; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)ptr->pprov_data; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + ppseudo_hdr->checksum); for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + ppseudo_hdr->checksum); } - ft1000_send_cmd (dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE); + ft1000_send_cmd(dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); @@ -1055,18 +1055,28 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->CardReady = 1; break; case MEDIA_STATE: - pmediamsg = (struct media_msg *) & cmdbuffer[0]; + pmediamsg = (struct media_msg *)&cmdbuffer[0]; if (info->ProgConStat != 0xFF) { - if (pmediamsg->state) { - DEBUG(1, "Media is up\n"); - if (info->mediastate == 0) { - netif_carrier_on(dev); - netif_wake_queue(dev); - info->mediastate = 1; - do_gettimeofday(&tv); - info->ConTm = tv.tv_sec; + if (pmediamsg->state) { + DEBUG(1, "Media is up\n"); + if (info->mediastate == 0) { + netif_carrier_on(dev); + netif_wake_queue(dev); + info->mediastate = 1; + do_gettimeofday(&tv); + info->ConTm = tv.tv_sec; + } + } else { + DEBUG(1, "Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + netif_carrier_off(dev); + netif_stop_queue(dev); + info->ConTm = 0; + } } - } else { + } + else { DEBUG(1, "Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; @@ -1075,25 +1085,15 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->ConTm = 0; } } - } - else { - DEBUG(1, "Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - netif_carrier_off(dev); - netif_stop_queue(dev); - info->ConTm = 0; - } - } break; case DSP_INIT_MSG: - pdspinitmsg = (struct dsp_init_msg *) & cmdbuffer[0]; + pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, - HWSERNUMSZ); + HWSERNUMSZ); memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); dev->dev_addr[0] = info->eui64[0]; @@ -1104,28 +1104,28 @@ static void ft1000_proc_drvmsg(struct net_device *dev) dev->dev_addr[5] = info->eui64[7]; if (ntohs(pdspinitmsg->length) == - (sizeof(struct dsp_init_msg) - 20)) { + (sizeof(struct dsp_init_msg) - 20)) { memcpy(info->ProductMode, - pdspinitmsg->ProductMode, MODESZ); + pdspinitmsg->ProductMode, MODESZ); memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, - CALVERSZ); + CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, - CALDATESZ); + CALDATESZ); DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n", - info->RfCalVer[0], info->RfCalVer[1]); + info->RfCalVer[0], info->RfCalVer[1]); } - break ; + break; case DSP_STORE_INFO: DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n"); tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) & pdrvmsg->data[0]; + pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { DEBUG(1, - "FT1000:drivermsg:dsp info data = 0x%x\n", - *pmsg); + "FT1000:drivermsg:dsp info data = 0x%x\n", + *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; } } @@ -1152,8 +1152,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev) * Put message into Slow Queue * Form Pseudo header */ - pmsg = (u16 *) info->DSPInfoBlk; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)info->DSPInfoBlk; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4); ppseudo_hdr->source = 0x10; @@ -1177,7 +1177,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->DSPInfoBlk[8] = 0x7200; info->DSPInfoBlk[9] = htons(info->DSPInfoBlklen); - ft1000_send_cmd (dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0); + ft1000_send_cmd(dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0); } break; @@ -1203,8 +1203,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev) * Put message into Slow Queue * Form Pseudo header */ - pmsg = (u16 *) & tempbuffer[0]; - ppseudo_hdr = (struct pseudo_hdr *) pmsg; + pmsg = (u16 *)&tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; @@ -1220,11 +1220,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) /* Insert application id */ ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - } - pmsg = (u16 *) &tempbuffer[16]; + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + } + pmsg = (u16 *)&tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1239,7 +1239,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) *pmsg++ = convert.wrd; *pmsg++ = htons(info->DrvErrNum); - ft1000_send_cmd (dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0); + ft1000_send_cmd(dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0); info->DrvErrNum = 0; } @@ -1252,14 +1252,14 @@ static void ft1000_proc_drvmsg(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_parse_dpram_msg - Description: This function will parse the message received from the DSP - via the DPRAM interface. - Input: - dev - device structure - Output: - status - FAILURE - SUCCESS + Function: ft1000_parse_dpram_msg + Description: This function will parse the message received from the DSP + via the DPRAM interface. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ static int ft1000_parse_dpram_msg(struct net_device *dev) @@ -1290,7 +1290,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_DPRAM_MAG_RX_BASE); for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) { outl(info->DSPSess.MagRec[i], - dev->base_addr + FT1000_REG_MAG_DPDATA); + dev->base_addr + FT1000_REG_MAG_DPDATA); } } spin_unlock_irqrestore(&info->dpram_lock, flags); @@ -1311,7 +1311,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) if (doorbell & FT1000_DSP_ASIC_RESET) { DEBUG(0, - "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n"); + "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n"); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DSP_ASIC_RESET); udelay(200); @@ -1320,7 +1320,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) if (doorbell & FT1000_DB_DPRAM_RX) { DEBUG(1, - "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n"); + "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n"); nxtph = FT1000_DPRAM_RX_BASE + 2; if (info->AsicID == ELECTRABUZZ_ID) { total_len = @@ -1328,13 +1328,13 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } else { total_len = ntohs(ft1000_read_dpram_mag_16 - (dev, FT1000_MAG_TOTAL_LEN, - FT1000_MAG_TOTAL_LEN_INDX)); + (dev, FT1000_MAG_TOTAL_LEN, + FT1000_MAG_TOTAL_LEN_INDX)); } DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n", - total_len); + total_len); if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { - total_len += nxtph; + total_len += nxtph; /* * ft1000_read_reg will return a value that needs to be byteswap * in order to get DSP_QID_OFFSET. @@ -1395,7 +1395,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /* let's clear any unexpected doorbells from DSP */ doorbell = doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ | - FT1000_DB_COND_RESET | 0xff00); + FT1000_DB_COND_RESET | 0xff00); if (doorbell) { DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell); ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell); @@ -1407,14 +1407,14 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_flush_fifo - Description: This function will flush one packet from the downlink - FIFO. - Input: - dev - device structure - drv_err - driver error causing the flush fifo - Output: - None. + Function: ft1000_flush_fifo + Description: This function will flush one packet from the downlink + FIFO. + Input: + dev - device structure + drv_err - driver error causing the flush fifo + Output: + None. -------------------------------------------------------------------------*/ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) @@ -1512,7 +1512,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) */ tempword = inw(dev->base_addr + - FT1000_REG_SUP_IMASK); + FT1000_REG_SUP_IMASK); if (tempword == 0) { /* This indicates that we can not communicate with the ASIC */ info->DrvErrNum = @@ -1557,15 +1557,15 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) /*--------------------------------------------------------------------------- - Function: ft1000_copy_up_pkt - Description: This function will pull Flarion packets out of the Downlink - FIFO and convert it to an ethernet packet. The ethernet packet will - then be deliver to the TCP/IP stack. - Input: - dev - device structure - Output: - status - FAILURE - SUCCESS + Function: ft1000_copy_up_pkt + Description: This function will pull Flarion packets out of the Downlink + FIFO and convert it to an ethernet packet. The ethernet packet will + then be deliver to the TCP/IP stack. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ static int ft1000_copy_up_pkt(struct net_device *dev) @@ -1616,7 +1616,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) info->stats.rx_errors++; return FAILURE; } - pbuffer = (u8 *) skb_put(skb, len + 12); + pbuffer = (u8 *)skb_put(skb, len + 12); /* Pseudo header */ if (info->AsicID == ELECTRABUZZ_ID) { @@ -1658,7 +1658,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) if (chksum != tempword) { DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum, - tempword); + tempword); ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO); info->stats.rx_errors++; kfree_skb(skb); @@ -1685,7 +1685,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) for (i = 0; i < len / 2; i++) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); *pbuffer++ = (u8) (tempword >> 8); - *pbuffer++ = (u8) tempword; + *pbuffer++ = (u8)tempword; if (ft1000_chkcard(dev) == false) { kfree_skb(skb); return FAILURE; @@ -1698,7 +1698,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) *pbuffer++ = (u8) (tempword >> 8); } } else { - ptemplong = (u32 *) pbuffer; + ptemplong = (u32 *)pbuffer; for (i = 0; i < len / 4; i++) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); DEBUG(1, "Data = 0x%8x\n", templong); @@ -1743,17 +1743,17 @@ static int ft1000_copy_up_pkt(struct net_device *dev) /*--------------------------------------------------------------------------- - Function: ft1000_copy_down_pkt - Description: This function will take an ethernet packet and convert it to - a Flarion packet prior to sending it to the ASIC Downlink - FIFO. - Input: - dev - device structure - packet - address of ethernet packet - len - length of IP packet - Output: - status - FAILURE - SUCCESS + Function: ft1000_copy_down_pkt + Description: This function will take an ethernet packet and convert it to + a Flarion packet prior to sending it to the ASIC Downlink + FIFO. + Input: + dev - device structure + packet - address of ethernet packet + len - length of IP packet + Output: + status - FAILURE + SUCCESS -------------------------------------------------------------------------*/ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) @@ -1790,7 +1790,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) } if (len > ft1000_read_fifo_len(dev)) { DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n"); + "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n"); info->stats.tx_errors++; return SUCCESS; } @@ -1822,38 +1822,38 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) /* copy first word to UFIFO_BEG reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n", - pseudo.buff[0]); + pseudo.buff[0]); /* copy subsequent words to UFIFO_MID reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n", - pseudo.buff[1]); + pseudo.buff[1]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n", - pseudo.buff[2]); + pseudo.buff[2]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n", - pseudo.buff[3]); + pseudo.buff[3]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n", - pseudo.buff[4]); + pseudo.buff[4]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n", - pseudo.buff[5]); + pseudo.buff[5]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n", - pseudo.buff[6]); + pseudo.buff[6]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n", - pseudo.buff[7]); + pseudo.buff[7]); /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 1) - 1; i++) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", + i + 8, htons(*packet)); packet++; } @@ -1862,40 +1862,40 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n", - htons(*packet)); + "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n", + htons(*packet)); packet++; ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } else { ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } } else { - outl(*(u32 *) & pseudo.buff[0], - dev->base_addr + FT1000_REG_MAG_UFDR); + outl(*(u32 *)&pseudo.buff[0], + dev->base_addr + FT1000_REG_MAG_UFDR); DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[0]); - outl(*(u32 *) & pseudo.buff[2], - dev->base_addr + FT1000_REG_MAG_UFDR); + *(u32 *)&pseudo.buff[0]); + outl(*(u32 *)&pseudo.buff[2], + dev->base_addr + FT1000_REG_MAG_UFDR); DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[2]); - outl(*(u32 *) & pseudo.buff[4], - dev->base_addr + FT1000_REG_MAG_UFDR); + *(u32 *)&pseudo.buff[2]); + outl(*(u32 *)&pseudo.buff[4], + dev->base_addr + FT1000_REG_MAG_UFDR); DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[4]); - outl(*(u32 *) & pseudo.buff[6], - dev->base_addr + FT1000_REG_MAG_UFDR); + *(u32 *)&pseudo.buff[4]); + outl(*(u32 *)&pseudo.buff[6], + dev->base_addr + FT1000_REG_MAG_UFDR); DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *) & pseudo.buff[6]); + *(u32 *)&pseudo.buff[6]); - plong = (u32 *) packet; + plong = (u32 *)packet; /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 2); i++) { outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); @@ -1904,8 +1904,8 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) /* Check for odd alignment */ if (len & 0x0003) { DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", - *plong); + "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", + *plong); outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); } outl(1, dev->base_addr + FT1000_REG_MAG_UFER); @@ -1935,7 +1935,7 @@ static int ft1000_open(struct net_device *dev) /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */ init_timer(&poll_timer); poll_timer.expires = jiffies + (2 * HZ); - poll_timer.data = (u_long) dev; + poll_timer.data = (u_long)dev; add_timer(&poll_timer); DEBUG(0, "ft1000_hw: ft1000_open is ended2\n"); @@ -1976,9 +1976,9 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) } DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n", - skb->len); + skb->len); - pdata = (u8 *) skb->data; + pdata = (u8 *)skb->data; if (info->mediastate == 0) { /* Drop packet is mediastate is down */ @@ -1989,11 +1989,11 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { /* Drop packet which has invalid size */ DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n"); + "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n"); return SUCCESS; } ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2), - skb->len - ENET_HEADER_SIZE + 2); + skb->len - ENET_HEADER_SIZE + 2); dev_kfree_skb(skb); @@ -2038,12 +2038,12 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) /* Check if we have packets in the Downlink FIFO */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = - ft1000_read_reg(dev, - FT1000_REG_DFIFO_STAT); + ft1000_read_reg(dev, + FT1000_REG_DFIFO_STAT); } else { tempword = - ft1000_read_reg(dev, - FT1000_REG_MAG_DFSR); + ft1000_read_reg(dev, + FT1000_REG_MAG_DFSR); } if (tempword & 0x1f) { ft1000_copy_up_pkt(dev); @@ -2060,7 +2060,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); /* Read interrupt type */ - inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR); + inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); DEBUG(1, "ft1000_hw: interrupt status register after clear = 0x%x\n", inttype); } ft1000_enable_interrupts(dev); @@ -2103,7 +2103,7 @@ void stop_ft1000_card(struct net_device *dev) } static void ft1000_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) + struct ethtool_drvinfo *info) { struct ft1000_info *ft_info; ft_info = netdev_priv(dev); @@ -2129,19 +2129,19 @@ static const struct ethtool_ops ops = { }; struct net_device *init_ft1000_card(struct pcmcia_device *link, - void *ft1000_reset) + void *ft1000_reset) { struct ft1000_info *info; struct ft1000_pcmcia *pcmcia; struct net_device *dev; static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */ - { - .ndo_open = &ft1000_open, - .ndo_stop = &ft1000_close, - .ndo_start_xmit = &ft1000_start_xmit, - .ndo_get_stats = &ft1000_stats, - }; + { + .ndo_open = &ft1000_open, + .ndo_stop = &ft1000_close, + .ndo_start_xmit = &ft1000_start_xmit, + .ndo_get_stats = &ft1000_stats, + }; DEBUG(1, "ft1000_hw: init_ft1000_card()\n"); DEBUG(1, "ft1000_hw: irq = %d\n", link->irq); @@ -2153,7 +2153,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, flarion_ft1000_cnt--; dev_info(&link->dev, - "This driver can not support more than one instance\n"); + "This driver can not support more than one instance\n"); return NULL; } @@ -2168,8 +2168,8 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, memset(info, 0, sizeof(struct ft1000_info)); - DEBUG(1, "address of dev = 0x%8x\n", (u32) dev); - DEBUG(1, "address of dev info = 0x%8x\n", (u32) info); + DEBUG(1, "address of dev = 0x%8x\n", (u32)dev); + DEBUG(1, "address of dev info = 0x%8x\n", (u32)info); DEBUG(0, "device name = %s\n", dev->name); memset(&info->stats, 0, sizeof(struct net_device_stats)); @@ -2246,7 +2246,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, ft1000_card_present = 1; dev->ethtool_ops = &ops; printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n", - dev->name, dev->base_addr, dev->irq, dev->dev_addr); + dev->name, dev->base_addr, dev->irq, dev->dev_addr); return dev; err_unreg: diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 4397ada1e387..658f3cab8e72 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -1,31 +1,31 @@ /* -*--------------------------------------------------------------------------- -* FT1000 driver for Flarion Flash OFDM NIC Device -* -* Copyright (C) 2006 Flarion Technologies, All rights reserved. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2 of the License, or (at your option) any -* later version. This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 59 Temple Place - -* Suite 330, Boston, MA 02111-1307, USA. -*--------------------------------------------------------------------------- -* -* File: ft1000_chdev.c -* -* Description: Custom character device dispatch routines. -* -* History: -* 8/29/02 Whc Ported to Linux. -* 6/05/06 Whc Porting to Linux 2.6.9 -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * FT1000 driver for Flarion Flash OFDM NIC Device + * + * Copyright (C) 2006 Flarion Technologies, All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + *--------------------------------------------------------------------------- + * + * File: ft1000_chdev.c + * + * Description: Custom character device dispatch routines. + * + * History: + * 8/29/02 Whc Ported to Linux. + * 6/05/06 Whc Porting to Linux 2.6.9 + * + *--------------------------------------------------------------------------- + */ #include #include #include @@ -43,7 +43,7 @@ static int ft1000_flarion_cnt; static int ft1000_open(struct inode *inode, struct file *file); static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); static long ft1000_ioctl(struct file *file, unsigned int command, - unsigned long argument); + unsigned long argument); static int ft1000_release(struct inode *inode, struct file *file); /* List to free receive command buffer pool */ @@ -55,8 +55,8 @@ spinlock_t free_buff_lock; int numofmsgbuf = 0; /* -* Table of entry-point routines for char device -*/ + * Table of entry-point routines for char device + */ static const struct file_operations ft1000fops = { .unlocked_ioctl = ft1000_ioctl, .poll = ft1000_poll_dev, @@ -66,104 +66,104 @@ static const struct file_operations ft1000fops = { }; /* ---------------------------------------------------------------------------- -* Function: ft1000_get_buffer -* -* Parameters: -* -* Returns: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + --------------------------------------------------------------------------- + * Function: ft1000_get_buffer + * + * Parameters: + * + * Returns: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist) { - unsigned long flags; + unsigned long flags; struct dpram_blk *ptr; - spin_lock_irqsave(&free_buff_lock, flags); - /* Check if buffer is available */ - if (list_empty(bufflist)) { - DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); - ptr = NULL; - } else { - numofmsgbuf--; - ptr = list_entry(bufflist->next, struct dpram_blk, list); - list_del(&ptr->list); - /* DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ - } - spin_unlock_irqrestore(&free_buff_lock, flags); - - return ptr; + spin_lock_irqsave(&free_buff_lock, flags); + /* Check if buffer is available */ + if (list_empty(bufflist)) { + DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); + ptr = NULL; + } else { + numofmsgbuf--; + ptr = list_entry(bufflist->next, struct dpram_blk, list); + list_del(&ptr->list); + /* DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ + } + spin_unlock_irqrestore(&free_buff_lock, flags); + + return ptr; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_free_buffer -* -* Parameters: -* -* Returns: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_free_buffer + * + * Parameters: + * + * Returns: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) { - unsigned long flags; - - spin_lock_irqsave(&free_buff_lock, flags); - /* Put memory back to list */ - list_add_tail(&pdpram_blk->list, plist); - numofmsgbuf++; - /*DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ - spin_unlock_irqrestore(&free_buff_lock, flags); + unsigned long flags; + + spin_lock_irqsave(&free_buff_lock, flags); + /* Put memory back to list */ + list_add_tail(&pdpram_blk->list, plist); + numofmsgbuf++; + /*DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ + spin_unlock_irqrestore(&free_buff_lock, flags); } /* -*--------------------------------------------------------------------------- -* Function: ft1000_CreateDevice -* -* Parameters: dev - pointer to adapter object -* -* Returns: 0 if successful -* -* Description: Creates a private char device. -* -* Notes: Only called by init_module(). -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_CreateDevice + * + * Parameters: dev - pointer to adapter object + * + * Returns: 0 if successful + * + * Description: Creates a private char device. + * + * Notes: Only called by init_module(). + * + *--------------------------------------------------------------------------- + */ int ft1000_create_dev(struct ft1000_usb *dev) { - int result; - int i; + int result; + int i; struct dentry *dir, *file; struct ft1000_debug_dirs *tmp; - /* make a new device name */ - sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber); + /* make a new device name */ + sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber); - DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); - DEBUG("DeviceCreated = %x\n", dev->DeviceCreated); + DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); + DEBUG("DeviceCreated = %x\n", dev->DeviceCreated); - if (dev->DeviceCreated) { - DEBUG("%s: \"%s\" already registered\n", __func__, dev->DeviceName); - return -EIO; - } + if (dev->DeviceCreated) { + DEBUG("%s: \"%s\" already registered\n", __func__, dev->DeviceName); + return -EIO; + } - /* register the device */ - DEBUG("%s: \"%s\" debugfs device registration\n", __func__, dev->DeviceName); + /* register the device */ + DEBUG("%s: \"%s\" debugfs device registration\n", __func__, dev->DeviceName); tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); if (tmp == NULL) { @@ -178,7 +178,7 @@ int ft1000_create_dev(struct ft1000_usb *dev) } file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, - dev, &ft1000fops); + dev, &ft1000fops); if (IS_ERR(file)) { result = PTR_ERR(file); goto debug_file_fail; @@ -189,25 +189,25 @@ int ft1000_create_dev(struct ft1000_usb *dev) tmp->int_number = dev->CardNumber; list_add(&(tmp->list), &(dev->nodes.list)); - DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, dev->DeviceName); - - /* initialize application information */ - dev->appcnt = 0; - for (i=0; iapp_info[i].nTxMsg = 0; - dev->app_info[i].nRxMsg = 0; - dev->app_info[i].nTxMsgReject = 0; - dev->app_info[i].nRxMsgMiss = 0; - dev->app_info[i].fileobject = NULL; - dev->app_info[i].app_id = i+1; - dev->app_info[i].DspBCMsgFlag = 0; - dev->app_info[i].NumOfMsg = 0; - init_waitqueue_head(&dev->app_info[i].wait_dpram_msg); - INIT_LIST_HEAD(&dev->app_info[i].app_sqlist); - } - - dev->DeviceCreated = TRUE; - ft1000_flarion_cnt++; + DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, dev->DeviceName); + + /* initialize application information */ + dev->appcnt = 0; + for (i = 0; i < MAX_NUM_APP; i++) { + dev->app_info[i].nTxMsg = 0; + dev->app_info[i].nRxMsg = 0; + dev->app_info[i].nTxMsgReject = 0; + dev->app_info[i].nRxMsgMiss = 0; + dev->app_info[i].fileobject = NULL; + dev->app_info[i].app_id = i+1; + dev->app_info[i].DspBCMsgFlag = 0; + dev->app_info[i].NumOfMsg = 0; + init_waitqueue_head(&dev->app_info[i].wait_dpram_msg); + INIT_LIST_HEAD(&dev->app_info[i].app_sqlist); + } + + dev->DeviceCreated = TRUE; + ft1000_flarion_cnt++; return 0; @@ -220,33 +220,33 @@ int ft1000_create_dev(struct ft1000_usb *dev) } /* -*--------------------------------------------------------------------------- -* Function: ft1000_DestroyDeviceDEBUG -* -* Parameters: dev - pointer to adapter object -* -* Description: Destroys a private char device. -* -* Notes: Only called by cleanup_module(). -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_DestroyDeviceDEBUG + * + * Parameters: dev - pointer to adapter object + * + * Description: Destroys a private char device. + * + * Notes: Only called by cleanup_module(). + * + *--------------------------------------------------------------------------- + */ void ft1000_destroy_dev(struct net_device *netdev) { struct ft1000_info *info = netdev_priv(netdev); struct ft1000_usb *dev = info->priv; - int i; + int i; struct dpram_blk *pdpram_blk; struct dpram_blk *ptr; struct list_head *pos, *q; struct ft1000_debug_dirs *dir; - DEBUG("%s called\n", __func__); + DEBUG("%s called\n", __func__); - if (dev->DeviceCreated) { - ft1000_flarion_cnt--; + if (dev->DeviceCreated) { + ft1000_flarion_cnt--; list_for_each_safe(pos, q, &dev->nodes.list) { dir = list_entry(pos, struct ft1000_debug_dirs, list); if (dir->int_number == dev->CardNumber) { @@ -257,28 +257,28 @@ void ft1000_destroy_dev(struct net_device *netdev) } } DEBUG("%s: unregistered device \"%s\"\n", __func__, - dev->DeviceName); - - /* Make sure we free any memory reserve for slow Queue */ - for (i=0; iapp_info[i].app_sqlist) == 0) { - pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - - } - wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); - } - - /* Remove buffer allocated for receive command data */ - if (ft1000_flarion_cnt == 0) { - while (list_empty(&freercvpool) == 0) { - ptr = list_entry(freercvpool.next, struct dpram_blk, list); - list_del(&ptr->list); - kfree(ptr->pbuffer); - kfree(ptr); - } - } + dev->DeviceName); + + /* Make sure we free any memory reserve for slow Queue */ + for (i = 0; i < MAX_NUM_APP; i++) { + while (list_empty(&dev->app_info[i].app_sqlist) == 0) { + pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + + } + wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); + } + + /* Remove buffer allocated for receive command data */ + if (ft1000_flarion_cnt == 0) { + while (list_empty(&freercvpool) == 0) { + ptr = list_entry(freercvpool.next, struct dpram_blk, list); + list_del(&ptr->list); + kfree(ptr->pbuffer); + kfree(ptr); + } + } dev->DeviceCreated = FALSE; } @@ -286,503 +286,503 @@ void ft1000_destroy_dev(struct net_device *netdev) } /* -*--------------------------------------------------------------------------- -* Function: ft1000_open -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_open + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static int ft1000_open(struct inode *inode, struct file *file) { struct ft1000_info *info; struct ft1000_usb *dev = (struct ft1000_usb *)inode->i_private; - int i,num; + int i, num; - DEBUG("%s called\n", __func__); - num = (MINOR(inode->i_rdev) & 0xf); - DEBUG("ft1000_open: minor number=%d\n", num); + DEBUG("%s called\n", __func__); + num = (MINOR(inode->i_rdev) & 0xf); + DEBUG("ft1000_open: minor number=%d\n", num); info = file->private_data = netdev_priv(dev->net); - DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt); - - /* Check if maximum number of application exceeded */ - if (dev->appcnt > MAX_NUM_APP) { - DEBUG("Maximum number of application exceeded\n"); - return -EACCES; - } - - /* Search for available application info block */ - for (i=0; iapp_info[i].fileobject == NULL)) { - break; - } - } - - /* Fail due to lack of application info block */ - if (i == MAX_NUM_APP) { - DEBUG("Could not find an application info block\n"); - return -EACCES; - } - - dev->appcnt++; - dev->app_info[i].fileobject = &file->f_owner; - dev->app_info[i].nTxMsg = 0; - dev->app_info[i].nRxMsg = 0; - dev->app_info[i].nTxMsgReject = 0; - dev->app_info[i].nRxMsgMiss = 0; + DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt); + + /* Check if maximum number of application exceeded */ + if (dev->appcnt > MAX_NUM_APP) { + DEBUG("Maximum number of application exceeded\n"); + return -EACCES; + } + + /* Search for available application info block */ + for (i = 0; i < MAX_NUM_APP; i++) { + if ((dev->app_info[i].fileobject == NULL)) { + break; + } + } + + /* Fail due to lack of application info block */ + if (i == MAX_NUM_APP) { + DEBUG("Could not find an application info block\n"); + return -EACCES; + } + + dev->appcnt++; + dev->app_info[i].fileobject = &file->f_owner; + dev->app_info[i].nTxMsg = 0; + dev->app_info[i].nRxMsg = 0; + dev->app_info[i].nTxMsgReject = 0; + dev->app_info[i].nRxMsgMiss = 0; nonseekable_open(inode, file); - return 0; + return 0; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_poll_dev -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_poll_dev + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) { - struct net_device *netdev = file->private_data; + struct net_device *netdev = file->private_data; struct ft1000_info *info = netdev_priv(netdev); struct ft1000_usb *dev = info->priv; - int i; - - /* DEBUG("ft1000_poll_dev called\n"); */ - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); - return -EBADF; - } - - /* Search for matching file object */ - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id); */ - break; - } - } - - /* Could not find application info block */ - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - return -EACCES; - } - - if (list_empty(&dev->app_info[i].app_sqlist) == 0) { - DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); - return(POLLIN | POLLRDNORM | POLLPRI); - } - - poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait); - /* DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); */ + int i; + + /* DEBUG("ft1000_poll_dev called\n"); */ + if (ft1000_flarion_cnt == 0) { + DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); + return -EBADF; + } + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (dev->app_info[i].fileobject == &file->f_owner) { + /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id); */ + break; + } + } + + /* Could not find application info block */ + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + return -EACCES; + } + + if (list_empty(&dev->app_info[i].app_sqlist) == 0) { + DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); + return(POLLIN | POLLRDNORM | POLLPRI); + } + + poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait); + /* DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); */ return 0; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_ioctl -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_ioctl + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static long ft1000_ioctl(struct file *file, unsigned int command, - unsigned long argument) + unsigned long argument) { - void __user *argp = (void __user *)argument; + void __user *argp = (void __user *)argument; struct ft1000_info *info; - struct ft1000_usb *ft1000dev; - int result=0; - int cmd; - int i; - u16 tempword; - unsigned long flags; - struct timeval tv; + struct ft1000_usb *ft1000dev; + int result = 0; + int cmd; + int i; + u16 tempword; + unsigned long flags; + struct timeval tv; struct IOCTL_GET_VER get_ver_data; struct IOCTL_GET_DSP_STAT get_stat_data; - u8 ConnectionMsg[] = {0x00,0x44,0x10,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x93,0x64, - 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0a, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x02,0x37,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x7f,0x00, - 0x00,0x01,0x00,0x00}; + u8 ConnectionMsg[] = {0x00, 0x44, 0x10, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x93, 0x64, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x37, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x00, 0x00}; - unsigned short ledStat=0; - unsigned short conStat=0; + unsigned short ledStat = 0; + unsigned short conStat = 0; - /* DEBUG("ft1000_ioctl called\n"); */ + /* DEBUG("ft1000_ioctl called\n"); */ - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); - return -EBADF; - } + if (ft1000_flarion_cnt == 0) { + DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); + return -EBADF; + } - /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ + /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ info = file->private_data; ft1000dev = info->priv; - cmd = _IOC_NR(command); - /* DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); */ - - /* process the command */ - switch (cmd) { - case IOCTL_REGISTER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); - result = get_user(tempword, (__u16 __user*)argp); - if (result) { - DEBUG("result = %d failed to get_user\n", result); - break; - } - if (tempword == DSPBCMSGID) { - /* Search for matching file object */ - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - ft1000dev->app_info[i].DspBCMsgFlag = 1; - DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); - break; - } - } - } - break; - - case IOCTL_GET_VER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); - - get_ver_data.drv_ver = FT1000_DRV_VER; - - if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - - DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); - - break; - case IOCTL_CONNECT: - /* Connect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); - ConnectionMsg[79] = 0xfc; - result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - - break; - case IOCTL_DISCONNECT: - /* Disconnect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); - ConnectionMsg[79] = 0xfd; - result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - break; - case IOCTL_GET_DSP_STAT_CMD: - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */ - memset(&get_stat_data, 0, sizeof(get_stat_data)); - memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); - memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); - memcpy(get_stat_data.Sku, info->Sku, SKUSZ); - memcpy(get_stat_data.eui64, info->eui64, EUISZ); - - if (info->ProgConStat != 0xFF) { - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); - get_stat_data.LedStat = ntohs(ledStat); - DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); - get_stat_data.ConStat = ntohs(conStat); - DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); - } else { - get_stat_data.ConStat = 0x0f; - } - - - get_stat_data.nTxPkts = info->stats.tx_packets; - get_stat_data.nRxPkts = info->stats.rx_packets; - get_stat_data.nTxBytes = info->stats.tx_bytes; - get_stat_data.nRxBytes = info->stats.rx_bytes; - do_gettimeofday(&tv); - get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); - DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); - if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); - break; - case IOCTL_SET_DPRAM_CMD: - { + cmd = _IOC_NR(command); + /* DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); */ + + /* process the command */ + switch (cmd) { + case IOCTL_REGISTER_CMD: + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); + result = get_user(tempword, (__u16 __user *)argp); + if (result) { + DEBUG("result = %d failed to get_user\n", result); + break; + } + if (tempword == DSPBCMSGID) { + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + ft1000dev->app_info[i].DspBCMsgFlag = 1; + DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); + break; + } + } + } + break; + + case IOCTL_GET_VER_CMD: + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); + + get_ver_data.drv_ver = FT1000_DRV_VER; + + if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } + + DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n", (unsigned int)get_ver_data.drv_ver); + + break; + case IOCTL_CONNECT: + /* Connect Message */ + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); + ConnectionMsg[79] = 0xfc; + result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + + break; + case IOCTL_DISCONNECT: + /* Disconnect Message */ + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); + ConnectionMsg[79] = 0xfd; + result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + break; + case IOCTL_GET_DSP_STAT_CMD: + /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */ + memset(&get_stat_data, 0, sizeof(get_stat_data)); + memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); + memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); + memcpy(get_stat_data.Sku, info->Sku, SKUSZ); + memcpy(get_stat_data.eui64, info->eui64, EUISZ); + + if (info->ProgConStat != 0xFF) { + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); + get_stat_data.LedStat = ntohs(ledStat); + DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); + get_stat_data.ConStat = ntohs(conStat); + DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); + } else { + get_stat_data.ConStat = 0x0f; + } + + + get_stat_data.nTxPkts = info->stats.tx_packets; + get_stat_data.nRxPkts = info->stats.rx_packets; + get_stat_data.nTxBytes = info->stats.tx_bytes; + get_stat_data.nRxBytes = info->stats.rx_bytes; + do_gettimeofday(&tv); + get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); + DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); + if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } + DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); + break; + case IOCTL_SET_DPRAM_CMD: + { struct IOCTL_DPRAM_BLK *dpram_data = NULL; /* struct IOCTL_DPRAM_COMMAND dpram_command; */ - u16 qtype; - u16 msgsz; + u16 qtype; + u16 msgsz; struct pseudo_hdr *ppseudo_hdr; - u16 *pmsg; - u16 total_len; - u16 app_index; - u16 status; + u16 *pmsg; + u16 total_len; + u16 app_index; + u16 status; - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/ + /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/ - if (ft1000_flarion_cnt == 0) - return -EBADF; + if (ft1000_flarion_cnt == 0) + return -EBADF; - if (ft1000dev->DrvMsgPend) - return -ENOTTY; + if (ft1000dev->DrvMsgPend) + return -ENOTTY; - if (ft1000dev->fProvComplete == 0) - return -EACCES; + if (ft1000dev->fProvComplete == 0) + return -EACCES; - ft1000dev->fAppMsgPend = 1; + ft1000dev->fAppMsgPend = 1; - if (info->CardReady) { + if (info->CardReady) { - /* DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); */ + /* DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); */ - /* Get the length field to see how many bytes to copy */ - result = get_user(msgsz, (__u16 __user *)argp); - if (result) - break; - msgsz = ntohs(msgsz); - /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ - - if (msgsz > MAX_CMD_SQSIZE) { - DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); - result = -EINVAL; - break; - } - - result = -ENOMEM; - dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); - if (!dpram_data) - break; + /* Get the length field to see how many bytes to copy */ + result = get_user(msgsz, (__u16 __user *)argp); + if (result) + break; + msgsz = ntohs(msgsz); + /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ + + if (msgsz > MAX_CMD_SQSIZE) { + DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); + result = -EINVAL; + break; + } - if (copy_from_user(dpram_data, argp, msgsz+2)) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); - result = -EFAULT; - } else { - /* Check if this message came from a registered application */ - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - break; - } - } - if (i==MAX_NUM_APP) { - DEBUG("FT1000:No matching application fileobject\n"); - result = -EINVAL; - kfree(dpram_data); - break; - } - app_index = i; - - /* Check message qtype type which is the lower byte within qos_class */ - qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; - /* DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); */ - if (qtype) { - } else { - /* Put message into Slow Queue */ - /* Only put a message into the DPRAM if msg doorbell is available */ - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - /* DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); */ - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 2ms and try again due to DSP doorbell busy */ - mdelay(2); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 1ms and try again due to DSP doorbell busy */ - mdelay(1); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - /* Suspend for 3ms and try again due to DSP doorbell busy */ - mdelay(3); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); - result = -ENOTTY; - kfree(dpram_data); - break; - } - } - } - } - } - - /*DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); */ - - /* Make sure we are within the limits of the slow queue memory limitation */ - if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) { - /* Need to put sequence number plus new checksum for message */ - pmsg = (u16 *)&dpram_data->pseudohdr; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - total_len = msgsz+2; - if (total_len & 0x1) { - total_len++; - } - - /* Insert slow queue sequence number */ - ppseudo_hdr->seq_num = info->squeseqnum++; - ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id; - /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ - } - pmsg++; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - result = card_send_command(ft1000dev,(unsigned short*)dpram_data,total_len+2); - - - ft1000dev->app_info[app_index].nTxMsg++; - } else { - result = -EINVAL; - } - } - } - } else { - DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); - result = -EACCES; - } - kfree(dpram_data); - - } - break; - case IOCTL_GET_DPRAM_CMD: - { + result = -ENOMEM; + dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); + if (!dpram_data) + break; + + if (copy_from_user(dpram_data, argp, msgsz+2)) { + DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + result = -EFAULT; + } else { + /* Check if this message came from a registered application */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + break; + } + } + if (i == MAX_NUM_APP) { + DEBUG("FT1000:No matching application fileobject\n"); + result = -EINVAL; + kfree(dpram_data); + break; + } + app_index = i; + + /* Check message qtype type which is the lower byte within qos_class */ + qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; + /* DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); */ + if (qtype) { + } else { + /* Put message into Slow Queue */ + /* Only put a message into the DPRAM if msg doorbell is available */ + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + /* DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); */ + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 2ms and try again due to DSP doorbell busy */ + mdelay(2); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 1ms and try again due to DSP doorbell busy */ + mdelay(1); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + /* Suspend for 3ms and try again due to DSP doorbell busy */ + mdelay(3); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); + result = -ENOTTY; + kfree(dpram_data); + break; + } + } + } + } + } + + /*DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); */ + + /* Make sure we are within the limits of the slow queue memory limitation */ + if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) { + /* Need to put sequence number plus new checksum for message */ + pmsg = (u16 *)&dpram_data->pseudohdr; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + total_len = msgsz+2; + if (total_len & 0x1) { + total_len++; + } + + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + for (i = 1; i < 7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + } + pmsg++; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + result = card_send_command(ft1000dev, (unsigned short *)dpram_data, total_len+2); + + + ft1000dev->app_info[app_index].nTxMsg++; + } else { + result = -EINVAL; + } + } + } + } else { + DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); + result = -EACCES; + } + kfree(dpram_data); + + } + break; + case IOCTL_GET_DPRAM_CMD: + { struct dpram_blk *pdpram_blk; struct IOCTL_DPRAM_BLK __user *pioctl_dpram; - int msglen; - - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ - - if (ft1000_flarion_cnt == 0) - return -EBADF; - - /* Search for matching file object */ - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - /*DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ - break; - } - } - - /* Could not find application info block */ - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - result = -EBADF; - break; - } - - result = 0; - pioctl_dpram = argp; - if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - /* DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); */ - spin_lock_irqsave(&free_buff_lock, flags); - pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000dev->app_info[i].NumOfMsg--; - /* DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ - spin_unlock_irqrestore(&free_buff_lock, flags); - msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; - result = get_user(msglen, &pioctl_dpram->total_len); - if (result) - break; - msglen = htons(msglen); - /* DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); */ - if (copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; + int msglen; + + /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ + + if (ft1000_flarion_cnt == 0) + return -EBADF; + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + /*DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + break; + } + } + + /* Could not find application info block */ + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + result = -EBADF; break; - } + } + + result = 0; + pioctl_dpram = argp; + if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { + /* DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); */ + spin_lock_irqsave(&free_buff_lock, flags); + pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000dev->app_info[i].NumOfMsg--; + /* DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ + spin_unlock_irqrestore(&free_buff_lock, flags); + msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; + result = get_user(msglen, &pioctl_dpram->total_len); + if (result) + break; + msglen = htons(msglen); + /* DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); */ + if (copy_to_user(&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } - ft1000_free_buffer(pdpram_blk, &freercvpool); - result = msglen; - } - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); */ - } - break; - - default: - DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); - result = -ENOTTY; - break; - } - ft1000dev->fAppMsgPend = 0; - return result; + ft1000_free_buffer(pdpram_blk, &freercvpool); + result = msglen; + } + /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); */ + } + break; + + default: + DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); + result = -ENOTTY; + break; + } + ft1000dev->fAppMsgPend = 0; + return result; } /* -*--------------------------------------------------------------------------- -* Function: ft1000_release -* -* Parameters: -* -* Description: -* -* Notes: -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * Function: ft1000_release + * + * Parameters: + * + * Description: + * + * Notes: + * + *--------------------------------------------------------------------------- + */ static int ft1000_release(struct inode *inode, struct file *file) { struct ft1000_info *info; - struct net_device *dev; - struct ft1000_usb *ft1000dev; - int i; + struct net_device *dev; + struct ft1000_usb *ft1000dev; + int i; struct dpram_blk *pdpram_blk; - DEBUG("ft1000_release called\n"); + DEBUG("ft1000_release called\n"); - dev = file->private_data; + dev = file->private_data; info = netdev_priv(dev); ft1000dev = info->priv; - if (ft1000_flarion_cnt == 0) { - ft1000dev->appcnt--; - return -EBADF; - } - - /* Search for matching file object */ - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ - break; - } - } - - if (i==MAX_NUM_APP) - return 0; - - while (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - DEBUG("Remove and free memory queue up on slow queue\n"); - pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - - /* initialize application information */ - ft1000dev->appcnt--; - DEBUG("ft1000_chdev:%s:appcnt = %d\n", __func__, ft1000dev->appcnt); - ft1000dev->app_info[i].fileobject = NULL; - - return 0; + if (ft1000_flarion_cnt == 0) { + ft1000dev->appcnt--; + return -EBADF; + } + + /* Search for matching file object */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (ft1000dev->app_info[i].fileobject == &file->f_owner) { + /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + break; + } + } + + if (i == MAX_NUM_APP) + return 0; + + while (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { + DEBUG("Remove and free memory queue up on slow queue\n"); + pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + } + + /* initialize application information */ + ft1000dev->appcnt--; + DEBUG("ft1000_chdev:%s:appcnt = %d\n", __func__, ft1000dev->appcnt); + ft1000dev->app_info[i].fileobject = NULL; + + return 0; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index fe882bd69e38..2cce4224485b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -1,8 +1,8 @@ /* -* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -* -* This file is part of Express Card USB Driver -*/ + * CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. + * + * This file is part of Express Card USB Driver + */ #include #include @@ -117,17 +117,17 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) while (loopcnt < 10) { status = ft1000_read_register(ft1000dev, &temp, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", - temp); + temp); if (temp & 0x0080) { DEBUG("FT1000:Got checkusb doorbell\n"); status = ft1000_write_register(ft1000dev, 0x0080, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); status = ft1000_write_register(ft1000dev, 0x0100, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); status = ft1000_write_register(ft1000dev, 0x8000, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); break; } loopcnt++; @@ -138,7 +138,7 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) loopcnt = 0; while (loopcnt < 20) { status = ft1000_read_register(ft1000dev, &temp, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp); if (temp & 0x8000) { loopcnt++; @@ -164,10 +164,10 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) while (loopcnt < 100) { /* Need to clear downloader doorbell if Hartley ASIC */ status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (ft1000dev->fcodeldr) { DEBUG(" get_handshake: fcodeldr is %d\n", - ft1000dev->fcodeldr); + ft1000dev->fcodeldr); ft1000dev->fcodeldr = 0; status = check_usb_db(ft1000dev); if (status != 0) { @@ -175,12 +175,12 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) break; } status = ft1000_write_register(ft1000dev, - FT1000_DB_DNLD_RX, - FT1000_REG_DOORBELL); + FT1000_DB_DNLD_RX, + FT1000_REG_DOORBELL); } status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); + DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); handshake = ntohs(handshake); if (status) @@ -209,12 +209,12 @@ static void put_handshake(struct ft1000_usb *ft1000dev, u16 handshake_value) tempword = (u16)(tempx & 0xffff); status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, - tempword, 0); + tempword, 0); tempword = (u16)(tempx >> 16); status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, - tempword, 1); + tempword, 1); status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); } static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) @@ -230,27 +230,27 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) while (loopcnt < 100) { if (ft1000dev->usbboot == 2) { status = ft1000_read_dpram32(ft1000dev, 0, - (u8 *)&(ft1000dev->tempbuf[0]), 64); + (u8 *)&(ft1000dev->tempbuf[0]), 64); for (temp = 0; temp < 16; temp++) { DEBUG("tempbuf %d = 0x%x\n", temp, - ft1000dev->tempbuf[temp]); + ft1000dev->tempbuf[temp]); } status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, - (u8 *)&handshake, 1); + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); DEBUG("handshake from read_dpram16 = 0x%x\n", - handshake); + handshake); if (ft1000dev->dspalive == ft1000dev->tempbuf[6]) { handshake = 0; } else { handshake = ft1000dev->tempbuf[1]; ft1000dev->dspalive = - ft1000dev->tempbuf[6]; + ft1000dev->tempbuf[6]; } } else { status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_HANDSHAKE_LOC, - (u8 *)&handshake, 1); + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); } loopcnt++; @@ -281,12 +281,12 @@ static u16 get_request_type(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else { tempx = 0; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); tempx |= (tempword << 16); tempx = ntohl(tempx); } @@ -304,7 +304,7 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else { if (ft1000dev->usbboot == 2) { @@ -313,8 +313,8 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev) } else { tempx = 0; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_TYPE_LOC, - (u8 *)&tempword, 1); + DWNLD_MAG1_TYPE_LOC, + (u8 *)&tempword, 1); } tempx |= (tempword << 16); tempx = ntohl(tempx); @@ -332,14 +332,14 @@ static long get_request_value(struct ft1000_usb *ft1000dev) if (ft1000dev->bootmode == 1) { status = fix_ft1000_read_dpram32(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&value); + DWNLD_MAG1_SIZE_LOC, (u8 *)&value); value = ntohl(value); } else { status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); value = tempword; status = ft1000_read_dpram16(ft1000dev, - DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); value |= (tempword << 16); value = ntohl(value); } @@ -369,7 +369,7 @@ static u16 hdr_checksum(struct pseudo_hdr *pHdr) chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ - usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); + usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); return chksum; } @@ -387,7 +387,7 @@ static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset) } static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, - u16 tempbuffer[], u16 dpram) + u16 tempbuffer[], u16 dpram) { int status; u16 resultbuffer[64]; @@ -395,37 +395,37 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, for (i = 0; i < 10; i++) { status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 64); + (u8 *)&tempbuffer[0], 64); if (status == 0) { /* Work around for ASIC bit stuffing problem. */ if ((tempbuffer[31] & 0xfe00) == 0xfe00) { status = ft1000_write_dpram32(ft1000dev, - dpram+12, (u8 *)&tempbuffer[24], - 64); + dpram+12, (u8 *)&tempbuffer[24], + 64); } /* Let's check the data written */ status = ft1000_read_dpram32(ft1000dev, dpram, - (u8 *)&resultbuffer[0], 64); + (u8 *)&resultbuffer[0], 64); if ((tempbuffer[31] & 0xfe00) == 0xfe00) { if (check_buffers(tempbuffer, resultbuffer, 28, - 0)) { + 0)) { DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n"); usleep_range(9000, 11000); break; } status = ft1000_read_dpram32(ft1000dev, - dpram+12, - (u8 *)&resultbuffer[0], 64); + dpram+12, + (u8 *)&resultbuffer[0], 64); if (check_buffers(tempbuffer, resultbuffer, 16, - 24)) { + 24)) { DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n"); usleep_range(9000, 11000); break; } } else { if (check_buffers(tempbuffer, resultbuffer, 32, - 0)) { + 0)) { DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n"); usleep_range(9000, 11000); break; @@ -445,7 +445,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, * long word_length - length of the buffer to be written to DPRAM */ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, - long word_length) + long word_length) { int status = 0; u16 dpram; @@ -489,13 +489,13 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, if (ft1000dev->bootmode == 0) { if (dpram >= 0x3F4) status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 8); + (u8 *)&tempbuffer[0], 8); else status = ft1000_write_dpram32(ft1000dev, dpram, - (u8 *)&tempbuffer[0], 64); + (u8 *)&tempbuffer[0], 64); } else { status = write_dpram32_and_check(ft1000dev, tempbuffer, - dpram); + dpram); if (status != 0) { DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]); break; @@ -548,7 +548,7 @@ static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile, } static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake, - u32 *state) + u32 *state) { int status = 0; @@ -571,7 +571,7 @@ static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake, } static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, - u8 **c_file, const u8 *endpoint, bool boot_case) + u8 **c_file, const u8 *endpoint, bool boot_case) { long word_length; int status = 0; @@ -602,7 +602,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, ft1000dev->usbboot++; if (ft1000dev->usbboot == 1) status |= ft1000_write_dpram16(ft1000dev, - DWNLD_MAG1_PS_HDR_LOC, 0, 0); + DWNLD_MAG1_PS_HDR_LOC, 0, 0); } return status; } @@ -705,14 +705,14 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case REQUEST_CODE_SEGMENT: status = request_code_segment(ft1000dev, - &s_file, &c_file, - (const u8 *)boot_end, - true); - break; + &s_file, &c_file, + (const u8 *)boot_end, + true); + break; default: DEBUG - ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", - request); + ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", + request); status = -1; break; } @@ -724,7 +724,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, HANDSHAKE_RESPONSE); } else { DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + ("FT1000:download:Download error: Handshake failed\n"); status = -1; } @@ -735,56 +735,56 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, ft1000dev->bootmode = 0; if (ft1000dev->usbboot) handshake = - get_handshake_usb(ft1000dev, - HANDSHAKE_REQUEST); + get_handshake_usb(ft1000dev, + HANDSHAKE_REQUEST); else handshake = - get_handshake(ft1000dev, HANDSHAKE_REQUEST); + get_handshake(ft1000dev, HANDSHAKE_REQUEST); if (handshake == HANDSHAKE_REQUEST) { /* * Get type associated with the request. */ if (ft1000dev->usbboot) request = - get_request_type_usb(ft1000dev); + get_request_type_usb(ft1000dev); else request = get_request_type(ft1000dev); switch (request) { case REQUEST_FILE_CHECKSUM: DEBUG - ("FT1000:download:image_chksum = 0x%8x\n", - image_chksum); + ("FT1000:download:image_chksum = 0x%8x\n", + image_chksum); put_request_value(ft1000dev, image_chksum); break; case REQUEST_RUN_ADDRESS: DEBUG - ("FT1000:download: REQUEST_RUN_ADDRESS\n"); + ("FT1000:download: REQUEST_RUN_ADDRESS\n"); if (correct_version) { DEBUG - ("FT1000:download:run_address = 0x%8x\n", - (int)run_address); + ("FT1000:download:run_address = 0x%8x\n", + (int)run_address); put_request_value(ft1000dev, run_address); } else { DEBUG - ("FT1000:download:Download error: Got Run address request before image offset request.\n"); + ("FT1000:download:Download error: Got Run address request before image offset request.\n"); status = -1; break; } break; case REQUEST_CODE_LENGTH: DEBUG - ("FT1000:download:REQUEST_CODE_LENGTH\n"); + ("FT1000:download:REQUEST_CODE_LENGTH\n"); if (correct_version) { DEBUG - ("FT1000:download:run_size = 0x%8x\n", - (int)run_size); + ("FT1000:download:run_size = 0x%8x\n", + (int)run_size); put_request_value(ft1000dev, run_size); } else { DEBUG - ("FT1000:download:Download error: Got Size request before image offset request.\n"); + ("FT1000:download:Download error: Got Size request before image offset request.\n"); status = -1; break; } @@ -793,47 +793,47 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, ft1000dev->usbboot = 3; /* Reposition ptrs to beginning of provisioning section */ s_file = - (u16 *) (pFileStart + - file_hdr->commands_offset); + (u16 *) (pFileStart + + file_hdr->commands_offset); c_file = - (u8 *) (pFileStart + - file_hdr->commands_offset); + (u8 *) (pFileStart + + file_hdr->commands_offset); state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */ if (!correct_version) { DEBUG - ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); + ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); status = -1; break; } status = request_code_segment(ft1000dev, - &s_file, &c_file, - (const u8 *)code_end, - false); + &s_file, &c_file, + (const u8 *)code_end, + false); break; case REQUEST_MAILBOX_DATA: DEBUG - ("FT1000:download: REQUEST_MAILBOX_DATA\n"); + ("FT1000:download: REQUEST_MAILBOX_DATA\n"); /* Convert length from byte count to word count. Make sure we round up. */ word_length = - (long)(pft1000info->DSPInfoBlklen + - 1) / 2; + (long)(pft1000info->DSPInfoBlklen + + 1) / 2; put_request_value(ft1000dev, word_length); mailbox_data = - (struct drv_msg *)&(pft1000info-> - DSPInfoBlk[0]); + (struct drv_msg *)&(pft1000info-> + DSPInfoBlk[0]); /* * Position ASIC DPRAM auto-increment pointer. */ - data = (u16 *) &mailbox_data->data[0]; - dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + data = (u16 *)&mailbox_data->data[0]; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -844,18 +844,18 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, templong = *data++; templong |= (*data++ << 16); status = - fix_ft1000_write_dpram32 - (ft1000dev, dpram++, - (u8 *) &templong); + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *)&templong); } break; case REQUEST_VERSION_INFO: DEBUG - ("FT1000:download:REQUEST_VERSION_INFO\n"); + ("FT1000:download:REQUEST_VERSION_INFO\n"); word_length = - file_hdr->version_data_size; + file_hdr->version_data_size; put_request_value(ft1000dev, word_length); /* @@ -863,11 +863,11 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, */ s_file = - (u16 *) (pFileStart + - file_hdr-> - version_data_offset); + (u16 *) (pFileStart + + file_hdr-> + version_data_offset); - dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -879,26 +879,26 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, temp = ntohs(*s_file++); templong |= (temp << 16); status = - fix_ft1000_write_dpram32 - (ft1000dev, dpram++, - (u8 *) &templong); + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *)&templong); } break; case REQUEST_CODE_BY_VERSION: DEBUG - ("FT1000:download:REQUEST_CODE_BY_VERSION\n"); + ("FT1000:download:REQUEST_CODE_BY_VERSION\n"); correct_version = false; requested_version = - get_request_value(ft1000dev); + get_request_value(ft1000dev); dsp_img_info = - (struct dsp_image_info *)(pFileStart - + - sizeof - (struct - dsp_file_hdr)); + (struct dsp_image_info *)(pFileStart + + + sizeof + (struct + dsp_file_hdr)); for (image = 0; image < file_hdr->nDspImages; @@ -908,29 +908,29 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, requested_version) { correct_version = true; DEBUG - ("FT1000:download: correct_version is TRUE\n"); + ("FT1000:download: correct_version is TRUE\n"); s_file = - (u16 *) (pFileStart - + - dsp_img_info-> - begin_offset); + (u16 *) (pFileStart + + + dsp_img_info-> + begin_offset); c_file = - (u8 *) (pFileStart + - dsp_img_info-> - begin_offset); + (u8 *) (pFileStart + + dsp_img_info-> + begin_offset); code_end = - (u8 *) (pFileStart + - dsp_img_info-> - end_offset); + (u8 *) (pFileStart + + dsp_img_info-> + end_offset); run_address = - dsp_img_info-> - run_address; + dsp_img_info-> + run_address; run_size = - dsp_img_info-> - image_size; + dsp_img_info-> + image_size; image_chksum = - (u32) dsp_img_info-> - checksum; + (u32)dsp_img_info-> + checksum; break; } dsp_img_info++; @@ -942,8 +942,8 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, * Error, beyond boot code range. */ DEBUG - ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", - (int)requested_version); + ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", + (int)requested_version); status = -1; break; } @@ -951,8 +951,8 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, default: DEBUG - ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", - request); + ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", + request); status = -1; break; } @@ -964,7 +964,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, HANDSHAKE_RESPONSE); } else { DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + ("FT1000:download:Download error: Handshake failed\n"); status = -1; } @@ -990,9 +990,9 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Get buffer for provisioning data */ pbuffer = - kmalloc((pseudo_header_len + - sizeof(struct pseudo_hdr)), - GFP_ATOMIC); + kmalloc((pseudo_header_len + + sizeof(struct pseudo_hdr)), + GFP_ATOMIC); if (pbuffer) { memcpy(pbuffer, (void *)c_file, (u32) (pseudo_header_len + @@ -1000,20 +1000,20 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, pseudo_hdr))); /* link provisioning data */ pprov_record = - kmalloc(sizeof(struct prov_record), - GFP_ATOMIC); + kmalloc(sizeof(struct prov_record), + GFP_ATOMIC); if (pprov_record) { pprov_record->pprov_data = - pbuffer; + pbuffer; list_add_tail(&pprov_record-> list, &pft1000info-> prov_list); /* Move to next entry if available */ c_file = - (u8 *) ((unsigned long) - c_file + - (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + (u8 *) ((unsigned long) + c_file + + (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ((unsigned long)(c_file) - (unsigned long)(pFileStart) >= @@ -1032,8 +1032,8 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, status = -1; } DEBUG - ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", - state, status); + ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", + state, status); break; case STATE_DONE_PROV: @@ -1050,16 +1050,16 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; /**** - // Check if Card is present - status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); - if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { - break; - } - - status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); - if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { - break; - } + // Check if Card is present + status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { + break; + } + + status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { + break; + } ****/ } /* End while */ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 2e13e7b7ec10..da1195574640 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1,8 +1,8 @@ /* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -* -* -* This file is part of Express Card USB Driver -*/ + * + * + * This file is part of Express Card USB Driver + */ #include #include @@ -35,16 +35,16 @@ static u8 tempbuffer[1600]; #define MAX_RCV_LOOP 100 /* send a control message via USB interface synchronously -* Parameters: ft1000_usb - device structure -* pipe - usb control message pipe -* request - control request -* requesttype - control message request type -* value - value to be written or 0 -* index - register index -* data - data buffer to hold the read/write values -* size - data size -* timeout - control message time out value -*/ + * Parameters: ft1000_usb - device structure + * pipe - usb control message pipe + * request - control request + * requesttype - control message request type + * value - value to be written or 0 + * index - register index + * data - data buffer to hold the read/write values + * size - data size + * timeout - control message time out value + */ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout) @@ -171,7 +171,7 @@ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, /* write into DPRAM a number of bytes */ int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, - u8 highlow) + u8 highlow) { int ret = 0; u8 request; @@ -287,7 +287,7 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) u16 tempword; status = ft1000_write_register(ft1000dev, HOST_INTF_BE, - FT1000_REG_SUP_CTRL); + FT1000_REG_SUP_CTRL); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_CTRL); @@ -318,12 +318,12 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) } /* send a command to ASIC -* Parameters: ft1000_usb - device structure -* ptempbuffer - command buffer -* size - command buffer size -*/ + * Parameters: ft1000_usb - device structure + * ptempbuffer - command buffer + * size - command buffer size + */ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, - int size) + int size) { int ret; unsigned short temp; @@ -355,7 +355,7 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, return ret; usleep_range(900, 1100); ret = ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (ret) return ret; usleep_range(900, 1100); @@ -399,12 +399,12 @@ int dsp_reload(struct ft1000_usb *ft1000dev) msleep(1000); status = - ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); + ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); /* Let's check for FEFE */ status = - ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, - (u8 *) &templong, 4); + ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, + (u8 *)&templong, 4); DEBUG("templong (fefe) = 0x%8x\n", templong); /* call codeloader */ @@ -465,7 +465,7 @@ static int ft1000_reset_card(struct net_device *dev) while (list_empty(&info->prov_list) == 0) { DEBUG("ft1000_reset_card:deleting provisioning record\n"); ptr = - list_entry(info->prov_list.next, struct prov_record, list); + list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); @@ -484,7 +484,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Initialize DSP heartbeat area */ ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *) &tempword, + ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX); DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); @@ -508,8 +508,8 @@ static void ft1000_usb_transmit_complete(struct urb *urb) } /* take an ethernet packet and convert it to a Flarion -* packet prior to sending it to the ASIC Downlink FIFO. -*/ + * packet prior to sending it to the ASIC Downlink FIFO. + */ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) { struct ft1000_info *pInfo = netdev_priv(netdev); @@ -545,7 +545,7 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) hdr.control = 0x00; hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^ - hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control; + hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control; memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr)); memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len); @@ -559,7 +559,7 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) pFt1000Dev->tx_buf, count, ft1000_usb_transmit_complete, (void *)pFt1000Dev); - t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer; + t = (u8 *)pFt1000Dev->tx_urb->transfer_buffer; ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC); @@ -574,9 +574,9 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) } /* transmit an ethernet packet -* Parameters: skb - socket buffer to be sent -* dev - network device -*/ + * Parameters: skb - socket buffer to be sent + * dev - network device + */ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -595,10 +595,10 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) } pipe = - usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); + usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe)); - pdata = (u8 *) skb->data; + pdata = (u8 *)skb->data; if (pInfo->mediastate == 0) { /* Drop packet is mediastate is down */ @@ -814,8 +814,8 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, } /* take a packet from the FIFO up link and -* convert it into an ethernet packet and deliver it to the IP stack -*/ + * convert it into an ethernet packet and deliver it to the IP stack + */ static int ft1000_copy_up_pkt(struct urb *urb) { struct ft1000_info *info = urb->context; @@ -839,7 +839,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) len = urb->transfer_buffer_length; lena = urb->actual_length; - chksum = (u16 *) ft1000dev->rx_buf; + chksum = (u16 *)ft1000dev->rx_buf; tempword = *chksum++; for (i = 1; i < 7; i++) @@ -860,7 +860,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) return -1; } - pbuffer = (u8 *) skb_put(skb, len + 12); + pbuffer = (u8 *)skb_put(skb, len + 12); /* subtract the number of bytes read already */ ptemp = pbuffer; @@ -914,7 +914,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) usb_rcvbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_in_endpointAddr), pFt1000Dev->rx_buf, MAX_BUF_SIZE, - (usb_complete_t) ft1000_copy_up_pkt, info); + (usb_complete_t)ft1000_copy_up_pkt, info); result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC); @@ -976,10 +976,10 @@ static int ft1000_chkcard(struct ft1000_usb *dev) } /* read a message from the dpram area. -* Input: -* dev - network device structure -* pbuffer - caller supply address to buffer -*/ + * Input: + * dev - network device structure + * pbuffer - caller supply address to buffer + */ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, int maxsz) { @@ -990,46 +990,46 @@ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, u16 tempword; ret = - ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *) &size, - FT1000_MAG_PH_LEN_INDX); + ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, + FT1000_MAG_PH_LEN_INDX); size = ntohs(size) + PSEUDOSZ; if (size > maxsz) { DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size); return FALSE; } - ppseudohdr = (u16 *) pbuffer; + ppseudohdr = (u16 *)pbuffer; ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE, FT1000_REG_DPRAM_ADDR); ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE + 1, FT1000_REG_DPRAM_ADDR); for (i = 0; i <= (size >> 2); i++) { ret = - ft1000_read_register(dev, pbuffer, - FT1000_REG_MAG_DPDATAL); + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAL); pbuffer++; ret = - ft1000_read_register(dev, pbuffer, - FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAH); pbuffer++; } /* copy odd aligned word */ ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); pbuffer++; ret = - ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; if (size & 0x0001) { /* copy odd byte from fifo */ ret = - ft1000_read_register(dev, &tempword, - FT1000_REG_DPRAM_DATA); + ft1000_read_register(dev, &tempword, + FT1000_REG_DPRAM_DATA); *pbuffer = ntohs(tempword); } /* Check if pseudo header checksum is good @@ -1066,7 +1066,7 @@ static int ft1000_dsp_prov(void *arg) /* Check if doorbell is available */ DEBUG("check if doorbell is cleared\n"); status = - ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); + ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); if (status) { DEBUG("ft1000_dsp_prov::ft1000_read_register error\n"); break; @@ -1088,13 +1088,13 @@ static int ft1000_dsp_prov(void *arg) /* Send provisioning data */ ptr = - list_entry(info->prov_list.next, struct prov_record, - list); - len = *(u16 *) ptr->pprov_data; + list_entry(info->prov_list.next, struct prov_record, + list); + len = *(u16 *)ptr->pprov_data; len = htons(len); len += PSEUDOSZ; - pmsg = (u16 *) ptr->pprov_data; + pmsg = (u16 *)ptr->pprov_data; ppseudo_hdr = (struct pseudo_hdr *)pmsg; /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; @@ -1109,12 +1109,12 @@ static int ft1000_dsp_prov(void *arg) memcpy(&TempShortBuf[2], ppseudo_hdr, len); status = - ft1000_write_dpram32(dev, 0, - (u8 *) &TempShortBuf[0], - (unsigned short)(len + 2)); + ft1000_write_dpram32(dev, 0, + (u8 *)&TempShortBuf[0], + (unsigned short)(len + 2)); status = - ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); list_del(&ptr->list); kfree(ptr->pprov_data); @@ -1229,12 +1229,12 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) if (ntohs(pdspinitmsg->length) == (sizeof(struct dsp_init_msg) - 20)) { memcpy(info->ProductMode, pdspinitmsg->ProductMode, - MODESZ); + MODESZ); memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ); DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], - info->RfCalVer[1]); + info->RfCalVer[1]); } break; } @@ -1252,7 +1252,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) } else { dev->fProvComplete = true; status = ft1000_write_register(dev, FT1000_DB_HB, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); } DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); @@ -1264,7 +1264,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) &pdrvmsg->data[0]; + pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; @@ -1281,27 +1281,27 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) /* allow any outstanding ioctl to finish */ mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) break; } } /* Put message into Slow Queue Form Pseudo header */ - pmsg = (u16 *) info->DSPInfoBlk; + pmsg = (u16 *)info->DSPInfoBlk; *pmsg++ = 0; *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen); ppseudo_hdr = - (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; + (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2]; ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4 - + info->DSPInfoBlklen); + + info->DSPInfoBlklen); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; ppseudo_hdr->portdest = 0; @@ -1323,10 +1323,10 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) info->DSPInfoBlk[10] = 0x7200; info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); status = ft1000_write_dpram32(dev, 0, - (u8 *)&info->DSPInfoBlk[0], - (unsigned short)(info->DSPInfoBlklen + 22)); + (u8 *)&info->DSPInfoBlk[0], + (unsigned short)(info->DSPInfoBlklen + 22)); status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); dev->DrvMsgPend = 0; break; } @@ -1337,17 +1337,17 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) /* allow any outstanding ioctl to finish */ mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); status = ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) mdelay(10); } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { /* Put message into Slow Queue Form Pseudo header */ - pmsg = (u16 *) &tempbuffer[0]; + pmsg = (u16 *)&tempbuffer[0]; ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; @@ -1368,7 +1368,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - pmsg = (u16 *) &tempbuffer[16]; + pmsg = (u16 *)&tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1384,7 +1384,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) *pmsg++ = htons(info->DrvErrNum); status = card_send_command(dev, (unsigned char *)&tempbuffer[0], - (u16)(0x0012 + PSEUDOSZ)); + (u16)(0x0012 + PSEUDOSZ)); if (status) goto out; info->DrvErrNum = 0; @@ -1412,9 +1412,9 @@ static int dsp_broadcast_msg_id(struct ft1000_usb *dev) for (i = 0; i < MAX_NUM_APP; i++) { if ((dev->app_info[i].DspBCMsgFlag) - && (dev->app_info[i].fileobject) - && (dev->app_info[i].NumOfMsg - < MAX_MSG_LIMIT)) { + && (dev->app_info[i].fileobject) + && (dev->app_info[i].NumOfMsg + < MAX_MSG_LIMIT)) { pdpram_blk = ft1000_get_buffer(&freercvpool); if (pdpram_blk == NULL) { DEBUG("Out of memory in free receive command pool\n"); @@ -1422,18 +1422,18 @@ static int dsp_broadcast_msg_id(struct ft1000_usb *dev) return -1; } if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer, - MAX_CMD_SQSIZE)) { + MAX_CMD_SQSIZE)) { /* Put message into the * appropriate application block */ dev->app_info[i].nRxMsg++; spin_lock_irqsave(&free_buff_lock, flags); list_add_tail(&pdpram_blk->list, - &dev->app_info[i] .app_sqlist); + &dev->app_info[i] .app_sqlist); dev->app_info[i].NumOfMsg++; spin_unlock_irqrestore(&free_buff_lock, flags); wake_up_interruptible(&dev->app_info[i] - .wait_dpram_msg); + .wait_dpram_msg); } else { dev->app_info[i].nRxMsgMiss++; ft1000_free_buffer(pdpram_blk, &freercvpool); @@ -1461,7 +1461,7 @@ static int handle_misc_portid(struct ft1000_usb *dev) /* Search for correct application block */ for (i = 0; i < MAX_NUM_APP; i++) { if (dev->app_info[i].app_id == ((struct pseudo_hdr *) - pdpram_blk->pbuffer)->portdest) + pdpram_blk->pbuffer)->portdest) break; } if (i == MAX_NUM_APP) { @@ -1502,14 +1502,14 @@ int ft1000_poll(void *dev_id) if (!status) { if (tempword & FT1000_DB_DPRAM_RX) { status = ft1000_read_dpram16(dev, - 0x200, (u8 *)&data, 0); + 0x200, (u8 *)&data, 0); size = ntohs(data) + 16 + 2; if (size % 4) { modulo = 4 - (size % 4); size = size + modulo; } status = ft1000_read_dpram16(dev, 0x201, - (u8 *)&portid, 1); + (u8 *)&portid, 1); portid &= 0xff; if (size < MAX_CMD_SQSIZE) { switch (portid) { @@ -1529,18 +1529,18 @@ int ft1000_poll(void *dev_id) } else DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); status = ft1000_write_register(dev, - FT1000_DB_DPRAM_RX, - FT1000_REG_DOORBELL); + FT1000_DB_DPRAM_RX, + FT1000_REG_DOORBELL); } else if (tempword & FT1000_DSP_ASIC_RESET) { /* Let's reset the ASIC from the Host side as well */ status = ft1000_write_register(dev, ASIC_RESET_BIT, - FT1000_REG_RESET); + FT1000_REG_RESET); status = ft1000_read_register(dev, &tempword, - FT1000_REG_RESET); + FT1000_REG_RESET); i = 0; while (tempword & ASIC_RESET_BIT) { status = ft1000_read_register(dev, &tempword, - FT1000_REG_RESET); + FT1000_REG_RESET); usleep_range(9000, 11000); i++; if (i == 100) @@ -1553,51 +1553,51 @@ int ft1000_poll(void *dev_id) usleep_range(9000, 11000); /* Program WMARK register */ status = ft1000_write_register(dev, 0x600, - FT1000_REG_MAG_WATERMARK); + FT1000_REG_MAG_WATERMARK); /* clear ASIC reset doorbell */ status = ft1000_write_register(dev, - FT1000_DSP_ASIC_RESET, - FT1000_REG_DOORBELL); + FT1000_DSP_ASIC_RESET, + FT1000_REG_DOORBELL); usleep_range(9000, 11000); } else if (tempword & FT1000_ASIC_RESET_REQ) { DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); /* clear ASIC reset request from DSP */ status = ft1000_write_register(dev, - FT1000_ASIC_RESET_REQ, - FT1000_REG_DOORBELL); + FT1000_ASIC_RESET_REQ, + FT1000_REG_DOORBELL); status = ft1000_write_register(dev, HOST_INTF_BE, - FT1000_REG_SUP_CTRL); + FT1000_REG_SUP_CTRL); /* copy dsp session record from Adapter block */ status = ft1000_write_dpram32(dev, 0, - (u8 *)&info->DSPSess.Rec[0], 1024); + (u8 *)&info->DSPSess.Rec[0], 1024); status = ft1000_write_register(dev, 0x600, - FT1000_REG_MAG_WATERMARK); + FT1000_REG_MAG_WATERMARK); /* ring doorbell to tell DSP that * ASIC is out of reset * */ status = ft1000_write_register(dev, - FT1000_ASIC_RESET_DSP, - FT1000_REG_DOORBELL); + FT1000_ASIC_RESET_DSP, + FT1000_REG_DOORBELL); } else if (tempword & FT1000_DB_COND_RESET) { DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); if (!dev->fAppMsgPend) { /* Reset ASIC and DSP */ status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER0, - (u8 *)&(info->DSP_TIME[0]), - FT1000_MAG_DSP_TIMER0_INDX); + FT1000_MAG_DSP_TIMER0, + (u8 *)&(info->DSP_TIME[0]), + FT1000_MAG_DSP_TIMER0_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER1, - (u8 *)&(info->DSP_TIME[1]), - FT1000_MAG_DSP_TIMER1_INDX); + FT1000_MAG_DSP_TIMER1, + (u8 *)&(info->DSP_TIME[1]), + FT1000_MAG_DSP_TIMER1_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER2, - (u8 *)&(info->DSP_TIME[2]), - FT1000_MAG_DSP_TIMER2_INDX); + FT1000_MAG_DSP_TIMER2, + (u8 *)&(info->DSP_TIME[2]), + FT1000_MAG_DSP_TIMER2_INDX); status = ft1000_read_dpram16(dev, - FT1000_MAG_DSP_TIMER3, - (u8 *)&(info->DSP_TIME[3]), - FT1000_MAG_DSP_TIMER3_INDX); + FT1000_MAG_DSP_TIMER3, + (u8 *)&(info->DSP_TIME[3]), + FT1000_MAG_DSP_TIMER3_INDX); info->CardReady = 0; info->DrvErrNum = DSP_CONDRESET_INFO; DEBUG("ft1000_hw:DSP conditional reset requested\n"); @@ -1607,7 +1607,7 @@ int ft1000_poll(void *dev_id) dev->fCondResetPend = true; } ft1000_write_register(dev, FT1000_DB_COND_RESET, - FT1000_REG_DOORBELL); + FT1000_REG_DOORBELL); } } return 0; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h index cb644a58d9f3..e9472bebda0b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h @@ -1,30 +1,30 @@ /* -*--------------------------------------------------------------------------- -* FT1000 driver for Flarion Flash OFDM NIC Device -* -* Copyright (C) 2002 Flarion Technologies, All rights reserved. -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2 of the License, or (at your option) any -* later version. This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 59 Temple Place - -* Suite 330, Boston, MA 02111-1307, USA. -*--------------------------------------------------------------------------- -* -* File: ft1000_ioctl.h -* -* Description: Common structures and defines relating to IOCTL -* -* History: -* 11/5/02 Whc Created. -* -*--------------------------------------------------------------------------- -*/ + *--------------------------------------------------------------------------- + * FT1000 driver for Flarion Flash OFDM NIC Device + * + * Copyright (C) 2002 Flarion Technologies, All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + *--------------------------------------------------------------------------- + * + * File: ft1000_ioctl.h + * + * Description: Common structures and defines relating to IOCTL + * + * History: + * 11/5/02 Whc Created. + * + *--------------------------------------------------------------------------- + */ #ifndef _FT1000IOCTLH_ #define _FT1000IOCTLH_ @@ -94,8 +94,8 @@ struct IOCTL_DPRAM_COMMAND { } __packed; /* -* Custom IOCTL command codes -*/ + * Custom IOCTL command codes + */ #define FT1000_MAGIC_CODE 'F' #define IOCTL_REGISTER_CMD 0 @@ -106,8 +106,8 @@ struct IOCTL_DPRAM_COMMAND { #define IOCTL_CONNECT 10 #define IOCTL_DISCONNECT 11 -#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, \ - IOCTL_GET_DSP_STAT_CMD, \ +#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, \ + IOCTL_GET_DSP_STAT_CMD, \ struct IOCTL_GET_DSP_STAT) #define IOCTL_FT1000_GET_VER _IOR(FT1000_MAGIC_CODE, IOCTL_GET_VER_CMD, \ struct IOCTL_GET_VER) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 39be30c0eedf..244e3d66d599 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -109,8 +109,8 @@ static int ft1000_probe(struct usb_interface *interface, for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = - (struct usb_endpoint_descriptor *)&iface_desc-> - endpoint[i].desc; + (struct usb_endpoint_descriptor *)&iface_desc-> + endpoint[i].desc; DEBUG("endpoint %d\n", i); DEBUG("bEndpointAddress=%x, bmAttributes=%x\n", endpoint->bEndpointAddress, endpoint->bmAttributes); @@ -118,7 +118,7 @@ static int ft1000_probe(struct usb_interface *interface, && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_in_endpointAddr = - endpoint->bEndpointAddress; + endpoint->bEndpointAddress; DEBUG("ft1000_probe: in: %d\n", endpoint->bEndpointAddress); } @@ -127,7 +127,7 @@ static int ft1000_probe(struct usb_interface *interface, && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_out_endpointAddr = - endpoint->bEndpointAddress; + endpoint->bEndpointAddress; DEBUG("ft1000_probe: out: %d\n", endpoint->bEndpointAddress); } @@ -172,7 +172,7 @@ static int ft1000_probe(struct usb_interface *interface, gPollingfailed = false; ft1000dev->pPollThread = - kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll"); + kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll"); if (IS_ERR(ft1000dev->pPollThread)) { ret = PTR_ERR(ft1000dev->pPollThread); @@ -218,7 +218,7 @@ static void ft1000_disconnect(struct usb_interface *interface) DEBUG("ft1000_disconnect is called\n"); - pft1000info = (struct ft1000_info *) usb_get_intfdata(interface); + pft1000info = (struct ft1000_info *)usb_get_intfdata(interface); DEBUG("In disconnect pft1000info=%p\n", pft1000info); if (pft1000info) { @@ -233,7 +233,7 @@ static void ft1000_disconnect(struct usb_interface *interface) ft1000_destroy_dev(ft1000dev->net); unregister_netdev(ft1000dev->net); DEBUG - ("ft1000_disconnect: network device unregistered\n"); + ("ft1000_disconnect: network device unregistered\n"); free_netdev(ft1000dev->net); } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 8f7ccae57f31..418e6df91910 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -137,7 +137,7 @@ extern spinlock_t free_buff_lock; int ft1000_create_dev(struct ft1000_usb *dev); void ft1000_destroy_dev(struct net_device *dev); extern int card_send_command(struct ft1000_usb *ft1000dev, - void *ptempbuffer, int size); + void *ptempbuffer, int size); struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist); void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist); -- GitLab From b5d8204d00fa3bcd1f3b4b060fb90675d00baee0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 3 Nov 2014 16:25:44 -0800 Subject: [PATCH 2883/9457] staging: ft1000: Logging message neatening Use a more common logging style. o Convert DEBUG macros to pr_debug o Add pr_fmt o Remove embedded function names from pr_debug o Convert printks to pr_ o Coalesce formats and align arguments o Add missing terminating newlines Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- .../ft1000/ft1000-pcmcia/ft1000_dnld.c | 6 +- .../staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 340 +++++++----------- .../staging/ft1000/ft1000-usb/ft1000_debug.c | 136 ++++--- .../ft1000/ft1000-usb/ft1000_download.c | 138 +++---- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 194 +++++----- .../staging/ft1000/ft1000-usb/ft1000_usb.c | 85 +++-- .../staging/ft1000/ft1000-usb/ft1000_usb.h | 2 - 7 files changed, 383 insertions(+), 518 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index deb12560dc09..115005061765 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -20,6 +20,8 @@ ---------------------------------------------------------------------------*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define __KERNEL_SYSCALLS__ #include @@ -316,7 +318,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, file_version = *(long *)pFileStart; if (file_version != 6) { - printk(KERN_ERR "ft1000: unsupported firmware version %ld\n", file_version); + pr_err("unsupported firmware version %ld\n", file_version); Status = FAILURE; } @@ -688,7 +690,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, uiState = STATE_SECTION_PROV; } else { netdev_dbg(dev, - "FT1000:download:Download error: Bad Port IDs in Pseudo Record\n"); + "Download error: Bad Port IDs in Pseudo Record\n"); netdev_dbg(dev, "\t Port Source = 0x%2.2x\n", pHdr->portsrc); netdev_dbg(dev, "\t Port Destination = 0x%2.2x\n", diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index c6bee28cad73..11dbe369e18b 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -17,6 +17,8 @@ Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -44,12 +46,6 @@ #include #include -#ifdef FT_DEBUG -#define DEBUG(n, args...) printk(KERN_DEBUG args); -#else -#define DEBUG(n, args...) -#endif - #include #include "ft1000.h" @@ -282,12 +278,9 @@ static void ft1000_enable_interrupts(struct net_device *dev) { u16 tempword; - DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n"); ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); - DEBUG(1, - "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + pr_debug("current interrupt enable mask = 0x%x\n", tempword); } /*--------------------------------------------------------------------------- @@ -304,12 +297,9 @@ static void ft1000_disable_interrupts(struct net_device *dev) { u16 tempword; - DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n"); ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); - DEBUG(1, - "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n", - tempword); + pr_debug("current interrupt enable mask = 0x%x\n", tempword); } /*--------------------------------------------------------------------------- @@ -329,8 +319,6 @@ static void ft1000_reset_asic(struct net_device *dev) struct ft1000_pcmcia *pcmcia = info->priv; u16 tempword; - DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n"); - (*info->ft1000_reset) (pcmcia->link); /* @@ -351,10 +339,10 @@ static void ft1000_reset_asic(struct net_device *dev) } /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); } @@ -377,8 +365,6 @@ static int ft1000_reset_card(struct net_device *dev) unsigned long flags; struct prov_record *ptr; - DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n"); - info->CardReady = 0; info->ProgConStat = 0; info->squeseqnum = 0; @@ -388,8 +374,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { - DEBUG(0, - "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); + pr_debug("deleting provisioning record\n"); ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); @@ -397,11 +382,10 @@ static int ft1000_reset_card(struct net_device *dev) } if (info->AsicID == ELECTRABUZZ_ID) { - DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting DSP\n"); + pr_debug("resetting DSP\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); } else { - DEBUG(1, - "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n"); + pr_debug("resetting ASIC and DSP\n"); ft1000_write_reg(dev, FT1000_REG_RESET, (DSP_RESET_BIT | ASIC_RESET_BIT)); } @@ -428,17 +412,16 @@ static int ft1000_reset_card(struct net_device *dev) spin_unlock_irqrestore(&info->dpram_lock, flags); } - DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n"); + pr_debug("resetting ASIC\n"); mdelay(10); /* reset ASIC */ ft1000_reset_asic(dev); - DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n"); + pr_debug("downloading dsp image\n"); if (info->AsicID == MAGNEMITE_ID) { /* Put dsp in reset and take ASIC out of reset */ - DEBUG(0, - "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); + pr_debug("Put DSP in reset and take ASIC out of reset\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); /* Setting MAGNEMITE ASIC to big endian mode */ @@ -450,7 +433,7 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_RESET, 0); /* FLARION_DSP_ACTIVE; */ mdelay(10); - DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n"); + pr_debug("Take DSP out of reset\n"); /* Wait for 0xfefe indicating dsp ready before starting download */ for (i = 0; i < 50; i++) { @@ -464,8 +447,7 @@ static int ft1000_reset_card(struct net_device *dev) } if (i == 50) { - DEBUG(0, - "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n"); + pr_debug("No FEFE detected from DSP\n"); return false; } @@ -476,10 +458,10 @@ static int ft1000_reset_card(struct net_device *dev) } if (card_download(dev, fw_entry->data, fw_entry->size)) { - DEBUG(1, "card download unsuccessful\n"); + pr_debug("card download unsuccessful\n"); return false; } else { - DEBUG(1, "card download successful\n"); + pr_debug("card download successful\n"); } mdelay(10); @@ -494,8 +476,7 @@ static int ft1000_reset_card(struct net_device *dev) /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram(dev, FT1000_HI_HO, ho); tempword = ft1000_read_dpram(dev, FT1000_HI_HO); - DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); } else { /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag, @@ -503,8 +484,7 @@ static int ft1000_reset_card(struct net_device *dev) tempword = ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX); - DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); } info->CardReady = 1; @@ -541,8 +521,7 @@ static int ft1000_chkcard(struct net_device *dev) */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG(1, - "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + pr_debug("IMASK = 0 Card not detected\n"); return false; } /* @@ -551,8 +530,7 @@ static int ft1000_chkcard(struct net_device *dev) */ tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (tempword == 0xffff) { - DEBUG(1, - "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + pr_debug("Version = 0xffff Card not detected\n"); return false; } return true; @@ -589,8 +567,7 @@ static void ft1000_hbchk(u_long data) (dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX)); } - DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n", - tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); /* Let's perform another check if ho is not detected */ if (tempword != ho) { if (info->AsicID == ELECTRABUZZ_ID) { @@ -601,8 +578,7 @@ static void ft1000_hbchk(u_long data) } } if (tempword != ho) { - printk(KERN_INFO - "ft1000: heartbeat failed - no ho detected\n"); + pr_info("heartbeat failed - no ho detected\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -632,8 +608,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -650,8 +625,7 @@ static void ft1000_hbchk(u_long data) tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); } if (tempword & FT1000_DB_HB) { - printk(KERN_INFO - "ft1000: heartbeat doorbell not clear by firmware\n"); + pr_info("heartbeat doorbell not clear by firmware\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -681,8 +655,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -730,8 +703,7 @@ static void ft1000_hbchk(u_long data) } if (tempword != hi) { - printk(KERN_INFO - "ft1000: heartbeat failed - cannot write hi into DPRAM\n"); + pr_info("heartbeat failed - cannot write hi into DPRAM\n"); if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -761,8 +733,7 @@ static void ft1000_hbchk(u_long data) } info->DrvErrNum = DSP_HB_INFO; if (ft1000_reset_card(dev) == 0) { - printk(KERN_INFO - "ft1000: Hardware Failure Detected - PC Card disabled\n"); + pr_info("Hardware Failure Detected - PC Card disabled\n"); info->ProgConStat = 0xff; return; } @@ -802,8 +773,8 @@ static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, if ((size & 0x0001)) { size++; } - DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size); - DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer)); + pr_debug("total length = %d\n", size); + pr_debug("length = %d\n", ntohs(*ptempbuffer)); /* * put message into slow queue area * All messages are in the form total_len + pseudo header + message body @@ -830,8 +801,7 @@ static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size); /* Write pseudo header and messgae body */ for (i = 0; i < (size >> 1); i++) { - DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i, - *ptempbuffer); + pr_debug("data %d = 0x%x\n", i, *ptempbuffer); tempword = htons(*ptempbuffer++); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword); } @@ -844,18 +814,16 @@ static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size, ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE + 1); for (i = 0; i < (size >> 2); i++) { - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", - *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH); } - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer); + pr_debug("data = 0x%x\n", *ptempbuffer); outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH); } spin_unlock_irqrestore(&info->dpram_lock, flags); @@ -896,9 +864,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); } if (size > maxsz) { - DEBUG(1, - "FT1000:ft1000_receive_cmd:Invalid command length = %d\n", - size); + pr_debug("Invalid command length = %d\n", size); return false; } else { ppseudohdr = (u16 *)pbuffer; @@ -915,7 +881,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_RX_BASE); *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_RX_BASE + 1); @@ -931,10 +897,10 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, } /* copy odd aligned word */ *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH); - DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); + pr_debug("received data = 0x%x\n", *pbuffer); pbuffer++; } if (size & 0x0001) { @@ -953,8 +919,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, tempword ^= *ppseudohdr++; } if ((tempword != *ppseudohdr)) { - DEBUG(1, - "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); + pr_debug("Pseudo header checksum mismatch\n"); /* Drop this message */ return false; } @@ -1003,14 +968,13 @@ static void ft1000_proc_drvmsg(struct net_device *dev) /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ pdrvmsg = (struct drv_msg *)&cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); - DEBUG(1, "Command message type = 0x%x\n", msgtype); + pr_debug("Command message type = 0x%x\n", msgtype); switch (msgtype) { case DSP_PROVISION: - DEBUG(0, - "Got a provisioning request message from DSP\n"); + pr_debug("Got a provisioning request message from DSP\n"); mdelay(25); while (list_empty(&info->prov_list) == 0) { - DEBUG(0, "Sending a provisioning message\n"); + pr_debug("Sending a provisioning message\n"); /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); @@ -1035,12 +999,12 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; - DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + pr_debug("checksum = 0x%x\n", + ppseudo_hdr->checksum); for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; - DEBUG(1, "checksum = 0x%x\n", - ppseudo_hdr->checksum); + pr_debug("checksum = 0x%x\n", + ppseudo_hdr->checksum); } ft1000_send_cmd(dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE); @@ -1058,7 +1022,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) pmediamsg = (struct media_msg *)&cmdbuffer[0]; if (info->ProgConStat != 0xFF) { if (pmediamsg->state) { - DEBUG(1, "Media is up\n"); + pr_debug("Media is up\n"); if (info->mediastate == 0) { netif_carrier_on(dev); netif_wake_queue(dev); @@ -1067,7 +1031,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) info->ConTm = tv.tv_sec; } } else { - DEBUG(1, "Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; netif_carrier_off(dev); @@ -1077,7 +1041,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } } else { - DEBUG(1, "Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; netif_carrier_off(dev); @@ -1089,9 +1053,9 @@ static void ft1000_proc_drvmsg(struct net_device *dev) case DSP_INIT_MSG: pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[0]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); + pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], + info->DspVer[2], info->DspVer[3]); memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, HWSERNUMSZ); memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); @@ -1111,27 +1075,26 @@ static void ft1000_proc_drvmsg(struct net_device *dev) CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ); - DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n", - info->RfCalVer[0], info->RfCalVer[1]); + pr_debug("RFCalVer = 0x%2x 0x%2x\n", + info->RfCalVer[0], info->RfCalVer[1]); } break; case DSP_STORE_INFO: - DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n"); + pr_debug("Got DSP_STORE_INFO\n"); tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG(1, - "FT1000:drivermsg:dsp info data = 0x%x\n", - *pmsg); + pr_debug("dsp info data = 0x%x\n", + *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; } } break; case DSP_GET_INFO: - DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n"); + pr_debug("Got DSP_GET_INFO\n"); /* * copy dsp info block to dsp * allow any outstanding ioctl to finish @@ -1182,7 +1145,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) break; case GET_DRV_ERR_RPT_MSG: - DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + pr_debug("Got GET_DRV_ERR_RPT_MSG\n"); /* * copy driver error message to dsp * allow any outstanding ioctl to finish @@ -1273,7 +1236,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) unsigned long flags; doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - DEBUG(1, "Doorbell = 0x%x\n", doorbell); + pr_debug("Doorbell = 0x%x\n", doorbell); if (doorbell & FT1000_ASIC_RESET_REQ) { /* Copy DSP session record from info block */ @@ -1298,7 +1261,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) /* clear ASIC RESET request */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_REQ); - DEBUG(1, "Got an ASIC RESET Request\n"); + pr_debug("Got an ASIC RESET Request\n"); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_DSP); @@ -1310,8 +1273,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DSP_ASIC_RESET) { - DEBUG(0, - "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n"); + pr_debug("Got a dsp ASIC reset message\n"); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DSP_ASIC_RESET); udelay(200); @@ -1319,8 +1281,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DB_DPRAM_RX) { - DEBUG(1, - "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n"); + pr_debug("Got a slow queue message\n"); nxtph = FT1000_DPRAM_RX_BASE + 2; if (info->AsicID == ELECTRABUZZ_ID) { total_len = @@ -1331,8 +1292,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) (dev, FT1000_MAG_TOTAL_LEN, FT1000_MAG_TOTAL_LEN_INDX)); } - DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n", - total_len); + pr_debug("total length = %d\n", total_len); if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { total_len += nxtph; /* @@ -1351,7 +1311,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) (dev, FT1000_MAG_PORT_ID, FT1000_MAG_PORT_ID_INDX) & 0xff); } - DEBUG(1, "DSP_QID = 0x%x\n", portid); + pr_debug("DSP_QID = 0x%x\n", portid); if (portid == DRIVERID) { /* We are assumming one driver message from the DSP at a time. */ @@ -1387,7 +1347,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_MAG_DSP_TIMER3_INDX); } info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG(1, "ft1000_hw:DSP conditional reset requested\n"); + pr_debug("DSP conditional reset requested\n"); ft1000_reset_card(dev); ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_COND_RESET); @@ -1397,7 +1357,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ | FT1000_DB_COND_RESET | 0xff00); if (doorbell) { - DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell); + pr_debug("Clearing unexpected doorbell = 0x%x\n", doorbell); ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell); } @@ -1425,7 +1385,6 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) u32 templong; u16 tempword; - DEBUG(1, "ft1000:ft1000_hw:ft1000_flush_fifo called\n"); if (pcmcia->PktIntfErr > MAX_PH_ERR) { if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = @@ -1531,23 +1490,23 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) } while ((tempword & 0x03) != 0x03); if (info->AsicID == ELECTRABUZZ_ID) { i++; - DEBUG(0, "Flushing FIFO complete = %x\n", tempword); + pr_debug("Flushing FIFO complete = %x\n", tempword); /* Flush last word in FIFO. */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); /* Update FIFO counter for DSP */ i = i * 2; - DEBUG(0, "Flush Data byte count to dsp = %d\n", i); + pr_debug("Flush Data byte count to dsp = %d\n", i); info->fifo_cnt += i; ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt); } else { - DEBUG(0, "Flushing FIFO complete = %x\n", tempword); + pr_debug("Flushing FIFO complete = %x\n", tempword); /* Flush last word in FIFO */ templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT); - DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword); + pr_debug("FT1000_REG_SUP_STAT = 0x%x\n", tempword); tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR); - DEBUG(0, "FT1000_REG_MAG_DFSR = 0x%x\n", tempword); + pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword); } if (DrvErrNum) { pcmcia->PktIntfErr++; @@ -1581,7 +1540,6 @@ static int ft1000_copy_up_pkt(struct net_device *dev) u32 *ptemplong; u32 templong; - DEBUG(1, "ft1000_copy_up_pkt\n"); /* Read length */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); @@ -1591,10 +1549,10 @@ static int ft1000_copy_up_pkt(struct net_device *dev) len = ntohs(tempword); } chksum = tempword; - DEBUG(1, "Number of Bytes in FIFO = %d\n", len); + pr_debug("Number of Bytes in FIFO = %d\n", len); if (len > ENET_MAX_SIZE) { - DEBUG(0, "size of ethernet packet invalid\n"); + pr_debug("size of ethernet packet invalid\n"); if (info->AsicID == MAGNEMITE_ID) { /* Read High word to complete 32 bit access */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1607,7 +1565,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) skb = dev_alloc_skb(len + 12 + 2); if (skb == NULL) { - DEBUG(0, "No Network buffers available\n"); + pr_debug("No Network buffers available\n"); /* Read High word to complete 32 bit access */ if (info->AsicID == MAGNEMITE_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1628,37 +1586,37 @@ static int ft1000_copy_up_pkt(struct net_device *dev) tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); } else { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); chksum ^= tempword; /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); - DEBUG(1, "Pseudo = 0x%x\n", tempword); + pr_debug("Pseudo = 0x%x\n", tempword); } if (chksum != tempword) { - DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum, - tempword); + pr_debug("Packet checksum mismatch 0x%x 0x%x\n", + chksum, tempword); ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO); info->stats.rx_errors++; kfree_skb(skb); @@ -1701,22 +1659,22 @@ static int ft1000_copy_up_pkt(struct net_device *dev) ptemplong = (u32 *)pbuffer; for (i = 0; i < len / 4; i++) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); - DEBUG(1, "Data = 0x%8x\n", templong); + pr_debug("Data = 0x%8x\n", templong); *ptemplong++ = templong; } /* Need to read one more word if odd align. */ if (len & 0x0003) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); - DEBUG(1, "Data = 0x%8x\n", templong); + pr_debug("Data = 0x%8x\n", templong); *ptemplong++ = templong; } } - DEBUG(1, "Data passed to Protocol layer:\n"); + pr_debug("Data passed to Protocol layer:\n"); for (i = 0; i < len + 12; i++) { - DEBUG(1, "Protocol Data: 0x%x\n ", *ptemp++); + pr_debug("Protocol Data: 0x%x\n", *ptemp++); } skb->dev = dev; @@ -1768,8 +1726,6 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) int i; u32 *plong; - DEBUG(1, "ft1000_hw: copy_down_pkt()\n"); - /* Check if there is room on the FIFO */ if (len > ft1000_read_fifo_len(dev)) { udelay(10); @@ -1789,8 +1745,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) udelay(20); } if (len > ft1000_read_fifo_len(dev)) { - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n"); + pr_debug("Transmit FIFO is full - pkt drop\n"); info->stats.tx_errors++; return SUCCESS; } @@ -1821,39 +1776,30 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) if (info->AsicID == ELECTRABUZZ_ID) { /* copy first word to UFIFO_BEG reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n", - pseudo.buff[0]); + pr_debug("data 0 BEG = 0x%04x\n", pseudo.buff[0]); /* copy subsequent words to UFIFO_MID reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n", - pseudo.buff[1]); + pr_debug("data 1 MID = 0x%04x\n", pseudo.buff[1]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n", - pseudo.buff[2]); + pr_debug("data 2 MID = 0x%04x\n", pseudo.buff[2]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n", - pseudo.buff[3]); + pr_debug("data 3 MID = 0x%04x\n", pseudo.buff[3]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n", - pseudo.buff[4]); + pr_debug("data 4 MID = 0x%04x\n", pseudo.buff[4]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n", - pseudo.buff[5]); + pr_debug("data 5 MID = 0x%04x\n", pseudo.buff[5]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n", - pseudo.buff[6]); + pr_debug("data 6 MID = 0x%04x\n", pseudo.buff[6]); ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]); - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n", - pseudo.buff[7]); + pr_debug("data 7 MID = 0x%04x\n", pseudo.buff[7]); /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 1) - 1; i++) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); packet++; } @@ -1861,39 +1807,31 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) if (len & 0x0001) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n", - htons(*packet)); + pr_debug("data MID = 0x%04x\n", htons(*packet)); packet++; ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } else { ft1000_write_reg(dev, FT1000_REG_UFIFO_END, htons(*packet)); - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n", - i + 8, htons(*packet)); + pr_debug("data %d MID = 0x%04x\n", + i + 8, htons(*packet)); } } else { outl(*(u32 *)&pseudo.buff[0], dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *)&pseudo.buff[0]); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[0]); outl(*(u32 *)&pseudo.buff[2], dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *)&pseudo.buff[2]); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[2]); outl(*(u32 *)&pseudo.buff[4], dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *)&pseudo.buff[4]); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[4]); outl(*(u32 *)&pseudo.buff[6], dev->base_addr + FT1000_REG_MAG_UFDR); - DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n", - *(u32 *)&pseudo.buff[6]); + pr_debug("Pseudo = 0x%8x\n", *(u32 *)&pseudo.buff[6]); plong = (u32 *)packet; /* Write PPP type + IP Packet into Downlink FIFO */ @@ -1903,9 +1841,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len) /* Check for odd alignment */ if (len & 0x0003) { - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", - *plong); + pr_debug("data = 0x%8x\n", *plong); outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); } outl(1, dev->base_addr + FT1000_REG_MAG_UFER); @@ -1926,11 +1862,7 @@ static struct net_device_stats *ft1000_stats(struct net_device *dev) static int ft1000_open(struct net_device *dev) { - - DEBUG(0, "ft1000_hw: ft1000_open is called\n"); - ft1000_reset_card(dev); - DEBUG(0, "ft1000_hw: ft1000_open is ended\n"); /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */ init_timer(&poll_timer); @@ -1938,7 +1870,6 @@ static int ft1000_open(struct net_device *dev) poll_timer.data = (u_long)dev; add_timer(&poll_timer); - DEBUG(0, "ft1000_hw: ft1000_open is ended2\n"); return 0; } @@ -1946,13 +1877,11 @@ static int ft1000_close(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); - DEBUG(0, "ft1000_hw: ft1000_close()\n"); - info->CardReady = 0; del_timer(&poll_timer); if (ft1000_card_present == 1) { - DEBUG(0, "Media is down\n"); + pr_debug("Media is down\n"); netif_stop_queue(dev); ft1000_disable_interrupts(dev); @@ -1969,27 +1898,24 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ft1000_info *info = netdev_priv(dev); u8 *pdata; - DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n"); if (skb == NULL) { - DEBUG(1, "ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n"); + pr_debug("skb == NULL!!!\n"); return 0; } - DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n", - skb->len); + pr_debug("length of packet = %d\n", skb->len); pdata = (u8 *)skb->data; if (info->mediastate == 0) { /* Drop packet is mediastate is down */ - DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:mediastate is down\n"); + pr_debug("mediastate is down\n"); return SUCCESS; } if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { /* Drop packet which has invalid size */ - DEBUG(1, - "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n"); + pr_debug("invalid ethernet length\n"); return SUCCESS; } ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2), @@ -2008,8 +1934,6 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) u16 inttype; int cnt; - DEBUG(1, "ft1000_hw: ft1000_interrupt()\n"); - if (info->CardReady == 0) { ft1000_disable_interrupts(dev); return IRQ_HANDLED; @@ -2031,7 +1955,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) ft1000_parse_dpram_msg(dev); if (inttype & ISR_RCV) { - DEBUG(1, "Data in FIFO\n"); + pr_debug("Data in FIFO\n"); cnt = 0; do { @@ -2056,12 +1980,13 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) } /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); /* Read interrupt type */ inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - DEBUG(1, "ft1000_hw: interrupt status register after clear = 0x%x\n", inttype); + pr_debug("interrupt status register after clear = 0x%x\n", + inttype); } ft1000_enable_interrupts(dev); return IRQ_HANDLED; @@ -2073,8 +1998,6 @@ void stop_ft1000_card(struct net_device *dev) struct prov_record *ptr; /* int cnt; */ - DEBUG(0, "ft1000_hw: stop_ft1000_card()\n"); - info->CardReady = 0; ft1000_card_present = 0; netif_stop_queue(dev); @@ -2143,9 +2066,8 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, .ndo_get_stats = &ft1000_stats, }; - DEBUG(1, "ft1000_hw: init_ft1000_card()\n"); - DEBUG(1, "ft1000_hw: irq = %d\n", link->irq); - DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start); + pr_debug("irq = %d, port = 0x%04llx\n", + link->irq, (unsigned long long)link->resource[0]->start); flarion_ft1000_cnt++; @@ -2168,9 +2090,9 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, memset(info, 0, sizeof(struct ft1000_info)); - DEBUG(1, "address of dev = 0x%8x\n", (u32)dev); - DEBUG(1, "address of dev info = 0x%8x\n", (u32)info); - DEBUG(0, "device name = %s\n", dev->name); + pr_debug("address of dev = 0x%p\n", dev); + pr_debug("address of dev info = 0x%p\n", info); + pr_debug("device name = %s\n", dev->name); memset(&info->stats, 0, sizeof(struct net_device_stats)); @@ -2202,7 +2124,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */ - DEBUG(0, "device name = %s\n", dev->name); + pr_debug("device name = %s\n", dev->name); dev->irq = link->irq; dev->base_addr = link->resource[0]->start; @@ -2222,21 +2144,21 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, } if (register_netdev(dev) != 0) { - DEBUG(0, "ft1000: Could not register netdev"); + pr_debug("Could not register netdev\n"); goto err_reg; } info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (info->AsicID == ELECTRABUZZ_ID) { - DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n"); + pr_debug("ELECTRABUZZ ASIC\n"); if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) { - printk(KERN_INFO "ft1000: Could not open ft1000.img\n"); + pr_info("Could not open ft1000.img\n"); goto err_unreg; } } else { - DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n"); + pr_debug("MAGNEMITE ASIC\n"); if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) { - printk(KERN_INFO "ft1000: Could not open ft2000.img\n"); + pr_info("Could not open ft2000.img\n"); goto err_unreg; } } @@ -2245,8 +2167,8 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, ft1000_card_present = 1; dev->ethtool_ops = &ops; - printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n", - dev->name, dev->base_addr, dev->irq, dev->dev_addr); + pr_info("%s: addr 0x%04lx irq %d, MAC addr %pM\n", + dev->name, dev->base_addr, dev->irq, dev->dev_addr); return dev; err_unreg: diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 658f3cab8e72..c8d278229940 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -26,6 +26,9 @@ * *--------------------------------------------------------------------------- */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -87,13 +90,13 @@ struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist) spin_lock_irqsave(&free_buff_lock, flags); /* Check if buffer is available */ if (list_empty(bufflist)) { - DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); + pr_debug("No more buffer - %d\n", numofmsgbuf); ptr = NULL; } else { numofmsgbuf--; ptr = list_entry(bufflist->next, struct dpram_blk, list); list_del(&ptr->list); - /* DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ + /* pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */ } spin_unlock_irqrestore(&free_buff_lock, flags); @@ -125,7 +128,7 @@ void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) /* Put memory back to list */ list_add_tail(&pdpram_blk->list, plist); numofmsgbuf++; - /*DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); */ + /*pr_debug("number of free msg buffers = %d\n", numofmsgbuf); */ spin_unlock_irqrestore(&free_buff_lock, flags); } @@ -153,17 +156,17 @@ int ft1000_create_dev(struct ft1000_usb *dev) /* make a new device name */ sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber); - DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); - DEBUG("DeviceCreated = %x\n", dev->DeviceCreated); + pr_debug("number of instance = %d\n", ft1000_flarion_cnt); + pr_debug("DeviceCreated = %x\n", dev->DeviceCreated); if (dev->DeviceCreated) { - DEBUG("%s: \"%s\" already registered\n", __func__, dev->DeviceName); + pr_debug("\"%s\" already registered\n", dev->DeviceName); return -EIO; } /* register the device */ - DEBUG("%s: \"%s\" debugfs device registration\n", __func__, dev->DeviceName); + pr_debug("\"%s\" debugfs device registration\n", dev->DeviceName); tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); if (tmp == NULL) { @@ -189,7 +192,7 @@ int ft1000_create_dev(struct ft1000_usb *dev) tmp->int_number = dev->CardNumber; list_add(&(tmp->list), &(dev->nodes.list)); - DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, dev->DeviceName); + pr_debug("registered debugfs directory \"%s\"\n", dev->DeviceName); /* initialize application information */ dev->appcnt = 0; @@ -241,10 +244,6 @@ void ft1000_destroy_dev(struct net_device *netdev) struct list_head *pos, *q; struct ft1000_debug_dirs *dir; - DEBUG("%s called\n", __func__); - - - if (dev->DeviceCreated) { ft1000_flarion_cnt--; list_for_each_safe(pos, q, &dev->nodes.list) { @@ -256,8 +255,7 @@ void ft1000_destroy_dev(struct net_device *netdev) kfree(dir); } } - DEBUG("%s: unregistered device \"%s\"\n", __func__, - dev->DeviceName); + pr_debug("unregistered device \"%s\"\n", dev->DeviceName); /* Make sure we free any memory reserve for slow Queue */ for (i = 0; i < MAX_NUM_APP; i++) { @@ -303,17 +301,17 @@ static int ft1000_open(struct inode *inode, struct file *file) struct ft1000_usb *dev = (struct ft1000_usb *)inode->i_private; int i, num; - DEBUG("%s called\n", __func__); num = (MINOR(inode->i_rdev) & 0xf); - DEBUG("ft1000_open: minor number=%d\n", num); + pr_debug("minor number=%d\n", num); info = file->private_data = netdev_priv(dev->net); - DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt); + pr_debug("f_owner = %p number of application = %d\n", + &file->f_owner, dev->appcnt); /* Check if maximum number of application exceeded */ if (dev->appcnt > MAX_NUM_APP) { - DEBUG("Maximum number of application exceeded\n"); + pr_debug("Maximum number of application exceeded\n"); return -EACCES; } @@ -326,7 +324,7 @@ static int ft1000_open(struct inode *inode, struct file *file) /* Fail due to lack of application info block */ if (i == MAX_NUM_APP) { - DEBUG("Could not find an application info block\n"); + pr_debug("Could not find an application info block\n"); return -EACCES; } @@ -362,33 +360,32 @@ static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) struct ft1000_usb *dev = info->priv; int i; - /* DEBUG("ft1000_poll_dev called\n"); */ if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); + pr_debug("called with ft1000_flarion_cnt value zero\n"); return -EBADF; } /* Search for matching file object */ for (i = 0; i < MAX_NUM_APP; i++) { if (dev->app_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id); */ + /* pr_debug("Message is for AppId = %d\n", dev->app_info[i].app_id); */ break; } } /* Could not find application info block */ if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + pr_debug("Could not find application info block\n"); return -EACCES; } if (list_empty(&dev->app_info[i].app_sqlist) == 0) { - DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); + pr_debug("Message detected in slow queue\n"); return(POLLIN | POLLRDNORM | POLLPRI); } poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait); - /* DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); */ + /* pr_debug("Polling for data from DSP\n"); */ return 0; } @@ -429,27 +426,25 @@ static long ft1000_ioctl(struct file *file, unsigned int command, unsigned short ledStat = 0; unsigned short conStat = 0; - /* DEBUG("ft1000_ioctl called\n"); */ - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); + pr_debug("called with ft1000_flarion_cnt of zero\n"); return -EBADF; } - /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ + /* pr_debug("command = 0x%x argument = 0x%8x\n", command, (u32)argument); */ info = file->private_data; ft1000dev = info->priv; cmd = _IOC_NR(command); - /* DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); */ + /* pr_debug("cmd = 0x%x\n", cmd); */ /* process the command */ switch (cmd) { case IOCTL_REGISTER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); + pr_debug("IOCTL_FT1000_REGISTER called\n"); result = get_user(tempword, (__u16 __user *)argp); if (result) { - DEBUG("result = %d failed to get_user\n", result); + pr_debug("result = %d failed to get_user\n", result); break; } if (tempword == DSPBCMSGID) { @@ -457,7 +452,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, for (i = 0; i < MAX_NUM_APP; i++) { if (ft1000dev->app_info[i].fileobject == &file->f_owner) { ft1000dev->app_info[i].DspBCMsgFlag = 1; - DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); + pr_debug("Registered for broadcast messages\n"); break; } } @@ -465,34 +460,35 @@ static long ft1000_ioctl(struct file *file, unsigned int command, break; case IOCTL_GET_VER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); + pr_debug("IOCTL_FT1000_GET_VER called\n"); get_ver_data.drv_ver = FT1000_DRV_VER; if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + pr_debug("copy fault occurred\n"); result = -EFAULT; break; } - DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n", (unsigned int)get_ver_data.drv_ver); + pr_debug("driver version = 0x%x\n", + (unsigned int)get_ver_data.drv_ver); break; case IOCTL_CONNECT: /* Connect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); + pr_debug("IOCTL_FT1000_CONNECT\n"); ConnectionMsg[79] = 0xfc; result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_DISCONNECT: /* Disconnect Message */ - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); + pr_debug("IOCTL_FT1000_DISCONNECT\n"); ConnectionMsg[79] = 0xfd; result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_GET_DSP_STAT_CMD: - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */ + /* pr_debug("IOCTL_FT1000_GET_DSP_STAT\n"); */ memset(&get_stat_data, 0, sizeof(get_stat_data)); memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); @@ -502,10 +498,10 @@ static long ft1000_ioctl(struct file *file, unsigned int command, if (info->ProgConStat != 0xFF) { ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); get_stat_data.LedStat = ntohs(ledStat); - DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); + pr_debug("LedStat = 0x%x\n", get_stat_data.LedStat); ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); get_stat_data.ConStat = ntohs(conStat); - DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); + pr_debug("ConStat = 0x%x\n", get_stat_data.ConStat); } else { get_stat_data.ConStat = 0x0f; } @@ -517,13 +513,13 @@ static long ft1000_ioctl(struct file *file, unsigned int command, get_stat_data.nRxBytes = info->stats.rx_bytes; do_gettimeofday(&tv); get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); - DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); + pr_debug("Connection Time = %d\n", (int)get_stat_data.ConTm); if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + pr_debug("copy fault occurred\n"); result = -EFAULT; break; } - DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); + pr_debug("GET_DSP_STAT succeed\n"); break; case IOCTL_SET_DPRAM_CMD: { @@ -537,7 +533,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, u16 app_index; u16 status; - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/ + /* pr_debug("IOCTL_FT1000_SET_DPRAM called\n");*/ if (ft1000_flarion_cnt == 0) @@ -553,17 +549,17 @@ static long ft1000_ioctl(struct file *file, unsigned int command, if (info->CardReady) { - /* DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); */ + /* pr_debug("try to SET_DPRAM\n"); */ /* Get the length field to see how many bytes to copy */ result = get_user(msgsz, (__u16 __user *)argp); if (result) break; msgsz = ntohs(msgsz); - /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ + /* pr_debug("length of message = %d\n", msgsz); */ if (msgsz > MAX_CMD_SQSIZE) { - DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); + pr_debug("bad message length = %d\n", msgsz); result = -EINVAL; break; } @@ -574,7 +570,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, break; if (copy_from_user(dpram_data, argp, msgsz+2)) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + pr_debug("copy fault occurred\n"); result = -EFAULT; } else { /* Check if this message came from a registered application */ @@ -584,7 +580,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, } } if (i == MAX_NUM_APP) { - DEBUG("FT1000:No matching application fileobject\n"); + pr_debug("No matching application fileobject\n"); result = -EINVAL; kfree(dpram_data); break; @@ -593,13 +589,13 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* Check message qtype type which is the lower byte within qos_class */ qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; - /* DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); */ + /* pr_debug("qtype = %d\n", qtype); */ if (qtype) { } else { /* Put message into Slow Queue */ /* Only put a message into the DPRAM if msg doorbell is available */ status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - /* DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); */ + /* pr_debug("READ REGISTER tempword=%x\n", tempword); */ if (tempword & FT1000_DB_DPRAM_TX) { /* Suspend for 2ms and try again due to DSP doorbell busy */ mdelay(2); @@ -615,7 +611,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, mdelay(3); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { - DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); + pr_debug("Doorbell not available\n"); result = -ENOTTY; kfree(dpram_data); break; @@ -625,7 +621,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, } } - /*DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); */ + /*pr_debug("finished reading register\n"); */ /* Make sure we are within the limits of the slow queue memory limitation */ if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) { @@ -642,10 +638,10 @@ static long ft1000_ioctl(struct file *file, unsigned int command, ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + /* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */ for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; - /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */ + /* pr_debug("checksum = 0x%x\n", ppseudo_hdr->checksum); */ } pmsg++; ppseudo_hdr = (struct pseudo_hdr *)pmsg; @@ -659,7 +655,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, } } } else { - DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); + pr_debug("Card not ready take messages\n"); result = -EACCES; } kfree(dpram_data); @@ -672,7 +668,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command, struct IOCTL_DPRAM_BLK __user *pioctl_dpram; int msglen; - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */ + /* pr_debug("IOCTL_FT1000_GET_DPRAM called\n"); */ if (ft1000_flarion_cnt == 0) return -EBADF; @@ -680,14 +676,14 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* Search for matching file object */ for (i = 0; i < MAX_NUM_APP; i++) { if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - /*DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + /*pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ break; } } /* Could not find application info block */ if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + pr_debug("Could not find application info block\n"); result = -EBADF; break; } @@ -695,21 +691,21 @@ static long ft1000_ioctl(struct file *file, unsigned int command, result = 0; pioctl_dpram = argp; if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - /* DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); */ + /* pr_debug("Message detected in slow queue\n"); */ spin_lock_irqsave(&free_buff_lock, flags); pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); list_del(&pdpram_blk->list); ft1000dev->app_info[i].NumOfMsg--; - /* DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ + /* pr_debug("NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */ spin_unlock_irqrestore(&free_buff_lock, flags); msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; result = get_user(msglen, &pioctl_dpram->total_len); if (result) break; msglen = htons(msglen); - /* DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); */ + /* pr_debug("msg length = %x\n", msglen); */ if (copy_to_user(&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + pr_debug("copy fault occurred\n"); result = -EFAULT; break; } @@ -717,12 +713,12 @@ static long ft1000_ioctl(struct file *file, unsigned int command, ft1000_free_buffer(pdpram_blk, &freercvpool); result = msglen; } - /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); */ + /* pr_debug("IOCTL_FT1000_GET_DPRAM no message\n"); */ } break; default: - DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); + pr_debug("unknown command: 0x%x\n", command); result = -ENOTTY; break; } @@ -750,8 +746,6 @@ static int ft1000_release(struct inode *inode, struct file *file) int i; struct dpram_blk *pdpram_blk; - DEBUG("ft1000_release called\n"); - dev = file->private_data; info = netdev_priv(dev); ft1000dev = info->priv; @@ -764,7 +758,7 @@ static int ft1000_release(struct inode *inode, struct file *file) /* Search for matching file object */ for (i = 0; i < MAX_NUM_APP; i++) { if (ft1000dev->app_info[i].fileobject == &file->f_owner) { - /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ + /* pr_debug("Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */ break; } } @@ -773,7 +767,7 @@ static int ft1000_release(struct inode *inode, struct file *file) return 0; while (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) { - DEBUG("Remove and free memory queue up on slow queue\n"); + pr_debug("Remove and free memory queue up on slow queue\n"); pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list); list_del(&pdpram_blk->list); ft1000_free_buffer(pdpram_blk, &freercvpool); @@ -781,7 +775,7 @@ static int ft1000_release(struct inode *inode, struct file *file) /* initialize application information */ ft1000dev->appcnt--; - DEBUG("ft1000_chdev:%s:appcnt = %d\n", __func__, ft1000dev->appcnt); + pr_debug("appcnt = %d\n", ft1000dev->appcnt); ft1000dev->app_info[i].fileobject = NULL; return 0; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 2cce4224485b..e8126325877b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -4,6 +4,8 @@ * This file is part of Express Card USB Driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -118,10 +120,9 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) while (loopcnt < 10) { status = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", - temp); + pr_debug("read FT1000_REG_DOORBELL value is %x\n", temp); if (temp & 0x0080) { - DEBUG("FT1000:Got checkusb doorbell\n"); + pr_debug("Got checkusb doorbell\n"); status = ft1000_write_register(ft1000dev, 0x0080, FT1000_REG_DOORBELL); status = ft1000_write_register(ft1000dev, 0x0100, @@ -139,12 +140,12 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) while (loopcnt < 20) { status = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp); + pr_debug("Doorbell = 0x%x\n", temp); if (temp & 0x8000) { loopcnt++; msleep(10); } else { - DEBUG("check_usb_db: door bell is cleared, return 0\n"); + pr_debug("door bell is cleared, return 0\n"); return 0; } } @@ -166,12 +167,11 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL); if (ft1000dev->fcodeldr) { - DEBUG(" get_handshake: fcodeldr is %d\n", - ft1000dev->fcodeldr); + pr_debug("fcodeldr is %d\n", ft1000dev->fcodeldr); ft1000dev->fcodeldr = 0; status = check_usb_db(ft1000dev); if (status != 0) { - DEBUG("get_handshake: check_usb_db failed\n"); + pr_debug("check_usb_db failed\n"); break; } status = ft1000_write_register(ft1000dev, @@ -232,14 +232,14 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) status = ft1000_read_dpram32(ft1000dev, 0, (u8 *)&(ft1000dev->tempbuf[0]), 64); for (temp = 0; temp < 16; temp++) { - DEBUG("tempbuf %d = 0x%x\n", temp, - ft1000dev->tempbuf[temp]); + pr_debug("tempbuf %d = 0x%x\n", + temp, ft1000dev->tempbuf[temp]); } status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); - DEBUG("handshake from read_dpram16 = 0x%x\n", - handshake); + pr_debug("handshake from read_dpram16 = 0x%x\n", + handshake); if (ft1000dev->dspalive == ft1000dev->tempbuf[6]) { handshake = 0; } else { @@ -409,7 +409,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, if ((tempbuffer[31] & 0xfe00) == 0xfe00) { if (check_buffers(tempbuffer, resultbuffer, 28, 0)) { - DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n"); + pr_debug("DPRAM write failed 1 during bootloading\n"); usleep_range(9000, 11000); break; } @@ -419,14 +419,14 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, if (check_buffers(tempbuffer, resultbuffer, 16, 24)) { - DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n"); + pr_debug("DPRAM write failed 2 during bootloading\n"); usleep_range(9000, 11000); break; } } else { if (check_buffers(tempbuffer, resultbuffer, 32, 0)) { - DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n"); + pr_debug("DPRAM write failed 3 during bootloading\n"); usleep_range(9000, 11000); break; } @@ -453,7 +453,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, u16 tempword; u16 tempbuffer[64]; - /*DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); */ + /*pr_debug("start word_length = %d\n",(int)word_length); */ dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; tempword = *(*pUsFile); (*pUsFile)++; @@ -483,9 +483,9 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, } } - /*DEBUG("write_blk: loopcnt is %d\n", loopcnt); */ - /*DEBUG("write_blk: bootmode = %d\n", bootmode); */ - /*DEBUG("write_blk: dpram = %x\n", dpram); */ + /*pr_debug("loopcnt is %d\n", loopcnt); */ + /*pr_debug("write_blk: bootmode = %d\n", bootmode); */ + /*pr_debug("write_blk: dpram = %x\n", dpram); */ if (ft1000dev->bootmode == 0) { if (dpram >= 0x3F4) status = ft1000_write_dpram32(ft1000dev, dpram, @@ -497,7 +497,8 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, status = write_dpram32_and_check(ft1000dev, tempbuffer, dpram); if (status != 0) { - DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]); + pr_debug("Write failed tempbuffer[31] = 0x%x\n", + tempbuffer[31]); break; } } @@ -508,7 +509,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, static void usb_dnld_complete(struct urb *urb) { - /* DEBUG("****** usb_dnld_complete\n"); */ + /* pr_debug("****** usb_dnld_complete\n"); */ } /* writes a block of DSP image to DPRAM @@ -552,18 +553,17 @@ static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake, { int status = 0; - DEBUG("FT1000:STATE_START_DWNLD\n"); if (ft1000dev->usbboot) *hshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY); else *hshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY); if (*hshake == HANDSHAKE_DSP_BL_READY) { - DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); + pr_debug("handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY); } else if (*hshake == HANDSHAKE_TIMEOUT_VALUE) { status = -ETIMEDOUT; } else { - DEBUG("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -ENETRESET; } *state = STATE_BOOT_DWNLD; @@ -576,17 +576,17 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, long word_length; int status = 0; - /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/ word_length = get_request_value(ft1000dev); - /*DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); */ + /*pr_debug("word_length = 0x%x\n", (int)word_length); */ /*NdisMSleep (100); */ if (word_length > MAX_LENGTH) { - DEBUG("FT1000:download:Download error: Max length exceeded\n"); + pr_debug("Download error: Max length exceeded\n"); return -1; } if ((word_length * 2 + (long)c_file) > (long)endpoint) { /* Error, beyond boot code range.*/ - DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length); + pr_debug("Download error: Requested len=%d exceeds BOOT code boundary\n", + (int)word_length); return -1; } if (word_length & 0x1) @@ -595,7 +595,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, if (boot_case) { status = write_blk(ft1000dev, s_file, c_file, word_length); - /*DEBUG("write_blk returned %d\n", status); */ + /*pr_debug("write_blk returned %d\n", status); */ } else { status = write_blk_fifo(ft1000dev, s_file, c_file, word_length); if (ft1000dev->usbboot == 0) @@ -641,8 +641,6 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, struct prov_record *pprov_record; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - DEBUG("Entered scram_dnldr...\n"); - ft1000dev->fcodeldr = 0; ft1000dev->usbboot = 0; ft1000dev->dspalive = 0xffff; @@ -674,7 +672,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case STATE_BOOT_DWNLD: - DEBUG("FT1000:STATE_BOOT_DWNLD\n"); + pr_debug("STATE_BOOT_DWNLD\n"); ft1000dev->bootmode = 1; handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST); if (handshake == HANDSHAKE_REQUEST) { @@ -684,22 +682,22 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, request = get_request_type(ft1000dev); switch (request) { case REQUEST_RUN_ADDRESS: - DEBUG("FT1000:REQUEST_RUN_ADDRESS\n"); + pr_debug("REQUEST_RUN_ADDRESS\n"); put_request_value(ft1000dev, loader_code_address); break; case REQUEST_CODE_LENGTH: - DEBUG("FT1000:REQUEST_CODE_LENGTH\n"); + pr_debug("REQUEST_CODE_LENGTH\n"); put_request_value(ft1000dev, loader_code_size); break; case REQUEST_DONE_BL: - DEBUG("FT1000:REQUEST_DONE_BL\n"); + pr_debug("REQUEST_DONE_BL\n"); /* Reposition ptrs to beginning of code section */ s_file = (u16 *) (boot_end); c_file = (u8 *) (boot_end); - /* DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); */ - /* DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ + /* pr_debug("download:s_file = 0x%8x\n", (int)s_file); */ + /* pr_debug("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ state = STATE_CODE_DWNLD; ft1000dev->fcodeldr = 1; break; @@ -710,8 +708,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, true); break; default: - DEBUG - ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", + pr_debug("Download error: Bad request type=%d in BOOT download state\n", request); status = -1; break; @@ -723,15 +720,14 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, put_handshake(ft1000dev, HANDSHAKE_RESPONSE); } else { - DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -1; } break; case STATE_CODE_DWNLD: - /* DEBUG("FT1000:STATE_CODE_DWNLD\n"); */ + /* pr_debug("STATE_CODE_DWNLD\n"); */ ft1000dev->bootmode = 0; if (ft1000dev->usbboot) handshake = @@ -751,40 +747,33 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, request = get_request_type(ft1000dev); switch (request) { case REQUEST_FILE_CHECKSUM: - DEBUG - ("FT1000:download:image_chksum = 0x%8x\n", + pr_debug("image_chksum = 0x%8x\n", image_chksum); put_request_value(ft1000dev, image_chksum); break; case REQUEST_RUN_ADDRESS: - DEBUG - ("FT1000:download: REQUEST_RUN_ADDRESS\n"); + pr_debug("REQUEST_RUN_ADDRESS\n"); if (correct_version) { - DEBUG - ("FT1000:download:run_address = 0x%8x\n", + pr_debug("run_address = 0x%8x\n", (int)run_address); put_request_value(ft1000dev, run_address); } else { - DEBUG - ("FT1000:download:Download error: Got Run address request before image offset request.\n"); + pr_debug("Download error: Got Run address request before image offset request\n"); status = -1; break; } break; case REQUEST_CODE_LENGTH: - DEBUG - ("FT1000:download:REQUEST_CODE_LENGTH\n"); + pr_debug("REQUEST_CODE_LENGTH\n"); if (correct_version) { - DEBUG - ("FT1000:download:run_size = 0x%8x\n", + pr_debug("run_size = 0x%8x\n", (int)run_size); put_request_value(ft1000dev, run_size); } else { - DEBUG - ("FT1000:download:Download error: Got Size request before image offset request.\n"); + pr_debug("Download error: Got Size request before image offset request\n"); status = -1; break; } @@ -801,10 +790,9 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: - /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */ + /* pr_debug("REQUEST_CODE_SEGMENT - CODELOADER\n"); */ if (!correct_version) { - DEBUG - ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); + pr_debug("Download error: Got Code Segment request before image offset request\n"); status = -1; break; } @@ -817,8 +805,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case REQUEST_MAILBOX_DATA: - DEBUG - ("FT1000:download: REQUEST_MAILBOX_DATA\n"); + pr_debug("REQUEST_MAILBOX_DATA\n"); /* Convert length from byte count to word count. Make sure we round up. */ word_length = (long)(pft1000info->DSPInfoBlklen + @@ -852,8 +839,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case REQUEST_VERSION_INFO: - DEBUG - ("FT1000:download:REQUEST_VERSION_INFO\n"); + pr_debug("REQUEST_VERSION_INFO\n"); word_length = file_hdr->version_data_size; put_request_value(ft1000dev, @@ -887,8 +873,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; case REQUEST_CODE_BY_VERSION: - DEBUG - ("FT1000:download:REQUEST_CODE_BY_VERSION\n"); + pr_debug("REQUEST_CODE_BY_VERSION\n"); correct_version = false; requested_version = get_request_value(ft1000dev); @@ -907,8 +892,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, if (dsp_img_info->version == requested_version) { correct_version = true; - DEBUG - ("FT1000:download: correct_version is TRUE\n"); + pr_debug("correct_version is TRUE\n"); s_file = (u16 *) (pFileStart + @@ -941,8 +925,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* * Error, beyond boot code range. */ - DEBUG - ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", + pr_debug("Download error: Bad Version Request = 0x%x.\n", (int)requested_version); status = -1; break; @@ -950,8 +933,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; default: - DEBUG - ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", + pr_debug("Download error: Bad request type=%d in CODE download state.\n", request); status = -1; break; @@ -963,20 +945,19 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, put_handshake(ft1000dev, HANDSHAKE_RESPONSE); } else { - DEBUG - ("FT1000:download:Download error: Handshake failed\n"); + pr_debug("Download error: Handshake failed\n"); status = -1; } break; case STATE_DONE_DWNLD: - DEBUG("FT1000:download:Code loader is done...\n"); + pr_debug("Code loader is done...\n"); state = STATE_SECTION_PROV; break; case STATE_SECTION_PROV: - DEBUG("FT1000:download:STATE_SECTION_PROV\n"); + pr_debug("STATE_SECTION_PROV\n"); pseudo_header = (struct pseudo_hdr *)c_file; if (pseudo_header->checksum == @@ -1031,13 +1012,12 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Checksum did not compute */ status = -1; } - DEBUG - ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", + pr_debug("after STATE_SECTION_PROV, state = %d, status= %d\n", state, status); break; case STATE_DONE_PROV: - DEBUG("FT1000:download:STATE_DONE_PROV\n"); + pr_debug("STATE_DONE_PROV\n"); state = STATE_DONE_FILE; break; @@ -1064,7 +1044,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } /* End while */ - DEBUG("Download exiting with status = 0x%8x\n", status); + pr_debug("Download exiting with status = 0x%8x\n", status); ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index da1195574640..d12cfc9aa32a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -4,6 +4,8 @@ * This file is part of Express Card USB Driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -52,7 +54,7 @@ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, int ret; if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) { - DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n"); + pr_debug("ft1000dev or ft1000dev->dev == NULL, failure\n"); return -ENODEV; } @@ -212,7 +214,7 @@ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, *buffer++ = buf[pos++]; *buffer++ = buf[pos++]; } else { - DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n"); + pr_debug("DPRAM32 Read failed\n"); *buffer++ = 0; *buffer++ = 0; *buffer++ = 0; @@ -246,7 +248,7 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) buf[pos2++] = *buffer++; ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16); } else { - DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n"); + pr_debug("DPRAM32 Read failed\n"); return ret; } @@ -270,8 +272,7 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) for (i = 0; i < 16; i++) { if (tempbuffer[i] != resultbuffer[i]) { ret = -1; - DEBUG("%s Failed to write\n", - __func__); + pr_debug("Failed to write\n"); } } } @@ -292,14 +293,14 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) FT1000_REG_SUP_CTRL); if (value) { - DEBUG("Reset DSP\n"); + pr_debug("Reset DSP\n"); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); tempword |= DSP_RESET_BIT; status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); } else { - DEBUG("Activate DSP\n"); + pr_debug("Activate DSP\n"); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); tempword |= DSP_ENCRYPTED; @@ -329,7 +330,7 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, unsigned short temp; unsigned char *commandbuf; - DEBUG("card_send_command: enter card_send_command... size=%d\n", size); + pr_debug("enter card_send_command... size=%d\n", size); commandbuf = kmalloc(size + 2, GFP_KERNEL); if (!commandbuf) @@ -364,7 +365,7 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, #if 0 if ((temp & 0x0100) == 0) - DEBUG("card_send_command: Message sent\n"); + pr_debug("Message sent\n"); #endif return ret; } @@ -390,7 +391,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); msleep(1000); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - DEBUG("Reset Register = 0x%x\n", tempword); + pr_debug("Reset Register = 0x%x\n", tempword); /* Toggle DSP reset */ card_reset_dsp(ft1000dev, 1); @@ -405,7 +406,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) status = ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (u8 *)&templong, 4); - DEBUG("templong (fefe) = 0x%8x\n", templong); + pr_debug("templong (fefe) = 0x%8x\n", templong); /* call codeloader */ status = scram_dnldr(ft1000dev, pFileStart, FileLength); @@ -415,8 +416,6 @@ int dsp_reload(struct ft1000_usb *ft1000dev) msleep(1000); - DEBUG("dsp_reload returned\n"); - return 0; } @@ -427,8 +426,6 @@ static void ft1000_reset_asic(struct net_device *dev) struct ft1000_usb *ft1000dev = info->priv; u16 tempword; - DEBUG("ft1000_hw:ft1000_reset_asic called\n"); - /* Let's use the register provided by the Magnemite ASIC to reset the * ASIC and DSP. */ @@ -442,10 +439,10 @@ static void ft1000_reset_asic(struct net_device *dev) /* clear interrupts */ ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); ft1000_write_register(ft1000dev, tempword, FT1000_REG_SUP_ISR); ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); + pr_debug("interrupt status register = 0x%x\n", tempword); } static int ft1000_reset_card(struct net_device *dev) @@ -455,15 +452,13 @@ static int ft1000_reset_card(struct net_device *dev) u16 tempword; struct prov_record *ptr; - DEBUG("ft1000_hw:ft1000_reset_card called.....\n"); - ft1000dev->fCondResetPend = true; info->CardReady = 0; ft1000dev->fProvComplete = false; /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { - DEBUG("ft1000_reset_card:deleting provisioning record\n"); + pr_debug("deleting provisioning record\n"); ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); @@ -471,13 +466,13 @@ static int ft1000_reset_card(struct net_device *dev) kfree(ptr); } - DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n"); + pr_debug("reset asic\n"); ft1000_reset_asic(dev); - DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n"); + pr_debug("call dsp_reload\n"); dsp_reload(ft1000dev); - DEBUG("dsp reload successful\n"); + pr_debug("dsp reload successful\n"); mdelay(10); @@ -486,7 +481,7 @@ static int ft1000_reset_card(struct net_device *dev) FT1000_MAG_HI_HO_INDX); ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX); - DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); + pr_debug("hi_ho value = 0x%x\n", tempword); info->CardReady = 1; @@ -520,14 +515,13 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) struct pseudo_hdr hdr; if (!pInfo->CardReady) { - DEBUG("ft1000_copy_down_pkt::Card Not Ready\n"); + pr_debug("Card Not Ready\n"); return -ENODEV; } count = sizeof(struct pseudo_hdr) + len; if (count > MAX_BUF_SIZE) { - DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n"); - DEBUG("size = %d\n", count); + pr_debug("Message Size Overflow! size = %d\n", count); return -EINVAL; } @@ -564,7 +558,7 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC); if (ret) { - DEBUG("ft1000 failed tx_urb %d\n", ret); + pr_debug("failed tx_urb %d\n", ret); return ret; } pInfo->stats.tx_packets++; @@ -585,12 +579,12 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) int maxlen, pipe; if (skb == NULL) { - DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n"); + pr_debug("skb == NULL!!!\n"); return NETDEV_TX_OK; } if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); goto err; } @@ -602,13 +596,13 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) if (pInfo->mediastate == 0) { /* Drop packet is mediastate is down */ - DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n"); + pr_debug("mediastate is down\n"); goto err; } if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { /* Drop packet which has invalid size */ - DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n"); + pr_debug("invalid ethernet length\n"); goto err; } @@ -628,7 +622,7 @@ static int ft1000_open(struct net_device *dev) struct ft1000_usb *pFt1000Dev = pInfo->priv; struct timeval tv; - DEBUG("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber); + pr_debug("ft1000_open is called for card %d\n", pFt1000Dev->CardNumber); pInfo->stats.rx_bytes = 0; pInfo->stats.tx_bytes = 0; @@ -676,11 +670,9 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) char card_nr[2]; u8 gCardIndex = 0; - DEBUG("Enter init_ft1000_netdev...\n"); - netdev = alloc_etherdev(sizeof(struct ft1000_info)); if (!netdev) { - DEBUG("init_ft1000_netdev: can not allocate network device\n"); + pr_debug("can not allocate network device\n"); return -ENOMEM; } @@ -690,7 +682,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) dev_alloc_name(netdev, netdev->name); - DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name); + pr_debug("network device name is %s\n", netdev->name); if (strncmp(netdev->name, "eth", 3) == 0) { card_nr[0] = netdev->name[3]; @@ -702,7 +694,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) } ft1000dev->CardNumber = gCardIndex; - DEBUG("card number = %d\n", ft1000dev->CardNumber); + pr_debug("card number = %d\n", ft1000dev->CardNumber); } else { netdev_err(ft1000dev->net, "ft1000: Invalid device name\n"); ret_val = -ENXIO; @@ -738,7 +730,7 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) ft1000dev->net = netdev; - DEBUG("Initialize free_buff_lock and freercvpool\n"); + pr_debug("Initialize free_buff_lock and freercvpool\n"); spin_lock_init(&free_buff_lock); /* initialize a list of buffers to be use for queuing @@ -790,7 +782,6 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, netdev = ft1000dev->net; pInfo = netdev_priv(ft1000dev->net); - DEBUG("Enter reg_ft1000_netdev...\n"); ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID); @@ -799,15 +790,13 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, rc = register_netdev(netdev); if (rc) { - DEBUG("reg_ft1000_netdev: could not register network device\n"); + pr_debug("could not register network device\n"); free_netdev(netdev); return rc; } ft1000_create_dev(ft1000dev); - DEBUG("reg_ft1000_netdev returned\n"); - pInfo->CardReady = 1; return 0; @@ -832,7 +821,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) u16 *chksum; if (ft1000dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); return 0; } /* Read length */ @@ -854,7 +843,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) skb = dev_alloc_skb(len + 12 + 2); if (skb == NULL) { - DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); + pr_debug("No Network buffers available\n"); info->stats.rx_errors++; ft1000_submit_rx_urb(info); return -1; @@ -905,7 +894,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) struct ft1000_usb *pFt1000Dev = info->priv; if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { - DEBUG("network driver is closed, return\n"); + pr_debug("network driver is closed, return\n"); return -ENODEV; } @@ -919,8 +908,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC); if (result) { - pr_err("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", - result); + pr_err("submitting rx_urb %d failed\n", result); return result; } @@ -935,7 +923,7 @@ int ft1000_close(struct net_device *net) ft1000dev->status |= FT1000_STATUS_CLOSING; - DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); + pr_debug("pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); netif_carrier_off(net); netif_stop_queue(net); ft1000dev->status &= ~FT1000_STATUS_CLOSING; @@ -952,7 +940,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) int status; if (dev->fCondResetPend) { - DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); + pr_debug("Card is being reset, return FALSE\n"); return TRUE; } /* Mask register is used to check for device presence since it is never @@ -960,7 +948,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) */ status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + pr_debug("IMASK = 0 Card not detected\n"); return FALSE; } /* The system will return the value of 0xffff for the version register @@ -969,7 +957,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); if (tempword != 0x1b01) { dev->status |= FT1000_STATUS_CLOSING; - DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + pr_debug("Version = 0xffff Card not detected\n"); return FALSE; } return TRUE; @@ -994,8 +982,7 @@ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, FT1000_MAG_PH_LEN_INDX); size = ntohs(size) + PSEUDOSZ; if (size > maxsz) { - DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", - size); + pr_debug("Invalid command length = %d\n", size); return FALSE; } ppseudohdr = (u16 *)pbuffer; @@ -1058,17 +1045,15 @@ static int ft1000_dsp_prov(void *arg) int status; u16 TempShortBuf[256]; - DEBUG("*** DspProv Entered\n"); - while (list_empty(&info->prov_list) == 0) { - DEBUG("DSP Provisioning List Entry\n"); + pr_debug("DSP Provisioning List Entry\n"); /* Check if doorbell is available */ - DEBUG("check if doorbell is cleared\n"); + pr_debug("check if doorbell is cleared\n"); status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); if (status) { - DEBUG("ft1000_dsp_prov::ft1000_read_register error\n"); + pr_debug("ft1000_read_register error\n"); break; } @@ -1076,7 +1061,7 @@ static int ft1000_dsp_prov(void *arg) mdelay(10); i++; if (i == 10) { - DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); + pr_debug("message drop\n"); return -1; } ft1000_read_register(dev, &tempword, @@ -1084,7 +1069,7 @@ static int ft1000_dsp_prov(void *arg) } if (!(tempword & FT1000_DB_DPRAM_TX)) { - DEBUG("*** Provision Data Sent to DSP\n"); + pr_debug("*** Provision Data Sent to DSP\n"); /* Send provisioning data */ ptr = @@ -1123,7 +1108,7 @@ static int ft1000_dsp_prov(void *arg) usleep_range(9000, 11000); } - DEBUG("DSP Provisioning List Entry finished\n"); + pr_debug("DSP Provisioning List Entry finished\n"); msleep(100); @@ -1158,37 +1143,26 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); #ifdef JDEBUG - DEBUG("ft1000_proc_drvmsg:cmdbuffer\n"); - for (i = 0; i < size; i += 5) { - if ((i + 5) < size) - DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i], - cmdbuffer[i + 1], cmdbuffer[i + 2], - cmdbuffer[i + 3], cmdbuffer[i + 4]); - else { - for (j = i; j < size; j++) - DEBUG("0x%x ", cmdbuffer[j]); - DEBUG("\n"); - break; - } - } + print_hex_dump_debug("cmdbuffer: ", HEX_DUMP_OFFSET, 16, 1, + cmdbuffer, size, true); #endif pdrvmsg = (struct drv_msg *)&cmdbuffer[2]; msgtype = ntohs(pdrvmsg->type); - DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); + pr_debug("Command message type = 0x%x\n", msgtype); switch (msgtype) { case MEDIA_STATE:{ - DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); + pr_debug("Command message type = MEDIA_STATE\n"); pmediamsg = (struct media_msg *)&cmdbuffer[0]; if (info->ProgConStat != 0xFF) { if (pmediamsg->state) { - DEBUG("Media is up\n"); + pr_debug("Media is up\n"); if (info->mediastate == 0) { if (dev->NetDevRegDone) netif_wake_queue(dev->net); info->mediastate = 1; } } else { - DEBUG("Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; if (dev->NetDevRegDone) @@ -1196,7 +1170,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) } } } else { - DEBUG("Media is down\n"); + pr_debug("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; info->ConTm = 0; @@ -1205,20 +1179,20 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) break; } case DSP_INIT_MSG:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + pr_debug("Command message type = DSP_INIT_MSG\n"); pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); + pr_debug("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, HWSERNUMSZ); memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); - DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", - info->eui64[0], info->eui64[1], info->eui64[2], - info->eui64[3], info->eui64[4], info->eui64[5], - info->eui64[6], info->eui64[7]); + pr_debug("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", + info->eui64[0], info->eui64[1], info->eui64[2], + info->eui64[3], info->eui64[4], info->eui64[5], + info->eui64[6], info->eui64[7]); dev->net->dev_addr[0] = info->eui64[0]; dev->net->dev_addr[1] = info->eui64[1]; dev->net->dev_addr[2] = info->eui64[2]; @@ -1233,13 +1207,13 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ); - DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], - info->RfCalVer[1]); + pr_debug("RFCalVer = 0x%2x 0x%2x\n", + info->RfCalVer[0], info->RfCalVer[1]); } break; } case DSP_PROVISION:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + pr_debug("Command message type = DSP_PROVISION\n"); /* kick off dspprov routine to start provisioning * Send provisioning data to DSP @@ -1253,20 +1227,19 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) dev->fProvComplete = true; status = ft1000_write_register(dev, FT1000_DB_HB, FT1000_REG_DOORBELL); - DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); + pr_debug("No more DSP provisioning data in dsp image\n"); } - DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); + pr_debug("DSP PROVISION is done\n"); break; } case DSP_STORE_INFO:{ - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); - DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); + pr_debug("Command message type = DSP_STORE_INFO"); tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { pmsg = (u16 *)&pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); + pr_debug("dsp info data = 0x%x\n", *pmsg); info->DSPInfoBlk[i + 10] = *pmsg++; } } else { @@ -1275,7 +1248,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) break; } case DSP_GET_INFO:{ - DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); + pr_debug("Got DSP_GET_INFO\n"); /* copy dsp info block to dsp */ dev->DrvMsgPend = 1; /* allow any outstanding ioctl to finish */ @@ -1331,7 +1304,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) break; } case GET_DRV_ERR_RPT_MSG:{ - DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + pr_debug("Got GET_DRV_ERR_RPT_MSG\n"); /* copy driver error message to dsp */ dev->DrvMsgPend = 1; /* allow any outstanding ioctl to finish */ @@ -1399,7 +1372,6 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) status = 0; out: kfree(cmdbuffer); - DEBUG("return from ft1000_proc_drvmsg\n"); return status; } @@ -1417,7 +1389,7 @@ static int dsp_broadcast_msg_id(struct ft1000_usb *dev) < MAX_MSG_LIMIT)) { pdpram_blk = ft1000_get_buffer(&freercvpool); if (pdpram_blk == NULL) { - DEBUG("Out of memory in free receive command pool\n"); + pr_debug("Out of memory in free receive command pool\n"); dev->app_info[i].nRxMsgMiss++; return -1; } @@ -1437,7 +1409,7 @@ static int dsp_broadcast_msg_id(struct ft1000_usb *dev) } else { dev->app_info[i].nRxMsgMiss++; ft1000_free_buffer(pdpram_blk, &freercvpool); - DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); + pr_debug("ft1000_get_buffer NULL\n"); return -1; } } @@ -1452,7 +1424,7 @@ static int handle_misc_portid(struct ft1000_usb *dev) pdpram_blk = ft1000_get_buffer(&freercvpool); if (pdpram_blk == NULL) { - DEBUG("Out of memory in free receive command pool\n"); + pr_debug("Out of memory in free receive command pool\n"); return -1; } if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE)) @@ -1465,7 +1437,8 @@ static int handle_misc_portid(struct ft1000_usb *dev) break; } if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); + pr_debug("No application matching id = %d\n", + ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); goto exit_failure; } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { goto exit_failure; @@ -1495,7 +1468,7 @@ int ft1000_poll(void *dev_id) u16 portid; if (ft1000_chkcard(dev) == FALSE) { - DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); + pr_debug("failed\n"); return -1; } status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); @@ -1514,7 +1487,7 @@ int ft1000_poll(void *dev_id) if (size < MAX_CMD_SQSIZE) { switch (portid) { case DRIVERID: - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); status = ft1000_proc_drvmsg(dev, size); if (status != 0) return status; @@ -1527,7 +1500,8 @@ int ft1000_poll(void *dev_id) break; } } else - DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); + pr_debug("Invalid total length for SlowQ = %d\n", + size); status = ft1000_write_register(dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL); @@ -1547,7 +1521,7 @@ int ft1000_poll(void *dev_id) break; } if (i == 100) { - DEBUG("Unable to reset ASIC\n"); + pr_debug("Unable to reset ASIC\n"); return 0; } usleep_range(9000, 11000); @@ -1560,7 +1534,7 @@ int ft1000_poll(void *dev_id) FT1000_REG_DOORBELL); usleep_range(9000, 11000); } else if (tempword & FT1000_ASIC_RESET_REQ) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); /* clear ASIC reset request from DSP */ status = ft1000_write_register(dev, FT1000_ASIC_RESET_REQ, @@ -1579,7 +1553,7 @@ int ft1000_poll(void *dev_id) FT1000_ASIC_RESET_DSP, FT1000_REG_DOORBELL); } else if (tempword & FT1000_DB_COND_RESET) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); + pr_debug("FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); if (!dev->fAppMsgPend) { /* Reset ASIC and DSP */ status = ft1000_read_dpram16(dev, @@ -1600,7 +1574,7 @@ int ft1000_poll(void *dev_id) FT1000_MAG_DSP_TIMER3_INDX); info->CardReady = 0; info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG("ft1000_hw:DSP conditional reset requested\n"); + pr_debug("DSP conditional reset requested\n"); info->ft1000_reset(dev->net); } else { dev->fProvComplete = false; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 244e3d66d599..a6b55f42c07c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -7,6 +7,9 @@ * $Id: *==================================================== */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -45,7 +48,7 @@ static int ft1000_poll_thread(void *arg) if (!gPollingfailed) { ret = ft1000_poll(arg); if (ret != 0) { - DEBUG("ft1000_poll_thread: polling failed\n"); + pr_debug("polling failed\n"); gPollingfailed = true; } } @@ -71,9 +74,8 @@ static int ft1000_probe(struct usb_interface *interface, return -ENOMEM; dev = interface_to_usbdev(interface); - DEBUG("ft1000_probe: usb device descriptor info:\n"); - DEBUG("ft1000_probe: number of configuration is %d\n", - dev->descriptor.bNumConfigurations); + pr_debug("usb device descriptor info - number of configuration is %d\n", + dev->descriptor.bNumConfigurations); ft1000dev->dev = dev; ft1000dev->status = 0; @@ -85,42 +87,38 @@ static int ft1000_probe(struct usb_interface *interface, goto err_fw; } - DEBUG("ft1000_probe is called\n"); numaltsetting = interface->num_altsetting; - DEBUG("ft1000_probe: number of alt settings is :%d\n", numaltsetting); + pr_debug("number of alt settings is: %d\n", numaltsetting); iface_desc = interface->cur_altsetting; - DEBUG("ft1000_probe: number of endpoints is %d\n", - iface_desc->desc.bNumEndpoints); - DEBUG("ft1000_probe: descriptor type is %d\n", - iface_desc->desc.bDescriptorType); - DEBUG("ft1000_probe: interface number is %d\n", - iface_desc->desc.bInterfaceNumber); - DEBUG("ft1000_probe: alternatesetting is %d\n", - iface_desc->desc.bAlternateSetting); - DEBUG("ft1000_probe: interface class is %d\n", - iface_desc->desc.bInterfaceClass); - DEBUG("ft1000_probe: control endpoint info:\n"); - DEBUG("ft1000_probe: descriptor0 type -- %d\n", - iface_desc->endpoint[0].desc.bmAttributes); - DEBUG("ft1000_probe: descriptor1 type -- %d\n", - iface_desc->endpoint[1].desc.bmAttributes); - DEBUG("ft1000_probe: descriptor2 type -- %d\n", - iface_desc->endpoint[2].desc.bmAttributes); + pr_debug("number of endpoints is: %d\n", + iface_desc->desc.bNumEndpoints); + pr_debug("descriptor type is: %d\n", iface_desc->desc.bDescriptorType); + pr_debug("interface number is: %d\n", + iface_desc->desc.bInterfaceNumber); + pr_debug("alternatesetting is: %d\n", + iface_desc->desc.bAlternateSetting); + pr_debug("interface class is: %d\n", iface_desc->desc.bInterfaceClass); + pr_debug("control endpoint info:\n"); + pr_debug("descriptor0 type -- %d\n", + iface_desc->endpoint[0].desc.bmAttributes); + pr_debug("descriptor1 type -- %d\n", + iface_desc->endpoint[1].desc.bmAttributes); + pr_debug("descriptor2 type -- %d\n", + iface_desc->endpoint[2].desc.bmAttributes); for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = (struct usb_endpoint_descriptor *)&iface_desc-> endpoint[i].desc; - DEBUG("endpoint %d\n", i); - DEBUG("bEndpointAddress=%x, bmAttributes=%x\n", - endpoint->bEndpointAddress, endpoint->bmAttributes); + pr_debug("endpoint %d\n", i); + pr_debug("bEndpointAddress=%x, bmAttributes=%x\n", + endpoint->bEndpointAddress, endpoint->bmAttributes); if ((endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; - DEBUG("ft1000_probe: in: %d\n", - endpoint->bEndpointAddress); + pr_debug("in: %d\n", endpoint->bEndpointAddress); } if (!(endpoint->bEndpointAddress & USB_DIR_IN) @@ -128,17 +126,17 @@ static int ft1000_probe(struct usb_interface *interface, USB_ENDPOINT_XFER_BULK)) { ft1000dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; - DEBUG("ft1000_probe: out: %d\n", - endpoint->bEndpointAddress); + pr_debug("out: %d\n", endpoint->bEndpointAddress); } } - DEBUG("bulk_in=%d, bulk_out=%d\n", ft1000dev->bulk_in_endpointAddr, - ft1000dev->bulk_out_endpointAddr); + pr_debug("bulk_in=%d, bulk_out=%d\n", + ft1000dev->bulk_in_endpointAddr, + ft1000dev->bulk_out_endpointAddr); ret = request_firmware(&dsp_fw, "ft3000.img", &dev->dev); if (ret < 0) { - pr_err("Error request_firmware().\n"); + pr_err("Error request_firmware()\n"); goto err_fw; } @@ -155,7 +153,7 @@ static int ft1000_probe(struct usb_interface *interface, FileLength = dsp_fw->size; release_firmware(dsp_fw); - DEBUG("ft1000_probe: start downloading dsp image...\n"); + pr_debug("start downloading dsp image...\n"); ret = init_ft1000_netdev(ft1000dev); if (ret) @@ -163,7 +161,7 @@ static int ft1000_probe(struct usb_interface *interface, pft1000info = netdev_priv(ft1000dev->net); - DEBUG("In probe: pft1000info=%p\n", pft1000info); + pr_debug("pft1000info=%p\n", pft1000info); ret = dsp_reload(ft1000dev); if (ret) { pr_err("Problem with DSP image loading\n"); @@ -187,10 +185,10 @@ static int ft1000_probe(struct usb_interface *interface, goto err_thread; } msleep(100); - DEBUG("ft1000_probe::Waiting for Card Ready\n"); + pr_debug("Waiting for Card Ready\n"); } - DEBUG("ft1000_probe::Card Ready!!!! Registering network device\n"); + pr_debug("Card Ready!!!! Registering network device\n"); ret = reg_ft1000_netdev(ft1000dev, interface); if (ret) @@ -216,24 +214,21 @@ static void ft1000_disconnect(struct usb_interface *interface) struct ft1000_info *pft1000info; struct ft1000_usb *ft1000dev; - DEBUG("ft1000_disconnect is called\n"); - pft1000info = (struct ft1000_info *)usb_get_intfdata(interface); - DEBUG("In disconnect pft1000info=%p\n", pft1000info); + pr_debug("In disconnect pft1000info=%p\n", pft1000info); if (pft1000info) { ft1000dev = pft1000info->priv; if (ft1000dev->pPollThread) kthread_stop(ft1000dev->pPollThread); - DEBUG("ft1000_disconnect: threads are terminated\n"); + pr_debug("threads are terminated\n"); if (ft1000dev->net) { - DEBUG("ft1000_disconnect: destroy char driver\n"); + pr_debug("destroy char driver\n"); ft1000_destroy_dev(ft1000dev->net); unregister_netdev(ft1000dev->net); - DEBUG - ("ft1000_disconnect: network device unregistered\n"); + pr_debug("network device unregistered\n"); free_netdev(ft1000dev->net); } @@ -241,7 +236,7 @@ static void ft1000_disconnect(struct usb_interface *interface) usb_free_urb(ft1000dev->rx_urb); usb_free_urb(ft1000dev->tx_urb); - DEBUG("ft1000_disconnect: urb freed\n"); + pr_debug("urb freed\n"); kfree(ft1000dev); } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 418e6df91910..fea60d5651a7 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -28,8 +28,6 @@ struct app_info_block { */ } __packed; -#define DEBUG(args...) pr_info(args) - #define FALSE 0 #define TRUE 1 -- GitLab From 7be921a226dcbbbd8fb6f5d63bea4856b3a11624 Mon Sep 17 00:00:00 2001 From: Jia He Date: Tue, 4 Nov 2014 09:39:58 +0800 Subject: [PATCH 2884/9457] staging: rtl8188eu: Fix coding style space related ERROR problems This fixes space related ERROR reports by checkpatch.pl Generated by $ git ls-files "drivers/staging/rtl8188eu/*.[ch]" | \ xargs ./scripts/checkpatch.pl -f --fix-inplace --strict --types=SPACING Already checked by text comparasion $git diff -w and binary comparasion of r8188eu.ko $objdiff diff Signed-off-by: Jia He Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_cmd.c | 2 +- .../staging/rtl8188eu/core/rtw_ieee80211.c | 16 ++++----- drivers/staging/rtl8188eu/core/rtw_mlme.c | 2 +- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 22 ++++++------ drivers/staging/rtl8188eu/core/rtw_recv.c | 12 +++---- drivers/staging/rtl8188eu/core/rtw_security.c | 20 +++++------ drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 2 +- drivers/staging/rtl8188eu/core/rtw_xmit.c | 10 +++--- drivers/staging/rtl8188eu/hal/bb_cfg.c | 2 +- drivers/staging/rtl8188eu/hal/fw.c | 8 ++--- drivers/staging/rtl8188eu/hal/mac_cfg.c | 2 +- drivers/staging/rtl8188eu/hal/odm.c | 8 ++--- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 2 +- drivers/staging/rtl8188eu/hal/odm_RTL8188E.c | 2 +- drivers/staging/rtl8188eu/hal/phy.c | 2 +- drivers/staging/rtl8188eu/hal/rf.c | 2 +- drivers/staging/rtl8188eu/hal/rf_cfg.c | 4 +-- drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c | 2 +- .../staging/rtl8188eu/hal/rtl8188eu_xmit.c | 2 +- drivers/staging/rtl8188eu/hal/usb_halinit.c | 2 +- .../staging/rtl8188eu/include/ieee80211_ext.h | 20 +++++------ .../staging/rtl8188eu/include/osdep_service.h | 4 +-- drivers/staging/rtl8188eu/include/rtw_debug.h | 2 +- drivers/staging/rtl8188eu/include/rtw_led.h | 2 +- .../staging/rtl8188eu/include/rtw_mlme_ext.h | 26 +++++++------- drivers/staging/rtl8188eu/include/wifi.h | 36 +++++++++---------- .../staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- drivers/staging/rtl8188eu/os_dep/os_intfs.c | 2 +- .../staging/rtl8188eu/os_dep/usb_ops_linux.c | 4 +-- drivers/staging/rtl8188eu/os_dep/xmit_linux.c | 2 +- 30 files changed, 112 insertions(+), 112 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index dd24138d13b1..a1cc788fe4b3 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -637,7 +637,7 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) ether_addr_copy(psetstakey_para->addr, sta->hwaddr); if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm; + psetstakey_para->algorithm = (unsigned char)psecuritypriv->dot11PrivacyAlgrthm; else GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c index 755d3effd0a7..f2c3ca79c0c9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c @@ -159,7 +159,7 @@ u8 *rtw_set_ie return pbuf + len + 2; } -inline u8 *rtw_set_ie_ch_switch (u8 *buf, u32 *buf_len, u8 ch_switch_mode, +inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt) { u8 ie_data[3]; @@ -870,7 +870,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, if (elen < 4) { if (show_errors) { DBG_88E("short vendor specific information element ignored (len=%lu)\n", - (unsigned long) elen); + (unsigned long)elen); } return -1; } @@ -890,7 +890,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ if (elen < 5) { DBG_88E("short WME information element ignored (len=%lu)\n", - (unsigned long) elen); + (unsigned long)elen); return -1; } switch (pos[4]) { @@ -905,7 +905,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("unknown WME information element ignored (subtype=%d len=%lu)\n", - pos[4], (unsigned long) elen); + pos[4], (unsigned long)elen); return -1; } break; @@ -916,7 +916,7 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("Unknown Microsoft information element ignored (type=%d len=%lu)\n", - pos[3], (unsigned long) elen); + pos[3], (unsigned long)elen); return -1; } break; @@ -929,13 +929,13 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, break; default: DBG_88E("Unknown Broadcom information element ignored (type=%d len=%lu)\n", - pos[3], (unsigned long) elen); + pos[3], (unsigned long)elen); return -1; } break; default: DBG_88E("unknown vendor specific information element ignored (vendor OUI %02x:%02x:%02x len=%lu)\n", - pos[0], pos[1], pos[2], (unsigned long) elen); + pos[0], pos[1], pos[2], (unsigned long)elen); return -1; } return 0; @@ -969,7 +969,7 @@ enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len, if (elen > left) { if (show_errors) { DBG_88E("IEEE 802.11 element parse failed (id=%d elen=%d left=%lu)\n", - id, elen, (unsigned long) left); + id, elen, (unsigned long)left); } return ParseFailed; } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c index dec26a89c356..d4632da50c1d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c @@ -2115,7 +2115,7 @@ void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitfr if (0 == issued) { DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority); psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); - rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra); + rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra); } } } diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index a00ebcddc881..b0e92372fa5e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -227,7 +227,7 @@ static void init_mlme_ext_priv_value(struct adapter *padapter) pmlmeext->cur_channel = padapter->registrypriv.channel; pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - pmlmeext->oper_channel = pmlmeext->cur_channel ; + pmlmeext->oper_channel = pmlmeext->cur_channel; pmlmeext->oper_bwmode = pmlmeext->cur_bwmode; pmlmeext->oper_ch_offset = pmlmeext->cur_ch_offset; pmlmeext->retry = 0; @@ -2000,7 +2000,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) DBG_88E("%s, alloc mgnt frame fail\n", __func__); return; } -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) spin_lock_bh(&pmlmepriv->bcn_update_lock); #endif /* if defined (CONFIG_88EU_AP_MODE) */ @@ -2027,7 +2027,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) SetFrameSubType(pframe, WIFI_BEACON); pframe += sizeof(struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { int len_diff; @@ -2042,8 +2042,8 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) ); pframe += (cur_network->IELength+len_diff); pattrib->pktlen += (cur_network->IELength+len_diff); - wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, - pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); + wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, + pattrib->pktlen-sizeof(struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); if (wps_ie && wps_ielen > 0) rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); if (sr != 0) @@ -2101,7 +2101,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) /* todo:HT for adhoc */ _issue_bcn: -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) pmlmepriv->update_bcn = false; spin_unlock_bh(&pmlmepriv->bcn_update_lock); @@ -2130,7 +2130,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p __le16 *fctrl; unsigned char *mac, *bssid; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); -#if defined (CONFIG_88EU_AP_MODE) +#if defined(CONFIG_88EU_AP_MODE) u8 *pwps_ie; uint wps_ielen; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -2323,8 +2323,8 @@ static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps pmlmeext->mgnt_seq++; SetFrameSubType(pframe, WIFI_PROBEREQ); - pframe += sizeof (struct rtw_ieee80211_hdr_3addr); - pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); if (pssid) pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); @@ -3209,7 +3209,7 @@ int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int return ret; } -void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) +void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset) { struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; @@ -3260,7 +3260,7 @@ void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); } - pframe = rtw_set_ie_ch_switch (pframe, &(pattrib->pktlen), 0, new_ch, 0); + pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0); pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen), hal_ch_offset_to_secondary_ch_offset(ch_offset)); diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 53a054c189e4..a1619b88733f 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -46,7 +46,7 @@ void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS); void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) { - memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv)); + memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); spin_lock_init(&psta_recvpriv->lock); @@ -109,7 +109,7 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) return res; } -void _rtw_free_recv_priv (struct recv_priv *precvpriv) +void _rtw_free_recv_priv(struct recv_priv *precvpriv) { struct adapter *padapter = precvpriv->adapter; @@ -124,7 +124,7 @@ void _rtw_free_recv_priv (struct recv_priv *precvpriv) } -struct recv_frame *_rtw_alloc_recvframe (struct __queue *pfree_recv_queue) +struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue) { struct recv_frame *hdr; struct list_head *plist, *phead; @@ -797,7 +797,7 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, return ret; } -static int ap2sta_data_frame ( +static int ap2sta_data_frame( struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta) @@ -1266,7 +1266,7 @@ static int validate_recv_frame(struct adapter *adapter, u8 bDumpRxPkt; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; u8 *ptr = precv_frame->rx_data; - u8 ver = (unsigned char) (*ptr)&0x3; + u8 ver = (unsigned char)(*ptr)&0x3; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; @@ -1981,7 +1981,7 @@ static int process_recv_indicatepkts(struct adapter *padapter, } } } else { /* B/G mode */ - retval = wlanhdr_to_ethhdr (prframe); + retval = wlanhdr_to_ethhdr(prframe); if (retval != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n")); return retval; diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c index 1baa98e636e1..bd8d60a230e9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_security.c +++ b/drivers/staging/rtl8188eu/core/rtw_security.c @@ -189,7 +189,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 4); + pframe = (u8 *)round_up((size_t)(pframe), 4); } } } @@ -258,7 +258,7 @@ static void secmicputuint32(u8 *p, u32 val) { long i; for (i = 0; i < 4; i++) { - *p++ = (u8) (val & 0xff); + *p++ = (u8)(val & 0xff); val >>= 8; } } @@ -621,14 +621,14 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); } else { - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/ arcfour_init(&mycontext, rc4key, 16); arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 4); + pframe = (u8 *)round_up((size_t)(pframe), 4); } } } else { @@ -953,8 +953,8 @@ static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu, mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ for (i = 8; i < 14; i++) mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ - mic_iv[14] = (unsigned char) (payload_length / 256); - mic_iv[15] = (unsigned char) (payload_length % 256); + mic_iv[14] = (unsigned char)(payload_length / 256); + mic_iv[15] = (unsigned char)(payload_length % 256); } /************************************************/ @@ -1045,8 +1045,8 @@ static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ for (i = 8; i < 14; i++) ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ - ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char) (c % 256); + ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ + ctr_preload[15] = (unsigned char)(c % 256); } /************************************/ @@ -1238,11 +1238,11 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe) aes_cipher(prwskey, pattrib->hdrlen, pframe, length); } else{ - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; aes_cipher(prwskey, pattrib->hdrlen, pframe, length); pframe += pxmitpriv->frag_len; - pframe = (u8 *) round_up((size_t)(pframe), 8); + pframe = (u8 *)round_up((size_t)(pframe), 8); } } } else{ diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c index e1dc8fa82d38..dc9d0ddf6b3a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c @@ -29,7 +29,7 @@ static void _rtw_init_stainfo(struct sta_info *psta) { - memset((u8 *)psta, 0, sizeof (struct sta_info)); + memset((u8 *)psta, 0, sizeof(struct sta_info)); spin_lock_init(&psta->lock); INIT_LIST_HEAD(&psta->list); diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index 639ace06a3d6..a0bbf9093338 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -37,7 +37,7 @@ static void _init_txservq(struct tx_servq *ptxservq) void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) { - memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv)); + memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv)); spin_lock_init(&psta_xmitpriv->lock); _init_txservq(&psta_xmitpriv->be_q); _init_txservq(&psta_xmitpriv->bk_q); @@ -223,7 +223,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) return res; } -void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv) +void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) { int i; struct adapter *padapter = pxmitpriv->adapter; @@ -691,7 +691,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr payload = pframe; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { - payload = (u8 *) round_up((size_t)(payload), 4); + payload = (u8 *)round_up((size_t)(payload), 4); RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n", curfragnum, *payload, *(payload+1), @@ -772,7 +772,7 @@ static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmi return _SUCCESS; } -s32 rtw_make_wlanhdr (struct adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) +s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) { u16 *qc; @@ -1098,7 +1098,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct addr = (size_t)(pframe); - mem_start = (unsigned char *) round_up(addr, 4) + hw_hdr_offset; + mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset; memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); } diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c index c2d166fa0a7f..1e963bf9e48b 100644 --- a/drivers/staging/rtl8188eu/hal/bb_cfg.c +++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c @@ -552,7 +552,7 @@ static void store_pwrindex_offset(struct adapter *Adapter, u32 regaddr, u32 bitm } } -static void rtl_addr_delay(struct adapter *adapt, u32 addr, u32 bit_mask ,u32 data) +static void rtl_addr_delay(struct adapter *adapt, u32 addr, u32 bit_mask, u32 data) { if (addr == 0xfe) { msleep(50); diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c index 17b7f3750547..3b2875481fc5 100644 --- a/drivers/staging/rtl8188eu/hal/fw.c +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -84,7 +84,7 @@ static void _rtl88e_fw_block_write(struct adapter *adapt, static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) { u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); + u8 remain = (u8)(fwlen % 4); remain = (remain == 0) ? 0 : (4 - remain); @@ -101,7 +101,7 @@ static void _rtl88e_fw_page_write(struct adapter *adapt, u32 page, const u8 *buffer, u32 size) { u8 value8; - u8 u8page = (u8) (page & 0x07); + u8 u8page = (u8)(page & 0x07); value8 = (usb_read8(adapt, REG_MCUFWDL + 2) & 0xF8) | u8page; @@ -193,13 +193,13 @@ int rtl88eu_download_fw(struct adapter *adapt) u32 fwsize; int err; - if (request_firmware(&fw, fw_name, device)){ + if (request_firmware(&fw, fw_name, device)) { dev_err(device, "Firmware %s not available\n", fw_name); return -ENOENT; } if (fw->size > FW_8188E_SIZE) { - dev_err(device,"Firmware size exceed 0x%X. Check it.\n", + dev_err(device, "Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE); return -1; } diff --git a/drivers/staging/rtl8188eu/hal/mac_cfg.c b/drivers/staging/rtl8188eu/hal/mac_cfg.c index c0e7fa938059..febc83a5adb8 100644 --- a/drivers/staging/rtl8188eu/hal/mac_cfg.c +++ b/drivers/staging/rtl8188eu/hal/mac_cfg.c @@ -127,7 +127,7 @@ bool rtl88eu_phy_mac_config(struct adapter *adapt) ptrarray = array_MAC_REG_8188E; for (i = 0; i < arraylength; i = i + 2) - usb_write8(adapt, ptrarray[i], (u8) ptrarray[i + 1]); + usb_write8(adapt, ptrarray[i], (u8)ptrarray[i + 1]); usb_write8(adapt, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); return true; diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c index e4df83710ca6..9873998011d2 100644 --- a/drivers/staging/rtl8188eu/hal/odm.c +++ b/drivers/staging/rtl8188eu/hal/odm.c @@ -437,8 +437,8 @@ void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) { struct adapter *adapter = pDM_Odm->Adapter; - pDM_Odm->bCckHighPower = (bool) phy_query_bb_reg(adapter, 0x824, BIT9); - pDM_Odm->RFPathRxEnable = (u8) phy_query_bb_reg(adapter, 0xc04, 0x0F); + pDM_Odm->bCckHighPower = (bool)phy_query_bb_reg(adapter, 0x824, BIT9); + pDM_Odm->RFPathRxEnable = (u8)phy_query_bb_reg(adapter, 0xc04, 0x0F); ODM_InitDebugSetting(pDM_Odm); } @@ -529,7 +529,7 @@ void odm_DIGInit(struct odm_dm_struct *pDM_Odm) struct adapter *adapter = pDM_Odm->Adapter; struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; - pDM_DigTable->CurIGValue = (u8) phy_query_bb_reg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N); + pDM_DigTable->CurIGValue = (u8)phy_query_bb_reg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N); pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; pDM_DigTable->FALowThresh = DM_false_ALARM_THRESH_LOW; @@ -620,7 +620,7 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm) } else if (pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) { /* 1 Lower Bound for 88E AntDiv */ if (pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) { - DIG_Dynamic_MIN = (u8) pDM_DigTable->AntDiv_RSSI_max; + DIG_Dynamic_MIN = (u8)pDM_DigTable->AntDiv_RSSI_max; ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_DIG(): pDM_DigTable->AntDiv_RSSI_max=%d\n", pDM_DigTable->AntDiv_RSSI_max)); diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 4e4e21936e7c..29f87dffbad3 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -118,7 +118,7 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm, cck_highpwr = dm_odm->bCckHighPower; - cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; + cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a; /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */ /* The RSSI formula should be modified according to the gain table */ diff --git a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c index 5342af778eb0..d3c6873925ba 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RTL8188E.c @@ -278,7 +278,7 @@ static void rtl88eu_dm_hw_ant_div(struct odm_dm_struct *dm_odm) struct rtw_dig *dig_table = &dm_odm->DM_DigTable; struct sta_info *entry; u32 i, min_rssi = 0xFF, ant_div_max_rssi = 0, max_rssi = 0; - u32 local_min_rssi,local_max_rssi; + u32 local_min_rssi, local_max_rssi; u32 main_rssi, aux_rssi; u8 RxIdleAnt = 0, target_ant = 7; diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c index c4f7f358a81c..3f663fe151ba 100644 --- a/drivers/staging/rtl8188eu/hal/phy.c +++ b/drivers/staging/rtl8188eu/hal/phy.c @@ -478,7 +478,7 @@ void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt) /* 2.4G, decrease power */ {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11}, /* 2.4G, increase power */ - {0, 0, -1, -2, -3, -4,-4, -4, -4, -5, -7, -8,-9, -9, -10}, + {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}, }; u8 thermal_mapping[2][index_mapping_NUM_88E] = { /* 2.4G, decrease power */ diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c index c2fac34c8132..eea4c8a6022b 100644 --- a/drivers/staging/rtl8188eu/hal/rf.c +++ b/drivers/staging/rtl8188eu/hal/rf.c @@ -131,7 +131,7 @@ void rtl88eu_phy_rf6052_set_cck_txpower(struct adapter *adapt, u8 *powerlevel) /* powerbase1 for HT MCS rates */ static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm, u8 *pwr_level_bw20, u8 *pwr_level_bw40, - u8 channel,u32 *ofdmbase, u32 *mcs_base) + u8 channel, u32 *ofdmbase, u32 *mcs_base) { struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); u32 powerbase0, powerbase1; diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c index ddc2f55fe13f..5dc11cae2ef9 100644 --- a/drivers/staging/rtl8188eu/hal/rf_cfg.c +++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c @@ -164,7 +164,7 @@ do { \ #define B3WIREDATALENGTH 0x800 #define BRFSI_RFENV 0x10 -static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath,u32 addr, u32 mask, u32 data) +static void rtl_rfreg_delay(struct adapter *adapt, enum rf_radio_path rfpath, u32 addr, u32 mask, u32 data) { if (addr == 0xfe) { mdelay(50); @@ -190,7 +190,7 @@ static void rtl8188e_config_rf_reg(struct adapter *adapt, u32 content = 0x1000; /*RF Content: radio_a_txt*/ u32 maskforphyset = (u32)(content & 0xE000); - rtl_rfreg_delay(adapt, RF90_PATH_A, addr| maskforphyset, + rtl_rfreg_delay(adapt, RF90_PATH_A, addr | maskforphyset, RFREG_OFFSET_MASK, data); } diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c index ce55d9d9f0f6..7f30dea1b53b 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c @@ -252,7 +252,7 @@ void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt) { u8 opmode, macid; u16 mst_rpt = le16_to_cpu(mstatus_rpt); - opmode = (u8) mst_rpt; + opmode = (u8)mst_rpt; macid = (u8)(mst_rpt >> 8); DBG_88E("### %s: MStatus=%x MACID=%d\n", __func__, opmode, macid); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c index be9eede6931d..594c1da9db23 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c @@ -399,7 +399,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe) mem_addr += w_sz; - mem_addr = (u8 *) round_up((size_t)mem_addr, 4); + mem_addr = (u8 *)round_up((size_t)mem_addr, 4); } rtw_free_xmitframe(pxmitpriv, pxmitframe); diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index ac6abac58bfe..14650e91c78a 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -2012,7 +2012,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV u8 bRSSIDump = *((u8 *)pValue); struct odm_dm_struct *dm_ocm = &(haldata->odmpriv); if (bRSSIDump) - dm_ocm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT ; + dm_ocm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT; else dm_ocm->DebugComponents = 0; } diff --git a/drivers/staging/rtl8188eu/include/ieee80211_ext.h b/drivers/staging/rtl8188eu/include/ieee80211_ext.h index 1052d1817a97..15e53d380ad0 100644 --- a/drivers/staging/rtl8188eu/include/ieee80211_ext.h +++ b/drivers/staging/rtl8188eu/include/ieee80211_ext.h @@ -103,24 +103,24 @@ struct wme_parameter_element { #define WPA_PUT_LE16(a, val) \ do { \ - (a)[1] = ((u16) (val)) >> 8; \ - (a)[0] = ((u16) (val)) & 0xff; \ + (a)[1] = ((u16)(val)) >> 8; \ + (a)[0] = ((u16)(val)) & 0xff; \ } while (0) #define WPA_PUT_BE32(a, val) \ do { \ - (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[3] = (u8) (((u32) (val)) & 0xff); \ + (a)[0] = (u8)((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8)((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8)((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8)(((u32) (val)) & 0xff); \ } while (0) #define WPA_PUT_LE32(a, val) \ do { \ - (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ - (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ - (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ - (a)[0] = (u8) (((u32) (val)) & 0xff); \ + (a)[3] = (u8)((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8)((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8)((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8)(((u32) (val)) & 0xff); \ } while (0) #define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *)(a), (val)) diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h index fed9c86890b4..82f58f87656a 100644 --- a/drivers/staging/rtl8188eu/include/osdep_service.h +++ b/drivers/staging/rtl8188eu/include/osdep_service.h @@ -182,8 +182,8 @@ u64 rtw_modular64(u64 x, u64 y); /* Macros for handling unaligned memory accesses */ -#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ - ((u32) (a)[2])) +#define RTW_GET_BE24(a) ((((u32)(a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32)(a)[2])) void rtw_buf_free(u8 **buf, u32 *buf_len); void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h index a38616e3cad2..971bf457f32d 100644 --- a/drivers/staging/rtl8188eu/include/rtw_debug.h +++ b/drivers/staging/rtl8188eu/include/rtw_debug.h @@ -106,7 +106,7 @@ extern u32 GlobalDebugLevel; u8 *ptr = (u8 *)_hexdata; \ pr_info("%s", DRIVER_PREFIX); \ pr_info(_titlestring); \ - for (__i = 0; __i < (int)_hexdatalen; __i++ ) { \ + for (__i = 0; __i < (int)_hexdatalen; __i++) { \ pr_info("%02X%s", ptr[__i], \ (((__i + 1) % 4) == 0) ? \ " " : " "); \ diff --git a/drivers/staging/rtl8188eu/include/rtw_led.h b/drivers/staging/rtl8188eu/include/rtw_led.h index c5194b620da4..dec8dbc483b4 100644 --- a/drivers/staging/rtl8188eu/include/rtw_led.h +++ b/drivers/staging/rtl8188eu/include/rtw_led.h @@ -92,7 +92,7 @@ struct LED_871x { void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction); -struct led_priv{ +struct led_priv { /* add for led control */ struct LED_871x SwLed0; u8 bRegUseLed; diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h index d699ca19ef16..8d72ccf5f2a0 100644 --- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h @@ -448,7 +448,7 @@ struct mlme_ext_priv { int init_mlme_ext_priv(struct adapter *adapter); int init_hw_mlme_ext(struct adapter *padapter); -void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); +void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext); extern void init_mlme_ext_timer(struct adapter *padapter); extern void init_addba_retry_timer(struct adapter *adapt, struct sta_info *sta); extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); @@ -646,8 +646,8 @@ void mlmeext_sta_add_event_callback(struct adapter *padapter, void linked_status_chk(struct adapter *padapter); -void survey_timer_hdl (void *function_context); -void link_timer_hdl (void *funtion_context); +void survey_timer_hdl(void *function_context); +void link_timer_hdl(void *funtion_context); void addba_timer_hdl(void *function_context); #define set_survey_timer(mlmeext, ms) \ @@ -708,15 +708,15 @@ u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf); #ifdef _RTW_CMD_C_ static struct cmd_hdl wlancmds[] = { - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) - GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), tx_beacon_hdl) @@ -787,7 +787,7 @@ static struct fwevent wlanevents[] = { {0, NULL}, {0, NULL}, {0, &rtw_survey_event_callback}, /*8*/ - {sizeof (struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ + {sizeof(struct surveydone_event), &rtw_surveydone_event_callback},/*9*/ {0, &rtw_joinbss_event_callback}, /*10*/ {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, {sizeof(struct stadel_event), &rtw_stadel_event_callback}, diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h index a88ebf41bba1..8dbdfafd52b5 100644 --- a/drivers/staging/rtl8188eu/include/wifi.h +++ b/drivers/staging/rtl8188eu/include/wifi.h @@ -766,27 +766,27 @@ enum ht_cap_ampdu_factor { #define OP_MODE_20MHZ_HT_STA_ASSOCED 2 #define OP_MODE_MIXED 3 -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) -#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) -#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) -#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) -#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) -#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8)BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8)BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8)BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8)BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8)BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8)BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8)BIT(5)) #define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ - ((u16) (0x0001 | 0x0002)) + ((u16)(0x0001 | 0x0002)) #define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 -#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) -#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) -#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) - -#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) -#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) -#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16) BIT(8)) -#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) -#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) -#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8)BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8)BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8)BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16)BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16)BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BC ((u16)BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16)BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16)BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16)BIT(11)) /* ===============WPS Section=============== */ /* For WPSv1.0 */ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 08ba7d3e6c69..f34fb29ae225 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -361,7 +361,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, param->u.crypt.err = 0; param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - if (param_len < (u32) ((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { + if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) { ret = -EINVAL; goto exit; } diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 08a80f759b8d..0b488d29bd37 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -527,7 +527,7 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) registry_par->channel = (u8)rtw_channel; registry_par->wireless_mode = (u8)rtw_wireless_mode; - registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; + registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense; registry_par->vcs_type = (u8)rtw_vcs_type; registry_par->rts_thresh = (u16)rtw_rts_thresh; registry_par->frag_thresh = (u16)rtw_frag_thresh; diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c index 7da85f9c127b..d2efa9dfc8c0 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c @@ -160,10 +160,10 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb) switch (haldata->UsbRxAggMode) { case USB_RX_AGG_DMA: case USB_RX_AGG_MIX: - pkt_offset = (u16) round_up(pkt_offset, 128); + pkt_offset = (u16)round_up(pkt_offset, 128); break; case USB_RX_AGG_USB: - pkt_offset = (u16) round_up(pkt_offset, 4); + pkt_offset = (u16)round_up(pkt_offset, 4); break; case USB_RX_AGG_DISABLE: default: diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c index 0ce47b07ef86..d5e41a52a0eb 100644 --- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c @@ -46,7 +46,7 @@ void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile) } -uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) +uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) { uint len = 0; -- GitLab From 2a68c897246b70a0c6b51a4a7d48d19b56b3e76b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 4 Nov 2014 08:45:45 +0200 Subject: [PATCH 2885/9457] Bluetooth: Fix sparse warnings in RFCOMM This patch fixes the following sparse warnings in rfcomm/core.c: net/bluetooth/rfcomm/core.c:391:16: warning: dubious: x | !y net/bluetooth/rfcomm/core.c:546:24: warning: dubious: x | !y Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/rfcomm/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index bce9c3d39324..64e20dde4837 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -81,6 +81,8 @@ static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); #define __test_cr(b) (!!(b & 0x02)) #define __test_pf(b) (!!(b & 0x10)) +#define __session_dir(s) ((s)->initiator ? 0x00 : 0x01) + #define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01) #define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) #define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir) @@ -388,7 +390,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, return err; } - dlci = __dlci(!s->initiator, channel); + dlci = __dlci(__session_dir(s), channel); /* Check if DLCI already exists */ if (rfcomm_dlc_get(s, dlci)) @@ -543,7 +545,7 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel) rfcomm_lock(); s = rfcomm_session_get(src, dst); if (s) { - dlci = __dlci(!s->initiator, channel); + dlci = __dlci(__session_dir(s), channel); dlc = rfcomm_dlc_get(s, dlci); } rfcomm_unlock(); -- GitLab From 2c4cc91b0b43ae364d47b0eec560b8e5bd5af746 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 3 Nov 2014 20:51:45 -0500 Subject: [PATCH 2886/9457] drm: Fix DRM_FORCE_ON_DIGITAL use A connector may be forced on from the command line via video= command line setting. The digital output of dual-mode connectors can also be specifically selected and forced on; eg., 'video=DVI-I-2:D'. However, in this case, the connector->status will be mistakenly set to connector_status_disconnected, and the connector will not be mode set. Fix the connector->status when connector->force is DRM_FORCE_ON_DIGITAL. Note that this seems to have been broken ever since the introduction of the connector forcing support in commit d50ba256b5f1478e15accfcfda9b72fd7a661364 Author: Dave Airlie Date: Wed Sep 23 14:44:08 2009 +1000 drm/kms: start adding command line interface using fb. Signed-off-by: Peter Hurley [danvet: Add note about that this never worked.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_probe_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 6857e9ad6339..7483a47de8e4 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -118,7 +118,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect mode->status = MODE_UNVERIFIED; if (connector->force) { - if (connector->force == DRM_FORCE_ON) + if (connector->force == DRM_FORCE_ON || + connector->force == DRM_FORCE_ON_DIGITAL) connector->status = connector_status_connected; else connector->status = connector_status_disconnected; -- GitLab From b74c6c92f2839206a3714a00af53b4bdc24c7224 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 3 Nov 2014 20:53:41 -0500 Subject: [PATCH 2887/9457] drm: Remove compiler BUG_ON() test modeset->num_connectors must be 0 to reach the BUG_ON() which tests for non-zero modeset->num_connectors; remove BUG_ON(). Signed-off-by: Peter Hurley Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0c0c39bac23d..09d47e9ba026 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1570,7 +1570,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) modeset = &fb_helper->crtc_info[i].mode_set; if (modeset->num_connectors == 0) { BUG_ON(modeset->fb); - BUG_ON(modeset->num_connectors); if (modeset->mode) drm_mode_destroy(dev, modeset->mode); modeset->mode = NULL; -- GitLab From 0563921abf01a7a38b5f670c3de05dc0b0b8617d Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Mon, 3 Nov 2014 20:06:47 +0200 Subject: [PATCH 2888/9457] ieee80211: add "max length of AMPDU" enum for VHT Maximum length of AMPDU that an STA can receive in VHT. length = 2 ^ (13 + max_ampdu_length_exp) - 1. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 5fab17b382b5..f65b5446d983 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1274,7 +1274,7 @@ struct ieee80211_ht_cap { #define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2 /* - * Maximum length of AMPDU that the STA can receive. + * Maximum length of AMPDU that the STA can receive in high-throughput (HT). * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) */ enum ieee80211_max_ampdu_length_exp { @@ -1284,6 +1284,21 @@ enum ieee80211_max_ampdu_length_exp { IEEE80211_HT_MAX_AMPDU_64K = 3 }; +/* + * Maximum length of AMPDU that the STA can receive in VHT. + * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + */ +enum ieee80211_vht_max_ampdu_length_exp { + IEEE80211_VHT_MAX_AMPDU_8K = 0, + IEEE80211_VHT_MAX_AMPDU_16K = 1, + IEEE80211_VHT_MAX_AMPDU_32K = 2, + IEEE80211_VHT_MAX_AMPDU_64K = 3, + IEEE80211_VHT_MAX_AMPDU_128K = 4, + IEEE80211_VHT_MAX_AMPDU_256K = 5, + IEEE80211_VHT_MAX_AMPDU_512K = 6, + IEEE80211_VHT_MAX_AMPDU_1024K = 7 +}; + #define IEEE80211_HT_MAX_AMPDU_FACTOR 13 /* Minimum MPDU start spacing */ -- GitLab From 5b3dc42b1b0db0264bbbe4ae44c15ab97bfd1e93 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 26 Oct 2014 00:32:53 +0200 Subject: [PATCH 2889/9457] mac80211: add support for driver tx power reporting The configured tx power is often limited by hardware capabilities, channel settings, antenna configuration, etc. Signed-off-by: Felix Fietkau [fix tracing compilation] Signed-off-by: Johannes Berg --- include/net/mac80211.h | 5 +++++ net/mac80211/cfg.c | 3 +++ net/mac80211/driver-ops.h | 14 ++++++++++++++ net/mac80211/trace.h | 27 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1614b2fc3bf6..03edbf6f6230 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2857,6 +2857,9 @@ enum ieee80211_roc_type { * @get_expected_throughput: extract the expected throughput towards the * specified station. The returned value is expressed in Kbps. It returns 0 * if the RC algorithm does not have proper data to provide. + * + * @get_txpower: get current maximum tx power (in dBm) based on configuration + * and hardware limits. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -3065,6 +3068,8 @@ struct ieee80211_ops { int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); u32 (*get_expected_throughput)(struct ieee80211_sta *sta); + int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int *dbm); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fbcc209687c8..b9659b8b70f8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2133,6 +2133,9 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); + if (local->ops->get_txpower) + return drv_get_txpower(local, sdata, dbm); + if (!local->use_chanctx) *dbm = local->hw.conf.power_level; else diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 3df28e0fa045..d1e128e5db41 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1279,4 +1279,18 @@ static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, return ret; } +static inline int drv_get_txpower(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, int *dbm) +{ + int ret; + + if (!local->ops->get_txpower) + return -EOPNOTSUPP; + + ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); + trace_drv_get_txpower(local, sdata, *dbm, ret); + + return ret; +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 976606aebac9..aeeace5ba47b 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2150,6 +2150,33 @@ DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch, TP_ARGS(local, sdata) ); +TRACE_EVENT(drv_get_txpower, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + int dbm, int ret), + + TP_ARGS(local, sdata, dbm, ret), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __field(int, dbm) + __field(int, ret) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + __entry->dbm = dbm; + __entry->ret = ret; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret + ) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- GitLab From 2603fe21b764eb7412598c8c6cd6199fb8b1d9c5 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 3 Nov 2014 21:35:48 +0100 Subject: [PATCH 2890/9457] ALSA: es18xx: Add GPO controls Add GPO0 and GPO1 (General Purpose Outputs) controls to mixer. These can be used on some cards to control amplifier mute (seen in ES1868 datasheet) or additional onboard chips such as QX2130 QXpander processor. These GPOs are present on ES1868, ES1869, ES1887 and ES1888 chips. Tested on ES1868 with QX2130. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai --- sound/isa/es18xx.c | 52 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 63e7323e218f..b481bb8c31bc 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -156,6 +156,7 @@ struct snd_es18xx { #define ES18XX_I2S 0x0200 /* I2S mixer control */ #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */ #define ES18XX_CONTROL 0x0800 /* Has control ports */ +#define ES18XX_GPO_2BIT 0x1000 /* GPO0,1 controlled by PM port */ /* Power Management */ #define ES18XX_PM 0x07 @@ -1120,11 +1121,14 @@ static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg) return snd_es18xx_read(chip, reg); } -#define ES18XX_SINGLE(xname, xindex, reg, shift, mask, invert) \ +#define ES18XX_SINGLE(xname, xindex, reg, shift, mask, flags) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_es18xx_info_single, \ .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \ - .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } + .private_value = reg | (shift << 8) | (mask << 16) | (flags << 24) } + +#define ES18XX_FL_INVERT (1 << 0) +#define ES18XX_FL_PMPORT (1 << 1) static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1143,10 +1147,14 @@ static int snd_es18xx_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; + int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; int val; - - val = snd_es18xx_reg_read(chip, reg); + + if (pm_port) + val = inb(chip->port + ES18XX_PM); + else + val = snd_es18xx_reg_read(chip, reg); ucontrol->value.integer.value[0] = (val >> shift) & mask; if (invert) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; @@ -1159,7 +1167,8 @@ static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 8) & 0xff; int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 24) & ES18XX_FL_INVERT; + int pm_port = (kcontrol->private_value >> 24) & ES18XX_FL_PMPORT; unsigned char val; val = (ucontrol->value.integer.value[0] & mask); @@ -1167,6 +1176,15 @@ static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e val = mask - val; mask <<= shift; val <<= shift; + if (pm_port) { + unsigned char cur = inb(chip->port + ES18XX_PM); + + if ((cur & mask) == val) + return 0; + outb((cur & ~mask) | val, chip->port + ES18XX_PM); + return 1; + } + return snd_es18xx_reg_bits(chip, reg, mask, val) != val; } @@ -1288,7 +1306,7 @@ static struct snd_kcontrol_new snd_es18xx_opt_speaker = ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0); static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { -ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), +ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, ES18XX_FL_INVERT), ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0), ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) @@ -1347,6 +1365,11 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = { ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), }; +static struct snd_kcontrol_new snd_es18xx_opt_gpo_2bit[] = { +ES18XX_SINGLE("GPO0 Switch", 0, ES18XX_PM, 0, 1, ES18XX_FL_PMPORT), +ES18XX_SINGLE("GPO1 Switch", 0, ES18XX_PM, 1, 1, ES18XX_FL_PMPORT), +}; + static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) { int data; @@ -1613,10 +1636,10 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, switch (chip->version) { case 0x1868: - chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL; + chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_GPO_2BIT; break; case 0x1869: - chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV; + chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV | ES18XX_GPO_2BIT; break; case 0x1878: chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; @@ -1626,7 +1649,7 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, break; case 0x1887: case 0x1888: - chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; + chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_GPO_2BIT; break; default: snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", @@ -1928,6 +1951,15 @@ static int snd_es18xx_mixer(struct snd_card *card) return err; } } + if (chip->caps & ES18XX_GPO_2BIT) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_gpo_2bit); idx++) { + err = snd_ctl_add(card, + snd_ctl_new1(&snd_es18xx_opt_gpo_2bit[idx], + chip)); + if (err < 0) + return err; + } + } return 0; } -- GitLab From 8c9952b26b2be25311706082598e5e176eb92748 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 3 Nov 2014 16:09:58 -0500 Subject: [PATCH 2891/9457] HID: logitech-hidpp: fix negated returns Reported by Dan Carpenter: drivers/hid/hid-logitech-hidpp.c:359 hidpp_root_get_protocol_version() warn: should this return really be negated? drivers/hid/hid-logitech-hidpp.c:398 hidpp_devicenametype_get_count() warn: should this return really be negated? drivers/hid/hid-logitech-hidpp.c:417 hidpp_devicenametype_get_device_name() warn: should this return really be negated? drivers/hid/hid-logitech-hidpp.c:524 hidpp_touchpad_get_raw_info() warn: should this return really be negated? The problem lies in hidpp_send_message_sync() which can return 2 types of errors depending of their sign. Adding a comment there to clarify what is happening. To solve that, print an error in case of a protocol problem, and raise -EPROTO instead. Reported-by: Dan Carpenter Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 36 ++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 8d2d54b527b0..61f9e75c45d2 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -151,6 +151,14 @@ static int __hidpp_send_report(struct hid_device *hdev, return ret == fields_count ? 0 : -1; } +/** + * hidpp_send_message_sync() returns 0 in case of success, and something else + * in case of a failure. + * - If ' something else' is positive, that means that an error has been raised + * by the protocol itself. + * - If ' something else' is negative, that means that we had a classic error + * (-ENOMEM, -EPIPE, etc...) + */ static int hidpp_send_message_sync(struct hidpp_device *hidpp, struct hidpp_report *message, struct hidpp_report *response) @@ -359,8 +367,13 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) return 0; } + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } if (ret) - return -ret; + return ret; hidpp->protocol_major = response.fap.params[0]; hidpp->protocol_minor = response.fap.params[1]; @@ -398,8 +411,13 @@ static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp, ret = hidpp_send_fap_command_sync(hidpp, feature_index, CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } if (ret) - return -ret; + return ret; *nameLength = response.fap.params[0]; @@ -417,8 +435,13 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1, &response); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } if (ret) - return -ret; + return ret; if (response.report_id == REPORT_ID_HIDPP_LONG) count = HIDPP_REPORT_LONG_LENGTH - 4; @@ -524,8 +547,13 @@ static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp, ret = hidpp_send_fap_command_sync(hidpp, feature_index, CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } if (ret) - return -ret; + return ret; raw_info->x_size = get_unaligned_be16(¶ms[0]); raw_info->y_size = get_unaligned_be16(¶ms[2]); -- GitLab From 552f12eb68440a0328dc9929066f6d0321a75874 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 3 Nov 2014 16:09:59 -0500 Subject: [PATCH 2892/9457] HID: logitech-hidpp: 2 fixes in hidpp_root_get_protocol_version() - remove the constant '1' - when the device is not connected, the protocol error HIDPP_ERROR_RESOURCE_ERROR is raised. We should not warn the user about it because it is somewhat expected as an answer when we check if the device is connected. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-hidpp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 61f9e75c45d2..1a6395d0c2bd 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -361,12 +361,16 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) CMD_ROOT_GET_PROTOCOL_VERSION, NULL, 0, &response); - if (ret == 1) { + if (ret == HIDPP_ERROR_INVALID_SUBID) { hidpp->protocol_major = 1; hidpp->protocol_minor = 0; return 0; } + /* the device might not be connected */ + if (ret == HIDPP_ERROR_RESOURCE_ERROR) + return -EIO; + if (ret > 0) { hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", __func__, ret); -- GitLab From ee76a9abde4f428a3d342822301ddb8d080d6557 Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Mon, 3 Nov 2014 10:28:11 +0800 Subject: [PATCH 2893/9457] pinctrl: Fix path error in documentation Fix pinconfig include file path. Signed-off-by: Yingjoe Chen Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 98eb94d91a1c..47d84b6ee91b 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -216,4 +216,4 @@ arguments are described below. or 0 to disable debouncing More in-depth documentation on these parameters can be found in - + -- GitLab From 354567e6084c0760dc1e3a164ce4e77c5a943acc Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 3 Nov 2014 13:01:32 +0200 Subject: [PATCH 2894/9457] gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod() The GPIO resources (GpioIo/GpioInt) used in ACPI contain a GPIO number which is relative to the hardware GPIO controller. Typically this number can be translated directly to Linux GPIO number because the mapping is pretty much 1:1. However, when the GPIO driver is using pins exported by a pin controller driver via set of GPIO ranges, the mapping might not be 1:1 anymore and direct translation does not work. In such cases we need to translate the ACPI GPIO number to be suitable for the GPIO controller driver in question by checking all the pin controller GPIO ranges under the given device and using those to get the proper GPIO number. Signed-off-by: Mika Westerberg Acked-by: Rafael J. Wysocki Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 05c6275da224..5be637dffa73 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -11,12 +11,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include "gpiolib.h" @@ -55,6 +57,58 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) return ACPI_HANDLE(gc->dev) == data; } +#ifdef CONFIG_PINCTRL +/** + * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO + * @chip: GPIO chip + * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource + * + * Function takes ACPI GpioIo/GpioInt pin number as a parameter and + * translates it to a corresponding offset suitable to be passed to a + * GPIO controller driver. + * + * Typically the returned offset is same as @pin, but if the GPIO + * controller uses pin controller and the mapping is not contigous the + * offset might be different. + */ +static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin) +{ + struct gpio_pin_range *pin_range; + + /* If there are no ranges in this chip, use 1:1 mapping */ + if (list_empty(&chip->pin_ranges)) + return pin; + + list_for_each_entry(pin_range, &chip->pin_ranges, node) { + const struct pinctrl_gpio_range *range = &pin_range->range; + int i; + + if (range->pins) { + for (i = 0; i < range->npins; i++) { + if (range->pins[i] == pin) + return range->base + i - chip->base; + } + } else { + if (pin >= range->pin_base && + pin < range->pin_base + range->npins) { + unsigned gpio_base; + + gpio_base = range->base - chip->base; + return gpio_base + pin - range->pin_base; + } + } + } + + return -EINVAL; +} +#else +static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, + int pin) +{ + return pin; +} +#endif + /** * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") @@ -69,6 +123,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) struct gpio_chip *chip; acpi_handle handle; acpi_status status; + int offset; status = acpi_get_handle(NULL, path, &handle); if (ACPI_FAILURE(status)) @@ -78,10 +133,11 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) if (!chip) return ERR_PTR(-ENODEV); - if (pin < 0 || pin > chip->ngpio) - return ERR_PTR(-EINVAL); + offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin); + if (offset < 0) + return ERR_PTR(offset); - return gpiochip_get_desc(chip, pin); + return gpiochip_get_desc(chip, offset); } static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) -- GitLab From 6e08d6bbebebcf70f982d7190c4b6dc456cedd57 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 3 Nov 2014 13:01:33 +0200 Subject: [PATCH 2895/9457] pinctrl: Add Intel Cherryview/Braswell pin controller support This driver supports the pin/GPIO controllers found in newer Intel SoCs like Cherryview and Braswell. The driver provides full GPIO support and minimal set of pin controlling funtionality. The driver is based on the original Cherryview GPIO driver authored by Ning Li and Alan Cox. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/pinctrl/intel/Kconfig | 12 + drivers/pinctrl/intel/Makefile | 1 + drivers/pinctrl/intel/pinctrl-cherryview.c | 1519 ++++++++++++++++++++ 3 files changed, 1532 insertions(+) create mode 100644 drivers/pinctrl/intel/pinctrl-cherryview.c diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 957c90386307..b801d869e91c 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -13,3 +13,15 @@ config PINCTRL_BAYTRAIL so only a small amount is available for gpio use. Requires ACPI device enumeration code to set up a platform device. + +config PINCTRL_CHERRYVIEW + tristate "Intel Cherryview/Braswell pinctrl and GPIO driver" + depends on ACPI + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + help + Cherryview/Braswell pinctrl driver provides an interface that + allows configuring of SoC pins and using them as GPIOs. diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index d049b769e327..4c210e4139e2 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile @@ -1,3 +1,4 @@ # Intel pin control drivers obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o +obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c new file mode 100644 index 000000000000..e9f8b39d1a9f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -0,0 +1,1519 @@ +/* + * Cherryview/Braswell pinctrl driver + * + * Copyright (C) 2014, Intel Corporation + * Author: Mika Westerberg + * + * This driver is based on the original Cherryview GPIO driver by + * Ning Li + * Alan Cox + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHV_INTSTAT 0x300 +#define CHV_INTMASK 0x380 + +#define FAMILY_PAD_REGS_OFF 0x4400 +#define FAMILY_PAD_REGS_SIZE 0x400 +#define MAX_FAMILY_PAD_GPIO_NO 15 +#define GPIO_REGS_SIZE 8 + +#define CHV_PADCTRL0 0x000 +#define CHV_PADCTRL0_INTSEL_SHIFT 28 +#define CHV_PADCTRL0_INTSEL_MASK (0xf << CHV_PADCTRL0_INTSEL_SHIFT) +#define CHV_PADCTRL0_TERM_UP BIT(23) +#define CHV_PADCTRL0_TERM_SHIFT 20 +#define CHV_PADCTRL0_TERM_MASK (7 << CHV_PADCTRL0_TERM_SHIFT) +#define CHV_PADCTRL0_TERM_20K 1 +#define CHV_PADCTRL0_TERM_5K 2 +#define CHV_PADCTRL0_TERM_1K 4 +#define CHV_PADCTRL0_PMODE_SHIFT 16 +#define CHV_PADCTRL0_PMODE_MASK (0xf << CHV_PADCTRL0_PMODE_SHIFT) +#define CHV_PADCTRL0_GPIOEN BIT(15) +#define CHV_PADCTRL0_GPIOCFG_SHIFT 8 +#define CHV_PADCTRL0_GPIOCFG_MASK (7 << CHV_PADCTRL0_GPIOCFG_SHIFT) +#define CHV_PADCTRL0_GPIOCFG_GPIO 0 +#define CHV_PADCTRL0_GPIOCFG_GPO 1 +#define CHV_PADCTRL0_GPIOCFG_GPI 2 +#define CHV_PADCTRL0_GPIOCFG_HIZ 3 +#define CHV_PADCTRL0_GPIOTXSTATE BIT(1) +#define CHV_PADCTRL0_GPIORXSTATE BIT(0) + +#define CHV_PADCTRL1 0x004 +#define CHV_PADCTRL1_CFGLOCK BIT(31) +#define CHV_PADCTRL1_INVRXTX_SHIFT 4 +#define CHV_PADCTRL1_INVRXTX_MASK (0xf << CHV_PADCTRL1_INVRXTX_SHIFT) +#define CHV_PADCTRL1_INVRXTX_TXENABLE (2 << CHV_PADCTRL1_INVRXTX_SHIFT) +#define CHV_PADCTRL1_ODEN BIT(3) +#define CHV_PADCTRL1_INVRXTX_RXDATA (4 << CHV_PADCTRL1_INVRXTX_SHIFT) +#define CHV_PADCTRL1_INTWAKECFG_MASK 7 +#define CHV_PADCTRL1_INTWAKECFG_FALLING 1 +#define CHV_PADCTRL1_INTWAKECFG_RISING 2 +#define CHV_PADCTRL1_INTWAKECFG_BOTH 3 +#define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 + +/** + * struct chv_alternate_function - A per group or per pin alternate function + * @pin: Pin number (only used in per pin configs) + * @mode: Mode the pin should be set in + * @invert_oe: Invert OE for this pin + */ +struct chv_alternate_function { + unsigned pin; + u8 mode; + bool invert_oe; +}; + +/** + * struct chv_pincgroup - describes a CHV pin group + * @name: Name of the group + * @pins: An array of pins in this group + * @npins: Number of pins in this group + * @altfunc: Alternate function applied to all pins in this group + * @overrides: Alternate function override per pin or %NULL if not used + * @noverrides: Number of per pin alternate function overrides if + * @overrides != NULL. + */ +struct chv_pingroup { + const char *name; + const unsigned *pins; + size_t npins; + struct chv_alternate_function altfunc; + const struct chv_alternate_function *overrides; + size_t noverrides; +}; + +/** + * struct chv_function - A CHV pinmux function + * @name: Name of the function + * @groups: An array of groups for this function + * @ngroups: Number of groups in @groups + */ +struct chv_function { + const char *name; + const char * const *groups; + size_t ngroups; +}; + +/** + * struct chv_gpio_pinrange - A range of pins that can be used as GPIOs + * @base: Start pin number + * @npins: Number of pins in this range + */ +struct chv_gpio_pinrange { + unsigned base; + unsigned npins; +}; + +/** + * struct chv_community - A community specific configuration + * @uid: ACPI _UID used to match the community + * @pins: All pins in this community + * @npins: Number of pins + * @groups: All groups in this community + * @ngroups: Number of groups + * @functions: All functions in this community + * @nfunctions: Number of functions + * @ngpios: Number of GPIOs in this community + * @gpio_ranges: An array of GPIO ranges in this community + * @ngpio_ranges: Number of GPIO ranges + * @ngpios: Total number of GPIOs in this community + */ +struct chv_community { + const char *uid; + const struct pinctrl_pin_desc *pins; + size_t npins; + const struct chv_pingroup *groups; + size_t ngroups; + const struct chv_function *functions; + size_t nfunctions; + const struct chv_gpio_pinrange *gpio_ranges; + size_t ngpio_ranges; + size_t ngpios; +}; + +/** + * struct chv_pinctrl - CHV pinctrl private structure + * @dev: Pointer to the parent device + * @pctldesc: Pin controller description + * @pctldev: Pointer to the pin controller device + * @chip: GPIO chip in this pin controller + * @regs: MMIO registers + * @lock: Lock to serialize register accesses + * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO + * offset (in GPIO number space) + * @community: Community this pinctrl instance represents + * + * The first group in @groups is expected to contain all pins that can be + * used as GPIOs. + */ +struct chv_pinctrl { + struct device *dev; + struct pinctrl_desc pctldesc; + struct pinctrl_dev *pctldev; + struct gpio_chip chip; + void __iomem *regs; + spinlock_t lock; + unsigned intr_lines[16]; + const struct chv_community *community; +}; + +#define gpiochip_to_pinctrl(c) container_of(c, struct chv_pinctrl, chip) + +#define ALTERNATE_FUNCTION(p, m, i) \ + { \ + .pin = (p), \ + .mode = (m), \ + .invert_oe = (i), \ + } + +#define PIN_GROUP(n, p, m, i) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + .altfunc.mode = (m), \ + .altfunc.invert_oe = (i), \ + } + +#define PIN_GROUP_WITH_OVERRIDE(n, p, m, i, o) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + .altfunc.mode = (m), \ + .altfunc.invert_oe = (i), \ + .overrides = (o), \ + .noverrides = ARRAY_SIZE((o)), \ + } + +#define FUNCTION(n, g) \ + { \ + .name = (n), \ + .groups = (g), \ + .ngroups = ARRAY_SIZE((g)), \ + } + +#define GPIO_PINRANGE(start, end) \ + { \ + .base = (start), \ + .npins = (end) - (start) + 1, \ + } + +static const struct pinctrl_pin_desc southwest_pins[] = { + PINCTRL_PIN(0, "FST_SPI_D2"), + PINCTRL_PIN(1, "FST_SPI_D0"), + PINCTRL_PIN(2, "FST_SPI_CLK"), + PINCTRL_PIN(3, "FST_SPI_D3"), + PINCTRL_PIN(4, "FST_SPI_CS1_B"), + PINCTRL_PIN(5, "FST_SPI_D1"), + PINCTRL_PIN(6, "FST_SPI_CS0_B"), + PINCTRL_PIN(7, "FST_SPI_CS2_B"), + + PINCTRL_PIN(15, "UART1_RTS_B"), + PINCTRL_PIN(16, "UART1_RXD"), + PINCTRL_PIN(17, "UART2_RXD"), + PINCTRL_PIN(18, "UART1_CTS_B"), + PINCTRL_PIN(19, "UART2_RTS_B"), + PINCTRL_PIN(20, "UART1_TXD"), + PINCTRL_PIN(21, "UART2_TXD"), + PINCTRL_PIN(22, "UART2_CTS_B"), + + PINCTRL_PIN(30, "MF_HDA_CLK"), + PINCTRL_PIN(31, "MF_HDA_RSTB"), + PINCTRL_PIN(32, "MF_HDA_SDIO"), + PINCTRL_PIN(33, "MF_HDA_SDO"), + PINCTRL_PIN(34, "MF_HDA_DOCKRSTB"), + PINCTRL_PIN(35, "MF_HDA_SYNC"), + PINCTRL_PIN(36, "MF_HDA_SDI1"), + PINCTRL_PIN(37, "MF_HDA_DOCKENB"), + + PINCTRL_PIN(45, "I2C5_SDA"), + PINCTRL_PIN(46, "I2C4_SDA"), + PINCTRL_PIN(47, "I2C6_SDA"), + PINCTRL_PIN(48, "I2C5_SCL"), + PINCTRL_PIN(49, "I2C_NFC_SDA"), + PINCTRL_PIN(50, "I2C4_SCL"), + PINCTRL_PIN(51, "I2C6_SCL"), + PINCTRL_PIN(52, "I2C_NFC_SCL"), + + PINCTRL_PIN(60, "I2C1_SDA"), + PINCTRL_PIN(61, "I2C0_SDA"), + PINCTRL_PIN(62, "I2C2_SDA"), + PINCTRL_PIN(63, "I2C1_SCL"), + PINCTRL_PIN(64, "I2C3_SDA"), + PINCTRL_PIN(65, "I2C0_SCL"), + PINCTRL_PIN(66, "I2C2_SCL"), + PINCTRL_PIN(67, "I2C3_SCL"), + + PINCTRL_PIN(75, "SATA_GP0"), + PINCTRL_PIN(76, "SATA_GP1"), + PINCTRL_PIN(77, "SATA_LEDN"), + PINCTRL_PIN(78, "SATA_GP2"), + PINCTRL_PIN(79, "MF_SMB_ALERTB"), + PINCTRL_PIN(80, "SATA_GP3"), + PINCTRL_PIN(81, "MF_SMB_CLK"), + PINCTRL_PIN(82, "MF_SMB_DATA"), + + PINCTRL_PIN(90, "PCIE_CLKREQ0B"), + PINCTRL_PIN(91, "PCIE_CLKREQ1B"), + PINCTRL_PIN(92, "GP_SSP_2_CLK"), + PINCTRL_PIN(93, "PCIE_CLKREQ2B"), + PINCTRL_PIN(94, "GP_SSP_2_RXD"), + PINCTRL_PIN(95, "PCIE_CLKREQ3B"), + PINCTRL_PIN(96, "GP_SSP_2_FS"), + PINCTRL_PIN(97, "GP_SSP_2_TXD"), +}; + +static const unsigned southwest_fspi_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static const unsigned southwest_uart0_pins[] = { 16, 20 }; +static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 }; +static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 }; +static const unsigned southwest_i2c0_pins[] = { 61, 65 }; +static const unsigned southwest_hda_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37 }; +static const unsigned southwest_lpe_pins[] = { + 30, 31, 32, 33, 34, 35, 36, 37, 92, 94, 96, 97, +}; +static const unsigned southwest_i2c1_pins[] = { 60, 63 }; +static const unsigned southwest_i2c2_pins[] = { 62, 66 }; +static const unsigned southwest_i2c3_pins[] = { 64, 67 }; +static const unsigned southwest_i2c4_pins[] = { 46, 50 }; +static const unsigned southwest_i2c5_pins[] = { 45, 48 }; +static const unsigned southwest_i2c6_pins[] = { 47, 51 }; +static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 }; +static const unsigned southwest_smbus_pins[] = { 79, 81, 82 }; +static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 }; + +/* LPE I2S TXD pins need to have invert_oe set */ +static const struct chv_alternate_function southwest_lpe_altfuncs[] = { + ALTERNATE_FUNCTION(30, 1, true), + ALTERNATE_FUNCTION(34, 1, true), + ALTERNATE_FUNCTION(97, 1, true), +}; + +/* + * Two spi3 chipselects are available in different mode than the main spi3 + * functionality, which is using mode 1. + */ +static const struct chv_alternate_function southwest_spi3_altfuncs[] = { + ALTERNATE_FUNCTION(76, 3, false), + ALTERNATE_FUNCTION(80, 3, false), +}; + +static const struct chv_pingroup southwest_groups[] = { + PIN_GROUP("uart0_grp", southwest_uart0_pins, 2, false), + PIN_GROUP("uart1_grp", southwest_uart1_pins, 1, false), + PIN_GROUP("uart2_grp", southwest_uart2_pins, 1, false), + PIN_GROUP("hda_grp", southwest_hda_pins, 2, false), + PIN_GROUP("i2c0_grp", southwest_i2c0_pins, 1, true), + PIN_GROUP("i2c1_grp", southwest_i2c1_pins, 1, true), + PIN_GROUP("i2c2_grp", southwest_i2c2_pins, 1, true), + PIN_GROUP("i2c3_grp", southwest_i2c3_pins, 1, true), + PIN_GROUP("i2c4_grp", southwest_i2c4_pins, 1, true), + PIN_GROUP("i2c5_grp", southwest_i2c5_pins, 1, true), + PIN_GROUP("i2c6_grp", southwest_i2c6_pins, 1, true), + PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true), + + PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false, + southwest_lpe_altfuncs), + PIN_GROUP_WITH_OVERRIDE("spi3_grp", southwest_spi3_pins, 2, false, + southwest_spi3_altfuncs), +}; + +static const char * const southwest_uart0_groups[] = { "uart0_grp" }; +static const char * const southwest_uart1_groups[] = { "uart1_grp" }; +static const char * const southwest_uart2_groups[] = { "uart2_grp" }; +static const char * const southwest_hda_groups[] = { "hda_grp" }; +static const char * const southwest_lpe_groups[] = { "lpe_grp" }; +static const char * const southwest_i2c0_groups[] = { "i2c0_grp" }; +static const char * const southwest_i2c1_groups[] = { "i2c1_grp" }; +static const char * const southwest_i2c2_groups[] = { "i2c2_grp" }; +static const char * const southwest_i2c3_groups[] = { "i2c3_grp" }; +static const char * const southwest_i2c4_groups[] = { "i2c4_grp" }; +static const char * const southwest_i2c5_groups[] = { "i2c5_grp" }; +static const char * const southwest_i2c6_groups[] = { "i2c6_grp" }; +static const char * const southwest_i2c_nfc_groups[] = { "i2c_nfc_grp" }; +static const char * const southwest_spi3_groups[] = { "spi3_grp" }; + +/* + * Only do pinmuxing for certain LPSS devices for now. Rest of the pins are + * enabled only as GPIOs. + */ +static const struct chv_function southwest_functions[] = { + FUNCTION("uart0", southwest_uart0_groups), + FUNCTION("uart1", southwest_uart1_groups), + FUNCTION("uart2", southwest_uart2_groups), + FUNCTION("hda", southwest_hda_groups), + FUNCTION("lpe", southwest_lpe_groups), + FUNCTION("i2c0", southwest_i2c0_groups), + FUNCTION("i2c1", southwest_i2c1_groups), + FUNCTION("i2c2", southwest_i2c2_groups), + FUNCTION("i2c3", southwest_i2c3_groups), + FUNCTION("i2c4", southwest_i2c4_groups), + FUNCTION("i2c5", southwest_i2c5_groups), + FUNCTION("i2c6", southwest_i2c6_groups), + FUNCTION("i2c_nfc", southwest_i2c_nfc_groups), + FUNCTION("spi3", southwest_spi3_groups), +}; + +static const struct chv_gpio_pinrange southwest_gpio_ranges[] = { + GPIO_PINRANGE(0, 7), + GPIO_PINRANGE(15, 22), + GPIO_PINRANGE(30, 37), + GPIO_PINRANGE(45, 52), + GPIO_PINRANGE(60, 67), + GPIO_PINRANGE(75, 82), + GPIO_PINRANGE(90, 97), +}; + +static const struct chv_community southwest_community = { + .uid = "1", + .pins = southwest_pins, + .npins = ARRAY_SIZE(southwest_pins), + .groups = southwest_groups, + .ngroups = ARRAY_SIZE(southwest_groups), + .functions = southwest_functions, + .nfunctions = ARRAY_SIZE(southwest_functions), + .gpio_ranges = southwest_gpio_ranges, + .ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges), + .ngpios = ARRAY_SIZE(southwest_pins), +}; + +static const struct pinctrl_pin_desc north_pins[] = { + PINCTRL_PIN(0, "GPIO_DFX_0"), + PINCTRL_PIN(1, "GPIO_DFX_3"), + PINCTRL_PIN(2, "GPIO_DFX_7"), + PINCTRL_PIN(3, "GPIO_DFX_1"), + PINCTRL_PIN(4, "GPIO_DFX_5"), + PINCTRL_PIN(5, "GPIO_DFX_4"), + PINCTRL_PIN(6, "GPIO_DFX_8"), + PINCTRL_PIN(7, "GPIO_DFX_2"), + PINCTRL_PIN(8, "GPIO_DFX_6"), + + PINCTRL_PIN(15, "GPIO_SUS0"), + PINCTRL_PIN(16, "SEC_GPIO_SUS10"), + PINCTRL_PIN(17, "GPIO_SUS3"), + PINCTRL_PIN(18, "GPIO_SUS7"), + PINCTRL_PIN(19, "GPIO_SUS1"), + PINCTRL_PIN(20, "GPIO_SUS5"), + PINCTRL_PIN(21, "SEC_GPIO_SUS11"), + PINCTRL_PIN(22, "GPIO_SUS4"), + PINCTRL_PIN(23, "SEC_GPIO_SUS8"), + PINCTRL_PIN(24, "GPIO_SUS2"), + PINCTRL_PIN(25, "GPIO_SUS6"), + PINCTRL_PIN(26, "CX_PREQ_B"), + PINCTRL_PIN(27, "SEC_GPIO_SUS9"), + + PINCTRL_PIN(30, "TRST_B"), + PINCTRL_PIN(31, "TCK"), + PINCTRL_PIN(32, "PROCHOT_B"), + PINCTRL_PIN(33, "SVIDO_DATA"), + PINCTRL_PIN(34, "TMS"), + PINCTRL_PIN(35, "CX_PRDY_B_2"), + PINCTRL_PIN(36, "TDO_2"), + PINCTRL_PIN(37, "CX_PRDY_B"), + PINCTRL_PIN(38, "SVIDO_ALERT_B"), + PINCTRL_PIN(39, "TDO"), + PINCTRL_PIN(40, "SVIDO_CLK"), + PINCTRL_PIN(41, "TDI"), + + PINCTRL_PIN(45, "GP_CAMERASB_05"), + PINCTRL_PIN(46, "GP_CAMERASB_02"), + PINCTRL_PIN(47, "GP_CAMERASB_08"), + PINCTRL_PIN(48, "GP_CAMERASB_00"), + PINCTRL_PIN(49, "GP_CAMERASB_06"), + PINCTRL_PIN(50, "GP_CAMERASB_10"), + PINCTRL_PIN(51, "GP_CAMERASB_03"), + PINCTRL_PIN(52, "GP_CAMERASB_09"), + PINCTRL_PIN(53, "GP_CAMERASB_01"), + PINCTRL_PIN(54, "GP_CAMERASB_07"), + PINCTRL_PIN(55, "GP_CAMERASB_11"), + PINCTRL_PIN(56, "GP_CAMERASB_04"), + + PINCTRL_PIN(60, "PANEL0_BKLTEN"), + PINCTRL_PIN(61, "HV_DDI0_HPD"), + PINCTRL_PIN(62, "HV_DDI2_DDC_SDA"), + PINCTRL_PIN(63, "PANEL1_BKLTCTL"), + PINCTRL_PIN(64, "HV_DDI1_HPD"), + PINCTRL_PIN(65, "PANEL0_BKLTCTL"), + PINCTRL_PIN(66, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(67, "HV_DDI2_DDC_SCL"), + PINCTRL_PIN(68, "HV_DDI2_HPD"), + PINCTRL_PIN(69, "PANEL1_VDDEN"), + PINCTRL_PIN(70, "PANEL1_BKLTEN"), + PINCTRL_PIN(71, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(72, "PANEL0_VDDEN"), +}; + +static const struct chv_gpio_pinrange north_gpio_ranges[] = { + GPIO_PINRANGE(0, 8), + GPIO_PINRANGE(15, 27), + GPIO_PINRANGE(30, 41), + GPIO_PINRANGE(45, 56), + GPIO_PINRANGE(60, 72), +}; + +static const struct chv_community north_community = { + .uid = "2", + .pins = north_pins, + .npins = ARRAY_SIZE(north_pins), + .gpio_ranges = north_gpio_ranges, + .ngpio_ranges = ARRAY_SIZE(north_gpio_ranges), + .ngpios = ARRAY_SIZE(north_pins), +}; + +static const struct pinctrl_pin_desc east_pins[] = { + PINCTRL_PIN(0, "PMU_SLP_S3_B"), + PINCTRL_PIN(1, "PMU_BATLOW_B"), + PINCTRL_PIN(2, "SUS_STAT_B"), + PINCTRL_PIN(3, "PMU_SLP_S0IX_B"), + PINCTRL_PIN(4, "PMU_AC_PRESENT"), + PINCTRL_PIN(5, "PMU_PLTRST_B"), + PINCTRL_PIN(6, "PMU_SUSCLK"), + PINCTRL_PIN(7, "PMU_SLP_LAN_B"), + PINCTRL_PIN(8, "PMU_PWRBTN_B"), + PINCTRL_PIN(9, "PMU_SLP_S4_B"), + PINCTRL_PIN(10, "PMU_WAKE_B"), + PINCTRL_PIN(11, "PMU_WAKE_LAN_B"), + + PINCTRL_PIN(15, "MF_ISH_GPIO_3"), + PINCTRL_PIN(16, "MF_ISH_GPIO_7"), + PINCTRL_PIN(17, "MF_ISH_I2C1_SCL"), + PINCTRL_PIN(18, "MF_ISH_GPIO_1"), + PINCTRL_PIN(19, "MF_ISH_GPIO_5"), + PINCTRL_PIN(20, "MF_ISH_GPIO_9"), + PINCTRL_PIN(21, "MF_ISH_GPIO_0"), + PINCTRL_PIN(22, "MF_ISH_GPIO_4"), + PINCTRL_PIN(23, "MF_ISH_GPIO_8"), + PINCTRL_PIN(24, "MF_ISH_GPIO_2"), + PINCTRL_PIN(25, "MF_ISH_GPIO_6"), + PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"), +}; + +static const struct chv_gpio_pinrange east_gpio_ranges[] = { + GPIO_PINRANGE(0, 11), + GPIO_PINRANGE(15, 26), +}; + +static const struct chv_community east_community = { + .uid = "3", + .pins = east_pins, + .npins = ARRAY_SIZE(east_pins), + .gpio_ranges = east_gpio_ranges, + .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges), + .ngpios = ARRAY_SIZE(east_pins), +}; + +static const struct pinctrl_pin_desc southeast_pins[] = { + PINCTRL_PIN(0, "MF_PLT_CLK0"), + PINCTRL_PIN(1, "PWM1"), + PINCTRL_PIN(2, "MF_PLT_CLK1"), + PINCTRL_PIN(3, "MF_PLT_CLK4"), + PINCTRL_PIN(4, "MF_PLT_CLK3"), + PINCTRL_PIN(5, "PWM0"), + PINCTRL_PIN(6, "MF_PLT_CLK5"), + PINCTRL_PIN(7, "MF_PLT_CLK2"), + + PINCTRL_PIN(15, "SDMMC2_D3_CD_B"), + PINCTRL_PIN(16, "SDMMC1_CLK"), + PINCTRL_PIN(17, "SDMMC1_D0"), + PINCTRL_PIN(18, "SDMMC2_D1"), + PINCTRL_PIN(19, "SDMMC2_CLK"), + PINCTRL_PIN(20, "SDMMC1_D2"), + PINCTRL_PIN(21, "SDMMC2_D2"), + PINCTRL_PIN(22, "SDMMC2_CMD"), + PINCTRL_PIN(23, "SDMMC1_CMD"), + PINCTRL_PIN(24, "SDMMC1_D1"), + PINCTRL_PIN(25, "SDMMC2_D0"), + PINCTRL_PIN(26, "SDMMC1_D3_CD_B"), + + PINCTRL_PIN(30, "SDMMC3_D1"), + PINCTRL_PIN(31, "SDMMC3_CLK"), + PINCTRL_PIN(32, "SDMMC3_D3"), + PINCTRL_PIN(33, "SDMMC3_D2"), + PINCTRL_PIN(34, "SDMMC3_CMD"), + PINCTRL_PIN(35, "SDMMC3_D0"), + + PINCTRL_PIN(45, "MF_LPC_AD2"), + PINCTRL_PIN(46, "LPC_CLKRUNB"), + PINCTRL_PIN(47, "MF_LPC_AD0"), + PINCTRL_PIN(48, "LPC_FRAMEB"), + PINCTRL_PIN(49, "MF_LPC_CLKOUT1"), + PINCTRL_PIN(50, "MF_LPC_AD3"), + PINCTRL_PIN(51, "MF_LPC_CLKOUT0"), + PINCTRL_PIN(52, "MF_LPC_AD1"), + + PINCTRL_PIN(60, "SPI1_MISO"), + PINCTRL_PIN(61, "SPI1_CSO_B"), + PINCTRL_PIN(62, "SPI1_CLK"), + PINCTRL_PIN(63, "MMC1_D6"), + PINCTRL_PIN(64, "SPI1_MOSI"), + PINCTRL_PIN(65, "MMC1_D5"), + PINCTRL_PIN(66, "SPI1_CS1_B"), + PINCTRL_PIN(67, "MMC1_D4_SD_WE"), + PINCTRL_PIN(68, "MMC1_D7"), + PINCTRL_PIN(69, "MMC1_RCLK"), + + PINCTRL_PIN(75, "USB_OC1_B"), + PINCTRL_PIN(76, "PMU_RESETBUTTON_B"), + PINCTRL_PIN(77, "GPIO_ALERT"), + PINCTRL_PIN(78, "SDMMC3_PWR_EN_B"), + PINCTRL_PIN(79, "ILB_SERIRQ"), + PINCTRL_PIN(80, "USB_OC0_B"), + PINCTRL_PIN(81, "SDMMC3_CD_B"), + PINCTRL_PIN(82, "SPKR"), + PINCTRL_PIN(83, "SUSPWRDNACK"), + PINCTRL_PIN(84, "SPARE_PIN"), + PINCTRL_PIN(85, "SDMMC3_1P8_EN"), +}; + +static const unsigned southeast_pwm0_pins[] = { 5 }; +static const unsigned southeast_pwm1_pins[] = { 1 }; +static const unsigned southeast_sdmmc1_pins[] = { + 16, 17, 20, 23, 24, 26, 63, 65, 67, 68, 69, +}; +static const unsigned southeast_sdmmc2_pins[] = { 15, 18, 19, 21, 22, 25 }; +static const unsigned southeast_sdmmc3_pins[] = { + 30, 31, 32, 33, 34, 35, 78, 81, 85, +}; +static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 }; +static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 }; + +static const struct chv_pingroup southeast_groups[] = { + PIN_GROUP("pwm0_grp", southeast_pwm0_pins, 1, false), + PIN_GROUP("pwm1_grp", southeast_pwm1_pins, 1, false), + PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, 1, false), + PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, 1, false), + PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, 1, false), + PIN_GROUP("spi1_grp", southeast_spi1_pins, 1, false), + PIN_GROUP("spi2_grp", southeast_spi2_pins, 4, false), +}; + +static const char * const southeast_pwm0_groups[] = { "pwm0_grp" }; +static const char * const southeast_pwm1_groups[] = { "pwm1_grp" }; +static const char * const southeast_sdmmc1_groups[] = { "sdmmc1_grp" }; +static const char * const southeast_sdmmc2_groups[] = { "sdmmc2_grp" }; +static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" }; +static const char * const southeast_spi1_groups[] = { "spi1_grp" }; +static const char * const southeast_spi2_groups[] = { "spi2_grp" }; + +static const struct chv_function southeast_functions[] = { + FUNCTION("pwm0", southeast_pwm0_groups), + FUNCTION("pwm1", southeast_pwm1_groups), + FUNCTION("sdmmc1", southeast_sdmmc1_groups), + FUNCTION("sdmmc2", southeast_sdmmc2_groups), + FUNCTION("sdmmc3", southeast_sdmmc3_groups), + FUNCTION("spi1", southeast_spi1_groups), + FUNCTION("spi2", southeast_spi2_groups), +}; + +static const struct chv_gpio_pinrange southeast_gpio_ranges[] = { + GPIO_PINRANGE(0, 7), + GPIO_PINRANGE(15, 26), + GPIO_PINRANGE(30, 35), + GPIO_PINRANGE(45, 52), + GPIO_PINRANGE(60, 69), + GPIO_PINRANGE(75, 85), +}; + +static const struct chv_community southeast_community = { + .uid = "4", + .pins = southeast_pins, + .npins = ARRAY_SIZE(southeast_pins), + .groups = southeast_groups, + .ngroups = ARRAY_SIZE(southeast_groups), + .functions = southeast_functions, + .nfunctions = ARRAY_SIZE(southeast_functions), + .gpio_ranges = southeast_gpio_ranges, + .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges), + .ngpios = ARRAY_SIZE(southeast_pins), +}; + +static const struct chv_community *chv_communities[] = { + &southwest_community, + &north_community, + &east_community, + &southeast_community, +}; + +static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset, + unsigned reg) +{ + unsigned family_no = offset / MAX_FAMILY_PAD_GPIO_NO; + unsigned pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; + + offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no + + GPIO_REGS_SIZE * pad_no; + + return pctrl->regs + offset + reg; +} + +static void chv_writel(u32 value, void __iomem *reg) +{ + writel(value, reg); + /* simple readback to confirm the bus transferring done */ + readl(reg); +} + +/* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ +static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned offset) +{ + void __iomem *reg; + + reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); + return readl(reg) & CHV_PADCTRL1_CFGLOCK; +} + +static int chv_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->community->ngroups; +} + +static const char *chv_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->community->groups[group].name; +} + +static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, + const unsigned **pins, unsigned *npins) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *pins = pctrl->community->groups[group].pins; + *npins = pctrl->community->groups[group].npins; + return 0; +} + +static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned offset) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + u32 ctrl0, ctrl1; + bool locked; + + spin_lock_irqsave(&pctrl->lock, flags); + + ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1)); + locked = chv_pad_locked(pctrl, offset); + + spin_unlock_irqrestore(&pctrl->lock, flags); + + if (ctrl0 & CHV_PADCTRL0_GPIOEN) { + seq_puts(s, "GPIO "); + } else { + u32 mode; + + mode = ctrl0 & CHV_PADCTRL0_PMODE_MASK; + mode >>= CHV_PADCTRL0_PMODE_SHIFT; + + seq_printf(s, "mode %d ", mode); + } + + seq_printf(s, "ctrl0 0x%08x ctrl1 0x%08x", ctrl0, ctrl1); + + if (locked) + seq_puts(s, " [LOCKED]"); +} + +static const struct pinctrl_ops chv_pinctrl_ops = { + .get_groups_count = chv_get_groups_count, + .get_group_name = chv_get_group_name, + .get_group_pins = chv_get_group_pins, + .pin_dbg_show = chv_pin_dbg_show, +}; + +static int chv_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->community->nfunctions; +} + +static const char *chv_get_function_name(struct pinctrl_dev *pctldev, + unsigned function) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->community->functions[function].name; +} + +static int chv_get_function_groups(struct pinctrl_dev *pctldev, + unsigned function, + const char * const **groups, + unsigned * const ngroups) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctrl->community->functions[function].groups; + *ngroups = pctrl->community->functions[function].ngroups; + return 0; +} + +static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, + unsigned group) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct chv_pingroup *grp; + unsigned long flags; + int i; + + grp = &pctrl->community->groups[group]; + + spin_lock_irqsave(&pctrl->lock, flags); + + /* Check first that the pad is not locked */ + for (i = 0; i < grp->npins; i++) { + if (chv_pad_locked(pctrl, grp->pins[i])) { + dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n", + grp->pins[i]); + spin_unlock_irqrestore(&pctrl->lock, flags); + return -EBUSY; + } + } + + for (i = 0; i < grp->npins; i++) { + const struct chv_alternate_function *altfunc = &grp->altfunc; + int pin = grp->pins[i]; + void __iomem *reg; + u32 value; + + /* Check if there is pin-specific config */ + if (grp->overrides) { + int j; + + for (j = 0; j < grp->noverrides; j++) { + if (grp->overrides[j].pin == pin) { + altfunc = &grp->overrides[j]; + break; + } + } + } + + reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); + value = readl(reg); + /* Disable GPIO mode */ + value &= ~CHV_PADCTRL0_GPIOEN; + /* Set to desired mode */ + value &= ~CHV_PADCTRL0_PMODE_MASK; + value |= altfunc->mode << CHV_PADCTRL0_PMODE_SHIFT; + chv_writel(value, reg); + + /* Update for invert_oe */ + reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); + value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK; + if (altfunc->invert_oe) + value |= CHV_PADCTRL1_INVRXTX_TXENABLE; + chv_writel(value, reg); + + dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", + pin, altfunc->mode, altfunc->invert_oe ? "" : "not "); + } + + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + void __iomem *reg; + u32 value; + + spin_lock_irqsave(&pctrl->lock, flags); + + if (chv_pad_locked(pctrl, offset)) { + value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + if (!(value & CHV_PADCTRL0_GPIOEN)) { + /* Locked so cannot enable */ + spin_unlock_irqrestore(&pctrl->lock, flags); + return -EBUSY; + } + } else { + int i; + + /* Reset the interrupt mapping */ + for (i = 0; i < ARRAY_SIZE(pctrl->intr_lines); i++) { + if (pctrl->intr_lines[i] == offset) { + pctrl->intr_lines[i] = 0; + break; + } + } + + /* Disable interrupt generation */ + reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); + value = readl(reg); + value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; + value &= ~CHV_PADCTRL1_INVRXTX_MASK; + chv_writel(value, reg); + + /* Switch to a GPIO mode */ + reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); + value = readl(reg) | CHV_PADCTRL0_GPIOEN; + chv_writel(value, reg); + } + + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + void __iomem *reg; + u32 value; + + spin_lock_irqsave(&pctrl->lock, flags); + + reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); + value = readl(reg) & ~CHV_PADCTRL0_GPIOEN; + chv_writel(value, reg); + + spin_unlock_irqrestore(&pctrl->lock, flags); +} + +static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, bool input) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); + unsigned long flags; + u32 ctrl0; + + spin_lock_irqsave(&pctrl->lock, flags); + + ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK; + if (input) + ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; + else + ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; + chv_writel(ctrl0, reg); + + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static const struct pinmux_ops chv_pinmux_ops = { + .get_functions_count = chv_get_functions_count, + .get_function_name = chv_get_function_name, + .get_function_groups = chv_get_function_groups, + .set_mux = chv_pinmux_set_mux, + .gpio_request_enable = chv_gpio_request_enable, + .gpio_disable_free = chv_gpio_disable_free, + .gpio_set_direction = chv_gpio_set_direction, +}; + +static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned long flags; + u32 ctrl0, ctrl1; + u16 arg = 0; + u32 term; + + spin_lock_irqsave(&pctrl->lock, flags); + ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + spin_unlock_irqrestore(&pctrl->lock, flags); + + term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (term) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (!(ctrl0 & CHV_PADCTRL0_TERM_UP)) + return -EINVAL; + + switch (term) { + case CHV_PADCTRL0_TERM_20K: + arg = 20000; + break; + case CHV_PADCTRL0_TERM_5K: + arg = 5000; + break; + case CHV_PADCTRL0_TERM_1K: + arg = 1000; + break; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (!term || (ctrl0 & CHV_PADCTRL0_TERM_UP)) + return -EINVAL; + + switch (term) { + case CHV_PADCTRL0_TERM_20K: + arg = 20000; + break; + case CHV_PADCTRL0_TERM_5K: + arg = 5000; + break; + } + + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(ctrl1 & CHV_PADCTRL1_ODEN)) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { + u32 cfg; + + cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ) + return -EINVAL; + + break; + } + + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, + enum pin_config_param param, u16 arg) +{ + void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); + unsigned long flags; + u32 ctrl0, pull; + + spin_lock_irqsave(&pctrl->lock, flags); + ctrl0 = readl(reg); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + + switch (arg) { + case 1000: + /* For 1k there is only pull up */ + pull = CHV_PADCTRL0_TERM_1K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 5000: + pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 20000: + pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; + break; + default: + spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; + } + + ctrl0 |= CHV_PADCTRL0_TERM_UP | pull; + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + + switch (arg) { + case 5000: + pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 20000: + pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; + break; + default: + spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; + } + + ctrl0 |= pull; + break; + + default: + spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; + } + + chv_writel(ctrl0, reg); + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *configs, unsigned nconfigs) +{ + struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param; + int i, ret; + u16 arg; + + if (chv_pad_locked(pctrl, pin)) + return -EBUSY; + + for (i = 0; i < nconfigs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = chv_config_set_pull(pctrl, pin, param, arg); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + + dev_dbg(pctrl->dev, "pin %d set config %d arg %u\n", pin, + param, arg); + } + + return 0; +} + +static const struct pinconf_ops chv_pinconf_ops = { + .is_generic = true, + .pin_config_set = chv_config_set, + .pin_config_get = chv_config_get, +}; + +static struct pinctrl_desc chv_pinctrl_desc = { + .pctlops = &chv_pinctrl_ops, + .pmxops = &chv_pinmux_ops, + .confops = &chv_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int chv_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + return pinctrl_request_gpio(chip->base + offset); +} + +static void chv_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + pinctrl_free_gpio(chip->base + offset); +} + +static unsigned chv_gpio_offset_to_pin(struct chv_pinctrl *pctrl, + unsigned offset) +{ + return pctrl->community->pins[offset].number; +} + +static int chv_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); + int pin = chv_gpio_offset_to_pin(pctrl, offset); + u32 ctrl0, cfg; + + ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + + cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + + if (cfg == CHV_PADCTRL0_GPIOCFG_GPO) + return !!(ctrl0 & CHV_PADCTRL0_GPIOTXSTATE); + return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE); +} + +static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); + unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); + unsigned long flags; + void __iomem *reg; + u32 ctrl0; + + spin_lock_irqsave(&pctrl->lock, flags); + + reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); + ctrl0 = readl(reg); + + if (value) + ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; + else + ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; + + chv_writel(ctrl0, reg); + + spin_unlock_irqrestore(&pctrl->lock, flags); +} + +static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(chip); + unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); + u32 ctrl0, direction; + + ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + + direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + + return direction != CHV_PADCTRL0_GPIOCFG_GPO; +} + +static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return pinctrl_gpio_direction_input(chip->base + offset); +} + +static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + return pinctrl_gpio_direction_output(chip->base + offset); +} + +static const struct gpio_chip chv_gpio_chip = { + .owner = THIS_MODULE, + .request = chv_gpio_request, + .free = chv_gpio_free, + .get_direction = chv_gpio_get_direction, + .direction_input = chv_gpio_direction_input, + .direction_output = chv_gpio_direction_output, + .get = chv_gpio_get, + .set = chv_gpio_set, +}; + +static void chv_gpio_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); + int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); + u32 intr_line; + + spin_lock(&pctrl->lock); + + intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line &= CHV_PADCTRL0_INTSEL_MASK; + intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; + chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); + + spin_unlock(&pctrl->lock); +} + +static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); + int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); + u32 value, intr_line; + unsigned long flags; + + spin_lock_irqsave(&pctrl->lock, flags); + + intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line &= CHV_PADCTRL0_INTSEL_MASK; + intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; + + value = readl(pctrl->regs + CHV_INTMASK); + if (mask) + value &= ~BIT(intr_line); + else + value |= BIT(intr_line); + chv_writel(value, pctrl->regs + CHV_INTMASK); + + spin_unlock_irqrestore(&pctrl->lock, flags); +} + +static void chv_gpio_irq_mask(struct irq_data *d) +{ + chv_gpio_irq_mask_unmask(d, true); +} + +static void chv_gpio_irq_unmask(struct irq_data *d) +{ + chv_gpio_irq_mask_unmask(d, false); +} + +static int chv_gpio_irq_type(struct irq_data *d, unsigned type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); + unsigned offset = irqd_to_hwirq(d); + int pin = chv_gpio_offset_to_pin(pctrl, offset); + unsigned long flags; + u32 value; + + spin_lock_irqsave(&pctrl->lock, flags); + + /* + * Pins which can be used as shared interrupt are configured in + * BIOS. Driver trusts BIOS configurations and assigns different + * handler according to the irq type. + * + * Driver needs to save the mapping between each pin and + * its interrupt line. + * 1. If the pin cfg is locked in BIOS: + * Trust BIOS has programmed IntWakeCfg bits correctly, + * driver just needs to save the mapping. + * 2. If the pin cfg is not locked in BIOS: + * Driver programs the IntWakeCfg bits and save the mapping. + */ + if (!chv_pad_locked(pctrl, pin)) { + void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); + + value = readl(reg); + value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; + value &= ~CHV_PADCTRL1_INVRXTX_MASK; + + if (type & IRQ_TYPE_EDGE_BOTH) { + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + value |= CHV_PADCTRL1_INTWAKECFG_BOTH; + else if (type & IRQ_TYPE_EDGE_RISING) + value |= CHV_PADCTRL1_INTWAKECFG_RISING; + else if (type & IRQ_TYPE_EDGE_FALLING) + value |= CHV_PADCTRL1_INTWAKECFG_FALLING; + } else if (type & IRQ_TYPE_LEVEL_MASK) { + value |= CHV_PADCTRL1_INTWAKECFG_LEVEL; + if (type & IRQ_TYPE_LEVEL_LOW) + value |= CHV_PADCTRL1_INVRXTX_RXDATA; + } + + chv_writel(value, reg); + } + + value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + value &= CHV_PADCTRL0_INTSEL_MASK; + value >>= CHV_PADCTRL0_INTSEL_SHIFT; + + pctrl->intr_lines[value] = offset; + + if (type & IRQ_TYPE_EDGE_BOTH) + __irq_set_handler_locked(d->irq, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + __irq_set_handler_locked(d->irq, handle_level_irq); + + spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static struct irq_chip chv_gpio_irqchip = { + .name = "chv-gpio", + .irq_ack = chv_gpio_irq_ack, + .irq_mask = chv_gpio_irq_mask, + .irq_unmask = chv_gpio_irq_unmask, + .irq_set_type = chv_gpio_irq_type, + .flags = IRQCHIP_SKIP_SET_WAKE, +}; + +static void chv_gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct chv_pinctrl *pctrl = gpiochip_to_pinctrl(gc); + struct irq_chip *chip = irq_get_chip(irq); + unsigned long pending; + u32 intr_line; + + chained_irq_enter(chip, desc); + + pending = readl(pctrl->regs + CHV_INTSTAT); + for_each_set_bit(intr_line, &pending, 16) { + unsigned irq, offset; + + offset = pctrl->intr_lines[intr_line]; + irq = irq_find_mapping(gc->irqdomain, offset); + generic_handle_irq(irq); + } + + chained_irq_exit(chip, desc); +} + +static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) +{ + const struct chv_gpio_pinrange *range; + struct gpio_chip *chip = &pctrl->chip; + int ret, i, offset; + + *chip = chv_gpio_chip; + + chip->ngpio = pctrl->community->ngpios; + chip->label = dev_name(pctrl->dev); + chip->dev = pctrl->dev; + chip->base = -1; + + ret = gpiochip_add(chip); + if (ret) { + dev_err(pctrl->dev, "Failed to register gpiochip\n"); + return ret; + } + + for (i = 0, offset = 0; i < pctrl->community->ngpio_ranges; i++) { + range = &pctrl->community->gpio_ranges[i]; + ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), offset, + range->base, range->npins); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + goto fail; + } + + offset += range->npins; + } + + /* Mask and clear all interrupts */ + chv_writel(0, pctrl->regs + CHV_INTMASK); + chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); + + ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, + handle_simple_irq, IRQ_TYPE_NONE); + if (ret) { + dev_err(pctrl->dev, "failed to add IRQ chip\n"); + goto fail; + } + + gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq, + chv_gpio_irq_handler); + return 0; + +fail: + gpiochip_remove(chip); + + return ret; +} + +static int chv_pinctrl_probe(struct platform_device *pdev) +{ + struct chv_pinctrl *pctrl; + struct acpi_device *adev; + struct resource *res; + int ret, irq, i; + + adev = ACPI_COMPANION(&pdev->dev); + if (!adev) + return -ENODEV; + + pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(chv_communities); i++) + if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) { + pctrl->community = chv_communities[i]; + break; + } + if (i == ARRAY_SIZE(chv_communities)) + return -ENODEV; + + spin_lock_init(&pctrl->lock); + pctrl->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pctrl->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pctrl->regs)) + return PTR_ERR(pctrl->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "failed to get interrupt number\n"); + return irq; + } + + pctrl->pctldesc = chv_pinctrl_desc; + pctrl->pctldesc.name = dev_name(&pdev->dev); + pctrl->pctldesc.pins = pctrl->community->pins; + pctrl->pctldesc.npins = pctrl->community->npins; + + pctrl->pctldev = pinctrl_register(&pctrl->pctldesc, &pdev->dev, pctrl); + if (!pctrl->pctldev) { + dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + return -ENODEV; + } + + ret = chv_gpio_probe(pctrl, irq); + if (ret) { + pinctrl_unregister(pctrl->pctldev); + return ret; + } + + platform_set_drvdata(pdev, pctrl); + + return 0; +} + +static int chv_pinctrl_remove(struct platform_device *pdev) +{ + struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); + + gpiochip_remove(&pctrl->chip); + pinctrl_unregister(pctrl->pctldev); + + return 0; +} + +static const struct acpi_device_id chv_pinctrl_acpi_match[] = { + { "INT33FF" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); + +static struct platform_driver chv_pinctrl_driver = { + .probe = chv_pinctrl_probe, + .remove = chv_pinctrl_remove, + .driver = { + .name = "cherryview-pinctrl", + .owner = THIS_MODULE, + .acpi_match_table = chv_pinctrl_acpi_match, + }, +}; + +static int __init chv_pinctrl_init(void) +{ + return platform_driver_register(&chv_pinctrl_driver); +} +subsys_initcall(chv_pinctrl_init); + +static void __exit chv_pinctrl_exit(void) +{ + platform_driver_unregister(&chv_pinctrl_driver); +} +module_exit(chv_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg "); +MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 19858e7bdc63e00a401247a17d9f85949b48359d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 4 Nov 2014 12:05:01 +1100 Subject: [PATCH 2896/9457] quota: Add log level to printk JK: Added VFS: prefix to the message when changing it to make it more standard. Signed-off-by: Anton Blanchard Signed-off-by: Jan Kara --- fs/quota/dquot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6b4527216a7f..a180b1d1a6c6 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2743,8 +2743,8 @@ static int __init dquot_init(void) for (i = 0; i < nr_hash; i++) INIT_HLIST_HEAD(dquot_hash + i); - printk("Dquot-cache hash table entries: %ld (order %ld, %ld bytes)\n", - nr_hash, order, (PAGE_SIZE << order)); + pr_info("VFS: Dquot-cache hash table entries: %ld (order %ld," + " %ld bytes)\n", nr_hash, order, (PAGE_SIZE << order)); register_shrinker(&dqcache_shrinker); -- GitLab From 0b2e4959ceacb26eb586698d9ceecc0a6bd30f72 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 4 Nov 2014 13:15:10 +0800 Subject: [PATCH 2897/9457] ASoC: rt5645: make bias level more reasonale This patah separate bias level off to standby and off. The standby level will provide the necessary power for JD and push button functions. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 57ba74292259..1423cb283f15 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2069,8 +2069,8 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { switch (level) { - case SND_SOC_BIAS_STANDBY: - if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { + case SND_SOC_BIAS_PREPARE: + if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_VREF1 | RT5645_PWR_MB | RT5645_PWR_BG | RT5645_PWR_VREF2, @@ -2085,15 +2085,24 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, } break; + case SND_SOC_BIAS_STANDBY: + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_VREF1 | RT5645_PWR_MB | + RT5645_PWR_BG | RT5645_PWR_VREF2, + RT5645_PWR_VREF1 | RT5645_PWR_MB | + RT5645_PWR_BG | RT5645_PWR_VREF2); + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_FV1 | RT5645_PWR_FV2, + RT5645_PWR_FV1 | RT5645_PWR_FV2); + break; + case SND_SOC_BIAS_OFF: snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); - snd_soc_write(codec, RT5645_PWR_DIG1, 0x0000); - snd_soc_write(codec, RT5645_PWR_DIG2, 0x0000); - snd_soc_write(codec, RT5645_PWR_VOL, 0x0000); - snd_soc_write(codec, RT5645_PWR_MIXER, 0x0000); - snd_soc_write(codec, RT5645_PWR_ANLG1, 0x0000); - snd_soc_write(codec, RT5645_PWR_ANLG2, 0x0000); + snd_soc_update_bits(codec, RT5645_PWR_ANLG1, + RT5645_PWR_VREF1 | RT5645_PWR_MB | + RT5645_PWR_BG | RT5645_PWR_VREF2 | + RT5645_PWR_FV1 | RT5645_PWR_FV2, 0x0); break; default: -- GitLab From e648f6add20d1cfb5945e24b5bffe5843476645b Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Tue, 4 Nov 2014 14:45:24 +0800 Subject: [PATCH 2898/9457] ASoC: Intel: Fix the driver data not set issue The priv_data is allocated again here wrongly, and it is not set to the driver data after assignment. This make the pdata->dev is NULL and oops occurs on the first call to hsw_volume_put. The resource has been allocated in driver probe callback hsw_pcm_dev_probe, so here just remove this sencond allocation is OK. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-pcm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index cd54dd9967af..093b9393ae46 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -868,7 +868,6 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) dev = platform->dev; dma_dev = pdata->dma_dev; - priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL); priv_data->hsw = pdata->dsp; priv_data->dev = platform->dev; priv_data->pm_state = HSW_PM_STATE_D0; -- GitLab From 4539441690cd31ae7d42e6f080033911a1788440 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Nov 2014 19:33:02 +0100 Subject: [PATCH 2899/9457] ASoC: mioa701_wm9713: Don't opencode CODEC register access Properly use snd_soc_update_bits() instead of manually calling the CODEC driver's read and write callbacks. The later will stop working once the wm9713 driver has been converted to regmap. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/pxa/mioa701_wm9713.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 595eee341e90..a6b2be20cc0b 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -127,15 +127,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - unsigned short reg; /* Prepare GPIO8 for rear speaker amplifier */ - reg = codec->driver->read(codec, AC97_GPIO_CFG); - codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100); + snd_soc_update_bits(codec, AC97_GPIO_CFG, 0x100, 0x100); /* Prepare MIC input */ - reg = codec->driver->read(codec, AC97_3D_CONTROL); - codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000); + snd_soc_update_bits(codec, AC97_3D_CONTROL, 0xc000, 0xc000); return 0; } -- GitLab From 313665b983fe30af9d0eb274f7e03276e05a1bbf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Nov 2014 11:30:58 +0100 Subject: [PATCH 2900/9457] ASoC: Remove card field from snd_soc_dai struct The card field of the snd_soc_dai field is very rarely used. We can use dai->component->card instead and remove the card field from the snd_soc_dai struct. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 2 -- sound/soc/soc-core.c | 7 +------ sound/soc/soc-dapm.c | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 45d0fa10ab9e..373d1775ecba 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -275,8 +275,6 @@ struct snd_soc_dai { unsigned int tx_mask; unsigned int rx_mask; - struct snd_soc_card *card; - struct list_head list; }; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ea1df2083bd5..f3216fc6d9f1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1315,11 +1315,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", card->name, num, order); - /* config components */ - cpu_dai->card = card; - for (i = 0; i < rtd->num_codecs; i++) - rtd->codec_dais[i]->card = card; - /* set default power off timeout */ rtd->pmdown_time = pmdown_time; @@ -2314,7 +2309,7 @@ EXPORT_SYMBOL_GPL(snd_soc_add_card_controls); int snd_soc_add_dai_controls(struct snd_soc_dai *dai, const struct snd_kcontrol_new *controls, int num_controls) { - struct snd_card *card = dai->card->snd_card; + struct snd_card *card = dai->component->card->snd_card; return snd_soc_add_controls(card, dai->dev, controls, num_controls, NULL, dai); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6bf2c9795df2..c5136bb1f982 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1043,7 +1043,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget_list **list) { - struct snd_soc_card *card = dai->card; + struct snd_soc_card *card = dai->component->card; struct snd_soc_dapm_widget *w; int paths; -- GitLab From 8e2be56273666614e24756d7ee551203b8a86809 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Nov 2014 11:30:59 +0100 Subject: [PATCH 2901/9457] ASoC: Consolidate CPU and CODEC DAI probe CPU and CODEC DAI probe are performed in exactly the same way. Which means we can reuse the snd_soc_codec_dai_probe() for probing CPU DAIs as well. While we are at it also drop the unused card parameter form the function. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f3216fc6d9f1..406925c2bbe7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1241,25 +1241,22 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, return 0; } -static int soc_probe_codec_dai(struct snd_soc_card *card, - struct snd_soc_dai *codec_dai, - int order) +static int soc_probe_dai(struct snd_soc_dai *dai, int order) { int ret; - if (!codec_dai->probed && codec_dai->driver->probe_order == order) { - if (codec_dai->driver->probe) { - ret = codec_dai->driver->probe(codec_dai); + if (!dai->probed && dai->driver->probe_order == order) { + if (dai->driver->probe) { + ret = dai->driver->probe(dai); if (ret < 0) { - dev_err(codec_dai->dev, - "ASoC: failed to probe CODEC DAI %s: %d\n", - codec_dai->name, ret); + dev_err(dai->dev, + "ASoC: failed to probe DAI %s: %d\n", + dai->name, ret); return ret; } } - /* mark codec_dai as probed and add to card dai list */ - codec_dai->probed = 1; + dai->probed = 1; } return 0; @@ -1318,24 +1315,13 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) /* set default power off timeout */ rtd->pmdown_time = pmdown_time; - /* probe the cpu_dai */ - if (!cpu_dai->probed && - cpu_dai->driver->probe_order == order) { - if (cpu_dai->driver->probe) { - ret = cpu_dai->driver->probe(cpu_dai); - if (ret < 0) { - dev_err(cpu_dai->dev, - "ASoC: failed to probe CPU DAI %s: %d\n", - cpu_dai->name, ret); - return ret; - } - } - cpu_dai->probed = 1; - } + ret = soc_probe_dai(cpu_dai, order); + if (ret) + return ret; /* probe the CODEC DAI */ for (i = 0; i < rtd->num_codecs; i++) { - ret = soc_probe_codec_dai(card, rtd->codec_dais[i], order); + ret = soc_probe_dai(rtd->codec_dais[i], order); if (ret) return ret; } -- GitLab From 6e0bd6c35b021dc73a81ebd1ef79761233c48b50 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Mon, 3 Nov 2014 10:33:18 +0100 Subject: [PATCH 2902/9457] cfg80211: 802.11p OCB mode handling This patch adds new iface type (NL80211_IFTYPE_OCB) representing the OCB (Outside the Context of a BSS) mode. When establishing a connection to the network a cfg80211_join_ocb function is called (particular nl80211_command is added as well). A mandatory parameters during the ocb_join operation are 'center frequency' and 'channel width (5/10 MHz)'. Changes done in mac80211 are minimal possible required to avoid many warnings (warning: enumeration value 'NL80211_IFTYPE_OCB' not handled in switch) during compilation. Full functionality (where needed) is added in the following patch. Signed-off-by: Rostislav Lisovy Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 19 ++++++++ include/uapi/linux/nl80211.h | 11 +++++ net/mac80211/cfg.c | 1 + net/mac80211/chan.c | 2 + net/mac80211/iface.c | 5 ++ net/mac80211/util.c | 3 ++ net/wireless/Makefile | 2 +- net/wireless/chan.c | 8 ++++ net/wireless/core.c | 3 ++ net/wireless/core.h | 12 +++++ net/wireless/nl80211.c | 39 ++++++++++++++++ net/wireless/ocb.c | 88 ++++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 21 +++++++++ net/wireless/trace.h | 21 +++++++++ net/wireless/util.c | 5 +- 15 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 net/wireless/ocb.c diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f67948e18600..5c3acd07acd9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1358,6 +1358,16 @@ struct mesh_setup { u32 basic_rates; }; +/** + * struct ocb_setup - 802.11p OCB mode setup configuration + * @chandef: defines the channel to use + * + * These parameters are fixed when connecting to the network + */ +struct ocb_setup { + struct cfg80211_chan_def chandef; +}; + /** * struct ieee80211_txq_params - TX queue parameters * @ac: AC identifier @@ -2352,6 +2362,11 @@ struct cfg80211_qos_map { * with the peer followed by immediate teardown when the addition is later * rejected) * @del_tx_ts: remove an existing TX TS + * + * @join_ocb: join the OCB network with the specified parameters + * (invoked with the wireless_dev mutex held) + * @leave_ocb: leave the current OCB network + * (invoked with the wireless_dev mutex held) */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2433,6 +2448,10 @@ struct cfg80211_ops { const struct mesh_setup *setup); int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); + int (*join_ocb)(struct wiphy *wiphy, struct net_device *dev, + struct ocb_setup *setup); + int (*leave_ocb)(struct wiphy *wiphy, struct net_device *dev); + int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f7daae59248e..9b3025e4377a 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -746,6 +746,11 @@ * destination %NL80211_ATTR_MAC on the interface identified by * %NL80211_ATTR_IFINDEX. * + * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and + * bandwidth of a channel must be given. + * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the + * network is determined by the network interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -922,6 +927,9 @@ enum nl80211_commands { NL80211_CMD_GET_MPP, + NL80211_CMD_JOIN_OCB, + NL80211_CMD_LEAVE_OCB, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2074,6 +2082,8 @@ enum nl80211_attrs { * and therefore can't be created in the normal ways, use the * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE * commands to create and destroy one + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS + * This mode corresponds to the MIB variable dot11OCBActivated=true * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -2093,6 +2103,7 @@ enum nl80211_iftype { NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, NL80211_IFTYPE_P2P_DEVICE, + NL80211_IFTYPE_OCB, /* keep last */ NUM_NL80211_IFTYPES, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b9659b8b70f8..1e2afc95ad09 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -230,6 +230,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_OCB: /* shouldn't happen */ WARN_ON_ONCE(1); break; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index ee71bb6f64f7..ff1f877e3b63 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -270,6 +270,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: width = vif->bss_conf.chandef.width; break; case NL80211_IFTYPE_UNSPECIFIED: @@ -909,6 +910,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata) case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: ieee80211_queue_work(&sdata->local->hw, &sdata->csa_finalize_work); break; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1ffcc0701244..d69e7532095f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -521,6 +521,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_OCB: /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: @@ -631,6 +632,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: netif_carrier_off(dev); break; case NL80211_IFTYPE_WDS: @@ -1351,6 +1353,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; ieee80211_sta_setup_sdata(sdata); break; + case NL80211_IFTYPE_OCB: + /* to be implemented in the future */ + break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; ieee80211_ibss_setup_sdata(sdata); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 666aa1306c45..d7d69c89ff34 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1841,6 +1841,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) ieee80211_bss_info_change_notify(sdata, changed); sdata_unlock(sdata); break; + case NL80211_IFTYPE_OCB: + /* to be implemented in the future */ + break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; /* fall through */ diff --git a/net/wireless/Makefile b/net/wireless/Makefile index a761670af31d..4c9e39f04ef8 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 8f39e33e71bb..85506f1d0789 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -366,6 +366,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -892,6 +893,13 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, *radar_detect |= BIT(wdev->chandef.width); } return; + case NL80211_IFTYPE_OCB: + if (wdev->chandef.chan) { + *chan = wdev->chandef.chan; + *chanmode = CHAN_MODE_SHARED; + return; + } + break; case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: diff --git a/net/wireless/core.c b/net/wireless/core.c index da4dcb65ade4..a4d27927aba2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -869,6 +869,9 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_P2P_GO: __cfg80211_stop_ap(rdev, dev, true); break; + case NL80211_IFTYPE_OCB: + __cfg80211_leave_ocb(rdev, dev); + break; case NL80211_IFTYPE_WDS: /* must be handled by mac80211/driver, has no APIs */ break; diff --git a/net/wireless/core.h b/net/wireless/core.h index 7e3a3cef7df9..61ee664cf2bd 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -290,6 +290,18 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, struct cfg80211_chan_def *chandef); +/* OCB */ +int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup); +int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup); +int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev); +int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev); + /* AP */ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, struct net_device *dev, bool notify); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f7d918858d32..1a31736914e5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -885,6 +885,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) return -ENOLINK; break; case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_WDS: @@ -8275,6 +8276,28 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } +static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct ocb_setup setup = {}; + int err; + + err = nl80211_parse_chandef(rdev, info, &setup.chandef); + if (err) + return err; + + return cfg80211_join_ocb(rdev, dev, &setup); +} + +static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + + return cfg80211_leave_ocb(rdev, dev); +} + static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -10218,6 +10241,22 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_JOIN_OCB, + .doit = nl80211_join_ocb, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_LEAVE_OCB, + .doit = nl80211_leave_ocb, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, #ifdef CONFIG_PM { .cmd = NL80211_CMD_GET_WOWLAN, diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c new file mode 100644 index 000000000000..c00d4a792319 --- /dev/null +++ b/net/wireless/ocb.c @@ -0,0 +1,88 @@ +/* + * OCB mode implementation + * + * Copyright: (c) 2014 Czech Technical University in Prague + * (c) 2014 Volkswagen Group Research + * Author: Rostislav Lisovy + * Funded by: Volkswagen Group Research + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include "nl80211.h" +#include "core.h" +#include "rdev-ops.h" + +int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) + return -EOPNOTSUPP; + + if (WARN_ON(!setup->chandef.chan)) + return -EINVAL; + + err = rdev_join_ocb(rdev, dev, setup); + if (!err) + wdev->chandef = setup->chandef; + + return err; +} + +int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_join_ocb(rdev, dev, setup); + wdev_unlock(wdev); + + return err; +} + +int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + ASSERT_WDEV_LOCK(wdev); + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) + return -EOPNOTSUPP; + + if (!rdev->ops->leave_ocb) + return -EOPNOTSUPP; + + err = rdev_leave_ocb(rdev, dev); + if (!err) + memset(&wdev->chandef, 0, sizeof(wdev->chandef)); + + return err; +} + +int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + wdev_lock(wdev); + err = __cfg80211_leave_ocb(rdev, dev); + wdev_unlock(wdev); + + return err; +} diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 71b1db3cc645..1b3864cd50ca 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -348,6 +348,27 @@ static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev, return ret; } +static inline int rdev_join_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ocb_setup *setup) +{ + int ret; + trace_rdev_join_ocb(&rdev->wiphy, dev, setup); + ret = rdev->ops->join_ocb(&rdev->wiphy, dev, setup); + trace_rdev_return_int(&rdev->wiphy, ret); + return ret; +} + +static inline int rdev_leave_ocb(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + int ret; + trace_rdev_leave_ocb(&rdev->wiphy, dev); + ret = rdev->ops->leave_ocb(&rdev->wiphy, dev); + trace_rdev_return_int(&rdev->wiphy, ret); + return ret; +} + static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, struct net_device *dev, struct bss_parameters *params) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index cdb2c2ef1ae1..277a85df910e 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -600,6 +600,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss, TP_ARGS(wiphy, netdev) ); +DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), + TP_ARGS(wiphy, netdev) +); + DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), TP_ARGS(wiphy, netdev) @@ -1316,6 +1321,22 @@ TRACE_EVENT(rdev_join_ibss, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) ); +TRACE_EVENT(rdev_join_ocb, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + const struct ocb_setup *setup), + TP_ARGS(wiphy, netdev, setup), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG) +); + TRACE_EVENT(rdev_set_wiphy_params, TP_PROTO(struct wiphy *wiphy, u32 changed), TP_ARGS(wiphy, changed), diff --git a/net/wireless/util.c b/net/wireless/util.c index 5e233a577d0f..d0ac795445b7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -442,7 +442,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, break; case cpu_to_le16(0): if (iftype != NL80211_IFTYPE_ADHOC && - iftype != NL80211_IFTYPE_STATION) + iftype != NL80211_IFTYPE_STATION && + iftype != NL80211_IFTYPE_OCB) return -1; break; } @@ -519,6 +520,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, memcpy(hdr.addr3, skb->data, ETH_ALEN); hdrlen = 24; break; + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_ADHOC: /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -937,6 +939,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->use_4addr) break; /* fall through */ + case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_ADHOC: dev->priv_flags |= IFF_DONT_BRIDGE; -- GitLab From 239281f803e2efdb77d906ef296086b6917e5d71 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Mon, 3 Nov 2014 10:33:19 +0100 Subject: [PATCH 2903/9457] mac80211: 802.11p OCB mode support This patch adds 802.11p OCB (Outside the Context of a BSS) mode support. When communicating in OCB mode a mandatory wildcard BSSID (48 '1' bits) is used. The EDCA parameters handling function was changed to support 802.11p specific values. The insertion of a newly discovered STAs is done in the similar way as in the IBSS mode -- through the deferred insertion. The OCB mode uses a periodic 'housekeeping task' for expiration of disconnected STAs (in the similar manner as in the MESH mode). New Kconfig option for verbose OCB debugging outputs is added. Signed-off-by: Rostislav Lisovy Signed-off-by: Johannes Berg --- include/net/mac80211.h | 2 + net/mac80211/Kconfig | 11 ++ net/mac80211/Makefile | 3 +- net/mac80211/cfg.c | 13 ++ net/mac80211/chan.c | 1 + net/mac80211/debug.h | 10 ++ net/mac80211/driver-ops.h | 3 +- net/mac80211/ieee80211_i.h | 29 +++++ net/mac80211/iface.c | 20 ++- net/mac80211/ocb.c | 250 +++++++++++++++++++++++++++++++++++++ net/mac80211/rx.c | 35 ++++++ net/mac80211/tx.c | 15 +++ net/mac80211/util.c | 30 ++++- net/mac80211/wme.c | 4 + 14 files changed, 417 insertions(+), 9 deletions(-) create mode 100644 net/mac80211/ocb.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 03edbf6f6230..db54635d65c5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -263,6 +263,7 @@ struct ieee80211_vif_chanctx_switch { * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, * note that this is only called when it changes after the channel * context had been assigned. + * @BSS_CHANGED_OCB: OCB join status changed */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -287,6 +288,7 @@ enum ieee80211_bss_change { BSS_CHANGED_P2P_PS = 1<<19, BSS_CHANGED_BEACON_INFO = 1<<20, BSS_CHANGED_BANDWIDTH = 1<<21, + BSS_CHANGED_OCB = 1<<22, /* when adding here, make sure to change ieee80211_reconfig */ }; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 67cf8125d75d..75cc6801a431 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -176,6 +176,17 @@ config MAC80211_HT_DEBUG Do not select this option. +config MAC80211_OCB_DEBUG + bool "Verbose OCB debugging" + depends on MAC80211_DEBUG_MENU + ---help--- + Selecting this option causes mac80211 to print out + very verbose OCB debugging messages. It should not + be selected on production systems as those messages + are remotely triggerable. + + Do not select this option. + config MAC80211_IBSS_DEBUG bool "Verbose IBSS debugging" depends on MAC80211_DEBUG_MENU diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 7273d2796dd1..e53671b1105e 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -27,7 +27,8 @@ mac80211-y := \ event.o \ chan.o \ trace.o mlme.o \ - tdls.o + tdls.o \ + ocb.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1e2afc95ad09..06185940cbb6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2019,6 +2019,17 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); } +static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev, + struct ocb_setup *setup) +{ + return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup); +} + +static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev) +{ + return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev)); +} + static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, int rate[IEEE80211_NUM_BANDS]) { @@ -3693,6 +3704,8 @@ const struct cfg80211_ops mac80211_config_ops = { .join_mesh = ieee80211_join_mesh, .leave_mesh = ieee80211_leave_mesh, #endif + .join_ocb = ieee80211_join_ocb, + .leave_ocb = ieee80211_leave_ocb, .change_bss = ieee80211_change_bss, .set_txq_params = ieee80211_set_txq_params, .set_monitor_channel = ieee80211_set_monitor_channel, diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index ff1f877e3b63..c7c514220298 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -675,6 +675,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_OCB: break; default: WARN_ON_ONCE(1); diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h index 493d68061f0c..1956b3115dd5 100644 --- a/net/mac80211/debug.h +++ b/net/mac80211/debug.h @@ -2,6 +2,12 @@ #define __MAC80211_DEBUG_H #include +#ifdef CONFIG_MAC80211_OCB_DEBUG +#define MAC80211_OCB_DEBUG 1 +#else +#define MAC80211_OCB_DEBUG 0 +#endif + #ifdef CONFIG_MAC80211_IBSS_DEBUG #define MAC80211_IBSS_DEBUG 1 #else @@ -131,6 +137,10 @@ do { \ _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ sdata, fmt, ##__VA_ARGS__) +#define ocb_dbg(sdata, fmt, ...) \ + _sdata_dbg(MAC80211_OCB_DEBUG, \ + sdata, fmt, ##__VA_ARGS__) + #define ibss_dbg(sdata, fmt, ...) \ _sdata_dbg(MAC80211_IBSS_DEBUG, \ sdata, fmt, ##__VA_ARGS__) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index d1e128e5db41..8e1889ff2e53 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -214,7 +214,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, BSS_CHANGED_BEACON_ENABLED) && sdata->vif.type != NL80211_IFTYPE_AP && sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_OCB)) return; if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eb425298fe69..fbd6bee9c959 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -576,6 +576,25 @@ struct ieee80211_if_ibss { } state; }; +/** + * struct ieee80211_if_ocb - OCB mode state + * + * @housekeeping_timer: timer for periodic invocation of a housekeeping task + * @wrkq_flags: OCB deferred task action + * @incomplete_lock: delayed STA insertion lock + * @incomplete_stations: list of STAs waiting for delayed insertion + * @joined: indication if the interface is connected to an OCB network + */ +struct ieee80211_if_ocb { + struct timer_list housekeeping_timer; + unsigned long wrkq_flags; + + spinlock_t incomplete_lock; + struct list_head incomplete_stations; + + bool joined; +}; + /** * struct ieee80211_mesh_sync_ops - Extensible synchronization framework interface * @@ -869,6 +888,7 @@ struct ieee80211_sub_if_data { struct ieee80211_if_managed mgd; struct ieee80211_if_ibss ibss; struct ieee80211_if_mesh mesh; + struct ieee80211_if_ocb ocb; u32 mntr_flags; } u; @@ -1505,6 +1525,15 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); +/* OCB code */ +void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata); +void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, + const u8 *bssid, const u8 *addr, u32 supp_rates); +void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata); +int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, + struct ocb_setup *setup); +int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata); + /* mesh code */ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d69e7532095f..6b631c049eba 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -258,6 +258,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { + /* + * Only OCB and monitor mode may coexist + */ + if ((sdata->vif.type == NL80211_IFTYPE_OCB && + nsdata->vif.type != NL80211_IFTYPE_MONITOR) || + (sdata->vif.type != NL80211_IFTYPE_MONITOR && + nsdata->vif.type == NL80211_IFTYPE_OCB)) + return -EBUSY; + /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution @@ -1283,6 +1292,9 @@ static void ieee80211_iface_work(struct work_struct *work) break; ieee80211_mesh_work(sdata); break; + case NL80211_IFTYPE_OCB: + ieee80211_ocb_work(sdata); + break; default: break; } @@ -1302,6 +1314,9 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { + static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff, + 0xff, 0xff, 0xff}; + /* clear type-dependent union */ memset(&sdata->u, 0, sizeof(sdata->u)); @@ -1354,7 +1369,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, ieee80211_sta_setup_sdata(sdata); break; case NL80211_IFTYPE_OCB: - /* to be implemented in the future */ + sdata->vif.bss_conf.bssid = bssid_wildcard; + ieee80211_ocb_setup_sdata(sdata); break; case NL80211_IFTYPE_ADHOC: sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; @@ -1403,6 +1419,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could maybe also all others here? * Just not sure how that interacts @@ -1418,6 +1435,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_OCB: /* * Could probably support everything * but WDS here (WDS do_open can fail diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c new file mode 100644 index 000000000000..358d5f9d8207 --- /dev/null +++ b/net/mac80211/ocb.c @@ -0,0 +1,250 @@ +/* + * OCB mode implementation + * + * Copyright: (c) 2014 Czech Technical University in Prague + * (c) 2014 Volkswagen Group Research + * Author: Rostislav Lisovy + * Funded by: Volkswagen Group Research + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ieee80211_i.h" +#include "driver-ops.h" +#include "rate.h" + +#define IEEE80211_OCB_HOUSEKEEPING_INTERVAL (60 * HZ) +#define IEEE80211_OCB_PEER_INACTIVITY_LIMIT (240 * HZ) +#define IEEE80211_OCB_MAX_STA_ENTRIES 128 + +/** + * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks + * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks + * + * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb + */ +enum ocb_deferred_task_flags { + OCB_WORK_HOUSEKEEPING, +}; + +void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, + const u8 *bssid, const u8 *addr, + u32 supp_rates) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_supported_band *sband; + enum nl80211_bss_scan_width scan_width; + struct sta_info *sta; + int band; + + /* XXX: Consider removing the least recently used entry and + * allow new one to be added. + */ + if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) { + net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n", + sdata->name, addr); + return; + } + + ocb_dbg(sdata, "Adding new OCB station %pM\n", addr); + + rcu_read_lock(); + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + if (WARN_ON_ONCE(!chanctx_conf)) { + rcu_read_unlock(); + return; + } + band = chanctx_conf->def.chan->band; + scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def); + rcu_read_unlock(); + + sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); + if (!sta) + return; + + sta->last_rx = jiffies; + + /* Add only mandatory rates for now */ + sband = local->hw.wiphy->bands[band]; + sta->sta.supp_rates[band] = + ieee80211_mandatory_rates(sband, scan_width); + + spin_lock(&ifocb->incomplete_lock); + list_add(&sta->list, &ifocb->incomplete_stations); + spin_unlock(&ifocb->incomplete_lock); + ieee80211_queue_work(&local->hw, &sdata->work); +} + +static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) + __acquires(RCU) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + u8 addr[ETH_ALEN]; + + memcpy(addr, sta->sta.addr, ETH_ALEN); + + ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n", + addr, sdata->name); + + sta_info_move_state(sta, IEEE80211_STA_AUTH); + sta_info_move_state(sta, IEEE80211_STA_ASSOC); + sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); + + rate_control_rate_init(sta); + + /* If it fails, maybe we raced another insertion? */ + if (sta_info_insert_rcu(sta)) + return sta_info_get(sdata, addr); + return sta; +} + +static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + ocb_dbg(sdata, "Running ocb housekeeping\n"); + + ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT); + + mod_timer(&ifocb->housekeeping_timer, + round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL)); +} + +void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct sta_info *sta; + + if (ifocb->joined != true) + return; + + sdata_lock(sdata); + + spin_lock_bh(&ifocb->incomplete_lock); + while (!list_empty(&ifocb->incomplete_stations)) { + sta = list_first_entry(&ifocb->incomplete_stations, + struct sta_info, list); + list_del(&sta->list); + spin_unlock_bh(&ifocb->incomplete_lock); + + ieee80211_ocb_finish_sta(sta); + rcu_read_unlock(); + spin_lock_bh(&ifocb->incomplete_lock); + } + spin_unlock_bh(&ifocb->incomplete_lock); + + if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags)) + ieee80211_ocb_housekeeping(sdata); + + sdata_unlock(sdata); +} + +static void ieee80211_ocb_housekeeping_timer(unsigned long data) +{ + struct ieee80211_sub_if_data *sdata = (void *)data; + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + + ieee80211_queue_work(&local->hw, &sdata->work); +} + +void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + + setup_timer(&ifocb->housekeeping_timer, + ieee80211_ocb_housekeeping_timer, + (unsigned long)sdata); + INIT_LIST_HEAD(&ifocb->incomplete_stations); + spin_lock_init(&ifocb->incomplete_lock); +} + +int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, + struct ocb_setup *setup) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + u32 changed = BSS_CHANGED_OCB; + int err; + + if (ifocb->joined == true) + return -EINVAL; + + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; + sdata->smps_mode = IEEE80211_SMPS_OFF; + sdata->needed_rx_chains = sdata->local->rx_chains; + + mutex_lock(&sdata->local->mtx); + err = ieee80211_vif_use_channel(sdata, &setup->chandef, + IEEE80211_CHANCTX_SHARED); + mutex_unlock(&sdata->local->mtx); + if (err) + return err; + + ieee80211_bss_info_change_notify(sdata, changed); + + ifocb->joined = true; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + ieee80211_queue_work(&local->hw, &sdata->work); + + netif_carrier_on(sdata->dev); + return 0; +} + +int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + + ifocb->joined = false; + sta_info_flush(sdata); + + spin_lock_bh(&ifocb->incomplete_lock); + while (!list_empty(&ifocb->incomplete_stations)) { + sta = list_first_entry(&ifocb->incomplete_stations, + struct sta_info, list); + list_del(&sta->list); + spin_unlock_bh(&ifocb->incomplete_lock); + + sta_info_free(local, sta); + spin_lock_bh(&ifocb->incomplete_lock); + } + spin_unlock_bh(&ifocb->incomplete_lock); + + netif_carrier_off(sdata->dev); + clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB); + + mutex_lock(&sdata->local->mtx); + ieee80211_vif_release_channel(sdata); + mutex_unlock(&sdata->local->mtx); + + skb_queue_purge(&sdata->skb_queue); + + del_timer_sync(&sdata->u.ocb.housekeeping_timer); + /* If the timer fired while we waited for it, it will have + * requeued the work. Now the work will be running again + * but will not rearm the timer again because it checks + * whether we are connected to the network or not -- at this + * point we shouldn't be anymore. + */ + + return 0; +} diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b04ca4049c95..bc63aa0c5401 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1032,6 +1032,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) ieee80211_is_pspoll(hdr->frame_control)) && rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && rx->sdata->vif.type != NL80211_IFTYPE_WDS && + rx->sdata->vif.type != NL80211_IFTYPE_OCB && (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { /* * accept port control frames from the AP even when it's not @@ -1272,6 +1273,12 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->last_rx_rate_vht_nss = status->vht_nss; } } + } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { + u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, + NL80211_IFTYPE_OCB); + /* OCB uses wild-card BSSID */ + if (is_broadcast_ether_addr(bssid)) + sta->last_rx = jiffies; } else if (!is_multicast_ether_addr(hdr->addr1)) { /* * Mesh beacons will update last_rx when if they are found to @@ -2820,6 +2827,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) if (!ieee80211_vif_is_mesh(&sdata->vif) && sdata->vif.type != NL80211_IFTYPE_ADHOC && + sdata->vif.type != NL80211_IFTYPE_OCB && sdata->vif.type != NL80211_IFTYPE_STATION) return RX_DROP_MONITOR; @@ -3130,6 +3138,33 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx, BIT(rate_idx)); } break; + case NL80211_IFTYPE_OCB: + if (!bssid) + return false; + if (ieee80211_is_beacon(hdr->frame_control)) { + return false; + } else if (!is_broadcast_ether_addr(bssid)) { + ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n"); + return false; + } else if (!multicast && + !ether_addr_equal(sdata->dev->dev_addr, + hdr->addr1)) { + /* if we are in promisc mode we also accept + * packets not destined for us + */ + if (!(sdata->dev->flags & IFF_PROMISC)) + return false; + rx->flags &= ~IEEE80211_RX_RA_MATCH; + } else if (!rx->sta) { + int rate_idx; + if (status->flag & RX_FLAG_HT) + rate_idx = 0; /* TODO: HT rates */ + else + rate_idx = status->rate_idx; + ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2, + BIT(rate_idx)); + } + break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 900632a250ec..3ffd91f295a6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -296,6 +296,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) */ return TX_DROP; + if (tx->sdata->vif.type == NL80211_IFTYPE_OCB) + return TX_CONTINUE; + if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) return TX_CONTINUE; @@ -2013,6 +2016,17 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, goto fail_rcu; band = chanctx_conf->def.chan->band; break; + case NL80211_IFTYPE_OCB: + /* DA SA BSSID */ + memcpy(hdr.addr1, skb->data, ETH_ALEN); + memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); + eth_broadcast_addr(hdr.addr3); + hdrlen = 24; + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + if (!chanctx_conf) + goto fail_rcu; + band = chanctx_conf->def.chan->band; + break; case NL80211_IFTYPE_ADHOC: /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -2057,6 +2071,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, * EAPOL frames from the local station. */ if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && + (sdata->vif.type != NL80211_IFTYPE_OCB) && !multicast && !authorized && (cpu_to_be16(ethertype) != sdata->control_port_protocol || !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d7d69c89ff34..91e16b4d4e3c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1101,6 +1101,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx_conf *chanctx_conf; int ac; bool use_11b, enable_qos; + bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */ int aCWmin, aCWmax; if (!local->ops->conf_tx) @@ -1125,6 +1126,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, */ enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); + is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB); + /* Set defaults according to 802.11-2007 Table 7-37 */ aCWmax = 1023; if (use_11b) @@ -1146,7 +1149,10 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; - qparam.aifs = 7; + if (is_ocb) + qparam.aifs = 9; + else + qparam.aifs = 7; break; /* never happens but let's not leave undefined */ default: @@ -1154,21 +1160,32 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, qparam.cw_max = aCWmax; qparam.cw_min = aCWmin; qparam.txop = 0; - qparam.aifs = 3; + if (is_ocb) + qparam.aifs = 6; + else + qparam.aifs = 3; break; case IEEE80211_AC_VI: qparam.cw_max = aCWmin; qparam.cw_min = (aCWmin + 1) / 2 - 1; - if (use_11b) + if (is_ocb) + qparam.txop = 0; + else if (use_11b) qparam.txop = 6016/32; else qparam.txop = 3008/32; - qparam.aifs = 2; + + if (is_ocb) + qparam.aifs = 3; + else + qparam.aifs = 2; break; case IEEE80211_AC_VO: qparam.cw_max = (aCWmin + 1) / 2 - 1; qparam.cw_min = (aCWmin + 1) / 4 - 1; - if (use_11b) + if (is_ocb) + qparam.txop = 0; + else if (use_11b) qparam.txop = 3264/32; else qparam.txop = 1504/32; @@ -1842,7 +1859,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) sdata_unlock(sdata); break; case NL80211_IFTYPE_OCB: - /* to be implemented in the future */ + changed |= BSS_CHANGED_OCB; + ieee80211_bss_info_change_notify(sdata, changed); break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index d3c5672d775f..fdf52db95b33 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -148,6 +148,10 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_ADHOC: ra = skb->data; break; + case NL80211_IFTYPE_OCB: + /* all stations are required to support WME */ + qos = true; + break; default: break; } -- GitLab From 8ed2874715c17f27bb7b9bacbcfa41bc88a64476 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Oct 2014 12:03:19 +0100 Subject: [PATCH 2904/9457] mac80211: handle RIC data element in reassociation request When the RIC data element (RDE) is included in the IEs coming from userspace for an association request, its handling is currently broken as any IEs that are contained within it would be split off from it and inserted again after all the IEs that mac80211 generates (e.g. HT, VHT.) To fix this, treat the RIC element specially, and stop after it only when we find something that doesn't actually belong to it. This assumes userspace is actually correctly building it, directly after the fast BSS transition IE and before all the others like extended capabilities. This leaves as a potential problem the case where userspace is building the following IEs: [RDE] [vendor resource description] [vendor non-resource IE] In this case, we'd erroneously consider all three IEs to be part of the RIC data together, and not split them between the two vendor IEs. Unfortunately, it isn't easily possible to distinguish vendor IEs, so this isn't easy to fix. Luckily, this case is rare as normally wpa_supplicant will include an extended capabilities IE in the IEs, and that certainly will break the two vendor IEs apart correctly. Reviewed-by: Eliad Peller Reviewed-by: Beni Lev Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 4 ++++ net/mac80211/mlme.c | 27 ++++++++++++++++++++++++--- net/mac80211/util.c | 26 ++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fbd6bee9c959..a51c993ece73 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1903,6 +1903,10 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); +size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, + const u8 *after_ric, int n_after_ric, + size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u16 cap); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c078cd344ca4..213a420704a6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -775,11 +775,30 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) WLAN_EID_QOS_CAPA, WLAN_EID_RRM_ENABLED_CAPABILITIES, WLAN_EID_MOBILITY_DOMAIN, + WLAN_EID_FAST_BSS_TRANSITION, /* reassoc only */ + WLAN_EID_RIC_DATA, /* reassoc only */ WLAN_EID_SUPPORTED_REGULATORY_CLASSES, }; - noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, - before_ht, ARRAY_SIZE(before_ht), - offset); + static const u8 after_ric[] = { + WLAN_EID_SUPPORTED_REGULATORY_CLASSES, + WLAN_EID_HT_CAPABILITY, + WLAN_EID_BSS_COEX_2040, + WLAN_EID_EXT_CAPABILITY, + WLAN_EID_QOS_TRAFFIC_CAPA, + WLAN_EID_TIM_BCAST_REQ, + WLAN_EID_INTERWORKING, + /* 60GHz doesn't happen right now */ + WLAN_EID_VHT_CAPABILITY, + WLAN_EID_OPMODE_NOTIF, + }; + + noffset = ieee80211_ie_split_ric(assoc_data->ie, + assoc_data->ie_len, + before_ht, + ARRAY_SIZE(before_ht), + after_ric, + ARRAY_SIZE(after_ric), + offset); pos = skb_put(skb, noffset - offset); memcpy(pos, assoc_data->ie + offset, noffset - offset); offset = noffset; @@ -813,6 +832,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) WLAN_EID_TIM_BCAST_REQ, WLAN_EID_INTERWORKING, }; + + /* RIC already taken above, so no need to handle here anymore */ noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, before_vht, ARRAY_SIZE(before_vht), offset); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 91e16b4d4e3c..5f7b0e935b65 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2101,16 +2101,34 @@ static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) return false; } -size_t ieee80211_ie_split(const u8 *ies, size_t ielen, - const u8 *ids, int n_ids, size_t offset) +size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, + const u8 *after_ric, int n_after_ric, + size_t offset) { size_t pos = offset; - while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) - pos += 2 + ies[pos + 1]; + while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { + if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { + pos += 2 + ies[pos + 1]; + + while (pos < ielen && + !ieee80211_id_in_list(after_ric, n_after_ric, + ies[pos])) + pos += 2 + ies[pos + 1]; + } else { + pos += 2 + ies[pos + 1]; + } + } return pos; } + +size_t ieee80211_ie_split(const u8 *ies, size_t ielen, + const u8 *ids, int n_ids, size_t offset) +{ + return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset); +} EXPORT_SYMBOL(ieee80211_ie_split); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) -- GitLab From 13a8098af93e31788684c1f2682739beb93dc680 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Tue, 4 Nov 2014 11:33:04 +0200 Subject: [PATCH 2905/9457] mac80211: increase U-APSD max service period length Deliver up to 128 frames during service period instead of 8 if unlimited is specified by the client during association. 8 was just an arbitrary value; so is 128 since unlimited can be any number. However for large traffic bursts, increasing this value looks reasonable. Also, it seems that a few certification tests expect more frames to be delivered during SP. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 2cd48cefcbdc..adc25371b171 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1531,7 +1531,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta) break; case 0: /* XXX: what is a good value? */ - n_frames = 8; + n_frames = 128; break; } -- GitLab From cf2c92d840c1424bcb3bb501147c79c9b067ad77 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 4 Nov 2014 11:43:54 +0200 Subject: [PATCH 2906/9457] mac80211: replace restart_complete() with reconfig_complete() Drivers might want to know also when mac80211 has completed reconfiguring after resume (e.g. in order to know when frames can be passed to mac80211). Rename restart_complete() to a more-generic reconfig_complete(), and add a new enum to indicate the reconfiguration type. Update the current users with the new prototype. Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 8 ++++-- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 +++++++++++--- include/net/mac80211.h | 29 ++++++++++++++++----- net/mac80211/driver-ops.h | 10 ++++--- net/mac80211/trace.h | 23 +++++++++++++--- net/mac80211/util.c | 5 +++- 7 files changed, 77 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fe531ea6926c..cc8f1fc65044 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -321,7 +321,7 @@ enum ath10k_state { * stopped in ath10k_core_restart() work holding conf_mutex. The state * RESTARTED means that the device is up and mac80211 has started hw * reconfiguration. Once mac80211 is done with the reconfiguration we - * set the state to STATE_ON in restart_complete(). */ + * set the state to STATE_ON in reconfig_complete(). */ ATH10K_STATE_RESTARTING, ATH10K_STATE_RESTARTED, diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 46709301a51e..f57459a2f51a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3929,10 +3929,14 @@ static int ath10k_resume(struct ieee80211_hw *hw) } #endif -static void ath10k_restart_complete(struct ieee80211_hw *hw) +static void ath10k_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) { struct ath10k *ar = hw->priv; + if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) + return; + mutex_lock(&ar->conf_mutex); /* If device failed to restart it will be in a different state, e.g. @@ -4450,7 +4454,7 @@ static const struct ieee80211_ops ath10k_ops = { .tx_last_beacon = ath10k_tx_last_beacon, .set_antenna = ath10k_set_antenna, .get_antenna = ath10k_get_antenna, - .restart_complete = ath10k_restart_complete, + .reconfig_complete = ath10k_reconfig_complete, .get_survey = ath10k_get_survey, .set_bitrate_mask = ath10k_set_bitrate_mask, .sta_rc_update = ath10k_sta_rc_update, diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c7a73c68bdab..e16c29dc9d49 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -857,9 +857,8 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw) return ret; } -static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) +static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; mutex_lock(&mvm->mutex); @@ -877,6 +876,21 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) mutex_unlock(&mvm->mutex); } +static void +iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + + switch (reconfig_type) { + case IEEE80211_RECONFIG_TYPE_RESTART: + iwl_mvm_restart_complete(mvm); + break; + case IEEE80211_RECONFIG_TYPE_SUSPEND: + break; + } +} + void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) { lockdep_assert_held(&mvm->mutex); @@ -3014,7 +3028,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, .ampdu_action = iwl_mvm_mac_ampdu_action, .start = iwl_mvm_mac_start, - .restart_complete = iwl_mvm_mac_restart_complete, + .reconfig_complete = iwl_mvm_mac_reconfig_complete, .stop = iwl_mvm_mac_stop, .add_interface = iwl_mvm_mac_add_interface, .remove_interface = iwl_mvm_mac_remove_interface, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index db54635d65c5..5f203a6a5e7e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2388,6 +2388,22 @@ enum ieee80211_roc_type { IEEE80211_ROC_TYPE_MGMT_TX, }; +/** + * enum ieee80211_reconfig_complete_type - reconfig type + * + * This enum is used by the reconfig_complete() callback to indicate what + * reconfiguration type was completed. + * + * @IEEE80211_RECONFIG_TYPE_RESTART: hw restart type + * (also due to resume() callback returning 1) + * @IEEE80211_RECONFIG_TYPE_SUSPEND: suspend type (regardless + * of wowlan configuration) + */ +enum ieee80211_reconfig_type { + IEEE80211_RECONFIG_TYPE_RESTART, + IEEE80211_RECONFIG_TYPE_SUSPEND, +}; + /** * struct ieee80211_ops - callbacks from mac80211 to the driver * @@ -2823,11 +2839,11 @@ enum ieee80211_roc_type { * disabled/enabled via @bss_info_changed. * @stop_ap: Stop operation on the AP interface. * - * @restart_complete: Called after a call to ieee80211_restart_hw(), when the - * reconfiguration has completed. This can help the driver implement the - * reconfiguration step. Also called when reconfiguring because the - * driver's resume function returned 1, as this is just like an "inline" - * hardware restart. This callback may sleep. + * @reconfig_complete: Called after a call to ieee80211_restart_hw() and + * during resume, when the reconfiguration has completed. + * This can help the driver implement the reconfiguration step (and + * indicate mac80211 is ready to receive frames). + * This callback may sleep. * * @ipv6_addr_change: IPv6 address assignment on the given interface changed. * Currently, this is only called for managed or P2P client interfaces. @@ -3050,7 +3066,8 @@ struct ieee80211_ops { int n_vifs, enum ieee80211_chanctx_switch_mode mode); - void (*restart_complete)(struct ieee80211_hw *hw); + void (*reconfig_complete)(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type); #if IS_ENABLED(CONFIG_IPV6) void (*ipv6_addr_change)(struct ieee80211_hw *hw, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 8e1889ff2e53..9759dd1f0734 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1152,13 +1152,15 @@ static inline void drv_stop_ap(struct ieee80211_local *local, trace_drv_return_void(local); } -static inline void drv_restart_complete(struct ieee80211_local *local) +static inline void +drv_reconfig_complete(struct ieee80211_local *local, + enum ieee80211_reconfig_type reconfig_type) { might_sleep(); - trace_drv_restart_complete(local); - if (local->ops->restart_complete) - local->ops->restart_complete(&local->hw); + trace_drv_reconfig_complete(local, reconfig_type); + if (local->ops->reconfig_complete) + local->ops->reconfig_complete(&local->hw, reconfig_type); trace_drv_return_void(local); } diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index aeeace5ba47b..809a4983eb4a 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1562,9 +1562,26 @@ DEFINE_EVENT(local_sdata_evt, drv_stop_ap, TP_ARGS(local, sdata) ); -DEFINE_EVENT(local_only_evt, drv_restart_complete, - TP_PROTO(struct ieee80211_local *local), - TP_ARGS(local) +TRACE_EVENT(drv_reconfig_complete, + TP_PROTO(struct ieee80211_local *local, + enum ieee80211_reconfig_type reconfig_type), + TP_ARGS(local, reconfig_type), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(u8, reconfig_type) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->reconfig_type = reconfig_type; + ), + + TP_printk( + LOCAL_PR_FMT " reconfig_type:%d", + LOCAL_PR_ARG, __entry->reconfig_type + ) + ); #if IS_ENABLED(CONFIG_IPV6) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5f7b0e935b65..f9319a5dca64 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1998,7 +1998,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) * We may want to change that later, however. */ if (!local->suspended || reconfig_due_to_wowlan) - drv_restart_complete(local); + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); if (!local->suspended) return 0; @@ -2009,6 +2009,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) mb(); local->resuming = false; + if (!reconfig_due_to_wowlan) + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); + list_for_each_entry(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; -- GitLab From aff437667b93c3d65576b02628885687c72e1b3b Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 24 Oct 2014 12:42:33 +0100 Subject: [PATCH 2907/9457] drm/i915: Move flags describing VMA mappings into the VMA If these flags are on the object level it will be more difficult to allow for multiple VMAs per object. v2: Simplification and cleanup after code review comments (Chris Wilson). Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- drivers/gpu/drm/i915/i915_gem_context.c | 10 ++++----- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 +++----- drivers/gpu/drm/i915/i915_gem_gtt.c | 24 +++++++++++----------- drivers/gpu/drm/i915/i915_gem_gtt.h | 8 ++++++-- drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 10 +++++---- 9 files changed, 36 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e60d5c2f4a35..61ea8da93c3b 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -116,7 +116,7 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) static inline const char *get_global_flag(struct drm_i915_gem_object *obj) { - return obj->has_global_gtt_mapping ? "g" : " "; + return i915_gem_obj_to_ggtt(obj) ? "g" : " "; } static void diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 583c97debeb7..627b7e71f168 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1856,8 +1856,6 @@ struct drm_i915_gem_object { unsigned long gt_ro:1; unsigned int cache_level:3; - unsigned int has_aliasing_ppgtt_mapping:1; - unsigned int has_global_gtt_mapping:1; unsigned int has_dma_mapping:1; unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 827edb589883..7e919784b112 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3701,7 +3701,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, list_for_each_entry(vma, &obj->vma_list, vma_link) if (drm_mm_node_allocated(&vma->node)) vma->bind_vma(vma, cache_level, - obj->has_global_gtt_mapping ? GLOBAL_BIND : 0); + vma->bound & GLOBAL_BIND); } list_for_each_entry(vma, &obj->vma_list, vma_link) @@ -4097,7 +4097,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, return PTR_ERR(vma); } - if (flags & PIN_GLOBAL && !obj->has_global_gtt_mapping) + if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND)) vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); vma->pin_count++; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index a5221d8f1580..7d3257111737 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -522,6 +522,7 @@ static int do_switch(struct intel_engine_cs *ring, struct intel_context *from = ring->last_context; u32 hw_flags = 0; bool uninitialized = false; + struct i915_vma *vma; int ret, i; if (from != NULL && ring == &dev_priv->ring[RCS]) { @@ -571,11 +572,10 @@ static int do_switch(struct intel_engine_cs *ring, if (ret) goto unpin_out; - if (!to->legacy_hw_ctx.rcs_state->has_global_gtt_mapping) { - struct i915_vma *vma = i915_gem_obj_to_vma(to->legacy_hw_ctx.rcs_state, - &dev_priv->gtt.base); - vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, GLOBAL_BIND); - } + vma = i915_gem_obj_to_ggtt(to->legacy_hw_ctx.rcs_state); + if (!(vma->bound & GLOBAL_BIND)) + vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, + GLOBAL_BIND); if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) hw_flags |= MI_RESTORE_INHIBIT; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1a0611bb576b..c70b329b07cd 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -357,12 +357,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, * through the ppgtt for non_secure batchbuffers. */ if (unlikely(IS_GEN6(dev) && reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && - !target_i915_obj->has_global_gtt_mapping)) { - struct i915_vma *vma = - list_first_entry(&target_i915_obj->vma_list, - typeof(*vma), vma_link); - vma->bind_vma(vma, target_i915_obj->cache_level, GLOBAL_BIND); - } + !(target_vma->bound & GLOBAL_BIND))) + target_vma->bind_vma(target_vma, target_i915_obj->cache_level, + GLOBAL_BIND); /* Validate that the target is in a valid r/w GPU domain */ if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ae82ef5e7df4..cb7adabc4e44 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1336,7 +1336,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) * Unfortunately above, we've just wiped out the mappings * without telling our object about it. So we need to fake it. */ - obj->has_global_gtt_mapping = 0; + vma->bound &= ~GLOBAL_BIND; vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); } @@ -1533,7 +1533,7 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma, BUG_ON(!i915_is_ggtt(vma->vm)); intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags); - vma->obj->has_global_gtt_mapping = 1; + vma->bound = GLOBAL_BIND; } static void i915_ggtt_clear_range(struct i915_address_space *vm, @@ -1552,7 +1552,7 @@ static void i915_ggtt_unbind_vma(struct i915_vma *vma) const unsigned int size = vma->obj->base.size >> PAGE_SHIFT; BUG_ON(!i915_is_ggtt(vma->vm)); - vma->obj->has_global_gtt_mapping = 0; + vma->bound = 0; intel_gtt_clear_range(first, size); } @@ -1580,24 +1580,24 @@ static void ggtt_bind_vma(struct i915_vma *vma, * flags. At all other times, the GPU will use the aliasing PPGTT. */ if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { - if (!obj->has_global_gtt_mapping || + if (!(vma->bound & GLOBAL_BIND) || (cache_level != obj->cache_level)) { vma->vm->insert_entries(vma->vm, obj->pages, vma->node.start, cache_level, flags); - obj->has_global_gtt_mapping = 1; + vma->bound |= GLOBAL_BIND; } } if (dev_priv->mm.aliasing_ppgtt && - (!obj->has_aliasing_ppgtt_mapping || + (!(vma->bound & LOCAL_BIND) || (cache_level != obj->cache_level))) { struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; appgtt->base.insert_entries(&appgtt->base, vma->obj->pages, vma->node.start, cache_level, flags); - vma->obj->has_aliasing_ppgtt_mapping = 1; + vma->bound |= LOCAL_BIND; } } @@ -1607,21 +1607,21 @@ static void ggtt_unbind_vma(struct i915_vma *vma) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj = vma->obj; - if (obj->has_global_gtt_mapping) { + if (vma->bound & GLOBAL_BIND) { vma->vm->clear_range(vma->vm, vma->node.start, obj->base.size, true); - obj->has_global_gtt_mapping = 0; + vma->bound &= ~GLOBAL_BIND; } - if (obj->has_aliasing_ppgtt_mapping) { + if (vma->bound & LOCAL_BIND) { struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; appgtt->base.clear_range(&appgtt->base, vma->node.start, obj->base.size, true); - obj->has_aliasing_ppgtt_mapping = 0; + vma->bound &= ~LOCAL_BIND; } } @@ -1699,7 +1699,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, DRM_DEBUG_KMS("Reservation failed: %i\n", ret); return ret; } - obj->has_global_gtt_mapping = 1; + vma->bound |= GLOBAL_BIND; } dev_priv->gtt.base.start = start; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index d5c14af51e99..d0562d0ef6ec 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -123,6 +123,12 @@ struct i915_vma { struct drm_i915_gem_object *obj; struct i915_address_space *vm; + /** Flags and address space this VMA is bound to */ +#define GLOBAL_BIND (1<<0) +#define LOCAL_BIND (1<<1) +#define PTE_READ_ONLY (1<<2) + unsigned int bound : 4; + /** This object's place on the active/inactive lists */ struct list_head mm_list; @@ -155,8 +161,6 @@ struct i915_vma { * setting the valid PTE entries to a reserved scratch page. */ void (*unbind_vma)(struct i915_vma *vma); /* Map an object into an address space with the given cache flags. */ -#define GLOBAL_BIND (1<<0) -#define PTE_READ_ONLY (1<<1) void (*bind_vma)(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags); diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 85fda6b803e4..c38891892547 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -533,7 +533,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, } } - obj->has_global_gtt_mapping = 1; + vma->bound |= GLOBAL_BIND; list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); list_add_tail(&vma->mm_list, &ggtt->inactive_list); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index e664599de6e7..d17360bc1cd1 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -565,6 +565,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, struct i915_address_space *vm) { struct drm_i915_error_object *dst; + struct i915_vma *vma = NULL; int num_pages; bool use_ggtt; int i = 0; @@ -585,16 +586,17 @@ i915_error_object_create(struct drm_i915_private *dev_priv, dst->gtt_offset = -1; reloc_offset = dst->gtt_offset; + if (i915_is_ggtt(vm)) + vma = i915_gem_obj_to_ggtt(src); use_ggtt = (src->cache_level == I915_CACHE_NONE && - i915_is_ggtt(vm) && - src->has_global_gtt_mapping && - reloc_offset + num_pages * PAGE_SIZE <= dev_priv->gtt.mappable_end); + vma && (vma->bound & GLOBAL_BIND) && + reloc_offset + num_pages * PAGE_SIZE <= dev_priv->gtt.mappable_end); /* Cannot access stolen address directly, try to use the aperture */ if (src->stolen) { use_ggtt = true; - if (!src->has_global_gtt_mapping) + if (!(vma && vma->bound & GLOBAL_BIND)) goto unwind; reloc_offset = i915_gem_obj_ggtt_offset(src); -- GitLab From a919db9015832d7e4140a38e20ddc1c305c95cb2 Mon Sep 17 00:00:00 2001 From: Sonika Jindal Date: Thu, 23 Oct 2014 07:41:33 -0700 Subject: [PATCH 2908/9457] drm/i915: Update plane parameters for cursor plane (v2) This allows the cursor plane to be updated the same way as primary and sprites, and same set_property handler is used for all of these planes. v2 (by Matt Roper): Rework to apply to latest di-nightly codebase. The switch to split check/commit plane programming changed the code flow enough that the original patch could no longer be applied. Signed-off-by: Sonika Jindal Reviewed-by: Matt Roper Tested-by (IVB): Matt Roper Signed-off-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1d2fa7f4523e..910e8a4603fa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11955,12 +11955,24 @@ intel_commit_cursor_plane(struct drm_plane *plane, struct drm_crtc *crtc = state->crtc; struct drm_framebuffer *fb = state->fb; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct drm_i915_gem_object *obj = intel_fb->obj; int crtc_w, crtc_h; crtc->cursor_x = state->orig_dst.x1; crtc->cursor_y = state->orig_dst.y1; + + intel_plane->crtc_x = state->orig_dst.x1; + intel_plane->crtc_y = state->orig_dst.y1; + intel_plane->crtc_w = drm_rect_width(&state->orig_dst); + intel_plane->crtc_h = drm_rect_height(&state->orig_dst); + intel_plane->src_x = state->orig_src.x1; + intel_plane->src_y = state->orig_src.y1; + intel_plane->src_w = drm_rect_width(&state->orig_src); + intel_plane->src_h = drm_rect_height(&state->orig_src); + intel_plane->obj = obj; + if (fb != crtc->cursor->fb) { crtc_w = drm_rect_width(&state->orig_dst); crtc_h = drm_rect_height(&state->orig_dst); -- GitLab From 42c7156af94783ff42edba6a3b07a51d35552c60 Mon Sep 17 00:00:00 2001 From: Brad Volkin Date: Thu, 16 Oct 2014 12:24:42 -0700 Subject: [PATCH 2909/9457] drm/i915: Abort command parsing for chained batches libva uses chained batch buffers in a way that the command parser can't generally handle. Fortunately, libva doesn't need to write registers from batch buffers in the way that mesa does, so this patch causes the driver to fall back to non-secure dispatch if the parser detects a chained batch buffer. Note: The 2nd hunk to munge the error code of the parser looks a bit superflous. At least until we have the batch copy code ready and can run the cmd parser in granting mode. But it isn't since we still need to let existing libva buffers pass (though not with elevated privs ofc!). Testcase: igt/gem_exec_parse/chained-batch Signed-off-by: Brad Volkin [danvet: Add note - this confused me in review and Brad clarified things (after a few mails ...).] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 18 +++++++++++++++- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 24 ++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 86b3ae0934a7..ef38915075a1 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -138,6 +138,11 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { .mask = MI_GLOBAL_GTT, .expected = 0, }}, ), + /* + * MI_BATCH_BUFFER_START requires some special handling. It's not + * really a 'skip' action but it doesn't seem like it's worth adding + * a new action. See i915_parse_cmds(). + */ CMD( MI_BATCH_BUFFER_START, SMI, !F, 0xFF, S ), }; @@ -955,7 +960,8 @@ static bool check_cmd(const struct intel_engine_cs *ring, * Parses the specified batch buffer looking for privilege violations as * described in the overview. * - * Return: non-zero if the parser finds violations or otherwise fails + * Return: non-zero if the parser finds violations or otherwise fails; -EACCES + * if the batch appears legal but should use hardware parsing */ int i915_parse_cmds(struct intel_engine_cs *ring, struct drm_i915_gem_object *batch_obj, @@ -1002,6 +1008,16 @@ int i915_parse_cmds(struct intel_engine_cs *ring, break; } + /* + * If the batch buffer contains a chained batch, return an + * error that tells the caller to abort and dispatch the + * workload as a non-secure batch. + */ + if (desc->cmd.value == MI_BATCH_BUFFER_START) { + ret = -EACCES; + break; + } + if (desc->flags & CMD_DESC_FIXED) length = desc->length.fixed; else diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c70b329b07cd..4b7f5c104ce0 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1365,17 +1365,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, batch_obj, args->batch_start_offset, file->is_master); - if (ret) - goto err; - - /* - * XXX: Actually do this when enabling batch copy... - * - * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit - * from MI_BATCH_BUFFER_START commands issued in the - * dispatch_execbuffer implementations. We specifically don't - * want that set when the command parser is enabled. - */ + if (ret) { + if (ret != -EACCES) + goto err; + } else { + /* + * XXX: Actually do this when enabling batch copy... + * + * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit + * from MI_BATCH_BUFFER_START commands issued in the + * dispatch_execbuffer implementations. We specifically don't + * want that set when the command parser is enabled. + */ + } } /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure -- GitLab From 655b5391ca5ef4095110c0b3f82f10e337f0a736 Mon Sep 17 00:00:00 2001 From: Armin Reese Date: Thu, 23 Oct 2014 08:34:27 -0700 Subject: [PATCH 2910/9457] drm/i915 Update Gen8 golden context batch buffer The file drivers/gpu/drm/i915/intel_renderstate_gen8.c is updated to the version created by IGT null_state_gen Signed-off-by: Armin Reese Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_renderstate_gen8.c | 802 ++++++++++++++---- 1 file changed, 640 insertions(+), 162 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c index 75ef1b5de45c..78011d73fa9f 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c @@ -1,70 +1,575 @@ #include "intel_renderstate.h" static const u32 gen8_null_state_relocs[] = { - 0x00000048, - 0x00000050, - 0x00000060, - 0x000003ec, + 0x00000798, + 0x000007a4, + 0x000007ac, + 0x000007bc, -1, }; static const u32 gen8_null_state_batch[] = { + 0x7a000004, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, 0x69040000, - 0x61020001, + 0x78140000, + 0x04000000, + 0x7820000a, + 0x00000000, + 0x00000000, + 0x80000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78130002, + 0x00000000, + 0x00000000, + 0x02001808, + 0x781f0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78510009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78100007, + 0x00000000, + 0x00000000, + 0x00010000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781b0007, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000800, + 0x00000000, + 0x78110008, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781e0003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781d0007, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78120002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78500003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781c0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x780c0000, + 0x00000000, + 0x78520003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78300000, + 0x08010040, + 0x78310000, + 0x1e000000, + 0x78320000, + 0x1e000000, + 0x78330000, + 0x1e000000, + 0x79190002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x791a0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x791b0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79120000, + 0x00000000, + 0x79130000, + 0x00000000, + 0x79140000, + 0x00000000, + 0x79150000, + 0x00000000, + 0x79160000, + 0x00000000, + 0x78150009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78190009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781a0009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78160009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78170009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78490001, + 0x00000000, + 0x00000000, + 0x784a0000, + 0x00000000, + 0x784b0000, + 0x00000004, + 0x79170101, + 0x00000000, + 0x00000080, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, 0x00000000, 0x00000000, - 0x79120000, 0x00000000, - 0x79130000, 0x00000000, - 0x79140000, 0x00000000, - 0x79150000, 0x00000000, - 0x79160000, 0x00000000, - 0x6101000e, - 0x00000001, 0x00000000, - 0x00000001, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x20000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x40000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x60000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x6101000e, 0x00000001, /* reloc */ 0x00000000, + 0x00000000, 0x00000001, /* reloc */ 0x00000000, + 0x00000001, /* reloc */ 0x00000000, + 0x00000001, 0x00000000, 0x00000001, /* reloc */ 0x00000000, - 0xfffff001, 0x00001001, - 0xfffff001, 0x00001001, - 0x78230000, - 0x000006e0, - 0x78210000, - 0x00000700, - 0x78300000, - 0x08010040, - 0x78330000, - 0x08000000, - 0x78310000, - 0x08000000, - 0x78320000, - 0x08000000, - 0x78240000, - 0x00000641, - 0x780e0000, - 0x00000601, + 0x00000001, + 0x00001001, + 0x61020001, + 0x00000000, + 0x00000000, + 0x79000002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78050006, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x40000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x80000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0xc0000000, + 0x00000000, + 0x00000000, + 0x79080001, + 0x00000000, + 0x00000000, + 0x790a0001, + 0x00000000, + 0x00000000, + 0x78060003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78070003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78040001, + 0x00000000, + 0x00000000, + 0x79110000, + 0x00000000, 0x780d0000, 0x00000000, - 0x78180000, - 0x00000001, - 0x78520003, + 0x79060000, 0x00000000, + 0x7907001f, 0x00000000, 0x00000000, 0x00000000, - 0x78190009, 0x00000000, 0x00000000, 0x00000000, @@ -75,7 +580,6 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x781b0007, 0x00000000, 0x00000000, 0x00000000, @@ -84,26 +588,22 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x78270000, 0x00000000, - 0x782c0000, 0x00000000, - 0x781c0002, 0x00000000, 0x00000000, 0x00000000, - 0x78160009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x7902000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x78110008, 0x00000000, 0x00000000, 0x00000000, @@ -113,12 +613,10 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x78290000, 0x00000000, - 0x782e0000, 0x00000000, - 0x781a0009, 0x00000000, + 0x790c000f, 0x00000000, 0x00000000, 0x00000000, @@ -128,7 +626,6 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x781d0007, 0x00000000, 0x00000000, 0x00000000, @@ -136,153 +633,153 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, + 0x780a0003, 0x00000000, - 0x78280000, 0x00000000, - 0x782d0000, 0x00000000, - 0x78260000, 0x00000000, - 0x782b0000, + 0x78080083, + 0x00004000, 0x00000000, - 0x78150009, 0x00000000, 0x00000000, + 0x04004000, 0x00000000, 0x00000000, 0x00000000, + 0x08004000, 0x00000000, 0x00000000, 0x00000000, + 0x0c004000, 0x00000000, 0x00000000, - 0x78100007, 0x00000000, + 0x10004000, 0x00000000, 0x00000000, 0x00000000, + 0x14004000, 0x00000000, 0x00000000, 0x00000000, + 0x18004000, 0x00000000, - 0x781e0003, 0x00000000, 0x00000000, + 0x1c004000, 0x00000000, 0x00000000, - 0x78120002, 0x00000000, + 0x20004000, 0x00000000, 0x00000000, - 0x781f0002, - 0x30400820, 0x00000000, + 0x24004000, 0x00000000, - 0x78510009, 0x00000000, 0x00000000, + 0x28004000, 0x00000000, 0x00000000, 0x00000000, + 0x2c004000, 0x00000000, 0x00000000, 0x00000000, + 0x30004000, 0x00000000, 0x00000000, - 0x78500003, - 0x00210000, 0x00000000, + 0x34004000, 0x00000000, 0x00000000, - 0x78130002, 0x00000000, + 0x38004000, 0x00000000, 0x00000000, - 0x782a0000, - 0x00000480, - 0x782f0000, - 0x00000540, - 0x78140000, - 0x00000800, - 0x78170009, 0x00000000, + 0x3c004000, 0x00000000, 0x00000000, 0x00000000, + 0x40004000, 0x00000000, 0x00000000, 0x00000000, + 0x44004000, 0x00000000, 0x00000000, 0x00000000, - 0x7820000a, - 0x00000580, + 0x48004000, 0x00000000, - 0x08080000, 0x00000000, 0x00000000, - 0x1f000002, - 0x00060000, + 0x4c004000, 0x00000000, 0x00000000, 0x00000000, + 0x50004000, 0x00000000, - 0x784d0000, - 0x40000000, - 0x784f0000, - 0x80000100, - 0x780f0000, - 0x00000740, - 0x78050006, 0x00000000, 0x00000000, + 0x54004000, 0x00000000, 0x00000000, 0x00000000, + 0x58004000, 0x00000000, 0x00000000, - 0x78070003, 0x00000000, + 0x5c004000, 0x00000000, 0x00000000, 0x00000000, - 0x78060003, + 0x60004000, 0x00000000, 0x00000000, 0x00000000, + 0x64004000, 0x00000000, - 0x78040001, 0x00000000, - 0x00000001, - 0x79000002, - 0xffffffff, + 0x00000000, + 0x68004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x6c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x70004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x74004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78004000, + 0x00000000, 0x00000000, 0x00000000, - 0x78080003, - 0x00006000, - 0x000005e0, /* reloc */ + 0x7c004000, 0x00000000, 0x00000000, - 0x78090005, + 0x00000000, + 0x80004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78090043, 0x02000000, 0x22220000, - 0x02f60000, - 0x11230000, - 0x02850004, - 0x11230000, - 0x784b0000, - 0x0000000f, - 0x78490001, 0x00000000, 0x00000000, - 0x7b000005, 0x00000000, - 0x00000003, 0x00000000, - 0x00000001, 0x00000000, 0x00000000, - 0x05000000, /* cmds end */ 0x00000000, 0x00000000, 0x00000000, @@ -297,8 +794,6 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x000004c0, /* state start */ - 0x00000500, 0x00000000, 0x00000000, 0x00000000, @@ -345,46 +840,65 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, + 0x680b0001, + 0x78260000, + 0x00000000, + 0x78270000, + 0x00000000, + 0x78280000, + 0x00000000, + 0x78290000, + 0x00000000, + 0x782a0000, + 0x00000000, + 0x780e0000, + 0x00000dc1, + 0x78240000, + 0x00000e01, + 0x784f0000, + 0x80000100, + 0x784d0000, + 0x40000000, + 0x782b0000, + 0x00000000, + 0x782c0000, + 0x00000000, + 0x782d0000, + 0x00000000, + 0x782e0000, + 0x00000000, + 0x782f0000, + 0x00000000, + 0x780f0000, 0x00000000, + 0x78230000, + 0x00000e60, + 0x78210000, + 0x00000e80, + 0x7b000005, + 0x00000004, + 0x00000001, 0x00000000, + 0x00000001, 0x00000000, - 0x00000092, 0x00000000, + 0x05000000, /* cmds end */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, /* state start */ 0x00000000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0060005a, - 0x21403ae8, - 0x3a0000c0, - 0x008d0040, - 0x0060005a, - 0x21603ae8, - 0x3a0000c0, - 0x008d0080, - 0x0060005a, - 0x21803ae8, - 0x3a0000d0, - 0x008d0040, - 0x0060005a, - 0x21a03ae8, - 0x3a0000d0, - 0x008d0080, - 0x02800031, - 0x2e0022e8, - 0x0e000140, - 0x08840001, - 0x05800031, - 0x200022e0, - 0x0e000e00, - 0x90031000, 0x00000000, 0x00000000, 0x00000000, @@ -410,38 +924,6 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, - 0x06200000, - 0x00000002, 0x00000000, 0x00000000, 0x00000000, @@ -449,8 +931,6 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0xf99a130c, - 0x799a130c, 0x00000000, 0x00000000, 0x00000000, @@ -466,9 +946,7 @@ static const u32 gen8_null_state_batch[] = { 0x00000000, 0x00000000, 0x00000000, - 0x3f800000, 0x00000000, - 0x3f800000, 0x00000000, 0x00000000, 0x00000000, -- GitLab From ff7a60f28fa2e018ecd91dc00cbb91d07ff1eb91 Mon Sep 17 00:00:00 2001 From: Armin Reese Date: Thu, 23 Oct 2014 08:34:28 -0700 Subject: [PATCH 2911/9457] drm/i915 Add golden context support for Gen9 This patch includes the Gen9 batch buffer to generate a 'golden context' for that product family. Signed-off-by: Armin Reese Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/i915_gem_render_state.c | 2 + drivers/gpu/drm/i915/intel_renderstate.h | 1 + drivers/gpu/drm/i915/intel_renderstate_gen9.c | 974 ++++++++++++++++++ 4 files changed, 979 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/intel_renderstate_gen9.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 75fd7de9bf4b..9c646c66fa58 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -40,7 +40,8 @@ i915-y += i915_cmd_parser.o \ # autogenerated null render state i915-y += intel_renderstate_gen6.o \ intel_renderstate_gen7.o \ - intel_renderstate_gen8.o + intel_renderstate_gen8.o \ + intel_renderstate_gen9.o # modesetting core code i915-y += intel_bios.o \ diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index a9a62d75aa57..98dcd94acba8 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -38,6 +38,8 @@ render_state_get_rodata(struct drm_device *dev, const int gen) return &gen7_null_state; case 8: return &gen8_null_state; + case 9: + return &gen9_null_state; } return NULL; diff --git a/drivers/gpu/drm/i915/intel_renderstate.h b/drivers/gpu/drm/i915/intel_renderstate.h index 6c792d3a9c9c..5bd69852752c 100644 --- a/drivers/gpu/drm/i915/intel_renderstate.h +++ b/drivers/gpu/drm/i915/intel_renderstate.h @@ -29,6 +29,7 @@ extern const struct intel_renderstate_rodata gen6_null_state; extern const struct intel_renderstate_rodata gen7_null_state; extern const struct intel_renderstate_rodata gen8_null_state; +extern const struct intel_renderstate_rodata gen9_null_state; #define RO_RENDERSTATE(_g) \ const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c b/drivers/gpu/drm/i915/intel_renderstate_gen9.c new file mode 100644 index 000000000000..875075373807 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c @@ -0,0 +1,974 @@ +#include "intel_renderstate.h" + +static const u32 gen9_null_state_relocs[] = { + 0x000007a8, + 0x000007b4, + 0x000007bc, + 0x000007cc, + -1, +}; + +static const u32 gen9_null_state_batch[] = { + 0x7a000004, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x69040300, + 0x78140000, + 0x04000000, + 0x7820000a, + 0x00000000, + 0x00000000, + 0x80000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78130002, + 0x00000000, + 0x00000000, + 0x02001808, + 0x781f0004, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78510009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78100007, + 0x00000000, + 0x00000000, + 0x00010000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781b0007, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000800, + 0x00000000, + 0x78110008, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781e0003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781d0009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78120002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78500003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781c0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x780c0000, + 0x00000000, + 0x78520003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78300000, + 0x08010040, + 0x78310000, + 0x1e000000, + 0x78320000, + 0x1e000000, + 0x78330000, + 0x1e000000, + 0x79190002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x791a0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x791b0002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79120000, + 0x00000000, + 0x79130000, + 0x00000000, + 0x79140000, + 0x00000000, + 0x79150000, + 0x00000000, + 0x79160000, + 0x00000000, + 0x78150009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78190009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x781a0009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78160009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78170009, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78490001, + 0x00000000, + 0x00000000, + 0x784a0000, + 0x00000000, + 0x784b0000, + 0x00000004, + 0x79170101, + 0x00000000, + 0x00000080, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x20000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x40000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79180006, + 0x60000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x61010011, + 0x00000001, /* reloc */ + 0x00000000, + 0x00000000, + 0x00000001, /* reloc */ + 0x00000000, + 0x00000001, /* reloc */ + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000001, /* reloc */ + 0x00000000, + 0x00001001, + 0x00001001, + 0x00000001, + 0x00001001, + 0x00000000, + 0x00000000, + 0x00000000, + 0x61020001, + 0x00000000, + 0x00000000, + 0x79000002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78050006, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x40000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0x80000000, + 0x00000000, + 0x00000000, + 0x79040002, + 0xc0000000, + 0x00000000, + 0x00000000, + 0x79080001, + 0x00000000, + 0x00000000, + 0x790a0001, + 0x00000000, + 0x00000000, + 0x78060003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78070003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78040001, + 0x00000000, + 0x00000000, + 0x79110000, + 0x00000000, + 0x780d0000, + 0x00000000, + 0x79060000, + 0x00000000, + 0x7907001f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x7902000f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x790c000f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x780a0003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78080083, + 0x00004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x04004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x10004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x14004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x18004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x1c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x20004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x24004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x28004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x2c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x30004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x34004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x38004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x3c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x44004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x48004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x50004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x54004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x58004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x5c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x60004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x64004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x68004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x6c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x70004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x74004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x7c004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80004000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78090043, + 0x02000000, + 0x22220000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x78550003, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x680b0001, + 0x780e0000, + 0x00000e01, + 0x78240000, + 0x00000e41, + 0x784f0000, + 0x80000100, + 0x784d0000, + 0x40000000, + 0x782b0000, + 0x00000000, + 0x782c0000, + 0x00000000, + 0x782d0000, + 0x00000000, + 0x782e0000, + 0x00000000, + 0x782f0000, + 0x00000000, + 0x780f0000, + 0x00000000, + 0x78230000, + 0x00000ea0, + 0x78210000, + 0x00000ec0, + 0x78260000, + 0x00000000, + 0x78270000, + 0x00000000, + 0x78280000, + 0x00000000, + 0x78290000, + 0x00000000, + 0x782a0000, + 0x00000000, + 0x7b000005, + 0x00000004, + 0x00000001, + 0x00000000, + 0x00000001, + 0x00000000, + 0x00000000, + 0x05000000, /* cmds end */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, /* state start */ + 0x00000000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, /* state end */ +}; + +RO_RENDERSTATE(9); -- GitLab From 3f20df98870236b288a90fc3b65f593d3db05b17 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 14:51:34 +0100 Subject: [PATCH 2912/9457] drm/i915: only flip frontbuffer if crtc is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in flipping a buffer for a disabled crtc. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 910e8a4603fa..140bbefaac8d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8544,9 +8544,9 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, if (old_width != width) intel_update_watermarks(crtc); intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); - } - intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe)); + intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe)); + } return 0; fail_unpin: -- GitLab From c5d974728fafc151e740638b4cf492958be78b5b Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 25 Oct 2014 00:11:11 +0100 Subject: [PATCH 2913/9457] drm/i915: Remove unnecessary test on the gen in intel_do_mmio_flip() use_mmio_flip() makes sure we only enable MMIO flips on gen5+. So we don't need to take into account older devices. Signed-off-by: Damien Lespiau Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 140bbefaac8d..46224c6307cb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9567,12 +9567,11 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) reg = DSPCNTR(intel_crtc->plane); dspcntr = I915_READ(reg); - if (INTEL_INFO(dev)->gen >= 4) { - if (obj->tiling_mode != I915_TILING_NONE) - dspcntr |= DISPPLANE_TILED; - else - dspcntr &= ~DISPPLANE_TILED; - } + if (obj->tiling_mode != I915_TILING_NONE) + dspcntr |= DISPPLANE_TILED; + else + dspcntr &= ~DISPPLANE_TILED; + I915_WRITE(reg, dspcntr); I915_WRITE(DSPSURF(intel_crtc->plane), -- GitLab From d507941beb1ef98c19e2902007aee4faf36f854f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 4 Nov 2014 13:57:15 +0100 Subject: [PATCH 2914/9457] ALSA: pcm: Correct PCM BUG error message While converting to dev_*(), the message showing the invalid PCM position was wrongly tagged as if an XRUN although it's actually a BUG. This patch corrects the message again. Signed-off-by: Takashi Iwai --- sound/core/pcm_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index dfc28542a007..7b9e2fb35a86 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -345,7 +345,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, snd_pcm_debug_name(substream, name, sizeof(name)); xrun_log_show(substream); pcm_err(substream->pcm, - "XRUN: %s, pos = %ld, buffer size = %ld, period size = %ld\n", + "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n", name, pos, runtime->buffer_size, runtime->period_size); } -- GitLab From f5914908a5b7b2338f210e56827a1ef35585dc6d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 4 Nov 2014 12:45:59 +0100 Subject: [PATCH 2915/9457] ALSA: pcm: Replace PCM hwptr tracking with tracepoints ALSA PCM core has a mechanism tracking the PCM hwptr updates for analyzing XRUNs. But its log is limited (up to 10) and its log output is a kernel message, which is hard to handle. In this patch, the hwptr logging is moved to the tracing infrastructure instead of its own. Not only the hwptr updates but also XRUN and hwptr errors are recorded on the trace log, so that user can see such events at the exact timing. The new "snd_pcm" entry will appear in the tracing events: # ls -F /sys/kernel/debug/tracing/events/snd_pcm enable filter hw_ptr_error/ hwptr/ xrun/ The hwptr is for the regular hwptr update events. An event trace looks like: aplay-26187 [004] d..3 4012.834761: hwptr: pcmC0D0p/sub0: POS: pos=488, old=0, base=0, period=1024, buf=16384 "POS" shows the hwptr update by the explicit position update call and "IRQ" means the hwptr update by the interrupt, i.e. snd_pcm_period_elapsed() call. The "pos" is the passed ring-buffer offset by the caller, "old" is the previous hwptr, "base" is the hwptr base position, "period" and "buf" are period- and buffer-size of the target PCM substream. (Note that the hwptr position displayed here isn't the ring-buffer offset. It increments up to the PCM position boundary.) The XRUN event appears similarly, but without "pos" field. The hwptr error events appear with the PCM identifier and its reason string, such as "Lost interrupt?". The XRUN and hwptr error reports on kernel message are still left, can be turned on/off via xrun_debug proc like before. But the bit 3, 4, 5 and 6 bits of xrun_debug proc are dropped by this patch. Also, along with the change, the message strings have been reformatted to be a bit more consistent. Last but not least, the hwptr reporting is enabled only when CONFIG_SND_PCM_XRUN_DEBUG is set. Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/Procfile.txt | 13 --- sound/core/Makefile | 3 + sound/core/pcm_lib.c | 146 +++++--------------------- sound/core/pcm_trace.h | 110 +++++++++++++++++++ 4 files changed, 137 insertions(+), 135 deletions(-) create mode 100644 sound/core/pcm_trace.h diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt index 7fcd1ad96fcc..cfc49567b9dc 100644 --- a/Documentation/sound/alsa/Procfile.txt +++ b/Documentation/sound/alsa/Procfile.txt @@ -101,10 +101,6 @@ card*/pcm*/xrun_debug bit 0 = Enable XRUN/jiffies debug messages bit 1 = Show stack trace at XRUN / jiffies check bit 2 = Enable additional jiffies check - bit 3 = Log hwptr update at each period interrupt - bit 4 = Log hwptr update at each snd_pcm_update_hw_ptr() - bit 5 = Show last 10 positions on error - bit 6 = Do above only once When the bit 0 is set, the driver will show the messages to kernel log when an xrun is detected. The debug message is @@ -121,15 +117,6 @@ card*/pcm*/xrun_debug buggy) hardware that doesn't give smooth pointer updates. This feature is enabled via the bit 2. - Bits 3 and 4 are for logging the hwptr records. Note that - these will give flood of kernel messages. - - When bit 5 is set, the driver logs the last 10 xrun errors and - the proc file shows each jiffies, position, period_size, - buffer_size, old_hw_ptr, and hw_ptr_base values. - - When bit 6 is set, the full xrun log is shown only once. - card*/pcm*/sub*/info The general information of this PCM sub-stream. diff --git a/sound/core/Makefile b/sound/core/Makefile index 394a38909f6b..4daf2f58261c 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -14,6 +14,9 @@ snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ pcm_memory.o memalloc.o snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o +# for trace-points +CFLAGS_pcm_lib.o := -I$(src) + snd-pcm-dmaengine-objs := pcm_dmaengine.o snd-rawmidi-objs := rawmidi.o diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 7b9e2fb35a86..ec9e7866177f 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -32,6 +32,15 @@ #include #include +#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#define CREATE_TRACE_POINTS +#include "pcm_trace.h" +#else +#define trace_hwptr(substream, pos, in_interrupt) +#define trace_xrun(substream) +#define trace_hw_ptr_error(substream, reason) +#endif + /* * fill ring buffer with silence * runtime->silence_start: starting pointer to silence area @@ -146,10 +155,6 @@ EXPORT_SYMBOL(snd_pcm_debug_name); #define XRUN_DEBUG_BASIC (1<<0) #define XRUN_DEBUG_STACK (1<<1) /* dump also stack */ #define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */ -#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */ -#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */ -#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */ -#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */ #ifdef CONFIG_SND_PCM_XRUN_DEBUG @@ -168,6 +173,7 @@ static void xrun(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; + trace_xrun(substream); if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); @@ -180,97 +186,19 @@ static void xrun(struct snd_pcm_substream *substream) } #ifdef CONFIG_SND_PCM_XRUN_DEBUG -#define hw_ptr_error(substream, fmt, args...) \ +#define hw_ptr_error(substream, in_interrupt, reason, fmt, args...) \ do { \ + trace_hw_ptr_error(substream, reason); \ if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ - xrun_log_show(substream); \ - pr_err_ratelimited("ALSA: PCM: " fmt, ##args); \ + pr_err_ratelimited("ALSA: PCM: [%c] " reason ": " fmt, \ + (in_interrupt) ? 'Q' : 'P', ##args); \ dump_stack_on_xrun(substream); \ } \ } while (0) -#define XRUN_LOG_CNT 10 - -struct hwptr_log_entry { - unsigned int in_interrupt; - unsigned long jiffies; - snd_pcm_uframes_t pos; - snd_pcm_uframes_t period_size; - snd_pcm_uframes_t buffer_size; - snd_pcm_uframes_t old_hw_ptr; - snd_pcm_uframes_t hw_ptr_base; -}; - -struct snd_pcm_hwptr_log { - unsigned int idx; - unsigned int hit: 1; - struct hwptr_log_entry entries[XRUN_LOG_CNT]; -}; - -static void xrun_log(struct snd_pcm_substream *substream, - snd_pcm_uframes_t pos, int in_interrupt) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_pcm_hwptr_log *log = runtime->hwptr_log; - struct hwptr_log_entry *entry; - - if (log == NULL) { - log = kzalloc(sizeof(*log), GFP_ATOMIC); - if (log == NULL) - return; - runtime->hwptr_log = log; - } else { - if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) - return; - } - entry = &log->entries[log->idx]; - entry->in_interrupt = in_interrupt; - entry->jiffies = jiffies; - entry->pos = pos; - entry->period_size = runtime->period_size; - entry->buffer_size = runtime->buffer_size; - entry->old_hw_ptr = runtime->status->hw_ptr; - entry->hw_ptr_base = runtime->hw_ptr_base; - log->idx = (log->idx + 1) % XRUN_LOG_CNT; -} - -static void xrun_log_show(struct snd_pcm_substream *substream) -{ - struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log; - struct hwptr_log_entry *entry; - char name[16]; - unsigned int idx; - int cnt; - - if (log == NULL) - return; - if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit) - return; - snd_pcm_debug_name(substream, name, sizeof(name)); - for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) { - entry = &log->entries[idx]; - if (entry->period_size == 0) - break; - pr_info("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, " - "hwptr=%ld/%ld\n", - name, entry->in_interrupt ? "[Q] " : "", - entry->jiffies, - (unsigned long)entry->pos, - (unsigned long)entry->period_size, - (unsigned long)entry->buffer_size, - (unsigned long)entry->old_hw_ptr, - (unsigned long)entry->hw_ptr_base); - idx++; - idx %= XRUN_LOG_CNT; - } - log->hit = 1; -} - #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ #define hw_ptr_error(substream, fmt, args...) do { } while (0) -#define xrun_log(substream, pos, in_interrupt) do { } while (0) -#define xrun_log_show(substream) do { } while (0) #endif @@ -343,7 +271,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (printk_ratelimit()) { char name[16]; snd_pcm_debug_name(substream, name, sizeof(name)); - xrun_log_show(substream); pcm_err(substream->pcm, "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n", name, pos, runtime->buffer_size, @@ -352,8 +279,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, pos = 0; } pos -= pos % runtime->min_align; - if (xrun_debug(substream, XRUN_DEBUG_LOG)) - xrun_log(substream, pos, in_interrupt); + trace_hwptr(substream, pos, in_interrupt); hw_base = runtime->hw_ptr_base; new_hw_ptr = hw_base + pos; if (in_interrupt) { @@ -388,22 +314,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, delta = new_hw_ptr - old_hw_ptr; if (delta < 0) delta += runtime->boundary; - if (xrun_debug(substream, in_interrupt ? - XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { - char name[16]; - snd_pcm_debug_name(substream, name, sizeof(name)); - pcm_dbg(substream->pcm, - "%s_update: %s: pos=%u/%u/%u, hwptr=%ld/%ld/%ld/%ld\n", - in_interrupt ? "period" : "hwptr", - name, - (unsigned int)pos, - (unsigned int)runtime->period_size, - (unsigned int)runtime->buffer_size, - (unsigned long)delta, - (unsigned long)old_hw_ptr, - (unsigned long)new_hw_ptr, - (unsigned long)runtime->hw_ptr_base); - } if (runtime->no_period_wakeup) { snd_pcm_sframes_t xrun_threshold; @@ -431,13 +341,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, /* something must be really wrong */ if (delta >= runtime->buffer_size + runtime->period_size) { - hw_ptr_error(substream, - "Unexpected hw_pointer value %s" - "(stream=%i, pos=%ld, new_hw_ptr=%ld, " - "old_hw_ptr=%ld)\n", - in_interrupt ? "[Q] " : "[P]", - substream->stream, (long)pos, - (long)new_hw_ptr, (long)old_hw_ptr); + hw_ptr_error(substream, in_interrupt, "Unexpected hw_ptr", + "(stream=%i, pos=%ld, new_hw_ptr=%ld, old_hw_ptr=%ld)\n", + substream->stream, (long)pos, + (long)new_hw_ptr, (long)old_hw_ptr); return 0; } @@ -474,11 +381,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, delta--; } /* align hw_base to buffer_size */ - hw_ptr_error(substream, - "hw_ptr skipping! %s" - "(pos=%ld, delta=%ld, period=%ld, " - "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", - in_interrupt ? "[Q] " : "", + hw_ptr_error(substream, in_interrupt, "hw_ptr skipping", + "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n", (long)pos, (long)hdelta, (long)runtime->period_size, jdelta, ((hdelta * HZ) / runtime->rate), hw_base, @@ -490,11 +394,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, } no_jiffies_check: if (delta > runtime->period_size + runtime->period_size / 2) { - hw_ptr_error(substream, - "Lost interrupts? %s" - "(stream=%i, delta=%ld, new_hw_ptr=%ld, " - "old_hw_ptr=%ld)\n", - in_interrupt ? "[Q] " : "", + hw_ptr_error(substream, in_interrupt, + "Lost interrupts?", + "(stream=%i, delta=%ld, new_hw_ptr=%ld, old_hw_ptr=%ld)\n", substream->stream, (long)delta, (long)new_hw_ptr, (long)old_hw_ptr); diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h new file mode 100644 index 000000000000..b63b654da5ff --- /dev/null +++ b/sound/core/pcm_trace.h @@ -0,0 +1,110 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM snd_pcm +#define TRACE_INCLUDE_FILE pcm_trace + +#if !defined(_PCM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _PCM_TRACE_H + +#include + +TRACE_EVENT(hwptr, + TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_uframes_t pos, bool irq), + TP_ARGS(substream, pos, irq), + TP_STRUCT__entry( + __field( bool, in_interrupt ) + __field( unsigned int, card ) + __field( unsigned int, device ) + __field( unsigned int, number ) + __field( unsigned int, stream ) + __field( snd_pcm_uframes_t, pos ) + __field( snd_pcm_uframes_t, period_size ) + __field( snd_pcm_uframes_t, buffer_size ) + __field( snd_pcm_uframes_t, old_hw_ptr ) + __field( snd_pcm_uframes_t, hw_ptr_base ) + ), + TP_fast_assign( + __entry->in_interrupt = (irq); + __entry->card = (substream)->pcm->card->number; + __entry->device = (substream)->pcm->device; + __entry->number = (substream)->number; + __entry->stream = (substream)->stream; + __entry->pos = (pos); + __entry->period_size = (substream)->runtime->period_size; + __entry->buffer_size = (substream)->runtime->buffer_size; + __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; + __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; + ), + TP_printk("pcmC%dD%d%c/sub%d: %s: pos=%lu, old=%lu, base=%lu, period=%lu, buf=%lu", + __entry->card, __entry->device, + __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', + __entry->number, + __entry->in_interrupt ? "IRQ" : "POS", + (unsigned long)__entry->pos, + (unsigned long)__entry->old_hw_ptr, + (unsigned long)__entry->hw_ptr_base, + (unsigned long)__entry->period_size, + (unsigned long)__entry->buffer_size) +); + +TRACE_EVENT(xrun, + TP_PROTO(struct snd_pcm_substream *substream), + TP_ARGS(substream), + TP_STRUCT__entry( + __field( unsigned int, card ) + __field( unsigned int, device ) + __field( unsigned int, number ) + __field( unsigned int, stream ) + __field( snd_pcm_uframes_t, period_size ) + __field( snd_pcm_uframes_t, buffer_size ) + __field( snd_pcm_uframes_t, old_hw_ptr ) + __field( snd_pcm_uframes_t, hw_ptr_base ) + ), + TP_fast_assign( + __entry->card = (substream)->pcm->card->number; + __entry->device = (substream)->pcm->device; + __entry->number = (substream)->number; + __entry->stream = (substream)->stream; + __entry->period_size = (substream)->runtime->period_size; + __entry->buffer_size = (substream)->runtime->buffer_size; + __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; + __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; + ), + TP_printk("pcmC%dD%d%c/sub%d: XRUN: old=%lu, base=%lu, period=%lu, buf=%lu", + __entry->card, __entry->device, + __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', + __entry->number, + (unsigned long)__entry->old_hw_ptr, + (unsigned long)__entry->hw_ptr_base, + (unsigned long)__entry->period_size, + (unsigned long)__entry->buffer_size) +); + +TRACE_EVENT(hw_ptr_error, + TP_PROTO(struct snd_pcm_substream *substream, const char *why), + TP_ARGS(substream, why), + TP_STRUCT__entry( + __field( unsigned int, card ) + __field( unsigned int, device ) + __field( unsigned int, number ) + __field( unsigned int, stream ) + __field( const char *, reason ) + ), + TP_fast_assign( + __entry->card = (substream)->pcm->card->number; + __entry->device = (substream)->pcm->device; + __entry->number = (substream)->number; + __entry->stream = (substream)->stream; + __entry->reason = (why); + ), + TP_printk("pcmC%dD%d%c/sub%d: ERROR: %s", + __entry->card, __entry->device, + __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', + __entry->number, __entry->reason) +); + +#endif /* _PCM_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#include -- GitLab From 2b30d411dbc6eddfb5b4f9afd5a2c57b6f4dd96c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 4 Nov 2014 14:02:40 +0100 Subject: [PATCH 2916/9457] ALSA: pcm: Add xrun_injection proc entry This patch adds a new proc entry for PCM substreams to inject an XRUN. When a PCM substream is running and any value is written to its xrun_injection proc file, the driver triggers XRUN. This is a useful feature for debugging XRUN and error handling code paths. Note that this entry is enabled only when CONFIG_SND_PCM_XRUN_DEBUG is set. Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/Procfile.txt | 4 ++++ include/sound/pcm.h | 3 +++ sound/core/pcm.c | 33 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt index cfc49567b9dc..7f8a0d325905 100644 --- a/Documentation/sound/alsa/Procfile.txt +++ b/Documentation/sound/alsa/Procfile.txt @@ -133,6 +133,10 @@ card*/pcm*/sub*/sw_params card*/pcm*/sub*/prealloc The buffer pre-allocation information. +card*/pcm*/sub*/xrun_injection + Triggers an XRUN to the running stream when any value is + written to this proc file. Used for fault injection. + This entry is write-only. AC97 Codec Information ---------------------- diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 29eb09ef2969..0b8daeed0a33 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -416,7 +416,10 @@ struct snd_pcm_substream { struct snd_info_entry *proc_status_entry; struct snd_info_entry *proc_prealloc_entry; struct snd_info_entry *proc_prealloc_max_entry; +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + struct snd_info_entry *proc_xrun_injection_entry; #endif +#endif /* CONFIG_SND_VERBOSE_PROCFS */ /* misc flags */ unsigned int hw_opened: 1; }; diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 31acc3df62cd..8f624b7af0ca 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -483,6 +483,19 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, } #ifdef CONFIG_SND_PCM_XRUN_DEBUG +static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_pcm_substream *substream = entry->private_data; + struct snd_pcm_runtime *runtime; + + snd_pcm_stream_lock_irq(substream); + runtime = substream->runtime; + if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING) + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); + snd_pcm_stream_unlock_irq(substream); +} + static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { @@ -614,6 +627,22 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } substream->proc_status_entry = entry; +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + entry = snd_info_create_card_entry(card, "xrun_injection", + substream->proc_root); + if (entry) { + entry->private_data = substream; + entry->c.text.read = NULL; + entry->c.text.write = snd_pcm_xrun_injection_write; + entry->mode = S_IFREG | S_IWUSR; + if (snd_info_register(entry) < 0) { + snd_info_free_entry(entry); + entry = NULL; + } + } + substream->proc_xrun_injection_entry = entry; +#endif /* CONFIG_SND_PCM_XRUN_DEBUG */ + return 0; } @@ -627,6 +656,10 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) substream->proc_sw_params_entry = NULL; snd_info_free_entry(substream->proc_status_entry); substream->proc_status_entry = NULL; +#ifdef CONFIG_SND_PCM_XRUN_DEBUG + snd_info_free_entry(substream->proc_xrun_injection_entry); + substream->proc_xrun_injection_entry = NULL; +#endif snd_info_free_entry(substream->proc_root); substream->proc_root = NULL; return 0; -- GitLab From e7a00e4210e4cc980e3ba67ec7301af54061d14b Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sun, 6 Apr 2014 12:52:11 +0200 Subject: [PATCH 2917/9457] of: introduce of_property_read_s32 Introduce signed 32bit integer of_property_read method. Signed-off-by: Sebastian Reichel Signed-off-by: Grant Likely --- include/linux/of.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/of.h b/include/linux/of.h index 29f0adc5f3e4..30912939a610 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -760,6 +760,13 @@ static inline int of_property_read_u32(const struct device_node *np, return of_property_read_u32_array(np, propname, out_value, 1); } +static inline int of_property_read_s32(const struct device_node *np, + const char *propname, + s32 *out_value) +{ + return of_property_read_u32(np, propname, (u32*) out_value); +} + #define of_property_for_each_u32(np, propname, prop, p, u) \ for (prop = of_find_property(np, propname, NULL), \ p = of_prop_next_u32(prop, NULL, &u); \ -- GitLab From 5063e25a302e6a83f6590d9a06bd5f6400b17430 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 3 Oct 2014 16:28:27 +0100 Subject: [PATCH 2918/9457] of: Eliminate of_allnodes list The device tree structure is composed of two lists; the 'allnodes' list which is a singly linked list containing every node in the tree, and the child->parent structure where each parent node has a singly linked list of children. All of the data in the allnodes list can be easily reproduced with the parent-child lists, so of_allnodes is actually unnecessary. Remove it entirely which saves a bit of memory and simplifies the data structure quite a lot. Signed-off-by: Grant Likely Cc: Rob Herring Cc: Gaurav Minocha Cc: Pantelis Antoniou --- Documentation/devicetree/of_selftest.txt | 20 +------ Documentation/devicetree/todo.txt | 1 - drivers/mfd/vexpress-sysreg.c | 2 +- drivers/of/base.c | 53 ++++++++++-------- drivers/of/dynamic.c | 13 ----- drivers/of/fdt.c | 30 +++++----- drivers/of/pdt.c | 27 +++------ drivers/of/selftest.c | 71 +++++++++++------------- include/linux/of.h | 11 ++-- include/linux/of_pdt.h | 3 +- 10 files changed, 98 insertions(+), 133 deletions(-) diff --git a/Documentation/devicetree/of_selftest.txt b/Documentation/devicetree/of_selftest.txt index 1e3d5c92b5e3..57a808b588bf 100644 --- a/Documentation/devicetree/of_selftest.txt +++ b/Documentation/devicetree/of_selftest.txt @@ -63,7 +63,6 @@ struct device_node { struct device_node *parent; struct device_node *child; struct device_node *sibling; - struct device_node *allnext; /* next in list of all nodes */ ... }; @@ -99,12 +98,6 @@ child11 -> sibling12 -> sibling13 -> sibling14 -> null Figure 1: Generic structure of un-flattened device tree -*allnext: it is used to link all the nodes of DT into a list. So, for the - above tree the list would be as follows: - -root->child1->child11->sibling12->sibling13->child131->sibling14->sibling2-> -child21->sibling22->sibling23->sibling3->child31->sibling32->sibling4->null - Before executing OF selftest, it is required to attach the test data to machine's device tree (if present). So, when selftest_data_add() is called, at first it reads the flattened device tree data linked into the kernel image @@ -131,11 +124,6 @@ root ('/') test-child01 null null null -allnext list: - -root->testcase-data->test-child0->test-child01->test-sibling1->test-sibling2 -->test-sibling3->null - Figure 2: Example test data tree to be attached to live tree. According to the scenario above, the live tree is already present so it isn't @@ -204,8 +192,6 @@ detached and then moving up the parent nodes are removed, and eventually the whole tree). selftest_data_remove() calls detach_node_and_children() that uses of_detach_node() to detach the nodes from the live device tree. -To detach a node, of_detach_node() first updates all_next linked list, by -attaching the previous node's allnext to current node's allnext pointer. And -then, it either updates the child pointer of given node's parent to its -sibling or attaches the previous sibling to the given node's sibling, as -appropriate. That is it :) +To detach a node, of_detach_node() either updates the child pointer of given +node's parent to its sibling or attaches the previous sibling to the given +node's sibling, as appropriate. That is it :) diff --git a/Documentation/devicetree/todo.txt b/Documentation/devicetree/todo.txt index c3cf0659bd19..b5139d1de811 100644 --- a/Documentation/devicetree/todo.txt +++ b/Documentation/devicetree/todo.txt @@ -2,7 +2,6 @@ Todo list for devicetree: === General structure === - Switch from custom lists to (h)list_head for nodes and properties structure -- Remove of_allnodes list and iterate using list of child nodes alone === CONFIG_OF_DYNAMIC === - Switch to RCU for tree updates and get rid of global spinlock diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 9e21e4fc9599..8f43ab8fd2d6 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c @@ -223,7 +223,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) vexpress_config_set_master(vexpress_sysreg_get_master()); /* Confirm board type against DT property, if available */ - if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) { + if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) { u32 id = vexpress_get_procid(VEXPRESS_SITE_MASTER); u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; diff --git a/drivers/of/base.c b/drivers/of/base.c index 3823edf2d012..1f61a908a767 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -32,8 +32,8 @@ LIST_HEAD(aliases_lookup); -struct device_node *of_allnodes; -EXPORT_SYMBOL(of_allnodes); +struct device_node *of_root; +EXPORT_SYMBOL(of_root); struct device_node *of_chosen; struct device_node *of_aliases; struct device_node *of_stdout; @@ -48,7 +48,7 @@ struct kset *of_kset; */ DEFINE_MUTEX(of_mutex); -/* use when traversing tree through the allnext, child, sibling, +/* use when traversing tree through the child, sibling, * or parent members of struct device_node. */ DEFINE_RAW_SPINLOCK(devtree_lock); @@ -204,7 +204,7 @@ static int __init of_init(void) mutex_unlock(&of_mutex); /* Symlink in /proc as required by userspace ABI */ - if (of_allnodes) + if (of_root) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); return 0; @@ -245,6 +245,23 @@ struct property *of_find_property(const struct device_node *np, } EXPORT_SYMBOL(of_find_property); +struct device_node *__of_find_all_nodes(struct device_node *prev) +{ + struct device_node *np; + if (!prev) { + np = of_root; + } else if (prev->child) { + np = prev->child; + } else { + /* Walk back up looking for a sibling, or the end of the structure */ + np = prev; + while (np->parent && !np->sibling) + np = np->parent; + np = np->sibling; /* Might be null at the end of the tree */ + } + return np; +} + /** * of_find_all_nodes - Get next node in global list * @prev: Previous node or NULL to start iteration @@ -259,10 +276,8 @@ struct device_node *of_find_all_nodes(struct device_node *prev) unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - np = prev ? prev->allnext : of_allnodes; - for (; np != NULL; np = np->allnext) - if (of_node_get(np)) - break; + np = __of_find_all_nodes(prev); + of_node_get(np); of_node_put(prev); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; @@ -736,7 +751,7 @@ struct device_node *of_find_node_by_path(const char *path) unsigned long flags; if (strcmp(path, "/") == 0) - return of_node_get(of_allnodes); + return of_node_get(of_root); /* The path could begin with an alias */ if (*path != '/') { @@ -761,7 +776,7 @@ struct device_node *of_find_node_by_path(const char *path) /* Step down the tree matching path components */ raw_spin_lock_irqsave(&devtree_lock, flags); if (!np) - np = of_node_get(of_allnodes); + np = of_node_get(of_root); while (np && *path == '/') { path++; /* Increment past '/' delimiter */ np = __of_find_node_by_path(np, path); @@ -790,8 +805,7 @@ struct device_node *of_find_node_by_name(struct device_node *from, unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - np = from ? from->allnext : of_allnodes; - for (; np; np = np->allnext) + for_each_of_allnodes_from(from, np) if (np->name && (of_node_cmp(np->name, name) == 0) && of_node_get(np)) break; @@ -820,8 +834,7 @@ struct device_node *of_find_node_by_type(struct device_node *from, unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - np = from ? from->allnext : of_allnodes; - for (; np; np = np->allnext) + for_each_of_allnodes_from(from, np) if (np->type && (of_node_cmp(np->type, type) == 0) && of_node_get(np)) break; @@ -852,12 +865,10 @@ struct device_node *of_find_compatible_node(struct device_node *from, unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - np = from ? from->allnext : of_allnodes; - for (; np; np = np->allnext) { + for_each_of_allnodes_from(from, np) if (__of_device_is_compatible(np, compatible, type, NULL) && of_node_get(np)) break; - } of_node_put(from); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; @@ -884,8 +895,7 @@ struct device_node *of_find_node_with_property(struct device_node *from, unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); - np = from ? from->allnext : of_allnodes; - for (; np; np = np->allnext) { + for_each_of_allnodes_from(from, np) { for (pp = np->properties; pp; pp = pp->next) { if (of_prop_cmp(pp->name, prop_name) == 0) { of_node_get(np); @@ -967,8 +977,7 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from, *match = NULL; raw_spin_lock_irqsave(&devtree_lock, flags); - np = from ? from->allnext : of_allnodes; - for (; np; np = np->allnext) { + for_each_of_allnodes_from(from, np) { m = __of_match_node(matches, np); if (m && of_node_get(np)) { if (match) @@ -1025,7 +1034,7 @@ struct device_node *of_find_node_by_phandle(phandle handle) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); - for (np = of_allnodes; np; np = np->allnext) + for_each_of_allnodes(np) if (np->phandle == handle) break; of_node_get(np); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index f297891d8529..da2509d639c8 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -117,8 +117,6 @@ void __of_attach_node(struct device_node *np) np->child = NULL; np->sibling = np->parent->child; - np->allnext = np->parent->allnext; - np->parent->allnext = np; np->parent->child = np; of_node_clear_flag(np, OF_DETACHED); } @@ -154,17 +152,6 @@ void __of_detach_node(struct device_node *np) if (WARN_ON(!parent)) return; - if (of_allnodes == np) - of_allnodes = np->allnext; - else { - struct device_node *prev; - for (prev = of_allnodes; - prev->allnext != np; - prev = prev->allnext) - ; - prev->allnext = np->allnext; - } - if (parent->child == np) parent->child = np->sibling; else { diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index d1ffca8b34ea..1d30b9f96466 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -145,15 +145,15 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size, * @mem: Memory chunk to use for allocating device nodes and properties * @p: pointer to node in flat tree * @dad: Parent struct device_node - * @allnextpp: pointer to ->allnext from last allocated device_node * @fpsize: Size of the node path up at the current depth. */ static void * unflatten_dt_node(void *blob, void *mem, int *poffset, struct device_node *dad, - struct device_node ***allnextpp, - unsigned long fpsize) + struct device_node **nodepp, + unsigned long fpsize, + bool dryrun) { const __be32 *p; struct device_node *np; @@ -200,7 +200,7 @@ static void * unflatten_dt_node(void *blob, np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, __alignof__(struct device_node)); - if (allnextpp) { + if (!dryrun) { char *fn; of_node_init(np); np->full_name = fn = ((char *)np) + sizeof(*np); @@ -222,8 +222,6 @@ static void * unflatten_dt_node(void *blob, memcpy(fn, pathp, l); prev_pp = &np->properties; - **allnextpp = np; - *allnextpp = &np->allnext; if (dad != NULL) { np->parent = dad; /* we temporarily use the next field as `last_child'*/ @@ -254,7 +252,7 @@ static void * unflatten_dt_node(void *blob, has_name = 1; pp = unflatten_dt_alloc(&mem, sizeof(struct property), __alignof__(struct property)); - if (allnextpp) { + if (!dryrun) { /* We accept flattened tree phandles either in * ePAPR-style "phandle" properties, or the * legacy "linux,phandle" properties. If both @@ -296,7 +294,7 @@ static void * unflatten_dt_node(void *blob, sz = (pa - ps) + 1; pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, __alignof__(struct property)); - if (allnextpp) { + if (!dryrun) { pp->name = "name"; pp->length = sz; pp->value = pp + 1; @@ -308,7 +306,7 @@ static void * unflatten_dt_node(void *blob, (char *)pp->value); } } - if (allnextpp) { + if (!dryrun) { *prev_pp = NULL; np->name = of_get_property(np, "name", NULL); np->type = of_get_property(np, "device_type", NULL); @@ -324,11 +322,13 @@ static void * unflatten_dt_node(void *blob, if (depth < 0) depth = 0; while (*poffset > 0 && depth > old_depth) - mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp, - fpsize); + mem = unflatten_dt_node(blob, mem, poffset, np, NULL, + fpsize, dryrun); if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) pr_err("unflatten: error %d processing FDT\n", *poffset); + if (nodepp) + *nodepp = np; return mem; } @@ -352,7 +352,6 @@ static void __unflatten_device_tree(void *blob, unsigned long size; int start; void *mem; - struct device_node **allnextp = mynodes; pr_debug(" -> unflatten_device_tree()\n"); @@ -373,7 +372,7 @@ static void __unflatten_device_tree(void *blob, /* First pass, scan for size */ start = 0; - size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0); + size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0, true); size = ALIGN(size, 4); pr_debug(" size is %lx, allocating...\n", size); @@ -388,11 +387,10 @@ static void __unflatten_device_tree(void *blob, /* Second pass, do actual unflattening */ start = 0; - unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); + unflatten_dt_node(blob, mem, &start, NULL, mynodes, 0, false); if (be32_to_cpup(mem + size) != 0xdeadbeef) pr_warning("End of tree marker overwritten: %08x\n", be32_to_cpup(mem + size)); - *allnextp = NULL; pr_debug(" <- unflatten_device_tree()\n"); } @@ -1041,7 +1039,7 @@ bool __init early_init_dt_scan(void *params) */ void __init unflatten_device_tree(void) { - __unflatten_device_tree(initial_boot_params, &of_allnodes, + __unflatten_device_tree(initial_boot_params, &of_root, early_init_dt_alloc_memory_arch); /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 36b4035881b0..d2acae825af9 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -25,8 +25,7 @@ static struct of_pdt_ops *of_pdt_prom_ops __initdata; -void __initdata (*of_pdt_build_more)(struct device_node *dp, - struct device_node ***nextp); +void __initdata (*of_pdt_build_more)(struct device_node *dp); #if defined(CONFIG_SPARC) unsigned int of_pdt_unique_id __initdata; @@ -192,8 +191,7 @@ static struct device_node * __init of_pdt_create_node(phandle node, } static struct device_node * __init of_pdt_build_tree(struct device_node *parent, - phandle node, - struct device_node ***nextp) + phandle node) { struct device_node *ret = NULL, *prev_sibling = NULL; struct device_node *dp; @@ -210,16 +208,12 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, ret = dp; prev_sibling = dp; - *(*nextp) = dp; - *nextp = &dp->allnext; - dp->full_name = of_pdt_build_full_name(dp); - dp->child = of_pdt_build_tree(dp, - of_pdt_prom_ops->getchild(node), nextp); + dp->child = of_pdt_build_tree(dp, of_pdt_prom_ops->getchild(node)); if (of_pdt_build_more) - of_pdt_build_more(dp, nextp); + of_pdt_build_more(dp); node = of_pdt_prom_ops->getsibling(node); } @@ -234,20 +228,17 @@ static void * __init kernel_tree_alloc(u64 size, u64 align) void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) { - struct device_node **nextp; - BUG_ON(!ops); of_pdt_prom_ops = ops; - of_allnodes = of_pdt_create_node(root_node, NULL); + of_root = of_pdt_create_node(root_node, NULL); #if defined(CONFIG_SPARC) - of_allnodes->path_component_name = ""; + of_root->path_component_name = ""; #endif - of_allnodes->full_name = "/"; + of_root->full_name = "/"; - nextp = &of_allnodes->allnext; - of_allnodes->child = of_pdt_build_tree(of_allnodes, - of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp); + of_root->child = of_pdt_build_tree(of_root, + of_pdt_prom_ops->getchild(of_root->phandle)); /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ of_alias_scan(kernel_tree_alloc); diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 11b873c54a77..bf7d99317a94 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -148,7 +148,7 @@ static void __init of_selftest_dynamic(void) static int __init of_selftest_check_node_linkage(struct device_node *np) { - struct device_node *child, *allnext_index = np; + struct device_node *child; int count = 0, rc; for_each_child_of_node(np, child) { @@ -158,14 +158,6 @@ static int __init of_selftest_check_node_linkage(struct device_node *np) return -EINVAL; } - while (allnext_index && allnext_index != child) - allnext_index = allnext_index->allnext; - if (allnext_index != child) { - pr_err("Node %s is ordered differently in sibling and allnode lists\n", - child->name); - return -EINVAL; - } - rc = of_selftest_check_node_linkage(child); if (rc < 0) return rc; @@ -180,12 +172,12 @@ static void __init of_selftest_check_tree_linkage(void) struct device_node *np; int allnode_count = 0, child_count; - if (!of_allnodes) + if (!of_root) return; for_each_of_allnodes(np) allnode_count++; - child_count = of_selftest_check_node_linkage(of_allnodes); + child_count = of_selftest_check_node_linkage(of_root); selftest(child_count > 0, "Device node data structure is corrupted\n"); selftest(child_count == allnode_count, "allnodes list size (%i) doesn't match" @@ -775,33 +767,29 @@ static void update_node_properties(struct device_node *np, */ static int attach_node_and_children(struct device_node *np) { - struct device_node *next, *root = np, *dup; + struct device_node *next, *dup, *child; - /* skip root node */ - np = np->child; - /* storing a copy in temporary node */ - dup = np; + dup = of_find_node_by_path(np->full_name); + if (dup) { + update_node_properties(np, dup); + return 0; + } - while (dup) { + /* Children of the root need to be remembered for removal */ + if (np->parent == of_root) { if (WARN_ON(last_node_index >= NO_OF_NODES)) return -EINVAL; - nodes[last_node_index++] = dup; - dup = dup->sibling; + nodes[last_node_index++] = np; } - dup = NULL; - while (np) { - next = np->allnext; - dup = of_find_node_by_path(np->full_name); - if (dup) - update_node_properties(np, dup); - else { - np->child = NULL; - if (np->parent == root) - np->parent = of_allnodes; - of_attach_node(np); - } - np = next; + child = np->child; + np->child = NULL; + np->sibling = NULL; + of_attach_node(np); + while (child) { + next = child->sibling; + attach_node_and_children(child); + child = next; } return 0; @@ -846,10 +834,10 @@ static int __init selftest_data_add(void) return -EINVAL; } - if (!of_allnodes) { + if (!of_root) { /* enabling flag for removing nodes */ selftest_live_tree = true; - of_allnodes = selftest_data_node; + of_root = selftest_data_node; for_each_of_allnodes(np) __of_attach_node_sysfs(np); @@ -859,7 +847,14 @@ static int __init selftest_data_add(void) } /* attach the sub-tree to live tree */ - return attach_node_and_children(selftest_data_node); + np = selftest_data_node->child; + while (np) { + struct device_node *next = np->sibling; + np->parent = of_root; + attach_node_and_children(np); + np = next; + } + return 0; } /** @@ -889,10 +884,10 @@ static void selftest_data_remove(void) of_node_put(of_chosen); of_aliases = NULL; of_chosen = NULL; - for_each_child_of_node(of_allnodes, np) + for_each_child_of_node(of_root, np) detach_node_and_children(np); - __of_detach_node_sysfs(of_allnodes); - of_allnodes = NULL; + __of_detach_node_sysfs(of_root); + of_root = NULL; return; } diff --git a/include/linux/of.h b/include/linux/of.h index 30912939a610..f54da3b699a8 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -56,7 +56,6 @@ struct device_node { struct device_node *child; struct device_node *sibling; struct device_node *next; /* next device of same type */ - struct device_node *allnext; /* next in list of all nodes */ struct kobject kobj; unsigned long _flags; void *data; @@ -108,7 +107,7 @@ static inline void of_node_put(struct device_node *node) { } #ifdef CONFIG_OF /* Pointer for first entry in chain of all nodes. */ -extern struct device_node *of_allnodes; +extern struct device_node *of_root; extern struct device_node *of_chosen; extern struct device_node *of_aliases; extern struct device_node *of_stdout; @@ -116,7 +115,7 @@ extern raw_spinlock_t devtree_lock; static inline bool of_have_populated_dt(void) { - return of_allnodes != NULL; + return of_root != NULL; } static inline bool of_node_is_root(const struct device_node *node) @@ -160,6 +159,7 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag clear_bit(flag, &p->_flags); } +extern struct device_node *__of_find_all_nodes(struct device_node *prev); extern struct device_node *of_find_all_nodes(struct device_node *prev); /* @@ -215,8 +215,9 @@ static inline const char *of_node_full_name(const struct device_node *np) return np ? np->full_name : ""; } -#define for_each_of_allnodes(dn) \ - for (dn = of_allnodes; dn; dn = dn->allnext) +#define for_each_of_allnodes_from(from, dn) \ + for (dn = __of_find_all_nodes(from); dn; dn = __of_find_all_nodes(dn)) +#define for_each_of_allnodes(dn) for_each_of_allnodes_from(NULL, dn) extern struct device_node *of_find_node_by_name(struct device_node *from, const char *name); extern struct device_node *of_find_node_by_type(struct device_node *from, diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h index c65a18a0cfdf..7e09244bb679 100644 --- a/include/linux/of_pdt.h +++ b/include/linux/of_pdt.h @@ -39,7 +39,6 @@ extern void *prom_early_alloc(unsigned long size); /* for building the device tree */ extern void of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops); -extern void (*of_pdt_build_more)(struct device_node *dp, - struct device_node ***nextp); +extern void (*of_pdt_build_more)(struct device_node *dp); #endif /* _LINUX_OF_PDT_H */ -- GitLab From 263bc3fd6a8e50dc3ef423f36a1ec9cd951a76b8 Mon Sep 17 00:00:00 2001 From: Kiran Padwal Date: Thu, 30 Oct 2014 11:55:11 +0530 Subject: [PATCH 2919/9457] iommu/msm: Use dev_get_platdata() Use the wrapper function for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Kiran Padwal Signed-off-by: Joerg Roedel --- drivers/iommu/msm_iommu_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c index 9574d217227c..b6d01f97e537 100644 --- a/drivers/iommu/msm_iommu_dev.c +++ b/drivers/iommu/msm_iommu_dev.c @@ -131,7 +131,7 @@ static int msm_iommu_probe(struct platform_device *pdev) struct clk *iommu_clk; struct clk *iommu_pclk; struct msm_iommu_drvdata *drvdata; - struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; + struct msm_iommu_dev *iommu_dev = dev_get_platdata(&pdev->dev); void __iomem *regs_base; int ret, irq, par; @@ -263,7 +263,7 @@ static int msm_iommu_remove(struct platform_device *pdev) static int msm_iommu_ctx_probe(struct platform_device *pdev) { - struct msm_iommu_ctx_dev *c = pdev->dev.platform_data; + struct msm_iommu_ctx_dev *c = dev_get_platdata(&pdev->dev); struct msm_iommu_drvdata *drvdata; struct msm_iommu_ctx_drvdata *ctx_drvdata; int i, ret; -- GitLab From 99cb9aee770e482ac5ab1fe77213a38df9dd4e77 Mon Sep 17 00:00:00 2001 From: Kiran Padwal Date: Thu, 30 Oct 2014 11:59:47 +0530 Subject: [PATCH 2920/9457] iommu/omap: Use dev_get_platdata() Use the wrapper function for retrieving the platform data instead of accessing dev->platform_data directly. Signed-off-by: Kiran Padwal Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 2ba321921f81..839cd8bc9aaf 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -170,7 +170,7 @@ static int iommu_enable(struct omap_iommu *obj) { int err; struct platform_device *pdev = to_platform_device(obj->dev); - struct iommu_platform_data *pdata = pdev->dev.platform_data; + struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev); if (pdata && pdata->deassert_reset) { err = pdata->deassert_reset(pdev, pdata->reset_name); @@ -190,7 +190,7 @@ static int iommu_enable(struct omap_iommu *obj) static void iommu_disable(struct omap_iommu *obj) { struct platform_device *pdev = to_platform_device(obj->dev); - struct iommu_platform_data *pdata = pdev->dev.platform_data; + struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev); omap2_iommu_disable(obj); @@ -1007,7 +1007,7 @@ static int omap_iommu_probe(struct platform_device *pdev) int irq; struct omap_iommu *obj; struct resource *res; - struct iommu_platform_data *pdata = pdev->dev.platform_data; + struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *of = pdev->dev.of_node; obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL); -- GitLab From e222d6a4259c134553acab493b5ab9fc05d70132 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 1 Nov 2014 11:45:32 +0800 Subject: [PATCH 2921/9457] iommu/ipmmu-vmsa: Return proper error if devm_request_irq fails Signed-off-by: Axel Lin Acked-by: Laurent Pinchart Signed-off-by: Joerg Roedel --- drivers/iommu/ipmmu-vmsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 7dab5cbcc775..d25fa125e869 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1184,7 +1184,7 @@ static int ipmmu_probe(struct platform_device *pdev) dev_name(&pdev->dev), mmu); if (ret < 0) { dev_err(&pdev->dev, "failed to request IRQ %d\n", irq); - return irq; + return ret; } ipmmu_device_reset(mmu); -- GitLab From 4c8c3a4fcc021677c9a363b4e77f61dd09dbfd1a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2014 11:00:23 +0100 Subject: [PATCH 2922/9457] ALSA: usb-audio: Flatten probe and disconnect functions The usb-audio probe and disconnect functions have been split just for adapting the (new!) API at 2.5 kernel time. We left them until now, partly because we wanted to build with the pretty old kernels in the external alsa-driver tree. But the support of such old kernels has been longly stopped, so it's good time to clean up this mess. One good point by this cleanup is that now the probe function returns a proper error code instead of only -EIO. Signed-off-by: Takashi Iwai --- sound/usb/card.c | 75 +++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 7ecd0e8a5c51..be16bdc53c2a 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -112,7 +112,7 @@ static struct usb_driver usb_audio_driver; /* * disconnect streams - * called from snd_usb_audio_disconnect() + * called from usb_audio_disconnect() */ static void snd_usb_stream_disconnect(struct list_head *head) { @@ -475,14 +475,14 @@ static int snd_usb_audio_create(struct usb_interface *intf, * only at the first time. the successive calls of this function will * append the pcm interface to the corresponding card. */ -static struct snd_usb_audio * -snd_usb_audio_probe(struct usb_device *dev, - struct usb_interface *intf, - const struct usb_device_id *usb_id) +static int usb_audio_probe(struct usb_interface *intf, + const struct usb_device_id *usb_id) { - const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info; - int i, err; + struct usb_device *dev = interface_to_usbdev(intf); + const struct snd_usb_audio_quirk *quirk = + (const struct snd_usb_audio_quirk *)usb_id->driver_info; struct snd_usb_audio *chip; + int i, err; struct usb_host_interface *alts; int ifnum; u32 id; @@ -492,10 +492,11 @@ snd_usb_audio_probe(struct usb_device *dev, id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) - goto __err_val; + return -ENXIO; - if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0) - goto __err_val; + err = snd_usb_apply_boot_quirk(dev, intf, quirk); + if (err < 0) + return err; /* * found a config. now register to ALSA @@ -508,6 +509,7 @@ snd_usb_audio_probe(struct usb_device *dev, if (usb_chip[i] && usb_chip[i]->dev == dev) { if (usb_chip[i]->shutdown) { dev_err(&dev->dev, "USB device is in the shutdown state, cannot create a card instance\n"); + err = -EIO; goto __error; } chip = usb_chip[i]; @@ -523,15 +525,16 @@ snd_usb_audio_probe(struct usb_device *dev, if (enable[i] && ! usb_chip[i] && (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { - if (snd_usb_audio_create(intf, dev, i, quirk, - &chip) < 0) { + err = snd_usb_audio_create(intf, dev, i, quirk, + &chip); + if (err < 0) goto __error; - } chip->pm_intf = intf; break; } if (!chip) { dev_err(&dev->dev, "no available usb audio device\n"); + err = -ENODEV; goto __error; } } @@ -548,28 +551,32 @@ snd_usb_audio_probe(struct usb_device *dev, err = 1; /* continue */ if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { /* need some special handlings */ - if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0) + err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk); + if (err < 0) goto __error; } if (err > 0) { /* create normal USB audio interfaces */ - if (snd_usb_create_streams(chip, ifnum) < 0 || - snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) { + err = snd_usb_create_streams(chip, ifnum); + if (err < 0) + goto __error; + err = snd_usb_create_mixer(chip, ifnum, ignore_ctl_error); + if (err < 0) goto __error; - } } /* we are allowed to call snd_card_register() many times */ - if (snd_card_register(chip->card) < 0) { + err = snd_card_register(chip->card); + if (err < 0) goto __error; - } usb_chip[chip->index] = chip; chip->num_interfaces++; chip->probing = 0; + usb_set_intfdata(intf, chip); mutex_unlock(®ister_mutex); - return chip; + return 0; __error: if (chip) { @@ -578,17 +585,16 @@ snd_usb_audio_probe(struct usb_device *dev, chip->probing = 0; } mutex_unlock(®ister_mutex); - __err_val: - return NULL; + return err; } /* * we need to take care of counter, since disconnection can be called also * many times as well as usb_audio_probe(). */ -static void snd_usb_audio_disconnect(struct usb_device *dev, - struct snd_usb_audio *chip) +static void usb_audio_disconnect(struct usb_interface *intf) { + struct snd_usb_audio *chip = usb_get_intfdata(intf); struct snd_card *card; struct list_head *p; @@ -630,27 +636,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, } } -/* - * new 2.5 USB kernel API - */ -static int usb_audio_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct snd_usb_audio *chip; - chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); - if (chip) { - usb_set_intfdata(intf, chip); - return 0; - } else - return -EIO; -} - -static void usb_audio_disconnect(struct usb_interface *intf) -{ - snd_usb_audio_disconnect(interface_to_usbdev(intf), - usb_get_intfdata(intf)); -} - #ifdef CONFIG_PM int snd_usb_autoresume(struct snd_usb_audio *chip) -- GitLab From a6cece9d81990e729c1f9da2a5bff2d29f7df649 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2014 11:24:32 +0100 Subject: [PATCH 2923/9457] ALSA: usb-audio: Pass direct struct pointer instead of list_head Some functions in mixer.c and endpoint.c receive list_head instead of the object itself. This is not obvious and rather error-prone. Let's pass the proper object directly instead. The functions in midi.c still receive list_head and this can't be changed since the object definition isn't exposed to the outside of midi.c, so left as is. Signed-off-by: Takashi Iwai --- sound/usb/card.c | 20 ++++++++++---------- sound/usb/endpoint.c | 7 ++----- sound/usb/endpoint.h | 2 +- sound/usb/mixer.c | 5 +---- sound/usb/mixer.h | 2 +- 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index be16bdc53c2a..fa6c0972aa23 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -114,13 +114,11 @@ static struct usb_driver usb_audio_driver; * disconnect streams * called from usb_audio_disconnect() */ -static void snd_usb_stream_disconnect(struct list_head *head) +static void snd_usb_stream_disconnect(struct snd_usb_stream *as) { int idx; - struct snd_usb_stream *as; struct snd_usb_substream *subs; - as = list_entry(head, struct snd_usb_stream, list); for (idx = 0; idx < 2; idx++) { subs = &as->substream[idx]; if (!subs->num_formats) @@ -307,10 +305,10 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) static int snd_usb_audio_free(struct snd_usb_audio *chip) { - struct list_head *p, *n; + struct snd_usb_endpoint *ep, *n; - list_for_each_safe(p, n, &chip->ep_list) - snd_usb_endpoint_free(p); + list_for_each_entry_safe(ep, n, &chip->ep_list, list) + snd_usb_endpoint_free(ep); mutex_destroy(&chip->mutex); kfree(chip); @@ -609,12 +607,14 @@ static void usb_audio_disconnect(struct usb_interface *intf) mutex_lock(®ister_mutex); chip->num_interfaces--; if (chip->num_interfaces <= 0) { + struct snd_usb_stream *as; struct snd_usb_endpoint *ep; + struct usb_mixer_interface *mixer; snd_card_disconnect(card); /* release the pcm resources */ - list_for_each(p, &chip->pcm_list) { - snd_usb_stream_disconnect(p); + list_for_each_entry(as, &chip->pcm_list, list) { + snd_usb_stream_disconnect(as); } /* release the endpoint resources */ list_for_each_entry(ep, &chip->ep_list, list) { @@ -625,8 +625,8 @@ static void usb_audio_disconnect(struct usb_interface *intf) snd_usbmidi_disconnect(p); } /* release mixer resources */ - list_for_each(p, &chip->mixer_list) { - snd_usb_mixer_disconnect(p); + list_for_each_entry(mixer, &chip->mixer_list, list) { + snd_usb_mixer_disconnect(mixer); } usb_chip[chip->index] = NULL; mutex_unlock(®ister_mutex); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 114e3e7ff511..167d0c1643e1 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1002,15 +1002,12 @@ void snd_usb_endpoint_release(struct snd_usb_endpoint *ep) /** * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint * - * @ep: the list header of the endpoint to free + * @ep: the endpoint to free * * This free all resources of the given ep. */ -void snd_usb_endpoint_free(struct list_head *head) +void snd_usb_endpoint_free(struct snd_usb_endpoint *ep) { - struct snd_usb_endpoint *ep; - - ep = list_entry(head, struct snd_usb_endpoint, list); kfree(ep); } diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index e61ee5c356a3..6428392d8f62 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -24,7 +24,7 @@ void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_release(struct snd_usb_endpoint *ep); -void snd_usb_endpoint_free(struct list_head *head); +void snd_usb_endpoint_free(struct snd_usb_endpoint *ep); int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 63a8adb1705e..e4aaa21baed2 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2483,11 +2483,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, return err; } -void snd_usb_mixer_disconnect(struct list_head *p) +void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) { - struct usb_mixer_interface *mixer; - - mixer = list_entry(p, struct usb_mixer_interface, list); usb_kill_urb(mixer->urb); usb_kill_urb(mixer->rc_urb); } diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 73b1f649447b..2c7b9c9c2aa6 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -57,7 +57,7 @@ struct usb_mixer_elem_info { int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, int ignore_error); -void snd_usb_mixer_disconnect(struct list_head *p); +void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); -- GitLab From ae366c2049b48b54e5250cb57438bbebd1dbe610 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2014 11:32:19 +0100 Subject: [PATCH 2924/9457] ALSA: usb-audio: Use strim() instead of open code Signed-off-by: Takashi Iwai --- sound/usb/card.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index fa6c0972aa23..69725d5fa2d6 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -321,16 +321,6 @@ static int snd_usb_audio_dev_free(struct snd_device *device) return snd_usb_audio_free(chip); } -static void remove_trailing_spaces(char *str) -{ - char *p; - - if (!*str) - return; - for (p = str + strlen(str) - 1; p >= str && isspace(*p); p--) - *p = 0; -} - /* * create a chip instance and set its names. */ @@ -414,7 +404,7 @@ static int snd_usb_audio_create(struct usb_interface *intf, USB_ID_PRODUCT(chip->usb_id)); } } - remove_trailing_spaces(card->shortname); + strim(card->shortname); /* retrieve the vendor and device strings as longname */ if (quirk && quirk->vendor_name && *quirk->vendor_name) { @@ -428,7 +418,7 @@ static int snd_usb_audio_create(struct usb_interface *intf, /* we don't really care if there isn't any vendor string */ } if (len > 0) { - remove_trailing_spaces(card->longname); + strim(card->longname); if (*card->longname) strlcat(card->longname, " ", sizeof(card->longname)); } -- GitLab From 7b8ef67a0b1edb37957a2aa71a5c0bbbcf2694e9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 4 Nov 2014 13:27:45 +0000 Subject: [PATCH 2925/9457] ASoC: Intel: Fix build with CONFIG_SLEEP enabled. Fix the following build error when CONFIG_SLEEP is enabled and CONFIG_RUNTIME is disabled. The BDW ADSP sleep PM functionality depends on the runtime pm calls for context save/restore. All error/warnings: >> ERROR: "snd_soc_suspend" undefined! >> ERROR: "snd_soc_resume" undefined! Reported-by: kbuild test robot Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-pcm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 093b9393ae46..e7a3b6af87ba 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -1003,7 +1003,6 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM #ifdef CONFIG_PM_RUNTIME static int hsw_pcm_runtime_idle(struct device *dev) @@ -1063,6 +1062,8 @@ static int hsw_pcm_runtime_resume(struct device *dev) #define hsw_pcm_runtime_resume NULL #endif +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_RUNTIME) + static void hsw_pcm_complete(struct device *dev) { struct hsw_priv_data *pdata = dev_get_drvdata(dev); @@ -1158,6 +1159,11 @@ static int hsw_pcm_prepare(struct device *dev) return 0; } +#else +#define hsw_pcm_prepare NULL +#define hsw_pcm_complete NULL +#endif + static const struct dev_pm_ops hsw_pcm_pm = { .runtime_idle = hsw_pcm_runtime_idle, .runtime_suspend = hsw_pcm_runtime_suspend, @@ -1165,9 +1171,6 @@ static const struct dev_pm_ops hsw_pcm_pm = { .prepare = hsw_pcm_prepare, .complete = hsw_pcm_complete, }; -#else -#define hsw_pcm_pm NULL -#endif static struct platform_driver hsw_pcm_driver = { .driver = { -- GitLab From b8ab956c544e51a8d19ea3f38b54355d6aa92c33 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 4 Nov 2014 12:52:41 +0100 Subject: [PATCH 2926/9457] block: Expand a bit documentation about elevator_allow_merge_fn Explain that two requests can be merged without elevator_allow_merge_fn() being called. Signed-off-by: Jan Kara Signed-off-by: Jens Axboe --- Documentation/block/biodoc.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index 2101e718670d..f1323c6b7ed2 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt @@ -946,7 +946,11 @@ elevator_allow_merge_fn called whenever the block layer determines request safely. The io scheduler may still want to stop a merge at this point if it results in some sort of conflict internally, - this hook allows it to do that. + this hook allows it to do that. Note however + that two *requests* can still be merged at later + time. Currently the io scheduler has no way to + prevent that. It can only learn about the fact + from elevator_merge_req_fn callback. elevator_dispatch_fn* fills the dispatch queue with ready requests. I/O schedulers are free to postpone requests by -- GitLab From 1ef4c850491e6598f81f578f62697f9c9c2facca Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Tue, 4 Nov 2014 16:14:58 +0100 Subject: [PATCH 2927/9457] cfg80211: fix nl80211 cmd id in nl80211_send_mpath() Netlink command for nl80211_send_mpath() should be NL80211_CMD_NEW_MPATH. Signed-off-by: Henning Rogge Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1a31736914e5..24549cbe0b54 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4453,7 +4453,7 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, void *hdr; struct nlattr *pinfoattr; - hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); + hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH); if (!hdr) return -1; -- GitLab From 01f7ae056916b4e75ccaa48b9daacb9806caf4aa Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 2 Nov 2014 10:13:11 +0800 Subject: [PATCH 2928/9457] arch: tile: kernel: signal.c: Use __copy_from/to_user() instead of __get/put_user() setup/restore_sigcontext() want to copy all related registers between user and kernel. So use block copy instead of each registers copy. Then can let code simple and clearer (which can avoid compiler's warning): The related warning (with allmodconfig under tile): CC arch/tile/kernel/signal.o In file included from include/linux/poll.h:11:0, from include/linux/ring_buffer.h:7, from include/linux/ftrace_event.h:5, from include/trace/syscall.h:6, from include/linux/syscalls.h:81, from arch/tile/kernel/signal.c:30: arch/tile/kernel/signal.c: In function 'setup_sigcontext': arch/tile/kernel/signal.c:116:31: warning: iteration 53u invokes undefined behavior [-Waggressive-loop-optimizations] err |= __put_user(regs->regs[i], &sc->gregs[i]); ^ ./arch/tile/include/asm/uaccess.h:236:26: note: in definition of macro '__put_user_asm' : "r" (ptr), "r" (x), "i" (-EFAULT)) ^ ./arch/tile/include/asm/uaccess.h:297:10: note: in expansion of macro '__put_user_8' case 8: __put_user_8(x, ptr, __ret); break; \ ^ arch/tile/kernel/signal.c:116:10: note: in expansion of macro '__put_user' err |= __put_user(regs->regs[i], &sc->gregs[i]); ^ arch/tile/kernel/signal.c:115:2: note: containing loop for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) ^ Signed-off-by: Chen Gang Signed-off-by: Chris Metcalf --- arch/tile/kernel/signal.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 7c2fecc52177..491669065ffb 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -45,8 +45,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { - int err = 0; - int i; + int err; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; @@ -57,9 +56,7 @@ int restore_sigcontext(struct pt_regs *regs, */ BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); - - for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __get_user(regs->regs[i], &sc->gregs[i]); + err = __copy_from_user(regs, sc, sizeof(*regs)); /* Ensure that the PL is always set to USER_PL. */ regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); @@ -110,12 +107,7 @@ SYSCALL_DEFINE0(rt_sigreturn) int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) { - int i, err = 0; - - for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __put_user(regs->regs[i], &sc->gregs[i]); - - return err; + return __copy_to_user(sc, regs, sizeof(*regs)); } /* -- GitLab From 11175886daa6b31dfc713b6664215405de9ea1c7 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 3 Nov 2014 18:16:56 +0100 Subject: [PATCH 2929/9457] iommu/rockchip: Allow to compile with COMPILE_TEST Add optional CONFIG_COMPILE_TEST to dependency list. Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d0a1261eb1ba..f6f259af653c 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -154,7 +154,8 @@ config OMAP_IOMMU_DEBUG config ROCKCHIP_IOMMU bool "Rockchip IOMMU Support" - depends on ARCH_ROCKCHIP + depends on ARM + depends on ARCH_ROCKCHIP || COMPILE_TEST select IOMMU_API select ARM_DMA_USE_IOMMU help -- GitLab From 980edbd503dc0823c75e138edc53a48f99e1e3f6 Mon Sep 17 00:00:00 2001 From: Simon Vincent Date: Tue, 4 Nov 2014 15:29:51 +0000 Subject: [PATCH 2930/9457] 6lowpan: fix udp header compression when using raw sockets If you use RAW sockets the transport header offset is not set by the ipv6 stack so when we get to the udp header compression it does not compress the right part of the packet. This patch adds a check for this scenario and sets the transport header offset. Signed-off-by: Simon Vincent Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/6lowpan/iphc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 73a7065f0c6b..cd5f8b8e34cd 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -512,9 +512,17 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift, static void compress_udp_header(u8 **hc_ptr, struct sk_buff *skb) { - struct udphdr *uh = udp_hdr(skb); + struct udphdr *uh; u8 tmp; + /* In the case of RAW sockets the transport header is not set by + * the ip6 stack so we must set it ourselves + */ + if (skb->transport_header == skb->network_header) + skb_set_transport_header(skb, sizeof(struct ipv6hdr)); + + uh = udp_hdr(skb); + if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) == LOWPAN_NHC_UDP_4BIT_PORT) && ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) == -- GitLab From 851da976dc1d72becc03e144b38c4efab9e7b361 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 4 Nov 2014 13:14:13 +0000 Subject: [PATCH 2931/9457] of/unittest: Remove test devices after adding them The of_platform_populate() test cases don't remove the test devices after they are added. Fix this by adding tests for of_platform_depopulate(). At the same time rework the selftest() macro to return the test result value. This makes it easy to use the macro inside an if() condition. Signed-off-by: Grant Likely --- drivers/of/selftest.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index bf7d99317a94..082bb2b6a5ad 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -30,15 +30,17 @@ static struct device_node *nodes[NO_OF_NODES]; static int last_node_index; static bool selftest_live_tree; -#define selftest(result, fmt, ...) { \ - if (!(result)) { \ +#define selftest(result, fmt, ...) ({ \ + bool failed = !(result); \ + if (failed) { \ selftest_results.failed++; \ pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ } else { \ selftest_results.passed++; \ pr_debug("pass %s():%i\n", __func__, __LINE__); \ } \ -} + failed; \ +}) static void __init of_selftest_find_node_by_name(void) { @@ -694,10 +696,13 @@ static void __init of_selftest_match_node(void) } } +struct device test_bus = { + .init_name = "unittest-bus", +}; static void __init of_selftest_platform_populate(void) { - int irq; - struct device_node *np, *child; + int irq, rc; + struct device_node *np, *child, *grandchild; struct platform_device *pdev; struct of_device_id match[] = { { .compatible = "test-device", }, @@ -722,20 +727,32 @@ static void __init of_selftest_platform_populate(void) irq = platform_get_irq(pdev, 0); selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq); - np = of_find_node_by_path("/testcase-data/platform-tests"); - if (!np) { - pr_err("No testcase data in device tree\n"); + if (selftest(np = of_find_node_by_path("/testcase-data/platform-tests"), + "No testcase data in device tree\n")); + return; + + if (selftest(!(rc = device_register(&test_bus)), + "testbus registration failed; rc=%i\n", rc)); return; - } for_each_child_of_node(np, child) { - struct device_node *grandchild; - of_platform_populate(child, match, NULL, NULL); + of_platform_populate(child, match, NULL, &test_bus); for_each_child_of_node(child, grandchild) selftest(of_find_device_by_node(grandchild), "Could not create device for node '%s'\n", grandchild->name); } + + of_platform_depopulate(&test_bus); + for_each_child_of_node(np, child) { + for_each_child_of_node(child, grandchild) + selftest(!of_find_device_by_node(grandchild), + "device didn't get destroyed '%s'\n", + grandchild->name); + } + + device_unregister(&test_bus); + of_node_put(np); } /** -- GitLab From 19fd74879a32fb10357e0cda9c8050f01bb3eeb8 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 4 Nov 2014 13:24:45 +0000 Subject: [PATCH 2932/9457] of/unittest: Rename selftest.c to unittest.c This is unit testing code. It should use that name because it makes more sense than 'selftest'. Rename the files to match and rename the config variable. Signed-off-by: Grant Likely --- drivers/of/Kconfig | 4 ++-- drivers/of/Makefile | 4 ++-- drivers/of/{testcase-data => unittest-data}/testcases.dts | 0 .../of/{testcase-data => unittest-data}/tests-interrupts.dtsi | 0 drivers/of/{testcase-data => unittest-data}/tests-match.dtsi | 0 .../of/{testcase-data => unittest-data}/tests-phandle.dtsi | 0 .../of/{testcase-data => unittest-data}/tests-platform.dtsi | 0 drivers/of/{selftest.c => unittest.c} | 0 8 files changed, 4 insertions(+), 4 deletions(-) rename drivers/of/{testcase-data => unittest-data}/testcases.dts (100%) rename drivers/of/{testcase-data => unittest-data}/tests-interrupts.dtsi (100%) rename drivers/of/{testcase-data => unittest-data}/tests-match.dtsi (100%) rename drivers/of/{testcase-data => unittest-data}/tests-phandle.dtsi (100%) rename drivers/of/{testcase-data => unittest-data}/tests-platform.dtsi (100%) rename drivers/of/{selftest.c => unittest.c} (100%) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 1a13f5b722c5..be16ce2ffd69 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -7,8 +7,8 @@ config OF menu "Device Tree and Open Firmware support" depends on OF -config OF_SELFTEST - bool "Device Tree Runtime self tests" +config OF_UNITTEST + bool "Device Tree runtime unit tests" depends on OF_IRQ && OF_EARLY_FLATTREE select OF_DYNAMIC select OF_RESOLVE diff --git a/drivers/of/Makefile b/drivers/of/Makefile index ca9209ce50cd..d90553fcd37f 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -6,8 +6,8 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_NET) += of_net.o -obj-$(CONFIG_OF_SELFTEST) += of_selftest.o -of_selftest-objs := selftest.o testcase-data/testcases.dtb.o +obj-$(CONFIG_OF_UNITTEST) += of_unittest.o +of_unittest-objs := unittest.o unittest-data/testcases.dtb.o obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o diff --git a/drivers/of/testcase-data/testcases.dts b/drivers/of/unittest-data/testcases.dts similarity index 100% rename from drivers/of/testcase-data/testcases.dts rename to drivers/of/unittest-data/testcases.dts diff --git a/drivers/of/testcase-data/tests-interrupts.dtsi b/drivers/of/unittest-data/tests-interrupts.dtsi similarity index 100% rename from drivers/of/testcase-data/tests-interrupts.dtsi rename to drivers/of/unittest-data/tests-interrupts.dtsi diff --git a/drivers/of/testcase-data/tests-match.dtsi b/drivers/of/unittest-data/tests-match.dtsi similarity index 100% rename from drivers/of/testcase-data/tests-match.dtsi rename to drivers/of/unittest-data/tests-match.dtsi diff --git a/drivers/of/testcase-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi similarity index 100% rename from drivers/of/testcase-data/tests-phandle.dtsi rename to drivers/of/unittest-data/tests-phandle.dtsi diff --git a/drivers/of/testcase-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi similarity index 100% rename from drivers/of/testcase-data/tests-platform.dtsi rename to drivers/of/unittest-data/tests-platform.dtsi diff --git a/drivers/of/selftest.c b/drivers/of/unittest.c similarity index 100% rename from drivers/of/selftest.c rename to drivers/of/unittest.c -- GitLab From b75b276bead4850c86e60747babe09be5c13d4d1 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Tue, 21 Oct 2014 18:27:25 +0200 Subject: [PATCH 2933/9457] of: Request and map make argument name constant This patch makes the name argument from of_io_request_and_map constant. Signed-off-by: Matthias Brugger Signed-off-by: Grant Likely --- drivers/of/address.c | 2 +- include/linux/of_address.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index afdb78299f61..e02828fa3acd 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -871,7 +871,7 @@ EXPORT_SYMBOL(of_iomap); * return PTR_ERR(base); */ void __iomem *of_io_request_and_map(struct device_node *np, int index, - char *name) + const char *name) { struct resource res; void __iomem *mem; diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 8cb14eb393d6..d88e81be6368 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -106,7 +106,7 @@ extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); void __iomem *of_iomap(struct device_node *node, int index); void __iomem *of_io_request_and_map(struct device_node *device, - int index, char *name); + int index, const char *name); #else #include @@ -123,7 +123,7 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) } static inline void __iomem *of_io_request_and_map(struct device_node *device, - int index, char *name) + int index, const char *name) { return IOMEM_ERR_PTR(-EINVAL); } -- GitLab From 50ba08f301a1b0310775deeed00c9b24ba75fe8a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 29 Oct 2014 12:15:00 -0600 Subject: [PATCH 2934/9457] of/fdt: Don't clear initial_boot_params if fdt_check_header() fails If the device tree pointer is NULL, early_init_dt_verify() fails, leaving initial_boot_params unchanged. If the device tree pointer is non-NULL but invalid, early_init_dt_verify() again fails but this time it also clears initial_boot_params. Leave initial_boot_params unchanged if the device tree pointer is invalid. This doesn't fix a bug, but it makes the behavior more consistent and easier to analyze. Signed-off-by: Bjorn Helgaas Signed-off-by: Zhen Lei Signed-off-by: Grant Likely --- drivers/of/fdt.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 1d30b9f96466..535124670257 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -992,15 +992,12 @@ bool __init early_init_dt_verify(void *params) if (!params) return false; - /* Setup flat device-tree pointer */ - initial_boot_params = params; - /* check device tree validity */ - if (fdt_check_header(params)) { - initial_boot_params = NULL; + if (fdt_check_header(params)) return false; - } + /* Setup flat device-tree pointer */ + initial_boot_params = params; return true; } -- GitLab From 8cccffc52694938fc88f3d90bc7fed8460e27191 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 29 Oct 2014 17:09:32 +0100 Subject: [PATCH 2935/9457] of: check for size < 0 after rounding in early_init_dt_add_memory_arch Memory regions passed to early_init_dt_add_memory_arch() are rounded to PAGE_SIZE by subtracting the size of the leading fractional page from the 'size' argument. However, size being a u64 type, if its value is sufficiently small, the subtraction wraps around and produces a bogus value, potentially leading to crashes. Fix this by ignoring the memory range in such cases. Signed-off-by: Ard Biesheuvel Signed-off-by: Grant Likely --- drivers/of/fdt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 535124670257..83a8e1154602 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -928,6 +928,11 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) const u64 phys_offset = __pa(PAGE_OFFSET); if (!PAGE_ALIGNED(base)) { + if (size < PAGE_SIZE - (base & ~PAGE_MASK)) { + pr_warn("Ignoring memory block 0x%llx - 0x%llx\n", + base, base + size); + return; + } size -= PAGE_SIZE - (base & ~PAGE_MASK); base = PAGE_ALIGN(base); } -- GitLab From d94a75c13331cc00675b09d56f1a910bd53b7dd4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:44:52 +0200 Subject: [PATCH 2936/9457] of: Correct of_phandle_args node reference in comments The device_node pointer in struct of_phandle_args is called "np", not "node". Signed-off-by: Geert Uytterhoeven Signed-off-by: Grant Likely --- drivers/of/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 1f61a908a767..ea3c363ef085 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1525,7 +1525,7 @@ EXPORT_SYMBOL(of_parse_phandle); * Returns 0 on success and fills out_args, on error returns appropriate * errno value. * - * Caller is responsible to call of_node_put() on the returned out_args->node + * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * * Example: @@ -1568,7 +1568,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_args); * Returns 0 on success and fills out_args, on error returns appropriate * errno value. * - * Caller is responsible to call of_node_put() on the returned out_args->node + * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * * Example: -- GitLab From 1821dda4ae1f857f24094de88a5694e6fd9029e9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:44:53 +0200 Subject: [PATCH 2937/9457] of: Improve grammar for of_alias_scan() documentation Signed-off-by: Geert Uytterhoeven Signed-off-by: Grant Likely --- drivers/of/base.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index ea3c363ef085..3ab72f578344 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1814,14 +1814,14 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np, } /** - * of_alias_scan - Scan all properties of 'aliases' node + * of_alias_scan - Scan all properties of the 'aliases' node * - * The function scans all the properties of 'aliases' node and populate - * the the global lookup table with the properties. It returns the - * number of alias_prop found, or error code in error case. + * The function scans all the properties of the 'aliases' node and populates + * the global lookup table with the properties. It returns the + * number of alias properties found, or an error code in case of failure. * * @dt_alloc: An allocator that provides a virtual address to memory - * for the resulting tree + * for storing the resulting tree */ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) { -- GitLab From c50949d3298d30f24a8eca1f9d5053f4d2b0a96e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:44:54 +0200 Subject: [PATCH 2938/9457] of: Grammar s/an/a/ Signed-off-by: Geert Uytterhoeven Signed-off-by: Grant Likely --- drivers/of/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ab72f578344..8452e50f5755 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -933,7 +933,7 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches, } /** - * of_match_node - Tell if an device_node has a matching of_match structure + * of_match_node - Tell if a device_node has a matching of_match structure * @matches: array of of device match structures to search in * @node: the of device structure to match against * -- GitLab From c0e848d8b878c1868914de7193423cb715d49400 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Oct 2014 11:44:55 +0200 Subject: [PATCH 2939/9457] of: Remove spaces before tabs Signed-off-by: Geert Uytterhoeven Signed-off-by: Grant Likely --- drivers/of/base.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 8452e50f5755..6137f18d4244 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -592,9 +592,9 @@ EXPORT_SYMBOL(of_get_parent); * of_get_next_parent - Iterate to a node's parent * @node: Node to get parent of * - * This is like of_get_parent() except that it drops the - * refcount on the passed node, making it suitable for iterating - * through a node's parents. + * This is like of_get_parent() except that it drops the + * refcount on the passed node, making it suitable for iterating + * through a node's parents. * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. @@ -1531,15 +1531,15 @@ EXPORT_SYMBOL(of_parse_phandle); * Example: * * phandle1: node1 { - * #list-cells = <2>; + * #list-cells = <2>; * } * * phandle2: node2 { - * #list-cells = <1>; + * #list-cells = <1>; * } * * node3 { - * list = <&phandle1 1 2 &phandle2 3>; + * list = <&phandle1 1 2 &phandle2 3>; * } * * To get a device_node of the `node2' node you may call this: @@ -1580,7 +1580,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_args); * } * * node3 { - * list = <&phandle1 0 2 &phandle2 2 3>; + * list = <&phandle1 0 2 &phandle2 2 3>; * } * * To get a device_node of the `node2' node you may call this: -- GitLab From 5f563585ab0afa8c35b3627d65c07966f7a5080e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 2 Oct 2014 16:01:10 +0200 Subject: [PATCH 2940/9457] of: Fix padding in _OF_DECLARE macro definition Signed-off-by: Thierry Reding Signed-off-by: Grant Likely --- include/linux/of.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/of.h b/include/linux/of.h index f54da3b699a8..3c851a8f23eb 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -836,7 +836,7 @@ static inline int of_get_available_child_count(const struct device_node *np) = { .compatible = compat, \ .data = (fn == (fn_type)NULL) ? fn : fn } #else -#define _OF_DECLARE(table, name, compat, fn, fn_type) \ +#define _OF_DECLARE(table, name, compat, fn, fn_type) \ static const struct of_device_id __of_table_##name \ __attribute__((unused)) \ = { .compatible = compat, \ -- GitLab From 43c0767e17ac70e494b6a381b3a20be6a1a75c70 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 4 Nov 2014 10:26:26 +0000 Subject: [PATCH 2941/9457] of/platform: Move platform devices under /sys/devices/platform Currently the devices created by drivers/of/platform.c get created at the root of /sys/devices. This goes against the typical pattern for sysfs where the top level /sys/devices structure contains categories of devices, and the structure of devices is placed below that. To fix this, make the code in drivers/of/platform.c follow the drivers/base/platform.c behaviour, and use &platform_bus as the default parent for all new platform_devices and amba_devices. This change has been discussed for a long time, but nobody has actually acted on it. Userspace code that expects to find devices under a fixed /sys/devices/... path will be affected. It isn't /supposed/ to do that, but if anyone complains then I'll add a default-off workaround option to put them back into the root. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt Acked-by: Greg Kroah-Hartman Cc: Rob Herring Cc: Arnd Bergmann --- drivers/of/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 3b64d0bf5bba..7c6771986c06 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -138,7 +138,7 @@ struct platform_device *of_device_alloc(struct device_node *np, } dev->dev.of_node = of_node_get(np); - dev->dev.parent = parent; + dev->dev.parent = parent ? : &platform_bus; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); @@ -291,7 +291,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, /* setup generic device info */ dev->dev.of_node = of_node_get(node); - dev->dev.parent = parent; + dev->dev.parent = parent ? : &platform_bus; dev->dev.platform_data = platform_data; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); -- GitLab From 0d8a52f933f817d0b62955a5a362fb7f2508f06c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 4 Nov 2014 11:55:09 +0300 Subject: [PATCH 2942/9457] ieee802154: || vs && in ieee802154_is_valid_extended_addr() The ieee802154_is_valid_extended_addr() always returns true because there is a typo. The || should be &&. Neither 0x0000000000000000ULL nor 0xffffffffffffffffULL are valid addresses. Signed-off-by: Dan Carpenter Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 5d9e7459d94b..4c032863cd71 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -209,7 +209,7 @@ static inline bool ieee802154_is_valid_extended_addr(const __le64 addr) * This is currently a workaround because neighbor discovery can't * deal with short addresses types right now. */ - return ((addr != cpu_to_le64(0x0000000000000000ULL)) || + return ((addr != cpu_to_le64(0x0000000000000000ULL)) && (addr != cpu_to_le64(0xffffffffffffffffULL))); } -- GitLab From c5a589cc3034d035e8490216a45abd3a3b3cd85e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 30 Oct 2014 18:39:12 +0100 Subject: [PATCH 2943/9457] netfilter: nf_log: fix sparse warning in nf_logger_find_get() net/netfilter/nf_log.c:157:16: warning: incorrect type in assignment (different address spaces) net/netfilter/nf_log.c:157:16: expected struct nf_logger *logger net/netfilter/nf_log.c:157:16: got struct nf_logger [noderef] * Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_log.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 9562e393fdf7..49a64174f3f1 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -154,8 +154,7 @@ int nf_logger_find_get(int pf, enum nf_log_type type) struct nf_logger *logger; int ret = -ENOENT; - logger = loggers[pf][type]; - if (logger == NULL) + if (rcu_access_pointer(loggers[pf][type]) == NULL) request_module("nf-logger-%u-%u", pf, type); rcu_read_lock(); -- GitLab From 679315e5fae1e4614eed0d9aa26999ddcb6a0f77 Mon Sep 17 00:00:00 2001 From: Anton Staaf Date: Mon, 3 Nov 2014 08:43:20 -0800 Subject: [PATCH 2944/9457] USB: serial: add Google simple serial SubClass support Add support for Google devices that export simple serial interfaces using the vendor specific SubClass/Protocol pair 0x50/0x01. Signed-off-by: Anton Staaf Reviewed-by: Benson Leung [johan: move id entries and update Kconfig] Signed-off-by: Johan Hovold --- drivers/usb/serial/Kconfig | 1 + drivers/usb/serial/usb-serial-simple.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index d185613bbd7d..b7cf1982d1d9 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -60,6 +60,7 @@ config USB_SERIAL_SIMPLE - Suunto ANT+ USB device. - Medtronic CareLink USB device - Fundamental Software dongle. + - Google USB serial devices - HP4x calculators - a number of Motorola phones - Novatel Wireless GPS receivers diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index 7064eb8d6142..bc310112eae9 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -56,6 +56,14 @@ DEVICE(funsoft, FUNSOFT_IDS); { USB_DEVICE(0x8087, 0x0716) } DEVICE(flashloader, FLASHLOADER_IDS); +/* Google Serial USB SubClass */ +#define GOOGLE_IDS() \ + { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \ + USB_CLASS_VENDOR_SPEC, \ + 0x50, \ + 0x01) } +DEVICE(google, GOOGLE_IDS); + /* ViVOpay USB Serial Driver */ #define VIVOPAY_IDS() \ { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ @@ -97,6 +105,7 @@ static struct usb_serial_driver * const serial_drivers[] = { &zio_device, &funsoft_device, &flashloader_device, + &google_device, &vivopay_device, &moto_modem_device, &novatel_gps_device, @@ -111,6 +120,7 @@ static const struct usb_device_id id_table[] = { ZIO_IDS(), FUNSOFT_IDS(), FLASHLOADER_IDS(), + GOOGLE_IDS(), VIVOPAY_IDS(), MOTO_IDS(), NOVATEL_IDS(), -- GitLab From 9c6ac78eb3521c5937b2dd8a7d1b300f41092f45 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 24 Oct 2014 15:38:21 -0400 Subject: [PATCH 2945/9457] writeback: fix a subtle race condition in I_DIRTY clearing After invoking ->dirty_inode(), __mark_inode_dirty() does smp_mb() and tests inode->i_state locklessly to see whether it already has all the necessary I_DIRTY bits set. The comment above the barrier doesn't contain any useful information - memory barriers can't ensure "changes are seen by all cpus" by itself. And it sure enough was broken. Please consider the following scenario. CPU 0 CPU 1 ------------------------------------------------------------------------------- enters __writeback_single_inode() grabs inode->i_lock tests PAGECACHE_TAG_DIRTY which is clear enters __set_page_dirty() grabs mapping->tree_lock sets PAGECACHE_TAG_DIRTY releases mapping->tree_lock leaves __set_page_dirty() enters __mark_inode_dirty() smp_mb() sees I_DIRTY_PAGES set leaves __mark_inode_dirty() clears I_DIRTY_PAGES releases inode->i_lock Now @inode has dirty pages w/ I_DIRTY_PAGES clear. This doesn't seem to lead to an immediately critical problem because requeue_inode() later checks PAGECACHE_TAG_DIRTY instead of I_DIRTY_PAGES when deciding whether the inode needs to be requeued for IO and there are enough unintentional memory barriers inbetween, so while the inode ends up with inconsistent I_DIRTY_PAGES flag, it doesn't fall off the IO list. The lack of explicit barrier may also theoretically affect the other I_DIRTY bits which deal with metadata dirtiness. There is no guarantee that a strong enough barrier exists between I_DIRTY_[DATA]SYNC clearing and write_inode() writing out the dirtied inode. Filesystem inode writeout path likely has enough stuff which can behave as full barrier but it's theoretically possible that the writeout may not see all the updates from ->dirty_inode(). Fix it by adding an explicit smp_mb() after I_DIRTY clearing. Note that I_DIRTY_PAGES needs a special treatment as it always needs to be cleared to be interlocked with the lockless test on __mark_inode_dirty() side. It's cleared unconditionally and reinstated after smp_mb() if the mapping still has dirty pages. Also add comments explaining how and why the barriers are paired. Lightly tested. Signed-off-by: Tejun Heo Cc: Jan Kara Cc: Mikulas Patocka Cc: Jens Axboe Cc: Al Viro Cc: stable@vger.kernel.org Reviewed-by: Jan Kara Signed-off-by: Jens Axboe --- fs/fs-writeback.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ef9bef118342..2d609a5fbfea 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -479,12 +479,28 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) * write_inode() */ spin_lock(&inode->i_lock); - /* Clear I_DIRTY_PAGES if we've written out all dirty pages */ - if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) - inode->i_state &= ~I_DIRTY_PAGES; + dirty = inode->i_state & I_DIRTY; - inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC); + inode->i_state &= ~I_DIRTY; + + /* + * Paired with smp_mb() in __mark_inode_dirty(). This allows + * __mark_inode_dirty() to test i_state without grabbing i_lock - + * either they see the I_DIRTY bits cleared or we see the dirtied + * inode. + * + * I_DIRTY_PAGES is always cleared together above even if @mapping + * still has dirty pages. The flag is reinstated after smp_mb() if + * necessary. This guarantees that either __mark_inode_dirty() + * sees clear I_DIRTY_PAGES or we see PAGECACHE_TAG_DIRTY. + */ + smp_mb(); + + if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) + inode->i_state |= I_DIRTY_PAGES; + spin_unlock(&inode->i_lock); + /* Don't write the inode if only I_DIRTY_PAGES was set */ if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { int err = write_inode(inode, wbc); @@ -1148,12 +1164,11 @@ void __mark_inode_dirty(struct inode *inode, int flags) } /* - * make sure that changes are seen by all cpus before we test i_state - * -- mikulas + * Paired with smp_mb() in __writeback_single_inode() for the + * following lockless i_state test. See there for details. */ smp_mb(); - /* avoid the locking if we can */ if ((inode->i_state & flags) == flags) return; -- GitLab From d1d81802522ade84128a2c66c0d500e372474dca Mon Sep 17 00:00:00 2001 From: Torsten Fleischer Date: Mon, 3 Nov 2014 17:17:55 +0100 Subject: [PATCH 2946/9457] spi: spi-gpio: Add dt support for a single device with no chip select In order to describe a single slave device that has no chip select line the 'num-chipselects' property has to be <0> and the 'cs-gpios' property doesn't need to be set. Signed-off-by: Torsten Fleischer Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-gpio.txt | 6 ++++-- drivers/spi/spi-gpio.c | 21 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-gpio.txt b/Documentation/devicetree/bindings/spi/spi-gpio.txt index 8a824be15754..a95603bcf6ff 100644 --- a/Documentation/devicetree/bindings/spi/spi-gpio.txt +++ b/Documentation/devicetree/bindings/spi/spi-gpio.txt @@ -8,8 +8,10 @@ Required properties: - gpio-sck: GPIO spec for the SCK line to use - gpio-miso: GPIO spec for the MISO line to use - gpio-mosi: GPIO spec for the MOSI line to use - - cs-gpios: GPIOs to use for chipselect lines - - num-chipselects: number of chipselect lines + - cs-gpios: GPIOs to use for chipselect lines. + Not needed if num-chipselects = <0>. + - num-chipselects: Number of chipselect lines. Should be <0> if a single device + with no chip select is connected. Example: diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 9f595535cf27..f0492c99d145 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -413,6 +413,7 @@ static int spi_gpio_probe(struct platform_device *pdev) struct spi_gpio_platform_data *pdata; u16 master_flags = 0; bool use_of = 0; + int num_devices; status = spi_gpio_probe_dt(pdev); if (status < 0) @@ -422,16 +423,21 @@ static int spi_gpio_probe(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); #ifdef GENERIC_BITBANG - if (!pdata || !pdata->num_chipselect) + if (!pdata || (!use_of && !pdata->num_chipselect)) return -ENODEV; #endif + if (use_of && !SPI_N_CHIPSEL) + num_devices = 1; + else + num_devices = SPI_N_CHIPSEL; + status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); if (status < 0) return status; master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + - (sizeof(int) * SPI_N_CHIPSEL)); + (sizeof(int) * num_devices)); if (!master) { status = -ENOMEM; goto gpio_free; @@ -446,7 +452,7 @@ static int spi_gpio_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->flags = master_flags; master->bus_num = pdev->id; - master->num_chipselect = SPI_N_CHIPSEL; + master->num_chipselect = num_devices; master->setup = spi_gpio_setup; master->cleanup = spi_gpio_cleanup; #ifdef CONFIG_OF @@ -461,9 +467,12 @@ static int spi_gpio_probe(struct platform_device *pdev) * property of the node. */ - for (i = 0; i < SPI_N_CHIPSEL; i++) - spi_gpio->cs_gpios[i] = - of_get_named_gpio(np, "cs-gpios", i); + if (!SPI_N_CHIPSEL) + spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT; + else + for (i = 0; i < SPI_N_CHIPSEL; i++) + spi_gpio->cs_gpios[i] = + of_get_named_gpio(np, "cs-gpios", i); } #endif -- GitLab From defcd98b16461e123cb4a6cb6ef24a1d0085c1b2 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Mon, 3 Nov 2014 10:28:57 -0800 Subject: [PATCH 2947/9457] ASoC: max98090: Different comp tables for different pclks In addtion expand the table to handle other values of sysclk. Instead of making the table 3D, expand it to a more descriptive struct. The divisors are specified in Table 19 of the 98090 data sheet version 0p94. The dmic frequency was previously assumed. Instead make it explicit and configurable through device tree. This now handles independently set pclk and dmic frequency. Based on downstream work by Ralph Birt. Signed-off-by: Dylan Reid Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/max98090.txt | 2 + sound/soc/codecs/max98090.c | 189 ++++++++++++++---- sound/soc/codecs/max98090.h | 8 + 3 files changed, 163 insertions(+), 36 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/max98090.txt b/Documentation/devicetree/bindings/sound/max98090.txt index c454e67f54bb..aa802a274520 100644 --- a/Documentation/devicetree/bindings/sound/max98090.txt +++ b/Documentation/devicetree/bindings/sound/max98090.txt @@ -16,6 +16,8 @@ Optional properties: - clock-names: Should be "mclk" +- maxim,dmic-freq: Frequency at which to clock DMIC + Pins on the device (for linking into audio routes): * MIC1 diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 1229554f1464..a65861cf0a44 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1826,27 +1826,155 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, return 0; } -static const int comp_pclk_rates[] = { - 11289600, 12288000, 12000000, 13000000, 19200000 -}; - -static const int dmic_micclk[] = { - 2, 2, 2, 2, 4, 2 -}; +static const int dmic_divisors[] = { 2, 3, 4, 5, 6, 8 }; static const int comp_lrclk_rates[] = { 8000, 16000, 32000, 44100, 48000, 96000 }; -static const int dmic_comp[6][6] = { - {7, 8, 3, 3, 3, 3}, - {7, 8, 3, 3, 3, 3}, - {7, 8, 3, 3, 3, 3}, - {7, 8, 3, 1, 1, 1}, - {7, 8, 3, 1, 2, 2}, - {7, 8, 3, 3, 3, 3} +struct dmic_table { + int pclk; + struct { + int freq; + int comp[6]; /* One each for 8, 16, 32, 44.1, 48, and 96 kHz */ + } settings[6]; /* One for each dmic divisor. */ }; +static const struct dmic_table dmic_table[] = { /* One for each pclk freq. */ + { + .pclk = 11289600, + .settings = { + { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 6, 6, 6, 6 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + }, + }, + { + .pclk = 12000000, + .settings = { + { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + } + }, + { + .pclk = 12288000, + .settings = { + { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 6, 6, 6, 6 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } }, + } + }, + { + .pclk = 13000000, + .settings = { + { .freq = 2, .comp = { 7, 8, 1, 1, 1, 1 } }, + { .freq = 1, .comp = { 7, 8, 0, 0, 0, 0 } }, + { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } }, + { .freq = 0, .comp = { 7, 8, 4, 4, 5, 5 } }, + { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } }, + { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } }, + } + }, + { + .pclk = 19200000, + .settings = { + { .freq = 2, .comp = { 0, 0, 0, 0, 0, 0 } }, + { .freq = 1, .comp = { 7, 8, 1, 1, 1, 1 } }, + { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } }, + { .freq = 0, .comp = { 7, 8, 2, 2, 3, 3 } }, + { .freq = 0, .comp = { 7, 8, 1, 1, 2, 2 } }, + { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } }, + } + }, +}; + +static int max98090_find_divisor(int target_freq, int pclk) +{ + int current_diff = INT_MAX; + int test_diff = INT_MAX; + int divisor_index = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(dmic_divisors); i++) { + test_diff = abs(target_freq - (pclk / dmic_divisors[i])); + if (test_diff < current_diff) { + current_diff = test_diff; + divisor_index = i; + } + } + + return divisor_index; +} + +static int max98090_find_closest_pclk(int pclk) +{ + int m1; + int m2; + int i; + + for (i = 0; i < ARRAY_SIZE(dmic_table); i++) { + if (pclk == dmic_table[i].pclk) + return i; + if (pclk < dmic_table[i].pclk) { + if (i == 0) + return i; + m1 = pclk - dmic_table[i-1].pclk; + m2 = dmic_table[i].pclk - pclk; + if (m1 < m2) + return i - 1; + else + return i; + } + } + + return -EINVAL; +} + +static int max98090_configure_dmic(struct max98090_priv *max98090, + int target_dmic_clk, int pclk, int fs) +{ + int micclk_index; + int pclk_index; + int dmic_freq; + int dmic_comp; + int i; + + pclk_index = max98090_find_closest_pclk(pclk); + if (pclk_index < 0) + return pclk_index; + + micclk_index = max98090_find_divisor(target_dmic_clk, pclk); + + for (i = 0; i < ARRAY_SIZE(comp_lrclk_rates) - 1; i++) { + if (fs <= (comp_lrclk_rates[i] + comp_lrclk_rates[i+1]) / 2) + break; + } + + dmic_freq = dmic_table[pclk_index].settings[micclk_index].freq; + dmic_comp = dmic_table[pclk_index].settings[micclk_index].comp[i]; + + regmap_update_bits(max98090->regmap, M98090_REG_DIGITAL_MIC_ENABLE, + M98090_MICCLK_MASK, + micclk_index << M98090_MICCLK_SHIFT); + + regmap_update_bits(max98090->regmap, M98090_REG_DIGITAL_MIC_CONFIG, + M98090_DMIC_COMP_MASK | M98090_DMIC_FREQ_MASK, + dmic_comp << M98090_DMIC_COMP_SHIFT | + dmic_freq << M98090_DMIC_FREQ_SHIFT); + + return 0; +} + static int max98090_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -1854,7 +1982,6 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct max98090_cdata *cdata; - int i, j; cdata = &max98090->dai[0]; max98090->bclk = snd_soc_params_to_bclk(params); @@ -1893,27 +2020,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG, M98090_DHF_MASK, M98090_DHF_MASK); - /* Check for supported PCLK to LRCLK ratios */ - for (j = 0; j < ARRAY_SIZE(comp_pclk_rates); j++) { - if (comp_pclk_rates[j] == max98090->sysclk) { - break; - } - } - - for (i = 0; i < ARRAY_SIZE(comp_lrclk_rates) - 1; i++) { - if (max98090->lrclk <= (comp_lrclk_rates[i] + - comp_lrclk_rates[i + 1]) / 2) { - break; - } - } - - snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_ENABLE, - M98090_MICCLK_MASK, - dmic_micclk[j] << M98090_MICCLK_SHIFT); - - snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_CONFIG, - M98090_DMIC_COMP_MASK, - dmic_comp[j][i] << M98090_DMIC_COMP_SHIFT); + max98090_configure_dmic(max98090, max98090->dmic_freq, max98090->pclk, + max98090->lrclk); return 0; } @@ -1944,12 +2052,15 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, if ((freq >= 10000000) && (freq <= 20000000)) { snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK, M98090_PSCLK_DIV1); + max98090->pclk = freq; } else if ((freq > 20000000) && (freq <= 40000000)) { snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK, M98090_PSCLK_DIV2); + max98090->pclk = freq >> 1; } else if ((freq > 40000000) && (freq <= 60000000)) { snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK, M98090_PSCLK_DIV4); + max98090->pclk = freq >> 2; } else { dev_err(codec->dev, "Invalid master clock frequency\n"); return -EINVAL; @@ -2324,6 +2435,7 @@ static int max98090_probe(struct snd_soc_codec *codec) /* Initialize private data */ max98090->sysclk = (unsigned)-1; + max98090->pclk = (unsigned)-1; max98090->master = false; cdata = &max98090->dai[0]; @@ -2463,6 +2575,11 @@ static int max98090_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, max98090); max98090->pdata = i2c->dev.platform_data; + ret = of_property_read_u32(i2c->dev.of_node, "maxim,dmic-freq", + &max98090->dmic_freq); + if (ret < 0) + max98090->dmic_freq = MAX98090_DEFAULT_DMIC_FREQ; + max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); if (IS_ERR(max98090->regmap)) { ret = PTR_ERR(max98090->regmap); diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index a5f6bada06da..21ff743f5af2 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h @@ -11,6 +11,12 @@ #ifndef _MAX98090_H #define _MAX98090_H +/* + * The default operating frequency for a DMIC attached to the codec. + * This can be overridden by a device tree property. + */ +#define MAX98090_DEFAULT_DMIC_FREQ 2500000 + /* * MAX98090 Register Definitions */ @@ -1518,8 +1524,10 @@ struct max98090_priv { struct max98090_pdata *pdata; struct clk *mclk; unsigned int sysclk; + unsigned int pclk; unsigned int bclk; unsigned int lrclk; + u32 dmic_freq; struct max98090_cdata dai[1]; int jack_state; struct delayed_work jack_work; -- GitLab From 4973404f81b5474748d39ff6f6beb6b1bc5e76f3 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:10:01 +0100 Subject: [PATCH 2948/9457] cipso: kerneldoc warning fix Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/cipso_ipv4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 4715f25dfe03..e24df5a23446 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -539,7 +539,7 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, /** * cipso_v4_doi_free - Frees a DOI definition - * @entry: the entry's RCU field + * @doi_def: the DOI definition * * Description: * This function frees all of the memory associated with a DOI definition. -- GitLab From 4c787b162607fa4ee9da021a8683d13dd5c7cb9f Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:13:50 +0100 Subject: [PATCH 2949/9457] ipv4: include linux/bug.h instead of asm/bug.h Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/cipso_ipv4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index e24df5a23446..253a61b4e69e 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include /* List of available DOI definitions */ -- GitLab From 988b13438c0c6893192d4ca082eb4df39222b07b Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:19:19 +0100 Subject: [PATCH 2950/9457] cipso: remove NULL assignment on static Also add blank line after structure declarations Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/cipso_ipv4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 253a61b4e69e..5160c710f2eb 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -72,6 +72,7 @@ struct cipso_v4_map_cache_bkt { u32 size; struct list_head list; }; + struct cipso_v4_map_cache_entry { u32 hash; unsigned char *key; @@ -82,7 +83,8 @@ struct cipso_v4_map_cache_entry { u32 activity; struct list_head list; }; -static struct cipso_v4_map_cache_bkt *cipso_v4_cache = NULL; + +static struct cipso_v4_map_cache_bkt *cipso_v4_cache; /* Restricted bitmap (tag #1) flags */ int cipso_v4_rbm_optfmt = 0; -- GitLab From b92022f3e507d4d8415b34d6ac81adf2d45c2071 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:25:38 +0100 Subject: [PATCH 2951/9457] tcp: spelling s/plugable/pluggable Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/tcp_cong.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index b1c5970d47a1..27ead0dd16bc 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -1,5 +1,5 @@ /* - * Plugable TCP congestion control support and newReno + * Pluggable TCP congestion control support and newReno * congestion control. * Based on ideas from I/O scheduler support and Web100. * -- GitLab From c9f503b00622525bb9a549ff38c4bb20b4287b84 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:31:26 +0100 Subject: [PATCH 2952/9457] ipv4: use seq_puts instead of seq_printf where possible Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 8e3eb39f84e7..f0d4eb8b99b9 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -296,12 +296,12 @@ static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals, int j; if (count) { - seq_printf(seq, "\nIcmpMsg:"); + seq_puts(seq, "\nIcmpMsg:"); for (j = 0; j < count; ++j) seq_printf(seq, " %sType%u", type[j] & 0x100 ? "Out" : "In", type[j] & 0xff); - seq_printf(seq, "\nIcmpMsg:"); + seq_puts(seq, "\nIcmpMsg:"); for (j = 0; j < count; ++j) seq_printf(seq, " %lu", vals[j]); } @@ -342,7 +342,7 @@ static void icmp_put(struct seq_file *seq) seq_puts(seq, "\nIcmp: InMsgs InErrors InCsumErrors"); for (i = 0; icmpmibmap[i].name != NULL; i++) seq_printf(seq, " In%s", icmpmibmap[i].name); - seq_printf(seq, " OutMsgs OutErrors"); + seq_puts(seq, " OutMsgs OutErrors"); for (i = 0; icmpmibmap[i].name != NULL; i++) seq_printf(seq, " Out%s", icmpmibmap[i].name); seq_printf(seq, "\nIcmp: %lu %lu %lu", -- GitLab From 0d3979b9c711bf823d65e8abe9ab2e8bff0669fa Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:37:46 +0100 Subject: [PATCH 2953/9457] ipv4: remove 0/NULL assignment on static static values are automatically initialized to 0 Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index a896da50f398..7fa18bc7e47f 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -115,7 +115,7 @@ */ int ic_set_manually __initdata = 0; /* IPconfig parameters set manually */ -static int ic_enable __initdata = 0; /* IP config enabled? */ +static int ic_enable __initdata; /* IP config enabled? */ /* Protocol choice */ int ic_proto_enabled __initdata = 0 @@ -130,7 +130,7 @@ int ic_proto_enabled __initdata = 0 #endif ; -static int ic_host_name_set __initdata = 0; /* Host name set by us? */ +static int ic_host_name_set __initdata; /* Host name set by us? */ __be32 ic_myaddr = NONE; /* My IP address */ static __be32 ic_netmask = NONE; /* Netmask for local subnet */ @@ -160,17 +160,17 @@ static u8 ic_domain[64]; /* DNS (not NIS) domain name */ static char user_dev_name[IFNAMSIZ] __initdata = { 0, }; /* Protocols supported by available interfaces */ -static int ic_proto_have_if __initdata = 0; +static int ic_proto_have_if __initdata; /* MTU for boot device */ -static int ic_dev_mtu __initdata = 0; +static int ic_dev_mtu __initdata; #ifdef IPCONFIG_DYNAMIC static DEFINE_SPINLOCK(ic_recv_lock); -static volatile int ic_got_reply __initdata = 0; /* Proto(s) that replied */ +static volatile int ic_got_reply __initdata; /* Proto(s) that replied */ #endif #ifdef IPCONFIG_DHCP -static int ic_dhcp_msgtype __initdata = 0; /* DHCP msg type received */ +static int ic_dhcp_msgtype __initdata; /* DHCP msg type received */ #endif @@ -186,8 +186,8 @@ struct ic_device { __be32 xid; }; -static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ -static struct net_device *ic_dev __initdata = NULL; /* Selected device */ +static struct ic_device *ic_first_dev __initdata; /* List of open device */ +static struct net_device *ic_dev __initdata; /* Selected device */ static bool __init ic_is_init_dev(struct net_device *dev) { -- GitLab From aa1f731e52807077e9e13a86c0cad12d442c8fd4 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:44:04 +0100 Subject: [PATCH 2954/9457] inet: frags: remove inline on static in c file remove __inline__ / inline and let compiler decide what to do with static functions Inspired-by: "David S. Miller" Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/ip_fragment.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2811cc18701a..4d964dadd655 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -80,7 +80,7 @@ struct ipq { struct inet_peer *peer; }; -static inline u8 ip4_frag_ecn(u8 tos) +static u8 ip4_frag_ecn(u8 tos) { return 1 << (tos & INET_ECN_MASK); } @@ -148,7 +148,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, const void *a) inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, 1) : NULL; } -static __inline__ void ip4_frag_free(struct inet_frag_queue *q) +static void ip4_frag_free(struct inet_frag_queue *q) { struct ipq *qp; @@ -160,7 +160,7 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q) /* Destruction primitives. */ -static __inline__ void ipq_put(struct ipq *ipq) +static void ipq_put(struct ipq *ipq) { inet_frag_put(&ipq->q, &ip4_frags); } @@ -236,7 +236,7 @@ static void ip_expire(unsigned long arg) /* Find the correct entry in the "incomplete datagrams" queue for * this IP datagram, and create new one, if nothing is found. */ -static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) +static struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) { struct inet_frag_queue *q; struct ip4_create_arg arg; @@ -256,7 +256,7 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) } /* Is the fragment too far ahead to be part of ipq? */ -static inline int ip_frag_too_far(struct ipq *qp) +static int ip_frag_too_far(struct ipq *qp) { struct inet_peer *peer = qp->peer; unsigned int max = sysctl_ipfrag_max_dist; @@ -795,16 +795,16 @@ static void __init ip4_frags_ctl_register(void) register_net_sysctl(&init_net, "net/ipv4", ip4_frags_ctl_table); } #else -static inline int ip4_frags_ns_ctl_register(struct net *net) +static int ip4_frags_ns_ctl_register(struct net *net) { return 0; } -static inline void ip4_frags_ns_ctl_unregister(struct net *net) +static void ip4_frags_ns_ctl_unregister(struct net *net) { } -static inline void __init ip4_frags_ctl_register(void) +static void __init ip4_frags_ctl_register(void) { } #endif -- GitLab From c18450a52a10a5c4cea3dc426c40447a7152290f Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:48:41 +0100 Subject: [PATCH 2955/9457] udp: remove else after return else is unnecessary after return 0 in __udp4_lib_rcv() Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/udp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index cd0db5471bb5..cf0cece50b6c 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1777,14 +1777,14 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, if (ret > 0) return -ret; return 0; - } else { - if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) - return __udp4_lib_mcast_deliver(net, skb, uh, - saddr, daddr, udptable); - - sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); } + if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) + return __udp4_lib_mcast_deliver(net, skb, uh, + saddr, daddr, udptable); + + sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); + if (sk != NULL) { int ret; -- GitLab From 436f7c206860729d543a457aca5887e52039a5f4 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 20:52:14 +0100 Subject: [PATCH 2956/9457] igmp: remove camel case definitions use standard uppercase for definitions Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index fb70e3ecc3e4..3f8051358202 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -112,17 +112,17 @@ #ifdef CONFIG_IP_MULTICAST /* Parameter names and values are taken from igmp-v2-06 draft */ -#define IGMP_V1_Router_Present_Timeout (400*HZ) -#define IGMP_V2_Router_Present_Timeout (400*HZ) -#define IGMP_V2_Unsolicited_Report_Interval (10*HZ) -#define IGMP_V3_Unsolicited_Report_Interval (1*HZ) -#define IGMP_Query_Response_Interval (10*HZ) -#define IGMP_Query_Robustness_Variable 2 +#define IGMP_V1_ROUTER_PRESENT_TIMEOUT (400*HZ) +#define IGMP_V2_ROUTER_PRESENT_TIMEOUT (400*HZ) +#define IGMP_V2_UNSOLICITED_REPORT_INTERVAL (10*HZ) +#define IGMP_V3_UNSOLICITED_REPORT_INTERVAL (1*HZ) +#define IGMP_QUERY_RESPONSE_INTERVAL (10*HZ) +#define IGMP_QUERY_ROBUSTNESS_VARIABLE 2 -#define IGMP_Initial_Report_Delay (1) +#define IGMP_INITIAL_REPORT_DELAY (1) -/* IGMP_Initial_Report_Delay is not from IGMP specs! +/* IGMP_INITIAL_REPORT_DELAY is not from IGMP specs! * IGMP specs require to report membership immediately after * joining a group, but we delay the first report by a * small interval. It seems more natural and still does not @@ -879,15 +879,15 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, if (ih->code == 0) { /* Alas, old v1 router presents here. */ - max_delay = IGMP_Query_Response_Interval; + max_delay = IGMP_QUERY_RESPONSE_INTERVAL; in_dev->mr_v1_seen = jiffies + - IGMP_V1_Router_Present_Timeout; + IGMP_V1_ROUTER_PRESENT_TIMEOUT; group = 0; } else { /* v2 router present */ max_delay = ih->code*(HZ/IGMP_TIMER_SCALE); in_dev->mr_v2_seen = jiffies + - IGMP_V2_Router_Present_Timeout; + IGMP_V2_ROUTER_PRESENT_TIMEOUT; } /* cancel the interface change timer */ in_dev->mr_ifc_count = 0; @@ -899,7 +899,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, return true; /* ignore bogus packet; freed by caller */ } else if (IGMP_V1_SEEN(in_dev)) { /* This is a v3 query with v1 queriers present */ - max_delay = IGMP_Query_Response_Interval; + max_delay = IGMP_QUERY_RESPONSE_INTERVAL; group = 0; } else if (IGMP_V2_SEEN(in_dev)) { /* this is a v3 query with v2 queriers present; @@ -1218,7 +1218,7 @@ static void igmp_group_added(struct ip_mc_list *im) return; if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) { spin_lock_bh(&im->lock); - igmp_start_timer(im, IGMP_Initial_Report_Delay); + igmp_start_timer(im, IGMP_INITIAL_REPORT_DELAY); spin_unlock_bh(&im->lock); return; } @@ -1541,7 +1541,7 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) int sysctl_igmp_max_memberships __read_mostly = IP_MAX_MEMBERSHIPS; int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF; #ifdef CONFIG_IP_MULTICAST -int sysctl_igmp_qrv __read_mostly = IGMP_Query_Robustness_Variable; +int sysctl_igmp_qrv __read_mostly = IGMP_QUERY_ROBUSTNESS_VARIABLE; #endif static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, -- GitLab From 4d51abf9bcca01efa3afbe94d50cc2cda8095da8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jun 2014 13:37:33 -0700 Subject: [PATCH 2957/9457] block: Use dma_zalloc_coherent Use the zeroing function instead of dma_alloc_coherent & memset(,0,) Signed-off-by: Joe Perches Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index e2bb8afbeae5..baee59530d6e 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1275,11 +1275,10 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, if (!nvmeq) return NULL; - nvmeq->cqes = dma_alloc_coherent(dmadev, CQ_SIZE(depth), - &nvmeq->cq_dma_addr, GFP_KERNEL); + nvmeq->cqes = dma_zalloc_coherent(dmadev, CQ_SIZE(depth), + &nvmeq->cq_dma_addr, GFP_KERNEL); if (!nvmeq->cqes) goto free_nvmeq; - memset((void *)nvmeq->cqes, 0, CQ_SIZE(depth)); nvmeq->sq_cmds = dma_alloc_coherent(dmadev, SQ_SIZE(depth), &nvmeq->sq_dma_addr, GFP_KERNEL); -- GitLab From 6fccf9383b280d463a7dfe1e0d048aff8df8a25e Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 18 Jun 2014 13:58:57 -0600 Subject: [PATCH 2958/9457] NVMe: Async event request Submits NVMe asynchronous event requests, one event up to the controller maximum or number of possible different event types (8), whichever is smaller. Events successfully returned by the controller are logged. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 42 +++++++++++++++++++++++++++++++++++++++ include/linux/nvme.h | 1 + 2 files changed, 43 insertions(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index baee59530d6e..42a62bbf4a11 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -207,6 +207,7 @@ static int alloc_cmdid_killable(struct nvme_queue *nvmeq, void *ctx, #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) #define CMD_CTX_ABORT (0x318 + CMD_CTX_BASE) +#define CMD_CTX_ASYNC (0x31C + CMD_CTX_BASE) static void special_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) @@ -229,6 +230,17 @@ static void special_completion(struct nvme_queue *nvmeq, void *ctx, cqe->command_id, le16_to_cpup(&cqe->sq_id)); return; } + if (ctx == CMD_CTX_ASYNC) { + u32 result = le32_to_cpup(&cqe->result); + u16 status = le16_to_cpup(&cqe->status) >> 1; + + if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ) + ++nvmeq->dev->event_limit; + if (status == NVME_SC_SUCCESS) + dev_warn(nvmeq->q_dmadev, + "async event result %08x\n", result); + return; + } dev_warn(nvmeq->q_dmadev, "Unknown special completion %p\n", ctx); } @@ -1161,6 +1173,8 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) continue; if (info[cmdid].ctx == CMD_CTX_CANCELLED) continue; + if (timeout && info[cmdid].ctx == CMD_CTX_ASYNC) + continue; if (timeout && nvmeq->dev->initialized) { nvme_abort_cmd(cmdid, nvmeq); continue; @@ -1842,6 +1856,27 @@ static void nvme_resubmit_bios(struct nvme_queue *nvmeq) } } +static int nvme_submit_async_req(struct nvme_queue *nvmeq) +{ + struct nvme_command *c; + int cmdid; + + cmdid = alloc_cmdid(nvmeq, CMD_CTX_ASYNC, special_completion, 0); + if (cmdid < 0) + return cmdid; + + c = &nvmeq->sq_cmds[nvmeq->sq_tail]; + memset(c, 0, sizeof(*c)); + c->common.opcode = nvme_admin_async_event; + c->common.command_id = cmdid; + + if (++nvmeq->sq_tail == nvmeq->q_depth) + nvmeq->sq_tail = 0; + writel(nvmeq->sq_tail, nvmeq->q_db); + + return 0; +} + static int nvme_kthread(void *data) { struct nvme_dev *dev, *next; @@ -1875,6 +1910,12 @@ static int nvme_kthread(void *data) nvme_cancel_ios(nvmeq, true); nvme_resubmit_bios(nvmeq); nvme_resubmit_iods(nvmeq); + + while ((i == 0) && (dev->event_limit > 0)) { + if (nvme_submit_async_req(nvmeq)) + break; + dev->event_limit--; + } unlock: spin_unlock_irq(&nvmeq->q_lock); } @@ -2244,6 +2285,7 @@ static int nvme_dev_add(struct nvme_dev *dev) dev->oncs = le16_to_cpup(&ctrl->oncs); dev->abort_limit = ctrl->acl + 1; dev->vwc = ctrl->vwc; + dev->event_limit = min(ctrl->aerl + 1, 8); memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 2bf403195c09..974efd04a4b1 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -99,6 +99,7 @@ struct nvme_dev { u32 stripe_size; u16 oncs; u16 abort_limit; + u8 event_limit; u8 vwc; u8 initialized; }; -- GitLab From a7dd7957acf798ac406afd6631e64a27ac4a5bf1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 28 Jun 2014 09:00:27 -0400 Subject: [PATCH 2959/9457] NVMe: Update list of status codes Taken from the draft NVMe 1.1b specification. Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- include/uapi/linux/nvme.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/uapi/linux/nvme.h b/include/uapi/linux/nvme.h index 29a7d8619d8d..134518b0100b 100644 --- a/include/uapi/linux/nvme.h +++ b/include/uapi/linux/nvme.h @@ -440,9 +440,15 @@ enum { NVME_SC_FUSED_MISSING = 0xa, NVME_SC_INVALID_NS = 0xb, NVME_SC_CMD_SEQ_ERROR = 0xc, + NVME_SC_SGL_INVALID_LAST = 0xd, + NVME_SC_SGL_INVALID_COUNT = 0xe, + NVME_SC_SGL_INVALID_DATA = 0xf, + NVME_SC_SGL_INVALID_METADATA = 0x10, + NVME_SC_SGL_INVALID_TYPE = 0x11, NVME_SC_LBA_RANGE = 0x80, NVME_SC_CAP_EXCEEDED = 0x81, NVME_SC_NS_NOT_READY = 0x82, + NVME_SC_RESERVATION_CONFLICT = 0x83, NVME_SC_CQ_INVALID = 0x100, NVME_SC_QID_INVALID = 0x101, NVME_SC_QUEUE_SIZE = 0x102, @@ -454,7 +460,15 @@ enum { NVME_SC_INVALID_VECTOR = 0x108, NVME_SC_INVALID_LOG_PAGE = 0x109, NVME_SC_INVALID_FORMAT = 0x10a, + NVME_SC_FIRMWARE_NEEDS_RESET = 0x10b, + NVME_SC_INVALID_QUEUE = 0x10c, + NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d, + NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e, + NVME_SC_FEATURE_NOT_PER_NS = 0x10f, + NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110, NVME_SC_BAD_ATTRIBUTES = 0x180, + NVME_SC_INVALID_PI = 0x181, + NVME_SC_READ_ONLY = 0x182, NVME_SC_WRITE_FAULT = 0x280, NVME_SC_READ_ERROR = 0x281, NVME_SC_GUARD_CHECK = 0x282, -- GitLab From 1d0906246095184d1624c643c2088152d330c40a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 23 Jun 2014 11:34:01 -0600 Subject: [PATCH 2960/9457] NVMe: Mismatched host/device page size support Adds support for devices with max page size smaller than the host's. In the case we encounter such a host/device combination, the driver will split a page into as many PRP entries as necessary for the device's page size capabilities. If the device's reported minimum page size is greater than the host's, the driver will not attempt to enable the device and return an error instead. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 59 ++++++++++++++++++++++++++------------- include/linux/nvme.h | 2 ++ 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 42a62bbf4a11..e60bb0fec7e3 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -373,17 +373,17 @@ static __le64 **iod_list(struct nvme_iod *iod) * as it only leads to a small amount of wasted memory for the lifetime of * the I/O. */ -static int nvme_npages(unsigned size) +static int nvme_npages(unsigned size, struct nvme_dev *dev) { - unsigned nprps = DIV_ROUND_UP(size + PAGE_SIZE, PAGE_SIZE); - return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8); + unsigned nprps = DIV_ROUND_UP(size + dev->page_size, dev->page_size); + return DIV_ROUND_UP(8 * nprps, dev->page_size - 8); } static struct nvme_iod * -nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp) +nvme_alloc_iod(unsigned nseg, unsigned nbytes, struct nvme_dev *dev, gfp_t gfp) { struct nvme_iod *iod = kmalloc(sizeof(struct nvme_iod) + - sizeof(__le64 *) * nvme_npages(nbytes) + + sizeof(__le64 *) * nvme_npages(nbytes, dev) + sizeof(struct scatterlist) * nseg, gfp); if (iod) { @@ -400,7 +400,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp) void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod) { - const int last_prp = PAGE_SIZE / 8 - 1; + const int last_prp = dev->page_size / 8 - 1; int i; __le64 **list = iod_list(iod); dma_addr_t prp_dma = iod->first_dma; @@ -491,26 +491,27 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod, int total_len, __le64 **list = iod_list(iod); dma_addr_t prp_dma; int nprps, i; + u32 page_size = dev->page_size; - length -= (PAGE_SIZE - offset); + length -= (page_size - offset); if (length <= 0) return total_len; - dma_len -= (PAGE_SIZE - offset); + dma_len -= (page_size - offset); if (dma_len) { - dma_addr += (PAGE_SIZE - offset); + dma_addr += (page_size - offset); } else { sg = sg_next(sg); dma_addr = sg_dma_address(sg); dma_len = sg_dma_len(sg); } - if (length <= PAGE_SIZE) { + if (length <= page_size) { iod->first_dma = dma_addr; return total_len; } - nprps = DIV_ROUND_UP(length, PAGE_SIZE); + nprps = DIV_ROUND_UP(length, page_size); if (nprps <= (256 / 8)) { pool = dev->prp_small_pool; iod->npages = 0; @@ -523,13 +524,13 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod, int total_len, if (!prp_list) { iod->first_dma = dma_addr; iod->npages = -1; - return (total_len - length) + PAGE_SIZE; + return (total_len - length) + page_size; } list[0] = prp_list; iod->first_dma = prp_dma; i = 0; for (;;) { - if (i == PAGE_SIZE / 8) { + if (i == page_size >> 3) { __le64 *old_prp_list = prp_list; prp_list = dma_pool_alloc(pool, gfp, &prp_dma); if (!prp_list) @@ -540,9 +541,9 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod, int total_len, i = 1; } prp_list[i++] = cpu_to_le64(dma_addr); - dma_len -= PAGE_SIZE; - dma_addr += PAGE_SIZE; - length -= PAGE_SIZE; + dma_len -= page_size; + dma_addr += page_size; + length -= page_size; if (length <= 0) break; if (dma_len > 0) @@ -749,7 +750,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, if ((bio->bi_rw & REQ_FLUSH) && psegs) return nvme_split_flush_data(nvmeq, bio); - iod = nvme_alloc_iod(psegs, bio->bi_iter.bi_size, GFP_ATOMIC); + iod = nvme_alloc_iod(psegs, bio->bi_iter.bi_size, ns->dev, GFP_ATOMIC); if (!iod) return -ENOMEM; @@ -1463,6 +1464,24 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) u32 aqa; u64 cap = readq(&dev->bar->cap); struct nvme_queue *nvmeq; + unsigned page_shift = PAGE_SHIFT; + unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12; + unsigned dev_page_max = NVME_CAP_MPSMAX(cap) + 12; + + if (page_shift < dev_page_min) { + dev_err(&dev->pci_dev->dev, + "Minimum device page size (%u) too large for " + "host (%u)\n", 1 << dev_page_min, + 1 << page_shift); + return -ENODEV; + } + if (page_shift > dev_page_max) { + dev_info(&dev->pci_dev->dev, + "Device maximum page size (%u) smaller than " + "host (%u); enabling work-around\n", + 1 << dev_page_max, 1 << page_shift); + page_shift = dev_page_max; + } result = nvme_disable_ctrl(dev, cap); if (result < 0) @@ -1478,8 +1497,10 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) aqa = nvmeq->q_depth - 1; aqa |= aqa << 16; + dev->page_size = 1 << page_shift; + dev->ctrl_config = NVME_CC_ENABLE | NVME_CC_CSS_NVM; - dev->ctrl_config |= (PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; + dev->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT; dev->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE; dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES; @@ -1529,7 +1550,7 @@ struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, } err = -ENOMEM; - iod = nvme_alloc_iod(count, length, GFP_KERNEL); + iod = nvme_alloc_iod(count, length, dev, GFP_KERNEL); if (!iod) goto put_pages; diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 974efd04a4b1..ed09074e5554 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -38,6 +38,7 @@ struct nvme_bar { #define NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff) #define NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf) #define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf) +#define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf) enum { NVME_CC_ENABLE = 1 << 0, @@ -97,6 +98,7 @@ struct nvme_dev { char firmware_rev[8]; u32 max_hw_sectors; u32 stripe_size; + u32 page_size; u16 oncs; u16 abort_limit; u8 event_limit; -- GitLab From 01079522f94b3a1c87cfa375be3917d2da6e6363 Mon Sep 17 00:00:00 2001 From: Dan McLeran Date: Mon, 23 Jun 2014 08:24:36 -0600 Subject: [PATCH 2961/9457] NVMe: Change nvme_enable_ctrl to set EN and manage CC thru ctrl_config. Change the behavior of nvme_enable_ctrl to set EN. Clear CC.SH for both nvme_enable_ctrl and nvme_disable_ctrl. Remove reading of the CC register and manage the state in dev->ctrl_config. Signed-off-by: Dan McLeran [removed an unwanted write to CC] Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index e60bb0fec7e3..0a98de813a12 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1422,25 +1422,30 @@ static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled) */ static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap) { - u32 cc = readl(&dev->bar->cc); + dev->ctrl_config &= ~NVME_CC_SHN_MASK; + dev->ctrl_config &= ~NVME_CC_ENABLE; + writel(dev->ctrl_config, &dev->bar->cc); - if (cc & NVME_CC_ENABLE) - writel(cc & ~NVME_CC_ENABLE, &dev->bar->cc); return nvme_wait_ready(dev, cap, false); } static int nvme_enable_ctrl(struct nvme_dev *dev, u64 cap) { + dev->ctrl_config &= ~NVME_CC_SHN_MASK; + dev->ctrl_config |= NVME_CC_ENABLE; + writel(dev->ctrl_config, &dev->bar->cc); + return nvme_wait_ready(dev, cap, true); } static int nvme_shutdown_ctrl(struct nvme_dev *dev) { unsigned long timeout; - u32 cc; - cc = (readl(&dev->bar->cc) & ~NVME_CC_SHN_MASK) | NVME_CC_SHN_NORMAL; - writel(cc, &dev->bar->cc); + dev->ctrl_config &= ~NVME_CC_SHN_MASK; + dev->ctrl_config |= NVME_CC_SHN_NORMAL; + + writel(dev->ctrl_config, &dev->bar->cc); timeout = 2 * HZ + jiffies; while ((readl(&dev->bar->csts) & NVME_CSTS_SHST_MASK) != @@ -1499,7 +1504,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) dev->page_size = 1 << page_shift; - dev->ctrl_config = NVME_CC_ENABLE | NVME_CC_CSS_NVM; + dev->ctrl_config = NVME_CC_CSS_NVM; dev->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT; dev->ctrl_config |= NVME_CC_ARB_RR | NVME_CC_SHN_NONE; dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES; @@ -1507,7 +1512,6 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) writel(aqa, &dev->bar->aqa); writeq(nvmeq->sq_dma_addr, &dev->bar->asq); writeq(nvmeq->cq_dma_addr, &dev->bar->acq); - writel(dev->ctrl_config, &dev->bar->cc); result = nvme_enable_ctrl(dev, cap); if (result) -- GitLab From badc34d4154de81b965629a5c3110e058eb8ca2b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 23 Jun 2014 14:25:35 -0600 Subject: [PATCH 2962/9457] NVMe: Handling devices incapable of I/O This is a minor refactor for handling devices that are incapable of IO. The driver previously used special error codes to know that IO queues are unavailable, but we have an online queue count now. This also fixes an issue where the driver successfully sets the queue count, but either is unable to allocate an IO queue or the device can't create one for some reason. If the driver can successfully enable the device and get responses to admin commands, the driver will bring up a character device for managment but not create block devices. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 0a98de813a12..f3103aa91d2e 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2172,7 +2172,7 @@ static int set_queue_count(struct nvme_dev *dev, int count) if (status > 0) { dev_err(&dev->pci_dev->dev, "Could not set queue count (%d)\n", status); - return -EBUSY; + return 0; } return min(result & 0xffff, result >> 16) + 1; } @@ -2214,7 +2214,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) nr_io_queues = num_possible_cpus(); result = set_queue_count(dev, nr_io_queues); - if (result < 0) + if (result <= 0) return result; if (result < nr_io_queues) nr_io_queues = result; @@ -2740,7 +2740,7 @@ static int nvme_dev_start(struct nvme_dev *dev) } result = nvme_setup_io_queues(dev); - if (result && result != -EBUSY) + if (result) goto disable; return result; @@ -2777,9 +2777,9 @@ static int nvme_dev_resume(struct nvme_dev *dev) int ret; ret = nvme_dev_start(dev); - if (ret && ret != -EBUSY) + if (ret) return ret; - if (ret == -EBUSY) { + if (dev->online_queues < 2) { spin_lock(&dev_list_lock); dev->reset_workfn = nvme_remove_disks; queue_work(nvme_workq, &dev->reset_work); @@ -2852,17 +2852,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) kref_init(&dev->kref); result = nvme_dev_start(dev); - if (result) { - if (result == -EBUSY) - goto create_cdev; + if (result) goto release_pools; - } - result = nvme_dev_add(dev); + if (dev->online_queues > 1) + result = nvme_dev_add(dev); if (result) goto shutdown; - create_cdev: scnprintf(dev->name, sizeof(dev->name), "nvme%d", dev->instance); dev->miscdev.minor = MISC_DYNAMIC_MINOR; dev->miscdev.parent = &pdev->dev; -- GitLab From c81f49758a677e878df4e6a33f29d8ce401bf66d Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 23 Jun 2014 15:24:53 -0600 Subject: [PATCH 2963/9457] NVMe: Use pci_stop_and_remove_bus_device_locked() Race conditions are theoretically possible between the NVMe PCI device removal and the generic PCI bus rescan and device removal that can be triggered via sysfs. To avoid those race conditions make the NVMe code use pci_stop_and_remove_bus_device_locked(). Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index f3103aa91d2e..48a712734b55 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2759,7 +2759,7 @@ static int nvme_remove_dead_ctrl(void *arg) struct pci_dev *pdev = dev->pci_dev; if (pci_get_drvdata(pdev)) - pci_stop_and_remove_bus_device(pdev); + pci_stop_and_remove_bus_device_locked(pdev); kref_put(&dev->kref, nvme_free_dev); return 0; } -- GitLab From a67394790a9c52657273212647e350e36a292183 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 23 Jun 2014 16:03:21 -0600 Subject: [PATCH 2964/9457] NVMe: Whitespace fixes Fixing tabs inadvertently converted to spaces. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 48a712734b55..c5f379f08f50 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2892,12 +2892,12 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) { - struct nvme_dev *dev = pci_get_drvdata(pdev); + struct nvme_dev *dev = pci_get_drvdata(pdev); - if (prepare) - nvme_dev_shutdown(dev); - else - nvme_dev_resume(dev); + if (prepare) + nvme_dev_shutdown(dev); + else + nvme_dev_resume(dev); } static void nvme_shutdown(struct pci_dev *pdev) -- GitLab From 7c1b24503873e6cfc1d31f2e55c35358fd438351 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 25 Jun 2014 11:18:12 -0600 Subject: [PATCH 2965/9457] NVMe: Skip orderly shutdown on failed devices Rather than skipping shutdown only for devices that have been removed, skip the orderly shutdown on failed devices to avoid the long timeout handling that inevitably happens when deleting queues on such a device. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index c5f379f08f50..ac3694083e89 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2567,11 +2567,14 @@ static void nvme_dev_list_remove(struct nvme_dev *dev) static void nvme_dev_shutdown(struct nvme_dev *dev) { int i; + u32 csts = -1; dev->initialized = 0; nvme_dev_list_remove(dev); - if (!dev->bar || (dev->bar && readl(&dev->bar->csts) == -1)) { + if (dev->bar) + csts = readl(&dev->bar->csts); + if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { for (i = dev->queue_count - 1; i >= 0; i--) { struct nvme_queue *nvmeq = raw_nvmeq(dev, i); nvme_suspend_queue(nvmeq); -- GitLab From 2484f40780b97df1b5eb09e78ce4efaa78b21875 Mon Sep 17 00:00:00 2001 From: Dan McLeran Date: Tue, 1 Jul 2014 09:33:32 -0600 Subject: [PATCH 2966/9457] NVMe: Add shutdown timeout as module parameter. The current implementation hard-codes the shutdown timeout to 2 seconds. Some devices take longer than this to complete a normal shutdown. Changing the shutdown timeout to a module parameter with a default timeout of 5 seconds. Signed-off-by: Dan McLeran Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ac3694083e89..3ada636356e8 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -48,6 +48,7 @@ #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) #define ADMIN_TIMEOUT (admin_timeout * HZ) +#define SHUTDOWN_TIMEOUT (shutdown_timeout * HZ) #define IOD_TIMEOUT (retry_time * HZ) static unsigned char admin_timeout = 60; @@ -62,6 +63,10 @@ static unsigned char retry_time = 30; module_param(retry_time, byte, 0644); MODULE_PARM_DESC(retry_time, "time in seconds to retry failed I/O"); +static unsigned char shutdown_timeout = 5; +module_param(shutdown_timeout, byte, 0644); +MODULE_PARM_DESC(shutdown_timeout, "timeout in seconds for controller shutdown"); + static int nvme_major; module_param(nvme_major, int, 0); @@ -1447,7 +1452,7 @@ static int nvme_shutdown_ctrl(struct nvme_dev *dev) writel(dev->ctrl_config, &dev->bar->cc); - timeout = 2 * HZ + jiffies; + timeout = SHUTDOWN_TIMEOUT + jiffies; while ((readl(&dev->bar->csts) & NVME_CSTS_SHST_MASK) != NVME_CSTS_SHST_CMPLT) { msleep(100); -- GitLab From f435c2825b4cc6453b9a1f91418cabbd6ba08cc0 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 7 Jul 2014 09:14:42 -0600 Subject: [PATCH 2967/9457] NVMe: Call nvme_free_queue directly Rather than relying on call_rcu, this patch directly frees the nvme_queue's memory after ensuring no readers exist. Some arch specific dma_free_coherent implementations may not be called from a call_rcu's soft interrupt context, hence the change. Signed-off-by: Keith Busch Reported-by: Matthew Minter Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 3ada636356e8..d3a025fc1268 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -95,7 +95,7 @@ struct async_cmd_info { * commands and one for I/O commands). */ struct nvme_queue { - struct rcu_head r_head; + struct llist_node node; struct device *q_dmadev; struct nvme_dev *dev; char irqname[24]; /* nvme4294967295-65535\0 */ @@ -1192,10 +1192,8 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) } } -static void nvme_free_queue(struct rcu_head *r) +static void nvme_free_queue(struct nvme_queue *nvmeq) { - struct nvme_queue *nvmeq = container_of(r, struct nvme_queue, r_head); - spin_lock_irq(&nvmeq->q_lock); while (bio_list_peek(&nvmeq->sq_cong)) { struct bio *bio = bio_list_pop(&nvmeq->sq_cong); @@ -1225,14 +1223,21 @@ static void nvme_free_queue(struct rcu_head *r) static void nvme_free_queues(struct nvme_dev *dev, int lowest) { + LLIST_HEAD(q_list); + struct nvme_queue *nvmeq, *next; + struct llist_node *entry; int i; for (i = dev->queue_count - 1; i >= lowest; i--) { - struct nvme_queue *nvmeq = raw_nvmeq(dev, i); + nvmeq = raw_nvmeq(dev, i); rcu_assign_pointer(dev->queues[i], NULL); - call_rcu(&nvmeq->r_head, nvme_free_queue); + llist_add(&nvmeq->node, &q_list); dev->queue_count--; } + synchronize_rcu(); + entry = llist_del_all(&q_list); + llist_for_each_entry_safe(nvmeq, next, entry, node) + nvme_free_queue(nvmeq); } /** @@ -2929,7 +2934,6 @@ static void nvme_remove(struct pci_dev *pdev) nvme_dev_remove(dev); nvme_dev_shutdown(dev); nvme_free_queues(dev, 0); - rcu_barrier(); nvme_release_instance(dev); nvme_release_prp_pools(dev); kref_put(&dev->kref, nvme_free_dev); -- GitLab From 302c6727e5eb4d0be0e02d077b65feb3e73ea254 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 18 Jul 2014 11:40:20 -0600 Subject: [PATCH 2968/9457] NVMe: Fix filesystem sync deadlock on removal This changes the order of deleting the gendisks so it happens after the nvme IO queues are freed. If a device is removed while a filesystem has associated dirty data, the removal will wait on these to complete before proceeding from del_gendisk, which could have caused deadlock before. The implication of this is that an orderly removal of a responsive device won't necessarily wait for dirty data to be written, but we are not guaranteed the device is even going to respond at this point either. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index d3a025fc1268..48a1be4ab24c 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2781,8 +2781,8 @@ static void nvme_remove_disks(struct work_struct *ws) { struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); - nvme_dev_remove(dev); nvme_free_queues(dev, 1); + nvme_dev_remove(dev); } static int nvme_dev_resume(struct nvme_dev *dev) @@ -2931,9 +2931,9 @@ static void nvme_remove(struct pci_dev *pdev) flush_work(&dev->reset_work); flush_work(&dev->cpu_work); misc_deregister(&dev->miscdev); - nvme_dev_remove(dev); nvme_dev_shutdown(dev); nvme_free_queues(dev, 0); + nvme_dev_remove(dev); nvme_release_instance(dev); nvme_release_prp_pools(dev); kref_put(&dev->kref, nvme_free_dev); -- GitLab From 5905535610fc6b11379a999ff45bfa39f0d605b6 Mon Sep 17 00:00:00 2001 From: Sam Bradshaw Date: Tue, 29 Jul 2014 13:31:36 -0700 Subject: [PATCH 2969/9457] NVMe: Correctly handle IOCTL_SUBMIT_IO when cpus > online queues nvme_submit_io_cmd() uses smp_processor_id() to pick an IO queue index. This patch fixes the case where there are more cpus from which the ioctl call can originate than online queues, which can happen when a device supports or was allocated fewer interrupt vectors than exist cpu cores. Thanks to Keith Busch for the implementation suggestion. Signed-off-by: Sam Bradshaw Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 48a1be4ab24c..5d44c9344522 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -984,8 +984,8 @@ int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, int nvme_submit_io_cmd(struct nvme_dev *dev, struct nvme_command *cmd, u32 *result) { - return nvme_submit_sync_cmd(dev, smp_processor_id() + 1, cmd, result, - NVME_IO_TIMEOUT); + return nvme_submit_sync_cmd(dev, this_cpu_read(*dev->io_queue), cmd, + result, NVME_IO_TIMEOUT); } static int nvme_submit_admin_cmd_async(struct nvme_dev *dev, -- GitLab From 062261be4e39e35bdf2fba16a4b2d8a432ae8281 Mon Sep 17 00:00:00 2001 From: Andreea-Cristina Bernat Date: Mon, 18 Aug 2014 17:41:01 +0300 Subject: [PATCH 2970/9457] nvme: Replace rcu_assign_pointer() with RCU_INIT_POINTER() The use of "rcu_assign_pointer()" is NULLing out the pointer. According to RCU_INIT_POINTER()'s block comment: "1. This use of RCU_INIT_POINTER() is NULLing out the pointer" it is better to use it instead of rcu_assign_pointer() because it has a smaller overhead. The following Coccinelle semantic patch was used: @@ @@ - rcu_assign_pointer + RCU_INIT_POINTER (..., NULL) Signed-off-by: Andreea-Cristina Bernat Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 5d44c9344522..c1e3c1a101b8 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1230,7 +1230,7 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) for (i = dev->queue_count - 1; i >= lowest; i--) { nvmeq = raw_nvmeq(dev, i); - rcu_assign_pointer(dev->queues[i], NULL); + RCU_INIT_POINTER(dev->queues[i], NULL); llist_add(&nvmeq->node, &q_list); dev->queue_count--; } -- GitLab From a96d4f5c2da66a0c1537bfd8aaa868b69595476a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 19 Aug 2014 19:15:59 -0600 Subject: [PATCH 2971/9457] NVMe: Reference count pci device If an nvme device is removed but user space has an open reference, the nvme driver would have been holding an invalid reference to its pci device. You may get a general protection fault on x86 h/w when the driver uses that reference in dma_map_sg(), as is done in nvme_map_user_pages() from the IOCTL interface. This patch fixes the fault by taking a reference on the pci device and holding it even after device removal until all opens on the nvme device are closed. Signed-off-by: Keith Busch Reported-by: Nilesh Choudhury Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index c1e3c1a101b8..955b5699ff96 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2678,6 +2678,7 @@ static void nvme_free_dev(struct kref *kref) { struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); + pci_dev_put(dev->pci_dev); nvme_free_namespaces(dev); free_percpu(dev->io_queue); kfree(dev->queues); @@ -2853,11 +2854,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->reset_workfn = nvme_reset_failed_dev; INIT_WORK(&dev->reset_work, nvme_reset_workfn); INIT_WORK(&dev->cpu_work, nvme_cpu_workfn); - dev->pci_dev = pdev; + dev->pci_dev = pci_dev_get(pdev); pci_set_drvdata(pdev, dev); result = nvme_set_instance(dev); if (result) - goto free; + goto put_pci; result = nvme_setup_prp_pools(dev); if (result) @@ -2895,6 +2896,8 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) nvme_release_prp_pools(dev); release: nvme_release_instance(dev); + put_pci: + pci_dev_put(dev->pci_dev); free: free_percpu(dev->io_queue); kfree(dev->queues); -- GitLab From e179729a821c1b82375f5593533c027462e753b7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 27 Aug 2014 13:55:38 -0600 Subject: [PATCH 2972/9457] NVMe: Remove duplicate compat SG_IO code We can return -ENOIOCTLCMD and the ioctl will be handled by fs/compat_ioctl.c instead. This removes a lot of duplicate code in the nvme driver. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 +- drivers/block/nvme-scsi.c | 146 -------------------------------------- 2 files changed, 1 insertion(+), 149 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 955b5699ff96..37f22b6bb009 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1807,11 +1807,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct nvme_ns *ns = bdev->bd_disk->private_data; - switch (cmd) { case SG_IO: - return nvme_sg_io32(ns, arg); + return -ENOIOCTLCMD; } return nvme_ioctl(bdev, mode, cmd, arg); } diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index a4cd6d691c63..dabafa6a64cb 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -3016,152 +3016,6 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr) return retcode; } -#ifdef CONFIG_COMPAT -typedef struct sg_io_hdr32 { - compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ - compat_int_t dxfer_direction; /* [i] data transfer direction */ - unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ - unsigned char mx_sb_len; /* [i] max length to write to sbp */ - unsigned short iovec_count; /* [i] 0 implies no scatter gather */ - compat_uint_t dxfer_len; /* [i] byte count of data transfer */ - compat_uint_t dxferp; /* [i], [*io] points to data transfer memory - or scatter gather list */ - compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ - compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ - compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ - compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ - compat_int_t pack_id; /* [i->o] unused internally (normally) */ - compat_uptr_t usr_ptr; /* [i->o] unused internally */ - unsigned char status; /* [o] scsi status */ - unsigned char masked_status; /* [o] shifted, masked scsi status */ - unsigned char msg_status; /* [o] messaging level data (optional) */ - unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ - unsigned short host_status; /* [o] errors from host adapter */ - unsigned short driver_status; /* [o] errors from software driver */ - compat_int_t resid; /* [o] dxfer_len - actual_transferred */ - compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ - compat_uint_t info; /* [o] auxiliary information */ -} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */ - -typedef struct sg_iovec32 { - compat_uint_t iov_base; - compat_uint_t iov_len; -} sg_iovec32_t; - -static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count) -{ - sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1); - sg_iovec32_t __user *iov32 = dxferp; - int i; - - for (i = 0; i < iovec_count; i++) { - u32 base, len; - - if (get_user(base, &iov32[i].iov_base) || - get_user(len, &iov32[i].iov_len) || - put_user(compat_ptr(base), &iov[i].iov_base) || - put_user(len, &iov[i].iov_len)) - return -EFAULT; - } - - if (put_user(iov, &sgio->dxferp)) - return -EFAULT; - return 0; -} - -int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg) -{ - sg_io_hdr32_t __user *sgio32 = (sg_io_hdr32_t __user *)arg; - sg_io_hdr_t __user *sgio; - u16 iovec_count; - u32 data; - void __user *dxferp; - int err; - int interface_id; - - if (get_user(interface_id, &sgio32->interface_id)) - return -EFAULT; - if (interface_id != 'S') - return -EINVAL; - - if (get_user(iovec_count, &sgio32->iovec_count)) - return -EFAULT; - - { - void __user *top = compat_alloc_user_space(0); - void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) + - (iovec_count * sizeof(sg_iovec_t))); - if (new > top) - return -EINVAL; - - sgio = new; - } - - /* Ok, now construct. */ - if (copy_in_user(&sgio->interface_id, &sgio32->interface_id, - (2 * sizeof(int)) + - (2 * sizeof(unsigned char)) + - (1 * sizeof(unsigned short)) + - (1 * sizeof(unsigned int)))) - return -EFAULT; - - if (get_user(data, &sgio32->dxferp)) - return -EFAULT; - dxferp = compat_ptr(data); - if (iovec_count) { - if (sg_build_iovec(sgio, dxferp, iovec_count)) - return -EFAULT; - } else { - if (put_user(dxferp, &sgio->dxferp)) - return -EFAULT; - } - - { - unsigned char __user *cmdp; - unsigned char __user *sbp; - - if (get_user(data, &sgio32->cmdp)) - return -EFAULT; - cmdp = compat_ptr(data); - - if (get_user(data, &sgio32->sbp)) - return -EFAULT; - sbp = compat_ptr(data); - - if (put_user(cmdp, &sgio->cmdp) || - put_user(sbp, &sgio->sbp)) - return -EFAULT; - } - - if (copy_in_user(&sgio->timeout, &sgio32->timeout, - 3 * sizeof(int))) - return -EFAULT; - - if (get_user(data, &sgio32->usr_ptr)) - return -EFAULT; - if (put_user(compat_ptr(data), &sgio->usr_ptr)) - return -EFAULT; - - err = nvme_sg_io(ns, sgio); - if (err >= 0) { - void __user *datap; - - if (copy_in_user(&sgio32->pack_id, &sgio->pack_id, - sizeof(int)) || - get_user(datap, &sgio->usr_ptr) || - put_user((u32)(unsigned long)datap, - &sgio32->usr_ptr) || - copy_in_user(&sgio32->status, &sgio->status, - (4 * sizeof(unsigned char)) + - (2 * sizeof(unsigned short)) + - (3 * sizeof(int)))) - err = -EFAULT; - } - - return err; -} -#endif - int nvme_sg_get_version_num(int __user *ip) { return put_user(sg_version_num, ip); -- GitLab From 695a4fe79ffa70023238b6b2d4c20fe1a05288fb Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 27 Aug 2014 13:55:39 -0600 Subject: [PATCH 2973/9457] NVMe: Fix SG_IO status values We've only been setting the sg_io_hdr status values on SCSI commands that require an nvme command to complete the translation. The fields in the struct are output parameters, so we have to set them, otherwise user space will see whatever was in memory from before. In the case of compat SG_IO, this would reveal kernel memory. This fixes the issue by initializing the sg_io_hdr with successful status. Signed-off-by: Keith Busch Acked-by: Vishal Verma Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-scsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index dabafa6a64cb..046ae3321c5e 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -2915,6 +2915,14 @@ static int nvme_scsi_translate(struct nvme_ns *ns, struct sg_io_hdr *hdr) if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; + /* + * Prime the hdr with good status for scsi commands that don't require + * an nvme command for translation. + */ + retcode = nvme_trans_status_code(hdr, NVME_SC_SUCCESS); + if (retcode) + return retcode; + opcode = cmd[0]; switch (opcode) { -- GitLab From b4ff9c8ddb6f0cec99a53ab26a5aa2ed0162c472 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 29 Aug 2014 09:06:12 -0600 Subject: [PATCH 2974/9457] NVMe: Translate NVMe status to errno This returns a more appropriate error for the "capacity exceeded" status. In case other NVMe statuses have a better errno, this patch adds a convience function to translate an NVMe status code to an errno for IO commands, defaulting to the current -EIO. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 37f22b6bb009..3153692da288 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -450,6 +450,18 @@ static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) } } +static int nvme_error_status(u16 status) +{ + switch (status & 0x7ff) { + case NVME_SC_SUCCESS: + return 0; + case NVME_SC_CAP_EXCEEDED: + return -ENOSPC; + default: + return -EIO; + } +} + static void bio_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) { @@ -469,7 +481,7 @@ static void bio_completion(struct nvme_queue *nvmeq, void *ctx, wake_up(&nvmeq->sq_full); return; } - error = -EIO; + error = nvme_error_status(status); } if (iod->nents) { dma_unmap_sg(nvmeq->q_dmadev, iod->sg, iod->nents, -- GitLab From 7be50e93fbc281967589a04be5b1125539b0d0e2 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 10 Sep 2014 15:48:47 -0600 Subject: [PATCH 2975/9457] NVMe: Fix nvmeq waitqueue entry initialization We need to update the nvme queue's wait_queue_t entry during each initialization since the nvme_thread may be ended and restarted when the device is reset. If a device reset occurs during a large amount of buffered IO, it would take a lot longer to complete the outstanding requests due to the 1 second polling instead of waking up as completions occur. Fixes: b9afca3efb18a9b8392cb544a3e29e8b1168400c Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 3153692da288..16a886c2b73d 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1333,7 +1333,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, nvmeq->cq_head = 0; nvmeq->cq_phase = 1; init_waitqueue_head(&nvmeq->sq_full); - init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); bio_list_init(&nvmeq->sq_cong); INIT_LIST_HEAD(&nvmeq->iod_bio); nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; @@ -1373,6 +1372,8 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) struct nvme_dev *dev = nvmeq->dev; unsigned extra = nvme_queue_extra(nvmeq->q_depth); + spin_lock_irq(&nvmeq->q_lock); + init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); nvmeq->sq_tail = 0; nvmeq->cq_head = 0; nvmeq->cq_phase = 1; @@ -1382,6 +1383,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) nvme_cancel_ios(nvmeq, false); nvmeq->q_suspended = 0; dev->online_queues++; + spin_unlock_irq(&nvmeq->q_lock); } static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) @@ -1401,10 +1403,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) if (result < 0) goto release_sq; - spin_lock_irq(&nvmeq->q_lock); nvme_init_queue(nvmeq, qid); - spin_unlock_irq(&nvmeq->q_lock); - return result; release_sq: @@ -1543,9 +1542,6 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) if (result) return result; - spin_lock_irq(&nvmeq->q_lock); - nvme_init_queue(nvmeq, 0); - spin_unlock_irq(&nvmeq->q_lock); return result; } @@ -2762,6 +2758,7 @@ static int nvme_dev_start(struct nvme_dev *dev) result = nvme_thread ? PTR_ERR(nvme_thread) : -EINTR; goto disable; } + nvme_init_queue(raw_nvmeq(dev, 0), 0); result = nvme_setup_io_queues(dev); if (result) -- GitLab From 1b9dbf7fe02d85f70e8efc1c12c070206c0d5c5f Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 10 Sep 2014 17:21:14 -0600 Subject: [PATCH 2976/9457] NVMe: Add revalidate_disk callback This adds a callback to revalidate the disk and change its block size and capacity if needed. Before, a user would have to remove + rescan an entire device if they changed the logical block size using an NVMe Format or other vendor specific command; now they can just run something that issues the BLKRRPART IOCTL, like # hdparm -z /dev/nvmeXnY This can also be used in response to the 1.2 Spec's Namespace Attribute Change asynchronous event. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 16a886c2b73d..93ee55ee3775 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1853,6 +1853,35 @@ static int nvme_getgeo(struct block_device *bd, struct hd_geometry *geo) return 0; } +static int nvme_revalidate_disk(struct gendisk *disk) +{ + struct nvme_ns *ns = disk->private_data; + struct nvme_dev *dev = ns->dev; + struct nvme_id_ns *id; + dma_addr_t dma_addr; + int lbaf; + + id = dma_alloc_coherent(&dev->pci_dev->dev, 4096, &dma_addr, + GFP_KERNEL); + if (!id) { + dev_warn(&dev->pci_dev->dev, "%s: Memory alocation failure\n", + __func__); + return 0; + } + + if (nvme_identify(dev, ns->ns_id, 0, dma_addr)) + goto free; + + lbaf = id->flbas & 0xf; + ns->lba_shift = id->lbaf[lbaf].ds; + + blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); + set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); + free: + dma_free_coherent(&dev->pci_dev->dev, 4096, id, dma_addr); + return 0; +} + static const struct block_device_operations nvme_fops = { .owner = THIS_MODULE, .ioctl = nvme_ioctl, @@ -1860,6 +1889,7 @@ static const struct block_device_operations nvme_fops = { .open = nvme_open, .release = nvme_release, .getgeo = nvme_getgeo, + .revalidate_disk= nvme_revalidate_disk, }; static void nvme_resubmit_iods(struct nvme_queue *nvmeq) -- GitLab From 7963e521811ed19396d47793cc77d87c643ab891 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 12 Sep 2014 16:07:20 -0600 Subject: [PATCH 2977/9457] NVMe: Passthrough IOCTL for IO commands The NVME_IOCTL_SUBMIT_IO only works for IO commands with block data transfers and isn't usable for other NVMe commands like flush, data set management, or any sort of vendor unique command. The NVME_IOCTL_ADMIN_CMD, however, can easily be modified to accept arbitrary IO commands in addition to arbitrary admin commands without breaking backward compatibility. This patch just adds a new IOCTL to distinguish if the driver should submit the command on an IO or Admin queue. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 17 ++++++++++++----- include/uapi/linux/nvme.h | 5 ++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 93ee55ee3775..70be3a151eb7 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1732,10 +1732,10 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) return status; } -static int nvme_user_admin_cmd(struct nvme_dev *dev, - struct nvme_admin_cmd __user *ucmd) +static int nvme_user_cmd(struct nvme_dev *dev, + struct nvme_passthru_cmd __user *ucmd, bool ioq) { - struct nvme_admin_cmd cmd; + struct nvme_passthru_cmd cmd; struct nvme_command c; int status, length; struct nvme_iod *uninitialized_var(iod); @@ -1774,6 +1774,9 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev, ADMIN_TIMEOUT; if (length != cmd.data_len) status = -ENOMEM; + else if (ioq) + status = nvme_submit_sync_cmd(dev, this_cpu_read(*dev->io_queue), &c, + &cmd.result, timeout); else status = nvme_submit_sync_cmd(dev, 0, &c, &cmd.result, timeout); @@ -1799,7 +1802,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, force_successful_syscall_return(); return ns->ns_id; case NVME_IOCTL_ADMIN_CMD: - return nvme_user_admin_cmd(ns->dev, (void __user *)arg); + return nvme_user_cmd(ns->dev, (void __user *)arg, false); + case NVME_IOCTL_IO_CMD: + return nvme_user_cmd(ns->dev, (void __user *)arg, true); case NVME_IOCTL_SUBMIT_IO: return nvme_submit_io(ns, (void __user *)arg); case SG_GET_VERSION_NUM: @@ -2743,7 +2748,9 @@ static long nvme_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg) struct nvme_dev *dev = f->private_data; switch (cmd) { case NVME_IOCTL_ADMIN_CMD: - return nvme_user_admin_cmd(dev, (void __user *)arg); + return nvme_user_cmd(dev, (void __user *)arg, false); + case NVME_IOCTL_IO_CMD: + return nvme_user_cmd(dev, (void __user *)arg, true); default: return -ENOTTY; } diff --git a/include/uapi/linux/nvme.h b/include/uapi/linux/nvme.h index 134518b0100b..97106556408f 100644 --- a/include/uapi/linux/nvme.h +++ b/include/uapi/linux/nvme.h @@ -503,7 +503,7 @@ struct nvme_user_io { __u16 appmask; }; -struct nvme_admin_cmd { +struct nvme_passthru_cmd { __u8 opcode; __u8 flags; __u16 rsvd1; @@ -524,8 +524,11 @@ struct nvme_admin_cmd { __u32 result; }; +#define nvme_admin_cmd nvme_passthru_cmd + #define NVME_IOCTL_ID _IO('N', 0x40) #define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd) #define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io) +#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd) #endif /* _UAPI_LINUX_NVME_H */ -- GitLab From 60e0545cc92ce4172c7069d559568717f64af332 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 15 Sep 2014 14:08:38 -0600 Subject: [PATCH 2978/9457] NVMe: Updates for 1.1 spec Updating commands and structures for NVMe 1.1 updates, mostly for nvme reservations. There are no additional in-kernel uses, but this is for the uapi. While doing this, I noticed that the software progress features was using the wrong value, so updating that value as well. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- include/uapi/linux/nvme.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/nvme.h b/include/uapi/linux/nvme.h index 97106556408f..26386cf3db44 100644 --- a/include/uapi/linux/nvme.h +++ b/include/uapi/linux/nvme.h @@ -181,6 +181,22 @@ enum { NVME_LBART_ATTRIB_HIDE = 1 << 1, }; +struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 resv5[2]; + __u8 ptpls; + __u8 resv10[13]; + struct { + __le16 cntlid; + __u8 rcsts; + __u8 resv3[5]; + __le64 hostid; + __le64 rkey; + } regctl_ds[]; +}; + /* I/O commands */ enum nvme_opcode { @@ -189,7 +205,12 @@ enum nvme_opcode { nvme_cmd_read = 0x02, nvme_cmd_write_uncor = 0x04, nvme_cmd_compare = 0x05, + nvme_cmd_write_zeroes = 0x08, nvme_cmd_dsm = 0x09, + nvme_cmd_resv_register = 0x0d, + nvme_cmd_resv_report = 0x0e, + nvme_cmd_resv_acquire = 0x11, + nvme_cmd_resv_release = 0x15, }; struct nvme_common_command { @@ -305,7 +326,11 @@ enum { NVME_FEAT_IRQ_CONFIG = 0x09, NVME_FEAT_WRITE_ATOMIC = 0x0a, NVME_FEAT_ASYNC_EVENT = 0x0b, - NVME_FEAT_SW_PROGRESS = 0x0c, + NVME_FEAT_AUTO_PST = 0x0c, + NVME_FEAT_SW_PROGRESS = 0x80, + NVME_FEAT_HOST_ID = 0x81, + NVME_FEAT_RESV_MASK = 0x82, + NVME_FEAT_RESV_PERSIST = 0x83, NVME_LOG_ERROR = 0x01, NVME_LOG_SMART = 0x02, NVME_LOG_FW_SLOT = 0x03, -- GitLab From 387caa5a2b11ecb1abbbec8ef9d798f757ba3e5f Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 22 Sep 2014 13:46:19 -0600 Subject: [PATCH 2979/9457] NVMe: Fix device probe waiting on kthread If we ever do parallel device probing, we need to wake up all processes waiting for nvme kthread to start, not just one. This is currently serialized so the bug is not reachable today, but fixing this anyway in the hopes we implement parallel or asynchronous probe in the future. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 70be3a151eb7..0196fce0ddf5 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2787,7 +2787,7 @@ static int nvme_dev_start(struct nvme_dev *dev) if (start_thread) { nvme_thread = kthread_run(nvme_kthread, NULL, "nvme"); - wake_up(&nvme_kthread_wait); + wake_up_all(&nvme_kthread_wait); } else wait_event_killable(nvme_kthread_wait, nvme_thread); -- GitLab From 5940c8578fe720afbf4ef041bad0d72a101f1d88 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 4 Nov 2014 13:18:10 -0700 Subject: [PATCH 2980/9457] NVMe: Clear QUEUE_FLAG_STACKABLE The nvme namespace request_queue's flags are initialized to QUEUE_FLAG_DEFAULT, which currently sets QUEUE_FLAG_STACKABLE. The device-mapper indicates this flag means the block driver is requset based, though this driver is bio-based and problems will occur if an nvme namespace is used with a request based dm device. This patch clears the stackable flag. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 0196fce0ddf5..8fffc68c74eb 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2030,6 +2030,7 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, if (!ns->queue) goto out_free_ns; ns->queue->queue_flags = QUEUE_FLAG_DEFAULT; + queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue); queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, ns->queue); -- GitLab From 45c3cbb18462b76848476da596b8c1647929ab1f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 3 Nov 2014 18:28:39 -0300 Subject: [PATCH 2981/9457] [media] si2168: do not print device is warm every-time when opened It repeated "found a 'Silicon Labs Si2168' in warm state" everytime when device was opened. Message is aimed to point out firmware is downloaded, up and running. So print it only in case firmware download is performed. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 1cd93be281ed..7bac74835d73 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -498,10 +498,9 @@ static int si2168_init(struct dvb_frontend *fe) s->fw_loaded = true; -warm: dev_info(&s->client->dev, "found a '%s' in warm state\n", si2168_ops.info.name); - +warm: s->active = true; return 0; -- GitLab From 9e60352cf83faaba57f99f6960b545687b8bbb20 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 3 Oct 2014 11:15:47 -0600 Subject: [PATCH 2982/9457] NVMe: Do not open disks that are being deleted It is possible the block layer will request to open a block device after the driver deleted it. Subsequent releases will cause a double free, or the disk's private_data is pointing to freed memory. This patch protects the driver's freed disks from being opened and accessed: the nvme namespaces are freed only when the device's refcount is 0, so at that moment there were no active openers and no more should be allowed, and it is safe to clear the disk's private_data that is about to be freed. Signed-off-by: Keith Busch Reported-by: Henry Chow Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 8fffc68c74eb..fb21d365efb5 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1832,11 +1832,18 @@ static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, static int nvme_open(struct block_device *bdev, fmode_t mode) { - struct nvme_ns *ns = bdev->bd_disk->private_data; - struct nvme_dev *dev = ns->dev; + int ret = 0; + struct nvme_ns *ns; - kref_get(&dev->kref); - return 0; + spin_lock(&dev_list_lock); + ns = bdev->bd_disk->private_data; + if (!ns) + ret = -ENXIO; + else if (!kref_get_unless_zero(&ns->dev->kref)) + ret = -ENXIO; + spin_unlock(&dev_list_lock); + + return ret; } static void nvme_free_dev(struct kref *kref); @@ -2711,6 +2718,11 @@ static void nvme_free_namespaces(struct nvme_dev *dev) list_for_each_entry_safe(ns, next, &dev->namespaces, list) { list_del(&ns->list); + + spin_lock(&dev_list_lock); + ns->disk->private_data = NULL; + spin_unlock(&dev_list_lock); + put_disk(ns->disk); kfree(ns); } -- GitLab From 9dbbfab7d54109626031bf3bc476fb1804113970 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 6 Oct 2014 15:23:06 -0600 Subject: [PATCH 2983/9457] NVMe: Do not over allocate for discard requests Discard requests are often for very large ranges. The discard size is not representative of the data transfer size so we don't need to allocate for such a large prp list. This patch requests allocating only enough for the memory needed for the data transfer and saves a little over 8k of memory per max discard request. Signed-off-by: Keith Busch Reported-by: Paul Grabinar Signed-off-by: Matthew Wilcox Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index fb21d365efb5..c70eff3673d0 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -763,11 +763,13 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, struct nvme_iod *iod; int psegs = bio_phys_segments(ns->queue, bio); int result; + unsigned size = !(bio->bi_rw & REQ_DISCARD) ? bio->bi_iter.bi_size : + sizeof(struct nvme_dsm_range); if ((bio->bi_rw & REQ_FLUSH) && psegs) return nvme_split_flush_data(nvmeq, bio); - iod = nvme_alloc_iod(psegs, bio->bi_iter.bi_size, ns->dev, GFP_ATOMIC); + iod = nvme_alloc_iod(psegs, size, ns->dev, GFP_ATOMIC); if (!iod) return -ENOMEM; -- GitLab From a4aea5623d4a54682b6ff5c18196d7802f3e478f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Bj=C3=B8rling?= Date: Tue, 4 Nov 2014 08:20:14 -0700 Subject: [PATCH 2984/9457] NVMe: Convert to blk-mq This converts the NVMe driver to a blk-mq request-based driver. The NVMe driver is currently bio-based and implements queue logic within itself. By using blk-mq, a lot of these responsibilities can be moved and simplified. The patch is divided into the following blocks: * Per-command data and cmdid have been moved into the struct request field. The cmdid_data can be retrieved using blk_mq_rq_to_pdu() and id maintenance are now handled by blk-mq through the rq->tag field. * The logic for splitting bio's has been moved into the blk-mq layer. The driver instead notifies the block layer about limited gap support in SG lists. * blk-mq handles timeouts and is reimplemented within nvme_timeout(). This both includes abort handling and command cancelation. * Assignment of nvme queues to CPUs are replaced with the blk-mq version. The current blk-mq strategy is to assign the number of mapped queues and CPUs to provide synergy, while the nvme driver assign as many nvme hw queues as possible. This can be implemented in blk-mq if needed. * NVMe queues are merged with the tags structure of blk-mq. * blk-mq takes care of setup/teardown of nvme queues and guards invalid accesses. Therefore, RCU-usage for nvme queues can be removed. * IO tracing and accounting are handled by blk-mq and therefore removed. * Queue suspension logic is replaced with the logic from the block layer. Contributions in this patch from: Sam Bradshaw Jens Axboe Keith Busch Robert Nelson Acked-by: Keith Busch Acked-by: Jens Axboe Updated for new ->queue_rq() prototype. Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 1366 +++++++++++++++---------------------- drivers/block/nvme-scsi.c | 8 +- include/linux/nvme.h | 15 +- 3 files changed, 570 insertions(+), 819 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index c70eff3673d0..39050a3d10fd 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -13,9 +13,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -42,9 +41,8 @@ #include #include -#include - #define NVME_Q_DEPTH 1024 +#define NVME_AQ_DEPTH 64 #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) #define ADMIN_TIMEOUT (admin_timeout * HZ) @@ -81,10 +79,12 @@ static wait_queue_head_t nvme_kthread_wait; static struct notifier_block nvme_nb; static void nvme_reset_failed_dev(struct work_struct *ws); +static int nvme_process_cq(struct nvme_queue *nvmeq); struct async_cmd_info { struct kthread_work work; struct kthread_worker *worker; + struct request *req; u32 result; int status; void *ctx; @@ -104,10 +104,6 @@ struct nvme_queue { volatile struct nvme_completion *cqes; dma_addr_t sq_dma_addr; dma_addr_t cq_dma_addr; - wait_queue_head_t sq_full; - wait_queue_t sq_cong_wait; - struct bio_list sq_cong; - struct list_head iod_bio; u32 __iomem *q_db; u16 q_depth; u16 cq_vector; @@ -117,10 +113,8 @@ struct nvme_queue { u16 qid; u8 cq_phase; u8 cqe_seen; - u8 q_suspended; - cpumask_var_t cpu_mask; struct async_cmd_info cmdinfo; - unsigned long cmdid_data[]; + struct blk_mq_hw_ctx *hctx; }; /* @@ -148,62 +142,72 @@ typedef void (*nvme_completion_fn)(struct nvme_queue *, void *, struct nvme_cmd_info { nvme_completion_fn fn; void *ctx; - unsigned long timeout; int aborted; + struct nvme_queue *nvmeq; }; -static struct nvme_cmd_info *nvme_cmd_info(struct nvme_queue *nvmeq) +static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int hctx_idx) { - return (void *)&nvmeq->cmdid_data[BITS_TO_LONGS(nvmeq->q_depth)]; + struct nvme_dev *dev = data; + struct nvme_queue *nvmeq = dev->queues[0]; + + WARN_ON(nvmeq->hctx); + nvmeq->hctx = hctx; + hctx->driver_data = nvmeq; + return 0; } -static unsigned nvme_queue_extra(int depth) +static int nvme_admin_init_request(void *data, struct request *req, + unsigned int hctx_idx, unsigned int rq_idx, + unsigned int numa_node) { - return DIV_ROUND_UP(depth, 8) + (depth * sizeof(struct nvme_cmd_info)); + struct nvme_dev *dev = data; + struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = dev->queues[0]; + + BUG_ON(!nvmeq); + cmd->nvmeq = nvmeq; + return 0; } -/** - * alloc_cmdid() - Allocate a Command ID - * @nvmeq: The queue that will be used for this command - * @ctx: A pointer that will be passed to the handler - * @handler: The function to call on completion - * - * Allocate a Command ID for a queue. The data passed in will - * be passed to the completion handler. This is implemented by using - * the bottom two bits of the ctx pointer to store the handler ID. - * Passing in a pointer that's not 4-byte aligned will cause a BUG. - * We can change this if it becomes a problem. - * - * May be called with local interrupts disabled and the q_lock held, - * or with interrupts enabled and no locks held. - */ -static int alloc_cmdid(struct nvme_queue *nvmeq, void *ctx, - nvme_completion_fn handler, unsigned timeout) +static int nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int hctx_idx) { - int depth = nvmeq->q_depth - 1; - struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); - int cmdid; + struct nvme_dev *dev = data; + struct nvme_queue *nvmeq = dev->queues[ + (hctx_idx % dev->queue_count) + 1]; - do { - cmdid = find_first_zero_bit(nvmeq->cmdid_data, depth); - if (cmdid >= depth) - return -EBUSY; - } while (test_and_set_bit(cmdid, nvmeq->cmdid_data)); + if (!nvmeq->hctx) + nvmeq->hctx = hctx; + + /* nvmeq queues are shared between namespaces. We assume here that + * blk-mq map the tags so they match up with the nvme queue tags. */ + WARN_ON(nvmeq->hctx->tags != hctx->tags); - info[cmdid].fn = handler; - info[cmdid].ctx = ctx; - info[cmdid].timeout = jiffies + timeout; - info[cmdid].aborted = 0; - return cmdid; + hctx->driver_data = nvmeq; + return 0; } -static int alloc_cmdid_killable(struct nvme_queue *nvmeq, void *ctx, - nvme_completion_fn handler, unsigned timeout) +static int nvme_init_request(void *data, struct request *req, + unsigned int hctx_idx, unsigned int rq_idx, + unsigned int numa_node) { - int cmdid; - wait_event_killable(nvmeq->sq_full, - (cmdid = alloc_cmdid(nvmeq, ctx, handler, timeout)) >= 0); - return (cmdid < 0) ? -EINTR : cmdid; + struct nvme_dev *dev = data; + struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = dev->queues[hctx_idx + 1]; + + BUG_ON(!nvmeq); + cmd->nvmeq = nvmeq; + return 0; +} + +static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx, + nvme_completion_fn handler) +{ + cmd->fn = handler; + cmd->ctx = ctx; + cmd->aborted = 0; } /* Special values must be less than 0x1000 */ @@ -211,18 +215,12 @@ static int alloc_cmdid_killable(struct nvme_queue *nvmeq, void *ctx, #define CMD_CTX_CANCELLED (0x30C + CMD_CTX_BASE) #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) -#define CMD_CTX_ABORT (0x318 + CMD_CTX_BASE) -#define CMD_CTX_ASYNC (0x31C + CMD_CTX_BASE) static void special_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) { if (ctx == CMD_CTX_CANCELLED) return; - if (ctx == CMD_CTX_ABORT) { - ++nvmeq->dev->abort_limit; - return; - } if (ctx == CMD_CTX_COMPLETED) { dev_warn(nvmeq->q_dmadev, "completed id %d twice on queue %d\n", @@ -235,110 +233,89 @@ static void special_completion(struct nvme_queue *nvmeq, void *ctx, cqe->command_id, le16_to_cpup(&cqe->sq_id)); return; } - if (ctx == CMD_CTX_ASYNC) { - u32 result = le32_to_cpup(&cqe->result); - u16 status = le16_to_cpup(&cqe->status) >> 1; - - if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ) - ++nvmeq->dev->event_limit; - if (status == NVME_SC_SUCCESS) - dev_warn(nvmeq->q_dmadev, - "async event result %08x\n", result); - return; - } - dev_warn(nvmeq->q_dmadev, "Unknown special completion %p\n", ctx); } -static void async_completion(struct nvme_queue *nvmeq, void *ctx, - struct nvme_completion *cqe) -{ - struct async_cmd_info *cmdinfo = ctx; - cmdinfo->result = le32_to_cpup(&cqe->result); - cmdinfo->status = le16_to_cpup(&cqe->status) >> 1; - queue_kthread_work(cmdinfo->worker, &cmdinfo->work); -} - -/* - * Called with local interrupts disabled and the q_lock held. May not sleep. - */ -static void *free_cmdid(struct nvme_queue *nvmeq, int cmdid, - nvme_completion_fn *fn) +static void *cancel_cmd_info(struct nvme_cmd_info *cmd, nvme_completion_fn *fn) { void *ctx; - struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); - if (cmdid >= nvmeq->q_depth || !info[cmdid].fn) { - if (fn) - *fn = special_completion; - return CMD_CTX_INVALID; - } if (fn) - *fn = info[cmdid].fn; - ctx = info[cmdid].ctx; - info[cmdid].fn = special_completion; - info[cmdid].ctx = CMD_CTX_COMPLETED; - clear_bit(cmdid, nvmeq->cmdid_data); - wake_up(&nvmeq->sq_full); + *fn = cmd->fn; + ctx = cmd->ctx; + cmd->fn = special_completion; + cmd->ctx = CMD_CTX_CANCELLED; return ctx; } -static void *cancel_cmdid(struct nvme_queue *nvmeq, int cmdid, - nvme_completion_fn *fn) +static void async_req_completion(struct nvme_queue *nvmeq, void *ctx, + struct nvme_completion *cqe) { - void *ctx; - struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); - if (fn) - *fn = info[cmdid].fn; - ctx = info[cmdid].ctx; - info[cmdid].fn = special_completion; - info[cmdid].ctx = CMD_CTX_CANCELLED; - return ctx; -} + struct request *req = ctx; -static struct nvme_queue *raw_nvmeq(struct nvme_dev *dev, int qid) -{ - return rcu_dereference_raw(dev->queues[qid]); + u32 result = le32_to_cpup(&cqe->result); + u16 status = le16_to_cpup(&cqe->status) >> 1; + + if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ) + ++nvmeq->dev->event_limit; + if (status == NVME_SC_SUCCESS) + dev_warn(nvmeq->q_dmadev, + "async event result %08x\n", result); + + blk_put_request(req); } -static struct nvme_queue *get_nvmeq(struct nvme_dev *dev) __acquires(RCU) +static void abort_completion(struct nvme_queue *nvmeq, void *ctx, + struct nvme_completion *cqe) { - struct nvme_queue *nvmeq; - unsigned queue_id = get_cpu_var(*dev->io_queue); + struct request *req = ctx; + + u16 status = le16_to_cpup(&cqe->status) >> 1; + u32 result = le32_to_cpup(&cqe->result); - rcu_read_lock(); - nvmeq = rcu_dereference(dev->queues[queue_id]); - if (nvmeq) - return nvmeq; + blk_put_request(req); - rcu_read_unlock(); - put_cpu_var(*dev->io_queue); - return NULL; + dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result); + ++nvmeq->dev->abort_limit; } -static void put_nvmeq(struct nvme_queue *nvmeq) __releases(RCU) +static void async_completion(struct nvme_queue *nvmeq, void *ctx, + struct nvme_completion *cqe) { - rcu_read_unlock(); - put_cpu_var(nvmeq->dev->io_queue); + struct async_cmd_info *cmdinfo = ctx; + cmdinfo->result = le32_to_cpup(&cqe->result); + cmdinfo->status = le16_to_cpup(&cqe->status) >> 1; + queue_kthread_work(cmdinfo->worker, &cmdinfo->work); + blk_put_request(cmdinfo->req); } -static struct nvme_queue *lock_nvmeq(struct nvme_dev *dev, int q_idx) - __acquires(RCU) +static inline struct nvme_cmd_info *get_cmd_from_tag(struct nvme_queue *nvmeq, + unsigned int tag) { - struct nvme_queue *nvmeq; - - rcu_read_lock(); - nvmeq = rcu_dereference(dev->queues[q_idx]); - if (nvmeq) - return nvmeq; + struct blk_mq_hw_ctx *hctx = nvmeq->hctx; + struct request *req = blk_mq_tag_to_rq(hctx->tags, tag); - rcu_read_unlock(); - return NULL; + return blk_mq_rq_to_pdu(req); } -static void unlock_nvmeq(struct nvme_queue *nvmeq) __releases(RCU) +/* + * Called with local interrupts disabled and the q_lock held. May not sleep. + */ +static void *nvme_finish_cmd(struct nvme_queue *nvmeq, int tag, + nvme_completion_fn *fn) { - rcu_read_unlock(); + struct nvme_cmd_info *cmd = get_cmd_from_tag(nvmeq, tag); + void *ctx; + if (tag >= nvmeq->q_depth) { + *fn = special_completion; + return CMD_CTX_INVALID; + } + if (fn) + *fn = cmd->fn; + ctx = cmd->ctx; + cmd->fn = special_completion; + cmd->ctx = CMD_CTX_COMPLETED; + return ctx; } /** @@ -348,26 +325,29 @@ static void unlock_nvmeq(struct nvme_queue *nvmeq) __releases(RCU) * * Safe to use from interrupt context */ -static int nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd) +static int __nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd) { - unsigned long flags; - u16 tail; - spin_lock_irqsave(&nvmeq->q_lock, flags); - if (nvmeq->q_suspended) { - spin_unlock_irqrestore(&nvmeq->q_lock, flags); - return -EBUSY; - } - tail = nvmeq->sq_tail; + u16 tail = nvmeq->sq_tail; + memcpy(&nvmeq->sq_cmds[tail], cmd, sizeof(*cmd)); if (++tail == nvmeq->q_depth) tail = 0; writel(tail, nvmeq->q_db); nvmeq->sq_tail = tail; - spin_unlock_irqrestore(&nvmeq->q_lock, flags); return 0; } +static int nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd) +{ + unsigned long flags; + int ret; + spin_lock_irqsave(&nvmeq->q_lock, flags); + ret = __nvme_submit_cmd(nvmeq, cmd); + spin_unlock_irqrestore(&nvmeq->q_lock, flags); + return ret; +} + static __le64 **iod_list(struct nvme_iod *iod) { return ((void *)iod) + iod->offset; @@ -397,7 +377,6 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, struct nvme_dev *dev, gfp_t gfp) iod->length = nbytes; iod->nents = 0; iod->first_dma = 0ULL; - iod->start_time = jiffies; } return iod; @@ -421,35 +400,6 @@ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod) kfree(iod); } -static void nvme_start_io_acct(struct bio *bio) -{ - struct gendisk *disk = bio->bi_bdev->bd_disk; - if (blk_queue_io_stat(disk->queue)) { - const int rw = bio_data_dir(bio); - int cpu = part_stat_lock(); - part_round_stats(cpu, &disk->part0); - part_stat_inc(cpu, &disk->part0, ios[rw]); - part_stat_add(cpu, &disk->part0, sectors[rw], - bio_sectors(bio)); - part_inc_in_flight(&disk->part0, rw); - part_stat_unlock(); - } -} - -static void nvme_end_io_acct(struct bio *bio, unsigned long start_time) -{ - struct gendisk *disk = bio->bi_bdev->bd_disk; - if (blk_queue_io_stat(disk->queue)) { - const int rw = bio_data_dir(bio); - unsigned long duration = jiffies - start_time; - int cpu = part_stat_lock(); - part_stat_add(cpu, &disk->part0, ticks[rw], duration); - part_round_stats(cpu, &disk->part0); - part_dec_in_flight(&disk->part0, rw); - part_stat_unlock(); - } -} - static int nvme_error_status(u16 status) { switch (status & 0x7ff) { @@ -462,36 +412,37 @@ static int nvme_error_status(u16 status) } } -static void bio_completion(struct nvme_queue *nvmeq, void *ctx, +static void req_completion(struct nvme_queue *nvmeq, void *ctx, struct nvme_completion *cqe) { struct nvme_iod *iod = ctx; - struct bio *bio = iod->private; + struct request *req = iod->private; + struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req); + u16 status = le16_to_cpup(&cqe->status) >> 1; - int error = 0; if (unlikely(status)) { - if (!(status & NVME_SC_DNR || - bio->bi_rw & REQ_FAILFAST_MASK) && - (jiffies - iod->start_time) < IOD_TIMEOUT) { - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, - &nvmeq->sq_cong_wait); - list_add_tail(&iod->node, &nvmeq->iod_bio); - wake_up(&nvmeq->sq_full); + if (!(status & NVME_SC_DNR || blk_noretry_request(req)) + && (jiffies - req->start_time) < req->timeout) { + blk_mq_requeue_request(req); + blk_mq_kick_requeue_list(req->q); return; } - error = nvme_error_status(status); - } - if (iod->nents) { - dma_unmap_sg(nvmeq->q_dmadev, iod->sg, iod->nents, - bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - nvme_end_io_acct(bio, iod->start_time); - } + req->errors = nvme_error_status(status); + } else + req->errors = 0; + + if (cmd_rq->aborted) + dev_warn(&nvmeq->dev->pci_dev->dev, + "completing aborted command with status:%04x\n", + status); + + if (iod->nents) + dma_unmap_sg(&nvmeq->dev->pci_dev->dev, iod->sg, iod->nents, + rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); nvme_free_iod(nvmeq->dev, iod); - trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio, error); - bio_endio(bio, error); + blk_mq_complete_request(req); } /* length is in bytes. gfp flags indicates whether we may sleep. */ @@ -574,88 +525,25 @@ int nvme_setup_prps(struct nvme_dev *dev, struct nvme_iod *iod, int total_len, return total_len; } -static int nvme_split_and_submit(struct bio *bio, struct nvme_queue *nvmeq, - int len) -{ - struct bio *split = bio_split(bio, len >> 9, GFP_ATOMIC, NULL); - if (!split) - return -ENOMEM; - - trace_block_split(bdev_get_queue(bio->bi_bdev), bio, - split->bi_iter.bi_sector); - bio_chain(split, bio); - - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, &nvmeq->sq_cong_wait); - bio_list_add(&nvmeq->sq_cong, split); - bio_list_add(&nvmeq->sq_cong, bio); - wake_up(&nvmeq->sq_full); - - return 0; -} - -/* NVMe scatterlists require no holes in the virtual address */ -#define BIOVEC_NOT_VIRT_MERGEABLE(vec1, vec2) ((vec2)->bv_offset || \ - (((vec1)->bv_offset + (vec1)->bv_len) % PAGE_SIZE)) - -static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod, - struct bio *bio, enum dma_data_direction dma_dir, int psegs) -{ - struct bio_vec bvec, bvprv; - struct bvec_iter iter; - struct scatterlist *sg = NULL; - int length = 0, nsegs = 0, split_len = bio->bi_iter.bi_size; - int first = 1; - - if (nvmeq->dev->stripe_size) - split_len = nvmeq->dev->stripe_size - - ((bio->bi_iter.bi_sector << 9) & - (nvmeq->dev->stripe_size - 1)); - - sg_init_table(iod->sg, psegs); - bio_for_each_segment(bvec, bio, iter) { - if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) { - sg->length += bvec.bv_len; - } else { - if (!first && BIOVEC_NOT_VIRT_MERGEABLE(&bvprv, &bvec)) - return nvme_split_and_submit(bio, nvmeq, - length); - - sg = sg ? sg + 1 : iod->sg; - sg_set_page(sg, bvec.bv_page, - bvec.bv_len, bvec.bv_offset); - nsegs++; - } - - if (split_len - length < bvec.bv_len) - return nvme_split_and_submit(bio, nvmeq, split_len); - length += bvec.bv_len; - bvprv = bvec; - first = 0; - } - iod->nents = nsegs; - sg_mark_end(sg); - if (dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir) == 0) - return -ENOMEM; - - BUG_ON(length != bio->bi_iter.bi_size); - return length; -} - -static int nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns, - struct bio *bio, struct nvme_iod *iod, int cmdid) +/* + * We reuse the small pool to allocate the 16-byte range here as it is not + * worth having a special pool for these or additional cases to handle freeing + * the iod. + */ +static void nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns, + struct request *req, struct nvme_iod *iod) { struct nvme_dsm_range *range = (struct nvme_dsm_range *)iod_list(iod)[0]; struct nvme_command *cmnd = &nvmeq->sq_cmds[nvmeq->sq_tail]; range->cattr = cpu_to_le32(0); - range->nlb = cpu_to_le32(bio->bi_iter.bi_size >> ns->lba_shift); - range->slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_iter.bi_sector)); + range->nlb = cpu_to_le32(blk_rq_bytes(req) >> ns->lba_shift); + range->slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req))); memset(cmnd, 0, sizeof(*cmnd)); cmnd->dsm.opcode = nvme_cmd_dsm; - cmnd->dsm.command_id = cmdid; + cmnd->dsm.command_id = req->tag; cmnd->dsm.nsid = cpu_to_le32(ns->ns_id); cmnd->dsm.prp1 = cpu_to_le64(iod->first_dma); cmnd->dsm.nr = 0; @@ -664,11 +552,9 @@ static int nvme_submit_discard(struct nvme_queue *nvmeq, struct nvme_ns *ns, if (++nvmeq->sq_tail == nvmeq->q_depth) nvmeq->sq_tail = 0; writel(nvmeq->sq_tail, nvmeq->q_db); - - return 0; } -static int nvme_submit_flush(struct nvme_queue *nvmeq, struct nvme_ns *ns, +static void nvme_submit_flush(struct nvme_queue *nvmeq, struct nvme_ns *ns, int cmdid) { struct nvme_command *cmnd = &nvmeq->sq_cmds[nvmeq->sq_tail]; @@ -681,49 +567,34 @@ static int nvme_submit_flush(struct nvme_queue *nvmeq, struct nvme_ns *ns, if (++nvmeq->sq_tail == nvmeq->q_depth) nvmeq->sq_tail = 0; writel(nvmeq->sq_tail, nvmeq->q_db); - - return 0; } -static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod) +static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod, + struct nvme_ns *ns) { - struct bio *bio = iod->private; - struct nvme_ns *ns = bio->bi_bdev->bd_disk->private_data; + struct request *req = iod->private; struct nvme_command *cmnd; - int cmdid; - u16 control; - u32 dsmgmt; + u16 control = 0; + u32 dsmgmt = 0; - cmdid = alloc_cmdid(nvmeq, iod, bio_completion, NVME_IO_TIMEOUT); - if (unlikely(cmdid < 0)) - return cmdid; - - if (bio->bi_rw & REQ_DISCARD) - return nvme_submit_discard(nvmeq, ns, bio, iod, cmdid); - if (bio->bi_rw & REQ_FLUSH) - return nvme_submit_flush(nvmeq, ns, cmdid); - - control = 0; - if (bio->bi_rw & REQ_FUA) + if (req->cmd_flags & REQ_FUA) control |= NVME_RW_FUA; - if (bio->bi_rw & (REQ_FAILFAST_DEV | REQ_RAHEAD)) + if (req->cmd_flags & (REQ_FAILFAST_DEV | REQ_RAHEAD)) control |= NVME_RW_LR; - dsmgmt = 0; - if (bio->bi_rw & REQ_RAHEAD) + if (req->cmd_flags & REQ_RAHEAD) dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH; cmnd = &nvmeq->sq_cmds[nvmeq->sq_tail]; memset(cmnd, 0, sizeof(*cmnd)); - cmnd->rw.opcode = bio_data_dir(bio) ? nvme_cmd_write : nvme_cmd_read; - cmnd->rw.command_id = cmdid; + cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read); + cmnd->rw.command_id = req->tag; cmnd->rw.nsid = cpu_to_le32(ns->ns_id); cmnd->rw.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); cmnd->rw.prp2 = cpu_to_le64(iod->first_dma); - cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, bio->bi_iter.bi_sector)); - cmnd->rw.length = - cpu_to_le16((bio->bi_iter.bi_size >> ns->lba_shift) - 1); + cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req))); + cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); cmnd->rw.control = cpu_to_le16(control); cmnd->rw.dsmgmt = cpu_to_le32(dsmgmt); @@ -734,47 +605,37 @@ static int nvme_submit_iod(struct nvme_queue *nvmeq, struct nvme_iod *iod) return 0; } -static int nvme_split_flush_data(struct nvme_queue *nvmeq, struct bio *bio) -{ - struct bio *split = bio_clone(bio, GFP_ATOMIC); - if (!split) - return -ENOMEM; - - split->bi_iter.bi_size = 0; - split->bi_phys_segments = 0; - bio->bi_rw &= ~REQ_FLUSH; - bio_chain(split, bio); - - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, &nvmeq->sq_cong_wait); - bio_list_add(&nvmeq->sq_cong, split); - bio_list_add(&nvmeq->sq_cong, bio); - wake_up_process(nvme_thread); - - return 0; -} - -/* - * Called with local interrupts disabled and the q_lock held. May not sleep. - */ -static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, - struct bio *bio) +static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { + struct nvme_ns *ns = hctx->queue->queuedata; + struct nvme_queue *nvmeq = hctx->driver_data; + struct request *req = bd->rq; + struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); struct nvme_iod *iod; - int psegs = bio_phys_segments(ns->queue, bio); - int result; - unsigned size = !(bio->bi_rw & REQ_DISCARD) ? bio->bi_iter.bi_size : + int psegs = req->nr_phys_segments; + int result = BLK_MQ_RQ_QUEUE_BUSY; + enum dma_data_direction dma_dir; + unsigned size = !(req->cmd_flags & REQ_DISCARD) ? blk_rq_bytes(req) : sizeof(struct nvme_dsm_range); - if ((bio->bi_rw & REQ_FLUSH) && psegs) - return nvme_split_flush_data(nvmeq, bio); + /* + * Requeued IO has already been prepped + */ + iod = req->special; + if (iod) + goto submit_iod; iod = nvme_alloc_iod(psegs, size, ns->dev, GFP_ATOMIC); if (!iod) - return -ENOMEM; + return result; + + iod->private = req; + req->special = iod; - iod->private = bio; - if (bio->bi_rw & REQ_DISCARD) { + nvme_set_info(cmd, iod, req_completion); + + if (req->cmd_flags & REQ_DISCARD) { void *range; /* * We reuse the small pool to allocate the 16-byte range here @@ -784,33 +645,45 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, range = dma_pool_alloc(nvmeq->dev->prp_small_pool, GFP_ATOMIC, &iod->first_dma); - if (!range) { - result = -ENOMEM; - goto free_iod; - } + if (!range) + goto finish_cmd; iod_list(iod)[0] = (__le64 *)range; iod->npages = 0; } else if (psegs) { - result = nvme_map_bio(nvmeq, iod, bio, - bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE, - psegs); - if (result <= 0) - goto free_iod; - if (nvme_setup_prps(nvmeq->dev, iod, result, GFP_ATOMIC) != - result) { - result = -ENOMEM; - goto free_iod; + dma_dir = rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + + sg_init_table(iod->sg, psegs); + iod->nents = blk_rq_map_sg(req->q, req, iod->sg); + if (!iod->nents) { + result = BLK_MQ_RQ_QUEUE_ERROR; + goto finish_cmd; } - nvme_start_io_acct(bio); - } - if (unlikely(nvme_submit_iod(nvmeq, iod))) { - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, &nvmeq->sq_cong_wait); - list_add_tail(&iod->node, &nvmeq->iod_bio); + + if (!dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir)) + goto finish_cmd; + + if (blk_rq_bytes(req) != nvme_setup_prps(nvmeq->dev, iod, + blk_rq_bytes(req), GFP_ATOMIC)) + goto finish_cmd; } - return 0; - free_iod: + blk_mq_start_request(req); + + submit_iod: + spin_lock_irq(&nvmeq->q_lock); + if (req->cmd_flags & REQ_DISCARD) + nvme_submit_discard(nvmeq, ns, req, iod); + else if (req->cmd_flags & REQ_FLUSH) + nvme_submit_flush(nvmeq, ns, req->tag); + else + nvme_submit_iod(nvmeq, iod, ns); + + nvme_process_cq(nvmeq); + spin_unlock_irq(&nvmeq->q_lock); + return BLK_MQ_RQ_QUEUE_OK; + + finish_cmd: + nvme_finish_cmd(nvmeq, req->tag, NULL); nvme_free_iod(nvmeq->dev, iod); return result; } @@ -833,8 +706,7 @@ static int nvme_process_cq(struct nvme_queue *nvmeq) head = 0; phase = !phase; } - - ctx = free_cmdid(nvmeq, cqe.command_id, &fn); + ctx = nvme_finish_cmd(nvmeq, cqe.command_id, &fn); fn(nvmeq, ctx, &cqe); } @@ -855,29 +727,13 @@ static int nvme_process_cq(struct nvme_queue *nvmeq) return 1; } -static void nvme_make_request(struct request_queue *q, struct bio *bio) +/* Admin queue isn't initialized as a request queue. If at some point this + * happens anyway, make sure to notify the user */ +static int nvme_admin_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) { - struct nvme_ns *ns = q->queuedata; - struct nvme_queue *nvmeq = get_nvmeq(ns->dev); - int result = -EBUSY; - - if (!nvmeq) { - bio_endio(bio, -EIO); - return; - } - - spin_lock_irq(&nvmeq->q_lock); - if (!nvmeq->q_suspended && bio_list_empty(&nvmeq->sq_cong)) - result = nvme_submit_bio_queue(nvmeq, ns, bio); - if (unlikely(result)) { - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, &nvmeq->sq_cong_wait); - bio_list_add(&nvmeq->sq_cong, bio); - } - - nvme_process_cq(nvmeq); - spin_unlock_irq(&nvmeq->q_lock); - put_nvmeq(nvmeq); + WARN_ON_ONCE(1); + return BLK_MQ_RQ_QUEUE_ERROR; } static irqreturn_t nvme_irq(int irq, void *data) @@ -901,10 +757,11 @@ static irqreturn_t nvme_irq_check(int irq, void *data) return IRQ_WAKE_THREAD; } -static void nvme_abort_command(struct nvme_queue *nvmeq, int cmdid) +static void nvme_abort_cmd_info(struct nvme_queue *nvmeq, struct nvme_cmd_info * + cmd_info) { spin_lock_irq(&nvmeq->q_lock); - cancel_cmdid(nvmeq, cmdid, NULL); + cancel_cmd_info(cmd_info, NULL); spin_unlock_irq(&nvmeq->q_lock); } @@ -927,45 +784,31 @@ static void sync_completion(struct nvme_queue *nvmeq, void *ctx, * Returns 0 on success. If the result is negative, it's a Linux error code; * if the result is positive, it's an NVM Express status code */ -static int nvme_submit_sync_cmd(struct nvme_dev *dev, int q_idx, - struct nvme_command *cmd, +static int nvme_submit_sync_cmd(struct request *req, struct nvme_command *cmd, u32 *result, unsigned timeout) { - int cmdid, ret; + int ret; struct sync_cmd_info cmdinfo; - struct nvme_queue *nvmeq; - - nvmeq = lock_nvmeq(dev, q_idx); - if (!nvmeq) - return -ENODEV; + struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = cmd_rq->nvmeq; cmdinfo.task = current; cmdinfo.status = -EINTR; - cmdid = alloc_cmdid(nvmeq, &cmdinfo, sync_completion, timeout); - if (cmdid < 0) { - unlock_nvmeq(nvmeq); - return cmdid; - } - cmd->common.command_id = cmdid; + cmd->common.command_id = req->tag; + + nvme_set_info(cmd_rq, &cmdinfo, sync_completion); set_current_state(TASK_KILLABLE); ret = nvme_submit_cmd(nvmeq, cmd); if (ret) { - free_cmdid(nvmeq, cmdid, NULL); - unlock_nvmeq(nvmeq); + nvme_finish_cmd(nvmeq, req->tag, NULL); set_current_state(TASK_RUNNING); - return ret; } - unlock_nvmeq(nvmeq); schedule_timeout(timeout); if (cmdinfo.status == -EINTR) { - nvmeq = lock_nvmeq(dev, q_idx); - if (nvmeq) { - nvme_abort_command(nvmeq, cmdid); - unlock_nvmeq(nvmeq); - } + nvme_abort_cmd_info(nvmeq, blk_mq_rq_to_pdu(req)); return -EINTR; } @@ -975,59 +818,99 @@ static int nvme_submit_sync_cmd(struct nvme_dev *dev, int q_idx, return cmdinfo.status; } -static int nvme_submit_async_cmd(struct nvme_queue *nvmeq, +static int nvme_submit_async_admin_req(struct nvme_dev *dev) +{ + struct nvme_queue *nvmeq = dev->queues[0]; + struct nvme_command c; + struct nvme_cmd_info *cmd_info; + struct request *req; + + req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_KERNEL, false); + if (!req) + return -ENOMEM; + + cmd_info = blk_mq_rq_to_pdu(req); + nvme_set_info(cmd_info, req, async_req_completion); + + memset(&c, 0, sizeof(c)); + c.common.opcode = nvme_admin_async_event; + c.common.command_id = req->tag; + + return __nvme_submit_cmd(nvmeq, &c); +} + +static int nvme_submit_admin_async_cmd(struct nvme_dev *dev, struct nvme_command *cmd, struct async_cmd_info *cmdinfo, unsigned timeout) { - int cmdid; + struct nvme_queue *nvmeq = dev->queues[0]; + struct request *req; + struct nvme_cmd_info *cmd_rq; - cmdid = alloc_cmdid_killable(nvmeq, cmdinfo, async_completion, timeout); - if (cmdid < 0) - return cmdid; + req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_KERNEL, false); + if (!req) + return -ENOMEM; + + req->timeout = timeout; + cmd_rq = blk_mq_rq_to_pdu(req); + cmdinfo->req = req; + nvme_set_info(cmd_rq, cmdinfo, async_completion); cmdinfo->status = -EINTR; - cmd->common.command_id = cmdid; + + cmd->common.command_id = req->tag; + return nvme_submit_cmd(nvmeq, cmd); } -int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, - u32 *result) +int __nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, + u32 *result, unsigned timeout) { - return nvme_submit_sync_cmd(dev, 0, cmd, result, ADMIN_TIMEOUT); + int res; + struct request *req; + + req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_KERNEL, false); + if (!req) + return -ENOMEM; + res = nvme_submit_sync_cmd(req, cmd, result, timeout); + blk_put_request(req); + return res; } -int nvme_submit_io_cmd(struct nvme_dev *dev, struct nvme_command *cmd, +int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, u32 *result) { - return nvme_submit_sync_cmd(dev, this_cpu_read(*dev->io_queue), cmd, - result, NVME_IO_TIMEOUT); + return __nvme_submit_admin_cmd(dev, cmd, result, ADMIN_TIMEOUT); } -static int nvme_submit_admin_cmd_async(struct nvme_dev *dev, - struct nvme_command *cmd, struct async_cmd_info *cmdinfo) +int nvme_submit_io_cmd(struct nvme_dev *dev, struct nvme_ns *ns, + struct nvme_command *cmd, u32 *result) { - return nvme_submit_async_cmd(raw_nvmeq(dev, 0), cmd, cmdinfo, - ADMIN_TIMEOUT); + int res; + struct request *req; + + req = blk_mq_alloc_request(ns->queue, WRITE, (GFP_KERNEL|__GFP_WAIT), + false); + if (!req) + return -ENOMEM; + res = nvme_submit_sync_cmd(req, cmd, result, NVME_IO_TIMEOUT); + blk_put_request(req); + return res; } static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) { - int status; struct nvme_command c; memset(&c, 0, sizeof(c)); c.delete_queue.opcode = opcode; c.delete_queue.qid = cpu_to_le16(id); - status = nvme_submit_admin_cmd(dev, &c, NULL); - if (status) - return -EIO; - return 0; + return nvme_submit_admin_cmd(dev, &c, NULL); } static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, struct nvme_queue *nvmeq) { - int status; struct nvme_command c; int flags = NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED; @@ -1039,16 +922,12 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, c.create_cq.cq_flags = cpu_to_le16(flags); c.create_cq.irq_vector = cpu_to_le16(nvmeq->cq_vector); - status = nvme_submit_admin_cmd(dev, &c, NULL); - if (status) - return -EIO; - return 0; + return nvme_submit_admin_cmd(dev, &c, NULL); } static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid, struct nvme_queue *nvmeq) { - int status; struct nvme_command c; int flags = NVME_QUEUE_PHYS_CONTIG | NVME_SQ_PRIO_MEDIUM; @@ -1060,10 +939,7 @@ static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid, c.create_sq.sq_flags = cpu_to_le16(flags); c.create_sq.cqid = cpu_to_le16(qid); - status = nvme_submit_admin_cmd(dev, &c, NULL); - if (status) - return -EIO; - return 0; + return nvme_submit_admin_cmd(dev, &c, NULL); } static int adapter_delete_cq(struct nvme_dev *dev, u16 cqid) @@ -1119,28 +995,27 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, } /** - * nvme_abort_cmd - Attempt aborting a command - * @cmdid: Command id of a timed out IO - * @queue: The queue with timed out IO + * nvme_abort_req - Attempt aborting a request * * Schedule controller reset if the command was already aborted once before and * still hasn't been returned to the driver, or if this is the admin queue. */ -static void nvme_abort_cmd(int cmdid, struct nvme_queue *nvmeq) +static void nvme_abort_req(struct request *req) { - int a_cmdid; - struct nvme_command cmd; + struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = cmd_rq->nvmeq; struct nvme_dev *dev = nvmeq->dev; - struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); - struct nvme_queue *adminq; + struct request *abort_req; + struct nvme_cmd_info *abort_cmd; + struct nvme_command cmd; - if (!nvmeq->qid || info[cmdid].aborted) { + if (!nvmeq->qid || cmd_rq->aborted) { if (work_busy(&dev->reset_work)) return; list_del_init(&dev->node); dev_warn(&dev->pci_dev->dev, - "I/O %d QID %d timeout, reset controller\n", cmdid, - nvmeq->qid); + "I/O %d QID %d timeout, reset controller\n", + req->tag, nvmeq->qid); dev->reset_workfn = nvme_reset_failed_dev; queue_work(nvme_workq, &dev->reset_work); return; @@ -1149,89 +1024,79 @@ static void nvme_abort_cmd(int cmdid, struct nvme_queue *nvmeq) if (!dev->abort_limit) return; - adminq = rcu_dereference(dev->queues[0]); - a_cmdid = alloc_cmdid(adminq, CMD_CTX_ABORT, special_completion, - ADMIN_TIMEOUT); - if (a_cmdid < 0) + abort_req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC, + false); + if (!abort_req) return; + abort_cmd = blk_mq_rq_to_pdu(abort_req); + nvme_set_info(abort_cmd, abort_req, abort_completion); + memset(&cmd, 0, sizeof(cmd)); cmd.abort.opcode = nvme_admin_abort_cmd; - cmd.abort.cid = cmdid; + cmd.abort.cid = req->tag; cmd.abort.sqid = cpu_to_le16(nvmeq->qid); - cmd.abort.command_id = a_cmdid; + cmd.abort.command_id = abort_req->tag; --dev->abort_limit; - info[cmdid].aborted = 1; - info[cmdid].timeout = jiffies + ADMIN_TIMEOUT; + cmd_rq->aborted = 1; - dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", cmdid, + dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", req->tag, nvmeq->qid); - nvme_submit_cmd(adminq, &cmd); + if (nvme_submit_cmd(dev->queues[0], &cmd) < 0) { + dev_warn(nvmeq->q_dmadev, + "Could not abort I/O %d QID %d", + req->tag, nvmeq->qid); + blk_put_request(req); + } } -/** - * nvme_cancel_ios - Cancel outstanding I/Os - * @queue: The queue to cancel I/Os on - * @timeout: True to only cancel I/Os which have timed out - */ -static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) +static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx, + struct request *req, void *data, bool reserved) { - int depth = nvmeq->q_depth - 1; - struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); - unsigned long now = jiffies; - int cmdid; + struct nvme_queue *nvmeq = data; + void *ctx; + nvme_completion_fn fn; + struct nvme_cmd_info *cmd; + static struct nvme_completion cqe = { + .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), + }; - for_each_set_bit(cmdid, nvmeq->cmdid_data, depth) { - void *ctx; - nvme_completion_fn fn; - static struct nvme_completion cqe = { - .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), - }; + cmd = blk_mq_rq_to_pdu(req); - if (timeout && !time_after(now, info[cmdid].timeout)) - continue; - if (info[cmdid].ctx == CMD_CTX_CANCELLED) - continue; - if (timeout && info[cmdid].ctx == CMD_CTX_ASYNC) - continue; - if (timeout && nvmeq->dev->initialized) { - nvme_abort_cmd(cmdid, nvmeq); - continue; - } - dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", cmdid, - nvmeq->qid); - ctx = cancel_cmdid(nvmeq, cmdid, &fn); - fn(nvmeq, ctx, &cqe); - } + if (cmd->ctx == CMD_CTX_CANCELLED) + return; + + dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", + req->tag, nvmeq->qid); + ctx = cancel_cmd_info(cmd, &fn); + fn(nvmeq, ctx, &cqe); } -static void nvme_free_queue(struct nvme_queue *nvmeq) +static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) { - spin_lock_irq(&nvmeq->q_lock); - while (bio_list_peek(&nvmeq->sq_cong)) { - struct bio *bio = bio_list_pop(&nvmeq->sq_cong); - bio_endio(bio, -EIO); - } - while (!list_empty(&nvmeq->iod_bio)) { - static struct nvme_completion cqe = { - .status = cpu_to_le16( - (NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1), - }; - struct nvme_iod *iod = list_first_entry(&nvmeq->iod_bio, - struct nvme_iod, - node); - list_del(&iod->node); - bio_completion(nvmeq, iod, &cqe); - } - spin_unlock_irq(&nvmeq->q_lock); + struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); + struct nvme_queue *nvmeq = cmd->nvmeq; + + dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, + nvmeq->qid); + if (nvmeq->dev->initialized) + nvme_abort_req(req); + + /* + * The aborted req will be completed on receiving the abort req. + * We enable the timer again. If hit twice, it'll cause a device reset, + * as the device then is in a faulty state. + */ + return BLK_EH_RESET_TIMER; +} +static void nvme_free_queue(struct nvme_queue *nvmeq) +{ dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth), (void *)nvmeq->cqes, nvmeq->cq_dma_addr); dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth), nvmeq->sq_cmds, nvmeq->sq_dma_addr); - if (nvmeq->qid) - free_cpumask_var(nvmeq->cpu_mask); kfree(nvmeq); } @@ -1243,10 +1108,10 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) int i; for (i = dev->queue_count - 1; i >= lowest; i--) { - nvmeq = raw_nvmeq(dev, i); - RCU_INIT_POINTER(dev->queues[i], NULL); + struct nvme_queue *nvmeq = dev->queues[i]; llist_add(&nvmeq->node, &q_list); dev->queue_count--; + dev->queues[i] = NULL; } synchronize_rcu(); entry = llist_del_all(&q_list); @@ -1257,19 +1122,12 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) /** * nvme_suspend_queue - put queue into suspended state * @nvmeq - queue to suspend - * - * Returns 1 if already suspended, 0 otherwise. */ static int nvme_suspend_queue(struct nvme_queue *nvmeq) { int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; spin_lock_irq(&nvmeq->q_lock); - if (nvmeq->q_suspended) { - spin_unlock_irq(&nvmeq->q_lock); - return 1; - } - nvmeq->q_suspended = 1; nvmeq->dev->online_queues--; spin_unlock_irq(&nvmeq->q_lock); @@ -1281,15 +1139,18 @@ static int nvme_suspend_queue(struct nvme_queue *nvmeq) static void nvme_clear_queue(struct nvme_queue *nvmeq) { + struct blk_mq_hw_ctx *hctx = nvmeq->hctx; + spin_lock_irq(&nvmeq->q_lock); nvme_process_cq(nvmeq); - nvme_cancel_ios(nvmeq, false); + if (hctx && hctx->tags) + blk_mq_tag_busy_iter(hctx, nvme_cancel_queue_ios, nvmeq); spin_unlock_irq(&nvmeq->q_lock); } static void nvme_disable_queue(struct nvme_dev *dev, int qid) { - struct nvme_queue *nvmeq = raw_nvmeq(dev, qid); + struct nvme_queue *nvmeq = dev->queues[qid]; if (!nvmeq) return; @@ -1309,8 +1170,7 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth, int vector) { struct device *dmadev = &dev->pci_dev->dev; - unsigned extra = nvme_queue_extra(depth); - struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq) + extra, GFP_KERNEL); + struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); if (!nvmeq) return NULL; @@ -1324,9 +1184,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, if (!nvmeq->sq_cmds) goto free_cqdma; - if (qid && !zalloc_cpumask_var(&nvmeq->cpu_mask, GFP_KERNEL)) - goto free_sqdma; - nvmeq->q_dmadev = dmadev; nvmeq->dev = dev; snprintf(nvmeq->irqname, sizeof(nvmeq->irqname), "nvme%dq%d", @@ -1334,22 +1191,15 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, spin_lock_init(&nvmeq->q_lock); nvmeq->cq_head = 0; nvmeq->cq_phase = 1; - init_waitqueue_head(&nvmeq->sq_full); - bio_list_init(&nvmeq->sq_cong); - INIT_LIST_HEAD(&nvmeq->iod_bio); nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; nvmeq->q_depth = depth; nvmeq->cq_vector = vector; nvmeq->qid = qid; - nvmeq->q_suspended = 1; dev->queue_count++; - rcu_assign_pointer(dev->queues[qid], nvmeq); + dev->queues[qid] = nvmeq; return nvmeq; - free_sqdma: - dma_free_coherent(dmadev, SQ_SIZE(depth), (void *)nvmeq->sq_cmds, - nvmeq->sq_dma_addr); free_cqdma: dma_free_coherent(dmadev, CQ_SIZE(depth), (void *)nvmeq->cqes, nvmeq->cq_dma_addr); @@ -1372,18 +1222,13 @@ static int queue_request_irq(struct nvme_dev *dev, struct nvme_queue *nvmeq, static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) { struct nvme_dev *dev = nvmeq->dev; - unsigned extra = nvme_queue_extra(nvmeq->q_depth); spin_lock_irq(&nvmeq->q_lock); - init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); nvmeq->sq_tail = 0; nvmeq->cq_head = 0; nvmeq->cq_phase = 1; nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; - memset(nvmeq->cmdid_data, 0, extra); memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); - nvme_cancel_ios(nvmeq, false); - nvmeq->q_suspended = 0; dev->online_queues++; spin_unlock_irq(&nvmeq->q_lock); } @@ -1486,6 +1331,52 @@ static int nvme_shutdown_ctrl(struct nvme_dev *dev) return 0; } +static struct blk_mq_ops nvme_mq_admin_ops = { + .queue_rq = nvme_admin_queue_rq, + .map_queue = blk_mq_map_queue, + .init_hctx = nvme_admin_init_hctx, + .init_request = nvme_admin_init_request, + .timeout = nvme_timeout, +}; + +static struct blk_mq_ops nvme_mq_ops = { + .queue_rq = nvme_queue_rq, + .map_queue = blk_mq_map_queue, + .init_hctx = nvme_init_hctx, + .init_request = nvme_init_request, + .timeout = nvme_timeout, +}; + +static int nvme_alloc_admin_tags(struct nvme_dev *dev) +{ + if (!dev->admin_q) { + dev->admin_tagset.ops = &nvme_mq_admin_ops; + dev->admin_tagset.nr_hw_queues = 1; + dev->admin_tagset.queue_depth = NVME_AQ_DEPTH - 1; + dev->admin_tagset.timeout = ADMIN_TIMEOUT; + dev->admin_tagset.numa_node = dev_to_node(&dev->pci_dev->dev); + dev->admin_tagset.cmd_size = sizeof(struct nvme_cmd_info); + dev->admin_tagset.driver_data = dev; + + if (blk_mq_alloc_tag_set(&dev->admin_tagset)) + return -ENOMEM; + + dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); + if (!dev->admin_q) { + blk_mq_free_tag_set(&dev->admin_tagset); + return -ENOMEM; + } + } + + return 0; +} + +static void nvme_free_admin_tags(struct nvme_dev *dev) +{ + if (dev->admin_q) + blk_mq_free_tag_set(&dev->admin_tagset); +} + static int nvme_configure_admin_queue(struct nvme_dev *dev) { int result; @@ -1515,9 +1406,9 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) if (result < 0) return result; - nvmeq = raw_nvmeq(dev, 0); + nvmeq = dev->queues[0]; if (!nvmeq) { - nvmeq = nvme_alloc_queue(dev, 0, 64, 0); + nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); if (!nvmeq) return -ENOMEM; } @@ -1538,13 +1429,23 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) result = nvme_enable_ctrl(dev, cap); if (result) - return result; + goto free_nvmeq; + + result = nvme_alloc_admin_tags(dev); + if (result) + goto free_nvmeq; result = queue_request_irq(dev, nvmeq, nvmeq->irqname); if (result) - return result; + goto free_tags; return result; + + free_tags: + nvme_free_admin_tags(dev); + free_nvmeq: + nvme_free_queues(dev, 0); + return result; } struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, @@ -1702,7 +1603,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) if (length != (io.nblocks + 1) << ns->lba_shift) status = -ENOMEM; else - status = nvme_submit_io_cmd(dev, &c, NULL); + status = nvme_submit_io_cmd(dev, ns, &c, NULL); if (meta_len) { if (status == NVME_SC_SUCCESS && !(io.opcode & 1)) { @@ -1734,8 +1635,8 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) return status; } -static int nvme_user_cmd(struct nvme_dev *dev, - struct nvme_passthru_cmd __user *ucmd, bool ioq) +static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns, + struct nvme_passthru_cmd __user *ucmd) { struct nvme_passthru_cmd cmd; struct nvme_command c; @@ -1774,13 +1675,23 @@ static int nvme_user_cmd(struct nvme_dev *dev, timeout = cmd.timeout_ms ? msecs_to_jiffies(cmd.timeout_ms) : ADMIN_TIMEOUT; + if (length != cmd.data_len) status = -ENOMEM; - else if (ioq) - status = nvme_submit_sync_cmd(dev, this_cpu_read(*dev->io_queue), &c, - &cmd.result, timeout); - else - status = nvme_submit_sync_cmd(dev, 0, &c, &cmd.result, timeout); + else if (ns) { + struct request *req; + + req = blk_mq_alloc_request(ns->queue, WRITE, + (GFP_KERNEL|__GFP_WAIT), false); + if (!req) + status = -ENOMEM; + else { + status = nvme_submit_sync_cmd(req, &c, &cmd.result, + timeout); + blk_put_request(req); + } + } else + status = __nvme_submit_admin_cmd(dev, &c, &cmd.result, timeout); if (cmd.data_len) { nvme_unmap_user_pages(dev, cmd.opcode & 1, iod); @@ -1804,9 +1715,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, force_successful_syscall_return(); return ns->ns_id; case NVME_IOCTL_ADMIN_CMD: - return nvme_user_cmd(ns->dev, (void __user *)arg, false); + return nvme_user_cmd(ns->dev, NULL, (void __user *)arg); case NVME_IOCTL_IO_CMD: - return nvme_user_cmd(ns->dev, (void __user *)arg, true); + return nvme_user_cmd(ns->dev, ns, (void __user *)arg); case NVME_IOCTL_SUBMIT_IO: return nvme_submit_io(ns, (void __user *)arg); case SG_GET_VERSION_NUM: @@ -1906,62 +1817,6 @@ static const struct block_device_operations nvme_fops = { .revalidate_disk= nvme_revalidate_disk, }; -static void nvme_resubmit_iods(struct nvme_queue *nvmeq) -{ - struct nvme_iod *iod, *next; - - list_for_each_entry_safe(iod, next, &nvmeq->iod_bio, node) { - if (unlikely(nvme_submit_iod(nvmeq, iod))) - break; - list_del(&iod->node); - if (bio_list_empty(&nvmeq->sq_cong) && - list_empty(&nvmeq->iod_bio)) - remove_wait_queue(&nvmeq->sq_full, - &nvmeq->sq_cong_wait); - } -} - -static void nvme_resubmit_bios(struct nvme_queue *nvmeq) -{ - while (bio_list_peek(&nvmeq->sq_cong)) { - struct bio *bio = bio_list_pop(&nvmeq->sq_cong); - struct nvme_ns *ns = bio->bi_bdev->bd_disk->private_data; - - if (bio_list_empty(&nvmeq->sq_cong) && - list_empty(&nvmeq->iod_bio)) - remove_wait_queue(&nvmeq->sq_full, - &nvmeq->sq_cong_wait); - if (nvme_submit_bio_queue(nvmeq, ns, bio)) { - if (!waitqueue_active(&nvmeq->sq_full)) - add_wait_queue(&nvmeq->sq_full, - &nvmeq->sq_cong_wait); - bio_list_add_head(&nvmeq->sq_cong, bio); - break; - } - } -} - -static int nvme_submit_async_req(struct nvme_queue *nvmeq) -{ - struct nvme_command *c; - int cmdid; - - cmdid = alloc_cmdid(nvmeq, CMD_CTX_ASYNC, special_completion, 0); - if (cmdid < 0) - return cmdid; - - c = &nvmeq->sq_cmds[nvmeq->sq_tail]; - memset(c, 0, sizeof(*c)); - c->common.opcode = nvme_admin_async_event; - c->common.command_id = cmdid; - - if (++nvmeq->sq_tail == nvmeq->q_depth) - nvmeq->sq_tail = 0; - writel(nvmeq->sq_tail, nvmeq->q_db); - - return 0; -} - static int nvme_kthread(void *data) { struct nvme_dev *dev, *next; @@ -1977,34 +1832,26 @@ static int nvme_kthread(void *data) continue; list_del_init(&dev->node); dev_warn(&dev->pci_dev->dev, - "Failed status, reset controller\n"); + "Failed status: %x, reset controller\n", + readl(&dev->bar->csts)); dev->reset_workfn = nvme_reset_failed_dev; queue_work(nvme_workq, &dev->reset_work); continue; } - rcu_read_lock(); for (i = 0; i < dev->queue_count; i++) { - struct nvme_queue *nvmeq = - rcu_dereference(dev->queues[i]); + struct nvme_queue *nvmeq = dev->queues[i]; if (!nvmeq) continue; spin_lock_irq(&nvmeq->q_lock); - if (nvmeq->q_suspended) - goto unlock; nvme_process_cq(nvmeq); - nvme_cancel_ios(nvmeq, true); - nvme_resubmit_bios(nvmeq); - nvme_resubmit_iods(nvmeq); while ((i == 0) && (dev->event_limit > 0)) { - if (nvme_submit_async_req(nvmeq)) + if (nvme_submit_async_admin_req(dev)) break; dev->event_limit--; } - unlock: spin_unlock_irq(&nvmeq->q_lock); } - rcu_read_unlock(); } spin_unlock(&dev_list_lock); schedule_timeout(round_jiffies_relative(HZ)); @@ -2027,29 +1874,29 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, { struct nvme_ns *ns; struct gendisk *disk; + int node = dev_to_node(&dev->pci_dev->dev); int lbaf; if (rt->attributes & NVME_LBART_ATTRIB_HIDE) return NULL; - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node); if (!ns) return NULL; - ns->queue = blk_alloc_queue(GFP_KERNEL); + ns->queue = blk_mq_init_queue(&dev->tagset); if (!ns->queue) goto out_free_ns; - ns->queue->queue_flags = QUEUE_FLAG_DEFAULT; - queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue); - queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, ns->queue); - blk_queue_make_request(ns->queue, nvme_make_request); + queue_flag_set_unlocked(QUEUE_FLAG_SG_GAPS, ns->queue); + queue_flag_clear_unlocked(QUEUE_FLAG_IO_STAT, ns->queue); ns->dev = dev; ns->queue->queuedata = ns; - disk = alloc_disk(0); + disk = alloc_disk_node(0, node); if (!disk) goto out_free_queue; + ns->ns_id = nsid; ns->disk = disk; lbaf = id->flbas & 0xf; @@ -2058,6 +1905,8 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); if (dev->max_hw_sectors) blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); + if (dev->stripe_size) + blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9); if (dev->vwc & NVME_CTRL_VWC_PRESENT) blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA); @@ -2083,143 +1932,19 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, return NULL; } -static int nvme_find_closest_node(int node) -{ - int n, val, min_val = INT_MAX, best_node = node; - - for_each_online_node(n) { - if (n == node) - continue; - val = node_distance(node, n); - if (val < min_val) { - min_val = val; - best_node = n; - } - } - return best_node; -} - -static void nvme_set_queue_cpus(cpumask_t *qmask, struct nvme_queue *nvmeq, - int count) -{ - int cpu; - for_each_cpu(cpu, qmask) { - if (cpumask_weight(nvmeq->cpu_mask) >= count) - break; - if (!cpumask_test_and_set_cpu(cpu, nvmeq->cpu_mask)) - *per_cpu_ptr(nvmeq->dev->io_queue, cpu) = nvmeq->qid; - } -} - -static void nvme_add_cpus(cpumask_t *mask, const cpumask_t *unassigned_cpus, - const cpumask_t *new_mask, struct nvme_queue *nvmeq, int cpus_per_queue) -{ - int next_cpu; - for_each_cpu(next_cpu, new_mask) { - cpumask_or(mask, mask, get_cpu_mask(next_cpu)); - cpumask_or(mask, mask, topology_thread_cpumask(next_cpu)); - cpumask_and(mask, mask, unassigned_cpus); - nvme_set_queue_cpus(mask, nvmeq, cpus_per_queue); - } -} - static void nvme_create_io_queues(struct nvme_dev *dev) { - unsigned i, max; + unsigned i; - max = min(dev->max_qid, num_online_cpus()); - for (i = dev->queue_count; i <= max; i++) + for (i = dev->queue_count; i <= dev->max_qid; i++) if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) break; - max = min(dev->queue_count - 1, num_online_cpus()); - for (i = dev->online_queues; i <= max; i++) - if (nvme_create_queue(raw_nvmeq(dev, i), i)) + for (i = dev->online_queues; i <= dev->queue_count - 1; i++) + if (nvme_create_queue(dev->queues[i], i)) break; } -/* - * If there are fewer queues than online cpus, this will try to optimally - * assign a queue to multiple cpus by grouping cpus that are "close" together: - * thread siblings, core, socket, closest node, then whatever else is - * available. - */ -static void nvme_assign_io_queues(struct nvme_dev *dev) -{ - unsigned cpu, cpus_per_queue, queues, remainder, i; - cpumask_var_t unassigned_cpus; - - nvme_create_io_queues(dev); - - queues = min(dev->online_queues - 1, num_online_cpus()); - if (!queues) - return; - - cpus_per_queue = num_online_cpus() / queues; - remainder = queues - (num_online_cpus() - queues * cpus_per_queue); - - if (!alloc_cpumask_var(&unassigned_cpus, GFP_KERNEL)) - return; - - cpumask_copy(unassigned_cpus, cpu_online_mask); - cpu = cpumask_first(unassigned_cpus); - for (i = 1; i <= queues; i++) { - struct nvme_queue *nvmeq = lock_nvmeq(dev, i); - cpumask_t mask; - - cpumask_clear(nvmeq->cpu_mask); - if (!cpumask_weight(unassigned_cpus)) { - unlock_nvmeq(nvmeq); - break; - } - - mask = *get_cpu_mask(cpu); - nvme_set_queue_cpus(&mask, nvmeq, cpus_per_queue); - if (cpus_weight(mask) < cpus_per_queue) - nvme_add_cpus(&mask, unassigned_cpus, - topology_thread_cpumask(cpu), - nvmeq, cpus_per_queue); - if (cpus_weight(mask) < cpus_per_queue) - nvme_add_cpus(&mask, unassigned_cpus, - topology_core_cpumask(cpu), - nvmeq, cpus_per_queue); - if (cpus_weight(mask) < cpus_per_queue) - nvme_add_cpus(&mask, unassigned_cpus, - cpumask_of_node(cpu_to_node(cpu)), - nvmeq, cpus_per_queue); - if (cpus_weight(mask) < cpus_per_queue) - nvme_add_cpus(&mask, unassigned_cpus, - cpumask_of_node( - nvme_find_closest_node( - cpu_to_node(cpu))), - nvmeq, cpus_per_queue); - if (cpus_weight(mask) < cpus_per_queue) - nvme_add_cpus(&mask, unassigned_cpus, - unassigned_cpus, - nvmeq, cpus_per_queue); - - WARN(cpumask_weight(nvmeq->cpu_mask) != cpus_per_queue, - "nvme%d qid:%d mis-matched queue-to-cpu assignment\n", - dev->instance, i); - - irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector, - nvmeq->cpu_mask); - cpumask_andnot(unassigned_cpus, unassigned_cpus, - nvmeq->cpu_mask); - cpu = cpumask_next(cpu, unassigned_cpus); - if (remainder && !--remainder) - cpus_per_queue++; - unlock_nvmeq(nvmeq); - } - WARN(cpumask_weight(unassigned_cpus), "nvme%d unassigned online cpus\n", - dev->instance); - i = 0; - cpumask_andnot(unassigned_cpus, cpu_possible_mask, cpu_online_mask); - for_each_cpu(cpu, unassigned_cpus) - *per_cpu_ptr(dev->io_queue, cpu) = (i++ % queues) + 1; - free_cpumask_var(unassigned_cpus); -} - static int set_queue_count(struct nvme_dev *dev, int count) { int status; @@ -2243,33 +1968,9 @@ static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues) return 4096 + ((nr_io_queues + 1) * 8 * dev->db_stride); } -static void nvme_cpu_workfn(struct work_struct *work) -{ - struct nvme_dev *dev = container_of(work, struct nvme_dev, cpu_work); - if (dev->initialized) - nvme_assign_io_queues(dev); -} - -static int nvme_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - struct nvme_dev *dev; - - switch (action) { - case CPU_ONLINE: - case CPU_DEAD: - spin_lock(&dev_list_lock); - list_for_each_entry(dev, &dev_list, node) - schedule_work(&dev->cpu_work); - spin_unlock(&dev_list_lock); - break; - } - return NOTIFY_OK; -} - static int nvme_setup_io_queues(struct nvme_dev *dev) { - struct nvme_queue *adminq = raw_nvmeq(dev, 0); + struct nvme_queue *adminq = dev->queues[0]; struct pci_dev *pdev = dev->pci_dev; int result, i, vecs, nr_io_queues, size; @@ -2321,14 +2022,12 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) dev->max_qid = nr_io_queues; result = queue_request_irq(dev, adminq, adminq->irqname); - if (result) { - adminq->q_suspended = 1; + if (result) goto free_queues; - } /* Free previously allocated queues that are no longer usable */ nvme_free_queues(dev, nr_io_queues + 1); - nvme_assign_io_queues(dev); + nvme_create_io_queues(dev); return 0; @@ -2378,8 +2077,30 @@ static int nvme_dev_add(struct nvme_dev *dev) if (ctrl->mdts) dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); if ((pdev->vendor == PCI_VENDOR_ID_INTEL) && - (pdev->device == 0x0953) && ctrl->vs[3]) + (pdev->device == 0x0953) && ctrl->vs[3]) { + unsigned int max_hw_sectors; + dev->stripe_size = 1 << (ctrl->vs[3] + shift); + max_hw_sectors = dev->stripe_size >> (shift - 9); + if (dev->max_hw_sectors) { + dev->max_hw_sectors = min(max_hw_sectors, + dev->max_hw_sectors); + } else + dev->max_hw_sectors = max_hw_sectors; + } + + dev->tagset.ops = &nvme_mq_ops; + dev->tagset.nr_hw_queues = dev->online_queues - 1; + dev->tagset.timeout = NVME_IO_TIMEOUT; + dev->tagset.numa_node = dev_to_node(&dev->pci_dev->dev); + dev->tagset.queue_depth = + min_t(int, dev->q_depth, BLK_MQ_MAX_DEPTH) - 1; + dev->tagset.cmd_size = sizeof(struct nvme_cmd_info); + dev->tagset.flags = BLK_MQ_F_SHOULD_MERGE; + dev->tagset.driver_data = dev; + + if (blk_mq_alloc_tag_set(&dev->tagset)) + goto out; id_ns = mem; for (i = 1; i <= nn; i++) { @@ -2529,7 +2250,8 @@ static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode, c.delete_queue.qid = cpu_to_le16(nvmeq->qid); init_kthread_work(&nvmeq->cmdinfo.work, fn); - return nvme_submit_admin_cmd_async(nvmeq->dev, &c, &nvmeq->cmdinfo); + return nvme_submit_admin_async_cmd(nvmeq->dev, &c, &nvmeq->cmdinfo, + ADMIN_TIMEOUT); } static void nvme_del_cq_work_handler(struct kthread_work *work) @@ -2592,7 +2314,7 @@ static void nvme_disable_io_queues(struct nvme_dev *dev) atomic_set(&dq.refcount, 0); dq.worker = &worker; for (i = dev->queue_count - 1; i > 0; i--) { - struct nvme_queue *nvmeq = raw_nvmeq(dev, i); + struct nvme_queue *nvmeq = dev->queues[i]; if (nvme_suspend_queue(nvmeq)) continue; @@ -2637,7 +2359,7 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) csts = readl(&dev->bar->csts); if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { for (i = dev->queue_count - 1; i >= 0; i--) { - struct nvme_queue *nvmeq = raw_nvmeq(dev, i); + struct nvme_queue *nvmeq = dev->queues[i]; nvme_suspend_queue(nvmeq); nvme_clear_queue(nvmeq); } @@ -2649,6 +2371,12 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) nvme_dev_unmap(dev); } +static void nvme_dev_remove_admin(struct nvme_dev *dev) +{ + if (dev->admin_q && !blk_queue_dying(dev->admin_q)) + blk_cleanup_queue(dev->admin_q); +} + static void nvme_dev_remove(struct nvme_dev *dev) { struct nvme_ns *ns; @@ -2736,7 +2464,7 @@ static void nvme_free_dev(struct kref *kref) pci_dev_put(dev->pci_dev); nvme_free_namespaces(dev); - free_percpu(dev->io_queue); + blk_mq_free_tag_set(&dev->tagset); kfree(dev->queues); kfree(dev->entry); kfree(dev); @@ -2761,11 +2489,16 @@ static int nvme_dev_release(struct inode *inode, struct file *f) static long nvme_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { struct nvme_dev *dev = f->private_data; + struct nvme_ns *ns; + switch (cmd) { case NVME_IOCTL_ADMIN_CMD: - return nvme_user_cmd(dev, (void __user *)arg, false); + return nvme_user_cmd(dev, NULL, (void __user *)arg); case NVME_IOCTL_IO_CMD: - return nvme_user_cmd(dev, (void __user *)arg, true); + if (list_empty(&dev->namespaces)) + return -ENOTTY; + ns = list_first_entry(&dev->namespaces, struct nvme_ns, list); + return nvme_user_cmd(dev, ns, (void __user *)arg); default: return -ENOTTY; } @@ -2779,6 +2512,22 @@ static const struct file_operations nvme_dev_fops = { .compat_ioctl = nvme_dev_ioctl, }; +static void nvme_set_irq_hints(struct nvme_dev *dev) +{ + struct nvme_queue *nvmeq; + int i; + + for (i = 0; i < dev->online_queues; i++) { + nvmeq = dev->queues[i]; + + if (!nvmeq->hctx) + continue; + + irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector, + nvmeq->hctx->cpumask); + } +} + static int nvme_dev_start(struct nvme_dev *dev) { int result; @@ -2810,12 +2559,15 @@ static int nvme_dev_start(struct nvme_dev *dev) result = nvme_thread ? PTR_ERR(nvme_thread) : -EINTR; goto disable; } - nvme_init_queue(raw_nvmeq(dev, 0), 0); + + nvme_init_queue(dev->queues[0], 0); result = nvme_setup_io_queues(dev); if (result) goto disable; + nvme_set_irq_hints(dev); + return result; disable: @@ -2866,7 +2618,7 @@ static void nvme_dev_reset(struct nvme_dev *dev) { nvme_dev_shutdown(dev); if (nvme_dev_resume(dev)) { - dev_err(&dev->pci_dev->dev, "Device failed to resume\n"); + dev_warn(&dev->pci_dev->dev, "Device failed to resume\n"); kref_get(&dev->kref); if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d", dev->instance))) { @@ -2891,28 +2643,28 @@ static void nvme_reset_workfn(struct work_struct *work) static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - int result = -ENOMEM; + int node, result = -ENOMEM; struct nvme_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + node = dev_to_node(&pdev->dev); + if (node == NUMA_NO_NODE) + set_dev_node(&pdev->dev, 0); + + dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); if (!dev) return -ENOMEM; - dev->entry = kcalloc(num_possible_cpus(), sizeof(*dev->entry), - GFP_KERNEL); + dev->entry = kzalloc_node(num_possible_cpus() * sizeof(*dev->entry), + GFP_KERNEL, node); if (!dev->entry) goto free; - dev->queues = kcalloc(num_possible_cpus() + 1, sizeof(void *), - GFP_KERNEL); + dev->queues = kzalloc_node((num_possible_cpus() + 1) * sizeof(void *), + GFP_KERNEL, node); if (!dev->queues) goto free; - dev->io_queue = alloc_percpu(unsigned short); - if (!dev->io_queue) - goto free; INIT_LIST_HEAD(&dev->namespaces); dev->reset_workfn = nvme_reset_failed_dev; INIT_WORK(&dev->reset_work, nvme_reset_workfn); - INIT_WORK(&dev->cpu_work, nvme_cpu_workfn); dev->pci_dev = pci_dev_get(pdev); pci_set_drvdata(pdev, dev); result = nvme_set_instance(dev); @@ -2942,11 +2694,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (result) goto remove; + nvme_set_irq_hints(dev); + dev->initialized = 1; return 0; remove: nvme_dev_remove(dev); + nvme_dev_remove_admin(dev); nvme_free_namespaces(dev); shutdown: nvme_dev_shutdown(dev); @@ -2958,7 +2713,6 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) put_pci: pci_dev_put(dev->pci_dev); free: - free_percpu(dev->io_queue); kfree(dev->queues); kfree(dev->entry); kfree(dev); @@ -2991,11 +2745,12 @@ static void nvme_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); flush_work(&dev->reset_work); - flush_work(&dev->cpu_work); misc_deregister(&dev->miscdev); + nvme_dev_remove(dev); nvme_dev_shutdown(dev); + nvme_dev_remove_admin(dev); nvme_free_queues(dev, 0); - nvme_dev_remove(dev); + nvme_free_admin_tags(dev); nvme_release_instance(dev); nvme_release_prp_pools(dev); kref_put(&dev->kref, nvme_free_dev); @@ -3079,18 +2834,11 @@ static int __init nvme_init(void) else if (result > 0) nvme_major = result; - nvme_nb.notifier_call = &nvme_cpu_notify; - result = register_hotcpu_notifier(&nvme_nb); - if (result) - goto unregister_blkdev; - result = pci_register_driver(&nvme_driver); if (result) - goto unregister_hotcpu; + goto unregister_blkdev; return 0; - unregister_hotcpu: - unregister_hotcpu_notifier(&nvme_nb); unregister_blkdev: unregister_blkdev(nvme_major, "nvme"); kill_workq: diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index 046ae3321c5e..49f86d1a5aa2 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c @@ -2105,7 +2105,7 @@ static int nvme_trans_do_nvme_io(struct nvme_ns *ns, struct sg_io_hdr *hdr, nvme_offset += unit_num_blocks; - nvme_sc = nvme_submit_io_cmd(dev, &c, NULL); + nvme_sc = nvme_submit_io_cmd(dev, ns, &c, NULL); if (nvme_sc != NVME_SC_SUCCESS) { nvme_unmap_user_pages(dev, (is_write) ? DMA_TO_DEVICE : DMA_FROM_DEVICE, @@ -2658,7 +2658,7 @@ static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr, c.common.opcode = nvme_cmd_flush; c.common.nsid = cpu_to_le32(ns->ns_id); - nvme_sc = nvme_submit_io_cmd(ns->dev, &c, NULL); + nvme_sc = nvme_submit_io_cmd(ns->dev, ns, &c, NULL); res = nvme_trans_status_code(hdr, nvme_sc); if (res) goto out; @@ -2686,7 +2686,7 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns, c.common.opcode = nvme_cmd_flush; c.common.nsid = cpu_to_le32(ns->ns_id); - nvme_sc = nvme_submit_io_cmd(ns->dev, &c, NULL); + nvme_sc = nvme_submit_io_cmd(ns->dev, ns, &c, NULL); res = nvme_trans_status_code(hdr, nvme_sc); if (res) @@ -2894,7 +2894,7 @@ static int nvme_trans_unmap(struct nvme_ns *ns, struct sg_io_hdr *hdr, c.dsm.nr = cpu_to_le32(ndesc - 1); c.dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD); - nvme_sc = nvme_submit_io_cmd(dev, &c, NULL); + nvme_sc = nvme_submit_io_cmd(dev, ns, &c, NULL); res = nvme_trans_status_code(hdr, nvme_sc); dma_free_coherent(&dev->pci_dev->dev, ndesc * sizeof(*range), diff --git a/include/linux/nvme.h b/include/linux/nvme.h index ed09074e5554..258945fcabf1 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -19,6 +19,7 @@ #include #include #include +#include struct nvme_bar { __u64 cap; /* Controller Capabilities */ @@ -71,8 +72,10 @@ extern unsigned char nvme_io_timeout; */ struct nvme_dev { struct list_head node; - struct nvme_queue __rcu **queues; - unsigned short __percpu *io_queue; + struct nvme_queue **queues; + struct request_queue *admin_q; + struct blk_mq_tag_set tagset; + struct blk_mq_tag_set admin_tagset; u32 __iomem *dbs; struct pci_dev *pci_dev; struct dma_pool *prp_page_pool; @@ -91,7 +94,6 @@ struct nvme_dev { struct miscdevice miscdev; work_func_t reset_workfn; struct work_struct reset_work; - struct work_struct cpu_work; char name[12]; char serial[20]; char model[40]; @@ -135,7 +137,6 @@ struct nvme_iod { int offset; /* Of PRP list */ int nents; /* Used in scatterlist */ int length; /* Of data, in bytes */ - unsigned long start_time; dma_addr_t first_dma; struct list_head node; struct scatterlist sg[0]; @@ -153,12 +154,14 @@ static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) */ void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod); -int nvme_setup_prps(struct nvme_dev *, struct nvme_iod *, int , gfp_t); +int nvme_setup_prps(struct nvme_dev *, struct nvme_iod *, int, gfp_t); struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, unsigned long addr, unsigned length); void nvme_unmap_user_pages(struct nvme_dev *dev, int write, struct nvme_iod *iod); -int nvme_submit_io_cmd(struct nvme_dev *, struct nvme_command *, u32 *); +int nvme_submit_io_cmd(struct nvme_dev *, struct nvme_ns *, + struct nvme_command *, u32 *); +int nvme_submit_flush_data(struct nvme_queue *nvmeq, struct nvme_ns *ns); int nvme_submit_admin_cmd(struct nvme_dev *, struct nvme_command *, u32 *result); int nvme_identify(struct nvme_dev *, unsigned nsid, unsigned cns, -- GitLab From 3adec272425f6bb72375436b9dd67b0f5a7f7eef Mon Sep 17 00:00:00 2001 From: Bimow Chen Date: Wed, 1 Oct 2014 07:28:54 -0300 Subject: [PATCH 2985/9457] [media] af9033: fix DVBv3 signal strength value not correct issue Register 0x800048 is not dB measure but relative scale. Fix it and conform to NorDig specifications. Signed-off-by: Bimow Chen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 43 ++++++++++++++++++----- drivers/media/dvb-frontends/af9033_priv.h | 6 ++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 63a89c1c59ff..2b3d2f06c01b 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -862,16 +862,43 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr) static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct af9033_dev *dev = fe->demodulator_priv; - int ret; - u8 strength2; + struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache; + int ret, tmp, power_real; + u8 u8tmp, gain_offset, buf[7]; - /* read signal strength of 0-100 scale */ - ret = af9033_rd_reg(dev, 0x800048, &strength2); - if (ret < 0) - goto err; + if (dev->is_af9035) { + ret = af9033_rd_reg(dev, 0x80004a, &u8tmp); + /* scale value to 0x0000-0xffff */ + *strength = u8tmp * 0xffff / 100; + } else { + ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp); + ret |= af9033_rd_regs(dev, 0x80f900, buf, 7); + + if (c->frequency <= 300000000) + gain_offset = 7; /* VHF */ + else + gain_offset = 4; /* UHF */ + + power_real = (u8tmp - 100 - gain_offset) - + power_reference[((buf[3] >> 0) & 3)][((buf[6] >> 0) & 7)]; + + if (power_real < -15) + tmp = 0; + else if ((power_real >= -15) && (power_real < 0)) + tmp = (2 * (power_real + 15)) / 3; + else if ((power_real >= 0) && (power_real < 20)) + tmp = 4 * power_real + 10; + else if ((power_real >= 20) && (power_real < 35)) + tmp = (2 * (power_real - 20)) / 3 + 90; + else + tmp = 100; + + /* scale value to 0x0000-0xffff */ + *strength = tmp * 0xffff / 100; + } - /* scale value to 0x0000-0xffff */ - *strength = strength2 * 0xffff / 100; + if (ret) + goto err; return 0; diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h index c12c92cb5855..c9c87981f80b 100644 --- a/drivers/media/dvb-frontends/af9033_priv.h +++ b/drivers/media/dvb-frontends/af9033_priv.h @@ -2051,4 +2051,10 @@ static const struct reg_val tuner_init_it9135_62[] = { { 0x80fd8b, 0x00 }, }; +/* NorDig power reference table */ +static const int power_reference[][5] = { + {-93, -91, -90, -89, -88}, /* QPSK 1/2 ~ 7/8 */ + {-87, -85, -84, -83, -82}, /* 16QAM 1/2 ~ 7/8 */ + {-82, -80, -78, -77, -76}, /* 64QAM 1/2 ~ 7/8 */ +}; #endif /* AF9033_PRIV_H */ -- GitLab From 0b0d96281f6d59280094b240ca5046b317ade614 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 3 Nov 2014 20:24:13 -0300 Subject: [PATCH 2986/9457] [media] af9033: fix AF9033 DVBv3 signal strength measurement Previous patch changes used signal strength firmware register from 0x800048 to 0x80004a in case of AF9033/AF9035 chip. In practice reported values were running upside-down, when RR strength increases reported value decreases and vice versa. That is because of 0x80004a returns values that are dBm scale, but negative RF strength dBm returned as positive number. 0x800048 returns 0-100, like percentage 0x80004a returns 0-255 dBm, without a negative sign So restore old measurement now. Cc: Bimow Chen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 2b3d2f06c01b..e3bae7737874 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -867,7 +867,11 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) u8 u8tmp, gain_offset, buf[7]; if (dev->is_af9035) { - ret = af9033_rd_reg(dev, 0x80004a, &u8tmp); + /* read signal strength of 0-100 scale */ + ret = af9033_rd_reg(dev, 0x800048, &u8tmp); + if (ret < 0) + goto err; + /* scale value to 0x0000-0xffff */ *strength = u8tmp * 0xffff / 100; } else { -- GitLab From 1620d221842cb2445680be2afbb36272350b4cac Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 3 Nov 2014 21:23:26 -0300 Subject: [PATCH 2987/9457] [media] af9033: improve read_signal_strength error handling slightly Check return status after each register access routine and avoid masking return status values. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index e3bae7737874..3f688dea9f07 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -876,7 +876,12 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) *strength = u8tmp * 0xffff / 100; } else { ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp); - ret |= af9033_rd_regs(dev, 0x80f900, buf, 7); + if (ret < 0) + goto err; + + ret = af9033_rd_regs(dev, 0x80f900, buf, 7); + if (ret < 0) + goto err; if (c->frequency <= 300000000) gain_offset = 7; /* VHF */ @@ -901,9 +906,6 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) *strength = tmp * 0xffff / 100; } - if (ret) - goto err; - return 0; err: -- GitLab From 6d03f6a875467d924ae4a57c26418810192d842e Mon Sep 17 00:00:00 2001 From: Bimow Chen Date: Wed, 1 Oct 2014 23:37:13 -0300 Subject: [PATCH 2988/9457] [media] af9033: fix DVBv3 snr value not correct issue Snr returns value not correct. Fix it. Signed-off-by: Bimow Chen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 61 +++++++++++++++++++++-- drivers/media/dvb-frontends/af9033_priv.h | 5 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index 3f688dea9f07..a490033e3a7c 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -849,14 +849,42 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr) { struct af9033_dev *dev = fe->demodulator_priv; struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache; + int ret; + u8 u8tmp; /* use DVBv5 CNR */ - if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) - *snr = div_s64(c->cnr.stat[0].svalue, 100); /* 1000x => 10x */ - else + if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) { + *snr = div_s64(c->cnr.stat[0].svalue, 1000); + + /* read current modulation */ + ret = af9033_rd_reg(dev, 0x80f903, &u8tmp); + if (ret) + goto err; + + /* scale value to 0x0000-0xffff */ + switch ((u8tmp >> 0) & 3) { + case 0: + *snr = *snr * 0xFFFF / 23; + break; + case 1: + *snr = *snr * 0xFFFF / 26; + break; + case 2: + *snr = *snr * 0xFFFF / 32; + break; + default: + goto err; + } + } else { *snr = 0; + } return 0; + +err: + dev_dbg(&dev->client->dev, "failed=%d\n", ret); + + return ret; } static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength) @@ -1044,6 +1072,33 @@ static void af9033_stat_work(struct work_struct *work) snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0); + /* read superframe number */ + ret = af9033_rd_reg(dev, 0x80f78b, &u8tmp); + if (ret) + goto err; + + if (u8tmp) + snr_val /= u8tmp; + + /* read current transmission mode */ + ret = af9033_rd_reg(dev, 0x80f900, &u8tmp); + if (ret) + goto err; + + switch ((u8tmp >> 0) & 3) { + case 0: + snr_val *= 4; + break; + case 1: + snr_val *= 1; + break; + case 2: + snr_val *= 2; + break; + default: + goto err; + } + /* read current modulation */ ret = af9033_rd_reg(dev, 0x80f903, &u8tmp); if (ret) diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h index c9c87981f80b..8e23275148ed 100644 --- a/drivers/media/dvb-frontends/af9033_priv.h +++ b/drivers/media/dvb-frontends/af9033_priv.h @@ -181,7 +181,10 @@ static const struct val_snr qam64_snr_lut[] = { { 0x05570d, 26 }, { 0x059feb, 27 }, { 0x05bf38, 28 }, - { 0xffffff, 29 }, + { 0x05f78f, 29 }, + { 0x0612c3, 30 }, + { 0x0626be, 31 }, + { 0xffffff, 32 }, }; static const struct reg_val ofsm_init[] = { -- GitLab From c3a80cd024527381c4020ae38252ce34867b5f73 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 3 Nov 2014 21:53:05 -0300 Subject: [PATCH 2989/9457] [media] af9033: return 0.1 dB DVBv3 SNR for AF9030 family Previous patch changed both AF9030 and IT9130 SNR reporting from dB to relative. Restore AF9030 to old behavior as it has been always returning 0.1 dB value. Leave IT9130 relative as old IT9130 was returning relative values. Cc: Bimow Chen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 43 ++++++++++++++++------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index a490033e3a7c..e64070156247 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -854,26 +854,33 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr) /* use DVBv5 CNR */ if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) { - *snr = div_s64(c->cnr.stat[0].svalue, 1000); + /* Return 0.1 dB for AF9030 and 0-0xffff for IT9130. */ + if (dev->is_af9035) { + /* 1000x => 10x (0.1 dB) */ + *snr = div_s64(c->cnr.stat[0].svalue, 100); + } else { + /* 1000x => 1x (1 dB) */ + *snr = div_s64(c->cnr.stat[0].svalue, 1000); - /* read current modulation */ - ret = af9033_rd_reg(dev, 0x80f903, &u8tmp); - if (ret) - goto err; + /* read current modulation */ + ret = af9033_rd_reg(dev, 0x80f903, &u8tmp); + if (ret) + goto err; - /* scale value to 0x0000-0xffff */ - switch ((u8tmp >> 0) & 3) { - case 0: - *snr = *snr * 0xFFFF / 23; - break; - case 1: - *snr = *snr * 0xFFFF / 26; - break; - case 2: - *snr = *snr * 0xFFFF / 32; - break; - default: - goto err; + /* scale value to 0x0000-0xffff */ + switch ((u8tmp >> 0) & 3) { + case 0: + *snr = *snr * 0xffff / 23; + break; + case 1: + *snr = *snr * 0xffff / 26; + break; + case 2: + *snr = *snr * 0xffff / 32; + break; + default: + goto err; + } } } else { *snr = 0; -- GitLab From fdc533a97b8ff9b722d4e4400bbaca8d9217b547 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 3 Nov 2014 22:01:56 -0300 Subject: [PATCH 2990/9457] [media] af9033: continue polling unless critical IO error That case is not IO error, so better to jump out now, but still continue polling. Cc: Bimow Chen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/af9033.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index e64070156247..c17e34fd0fb4 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -1103,7 +1103,7 @@ static void af9033_stat_work(struct work_struct *work) snr_val *= 2; break; default: - goto err; + goto err_schedule_delayed_work; } /* read current modulation */ -- GitLab From 0b14261edc8c7c7ef6d30133df9188f5a7f3d85f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 4 Nov 2014 07:26:35 -0300 Subject: [PATCH 2991/9457] [media] MAINTAINERS: add maintainer for CODA video4linux mem2mem driver Add myself as maintainer for the CODA V4L2 mem2mem driver. Signed-off-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1629341dcd9e..39e3f9155ebb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2487,6 +2487,13 @@ F: fs/coda/ F: include/linux/coda*.h F: include/uapi/linux/coda*.h +CODA V4L2 MEM2MEM DRIVER +M: Philipp Zabel +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/coda.txt +F: drivers/media/platform/coda/ + COMMON CLK FRAMEWORK M: Mike Turquette L: linux-kernel@vger.kernel.org -- GitLab From 5eedd8d3addc02b833265c8d1d15a79916916208 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Tue, 4 Nov 2014 11:45:58 -0300 Subject: [PATCH 2992/9457] [media] smipcie: add DVBSky S952 V3 support DVBSky S952 V3 card has a dual channels of dvb-s/s2. 1>Frontend: Integrated tuner and demod: M88RS6000 2>PCIe bridge: SMI PCIe Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/smipcie/Kconfig | 2 + drivers/media/pci/smipcie/smipcie.c | 78 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig index 78b76ca85ed4..75a299295999 100644 --- a/drivers/media/pci/smipcie/Kconfig +++ b/drivers/media/pci/smipcie/Kconfig @@ -3,9 +3,11 @@ config DVB_SMIPCIE depends on DVB_CORE && PCI && I2C select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT help Support for cards with SMI PCIe bridge: - DVBSky S950 V3 + - DVBSky S952 V3 Say Y or M if you own such a device and want to use it. If unsure say N. diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 6ad6cc5c33b1..d1c14631a101 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -17,6 +17,7 @@ #include "smipcie.h" #include "m88ds3103.h" #include "m88ts2022.h" +#include "m88rs6000t.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -542,6 +543,70 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) return ret; } +static const struct m88ds3103_config smi_dvbsky_m88rs6000_cfg = { + .i2c_addr = 0x69, + .clock = 27000000, + .i2c_wr_max = 33, + .ts_mode = M88DS3103_TS_PARALLEL, + .ts_clk = 16000, + .ts_clk_pol = 1, + .agc = 0x99, + .lnb_hv_pol = 0, + .lnb_en_pol = 1, +}; + +static int smi_dvbsky_m88rs6000_fe_attach(struct smi_port *port) +{ + int ret = 0; + struct smi_dev *dev = port->dev; + struct i2c_adapter *i2c; + /* tuner I2C module */ + struct i2c_adapter *tuner_i2c_adapter; + struct i2c_client *tuner_client; + struct i2c_board_info tuner_info; + struct m88rs6000t_config m88rs6000t_config; + + memset(&tuner_info, 0, sizeof(struct i2c_board_info)); + i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; + + /* attach demod */ + port->fe = dvb_attach(m88ds3103_attach, + &smi_dvbsky_m88rs6000_cfg, i2c, &tuner_i2c_adapter); + if (!port->fe) { + ret = -ENODEV; + return ret; + } + /* attach tuner */ + m88rs6000t_config.fe = port->fe; + strlcpy(tuner_info.type, "m88rs6000t", I2C_NAME_SIZE); + tuner_info.addr = 0x21; + tuner_info.platform_data = &m88rs6000t_config; + request_module("m88rs6000t"); + tuner_client = i2c_new_device(tuner_i2c_adapter, &tuner_info); + if (tuner_client == NULL || tuner_client->dev.driver == NULL) { + ret = -ENODEV; + goto err_tuner_i2c_device; + } + + if (!try_module_get(tuner_client->dev.driver->owner)) { + ret = -ENODEV; + goto err_tuner_i2c_module; + } + + /* delegate signal strength measurement to tuner */ + port->fe->ops.read_signal_strength = + port->fe->ops.tuner_ops.get_rf_strength; + + port->i2c_client_tuner = tuner_client; + return ret; + +err_tuner_i2c_module: + i2c_unregister_device(tuner_client); +err_tuner_i2c_device: + dvb_frontend_detach(port->fe); + return ret; +} + static int smi_fe_init(struct smi_port *port) { int ret = 0; @@ -556,6 +621,9 @@ static int smi_fe_init(struct smi_port *port) case DVBSKY_FE_M88DS3103: ret = smi_dvbsky_m88ds3103_fe_attach(port); break; + case DVBSKY_FE_M88RS6000: + ret = smi_dvbsky_m88rs6000_fe_attach(port); + break; } if (ret < 0) return ret; @@ -917,6 +985,15 @@ static struct smi_cfg_info dvbsky_s950_cfg = { .fe_1 = DVBSKY_FE_M88DS3103, }; +static struct smi_cfg_info dvbsky_s952_cfg = { + .type = SMI_DVBSKY_S952, + .name = "DVBSky S952 V3", + .ts_0 = SMI_TS_DMA_BOTH, + .ts_1 = SMI_TS_DMA_BOTH, + .fe_0 = DVBSKY_FE_M88RS6000, + .fe_1 = DVBSKY_FE_M88RS6000, +}; + /* PCI IDs */ #define SMI_ID(_subvend, _subdev, _driverdata) { \ .vendor = SMI_VID, .device = SMI_PID, \ @@ -925,6 +1002,7 @@ static struct smi_cfg_info dvbsky_s950_cfg = { static const struct pci_device_id smi_id_table[] = { SMI_ID(0x4254, 0x0550, dvbsky_s950_cfg), + SMI_ID(0x4254, 0x0552, dvbsky_s952_cfg), {0} }; MODULE_DEVICE_TABLE(pci, smi_id_table); -- GitLab From ffdcd955c3078af3ce117edcfce80fde1a512bed Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 21 Oct 2014 13:33:55 +0200 Subject: [PATCH 2993/9457] ACPI: Add support for device specific properties Device Tree is used in many embedded systems to describe the system configuration to the OS. It supports attaching properties or name-value pairs to the devices it describe. With these properties one can pass additional information to the drivers that would not be available otherwise. ACPI is another configuration mechanism (among other things) typically seen, but not limited to, x86 machines. ACPI allows passing arbitrary data from methods but there has not been mechanism equivalent to Device Tree until the introduction of _DSD in the recent publication of the ACPI 5.1 specification. In order to facilitate ACPI usage in systems where Device Tree is typically used, it would be beneficial to standardize a way to retrieve Device Tree style properties from ACPI devices, which is what we do in this patch. If a given device described in ACPI namespace wants to export properties it must implement _DSD method (Device Specific Data, introduced with ACPI 5.1) that returns the properties in a package of packages. For example: Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"name1", }, Package () {"name2", }, ... } }) The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301 and is documented in the ACPI 5.1 companion document called "_DSD Implementation Guide" [1], [2]. We add several helper functions that can be used to extract these properties and convert them to different Linux data types. The ultimate goal is that we only have one device property API that retrieves the requested properties from Device Tree or from ACPI transparent to the caller. [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf Reviewed-by: Hanjun Guo Reviewed-by: Josh Triplett Reviewed-by: Grant Likely Signed-off-by: Darren Hart Signed-off-by: Rafael J. Wysocki Signed-off-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 1 + drivers/acpi/internal.h | 6 + drivers/acpi/property.c | 364 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/scan.c | 2 + include/acpi/acpi_bus.h | 7 + include/linux/acpi.h | 40 +++++ 6 files changed, 420 insertions(+) create mode 100644 drivers/acpi/property.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c3b2fcb729f3..6d11522f0e48 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -47,6 +47,7 @@ acpi-y += int340x_thermal.o acpi-y += power.o acpi-y += event.o acpi-y += sysfs.o +acpi-y += property.o acpi-$(CONFIG_X86) += acpi_cmos_rtc.o acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-$(CONFIG_ACPI_NUMA) += numa.o diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 447f6d679b29..163e82f536fa 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -173,4 +173,10 @@ static inline void suspend_nvs_restore(void) {} bool acpi_osi_is_win8(void); #endif +/*-------------------------------------------------------------------------- + Device properties + -------------------------------------------------------------------------- */ +void acpi_init_properties(struct acpi_device *adev); +void acpi_free_properties(struct acpi_device *adev); + #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c new file mode 100644 index 000000000000..c4a3e800e82c --- /dev/null +++ b/drivers/acpi/property.c @@ -0,0 +1,364 @@ +/* + * ACPI device specific properties support. + * + * Copyright (C) 2014, Intel Corporation + * All rights reserved. + * + * Authors: Mika Westerberg + * Darren Hart + * Rafael J. Wysocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "internal.h" + +/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */ +static const u8 prp_uuid[16] = { + 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d, + 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 +}; + +static bool acpi_property_value_ok(const union acpi_object *value) +{ + int j; + + /* + * The value must be an integer, a string, a reference, or a package + * whose every element must be an integer, a string, or a reference. + */ + switch (value->type) { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_LOCAL_REFERENCE: + return true; + + case ACPI_TYPE_PACKAGE: + for (j = 0; j < value->package.count; j++) + switch (value->package.elements[j].type) { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_LOCAL_REFERENCE: + continue; + + default: + return false; + } + + return true; + } + return false; +} + +static bool acpi_properties_format_valid(const union acpi_object *properties) +{ + int i; + + for (i = 0; i < properties->package.count; i++) { + const union acpi_object *property; + + property = &properties->package.elements[i]; + /* + * Only two elements allowed, the first one must be a string and + * the second one has to satisfy certain conditions. + */ + if (property->package.count != 2 + || property->package.elements[0].type != ACPI_TYPE_STRING + || !acpi_property_value_ok(&property->package.elements[1])) + return false; + } + return true; +} + +void acpi_init_properties(struct acpi_device *adev) +{ + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + const union acpi_object *desc; + acpi_status status; + int i; + + status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, + ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(status)) + return; + + desc = buf.pointer; + if (desc->package.count % 2) + goto fail; + + /* Look for the device properties UUID. */ + for (i = 0; i < desc->package.count; i += 2) { + const union acpi_object *uuid, *properties; + + uuid = &desc->package.elements[i]; + properties = &desc->package.elements[i + 1]; + + /* + * The first element must be a UUID and the second one must be + * a package. + */ + if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16 + || properties->type != ACPI_TYPE_PACKAGE) + break; + + if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid))) + continue; + + /* + * We found the matching UUID. Now validate the format of the + * package immediately following it. + */ + if (!acpi_properties_format_valid(properties)) + break; + + adev->data.pointer = buf.pointer; + adev->data.properties = properties; + return; + } + + fail: + dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n"); + ACPI_FREE(buf.pointer); +} + +void acpi_free_properties(struct acpi_device *adev) +{ + ACPI_FREE((void *)adev->data.pointer); + adev->data.pointer = NULL; + adev->data.properties = NULL; +} + +/** + * acpi_dev_get_property - return an ACPI property with given name + * @adev: ACPI device to get property + * @name: Name of the property + * @type: Expected property type + * @obj: Location to store the property value (if not %NULL) + * + * Look up a property with @name and store a pointer to the resulting ACPI + * object at the location pointed to by @obj if found. + * + * Callers must not attempt to free the returned objects. These objects will be + * freed by the ACPI core automatically during the removal of @adev. + * + * Return: %0 if property with @name has been found (success), + * %-EINVAL if the arguments are invalid, + * %-ENODATA if the property doesn't exist, + * %-EPROTO if the property value type doesn't match @type. + */ +int acpi_dev_get_property(struct acpi_device *adev, const char *name, + acpi_object_type type, const union acpi_object **obj) +{ + const union acpi_object *properties; + int i; + + if (!adev || !name) + return -EINVAL; + + if (!adev->data.pointer || !adev->data.properties) + return -ENODATA; + + properties = adev->data.properties; + for (i = 0; i < properties->package.count; i++) { + const union acpi_object *propname, *propvalue; + const union acpi_object *property; + + property = &properties->package.elements[i]; + + propname = &property->package.elements[0]; + propvalue = &property->package.elements[1]; + + if (!strcmp(name, propname->string.pointer)) { + if (type != ACPI_TYPE_ANY && propvalue->type != type) + return -EPROTO; + else if (obj) + *obj = propvalue; + + return 0; + } + } + return -ENODATA; +} +EXPORT_SYMBOL_GPL(acpi_dev_get_property); + +/** + * acpi_dev_get_property_array - return an ACPI array property with given name + * @adev: ACPI device to get property + * @name: Name of the property + * @type: Expected type of array elements + * @obj: Location to store a pointer to the property value (if not NULL) + * + * Look up an array property with @name and store a pointer to the resulting + * ACPI object at the location pointed to by @obj if found. + * + * Callers must not attempt to free the returned objects. Those objects will be + * freed by the ACPI core automatically during the removal of @adev. + * + * Return: %0 if array property (package) with @name has been found (success), + * %-EINVAL if the arguments are invalid, + * %-ENODATA if the property doesn't exist, + * %-EPROTO if the property is not a package or the type of its elements + * doesn't match @type. + */ +int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, + acpi_object_type type, + const union acpi_object **obj) +{ + const union acpi_object *prop; + int ret, i; + + ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop); + if (ret) + return ret; + + if (type != ACPI_TYPE_ANY) { + /* Check that all elements are of correct type. */ + for (i = 0; i < prop->package.count; i++) + if (prop->package.elements[i].type != type) + return -EPROTO; + } + if (obj) + *obj = prop; + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_dev_get_property_array); + +/** + * acpi_dev_get_property_reference - returns handle to the referenced object + * @adev: ACPI device to get property + * @name: Name of the property + * @size_prop: Name of the "size" property in referenced object + * @index: Index of the reference to return + * @args: Location to store the returned reference with optional arguments + * + * Find property with @name, verifify that it is a package containing at least + * one object reference and if so, store the ACPI device object pointer to the + * target object in @args->adev. + * + * If the reference includes arguments (@size_prop is not %NULL) follow the + * reference and check whether or not there is an integer property @size_prop + * under the target object and if so, whether or not its value matches the + * number of arguments that follow the reference. If there's more than one + * reference in the property value package, @index is used to select the one to + * return. + * + * Return: %0 on success, negative error code on failure. + */ +int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, + const char *size_prop, size_t index, + struct acpi_reference_args *args) +{ + const union acpi_object *element, *end; + const union acpi_object *obj; + struct acpi_device *device; + int ret, idx = 0; + + ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj); + if (ret) + return ret; + + /* + * The simplest case is when the value is a single reference. Just + * return that reference then. + */ + if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { + if (size_prop || index) + return -EINVAL; + + ret = acpi_bus_get_device(obj->reference.handle, &device); + if (ret) + return ret; + + args->adev = device; + args->nargs = 0; + return 0; + } + + /* + * If it is not a single reference, then it is a package of + * references followed by number of ints as follows: + * + * Package () { REF, INT, REF, INT, INT } + * + * The index argument is then used to determine which reference + * the caller wants (along with the arguments). + */ + if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) + return -EPROTO; + + element = obj->package.elements; + end = element + obj->package.count; + + while (element < end) { + u32 nargs, i; + + if (element->type != ACPI_TYPE_LOCAL_REFERENCE) + return -EPROTO; + + ret = acpi_bus_get_device(element->reference.handle, &device); + if (ret) + return -ENODEV; + + element++; + nargs = 0; + + if (size_prop) { + const union acpi_object *prop; + + /* + * Find out how many arguments the refenced object + * expects by reading its size_prop property. + */ + ret = acpi_dev_get_property(device, size_prop, + ACPI_TYPE_INTEGER, &prop); + if (ret) + return ret; + + nargs = prop->integer.value; + if (nargs > MAX_ACPI_REFERENCE_ARGS + || element + nargs > end) + return -EPROTO; + + /* + * Skip to the start of the arguments and verify + * that they all are in fact integers. + */ + for (i = 0; i < nargs; i++) + if (element[i].type != ACPI_TYPE_INTEGER) + return -EPROTO; + } else { + /* assume following integer elements are all args */ + for (i = 0; element + i < end; i++) { + int type = element[i].type; + + if (type == ACPI_TYPE_INTEGER) + nargs++; + else if (type == ACPI_TYPE_LOCAL_REFERENCE) + break; + else + return -EPROTO; + } + } + + if (idx++ == index) { + args->adev = device; + args->nargs = nargs; + for (i = 0; i < nargs; i++) + args->args[i] = element[i].integer.value; + + return 0; + } + + element += nargs; + } + + return -EPROTO; +} +EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0476e90b2091..40d80ac0552f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -922,6 +922,7 @@ static void acpi_device_release(struct device *dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); + acpi_free_properties(acpi_dev); acpi_free_pnp_ids(&acpi_dev->pnp); acpi_free_power_resources_lists(acpi_dev); kfree(acpi_dev); @@ -1926,6 +1927,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, acpi_set_device_status(device, sta); acpi_device_get_busid(device); acpi_set_pnp_ids(handle, &device->pnp, type); + acpi_init_properties(device); acpi_bus_get_flags(device); device->flags.match_driver = false; device->flags.initialized = true; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f34a0835aa4f..475781170091 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -337,6 +337,12 @@ struct acpi_device_physical_node { bool put_online:1; }; +/* ACPI Device Specific Data (_DSD) */ +struct acpi_device_data { + const union acpi_object *pointer; + const union acpi_object *properties; +}; + /* Device */ struct acpi_device { int device_type; @@ -353,6 +359,7 @@ struct acpi_device { struct acpi_device_wakeup wakeup; struct acpi_device_perf performance; struct acpi_device_dir dir; + struct acpi_device_data data; struct acpi_scan_handler *handler; struct acpi_hotplug_context *hp; struct acpi_driver *driver; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 407a12f663eb..dcdf8738898c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -659,4 +659,44 @@ do { \ #endif #endif +/* Device properties */ + +#define MAX_ACPI_REFERENCE_ARGS 8 +struct acpi_reference_args { + struct acpi_device *adev; + size_t nargs; + u64 args[MAX_ACPI_REFERENCE_ARGS]; +}; + +#ifdef CONFIG_ACPI +int acpi_dev_get_property(struct acpi_device *adev, const char *name, + acpi_object_type type, const union acpi_object **obj); +int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, + acpi_object_type type, + const union acpi_object **obj); +int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, + const char *cells_name, size_t index, + struct acpi_reference_args *args); +#else +static inline int acpi_dev_get_property(struct acpi_device *adev, + const char *name, acpi_object_type type, + const union acpi_object **obj) +{ + return -ENXIO; +} +static inline int acpi_dev_get_property_array(struct acpi_device *adev, + const char *name, + acpi_object_type type, + const union acpi_object **obj) +{ + return -ENXIO; +} +static inline int acpi_dev_get_property_reference(struct acpi_device *adev, + const char *name, const char *cells_name, + size_t index, struct acpi_reference_args *args) +{ + return -ENXIO; +} +#endif + #endif /*_LINUX_ACPI_H*/ -- GitLab From b31384fa5de37a100507751dfb5c0a49d06cee67 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 4 Nov 2014 01:28:56 +0100 Subject: [PATCH 2994/9457] Driver core: Unified device properties interface for platform firmware Add a uniform interface by which device drivers can request device properties from the platform firmware by providing a property name and the corresponding data type. The purpose of it is to help to write portable code that won't depend on any particular platform firmware interface. The following general helper functions are added: device_property_present() device_property_read_u8() device_property_read_u16() device_property_read_u32() device_property_read_u64() device_property_read_string() device_property_read_u8_array() device_property_read_u16_array() device_property_read_u32_array() device_property_read_u64_array() device_property_read_string_array() The first one allows the caller to check if the given property is present. The next 5 of them allow single-valued properties of various types to be retrieved in a uniform way. The remaining 5 are for reading properties with multiple values (arrays of either numbers or strings). The interface covers both ACPI and Device Trees. This change set includes material from Mika Westerberg and Aaron Lu. Signed-off-by: Aaron Lu Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 178 +++++++++++++++++++++++++++++++++++++ drivers/base/Makefile | 2 +- drivers/base/property.c | 185 +++++++++++++++++++++++++++++++++++++++ drivers/of/base.c | 33 +++++++ include/linux/acpi.h | 32 +++++++ include/linux/of.h | 12 +++ include/linux/property.h | 73 +++++++++++++++ 7 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 drivers/base/property.c create mode 100644 include/linux/property.h diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index c4a3e800e82c..2541b1fd1fa5 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -362,3 +362,181 @@ int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, return -EPROTO; } EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); + +int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, + void **valptr) +{ + return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, + (const union acpi_object **)valptr); +} + +int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, + enum dev_prop_type proptype, void *val) +{ + const union acpi_object *obj; + int ret; + + if (!val) + return -EINVAL; + + if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { + ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj); + if (ret) + return ret; + + switch (proptype) { + case DEV_PROP_U8: + if (obj->integer.value > U8_MAX) + return -EOVERFLOW; + *(u8 *)val = obj->integer.value; + break; + case DEV_PROP_U16: + if (obj->integer.value > U16_MAX) + return -EOVERFLOW; + *(u16 *)val = obj->integer.value; + break; + case DEV_PROP_U32: + if (obj->integer.value > U32_MAX) + return -EOVERFLOW; + *(u32 *)val = obj->integer.value; + break; + default: + *(u64 *)val = obj->integer.value; + break; + } + } else if (proptype == DEV_PROP_STRING) { + ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj); + if (ret) + return ret; + + *(char **)val = obj->string.pointer; + } else { + ret = -EINVAL; + } + return ret; +} + +static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, + size_t nval) +{ + int i; + + for (i = 0; i < nval; i++) { + if (items[i].type != ACPI_TYPE_INTEGER) + return -EPROTO; + if (items[i].integer.value > U8_MAX) + return -EOVERFLOW; + + val[i] = items[i].integer.value; + } + return 0; +} + +static int acpi_copy_property_array_u16(const union acpi_object *items, + u16 *val, size_t nval) +{ + int i; + + for (i = 0; i < nval; i++) { + if (items[i].type != ACPI_TYPE_INTEGER) + return -EPROTO; + if (items[i].integer.value > U16_MAX) + return -EOVERFLOW; + + val[i] = items[i].integer.value; + } + return 0; +} + +static int acpi_copy_property_array_u32(const union acpi_object *items, + u32 *val, size_t nval) +{ + int i; + + for (i = 0; i < nval; i++) { + if (items[i].type != ACPI_TYPE_INTEGER) + return -EPROTO; + if (items[i].integer.value > U32_MAX) + return -EOVERFLOW; + + val[i] = items[i].integer.value; + } + return 0; +} + +static int acpi_copy_property_array_u64(const union acpi_object *items, + u64 *val, size_t nval) +{ + int i; + + for (i = 0; i < nval; i++) { + if (items[i].type != ACPI_TYPE_INTEGER) + return -EPROTO; + + val[i] = items[i].integer.value; + } + return 0; +} + +static int acpi_copy_property_array_string(const union acpi_object *items, + char **val, size_t nval) +{ + int i; + + for (i = 0; i < nval; i++) { + if (items[i].type != ACPI_TYPE_STRING) + return -EPROTO; + + val[i] = items[i].string.pointer; + } + return 0; +} + +int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, + enum dev_prop_type proptype, void *val, size_t nval) +{ + const union acpi_object *obj; + const union acpi_object *items; + int ret; + + if (val && nval == 1) { + ret = acpi_dev_prop_read_single(adev, propname, proptype, val); + if (!ret) + return ret; + } + + ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj); + if (ret) + return ret; + + if (!val) + return obj->package.count; + else if (nval <= 0) + return -EINVAL; + + if (nval > obj->package.count) + return -EOVERFLOW; + + items = obj->package.elements; + switch (proptype) { + case DEV_PROP_U8: + ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); + break; + case DEV_PROP_U16: + ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); + break; + case DEV_PROP_U32: + ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); + break; + case DEV_PROP_U64: + ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); + break; + case DEV_PROP_STRING: + ret = acpi_copy_property_array_string(items, (char **)val, nval); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 6922cd6850a2..53c3fe1aeb29 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o \ - topology.o container.o + topology.o container.o property.o obj-$(CONFIG_DEVTMPFS) += devtmpfs.o obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ diff --git a/drivers/base/property.c b/drivers/base/property.c new file mode 100644 index 000000000000..6a94ef6e83c9 --- /dev/null +++ b/drivers/base/property.c @@ -0,0 +1,185 @@ +/* + * property.c - Unified device property interface. + * + * Copyright (C) 2014, Intel Corporation + * Authors: Rafael J. Wysocki + * Mika Westerberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +/** + * device_property_present - check if a property of a device is present + * @dev: Device whose property is being checked + * @propname: Name of the property + * + * Check if property @propname is present in the device firmware description. + */ +bool device_property_present(struct device *dev, const char *propname) +{ + if (IS_ENABLED(CONFIG_OF) && dev->of_node) + return of_property_read_bool(dev->of_node, propname); + + return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL); +} +EXPORT_SYMBOL_GPL(device_property_present); + +#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ + (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ + : of_property_count_elems_of_size((node), (propname), sizeof(type)) + +#define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \ + IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \ + (OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \ + _val_, _nval_)) : \ + acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \ + _proptype_, _val_, _nval_) + +/** + * device_property_read_u8_array - return a u8 array property of a device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Function reads an array of u8 properties with @propname from the device + * firmware description and stores them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected. + */ +int device_property_read_u8_array(struct device *dev, const char *propname, + u8 *val, size_t nval) +{ + return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval); +} +EXPORT_SYMBOL_GPL(device_property_read_u8_array); + +/** + * device_property_read_u16_array - return a u16 array property of a device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Function reads an array of u16 properties with @propname from the device + * firmware description and stores them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected. + */ +int device_property_read_u16_array(struct device *dev, const char *propname, + u16 *val, size_t nval) +{ + return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval); +} +EXPORT_SYMBOL_GPL(device_property_read_u16_array); + +/** + * device_property_read_u32_array - return a u32 array property of a device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Function reads an array of u32 properties with @propname from the device + * firmware description and stores them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected. + */ +int device_property_read_u32_array(struct device *dev, const char *propname, + u32 *val, size_t nval) +{ + return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval); +} +EXPORT_SYMBOL_GPL(device_property_read_u32_array); + +/** + * device_property_read_u64_array - return a u64 array property of a device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Function reads an array of u64 properties with @propname from the device + * firmware description and stores them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected. + */ +int device_property_read_u64_array(struct device *dev, const char *propname, + u64 *val, size_t nval) +{ + return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval); +} +EXPORT_SYMBOL_GPL(device_property_read_u64_array); + +/** + * device_property_read_string_array - return a string array property of device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Function reads an array of string properties with @propname from the device + * firmware description and stores them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO or %-EILSEQ if the property is not an array of strings, + * %-EOVERFLOW if the size of the property is not as expected. + */ +int device_property_read_string_array(struct device *dev, const char *propname, + const char **val, size_t nval) +{ + return IS_ENABLED(CONFIG_OF) && dev->of_node ? + of_property_read_string_array(dev->of_node, propname, val, nval) : + acpi_dev_prop_read(ACPI_COMPANION(dev), propname, + DEV_PROP_STRING, val, nval); +} +EXPORT_SYMBOL_GPL(device_property_read_string_array); + +/** + * device_property_read_string - return a string property of a device + * @dev: Device to get the property of + * @propname: Name of the property + * @val: The value is stored here + * + * Function reads property @propname from the device firmware description and + * stores the value into @val if found. The value is checked to be a string. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO or %-EILSEQ if the property type is not a string. + */ +int device_property_read_string(struct device *dev, const char *propname, + const char **val) +{ + return IS_ENABLED(CONFIG_OF) && dev->of_node ? + of_property_read_string(dev->of_node, propname, val) : + acpi_dev_prop_read(ACPI_COMPANION(dev), propname, + DEV_PROP_STRING, val, 1); +} +EXPORT_SYMBOL_GPL(device_property_read_string); diff --git a/drivers/of/base.c b/drivers/of/base.c index 3823edf2d012..4c2ccde42427 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1249,6 +1249,39 @@ int of_property_read_u64(const struct device_node *np, const char *propname, } EXPORT_SYMBOL_GPL(of_property_read_u64); +/** + * of_property_read_u64_array - Find and read an array of 64 bit integers + * from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 64-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_values is modified only if a valid u64 value can be decoded. + */ +int of_property_read_u64_array(const struct device_node *np, + const char *propname, u64 *out_values, + size_t sz) +{ + const __be32 *val = of_find_property_value_of_size(np, propname, + (sz * sizeof(*out_values))); + + if (IS_ERR(val)) + return PTR_ERR(val); + + while (sz--) { + *out_values++ = of_read_number(val, 2); + val += 2; + } + return 0; +} + /** * of_property_read_string - Find and read a string from a property * @np: device node from which the property value is to be read. diff --git a/include/linux/acpi.h b/include/linux/acpi.h index dcdf8738898c..76d64d6a903a 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -28,6 +28,7 @@ #include #include /* for struct resource */ #include +#include #ifndef _LINUX #define _LINUX @@ -677,6 +678,13 @@ int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, const char *cells_name, size_t index, struct acpi_reference_args *args); + +int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, + void **valptr); +int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, + enum dev_prop_type proptype, void *val); +int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, + enum dev_prop_type proptype, void *val, size_t nval); #else static inline int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, @@ -697,6 +705,30 @@ static inline int acpi_dev_get_property_reference(struct acpi_device *adev, { return -ENXIO; } + +static inline int acpi_dev_prop_get(struct acpi_device *adev, + const char *propname, + void **valptr) +{ + return -ENXIO; +} + +static inline int acpi_dev_prop_read_single(struct acpi_device *adev, + const char *propname, + enum dev_prop_type proptype, + void *val) +{ + return -ENXIO; +} + +static inline int acpi_dev_prop_read(struct acpi_device *adev, + const char *propname, + enum dev_prop_type proptype, + void *val, size_t nval) +{ + return -ENXIO; +} + #endif #endif /*_LINUX_ACPI_H*/ diff --git a/include/linux/of.h b/include/linux/of.h index 29f0adc5f3e4..ce9f6a2b3532 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -263,6 +264,10 @@ extern int of_property_read_u32_array(const struct device_node *np, size_t sz); extern int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value); +extern int of_property_read_u64_array(const struct device_node *np, + const char *propname, + u64 *out_values, + size_t sz); extern int of_property_read_string(struct device_node *np, const char *propname, @@ -477,6 +482,13 @@ static inline int of_property_read_u32_array(const struct device_node *np, return -ENOSYS; } +static inline int of_property_read_u64_array(const struct device_node *np, + const char *propname, + u64 *out_values, size_t sz) +{ + return -ENOSYS; +} + static inline int of_property_read_string(struct device_node *np, const char *propname, const char **out_string) diff --git a/include/linux/property.h b/include/linux/property.h new file mode 100644 index 000000000000..9242fb0221ba --- /dev/null +++ b/include/linux/property.h @@ -0,0 +1,73 @@ +/* + * property.h - Unified device property interface. + * + * Copyright (C) 2014, Intel Corporation + * Authors: Rafael J. Wysocki + * Mika Westerberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _LINUX_PROPERTY_H_ +#define _LINUX_PROPERTY_H_ + +#include + +struct device; + +enum dev_prop_type { + DEV_PROP_U8, + DEV_PROP_U16, + DEV_PROP_U32, + DEV_PROP_U64, + DEV_PROP_STRING, + DEV_PROP_MAX, +}; + +bool device_property_present(struct device *dev, const char *propname); +int device_property_read_u8_array(struct device *dev, const char *propname, + u8 *val, size_t nval); +int device_property_read_u16_array(struct device *dev, const char *propname, + u16 *val, size_t nval); +int device_property_read_u32_array(struct device *dev, const char *propname, + u32 *val, size_t nval); +int device_property_read_u64_array(struct device *dev, const char *propname, + u64 *val, size_t nval); +int device_property_read_string_array(struct device *dev, const char *propname, + const char **val, size_t nval); +int device_property_read_string(struct device *dev, const char *propname, + const char **val); + +static inline bool device_property_read_bool(struct device *dev, + const char *propname) +{ + return device_property_present(dev, propname); +} + +static inline int device_property_read_u8(struct device *dev, + const char *propname, u8 *val) +{ + return device_property_read_u8_array(dev, propname, val, 1); +} + +static inline int device_property_read_u16(struct device *dev, + const char *propname, u16 *val) +{ + return device_property_read_u16_array(dev, propname, val, 1); +} + +static inline int device_property_read_u32(struct device *dev, + const char *propname, u32 *val) +{ + return device_property_read_u32_array(dev, propname, val, 1); +} + +static inline int device_property_read_u64(struct device *dev, + const char *propname, u64 *val) +{ + return device_property_read_u64_array(dev, propname, val, 1); +} + +#endif /* _LINUX_PROPERTY_H_ */ -- GitLab From 733e625139fe455b4d910ac63c18c90f7cbe2d6f Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 21 Oct 2014 13:33:56 +0200 Subject: [PATCH 2995/9457] ACPI: Allow drivers to match using Device Tree compatible property We have lots of existing Device Tree enabled drivers and allocating separate _HID for each is not feasible. Instead we allocate special _HID "PRP0001" that means that the match should be done using Device Tree compatible property using driver's .of_match_table instead if the driver is missing .acpi_match_table. If there is a need to distinguish from where the device is enumerated (DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev). Signed-off-by: Mika Westerberg Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 39 +++++++++++++++ drivers/acpi/scan.c | 106 +++++++++++++++++++++++++++++++++++----- include/acpi/acpi_bus.h | 1 + include/linux/acpi.h | 8 +-- 4 files changed, 137 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 2541b1fd1fa5..27add91bc270 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -76,6 +76,42 @@ static bool acpi_properties_format_valid(const union acpi_object *properties) return true; } +static void acpi_init_of_compatible(struct acpi_device *adev) +{ + const union acpi_object *of_compatible; + struct acpi_hardware_id *hwid; + bool acpi_of = false; + int ret; + + /* + * Check if the special PRP0001 ACPI ID is present and in that + * case we fill in Device Tree compatible properties for this + * device. + */ + list_for_each_entry(hwid, &adev->pnp.ids, list) { + if (!strcmp(hwid->id, "PRP0001")) { + acpi_of = true; + break; + } + } + + if (!acpi_of) + return; + + ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING, + &of_compatible); + if (ret) { + ret = acpi_dev_get_property(adev, "compatible", + ACPI_TYPE_STRING, &of_compatible); + if (ret) { + acpi_handle_warn(adev->handle, + "PRP0001 requires compatible property\n"); + return; + } + } + adev->data.of_compatible = of_compatible; +} + void acpi_init_properties(struct acpi_device *adev) { struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; @@ -119,6 +155,8 @@ void acpi_init_properties(struct acpi_device *adev) adev->data.pointer = buf.pointer; adev->data.properties = properties; + + acpi_init_of_compatible(adev); return; } @@ -130,6 +168,7 @@ void acpi_init_properties(struct acpi_device *adev) void acpi_free_properties(struct acpi_device *adev) { ACPI_FREE((void *)adev->data.pointer); + adev->data.of_compatible = NULL; adev->data.pointer = NULL; adev->data.properties = NULL; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 40d80ac0552f..3a8f66444532 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -124,17 +124,56 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, if (list_empty(&acpi_dev->pnp.ids)) return 0; - len = snprintf(modalias, size, "acpi:"); - size -= len; - - list_for_each_entry(id, &acpi_dev->pnp.ids, list) { - count = snprintf(&modalias[len], size, "%s:", id->id); - if (count < 0) - return -EINVAL; - if (count >= size) - return -ENOMEM; - len += count; - size -= count; + /* + * If the device has PRP0001 we expose DT compatible modalias + * instead in form of of:NnameTCcompatible. + */ + if (acpi_dev->data.of_compatible) { + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; + const union acpi_object *of_compatible, *obj; + int i, nval; + char *c; + + acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); + /* DT strings are all in lower case */ + for (c = buf.pointer; *c != '\0'; c++) + *c = tolower(*c); + + len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); + ACPI_FREE(buf.pointer); + + of_compatible = acpi_dev->data.of_compatible; + if (of_compatible->type == ACPI_TYPE_PACKAGE) { + nval = of_compatible->package.count; + obj = of_compatible->package.elements; + } else { /* Must be ACPI_TYPE_STRING. */ + nval = 1; + obj = of_compatible; + } + for (i = 0; i < nval; i++, obj++) { + count = snprintf(&modalias[len], size, "C%s", + obj->string.pointer); + if (count < 0) + return -EINVAL; + if (count >= size) + return -ENOMEM; + + len += count; + size -= count; + } + } else { + len = snprintf(modalias, size, "acpi:"); + size -= len; + + list_for_each_entry(id, &acpi_dev->pnp.ids, list) { + count = snprintf(&modalias[len], size, "%s:", id->id); + if (count < 0) + return -EINVAL; + if (count >= size) + return -ENOMEM; + len += count; + size -= count; + } } modalias[len] = '\0'; @@ -902,6 +941,51 @@ int acpi_match_device_ids(struct acpi_device *device, } EXPORT_SYMBOL(acpi_match_device_ids); +/* Performs match against special "PRP0001" shoehorn ACPI ID */ +static bool acpi_of_driver_match_device(struct device *dev, + const struct device_driver *drv) +{ + const union acpi_object *of_compatible, *obj; + struct acpi_device *adev; + int i, nval; + + adev = ACPI_COMPANION(dev); + if (!adev) + return false; + + of_compatible = adev->data.of_compatible; + if (!drv->of_match_table || !of_compatible) + return false; + + if (of_compatible->type == ACPI_TYPE_PACKAGE) { + nval = of_compatible->package.count; + obj = of_compatible->package.elements; + } else { /* Must be ACPI_TYPE_STRING. */ + nval = 1; + obj = of_compatible; + } + /* Now we can look for the driver DT compatible strings */ + for (i = 0; i < nval; i++, obj++) { + const struct of_device_id *id; + + for (id = drv->of_match_table; id->compatible[0]; id++) + if (!strcasecmp(obj->string.pointer, id->compatible)) + return true; + } + + return false; +} + +bool acpi_driver_match_device(struct device *dev, + const struct device_driver *drv) +{ + if (!drv->acpi_match_table) + return acpi_of_driver_match_device(dev, drv); + + return !!acpi_match_device(drv->acpi_match_table, dev); +} +EXPORT_SYMBOL_GPL(acpi_driver_match_device); + static void acpi_free_power_resources_lists(struct acpi_device *device) { int i; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 475781170091..f59cbf860658 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -341,6 +341,7 @@ struct acpi_device_physical_node { struct acpi_device_data { const union acpi_object *pointer; const union acpi_object *properties; + const union acpi_object *of_compatible; }; /* Device */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 76d64d6a903a..38296d686c55 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -424,12 +424,8 @@ extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, const struct device *dev); -static inline bool acpi_driver_match_device(struct device *dev, - const struct device_driver *drv) -{ - return !!acpi_match_device(drv->acpi_match_table, dev); -} - +extern bool acpi_driver_match_device(struct device *dev, + const struct device_driver *drv); int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *); int acpi_device_modalias(struct device *, char *, int); -- GitLab From f60e7074902a66d9a132a971ecda63ee5b8bc154 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 21 Oct 2014 13:33:56 +0200 Subject: [PATCH 2996/9457] misc: at25: Make use of device property API Make use of device property API in this driver so that both DT and ACPI based systems can use this driver. In addition we hard-code the name of the chip to be "at25" for the reason that there is no common mechanism to fetch name of the firmware node. The only existing user (arch/arm/boot/dts/phy3250.dts) uses the same name so it should continue to work. Signed-off-by: Mika Westerberg Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/misc/eeprom/at25.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 634f72929e12..0a1af93ec638 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -18,7 +18,7 @@ #include #include -#include +#include /* * NOTE: this is an *EEPROM* driver. The vagaries of product naming @@ -301,35 +301,33 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf, /*-------------------------------------------------------------------------*/ -static int at25_np_to_chip(struct device *dev, - struct device_node *np, - struct spi_eeprom *chip) +static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip) { u32 val; memset(chip, 0, sizeof(*chip)); - strncpy(chip->name, np->name, sizeof(chip->name)); + strncpy(chip->name, "at25", sizeof(chip->name)); - if (of_property_read_u32(np, "size", &val) == 0 || - of_property_read_u32(np, "at25,byte-len", &val) == 0) { + if (device_property_read_u32(dev, "size", &val) == 0 || + device_property_read_u32(dev, "at25,byte-len", &val) == 0) { chip->byte_len = val; } else { dev_err(dev, "Error: missing \"size\" property\n"); return -ENODEV; } - if (of_property_read_u32(np, "pagesize", &val) == 0 || - of_property_read_u32(np, "at25,page-size", &val) == 0) { + if (device_property_read_u32(dev, "pagesize", &val) == 0 || + device_property_read_u32(dev, "at25,page-size", &val) == 0) { chip->page_size = (u16)val; } else { dev_err(dev, "Error: missing \"pagesize\" property\n"); return -ENODEV; } - if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) { + if (device_property_read_u32(dev, "at25,addr-mode", &val) == 0) { chip->flags = (u16)val; } else { - if (of_property_read_u32(np, "address-width", &val)) { + if (device_property_read_u32(dev, "address-width", &val)) { dev_err(dev, "Error: missing \"address-width\" property\n"); return -ENODEV; @@ -350,7 +348,7 @@ static int at25_np_to_chip(struct device *dev, val); return -ENODEV; } - if (of_find_property(np, "read-only", NULL)) + if (device_property_present(dev, "read-only")) chip->flags |= EE_READONLY; } return 0; @@ -360,21 +358,15 @@ static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; struct spi_eeprom chip; - struct device_node *np = spi->dev.of_node; int err; int sr; int addrlen; /* Chip description */ if (!spi->dev.platform_data) { - if (np) { - err = at25_np_to_chip(&spi->dev, np, &chip); - if (err) - return err; - } else { - dev_err(&spi->dev, "Error: no chip description\n"); - return -ENODEV; - } + err = at25_fw_to_chip(&spi->dev, &chip); + if (err) + return err; } else chip = *(struct spi_eeprom *)spi->dev.platform_data; -- GitLab From 0d9a693cc8619b28f0eeb689a554647d42848fde Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 29 Oct 2014 15:41:01 +0100 Subject: [PATCH 2997/9457] gpio / ACPI: Add support for _DSD device properties With release of ACPI 5.1 and _DSD method we can finally name GPIOs (and other things as well) returned by _CRS. Previously we were only able to use integer index to find the corresponding GPIO, which is pretty error prone if the order changes. With _DSD we can now query GPIOs using name instead of an integer index, like the below example shows: // Bluetooth device with reset and shutdown GPIOs Device (BTH) { Name (_HID, ...) Name (_CRS, ResourceTemplate () { GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, "\\_SB.GPO0", 0, ResourceConsumer) {15} GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, "\\_SB.GPO0", 0, ResourceConsumer) {27, 31} }) Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }}, Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }}, } }) } The format of the supported GPIO property is: Package () { "name", Package () { ref, index, pin, active_low }} ref - The device that has _CRS containing GpioIo()/GpioInt() resources, typically this is the device itself (BTH in our case). index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero. pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero. active_low - If 1 the GPIO is marked as active_low. Since ACPI GpioIo() resource does not have field saying whether it is active low or high, the "active_low" argument can be used here. Setting it to 1 marks the GPIO as active low. In our Bluetooth example the "reset-gpio" refers to the second GpioIo() resource, second pin in that resource with the GPIO number of 31. This patch implements necessary support to gpiolib for extracting GPIOs using _DSD device properties. Signed-off-by: Mika Westerberg Acked-by: Linus Walleij Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- Documentation/acpi/gpio-properties.txt | 52 +++++++++++++++++ drivers/gpio/gpiolib-acpi.c | 78 +++++++++++++++++++++----- drivers/gpio/gpiolib.c | 30 ++++++++-- drivers/gpio/gpiolib.h | 7 ++- 4 files changed, 146 insertions(+), 21 deletions(-) create mode 100644 Documentation/acpi/gpio-properties.txt diff --git a/Documentation/acpi/gpio-properties.txt b/Documentation/acpi/gpio-properties.txt new file mode 100644 index 000000000000..3e45b8b7e4f2 --- /dev/null +++ b/Documentation/acpi/gpio-properties.txt @@ -0,0 +1,52 @@ +_DSD Device Properties Related to GPIO +-------------------------------------- + +With the release of ACPI 5.1 and the _DSD configuration objecte names +can finally be given to GPIOs (and other things as well) returned by +_CRS. Previously, we were only able to use an integer index to find +the corresponding GPIO, which is pretty error prone (it depends on +the _CRS output ordering, for example). + +With _DSD we can now query GPIOs using a name instead of an integer +index, like the ASL example below shows: + + // Bluetooth device with reset and shutdown GPIOs + Device (BTH) + { + Name (_HID, ...) + + Name (_CRS, ResourceTemplate () + { + GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, + "\\_SB.GPO0", 0, ResourceConsumer) {15} + GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, + "\\_SB.GPO0", 0, ResourceConsumer) {27, 31} + }) + + Name (_DSD, Package () + { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }}, + Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }}, + } + }) + } + +The format of the supported GPIO property is: + + Package () { "name", Package () { ref, index, pin, active_low }} + + ref - The device that has _CRS containing GpioIo()/GpioInt() resources, + typically this is the device itself (BTH in our case). + index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero. + pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero. + active_low - If 1 the GPIO is marked as active_low. + +Since ACPI GpioIo() resource does not have a field saying whether it is +active low or high, the "active_low" argument can be used here. Setting +it to 1 marks the GPIO as active low. + +In our Bluetooth example the "reset-gpio" refers to the second GpioIo() +resource, second pin in that resource with the GPIO number of 31. diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 05c6275da224..8aa6ca473748 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -290,6 +290,7 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; + int pin_index; struct gpio_desc *desc; int n; }; @@ -303,13 +304,24 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data) if (lookup->n++ == lookup->index && !lookup->desc) { const struct acpi_resource_gpio *agpio = &ares->data.gpio; + int pin_index = lookup->pin_index; + + if (pin_index >= agpio->pin_table_length) + return 1; lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr, - agpio->pin_table[0]); + agpio->pin_table[pin_index]); lookup->info.gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT; - lookup->info.active_low = - agpio->polarity == ACPI_ACTIVE_LOW; + + /* + * ActiveLow is only specified for GpioInt resource. If + * GpioIo is used then the only way to set the flag is + * to use _DSD "gpios" property. + */ + if (lookup->info.gpioint) + lookup->info.active_low = + agpio->polarity == ACPI_ACTIVE_LOW; } return 1; @@ -317,40 +329,75 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data) /** * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources - * @dev: pointer to a device to get GPIO from + * @adev: pointer to a ACPI device to get GPIO from + * @propname: Property name of the GPIO (optional) * @index: index of GpioIo/GpioInt resource (starting from %0) * @info: info pointer to fill in (optional) * - * Function goes through ACPI resources for @dev and based on @index looks + * Function goes through ACPI resources for @adev and based on @index looks * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor, * and returns it. @index matches GpioIo/GpioInt resources only so if there * are total %3 GPIO resources, the index goes from %0 to %2. * + * If @propname is specified the GPIO is looked using device property. In + * that case @index is used to select the GPIO entry in the property value + * (in case of multiple). + * * If the GPIO cannot be translated or there is an error an ERR_PTR is * returned. * * Note: if the GPIO resource has multiple entries in the pin list, this * function only returns the first. */ -struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, +struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, + const char *propname, int index, struct acpi_gpio_info *info) { struct acpi_gpio_lookup lookup; struct list_head resource_list; - struct acpi_device *adev; - acpi_handle handle; + bool active_low = false; int ret; - if (!dev) - return ERR_PTR(-EINVAL); - - handle = ACPI_HANDLE(dev); - if (!handle || acpi_bus_get_device(handle, &adev)) + if (!adev) return ERR_PTR(-ENODEV); memset(&lookup, 0, sizeof(lookup)); lookup.index = index; + if (propname) { + struct acpi_reference_args args; + + dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); + + memset(&args, 0, sizeof(args)); + ret = acpi_dev_get_property_reference(adev, propname, NULL, + index, &args); + if (ret) + return ERR_PTR(ret); + + /* + * The property was found and resolved so need to + * lookup the GPIO based on returned args instead. + */ + adev = args.adev; + if (args.nargs >= 2) { + lookup.index = args.args[0]; + lookup.pin_index = args.args[1]; + /* + * 3rd argument, if present is used to + * specify active_low. + */ + if (args.nargs >= 3) + active_low = !!args.args[2]; + } + + dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n", + dev_name(&adev->dev), args.nargs, + args.args[0], args.args[1], args.args[2]); + } else { + dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); + } + INIT_LIST_HEAD(&resource_list); ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio, &lookup); @@ -359,8 +406,11 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, acpi_dev_free_resource_list(&resource_list); - if (lookup.desc && info) + if (lookup.desc && info) { *info = lookup.info; + if (active_low) + info->active_low = active_low; + } return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8e98ca25ec7..2bca0495cb46 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1505,14 +1505,36 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { + static const char * const suffixes[] = { "gpios", "gpio" }; + struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_gpio_info info; struct gpio_desc *desc; + char propname[32]; + int i; - desc = acpi_get_gpiod_by_index(dev, idx, &info); - if (IS_ERR(desc)) - return desc; + /* Try first from _DSD */ + for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + if (con_id && strcmp(con_id, "gpios")) { + snprintf(propname, sizeof(propname), "%s-%s", + con_id, suffixes[i]); + } else { + snprintf(propname, sizeof(propname), "%s", + suffixes[i]); + } + + desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); + if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) + break; + } + + /* Then from plain _CRS GPIOs */ + if (IS_ERR(desc)) { + desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); + if (IS_ERR(desc)) + return desc; + } - if (info.gpioint && info.active_low) + if (info.active_low) *flags |= GPIO_ACTIVE_LOW; return desc; diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 9db2b6a71c5d..e3a52113a541 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -34,7 +34,8 @@ void acpi_gpiochip_remove(struct gpio_chip *chip); void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); -struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, +struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, + const char *propname, int index, struct acpi_gpio_info *info); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } @@ -47,8 +48,8 @@ static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } static inline struct gpio_desc * -acpi_get_gpiod_by_index(struct device *dev, int index, - struct acpi_gpio_info *info) +acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, + int index, struct acpi_gpio_info *info) { return ERR_PTR(-ENOSYS); } -- GitLab From c479ff093328c63ae9e496951a34f7fef550503a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 21 Oct 2014 13:33:56 +0200 Subject: [PATCH 2998/9457] gpio: sch: Consolidate core and resume banks This is actually a single device with two sets of identical registers, which just happen to start from a different offset. Instead of having separate GPIO chips created we consolidate them to be single GPIO chip. In addition having a single GPIO chip allows us to handle ACPI GPIO translation in the core in a more generic way, since the two GPIO chips share the same parent ACPI device. Signed-off-by: Mika Westerberg Acked-by: Linus Walleij Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/gpio/gpio-sch.c | 293 +++++++++++++++------------------------- 1 file changed, 112 insertions(+), 181 deletions(-) diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 41e91d70301e..99720c8bc8ed 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -29,290 +29,221 @@ #include -static DEFINE_SPINLOCK(gpio_lock); - -#define CGEN (0x00) -#define CGIO (0x04) -#define CGLV (0x08) - -#define RGEN (0x20) -#define RGIO (0x24) -#define RGLV (0x28) - -static unsigned short gpio_ba; - -static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned gpio_num) -{ - u8 curr_dirs; - unsigned short offset, bit; - - spin_lock(&gpio_lock); - - offset = CGIO + gpio_num / 8; - bit = gpio_num % 8; - - curr_dirs = inb(gpio_ba + offset); - - if (!(curr_dirs & (1 << bit))) - outb(curr_dirs | (1 << bit), gpio_ba + offset); +#define GEN 0x00 +#define GIO 0x04 +#define GLV 0x08 + +struct sch_gpio { + struct gpio_chip chip; + spinlock_t lock; + unsigned short iobase; + unsigned short core_base; + unsigned short resume_base; +}; - spin_unlock(&gpio_lock); - return 0; -} +#define to_sch_gpio(c) container_of(c, struct sch_gpio, chip) -static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num) +static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio, + unsigned reg) { - int res; - unsigned short offset, bit; + unsigned base = 0; - offset = CGLV + gpio_num / 8; - bit = gpio_num % 8; + if (gpio >= sch->resume_base) { + gpio -= sch->resume_base; + base += 0x20; + } - res = !!(inb(gpio_ba + offset) & (1 << bit)); - return res; + return base + reg + gpio / 8; } -static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val) +static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio) { - u8 curr_vals; - unsigned short offset, bit; - - spin_lock(&gpio_lock); - - offset = CGLV + gpio_num / 8; - bit = gpio_num % 8; - - curr_vals = inb(gpio_ba + offset); - - if (val) - outb(curr_vals | (1 << bit), gpio_ba + offset); - else - outb((curr_vals & ~(1 << bit)), gpio_ba + offset); - spin_unlock(&gpio_lock); + if (gpio >= sch->resume_base) + gpio -= sch->resume_base; + return gpio % 8; } -static int sch_gpio_core_direction_out(struct gpio_chip *gc, - unsigned gpio_num, int val) +static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio) { - u8 curr_dirs; unsigned short offset, bit; + u8 enable; - spin_lock(&gpio_lock); + spin_lock(&sch->lock); - offset = CGIO + gpio_num / 8; - bit = gpio_num % 8; - - curr_dirs = inb(gpio_ba + offset); - if (curr_dirs & (1 << bit)) - outb(curr_dirs & ~(1 << bit), gpio_ba + offset); + offset = sch_gpio_offset(sch, gpio, GEN); + bit = sch_gpio_bit(sch, gpio); - spin_unlock(&gpio_lock); + enable = inb(sch->iobase + offset); + if (!(enable & (1 << bit))) + outb(enable | (1 << bit), sch->iobase + offset); - /* - * according to the datasheet, writing to the level register has no - * effect when GPIO is programmed as input. - * Actually the the level register is read-only when configured as input. - * Thus presetting the output level before switching to output is _NOT_ possible. - * Hence we set the level after configuring the GPIO as output. - * But we cannot prevent a short low pulse if direction is set to high - * and an external pull-up is connected. - */ - sch_gpio_core_set(gc, gpio_num, val); - return 0; + spin_unlock(&sch->lock); } -static struct gpio_chip sch_gpio_core = { - .label = "sch_gpio_core", - .owner = THIS_MODULE, - .direction_input = sch_gpio_core_direction_in, - .get = sch_gpio_core_get, - .direction_output = sch_gpio_core_direction_out, - .set = sch_gpio_core_set, -}; - -static int sch_gpio_resume_direction_in(struct gpio_chip *gc, - unsigned gpio_num) +static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num) { + struct sch_gpio *sch = to_sch_gpio(gc); u8 curr_dirs; unsigned short offset, bit; - spin_lock(&gpio_lock); + spin_lock(&sch->lock); - offset = RGIO + gpio_num / 8; - bit = gpio_num % 8; + offset = sch_gpio_offset(sch, gpio_num, GIO); + bit = sch_gpio_bit(sch, gpio_num); - curr_dirs = inb(gpio_ba + offset); + curr_dirs = inb(sch->iobase + offset); if (!(curr_dirs & (1 << bit))) - outb(curr_dirs | (1 << bit), gpio_ba + offset); + outb(curr_dirs | (1 << bit), sch->iobase + offset); - spin_unlock(&gpio_lock); + spin_unlock(&sch->lock); return 0; } -static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num) +static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num) { + struct sch_gpio *sch = to_sch_gpio(gc); + int res; unsigned short offset, bit; - offset = RGLV + gpio_num / 8; - bit = gpio_num % 8; + offset = sch_gpio_offset(sch, gpio_num, GLV); + bit = sch_gpio_bit(sch, gpio_num); + + res = !!(inb(sch->iobase + offset) & (1 << bit)); - return !!(inb(gpio_ba + offset) & (1 << bit)); + return res; } -static void sch_gpio_resume_set(struct gpio_chip *gc, - unsigned gpio_num, int val) +static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val) { + struct sch_gpio *sch = to_sch_gpio(gc); u8 curr_vals; unsigned short offset, bit; - spin_lock(&gpio_lock); + spin_lock(&sch->lock); - offset = RGLV + gpio_num / 8; - bit = gpio_num % 8; + offset = sch_gpio_offset(sch, gpio_num, GLV); + bit = sch_gpio_bit(sch, gpio_num); - curr_vals = inb(gpio_ba + offset); + curr_vals = inb(sch->iobase + offset); if (val) - outb(curr_vals | (1 << bit), gpio_ba + offset); + outb(curr_vals | (1 << bit), sch->iobase + offset); else - outb((curr_vals & ~(1 << bit)), gpio_ba + offset); + outb((curr_vals & ~(1 << bit)), sch->iobase + offset); - spin_unlock(&gpio_lock); + spin_unlock(&sch->lock); } -static int sch_gpio_resume_direction_out(struct gpio_chip *gc, - unsigned gpio_num, int val) +static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num, + int val) { + struct sch_gpio *sch = to_sch_gpio(gc); u8 curr_dirs; unsigned short offset, bit; - offset = RGIO + gpio_num / 8; - bit = gpio_num % 8; + spin_lock(&sch->lock); - spin_lock(&gpio_lock); + offset = sch_gpio_offset(sch, gpio_num, GIO); + bit = sch_gpio_bit(sch, gpio_num); - curr_dirs = inb(gpio_ba + offset); + curr_dirs = inb(sch->iobase + offset); if (curr_dirs & (1 << bit)) - outb(curr_dirs & ~(1 << bit), gpio_ba + offset); + outb(curr_dirs & ~(1 << bit), sch->iobase + offset); - spin_unlock(&gpio_lock); + spin_unlock(&sch->lock); /* - * according to the datasheet, writing to the level register has no - * effect when GPIO is programmed as input. - * Actually the the level register is read-only when configured as input. - * Thus presetting the output level before switching to output is _NOT_ possible. - * Hence we set the level after configuring the GPIO as output. - * But we cannot prevent a short low pulse if direction is set to high - * and an external pull-up is connected. - */ - sch_gpio_resume_set(gc, gpio_num, val); + * according to the datasheet, writing to the level register has no + * effect when GPIO is programmed as input. + * Actually the the level register is read-only when configured as input. + * Thus presetting the output level before switching to output is _NOT_ possible. + * Hence we set the level after configuring the GPIO as output. + * But we cannot prevent a short low pulse if direction is set to high + * and an external pull-up is connected. + */ + sch_gpio_set(gc, gpio_num, val); return 0; } -static struct gpio_chip sch_gpio_resume = { - .label = "sch_gpio_resume", +static struct gpio_chip sch_gpio_chip = { + .label = "sch_gpio", .owner = THIS_MODULE, - .direction_input = sch_gpio_resume_direction_in, - .get = sch_gpio_resume_get, - .direction_output = sch_gpio_resume_direction_out, - .set = sch_gpio_resume_set, + .direction_input = sch_gpio_direction_in, + .get = sch_gpio_get, + .direction_output = sch_gpio_direction_out, + .set = sch_gpio_set, }; static int sch_gpio_probe(struct platform_device *pdev) { + struct sch_gpio *sch; struct resource *res; - int err, id; - id = pdev->id; - if (!id) - return -ENODEV; + sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL); + if (!sch) + return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) return -EBUSY; - if (!request_region(res->start, resource_size(res), pdev->name)) + if (!devm_request_region(&pdev->dev, res->start, resource_size(res), + pdev->name)) return -EBUSY; - gpio_ba = res->start; + spin_lock_init(&sch->lock); + sch->iobase = res->start; + sch->chip = sch_gpio_chip; + sch->chip.label = dev_name(&pdev->dev); + sch->chip.dev = &pdev->dev; - switch (id) { + switch (pdev->id) { case PCI_DEVICE_ID_INTEL_SCH_LPC: - sch_gpio_core.base = 0; - sch_gpio_core.ngpio = 10; - sch_gpio_resume.base = 10; - sch_gpio_resume.ngpio = 4; + sch->core_base = 0; + sch->resume_base = 10; + sch->chip.ngpio = 14; + /* * GPIO[6:0] enabled by default * GPIO7 is configured by the CMC as SLPIOVR * Enable GPIO[9:8] core powered gpios explicitly */ - outb(0x3, gpio_ba + CGEN + 1); + sch_gpio_enable(sch, 8); + sch_gpio_enable(sch, 9); /* * SUS_GPIO[2:0] enabled by default * Enable SUS_GPIO3 resume powered gpio explicitly */ - outb(0x8, gpio_ba + RGEN); + sch_gpio_enable(sch, 13); break; case PCI_DEVICE_ID_INTEL_ITC_LPC: - sch_gpio_core.base = 0; - sch_gpio_core.ngpio = 5; - sch_gpio_resume.base = 5; - sch_gpio_resume.ngpio = 9; + sch->core_base = 0; + sch->resume_base = 5; + sch->chip.ngpio = 14; break; case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: - sch_gpio_core.base = 0; - sch_gpio_core.ngpio = 21; - sch_gpio_resume.base = 21; - sch_gpio_resume.ngpio = 9; + sch->core_base = 0; + sch->resume_base = 21; + sch->chip.ngpio = 30; break; default: - err = -ENODEV; - goto err_sch_gpio_core; + return -ENODEV; } - sch_gpio_core.dev = &pdev->dev; - sch_gpio_resume.dev = &pdev->dev; - - err = gpiochip_add(&sch_gpio_core); - if (err < 0) - goto err_sch_gpio_core; + platform_set_drvdata(pdev, sch); - err = gpiochip_add(&sch_gpio_resume); - if (err < 0) - goto err_sch_gpio_resume; - - return 0; - -err_sch_gpio_resume: - gpiochip_remove(&sch_gpio_core); - -err_sch_gpio_core: - release_region(res->start, resource_size(res)); - gpio_ba = 0; - - return err; + return gpiochip_add(&sch->chip); } static int sch_gpio_remove(struct platform_device *pdev) { - struct resource *res; - if (gpio_ba) { - - gpiochip_remove(&sch_gpio_core); - gpiochip_remove(&sch_gpio_resume); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - - release_region(res->start, resource_size(res)); - gpio_ba = 0; - } + struct sch_gpio *sch = platform_get_drvdata(pdev); + gpiochip_remove(&sch->chip); return 0; } -- GitLab From 5c51277a9ababfa44a7f944100bdc9fbda139905 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 27 Oct 2014 23:29:32 +0100 Subject: [PATCH 2999/9457] leds: leds-gpio: Add support for GPIO descriptors GPIO descriptors are the preferred way over legacy GPIO numbers nowadays. Convert the driver to use GPIO descriptors internally but still allow passing legacy GPIO numbers from platform data to support existing platforms. Signed-off-by: Mika Westerberg Acked-by: Alexandre Courbot Acked-by: Bryan Wu Acked-by: Arnd Bergmann Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/leds/leds-gpio.c | 80 ++++++++++++++++++++++------------------ include/linux/leds.h | 1 + 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index b4518c8751c8..1ff95ce9487a 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -24,11 +25,10 @@ struct gpio_led_data { struct led_classdev cdev; - unsigned gpio; + struct gpio_desc *gpiod; struct work_struct work; u8 new_level; u8 can_sleep; - u8 active_low; u8 blinking; int (*platform_gpio_blink_set)(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off); @@ -40,12 +40,16 @@ static void gpio_led_work(struct work_struct *work) container_of(work, struct gpio_led_data, work); if (led_dat->blinking) { - led_dat->platform_gpio_blink_set(led_dat->gpio, - led_dat->new_level, - NULL, NULL); + int gpio = desc_to_gpio(led_dat->gpiod); + int level = led_dat->new_level; + + if (gpiod_is_active_low(led_dat->gpiod)) + level = !level; + + led_dat->platform_gpio_blink_set(gpio, level, NULL, NULL); led_dat->blinking = 0; } else - gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); + gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); } static void gpio_led_set(struct led_classdev *led_cdev, @@ -60,9 +64,6 @@ static void gpio_led_set(struct led_classdev *led_cdev, else level = 1; - if (led_dat->active_low) - level = !level; - /* Setting GPIOs with I2C/etc requires a task context, and we don't * seem to have a reliable way to know if we're already in one; so * let's just assume the worst. @@ -72,11 +73,16 @@ static void gpio_led_set(struct led_classdev *led_cdev, schedule_work(&led_dat->work); } else { if (led_dat->blinking) { - led_dat->platform_gpio_blink_set(led_dat->gpio, level, - NULL, NULL); + int gpio = desc_to_gpio(led_dat->gpiod); + + if (gpiod_is_active_low(led_dat->gpiod)) + level = !level; + + led_dat->platform_gpio_blink_set(gpio, level, NULL, + NULL); led_dat->blinking = 0; } else - gpio_set_value(led_dat->gpio, level); + gpiod_set_value(led_dat->gpiod, level); } } @@ -85,9 +91,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev, { struct gpio_led_data *led_dat = container_of(led_cdev, struct gpio_led_data, cdev); + int gpio = desc_to_gpio(led_dat->gpiod); led_dat->blinking = 1; - return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK, + return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK, delay_on, delay_off); } @@ -97,24 +104,33 @@ static int create_gpio_led(const struct gpio_led *template, { int ret, state; - led_dat->gpio = -1; + if (!template->gpiod) { + unsigned long flags = 0; - /* skip leds that aren't available */ - if (!gpio_is_valid(template->gpio)) { - dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n", - template->gpio, template->name); - return 0; - } + /* skip leds that aren't available */ + if (!gpio_is_valid(template->gpio)) { + dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n", + template->gpio, template->name); + return 0; + } - ret = devm_gpio_request(parent, template->gpio, template->name); - if (ret < 0) - return ret; + if (template->active_low) + flags |= GPIOF_ACTIVE_LOW; + + ret = devm_gpio_request_one(parent, template->gpio, flags, + template->name); + if (ret < 0) + return ret; + + led_dat->gpiod = gpio_to_desc(template->gpio); + if (IS_ERR(led_dat->gpiod)) + return PTR_ERR(led_dat->gpiod); + } led_dat->cdev.name = template->name; led_dat->cdev.default_trigger = template->default_trigger; - led_dat->gpio = template->gpio; - led_dat->can_sleep = gpio_cansleep(template->gpio); - led_dat->active_low = template->active_low; + led_dat->gpiod = template->gpiod; + led_dat->can_sleep = gpiod_cansleep(template->gpiod); led_dat->blinking = 0; if (blink_set) { led_dat->platform_gpio_blink_set = blink_set; @@ -122,30 +138,24 @@ static int create_gpio_led(const struct gpio_led *template, } led_dat->cdev.brightness_set = gpio_led_set; if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low; + state = !!gpiod_get_value_cansleep(led_dat->gpiod); else state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; if (!template->retain_state_suspended) led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); + ret = gpiod_direction_output(led_dat->gpiod, state); if (ret < 0) return ret; INIT_WORK(&led_dat->work, gpio_led_work); - ret = led_classdev_register(parent, &led_dat->cdev); - if (ret < 0) - return ret; - - return 0; + return led_classdev_register(parent, &led_dat->cdev); } static void delete_gpio_led(struct gpio_led_data *led) { - if (!gpio_is_valid(led->gpio)) - return; led_classdev_unregister(&led->cdev); cancel_work_sync(&led->work); } diff --git a/include/linux/leds.h b/include/linux/leds.h index a57611d0c94e..f3af5c4d9084 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -261,6 +261,7 @@ struct gpio_led { unsigned retain_state_suspended : 1; unsigned default_state : 2; /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ + struct gpio_desc *gpiod; }; #define LEDS_GPIO_DEFSTATE_OFF 0 #define LEDS_GPIO_DEFSTATE_ON 1 -- GitLab From 633a21d80b4a2cd648aa2dacdb22494ffb2f28f0 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 21 Oct 2014 23:30:25 +0200 Subject: [PATCH 3000/9457] input: gpio_keys_polled: Add support for GPIO descriptors GPIO descriptors are the preferred way over legacy GPIO numbers nowadays. Convert the driver to use GPIO descriptors internally but still allow passing legacy GPIO numbers from platform data to support existing platforms. Signed-off-by: Aaron Lu Signed-off-by: Mika Westerberg Acked-by: Alexandre Courbot Reviewed-by: Linus Walleij Acked-by: Dmitry Torokhov Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/input/keyboard/gpio_keys_polled.c | 39 ++++++++++++++++------- include/linux/gpio_keys.h | 3 ++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 432d36395f35..b7a514ced509 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -51,15 +52,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input, int state; if (bdata->can_sleep) - state = !!gpio_get_value_cansleep(button->gpio); + state = !!gpiod_get_value_cansleep(button->gpiod); else - state = !!gpio_get_value(button->gpio); + state = !!gpiod_get_value(button->gpiod); if (state != bdata->last_state) { unsigned int type = button->type ?: EV_KEY; - input_event(input, type, button->code, - !!(state ^ button->active_low)); + input_event(input, type, button->code, state); input_sync(input); bdata->count = 0; bdata->last_state = state; @@ -259,7 +259,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_keys_button_data *bdata = &bdev->data[i]; - unsigned int gpio = button->gpio; unsigned int type = button->type ?: EV_KEY; if (button->wakeup) { @@ -267,15 +266,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) return -EINVAL; } - error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN, - button->desc ? : DRV_NAME); - if (error) { - dev_err(dev, "unable to claim gpio %u, err=%d\n", - gpio, error); - return error; + /* + * Legacy GPIO number so request the GPIO here and + * convert it to descriptor. + */ + if (!button->gpiod && gpio_is_valid(button->gpio)) { + unsigned flags = 0; + + if (button->active_low) + flags |= GPIOF_ACTIVE_LOW; + + error = devm_gpio_request_one(&pdev->dev, button->gpio, + flags, button->desc ? : DRV_NAME); + if (error) { + dev_err(dev, "unable to claim gpio %u, err=%d\n", + button->gpio, error); + return error; + } + + button->gpiod = gpio_to_desc(button->gpio); } - bdata->can_sleep = gpio_cansleep(gpio); + if (IS_ERR(button->gpiod)) + return PTR_ERR(button->gpiod); + + bdata->can_sleep = gpiod_cansleep(button->gpiod); bdata->last_state = -1; bdata->threshold = DIV_ROUND_UP(button->debounce_interval, pdata->poll_interval); diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 8b622468952c..ee2d8c6f9130 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -2,6 +2,7 @@ #define _GPIO_KEYS_H struct device; +struct gpio_desc; /** * struct gpio_keys_button - configuration parameters @@ -17,6 +18,7 @@ struct device; * disable button via sysfs * @value: axis value for %EV_ABS * @irq: Irq number in case of interrupt keys + * @gpiod: GPIO descriptor */ struct gpio_keys_button { unsigned int code; @@ -29,6 +31,7 @@ struct gpio_keys_button { bool can_disable; int value; unsigned int irq; + struct gpio_desc *gpiod; }; /** -- GitLab From 8a0662d9ed2968e1186208336a8e1fab3fdfea63 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 4 Nov 2014 14:03:59 +0100 Subject: [PATCH 3001/9457] Driver core: Unified interface for firmware node properties Add new generic routines are provided for retrieving properties from device description objects in the platform firmware in case there are no struct device objects for them (either those objects have not been created yet or they do not exist at all). The following functions are provided: fwnode_property_present() fwnode_property_read_u8() fwnode_property_read_u16() fwnode_property_read_u32() fwnode_property_read_u64() fwnode_property_read_string() fwnode_property_read_u8_array() fwnode_property_read_u16_array() fwnode_property_read_u32_array() fwnode_property_read_u64_array() fwnode_property_read_string_array() in analogy with the corresponding functions for struct device added previously. For all of them, the first argument is a pointer to struct fwnode_handle (new type) that allows a device description object (depending on what platform firmware interface is in use) to be obtained. Add a new macro device_for_each_child_node() for iterating over the children of the device description object associated with a given device and a new function device_get_child_node_count() returning the number of a given device's child nodes. The interface covers both ACPI and Device Trees. Suggested-by: Grant Likely Acked-by: Greg Kroah-Hartman Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 21 ++++ drivers/base/property.c | 246 +++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_bus.h | 17 +++ include/linux/acpi.h | 26 +++++ include/linux/of.h | 22 ++++ include/linux/property.h | 70 +++++++++++ 6 files changed, 402 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3a8f66444532..9cb5cca3cfe3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1389,6 +1389,26 @@ int acpi_device_add(struct acpi_device *device, return result; } +struct acpi_device *acpi_get_next_child(struct device *dev, + struct acpi_device *child) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + struct list_head *head, *next; + + if (!adev) + return NULL; + + head = &adev->children; + if (list_empty(head)) + return NULL; + + if (!child) + return list_first_entry(head, struct acpi_device, node); + + next = child->node.next; + return next == head ? NULL : list_entry(next, struct acpi_device, node); +} + /* -------------------------------------------------------------------------- Driver Management -------------------------------------------------------------------------- */ @@ -2008,6 +2028,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, device->device_type = type; device->handle = handle; device->parent = acpi_bus_get_parent(handle); + device->fwnode.type = FWNODE_ACPI; acpi_set_device_status(device, sta); acpi_device_get_busid(device); acpi_set_pnp_ids(handle, &device->pnp, type); diff --git a/drivers/base/property.c b/drivers/base/property.c index 6a94ef6e83c9..c45845874d4f 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -31,6 +31,22 @@ bool device_property_present(struct device *dev, const char *propname) } EXPORT_SYMBOL_GPL(device_property_present); +/** + * fwnode_property_present - check if a property of a firmware node is present + * @fwnode: Firmware node whose property to check + * @propname: Name of the property + */ +bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname) +{ + if (is_of_node(fwnode)) + return of_property_read_bool(of_node(fwnode), propname); + else if (is_acpi_node(fwnode)) + return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL); + + return false; +} +EXPORT_SYMBOL_GPL(fwnode_property_present); + #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ : of_property_count_elems_of_size((node), (propname), sizeof(type)) @@ -183,3 +199,233 @@ int device_property_read_string(struct device *dev, const char *propname, DEV_PROP_STRING, val, 1); } EXPORT_SYMBOL_GPL(device_property_read_string); + +#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \ +({ \ + int _ret_; \ + if (is_of_node(_fwnode_)) \ + _ret_ = OF_DEV_PROP_READ_ARRAY(of_node(_fwnode_), _propname_, \ + _type_, _val_, _nval_); \ + else if (is_acpi_node(_fwnode_)) \ + _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \ + _proptype_, _val_, _nval_); \ + else \ + _ret_ = -ENXIO; \ + _ret_; \ +}) + +/** + * fwnode_property_read_u8_array - return a u8 array property of firmware node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Read an array of u8 properties with @propname from @fwnode and stores them to + * @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, + const char *propname, u8 *val, size_t nval) +{ + return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8, + val, nval); +} +EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); + +/** + * fwnode_property_read_u16_array - return a u16 array property of firmware node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Read an array of u16 properties with @propname from @fwnode and store them to + * @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, + const char *propname, u16 *val, size_t nval) +{ + return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16, + val, nval); +} +EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); + +/** + * fwnode_property_read_u32_array - return a u32 array property of firmware node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Read an array of u32 properties with @propname from @fwnode store them to + * @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, + const char *propname, u32 *val, size_t nval) +{ + return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32, + val, nval); +} +EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); + +/** + * fwnode_property_read_u64_array - return a u64 array property firmware node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Read an array of u64 properties with @propname from @fwnode and store them to + * @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of numbers, + * %-EOVERFLOW if the size of the property is not as expected, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, + const char *propname, u64 *val, size_t nval) +{ + return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64, + val, nval); +} +EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); + +/** + * fwnode_property_read_string_array - return string array property of a node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The values are stored here + * @nval: Size of the @val array + * + * Read an string list property @propname from the given firmware node and store + * them to @val if found. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of strings, + * %-EOVERFLOW if the size of the property is not as expected, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_string_array(struct fwnode_handle *fwnode, + const char *propname, const char **val, + size_t nval) +{ + if (is_of_node(fwnode)) + return of_property_read_string_array(of_node(fwnode), propname, + val, nval); + else if (is_acpi_node(fwnode)) + return acpi_dev_prop_read(acpi_node(fwnode), propname, + DEV_PROP_STRING, val, nval); + + return -ENXIO; +} +EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); + +/** + * fwnode_property_read_string - return a string property of a firmware node + * @fwnode: Firmware node to get the property of + * @propname: Name of the property + * @val: The value is stored here + * + * Read property @propname from the given firmware node and store the value into + * @val if found. The value is checked to be a string. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO or %-EILSEQ if the property is not a string, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_read_string(struct fwnode_handle *fwnode, + const char *propname, const char **val) +{ + if (is_of_node(fwnode)) + return of_property_read_string(of_node(fwnode),propname, val); + else if (is_acpi_node(fwnode)) + return acpi_dev_prop_read(acpi_node(fwnode), propname, + DEV_PROP_STRING, val, 1); + + return -ENXIO; +} +EXPORT_SYMBOL_GPL(fwnode_property_read_string); + +/** + * device_get_next_child_node - Return the next child node handle for a device + * @dev: Device to find the next child node for. + * @child: Handle to one of the device's child nodes or a null handle. + */ +struct fwnode_handle *device_get_next_child_node(struct device *dev, + struct fwnode_handle *child) +{ + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + struct device_node *node; + + node = of_get_next_available_child(dev->of_node, of_node(child)); + if (node) + return &node->fwnode; + } else if (IS_ENABLED(CONFIG_ACPI)) { + struct acpi_device *node; + + node = acpi_get_next_child(dev, acpi_node(child)); + if (node) + return acpi_fwnode_handle(node); + } + return NULL; +} +EXPORT_SYMBOL_GPL(device_get_next_child_node); + +/** + * fwnode_handle_put - Drop reference to a device node + * @fwnode: Pointer to the device node to drop the reference to. + * + * This has to be used when terminating device_for_each_child_node() iteration + * with break or return to prevent stale device node references from being left + * behind. + */ +void fwnode_handle_put(struct fwnode_handle *fwnode) +{ + if (is_of_node(fwnode)) + of_node_put(of_node(fwnode)); +} +EXPORT_SYMBOL_GPL(fwnode_handle_put); + +/** + * device_get_child_node_count - return the number of child nodes for device + * @dev: Device to cound the child nodes for + */ +unsigned int device_get_child_node_count(struct device *dev) +{ + struct fwnode_handle *child; + unsigned int count = 0; + + device_for_each_child_node(dev, child) + count++; + + return count; +} +EXPORT_SYMBOL_GPL(device_get_child_node_count); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f59cbf860658..a361f43b1974 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -27,6 +27,7 @@ #define __ACPI_BUS_H__ #include +#include /* TBD: Make dynamic */ #define ACPI_MAX_HANDLES 10 @@ -348,6 +349,7 @@ struct acpi_device_data { struct acpi_device { int device_type; acpi_handle handle; /* no handle for fixed hardware */ + struct fwnode_handle fwnode; struct acpi_device *parent; struct list_head children; struct list_head node; @@ -372,6 +374,21 @@ struct acpi_device { void (*remove)(struct acpi_device *); }; +static inline bool is_acpi_node(struct fwnode_handle *fwnode) +{ + return fwnode && fwnode->type == FWNODE_ACPI; +} + +static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode) +{ + return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL; +} + +static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) +{ + return &adev->fwnode; +} + static inline void *acpi_driver_data(struct acpi_device *d) { return d->driver_data; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 38296d686c55..5b8802216a93 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -440,6 +440,23 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *); #define ACPI_COMPANION_SET(dev, adev) do { } while (0) #define ACPI_HANDLE(dev) (NULL) +struct fwnode_handle; + +static inline bool is_acpi_node(struct fwnode_handle *fwnode) +{ + return false; +} + +static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode) +{ + return NULL; +} + +static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) +{ + return NULL; +} + static inline const char *acpi_dev_name(struct acpi_device *adev) { return NULL; @@ -681,6 +698,9 @@ int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val); int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, enum dev_prop_type proptype, void *val, size_t nval); + +struct acpi_device *acpi_get_next_child(struct device *dev, + struct acpi_device *child); #else static inline int acpi_dev_get_property(struct acpi_device *adev, const char *name, acpi_object_type type, @@ -725,6 +745,12 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev, return -ENXIO; } +static inline struct acpi_device *acpi_get_next_child(struct device *dev, + struct acpi_device *child) +{ + return NULL; +} + #endif #endif /*_LINUX_ACPI_H*/ diff --git a/include/linux/of.h b/include/linux/of.h index ce9f6a2b3532..cf79be1441d2 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -50,6 +50,7 @@ struct device_node { const char *type; phandle phandle; const char *full_name; + struct fwnode_handle fwnode; struct property *properties; struct property *deadprops; /* removed properties */ @@ -80,6 +81,7 @@ extern struct kobj_type of_node_ktype; static inline void of_node_init(struct device_node *node) { kobject_init(&node->kobj, &of_node_ktype); + node->fwnode.type = FWNODE_OF; } /* true when node is initialized */ @@ -115,6 +117,16 @@ extern struct device_node *of_aliases; extern struct device_node *of_stdout; extern raw_spinlock_t devtree_lock; +static inline bool is_of_node(struct fwnode_handle *fwnode) +{ + return fwnode && fwnode->type == FWNODE_OF; +} + +static inline struct device_node *of_node(struct fwnode_handle *fwnode) +{ + return fwnode ? container_of(fwnode, struct device_node, fwnode) : NULL; +} + static inline bool of_have_populated_dt(void) { return of_allnodes != NULL; @@ -360,6 +372,16 @@ bool of_console_check(struct device_node *dn, char *name, int index); #else /* CONFIG_OF */ +static inline bool is_of_node(struct fwnode_handle *fwnode) +{ + return false; +} + +static inline struct device_node *of_node(struct fwnode_handle *fwnode) +{ + return NULL; +} + static inline const char* of_node_full_name(const struct device_node *np) { return ""; diff --git a/include/linux/property.h b/include/linux/property.h index 9242fb0221ba..a6a3d98bd7e9 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -40,6 +40,46 @@ int device_property_read_string_array(struct device *dev, const char *propname, int device_property_read_string(struct device *dev, const char *propname, const char **val); +enum fwnode_type { + FWNODE_INVALID = 0, + FWNODE_OF, + FWNODE_ACPI, +}; + +struct fwnode_handle { + enum fwnode_type type; +}; + +bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); +int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, + const char *propname, u8 *val, + size_t nval); +int fwnode_property_read_u16_array(struct fwnode_handle *fwnode, + const char *propname, u16 *val, + size_t nval); +int fwnode_property_read_u32_array(struct fwnode_handle *fwnode, + const char *propname, u32 *val, + size_t nval); +int fwnode_property_read_u64_array(struct fwnode_handle *fwnode, + const char *propname, u64 *val, + size_t nval); +int fwnode_property_read_string_array(struct fwnode_handle *fwnode, + const char *propname, const char **val, + size_t nval); +int fwnode_property_read_string(struct fwnode_handle *fwnode, + const char *propname, const char **val); + +struct fwnode_handle *device_get_next_child_node(struct device *dev, + struct fwnode_handle *child); + +#define device_for_each_child_node(dev, child) \ + for (child = device_get_next_child_node(dev, NULL); child; \ + child = device_get_next_child_node(dev, child)) + +void fwnode_handle_put(struct fwnode_handle *fwnode); + +unsigned int device_get_child_node_count(struct device *dev); + static inline bool device_property_read_bool(struct device *dev, const char *propname) { @@ -70,4 +110,34 @@ static inline int device_property_read_u64(struct device *dev, return device_property_read_u64_array(dev, propname, val, 1); } +static inline bool fwnode_property_read_bool(struct fwnode_handle *fwnode, + const char *propname) +{ + return fwnode_property_present(fwnode, propname); +} + +static inline int fwnode_property_read_u8(struct fwnode_handle *fwnode, + const char *propname, u8 *val) +{ + return fwnode_property_read_u8_array(fwnode, propname, val, 1); +} + +static inline int fwnode_property_read_u16(struct fwnode_handle *fwnode, + const char *propname, u16 *val) +{ + return fwnode_property_read_u16_array(fwnode, propname, val, 1); +} + +static inline int fwnode_property_read_u32(struct fwnode_handle *fwnode, + const char *propname, u32 *val) +{ + return fwnode_property_read_u32_array(fwnode, propname, val, 1); +} + +static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode, + const char *propname, u64 *val) +{ + return fwnode_property_read_u64_array(fwnode, propname, val, 1); +} + #endif /* _LINUX_PROPERTY_H_ */ -- GitLab From 40b7318319281b1bdec804f6435f26cadd329c13 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 21 Oct 2014 13:33:59 +0200 Subject: [PATCH 3002/9457] gpio: Support for unified device properties interface Some drivers need to deal with only firmware representation of its GPIOs. An example would be a GPIO button array driver where each button is described as a separate firmware node in device tree. Typically these child nodes do not have physical representation in the Linux device model. In order to help device drivers to handle such firmware child nodes we add dev[m]_get_named_gpiod_from_child() that takes a child firmware node pointer as its second argument (the first one is the parent device itself), finds the GPIO using whatever is the underlying firmware method, and requests the GPIO properly. Signed-off-by: Mika Westerberg Acked-by: Alexandre Courbot Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/gpio/devres.c | 32 ++++++++++++++++++++ drivers/gpio/gpiolib.c | 55 +++++++++++++++++++++++++++++++++++ include/linux/gpio/consumer.h | 7 +++++ 3 files changed, 94 insertions(+) diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 954b9f6b0ef8..13dbd3dfc33a 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -108,6 +108,38 @@ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev, } EXPORT_SYMBOL(__devm_gpiod_get_index); +/** + * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node + * @dev: GPIO consumer + * @child: firmware node (child of @dev) + * + * GPIO descriptors returned from this function are automatically disposed on + * driver detach. + */ +struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + struct fwnode_handle *child) +{ + struct gpio_desc **dr; + struct gpio_desc *desc; + + dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), + GFP_KERNEL); + if (!dr) + return ERR_PTR(-ENOMEM); + + desc = fwnode_get_named_gpiod(child, "gpios"); + if (IS_ERR(desc)) { + devres_free(dr); + return desc; + } + + *dr = desc; + devres_add(dev, dr); + + return desc; +} +EXPORT_SYMBOL(devm_get_gpiod_from_child); + /** * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() * @dev: GPIO consumer diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 2bca0495cb46..58659dbe702a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1734,6 +1734,61 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev, } EXPORT_SYMBOL_GPL(__gpiod_get_index); +/** + * fwnode_get_named_gpiod - obtain a GPIO from firmware node + * @fwnode: handle of the firmware node + * @propname: name of the firmware property representing the GPIO + * + * This function can be used for drivers that get their configuration + * from firmware. + * + * Function properly finds the corresponding GPIO using whatever is the + * underlying firmware interface and then makes sure that the GPIO + * descriptor is requested before it is returned to the caller. + * + * In case of error an ERR_PTR() is returned. + */ +struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, + const char *propname) +{ + struct gpio_desc *desc = ERR_PTR(-ENODEV); + bool active_low = false; + int ret; + + if (!fwnode) + return ERR_PTR(-EINVAL); + + if (is_of_node(fwnode)) { + enum of_gpio_flags flags; + + desc = of_get_named_gpiod_flags(of_node(fwnode), propname, 0, + &flags); + if (!IS_ERR(desc)) + active_low = flags & OF_GPIO_ACTIVE_LOW; + } else if (is_acpi_node(fwnode)) { + struct acpi_gpio_info info; + + desc = acpi_get_gpiod_by_index(acpi_node(fwnode), propname, 0, + &info); + if (!IS_ERR(desc)) + active_low = info.active_low; + } + + if (IS_ERR(desc)) + return desc; + + ret = gpiod_request(desc, NULL); + if (ret) + return ERR_PTR(ret); + + /* Only value flag can be set from both DT and ACPI is active_low */ + if (active_low) + set_bit(FLAG_ACTIVE_LOW, &desc->flags); + + return desc; +} +EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod); + /** * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO * function diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 12f146fa6604..00b1b70d68ba 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -94,6 +94,13 @@ int gpiod_to_irq(const struct gpio_desc *desc); struct gpio_desc *gpio_to_desc(unsigned gpio); int desc_to_gpio(const struct gpio_desc *desc); +/* Child properties interface */ +struct fwnode_handle; + +struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, + const char *propname); +struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + struct fwnode_handle *child); #else /* CONFIG_GPIOLIB */ static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev, -- GitLab From a43f2cbbb009f96231bbbe24ad4f824215dedb81 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 27 Oct 2014 23:30:10 +0100 Subject: [PATCH 3003/9457] leds: leds-gpio: Make use of device property API Make use of device property API in this driver so that both OF and ACPI based system can use the same driver. This change contains material from Max Eliaser and Mika Westerberg. Signed-off-by: Mika Westerberg Acked-by: Bryan Wu Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/leds/leds-gpio.c | 63 +++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 1ff95ce9487a..edd370dbb22f 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -16,10 +16,8 @@ #include #include #include -#include -#include -#include #include +#include #include #include @@ -171,40 +169,37 @@ static inline int sizeof_gpio_leds_priv(int num_leds) (sizeof(struct gpio_led_data) * num_leds); } -/* Code to create from OpenFirmware platform devices */ -#ifdef CONFIG_OF_GPIO -static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) +static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node, *child; + struct device *dev = &pdev->dev; + struct fwnode_handle *child; struct gpio_leds_priv *priv; int count, ret; - /* count LEDs in this device, so we know how much to allocate */ - count = of_get_available_child_count(np); + count = device_get_child_node_count(dev); if (!count) return ERR_PTR(-ENODEV); - for_each_available_child_of_node(np, child) - if (of_get_gpio(child, 0) == -EPROBE_DEFER) - return ERR_PTR(-EPROBE_DEFER); - - priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), - GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL); if (!priv) return ERR_PTR(-ENOMEM); - for_each_available_child_of_node(np, child) { + device_for_each_child_node(dev, child) { struct gpio_led led = {}; - enum of_gpio_flags flags; - const char *state; - - led.gpio = of_get_gpio_flags(child, 0, &flags); - led.active_low = flags & OF_GPIO_ACTIVE_LOW; - led.name = of_get_property(child, "label", NULL) ? : child->name; - led.default_trigger = - of_get_property(child, "linux,default-trigger", NULL); - state = of_get_property(child, "default-state", NULL); - if (state) { + const char *state = NULL; + + led.gpiod = devm_get_gpiod_from_child(dev, child); + if (IS_ERR(led.gpiod)) { + fwnode_handle_put(child); + goto err; + } + + fwnode_property_read_string(child, "label", &led.name); + fwnode_property_read_string(child, "linux,default-trigger", + &led.default_trigger); + + if (!fwnode_property_read_string(child, "linux,default_state", + &state)) { if (!strcmp(state, "keep")) led.default_state = LEDS_GPIO_DEFSTATE_KEEP; else if (!strcmp(state, "on")) @@ -213,13 +208,13 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) led.default_state = LEDS_GPIO_DEFSTATE_OFF; } - if (of_get_property(child, "retain-state-suspended", NULL)) + if (fwnode_property_present(child, "retain-state-suspended")) led.retain_state_suspended = 1; ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], - &pdev->dev, NULL); + dev, NULL); if (ret < 0) { - of_node_put(child); + fwnode_handle_put(child); goto err; } } @@ -238,12 +233,6 @@ static const struct of_device_id of_gpio_leds_match[] = { }; MODULE_DEVICE_TABLE(of, of_gpio_leds_match); -#else /* CONFIG_OF_GPIO */ -static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) -{ - return ERR_PTR(-ENODEV); -} -#endif /* CONFIG_OF_GPIO */ static int gpio_led_probe(struct platform_device *pdev) { @@ -271,7 +260,7 @@ static int gpio_led_probe(struct platform_device *pdev) } } } else { - priv = gpio_leds_create_of(pdev); + priv = gpio_leds_create(pdev); if (IS_ERR(priv)) return PTR_ERR(priv); } @@ -298,7 +287,7 @@ static struct platform_driver gpio_led_driver = { .driver = { .name = "leds-gpio", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(of_gpio_leds_match), + .of_match_table = of_gpio_leds_match, }, }; -- GitLab From b26d4e2283b6d9b65bfe14b99c9c3a560e390a00 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 21 Oct 2014 13:34:00 +0200 Subject: [PATCH 3004/9457] input: gpio_keys_polled: Make use of device property API Make use of device property API in this driver so that both OF based system and ACPI based system can use this driver. Signed-off-by: Aaron Lu Signed-off-by: Mika Westerberg Acked-by: Dmitry Torokhov Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/input/keyboard/gpio_keys_polled.c | 73 ++++++++--------------- 1 file changed, 24 insertions(+), 49 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index b7a514ced509..c9c1c8ca7267 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -25,9 +25,7 @@ #include #include #include -#include -#include -#include +#include #define DRV_NAME "gpio-keys-polled" @@ -102,21 +100,15 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) pdata->disable(bdev->dev); } -#ifdef CONFIG_OF static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) { - struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; + struct fwnode_handle *child; int error; int nbuttons; - int i; - - node = dev->of_node; - if (!node) - return NULL; - nbuttons = of_get_child_count(node); + nbuttons = device_get_child_node_count(dev); if (nbuttons == 0) return NULL; @@ -126,52 +118,44 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct return ERR_PTR(-ENOMEM); pdata->buttons = (struct gpio_keys_button *)(pdata + 1); - pdata->nbuttons = nbuttons; - pdata->rep = !!of_get_property(node, "autorepeat", NULL); - of_property_read_u32(node, "poll-interval", &pdata->poll_interval); + pdata->rep = device_property_present(dev, "autorepeat"); + device_property_read_u32(dev, "poll-interval", &pdata->poll_interval); - i = 0; - for_each_child_of_node(node, pp) { - int gpio; - enum of_gpio_flags flags; - - if (!of_find_property(pp, "gpios", NULL)) { - pdata->nbuttons--; - dev_warn(dev, "Found button without gpios\n"); - continue; - } + device_for_each_child_node(dev, child) { + struct gpio_desc *desc; - gpio = of_get_gpio_flags(pp, 0, &flags); - if (gpio < 0) { - error = gpio; + desc = devm_get_gpiod_from_child(dev, child); + if (IS_ERR(desc)) { + error = PTR_ERR(desc); if (error != -EPROBE_DEFER) dev_err(dev, "Failed to get gpio flags, error: %d\n", error); + fwnode_handle_put(child); return ERR_PTR(error); } - button = &pdata->buttons[i++]; + button = &pdata->buttons[pdata->nbuttons++]; + button->gpiod = desc; - button->gpio = gpio; - button->active_low = flags & OF_GPIO_ACTIVE_LOW; - - if (of_property_read_u32(pp, "linux,code", &button->code)) { - dev_err(dev, "Button without keycode: 0x%x\n", - button->gpio); + if (fwnode_property_read_u32(child, "linux,code", &button->code)) { + dev_err(dev, "Button without keycode: %d\n", + pdata->nbuttons - 1); + fwnode_handle_put(child); return ERR_PTR(-EINVAL); } - button->desc = of_get_property(pp, "label", NULL); + fwnode_property_read_string(child, "label", &button->desc); - if (of_property_read_u32(pp, "linux,input-type", &button->type)) + if (fwnode_property_read_u32(child, "linux,input-type", + &button->type)) button->type = EV_KEY; - button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); + button->wakeup = fwnode_property_present(child, "gpio-key,wakeup"); - if (of_property_read_u32(pp, "debounce-interval", - &button->debounce_interval)) + if (fwnode_property_read_u32(child, "debounce-interval", + &button->debounce_interval)) button->debounce_interval = 5; } @@ -187,15 +171,6 @@ static const struct of_device_id gpio_keys_polled_of_match[] = { }; MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); -#else - -static inline struct gpio_keys_platform_data * -gpio_keys_polled_get_devtree_pdata(struct device *dev) -{ - return NULL; -} -#endif - static int gpio_keys_polled_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -323,7 +298,7 @@ static struct platform_driver gpio_keys_polled_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, - .of_match_table = of_match_ptr(gpio_keys_polled_of_match), + .of_match_table = gpio_keys_polled_of_match, }, }; module_platform_driver(gpio_keys_polled_driver); -- GitLab From f028d5242d7ecb0a1bfc80e7bd292201c8612641 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 3 Nov 2014 23:39:41 +0100 Subject: [PATCH 3005/9457] ACPI / GPIO: Driver GPIO mappings for ACPI GPIOs Provide a way for device drivers using GPIOs described by ACPI GpioIo resources in _CRS to tell the GPIO subsystem what names (connection IDs) to associate with specific GPIO pins defined in there. To do that, a driver needs to define a mapping table as a NULL-terminated array of struct acpi_gpio_mapping objects that each contain a name, a pointer to an array of line data (struct acpi_gpio_params) objects and the size of that array. Each struct acpi_gpio_params object consists of three fields, crs_entry_index, line_index, active_low, representing the index of the target GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target line in that resource starting from zero, and the active-low flag for that line, respectively. Next, the mapping table needs to be passed as the second argument to acpi_dev_add_driver_gpios() that will register it with the ACPI device object pointed to by its first argument. That should be done in the driver's .probe() routine. On removal, the driver should unregister its GPIO mapping table by calling acpi_dev_remove_driver_gpios() on the ACPI device object where that table was previously registered. Included are fixes from Mika Westerberg. Acked-by: Alexandre Courbot Reviewed-by: Linus Walleij Signed-off-by: Rafael J. Wysocki --- drivers/gpio/gpiolib-acpi.c | 43 +++++++++++++++++++++++++++++++++++-- include/acpi/acpi_bus.h | 3 +++ include/linux/acpi.h | 30 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 8aa6ca473748..5a4d061e787e 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -287,6 +287,41 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) } } +int acpi_dev_add_driver_gpios(struct acpi_device *adev, + const struct acpi_gpio_mapping *gpios) +{ + if (adev && gpios) { + adev->driver_gpios = gpios; + return 0; + } + return -EINVAL; +} +EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios); + +static bool acpi_get_driver_gpio_data(struct acpi_device *adev, + const char *name, int index, + struct acpi_reference_args *args) +{ + const struct acpi_gpio_mapping *gm; + + if (!adev->driver_gpios) + return false; + + for (gm = adev->driver_gpios; gm->name; gm++) + if (!strcmp(name, gm->name) && gm->data && index < gm->size) { + const struct acpi_gpio_params *par = gm->data + index; + + args->adev = adev; + args->args[0] = par->crs_entry_index; + args->args[1] = par->line_index; + args->args[2] = par->active_low; + args->nargs = 3; + return true; + } + + return false; +} + struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; @@ -372,8 +407,12 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, memset(&args, 0, sizeof(args)); ret = acpi_dev_get_property_reference(adev, propname, NULL, index, &args); - if (ret) - return ERR_PTR(ret); + if (ret) { + bool found = acpi_get_driver_gpio_data(adev, propname, + index, &args); + if (!found) + return ERR_PTR(ret); + } /* * The property was found and resolved so need to diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a361f43b1974..7d1ce40e201e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -345,6 +345,8 @@ struct acpi_device_data { const union acpi_object *of_compatible; }; +struct acpi_gpio_mapping; + /* Device */ struct acpi_device { int device_type; @@ -366,6 +368,7 @@ struct acpi_device { struct acpi_scan_handler *handler; struct acpi_hotplug_context *hp; struct acpi_driver *driver; + const struct acpi_gpio_mapping *driver_gpios; void *driver_data; struct device dev; unsigned int physical_node_count; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 5b8802216a93..0902426c4521 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -673,6 +673,36 @@ do { \ #endif #endif +struct acpi_gpio_params { + unsigned int crs_entry_index; + unsigned int line_index; + bool active_low; +}; + +struct acpi_gpio_mapping { + const char *name; + const struct acpi_gpio_params *data; + unsigned int size; +}; + +#if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) +int acpi_dev_add_driver_gpios(struct acpi_device *adev, + const struct acpi_gpio_mapping *gpios); + +static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) +{ + if (adev) + adev->driver_gpios = NULL; +} +#else +static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev, + const struct acpi_gpio_mapping *gpios) +{ + return -ENXIO; +} +static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {} +#endif + /* Device properties */ #define MAX_ACPI_REFERENCE_ARGS 8 -- GitLab From 72daceb9a10af4614d4aee304f07904191962f07 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 27 Oct 2014 12:15:14 +0200 Subject: [PATCH 3006/9457] net: rfkill: gpio: Add default GPIO driver mappings for ACPI The driver uses devm_gpiod_get_index(..., index) so that the index refers directly to the GpioIo resource under the ACPI device. The problem with this is that if the ordering changes we get wrong GPIOs. With ACPI 5.1 _DSD we can now use names instead to reference GPIOs analogous to Device Tree. However, we still have systems out there that do not provide _DSD at all. These systems must be supported as well. Luckily we now have acpi_dev_add_driver_gpios() that can be used to provide mappings for systems where _DSD is not provided and still take advantage of _DSD if it exists. This patch changes the driver to create default GPIO mappings if we are running on ACPI system. While there we can drop the indices completely and use devm_gpiod_get() with name instead. Signed-off-by: Mika Westerberg Reviewed-by: Johannes Berg Acked-by: John W. Linville Acked-by: Linus Walleij Signed-off-by: Rafael J. Wysocki --- net/rfkill/rfkill-gpio.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 0f62326c0f5e..2a4717967502 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c @@ -63,6 +63,15 @@ static const struct rfkill_ops rfkill_gpio_ops = { .set_block = rfkill_gpio_set_power, }; +static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; +static const struct acpi_gpio_params shutdown_gpios = { 1, 0, false }; + +static const struct acpi_gpio_mapping acpi_rfkill_default_gpios[] = { + { "reset-gpios", &reset_gpios, 1 }, + { "shutdown-gpios", &shutdown_gpios, 1 }, + { }, +}; + static int rfkill_gpio_acpi_probe(struct device *dev, struct rfkill_gpio_data *rfkill) { @@ -75,7 +84,8 @@ static int rfkill_gpio_acpi_probe(struct device *dev, rfkill->name = dev_name(dev); rfkill->type = (unsigned)id->driver_data; - return 0; + return acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), + acpi_rfkill_default_gpios); } static int rfkill_gpio_probe(struct platform_device *pdev) @@ -102,7 +112,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev) rfkill->clk = devm_clk_get(&pdev->dev, NULL); - gpio = devm_gpiod_get_index(&pdev->dev, "reset", 0); + gpio = devm_gpiod_get(&pdev->dev, "reset"); if (!IS_ERR(gpio)) { ret = gpiod_direction_output(gpio, 0); if (ret) @@ -110,7 +120,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev) rfkill->reset_gpio = gpio; } - gpio = devm_gpiod_get_index(&pdev->dev, "shutdown", 1); + gpio = devm_gpiod_get(&pdev->dev, "shutdown"); if (!IS_ERR(gpio)) { ret = gpiod_direction_output(gpio, 0); if (ret) @@ -150,6 +160,8 @@ static int rfkill_gpio_remove(struct platform_device *pdev) rfkill_unregister(rfkill->rfkill_dev); rfkill_destroy(rfkill->rfkill_dev); + acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev)); + return 0; } -- GitLab From e36d453e98c57dda0f8ba68585676ac4ba36631e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 3 Nov 2014 23:39:57 +0100 Subject: [PATCH 3007/9457] ACPI / GPIO: Document ACPI GPIO mappings API Document the previously introduced method that can be used by device drivers to provide the GPIO subsystem with mappings between GPIO names (connection IDs) and GpioIo()/GpioInt() resources in _CRS. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg --- Documentation/acpi/gpio-properties.txt | 44 ++++++++++++++++++++++++++ Documentation/gpio/consumer.txt | 18 +++++++++++ 2 files changed, 62 insertions(+) diff --git a/Documentation/acpi/gpio-properties.txt b/Documentation/acpi/gpio-properties.txt index 3e45b8b7e4f2..ae36fcf86dc7 100644 --- a/Documentation/acpi/gpio-properties.txt +++ b/Documentation/acpi/gpio-properties.txt @@ -50,3 +50,47 @@ it to 1 marks the GPIO as active low. In our Bluetooth example the "reset-gpio" refers to the second GpioIo() resource, second pin in that resource with the GPIO number of 31. + +ACPI GPIO Mappings Provided by Drivers +-------------------------------------- + +There are systems in which the ACPI tables do not contain _DSD but provide _CRS +with GpioIo()/GpioInt() resources and device drivers still need to work with +them. + +In those cases ACPI device identification objects, _HID, _CID, _CLS, _SUB, _HRV, +available to the driver can be used to identify the device and that is supposed +to be sufficient to determine the meaning and purpose of all of the GPIO lines +listed by the GpioIo()/GpioInt() resources returned by _CRS. In other words, +the driver is supposed to know what to use the GpioIo()/GpioInt() resources for +once it has identified the device. Having done that, it can simply assign names +to the GPIO lines it is going to use and provide the GPIO subsystem with a +mapping between those names and the ACPI GPIO resources corresponding to them. + +To do that, the driver needs to define a mapping table as a NULL-terminated +array of struct acpi_gpio_mapping objects that each contain a name, a pointer +to an array of line data (struct acpi_gpio_params) objects and the size of that +array. Each struct acpi_gpio_params object consists of three fields, +crs_entry_index, line_index, active_low, representing the index of the target +GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target +line in that resource starting from zero, and the active-low flag for that line, +respectively, in analogy with the _DSD GPIO property format specified above. + +For the example Bluetooth device discussed previously the data structures in +question would look like this: + +static const struct acpi_gpio_params reset_gpio = { 1, 1, false }; +static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false }; + +static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = { + { "reset-gpio", &reset_gpio, 1 }, + { "shutdown-gpio", &shutdown_gpio, 1 }, + { }, +}; + +Next, the mapping table needs to be passed as the second argument to +acpi_dev_add_driver_gpios() that will register it with the ACPI device object +pointed to by its first argument. That should be done in the driver's .probe() +routine. On removal, the driver should unregister its GPIO mapping table by +calling acpi_dev_remove_driver_gpios() on the ACPI device object where that +table was previously registered. diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index 6ce544191ca6..859918db36b8 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -219,6 +219,24 @@ part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup capabilities. +GPIOs and ACPI +============== + +On ACPI systems, GPIOs are described by GpioIo()/GpioInt() resources listed by +the _CRS configuration objects of devices. Those resources do not provide +connection IDs (names) for GPIOs, so it is necessary to use an additional +mechanism for this purpose. + +Systems compliant with ACPI 5.1 or newer may provide a _DSD configuration object +which, among other things, may be used to provide connection IDs for specific +GPIOs described by the GpioIo()/GpioInt() resources in _CRS. If that is the +case, it will be handled by the GPIO subsystem automatically. However, if the +_DSD is not present, the mappings between GpioIo()/GpioInt() resources and GPIO +connection IDs need to be provided by device drivers. + +For details refer to Documentation/acpi/gpio-properties.txt + + Interacting With the Legacy GPIO Subsystem ========================================== Many kernel subsystems still handle GPIOs using the legacy integer-based -- GitLab From c673a2b4008103525a3cf21bedf15ffac37bfef0 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 31 Oct 2014 13:40:58 +0200 Subject: [PATCH 3008/9457] leds: leds-gpio: Convert gpio_blink_set() to use GPIO descriptors Commit 21f2aae91e902aad ("leds: leds-gpio: Add support for GPIO descriptors") already converted most of the driver to use GPIO descriptors. What is still missing is the platform specific hook gpio_blink_set() and board files which pass legacy GPIO numbers to this driver in platform data. In this patch we handle the former and convert gpio_blink_set() to take GPIO descriptor instead. In order to do this we convert the existing four users to accept GPIO descriptor and translate it to legacy GPIO number in the platform code. This effectively "pushes" legacy GPIO number usage from the driver to platforms. Also add comment to the remaining block describing that it is legacy code path and we are getting rid of it eventually. Suggested-by: Linus Walleij Signed-off-by: Mika Westerberg Acked-by: Andrew Lunn Reviewed-by: Linus Walleij Acked-by: Alexandre Courbot Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-s3c24xx/h1940-bluetooth.c | 4 +-- arch/arm/mach-s3c24xx/h1940.h | 4 ++- arch/arm/mach-s3c24xx/mach-h1940.c | 3 +- arch/arm/mach-s3c24xx/mach-rx1950.c | 3 +- arch/arm/plat-orion/gpio.c | 3 +- arch/arm/plat-orion/include/plat/orion-gpio.h | 5 ++- drivers/leds/leds-gpio.c | 31 ++++++++----------- include/linux/leds.h | 2 +- 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c index b4d14b864367..9c8b1279a4ba 100644 --- a/arch/arm/mach-s3c24xx/h1940-bluetooth.c +++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c @@ -41,7 +41,7 @@ static void h1940bt_enable(int on) mdelay(10); gpio_set_value(S3C2410_GPH(1), 0); - h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL); + h1940_led_blink_set(NULL, GPIO_LED_BLINK, NULL, NULL); } else { gpio_set_value(S3C2410_GPH(1), 1); @@ -50,7 +50,7 @@ static void h1940bt_enable(int on) mdelay(10); gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0); - h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL); + h1940_led_blink_set(NULL, GPIO_LED_NO_BLINK_LOW, NULL, NULL); } } diff --git a/arch/arm/mach-s3c24xx/h1940.h b/arch/arm/mach-s3c24xx/h1940.h index 2950cc466840..596d9f64c5b6 100644 --- a/arch/arm/mach-s3c24xx/h1940.h +++ b/arch/arm/mach-s3c24xx/h1940.h @@ -19,8 +19,10 @@ #define H1940_SUSPEND_RESUMEAT (0x30081000) #define H1940_SUSPEND_CHECK (0x30080000) +struct gpio_desc; + extern void h1940_pm_return(void); -extern int h1940_led_blink_set(unsigned gpio, int state, +extern int h1940_led_blink_set(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off); diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index d35ddc1d9991..d40d4f5244c6 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -359,10 +359,11 @@ static struct platform_device h1940_battery = { static DEFINE_SPINLOCK(h1940_blink_spin); -int h1940_led_blink_set(unsigned gpio, int state, +int h1940_led_blink_set(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off) { int blink_gpio, check_gpio1, check_gpio2; + int gpio = desc ? desc_to_gpio(desc) : -EINVAL; switch (gpio) { case H1940_LATCH_LED_GREEN: diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index c3f2682d0c62..1d35ff375a01 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -250,9 +250,10 @@ static void rx1950_disable_charger(void) static DEFINE_SPINLOCK(rx1950_blink_spin); -static int rx1950_led_blink_set(unsigned gpio, int state, +static int rx1950_led_blink_set(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off) { + int gpio = desc_to_gpio(desc); int blink_gpio, check_gpio; switch (gpio) { diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index b61a3bcc2fa8..b357053f40d9 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c @@ -306,9 +306,10 @@ EXPORT_SYMBOL(orion_gpio_set_blink); #define ORION_BLINK_HALF_PERIOD 100 /* ms */ -int orion_gpio_led_blink_set(unsigned gpio, int state, +int orion_gpio_led_blink_set(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off) { + unsigned gpio = desc_to_gpio(desc); if (delay_on && delay_off && !*delay_on && !*delay_off) *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD; diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h index e763988b04b9..e856b073a9c8 100644 --- a/arch/arm/plat-orion/include/plat/orion-gpio.h +++ b/arch/arm/plat-orion/include/plat/orion-gpio.h @@ -14,12 +14,15 @@ #include #include #include + +struct gpio_desc; + /* * Orion-specific GPIO API extensions. */ void orion_gpio_set_unused(unsigned pin); void orion_gpio_set_blink(unsigned pin, int blink); -int orion_gpio_led_blink_set(unsigned gpio, int state, +int orion_gpio_led_blink_set(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off); #define GPIO_INPUT_OK (1 << 0) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index edd370dbb22f..ba4698c32bb0 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -28,7 +28,7 @@ struct gpio_led_data { u8 new_level; u8 can_sleep; u8 blinking; - int (*platform_gpio_blink_set)(unsigned gpio, int state, + int (*platform_gpio_blink_set)(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off); }; @@ -38,13 +38,8 @@ static void gpio_led_work(struct work_struct *work) container_of(work, struct gpio_led_data, work); if (led_dat->blinking) { - int gpio = desc_to_gpio(led_dat->gpiod); - int level = led_dat->new_level; - - if (gpiod_is_active_low(led_dat->gpiod)) - level = !level; - - led_dat->platform_gpio_blink_set(gpio, level, NULL, NULL); + led_dat->platform_gpio_blink_set(led_dat->gpiod, + led_dat->new_level, NULL, NULL); led_dat->blinking = 0; } else gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); @@ -71,13 +66,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, schedule_work(&led_dat->work); } else { if (led_dat->blinking) { - int gpio = desc_to_gpio(led_dat->gpiod); - - if (gpiod_is_active_low(led_dat->gpiod)) - level = !level; - - led_dat->platform_gpio_blink_set(gpio, level, NULL, - NULL); + led_dat->platform_gpio_blink_set(led_dat->gpiod, level, + NULL, NULL); led_dat->blinking = 0; } else gpiod_set_value(led_dat->gpiod, level); @@ -89,20 +79,25 @@ static int gpio_blink_set(struct led_classdev *led_cdev, { struct gpio_led_data *led_dat = container_of(led_cdev, struct gpio_led_data, cdev); - int gpio = desc_to_gpio(led_dat->gpiod); led_dat->blinking = 1; - return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK, + return led_dat->platform_gpio_blink_set(led_dat->gpiod, GPIO_LED_BLINK, delay_on, delay_off); } static int create_gpio_led(const struct gpio_led *template, struct gpio_led_data *led_dat, struct device *parent, - int (*blink_set)(unsigned, int, unsigned long *, unsigned long *)) + int (*blink_set)(struct gpio_desc *, int, unsigned long *, + unsigned long *)) { int ret, state; if (!template->gpiod) { + /* + * This is the legacy code path for platform code that + * still uses GPIO numbers. Ultimately we would like to get + * rid of this block completely. + */ unsigned long flags = 0; /* skip leds that aren't available */ diff --git a/include/linux/leds.h b/include/linux/leds.h index f3af5c4d9084..361101fef270 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -274,7 +274,7 @@ struct gpio_led_platform_data { #define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */ #define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */ #define GPIO_LED_BLINK 2 /* Please, blink */ - int (*gpio_blink_set)(unsigned gpio, int state, + int (*gpio_blink_set)(struct gpio_desc *desc, int state, unsigned long *delay_on, unsigned long *delay_off); }; -- GitLab From 274e2da0ecb4d28e3d4e9f029b096e0e8c401a66 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 3 Nov 2014 17:35:01 +0100 Subject: [PATCH 3009/9457] syncookies: avoid magic values and document which-bit-is-what-option Was a bit more difficult to read than needed due to magic shifts; add defines and document the used encoding scheme. Joint work with Daniel Borkmann. Acked-by: Eric Dumazet Signed-off-by: Daniel Borkmann Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv4/syncookies.c | 50 ++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 4ac7bcaf2f46..c3792c0557dd 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -19,10 +19,6 @@ #include #include -/* Timestamps: lowest bits store TCP options */ -#define TSBITS 6 -#define TSMASK (((__u32)1 << TSBITS) - 1) - extern int sysctl_tcp_syncookies; static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly; @@ -30,6 +26,30 @@ static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly; #define COOKIEBITS 24 /* Upper bits store count */ #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) +/* TCP Timestamp: 6 lowest bits of timestamp sent in the cookie SYN-ACK + * stores TCP options: + * + * MSB LSB + * | 31 ... 6 | 5 | 4 | 3 2 1 0 | + * | Timestamp | ECN | SACK | WScale | + * + * When we receive a valid cookie-ACK, we look at the echoed tsval (if + * any) to figure out which TCP options we should use for the rebuilt + * connection. + * + * A WScale setting of '0xf' (which is an invalid scaling value) + * means that original syn did not include the TCP window scaling option. + */ +#define TS_OPT_WSCALE_MASK 0xf +#define TS_OPT_SACK BIT(4) +#define TS_OPT_ECN BIT(5) +/* There is no TS_OPT_TIMESTAMP: + * if ACK contains timestamp option, we already know it was + * requested/supported by the syn/synack exchange. + */ +#define TSBITS 6 +#define TSMASK (((__u32)1 << TSBITS) - 1) + static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS], ipv4_cookie_scratch); @@ -67,9 +87,11 @@ __u32 cookie_init_timestamp(struct request_sock *req) ireq = inet_rsk(req); - options = ireq->wscale_ok ? ireq->snd_wscale : 0xf; - options |= ireq->sack_ok << 4; - options |= ireq->ecn_ok << 5; + options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK; + if (ireq->sack_ok) + options |= TS_OPT_SACK; + if (ireq->ecn_ok) + options |= TS_OPT_ECN; ts = ts_now & ~TSMASK; ts |= options; @@ -219,16 +241,13 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, * additional tcp options in the timestamp. * This extracts these options from the timestamp echo. * - * The lowest 4 bits store snd_wscale. - * next 2 bits indicate SACK and ECN support. - * * return false if we decode an option that should not be. */ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, struct net *net, bool *ecn_ok) { /* echoed timestamp, lowest bits contain options */ - u32 options = tcp_opt->rcv_tsecr & TSMASK; + u32 options = tcp_opt->rcv_tsecr; if (!tcp_opt->saw_tstamp) { tcp_clear_options(tcp_opt); @@ -238,19 +257,20 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, if (!sysctl_tcp_timestamps) return false; - tcp_opt->sack_ok = (options & (1 << 4)) ? TCP_SACK_SEEN : 0; - *ecn_ok = (options >> 5) & 1; + tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0; + *ecn_ok = options & TS_OPT_ECN; if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn) return false; if (tcp_opt->sack_ok && !sysctl_tcp_sack) return false; - if ((options & 0xf) == 0xf) + if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK) return true; /* no window scaling */ tcp_opt->wscale_ok = 1; - tcp_opt->snd_wscale = options & 0xf; + tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK; + return sysctl_tcp_window_scaling != 0; } EXPORT_SYMBOL(cookie_check_timestamp); -- GitLab From f1673381b1481a409238d4552a0700d490c5b36c Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 3 Nov 2014 17:35:02 +0100 Subject: [PATCH 3010/9457] syncookies: split cookie_check_timestamp() into two functions The function cookie_check_timestamp(), both called from IPv4/6 context, is being used to decode the echoed timestamp from the SYN/ACK into TCP options used for follow-up communication with the peer. We can remove ECN handling from that function, split it into a separate one, and simply rename the original function into cookie_decode_options(). cookie_decode_options() just fills in tcp_option struct based on the echoed timestamp received from the peer. Anything that fails in this function will actually discard the request socket. While this is the natural place for decoding options such as ECN which commit 172d69e63c7f ("syncookies: add support for ECN") added, we argue that in particular for ECN handling, it can be checked at a later point in time as the request sock would actually not need to be dropped from this, but just ECN support turned off. Therefore, we split this functionality into cookie_ecn_ok(), which tells us if the timestamp indicates ECN support AND the tcp_ecn sysctl is enabled. This prepares for per-route ECN support: just looking at the tcp_ecn sysctl won't be enough anymore at that point; if the timestamp indicates ECN and sysctl tcp_ecn == 0, we will also need to check the ECN dst metric. This would mean adding a route lookup to cookie_check_timestamp(), which we definitely want to avoid. As we already do a route lookup at a later point in cookie_{v4,v6}_check(), we can simply make use of that as well for the new cookie_ecn_ok() function w/o any additional cost. Joint work with Daniel Borkmann. Acked-by: Eric Dumazet Signed-off-by: Daniel Borkmann Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- include/net/tcp.h | 9 ++++----- net/ipv4/syncookies.c | 31 +++++++++++++++++++++---------- net/ipv6/syncookies.c | 5 ++--- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 3a35b1500359..36c5084964cd 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -490,17 +490,16 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, u16 *mssp); __u32 cookie_v4_init_sequence(struct sock *sk, const struct sk_buff *skb, __u16 *mss); -#endif - __u32 cookie_init_timestamp(struct request_sock *req); -bool cookie_check_timestamp(struct tcp_options_received *opt, struct net *net, - bool *ecn_ok); +bool cookie_timestamp_decode(struct tcp_options_received *opt); +bool cookie_ecn_ok(const struct tcp_options_received *opt, + const struct net *net); /* From net/ipv6/syncookies.c */ int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th, u32 cookie); struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); -#ifdef CONFIG_SYN_COOKIES + u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, const struct tcphdr *th, u16 *mssp); __u32 cookie_v6_init_sequence(struct sock *sk, const struct sk_buff *skb, diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index c3792c0557dd..6de772500ee9 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -241,10 +241,10 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, * additional tcp options in the timestamp. * This extracts these options from the timestamp echo. * - * return false if we decode an option that should not be. + * return false if we decode a tcp option that is disabled + * on the host. */ -bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, - struct net *net, bool *ecn_ok) +bool cookie_timestamp_decode(struct tcp_options_received *tcp_opt) { /* echoed timestamp, lowest bits contain options */ u32 options = tcp_opt->rcv_tsecr; @@ -258,9 +258,6 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, return false; tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0; - *ecn_ok = options & TS_OPT_ECN; - if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn) - return false; if (tcp_opt->sack_ok && !sysctl_tcp_sack) return false; @@ -273,7 +270,22 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, return sysctl_tcp_window_scaling != 0; } -EXPORT_SYMBOL(cookie_check_timestamp); +EXPORT_SYMBOL(cookie_timestamp_decode); + +bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt, + const struct net *net) +{ + bool ecn_ok = tcp_opt->rcv_tsecr & TS_OPT_ECN; + + if (!ecn_ok) + return false; + + if (net->ipv4.sysctl_tcp_ecn) + return true; + + return false; +} +EXPORT_SYMBOL(cookie_ecn_ok); struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) { @@ -289,7 +301,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) int mss; struct rtable *rt; __u8 rcv_wscale; - bool ecn_ok = false; struct flowi4 fl4; if (!sysctl_tcp_syncookies || !th->ack || th->rst) @@ -310,7 +321,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) memset(&tcp_opt, 0, sizeof(tcp_opt)); tcp_parse_options(skb, &tcp_opt, 0, NULL); - if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) + if (!cookie_timestamp_decode(&tcp_opt)) goto out; ret = NULL; @@ -328,7 +339,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) ireq->ir_loc_addr = ip_hdr(skb)->daddr; ireq->ir_rmt_addr = ip_hdr(skb)->saddr; ireq->ir_mark = inet_request_mark(sk, skb); - ireq->ecn_ok = ecn_ok; ireq->snd_wscale = tcp_opt.snd_wscale; ireq->sack_ok = tcp_opt.sack_ok; ireq->wscale_ok = tcp_opt.wscale_ok; @@ -377,6 +387,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) dst_metric(&rt->dst, RTAX_INITRWND)); ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk)); ret = get_cookie_sock(sk, skb, req, &rt->dst); /* ip_queue_xmit() depends on our flow being setup diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index be291baa2ec2..52cc8cb02c0c 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -166,7 +166,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) int mss; struct dst_entry *dst; __u8 rcv_wscale; - bool ecn_ok = false; if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; @@ -186,7 +185,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) memset(&tcp_opt, 0, sizeof(tcp_opt)); tcp_parse_options(skb, &tcp_opt, 0, NULL); - if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) + if (!cookie_timestamp_decode(&tcp_opt)) goto out; ret = NULL; @@ -223,7 +222,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) req->expires = 0UL; req->num_retrans = 0; - ireq->ecn_ok = ecn_ok; ireq->snd_wscale = tcp_opt.snd_wscale; ireq->sack_ok = tcp_opt.sack_ok; ireq->wscale_ok = tcp_opt.wscale_ok; @@ -264,6 +262,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) dst_metric(dst, RTAX_INITRWND)); ireq->rcv_wscale = rcv_wscale; + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk)); ret = get_cookie_sock(sk, skb, req, dst); out: -- GitLab From f7b3bec6f5167efaf56b756abfafb924cb1d3050 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 3 Nov 2014 17:35:03 +0100 Subject: [PATCH 3011/9457] net: allow setting ecn via routing table This patch allows to set ECN on a per-route basis in case the sysctl tcp_ecn is not set to 1. In other words, when ECN is set for specific routes, it provides a tcp_ecn=1 behaviour for that route while the rest of the stack acts according to the global settings. One can use 'ip route change dev $dev $net features ecn' to toggle this. Having a more fine-grained per-route setting can be beneficial for various reasons, for example, 1) within data centers, or 2) local ISPs may deploy ECN support for their own video/streaming services [1], etc. There was a recent measurement study/paper [2] which scanned the Alexa's publicly available top million websites list from a vantage point in US, Europe and Asia: Half of the Alexa list will now happily use ECN (tcp_ecn=2, most likely blamed to commit 255cac91c3 ("tcp: extend ECN sysctl to allow server-side only ECN") ;)); the break in connectivity on-path was found is about 1 in 10,000 cases. Timeouts rather than receiving back RSTs were much more common in the negotiation phase (and mostly seen in the Alexa middle band, ranks around 50k-150k): from 12-thousand hosts on which there _may_ be ECN-linked connection failures, only 79 failed with RST when _not_ failing with RST when ECN is not requested. It's unclear though, how much equipment in the wild actually marks CE when buffers start to fill up. We thought about a fallback to non-ECN for retransmitted SYNs as another global option (which could perhaps one day be made default), but as Eric points out, there's much more work needed to detect broken middleboxes. Two examples Eric mentioned are buggy firewalls that accept only a single SYN per flow, and middleboxes that successfully let an ECN flow establish, but later mark CE for all packets (so cwnd converges to 1). [1] http://www.ietf.org/proceedings/89/slides/slides-89-tsvarea-1.pdf, p.15 [2] http://ecn.ethz.ch/ Joint work with Daniel Borkmann. Reference: http://thread.gmane.org/gmane.linux.network/335797 Suggested-by: Hannes Frederic Sowa Acked-by: Eric Dumazet Signed-off-by: Daniel Borkmann Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- include/net/tcp.h | 2 +- net/ipv4/syncookies.c | 6 +++--- net/ipv4/tcp_input.c | 25 +++++++++++++++---------- net/ipv4/tcp_output.c | 13 +++++++++++-- net/ipv6/syncookies.c | 2 +- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 36c5084964cd..f50f29faf76f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -493,7 +493,7 @@ __u32 cookie_v4_init_sequence(struct sock *sk, const struct sk_buff *skb, __u32 cookie_init_timestamp(struct request_sock *req); bool cookie_timestamp_decode(struct tcp_options_received *opt); bool cookie_ecn_ok(const struct tcp_options_received *opt, - const struct net *net); + const struct net *net, const struct dst_entry *dst); /* From net/ipv6/syncookies.c */ int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th, diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 6de772500ee9..45fe60c5238e 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -273,7 +273,7 @@ bool cookie_timestamp_decode(struct tcp_options_received *tcp_opt) EXPORT_SYMBOL(cookie_timestamp_decode); bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt, - const struct net *net) + const struct net *net, const struct dst_entry *dst) { bool ecn_ok = tcp_opt->rcv_tsecr & TS_OPT_ECN; @@ -283,7 +283,7 @@ bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt, if (net->ipv4.sysctl_tcp_ecn) return true; - return false; + return dst_feature(dst, RTAX_FEATURE_ECN); } EXPORT_SYMBOL(cookie_ecn_ok); @@ -387,7 +387,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) dst_metric(&rt->dst, RTAX_INITRWND)); ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk)); + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); ret = get_cookie_sock(sk, skb, req, &rt->dst); /* ip_queue_xmit() depends on our flow being setup diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4e4617e90417..196b4388116c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5876,20 +5876,22 @@ static inline void pr_drop_req(struct request_sock *req, __u16 port, int family) */ static void tcp_ecn_create_request(struct request_sock *req, const struct sk_buff *skb, - const struct sock *listen_sk) + const struct sock *listen_sk, + const struct dst_entry *dst) { const struct tcphdr *th = tcp_hdr(skb); const struct net *net = sock_net(listen_sk); bool th_ecn = th->ece && th->cwr; - bool ect, need_ecn; + bool ect, need_ecn, ecn_ok; if (!th_ecn) return; ect = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield); need_ecn = tcp_ca_needs_ecn(listen_sk); + ecn_ok = net->ipv4.sysctl_tcp_ecn || dst_feature(dst, RTAX_FEATURE_ECN); - if (!ect && !need_ecn && net->ipv4.sysctl_tcp_ecn) + if (!ect && !need_ecn && ecn_ok) inet_rsk(req)->ecn_ok = 1; else if (ect && need_ecn) inet_rsk(req)->ecn_ok = 1; @@ -5954,13 +5956,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, if (security_inet_conn_request(sk, skb, req)) goto drop_and_free; - if (!want_cookie || tmp_opt.tstamp_ok) - tcp_ecn_create_request(req, skb, sk); - - if (want_cookie) { - isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); - req->cookie_ts = tmp_opt.tstamp_ok; - } else if (!isn) { + if (!want_cookie && !isn) { /* VJ's idea. We save last timestamp seen * from the destination in peer table, when entering * state TIME-WAIT, and check against it before @@ -6008,6 +6004,15 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, goto drop_and_free; } + tcp_ecn_create_request(req, skb, sk, dst); + + if (want_cookie) { + isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); + req->cookie_ts = tmp_opt.tstamp_ok; + if (!tmp_opt.tstamp_ok) + inet_rsk(req)->ecn_ok = 0; + } + tcp_rsk(req)->snt_isn = isn; tcp_openreq_init_rwin(req, sk, dst); fastopen = !want_cookie && diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a3d453b94747..0b88158dd4a7 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -333,10 +333,19 @@ static void tcp_ecn_send_synack(struct sock *sk, struct sk_buff *skb) static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); + bool use_ecn = sock_net(sk)->ipv4.sysctl_tcp_ecn == 1 || + tcp_ca_needs_ecn(sk); + + if (!use_ecn) { + const struct dst_entry *dst = __sk_dst_get(sk); + + if (dst && dst_feature(dst, RTAX_FEATURE_ECN)) + use_ecn = true; + } tp->ecn_flags = 0; - if (sock_net(sk)->ipv4.sysctl_tcp_ecn == 1 || - tcp_ca_needs_ecn(sk)) { + + if (use_ecn) { TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; tp->ecn_flags = TCP_ECN_OK; if (tcp_ca_needs_ecn(sk)) diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 52cc8cb02c0c..7337fc7947e2 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -262,7 +262,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) dst_metric(dst, RTAX_INITRWND)); ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk)); + ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); ret = get_cookie_sock(sk, skb, req, dst); out: -- GitLab From 78eaf6095cc763c1a228ebac5682852f04e85205 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Tue, 4 Nov 2014 17:11:10 +0800 Subject: [PATCH 3012/9457] clk: rockchip: disable unused clocks The rockchip clock driver use CLK_IGNORE_UNUSED flag to make sure all the clocks are available like default power on state. We have implement the clock manage in most of rockchip drivers, it is time to remove it for power save. Instead we add CLK_IGNORE_UNUSED for some clock nodes which should be on during boot or no module driver in kernel will initialize it. Signed-off-by: Kever Yang Reviewed-by: Doug Anderson Tested-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 38 ++++----- drivers/clk/rockchip/clk-rk3288.c | 128 +++++++++++++++--------------- drivers/clk/rockchip/clk.c | 9 --- 3 files changed, 83 insertions(+), 92 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index beed49c79126..4dfd5e249347 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -257,9 +257,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "hclk_vdpu", "aclk_vdpu", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), - GATE(0, "gpll_ddr", "gpll", 0, + GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 7, GFLAGS), - COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(0), 2, GFLAGS), @@ -270,10 +270,10 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 6, GFLAGS), GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, RK2928_CLKGATE_CON(0), 5, GFLAGS), - GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, + GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 4, GFLAGS), - COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 0, GFLAGS), COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0, @@ -304,9 +304,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -399,8 +399,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* aclk_cpu gates */ GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), @@ -416,8 +416,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS), + GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), @@ -457,18 +457,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS), - GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS), /* aclk_peri */ GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS), - GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS), - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 4, GFLAGS), + GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS), + GATE(0, "pclk_peri_axi_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS), GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), @@ -511,7 +511,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, + GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, @@ -618,7 +618,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { - COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, + COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), @@ -633,7 +633,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "armclk", 0, + GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 279a662f5bd7..bd9534a00737 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -228,67 +228,67 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { * Clock-Architecture Diagram 1 */ - GATE(0, "apll_core", "apll", 0, + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 1, GFLAGS), - GATE(0, "gpll_core", "gpll", 0, + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 0, GFLAGS), - COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 1, GFLAGS), - COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 3, GFLAGS), - COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, + COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 4, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 5, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 6, GFLAGS), COMPOSITE_NOMUX(0, "atclk", "armclk", 0, RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 7, GFLAGS), - COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, + COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 8, GFLAGS), GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 9, GFLAGS), - GATE(0, "cs_dbg", "pclk_dbg_pre", 0, + GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(12), 10, GFLAGS), GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 11, GFLAGS), - GATE(0, "dpll_ddr", "dpll", 0, + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 8, GFLAGS), GATE(0, "gpll_ddr", "gpll", 0, RK3288_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), - GATE(0, "gpll_aclk_cpu", "gpll", 0, + GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 10, GFLAGS), - GATE(0, "cpll_aclk_cpu", "cpll", 0, + GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 11, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, + COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), - GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 3, GFLAGS), - COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, RK3288_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, @@ -296,7 +296,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), - GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0, + GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, @@ -375,12 +375,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), - COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(3), 0, GFLAGS), DIV(0, "hclk_vio", "aclk_vio0", 0, RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), - COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(3), 2, GFLAGS), @@ -438,7 +438,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { DIV(0, "pclk_pd_alive", "gpll", 0, RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), - COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0, + COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 8, GFLAGS), @@ -446,16 +446,16 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 7, GFLAGS), - COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(2), 0, GFLAGS), COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 3, GFLAGS), - COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 2, GFLAGS), - GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(2), 1, GFLAGS), /* @@ -492,13 +492,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), - GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0, + GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, @@ -603,19 +603,19 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ /* aclk_cpu gates */ - GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS), - GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS), - GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS), + GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS), + GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS), + GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS), GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS), GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), - GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS), + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS), GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), @@ -632,34 +632,34 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), - GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS), + GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), /* ddrctrl [DDR Controller PHY clock] gates */ - GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS), - GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS), + GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), + GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS), /* ddrphy gates */ - GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS), + GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS), /* aclk_peri gates */ - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS), - GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS), - GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS), + GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS), GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), - GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS), - GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS), - GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS), + GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS), + GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), @@ -671,7 +671,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS), + GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), @@ -707,22 +707,22 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS), - GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), + GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS), /* pclk_pd_pmu gates */ - GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS), - GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS), - GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS), - GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), + GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), + GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS), + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), /* hclk_vio gates */ GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), - GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), - GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), + GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS), + GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS), GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), @@ -731,24 +731,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), - GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS), GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), /* aclk_vio0 gates */ GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), - GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), + GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS), GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), /* aclk_vio1 gates */ GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), - GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), + GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS), /* aclk_rga_pre gates */ GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), - GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), + GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS), /* * Other ungrouped clocks. diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 1e68bff481b8..dec6f8d6dc13 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -246,9 +246,6 @@ void __init rockchip_clk_register_branches( list->div_flags, &clk_lock); break; case branch_fraction_divider: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_frac_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->div_flags, @@ -258,18 +255,12 @@ void __init rockchip_clk_register_branches( case branch_gate: flags |= CLK_SET_RATE_PARENT; - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = clk_register_gate(NULL, list->name, list->parent_names[0], flags, reg_base + list->gate_offset, list->gate_shift, list->gate_flags, &clk_lock); break; case branch_composite: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->mux_shift, -- GitLab From 05006e8c59050b2bab1bfe9cac631505d21122a3 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 22:54:36 +0100 Subject: [PATCH 3013/9457] esp4: remove assignment in if condition Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/esp4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 360b565918c4..d2bf02e0a678 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -392,8 +392,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) if (elen <= 0) goto out; - if ((err = skb_cow_data(skb, 0, &trailer)) < 0) + err = skb_cow_data(skb, 0, &trailer); + if (err < 0) goto out; + nfrags = err; assoclen = sizeof(*esph); -- GitLab From 869ba988fedb0fb9f4b0f18904623dc29775c503 Mon Sep 17 00:00:00 2001 From: Florent Fourcot Date: Tue, 4 Nov 2014 23:01:00 +0100 Subject: [PATCH 3014/9457] ipv6: trivial, add bracket for the if block The "else" block is on several lines and use bracket. Signed-off-by: Florent Fourcot Signed-off-by: David S. Miller --- net/ipv6/ip6_flowlabel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 3dd7d4ebd7cd..c14343715049 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -769,10 +769,10 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) static int ip6fl_seq_show(struct seq_file *seq, void *v) { struct ip6fl_iter_state *state = ip6fl_seq_private(seq); - if (v == SEQ_START_TOKEN) + if (v == SEQ_START_TOKEN) { seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); - else { + } else { struct ip6_flowlabel *fl = v; seq_printf(seq, "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", -- GitLab From 6cf1093e58f5c103840cf361721b6e346ec2275d Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 4 Nov 2014 23:11:19 +0100 Subject: [PATCH 3015/9457] udp: remove blank line between set and test Suggested-by: Joe Perches Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/ipv4/udp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index cf0cece50b6c..3f001db72351 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1784,7 +1784,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, saddr, daddr, udptable); sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk != NULL) { int ret; -- GitLab From 30349bdbc4da5ecf0efa25556e3caff9c9b8c5f7 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Tue, 4 Nov 2014 01:25:09 +0200 Subject: [PATCH 3016/9457] net: phy: spi_ks8995: remove sysfs bin file by registered attribute When a sysfs binary file is asked to be removed, it is found by attribute name, so strictly speaking this change is not a fix, but just in case when attribute name is changed in the driver or sysfs internals are changed, it might be better to remove the previously created file using right the same binary attribute. Signed-off-by: Vladimir Zapolskiy Cc: Florian Fainelli Cc: David S. Miller Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/spi_ks8995.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index eab57fc5b967..46530159256b 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c @@ -353,7 +353,9 @@ static int ks8995_probe(struct spi_device *spi) static int ks8995_remove(struct spi_device *spi) { - sysfs_remove_bin_file(&spi->dev.kobj, &ks8995_registers_attr); + struct ks8995_switch *ks = spi_get_drvdata(spi); + + sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr); return 0; } -- GitLab From 083fe3b035d286d79071fd77d2a2c5abfdef495b Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 19:00:17 +0100 Subject: [PATCH 3017/9457] drm: make sure visible is set to false if fb is null MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't let visible set true while the fb is null, some places of the code only check for visible to base its decisions. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_plane_helper.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 827ec1a3040b..fe4d1fb2376c 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -127,6 +127,11 @@ int drm_plane_helper_check_update(struct drm_plane *plane, return -ERANGE; } + if (!fb) { + *visible = false; + return 0; + } + *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); if (!*visible) /* -- GitLab From 3ead8bb26e1e3a8b35f41a0eb65a1bd571b0204e Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 19:00:18 +0100 Subject: [PATCH 3018/9457] drm/i915: remove unneeded visible check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fb check introduced to drm_plane_helper_check_update() just make this check impossible to branch in. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 46224c6307cb..6e9d4e16d60f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11639,23 +11639,12 @@ intel_check_primary_plane(struct drm_plane *plane, struct drm_rect *dest = &state->dst; struct drm_rect *src = &state->src; const struct drm_rect *clip = &state->clip; - int ret; - - ret = drm_plane_helper_check_update(plane, crtc, fb, - src, dest, clip, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, true, &state->visible); - if (ret) - return ret; - /* no fb bound */ - if (state->visible && !fb) { - DRM_ERROR("No FB bound\n"); - return -EINVAL; - } - - return 0; + return drm_plane_helper_check_update(plane, crtc, fb, + src, dest, clip, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + false, true, &state->visible); } static int -- GitLab From 7c10a2b5876e014b3986d7e20b2a2894a757b138 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:43 +0200 Subject: [PATCH 3019/9457] drm/i915: add new intel audio file to group DP/HDMI audio In preparation for some additional cleanup. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/intel_audio.c | 357 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 323 +----------------------- drivers/gpu/drm/i915/intel_drv.h | 8 +- 4 files changed, 368 insertions(+), 323 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_audio.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 9c646c66fa58..891e584e97ea 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -44,7 +44,8 @@ i915-y += intel_renderstate_gen6.o \ intel_renderstate_gen9.o # modesetting core code -i915-y += intel_bios.o \ +i915-y += intel_audio.o \ + intel_bios.o \ intel_display.o \ intel_fifo_underrun.o \ intel_frontbuffer.o \ diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c new file mode 100644 index 000000000000..167903b5e3ff --- /dev/null +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -0,0 +1,357 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include "intel_drv.h" +#include "i915_drv.h" + +static struct { + int clock; + u32 config; +} hdmi_audio_clock[] = { + { DIV_ROUND_UP(25200 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 }, + { 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */ + { 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 }, + { 27000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 }, + { 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 }, + { 54000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 }, + { DIV_ROUND_UP(74250 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 }, + { 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 }, + { DIV_ROUND_UP(148500 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 }, + { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, +}; + +/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ +static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { + if (mode->clock == hdmi_audio_clock[i].clock) + break; + } + + if (i == ARRAY_SIZE(hdmi_audio_clock)) { + DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n", mode->clock); + i = 1; + } + + DRM_DEBUG_KMS("Configuring HDMI audio for pixel clock %d (0x%08x)\n", + hdmi_audio_clock[i].clock, + hdmi_audio_clock[i].config); + + return hdmi_audio_clock[i].config; +} + +static bool intel_eld_uptodate(struct drm_connector *connector, + int reg_eldv, uint32_t bits_eldv, + int reg_elda, uint32_t bits_elda, + int reg_edid) +{ + struct drm_i915_private *dev_priv = connector->dev->dev_private; + uint8_t *eld = connector->eld; + uint32_t i; + + i = I915_READ(reg_eldv); + i &= bits_eldv; + + if (!eld[0]) + return !i; + + if (!i) + return false; + + i = I915_READ(reg_elda); + i &= ~bits_elda; + I915_WRITE(reg_elda, i); + + for (i = 0; i < eld[2]; i++) + if (I915_READ(reg_edid) != *((uint32_t *)eld + i)) + return false; + + return true; +} + +static void g4x_write_eld(struct drm_connector *connector, + struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + struct drm_i915_private *dev_priv = connector->dev->dev_private; + uint8_t *eld = connector->eld; + uint32_t eldv; + uint32_t len; + uint32_t i; + + i = I915_READ(G4X_AUD_VID_DID); + + if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL) + eldv = G4X_ELDV_DEVCL_DEVBLC; + else + eldv = G4X_ELDV_DEVCTG; + + if (intel_eld_uptodate(connector, + G4X_AUD_CNTL_ST, eldv, + G4X_AUD_CNTL_ST, G4X_ELD_ADDR, + G4X_HDMIW_HDMIEDID)) + return; + + i = I915_READ(G4X_AUD_CNTL_ST); + i &= ~(eldv | G4X_ELD_ADDR); + len = (i >> 9) & 0x1f; /* ELD buffer size */ + I915_WRITE(G4X_AUD_CNTL_ST, i); + + if (!eld[0]) + return; + + len = min_t(uint8_t, eld[2], len); + DRM_DEBUG_DRIVER("ELD size %d\n", len); + for (i = 0; i < len; i++) + I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i)); + + i = I915_READ(G4X_AUD_CNTL_ST); + i |= eldv; + I915_WRITE(G4X_AUD_CNTL_ST, i); +} + +static void haswell_write_eld(struct drm_connector *connector, + struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint8_t *eld = connector->eld; + uint32_t eldv; + uint32_t i; + int len; + int pipe = to_intel_crtc(crtc)->pipe; + int tmp; + + int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); + int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); + int aud_config = HSW_AUD_CFG(pipe); + int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD; + + /* Audio output enable */ + DRM_DEBUG_DRIVER("HDMI audio: enable codec\n"); + tmp = I915_READ(aud_cntrl_st2); + tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4)); + I915_WRITE(aud_cntrl_st2, tmp); + POSTING_READ(aud_cntrl_st2); + + assert_pipe_disabled(dev_priv, to_intel_crtc(crtc)->pipe); + + /* Set ELD valid state */ + tmp = I915_READ(aud_cntrl_st2); + DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); + tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); + I915_WRITE(aud_cntrl_st2, tmp); + tmp = I915_READ(aud_cntrl_st2); + DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp); + + /* Enable HDMI mode */ + tmp = I915_READ(aud_config); + DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp); + /* clear N_programing_enable and N_value_index */ + tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); + I915_WRITE(aud_config, tmp); + + DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); + + eldv = AUDIO_ELD_VALID_A << (pipe * 4); + + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { + DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); + eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ + I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ + } else { + I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); + } + + if (intel_eld_uptodate(connector, + aud_cntrl_st2, eldv, + aud_cntl_st, IBX_ELD_ADDRESS, + hdmiw_hdmiedid)) + return; + + i = I915_READ(aud_cntrl_st2); + i &= ~eldv; + I915_WRITE(aud_cntrl_st2, i); + + if (!eld[0]) + return; + + i = I915_READ(aud_cntl_st); + i &= ~IBX_ELD_ADDRESS; + I915_WRITE(aud_cntl_st, i); + i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ + DRM_DEBUG_DRIVER("port num:%d\n", i); + + len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ + DRM_DEBUG_DRIVER("ELD size %d\n", len); + for (i = 0; i < len; i++) + I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); + + i = I915_READ(aud_cntrl_st2); + i |= eldv; + I915_WRITE(aud_cntrl_st2, i); + +} + +static void ironlake_write_eld(struct drm_connector *connector, + struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint8_t *eld = connector->eld; + uint32_t eldv; + uint32_t i; + int len; + int hdmiw_hdmiedid; + int aud_config; + int aud_cntl_st; + int aud_cntrl_st2; + int pipe = to_intel_crtc(crtc)->pipe; + + if (HAS_PCH_IBX(connector->dev)) { + hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); + aud_config = IBX_AUD_CFG(pipe); + aud_cntl_st = IBX_AUD_CNTL_ST(pipe); + aud_cntrl_st2 = IBX_AUD_CNTL_ST2; + } else if (IS_VALLEYVIEW(connector->dev)) { + hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe); + aud_config = VLV_AUD_CFG(pipe); + aud_cntl_st = VLV_AUD_CNTL_ST(pipe); + aud_cntrl_st2 = VLV_AUD_CNTL_ST2; + } else { + hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe); + aud_config = CPT_AUD_CFG(pipe); + aud_cntl_st = CPT_AUD_CNTL_ST(pipe); + aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; + } + + DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); + + if (IS_VALLEYVIEW(connector->dev)) { + struct intel_encoder *intel_encoder; + struct intel_digital_port *intel_dig_port; + + intel_encoder = intel_attached_encoder(connector); + intel_dig_port = enc_to_dig_port(&intel_encoder->base); + i = intel_dig_port->port; + } else { + i = I915_READ(aud_cntl_st); + i = (i >> 29) & DIP_PORT_SEL_MASK; + /* DIP_Port_Select, 0x1 = PortB */ + } + + if (!i) { + DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); + /* operate blindly on all ports */ + eldv = IBX_ELD_VALIDB; + eldv |= IBX_ELD_VALIDB << 4; + eldv |= IBX_ELD_VALIDB << 8; + } else { + DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(i)); + eldv = IBX_ELD_VALIDB << ((i - 1) * 4); + } + + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { + DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); + eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ + I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ + } else { + I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); + } + + if (intel_eld_uptodate(connector, + aud_cntrl_st2, eldv, + aud_cntl_st, IBX_ELD_ADDRESS, + hdmiw_hdmiedid)) + return; + + i = I915_READ(aud_cntrl_st2); + i &= ~eldv; + I915_WRITE(aud_cntrl_st2, i); + + if (!eld[0]) + return; + + i = I915_READ(aud_cntl_st); + i &= ~IBX_ELD_ADDRESS; + I915_WRITE(aud_cntl_st, i); + + len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ + DRM_DEBUG_DRIVER("ELD size %d\n", len); + for (i = 0; i < len; i++) + I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); + + i = I915_READ(aud_cntrl_st2); + i |= eldv; + I915_WRITE(aud_cntrl_st2, i); +} + +void intel_write_eld(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct drm_crtc *crtc = encoder->crtc; + struct drm_connector *connector; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + connector = drm_select_eld(encoder, mode); + if (!connector) + return; + + DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", + connector->base.id, + connector->name, + connector->encoder->base.id, + connector->encoder->name); + + connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; + + if (dev_priv->display.write_eld) + dev_priv->display.write_eld(connector, crtc, mode); +} + +/** + * intel_init_audio - Set up chip specific audio functions + * @dev: drm device + */ +void intel_init_audio(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (IS_G4X(dev)) + dev_priv->display.write_eld = g4x_write_eld; + else if (IS_VALLEYVIEW(dev)) + dev_priv->display.write_eld = ironlake_write_eld; + else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) + dev_priv->display.write_eld = haswell_write_eld; + else if (HAS_PCH_SPLIT(dev)) + dev_priv->display.write_eld = ironlake_write_eld; +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6e9d4e16d60f..aeda09dcfb72 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -406,7 +406,7 @@ static void vlv_clock(int refclk, intel_clock_t *clock) /** * Returns whether any output on the specified pipe is of the specified type */ -static bool intel_pipe_has_type(struct intel_crtc *crtc, int type) +bool intel_pipe_has_type(struct intel_crtc *crtc, int type) { struct drm_device *dev = crtc->base.dev; struct intel_encoder *encoder; @@ -7940,316 +7940,6 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, return true; } -static struct { - int clock; - u32 config; -} hdmi_audio_clock[] = { - { DIV_ROUND_UP(25200 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 }, - { 25200, AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 }, /* default per bspec */ - { 27000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 }, - { 27000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 }, - { 54000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 }, - { 54000 * 1001 / 1000, AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 }, - { DIV_ROUND_UP(74250 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 }, - { 74250, AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 }, - { DIV_ROUND_UP(148500 * 1000, 1001), AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 }, - { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, -}; - -/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ -static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { - if (mode->clock == hdmi_audio_clock[i].clock) - break; - } - - if (i == ARRAY_SIZE(hdmi_audio_clock)) { - DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n", mode->clock); - i = 1; - } - - DRM_DEBUG_KMS("Configuring HDMI audio for pixel clock %d (0x%08x)\n", - hdmi_audio_clock[i].clock, - hdmi_audio_clock[i].config); - - return hdmi_audio_clock[i].config; -} - -static bool intel_eld_uptodate(struct drm_connector *connector, - int reg_eldv, uint32_t bits_eldv, - int reg_elda, uint32_t bits_elda, - int reg_edid) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint8_t *eld = connector->eld; - uint32_t i; - - i = I915_READ(reg_eldv); - i &= bits_eldv; - - if (!eld[0]) - return !i; - - if (!i) - return false; - - i = I915_READ(reg_elda); - i &= ~bits_elda; - I915_WRITE(reg_elda, i); - - for (i = 0; i < eld[2]; i++) - if (I915_READ(reg_edid) != *((uint32_t *)eld + i)) - return false; - - return true; -} - -static void g4x_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint8_t *eld = connector->eld; - uint32_t eldv; - uint32_t len; - uint32_t i; - - i = I915_READ(G4X_AUD_VID_DID); - - if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL) - eldv = G4X_ELDV_DEVCL_DEVBLC; - else - eldv = G4X_ELDV_DEVCTG; - - if (intel_eld_uptodate(connector, - G4X_AUD_CNTL_ST, eldv, - G4X_AUD_CNTL_ST, G4X_ELD_ADDR, - G4X_HDMIW_HDMIEDID)) - return; - - i = I915_READ(G4X_AUD_CNTL_ST); - i &= ~(eldv | G4X_ELD_ADDR); - len = (i >> 9) & 0x1f; /* ELD buffer size */ - I915_WRITE(G4X_AUD_CNTL_ST, i); - - if (!eld[0]) - return; - - len = min_t(uint8_t, eld[2], len); - DRM_DEBUG_DRIVER("ELD size %d\n", len); - for (i = 0; i < len; i++) - I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i)); - - i = I915_READ(G4X_AUD_CNTL_ST); - i |= eldv; - I915_WRITE(G4X_AUD_CNTL_ST, i); -} - -static void haswell_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint8_t *eld = connector->eld; - uint32_t eldv; - uint32_t i; - int len; - int pipe = to_intel_crtc(crtc)->pipe; - int tmp; - - int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); - int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); - int aud_config = HSW_AUD_CFG(pipe); - int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD; - - /* Audio output enable */ - DRM_DEBUG_DRIVER("HDMI audio: enable codec\n"); - tmp = I915_READ(aud_cntrl_st2); - tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4)); - I915_WRITE(aud_cntrl_st2, tmp); - POSTING_READ(aud_cntrl_st2); - - assert_pipe_disabled(dev_priv, to_intel_crtc(crtc)->pipe); - - /* Set ELD valid state */ - tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); - tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); - I915_WRITE(aud_cntrl_st2, tmp); - tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp); - - /* Enable HDMI mode */ - tmp = I915_READ(aud_config); - DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp); - /* clear N_programing_enable and N_value_index */ - tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); - I915_WRITE(aud_config, tmp); - - DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); - - eldv = AUDIO_ELD_VALID_A << (pipe * 4); - - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { - DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); - eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ - I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - } else { - I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - } - - if (intel_eld_uptodate(connector, - aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS, - hdmiw_hdmiedid)) - return; - - i = I915_READ(aud_cntrl_st2); - i &= ~eldv; - I915_WRITE(aud_cntrl_st2, i); - - if (!eld[0]) - return; - - i = I915_READ(aud_cntl_st); - i &= ~IBX_ELD_ADDRESS; - I915_WRITE(aud_cntl_st, i); - i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ - DRM_DEBUG_DRIVER("port num:%d\n", i); - - len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ - DRM_DEBUG_DRIVER("ELD size %d\n", len); - for (i = 0; i < len; i++) - I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - - i = I915_READ(aud_cntrl_st2); - i |= eldv; - I915_WRITE(aud_cntrl_st2, i); - -} - -static void ironlake_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint8_t *eld = connector->eld; - uint32_t eldv; - uint32_t i; - int len; - int hdmiw_hdmiedid; - int aud_config; - int aud_cntl_st; - int aud_cntrl_st2; - int pipe = to_intel_crtc(crtc)->pipe; - - if (HAS_PCH_IBX(connector->dev)) { - hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); - aud_config = IBX_AUD_CFG(pipe); - aud_cntl_st = IBX_AUD_CNTL_ST(pipe); - aud_cntrl_st2 = IBX_AUD_CNTL_ST2; - } else if (IS_VALLEYVIEW(connector->dev)) { - hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe); - aud_config = VLV_AUD_CFG(pipe); - aud_cntl_st = VLV_AUD_CNTL_ST(pipe); - aud_cntrl_st2 = VLV_AUD_CNTL_ST2; - } else { - hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe); - aud_config = CPT_AUD_CFG(pipe); - aud_cntl_st = CPT_AUD_CNTL_ST(pipe); - aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; - } - - DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); - - if (IS_VALLEYVIEW(connector->dev)) { - struct intel_encoder *intel_encoder; - struct intel_digital_port *intel_dig_port; - - intel_encoder = intel_attached_encoder(connector); - intel_dig_port = enc_to_dig_port(&intel_encoder->base); - i = intel_dig_port->port; - } else { - i = I915_READ(aud_cntl_st); - i = (i >> 29) & DIP_PORT_SEL_MASK; - /* DIP_Port_Select, 0x1 = PortB */ - } - - if (!i) { - DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); - /* operate blindly on all ports */ - eldv = IBX_ELD_VALIDB; - eldv |= IBX_ELD_VALIDB << 4; - eldv |= IBX_ELD_VALIDB << 8; - } else { - DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(i)); - eldv = IBX_ELD_VALIDB << ((i - 1) * 4); - } - - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { - DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); - eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ - I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - } else { - I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - } - - if (intel_eld_uptodate(connector, - aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS, - hdmiw_hdmiedid)) - return; - - i = I915_READ(aud_cntrl_st2); - i &= ~eldv; - I915_WRITE(aud_cntrl_st2, i); - - if (!eld[0]) - return; - - i = I915_READ(aud_cntl_st); - i &= ~IBX_ELD_ADDRESS; - I915_WRITE(aud_cntl_st, i); - - len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ - DRM_DEBUG_DRIVER("ELD size %d\n", len); - for (i = 0; i < len; i++) - I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - - i = I915_READ(aud_cntrl_st2); - i |= eldv; - I915_WRITE(aud_cntrl_st2, i); -} - -void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct drm_crtc *crtc = encoder->crtc; - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - connector = drm_select_eld(encoder, mode); - if (!connector) - return; - - DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, - connector->name, - connector->encoder->base.id, - connector->encoder->name); - - connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; - - if (dev_priv->display.write_eld) - dev_priv->display.write_eld(connector, crtc, mode); -} - static void i845_update_cursor(struct drm_crtc *crtc, u32 base) { struct drm_device *dev = crtc->dev; @@ -12638,33 +12328,25 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.get_display_clock_speed = i830_get_display_clock_speed; - if (IS_G4X(dev)) { - dev_priv->display.write_eld = g4x_write_eld; - } else if (IS_GEN5(dev)) { + if (IS_GEN5(dev)) { dev_priv->display.fdi_link_train = ironlake_fdi_link_train; - dev_priv->display.write_eld = ironlake_write_eld; } else if (IS_GEN6(dev)) { dev_priv->display.fdi_link_train = gen6_fdi_link_train; - dev_priv->display.write_eld = ironlake_write_eld; dev_priv->display.modeset_global_resources = snb_modeset_global_resources; } else if (IS_IVYBRIDGE(dev)) { /* FIXME: detect B0+ stepping and use auto training */ dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; - dev_priv->display.write_eld = ironlake_write_eld; dev_priv->display.modeset_global_resources = ivb_modeset_global_resources; } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { dev_priv->display.fdi_link_train = hsw_fdi_link_train; - dev_priv->display.write_eld = haswell_write_eld; dev_priv->display.modeset_global_resources = haswell_modeset_global_resources; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.modeset_global_resources = valleyview_modeset_global_resources; - dev_priv->display.write_eld = ironlake_write_eld; } else if (INTEL_INFO(dev)->gen >= 9) { - dev_priv->display.write_eld = haswell_write_eld; dev_priv->display.modeset_global_resources = haswell_modeset_global_resources; } @@ -12919,6 +12601,7 @@ void intel_modeset_init(struct drm_device *dev) return; intel_init_display(dev); + intel_init_audio(dev); if (IS_GEN2(dev)) { dev->mode_config.max_width = 2048; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5ab813c6091e..3bbc4fe817ff 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -848,6 +848,11 @@ void intel_frontbuffer_flip(struct drm_device *dev, void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); +/* intel_audio.c */ +void intel_init_audio(struct drm_device *dev); +void intel_write_eld(struct drm_encoder *encoder, + struct drm_display_mode *mode); + /* intel_display.c */ const char *intel_output_name(int output); bool intel_has_pending_fb_unpin(struct drm_device *dev); @@ -873,6 +878,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe); +bool intel_pipe_has_type(struct intel_crtc *crtc, int type); static inline void intel_wait_for_vblank(struct drm_device *dev, int pipe) { @@ -924,8 +930,6 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pipe_enabled(d, p) assert_pipe(d, p, true) #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) -void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode); unsigned long intel_gen4_compute_page_offset(int *x, int *y, unsigned int tiling_mode, unsigned int bpp, -- GitLab From 87fcb2ad4582c6fb8fb661a943670485df0a1810 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:44 +0200 Subject: [PATCH 3020/9457] drm/i915/audio: constify hdmi audio clock struct Const is good. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 167903b5e3ff..e761f2c8d1ae 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -28,7 +28,7 @@ #include "intel_drv.h" #include "i915_drv.h" -static struct { +static const struct { int clock; u32 config; } hdmi_audio_clock[] = { -- GitLab From f9f682ae3530f9287379dd91d1b7deaef4abf391 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:45 +0200 Subject: [PATCH 3021/9457] drm/i915/audio: beat some sense into the variable types and names Most importantly, "i" need not be the universal variable used for everything. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 115 ++++++++++++++--------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index e761f2c8d1ae..00e9bfcd1e8d 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -73,20 +73,21 @@ static bool intel_eld_uptodate(struct drm_connector *connector, { struct drm_i915_private *dev_priv = connector->dev->dev_private; uint8_t *eld = connector->eld; - uint32_t i; + uint32_t tmp; + int i; - i = I915_READ(reg_eldv); - i &= bits_eldv; + tmp = I915_READ(reg_eldv); + tmp &= bits_eldv; if (!eld[0]) - return !i; + return !tmp; - if (!i) + if (!tmp) return false; - i = I915_READ(reg_elda); - i &= ~bits_elda; - I915_WRITE(reg_elda, i); + tmp = I915_READ(reg_elda); + tmp &= ~bits_elda; + I915_WRITE(reg_elda, tmp); for (i = 0; i < eld[2]; i++) if (I915_READ(reg_edid) != *((uint32_t *)eld + i)) @@ -102,12 +103,11 @@ static void g4x_write_eld(struct drm_connector *connector, struct drm_i915_private *dev_priv = connector->dev->dev_private; uint8_t *eld = connector->eld; uint32_t eldv; - uint32_t len; - uint32_t i; - - i = I915_READ(G4X_AUD_VID_DID); + uint32_t tmp; + int len, i; - if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL) + tmp = I915_READ(G4X_AUD_VID_DID); + if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) eldv = G4X_ELDV_DEVCL_DEVBLC; else eldv = G4X_ELDV_DEVCTG; @@ -118,22 +118,22 @@ static void g4x_write_eld(struct drm_connector *connector, G4X_HDMIW_HDMIEDID)) return; - i = I915_READ(G4X_AUD_CNTL_ST); - i &= ~(eldv | G4X_ELD_ADDR); - len = (i >> 9) & 0x1f; /* ELD buffer size */ - I915_WRITE(G4X_AUD_CNTL_ST, i); + tmp = I915_READ(G4X_AUD_CNTL_ST); + tmp &= ~(eldv | G4X_ELD_ADDR); + len = (tmp >> 9) & 0x1f; /* ELD buffer size */ + I915_WRITE(G4X_AUD_CNTL_ST, tmp); if (!eld[0]) return; - len = min_t(uint8_t, eld[2], len); + len = min_t(int, eld[2], len); DRM_DEBUG_DRIVER("ELD size %d\n", len); for (i = 0; i < len; i++) I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i)); - i = I915_READ(G4X_AUD_CNTL_ST); - i |= eldv; - I915_WRITE(G4X_AUD_CNTL_ST, i); + tmp = I915_READ(G4X_AUD_CNTL_ST); + tmp |= eldv; + I915_WRITE(G4X_AUD_CNTL_ST, tmp); } static void haswell_write_eld(struct drm_connector *connector, @@ -144,11 +144,10 @@ static void haswell_write_eld(struct drm_connector *connector, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint8_t *eld = connector->eld; uint32_t eldv; - uint32_t i; - int len; - int pipe = to_intel_crtc(crtc)->pipe; - int tmp; - + uint32_t tmp; + int len, i; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + enum port port; int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); int aud_config = HSW_AUD_CFG(pipe); @@ -196,28 +195,27 @@ static void haswell_write_eld(struct drm_connector *connector, hdmiw_hdmiedid)) return; - i = I915_READ(aud_cntrl_st2); - i &= ~eldv; - I915_WRITE(aud_cntrl_st2, i); + tmp = I915_READ(aud_cntrl_st2); + tmp &= ~eldv; + I915_WRITE(aud_cntrl_st2, tmp); if (!eld[0]) return; - i = I915_READ(aud_cntl_st); - i &= ~IBX_ELD_ADDRESS; - I915_WRITE(aud_cntl_st, i); - i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ - DRM_DEBUG_DRIVER("port num:%d\n", i); + tmp = I915_READ(aud_cntl_st); + tmp &= ~IBX_ELD_ADDRESS; + I915_WRITE(aud_cntl_st, tmp); + port = (tmp >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ + DRM_DEBUG_DRIVER("port num:%d\n", port); - len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ + len = min_t(int, eld[2], 21); /* 84 bytes of hw ELD buffer */ DRM_DEBUG_DRIVER("ELD size %d\n", len); for (i = 0; i < len; i++) I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - i = I915_READ(aud_cntrl_st2); - i |= eldv; - I915_WRITE(aud_cntrl_st2, i); - + tmp = I915_READ(aud_cntrl_st2); + tmp |= eldv; + I915_WRITE(aud_cntrl_st2, tmp); } static void ironlake_write_eld(struct drm_connector *connector, @@ -228,13 +226,14 @@ static void ironlake_write_eld(struct drm_connector *connector, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint8_t *eld = connector->eld; uint32_t eldv; - uint32_t i; - int len; + uint32_t tmp; + int len, i; int hdmiw_hdmiedid; int aud_config; int aud_cntl_st; int aud_cntrl_st2; - int pipe = to_intel_crtc(crtc)->pipe; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + enum port port; if (HAS_PCH_IBX(connector->dev)) { hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); @@ -261,22 +260,22 @@ static void ironlake_write_eld(struct drm_connector *connector, intel_encoder = intel_attached_encoder(connector); intel_dig_port = enc_to_dig_port(&intel_encoder->base); - i = intel_dig_port->port; + port = intel_dig_port->port; } else { - i = I915_READ(aud_cntl_st); - i = (i >> 29) & DIP_PORT_SEL_MASK; + tmp = I915_READ(aud_cntl_st); + port = (tmp >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ } - if (!i) { + if (!port) { DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); /* operate blindly on all ports */ eldv = IBX_ELD_VALIDB; eldv |= IBX_ELD_VALIDB << 4; eldv |= IBX_ELD_VALIDB << 8; } else { - DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(i)); - eldv = IBX_ELD_VALIDB << ((i - 1) * 4); + DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(port)); + eldv = IBX_ELD_VALIDB << ((port - 1) * 4); } if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { @@ -293,25 +292,25 @@ static void ironlake_write_eld(struct drm_connector *connector, hdmiw_hdmiedid)) return; - i = I915_READ(aud_cntrl_st2); - i &= ~eldv; - I915_WRITE(aud_cntrl_st2, i); + tmp = I915_READ(aud_cntrl_st2); + tmp &= ~eldv; + I915_WRITE(aud_cntrl_st2, tmp); if (!eld[0]) return; - i = I915_READ(aud_cntl_st); - i &= ~IBX_ELD_ADDRESS; - I915_WRITE(aud_cntl_st, i); + tmp = I915_READ(aud_cntl_st); + tmp &= ~IBX_ELD_ADDRESS; + I915_WRITE(aud_cntl_st, tmp); - len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ + len = min_t(int, eld[2], 21); /* 84 bytes of hw ELD buffer */ DRM_DEBUG_DRIVER("ELD size %d\n", len); for (i = 0; i < len; i++) I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - i = I915_READ(aud_cntrl_st2); - i |= eldv; - I915_WRITE(aud_cntrl_st2, i); + tmp = I915_READ(aud_cntrl_st2); + tmp |= eldv; + I915_WRITE(aud_cntrl_st2, tmp); } void intel_write_eld(struct drm_encoder *encoder, -- GitLab From 33d1e7c6f41656b62a0736a9f0eb977f5f1ff88f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:46 +0200 Subject: [PATCH 3022/9457] drm/i915: pass intel_encoder to intel_write_eld Everything else can be derived from that. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 9 +++++---- drivers/gpu/drm/i915/intel_ddi.c | 2 +- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 3 +-- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 00e9bfcd1e8d..829afd5305d1 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -313,10 +313,11 @@ static void ironlake_write_eld(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); } -void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode) +void intel_write_eld(struct intel_encoder *intel_encoder) { - struct drm_crtc *crtc = encoder->crtc; + struct drm_encoder *encoder = &intel_encoder->base; + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); + struct drm_display_mode *mode = &crtc->config.adjusted_mode; struct drm_connector *connector; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -334,7 +335,7 @@ void intel_write_eld(struct drm_encoder *encoder, connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; if (dev_priv->display.write_eld) - dev_priv->display.write_eld(connector, crtc, mode); + dev_priv->display.write_eld(connector, encoder->crtc, mode); } /** diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cb5367c6f95a..2688bc940879 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1126,7 +1126,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) /* write eld */ DRM_DEBUG_DRIVER("DDI audio: write eld information\n"); - intel_write_eld(encoder, &crtc->config.adjusted_mode); + intel_write_eld(intel_encoder); } if (type == INTEL_OUTPUT_EDP) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 64c8e047891d..b474a29d00d5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1250,7 +1250,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder) DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", pipe_name(crtc->pipe)); intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; - intel_write_eld(&encoder->base, adjusted_mode); + intel_write_eld(encoder); } /* Split out the IBX/CPU vs CPT settings */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3bbc4fe817ff..bf72a9201a15 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -850,8 +850,7 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); /* intel_audio.c */ void intel_init_audio(struct drm_device *dev); -void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode); +void intel_write_eld(struct intel_encoder *encoder); /* intel_display.c */ const char *intel_output_name(int output); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 8b5f3aa027f3..07b5ebd65d41 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -666,7 +666,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", pipe_name(crtc->pipe)); hdmi_val |= SDVO_AUDIO_ENABLE; - intel_write_eld(&encoder->base, adjusted_mode); + intel_write_eld(encoder); } if (HAS_PCH_CPT(dev)) -- GitLab From 820d2d77482810702758381808bdbb64595298e2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:47 +0200 Subject: [PATCH 3023/9457] drm/i915/audio: pass intel_encoder on to platform specific ELD functions This will simplify things later on. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_audio.c | 22 ++++++++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 627b7e71f168..6a73803482cb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -434,6 +434,7 @@ struct drm_i915_error_state { }; struct intel_connector; +struct intel_encoder; struct intel_crtc_config; struct intel_plane_config; struct intel_crtc; @@ -483,7 +484,7 @@ struct drm_i915_display_funcs { void (*crtc_disable)(struct drm_crtc *crtc); void (*off)(struct drm_crtc *crtc); void (*write_eld)(struct drm_connector *connector, - struct drm_crtc *crtc, + struct intel_encoder *encoder, struct drm_display_mode *mode); void (*fdi_link_train)(struct drm_crtc *crtc); void (*init_clock_gating)(struct drm_device *dev); @@ -2798,7 +2799,6 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) extern void intel_i2c_reset(struct drm_device *dev); /* intel_opregion.c */ -struct intel_encoder; #ifdef CONFIG_ACPI extern int intel_opregion_setup(struct drm_device *dev); extern void intel_opregion_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 829afd5305d1..4a384d780b20 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -97,7 +97,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector, } static void g4x_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, + struct intel_encoder *encoder, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; @@ -137,16 +137,16 @@ static void g4x_write_eld(struct drm_connector *connector, } static void haswell_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, + struct intel_encoder *encoder, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); uint8_t *eld = connector->eld; uint32_t eldv; uint32_t tmp; int len, i; - enum pipe pipe = to_intel_crtc(crtc)->pipe; + enum pipe pipe = intel_crtc->pipe; enum port port; int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); @@ -160,7 +160,7 @@ static void haswell_write_eld(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); POSTING_READ(aud_cntrl_st2); - assert_pipe_disabled(dev_priv, to_intel_crtc(crtc)->pipe); + assert_pipe_disabled(dev_priv, pipe); /* Set ELD valid state */ tmp = I915_READ(aud_cntrl_st2); @@ -219,11 +219,11 @@ static void haswell_write_eld(struct drm_connector *connector, } static void ironlake_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc, + struct intel_encoder *encoder, struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); uint8_t *eld = connector->eld; uint32_t eldv; uint32_t tmp; @@ -232,7 +232,7 @@ static void ironlake_write_eld(struct drm_connector *connector, int aud_config; int aud_cntl_st; int aud_cntrl_st2; - enum pipe pipe = to_intel_crtc(crtc)->pipe; + enum pipe pipe = intel_crtc->pipe; enum port port; if (HAS_PCH_IBX(connector->dev)) { @@ -255,11 +255,9 @@ static void ironlake_write_eld(struct drm_connector *connector, DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); if (IS_VALLEYVIEW(connector->dev)) { - struct intel_encoder *intel_encoder; struct intel_digital_port *intel_dig_port; - intel_encoder = intel_attached_encoder(connector); - intel_dig_port = enc_to_dig_port(&intel_encoder->base); + intel_dig_port = enc_to_dig_port(&encoder->base); port = intel_dig_port->port; } else { tmp = I915_READ(aud_cntl_st); @@ -335,7 +333,7 @@ void intel_write_eld(struct intel_encoder *intel_encoder) connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; if (dev_priv->display.write_eld) - dev_priv->display.write_eld(connector, encoder->crtc, mode); + dev_priv->display.write_eld(connector, intel_encoder, mode); } /** -- GitLab From 6847d71bfc9b2855fb5fd0517309fb1adf9203ff Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 27 Oct 2014 17:47:52 -0200 Subject: [PATCH 3024/9457] drm/i915: transform INTEL_OUTPUT_* into an enum Because I got annoyed that I had to document what values "int ddi_personality" is supposed to hold. A good side-effect of this change is that now the compilers can do some additional checks on our code, which may prevent some bugs in the future. A bad side-effect of this change is that now the compilers do some additional checks on our code and complain when a switch statement doesn't check for all possible values, so we need to add "default" cases to all those switches. Hopefully, this may help preventing confusions against DRM_MODE_CONNECTOR_* and DRM_MODE_ENCODER_*. I guess that just by looking at the patch, some people will think this change is not worth its benefits. In this case, I don't really mind dropping the patch. Also, there's probably still a few more places where we can s/int/enum intel_output_type/, but we can change that later, when we spot the places. Signed-off-by: Paulo Zanoni [danvet: Resolve conflict due to reordered patches.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ drivers/gpu/drm/i915/intel_display.c | 10 ++++++++++ drivers/gpu/drm/i915/intel_drv.h | 28 +++++++++++++++------------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 61ea8da93c3b..a79f83ce9c84 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2971,6 +2971,8 @@ static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe, break; } break; + default: + break; } } drm_modeset_unlock_all(dev); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aeda09dcfb72..ee982f5412d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6269,6 +6269,8 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, case INTEL_OUTPUT_DSI: is_dsi = true; break; + default: + break; } num_connectors++; @@ -6597,6 +6599,8 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) if (enc_to_dig_port(&encoder->base)->port == PORT_A) has_cpu_edp = true; break; + default: + break; } } @@ -6901,6 +6905,8 @@ static void lpt_init_pch_refclk(struct drm_device *dev) case INTEL_OUTPUT_ANALOG: has_vga = true; break; + default: + break; } } @@ -6934,6 +6940,8 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) case INTEL_OUTPUT_LVDS: is_lvds = true; break; + default: + break; } num_connectors++; } @@ -7188,6 +7196,8 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, case INTEL_OUTPUT_HDMI: is_sdvo = true; break; + default: + break; } num_connectors++; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bf72a9201a15..1e58e64aaecc 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -94,18 +94,20 @@ /* these are outputs from the chip - integrated only external chips are via DVO or SDVO output */ -#define INTEL_OUTPUT_UNUSED 0 -#define INTEL_OUTPUT_ANALOG 1 -#define INTEL_OUTPUT_DVO 2 -#define INTEL_OUTPUT_SDVO 3 -#define INTEL_OUTPUT_LVDS 4 -#define INTEL_OUTPUT_TVOUT 5 -#define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_DISPLAYPORT 7 -#define INTEL_OUTPUT_EDP 8 -#define INTEL_OUTPUT_DSI 9 -#define INTEL_OUTPUT_UNKNOWN 10 -#define INTEL_OUTPUT_DP_MST 11 +enum intel_output_type { + INTEL_OUTPUT_UNUSED = 0, + INTEL_OUTPUT_ANALOG = 1, + INTEL_OUTPUT_DVO = 2, + INTEL_OUTPUT_SDVO = 3, + INTEL_OUTPUT_LVDS = 4, + INTEL_OUTPUT_TVOUT = 5, + INTEL_OUTPUT_HDMI = 6, + INTEL_OUTPUT_DISPLAYPORT = 7, + INTEL_OUTPUT_EDP = 8, + INTEL_OUTPUT_DSI = 9, + INTEL_OUTPUT_UNKNOWN = 10, + INTEL_OUTPUT_DP_MST = 11, +}; #define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_LVDS 1 @@ -136,7 +138,7 @@ struct intel_encoder { */ struct intel_crtc *new_crtc; - int type; + enum intel_output_type type; unsigned int cloneable; bool connectors_active; void (*hot_plug)(struct intel_encoder *); -- GitLab From c17ed5b5a46ec715620b0548a187d3ed98f4cf0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:27 +0300 Subject: [PATCH 3025/9457] drm/i915: Warn if trying to register eDP on port != B/C on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only ports B and C have the power sequencer and backlight controls, so complain if we ever try to register an eDP connector on some other port. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b474a29d00d5..3f1858065a1c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5203,6 +5203,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, if (type == DRM_MODE_CONNECTOR_eDP) intel_encoder->type = INTEL_OUTPUT_EDP; + /* eDP only on port B and/or C on vlv/chv */ + if (WARN_ON(IS_VALLEYVIEW(dev) && is_edp(intel_dp) && + port != PORT_B && port != PORT_C)) + return false; + DRM_DEBUG_KMS("Adding %s connector on port %c\n", type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP", port_name(port)); -- GitLab From 7a66800e035bb6a64c2d0f8cb315edabbef819b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:29 +0300 Subject: [PATCH 3026/9457] drm/i915: Remove high level intel_edp_vdd_{on, off}() from hpd/detect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit want_panel_vdd is a bool so it can't cope with interleaving on/off calls from multiple threads. If we want to make that possible we'd need to convert want_panel_vdd into a proper ref count. But an easier fix is to remove the high level vdd on/off calls from detect/hpd code paths and just rely on the delayed vdd off to avoid needless vdd on<->off ping pong. After this change only the encoder enable/disable paths use the high level functions, which is fine since both the on and off low level edp vdd calls from intel_dp_aux_ch() happen without dropping pps_mutex in between and so want_panel_vdd can't change in between. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3f1858065a1c..9076e9a04f82 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3846,8 +3846,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; - intel_edp_panel_vdd_on(intel_dp); - if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); @@ -3855,8 +3853,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); - - intel_edp_panel_vdd_off(intel_dp, false); } static bool @@ -3870,7 +3866,6 @@ intel_dp_probe_mst(struct intel_dp *intel_dp) if (intel_dp->dpcd[DP_DPCD_REV] < 0x12) return false; - intel_edp_panel_vdd_on(intel_dp); if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) { if (buf[0] & DP_MST_CAP) { DRM_DEBUG_KMS("Sink is MST capable\n"); @@ -3880,7 +3875,6 @@ intel_dp_probe_mst(struct intel_dp *intel_dp) intel_dp->is_mst = false; } } - intel_edp_panel_vdd_off(intel_dp, false); drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); return intel_dp->is_mst; @@ -5086,9 +5080,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_edp_panel_vdd_sanitize(intel_encoder); /* Cache DPCD and EDID for edp. */ - intel_edp_panel_vdd_on(intel_dp); has_dpcd = intel_dp_get_dpcd(intel_dp); - intel_edp_panel_vdd_off(intel_dp, false); if (has_dpcd) { if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) -- GitLab From 36b5f425dd560d37f5633cf317818377c1db70de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:30 +0300 Subject: [PATCH 3027/9457] drm/i915: Store power sequencer delays in intel_dp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The power seqeuncer delays are fixed for a given panel, so we can keep them around once computed. Not that on VLV/CHV we still re-compute them every time we initialize the power seqeuncer registers, but that will change soon enough. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 52 ++++++++++++-------------------- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9076e9a04f82..269403154751 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -283,12 +283,10 @@ intel_hrawclk(struct drm_device *dev) static void intel_dp_init_panel_power_sequencer(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *out); + struct intel_dp *intel_dp); static void intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *out); + struct intel_dp *intel_dp); static void pps_lock(struct intel_dp *intel_dp) { @@ -330,7 +328,6 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *encoder; unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B); - struct edp_power_seq power_seq; lockdep_assert_held(&dev_priv->pps_mutex); @@ -368,9 +365,8 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) port_name(intel_dig_port->port)); /* init power sequencer on this pipe and port */ - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, - &power_seq); + intel_dp_init_panel_power_sequencer(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); return intel_dp->pps_pipe; } @@ -425,7 +421,6 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct edp_power_seq power_seq; enum port port = intel_dig_port->port; lockdep_assert_held(&dev_priv->pps_mutex); @@ -453,9 +448,8 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) DRM_DEBUG_KMS("initial power sequencer for port %c: pipe %c\n", port_name(port), pipe_name(intel_dp->pps_pipe)); - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, - &power_seq); + intel_dp_init_panel_power_sequencer(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); } void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv) @@ -2620,7 +2614,6 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); - struct edp_power_seq power_seq; lockdep_assert_held(&dev_priv->pps_mutex); @@ -2648,9 +2641,8 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) pipe_name(intel_dp->pps_pipe), port_name(intel_dig_port->port)); /* init power sequencer on this pipe and port */ - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, - &power_seq); + intel_dp_init_panel_power_sequencer(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); } static void vlv_pre_enable_dp(struct intel_encoder *encoder) @@ -4731,11 +4723,11 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) static void intel_dp_init_panel_power_sequencer(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *out) + struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dev->dev_private; - struct edp_power_seq cur, vbt, spec, final; + struct edp_power_seq cur, vbt, spec, + *final = &intel_dp->pps_delays; u32 pp_on, pp_off, pp_div, pp; int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg; @@ -4802,7 +4794,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, /* Use the max of the register settings and vbt. If both are * unset, fall back to the spec limits. */ -#define assign_final(field) final.field = (max(cur.field, vbt.field) == 0 ? \ +#define assign_final(field) final->field = (max(cur.field, vbt.field) == 0 ? \ spec.field : \ max(cur.field, vbt.field)) assign_final(t1_t3); @@ -4812,7 +4804,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, assign_final(t11_t12); #undef assign_final -#define get_delay(field) (DIV_ROUND_UP(final.field, 10)) +#define get_delay(field) (DIV_ROUND_UP(final->field, 10)) intel_dp->panel_power_up_delay = get_delay(t1_t3); intel_dp->backlight_on_delay = get_delay(t8); intel_dp->backlight_off_delay = get_delay(t9); @@ -4826,21 +4818,18 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); - - if (out) - *out = final; } static void intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *seq) + struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dev->dev_private; u32 pp_on, pp_off, pp_div, port_sel = 0; int div = HAS_PCH_SPLIT(dev) ? intel_pch_rawclk(dev) : intel_hrawclk(dev); int pp_on_reg, pp_off_reg, pp_div_reg; enum port port = dp_to_dig_port(intel_dp)->port; + const struct edp_power_seq *seq = &intel_dp->pps_delays; lockdep_assert_held(&dev_priv->pps_mutex); @@ -5058,8 +5047,7 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder) } static bool intel_edp_init_connector(struct intel_dp *intel_dp, - struct intel_connector *intel_connector, - struct edp_power_seq *power_seq) + struct intel_connector *intel_connector) { struct drm_connector *connector = &intel_connector->base; struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); @@ -5095,7 +5083,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, /* We now know it's not a ghost, init power sequence regs. */ pps_lock(intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, power_seq); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); pps_unlock(intel_dp); mutex_lock(&dev->mode_config.mutex); @@ -5156,7 +5144,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_dig_port->port; - struct edp_power_seq power_seq = { 0 }; int type; intel_dp->pps_pipe = INVALID_PIPE; @@ -5246,8 +5233,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, vlv_initial_power_sequencer_setup(intel_dp); } else { intel_dp_init_panel_power_timestamps(intel_dp); - intel_dp_init_panel_power_sequencer(dev, intel_dp, - &power_seq); + intel_dp_init_panel_power_sequencer(dev, intel_dp); } pps_unlock(intel_dp); } @@ -5262,7 +5248,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, } } - if (!intel_edp_init_connector(intel_dp, intel_connector, &power_seq)) { + if (!intel_edp_init_connector(intel_dp, intel_connector)) { drm_dp_aux_unregister(&intel_dp->aux); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1e58e64aaecc..b323c9b01c40 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -592,6 +592,7 @@ struct intel_dp { * this port. Only relevant on VLV/CHV. */ enum pipe pps_pipe; + struct edp_power_seq pps_delays; bool use_tps3; bool can_mst; /* this port supports mst */ -- GitLab From 81ddbc69992a1f29aeb2a5b183e5228cc7c49caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:31 +0300 Subject: [PATCH 3028/9457] drm/i915: Don't initialize power seqeuencer delays more than once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we read the current power seqeuncer delays from the registers (as well as looking at the vbt and spec values) we may end up corrupting delays we already initialized when we switch to another pipe and the power seqeuncer there has different values currently in the registers. So make sure we only initialize the delays once even if intel_dp_init_panel_power_sequencer() gets called multiple times. There was some discussion in the review about when exactly we need to unlock the pps. Quoting Bspec: "If this bit is not a zero, it activates the register write protect and writes to those registers will be ignored unless the write protect key value is set in the panel sequencing control register." Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak [danvet: Add Bspec quote per review discussion between Imre and Ville.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 269403154751..e1894cea44cc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4733,6 +4733,10 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, lockdep_assert_held(&dev_priv->pps_mutex); + /* already initialized? */ + if (final->t11_t12 != 0) + return; + if (HAS_PCH_SPLIT(dev)) { pp_ctrl_reg = PCH_PP_CONTROL; pp_on_reg = PCH_PP_ON_DELAYS; -- GitLab From 9f0fb5bec73e4afd84d4dec040a9d54a971620ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:32 +0300 Subject: [PATCH 3029/9457] drm/i915: Split power sequencer panel on/off functions to locked and unlocked variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll be needing to the call the power seqeuencer functions while already holding pps_mutex, so split the locking out to small wrapper functions. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e1894cea44cc..c97bb5c8c62a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1555,23 +1555,23 @@ static void intel_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) pps_unlock(intel_dp); } -void intel_edp_panel_on(struct intel_dp *intel_dp) +static void edp_panel_on(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; u32 pp; u32 pp_ctrl_reg; + lockdep_assert_held(&dev_priv->pps_mutex); + if (!is_edp(intel_dp)) return; DRM_DEBUG_KMS("Turn eDP power on\n"); - pps_lock(intel_dp); - if (edp_have_panel_power(intel_dp)) { DRM_DEBUG_KMS("eDP power already on\n"); - goto out; + return; } wait_panel_power_cycle(intel_dp); @@ -1600,12 +1600,20 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg); } +} - out: +void intel_edp_panel_on(struct intel_dp *intel_dp) +{ + if (!is_edp(intel_dp)) + return; + + pps_lock(intel_dp); + edp_panel_on(intel_dp); pps_unlock(intel_dp); } -void intel_edp_panel_off(struct intel_dp *intel_dp) + +static void edp_panel_off(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -1615,13 +1623,13 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) u32 pp; u32 pp_ctrl_reg; + lockdep_assert_held(&dev_priv->pps_mutex); + if (!is_edp(intel_dp)) return; DRM_DEBUG_KMS("Turn eDP power off\n"); - pps_lock(intel_dp); - WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); pp = ironlake_get_pp_control(intel_dp); @@ -1643,7 +1651,15 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) /* We got a reference when we enabled the VDD. */ power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_put(dev_priv, power_domain); +} +void intel_edp_panel_off(struct intel_dp *intel_dp) +{ + if (!is_edp(intel_dp)) + return; + + pps_lock(intel_dp); + edp_panel_off(intel_dp); pps_unlock(intel_dp); } -- GitLab From 093e3f134e2eff13503f708b81aecc2501e7aecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:33 +0300 Subject: [PATCH 3030/9457] drm/i915: Hold the pps mutex across the whole panel power enable sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just grab the pps_mutex once and do all the pps panel startup operations while holding the mutex instead of grabbing the mutex separately for each individual step. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 47 +++++++++++---------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c97bb5c8c62a..cad4e112cfaa 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -113,6 +113,7 @@ static struct intel_dp *intel_attached_dp(struct drm_connector *connector) static void intel_dp_link_down(struct intel_dp *intel_dp); static bool edp_panel_vdd_on(struct intel_dp *intel_dp); static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); +static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); int intel_dp_max_link_bw(struct intel_dp *intel_dp) @@ -1539,22 +1540,6 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) edp_panel_vdd_schedule_off(intel_dp); } -/* - * Must be paired with intel_edp_panel_vdd_on(). - * Nested calls to these functions are not allowed since - * we drop the lock. Caller must use some higher level - * locking to prevent nested calls from other threads. - */ -static void intel_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) -{ - if (!is_edp(intel_dp)) - return; - - pps_lock(intel_dp); - edp_panel_vdd_off(intel_dp, sync); - pps_unlock(intel_dp); -} - static void edp_panel_on(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -2552,10 +2537,19 @@ static void intel_enable_dp(struct intel_encoder *encoder) if (WARN_ON(dp_reg & DP_PORT_EN)) return; + pps_lock(intel_dp); + + if (IS_VALLEYVIEW(dev)) + vlv_init_panel_power_sequencer(intel_dp); + intel_dp_enable_port(intel_dp); - intel_edp_panel_vdd_on(intel_dp); - intel_edp_panel_on(intel_dp); - intel_edp_panel_vdd_off(intel_dp, true); + + edp_panel_vdd_on(intel_dp); + edp_panel_on(intel_dp); + edp_panel_vdd_off(intel_dp, true); + + pps_unlock(intel_dp); + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); @@ -2633,6 +2627,9 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) lockdep_assert_held(&dev_priv->pps_mutex); + if (!is_edp(intel_dp)) + return; + if (intel_dp->pps_pipe == crtc->pipe) return; @@ -2687,12 +2684,6 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); - if (is_edp(intel_dp)) { - pps_lock(intel_dp); - vlv_init_panel_power_sequencer(intel_dp); - pps_unlock(intel_dp); - } - intel_enable_dp(encoder); vlv_wait_port_ready(dev_priv, dport); @@ -2787,12 +2778,6 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); - if (is_edp(intel_dp)) { - pps_lock(intel_dp); - vlv_init_panel_power_sequencer(intel_dp); - pps_unlock(intel_dp); - } - intel_enable_dp(encoder); vlv_wait_port_ready(dev_priv, dport); -- GitLab From 61234fa5e5232c35f87d44d9d596af4b10eac255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:34 +0300 Subject: [PATCH 3031/9457] drm/i915: Wait for PHY port ready before link training on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no point in checking if the data lanes came out of reset after link training. If the data lanes aren't ready link training will fail anyway. Suggested-by: Todd Previte Cc: Todd Previte Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Acked-by: Todd Previte Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cad4e112cfaa..f3b6cd5057ea 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2550,6 +2550,9 @@ static void intel_enable_dp(struct intel_encoder *encoder) pps_unlock(intel_dp); + if (IS_VALLEYVIEW(dev)) + vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp)); + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); @@ -2685,8 +2688,6 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); intel_enable_dp(encoder); - - vlv_wait_port_ready(dev_priv, dport); } static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder) @@ -2779,8 +2780,6 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); intel_enable_dp(encoder); - - vlv_wait_port_ready(dev_priv, dport); } static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) -- GitLab From 7b713f50d78b68c04c86eb21e59faf7247aa2cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:35 +0300 Subject: [PATCH 3032/9457] drm/i915: Fix eDP link training when switching pipes on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When switching from one pipe to another, the power sequencer of the new pipe seems to need a bit of kicking to lock into the port. Even the vdd force bit doesn't work before the power sequencer has been sufficiently kicked, so this must be done before any AUX transactions are attempted. After extensive experimentation I've determined that it's sufficient to first write the port register with the correct values except the port must remain disabled, then we can do a second write to enable the port, after which the power sequencer is operational and allows the port to start up properly. Contrary to my earlier theories we don't need to enable the port with the idle pattern, so let's just use training pattern 1 as that's what other platforms use here. v2: Refine the kick procedure Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f3b6cd5057ea..823355705a5e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2517,14 +2517,23 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - intel_dp->DP |= DP_PORT_EN; - /* enable with pattern 1 (as per spec) */ _intel_dp_set_link_train(intel_dp, &intel_dp->DP, DP_TRAINING_PATTERN_1); I915_WRITE(intel_dp->output_reg, intel_dp->DP); POSTING_READ(intel_dp->output_reg); + + /* + * Magic for VLV/CHV. We _must_ first set up the register + * without actually enabling the port, and then do another + * write to enable the port. Otherwise link training will + * fail when the power sequencer is freshly used for this port. + */ + intel_dp->DP |= DP_PORT_EN; + + I915_WRITE(intel_dp->output_reg, intel_dp->DP); + POSTING_READ(intel_dp->output_reg); } static void intel_enable_dp(struct intel_encoder *encoder) -- GitLab From 961a0db00977ff98ff99d942ae4c046423e1aebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:29:42 +0300 Subject: [PATCH 3033/9457] drm/i915: Kick the power sequencer before AUX transactions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we pick a new power sequencer for the port but we're not doing a full modeset, the power sequencer may have locked on to another port (or no port). So kick it a bit to make sure it controls the port we want. Again just like when we attempt to actually enable the DP port, we must first write the port register with the approriate value except the enable bit, and then we must enable the port to make the power sequencer happy. In this case since we don't want the port actually enabled we just toggle it on and immediately back off. Going forward the power sequencer will keep working on that specific port until again moved to another port. v2: Refine the kick procedure Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 823355705a5e..4f7df371c098 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -321,6 +321,52 @@ static void pps_unlock(struct intel_dp *intel_dp) intel_display_power_put(dev_priv, power_domain); } +static void +vlv_power_sequencer_kick(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_dp->pps_pipe; + uint32_t DP; + + if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN, + "skipping pipe %c power seqeuncer kick due to port %c being active\n", + pipe_name(pipe), port_name(intel_dig_port->port))) + return; + + DRM_DEBUG_KMS("kicking pipe %c power sequencer for port %c\n", + pipe_name(pipe), port_name(intel_dig_port->port)); + + /* Preserve the BIOS-computed detected bit. This is + * supposed to be read-only. + */ + DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; + DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; + DP |= DP_PORT_WIDTH(1); + DP |= DP_LINK_TRAIN_PAT_1; + + if (IS_CHERRYVIEW(dev)) + DP |= DP_PIPE_SELECT_CHV(pipe); + else if (pipe == PIPE_B) + DP |= DP_PIPEB_SELECT; + + /* + * Similar magic as in intel_dp_enable_port(). + * We _must_ do this port enable + disable trick + * to make this power seqeuencer lock onto the port. + * Otherwise even VDD force bit won't work. + */ + I915_WRITE(intel_dp->output_reg, DP); + POSTING_READ(intel_dp->output_reg); + + I915_WRITE(intel_dp->output_reg, DP | DP_PORT_EN); + POSTING_READ(intel_dp->output_reg); + + I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); + POSTING_READ(intel_dp->output_reg); +} + static enum pipe vlv_power_sequencer_pipe(struct intel_dp *intel_dp) { @@ -369,6 +415,12 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) intel_dp_init_panel_power_sequencer(dev, intel_dp); intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + /* + * Even vdd force doesn't work until we've made + * the power sequencer lock in on the port. + */ + vlv_power_sequencer_kick(intel_dp); + return intel_dp->pps_pipe; } -- GitLab From 9a42356b964dee6418d8b812109298658cc8dc38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:29:48 +0300 Subject: [PATCH 3034/9457] drm/i915: Don't kick the power seqeuncer just to check if we have vdd/panel power MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there's no power sequencer assigned to the port currently we can't very well have vdd or panel power enabled either. If we would try to check that from the pps registers we'd need to pick a power seqeuncer and kick it. So let's skip the register read and the kick. Note that there's still a bit an issue about correctly recovering pps state from resume if the bios is nasty: With this check we'll always assume that the pps is off. But that's better done in a follow-up patch and it shouldn't be too harmful - at most we waste time enabling the pps if it's on already. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak [danvet: Add note about resume issues Imre spotted.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4f7df371c098..451dd253b5d6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -597,6 +597,10 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp) lockdep_assert_held(&dev_priv->pps_mutex); + if (IS_VALLEYVIEW(dev) && + intel_dp->pps_pipe == INVALID_PIPE) + return false; + return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0; } @@ -607,6 +611,10 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp) lockdep_assert_held(&dev_priv->pps_mutex); + if (IS_VALLEYVIEW(dev) && + intel_dp->pps_pipe == INVALID_PIPE) + return false; + return I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD; } -- GitLab From 83b8459756659ce55446e3eb97d64b966c60bfb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:29:51 +0300 Subject: [PATCH 3035/9457] drm/i915: Clear PPS port select when giving up the power sequencer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VLV gets confused if two power sequencers have the same port selected. It would seem the port doesn't start up properly in the is case and vlv_wait_port_ready() will fail as will the link training. Clearing the port select in the PP_ON_DELAYS register fixes this problem. CHV doesn't seem to need this, but it doesn't seem to hurt either so let's just do it for both to keep the code between the platforms as uniform as possible. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 451dd253b5d6..04d7bc730995 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2657,6 +2657,32 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder) } } +static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_i915_private *dev_priv = intel_dig_port->base.base.dev->dev_private; + enum pipe pipe = intel_dp->pps_pipe; + int pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe); + + edp_panel_vdd_off_sync(intel_dp); + + /* + * VLV seems to get confused when multiple power seqeuencers + * have the same port selected (even if only one has power/vdd + * enabled). The failure manifests as vlv_wait_port_ready() failing + * CHV on the other hand doesn't seem to mind having the same port + * selected in multiple power seqeuencers, but let's clear the + * port select always when logically disconnecting a power sequencer + * from a port. + */ + DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n", + pipe_name(pipe), port_name(intel_dig_port->port)); + I915_WRITE(pp_on_reg, 0); + POSTING_READ(pp_on_reg); + + intel_dp->pps_pipe = INVALID_PIPE; +} + static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe) { @@ -2683,9 +2709,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, pipe_name(pipe), port_name(port)); /* make sure vdd is off before we steal it */ - edp_panel_vdd_off_sync(intel_dp); - - intel_dp->pps_pipe = INVALID_PIPE; + vlv_detach_power_sequencer(intel_dp); } } @@ -2711,7 +2735,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) * we still have control of it. */ if (intel_dp->pps_pipe != INVALID_PIPE) - edp_panel_vdd_off_sync(intel_dp); + vlv_detach_power_sequencer(intel_dp); /* * We may be stealing the power -- GitLab From ac3c12e4e5a31b75b2621f8f23336bebbe3dbff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:29:56 +0300 Subject: [PATCH 3036/9457] drm/i915: Warn if stealing non pipe A/B power sequencer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no power sequencer on pipe C on VLV/CHV so scream a bit if we try to steal one from pipes other than A and B. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 04d7bc730995..7df024c63bff 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2691,6 +2691,9 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, lockdep_assert_held(&dev_priv->pps_mutex); + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { struct intel_dp *intel_dp; -- GitLab From a8c3344e069e9c483b1fd328e14fbc6235073649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:29:59 +0300 Subject: [PATCH 3037/9457] drm/i915: Steal power sequencer in vlv_power_sequencer_pipe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case we fumble something and end up picking an already used power seqeuencer in vlv_power_sequencer_pipe() at least try to steal it gracefully. In theory this should never happen though. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7df024c63bff..1900c4d48376 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -114,6 +114,8 @@ static void intel_dp_link_down(struct intel_dp *intel_dp); static bool edp_panel_vdd_on(struct intel_dp *intel_dp); static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); +static void vlv_steal_power_sequencer(struct drm_device *dev, + enum pipe pipe); int intel_dp_max_link_bw(struct intel_dp *intel_dp) @@ -375,9 +377,13 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *encoder; unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B); + enum pipe pipe; lockdep_assert_held(&dev_priv->pps_mutex); + /* We should never land here with regular DP ports */ + WARN_ON(!is_edp(intel_dp)); + if (intel_dp->pps_pipe != INVALID_PIPE) return intel_dp->pps_pipe; @@ -403,9 +409,12 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) * are two power sequencers and up to two eDP ports. */ if (WARN_ON(pipes == 0)) - return PIPE_A; + pipe = PIPE_A; + else + pipe = ffs(pipes) - 1; - intel_dp->pps_pipe = ffs(pipes) - 1; + vlv_steal_power_sequencer(dev, pipe); + intel_dp->pps_pipe = pipe; DRM_DEBUG_KMS("picked pipe %c power sequencer for port %c\n", pipe_name(intel_dp->pps_pipe), -- GitLab From 3936fcf453af4de87303f42bb34ef5e3eb13c139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:30:02 +0300 Subject: [PATCH 3038/9457] drm/i915: Improve VDD/PPS debugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print the port name in the VDD/PPS debugs messages. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1900c4d48376..21fb42241b2f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1473,7 +1473,8 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - DRM_DEBUG_KMS("Turning eDP VDD on\n"); + DRM_DEBUG_KMS("Turning eDP port %c VDD on\n", + port_name(intel_dig_port->port)); if (!edp_have_panel_power(intel_dp)) wait_panel_power_cycle(intel_dp); @@ -1492,7 +1493,8 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) * If the panel wasn't on, delay before accessing aux channel */ if (!edp_have_panel_power(intel_dp)) { - DRM_DEBUG_KMS("eDP was not running\n"); + DRM_DEBUG_KMS("eDP port %c panel power wasn't enabled\n", + port_name(intel_dig_port->port)); msleep(intel_dp->panel_power_up_delay); } @@ -1517,7 +1519,8 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp) vdd = edp_panel_vdd_on(intel_dp); pps_unlock(intel_dp); - WARN(!vdd, "eDP VDD already requested on\n"); + WARN(!vdd, "eDP port %c VDD already requested on\n", + port_name(dp_to_dig_port(intel_dp)->port)); } static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) @@ -1538,7 +1541,8 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) if (!edp_have_panel_vdd(intel_dp)) return; - DRM_DEBUG_KMS("Turning eDP VDD off\n"); + DRM_DEBUG_KMS("Turning eDP port %c VDD off\n", + port_name(intel_dig_port->port)); pp = ironlake_get_pp_control(intel_dp); pp &= ~EDP_FORCE_VDD; @@ -1599,7 +1603,8 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) if (!is_edp(intel_dp)) return; - WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); + WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on", + port_name(dp_to_dig_port(intel_dp)->port)); intel_dp->want_panel_vdd = false; @@ -1621,7 +1626,8 @@ static void edp_panel_on(struct intel_dp *intel_dp) if (!is_edp(intel_dp)) return; - DRM_DEBUG_KMS("Turn eDP power on\n"); + DRM_DEBUG_KMS("Turn eDP port %c panel power on\n", + port_name(dp_to_dig_port(intel_dp)->port)); if (edp_have_panel_power(intel_dp)) { DRM_DEBUG_KMS("eDP power already on\n"); @@ -1682,9 +1688,11 @@ static void edp_panel_off(struct intel_dp *intel_dp) if (!is_edp(intel_dp)) return; - DRM_DEBUG_KMS("Turn eDP power off\n"); + DRM_DEBUG_KMS("Turn eDP port %c panel power off\n", + port_name(dp_to_dig_port(intel_dp)->port)); - WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); + WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n", + port_name(dp_to_dig_port(intel_dp)->port)); pp = ironlake_get_pp_control(intel_dp); /* We need to switch off panel power _and_ force vdd, for otherwise some -- GitLab From e7a89acea863ffdffa66f4c6cda272eebd893c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:30:07 +0300 Subject: [PATCH 3039/9457] drm/i915: Warn if panel power is already on when enabling it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should never enable the panel power twice. That would indicate a bug somewhere else as we would need to enable the port twice without disabling it in between. Also print the port name. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 21fb42241b2f..9db977b475f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1629,10 +1629,10 @@ static void edp_panel_on(struct intel_dp *intel_dp) DRM_DEBUG_KMS("Turn eDP port %c panel power on\n", port_name(dp_to_dig_port(intel_dp)->port)); - if (edp_have_panel_power(intel_dp)) { - DRM_DEBUG_KMS("eDP power already on\n"); + if (WARN(edp_have_panel_power(intel_dp), + "eDP port %c panel power already on\n", + port_name(dp_to_dig_port(intel_dp)->port))) return; - } wait_panel_power_cycle(intel_dp); -- GitLab From 034e43c6c0dc7e70a6edc96987758237cb92f0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 21:27:28 +0300 Subject: [PATCH 3040/9457] drm/i915: Warn if stealing power sequencer from an active eDP port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eDP ports need the power seqeuncer whenever the port is active. Warn if we accidentally steal the power sequener from an active eDP port. This should not happen unless there's a bug somewhere else, but it's best to scream loudly if it happens to help with debugging. Note that this only checks for active pipes and not for enabled pipes which are turned off with dpms. Which means we might run the risk that the pps might get stolen and we can't reacquire one when enabling the pipe again with dpms on. But on current platforms that's impossible since we only support two edp ports with just two panel power sequencers. So a more elaborate scheme which reserves the pps even when the pipe is inactive isn't required. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak [danvet: Summarize my discussion with Ville about dpms on/off issues.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9db977b475f8..90d752d5d6ea 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2728,6 +2728,10 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n", pipe_name(pipe), port_name(port)); + WARN(encoder->connectors_active, + "stealing pipe %c power sequencer from active eDP port %c\n", + pipe_name(pipe), port_name(port)); + /* make sure vdd is off before we steal it */ vlv_detach_power_sequencer(intel_dp); } -- GitLab From d288f65fe9472501929eb8d63c2b248813b92056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 28 Oct 2014 13:20:22 +0200 Subject: [PATCH 3041/9457] drm/i915: Make sure DPLL is enabled when kicking the power sequencer on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The power seqeuencer kick procedure requires the DPLL to be running in order to complete successfully. In case the DPLL isn't currently running when we need to kick the power seqeuncer enable it temporarily. This can happen eg. during ->detect() when the pipe is not already active. To avoid needlessly duplicating the DPLL programming re-use the already existing functions by passing a temporary pipe config to them instead of having them consult the current pipe config at crtc->config. v2: Introduce vlv_force_pll_{on,off}() (Daniel) v3: Rebase due to drm_crtc vs. intel_crtc changes Fix a typo in commit msg (checkpatch) Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak (v1) [danvet: Appease checkpatch.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 131 +++++++++++++++++++-------- drivers/gpu/drm/i915/intel_dp.c | 14 +++ drivers/gpu/drm/i915/intel_drv.h | 4 + 3 files changed, 111 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee982f5412d6..848f330a931f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -94,8 +94,10 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, static void ironlake_set_pipeconf(struct drm_crtc *crtc); static void haswell_set_pipeconf(struct drm_crtc *crtc); static void intel_set_pipe_csc(struct drm_crtc *crtc); -static void vlv_prepare_pll(struct intel_crtc *crtc); -static void chv_prepare_pll(struct intel_crtc *crtc); +static void vlv_prepare_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config); +static void chv_prepare_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config); static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe) { @@ -1484,12 +1486,13 @@ static void intel_init_dpio(struct drm_device *dev) } } -static void vlv_enable_pll(struct intel_crtc *crtc) +static void vlv_enable_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int reg = DPLL(crtc->pipe); - u32 dpll = crtc->config.dpll_hw_state.dpll; + u32 dpll = pipe_config->dpll_hw_state.dpll; assert_pipe_disabled(dev_priv, crtc->pipe); @@ -1507,7 +1510,7 @@ static void vlv_enable_pll(struct intel_crtc *crtc) if (wait_for(((I915_READ(reg) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) DRM_ERROR("DPLL %d failed to lock\n", crtc->pipe); - I915_WRITE(DPLL_MD(crtc->pipe), crtc->config.dpll_hw_state.dpll_md); + I915_WRITE(DPLL_MD(crtc->pipe), pipe_config->dpll_hw_state.dpll_md); POSTING_READ(DPLL_MD(crtc->pipe)); /* We do this three times for luck */ @@ -1522,7 +1525,8 @@ static void vlv_enable_pll(struct intel_crtc *crtc) udelay(150); /* wait for warmup */ } -static void chv_enable_pll(struct intel_crtc *crtc) +static void chv_enable_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1547,14 +1551,14 @@ static void chv_enable_pll(struct intel_crtc *crtc) udelay(1); /* Enable PLL */ - I915_WRITE(DPLL(pipe), crtc->config.dpll_hw_state.dpll); + I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll); /* Check PLL is locked */ if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) DRM_ERROR("PLL %d failed to lock\n", pipe); /* not sure when this should be written */ - I915_WRITE(DPLL_MD(pipe), crtc->config.dpll_hw_state.dpll_md); + I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); POSTING_READ(DPLL_MD(pipe)); mutex_unlock(&dev_priv->dpio_lock); @@ -4842,9 +4846,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (!is_dsi) { if (IS_CHERRYVIEW(dev)) - chv_prepare_pll(intel_crtc); + chv_prepare_pll(intel_crtc, &intel_crtc->config); else - vlv_prepare_pll(intel_crtc); + vlv_prepare_pll(intel_crtc, &intel_crtc->config); } if (intel_crtc->config.has_dp_encoder) @@ -4864,9 +4868,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (!is_dsi) { if (IS_CHERRYVIEW(dev)) - chv_enable_pll(intel_crtc); + chv_enable_pll(intel_crtc, &intel_crtc->config); else - vlv_enable_pll(intel_crtc); + vlv_enable_pll(intel_crtc, &intel_crtc->config); } for_each_encoder_on_crtc(dev, crtc, encoder) @@ -5747,7 +5751,8 @@ void intel_dp_set_m_n(struct intel_crtc *crtc) &crtc->config.dp_m2_n2); } -static void vlv_update_pll(struct intel_crtc *crtc) +static void vlv_update_pll(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) { u32 dpll, dpll_md; @@ -5762,14 +5767,15 @@ static void vlv_update_pll(struct intel_crtc *crtc) if (crtc->pipe == PIPE_B) dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; dpll |= DPLL_VCO_ENABLE; - crtc->config.dpll_hw_state.dpll = dpll; + pipe_config->dpll_hw_state.dpll = dpll; - dpll_md = (crtc->config.pixel_multiplier - 1) + dpll_md = (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; - crtc->config.dpll_hw_state.dpll_md = dpll_md; + pipe_config->dpll_hw_state.dpll_md = dpll_md; } -static void vlv_prepare_pll(struct intel_crtc *crtc) +static void vlv_prepare_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -5780,11 +5786,11 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) mutex_lock(&dev_priv->dpio_lock); - bestn = crtc->config.dpll.n; - bestm1 = crtc->config.dpll.m1; - bestm2 = crtc->config.dpll.m2; - bestp1 = crtc->config.dpll.p1; - bestp2 = crtc->config.dpll.p2; + bestn = pipe_config->dpll.n; + bestm1 = pipe_config->dpll.m1; + bestm2 = pipe_config->dpll.m2; + bestp1 = pipe_config->dpll.p1; + bestp2 = pipe_config->dpll.p2; /* See eDP HDMI DPIO driver vbios notes doc */ @@ -5821,7 +5827,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv); /* Set HBR and RBR LPF coefficients */ - if (crtc->config.port_clock == 162000 || + if (pipe_config->port_clock == 162000 || intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG) || intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), @@ -5860,19 +5866,21 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) mutex_unlock(&dev_priv->dpio_lock); } -static void chv_update_pll(struct intel_crtc *crtc) +static void chv_update_pll(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) { - crtc->config.dpll_hw_state.dpll = DPLL_SSC_REF_CLOCK_CHV | + pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS | DPLL_VCO_ENABLE; if (crtc->pipe != PIPE_A) - crtc->config.dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; + pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; - crtc->config.dpll_hw_state.dpll_md = - (crtc->config.pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; + pipe_config->dpll_hw_state.dpll_md = + (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } -static void chv_prepare_pll(struct intel_crtc *crtc) +static void chv_prepare_pll(struct intel_crtc *crtc, + const struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -5883,18 +5891,18 @@ static void chv_prepare_pll(struct intel_crtc *crtc) u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac; int refclk; - bestn = crtc->config.dpll.n; - bestm2_frac = crtc->config.dpll.m2 & 0x3fffff; - bestm1 = crtc->config.dpll.m1; - bestm2 = crtc->config.dpll.m2 >> 22; - bestp1 = crtc->config.dpll.p1; - bestp2 = crtc->config.dpll.p2; + bestn = pipe_config->dpll.n; + bestm2_frac = pipe_config->dpll.m2 & 0x3fffff; + bestm1 = pipe_config->dpll.m1; + bestm2 = pipe_config->dpll.m2 >> 22; + bestp1 = pipe_config->dpll.p1; + bestp2 = pipe_config->dpll.p2; /* * Enable Refclk and SSC */ I915_WRITE(dpll_reg, - crtc->config.dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); + pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); mutex_lock(&dev_priv->dpio_lock); @@ -5942,6 +5950,53 @@ static void chv_prepare_pll(struct intel_crtc *crtc) mutex_unlock(&dev_priv->dpio_lock); } +/** + * vlv_force_pll_on - forcibly enable just the PLL + * @dev_priv: i915 private structure + * @pipe: pipe PLL to enable + * @dpll: PLL configuration + * + * Enable the PLL for @pipe using the supplied @dpll config. To be used + * in cases where we need the PLL enabled even when @pipe is not going to + * be enabled. + */ +void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, + const struct dpll *dpll) +{ + struct intel_crtc *crtc = + to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); + struct intel_crtc_config pipe_config = { + .pixel_multiplier = 1, + .dpll = *dpll, + }; + + if (IS_CHERRYVIEW(dev)) { + chv_update_pll(crtc, &pipe_config); + chv_prepare_pll(crtc, &pipe_config); + chv_enable_pll(crtc, &pipe_config); + } else { + vlv_update_pll(crtc, &pipe_config); + vlv_prepare_pll(crtc, &pipe_config); + vlv_enable_pll(crtc, &pipe_config); + } +} + +/** + * vlv_force_pll_off - forcibly disable just the PLL + * @dev_priv: i915 private structure + * @pipe: pipe PLL to disable + * + * Disable the PLL for @pipe. To be used in cases where we need + * the PLL enabled even when @pipe is not going to be enabled. + */ +void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe) +{ + if (IS_CHERRYVIEW(dev)) + chv_disable_pll(to_i915(dev), pipe); + else + vlv_disable_pll(to_i915(dev), pipe); +} + static void i9xx_update_pll(struct intel_crtc *crtc, intel_clock_t *reduced_clock, int num_connectors) @@ -6323,9 +6378,9 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, has_reduced_clock ? &reduced_clock : NULL, num_connectors); } else if (IS_CHERRYVIEW(dev)) { - chv_update_pll(crtc); + chv_update_pll(crtc, &crtc->config); } else if (IS_VALLEYVIEW(dev)) { - vlv_update_pll(crtc); + vlv_update_pll(crtc, &crtc->config); } else { i9xx_update_pll(crtc, has_reduced_clock ? &reduced_clock : NULL, diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 90d752d5d6ea..ccc690e2e906 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -330,6 +330,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; enum pipe pipe = intel_dp->pps_pipe; + bool pll_enabled; uint32_t DP; if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN, @@ -353,6 +354,16 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) else if (pipe == PIPE_B) DP |= DP_PIPEB_SELECT; + pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE; + + /* + * The DPLL for the pipe must be enabled for this to work. + * So enable temporarily it if it's not already enabled. + */ + if (!pll_enabled) + vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ? + &chv_dpll[0].dpll : &vlv_dpll[0].dpll); + /* * Similar magic as in intel_dp_enable_port(). * We _must_ do this port enable + disable trick @@ -367,6 +378,9 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); POSTING_READ(intel_dp->output_reg); + + if (!pll_enabled) + vlv_force_pll_off(dev, pipe); } static enum pipe diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b323c9b01c40..d53ac23cb127 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -918,6 +918,10 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc); void intel_put_shared_dpll(struct intel_crtc *crtc); +void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, + const struct dpll *dpll); +void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe); + /* modesetting asserts */ void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe); -- GitLab From 14af293f060cbf2a508463b01dc4e124bd3c6e15 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 14:51:31 +0100 Subject: [PATCH 3042/9457] drm/i915: create a prepare step for primary planes updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take out the pin_fb code so commit phase can't fail anymore. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 848f330a931f..d678bc0c8184 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11403,20 +11403,16 @@ intel_check_primary_plane(struct drm_plane *plane, } static int -intel_commit_primary_plane(struct drm_plane *plane, - struct intel_plane_state *state) +intel_prepare_primary_plane(struct drm_plane *plane, + struct intel_plane_state *state) { struct drm_crtc *crtc = state->crtc; struct drm_framebuffer *fb = state->fb; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; - struct drm_framebuffer *old_fb = plane->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); - struct intel_plane *intel_plane = to_intel_plane(plane); - struct drm_rect *src = &state->src; int ret; intel_crtc_wait_for_pending_flips(crtc); @@ -11426,7 +11422,7 @@ intel_commit_primary_plane(struct drm_plane *plane, return -EBUSY; } - if (plane->fb != fb) { + if (old_obj != obj) { mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); if (ret == 0) @@ -11439,6 +11435,25 @@ intel_commit_primary_plane(struct drm_plane *plane, } } + return 0; +} + +static void +intel_commit_primary_plane(struct drm_plane *plane, + struct intel_plane_state *state) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *old_fb = plane->fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); + struct intel_plane *intel_plane = to_intel_plane(plane); + struct drm_rect *src = &state->src; + crtc->primary->fb = fb; crtc->x = src->x1; crtc->y = src->y1; @@ -11515,8 +11530,6 @@ intel_commit_primary_plane(struct drm_plane *plane, intel_unpin_fb_obj(old_obj); mutex_unlock(&dev->struct_mutex); } - - return 0; } static int @@ -11557,6 +11570,10 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; + ret = intel_prepare_primary_plane(plane, &state); + if (ret) + return ret; + intel_commit_primary_plane(plane, &state); return 0; -- GitLab From 34aa50a976c58697ad4050674b272892efea865c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 14:51:32 +0100 Subject: [PATCH 3043/9457] drm/i915: create a prepare phase for sprite plane updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit take out pin_fb code so the commit phase can't fail anymore. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 63 ++++++++++++++++++----------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2c060addea29..3631b0ef4d2e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1192,34 +1192,18 @@ intel_check_sprite_plane(struct drm_plane *plane, } static int -intel_commit_sprite_plane(struct drm_plane *plane, - struct intel_plane_state *state) +intel_prepare_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *state) { struct drm_device *dev = plane->dev; struct drm_crtc *crtc = state->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_plane *intel_plane = to_intel_plane(plane); enum pipe pipe = intel_crtc->pipe; struct drm_framebuffer *fb = state->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct drm_i915_gem_object *old_obj = intel_plane->obj; - int crtc_x, crtc_y; - unsigned int crtc_w, crtc_h; - uint32_t src_x, src_y, src_w, src_h; - struct drm_rect *dst = &state->dst; - const struct drm_rect *clip = &state->clip; - bool primary_enabled; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); int ret; - /* - * If the sprite is completely covering the primary plane, - * we can disable the primary and save power. - */ - primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); - WARN_ON(!primary_enabled && !state->visible && intel_crtc->active); - - if (old_obj != obj) { mutex_lock(&dev->struct_mutex); @@ -1238,6 +1222,36 @@ intel_commit_sprite_plane(struct drm_plane *plane, return ret; } + return 0; +} + +static void +intel_commit_sprite_plane(struct drm_plane *plane, + struct intel_plane_state *state) +{ + struct drm_device *dev = plane->dev; + struct drm_crtc *crtc = state->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane *intel_plane = to_intel_plane(plane); + enum pipe pipe = intel_crtc->pipe; + struct drm_framebuffer *fb = state->fb; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj = intel_fb->obj; + struct drm_i915_gem_object *old_obj = intel_plane->obj; + int crtc_x, crtc_y; + unsigned int crtc_w, crtc_h; + uint32_t src_x, src_y, src_w, src_h; + struct drm_rect *dst = &state->dst; + const struct drm_rect *clip = &state->clip; + bool primary_enabled; + + /* + * If the sprite is completely covering the primary plane, + * we can disable the primary and save power. + */ + primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); + WARN_ON(!primary_enabled && !state->visible && intel_crtc->active); + intel_plane->crtc_x = state->orig_dst.x1; intel_plane->crtc_y = state->orig_dst.y1; intel_plane->crtc_w = drm_rect_width(&state->orig_dst); @@ -1298,8 +1312,6 @@ intel_commit_sprite_plane(struct drm_plane *plane, intel_unpin_fb_obj(old_obj); mutex_unlock(&dev->struct_mutex); } - - return 0; } static int @@ -1339,7 +1351,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret) return ret; - return intel_commit_sprite_plane(plane, &state); + ret = intel_prepare_sprite_plane(plane, &state); + if (ret) + return ret; + + intel_commit_sprite_plane(plane, &state); + return 0; } static int -- GitLab From 77cde95217484e845743818691df026cec2534f4 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 24 Oct 2014 14:51:33 +0100 Subject: [PATCH 3044/9457] drm/i915: use intel_fb_obj() macros to assign gem objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the macros makes the code cleaner and it also checks for a NULL fb. Signed-off-by: Gustavo Padovan Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 3631b0ef4d2e..8b80d68619af 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1032,8 +1032,7 @@ intel_check_sprite_plane(struct drm_plane *plane, struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc); struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_framebuffer *fb = state->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; uint32_t src_x, src_y, src_w, src_h; @@ -1235,9 +1234,8 @@ intel_commit_sprite_plane(struct drm_plane *plane, struct intel_plane *intel_plane = to_intel_plane(plane); enum pipe pipe = intel_crtc->pipe; struct drm_framebuffer *fb = state->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct drm_i915_gem_object *old_obj = intel_plane->obj; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; uint32_t src_x, src_y, src_w, src_h; -- GitLab From 5d93a6e5a9d225d9c38a63d2e0164ddc4228b354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 20:52:33 +0300 Subject: [PATCH 3045/9457] drm/i915: Do vlv cmnlane toggle w/a in more cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case the cmnlane power well is down but cmnreset isn't asserted we would currently skip the off+on toggle for the power well. That could leave cmnreset deasserted while cmnlane is powered down which might lead to problems with the PHY. To avoid such issues skip the cmnlane toggle only if both cmnlane and disp2d wells are up and cmnreset is already deasserted. In all other cases power down the cmnlane well which will also make sure cmnreset gets asserted correctly while cmnlane is powered down. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 39c33e0a753c..59ca54fc2487 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1137,12 +1137,9 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) struct i915_power_well *disp2d = lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); - /* nothing to do if common lane is already off */ - if (!cmn->ops->is_enabled(dev_priv, cmn)) - return; - /* If the display might be already active skip this */ - if (disp2d->ops->is_enabled(dev_priv, disp2d) && + if (cmn->ops->is_enabled(dev_priv, cmn) && + disp2d->ops->is_enabled(dev_priv, disp2d) && I915_READ(DPIO_CTL) & DPIO_CMNRST) return; -- GitLab From c14b048521ed3413df939ec6cc5dd450ff618120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Oct 2014 20:52:34 +0300 Subject: [PATCH 3046/9457] drm/i915: Initialize new chv primary plane and pipe blender registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV adds a bunch of new registers for primary plane size/position and pipe blender setup. Initialize all those registers to avoid nasty surprises. PRIMSIZE is especially important as without programming it the outout will be garbled whenever the primary plane size would not match what the BIOS set up. Also program the sprite constant alpha register to disable the constant alpha blending factor. This applies to vlv as well as chv. Signed-off-by: Ville Syrjälä Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 25 ++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++ drivers/gpu/drm/i915/intel_sprite.c | 2 ++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ea84e1ec5e5f..a9a861798ff5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4272,9 +4272,11 @@ enum punit_power_well { #define DISPPLANE_NO_LINE_DOUBLE 0 #define DISPPLANE_STEREO_POLARITY_FIRST 0 #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -#define DISPPLANE_ROTATE_180 (1<<15) +#define DISPPLANE_ALPHA_PREMULTIPLY (1<<16) /* CHV pipe B */ +#define DISPPLANE_ROTATE_180 (1<<15) #define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */ #define DISPPLANE_TILED (1<<10) +#define DISPPLANE_MIRROR (1<<8) /* CHV pipe B */ #define _DSPAADDR 0x70184 #define _DSPASTRIDE 0x70188 #define _DSPAPOS 0x7018C /* reserved */ @@ -4295,6 +4297,24 @@ enum punit_power_well { #define DSPOFFSET(plane) _PIPE2(plane, _DSPAOFFSET) #define DSPSURFLIVE(plane) _PIPE2(plane, _DSPASURFLIVE) +/* CHV pipe B blender and primary plane */ +#define _CHV_BLEND_A 0x60a00 +#define CHV_BLEND_LEGACY (0<<30) +#define CHV_BLEND_ANDROID (1<<30) +#define CHV_BLEND_MPO (2<<30) +#define CHV_BLEND_MASK (3<<30) +#define _CHV_CANVAS_A 0x60a04 +#define _PRIMPOS_A 0x60a08 +#define _PRIMSIZE_A 0x60a0c +#define _PRIMCNSTALPHA_A 0x60a10 +#define PRIM_CONST_ALPHA_ENABLE (1<<31) + +#define CHV_BLEND(pipe) _TRANSCODER2(pipe, _CHV_BLEND_A) +#define CHV_CANVAS(pipe) _TRANSCODER2(pipe, _CHV_CANVAS_A) +#define PRIMPOS(plane) _TRANSCODER2(plane, _PRIMPOS_A) +#define PRIMSIZE(plane) _TRANSCODER2(plane, _PRIMSIZE_A) +#define PRIMCNSTALPHA(plane) _TRANSCODER2(plane, _PRIMCNSTALPHA_A) + /* Display/Sprite base address macros */ #define DISP_BASEADDR_MASK (0xfffff000) #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) @@ -4496,6 +4516,7 @@ enum punit_power_well { #define SP_FORMAT_RGBA1010102 (9<<26) #define SP_FORMAT_RGBX8888 (0xe<<26) #define SP_FORMAT_RGBA8888 (0xf<<26) +#define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */ #define SP_SOURCE_KEY (1<<22) #define SP_YUV_BYTE_ORDER_MASK (3<<16) #define SP_YUV_ORDER_YUYV (0<<16) @@ -4504,6 +4525,7 @@ enum punit_power_well { #define SP_YUV_ORDER_VYUY (3<<16) #define SP_ROTATE_180 (1<<15) #define SP_TILED (1<<10) +#define SP_MIRROR (1<<8) /* CHV pipe B */ #define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184) #define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188) #define _SPAPOS (VLV_DISPLAY_BASE + 0x7218c) @@ -4514,6 +4536,7 @@ enum punit_power_well { #define _SPAKEYMAXVAL (VLV_DISPLAY_BASE + 0x721a0) #define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) #define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) +#define SP_CONST_ALPHA_ENABLE (1<<31) #define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4) #define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d678bc0c8184..c17ec502b087 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2451,6 +2451,12 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, ((intel_crtc->config.pipe_src_h - 1) << 16) | (intel_crtc->config.pipe_src_w - 1)); I915_WRITE(DSPPOS(plane), 0); + } else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) { + I915_WRITE(PRIMSIZE(plane), + ((intel_crtc->config.pipe_src_h - 1) << 16) | + (intel_crtc->config.pipe_src_w - 1)); + I915_WRITE(PRIMPOS(plane), 0); + I915_WRITE(PRIMCNSTALPHA(plane), 0); } switch (fb->pixel_format) { @@ -4856,6 +4862,13 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_set_pipe_timings(intel_crtc); + if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) { + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY); + I915_WRITE(CHV_CANVAS(pipe), 0); + } + i9xx_set_pipeconf(intel_crtc); intel_crtc->active = true; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8b80d68619af..4912161c95b3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -438,6 +438,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, else I915_WRITE(SPLINOFF(pipe, plane), linear_offset); + I915_WRITE(SPCONSTALPHA(pipe, plane), 0); + I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); I915_WRITE(SPCNTR(pipe, plane), sprctl); I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + -- GitLab From 1a5df187172a92ffdf8dc89988154d512d66a896 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 27 Oct 2014 17:54:32 -0200 Subject: [PATCH 3047/9457] drm/i915: kill intel_resume_prepare() Because, really, the abstraction is not working for us. It is nice for VLV, but doesn't add anything useful on SNB/HSW/BDW. We want to change this code due to a recently-discovered bug, but we can't seem to find a nice solution that repects the current abstraction. So let's kill intel_resume_prepare() and its friends, and add an equivalent implementation to both its callers. Also, look at the diffstat! v2: - Rebase. Signed-off-by: Paulo Zanoni Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 63 ++++++++------------------------- 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 035ec94ca3c7..33b6fc49dda7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -551,8 +551,8 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv) } static int intel_suspend_complete(struct drm_i915_private *dev_priv); -static int intel_resume_prepare(struct drm_i915_private *dev_priv, - bool rpm_resume); +static int vlv_resume_prepare(struct drm_i915_private *dev_priv, + bool rpm_resume); static int i915_drm_suspend(struct drm_device *dev) { @@ -744,7 +744,7 @@ static int i915_drm_resume(struct drm_device *dev) static int i915_drm_resume_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret; + int ret = 0; /* * We have a resume ordering issue with the snd-hda driver also @@ -760,7 +760,10 @@ static int i915_drm_resume_early(struct drm_device *dev) pci_set_master(dev->pdev); - ret = intel_resume_prepare(dev_priv, false); + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + hsw_disable_pc8(dev_priv); + else if (IS_VALLEYVIEW(dev_priv)) + ret = vlv_resume_prepare(dev_priv, false); if (ret) DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); @@ -986,25 +989,6 @@ static int hsw_suspend_complete(struct drm_i915_private *dev_priv) return 0; } -static int snb_resume_prepare(struct drm_i915_private *dev_priv, - bool rpm_resume) -{ - struct drm_device *dev = dev_priv->dev; - - if (rpm_resume) - intel_init_pch_refclk(dev); - - return 0; -} - -static int hsw_resume_prepare(struct drm_i915_private *dev_priv, - bool rpm_resume) -{ - hsw_disable_pc8(dev_priv); - - return 0; -} - /* * Save all Gunit registers that may be lost after a D3 and a subsequent * S0i[R123] transition. The list of registers needing a save/restore is @@ -1462,7 +1446,7 @@ static int intel_runtime_resume(struct device *device) struct pci_dev *pdev = to_pci_dev(device); struct drm_device *dev = pci_get_drvdata(pdev); struct drm_i915_private *dev_priv = dev->dev_private; - int ret; + int ret = 0; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev))) return -ENODEV; @@ -1472,7 +1456,13 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv->pm.suspended = false; - ret = intel_resume_prepare(dev_priv, true); + if (IS_GEN6(dev_priv)) + intel_init_pch_refclk(dev); + else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + hsw_disable_pc8(dev_priv); + else if (IS_VALLEYVIEW(dev_priv)) + ret = vlv_resume_prepare(dev_priv, true); + /* * No point of rolling back things in case of an error, as the best * we can do is to hope that things will still work (and disable RPM). @@ -1510,29 +1500,6 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv) return ret; } -/* - * This function implements common functionality of runtime and system - * resume sequence. Variable rpm_resume used for implementing different - * code paths. - */ -static int intel_resume_prepare(struct drm_i915_private *dev_priv, - bool rpm_resume) -{ - struct drm_device *dev = dev_priv->dev; - int ret; - - if (IS_GEN6(dev)) - ret = snb_resume_prepare(dev_priv, rpm_resume); - else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - ret = hsw_resume_prepare(dev_priv, rpm_resume); - else if (IS_VALLEYVIEW(dev)) - ret = vlv_resume_prepare(dev_priv, rpm_resume); - else - ret = 0; - - return ret; -} - static const struct dev_pm_ops i915_pm_ops = { /* * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND, -- GitLab From efee833a2d0a69dfa2c4ec28377b00803a0f9a60 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 27 Oct 2014 17:54:33 -0200 Subject: [PATCH 3048/9457] drm/i915: run hsw_disable_pc8() later on resume We want to run intel_uncore_early_sanitize() before we touch any registers, because on BDW, when we resume, the FPGA_DBG_RM_NOCLAIM bit is set, so we need to clear it - through intel_uncore_early_sanitize() - before we do anything else. With the current code, we don't clear the bit before our first register access, so we print a WARN complaining about an unclaimed register error. v1: Was called "drm/i915: run intel_uncore_early_sanitize earlier on resume" v2: Was called "drm/i915: run intel_uncore_early_sanitize earlier on resume on non-VLV" v3: This one, on top of the intel_resume_prepare() rework. v4: Rebase. Signed-off-by: Paulo Zanoni Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 33b6fc49dda7..0c7cf480e854 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -760,14 +760,16 @@ static int i915_drm_resume_early(struct drm_device *dev) pci_set_master(dev->pdev); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hsw_disable_pc8(dev_priv); - else if (IS_VALLEYVIEW(dev_priv)) + if (IS_VALLEYVIEW(dev_priv)) ret = vlv_resume_prepare(dev_priv, false); if (ret) DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); intel_uncore_early_sanitize(dev, true); + + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + hsw_disable_pc8(dev_priv); + intel_uncore_sanitize(dev); intel_power_domains_init_hw(dev_priv); -- GitLab From 6ca2aeb27b4a8451052baa61c11c33bd5de8a71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 20 Oct 2014 19:47:53 +0300 Subject: [PATCH 3049/9457] drm/i915: Add support for CHV pipe B sprite CSC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV has a programmable CSC unit on the pipe B sprites. Program the unit appropriately for BT.601 limited range YCbCr to full range RGB color conversion. This matches the programming we currently do for sprites on the other pipes and on other platforms. It seems the CSC only works when the input data is YCbCr. For RGB pixel formats it doesn't matter what we program into the CSC registers. Doesn't make much sense to me especially since the register names give the impression that RGB input data would also work. But that's how it behaves here. In the review discussions there's been some nice math to explain the values obtained here. First about the YCbCr->RGB matrix: "I had the RGB->YCbCr matrix, inverted it and the values came out. But they should match the wikipedia article. Also keep in mind that the coefficients are in .12 in fixed point format, hence we need a 1<<12 factor. So let's try it: Kb=.114 Kr=.299 (1<<12) * 255/219 ~= 4769 -(1<<12) * 255/112*(1-Kb)*Kb/(1-Kb-Kr) ~= -1605 -(1<<12) * 255/112*(1-Kr)*Kr/(1-Kb-Kr) ~= -3330 (1<<12) * 255/112*(1-Kr) ~= 6537 (1<<12) * 255/112*(1-Kb) ~= 8263 "Looks like the same values to me." And then about the limits used for clamping: "> where did you get these min/max? "The hardware apparently deals in 10bit values, so we need to multiply everything by 4 when we start with the 8bit min/max values. Y = [16:235] * 4 = [64:940] CbCr = ([16:240] - 128) * 4 = [-112:112] * 4 = [-448:448] "The -128 being the -0.5 bias that the hardware already applied before the data entered the CSC unit." Raw data is also supplied in 10bpc in the registers. Signed-off-by: Ville Syrjälä Reviewed-by Rodrigo Vivi [danvet: Copypaste explanations&math from the review discussion.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 33 ++++++++++++++ drivers/gpu/drm/i915/intel_sprite.c | 70 +++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a9a861798ff5..2a4bdd56c4e0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4565,6 +4565,39 @@ enum punit_power_well { #define SPCONSTALPHA(pipe, plane) _PIPE(pipe * 2 + plane, _SPACONSTALPHA, _SPBCONSTALPHA) #define SPGAMC(pipe, plane) _PIPE(pipe * 2 + plane, _SPAGAMC, _SPBGAMC) +/* + * CHV pipe B sprite CSC + * + * |cr| |c0 c1 c2| |cr + cr_ioff| |cr_ooff| + * |yg| = |c3 c4 c5| x |yg + yg_ioff| + |yg_ooff| + * |cb| |c6 c7 c8| |cb + cr_ioff| |cb_ooff| + */ +#define SPCSCYGOFF(sprite) (VLV_DISPLAY_BASE + 0x6d900 + (sprite) * 0x1000) +#define SPCSCCBOFF(sprite) (VLV_DISPLAY_BASE + 0x6d904 + (sprite) * 0x1000) +#define SPCSCCROFF(sprite) (VLV_DISPLAY_BASE + 0x6d908 + (sprite) * 0x1000) +#define SPCSC_OOFF(x) (((x) & 0x7ff) << 16) /* s11 */ +#define SPCSC_IOFF(x) (((x) & 0x7ff) << 0) /* s11 */ + +#define SPCSCC01(sprite) (VLV_DISPLAY_BASE + 0x6d90c + (sprite) * 0x1000) +#define SPCSCC23(sprite) (VLV_DISPLAY_BASE + 0x6d910 + (sprite) * 0x1000) +#define SPCSCC45(sprite) (VLV_DISPLAY_BASE + 0x6d914 + (sprite) * 0x1000) +#define SPCSCC67(sprite) (VLV_DISPLAY_BASE + 0x6d918 + (sprite) * 0x1000) +#define SPCSCC8(sprite) (VLV_DISPLAY_BASE + 0x6d91c + (sprite) * 0x1000) +#define SPCSC_C1(x) (((x) & 0x7fff) << 16) /* s3.12 */ +#define SPCSC_C0(x) (((x) & 0x7fff) << 0) /* s3.12 */ + +#define SPCSCYGICLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d920 + (sprite) * 0x1000) +#define SPCSCCBICLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d924 + (sprite) * 0x1000) +#define SPCSCCRICLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d928 + (sprite) * 0x1000) +#define SPCSC_IMAX(x) (((x) & 0x7ff) << 16) /* s11 */ +#define SPCSC_IMIN(x) (((x) & 0x7ff) << 0) /* s11 */ + +#define SPCSCYGOCLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d92c + (sprite) * 0x1000) +#define SPCSCCBOCLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d930 + (sprite) * 0x1000) +#define SPCSCCROCLAMP(sprite) (VLV_DISPLAY_BASE + 0x6d934 + (sprite) * 0x1000) +#define SPCSC_OMAX(x) ((x) << 16) /* u10 */ +#define SPCSC_OMIN(x) ((x) << 0) /* u10 */ + /* Skylake plane registers */ #define _PLANE_CTL_1_A 0x70180 diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4912161c95b3..bf1eb158e624 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -37,6 +37,20 @@ #include #include "i915_drv.h" +static bool +format_is_yuv(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_YUYV: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_YVYU: + return true; + default: + return false; + } +} + static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) { /* paranoia */ @@ -319,6 +333,45 @@ skl_get_colorkey(struct drm_plane *drm_plane, } } +static void +chv_update_csc(struct intel_plane *intel_plane, uint32_t format) +{ + struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private; + int plane = intel_plane->plane; + + /* Seems RGB data bypasses the CSC always */ + if (!format_is_yuv(format)) + return; + + /* + * BT.601 limited range YCbCr -> full range RGB + * + * |r| | 6537 4769 0| |cr | + * |g| = |-3330 4769 -1605| x |y-64| + * |b| | 0 4769 8263| |cb | + * + * Cb and Cr apparently come in as signed already, so no + * need for any offset. For Y we need to remove the offset. + */ + I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); + I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); + I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); + + I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537)); + I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0)); + I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769)); + I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0)); + I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263)); + + I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64)); + I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); + I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); + + I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); + I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); + I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); +} + static void vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -430,6 +483,9 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, intel_update_primary_plane(intel_crtc); + if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) + chv_update_csc(intel_plane, fb->pixel_format); + I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); @@ -1004,20 +1060,6 @@ ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) key->flags = I915_SET_COLORKEY_NONE; } -static bool -format_is_yuv(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_YUYV: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_YVYU: - return true; - default: - return false; - } -} - static bool colorkey_enabled(struct intel_plane *intel_plane) { struct drm_intel_sprite_colorkey key; -- GitLab From baa4e575d6a18dcd6f2e622784aa16ab24024f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 27 Oct 2014 16:07:32 +0200 Subject: [PATCH 3050/9457] drm/i915: Enable pipe-a power well on chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that the pipe-a power well has replaced the disp2d power well on chv. At least that's the case with the current punit firmware. So enable the pipe-a power and expand its domains to cover everything the disp2d well ought to cover. The other power wells (apart from the cmnlane wells) still seem awol in the current punit firmware. So leave them disabled in the code. This fixes a hilarious oops during resume on bsw where intel_hdmi_get_config() would read the port register and get back 0xffffffff and thus think the port is enabled on pipe D. It would then go and index the pipe_to_crtc_mapping[] array with PIPE_D and blow up when intel_hdmi_get_config() tries to write to crtc->config. Someone really ought to replace all naked pipe_to_crtc_mapping[] uses with the appropriate function call so we could add a warning there if the pipe doesn't actually exist... We must also call the power seqeuencer state reset function from the pipe-a well disable just like we do from disp2d on vlv. Otherwise the eDP panel won't recover at resume time since the PPS has lost its hold on the port. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84903 Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 59ca54fc2487..dcbecffc6b5f 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -587,6 +587,9 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, power_well->data != PIPE_C); chv_set_pipe_power_well(dev_priv, power_well, false); + + if (power_well->data == PIPE_A) + vlv_power_sequencer_reset(dev_priv); } static void check_power_well_state(struct drm_i915_private *dev_priv, @@ -938,12 +941,20 @@ static struct i915_power_well chv_power_wells[] = { .data = PUNIT_POWER_WELL_DISP2D, .ops = &vlv_display_power_well_ops, }, +#endif { .name = "pipe-a", - .domains = CHV_PIPE_A_POWER_DOMAINS, + /* + * FIXME: pipe A power well seems to be the new disp2d well. + * At least all registers seem to be housed there. Figure + * out if this a a temporary situation in pre-production + * hardware or a permanent state of affairs. + */ + .domains = CHV_PIPE_A_POWER_DOMAINS | VLV_DISPLAY_POWER_DOMAINS, .data = PIPE_A, .ops = &chv_pipe_power_well_ops, }, +#if 0 { .name = "pipe-b", .domains = CHV_PIPE_B_POWER_DOMAINS, -- GitLab From 6189b0369c67f5bc6687ee957b3c1317dbb78922 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 28 Oct 2014 13:53:01 +0200 Subject: [PATCH 3051/9457] drm/i915/audio: set ELD Conn_Type at one place Keep the driver modifications to ELD together. This also sets the Conn_Type for G4X DP which wasn't done before. Clean up the debugs while at it; this is all obvious from the connector name. v3: add missing ~ (Rodrigo) Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 4a384d780b20..537f6d8927f1 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -181,13 +181,10 @@ static void haswell_write_eld(struct drm_connector *connector, eldv = AUDIO_ELD_VALID_A << (pipe * 4); - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { - DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); - eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - } else { + else I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - } if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, @@ -276,13 +273,10 @@ static void ironlake_write_eld(struct drm_connector *connector, eldv = IBX_ELD_VALIDB << ((port - 1) * 4); } - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) { - DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); - eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - } else { + else I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - } if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, @@ -330,6 +324,11 @@ void intel_write_eld(struct intel_encoder *intel_encoder) connector->encoder->base.id, connector->encoder->name); + /* ELD Conn_Type */ + connector->eld[5] &= ~(3 << 2); + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) + connector->eld[5] |= (1 << 2); + connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; if (dev_priv->display.write_eld) -- GitLab From 2aa0de39fa071129fdd952a0d99828db8434d88f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:49 +0200 Subject: [PATCH 3052/9457] drm/i915/ddi: write ELD where it's supposed to be done The audio programming sequence states that the ELD must be written and enabled after the pipe is ready. Indeed, this should clarify the situation with commit c79057922ed6c2c6df1214e6ab4414fea1b23db2 Author: Daniel Vetter Date: Wed Apr 16 16:56:09 2014 +0200 drm/i915: Remove vblank wait from haswell_write_eld and Ville's review of it [1]. Moreover, we should not touch the relevant registers before we get the audio power domain. [1] http://mid.gmane.org/20140416155309.GK18465@intel.com Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 2 -- drivers/gpu/drm/i915/intel_ddi.c | 11 ++--------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 537f6d8927f1..158ad60a6e21 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -160,8 +160,6 @@ static void haswell_write_eld(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); POSTING_READ(aud_cntrl_st2); - assert_pipe_disabled(dev_priv, pipe); - /* Set ELD valid state */ tmp = I915_READ(aud_cntrl_st2); DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 2688bc940879..56e7cb1ddc75 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1120,15 +1120,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; - if (crtc->config.has_audio) { - DRM_DEBUG_DRIVER("Audio on pipe %c on DDI\n", - pipe_name(crtc->pipe)); - - /* write eld */ - DRM_DEBUG_DRIVER("DDI audio: write eld information\n"); - intel_write_eld(intel_encoder); - } - if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_edp_panel_on(intel_dp); @@ -1225,6 +1216,8 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) if (intel_crtc->config.has_audio) { intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); + intel_write_eld(intel_encoder); + tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); -- GitLab From 69bfe1a9b4dffca482c6cd7f1e218f24a1128dcc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:50 +0200 Subject: [PATCH 3053/9457] drm/i915: introduce intel_audio_codec_{enable, disable} Introduce functions to enable/disable the audio codec, incorporating the ELD setup within enable. The disable is initially limited to HSW, covering exactly what was done previously. The only functional difference is that ELD valid is no longer set if there is no connector with ELD, which should be the right thing to do anyway. Otherwise the sequence remains the same, with warts and all, in preparation for applying more sanity. v2: add kernel doc. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 +-- drivers/gpu/drm/i915/intel_audio.c | 83 +++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_ddi.c | 17 +----- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 6 files changed, 73 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6a73803482cb..0344fd561789 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -483,9 +483,10 @@ struct drm_i915_display_funcs { void (*crtc_enable)(struct drm_crtc *crtc); void (*crtc_disable)(struct drm_crtc *crtc); void (*off)(struct drm_crtc *crtc); - void (*write_eld)(struct drm_connector *connector, - struct intel_encoder *encoder, - struct drm_display_mode *mode); + void (*audio_codec_enable)(struct drm_connector *connector, + struct intel_encoder *encoder, + struct drm_display_mode *mode); + void (*audio_codec_disable)(struct intel_encoder *encoder); void (*fdi_link_train)(struct drm_crtc *crtc); void (*init_clock_gating)(struct drm_device *dev); int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 158ad60a6e21..f291efc8b229 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -96,9 +96,9 @@ static bool intel_eld_uptodate(struct drm_connector *connector, return true; } -static void g4x_write_eld(struct drm_connector *connector, - struct intel_encoder *encoder, - struct drm_display_mode *mode) +static void g4x_audio_codec_enable(struct drm_connector *connector, + struct intel_encoder *encoder, + struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; uint8_t *eld = connector->eld; @@ -136,9 +136,22 @@ static void g4x_write_eld(struct drm_connector *connector, I915_WRITE(G4X_AUD_CNTL_ST, tmp); } -static void haswell_write_eld(struct drm_connector *connector, - struct intel_encoder *encoder, - struct drm_display_mode *mode) +static void hsw_audio_codec_disable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = encoder->base.crtc; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + uint32_t tmp; + + tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); + tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); + I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); +} + +static void hsw_audio_codec_enable(struct drm_connector *connector, + struct intel_encoder *encoder, + struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); @@ -211,11 +224,16 @@ static void haswell_write_eld(struct drm_connector *connector, tmp = I915_READ(aud_cntrl_st2); tmp |= eldv; I915_WRITE(aud_cntrl_st2, tmp); + + /* XXX: Transitional */ + tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); + tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); + I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); } -static void ironlake_write_eld(struct drm_connector *connector, - struct intel_encoder *encoder, - struct drm_display_mode *mode) +static void ilk_audio_codec_enable(struct drm_connector *connector, + struct intel_encoder *encoder, + struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = connector->dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); @@ -303,7 +321,14 @@ static void ironlake_write_eld(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); } -void intel_write_eld(struct intel_encoder *intel_encoder) +/** + * intel_audio_codec_enable - Enable the audio codec for HD audio + * @intel_encoder: encoder on which to enable audio + * + * The enable sequences may only be performed after enabling the transcoder and + * port, and after completed link training. + */ +void intel_audio_codec_enable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); @@ -329,8 +354,24 @@ void intel_write_eld(struct intel_encoder *intel_encoder) connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; - if (dev_priv->display.write_eld) - dev_priv->display.write_eld(connector, intel_encoder, mode); + if (dev_priv->display.audio_codec_enable) + dev_priv->display.audio_codec_enable(connector, intel_encoder, mode); +} + +/** + * intel_audio_codec_disable - Disable the audio codec for HD audio + * @encoder: encoder on which to disable audio + * + * The disable sequences must be performed before disabling the transcoder or + * port. + */ +void intel_audio_codec_disable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->display.audio_codec_disable) + dev_priv->display.audio_codec_disable(encoder); } /** @@ -341,12 +382,14 @@ void intel_init_audio(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_G4X(dev)) - dev_priv->display.write_eld = g4x_write_eld; - else if (IS_VALLEYVIEW(dev)) - dev_priv->display.write_eld = ironlake_write_eld; - else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) - dev_priv->display.write_eld = haswell_write_eld; - else if (HAS_PCH_SPLIT(dev)) - dev_priv->display.write_eld = ironlake_write_eld; + if (IS_G4X(dev)) { + dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; + } else if (IS_VALLEYVIEW(dev)) { + dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + } else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) { + dev_priv->display.audio_codec_enable = hsw_audio_codec_enable; + dev_priv->display.audio_codec_disable = hsw_audio_codec_disable; + } else if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + } } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 56e7cb1ddc75..b182b9b80461 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1186,12 +1186,10 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) struct drm_encoder *encoder = &intel_encoder->base; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; - uint32_t tmp; if (type == INTEL_OUTPUT_HDMI) { struct intel_digital_port *intel_dig_port = @@ -1216,11 +1214,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) if (intel_crtc->config.has_audio) { intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); - intel_write_eld(intel_encoder); - - tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); - I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); + intel_audio_codec_enable(intel_encoder); } } @@ -1229,19 +1223,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) struct drm_encoder *encoder = &intel_encoder->base; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; int type = intel_encoder->type; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t tmp; - /* We can't touch HSW_AUD_PIN_ELD_CP_VLD uncionditionally because this - * register is part of the power well on Haswell. */ if (intel_crtc->config.has_audio) { - tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << - (pipe * 4)); - I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); + intel_audio_codec_disable(intel_encoder); intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ccc690e2e906..f1a5fe26a9c8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1328,7 +1328,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder) DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", pipe_name(crtc->pipe)); intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; - intel_write_eld(encoder); + intel_audio_codec_enable(encoder); } /* Split out the IBX/CPU vs CPT settings */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d53ac23cb127..134ab083fd01 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -853,7 +853,8 @@ void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); /* intel_audio.c */ void intel_init_audio(struct drm_device *dev); -void intel_write_eld(struct intel_encoder *encoder); +void intel_audio_codec_enable(struct intel_encoder *encoder); +void intel_audio_codec_disable(struct intel_encoder *encoder); /* intel_display.c */ const char *intel_output_name(int output); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 07b5ebd65d41..f29026a1157d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -666,7 +666,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", pipe_name(crtc->pipe)); hdmi_val |= SDVO_AUDIO_ENABLE; - intel_write_eld(encoder); + intel_audio_codec_enable(encoder); } if (HAS_PCH_CPT(dev)) -- GitLab From d806fbf5d38f23fc1b259fee181b749665d72735 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:51 +0200 Subject: [PATCH 3054/9457] drm/i915/audio: remove misleading checks for !eld[0] We'll never end up in the hooks with eld[0] unset, as that's checked by drm_select_eld(). Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index f291efc8b229..7580b3823e30 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -79,9 +79,6 @@ static bool intel_eld_uptodate(struct drm_connector *connector, tmp = I915_READ(reg_eldv); tmp &= bits_eldv; - if (!eld[0]) - return !tmp; - if (!tmp) return false; @@ -123,9 +120,6 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, len = (tmp >> 9) & 0x1f; /* ELD buffer size */ I915_WRITE(G4X_AUD_CNTL_ST, tmp); - if (!eld[0]) - return; - len = min_t(int, eld[2], len); DRM_DEBUG_DRIVER("ELD size %d\n", len); for (i = 0; i < len; i++) @@ -207,9 +201,6 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, tmp &= ~eldv; I915_WRITE(aud_cntrl_st2, tmp); - if (!eld[0]) - return; - tmp = I915_READ(aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS; I915_WRITE(aud_cntl_st, tmp); @@ -304,9 +295,6 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, tmp &= ~eldv; I915_WRITE(aud_cntrl_st2, tmp); - if (!eld[0]) - return; - tmp = I915_READ(aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS; I915_WRITE(aud_cntl_st, tmp); -- GitLab From 1e74a324465e5a4f8e3ee7c423aef92c54de8a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 28 Oct 2014 16:15:51 +0200 Subject: [PATCH 3055/9457] drm/i915: Initialize PPS timestamps on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pps timestamp initialization was accidentally lost on vlv/chv in commit a4a5d2f8a96e09844a91469e889f15bd5e927399 Author: Ville Syrjälä Date: Thu Sep 4 14:54:20 2014 +0300 drm/i915: Track which port is using which pipe's power sequencer Restore it so that we avoid introducing random delays into the pps operations during/after driver init time. Cc: Imre Deak Reported-by: Imre Deak Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f1a5fe26a9c8..45c0a6636030 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5364,12 +5364,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, if (is_edp(intel_dp)) { pps_lock(intel_dp); - if (IS_VALLEYVIEW(dev)) { + intel_dp_init_panel_power_timestamps(intel_dp); + if (IS_VALLEYVIEW(dev)) vlv_initial_power_sequencer_setup(intel_dp); - } else { - intel_dp_init_panel_power_timestamps(intel_dp); + else intel_dp_init_panel_power_sequencer(dev, intel_dp); - } pps_unlock(intel_dp); } -- GitLab From 49e6bc51bc9e22c8a433ba32a4e45a5818de3850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 28 Oct 2014 16:15:52 +0200 Subject: [PATCH 3056/9457] drm/i915: Read out the power sequencer port assignment on resume on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we suspend we turn everything off so the pps should be idle, and we also (or at least should) disable all power wells which will reset the power sequencer port assignment. So when we resume all power sequencers should be in their reset state. However it's at least theoretically possible that the BIOS would touch the power seuqencer(s), so to be safe we ought to read out the current port assignment like we do at driver init time. To do that we can simply call vlv_initial_power_sequencer_setup() from the encoder ->reset() hook before calling intel_edp_panel_vdd_sanitize(). There's no danger or clobbering the pps delays since we now have those stored within intel_dp and we don't change them once initialized. This will make sure that the vdd state gets correctly tracked post-resume in case the BIOS enabled it. We need to shuffle things around a bit to get the locking right, and while at it, make intel_edp_panel_vdd_sanitize() static and move it around a bit to avoid a forward declaration. Cc: Imre Deak Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 80 +++++++++++++++++++------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 45c0a6636030..ec80e828240e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4677,9 +4677,52 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) pps_unlock(intel_dp); } +static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_display_power_domain power_domain; + + lockdep_assert_held(&dev_priv->pps_mutex); + + if (!edp_have_panel_vdd(intel_dp)) + return; + + /* + * The VDD bit needs a power domain reference, so if the bit is + * already enabled when we boot or resume, grab this reference and + * schedule a vdd off, so we don't hold on to the reference + * indefinitely. + */ + DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n"); + power_domain = intel_display_port_power_domain(&intel_dig_port->base); + intel_display_power_get(dev_priv, power_domain); + + edp_panel_vdd_schedule_off(intel_dp); +} + static void intel_dp_encoder_reset(struct drm_encoder *encoder) { - intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); + struct intel_dp *intel_dp; + + if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP) + return; + + intel_dp = enc_to_intel_dp(encoder); + + pps_lock(intel_dp); + + /* + * Read out the current power sequencer assignment, + * in case the BIOS did something with it. + */ + if (IS_VALLEYVIEW(encoder->dev)) + vlv_initial_power_sequencer_setup(intel_dp); + + intel_edp_panel_vdd_sanitize(intel_dp); + + pps_unlock(intel_dp); } static const struct drm_connector_funcs intel_dp_connector_funcs = { @@ -5150,37 +5193,6 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port, return downclock_mode; } -void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder) -{ - struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp *intel_dp; - enum intel_display_power_domain power_domain; - - if (intel_encoder->type != INTEL_OUTPUT_EDP) - return; - - intel_dp = enc_to_intel_dp(&intel_encoder->base); - - pps_lock(intel_dp); - - if (!edp_have_panel_vdd(intel_dp)) - goto out; - /* - * The VDD bit needs a power domain reference, so if the bit is - * already enabled when we boot or resume, grab this reference and - * schedule a vdd off, so we don't hold on to the reference - * indefinitely. - */ - DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n"); - power_domain = intel_display_port_power_domain(intel_encoder); - intel_display_power_get(dev_priv, power_domain); - - edp_panel_vdd_schedule_off(intel_dp); - out: - pps_unlock(intel_dp); -} - static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_connector *intel_connector) { @@ -5200,7 +5212,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (!is_edp(intel_dp)) return true; - intel_edp_panel_vdd_sanitize(intel_encoder); + pps_lock(intel_dp); + intel_edp_panel_vdd_sanitize(intel_dp); + pps_unlock(intel_dp); /* Cache DPCD and EDID for edp. */ has_dpcd = intel_dp_get_dpcd(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 134ab083fd01..82d89167cd2f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -981,7 +981,6 @@ bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, void intel_edp_backlight_on(struct intel_dp *intel_dp); void intel_edp_backlight_off(struct intel_dp *intel_dp); void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); -void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder); void intel_edp_panel_on(struct intel_dp *intel_dp); void intel_edp_panel_off(struct intel_dp *intel_dp); void intel_edp_psr_enable(struct intel_dp *intel_dp); -- GitLab From c883ef1b1c998d2d66866772fd0fc34afa45641e Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 28 Oct 2014 17:32:30 +0200 Subject: [PATCH 3057/9457] drm/i915: Redefine WARN_ON to include the condition When looking at the bug report logs with triggered WARN_ON, the person doing bug triaging will have to find exact kernel source and match file/line. Attach the condition that triggered the WARN_ON to kernel log. In most cases the context is self evident and this way we can save developer time. The drawback is ~16kbytes bigger i915.ko Signed-off-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0344fd561789..0e12c6ac2be5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -57,6 +57,9 @@ #define DRIVER_DESC "Intel Graphics" #define DRIVER_DATE "20141024" +#undef WARN_ON +#define WARN_ON(x) WARN(x, "WARN_ON(" #x ")") + enum pipe { INVALID_PIPE = -1, PIPE_A = 0, -- GitLab From 6402c330a62685c77c32d1bdfa882759c9f8e8a7 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Fri, 31 Oct 2014 12:00:26 +0000 Subject: [PATCH 3058/9457] drm/i915: Fix null pointer dereference in ring cleanup code If a ring failed to initialise for any reason then the error path would try to clean up all rings including those that had not yet been allocated. The ring clean up code did a check that the ring was valid before starting its work. Unfortunately, that was after it had already dereferenced the ring to obtain a dev_private pointer. Signed-off-by: John Harrison Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 4 +++- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 803fc38664c4..d7525bd6d810 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1214,11 +1214,13 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf) */ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_i915_private *dev_priv; if (!intel_ring_initialized(ring)) return; + dev_priv = ring->dev->dev_private; + intel_logical_ring_stop(ring); WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); ring->preallocated_lazy_request = NULL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a8f72e8d64e3..f457146ff6a4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1845,12 +1845,15 @@ static int intel_init_ring_buffer(struct drm_device *dev, void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) { - struct drm_i915_private *dev_priv = to_i915(ring->dev); - struct intel_ringbuffer *ringbuf = ring->buffer; + struct drm_i915_private *dev_priv; + struct intel_ringbuffer *ringbuf; if (!intel_ring_initialized(ring)) return; + dev_priv = to_i915(ring->dev); + ringbuf = ring->buffer; + intel_stop_ring_buffer(ring); WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); -- GitLab From cd0707cb1dbdd96b0358e5b10eba89c3bbe5a690 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Thu, 30 Oct 2014 15:41:56 +0000 Subject: [PATCH 3059/9457] drm/i915: Remove redundant return value and WARN_ON execlists_submit_context() always returns 0, which is redundant. And its name is inaccurate, since it actually submits (up to) TWO contextS. So we rename it, change it to "void", and remove the WARN_ON() testing its return value. Change-Id: Ie225b0eca7754c6093c8b8bd15550b251b6feb82 Signed-off-by: Dave Gordon Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d7525bd6d810..70a6c63f3b9a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -356,9 +356,9 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai return 0; } -static int execlists_submit_context(struct intel_engine_cs *ring, - struct intel_context *to0, u32 tail0, - struct intel_context *to1, u32 tail1) +static void execlists_submit_contexts(struct intel_engine_cs *ring, + struct intel_context *to0, u32 tail0, + struct intel_context *to1, u32 tail1) { struct drm_i915_gem_object *ctx_obj0; struct drm_i915_gem_object *ctx_obj1 = NULL; @@ -378,8 +378,6 @@ static int execlists_submit_context(struct intel_engine_cs *ring, } execlists_elsp_write(ring, ctx_obj0, ctx_obj1); - - return 0; } static void execlists_context_unqueue(struct intel_engine_cs *ring) @@ -413,9 +411,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) WARN_ON(req1 && req1->elsp_submitted); - WARN_ON(execlists_submit_context(ring, req0->ctx, req0->tail, - req1 ? req1->ctx : NULL, - req1 ? req1->tail : 0)); + execlists_submit_contexts(ring, req0->ctx, req0->tail, + req1 ? req1->ctx : NULL, + req1 ? req1->tail : 0); req0->elsp_submitted++; if (req1) -- GitLab From d0737e1d5944f570d5151ae6213952058c18a903 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:30 +0200 Subject: [PATCH 3060/9457] drm/i915: Make *_crtc_mode_set work on new_config This shouldn't change the behavior of those functions, since they are called after the new_config is made effective and that points to the current config. In a follow up patch, the mode set sequence will be changed so this is called before disabling crtcs, and in that case those functions should work on the staged config. Signed-off-by: Ander Conselvan de Oliveira [danvet: Flatten if by moving the check into the WARN.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 31 +++++- drivers/gpu/drm/i915/intel_display.c | 153 ++++++++++++++++----------- 2 files changed, 116 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b182b9b80461..d41768846f18 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -459,6 +459,27 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) return ret; } +static struct intel_encoder * +intel_ddi_get_crtc_new_encoder(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct intel_encoder *intel_encoder, *ret = NULL; + int num_encoders = 0; + + for_each_intel_encoder(dev, intel_encoder) { + if (intel_encoder->new_crtc == crtc) { + ret = intel_encoder; + num_encoders++; + } + } + + WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders, + pipe_name(crtc->pipe)); + + BUG_ON(ret == NULL); + return ret; +} + #define LC_FREQ 2700 #define LC_FREQ_2K U64_C(LC_FREQ * 2000) @@ -792,7 +813,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p); - intel_crtc->config.dpll_hw_state.wrpll = val; + intel_crtc->new_config->dpll_hw_state.wrpll = val; pll = intel_get_shared_dpll(intel_crtc); if (pll == NULL) { @@ -801,7 +822,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, return false; } - intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); + intel_crtc->new_config->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); } return true; @@ -817,9 +838,9 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, */ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) { - struct drm_crtc *crtc = &intel_crtc->base; - struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); - int clock = intel_crtc->config.port_clock; + struct intel_encoder *intel_encoder = + intel_ddi_get_crtc_new_encoder(intel_crtc); + int clock = intel_crtc->new_config->port_clock; intel_put_shared_dpll(intel_crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c17ec502b087..6bd290d902df 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -420,13 +420,31 @@ bool intel_pipe_has_type(struct intel_crtc *crtc, int type) return false; } +/** + * Returns whether any output on the specified pipe will have the specified + * type after a staged modeset is complete, i.e., the same as + * intel_pipe_has_type() but looking at encoder->new_crtc instead of + * encoder->crtc. + */ +static bool intel_pipe_will_have_type(struct intel_crtc *crtc, int type) +{ + struct drm_device *dev = crtc->base.dev; + struct intel_encoder *encoder; + + for_each_intel_encoder(dev, encoder) + if (encoder->new_crtc == crtc && encoder->type == type) + return true; + + return false; +} + static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc, int refclk) { struct drm_device *dev = crtc->base.dev; const intel_limit_t *limit; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_is_dual_link_lvds(dev)) { if (refclk == 100000) limit = &intel_limits_ironlake_dual_lvds_100m; @@ -449,15 +467,15 @@ static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc) struct drm_device *dev = crtc->base.dev; const intel_limit_t *limit; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_is_dual_link_lvds(dev)) limit = &intel_limits_g4x_dual_channel_lvds; else limit = &intel_limits_g4x_single_channel_lvds; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { + } else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI) || + intel_pipe_will_have_type(crtc, INTEL_OUTPUT_ANALOG)) { limit = &intel_limits_g4x_hdmi; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { + } else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO)) { limit = &intel_limits_g4x_sdvo; } else /* The option is for other outputs */ limit = &intel_limits_i9xx_sdvo; @@ -475,7 +493,7 @@ static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk) else if (IS_G4X(dev)) { limit = intel_g4x_limit(crtc); } else if (IS_PINEVIEW(dev)) { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits_pineview_lvds; else limit = &intel_limits_pineview_sdvo; @@ -484,14 +502,14 @@ static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk) } else if (IS_VALLEYVIEW(dev)) { limit = &intel_limits_vlv; } else if (!IS_GEN2(dev)) { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits_i9xx_lvds; else limit = &intel_limits_i9xx_sdvo; } else { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) limit = &intel_limits_i8xx_lvds; - else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO)) + else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO)) limit = &intel_limits_i8xx_dvo; else limit = &intel_limits_i8xx_dac; @@ -586,7 +604,7 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, intel_clock_t clock; int err = target; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -647,7 +665,7 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, intel_clock_t clock; int err = target; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -710,7 +728,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc, int err_most = (target >> 8) + (target >> 9); found = false; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_is_dual_link_lvds(dev)) clock.p2 = limit->p2.p2_fast; else @@ -5628,7 +5646,7 @@ static int i9xx_get_refclk(struct intel_crtc *crtc, int num_connectors) if (IS_VALLEYVIEW(dev)) { refclk = 100000; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + } else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); @@ -6018,29 +6036,29 @@ static void i9xx_update_pll(struct intel_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; u32 dpll; bool is_sdvo; - struct dpll *clock = &crtc->config.dpll; + struct dpll *clock = &crtc->new_config->dpll; i9xx_update_pll_dividers(crtc, reduced_clock); - is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); + is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) || + intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI); dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) dpll |= DPLLB_MODE_LVDS; else dpll |= DPLLB_MODE_DAC_SERIAL; if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { - dpll |= (crtc->config.pixel_multiplier - 1) + dpll |= (crtc->new_config->pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; } if (is_sdvo) dpll |= DPLL_SDVO_HIGH_SPEED; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ @@ -6068,21 +6086,21 @@ static void i9xx_update_pll(struct intel_crtc *crtc, if (INTEL_INFO(dev)->gen >= 4) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); - if (crtc->config.sdvo_tv_clock) + if (crtc->new_config->sdvo_tv_clock) dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; dpll |= DPLL_VCO_ENABLE; - crtc->config.dpll_hw_state.dpll = dpll; + crtc->new_config->dpll_hw_state.dpll = dpll; if (INTEL_INFO(dev)->gen >= 4) { - u32 dpll_md = (crtc->config.pixel_multiplier - 1) + u32 dpll_md = (crtc->new_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; - crtc->config.dpll_hw_state.dpll_md = dpll_md; + crtc->new_config->dpll_hw_state.dpll_md = dpll_md; } } @@ -6093,13 +6111,13 @@ static void i8xx_update_pll(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 dpll; - struct dpll *clock = &crtc->config.dpll; + struct dpll *clock = &crtc->new_config->dpll; i9xx_update_pll_dividers(crtc, reduced_clock); dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; } else { if (clock->p1 == 2) @@ -6110,17 +6128,17 @@ static void i8xx_update_pll(struct intel_crtc *crtc, dpll |= PLL_P2_DIVIDE_BY_4; } - if (!IS_I830(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO)) + if (!IS_I830(dev) && intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv) && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; dpll |= DPLL_VCO_ENABLE; - crtc->config.dpll_hw_state.dpll = dpll; + crtc->new_config->dpll_hw_state.dpll = dpll; } static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) @@ -6329,7 +6347,10 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, struct intel_encoder *encoder; const intel_limit_t *limit; - for_each_encoder_on_crtc(dev, &crtc->base, encoder) { + for_each_intel_encoder(dev, encoder) { + if (encoder->new_crtc != crtc) + continue; + switch (encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; @@ -6347,7 +6368,7 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, if (is_dsi) return 0; - if (!crtc->config.clock_set) { + if (!crtc->new_config->clock_set) { refclk = i9xx_get_refclk(crtc, num_connectors); /* @@ -6358,7 +6379,7 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, */ limit = intel_limit(crtc, refclk); ok = dev_priv->display.find_dpll(limit, crtc, - crtc->config.port_clock, + crtc->new_config->port_clock, refclk, NULL, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); @@ -6379,11 +6400,11 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, &reduced_clock); } /* Compat-code for transition, will disappear. */ - crtc->config.dpll.n = clock.n; - crtc->config.dpll.m1 = clock.m1; - crtc->config.dpll.m2 = clock.m2; - crtc->config.dpll.p1 = clock.p1; - crtc->config.dpll.p2 = clock.p2; + crtc->new_config->dpll.n = clock.n; + crtc->new_config->dpll.m1 = clock.m1; + crtc->new_config->dpll.m2 = clock.m2; + crtc->new_config->dpll.p1 = clock.p1; + crtc->new_config->dpll.p2 = clock.p2; } if (IS_GEN2(dev)) { @@ -6391,9 +6412,9 @@ static int i9xx_crtc_mode_set(struct intel_crtc *crtc, has_reduced_clock ? &reduced_clock : NULL, num_connectors); } else if (IS_CHERRYVIEW(dev)) { - chv_update_pll(crtc, &crtc->config); + chv_update_pll(crtc, crtc->new_config); } else if (IS_VALLEYVIEW(dev)) { - vlv_update_pll(crtc, &crtc->config); + vlv_update_pll(crtc, crtc->new_config); } else { i9xx_update_pll(crtc, has_reduced_clock ? &reduced_clock : NULL, @@ -7003,7 +7024,10 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) int num_connectors = 0; bool is_lvds = false; - for_each_encoder_on_crtc(dev, crtc, encoder) { + for_each_intel_encoder(dev, encoder) { + if (encoder->new_crtc != to_intel_crtc(crtc)) + continue; + switch (encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; @@ -7194,7 +7218,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, const intel_limit_t *limit; bool ret, is_lvds = false; - is_lvds = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_LVDS); + is_lvds = intel_pipe_will_have_type(intel_crtc, INTEL_OUTPUT_LVDS); refclk = ironlake_get_refclk(crtc); @@ -7205,7 +7229,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, */ limit = intel_limit(intel_crtc, refclk); ret = dev_priv->display.find_dpll(limit, intel_crtc, - intel_crtc->config.port_clock, + intel_crtc->new_config->port_clock, refclk, NULL, clock); if (!ret) return false; @@ -7255,7 +7279,10 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, int factor, num_connectors = 0; bool is_lvds = false, is_sdvo = false; - for_each_encoder_on_crtc(dev, crtc, intel_encoder) { + for_each_intel_encoder(dev, intel_encoder) { + if (intel_encoder->new_crtc != to_intel_crtc(crtc)) + continue; + switch (intel_encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; @@ -7278,10 +7305,10 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, dev_priv->vbt.lvds_ssc_freq == 100000) || (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev))) factor = 25; - } else if (intel_crtc->config.sdvo_tv_clock) + } else if (intel_crtc->new_config->sdvo_tv_clock) factor = 20; - if (ironlake_needs_fb_cb_tune(&intel_crtc->config.dpll, factor)) + if (ironlake_needs_fb_cb_tune(&intel_crtc->new_config->dpll, factor)) *fp |= FP_CB_TUNE; if (fp2 && (reduced_clock->m < factor * reduced_clock->n)) @@ -7294,20 +7321,20 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, else dpll |= DPLLB_MODE_DAC_SERIAL; - dpll |= (intel_crtc->config.pixel_multiplier - 1) + dpll |= (intel_crtc->new_config->pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; if (is_sdvo) dpll |= DPLL_SDVO_HIGH_SPEED; - if (intel_crtc->config.has_dp_encoder) + if (intel_crtc->new_config->has_dp_encoder) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ - dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + dpll |= (1 << (intel_crtc->new_config->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; /* also FPA1 */ - dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + dpll |= (1 << (intel_crtc->new_config->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - switch (intel_crtc->config.dpll.p2) { + switch (intel_crtc->new_config->dpll.p2) { case 5: dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; break; @@ -7348,22 +7375,22 @@ static int ironlake_crtc_mode_set(struct intel_crtc *crtc, ok = ironlake_compute_clocks(&crtc->base, &clock, &has_reduced_clock, &reduced_clock); - if (!ok && !crtc->config.clock_set) { + if (!ok && !crtc->new_config->clock_set) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; } /* Compat-code for transition, will disappear. */ - if (!crtc->config.clock_set) { - crtc->config.dpll.n = clock.n; - crtc->config.dpll.m1 = clock.m1; - crtc->config.dpll.m2 = clock.m2; - crtc->config.dpll.p1 = clock.p1; - crtc->config.dpll.p2 = clock.p2; + if (!crtc->new_config->clock_set) { + crtc->new_config->dpll.n = clock.n; + crtc->new_config->dpll.m1 = clock.m1; + crtc->new_config->dpll.m2 = clock.m2; + crtc->new_config->dpll.p1 = clock.p1; + crtc->new_config->dpll.p2 = clock.p2; } /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ - if (crtc->config.has_pch_encoder) { - fp = i9xx_dpll_compute_fp(&crtc->config.dpll); + if (crtc->new_config->has_pch_encoder) { + fp = i9xx_dpll_compute_fp(&crtc->new_config->dpll); if (has_reduced_clock) fp2 = i9xx_dpll_compute_fp(&reduced_clock); @@ -7371,12 +7398,12 @@ static int ironlake_crtc_mode_set(struct intel_crtc *crtc, &fp, &reduced_clock, has_reduced_clock ? &fp2 : NULL); - crtc->config.dpll_hw_state.dpll = dpll; - crtc->config.dpll_hw_state.fp0 = fp; + crtc->new_config->dpll_hw_state.dpll = dpll; + crtc->new_config->dpll_hw_state.fp0 = fp; if (has_reduced_clock) - crtc->config.dpll_hw_state.fp1 = fp2; + crtc->new_config->dpll_hw_state.fp1 = fp2; else - crtc->config.dpll_hw_state.fp1 = fp; + crtc->new_config->dpll_hw_state.fp1 = fp; pll = intel_get_shared_dpll(crtc); if (pll == NULL) { -- GitLab From a8f29e89f2b54fbf2c52be341f149bc195b63a8b Mon Sep 17 00:00:00 2001 From: Austin Lund Date: Thu, 24 Jul 2014 07:40:20 -0300 Subject: [PATCH 3061/9457] [media] media/rc: Send sync space information on the lirc device Userspace expects to see a long space before the first pulse is sent on the lirc device. Currently, if a long time has passed and a new packet is started, the lirc codec just returns and doesn't send anything. This makes lircd ignore many perfectly valid signals unless they are sent in quick sucession. When a reset event is delivered, we cannot know anything about the duration of the space. But it should be safe to assume it has been a long time and we just set the duration to maximum. Signed-off-by: Austin Lund Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-lirc-codec.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index ed2c8a1ed8ca..98893a8332c7 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) return -EINVAL; /* Packet start */ - if (ev.reset) - return 0; + if (ev.reset) { + /* Userspace expects a long space event before the start of + * the signal to use as a sync. This may be done with repeat + * packets and normal samples. But if a reset has been sent + * then we assume that a long time has passed, so we send a + * space with the maximum time value. */ + sample = LIRC_SPACE(LIRC_VALUE_MASK); + IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); /* Carrier reports */ - if (ev.carrier_report) { + } else if (ev.carrier_report) { sample = LIRC_FREQUENCY(ev.carrier); IR_dprintk(2, "carrier report (freq: %d)\n", sample); -- GitLab From 3cb9ae4fd82ebc9759bc59998c88c385d35496fe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 29 Oct 2014 10:03:57 +0100 Subject: [PATCH 3062/9457] drm: Move drm_crtc_init from drm_crtc.h to drm_plane_helper.h Just a bit of OCD cleanup on headers - this function isn't the core interface any more but just a helper for drivers who haven't yet transitioned to universal planes. Put the declaration at the right spot and sprinkle necessary #includes over all drivers. Maybe this helps to encourage driver maintainers to do the switch. v2: Fix #include ordering for tegra, reported by 0-day builder. v3: Include required headers, reported by Thierry. Cc: Matt Roper Cc: Thierry Reding Reviewed-by: Matt Roper Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/armada/armada_crtc.c | 1 + drivers/gpu/drm/ast/ast_mode.c | 1 + drivers/gpu/drm/bochs/bochs_kms.c | 1 + drivers/gpu/drm/cirrus/cirrus_mode.c | 1 + drivers/gpu/drm/gma500/psb_intel_display.c | 1 + drivers/gpu/drm/mgag200/mgag200_mode.c | 1 + drivers/gpu/drm/nouveau/dispnv04/crtc.c | 1 + drivers/gpu/drm/nouveau/nv50_display.c | 1 + drivers/gpu/drm/omapdrm/omap_crtc.c | 1 + drivers/gpu/drm/qxl/qxl_display.c | 1 + drivers/gpu/drm/radeon/radeon_display.c | 1 + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 + drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 1 + drivers/gpu/drm/sti/sti_drm_crtc.c | 1 + drivers/gpu/drm/tegra/dc.c | 2 ++ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 1 + drivers/gpu/drm/udl/udl_modeset.c | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 1 + drivers/staging/imx-drm/imx-drm-core.c | 1 + include/drm/drm_crtc.h | 3 --- include/drm/drm_plane_helper.h | 5 +++++ 22 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 9a0cc09e6653..0b164fb1c107 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "armada_crtc.h" #include "armada_drm.h" #include "armada_fb.h" diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 9dc0fd5c1ea4..b7ee2634e47c 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "ast_drv.h" #include "ast_tables.h" diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 6b7efcf363d6..5ffd4895d040 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -6,6 +6,7 @@ */ #include "bochs.h" +#include static int defx = 1024; static int defy = 768; diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index c7c5a9d91fa0..99d4a74ffeaf 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -16,6 +16,7 @@ */ #include #include +#include #include diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2c38bda217ec..2b1db0c12fdc 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -32,6 +32,27 @@ #include #include +/** + * DOC: overview + * + * This helper library provides implementations of check and commit functions on + * top of the CRTC modeset helper callbacks and the plane helper callbacks. It + * also provides convenience implementations for the atomic state handling + * callbacks for drivers which don't need to subclass the drm core structures to + * add their own additional internal state. + * + * This library also provides default implementations for the check callback in + * drm_atomic_helper_check and for the commit callback with + * drm_atomic_helper_commit. But the individual stages and callbacks are expose + * to allow drivers to mix and match and e.g. use the plane helpers only + * together with a driver private modeset implementation. + * + * This library also provides implementations for all the legacy driver + * interfaces on top of the atomic interface. See drm_atomic_helper_set_config, + * drm_atomic_helper_disable_plane, drm_atomic_helper_disable_plane and the + * various functions to implement set_property callbacks. New drivers must not + * implement these functions themselves but must use the provided helpers. + */ static void drm_atomic_helper_plane_changed(struct drm_atomic_state *state, struct drm_plane_state *plane_state, @@ -1707,6 +1728,21 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, } EXPORT_SYMBOL(drm_atomic_helper_page_flip); +/** + * DOC: atomic state reset and initialization + * + * Both the drm core and the atomic helpers assume that there is always the full + * and correct atomic software state for all connectors, CRTCs and planes + * available. Which is a bit a problem on driver load and also after system + * suspend. One way to solve this is to have a hardware state read-out + * infrastructure which reconstructs the full software state (e.g. the i915 + * driver). + * + * The simpler solution is to just reset the software state to everything off, + * which is easiest to do by calling drm_mode_config_reset(). To facilitate this + * the atomic helpers provide default reset implementations for all hooks. + */ + /** * drm_atomic_helper_crtc_reset - default ->reset hook for CRTCs * @crtc: drm CRTC diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 46728a8ac622..33195e9adaab 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -41,6 +41,26 @@ #include #include +/** + * DOC: overview + * + * The CRTC modeset helper library provides a default set_config implementation + * in drm_crtc_helper_set_config(). Plus a few other convenience functions using + * the same callbacks which drivers can use to e.g. restore the modeset + * configuration on resume with drm_helper_resume_force_mode(). + * + * The driver callbacks are mostly compatible with the atomic modeset helpers, + * except for the handling of the primary plane: Atomic helpers require that the + * primary plane is implemented as a real standalone plane and not directly tied + * to the CRTC state. For easier transition this library provides functions to + * implement the old semantics required by the CRTC helpers using the new plane + * and atomic helper callbacks. + * + * Drivers are strongly urged to convert to the atomic helpers (by way of first + * converting to the plane helpers). New drivers must not use these functions + * but need to implement the atomic interface instead, potentially using the + * atomic helpers for that. + */ MODULE_AUTHOR("David Airlie, Jesse Barnes"); MODULE_DESCRIPTION("DRM KMS helper"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index a5a295872fbb..fa56bb5da6c3 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -31,6 +31,32 @@ #define SUBPIXEL_MASK 0xffff +/** + * DOC: overview + * + * This helper library has two parts. The first part has support to implement + * primary plane support on top of the normal CRTC configuration interface. + * Since the legacy ->set_config interface ties the primary plane together with + * the CRTC state this does not allow userspace to disable the primary plane + * itself. To avoid too much duplicated code use + * drm_plane_helper_check_update() which can be used to enforce the same + * restrictions as primary planes had thus. The default primary plane only + * expose XRBG8888 and ARGB8888 as valid pixel formats for the attached + * framebuffer. + * + * Drivers are highly recommended to implement proper support for primary + * planes, and newly merged drivers must not rely upon these transitional + * helpers. + * + * The second part also implements transitional helpers which allow drivers to + * gradually switch to the atomic helper infrastructure for plane updates. Once + * that switch is complete drivers shouldn't use these any longer, instead using + * the proper legacy implementations for update and disable plane hooks provided + * by the atomic helpers. + * + * Again drivers are strongly urged to switch to the new interfaces. + */ + /* * This is the minimal list of formats that seem to be safe for modeset use * with all current DRM drivers. Most hardware can actually support more -- GitLab From 321ebf04dc7ab5c54d658f93db0ffe35277664ab Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 4 Nov 2014 22:57:27 +0100 Subject: [PATCH 3497/9457] drm/atomic: Refcounting for plane_state->fb So my original plan was that the drm core refcounts framebuffers like with the legacy ioctls. But that doesn't work for a bunch of reasons: - State objects might live longer than until the next fb change happens for a plane. For example delayed cleanup work only happens _after_ the pageflip ioctl has completed. So this definitely doesn't work without the plane state holding its own references. - The other issue is transition from legacy to atomic implementations, where the driver works under a mix of both worlds. Which means legacy paths might not properly update the ->fb pointer under plane->state->fb. Which is a bit a problem when then someone comes around and _does_ try to clean it up when it's long gone. The second issue is just a bit a transition bug, since drivers should update plane->state->fb in all the paths that aren't converted yet. But a bit more robustness for the transition can't hurt - we pull similar tricks with cleaning up the old fb in the transitional helpers already. The pattern for drivers that transition is if (plane->state) drm_atomic_set_fb_for_plane(plane->state, plane->fb); inserted after the fb update has logically completed at the end of ->set_config (or ->set_base/mode_set if using the crtc helpers), ->page_flip, ->update_plane or any other entry point which updates plane->fb. v2: Update kerneldoc - copypasta fail. v3: Fix spelling in the commit message (Sean). Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 28 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_atomic_helper.c | 25 +++++++++++++++++++------ drivers/gpu/drm/drm_crtc_helper.c | 7 ++++--- drivers/gpu/drm/drm_plane_helper.c | 14 +++++++------- include/drm/drm_atomic.h | 2 ++ 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index ad15a88c0f74..ed991ba66e21 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -367,6 +367,34 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, } EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane); +/** + * drm_atomic_set_fb_for_plane - set crtc for plane + * @plane_state: atomic state object for the plane + * @fb: fb to use for the plane + * + * Changing the assigned framebuffer for a plane requires us to grab a reference + * to the new fb and drop the reference to the old fb, if there is one. This + * function takes care of all these details besides updating the pointer in the + * state object itself. + */ +void +drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb) +{ + if (plane_state->fb) + drm_framebuffer_unreference(plane_state->fb); + if (fb) + drm_framebuffer_reference(fb); + plane_state->fb = fb; + + if (fb) + DRM_DEBUG_KMS("Set [FB:%d] for plane state %p\n", + fb->base.id, plane_state); + else + DRM_DEBUG_KMS("Set [NOFB] for plane state %p\n", plane_state); +} +EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); + /** * drm_atomic_set_crtc_for_connector - set crtc for connector * @conn_state: atomic state object for the connector diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2b1db0c12fdc..ca839bd9bb0d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1182,7 +1182,7 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane, ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); if (ret != 0) goto fail; - plane_state->fb = fb; + drm_atomic_set_fb_for_plane(plane_state, fb); plane_state->crtc_x = crtc_x; plane_state->crtc_y = crtc_y; plane_state->crtc_h = crtc_h; @@ -1250,7 +1250,7 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane) ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); if (ret != 0) goto fail; - plane_state->fb = NULL; + drm_atomic_set_fb_for_plane(plane_state, NULL); plane_state->crtc_x = 0; plane_state->crtc_y = 0; plane_state->crtc_h = 0; @@ -1422,7 +1422,7 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set) ret = drm_atomic_set_crtc_for_plane(primary_state, crtc); if (ret != 0) goto fail; - primary_state->fb = set->fb; + drm_atomic_set_fb_for_plane(primary_state, set->fb); primary_state->crtc_x = 0; primary_state->crtc_y = 0; primary_state->crtc_h = set->mode->vdisplay; @@ -1694,7 +1694,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); if (ret != 0) goto fail; - plane_state->fb = fb; + drm_atomic_set_fb_for_plane(plane_state, fb); ret = drm_atomic_async_commit(state); if (ret != 0) @@ -1808,6 +1808,9 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); */ void drm_atomic_helper_plane_reset(struct drm_plane *plane) { + if (plane->state && plane->state->fb) + drm_framebuffer_unreference(plane->state->fb); + kfree(plane->state); plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); } @@ -1823,10 +1826,17 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_reset); struct drm_plane_state * drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) { + struct drm_plane_state *state; + if (WARN_ON(!plane->state)) return NULL; - return kmemdup(plane->state, sizeof(*plane->state), GFP_KERNEL); + state = kmemdup(plane->state, sizeof(*plane->state), GFP_KERNEL); + + if (state && state->fb) + drm_framebuffer_reference(state->fb); + + return state; } EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); @@ -1839,8 +1849,11 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); * subclassed plane state structure. */ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_plane_state *state) { + if (state->fb) + drm_framebuffer_unreference(state->fb); + kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 33195e9adaab..d552708409de 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -34,11 +34,13 @@ #include #include +#include #include #include #include #include #include +#include #include /** @@ -998,15 +1000,14 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, if (plane->funcs->atomic_duplicate_state) plane_state = plane->funcs->atomic_duplicate_state(plane); else if (plane->state) - plane_state = kmemdup(plane->state, sizeof(*plane_state), - GFP_KERNEL); + plane_state = drm_atomic_helper_plane_duplicate_state(plane); else plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); if (!plane_state) return -ENOMEM; plane_state->crtc = crtc; - plane_state->fb = crtc->primary->fb; + drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb); plane_state->crtc_x = 0; plane_state->crtc_y = 0; plane_state->crtc_h = crtc->mode.vdisplay; diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index fa56bb5da6c3..d99c452b0563 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include #define SUBPIXEL_MASK 0xffff @@ -464,7 +466,7 @@ int drm_plane_helper_commit(struct drm_plane *plane, if (plane->funcs->atomic_destroy_state) plane->funcs->atomic_destroy_state(plane, plane_state); else - kfree(plane_state); + drm_atomic_helper_plane_destroy_state(plane, plane_state); } return ret; @@ -505,15 +507,14 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, if (plane->funcs->atomic_duplicate_state) plane_state = plane->funcs->atomic_duplicate_state(plane); else if (plane->state) - plane_state = kmemdup(plane->state, sizeof(*plane_state), - GFP_KERNEL); + plane_state = drm_atomic_helper_plane_duplicate_state(plane); else plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); if (!plane_state) return -ENOMEM; plane_state->crtc = crtc; - plane_state->fb = fb; + drm_atomic_set_fb_for_plane(plane_state, fb); plane_state->crtc_x = crtc_x; plane_state->crtc_y = crtc_y; plane_state->crtc_h = crtc_h; @@ -552,15 +553,14 @@ int drm_plane_helper_disable(struct drm_plane *plane) if (plane->funcs->atomic_duplicate_state) plane_state = plane->funcs->atomic_duplicate_state(plane); else if (plane->state) - plane_state = kmemdup(plane->state, sizeof(*plane_state), - GFP_KERNEL); + plane_state = drm_atomic_helper_plane_duplicate_state(plane); else plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); if (!plane_state) return -ENOMEM; plane_state->crtc = NULL; - plane_state->fb = NULL; + drm_atomic_set_fb_for_plane(plane_state, NULL); return drm_plane_helper_commit(plane, plane_state, plane->fb); } diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 5bb15f550c42..9d919168bc11 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -46,6 +46,8 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, int __must_check drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, struct drm_crtc *crtc); +void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb); int __must_check drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc); -- GitLab From cbffccc970394f82e397fccbeb136eeaffb3c552 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 5 Nov 2014 14:39:21 -0800 Subject: [PATCH 3498/9457] net; ipv[46] - Remove 2 unnecessary NETDEBUG OOM messages These messages aren't useful as there's a generic dump_stack() on OOM. Neaten the comment and if test above the OOM by separating the assign in if into an allocation then if test. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 8 +++----- net/ipv6/ip6_output.c | 10 ++++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index bc6471d4abcd..4a929adf2ab7 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -662,12 +662,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) if (len < left) { len &= ~7; } - /* - * Allocate buffer. - */ - if ((skb2 = alloc_skb(len+hlen+ll_rs, GFP_ATOMIC)) == NULL) { - NETDEBUG(KERN_INFO "IP: frag: no memory for new fragment!\n"); + /* Allocate buffer */ + skb2 = alloc_skb(len + hlen + ll_rs, GFP_ATOMIC); + if (!skb2) { err = -ENOMEM; goto fail; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 8e950c250ada..916d2a166a9b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -747,13 +747,11 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) if (len < left) { len &= ~7; } - /* - * Allocate buffer. - */ - if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + - hroom + troom, GFP_ATOMIC)) == NULL) { - NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); + /* Allocate buffer */ + frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + + hroom + troom, GFP_ATOMIC); + if (!frag) { IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); err = -ENOMEM; -- GitLab From 450834977796cc74d1265d7dfe69cf6767537dfc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 5 Nov 2014 15:36:08 -0800 Subject: [PATCH 3499/9457] net: esp: Convert NETDEBUG to pr_info Commit 64ce207306de ("[NET]: Make NETDEBUG pure printk wrappers") originally had these NETDEBUG printks as always emitting. Commit a2a316fd068c ("[NET]: Replace CONFIG_NET_DEBUG with sysctl") added a net_msg_warn sysctl to these NETDEBUG uses. Convert these NETDEBUG uses to normal pr_info calls. This changes the output prefix from "ESP: " to include "IPSec: " for the ipv4 case and "IPv6: " for the ipv6 case. These output lines are now like the other messages in the files. Other miscellanea: Neaten the arithmetic spacing to be consistent with other arithmetic spacing in the files. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/esp4.c | 10 +++++----- net/ipv6/esp6.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index d2bf02e0a678..60173d4d3a0e 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -603,12 +603,12 @@ static int esp_init_authenc(struct xfrm_state *x) BUG_ON(!aalg_desc); err = -EINVAL; - if (aalg_desc->uinfo.auth.icv_fullbits/8 != + if (aalg_desc->uinfo.auth.icv_fullbits / 8 != crypto_aead_authsize(aead)) { - NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", - x->aalg->alg_name, - crypto_aead_authsize(aead), - aalg_desc->uinfo.auth.icv_fullbits/8); + pr_info("ESP: %s digestsize %u != %hu\n", + x->aalg->alg_name, + crypto_aead_authsize(aead), + aalg_desc->uinfo.auth.icv_fullbits / 8); goto free_key; } diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 83fc3a385a26..d21d7b22eebc 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -544,12 +544,12 @@ static int esp_init_authenc(struct xfrm_state *x) BUG_ON(!aalg_desc); err = -EINVAL; - if (aalg_desc->uinfo.auth.icv_fullbits/8 != + if (aalg_desc->uinfo.auth.icv_fullbits / 8 != crypto_aead_authsize(aead)) { - NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", - x->aalg->alg_name, - crypto_aead_authsize(aead), - aalg_desc->uinfo.auth.icv_fullbits/8); + pr_info("ESP: %s digestsize %u != %hu\n", + x->aalg->alg_name, + crypto_aead_authsize(aead), + aalg_desc->uinfo.auth.icv_fullbits / 8); goto free_key; } -- GitLab From 926c512685ddd8f26f1c789218391530ccd54a35 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 5 Nov 2014 15:42:09 -0800 Subject: [PATCH 3500/9457] sock.h: Remove unused NETDEBUG macro It's unused now, just delete it. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/sock.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 7db3db112baa..6767d75ecb17 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2280,9 +2280,6 @@ bool sk_net_capable(const struct sock *sk, int cap); * Enable debug/info messages */ extern int net_msg_warn; -#define NETDEBUG(fmt, args...) \ - do { if (net_msg_warn) printk(fmt,##args); } while (0) - #define LIMIT_NETDEBUG(fmt, args...) \ do { if (net_msg_warn && net_ratelimit()) printk(fmt,##args); } while(0) -- GitLab From 747029a566e5d637ef4972afd2cb7202f7b7ca7c Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 6 Nov 2014 19:46:50 +0100 Subject: [PATCH 3501/9457] ipv4: add kernel parameter tcpmhash_entries This patch also adds a reference to ip-sysctl.txt where TCP metrics setup is described Signed-off-by: Fabian Frederick Signed-off-by: Jonathan Corbet --- Documentation/kernel-parameters.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4c81a860cc2b..e8066db54d3d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3412,6 +3412,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. neutralize any effect of /proc/sys/kernel/sysrq. Useful for debugging. + tcpmhash_entries= [KNL,NET] + Set the number of tcp_metrics_hash slots. + Default value is 8192 or 16384 depending on total + ram pages. This is used to specify the TCP metrics + cache size. See Documentation/networking/ip-sysctl.txt + "tcp_no_metrics_save" section for more details. + tdfx= [HW,DRM] test_suspend= [SUSPEND][,N] -- GitLab From c0d7305cb3e5e77dba822706e21898314e893fb7 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 7 Nov 2014 00:31:15 +0900 Subject: [PATCH 3502/9457] Documentation: vm: Add 1GB large page support information This patch adds 1GB large page support information in Documentation/vm/hugetlbpage.txt Reference: https://lkml.org/lkml/2014/10/31/366 Signed-off-by: Masanari Iida Reviewed-by: Luiz Capitulino Signed-off-by: Jonathan Corbet --- Documentation/vm/hugetlbpage.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index b64e0af9cc56..f2d3a100fe38 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt @@ -1,8 +1,8 @@ The intent of this file is to give a brief summary of hugetlbpage support in the Linux kernel. This support is built on top of multiple page size support -that is provided by most modern architectures. For example, i386 -architecture supports 4K and 4M (2M in PAE mode) page sizes, ia64 +that is provided by most modern architectures. For example, x86 CPUs normally +support 4K and 2M (1G if architecturally supported) page sizes, ia64 architecture supports multiple page sizes 4K, 8K, 64K, 256K, 1M, 4M, 16M, 256M and ppc64 supports 4K and 16M. A TLB is a cache of virtual-to-physical translations. Typically this is a very scarce resource on processor. -- GitLab From 82cf94cbcf95356ba9ba8c2533291a7792bbe5e7 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 6 Nov 2014 12:47:38 +0800 Subject: [PATCH 3503/9457] r8152: move r8152b_get_version Move r8152b_get_version() to the location before rtl_ops_init(). Then, the rtl_ops_init() could use tp->version. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index fd41675bc038..4b6db8afea71 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3833,6 +3833,7 @@ static int rtl8152_probe(struct usb_interface *intf, tp->netdev = netdev; tp->intf = intf; + r8152b_get_version(tp); ret = rtl_ops_init(tp, id); if (ret) goto out; @@ -3866,11 +3867,9 @@ static int rtl8152_probe(struct usb_interface *intf, tp->mii.phy_id_mask = 0x3f; tp->mii.reg_num_mask = 0x1f; tp->mii.phy_id = R8152_PHY_ID; - tp->mii.supports_gmii = 0; intf->needs_remote_wakeup = 1; - r8152b_get_version(tp); tp->rtl_ops.init(tp); set_ethernet_addr(tp); -- GitLab From 55b6547547f9a6719b62fb07d656863142e028a8 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 6 Nov 2014 12:47:39 +0800 Subject: [PATCH 3504/9457] r8152: modify rtl_ops_init Replace using VID/PID with using tp->version to initialize the ops. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 79 +++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 4b6db8afea71..cf1b8a7a4c77 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3742,66 +3742,43 @@ static void rtl8153_unload(struct r8152 *tp) r8153_power_cut_en(tp, false); } -static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id) +static int rtl_ops_init(struct r8152 *tp) { struct rtl_ops *ops = &tp->rtl_ops; - int ret = -ENODEV; - - switch (id->idVendor) { - case VENDOR_ID_REALTEK: - switch (id->idProduct) { - case PRODUCT_ID_RTL8152: - ops->init = r8152b_init; - ops->enable = rtl8152_enable; - ops->disable = rtl8152_disable; - ops->up = rtl8152_up; - ops->down = rtl8152_down; - ops->unload = rtl8152_unload; - ops->eee_get = r8152_get_eee; - ops->eee_set = r8152_set_eee; - ret = 0; - break; - case PRODUCT_ID_RTL8153: - ops->init = r8153_init; - ops->enable = rtl8153_enable; - ops->disable = rtl8153_disable; - ops->up = rtl8153_up; - ops->down = rtl8153_down; - ops->unload = rtl8153_unload; - ops->eee_get = r8153_get_eee; - ops->eee_set = r8153_set_eee; - ret = 0; - break; - default: - break; - } + int ret = 0; + + switch (tp->version) { + case RTL_VER_01: + case RTL_VER_02: + ops->init = r8152b_init; + ops->enable = rtl8152_enable; + ops->disable = rtl8152_disable; + ops->up = rtl8152_up; + ops->down = rtl8152_down; + ops->unload = rtl8152_unload; + ops->eee_get = r8152_get_eee; + ops->eee_set = r8152_set_eee; break; - case VENDOR_ID_SAMSUNG: - switch (id->idProduct) { - case PRODUCT_ID_SAMSUNG: - ops->init = r8153_init; - ops->enable = rtl8153_enable; - ops->disable = rtl8153_disable; - ops->up = rtl8153_up; - ops->down = rtl8153_down; - ops->unload = rtl8153_unload; - ops->eee_get = r8153_get_eee; - ops->eee_set = r8153_set_eee; - ret = 0; - break; - default: - break; - } + case RTL_VER_03: + case RTL_VER_04: + case RTL_VER_05: + ops->init = r8153_init; + ops->enable = rtl8153_enable; + ops->disable = rtl8153_disable; + ops->up = rtl8153_up; + ops->down = rtl8153_down; + ops->unload = rtl8153_unload; + ops->eee_get = r8153_get_eee; + ops->eee_set = r8153_set_eee; break; default: + ret = -ENODEV; + netif_err(tp, probe, tp->netdev, "Unknown Device\n"); break; } - if (ret) - netif_err(tp, probe, tp->netdev, "Unknown Device\n"); - return ret; } @@ -3834,7 +3811,7 @@ static int rtl8152_probe(struct usb_interface *intf, tp->intf = intf; r8152b_get_version(tp); - ret = rtl_ops_init(tp, id); + ret = rtl_ops_init(tp); if (ret) goto out; -- GitLab From 662412d14bfa6a672626e4470cab73b75c8b42f0 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 6 Nov 2014 12:47:40 +0800 Subject: [PATCH 3505/9457] r8152: remove the definitions of the PID The PIDs are only used in the id table, so the definitions are unnacessary. Remove them wouldn't have confusion. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index cf1b8a7a4c77..66b139a8b6ca 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -461,11 +461,7 @@ enum rtl8152_flags { /* Define these values to match your device */ #define VENDOR_ID_REALTEK 0x0bda -#define PRODUCT_ID_RTL8152 0x8152 -#define PRODUCT_ID_RTL8153 0x8153 - #define VENDOR_ID_SAMSUNG 0x04e8 -#define PRODUCT_ID_SAMSUNG 0xa101 #define MCU_TYPE_PLA 0x0100 #define MCU_TYPE_USB 0x0000 @@ -3898,9 +3894,9 @@ static void rtl8152_disconnect(struct usb_interface *intf) /* table of devices that work with this driver */ static struct usb_device_id rtl8152_table[] = { - {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, - {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, - {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, + {USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)}, + {USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, + {USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, {} }; -- GitLab From 6c3ce8a30c1bafa8952461fb76e66e2da338b7ed Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Thu, 6 Nov 2014 14:51:02 -0500 Subject: [PATCH 3506/9457] sunvnet: Fix indentation in maybe_tx_wakeup() remove redundant tab. Signed-off-by: Sowmini Varadhan Reported-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index e7bb63b2d525..2688b19a6e63 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -627,7 +627,7 @@ static void maybe_tx_wakeup(struct vnet_port *port) struct vio_dring_state *dr; dr = &port->vio.drings[VIO_DRIVER_TX_RING]; - netif_tx_wake_queue(txq); + netif_tx_wake_queue(txq); } __netif_tx_unlock(txq); } -- GitLab From 8c4ee3e70646d6bfdda55afe84016b914c7fdd0e Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Thu, 6 Nov 2014 14:51:08 -0500 Subject: [PATCH 3507/9457] sunvnet: Return from vnet_napi_event() if no packets to read vnet_event_napi() may be called as part of the NAPI ->poll, to resume reading descriptor rings. When no data is available, descriptor ring state (e.g., rcv_nxt) needs to be reset carefully to stay in lock-step with ldc_read(). In the interest of simplicity, the best way to do this is to return from vnet_event_napi() when there are no more packets to read. The next trip through ldc_rx will correctly set up the dring state. Signed-off-by: Sowmini Varadhan Tested-by: David Stevens Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 2688b19a6e63..5c5fb59adf76 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -691,7 +691,6 @@ static int vnet_event_napi(struct vnet_port *port, int budget) pkt->end_idx = -1; goto napi_resume; } -ldc_read: err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf)); if (unlikely(err < 0)) { if (err == -ECONNRESET) @@ -722,8 +721,8 @@ static int vnet_event_napi(struct vnet_port *port, int budget) err = vnet_rx(port, &msgbuf, &npkts, budget); if (npkts >= budget) break; - if (npkts == 0 && err != -ECONNRESET) - goto ldc_read; + if (npkts == 0) + break; } else if (msgbuf.tag.stype == VIO_SUBTYPE_ACK) { err = vnet_ack(port, &msgbuf); if (err > 0) -- GitLab From ec98a4975e66a3aa366cd227edab027b01adea37 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Nov 2014 12:23:23 +0100 Subject: [PATCH 3508/9457] leds: leds-gpio: Fix legacy GPIO number case In the legacy case, led_dat->gpiod is initialized correctly, but overwritten later by template->gpiod, which is NULL, causing leds-gpio to fail with: gpiod_direction_output: invalid GPIO leds-gpio: probe of leds-gpio failed with error -22 Move the initialization of led_dat->gpiod from template->gpiod up, and always use led_dat->gpiod later, to fix this. Fixes: 5c51277a9ababfa4 (leds: leds-gpio: Add support for GPIO descriptors) Signed-off-by: Geert Uytterhoeven Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/leds/leds-gpio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index ba4698c32bb0..b3c5d9d6a42b 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -92,7 +92,8 @@ static int create_gpio_led(const struct gpio_led *template, { int ret, state; - if (!template->gpiod) { + led_dat->gpiod = template->gpiod; + if (!led_dat->gpiod) { /* * This is the legacy code path for platform code that * still uses GPIO numbers. Ultimately we would like to get @@ -122,8 +123,7 @@ static int create_gpio_led(const struct gpio_led *template, led_dat->cdev.name = template->name; led_dat->cdev.default_trigger = template->default_trigger; - led_dat->gpiod = template->gpiod; - led_dat->can_sleep = gpiod_cansleep(template->gpiod); + led_dat->can_sleep = gpiod_cansleep(led_dat->gpiod); led_dat->blinking = 0; if (blink_set) { led_dat->platform_gpio_blink_set = blink_set; -- GitLab From 56b2c3eea398c772dd895dc62c18cbdd1ba127b1 Mon Sep 17 00:00:00 2001 From: Martin Townsend Date: Thu, 6 Nov 2014 19:15:13 +0000 Subject: [PATCH 3509/9457] 6lowpan: move skb_free from error paths in decompression Currently we ensure that the skb is freed on every error path in IPHC decompression which makes it easy to introduce skb leaks. By centralising the skb_free into the receive function it makes future decompression routines easier to maintain. It does come at the expense of ensuring that the skb passed into the decompression routine must not be copied. Signed-off-by: Martin Townsend Acked-by: Jukka Rissanen Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/6lowpan/iphc.c | 31 ++++++++++++------------------- net/bluetooth/6lowpan.c | 15 +++++++-------- net/ieee802154/6lowpan_rtnl.c | 16 ++++++---------- 3 files changed, 25 insertions(+), 37 deletions(-) diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index cd5f8b8e34cd..aced97db62f0 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -319,7 +319,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, if (iphc1 & LOWPAN_IPHC_CID) { pr_debug("CID flag is set, increase header with one\n"); if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context))) - goto drop; + return -EINVAL; } hdr.version = 6; @@ -331,7 +331,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, */ case 0: /* 00b */ if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) - goto drop; + return -EINVAL; memcpy(&hdr.flow_lbl, &skb->data[0], 3); skb_pull(skb, 3); @@ -344,7 +344,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, */ case 2: /* 10b */ if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) - goto drop; + return -EINVAL; hdr.priority = ((tmp >> 2) & 0x0f); hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); @@ -354,7 +354,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, */ case 1: /* 01b */ if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) - goto drop; + return -EINVAL; hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); @@ -371,7 +371,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr))) - goto drop; + return -EINVAL; pr_debug("NH flag is set, next header carried inline: %02x\n", hdr.nexthdr); @@ -383,7 +383,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, } else { if (lowpan_fetch_skb(skb, &hdr.hop_limit, sizeof(hdr.hop_limit))) - goto drop; + return -EINVAL; } /* Extract SAM to the tmp variable */ @@ -402,7 +402,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, /* Check on error of previous branch */ if (err) - goto drop; + return -EINVAL; /* Extract DAM to the tmp variable */ tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; @@ -417,7 +417,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, tmp); if (err) - goto drop; + return -EINVAL; } } else { err = uncompress_addr(skb, &hdr.daddr, tmp, daddr, @@ -425,7 +425,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, pr_debug("dest: stateless compression mode %d dest %pI6c\n", tmp, &hdr.daddr); if (err) - goto drop; + return -EINVAL; } /* UDP data uncompression */ @@ -434,16 +434,14 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, const int needed = sizeof(struct udphdr) + sizeof(hdr); if (uncompress_udp_header(skb, &uh)) - goto drop; + return -EINVAL; /* replace the compressed UDP head by the uncompressed UDP * header */ err = skb_cow(skb, needed); - if (unlikely(err)) { - kfree_skb(skb); + if (unlikely(err)) return err; - } skb_push(skb, sizeof(struct udphdr)); skb_reset_transport_header(skb); @@ -455,10 +453,8 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, hdr.nexthdr = UIP_PROTO_UDP; } else { err = skb_cow(skb, sizeof(hdr)); - if (unlikely(err)) { - kfree_skb(skb); + if (unlikely(err)) return err; - } } hdr.payload_len = htons(skb->len); @@ -478,9 +474,6 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); return 0; -drop: - kfree_skb(skb); - return -EINVAL; } EXPORT_SYMBOL_GPL(lowpan_header_decompress); diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index eef298d17452..dc23c55f1ab6 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -294,20 +294,20 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, peer = __peer_lookup_chan(dev, chan); rcu_read_unlock(); if (!peer) - goto drop; + return -EINVAL; saddr = peer->eui64_addr; daddr = dev->netdev->dev_addr; /* at least two bytes will be used for the encoding */ if (skb->len < 2) - goto drop; + return -EINVAL; if (lowpan_fetch_skb_u8(skb, &iphc0)) - goto drop; + return -EINVAL; if (lowpan_fetch_skb_u8(skb, &iphc1)) - goto drop; + return -EINVAL; return lowpan_header_decompress(skb, netdev, saddr, IEEE802154_ADDR_LONG, @@ -315,9 +315,6 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, iphc0, iphc1); -drop: - kfree_skb(skb); - return -EINVAL; } static int recv_pkt(struct sk_buff *skb, struct net_device *dev, @@ -370,8 +367,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, goto drop; ret = iphc_decompress(local_skb, dev, chan); - if (ret < 0) + if (ret < 0) { + kfree_skb(local_skb); goto drop; + } local_skb->protocol = htons(ETH_P_IPV6); local_skb->pkt_type = PACKET_HOST; diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index a96b64c9a73d..290e14f2e92e 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -176,13 +176,13 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); /* at least two bytes will be used for the encoding */ if (skb->len < 2) - goto drop; + return -EINVAL; if (lowpan_fetch_skb_u8(skb, &iphc0)) - goto drop; + return -EINVAL; if (lowpan_fetch_skb_u8(skb, &iphc1)) - goto drop; + return -EINVAL; ieee802154_addr_to_sa(&sa, &hdr->source); ieee802154_addr_to_sa(&da, &hdr->dest); @@ -200,10 +200,6 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr) return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, IEEE802154_ADDR_LEN, dap, da.addr_type, IEEE802154_ADDR_LEN, iphc0, iphc1); - -drop: - kfree_skb(skb); - return -EINVAL; } static struct sk_buff* @@ -522,7 +518,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ ret = iphc_decompress(skb, &hdr); if (ret < 0) - goto drop; + goto drop_skb; return lowpan_give_skb_to_devices(skb, NULL); case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ @@ -530,7 +526,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, if (ret == 1) { ret = iphc_decompress(skb, &hdr); if (ret < 0) - goto drop; + goto drop_skb; return lowpan_give_skb_to_devices(skb, NULL); } else if (ret == -1) { @@ -543,7 +539,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, if (ret == 1) { ret = iphc_decompress(skb, &hdr); if (ret < 0) - goto drop; + goto drop_skb; return lowpan_give_skb_to_devices(skb, NULL); } else if (ret == -1) { -- GitLab From 63692df103e9c76b26c382ce8079283b7df9a99a Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 23 Oct 2014 14:22:12 -0400 Subject: [PATCH 3510/9457] PCI: Allow numa_node override via sysfs NUMA systems with ACPI normally describe the physical topology via _PXM methods. But many BIOSes don't implement _PXM, which leaves the kernel with no way to discover the device topology, which reduces performance because we can't put memory and processes close to the device. The NUMA node of a PCI device is already exported in the sysfs "numa_node" file. Make that file writable so users can workaround the lack of _PXM methods in the BIOS. For example: echo 3 > /sys/devices/pci0000:ff/0000:03:1f.3/numa_node sets the node for PCI device 0000:03:1f.3. Writing the file emits a FW_BUG warning to encourage users to request firmware updates. It also taints the kernel with TAINT_FIRMWARE_WORKAROUND because overriding the node incorrectly can cause performance issues. [bhelgaas: changelog, documentation text] Signed-off-by: Prarit Bhargava Signed-off-by: Bjorn Helgaas CC: Myron Stowe CC: Alexander Ducyk CC: Jiang Liu --- Documentation/ABI/testing/sysfs-bus-pci | 13 ++++++++++++ drivers/pci/pci-sysfs.c | 27 ++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index ee6c04036492..b3bc50f650ee 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -281,3 +281,16 @@ Description: opt-out of driver binding using a driver_override name such as "none". Only a single driver may be specified in the override, there is no support for parsing delimiters. + +What: /sys/bus/pci/devices/.../numa_node +Date: Oct 2014 +Contact: Prarit Bhargava +Description: + This file contains the NUMA node to which the PCI device is + attached, or -1 if the node is unknown. The initial value + comes from an ACPI _PXM method or a similar firmware + source. If that is missing or incorrect, this file can be + written to override the node. In that case, please report + a firmware bug to the system vendor. Writing to this file + taints the kernel with TAINT_FIRMWARE_WORKAROUND, which + reduces the supportability of your system. diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 92b6d9ab00e4..91e760f9655b 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -221,12 +221,37 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(enabled); #ifdef CONFIG_NUMA +static ssize_t numa_node_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int node, ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + ret = kstrtoint(buf, 0, &node); + if (ret) + return ret; + + if (!node_online(node)) + return -EINVAL; + + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + dev_alert(&pdev->dev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.", + node); + + dev->numa_node = node; + return count; +} + static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n", dev->numa_node); } -static DEVICE_ATTR_RO(numa_node); +static DEVICE_ATTR_RW(numa_node); #endif static ssize_t dma_mask_bits_show(struct device *dev, -- GitLab From 06529407329841ed836b30e4a99905a522ffa323 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:11:56 +0100 Subject: [PATCH 3511/9457] usb: gadget: f_hid: check return value of class_create class_create() might fail, so check its return value and react appropriately. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 59ab62c92b66..f3b3e19281ea 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -742,6 +742,10 @@ int __init ghid_setup(struct usb_gadget *g, int count) dev_t dev; hidg_class = class_create(THIS_MODULE, "hidg"); + if (IS_ERR(hidg_class)) { + hidg_class = NULL; + return PTR_ERR(hidg_class); + } status = alloc_chrdev_region(&dev, 0, count, "hidg"); if (!status) { -- GitLab From 634060870afbfbe37a567f35b78da9b74e81ad84 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:11:57 +0100 Subject: [PATCH 3512/9457] usb: gadget: f_hid: check return value of device_create device_create() might fail, so check its return value and react appropriately. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index f3b3e19281ea..ad538811c48b 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -556,6 +556,7 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_ep *ep; struct f_hidg *hidg = func_to_hidg(f); + struct device *device; int status; dev_t dev; @@ -623,10 +624,16 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) if (status) goto fail_free_descs; - device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor); + device = device_create(hidg_class, NULL, dev, NULL, + "%s%d", "hidg", hidg->minor); + if (IS_ERR(device)) { + status = PTR_ERR(device); + goto del; + } return 0; - +del: + cdev_del(&hidg->cdev); fail_free_descs: usb_free_all_descriptors(f); fail: -- GitLab From 00896f66f5032e5f53874a76e02cdad09f7ff90b Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:11:58 +0100 Subject: [PATCH 3513/9457] usb: gadget: hid: mirror init operations in module cleanup So far platform driver has been unregistered first, so just after that the usb composite is still available, but there is no hid data any more. Reverse the order so that first the usb composite becomes unavailable and second the hid data goes away. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 778613eb37af..fba80a25260b 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -260,7 +260,7 @@ module_init(hidg_init); static void __exit hidg_cleanup(void) { - platform_driver_unregister(&hidg_plat_driver); usb_composite_unregister(&hidg_driver); + platform_driver_unregister(&hidg_plat_driver); } module_exit(hidg_cleanup); -- GitLab From cb382536052fcc7713988869b54a81137069e5a9 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:11:59 +0100 Subject: [PATCH 3514/9457] usb: gadget: f_hid: convert to new function interface with backward compatibility Converting hid to the new function interface requires converting the USB hid's function code and its users. This patch converts the f_hid.c to the new function interface. The file can now be compiled into a separate usb_f_hid.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 3 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_hid.c | 218 +++++++++++++++++++++++---- drivers/usb/gadget/function/u_hid.h | 35 +++++ drivers/usb/gadget/legacy/hid.c | 1 + 5 files changed, 227 insertions(+), 32 deletions(-) create mode 100644 drivers/usb/gadget/function/u_hid.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 501c2a38d071..ea2d7706db6c 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -193,6 +193,9 @@ config USB_F_UVC config USB_F_MIDI tristate +config USB_F_HID + tristate + choice tristate "USB Gadget Drivers" default USB_ETH diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 576eea5c0a8b..dd68091d92f0 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -40,3 +40,5 @@ usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o +usb_f_hid-y := f_hid.o +obj-$(CONFIG_USB_F_HID) += usb_f_hid.o diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index ad538811c48b..f5dcf9480ba5 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -21,9 +22,16 @@ #include #include "u_f.h" +#include "u_hid.h" + +#define HIDG_MINORS 4 static int major, minors; static struct class *hidg_class; +#ifndef USBF_HID_INCLUDED +static DEFINE_IDA(hidg_ida); +static DEFINE_MUTEX(hidg_ida_lock); /* protects access to hidg_ida */ +#endif /*-------------------------------------------------------------------------*/ /* HID gadget struct */ @@ -160,6 +168,26 @@ static struct usb_descriptor_header *hidg_fs_descriptors[] = { NULL, }; +/*-------------------------------------------------------------------------*/ +/* Strings */ + +#define CT_FUNC_HID_IDX 0 + +static struct usb_string ct_func_string_defs[] = { + [CT_FUNC_HID_IDX].s = "HID Interface", + {}, /* end of list */ +}; + +static struct usb_gadget_strings ct_func_string_table = { + .language = 0x0409, /* en-US */ + .strings = ct_func_string_defs, +}; + +static struct usb_gadget_strings *ct_func_strings[] = { + &ct_func_string_table, + NULL, +}; + /*-------------------------------------------------------------------------*/ /* Char Device */ @@ -552,7 +580,7 @@ const struct file_operations f_hidg_fops = { .llseek = noop_llseek, }; -static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) +static int hidg_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_ep *ep; struct f_hidg *hidg = func_to_hidg(f); @@ -560,6 +588,15 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) int status; dev_t dev; + /* maybe allocate device-global string IDs, and patch descriptors */ + if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) { + status = usb_string_id(c->cdev); + if (status < 0) + return status; + ct_func_string_defs[CT_FUNC_HID_IDX].id = status; + hidg_interface_desc.iInterface = status; + } + /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); if (status < 0) @@ -647,6 +684,7 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) return status; } +#ifdef USBF_HID_INCLUDED static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_hidg *hidg = func_to_hidg(f); @@ -666,29 +704,8 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) kfree(hidg); } -/*-------------------------------------------------------------------------*/ -/* Strings */ - -#define CT_FUNC_HID_IDX 0 - -static struct usb_string ct_func_string_defs[] = { - [CT_FUNC_HID_IDX].s = "HID Interface", - {}, /* end of list */ -}; - -static struct usb_gadget_strings ct_func_string_table = { - .language = 0x0409, /* en-US */ - .strings = ct_func_string_defs, -}; - -static struct usb_gadget_strings *ct_func_strings[] = { - &ct_func_string_table, - NULL, -}; - /*-------------------------------------------------------------------------*/ /* usb_configuration */ - int __init hidg_bind_config(struct usb_configuration *c, struct hidg_func_descriptor *fdesc, int index) { @@ -698,15 +715,6 @@ int __init hidg_bind_config(struct usb_configuration *c, if (index >= minors) return -ENOENT; - /* maybe allocate device-global string IDs, and patch descriptors */ - if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) { - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ct_func_string_defs[CT_FUNC_HID_IDX].id = status; - hidg_interface_desc.iInterface = status; - } - /* allocate and initialize one new instance */ hidg = kzalloc(sizeof *hidg, GFP_KERNEL); if (!hidg) @@ -743,7 +751,153 @@ int __init hidg_bind_config(struct usb_configuration *c, return status; } -int __init ghid_setup(struct usb_gadget *g, int count) +#else + +static inline int hidg_get_minor(void) +{ + int ret; + + ret = ida_simple_get(&hidg_ida, 0, 0, GFP_KERNEL); + + return ret; +} + +static inline void hidg_put_minor(int minor) +{ + ida_simple_remove(&hidg_ida, minor); +} + +static void hidg_free_inst(struct usb_function_instance *f) +{ + struct f_hid_opts *opts; + + opts = container_of(f, struct f_hid_opts, func_inst); + + mutex_lock(&hidg_ida_lock); + + hidg_put_minor(opts->minor); + if (idr_is_empty(&hidg_ida.idr)) + ghid_cleanup(); + + mutex_unlock(&hidg_ida_lock); + + if (opts->report_desc_alloc) + kfree(opts->report_desc); + + kfree(opts); +} + +static struct usb_function_instance *hidg_alloc_inst(void) +{ + struct f_hid_opts *opts; + struct usb_function_instance *ret; + int status = 0; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + + opts->func_inst.free_func_inst = hidg_free_inst; + ret = &opts->func_inst; + + mutex_lock(&hidg_ida_lock); + + if (idr_is_empty(&hidg_ida.idr)) { + status = ghid_setup(NULL, HIDG_MINORS); + if (status) { + ret = ERR_PTR(status); + kfree(opts); + goto unlock; + } + } + + opts->minor = hidg_get_minor(); + if (opts->minor < 0) { + ret = ERR_PTR(opts->minor); + kfree(opts); + if (idr_is_empty(&hidg_ida.idr)) + ghid_cleanup(); + } + +unlock: + mutex_unlock(&hidg_ida_lock); + return ret; +} + +static void hidg_free(struct usb_function *f) +{ + struct f_hidg *hidg; + + hidg = func_to_hidg(f); + kfree(hidg->report_desc); + kfree(hidg); +} + +static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct f_hidg *hidg = func_to_hidg(f); + + device_destroy(hidg_class, MKDEV(major, hidg->minor)); + cdev_del(&hidg->cdev); + + /* disable/free request and end point */ + usb_ep_disable(hidg->in_ep); + usb_ep_dequeue(hidg->in_ep, hidg->req); + kfree(hidg->req->buf); + usb_ep_free_request(hidg->in_ep, hidg->req); + + usb_free_all_descriptors(f); +} + +struct usb_function *hidg_alloc(struct usb_function_instance *fi) +{ + struct f_hidg *hidg; + struct f_hid_opts *opts; + + /* allocate and initialize one new instance */ + hidg = kzalloc(sizeof(*hidg), GFP_KERNEL); + if (!hidg) + return ERR_PTR(-ENOMEM); + + opts = container_of(fi, struct f_hid_opts, func_inst); + + hidg->minor = opts->minor; + hidg->bInterfaceSubClass = opts->subclass; + hidg->bInterfaceProtocol = opts->protocol; + hidg->report_length = opts->report_length; + hidg->report_desc_length = opts->report_desc_length; + if (opts->report_desc) { + hidg->report_desc = kmemdup(opts->report_desc, + opts->report_desc_length, + GFP_KERNEL); + if (!hidg->report_desc) { + kfree(hidg); + return ERR_PTR(-ENOMEM); + } + } + + hidg->func.name = "hid"; + hidg->func.strings = ct_func_strings; + hidg->func.bind = hidg_bind; + hidg->func.unbind = hidg_unbind; + hidg->func.set_alt = hidg_set_alt; + hidg->func.disable = hidg_disable; + hidg->func.setup = hidg_setup; + hidg->func.free_func = hidg_free; + + /* this could me made configurable at some point */ + hidg->qlen = 4; + + return &hidg->func; +} + +DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Fabien Chouteau"); + +#endif + +int ghid_setup(struct usb_gadget *g, int count) { int status; dev_t dev; diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h new file mode 100644 index 000000000000..3edfc9567ab7 --- /dev/null +++ b/drivers/usb/gadget/function/u_hid.h @@ -0,0 +1,35 @@ +/* + * u_hid.h + * + * Utility definitions for the hid function + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Andrzej Pietrasiewicz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef U_HID_H +#define U_HID_H + +#include + +struct f_hid_opts { + struct usb_function_instance func_inst; + int minor; + unsigned char subclass; + unsigned char protocol; + unsigned short report_length; + unsigned short report_desc_length; + unsigned char *report_desc; + bool report_desc_alloc; +}; + +int ghid_setup(struct usb_gadget *g, int count); +void ghid_cleanup(void); + +#endif /* U_HID_H */ diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index fba80a25260b..26cb4ea2aaf7 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -36,6 +36,7 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ +#define USBF_HID_INCLUDED #include "f_hid.c" -- GitLab From 4bc8a33f2407975a5a40bd6adf86de815d2ce913 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:12:00 +0100 Subject: [PATCH 3515/9457] usb: gadget: hid: convert to new interface of f_hid Use the new f_hid interface in order for the old to be removed. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/legacy/hid.c | 78 ++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 8011b190e679..fd48ef3af4eb 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -420,6 +420,7 @@ endif # TTY config USB_G_HID tristate "HID Gadget" select USB_LIBCOMPOSITE + select USB_F_HID help The HID gadget driver provides generic emulation of USB Human Interface Devices (HID). diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 26cb4ea2aaf7..633fe7e07688 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -17,11 +17,14 @@ #include #include #include +#include #include "gadget_chips.h" #define DRIVER_DESC "HID Gadget" #define DRIVER_VERSION "2010/03/16" +#include "u_hid.h" + /*-------------------------------------------------------------------------*/ #define HIDG_VENDOR_NUM 0x0525 /* XXX NetChip */ @@ -29,18 +32,9 @@ /*-------------------------------------------------------------------------*/ -/* - * kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#define USBF_HID_INCLUDED -#include "f_hid.c" - - struct hidg_func_node { + struct usb_function_instance *fi; + struct usb_function *f; struct list_head node; struct hidg_func_descriptor *func; }; @@ -114,8 +108,8 @@ static struct usb_gadget_strings *dev_strings[] = { static int __init do_config(struct usb_configuration *c) { - struct hidg_func_node *e; - int func = 0, status = 0; + struct hidg_func_node *e, *n; + int status = 0; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; @@ -123,11 +117,24 @@ static int __init do_config(struct usb_configuration *c) } list_for_each_entry(e, &hidg_func_list, node) { - status = hidg_bind_config(c, e->func, func++); - if (status) - break; + e->f = usb_get_function(e->fi); + if (IS_ERR(e->f)) + goto put; + status = usb_add_function(c, e->f); + if (status < 0) { + usb_put_function(e->f); + goto put; + } } + return 0; +put: + list_for_each_entry(n, &hidg_func_list, node) { + if (n == e) + break; + usb_remove_function(c, n->f); + usb_put_function(n->f); + } return status; } @@ -144,6 +151,8 @@ static int __init hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct list_head *tmp; + struct hidg_func_node *n, *m; + struct f_hid_opts *hid_opts; int status, funcs = 0; list_for_each(tmp, &hidg_func_list) @@ -152,10 +161,20 @@ static int __init hid_bind(struct usb_composite_dev *cdev) if (!funcs) return -ENODEV; - /* set up HID */ - status = ghid_setup(cdev->gadget, funcs); - if (status < 0) - return status; + list_for_each_entry(n, &hidg_func_list, node) { + n->fi = usb_get_function_instance("hid"); + if (IS_ERR(n->fi)) { + status = PTR_ERR(n->fi); + goto put; + } + hid_opts = container_of(n->fi, struct f_hid_opts, func_inst); + hid_opts->subclass = n->func->subclass; + hid_opts->protocol = n->func->protocol; + hid_opts->report_length = n->func->report_length; + hid_opts->report_desc_length = n->func->report_desc_length; + hid_opts->report_desc = n->func->report_desc; + } + /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. @@ -163,24 +182,37 @@ static int __init hid_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) - return status; + goto put; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &config_driver, do_config); if (status < 0) - return status; + goto put; usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); return 0; + +put: + list_for_each_entry(m, &hidg_func_list, node) { + if (m == n) + break; + usb_put_function_instance(m->fi); + } + return status; } static int __exit hid_unbind(struct usb_composite_dev *cdev) { - ghid_cleanup(); + struct hidg_func_node *n; + + list_for_each_entry(n, &hidg_func_list, node) { + usb_put_function(n->f); + usb_put_function_instance(n->fi); + } return 0; } -- GitLab From 5d66a39102b1c18494bb3801100a5fb3cf7e5bdb Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:12:01 +0100 Subject: [PATCH 3516/9457] usb: gadget: f_hid: remove compatibility layer There are no old function interface users left, so remove it. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 73 ----------------------------- 1 file changed, 73 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index f5dcf9480ba5..df3cc32d1d23 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -28,10 +28,8 @@ static int major, minors; static struct class *hidg_class; -#ifndef USBF_HID_INCLUDED static DEFINE_IDA(hidg_ida); static DEFINE_MUTEX(hidg_ida_lock); /* protects access to hidg_ida */ -#endif /*-------------------------------------------------------------------------*/ /* HID gadget struct */ @@ -684,75 +682,6 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) return status; } -#ifdef USBF_HID_INCLUDED -static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_hidg *hidg = func_to_hidg(f); - - device_destroy(hidg_class, MKDEV(major, hidg->minor)); - cdev_del(&hidg->cdev); - - /* disable/free request and end point */ - usb_ep_disable(hidg->in_ep); - usb_ep_dequeue(hidg->in_ep, hidg->req); - kfree(hidg->req->buf); - usb_ep_free_request(hidg->in_ep, hidg->req); - - usb_free_all_descriptors(f); - - kfree(hidg->report_desc); - kfree(hidg); -} - -/*-------------------------------------------------------------------------*/ -/* usb_configuration */ -int __init hidg_bind_config(struct usb_configuration *c, - struct hidg_func_descriptor *fdesc, int index) -{ - struct f_hidg *hidg; - int status; - - if (index >= minors) - return -ENOENT; - - /* allocate and initialize one new instance */ - hidg = kzalloc(sizeof *hidg, GFP_KERNEL); - if (!hidg) - return -ENOMEM; - - hidg->minor = index; - hidg->bInterfaceSubClass = fdesc->subclass; - hidg->bInterfaceProtocol = fdesc->protocol; - hidg->report_length = fdesc->report_length; - hidg->report_desc_length = fdesc->report_desc_length; - hidg->report_desc = kmemdup(fdesc->report_desc, - fdesc->report_desc_length, - GFP_KERNEL); - if (!hidg->report_desc) { - kfree(hidg); - return -ENOMEM; - } - - hidg->func.name = "hid"; - hidg->func.strings = ct_func_strings; - hidg->func.bind = hidg_bind; - hidg->func.unbind = hidg_unbind; - hidg->func.set_alt = hidg_set_alt; - hidg->func.disable = hidg_disable; - hidg->func.setup = hidg_setup; - - /* this could me made configurable at some point */ - hidg->qlen = 4; - - status = usb_add_function(c, &hidg->func); - if (status) - kfree(hidg); - - return status; -} - -#else - static inline int hidg_get_minor(void) { int ret; @@ -895,8 +824,6 @@ DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Fabien Chouteau"); -#endif - int ghid_setup(struct usb_gadget *g, int count) { int status; -- GitLab From 5ca8d3ec9970f4798e68bd21a9d44db3d0ff4da7 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:12:02 +0100 Subject: [PATCH 3517/9457] usb: gadget: f_hid: use usb_gstrings_attach Before configfs is integrated the usb_gstrings_attach() interface must be used. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index df3cc32d1d23..dfdb4327ef3e 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -582,18 +582,17 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_ep *ep; struct f_hidg *hidg = func_to_hidg(f); + struct usb_string *us; struct device *device; int status; dev_t dev; /* maybe allocate device-global string IDs, and patch descriptors */ - if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) { - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ct_func_string_defs[CT_FUNC_HID_IDX].id = status; - hidg_interface_desc.iInterface = status; - } + us = usb_gstrings_attach(c->cdev, ct_func_strings, + ARRAY_SIZE(ct_func_string_defs)); + if (IS_ERR(us)) + return PTR_ERR(us); + hidg_interface_desc.iInterface = us[CT_FUNC_HID_IDX].id; /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); @@ -806,7 +805,6 @@ struct usb_function *hidg_alloc(struct usb_function_instance *fi) } hidg->func.name = "hid"; - hidg->func.strings = ct_func_strings; hidg->func.bind = hidg_bind; hidg->func.unbind = hidg_unbind; hidg->func.set_alt = hidg_set_alt; -- GitLab From 21a9476a7ba847e413bf1c144d7c614532aed6dd Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:12:03 +0100 Subject: [PATCH 3518/9457] usb: gadget: hid: add configfs support Make the hid function available for gadgets composed with configfs. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- .../ABI/testing/configfs-usb-gadget-hid | 11 ++ Documentation/usb/gadget_hid.txt | 7 + drivers/usb/gadget/Kconfig | 10 ++ drivers/usb/gadget/function/f_hid.c | 144 +++++++++++++++++- drivers/usb/gadget/function/u_hid.h | 7 + 5 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-hid diff --git a/Documentation/ABI/testing/configfs-usb-gadget-hid b/Documentation/ABI/testing/configfs-usb-gadget-hid new file mode 100644 index 000000000000..f12e00e6baa3 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-hid @@ -0,0 +1,11 @@ +What: /config/usb-gadget/gadget/functions/hid.name +Date: Nov 2014 +KernelVersion: 3.19 +Description: + The attributes: + + protocol - HID protocol to use + report_desc - blob corresponding to HID report descriptors + except the data passed through /dev/hidg + report_length - HID report length + subclass - HID device subclass to use diff --git a/Documentation/usb/gadget_hid.txt b/Documentation/usb/gadget_hid.txt index 12696c2e43fb..7a0fb8e16e27 100644 --- a/Documentation/usb/gadget_hid.txt +++ b/Documentation/usb/gadget_hid.txt @@ -74,6 +74,13 @@ static struct platform_device my_hid = { You can add as many HID functions as you want, only limited by the amount of interrupt endpoints your gadget driver supports. +Configuration with configfs + + Instead of adding fake platform devices and drivers in order to pass + some data to the kernel, if HID is a part of a gadget composed with + configfs the hidg_func_descriptor.report_desc is passed to the kernel + by writing the appropriate stream of bytes to a configfs attribute. + Send and receive HID reports HID reports can be sent/received using read/write on the diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ea2d7706db6c..747ef53bda14 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -413,6 +413,16 @@ config USB_CONFIGFS_F_MIDI connections can then be made on the gadget system, using ALSA's aconnect utility etc. +config USB_CONFIGFS_F_HID + boolean "HID function" + depends on USB_CONFIGFS + select USB_F_HID + help + The HID function driver provides generic emulation of USB + Human Interface Devices (HID). + + For more information, see Documentation/usb/gadget_hid.txt. + source "drivers/usb/gadget/legacy/Kconfig" endchoice diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index dfdb4327ef3e..56ca3fc81555 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -690,6 +690,136 @@ static inline int hidg_get_minor(void) return ret; } +static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_hid_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_hid_opts); +CONFIGFS_ATTR_OPS(f_hid_opts); + +static void hid_attr_release(struct config_item *item) +{ + struct f_hid_opts *opts = to_f_hid_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations hidg_item_ops = { + .release = hid_attr_release, + .show_attribute = f_hid_opts_attr_show, + .store_attribute = f_hid_opts_attr_store, +}; + +#define F_HID_OPT(name, prec, limit) \ +static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%d\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret; \ + u##prec num; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou##prec(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + if (num > limit) { \ + ret = -EINVAL; \ + goto end; \ + } \ + opts->name = num; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_hid_opts_attribute f_hid_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\ + f_hid_opts_##name##_store) + +F_HID_OPT(subclass, 8, 255); +F_HID_OPT(protocol, 8, 255); +F_HID_OPT(report_length, 16, 65536); + +static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) +{ + int result; + + mutex_lock(&opts->lock); + result = opts->report_desc_length; + memcpy(page, opts->report_desc, opts->report_desc_length); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts, + const char *page, size_t len) +{ + int ret = -EBUSY; + char *d; + + mutex_lock(&opts->lock); + + if (opts->refcnt) + goto end; + if (len > PAGE_SIZE) { + ret = -ENOSPC; + goto end; + } + d = kmemdup(page, len, GFP_KERNEL); + if (!d) { + ret = -ENOMEM; + goto end; + } + kfree(opts->report_desc); + opts->report_desc = d; + opts->report_desc_length = len; + opts->report_desc_alloc = true; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +static struct f_hid_opts_attribute f_hid_opts_report_desc = + __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR, + f_hid_opts_report_desc_show, + f_hid_opts_report_desc_store); + +static struct configfs_attribute *hid_attrs[] = { + &f_hid_opts_subclass.attr, + &f_hid_opts_protocol.attr, + &f_hid_opts_report_length.attr, + &f_hid_opts_report_desc.attr, + NULL, +}; + +static struct config_item_type hid_func_type = { + .ct_item_ops = &hidg_item_ops, + .ct_attrs = hid_attrs, + .ct_owner = THIS_MODULE, +}; + static inline void hidg_put_minor(int minor) { ida_simple_remove(&hidg_ida, minor); @@ -724,7 +854,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); - + mutex_init(&opts->lock); opts->func_inst.free_func_inst = hidg_free_inst; ret = &opts->func_inst; @@ -746,6 +876,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) if (idr_is_empty(&hidg_ida.idr)) ghid_cleanup(); } + config_group_init_type_name(&opts->func_inst.group, "", &hid_func_type); unlock: mutex_unlock(&hidg_ida_lock); @@ -755,10 +886,15 @@ static struct usb_function_instance *hidg_alloc_inst(void) static void hidg_free(struct usb_function *f) { struct f_hidg *hidg; + struct f_hid_opts *opts; hidg = func_to_hidg(f); + opts = container_of(f->fi, struct f_hid_opts, func_inst); kfree(hidg->report_desc); kfree(hidg); + mutex_lock(&opts->lock); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) @@ -789,6 +925,9 @@ struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_hid_opts, func_inst); + mutex_lock(&opts->lock); + ++opts->refcnt; + hidg->minor = opts->minor; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol; @@ -800,10 +939,13 @@ struct usb_function *hidg_alloc(struct usb_function_instance *fi) GFP_KERNEL); if (!hidg->report_desc) { kfree(hidg); + mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); } } + mutex_unlock(&opts->lock); + hidg->func.name = "hid"; hidg->func.bind = hidg_bind; hidg->func.unbind = hidg_unbind; diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h index 3edfc9567ab7..aaa0e368a159 100644 --- a/drivers/usb/gadget/function/u_hid.h +++ b/drivers/usb/gadget/function/u_hid.h @@ -27,6 +27,13 @@ struct f_hid_opts { unsigned short report_desc_length; unsigned char *report_desc; bool report_desc_alloc; + + /* + * Protect the data form concurrent access by read/write + * and create symlink/remove symlink. + */ + struct mutex lock; + int refcnt; }; int ghid_setup(struct usb_gadget *g, int count); -- GitLab From cd72f890d2d344f36d8f51f27bed2607062bb985 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 6 Nov 2014 11:31:00 -0600 Subject: [PATCH 3519/9457] usb: dwc3: core: enable phy suspend quirk on non-FPGA as it turns out, at least AM437x silicon (non-FPGA) needs to enable PHY suspend quirk. So let's allow for PHY suspend quirk to be used with non-FPGA builds too. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8ae42b8db02b..25ddc39efad8 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -404,7 +404,7 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->tx_de_emphasis_quirk) reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); - if (dwc->dis_u3_susphy_quirk && dwc->is_fpga) + if (dwc->dis_u3_susphy_quirk) reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); @@ -422,7 +422,7 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB2PHYCFG_SUSPHY; - if (dwc->dis_u2_susphy_quirk && dwc->is_fpga) + if (dwc->dis_u2_susphy_quirk) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); -- GitLab From 7af0ea5dee68c18259b07b86835d2648156d47f4 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 22 Oct 2014 07:46:50 -0500 Subject: [PATCH 3520/9457] tty: serial: omap: Increase max consoles and add check to prevent crash Increase the maximum number of consoles possible to 10 since DRA7 now has the maximum number of consoles possible. without doing this, for example, enabling DRA7 UART10 results in internal data structures and console cannot match up and we endup with a crash as follows: [ 1.903503] omap_uart 48424000.serial: [UART-1]: failure [serial_omap_probe]: -22 [ 1.911437] omap_uart: probe of 48424000.serial failed with error -22 [ 1.920379] Unable to handle kernel NULL pointer dereference at virtual address 00000004 [ 1.928894] pgd = c0004000 [ 1.931732] [00000004] *pgd=00000000 [ 1.935485] Internal error: Oops: 5 [#1] SMP ARM [ 1.940338] Modules linked in: [ 1.943542] CPU: 1 PID: 12 Comm: kworker/1:0 Tainted: G W 3.18.0-rc1-00001-g8821bc4-dirty #6 [ 1.953521] task: ed8a2d00 ti: ed8a4000 task.ti: ed8a4000 [ 1.959197] PC is at process_one_work+0x38/0x4a4 [ 1.964050] LR is at 0x0 [ 1.966705] pc : [] lr : [<00000000>] psr: 40000093 [ 1.966705] sp : ed8a5ea8 ip : ed8a5ec8 fp : eeb9abc0 [ 1.978759] r10: ed8a4000 r9 : 00000008 r8 : ed842458 [ 1.984252] r7 : 00000000 r6 : eeb9abc0 r5 : ed842440 r4 : edbf26a8 [ 1.991119] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : 00000000 [ 1.997985] Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel [ 2.005767] Control: 10c5387d Table: 8000406a DAC: 00000015 [ 2.011810] Process kworker/1:0 (pid: 12, stack limit = 0xed8a4248) [ 2.018371] Stack: (0xed8a5ea8 to 0xed8a6000) [ 2.022949] 5ea0: 00000001 00000000 60000093 c008346c 00000001 ed8a5ec8 [ 2.031555] 5ec0: c0054de4 eeb9abc0 ed8a4000 ed842458 00000008 ed8a4000 eeb9abc0 ed842440 [ 2.040161] 5ee0: eeb9abc0 eeb9abf0 ed8a4000 ed842458 00000008 ed8a4000 eeb9abc0 c0054ec4 [ 2.048767] 5f00: ed8a4000 eeb9ac4c a0000053 00000000 ed845bc0 ed842440 c0054d80 00000000 [ 2.057342] 5f20: 00000000 00000000 00000000 c005999c 00000001 00000000 c05eaa64 ed842440 [ 2.065948] 5f40: 00000000 00000000 dead4ead ffffffff ffffffff c097c680 00000000 00000000 [ 2.074554] 5f60: c078acd4 ed8a5f64 ed8a5f64 00000000 00000000 dead4ead ffffffff ffffffff [ 2.083160] 5f80: c097c680 00000000 00000000 c078acd4 ed8a5f90 ed8a5f90 600000d3 ed845bc0 [ 2.091766] 5fa0: c00598d4 00000000 00000000 c000e668 00000000 00000000 00000000 00000000 [ 2.100341] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 2.108947] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 90005148 11010482 [ 2.117553] [] (process_one_work) from [] (worker_thread+0x144/0x498) [ 2.126159] [] (worker_thread) from [] (kthread+0xc8/0xe4) [ 2.133758] [] (kthread) from [] (ret_from_fork+0x14/0x2c) [ 2.141357] Code: e1a04001 e1a05000 e893000f e31e0004 (e5978004) [ 2.147766] ---[ end trace 5798e2803311b69f ]--- The final solution is to transition off to use 8250 driver and no dependency on console structures and move away from omap-serial driver, hence no major cleanups are done for this driver, so add a simple check to prevent future crashes in a similar manner in case of platform with additional ports. Signed-off-by: Nishanth Menon Acked-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6cda5cd8b513..9d22d3369da9 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -46,7 +46,7 @@ #include -#define OMAP_MAX_HSUART_PORTS 6 +#define OMAP_MAX_HSUART_PORTS 10 #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) @@ -1693,6 +1693,13 @@ static int serial_omap_probe(struct platform_device *pdev) goto err_port_line; } + if (up->port.line >= OMAP_MAX_HSUART_PORTS) { + dev_err(&pdev->dev, "uart ID %d > MAX %d.\n", up->port.line, + OMAP_MAX_HSUART_PORTS); + ret = -ENXIO; + goto err_port_line; + } + ret = serial_omap_probe_rs485(up, pdev->dev.of_node); if (ret < 0) goto err_rs485; -- GitLab From 9b8777e3473e31b2aabd669e5f34866d4a3afb6a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 16 Oct 2014 21:48:21 +0200 Subject: [PATCH 3521/9457] serial: of: add a PORT_RT2880 definition The Ralink RT2880 SoC and its successors have an internal 8250 core. This core needs the same quirks applied as the AMD AU1xxx uart. In addition to these quirks, the ports memory region is only 0x100 unlike the AU1xxx which has a size of 0x1000. Signed-off-by: John Crispin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 5 ++++- drivers/tty/serial/of_serial.c | 10 +++++++++- include/uapi/linux/serial_core.h | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 7e78f3077b5d..223503299e99 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2640,8 +2640,11 @@ serial8250_pm(struct uart_port *port, unsigned int state, static unsigned int serial8250_port_size(struct uart_8250_port *pt) { - if (pt->port.iotype == UPIO_AU) + if (pt->port.iotype == UPIO_AU) { + if (pt->port.type == PORT_RT2880) + return 0x100; return 0x1000; + } if (is_omap1_8250(pt)) return 0x16 << pt->port.regshift; diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 9c64ad2ac1a8..8749fb849803 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -130,8 +130,15 @@ static int of_platform_serial_setup(struct platform_device *ofdev, port->dev = &ofdev->dev; - if (type == PORT_TEGRA) + switch (type) { + case PORT_TEGRA: port->handle_break = tegra_serial_handle_break; + break; + + case PORT_RT2880: + port->iotype = UPIO_AU; + break; + } return 0; out: @@ -317,6 +324,7 @@ static struct of_device_id of_platform_serial_table[] = { { .compatible = "ns16850", .data = (void *)PORT_16850, }, { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, + { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, { .compatible = "altr,16550-FIFO32", .data = (void *)PORT_ALTR_16550_F32, }, { .compatible = "altr,16550-FIFO64", diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 16ad8521af6a..c17218094f18 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -54,7 +54,8 @@ #define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */ #define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */ #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ -#define PORT_MAX_8250 28 /* max port ID */ +#define PORT_RT2880 29 /* Ralink RT2880 internal UART */ +#define PORT_MAX_8250 29 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed -- GitLab From e8ec41921e46d82f7cc1fe7ee30a821bd536890d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 16 Oct 2014 21:48:22 +0200 Subject: [PATCH 3522/9457] serial: ralink: adds Mediatek MT7620 serial Add the config symbol for Mediatek MT7620 SoC to the SERIAL_8250_RT288X dependencies. Signed-off-by: John Crispin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 5d3d65c0733e..0fcbcd29502f 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -293,7 +293,7 @@ config SERIAL_8250_EM config SERIAL_8250_RT288X bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" - depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) + depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620) help If you have a Ralink RT288x/RT305x SoC based board and want to use the serial port, say Y to this option. The driver can handle up to 2 serial -- GitLab From a7ae7f8243b15cd65b5811de031eb4f8413b3e6f Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 16 Oct 2014 22:43:27 +0200 Subject: [PATCH 3523/9457] serial: of_serial: add "ralink,rt2880-uart" to the binding documentation Signed-off-by: John Crispin Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/of-serial.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt index 8c4fd0332028..b52b98234b9b 100644 --- a/Documentation/devicetree/bindings/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/serial/of-serial.txt @@ -10,6 +10,7 @@ Required properties: - "ns16850" - "nvidia,tegra20-uart" - "nxp,lpc3220-uart" + - "ralink,rt2880-uart" - "ibm,qpace-nwp-serial" - "altr,16550-FIFO32" - "altr,16550-FIFO64" -- GitLab From 66f37aafd6a6177287334397c59d7a727d16cd24 Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Mon, 20 Oct 2014 19:12:20 +0200 Subject: [PATCH 3524/9457] tty/serial: at91: fix rx ring buffer management This patch swaps the use "tail" and "head" to fit the semantic of the linux circular buffer documentation: - head: the point at which the producer (the DMA controller) inserts items. - tail: the point at which the consumer (the serial framework) finds the next item. Besides the former code of the rx ring buffer didn't manage the case where head < tail, which might lead to loss of data. To fix this bug the data are now sent from the DMA buffer to the serial framework in two steps: 1 - First, we test if head < tail. If so, we copy the data from tail to the end of the DMA buffer then reset tail to zero. 2 - Finally, we copy data from tail to head then set tail to head. In addition, since tty_insert_flip_string() may now be called twice, atmel_flip_buffer_rx_dma() becomes less efficient than moving the calls dma_sync_sg_for_cpu(), dma_sync_sg_for_device(), tty_insert_flip_string() and tty_flip_buffer_push() directly into atmel_rx_from_dma(). Signed-off-by: Cyrille Pitchen Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 94 ++++++++++++++++++------------- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 8a84034d130c..9eb624a22431 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -880,32 +880,6 @@ static int atmel_prepare_tx_dma(struct uart_port *port) return -EINVAL; } -static void atmel_flip_buffer_rx_dma(struct uart_port *port, - char *buf, size_t count) -{ - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - struct tty_port *tport = &port->state->port; - - dma_sync_sg_for_cpu(port->dev, - &atmel_port->sg_rx, - 1, - DMA_DEV_TO_MEM); - - tty_insert_flip_string(tport, buf, count); - - dma_sync_sg_for_device(port->dev, - &atmel_port->sg_rx, - 1, - DMA_DEV_TO_MEM); - /* - * Drop the lock here since it might end up calling - * uart_start(), which takes the lock. - */ - spin_unlock(&port->lock); - tty_flip_buffer_push(tport); - spin_lock(&port->lock); -} - static void atmel_complete_rx_dma(void *arg) { struct uart_port *port = arg; @@ -934,11 +908,12 @@ static void atmel_release_rx_dma(struct uart_port *port) static void atmel_rx_from_dma(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + struct tty_port *tport = &port->state->port; struct circ_buf *ring = &atmel_port->rx_ring; struct dma_chan *chan = atmel_port->chan_rx; struct dma_tx_state state; enum dma_status dmastat; - size_t pending, count; + size_t count; /* Reset the UART timeout early so that we don't miss one */ @@ -953,27 +928,68 @@ static void atmel_rx_from_dma(struct uart_port *port) tasklet_schedule(&atmel_port->tasklet); return; } - /* current transfer size should no larger than dma buffer */ - pending = sg_dma_len(&atmel_port->sg_rx) - state.residue; - BUG_ON(pending > sg_dma_len(&atmel_port->sg_rx)); + /* CPU claims ownership of RX DMA buffer */ + dma_sync_sg_for_cpu(port->dev, + &atmel_port->sg_rx, + 1, + DMA_DEV_TO_MEM); + + /* + * ring->head points to the end of data already written by the DMA. + * ring->tail points to the beginning of data to be read by the + * framework. + * The current transfer size should not be larger than the dma buffer + * length. + */ + ring->head = sg_dma_len(&atmel_port->sg_rx) - state.residue; + BUG_ON(ring->head > sg_dma_len(&atmel_port->sg_rx)); /* - * This will take the chars we have so far, - * ring->head will record the transfer size, only new bytes come - * will insert into the framework. + * At this point ring->head may point to the first byte right after the + * last byte of the dma buffer: + * 0 <= ring->head <= sg_dma_len(&atmel_port->sg_rx) + * + * However ring->tail must always points inside the dma buffer: + * 0 <= ring->tail <= sg_dma_len(&atmel_port->sg_rx) - 1 + * + * Since we use a ring buffer, we have to handle the case + * where head is lower than tail. In such a case, we first read from + * tail to the end of the buffer then reset tail. */ - if (pending > ring->head) { - count = pending - ring->head; + if (ring->head < ring->tail) { + count = sg_dma_len(&atmel_port->sg_rx) - ring->tail; - atmel_flip_buffer_rx_dma(port, ring->buf + ring->head, count); + tty_insert_flip_string(tport, ring->buf + ring->tail, count); + ring->tail = 0; + port->icount.rx += count; + } - ring->head += count; - if (ring->head == sg_dma_len(&atmel_port->sg_rx)) - ring->head = 0; + /* Finally we read data from tail to head */ + if (ring->tail < ring->head) { + count = ring->head - ring->tail; + tty_insert_flip_string(tport, ring->buf + ring->tail, count); + /* Wrap ring->head if needed */ + if (ring->head >= sg_dma_len(&atmel_port->sg_rx)) + ring->head = 0; + ring->tail = ring->head; port->icount.rx += count; } + /* USART retreives ownership of RX DMA buffer */ + dma_sync_sg_for_device(port->dev, + &atmel_port->sg_rx, + 1, + DMA_DEV_TO_MEM); + + /* + * Drop the lock here since it might end up calling + * uart_start(), which takes the lock. + */ + spin_unlock(&port->lock); + tty_flip_buffer_push(tport); + spin_lock(&port->lock); + UART_PUT_IER(port, ATMEL_US_TIMEOUT); } -- GitLab From 42b4eba0612f87632a3e4d58c03f00e108e05dbc Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 10 Oct 2014 18:53:24 +0200 Subject: [PATCH 3525/9457] serial: mxs-auart: clean get_mctrl and set_mctrl Russell King: The only thing which the .get_mctrl method is supposed to do is to return the state of the /input/ lines, which are CTS, DCD, DSR, RI. The output line state is stored in port->mctrl, and is added to the returned value by serial_core when it's required. RTS output state should not be returned from the .get_mctrl method. This patch removes ctrl variable from mxs_auart_port and removes useless reading back RTS line. The ctrl variable in mxs_auart_port duplicated mctrl, member of uart_port structure in serial_core.h. The removed code from mxs_auart_set_mctrl() and mxs_auart_get_mctrl duplicated uart_update_mctrl() and uart_tiocmget() in serial_core.c. Signed-off-by: Janusz Uzycki Reviewed-by: Richard Genoud Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 0296c1c3b70e..907c3e521906 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -143,7 +143,6 @@ struct mxs_auart_port { #define MXS_AUART_DMA_RX_READY 3 /* bit 3 */ #define MXS_AUART_RTSCTS 4 /* bit 4 */ unsigned long flags; - unsigned int ctrl; enum mxs_auart_type devtype; unsigned int irq; @@ -406,8 +405,6 @@ static void mxs_auart_release_port(struct uart_port *u) static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) { - struct mxs_auart_port *s = to_auart_port(u); - u32 ctrl = readl(u->membase + AUART_CTRL2); ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); @@ -418,24 +415,17 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) ctrl |= AUART_CTRL2_RTS; } - s->ctrl = mctrl; writel(ctrl, u->membase + AUART_CTRL2); } static u32 mxs_auart_get_mctrl(struct uart_port *u) { - struct mxs_auart_port *s = to_auart_port(u); u32 stat = readl(u->membase + AUART_STAT); - int ctrl2 = readl(u->membase + AUART_CTRL2); - u32 mctrl = s->ctrl; + u32 mctrl = 0; - mctrl &= ~TIOCM_CTS; if (stat & AUART_STAT_CTS) mctrl |= TIOCM_CTS; - if (ctrl2 & AUART_CTRL2_RTS) - mctrl |= TIOCM_RTS; - return mctrl; } @@ -1071,8 +1061,6 @@ static int mxs_auart_probe(struct platform_device *pdev) s->port.type = PORT_IMX; s->port.dev = s->dev = &pdev->dev; - s->ctrl = 0; - s->irq = platform_get_irq(pdev, 0); s->port.irq = s->irq; ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); -- GitLab From 7c573d7ea6c5a866cf89b7bf45fc5ab82d289cf1 Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 10 Oct 2014 18:53:25 +0200 Subject: [PATCH 3526/9457] serial: mxs-auart: use mctrl_gpio helpers for handling modem signals Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited. Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO. This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals. Signed-off-by: Janusz Uzycki Reviewed-by: Richard Genoud Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/fsl-mxs-auart.txt | 10 +++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++-- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt index 59a40f18d551..7c408c87e613 100644 --- a/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt @@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial@8006a000 { @@ -21,6 +26,9 @@ auart0: serial@8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in "aliases" diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 649b784081c7..4e6a0babf6b9 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1408,6 +1408,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port. diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 907c3e521906..5922cb435a87 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -42,6 +42,9 @@ #include +#include +#include "serial_mctrl_gpio.h" + #define MXS_AUART_PORTS 5 #define MXS_AUART_FIFO_SIZE 16 @@ -158,6 +161,8 @@ struct mxs_auart_port { struct scatterlist rx_sgl; struct dma_chan *rx_dma_chan; void *rx_dma_buf; + + struct mctrl_gpios *gpios; }; static struct platform_device_id mxs_auart_devtype[] = { @@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u) static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) { + struct mxs_auart_port *s = to_auart_port(u); + u32 ctrl = readl(u->membase + AUART_CTRL2); ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); @@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) } writel(ctrl, u->membase + AUART_CTRL2); + + mctrl_gpio_set(s->gpios, mctrl); } static u32 mxs_auart_get_mctrl(struct uart_port *u) { + struct mxs_auart_port *s = to_auart_port(u); u32 stat = readl(u->membase + AUART_STAT); u32 mctrl = 0; if (stat & AUART_STAT_CTS) mctrl |= TIOCM_CTS; - return mctrl; + return mctrl_gpio_get(s->gpios, &mctrl); } static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); @@ -554,6 +564,10 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s) } +#define RTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART() IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS)) static void mxs_auart_settermios(struct uart_port *u, struct ktermios *termios, struct ktermios *old) @@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |= AUART_LINECTRL_STP2; /* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); if (cflag & CRTSCTS) { /* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR; } - ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; - } else { - ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); + /* Even if RTS is GPIO line RTSEN can be enabled because + * the pinctrl configuration decides about RTS pin function */ + ctrl2 |= AUART_CTRL2_RTSEN; + if (CTS_AT_AUART()) + ctrl2 |= AUART_CTRL2_CTSEN; } /* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR); if (istat & AUART_INTR_CTSMIS) { - uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); + if (CTS_AT_AUART()) + uart_handle_cts_change(&s->port, + stat & AUART_STAT_CTS); writel(AUART_INTR_CTSMIS, s->port.membase + AUART_INTR_CLR); istat &= ~AUART_INTR_CTSMIS; @@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, return 0; } +static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) +{ + s->gpios = mctrl_gpio_init(dev, 0); + if (IS_ERR_OR_NULL(s->gpios)) + return false; + + /* Block (enabled before) DMA option if RTS or CTS is GPIO line */ + if (!RTS_AT_AUART() || !CTS_AT_AUART()) { + if (test_bit(MXS_AUART_RTSCTS, &s->flags)) + dev_warn(dev, + "DMA and flow control via gpio may cause some problems. DMA disabled!\n"); + clear_bit(MXS_AUART_RTSCTS, &s->flags); + } + + return true; +} + static int mxs_auart_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s); + if (!mxs_auart_init_gpios(s, &pdev->dev)) + dev_err(&pdev->dev, + "Failed to initialize GPIOs. The serial port may not work as expected\n"); + auart_port[s->port.line] = s; mxs_auart_reset(&s->port); -- GitLab From f9e42397d79b6e810437ba1130b0b4b594f5e56c Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 10 Oct 2014 18:53:26 +0200 Subject: [PATCH 3527/9457] serial: mxs-auart: add interrupts for modem control lines Handle CTS/DSR/RI/DCD GPIO interrupts in mxs-auart. Signed-off-by: Janusz Uzycki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 174 ++++++++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 5922cb435a87..088f1e17b33e 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -42,7 +42,10 @@ #include +#include +#include #include +#include #include "serial_mctrl_gpio.h" #define MXS_AUART_PORTS 5 @@ -146,6 +149,7 @@ struct mxs_auart_port { #define MXS_AUART_DMA_RX_READY 3 /* bit 3 */ #define MXS_AUART_RTSCTS 4 /* bit 4 */ unsigned long flags; + unsigned int mctrl_prev; enum mxs_auart_type devtype; unsigned int irq; @@ -163,6 +167,8 @@ struct mxs_auart_port { void *rx_dma_buf; struct mctrl_gpios *gpios; + int gpio_irq[UART_GPIO_MAX]; + bool ms_irq_enabled; }; static struct platform_device_id mxs_auart_devtype[] = { @@ -427,6 +433,29 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) mctrl_gpio_set(s->gpios, mctrl); } +#define MCTRL_ANY_DELTA (TIOCM_RI | TIOCM_DSR | TIOCM_CD | TIOCM_CTS) +static u32 mxs_auart_modem_status(struct mxs_auart_port *s, u32 mctrl) +{ + u32 mctrl_diff; + + mctrl_diff = mctrl ^ s->mctrl_prev; + s->mctrl_prev = mctrl; + if (mctrl_diff & MCTRL_ANY_DELTA && s->ms_irq_enabled && + s->port.state != NULL) { + if (mctrl_diff & TIOCM_RI) + s->port.icount.rng++; + if (mctrl_diff & TIOCM_DSR) + s->port.icount.dsr++; + if (mctrl_diff & TIOCM_CD) + uart_handle_dcd_change(&s->port, mctrl & TIOCM_CD); + if (mctrl_diff & TIOCM_CTS) + uart_handle_cts_change(&s->port, mctrl & TIOCM_CTS); + + wake_up_interruptible(&s->port.state->port.delta_msr_wait); + } + return mctrl; +} + static u32 mxs_auart_get_mctrl(struct uart_port *u) { struct mxs_auart_port *s = to_auart_port(u); @@ -439,6 +468,64 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u) return mctrl_gpio_get(s->gpios, &mctrl); } +/* + * Enable modem status interrupts + */ +static void mxs_auart_enable_ms(struct uart_port *port) +{ + struct mxs_auart_port *s = to_auart_port(port); + + /* + * Interrupt should not be enabled twice + */ + if (s->ms_irq_enabled) + return; + + s->ms_irq_enabled = true; + + if (s->gpio_irq[UART_GPIO_CTS] >= 0) + enable_irq(s->gpio_irq[UART_GPIO_CTS]); + /* TODO: enable AUART_INTR_CTSMIEN otherwise */ + + if (s->gpio_irq[UART_GPIO_DSR] >= 0) + enable_irq(s->gpio_irq[UART_GPIO_DSR]); + + if (s->gpio_irq[UART_GPIO_RI] >= 0) + enable_irq(s->gpio_irq[UART_GPIO_RI]); + + if (s->gpio_irq[UART_GPIO_DCD] >= 0) + enable_irq(s->gpio_irq[UART_GPIO_DCD]); +} + +/* + * Disable modem status interrupts + */ +static void mxs_auart_disable_ms(struct uart_port *port) +{ + struct mxs_auart_port *s = to_auart_port(port); + + /* + * Interrupt should not be disabled twice + */ + if (!s->ms_irq_enabled) + return; + + s->ms_irq_enabled = false; + + if (s->gpio_irq[UART_GPIO_CTS] >= 0) + disable_irq(s->gpio_irq[UART_GPIO_CTS]); + /* TODO: disable AUART_INTR_CTSMIEN otherwise */ + + if (s->gpio_irq[UART_GPIO_DSR] >= 0) + disable_irq(s->gpio_irq[UART_GPIO_DSR]); + + if (s->gpio_irq[UART_GPIO_RI] >= 0) + disable_irq(s->gpio_irq[UART_GPIO_RI]); + + if (s->gpio_irq[UART_GPIO_DCD] >= 0) + disable_irq(s->gpio_irq[UART_GPIO_DCD]); +} + static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); static void dma_rx_callback(void *arg) { @@ -689,6 +776,12 @@ static void mxs_auart_settermios(struct uart_port *u, dev_err(s->dev, "We can not start up the DMA.\n"); } } + + /* CTS flow-control and modem-status interrupts */ + if (UART_ENABLE_MS(u, termios->c_cflag)) + mxs_auart_enable_ms(u); + else + mxs_auart_disable_ms(u); } static irqreturn_t mxs_auart_irq_handle(int irq, void *context) @@ -706,8 +799,18 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | AUART_INTR_CTSMIS), s->port.membase + AUART_INTR_CLR); + /* + * Dealing with GPIO interrupt + */ + if (irq == s->gpio_irq[UART_GPIO_CTS] || + irq == s->gpio_irq[UART_GPIO_DCD] || + irq == s->gpio_irq[UART_GPIO_DSR] || + irq == s->gpio_irq[UART_GPIO_RI]) + mxs_auart_modem_status(s, + mctrl_gpio_get(s->gpios, &s->mctrl_prev)); + if (istat & AUART_INTR_CTSMIS) { - if (CTS_AT_AUART()) + if (CTS_AT_AUART() && s->ms_irq_enabled) uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); writel(AUART_INTR_CTSMIS, @@ -770,6 +873,10 @@ static int mxs_auart_startup(struct uart_port *u) */ writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET); + /* get initial status of modem lines */ + mctrl_gpio_get(s->gpios, &s->mctrl_prev); + + s->ms_irq_enabled = false; return 0; } @@ -777,6 +884,8 @@ static void mxs_auart_shutdown(struct uart_port *u) { struct mxs_auart_port *s = to_auart_port(u); + mxs_auart_disable_ms(u); + if (auart_dma_enabled(s)) mxs_auart_dma_exit(s); @@ -833,6 +942,7 @@ static struct uart_ops mxs_auart_ops = { .start_tx = mxs_auart_start_tx, .stop_tx = mxs_auart_stop_tx, .stop_rx = mxs_auart_stop_rx, + .enable_ms = mxs_auart_enable_ms, .break_ctl = mxs_auart_break_ctl, .set_mctrl = mxs_auart_set_mctrl, .get_mctrl = mxs_auart_get_mctrl, @@ -1035,6 +1145,9 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) { + enum mctrl_gpio_idx i; + struct gpio_desc *gpiod; + s->gpios = mctrl_gpio_init(dev, 0); if (IS_ERR_OR_NULL(s->gpios)) return false; @@ -1047,9 +1160,54 @@ static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev) clear_bit(MXS_AUART_RTSCTS, &s->flags); } + for (i = 0; i < UART_GPIO_MAX; i++) { + gpiod = mctrl_gpio_to_gpiod(s->gpios, i); + if (gpiod && (gpiod_get_direction(gpiod) == GPIOF_DIR_IN)) + s->gpio_irq[i] = gpiod_to_irq(gpiod); + else + s->gpio_irq[i] = -EINVAL; + } + return true; } +static void mxs_auart_free_gpio_irq(struct mxs_auart_port *s) +{ + enum mctrl_gpio_idx i; + + for (i = 0; i < UART_GPIO_MAX; i++) + if (s->gpio_irq[i] >= 0) + free_irq(s->gpio_irq[i], s); +} + +static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s) +{ + int *irq = s->gpio_irq; + enum mctrl_gpio_idx i; + int err = 0; + + for (i = 0; (i < UART_GPIO_MAX) && !err; i++) { + if (irq[i] < 0) + continue; + + irq_set_status_flags(irq[i], IRQ_NOAUTOEN); + err = request_irq(irq[i], mxs_auart_irq_handle, + IRQ_TYPE_EDGE_BOTH, dev_name(s->dev), s); + if (err) + dev_err(s->dev, "%s - Can't get %d irq\n", + __func__, irq[i]); + } + + /* + * If something went wrong, rollback. + */ + while (err && (--i >= 0)) + if (irq[i] >= 0) + free_irq(irq[i], s); + + return err; +} + static int mxs_auart_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -1097,6 +1255,8 @@ static int mxs_auart_probe(struct platform_device *pdev) s->port.type = PORT_IMX; s->port.dev = s->dev = &pdev->dev; + s->mctrl_prev = 0; + s->irq = platform_get_irq(pdev, 0); s->port.irq = s->irq; ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); @@ -1109,13 +1269,20 @@ static int mxs_auart_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to initialize GPIOs. The serial port may not work as expected\n"); + /* + * Get the GPIO lines IRQ + */ + ret = mxs_auart_request_gpio_irq(s); + if (ret) + goto out_free_irq; + auart_port[s->port.line] = s; mxs_auart_reset(&s->port); ret = uart_add_one_port(&auart_driver, &s->port); if (ret) - goto out_free_irq; + goto out_free_gpio_irq; version = readl(s->port.membase + AUART_VERSION); dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n", @@ -1124,6 +1291,8 @@ static int mxs_auart_probe(struct platform_device *pdev) return 0; +out_free_gpio_irq: + mxs_auart_free_gpio_irq(s); out_free_irq: auart_port[pdev->id] = NULL; free_irq(s->irq, s); @@ -1143,6 +1312,7 @@ static int mxs_auart_remove(struct platform_device *pdev) auart_port[pdev->id] = NULL; + mxs_auart_free_gpio_irq(s); clk_put(s->clk); free_irq(s->irq, s); kfree(s); -- GitLab From 36a262782b045220bfccf89bd2c4d78cbe152c8e Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 10 Oct 2014 18:53:27 +0200 Subject: [PATCH 3528/9457] serial: mxs-auart: enable PPS support Enables PPS support in mxs-auart serial driver to make PPS API working. Signed-off-by: Janusz Uzycki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 088f1e17b33e..386b52894056 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -784,6 +784,16 @@ static void mxs_auart_settermios(struct uart_port *u, mxs_auart_disable_ms(u); } +static void mxs_auart_set_ldisc(struct uart_port *port, int new) +{ + if (new == N_PPS) { + port->flags |= UPF_HARDPPS_CD; + mxs_auart_enable_ms(port); + } else { + port->flags &= ~UPF_HARDPPS_CD; + } +} + static irqreturn_t mxs_auart_irq_handle(int irq, void *context) { u32 istat; @@ -949,6 +959,7 @@ static struct uart_ops mxs_auart_ops = { .startup = mxs_auart_startup, .shutdown = mxs_auart_shutdown, .set_termios = mxs_auart_settermios, + .set_ldisc = mxs_auart_set_ldisc, .type = mxs_auart_type, .release_port = mxs_auart_release_port, .request_port = mxs_auart_request_port, -- GitLab From 660beb0e94ad81cfcb6b7846606c0378b0152064 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 29 Oct 2014 11:14:37 -0700 Subject: [PATCH 3529/9457] tty: serial: msm: Fix sysrq spinlock recursion on non-DM The handle_rx() path calls uart_handle_sysrq_char() with the port lock held. This causes a spinlock recursion. Release and reacquire the lock here to avoid this. BUG: spinlock recursion on CPU#0, swapper/0 lock: msm_uart_ports+0x1e0/0x2d0, .magic: dead4ead, .owner: swapper/0, .owner_cpu: 0 CPU: 0 PID: 0 Comm: swapper Not tainted 3.17.0-rc7-00012-gb38ee8265941 #69 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (do_raw_spin_lock+0x11c/0x13c) [] (do_raw_spin_lock) from [] (msm_console_write+0x78/0x188) [] (msm_console_write) from [] (call_console_drivers.constprop.22+0xb4/0x144) [] (call_console_drivers.constprop.22) from [] (console_unlock+0x27c/0x4ac) [] (console_unlock) from [] (vprintk_emit+0x1f4/0x5a8) [] (vprintk_emit) from [] (printk+0x30/0x40) [] (printk) from [] (__handle_sysrq+0x58/0x1b8) [] (__handle_sysrq) from [] (msm_irq+0x694/0x6f8) [] (msm_irq) from [] (handle_irq_event_percpu+0x58/0x270) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x3c/0x5c) [] (handle_irq_event) from [] (handle_level_irq+0x9c/0x138) [] (handle_level_irq) from [] (generic_handle_irq+0x24/0x38) [] (generic_handle_irq) from [] (handle_IRQ+0x44/0xb0) [] (handle_IRQ) from [] (msm_vic_handle_irq+0x44/0x64) [] (msm_vic_handle_irq) from [] (__irq_svc+0x44/0x7c) Exception stack(0xc0719f68 to 0xc0719fb0) 9f60: 00000001 00000001 00000000 c0722938 c0718000 c0769acc 9f80: 00000000 c0720098 c0769305 4117b362 c0769acc 00000000 01000000 c0719fb0 9fa0: c004cab0 c000f880 20000013 ffffffff [] (__irq_svc) from [] (arch_cpu_idle+0x20/0x30) [] (arch_cpu_idle) from [] (cpu_startup_entry+0xf4/0x23c) [] (cpu_startup_entry) from [] (start_kernel+0x32c/0x394) Cc: Frank Rowand Cc: Daniel Thompson Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 4b6c78331a64..cedcc36762a2 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -174,6 +174,7 @@ static void handle_rx(struct uart_port *port) while ((sr = msm_read(port, UART_SR)) & UART_SR_RX_READY) { unsigned int c; char flag = TTY_NORMAL; + int sysrq; c = msm_read(port, UART_RF); @@ -195,7 +196,10 @@ static void handle_rx(struct uart_port *port) else if (sr & UART_SR_PAR_FRAME_ERR) flag = TTY_FRAME; - if (!uart_handle_sysrq_char(port, c)) + spin_unlock(&port->lock); + sysrq = uart_handle_sysrq_char(port, c); + spin_lock(&port->lock); + if (!sysrq) tty_insert_flip_char(tport, c, flag); } -- GitLab From 0896d4d4fb162297d7199410bae386a96a2e473b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 29 Oct 2014 11:14:38 -0700 Subject: [PATCH 3530/9457] tty: serial: msm: Support sysrq on uartDM devices To properly support sysrq on uartDM hardware we need to properly handle break characters. With the DM hardware the fifo can pack 4 characters at a time, where a break is indicated by an all zero byte. Unfortunately, we can't differentiate between an all zero byte for a break and an all zero byte of data, so try and do as best we can. First unmask the RX break start interrupt and record the interrupt when it arrives. Then while processing the fifo, detect the break by searching for an all zero character as long as we recently received an RX break start interrupt. This should make sysrq work fairly well. Cc: Frank Rowand Cc: Daniel Thompson Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 41 +++++++++++++++++++++++++-------- drivers/tty/serial/msm_serial.h | 2 ++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index cedcc36762a2..d44c04976f7a 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -54,6 +54,7 @@ struct msm_port { unsigned int imr; int is_uartdm; unsigned int old_snap_state; + bool break_detected; }; static inline void wait_for_xmitr(struct uart_port *port) @@ -126,23 +127,38 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) while (count > 0) { unsigned char buf[4]; + int sysrq, r_count, i; sr = msm_read(port, UART_SR); if ((sr & UART_SR_RX_READY) == 0) { msm_port->old_snap_state -= count; break; } + ioread32_rep(port->membase + UARTDM_RF, buf, 1); - if (sr & UART_SR_RX_BREAK) { - port->icount.brk++; - if (uart_handle_break(port)) - continue; - } else if (sr & UART_SR_PAR_FRAME_ERR) - port->icount.frame++; + r_count = min_t(int, count, sizeof(buf)); + + for (i = 0; i < r_count; i++) { + char flag = TTY_NORMAL; - /* TODO: handle sysrq */ - tty_insert_flip_string(tport, buf, min(count, 4)); - count -= 4; + if (msm_port->break_detected && buf[i] == 0) { + port->icount.brk++; + flag = TTY_BREAK; + msm_port->break_detected = false; + if (uart_handle_break(port)) + continue; + } + + if (!(port->read_status_mask & UART_SR_RX_BREAK)) + flag = TTY_NORMAL; + + spin_unlock(&port->lock); + sysrq = uart_handle_sysrq_char(port, buf[i]); + spin_lock(&port->lock); + if (!sysrq) + tty_insert_flip_char(tport, buf[i], flag); + } + count -= r_count; } spin_unlock(&port->lock); @@ -291,6 +307,11 @@ static irqreturn_t msm_irq(int irq, void *dev_id) misr = msm_read(port, UART_MISR); msm_write(port, 0, UART_IMR); /* disable interrupt */ + if (misr & UART_IMR_RXBREAK_START) { + msm_port->break_detected = true; + msm_write(port, UART_CR_CMD_RESET_RXBREAK_START, UART_CR); + } + if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) { if (msm_port->is_uartdm) handle_rx_dm(port, misr); @@ -496,7 +517,7 @@ static int msm_startup(struct uart_port *port) /* turn on RX and CTS interrupts */ msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | - UART_IMR_CURRENT_CTS; + UART_IMR_CURRENT_CTS | UART_IMR_RXBREAK_START; if (msm_port->is_uartdm) { msm_write(port, 0xFFFFFF, UARTDM_DMRX); diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h index 73d3abe71e79..3e1c7138d8cd 100644 --- a/drivers/tty/serial/msm_serial.h +++ b/drivers/tty/serial/msm_serial.h @@ -65,6 +65,7 @@ #define UART_CR_TX_ENABLE (1 << 2) #define UART_CR_RX_DISABLE (1 << 1) #define UART_CR_RX_ENABLE (1 << 0) +#define UART_CR_CMD_RESET_RXBREAK_START ((1 << 11) | (2 << 4)) #define UART_IMR 0x0014 #define UART_IMR_TXLEV (1 << 0) @@ -72,6 +73,7 @@ #define UART_IMR_RXLEV (1 << 4) #define UART_IMR_DELTA_CTS (1 << 5) #define UART_IMR_CURRENT_CTS (1 << 6) +#define UART_IMR_RXBREAK_START (1 << 10) #define UART_IPR_RXSTALE_LAST 0x20 #define UART_IPR_STALE_LSB 0x1F -- GitLab From a12f1b406f2d3c3e3bba5300b6e420d004ca263b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 29 Oct 2014 18:47:01 -0700 Subject: [PATCH 3531/9457] tty: serial: msm: Reset uartdm after baud rate change We need to issue a reset if we ever change the value of the IPR register on DM hardware. If we don't reset the hardware the RX stale interrupt never triggers and the only way to trigger an RX handling event is by filling up the fifo. This causes things like getty to not work so well considering it might change the baud rate a few times. Fix this by moving the reset on startup and any reprogramming required after the reset to be after we change the baud rate. Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 49 ++++++++------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index d44c04976f7a..b507f5a16c1c 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -427,9 +427,6 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) entry = msm_find_best_baud(port, baud); - if (msm_port->is_uartdm) - msm_write(port, UART_CR_CMD_RESET_RX, UART_CR); - msm_write(port, entry->code, UART_CSR); /* RX stale watermark */ @@ -446,6 +443,18 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) /* set TX watermark */ msm_write(port, 10, UART_TFWR); + msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); + msm_reset(port); + + /* Enable RX and TX */ + msm_write(port, UART_CR_TX_ENABLE | UART_CR_RX_ENABLE, UART_CR); + + /* turn on RX and CTS interrupts */ + msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | + UART_IMR_CURRENT_CTS | UART_IMR_RXBREAK_START; + + msm_write(port, msm_port->imr, UART_IMR); + if (msm_port->is_uartdm) { msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); msm_write(port, 0xFFFFFF, UARTDM_DMRX); @@ -492,40 +501,6 @@ static int msm_startup(struct uart_port *port) data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2); data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; msm_write(port, data, UART_MR1); - - /* make sure that RXSTALE count is non-zero */ - data = msm_read(port, UART_IPR); - if (unlikely(!data)) { - data |= UART_IPR_RXSTALE_LAST; - data |= UART_IPR_STALE_LSB; - msm_write(port, data, UART_IPR); - } - - data = 0; - if (!port->cons || (port->cons && !(port->cons->flags & CON_ENABLED))) { - msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); - msm_reset(port); - data = UART_CR_TX_ENABLE; - } - - data |= UART_CR_RX_ENABLE; - msm_write(port, data, UART_CR); /* enable TX & RX */ - - /* Make sure IPR is not 0 to start with*/ - if (msm_port->is_uartdm) - msm_write(port, UART_IPR_STALE_LSB, UART_IPR); - - /* turn on RX and CTS interrupts */ - msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE | - UART_IMR_CURRENT_CTS | UART_IMR_RXBREAK_START; - - if (msm_port->is_uartdm) { - msm_write(port, 0xFFFFFF, UARTDM_DMRX); - msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); - msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); - } - - msm_write(port, msm_port->imr, UART_IMR); return 0; } -- GitLab From 97f754710304382607417c700476007443cd96a4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 22 Oct 2014 17:33:01 -0700 Subject: [PATCH 3532/9457] tty: serial: msm_serial: Use DT aliases We rely on probe order of this driver to determine the line number for the uart port. This makes it impossible to know the line number when these devices are populated via DT. Use the DT alias mechanism to assign the line based on the aliases node. Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index b507f5a16c1c..09364dd8cf3a 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1044,17 +1044,22 @@ static int msm_serial_probe(struct platform_device *pdev) struct resource *resource; struct uart_port *port; const struct of_device_id *id; - int irq; + int irq, line; if (pdev->id == -1) pdev->id = atomic_inc_return(&msm_uart_next_id) - 1; - if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) + if (pdev->dev.of_node) + line = of_alias_get_id(pdev->dev.of_node, "serial"); + else + line = pdev->id; + + if (unlikely(line < 0 || line >= UART_NR)) return -ENXIO; - dev_info(&pdev->dev, "msm_serial: detected port #%d\n", pdev->id); + dev_info(&pdev->dev, "msm_serial: detected port #%d\n", line); - port = get_port_from_line(pdev->id); + port = get_port_from_line(line); port->dev = &pdev->dev; msm_port = UART_TO_MSM(port); -- GitLab From f968ef34945f8e606c5d98ff330a5903785ea76a Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 28 Oct 2014 09:28:07 +0100 Subject: [PATCH 3533/9457] serial: imx: clean up imx_poll_put_char() imx_put_poll_char() has been simplified to remove the code to disable interrupts. The present code can corrupt register state when re-entered from FIQ handler. Switch to _relaxed() MMIO functions (which are safe for polled I/O and needed to avoid taking spin locks). Signed-off-by: Daniel Thompson Signed-off-by: Dirk Behme Cc: Jiri Slaby Cc: Huang Shijie Cc: linux-serial@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index d2e6cf5a1ab8..8d61aa98b932 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1457,42 +1457,28 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) #if defined(CONFIG_CONSOLE_POLL) static int imx_poll_get_char(struct uart_port *port) { - if (!(readl(port->membase + USR2) & USR2_RDR)) + if (!(readl_relaxed(port->membase + USR2) & USR2_RDR)) return NO_POLL_CHAR; - return readl(port->membase + URXD0) & URXD_RX_DATA; + return readl_relaxed(port->membase + URXD0) & URXD_RX_DATA; } static void imx_poll_put_char(struct uart_port *port, unsigned char c) { - struct imx_port_ucrs old_ucr; unsigned int status; - /* save control registers */ - imx_port_ucrs_save(port, &old_ucr); - - /* disable interrupts */ - writel(UCR1_UARTEN, port->membase + UCR1); - writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), - port->membase + UCR2); - writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), - port->membase + UCR3); - /* drain */ do { - status = readl(port->membase + USR1); + status = readl_relaxed(port->membase + USR1); } while (~status & USR1_TRDY); /* write */ - writel(c, port->membase + URTX0); + writel_relaxed(c, port->membase + URTX0); /* flush */ do { - status = readl(port->membase + USR2); + status = readl_relaxed(port->membase + USR2); } while (~status & USR2_TXDC); - - /* restore control registers */ - imx_port_ucrs_restore(port, &old_ucr); } #endif -- GitLab From 6b8bdad961647ebbc3fec8130f6487ab9fddaef4 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 28 Oct 2014 09:28:08 +0100 Subject: [PATCH 3534/9457] serial: imx: add imx_poll_init() For the console poll usage, .poll_init() will perform deeper hardware initialization to ensure the serial port is always active. Signed-off-by: Daniel Thompson Signed-off-by: Dirk Behme Cc: Jiri Slaby Cc: Huang Shijie Cc: linux-serial@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 8d61aa98b932..062e7614c986 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1455,6 +1455,41 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) } #if defined(CONFIG_CONSOLE_POLL) + +static int imx_poll_init(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + unsigned long flags; + unsigned long temp; + int retval; + + retval = clk_prepare_enable(sport->clk_ipg); + if (retval) + return retval; + retval = clk_prepare_enable(sport->clk_per); + if (retval) + clk_disable_unprepare(sport->clk_ipg); + + imx_setup_ufcr(sport, 0); + + spin_lock_irqsave(&sport->port.lock, flags); + + temp = readl(sport->port.membase + UCR1); + if (is_imx1_uart(sport)) + temp |= IMX1_UCR1_UARTCLKEN; + temp |= UCR1_UARTEN | UCR1_RRDYEN; + temp &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN); + writel(temp, sport->port.membase + UCR1); + + temp = readl(sport->port.membase + UCR2); + temp |= UCR2_RXEN; + writel(temp, sport->port.membase + UCR2); + + spin_unlock_irqrestore(&sport->port.lock, flags); + + return 0; +} + static int imx_poll_get_char(struct uart_port *port) { if (!(readl_relaxed(port->membase + USR2) & USR2_RDR)) @@ -1499,6 +1534,7 @@ static struct uart_ops imx_pops = { .config_port = imx_config_port, .verify_port = imx_verify_port, #if defined(CONFIG_CONSOLE_POLL) + .poll_init = imx_poll_init, .poll_get_char = imx_poll_get_char, .poll_put_char = imx_poll_put_char, #endif -- GitLab From c0ec3fd123e9e64e095fb221ace841e00c04e40b Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:22:57 -0700 Subject: [PATCH 3535/9457] tty: serial: bcm63xx: Allow bcm63xx_uart to be built on other platforms This device was originally supported on bcm63xx only, but it shows up on a wide variety of MIPS and ARM chipsets spanning multiple product lines. Now that the driver has eliminated dependencies on bcm63xx-specific header files, we can build it on any non-bcm63xx kernel. Compile-tested on x86, both statically and as a module. Tested for functionality on bcm3384 (a new MIPS platform under active development). Signed-off-by: Kevin Cernekee Acked-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 4e6a0babf6b9..9503789ece94 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1283,7 +1283,7 @@ config SERIAL_TIMBERDALE config SERIAL_BCM63XX tristate "bcm63xx serial port support" select SERIAL_CORE - depends on BCM63XX + depends on MIPS || ARM || COMPILE_TEST help If you have a bcm63xx CPU, you can enable its onboard serial port by enabling this options. -- GitLab From 048c1df7e22b2d40c639837440527ba43b6a591c Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:22:58 -0700 Subject: [PATCH 3536/9457] tty: serial: bcm63xx: Add support for unnamed clock outputs from DT The original non-DT bcm63xx clk code ignores the struct device argument and looks up a global clock name. DT platforms, by contrast, often just use a phandle to reference a clock node with no "clock-output-names" property. Modify the UART driver to support both schemes. Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 231519022b73..de955732607d 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -824,7 +824,8 @@ static int bcm_uart_probe(struct platform_device *pdev) if (!res_irq) return -ENODEV; - clk = clk_get(&pdev->dev, "periph"); + clk = pdev->dev.of_node ? of_clk_get(pdev->dev.of_node, 0) : + clk_get(&pdev->dev, "periph"); if (IS_ERR(clk)) return -ENODEV; -- GitLab From 4b65208f3ab62e0eb2a8052c7ceec090d6d5617d Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:22:59 -0700 Subject: [PATCH 3537/9457] tty: serial: bcm63xx: Update the Kconfig help text Remove incorrect "bcm963xx_uart" module name; add a list of known users; tweak grammar/indentation/capitalization. Signed-off-by: Kevin Cernekee Acked-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9503789ece94..5210c9f62302 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1281,22 +1281,24 @@ config SERIAL_TIMBERDALE Add support for UART controller on timberdale. config SERIAL_BCM63XX - tristate "bcm63xx serial port support" + tristate "Broadcom BCM63xx/BCM33xx UART support" select SERIAL_CORE depends on MIPS || ARM || COMPILE_TEST help - If you have a bcm63xx CPU, you can enable its onboard - serial port by enabling this options. + This enables the driver for the onchip UART core found on + the following chipsets: - To compile this driver as a module, choose M here: the - module will be called bcm963xx_uart. + BCM33xx (cable modem) + BCM63xx/BCM63xxx (DSL) + BCM68xx (PON) + BCM7xxx (STB) - DOCSIS console config SERIAL_BCM63XX_CONSOLE - bool "Console on bcm63xx serial port" + bool "Console on BCM63xx serial port" depends on SERIAL_BCM63XX=y select SERIAL_CORE_CONSOLE help - If you have enabled the serial port on the bcm63xx CPU + If you have enabled the serial port on the BCM63xx CPU you can make it the console by answering Y to this option. config SERIAL_GRLIB_GAISLER_APBUART -- GitLab From 4137cd9b5c79ff213731865b0ac227c6d8c32e4b Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:23:00 -0700 Subject: [PATCH 3538/9457] tty: serial: bcm63xx: Fix typo in MODULE_DESCRIPTION Remove the extra '<' character. Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index de955732607d..b615af2230aa 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -906,5 +906,5 @@ module_init(bcm_uart_init); module_exit(bcm_uart_exit); MODULE_AUTHOR("Maxime Bizon "); -MODULE_DESCRIPTION("Broadcom 63 Date: Tue, 21 Oct 2014 15:23:01 -0700 Subject: [PATCH 3539/9457] Documentation: DT: Add entries for bcm63xx UART This squashes a checkpatch warning on my new bcm3384 dts submission. Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/bcm63xx-uart.txt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/bcm63xx-uart.txt diff --git a/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt b/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt new file mode 100644 index 000000000000..5c52e5eef16d --- /dev/null +++ b/Documentation/devicetree/bindings/serial/bcm63xx-uart.txt @@ -0,0 +1,30 @@ +* BCM63xx UART + +Required properties: + +- compatible: "brcm,bcm6345-uart" + +- reg: The base address of the UART register bank. + +- interrupts: A single interrupt specifier. + +- clocks: Clock driving the hardware; used to figure out the baud rate + divisor. + +Example: + + uart0: serial@14e00520 { + compatible = "brcm,bcm6345-uart"; + reg = <0x14e00520 0x18>; + interrupt-parent = <&periph_intc>; + interrupts = <2>; + clocks = <&periph_clk>; + }; + + clocks { + periph_clk: periph_clk@0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <54000000>; + }; + }; -- GitLab From 1ab8e4b1acdf39ebe6002bbe07ef6e578cff5d74 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:23:02 -0700 Subject: [PATCH 3540/9457] tty: serial: bcm63xx: Enable DT earlycon support This enables early console output if there is a chosen/stdout-path property referencing a UART node with the "brcm,bcm6345-uart" compatible string. The bootloader sets up the pinmux and baud/parity/etc. Tested on bcm3384 (MIPS, DT). Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/bcm63xx_uart.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 5210c9f62302..7088373efc15 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1297,6 +1297,7 @@ config SERIAL_BCM63XX_CONSOLE bool "Console on BCM63xx serial port" depends on SERIAL_BCM63XX=y select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON help If you have enabled the serial port on the BCM63xx CPU you can make it the console by answering Y to this option. diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index b615af2230aa..109dea711318 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -782,6 +782,26 @@ static int __init bcm63xx_console_init(void) console_initcall(bcm63xx_console_init); +static void bcm_early_write(struct console *con, const char *s, unsigned n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, bcm_console_putchar); + wait_for_xmitr(&dev->port); +} + +static int __init bcm_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = bcm_early_write; + return 0; +} + +OF_EARLYCON_DECLARE(bcm63xx_uart, "brcm,bcm6345-uart", bcm_early_console_setup); + #define BCM63XX_CONSOLE (&bcm63xx_console) #else #define BCM63XX_CONSOLE NULL -- GitLab From e979f3b712c8b8ae44bab591427f1647dd25aa0d Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:23:03 -0700 Subject: [PATCH 3541/9457] tty: serial: bcm63xx: Eliminate unnecessary request/release functions We don't really need to perform the ioremap "on demand" so it's simpler just to do it from the probe function. This also lets us eliminate the UART_REG_SIZE constant and rely on the resource information passed in from the DT or platform code. Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 30 ++++++++++-------------------- include/linux/serial_bcm63xx.h | 2 -- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 109dea711318..e04e5805ae6e 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -588,20 +588,7 @@ static void bcm_uart_set_termios(struct uart_port *port, */ static int bcm_uart_request_port(struct uart_port *port) { - unsigned int size; - - size = UART_REG_SIZE; - if (!request_mem_region(port->mapbase, size, "bcm63xx")) { - dev_err(port->dev, "Memory region busy\n"); - return -EBUSY; - } - - port->membase = ioremap(port->mapbase, size); - if (!port->membase) { - dev_err(port->dev, "Unable to map registers\n"); - release_mem_region(port->mapbase, size); - return -EBUSY; - } + /* UARTs always present */ return 0; } @@ -610,8 +597,7 @@ static int bcm_uart_request_port(struct uart_port *port) */ static void bcm_uart_release_port(struct uart_port *port) { - release_mem_region(port->mapbase, UART_REG_SIZE); - iounmap(port->membase); + /* Nothing to release ... */ } /* @@ -833,13 +819,20 @@ static int bcm_uart_probe(struct platform_device *pdev) if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) return -EINVAL; - if (ports[pdev->id].membase) + port = &ports[pdev->id]; + if (port->membase) return -EBUSY; + memset(port, 0, sizeof(*port)); res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res_mem) return -ENODEV; + port->mapbase = res_mem->start; + port->membase = devm_ioremap_resource(&pdev->dev, res_mem); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res_irq) return -ENODEV; @@ -849,10 +842,7 @@ static int bcm_uart_probe(struct platform_device *pdev) if (IS_ERR(clk)) return -ENODEV; - port = &ports[pdev->id]; - memset(port, 0, sizeof(*port)); port->iotype = UPIO_MEM; - port->mapbase = res_mem->start; port->irq = res_irq->start; port->ops = &bcm_uart_ops; port->flags = UPF_BOOT_AUTOCONF; diff --git a/include/linux/serial_bcm63xx.h b/include/linux/serial_bcm63xx.h index a80aa1a5bee2..570e964dc899 100644 --- a/include/linux/serial_bcm63xx.h +++ b/include/linux/serial_bcm63xx.h @@ -116,6 +116,4 @@ UART_FIFO_PARERR_MASK | \ UART_FIFO_BRKDET_MASK) -#define UART_REG_SIZE 24 - #endif /* _LINUX_SERIAL_BCM63XX_H */ -- GitLab From 7645c2f4677198df449228a4736d7f94e5c14156 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 21 Oct 2014 15:23:06 -0700 Subject: [PATCH 3542/9457] MAINTAINERS: Add entry for rp2 (Rocketport Express/Infinity) driver I wrote this driver and use it daily on several machines for work, so why not. Signed-off-by: Kevin Cernekee Acked-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3c6427190be2..878a56066924 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7813,6 +7813,12 @@ S: Maintained F: Documentation/serial/rocket.txt F: drivers/tty/rocket* +ROCKETPORT EXPRESS/INFINITY DRIVER +M: Kevin Cernekee +L: linux-serial@vger.kernel.org +S: Odd Fixes +F: drivers/tty/serial/rp2.* + ROSE NETWORK LAYER M: Ralf Baechle L: linux-hams@vger.kernel.org -- GitLab From 2a768264eef098cc1355b02ca5023b6cfb183a1f Mon Sep 17 00:00:00 2001 From: Eddie Huang Date: Wed, 22 Oct 2014 21:12:07 +0800 Subject: [PATCH 3543/9457] tty: serial: Fix mediatek UART driver setting baudrate issue In mtk8250_set_termios function, calculating quot value can not be zero, otherwise, using DIV_ROUND_CLOSEST(port->uartclk, quot * baud) will fail due to divisor is zero. Signed-off-by: Eddie Huang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_mtk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 8f37d57165ec..6f93123a428a 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -74,14 +74,14 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, /* Set to next lower baudrate supported */ if ((baud == 500000) || (baud == 576000)) baud = 460800; - quot = DIV_ROUND_CLOSEST(port->uartclk, 4 * baud); + quot = DIV_ROUND_UP(port->uartclk, 4 * baud); } else { serial_port_out(port, UART_MTK_HIGHS, 0x3); /* Set to highest baudrate supported */ if (baud >= 1152000) baud = 921600; - quot = DIV_ROUND_CLOSEST(port->uartclk, 256 * baud); + quot = DIV_ROUND_UP(port->uartclk, 256 * baud); } /* -- GitLab From 5483c10e03c6e37b81b79bf88749bcfbe474a639 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 22 Oct 2014 17:43:16 +0200 Subject: [PATCH 3544/9457] serial: at91: Use dmaengine_slave_config API We are removing the dmaengine_device_control API, that shouldn't even have been exposed in the first place. Change the callers to use the proper API. Signed-off-by: Maxime Ripard Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 9eb624a22431..b9987109b2da 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -862,9 +862,8 @@ static int atmel_prepare_tx_dma(struct uart_port *port) config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; config.dst_addr = port->mapbase + ATMEL_US_THR; - ret = dmaengine_device_control(atmel_port->chan_tx, - DMA_SLAVE_CONFIG, - (unsigned long)&config); + ret = dmaengine_slave_config(atmel_port->chan_tx, + &config); if (ret) { dev_err(port->dev, "DMA tx slave configuration failed\n"); goto chan_err; @@ -1042,9 +1041,8 @@ static int atmel_prepare_rx_dma(struct uart_port *port) config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; config.src_addr = port->mapbase + ATMEL_US_RHR; - ret = dmaengine_device_control(atmel_port->chan_rx, - DMA_SLAVE_CONFIG, - (unsigned long)&config); + ret = dmaengine_slave_config(atmel_port->chan_rx, + &config); if (ret) { dev_err(port->dev, "DMA rx slave configuration failed\n"); goto chan_err; -- GitLab From 08de1014ffd49f156b8b9a0a88ed6dff9a52a275 Mon Sep 17 00:00:00 2001 From: Jingchang Lu Date: Fri, 24 Oct 2014 17:20:49 +0800 Subject: [PATCH 3545/9457] serial: fsl-lpuart: add lpuart32 power management support This adds 32-bit register lpuart32 power management support, this also updates the 8-bit register lpuart resume function. Signed-off-by: Jingchang Lu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 6dd53af546a3..4e2577249ac5 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1862,6 +1862,20 @@ static int lpuart_suspend(struct device *dev) static int lpuart_resume(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); + unsigned long temp; + + if (sport->lpuart32) { + lpuart32_setup_watermark(sport); + temp = lpuart32_read(sport->port.membase + UARTCTRL); + temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | + UARTCTRL_TE | UARTCTRL_ILIE); + lpuart32_write(temp, sport->port.membase + UARTCTRL); + } else { + lpuart_setup_watermark(sport); + temp = readb(sport->port.membase + UARTCR2); + temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE); + writeb(temp, sport->port.membase + UARTCR2); + } uart_resume_port(&lpuart_reg, &sport->port); -- GitLab From 398a9db655efcc208285997c351fe73702735d88 Mon Sep 17 00:00:00 2001 From: Aaron Sierra Date: Thu, 30 Oct 2014 19:49:45 -0500 Subject: [PATCH 3546/9457] serial: 8250_pci: Handle devices mapped above 4 GiB Several init/setup functions passed the PCI BAR resource start address to ioremap_nocache() via an unsigned long. This caused address truncation for a 32-bit device mapped above 4 GiB (i.e. the CPU interacts with the device via a translated address), which resulted in a kernel panic. This patch replaces all of the instances of intermediate variable use with pci_ioremap_bar() to ensure the full resource_size_t start address is used and that ioremap_nocache() is still called. The kernel panic (Exar XR17V358 PCIe device on a Freescale P2020 SBC): Machine check in kernel mode. Caused by (from MCSR=10008): Bus - Read Data Bus Error Oops: Machine check, sig: 7 [#1] SMP NR_CPUS=2 X-ES P2020 Modules linked in: CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.14.15-xes_r2-00002-g560e401 #978 task: bf850000 ti: bffee000 task.ti: bf84c000 NIP: 80318e10 LR: 80319ecc CTR: 80318dfc REGS: bffeff10 TRAP: 0204 Not tainted (3.14.15-xes_r2-00002-g560e401) MSR: 00021000 CR: 20adbe42 XER: 00000000 DEAR: c1058001 ESR: 00000000 GPR00: 00000000 bf84db30 bf850000 80cb4af8 00000001 00000000 80000007 80000000 GPR08: bf837c9c c1058001 00000001 00000000 80000007 00000000 80002a10 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 80cb0000 80c72dc4 GPR24: 80cb4900 fffffffe 00029000 00000001 bf8c11e8 ffffffea 80c72ce4 80cb4af8 NIP [80318e10] mem_serial_in+0x14/0x28 LR [80319ecc] serial8250_config_port+0x160/0xe38 Call Trace: [bf84db30] [80319d94] serial8250_config_port+0x28/0xe38 (unreliable) [bf84db60] [80315e3c] uart_add_one_port+0x148/0x3a4 [bf84dbf0] [8031bf40] serial8250_register_8250_port+0x2dc/0x3c8 [bf84dc20] [8032111c] pciserial_init_ports+0xd4/0x1c0 [bf84dd50] [803212f8] pciserial_init_one+0xf0/0x224 [bf84dd90] [802d8ff4] local_pci_probe+0x34/0x8c [bf84dda0] [802d92c8] pci_device_probe+0x84/0xa0 [bf84ddc0] [80329ee0] driver_probe_device+0xac/0x26c [bf84dde0] [8032a15c] __driver_attach+0xbc/0xc0 [bf84de00] [80328388] bus_for_each_dev+0x90/0xcc [bf84de30] [80329cd0] driver_attach+0x24/0x34 [bf84de40] [80328e28] bus_add_driver+0x104/0x1fc [bf84de60] [8032a8c8] driver_register+0x70/0x138 [bf84de70] [802d93c0] __pci_register_driver+0x48/0x58 [bf84de80] [8077e0e4] serial_pci_driver_init+0x24/0x34 [bf84de90] [80002228] do_one_initcall+0x34/0x1b0 [bf84df00] [80764294] kernel_init_freeable+0x138/0x1e8 [bf84df30] [80002a24] kernel_init+0x14/0x108 [bf84df40] [8000ef94] ret_from_kernel_thread+0x5c/0x64 Instruction dump: 800800c4 7d290214 39290001 7c0004ac 7ca049ae 7c0004ac 4e800020 88030035 81230008 7c840030 7d292214 7c0004ac <88690000> 0c030000 4c00012c 5463063e ---[ end trace e3c16443b5d573c6 ]--- Signed-off-by: Aaron Sierra Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 47 +++++++++++------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index a9b935a9b462..50f75703fd54 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -79,29 +79,24 @@ setup_port(struct serial_private *priv, struct uart_8250_port *port, int bar, int offset, int regshift) { struct pci_dev *dev = priv->dev; - unsigned long base, len; if (bar >= PCI_NUM_BAR_RESOURCES) return -EINVAL; - base = pci_resource_start(dev, bar); - if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) { - len = pci_resource_len(dev, bar); - if (!priv->remapped_bar[bar]) - priv->remapped_bar[bar] = ioremap_nocache(base, len); + priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar); if (!priv->remapped_bar[bar]) return -ENOMEM; port->port.iotype = UPIO_MEM; port->port.iobase = 0; - port->port.mapbase = base + offset; + port->port.mapbase = pci_resource_start(dev, bar) + offset; port->port.membase = priv->remapped_bar[bar] + offset; port->port.regshift = regshift; } else { port->port.iotype = UPIO_PORT; - port->port.iobase = base + offset; + port->port.iobase = pci_resource_start(dev, bar) + offset; port->port.mapbase = 0; port->port.membase = NULL; port->port.regshift = 0; @@ -317,7 +312,6 @@ static void pci_plx9050_exit(struct pci_dev *dev) static void pci_ni8420_exit(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -325,9 +319,7 @@ static void pci_ni8420_exit(struct pci_dev *dev) return; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return; @@ -349,7 +341,6 @@ static void pci_ni8420_exit(struct pci_dev *dev) static void pci_ni8430_exit(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -357,9 +348,7 @@ static void pci_ni8430_exit(struct pci_dev *dev) return; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return; @@ -682,7 +671,6 @@ static int pci_xircom_init(struct pci_dev *dev) static int pci_ni8420_init(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; unsigned int bar = 0; if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) { @@ -690,9 +678,7 @@ static int pci_ni8420_init(struct pci_dev *dev) return 0; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return -ENOMEM; @@ -714,7 +700,7 @@ static int pci_ni8420_init(struct pci_dev *dev) static int pci_ni8430_init(struct pci_dev *dev) { void __iomem *p; - unsigned long base, len; + struct pci_bus_region region; u32 device_window; unsigned int bar = 0; @@ -723,14 +709,17 @@ static int pci_ni8430_init(struct pci_dev *dev) return 0; } - base = pci_resource_start(dev, bar); - len = pci_resource_len(dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); if (p == NULL) return -ENOMEM; - /* Set device window address and size in BAR0 */ - device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) + /* + * Set device window address and size in BAR0, while acknowledging that + * the resource structure may contain a translated address that differs + * from the address the device responds to. + */ + pcibios_resource_to_bus(dev->bus, ®ion, &dev->resource[bar]); + device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00) | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE; writel(device_window, p + MITE_IOWBSR1); @@ -757,8 +746,8 @@ pci_ni8430_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { + struct pci_dev *dev = priv->dev; void __iomem *p; - unsigned long base, len; unsigned int bar, offset = board->first_offset; if (idx >= board->num_ports) @@ -767,9 +756,7 @@ pci_ni8430_setup(struct serial_private *priv, bar = FL_GET_BASE(board->flags); offset += idx * board->uart_offset; - base = pci_resource_start(priv->dev, bar); - len = pci_resource_len(priv->dev, bar); - p = ioremap_nocache(base, len); + p = pci_ioremap_bar(dev, bar); /* enable the transceiver */ writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, -- GitLab From 5d14bba91d8c350b21d28834fab95f67a46a264e Mon Sep 17 00:00:00 2001 From: Aaron Sierra Date: Thu, 30 Oct 2014 19:49:52 -0500 Subject: [PATCH 3547/9457] serial: 8250_pci: Check mapping in pci_ni8430_init Check the return value of ioremap_nocache to make sure we got a valid mapping. Signed-off-by: Aaron Sierra Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 50f75703fd54..003679fc884b 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -757,6 +757,8 @@ pci_ni8430_setup(struct serial_private *priv, offset += idx * board->uart_offset; p = pci_ioremap_bar(dev, bar); + if (!p) + return -ENOMEM; /* enable the transceiver */ writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE, -- GitLab From 1bd8324535ec1ff44aef55c0e40b9e7d56b310fb Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 3 Nov 2014 23:16:54 +0100 Subject: [PATCH 3548/9457] serial: of-serial: fetch line number from DT The general agreed way to specify a fixed line number for a serial console is to provide a "serial" alias in the devicetree. Start parsing this property in of_serial. Signed-off-by: Lucas Stach Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 8749fb849803..7bc163421be4 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -102,6 +102,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_property_read_u32(np, "fifo-size", &prop) == 0) port->fifosize = prop; + /* Check for a fixed line number */ + if ((ret = of_alias_get_id(np, "serial")) >= 0) + port->line = ret; + port->irq = irq_of_parse_and_map(np, 0); port->iotype = UPIO_MEM; if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { -- GitLab From f77d55a3b56a98d14b6e7dc549c24b33011d175d Mon Sep 17 00:00:00 2001 From: Julien CHAUVEAU Date: Tue, 4 Nov 2014 11:45:55 +0100 Subject: [PATCH 3549/9457] serial: 8250_dw: get index of serial line from DT aliases Get index of serial line from device tree using function of_alias_get_id(). If no alias is found, the 8250 core takes care of incrementing the line number. Signed-off-by: Julien CHAUVEAU Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 73a14ae8f0ae..18ff53298d2f 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -258,6 +258,7 @@ static int dw8250_probe_of(struct uart_port *p, struct uart_8250_port *up = up_to_u8250p(p); u32 val; bool has_ucv = true; + int id; if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { #ifdef __BIG_ENDIAN @@ -301,6 +302,11 @@ static int dw8250_probe_of(struct uart_port *p, if (!of_property_read_u32(np, "reg-shift", &val)) p->regshift = val; + /* get index of serial line, if found in DT aliases */ + id = of_alias_get_id(np, "serial"); + if (id >= 0) + p->line = id; + /* clock got configured through clk api, all done */ if (p->uartclk) return 0; -- GitLab From 19038ad9f08c96dcff870b18af8fd5ae5141dec1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 5 Nov 2014 13:35:16 +0100 Subject: [PATCH 3550/9457] tty: xuartps: Add support for setting modem control signals Add support for setting the state of the DTR and RTS signals. Acked-by: Soren Brinkmann Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 200c1af2141b..542bab37e502 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -132,6 +132,15 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); /* Goes in read_status_mask for break detection as the HW doesn't do it*/ #define CDNS_UART_IXR_BRK 0x80000000 +/* + * Modem Control register: + * The read/write Modem Control register controls the interface with the modem + * or data set, or a peripheral device emulating a modem. + */ +#define CDNS_UART_MODEMCR_FCM 0x00000020 /* Automatic flow control mode */ +#define CDNS_UART_MODEMCR_RTS 0x00000002 /* Request to send output control */ +#define CDNS_UART_MODEMCR_DTR 0x00000001 /* Data Terminal Ready */ + /* * Channel Status Register: * The channel status register (CSR) is provided to enable the control logic @@ -915,7 +924,18 @@ static unsigned int cdns_uart_get_mctrl(struct uart_port *port) static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - /* N/A */ + u32 val; + + val = cdns_uart_readl(CDNS_UART_MODEMCR_OFFSET); + + val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR); + + if (mctrl & TIOCM_RTS) + val |= CDNS_UART_MODEMCR_RTS; + if (mctrl & TIOCM_DTR) + val |= CDNS_UART_MODEMCR_DTR; + + cdns_uart_writel(val, CDNS_UART_MODEMCR_OFFSET); } #ifdef CONFIG_CONSOLE_POLL -- GitLab From 633caba8932d9ba2f79bbcb7573e58eae3fdac68 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 12:40:03 -0500 Subject: [PATCH 3551/9457] tty: Move tty hung up check from port->lock critical section The port->lock does not protect the filp->f_op field; move the tty_hung_up_p() test outside the port->lock critical section in tty_port_close_start(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 1b9335796da4..3b641d115fd2 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -473,12 +473,10 @@ int tty_port_close_start(struct tty_port *port, { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->lock, flags); + if (tty_hung_up_p(filp)) return 0; - } + spin_lock_irqsave(&port->lock, flags); if (tty->count == 1 && port->count != 1) { printk(KERN_WARNING "tty_port_close_start: tty->count = 1 port count = %d.\n", -- GitLab From 413ba6385382bc80e4bf2f58efa900e82e810b11 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 12:40:04 -0500 Subject: [PATCH 3552/9457] tty: Convert tty->closing to int tty->closing is a bitfield member; prevent corruption from non-atomic update by assigning a unique memory location. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/tty.h b/include/linux/tty.h index c52a689e09aa..7d66ae508e5c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -284,7 +284,7 @@ struct tty_struct { #define N_TTY_BUF_SIZE 4096 - unsigned char closing:1; + int closing; unsigned char *write_buf; int write_cnt; /* If the tty has a pending do_SAK, queue it here - akpm */ -- GitLab From 3f40f5b2a22110754ce469f5722bade8aeb241e5 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 12:40:05 -0500 Subject: [PATCH 3553/9457] tty: Flush tty buffers after hardware shutdown The line discipline buffer and the tty buffers must be flushed again after hardware shutdown; otherwise, a brief window exists between the ldisc flush in tty_port_close_start() and the subsequent tty_port_shutdown(), during which more data could be received into the tty buffers. A racing open might then be able to receive data from the previous session. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 3b641d115fd2..4d9abaa81be4 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -520,6 +520,7 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) { unsigned long flags; + tty_ldisc_flush(tty); tty->closing = 0; spin_lock_irqsave(&port->lock, flags); -- GitLab From 9191aaaa82d3149767125d58b2d260a3749d9f5e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 13:11:41 -0500 Subject: [PATCH 3554/9457] tty: Allow safe access to termios for set_ldisc() handlers Allow a tty driver to safely access termios settings while handling the set_ldisc() notification. UART drivers use the set_ldisc() notification to check if the N_PPS line discipline is being enabled; if so, modem status interrupts may also need to be enabled. Conversely, modem status interrupts may need to be disabled if switching away from the N_PPS line discipline. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index b66a81d0549e..3737f55272d2 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -572,8 +572,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_restore(tty, old_ldisc); } - if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) + if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) { + down_read(&tty->termios_rwsem); tty->ops->set_ldisc(tty); + up_read(&tty->termios_rwsem); + } /* At this point we hold a reference to the new ldisc and a reference to the old ldisc, or we hold two references to -- GitLab From db1b9dfcd622604b268234e01c539927093abce7 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 13:11:42 -0500 Subject: [PATCH 3555/9457] serial: core: Claim port mutex for set_ldisc() Three UART drivers (8250, atmel & amba-pl010) enable modem status interrupts if the line discipline is changed to N_PPS. However, the uart port flags may only be safely modified while holding the port mutex. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 1a2d90fe86da..5209eaaa7225 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1245,8 +1245,11 @@ static void uart_set_ldisc(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *uport = state->uart_port; - if (uport->ops->set_ldisc) + if (uport->ops->set_ldisc) { + mutex_lock(&state->port.mutex); uport->ops->set_ldisc(uport, tty->termios.c_line); + mutex_unlock(&state->port.mutex); + } } static void uart_set_termios(struct tty_struct *tty, -- GitLab From 732a84a037a4de29b54e0b4e6cb6f9b3813e29e5 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 13:11:43 -0500 Subject: [PATCH 3556/9457] serial: core: Pass termios to set_ldisc() notifications UART drivers which enable modem status interrupts when switching to N_PPS line discipline need to determine if modem status interrupts should be disabled when switching from N_PPS. Specifically, the set_ldisc() notification needs to evaluate UART_ENABLE_MS() which requires termios->c_cflag. Convert in-tree UART drivers to new interface. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 4 ++-- drivers/tty/serial/amba-pl010.c | 4 ++-- drivers/tty/serial/atmel_serial.c | 4 ++-- drivers/tty/serial/bfin_uart.c | 5 +++-- drivers/tty/serial/clps711x.c | 5 +++-- drivers/tty/serial/serial_core.c | 2 +- include/linux/serial_core.h | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 223503299e99..116b5a75f1af 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2609,9 +2609,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, } static void -serial8250_set_ldisc(struct uart_port *port, int new) +serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) { - if (new == N_PPS) { + if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; serial8250_enable_ms(port); } else diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 00ae8dcabc9b..230bc7a290d5 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -479,9 +479,9 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, spin_unlock_irqrestore(&uap->port.lock, flags); } -static void pl010_set_ldisc(struct uart_port *port, int new) +static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) { - if (new == N_PPS) { + if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; pl010_enable_ms(port); } else diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index b9987109b2da..6a1d960e2e82 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2056,9 +2056,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, spin_unlock_irqrestore(&port->lock, flags); } -static void atmel_set_ldisc(struct uart_port *port, int new) +static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) { - if (new == N_PPS) { + if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; atmel_enable_ms(port); } else { diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 7da9911e95f0..44b27ec32341 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -944,12 +944,13 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) * Enable the IrDA function if tty->ldisc.num is N_IRDA. * In other cases, disable IrDA function. */ -static void bfin_serial_set_ldisc(struct uart_port *port, int ld) +static void bfin_serial_set_ldisc(struct uart_port *port, + struct ktermios *termios) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; unsigned int val; - switch (ld) { + switch (termios->c_line) { case N_IRDA: val = UART_GET_GCTL(uart); val |= (UMOD_IRDA | RPOLC); diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index acfe31773643..f963c4c48085 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -225,13 +225,14 @@ static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) writel(ubrlcr, port->membase + UBRLCR_OFFSET); } -static void uart_clps711x_set_ldisc(struct uart_port *port, int ld) +static void uart_clps711x_set_ldisc(struct uart_port *port, + struct ktermios *termios) { if (!port->line) { struct clps711x_port *s = dev_get_drvdata(port->dev); regmap_update_bits(s->syscon, SYSCON_OFFSET, SYSCON1_SIREN, - (ld == N_IRDA) ? SYSCON1_SIREN : 0); + (termios->c_line == N_IRDA) ? SYSCON1_SIREN : 0); } } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 5209eaaa7225..c5fb08cfbdb1 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1247,7 +1247,7 @@ static void uart_set_ldisc(struct tty_struct *tty) if (uport->ops->set_ldisc) { mutex_lock(&state->port.mutex); - uport->ops->set_ldisc(uport, tty->termios.c_line); + uport->ops->set_ldisc(uport, &tty->termios); mutex_unlock(&state->port.mutex); } } diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index ad9329669aba..40b4cc4f8e1d 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -63,7 +63,7 @@ struct uart_ops { void (*flush_buffer)(struct uart_port *); void (*set_termios)(struct uart_port *, struct ktermios *new, struct ktermios *old); - void (*set_ldisc)(struct uart_port *, int new); + void (*set_ldisc)(struct uart_port *, struct ktermios *); void (*pm)(struct uart_port *, unsigned int state, unsigned int oldstate); -- GitLab From d41510ce2f071c9ccb1903d7a5135443a57dbe4e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 13:11:44 -0500 Subject: [PATCH 3557/9457] serial: Take uart port lock for direct *_enable_ms() Three UART drivers (8250, atmel & amba-pl010) directly call their enable_ms() method; the uart port lock must be acquired before any h/w programming. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 2 ++ drivers/tty/serial/amba-pl010.c | 2 ++ drivers/tty/serial/atmel_serial.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 116b5a75f1af..f0f35e782bc3 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -2613,7 +2613,9 @@ serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; + spin_lock_irq(&port->lock); serial8250_enable_ms(port); + spin_unlock_irq(&port->lock); } else port->flags &= ~UPF_HARDPPS_CD; } diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 230bc7a290d5..194108b0de84 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -483,7 +483,9 @@ static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; + spin_lock_irq(&port->lock); pl010_enable_ms(port); + spin_unlock_irq(&port->lock); } else port->flags &= ~UPF_HARDPPS_CD; } diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 6a1d960e2e82..e67cb3831280 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2060,7 +2060,9 @@ static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) { if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; + spin_lock_irq(&port->lock); atmel_enable_ms(port); + spin_unlock_irq(&port->lock); } else { port->flags &= ~UPF_HARDPPS_CD; } -- GitLab From cab68f89546ba5a04bf28aaeaca841d4ccc2fd52 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 Nov 2014 13:11:45 -0500 Subject: [PATCH 3558/9457] serial: Test/disable MSIs if switching from N_PPS Switching to the N_PPS line discipline may require enabling modem status interrupts; conversely switching from N_PPS may require disabling modem status interrupts. Affected drivers: 8250 amba-pl010 atmel Cc: Nicolas Ferre Cc: Russell King Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 21 ++++++++++++++++++++- drivers/tty/serial/amba-pl010.c | 18 +++++++++++++++++- drivers/tty/serial/atmel_serial.c | 5 +++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index f0f35e782bc3..25eb8e93615d 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1402,6 +1402,19 @@ static void serial8250_stop_rx(struct uart_port *port) serial8250_rpm_put(up); } +static void serial8250_disable_ms(struct uart_port *port) +{ + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + + /* no MSR capabilities */ + if (up->bugs & UART_BUG_NOMSR) + return; + + up->ier &= ~UART_IER_MSI; + serial_port_out(port, UART_IER, up->ier); +} + static void serial8250_enable_ms(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); @@ -2616,8 +2629,14 @@ serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios) spin_lock_irq(&port->lock); serial8250_enable_ms(port); spin_unlock_irq(&port->lock); - } else + } else { port->flags &= ~UPF_HARDPPS_CD; + if (!UART_ENABLE_MS(port, termios->c_cflag)) { + spin_lock_irq(&port->lock); + serial8250_disable_ms(port); + spin_unlock_irq(&port->lock); + } + } } diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 194108b0de84..5d41d5b92619 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -106,6 +106,16 @@ static void pl010_stop_rx(struct uart_port *port) writel(cr, uap->port.membase + UART010_CR); } +static void pl010_disable_ms(struct uart_port *port) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr; + + cr = readb(uap->port.membase + UART010_CR); + cr &= ~UART010_CR_MSIE; + writel(cr, uap->port.membase + UART010_CR); +} + static void pl010_enable_ms(struct uart_port *port) { struct uart_amba_port *uap = @@ -486,8 +496,14 @@ static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios) spin_lock_irq(&port->lock); pl010_enable_ms(port); spin_unlock_irq(&port->lock); - } else + } else { port->flags &= ~UPF_HARDPPS_CD; + if (!UART_ENABLE_MS(port, termios->c_cflag)) { + spin_lock_irq(&port->lock); + pl010_disable_ms(port); + spin_unlock_irq(&port->lock); + } + } } static const char *pl010_type(struct uart_port *port) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index e67cb3831280..b1d61dc3fc1b 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2065,6 +2065,11 @@ static void atmel_set_ldisc(struct uart_port *port, struct ktermios *termios) spin_unlock_irq(&port->lock); } else { port->flags &= ~UPF_HARDPPS_CD; + if (!UART_ENABLE_MS(port, termios->c_cflag)) { + spin_lock_irq(&port->lock); + atmel_disable_ms(port); + spin_unlock_irq(&port->lock); + } } } -- GitLab From 2fdd8c8c5304901fa7dbb2ce5dbc90a1984cee3d Mon Sep 17 00:00:00 2001 From: Sergej Pupykin Date: Thu, 6 Nov 2014 14:36:31 +0300 Subject: [PATCH 3559/9457] parport: Add support for the WCH382 2S/1P multi-IO card WCH382 is a PCI-E card with 1 LPT and 2 DB9 COM ports detected as Serial controller: Device 1c00:3250 (rev 10) (prog-if 05 [16850]) Signed-off-by: Sergej Pupykin Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_serial.c | 10 ++++++++++ drivers/tty/serial/8250/8250_pci.c | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index ee932004724f..e15b4845f7c6 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -64,6 +64,7 @@ enum parport_pc_pci_cards { timedia_9079c, wch_ch353_1s1p, wch_ch353_2s1p, + wch_ch382_2s1p, sunix_2s1p, }; @@ -151,6 +152,7 @@ static struct parport_pc_pci cards[] = { /* timedia_9079c */ { 1, { { 2, 3 }, } }, /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } }, /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, + /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } }, /* sunix_2s1p */ { 1, { { 3, -1 }, } }, }; @@ -257,6 +259,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = { /* WCH CARDS */ { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p}, { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, + { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p}, /* * More SUNIX variations. At least one of these has part number @@ -494,6 +497,13 @@ static struct pciserial_board pci_parport_serial_boards[] = { .base_baud = 115200, .uart_offset = 8, }, + [wch_ch382_2s1p] = { + .flags = FL_BASE0, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + .first_offset = 0xC0, + }, [sunix_2s1p] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 003679fc884b..0468e15e6f10 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1783,6 +1783,16 @@ pci_wch_ch353_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int +pci_wch_ch382_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_8250_port *port, int idx) +{ + port->port.flags |= UPF_FIXED_TYPE; + port->port.type = PORT_16850; + return pci_default_setup(priv, board, port, idx); +} + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1837,6 +1847,8 @@ pci_wch_ch353_setup(struct serial_private *priv, #define PCI_VENDOR_ID_SUNIX 0x1fd4 #define PCI_DEVICE_ID_SUNIX_1999 0x1999 +#define PCIE_VENDOR_ID_WCH 0x1c00 +#define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -2528,6 +2540,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, + /* WCH CH382 2S1P card (16750 clone) */ + { + .vendor = PCIE_VENDOR_ID_WCH, + .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch382_setup, + }, /* * ASIX devices with FIFO bug */ @@ -3635,6 +3655,7 @@ static const struct pci_device_id blacklist[] = { /* multi-io cards handled by parport_serial */ { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ + { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ }; /* -- GitLab From 7f1dc2f384792f271833cd89a8608d189b63ea6d Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 16 Oct 2014 14:16:22 +0530 Subject: [PATCH 3560/9457] serial: 8250: sparse warning of incorrect type fixed a sparse warning in 8250_core.c : incorrect type in assignment (different address spaces) the warning was because an unsigned char pointer was being assigned to a pointer of unsigned char __iomem type . Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 458ad28338fe..b00836851061 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -56,7 +56,7 @@ struct old_serial_port { unsigned int flags; unsigned char hub6; unsigned char io_type; - unsigned char *iomem_base; + unsigned char __iomem *iomem_base; unsigned short iomem_reg_shift; unsigned long irqflags; }; -- GitLab From a5f276f10ff70da89b349df445e944c8cd87956c Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 22:46:13 +0100 Subject: [PATCH 3561/9457] serial_core: Handle TIOC[GS]RS485 ioctls. The following drivers: 8250_core, atmel_serial, max310x, mcf, omap-serial and sci16is7xx implement code to handle RS485 ioctls. In order to avoid code duplication, we implement a simple ioctl handler on the serial_core layer. This handler can be used by all the other drivers instead of duplicating code. Until this is the only RS485 ioctl handler, it will try first the rs485_config callback and if it is not present it will call the driver specific ioctl. Reviewed-by: Alan Cox Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 45 ++++++++++++++++++++++++++++++++ include/linux/serial_core.h | 3 +++ 2 files changed, 48 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index c5fb08cfbdb1..ab4db1dcc474 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1152,6 +1152,39 @@ static int uart_get_icount(struct tty_struct *tty, return 0; } +static int uart_get_rs485_config(struct uart_port *port, + struct serial_rs485 __user *rs485) +{ + if (!port->rs485_config) + return -ENOIOCTLCMD; + + if (copy_to_user(rs485, &port->rs485, sizeof(port->rs485))) + return -EFAULT; + return 0; +} + +static int uart_set_rs485_config(struct uart_port *port, + struct serial_rs485 __user *rs485_user) +{ + struct serial_rs485 rs485; + int ret; + + if (!port->rs485_config) + return -ENOIOCTLCMD; + + if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) + return -EFAULT; + + ret = port->rs485_config(port, &rs485); + if (ret) + return ret; + + if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485))) + return -EFAULT; + + return 0; +} + /* * Called via sys_ioctl. We can use spin_lock_irq() here. */ @@ -1223,6 +1256,18 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, * protected against the tty being hung up. */ switch (cmd) { + case TIOCGRS485: + ret = uart_get_rs485_config(state->uart_port, uarg); + break; + + case TIOCSRS485: + ret = uart_set_rs485_config(state->uart_port, uarg); + break; + } + if (ret != -ENOIOCTLCMD) + goto out; + + switch (cmd) { case TIOCSERGETLSR: /* Get line status register */ ret = uart_get_lsr_info(tty, state, uarg); break; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 40b4cc4f8e1d..3231a43f6acf 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -131,6 +131,8 @@ struct uart_port { void (*pm)(struct uart_port *, unsigned int state, unsigned int old); void (*handle_break)(struct uart_port *); + int (*rs485_config)(struct uart_port *, + struct serial_rs485 *rs485); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ @@ -231,6 +233,7 @@ struct uart_port { unsigned char unused[2]; struct attribute_group *attr_group; /* port specific attributes */ const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ + struct serial_rs485 rs485; void *private_data; /* generic platform data pointer */ }; -- GitLab From 46c55b4bb9b55b7b09b6879668a209a5657814b3 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:51 +0100 Subject: [PATCH 3562/9457] serial/8250: Copy RS485 fields to serial_core Initialize recently added rs485 fields on serial_core Reviewed-by: Alan Cox Cc: Jiri Slaby Cc: Sebastian Andrzej Siewior Cc: Alan Cox Cc: Tony Lindgren Cc: Peter Hurley Cc: Yoshihiro YUNOMAE Cc: Andy Shevchenko Cc: Ingo Molnar Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 25eb8e93615d..3f2c6576ab4e 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -3619,6 +3619,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart->rs485 = up->rs485; uart->port.throttle = up->port.throttle; uart->port.unthrottle = up->port.unthrottle; + uart->port.rs485_config = up->port.rs485_config; + uart->port.rs485 = up->port.rs485; /* Take tx_loadsz from fifosize if it wasn't set separately */ if (uart->port.fifosize && !uart->tx_loadsz) -- GitLab From 41e69093fd608c0348fb12c0879ab464f986d2a8 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:52 +0100 Subject: [PATCH 3563/9457] 8250/fintek: Use rs485 handler from serial_core In order to remove the handler for rs485 ioctls on serial_8250, all the drivers must use the implementation on serial_core. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_fintek.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 1bb28cb69493..1e6899bc9429 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c @@ -89,11 +89,11 @@ static int fintek_8250_check_id(void) return 0; } -static int fintek_8250_rs4850_config(struct uart_8250_port *uart, +static int fintek_8250_rs485_config(struct uart_port *port, struct serial_rs485 *rs485) { uint8_t config = 0; - int index = fintek_8250_get_index(uart->port.iobase); + int index = fintek_8250_get_index(port->iobase); if (index < 0) return -EINVAL; @@ -134,6 +134,8 @@ static int fintek_8250_rs4850_config(struct uart_8250_port *uart, outb(config, DATA_PORT); fintek_8250_exit_key(); + port->rs485 = *rs485; + return 0; } @@ -166,7 +168,7 @@ fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) uart.port.irq = pnp_irq(dev, 0); uart.port.iobase = pnp_port_start(dev, 0); uart.port.iotype = UPIO_PORT; - uart.rs485_config = fintek_8250_rs4850_config; + uart.port.rs485_config = fintek_8250_rs485_config; uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) -- GitLab From 039ec1f010e6b058f497381d5a6bb840e160b4ac Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:53 +0100 Subject: [PATCH 3564/9457] serial/8250: Remove obsolete handling of rs485 ioctls There is no more users for this functions. All the 8250 drivers are using the rs485 handler on serial_core instead. Reviewed-by: Alan Cox Cc: Jiri Slaby Cc: Sebastian Andrzej Siewior Cc: Alan Cox Cc: Tony Lindgren Cc: Peter Hurley Cc: Yoshihiro YUNOMAE Cc: Andy Shevchenko Cc: Ingo Molnar Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 39 ----------------------------- include/linux/serial_8250.h | 3 --- 2 files changed, 42 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 3f2c6576ab4e..30522d680014 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -3005,42 +3005,6 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } -static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, - unsigned long arg) -{ - struct uart_8250_port *up = - container_of(port, struct uart_8250_port, port); - int ret; - struct serial_rs485 rs485_config; - - if (!up->rs485_config) - return -ENOIOCTLCMD; - - switch (cmd) { - case TIOCSRS485: - if (copy_from_user(&rs485_config, (void __user *)arg, - sizeof(rs485_config))) - return -EFAULT; - - ret = up->rs485_config(up, &rs485_config); - if (ret) - return ret; - - memcpy(&up->rs485, &rs485_config, sizeof(rs485_config)); - - return 0; - case TIOCGRS485: - if (copy_to_user((void __user *)arg, &up->rs485, - sizeof(up->rs485))) - return -EFAULT; - return 0; - default: - break; - } - - return -ENOIOCTLCMD; -} - static const char * serial8250_type(struct uart_port *port) { @@ -3072,7 +3036,6 @@ static struct uart_ops serial8250_pops = { .request_port = serial8250_request_port, .config_port = serial8250_config_port, .verify_port = serial8250_verify_port, - .ioctl = serial8250_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = serial8250_get_poll_char, .poll_put_char = serial8250_put_poll_char, @@ -3615,8 +3578,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart->port.fifosize = up->port.fifosize; uart->tx_loadsz = up->tx_loadsz; uart->capabilities = up->capabilities; - uart->rs485_config = up->rs485_config; - uart->rs485 = up->rs485; uart->port.throttle = up->port.throttle; uart->port.unthrottle = up->port.unthrottle; uart->port.rs485_config = up->port.rs485_config; diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 3df10d5f154b..e02acf0a0ec9 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -97,13 +97,10 @@ struct uart_8250_port { unsigned char msr_saved_flags; struct uart_8250_dma *dma; - struct serial_rs485 rs485; /* 8250 specific callbacks */ int (*dl_read)(struct uart_8250_port *); void (*dl_write)(struct uart_8250_port *, int); - int (*rs485_config)(struct uart_8250_port *, - struct serial_rs485 *rs485); }; static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) -- GitLab From b57d15fe8b37fef8f374afa08e3a557898d5d517 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:54 +0100 Subject: [PATCH 3565/9457] serial/sc16is7xx: Use the rs485 functions on serial_core In order to unify all the rs485 ioctl handling. Use the implementation of TIOC[GS]RS485 ioctl handling on serial_core. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 53 ++++++++-------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 7a7911384eca..df9a384dfbda 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -304,8 +304,6 @@ struct sc16is7xx_one { struct uart_port port; struct work_struct tx_work; struct work_struct md_work; - - struct serial_rs485 rs485; }; struct sc16is7xx_port { @@ -657,15 +655,15 @@ static void sc16is7xx_stop_tx(struct uart_port* port) struct circ_buf *xmit = &one->port.state->xmit; /* handle rs485 */ - if (one->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { /* do nothing if current tx not yet completed */ int lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); if (!(lsr & SC16IS7XX_LSR_TEMT_BIT)) return; if (uart_circ_empty(xmit) && - (one->rs485.delay_rts_after_send > 0)) - mdelay(one->rs485.delay_rts_after_send); + (port->rs485.delay_rts_after_send > 0)) + mdelay(port->rs485.delay_rts_after_send); } sc16is7xx_port_update(port, SC16IS7XX_IER_REG, @@ -688,9 +686,9 @@ static void sc16is7xx_start_tx(struct uart_port *port) struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); /* handle rs485 */ - if ((one->rs485.flags & SER_RS485_ENABLED) && - (one->rs485.delay_rts_before_send > 0)) { - mdelay(one->rs485.delay_rts_before_send); + if ((port->rs485.flags & SER_RS485_ENABLED) && + (port->rs485.delay_rts_before_send > 0)) { + mdelay(port->rs485.delay_rts_before_send); } if (!work_pending(&one->tx_work)) @@ -830,47 +828,20 @@ static void sc16is7xx_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } -static void sc16is7xx_config_rs485(struct uart_port *port, +static int sc16is7xx_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) { - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - - one->rs485 = *rs485; - - if (one->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, SC16IS7XX_EFCR_AUTO_RS485_BIT, SC16IS7XX_EFCR_AUTO_RS485_BIT); - } else { + else sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, SC16IS7XX_EFCR_AUTO_RS485_BIT, 0); - } -} - -static int sc16is7xx_ioctl(struct uart_port *port, unsigned int cmd, - unsigned long arg) -{ - struct serial_rs485 rs485; + port->rs485 = *rs485; - switch (cmd) { - case TIOCSRS485: - if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485))) - return -EFAULT; - - sc16is7xx_config_rs485(port, &rs485); - return 0; - case TIOCGRS485: - if (copy_to_user((void __user *)arg, - &(to_sc16is7xx_one(port, port)->rs485), - sizeof(rs485))) - return -EFAULT; - return 0; - default: - break; - } - - return -ENOIOCTLCMD; + return 0; } static int sc16is7xx_startup(struct uart_port *port) @@ -996,7 +967,6 @@ static const struct uart_ops sc16is7xx_ops = { .release_port = sc16is7xx_null_void, .config_port = sc16is7xx_config_port, .verify_port = sc16is7xx_verify_port, - .ioctl = sc16is7xx_ioctl, .pm = sc16is7xx_pm, }; @@ -1126,6 +1096,7 @@ static int sc16is7xx_probe(struct device *dev, s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.uartclk = freq; + s->p[i].port.rs485_config = sc16is7xx_config_rs485; s->p[i].port.ops = &sc16is7xx_ops; /* Disable all interrupts */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0); -- GitLab From 2fc0184dae7be565e4ad47c720e6014cd5543a21 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:55 +0100 Subject: [PATCH 3566/9457] serial/mcf: Use the rs485 functions on serial_core In order to unify all the rs485 ioctl handling. Use the implementation of TIOC[GS]RS485 ioctl handling on serial_core. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mcf.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index bc896dc7d2ed..d7be1f18545b 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -57,7 +57,6 @@ struct mcf_uart { struct uart_port port; unsigned int sigs; /* Local copy of line sigs */ unsigned char imr; /* Local IMR mirror */ - struct serial_rs485 rs485; /* RS485 settings */ }; /****************************************************************************/ @@ -104,7 +103,7 @@ static void mcf_start_tx(struct uart_port *port) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); - if (pp->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { /* Enable Transmitter */ writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); /* Manually assert RTS */ @@ -258,7 +257,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, mr2 |= MCFUART_MR2_TXCTS; } - if (pp->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); mr2 |= MCFUART_MR2_TXRTS; } @@ -360,7 +359,7 @@ static void mcf_tx_chars(struct mcf_uart *pp) pp->imr &= ~MCFUART_UIR_TXREADY; writeb(pp->imr, port->membase + MCFUART_UIMR); /* Disable TX to negate RTS automatically */ - if (pp->rs485.flags & SER_RS485_ENABLED) + if (port->rs485.flags & SER_RS485_ENABLED) writeb(MCFUART_UCR_TXDISABLE, port->membase + MCFUART_UCR); } @@ -440,7 +439,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) /****************************************************************************/ /* Enable or disable the RS485 support */ -static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) +static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; @@ -460,32 +459,9 @@ static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) } writeb(mr1, port->membase + MCFUART_UMR); writeb(mr2, port->membase + MCFUART_UMR); - pp->rs485 = *rs485; + port->rs485 = *rs485; spin_unlock_irqrestore(&port->lock, flags); -} -static int mcf_ioctl(struct uart_port *port, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { - case TIOCSRS485: { - struct serial_rs485 rs485; - if (copy_from_user(&rs485, (struct serial_rs485 *)arg, - sizeof(struct serial_rs485))) - return -EFAULT; - mcf_config_rs485(port, &rs485); - break; - } - case TIOCGRS485: { - struct mcf_uart *pp = container_of(port, struct mcf_uart, port); - if (copy_to_user((struct serial_rs485 *)arg, &pp->rs485, - sizeof(struct serial_rs485))) - return -EFAULT; - break; - } - default: - return -ENOIOCTLCMD; - } return 0; } @@ -510,7 +486,6 @@ static const struct uart_ops mcf_uart_ops = { .release_port = mcf_release_port, .config_port = mcf_config_port, .verify_port = mcf_verify_port, - .ioctl = mcf_ioctl, }; static struct mcf_uart mcf_ports[4]; @@ -538,6 +513,7 @@ int __init early_mcf_setup(struct mcf_platform_uart *platp) port->irq = platp[i].irq; port->uartclk = MCF_BUSCLK; port->flags = UPF_BOOT_AUTOCONF; + port->rs485_config = mcf_config_rs485; port->ops = &mcf_uart_ops; } @@ -663,6 +639,7 @@ static int mcf_probe(struct platform_device *pdev) port->uartclk = MCF_BUSCLK; port->ops = &mcf_uart_ops; port->flags = UPF_BOOT_AUTOCONF; + port->rs485_config = mcf_config_rs485; uart_add_one_port(&mcf_driver, port); } -- GitLab From 13bd3e6fa177883914fa64b609651e56d58eea65 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:56 +0100 Subject: [PATCH 3567/9457] serial/atmel: Use the rs485 functions on serial_core In order to unify all the rs485 ioctl handling. Use the implementation of TIOC[GS]RS485 ioctl handling on serial_core. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 79 ++++++++++--------------------- 1 file changed, 24 insertions(+), 55 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index b1d61dc3fc1b..80c4bfcff3fa 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -167,7 +167,6 @@ struct atmel_uart_port { struct circ_buf rx_ring; - struct serial_rs485 rs485; /* rs485 settings */ struct mctrl_gpios *gpios; int gpio_irq[UART_GPIO_MAX]; unsigned int tx_done_mask; @@ -290,7 +289,8 @@ static unsigned int atmel_get_lines_status(struct uart_port *port) } /* Enable or disable the rs485 support */ -void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) +static int atmel_config_rs485(struct uart_port *port, + struct serial_rs485 *rs485conf) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int mode; @@ -306,7 +306,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) /* Resetting serial mode to RS232 (0x0) */ mode &= ~ATMEL_US_USMODE; - atmel_port->rs485 = *rs485conf; + port->rs485 = *rs485conf; if (rs485conf->flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); @@ -329,6 +329,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) spin_unlock_irqrestore(&port->lock, flags); + return 0; } /* @@ -372,11 +373,10 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) /* Resetting serial mode to RS232 (0x0) */ mode &= ~ATMEL_US_USMODE; - if (atmel_port->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - if ((atmel_port->rs485.delay_rts_after_send) > 0) - UART_PUT_TTGR(port, - atmel_port->rs485.delay_rts_after_send); + if ((port->rs485.delay_rts_after_send) > 0) + UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -423,8 +423,8 @@ static void atmel_stop_tx(struct uart_port *port) /* Disable interrupts */ UART_PUT_IDR(port, atmel_port->tx_done_mask); - if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && - !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) + if ((port->rs485.flags & SER_RS485_ENABLED) && + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) atmel_start_rx(port); } @@ -441,8 +441,8 @@ static void atmel_start_tx(struct uart_port *port) really need this.*/ return; - if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && - !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) + if ((port->rs485.flags & SER_RS485_ENABLED) && + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) atmel_stop_rx(port); /* re-enable PDC transmit */ @@ -807,7 +807,7 @@ static void atmel_tx_dma(struct uart_port *port) atmel_port->cookie_tx = dmaengine_submit(desc); } else { - if (atmel_port->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { /* DMA done, stop TX, start RX for RS485 */ atmel_start_rx(port); } @@ -1254,8 +1254,8 @@ static void atmel_tx_pdc(struct uart_port *port) /* Enable interrupts */ UART_PUT_IER(port, atmel_port->tx_done_mask); } else { - if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && - !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) { + if ((port->rs485.flags & SER_RS485_ENABLED) && + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { /* DMA done, stop TX, start RX for RS485 */ atmel_start_rx(port); } @@ -1566,7 +1566,7 @@ static int atmel_init_property(struct atmel_uart_port *atmel_port, return 0; } -static void atmel_init_rs485(struct atmel_uart_port *atmel_port, +static void atmel_init_rs485(struct uart_port *port, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1577,7 +1577,7 @@ static void atmel_init_rs485(struct atmel_uart_port *atmel_port, /* rs485 properties */ if (of_property_read_u32_array(np, "rs485-rts-delay", rs485_delay, 2) == 0) { - struct serial_rs485 *rs485conf = &atmel_port->rs485; + struct serial_rs485 *rs485conf = &port->rs485; rs485conf->delay_rts_before_send = rs485_delay[0]; rs485conf->delay_rts_after_send = rs485_delay[1]; @@ -1591,7 +1591,7 @@ static void atmel_init_rs485(struct atmel_uart_port *atmel_port, rs485conf->flags |= SER_RS485_ENABLED; } } else { - atmel_port->rs485 = pdata->rs485; + port->rs485 = pdata->rs485; } } @@ -1927,7 +1927,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, { unsigned long flags; unsigned int mode, imr, quot, baud; - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); /* Get current mode register */ mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL @@ -2029,10 +2028,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, /* Resetting serial mode to RS232 (0x0) */ mode &= ~ATMEL_US_USMODE; - if (atmel_port->rs485.flags & SER_RS485_ENABLED) { - if ((atmel_port->rs485.delay_rts_after_send) > 0) - UART_PUT_TTGR(port, - atmel_port->rs485.delay_rts_after_send); + if (port->rs485.flags & SER_RS485_ENABLED) { + if ((port->rs485.delay_rts_after_send) > 0) + UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } @@ -2171,35 +2169,6 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) } #endif -static int -atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) -{ - struct serial_rs485 rs485conf; - - switch (cmd) { - case TIOCSRS485: - if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, - sizeof(rs485conf))) - return -EFAULT; - - atmel_config_rs485(port, &rs485conf); - break; - - case TIOCGRS485: - if (copy_to_user((struct serial_rs485 *) arg, - &(to_atmel_uart_port(port)->rs485), - sizeof(rs485conf))) - return -EFAULT; - break; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - - - static struct uart_ops atmel_pops = { .tx_empty = atmel_tx_empty, .set_mctrl = atmel_set_mctrl, @@ -2220,7 +2189,6 @@ static struct uart_ops atmel_pops = { .config_port = atmel_config_port, .verify_port = atmel_verify_port, .pm = atmel_serial_pm, - .ioctl = atmel_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_get_char = atmel_poll_get_char, .poll_put_char = atmel_poll_put_char, @@ -2240,7 +2208,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, if (!atmel_init_property(atmel_port, pdev)) atmel_set_ops(port); - atmel_init_rs485(atmel_port, pdev); + atmel_init_rs485(port, pdev); port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF; @@ -2249,6 +2217,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, port->dev = &pdev->dev; port->mapbase = pdev->resource[0].start; port->irq = pdev->resource[1].start; + port->rs485_config = atmel_config_rs485; tasklet_init(&atmel_port->tasklet, atmel_tasklet_func, (unsigned long)port); @@ -2283,7 +2252,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, } /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ - if (atmel_port->rs485.flags & SER_RS485_ENABLED) + if (port->rs485.flags & SER_RS485_ENABLED) atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; else if (atmel_use_pdc_tx(port)) { port->fifosize = PDC_BUFFER_SIZE; @@ -2629,7 +2598,7 @@ static int atmel_serial_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, port); - if (port->rs485.flags & SER_RS485_ENABLED) { + if (port->uart.rs485.flags & SER_RS485_ENABLED) { UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); } -- GitLab From dadd7ecbff4bf01ec446c4390cfeab20124b5708 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 22:46:14 +0100 Subject: [PATCH 3568/9457] serial/omap: Use the rs485 functions on serial_core In order to unify all the rs485 ioctl handling Use the implementation of TIOC[GS]RS485 ioctl handling on serial_core. Reviewed-by: Alan Cox Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 69 ++++++++++---------------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 9d22d3369da9..050d1b5c7b36 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -163,7 +163,6 @@ struct uart_omap_port { u8 wakeups_enabled; u32 features; - struct serial_rs485 rs485; int rts_gpio; struct pm_qos_request pm_qos_request; @@ -316,7 +315,7 @@ static void serial_omap_stop_tx(struct uart_port *port) pm_runtime_get_sync(up->dev); /* Handle RS-485 */ - if (up->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { if (up->scr & OMAP_UART_SCR_TX_EMPTY) { /* THR interrupt is fired when both TX FIFO and TX * shift register are empty. This means there's nothing @@ -327,10 +326,12 @@ static void serial_omap_stop_tx(struct uart_port *port) */ up->scr &= ~OMAP_UART_SCR_TX_EMPTY; serial_out(up, UART_OMAP_SCR, up->scr); - res = (up->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? 1 : 0; + res = (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) ? + 1 : 0; if (gpio_get_value(up->rts_gpio) != res) { - if (up->rs485.delay_rts_after_send > 0) - mdelay(up->rs485.delay_rts_after_send); + if (port->rs485.delay_rts_after_send > 0) + mdelay( + port->rs485.delay_rts_after_send); gpio_set_value(up->rts_gpio, res); } } else { @@ -353,8 +354,8 @@ static void serial_omap_stop_tx(struct uart_port *port) serial_out(up, UART_IER, up->ier); } - if ((up->rs485.flags & SER_RS485_ENABLED) && - !(up->rs485.flags & SER_RS485_RX_DURING_TX)) { + if ((port->rs485.flags & SER_RS485_ENABLED) && + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { /* * Empty the RX FIFO, we are not interested in anything * received during the half-duplex transmission. @@ -429,22 +430,22 @@ static void serial_omap_start_tx(struct uart_port *port) pm_runtime_get_sync(up->dev); /* Handle RS-485 */ - if (up->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_ENABLED) { /* Fire THR interrupts when FIFO is below trigger level */ up->scr &= ~OMAP_UART_SCR_TX_EMPTY; serial_out(up, UART_OMAP_SCR, up->scr); /* if rts not already enabled */ - res = (up->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; + res = (port->rs485.flags & SER_RS485_RTS_ON_SEND) ? 1 : 0; if (gpio_get_value(up->rts_gpio) != res) { gpio_set_value(up->rts_gpio, res); - if (up->rs485.delay_rts_before_send > 0) - mdelay(up->rs485.delay_rts_before_send); + if (port->rs485.delay_rts_before_send > 0) + mdelay(port->rs485.delay_rts_before_send); } } - if ((up->rs485.flags & SER_RS485_ENABLED) && - !(up->rs485.flags & SER_RS485_RX_DURING_TX)) + if ((port->rs485.flags & SER_RS485_ENABLED) && + !(port->rs485.flags & SER_RS485_RX_DURING_TX)) serial_omap_stop_rx(port); serial_omap_enable_ier_thri(up); @@ -1355,7 +1356,7 @@ static inline void serial_omap_add_console_port(struct uart_omap_port *up) #endif /* Enable or disable the rs485 support */ -static void +static int serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) { struct uart_omap_port *up = to_uart_omap_port(port); @@ -1372,7 +1373,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) serial_out(up, UART_IER, 0); /* store new config */ - up->rs485 = *rs485conf; + port->rs485 = *rs485conf; /* * Just as a precaution, only allow rs485 @@ -1380,12 +1381,12 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) */ if (gpio_is_valid(up->rts_gpio)) { /* enable / disable rts */ - val = (up->rs485.flags & SER_RS485_ENABLED) ? + val = (port->rs485.flags & SER_RS485_ENABLED) ? SER_RS485_RTS_AFTER_SEND : SER_RS485_RTS_ON_SEND; - val = (up->rs485.flags & val) ? 1 : 0; + val = (port->rs485.flags & val) ? 1 : 0; gpio_set_value(up->rts_gpio, val); } else - up->rs485.flags &= ~SER_RS485_ENABLED; + port->rs485.flags &= ~SER_RS485_ENABLED; /* Enable interrupts */ up->ier = mode; @@ -1394,7 +1395,7 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) /* If RS-485 is disabled, make sure the THR interrupt is fired when * TX FIFO is below the trigger level. */ - if (!(up->rs485.flags & SER_RS485_ENABLED) && + if (!(port->rs485.flags & SER_RS485_ENABLED) && (up->scr & OMAP_UART_SCR_TX_EMPTY)) { up->scr &= ~OMAP_UART_SCR_TX_EMPTY; serial_out(up, UART_OMAP_SCR, up->scr); @@ -1403,36 +1404,10 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); -} - -static int -serial_omap_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) -{ - struct serial_rs485 rs485conf; - - switch (cmd) { - case TIOCSRS485: - if (copy_from_user(&rs485conf, (void __user *) arg, - sizeof(rs485conf))) - return -EFAULT; - serial_omap_config_rs485(port, &rs485conf); - break; - - case TIOCGRS485: - if (copy_to_user((void __user *) arg, - &(to_uart_omap_port(port)->rs485), - sizeof(rs485conf))) - return -EFAULT; - break; - - default: - return -ENOIOCTLCMD; - } return 0; } - static struct uart_ops serial_omap_pops = { .tx_empty = serial_omap_tx_empty, .set_mctrl = serial_omap_set_mctrl, @@ -1453,7 +1428,6 @@ static struct uart_ops serial_omap_pops = { .request_port = serial_omap_request_port, .config_port = serial_omap_config_port, .verify_port = serial_omap_verify_port, - .ioctl = serial_omap_ioctl, #ifdef CONFIG_CONSOLE_POLL .poll_put_char = serial_omap_poll_put_char, .poll_get_char = serial_omap_poll_get_char, @@ -1587,7 +1561,7 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) static int serial_omap_probe_rs485(struct uart_omap_port *up, struct device_node *np) { - struct serial_rs485 *rs485conf = &up->rs485; + struct serial_rs485 *rs485conf = &up->port.rs485; u32 rs485_delay[2]; enum of_gpio_flags flags; int ret; @@ -1709,6 +1683,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.membase = base; up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; + up->port.rs485_config = serial_omap_config_rs485; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, -- GitLab From c267d679cfd9699b9349fd714f63f6b4ee59dda2 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:58 +0100 Subject: [PATCH 3569/9457] drivers/max310: Use the rs485 functions on serial_core In order to unify all the rs485 ioctl handling Use the implementation of TIOC[GS]RS485 ioctl handling on serial_core. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 70 ++++++++++++++---------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index ecb466701ede..182549f55904 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -877,53 +877,37 @@ static void max310x_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } -static int max310x_ioctl(struct uart_port *port, unsigned int cmd, - unsigned long arg) +static int max310x_rs485_config(struct uart_port *port, + struct serial_rs485 *rs485) { - struct serial_rs485 rs485; unsigned int val; - switch (cmd) { - case TIOCSRS485: - if (copy_from_user(&rs485, (void __user *)arg, sizeof(rs485))) - return -EFAULT; - if (rs485.delay_rts_before_send > 0x0f || - rs485.delay_rts_after_send > 0x0f) - return -ERANGE; - val = (rs485.delay_rts_before_send << 4) | - rs485.delay_rts_after_send; - max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); - if (rs485.flags & SER_RS485_ENABLED) { - max310x_port_update(port, MAX310X_MODE1_REG, - MAX310X_MODE1_TRNSCVCTRL_BIT, - MAX310X_MODE1_TRNSCVCTRL_BIT); - max310x_port_update(port, MAX310X_MODE2_REG, - MAX310X_MODE2_ECHOSUPR_BIT, - MAX310X_MODE2_ECHOSUPR_BIT); - } else { - max310x_port_update(port, MAX310X_MODE1_REG, - MAX310X_MODE1_TRNSCVCTRL_BIT, 0); - max310x_port_update(port, MAX310X_MODE2_REG, - MAX310X_MODE2_ECHOSUPR_BIT, 0); - } - return 0; - case TIOCGRS485: - memset(&rs485, 0, sizeof(rs485)); - val = max310x_port_read(port, MAX310X_MODE1_REG); - rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ? - SER_RS485_ENABLED : 0; - rs485.flags |= SER_RS485_RTS_ON_SEND; - val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG); - rs485.delay_rts_before_send = val >> 4; - rs485.delay_rts_after_send = val & 0x0f; - if (copy_to_user((void __user *)arg, &rs485, sizeof(rs485))) - return -EFAULT; - return 0; - default: - break; + if (rs485->delay_rts_before_send > 0x0f || + rs485->delay_rts_after_send > 0x0f) + return -ERANGE; + + val = (rs485->delay_rts_before_send << 4) | + rs485->delay_rts_after_send; + max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); + if (rs485->flags & SER_RS485_ENABLED) { + max310x_port_update(port, MAX310X_MODE1_REG, + MAX310X_MODE1_TRNSCVCTRL_BIT, + MAX310X_MODE1_TRNSCVCTRL_BIT); + max310x_port_update(port, MAX310X_MODE2_REG, + MAX310X_MODE2_ECHOSUPR_BIT, + MAX310X_MODE2_ECHOSUPR_BIT); + } else { + max310x_port_update(port, MAX310X_MODE1_REG, + MAX310X_MODE1_TRNSCVCTRL_BIT, 0); + max310x_port_update(port, MAX310X_MODE2_REG, + MAX310X_MODE2_ECHOSUPR_BIT, 0); } - return -ENOIOCTLCMD; + rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED; + memset(rs485->padding, 0, sizeof(rs485->padding)); + port->rs485 = *rs485; + + return 0; } static int max310x_startup(struct uart_port *port) @@ -1018,7 +1002,6 @@ static const struct uart_ops max310x_ops = { .release_port = max310x_null_void, .config_port = max310x_config_port, .verify_port = max310x_verify_port, - .ioctl = max310x_ioctl, }; static int __maybe_unused max310x_suspend(struct device *dev) @@ -1219,6 +1202,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, s->p[i].port.iobase = i * 0x20; s->p[i].port.membase = (void __iomem *)~0; s->p[i].port.uartclk = uartclk; + s->p[i].port.rs485_config = max310x_rs485_config; s->p[i].port.ops = &max310x_ops; /* Disable all interrupts */ max310x_port_write(&s->p[i].port, MAX310X_IRQEN_REG, 0); -- GitLab From a9c20a9cf3190a517b88d8e08d93157256f97673 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:22:59 +0100 Subject: [PATCH 3570/9457] serial_core: Remove call to driver-specific TIO[GS]RS485] Once there is no more handlers for TIOC[GS]RS485 there is no need to call the driver specific ioctl when the generic implementation is missing. Reviewed-by: Alan Cox Cc: Jiri Slaby Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index ab4db1dcc474..99fcdba0e3e9 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1155,9 +1155,6 @@ static int uart_get_icount(struct tty_struct *tty, static int uart_get_rs485_config(struct uart_port *port, struct serial_rs485 __user *rs485) { - if (!port->rs485_config) - return -ENOIOCTLCMD; - if (copy_to_user(rs485, &port->rs485, sizeof(port->rs485))) return -EFAULT; return 0; @@ -1255,7 +1252,12 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, * All these rely on hardware being present and need to be * protected against the tty being hung up. */ + switch (cmd) { + case TIOCSERGETLSR: /* Get line status register */ + ret = uart_get_lsr_info(tty, state, uarg); + break; + case TIOCGRS485: ret = uart_get_rs485_config(state->uart_port, uarg); break; @@ -1263,15 +1265,6 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, case TIOCSRS485: ret = uart_set_rs485_config(state->uart_port, uarg); break; - } - if (ret != -ENOIOCTLCMD) - goto out; - - switch (cmd) { - case TIOCSERGETLSR: /* Get line status register */ - ret = uart_get_lsr_info(tty, state, uarg); - break; - default: { struct uart_port *uport = state->uart_port; if (uport->ops->ioctl) -- GitLab From bd737f8738b7e15930aa7b47c94c28a8d83148ac Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Thu, 6 Nov 2014 09:23:00 +0100 Subject: [PATCH 3571/9457] tty/serial_core: Introduce lock mechanism for RS485 Introduce an homogeneous lock system between setting and using the rs485 data of the uart_port. This patch should not be split into multiple ones in order to avoid leaving the tree in an unstable state. Acked-by: Nicolas Ferre Reviewed-by: Alan Cox Suggested-by: Alan Cox Cc: Nicolas Ferre Cc: Jiri Slaby Cc: One Thousand Gnomes Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 10 ++++------ drivers/tty/serial/mcf.c | 5 +---- drivers/tty/serial/omap-serial.c | 3 --- drivers/tty/serial/serial_core.c | 13 ++++++++++++- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 80c4bfcff3fa..2cb04137ae78 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -294,9 +294,6 @@ static int atmel_config_rs485(struct uart_port *port, { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); unsigned int mode; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); /* Disable interrupts */ UART_PUT_IDR(port, atmel_port->tx_done_mask); @@ -327,8 +324,6 @@ static int atmel_config_rs485(struct uart_port *port, /* Enable interrupts */ UART_PUT_IER(port, atmel_port->tx_done_mask); - spin_unlock_irqrestore(&port->lock, flags); - return 0; } @@ -2533,6 +2528,7 @@ static int atmel_serial_probe(struct platform_device *pdev) struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev); void *data; int ret = -ENODEV; + bool rs485_enabled; BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); @@ -2580,6 +2576,8 @@ static int atmel_serial_probe(struct platform_device *pdev) port->rx_ring.buf = data; } + rs485_enabled = port->uart.rs485.flags & SER_RS485_ENABLED; + ret = uart_add_one_port(&atmel_uart, &port->uart); if (ret) goto err_add_port; @@ -2598,7 +2596,7 @@ static int atmel_serial_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, port); - if (port->uart.rs485.flags & SER_RS485_ENABLED) { + if (rs485_enabled) { UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); } diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index d7be1f18545b..fdd5c7bd1e8d 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -257,12 +257,12 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, mr2 |= MCFUART_MR2_TXCTS; } + spin_lock_irqsave(&port->lock, flags); if (port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); mr2 |= MCFUART_MR2_TXRTS; } - spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); @@ -442,10 +442,8 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); - unsigned long flags; unsigned char mr1, mr2; - spin_lock_irqsave(&port->lock, flags); /* Get mode registers */ mr1 = readb(port->membase + MCFUART_UMR); mr2 = readb(port->membase + MCFUART_UMR); @@ -460,7 +458,6 @@ static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) writeb(mr1, port->membase + MCFUART_UMR); writeb(mr2, port->membase + MCFUART_UMR); port->rs485 = *rs485; - spin_unlock_irqrestore(&port->lock, flags); return 0; } diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 050d1b5c7b36..e0bec06a5f60 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1360,12 +1360,10 @@ static int serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned long flags; unsigned int mode; int val; pm_runtime_get_sync(up->dev); - spin_lock_irqsave(&up->port.lock, flags); /* Disable interrupts from this port */ mode = up->ier; @@ -1401,7 +1399,6 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) serial_out(up, UART_OMAP_SCR, up->scr); } - spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 99fcdba0e3e9..5c8b8f50f787 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1155,8 +1155,16 @@ static int uart_get_icount(struct tty_struct *tty, static int uart_get_rs485_config(struct uart_port *port, struct serial_rs485 __user *rs485) { - if (copy_to_user(rs485, &port->rs485, sizeof(port->rs485))) + unsigned long flags; + struct serial_rs485 aux; + + spin_lock_irqsave(&port->lock, flags); + aux = port->rs485; + spin_unlock_irqrestore(&port->lock, flags); + + if (copy_to_user(rs485, &aux, sizeof(aux))) return -EFAULT; + return 0; } @@ -1165,6 +1173,7 @@ static int uart_set_rs485_config(struct uart_port *port, { struct serial_rs485 rs485; int ret; + unsigned long flags; if (!port->rs485_config) return -ENOIOCTLCMD; @@ -1172,7 +1181,9 @@ static int uart_set_rs485_config(struct uart_port *port, if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) return -EFAULT; + spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, &rs485); + spin_unlock_irqrestore(&port->lock, flags); if (ret) return ret; -- GitLab From 2dc98946d4d4398ab07d569c414c1f839907ea0b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 6 Nov 2014 13:28:16 +0200 Subject: [PATCH 3572/9457] serial: 8250_dma: call serial8250_tx_dma unconditionally Since we have the same check inside the function we may drop it away in __dma_tx_complete(). Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dma.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 258430b72039..b16f9b169202 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -21,6 +21,7 @@ static void __dma_tx_complete(void *param) struct uart_8250_dma *dma = p->dma; struct circ_buf *xmit = &p->port.state->xmit; unsigned long flags; + int ret; dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); @@ -36,15 +37,11 @@ static void __dma_tx_complete(void *param) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&p->port); - if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { - int ret; - - ret = serial8250_tx_dma(p); - if (ret) { - dma->tx_err = 1; - p->ier |= UART_IER_THRI; - serial_port_out(&p->port, UART_IER, p->ier); - } + ret = serial8250_tx_dma(p); + if (ret) { + dma->tx_err = 1; + p->ier |= UART_IER_THRI; + serial_port_out(&p->port, UART_IER, p->ier); } spin_unlock_irqrestore(&p->port.lock, flags); -- GitLab From b1835d238ad3dc6ad8fe23172b1995d1fb5bdd39 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 6 Nov 2014 13:28:17 +0200 Subject: [PATCH 3573/9457] serial: 8250_dma: no need to set tx_err twice In the serial8250_tx_dma() the tx_err flag is set in case of error. Thus, there is no need to repeat this in __dma_tx_complete(). Signed-off-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index b16f9b169202..fcd7ac6af2fc 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -39,7 +39,6 @@ static void __dma_tx_complete(void *param) ret = serial8250_tx_dma(p); if (ret) { - dma->tx_err = 1; p->ier |= UART_IER_THRI; serial_port_out(&p->port, UART_IER, p->ier); } @@ -93,7 +92,6 @@ int serial8250_tx_dma(struct uart_8250_port *p) } dma->tx_running = 1; - desc->callback = __dma_tx_complete; desc->callback_param = p; -- GitLab From 1511316fbd1c690ad0a16324d88fb5ec45d6be36 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 6 Nov 2014 19:00:42 +0530 Subject: [PATCH 3574/9457] serial: MIPS: lantiq: use devm_iounmap instead of iounmap port->membase was allocated using devm_ioremap_nocache, so ideally we should unmap it using devm_iounmap. but it was using iounmap. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/lantiq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 4675fe198d31..18c3844510ff 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -497,8 +497,10 @@ lqasc_type(struct uart_port *port) static void lqasc_release_port(struct uart_port *port) { + struct platform_device *pdev = to_platform_device(port->dev); + if (port->flags & UPF_IOREMAP) { - iounmap(port->membase); + devm_iounmap(&pdev->dev, port->membase); port->membase = NULL; } } -- GitLab From d7685ca7c4f5d22dd9b045992e82c1c444a92187 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Mon, 3 Nov 2014 19:52:37 +0100 Subject: [PATCH 3575/9457] drivers: serial: jsm: Add Classic board UART structure This commit adds the UART structure for the Digi Classic cards. This code comes from the staging/dgnc driver. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm.h | 59 +++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index af7013488aeb..9861639d838f 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -222,7 +222,10 @@ struct jsm_channel { u8 ch_mostat; /* FEP output modem status */ u8 ch_mistat; /* FEP input modem status */ - struct neo_uart_struct __iomem *ch_neo_uart; /* Pointer to the "mapped" UART struct */ + /* Pointers to the "mapped" UART structs */ + struct neo_uart_struct __iomem *ch_neo_uart; /* NEO card */ + struct cls_uart_struct __iomem *ch_cls_uart; /* Classic card */ + u8 ch_cached_lsr; /* Cached value of the LSR register */ u8 *ch_rqueue; /* Our read queue buffer - malloc'ed */ @@ -254,6 +257,60 @@ struct jsm_channel { u64 ch_xoff_sends; /* Count of xoffs transmitted */ }; +/************************************************************************ + * Per channel/port Classic UART structures * + ************************************************************************ + * Base Structure Entries Usage Meanings to Host * + * * + * W = read write R = read only * + * U = Unused. * + ************************************************************************/ + +struct cls_uart_struct { + u8 txrx; /* WR RHR/THR - Holding Reg */ + u8 ier; /* WR IER - Interrupt Enable Reg */ + u8 isr_fcr; /* WR ISR/FCR - Interrupt Status Reg/Fifo Control Reg*/ + u8 lcr; /* WR LCR - Line Control Reg */ + u8 mcr; /* WR MCR - Modem Control Reg */ + u8 lsr; /* WR LSR - Line Status Reg */ + u8 msr; /* WR MSR - Modem Status Reg */ + u8 spr; /* WR SPR - Scratch Pad Reg */ +}; + +/* Where to read the interrupt register (8bits) */ +#define UART_CLASSIC_POLL_ADDR_OFFSET 0x40 + +#define UART_EXAR654_ENHANCED_REGISTER_SET 0xBF + +#define UART_16654_FCR_TXTRIGGER_8 0x0 +#define UART_16654_FCR_TXTRIGGER_16 0x10 +#define UART_16654_FCR_TXTRIGGER_32 0x20 +#define UART_16654_FCR_TXTRIGGER_56 0x30 + +#define UART_16654_FCR_RXTRIGGER_8 0x0 +#define UART_16654_FCR_RXTRIGGER_16 0x40 +#define UART_16654_FCR_RXTRIGGER_56 0x80 +#define UART_16654_FCR_RXTRIGGER_60 0xC0 + +#define UART_IIR_CTSRTS 0x20 /* Received CTS/RTS change of state */ +#define UART_IIR_RDI_TIMEOUT 0x0C /* Receiver data TIMEOUT */ + +/* + * These are the EXTENDED definitions for the Exar 654's Interrupt + * Enable Register. + */ +#define UART_EXAR654_EFR_ECB 0x10 /* Enhanced control bit */ +#define UART_EXAR654_EFR_IXON 0x2 /* Receiver compares Xon1/Xoff1 */ +#define UART_EXAR654_EFR_IXOFF 0x8 /* Transmit Xon1/Xoff1 */ +#define UART_EXAR654_EFR_RTSDTR 0x40 /* Auto RTS/DTR Flow Control Enable */ +#define UART_EXAR654_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow COntrol Enable */ + +#define UART_EXAR654_XOFF_DETECT 0x1 /* Indicates whether chip saw an incoming XOFF char */ +#define UART_EXAR654_XON_DETECT 0x2 /* Indicates whether chip saw an incoming XON char */ + +#define UART_EXAR654_IER_XOFF 0x20 /* Xoff Interrupt Enable */ +#define UART_EXAR654_IER_RTSDTR 0x40 /* Output Interrupt Enable */ +#define UART_EXAR654_IER_CTSDSR 0x80 /* Input Interrupt Enable */ /************************************************************************ * Per channel/port NEO UART structure * -- GitLab From 8a8ae62f8296760a2a1eee7009a1444c327603e0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 6 Nov 2014 16:56:33 +0100 Subject: [PATCH 3576/9457] tty: warn on deprecated serial flags When somebody calls TIOCSSERIAL ioctl with serial flags to set one of * ASYNC_SESSION_LOCKOUT * ASYNC_PGRP_LOCKOUT * ASYNC_CALLOUT_NOHUP * ASYNC_AUTOPROBE nothing happens. We actually ignore the flags for over a decade at least (I checked 2.6.0). So start yelling at users who use those flags, that they shouldn't. Signed-off-by: Jiri Slaby Cc: Peter Hurley Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 21 +++++++++++++++++++++ include/uapi/linux/tty_flags.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 01d45fd7d359..705885891b87 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2760,6 +2760,24 @@ static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) return 0; } +static void tty_warn_deprecated_flags(struct serial_struct __user *ss) +{ + static DEFINE_RATELIMIT_STATE(depr_flags, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + char comm[TASK_COMM_LEN]; + int flags; + + if (get_user(flags, &ss->flags)) + return; + + flags &= ASYNC_DEPRECATED; + + if (flags && __ratelimit(&depr_flags)) + pr_warning("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", + __func__, get_task_comm(comm, current), flags); +} + /* * if pty, return the slave side (real_tty) * otherwise, return self @@ -2903,6 +2921,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } break; + case TIOCSSERIAL: + tty_warn_deprecated_flags(p); + break; } if (tty->ops->ioctl) { retval = tty->ops->ioctl(tty, cmd, arg); diff --git a/include/uapi/linux/tty_flags.h b/include/uapi/linux/tty_flags.h index d2bc4ff94f43..fae4864737fa 100644 --- a/include/uapi/linux/tty_flags.h +++ b/include/uapi/linux/tty_flags.h @@ -64,6 +64,8 @@ #define ASYNC_MAGIC_MULTIPLIER (1U << ASYNCB_MAGIC_MULTIPLIER) #define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) +#define ASYNC_DEPRECATED (ASYNC_SESSION_LOCKOUT | ASYNC_PGRP_LOCKOUT | \ + ASYNC_CALLOUT_NOHUP | ASYNC_AUTOPROBE) #define ASYNC_USR_MASK (ASYNC_SPD_MASK|ASYNC_CALLOUT_NOHUP| \ ASYNC_LOW_LATENCY) #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) -- GitLab From c904375d4b15122c225c1073fd7a56bd541b0ce5 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Thu, 6 Nov 2014 21:10:17 +0100 Subject: [PATCH 3577/9457] serial: 8250_core: actually limit char reads to max_count In serial8250_rx_chars(), max_count is set to 256. Due to the post-decrement operator used in the while() condition, the maximum number of iterations actually 257. This is not a problem, but it is mildly surprising if you're debugging. Use pre-decrement instead. Signed-off-by: Frans Klaver Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 30522d680014..d0d0c3b6af02 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1501,7 +1501,7 @@ serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) ignore_char: lsr = serial_in(up, UART_LSR); - } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); + } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0)); spin_unlock(&port->lock); tty_flip_buffer_push(&port->state->port); spin_lock(&port->lock); -- GitLab From 161d6981096f5700ff5a2618bc9337c157eb717a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 28 Oct 2014 17:40:40 +0100 Subject: [PATCH 3578/9457] core: platform: add warning if driver has no owner Commit 9447057eaff8 ("platform_device: use a macro instead of platform_driver_register") introduced a codepath which could result into drivers having no owner. This went unnoticed for months, so add a warning in case this happens again somewhere else somewhen. Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 9e29943e56ca..6b10ff3bb410 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -151,6 +151,9 @@ int driver_register(struct device_driver *drv) BUG_ON(!drv->bus->p); + if (!drv->owner) + printk(KERN_WARNING "Driver '%s' needs an owner", drv->name); + if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) -- GitLab From c3b50dc219e1437e4dcb6a1639b004648dc29faa Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 28 Oct 2014 17:40:41 +0100 Subject: [PATCH 3579/9457] core: platform: let platform_driver_probe initialize module owner Since commit 9447057eaff8 ("platform_device: use a macro instead of platform_driver_register"), platform_driver_register() always overwrites the .owner field of a platform_driver with THIS_MODULE. This breaks platform_driver_probe() which uses it from within the platform core instead of the module init. Fix it by using a similar #define construct to obtain THIS_MODULE and pass it on later. Reported-by: Russell King Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 11 ++++++----- include/linux/platform_device.h | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index b2afc29403f9..c87a63326871 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -580,9 +580,10 @@ void platform_driver_unregister(struct platform_driver *drv) EXPORT_SYMBOL_GPL(platform_driver_unregister); /** - * platform_driver_probe - register driver for non-hotpluggable device + * __platform_driver_probe - register driver for non-hotpluggable device * @drv: platform driver structure * @probe: the driver probe routine, probably from an __init section + * @module: module which will be the owner of the driver * * Use this instead of platform_driver_register() when you know the device * is not hotpluggable and has already been registered, and you want to @@ -598,8 +599,8 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister); * Returns zero if the driver registered and bound to a device, else returns * a negative error code and with the driver not registered. */ -int __init_or_module platform_driver_probe(struct platform_driver *drv, - int (*probe)(struct platform_device *)) +int __init_or_module __platform_driver_probe(struct platform_driver *drv, + int (*probe)(struct platform_device *), struct module *module) { int retval, code; @@ -614,7 +615,7 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, /* temporary section violation during probe() */ drv->probe = probe; - retval = code = platform_driver_register(drv); + retval = code = __platform_driver_register(drv, module); /* * Fixup that section violation, being paranoid about code scanning @@ -633,7 +634,7 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, platform_driver_unregister(drv); return retval; } -EXPORT_SYMBOL_GPL(platform_driver_probe); +EXPORT_SYMBOL_GPL(__platform_driver_probe); /** * platform_create_bundle - register driver and create corresponding device diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 153d303af7eb..c8d95c60da19 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -197,8 +197,10 @@ extern void platform_driver_unregister(struct platform_driver *); /* non-hotpluggable platform devices may use this so that probe() and * its support may live in __init sections, conserving runtime memory. */ -extern int platform_driver_probe(struct platform_driver *driver, - int (*probe)(struct platform_device *)); +#define platform_driver_probe(drv, probe) \ + __platform_driver_probe(drv, probe, THIS_MODULE) +extern int __platform_driver_probe(struct platform_driver *driver, + int (*probe)(struct platform_device *), struct module *module); static inline void *platform_get_drvdata(const struct platform_device *pdev) { -- GitLab From 291f653a140ad880426125e5e9dbb70f4c184683 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 28 Oct 2014 17:40:42 +0100 Subject: [PATCH 3580/9457] core: platform: let platform_create_bundle initialize module owner Since commit 9447057eaff8 ("platform_device: use a macro instead of platform_driver_register"), platform_driver_register() always overwrites the .owner field of a platform_driver with THIS_MODULE. This breaks platform_create_bundle() which uses it via platform_driver_probe() from within the platform core instead of the module init. Fix it by using a similar #define construct to obtain THIS_MODULE and pass it on later. Reported-by: Russell King Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 11 ++++++----- include/linux/platform_device.h | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c87a63326871..cdb6c076c3f7 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -637,24 +637,25 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv, EXPORT_SYMBOL_GPL(__platform_driver_probe); /** - * platform_create_bundle - register driver and create corresponding device + * __platform_create_bundle - register driver and create corresponding device * @driver: platform driver structure * @probe: the driver probe routine, probably from an __init section * @res: set of resources that needs to be allocated for the device * @n_res: number of resources * @data: platform specific data for this platform device * @size: size of platform specific data + * @module: module which will be the owner of the driver * * Use this in legacy-style modules that probe hardware directly and * register a single platform device and corresponding platform driver. * * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ -struct platform_device * __init_or_module platform_create_bundle( +struct platform_device * __init_or_module __platform_create_bundle( struct platform_driver *driver, int (*probe)(struct platform_device *), struct resource *res, unsigned int n_res, - const void *data, size_t size) + const void *data, size_t size, struct module *module) { struct platform_device *pdev; int error; @@ -677,7 +678,7 @@ struct platform_device * __init_or_module platform_create_bundle( if (error) goto err_pdev_put; - error = platform_driver_probe(driver, probe); + error = __platform_driver_probe(driver, probe, module); if (error) goto err_pdev_del; @@ -690,7 +691,7 @@ struct platform_device * __init_or_module platform_create_bundle( err_out: return ERR_PTR(error); } -EXPORT_SYMBOL_GPL(platform_create_bundle); +EXPORT_SYMBOL_GPL(__platform_create_bundle); /* modalias support enables more hands-off userspace setup: * (a) environment variable lets new-style hotplug events work once system is diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index c8d95c60da19..ae4882ca4a64 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -240,10 +240,12 @@ static void __exit __platform_driver##_exit(void) \ } \ module_exit(__platform_driver##_exit); -extern struct platform_device *platform_create_bundle( +#define platform_create_bundle(driver, probe, res, n_res, data, size) \ + __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE) +extern struct platform_device *__platform_create_bundle( struct platform_driver *driver, int (*probe)(struct platform_device *), struct resource *res, unsigned int n_res, - const void *data, size_t size); + const void *data, size_t size, struct module *module); /* early platform driver interface */ struct early_platform_driver { -- GitLab From 1f648f88cea7f9b16ea8964cd81b92fb08df75a5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 28 Oct 2014 17:40:43 +0100 Subject: [PATCH 3581/9457] coccinelle: api: add spatch to prevent unnecessary .owner There are calls which silently set the owner of a module. This is the preferred way [1], so avoid setting it manually. Currently, we only care about platform drivers, but there might be more calls to be added later. [1] https://lkml.org/lkml/2014/10/12/87 Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- .../api/platform_no_drv_owner.cocci | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 scripts/coccinelle/api/platform_no_drv_owner.cocci diff --git a/scripts/coccinelle/api/platform_no_drv_owner.cocci b/scripts/coccinelle/api/platform_no_drv_owner.cocci new file mode 100644 index 000000000000..e065b9e714fc --- /dev/null +++ b/scripts/coccinelle/api/platform_no_drv_owner.cocci @@ -0,0 +1,106 @@ +/// Remove .owner field if calls are used which set it automatically +/// +// Confidence: High +// Copyright: (C) 2014 Wolfram Sang. GPL v2. + +virtual patch +virtual context +virtual org +virtual report + +@match1@ +declarer name module_platform_driver; +declarer name module_platform_driver_probe; +identifier __driver; +@@ +( + module_platform_driver(__driver); +| + module_platform_driver_probe(__driver, ...); +) + +@fix1 depends on match1 && patch && !context && !org && !report@ +identifier match1.__driver; +@@ + static struct platform_driver __driver = { + .driver = { +- .owner = THIS_MODULE, + } + }; + +@match2@ +identifier __driver; +@@ +( + platform_driver_register(&__driver) +| + platform_driver_probe(&__driver, ...) +| + platform_create_bundle(&__driver, ...) +) + +@fix2 depends on match2 && patch && !context && !org && !report@ +identifier match2.__driver; +@@ + static struct platform_driver __driver = { + .driver = { +- .owner = THIS_MODULE, + } + }; + +// ---------------------------------------------------------------------------- + +@fix1_context depends on match1 && !patch && (context || org || report)@ +identifier match1.__driver; +position j0; +@@ + + static struct platform_driver __driver = { + .driver = { +* .owner@j0 = THIS_MODULE, + } + }; + +@fix2_context depends on match2 && !patch && (context || org || report)@ +identifier match2.__driver; +position j0; +@@ + + static struct platform_driver __driver = { + .driver = { +* .owner@j0 = THIS_MODULE, + } + }; + +// ---------------------------------------------------------------------------- + +@script:python fix1_org depends on org@ +j0 << fix1_context.j0; +@@ + +msg = "No need to set .owner here. The core will do it." +coccilib.org.print_todo(j0[0], msg) + +@script:python fix2_org depends on org@ +j0 << fix2_context.j0; +@@ + +msg = "No need to set .owner here. The core will do it." +coccilib.org.print_todo(j0[0], msg) + +// ---------------------------------------------------------------------------- + +@script:python fix1_report depends on report@ +j0 << fix1_context.j0; +@@ + +msg = "No need to set .owner here. The core will do it." +coccilib.report.print_report(j0[0], msg) + +@script:python fix2_report depends on report@ +j0 << fix2_context.j0; +@@ + +msg = "No need to set .owner here. The core will do it." +coccilib.report.print_report(j0[0], msg) + -- GitLab From 95db1ccb15ae3703f751891ce1ee8f7734c21c96 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Fri, 7 Nov 2014 00:05:32 +0100 Subject: [PATCH 3582/9457] drivers: serial: jsm: Add the Classic board implementation This commit adds the Digi Classic board implementation to the staging/jsm driver. The code here is taken from the staging/dgnc driver and modified to match the serial/jsm state. This work is mostly based on the changes that has been done to the code handling the Digi Neo cards with the inspiration coming from the diff between staging/dgnc and serial/jsm as well as the LKML history for the jsm_neo.c The code compiles now and has no sparse and checkpatch errors or warnings. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/Makefile | 2 +- drivers/tty/serial/jsm/jsm.h | 3 +- drivers/tty/serial/jsm/jsm_cls.c | 990 +++++++++++++++++++++++++++++++ 3 files changed, 993 insertions(+), 2 deletions(-) create mode 100644 drivers/tty/serial/jsm/jsm_cls.c diff --git a/drivers/tty/serial/jsm/Makefile b/drivers/tty/serial/jsm/Makefile index e46b6e0f8b18..705d1ff6fdeb 100644 --- a/drivers/tty/serial/jsm/Makefile +++ b/drivers/tty/serial/jsm/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_SERIAL_JSM) += jsm.o -jsm-objs := jsm_driver.o jsm_neo.o jsm_tty.o +jsm-objs := jsm_driver.o jsm_neo.o jsm_tty.o jsm_cls.o diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 9861639d838f..309428273571 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -189,7 +189,7 @@ struct jsm_board #define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ -/* Our Read/Error/Write queue sizes */ +/* Our Read/Error queue sizes */ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ #define EQUEUEMASK 0x1FFF /* 8 K - 1 */ #define RQUEUESIZE (RQUEUEMASK + 1) @@ -431,6 +431,7 @@ struct neo_uart_struct { */ extern struct uart_driver jsm_uart_driver; extern struct board_ops jsm_neo_ops; +extern struct board_ops jsm_cls_ops; extern int jsm_debug; /************************************************************************* diff --git a/drivers/tty/serial/jsm/jsm_cls.c b/drivers/tty/serial/jsm/jsm_cls.c new file mode 100644 index 000000000000..b3a508d5608c --- /dev/null +++ b/drivers/tty/serial/jsm/jsm_cls.c @@ -0,0 +1,990 @@ +/* + * Copyright 2003 Digi International (www.digi.com) + * Scott H Kilau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! + * + * This is shared code between Digi's CVS archive and the + * Linux Kernel sources. + * Changing the source just for reformatting needlessly breaks + * our CVS diff history. + * + * Send any bug fixes/changes to: Eng.Linux at digi dot com. + * Thank you. + * + */ + +#include /* For udelay */ +#include /* For read[bwl]/write[bwl] */ +#include /* For struct async_serial */ +#include /* For the various UART offsets */ +#include +#include + +#include "jsm.h" /* Driver main header file */ + +static struct { + unsigned int rate; + unsigned int cflag; +} baud_rates[] = { + { 921600, B921600 }, + { 460800, B460800 }, + { 230400, B230400 }, + { 115200, B115200 }, + { 57600, B57600 }, + { 38400, B38400 }, + { 19200, B19200 }, + { 9600, B9600 }, + { 4800, B4800 }, + { 2400, B2400 }, + { 1200, B1200 }, + { 600, B600 }, + { 300, B300 }, + { 200, B200 }, + { 150, B150 }, + { 134, B134 }, + { 110, B110 }, + { 75, B75 }, + { 50, B50 }, +}; + +static void cls_set_cts_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn on CTS flow control, turn off IXON flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR); + isr_fcr &= ~(UART_EXAR654_EFR_IXON); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* + * Enable interrupts for CTS flow, turn off interrupts for + * received XOFF chars + */ + ier |= (UART_EXAR654_IER_CTSDSR); + ier &= ~(UART_EXAR654_IER_XOFF); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); + + ch->ch_t_tlevel = 16; +} + +static void cls_set_ixon_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn on IXON flow control, turn off CTS flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON); + isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Now set our current start/stop chars while in enhanced mode */ + writeb(ch->ch_startc, &ch->ch_cls_uart->mcr); + writeb(0, &ch->ch_cls_uart->lsr); + writeb(ch->ch_stopc, &ch->ch_cls_uart->msr); + writeb(0, &ch->ch_cls_uart->spr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* + * Disable interrupts for CTS flow, turn on interrupts for + * received XOFF chars + */ + ier &= ~(UART_EXAR654_IER_CTSDSR); + ier |= (UART_EXAR654_IER_XOFF); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); +} + +static void cls_set_no_output_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn off IXON flow control, turn off CTS flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB); + isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* + * Disable interrupts for CTS flow, turn off interrupts for + * received XOFF chars + */ + ier &= ~(UART_EXAR654_IER_CTSDSR); + ier &= ~(UART_EXAR654_IER_XOFF); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); + + ch->ch_r_watermark = 0; + ch->ch_t_tlevel = 16; + ch->ch_r_tlevel = 16; +} + +static void cls_set_rts_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn on RTS flow control, turn off IXOFF flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR); + isr_fcr &= ~(UART_EXAR654_EFR_IXOFF); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* Enable interrupts for RTS flow */ + ier |= (UART_EXAR654_IER_RTSDTR); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); + + ch->ch_r_watermark = 4; + ch->ch_r_tlevel = 8; +} + +static void cls_set_ixoff_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn on IXOFF flow control, turn off RTS flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF); + isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Now set our current start/stop chars while in enhanced mode */ + writeb(ch->ch_startc, &ch->ch_cls_uart->mcr); + writeb(0, &ch->ch_cls_uart->lsr); + writeb(ch->ch_stopc, &ch->ch_cls_uart->msr); + writeb(0, &ch->ch_cls_uart->spr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* Disable interrupts for RTS flow */ + ier &= ~(UART_EXAR654_IER_RTSDTR); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); +} + +static void cls_set_no_input_flow_control(struct jsm_channel *ch) +{ + u8 lcrb = readb(&ch->ch_cls_uart->lcr); + u8 ier = readb(&ch->ch_cls_uart->ier); + u8 isr_fcr = 0; + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn off IXOFF flow control, turn off RTS flow control */ + isr_fcr |= (UART_EXAR654_EFR_ECB); + isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* Disable interrupts for RTS flow */ + ier &= ~(UART_EXAR654_IER_RTSDTR); + writeb(ier, &ch->ch_cls_uart->ier); + + /* Set the usual FIFO values */ + writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr); + + writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 | + UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); + + ch->ch_t_tlevel = 16; + ch->ch_r_tlevel = 16; +} + +/* + * cls_clear_break. + * Determines whether its time to shut off break condition. + * + * No locks are assumed to be held when calling this function. + * channel lock is held and released in this function. + */ +static void cls_clear_break(struct jsm_channel *ch, int force) +{ + unsigned long lock_flags; + + spin_lock_irqsave(&ch->ch_lock, lock_flags); + + /* Turn break off, and unset some variables */ + if (ch->ch_flags & CH_BREAK_SENDING) { + u8 temp = readb(&ch->ch_cls_uart->lcr); + + writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); + + ch->ch_flags &= ~(CH_BREAK_SENDING); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, + "clear break Finishing UART_LCR_SBC! finished: %lx\n", + jiffies); + } + spin_unlock_irqrestore(&ch->ch_lock, lock_flags); +} + +static void cls_disable_receiver(struct jsm_channel *ch) +{ + u8 tmp = readb(&ch->ch_cls_uart->ier); + + tmp &= ~(UART_IER_RDI); + writeb(tmp, &ch->ch_cls_uart->ier); +} + +static void cls_enable_receiver(struct jsm_channel *ch) +{ + u8 tmp = readb(&ch->ch_cls_uart->ier); + + tmp |= (UART_IER_RDI); + writeb(tmp, &ch->ch_cls_uart->ier); +} + +/* Make the UART raise any of the output signals we want up */ +static void cls_assert_modem_signals(struct jsm_channel *ch) +{ + if (!ch) + return; + + writeb(ch->ch_mostat, &ch->ch_cls_uart->mcr); +} + +static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch) +{ + int qleft = 0; + u8 linestatus = 0; + u8 error_mask = 0; + u16 head; + u16 tail; + unsigned long flags; + + if (!ch) + return; + + spin_lock_irqsave(&ch->ch_lock, flags); + + /* cache head and tail of queue */ + head = ch->ch_r_head & RQUEUEMASK; + tail = ch->ch_r_tail & RQUEUEMASK; + + /* Get our cached LSR */ + linestatus = ch->ch_cached_lsr; + ch->ch_cached_lsr = 0; + + /* Store how much space we have left in the queue */ + qleft = tail - head - 1; + if (qleft < 0) + qleft += RQUEUEMASK + 1; + + /* + * Create a mask to determine whether we should + * insert the character (if any) into our queue. + */ + if (ch->ch_c_iflag & IGNBRK) + error_mask |= UART_LSR_BI; + + while (1) { + /* + * Grab the linestatus register, we need to + * check to see if there is any data to read + */ + linestatus = readb(&ch->ch_cls_uart->lsr); + + /* Break out if there is no data to fetch */ + if (!(linestatus & UART_LSR_DR)) + break; + + /* + * Discard character if we are ignoring the error mask + * which in this case is the break signal. + */ + if (linestatus & error_mask) { + u8 discard; + + linestatus = 0; + discard = readb(&ch->ch_cls_uart->txrx); + continue; + } + + /* + * If our queue is full, we have no choice but to drop some + * data. The assumption is that HWFLOW or SWFLOW should have + * stopped things way way before we got to this point. + * + * I decided that I wanted to ditch the oldest data first, + * I hope thats okay with everyone? Yes? Good. + */ + while (qleft < 1) { + tail = (tail + 1) & RQUEUEMASK; + ch->ch_r_tail = tail; + ch->ch_err_overrun++; + qleft++; + } + + ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE + | UART_LSR_FE); + ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx); + + qleft--; + + if (ch->ch_equeue[head] & UART_LSR_PE) + ch->ch_err_parity++; + if (ch->ch_equeue[head] & UART_LSR_BI) + ch->ch_err_break++; + if (ch->ch_equeue[head] & UART_LSR_FE) + ch->ch_err_frame++; + + /* Add to, and flip head if needed */ + head = (head + 1) & RQUEUEMASK; + ch->ch_rxcount++; + } + + /* + * Write new final heads to channel structure. + */ + ch->ch_r_head = head & RQUEUEMASK; + ch->ch_e_head = head & EQUEUEMASK; + + spin_unlock_irqrestore(&ch->ch_lock, flags); +} + +static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch) +{ + u16 tail; + int n; + int qlen; + u32 len_written = 0; + struct circ_buf *circ; + + if (!ch) + return; + + circ = &ch->uart_port.state->xmit; + + /* No data to write to the UART */ + if (uart_circ_empty(circ)) + return; + + /* If port is "stopped", don't send any data to the UART */ + if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_BREAK_SENDING)) + return; + + /* We have to do it this way, because of the EXAR TXFIFO count bug. */ + if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM))) + return; + + n = 32; + + /* cache tail of queue */ + tail = circ->tail & (UART_XMIT_SIZE - 1); + qlen = uart_circ_chars_pending(circ); + + /* Find minimum of the FIFO space, versus queue length */ + n = min(n, qlen); + + while (n > 0) { + writeb(circ->buf[tail], &ch->ch_cls_uart->txrx); + tail = (tail + 1) & (UART_XMIT_SIZE - 1); + n--; + ch->ch_txcount++; + len_written++; + } + + /* Update the final tail */ + circ->tail = tail & (UART_XMIT_SIZE - 1); + + if (len_written > ch->ch_t_tlevel) + ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); + + if (uart_circ_empty(circ)) + uart_write_wakeup(&ch->uart_port); +} + +static void cls_parse_modem(struct jsm_channel *ch, u8 signals) +{ + u8 msignals = signals; + + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, + "neo_parse_modem: port: %d msignals: %x\n", + ch->ch_portnum, msignals); + + /* + * Scrub off lower bits. + * They signify delta's, which I don't care about + * Keep DDCD and DDSR though + */ + msignals &= 0xf8; + + if (msignals & UART_MSR_DDCD) + uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD); + if (msignals & UART_MSR_DDSR) + uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_CTS); + + if (msignals & UART_MSR_DCD) + ch->ch_mistat |= UART_MSR_DCD; + else + ch->ch_mistat &= ~UART_MSR_DCD; + + if (msignals & UART_MSR_DSR) + ch->ch_mistat |= UART_MSR_DSR; + else + ch->ch_mistat &= ~UART_MSR_DSR; + + if (msignals & UART_MSR_RI) + ch->ch_mistat |= UART_MSR_RI; + else + ch->ch_mistat &= ~UART_MSR_RI; + + if (msignals & UART_MSR_CTS) + ch->ch_mistat |= UART_MSR_CTS; + else + ch->ch_mistat &= ~UART_MSR_CTS; + + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, + "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", + ch->ch_portnum, + !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), + !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_CTS), + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DSR), + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_RI), + !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DCD)); +} + +/* Parse the ISR register for the specific port */ +static inline void cls_parse_isr(struct jsm_board *brd, uint port) +{ + struct jsm_channel *ch; + u8 isr = 0; + unsigned long flags; + + /* + * No need to verify board pointer, it was already + * verified in the interrupt routine. + */ + + if (port > brd->nasync) + return; + + ch = brd->channels[port]; + if (!ch) + return; + + /* Here we try to figure out what caused the interrupt to happen */ + while (1) { + isr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Bail if no pending interrupt on port */ + if (isr & UART_IIR_NO_INT) + break; + + /* Receive Interrupt pending */ + if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) { + /* Read data from uart -> queue */ + cls_copy_data_from_uart_to_queue(ch); + jsm_check_queue_flow_control(ch); + } + + /* Transmit Hold register empty pending */ + if (isr & UART_IIR_THRI) { + /* Transfer data (if any) from Write Queue -> UART. */ + spin_lock_irqsave(&ch->ch_lock, flags); + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); + spin_unlock_irqrestore(&ch->ch_lock, flags); + cls_copy_data_from_queue_to_uart(ch); + } + + /* + * CTS/RTS change of state: + * Don't need to do anything, the cls_parse_modem + * below will grab the updated modem signals. + */ + + /* Parse any modem signal changes */ + cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); + } +} + +/* Channel lock MUST be held before calling this function! */ +static void cls_flush_uart_write(struct jsm_channel *ch) +{ + u8 tmp = 0; + u8 i = 0; + + if (!ch) + return; + + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), + &ch->ch_cls_uart->isr_fcr); + + for (i = 0; i < 10; i++) { + /* Check to see if the UART feels it completely flushed FIFO */ + tmp = readb(&ch->ch_cls_uart->isr_fcr); + if (tmp & UART_FCR_CLEAR_XMIT) { + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, + "Still flushing TX UART... i: %d\n", i); + udelay(10); + } else + break; + } + + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); +} + +/* Channel lock MUST be held before calling this function! */ +static void cls_flush_uart_read(struct jsm_channel *ch) +{ + if (!ch) + return; + + /* + * For complete POSIX compatibility, we should be purging the + * read FIFO in the UART here. + * + * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also + * incorrectly flushes write data as well as just basically trashing the + * FIFO. + * + * Presumably, this is a bug in this UART. + */ + + udelay(10); +} + +static void cls_send_start_character(struct jsm_channel *ch) +{ + if (!ch) + return; + + if (ch->ch_startc != __DISABLED_CHAR) { + ch->ch_xon_sends++; + writeb(ch->ch_startc, &ch->ch_cls_uart->txrx); + } +} + +static void cls_send_stop_character(struct jsm_channel *ch) +{ + if (!ch) + return; + + if (ch->ch_stopc != __DISABLED_CHAR) { + ch->ch_xoff_sends++; + writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx); + } +} + +/* + * cls_param() + * Send any/all changes to the line to the UART. + */ +static void cls_param(struct jsm_channel *ch) +{ + u8 lcr = 0; + u8 uart_lcr = 0; + u8 ier = 0; + u32 baud = 9600; + int quot = 0; + struct jsm_board *bd; + int i; + unsigned int cflag; + + bd = ch->ch_bd; + if (!bd) + return; + + /* + * If baud rate is zero, flush queues, and set mval to drop DTR. + */ + if ((ch->ch_c_cflag & (CBAUD)) == 0) { + ch->ch_r_head = 0; + ch->ch_r_tail = 0; + ch->ch_e_head = 0; + ch->ch_e_tail = 0; + + cls_flush_uart_write(ch); + cls_flush_uart_read(ch); + + /* The baudrate is B0 so all modem lines are to be dropped. */ + ch->ch_flags |= (CH_BAUD0); + ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); + cls_assert_modem_signals(ch); + return; + } + + cflag = C_BAUD(ch->uart_port.state->port.tty); + baud = 9600; + for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { + if (baud_rates[i].cflag == cflag) { + baud = baud_rates[i].rate; + break; + } + } + + if (ch->ch_flags & CH_BAUD0) + ch->ch_flags &= ~(CH_BAUD0); + + if (ch->ch_c_cflag & PARENB) + lcr |= UART_LCR_PARITY; + + if (!(ch->ch_c_cflag & PARODD)) + lcr |= UART_LCR_EPAR; + + /* + * Not all platforms support mark/space parity, + * so this will hide behind an ifdef. + */ +#ifdef CMSPAR + if (ch->ch_c_cflag & CMSPAR) + lcr |= UART_LCR_SPAR; +#endif + + if (ch->ch_c_cflag & CSTOPB) + lcr |= UART_LCR_STOP; + + switch (ch->ch_c_cflag & CSIZE) { + case CS5: + lcr |= UART_LCR_WLEN5; + break; + case CS6: + lcr |= UART_LCR_WLEN6; + break; + case CS7: + lcr |= UART_LCR_WLEN7; + break; + case CS8: + default: + lcr |= UART_LCR_WLEN8; + break; + } + + ier = readb(&ch->ch_cls_uart->ier); + uart_lcr = readb(&ch->ch_cls_uart->lcr); + + if (baud == 0) + baud = 9600; + + quot = ch->ch_bd->bd_dividend / baud; + + if (quot != 0) { + writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr); + writeb((quot & 0xff), &ch->ch_cls_uart->txrx); + writeb((quot >> 8), &ch->ch_cls_uart->ier); + writeb(lcr, &ch->ch_cls_uart->lcr); + } + + if (uart_lcr != lcr) + writeb(lcr, &ch->ch_cls_uart->lcr); + + if (ch->ch_c_cflag & CREAD) + ier |= (UART_IER_RDI | UART_IER_RLSI); + + ier |= (UART_IER_THRI | UART_IER_MSI); + + writeb(ier, &ch->ch_cls_uart->ier); + + if (ch->ch_c_cflag & CRTSCTS) + cls_set_cts_flow_control(ch); + else if (ch->ch_c_iflag & IXON) { + /* + * If start/stop is set to disable, + * then we should disable flow control. + */ + if ((ch->ch_startc == __DISABLED_CHAR) || + (ch->ch_stopc == __DISABLED_CHAR)) + cls_set_no_output_flow_control(ch); + else + cls_set_ixon_flow_control(ch); + } else + cls_set_no_output_flow_control(ch); + + if (ch->ch_c_cflag & CRTSCTS) + cls_set_rts_flow_control(ch); + else if (ch->ch_c_iflag & IXOFF) { + /* + * If start/stop is set to disable, + * then we should disable flow control. + */ + if ((ch->ch_startc == __DISABLED_CHAR) || + (ch->ch_stopc == __DISABLED_CHAR)) + cls_set_no_input_flow_control(ch); + else + cls_set_ixoff_flow_control(ch); + } else + cls_set_no_input_flow_control(ch); + + cls_assert_modem_signals(ch); + + /* get current status of the modem signals now */ + cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); +} + +/* + * cls_intr() + * + * Classic specific interrupt handler. + */ +static irqreturn_t cls_intr(int irq, void *voidbrd) +{ + struct jsm_board *brd = voidbrd; + unsigned long lock_flags; + unsigned char uart_poll; + uint i = 0; + + /* Lock out the slow poller from running on this board. */ + spin_lock_irqsave(&brd->bd_intr_lock, lock_flags); + + /* + * Check the board's global interrupt offset to see if we + * acctually do have an interrupt pending on us. + */ + uart_poll = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET); + + jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n", + __FILE__, __LINE__, uart_poll); + + if (!uart_poll) { + jsm_dbg(INTR, &brd->pci_dev, + "Kernel interrupted to me, but no pending interrupts...\n"); + spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); + return IRQ_NONE; + } + + /* At this point, we have at least SOMETHING to service, dig further. */ + + /* Parse each port to find out what caused the interrupt */ + for (i = 0; i < brd->nasync; i++) + cls_parse_isr(brd, i); + + spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); + + return IRQ_HANDLED; +} + +/* Inits UART */ +static void cls_uart_init(struct jsm_channel *ch) +{ + unsigned char lcrb = readb(&ch->ch_cls_uart->lcr); + unsigned char isr_fcr = 0; + + writeb(0, &ch->ch_cls_uart->ier); + + /* + * The Enhanced Register Set may only be accessed when + * the Line Control Register is set to 0xBFh. + */ + writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr); + + isr_fcr = readb(&ch->ch_cls_uart->isr_fcr); + + /* Turn on Enhanced/Extended controls */ + isr_fcr |= (UART_EXAR654_EFR_ECB); + + writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr); + + /* Write old LCR value back out, which turns enhanced access off */ + writeb(lcrb, &ch->ch_cls_uart->lcr); + + /* Clear out UART and FIFO */ + readb(&ch->ch_cls_uart->txrx); + + writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), + &ch->ch_cls_uart->isr_fcr); + udelay(10); + + ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); + + readb(&ch->ch_cls_uart->lsr); + readb(&ch->ch_cls_uart->msr); +} + +/* + * Turns off UART. + */ +static void cls_uart_off(struct jsm_channel *ch) +{ + /* Stop all interrupts from accurring. */ + writeb(0, &ch->ch_cls_uart->ier); +} + +/* + * cls_get_uarts_bytes_left. + * Returns 0 is nothing left in the FIFO, returns 1 otherwise. + * + * The channel lock MUST be held by the calling function. + */ +static u32 cls_get_uart_bytes_left(struct jsm_channel *ch) +{ + u8 left = 0; + u8 lsr = readb(&ch->ch_cls_uart->lsr); + + /* Determine whether the Transmitter is empty or not */ + if (!(lsr & UART_LSR_TEMT)) + left = 1; + else { + ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); + left = 0; + } + + return left; +} + +/* + * cls_send_break. + * Starts sending a break thru the UART. + * + * The channel lock MUST be held by the calling function. + */ +static void cls_send_break(struct jsm_channel *ch) +{ + /* Tell the UART to start sending the break */ + if (!(ch->ch_flags & CH_BREAK_SENDING)) { + u8 temp = readb(&ch->ch_cls_uart->lcr); + + writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr); + ch->ch_flags |= (CH_BREAK_SENDING); + } +} + +/* + * cls_send_immediate_char. + * Sends a specific character as soon as possible to the UART, + * jumping over any bytes that might be in the write queue. + * + * The channel lock MUST be held by the calling function. + */ +static void cls_send_immediate_char(struct jsm_channel *ch, unsigned char c) +{ + writeb(c, &ch->ch_cls_uart->txrx); +} + +struct board_ops jsm_cls_ops = { + .intr = cls_intr, + .uart_init = cls_uart_init, + .uart_off = cls_uart_off, + .param = cls_param, + .assert_modem_signals = cls_assert_modem_signals, + .flush_uart_write = cls_flush_uart_write, + .flush_uart_read = cls_flush_uart_read, + .disable_receiver = cls_disable_receiver, + .enable_receiver = cls_enable_receiver, + .send_break = cls_send_break, + .clear_break = cls_clear_break, + .send_start_character = cls_send_start_character, + .send_stop_character = cls_send_stop_character, + .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart, + .get_uart_bytes_left = cls_get_uart_bytes_left, + .send_immediate_char = cls_send_immediate_char +}; + -- GitLab From 8c402946f0743af91d22eca31d98b058b3371054 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 6 Nov 2014 15:16:04 -0800 Subject: [PATCH 3583/9457] f2fs: introduce the number of inode entries This patch adds to monitor the number of ino entries. Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 27 +++++++++++++++------------ fs/f2fs/debug.c | 4 +++- fs/f2fs/f2fs.h | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index dd6a357a59de..bcd686e0dded 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -318,6 +318,8 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) e->ino = ino; list_add_tail(&e->list, &sbi->ino_list[type]); + if (type != ORPHAN_INO) + sbi->ino_num[type]++; } spin_unlock(&sbi->ino_lock[type]); } @@ -331,8 +333,7 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) if (e) { list_del(&e->list); radix_tree_delete(&sbi->ino_root[type], ino); - if (type == ORPHAN_INO) - sbi->n_orphans--; + sbi->ino_num[type]--; spin_unlock(&sbi->ino_lock[type]); kmem_cache_free(ino_entry_slab, e); return; @@ -373,6 +374,7 @@ void release_dirty_inode(struct f2fs_sb_info *sbi) list_del(&e->list); radix_tree_delete(&sbi->ino_root[i], e->ino); kmem_cache_free(ino_entry_slab, e); + sbi->ino_num[i]--; } spin_unlock(&sbi->ino_lock[i]); } @@ -383,10 +385,10 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi) int err = 0; spin_lock(&sbi->ino_lock[ORPHAN_INO]); - if (unlikely(sbi->n_orphans >= sbi->max_orphans)) + if (unlikely(sbi->ino_num[ORPHAN_INO] >= sbi->max_orphans)) err = -ENOSPC; else - sbi->n_orphans++; + sbi->ino_num[ORPHAN_INO]++; spin_unlock(&sbi->ino_lock[ORPHAN_INO]); return err; @@ -395,8 +397,8 @@ int acquire_orphan_inode(struct f2fs_sb_info *sbi) void release_orphan_inode(struct f2fs_sb_info *sbi) { spin_lock(&sbi->ino_lock[ORPHAN_INO]); - f2fs_bug_on(sbi, sbi->n_orphans == 0); - sbi->n_orphans--; + f2fs_bug_on(sbi, sbi->ino_num[ORPHAN_INO] == 0); + sbi->ino_num[ORPHAN_INO]--; spin_unlock(&sbi->ino_lock[ORPHAN_INO]); } @@ -460,11 +462,12 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) struct f2fs_orphan_block *orphan_blk = NULL; unsigned int nentries = 0; unsigned short index; - unsigned short orphan_blocks = - (unsigned short)GET_ORPHAN_BLOCKS(sbi->n_orphans); + unsigned short orphan_blocks; struct page *page = NULL; struct ino_entry *orphan = NULL; + orphan_blocks = GET_ORPHAN_BLOCKS(sbi->ino_num[ORPHAN_INO]); + for (index = 0; index < orphan_blocks; index++) grab_meta_page(sbi, start_blk + index); @@ -892,7 +895,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) else clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); - orphan_blocks = GET_ORPHAN_BLOCKS(sbi->n_orphans); + orphan_blocks = GET_ORPHAN_BLOCKS(sbi->ino_num[ORPHAN_INO]); ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + orphan_blocks); @@ -908,7 +911,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) orphan_blocks); } - if (sbi->n_orphans) + if (sbi->ino_num[ORPHAN_INO]) set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); else clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); @@ -943,7 +946,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_put_page(cp_page, 1); } - if (sbi->n_orphans) { + if (sbi->ino_num[ORPHAN_INO]) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; } @@ -1045,6 +1048,7 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi) INIT_RADIX_TREE(&sbi->ino_root[i], GFP_ATOMIC); spin_lock_init(&sbi->ino_lock[i]); INIT_LIST_HEAD(&sbi->ino_list[i]); + sbi->ino_num[i] = 0; } /* @@ -1053,7 +1057,6 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi) * orphan entries with the limitation one reserved segment * for cp pack we can have max 1020*504 orphan entries */ - sbi->n_orphans = 0; sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS - NR_CURSEG_TYPE) * F2FS_ORPHANS_PER_BLOCK; } diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 86e6e926278d..74a0d78dbd3e 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -119,6 +119,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi) { struct f2fs_stat_info *si = F2FS_STAT(sbi); unsigned npages; + int i; if (si->base_mem) goto get_cache; @@ -168,8 +169,9 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->cache_mem += npages << PAGE_CACHE_SHIFT; npages = META_MAPPING(sbi)->nrpages; si->cache_mem += npages << PAGE_CACHE_SHIFT; - si->cache_mem += sbi->n_orphans * sizeof(struct ino_entry); si->cache_mem += sbi->n_dirty_dirs * sizeof(struct dir_inode_entry); + for (i = 0; i <= UPDATE_INO; i++) + si->cache_mem += sbi->ino_num[i] * sizeof(struct ino_entry); } static int stat_show(struct seq_file *s, void *v) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d45f3f4d7f93..994b87eb7a7d 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -532,9 +532,9 @@ struct f2fs_sb_info { struct radix_tree_root ino_root[MAX_INO_ENTRY]; /* ino entry array */ spinlock_t ino_lock[MAX_INO_ENTRY]; /* for ino entry lock */ struct list_head ino_list[MAX_INO_ENTRY]; /* inode list head */ + unsigned long ino_num[MAX_INO_ENTRY]; /* number of entries */ /* for orphan inode, use 0'th array */ - unsigned int n_orphans; /* # of orphan inodes */ unsigned int max_orphans; /* max orphan inodes */ /* for directory inode management */ -- GitLab From 03a8482c17dd0ae3251451d54cbbc03f930f21d5 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Fri, 7 Nov 2014 00:05:33 +0100 Subject: [PATCH 3584/9457] drivers: serial: jsm: Enable support for Digi Classic adapters This commit enables support for the Digi Classic adapters line in the jsm driver. This means changes in: - device probing code - device cleanup code - driver description (Kconfig) The init/cleanup code is based on the staging/dgnc driver. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 4 +- drivers/tty/serial/jsm/jsm.h | 4 + drivers/tty/serial/jsm/jsm_driver.c | 151 ++++++++++++++++++++++------ drivers/tty/serial/jsm/jsm_tty.c | 2 + 4 files changed, 128 insertions(+), 33 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 7088373efc15..e71a28b4b94e 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1029,11 +1029,11 @@ config SERIAL_VR41XX_CONSOLE a console on a serial port, say Y. Otherwise, say N. config SERIAL_JSM - tristate "Digi International NEO PCI Support" + tristate "Digi International NEO and Classic PCI Support" depends on PCI select SERIAL_CORE help - This is a driver for Digi International's Neo series + This is a driver for Digi International's Neo and Classic series of cards which provide multiple serial ports. You would need something like this to connect more than two modems to your Linux box, for instance in order to become a dial-in server. This driver diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 309428273571..662523d66704 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -68,6 +68,10 @@ do { \ #define MAX_STOPS_SENT 5 /* Board ids */ +#define PCI_DEVICE_ID_CLASSIC_4 0x0028 +#define PCI_DEVICE_ID_CLASSIC_8 0x0029 +#define PCI_DEVICE_ID_CLASSIC_4_422 0x00D0 +#define PCI_DEVICE_ID_CLASSIC_8_422 0x00D1 #define PCI_DEVICE_ID_NEO_4 0x00B0 #define PCI_DEVICE_ID_NEO_1_422 0x00CC #define PCI_DEVICE_ID_NEO_1_422_485 0x00CD diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index d2885a7bb090..0927ddf3d071 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -31,8 +31,7 @@ #include "jsm.h" MODULE_AUTHOR("Digi International, http://www.digi.com"); -MODULE_DESCRIPTION("Driver for the Digi International " - "Neo PCI based product line"); +MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("jsm"); @@ -50,7 +49,7 @@ struct uart_driver jsm_uart_driver = { }; static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state); + pci_channel_state_t state); static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); static void jsm_io_resume(struct pci_dev *pdev); @@ -68,7 +67,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc = 0; struct jsm_board *brd; - static int adapter_count = 0; + static int adapter_count; rc = pci_enable_device(pdev); if (rc) { @@ -82,10 +81,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_device; } - brd = kzalloc(sizeof(struct jsm_board), GFP_KERNEL); + brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) { - dev_err(&pdev->dev, - "memory allocation for board structure failed\n"); rc = -ENOMEM; goto out_release_regions; } @@ -95,7 +92,6 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->pci_dev = pdev; switch (pdev->device) { - case PCI_DEVICE_ID_NEO_2DB9: case PCI_DEVICE_ID_NEO_2DB9PRI: case PCI_DEVICE_ID_NEO_2RJ45: @@ -104,6 +100,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->maxports = 2; break; + case PCI_DEVICE_ID_CLASSIC_4: + case PCI_DEVICE_ID_CLASSIC_4_422: case PCI_DEVICE_ID_NEO_4: case PCIE_DEVICE_ID_NEO_4: case PCIE_DEVICE_ID_NEO_4RJ45: @@ -111,6 +109,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->maxports = 4; break; + case PCI_DEVICE_ID_CLASSIC_8: + case PCI_DEVICE_ID_CLASSIC_8_422: case PCI_DEVICE_ID_DIGI_NEO_8: case PCIE_DEVICE_ID_NEO_8: case PCIE_DEVICE_ID_NEO_8RJ45: @@ -129,36 +129,109 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->irq = pdev->irq; - jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); + switch (pdev->device) { + case PCI_DEVICE_ID_CLASSIC_4: + case PCI_DEVICE_ID_CLASSIC_4_422: + case PCI_DEVICE_ID_CLASSIC_8: + case PCI_DEVICE_ID_CLASSIC_8_422: + + jsm_dbg(INIT, &brd->pci_dev, + "jsm_found_board - Classic adapter\n"); + + /* + * For PCI ClassicBoards + * PCI Local Address (.i.e. "resource" number) space + * 0 PLX Memory Mapped Config + * 1 PLX I/O Mapped Config + * 2 I/O Mapped UARTs and Status + * 3 Memory Mapped VPD + * 4 Memory Mapped UARTs and Status + */ + + /* Get the PCI Base Address Registers */ + brd->membase = pci_resource_start(pdev, 4); + brd->membase_end = pci_resource_end(pdev, 4); + + if (brd->membase & 0x1) + brd->membase &= ~0x3; + else + brd->membase &= ~0xF; + + brd->iobase = pci_resource_start(pdev, 1); + brd->iobase_end = pci_resource_end(pdev, 1); + brd->iobase = ((unsigned int)(brd->iobase)) & 0xFFFE; + + /* Assign the board_ops struct */ + brd->bd_ops = &jsm_cls_ops; + + brd->bd_uart_offset = 0x8; + brd->bd_dividend = 921600; + + brd->re_map_membase = ioremap(brd->membase, + pci_resource_len(pdev, 4)); + if (!brd->re_map_membase) { + dev_err(&pdev->dev, + "Card has no PCI Memory resources, failing board.\n"); + rc = -ENOMEM; + goto out_kfree_brd; + } - /* get the PCI Base Address Registers */ - brd->membase = pci_resource_start(pdev, 0); - brd->membase_end = pci_resource_end(pdev, 0); + /* + * Enable Local Interrupt 1 (0x1), + * Local Interrupt 1 Polarity Active high (0x2), + * Enable PCI interrupt (0x43) + */ + outb(0x43, brd->iobase + 0x4c); - if (brd->membase & 1) - brd->membase &= ~3; - else - brd->membase &= ~15; + break; - /* Assign the board_ops struct */ - brd->bd_ops = &jsm_neo_ops; + case PCI_DEVICE_ID_NEO_2DB9: + case PCI_DEVICE_ID_NEO_2DB9PRI: + case PCI_DEVICE_ID_NEO_2RJ45: + case PCI_DEVICE_ID_NEO_2RJ45PRI: + case PCI_DEVICE_ID_NEO_2_422_485: + case PCI_DEVICE_ID_NEO_4: + case PCIE_DEVICE_ID_NEO_4: + case PCIE_DEVICE_ID_NEO_4RJ45: + case PCIE_DEVICE_ID_NEO_4_IBM: + case PCI_DEVICE_ID_DIGI_NEO_8: + case PCIE_DEVICE_ID_NEO_8: + case PCIE_DEVICE_ID_NEO_8RJ45: - brd->bd_uart_offset = 0x200; - brd->bd_dividend = 921600; + jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); - brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0)); - if (!brd->re_map_membase) { - dev_err(&pdev->dev, - "card has no PCI Memory resources, " - "failing board.\n"); - rc = -ENOMEM; - goto out_kfree_brd; + /* get the PCI Base Address Registers */ + brd->membase = pci_resource_start(pdev, 0); + brd->membase_end = pci_resource_end(pdev, 0); + + if (brd->membase & 1) + brd->membase &= ~0x3; + else + brd->membase &= ~0xF; + + /* Assign the board_ops struct */ + brd->bd_ops = &jsm_neo_ops; + + brd->bd_uart_offset = 0x200; + brd->bd_dividend = 921600; + + brd->re_map_membase = ioremap(brd->membase, + pci_resource_len(pdev, 0)); + if (!brd->re_map_membase) { + dev_err(&pdev->dev, + "Card has no PCI Memory resources, failing board.\n"); + rc = -ENOMEM; + goto out_kfree_brd; + } + + break; + default: + return -ENXIO; } - rc = request_irq(brd->irq, brd->bd_ops->intr, - IRQF_SHARED, "JSM", brd); + rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd); if (rc) { - printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); + dev_warn(&pdev->dev, "Failed to hook IRQ %d\n", brd->irq); goto out_iounmap; } @@ -178,7 +251,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Log the information about the board */ - dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n", + dev_info(&pdev->dev, "board %d: Digi Classic/Neo (rev %d), irq %d\n", adapter_count, brd->rev, brd->irq); pci_set_drvdata(pdev, brd); @@ -205,6 +278,18 @@ static void jsm_remove_one(struct pci_dev *pdev) struct jsm_board *brd = pci_get_drvdata(pdev); int i = 0; + switch (pdev->device) { + case PCI_DEVICE_ID_CLASSIC_4: + case PCI_DEVICE_ID_CLASSIC_4_422: + case PCI_DEVICE_ID_CLASSIC_8: + case PCI_DEVICE_ID_CLASSIC_8_422: + /* Tell card not to interrupt anymore. */ + outb(0x0, brd->iobase + 0x4c); + break; + default: + break; + } + jsm_remove_uart_port(brd); free_irq(brd->irq, brd); @@ -239,6 +324,10 @@ static struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4), 0, 0, 11 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4RJ45), 0, 0, 12 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_8RJ45), 0, 0, 13 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_4), 0, 0, 14 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_4_422), 0, 0, 15 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_8), 0, 0, 16 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_CLASSIC_8_422), 0, 0, 17 }, { 0, } }; MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 8814680630a4..4259e5af8467 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -425,6 +425,8 @@ int jsm_tty_init(struct jsm_board *brd) if (brd->bd_uart_offset == 0x200) ch->ch_neo_uart = vaddr + (brd->bd_uart_offset * i); + else + ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i); ch->ch_bd = brd; ch->ch_portnum = i; -- GitLab From ad5708f67e0f5aa78915715c660b4f2ca9130279 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Fri, 7 Nov 2014 00:05:35 +0100 Subject: [PATCH 3585/9457] drivers: serial: jsm: Remove FSF address from the file documentation/header This commit removes the address of Free Software Foundation from each of the mentioned file in order to suppress the checkpatch warning. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm.h | 5 ----- drivers/tty/serial/jsm/jsm_cls.c | 5 ----- drivers/tty/serial/jsm/jsm_driver.c | 5 ----- drivers/tty/serial/jsm/jsm_neo.c | 5 ----- drivers/tty/serial/jsm/jsm_tty.c | 5 ----- 5 files changed, 25 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 662523d66704..72ed5c106d26 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -13,11 +13,6 @@ * 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. - * * Contact Information: * Scott H Kilau * Wendy Xiong diff --git a/drivers/tty/serial/jsm/jsm_cls.c b/drivers/tty/serial/jsm/jsm_cls.c index b3a508d5608c..4cb927563cf1 100644 --- a/drivers/tty/serial/jsm/jsm_cls.c +++ b/drivers/tty/serial/jsm/jsm_cls.c @@ -12,11 +12,6 @@ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! * * This is shared code between Digi's CVS archive and the diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 0927ddf3d071..efbd87a76656 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -13,11 +13,6 @@ * 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. - * * Contact Information: * Scott H Kilau * Wendy Xiong diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index dfaf48826417..dc2cd9040d64 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -13,11 +13,6 @@ * 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. - * * Contact Information: * Scott H Kilau * Wendy Xiong diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 4259e5af8467..c60e4542c050 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -13,11 +13,6 @@ * 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. - * * Contact Information: * Scott H Kilau * Ananda Venkatarman -- GitLab From e5e7ea3c86e56b725e4076e8dc583378abad7697 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 6 Nov 2014 15:24:46 -0800 Subject: [PATCH 3586/9457] f2fs: control the memory footprint used by ino entries This patch adds to control the memory footprint used by ino entries. This will conduct best effort, not strictly. Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 28 ++++++++++++++++++++++------ fs/f2fs/node.h | 3 ++- fs/f2fs/segment.c | 3 ++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 44b8afef43d9..4ea2c4728156 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -31,22 +31,38 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct sysinfo val; + unsigned long avail_ram; unsigned long mem_size = 0; bool res = false; si_meminfo(&val); - /* give 25%, 25%, 50% memory for each components respectively */ + + /* only uses low memory */ + avail_ram = val.totalram - val.totalhigh; + + /* give 25%, 25%, 50%, 50% memory for each components respectively */ if (type == FREE_NIDS) { - mem_size = (nm_i->fcnt * sizeof(struct free_nid)) >> 12; - res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 2); + mem_size = (nm_i->fcnt * sizeof(struct free_nid)) >> + PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2); } else if (type == NAT_ENTRIES) { - mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >> 12; - res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 2); + mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >> + PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2); } else if (type == DIRTY_DENTS) { if (sbi->sb->s_bdi->dirty_exceeded) return false; mem_size = get_pages(sbi, F2FS_DIRTY_DENTS); - res = mem_size < ((val.totalram * nm_i->ram_thresh / 100) >> 1); + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); + } else if (type == INO_ENTRIES) { + int i; + + if (sbi->sb->s_bdi->dirty_exceeded) + return false; + for (i = 0; i <= UPDATE_INO; i++) + mem_size += (sbi->ino_num[i] * sizeof(struct ino_entry)) + >> PAGE_CACHE_SHIFT; + res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); } return res; } diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index acb71e507a7a..d10b6448a671 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -106,7 +106,8 @@ static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne, enum mem_type { FREE_NIDS, /* indicates the free nid list */ NAT_ENTRIES, /* indicates the cached nat entry */ - DIRTY_DENTS /* indicates dirty dentry pages */ + DIRTY_DENTS, /* indicates dirty dentry pages */ + INO_ENTRIES, /* indicates inode entries */ }; struct nat_entry_set { diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 16721b5dffa4..e094675497d8 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -276,7 +276,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) { /* check the # of cached NAT entries and prefree segments */ if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK) || - excess_prefree_segs(sbi)) + excess_prefree_segs(sbi) || + available_free_memory(sbi, INO_ENTRIES)) f2fs_sync_fs(sbi->sb, true); } -- GitLab From e98c72c94205c59745f9ed0ac2837d5b83084a46 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 6 Nov 2014 17:02:13 -0600 Subject: [PATCH 3587/9457] amd-xgbe: Free channel/ring structures later The channel structure is freed before freeing the per channel interrupts resulting in a kernel oops. Move the call to free the channel structure to after the freeing of the per channel interrupts. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index ced9f52eb45b..ec5fff38108d 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1369,9 +1369,6 @@ static int xgbe_close(struct net_device *netdev) /* Free the ring descriptors and buffers */ desc_if->free_ring_resources(pdata); - /* Free the channel and ring structures */ - xgbe_free_channels(pdata); - /* Release the interrupts */ devm_free_irq(pdata->dev, pdata->dev_irq, pdata); if (pdata->per_channel_irq) { @@ -1380,6 +1377,9 @@ static int xgbe_close(struct net_device *netdev) devm_free_irq(pdata->dev, channel->dma_irq, channel); } + /* Free the channel and ring structures */ + xgbe_free_channels(pdata); + /* Disable the clocks */ clk_disable_unprepare(pdata->ptpclk); clk_disable_unprepare(pdata->sysclk); -- GitLab From f5eecbbef0b7d28b171b3b873e1e4a69aabd7b58 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 6 Nov 2014 17:02:19 -0600 Subject: [PATCH 3588/9457] amd-xgbe: Check for complete packet on skb allocation error If the skb allocation fails during receive processing, the driver would continue reading descriptors without first determining if there were any more descriptors for the current packet. Update the code to check whether more descriptors are associated with the current packet or whether to move on to the next descriptor as a new packet. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index ec5fff38108d..0544931329d1 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1908,7 +1908,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) skb = xgbe_create_skb(pdata, rdata, &put_len); if (!skb) { error = 1; - goto read_again; + goto skip_data; } } @@ -1926,10 +1926,10 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) } } +skip_data: if (incomplete || context_next) goto read_again; - /* Stray Context Descriptor? */ if (!skb) goto next_packet; -- GitLab From 245bd6f6af8a62a2e2e14976e5ef3dc2b82ec153 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Nov 2014 15:51:00 +0200 Subject: [PATCH 3589/9457] PM / clock_ops: Add pm_clk_add_clk() The existing pm_clk_add() allows to pass a clock by con_id. However, when referring to a specific clock from DT, no con_id is available. Add pm_clk_add_clk(), which allows to specify the struct clk * directly. The will will increment refcount on clock pointer, so the caller has to use clk_put() on clock pointer when done. Reviewed-by: Santosh Shilimkar Reviewed-by: Kevin Hilman Signed-off-by: Geert Uytterhoeven Signed-off-by: Grygorii Strashko Reviewed-by: Dmitry Torokhov Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 47 ++++++++++++++++++++++++++-------- include/linux/pm_clock.h | 8 ++++++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 78369305e069..f061eaa48bb5 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,8 @@ static inline int __pm_clk_enable(struct device *dev, struct clk *clk) */ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) { - ce->clk = clk_get(dev, ce->con_id); + if (!ce->clk) + ce->clk = clk_get(dev, ce->con_id); if (IS_ERR(ce->clk)) { ce->status = PCE_STATUS_ERROR; } else { @@ -63,15 +65,8 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) } } -/** - * pm_clk_add - Start using a device clock for power management. - * @dev: Device whose clock is going to be used for power management. - * @con_id: Connection ID of the clock. - * - * Add the clock represented by @con_id to the list of clocks used for - * the power management of @dev. - */ -int pm_clk_add(struct device *dev, const char *con_id) +static int __pm_clk_add(struct device *dev, const char *con_id, + struct clk *clk) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; @@ -93,6 +88,12 @@ int pm_clk_add(struct device *dev, const char *con_id) kfree(ce); return -ENOMEM; } + } else { + if (IS_ERR(ce->clk) || !__clk_get(clk)) { + kfree(ce); + return -ENOENT; + } + ce->clk = clk; } pm_clk_acquire(dev, ce); @@ -103,6 +104,32 @@ int pm_clk_add(struct device *dev, const char *con_id) return 0; } +/** + * pm_clk_add - Start using a device clock for power management. + * @dev: Device whose clock is going to be used for power management. + * @con_id: Connection ID of the clock. + * + * Add the clock represented by @con_id to the list of clocks used for + * the power management of @dev. + */ +int pm_clk_add(struct device *dev, const char *con_id) +{ + return __pm_clk_add(dev, con_id, NULL); +} + +/** + * pm_clk_add_clk - Start using a device clock for power management. + * @dev: Device whose clock is going to be used for power management. + * @clk: Clock pointer + * + * Add the clock to the list of clocks used for the power management of @dev. + * It will increment refcount on clock pointer, use clk_put() on it when done. + */ +int pm_clk_add_clk(struct device *dev, struct clk *clk) +{ + return __pm_clk_add(dev, NULL, clk); +} + /** * __pm_clk_remove - Destroy PM clock entry. * @ce: PM clock entry to destroy. diff --git a/include/linux/pm_clock.h b/include/linux/pm_clock.h index 8348866e7b05..0b0039634410 100644 --- a/include/linux/pm_clock.h +++ b/include/linux/pm_clock.h @@ -18,6 +18,8 @@ struct pm_clk_notifier_block { char *con_ids[]; }; +struct clk; + #ifdef CONFIG_PM_CLK static inline bool pm_clk_no_clocks(struct device *dev) { @@ -29,6 +31,7 @@ extern void pm_clk_init(struct device *dev); extern int pm_clk_create(struct device *dev); extern void pm_clk_destroy(struct device *dev); extern int pm_clk_add(struct device *dev, const char *con_id); +extern int pm_clk_add_clk(struct device *dev, struct clk *clk); extern void pm_clk_remove(struct device *dev, const char *con_id); extern int pm_clk_suspend(struct device *dev); extern int pm_clk_resume(struct device *dev); @@ -51,6 +54,11 @@ static inline int pm_clk_add(struct device *dev, const char *con_id) { return -EINVAL; } + +static inline int pm_clk_add_clk(struct device *dev, struct clk *clk) +{ + return -EINVAL; +} static inline void pm_clk_remove(struct device *dev, const char *con_id) { } -- GitLab From 471f7707b6f0b18b6aa81119ed01525d9e712427 Mon Sep 17 00:00:00 2001 From: "Strashko, Grygorii" Date: Thu, 6 Nov 2014 15:51:01 +0200 Subject: [PATCH 3590/9457] PM / clock_ops: make __pm_clk_enable more generic Now there are two places in code which do the same things, so allow __pm_clk_enable() to accept pointer on pm_clock_entry structure as second parameter instead of pointer on clock and remove duplicated code. Also, updated function intended to be used by following patch. Signed-off-by: Grygorii Strashko Reviewed-by: Dmitry Torokhov Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 38 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index f061eaa48bb5..b32b5d47b3c5 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -35,14 +35,20 @@ struct pm_clock_entry { /** * pm_clk_enable - Enable a clock, reporting any errors * @dev: The device for the given clock - * @clk: The clock being enabled. + * @ce: PM clock entry corresponding to the clock. */ -static inline int __pm_clk_enable(struct device *dev, struct clk *clk) +static inline int __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce) { - int ret = clk_enable(clk); - if (ret) - dev_err(dev, "%s: failed to enable clk %p, error %d\n", - __func__, clk, ret); + int ret; + + if (ce->status < PCE_STATUS_ERROR) { + ret = clk_enable(ce->clk); + if (!ret) + ce->status = PCE_STATUS_ENABLED; + else + dev_err(dev, "%s: failed to enable clk %p, error %d\n", + __func__, ce->clk, ret); + } return ret; } @@ -293,7 +299,6 @@ int pm_clk_resume(struct device *dev) struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; unsigned long flags; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -302,13 +307,8 @@ int pm_clk_resume(struct device *dev) spin_lock_irqsave(&psd->lock, flags); - list_for_each_entry(ce, &psd->clock_list, node) { - if (ce->status < PCE_STATUS_ERROR) { - ret = __pm_clk_enable(dev, ce->clk); - if (!ret) - ce->status = PCE_STATUS_ENABLED; - } - } + list_for_each_entry(ce, &psd->clock_list, node) + __pm_clk_enable(dev, ce); spin_unlock_irqrestore(&psd->lock, flags); @@ -417,7 +417,6 @@ int pm_clk_resume(struct device *dev) struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; unsigned long flags; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -427,13 +426,8 @@ int pm_clk_resume(struct device *dev) spin_lock_irqsave(&psd->lock, flags); - list_for_each_entry(ce, &psd->clock_list, node) { - if (ce->status < PCE_STATUS_ERROR) { - ret = __pm_clk_enable(dev, ce->clk); - if (!ret) - ce->status = PCE_STATUS_ENABLED; - } - } + list_for_each_entry(ce, &psd->clock_list, node) + __pm_clk_enable(dev, ce); spin_unlock_irqrestore(&psd->lock, flags); -- GitLab From 5fa2704e011e6d0ebc144188cc5fb02363e12f05 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Nov 2014 11:02:26 +1000 Subject: [PATCH 3591/9457] drm: drop README.drm, ancient scrolls This stuff is ancient, we have docs now in the kernel, lets just drop it. Pointed out by Glenn Reviewed-by: Thierry Reding Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/README.drm | 43 -------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 drivers/gpu/drm/README.drm diff --git a/drivers/gpu/drm/README.drm b/drivers/gpu/drm/README.drm deleted file mode 100644 index b5b332722581..000000000000 --- a/drivers/gpu/drm/README.drm +++ /dev/null @@ -1,43 +0,0 @@ -************************************************************ -* For the very latest on DRI development, please see: * -* http://dri.freedesktop.org/ * -************************************************************ - -The Direct Rendering Manager (drm) is a device-independent kernel-level -device driver that provides support for the XFree86 Direct Rendering -Infrastructure (DRI). - -The DRM supports the Direct Rendering Infrastructure (DRI) in four major -ways: - - 1. The DRM provides synchronized access to the graphics hardware via - the use of an optimized two-tiered lock. - - 2. The DRM enforces the DRI security policy for access to the graphics - hardware by only allowing authenticated X11 clients access to - restricted regions of memory. - - 3. The DRM provides a generic DMA engine, complete with multiple - queues and the ability to detect the need for an OpenGL context - switch. - - 4. The DRM is extensible via the use of small device-specific modules - that rely extensively on the API exported by the DRM module. - - -Documentation on the DRI is available from: - http://dri.freedesktop.org/wiki/Documentation - http://sourceforge.net/project/showfiles.php?group_id=387 - http://dri.sourceforge.net/doc/ - -For specific information about kernel-level support, see: - - The Direct Rendering Manager, Kernel Support for the Direct Rendering - Infrastructure - http://dri.sourceforge.net/doc/drm_low_level.html - - Hardware Locking for the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/hardware_locking_low_level.html - - A Security Analysis of the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/security_low_level.html -- GitLab From 5c91ae08e4500ebc8efd584c8b87c4040d5393ea Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Thu, 6 Nov 2014 18:06:01 -0800 Subject: [PATCH 3592/9457] vxlan: Fix to enable UDP checksums on interface Add definition to vxlan nla_policy for UDP checksum. This is necessary to enable UDP checksums on VXLAN. In some instances, enabling UDP checksums can improve performance on receive for devices that return legacy checksum-unnecessary for UDP/IP. Also, UDP checksum provides some protection against VNI corruption. Testing: Ran 200 instances of TCP_STREAM and TCP_RR on bnx2x. TCP_STREAM IPv4, without UDP checksums 14.41% TX CPU utilization 25.71% RX CPU utilization 9083.4 Mbps IPv4, with UDP checksums 13.99% TX CPU utilization 13.40% RX CPU utilization 9095.65 Mbps TCP_RR IPv4, without UDP checksums 94.08% TX CPU utilization 156/248/462 90/95/99% latencies 1.12743e+06 tps IPv4, with UDP checksums 94.43% TX CPU utilization 158/250/462 90/95/99% latencies 1.13345e+06 tps Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ca309820d39e..0ab411461d2e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2233,6 +2233,9 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 }, [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 }, [IFLA_VXLAN_PORT] = { .type = NLA_U16 }, + [IFLA_VXLAN_UDP_CSUM] = { .type = NLA_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 }, }; static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) -- GitLab From 929059250a6795da9a8bd91b8d7a4d9379030f49 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 23 Oct 2014 16:31:05 +0200 Subject: [PATCH 3593/9457] of: Add vendor prefix for HannStar Display Corporation Signed-off-by: Philipp Zabel Acked-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 723999d73744..98630393e57f 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -64,6 +64,7 @@ gmt Global Mixed-mode Technology, Inc. google Google, Inc. gumstix Gumstix, Inc. gw Gateworks Corporation +hannstar HannStar Display Corporation haoyu Haoyu Microelectronic Co. Ltd. hisilicon Hisilicon Limited. honeywell Honeywell -- GitLab From a853205efb741951382edfdb1efa36886eeb90c3 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 23 Oct 2014 16:31:06 +0200 Subject: [PATCH 3594/9457] drm/panel: simple: Add HannStar HSD070PWW1 7.0" WXGA TFT LCD panel This patch adds support for the HannStar Display Corp. HSD070PWW1 7.0" WXGA TFT LCD panel to the simple-panel driver. The binding documentation is included. This panel is connected via LVDS and uses the data enable signal for timing. Since HSYNC/VSYNC are ignored, the split between sync length and porches is arbitrary, as long as the complete horizontal blanking interval is 160 clocks, and the vertical blanking interval is 23 lines. Signed-off-by: Philipp Zabel Signed-off-by: Thierry Reding --- .../bindings/panel/hannstar,hsd070pww1.txt | 7 +++++ drivers/gpu/drm/panel/panel-simple.c | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt diff --git a/Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt b/Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt new file mode 100644 index 000000000000..7da1d5c038ff --- /dev/null +++ b/Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt @@ -0,0 +1,7 @@ +HannStar Display Corp. HSD070PWW1 7.0" WXGA TFT LCD panel + +Required properties: +- compatible: should be "hannstar,hsd070pww1" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 83d93062930d..de78d3e0f226 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -535,6 +535,29 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = { }, }; +static const struct drm_display_mode hannstar_hsd070pww1_mode = { + .clock = 71100, + .hdisplay = 1280, + .hsync_start = 1280 + 1, + .hsync_end = 1280 + 1 + 158, + .htotal = 1280 + 1 + 158 + 1, + .vdisplay = 800, + .vsync_start = 800 + 1, + .vsync_end = 800 + 1 + 21, + .vtotal = 800 + 1 + 21 + 1, + .vrefresh = 60, +}; + +static const struct panel_desc hannstar_hsd070pww1 = { + .modes = &hannstar_hsd070pww1_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 151, + .height = 94, + }, +}; + static const struct drm_display_mode innolux_n116bge_mode = { .clock = 71000, .hdisplay = 1366, @@ -659,6 +682,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "foxlink,fl500wvr00-a0t", .data = &foxlink_fl500wvr00_a0t, + }, { + .compatible = "hannstar,hsd070pww1", + .data = &hannstar_hsd070pww1, }, { .compatible = "innolux,n116bge", .data = &innolux_n116bge, -- GitLab From e35e305eff0fda4ddd5cfbd8eea06948faa503af Mon Sep 17 00:00:00 2001 From: Ajay Kumar Date: Mon, 1 Sep 2014 15:40:02 +0530 Subject: [PATCH 3595/9457] drm/panel: simple: Add AUO B116XW03 panel support The AUO B116XW03 is a 11.6" HD TFT LCD panel connecting to a LVDS interface and with an integrated LED backlight unit. This panel is used on the Samsung Chromebook(XE303C12). Signed-off-by: Ajay Kumar [treding@nvidia.com: add missing .bpc field] Signed-off-by: Thierry Reding --- .../bindings/panel/auo,b116xw03.txt | 7 +++++ drivers/gpu/drm/panel/panel-simple.c | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/auo,b116xw03.txt diff --git a/Documentation/devicetree/bindings/panel/auo,b116xw03.txt b/Documentation/devicetree/bindings/panel/auo,b116xw03.txt new file mode 100644 index 000000000000..690d0a568ef3 --- /dev/null +++ b/Documentation/devicetree/bindings/panel/auo,b116xw03.txt @@ -0,0 +1,7 @@ +AU Optronics Corporation 11.6" HD (1366x768) color TFT-LCD panel + +Required properties: +- compatible: should be "auo,b116xw03" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index de78d3e0f226..f6d6ebc33e78 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -369,6 +369,29 @@ static const struct panel_desc auo_b101xtn01 = { }, }; +static const struct drm_display_mode auo_b116xw03_mode = { + .clock = 70589, + .hdisplay = 1366, + .hsync_start = 1366 + 40, + .hsync_end = 1366 + 40 + 40, + .htotal = 1366 + 40 + 40 + 32, + .vdisplay = 768, + .vsync_start = 768 + 10, + .vsync_end = 768 + 10 + 12, + .vtotal = 768 + 10 + 12 + 6, + .vrefresh = 60, +}; + +static const struct panel_desc auo_b116xw03 = { + .modes = &auo_b116xw03_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 256, + .height = 144, + }, +}; + static const struct drm_display_mode auo_b133xtn01_mode = { .clock = 69500, .hdisplay = 1366, @@ -658,6 +681,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,b101xtn01", .data = &auo_b101xtn01, + }, { + .compatible = "auo,b116xw03", + .data = &auo_b116xw03, }, { .compatible = "auo,b133htn01", .data = &auo_b133htn01, -- GitLab From d7a839cde9acaa7252c75178bdbacce3cf12419c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 10:11:01 +0100 Subject: [PATCH 3596/9457] drm/panel: simple: Add missing .bpc fields Various panels were missing the .bpc field which encodes the number of bits per color. Not every display driver relies on this value, but since the panels can be used with any display engine it must be specified so that if a driver knows how to differentiate based on this field it can do so. Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index f6d6ebc33e78..bc6a566b1f26 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -431,6 +431,7 @@ static const struct drm_display_mode auo_b133htn01_mode = { static const struct panel_desc auo_b133htn01 = { .modes = &auo_b133htn01_mode, .num_modes = 1, + .bpc = 6, .size = { .width = 293, .height = 165, @@ -552,6 +553,7 @@ static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = { static const struct panel_desc foxlink_fl500wvr00_a0t = { .modes = &foxlink_fl500wvr00_a0t_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 108, .height = 65, @@ -786,6 +788,7 @@ static const struct panel_desc_dsi lg_ld070wx3_sl01 = { .desc = { .modes = &lg_ld070wx3_sl01_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 94, .height = 151, @@ -813,6 +816,7 @@ static const struct panel_desc_dsi lg_lh500wx1_sd03 = { .desc = { .modes = &lg_lh500wx1_sd03_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 62, .height = 110, @@ -840,6 +844,7 @@ static const struct panel_desc_dsi panasonic_vvx10f004b00 = { .desc = { .modes = &panasonic_vvx10f004b00_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 217, .height = 136, -- GitLab From d731f661b5d2dd5f7748d2d8a4ed939b9d88128d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 6 Nov 2014 17:44:33 +0100 Subject: [PATCH 3597/9457] drm/panel: simple: Add support for Innolux G121I1-L01 The Innolux G121I1-L01 is a 12.1" TFT LCD panel and can be supported by the simple-panel driver. This panel is connected via LVDS and uses the data enable signal for timing. Since HSYNC/VSYNC are ignored, the split between sync length and porches is arbitrary, as long as the complete horizontal blanking interval is 160 clocks, and the vertical blanking interval is 24 lines. Signed-off-by: Lucas Stach Signed-off-by: Thierry Reding --- .../bindings/panel/innolux,g121i1-l01.txt | 7 +++++ drivers/gpu/drm/panel/panel-simple.c | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt diff --git a/Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt b/Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt new file mode 100644 index 000000000000..2743b07cd2f2 --- /dev/null +++ b/Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt @@ -0,0 +1,7 @@ +Innolux Corporation 12.1" WXGA (1280x800) TFT LCD panel + +Required properties: +- compatible: should be "innolux,g121i1-l01" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index bc6a566b1f26..be535e787d5e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -583,6 +583,29 @@ static const struct panel_desc hannstar_hsd070pww1 = { }, }; +static const struct drm_display_mode innolux_g121i1_l01_mode = { + .clock = 71000, + .hdisplay = 1280, + .hsync_start = 1280 + 64, + .hsync_end = 1280 + 64 + 32, + .htotal = 1280 + 64 + 32 + 64, + .vdisplay = 800, + .vsync_start = 800 + 9, + .vsync_end = 800 + 9 + 6, + .vtotal = 800 + 9 + 6 + 9, + .vrefresh = 60, +}; + +static const struct panel_desc innolux_g121i1_l01 = { + .modes = &innolux_g121i1_l01_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 261, + .height = 163, + }, +}; + static const struct drm_display_mode innolux_n116bge_mode = { .clock = 71000, .hdisplay = 1366, @@ -713,6 +736,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "hannstar,hsd070pww1", .data = &hannstar_hsd070pww1, + }, { + .compatible ="innolux,g121i1-l01", + .data = &innolux_g121i1_l01 }, { .compatible = "innolux,n116bge", .data = &innolux_n116bge, -- GitLab From 071964ae2b27e645fe8324557fe2754ec77b6417 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 6 Nov 2014 17:44:34 +0100 Subject: [PATCH 3598/9457] of: Add vendor prefix for Hitachi Ltd. Corporation Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 98630393e57f..0b2fc732f1f3 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -67,6 +67,7 @@ gw Gateworks Corporation hannstar HannStar Display Corporation haoyu Haoyu Microelectronic Co. Ltd. hisilicon Hisilicon Limited. +hit Hitachi Ltd. honeywell Honeywell hp Hewlett Packard i2se I2SE GmbH -- GitLab From 61ac0bf89d74e92b086eb147e5a5aed5b37ad396 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 6 Nov 2014 17:44:35 +0100 Subject: [PATCH 3599/9457] drm/panel: simple: Add support for Hitachi TX23D38VM0CAA The Hitachi TX23D38VM0CAA is a 9" WVGA TFT LCD panel and can be supported by the simple-panel driver. This panel is connected via LVDS and uses the data enable signal for timing. Since HSYNC/VSYNC are ignored, the split between sync length and porches is arbitrary, as long as the complete horizontal blanking interval is 256 clocks, and the vertical blanking interval is 45 lines. Signed-off-by: Lucas Stach Signed-off-by: Thierry Reding --- .../bindings/panel/hit,tx23d38vm0caa.txt | 7 +++++ drivers/gpu/drm/panel/panel-simple.c | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt diff --git a/Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt b/Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt new file mode 100644 index 000000000000..04caaae19af6 --- /dev/null +++ b/Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt @@ -0,0 +1,7 @@ +Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel + +Required properties: +- compatible: should be "hit,tx23d38vm0caa" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index be535e787d5e..965114b7d6bf 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -583,6 +583,29 @@ static const struct panel_desc hannstar_hsd070pww1 = { }, }; +static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = { + .clock = 33333, + .hdisplay = 800, + .hsync_start = 800 + 85, + .hsync_end = 800 + 85 + 86, + .htotal = 800 + 85 + 86 + 85, + .vdisplay = 480, + .vsync_start = 480 + 16, + .vsync_end = 480 + 16 + 13, + .vtotal = 480 + 16 + 13 + 16, + .vrefresh = 60, +}; + +static const struct panel_desc hitachi_tx23d38vm0caa = { + .modes = &hitachi_tx23d38vm0caa_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 195, + .height = 117, + }, +}; + static const struct drm_display_mode innolux_g121i1_l01_mode = { .clock = 71000, .hdisplay = 1280, @@ -736,6 +759,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "hannstar,hsd070pww1", .data = &hannstar_hsd070pww1, + }, { + .compatible = "hit,tx23d38vm0caa", + .data = &hitachi_tx23d38vm0caa }, { .compatible ="innolux,g121i1-l01", .data = &innolux_g121i1_l01 -- GitLab From 789c89935cef776ab5e8b8c5120d9c29a88ab40e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 20 Oct 2014 17:52:31 +0300 Subject: [PATCH 3600/9457] UBIFS: fix budget leak in error path We forgot to free the budget in 'write_begin_slow()' when 'do_readpage()' fails. This patch fixes the issue. Suggested-by: Kirill A. Shutemov Signed-off-by: Artem Bityutskiy --- fs/ubifs/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index b5b593c45270..538519ee37d9 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -262,6 +262,7 @@ static int write_begin_slow(struct address_space *mapping, if (err) { unlock_page(page); page_cache_release(page); + ubifs_release_budget(c, &req); return err; } } -- GitLab From 326087033108e7806e24974f2c8271f95cddaf3a Mon Sep 17 00:00:00 2001 From: Tanya Brokhman Date: Mon, 20 Oct 2014 19:57:00 +0300 Subject: [PATCH 3601/9457] UBI: Extend UBI layer debug/messaging capabilities If there is more then one UBI device mounted, there is no way to distinguish between messages from different UBI devices. Add device number to all ubi layer message types. The R/O block driver messages were replaced by pr_* since ubi_device structure is not used by it. Amended a bit by Artem. Signed-off-by: Tanya Brokhman Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 126 +++++++++++++++++--------------- drivers/mtd/ubi/block.c | 41 +++++------ drivers/mtd/ubi/build.c | 126 +++++++++++++++++--------------- drivers/mtd/ubi/cdev.c | 36 ++++----- drivers/mtd/ubi/debug.c | 10 +-- drivers/mtd/ubi/eba.c | 53 +++++++------- drivers/mtd/ubi/fastmap.c | 96 ++++++++++++------------ drivers/mtd/ubi/io.c | 150 +++++++++++++++++++------------------- drivers/mtd/ubi/kapi.c | 6 +- drivers/mtd/ubi/misc.c | 4 +- drivers/mtd/ubi/ubi.h | 13 ++-- drivers/mtd/ubi/vmt.c | 69 +++++++++--------- drivers/mtd/ubi/vtbl.c | 48 ++++++------ drivers/mtd/ubi/wl.c | 70 ++++++++++-------- 14 files changed, 441 insertions(+), 407 deletions(-) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 6f27d9a1be3b..9d2e16f3150a 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -176,6 +176,7 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) /** * validate_vid_hdr - check volume identifier header. + * @ubi: UBI device description object * @vid_hdr: the volume identifier header to check * @av: information about the volume this logical eraseblock belongs to * @pnum: physical eraseblock number the VID header came from @@ -188,7 +189,8 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) * information in the VID header is consistent to the information in other VID * headers of the same volume. */ -static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, +static int validate_vid_hdr(const struct ubi_device *ubi, + const struct ubi_vid_hdr *vid_hdr, const struct ubi_ainf_volume *av, int pnum) { int vol_type = vid_hdr->vol_type; @@ -206,7 +208,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, */ if (vol_id != av->vol_id) { - ubi_err("inconsistent vol_id"); + ubi_err(ubi, "inconsistent vol_id"); goto bad; } @@ -216,17 +218,17 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, av_vol_type = UBI_VID_DYNAMIC; if (vol_type != av_vol_type) { - ubi_err("inconsistent vol_type"); + ubi_err(ubi, "inconsistent vol_type"); goto bad; } if (used_ebs != av->used_ebs) { - ubi_err("inconsistent used_ebs"); + ubi_err(ubi, "inconsistent used_ebs"); goto bad; } if (data_pad != av->data_pad) { - ubi_err("inconsistent data_pad"); + ubi_err(ubi, "inconsistent data_pad"); goto bad; } } @@ -234,7 +236,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, return 0; bad: - ubi_err("inconsistent VID header at PEB %d", pnum); + ubi_err(ubi, "inconsistent VID header at PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); ubi_dump_av(av); return -EINVAL; @@ -336,7 +338,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, * support these images anymore. Well, those images still work, * but only if no unclean reboots happened. */ - ubi_err("unsupported on-flash UBI format"); + ubi_err(ubi, "unsupported on-flash UBI format"); return -EINVAL; } @@ -377,7 +379,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, if (err == UBI_IO_BITFLIPS) bitflips = 1; else { - ubi_err("VID of PEB %d header is bad, but it was OK earlier, err %d", + ubi_err(ubi, "VID of PEB %d header is bad, but it was OK earlier, err %d", pnum, err); if (err > 0) err = -EIO; @@ -507,7 +509,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * logical eraseblocks because there was an unclean reboot. */ if (aeb->sqnum == sqnum && sqnum != 0) { - ubi_err("two LEBs with same sequence number %llu", + ubi_err(ubi, "two LEBs with same sequence number %llu", sqnum); ubi_dump_aeb(aeb, 0); ubi_dump_vid_hdr(vid_hdr); @@ -527,7 +529,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * This logical eraseblock is newer than the one * found earlier. */ - err = validate_vid_hdr(vid_hdr, av, pnum); + err = validate_vid_hdr(ubi, vid_hdr, av, pnum); if (err) return err; @@ -565,7 +567,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * attaching information. */ - err = validate_vid_hdr(vid_hdr, av, pnum); + err = validate_vid_hdr(ubi, vid_hdr, av, pnum); if (err) return err; @@ -668,7 +670,8 @@ static int early_erase_peb(struct ubi_device *ubi, * Erase counter overflow. Upgrade UBI and use 64-bit * erase counters internally. */ - ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec); + ubi_err(ubi, "erase counter overflow at PEB %d, EC %d", + pnum, ec); return -EINVAL; } @@ -736,7 +739,7 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, return aeb; } - ubi_err("no free eraseblocks"); + ubi_err(ubi, "no free eraseblocks"); return ERR_PTR(-ENOSPC); } @@ -785,9 +788,9 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) goto out_unlock; - ubi_err("PEB %d contains corrupted VID header, and the data does not contain all 0xFF", + ubi_err(ubi, "PEB %d contains corrupted VID header, and the data does not contain all 0xFF", pnum); - ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); + ubi_err(ubi, "this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); ubi_dump_vid_hdr(vid_hdr); pr_err("hexdump of PEB %d offset %d, length %d", pnum, ubi->leb_start, ubi->leb_size); @@ -859,7 +862,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, bitflips = 1; break; default: - ubi_err("'ubi_io_read_ec_hdr()' returned unknown code %d", err); + ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code %d", + err); return -EINVAL; } @@ -868,7 +872,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, /* Make sure UBI version is OK */ if (ech->version != UBI_VERSION) { - ubi_err("this UBI version is %d, image version is %d", + ubi_err(ubi, "this UBI version is %d, image version is %d", UBI_VERSION, (int)ech->version); return -EINVAL; } @@ -882,7 +886,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, * flash. Upgrade UBI and use 64-bit erase counters * internally. */ - ubi_err("erase counter overflow, max is %d", + ubi_err(ubi, "erase counter overflow, max is %d", UBI_MAX_ERASECOUNTER); ubi_dump_ec_hdr(ech); return -EINVAL; @@ -903,7 +907,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (!ubi->image_seq) ubi->image_seq = image_seq; if (image_seq && ubi->image_seq != image_seq) { - ubi_err("bad image sequence number %d in PEB %d, expected %d", + ubi_err(ubi, "bad image sequence number %d in PEB %d, expected %d", image_seq, pnum, ubi->image_seq); ubi_dump_ec_hdr(ech); return -EINVAL; @@ -981,7 +985,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; goto adjust_mean_ec; default: - ubi_err("'ubi_io_read_vid_hdr()' returned unknown code %d", + ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code %d", err); return -EINVAL; } @@ -999,7 +1003,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, case UBI_COMPAT_DELETE: if (vol_id != UBI_FM_SB_VOLUME_ID && vol_id != UBI_FM_DATA_VOLUME_ID) { - ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", + ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it", vol_id, lnum); } err = add_to_list(ai, pnum, vol_id, lnum, @@ -1009,13 +1013,13 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_RO: - ubi_msg("read-only compatible internal volume %d:%d found, switch to read-only mode", + ubi_msg(ubi, "read-only compatible internal volume %d:%d found, switch to read-only mode", vol_id, lnum); ubi->ro_mode = 1; break; case UBI_COMPAT_PRESERVE: - ubi_msg("\"preserve\" compatible internal volume %d:%d found", + ubi_msg(ubi, "\"preserve\" compatible internal volume %d:%d found", vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 0, &ai->alien); @@ -1024,14 +1028,14 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_REJECT: - ubi_err("incompatible internal volume %d:%d found", + ubi_err(ubi, "incompatible internal volume %d:%d found", vol_id, lnum); return -EINVAL; } } if (ec_err) - ubi_warn("valid VID header but corrupted EC header at PEB %d", + ubi_warn(ubi, "valid VID header but corrupted EC header at PEB %d", pnum); err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); if (err) @@ -1075,7 +1079,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) * with the flash HW or driver. */ if (ai->corr_peb_count) { - ubi_err("%d PEBs are corrupted and preserved", + ubi_err(ubi, "%d PEBs are corrupted and preserved", ai->corr_peb_count); pr_err("Corrupted PEBs are:"); list_for_each_entry(aeb, &ai->corr, u.list) @@ -1087,7 +1091,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) * otherwise, only print a warning. */ if (ai->corr_peb_count >= max_corr) { - ubi_err("too many corrupted PEBs, refusing"); + ubi_err(ubi, "too many corrupted PEBs, refusing"); return -EINVAL; } } @@ -1110,11 +1114,11 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) */ if (ai->maybe_bad_peb_count <= 2) { ai->is_empty = 1; - ubi_msg("empty MTD device detected"); + ubi_msg(ubi, "empty MTD device detected"); get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); } else { - ubi_err("MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); + ubi_err(ubi, "MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); return -EINVAL; } @@ -1248,7 +1252,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, goto out_vidh; } - ubi_msg("scanning is finished"); + ubi_msg(ubi, "scanning is finished"); /* Calculate mean erase counter */ if (ai->ec_count) @@ -1515,37 +1519,37 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) vols_found += 1; if (ai->is_empty) { - ubi_err("bad is_empty flag"); + ubi_err(ubi, "bad is_empty flag"); goto bad_av; } if (av->vol_id < 0 || av->highest_lnum < 0 || av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || av->data_pad < 0 || av->last_data_size < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad_av; } if (av->vol_id >= UBI_MAX_VOLUMES && av->vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("bad vol_id"); + ubi_err(ubi, "bad vol_id"); goto bad_av; } if (av->vol_id > ai->highest_vol_id) { - ubi_err("highest_vol_id is %d, but vol_id %d is there", + ubi_err(ubi, "highest_vol_id is %d, but vol_id %d is there", ai->highest_vol_id, av->vol_id); goto out; } if (av->vol_type != UBI_DYNAMIC_VOLUME && av->vol_type != UBI_STATIC_VOLUME) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad_av; } if (av->data_pad > ubi->leb_size / 2) { - ubi_err("bad data_pad"); + ubi_err(ubi, "bad data_pad"); goto bad_av; } @@ -1557,48 +1561,48 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) leb_count += 1; if (aeb->pnum < 0 || aeb->ec < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad_aeb; } if (aeb->ec < ai->min_ec) { - ubi_err("bad ai->min_ec (%d), %d found", + ubi_err(ubi, "bad ai->min_ec (%d), %d found", ai->min_ec, aeb->ec); goto bad_aeb; } if (aeb->ec > ai->max_ec) { - ubi_err("bad ai->max_ec (%d), %d found", + ubi_err(ubi, "bad ai->max_ec (%d), %d found", ai->max_ec, aeb->ec); goto bad_aeb; } if (aeb->pnum >= ubi->peb_count) { - ubi_err("too high PEB number %d, total PEBs %d", + ubi_err(ubi, "too high PEB number %d, total PEBs %d", aeb->pnum, ubi->peb_count); goto bad_aeb; } if (av->vol_type == UBI_STATIC_VOLUME) { if (aeb->lnum >= av->used_ebs) { - ubi_err("bad lnum or used_ebs"); + ubi_err(ubi, "bad lnum or used_ebs"); goto bad_aeb; } } else { if (av->used_ebs != 0) { - ubi_err("non-zero used_ebs"); + ubi_err(ubi, "non-zero used_ebs"); goto bad_aeb; } } if (aeb->lnum > av->highest_lnum) { - ubi_err("incorrect highest_lnum or lnum"); + ubi_err(ubi, "incorrect highest_lnum or lnum"); goto bad_aeb; } } if (av->leb_count != leb_count) { - ubi_err("bad leb_count, %d objects in the tree", + ubi_err(ubi, "bad leb_count, %d objects in the tree", leb_count); goto bad_av; } @@ -1609,13 +1613,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) aeb = last_aeb; if (aeb->lnum != av->highest_lnum) { - ubi_err("bad highest_lnum"); + ubi_err(ubi, "bad highest_lnum"); goto bad_aeb; } } if (vols_found != ai->vols_found) { - ubi_err("bad ai->vols_found %d, should be %d", + ubi_err(ubi, "bad ai->vols_found %d, should be %d", ai->vols_found, vols_found); goto out; } @@ -1632,7 +1636,8 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidh, 1); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("VID header is not OK (%d)", err); + ubi_err(ubi, "VID header is not OK (%d)", + err); if (err > 0) err = -EIO; return err; @@ -1641,37 +1646,37 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; if (av->vol_type != vol_type) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad_vid_hdr; } if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { - ubi_err("bad sqnum %llu", aeb->sqnum); + ubi_err(ubi, "bad sqnum %llu", aeb->sqnum); goto bad_vid_hdr; } if (av->vol_id != be32_to_cpu(vidh->vol_id)) { - ubi_err("bad vol_id %d", av->vol_id); + ubi_err(ubi, "bad vol_id %d", av->vol_id); goto bad_vid_hdr; } if (av->compat != vidh->compat) { - ubi_err("bad compat %d", vidh->compat); + ubi_err(ubi, "bad compat %d", vidh->compat); goto bad_vid_hdr; } if (aeb->lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad lnum %d", aeb->lnum); + ubi_err(ubi, "bad lnum %d", aeb->lnum); goto bad_vid_hdr; } if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { - ubi_err("bad used_ebs %d", av->used_ebs); + ubi_err(ubi, "bad used_ebs %d", av->used_ebs); goto bad_vid_hdr; } if (av->data_pad != be32_to_cpu(vidh->data_pad)) { - ubi_err("bad data_pad %d", av->data_pad); + ubi_err(ubi, "bad data_pad %d", av->data_pad); goto bad_vid_hdr; } } @@ -1680,12 +1685,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) continue; if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad highest_lnum %d", av->highest_lnum); + ubi_err(ubi, "bad highest_lnum %d", av->highest_lnum); goto bad_vid_hdr; } if (av->last_data_size != be32_to_cpu(vidh->data_size)) { - ubi_err("bad last_data_size %d", av->last_data_size); + ubi_err(ubi, "bad last_data_size %d", + av->last_data_size); goto bad_vid_hdr; } } @@ -1726,7 +1732,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) err = 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) if (!buf[pnum]) { - ubi_err("PEB %d is not referred", pnum); + ubi_err(ubi, "PEB %d is not referred", pnum); err = 1; } @@ -1736,18 +1742,18 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) return 0; bad_aeb: - ubi_err("bad attaching information about LEB %d", aeb->lnum); + ubi_err(ubi, "bad attaching information about LEB %d", aeb->lnum); ubi_dump_aeb(aeb, 0); ubi_dump_av(av); goto out; bad_av: - ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); ubi_dump_av(av); goto out; bad_vid_hdr: - ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); ubi_dump_av(av); ubi_dump_vid_hdr(vidh); diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 8876c7d3d712..6b6bce28bd63 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -111,13 +111,13 @@ static int __init ubiblock_set_param(const char *val, len = strnlen(val, UBIBLOCK_PARAM_LEN); if (len == 0) { - ubi_warn("block: empty 'block=' parameter - ignored\n"); + pr_warn("UBI: block: empty 'block=' parameter - ignored\n"); return 0; } if (len == UBIBLOCK_PARAM_LEN) { - ubi_err("block: parameter \"%s\" is too long, max. is %d\n", - val, UBIBLOCK_PARAM_LEN); + pr_err("UBI: block: parameter \"%s\" is too long, max. is %d\n", + val, UBIBLOCK_PARAM_LEN); return -EINVAL; } @@ -188,9 +188,8 @@ static int ubiblock_read_to_buf(struct ubiblock *dev, char *buffer, ret = ubi_read(dev->desc, leb, buffer, offset, len); if (ret) { - ubi_err("%s: error %d while reading from LEB %d (offset %d, " - "length %d)", dev->gd->disk_name, ret, leb, offset, - len); + dev_err(disk_to_dev(dev->gd), "%d while reading from LEB %d (offset %d, length %d)", + ret, leb, offset, len); return ret; } return 0; @@ -328,8 +327,8 @@ static int ubiblock_open(struct block_device *bdev, fmode_t mode) dev->desc = ubi_open_volume(dev->ubi_num, dev->vol_id, UBI_READONLY); if (IS_ERR(dev->desc)) { - ubi_err("%s failed to open ubi volume %d_%d", - dev->gd->disk_name, dev->ubi_num, dev->vol_id); + dev_err(disk_to_dev(dev->gd), "failed to open ubi volume %d_%d", + dev->ubi_num, dev->vol_id); ret = PTR_ERR(dev->desc); dev->desc = NULL; goto out_unlock; @@ -405,7 +404,7 @@ int ubiblock_create(struct ubi_volume_info *vi) /* Initialize the gendisk of this ubiblock device */ gd = alloc_disk(1); if (!gd) { - ubi_err("block: alloc_disk failed"); + pr_err("UBI: block: alloc_disk failed"); ret = -ENODEV; goto out_free_dev; } @@ -421,7 +420,7 @@ int ubiblock_create(struct ubi_volume_info *vi) spin_lock_init(&dev->queue_lock); dev->rq = blk_init_queue(ubiblock_request, &dev->queue_lock); if (!dev->rq) { - ubi_err("block: blk_init_queue failed"); + dev_err(disk_to_dev(gd), "blk_init_queue failed"); ret = -ENODEV; goto out_put_disk; } @@ -446,8 +445,8 @@ int ubiblock_create(struct ubi_volume_info *vi) /* Must be the last step: anyone can call file ops from now on */ add_disk(dev->gd); - ubi_msg("%s created from ubi%d:%d(%s)", - dev->gd->disk_name, dev->ubi_num, dev->vol_id, vi->name); + dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", + dev->ubi_num, dev->vol_id, vi->name); return 0; out_free_queue: @@ -464,7 +463,7 @@ static void ubiblock_cleanup(struct ubiblock *dev) { del_gendisk(dev->gd); blk_cleanup_queue(dev->rq); - ubi_msg("%s released", dev->gd->disk_name); + dev_info(disk_to_dev(dev->gd), "released"); put_disk(dev->gd); } @@ -518,8 +517,8 @@ static int ubiblock_resize(struct ubi_volume_info *vi) } if ((sector_t)disk_capacity != disk_capacity) { mutex_unlock(&devices_mutex); - ubi_warn("%s: the volume is too big (%d LEBs), cannot resize", - dev->gd->disk_name, vi->size); + dev_warn(disk_to_dev(dev->gd), "the volume is too big (%d LEBs), cannot resize", + vi->size); return -EFBIG; } @@ -527,8 +526,8 @@ static int ubiblock_resize(struct ubi_volume_info *vi) if (get_capacity(dev->gd) != disk_capacity) { set_capacity(dev->gd, disk_capacity); - ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, - vi->used_bytes); + dev_info(disk_to_dev(dev->gd), "resized to %lld bytes", + vi->used_bytes); } mutex_unlock(&dev->dev_mutex); mutex_unlock(&devices_mutex); @@ -596,8 +595,8 @@ static int __init ubiblock_create_from_param(void) desc = open_volume_desc(p->name, p->ubi_num, p->vol_id); if (IS_ERR(desc)) { - ubi_err("block: can't open volume, err=%ld\n", - PTR_ERR(desc)); + pr_err("UBI: block: can't open volume, err=%ld\n", + PTR_ERR(desc)); ret = PTR_ERR(desc); break; } @@ -607,8 +606,8 @@ static int __init ubiblock_create_from_param(void) ret = ubiblock_create(&vi); if (ret) { - ubi_err("block: can't add '%s' volume, err=%d\n", - vi.name, ret); + pr_err("UBI: block: can't add '%s' volume, err=%d\n", + vi.name, ret); break; } } diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6e30a3c280d0..3405be46ebe9 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -166,7 +166,7 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) case UBI_VOLUME_RESIZED: case UBI_VOLUME_RENAMED: if (ubi_update_fastmap(ubi)) { - ubi_err("Unable to update fastmap!"); + ubi_err(ubi, "Unable to update fastmap!"); ubi_ro_mode(ubi); } } @@ -517,7 +517,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) */ err = alloc_chrdev_region(&dev, 0, ubi->vtbl_slots + 1, ubi->ubi_name); if (err) { - ubi_err("cannot register UBI character devices"); + ubi_err(ubi, "cannot register UBI character devices"); return err; } @@ -528,7 +528,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) err = cdev_add(&ubi->cdev, dev, 1); if (err) { - ubi_err("cannot add character device"); + ubi_err(ubi, "cannot add character device"); goto out_unreg; } @@ -540,7 +540,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) if (ubi->volumes[i]) { err = ubi_add_volume(ubi, ubi->volumes[i]); if (err) { - ubi_err("cannot add volume %d", i); + ubi_err(ubi, "cannot add volume %d", i); goto out_volumes; } } @@ -556,7 +556,8 @@ static int uif_init(struct ubi_device *ubi, int *ref) cdev_del(&ubi->cdev); out_unreg: unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); - ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); + ubi_err(ubi, "cannot initialize UBI %s, error %d", + ubi->ubi_name, err); return err; } @@ -650,7 +651,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * guess we should just pick the largest region. But this is * not implemented. */ - ubi_err("multiple regions, not implemented"); + ubi_err(ubi, "multiple regions, not implemented"); return -EINVAL; } @@ -685,7 +686,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * which allows us to avoid costly division operations. */ if (!is_power_of_2(ubi->min_io_size)) { - ubi_err("min. I/O unit (%d) is not power of 2", + ubi_err(ubi, "min. I/O unit (%d) is not power of 2", ubi->min_io_size); return -EINVAL; } @@ -702,7 +703,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) if (ubi->max_write_size < ubi->min_io_size || ubi->max_write_size % ubi->min_io_size || !is_power_of_2(ubi->max_write_size)) { - ubi_err("bad write buffer size %d for %d min. I/O unit", + ubi_err(ubi, "bad write buffer size %d for %d min. I/O unit", ubi->max_write_size, ubi->min_io_size); return -EINVAL; } @@ -739,7 +740,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { - ubi_err("unaligned VID header shift %d", + ubi_err(ubi, "unaligned VID header shift %d", ubi->vid_hdr_shift); return -EINVAL; } @@ -749,7 +750,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || ubi->leb_start & (ubi->min_io_size - 1)) { - ubi_err("bad VID header (%d) or data offsets (%d)", + ubi_err(ubi, "bad VID header (%d) or data offsets (%d)", ubi->vid_hdr_offset, ubi->leb_start); return -EINVAL; } @@ -769,14 +770,14 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * read-only mode. */ if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { - ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); + ubi_warn(ubi, "EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); ubi->ro_mode = 1; } ubi->leb_size = ubi->peb_size - ubi->leb_start; if (!(ubi->mtd->flags & MTD_WRITEABLE)) { - ubi_msg("MTD device %d is write-protected, attach in read-only mode", + ubi_msg(ubi, "MTD device %d is write-protected, attach in read-only mode", ubi->mtd->index); ubi->ro_mode = 1; } @@ -809,7 +810,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) int err, old_reserved_pebs = vol->reserved_pebs; if (ubi->ro_mode) { - ubi_warn("skip auto-resize because of R/O mode"); + ubi_warn(ubi, "skip auto-resize because of R/O mode"); return 0; } @@ -830,21 +831,22 @@ static int autoresize(struct ubi_device *ubi, int vol_id) vtbl_rec = ubi->vtbl[vol_id]; err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) - ubi_err("cannot clean auto-resize flag for volume %d", + ubi_err(ubi, "cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) - ubi_err("cannot auto-resize volume %d", vol_id); + ubi_err(ubi, "cannot auto-resize volume %d", + vol_id); } if (err) return err; - ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, - vol->name, old_reserved_pebs, vol->reserved_pebs); + ubi_msg(ubi, "volume %d (\"%s\") re-sized from %d to %d LEBs", + vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; } @@ -885,7 +887,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, for (i = 0; i < UBI_MAX_DEVICES; i++) { ubi = ubi_devices[i]; if (ubi && mtd->index == ubi->mtd->index) { - ubi_err("mtd%d is already attached to ubi%d", + ubi_err(ubi, "mtd%d is already attached to ubi%d", mtd->index, i); return -EEXIST; } @@ -900,7 +902,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, * no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type == MTD_UBIVOLUME) { - ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI", + ubi_err(ubi, "refuse attaching mtd%d - it is already emulated on top of UBI", mtd->index); return -EINVAL; } @@ -911,7 +913,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi_devices[ubi_num]) break; if (ubi_num == UBI_MAX_DEVICES) { - ubi_err("only %d UBI devices may be created", + ubi_err(ubi, "only %d UBI devices may be created", UBI_MAX_DEVICES); return -ENFILE; } @@ -921,7 +923,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, /* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { - ubi_err("ubi%d already exists", ubi_num); + ubi_err(ubi, "ubi%d already exists", ubi_num); return -EEXIST; } } @@ -953,13 +955,14 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { - ubi_err("More than %i PEBs are needed for fastmap, sorry.", + ubi_err(ubi, "More than %i PEBs are needed for fastmap, sorry.", UBI_FM_MAX_START); ubi->fm_disabled = 1; } - ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "default fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "default fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); #else ubi->fm_disabled = 1; #endif @@ -970,7 +973,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, mutex_init(&ubi->fm_mutex); init_rwsem(&ubi->fm_sem); - ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); + ubi_msg(ubi, "attaching mtd%d to ubi%d", mtd->index, ubi_num); err = io_init(ubi, max_beb_per1024); if (err) @@ -989,7 +992,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, #endif err = ubi_attach(ubi, 0); if (err) { - ubi_err("failed to attach mtd%d, error %d", mtd->index, err); + ubi_err(ubi, "failed to attach mtd%d, error %d", + mtd->index, err); goto out_free; } @@ -1010,28 +1014,28 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->bgt_thread = kthread_create(ubi_thread, ubi, "%s", ubi->bgt_name); if (IS_ERR(ubi->bgt_thread)) { err = PTR_ERR(ubi->bgt_thread); - ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, - err); + ubi_err(ubi, "cannot spawn \"%s\", error %d", + ubi->bgt_name, err); goto out_debugfs; } - ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d", - mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num); - ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes", + ubi_msg(ubi, "attached mtd%d (name \"%s\", size %llu MiB)", + mtd->index, mtd->name, ubi->flash_size >> 20); + ubi_msg(ubi, "PEB size: %d bytes (%d KiB), LEB size: %d bytes", ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size); - ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d", + ubi_msg(ubi, "min./max. I/O unit sizes: %d/%d, sub-page size %d", ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size); - ubi_msg("VID header offset: %d (aligned %d), data offset: %d", + ubi_msg(ubi, "VID header offset: %d (aligned %d), data offset: %d", ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start); - ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", + ubi_msg(ubi, "good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count); - ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d", + ubi_msg(ubi, "user volume: %d, internal volumes: %d, max. volumes count: %d", ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, ubi->vtbl_slots); - ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", + ubi_msg(ubi, "max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, ubi->image_seq); - ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", + ubi_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); /* @@ -1100,7 +1104,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) return -EBUSY; } /* This may only happen if there is a bug */ - ubi_err("%s reference count %d, destroy anyway", + ubi_err(ubi, "%s reference count %d, destroy anyway", ubi->ubi_name, ubi->ref_count); } ubi_devices[ubi_num] = NULL; @@ -1108,7 +1112,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); - ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + ubi_msg(ubi, "detaching mtd%d", ubi->mtd->index); #ifdef CONFIG_MTD_UBI_FASTMAP /* If we don't write a new fastmap at detach time we lose all * EC updates that have been made since the last written fastmap. */ @@ -1136,7 +1140,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) put_mtd_device(ubi->mtd); vfree(ubi->peb_buf); vfree(ubi->fm_buf); - ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); + ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); put_device(&ubi->dev); return 0; } @@ -1218,7 +1222,8 @@ static int __init ubi_init(void) BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); if (mtd_devs > UBI_MAX_DEVICES) { - ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES); + pr_err("UBI error: too many MTD devices, maximum is %d", + UBI_MAX_DEVICES); return -EINVAL; } @@ -1226,19 +1231,19 @@ static int __init ubi_init(void) ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); if (IS_ERR(ubi_class)) { err = PTR_ERR(ubi_class); - ubi_err("cannot create UBI class"); + pr_err("UBI error: cannot create UBI class"); goto out; } err = class_create_file(ubi_class, &ubi_version); if (err) { - ubi_err("cannot create sysfs file"); + pr_err("UBI error: cannot create sysfs file"); goto out_class; } err = misc_register(&ubi_ctrl_cdev); if (err) { - ubi_err("cannot register device"); + pr_err("UBI error: cannot register device"); goto out_version; } @@ -1265,7 +1270,8 @@ static int __init ubi_init(void) mtd = open_mtd_device(p->name); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - ubi_err("cannot open mtd %s, error %d", p->name, err); + pr_err("UBI error: cannot open mtd %s, error %d", + p->name, err); /* See comment below re-ubi_is_module(). */ if (ubi_is_module()) goto out_detach; @@ -1277,7 +1283,8 @@ static int __init ubi_init(void) p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { - ubi_err("cannot attach mtd%d", mtd->index); + pr_err("UBI error: cannot attach mtd%d", + mtd->index); put_mtd_device(mtd); /* @@ -1300,7 +1307,7 @@ static int __init ubi_init(void) err = ubiblock_init(); if (err) { - ubi_err("block: cannot initialize, error %d", err); + pr_err("UBI error: block: cannot initialize, error %d", err); /* See comment above re-ubi_is_module(). */ if (ubi_is_module()) @@ -1326,7 +1333,7 @@ static int __init ubi_init(void) out_class: class_destroy(ubi_class); out: - ubi_err("cannot initialize UBI, error %d", err); + pr_err("UBI error: cannot initialize UBI, error %d", err); return err; } late_initcall(ubi_init); @@ -1365,7 +1372,7 @@ static int __init bytes_str_to_int(const char *str) result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - ubi_err("incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1381,7 +1388,7 @@ static int __init bytes_str_to_int(const char *str) case '\0': break; default: - ubi_err("incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1408,20 +1415,20 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - ubi_err("too many parameters, max. is %d\n", - UBI_MAX_DEVICES); + pr_err("UBI error: too many parameters, max. is %d\n", + UBI_MAX_DEVICES); return -EINVAL; } len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - ubi_err("parameter \"%s\" is too long, max. is %d\n", - val, MTD_PARAM_LEN_MAX); + pr_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } if (len == 0) { - pr_warn("UBI warning: empty 'mtd=' parameter - ignored\n"); + pr_err("UBI warning: empty 'mtd=' parameter - ignored\n"); return 0; } @@ -1435,7 +1442,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) tokens[i] = strsep(&pbuf, ","); if (pbuf) { - ubi_err("too many arguments at \"%s\"\n", val); + pr_err("UBI error: too many arguments at \"%s\"\n", val); return -EINVAL; } @@ -1455,8 +1462,8 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(token, 10, &p->max_beb_per1024); if (err) { - ubi_err("bad value for max_beb_per1024 parameter: %s", - token); + pr_err("UBI error: bad value for max_beb_per1024 parameter: %s", + token); return -EINVAL; } } @@ -1466,7 +1473,8 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(token, 10, &p->ubi_num); if (err) { - ubi_err("bad value for ubi_num parameter: %s", token); + pr_err("UBI error: bad value for ubi_num parameter: %s", + token); return -EINVAL; } } else diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 59de69a24e40..3410ea8109f8 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -48,13 +48,14 @@ /** * get_exclusive - get exclusive access to an UBI volume. + * @ubi: UBI device description object * @desc: volume descriptor * * This function changes UBI volume open mode to "exclusive". Returns previous * mode value (positive integer) in case of success and a negative error code * in case of failure. */ -static int get_exclusive(struct ubi_volume_desc *desc) +static int get_exclusive(struct ubi_device *ubi, struct ubi_volume_desc *desc) { int users, err; struct ubi_volume *vol = desc->vol; @@ -63,7 +64,7 @@ static int get_exclusive(struct ubi_volume_desc *desc) users = vol->readers + vol->writers + vol->exclusive; ubi_assert(users > 0); if (users > 1) { - ubi_err("%d users for volume %d", users, vol->vol_id); + ubi_err(ubi, "%d users for volume %d", users, vol->vol_id); err = -EBUSY; } else { vol->readers = vol->writers = 0; @@ -134,7 +135,7 @@ static int vol_cdev_release(struct inode *inode, struct file *file) vol->ubi->ubi_num, vol->vol_id, desc->mode); if (vol->updating) { - ubi_warn("update of volume %d not finished, volume is damaged", + ubi_warn(vol->ubi, "update of volume %d not finished, volume is damaged", vol->vol_id); ubi_assert(!vol->changing_leb); vol->updating = 0; @@ -158,7 +159,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) if (vol->updating) { /* Update is in progress, seeking is prohibited */ - ubi_err("updating"); + ubi_err(vol->ubi, "updating"); return -EBUSY; } @@ -193,11 +194,11 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, count, *offp, vol->vol_id); if (vol->updating) { - ubi_err("updating"); + ubi_err(vol->ubi, "updating"); return -EBUSY; } if (vol->upd_marker) { - ubi_err("damaged volume, update marker is set"); + ubi_err(vol->ubi, "damaged volume, update marker is set"); return -EBADF; } if (*offp == vol->used_bytes || count == 0) @@ -277,7 +278,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); if (off & (ubi->min_io_size - 1)) { - ubi_err("unaligned position"); + ubi_err(ubi, "unaligned position"); return -EINVAL; } @@ -286,7 +287,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, /* We can write only in fractions of the minimum I/O unit */ if (count & (ubi->min_io_size - 1)) { - ubi_err("unaligned write length"); + ubi_err(ubi, "unaligned write length"); return -EINVAL; } @@ -348,7 +349,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, err = ubi_more_leb_change_data(ubi, vol, buf, count); if (err < 0) { - ubi_err("cannot accept more %zd bytes of data, error %d", + ubi_err(ubi, "cannot accept more %zd bytes of data, error %d", count, err); return err; } @@ -370,7 +371,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, return err; if (err) { - ubi_warn("volume %d on UBI device %d is corrupted", + ubi_warn(ubi, "volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } @@ -420,7 +421,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, break; } - err = get_exclusive(desc); + err = get_exclusive(ubi, desc); if (err < 0) break; @@ -456,7 +457,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, req.bytes < 0 || req.lnum >= vol->usable_leb_size) break; - err = get_exclusive(desc); + err = get_exclusive(ubi, desc); if (err < 0) break; @@ -642,7 +643,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, return 0; bad: - ubi_err("bad volume creation request"); + ubi_err(ubi, "bad volume creation request"); ubi_dump_mkvol_req(req); return err; } @@ -708,12 +709,12 @@ static int rename_volumes(struct ubi_device *ubi, for (i = 0; i < req->count - 1; i++) { for (n = i + 1; n < req->count; n++) { if (req->ents[i].vol_id == req->ents[n].vol_id) { - ubi_err("duplicated volume id %d", + ubi_err(ubi, "duplicated volume id %d", req->ents[i].vol_id); return -EINVAL; } if (!strcmp(req->ents[i].name, req->ents[n].name)) { - ubi_err("duplicated volume name \"%s\"", + ubi_err(ubi, "duplicated volume name \"%s\"", req->ents[i].name); return -EINVAL; } @@ -736,7 +737,8 @@ static int rename_volumes(struct ubi_device *ubi, re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_READWRITE); if (IS_ERR(re->desc)) { err = PTR_ERR(re->desc); - ubi_err("cannot open volume %d, error %d", vol_id, err); + ubi_err(ubi, "cannot open volume %d, error %d", + vol_id, err); kfree(re); goto out_free; } @@ -795,7 +797,7 @@ static int rename_volumes(struct ubi_device *ubi, continue; /* The volume exists but busy, or an error occurred */ - ubi_err("cannot open volume \"%s\", error %d", + ubi_err(ubi, "cannot open volume \"%s\", error %d", re->new_name, err); goto out_free; } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 63cb1d7236ce..7335c9ff9d99 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -43,12 +43,12 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) return; err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto out; } - ubi_msg("dumping %d bytes of data from PEB %d, offset %d", + ubi_msg(ubi, "dumping %d bytes of data from PEB %d, offset %d", len, pnum, offset); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); out: @@ -238,8 +238,8 @@ int ubi_debugfs_init(void) if (IS_ERR_OR_NULL(dfs_rootdir)) { int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); - ubi_err("cannot create \"ubi\" debugfs directory, error %d\n", - err); + pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n", + err); return err; } @@ -433,7 +433,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) debugfs_remove_recursive(d->dfs_dir); out: err = dent ? PTR_ERR(dent) : -ENODEV; - ubi_err("cannot create \"%s\" debugfs file or directory, error %d\n", + ubi_err(ubi, "cannot create \"%s\" debugfs file or directory, error %d\n", fname, err); return err; } diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 2402d3b50171..a40020cf0923 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -422,7 +422,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, */ if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_BAD_HDR) { - ubi_warn("corrupted VID header at PEB %d, LEB %d:%d", + ubi_warn(ubi, "corrupted VID header at PEB %d, LEB %d:%d", pnum, vol_id, lnum); err = -EBADMSG; } else @@ -448,7 +448,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, goto out_unlock; scrub = 1; if (!check) { - ubi_msg("force data checking"); + ubi_msg(ubi, "force data checking"); check = 1; goto retry; } @@ -459,7 +459,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, if (check) { uint32_t crc1 = crc32(UBI_CRC32_INIT, buf, len); if (crc1 != crc) { - ubi_warn("CRC error: calculated %#08x, must be %#08x", + ubi_warn(ubi, "CRC error: calculated %#08x, must be %#08x", crc1, crc); err = -EBADMSG; goto out_unlock; @@ -513,7 +513,8 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, return new_pnum; } - ubi_msg("recover PEB %d, move data to PEB %d", pnum, new_pnum); + ubi_msg(ubi, "recover PEB %d, move data to PEB %d", + pnum, new_pnum); err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); if (err && err != UBI_IO_BITFLIPS) { @@ -554,7 +555,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, up_read(&ubi->fm_sem); ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - ubi_msg("data was successfully recovered"); + ubi_msg(ubi, "data was successfully recovered"); return 0; out_unlock: @@ -569,13 +570,13 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, * Bad luck? This physical eraseblock is bad too? Crud. Let's try to * get another one. */ - ubi_warn("failed to write to PEB %d", new_pnum); + ubi_warn(ubi, "failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { ubi_free_vid_hdr(ubi, vid_hdr); return err; } - ubi_msg("try again"); + ubi_msg(ubi, "try again"); goto retry; } @@ -613,7 +614,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, err = ubi_io_write_data(ubi, buf, pnum, offset, len); if (err) { - ubi_warn("failed to write data to PEB %d", pnum); + ubi_warn(ubi, "failed to write data to PEB %d", pnum); if (err == -EIO && ubi->bad_allowed) err = recover_peb(ubi, pnum, vol_id, lnum, buf, offset, len); @@ -654,7 +655,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); goto write_error; } @@ -662,7 +663,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, if (len) { err = ubi_io_write_data(ubi, buf, pnum, offset, len); if (err) { - ubi_warn("failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", len, offset, vol_id, lnum, pnum); goto write_error; } @@ -698,7 +699,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -775,14 +776,14 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); goto write_error; } err = ubi_io_write_data(ubi, buf, pnum, 0, len); if (err) { - ubi_warn("failed to write %d bytes of data to PEB %d", + ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", len, pnum); goto write_error; } @@ -818,7 +819,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -893,14 +894,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); goto write_error; } err = ubi_io_write_data(ubi, buf, pnum, 0, len); if (err) { - ubi_warn("failed to write %d bytes of data to PEB %d", + ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", len, pnum); goto write_error; } @@ -940,7 +941,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -1063,7 +1064,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, dbg_wl("read %d bytes of data", aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading data from PEB %d", + ubi_warn(ubi, "error %d while reading data from PEB %d", err, from); err = MOVE_SOURCE_RD_ERR; goto out_unlock_buf; @@ -1113,7 +1114,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading VID header back from PEB %d", + ubi_warn(ubi, "error %d while reading VID header back from PEB %d", err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; @@ -1140,7 +1141,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading data back from PEB %d", + ubi_warn(ubi, "error %d while reading data back from PEB %d", err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; @@ -1152,7 +1153,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { - ubi_warn("read data back from PEB %d and it is different", + ubi_warn(ubi, "read data back from PEB %d and it is different", to); err = -EINVAL; goto out_unlock_buf; @@ -1205,10 +1206,10 @@ static void print_rsvd_warning(struct ubi_device *ubi, return; } - ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d", + ubi_warn(ubi, "cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); if (ubi->corr_peb_count) - ubi_warn("%d PEBs are corrupted and not used", + ubi_warn(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); } @@ -1286,7 +1287,7 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, fm_eba[i][j] == UBI_LEB_UNMAPPED) continue; - ubi_err("LEB:%i:%i is PEB:%i instead of %i!", + ubi_err(ubi, "LEB:%i:%i is PEB:%i instead of %i!", vol->vol_id, i, fm_eba[i][j], scan_eba[i][j]); ubi_assert(0); @@ -1366,10 +1367,10 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai) } if (ubi->avail_pebs < EBA_RESERVED_PEBS) { - ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi_err(ubi, "no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, EBA_RESERVED_PEBS); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); err = -ENOSPC; goto out_free; diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index cfd5b5e90156..b56672bf3294 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -330,7 +330,7 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (found) av = tmp_av; else { - ubi_err("orphaned volume in fastmap pool!"); + ubi_err(ubi, "orphaned volume in fastmap pool!"); kmem_cache_free(ai->aeb_slab_cache, new_aeb); return UBI_BAD_FASTMAP; } @@ -414,14 +414,14 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, pnum = be32_to_cpu(pebs[i]); if (ubi_io_is_bad(ubi, pnum)) { - ubi_err("bad PEB in fastmap pool!"); + ubi_err(ubi, "bad PEB in fastmap pool!"); ret = UBI_BAD_FASTMAP; goto out; } err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i err:%i", + ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", pnum, err); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; @@ -435,7 +435,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, image_seq = be32_to_cpu(ech->image_seq); if (image_seq && (image_seq != ubi->image_seq)) { - ubi_err("bad image seq: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad image seq: 0x%x, expected: 0x%x", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto out; @@ -493,7 +493,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, } } else { /* We are paranoid and fall back to scanning mode */ - ubi_err("fastmap pool PEBs contains damaged PEBs!"); + ubi_err(ubi, "fastmap pool PEBs contains damaged PEBs!"); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; } @@ -588,7 +588,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) { - ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC); goto fail_bad; } @@ -598,7 +598,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } @@ -608,7 +608,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (fm_pos >= fm_size) goto fail_bad; if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } @@ -619,25 +619,26 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size); if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) { - ubi_err("bad pool size: %i", pool_size); + ubi_err(ubi, "bad pool size: %i", pool_size); goto fail_bad; } if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) { - ubi_err("bad WL pool size: %i", wl_pool_size); + ubi_err(ubi, "bad WL pool size: %i", wl_pool_size); goto fail_bad; } if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_pool_size < 0) { - ubi_err("bad maximal pool size: %i", fm->max_pool_size); + ubi_err(ubi, "bad maximal pool size: %i", fm->max_pool_size); goto fail_bad; } if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_wl_pool_size < 0) { - ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size); + ubi_err(ubi, "bad maximal WL pool size: %i", + fm->max_wl_pool_size); goto fail_bad; } @@ -696,8 +697,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) { - ubi_err("bad fastmap vol header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap vol header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC); goto fail_bad; } @@ -722,8 +722,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) { - ubi_err("bad fastmap EBA header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap EBA header magic: 0x%x, expected: 0x%x", be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC); goto fail_bad; } @@ -788,7 +787,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, int err; if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) { - ubi_err("bad PEB in fastmap EBA orphan list"); + ubi_err(ubi, "bad PEB in fastmap EBA orphan list"); ret = UBI_BAD_FASTMAP; kfree(ech); goto fail; @@ -796,8 +795,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i " \ - "err:%i", tmp_aeb->pnum, err); + ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", + tmp_aeb->pnum, err); ret = err > 0 ? UBI_BAD_FASTMAP : err; kfree(ech); @@ -908,14 +907,14 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, fm->to_be_tortured[0] = 1; if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { - ubi_err("bad super block magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad super block magic: 0x%x, expected: 0x%x", be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } if (fmsb->version != UBI_FM_FMT_VERSION) { - ubi_err("bad fastmap version: %i, expected: %i", + ubi_err(ubi, "bad fastmap version: %i, expected: %i", fmsb->version, UBI_FM_FMT_VERSION); ret = UBI_BAD_FASTMAP; goto free_fm_sb; @@ -923,15 +922,16 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, used_blocks = be32_to_cpu(fmsb->used_blocks); if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { - ubi_err("number of fastmap blocks is invalid: %i", used_blocks); + ubi_err(ubi, "number of fastmap blocks is invalid: %i", + used_blocks); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } fm_size = ubi->leb_size * used_blocks; if (fm_size != ubi->fm_size) { - ubi_err("bad fastmap size: %zi, expected: %zi", fm_size, - ubi->fm_size); + ubi_err(ubi, "bad fastmap size: %zi, expected: %zi", + fm_size, ubi->fm_size); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } @@ -960,7 +960,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i EC (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i EC (PEB: %i)", i, pnum); if (ret > 0) ret = UBI_BAD_FASTMAP; @@ -977,7 +977,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, * we shouldn't fail if image_seq == 0. */ if (image_seq && (image_seq != ubi->image_seq)) { - ubi_err("wrong image seq:%d instead of %d", + ubi_err(ubi, "wrong image seq:%d instead of %d", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; @@ -985,15 +985,14 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i)", i, pnum); goto free_hdr; } if (i == 0) { if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { - ubi_err("bad fastmap anchor vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap anchor vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_SB_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -1001,8 +1000,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } } else { if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { - ubi_err("bad fastmap data vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap data vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_DATA_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -1016,7 +1014,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, ubi->leb_start, ubi->leb_size); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i, " \ + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i, " "err: %i)", i, pnum, ret); goto free_hdr; } @@ -1030,8 +1028,9 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, fmsb2->data_crc = 0; crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); if (crc != tmp_crc) { - ubi_err("fastmap data CRC is invalid"); - ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc); + ubi_err(ubi, "fastmap data CRC is invalid"); + ubi_err(ubi, "CRC should be: 0x%x, calc: 0x%x", + tmp_crc, crc); ret = UBI_BAD_FASTMAP; goto free_hdr; } @@ -1067,9 +1066,10 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ubi->fm = fm; ubi->fm_pool.max_size = ubi->fm->max_pool_size; ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; - ubi_msg("attached by fastmap"); - ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "attached by fastmap"); + ubi_msg(ubi, "fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); ubi->fm_disabled = 0; ubi_free_vid_hdr(ubi, vh); @@ -1077,7 +1077,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, out: mutex_unlock(&ubi->fm_mutex); if (ret == UBI_BAD_FASTMAP) - ubi_err("Attach by fastmap failed, doing a full scan!"); + ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); return ret; free_hdr: @@ -1273,7 +1273,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr); if (ret) { - ubi_err("unable to write vid_hdr to fastmap SB!"); + ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); goto out_kfree; } @@ -1293,7 +1293,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum)); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr); if (ret) { - ubi_err("unable to write vid_hdr to PEB %i!", + ubi_err(ubi, "unable to write vid_hdr to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1303,7 +1303,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size), new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size); if (ret) { - ubi_err("unable to write fastmap to PEB %i!", + ubi_err(ubi, "unable to write fastmap to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1450,7 +1450,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) ubi->fm = NULL; if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) { - ubi_err("fastmap too large"); + ubi_err(ubi, "fastmap too large"); ret = -ENOSPC; goto err; } @@ -1462,7 +1462,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) if (!tmp_e && !old_fm) { int j; - ubi_err("could not get any free erase block"); + ubi_err(ubi, "could not get any free erase block"); for (j = 1; j < i; j++) ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); @@ -1478,7 +1478,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); - ubi_err("could not erase old fastmap PEB"); + ubi_err(ubi, "could not erase old fastmap PEB"); goto err; } @@ -1504,7 +1504,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) ret = erase_block(ubi, old_fm->e[0]->pnum); if (ret < 0) { int i; - ubi_err("could not erase old anchor PEB"); + ubi_err(ubi, "could not erase old anchor PEB"); for (i = 1; i < new_fm->used_blocks; i++) ubi_wl_put_fm_peb(ubi, new_fm->e[i], @@ -1525,7 +1525,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) } else { if (!tmp_e) { int i; - ubi_err("could not find any anchor PEB"); + ubi_err(ubi, "could not find any anchor PEB"); for (i = 1; i < new_fm->used_blocks; i++) ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); @@ -1555,13 +1555,13 @@ int ubi_update_fastmap(struct ubi_device *ubi) err: kfree(new_fm); - ubi_warn("Unable to write new fastmap, err=%i", ret); + ubi_warn(ubi, "Unable to write new fastmap, err=%i", ret); ret = 0; if (old_fm) { ret = invalidate_fastmap(ubi, old_fm); if (ret < 0) - ubi_err("Unable to invalidiate current fastmap!"); + ubi_err(ubi, "Unable to invalidiate current fastmap!"); else if (ret) ret = 0; } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index d36134925d31..396aaa543362 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -177,19 +177,20 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, * enabled. A corresponding message will be printed * later, when it is has been scrubbed. */ - ubi_msg("fixable bit-flip detected at PEB %d", pnum); + ubi_msg(ubi, "fixable bit-flip detected at PEB %d", + pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", + ubi_warn(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; } - ubi_err("error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", err, errstr, len, pnum, offset, read); dump_stack(); @@ -246,7 +247,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -273,7 +274,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } if (ubi_dbg_is_write_failure(ubi)) { - ubi_err("cannot write %d bytes to PEB %d:%d (emulated)", + ubi_err(ubi, "cannot write %d bytes to PEB %d:%d (emulated)", len, pnum, offset); dump_stack(); return -EIO; @@ -282,7 +283,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, addr = (loff_t)pnum * ubi->peb_size + offset; err = mtd_write(ubi->mtd, addr, len, &written, buf); if (err) { - ubi_err("error %d while writing %d bytes to PEB %d:%d, written %zd bytes", + ubi_err(ubi, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes", err, len, pnum, offset, written); dump_stack(); ubi_dump_flash(ubi, pnum, offset, len); @@ -338,7 +339,7 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) ubi_assert(pnum >= 0 && pnum < ubi->peb_count); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -355,12 +356,12 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) err = mtd_erase(ubi->mtd, &ei); if (err) { if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error %d while erasing PEB %d, retry", + ubi_warn(ubi, "error %d while erasing PEB %d, retry", err, pnum); yield(); goto retry; } - ubi_err("cannot erase PEB %d, error %d", pnum, err); + ubi_err(ubi, "cannot erase PEB %d, error %d", pnum, err); dump_stack(); return err; } @@ -368,17 +369,18 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE || ei.state == MTD_ERASE_FAILED); if (err) { - ubi_err("interrupted PEB %d erasure", pnum); + ubi_err(ubi, "interrupted PEB %d erasure", pnum); return -EINTR; } if (ei.state == MTD_ERASE_FAILED) { if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error while erasing PEB %d, retry", pnum); + ubi_warn(ubi, "error while erasing PEB %d, retry", + pnum); yield(); goto retry; } - ubi_err("cannot erase PEB %d", pnum); + ubi_err(ubi, "cannot erase PEB %d", pnum); dump_stack(); return -EIO; } @@ -388,7 +390,7 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) return err; if (ubi_dbg_is_erase_failure(ubi)) { - ubi_err("cannot erase PEB %d (emulated)", pnum); + ubi_err(ubi, "cannot erase PEB %d (emulated)", pnum); return -EIO; } @@ -411,7 +413,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) { int err, i, patt_count; - ubi_msg("run torture test for PEB %d", pnum); + ubi_msg(ubi, "run torture test for PEB %d", pnum); patt_count = ARRAY_SIZE(patterns); ubi_assert(patt_count > 0); @@ -428,7 +430,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); if (err == 0) { - ubi_err("erased PEB %d, but a non-0xFF byte found", + ubi_err(ubi, "erased PEB %d, but a non-0xFF byte found", pnum); err = -EIO; goto out; @@ -448,7 +450,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) err = ubi_check_pattern(ubi->peb_buf, patterns[i], ubi->peb_size); if (err == 0) { - ubi_err("pattern %x checking failed for PEB %d", + ubi_err(ubi, "pattern %x checking failed for PEB %d", patterns[i], pnum); err = -EIO; goto out; @@ -456,7 +458,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) } err = patt_count; - ubi_msg("PEB %d passed torture test, do not mark it as bad", pnum); + ubi_msg(ubi, "PEB %d passed torture test, do not mark it as bad", pnum); out: mutex_unlock(&ubi->buf_mutex); @@ -466,7 +468,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ - ubi_err("read problems on freshly erased PEB %d, must be bad", + ubi_err(ubi, "read problems on freshly erased PEB %d, must be bad", pnum); err = -EIO; } @@ -542,7 +544,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) * it. Supposedly the flash media or the driver is screwed up, so * return an error. */ - ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err); + ubi_err(ubi, "cannot invalidate PEB %d, write returned %d", pnum, err); ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); return -EIO; } @@ -574,7 +576,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) return err; if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -616,7 +618,7 @@ int ubi_io_is_bad(const struct ubi_device *ubi, int pnum) ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size); if (ret < 0) - ubi_err("error %d while checking if PEB %d is bad", + ubi_err(ubi, "error %d while checking if PEB %d is bad", ret, pnum); else if (ret) dbg_io("PEB %d is bad", pnum); @@ -642,7 +644,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) ubi_assert(pnum >= 0 && pnum < ubi->peb_count); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -651,7 +653,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size); if (err) - ubi_err("cannot mark PEB %d bad, error %d", pnum, err); + ubi_err(ubi, "cannot mark PEB %d bad, error %d", pnum, err); return err; } @@ -674,32 +676,32 @@ static int validate_ec_hdr(const struct ubi_device *ubi, leb_start = be32_to_cpu(ec_hdr->data_offset); if (ec_hdr->version != UBI_VERSION) { - ubi_err("node with incompatible UBI version found: this UBI version is %d, image version is %d", + ubi_err(ubi, "node with incompatible UBI version found: this UBI version is %d, image version is %d", UBI_VERSION, (int)ec_hdr->version); goto bad; } if (vid_hdr_offset != ubi->vid_hdr_offset) { - ubi_err("bad VID header offset %d, expected %d", + ubi_err(ubi, "bad VID header offset %d, expected %d", vid_hdr_offset, ubi->vid_hdr_offset); goto bad; } if (leb_start != ubi->leb_start) { - ubi_err("bad data offset %d, expected %d", + ubi_err(ubi, "bad data offset %d, expected %d", leb_start, ubi->leb_start); goto bad; } if (ec < 0 || ec > UBI_MAX_ERASECOUNTER) { - ubi_err("bad erase counter %lld", ec); + ubi_err(ubi, "bad erase counter %lld", ec); goto bad; } return 0; bad: - ubi_err("bad EC header"); + ubi_err(ubi, "bad EC header"); ubi_dump_ec_hdr(ec_hdr); dump_stack(); return 1; @@ -765,7 +767,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { /* The physical eraseblock is supposedly empty */ if (verbose) - ubi_warn("no EC header found at PEB %d, only 0xFF bytes", + ubi_warn(ubi, "no EC header found at PEB %d, only 0xFF bytes", pnum); dbg_bld("no EC header found at PEB %d, only 0xFF bytes", pnum); @@ -780,7 +782,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, * 0xFF bytes. Report that the header is corrupted. */ if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", pnum, magic, UBI_EC_HDR_MAGIC); ubi_dump_ec_hdr(ec_hdr); } @@ -794,7 +796,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad EC header CRC at PEB %d, calculated %#08x, read %#08x", + ubi_warn(ubi, "bad EC header CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); ubi_dump_ec_hdr(ec_hdr); } @@ -810,7 +812,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, /* And of course validate what has just been read from the media */ err = validate_ec_hdr(ubi, ec_hdr); if (err) { - ubi_err("validation failed for PEB %d", pnum); + ubi_err(ubi, "validation failed for PEB %d", pnum); return -EINVAL; } @@ -884,40 +886,40 @@ static int validate_vid_hdr(const struct ubi_device *ubi, int usable_leb_size = ubi->leb_size - data_pad; if (copy_flag != 0 && copy_flag != 1) { - ubi_err("bad copy_flag"); + ubi_err(ubi, "bad copy_flag"); goto bad; } if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || data_pad < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad; } if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("bad vol_id"); + ubi_err(ubi, "bad vol_id"); goto bad; } if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { - ubi_err("bad compat"); + ubi_err(ubi, "bad compat"); goto bad; } if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && compat != UBI_COMPAT_REJECT) { - ubi_err("bad compat"); + ubi_err(ubi, "bad compat"); goto bad; } if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad; } if (data_pad >= ubi->leb_size / 2) { - ubi_err("bad data_pad"); + ubi_err(ubi, "bad data_pad"); goto bad; } @@ -929,45 +931,45 @@ static int validate_vid_hdr(const struct ubi_device *ubi, * mapped logical eraseblocks. */ if (used_ebs == 0) { - ubi_err("zero used_ebs"); + ubi_err(ubi, "zero used_ebs"); goto bad; } if (data_size == 0) { - ubi_err("zero data_size"); + ubi_err(ubi, "zero data_size"); goto bad; } if (lnum < used_ebs - 1) { if (data_size != usable_leb_size) { - ubi_err("bad data_size"); + ubi_err(ubi, "bad data_size"); goto bad; } } else if (lnum == used_ebs - 1) { if (data_size == 0) { - ubi_err("bad data_size at last LEB"); + ubi_err(ubi, "bad data_size at last LEB"); goto bad; } } else { - ubi_err("too high lnum"); + ubi_err(ubi, "too high lnum"); goto bad; } } else { if (copy_flag == 0) { if (data_crc != 0) { - ubi_err("non-zero data CRC"); + ubi_err(ubi, "non-zero data CRC"); goto bad; } if (data_size != 0) { - ubi_err("non-zero data_size"); + ubi_err(ubi, "non-zero data_size"); goto bad; } } else { if (data_size == 0) { - ubi_err("zero data_size of copy"); + ubi_err(ubi, "zero data_size of copy"); goto bad; } } if (used_ebs != 0) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto bad; } } @@ -975,7 +977,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, return 0; bad: - ubi_err("bad VID header"); + ubi_err(ubi, "bad VID header"); ubi_dump_vid_hdr(vid_hdr); dump_stack(); return 1; @@ -1020,7 +1022,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { if (verbose) - ubi_warn("no VID header found at PEB %d, only 0xFF bytes", + ubi_warn(ubi, "no VID header found at PEB %d, only 0xFF bytes", pnum); dbg_bld("no VID header found at PEB %d, only 0xFF bytes", pnum); @@ -1031,7 +1033,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, } if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", pnum, magic, UBI_VID_HDR_MAGIC); ubi_dump_vid_hdr(vid_hdr); } @@ -1045,7 +1047,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad CRC at PEB %d, calculated %#08x, read %#08x", + ubi_warn(ubi, "bad CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); ubi_dump_vid_hdr(vid_hdr); } @@ -1059,7 +1061,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, err = validate_vid_hdr(ubi, vid_hdr); if (err) { - ubi_err("validation failed for PEB %d", pnum); + ubi_err(ubi, "validation failed for PEB %d", pnum); return -EINVAL; } @@ -1129,7 +1131,7 @@ static int self_check_not_bad(const struct ubi_device *ubi, int pnum) if (!err) return err; - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); dump_stack(); return err > 0 ? -EINVAL : err; } @@ -1154,14 +1156,14 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, magic = be32_to_cpu(ec_hdr->magic); if (magic != UBI_EC_HDR_MAGIC) { - ubi_err("bad magic %#08x, must be %#08x", + ubi_err(ubi, "bad magic %#08x, must be %#08x", magic, UBI_EC_HDR_MAGIC); goto fail; } err = validate_ec_hdr(ubi, ec_hdr); if (err) { - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); goto fail; } @@ -1201,8 +1203,9 @@ static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); if (hdr_crc != crc) { - ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "bad CRC, calculated %#08x, read %#08x", + crc, hdr_crc); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_ec_hdr(ec_hdr); dump_stack(); err = -EINVAL; @@ -1236,21 +1239,21 @@ static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, magic = be32_to_cpu(vid_hdr->magic); if (magic != UBI_VID_HDR_MAGIC) { - ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", + ubi_err(ubi, "bad VID header magic %#08x at PEB %d, must be %#08x", magic, pnum, UBI_VID_HDR_MAGIC); goto fail; } err = validate_vid_hdr(ubi, vid_hdr); if (err) { - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); goto fail; } return err; fail: - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); return -EINVAL; @@ -1288,9 +1291,9 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); if (hdr_crc != crc) { - ubi_err("bad VID header CRC at PEB %d, calculated %#08x, read %#08x", + ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); err = -EINVAL; @@ -1329,7 +1332,7 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf1) { - ubi_err("cannot allocate memory to check writes"); + ubi_err(ubi, "cannot allocate memory to check writes"); return 0; } @@ -1345,15 +1348,15 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, if (c == c1) continue; - ubi_err("self-check failed for PEB %d:%d, len %d", + ubi_err(ubi, "self-check failed for PEB %d:%d, len %d", pnum, offset, len); - ubi_msg("data differ at position %d", i); + ubi_msg(ubi, "data differ at position %d", i); dump_len = max_t(int, 128, len - i); - ubi_msg("hex dump of the original buffer from %d to %d", + ubi_msg(ubi, "hex dump of the original buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf + i, dump_len, 1); - ubi_msg("hex dump of the read buffer from %d to %d", + ubi_msg(ubi, "hex dump of the read buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf1 + i, dump_len, 1); @@ -1393,20 +1396,20 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubi_err("cannot allocate memory to check for 0xFFs"); + ubi_err(ubi, "cannot allocate memory to check for 0xFFs"); return 0; } err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && !mtd_is_bitflip(err)) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto error; } err = ubi_check_pattern(buf, 0xFF, len); if (err == 0) { - ubi_err("flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", + ubi_err(ubi, "flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", pnum, offset, len); goto fail; } @@ -1415,8 +1418,9 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) return 0; fail: - ubi_err("self-check failed for PEB %d", pnum); - ubi_msg("hex dump of the %d-%d region", offset, offset + len); + ubi_err(ubi, "self-check failed for PEB %d", pnum); + ubi_msg(ubi, "hex dump of the %d-%d region", + offset, offset + len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); err = -EINVAL; error: diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 3aac1acceeb4..f3bab669f6bb 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -204,7 +204,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) return ERR_PTR(err); } if (err == 1) { - ubi_warn("volume %d on UBI device %d is corrupted", + ubi_warn(ubi, "volume %d on UBI device %d is corrupted", vol_id, ubi->ubi_num); vol->corrupted = 1; } @@ -221,7 +221,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) kfree(desc); out_put_ubi: ubi_put_device(ubi); - ubi_err("cannot open device %d, volume %d, error %d", + ubi_err(ubi, "cannot open device %d, volume %d, error %d", ubi_num, vol_id, err); return ERR_PTR(err); } @@ -411,7 +411,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check); if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) { - ubi_warn("mark volume %d as corrupted", vol_id); + ubi_warn(ubi, "mark volume %d as corrupted", vol_id); vol->corrupted = 1; } diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index f913d701a5b3..dbda77e556cb 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -111,7 +111,7 @@ void ubi_update_reserved(struct ubi_device *ubi) ubi->avail_pebs -= need; ubi->rsvd_pebs += need; ubi->beb_rsvd_pebs += need; - ubi_msg("reserved more %d PEBs for bad PEB handling", need); + ubi_msg(ubi, "reserved more %d PEBs for bad PEB handling", need); } /** @@ -128,7 +128,7 @@ void ubi_calculate_reserved(struct ubi_device *ubi) ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count; if (ubi->beb_rsvd_level < 0) { ubi->beb_rsvd_level = 0; - ubi_warn("number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)", + ubi_warn(ubi, "number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)", ubi->bad_peb_count, ubi->bad_peb_limit); } } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 320fc38fa2a1..f80ffaba9058 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -50,13 +50,14 @@ #define UBI_NAME_STR "ubi" /* Normal UBI messages */ -#define ubi_msg(fmt, ...) pr_notice("UBI: " fmt "\n", ##__VA_ARGS__) +#define ubi_msg(ubi, fmt, ...) pr_notice("UBI-%d: %s:" fmt "\n", \ + ubi->ubi_num, __func__, ##__VA_ARGS__) /* UBI warning messages */ -#define ubi_warn(fmt, ...) pr_warn("UBI warning: %s: " fmt "\n", \ - __func__, ##__VA_ARGS__) +#define ubi_warn(ubi, fmt, ...) pr_warn("UBI-%d warning: %s: " fmt "\n", \ + ubi->ubi_num, __func__, ##__VA_ARGS__) /* UBI error messages */ -#define ubi_err(fmt, ...) pr_err("UBI error: %s: " fmt "\n", \ - __func__, ##__VA_ARGS__) +#define ubi_err(ubi, fmt, ...) pr_err("UBI-%d error: %s: " fmt "\n", \ + ubi->ubi_num, __func__, ##__VA_ARGS__) /* Background thread name pattern */ #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" @@ -987,7 +988,7 @@ static inline void ubi_ro_mode(struct ubi_device *ubi) { if (!ubi->ro_mode) { ubi->ro_mode = 1; - ubi_warn("switch to read-only mode"); + ubi_warn(ubi, "switch to read-only mode"); dump_stack(); } } diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 8330703c098f..ff4d97848d1c 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -223,7 +223,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) } if (vol_id == UBI_VOL_NUM_AUTO) { - ubi_err("out of volume IDs"); + ubi_err(ubi, "out of volume IDs"); err = -ENFILE; goto out_unlock; } @@ -237,7 +237,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Ensure that this volume does not exist */ err = -EEXIST; if (ubi->volumes[vol_id]) { - ubi_err("volume %d already exists", vol_id); + ubi_err(ubi, "volume %d already exists", vol_id); goto out_unlock; } @@ -246,7 +246,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (ubi->volumes[i] && ubi->volumes[i]->name_len == req->name_len && !strcmp(ubi->volumes[i]->name, req->name)) { - ubi_err("volume \"%s\" exists (ID %d)", req->name, i); + ubi_err(ubi, "volume \"%s\" exists (ID %d)", + req->name, i); goto out_unlock; } @@ -257,9 +258,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Reserve physical eraseblocks */ if (vol->reserved_pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs, only %d available", ubi->avail_pebs); + ubi_err(ubi, "not enough PEBs, only %d available", + ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); err = -ENOSPC; goto out_unlock; @@ -314,7 +316,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) dev = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1); err = cdev_add(&vol->cdev, dev, 1); if (err) { - ubi_err("cannot add character device"); + ubi_err(ubi, "cannot add character device"); goto out_mapping; } @@ -326,7 +328,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); err = device_register(&vol->dev); if (err) { - ubi_err("cannot register device"); + ubi_err(ubi, "cannot register device"); goto out_cdev; } @@ -386,7 +388,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) kfree(vol); else put_device(&vol->dev); - ubi_err("cannot create volume %d, error %d", vol_id, err); + ubi_err(ubi, "cannot create volume %d, error %d", vol_id, err); return err; } @@ -454,7 +456,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) return err; out_err: - ubi_err("cannot remove volume %d, error %d", vol_id, err); + ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err); spin_lock(&ubi->volumes_lock); ubi->volumes[vol_id] = vol; out_unlock: @@ -487,7 +489,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (vol->vol_type == UBI_STATIC_VOLUME && reserved_pebs < vol->used_ebs) { - ubi_err("too small size %d, %d LEBs contain data", + ubi_err(ubi, "too small size %d, %d LEBs contain data", reserved_pebs, vol->used_ebs); return -EINVAL; } @@ -516,10 +518,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (pebs > 0) { spin_lock(&ubi->volumes_lock); if (pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs: requested %d, available %d", + ubi_err(ubi, "not enough PEBs: requested %d, available %d", pebs, ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); spin_unlock(&ubi->volumes_lock); err = -ENOSPC; @@ -643,7 +645,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) dev = MKDEV(MAJOR(ubi->cdev.dev), vol->vol_id + 1); err = cdev_add(&vol->cdev, dev, 1); if (err) { - ubi_err("cannot add character device for volume %d, error %d", + ubi_err(ubi, "cannot add character device for volume %d, error %d", vol_id, err); return err; } @@ -710,7 +712,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (!vol) { if (reserved_pebs) { - ubi_err("no volume info, but volume exists"); + ubi_err(ubi, "no volume info, but volume exists"); goto fail; } spin_unlock(&ubi->volumes_lock); @@ -719,90 +721,91 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 || vol->name_len < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto fail; } if (vol->alignment > ubi->leb_size || vol->alignment == 0) { - ubi_err("bad alignment"); + ubi_err(ubi, "bad alignment"); goto fail; } n = vol->alignment & (ubi->min_io_size - 1); if (vol->alignment != 1 && n) { - ubi_err("alignment is not multiple of min I/O unit"); + ubi_err(ubi, "alignment is not multiple of min I/O unit"); goto fail; } n = ubi->leb_size % vol->alignment; if (vol->data_pad != n) { - ubi_err("bad data_pad, has to be %lld", n); + ubi_err(ubi, "bad data_pad, has to be %lld", n); goto fail; } if (vol->vol_type != UBI_DYNAMIC_VOLUME && vol->vol_type != UBI_STATIC_VOLUME) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto fail; } if (vol->upd_marker && vol->corrupted) { - ubi_err("update marker and corrupted simultaneously"); + ubi_err(ubi, "update marker and corrupted simultaneously"); goto fail; } if (vol->reserved_pebs > ubi->good_peb_count) { - ubi_err("too large reserved_pebs"); + ubi_err(ubi, "too large reserved_pebs"); goto fail; } n = ubi->leb_size - vol->data_pad; if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) { - ubi_err("bad usable_leb_size, has to be %lld", n); + ubi_err(ubi, "bad usable_leb_size, has to be %lld", n); goto fail; } if (vol->name_len > UBI_VOL_NAME_MAX) { - ubi_err("too long volume name, max is %d", UBI_VOL_NAME_MAX); + ubi_err(ubi, "too long volume name, max is %d", + UBI_VOL_NAME_MAX); goto fail; } n = strnlen(vol->name, vol->name_len + 1); if (n != vol->name_len) { - ubi_err("bad name_len %lld", n); + ubi_err(ubi, "bad name_len %lld", n); goto fail; } n = (long long)vol->used_ebs * vol->usable_leb_size; if (vol->vol_type == UBI_DYNAMIC_VOLUME) { if (vol->corrupted) { - ubi_err("corrupted dynamic volume"); + ubi_err(ubi, "corrupted dynamic volume"); goto fail; } if (vol->used_ebs != vol->reserved_pebs) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes != vol->usable_leb_size) { - ubi_err("bad last_eb_bytes"); + ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes != n) { - ubi_err("bad used_bytes"); + ubi_err(ubi, "bad used_bytes"); goto fail; } } else { if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes < 0 || vol->last_eb_bytes > vol->usable_leb_size) { - ubi_err("bad last_eb_bytes"); + ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes < 0 || vol->used_bytes > n || vol->used_bytes < n - vol->usable_leb_size) { - ubi_err("bad used_bytes"); + ubi_err(ubi, "bad used_bytes"); goto fail; } } @@ -820,7 +823,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (alignment != vol->alignment || data_pad != vol->data_pad || upd_marker != vol->upd_marker || vol_type != vol->vol_type || name_len != vol->name_len || strncmp(name, vol->name, name_len)) { - ubi_err("volume info is different"); + ubi_err(ubi, "volume info is different"); goto fail; } @@ -828,7 +831,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) return 0; fail: - ubi_err("self-check failed for volume %d", vol_id); + ubi_err(ubi, "self-check failed for volume %d", vol_id); if (vol) ubi_dump_vol_info(vol); ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 07cac5f9ffb8..1931dffe87b0 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -190,7 +190,7 @@ static int vtbl_check(const struct ubi_device *ubi, crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); if (be32_to_cpu(vtbl[i].crc) != crc) { - ubi_err("bad CRC at record %u: %#08x, not %#08x", + ubi_err(ubi, "bad CRC at record %u: %#08x, not %#08x", i, crc, be32_to_cpu(vtbl[i].crc)); ubi_dump_vtbl_record(&vtbl[i], i); return 1; @@ -224,7 +224,7 @@ static int vtbl_check(const struct ubi_device *ubi, n = ubi->leb_size % alignment; if (data_pad != n) { - ubi_err("bad data_pad, has to be %d", n); + ubi_err(ubi, "bad data_pad, has to be %d", n); err = 6; goto bad; } @@ -240,7 +240,7 @@ static int vtbl_check(const struct ubi_device *ubi, } if (reserved_pebs > ubi->good_peb_count) { - ubi_err("too large reserved_pebs %d, good PEBs %d", + ubi_err(ubi, "too large reserved_pebs %d, good PEBs %d", reserved_pebs, ubi->good_peb_count); err = 9; goto bad; @@ -270,7 +270,7 @@ static int vtbl_check(const struct ubi_device *ubi, if (len1 > 0 && len1 == len2 && !strncmp(vtbl[i].name, vtbl[n].name, len1)) { - ubi_err("volumes %d and %d have the same name \"%s\"", + ubi_err(ubi, "volumes %d and %d have the same name \"%s\"", i, n, vtbl[i].name); ubi_dump_vtbl_record(&vtbl[i], i); ubi_dump_vtbl_record(&vtbl[n], n); @@ -282,7 +282,7 @@ static int vtbl_check(const struct ubi_device *ubi, return 0; bad: - ubi_err("volume table check failed: record %d, error %d", i, err); + ubi_err(ubi, "volume table check failed: record %d, error %d", i, err); ubi_dump_vtbl_record(&vtbl[i], i); return -EINVAL; } @@ -446,11 +446,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, leb_corrupted[1] = memcmp(leb[0], leb[1], ubi->vtbl_size); if (leb_corrupted[1]) { - ubi_warn("volume table copy #2 is corrupted"); + ubi_warn(ubi, "volume table copy #2 is corrupted"); err = create_vtbl(ubi, ai, 1, leb[0]); if (err) goto out_free; - ubi_msg("volume table was restored"); + ubi_msg(ubi, "volume table was restored"); } /* Both LEB 1 and LEB 2 are OK and consistent */ @@ -465,15 +465,15 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, } if (leb_corrupted[1]) { /* Both LEB 0 and LEB 1 are corrupted */ - ubi_err("both volume tables are corrupted"); + ubi_err(ubi, "both volume tables are corrupted"); goto out_free; } - ubi_warn("volume table copy #1 is corrupted"); + ubi_warn(ubi, "volume table copy #1 is corrupted"); err = create_vtbl(ubi, ai, 0, leb[1]); if (err) goto out_free; - ubi_msg("volume table was restored"); + ubi_msg(ubi, "volume table was restored"); vfree(leb[0]); return leb[1]; @@ -562,7 +562,7 @@ static int init_volumes(struct ubi_device *ubi, if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) { /* Auto re-size flag may be set only for one volume */ if (ubi->autoresize_vol_id != -1) { - ubi_err("more than one auto-resize volume (%d and %d)", + ubi_err(ubi, "more than one auto-resize volume (%d and %d)", ubi->autoresize_vol_id, i); kfree(vol); return -EINVAL; @@ -608,7 +608,7 @@ static int init_volumes(struct ubi_device *ubi, * We found a static volume which misses several * eraseblocks. Treat it as corrupted. */ - ubi_warn("static volume %d misses %d LEBs - corrupted", + ubi_warn(ubi, "static volume %d misses %d LEBs - corrupted", av->vol_id, av->used_ebs - av->leb_count); vol->corrupted = 1; continue; @@ -646,10 +646,10 @@ static int init_volumes(struct ubi_device *ubi, vol->ubi = ubi; if (reserved_pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs, required %d, available %d", + ubi_err(ubi, "not enough PEBs, required %d, available %d", reserved_pebs, ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); } ubi->rsvd_pebs += reserved_pebs; @@ -660,13 +660,14 @@ static int init_volumes(struct ubi_device *ubi, /** * check_av - check volume attaching information. + * @ubi: UBI device description object * @vol: UBI volume description object * @av: volume attaching information * * This function returns zero if the volume attaching information is consistent * to the data read from the volume tabla, and %-EINVAL if not. */ -static int check_av(const struct ubi_volume *vol, +static int check_av(const struct ubi_device *ubi, const struct ubi_volume *vol, const struct ubi_ainf_volume *av) { int err; @@ -694,7 +695,7 @@ static int check_av(const struct ubi_volume *vol, return 0; bad: - ubi_err("bad attaching information, error %d", err); + ubi_err(ubi, "bad attaching information, error %d", err); ubi_dump_av(av); ubi_dump_vol_info(vol); return -EINVAL; @@ -718,14 +719,15 @@ static int check_attaching_info(const struct ubi_device *ubi, struct ubi_volume *vol; if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { - ubi_err("found %d volumes while attaching, maximum is %d + %d", + ubi_err(ubi, "found %d volumes while attaching, maximum is %d + %d", ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); return -EINVAL; } if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && ai->highest_vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("too large volume ID %d found", ai->highest_vol_id); + ubi_err(ubi, "too large volume ID %d found", + ai->highest_vol_id); return -EINVAL; } @@ -753,10 +755,10 @@ static int check_attaching_info(const struct ubi_device *ubi, * reboot while the volume was being removed. Discard * these eraseblocks. */ - ubi_msg("finish volume %d removal", av->vol_id); + ubi_msg(ubi, "finish volume %d removal", av->vol_id); ubi_remove_av(ai, av); } else if (av) { - err = check_av(vol, av); + err = check_av(ubi, vol, av); if (err) return err; } @@ -807,13 +809,13 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) if (IS_ERR(ubi->vtbl)) return PTR_ERR(ubi->vtbl); } else { - ubi_err("the layout volume was not found"); + ubi_err(ubi, "the layout volume was not found"); return -EINVAL; } } else { if (av->leb_count > UBI_LAYOUT_VOLUME_EBS) { /* This must not happen with proper UBI images */ - ubi_err("too many LEBs (%d) in layout volume", + ubi_err(ubi, "too many LEBs (%d) in layout volume", av->leb_count); return -EINVAL; } @@ -862,7 +864,7 @@ static void self_vtbl_check(const struct ubi_device *ubi) return; if (vtbl_check(ubi, ubi->vtbl)) { - ubi_err("self-check failed"); + ubi_err(ubi, "self-check failed"); BUG(); } } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 6654f191868e..7d2a25f96804 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -253,7 +253,7 @@ static int do_work(struct ubi_device *ubi) */ err = wrk->func(ubi, wrk, 0); if (err) - ubi_err("work failed with error code %d", err); + ubi_err(ubi, "work failed with error code %d", err); up_read(&ubi->work_sem); return err; @@ -470,8 +470,11 @@ struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) { struct ubi_wl_entry *e = NULL; - if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1)) + if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1)) { + ubi_warn(ubi, "Can't get peb for fastmap:anchor=%d, free_cnt=%d, reserved=%d", + anchor, ubi->free_count, ubi->beb_rsvd_pebs); goto out; + } if (anchor) e = find_anchor_wl_entry(&ubi->free); @@ -507,7 +510,7 @@ static int __wl_get_peb(struct ubi_device *ubi) retry: if (!ubi->free.rb_node) { if (ubi->works_count == 0) { - ubi_err("no free eraseblocks"); + ubi_err(ubi, "no free eraseblocks"); ubi_assert(list_empty(&ubi->works)); return -ENOSPC; } @@ -520,7 +523,7 @@ static int __wl_get_peb(struct ubi_device *ubi) e = find_mean_wl_entry(ubi, &ubi->free); if (!e) { - ubi_err("no free eraseblocks"); + ubi_err(ubi, "no free eraseblocks"); return -ENOSPC; } @@ -692,7 +695,8 @@ int ubi_wl_get_peb(struct ubi_device *ubi) err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, ubi->peb_size - ubi->vid_hdr_aloffset); if (err) { - ubi_err("new PEB %d does not contain all 0xFF bytes", peb); + ubi_err(ubi, "new PEB %d does not contain all 0xFF bytes", + peb); return err; } @@ -760,7 +764,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, * Erase counter overflow. Upgrade UBI and use 64-bit * erase counters internally. */ - ubi_err("erase counter overflow at PEB %d, EC %llu", + ubi_err(ubi, "erase counter overflow at PEB %d, EC %llu", e->pnum, ec); err = -EINVAL; goto out_free; @@ -1137,7 +1141,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_not_moved; } - ubi_err("error %d while reading VID header from PEB %d", + ubi_err(ubi, "error %d while reading VID header from PEB %d", err, e1->pnum); goto out_error; } @@ -1181,7 +1185,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, * UBI from trying to move it over and over again. */ if (ubi->erroneous_peb_count > ubi->max_erroneous) { - ubi_err("too many erroneous eraseblocks (%d)", + ubi_err(ubi, "too many erroneous eraseblocks (%d)", ubi->erroneous_peb_count); goto out_error; } @@ -1197,7 +1201,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, /* The PEB has been successfully moved */ if (scrubbing) - ubi_msg("scrubbed PEB %d (LEB %d:%d), data moved to PEB %d", + ubi_msg(ubi, "scrubbed PEB %d (LEB %d:%d), data moved to PEB %d", e1->pnum, vol_id, lnum, e2->pnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -1274,10 +1278,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, out_error: if (vol_id != -1) - ubi_err("error %d while moving PEB %d to PEB %d", + ubi_err(ubi, "error %d while moving PEB %d to PEB %d", err, e1->pnum, e2->pnum); else - ubi_err("error %d while moving PEB %d (LEB %d:%d) to PEB %d", + ubi_err(ubi, "error %d while moving PEB %d (LEB %d:%d) to PEB %d", err, e1->pnum, vol_id, lnum, e2->pnum); spin_lock(&ubi->wl_lock); ubi->move_from = ubi->move_to = NULL; @@ -1458,7 +1462,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, return err; } - ubi_err("failed to erase PEB %d, error %d", pnum, err); + ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || @@ -1486,7 +1490,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, /* It is %-EIO, the PEB went bad */ if (!ubi->bad_allowed) { - ubi_err("bad physical eraseblock %d detected", pnum); + ubi_err(ubi, "bad physical eraseblock %d detected", pnum); goto out_ro; } @@ -1494,7 +1498,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, if (ubi->beb_rsvd_pebs == 0) { if (ubi->avail_pebs == 0) { spin_unlock(&ubi->volumes_lock); - ubi_err("no reserved/available physical eraseblocks"); + ubi_err(ubi, "no reserved/available physical eraseblocks"); goto out_ro; } ubi->avail_pebs -= 1; @@ -1502,7 +1506,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, } spin_unlock(&ubi->volumes_lock); - ubi_msg("mark PEB %d as bad", pnum); + ubi_msg(ubi, "mark PEB %d as bad", pnum); err = ubi_io_mark_bad(ubi, pnum); if (err) goto out_ro; @@ -1523,11 +1527,12 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, ubi->good_peb_count -= 1; ubi_calculate_reserved(ubi); if (available_consumed) - ubi_warn("no PEBs in the reserved pool, used an available PEB"); + ubi_warn(ubi, "no PEBs in the reserved pool, used an available PEB"); else if (ubi->beb_rsvd_pebs) - ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); + ubi_msg(ubi, "%d PEBs left in the reserve", + ubi->beb_rsvd_pebs); else - ubi_warn("last PEB from the reserve was used"); + ubi_warn(ubi, "last PEB from the reserve was used"); spin_unlock(&ubi->volumes_lock); return err; @@ -1613,7 +1618,7 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, } else { err = prot_queue_del(ubi, e->pnum); if (err) { - ubi_err("PEB %d not found", pnum); + ubi_err(ubi, "PEB %d not found", pnum); ubi_ro_mode(ubi); spin_unlock(&ubi->wl_lock); return err; @@ -1646,7 +1651,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) { struct ubi_wl_entry *e; - ubi_msg("schedule PEB %d for scrubbing", pnum); + ubi_msg(ubi, "schedule PEB %d for scrubbing", pnum); retry: spin_lock(&ubi->wl_lock); @@ -1678,7 +1683,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) err = prot_queue_del(ubi, e->pnum); if (err) { - ubi_err("PEB %d not found", pnum); + ubi_err(ubi, "PEB %d not found", pnum); ubi_ro_mode(ubi); spin_unlock(&ubi->wl_lock); return err; @@ -1798,15 +1803,18 @@ int ubi_thread(void *u) int failures = 0; struct ubi_device *ubi = u; - ubi_msg("background thread \"%s\" started, PID %d", + ubi_msg(ubi, "background thread \"%s\" started, PID %d", ubi->bgt_name, task_pid_nr(current)); set_freezable(); for (;;) { int err; - if (kthread_should_stop()) + if (kthread_should_stop()) { + ubi_msg(ubi, "background thread \"%s\" should stop, PID %d", + ubi->bgt_name, task_pid_nr(current)); break; + } if (try_to_freeze()) continue; @@ -1823,14 +1831,14 @@ int ubi_thread(void *u) err = do_work(ubi); if (err) { - ubi_err("%s: work failed with error code %d", + ubi_err(ubi, "%s: work failed with error code %d", ubi->bgt_name, err); if (failures++ > WL_MAX_FAILURES) { /* * Too many failures, disable the thread and * switch to read-only mode. */ - ubi_msg("%s: %d consecutive failures", + ubi_msg(ubi, "%s: %d consecutive failures", ubi->bgt_name, WL_MAX_FAILURES); ubi_ro_mode(ubi); ubi->thread_enabled = 0; @@ -1981,10 +1989,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) #endif if (ubi->avail_pebs < reserved_pebs) { - ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi_err(ubi, "no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, reserved_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); goto out_free; } @@ -2072,8 +2080,8 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) read_ec = be64_to_cpu(ec_hdr->ec); if (ec != read_ec && read_ec - ec > 1) { - ubi_err("self-check failed for PEB %d", pnum); - ubi_err("read EC is %lld, should be %d", read_ec, ec); + ubi_err(ubi, "self-check failed for PEB %d", pnum); + ubi_err(ubi, "read EC is %lld, should be %d", read_ec, ec); dump_stack(); err = 1; } else @@ -2102,7 +2110,7 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, if (in_wl_tree(e, root)) return 0; - ubi_err("self-check failed for PEB %d, EC %d, RB-tree %p ", + ubi_err(ubi, "self-check failed for PEB %d, EC %d, RB-tree %p ", e->pnum, e->ec, root); dump_stack(); return -EINVAL; @@ -2130,7 +2138,7 @@ static int self_check_in_pq(const struct ubi_device *ubi, if (p == e) return 0; - ubi_err("self-check failed for PEB %d, EC %d, Protect queue", + ubi_err(ubi, "self-check failed for PEB %d, EC %d, Protect queue", e->pnum, e->ec); dump_stack(); return -EINVAL; -- GitLab From b81000b69ae99fdd77246e22ebf762a5dd008c1e Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 25 Oct 2014 19:43:41 +0200 Subject: [PATCH 3602/9457] UBI: vtbl: Use ubi_eba_atomic_leb_change() This is more a cosmetic change than a fix. By using ubi_eba_atomic_leb_change() we can guarantee that the first VTBL record is always correct and we don't really need the second one anymore. But we have to keep the second one to not break anything. Artem: add a comment Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/vtbl.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 1931dffe87b0..f8fc3081bbb4 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -30,9 +30,12 @@ * eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each * other. This redundancy guarantees robustness to unclean reboots. The volume * table is basically an array of volume table records. Each record contains - * full information about the volume and protected by a CRC checksum. + * full information about the volume and protected by a CRC checksum. Note, + * nowadays we use the atomic LEB change operation when updating the volume + * table, so we do not really need 2 LEBs anymore, but we preserve the older + * design for the backward compatibility reasons. * - * The volume table is changed, it is first changed in RAM. Then LEB 0 is + * When the volume table is changed, it is first changed in RAM. Then LEB 0 is * erased, and the updated volume table is written back to LEB 0. Then same for * LEB 1. This scheme guarantees recoverability from unclean reboots. * @@ -96,12 +99,8 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { - err = ubi_eba_unmap_leb(ubi, layout_vol, i); - if (err) - return err; - - err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size); + err = ubi_eba_atomic_leb_change(ubi, layout_vol, i, ubi->vtbl, + ubi->vtbl_size); if (err) return err; } @@ -148,12 +147,8 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi, layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { - err = ubi_eba_unmap_leb(ubi, layout_vol, i); - if (err) - return err; - - err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size); + err = ubi_eba_atomic_leb_change(ubi, layout_vol, i, ubi->vtbl, + ubi->vtbl_size); if (err) return err; } -- GitLab From 1365039d0cb32c0cf96eb9f750f4277c9a90f87d Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 4 Nov 2014 08:31:16 +0100 Subject: [PATCH 3603/9457] KVM: s390: Fix ipte locking ipte_unlock_siif uses cmpxchg to replace the in-memory data of the ipte lock together with ACCESS_ONCE for the intial read. union ipte_control { unsigned long val; struct { unsigned long k : 1; unsigned long kh : 31; unsigned long kg : 32; }; }; [...] static void ipte_unlock_siif(struct kvm_vcpu *vcpu) { union ipte_control old, new, *ic; ic = &vcpu->kvm->arch.sca->ipte_control; do { new = old = ACCESS_ONCE(*ic); new.kh--; if (!new.kh) new.k = 0; } while (cmpxchg(&ic->val, old.val, new.val) != old.val); if (!new.kh) wake_up(&vcpu->kvm->arch.ipte_wq); } The new value, is loaded twice from memory with gcc 4.7.2 of fedora 18, despite the ACCESS_ONCE: ---> l %r4,0(%r3) <--- load first 32 bit of lock (k and kh) in r4 alfi %r4,2147483647 <--- add -1 to r4 llgtr %r4,%r4 <--- zero out the sign bit of r4 lg %r1,0(%r3) <--- load all 64 bit of lock into new lgr %r2,%r1 <--- load the same into old risbg %r1,%r4,1,31,32 <--- shift and insert r4 into the bits 1-31 of new llihf %r4,2147483647 ngrk %r4,%r1,%r4 jne aa0 nihh %r1,32767 lgr %r4,%r2 csg %r4,%r1,0(%r3) cgr %r2,%r4 jne a70 If the memory value changes between the first load (l) and the second load (lg) we are broken. If that happens VCPU threads will hang (unkillable) in handle_ipte_interlock. Andreas Krebbel analyzed this and tracked it down to a compiler bug in that version: "while it is not that obvious the C99 standard basically forbids duplicating the memory access also in that case. For an argumentation of a similiar case please see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22278#c43 For the implementation-defined cases regarding volatile there are some GCC-specific clarifications which can be found here: https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html#Volatiles I've tracked down the problem with a reduced testcase. The problem was that during a tree level optimization (SRA - scalar replacement of aggregates) the volatile marker is lost. And an RTL level optimizer (CSE - common subexpression elimination) then propagated the memory read into its second use introducing another access to the memory location. So indeed Christian's suspicion that the union access has something to do with it is correct (since it triggered the SRA optimization). This issue has been reported and fixed in the GCC 4.8 development cycle: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145" This patch replaces the ACCESS_ONCE scheme with a barrier() based scheme that should work for all supported compilers. Signed-off-by: Christian Borntraeger Cc: stable@vger.kernel.org # v3.16+ --- arch/s390/kvm/gaccess.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 0f961a1c64b3..6dc0ad9c7050 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -229,10 +229,12 @@ static void ipte_lock_simple(struct kvm_vcpu *vcpu) goto out; ic = &vcpu->kvm->arch.sca->ipte_control; do { - old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); while (old.k) { cond_resched(); - old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); } new = old; new.k = 1; @@ -251,7 +253,9 @@ static void ipte_unlock_simple(struct kvm_vcpu *vcpu) goto out; ic = &vcpu->kvm->arch.sca->ipte_control; do { - new = old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); + new = old; new.k = 0; } while (cmpxchg(&ic->val, old.val, new.val) != old.val); wake_up(&vcpu->kvm->arch.ipte_wq); @@ -265,10 +269,12 @@ static void ipte_lock_siif(struct kvm_vcpu *vcpu) ic = &vcpu->kvm->arch.sca->ipte_control; do { - old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); while (old.kg) { cond_resched(); - old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); } new = old; new.k = 1; @@ -282,7 +288,9 @@ static void ipte_unlock_siif(struct kvm_vcpu *vcpu) ic = &vcpu->kvm->arch.sca->ipte_control; do { - new = old = ACCESS_ONCE(*ic); + old = *ic; + barrier(); + new = old; new.kh--; if (!new.kh) new.k = 0; -- GitLab From 2dca485f8740208604543c3960be31a5dd3ea603 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 31 Oct 2014 09:24:20 +0100 Subject: [PATCH 3604/9457] KVM: s390: flush CPU on load control some control register changes will flush some aspects of the CPU, e.g. POP explicitely mentions that for CR9-CR11 "TLBs may be cleared". Instead of trying to be clever and only flush on specific CRs, let play safe and flush on all lctl(g) as future machines might define new bits in CRs. Load control intercept should not happen that often. Signed-off-by: Christian Borntraeger Acked-by: Cornelia Huck Reviewed-by: David Hildenbrand Cc: stable@vger.kernel.org --- arch/s390/kvm/priv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 72bb2dd8b9cd..9c565b6b4ccb 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -791,7 +791,7 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) break; reg = (reg + 1) % 16; } while (1); - + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); return 0; } @@ -863,7 +863,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) break; reg = (reg + 1) % 16; } while (1); - + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); return 0; } -- GitLab From fc56eb66c348febef6c7bbd2c3918410cafd6313 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 29 Oct 2014 10:07:16 +0100 Subject: [PATCH 3605/9457] KVM: s390: fix handling of lctl[g]/stctl[g] According to the architecture all instructions are suppressing if memory access is prohibited due to DAT protection, unless stated otherwise for an instruction. The lctl[g]/stctl[g] implementations handled this incorrectly since control register handling was done piecemeal, which means they had terminating instead of suppressing semantics. This patch fixes this. Signed-off-by: Heiko Carstens Reviewed-by: Thomas Huth Reviewed-by: David Hildenbrand Signed-off-by: Christian Borntraeger --- arch/s390/kvm/priv.c | 68 +++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 9c565b6b4ccb..9bde32f66eb5 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -762,8 +762,8 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; - u32 val = 0; - int reg, rc; + int reg, rc, nr_regs; + u32 ctl_array[16]; u64 ga; vcpu->stat.instruction_lctl++; @@ -779,14 +779,15 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, ga); + nr_regs = ((reg3 - reg1) & 0xf) + 1; + rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); + if (rc) + return kvm_s390_inject_prog_cond(vcpu, rc); reg = reg1; + nr_regs = 0; do { - rc = read_guest(vcpu, ga, &val, sizeof(val)); - if (rc) - return kvm_s390_inject_prog_cond(vcpu, rc); vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; - vcpu->arch.sie_block->gcr[reg] |= val; - ga += 4; + vcpu->arch.sie_block->gcr[reg] |= ctl_array[nr_regs++]; if (reg == reg3) break; reg = (reg + 1) % 16; @@ -799,9 +800,9 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; + int reg, rc, nr_regs; + u32 ctl_array[16]; u64 ga; - u32 val; - int reg, rc; vcpu->stat.instruction_stctl++; @@ -817,26 +818,24 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) trace_kvm_s390_handle_stctl(vcpu, 0, reg1, reg3, ga); reg = reg1; + nr_regs = 0; do { - val = vcpu->arch.sie_block->gcr[reg] & 0x00000000fffffffful; - rc = write_guest(vcpu, ga, &val, sizeof(val)); - if (rc) - return kvm_s390_inject_prog_cond(vcpu, rc); - ga += 4; + ctl_array[nr_regs++] = vcpu->arch.sie_block->gcr[reg]; if (reg == reg3) break; reg = (reg + 1) % 16; } while (1); - - return 0; + rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u32)); + return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; } static int handle_lctlg(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; - u64 ga, val; - int reg, rc; + int reg, rc, nr_regs; + u64 ctl_array[16]; + u64 ga; vcpu->stat.instruction_lctlg++; @@ -848,17 +847,17 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) if (ga & 7) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - reg = reg1; - VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, ga); + nr_regs = ((reg3 - reg1) & 0xf) + 1; + rc = read_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); + if (rc) + return kvm_s390_inject_prog_cond(vcpu, rc); + reg = reg1; + nr_regs = 0; do { - rc = read_guest(vcpu, ga, &val, sizeof(val)); - if (rc) - return kvm_s390_inject_prog_cond(vcpu, rc); - vcpu->arch.sie_block->gcr[reg] = val; - ga += 8; + vcpu->arch.sie_block->gcr[reg] = ctl_array[nr_regs++]; if (reg == reg3) break; reg = (reg + 1) % 16; @@ -871,8 +870,9 @@ static int handle_stctg(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; - u64 ga, val; - int reg, rc; + int reg, rc, nr_regs; + u64 ctl_array[16]; + u64 ga; vcpu->stat.instruction_stctg++; @@ -884,23 +884,19 @@ static int handle_stctg(struct kvm_vcpu *vcpu) if (ga & 7) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - reg = reg1; - VCPU_EVENT(vcpu, 5, "stctg r1:%x, r3:%x, addr:%llx", reg1, reg3, ga); trace_kvm_s390_handle_stctl(vcpu, 1, reg1, reg3, ga); + reg = reg1; + nr_regs = 0; do { - val = vcpu->arch.sie_block->gcr[reg]; - rc = write_guest(vcpu, ga, &val, sizeof(val)); - if (rc) - return kvm_s390_inject_prog_cond(vcpu, rc); - ga += 8; + ctl_array[nr_regs++] = vcpu->arch.sie_block->gcr[reg]; if (reg == reg3) break; reg = (reg + 1) % 16; } while (1); - - return 0; + rc = write_guest(vcpu, ga, ctl_array, nr_regs * sizeof(u64)); + return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0; } static const intercept_handler_t eb_handlers[256] = { -- GitLab From 365dc1633521a32d55d839f56b41bb9a531d957a Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Fri, 31 Oct 2014 16:44:10 +0100 Subject: [PATCH 3606/9457] KVM: fix vm device attribute documentation Documentation uses incorrect attribute names for some vm device attributes: fix this. Signed-off-by: Dominik Dingel Signed-off-by: Christian Borntraeger --- Documentation/virtual/kvm/devices/vm.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 0d16f96c0eac..d426fc87fe93 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -12,14 +12,14 @@ specific. 1. GROUP: KVM_S390_VM_MEM_CTRL Architectures: s390 -1.1. ATTRIBUTE: KVM_S390_VM_MEM_CTRL +1.1. ATTRIBUTE: KVM_S390_VM_MEM_ENABLE_CMMA Parameters: none -Returns: -EBUSY if already a vcpus is defined, otherwise 0 +Returns: -EBUSY if a vcpu is already defined, otherwise 0 -Enables CMMA for the virtual machine +Enables Collaborative Memory Management Assist (CMMA) for the virtual machine. -1.2. ATTRIBUTE: KVM_S390_VM_CLR_CMMA -Parameteres: none +1.2. ATTRIBUTE: KVM_S390_VM_MEM_CLR_CMMA +Parameters: none Returns: 0 Clear the CMMA status for all guest pages, so any pages the guest marked -- GitLab From a76284e6f89b2ae37d413fe793752257be01765a Mon Sep 17 00:00:00 2001 From: Subodh Nijsure Date: Fri, 31 Oct 2014 13:50:28 -0500 Subject: [PATCH 3607/9457] UBIFS: fix a couple bugs in UBIFS xattr length calculation The journal update function did not work for extended attributes properly, because extended attribute inodes carry the xattr data, and the size of this data was not taken into account. Artem: improved commit message, amended the patch a bit. Signed-off-by: Subodh Nijsure Signed-off-by: Marc Kleine-Budde Signed-off-by: Ben Shelton Acked-by: Brad Mouring Acked-by: Gratian Crisan Signed-off-by: Artem Bityutskiy --- fs/ubifs/journal.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index fb166e204441..f6ac3f29323c 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -571,7 +571,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, aligned_dlen = ALIGN(dlen, 8); aligned_ilen = ALIGN(ilen, 8); + len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; + /* Make sure to also account for extended attributes */ + len += host_ui->data_len; + dent = kmalloc(len, GFP_NOFS); if (!dent) return -ENOMEM; @@ -648,7 +652,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, ino_key_init(c, &ino_key, dir->i_ino); ino_offs += aligned_ilen; - err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ); + err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, + UBIFS_INO_NODE_SZ + host_ui->data_len); if (err) goto out_ro; -- GitLab From b07597367001c2c4f36a97863530f71b84060d3d Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 7 Nov 2014 12:24:39 +0530 Subject: [PATCH 3608/9457] ASoC: Samsung: Add quirk for internal DMA Internal DMA is available only on some of Samsung platforms. So added a quirk for the same and made it optional. Signed-off-by: Padmavathi Venna Signed-off-by: Mark Brown --- include/linux/platform_data/asoc-s3c.h | 1 + sound/soc/samsung/i2s.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h index a6591c693ebb..5e0bc779e6c5 100644 --- a/include/linux/platform_data/asoc-s3c.h +++ b/include/linux/platform_data/asoc-s3c.h @@ -27,6 +27,7 @@ struct samsung_i2s { #define QUIRK_NO_MUXPSR (1 << 2) #define QUIRK_NEED_RSTCLR (1 << 3) #define QUIRK_SUPPORTS_TDM (1 << 4) +#define QUIRK_SUPPORTS_IDMA (1 << 5) /* Quirks of the I2S controller */ u32 quirks; dma_addr_t idma_addr; diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 9d513473b300..38b9a524cc9f 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -987,7 +987,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) if (i2s->quirks & QUIRK_NEED_RSTCLR) writel(CON_RSTCLR, i2s->addr + I2SCON); - if (i2s->quirks & QUIRK_SEC_DAI) + if (i2s->quirks & QUIRK_SUPPORTS_IDMA) idma_reg_addr_init(i2s->addr, i2s->sec_dai->idma_playback.dma_addr); @@ -1199,10 +1199,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) quirks = i2s_dai_data->quirks; if (of_property_read_u32(np, "samsung,idma-addr", &idma_addr)) { - if (quirks & QUIRK_SEC_DAI) { - dev_err(&pdev->dev, "idma address is not"\ + if (quirks & QUIRK_SUPPORTS_IDMA) { + dev_info(&pdev->dev, "idma address is not"\ "specified"); - return -EINVAL; } } } @@ -1309,13 +1308,14 @@ static const struct samsung_i2s_dai_data i2sv3_dai_type = { static const struct samsung_i2s_dai_data i2sv5_dai_type = { .dai_type = TYPE_PRI, - .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | + QUIRK_SUPPORTS_IDMA, }; static const struct samsung_i2s_dai_data i2sv6_dai_type = { .dai_type = TYPE_PRI, .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | - QUIRK_SUPPORTS_TDM, + QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, }; static const struct samsung_i2s_dai_data samsung_dai_type_pri = { -- GitLab From a5a56871f804edac93a53b5e871c0e9818fb9033 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 7 Nov 2014 12:24:40 +0530 Subject: [PATCH 3609/9457] ASoC: samsung: add support for exynos7 I2S controller Exynos7 I2S controller has no internal dma, supports more no. of root clock sampling frequencies and has more no.of Rx fifos to support 7.1CH recording in TDM mode. Due to more no. of root clock frequency values some of the bit offsets got shifted up by one. Also I2S1 on previous Samsung platforms uses v3 dai type but on Exynos7 it is upgraded to v5 with slightly modified register offsets for supporting more no.of RFS values. Due to the above changes, the driver has to be modified to handle all versions of I2S controller. For this I introduced a new structure to hold modified bit offsets and masks which is passed as dai data. Signed-off-by: Padmavathi Venna Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/samsung-i2s.txt | 15 +- sound/soc/samsung/Kconfig | 2 +- sound/soc/samsung/i2s-regs.h | 10 +- sound/soc/samsung/i2s.c | 218 +++++++++++++----- 4 files changed, 174 insertions(+), 71 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt index 7386d444ada1..d188296bb6ec 100644 --- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt +++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt @@ -6,10 +6,17 @@ Required SoC Specific Properties: - samsung,s3c6410-i2s: for 8/16/24bit stereo I2S. - samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with secondary fifo, s/w reset control and internal mux for root clk src. - - samsung,exynos5420-i2s: for 8/16/24bit multichannel(7.1) I2S with - secondary fifo, s/w reset control, internal mux for root clk src and - TDM support. TDM (Time division multiplexing) is to allow transfer of - multiple channel audio data on single data line. + - samsung,exynos5420-i2s: for 8/16/24bit multichannel(5.1) I2S for + playback, sterio channel capture, secondary fifo using internal + or external dma, s/w reset control, internal mux for root clk src + and 7.1 channel TDM support for playback. TDM (Time division multiplexing) + is to allow transfer of multiple channel audio data on single data line. + - samsung,exynos7-i2s: with all the available features of exynos5 i2s, + exynos7 I2S has 7.1 channel TDM support for capture, secondary fifo + with only external dma and more no.of root clk sampling frequencies. + - samsung,exynos7-i2s1: I2S1 on previous samsung platforms supports + stereo channels. exynos7 i2s1 upgraded to 5.1 multichannel with + slightly modified bit offsets. - reg: physical base address of the controller and length of memory mapped region. diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 55a38697443d..e0e737faadd9 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,6 +1,6 @@ config SND_SOC_SAMSUNG tristate "ASoC support for Samsung" - depends on PLAT_SAMSUNG + depends on (PLAT_SAMSUNG || ARCH_EXYNOS) depends on S3C64XX_PL080 || !ARCH_S3C64XX depends on S3C24XX_DMAC || !ARCH_S3C24XX select SND_SOC_GENERIC_DMAENGINE_PCM diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h index 821a50231002..9170c311d66e 100644 --- a/sound/soc/samsung/i2s-regs.h +++ b/sound/soc/samsung/i2s-regs.h @@ -33,8 +33,9 @@ #define I2SLVL3ADDR 0x3c #define I2SSTR1 0x40 #define I2SVER 0x44 -#define I2SFIC2 0x48 +#define I2SFIC1 0x48 #define I2STDM 0x4c +#define I2SFSTA 0x50 #define CON_RSTCLR (1 << 31) #define CON_FRXOFSTATUS (1 << 26) @@ -93,8 +94,6 @@ #define MOD_BLC_24BIT (2 << 13) #define MOD_BLC_MASK (3 << 13) -#define MOD_IMS_SYSMUX (1 << 10) -#define MOD_SLAVE (1 << 11) #define MOD_TXONLY (0 << 8) #define MOD_RXONLY (1 << 8) #define MOD_TXRX (2 << 8) @@ -132,7 +131,10 @@ #define EXYNOS5420_MOD_BCLK_256FS 8 #define EXYNOS5420_MOD_BCLK_MASK 0xf -#define MOD_CDCLKCON (1 << 12) +#define EXYNOS7_MOD_RCLK_64FS 4 +#define EXYNOS7_MOD_RCLK_128FS 5 +#define EXYNOS7_MOD_RCLK_96FS 6 +#define EXYNOS7_MOD_RCLK_192FS 7 #define PSR_PSREN (1 << 15) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 38b9a524cc9f..947352d00ddf 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -36,9 +36,24 @@ enum samsung_dai_type { TYPE_SEC, }; +struct samsung_i2s_variant_regs { + unsigned int bfs_off; + unsigned int rfs_off; + unsigned int sdf_off; + unsigned int txr_off; + unsigned int rclksrc_off; + unsigned int mss_off; + unsigned int cdclkcon_off; + unsigned int lrp_off; + unsigned int bfs_mask; + unsigned int rfs_mask; + unsigned int ftx0cnt_off; +}; + struct samsung_i2s_dai_data { int dai_type; u32 quirks; + const struct samsung_i2s_variant_regs *i2s_variant_regs; }; struct i2s_dai { @@ -81,6 +96,7 @@ struct i2s_dai { u32 suspend_i2scon; u32 suspend_i2spsr; unsigned long gpios[7]; /* i2s gpio line numbers */ + const struct samsung_i2s_variant_regs *variant_regs; }; /* Lock for cross i/f checks */ @@ -95,7 +111,8 @@ static inline bool is_secondary(struct i2s_dai *i2s) /* If operating in SoC-Slave mode */ static inline bool is_slave(struct i2s_dai *i2s) { - return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false; + u32 mod = readl(i2s->addr + I2SMOD); + return (mod & (1 << i2s->variant_regs->mss_off)) ? true : false; } /* If this interface of the controller is transmitting data */ @@ -200,14 +217,14 @@ static inline bool is_manager(struct i2s_dai *i2s) static inline unsigned get_rfs(struct i2s_dai *i2s) { u32 rfs; - - if (i2s->quirks & QUIRK_SUPPORTS_TDM) - rfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_RCLK_SHIFT; - else - rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT); - rfs &= MOD_RCLK_MASK; + rfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->rfs_off; + rfs &= i2s->variant_regs->rfs_mask; switch (rfs) { + case 7: return 192; + case 6: return 96; + case 5: return 128; + case 4: return 64; case 3: return 768; case 2: return 384; case 1: return 512; @@ -219,15 +236,23 @@ static inline unsigned get_rfs(struct i2s_dai *i2s) static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) { u32 mod = readl(i2s->addr + I2SMOD); - int rfs_shift; + int rfs_shift = i2s->variant_regs->rfs_off; - if (i2s->quirks & QUIRK_SUPPORTS_TDM) - rfs_shift = EXYNOS5420_MOD_RCLK_SHIFT; - else - rfs_shift = MOD_RCLK_SHIFT; - mod &= ~(MOD_RCLK_MASK << rfs_shift); + mod &= ~(i2s->variant_regs->rfs_mask << rfs_shift); switch (rfs) { + case 192: + mod |= (EXYNOS7_MOD_RCLK_192FS << rfs_shift); + break; + case 96: + mod |= (EXYNOS7_MOD_RCLK_96FS << rfs_shift); + break; + case 128: + mod |= (EXYNOS7_MOD_RCLK_128FS << rfs_shift); + break; + case 64: + mod |= (EXYNOS7_MOD_RCLK_64FS << rfs_shift); + break; case 768: mod |= (MOD_RCLK_768FS << rfs_shift); break; @@ -249,14 +274,8 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) static inline unsigned get_bfs(struct i2s_dai *i2s) { u32 bfs; - - if (i2s->quirks & QUIRK_SUPPORTS_TDM) { - bfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_BCLK_SHIFT; - bfs &= EXYNOS5420_MOD_BCLK_MASK; - } else { - bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT; - bfs &= MOD_BCLK_MASK; - } + bfs = readl(i2s->addr + I2SMOD) >> i2s->variant_regs->bfs_off; + bfs &= i2s->variant_regs->bfs_mask; switch (bfs) { case 8: return 256; @@ -275,16 +294,8 @@ static inline unsigned get_bfs(struct i2s_dai *i2s) static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) { u32 mod = readl(i2s->addr + I2SMOD); - int bfs_shift; int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM; - - if (i2s->quirks & QUIRK_SUPPORTS_TDM) { - bfs_shift = EXYNOS5420_MOD_BCLK_SHIFT; - mod &= ~(EXYNOS5420_MOD_BCLK_MASK << bfs_shift); - } else { - bfs_shift = MOD_BCLK_SHIFT; - mod &= ~(MOD_BCLK_MASK << bfs_shift); - } + int bfs_shift = i2s->variant_regs->bfs_off; /* Non-TDM I2S controllers do not support BCLK > 48 * FS */ if (!tdm && bfs > 48) { @@ -292,6 +303,8 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) return; } + mod &= ~(i2s->variant_regs->bfs_mask << bfs_shift); + switch (bfs) { case 48: mod |= (MOD_BCLK_48FS << bfs_shift); @@ -346,8 +359,9 @@ static inline int get_blc(struct i2s_dai *i2s) static void i2s_txctrl(struct i2s_dai *i2s, int on) { void __iomem *addr = i2s->addr; + int txr_off = i2s->variant_regs->txr_off; u32 con = readl(addr + I2SCON); - u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off); if (on) { con |= CON_ACTIVE; @@ -362,9 +376,9 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on) } if (any_rx_active(i2s)) - mod |= MOD_TXRX; + mod |= 2 << txr_off; else - mod |= MOD_TXONLY; + mod |= 0 << txr_off; } else { if (is_secondary(i2s)) { con |= CON_TXSDMA_PAUSE; @@ -382,7 +396,7 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on) con |= CON_TXCH_PAUSE; if (any_rx_active(i2s)) - mod |= MOD_RXONLY; + mod |= 1 << txr_off; else con &= ~CON_ACTIVE; } @@ -395,23 +409,24 @@ static void i2s_txctrl(struct i2s_dai *i2s, int on) static void i2s_rxctrl(struct i2s_dai *i2s, int on) { void __iomem *addr = i2s->addr; + int txr_off = i2s->variant_regs->txr_off; u32 con = readl(addr + I2SCON); - u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + u32 mod = readl(addr + I2SMOD) & ~(3 << txr_off); if (on) { con |= CON_RXDMA_ACTIVE | CON_ACTIVE; con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE); if (any_tx_active(i2s)) - mod |= MOD_TXRX; + mod |= 2 << txr_off; else - mod |= MOD_RXONLY; + mod |= 1 << txr_off; } else { con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE; con &= ~CON_RXDMA_ACTIVE; if (any_tx_active(i2s)) - mod |= MOD_TXONLY; + mod |= 0 << txr_off; else con &= ~CON_ACTIVE; } @@ -451,6 +466,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; u32 mod = readl(i2s->addr + I2SMOD); + const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; + unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; + unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; switch (clk_id) { case SAMSUNG_I2S_OPCLK: @@ -465,18 +483,18 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, if ((rfs && other && other->rfs && (other->rfs != rfs)) || (any_active(i2s) && (((dir == SND_SOC_CLOCK_IN) - && !(mod & MOD_CDCLKCON)) || + && !(mod & cdcon_mask)) || ((dir == SND_SOC_CLOCK_OUT) - && (mod & MOD_CDCLKCON))))) { + && (mod & cdcon_mask))))) { dev_err(&i2s->pdev->dev, "%s:%d Other DAI busy\n", __func__, __LINE__); return -EAGAIN; } if (dir == SND_SOC_CLOCK_IN) - mod |= MOD_CDCLKCON; + mod |= 1 << i2s_regs->cdclkcon_off; else - mod &= ~MOD_CDCLKCON; + mod &= 0 << i2s_regs->cdclkcon_off; i2s->rfs = rfs; break; @@ -491,8 +509,8 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, if (!any_active(i2s)) { if (i2s->op_clk && !IS_ERR(i2s->op_clk)) { - if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || - (!clk_id && (mod & MOD_IMS_SYSMUX))) { + if ((clk_id && !(mod & rsrc_mask)) || + (!clk_id && (mod & rsrc_mask))) { clk_disable_unprepare(i2s->op_clk); clk_put(i2s->op_clk); } else { @@ -520,8 +538,8 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, other->op_clk = i2s->op_clk; other->rclk_srcrate = i2s->rclk_srcrate; } - } else if ((!clk_id && (mod & MOD_IMS_SYSMUX)) - || (clk_id && !(mod & MOD_IMS_SYSMUX))) { + } else if ((!clk_id && (mod & rsrc_mask)) + || (clk_id && !(mod & rsrc_mask))) { dev_err(&i2s->pdev->dev, "%s:%d Other DAI busy\n", __func__, __LINE__); return -EAGAIN; @@ -533,10 +551,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, } if (clk_id == 0) - mod &= ~MOD_IMS_SYSMUX; + mod &= 0 << i2s_regs->rclksrc_off; else - mod |= MOD_IMS_SYSMUX; - break; + mod |= 1 << i2s_regs->rclksrc_off; default: dev_err(&i2s->pdev->dev, "We don't serve that!\n"); @@ -553,16 +570,12 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, { struct i2s_dai *i2s = to_info(dai); u32 mod = readl(i2s->addr + I2SMOD); - int lrp_shift, sdf_shift, sdf_mask, lrp_rlow; + int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; u32 tmp = 0; - if (i2s->quirks & QUIRK_SUPPORTS_TDM) { - lrp_shift = EXYNOS5420_MOD_LRP_SHIFT; - sdf_shift = EXYNOS5420_MOD_SDF_SHIFT; - } else { - lrp_shift = MOD_LRP_SHIFT; - sdf_shift = MOD_SDF_SHIFT; - } + lrp_shift = i2s->variant_regs->lrp_off; + sdf_shift = i2s->variant_regs->sdf_off; + mod_slave = 1 << i2s->variant_regs->mss_off; sdf_mask = MOD_SDF_MASK << sdf_shift; lrp_rlow = MOD_LR_RLOW << lrp_shift; @@ -605,7 +618,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: - tmp |= MOD_SLAVE; + tmp |= mod_slave; break; case SND_SOC_DAIFMT_CBS_CFS: /* Set default source clock in Master mode */ @@ -623,13 +636,13 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, * channel. */ if (any_active(i2s) && - ((mod & (sdf_mask | lrp_rlow | MOD_SLAVE)) != tmp)) { + ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { dev_err(&i2s->pdev->dev, "%s:%d Other DAI busy\n", __func__, __LINE__); return -EAGAIN; } - mod &= ~(sdf_mask | lrp_rlow | MOD_SLAVE); + mod &= ~(sdf_mask | lrp_rlow | mod_slave); mod |= tmp; writel(mod, i2s->addr + I2SMOD); @@ -751,6 +764,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; unsigned long flags; + const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; spin_lock_irqsave(&lock, flags); @@ -761,7 +775,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, other->mode |= DAI_MANAGER; } else { u32 mod = readl(i2s->addr + I2SMOD); - i2s->cdclk_out = !(mod & MOD_CDCLKCON); + i2s->cdclk_out = !(mod & (1 << i2s_regs->cdclkcon_off)); if (other) other->cdclk_out = i2s->cdclk_out; } @@ -914,13 +928,14 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) struct i2s_dai *i2s = to_info(dai); u32 reg = readl(i2s->addr + I2SFIC); snd_pcm_sframes_t delay; + const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) delay = FIC_RXCOUNT(reg); else if (is_secondary(i2s)) delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS)); else - delay = FIC_TXCOUNT(reg); + delay = (reg >> i2s_regs->ftx0cnt_off) & 0x7f; return delay; } @@ -1227,6 +1242,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) pri_dai->dma_capture.dma_size = 4; pri_dai->base = regs_base; pri_dai->quirks = quirks; + pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; if (quirks & QUIRK_PRI_6CHAN) pri_dai->i2s_dai_drv.playback.channels_max = 6; @@ -1301,21 +1317,93 @@ static int samsung_i2s_remove(struct platform_device *pdev) return 0; } +static const struct samsung_i2s_variant_regs i2sv3_regs = { + .bfs_off = 1, + .rfs_off = 3, + .sdf_off = 5, + .txr_off = 8, + .rclksrc_off = 10, + .mss_off = 11, + .cdclkcon_off = 12, + .lrp_off = 7, + .bfs_mask = 0x3, + .rfs_mask = 0x3, + .ftx0cnt_off = 8, +}; + +static const struct samsung_i2s_variant_regs i2sv6_regs = { + .bfs_off = 0, + .rfs_off = 4, + .sdf_off = 6, + .txr_off = 8, + .rclksrc_off = 10, + .mss_off = 11, + .cdclkcon_off = 12, + .lrp_off = 15, + .bfs_mask = 0xf, + .rfs_mask = 0x3, + .ftx0cnt_off = 8, +}; + +static const struct samsung_i2s_variant_regs i2sv7_regs = { + .bfs_off = 0, + .rfs_off = 4, + .sdf_off = 7, + .txr_off = 9, + .rclksrc_off = 11, + .mss_off = 12, + .cdclkcon_off = 22, + .lrp_off = 15, + .bfs_mask = 0xf, + .rfs_mask = 0x7, + .ftx0cnt_off = 0, +}; + +static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = { + .bfs_off = 0, + .rfs_off = 3, + .sdf_off = 6, + .txr_off = 8, + .rclksrc_off = 10, + .mss_off = 11, + .cdclkcon_off = 12, + .lrp_off = 15, + .bfs_mask = 0x7, + .rfs_mask = 0x7, + .ftx0cnt_off = 8, +}; + static const struct samsung_i2s_dai_data i2sv3_dai_type = { .dai_type = TYPE_PRI, .quirks = QUIRK_NO_MUXPSR, + .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type = { .dai_type = TYPE_PRI, .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_IDMA, + .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv6_dai_type = { .dai_type = TYPE_PRI, .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, + .i2s_variant_regs = &i2sv6_regs, +}; + +static const struct samsung_i2s_dai_data i2sv7_dai_type = { + .dai_type = TYPE_PRI, + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | + QUIRK_SUPPORTS_TDM, + .i2s_variant_regs = &i2sv7_regs, +}; + +static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { + .dai_type = TYPE_PRI, + .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, + .i2s_variant_regs = &i2sv5_i2s1_regs, }; static const struct samsung_i2s_dai_data samsung_dai_type_pri = { @@ -1349,6 +1437,12 @@ static const struct of_device_id exynos_i2s_match[] = { }, { .compatible = "samsung,exynos5420-i2s", .data = &i2sv6_dai_type, + }, { + .compatible = "samsung,exynos7-i2s", + .data = &i2sv7_dai_type, + }, { + .compatible = "samsung,exynos7-i2s1", + .data = &i2sv5_dai_type_i2s1, }, {}, }; -- GitLab From 19ba484d7b15c8650b30377aad6e65b34d3cf3d5 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 5 Nov 2014 13:42:53 +0800 Subject: [PATCH 3610/9457] ASoC: rt5677: Use specific r/w function for DSP mode In DSP mode, the register r/w should use the specific function to access that is invoked by address mapping of the DSP. The MX-65[1] is for switching DSP or codec mode. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 167 +++++++++++++++++++++++--------------- sound/soc/codecs/rt5677.h | 3 +- 2 files changed, 102 insertions(+), 68 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 0d24dc45dfe4..4b6f7d57c1bb 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -541,49 +541,51 @@ static bool rt5677_readable_register(struct device *dev, unsigned int reg) /** * rt5677_dsp_mode_i2c_write_addr - Write value to address on DSP mode. - * @codec: SoC audio codec device. + * @rt5677: Private Data. * @addr: Address index. * @value: Address data. * * * Returns 0 for success or negative error code. */ -static int rt5677_dsp_mode_i2c_write_addr(struct snd_soc_codec *codec, +static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677, unsigned int addr, unsigned int value, unsigned int opcode) { - struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_codec *codec = rt5677->codec; int ret; mutex_lock(&rt5677->dsp_cmd_lock); - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16); + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB, + addr >> 16); if (ret < 0) { dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB, + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB, addr & 0xffff); if (ret < 0) { dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB, + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_MSB, value >> 16); if (ret < 0) { dev_err(codec->dev, "Failed to set data msb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB, + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_LSB, value & 0xffff); if (ret < 0) { dev_err(codec->dev, "Failed to set data lsb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE, opcode); + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE, + opcode); if (ret < 0) { dev_err(codec->dev, "Failed to set op code value: %d\n", ret); goto err; @@ -597,42 +599,45 @@ static int rt5677_dsp_mode_i2c_write_addr(struct snd_soc_codec *codec, /** * rt5677_dsp_mode_i2c_read_addr - Read value from address on DSP mode. - * @codec: SoC audio codec device. + * rt5677: Private Data. * @addr: Address index. * @value: Address data. * + * * Returns 0 for success or negative error code. */ static int rt5677_dsp_mode_i2c_read_addr( - struct snd_soc_codec *codec, unsigned int addr, unsigned int *value) + struct rt5677_priv *rt5677, unsigned int addr, unsigned int *value) { - struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_codec *codec = rt5677->codec; int ret; unsigned int msb, lsb; mutex_lock(&rt5677->dsp_cmd_lock); - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16); + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB, + addr >> 16); if (ret < 0) { dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB, + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB, addr & 0xffff); if (ret < 0) { dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret); goto err; } - ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE , 0x0002); + ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE, + 0x0002); if (ret < 0) { dev_err(codec->dev, "Failed to set op code value: %d\n", ret); goto err; } - regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB, &msb); - regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB, &lsb); + regmap_read(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_MSB, &msb); + regmap_read(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_LSB, &lsb); *value = (msb << 16) | lsb; err: @@ -643,17 +648,17 @@ static int rt5677_dsp_mode_i2c_read_addr( /** * rt5677_dsp_mode_i2c_write - Write register on DSP mode. - * @codec: SoC audio codec device. + * rt5677: Private Data. * @reg: Register index. * @value: Register data. * * * Returns 0 for success or negative error code. */ -static int rt5677_dsp_mode_i2c_write(struct snd_soc_codec *codec, +static int rt5677_dsp_mode_i2c_write(struct rt5677_priv *rt5677, unsigned int reg, unsigned int value) { - return rt5677_dsp_mode_i2c_write_addr(codec, 0x18020000 + reg * 2, + return rt5677_dsp_mode_i2c_write_addr(rt5677, 0x18020000 + reg * 2, value, 0x0001); } @@ -661,57 +666,33 @@ static int rt5677_dsp_mode_i2c_write(struct snd_soc_codec *codec, * rt5677_dsp_mode_i2c_read - Read register on DSP mode. * @codec: SoC audio codec device. * @reg: Register index. + * @value: Register data. * * - * Returns Register value. + * Returns 0 for success or negative error code. */ -static unsigned int rt5677_dsp_mode_i2c_read( - struct snd_soc_codec *codec, unsigned int reg) +static int rt5677_dsp_mode_i2c_read( + struct rt5677_priv *rt5677, unsigned int reg, unsigned int *value) { - unsigned int value = 0; + int ret = rt5677_dsp_mode_i2c_read_addr(rt5677, 0x18020000 + reg * 2, + value); - rt5677_dsp_mode_i2c_read_addr(codec, 0x18020000 + reg * 2, &value); + *value &= 0xffff; - return value; + return ret; } -/** - * rt5677_dsp_mode_i2c_update_bits - update register on DSP mode. - * @codec: audio codec - * @reg: register index. - * @mask: register mask - * @value: new value - * - * - * Returns 1 for change, 0 for no change, or negative error code. - */ -static int rt5677_dsp_mode_i2c_update_bits(struct snd_soc_codec *codec, - unsigned int reg, unsigned int mask, unsigned int value) +static void rt5677_set_dsp_mode(struct snd_soc_codec *codec, bool on) { - unsigned int old, new; - int change, ret; - - ret = rt5677_dsp_mode_i2c_read(codec, reg); - if (ret < 0) { - dev_err(codec->dev, "Failed to read reg: %d\n", ret); - goto err; - } + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) { - ret = rt5677_dsp_mode_i2c_write(codec, reg, new); - if (ret < 0) { - dev_err(codec->dev, - "Failed to write reg: %d\n", ret); - goto err; - } + if (on) { + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2); + rt5677->is_dsp_mode = true; + } else { + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x0); + rt5677->is_dsp_mode = false; } - return change; - -err: - return ret; } static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) @@ -733,9 +714,14 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) RT5677_LDO1_SEL_MASK, 0x0); regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, RT5677_PWR_LDO1, RT5677_PWR_LDO1); - regmap_write(rt5677->regmap, RT5677_GLB_CLK2, 0x0080); + regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1, + RT5677_MCLK_SRC_MASK, RT5677_MCLK2_SRC); + regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2, + RT5677_PLL2_PR_SRC_MASK | RT5677_DSP_CLK_SRC_MASK, + RT5677_PLL2_PR_SRC_MCLK2 | RT5677_DSP_CLK_SRC_BYPASS); regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff); - regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07ff); + regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd); + rt5677_set_dsp_mode(codec, true); ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1, codec->dev); @@ -751,8 +737,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) release_firmware(rt5677->fw2); } - rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1, - 0x0); + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x0); regcache_cache_bypass(rt5677->regmap, false); regcache_cache_only(rt5677->regmap, true); @@ -762,9 +747,9 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) regcache_cache_only(rt5677->regmap, false); regcache_cache_bypass(rt5677->regmap, true); - rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1, - 0x1); - rt5677_dsp_mode_i2c_write(codec, RT5677_PWR_DSP1, 0x0001); + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x1); + rt5677_set_dsp_mode(codec, false); + regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x0001); regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); @@ -4019,6 +4004,32 @@ static int rt5677_resume(struct snd_soc_codec *codec) #define rt5677_resume NULL #endif +static int rt5677_read(void *context, unsigned int reg, unsigned int *val) +{ + struct i2c_client *client = context; + struct rt5677_priv *rt5677 = i2c_get_clientdata(client); + + if (rt5677->is_dsp_mode) + rt5677_dsp_mode_i2c_read(rt5677, reg, val); + else + regmap_read(rt5677->regmap_physical, reg, val); + + return 0; +} + +static int rt5677_write(void *context, unsigned int reg, unsigned int val) +{ + struct i2c_client *client = context; + struct rt5677_priv *rt5677 = i2c_get_clientdata(client); + + if (rt5677->is_dsp_mode) + rt5677_dsp_mode_i2c_write(rt5677, reg, val); + else + regmap_write(rt5677->regmap_physical, reg, val); + + return 0; +} + #define RT5677_STEREO_RATES SNDRV_PCM_RATE_8000_96000 #define RT5677_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) @@ -4144,6 +4155,17 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5677 = { .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), }; +static const struct regmap_config rt5677_regmap_physical = { + .name = "physical", + .reg_bits = 8, + .val_bits = 16, + + .max_register = RT5677_VENDOR_ID2 + 1, + .readable_reg = rt5677_readable_register, + + .cache_type = REGCACHE_NONE, +}; + static const struct regmap_config rt5677_regmap = { .reg_bits = 8, .val_bits = 16, @@ -4153,6 +4175,8 @@ static const struct regmap_config rt5677_regmap = { .volatile_reg = rt5677_volatile_register, .readable_reg = rt5677_readable_register, + .reg_read = rt5677_read, + .reg_write = rt5677_write, .cache_type = REGCACHE_RBTREE, .reg_defaults = rt5677_reg, @@ -4309,7 +4333,16 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, msleep(10); } - rt5677->regmap = devm_regmap_init_i2c(i2c, &rt5677_regmap); + rt5677->regmap_physical = devm_regmap_init_i2c(i2c, + &rt5677_regmap_physical); + if (IS_ERR(rt5677->regmap_physical)) { + ret = PTR_ERR(rt5677->regmap_physical); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + rt5677->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt5677_regmap); if (IS_ERR(rt5677->regmap)) { ret = PTR_ERR(rt5677->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 2f5b8c6c279e..9d473b2798d5 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -1628,7 +1628,7 @@ enum { struct rt5677_priv { struct snd_soc_codec *codec; struct rt5677_platform_data pdata; - struct regmap *regmap; + struct regmap *regmap, *regmap_physical; const struct firmware *fw1, *fw2; struct mutex dsp_cmd_lock; @@ -1646,6 +1646,7 @@ struct rt5677_priv { #endif bool dsp_vad_en; struct regmap_irq_chip_data *irq_data; + bool is_dsp_mode; }; #endif /* __RT5677_H__ */ -- GitLab From aa5ad3b6eb8feb2399a5d26c8fb0060561bb9534 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Thu, 6 Nov 2014 16:47:49 +0100 Subject: [PATCH 3611/9457] UBI: Fix double free after do_sync_erase() If the erase worker is unable to erase a PEB it will free the ubi_wl_entry itself. The failing ubi_wl_entry must not free()'d again after do_sync_erase() returns. Cc: Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 7d2a25f96804..834f6fe1f5fa 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1216,7 +1216,6 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, err = do_sync_erase(ubi, e1, vol_id, lnum, 0); if (err) { - kmem_cache_free(ubi_wl_entry_slab, e1); if (e2) kmem_cache_free(ubi_wl_entry_slab, e2); goto out_ro; @@ -1230,10 +1229,8 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", e2->pnum, vol_id, lnum); err = do_sync_erase(ubi, e2, vol_id, lnum, 0); - if (err) { - kmem_cache_free(ubi_wl_entry_slab, e2); + if (err) goto out_ro; - } } dbg_wl("done"); @@ -1269,10 +1266,9 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi_free_vid_hdr(ubi, vid_hdr); err = do_sync_erase(ubi, e2, vol_id, lnum, torture); - if (err) { - kmem_cache_free(ubi_wl_entry_slab, e2); + if (err) goto out_ro; - } + mutex_unlock(&ubi->move_mutex); return 0; -- GitLab From 9e2683530d6f78b30bcf4cabb97d1b7d6b925b85 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 31 Oct 2014 15:37:55 +0800 Subject: [PATCH 3612/9457] ASoC: rt5645: Add ASRC support This patch add ASRC support for rt5645 codec. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 144 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 286438d6916b..1dbbebc83d41 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -441,6 +441,65 @@ static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, RT5645_TDM_CTRL_1, 8, rt5645_tdm_adc_data_select); +static int rt5645_clk_sel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int u_bit = 0, p_bit = 0; + struct soc_enum *em = + (struct soc_enum *)kcontrol->private_value; + + switch (em->reg) { + case RT5645_ASRC_2: + switch (em->shift_l) { + case 0: + u_bit = 0x8; + p_bit = RT5645_PWR_ADC_S1F; + break; + case 4: + u_bit = 0x100; + p_bit = RT5645_PWR_DAC_MF_R; + break; + case 8: + u_bit = 0x200; + p_bit = RT5645_PWR_DAC_MF_L; + break; + case 12: + u_bit = 0x400; + p_bit = RT5645_PWR_DAC_S1F; + break; + } + break; + case RT5645_ASRC_3: + switch (em->shift_l) { + case 0: + u_bit = 0x1; + p_bit = RT5645_PWR_ADC_MF_R; + break; + case 4: + u_bit = 0x2; + p_bit = RT5645_PWR_ADC_MF_L; + break; + } + break; + } + + if (u_bit || p_bit) { + switch (ucontrol->value.integer.value[0]) { + case 1 ... 4: /*enable*/ + if (snd_soc_read(codec, RT5645_PWR_DIG2) & p_bit) + snd_soc_update_bits(codec, + RT5645_ASRC_1, u_bit, u_bit); + break; + default: /*disable*/ + snd_soc_update_bits(codec, RT5645_ASRC_1, u_bit, 0); + break; + } + } + + return snd_soc_put_enum_double(kcontrol, ucontrol); +} + static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, @@ -552,6 +611,53 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, return 0; } +static int is_using_asrc(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + unsigned int reg, shift, val; + + switch (source->shift) { + case 0: + reg = RT5645_ASRC_3; + shift = 0; + break; + case 1: + reg = RT5645_ASRC_3; + shift = 4; + break; + case 3: + reg = RT5645_ASRC_2; + shift = 0; + break; + case 8: + reg = RT5645_ASRC_2; + shift = 4; + break; + case 9: + reg = RT5645_ASRC_2; + shift = 8; + break; + case 10: + reg = RT5645_ASRC_2; + shift = 12; + break; + default: + return 0; + } + + val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; + switch (val) { + case 1: + case 2: + case 3: + case 4: + return 1; + default: + return 0; + } + +} + /* Digital Mixer */ static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, @@ -1244,6 +1350,30 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), + /* ASRC */ + SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5645_ASRC_1, + 11, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5645_ASRC_1, + 12, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5645_ASRC_1, + 10, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5645_ASRC_1, + 9, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5645_ASRC_1, + 8, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5645_ASRC_1, + 7, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5645_ASRC_1, + 5, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5645_ASRC_1, + 4, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5645_ASRC_1, + 3, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5645_ASRC_1, + 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5645_ASRC_1, + 0, 0, NULL, 0), + /* Input Side */ /* micbias */ SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, @@ -1502,6 +1632,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { + { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, + { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, + { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, + { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, + { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc }, + { "dac mono right filter", NULL, "DAC MONO R ASRC", is_using_asrc }, + { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc }, + + { "I2S1", NULL, "I2S1 ASRC" }, + { "I2S2", NULL, "I2S2 ASRC" }, + { "IN1P", NULL, "LDO2" }, { "IN2P", NULL, "LDO2" }, @@ -1548,12 +1689,15 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, + { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC" }, { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, + { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC" }, { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, + { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC" }, { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, -- GitLab From f38aed975c0c3645bbdfc5ebe35726e64caaf588 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 27 Oct 2014 00:46:11 +0100 Subject: [PATCH 3613/9457] UBI: Fix invalid vfree() The logic of vfree()'ing vol->upd_buf is tied to vol->updating. In ubi_start_update() vol->updating is set long before vmalloc()'ing vol->upd_buf. If we encounter a write failure in ubi_start_update() before vmalloc() the UBI device release function will try to vfree() vol->upd_buf because vol->updating is set. Fix this by allocating vol->upd_buf directly after setting vol->updating. Fixes: [ 31.559338] UBI warning: vol_cdev_release: update of volume 2 not finished, volume is damaged [ 31.559340] ------------[ cut here ]------------ [ 31.559343] WARNING: CPU: 1 PID: 2747 at mm/vmalloc.c:1446 __vunmap+0xe3/0x110() [ 31.559344] Trying to vfree() nonexistent vm area (ffffc90001f2b000) [ 31.559345] Modules linked in: [ 31.565620] 0000000000000bba ffff88002a0cbdb0 ffffffff818f0497 ffff88003b9ba148 [ 31.566347] ffff88002a0cbde0 ffffffff8156f515 ffff88003b9ba148 0000000000000bba [ 31.567073] 0000000000000000 0000000000000000 ffff88002a0cbe88 ffffffff8156c10a [ 31.567793] Call Trace: [ 31.568034] [] dump_stack+0x4e/0x7a [ 31.568510] [] ubi_io_write_vid_hdr+0x155/0x160 [ 31.569084] [] ubi_eba_write_leb+0x23a/0x870 [ 31.569628] [] vol_cdev_write+0x226/0x380 [ 31.570155] [] vfs_write+0xb5/0x1f0 [ 31.570627] [] SyS_pwrite64+0x6a/0xa0 [ 31.571123] [] system_call_fastpath+0x16/0x1b Cc: Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/upd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index ec2c2dc1c1ca..2a1b6e037e1a 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -133,6 +133,10 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, ubi_assert(!vol->updating && !vol->changing_leb); vol->updating = 1; + vol->upd_buf = vmalloc(ubi->leb_size); + if (!vol->upd_buf) + return -ENOMEM; + err = set_update_marker(ubi, vol); if (err) return err; @@ -152,14 +156,12 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, err = clear_update_marker(ubi, vol, 0); if (err) return err; + + vfree(vol->upd_buf); vol->updating = 0; return 0; } - vol->upd_buf = vmalloc(ubi->leb_size); - if (!vol->upd_buf) - return -ENOMEM; - vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, vol->usable_leb_size); vol->upd_bytes = bytes; -- GitLab From 31584ed18c073176a7ad96ddbfd09765e21e813d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 7 Nov 2014 14:12:34 +0100 Subject: [PATCH 3614/9457] ALSA: snd_ctl_activate_id(): Fix index look-up We want to know the offset for the id that was passed to the function, not the offset of the first id of the control (which is always 0). Signed-off-by: Lars-Peter Clausen Signed-off-by: Takashi Iwai --- sound/core/control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/control.c b/sound/core/control.c index 99aa3aa157ba..bb96a467e88d 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -572,7 +572,7 @@ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, ret = -ENOENT; goto unlock; } - index_offset = snd_ctl_get_ioff(kctl, &kctl->id); + index_offset = snd_ctl_get_ioff(kctl, id); vd = &kctl->vd[index_offset]; ret = 0; if (active) { -- GitLab From cb77c3ec075a50e9f956f62dc2e4c0394df1d578 Mon Sep 17 00:00:00 2001 From: Jaganath Kanakkassery Date: Fri, 7 Nov 2014 16:39:09 +0530 Subject: [PATCH 3615/9457] Bluetooth: Send mgmt_connected only if state is BT_CONFIG If a remote name request is initiated while acl connection is going on, and if it fails then mgmt_connected will be sent. Evetually after acl connection, authentication will not be initiated and userspace will never get pairing reply. < HCI Command: Create Connection (0x01|0x0005) plen 13 bdaddr AA:BB:CC:DD:EE:FF ptype 0xcc18 rswitch 0x01 clkoffset 0x2306 (valid) Packet type: DM1 DM3 DM5 DH1 DH3 DH5 > HCI Event: Command Status (0x0f) plen 4 Create Connection (0x01|0x0005) status 0x00 ncmd 1 > HCI Event: Inquiry Complete (0x01) plen 1 status 0x00 < HCI Command: Remote Name Request (0x01|0x0019) plen 10 bdaddr AA:BB:CC:DD:EE:FF mode 1 clkoffset 0x2306 > HCI Event: Command Status (0x0f) plen 4 Remote Name Request (0x01|0x0019) status 0x0c ncmd 1 Error: Command Disallowed > HCI Event: Connect Complete (0x03) plen 11 status 0x00 handle 50 bdaddr 00:0D:FD:47:53:B2 type ACL encrypt 0x00 < HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2 handle 50 > HCI Event: Command Status (0x0f) plen 4 Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1 > HCI Event: Max Slots Change (0x1b) plen 3 handle 50 slots 5 > HCI Event: Read Remote Supported Features (0x0b) plen 11 status 0x00 handle 50 Features: 0xff 0xff 0x8f 0xfe 0x9b 0xff 0x59 0x83 < HCI Command: Read Remote Extended Features (0x01|0x001c) plen 3 handle 50 page 1 > HCI Event: Command Status (0x0f) plen 4 Read Remote Extended Features (0x01|0x001c) status 0x00 ncmd 1 > HCI Event: Read Remote Extended Features (0x23) plen 13 status 0x00 handle 50 page 1 max 1 Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 This patch sends mgmt_connected in remote name command status only if conn->state is BT_CONFIG Signed-off-by: Jaganath Kanakkassery Signed-off-by: Johan Hedberg --- net/bluetooth/hci_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5e7be804c709..68c882fd20fd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1581,7 +1581,8 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, struct discovery_state *discov = &hdev->discovery; struct inquiry_entry *e; - if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) + if (conn && conn->state == BT_CONFIG && + !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, conn, 0, name, name_len); if (discov->state == DISCOVERY_STOPPED) -- GitLab From 7fe8c7778f7382400544a5a4252a07b5c093d187 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Tue, 2 Sep 2014 10:56:46 +0800 Subject: [PATCH 3616/9457] drm/panel: simple: Update Innolux N116BGE timings There are several different models of N116BGE. According to commit 0a2288c06aab ("drm/panel: simple: Add Innolux N116BGE panel support"), the video timings are for the eDP variant. The clock and htotal values added by that patch are out of spec according to the datasheets I have seen for the eDP N116BGE (-EA2 and -EB2). This patch changes the values to the "Typ" values on the datasheet. Signed-off-by: Daniel Kurtz [tested that these timings work with the Tegra132 Norrin panel] Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-simple.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 965114b7d6bf..ce4eb25687d7 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -630,15 +630,15 @@ static const struct panel_desc innolux_g121i1_l01 = { }; static const struct drm_display_mode innolux_n116bge_mode = { - .clock = 71000, + .clock = 76420, .hdisplay = 1366, - .hsync_start = 1366 + 64, - .hsync_end = 1366 + 64 + 6, - .htotal = 1366 + 64 + 6 + 64, + .hsync_start = 1366 + 136, + .hsync_end = 1366 + 136 + 30, + .htotal = 1366 + 136 + 30 + 60, .vdisplay = 768, .vsync_start = 768 + 8, - .vsync_end = 768 + 8 + 4, - .vtotal = 768 + 8 + 4 + 8, + .vsync_end = 768 + 8 + 12, + .vtotal = 768 + 8 + 12 + 12, .vrefresh = 60, .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, }; -- GitLab From eccda2d1e1848f215a6c7be4833ca1139e5ffd92 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 7 Nov 2014 14:41:05 +0100 Subject: [PATCH 3617/9457] drm/panel: ld9040: Fix build warnings on 64-bit The %* format specifier expects an integer, which works fine with size_t arguments on 32-bit because the types match. However on 64-bit, size_t is typedef'd to unsigned long and will cause a build warning. Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-ld9040.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ld9040.c b/drivers/gpu/drm/panel/panel-ld9040.c index dd1d3f2e624e..08cf2c588c3d 100644 --- a/drivers/gpu/drm/panel/panel-ld9040.c +++ b/drivers/gpu/drm/panel/panel-ld9040.c @@ -145,7 +145,7 @@ static void ld9040_dcs_write(struct ld9040 *ctx, const u8 *data, size_t len) if (ctx->error < 0 || len == 0) return; - dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", len, data); + dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data); ret = ld9040_spi_write_word(ctx, *data); while (!ret && --len) { @@ -154,8 +154,8 @@ static void ld9040_dcs_write(struct ld9040 *ctx, const u8 *data, size_t len) } if (ret) { - dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, len, - data); + dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, + (int)len, data); ctx->error = ret; } -- GitLab From d85a1609e62c22730aa4e3ef09884f04606b086e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 7 Nov 2014 14:42:16 +0100 Subject: [PATCH 3618/9457] drm/panel: s6e8aa0: Fix build warnings on 64-bit The %* format specifier expects an integer, which works fine with size_t arguments on 32-bit because the types match. However on 64-bit, size_t is typedef'd to unsigned long and will cause a build warning. Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-s6e8aa0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c index 6427aa187735..96f4476609b0 100644 --- a/drivers/gpu/drm/panel/panel-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c @@ -143,8 +143,8 @@ static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len) ret = mipi_dsi_dcs_write(dsi, data, len); if (ret < 0) { - dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, len, - data); + dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, + (int)len, data); ctx->error = ret; } } -- GitLab From f2c7648d91205f4200d3b5c76a8c18d426714d9e Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Tue, 28 Oct 2014 10:14:47 +0800 Subject: [PATCH 3619/9457] kvm: x86: vmx: move down hardware_setup() and hardware_unsetup() Just move this pair of functions down to make sure later we can add something dependent on others. Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 140 ++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 0cd99d8405f8..576b01b7b658 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3110,76 +3110,6 @@ static __init int alloc_kvm_area(void) return 0; } -static __init int hardware_setup(void) -{ - if (setup_vmcs_config(&vmcs_config) < 0) - return -EIO; - - if (boot_cpu_has(X86_FEATURE_NX)) - kvm_enable_efer_bits(EFER_NX); - - if (!cpu_has_vmx_vpid()) - enable_vpid = 0; - if (!cpu_has_vmx_shadow_vmcs()) - enable_shadow_vmcs = 0; - if (enable_shadow_vmcs) - init_vmcs_shadow_fields(); - - if (!cpu_has_vmx_ept() || - !cpu_has_vmx_ept_4levels()) { - enable_ept = 0; - enable_unrestricted_guest = 0; - enable_ept_ad_bits = 0; - } - - if (!cpu_has_vmx_ept_ad_bits()) - enable_ept_ad_bits = 0; - - if (!cpu_has_vmx_unrestricted_guest()) - enable_unrestricted_guest = 0; - - if (!cpu_has_vmx_flexpriority()) { - flexpriority_enabled = 0; - - /* - * set_apic_access_page_addr() is used to reload apic access - * page upon invalidation. No need to do anything if the - * processor does not have the APIC_ACCESS_ADDR VMCS field. - */ - kvm_x86_ops->set_apic_access_page_addr = NULL; - } - - if (!cpu_has_vmx_tpr_shadow()) - kvm_x86_ops->update_cr8_intercept = NULL; - - if (enable_ept && !cpu_has_vmx_ept_2m_page()) - kvm_disable_largepages(); - - if (!cpu_has_vmx_ple()) - ple_gap = 0; - - if (!cpu_has_vmx_apicv()) - enable_apicv = 0; - - if (enable_apicv) - kvm_x86_ops->update_cr8_intercept = NULL; - else { - kvm_x86_ops->hwapic_irr_update = NULL; - kvm_x86_ops->deliver_posted_interrupt = NULL; - kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; - } - - if (nested) - nested_vmx_setup_ctls_msrs(); - - return alloc_kvm_area(); -} - -static __exit void hardware_unsetup(void) -{ - free_kvm_area(); -} - static bool emulation_required(struct kvm_vcpu *vcpu) { return emulate_invalid_guest_state && !guest_state_valid(vcpu); @@ -5788,6 +5718,76 @@ static void update_ple_window_actual_max(void) ple_window_grow, INT_MIN); } +static __init int hardware_setup(void) +{ + if (setup_vmcs_config(&vmcs_config) < 0) + return -EIO; + + if (boot_cpu_has(X86_FEATURE_NX)) + kvm_enable_efer_bits(EFER_NX); + + if (!cpu_has_vmx_vpid()) + enable_vpid = 0; + if (!cpu_has_vmx_shadow_vmcs()) + enable_shadow_vmcs = 0; + if (enable_shadow_vmcs) + init_vmcs_shadow_fields(); + + if (!cpu_has_vmx_ept() || + !cpu_has_vmx_ept_4levels()) { + enable_ept = 0; + enable_unrestricted_guest = 0; + enable_ept_ad_bits = 0; + } + + if (!cpu_has_vmx_ept_ad_bits()) + enable_ept_ad_bits = 0; + + if (!cpu_has_vmx_unrestricted_guest()) + enable_unrestricted_guest = 0; + + if (!cpu_has_vmx_flexpriority()) { + flexpriority_enabled = 0; + + /* + * set_apic_access_page_addr() is used to reload apic access + * page upon invalidation. No need to do anything if the + * processor does not have the APIC_ACCESS_ADDR VMCS field. + */ + kvm_x86_ops->set_apic_access_page_addr = NULL; + } + + if (!cpu_has_vmx_tpr_shadow()) + kvm_x86_ops->update_cr8_intercept = NULL; + + if (enable_ept && !cpu_has_vmx_ept_2m_page()) + kvm_disable_largepages(); + + if (!cpu_has_vmx_ple()) + ple_gap = 0; + + if (!cpu_has_vmx_apicv()) + enable_apicv = 0; + + if (enable_apicv) + kvm_x86_ops->update_cr8_intercept = NULL; + else { + kvm_x86_ops->hwapic_irr_update = NULL; + kvm_x86_ops->deliver_posted_interrupt = NULL; + kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; + } + + if (nested) + nested_vmx_setup_ctls_msrs(); + + return alloc_kvm_area(); +} + +static __exit void hardware_unsetup(void) +{ + free_kvm_area(); +} + /* * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE * exiting, so only get here on cpu with PAUSE-Loop-Exiting. -- GitLab From 34a1cd60d17f62c1f077c1478a6c2ca8c3d17af4 Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Tue, 28 Oct 2014 10:14:48 +0800 Subject: [PATCH 3620/9457] kvm: x86: vmx: move some vmx setting from vmx_init() to hardware_setup() Instead of vmx_init(), actually it would make reasonable sense to do anything specific to vmx hardware setting in vmx_x86_ops->hardware_setup(). Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 267 ++++++++++++++++++++++----------------------- 1 file changed, 133 insertions(+), 134 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 576b01b7b658..12f6f9a8dd8d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5720,8 +5720,108 @@ static void update_ple_window_actual_max(void) static __init int hardware_setup(void) { - if (setup_vmcs_config(&vmcs_config) < 0) - return -EIO; + int r = -ENOMEM, i, msr; + + rdmsrl_safe(MSR_EFER, &host_efer); + + for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) + kvm_define_shared_msr(i, vmx_msr_index[i]); + + vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_io_bitmap_a) + return r; + + vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_io_bitmap_b) + goto out; + + vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_msr_bitmap_legacy) + goto out1; + + vmx_msr_bitmap_legacy_x2apic = + (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_msr_bitmap_legacy_x2apic) + goto out2; + + vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_msr_bitmap_longmode) + goto out3; + + vmx_msr_bitmap_longmode_x2apic = + (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_msr_bitmap_longmode_x2apic) + goto out4; + vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_vmread_bitmap) + goto out5; + + vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_vmwrite_bitmap) + goto out6; + + memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); + memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); + + /* + * Allow direct access to the PC debug port (it is often used for I/O + * delays, but the vmexits simply slow things down). + */ + memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); + clear_bit(0x80, vmx_io_bitmap_a); + + memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); + + memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); + memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); + + vmx_disable_intercept_for_msr(MSR_FS_BASE, false); + vmx_disable_intercept_for_msr(MSR_GS_BASE, false); + vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); + vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); + vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); + vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); + vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); + + memcpy(vmx_msr_bitmap_legacy_x2apic, + vmx_msr_bitmap_legacy, PAGE_SIZE); + memcpy(vmx_msr_bitmap_longmode_x2apic, + vmx_msr_bitmap_longmode, PAGE_SIZE); + + if (enable_apicv) { + for (msr = 0x800; msr <= 0x8ff; msr++) + vmx_disable_intercept_msr_read_x2apic(msr); + + /* According SDM, in x2apic mode, the whole id reg is used. + * But in KVM, it only use the highest eight bits. Need to + * intercept it */ + vmx_enable_intercept_msr_read_x2apic(0x802); + /* TMCCT */ + vmx_enable_intercept_msr_read_x2apic(0x839); + /* TPR */ + vmx_disable_intercept_msr_write_x2apic(0x808); + /* EOI */ + vmx_disable_intercept_msr_write_x2apic(0x80b); + /* SELF-IPI */ + vmx_disable_intercept_msr_write_x2apic(0x83f); + } + + if (enable_ept) { + kvm_mmu_set_mask_ptes(0ull, + (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, + (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull, + 0ull, VMX_EPT_EXECUTABLE_MASK); + ept_set_mmio_spte_mask(); + kvm_enable_tdp(); + } else + kvm_disable_tdp(); + + update_ple_window_actual_max(); + + if (setup_vmcs_config(&vmcs_config) < 0) { + r = -EIO; + goto out7; + } if (boot_cpu_has(X86_FEATURE_NX)) kvm_enable_efer_bits(EFER_NX); @@ -5781,10 +5881,38 @@ static __init int hardware_setup(void) nested_vmx_setup_ctls_msrs(); return alloc_kvm_area(); + +out7: + free_page((unsigned long)vmx_vmwrite_bitmap); +out6: + free_page((unsigned long)vmx_vmread_bitmap); +out5: + free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); +out4: + free_page((unsigned long)vmx_msr_bitmap_longmode); +out3: + free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); +out2: + free_page((unsigned long)vmx_msr_bitmap_legacy); +out1: + free_page((unsigned long)vmx_io_bitmap_b); +out: + free_page((unsigned long)vmx_io_bitmap_a); + + return r; } static __exit void hardware_unsetup(void) { + free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); + free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); + free_page((unsigned long)vmx_msr_bitmap_legacy); + free_page((unsigned long)vmx_msr_bitmap_longmode); + free_page((unsigned long)vmx_io_bitmap_b); + free_page((unsigned long)vmx_io_bitmap_a); + free_page((unsigned long)vmx_vmwrite_bitmap); + free_page((unsigned long)vmx_vmread_bitmap); + free_kvm_area(); } @@ -9187,150 +9315,21 @@ static struct kvm_x86_ops vmx_x86_ops = { static int __init vmx_init(void) { - int r, i, msr; - - rdmsrl_safe(MSR_EFER, &host_efer); - - for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) - kvm_define_shared_msr(i, vmx_msr_index[i]); - - vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_io_bitmap_a) - return -ENOMEM; - - r = -ENOMEM; - - vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_io_bitmap_b) - goto out; - - vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_msr_bitmap_legacy) - goto out1; - - vmx_msr_bitmap_legacy_x2apic = - (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_msr_bitmap_legacy_x2apic) - goto out2; - - vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_msr_bitmap_longmode) - goto out3; - - vmx_msr_bitmap_longmode_x2apic = - (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_msr_bitmap_longmode_x2apic) - goto out4; - vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_vmread_bitmap) - goto out5; - - vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!vmx_vmwrite_bitmap) - goto out6; - - memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); - memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); - - /* - * Allow direct access to the PC debug port (it is often used for I/O - * delays, but the vmexits simply slow things down). - */ - memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); - clear_bit(0x80, vmx_io_bitmap_a); - - memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); - - memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); - memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); - - set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ - - r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), - __alignof__(struct vcpu_vmx), THIS_MODULE); + int r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx), + __alignof__(struct vcpu_vmx), THIS_MODULE); if (r) - goto out7; + return r; #ifdef CONFIG_KEXEC rcu_assign_pointer(crash_vmclear_loaded_vmcss, crash_vmclear_local_loaded_vmcss); #endif - vmx_disable_intercept_for_msr(MSR_FS_BASE, false); - vmx_disable_intercept_for_msr(MSR_GS_BASE, false); - vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); - vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); - vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); - vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); - vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); - - memcpy(vmx_msr_bitmap_legacy_x2apic, - vmx_msr_bitmap_legacy, PAGE_SIZE); - memcpy(vmx_msr_bitmap_longmode_x2apic, - vmx_msr_bitmap_longmode, PAGE_SIZE); - - if (enable_apicv) { - for (msr = 0x800; msr <= 0x8ff; msr++) - vmx_disable_intercept_msr_read_x2apic(msr); - - /* According SDM, in x2apic mode, the whole id reg is used. - * But in KVM, it only use the highest eight bits. Need to - * intercept it */ - vmx_enable_intercept_msr_read_x2apic(0x802); - /* TMCCT */ - vmx_enable_intercept_msr_read_x2apic(0x839); - /* TPR */ - vmx_disable_intercept_msr_write_x2apic(0x808); - /* EOI */ - vmx_disable_intercept_msr_write_x2apic(0x80b); - /* SELF-IPI */ - vmx_disable_intercept_msr_write_x2apic(0x83f); - } - - if (enable_ept) { - kvm_mmu_set_mask_ptes(0ull, - (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, - (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull, - 0ull, VMX_EPT_EXECUTABLE_MASK); - ept_set_mmio_spte_mask(); - kvm_enable_tdp(); - } else - kvm_disable_tdp(); - - update_ple_window_actual_max(); - return 0; - -out7: - free_page((unsigned long)vmx_vmwrite_bitmap); -out6: - free_page((unsigned long)vmx_vmread_bitmap); -out5: - free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); -out4: - free_page((unsigned long)vmx_msr_bitmap_longmode); -out3: - free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); -out2: - free_page((unsigned long)vmx_msr_bitmap_legacy); -out1: - free_page((unsigned long)vmx_io_bitmap_b); -out: - free_page((unsigned long)vmx_io_bitmap_a); - return r; } static void __exit vmx_exit(void) { - free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); - free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); - free_page((unsigned long)vmx_msr_bitmap_legacy); - free_page((unsigned long)vmx_msr_bitmap_longmode); - free_page((unsigned long)vmx_io_bitmap_b); - free_page((unsigned long)vmx_io_bitmap_a); - free_page((unsigned long)vmx_vmwrite_bitmap); - free_page((unsigned long)vmx_vmread_bitmap); - #ifdef CONFIG_KEXEC RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); synchronize_rcu(); -- GitLab From a2ae9df7c991eca6c1ee6f42dbb18701a64175c3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 4 Nov 2014 18:31:19 +0100 Subject: [PATCH 3621/9457] kvm: x86: vmx: avoid returning bool to distinguish success from error Return a negative error code instead, and WARN() when we should be covering the entire 2-bit space of vmcs_field_type's return value. For increased robustness, add a BUILD_BUG_ON checking the range of vmcs_field_to_offset. Suggested-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 53 ++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 12f6f9a8dd8d..d6e3ddace074 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -720,12 +720,15 @@ static const unsigned short vmcs_field_to_offset_table[] = { FIELD(HOST_RSP, host_rsp), FIELD(HOST_RIP, host_rip), }; -static const int max_vmcs_field = ARRAY_SIZE(vmcs_field_to_offset_table); static inline short vmcs_field_to_offset(unsigned long field) { - if (field >= max_vmcs_field || vmcs_field_to_offset_table[field] == 0) - return -1; + BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); + + if (field >= ARRAY_SIZE(vmcs_field_to_offset_table) || + vmcs_field_to_offset_table[field] == 0) + return -ENOENT; + return vmcs_field_to_offset_table[field]; } @@ -6492,58 +6495,60 @@ static inline int vmcs_field_readonly(unsigned long field) * some of the bits we return here (e.g., on 32-bit guests, only 32 bits of * 64-bit fields are to be returned). */ -static inline bool vmcs12_read_any(struct kvm_vcpu *vcpu, - unsigned long field, u64 *ret) +static inline int vmcs12_read_any(struct kvm_vcpu *vcpu, + unsigned long field, u64 *ret) { short offset = vmcs_field_to_offset(field); char *p; if (offset < 0) - return 0; + return offset; p = ((char *)(get_vmcs12(vcpu))) + offset; switch (vmcs_field_type(field)) { case VMCS_FIELD_TYPE_NATURAL_WIDTH: *ret = *((natural_width *)p); - return 1; + return 0; case VMCS_FIELD_TYPE_U16: *ret = *((u16 *)p); - return 1; + return 0; case VMCS_FIELD_TYPE_U32: *ret = *((u32 *)p); - return 1; + return 0; case VMCS_FIELD_TYPE_U64: *ret = *((u64 *)p); - return 1; + return 0; default: - return 0; /* can never happen. */ + WARN_ON(1); + return -ENOENT; } } -static inline bool vmcs12_write_any(struct kvm_vcpu *vcpu, - unsigned long field, u64 field_value){ +static inline int vmcs12_write_any(struct kvm_vcpu *vcpu, + unsigned long field, u64 field_value){ short offset = vmcs_field_to_offset(field); char *p = ((char *) get_vmcs12(vcpu)) + offset; if (offset < 0) - return false; + return offset; switch (vmcs_field_type(field)) { case VMCS_FIELD_TYPE_U16: *(u16 *)p = field_value; - return true; + return 0; case VMCS_FIELD_TYPE_U32: *(u32 *)p = field_value; - return true; + return 0; case VMCS_FIELD_TYPE_U64: *(u64 *)p = field_value; - return true; + return 0; case VMCS_FIELD_TYPE_NATURAL_WIDTH: *(natural_width *)p = field_value; - return true; + return 0; default: - return false; /* can never happen. */ + WARN_ON(1); + return -ENOENT; } } @@ -6576,6 +6581,9 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) case VMCS_FIELD_TYPE_NATURAL_WIDTH: field_value = vmcs_readl(field); break; + default: + WARN_ON(1); + continue; } vmcs12_write_any(&vmx->vcpu, field, field_value); } @@ -6621,6 +6629,9 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) case VMCS_FIELD_TYPE_NATURAL_WIDTH: vmcs_writel(field, (long)field_value); break; + default: + WARN_ON(1); + break; } } } @@ -6659,7 +6670,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) /* Decode instruction info and find the field to read */ field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); /* Read the field, zero-extended to a u64 field_value */ - if (!vmcs12_read_any(vcpu, field, &field_value)) { + if (vmcs12_read_any(vcpu, field, &field_value) < 0) { nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); skip_emulated_instruction(vcpu); return 1; @@ -6729,7 +6740,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) return 1; } - if (!vmcs12_write_any(vcpu, field, field_value)) { + if (vmcs12_write_any(vcpu, field, field_value) < 0) { nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); skip_emulated_instruction(vcpu); return 1; -- GitLab From 4114c27d450bef228be9c7b0c40a888e18a3a636 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 5 Nov 2014 10:53:43 +0800 Subject: [PATCH 3622/9457] KVM: x86: reset RVI upon system reset A bug was reported as follows: when running Windows 7 32-bit guests on qemu-kvm, sometimes the guests run into blue screen during reboot. The problem was that a guest's RVI was not cleared when it rebooted. This patch has fixed the problem. Signed-off-by: Wei Wang Signed-off-by: Yang Zhang Tested-by: Rongrong Liu , Da Chun Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 3 +++ arch/x86/kvm/vmx.c | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 5f574b4add90..e7f7fc632a9b 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1714,6 +1714,9 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? 1 : count_vectors(apic->regs + APIC_ISR); apic->highest_isr_cache = -1; + if (kvm_x86_ops->hwapic_irr_update) + kvm_x86_ops->hwapic_irr_update(vcpu, + apic_find_highest_irr(apic)); kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); kvm_make_request(KVM_REQ_EVENT, vcpu); kvm_rtc_eoi_tracking_restore_one(vcpu); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d6e3ddace074..f9d56c1945de 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -7419,6 +7419,9 @@ static void vmx_set_rvi(int vector) u16 status; u8 old; + if (vector == -1) + vector = 0; + status = vmcs_read16(GUEST_INTR_STATUS); old = (u8)status & 0xff; if ((u8)vector != old) { @@ -7430,22 +7433,23 @@ static void vmx_set_rvi(int vector) static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) { + if (!is_guest_mode(vcpu)) { + vmx_set_rvi(max_irr); + return; + } + if (max_irr == -1) return; /* - * If a vmexit is needed, vmx_check_nested_events handles it. + * In guest mode. If a vmexit is needed, vmx_check_nested_events + * handles it. */ - if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) + if (nested_exit_on_intr(vcpu)) return; - if (!is_guest_mode(vcpu)) { - vmx_set_rvi(max_irr); - return; - } - /* - * Fall back to pre-APICv interrupt injection since L2 + * Else, fall back to pre-APICv interrupt injection since L2 * is run without virtual interrupt delivery. */ if (!kvm_event_needs_reinjection(vcpu) && -- GitLab From 5b38ab877e5bd6c6564f2f23f25e0c3d4768728a Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:41 +0200 Subject: [PATCH 3623/9457] KVM: x86: decode_modrm does not regard modrm correctly In one occassion, decode_modrm uses the rm field after it is extended with REX.B to determine the addressing mode. Doing so causes it not to read the offset for rip-relative addressing with REX.B=1. This patch moves the fetch where we already mask REX.B away instead. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index cd2029bbab48..a4703eb9c1ed 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1223,6 +1223,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, if (index_reg != 4) modrm_ea += reg_read(ctxt, index_reg) << scale; } else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) { + modrm_ea += insn_fetch(s32, ctxt); if (ctxt->mode == X86EMUL_MODE_PROT64) ctxt->rip_relative = 1; } else { @@ -1231,10 +1232,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, adjust_modrm_seg(ctxt, base_reg); } switch (ctxt->modrm_mod) { - case 0: - if (ctxt->modrm_rm == 5) - modrm_ea += insn_fetch(s32, ctxt); - break; case 1: modrm_ea += insn_fetch(s8, ctxt); break; -- GitLab From 3ffb24681cc46f869378a4de54615db8d4ef0daf Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:42 +0200 Subject: [PATCH 3624/9457] KVM: x86: No error-code on real-mode exceptions Real-mode exceptions do not deliver error code. As can be seen in Intel SDM volume 2, real-mode exceptions do not have parentheses, which indicate error-code. To avoid significant changes of the code, the error code is "removed" during exception queueing. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 14c49cf3f77f..e8850295031f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -353,6 +353,8 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, if (!vcpu->arch.exception.pending) { queue: + if (has_error && !is_protmode(vcpu)) + has_error = false; vcpu->arch.exception.pending = true; vcpu->arch.exception.has_error_code = has_error; vcpu->arch.exception.nr = nr; -- GitLab From 6d2a0526b09e551d0f395cfb63e7cb965db825af Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:43 +0200 Subject: [PATCH 3625/9457] KVM: x86: Emulator should set DR6 upon GD like real CPU It should clear B0-B3 and set BD. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a4703eb9c1ed..736a49f218ff 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3588,8 +3588,15 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt) if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5)) return emulate_ud(ctxt); - if (check_dr7_gd(ctxt)) + if (check_dr7_gd(ctxt)) { + ulong dr6; + + ctxt->ops->get_dr(ctxt, 6, &dr6); + dr6 &= ~15; + dr6 |= DR6_BD | DR6_RTM; + ctxt->ops->set_dr(ctxt, 6, dr6); return emulate_db(ctxt); + } return X86EMUL_CONTINUE; } -- GitLab From 7305eb5d8cf147ce4178e723c95de15e2f001429 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:44 +0200 Subject: [PATCH 3626/9457] KVM: x86: Clear DR6[0:3] on #DB during handle_dr DR6[0:3] (previous breakpoint indications) are cleared when #DB is injected during handle_exception, just as real hardware does. Similarily, handle_dr should clear DR6[0:3]. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f9d56c1945de..ad5e0806e1e1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5125,6 +5125,7 @@ static int handle_dr(struct kvm_vcpu *vcpu) vcpu->run->exit_reason = KVM_EXIT_DEBUG; return 0; } else { + vcpu->arch.dr6 &= ~15; vcpu->arch.dr6 |= DR6_BD | DR6_RTM; kvm_queue_exception(vcpu, DB_VECTOR); return 1; -- GitLab From 82b32774c2d00c0a12ab182c67e32e0b5e5e580a Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:45 +0200 Subject: [PATCH 3627/9457] KVM: x86: Breakpoints do not consider CS.base x86 debug registers hold a linear address. Therefore, breakpoints detection should consider CS.base, and check whether instruction linear address equals (CS.base + RIP). This patch introduces a function to evaluate RIP linear address and uses it for breakpoints detection. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/vmx.c | 4 +--- arch/x86/kvm/x86.c | 29 ++++++++++++++++------------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3ac807646911..904535fe825e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1067,6 +1067,7 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, void kvm_define_shared_msr(unsigned index, u32 msr); int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); +unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu); bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad5e0806e1e1..284f5c2fdf0b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5118,9 +5118,7 @@ static int handle_dr(struct kvm_vcpu *vcpu) if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { vcpu->run->debug.arch.dr6 = vcpu->arch.dr6; vcpu->run->debug.arch.dr7 = dr7; - vcpu->run->debug.arch.pc = - vmcs_readl(GUEST_CS_BASE) + - vmcs_readl(GUEST_RIP); + vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu); vcpu->run->debug.arch.exception = DB_VECTOR; vcpu->run->exit_reason = KVM_EXIT_DEBUG; return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e8850295031f..773c17ec42dd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5207,21 +5207,17 @@ static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, unsigned long rflag static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) { - struct kvm_run *kvm_run = vcpu->run; - unsigned long eip = vcpu->arch.emulate_ctxt.eip; - u32 dr6 = 0; - if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) && (vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) { - dr6 = kvm_vcpu_check_hw_bp(eip, 0, + struct kvm_run *kvm_run = vcpu->run; + unsigned long eip = kvm_get_linear_rip(vcpu); + u32 dr6 = kvm_vcpu_check_hw_bp(eip, 0, vcpu->arch.guest_debug_dr7, vcpu->arch.eff_db); if (dr6 != 0) { kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM; - kvm_run->debug.arch.pc = kvm_rip_read(vcpu) + - get_segment_base(vcpu, VCPU_SREG_CS); - + kvm_run->debug.arch.pc = eip; kvm_run->debug.arch.exception = DB_VECTOR; kvm_run->exit_reason = KVM_EXIT_DEBUG; *r = EMULATE_USER_EXIT; @@ -5231,7 +5227,8 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) if (unlikely(vcpu->arch.dr7 & DR7_BP_EN_MASK) && !(kvm_get_rflags(vcpu) & X86_EFLAGS_RF)) { - dr6 = kvm_vcpu_check_hw_bp(eip, 0, + unsigned long eip = kvm_get_linear_rip(vcpu); + u32 dr6 = kvm_vcpu_check_hw_bp(eip, 0, vcpu->arch.dr7, vcpu->arch.db); @@ -7538,12 +7535,18 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) return kvm_x86_ops->interrupt_allowed(vcpu); } -bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) +unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu) { - unsigned long current_rip = kvm_rip_read(vcpu) + - get_segment_base(vcpu, VCPU_SREG_CS); + if (is_64_bit_mode(vcpu)) + return kvm_rip_read(vcpu); + return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) + + kvm_rip_read(vcpu)); +} +EXPORT_SYMBOL_GPL(kvm_get_linear_rip); - return current_rip == linear_rip; +bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) +{ + return kvm_get_linear_rip(vcpu) == linear_rip; } EXPORT_SYMBOL_GPL(kvm_is_linear_rip); -- GitLab From b5bbf10ee6b65b70c10c139822bc2dc077cefa76 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:46 +0200 Subject: [PATCH 3628/9457] KVM: x86: Emulation of MOV-sreg to memory uses incorrect size In x86, you can only MOV-sreg to memory with either 16-bits or 64-bits size. In contrast, KVM may write to 32-bits memory on MOV-sreg. This patch fixes KVM behavior, and sets the destination operand size to two, if the destination is memory. When destination is registers, and the operand size is 32-bits, the high 16-bits in modern CPUs is filled with zero. This is handled correctly. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 736a49f218ff..713295d913fd 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3207,6 +3207,8 @@ static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) return emulate_ud(ctxt); ctxt->dst.val = get_segment_selector(ctxt, ctxt->modrm_reg); + if (ctxt->dst.bytes == 4 && ctxt->dst.type == OP_MEM) + ctxt->dst.bytes = 2; return X86EMUL_CONTINUE; } -- GitLab From 807c142595abcb99285746bd5512447bdf40b9b1 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:49 +0200 Subject: [PATCH 3629/9457] KVM: x86: SYSCALL cannot clear eflags[1] SYSCALL emulation currently clears in 64-bit mode eflags according to MSR_SYSCALL_MASK. However, on bare-metal eflags[1] which is fixed to one cannot be cleared, even if MSR_SYSCALL_MASK masks the bit. This wrong behavior may result in failed VM-entry, as VT disallows entry with eflags[1] cleared. This patch sets the bit after masking eflags on syscall. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 713295d913fd..e475cdff15e1 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2306,6 +2306,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); ctxt->eflags &= ~msr_data; + ctxt->eflags |= EFLG_RESERVED_ONE_MASK; #endif } else { /* legacy mode */ -- GitLab From 5aca3722362689a679419dc9b3e426921c70ef16 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:50 +0200 Subject: [PATCH 3630/9457] KVM: x86: Wrong flags on CMPS and SCAS emulation CMPS and SCAS instructions are evaluated in the wrong order. For reference (of CMPS), see http://www.fermimn.gov.it/linux/quarta/x86/cmps.htm : "Note that the direction of subtraction for CMPS is [SI] - [DI] or [ESI] - [EDI]. The left operand (SI or ESI) is the source and the right operand (DI or EDI) is the destination. This is the reverse of the usual Intel convention in which the left operand is the destination and the right operand is the source." Introducing em_cmp_r for this matter that performs comparison in reverse order using fastop infrastructure to avoid a wrapper function. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e475cdff15e1..7aba1db168c9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -380,6 +380,15 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); ON64(FOP2E(op##q, rax, cl)) \ FOP_END +/* 2 operand, src and dest are reversed */ +#define FASTOP2R(op, name) \ + FOP_START(name) \ + FOP2E(op##b, dl, al) \ + FOP2E(op##w, dx, ax) \ + FOP2E(op##l, edx, eax) \ + ON64(FOP2E(op##q, rdx, rax)) \ + FOP_END + #define FOP3E(op, dst, src, src2) \ FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET @@ -913,6 +922,8 @@ FASTOP2W(btc); FASTOP2(xadd); +FASTOP2R(cmp, cmp_r); + static u8 test_cc(unsigned int condition, unsigned long flags) { u8 rc; @@ -3993,12 +4004,12 @@ static const struct opcode opcode_table[256] = { I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov), I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov), I2bv(SrcSI | DstDI | Mov | String, em_mov), - F2bv(SrcSI | DstDI | String | NoWrite, em_cmp), + F2bv(SrcSI | DstDI | String | NoWrite, em_cmp_r), /* 0xA8 - 0xAF */ F2bv(DstAcc | SrcImm | NoWrite, em_test), I2bv(SrcAcc | DstDI | Mov | String, em_mov), I2bv(SrcSI | DstAcc | Mov | String, em_mov), - F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp), + F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r), /* 0xB0 - 0xB7 */ X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)), /* 0xB8 - 0xBF */ -- GitLab From 0fcc207c66a7cff024b05367b86d70d742072d61 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:51 +0200 Subject: [PATCH 3631/9457] KVM: x86: Emulate push sreg as done in Core According to Intel SDM push of segment selectors is done in the following manner: "if the operand size is 32-bits, either a zero-extended value is pushed on the stack or the segment selector is written on the stack using a 16-bit move. For the last case, all recent Core and Atom processors perform a 16-bit move, leaving the upper portion of the stack location unmodified." This patch modifies the behavior to match the core behavior. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7aba1db168c9..a2a9c18b42e4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1817,6 +1817,10 @@ static int em_push_sreg(struct x86_emulate_ctxt *ctxt) int seg = ctxt->src2.val; ctxt->src.val = get_segment_selector(ctxt, seg); + if (ctxt->op_bytes == 4) { + rsp_increment(ctxt, -2); + ctxt->op_bytes = 2; + } return em_push(ctxt); } -- GitLab From 9d88fca71a99a65c37cbfe481b4aa4e91a27ff13 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:52 +0200 Subject: [PATCH 3632/9457] KVM: x86: MOV to CR3 can set bit 63 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although Intel SDM mentions bit 63 is reserved, MOV to CR3 can have bit 63 set. As Intel SDM states in section 4.10.4 "Invalidation of TLBs and Paging-Structure Caches": " MOV to CR3. ... If CR4.PCIDE = 1 and bit 63 of the instruction’s source operand is 0 ..." In other words, bit 63 is not reserved. KVM emulator currently consider bit 63 as reserved. Fix it. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/emulate.c | 2 +- arch/x86/kvm/x86.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 904535fe825e..dc932d388c43 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -51,6 +51,7 @@ | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) #define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL +#define CR3_PCID_INVD (1UL << 63) #define CR4_RESERVED_BITS \ (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a2a9c18b42e4..9f960b428bb2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3564,7 +3564,7 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); if (efer & EFER_LMA) - rsvd = CR3_L_MODE_RESERVED_BITS; + rsvd = CR3_L_MODE_RESERVED_BITS & ~CR3_PCID_INVD; if (new_val & rsvd) return emulate_gp(ctxt, 0); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 773c17ec42dd..641358865a0c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -750,6 +750,8 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { + cr3 &= ~CR3_PCID_INVD; + if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { kvm_mmu_sync_roots(vcpu); kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); -- GitLab From 38827dbd3fb85a94a002fcf67b8735d5bc1a7e1a Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:53 +0200 Subject: [PATCH 3633/9457] KVM: x86: Do not update EFLAGS on faulting emulation If the emulation ends in fault, eflags should not be updated. However, several instruction emulations (actually all the fastops) currently update eflags, if the fault was detected afterwards (e.g., #PF during writeback). Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 641358865a0c..da1591eeb477 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5360,7 +5360,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, kvm_rip_write(vcpu, ctxt->eip); if (r == EMULATE_DONE) kvm_vcpu_check_singlestep(vcpu, rflags, &r); - __kvm_set_rflags(vcpu, ctxt->eflags); + if (!ctxt->have_exception || + exception_type(ctxt->exception.vector) == EXCPT_TRAP) + __kvm_set_rflags(vcpu, ctxt->eflags); /* * For STI, interrupts are shadowed; so KVM_REQ_EVENT will -- GitLab From 5b7f6a1e6f6cb6537694a9bbd43bb4ee5a6d8bc2 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:55 +0200 Subject: [PATCH 3634/9457] KVM: x86: Combine the lgdt and lidt emulation logic LGDT and LIDT emulation logic is almost identical. Merge the logic into a single point to avoid redundancy. This will be used by the next patch that will ensure the bases of the loaded GDTR and IDTR are canonical. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 9f960b428bb2..c86b3781fca2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3327,7 +3327,7 @@ static int em_sidt(struct x86_emulate_ctxt *ctxt) return emulate_store_desc_ptr(ctxt, ctxt->ops->get_idt); } -static int em_lgdt(struct x86_emulate_ctxt *ctxt) +static int em_lgdt_lidt(struct x86_emulate_ctxt *ctxt, bool lgdt) { struct desc_ptr desc_ptr; int rc; @@ -3339,12 +3339,20 @@ static int em_lgdt(struct x86_emulate_ctxt *ctxt) ctxt->op_bytes); if (rc != X86EMUL_CONTINUE) return rc; - ctxt->ops->set_gdt(ctxt, &desc_ptr); + if (lgdt) + ctxt->ops->set_gdt(ctxt, &desc_ptr); + else + ctxt->ops->set_idt(ctxt, &desc_ptr); /* Disable writeback. */ ctxt->dst.type = OP_NONE; return X86EMUL_CONTINUE; } +static int em_lgdt(struct x86_emulate_ctxt *ctxt) +{ + return em_lgdt_lidt(ctxt, true); +} + static int em_vmmcall(struct x86_emulate_ctxt *ctxt) { int rc; @@ -3358,20 +3366,7 @@ static int em_vmmcall(struct x86_emulate_ctxt *ctxt) static int em_lidt(struct x86_emulate_ctxt *ctxt) { - struct desc_ptr desc_ptr; - int rc; - - if (ctxt->mode == X86EMUL_MODE_PROT64) - ctxt->op_bytes = 8; - rc = read_descriptor(ctxt, ctxt->src.addr.mem, - &desc_ptr.size, &desc_ptr.address, - ctxt->op_bytes); - if (rc != X86EMUL_CONTINUE) - return rc; - ctxt->ops->set_idt(ctxt, &desc_ptr); - /* Disable writeback. */ - ctxt->dst.type = OP_NONE; - return X86EMUL_CONTINUE; + return em_lgdt_lidt(ctxt, false); } static int em_smsw(struct x86_emulate_ctxt *ctxt) -- GitLab From 9a9abf6b612709f67b9e3852554191541631d075 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:56 +0200 Subject: [PATCH 3635/9457] KVM: x86: Inject #GP when loading system segments with non-canonical base When emulating LTR/LDTR/LGDT/LIDT, #GP should be injected if the base is non-canonical. Otherwise, VM-entry will fail. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c86b3781fca2..fab270801809 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1620,6 +1620,9 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, sizeof(base3), &ctxt->exception); if (ret != X86EMUL_CONTINUE) return ret; + if (is_noncanonical_address(get_desc_base(&seg_desc) | + ((u64)base3 << 32))) + return emulate_gp(ctxt, 0); } load: ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); @@ -3339,6 +3342,9 @@ static int em_lgdt_lidt(struct x86_emulate_ctxt *ctxt, bool lgdt) ctxt->op_bytes); if (rc != X86EMUL_CONTINUE) return rc; + if (ctxt->mode == X86EMUL_MODE_PROT64 && + is_noncanonical_address(desc_ptr.address)) + return emulate_gp(ctxt, 0); if (lgdt) ctxt->ops->set_gdt(ctxt, &desc_ptr); else -- GitLab From 2c2ca2d12f5c7b7a961555029dcddd1154cc98e5 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:57 +0200 Subject: [PATCH 3636/9457] KVM: x86: Remove redundant and incorrect cpl check on task-switch Task-switch emulation checks the privilege level prior to performing the task-switch. This check is incorrect in the case of task-gates, in which the tss.dpl is ignored, and can cause superfluous exceptions. Moreover this check is unnecassary, since the CPU checks the privilege levels prior to exiting. Intel SDM 25.4.2 says "If CALL or JMP accesses a TSS descriptor directly outside IA-32e mode, privilege levels are checked on the TSS descriptor" prior to exiting. AMD 15.14.1 says "The intercept is checked before the task switch takes place but after the incoming TSS and task gate (if one was involved) have been checked for correctness." This patch removes the CPL checks for CALL and JMP. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index fab270801809..765f1897814b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2824,7 +2824,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, * * 1. jmp/call/int to task gate: Check against DPL of the task gate * 2. Exception/IRQ/iret: No check is performed - * 3. jmp/call to TSS: Check against DPL of the TSS + * 3. jmp/call to TSS/task-gate: No check is performed since the + * hardware checks it before exiting. */ if (reason == TASK_SWITCH_GATE) { if (idt_index != -1) { @@ -2841,13 +2842,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, if ((tss_selector & 3) > dpl || ops->cpl(ctxt) > dpl) return emulate_gp(ctxt, (idt_index << 3) | 0x2); } - } else if (reason != TASK_SWITCH_IRET) { - int dpl = next_tss_desc.dpl; - if ((tss_selector & 3) > dpl || ops->cpl(ctxt) > dpl) - return emulate_gp(ctxt, tss_selector); } - desc_limit = desc_limit_scaled(&next_tss_desc); if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || -- GitLab From 44b9683853c7b47d039366d7d2fd0d5380aba276 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 6 Nov 2014 17:30:51 -0800 Subject: [PATCH 3637/9457] HID: wacom - make sure touch_input is valid before using it touch_input is stored in wacom_shared for pen data to report touch switch status. It is possible, although we didn't see it happen on Linux yet, that pen data is procesed before touch interface is fully probed. As a by-product of this patch, it fixes the FreeBSD issue reported by Denis Akiyakov http://www.spinics.net/lists/linux-input/msg33971.html Reviewed-by: Hans Petter Selasky Tested-by: Denis Akiyakov Signed-off-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 586b2405b0d4..d343a6ee5bf7 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1681,7 +1681,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) return 0; if (data[0] == WACOM_REPORT_USB) { - if (features->type == INTUOSHT && features->touch_max) { + if (features->type == INTUOSHT && + wacom->shared->touch_input && + features->touch_max) { input_report_switch(wacom->shared->touch_input, SW_MUTE_DEVICE, data[8] & 0x40); input_sync(wacom->shared->touch_input); @@ -1774,7 +1776,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) int pid, battery, ps_connected; if ((wacom->shared->type == INTUOSHT) && - wacom->shared->touch_max) { + wacom->shared->touch_input && + wacom->shared->touch_max) { input_report_switch(wacom->shared->touch_input, SW_MUTE_DEVICE, data[5] & 0x40); input_sync(wacom->shared->touch_input); -- GitLab From 4ae612a3260336872e4f858d2d226a3721ccfd89 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 7 Nov 2014 00:23:13 -0200 Subject: [PATCH 3638/9457] serial: fsl_lpuart: Remove unneeded check for 'res' 'res' will be automatically checked inside devm_ioremap_resource(), so there is no need to explicitly perform a NULL check. Signed-off-by: Fabio Estevam Acked-by: Jingchang Lu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 4e2577249ac5..73d939c0825a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1786,15 +1786,13 @@ static int lpuart_probe(struct platform_device *pdev) } sport->port.line = ret; sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart"); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - sport->port.mapbase = res->start; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sport->port.membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(sport->port.membase)) return PTR_ERR(sport->port.membase); + sport->port.mapbase = res->start; sport->port.dev = &pdev->dev; sport->port.type = PORT_LPUART; sport->port.iotype = UPIO_MEM; -- GitLab From 144c29ed5fa361b890523358d791e6481d55e5a6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 7 Nov 2014 00:23:14 -0200 Subject: [PATCH 3639/9457] serial: fsl_lpuart: Remove unneeded registration message There is no real value in displaying "serial: Freescale lpuart driver" in every boot. The uart_register_driver() can fail and even so the "serial: Freescale lpuart driver" will be displayed, which is not really helpful. This is particularly annoying when booting multi_v7_defconfig kernel on a SoC that is not a Vybrid/Layerscape and even though this message gets displayed. Signed-off-by: Fabio Estevam Acked-by: Jingchang Lu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 73d939c0825a..4f58077b1413 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1896,11 +1896,8 @@ static struct platform_driver lpuart_driver = { static int __init lpuart_serial_init(void) { - int ret; - - pr_info("serial: Freescale lpuart driver\n"); + int ret = uart_register_driver(&lpuart_reg); - ret = uart_register_driver(&lpuart_reg); if (ret) return ret; -- GitLab From 4c0be45b18a3bd5c215589c4b320648e35024f6e Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:35 +0000 Subject: [PATCH 3640/9457] serial: pl011: Allocate TX DMA buffer from DMA capable memory Allocating with __GFP_DMA avoids the need for bounce buffers Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 83c8f721cdb2..8654049a70c0 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -988,7 +988,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) if (!uap->dmatx.chan) return; - uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL); + uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL | __GFP_DMA); if (!uap->dmatx.buf) { dev_err(uap->port.dev, "no memory for DMA TX buffer\n"); uap->port.fifosize = uap->fifosize; -- GitLab From e2a545a6aee935e44db08797f7155be38f3c18f9 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:39 +0000 Subject: [PATCH 3641/9457] serial: pl011: Avoid assumptions about buffer size when refilling TX DMA The existing code assumed that PL011_DMA_BUFFER_SIZE == UART_XMIT_SIZE, which may not always be the case. This allows for these two being different sizes and not copying too much data. Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8654049a70c0..6153a42d68db 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -501,7 +501,11 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count); else { size_t first = UART_XMIT_SIZE - xmit->tail; - size_t second = xmit->head; + size_t second; + + if (first > count) + first = count; + second = count - first; memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first); if (second) -- GitLab From c64be9231e089350fa55c7e03adc79e341ab8e89 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:43 +0000 Subject: [PATCH 3642/9457] serial: pl011: Set length of DMA transfer The DMA engines on some systems require that the dma_length is set when using scatter gather lists. Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6153a42d68db..55dc00dd0e5e 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -246,6 +246,7 @@ static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, sg_set_page(&sg->sg, phys_to_page(dma_addr), PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); sg_dma_address(&sg->sg) = dma_addr; + sg_dma_len(&sg->sg) = PL011_DMA_BUFFER_SIZE; return 0; } -- GitLab From 2d3b7d6e7dc8785f9a6c0e4d38188dd1a0859d11 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:47 +0000 Subject: [PATCH 3643/9457] serial: pl011: Don't enable RX DMA if residue processing not supported If the DMA engine doesn't support residue processing then the RX DMA handling won't work terribly well if polling is enabled. So, disable RX DMA if residue handling isn't available. Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 55dc00dd0e5e..d984a97043b3 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -322,7 +322,22 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * .src_maxburst = uap->fifosize >> 2, .device_fc = false, }; + struct dma_slave_caps caps; + /* + * Some DMA controllers provide information on their capabilities. + * If the controller does, check for suitable residue processing + * otherwise assime all is well. + */ + if (0 == dma_get_slave_caps(chan, &caps)) { + if (caps.residue_granularity == + DMA_RESIDUE_GRANULARITY_DESCRIPTOR) { + dma_release_channel(chan); + dev_info(uap->port.dev, + "RX DMA disabled - no residue processing\n"); + return; + } + } dmaengine_slave_config(chan, &rx_conf); uap->dmarx.chan = chan; -- GitLab From 98267d33e2da8cd386212856a22f4a64b32834ab Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Fri, 7 Nov 2014 14:14:23 +0000 Subject: [PATCH 3644/9457] serial: pl011: Add device tree support for RX DMA polling Add equivalent attributes to those provided in the platform data for use when RX DMA is enabled. Signed-off-by: Andrew Jackson Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/pl011.txt | 19 ++++++++++------ drivers/tty/serial/amba-pl011.c | 22 ++++++++++++++++--- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/pl011.txt b/Documentation/devicetree/bindings/serial/pl011.txt index 5d2e840ae65c..0e05340055e1 100644 --- a/Documentation/devicetree/bindings/serial/pl011.txt +++ b/Documentation/devicetree/bindings/serial/pl011.txt @@ -6,12 +6,17 @@ Required properties: - interrupts: exactly one interrupt specifier Optional properties: -- pinctrl: When present, must have one state named "sleep" - and one state named "default" -- clocks: When present, must refer to exactly one clock named - "apb_pclk" -- dmas: When present, may have one or two dma channels. - The first one must be named "rx", the second one - must be named "tx". +- pinctrl: When present, must have one state named "sleep" + and one state named "default" +- clocks: When present, must refer to exactly one clock named + "apb_pclk" +- dmas: When present, may have one or two dma channels. + The first one must be named "rx", the second one + must be named "tx". +- auto-poll: Enables polling when using RX DMA. +- poll-rate-ms: Rate at which poll occurs when auto-poll is set, + default 100ms. +- poll-timeout-ms: Poll timeout when auto-poll is set, default + 3000ms. See also bindings/arm/primecell.txt diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d984a97043b3..8d94c194f090 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -341,6 +341,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * dmaengine_slave_config(chan, &rx_conf); uap->dmarx.chan = chan; + uap->dmarx.auto_poll_rate = false; if (plat && plat->dma_rx_poll_enable) { /* Set poll rate if specified. */ if (plat->dma_rx_poll_rate) { @@ -361,9 +362,24 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * plat->dma_rx_poll_timeout; else uap->dmarx.poll_timeout = 3000; - } else - uap->dmarx.auto_poll_rate = false; - + } else if (!plat && dev->of_node) { + uap->dmarx.auto_poll_rate = of_property_read_bool( + dev->of_node, "auto-poll"); + if (uap->dmarx.auto_poll_rate) { + u32 x; + + if (0 == of_property_read_u32(dev->of_node, + "poll-rate-ms", &x)) + uap->dmarx.poll_rate = x; + else + uap->dmarx.poll_rate = 100; + if (0 == of_property_read_u32(dev->of_node, + "poll-timeout-ms", &x)) + uap->dmarx.poll_timeout = x; + else + uap->dmarx.poll_timeout = 3000; + } + } dev_info(uap->port.dev, "DMA channel RX %s\n", dma_chan_name(uap->dmarx.chan)); } -- GitLab From 1d53a3a7d3b886bcc60b90e41693b82a791c25ba Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Fri, 7 Nov 2014 09:52:22 -0700 Subject: [PATCH 3645/9457] vfio: make vfio run on s390 add Kconfig switch to hide INTx add Kconfig switch to let vfio announce PCI BARs are not mapable Signed-off-by: Frank Blaschka Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 2 +- drivers/vfio/pci/Kconfig | 8 ++++++++ drivers/vfio/pci/vfio_pci.c | 5 +++-- drivers/vfio/pci/vfio_pci_config.c | 7 +++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index d8c57636b9ce..b93c25901e89 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -16,7 +16,7 @@ config VFIO_SPAPR_EEH menuconfig VFIO tristate "VFIO Non-Privileged userspace driver framework" depends on IOMMU_API - select VFIO_IOMMU_TYPE1 if X86 + select VFIO_IOMMU_TYPE1 if (X86 || S390) select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES) select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES) select ANON_INODES diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig index c41b01e2b693..c6bb5da2d2a7 100644 --- a/drivers/vfio/pci/Kconfig +++ b/drivers/vfio/pci/Kconfig @@ -16,3 +16,11 @@ config VFIO_PCI_VGA BIOS and generic video drivers. If you don't know what to do here, say N. + +config VFIO_PCI_MMAP + depends on VFIO_PCI + def_bool y if !S390 + +config VFIO_PCI_INTX + depends on VFIO_PCI + def_bool y if !S390 diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 9558da3f06a0..255201f22126 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -215,7 +215,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) { u8 pin; pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); - if (pin) + if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && pin) return 1; } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) { @@ -406,7 +406,8 @@ static long vfio_pci_ioctl(void *device_data, info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE; - if (pci_resource_flags(pdev, info.index) & + if (IS_ENABLED(CONFIG_VFIO_PCI_MMAP) && + pci_resource_flags(pdev, info.index) & IORESOURCE_MEM && info.size >= PAGE_SIZE) info.flags |= VFIO_REGION_INFO_FLAG_MMAP; break; diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 1de3f94aa7de..ff75ca31a199 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -609,6 +609,10 @@ static int __init init_pci_cap_basic_perm(struct perm_bits *perm) /* Sometimes used by sw, just virtualize */ p_setb(perm, PCI_INTERRUPT_LINE, (u8)ALL_VIRT, (u8)ALL_WRITE); + + /* Virtualize interrupt pin to allow hiding INTx */ + p_setb(perm, PCI_INTERRUPT_PIN, (u8)ALL_VIRT, (u8)NO_WRITE); + return 0; } @@ -1445,6 +1449,9 @@ int vfio_config_init(struct vfio_pci_device *vdev) *(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device); } + if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX)) + vconfig[PCI_INTERRUPT_PIN] = 0; + ret = vfio_cap_init(vdev); if (ret) goto out; -- GitLab From 55dc68c012bf056880c03d9f6eb34c00880f9e88 Mon Sep 17 00:00:00 2001 From: Mark Knibbs Date: Tue, 4 Nov 2014 13:00:22 +0000 Subject: [PATCH 3646/9457] USB: storage: Reject bogus max LUN values Some mass storage devices return a bogus value in response to a Get Max LUN request. The Iomega Jaz USB Adapter responds with 0x10, hence my recent patch to use the US_FL_SINGLE_LUN quirk for it. The USB MSC Bulk Only Transport document says "The device shall return one byte of data that contains the maximum LUN supported by the device." Since the LUN field in the command block wrapper is only 4 bits wide, it might be helpful to report too-large LUN values in the kernel log, and assume max LUN is actually 0. That could get some devices which currently need the US_FL_SINGLE_LUN quirk to work. Signed-off-by: Mark Knibbs Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 22c7d4360fa2..d614deeacd87 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1035,9 +1035,20 @@ int usb_stor_Bulk_max_lun(struct us_data *us) usb_stor_dbg(us, "GetMaxLUN command result is %d, data is %d\n", result, us->iobuf[0]); - /* if we have a successful request, return the result */ - if (result > 0) - return us->iobuf[0]; + /* + * If we have a successful request, return the result if valid. The + * CBW LUN field is 4 bits wide, so the value reported by the device + * should fit into that. + */ + if (result > 0) { + if (us->iobuf[0] < 16) { + return us->iobuf[0]; + } else { + dev_info(&us->pusb_intf->dev, + "Max LUN %d is not valid, using 0 instead", + us->iobuf[0]); + } + } /* * Some devices don't like GetMaxLUN. They may STALL the control -- GitLab From 6827f7e3113ae11689546404f557fbfdba20aa50 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:17:10 +0530 Subject: [PATCH 3647/9457] host: uhci-platform: fix NULL pointer dereference on resource Fix in accessing NULL if resource didn't get. Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index b987f1d10058..cf8f46003f62 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -86,14 +86,14 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_rmr; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + uhci = hcd_to_uhci(hcd); uhci->regs = hcd->regs; -- GitLab From 239ab7a41ada94a0248028c380b66be7704db054 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:17:11 +0530 Subject: [PATCH 3648/9457] host: ehci-sead3: fix NULL pointer dereference on resource Fix on accessing NULL pointer dereference on get resource failed. Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sead3.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index cf1267673868..9b6e8d0eac43 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c @@ -110,14 +110,13 @@ static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err1; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); /* Root hub has integrated TT. */ hcd->has_tt = 1; -- GitLab From 0fb5f700e984d6e5c035d241ffab1900d0f1ebd2 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:08 +0530 Subject: [PATCH 3649/9457] host: ehci-atmel: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-atmel.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index ec9f7b75d497..56a88506febe 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -107,22 +107,15 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto fail_request_resource; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto fail_request_resource; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + iclk = devm_clk_get(&pdev->dev, "ehci_clk"); if (IS_ERR(iclk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); -- GitLab From 54891d7404267ac7a89a464752feba6a851d18fd Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:09 +0530 Subject: [PATCH 3650/9457] host: ohci-da8xx: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-da8xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index df06be6b47f5..1c76999b2184 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -313,16 +313,13 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver, return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENODEV; - hcd->rsrc_start = mem->start; - hcd->rsrc_len = resource_size(mem); - hcd->regs = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(hcd->regs)) { error = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = mem->start; + hcd->rsrc_len = resource_size(mem); ohci_hcd_init(hcd_to_ohci(hcd)); -- GitLab From a36cc4237f8e8aabb7d78b3d17eac7a23550992e Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:10 +0530 Subject: [PATCH 3651/9457] host: ehci-tegra: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 3e6f685a00ff..19a9af1b4d74 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -460,18 +460,14 @@ static int tegra_ehci_probe(struct platform_device *pdev) "nvidia,needs-double-reset"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto cleanup_clk_en; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto cleanup_clk_en; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + ehci->caps = hcd->regs + 0x100; ehci->has_hostpc = soc_config->has_hostpc; -- GitLab From 0af6b07094b6ad560bc1a1d062a81aaaebc57199 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:11 +0530 Subject: [PATCH 3652/9457] host: ehci-w90x900: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-w90x900.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index a9303aff125e..4717bf207595 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -42,27 +42,20 @@ static int usb_w90x900_probe(const struct hc_driver *driver, int retval = 0, irq; unsigned long val; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENXIO; - goto err1; - } - hcd = usb_create_hcd(driver, &pdev->dev, "w90x900 EHCI"); if (!hcd) { retval = -ENOMEM; goto err1; } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err2; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; -- GitLab From 04dc3150a3d341cda494b3689c14b334aa8f94e2 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:12 +0530 Subject: [PATCH 3653/9457] host: ohci-at91: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 6181549883af..39406607e53a 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -133,12 +133,6 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, struct resource *res; int irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_dbg(dev, "hcd probe: missing memory resource\n"); - return -ENXIO; - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_dbg(dev, "hcd probe: missing irq resource\n"); @@ -148,14 +142,15 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, hcd = usb_create_hcd(driver, dev, "at91"); if (!hcd) return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); iclk = devm_clk_get(dev, "ohci_clk"); if (IS_ERR(iclk)) { -- GitLab From b87a9c5294c640b07a7da8cec615bef650ef074d Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:13 +0530 Subject: [PATCH 3654/9457] host: ohci-exynos: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-exynos.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 39f366b6b1a7..035a8a85a867 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -155,19 +155,13 @@ static int exynos_ohci_probe(struct platform_device *pdev) goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto fail_io; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto fail_io; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); irq = platform_get_irq(pdev, 0); if (!irq) { -- GitLab From 5c36cc64c5036463e608d2ccaaf71bec50112119 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:14 +0530 Subject: [PATCH 3655/9457] host: ohci-jz4740: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-jz4740.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index c2c221a332eb..8ddd8f5470cb 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -153,13 +153,6 @@ static int jz4740_ohci_probe(struct platform_device *pdev) struct resource *res; int irq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) { - dev_err(&pdev->dev, "Failed to get platform resource\n"); - return -ENOENT; - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "Failed to get platform irq\n"); @@ -174,14 +167,14 @@ static int jz4740_ohci_probe(struct platform_device *pdev) jz4740_ohci = hcd_to_jz4740_hcd(hcd); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_free; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); jz4740_ohci->clk = devm_clk_get(&pdev->dev, "uhc"); if (IS_ERR(jz4740_ohci->clk)) { -- GitLab From c6d413cebd82cf35b6a4257cd94724ff60cffb71 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:15 +0530 Subject: [PATCH 3656/9457] host: ohci-octeon: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-octeon.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c index 15af8954085e..20d861b6192f 100644 --- a/drivers/usb/host/ohci-octeon.c +++ b/drivers/usb/host/ohci-octeon.c @@ -120,12 +120,6 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev) return -ENODEV; } - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - /* Ohci is a 32-bit device. */ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (ret) @@ -135,14 +129,14 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg_base = devm_ioremap_resource(&pdev->dev, res_mem); if (IS_ERR(reg_base)) { ret = PTR_ERR(reg_base); goto err1; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); ohci_octeon_hw_start(); -- GitLab From 7b519291b1b8ef82187936c9b6d1edfc5c805b3d Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:16 +0530 Subject: [PATCH 3657/9457] host: ohci-platform: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index adb691d3087c..9434c1d54495 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -134,12 +134,6 @@ static int ohci_platform_probe(struct platform_device *dev) return irq; } - res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!res_mem) { - dev_err(&dev->dev, "no memory resource provided"); - return -ENXIO; - } - hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); if (!hcd) @@ -231,14 +225,15 @@ static int ohci_platform_probe(struct platform_device *dev) goto err_reset; } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_power; -- GitLab From 15c85d9cc83b6aea97859377d887e7493f141193 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:17 +0530 Subject: [PATCH 3658/9457] host: ohci-pxa27x: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-pxa27x.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e68f3d02cd1a..13399814ef5f 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -447,20 +447,13 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - pr_err("no resource of IORESOURCE_MEM"); - retval = -ENXIO; - goto err; - } - - hcd->rsrc_start = r->start; - hcd->rsrc_len = resource_size(r); - hcd->regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err; } + hcd->rsrc_start = r->start; + hcd->rsrc_len = resource_size(r); /* initialize "struct pxa27x_ohci" */ pxa_ohci = to_pxa27x_ohci(hcd); -- GitLab From e71827f49415b9da0b4723cab398258c9a40ed08 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:18 +0530 Subject: [PATCH 3659/9457] host: ehci-sh: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sh.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index f9ebf8af99b9..0e0ce684aff3 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -86,15 +86,6 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - ret = -ENODEV; - goto fail_create_hcd; - } - irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(&pdev->dev, @@ -114,14 +105,14 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev) goto fail_create_hcd; } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto fail_request_resource; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); priv = devm_kzalloc(&pdev->dev, sizeof(struct ehci_sh_priv), GFP_KERNEL); -- GitLab From 0bf80cbf0642124329117fa9ba4b0ed9c0176329 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:19 +0530 Subject: [PATCH 3660/9457] host: ohci-spear: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-spear.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 8d5876692e7c..4a54f9d73136 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -74,20 +74,15 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENODEV; - goto err_put_hcd; - } - - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err_put_hcd; } + hcd->rsrc_start = pdev->resource[0].start; + hcd->rsrc_len = resource_size(res); + sohci_p = to_spear_ohci(hcd); sohci_p->clk = usbh_clk; -- GitLab From e507bf577e5a4c4f28dab4113625f218c5231ca7 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:20 +0530 Subject: [PATCH 3661/9457] host: ehci-msm: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-msm.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 9dc2118ae808..9db74ca7e5b9 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -88,19 +88,13 @@ static int ehci_msm_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get memory resource\n"); - ret = -ENODEV; - goto put_hcd; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); /* * OTG driver takes care of PHY initialization, clock management, -- GitLab From 6144171ddccfe2db193496614159501bf641034f Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:21 +0530 Subject: [PATCH 3662/9457] host: ehci-mv: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index b1855c1b6cd4..849806a75f1c 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -169,12 +169,6 @@ static int mv_ehci_probe(struct platform_device *pdev) } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); - if (r == NULL) { - dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_hcd; - } - ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->phy_regs)) { retval = PTR_ERR(ehci_mv->phy_regs); @@ -182,12 +176,6 @@ static int mv_ehci_probe(struct platform_device *pdev) } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); - if (!r) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_hcd; - } - ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->cap_regs)) { retval = PTR_ERR(ehci_mv->cap_regs); -- GitLab From d6e269ae4fb147eaa65ae6980064ee0c013fc7d6 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:22 +0530 Subject: [PATCH 3663/9457] host: ehci-mxc: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index dbe5e4eea08d..c7a9b31eeaef 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -69,20 +69,13 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "Found HC with no register addr. Check setup!\n"); - ret = -ENODEV; - goto err_alloc; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_alloc; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); hcd->has_tt = 1; ehci = hcd_to_ehci(hcd); -- GitLab From 073153bf227649057a911ff8d4383117fb866e2b Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:23 +0530 Subject: [PATCH 3664/9457] host: ehci-octeon: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-octeon.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index 9051439039a7..2d0c4bcba579 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -106,12 +106,6 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) return -ENODEV; } - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res_mem == NULL) { - dev_err(&pdev->dev, "No register space assigned\n"); - return -ENODEV; - } - /* * We can DMA from anywhere. But the descriptors must be in * the lower 4GB. @@ -125,14 +119,14 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err1; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); ehci_octeon_start(); -- GitLab From 69b89c603bdbc495a751c926b6311ce3db018f04 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:24 +0530 Subject: [PATCH 3665/9457] host: ehci-orion: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Reviewed-by: Gregory CLEMENT Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-orion.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 22e15cab8ea5..36b46576e5b3 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -175,15 +175,6 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) goto err; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - err = -ENODEV; - goto err; - } - /* * Right now device-tree probed devices don't get dma_mask * set. Since shared usb code relies on it, set it here for @@ -193,6 +184,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) if (err) goto err; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(regs)) { err = PTR_ERR(regs); -- GitLab From 2062ff489ca9d97b4bfee56e944727d9b02b0d63 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:25 +0530 Subject: [PATCH 3666/9457] host: ehci-platform: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index da056fe9d15b..35a9aeda0168 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -164,11 +164,6 @@ static int ehci_platform_probe(struct platform_device *dev) dev_err(&dev->dev, "no irq provided"); return irq; } - res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!res_mem) { - dev_err(&dev->dev, "no memory resource provided"); - return -ENXIO; - } hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, dev_name(&dev->dev)); @@ -250,14 +245,15 @@ static int ehci_platform_probe(struct platform_device *dev) goto err_reset; } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - + res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) goto err_power; -- GitLab From 3b59d31dd86b4839a62ac05de708cca3e20dfed4 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:26 +0530 Subject: [PATCH 3667/9457] host: ehci-spear: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-spear.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 1355ff0946b9..34e14746b92e 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -99,18 +99,13 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - retval = -ENODEV; - goto err_put_hcd; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err_put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); sehci = to_spear_ehci(hcd); sehci->clk = usbh_clk; -- GitLab From e7020f193a3d135e5dda476452e3372e27cc1789 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:27 +0530 Subject: [PATCH 3668/9457] host: xhci-plat: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Acked-by: Felipe Balbi Reviewed-by: Gregory CLEMENT Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 3d78b0cd674b..e68b4ec1757b 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -83,9 +83,6 @@ static int xhci_plat_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; if (of_device_is_compatible(pdev->dev.of_node, "marvell,armada-375-xhci") || @@ -109,15 +106,16 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + /* * Not all platforms have a clk so it is not an error if the * clock does not exists. -- GitLab From 972b98344beca6ca2f1de84141005a2ce2f8ffe5 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:28 +0530 Subject: [PATCH 3669/9457] musb: musb_core: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b841ee0bff06..55ebd4b1daac 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2080,10 +2080,10 @@ static int musb_probe(struct platform_device *pdev) struct resource *iomem; void __iomem *base; - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iomem || irq <= 0) + if (irq <= 0) return -ENODEV; + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, iomem); if (IS_ERR(base)) return PTR_ERR(base); -- GitLab From f3f5972f9e8754f772cffcb5bd7c47573d8cba3b Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:29 +0530 Subject: [PATCH 3670/9457] musb: musb_dsps: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_dsps.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 48bc09e7b83b..965c552f7035 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -447,9 +447,6 @@ static int dsps_musb_init(struct musb *musb) int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); - if (!r) - return -EINVAL; - reg_base = devm_ioremap_resource(dev, r); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); -- GitLab From 7520bee2f1ee18d285877e7c979d4b296458324e Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:30 +0530 Subject: [PATCH 3671/9457] phy: phy-rcar-usb: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/phy-rcar-usb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/phy/phy-rcar-usb.c b/drivers/usb/phy/phy-rcar-usb.c index 33265a5b2cdf..e9f3a93e42b7 100644 --- a/drivers/usb/phy/phy-rcar-usb.c +++ b/drivers/usb/phy/phy-rcar-usb.c @@ -195,11 +195,9 @@ static int rcar_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(reg0); res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (res1) { - reg1 = devm_ioremap_resource(dev, res1); - if (IS_ERR(reg1)) - return PTR_ERR(reg1); - } + reg1 = devm_ioremap_resource(dev, res1); + if (IS_ERR(reg1)) + return PTR_ERR(reg1); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) { -- GitLab From ec2a4f32b0e1c897f72f4b541a153969b62c2164 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:31 +0530 Subject: [PATCH 3672/9457] dwc3: dwc3-keystone: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-keystone.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 7ec8495f4523..dd8d2df6db31 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -104,11 +104,6 @@ static int kdwc3_probe(struct platform_device *pdev) kdwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "missing usbss resource\n"); - return -EINVAL; - } - kdwc->usbss = devm_ioremap_resource(dev, res); if (IS_ERR(kdwc->usbss)) return PTR_ERR(kdwc->usbss); -- GitLab From ce98f5486090aab28e6ef80ec180d75b65aa8ffe Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:32 +0530 Subject: [PATCH 3673/9457] host: ehci-fsl: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 2d2ae8db439e..fb7bd0c7dc15 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -93,21 +93,15 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto err2; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err2; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + pdata->regs = hcd->regs; if (pdata->power_budget) -- GitLab From 35df647c80b44b29dffab3a8374f45d9c0523c26 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:33 +0530 Subject: [PATCH 3674/9457] host: ehci-exynos: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-exynos.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 1b726bfdcbea..f58c9750e3e4 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -187,20 +187,15 @@ static int exynos_ehci_probe(struct platform_device *pdev) goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get I/O memory\n"); - err = -ENXIO; - goto fail_io; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto fail_io; } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "Failed to get IRQ\n"); -- GitLab From d9a887023076ceed7221c216627a0018ad3b86fa Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 4 Nov 2014 07:51:34 +0530 Subject: [PATCH 3675/9457] renesas_usbhs: common: remove duplicate check on resource Sanity check on resource happening with devm_ioremap_resource(). Signed-off-by: Varka Bhadram Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 6dae1151569b..169307ba08b7 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -496,9 +496,8 @@ static int usbhs_probe(struct platform_device *pdev) } /* platform data */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res || !irq_res) { + if (!irq_res) { dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); return -ENODEV; } @@ -508,6 +507,7 @@ static int usbhs_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); -- GitLab From b9ec1c9da64f0c1d130beb125a916d0725363ec9 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:45 -0600 Subject: [PATCH 3676/9457] usb: Create separate header for ehci-dbgp The FUSBH200 and FOTG210 controllers implement sufficiently EHCI- compatible debug ports to leverage ehci-dbgp from their respective drivers. Rather than including header, though, they replicate the necessary declarations in their own headers. Move the ehci-dbgp stuff into its own header as a first step towards removing this redundancy. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/ehci-dbgp.h | 84 +++++++++++++++++++++++++++++++++++ include/linux/usb/ehci_def.h | 65 +-------------------------- 2 files changed, 86 insertions(+), 63 deletions(-) create mode 100644 include/linux/usb/ehci-dbgp.h diff --git a/include/linux/usb/ehci-dbgp.h b/include/linux/usb/ehci-dbgp.h new file mode 100644 index 000000000000..796c1cd6f26a --- /dev/null +++ b/include/linux/usb/ehci-dbgp.h @@ -0,0 +1,84 @@ +/* + * Standalone EHCI usb debug driver + * + * Originally written by: + * Eric W. Biederman" and + * Yinghai Lu + * + * Changes for early/late printk and HW errata: + * Jason Wessel + * Copyright (C) 2009 Wind River Systems, Inc. + * + */ + +#ifndef __LINUX_USB_EHCI_DBGP_H +#define __LINUX_USB_EHCI_DBGP_H + +#include +#include + +/* Appendix C, Debug port ... intended for use with special "debug devices" + * that can help if there's no serial console. (nonstandard enumeration.) + */ +struct ehci_dbg_port { + u32 control; +#define DBGP_OWNER (1<<30) +#define DBGP_ENABLED (1<<28) +#define DBGP_DONE (1<<16) +#define DBGP_INUSE (1<<10) +#define DBGP_ERRCODE(x) (((x)>>7)&0x07) +# define DBGP_ERR_BAD 1 +# define DBGP_ERR_SIGNAL 2 +#define DBGP_ERROR (1<<6) +#define DBGP_GO (1<<5) +#define DBGP_OUT (1<<4) +#define DBGP_LEN(x) (((x)>>0)&0x0f) + u32 pids; +#define DBGP_PID_GET(x) (((x)>>16)&0xff) +#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) + u32 data03; + u32 data47; + u32 address; +#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) +}; + +#ifdef CONFIG_EARLY_PRINTK_DBGP +#include +extern int __init early_dbgp_init(char *s); +extern struct console early_dbgp_console; +#endif /* CONFIG_EARLY_PRINTK_DBGP */ + +struct usb_hcd; + +#ifdef CONFIG_XEN_DOM0 +extern int xen_dbgp_reset_prep(struct usb_hcd *); +extern int xen_dbgp_external_startup(struct usb_hcd *); +#else +static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) +{ + return 1; /* Shouldn't this be 0? */ +} + +static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) +{ + return -1; +} +#endif + +#ifdef CONFIG_EARLY_PRINTK_DBGP +/* Call backs from ehci host driver to ehci debug driver */ +extern int dbgp_external_startup(struct usb_hcd *); +extern int dbgp_reset_prep(struct usb_hcd *); +#else +static inline int dbgp_reset_prep(struct usb_hcd *hcd) +{ + return xen_dbgp_reset_prep(hcd); +} + +static inline int dbgp_external_startup(struct usb_hcd *hcd) +{ + return xen_dbgp_external_startup(hcd); +} +#endif + +#endif /* __LINUX_USB_EHCI_DBGP_H */ diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index daec99af5d54..966889a20ea3 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -19,6 +19,8 @@ #ifndef __LINUX_USB_EHCI_DEF_H #define __LINUX_USB_EHCI_DEF_H +#include + /* EHCI register interface, corresponds to EHCI Revision 0.95 specification */ /* Section 2.2 Host Controller Capability Registers */ @@ -190,67 +192,4 @@ struct ehci_regs { #define USBMODE_EX_HC (3<<0) /* host controller mode */ }; -/* Appendix C, Debug port ... intended for use with special "debug devices" - * that can help if there's no serial console. (nonstandard enumeration.) - */ -struct ehci_dbg_port { - u32 control; -#define DBGP_OWNER (1<<30) -#define DBGP_ENABLED (1<<28) -#define DBGP_DONE (1<<16) -#define DBGP_INUSE (1<<10) -#define DBGP_ERRCODE(x) (((x)>>7)&0x07) -# define DBGP_ERR_BAD 1 -# define DBGP_ERR_SIGNAL 2 -#define DBGP_ERROR (1<<6) -#define DBGP_GO (1<<5) -#define DBGP_OUT (1<<4) -#define DBGP_LEN(x) (((x)>>0)&0x0f) - u32 pids; -#define DBGP_PID_GET(x) (((x)>>16)&0xff) -#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) - u32 data03; - u32 data47; - u32 address; -#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) -}; - -#ifdef CONFIG_EARLY_PRINTK_DBGP -#include -extern int __init early_dbgp_init(char *s); -extern struct console early_dbgp_console; -#endif /* CONFIG_EARLY_PRINTK_DBGP */ - -struct usb_hcd; - -#ifdef CONFIG_XEN_DOM0 -extern int xen_dbgp_reset_prep(struct usb_hcd *); -extern int xen_dbgp_external_startup(struct usb_hcd *); -#else -static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) -{ - return 1; /* Shouldn't this be 0? */ -} - -static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) -{ - return -1; -} -#endif - -#ifdef CONFIG_EARLY_PRINTK_DBGP -/* Call backs from ehci host driver to ehci debug driver */ -extern int dbgp_external_startup(struct usb_hcd *); -extern int dbgp_reset_prep(struct usb_hcd *hcd); -#else -static inline int dbgp_reset_prep(struct usb_hcd *hcd) -{ - return xen_dbgp_reset_prep(hcd); -} -static inline int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd); -} -#endif - #endif /* __LINUX_USB_EHCI_DEF_H */ -- GitLab From 895baf2404ebc2f875fad39d2d81f98a38a8f9cc Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:46 -0600 Subject: [PATCH 3677/9457] fusbh200: Make Xen notificaiton consistent with EHCI If CONFIG_XEN_DOM0 is enabled, the ehci-dbgp driver notifies Xen of controller reset events via xen_dbgp_reset_prep() and xen_dbgp_external_startup() (via calls to xen_dbgp_op().) Otherwise defines them as no-ops to disable this logic. The fusbh200 driver copies much of the dbgp code from ehci_def.h, but it unconditionally defines the Xen hooks as no-ops, effectively disabling these notifications when CONFIG_EARLY_PRINTK_DBGP is disabled. When enabled, though, notifying Xen is dependent on CONFIG_XEN_DOM0 due to fusbh200 leveraging the ehci-dbgp driver. The following table compares the implementations of xen_dbgp_reset_prep() and xen_dbgp_external_startup() in the ehci-dbgp and fusbh200 drivers under the relevant configurations: EARLY_PRINTK_DBGP? XEN_DOM0? ehci-dbgp fusbh200 ------------------ --------- ------------- ------------- n n no-op no-op n y xen_dbgp_op() no-op y n no-op no-op y y xen_dbgp_op() xen_dbgp_op() This suggests that fusbh200 is, at best, indifferent to whether Xen is notified of these events. Make fusbh200 consistent with ehci-dbgp as a step towards consolidating this code duplication. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fusbh200.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index 6b719e066c3f..6e7b8c1cb877 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -318,6 +318,10 @@ extern struct console early_dbgp_console; struct usb_hcd; +#ifdef CONFIG_XEN_DOM0 +extern int xen_dbgp_reset_prep(struct usb_hcd *); +extern int xen_dbgp_external_startup(struct usb_hcd *); +#else static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) { return 1; /* Shouldn't this be 0? */ @@ -327,6 +331,7 @@ static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) { return -1; } +#endif #ifdef CONFIG_EARLY_PRINTK_DBGP /* Call backs from fusbh200 host driver to fusbh200 debug driver */ -- GitLab From d67bba78b308f7753dc5b4d5801f67817967b736 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:47 -0600 Subject: [PATCH 3678/9457] fusbh200: Remove superfluous macro definitions The fusbh200_dbg_port struct is a copy of the ehci_dbg_port definition in the header. Embedded in this definition are a number of macros which came along for the ride. These macros are not used in the fusbh200 driver and will conflict those in the new header. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fusbh200.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index 6e7b8c1cb877..da7152bcf9a8 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -290,24 +290,10 @@ struct fusbh200_regs { */ struct fusbh200_dbg_port { u32 control; -#define DBGP_OWNER (1<<30) -#define DBGP_ENABLED (1<<28) -#define DBGP_DONE (1<<16) -#define DBGP_INUSE (1<<10) -#define DBGP_ERRCODE(x) (((x)>>7)&0x07) -# define DBGP_ERR_BAD 1 -# define DBGP_ERR_SIGNAL 2 -#define DBGP_ERROR (1<<6) -#define DBGP_GO (1<<5) -#define DBGP_OUT (1<<4) -#define DBGP_LEN(x) (((x)>>0)&0x0f) u32 pids; -#define DBGP_PID_GET(x) (((x)>>16)&0xff) -#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) u32 data03; u32 data47; u32 address; -#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) }; #ifdef CONFIG_EARLY_PRINTK_DBGP -- GitLab From e004631a4f183a9e64db91e3753e97edc5a8cb94 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:48 -0600 Subject: [PATCH 3679/9457] fusbh200: Remove duplicate ehci-dbgp declarations Now that ehci-dbgp has its own header, use it rather than duplicating the declarations, etc. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fusbh200.h | 40 ++----------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index da7152bcf9a8..47aecfc03582 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -1,6 +1,8 @@ #ifndef __LINUX_FUSBH200_H #define __LINUX_FUSBH200_H +#include + /* definitions used for the EHCI driver */ /* @@ -296,44 +298,6 @@ struct fusbh200_dbg_port { u32 address; }; -#ifdef CONFIG_EARLY_PRINTK_DBGP -#include -extern int __init early_dbgp_init(char *s); -extern struct console early_dbgp_console; -#endif /* CONFIG_EARLY_PRINTK_DBGP */ - -struct usb_hcd; - -#ifdef CONFIG_XEN_DOM0 -extern int xen_dbgp_reset_prep(struct usb_hcd *); -extern int xen_dbgp_external_startup(struct usb_hcd *); -#else -static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) -{ - return 1; /* Shouldn't this be 0? */ -} - -static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) -{ - return -1; -} -#endif - -#ifdef CONFIG_EARLY_PRINTK_DBGP -/* Call backs from fusbh200 host driver to fusbh200 debug driver */ -extern int dbgp_external_startup(struct usb_hcd *); -extern int dbgp_reset_prep(struct usb_hcd *hcd); -#else -static inline int dbgp_reset_prep(struct usb_hcd *hcd) -{ - return xen_dbgp_reset_prep(hcd); -} -static inline int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd); -} -#endif - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fusbh200, dma) cpu_to_hc32(fusbh200, (u32)dma) -- GitLab From da5d5c58f3e9314cd43bf1d28a1a9e3b2659d632 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:49 -0600 Subject: [PATCH 3680/9457] fusbh200: Use ehci_dbg_port struct The FUSBH200 debug port has a EHCI-compatible register layout so there is no need to define a custom struct. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fusbh200.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index 47aecfc03582..d6e5b3d4aa68 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -86,7 +86,7 @@ struct fusbh200_hcd { /* one per controller */ /* glue to PCI and HCD framework */ struct fusbh200_caps __iomem *caps; struct fusbh200_regs __iomem *regs; - struct fusbh200_dbg_port __iomem *debug; + struct ehci_dbg_port __iomem *debug; __u32 hcs_params; /* cached register copy */ spinlock_t lock; @@ -287,17 +287,6 @@ struct fusbh200_regs { #define BMIER_VBUS_ERR_EN (1<<0) }; -/* Appendix C, Debug port ... intended for use with special "debug devices" - * that can help if there's no serial console. (nonstandard enumeration.) - */ -struct fusbh200_dbg_port { - u32 control; - u32 pids; - u32 data03; - u32 data47; - u32 address; -}; - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fusbh200, dma) cpu_to_hc32(fusbh200, (u32)dma) -- GitLab From a648c147011d97e0d410f251c27175231975584d Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:50 -0600 Subject: [PATCH 3681/9457] fotg210: Make Xen notification consistent with EHCI If CONFIG_XEN_DOM0 is enabled, the ehci-dbgp driver notifies Xen of controller reset events via xen_dbgp_reset_prep() and xen_dbgp_external_startup() (via calls to xen_dbgp_op().) Otherwise defines them as no-ops to disable this logic. The fotg210 driver copies much of the dbgp code from ehci_def.h, but it unconditionally defines the Xen hooks as no-ops, effectively disabling these notifications when CONFIG_EARLY_PRINTK_DBGP is disabled. When enabled, though, notifying Xen is dependent on CONFIG_XEN_DOM0 due to fotg210 leveraging the ehci-dbgp driver. The following table compares the implementations of xen_dbgp_reset_prep() and xen_dbgp_external_startup() in the ehci-dbgp and fotg210 drivers under the relevant configurations: EARLY_PRINTK_DBGP? XEN_DOM0? ehci-dbgp fotg210 ------------------ --------- ------------- ------------- n n no-op no-op n y xen_dbgp_op() no-op y n no-op no-op y y xen_dbgp_op() xen_dbgp_op() This suggests that fotg210 is, at best, indifferent to whether Xen is notified of these events. Make fotg210 consistent with ehci-dbgp as a step towards consolidating this code duplication. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fotg210.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index ac6cd1bfd208..98c9670bcf82 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -326,6 +326,10 @@ extern struct console early_dbgp_console; struct usb_hcd; +#ifdef CONFIG_XEN_DOM0 +extern int xen_dbgp_reset_prep(struct usb_hcd *); +extern int xen_dbgp_external_startup(struct usb_hcd *); +#else static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) { return 1; /* Shouldn't this be 0? */ @@ -335,6 +339,7 @@ static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) { return -1; } +#endif #ifdef CONFIG_EARLY_PRINTK_DBGP /* Call backs from fotg210 host driver to fotg210 debug driver */ -- GitLab From 0fa57f01278b78174848ca628ca9a87c4dd37696 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:51 -0600 Subject: [PATCH 3682/9457] fotg210: Remove superfluous macro definitions The fotg210_dbg_port struct is a copy of the ehci_dbg_port definition in the header. Embedded in this definition are a number of macros which came along for the ride. These macros are not used in the fotg210 driver and will conflict those in the new header. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fotg210.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index 98c9670bcf82..c2e513495704 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -298,24 +298,10 @@ struct fotg210_regs { */ struct fotg210_dbg_port { u32 control; -#define DBGP_OWNER (1<<30) -#define DBGP_ENABLED (1<<28) -#define DBGP_DONE (1<<16) -#define DBGP_INUSE (1<<10) -#define DBGP_ERRCODE(x) (((x)>>7)&0x07) -# define DBGP_ERR_BAD 1 -# define DBGP_ERR_SIGNAL 2 -#define DBGP_ERROR (1<<6) -#define DBGP_GO (1<<5) -#define DBGP_OUT (1<<4) -#define DBGP_LEN(x) (((x)>>0)&0x0f) u32 pids; -#define DBGP_PID_GET(x) (((x)>>16)&0xff) -#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) u32 data03; u32 data47; u32 address; -#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) }; #ifdef CONFIG_EARLY_PRINTK_DBGP -- GitLab From b1f6ccf580a9c547d0299561149c6a03c833515a Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:52 -0600 Subject: [PATCH 3683/9457] fotg210: Remove duplicate ehci-dbgp declarations Now that ehci-dbgp has its own header, use it rather than duplicating the declarations, etc. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fotg210.h | 40 ++------------------------------------ 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index c2e513495704..975d9bb25858 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -1,6 +1,8 @@ #ifndef __LINUX_FOTG210_H #define __LINUX_FOTG210_H +#include + /* definitions used for the EHCI driver */ /* @@ -304,44 +306,6 @@ struct fotg210_dbg_port { u32 address; }; -#ifdef CONFIG_EARLY_PRINTK_DBGP -#include -extern int __init early_dbgp_init(char *s); -extern struct console early_dbgp_console; -#endif /* CONFIG_EARLY_PRINTK_DBGP */ - -struct usb_hcd; - -#ifdef CONFIG_XEN_DOM0 -extern int xen_dbgp_reset_prep(struct usb_hcd *); -extern int xen_dbgp_external_startup(struct usb_hcd *); -#else -static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd) -{ - return 1; /* Shouldn't this be 0? */ -} - -static inline int xen_dbgp_external_startup(struct usb_hcd *hcd) -{ - return -1; -} -#endif - -#ifdef CONFIG_EARLY_PRINTK_DBGP -/* Call backs from fotg210 host driver to fotg210 debug driver */ -extern int dbgp_external_startup(struct usb_hcd *); -extern int dbgp_reset_prep(struct usb_hcd *hcd); -#else -static inline int dbgp_reset_prep(struct usb_hcd *hcd) -{ - return xen_dbgp_reset_prep(hcd); -} -static inline int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd); -} -#endif - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fotg210, dma) cpu_to_hc32(fotg210, (u32)dma) -- GitLab From 9183b3641f50c3cc70c24073117bb9d53b858fb0 Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:53 -0600 Subject: [PATCH 3684/9457] fotg210: Use ehci_dbg_port struct The FUSBH200 debug port has a EHCI-compatible register layout so there is no need to define a custom struct. Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fotg210.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index 975d9bb25858..3bad17859cd7 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -86,7 +86,7 @@ struct fotg210_hcd { /* one per controller */ /* glue to PCI and HCD framework */ struct fotg210_caps __iomem *caps; struct fotg210_regs __iomem *regs; - struct fotg210_dbg_port __iomem *debug; + struct ehci_dbg_port __iomem *debug; __u32 hcs_params; /* cached register copy */ spinlock_t lock; @@ -295,17 +295,6 @@ struct fotg210_regs { #define GMIR_MDEV_INT (1 << 0) }; -/* Appendix C, Debug port ... intended for use with special "debug devices" - * that can help if there's no serial console. (nonstandard enumeration.) - */ -struct fotg210_dbg_port { - u32 control; - u32 pids; - u32 data03; - u32 data47; - u32 address; -}; - /*-------------------------------------------------------------------------*/ #define QTD_NEXT(fotg210, dma) cpu_to_hc32(fotg210, (u32)dma) -- GitLab From 35a27eab6f94e15fa30f7662af00fbec50526f4a Mon Sep 17 00:00:00 2001 From: Chris Rorvick Date: Tue, 4 Nov 2014 19:18:54 -0600 Subject: [PATCH 3685/9457] usb: Remove __init from early_dbgp_init() prototype Specifying these attributes in both the prototype and the function definition is unnecessary and could cause confusion or bugs if they are inconsistent. As such, __init should only be specified at the function definition. Keith Owens suggested this as a janitorial task on LKML several years ago: https://lkml.org/lkml/2006/1/14/305 Signed-off-by: Chris Rorvick Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/ehci-dbgp.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/usb/ehci-dbgp.h b/include/linux/usb/ehci-dbgp.h index 796c1cd6f26a..7344d9e591cc 100644 --- a/include/linux/usb/ehci-dbgp.h +++ b/include/linux/usb/ehci-dbgp.h @@ -43,8 +43,7 @@ struct ehci_dbg_port { }; #ifdef CONFIG_EARLY_PRINTK_DBGP -#include -extern int __init early_dbgp_init(char *s); +extern int early_dbgp_init(char *s); extern struct console early_dbgp_console; #endif /* CONFIG_EARLY_PRINTK_DBGP */ -- GitLab From a8f820aa4066d2c97e75ecd1bbca8a7920b66f2c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:22:22 +0800 Subject: [PATCH 3686/9457] inet: Add skb_copy_datagram_iter This patch adds skb_copy_datagram_iter, which is identical to skb_copy_datagram_iovec except that it operates on iov_iter instead of iovec. Eventually all users of skb_copy_datagram_iovec should switch over to iov_iter and then we can remove skb_copy_datagram_iovec. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 ++ net/core/datagram.c | 87 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 53f4f6c93356..933cfce7fcd9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -150,6 +150,7 @@ struct net_device; struct scatterlist; struct pipe_inode_info; +struct iov_iter; #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) struct nf_conntrack { @@ -2653,6 +2654,8 @@ int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm, int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset, const struct iovec *to, int to_offset, int size); +int skb_copy_datagram_iter(const struct sk_buff *from, int offset, + struct iov_iter *to, int size); void skb_free_datagram(struct sock *sk, struct sk_buff *skb); void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); diff --git a/net/core/datagram.c b/net/core/datagram.c index fdbc9a81d4c2..84d90d087a30 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -481,6 +482,92 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, } EXPORT_SYMBOL(skb_copy_datagram_const_iovec); +/** + * skb_copy_datagram_iter - Copy a datagram to an iovec iterator. + * @skb: buffer to copy + * @offset: offset in the buffer to start copying from + * @to: iovec iterator to copy to + * @len: amount of data to copy from buffer to iovec + */ +int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, + struct iov_iter *to, int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + struct sk_buff *frag_iter; + + trace_skb_copy_datagram_iovec(skb, len); + + /* Copy header. */ + if (copy > 0) { + if (copy > len) + copy = len; + if (copy_to_iter(skb->data + offset, copy, to) != copy) + goto short_copy; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + + /* Copy paged appendix. Hmm... why does this look so complicated? */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + WARN_ON(start > offset + len); + + end = start + skb_frag_size(frag); + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (copy_page_to_iter(skb_frag_page(frag), + frag->page_offset + offset - + start, copy, to) != copy) + goto short_copy; + if (!(len -= copy)) + return 0; + offset += copy; + } + start = end; + } + + skb_walk_frags(skb, frag_iter) { + int end; + + WARN_ON(start > offset + len); + + end = start + frag_iter->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_iter(frag_iter, offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; + } + if (!len) + return 0; + + /* This is not really a user copy fault, but rather someone + * gave us a bogus length on the skb. We should probably + * print a warning here as it may indicate a kernel bug. + */ + +fault: + return -EFAULT; + +short_copy: + if (iov_iter_count(to)) + goto fault; + + return 0; +} +EXPORT_SYMBOL(skb_copy_datagram_iter); + /** * skb_copy_datagram_from_iovec - Copy a datagram from an iovec. * @skb: buffer to copy -- GitLab From e0b46d0ee9c240c7430a47e9b0365674d4a04522 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:22:23 +0800 Subject: [PATCH 3687/9457] tun: Use iovec iterators This patch removes the use of skb_copy_datagram_const_iovec in favour of the iovec iterator-based skb_copy_datagram_iter. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/tun.c | 65 ++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9dd3746994a4..2ff769bf3f35 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -71,6 +71,7 @@ #include #include #include +#include #include @@ -1230,11 +1231,11 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, static ssize_t tun_put_user(struct tun_struct *tun, struct tun_file *tfile, struct sk_buff *skb, - const struct iovec *iv, int len) + struct iov_iter *iter) { struct tun_pi pi = { 0, skb->protocol }; - ssize_t total = 0; - int vlan_offset = 0, copied; + ssize_t total; + int vlan_offset; int vlan_hlen = 0; int vnet_hdr_sz = 0; @@ -1244,23 +1245,25 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (tun->flags & TUN_VNET_HDR) vnet_hdr_sz = tun->vnet_hdr_sz; + total = skb->len + vlan_hlen + vnet_hdr_sz; + if (!(tun->flags & TUN_NO_PI)) { - if ((len -= sizeof(pi)) < 0) + if (iov_iter_count(iter) < sizeof(pi)) return -EINVAL; - if (len < skb->len + vlan_hlen + vnet_hdr_sz) { + total += sizeof(pi); + if (iov_iter_count(iter) < total) { /* Packet will be striped */ pi.flags |= TUN_PKT_STRIP; } - if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) + if (copy_to_iter(&pi, sizeof(pi), iter) != sizeof(pi)) return -EFAULT; - total += sizeof(pi); } if (vnet_hdr_sz) { struct virtio_net_hdr gso = { 0 }; /* no info leak */ - if ((len -= vnet_hdr_sz) < 0) + if (iov_iter_count(iter) < vnet_hdr_sz) return -EINVAL; if (skb_is_gso(skb)) { @@ -1299,17 +1302,12 @@ static ssize_t tun_put_user(struct tun_struct *tun, gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ - if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, - sizeof(gso)))) + if (copy_to_iter(&gso, sizeof(gso), iter) != sizeof(gso)) return -EFAULT; - total += vnet_hdr_sz; } - copied = total; - len = min_t(int, skb->len + vlan_hlen, len); - total += skb->len + vlan_hlen; if (vlan_hlen) { - int copy, ret; + int ret; struct { __be16 h_vlan_proto; __be16 h_vlan_TCI; @@ -1320,36 +1318,32 @@ static ssize_t tun_put_user(struct tun_struct *tun, vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); - copy = min_t(int, vlan_offset, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) + ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset); + if (ret || !iov_iter_count(iter)) goto done; - copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) + ret = copy_to_iter(&veth, sizeof(veth), iter); + if (ret != sizeof(veth) || !iov_iter_count(iter)) goto done; } - skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + skb_copy_datagram_iter(skb, vlan_offset, iter, skb->len - vlan_offset); done: tun->dev->stats.tx_packets++; - tun->dev->stats.tx_bytes += len; + tun->dev->stats.tx_bytes += skb->len + vlan_hlen; return total; } static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, - const struct iovec *iv, ssize_t len, int noblock) + const struct iovec *iv, unsigned long segs, + ssize_t len, int noblock) { struct sk_buff *skb; ssize_t ret = 0; int peeked, err, off = 0; + struct iov_iter iter; tun_debug(KERN_INFO, tun, "tun_do_read\n"); @@ -1362,11 +1356,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, /* Read frames from queue */ skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, &peeked, &off, &err); - if (skb) { - ret = tun_put_user(tun, tfile, skb, iv, len); - kfree_skb(skb); - } else - ret = err; + if (!skb) + return ret; + + iov_iter_init(&iter, READ, iv, segs, len); + ret = tun_put_user(tun, tfile, skb, &iter); + kfree_skb(skb); return ret; } @@ -1387,7 +1382,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, goto out; } - ret = tun_do_read(tun, tfile, iv, len, + ret = tun_do_read(tun, tfile, iv, count, len, file->f_flags & O_NONBLOCK); ret = min_t(ssize_t, ret, len); if (ret > 0) @@ -1488,7 +1483,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, m->msg_iov, total_len, + ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len, flags & MSG_DONTWAIT); if (ret > total_len) { m->msg_flags |= MSG_TRUNC; -- GitLab From 6c36d2e26cda1ad3e2c4b90dd843825fc62fe5b4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:22:25 +0800 Subject: [PATCH 3688/9457] macvtap: Use iovec iterators This patch removes the use of skb_copy_datagram_const_iovec in favour of the iovec iterator-based skb_copy_datagram_iter. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 46 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 880cc090dc44..cea99d4a8263 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -778,31 +779,29 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, /* Put packet to the user space buffer */ static ssize_t macvtap_put_user(struct macvtap_queue *q, const struct sk_buff *skb, - const struct iovec *iv, int len) + struct iov_iter *iter) { int ret; int vnet_hdr_len = 0; int vlan_offset = 0; - int copied, total; + int total; if (q->flags & IFF_VNET_HDR) { struct virtio_net_hdr vnet_hdr; vnet_hdr_len = q->vnet_hdr_sz; - if ((len -= vnet_hdr_len) < 0) + if (iov_iter_count(iter) < vnet_hdr_len) return -EINVAL; macvtap_skb_to_vnet_hdr(skb, &vnet_hdr); - if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) + if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter) != + sizeof(vnet_hdr)) return -EFAULT; } - total = copied = vnet_hdr_len; + total = vnet_hdr_len; total += skb->len; - if (!vlan_tx_tag_present(skb)) - len = min_t(int, skb->len, len); - else { - int copy; + if (vlan_tx_tag_present(skb)) { struct { __be16 h_vlan_proto; __be16 h_vlan_TCI; @@ -811,37 +810,33 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); - len = min_t(int, skb->len + VLAN_HLEN, len); total += VLAN_HLEN; - copy = min_t(int, vlan_offset, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) + ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset); + if (ret || !iov_iter_count(iter)) goto done; - copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); - len -= copy; - copied += copy; - if (ret || !len) + ret = copy_to_iter(&veth, sizeof(veth), iter); + if (ret != sizeof(veth) || !iov_iter_count(iter)) goto done; } - ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + ret = skb_copy_datagram_iter(skb, vlan_offset, iter, + skb->len - vlan_offset); done: return ret ? ret : total; } static ssize_t macvtap_do_read(struct macvtap_queue *q, - const struct iovec *iv, unsigned long len, + const struct iovec *iv, unsigned long segs, + unsigned long len, int noblock) { DEFINE_WAIT(wait); struct sk_buff *skb; ssize_t ret = 0; + struct iov_iter iter; while (len) { if (!noblock) @@ -863,7 +858,8 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, schedule(); continue; } - ret = macvtap_put_user(q, skb, iv, len); + iov_iter_init(&iter, READ, iv, segs, len); + ret = macvtap_put_user(q, skb, &iter); kfree_skb(skb); break; } @@ -886,7 +882,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, goto out; } - ret = macvtap_do_read(q, iv, len, file->f_flags & O_NONBLOCK); + ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@ -1117,7 +1113,7 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, int ret; if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) return -EINVAL; - ret = macvtap_do_read(q, m->msg_iov, total_len, + ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len, flags & MSG_DONTWAIT); if (ret > total_len) { m->msg_flags |= MSG_TRUNC; -- GitLab From bfe1be38fcee0e13ad53175d0b530707c20f93ec Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:22:26 +0800 Subject: [PATCH 3689/9457] net: Kill skb_copy_datagram_const_iovec Now that both macvtap and tun are using skb_copy_datagram_iter, we can kill the abomination that is skb_copy_datagram_const_iovec. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 -- net/core/datagram.c | 89 ------------------------------------------ 2 files changed, 92 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 933cfce7fcd9..103fbe8113f8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2651,9 +2651,6 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, int len); int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm, int offset, size_t count); -int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset, - const struct iovec *to, int to_offset, - int size); int skb_copy_datagram_iter(const struct sk_buff *from, int offset, struct iov_iter *to, int size); void skb_free_datagram(struct sock *sk, struct sk_buff *skb); diff --git a/net/core/datagram.c b/net/core/datagram.c index 84d90d087a30..26391a3fe3e5 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -393,95 +393,6 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, } EXPORT_SYMBOL(skb_copy_datagram_iovec); -/** - * skb_copy_datagram_const_iovec - Copy a datagram to an iovec. - * @skb: buffer to copy - * @offset: offset in the buffer to start copying from - * @to: io vector to copy to - * @to_offset: offset in the io vector to start copying to - * @len: amount of data to copy from buffer to iovec - * - * Returns 0 or -EFAULT. - * Note: the iovec is not modified during the copy. - */ -int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, - const struct iovec *to, int to_offset, - int len) -{ - int start = skb_headlen(skb); - int i, copy = start - offset; - struct sk_buff *frag_iter; - - /* Copy header. */ - if (copy > 0) { - if (copy > len) - copy = len; - if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to_offset += copy; - } - - /* Copy paged appendix. Hmm... why does this look so complicated? */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - WARN_ON(start > offset + len); - - end = start + skb_frag_size(frag); - if ((copy = end - offset) > 0) { - int err; - u8 *vaddr; - struct page *page = skb_frag_page(frag); - - if (copy > len) - copy = len; - vaddr = kmap(page); - err = memcpy_toiovecend(to, vaddr + frag->page_offset + - offset - start, to_offset, copy); - kunmap(page); - if (err) - goto fault; - if (!(len -= copy)) - return 0; - offset += copy; - to_offset += copy; - } - start = end; - } - - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_const_iovec(frag_iter, - offset - start, - to, to_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to_offset += copy; - } - start = end; - } - if (!len) - return 0; - -fault: - return -EFAULT; -} -EXPORT_SYMBOL(skb_copy_datagram_const_iovec); - /** * skb_copy_datagram_iter - Copy a datagram to an iovec iterator. * @skb: buffer to copy -- GitLab From 424c4f7875ee21e803f6ebeb8799b6185eda7864 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 7 Nov 2014 16:53:12 +0200 Subject: [PATCH 3690/9457] stmmac: remove custom implementation of print_hex_dump() There is a kernel helper to dump buffers in a hexdecimal format. This patch substitutes the open coded function by calling that helper. The output is slightly changed: - no lead space - ASCII part will be printed along with the dump - offset is longer than 3 characters (now 8) Signed-off-by: Andy Shevchenko Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fa598b97d710..53db11b29e61 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -191,14 +191,8 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) static void print_pkt(unsigned char *buf, int len) { - int j; - pr_debug("len = %d byte, buf addr: 0x%p", len, buf); - for (j = 0; j < len; j++) { - if ((j % 16) == 0) - pr_debug("\n %03x:", j); - pr_debug(" %02x", buf[j]); - } - pr_debug("\n"); + pr_debug("len = %d byte, buf addr: 0x%p\n", len, buf); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); } /* minimum number of free TX descriptors required to wake up TX process */ -- GitLab From 0d511a3801378bd328885e38d1f5e7481f224117 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:04 -0500 Subject: [PATCH 3691/9457] staging: unisys: visorchannel: Remove multiple blank lines Remove the instances of multiple blank lines in the visorchannel files. Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchannel/globals.h | 1 - drivers/staging/unisys/visorchannel/visorchannel_funcs.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/globals.h b/drivers/staging/unisys/visorchannel/globals.h index 07653b8dea7b..581ed83fe6d0 100644 --- a/drivers/staging/unisys/visorchannel/globals.h +++ b/drivers/staging/unisys/visorchannel/globals.h @@ -25,5 +25,4 @@ #define MYDRVNAME "visorchannel" - #endif diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index a50251a986a1..b3265c80d0f3 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -504,7 +504,6 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) } EXPORT_SYMBOL_GPL(visorchannel_signalinsert); - int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) { -- GitLab From ff247e7f9b3572ea041a60a01a151a8323fc257f Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:05 -0500 Subject: [PATCH 3692/9457] staging: unisys: visorchannel: Fix alignment issues Use the appropriate whitespace for multiline statements in visorchannel_funcs.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- .../staging/unisys/visorchannel/visorchannel_funcs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index b3265c80d0f3..1d55254b8967 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -226,7 +226,7 @@ visorchannel_read(VISORCHANNEL *channel, ulong offset, int rc = visor_memregion_read(channel->memregion, offset, local, nbytes); if ((rc >= 0) && (offset == 0) && - (nbytes >= sizeof(struct channel_header))) { + (nbytes >= sizeof(struct channel_header))) { memcpy(&channel->chan_hdr, local, sizeof(struct channel_header)); } @@ -399,7 +399,7 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, punsafe_sqh->tail = *ptail; ERRDRV("safe_sig_queue_validate: head = 0x%x, tail = 0x%x, MaxSlots = 0x%x", - *phead, *ptail, psafe_sqh->max_slots); + *phead, *ptail, psafe_sqh->max_slots); return 0; } return 1; @@ -622,9 +622,10 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, struct signal_queue_header q; errcode = visorchannel_read(channel, - off + phdr->ch_space_offset + - (i * sizeof(q)), - &q, sizeof(q)); + off + + phdr->ch_space_offset + + (i * sizeof(q)), + &q, sizeof(q)); if (errcode < 0) { seq_printf(seq, "failed to read signal queue #%d from channel @0x%-16.16Lx errcode=%d\n", -- GitLab From 6e4c8d30b16e90db90b570756e15c5a3255c3837 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:06 -0500 Subject: [PATCH 3693/9457] staging: unisys: visorchannel: Remove space between cast and variable Remove the whitespace between a cast and the variable in visorchannel_funcs.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchannel/visorchannel_funcs.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 1d55254b8967..eff9d0ee14c1 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -89,7 +89,7 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, } if (channelBytes == 0) /* we had better be a CLIENT of this channel */ - channelBytes = (ulong) p->chan_hdr.size; + channelBytes = (ulong)p->chan_hdr.size; if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) /* we had better be a CLIENT of this channel */ guid = p->chan_hdr.chtype; @@ -287,7 +287,7 @@ EXPORT_SYMBOL_GPL(visorchannel_clear); void __iomem * visorchannel_get_header(VISORCHANNEL *channel) { - return (void __iomem *) &(channel->chan_hdr); + return (void __iomem *)&(channel->chan_hdr); } EXPORT_SYMBOL_GPL(visorchannel_get_header); @@ -519,7 +519,7 @@ visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue) head = head + sig_hdr.max_slots; slots_used = (head - tail); slots_avail = sig_hdr.max_signals - slots_used; - return (int) slots_avail; + return (int)slots_avail; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail); @@ -530,7 +530,7 @@ visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue) if (!sig_read_header(channel, queue, &sig_hdr)) return 0; - return (int) sig_hdr.max_signals; + return (int)sig_hdr.max_signals; } EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots); @@ -593,13 +593,13 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, } else return; } - nbytes = (ulong) (phdr->size); + nbytes = (ulong)(phdr->size); seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n", addr + off, nbytes, nbytes_region); seq_printf(seq, "Type = %pUL\n", &phdr->chtype); seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->zone_uuid); seq_printf(seq, "Signature = 0x%-16.16Lx\n", - (long long) phdr->signature); + (long long)phdr->signature); seq_printf(seq, "LegacyState = %lu\n", (ulong)phdr->legacy_state); seq_printf(seq, "SrvState = %lu\n", (ulong)phdr->srv_state); seq_printf(seq, "CliStateBoot = %lu\n", (ulong)phdr->cli_state_boot); @@ -607,14 +607,14 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, seq_printf(seq, "HeaderSize = %lu\n", (ulong)phdr->header_size); seq_printf(seq, "Size = %llu\n", (long long)phdr->size); seq_printf(seq, "Features = 0x%-16.16llx\n", - (long long) phdr->features); + (long long)phdr->features); seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n", - (long long) phdr->partition_handle); + (long long)phdr->partition_handle); seq_printf(seq, "Handle = 0x%-16.16llx\n", - (long long) phdr->handle); - seq_printf(seq, "VersionId = %lu\n", (ulong) phdr->version_id); + (long long)phdr->handle); + seq_printf(seq, "VersionId = %lu\n", (ulong)phdr->version_id); seq_printf(seq, "oChannelSpace = %llu\n", - (long long) phdr->ch_space_offset); + (long long)phdr->ch_space_offset); if ((phdr->ch_space_offset == 0) || (errcode < 0)) ; else -- GitLab From 61a8a7bc4d86a97f588880b7f7c819f8938cabfc Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:07 -0500 Subject: [PATCH 3694/9457] staging: unisys: visorchannel: Remove unnecessary parentheses Remove extraneous parentheses around a variable in visorchannel_funcs.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchannel/visorchannel_funcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index eff9d0ee14c1..66094a32f495 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -287,7 +287,7 @@ EXPORT_SYMBOL_GPL(visorchannel_clear); void __iomem * visorchannel_get_header(VISORCHANNEL *channel) { - return (void __iomem *)&(channel->chan_hdr); + return (void __iomem *)&channel->chan_hdr; } EXPORT_SYMBOL_GPL(visorchannel_get_header); -- GitLab From e3b7a4cacfcf6ffe6eb289628dd147b3202b5924 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:08 -0500 Subject: [PATCH 3695/9457] staging: unisys: visorchannel: Place logical continuation at the end of a line Move the || logical continuation from the start of the second line of an if statement to the end of the first line. Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchannel/visorchannel_funcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 66094a32f495..29efd4dd0e82 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -388,8 +388,8 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh, struct signal_queue_header *punsafe_sqh, u32 *phead, u32 *ptail) { - if ((*phead >= psafe_sqh->max_slots) - || (*ptail >= psafe_sqh->max_slots)) { + if ((*phead >= psafe_sqh->max_slots) || + (*ptail >= psafe_sqh->max_slots)) { /* Choose 0 or max, maybe based on current tail value */ *phead = 0; *ptail = 0; -- GitLab From 83781f34a8dfff13c82c0b6729e722faba294657 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:09 -0500 Subject: [PATCH 3696/9457] staging: unisys: visorchannel: Adjust lines to contain a maximum of 80 characters Split multiple logging lines to get them closer to 80 characters per line. Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchannel/visorchannel_funcs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 29efd4dd0e82..b9dd77b508b0 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -334,7 +334,8 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, sizeof(struct signal_queue_header)) < 0) { ERRDRV("queue=%d SIG_QUEUE_OFFSET=%d", queue, (int)SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)); - ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", + rc); goto Away; } rc = TRUE; @@ -354,13 +355,15 @@ sig_do_data(VISORCHANNEL *channel, u32 queue, if (visor_memregion_write(channel->memregion, signal_data_offset, data, sig_hdr->signal_size) < 0) { - ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", + rc); goto Away; } } else { if (visor_memregion_read(channel->memregion, signal_data_offset, data, sig_hdr->signal_size) < 0) { - ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", + rc); goto Away; } } @@ -439,7 +442,8 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) goto Away; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { - ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", + rc); goto Away; } rc = TRUE; @@ -469,7 +473,8 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) if (sig_hdr.head == sig_hdr.tail) { sig_hdr.num_overflows++; if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { - ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", + rc); goto Away; } rc = FALSE; @@ -492,7 +497,8 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) goto Away; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { - ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); + ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", + rc); goto Away; } rc = TRUE; -- GitLab From c440ce1f5652d2e6fe4d8aec18ef6448ff75fdd2 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:10 -0500 Subject: [PATCH 3697/9457] staging: unisys: visorchannel: Rename goto label Away Rename the goto label used throughout visorchannel_funcs.c from Away to cleanup. Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- .../unisys/visorchannel/visorchannel_funcs.c | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index b9dd77b508b0..a0fd358e0c28 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -60,7 +60,7 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, if (p == NULL) { ERRDRV("allocation failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } p->memregion = NULL; p->needs_lock = needs_lock; @@ -79,13 +79,13 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, if (p->memregion == NULL) { ERRDRV("visor_memregion_create failed failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } if (visor_memregion_read(p->memregion, 0, &p->chan_hdr, sizeof(struct channel_header)) < 0) { ERRDRV("visor_memregion_read failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } if (channelBytes == 0) /* we had better be a CLIENT of this channel */ @@ -96,13 +96,13 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes, if (visor_memregion_resize(p->memregion, channelBytes) < 0) { ERRDRV("visor_memregion_resize failed: (status=0)\n"); rc = NULL; - goto Away; + goto cleanup; } p->size = channelBytes; p->guid = guid; rc = p; -Away: +cleanup: if (rc == NULL) { if (p != NULL) { @@ -255,7 +255,7 @@ visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes) if (buf == NULL) { ERRDRV("%s failed memory allocation", __func__); - goto Away; + goto cleanup; } memset(buf, ch, bufsize); while (nbytes > 0) { @@ -268,14 +268,14 @@ visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes) buf, thisbytes); if (x < 0) { rc = x; - goto Away; + goto cleanup; } written += thisbytes; nbytes -= thisbytes; } rc = 0; -Away: +cleanup: if (buf != NULL) { vfree(buf); buf = NULL; @@ -323,7 +323,7 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) { ERRDRV("oChannelSpace too small: (status=%d)\n", rc); - goto Away; + goto cleanup; } /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ @@ -336,10 +336,10 @@ sig_read_header(VISORCHANNEL *channel, u32 queue, queue, (int)SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)); ERRDRV("visor_memregion_read of signal queue failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } rc = TRUE; -Away: +cleanup: return rc; } @@ -357,18 +357,18 @@ sig_do_data(VISORCHANNEL *channel, u32 queue, data, sig_hdr->signal_size) < 0) { ERRDRV("visor_memregion_write of signal data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } } else { if (visor_memregion_read(channel->memregion, signal_data_offset, data, sig_hdr->signal_size) < 0) { ERRDRV("visor_memregion_read of signal data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } } rc = TRUE; -Away: +cleanup: return rc; } @@ -419,16 +419,16 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; - goto Away; + goto cleanup; } if (sig_hdr.head == sig_hdr.tail) { rc = FALSE; /* no signals to remove */ - goto Away; + goto cleanup; } sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) { ERRDRV("sig_read_data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } sig_hdr.num_received++; @@ -439,15 +439,15 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) { ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } rc = TRUE; -Away: +cleanup: if (channel->needs_lock) spin_unlock(&channel->remove_lock); @@ -466,7 +466,7 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) if (!sig_read_header(channel, queue, &sig_hdr)) { rc = FALSE; - goto Away; + goto cleanup; } sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots); @@ -475,15 +475,15 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) { ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } rc = FALSE; - goto Away; + goto cleanup; } if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) { ERRDRV("sig_write_data failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } sig_hdr.num_sent++; @@ -494,15 +494,15 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) { ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n", rc); - goto Away; + goto cleanup; } rc = TRUE; -Away: +cleanup: if (channel->needs_lock) spin_unlock(&channel->insert_lock); -- GitLab From f36b9dfed7da05e327ca22b44468a29623922c4e Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 6 Nov 2014 14:13:11 -0500 Subject: [PATCH 3698/9457] staging: unisys: visorchannel: Add braces to else arm of if/else statement Add braces to the else arm of an if/else block in visorchannel_funcs.c Signed-off-by: Bryan Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchannel/visorchannel_funcs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index a0fd358e0c28..36559d5fa673 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -596,8 +596,9 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues, if (off == 0) { phdr = &channel->chan_hdr; seq_puts(seq, "(following data may be stale)\n"); - } else + } else { return; + } } nbytes = (ulong)(phdr->size); seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n", -- GitLab From f9b64692e13b2f0d2a393e41972aa317f34a3e46 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 7 Nov 2014 17:48:34 +0530 Subject: [PATCH 3699/9457] staging: unisys: unneeded NULL check the NULL check for memregion is not required as it has already been checked for NULL after kzalloc. so we can reach this part of the code only if memregion is not NULL. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorutil/memregion_direct.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c index 26faad470705..33522cc8c22c 100644 --- a/drivers/staging/unisys/visorutil/memregion_direct.c +++ b/drivers/staging/unisys/visorutil/memregion_direct.c @@ -57,10 +57,8 @@ visor_memregion_create(HOSTADDRESS physaddr, ulong nbytes) rc = memregion; cleanup: if (rc == NULL) { - if (memregion != NULL) { - visor_memregion_destroy(memregion); - memregion = NULL; - } + visor_memregion_destroy(memregion); + memregion = NULL; } return rc; } -- GitLab From 930a021f2ec59d2143ca86a357773128785ed16f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 7 Nov 2014 17:48:35 +0530 Subject: [PATCH 3700/9457] staging: unisys: dereferencing NULL pointer we can reach the label Away in total five situation and in four of of them pDevInfo is NULL. so we were basically dereferencing a NULL pointer. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index b5a0e460da07..c8f7beaac87a 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -1298,7 +1298,8 @@ my_device_create(struct controlvm_message *inmsg) POSTCODE_SEVERITY_INFO); Away: /* get the bus and devNo for DiagPool channel */ - if (is_diagpool_channel(pDevInfo->chan_info.channel_type_uuid)) { + if (pDevInfo && + is_diagpool_channel(pDevInfo->chan_info.channel_type_uuid)) { g_diagpoolBusNo = busNo; g_diagpoolDevNo = devNo; LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu", -- GitLab From 314e5caa4b41555aec20ac39dd3df1ccc799bc65 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:00 +0000 Subject: [PATCH 3701/9457] staging: vt6655: baseband.h remove pDevice from struct vnt_private pointer Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 6ce856c01907..c41bc337c10d 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -80,11 +80,11 @@ void vnt_get_phy_field(struct vnt_private *, u32 frame_length, bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData); -void BBvSetShortSlotTime(struct vnt_private *pDevice); -void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData); +void BBvSetShortSlotTime(struct vnt_private *); +void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); /* VT3253 Baseband */ -bool BBbVT3253Init(struct vnt_private *pDevice); +bool BBbVT3253Init(struct vnt_private *); void BBvSoftwareReset(void __iomem *dwIoBase); void BBvPowerSaveModeON(void __iomem *dwIoBase); void BBvPowerSaveModeOFF(void __iomem *dwIoBase); @@ -105,9 +105,9 @@ TimerState1CallBack( unsigned long ); -void BBvAntennaDiversity(struct vnt_private *pDevice, +void BBvAntennaDiversity(struct vnt_private *, unsigned char byRxRate, unsigned char bySQ3); void -BBvClearAntDivSQ3Value(struct vnt_private *pDevice); +BBvClearAntDivSQ3Value(struct vnt_private *); #endif /* __BASEBAND_H__ */ -- GitLab From a5f0eef38b574248119353667eeee69559b9c291 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:01 +0000 Subject: [PATCH 3702/9457] staging: vt6655: baseband replace __iomem where caller is priv dereferenced. Replace with stucture vnt_private *priv in functions BBvSoftwareReset BBvSetTxAntennaMode BBvSetRxAntennaMode BBvSetDeepSleep BBvExitDeepSleep __iomem *dwIoBase will be moved into BBbWriteEmbedded and BBbReadEmbedded later. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 30 ++++++++++++++++++---------- drivers/staging/vt6655/baseband.h | 10 +++++----- drivers/staging/vt6655/card.c | 4 ++-- drivers/staging/vt6655/channel.c | 2 +- drivers/staging/vt6655/device_main.c | 6 +++--- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 32000d2bedb1..c6c811b18f46 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1719,22 +1719,22 @@ s_vChangeAntenna( if (priv->dwRxAntennaSel == 0) { priv->dwRxAntennaSel = 1; if (priv->bTxRxAntInv == true) - BBvSetRxAntennaMode(priv->PortOffset, ANT_A); + BBvSetRxAntennaMode(priv, ANT_A); else - BBvSetRxAntennaMode(priv->PortOffset, ANT_B); + BBvSetRxAntennaMode(priv, ANT_B); } else { priv->dwRxAntennaSel = 0; if (priv->bTxRxAntInv == true) - BBvSetRxAntennaMode(priv->PortOffset, ANT_B); + BBvSetRxAntennaMode(priv, ANT_B); else - BBvSetRxAntennaMode(priv->PortOffset, ANT_A); + BBvSetRxAntennaMode(priv, ANT_A); } if (priv->dwTxAntennaSel == 0) { priv->dwTxAntennaSel = 1; - BBvSetTxAntennaMode(priv->PortOffset, ANT_B); + BBvSetTxAntennaMode(priv, ANT_B); } else { priv->dwTxAntennaSel = 0; - BBvSetTxAntennaMode(priv->PortOffset, ANT_A); + BBvSetTxAntennaMode(priv, ANT_A); } } @@ -2266,8 +2266,10 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) * */ void -BBvSoftwareReset(void __iomem *dwIoBase) +BBvSoftwareReset(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; + BBbWriteEmbedded(dwIoBase, 0x50, 0x40); BBbWriteEmbedded(dwIoBase, 0x50, 0); BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); @@ -2333,8 +2335,9 @@ BBvPowerSaveModeOFF(void __iomem *dwIoBase) */ void -BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) +BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { + void __iomem *dwIoBase = priv->PortOffset; unsigned char byBBTxConf; BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf); /* CR09 */ @@ -2366,8 +2369,9 @@ BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) */ void -BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) +BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { + void __iomem *dwIoBase = priv->PortOffset; unsigned char byBBRxConf; BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf); /* CR10 */ @@ -2396,15 +2400,19 @@ BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode) * */ void -BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID) +BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { + void __iomem *dwIoBase = priv->PortOffset; + BBbWriteEmbedded(dwIoBase, 0x0C, 0x17); /* CR12 */ BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9); /* CR13 */ } void -BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID) +BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { + void __iomem *dwIoBase = priv->PortOffset; + BBbWriteEmbedded(dwIoBase, 0x0C, 0x00); /* CR12 */ BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); /* CR13 */ } diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index c41bc337c10d..8594347f45ac 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -85,13 +85,13 @@ void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); /* VT3253 Baseband */ bool BBbVT3253Init(struct vnt_private *); -void BBvSoftwareReset(void __iomem *dwIoBase); +void BBvSoftwareReset(struct vnt_private *); void BBvPowerSaveModeON(void __iomem *dwIoBase); void BBvPowerSaveModeOFF(void __iomem *dwIoBase); -void BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode); -void BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode); -void BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID); -void BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID); +void BBvSetTxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); +void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); +void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID); +void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID); /* timer for antenna diversity */ diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 60f051f8de8a..0121466b941d 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -445,7 +445,7 @@ bool CARDbRadioPowerOff(struct vnt_private *pDevice) MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); - BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvSetDeepSleep(pDevice, pDevice->byLocalID); pDevice->bRadioOff = true; pr_debug("chester power off\n"); @@ -480,7 +480,7 @@ bool CARDbRadioPowerOn(struct vnt_private *pDevice) pr_debug("chester pbRadioOff\n"); return true; } - BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID); + BBvExitDeepSleep(pDevice, pDevice->byLocalID); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 6bd5f161894d..cc1bc94ceaa3 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -197,7 +197,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) if (pDevice->bEnablePSMode) RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel); - BBvSoftwareReset(pDevice->PortOffset); + BBvSoftwareReset(pDevice); if (pDevice->byLocalID > REV_ID_VT3253_B1) { /* set HW default power register */ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 5fc6022badb2..397f13f10c1a 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -254,7 +254,7 @@ static void device_init_registers(struct vnt_private *pDevice) unsigned char byOFDMPwrdBm = 0; MACbShutdown(pDevice->PortOffset); - BBvSoftwareReset(pDevice->PortOffset); + BBvSoftwareReset(pDevice); /* Do MACbSoftwareReset in MACvInitialize */ MACbSoftwareReset(pDevice->PortOffset); @@ -446,8 +446,8 @@ static void device_init_registers(struct vnt_private *pDevice) BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); } - BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode); - BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode); + BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode); + BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode); /* Set BB and packet type at the same time. */ /* Set Short Slot Time, xIFS, and RSPINF. */ -- GitLab From 78b3c1fde09b072ee508ad26ffc237e5a3b6e6b1 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:02 +0000 Subject: [PATCH 3703/9457] staging: vt6655: baseband/rf s_bAL7230Init change __iomem for baseband functions Replace __iomem with vnt_private providing pointer for dwIoBase Change BBvPowerSaveModeON and BBvPowerSaveModeOFF to vnt_private and reference __iomem there, to be removed later. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 6 ++++-- drivers/staging/vt6655/baseband.h | 4 ++-- drivers/staging/vt6655/rf.c | 9 +++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index c6c811b18f46..9d5288ca2ed2 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2289,8 +2289,9 @@ BBvSoftwareReset(struct vnt_private *priv) * */ void -BBvPowerSaveModeON(void __iomem *dwIoBase) +BBvPowerSaveModeON(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; unsigned char byOrgData; BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); @@ -2311,8 +2312,9 @@ BBvPowerSaveModeON(void __iomem *dwIoBase) * */ void -BBvPowerSaveModeOFF(void __iomem *dwIoBase) +BBvPowerSaveModeOFF(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; unsigned char byOrgData; BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 8594347f45ac..26f9cdcb24b8 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -86,8 +86,8 @@ void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); /* VT3253 Baseband */ bool BBbVT3253Init(struct vnt_private *); void BBvSoftwareReset(struct vnt_private *); -void BBvPowerSaveModeON(void __iomem *dwIoBase); -void BBvPowerSaveModeOFF(void __iomem *dwIoBase); +void BBvPowerSaveModeON(struct vnt_private *); +void BBvPowerSaveModeOFF(struct vnt_private *); void BBvSetTxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode); void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID); diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index e505af91bfd0..2b1e7a09360e 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -424,8 +424,9 @@ static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = { * Return Value: true if succeeded; false if failed. * */ -static bool s_bAL7230Init(void __iomem *dwIoBase) +static bool s_bAL7230Init(struct vnt_private *priv) { + void __iomem *dwIoBase = priv->PortOffset; int ii; bool bResult; @@ -436,7 +437,7 @@ static bool s_bAL7230Init(void __iomem *dwIoBase) MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeOFF(dwIoBase); //RobertYu:20050106, have DC value for Calibration + BBvPowerSaveModeOFF(priv); /* RobertYu:20050106, have DC value for Calibration */ for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) bResult &= IFRFbWriteEmbedded(dwIoBase, dwAL7230InitTable[ii]); @@ -457,7 +458,7 @@ static bool s_bAL7230Init(void __iomem *dwIoBase) SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); - BBvPowerSaveModeON(dwIoBase); // RobertYu:20050106 + BBvPowerSaveModeON(priv); /* RobertYu:20050106 */ // PE1: TX_ON, PE2: RX_ON, PE3: PLLON //3-wire control for power saving mode @@ -759,7 +760,7 @@ bool RFbInit( break; case RF_AIROHA7230: pDevice->byMaxPwrLevel = AL7230_PWR_IDX_LEN; - bResult = s_bAL7230Init(pDevice->PortOffset); + bResult = s_bAL7230Init(pDevice); break; case RF_NOTHING: bResult = true; -- GitLab From 377f5bc00f7e147f01489821e13871b5c53966ff Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:03 +0000 Subject: [PATCH 3704/9457] staging: vt6655: BBbWriteEmbedded replace __iomem with vnt_private for callers Referencing dwIoBase inside function. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 82 +++++++++++++++---------------- drivers/staging/vt6655/baseband.h | 2 +- drivers/staging/vt6655/card.c | 24 ++++----- 3 files changed, 52 insertions(+), 56 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 9d5288ca2ed2..f1f10754963d 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2003,8 +2003,10 @@ bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch * Return Value: true if succeeded; false if failed. * */ -bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData) +bool BBbWriteEmbedded(struct vnt_private *priv, + unsigned char byBBAddr, unsigned char byData) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byValue; @@ -2056,14 +2058,14 @@ bool BBbVT3253Init(struct vnt_private *priv) if (byRFType == RF_RFMD2959) { if (byLocalID <= REV_ID_VT3253_A1) { for (ii = 0; ii < CB_VT3253_INIT_FOR_RFMD; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253InitTab_RFMD[ii][0], byVT3253InitTab_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253InitTab_RFMD[ii][0], byVT3253InitTab_RFMD[ii][1]); } else { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_RFMD; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_RFMD[ii][0], byVT3253B0_RFMD[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_RFMD[ii][0], byVT3253B0_RFMD[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC_FOR_RFMD2959; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC4_RFMD2959[ii][0], byVT3253B0_AGC4_RFMD2959[ii][1]); VNSvOutPortD(dwIoBase + MAC_REG_ITRTMSET, 0x23); MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); @@ -2078,10 +2080,10 @@ bool BBbVT3253Init(struct vnt_private *priv) priv->ldBmThreshold[3] = 0; } else if ((byRFType == RF_AIROHA) || (byRFType == RF_AL2230S)) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); priv->abyBBVGA[0] = 0x1C; priv->abyBBVGA[1] = 0x10; @@ -2093,10 +2095,10 @@ bool BBbVT3253Init(struct vnt_private *priv) priv->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2451) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); VNSvOutPortB(dwIoBase + MAC_REG_ITRTMSET, 0x23); MACvRegBitsOn(dwIoBase, MAC_REG_PAPEDELAY, BIT(0)); @@ -2111,28 +2113,28 @@ bool BBbVT3253Init(struct vnt_private *priv) priv->ldBmThreshold[3] = 0; } else if (byRFType == RF_UW2452) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]); /* Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);*/ /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ /* Select VC1/VC2, CR215 = 0x02->0x06 */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); /* {{RobertYu:20050125, request by Jack */ - bResult &= BBbWriteEmbedded(dwIoBase, 0x90, 0x20); - bResult &= BBbWriteEmbedded(dwIoBase, 0x97, 0xeb); + bResult &= BBbWriteEmbedded(priv, 0x90, 0x20); + bResult &= BBbWriteEmbedded(priv, 0x97, 0xeb); /* }} */ /* {{RobertYu:20050221, request by Jack */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xa6, 0x00); - bResult &= BBbWriteEmbedded(dwIoBase, 0xa8, 0x30); + bResult &= BBbWriteEmbedded(priv, 0xa6, 0x00); + bResult &= BBbWriteEmbedded(priv, 0xa8, 0x30); /* }} */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xb0, 0x58); + bResult &= BBbWriteEmbedded(priv, 0xb0, 0x58); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); priv->abyBBVGA[0] = 0x14; priv->abyBBVGA[1] = 0x0A; @@ -2146,10 +2148,10 @@ bool BBbVT3253Init(struct vnt_private *priv) } else if (byRFType == RF_VT3226) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); priv->abyBBVGA[0] = 0x1C; priv->abyBBVGA[1] = 0x10; @@ -2164,7 +2166,7 @@ bool BBbVT3253Init(struct vnt_private *priv) /* {{ RobertYu: 20050104 */ } else if (byRFType == RF_AIROHA7230) { for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]); /* {{ RobertYu:20050223, request by JerryChung */ @@ -2177,7 +2179,7 @@ bool BBbVT3253Init(struct vnt_private *priv) /* }} */ for (ii = 0; ii < CB_VT3253B0_AGC; ii++) - bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); + bResult &= BBbWriteEmbedded(priv, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]); priv->abyBBVGA[0] = 0x1C; priv->abyBBVGA[1] = 0x10; @@ -2195,8 +2197,8 @@ bool BBbVT3253Init(struct vnt_private *priv) } if (byLocalID > REV_ID_VT3253_A1) { - BBbWriteEmbedded(dwIoBase, 0x04, 0x7F); - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); + BBbWriteEmbedded(priv, 0x04, 0x7F); + BBbWriteEmbedded(priv, 0x0D, 0x01); } return bResult; @@ -2232,14 +2234,14 @@ BBvSetShortSlotTime(struct vnt_private *priv) if (byBBVGA == priv->abyBBVGA[0]) byBBRxConf |= 0x20; /* 0010 0000 */ - BBbWriteEmbedded(priv->PortOffset, 0x0A, byBBRxConf); /* CR10 */ + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) { unsigned char byBBRxConf = 0; - BBbWriteEmbedded(priv->PortOffset, 0xE7, byData); + BBbWriteEmbedded(priv, 0xE7, byData); BBbReadEmbedded(priv->PortOffset, 0x0A, &byBBRxConf); /* CR10 */ /* patch for 3253B0 Baseband with Cardbus module */ @@ -2250,7 +2252,7 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) else byBBRxConf |= 0x20; /* 0010 0000 */ priv->byBBVGACurrent = byData; - BBbWriteEmbedded(priv->PortOffset, 0x0A, byBBRxConf); /* CR10 */ + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } /* @@ -2268,12 +2270,10 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) void BBvSoftwareReset(struct vnt_private *priv) { - void __iomem *dwIoBase = priv->PortOffset; - - BBbWriteEmbedded(dwIoBase, 0x50, 0x40); - BBbWriteEmbedded(dwIoBase, 0x50, 0); - BBbWriteEmbedded(dwIoBase, 0x9C, 0x01); - BBbWriteEmbedded(dwIoBase, 0x9C, 0); + BBbWriteEmbedded(priv, 0x50, 0x40); + BBbWriteEmbedded(priv, 0x50, 0); + BBbWriteEmbedded(priv, 0x9C, 0x01); + BBbWriteEmbedded(priv, 0x9C, 0); } /* @@ -2296,7 +2296,7 @@ BBvPowerSaveModeON(struct vnt_private *priv) BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); byOrgData |= BIT(0); - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbWriteEmbedded(priv, 0x0D, byOrgData); } /* @@ -2319,7 +2319,7 @@ BBvPowerSaveModeOFF(struct vnt_private *priv) BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); byOrgData &= ~(BIT(0)); - BBbWriteEmbedded(dwIoBase, 0x0D, byOrgData); + BBbWriteEmbedded(priv, 0x0D, byOrgData); } /* @@ -2353,7 +2353,7 @@ BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) byBBTxConf &= 0xFD; /* 1111 1101 */ byBBTxConf |= 0x04; } - BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf); /* CR09 */ + BBbWriteEmbedded(priv, 0x09, byBBTxConf); /* CR09 */ } /* @@ -2386,7 +2386,7 @@ BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) byBBRxConf &= 0xFE; /* 1111 1110 */ byBBRxConf |= 0x02; } - BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf); /* CR10 */ + BBbWriteEmbedded(priv, 0x0A, byBBRxConf); /* CR10 */ } /* @@ -2404,19 +2404,15 @@ BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) void BBvSetDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { - void __iomem *dwIoBase = priv->PortOffset; - - BBbWriteEmbedded(dwIoBase, 0x0C, 0x17); /* CR12 */ - BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9); /* CR13 */ + BBbWriteEmbedded(priv, 0x0C, 0x17); /* CR12 */ + BBbWriteEmbedded(priv, 0x0D, 0xB9); /* CR13 */ } void BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID) { - void __iomem *dwIoBase = priv->PortOffset; - - BBbWriteEmbedded(dwIoBase, 0x0C, 0x00); /* CR12 */ - BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); /* CR13 */ + BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */ + BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */ } static diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 26f9cdcb24b8..743ec4f6538c 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -78,7 +78,7 @@ void vnt_get_phy_field(struct vnt_private *, u32 frame_length, u16 tx_rate, u8 pkt_type, struct vnt_phy_field *); bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); -bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData); +bool BBbWriteEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char byData); void BBvSetShortSlotTime(struct vnt_private *); void BBvSetVGAGainOffset(struct vnt_private *, unsigned char byData); diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 0121466b941d..6f1cea03513e 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -225,20 +225,20 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[3] = 0x10; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x1C) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); pDevice->abyBBVGA[0] = 0x18; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x14) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0x57); } } else { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03); + BBbWriteEmbedded(pDevice, 0x88, 0x03); bySlot = C_SLOT_SHORT; bySIFS = C_SIFS_A; byDIFS = C_SIFS_A + 2*C_SLOT_SHORT; @@ -251,17 +251,17 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[3] = 0x00; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x20) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0xD3); } } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02); + BBbWriteEmbedded(pDevice, 0x88, 0x02); bySlot = C_SLOT_LONG; bySIFS = C_SIFS_BG; byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; @@ -274,17 +274,17 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[3] = 0x00; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x20) - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); if (byData == 0x18) { - BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]); - BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3); + BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); + BBbWriteEmbedded(pDevice, 0xE1, 0xD3); } } - BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08); + BBbWriteEmbedded(pDevice, 0x88, 0x08); bySIFS = C_SIFS_BG; if (pDevice->bShortSlotTime) { -- GitLab From 8e8a9f5133cf4c31b3faae3986fb26bbc39c9216 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:04 +0000 Subject: [PATCH 3705/9457] staging: vt6655: BBbReadEmbedded replace __iomem with vnt_private Changing callers to point to private Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 22 ++++++++++------------ drivers/staging/vt6655/baseband.h | 2 +- drivers/staging/vt6655/card.c | 12 ++++++------ 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index f1f10754963d..86c72ba0a0cd 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1961,8 +1961,10 @@ void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, * Return Value: true if succeeded; false if failed. * */ -bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData) +bool BBbReadEmbedded(struct vnt_private *priv, + unsigned char byBBAddr, unsigned char *pbyData) { + void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byValue; @@ -2222,7 +2224,7 @@ BBvSetShortSlotTime(struct vnt_private *priv) unsigned char byBBRxConf = 0; unsigned char byBBVGA = 0; - BBbReadEmbedded(priv->PortOffset, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ if (priv->bShortSlotTime) byBBRxConf &= 0xDF; /* 1101 1111 */ @@ -2230,7 +2232,7 @@ BBvSetShortSlotTime(struct vnt_private *priv) byBBRxConf |= 0x20; /* 0010 0000 */ /* patch for 3253B0 Baseband with Cardbus module */ - BBbReadEmbedded(priv->PortOffset, 0xE7, &byBBVGA); + BBbReadEmbedded(priv, 0xE7, &byBBVGA); if (byBBVGA == priv->abyBBVGA[0]) byBBRxConf |= 0x20; /* 0010 0000 */ @@ -2243,7 +2245,7 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, unsigned char byData) BBbWriteEmbedded(priv, 0xE7, byData); - BBbReadEmbedded(priv->PortOffset, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ /* patch for 3253B0 Baseband with Cardbus module */ if (byData == priv->abyBBVGA[0]) byBBRxConf |= 0x20; /* 0010 0000 */ @@ -2291,10 +2293,9 @@ BBvSoftwareReset(struct vnt_private *priv) void BBvPowerSaveModeON(struct vnt_private *priv) { - void __iomem *dwIoBase = priv->PortOffset; unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); + BBbReadEmbedded(priv, 0x0D, &byOrgData); byOrgData |= BIT(0); BBbWriteEmbedded(priv, 0x0D, byOrgData); } @@ -2314,10 +2315,9 @@ BBvPowerSaveModeON(struct vnt_private *priv) void BBvPowerSaveModeOFF(struct vnt_private *priv) { - void __iomem *dwIoBase = priv->PortOffset; unsigned char byOrgData; - BBbReadEmbedded(dwIoBase, 0x0D, &byOrgData); + BBbReadEmbedded(priv, 0x0D, &byOrgData); byOrgData &= ~(BIT(0)); BBbWriteEmbedded(priv, 0x0D, byOrgData); } @@ -2339,10 +2339,9 @@ BBvPowerSaveModeOFF(struct vnt_private *priv) void BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { - void __iomem *dwIoBase = priv->PortOffset; unsigned char byBBTxConf; - BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf); /* CR09 */ + BBbReadEmbedded(priv, 0x09, &byBBTxConf); /* CR09 */ if (byAntennaMode == ANT_DIVERSITY) { /* bit 1 is diversity */ byBBTxConf |= 0x02; @@ -2373,10 +2372,9 @@ BBvSetTxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) void BBvSetRxAntennaMode(struct vnt_private *priv, unsigned char byAntennaMode) { - void __iomem *dwIoBase = priv->PortOffset; unsigned char byBBRxConf; - BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf); /* CR10 */ + BBbReadEmbedded(priv, 0x0A, &byBBRxConf); /* CR10 */ if (byAntennaMode == ANT_DIVERSITY) { byBBRxConf |= 0x01; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 743ec4f6538c..d9f6d63e4ab7 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -77,7 +77,7 @@ BBuGetFrameTime( void vnt_get_phy_field(struct vnt_private *, u32 frame_length, u16 tx_rate, u8 pkt_type, struct vnt_phy_field *); -bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData); +bool BBbReadEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char *pbyData); bool BBbWriteEmbedded(struct vnt_private *, unsigned char byBBAddr, unsigned char byData); void BBvSetShortSlotTime(struct vnt_private *); diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 6f1cea03513e..1869557e41d3 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -223,14 +223,14 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[0] = 0x20; pDevice->abyBBVGA[2] = 0x10; pDevice->abyBBVGA[3] = 0x10; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x1C) BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A); pDevice->abyBBVGA[0] = 0x18; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x14) { BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); BBbWriteEmbedded(pDevice, 0xE1, 0x57); @@ -249,13 +249,13 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x20) BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x18) { BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); BBbWriteEmbedded(pDevice, 0xE1, 0xD3); @@ -272,13 +272,13 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, pDevice->abyBBVGA[0] = 0x1C; pDevice->abyBBVGA[2] = 0x00; pDevice->abyBBVGA[3] = 0x00; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x20) BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); } else if (pDevice->byRFType == RF_UW2452) { pDevice->abyBBVGA[0] = 0x14; - BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData); + BBbReadEmbedded(pDevice, 0xE7, &byData); if (byData == 0x18) { BBbWriteEmbedded(pDevice, 0xE7, pDevice->abyBBVGA[0]); BBbWriteEmbedded(pDevice, 0xE1, 0xD3); -- GitLab From 61b90995d3629f2f6b1493d10f0b6a56d17af0ad Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 6 Nov 2014 20:02:05 +0000 Subject: [PATCH 3706/9457] staging: vt6655: Fix issue of byPacketType is not set at all. set by calling CARDbyGetPktType. change CARDbIsOFDMinBasicRate to check basic_rates. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 1869557e41d3..aaa72891fc51 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -342,6 +342,8 @@ bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin); } + pDevice->byPacketType = CARDbyGetPktType(pDevice); + CARDvSetRSPINF(pDevice, ePHYType); return true; @@ -876,7 +878,7 @@ bool CARDbIsOFDMinBasicRate(struct vnt_private *pDevice) int ii; for (ii = RATE_54M; ii >= RATE_6M; ii--) { - if ((pDevice->wBasicRate) & ((unsigned short)(1 << ii))) + if ((pDevice->basic_rates) & ((u32)(1 << ii))) return true; } return false; -- GitLab From 5aa1491a63d643e3eeb03b8a351a8d51d515baf7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 17:47:35 +0000 Subject: [PATCH 3707/9457] staging: comedi: comedidev.h: remove dummy PCI support functions Some low-level Comedi driver modules used to handle PCI devices and ISA devices in the same module with some conditional compilation. To reduce the amount of conditional compilation, some dummy inline versions of `comedi_to_pci_dev()`, `comedi_pci_enable()`, `comedi_pci_disable()`, and `comedi_pci_detach()` are defined in "comedidev.h" if `CONFIG_COMEDI_PCI_DRIVERS` is undefined. Since those Comedi low-level driver modules have since had PCI support split out into separate modules, there is no need to keep the dummy inline functions around any more, so remove them. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index bff5a581a287..0c0039a56a0c 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -603,32 +603,6 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); module_driver(__comedi_driver, comedi_pci_driver_register, \ comedi_pci_driver_unregister, &(__pci_driver)) -#else - -/* - * Some of the comedi mixed ISA/PCI drivers call the PCI specific - * functions. Provide some dummy functions if CONFIG_COMEDI_PCI_DRIVERS - * is not enabled. - */ - -static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) -{ - return NULL; -} - -static inline int comedi_pci_enable(struct comedi_device *dev) -{ - return -ENOSYS; -} - -static inline void comedi_pci_disable(struct comedi_device *dev) -{ -} - -static inline void comedi_pci_detach(struct comedi_device *dev) -{ -} - #endif /* CONFIG_COMEDI_PCI_DRIVERS */ #ifdef CONFIG_COMEDI_PCMCIA_DRIVERS -- GitLab From d51b365101d80bb99b9da723fd0cdb88e1a3ee12 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 17:47:36 +0000 Subject: [PATCH 3708/9457] staging: comedi: comedidev.h: remove some #ifdefs Some declarations and macro definitions in "comedidev.h" are protected by various `#ifdef`s for kernel configuration options, but the header file compiles fine without the `#ifdef`s regardless of whether those config option macros are defined or not. Remove the `#ifdef`s and compile the affected code unconditionally. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 0c0039a56a0c..b5e0ec3e4bf8 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -558,8 +558,6 @@ void comedi_driver_unregister(struct comedi_driver *); module_driver(__comedi_driver, comedi_driver_register, \ comedi_driver_unregister) -#ifdef CONFIG_COMEDI_PCI_DRIVERS - /* comedi_pci.c - comedi PCI driver specific functions */ /* @@ -603,10 +601,6 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); module_driver(__comedi_driver, comedi_pci_driver_register, \ comedi_pci_driver_unregister, &(__pci_driver)) -#endif /* CONFIG_COMEDI_PCI_DRIVERS */ - -#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS - /* comedi_pcmcia.c - comedi PCMCIA driver specific functions */ struct pcmcia_driver; @@ -640,10 +634,6 @@ void comedi_pcmcia_driver_unregister(struct comedi_driver *, module_driver(__comedi_driver, comedi_pcmcia_driver_register, \ comedi_pcmcia_driver_unregister, &(__pcmcia_driver)) -#endif /* CONFIG_COMEDI_PCMCIA_DRIVERS */ - -#ifdef CONFIG_COMEDI_USB_DRIVERS - /* comedi_usb.c - comedi USB driver specific functions */ struct usb_driver; @@ -673,6 +663,4 @@ void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); module_driver(__comedi_driver, comedi_usb_driver_register, \ comedi_usb_driver_unregister, &(__usb_driver)) -#endif /* CONFIG_COMEDI_USB_DRIVERS */ - #endif /* _COMEDIDEV_H */ -- GitLab From aae434b3c34d124abe2dc4ea86d9ba9b2bcf403a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 17:47:37 +0000 Subject: [PATCH 3709/9457] staging: comedi: split out PCMCIA support into new module Setting the `CONFIG_COMEDI_PCMCIA_DRIVERS` kernel configuration option makes the main "comedi" module depend on the "pcmcia" module, but many machines don't have PCMCIA slots and only a few low-level Comedi drivers need PCMCIA support. The Comedi PCMCIA support functions are all in "comedi_pcmcia.c". Turn it into a separate module so we don't have to pull in the other PCMCIA support modules unnecessarily. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 ++++- drivers/staging/comedi/Makefile | 3 ++- drivers/staging/comedi/comedi_pcmcia.c | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index b2d68ecb5e24..862b18fa2de4 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1076,11 +1076,14 @@ config COMEDI_NI_TIOCMD endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS - bool "Comedi PCMCIA drivers" + tristate "Comedi PCMCIA drivers" depends on PCMCIA ---help--- Enable support for comedi PCMCIA drivers. + To compile this support as a module, choose M here: the module will + be called comedi_pcmcia. + if COMEDI_PCMCIA_DRIVERS config COMEDI_CB_DAS16_CS diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index fae2d9090006..cfb121a52978 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -3,11 +3,12 @@ ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o -comedi-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o comedi-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o comedi-$(CONFIG_PROC_FS) += proc.o comedi-$(CONFIG_COMPAT) += comedi_compat32.o +obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o + obj-$(CONFIG_COMEDI) += comedi.o obj-$(CONFIG_COMEDI) += kcomedilib/ diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c index 9d49d5d01ad9..0529bae8e5ac 100644 --- a/drivers/staging/comedi/comedi_pcmcia.c +++ b/drivers/staging/comedi/comedi_pcmcia.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include #include #include @@ -154,3 +155,18 @@ void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister); + +static int __init comedi_pcmcia_init(void) +{ + return 0; +} +module_init(comedi_pcmcia_init); + +static void __exit comedi_pcmcia_exit(void) +{ +} +module_exit(comedi_pcmcia_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi PCMCIA interface module"); +MODULE_LICENSE("GPL"); -- GitLab From ba9ac25e96241d7f059dac3fcb9175c1491e425d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 17:47:38 +0000 Subject: [PATCH 3710/9457] staging: comedi: split out USB support into new module Setting the `CONFIG_COMEDI_USB_DRIVERS` kernel configuration option makes the main "comedi" module depend on the "usbcore" module. But perhaps the machine has no USB controllers (or they have been disabled), in which case the "usbcore" module may have been pulled in unnecessarily. Only a few low-level Comedi drivers require USB support. The Comedi USB support functions are all in "comedi_usb.c". Turn it into a separate module so we don't have to pull in the "usbcore" and "usb_common" modules unnecessarily. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 ++++- drivers/staging/comedi/Makefile | 2 +- drivers/staging/comedi/comedi_usb.c | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 862b18fa2de4..9e22ea1f8c54 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1155,11 +1155,14 @@ config COMEDI_QUATECH_DAQP_CS endif # COMEDI_PCMCIA_DRIVERS menuconfig COMEDI_USB_DRIVERS - bool "Comedi USB drivers" + tristate "Comedi USB drivers" depends on USB ---help--- Enable support for comedi USB drivers. + To compile this support as a module, choose M here: the module will + be called comedi_usb. + if COMEDI_USB_DRIVERS config COMEDI_DT9812 diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index cfb121a52978..e28eaeb598be 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -3,11 +3,11 @@ ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o -comedi-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o comedi-$(CONFIG_PROC_FS) += proc.o comedi-$(CONFIG_COMPAT) += comedi_compat32.o obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o +obj-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o obj-$(CONFIG_COMEDI) += comedi.o diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c index 13f18bef6091..0b862a64c049 100644 --- a/drivers/staging/comedi/comedi_usb.c +++ b/drivers/staging/comedi/comedi_usb.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include #include #include "comedidev.h" @@ -114,3 +115,18 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +static int __init comedi_usb_init(void) +{ + return 0; +} +module_init(comedi_usb_init); + +static void __exit comedi_usb_exit(void) +{ +} +module_exit(comedi_usb_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi USB interface module"); +MODULE_LICENSE("GPL"); -- GitLab From bc3fe15655c2bac782f45dce8b8c1537f07d9e81 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 31 Oct 2014 17:47:39 +0000 Subject: [PATCH 3711/9457] staging: comedi: split out PCI support into new module Setting the `CONFIG_COMEDI_PCI_DRIVERS` kernel configuration option makes the main "comedi" module depend on the PCI support in the kernel. That's not that big a deal since PCI support in the kernel is either built into the kernel or is absent, and is not in a separate module. Still, not all low-level Comedi drivers need PCI support, so we could save a bit of space by not including it. The Comedi PCI support functions are all in "comedi_pci.c". Turn it into a separate module so the support code doesn't have to be loaded unnecessarily. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 ++++- drivers/staging/comedi/Makefile | 2 +- drivers/staging/comedi/comedi_pci.c | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 9e22ea1f8c54..cf52577349a7 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -564,11 +564,14 @@ config COMEDI_S526 endif # COMEDI_ISA_DRIVERS menuconfig COMEDI_PCI_DRIVERS - bool "Comedi PCI drivers" + tristate "Comedi PCI drivers" depends on PCI ---help--- Enable support for comedi PCI drivers. + To compile this support as a module, choose M here: the module will + be called comedi_pci. + if COMEDI_PCI_DRIVERS config COMEDI_8255_PCI diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index e28eaeb598be..7f9dfb3923ab 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -2,10 +2,10 @@ ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o -comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o comedi-$(CONFIG_PROC_FS) += proc.o comedi-$(CONFIG_COMPAT) += comedi_compat32.o +obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o obj-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index aa0795a2660e..6ba59c977006 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include #include #include @@ -168,3 +169,18 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); + +static int __init comedi_pci_init(void) +{ + return 0; +} +module_init(comedi_pci_init); + +static void __exit comedi_pci_exit(void) +{ +} +module_exit(comedi_pci_exit); + +MODULE_AUTHOR("http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi PCI interface module"); +MODULE_LICENSE("GPL"); -- GitLab From f10f9fb2167bfb5f02a63eb320813ff3c71eec98 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 7 Nov 2014 16:46:42 +0200 Subject: [PATCH 3712/9457] stmmac: platform: fix sparse warnings This patch fixes the following sparse warnings. One is fixed by casting return value to a return type of the function. The others by creating a specific stmmac_platform.h which provides the bits related to the platform driver. drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c:59:29: warning: incorrect type in return expression (different address spaces) drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c:59:29: expected void * drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c:59:29: got void [noderef] *reg drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c:64:29: warning: symbol 'meson6_dwmac_data' was not declared. Should it be static? drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c:354:29: warning: symbol 'stih4xx_dwmac_data' was not declared. Should it be static? drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c:361:29: warning: symbol 'stid127_dwmac_data' was not declared. Should it be static? drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c:133:29: warning: symbol 'sun7i_gmac_data' was not declared. Should it be static? Signed-off-by: Andy Shevchenko Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-meson.c | 4 ++- .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 ++ .../net/ethernet/stmicro/stmmac/dwmac-sti.c | 2 ++ .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 ++ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 5 ---- .../ethernet/stmicro/stmmac/stmmac_platform.c | 2 ++ .../ethernet/stmicro/stmmac/stmmac_platform.h | 28 +++++++++++++++++++ 7 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c index d225a603e604..cca028d632f6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c @@ -18,6 +18,8 @@ #include #include +#include "stmmac_platform.h" + #define ETHMAC_SPEED_100 BIT(1) struct meson_dwmac { @@ -56,7 +58,7 @@ static void *meson6_dwmac_setup(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 1); dwmac->reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dwmac->reg)) - return dwmac->reg; + return ERR_CAST(dwmac->reg); return dwmac; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 3aad413e74b4..e97074cd5800 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -23,7 +23,9 @@ #include #include #include + #include "stmmac.h" +#include "stmmac_platform.h" #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c index ccfe7e510418..ea4069276444 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c @@ -22,6 +22,8 @@ #include #include +#include "stmmac_platform.h" + #define DWMAC_125MHZ 125000000 #define DWMAC_50MHZ 50000000 #define DWMAC_25MHZ 25000000 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c index 771cd15fca18..a26bda274c66 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c @@ -22,6 +22,8 @@ #include #include +#include "stmmac_platform.h" + struct sunxi_priv_data { int interface; int clk_enabled; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 709798b6aec3..bd75ee8b2757 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -135,11 +135,6 @@ void stmmac_disable_eee_mode(struct stmmac_priv *priv); bool stmmac_eee_init(struct stmmac_priv *priv); #ifdef CONFIG_STMMAC_PLATFORM -extern const struct stmmac_of_data meson6_dwmac_data; -extern const struct stmmac_of_data sun7i_gmac_data; -extern const struct stmmac_of_data stih4xx_dwmac_data; -extern const struct stmmac_of_data stid127_dwmac_data; -extern const struct stmmac_of_data socfpga_gmac_data; extern struct platform_driver stmmac_pltfr_driver; static inline int stmmac_register_platform(void) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index f4fe854f3ee3..9f18401022e1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -27,7 +27,9 @@ #include #include #include + #include "stmmac.h" +#include "stmmac_platform.h" static const struct of_device_id stmmac_dt_ids[] = { /* SoC specific glue layers should come before generic bindings */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h new file mode 100644 index 000000000000..25dd1f7ace02 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h @@ -0,0 +1,28 @@ +/******************************************************************************* + Copyright (C) 2007-2009 STMicroelectronics Ltd + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Author: Giuseppe Cavallaro +*******************************************************************************/ + +#ifndef __STMMAC_PLATFORM_H__ +#define __STMMAC_PLATFORM_H__ + +extern const struct stmmac_of_data meson6_dwmac_data; +extern const struct stmmac_of_data sun7i_gmac_data; +extern const struct stmmac_of_data stih4xx_dwmac_data; +extern const struct stmmac_of_data stid127_dwmac_data; +extern const struct stmmac_of_data socfpga_gmac_data; + +#endif /* __STMMAC_PLATFORM_H__ */ -- GitLab From 2ee37750014220c5cc5f560e967432edb870c890 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:29 -0700 Subject: [PATCH 3713/9457] staging: comedi: drivers: introduce comedi_nscans_left() Introduce a helper function to determine the number of scans left in the async command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 ++ drivers/staging/comedi/drivers.c | 39 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index b5e0ec3e4bf8..616e9b08c026 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -516,6 +516,8 @@ int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *, unsigned int comedi_dio_update_state(struct comedi_subdevice *, unsigned int *data); unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s); +unsigned int comedi_nscans_left(struct comedi_subdevice *s, + unsigned int nscans); void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 02a01baf5cc6..00194a5092cf 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -327,6 +327,45 @@ unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s) } EXPORT_SYMBOL_GPL(comedi_bytes_per_scan); +/** + * comedi_nscans_left - return the number of scans left in the command + * @s: comedi_subdevice struct + * @nscans: the expected number of scans + * + * If nscans is 0, the number of scans available in the async buffer will be + * used. Otherwise the expected number of scans will be used. + * + * If the async command has a stop_src of TRIG_COUNT, the nscans will be + * checked against the number of scans left in the command. + * + * The return value will then be either the expected number of scans or the + * number of scans remaining in the command. + */ +unsigned int comedi_nscans_left(struct comedi_subdevice *s, + unsigned int nscans) +{ + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + + if (nscans == 0) { + unsigned int nbytes = comedi_buf_read_n_available(s); + + nscans = nbytes / comedi_bytes_per_scan(s); + } + + if (cmd->stop_src == TRIG_COUNT) { + unsigned int scans_left = 0; + + if (async->scans_done < cmd->stop_arg) + scans_left = cmd->stop_arg - async->scans_done; + + if (nscans > scans_left) + nscans = scans_left; + } + return nscans; +} +EXPORT_SYMBOL_GPL(comedi_nscans_left); + /** * comedi_inc_scan_progress - update scan progress in asynchronous command * @s: comedi_subdevice struct -- GitLab From d682141e59676c2c31c2c8a939348369429b1042 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:30 -0700 Subject: [PATCH 3714/9457] staging: comedi: amplc_pci224: use comedi_async 'scans_done' to detect EOA Remove the private data member 'ao_stop_count' and use the comedi_async 'scans_done' member to detect the end-of-acquisition. Use the helper function comedi_nscans_left() to determine the number of scans available in the async buffer or left in the command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 43 ++++++------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 342779f1f84a..a896f0192fbd 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -381,7 +381,6 @@ struct pci224_private { unsigned short daccon; unsigned int cached_div1; unsigned int cached_div2; - unsigned int ao_stop_count; unsigned short ao_enab; /* max 16 channels so 'short' will do */ unsigned char intsce; }; @@ -514,26 +513,18 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, { struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int num_scans; + unsigned int num_scans = comedi_nscans_left(s, 0); unsigned int room; unsigned short dacstat; unsigned int i, n; - /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / comedi_bytes_per_scan(s); - if (cmd->stop_src == TRIG_COUNT) { - /* Fixed number of scans. */ - if (num_scans > devpriv->ao_stop_count) - num_scans = devpriv->ao_stop_count; - } - /* Determine how much room is in the FIFO (in samples). */ dacstat = inw(dev->iobase + PCI224_DACCON); switch (dacstat & PCI224_DACCON_FIFOFL_MASK) { case PCI224_DACCON_FIFOFL_EMPTY: room = PCI224_FIFO_ROOM_EMPTY; if (cmd->stop_src == TRIG_COUNT && - devpriv->ao_stop_count == 0) { + s->async->scans_done >= cmd->stop_arg) { /* FIFO empty at end of counted acquisition. */ s->async->events |= COMEDI_CB_EOA; comedi_handle_events(dev, s); @@ -574,18 +565,16 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, dev->iobase + PCI224_DACDATA); } } - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_stop_count -= num_scans; - if (devpriv->ao_stop_count == 0) { - /* - * Change FIFO interrupt trigger level to wait - * until FIFO is empty. - */ - devpriv->daccon = COMBINE(devpriv->daccon, - PCI224_DACCON_FIFOINTR_EMPTY, - PCI224_DACCON_FIFOINTR_MASK); - outw(devpriv->daccon, dev->iobase + PCI224_DACCON); - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { + /* + * Change FIFO interrupt trigger level to wait + * until FIFO is empty. + */ + devpriv->daccon = COMBINE(devpriv->daccon, + PCI224_DACCON_FIFOINTR_EMPTY, + PCI224_DACCON_FIFOINTR_MASK); + outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) == PCI224_DACCON_TRIG_NONE) { @@ -907,14 +896,6 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->scan_begin_src == TRIG_TIMER) pci224_ao_start_pacer(dev, s); - /* - * Sort out end of acquisition. - */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_stop_count = cmd->stop_arg; - else /* TRIG_EXT | TRIG_NONE */ - devpriv->ao_stop_count = 0; - spin_lock_irqsave(&devpriv->ao_spinlock, flags); if (cmd->start_src == TRIG_INT) { s->async->inttrig = pci224_ao_inttrig_start; -- GitLab From f5345d459b4bf5382ad5e419544b7b99f6674c6f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:31 -0700 Subject: [PATCH 3715/9457] staging: comedi: comedi_test: use comedi_async 'scans_done' to detect EOA Remove the private data member 'ai_count' and use the comedi_async 'scans_done' member to detect the end-of-acquisition. Use the helper function comedi_nscans_left() to check if the number of scans left in the command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 1b1399bcda5c..e56525a1c8f3 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -68,7 +68,6 @@ struct waveform_private { unsigned long usec_period; /* waveform period in microseconds */ unsigned long usec_current; /* current time (mod waveform period) */ unsigned long usec_remainder; /* usec since last scan */ - unsigned long ai_count; /* number of conversions remaining */ unsigned long state_bits; unsigned int scan_period; /* scan period in usec */ unsigned int convert_period; /* conversion period in usec */ @@ -178,7 +177,6 @@ static void waveform_ai_interrupt(unsigned long arg) unsigned long elapsed_time; unsigned int num_scans; ktime_t now; - bool stopping = false; /* check command is still active */ if (!test_bit(WAVEFORM_AI_RUNNING, &devpriv->state_bits)) @@ -193,16 +191,7 @@ static void waveform_ai_interrupt(unsigned long arg) devpriv->usec_remainder = (devpriv->usec_remainder + elapsed_time) % devpriv->scan_period; - if (cmd->stop_src == TRIG_COUNT) { - unsigned int remaining = cmd->stop_arg - devpriv->ai_count; - - if (num_scans >= remaining) { - /* about to finish */ - num_scans = remaining; - stopping = true; - } - } - + num_scans = comedi_nscans_left(s, num_scans); for (i = 0; i < num_scans; i++) { for (j = 0; j < cmd->chanlist_len; j++) { unsigned short sample; @@ -216,11 +205,10 @@ static void waveform_ai_interrupt(unsigned long arg) } } - devpriv->ai_count += i; devpriv->usec_current += elapsed_time; devpriv->usec_current %= devpriv->usec_period; - if (stopping) + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) async->events |= COMEDI_CB_EOA; else mod_timer(&devpriv->timer, jiffies + 1); @@ -317,7 +305,6 @@ static int waveform_ai_cmd(struct comedi_device *dev, return -1; } - devpriv->ai_count = 0; devpriv->scan_period = cmd->scan_begin_arg / nano_per_micro; if (cmd->convert_src == TRIG_NOW) -- GitLab From a65ccf634c91005bfc2c715b09aa43c1b18ce865 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:32 -0700 Subject: [PATCH 3716/9457] staging: comedi: amplc_pci230: use comedi_async 'scans_done' to detect AO EOA Remove the private data member 'ai_count' and use the comedi_async 'scans_done' member to detect the analog output end-of-acquisition. Use the helper function comedi_nscans_left() to get the number of scans in the async buffer of left in the command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 57 ++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a46fffd28a3e..5f4b67505932 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -491,7 +491,6 @@ struct pci230_private { spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ unsigned long daqio; /* PCI230's DAQ I/O space */ unsigned int ai_scan_count; /* Number of AI scans remaining */ - unsigned int ao_scan_count; /* Number of AO scans remaining. */ int intr_cpuid; /* ID of CPU running ISR */ unsigned short hwver; /* Hardware version (for '+' models) */ unsigned short adccon; /* ADCCON register value */ @@ -1073,13 +1072,12 @@ static void pci230_ao_stop(struct comedi_device *dev, static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned short data; int i; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0) + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) return; for (i = 0; i < cmd->chanlist_len; i++) { @@ -1093,13 +1091,8 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, s->readback[chan] = data; } - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_scan_count--; - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - async->events |= COMEDI_CB_EOA; - } - } + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; } /* @@ -1112,7 +1105,7 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int num_scans; + unsigned int num_scans = comedi_nscans_left(s, 0); unsigned int room; unsigned short dacstat; unsigned int i, n; @@ -1120,17 +1113,10 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, /* Get DAC FIFO status. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); - /* Determine number of scans available in buffer. */ - num_scans = comedi_buf_read_n_available(s) / comedi_bytes_per_scan(s); - if (cmd->stop_src == TRIG_COUNT) { - /* Fixed number of scans. */ - if (num_scans > devpriv->ao_scan_count) - num_scans = devpriv->ao_scan_count; - if (devpriv->ao_scan_count == 0) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; - } - } + + if (cmd->stop_src == TRIG_COUNT && num_scans == 0) + events |= COMEDI_CB_EOA; + if (events == 0) { /* Check for FIFO underrun. */ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) { @@ -1175,21 +1161,16 @@ static bool pci230_handle_ao_fifo(struct comedi_device *dev, } } - if (cmd->stop_src == TRIG_COUNT) { - devpriv->ao_scan_count -= num_scans; - if (devpriv->ao_scan_count == 0) { - /* - * All data for the command has been written - * to FIFO. Set FIFO interrupt trigger level - * to 'empty'. - */ - devpriv->daccon = - (devpriv->daccon & - ~PCI230P2_DAC_INT_FIFO_MASK) | - PCI230P2_DAC_INT_FIFO_EMPTY; - outw(devpriv->daccon, - devpriv->daqio + PCI230_DACCON); - } + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + /* + * All data for the command has been written + * to FIFO. Set FIFO interrupt trigger level + * to 'empty'. + */ + devpriv->daccon &= ~PCI230P2_DAC_INT_FIFO_MASK; + devpriv->daccon |= PCI230P2_DAC_INT_FIFO_EMPTY; + outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); } /* Check if FIFO underrun occurred while writing to FIFO. */ dacstat = inw(devpriv->daqio + PCI230_DACCON); @@ -1341,8 +1322,6 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; } - devpriv->ao_scan_count = cmd->stop_arg; - /* * Set range - see analogue output range table; 0 => unipolar 10V, * 1 => bipolar +/-10V range scale -- GitLab From f615915ee5faf74d8912df1694e810c8269f6b3f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:33 -0700 Subject: [PATCH 3717/9457] staging: comedi: drivers: introduce comedi_nsamples_left() Introduce a helper function to calculate the number of samples remaining when the cmd->stop_src is TRIG_COUNT. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 ++ drivers/staging/comedi/drivers.c | 32 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 616e9b08c026..77be191988ca 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -518,6 +518,8 @@ unsigned int comedi_dio_update_state(struct comedi_subdevice *, unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s); unsigned int comedi_nscans_left(struct comedi_subdevice *s, unsigned int nscans); +unsigned int comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples); void comedi_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 00194a5092cf..82ac84504589 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -366,6 +366,38 @@ unsigned int comedi_nscans_left(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_nscans_left); +/** + * comedi_nsamples_left - return the number of samples left in the command + * @s: comedi_subdevice struct + * @nsamples: the expected number of samples + * + * Returns the expected number of samples of the number of samples remaining + * in the command. + */ +unsigned int comedi_nsamples_left(struct comedi_subdevice *s, + unsigned int nsamples) +{ + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + + if (cmd->stop_src == TRIG_COUNT) { + /* +1 to force comedi_nscans_left() to return the scans left */ + unsigned int nscans = (nsamples / cmd->scan_end_arg) + 1; + unsigned int scans_left = comedi_nscans_left(s, nscans); + unsigned long long samples_left = 0; + + if (scans_left) { + samples_left = ((unsigned long long)scans_left * + cmd->scan_end_arg) - async->cur_chan; + } + + if (samples_left < nsamples) + nsamples = samples_left; + } + return nsamples; +} +EXPORT_SYMBOL_GPL(comedi_nsamples_left); + /** * comedi_inc_scan_progress - update scan progress in asynchronous command * @s: comedi_subdevice struct -- GitLab From c6de95f467073aa0913de9bace18946c51283826 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:34 -0700 Subject: [PATCH 3718/9457] staging: comedi: amplc_pci230: use comedi_async 'scans_done' to detect AI EOA Remove the private data member 'ai_scan_count' and use the comedi_async 'scans_done' member to detect the analog input end-of-acquisition. Use the comedi_nsamples_left() helper to work out the number of 'wake' samples in pci230_ai_update_fifo_trigger_level() and the number of 'todo' samples actually added to the async buffer in pci230_handle_ai(). Remove the unnecessary COMEDI_CB_OVERFLOW event for the hardware FIFO overflow error. The COMEDI_CB_ERROR event will terminate the command. comedi_buf_write_samples() can fail if the async buffer does not have room for the sample. The it will set the COMEDI_CB_OVERFLOW event and return 0. Detect this and quit trying to read and add more samples. The event will terminate the command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 5f4b67505932..fb0b70fdce7d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -490,7 +490,6 @@ struct pci230_private { spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */ spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ unsigned long daqio; /* PCI230's DAQ I/O space */ - unsigned int ai_scan_count; /* Number of AI scans remaining */ int intr_cpuid; /* ID of CPU running ISR */ unsigned short hwver; /* Hardware version (for '+' models) */ unsigned short adccon; /* ADCCON register value */ @@ -1720,19 +1719,15 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, { struct pci230_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int scanlen = cmd->scan_end_arg; unsigned int wake; unsigned short triglev; unsigned short adccon; if (cmd->flags & CMDF_WAKE_EOS) - wake = scanlen - s->async->cur_chan; - else if (cmd->stop_src != TRIG_COUNT || - devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL || - scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) - wake = PCI230_ADC_FIFOLEVEL_HALFFULL; + wake = cmd->scan_end_arg - s->async->cur_chan; else - wake = devpriv->ai_scan_count * scanlen - s->async->cur_chan; + wake = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL); + if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) { triglev = PCI230_ADC_INT_FIFO_HALF; } else if (wake > 1 && devpriv->hwver > 0) { @@ -2025,8 +2020,6 @@ static void pci230_handle_ai(struct comedi_device *dev, struct pci230_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - unsigned int scanlen = cmd->scan_end_arg; - unsigned int events = 0; unsigned int status_fifo; unsigned int i; unsigned int todo; @@ -2034,20 +2027,10 @@ static void pci230_handle_ai(struct comedi_device *dev, unsigned short val; /* Determine number of samples to read. */ - if (cmd->stop_src != TRIG_COUNT) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else if (devpriv->ai_scan_count == 0) { - todo = 0; - } else if (devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL || - scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL) { - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } else { - todo = devpriv->ai_scan_count * scanlen - async->cur_chan; - if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) - todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } + todo = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL); if (todo == 0) return; + fifoamount = 0; for (i = 0; i < todo; i++) { if (fifoamount == 0) { @@ -2059,7 +2042,7 @@ static void pci230_handle_ai(struct comedi_device *dev, * unnoticed by the caller. */ dev_err(dev->class_dev, "AI FIFO overrun\n"); - events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; + async->events |= COMEDI_CB_ERROR; break; } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) { /* FIFO empty. */ @@ -2080,21 +2063,21 @@ static void pci230_handle_ai(struct comedi_device *dev, } val = pci230_ai_read(dev); - comedi_buf_write_samples(s, &val, 1); + if (!comedi_buf_write_samples(s, &val, 1)) + break; fifoamount--; - if (async->cur_chan == 0) - devpriv->ai_scan_count--; - } - if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) { - /* End of acquisition. */ - events |= COMEDI_CB_EOA; + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + break; + } } - async->events |= events; - if (!(async->events & COMEDI_CB_CANCEL_MASK)) { - /* update FIFO interrupt trigger level */ + + /* update FIFO interrupt trigger level if still running */ + if (!(async->events & COMEDI_CB_CANCEL_MASK)) pci230_ai_update_fifo_trigger_level(dev, s); - } } static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) @@ -2130,8 +2113,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD)) return -EBUSY; - devpriv->ai_scan_count = cmd->stop_arg; - /* * Steps: * - Set channel scan list. -- GitLab From 979f99963cedb8a25f21ac9315082719d768379b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:35 -0700 Subject: [PATCH 3719/9457] staging: comedi: usbduxfast: use comedi_async 'scans_done' to detect AI EOA Remove the private data member 'ai_sample_count' and use the comedi_async 'scans_done' member to detect the analog input end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually add to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 5de76aba8fd9..ddc4cb9d5ed4 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -161,7 +161,6 @@ struct usbduxfast_private { uint8_t *duxbuf; int8_t *inbuf; short int ai_cmd_running; /* asynchronous command is running */ - long int ai_sample_count; /* number of samples to acquire */ int ignore; /* counter which ignores the first buffers */ struct semaphore sem; @@ -251,15 +250,12 @@ static void usbduxfast_ai_handle_urb(struct comedi_device *dev, unsigned int nsamples; nsamples = comedi_bytes_to_samples(s, urb->actual_length); - if (cmd->stop_src == TRIG_COUNT) { - if (devpriv->ai_sample_count < nsamples) { - nsamples = devpriv->ai_sample_count; - async->events |= COMEDI_CB_EOA; - } - devpriv->ai_sample_count -= nsamples; - } - + nsamples = comedi_nsamples_left(s, nsamples); comedi_buf_write_samples(s, urb->transfer_buffer, nsamples); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; } /* if command is still running, resubmit urb for BULK transfer */ @@ -788,11 +784,6 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, return result; } - if (cmd->stop_src == TRIG_COUNT) - devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg; - else /* TRIG_NONE */ - devpriv->ai_sample_count = 0; - if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) { /* enable this acquisition operation */ devpriv->ai_cmd_running = 1; -- GitLab From f9f983821691fde4539c18e43634d5f9cfa8c011 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:36 -0700 Subject: [PATCH 3720/9457] staging: comedi: cb_pcidas: use comedi_async 'scans_done' to detect AI EOA Remove the private data member 'count' and use the comedi_async 'scans_done' member to detect the analog input end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually add to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 1c38cd5f846c..e211ef8650c4 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -346,8 +346,6 @@ struct cb_pcidas_private { /* divisors of master clock for analog input pacing */ unsigned int divisor1; unsigned int divisor2; - /* number of analog input samples remaining */ - unsigned int count; /* bits to write to registers */ unsigned int adc_fifo_bits; unsigned int s5933_intcsr_bits; @@ -976,9 +974,6 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER) cb_pcidas_ai_load_counters(dev); - /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->count = cmd->chanlist_len * cmd->stop_arg; /* enable interrupts */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->adc_fifo_bits |= INTE; @@ -1352,17 +1347,15 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) /* if fifo half-full */ if (status & ADHFI) { /* read data */ - num_samples = half_fifo; - if (cmd->stop_src == TRIG_COUNT && - num_samples > devpriv->count) { - num_samples = devpriv->count; - } + num_samples = comedi_nsamples_left(s, half_fifo); insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, num_samples); comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); - devpriv->count -= num_samples; - if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) async->events |= COMEDI_CB_EOA; + /* clear half-full interrupt latch */ spin_lock_irqsave(&dev->spinlock, flags); outw(devpriv->adc_fifo_bits | INT, @@ -1379,9 +1372,9 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) break; val = inw(devpriv->adc_fifo); comedi_buf_write_samples(s, &val, 1); + if (cmd->stop_src == TRIG_COUNT && - --devpriv->count == 0) { - /* end of acquisition */ + async->scans_done >= cmd->stop_arg) { async->events |= COMEDI_CB_EOA; break; } -- GitLab From 9e4d755cdf0e98daa186733765e5fa14395717af Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:37 -0700 Subject: [PATCH 3721/9457] staging: comedi: cb_pcidas: use comedi_async 'scans_done' to detect AO EOA Remove the private data member 'ao_count' and use the comedi_async 'scans_done' member to detect the analog output end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually read from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e211ef8650c4..10c67fec75a0 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -356,8 +356,6 @@ struct cb_pcidas_private { /* divisors of master clock for analog output pacing */ unsigned int ao_divisor1; unsigned int ao_divisor2; - /* number of analog output samples remaining */ - unsigned int ao_count; unsigned int caldac_value[NUM_CHANNELS_8800]; unsigned int trimpot_value[NUM_CHANNELS_8402]; unsigned int dac08_value; @@ -1134,17 +1132,12 @@ static void cb_pcidas_ao_load_fifo(struct comedi_device *dev, unsigned int nsamples) { struct cb_pcidas_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; unsigned int nbytes; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples) - nsamples = devpriv->ao_count; - + nsamples = comedi_nsamples_left(s, nsamples); nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples); - nsamples = comedi_bytes_to_samples(s, nbytes); - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= nsamples; + nsamples = comedi_bytes_to_samples(s, nbytes); outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples); } @@ -1226,9 +1219,6 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) cb_pcidas_ao_load_counters(dev); - /* set number of conversions */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; /* set pacer source */ spin_lock_irqsave(&dev->spinlock, flags); switch (cmd->scan_begin_src) { @@ -1286,13 +1276,13 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) devpriv->control_status + INT_ADCFIFO); spin_unlock_irqrestore(&dev->spinlock, flags); if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { - if (cmd->stop_src == TRIG_NONE || - (cmd->stop_src == TRIG_COUNT - && devpriv->ao_count)) { + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { + async->events |= COMEDI_CB_EOA; + } else { dev_err(dev->class_dev, "dac fifo underflow\n"); async->events |= COMEDI_CB_ERROR; } - async->events |= COMEDI_CB_EOA; } } else if (status & DAHFI) { cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2); -- GitLab From ccedb44075776474c5a4f0625387f3d44b562f4e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:38 -0700 Subject: [PATCH 3722/9457] staging: comedi: cb_pcidas64: use comedi_async 'scans_done' to detect AI EOA Remove the private data member 'ai_count' and use the comedi_async 'scans_done' member to detect the analog output end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually add to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 55 +++++--------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index d7b61ba6b284..375bfbb60ebb 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1065,8 +1065,6 @@ struct pcidas64_private { /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; - /* number of analog input samples remaining */ - unsigned int ai_count; /* dma buffers for analog input */ uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ @@ -2199,10 +2197,6 @@ static void setup_sample_counters(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; - if (cmd->stop_src == TRIG_COUNT) { - /* set software count */ - devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; - } /* load hardware conversion counter */ if (use_hw_sample_counter(cmd)) { writew(cmd->stop_arg & 0xffff, @@ -2642,8 +2636,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; unsigned int i; uint16_t prepost_bits; int read_segment, read_index, write_segment, write_index; @@ -2672,22 +2664,16 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; - - if (cmd->stop_src == TRIG_COUNT) { - if (devpriv->ai_count == 0) - break; - if (num_samples > devpriv->ai_count) - num_samples = devpriv->ai_count; - - devpriv->ai_count -= num_samples; - } - if (num_samples < 0) { dev_err(dev->class_dev, "cb_pcidas64: bug! num_samples < 0\n"); break; } + num_samples = comedi_nsamples_left(s, num_samples); + if (num_samples == 0) + break; + for (i = 0; i < num_samples; i++) { unsigned short val; @@ -2707,29 +2693,23 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; + unsigned int nsamples; unsigned int i; - unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; - if (cmd->stop_src == TRIG_COUNT) { - if (max_transfer > devpriv->ai_count) - max_transfer = devpriv->ai_count; - - } - for (i = 0; read_code != write_code && i < max_transfer;) { + nsamples = comedi_nsamples_left(s, 100000); + for (i = 0; read_code != write_code && i < nsamples;) { unsigned short val; fifo_data = readl(dev->mmio + ADC_FIFO_REG); val = fifo_data & 0xffff; comedi_buf_write_samples(s, &val, 1); i++; - if (i < max_transfer) { + if (i < nsamples) { val = (fifo_data >> 16) & 0xffff; comedi_buf_write_samples(s, &val, 1); i++; @@ -2737,7 +2717,6 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; } - devpriv->ai_count -= i; } /* empty fifo */ @@ -2755,8 +2734,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { const struct pcidas64_board *thisboard = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - struct comedi_async *async = dev->read_subdev->async; - struct comedi_cmd *cmd = &async->cmd; + struct comedi_subdevice *s = dev->read_subdev; uint32_t next_transfer_addr; int j; int num_samples = 0; @@ -2777,13 +2755,8 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) { /* transfer data from dma buffer to comedi buffer */ - num_samples = dma_transfer_size(dev); - if (cmd->stop_src == TRIG_COUNT) { - if (num_samples > devpriv->ai_count) - num_samples = devpriv->ai_count; - devpriv->ai_count -= num_samples; - } - comedi_buf_write_samples(dev->read_subdev, + num_samples = comedi_nsamples_left(s, dma_transfer_size(dev)); + comedi_buf_write_samples(s, devpriv->ai_buffer[devpriv->ai_dma_index], num_samples); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % @@ -2835,10 +2808,10 @@ static void handle_ai_interrupt(struct comedi_device *dev, spin_unlock_irqrestore(&dev->spinlock, flags); } /* if we are have all the data, then quit */ - if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) || - (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) { + if ((cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) || + (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) async->events |= COMEDI_CB_EOA; - } comedi_handle_events(dev, s); } -- GitLab From 0be887b92a1d7fce7ea62d09eefacdab9b4370e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:39 -0700 Subject: [PATCH 3723/9457] staging: comedi: cb_pcidas64: use comedi_async 'scans_done' to detect AO EOA Remove the private data member 'ao_count' and use the comedi_async 'scans_done' member to detect the analog output end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually read from the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 40 +++++--------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 375bfbb60ebb..05da5b33834a 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1085,8 +1085,6 @@ struct pcidas64_private { dma_addr_t ao_dma_desc_bus_addr; /* keeps track of buffer where the next ao sample should go */ unsigned int ao_dma_index; - /* number of analog output samples remaining */ - unsigned long ao_count; unsigned int hw_revision; /* stc chip hardware revision number */ /* last bits sent to INTR_ENABLE_REG register */ unsigned int intr_enable_bits; @@ -2848,22 +2846,6 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) return 1; } -static int ao_stopped_by_error(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - - if (cmd->stop_src == TRIG_NONE) - return 1; - if (cmd->stop_src == TRIG_COUNT) { - if (devpriv->ao_count) - return 1; - if (last_ao_dma_load_completed(dev) == 0) - return 1; - } - return 0; -} - static inline int ao_dma_needs_restart(struct comedi_device *dev, unsigned short dma_status) { @@ -2894,20 +2876,13 @@ static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev, unsigned short *dest, unsigned int max_bytes) { - struct pcidas64_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; unsigned int nsamples = comedi_bytes_to_samples(s, max_bytes); unsigned int actual_bytes; - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples) - nsamples = devpriv->ao_count; - + nsamples = comedi_nsamples_left(s, nsamples); actual_bytes = comedi_buf_read_samples(s, dest, nsamples); - nsamples = comedi_bytes_to_samples(s, actual_bytes); - if (cmd->stop_src == TRIG_COUNT) - devpriv->ao_count -= nsamples; - return nsamples; + return comedi_bytes_to_samples(s, actual_bytes); } static unsigned int load_ao_dma_buffer(struct comedi_device *dev, @@ -3006,8 +2981,11 @@ static void handle_ao_interrupt(struct comedi_device *dev, } if ((status & DAC_DONE_BIT)) { - async->events |= COMEDI_CB_EOA; - if (ao_stopped_by_error(dev, cmd)) + if ((cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) || + last_ao_dma_load_completed(dev)) + async->events |= COMEDI_CB_EOA; + else async->events |= COMEDI_CB_ERROR; } comedi_handle_events(dev, s); @@ -3202,7 +3180,8 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) devpriv->main_iobase + DAC_FIFO_REG); } - if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) return 0; nbytes = load_ao_dma_buffer(dev, cmd); @@ -3267,7 +3246,6 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG); devpriv->ao_dma_index = 0; - devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len; set_dac_select_reg(dev, cmd); set_dac_interval_regs(dev, cmd); -- GitLab From 2d7840c70dcf526326a770d8a993c80ef7cae43f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:40 -0700 Subject: [PATCH 3724/9457] staging: comedi: quatech_daqp_cs: use comedi_async 'scans_done' to detect EOA Remove the private data member 'count' and use the comedi_async 'scans_done' member to detect the end-of-acquisition. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/quatech_daqp_cs.c | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 0630df367494..f77485b28fe2 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -65,8 +65,6 @@ struct daqp_private { enum { semaphore, buffer } interrupt_mode; struct completion eos; - - int count; }; /* The DAQP communicates with the system through a 16 byte I/O window. */ @@ -194,6 +192,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) struct comedi_device *dev = dev_id; struct daqp_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; int loop_limit = 10000; int status; @@ -227,12 +226,10 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) * and stop conversion if zero */ - if (devpriv->count > 0) { - devpriv->count--; - if (devpriv->count == 0) { - s->async->events |= COMEDI_CB_EOA; - break; - } + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) { + s->async->events |= COMEDI_CB_EOA; + break; } if ((loop_limit--) <= 0) @@ -573,12 +570,16 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ if (cmd->stop_src == TRIG_COUNT) { - devpriv->count = cmd->stop_arg * cmd->scan_end_arg; - threshold = 2 * devpriv->count; - while (threshold > DAQP_FIFO_SIZE * 3 / 4) - threshold /= 2; + unsigned long long nsamples; + unsigned long long nbytes; + + nsamples = (unsigned long long)cmd->stop_arg * + cmd->scan_end_arg; + nbytes = nsamples * comedi_bytes_per_sample(s); + while (nbytes > DAQP_FIFO_SIZE * 3 / 4) + nbytes /= 2; + threshold = nbytes; } else { - devpriv->count = -1; threshold = DAQP_FIFO_SIZE / 2; } -- GitLab From 605d76f6eb007aeb1dbcb7429adde73f2ef1fd9f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 Nov 2014 10:31:41 -0700 Subject: [PATCH 3725/9457] staging: comedi: das1800: use comedi_async 'scans_done' to detect EOA Remove the private data member 'count' and use the comedi_async 'scans_done' member to detect the end-of-acquisition. Use the comedi_nsamples_left() helper to get the number of samples to actually add to the async buffer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 52 ++++++++---------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 03b1ff9de92c..be825d21a185 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -421,7 +421,6 @@ static const struct das1800_board das1800_boards[] = { }; struct das1800_private { - unsigned int count; /* number of data points left to be taken */ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ int irq_dma_bits; /* bits for control register b */ @@ -479,41 +478,33 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct comedi_subdevice *s) { struct das1800_private *devpriv = dev->private; - int numPoints = 0; /* number of points to read */ - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2); - numPoints = FIFO_SIZE / 2; - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) - numPoints = devpriv->count; - insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); - munge_data(dev, devpriv->ai_buf0, numPoints); - comedi_buf_write_samples(s, devpriv->ai_buf0, numPoints); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count -= numPoints; + insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, nsamples); + munge_data(dev, devpriv->ai_buf0, nsamples); + comedi_buf_write_samples(s, devpriv->ai_buf0, nsamples); } static void das1800_handle_fifo_not_empty(struct comedi_device *dev, struct comedi_subdevice *s) { - struct das1800_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; unsigned short dpnt; int unipolar; - struct comedi_cmd *cmd = &s->async->cmd; unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; while (inb(dev->iobase + DAS1800_STATUS) & FNE) { - if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) - break; dpnt = inw(dev->iobase + DAS1800_FIFO); /* convert to unsigned type if we are in a bipolar mode */ if (!unipolar) ; dpnt = munge_bipolar_sample(dev, dpnt); comedi_buf_write_samples(s, &dpnt, 1); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count--; + + if (cmd->stop_src == TRIG_COUNT && + s->async->scans_done >= cmd->stop_arg) + break; } } @@ -524,8 +515,8 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, unsigned int channel, uint16_t *buffer) { struct das1800_private *devpriv = dev->private; - unsigned int num_bytes, num_samples; - struct comedi_cmd *cmd = &s->async->cmd; + unsigned int nbytes; + unsigned int nsamples; disable_dma(channel); @@ -534,17 +525,12 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, clear_dma_ff(channel); /* figure out how many points to read */ - num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); - num_samples = comedi_bytes_to_samples(s, num_bytes); - - /* if we only need some of the points */ - if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) - num_samples = devpriv->count; + nbytes = devpriv->dma_transfer_size - get_dma_residue(channel); + nsamples = comedi_bytes_to_samples(s, nbytes); + nsamples = comedi_nsamples_left(s, nsamples); - munge_data(dev, buffer, num_samples); - comedi_buf_write_samples(s, buffer, num_samples); - if (cmd->stop_src == TRIG_COUNT) - devpriv->count -= num_samples; + munge_data(dev, buffer, nsamples); + comedi_buf_write_samples(s, buffer, nsamples); } /* flushes remaining data from board when external trigger has stopped acquisition @@ -668,7 +654,8 @@ static void das1800_ai_handler(struct comedi_device *dev) else das1800_handle_fifo_not_empty(dev, s); async->events |= COMEDI_CB_EOA; - } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ + } else if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) { async->events |= COMEDI_CB_EOA; } @@ -1100,9 +1087,6 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, /* interrupt fifo half full */ devpriv->irq_dma_bits |= FIMD; } - /* determine how many conversions we need */ - if (cmd->stop_src == TRIG_COUNT) - devpriv->count = cmd->stop_arg * cmd->chanlist_len; das1800_cancel(dev, s); -- GitLab From dc3cfcd3f4804c9bf71e3b6152df6eb957856735 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 6 Nov 2014 19:26:47 +0900 Subject: [PATCH 3726/9457] staging: dgap: set tty's flags by tty_alloc_driver() tty's flags can be set by calling tty_alloc_driver(). Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index aa393d2941df..6418cc5687de 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -5236,7 +5236,10 @@ static int dgap_tty_register(struct board_t *brd) { int rc; - brd->serial_driver = tty_alloc_driver(MAXPORTS, 0); + brd->serial_driver = tty_alloc_driver(MAXPORTS, + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); if (IS_ERR(brd->serial_driver)) return PTR_ERR(brd->serial_driver); @@ -5250,9 +5253,6 @@ static int dgap_tty_register(struct board_t *brd) brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; brd->serial_driver->init_termios = dgap_default_termios; brd->serial_driver->driver_name = DRVSTR; - brd->serial_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); /* The kernel wants space to store pointers to tty_structs */ brd->serial_driver->ttys = @@ -5273,7 +5273,10 @@ static int dgap_tty_register(struct board_t *brd) * again, separately so we don't get the LD confused about what major * we are when we get into the dgap_tty_open() routine. */ - brd->print_driver = tty_alloc_driver(MAXPORTS, 0); + brd->print_driver = tty_alloc_driver(MAXPORTS, + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | + TTY_DRIVER_HARDWARE_BREAK); if (IS_ERR(brd->print_driver)) { rc = PTR_ERR(brd->print_driver); goto free_serial_drv; @@ -5289,9 +5292,6 @@ static int dgap_tty_register(struct board_t *brd) brd->print_driver->subtype = SERIAL_TYPE_NORMAL; brd->print_driver->init_termios = dgap_default_termios; brd->print_driver->driver_name = DRVSTR; - brd->print_driver->flags = (TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | - TTY_DRIVER_HARDWARE_BREAK); /* The kernel wants space to store pointers to tty_structs */ brd->print_driver->ttys = -- GitLab From 429161d164491f430ddbc591f45dc2cd39e0e8a1 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 6 Nov 2014 19:27:11 +0900 Subject: [PATCH 3727/9457] staging: dgap: fix memory leak caused by double allocation of tty_structs The tty_struct of serial_driver and print_driver were getting allocated twice. One is allocated in tty_alloc_driver(), the other is in dgap_tty_register(). So remove these in dgap_tty_register(). Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 6418cc5687de..688aaa43e6dc 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -5254,14 +5254,6 @@ static int dgap_tty_register(struct board_t *brd) brd->serial_driver->init_termios = dgap_default_termios; brd->serial_driver->driver_name = DRVSTR; - /* The kernel wants space to store pointers to tty_structs */ - brd->serial_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->serial_driver->ttys) { - rc = -ENOMEM; - goto free_serial_drv; - } - /* * Entry points for driver. Called by the kernel from * tty_io.c and n_tty.c. @@ -5293,14 +5285,6 @@ static int dgap_tty_register(struct board_t *brd) brd->print_driver->init_termios = dgap_default_termios; brd->print_driver->driver_name = DRVSTR; - /* The kernel wants space to store pointers to tty_structs */ - brd->print_driver->ttys = - kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); - if (!brd->print_driver->ttys) { - rc = -ENOMEM; - goto free_print_drv; - } - /* * Entry points for driver. Called by the kernel from * tty_io.c and n_tty.c. -- GitLab From 4c5dbca65bb0d2f5e940ca64d0876581f411d1a6 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 6 Nov 2014 19:27:33 +0900 Subject: [PATCH 3728/9457] staging: dgap: remove useless variables for saving tty's major The board_t has a tty_struct(serial_driver and print_driver) that has a major number. When major number is compared in dgap_tty_open(), just use brd->serial_driver{print_driver}->major. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 9 ++------- drivers/staging/dgap/dgap.h | 3 --- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 688aaa43e6dc..3f23e5b1df9c 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -4477,10 +4477,10 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file) spin_lock_irqsave(&ch->ch_lock, lock_flags2); /* Figure out our type */ - if (major == brd->dgap_serial_major) { + if (major == brd->serial_driver->major) { un = &brd->channels[minor]->ch_tun; un->un_type = DGAP_SERIAL; - } else if (major == brd->dgap_transparent_print_major) { + } else if (major == brd->print_driver->major) { un = &brd->channels[minor]->ch_pun; un->un_type = DGAP_PRINT; } else { @@ -5302,10 +5302,7 @@ static int dgap_tty_register(struct board_t *brd) goto unregister_serial_drv; dgap_boards_by_major[brd->serial_driver->major] = brd; - brd->dgap_serial_major = brd->serial_driver->major; - dgap_boards_by_major[brd->print_driver->major] = brd; - brd->dgap_transparent_print_major = brd->print_driver->major; return 0; @@ -6563,7 +6560,6 @@ static void dgap_cleanup_tty(struct board_t *brd) unsigned int i; dgap_boards_by_major[brd->serial_driver->major] = NULL; - brd->dgap_serial_major = 0; for (i = 0; i < brd->nasync; i++) { tty_port_destroy(&brd->serial_ports[i]); dev = brd->channels[i]->ch_tun.un_sysfs; @@ -6575,7 +6571,6 @@ static void dgap_cleanup_tty(struct board_t *brd) kfree(brd->serial_ports); dgap_boards_by_major[brd->print_driver->major] = NULL; - brd->dgap_transparent_print_major = 0; for (i = 0; i < brd->nasync; i++) { tty_port_destroy(&brd->printer_ports[i]); dev = brd->channels[i]->ch_pun.un_sysfs; diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 14e2ed0fe39b..684033156e8c 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -584,9 +584,6 @@ struct board_t { struct tty_port *printer_ports; char print_name[200]; - u32 dgap_serial_major; - u32 dgap_transparent_print_major; - struct bs_t __iomem *bd_bs; /* Base structure pointer */ char *flipbuf; /* Our flip buffer, alloced if */ -- GitLab From 48d43be475e48f5673b89c1faa6f7855d25f9a85 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 6 Nov 2014 19:27:59 +0900 Subject: [PATCH 3729/9457] staging: dgap: introducing find_board_by_major() use find_board_by_major function instead of getting a brd from static arrary. Becasue tty's major number doesn't start zero and we can find a brd from dgap_board[]. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 3f23e5b1df9c..f38354f04d50 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -80,7 +80,6 @@ static int dgap_poll_tick = 20; /* Poll interval - 20 ms */ static struct class *dgap_class; -static struct board_t *dgap_boards_by_major[256]; static uint dgap_count = 500; /* @@ -4409,6 +4408,22 @@ static void dgap_tty_unthrottle(struct tty_struct *tty) spin_unlock_irqrestore(&bd->bd_lock, lock_flags); } +static struct board_t *find_board_by_major(unsigned int major) +{ + unsigned int i; + + for (i = 0; i < MAXBOARDS; i++) { + struct board_t *brd = dgap_board[i]; + if (!brd) + return NULL; + if (major == brd->serial_driver->major || + major == brd->print_driver->major) + return brd; + } + + return NULL; +} + /************************************************************************ * * TTY Entry points and helper functions @@ -4435,11 +4450,7 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file) major = MAJOR(tty_devnum(tty)); minor = MINOR(tty_devnum(tty)); - if (major > 255) - return -EIO; - - /* Get board pointer from our array of majors we have allocated */ - brd = dgap_boards_by_major[major]; + brd = find_board_by_major(major); if (!brd) return -EIO; @@ -5301,9 +5312,6 @@ static int dgap_tty_register(struct board_t *brd) if (rc < 0) goto unregister_serial_drv; - dgap_boards_by_major[brd->serial_driver->major] = brd; - dgap_boards_by_major[brd->print_driver->major] = brd; - return 0; unregister_serial_drv: @@ -6559,7 +6567,6 @@ static void dgap_cleanup_tty(struct board_t *brd) struct device *dev; unsigned int i; - dgap_boards_by_major[brd->serial_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { tty_port_destroy(&brd->serial_ports[i]); dev = brd->channels[i]->ch_tun.un_sysfs; @@ -6570,7 +6577,6 @@ static void dgap_cleanup_tty(struct board_t *brd) put_tty_driver(brd->serial_driver); kfree(brd->serial_ports); - dgap_boards_by_major[brd->print_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { tty_port_destroy(&brd->printer_ports[i]); dev = brd->channels[i]->ch_pun.un_sysfs; -- GitLab From 546bf3382e41b8a5a4c216ea7bdc0f517ce04e22 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:45 -0700 Subject: [PATCH 3730/9457] staging: comedi: addi_apci_3120: introduce apci3120_ns_to_timer() The timer divisor calculations in this driver are over complicated. There are three timers on the board. They all use the same base clock with a fixed prescaler for each timer. The base clock used depends on the board version and type: APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns) APCI-3120 Rev B boards OSC = 20MHz base clock (50ns) APCI-3001 boards OSC = 20MHz base clock (50ns) The prescalers for each timer are: Timer 0 CLK = OSC/10 Timer 1 CLK = OSC/1000 Timer 2 CLK = OSC/1000 Add a new member to the private data, 'osc_base', to hold the base clock time. Set this member during the board attach. Introduce a helper function to calculate the divisor needed to generate a nanosecond time with a given timer. Use the new helper function in the driver to clarify the code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 137 ++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 71 +++++++++ 2 files changed, 100 insertions(+), 108 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c64799e3513c..960002dbaeca 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -309,14 +309,16 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned short us_ConvertTiming, us_TmpValue, i; + unsigned int divisor; + unsigned int ns; + unsigned short us_TmpValue, i; unsigned char b_Tmp; /* fix conversion time to 10 us */ if (!devpriv->ui_EocEosConversionTime) - us_ConvertTiming = 10; + ns = 10000; else - us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */ + ns = devpriv->ui_EocEosConversionTime; /* Clear software registers */ devpriv->b_TimerSelectMode = 0; @@ -329,20 +331,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, } else { devpriv->tsk_Current = current; /* Save the current process task structure */ - /* - * Testing if board have the new Quartz and calculate the time value - * to set in the timer - */ - us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); - - /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(dev->board_name, "apci3001")) { - us_ConvertTiming = (us_ConvertTiming * 2) - 2; - } else { - us_ConvertTiming = - ((us_ConvertTiming * 12926) / 10000) - 1; - } + divisor = apci3120_ns_to_timer(dev, 0, ns, CMDF_ROUND_NEAREST); us_TmpValue = (unsigned short) devpriv->b_InterruptMode; @@ -408,8 +397,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(us_ConvertTiming, - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor, dev->iobase + APCI3120_TIMER_VALUE); us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); @@ -467,8 +455,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(us_ConvertTiming, - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor, dev->iobase + APCI3120_TIMER_VALUE); /* Set the scan bit */ devpriv->b_ModeSelectRegister = @@ -719,14 +706,11 @@ static int apci3120_cyclic_ai(int mode, struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned char b_Tmp; - unsigned int ui_DelayTiming = 0; - unsigned int ui_TimerValue1 = 0; + unsigned int divisor1 = 0; unsigned int dmalen0 = 0; unsigned int dmalen1 = 0; unsigned int ui_TimerValue2 = 0; - unsigned int ui_TimerValue0; - unsigned int ui_ConvertTiming; - unsigned short us_TmpValue; + unsigned int divisor0; /* Resets the FIFO */ inb(dev->iobase + APCI3120_RESET_FIFO); @@ -759,42 +743,17 @@ static int apci3120_cyclic_ai(int mode, /* value for timer2 minus -2 has to be done */ ui_TimerValue2 = cmd->stop_arg - 2; - ui_ConvertTiming = cmd->convert_arg; - - if (mode == 2) - ui_DelayTiming = cmd->scan_begin_arg; /* Initializes the sequence array */ if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, cmd->chanlist, 0)) return -EINVAL; - us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); - - /* EL241003 Begin: add this section to replace floats calculation by integer calculations */ - /* EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001 */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(dev->board_name, "apci3001")) { - ui_TimerValue0 = ui_ConvertTiming * 2 - 2000; - ui_TimerValue0 = ui_TimerValue0 / 1000; - - if (mode == 2) { - ui_DelayTiming = ui_DelayTiming / 1000; - ui_TimerValue1 = ui_DelayTiming * 2 - 200; - ui_TimerValue1 = ui_TimerValue1 / 100; - } - } else { - ui_ConvertTiming = ui_ConvertTiming / 1000; - ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000; - ui_TimerValue0 = ui_TimerValue0 / 10000; - - if (mode == 2) { - ui_DelayTiming = ui_DelayTiming / 1000; - ui_TimerValue1 = ui_DelayTiming * 12926 - 1; - ui_TimerValue1 = ui_TimerValue1 / 1000000; - } + divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); + if (mode == 2) { + divisor1 = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, + cmd->flags); } - /* EL241003 End */ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) apci3120_exttrig_enable(dev); /* activate EXT trigger */ @@ -813,8 +772,7 @@ static int apci3120_cyclic_ai(int mode, APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue0), - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor0, dev->iobase + APCI3120_TIMER_VALUE); break; case 2: @@ -831,8 +789,7 @@ static int apci3120_cyclic_ai(int mode, APCI3120_SELECT_TIMER_1_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue1), - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor1, dev->iobase + APCI3120_TIMER_VALUE); /* init timer0 in mode 2 */ devpriv->b_TimerSelectMode = @@ -848,8 +805,7 @@ static int apci3120_cyclic_ai(int mode, outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(((unsigned short) ui_TimerValue0), - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor0, dev->iobase + APCI3120_TIMER_VALUE); break; } @@ -1487,8 +1443,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned int ui_Timervalue2; - unsigned short us_TmpValue; + unsigned int divisor; unsigned char b_Tmp; if (!data[1]) @@ -1496,22 +1451,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, devpriv->b_Timer2Interrupt = (unsigned char) data[2]; /* save info whether to enable or disable interrupt */ - ui_Timervalue2 = data[1] / 1000; /* convert nano seconds to u seconds */ - - us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); - - /* - * EL250804: Testing if board APCI3120 have the new Quartz or if it - * is an APCI3001 and calculate the time value to set in the timer - */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(dev->board_name, "apci3001")) { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 50; - } else { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 70; - } + divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ devpriv->us_OutputRegister = @@ -1551,15 +1491,14 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(ui_Timervalue2 & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((ui_Timervalue2 >> 16) & 0xffff, + outw((divisor >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* timer2 in Timer mode enabled */ devpriv->b_Timer2Mode = APCI3120_TIMER; @@ -1586,8 +1525,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(ui_Timervalue2 & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> @@ -1595,7 +1533,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((ui_Timervalue2 >> 16) & 0xffff, + outw((divisor >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* watchdog enabled */ devpriv->b_Timer2Mode = APCI3120_WATCHDOG; @@ -1624,8 +1562,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned int ui_Timervalue2 = 0; - unsigned short us_TmpValue; + unsigned int divisor; unsigned char b_Tmp; if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) @@ -1640,11 +1577,6 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, "timer2 not configured in TIMER MODE\n"); return -EINVAL; } - - if (data[1]) - ui_Timervalue2 = data[1]; - else - ui_Timervalue2 = 0; } switch (data[0]) { @@ -1734,28 +1666,17 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, "timer2 not configured in TIMER MODE\n"); return -EINVAL; } - us_TmpValue = inw(dev->iobase + APCI3120_RD_STATUS); - /* - * EL250804: Testing if board APCI3120 have the new Quartz or if it - * is an APCI3001 and calculate the time value to set in the timer - */ - if ((us_TmpValue & 0x00B0) == 0x00B0 - || !strcmp(dev->board_name, "apci3001")) { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 50; - } else { - /* Calculate the time value to set in the timer */ - ui_Timervalue2 = ui_Timervalue2 / 70; - } + divisor = apci3120_ns_to_timer(dev, 2, data[1], + CMDF_ROUND_DOWN); + /* Writing LOW unsigned short */ b_Tmp = ((devpriv-> b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(ui_Timervalue2 & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); + outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ b_Tmp = ((devpriv-> @@ -1763,7 +1684,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((ui_Timervalue2 >> 16) & 0xffff, + outw((divisor >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); break; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 056b3bf82094..c770e4643ce0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,6 +15,7 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) @@ -23,6 +24,14 @@ * PCI BAR 2 register map (devpriv->addon) */ +/* + * Board revisions + */ +#define APCI3120_REVA 0xa +#define APCI3120_REVB 0xb +#define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */ +#define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */ + enum apci3120_boardid { BOARD_APCI3120, BOARD_APCI3001, @@ -55,6 +64,7 @@ struct apci3120_dmabuf { struct apci3120_private { unsigned long amcc; unsigned long addon; + unsigned int osc_base; unsigned int ui_AiNbrofChannels; unsigned int ui_AiChannelList[32]; unsigned int ui_AiReadData[32]; @@ -76,6 +86,59 @@ struct apci3120_private { struct task_struct *tsk_Current; }; +/* + * There are three timers on the board. They all use the same base + * clock with a fixed prescaler for each timer. The base clock used + * depends on the board version and type. + * + * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns) + * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns) + * APCI-3001 boards OSC = 20MHz base clock (50ns) + * + * The prescalers for each timer are: + * Timer 0 CLK = OSC/10 + * Timer 1 CLK = OSC/1000 + * Timer 2 CLK = OSC/1000 + */ +static unsigned int apci3120_ns_to_timer(struct comedi_device *dev, + unsigned int timer, + unsigned int ns, + unsigned int flags) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int prescale = (timer == 0) ? 10 : 1000; + unsigned int timer_base = devpriv->osc_base * prescale; + unsigned int divisor; + + switch (flags & CMDF_ROUND_MASK) { + case CMDF_ROUND_UP: + divisor = DIV_ROUND_UP(ns, timer_base); + break; + case CMDF_ROUND_DOWN: + divisor = ns / timer_base; + break; + case CMDF_ROUND_NEAREST: + default: + divisor = DIV_ROUND_CLOSEST(ns, timer_base); + break; + } + + if (timer == 2) { + /* timer 2 is 24-bits */ + if (divisor > 0x00ffffff) + divisor = 0x00ffffff; + } else { + /* timers 0 and 1 are 16-bits */ + if (divisor > 0xffff) + divisor = 0xffff; + } + /* the timers require a minimum divisor of 2 */ + if (divisor < 2) + divisor = 2; + + return divisor; +} + #include "addi-data/hwdrv_apci3120.c" static void apci3120_dma_alloc(struct comedi_device *dev) @@ -131,6 +194,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, const struct apci3120_board *this_board = NULL; struct apci3120_private *devpriv; struct comedi_subdevice *s; + unsigned int status; int ret; if (context < ARRAY_SIZE(apci3120_boardtypes)) @@ -165,6 +229,13 @@ static int apci3120_auto_attach(struct comedi_device *dev, } } + status = inw(dev->iobase + APCI3120_RD_STATUS); + if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB || + context == BOARD_APCI3001) + devpriv->osc_base = APCI3120_REVB_OSC_BASE; + else + devpriv->osc_base = APCI3120_REVA_OSC_BASE; + ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; -- GitLab From 36d553e47d7ea50a2a954ede3540f4417b5094c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:46 -0700 Subject: [PATCH 3731/9457] staging: comedi: addi_apci_3120: rename private data 'b_DigitalOutputRegister' Rename this CamelCase member of the private data. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 50 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 960002dbaeca..9fca58c016c3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -391,8 +391,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev->iobase + APCI3120_WR_ADDRESS); /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -449,8 +448,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev->iobase + APCI3120_TIMER_CRT1); /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -767,8 +765,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_TIMER_CRT1); /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ @@ -784,8 +781,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_TIMER_CRT1); /* Select Timer 1 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_1_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ @@ -799,8 +795,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_TIMER_CRT1); /* Select Timer 0 */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -859,16 +854,14 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_TIMER_CRT1); /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(ui_TimerValue2 & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw((ui_TimerValue2 >> 16) & 0xffff, @@ -1487,15 +1480,13 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, */ /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw((divisor >> 16) & 0xffff, @@ -1521,15 +1512,13 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, */ /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -1671,16 +1660,14 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, CMDF_ROUND_DOWN); /* Writing LOW unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -1719,16 +1706,14 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* Read the LOW unsigned short of Timer 2 register */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); us_TmpValue = inw(dev->iobase + APCI3120_TIMER_VALUE); /* Read the HIGH unsigned short of Timer 2 register */ - b_Tmp = ((devpriv-> - b_DigitalOutputRegister) & 0xF0) | + b_Tmp = ((devpriv->do_bits) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); @@ -1774,10 +1759,9 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, if (comedi_dio_update_state(s, data)) { /* The do channels are bits 7:4 of the do register */ - devpriv->b_DigitalOutputRegister = s->state << 4; + devpriv->do_bits = s->state << 4; - outb(devpriv->b_DigitalOutputRegister, - dev->iobase + APCI3120_DIGITAL_OUTPUT); + outb(devpriv->do_bits, dev->iobase + APCI3120_DIGITAL_OUTPUT); } data[1] = s->state; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c770e4643ce0..f07d9ab35c9d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -72,7 +72,7 @@ struct apci3120_private { unsigned char b_DmaDoubleBuffer; unsigned int ui_DmaActualBuffer; struct apci3120_dmabuf dmabuf[2]; - unsigned char b_DigitalOutputRegister; + unsigned char do_bits; unsigned char b_TimerSelectMode; unsigned char b_ModeSelectRegister; unsigned short us_OutputRegister; -- GitLab From ca578bce6d940b4a653fe8ff73ba37fff0c8eaa7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:47 -0700 Subject: [PATCH 3732/9457] staging: comedi: addi_apci_3120: introduce apci3120_timer_write() Introduce a helper function to select a timer and write a value to it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 138 +++++------------- .../staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 35 insertions(+), 104 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 9fca58c016c3..ea825c7be944 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -200,6 +200,26 @@ static const struct comedi_lrange range_apci3120_ai = { } }; +static void apci3120_timer_write(struct comedi_device *dev, + unsigned int timer, unsigned int val) +{ + struct apci3120_private *devpriv = dev->private; + + /* write 16-bit value to timer (lower 16-bits of timer 2) */ + outb(((devpriv->do_bits) & 0xF0) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_TIMER_CRT0); + outw(val & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); + + if (timer == 2) { + /* write upper 16-bits to timer 2 */ + outb(((devpriv->do_bits) & 0xF0) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_TIMER_CRT0); + outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); + } +} + static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -312,7 +332,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, unsigned int divisor; unsigned int ns; unsigned short us_TmpValue, i; - unsigned char b_Tmp; /* fix conversion time to 10 us */ if (!devpriv->ui_EocEosConversionTime) @@ -390,13 +409,8 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - /* Select Timer 0 */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(divisor, dev->iobase + APCI3120_TIMER_VALUE); + apci3120_timer_write(dev, 0, divisor); us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); @@ -447,13 +461,8 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* Select Timer 0 */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(divisor, dev->iobase + APCI3120_TIMER_VALUE); + apci3120_timer_write(dev, 0, divisor); /* Set the scan bit */ devpriv->b_ModeSelectRegister = @@ -703,11 +712,9 @@ static int apci3120_cyclic_ai(int mode, { struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned char b_Tmp; unsigned int divisor1 = 0; unsigned int dmalen0 = 0; unsigned int dmalen1 = 0; - unsigned int ui_TimerValue2 = 0; unsigned int divisor0; /* Resets the FIFO */ @@ -739,9 +746,6 @@ static int apci3120_cyclic_ai(int mode, devpriv->ui_DmaActualBuffer = 0; - /* value for timer2 minus -2 has to be done */ - ui_TimerValue2 = cmd->stop_arg - 2; - /* Initializes the sequence array */ if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, cmd->chanlist, 0)) @@ -764,12 +768,8 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* Select Timer 0 */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); /* Set the conversion time */ - outw(divisor0, dev->iobase + APCI3120_TIMER_VALUE); + apci3120_timer_write(dev, 0, divisor0); break; case 2: @@ -780,12 +780,8 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* Select Timer 1 */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_1_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(divisor1, dev->iobase + APCI3120_TIMER_VALUE); + /* Set the scan begin time */ + apci3120_timer_write(dev, 1, divisor1); /* init timer0 in mode 2 */ devpriv->b_TimerSelectMode = @@ -794,13 +790,8 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* Select Timer 0 */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_0_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the conversion time */ - outw(divisor0, dev->iobase + APCI3120_TIMER_VALUE); + apci3120_timer_write(dev, 0, divisor0); break; } @@ -853,19 +844,8 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(ui_TimerValue2 & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((ui_TimerValue2 >> 16) & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); + /* Set the scan stop count (not sure about the -2) */ + apci3120_timer_write(dev, 2, cmd->stop_arg - 2); /* (2) Reset FC_TIMER BIT Clearing timer status register */ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); @@ -1437,7 +1417,6 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, { struct apci3120_private *devpriv = dev->private; unsigned int divisor; - unsigned char b_Tmp; if (!data[1]) dev_err(dev->class_dev, "No timer constant!\n"); @@ -1471,26 +1450,9 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* - * Configure the timer 2 for writing the LOW unsigned short of timer - * is Delay value You must make a b_tmp variable with - * DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0 - * you can set the digital output and configure the timer 2,and if - * you don't make this, digital output are erase (Set to 0) - */ + /* Set timer 2 delay */ + apci3120_timer_write(dev, 2, divisor); - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw((divisor >> 16) & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); /* timer2 in Timer mode enabled */ devpriv->b_Timer2Mode = APCI3120_TIMER; @@ -1503,27 +1465,9 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, outb(devpriv->b_TimerSelectMode, dev->iobase + APCI3120_TIMER_CRT1); - /* - * Configure the timer 2 for writing the LOW unsigned short of timer - * is Delay value You must make a b_tmp variable with - * DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0 - * you can set the digital output and configure the timer 2,and if - * you don't make this, digital output are erase (Set to 0) - */ + /* Set timer 2 delay */ + apci3120_timer_write(dev, 2, divisor); - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - outw((divisor >> 16) & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); /* watchdog enabled */ devpriv->b_Timer2Mode = APCI3120_WATCHDOG; @@ -1552,7 +1496,6 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, { struct apci3120_private *devpriv = dev->private; unsigned int divisor; - unsigned char b_Tmp; if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { @@ -1659,21 +1602,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); - /* Writing LOW unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - outw(divisor & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); - - /* Writing HIGH unsigned short */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - outw((divisor >> 16) & 0xffff, - dev->iobase + APCI3120_TIMER_VALUE); - + /* Set timer 2 delay */ + apci3120_timer_write(dev, 2, divisor); break; default: return -EINVAL; /* Not a valid input */ diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f07d9ab35c9d..6819cc09a60e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -19,6 +19,7 @@ #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) +#define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) /* * PCI BAR 2 register map (devpriv->addon) -- GitLab From 6931290785bb6ecd044b08ea0e62e073051fec86 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:48 -0700 Subject: [PATCH 3733/9457] staging: comedi: addi_apci_3120: introduce apci3120_timer_read() Introduce a helper function to select a timer and read a value from it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index ea825c7be944..7335a64d2d6f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -220,6 +220,29 @@ static void apci3120_timer_write(struct comedi_device *dev, } } +static unsigned int apci3120_timer_read(struct comedi_device *dev, + unsigned int timer) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int val; + + /* read 16-bit value from timer (lower 16-bits of timer 2) */ + outb(((devpriv->do_bits) & 0xF0) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_TIMER_CRT0); + val = inw(dev->iobase + APCI3120_TIMER_VALUE); + + if (timer == 2) { + /* read upper 16-bits from timer 2 */ + outb(((devpriv->do_bits) & 0xF0) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_TIMER_CRT0); + val |= (inw(dev->iobase + APCI3120_TIMER_VALUE) << 16); + } + + return val; +} + static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -1626,32 +1649,14 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned char b_Tmp; - unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue; + unsigned short us_StatusValue; if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { dev_err(dev->class_dev, "timer2 not configured\n"); } if (devpriv->b_Timer2Mode == APCI3120_TIMER) { - - /* Read the LOW unsigned short of Timer 2 register */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_LOW_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - us_TmpValue = inw(dev->iobase + APCI3120_TIMER_VALUE); - - /* Read the HIGH unsigned short of Timer 2 register */ - b_Tmp = ((devpriv->do_bits) & 0xF0) | - APCI3120_SELECT_TIMER_2_HIGH_WORD; - outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - - us_TmpValue_2 = inw(dev->iobase + APCI3120_TIMER_VALUE); - - /* combining both words */ - data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); - + data[0] = apci3120_timer_read(dev, 2); } else { /* Read watch dog status */ us_StatusValue = inw(dev->iobase + APCI3120_RD_STATUS); -- GitLab From 2e2e74e17a315d376292764b323e54ec21daa18e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:49 -0700 Subject: [PATCH 3734/9457] staging: comedi: addi_apci_3120: tidy up CTR0 register defines Define the CTR0 register in the main driver source file and remove all the old defines in hwrdv_apci3120.c. For aesthetics, save the raw digital output state (devpriv->do_bits) in the digital output (*insn_bits) function and use a macro to set them when reading/writing a timer. Use the CTR0 register define in the digital output (*insn_bits) function and remove the current register define. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 38 ++++++------------- .../staging/comedi/drivers/addi_apci_3120.c | 2 + 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 7335a64d2d6f..93b17252a907 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -86,16 +86,9 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_EOS_MODE 2 #define APCI3120_DMA_MODE 3 -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI3120_DIGITAL_OUTPUT 0x0d #define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 -/* digital output insn_write ON /OFF selection */ -#define APCI3120_SET4DIGITALOUTPUTON 1 -#define APCI3120_SET4DIGITALOUTPUTOFF 0 - /* Enable external trigger bit in nWrAddress */ #define APCI3120_ENABLE_EXT_TRIGGER 0x8000 @@ -110,7 +103,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RESET_FIFO 0x0c #define APCI3120_TIMER_0_MODE_2 0x01 #define APCI3120_TIMER_0_MODE_4 0x2 -#define APCI3120_SELECT_TIMER_0_WORD 0x00 #define APCI3120_ENABLE_TIMER0 0x1000 #define APCI3120_CLEAR_PR 0xf0ff #define APCI3120_CLEAR_PA 0xfff0 @@ -148,8 +140,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_ENABLE_TIMER_INT 0x04 #define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_SELECT_TIMER_1_WORD 0x01 #define APCI3120_TIMER_1_MODE_2 0x4 /* $$ BIT FOR MODE IN nCsTimerCtr1 */ @@ -157,11 +147,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_2_MODE_2 0x10 #define APCI3120_TIMER_2_MODE_5 0x30 -/* $$ BIT FOR MODE IN nCsTimerCtr0 */ -#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 -#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 - -#define APCI3120_TIMER_CRT0 0x0d #define APCI3120_TIMER_CRT1 0x0c #define APCI3120_TIMER_VALUE 0x04 @@ -206,16 +191,16 @@ static void apci3120_timer_write(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; /* write 16-bit value to timer (lower 16-bits of timer 2) */ - outb(((devpriv->do_bits) & 0xF0) | + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer), - dev->iobase + APCI3120_TIMER_CRT0); + dev->iobase + APCI3120_CTR0_REG); outw(val & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); if (timer == 2) { /* write upper 16-bits to timer 2 */ - outb(((devpriv->do_bits) & 0xF0) | + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer + 1), - dev->iobase + APCI3120_TIMER_CRT0); + dev->iobase + APCI3120_CTR0_REG); outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); } } @@ -227,16 +212,16 @@ static unsigned int apci3120_timer_read(struct comedi_device *dev, unsigned int val; /* read 16-bit value from timer (lower 16-bits of timer 2) */ - outb(((devpriv->do_bits) & 0xF0) | + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer), - dev->iobase + APCI3120_TIMER_CRT0); + dev->iobase + APCI3120_CTR0_REG); val = inw(dev->iobase + APCI3120_TIMER_VALUE); if (timer == 2) { /* read upper 16-bits from timer 2 */ - outb(((devpriv->do_bits) & 0xF0) | + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer + 1), - dev->iobase + APCI3120_TIMER_CRT0); + dev->iobase + APCI3120_CTR0_REG); val |= (inw(dev->iobase + APCI3120_TIMER_VALUE) << 16); } @@ -1693,10 +1678,9 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; if (comedi_dio_update_state(s, data)) { - /* The do channels are bits 7:4 of the do register */ - devpriv->do_bits = s->state << 4; - - outb(devpriv->do_bits, dev->iobase + APCI3120_DIGITAL_OUTPUT); + devpriv->do_bits = s->state; + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits), + dev->iobase + APCI3120_CTR0_REG); } data[1] = s->state; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6819cc09a60e..51637e1628bc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -19,6 +19,8 @@ #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) +#define APCI3120_CTR0_REG 0x0d +#define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) /* -- GitLab From dd62c4373ae1cd48d0f1561646443d2aed299e21 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:50 -0700 Subject: [PATCH 3735/9457] staging: comedi: addi_apci_3120: fix counter and external interrupt disable The APCI3120_DISABLE_ALL_TIMER define define is not needed, and it's used incorrectly in apci3120_cancel(). The define is a mask of the bits needed to disable the counters. Writing the value directly sets unintended bits. Prior to writing the value, the 'devpriv->us_OutputRegister' is set to 0 and written to the register. This disables all the timers and the external trigger. Remove the unnecessary apci3120_exttrig_disable() call as well as the write of APCI3120_DISABLE_ALL_TIMER. In apci3120_interrupt(), remove the unnecessary mask and write to disable all the timers. The COMEDI_CB_EOA event will cause the core to call the (*cancel) operation which will disable the timers. Remove the unused define. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 93b17252a907..6eaf62ab5446 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -167,9 +167,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER2_SELECT_EOS 0xc0 #define APCI3120_COUNTER 3 -#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & \ - APCI3120_DISABLE_TIMER1 & \ - APCI3120_DISABLE_TIMER2) /* ANALOG INPUT RANGE */ static const struct comedi_lrange range_apci3120_ai = { @@ -613,16 +610,9 @@ static int apci3120_cancel(struct comedi_device *dev, /* Disable BUS Master PCI */ outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); - /* Disable ext trigger */ - apci3120_exttrig_disable(dev); - + /* stop all counters and disable external trigger */ devpriv->us_OutputRegister = 0; - /* stop counters */ - outw(devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS); - - outw(APCI3120_DISABLE_ALL_TIMER, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); /* DISABLE_ALL_INTERRUPT */ outb(APCI3120_DISABLE_ALL_INTERRUPT, @@ -1346,13 +1336,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* stop timer 2 */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister & APCI3120_DISABLE_ALL_TIMER; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - s->async->events |= COMEDI_CB_EOA; break; -- GitLab From 0c188e9cc9c4e7920215903779be3010ffdaf602 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:51 -0700 Subject: [PATCH 3736/9457] staging: comedi: addi_apci_3120: rename APCI3120_TIMER_VALUE For aesthetics, rename this register offset. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 9 ++++----- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 6eaf62ab5446..c9b416ededcc 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -149,7 +149,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_CRT1 0x0c -#define APCI3120_TIMER_VALUE 0x04 #define APCI3120_TIMER_STATUS_REGISTER 0x0d #define APCI3120_RD_STATUS 0x02 #define APCI3120_WR_ADDRESS 0x00 @@ -191,14 +190,14 @@ static void apci3120_timer_write(struct comedi_device *dev, outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer), dev->iobase + APCI3120_CTR0_REG); - outw(val & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); + outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG); if (timer == 2) { /* write upper 16-bits to timer 2 */ outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer + 1), dev->iobase + APCI3120_CTR0_REG); - outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_VALUE); + outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG); } } @@ -212,14 +211,14 @@ static unsigned int apci3120_timer_read(struct comedi_device *dev, outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer), dev->iobase + APCI3120_CTR0_REG); - val = inw(dev->iobase + APCI3120_TIMER_VALUE); + val = inw(dev->iobase + APCI3120_TIMER_REG); if (timer == 2) { /* read upper 16-bits from timer 2 */ outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | APCI3120_CTR0_TIMER_SEL(timer + 1), dev->iobase + APCI3120_CTR0_REG); - val |= (inw(dev->iobase + APCI3120_TIMER_VALUE) << 16); + val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16); } return val; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 51637e1628bc..f431e5492de8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,6 +16,7 @@ * PCI BAR 1 register map (dev->iobase) */ #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) +#define APCI3120_TIMER_REG 0x04 #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) -- GitLab From 486beeb488f589bc34bb0cff51415c2040abcb47 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:52 -0700 Subject: [PATCH 3737/9457] staging: comedi: addi_apci_3120: rename private data 'b_TimerSelectMode' Rename this CamelCase member of the private data and tidy up the mask/set of its bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 70 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c9b416ededcc..546c4c373550 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -344,7 +344,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, ns = devpriv->ui_EocEosConversionTime; /* Clear software registers */ - devpriv->b_TimerSelectMode = 0; + devpriv->timer_mode = 0; devpriv->b_ModeSelectRegister = 0; devpriv->us_OutputRegister = 0; @@ -373,11 +373,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 4 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | - APCI3120_TIMER_0_MODE_4; - outb(devpriv->b_TimerSelectMode, + devpriv->timer_mode &= 0xfc; + devpriv->timer_mode |= APCI3120_TIMER_0_MODE_4; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ @@ -458,11 +456,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | - APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, + devpriv->timer_mode &= 0xfc; + devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set the conversion time */ @@ -720,7 +716,7 @@ static int apci3120_cyclic_ai(int mode, devpriv->ai_running = 1; /* clear software registers */ - devpriv->b_TimerSelectMode = 0; + devpriv->timer_mode = 0; devpriv->us_OutputRegister = 0; devpriv->b_ModeSelectRegister = 0; @@ -759,11 +755,9 @@ static int apci3120_cyclic_ai(int mode, switch (mode) { case 1: /* init timer0 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0xfc; + devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); @@ -771,21 +765,17 @@ static int apci3120_cyclic_ai(int mode, case 2: /* init timer1 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xF3) | APCI3120_TIMER_1_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0xf3; + devpriv->timer_mode |= APCI3120_TIMER_1_MODE_2; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set the scan begin time */ apci3120_timer_write(dev, 1, divisor1); /* init timer0 in mode 2 */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0xfc; + devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); @@ -834,12 +824,10 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* (1) Init timer 2 in mode 0 and write timer value */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | - APCI3120_TIMER_2_MODE_0; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0x0f; + devpriv->timer_mode |= APCI3120_TIMER_2_MODE_0; + outb(devpriv->timer_mode, + dev->iobase + APCI3120_TIMER_CRT1); /* Set the scan stop count (not sure about the -2) */ apci3120_timer_write(dev, 2, cmd->stop_arg - 2); @@ -1434,11 +1422,9 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0x0f; + devpriv->timer_mode |= APCI3120_TIMER_2_MODE_2; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set timer 2 delay */ apci3120_timer_write(dev, 2, divisor); @@ -1449,11 +1435,9 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, } else { /* Initialize Watch dog */ /* Set the Timer 2 in mode 5(Watchdog) */ - devpriv->b_TimerSelectMode = - (devpriv-> - b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5; - outb(devpriv->b_TimerSelectMode, - dev->iobase + APCI3120_TIMER_CRT1); + devpriv->timer_mode &= 0x0f; + devpriv->timer_mode |= APCI3120_TIMER_2_MODE_5; + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); /* Set timer 2 delay */ apci3120_timer_write(dev, 2, divisor); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f431e5492de8..6882f8ee67a4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -77,7 +77,7 @@ struct apci3120_private { unsigned int ui_DmaActualBuffer; struct apci3120_dmabuf dmabuf[2]; unsigned char do_bits; - unsigned char b_TimerSelectMode; + unsigned char timer_mode; unsigned char b_ModeSelectRegister; unsigned short us_OutputRegister; unsigned char b_Timer2Mode; -- GitLab From 2016c534dd2f4b0599e5a8513567a34d4746cdf6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:53 -0700 Subject: [PATCH 3738/9457] staging: comedi: addi_apci_3120: tidy up timer_mode masking Define a macro that returns the mask of the timer_mode bits for a given timer. Use the macro to remove the "magic" values used to clear the bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 16 ++++++++-------- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 546c4c373550..a876adae58d2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -373,7 +373,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 4 */ - devpriv->timer_mode &= 0xfc; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); devpriv->timer_mode |= APCI3120_TIMER_0_MODE_4; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -456,7 +456,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 2 */ - devpriv->timer_mode &= 0xfc; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -755,7 +755,7 @@ static int apci3120_cyclic_ai(int mode, switch (mode) { case 1: /* init timer0 in mode 2 */ - devpriv->timer_mode &= 0xfc; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -765,7 +765,7 @@ static int apci3120_cyclic_ai(int mode, case 2: /* init timer1 in mode 2 */ - devpriv->timer_mode &= 0xf3; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(1); devpriv->timer_mode |= APCI3120_TIMER_1_MODE_2; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -773,7 +773,7 @@ static int apci3120_cyclic_ai(int mode, apci3120_timer_write(dev, 1, divisor1); /* init timer0 in mode 2 */ - devpriv->timer_mode &= 0xfc; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -824,7 +824,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* (1) Init timer 2 in mode 0 and write timer value */ - devpriv->timer_mode &= 0x0f; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); devpriv->timer_mode |= APCI3120_TIMER_2_MODE_0; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -1422,7 +1422,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ - devpriv->timer_mode &= 0x0f; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); devpriv->timer_mode |= APCI3120_TIMER_2_MODE_2; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); @@ -1435,7 +1435,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, } else { /* Initialize Watch dog */ /* Set the Timer 2 in mode 5(Watchdog) */ - devpriv->timer_mode &= 0x0f; + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); devpriv->timer_mode |= APCI3120_TIMER_2_MODE_5; outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6882f8ee67a4..999add3928ef 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -20,6 +20,7 @@ #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) +#define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2)) #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) -- GitLab From e6da4c6a2db10ae79704e809ee2896e6bcf230b9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:54 -0700 Subject: [PATCH 3739/9457] staging: comedi: addi_apci_3120: introduce apci3120_timer_set_mode() Introduce a helper function to set the operation mode of a timer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 57 ++++++------------- .../staging/comedi/drivers/addi_apci_3120.c | 6 ++ 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a876adae58d2..dc6eb56e0e1a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -101,8 +101,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_10_GAIN 0x30 #define APCI3120_SEQ_RAM_ADDRESS 0x06 #define APCI3120_RESET_FIFO 0x0c -#define APCI3120_TIMER_0_MODE_2 0x01 -#define APCI3120_TIMER_0_MODE_4 0x2 #define APCI3120_ENABLE_TIMER0 0x1000 #define APCI3120_CLEAR_PR 0xf0ff #define APCI3120_CLEAR_PA 0xfff0 @@ -140,14 +138,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_ENABLE_TIMER_INT 0x04 #define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e -#define APCI3120_TIMER_1_MODE_2 0x4 - -/* $$ BIT FOR MODE IN nCsTimerCtr1 */ -#define APCI3120_TIMER_2_MODE_0 0x0 -#define APCI3120_TIMER_2_MODE_2 0x10 -#define APCI3120_TIMER_2_MODE_5 0x30 - -#define APCI3120_TIMER_CRT1 0x0c #define APCI3120_TIMER_STATUS_REGISTER 0x0d #define APCI3120_RD_STATUS 0x02 @@ -224,6 +214,16 @@ static unsigned int apci3120_timer_read(struct comedi_device *dev, return val; } +static void apci3120_timer_set_mode(struct comedi_device *dev, + unsigned int timer, unsigned int mode) +{ + struct apci3120_private *devpriv = dev->private; + + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer); + devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode); + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG); +} + static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -373,10 +373,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 4 */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); - devpriv->timer_mode |= APCI3120_TIMER_0_MODE_4; - outb(devpriv->timer_mode, - dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ devpriv->b_ModeSelectRegister = @@ -456,10 +453,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, return -EINVAL; /* Initialize Timer 0 mode 2 */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); - devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; - outb(devpriv->timer_mode, - dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor); @@ -755,9 +749,7 @@ static int apci3120_cyclic_ai(int mode, switch (mode) { case 1: /* init timer0 in mode 2 */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); - devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); @@ -765,17 +757,13 @@ static int apci3120_cyclic_ai(int mode, case 2: /* init timer1 in mode 2 */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(1); - devpriv->timer_mode |= APCI3120_TIMER_1_MODE_2; - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); /* Set the scan begin time */ apci3120_timer_write(dev, 1, divisor1); /* init timer0 in mode 2 */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(0); - devpriv->timer_mode |= APCI3120_TIMER_0_MODE_2; - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); @@ -824,10 +812,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* (1) Init timer 2 in mode 0 and write timer value */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); - devpriv->timer_mode |= APCI3120_TIMER_2_MODE_0; - outb(devpriv->timer_mode, - dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0); /* Set the scan stop count (not sure about the -2) */ apci3120_timer_write(dev, 2, cmd->stop_arg - 2); @@ -1422,22 +1407,16 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); - devpriv->timer_mode |= APCI3120_TIMER_2_MODE_2; - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE2); /* Set timer 2 delay */ apci3120_timer_write(dev, 2, divisor); /* timer2 in Timer mode enabled */ devpriv->b_Timer2Mode = APCI3120_TIMER; - } else { /* Initialize Watch dog */ - /* Set the Timer 2 in mode 5(Watchdog) */ - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(2); - devpriv->timer_mode |= APCI3120_TIMER_2_MODE_5; - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_CRT1); + apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE5); /* Set timer 2 delay */ apci3120_timer_write(dev, 2, divisor); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 999add3928ef..20babacd40d3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -20,6 +20,12 @@ #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) +#define APCI3120_TIMER_MODE_REG 0x0c +#define APCI3120_TIMER_MODE(_t, _m) ((_m) << ((_t) * 2)) +#define APCI3120_TIMER_MODE0 0 /* I8254_MODE0 */ +#define APCI3120_TIMER_MODE2 1 /* I8254_MODE2 */ +#define APCI3120_TIMER_MODE4 2 /* I8254_MODE4 */ +#define APCI3120_TIMER_MODE5 3 /* I8254_MODE5 */ #define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2)) #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) -- GitLab From b3c8ee5cbc5f995c738a5651a2b22297950be6a2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:55 -0700 Subject: [PATCH 3740/9457] staging: comedi: addi_apci_3120: move timer helpers to main driver source Move the timer read/write and set mode helpers from the included source file into the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 53 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 53 +++++++++++++++++++ 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index dc6eb56e0e1a..d4d66e490b54 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -171,59 +171,6 @@ static const struct comedi_lrange range_apci3120_ai = { } }; -static void apci3120_timer_write(struct comedi_device *dev, - unsigned int timer, unsigned int val) -{ - struct apci3120_private *devpriv = dev->private; - - /* write 16-bit value to timer (lower 16-bits of timer 2) */ - outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | - APCI3120_CTR0_TIMER_SEL(timer), - dev->iobase + APCI3120_CTR0_REG); - outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG); - - if (timer == 2) { - /* write upper 16-bits to timer 2 */ - outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | - APCI3120_CTR0_TIMER_SEL(timer + 1), - dev->iobase + APCI3120_CTR0_REG); - outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG); - } -} - -static unsigned int apci3120_timer_read(struct comedi_device *dev, - unsigned int timer) -{ - struct apci3120_private *devpriv = dev->private; - unsigned int val; - - /* read 16-bit value from timer (lower 16-bits of timer 2) */ - outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | - APCI3120_CTR0_TIMER_SEL(timer), - dev->iobase + APCI3120_CTR0_REG); - val = inw(dev->iobase + APCI3120_TIMER_REG); - - if (timer == 2) { - /* read upper 16-bits from timer 2 */ - outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | - APCI3120_CTR0_TIMER_SEL(timer + 1), - dev->iobase + APCI3120_CTR0_REG); - val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16); - } - - return val; -} - -static void apci3120_timer_set_mode(struct comedi_device *dev, - unsigned int timer, unsigned int mode) -{ - struct apci3120_private *devpriv = dev->private; - - devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer); - devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode); - outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG); -} - static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 20babacd40d3..e53561194bae 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -150,6 +150,59 @@ static unsigned int apci3120_ns_to_timer(struct comedi_device *dev, return divisor; } +static void apci3120_timer_write(struct comedi_device *dev, + unsigned int timer, unsigned int val) +{ + struct apci3120_private *devpriv = dev->private; + + /* write 16-bit value to timer (lower 16-bits of timer 2) */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_CTR0_REG); + outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG); + + if (timer == 2) { + /* write upper 16-bits to timer 2 */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_CTR0_REG); + outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG); + } +} + +static unsigned int apci3120_timer_read(struct comedi_device *dev, + unsigned int timer) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int val; + + /* read 16-bit value from timer (lower 16-bits of timer 2) */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer), + dev->iobase + APCI3120_CTR0_REG); + val = inw(dev->iobase + APCI3120_TIMER_REG); + + if (timer == 2) { + /* read upper 16-bits from timer 2 */ + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) | + APCI3120_CTR0_TIMER_SEL(timer + 1), + dev->iobase + APCI3120_CTR0_REG); + val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16); + } + + return val; +} + +static void apci3120_timer_set_mode(struct comedi_device *dev, + unsigned int timer, unsigned int mode) +{ + struct apci3120_private *devpriv = dev->private; + + devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer); + devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode); + outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG); +} + #include "addi-data/hwdrv_apci3120.c" static void apci3120_dma_alloc(struct comedi_device *dev) -- GitLab From 5a1f46c8fb2859be4fc7c225f2fca95640b6d7c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:56 -0700 Subject: [PATCH 3741/9457] staging: comedi: addi_apci_3120: rename private data 'us_OutputRegister' Rename this CamelCase member of the private data and tidy up the mask/set of its bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 110 +++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 42 insertions(+), 70 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d4d66e490b54..4231e99260ed 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -247,10 +247,9 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, return 1; /* Code to set the PA and PR...Here it set PA to 0 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; - devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_CLEAR_PA_PR; + devpriv->ctrl = ((n_chan - 1) & 0xf) << 8; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); for (i = 0; i < n_chan; i++) { /* store range list to card */ @@ -293,7 +292,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Clear software registers */ devpriv->timer_mode = 0; devpriv->b_ModeSelectRegister = 0; - devpriv->us_OutputRegister = 0; + devpriv->ctrl = 0; if (insn->unused[0] == 222) { /* second insn read */ for (i = 0; i < insn->n; i++) @@ -348,12 +347,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Sets gate 0 */ - devpriv->us_OutputRegister = - (devpriv-> - us_OutputRegister & APCI3120_CLEAR_PA_PR) | - APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_CLEAR_PA_PR; + devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor); @@ -386,13 +382,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + APCI3120_RESET_FIFO); /* clear PA PR and disable timer 0 */ - devpriv->us_OutputRegister = - (devpriv-> - us_OutputRegister & APCI3120_CLEAR_PA_PR) | - APCI3120_DISABLE_TIMER0; - - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_CLEAR_PA_PR; + devpriv->ctrl |= APCI3120_DISABLE_TIMER0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, @@ -434,11 +426,8 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + APCI3120_RD_STATUS); /* Sets gate 0 */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Start conversion */ outw(0, dev->iobase + APCI3120_START_CONVERSION); @@ -496,8 +485,8 @@ static int apci3120_reset(struct comedi_device *dev) dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Disables all counters, ext trigger and clears PA, PR */ - devpriv->us_OutputRegister = 0; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl = 0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); inw(dev->iobase + 0); /* make a dummy read */ inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ @@ -515,8 +504,8 @@ static int apci3120_exttrig_enable(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); return 0; } @@ -524,8 +513,8 @@ static int apci3120_exttrig_disable(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= ~APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); return 0; } @@ -547,8 +536,8 @@ static int apci3120_cancel(struct comedi_device *dev, outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); /* stop all counters and disable external trigger */ - devpriv->us_OutputRegister = 0; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl = 0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* DISABLE_ALL_INTERRUPT */ outb(APCI3120_DISABLE_ALL_INTERRUPT, @@ -658,7 +647,7 @@ static int apci3120_cyclic_ai(int mode, /* clear software registers */ devpriv->timer_mode = 0; - devpriv->us_OutputRegister = 0; + devpriv->ctrl = 0; devpriv->b_ModeSelectRegister = 0; /* Clear Timer Write TC int */ @@ -667,11 +656,10 @@ static int apci3120_cyclic_ai(int mode, /* Disables All Timer */ /* Sets PR and PA to 0 */ - devpriv->us_OutputRegister = devpriv->us_OutputRegister & - APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1 & APCI3120_CLEAR_PA_PR; - - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_DISABLE_TIMER0 & + APCI3120_DISABLE_TIMER1 & + APCI3120_CLEAR_PA_PR; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Resets the FIFO */ /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ @@ -744,11 +732,8 @@ static int apci3120_cyclic_ai(int mode, * configure Timer2 For counting EOS Reset gate 2 of Timer 2 to * disable it (Set Bit D14 to 0) */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER2; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_DISABLE_TIMER2; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* DISABLE TIMER intERRUPT */ devpriv->b_ModeSelectRegister = @@ -946,28 +931,21 @@ static int apci3120_cyclic_ai(int mode, if (devpriv->us_UseDma == APCI3120_DISABLE && cmd->stop_src == TRIG_COUNT) { /* set gate 2 to start conversion */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_TIMER2; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); } switch (mode) { case 1: /* set gate 0 to start conversion */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); break; case 2: /* set gate 0 and gate 1 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1; - devpriv->us_OutputRegister = - devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_TIMER1 | + APCI3120_ENABLE_TIMER0; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); break; } @@ -1301,7 +1279,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } else { /* Stops the Timer */ outw(devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER0 & + ctrl & APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS); } @@ -1336,9 +1314,8 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_DISABLE_TIMER2; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Disable TIMER Interrupt */ devpriv->b_ModeSelectRegister = @@ -1449,11 +1426,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* For Timer mode is Gate2 must be activated timer started */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister | APCI3120_ENABLE_TIMER2; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl |= APCI3120_ENABLE_TIMER2; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); } break; @@ -1482,10 +1456,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Reset Gate 2 */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); + devpriv->ctrl &= APCI3120_DISABLE_TIMER_INT; + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Reset FC_TIMER BIT */ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e53561194bae..e320c0826d3b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -86,7 +86,7 @@ struct apci3120_private { unsigned char do_bits; unsigned char timer_mode; unsigned char b_ModeSelectRegister; - unsigned short us_OutputRegister; + unsigned short ctrl; unsigned char b_Timer2Mode; unsigned char b_Timer2Interrupt; unsigned int ai_running:1; -- GitLab From c24ca0e691bd5b8e2e332577a6014de9572b9194 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:57 -0700 Subject: [PATCH 3742/9457] staging: comedi: addi_apci_3120: tidy up devpriv->ctrl use The apci3120_setup_chan_list() function sets devpriv->ctrl to the scan length (PR) and scan start (PA) values and writes the value to the register. There is no need to mask the value first. The apci3120_ai_insn_read() function calles apci3120_setup_chan_list(). There is no need to clear devpriv->ctrl first or clear any additional bits and write the register again. This also fixes an incorrect use of APCI3120_DISABLE_TIMER0 to disable the timer. apci3120_cyclic_ai() also calls apci3120_setup_chan_list() so it does not need to clear devpriv->ctrl or clear any addidional bits and write the register. Update the comments in apci3120_reset() and apci3120_cancel(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 34 +++---------------- .../staging/comedi/drivers/addi_apci_3120.c | 2 ++ 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 4231e99260ed..71fcaa4fb0c6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -102,9 +102,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_SEQ_RAM_ADDRESS 0x06 #define APCI3120_RESET_FIFO 0x0c #define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_CLEAR_PR 0xf0ff -#define APCI3120_CLEAR_PA 0xfff0 -#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) /* nWrMode_Select */ #define APCI3120_ENABLE_SCAN 0x8 @@ -246,9 +243,8 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, if (check) return 1; - /* Code to set the PA and PR...Here it set PA to 0 */ - devpriv->ctrl &= APCI3120_CLEAR_PA_PR; - devpriv->ctrl = ((n_chan - 1) & 0xf) << 8; + /* set scan length (PR) and scan start (PA) */ + devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); for (i = 0; i < n_chan; i++) { @@ -292,7 +288,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Clear software registers */ devpriv->timer_mode = 0; devpriv->b_ModeSelectRegister = 0; - devpriv->ctrl = 0; if (insn->unused[0] == 222) { /* second insn read */ for (i = 0; i < insn->n; i++) @@ -347,7 +342,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Sets gate 0 */ - devpriv->ctrl &= APCI3120_CLEAR_PA_PR; devpriv->ctrl |= APCI3120_ENABLE_TIMER0; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); @@ -380,11 +374,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + 0); /* Clears the FIFO */ inw(dev->iobase + APCI3120_RESET_FIFO); - /* clear PA PR and disable timer 0 */ - - devpriv->ctrl &= APCI3120_CLEAR_PA_PR; - devpriv->ctrl |= APCI3120_DISABLE_TIMER0; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, @@ -484,7 +473,7 @@ static int apci3120_reset(struct comedi_device *dev) outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* Disables all counters, ext trigger and clears PA, PR */ + /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); @@ -535,7 +524,7 @@ static int apci3120_cancel(struct comedi_device *dev, /* Disable BUS Master PCI */ outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); - /* stop all counters and disable external trigger */ + /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); @@ -647,20 +636,12 @@ static int apci3120_cyclic_ai(int mode, /* clear software registers */ devpriv->timer_mode = 0; - devpriv->ctrl = 0; devpriv->b_ModeSelectRegister = 0; /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - /* Disables All Timer */ - /* Sets PR and PA to 0 */ - devpriv->ctrl &= APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1 & - APCI3120_CLEAR_PA_PR; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); - /* Resets the FIFO */ /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ inb(dev->iobase + APCI3120_RESET_FIFO); @@ -728,12 +709,7 @@ static int apci3120_cyclic_ai(int mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (cmd->stop_src == TRIG_COUNT) { - /* - * configure Timer2 For counting EOS Reset gate 2 of Timer 2 to - * disable it (Set Bit D14 to 0) - */ - devpriv->ctrl &= APCI3120_DISABLE_TIMER2; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + /* configure Timer2 For counting EOS */ /* DISABLE TIMER intERRUPT */ devpriv->b_ModeSelectRegister = diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e320c0826d3b..97782401e142 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,6 +15,8 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) +#define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) #define APCI3120_TIMER_REG 0x04 #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) -- GitLab From e0ca363a3e0beef3b111ff73bdcec1f15bea671c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:58 -0700 Subject: [PATCH 3743/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_TIMER[012] For aesthetics, remove these defines and just use ~APCI3120_ENABLE_TIMER[012]. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 71fcaa4fb0c6..3575453afbc9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -131,7 +131,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 #define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) #define APCI3120_ENABLE_TIMER_INT 0x04 #define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e @@ -147,9 +146,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_ENABLE_TIMER0 0x1000 #define APCI3120_ENABLE_TIMER1 0x2000 #define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) -#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) #define APCI3120_TIMER2_SELECT_EOS 0xc0 #define APCI3120_COUNTER 3 @@ -1254,10 +1250,10 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) apci3120_interrupt_dma(irq, d); } else { /* Stops the Timer */ - outw(devpriv-> - ctrl & APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1, - dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl & + ~APCI3120_ENABLE_TIMER0 & + ~APCI3120_ENABLE_TIMER1, + dev->iobase + APCI3120_WR_ADDRESS); } } @@ -1290,7 +1286,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ - devpriv->ctrl &= APCI3120_DISABLE_TIMER2; + devpriv->ctrl &= ~APCI3120_ENABLE_TIMER2; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Disable TIMER Interrupt */ -- GitLab From 20f75b5641dfb12aa8acc53afd6ed65ca49af172 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:53:59 -0700 Subject: [PATCH 3744/9457] staging: comedi: addi_apci_3120: tidy up APCI3120_ENABLE_TIMER[012] For aesthetics, replace these defines with a macro that returns the correct bit needed to set the gate bit to enable a timer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 25 ++++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3575453afbc9..8e474a14a670 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -101,7 +101,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_10_GAIN 0x30 #define APCI3120_SEQ_RAM_ADDRESS 0x06 #define APCI3120_RESET_FIFO 0x0c -#define APCI3120_ENABLE_TIMER0 0x1000 /* nWrMode_Select */ #define APCI3120_ENABLE_SCAN 0x8 @@ -130,7 +129,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_WATCHDOG 2 #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 -#define APCI3120_ENABLE_TIMER2 0x4000 #define APCI3120_ENABLE_TIMER_INT 0x04 #define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e @@ -143,9 +141,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_ENABLE_TIMER_COUNTER 0x10 #define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) #define APCI3120_FC_TIMER 0x1000 -#define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_ENABLE_TIMER1 0x2000 -#define APCI3120_ENABLE_TIMER2 0x4000 #define APCI3120_TIMER2_SELECT_EOS 0xc0 #define APCI3120_COUNTER 3 @@ -338,7 +333,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* Sets gate 0 */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + devpriv->ctrl |= APCI3120_CTRL_GATE(0); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Set the conversion time */ @@ -411,7 +406,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + APCI3120_RD_STATUS); /* Sets gate 0 */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + devpriv->ctrl |= APCI3120_CTRL_GATE(0); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Start conversion */ @@ -903,20 +898,20 @@ static int apci3120_cyclic_ai(int mode, if (devpriv->us_UseDma == APCI3120_DISABLE && cmd->stop_src == TRIG_COUNT) { /* set gate 2 to start conversion */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER2; + devpriv->ctrl |= APCI3120_CTRL_GATE(2); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); } switch (mode) { case 1: /* set gate 0 to start conversion */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER0; + devpriv->ctrl |= APCI3120_CTRL_GATE(0); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); break; case 2: /* set gate 0 and gate 1 */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER1 | - APCI3120_ENABLE_TIMER0; + devpriv->ctrl |= APCI3120_CTRL_GATE(1) | + APCI3120_CTRL_GATE(0); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); break; @@ -1251,8 +1246,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } else { /* Stops the Timer */ outw(devpriv->ctrl & - ~APCI3120_ENABLE_TIMER0 & - ~APCI3120_ENABLE_TIMER1, + ~APCI3120_CTRL_GATE(0) & + ~APCI3120_CTRL_GATE(1), dev->iobase + APCI3120_WR_ADDRESS); } @@ -1286,7 +1281,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ - devpriv->ctrl &= ~APCI3120_ENABLE_TIMER2; + devpriv->ctrl &= ~APCI3120_CTRL_GATE(2); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); /* Disable TIMER Interrupt */ @@ -1398,7 +1393,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* For Timer mode is Gate2 must be activated timer started */ - devpriv->ctrl |= APCI3120_ENABLE_TIMER2; + devpriv->ctrl |= APCI3120_CTRL_GATE(2); outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 97782401e142..58db0aba088b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,6 +15,7 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) -- GitLab From 6d210c8d96b7ae073ed43c46de21329115e9090a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:00 -0700 Subject: [PATCH 3745/9457] staging: comedi: addi_apci_3120: rename APCI3120_ENABLE_EXT_TRIGGER For aesthetics, rename this define. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 7 ++----- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 8e474a14a670..77704685e108 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -89,9 +89,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 -/* Enable external trigger bit in nWrAddress */ -#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 - /* ANALOG OUTPUT AND INPUT DEFINE */ #define APCI3120_UNIPOLAR 0x80 #define APCI3120_BIPOLAR 0x00 @@ -484,7 +481,7 @@ static int apci3120_exttrig_enable(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->ctrl |= APCI3120_ENABLE_EXT_TRIGGER; + devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); return 0; } @@ -493,7 +490,7 @@ static int apci3120_exttrig_disable(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->ctrl &= ~APCI3120_ENABLE_EXT_TRIGGER; + devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); return 0; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 58db0aba088b..087ff1acf088 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,6 +15,7 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_CTRL_EXT_TRIG (1 << 15) #define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) -- GitLab From a6a1cfed89b5aca6e5ba179b3788d639ebe0c624 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:01 -0700 Subject: [PATCH 3746/9457] staging: comedi: addi_apci_3120: tidy up apci3120_exttrig_{enable,disable}() Merge these two functions and use an 'enable' parameter to determine if the external trigger needs to be enabled or disabled. This function always succeeds and the callers don't check the return. Change the return type to void. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 77704685e108..30606c947530 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -477,22 +477,15 @@ static int apci3120_reset(struct comedi_device *dev) return 0; } -static int apci3120_exttrig_enable(struct comedi_device *dev) +static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) { struct apci3120_private *devpriv = dev->private; - devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} - -static int apci3120_exttrig_disable(struct comedi_device *dev) -{ - struct apci3120_private *devpriv = dev->private; - - devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; + if (enable) + devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; + else + devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); - return 0; } static int apci3120_cancel(struct comedi_device *dev, @@ -649,7 +642,8 @@ static int apci3120_cyclic_ai(int mode, } if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) - apci3120_exttrig_enable(dev); /* activate EXT trigger */ + apci3120_exttrig_enable(dev, true); + switch (mode) { case 1: /* init timer0 in mode 2 */ @@ -1114,8 +1108,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) int_daq = (int_daq >> 12) & 0xF; if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { - /* Disable ext trigger */ - apci3120_exttrig_disable(dev); + apci3120_exttrig_enable(dev, false); devpriv->b_ExttrigEnable = APCI3120_DISABLE; } /* clear the timer 2 interrupt */ -- GitLab From 4ffa00a3cb634a363ee72339cb740ffdee389f66 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:02 -0700 Subject: [PATCH 3747/9457] staging: comedi: addi_apci_3120: introduce apci3120_timer_enable() Introduce a helper function to enable/disable a timer. The disable of timers 0 and 1 in apci3120_interrupt() is probably not needed. For now use the helper function to make sure the devpriv->ctrl bits are cleared correctly to disable the timers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 30606c947530..8da1db546b19 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -156,6 +156,18 @@ static const struct comedi_lrange range_apci3120_ai = { } }; +static void apci3120_timer_enable(struct comedi_device *dev, + unsigned int timer, bool enable) +{ + struct apci3120_private *devpriv = dev->private; + + if (enable) + devpriv->ctrl |= APCI3120_CTRL_GATE(timer); + else + devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer); + outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); +} + static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -329,9 +341,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* Sets gate 0 */ - devpriv->ctrl |= APCI3120_CTRL_GATE(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 0, true); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor); @@ -402,9 +412,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + APCI3120_RD_STATUS); - /* Sets gate 0 */ - devpriv->ctrl |= APCI3120_CTRL_GATE(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 0, true); /* Start conversion */ outw(0, dev->iobase + APCI3120_START_CONVERSION); @@ -887,25 +895,17 @@ static int apci3120_cyclic_ai(int mode, } if (devpriv->us_UseDma == APCI3120_DISABLE && - cmd->stop_src == TRIG_COUNT) { - /* set gate 2 to start conversion */ - devpriv->ctrl |= APCI3120_CTRL_GATE(2); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); - } + cmd->stop_src == TRIG_COUNT) + apci3120_timer_enable(dev, 2, true); switch (mode) { case 1: - /* set gate 0 to start conversion */ - devpriv->ctrl |= APCI3120_CTRL_GATE(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 0, true); break; case 2: - /* set gate 0 and gate 1 */ - devpriv->ctrl |= APCI3120_CTRL_GATE(1) | - APCI3120_CTRL_GATE(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 1, true); + apci3120_timer_enable(dev, 0, true); break; - } return 0; @@ -1234,11 +1234,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) /* do some data transfer */ apci3120_interrupt_dma(irq, d); } else { - /* Stops the Timer */ - outw(devpriv->ctrl & - ~APCI3120_CTRL_GATE(0) & - ~APCI3120_CTRL_GATE(1), - dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 0, false); + apci3120_timer_enable(dev, 1, false); } } @@ -1270,9 +1267,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); - /* Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0) */ - devpriv->ctrl &= ~APCI3120_CTRL_GATE(2); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 2, false); /* Disable TIMER Interrupt */ devpriv->b_ModeSelectRegister = @@ -1381,12 +1376,9 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ - /* For Timer mode is Gate2 must be activated timer started */ - devpriv->ctrl |= APCI3120_CTRL_GATE(2); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); - } - + /* start timer */ + if (devpriv->b_Timer2Mode == APCI3120_TIMER) + apci3120_timer_enable(dev, 2, true); break; case APCI3120_STOP: -- GitLab From 38abe9367fc6b047c5ffc6a7684ae8b4f3f78108 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:03 -0700 Subject: [PATCH 3748/9457] staging: comedi: addi_apci_3120: fix timer 2 disable in apci3120_write_insn_timer() The wrong define is being used to disable the gate to stop timer 2 in this function. Use the apci3120_timer_enable() helper to properly disable the timer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 8da1db546b19..3aa4bbedae7f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1404,9 +1404,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* Reset Gate 2 */ - devpriv->ctrl &= APCI3120_DISABLE_TIMER_INT; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + apci3120_timer_enable(dev, 2, false); /* Reset FC_TIMER BIT */ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); -- GitLab From 9625742666306f866c9b56c41c25f8d35721dd29 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:04 -0700 Subject: [PATCH 3749/9457] staging: comedi: addi_apci_3120: rename APCI3120_WR_ADDRESS For aesthetics, rename this define. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 11 +++++------ drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3aa4bbedae7f..184bff4cabd3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -132,7 +132,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_STATUS_REGISTER 0x0d #define APCI3120_RD_STATUS 0x02 -#define APCI3120_WR_ADDRESS 0x00 #define APCI3120_ENABLE_WATCHDOG 0x20 #define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) #define APCI3120_ENABLE_TIMER_COUNTER 0x10 @@ -165,7 +164,7 @@ static void apci3120_timer_enable(struct comedi_device *dev, devpriv->ctrl |= APCI3120_CTRL_GATE(timer); else devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } static int apci3120_ai_insn_config(struct comedi_device *dev, @@ -245,7 +244,7 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, /* set scan length (PR) and scan start (PA) */ devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); for (i = 0; i < n_chan; i++) { /* store range list to card */ @@ -471,7 +470,7 @@ static int apci3120_reset(struct comedi_device *dev) /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); inw(dev->iobase + 0); /* make a dummy read */ inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ @@ -493,7 +492,7 @@ static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; else devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } static int apci3120_cancel(struct comedi_device *dev, @@ -515,7 +514,7 @@ static int apci3120_cancel(struct comedi_device *dev, /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; - outw(devpriv->ctrl, dev->iobase + APCI3120_WR_ADDRESS); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); /* DISABLE_ALL_INTERRUPT */ outb(APCI3120_DISABLE_ALL_INTERRUPT, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 087ff1acf088..014a01495ae2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,6 +15,7 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_CTRL_REG 0x00 #define APCI3120_CTRL_EXT_TRIG (1 << 15) #define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) -- GitLab From a8f77b40b6c20d47816cbde84254ddef68480937 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:05 -0700 Subject: [PATCH 3750/9457] staging: comedi: addi_apci_3120: move apci3120_timer_enable() to driver source Move this helper function from the included source file into the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 12 ------------ drivers/staging/comedi/drivers/addi_apci_3120.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 184bff4cabd3..30e12986b6a3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -155,18 +155,6 @@ static const struct comedi_lrange range_apci3120_ai = { } }; -static void apci3120_timer_enable(struct comedi_device *dev, - unsigned int timer, bool enable) -{ - struct apci3120_private *devpriv = dev->private; - - if (enable) - devpriv->ctrl |= APCI3120_CTRL_GATE(timer); - else - devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer); - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); -} - static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 014a01495ae2..7bfb320d1312 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -208,6 +208,18 @@ static void apci3120_timer_set_mode(struct comedi_device *dev, outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG); } +static void apci3120_timer_enable(struct comedi_device *dev, + unsigned int timer, bool enable) +{ + struct apci3120_private *devpriv = dev->private; + + if (enable) + devpriv->ctrl |= APCI3120_CTRL_GATE(timer); + else + devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); +} + #include "addi-data/hwdrv_apci3120.c" static void apci3120_dma_alloc(struct comedi_device *dev) -- GitLab From b17d390661da546724fa465bbb7fcd7a5f849103 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:06 -0700 Subject: [PATCH 3751/9457] staging: comedi: addi_apci_3120: move apci3120_exttrig_enable() to driver source Move this helper function from the included source file into the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 11 ----------- drivers/staging/comedi/drivers/addi_apci_3120.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 30e12986b6a3..3683c9ca2aad 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -472,17 +472,6 @@ static int apci3120_reset(struct comedi_device *dev) return 0; } -static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) -{ - struct apci3120_private *devpriv = dev->private; - - if (enable) - devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; - else - devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); -} - static int apci3120_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 7bfb320d1312..8f7d9ef18b9c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -220,6 +220,17 @@ static void apci3120_timer_enable(struct comedi_device *dev, outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } +static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) +{ + struct apci3120_private *devpriv = dev->private; + + if (enable) + devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG; + else + devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG; + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); +} + #include "addi-data/hwdrv_apci3120.c" static void apci3120_dma_alloc(struct comedi_device *dev) -- GitLab From 24e18c85e57255f75cbbc3d8c4f8e36cd9ea7204 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:07 -0700 Subject: [PATCH 3752/9457] staging: comedi: addi_apci_3120: introduce apci3120_clr_timer2_interrupt() A dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt. Introduce a helper function to clarify this. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 30 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 6 ++++ 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3683c9ca2aad..6f547ee0b4ce 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -130,7 +130,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e -#define APCI3120_TIMER_STATUS_REGISTER 0x0d #define APCI3120_RD_STATUS 0x02 #define APCI3120_ENABLE_WATCHDOG 0x20 #define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) @@ -691,8 +690,8 @@ static int apci3120_cyclic_ai(int mode, /* Set the scan stop count (not sure about the -2) */ apci3120_timer_write(dev, 2, cmd->stop_arg - 2); - /* (2) Reset FC_TIMER BIT Clearing timer status register */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); + apci3120_clr_timer2_interrupt(dev); + /* enable timer counter and disable watch dog */ devpriv->b_ModeSelectRegister = (devpriv-> @@ -1067,7 +1066,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) unsigned short int_daq; unsigned int int_amcc, ui_Check, i; unsigned short us_TmpValue; - unsigned char b_DummyRead; ui_Check = 1; @@ -1087,8 +1085,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) apci3120_exttrig_enable(dev, false); devpriv->b_ExttrigEnable = APCI3120_DISABLE; } - /* clear the timer 2 interrupt */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); + + apci3120_clr_timer2_interrupt(dev); if (int_amcc & MASTER_ABORT_INT) dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); @@ -1194,8 +1192,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } - b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - + apci3120_clr_timer2_interrupt(dev); } if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { @@ -1205,8 +1202,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) outl(APCI3120_CLEAR_WRITE_TC_INT, devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - /* Clears the timer status register */ - inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); + apci3120_clr_timer2_interrupt(dev); + /* do some data transfer */ apci3120_interrupt_dma(irq, d); } else { @@ -1318,9 +1315,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, switch (data[0]) { case APCI3120_START: + apci3120_clr_timer2_interrupt(dev); - /* Reset FC_TIMER BIT */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* Enable Timer */ devpriv->b_ModeSelectRegister = @@ -1382,9 +1378,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); - /* Reset FC_TIMER BIT */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - + apci3120_clr_timer2_interrupt(dev); break; case 2: /* write new value to Timer */ @@ -1434,10 +1428,8 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, us_StatusValue = inw(dev->iobase + APCI3120_RD_STATUS); us_StatusValue = ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1; - if (us_StatusValue == 1) { - /* RESET FC_TIMER BIT */ - inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - } + if (us_StatusValue == 1) + apci3120_clr_timer2_interrupt(dev); data[0] = us_StatusValue; /* when data[0] = 1 then the watch dog has rundown */ } return insn->n; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 8f7d9ef18b9c..ce94f907d9ef 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -155,6 +155,12 @@ static unsigned int apci3120_ns_to_timer(struct comedi_device *dev, return divisor; } +static void apci3120_clr_timer2_interrupt(struct comedi_device *dev) +{ + /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */ + inb(dev->iobase + APCI3120_CTR0_REG); +} + static void apci3120_timer_write(struct comedi_device *dev, unsigned int timer, unsigned int val) { -- GitLab From 51db6bad08ea3f74768c40f254f4659f226b65e1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:08 -0700 Subject: [PATCH 3753/9457] staging: comedi: addi_apci_3120: remove unnecessary reset of the scan sequence The scan sequence does not need to be reset when the driver is attached. Remove the code in apci3120_reset() that does this. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 6f547ee0b4ce..3ebf5ecdbb5b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -437,8 +437,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - unsigned int i; - unsigned short us_TmpValue; devpriv->ai_running = 0; devpriv->b_EocEosInterrupt = APCI3120_DISABLE; @@ -463,11 +461,6 @@ static int apci3120_reset(struct comedi_device *dev) inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ - /* code to reset the RAM sequence */ - for (i = 0; i < 16; i++) { - us_TmpValue = i << 8; /* select the location */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); - } return 0; } -- GitLab From 9d5b070876ccd1f06121fa7ba5292c35a494ce24 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:09 -0700 Subject: [PATCH 3754/9457] staging: comedi: addi_apci_3120: tidy up scan chanlist programming Define the chanlist register and its bits and tidy up the programming of the scan chanlist. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 38 ++++++------------- .../staging/comedi/drivers/addi_apci_3120.c | 5 +++ 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3ebf5ecdbb5b..dd7805b7a3e4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -71,11 +71,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY /* for transfer count enable bit */ #define AGCSTS_TC_ENABLE 0x10000000 -/* used for test on mixture of BIP/UNI ranges */ -#define APCI3120_BIPOLAR_RANGES 4 - -#define APCI3120_ADDRESS_RANGE 16 - #define APCI3120_DISABLE 0 #define APCI3120_ENABLE 1 @@ -89,14 +84,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 -/* ANALOG OUTPUT AND INPUT DEFINE */ -#define APCI3120_UNIPOLAR 0x80 -#define APCI3120_BIPOLAR 0x00 -#define APCI3120_1_GAIN 0x00 -#define APCI3120_2_GAIN 0x10 -#define APCI3120_5_GAIN 0x20 -#define APCI3120_10_GAIN 0x30 -#define APCI3120_SEQ_RAM_ADDRESS 0x06 #define APCI3120_RESET_FIFO 0x0c /* nWrMode_Select */ @@ -214,9 +201,7 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, char check) { struct apci3120_private *devpriv = dev->private; - unsigned int i; - unsigned int gain; - unsigned short us_TmpValue; + int i; /* correct channel and range number check itself comedi/range.c */ if (n_chan < 1) { @@ -233,19 +218,20 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + /* set chanlist for scan */ for (i = 0; i < n_chan; i++) { - /* store range list to card */ - us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number */ + unsigned int chan = CR_CHAN(chanlist[i]); + unsigned int range = CR_RANGE(chanlist[i]); + unsigned int val; - if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) - us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ - else - us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar */ + val = APCI3120_CHANLIST_MUX(chan) | + APCI3120_CHANLIST_GAIN(range) | + APCI3120_CHANLIST_INDEX(i); + + if (comedi_range_is_unipolar(s, range)) + val |= APCI3120_CHANLIST_UNIPOLAR; - gain = CR_RANGE(chanlist[i]); /* get gain number */ - us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ - us_TmpValue |= i << 8; /* To select the RAM LOCATION */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + outw(val, dev->iobase + APCI3120_CHANLIST_REG); } return 1; /* we can serve this with scan logic */ } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ce94f907d9ef..45add7603d1b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -22,6 +22,11 @@ #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) #define APCI3120_TIMER_REG 0x04 +#define APCI3120_CHANLIST_REG 0x06 +#define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8) +#define APCI3120_CHANLIST_UNIPOLAR (1 << 7) +#define APCI3120_CHANLIST_GAIN(x) (((x) & 0x3) << 4) +#define APCI3120_CHANLIST_MUX(x) (((x) & 0xf) << 0) #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2)) #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14) #define APCI3120_AO_DATA(x) ((x) << 0) -- GitLab From ea0bb9d221d14b622dedeaa10bd5f6ac525e6efd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:10 -0700 Subject: [PATCH 3755/9457] staging: comedi: addi_apci_3120: remove 'check' param from apci3120_setup_chan_list() This parameter is always passed as '0'. Remove it and refactor the code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index dd7805b7a3e4..44a3fcd19b7f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -188,31 +188,18 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, return insn->n; } -/* - * This function will first check channel list is ok or not and then - * initialize the sequence RAM with the polarity, Gain,Channel number. - * If the last argument of function "check"is 1 then it only checks - * the channel list is ok or not. - */ static int apci3120_setup_chan_list(struct comedi_device *dev, struct comedi_subdevice *s, - int n_chan, - unsigned int *chanlist, - char check) + int n_chan, unsigned int *chanlist) { struct apci3120_private *devpriv = dev->private; int i; /* correct channel and range number check itself comedi/range.c */ if (n_chan < 1) { - if (!check) - dev_err(dev->class_dev, - "range/channel list is empty!\n"); + dev_err(dev->class_dev, "range/channel list is empty!\n"); return 0; } - /* All is ok, so we can setup channel/range list */ - if (check) - return 1; /* set scan length (PR) and scan start (PA) */ devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); @@ -282,7 +269,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Initialize the sequence array */ if (!apci3120_setup_chan_list(dev, s, 1, - &insn->chanspec, 0)) + &insn->chanspec)) return -EINVAL; /* Initialize Timer 0 mode 4 */ @@ -347,7 +334,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, - devpriv->ui_AiChannelList, 0)) + devpriv->ui_AiChannelList)) return -EINVAL; /* Initialize Timer 0 mode 2 */ @@ -594,7 +581,7 @@ static int apci3120_cyclic_ai(int mode, /* Initializes the sequence array */ if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, - cmd->chanlist, 0)) + cmd->chanlist)) return -EINVAL; divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); -- GitLab From d0bb66aa082c23741e85df459f7444f86cd86792 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:11 -0700 Subject: [PATCH 3756/9457] staging: comedi: addi_apci_3120: introduce apci3120_ai_reset_fifo() A dummy read of APCI3120_TIMER_MODE_REG resets the analog input FIFO. Introduce a helper function to clarify this. It's not necessary to do a dummy read of the FIFO (base + 0) before reseting it. Remove the unnecessary dummy reads. The APCI3120_TIMER_MODE_REG is a 16-bit register. This fixes a couple 8-bit reads. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 30 +++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 6 ++++ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 44a3fcd19b7f..0673e4fbc9b1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -84,8 +84,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 -#define APCI3120_RESET_FIFO 0x0c - /* nWrMode_Select */ #define APCI3120_ENABLE_SCAN 0x8 #define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) @@ -261,11 +259,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, switch (us_TmpValue) { case APCI3120_EOC_MODE: - - /* - * Testing the interrupt flag and set the EOC bit Clears the FIFO - */ - inw(dev->iobase + APCI3120_RESET_FIFO); + apci3120_ai_reset_fifo(dev); /* Initialize the sequence array */ if (!apci3120_setup_chan_list(dev, s, 1, @@ -321,16 +315,13 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, us_TmpValue = inw(dev->iobase + 0); *data = us_TmpValue; - inw(dev->iobase + APCI3120_RESET_FIFO); + apci3120_ai_reset_fifo(dev); } break; case APCI3120_EOS_MODE: - - inw(dev->iobase + 0); - /* Clears the FIFO */ - inw(dev->iobase + APCI3120_RESET_FIFO); + apci3120_ai_reset_fifo(dev); if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, @@ -430,8 +421,7 @@ static int apci3120_reset(struct comedi_device *dev) devpriv->ctrl = 0; outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); - inw(dev->iobase + 0); /* make a dummy read */ - inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ + apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ return 0; @@ -461,8 +451,8 @@ static int apci3120_cancel(struct comedi_device *dev, /* DISABLE_ALL_INTERRUPT */ outb(APCI3120_DISABLE_ALL_INTERRUPT, dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* Flush FIFO */ - inb(dev->iobase + APCI3120_RESET_FIFO); + + apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_RD_STATUS); devpriv->ui_DmaActualBuffer = 0; @@ -559,9 +549,6 @@ static int apci3120_cyclic_ai(int mode, unsigned int dmalen1 = 0; unsigned int divisor0; - /* Resets the FIFO */ - inb(dev->iobase + APCI3120_RESET_FIFO); - devpriv->ai_running = 1; /* clear software registers */ @@ -572,10 +559,7 @@ static int apci3120_cyclic_ai(int mode, outl(APCI3120_CLEAR_WRITE_TC_INT, devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - /* Resets the FIFO */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - inb(dev->iobase + APCI3120_RESET_FIFO); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + apci3120_ai_reset_fifo(dev); devpriv->ui_DmaActualBuffer = 0; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 45add7603d1b..8dfee45a0576 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -242,6 +242,12 @@ static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } +static void apci3120_ai_reset_fifo(struct comedi_device *dev) +{ + /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */ + inw(dev->iobase + APCI3120_TIMER_MODE_REG); +} + #include "addi-data/hwdrv_apci3120.c" static void apci3120_dma_alloc(struct comedi_device *dev) -- GitLab From 6ef680325566e817b12898a43471f318eba41ca0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:12 -0700 Subject: [PATCH 3757/9457] staging: comedi: addi_apci_3120: move ai range table to driver source Move the analog input comedi_lrange table from the included hwdrv_apci3120.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 14 -------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0673e4fbc9b1..cb2856da34fb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -125,20 +125,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER2_SELECT_EOS 0xc0 #define APCI3120_COUNTER 3 -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3120_ai = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - static int apci3120_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 8dfee45a0576..6c7f452a2dae 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -53,6 +53,19 @@ #define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */ #define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */ +static const struct comedi_lrange apci3120_ai_range = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + enum apci3120_boardid { BOARD_APCI3120, BOARD_APCI3001, @@ -355,7 +368,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; s->n_chan = 16; s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; - s->range_table = &range_apci3120_ai; + s->range_table = &apci3120_ai_range; s->insn_config = apci3120_ai_insn_config; s->insn_read = apci3120_ai_insn_read; if (0 /* dev->irq */) { -- GitLab From f85c54dbe557257b4c9f1f53f80b555378008f1f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:13 -0700 Subject: [PATCH 3758/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER At the start of apci3120_ai_insn_read() the devpriv->b_ModeSelectRegister is set to '0'. Remove the unnecessary masking to clear the interrupt enable bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index cb2856da34fb..2dd8e665d471 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -92,8 +92,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) #define APCI3120_ENABLE_EOC_INT 0x1 #define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER \ - (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) #define APCI3120_DISABLE_ALL_INTERRUPT \ (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) @@ -270,11 +268,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, APCI3120_ENABLE_EOC_INT; inw(dev->iobase + 0); - } else { - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER; } outb(devpriv->b_ModeSelectRegister, @@ -337,11 +330,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, APCI3120_ENABLE_EOS_INT; inw(dev->iobase + 0); - } else - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER; + } outb(devpriv->b_ModeSelectRegister, dev->iobase + APCI3120_WRITE_MODE_SELECT); -- GitLab From b2cf40a31df207dacc298bc6c559b24e28a896e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:14 -0700 Subject: [PATCH 3759/9457] staging: comedi: addi_apci_3120: properly disable interrupts in apci3120_cancel() The APCI3120_DISABLE_ALL_INTERRUPT define is a mask value used to clear bits in devpriv->b_ModeSelectRegister to disable the interrupt sources. Writing this value directly sets unintended bits. Just set the devpriv->b_ModeSelectRegister to '0' and write that to the register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 2dd8e665d471..84aff802ae18 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -92,8 +92,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) #define APCI3120_ENABLE_EOC_INT 0x1 #define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT \ - (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) /* status register bits */ #define APCI3120_EOC 0x8000 @@ -424,8 +422,9 @@ static int apci3120_cancel(struct comedi_device *dev, outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); /* DISABLE_ALL_INTERRUPT */ - outb(APCI3120_DISABLE_ALL_INTERRUPT, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->b_ModeSelectRegister = 0; + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_RD_STATUS); -- GitLab From 627e83a7e0f5d0141cbc726ec062d2804a6e12a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:15 -0700 Subject: [PATCH 3760/9457] staging: comedi: addi_apci_3120: rename private data 'b_ModeSelectRegister' Rename this CamelCase member of the private data and tidy up the mask/set of its bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 198 ++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 62 insertions(+), 138 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 84aff802ae18..fcb92e801c8a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -226,7 +226,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Clear software registers */ devpriv->timer_mode = 0; - devpriv->b_ModeSelectRegister = 0; + devpriv->mode = 0; if (insn->unused[0] == 222) { /* second insn read */ for (i = 0; i < insn->n; i++) @@ -252,23 +252,17 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_SCAN; + devpriv->mode &= APCI3120_DISABLE_SCAN; if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* Disables the EOS,DMA and enables the EOC interrupt */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_EOS_INT) | - APCI3120_ENABLE_EOC_INT; + devpriv->mode &= APCI3120_DISABLE_EOS_INT; + devpriv->mode |= APCI3120_ENABLE_EOC_INT; inw(dev->iobase + 0); - } - outb(devpriv->b_ModeSelectRegister, + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_timer_enable(dev, 0, true); @@ -312,25 +306,20 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, apci3120_timer_write(dev, 0, divisor); /* Set the scan bit */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | APCI3120_ENABLE_SCAN; - outb(devpriv->b_ModeSelectRegister, + devpriv->mode |= APCI3120_ENABLE_SCAN; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* If Interrupt function is loaded */ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* Disables the EOC,DMA and enables the EOS interrupt */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_EOC_INT) | - APCI3120_ENABLE_EOS_INT; + devpriv->mode &= APCI3120_DISABLE_EOC_INT; + devpriv->mode |= APCI3120_ENABLE_EOS_INT; inw(dev->iobase + 0); } - outb(devpriv->b_ModeSelectRegister, + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); inw(dev->iobase + APCI3120_RD_STATUS); @@ -386,9 +375,8 @@ static int apci3120_reset(struct comedi_device *dev) devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ /* Disable all interrupts, watchdog for the anolog output */ - devpriv->b_ModeSelectRegister = 0; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode = 0; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; @@ -422,9 +410,8 @@ static int apci3120_cancel(struct comedi_device *dev, outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); /* DISABLE_ALL_INTERRUPT */ - devpriv->b_ModeSelectRegister = 0; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode = 0; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_RD_STATUS); @@ -527,7 +514,7 @@ static int apci3120_cyclic_ai(int mode, /* clear software registers */ devpriv->timer_mode = 0; - devpriv->b_ModeSelectRegister = 0; + devpriv->mode = 0; /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, @@ -575,14 +562,10 @@ static int apci3120_cyclic_ai(int mode, break; } - /* common for all modes */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & - APCI3120_DISABLE_SCAN; - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + /* common for all modes */ + devpriv->mode &= APCI3120_DISABLE_SCAN; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* If DMA is disabled */ if (devpriv->us_UseDma == APCI3120_DISABLE) { @@ -590,23 +573,17 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_InterruptMode = APCI3120_EOS_MODE; devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | - APCI3120_ENABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_EOC_INT; + devpriv->mode |= APCI3120_ENABLE_EOS_INT; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (cmd->stop_src == TRIG_COUNT) { /* configure Timer2 For counting EOS */ /* DISABLE TIMER intERRUPT */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT & 0xEF; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_TIMER_INT & 0xef; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); /* (1) Init timer 2 in mode 0 and write timer value */ apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0); @@ -617,23 +594,14 @@ static int apci3120_cyclic_ai(int mode, apci3120_clr_timer2_interrupt(dev); /* enable timer counter and disable watch dog */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_COUNTER) & - APCI3120_DISABLE_WATCHDOG; + devpriv->mode &= APCI3120_DISABLE_WATCHDOG; + devpriv->mode |= APCI3120_ENABLE_TIMER_COUNTER; /* select EOS clock input for timer 2 */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_TIMER2_SELECT_EOS; + devpriv->mode |= APCI3120_TIMER2_SELECT_EOS; /* Enable timer2 interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode |= APCI3120_ENABLE_TIMER_INT; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = APCI3120_ENABLE; } @@ -648,11 +616,9 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_InterruptMode = APCI3120_DMA_MODE; /* Disables the EOC, EOS interrupt */ - devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & - APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_EOC_INT & + APCI3120_DISABLE_EOS_INT; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); dmalen0 = dmabuf0->size; dmalen1 = dmabuf1->size; @@ -1028,10 +994,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ } else { /* Disable EOC Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT; - outb(devpriv->b_ModeSelectRegister, + devpriv->mode &= APCI3120_DISABLE_EOC_INT; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } } @@ -1044,13 +1008,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (devpriv->ai_running) { ui_Check = 0; apci3120_interrupt_handle_eos(dev); - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + - APCI3120_WRITE_MODE_SELECT); + devpriv->mode |= APCI3120_ENABLE_EOS_INT; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); } else { ui_Check = 0; for (i = 0; i < devpriv->ui_AiNbrofChannels; @@ -1067,11 +1027,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } } else { - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_EOS_INT; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ devpriv->b_InterruptMode = APCI3120_EOC_MODE; } @@ -1082,11 +1040,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_EOS_INT; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); s->async->events |= COMEDI_CB_EOA; break; @@ -1106,14 +1062,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) default: /* disable Timer Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT; - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - + devpriv->mode &= APCI3120_DISABLE_TIMER_INT; + outb(devpriv->mode, + dev->iobase + APCI3120_WRITE_MODE_SELECT); } apci3120_clr_timer2_interrupt(dev); @@ -1167,17 +1118,12 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); /* Disable TIMER Interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF; + devpriv->mode &= APCI3120_DISABLE_TIMER_INT & 0xef; /* Disable Eoc and Eos Interrupts */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT & - APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE2); @@ -1243,34 +1189,23 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* Enable Timer */ - devpriv->b_ModeSelectRegister = - devpriv->b_ModeSelectRegister & 0x0B; + devpriv->mode &= 0x0b; } else { /* start watch dog */ /* Enable WatchDog */ - devpriv->b_ModeSelectRegister = - (devpriv-> - b_ModeSelectRegister & 0x0B) | - APCI3120_ENABLE_WATCHDOG; + devpriv->mode &= 0x0b; + devpriv->mode |= APCI3120_ENABLE_WATCHDOG; } /* enable disable interrupt */ if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) { + devpriv->mode |= APCI3120_ENABLE_TIMER_INT; - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister | - APCI3120_ENABLE_TIMER_INT; /* save the task structure to pass info to user */ devpriv->tsk_Current = current; } else { - - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT; + devpriv->mode &= APCI3120_DISABLE_TIMER_INT; } - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* start timer */ if (devpriv->b_Timer2Mode == APCI3120_TIMER) @@ -1280,25 +1215,14 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, case APCI3120_STOP: if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* Disable timer */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_COUNTER; + devpriv->mode &= APCI3120_DISABLE_TIMER_COUNTER; } else { /* Disable WatchDog */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_WATCHDOG; + devpriv->mode &= APCI3120_DISABLE_WATCHDOG; } /* Disable timer interrupt */ - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT; - - /* Write above states to register */ - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->mode &= APCI3120_DISABLE_TIMER_INT; + outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_timer_enable(dev, 2, false); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6c7f452a2dae..e1c0535adb4b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -108,7 +108,7 @@ struct apci3120_private { struct apci3120_dmabuf dmabuf[2]; unsigned char do_bits; unsigned char timer_mode; - unsigned char b_ModeSelectRegister; + unsigned char mode; unsigned short ctrl; unsigned char b_Timer2Mode; unsigned char b_Timer2Interrupt; -- GitLab From 363aa5f2f47ec32d9ddc40db7312bf907b957bae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:16 -0700 Subject: [PATCH 3761/9457] staging: comedi: addi_apci_3120: remove unnecessary devpriv->mode masking The devpriv->mode is set to '0' at the start of apci3120_ai_insn_read() and apci3120_cyclic_ai(). There is no need to clear any of the bits or do any of the additional writes of those cleared bits. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index fcb92e801c8a..c58d4a6a0241 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -251,13 +251,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Initialize Timer 0 mode 4 */ apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); - /* Reset the scan bit and Disables the EOS, DMA, EOC interrupt */ - devpriv->mode &= APCI3120_DISABLE_SCAN; - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - - /* Disables the EOS,DMA and enables the EOC interrupt */ - devpriv->mode &= APCI3120_DISABLE_EOS_INT; devpriv->mode |= APCI3120_ENABLE_EOC_INT; inw(dev->iobase + 0); } @@ -312,11 +306,8 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* If Interrupt function is loaded */ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - /* Disables the EOC,DMA and enables the EOS interrupt */ - devpriv->mode &= APCI3120_DISABLE_EOC_INT; devpriv->mode |= APCI3120_ENABLE_EOS_INT; inw(dev->iobase + 0); - } outb(devpriv->mode, @@ -563,8 +554,6 @@ static int apci3120_cyclic_ai(int mode, } - /* common for all modes */ - devpriv->mode &= APCI3120_DISABLE_SCAN; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* If DMA is disabled */ @@ -573,18 +562,12 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_InterruptMode = APCI3120_EOS_MODE; devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - devpriv->mode &= APCI3120_DISABLE_EOC_INT; devpriv->mode |= APCI3120_ENABLE_EOS_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (cmd->stop_src == TRIG_COUNT) { /* configure Timer2 For counting EOS */ - /* DISABLE TIMER intERRUPT */ - devpriv->mode &= APCI3120_DISABLE_TIMER_INT & 0xef; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - /* (1) Init timer 2 in mode 0 and write timer value */ apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0); @@ -594,7 +577,6 @@ static int apci3120_cyclic_ai(int mode, apci3120_clr_timer2_interrupt(dev); /* enable timer counter and disable watch dog */ - devpriv->mode &= APCI3120_DISABLE_WATCHDOG; devpriv->mode |= APCI3120_ENABLE_TIMER_COUNTER; /* select EOS clock input for timer 2 */ devpriv->mode |= APCI3120_TIMER2_SELECT_EOS; @@ -615,11 +597,6 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_InterruptMode = APCI3120_DMA_MODE; - /* Disables the EOC, EOS interrupt */ - devpriv->mode &= APCI3120_DISABLE_EOC_INT & - APCI3120_DISABLE_EOS_INT; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); - dmalen0 = dmabuf0->size; dmalen1 = dmabuf1->size; -- GitLab From 81ff03ba1979b5881d2a29effcd46a81fa554340 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:17 -0700 Subject: [PATCH 3762/9457] staging: comedi: addi_apci_3120: remove devpriv->mode '0xef' magic value This mask value is the same as APCI3120_DISABLE_TIMER_COUNTER. Use that instead and remove the "magic" value. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c58d4a6a0241..f351b50083f3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1095,7 +1095,8 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); /* Disable TIMER Interrupt */ - devpriv->mode &= APCI3120_DISABLE_TIMER_INT & 0xef; + devpriv->mode &= APCI3120_DISABLE_TIMER_INT & + APCI3120_DISABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ devpriv->mode &= APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; -- GitLab From b835aac0bdcf3b9aa76c173eff7af3cb1f45e719 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:18 -0700 Subject: [PATCH 3763/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_TIMER_COUNTER For aesthetics, remove this define and just use ~APCI3120_ENABLE_TIMER_COUNTER. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f351b50083f3..3eb53f1cea90 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -115,7 +115,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_ENABLE_WATCHDOG 0x20 #define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) #define APCI3120_ENABLE_TIMER_COUNTER 0x10 -#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) #define APCI3120_FC_TIMER 0x1000 #define APCI3120_TIMER2_SELECT_EOS 0xc0 @@ -1096,7 +1095,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, /* Disable TIMER Interrupt */ devpriv->mode &= APCI3120_DISABLE_TIMER_INT & - APCI3120_DISABLE_TIMER_COUNTER; + ~APCI3120_ENABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ devpriv->mode &= APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; @@ -1193,7 +1192,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, case APCI3120_STOP: if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* Disable timer */ - devpriv->mode &= APCI3120_DISABLE_TIMER_COUNTER; + devpriv->mode &= ~APCI3120_ENABLE_TIMER_COUNTER; } else { /* Disable WatchDog */ devpriv->mode &= APCI3120_DISABLE_WATCHDOG; -- GitLab From b6eb21d6df0dbb190fb7f96a66abc902ae51ee52 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:19 -0700 Subject: [PATCH 3764/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_WATCHDOG For aesthetics, remove this define and just use ~APCI3120_ENABLE_WATCHDOG. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3eb53f1cea90..f6812eab1d15 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -113,7 +113,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_ENABLE_WATCHDOG 0x20 -#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) #define APCI3120_ENABLE_TIMER_COUNTER 0x10 #define APCI3120_FC_TIMER 0x1000 @@ -1195,7 +1194,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, devpriv->mode &= ~APCI3120_ENABLE_TIMER_COUNTER; } else { /* Disable WatchDog */ - devpriv->mode &= APCI3120_DISABLE_WATCHDOG; + devpriv->mode &= ~APCI3120_ENABLE_WATCHDOG; } /* Disable timer interrupt */ devpriv->mode &= APCI3120_DISABLE_TIMER_INT; -- GitLab From 604f8e10b516a85124ef86fb7c25aa997c3092d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:20 -0700 Subject: [PATCH 3765/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_TIMER_INT For aesthetics, remove this define and just use ~APCI3120_ENABLE_TIMER_INT. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f6812eab1d15..31920b6876b5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -108,7 +108,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 #define APCI3120_ENABLE_TIMER_INT 0x04 -#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) #define APCI3120_WRITE_MODE_SELECT 0x0e #define APCI3120_RD_STATUS 0x02 @@ -1037,7 +1036,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) default: /* disable Timer Interrupt */ - devpriv->mode &= APCI3120_DISABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } @@ -1093,7 +1092,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); /* Disable TIMER Interrupt */ - devpriv->mode &= APCI3120_DISABLE_TIMER_INT & + devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT & ~APCI3120_ENABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ @@ -1179,7 +1178,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, /* save the task structure to pass info to user */ devpriv->tsk_Current = current; } else { - devpriv->mode &= APCI3120_DISABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; } outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); @@ -1197,7 +1196,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, devpriv->mode &= ~APCI3120_ENABLE_WATCHDOG; } /* Disable timer interrupt */ - devpriv->mode &= APCI3120_DISABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_timer_enable(dev, 2, false); -- GitLab From 1084dce74f1f69ce1b7a8715eb246d878b3a7448 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:21 -0700 Subject: [PATCH 3766/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_EOC_INT For aesthetics, remove this define and just use ~APCI3120_ENABLE_EOC_INT. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 31920b6876b5..545bc90234d5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -91,7 +91,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) #define APCI3120_ENABLE_EOC_INT 0x1 -#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) /* status register bits */ #define APCI3120_EOC 0x8000 @@ -968,7 +967,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ } else { /* Disable EOC Interrupt */ - devpriv->mode &= APCI3120_DISABLE_EOC_INT; + devpriv->mode &= ~APCI3120_ENABLE_EOC_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } @@ -1096,7 +1095,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, ~APCI3120_ENABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ - devpriv->mode &= APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; + devpriv->mode &= ~APCI3120_ENABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ -- GitLab From 7a945f984d88ff4a7ea33d34ed1773fcbb176699 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:22 -0700 Subject: [PATCH 3767/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_EOS_INT For aesthetics, remove this define and just use ~APCI3120_ENABLE_EOS_INT. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 545bc90234d5..a71b70f71688 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -89,7 +89,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) #define APCI3120_ENABLE_EOS_INT 0x2 -#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) #define APCI3120_ENABLE_EOC_INT 0x1 /* status register bits */ @@ -1000,7 +999,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } } else { - devpriv->mode &= APCI3120_DISABLE_EOS_INT; + devpriv->mode &= ~APCI3120_ENABLE_EOS_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ @@ -1013,7 +1012,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: - devpriv->mode &= APCI3120_DISABLE_EOS_INT; + devpriv->mode &= ~APCI3120_ENABLE_EOS_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); @@ -1095,7 +1094,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, ~APCI3120_ENABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ - devpriv->mode &= ~APCI3120_ENABLE_EOC_INT & APCI3120_DISABLE_EOS_INT; + devpriv->mode &= ~APCI3120_ENABLE_EOC_INT & ~APCI3120_ENABLE_EOS_INT; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ -- GitLab From 67d3a2e715d4a89898f6f4763eb285b7ae9fea26 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:23 -0700 Subject: [PATCH 3768/9457] staging: comedi: addi_apci_3120: remove APCI3120_DISABLE_SCAN This define is not used in the driver. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a71b70f71688..d2d0ef4efd66 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -86,7 +86,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY /* nWrMode_Select */ #define APCI3120_ENABLE_SCAN 0x8 -#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) #define APCI3120_ENABLE_EOS_INT 0x2 #define APCI3120_ENABLE_EOC_INT 0x1 -- GitLab From 1869ae026ca030340c954f6de91d05774101a103 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:24 -0700 Subject: [PATCH 3769/9457] staging: comedi: addi_apci_3120: define the "enable" bits in the mode register For aesthetics, redefine the bits in the mode register that enable interrupts and scanning. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 38 ++++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 4 ++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d2d0ef4efd66..03ebe971f823 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -84,12 +84,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 -/* nWrMode_Select */ -#define APCI3120_ENABLE_SCAN 0x8 -#define APCI3120_ENABLE_EOS_INT 0x2 - -#define APCI3120_ENABLE_EOC_INT 0x1 - /* status register bits */ #define APCI3120_EOC 0x8000 #define APCI3120_EOS 0x2000 @@ -104,7 +98,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_WATCHDOG 2 #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 -#define APCI3120_ENABLE_TIMER_INT 0x04 #define APCI3120_WRITE_MODE_SELECT 0x0e #define APCI3120_RD_STATUS 0x02 @@ -246,7 +239,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - devpriv->mode |= APCI3120_ENABLE_EOC_INT; + devpriv->mode |= APCI3120_MODE_EOC_IRQ_ENA; inw(dev->iobase + 0); } @@ -294,13 +287,13 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, apci3120_timer_write(dev, 0, divisor); /* Set the scan bit */ - devpriv->mode |= APCI3120_ENABLE_SCAN; + devpriv->mode |= APCI3120_MODE_SCAN_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); /* If Interrupt function is loaded */ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - devpriv->mode |= APCI3120_ENABLE_EOS_INT; + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; inw(dev->iobase + 0); } @@ -556,7 +549,7 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_InterruptMode = APCI3120_EOS_MODE; devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - devpriv->mode |= APCI3120_ENABLE_EOS_INT; + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (cmd->stop_src == TRIG_COUNT) { @@ -575,7 +568,7 @@ static int apci3120_cyclic_ai(int mode, /* select EOS clock input for timer 2 */ devpriv->mode |= APCI3120_TIMER2_SELECT_EOS; /* Enable timer2 interrupt */ - devpriv->mode |= APCI3120_ENABLE_TIMER_INT; + devpriv->mode |= APCI3120_MODE_TIMER2_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); devpriv->b_Timer2Mode = APCI3120_COUNTER; @@ -965,7 +958,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ } else { /* Disable EOC Interrupt */ - devpriv->mode &= ~APCI3120_ENABLE_EOC_INT; + devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } @@ -979,7 +972,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (devpriv->ai_running) { ui_Check = 0; apci3120_interrupt_handle_eos(dev); - devpriv->mode |= APCI3120_ENABLE_EOS_INT; + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } else { @@ -998,7 +991,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } } else { - devpriv->mode &= ~APCI3120_ENABLE_EOS_INT; + devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ @@ -1011,7 +1004,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: - devpriv->mode &= ~APCI3120_ENABLE_EOS_INT; + devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); @@ -1033,7 +1026,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) default: /* disable Timer Interrupt */ - devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); } @@ -1089,11 +1082,12 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); /* Disable TIMER Interrupt */ - devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT & + devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & ~APCI3120_ENABLE_TIMER_COUNTER; /* Disable Eoc and Eos Interrupts */ - devpriv->mode &= ~APCI3120_ENABLE_EOC_INT & ~APCI3120_ENABLE_EOS_INT; + devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA & + ~APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); if (data[0] == APCI3120_TIMER) { /* initialize timer */ @@ -1170,12 +1164,12 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, /* enable disable interrupt */ if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) { - devpriv->mode |= APCI3120_ENABLE_TIMER_INT; + devpriv->mode |= APCI3120_MODE_TIMER2_IRQ_ENA; /* save the task structure to pass info to user */ devpriv->tsk_Current = current; } else { - devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; } outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); @@ -1193,7 +1187,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, devpriv->mode &= ~APCI3120_ENABLE_WATCHDOG; } /* Disable timer interrupt */ - devpriv->mode &= ~APCI3120_ENABLE_TIMER_INT; + devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_timer_enable(dev, 2, false); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e1c0535adb4b..603bebb7e059 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,6 +40,10 @@ #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) +#define APCI3120_MODE_SCAN_ENA (1 << 3) +#define APCI3120_MODE_TIMER2_IRQ_ENA (1 << 2) +#define APCI3120_MODE_EOS_IRQ_ENA (1 << 1) +#define APCI3120_MODE_EOC_IRQ_ENA (1 << 0) /* * PCI BAR 2 register map (devpriv->addon) -- GitLab From 7cbc057d85b7da51ca610381a3de77fbafc51311 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:25 -0700 Subject: [PATCH 3770/9457] staging: comedi: addi_apci_3120: define the timer 2 operation bits For aesthetics, redefine the bits in the mode register used to set the operation mode of timer 2. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 23 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 4 ++++ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 03ebe971f823..87c82e4b76f5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -101,8 +101,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_WRITE_MODE_SELECT 0x0e #define APCI3120_RD_STATUS 0x02 -#define APCI3120_ENABLE_WATCHDOG 0x20 -#define APCI3120_ENABLE_TIMER_COUNTER 0x10 #define APCI3120_FC_TIMER 0x1000 #define APCI3120_TIMER2_SELECT_EOS 0xc0 @@ -564,7 +562,7 @@ static int apci3120_cyclic_ai(int mode, apci3120_clr_timer2_interrupt(dev); /* enable timer counter and disable watch dog */ - devpriv->mode |= APCI3120_ENABLE_TIMER_COUNTER; + devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER; /* select EOS clock input for timer 2 */ devpriv->mode |= APCI3120_TIMER2_SELECT_EOS; /* Enable timer2 interrupt */ @@ -1081,9 +1079,9 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, apci3120_timer_enable(dev, 2, false); - /* Disable TIMER Interrupt */ + /* disable timer 2 interrupt and reset operation mode (timer) */ devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & - ~APCI3120_ENABLE_TIMER_COUNTER; + ~APCI3120_MODE_TIMER2_AS_MASK; /* Disable Eoc and Eos Interrupts */ devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA & @@ -1156,10 +1154,11 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ /* Enable Timer */ devpriv->mode &= 0x0b; + devpriv->mode |= APCI3120_MODE_TIMER2_AS_TIMER; } else { /* start watch dog */ /* Enable WatchDog */ devpriv->mode &= 0x0b; - devpriv->mode |= APCI3120_ENABLE_WATCHDOG; + devpriv->mode |= APCI3120_MODE_TIMER2_AS_WDOG; } /* enable disable interrupt */ @@ -1179,15 +1178,9 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, break; case APCI3120_STOP: - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { - /* Disable timer */ - devpriv->mode &= ~APCI3120_ENABLE_TIMER_COUNTER; - } else { - /* Disable WatchDog */ - devpriv->mode &= ~APCI3120_ENABLE_WATCHDOG; - } - /* Disable timer interrupt */ - devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; + /* disable timer 2 interrupt and reset operation mode (timer) */ + devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & + ~APCI3120_MODE_TIMER2_AS_MASK; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); apci3120_timer_enable(dev, 2, false); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 603bebb7e059..ed51f41cd761 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,6 +40,10 @@ #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) +#define APCI3120_MODE_TIMER2_AS_TIMER (0 << 4) +#define APCI3120_MODE_TIMER2_AS_COUNTER (1 << 4) +#define APCI3120_MODE_TIMER2_AS_WDOG (2 << 4) +#define APCI3120_MODE_TIMER2_AS_MASK (3 << 4) /* sets AS_TIMER */ #define APCI3120_MODE_SCAN_ENA (1 << 3) #define APCI3120_MODE_TIMER2_IRQ_ENA (1 << 2) #define APCI3120_MODE_EOS_IRQ_ENA (1 << 1) -- GitLab From bd8e69e2b7bc51d5b5c97d3940ea42b3f816fb6b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:26 -0700 Subject: [PATCH 3771/9457] staging: comedi: addi_apci_3120: define the timer 2 clock select bits For aesthetics, redefine the bits in the mode register used to select the clock for timer 2. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 11 ++++------- drivers/staging/comedi/drivers/addi_apci_3120.c | 5 +++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 87c82e4b76f5..c0ae6d31d0c9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -103,7 +103,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_STATUS 0x02 #define APCI3120_FC_TIMER 0x1000 -#define APCI3120_TIMER2_SELECT_EOS 0xc0 #define APCI3120_COUNTER 3 static int apci3120_ai_insn_config(struct comedi_device *dev, @@ -561,14 +560,12 @@ static int apci3120_cyclic_ai(int mode, apci3120_clr_timer2_interrupt(dev); - /* enable timer counter and disable watch dog */ - devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER; - /* select EOS clock input for timer 2 */ - devpriv->mode |= APCI3120_TIMER2_SELECT_EOS; - /* Enable timer2 interrupt */ - devpriv->mode |= APCI3120_MODE_TIMER2_IRQ_ENA; + devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER | + APCI3120_MODE_TIMER2_CLK_EOS | + APCI3120_MODE_TIMER2_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = APCI3120_ENABLE; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ed51f41cd761..10155e6b322f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,6 +40,11 @@ #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) +#define APCI3120_MODE_TIMER2_CLK_OSC (0 << 6) +#define APCI3120_MODE_TIMER2_CLK_OUT1 (1 << 6) +#define APCI3120_MODE_TIMER2_CLK_EOC (2 << 6) +#define APCI3120_MODE_TIMER2_CLK_EOS (3 << 6) +#define APCI3120_MODE_TIMER2_CLK_MASK (3 << 6) #define APCI3120_MODE_TIMER2_AS_TIMER (0 << 4) #define APCI3120_MODE_TIMER2_AS_COUNTER (1 << 4) #define APCI3120_MODE_TIMER2_AS_WDOG (2 << 4) -- GitLab From aae8f725aac45e01b4708c89a462312f684ae1f4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:27 -0700 Subject: [PATCH 3772/9457] staging: comedi: addi_apci_3120: rename APCI3120_WRITE_MODE_SELECT For aesthetics, rename this define used for the mode register offset. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 42 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c0ae6d31d0c9..0e76b656035d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -98,7 +98,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_WATCHDOG 2 #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 -#define APCI3120_WRITE_MODE_SELECT 0x0e #define APCI3120_RD_STATUS 0x02 #define APCI3120_FC_TIMER 0x1000 @@ -240,8 +239,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + 0); } - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); apci3120_timer_enable(dev, 0, true); @@ -285,8 +283,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Set the scan bit */ devpriv->mode |= APCI3120_MODE_SCAN_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* If Interrupt function is loaded */ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { @@ -294,8 +291,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, inw(dev->iobase + 0); } - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); inw(dev->iobase + APCI3120_RD_STATUS); @@ -351,7 +347,7 @@ static int apci3120_reset(struct comedi_device *dev) /* Disable all interrupts, watchdog for the anolog output */ devpriv->mode = 0; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* disable all counters, ext trigger, and reset scan */ devpriv->ctrl = 0; @@ -386,7 +382,7 @@ static int apci3120_cancel(struct comedi_device *dev, /* DISABLE_ALL_INTERRUPT */ devpriv->mode = 0; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_RD_STATUS); @@ -538,7 +534,7 @@ static int apci3120_cyclic_ai(int mode, } - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* If DMA is disabled */ if (devpriv->us_UseDma == APCI3120_DISABLE) { @@ -547,7 +543,7 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_EocEosInterrupt = APCI3120_ENABLE; devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); if (cmd->stop_src == TRIG_COUNT) { /* configure Timer2 For counting EOS */ @@ -563,8 +559,7 @@ static int apci3120_cyclic_ai(int mode, devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER | APCI3120_MODE_TIMER2_CLK_EOS | APCI3120_MODE_TIMER2_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = APCI3120_ENABLE; @@ -954,8 +949,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } else { /* Disable EOC Interrupt */ devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); } } @@ -969,7 +963,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) apci3120_interrupt_handle_eos(dev); devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + dev->iobase + APCI3120_MODE_REG); } else { ui_Check = 0; for (i = 0; i < devpriv->ui_AiNbrofChannels; @@ -987,8 +981,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } else { devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ devpriv->b_InterruptMode = APCI3120_EOC_MODE; } @@ -1000,8 +993,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); s->async->events |= COMEDI_CB_EOA; break; @@ -1019,11 +1011,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) break; default: - /* disable Timer Interrupt */ devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); } apci3120_clr_timer2_interrupt(dev); @@ -1083,7 +1073,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev, /* Disable Eoc and Eos Interrupts */ devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA & ~APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); if (data[0] == APCI3120_TIMER) { /* initialize timer */ /* Set the Timer 2 in mode 2(Timer) */ @@ -1167,7 +1157,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, } else { devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; } - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* start timer */ if (devpriv->b_Timer2Mode == APCI3120_TIMER) @@ -1178,7 +1168,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, /* disable timer 2 interrupt and reset operation mode (timer) */ devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & ~APCI3120_MODE_TIMER2_AS_MASK; - outb(devpriv->mode, dev->iobase + APCI3120_WRITE_MODE_SELECT); + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); apci3120_timer_enable(dev, 2, false); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 10155e6b322f..0f3dabfabfc8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,6 +40,7 @@ #define APCI3120_CTR0_REG 0x0d #define APCI3120_CTR0_DO_BITS(x) ((x) << 4) #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0) +#define APCI3120_MODE_REG 0x0e #define APCI3120_MODE_TIMER2_CLK_OSC (0 << 6) #define APCI3120_MODE_TIMER2_CLK_OUT1 (1 << 6) #define APCI3120_MODE_TIMER2_CLK_EOC (2 << 6) -- GitLab From 34c0ae09a69173a5f831ad66cb2edf1fdb42205a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:28 -0700 Subject: [PATCH 3773/9457] staging: comedi: addi_apci_3120: remove scanning from ai (*insn_read) (*insn_read) functions are supposed to do simple polled reads of a single channel. This driver tries to be tricky and allow passing a chanlist in the analog input (*insn_config) to allow the (*insn_read) to do chanlist scanning with or without interrupts. The (*insn_config) doesn't follow the comedi API and this operation mode is not part of the API. Remove the scanning support from the (*insn_read) as well as the support code in the (*insn_config) and interrupt handler. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 113 ++---------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0e76b656035d..2656e53999f8 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -110,43 +110,18 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned int i; - if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE)) + if (data[0] != APCI3120_EOC_MODE) return -1; /* Check for Conversion time to be added */ devpriv->ui_EocEosConversionTime = data[2]; - if (data[0] == APCI3120_EOS_MODE) { - - /* Test the number of the channel */ - for (i = 0; i < data[3]; i++) { - - if (CR_CHAN(data[4 + i]) >= s->n_chan) { - dev_err(dev->class_dev, "bad channel list\n"); - return -2; - } - } - - devpriv->b_InterruptMode = APCI3120_EOS_MODE; - - if (data[1]) - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - else - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - /* Copy channel list and Range List to devpriv */ - devpriv->ui_AiNbrofChannels = data[3]; - for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) - devpriv->ui_AiChannelList[i] = data[4 + i]; - - } else { /* EOC */ - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - if (data[1]) - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - else - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - } + devpriv->b_InterruptMode = APCI3120_EOC_MODE; + if (data[1]) + devpriv->b_EocEosInterrupt = APCI3120_ENABLE; + else + devpriv->b_EocEosInterrupt = APCI3120_DISABLE; return insn->n; } @@ -186,11 +161,6 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, return 1; /* we can serve this with scan logic */ } -/* - * Reads analog input in synchronous mode EOC and EOS is selected - * as per configured if no conversion time is set uses default - * conversion time 10 microsec. - */ static int apci3120_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -266,60 +236,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, } break; - - case APCI3120_EOS_MODE: - apci3120_ai_reset_fifo(dev); - - if (!apci3120_setup_chan_list(dev, s, - devpriv->ui_AiNbrofChannels, - devpriv->ui_AiChannelList)) - return -EINVAL; - - /* Initialize Timer 0 mode 2 */ - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); - - /* Set the conversion time */ - apci3120_timer_write(dev, 0, divisor); - - /* Set the scan bit */ - devpriv->mode |= APCI3120_MODE_SCAN_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - /* If Interrupt function is loaded */ - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - inw(dev->iobase + 0); - } - - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - inw(dev->iobase + APCI3120_RD_STATUS); - - apci3120_timer_enable(dev, 0, true); - - /* Start conversion */ - outw(0, dev->iobase + APCI3120_START_CONVERSION); - - /* Waiting of end of conversion if interrupt is not installed */ - if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { - /* Waiting the end of conversion */ - do { - us_TmpValue = inw(dev->iobase + - APCI3120_RD_STATUS); - } while ((us_TmpValue & APCI3120_EOS) != - APCI3120_EOS); - - for (i = 0; i < devpriv->ui_AiNbrofChannels; - i++) { - /* Read the result in FIFO and write them in shared memory */ - us_TmpValue = inw(dev->iobase); - data[i] = (unsigned int) us_TmpValue; - } - - devpriv->b_InterruptMode = APCI3120_EOC_MODE; /* Restore defaults */ - } - break; - default: dev_err(dev->class_dev, "inputs wrong\n"); @@ -908,8 +824,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned short int_daq; - unsigned int int_amcc, ui_Check, i; - unsigned short us_TmpValue; + unsigned int int_amcc, ui_Check; ui_Check = 1; @@ -964,21 +879,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - } else { - ui_Check = 0; - for (i = 0; i < devpriv->ui_AiNbrofChannels; - i++) { - us_TmpValue = inw(dev->iobase + 0); - devpriv->ui_AiReadData[i] = - (unsigned int) us_TmpValue; - } - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } - } else { devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); -- GitLab From 46ad4793a7c8ae2c347f86427a82c1f04bc80fc6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:29 -0700 Subject: [PATCH 3774/9457] staging: comedi: addi_apci_3120: remove private data 'ui_EocEosConversionTime' This driver tries to be tricky and allow passing an analog input conversion time for the (*insn_read) in the (*insn_config). The (*insn_config) doesn't follow the comedi API and this programmable conversion time is not part of the API for (*insn_read) operations. Remove the member from the private data and use a fixed 10us (10000ns) conversion time in the (*insn_read). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 10 +--------- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 2656e53999f8..9b18abf13b24 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -114,9 +114,6 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, if (data[0] != APCI3120_EOC_MODE) return -1; - /* Check for Conversion time to be added */ - devpriv->ui_EocEosConversionTime = data[2]; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; if (data[1]) devpriv->b_EocEosInterrupt = APCI3120_ENABLE; @@ -172,10 +169,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, unsigned short us_TmpValue, i; /* fix conversion time to 10 us */ - if (!devpriv->ui_EocEosConversionTime) - ns = 10000; - else - ns = devpriv->ui_EocEosConversionTime; + ns = 10000; /* Clear software registers */ devpriv->timer_mode = 0; @@ -240,7 +234,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, dev_err(dev->class_dev, "inputs wrong\n"); } - devpriv->ui_EocEosConversionTime = 0; /* re initializing the variable */ } return insn->n; @@ -254,7 +247,6 @@ static int apci3120_reset(struct comedi_device *dev) devpriv->ai_running = 0; devpriv->b_EocEosInterrupt = APCI3120_DISABLE; devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ /* variables used in timer subdevice */ devpriv->b_Timer2Mode = 0; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 0f3dabfabfc8..13c06cd18456 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -129,7 +129,6 @@ struct apci3120_private { unsigned int ai_running:1; unsigned char b_InterruptMode; unsigned char b_EocEosInterrupt; - unsigned int ui_EocEosConversionTime; unsigned char b_ExttrigEnable; struct task_struct *tsk_Current; }; -- GitLab From 7ee779a237ab12b76264e11819af19b03f9c96c4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:30 -0700 Subject: [PATCH 3775/9457] staging: comedi: addi_apci_3120: remove interrupt support from ai (*insn_read) (*insn_read) functions are supposed to do simple polled reads of a single channel. This driver tries to be tricky and allow enabling interrupts in the analog input (*insn_config) to allow the (*insn_read) to read samples with the end-of-conversion interrupt. The (*insn_config) doesn't follow the comedi API and this operation mode is not part of the API. Remove the interrupt support from the (*insn_read) as well as the support code in the (*insn_config) and interrupt handler. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 74 +++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 17 insertions(+), 58 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 9b18abf13b24..40ff942f1f08 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -115,10 +115,6 @@ static int apci3120_ai_insn_config(struct comedi_device *dev, return -1; devpriv->b_InterruptMode = APCI3120_EOC_MODE; - if (data[1]) - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; - else - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; return insn->n; } @@ -198,11 +194,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* Initialize Timer 0 mode 4 */ apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - devpriv->mode |= APCI3120_MODE_EOC_IRQ_ENA; - inw(dev->iobase + 0); - } - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); apci3120_timer_enable(dev, 0, true); @@ -213,22 +204,17 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); - if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { - - do { - /* Waiting for the end of conversion */ - us_TmpValue = inw(dev->iobase + - APCI3120_RD_STATUS); - } while ((us_TmpValue & APCI3120_EOC) == - APCI3120_EOC); - - /* Read the result in FIFO and put it in insn data pointer */ - us_TmpValue = inw(dev->iobase + 0); - *data = us_TmpValue; + do { + /* Waiting for the end of conversion */ + us_TmpValue = inw(dev->iobase + + APCI3120_RD_STATUS); + } while ((us_TmpValue & APCI3120_EOC) == APCI3120_EOC); - apci3120_ai_reset_fifo(dev); - } + /* Read the result in FIFO and put it in insn data pointer */ + us_TmpValue = inw(dev->iobase + 0); + *data = us_TmpValue; + apci3120_ai_reset_fifo(dev); break; default: dev_err(dev->class_dev, "inputs wrong\n"); @@ -245,7 +231,6 @@ static int apci3120_reset(struct comedi_device *dev) struct apci3120_private *devpriv = dev->private; devpriv->ai_running = 0; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; devpriv->b_InterruptMode = APCI3120_EOC_MODE; /* variables used in timer subdevice */ @@ -298,7 +283,6 @@ static int apci3120_cancel(struct comedi_device *dev, devpriv->ai_running = 0; devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; return 0; } @@ -448,7 +432,6 @@ static int apci3120_cyclic_ai(int mode, if (devpriv->us_UseDma == APCI3120_DISABLE) { /* disable EOC and enable EOS */ devpriv->b_InterruptMode = APCI3120_EOS_MODE; - devpriv->b_EocEosInterrupt = APCI3120_ENABLE; devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); @@ -816,9 +799,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned short int_daq; - unsigned int int_amcc, ui_Check; - - ui_Check = 1; + unsigned int int_amcc; int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); @@ -845,41 +826,20 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); /* Ckeck if EOC interrupt */ - if (((int_daq & 0x8) == 0) - && (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) { - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { - - /* Read the AI Value */ - devpriv->ui_AiReadData[0] = inw(dev->iobase + 0); - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - } else { - /* Disable EOC Interrupt */ - devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - } + if (((int_daq & 0x8) == 0) && + (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) { + /* nothing to do... EOC mode is not currently used */ } /* Check If EOS interrupt */ if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { - - if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */ - - if (devpriv->ai_running) { - ui_Check = 0; - apci3120_interrupt_handle_eos(dev); - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, - dev->iobase + APCI3120_MODE_REG); - } - } else { - devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; + if (devpriv->ai_running) { + apci3120_interrupt_handle_eos(dev); + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ - devpriv->b_InterruptMode = APCI3120_EOC_MODE; } - } + /* Timer2 interrupt */ if (int_daq & 0x1) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 13c06cd18456..e7564ad8e140 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -128,7 +128,6 @@ struct apci3120_private { unsigned char b_Timer2Interrupt; unsigned int ai_running:1; unsigned char b_InterruptMode; - unsigned char b_EocEosInterrupt; unsigned char b_ExttrigEnable; struct task_struct *tsk_Current; }; -- GitLab From e614d1710803e47549d2189927c3b25de856cfb2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:31 -0700 Subject: [PATCH 3776/9457] staging: comedi: addi_apci_3120: remove apci3120_ai_insn_config() This function does not follow the comedi API for (*insn_config) functions. It's also no long needed. Just remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 15 --------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 40ff942f1f08..5d15acacc259 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -104,21 +104,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_COUNTER 3 -static int apci3120_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - - if (data[0] != APCI3120_EOC_MODE) - return -1; - - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - - return insn->n; -} - static int apci3120_setup_chan_list(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e7564ad8e140..572d545e7492 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -381,7 +381,6 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; s->range_table = &apci3120_ai_range; - s->insn_config = apci3120_ai_insn_config; s->insn_read = apci3120_ai_insn_read; if (0 /* dev->irq */) { dev->read_subdev = s; -- GitLab From 22f75dac46e0691ef03e44d27d21d2b860cc15fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:32 -0700 Subject: [PATCH 3777/9457] staging: comedi: addi_apci_3120: remove private data 'ui_AiReadData' This member of the private data was used to return analog input samples that were acquired for the (*insn_read) using interrupts. The interrupt support code for the (*insn_read) has been removed. Remove this unused member from the private data. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 +--- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 5d15acacc259..51cdecb211d6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -147,7 +147,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; unsigned int divisor; unsigned int ns; - unsigned short us_TmpValue, i; + unsigned short us_TmpValue; /* fix conversion time to 10 us */ ns = 10000; @@ -157,8 +157,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, devpriv->mode = 0; if (insn->unused[0] == 222) { /* second insn read */ - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ui_AiReadData[i]; } else { devpriv->tsk_Current = current; /* Save the current process task structure */ diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 572d545e7492..dc05b2f616ca 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -115,7 +115,6 @@ struct apci3120_private { unsigned int osc_base; unsigned int ui_AiNbrofChannels; unsigned int ui_AiChannelList[32]; - unsigned int ui_AiReadData[32]; unsigned short us_UseDma; unsigned char b_DmaDoubleBuffer; unsigned int ui_DmaActualBuffer; -- GitLab From 89e9057b50369474c1e701faccdeedf08566ec57 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:33 -0700 Subject: [PATCH 3778/9457] staging: comedi: addi_apci_3120: fix apci3120_ai_insn_read() Now that the scanning and interrupt support have been removed from this function it can be refactored to work correctly. The comedi core expects (*insn_read) functions to read insn->n values from the hardware and return the number of samples read. This function currently just reads one sample but it returns insn->n. Fix this function to work like the core expects. Use comedi_timeout() to prevent a possible deadlock in the loop that waits for the end-of-conversion. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 90 +++++++++---------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 51cdecb211d6..5fb884835643 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -139,6 +139,19 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, return 1; /* we can serve this with scan logic */ } +static int apci3120_ai_eoc(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_RD_STATUS); + if ((status & APCI3120_EOC) == 0) + return 0; + return -EBUSY; +} + static int apci3120_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -146,67 +159,44 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, { struct apci3120_private *devpriv = dev->private; unsigned int divisor; - unsigned int ns; - unsigned short us_TmpValue; - - /* fix conversion time to 10 us */ - ns = 10000; - - /* Clear software registers */ - devpriv->timer_mode = 0; - devpriv->mode = 0; - - if (insn->unused[0] == 222) { /* second insn read */ - } else { - devpriv->tsk_Current = current; /* Save the current process task structure */ - - divisor = apci3120_ns_to_timer(dev, 0, ns, CMDF_ROUND_NEAREST); - - us_TmpValue = (unsigned short) devpriv->b_InterruptMode; - - switch (us_TmpValue) { - - case APCI3120_EOC_MODE: - apci3120_ai_reset_fifo(dev); - - /* Initialize the sequence array */ - if (!apci3120_setup_chan_list(dev, s, 1, - &insn->chanspec)) - return -EINVAL; - - /* Initialize Timer 0 mode 4 */ - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); + int ret; + int i; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + /* set mode for A/D conversions by software trigger with timer 0 */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - apci3120_timer_enable(dev, 0, true); + /* load chanlist for single channel scan */ + if (!apci3120_setup_chan_list(dev, s, 1, &insn->chanspec)) + return -EINVAL; - /* Set the conversion time */ - apci3120_timer_write(dev, 0, divisor); + /* + * Timer 0 is used in MODE4 (software triggered strobe) to set the + * conversion time for each acquisition. Each conversion is triggered + * when the divisor is written to the timer, The conversion is done + * when the EOC bit in the status register is '0'. + */ + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); + apci3120_timer_enable(dev, 0, true); - us_TmpValue = - (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS); + /* fixed conversion time of 10 us */ + divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST); - do { - /* Waiting for the end of conversion */ - us_TmpValue = inw(dev->iobase + - APCI3120_RD_STATUS); - } while ((us_TmpValue & APCI3120_EOC) == APCI3120_EOC); + apci3120_ai_reset_fifo(dev); - /* Read the result in FIFO and put it in insn data pointer */ - us_TmpValue = inw(dev->iobase + 0); - *data = us_TmpValue; + for (i = 0; i < insn->n; i++) { + /* trigger conversion */ + apci3120_timer_write(dev, 0, divisor); - apci3120_ai_reset_fifo(dev); - break; - default: - dev_err(dev->class_dev, "inputs wrong\n"); + ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0); + if (ret) + return ret; - } + data[i] = inw(dev->iobase + 0); } return insn->n; - } static int apci3120_reset(struct comedi_device *dev) -- GitLab From bb201b94cc251584bb69ed9e1f002d886f66fd4b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:34 -0700 Subject: [PATCH 3779/9457] staging: comedi: addi_apci_3120: absorb apci3120_interrupt_handle_eos() Absorb this simple function into apci3120_interrupt(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 5fb884835643..1913fd2f29dd 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -747,25 +747,6 @@ static void apci3120_interrupt_dma(int irq, void *d) } } -/* - * This function handles EOS interrupt. - * This function copies the acquired data(from FIFO) to Comedi buffer. - */ -static int apci3120_interrupt_handle_eos(struct comedi_device *dev) -{ - struct apci3120_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - unsigned short val; - int i; - - for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { - val = inw(dev->iobase + 0); - comedi_buf_write_samples(s, &val, 1); - } - - return 0; -} - static irqreturn_t apci3120_interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -807,7 +788,14 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) /* Check If EOS interrupt */ if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { if (devpriv->ai_running) { - apci3120_interrupt_handle_eos(dev); + unsigned short val; + int i; + + for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { + val = inw(dev->iobase + 0); + comedi_buf_write_samples(s, &val, 1); + } + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); } -- GitLab From 2e8fcfdd057db84979d9c11cad94bb7e3a5d6af7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:35 -0700 Subject: [PATCH 3780/9457] staging: comedi: addi_apci_3120: remove private data 'ui_AiNbrofChannels' This member of the private data is always the cmd->chanlist_len. Use that instead and remove the member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 8 +++----- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 1913fd2f29dd..004142efd2e6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -361,7 +361,7 @@ static int apci3120_cyclic_ai(int mode, devpriv->ui_DmaActualBuffer = 0; /* Initializes the sequence array */ - if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels, + if (!apci3120_setup_chan_list(dev, s, cmd->chanlist_len, cmd->chanlist)) return -EINVAL; @@ -605,9 +605,6 @@ static int apci3120_ai_cmd(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - /* loading private structure with cmd structure inputs */ - devpriv->ui_AiNbrofChannels = cmd->chanlist_len; - if (cmd->start_src == TRIG_EXT) devpriv->b_ExttrigEnable = APCI3120_ENABLE; else @@ -752,6 +749,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) struct comedi_device *dev = d; struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; unsigned short int_daq; unsigned int int_amcc; @@ -791,7 +789,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) unsigned short val; int i; - for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { + for (i = 0; i < cmd->chanlist_len; i++) { val = inw(dev->iobase + 0); comedi_buf_write_samples(s, &val, 1); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index dc05b2f616ca..2eb7ab5da7d7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -113,7 +113,6 @@ struct apci3120_private { unsigned long amcc; unsigned long addon; unsigned int osc_base; - unsigned int ui_AiNbrofChannels; unsigned int ui_AiChannelList[32]; unsigned short us_UseDma; unsigned char b_DmaDoubleBuffer; -- GitLab From 08595f9da2f65530d1d9d383760dd2864a0208c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:36 -0700 Subject: [PATCH 3781/9457] staging: comedi: addi_apci_3120: remove private data 'ui_AiChannelList' This member of the private data is no longer used. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 2eb7ab5da7d7..9ff6580486e7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -113,7 +113,6 @@ struct apci3120_private { unsigned long amcc; unsigned long addon; unsigned int osc_base; - unsigned int ui_AiChannelList[32]; unsigned short us_UseDma; unsigned char b_DmaDoubleBuffer; unsigned int ui_DmaActualBuffer; -- GitLab From b0a0d0bc58d6e2f052350e3fe5b6c6bed6fad67b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:37 -0700 Subject: [PATCH 3782/9457] staging: comedi: addi_apci_3120: rename APCI3120_RD_STATUS For aesthetics, rename this define used for the status register offset. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 17 +++++++---------- drivers/staging/comedi/drivers/addi_apci_3120.c | 3 ++- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 004142efd2e6..5deb1ff921da 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -81,7 +81,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_EOS_MODE 2 #define APCI3120_DMA_MODE 3 -#define APCI3120_RD_STATUS 0x02 #define APCI3120_RD_FIFO 0x00 /* status register bits */ @@ -99,7 +98,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 -#define APCI3120_RD_STATUS 0x02 #define APCI3120_FC_TIMER 0x1000 #define APCI3120_COUNTER 3 @@ -146,7 +144,7 @@ static int apci3120_ai_eoc(struct comedi_device *dev, { unsigned int status; - status = inw(dev->iobase + APCI3120_RD_STATUS); + status = inw(dev->iobase + APCI3120_STATUS_REG); if ((status & APCI3120_EOC) == 0) return 0; return -EBUSY; @@ -220,7 +218,7 @@ static int apci3120_reset(struct comedi_device *dev) outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); apci3120_ai_reset_fifo(dev); - inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ + inw(dev->iobase + APCI3120_STATUS_REG); return 0; } @@ -251,7 +249,7 @@ static int apci3120_cancel(struct comedi_device *dev, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); apci3120_ai_reset_fifo(dev); - inw(dev->iobase + APCI3120_RD_STATUS); + inw(dev->iobase + APCI3120_STATUS_REG); devpriv->ui_DmaActualBuffer = 0; devpriv->ai_running = 0; @@ -753,7 +751,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) unsigned short int_daq; unsigned int int_amcc; - int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ + int_daq = inw(dev->iobase + APCI3120_STATUS_REG) & 0xf000; int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) { @@ -1030,8 +1028,7 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, if (devpriv->b_Timer2Mode == APCI3120_TIMER) { data[0] = apci3120_timer_read(dev, 2); } else { /* Read watch dog status */ - - us_StatusValue = inw(dev->iobase + APCI3120_RD_STATUS); + us_StatusValue = inw(dev->iobase + APCI3120_STATUS_REG); us_StatusValue = ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1; if (us_StatusValue == 1) @@ -1049,7 +1046,7 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, unsigned int val; /* the input channels are bits 11:8 of the status reg */ - val = inw(dev->iobase + APCI3120_RD_STATUS); + val = inw(dev->iobase + APCI3120_STATUS_REG); data[1] = (val >> 8) & 0xf; return insn->n; @@ -1080,7 +1077,7 @@ static int apci3120_ao_ready(struct comedi_device *dev, { unsigned int status; - status = inw(dev->iobase + APCI3120_RD_STATUS); + status = inw(dev->iobase + APCI3120_STATUS_REG); if (status & 0x0001) /* waiting for DA_READY */ return 0; return -EBUSY; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9ff6580486e7..d47b2e0f624b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -20,6 +20,7 @@ #define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) +#define APCI3120_STATUS_REG 0x02 #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) #define APCI3120_TIMER_REG 0x04 #define APCI3120_CHANLIST_REG 0x06 @@ -360,7 +361,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, } } - status = inw(dev->iobase + APCI3120_RD_STATUS); + status = inw(dev->iobase + APCI3120_STATUS_REG); if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB || context == BOARD_APCI3001) devpriv->osc_base = APCI3120_REVB_OSC_BASE; -- GitLab From 3da982374a85455bc16003c95827871d11d5fca1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:38 -0700 Subject: [PATCH 3783/9457] staging: comedi: addi_apci_3120: define status register bits Define the bits in the status register and use them to clarify the code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 58 ++++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 9 +++ 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 5deb1ff921da..83881a61dbe0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -83,10 +83,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_RD_FIFO 0x00 -/* status register bits */ -#define APCI3120_EOC 0x8000 -#define APCI3120_EOS 0x2000 - /* software trigger dummy register */ #define APCI3120_START_CONVERSION 0x02 @@ -98,8 +94,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_TIMER_DISABLE 0 #define APCI3120_TIMER_ENABLE 1 -#define APCI3120_FC_TIMER 0x1000 - #define APCI3120_COUNTER 3 static int apci3120_setup_chan_list(struct comedi_device *dev, @@ -145,7 +139,7 @@ static int apci3120_ai_eoc(struct comedi_device *dev, unsigned int status; status = inw(dev->iobase + APCI3120_STATUS_REG); - if ((status & APCI3120_EOC) == 0) + if ((status & APCI3120_STATUS_EOC_INT) == 0) return 0; return -EBUSY; } @@ -748,21 +742,20 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; - unsigned short int_daq; + unsigned int status; unsigned int int_amcc; - int_daq = inw(dev->iobase + APCI3120_STATUS_REG) & 0xf000; + status = inw(dev->iobase + APCI3120_STATUS_REG); int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); - if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) { + if (!(status & APCI3120_STATUS_INT_MASK) && + !(int_amcc & ANY_S593X_INT)) { dev_err(dev->class_dev, "IRQ from unknown source\n"); return IRQ_NONE; } outl(int_amcc | 0x00ff0000, devpriv->amcc + AMCC_OP_REG_INTCSR); - int_daq = (int_daq >> 12) & 0xF; - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { apci3120_exttrig_enable(dev, false); devpriv->b_ExttrigEnable = APCI3120_DISABLE; @@ -775,14 +768,13 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (int_amcc & TARGET_ABORT_INT) dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); - /* Ckeck if EOC interrupt */ - if (((int_daq & 0x8) == 0) && - (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) { + if ((status & APCI3120_STATUS_EOC_INT) == 0 && + devpriv->b_InterruptMode == APCI3120_EOC_MODE) { /* nothing to do... EOC mode is not currently used */ } - /* Check If EOS interrupt */ - if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { + if ((status & APCI3120_STATUS_EOS_INT) && + devpriv->b_InterruptMode == APCI3120_EOS_MODE) { if (devpriv->ai_running) { unsigned short val; int i; @@ -797,9 +789,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } } - /* Timer2 interrupt */ - if (int_daq & 0x1) { - + if (status & APCI3120_STATUS_TIMER2_INT) { switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; @@ -829,7 +819,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) apci3120_clr_timer2_interrupt(dev); } - if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { + if ((status & APCI3120_STATUS_AMCC_INT) && + devpriv->b_InterruptMode == APCI3120_DMA_MODE) { if (devpriv->ai_running) { /* Clear Timer Write TC int */ @@ -1019,7 +1010,7 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, unsigned int *data) { struct apci3120_private *devpriv = dev->private; - unsigned short us_StatusValue; + unsigned int status; if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { @@ -1027,13 +1018,15 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, } if (devpriv->b_Timer2Mode == APCI3120_TIMER) { data[0] = apci3120_timer_read(dev, 2); - } else { /* Read watch dog status */ - us_StatusValue = inw(dev->iobase + APCI3120_STATUS_REG); - us_StatusValue = - ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1; - if (us_StatusValue == 1) + } else { + /* Read watch dog status */ + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (status & APCI3120_STATUS_TIMER2_INT) { apci3120_clr_timer2_interrupt(dev); - data[0] = us_StatusValue; /* when data[0] = 1 then the watch dog has rundown */ + data[0] = 1; + } else { + data[0] = 0; + } } return insn->n; } @@ -1043,11 +1036,10 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int val; + unsigned int status; - /* the input channels are bits 11:8 of the status reg */ - val = inw(dev->iobase + APCI3120_STATUS_REG); - data[1] = (val >> 8) & 0xf; + status = inw(dev->iobase + APCI3120_STATUS_REG); + data[1] = APCI3120_STATUS_TO_DI_BITS(status); return insn->n; } @@ -1078,7 +1070,7 @@ static int apci3120_ao_ready(struct comedi_device *dev, unsigned int status; status = inw(dev->iobase + APCI3120_STATUS_REG); - if (status & 0x0001) /* waiting for DA_READY */ + if (status & APCI3120_STATUS_DA_READY) return 0; return -EBUSY; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d47b2e0f624b..c18ee1750237 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -21,7 +21,16 @@ #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) #define APCI3120_STATUS_REG 0x02 +#define APCI3120_STATUS_EOC_INT (1 << 15) +#define APCI3120_STATUS_AMCC_INT (1 << 14) +#define APCI3120_STATUS_EOS_INT (1 << 13) +#define APCI3120_STATUS_TIMER2_INT (1 << 12) +#define APCI3120_STATUS_INT_MASK (0xf << 12) +#define APCI3120_STATUS_TO_DI_BITS(x) (((x) >> 8) & 0xf) #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf) +#define APCI3120_STATUS_FIFO_FULL (1 << 2) +#define APCI3120_STATUS_FIFO_EMPTY (1 << 1) +#define APCI3120_STATUS_DA_READY (1 << 0) #define APCI3120_TIMER_REG 0x04 #define APCI3120_CHANLIST_REG 0x06 #define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8) -- GitLab From 196540ee440d054313040925e3ed9daf39b9ec19 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:39 -0700 Subject: [PATCH 3784/9457] staging: comedi: addi_apci_3120: remove private data 'ai_running' This member of the private data was used to determine if the interrupt routine was handling data for the (*insn_read) or an async command. Now that the (*insn_read) does not use interrupts this member is not needed. Remove the member and refactor the code. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 41 +++++++------------ .../staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 83881a61dbe0..7bd17c28ebae 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -195,7 +195,6 @@ static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->ai_running = 0; devpriv->b_InterruptMode = APCI3120_EOC_MODE; /* variables used in timer subdevice */ @@ -246,7 +245,6 @@ static int apci3120_cancel(struct comedi_device *dev, inw(dev->iobase + APCI3120_STATUS_REG); devpriv->ui_DmaActualBuffer = 0; - devpriv->ai_running = 0; devpriv->b_InterruptMode = APCI3120_EOC_MODE; return 0; @@ -338,8 +336,6 @@ static int apci3120_cyclic_ai(int mode, unsigned int dmalen1 = 0; unsigned int divisor0; - devpriv->ai_running = 1; - /* clear software registers */ devpriv->timer_mode = 0; devpriv->mode = 0; @@ -775,18 +771,16 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if ((status & APCI3120_STATUS_EOS_INT) && devpriv->b_InterruptMode == APCI3120_EOS_MODE) { - if (devpriv->ai_running) { - unsigned short val; - int i; - - for (i = 0; i < cmd->chanlist_len; i++) { - val = inw(dev->iobase + 0); - comedi_buf_write_samples(s, &val, 1); - } + unsigned short val; + int i; - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + for (i = 0; i < cmd->chanlist_len; i++) { + val = inw(dev->iobase + 0); + comedi_buf_write_samples(s, &val, 1); } + + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); } if (status & APCI3120_STATUS_TIMER2_INT) { @@ -821,21 +815,14 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if ((status & APCI3120_STATUS_AMCC_INT) && devpriv->b_InterruptMode == APCI3120_DMA_MODE) { - if (devpriv->ai_running) { + /* Clear Timer Write TC int */ + outl(APCI3120_CLEAR_WRITE_TC_INT, + devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - /* Clear Timer Write TC int */ - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - - apci3120_clr_timer2_interrupt(dev); - - /* do some data transfer */ - apci3120_interrupt_dma(irq, d); - } else { - apci3120_timer_enable(dev, 0, false); - apci3120_timer_enable(dev, 1, false); - } + apci3120_clr_timer2_interrupt(dev); + /* do some data transfer */ + apci3120_interrupt_dma(irq, d); } comedi_handle_events(dev, s); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c18ee1750237..98de447d96b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -133,7 +133,6 @@ struct apci3120_private { unsigned short ctrl; unsigned char b_Timer2Mode; unsigned char b_Timer2Interrupt; - unsigned int ai_running:1; unsigned char b_InterruptMode; unsigned char b_ExttrigEnable; struct task_struct *tsk_Current; -- GitLab From ae12280db7f219d961df703d5c00dff0328c1623 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:40 -0700 Subject: [PATCH 3785/9457] staging: comedi: addi_apci_3120: move apci3120_do_insn_bits() to driver source Move this function from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 18 ------------------ .../staging/comedi/drivers/addi_apci_3120.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 7bd17c28ebae..d577d37de0bc 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1031,24 +1031,6 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int apci3120_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - - if (comedi_dio_update_state(s, data)) { - devpriv->do_bits = s->state; - outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits), - dev->iobase + APCI3120_CTR0_REG); - } - - data[1] = s->state; - - return insn->n; -} - static int apci3120_ao_ready(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 98de447d96b7..22d17e2aafbe 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -281,6 +281,24 @@ static void apci3120_ai_reset_fifo(struct comedi_device *dev) #include "addi-data/hwdrv_apci3120.c" +static int apci3120_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + + if (comedi_dio_update_state(s, data)) { + devpriv->do_bits = s->state; + outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits), + dev->iobase + APCI3120_CTR0_REG); + } + + data[1] = s->state; + + return insn->n; +} + static void apci3120_dma_alloc(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; -- GitLab From c737b2ce4f964aed8fc7a255a73417b00d742d65 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:41 -0700 Subject: [PATCH 3786/9457] staging: comedi: addi_apci_3120: move apci3120_di_insn_bits() to driver source Move this function from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 13 ------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d577d37de0bc..a206d5e583d5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1018,19 +1018,6 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, return insn->n; } -static int apci3120_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int status; - - status = inw(dev->iobase + APCI3120_STATUS_REG); - data[1] = APCI3120_STATUS_TO_DI_BITS(status); - - return insn->n; -} - static int apci3120_ao_ready(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 22d17e2aafbe..7033b0bd3ddb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -281,6 +281,19 @@ static void apci3120_ai_reset_fifo(struct comedi_device *dev) #include "addi-data/hwdrv_apci3120.c" +static int apci3120_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + data[1] = APCI3120_STATUS_TO_DI_BITS(status); + + return insn->n; +} + static int apci3120_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, -- GitLab From 5cf5fa957946a7d25dc4ce25dba9c8a20f8b8def Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:42 -0700 Subject: [PATCH 3787/9457] staging: comedi: addi_apci_3120: move apci3120_ao_insn_write() to driver source Move this function, and its helper function, from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 38 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 38 +++++++++++++++++++ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a206d5e583d5..929ef0b4620c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1017,41 +1017,3 @@ static int apci3120_read_insn_timer(struct comedi_device *dev, } return insn->n; } - -static int apci3120_ao_ready(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned long context) -{ - unsigned int status; - - status = inw(dev->iobase + APCI3120_STATUS_REG); - if (status & APCI3120_STATUS_DA_READY) - return 0; - return -EBUSY; -} - -static int apci3120_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int chan = CR_CHAN(insn->chanspec); - int i; - - for (i = 0; i < insn->n; i++) { - unsigned int val = data[i]; - int ret; - - ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); - if (ret) - return ret; - - outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), - dev->iobase + APCI3120_AO_REG(chan)); - - s->readback[chan] = val; - } - - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 7033b0bd3ddb..c17a8408749f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -281,6 +281,44 @@ static void apci3120_ai_reset_fifo(struct comedi_device *dev) #include "addi-data/hwdrv_apci3120.c" +static int apci3120_ao_ready(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (status & APCI3120_STATUS_DA_READY) + return 0; + return -EBUSY; +} + +static int apci3120_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int chan = CR_CHAN(insn->chanspec); + int i; + + for (i = 0; i < insn->n; i++) { + unsigned int val = data[i]; + int ret; + + ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); + if (ret) + return ret; + + outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), + dev->iobase + APCI3120_AO_REG(chan)); + + s->readback[chan] = val; + } + + return insn->n; +} + static int apci3120_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, -- GitLab From 6a51cfc62f523c70b000368b32cb46fa0d24f536 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:43 -0700 Subject: [PATCH 3788/9457] staging: comedi: addi_apci_3120: move apci3120_ai_insn_read() to driver source Move this function, and its helper function, from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 60 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 60 +++++++++++++++++++ 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 929ef0b4620c..28c5792f0e90 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -131,66 +131,6 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, return 1; /* we can serve this with scan logic */ } -static int apci3120_ai_eoc(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned long context) -{ - unsigned int status; - - status = inw(dev->iobase + APCI3120_STATUS_REG); - if ((status & APCI3120_STATUS_EOC_INT) == 0) - return 0; - return -EBUSY; -} - -static int apci3120_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - unsigned int divisor; - int ret; - int i; - - /* set mode for A/D conversions by software trigger with timer 0 */ - devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | - APCI3120_MODE_TIMER2_AS_TIMER; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - /* load chanlist for single channel scan */ - if (!apci3120_setup_chan_list(dev, s, 1, &insn->chanspec)) - return -EINVAL; - - /* - * Timer 0 is used in MODE4 (software triggered strobe) to set the - * conversion time for each acquisition. Each conversion is triggered - * when the divisor is written to the timer, The conversion is done - * when the EOC bit in the status register is '0'. - */ - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); - apci3120_timer_enable(dev, 0, true); - - /* fixed conversion time of 10 us */ - divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST); - - apci3120_ai_reset_fifo(dev); - - for (i = 0; i < insn->n; i++) { - /* trigger conversion */ - apci3120_timer_write(dev, 0, divisor); - - ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0); - if (ret) - return ret; - - data[i] = inw(dev->iobase + 0); - } - - return insn->n; -} - static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c17a8408749f..70363faa99d6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -281,6 +281,66 @@ static void apci3120_ai_reset_fifo(struct comedi_device *dev) #include "addi-data/hwdrv_apci3120.c" +static int apci3120_ai_eoc(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned long context) +{ + unsigned int status; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + if ((status & APCI3120_STATUS_EOC_INT) == 0) + return 0; + return -EBUSY; +} + +static int apci3120_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int divisor; + int ret; + int i; + + /* set mode for A/D conversions by software trigger with timer 0 */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + /* load chanlist for single channel scan */ + if (!apci3120_setup_chan_list(dev, s, 1, &insn->chanspec)) + return -EINVAL; + + /* + * Timer 0 is used in MODE4 (software triggered strobe) to set the + * conversion time for each acquisition. Each conversion is triggered + * when the divisor is written to the timer, The conversion is done + * when the EOC bit in the status register is '0'. + */ + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4); + apci3120_timer_enable(dev, 0, true); + + /* fixed conversion time of 10 us */ + divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST); + + apci3120_ai_reset_fifo(dev); + + for (i = 0; i < insn->n; i++) { + /* trigger conversion */ + apci3120_timer_write(dev, 0, divisor); + + ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0); + if (ret) + return ret; + + data[i] = inw(dev->iobase + 0); + } + + return insn->n; +} + static int apci3120_ao_ready(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, -- GitLab From 0a3e518102b4a252dfcfe7d602d6e99e8c77d230 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:44 -0700 Subject: [PATCH 3789/9457] staging: comedi: addi_apci_3120: remove check in apci3120_setup_chan_list() The n_chan check is not needed. This value will always be >= 1. Remove the unnecessary check. For aesthetics, rename the function and change it's return type to void. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 19 +++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 3 +-- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 28c5792f0e90..3c172466a3c0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -96,19 +96,13 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_COUNTER 3 -static int apci3120_setup_chan_list(struct comedi_device *dev, - struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist) +static void apci3120_set_chanlist(struct comedi_device *dev, + struct comedi_subdevice *s, + int n_chan, unsigned int *chanlist) { struct apci3120_private *devpriv = dev->private; int i; - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - dev_err(dev->class_dev, "range/channel list is empty!\n"); - return 0; - } - /* set scan length (PR) and scan start (PA) */ devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); @@ -128,7 +122,6 @@ static int apci3120_setup_chan_list(struct comedi_device *dev, outw(val, dev->iobase + APCI3120_CHANLIST_REG); } - return 1; /* we can serve this with scan logic */ } static int apci3120_reset(struct comedi_device *dev) @@ -288,10 +281,8 @@ static int apci3120_cyclic_ai(int mode, devpriv->ui_DmaActualBuffer = 0; - /* Initializes the sequence array */ - if (!apci3120_setup_chan_list(dev, s, cmd->chanlist_len, - cmd->chanlist)) - return -EINVAL; + /* load chanlist for command scan */ + apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); if (mode == 2) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 70363faa99d6..d40fdf2219a5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -310,8 +310,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* load chanlist for single channel scan */ - if (!apci3120_setup_chan_list(dev, s, 1, &insn->chanspec)) - return -EINVAL; + apci3120_set_chanlist(dev, s, 1, &insn->chanspec); /* * Timer 0 is used in MODE4 (software triggered strobe) to set the -- GitLab From 169f35e82ce6ba0068ecaf3671342a8201c99c32 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:45 -0700 Subject: [PATCH 3790/9457] staging: comedi: addi_apci_3120: move apci3120_set_chanlist() to driver source Move this function from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 28 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3c172466a3c0..f7543f684016 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -96,34 +96,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_COUNTER 3 -static void apci3120_set_chanlist(struct comedi_device *dev, - struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist) -{ - struct apci3120_private *devpriv = dev->private; - int i; - - /* set scan length (PR) and scan start (PA) */ - devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); - - /* set chanlist for scan */ - for (i = 0; i < n_chan; i++) { - unsigned int chan = CR_CHAN(chanlist[i]); - unsigned int range = CR_RANGE(chanlist[i]); - unsigned int val; - - val = APCI3120_CHANLIST_MUX(chan) | - APCI3120_CHANLIST_GAIN(range) | - APCI3120_CHANLIST_INDEX(i); - - if (comedi_range_is_unipolar(s, range)) - val |= APCI3120_CHANLIST_UNIPOLAR; - - outw(val, dev->iobase + APCI3120_CHANLIST_REG); - } -} - static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d40fdf2219a5..044d2c42bcd5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -279,6 +279,34 @@ static void apci3120_ai_reset_fifo(struct comedi_device *dev) inw(dev->iobase + APCI3120_TIMER_MODE_REG); } +static void apci3120_set_chanlist(struct comedi_device *dev, + struct comedi_subdevice *s, + int n_chan, unsigned int *chanlist) +{ + struct apci3120_private *devpriv = dev->private; + int i; + + /* set scan length (PR) and scan start (PA) */ + devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + + /* set chanlist for scan */ + for (i = 0; i < n_chan; i++) { + unsigned int chan = CR_CHAN(chanlist[i]); + unsigned int range = CR_RANGE(chanlist[i]); + unsigned int val; + + val = APCI3120_CHANLIST_MUX(chan) | + APCI3120_CHANLIST_GAIN(range) | + APCI3120_CHANLIST_INDEX(i); + + if (comedi_range_is_unipolar(s, range)) + val |= APCI3120_CHANLIST_UNIPOLAR; + + outw(val, dev->iobase + APCI3120_CHANLIST_REG); + } +} + #include "addi-data/hwdrv_apci3120.c" static int apci3120_ai_eoc(struct comedi_device *dev, -- GitLab From e451dfeb4c205f74b3bfc35d58fd1a17dff490ed Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:46 -0700 Subject: [PATCH 3791/9457] staging: comedi: addi_apci_3120: factor DMA setup out of apci3120_cyclic_ai() For aesthetics, factor the DMA setup code out of apci3120_cyclic_ai(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 295 +++++++++--------- 1 file changed, 148 insertions(+), 147 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f7543f684016..6377c37fde16 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -224,6 +224,153 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, return 0; } +static void apci3120_setup_dma(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; + struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; + unsigned int dmalen0 = dmabuf0->size; + unsigned int dmalen1 = dmabuf1->size; + unsigned int scan_bytes; + + scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); + + if (cmd->stop_src == TRIG_COUNT) { + /* + * Must we fill full first buffer? And must we fill + * full second buffer when first is once filled? + */ + if (dmalen0 > (cmd->stop_arg * scan_bytes)) + dmalen0 = cmd->stop_arg * scan_bytes; + else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0)) + dmalen1 = cmd->stop_arg * scan_bytes - dmalen0; + } + + if (cmd->flags & CMDF_WAKE_EOS) { + /* don't we want wake up every scan? */ + if (dmalen0 > scan_bytes) { + dmalen0 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen0 += 2; + } + if (dmalen1 > scan_bytes) { + dmalen1 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen1 -= 2; + if (dmalen1 < 4) + dmalen1 = 4; + } + } else { + /* isn't output buff smaller that our DMA buff? */ + if (dmalen0 > s->async->prealloc_bufsz) + dmalen0 = s->async->prealloc_bufsz; + if (dmalen1 > s->async->prealloc_bufsz) + dmalen1 = s->async->prealloc_bufsz; + } + dmabuf0->use_size = dmalen0; + dmabuf1->use_size = dmalen1; + + /* Initialize DMA */ + + /* + * Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS + * register 1 + */ + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); + + /* changed since 16 bit interface for add on */ + /* ENABLE BUS MASTER */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); + + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); + + /* + * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux + * driver + */ + outw(0x1000, devpriv->addon + 2); + /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + + /* 2 No change */ + /* A2P FIFO MANAGEMENT */ + /* A2P fifo reset & transfer control enable */ + outl(APCI3120_A2P_FIFO_MANAGEMENT, + devpriv->amcc + APCI3120_AMCC_OP_MCSR); + + /* + * 3 + * beginning address of dma buf The 32 bit address of dma buffer + * is converted into two 16 bit addresses Can done by using _attach + * and put into into an array array used may be for differnet pages + */ + + /* DMA Start Address Low */ + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); + outw(dmabuf0->hw & 0xffff, devpriv->addon + 2); + + /* DMA Start Address High */ + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); + outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2); + + /* + * 4 + * amount of bytes to be transferred set transfer count used ADDON + * MWTC register commented testing + */ + + /* Nbr of acquisition LOW */ + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); + outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2); + + /* Nbr of acquisition HIGH */ + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); + outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2); + + /* + * 5 + * To configure A2P FIFO testing outl( + * FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR); + */ + + /* A2P FIFO RESET */ + /* + * TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux + * driver + */ + outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR); + /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + + /* + * 6 + * ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE | + * A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + */ + + /* + * 7 + * initialise end of dma interrupt AINT_WRITE_COMPL = + * ENABLE_WRITE_TC_INT(ADDI) + */ + /* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT, + devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ + /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ + outw(3, devpriv->addon + 4); + /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + + /* A2P FIFO RESET */ + /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ + outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR); + /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ +} + /* * This is used for analog input cyclic acquisition. * Performs the command operations. @@ -237,8 +384,6 @@ static int apci3120_cyclic_ai(int mode, struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int divisor1 = 0; - unsigned int dmalen0 = 0; - unsigned int dmalen1 = 0; unsigned int divisor0; /* clear software registers */ @@ -320,152 +465,8 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_Timer2Interrupt = APCI3120_ENABLE; } } else { - /* If DMA Enabled */ - struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; - struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; - unsigned int scan_bytes; - - scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); - devpriv->b_InterruptMode = APCI3120_DMA_MODE; - - dmalen0 = dmabuf0->size; - dmalen1 = dmabuf1->size; - - if (cmd->stop_src == TRIG_COUNT) { - /* - * Must we fill full first buffer? And must we fill - * full second buffer when first is once filled? - */ - if (dmalen0 > (cmd->stop_arg * scan_bytes)) { - dmalen0 = cmd->stop_arg * scan_bytes; - } else if (dmalen1 > (cmd->stop_arg * scan_bytes - - dmalen0)) - dmalen1 = cmd->stop_arg * scan_bytes - - dmalen0; - } - - if (cmd->flags & CMDF_WAKE_EOS) { - /* don't we want wake up every scan? */ - if (dmalen0 > scan_bytes) { - dmalen0 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen0 += 2; - } - if (dmalen1 > scan_bytes) { - dmalen1 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen1 -= 2; - if (dmalen1 < 4) - dmalen1 = 4; - } - } else { /* isn't output buff smaller that our DMA buff? */ - if (dmalen0 > s->async->prealloc_bufsz) - dmalen0 = s->async->prealloc_bufsz; - if (dmalen1 > s->async->prealloc_bufsz) - dmalen1 = s->async->prealloc_bufsz; - } - dmabuf0->use_size = dmalen0; - dmabuf1->use_size = dmalen1; - - /* Initialize DMA */ - - /* - * Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS - * register 1 - */ - outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - devpriv->amcc + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - /* ENABLE BUS MASTER */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); - - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); - - /* - * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outw(0x1000, devpriv->addon + 2); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* 2 No change */ - /* A2P FIFO MANAGEMENT */ - /* A2P fifo reset & transfer control enable */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->amcc + APCI3120_AMCC_OP_MCSR); - - /* - * 3 - * beginning address of dma buf The 32 bit address of dma buffer - * is converted into two 16 bit addresses Can done by using _attach - * and put into into an array array used may be for differnet pages - */ - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); - outw(dmabuf0->hw & 0xffff, devpriv->addon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); - outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2); - - /* - * 4 - * amount of bytes to be transferred set transfer count used ADDON - * MWTC register commented testing - */ - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); - outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); - outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2); - - /* - * 5 - * To configure A2P FIFO testing outl( - * FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR); - */ - - /* A2P FIFO RESET */ - /* - * TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* - * 6 - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE | - * A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - - /* - * 7 - * initialise end of dma interrupt AINT_WRITE_COMPL = - * ENABLE_WRITE_TC_INT(ADDI) - */ - /* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->amcc + AMCC_OP_REG_INTCSR); - - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ - outw(3, devpriv->addon + 4); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* A2P FIFO RESET */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + apci3120_setup_dma(dev, s); } if (devpriv->us_UseDma == APCI3120_DISABLE && -- GitLab From 76931af2009ef8e81fd30addf42a39d0265c45f5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:47 -0700 Subject: [PATCH 3792/9457] staging: comedi: addi_apci_3120: remove APCI3120_{ENABLE,DISABLE} These true/false defines don't add any significant clarity to the code. Remove them. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 6377c37fde16..4760200ca1e0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -71,9 +71,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY /* for transfer count enable bit */ #define AGCSTS_TC_ENABLE 0x10000000 -#define APCI3120_DISABLE 0 -#define APCI3120_ENABLE 1 - #define APCI3120_START 1 #define APCI3120_STOP 0 @@ -407,7 +404,7 @@ static int apci3120_cyclic_ai(int mode, cmd->flags); } - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) + if (devpriv->b_ExttrigEnable) apci3120_exttrig_enable(dev, true); switch (mode) { @@ -438,7 +435,7 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* If DMA is disabled */ - if (devpriv->us_UseDma == APCI3120_DISABLE) { + if (!devpriv->us_UseDma) { /* disable EOC and enable EOS */ devpriv->b_InterruptMode = APCI3120_EOS_MODE; @@ -462,15 +459,14 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); devpriv->b_Timer2Mode = APCI3120_COUNTER; - devpriv->b_Timer2Interrupt = APCI3120_ENABLE; + devpriv->b_Timer2Interrupt = 1; } } else { devpriv->b_InterruptMode = APCI3120_DMA_MODE; apci3120_setup_dma(dev, s); } - if (devpriv->us_UseDma == APCI3120_DISABLE && - cmd->stop_src == TRIG_COUNT) + if (!devpriv->us_UseDma && cmd->stop_src == TRIG_COUNT) apci3120_timer_enable(dev, 2, true); switch (mode) { @@ -498,9 +494,9 @@ static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_cmd *cmd = &s->async->cmd; if (cmd->start_src == TRIG_EXT) - devpriv->b_ExttrigEnable = APCI3120_ENABLE; + devpriv->b_ExttrigEnable = 1; else - devpriv->b_ExttrigEnable = APCI3120_DISABLE; + devpriv->b_ExttrigEnable = 0; if (cmd->scan_begin_src == TRIG_FOLLOW) return apci3120_cyclic_ai(1, dev, s); @@ -656,9 +652,9 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) outl(int_amcc | 0x00ff0000, devpriv->amcc + AMCC_OP_REG_INTCSR); - if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { + if (devpriv->b_ExttrigEnable) { apci3120_exttrig_enable(dev, false); - devpriv->b_ExttrigEnable = APCI3120_DISABLE; + devpriv->b_ExttrigEnable = 0; } apci3120_clr_timer2_interrupt(dev); @@ -841,7 +837,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, } /* enable disable interrupt */ - if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) { + if (devpriv->b_Timer2Interrupt) { devpriv->mode |= APCI3120_MODE_TIMER2_IRQ_ENA; /* save the task structure to pass info to user */ -- GitLab From 5c66a77e1d1da92f4b42c069d6591ecc41dbe6ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:48 -0700 Subject: [PATCH 3793/9457] staging: comedi: addi_apci_3120: flip 'us_UseDma' test in apci3120_cyclic_ai() For aesthetics, flip this test and do the DMA setup first. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 4760200ca1e0..31ef047b6281 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -434,8 +434,10 @@ static int apci3120_cyclic_ai(int mode, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - /* If DMA is disabled */ - if (!devpriv->us_UseDma) { + if (devpriv->us_UseDma) { + devpriv->b_InterruptMode = APCI3120_DMA_MODE; + apci3120_setup_dma(dev, s); + } else { /* disable EOC and enable EOS */ devpriv->b_InterruptMode = APCI3120_EOS_MODE; @@ -461,9 +463,6 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = 1; } - } else { - devpriv->b_InterruptMode = APCI3120_DMA_MODE; - apci3120_setup_dma(dev, s); } if (!devpriv->us_UseDma && cmd->stop_src == TRIG_COUNT) -- GitLab From b72b365666701b66d8ff09a5023b0d097d38e538 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:49 -0700 Subject: [PATCH 3794/9457] staging: comedi: addi_apci_3120: move timer 2 enable in apci3120_cyclic_ai() Move the enable of timer 2 to avoid needing the extra if() check. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 31ef047b6281..1481d18a12fa 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -462,12 +462,11 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = 1; + + apci3120_timer_enable(dev, 2, true); } } - if (!devpriv->us_UseDma && cmd->stop_src == TRIG_COUNT) - apci3120_timer_enable(dev, 2, true); - switch (mode) { case 1: apci3120_timer_enable(dev, 0, true); -- GitLab From fb43ceaf1d869215a0e704f0e83be993bdb07f56 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:50 -0700 Subject: [PATCH 3795/9457] staging: comedi: addi_apci_3120: move start_src check into apci3120_cyclic_ai() For aesthetics, move the check of the cmd->start_src. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 1481d18a12fa..b4d6fb467362 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -404,8 +404,12 @@ static int apci3120_cyclic_ai(int mode, cmd->flags); } - if (devpriv->b_ExttrigEnable) + if (cmd->start_src == TRIG_EXT) { + devpriv->b_ExttrigEnable = 1; apci3120_exttrig_enable(dev, true); + } else { + devpriv->b_ExttrigEnable = 0; + } switch (mode) { case 1: @@ -488,14 +492,8 @@ static int apci3120_cyclic_ai(int mode, static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - if (cmd->start_src == TRIG_EXT) - devpriv->b_ExttrigEnable = 1; - else - devpriv->b_ExttrigEnable = 0; - if (cmd->scan_begin_src == TRIG_FOLLOW) return apci3120_cyclic_ai(1, dev, s); /* TRIG_TIMER */ -- GitLab From aaf802fb304ccbfc68c9699ae3a800a769c3d838 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:51 -0700 Subject: [PATCH 3796/9457] staging: comedi: addi_apci_3120: absorb apci3120_cyclic_ai() This functon is called by apci3120_ai_cmd() with one additional parameter, 'mode', The 'mode' is based on the cmd->scan_begin_src. For aesthetics, absorb the function into apci3120_ai_cmd() and use the cmd->scan_begin_src directly to determine the 'mode'. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 45 +++---------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b4d6fb467362..8fc78039bfac 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -368,15 +368,8 @@ static void apci3120_setup_dma(struct comedi_device *dev, /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ } -/* - * This is used for analog input cyclic acquisition. - * Performs the command operations. - * If DMA is configured does DMA initialization otherwise does the - * acquisition with EOS interrupt. - */ -static int apci3120_cyclic_ai(int mode, - struct comedi_device *dev, - struct comedi_subdevice *s) +static int apci3120_ai_cmd(struct comedi_device *dev, + struct comedi_subdevice *s) { struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; @@ -399,7 +392,7 @@ static int apci3120_cyclic_ai(int mode, apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); - if (mode == 2) { + if (cmd->scan_begin_src == TRIG_TIMER) { divisor1 = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, cmd->flags); } @@ -411,16 +404,13 @@ static int apci3120_cyclic_ai(int mode, devpriv->b_ExttrigEnable = 0; } - switch (mode) { - case 1: + if (cmd->scan_begin_src == TRIG_FOLLOW) { /* init timer0 in mode 2 */ apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); - break; - - case 2: + } else { /* TRIG_TIMER */ /* init timer1 in mode 2 */ apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); @@ -432,8 +422,6 @@ static int apci3120_cyclic_ai(int mode, /* Set the conversion time */ apci3120_timer_write(dev, 0, divisor0); - break; - } outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); @@ -471,33 +459,14 @@ static int apci3120_cyclic_ai(int mode, } } - switch (mode) { - case 1: + if (cmd->scan_begin_src == TRIG_FOLLOW) { apci3120_timer_enable(dev, 0, true); - break; - case 2: + } else { /* TRIG_TIMER */ apci3120_timer_enable(dev, 1, true); apci3120_timer_enable(dev, 0, true); - break; } return 0; - -} - -/* - * Does asynchronous acquisition. - * Determines the mode 1 or 2. - */ -static int apci3120_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct comedi_cmd *cmd = &s->async->cmd; - - if (cmd->scan_begin_src == TRIG_FOLLOW) - return apci3120_cyclic_ai(1, dev, s); - /* TRIG_TIMER */ - return apci3120_cyclic_ai(2, dev, s); } /* -- GitLab From dc0a05608d465eda9b340b958af40c1eae61af7b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:52 -0700 Subject: [PATCH 3797/9457] staging: comedi: addi_apci_3120: tidy up timer programming in apci3120_ai_cmd() Tidy up the programming of timers 0 and 1 so that only one local variable is required. Also, remove the unnecessary clear of devpriv->timer_mode. This value will get set correctly by each apci3120_timer_set_mode() call. It's not necessary to clear it first. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 52 +++++++------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 8fc78039bfac..3656f9d23ebc 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -373,12 +373,10 @@ static int apci3120_ai_cmd(struct comedi_device *dev, { struct apci3120_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int divisor1 = 0; - unsigned int divisor0; + unsigned int divisor; - /* clear software registers */ - devpriv->timer_mode = 0; devpriv->mode = 0; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, @@ -391,12 +389,6 @@ static int apci3120_ai_cmd(struct comedi_device *dev, /* load chanlist for command scan */ apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); - divisor0 = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); - if (cmd->scan_begin_src == TRIG_TIMER) { - divisor1 = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, - cmd->flags); - } - if (cmd->start_src == TRIG_EXT) { devpriv->b_ExttrigEnable = 1; apci3120_exttrig_enable(dev, true); @@ -404,27 +396,24 @@ static int apci3120_ai_cmd(struct comedi_device *dev, devpriv->b_ExttrigEnable = 0; } - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* init timer0 in mode 2 */ - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); - - /* Set the conversion time */ - apci3120_timer_write(dev, 0, divisor0); - } else { /* TRIG_TIMER */ - /* init timer1 in mode 2 */ + if (cmd->scan_begin_src == TRIG_TIMER) { + /* + * Timer 1 is used in MODE2 (rate generator) to set the + * start time for each scan. + */ + divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, + cmd->flags); apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); - - /* Set the scan begin time */ - apci3120_timer_write(dev, 1, divisor1); - - /* init timer0 in mode 2 */ - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); - - /* Set the conversion time */ - apci3120_timer_write(dev, 0, divisor0); + apci3120_timer_write(dev, 1, divisor); } - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + /* + * Timer 0 is used in MODE2 (rate generator) to set the conversion + * time for each acquisition. + */ + divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); + apci3120_timer_write(dev, 0, divisor); if (devpriv->us_UseDma) { devpriv->b_InterruptMode = APCI3120_DMA_MODE; @@ -459,12 +448,9 @@ static int apci3120_ai_cmd(struct comedi_device *dev, } } - if (cmd->scan_begin_src == TRIG_FOLLOW) { - apci3120_timer_enable(dev, 0, true); - } else { /* TRIG_TIMER */ + if (cmd->scan_begin_src == TRIG_TIMER) apci3120_timer_enable(dev, 1, true); - apci3120_timer_enable(dev, 0, true); - } + apci3120_timer_enable(dev, 0, true); return 0; } -- GitLab From 502ccab2b644f2445af463e434783e56b407f31b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:53 -0700 Subject: [PATCH 3798/9457] staging: comedi: addi_apci_3120: tidy up timer 2 programming in apci3120_ai_cmd() Tidy up the programming of timer 2. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3656f9d23ebc..54c85837160e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -426,16 +426,20 @@ static int apci3120_ai_cmd(struct comedi_device *dev, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); if (cmd->stop_src == TRIG_COUNT) { - /* configure Timer2 For counting EOS */ - - /* (1) Init timer 2 in mode 0 and write timer value */ + /* + * Timer 2 is used in MODE0 (hardware retriggerable + * one-shot) to count the number of scans. + * + * NOTE: not sure about the -2 value + */ apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0); - - /* Set the scan stop count (not sure about the -2) */ apci3120_timer_write(dev, 2, cmd->stop_arg - 2); apci3120_clr_timer2_interrupt(dev); + apci3120_timer_enable(dev, 2, true); + + /* configure Timer 2 For counting EOS */ devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER | APCI3120_MODE_TIMER2_CLK_EOS | APCI3120_MODE_TIMER2_IRQ_ENA; @@ -443,8 +447,6 @@ static int apci3120_ai_cmd(struct comedi_device *dev, devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = 1; - - apci3120_timer_enable(dev, 2, true); } } -- GitLab From 15e920fb1581c531f8d139534fa58d964d4e8b45 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:54 -0700 Subject: [PATCH 3799/9457] staging: comedi: addi_apci_3120: reset fifo after programming chanlist The APCI-3120 documentation says that the FIFO should be reset after the chanlist sequence is programmed. Reset the FIFO after programming the chanlist and remove the extra FIFO resets in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 ---- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 54c85837160e..95a1b7dad397 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -112,7 +112,6 @@ static int apci3120_reset(struct comedi_device *dev) devpriv->ctrl = 0; outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); - apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_STATUS_REG); return 0; @@ -143,7 +142,6 @@ static int apci3120_cancel(struct comedi_device *dev, devpriv->mode = 0; outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - apci3120_ai_reset_fifo(dev); inw(dev->iobase + APCI3120_STATUS_REG); devpriv->ui_DmaActualBuffer = 0; @@ -382,8 +380,6 @@ static int apci3120_ai_cmd(struct comedi_device *dev, outl(APCI3120_CLEAR_WRITE_TC_INT, devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); - apci3120_ai_reset_fifo(dev); - devpriv->ui_DmaActualBuffer = 0; /* load chanlist for command scan */ diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 044d2c42bcd5..77499b473bb4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -305,6 +305,8 @@ static void apci3120_set_chanlist(struct comedi_device *dev, outw(val, dev->iobase + APCI3120_CHANLIST_REG); } + + apci3120_ai_reset_fifo(dev); } #include "addi-data/hwdrv_apci3120.c" @@ -352,8 +354,6 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, /* fixed conversion time of 10 us */ divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST); - apci3120_ai_reset_fifo(dev); - for (i = 0; i < insn->n; i++) { /* trigger conversion */ apci3120_timer_write(dev, 0, divisor); -- GitLab From 1022f64e7548a3bede7c671c6d52592f05954bd5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:55 -0700 Subject: [PATCH 3800/9457] staging: comedi: addi_apci_3120: set scan length/start after programming chanlist The APCI-3120 documentation says that the PR/PA bits should be set after the chanlist sequence is programmed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 77499b473bb4..f258ceb144fb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -286,10 +286,6 @@ static void apci3120_set_chanlist(struct comedi_device *dev, struct apci3120_private *devpriv = dev->private; int i; - /* set scan length (PR) and scan start (PA) */ - devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); - /* set chanlist for scan */ for (i = 0; i < n_chan; i++) { unsigned int chan = CR_CHAN(chanlist[i]); @@ -307,6 +303,10 @@ static void apci3120_set_chanlist(struct comedi_device *dev, } apci3120_ai_reset_fifo(dev); + + /* set scan length (PR) and scan start (PA) */ + devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } #include "addi-data/hwdrv_apci3120.c" -- GitLab From fdeb2f548790074dd7f9c39275b727ad00600af8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:56 -0700 Subject: [PATCH 3801/9457] staging: comedi: addi_apci_3120: enable chanlist scanning if needed The 'SCAN_ENA' bit in the mode register needs to be set if the chanlist has more than 1 channel. Set the bit in apci3120_set_chanlist() if needed. The callers write the mode register after setting any additional bits, Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f258ceb144fb..ec6623372721 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -307,6 +307,10 @@ static void apci3120_set_chanlist(struct comedi_device *dev, /* set scan length (PR) and scan start (PA) */ devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + + /* enable chanlist scanning if necessary */ + if (n_chan > 1) + devpriv->mode |= APCI3120_MODE_SCAN_ENA; } #include "addi-data/hwdrv_apci3120.c" -- GitLab From 28215c69885fa86be8b5e8f7269edfb4f8c1c480 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:57 -0700 Subject: [PATCH 3802/9457] staging: comedi: addi_apci_3120: tidy up devpriv->mode in apci3120_ai_cmd() There is no reason for the separate updates of the mode register in this function. Refactor the code so that the mode register is only updated at the end of the function after all the necessary bits have been set. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 95a1b7dad397..c7f6130ff6a1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -373,8 +373,9 @@ static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_cmd *cmd = &s->async->cmd; unsigned int divisor; - devpriv->mode = 0; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + /* set default mode bits */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, @@ -415,11 +416,9 @@ static int apci3120_ai_cmd(struct comedi_device *dev, devpriv->b_InterruptMode = APCI3120_DMA_MODE; apci3120_setup_dma(dev, s); } else { - /* disable EOC and enable EOS */ devpriv->b_InterruptMode = APCI3120_EOS_MODE; devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); if (cmd->stop_src == TRIG_COUNT) { /* @@ -439,13 +438,15 @@ static int apci3120_ai_cmd(struct comedi_device *dev, devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER | APCI3120_MODE_TIMER2_CLK_EOS | APCI3120_MODE_TIMER2_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); devpriv->b_Timer2Mode = APCI3120_COUNTER; devpriv->b_Timer2Interrupt = 1; } } + /* set mode to enable acquisition */ + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + if (cmd->scan_begin_src == TRIG_TIMER) apci3120_timer_enable(dev, 1, true); apci3120_timer_enable(dev, 0, true); -- GitLab From b278ea3cefc78bd3b5035b9db0c58ddcc5039de3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:58 -0700 Subject: [PATCH 3803/9457] staging: comedi: addi_apci_3120: remove private data 'b_InterruptMode' This member of the private data is not really needed. The interrupt mode can be determined by checking the devpriv->mode value to see if the interrupt is enabled. Remove the unnecessary member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 18 +++--------------- .../staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c7f6130ff6a1..84600d4788c4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -74,10 +74,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_START 1 #define APCI3120_STOP 0 -#define APCI3120_EOC_MODE 1 -#define APCI3120_EOS_MODE 2 -#define APCI3120_DMA_MODE 3 - #define APCI3120_RD_FIFO 0x00 /* software trigger dummy register */ @@ -97,8 +93,6 @@ static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - /* variables used in timer subdevice */ devpriv->b_Timer2Mode = 0; devpriv->b_Timer2Interrupt = 0; @@ -145,8 +139,6 @@ static int apci3120_cancel(struct comedi_device *dev, inw(dev->iobase + APCI3120_STATUS_REG); devpriv->ui_DmaActualBuffer = 0; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - return 0; } @@ -413,11 +405,8 @@ static int apci3120_ai_cmd(struct comedi_device *dev, apci3120_timer_write(dev, 0, divisor); if (devpriv->us_UseDma) { - devpriv->b_InterruptMode = APCI3120_DMA_MODE; apci3120_setup_dma(dev, s); } else { - devpriv->b_InterruptMode = APCI3120_EOS_MODE; - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; if (cmd->stop_src == TRIG_COUNT) { @@ -615,12 +604,12 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); if ((status & APCI3120_STATUS_EOC_INT) == 0 && - devpriv->b_InterruptMode == APCI3120_EOC_MODE) { + (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) { /* nothing to do... EOC mode is not currently used */ } if ((status & APCI3120_STATUS_EOS_INT) && - devpriv->b_InterruptMode == APCI3120_EOS_MODE) { + (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) { unsigned short val; int i; @@ -663,8 +652,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) apci3120_clr_timer2_interrupt(dev); } - if ((status & APCI3120_STATUS_AMCC_INT) && - devpriv->b_InterruptMode == APCI3120_DMA_MODE) { + if (status & APCI3120_STATUS_AMCC_INT) { /* Clear Timer Write TC int */ outl(APCI3120_CLEAR_WRITE_TC_INT, devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ec6623372721..a6ae42fca6c0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -133,7 +133,6 @@ struct apci3120_private { unsigned short ctrl; unsigned char b_Timer2Mode; unsigned char b_Timer2Interrupt; - unsigned char b_InterruptMode; unsigned char b_ExttrigEnable; struct task_struct *tsk_Current; }; -- GitLab From 3431ec2ff5e19bd6690072f91b45bef67ace0ccb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:54:59 -0700 Subject: [PATCH 3804/9457] staging: comedi: addi_apci_3120: remove private data 'b_ExttrigEnable' This member of the private data is not really needed. The devpriv->ctrl value can be checked to determine if the external trigger is enabled. Remove the unnecessary member. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 11 ++--------- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 84600d4788c4..b38bbd31ac0a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -96,7 +96,6 @@ static int apci3120_reset(struct comedi_device *dev) /* variables used in timer subdevice */ devpriv->b_Timer2Mode = 0; devpriv->b_Timer2Interrupt = 0; - devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ /* Disable all interrupts, watchdog for the anolog output */ devpriv->mode = 0; @@ -378,12 +377,8 @@ static int apci3120_ai_cmd(struct comedi_device *dev, /* load chanlist for command scan */ apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); - if (cmd->start_src == TRIG_EXT) { - devpriv->b_ExttrigEnable = 1; + if (cmd->start_src == TRIG_EXT) apci3120_exttrig_enable(dev, true); - } else { - devpriv->b_ExttrigEnable = 0; - } if (cmd->scan_begin_src == TRIG_TIMER) { /* @@ -591,10 +586,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) outl(int_amcc | 0x00ff0000, devpriv->amcc + AMCC_OP_REG_INTCSR); - if (devpriv->b_ExttrigEnable) { + if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) apci3120_exttrig_enable(dev, false); - devpriv->b_ExttrigEnable = 0; - } apci3120_clr_timer2_interrupt(dev); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index a6ae42fca6c0..3900a90b9608 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -133,7 +133,6 @@ struct apci3120_private { unsigned short ctrl; unsigned char b_Timer2Mode; unsigned char b_Timer2Interrupt; - unsigned char b_ExttrigEnable; struct task_struct *tsk_Current; }; -- GitLab From 3ed69b98b9fadb337b9500ec39007e8f448d4861 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:00 -0700 Subject: [PATCH 3805/9457] staging: comedi: addi_apci_3120: introduce apci3120_init_dma() Introduce a helper function to handle the common code that writes the DMA start address and number of acquisitions to the AMCC Add-on registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 75 ++++++------------- 1 file changed, 23 insertions(+), 52 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b38bbd31ac0a..09428446e728 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -210,6 +210,26 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, return 0; } +static void apci3120_init_dma(struct comedi_device *dev, + struct apci3120_dmabuf *dmabuf) +{ + struct apci3120_private *devpriv = dev->private; + + /* DMA Start Address Low */ + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); + outw(dmabuf->hw & 0xffff, devpriv->addon + 2); + /* DMA Start Address High */ + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); + outw((dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); + + /* Nbr of acquisition LOW */ + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); + outw(dmabuf->use_size & 0xffff, devpriv->addon + 2); + /* Nbr of acquisition HIGH */ + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); + outw((dmabuf->use_size >> 16) & 0xffff, devpriv->addon + 2); +} + static void apci3120_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -288,34 +308,7 @@ static void apci3120_setup_dma(struct comedi_device *dev, outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->amcc + APCI3120_AMCC_OP_MCSR); - /* - * 3 - * beginning address of dma buf The 32 bit address of dma buffer - * is converted into two 16 bit addresses Can done by using _attach - * and put into into an array array used may be for differnet pages - */ - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); - outw(dmabuf0->hw & 0xffff, devpriv->addon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); - outw((dmabuf0->hw >> 16) & 0xffff, devpriv->addon + 2); - - /* - * 4 - * amount of bytes to be transferred set transfer count used ADDON - * MWTC register commented testing - */ - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); - outw(dmabuf0->use_size & 0xffff, devpriv->addon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); - outw((dmabuf0->use_size >> 16) & 0xffff, devpriv->addon + 2); + apci3120_init_dma(dev, dmabuf0); /* * 5 @@ -481,21 +474,7 @@ static void apci3120_interrupt_dma(int irq, void *d) outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); /* 0x1000 is out putted in windows driver */ - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); - outw(next_dmabuf->hw & 0xffff, devpriv->addon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); - outw((next_dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); - outw(next_dmabuf->use_size & 0xffff, devpriv->addon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); - outw((next_dmabuf->use_size > 16) & 0xffff, devpriv->addon + 2); + apci3120_init_dma(dev, next_dmabuf); /* * To configure A2P FIFO @@ -543,15 +522,7 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->amcc + AMCC_OP_REG_MCSR); - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); - outw(dmabuf->hw & 0xffff, devpriv->addon + 2); - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); - outw((dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); - - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); - outw(dmabuf->use_size & 0xffff, devpriv->addon + 2); - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); - outw((dmabuf->use_size >> 16) & 0xffff, devpriv->addon + 2); + apci3120_init_dma(dev, dmabuf); /* * To configure A2P FIFO -- GitLab From 83bec8428a40ad783603ce836615abd0f147309f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:01 -0700 Subject: [PATCH 3806/9457] staging: comedi: addi_apci_3120: introduce apci3120_addon_write() Introduce a helper function to handle the common code that writes a 32-bit value to the 16-bit add-on register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 71 ++++++++----------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 09428446e728..b7c83caee0f7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,8 +44,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY * ADDON RELATED ADDITIONS */ /* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 -#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 +#define APCI3120_ENABLE_TRANSFER_ADD_ON 0x12000000 #define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L #define APCI3120_AMWEN_ENABLE 0x02 #define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 @@ -57,12 +56,9 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 /* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C -#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) -#define APCI3120_ADD_ON_MWAR_LOW 0x24 -#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) -#define APCI3120_ADD_ON_MWTC_LOW 0x058 -#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) +#define APCI3120_ADD_ON_MWAR 0x24 +#define APCI3120_ADD_ON_AGCSTS 0x3c +#define APCI3120_ADD_ON_MWTC 0x58 /* AMCC */ #define APCI3120_AMCC_OP_MCSR 0x3C @@ -89,6 +85,20 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_COUNTER 3 +static void apci3120_addon_write(struct comedi_device *dev, + unsigned int val, unsigned int reg) +{ + struct apci3120_private *devpriv = dev->private; + + /* 16-bit interface for AMCC add-on registers */ + + outw(reg, devpriv->addon + 0); + outw(val & 0xffff, devpriv->addon + 2); + + outw(reg + 2, devpriv->addon + 0); + outw((val >> 16) & 0xffff, devpriv->addon + 2); +} + static int apci3120_reset(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; @@ -119,10 +129,7 @@ static int apci3120_cancel(struct comedi_device *dev, outw(0, devpriv->addon + 4); /* Disable Bus Master ADD ON */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); - outw(0, devpriv->addon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); - outw(0, devpriv->addon + 2); + apci3120_addon_write(dev, 0, APCI3120_ADD_ON_AGCSTS); /* Disable BUS Master PCI */ outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); @@ -213,21 +220,11 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, static void apci3120_init_dma(struct comedi_device *dev, struct apci3120_dmabuf *dmabuf) { - struct apci3120_private *devpriv = dev->private; + /* DMA Start Address */ + apci3120_addon_write(dev, dmabuf->hw, APCI3120_ADD_ON_MWAR); - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->addon + 0); - outw(dmabuf->hw & 0xffff, devpriv->addon + 2); - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->addon + 0); - outw((dmabuf->hw >> 16) & 0xffff, devpriv->addon + 2); - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->addon + 0); - outw(dmabuf->use_size & 0xffff, devpriv->addon + 2); - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->addon + 0); - outw((dmabuf->use_size >> 16) & 0xffff, devpriv->addon + 2); + /* Nbr of acquisition */ + apci3120_addon_write(dev, dmabuf->use_size, APCI3120_ADD_ON_MWTC); } static void apci3120_setup_dma(struct comedi_device *dev, @@ -287,13 +284,9 @@ static void apci3120_setup_dma(struct comedi_device *dev, outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, devpriv->amcc + AMCC_OP_REG_AGCSTS); - /* changed since 16 bit interface for add on */ /* ENABLE BUS MASTER */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); - - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); + apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, + APCI3120_ADD_ON_AGCSTS); /* * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux @@ -468,11 +461,8 @@ static void apci3120_interrupt_dma(int irq, void *d) ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; outl(ui_Tmp, devpriv->amcc + AMCC_OP_REG_AGCSTS); - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); /* 0x1000 is out putted in windows driver */ + apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, + APCI3120_ADD_ON_AGCSTS); apci3120_init_dma(dev, next_dmabuf); @@ -510,11 +500,8 @@ static void apci3120_interrupt_dma(int irq, void *d) outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, devpriv->amcc + AMCC_OP_REG_AGCSTS); - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, devpriv->addon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->addon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->addon + 2); + apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, + APCI3120_ADD_ON_AGCSTS); /* * A2P FIFO MANAGEMENT * A2P fifo reset & transfer control enable -- GitLab From 636971fc9c95164d56f3727bd4d694991a9f01c5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:02 -0700 Subject: [PATCH 3807/9457] staging: comedi: addi_apci_3120: use amcc_s5933.h defines Use the defines for the AMCC 5933 PCI controller registers and bits instead of creating private defines in this driver. Move the generic AGCSTS_TC_ENABLE define from this driver to the header. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 151 ++++++------------ drivers/staging/comedi/drivers/amcc_s5933.h | 2 + 2 files changed, 50 insertions(+), 103 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b7c83caee0f7..a38d7997d516 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,29 +44,13 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY * ADDON RELATED ADDITIONS */ /* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON 0x12000000 -#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L #define APCI3120_AMWEN_ENABLE 0x02 #define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L -#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L #define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 #define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 #define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 -/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_MWAR 0x24 -#define APCI3120_ADD_ON_AGCSTS 0x3c -#define APCI3120_ADD_ON_MWTC 0x58 - -/* AMCC */ -#define APCI3120_AMCC_OP_MCSR 0x3C -#define APCI3120_AMCC_OP_REG_INTCSR 0x38 - -/* for transfer count enable bit */ -#define AGCSTS_TC_ENABLE 0x10000000 - #define APCI3120_START 1 #define APCI3120_STOP 0 @@ -128,10 +112,10 @@ static int apci3120_cancel(struct comedi_device *dev, /* Disable A2P Fifo write and AMWEN signal */ outw(0, devpriv->addon + 4); - /* Disable Bus Master ADD ON */ - apci3120_addon_write(dev, 0, APCI3120_ADD_ON_AGCSTS); + /* Add-On - disable bus master */ + apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS); - /* Disable BUS Master PCI */ + /* AMCC - disable bus master */ outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); /* disable all counters, ext trigger, and reset scan */ @@ -220,11 +204,11 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, static void apci3120_init_dma(struct comedi_device *dev, struct apci3120_dmabuf *dmabuf) { - /* DMA Start Address */ - apci3120_addon_write(dev, dmabuf->hw, APCI3120_ADD_ON_MWAR); + /* Add-On - DMA start address */ + apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR); - /* Nbr of acquisition */ - apci3120_addon_write(dev, dmabuf->use_size, APCI3120_ADD_ON_MWTC); + /* Add-On - Number of acquisitions */ + apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC); } static void apci3120_setup_dma(struct comedi_device *dev, @@ -277,70 +261,32 @@ static void apci3120_setup_dma(struct comedi_device *dev, /* Initialize DMA */ - /* - * Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS - * register 1 - */ + /* AMCC- enable transfer count and reset A2P FIFO */ outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, devpriv->amcc + AMCC_OP_REG_AGCSTS); - /* ENABLE BUS MASTER */ - apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, - APCI3120_ADD_ON_AGCSTS); - - /* - * TO VERIFIED BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outw(0x1000, devpriv->addon + 2); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); - /* 2 No change */ - /* A2P FIFO MANAGEMENT */ - /* A2P fifo reset & transfer control enable */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->amcc + APCI3120_AMCC_OP_MCSR); + /* AMCC - enable transfers and reset A2P flags */ + outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, + devpriv->amcc + AMCC_OP_REG_MCSR); apci3120_init_dma(dev, dmabuf0); - /* - * 5 - * To configure A2P FIFO testing outl( - * FIFO_ADVANCE_ON_BYTE_2, devpriv->amcc + AMCC_OP_REG_INTCSR); - */ - - /* A2P FIFO RESET */ - /* - * TO VERIFY BEGIN JK 07.05.04: Comparison between WIN32 and Linux - * driver - */ - outl(0x04000000UL, devpriv->amcc + AMCC_OP_REG_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - - /* - * 6 - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN AMWEN_ENABLE | - * A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ + /* AMCC- reset A2P flags */ + outl(RESET_A2P_FLAGS, devpriv->amcc + AMCC_OP_REG_MCSR); - /* - * 7 - * initialise end of dma interrupt AINT_WRITE_COMPL = - * ENABLE_WRITE_TC_INT(ADDI) - */ - /* A2P FIFO CONFIGURATE, END OF DMA intERRUPT INIT */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | APCI3120_ENABLE_WRITE_TC_INT, + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, devpriv->amcc + AMCC_OP_REG_INTCSR); - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ outw(3, devpriv->addon + 4); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ - /* A2P FIFO RESET */ - /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */ - outl(0x04000000UL, devpriv->amcc + APCI3120_AMCC_OP_MCSR); - /* END JK 07.05.04: Comparison between WIN32 and Linux driver */ + /* AMCC- reset A2P flags */ + outl(RESET_A2P_FLAGS, devpriv->amcc + AMCC_OP_REG_MCSR); } static int apci3120_ai_cmd(struct comedi_device *dev, @@ -354,9 +300,8 @@ static int apci3120_ai_cmd(struct comedi_device *dev, devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | APCI3120_MODE_TIMER2_AS_TIMER; - /* Clear Timer Write TC int */ - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); devpriv->ui_DmaActualBuffer = 0; @@ -438,7 +383,6 @@ static void apci3120_interrupt_dma(int irq, void *d) struct comedi_cmd *cmd = &s->async->cmd; struct apci3120_dmabuf *dmabuf; unsigned int samplesinbuf; - unsigned int ui_Tmp; dmabuf = &devpriv->dmabuf[devpriv->ui_DmaActualBuffer]; @@ -458,11 +402,14 @@ static void apci3120_interrupt_dma(int irq, void *d) next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->amcc + AMCC_OP_REG_AGCSTS); + /* AMCC - enable transfer count and reset A2P FIFO */ + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); - apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, - APCI3120_ADD_ON_AGCSTS); + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, + AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); apci3120_init_dma(dev, next_dmabuf); @@ -472,9 +419,9 @@ static void apci3120_interrupt_dma(int irq, void *d) * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 */ outw(3, devpriv->addon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT, + + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, devpriv->amcc + AMCC_OP_REG_INTCSR); } @@ -493,20 +440,19 @@ static void apci3120_interrupt_dma(int irq, void *d) if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; } else { - /* - * restart DMA if is not used double buffering - * ADDED REINITIALISE THE DMA - */ + /* restart DMA if is not using double buffering */ + + /* AMCC - enable transfer count and reset A2P FIFO */ outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, devpriv->amcc + AMCC_OP_REG_AGCSTS); - apci3120_addon_write(dev, APCI3120_ENABLE_TRANSFER_ADD_ON, - APCI3120_ADD_ON_AGCSTS); - /* - * A2P FIFO MANAGEMENT - * A2P fifo reset & transfer control enable - */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, + AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); + + /* AMCC - enable transfers and reset A2P flags */ + outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, devpriv->amcc + AMCC_OP_REG_MCSR); apci3120_init_dma(dev, dmabuf); @@ -517,9 +463,9 @@ static void apci3120_interrupt_dma(int irq, void *d) * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 */ outw(3, devpriv->addon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT, + + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, devpriv->amcc + AMCC_OP_REG_INTCSR); } } @@ -542,7 +488,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) return IRQ_NONE; } - outl(int_amcc | 0x00ff0000, devpriv->amcc + AMCC_OP_REG_INTCSR); + outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR); if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) apci3120_exttrig_enable(dev, false); @@ -604,9 +550,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } if (status & APCI3120_STATUS_AMCC_INT) { - /* Clear Timer Write TC int */ - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->amcc + APCI3120_AMCC_OP_REG_INTCSR); + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); apci3120_clr_timer2_interrupt(dev); diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h index cf6a497b092c..d4b8c0195bd3 100644 --- a/drivers/staging/comedi/drivers/amcc_s5933.h +++ b/drivers/staging/comedi/drivers/amcc_s5933.h @@ -110,6 +110,8 @@ #define AGCSTS_TCZERO_MASK 0x000000c0 #define AGCSTS_FIFO_ST_MASK 0x0000003f +#define AGCSTS_TC_ENABLE 0x10000000 + #define AGCSTS_RESET_MBFLAGS 0x08000000 #define AGCSTS_RESET_P2A_FIFO 0x04000000 #define AGCSTS_RESET_A2P_FIFO 0x02000000 -- GitLab From 0c63bd5aeab4b3bbd1755d18399e541bcdcf8474 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:03 -0700 Subject: [PATCH 3808/9457] staging: comedi: addi_apci_3120: define the Add-On registers Define the add-On registers and bits and remove the "magic" numbers in the driver. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 40 ++++++++----------- .../staging/comedi/drivers/addi_apci_3120.c | 5 +++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a38d7997d516..0e31537b1848 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,12 +44,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY * ADDON RELATED ADDITIONS */ /* Constant */ -#define APCI3120_AMWEN_ENABLE 0x02 -#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 -#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 -#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 #define APCI3120_START 1 #define APCI3120_STOP 0 @@ -76,11 +71,11 @@ static void apci3120_addon_write(struct comedi_device *dev, /* 16-bit interface for AMCC add-on registers */ - outw(reg, devpriv->addon + 0); - outw(val & 0xffff, devpriv->addon + 2); + outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); - outw(reg + 2, devpriv->addon + 0); - outw((val >> 16) & 0xffff, devpriv->addon + 2); + outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); } static int apci3120_reset(struct comedi_device *dev) @@ -109,7 +104,7 @@ static int apci3120_cancel(struct comedi_device *dev, { struct apci3120_private *devpriv = dev->private; - /* Disable A2P Fifo write and AMWEN signal */ + /* Add-On - disable DMA */ outw(0, devpriv->addon + 4); /* Add-On - disable bus master */ @@ -282,8 +277,9 @@ static void apci3120_setup_dma(struct comedi_device *dev, outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, devpriv->amcc + AMCC_OP_REG_INTCSR); - /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */ - outw(3, devpriv->addon + 4); + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); /* AMCC- reset A2P flags */ outl(RESET_A2P_FLAGS, devpriv->amcc + AMCC_OP_REG_MCSR); @@ -413,12 +409,10 @@ static void apci3120_interrupt_dma(int irq, void *d) apci3120_init_dma(dev, next_dmabuf); - /* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->addon + 4); + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | + APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); /* AMCC - enable write complete (DMA) and set FIFO advance */ outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, @@ -457,12 +451,10 @@ static void apci3120_interrupt_dma(int irq, void *d) apci3120_init_dma(dev, dmabuf); - /* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->addon + 4); + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | + APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); /* AMCC - enable write complete (DMA) and set FIFO advance */ outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3900a90b9608..699ba76c58ae 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -68,6 +68,11 @@ /* * PCI BAR 2 register map (devpriv->addon) */ +#define APCI3120_ADDON_ADDR_REG 0x00 +#define APCI3120_ADDON_DATA_REG 0x02 +#define APCI3120_ADDON_CTRL_REG 0x04 +#define APCI3120_ADDON_CTRL_AMWEN_ENA (1 << 1) +#define APCI3120_ADDON_CTRL_A2P_FIFO_ENA (1 << 0) /* * Board revisions -- GitLab From b7d62cf8123234e2f9eb644fd0be52b48a28075a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:04 -0700 Subject: [PATCH 3809/9457] staging: comedi: addi_apci_3120: move APCI3120_FIFO_ADVANCE_ON_BYTE_2 Move this define to the main driver source and convert it to a bit-shift. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 6 ------ drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0e31537b1848..474b600400f3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -40,12 +40,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY +----------+-----------+------------------------------------------------+ */ -/* - * ADDON RELATED ADDITIONS - */ -/* Constant */ -#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L - #define APCI3120_START 1 #define APCI3120_STOP 0 diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 699ba76c58ae..7ad7621e74e0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -11,6 +11,7 @@ * PCI BAR 0 register map (devpriv->amcc) * see amcc_s5933.h for register and bit defines */ +#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 (1 << 29) /* * PCI BAR 1 register map (dev->iobase) -- GitLab From 994211b6ffe85a92335e199249956a06eac301fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:05 -0700 Subject: [PATCH 3810/9457] staging: comedi: addi_apci_3120: move DMA init code to apci3120_init_dma() Move the common code used to initialize DMA to apci3120_init_dma(). This follows the programming procedure described in the APCI-3120 documentation. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 99 +++++-------------- 1 file changed, 27 insertions(+), 72 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 474b600400f3..78d3597f0a73 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -193,11 +193,33 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, static void apci3120_init_dma(struct comedi_device *dev, struct apci3120_dmabuf *dmabuf) { + struct apci3120_private *devpriv = dev->private; + + /* AMCC - enable transfer count and reset A2P FIFO */ + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); + + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); + + /* AMCC - enable transfers and reset A2P flags */ + outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, + devpriv->amcc + AMCC_OP_REG_MCSR); + /* Add-On - DMA start address */ apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR); /* Add-On - Number of acquisitions */ apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC); + + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, + devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); } static void apci3120_setup_dma(struct comedi_device *dev, @@ -248,35 +270,7 @@ static void apci3120_setup_dma(struct comedi_device *dev, dmabuf0->use_size = dmalen0; dmabuf1->use_size = dmalen1; - /* Initialize DMA */ - - /* AMCC- enable transfer count and reset A2P FIFO */ - outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - devpriv->amcc + AMCC_OP_REG_AGCSTS); - - /* Add-On - enable transfer count and reset A2P FIFO */ - apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - AMCC_OP_REG_AGCSTS); - - /* AMCC - enable transfers and reset A2P flags */ - outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, - devpriv->amcc + AMCC_OP_REG_MCSR); - apci3120_init_dma(dev, dmabuf0); - - /* AMCC- reset A2P flags */ - outl(RESET_A2P_FLAGS, devpriv->amcc + AMCC_OP_REG_MCSR); - - /* AMCC - enable write complete (DMA) and set FIFO advance */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, - devpriv->amcc + AMCC_OP_REG_INTCSR); - - /* Add-On - enable DMA */ - outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, - devpriv->addon + APCI3120_ADDON_CTRL_REG); - - /* AMCC- reset A2P flags */ - outl(RESET_A2P_FLAGS, devpriv->amcc + AMCC_OP_REG_MCSR); } static int apci3120_ai_cmd(struct comedi_device *dev, @@ -386,33 +380,16 @@ static void apci3120_interrupt_dma(int irq, void *d) return; } samplesinbuf = samplesinbuf >> 1; /* number of received samples */ + if (devpriv->b_DmaDoubleBuffer) { - /* switch DMA buffers if is used double buffering */ struct apci3120_dmabuf *next_dmabuf; next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; - /* AMCC - enable transfer count and reset A2P FIFO */ - outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - devpriv->amcc + AMCC_OP_REG_AGCSTS); - - /* Add-On - enable transfer count and reset A2P FIFO */ - apci3120_addon_write(dev, - AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - AMCC_OP_REG_AGCSTS); - + /* start DMA on next buffer */ apci3120_init_dma(dev, next_dmabuf); - - /* Add-On - enable DMA */ - outw(APCI3120_ADDON_CTRL_AMWEN_ENA | - APCI3120_ADDON_CTRL_A2P_FIFO_ENA, - devpriv->addon + APCI3120_ADDON_CTRL_REG); - - /* AMCC - enable write complete (DMA) and set FIFO advance */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, - devpriv->amcc + AMCC_OP_REG_INTCSR); - } + if (samplesinbuf) { comedi_buf_write_samples(s, dmabuf->virt, samplesinbuf); @@ -425,34 +402,12 @@ static void apci3120_interrupt_dma(int irq, void *d) return; } - if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ + if (devpriv->b_DmaDoubleBuffer) { + /* switch dma buffers for next interrupt */ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; } else { /* restart DMA if is not using double buffering */ - - /* AMCC - enable transfer count and reset A2P FIFO */ - outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - devpriv->amcc + AMCC_OP_REG_AGCSTS); - - /* Add-On - enable transfer count and reset A2P FIFO */ - apci3120_addon_write(dev, - AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - AMCC_OP_REG_AGCSTS); - - /* AMCC - enable transfers and reset A2P flags */ - outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, - devpriv->amcc + AMCC_OP_REG_MCSR); - apci3120_init_dma(dev, dmabuf); - - /* Add-On - enable DMA */ - outw(APCI3120_ADDON_CTRL_AMWEN_ENA | - APCI3120_ADDON_CTRL_A2P_FIFO_ENA, - devpriv->addon + APCI3120_ADDON_CTRL_REG); - - /* AMCC - enable write complete (DMA) and set FIFO advance */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, - devpriv->amcc + AMCC_OP_REG_INTCSR); } } -- GitLab From 884218c5a3ab3ebc522b53054019844dcac5fca7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:06 -0700 Subject: [PATCH 3811/9457] staging: comedi: addi_apci_3120: tidy up apci3120_reset() This function is only called during the attach of the driver and it's called after the private data has been kzalloc'd. There is no reason to clear any of the private data members. Simplify the function by just writing '0' to the necessary registers to disable all the interrupt sources and stop the timers. For aesthetics, change the return type to void. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 78d3597f0a73..f5948fd8b421 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -72,25 +72,16 @@ static void apci3120_addon_write(struct comedi_device *dev, outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); } -static int apci3120_reset(struct comedi_device *dev) +static void apci3120_reset(struct comedi_device *dev) { - struct apci3120_private *devpriv = dev->private; - - /* variables used in timer subdevice */ - devpriv->b_Timer2Mode = 0; - devpriv->b_Timer2Interrupt = 0; - - /* Disable all interrupts, watchdog for the anolog output */ - devpriv->mode = 0; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + /* disable all interrupt sources */ + outb(0, dev->iobase + APCI3120_MODE_REG); /* disable all counters, ext trigger, and reset scan */ - devpriv->ctrl = 0; - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + outw(0, dev->iobase + APCI3120_CTRL_REG); + /* clear interrupt status */ inw(dev->iobase + APCI3120_STATUS_REG); - - return 0; } static int apci3120_cancel(struct comedi_device *dev, -- GitLab From ca26b42d4f8c5d9be2a4cc2bf66a19ff71ac036e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:07 -0700 Subject: [PATCH 3812/9457] staging: comedi: addi_apci_3120: move apci3120_reset() to driver source Move this function from the included hwdrv_apci31210.c source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 12 ------------ drivers/staging/comedi/drivers/addi_apci_3120.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f5948fd8b421..c310cf32b1d8 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -72,18 +72,6 @@ static void apci3120_addon_write(struct comedi_device *dev, outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); } -static void apci3120_reset(struct comedi_device *dev) -{ - /* disable all interrupt sources */ - outb(0, dev->iobase + APCI3120_MODE_REG); - - /* disable all counters, ext trigger, and reset scan */ - outw(0, dev->iobase + APCI3120_CTRL_REG); - - /* clear interrupt status */ - inw(dev->iobase + APCI3120_STATUS_REG); -} - static int apci3120_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 7ad7621e74e0..79a96acc8b63 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -491,6 +491,18 @@ static void apci3120_dma_free(struct comedi_device *dev) } } +static void apci3120_reset(struct comedi_device *dev) +{ + /* disable all interrupt sources */ + outb(0, dev->iobase + APCI3120_MODE_REG); + + /* disable all counters, ext trigger, and reset scan */ + outw(0, dev->iobase + APCI3120_CTRL_REG); + + /* clear interrupt status */ + inw(dev->iobase + APCI3120_STATUS_REG); +} + static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context) { -- GitLab From e6539bbc17843b37524fbb419344653bd74b5961 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:08 -0700 Subject: [PATCH 3813/9457] staging: comedi: addi_apci_3120: rename private data 'us_UseDma' Rename this CamelCase member of the private data and convert it to a bit-field. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index c310cf32b1d8..8327e2c26084 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -293,7 +293,7 @@ static int apci3120_ai_cmd(struct comedi_device *dev, apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); apci3120_timer_write(dev, 0, divisor); - if (devpriv->us_UseDma) { + if (devpriv->use_dma) { apci3120_setup_dma(dev, s); } else { devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 79a96acc8b63..00caa1059db1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -129,7 +129,7 @@ struct apci3120_private { unsigned long amcc; unsigned long addon; unsigned int osc_base; - unsigned short us_UseDma; + unsigned int use_dma:1; unsigned char b_DmaDoubleBuffer; unsigned int ui_DmaActualBuffer; struct apci3120_dmabuf dmabuf[2]; @@ -467,7 +467,7 @@ static void apci3120_dma_alloc(struct comedi_device *dev) dmabuf->size = PAGE_SIZE << order; if (i == 0) - devpriv->us_UseDma = 1; + devpriv->use_dma = 1; if (i == 1) devpriv->b_DmaDoubleBuffer = 1; } -- GitLab From d65d73ff5e2973274cc216fe37adc801c900dd20 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:09 -0700 Subject: [PATCH 3814/9457] staging: comedi: addi_apci_3120: rename private data 'b_DmaDoubleBuffer' Rename this CamelCase member of the private data and convert it to a bit-field. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 8327e2c26084..02755066debe 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -360,7 +360,7 @@ static void apci3120_interrupt_dma(int irq, void *d) } samplesinbuf = samplesinbuf >> 1; /* number of received samples */ - if (devpriv->b_DmaDoubleBuffer) { + if (devpriv->use_double_buffer) { struct apci3120_dmabuf *next_dmabuf; next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; @@ -381,7 +381,7 @@ static void apci3120_interrupt_dma(int irq, void *d) return; } - if (devpriv->b_DmaDoubleBuffer) { + if (devpriv->use_double_buffer) { /* switch dma buffers for next interrupt */ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; } else { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 00caa1059db1..f76884559752 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -130,7 +130,7 @@ struct apci3120_private { unsigned long addon; unsigned int osc_base; unsigned int use_dma:1; - unsigned char b_DmaDoubleBuffer; + unsigned int use_double_buffer:1; unsigned int ui_DmaActualBuffer; struct apci3120_dmabuf dmabuf[2]; unsigned char do_bits; @@ -469,7 +469,7 @@ static void apci3120_dma_alloc(struct comedi_device *dev) if (i == 0) devpriv->use_dma = 1; if (i == 1) - devpriv->b_DmaDoubleBuffer = 1; + devpriv->use_double_buffer = 1; } } -- GitLab From d895948eb850131f83f18a2bf2d3c5e53486f7d7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:10 -0700 Subject: [PATCH 3815/9457] staging: comedi: addi_apci_3120: rename private data 'ui_DmaActualBuffer' Rename this CamelCase member of the private data and convert it to a bit-field. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 10 +++++----- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 02755066debe..ec488d163587 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -95,7 +95,7 @@ static int apci3120_cancel(struct comedi_device *dev, outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); inw(dev->iobase + APCI3120_STATUS_REG); - devpriv->ui_DmaActualBuffer = 0; + devpriv->cur_dmabuf = 0; return 0; } @@ -266,7 +266,7 @@ static int apci3120_ai_cmd(struct comedi_device *dev, /* AMCC- Clear write complete interrupt (DMA) */ outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); - devpriv->ui_DmaActualBuffer = 0; + devpriv->cur_dmabuf = 0; /* load chanlist for command scan */ apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); @@ -347,7 +347,7 @@ static void apci3120_interrupt_dma(int irq, void *d) struct apci3120_dmabuf *dmabuf; unsigned int samplesinbuf; - dmabuf = &devpriv->dmabuf[devpriv->ui_DmaActualBuffer]; + dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; samplesinbuf = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); @@ -363,7 +363,7 @@ static void apci3120_interrupt_dma(int irq, void *d) if (devpriv->use_double_buffer) { struct apci3120_dmabuf *next_dmabuf; - next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer]; + next_dmabuf = &devpriv->dmabuf[!devpriv->cur_dmabuf]; /* start DMA on next buffer */ apci3120_init_dma(dev, next_dmabuf); @@ -383,7 +383,7 @@ static void apci3120_interrupt_dma(int irq, void *d) if (devpriv->use_double_buffer) { /* switch dma buffers for next interrupt */ - devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; + devpriv->cur_dmabuf = !devpriv->cur_dmabuf; } else { /* restart DMA if is not using double buffering */ apci3120_init_dma(dev, dmabuf); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f76884559752..eec0cdba1206 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -131,7 +131,7 @@ struct apci3120_private { unsigned int osc_base; unsigned int use_dma:1; unsigned int use_double_buffer:1; - unsigned int ui_DmaActualBuffer; + unsigned int cur_dmabuf:1; struct apci3120_dmabuf dmabuf[2]; unsigned char do_bits; unsigned char timer_mode; -- GitLab From 4646364cc8e6346776828155ab817e254194df62 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:11 -0700 Subject: [PATCH 3816/9457] staging: comedi: addi_apci_3120: don't use timer 2 to count scans Timer 2 can be used to count the number of scans when the cmd->stop_src is TRIG_COUNT. Unfortunately that timer can also be used by userspace and this breaks the async command. Timer 2 also only works for counting the number of scans when DMA is not used. The number of scans is counted by the core using the private data membmer 'scans_done'. Use that to detect the End-Of-Scan for both DMA and none DMA modes. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 51 +++++-------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index ec488d163587..10ab6d89a6d5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -293,35 +293,11 @@ static int apci3120_ai_cmd(struct comedi_device *dev, apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); apci3120_timer_write(dev, 0, divisor); - if (devpriv->use_dma) { + if (devpriv->use_dma) apci3120_setup_dma(dev, s); - } else { + else devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - if (cmd->stop_src == TRIG_COUNT) { - /* - * Timer 2 is used in MODE0 (hardware retriggerable - * one-shot) to count the number of scans. - * - * NOTE: not sure about the -2 value - */ - apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0); - apci3120_timer_write(dev, 2, cmd->stop_arg - 2); - - apci3120_clr_timer2_interrupt(dev); - - apci3120_timer_enable(dev, 2, true); - - /* configure Timer 2 For counting EOS */ - devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER | - APCI3120_MODE_TIMER2_CLK_EOS | - APCI3120_MODE_TIMER2_IRQ_ENA; - - devpriv->b_Timer2Mode = APCI3120_COUNTER; - devpriv->b_Timer2Interrupt = 1; - } - } - /* set mode to enable acquisition */ outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); @@ -343,7 +319,8 @@ static void apci3120_interrupt_dma(int irq, void *d) struct comedi_device *dev = d; struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; struct apci3120_dmabuf *dmabuf; unsigned int samplesinbuf; @@ -373,13 +350,12 @@ static void apci3120_interrupt_dma(int irq, void *d) comedi_buf_write_samples(s, dmabuf->virt, samplesinbuf); if (!(cmd->flags & CMDF_WAKE_EOS)) - s->async->events |= COMEDI_CB_EOS; + async->events |= COMEDI_CB_EOS; } - if (cmd->stop_src == TRIG_COUNT && - s->async->scans_done >= cmd->stop_arg) { - s->async->events |= COMEDI_CB_EOA; + + if ((async->events & COMEDI_CB_CANCEL_MASK) || + (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)) return; - } if (devpriv->use_double_buffer) { /* switch dma buffers for next interrupt */ @@ -395,7 +371,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) struct comedi_device *dev = d; struct apci3120_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - struct comedi_cmd *cmd = &s->async->cmd; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; unsigned int status; unsigned int int_amcc; @@ -442,10 +419,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (status & APCI3120_STATUS_TIMER2_INT) { switch (devpriv->b_Timer2Mode) { case APCI3120_COUNTER: - devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - s->async->events |= COMEDI_CB_EOA; break; case APCI3120_TIMER: @@ -478,6 +451,10 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) /* do some data transfer */ apci3120_interrupt_dma(irq, d); } + + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + comedi_handle_events(dev, s); return IRQ_HANDLED; -- GitLab From ecaf4c41da4ace751f71fbb3df611a6167425b6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:12 -0700 Subject: [PATCH 3817/9457] staging: comedi: addi_apci_3120: define the AI FIFO register Define the offset for the analog input FIFO register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 4 +--- drivers/staging/comedi/drivers/addi_apci_3120.c | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 10ab6d89a6d5..703e4f9b1ba8 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -43,8 +43,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_START 1 #define APCI3120_STOP 0 -#define APCI3120_RD_FIFO 0x00 - /* software trigger dummy register */ #define APCI3120_START_CONVERSION 0x02 @@ -408,7 +406,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) int i; for (i = 0; i < cmd->chanlist_len; i++) { - val = inw(dev->iobase + 0); + val = inw(dev->iobase + APCI3120_AI_FIFO_REG); comedi_buf_write_samples(s, &val, 1); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index eec0cdba1206..322640ee91b5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -16,6 +16,7 @@ /* * PCI BAR 1 register map (dev->iobase) */ +#define APCI3120_AI_FIFO_REG 0x00 #define APCI3120_CTRL_REG 0x00 #define APCI3120_CTRL_EXT_TRIG (1 << 15) #define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) @@ -370,7 +371,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev, if (ret) return ret; - data[i] = inw(dev->iobase + 0); + data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG); } return insn->n; -- GitLab From dcb5e2c4dfa66aea823e37956ed0389491ed35ab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:13 -0700 Subject: [PATCH 3818/9457] staging: comedi: addi_apci_3120: define the AI software trigger register Define the offset for the analog input software trigger register. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 3 --- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 703e4f9b1ba8..0c9a6550f644 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -43,9 +43,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI3120_START 1 #define APCI3120_STOP 0 -/* software trigger dummy register */ -#define APCI3120_START_CONVERSION 0x02 - /* TIMER DEFINE */ #define APCI3120_QUARTZ_A 70 #define APCI3120_QUARTZ_B 50 diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 322640ee91b5..ec2077cb68f0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -22,6 +22,7 @@ #define APCI3120_CTRL_GATE(x) (1 << (12 + (x))) #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8) #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0) +#define APCI3120_AI_SOFTTRIG_REG 0x02 #define APCI3120_STATUS_REG 0x02 #define APCI3120_STATUS_EOC_INT (1 << 15) #define APCI3120_STATUS_AMCC_INT (1 << 14) -- GitLab From 15cf0617c0186c24f8d6ff7fcf2bf505878f351e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:14 -0700 Subject: [PATCH 3819/9457] staging: comedi: addi_apci_3120: fix timer (*insn_read) The timer subdevice in this driver does not follow the comedi API. Fix the (*insn_read) to work correctly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 35 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 15 +++++++- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0c9a6550f644..7c6dec1aaa45 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -608,38 +608,3 @@ static int apci3120_write_insn_timer(struct comedi_device *dev, return insn->n; } - -/* - * Read the Timer value - * - * for Timer: data[0]= Timer constant - * - * for watchdog: data[0] = 0 (still running) - * = 1 (run down) - */ -static int apci3120_read_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - unsigned int status; - - if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) - && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { - dev_err(dev->class_dev, "timer2 not configured\n"); - } - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { - data[0] = apci3120_timer_read(dev, 2); - } else { - /* Read watch dog status */ - status = inw(dev->iobase + APCI3120_STATUS_REG); - if (status & APCI3120_STATUS_TIMER2_INT) { - apci3120_clr_timer2_interrupt(dev); - data[0] = 1; - } else { - data[0] = 0; - } - } - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ec2077cb68f0..c67c10fc7d66 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -447,6 +447,19 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, return insn->n; } +static int apci3120_timer_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int i; + + for (i = 0; i < insn->n; i++) + data[i] = apci3120_timer_read(dev, 2); + + return insn->n; +} + static void apci3120_dma_alloc(struct comedi_device *dev) { struct apci3120_private *devpriv = dev->private; @@ -618,8 +631,8 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->n_chan = 1; s->maxdata = 0x00ffffff; s->insn_write = apci3120_write_insn_timer; - s->insn_read = apci3120_read_insn_timer; s->insn_config = apci3120_config_insn_timer; + s->insn_read = apci3120_timer_insn_read; return 0; } -- GitLab From 6d31274053716b4cac60a6de7eb40aba8adeb9d5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:15 -0700 Subject: [PATCH 3820/9457] staging: comedi: addi_apci_3120: fix timer (*insn_config) The timer subdevice in this driver does not follow the comedi API. Fix the (*insn_config) to correctly arm, disarm, set the mode, and get the status of the timer. Remove the unnecessary, and broken, (*insn_write). The new (*insn_config) does not enable the interrupt for timer 2. Remove the interrupt support code for the timer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 197 +----------------- .../staging/comedi/drivers/addi_apci_3120.c | 85 +++++++- 2 files changed, 83 insertions(+), 199 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 7c6dec1aaa45..b6507427712c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -40,19 +40,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY +----------+-----------+------------------------------------------------+ */ -#define APCI3120_START 1 -#define APCI3120_STOP 0 - -/* TIMER DEFINE */ -#define APCI3120_QUARTZ_A 70 -#define APCI3120_QUARTZ_B 50 -#define APCI3120_TIMER 1 -#define APCI3120_WATCHDOG 2 -#define APCI3120_TIMER_DISABLE 0 -#define APCI3120_TIMER_ENABLE 1 - -#define APCI3120_COUNTER 3 - static void apci3120_addon_write(struct comedi_device *dev, unsigned int val, unsigned int reg) { @@ -385,8 +372,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) apci3120_exttrig_enable(dev, false); - apci3120_clr_timer2_interrupt(dev); - if (int_amcc & MASTER_ABORT_INT) dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); if (int_amcc & TARGET_ABORT_INT) @@ -412,28 +397,10 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) } if (status & APCI3120_STATUS_TIMER2_INT) { - switch (devpriv->b_Timer2Mode) { - case APCI3120_COUNTER: - break; - - case APCI3120_TIMER: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - case APCI3120_WATCHDOG: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - default: - /* disable Timer Interrupt */ - devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - } - + /* + * for safety... + * timer2 interrupts are not enabled in the driver + */ apci3120_clr_timer2_interrupt(dev); } @@ -441,8 +408,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) /* AMCC- Clear write complete interrupt (DMA) */ outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); - apci3120_clr_timer2_interrupt(dev); - /* do some data transfer */ apci3120_interrupt_dma(irq, d); } @@ -454,157 +419,3 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) return IRQ_HANDLED; } - -/* - * Configure Timer 2 - * - * data[0] = TIMER configure as timer - * = WATCHDOG configure as watchdog - * data[1] = Timer constant - * data[2] = Timer2 interrupt (1)enable or(0) disable - */ -static int apci3120_config_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - unsigned int divisor; - - if (!data[1]) - dev_err(dev->class_dev, "No timer constant!\n"); - - devpriv->b_Timer2Interrupt = (unsigned char) data[2]; /* save info whether to enable or disable interrupt */ - - divisor = apci3120_ns_to_timer(dev, 2, data[1], CMDF_ROUND_DOWN); - - apci3120_timer_enable(dev, 2, false); - - /* disable timer 2 interrupt and reset operation mode (timer) */ - devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & - ~APCI3120_MODE_TIMER2_AS_MASK; - - /* Disable Eoc and Eos Interrupts */ - devpriv->mode &= ~APCI3120_MODE_EOC_IRQ_ENA & - ~APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - if (data[0] == APCI3120_TIMER) { /* initialize timer */ - /* Set the Timer 2 in mode 2(Timer) */ - apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE2); - - /* Set timer 2 delay */ - apci3120_timer_write(dev, 2, divisor); - - /* timer2 in Timer mode enabled */ - devpriv->b_Timer2Mode = APCI3120_TIMER; - } else { /* Initialize Watch dog */ - /* Set the Timer 2 in mode 5(Watchdog) */ - apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE5); - - /* Set timer 2 delay */ - apci3120_timer_write(dev, 2, divisor); - - /* watchdog enabled */ - devpriv->b_Timer2Mode = APCI3120_WATCHDOG; - - } - - return insn->n; - -} - -/* - * To start and stop the timer - * - * data[0] = 1 (start) - * = 0 (stop) - * = 2 (write new value) - * data[1] = new value - * - * devpriv->b_Timer2Mode = 0 DISABLE - * = 1 Timer - * = 2 Watch dog - */ -static int apci3120_write_insn_timer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci3120_private *devpriv = dev->private; - unsigned int divisor; - - if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG) - && (devpriv->b_Timer2Mode != APCI3120_TIMER)) { - dev_err(dev->class_dev, "timer2 not configured\n"); - return -EINVAL; - } - - if (data[0] == 2) { /* write new value */ - if (devpriv->b_Timer2Mode != APCI3120_TIMER) { - dev_err(dev->class_dev, - "timer2 not configured in TIMER MODE\n"); - return -EINVAL; - } - } - - switch (data[0]) { - case APCI3120_START: - apci3120_clr_timer2_interrupt(dev); - - if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */ - /* Enable Timer */ - devpriv->mode &= 0x0b; - devpriv->mode |= APCI3120_MODE_TIMER2_AS_TIMER; - } else { /* start watch dog */ - /* Enable WatchDog */ - devpriv->mode &= 0x0b; - devpriv->mode |= APCI3120_MODE_TIMER2_AS_WDOG; - } - - /* enable disable interrupt */ - if (devpriv->b_Timer2Interrupt) { - devpriv->mode |= APCI3120_MODE_TIMER2_IRQ_ENA; - - /* save the task structure to pass info to user */ - devpriv->tsk_Current = current; - } else { - devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA; - } - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - /* start timer */ - if (devpriv->b_Timer2Mode == APCI3120_TIMER) - apci3120_timer_enable(dev, 2, true); - break; - - case APCI3120_STOP: - /* disable timer 2 interrupt and reset operation mode (timer) */ - devpriv->mode &= ~APCI3120_MODE_TIMER2_IRQ_ENA & - ~APCI3120_MODE_TIMER2_AS_MASK; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - apci3120_timer_enable(dev, 2, false); - - apci3120_clr_timer2_interrupt(dev); - break; - - case 2: /* write new value to Timer */ - if (devpriv->b_Timer2Mode != APCI3120_TIMER) { - dev_err(dev->class_dev, - "timer2 not configured in TIMER MODE\n"); - return -EINVAL; - } - - divisor = apci3120_ns_to_timer(dev, 2, data[1], - CMDF_ROUND_DOWN); - - /* Set timer 2 delay */ - apci3120_timer_write(dev, 2, divisor); - break; - default: - return -EINVAL; /* Not a valid input */ - } - - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c67c10fc7d66..806f756685a8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -139,9 +139,6 @@ struct apci3120_private { unsigned char timer_mode; unsigned char mode; unsigned short ctrl; - unsigned char b_Timer2Mode; - unsigned char b_Timer2Interrupt; - struct task_struct *tsk_Current; }; /* @@ -447,6 +444,83 @@ static int apci3120_do_insn_bits(struct comedi_device *dev, return insn->n; } +static int apci3120_timer_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci3120_private *devpriv = dev->private; + unsigned int divisor; + unsigned int status; + unsigned int mode; + unsigned int timer_mode; + + switch (data[0]) { + case INSN_CONFIG_ARM: + apci3120_clr_timer2_interrupt(dev); + divisor = apci3120_ns_to_timer(dev, 2, data[1], + CMDF_ROUND_DOWN); + apci3120_timer_write(dev, 2, divisor); + apci3120_timer_enable(dev, 2, true); + break; + + case INSN_CONFIG_DISARM: + apci3120_timer_enable(dev, 2, false); + apci3120_clr_timer2_interrupt(dev); + break; + + case INSN_CONFIG_GET_COUNTER_STATUS: + data[1] = 0; + data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING | + COMEDI_COUNTER_TERMINAL_COUNT; + + if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) { + data[1] |= COMEDI_COUNTER_ARMED; + data[1] |= COMEDI_COUNTER_COUNTING; + } + status = inw(dev->iobase + APCI3120_STATUS_REG); + if (status & APCI3120_STATUS_TIMER2_INT) { + data[1] &= ~COMEDI_COUNTER_COUNTING; + data[1] |= COMEDI_COUNTER_TERMINAL_COUNT; + } + break; + + case INSN_CONFIG_SET_COUNTER_MODE: + switch (data[1]) { + case I8254_MODE0: + mode = APCI3120_MODE_TIMER2_AS_COUNTER; + timer_mode = APCI3120_TIMER_MODE0; + break; + case I8254_MODE2: + mode = APCI3120_MODE_TIMER2_AS_TIMER; + timer_mode = APCI3120_TIMER_MODE2; + break; + case I8254_MODE4: + mode = APCI3120_MODE_TIMER2_AS_TIMER; + timer_mode = APCI3120_TIMER_MODE4; + break; + case I8254_MODE5: + mode = APCI3120_MODE_TIMER2_AS_WDOG; + timer_mode = APCI3120_TIMER_MODE5; + break; + default: + return -EINVAL; + } + apci3120_timer_enable(dev, 2, false); + apci3120_clr_timer2_interrupt(dev); + apci3120_timer_set_mode(dev, 2, timer_mode); + devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK; + devpriv->mode |= mode; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + break; + + default: + return -EINVAL; + } + + return insn->n; +} + static int apci3120_timer_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -627,11 +701,10 @@ static int apci3120_auto_attach(struct comedi_device *dev, /* Timer subdevice */ s = &dev->subdevices[4]; s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->subdev_flags = SDF_READABLE; s->n_chan = 1; s->maxdata = 0x00ffffff; - s->insn_write = apci3120_write_insn_timer; - s->insn_config = apci3120_config_insn_timer; + s->insn_config = apci3120_timer_insn_config; s->insn_read = apci3120_timer_insn_read; return 0; -- GitLab From 38417cc46f50dcaf9d2f1e6bfd9ff0b3531a9eba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:16 -0700 Subject: [PATCH 3821/9457] staging: comedi: addi_apci_3120: fix cmd->convert_arg vaildation Regardless of the cmd->scan_begin_src, the minimum cmd->convert_arg value is 10000 (10us). Fix the validation in apci3120_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index b6507427712c..3ee1ecd72406 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -118,13 +118,8 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_arg) - err |= cfc_check_trigger_arg_min(&cmd->convert_arg, - 10000); - } else { - err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); - } + /* minimum conversion time per sample is 10us */ + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); -- GitLab From d32fc427e3b39fca4f14c9783969355c07dfdb51 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:17 -0700 Subject: [PATCH 3822/9457] staging: comedi: addi_apci_3120: move AI (*do_cmdtest) to main driver Move apci3120_ai_cmdtest() from the included source file to the main driver source file. Tidy up Step 4 a bit during the move. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 64 ------------------ .../staging/comedi/drivers/addi_apci_3120.c | 67 +++++++++++++++++++ 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3ee1ecd72406..3f401760aac5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -82,70 +82,6 @@ static int apci3120_cancel(struct comedi_device *dev, return 0; } -static int apci3120_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(cmd->start_src); - err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) - return 2; - - /* Step 3: check if arguments are trivially valid */ - - err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - - if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ - err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); - - /* minimum conversion time per sample is 10us */ - err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); - - err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); - err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - - if (cmd->stop_src == TRIG_COUNT) - err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); - else /* TRIG_NONE */ - err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - - if (err) - return 3; - - /* step 4: fix up any arguments */ - - if (cmd->scan_begin_src == TRIG_TIMER && - cmd->scan_begin_arg < cmd->convert_arg * cmd->scan_end_arg) { - cmd->scan_begin_arg = cmd->convert_arg * cmd->scan_end_arg; - err |= -EINVAL; - } - - if (err) - return 4; - - return 0; -} - static void apci3120_init_dma(struct comedi_device *dev, struct apci3120_dmabuf *dmabuf) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 806f756685a8..da7da56a42f6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -318,6 +318,73 @@ static void apci3120_set_chanlist(struct comedi_device *dev, #include "addi-data/hwdrv_apci3120.c" +static int apci3120_ai_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + unsigned int arg; + int err = 0; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); + + /* minimum conversion time per sample is 10us */ + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* Step 4: fix up any arguments */ + + if (cmd->scan_begin_src == TRIG_TIMER) { + /* scan begin must be larger than the scan time */ + arg = cmd->convert_arg * cmd->scan_end_arg; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, arg); + } + + if (err) + return 4; + + /* Step 5: check channel list if it exists */ + + return 0; +} + static int apci3120_ai_eoc(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, -- GitLab From d8cdd97c8f546fbdb13f9f1dd609b94c5008b53a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:18 -0700 Subject: [PATCH 3823/9457] staging: comedi: addi_apci_3120: add copyright information Remove the copyright info from the included source file and add it to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 42 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 23 ++++++++++ 2 files changed, 23 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3f401760aac5..3cbcc0c9fb48 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1,45 +1,3 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -@endverbatim -*/ -/* - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : APCI-3120 | Compiler : GCC | - | Module name : hwdrv_apci3120.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-----------------------------------------------------------------------+ - | Description :APCI3120 Module. Hardware abstraction Layer for APCI3120| - +-----------------------------------------------------------------------+ - | UPDATE'S | - +-----------------------------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - static void apci3120_addon_write(struct comedi_device *dev, unsigned int val, unsigned int reg) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index da7da56a42f6..0591f8b67909 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,3 +1,26 @@ +/* + * addi_apci_3120.c + * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + * + * ADDI-DATA GmbH + * Dieselstrasse 3 + * D-77833 Ottersweier + * Tel: +19(0)7223/9493-0 + * Fax: +49(0)7223/9493-92 + * http://www.addi-data.com + * info@addi-data.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + #include #include #include -- GitLab From 4ba10fc04a0bd461b31cd5032207cb38304d7b63 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:19 -0700 Subject: [PATCH 3824/9457] staging: comedi: addi_apci_3120: remove unnecessary include The header is not needed by this driver. Remove the include. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 0591f8b67909..4f1ec0bc645f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -23,7 +23,6 @@ #include #include -#include #include #include "../comedidev.h" -- GitLab From 0b7defa70227f7c7f313e0ea4f0eeb88c5de79a3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:20 -0700 Subject: [PATCH 3825/9457] staging: comedi: addi_apci_3120: move apci3120_addon_write() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 14 -------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3cbcc0c9fb48..1799833cde32 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1,17 +1,3 @@ -static void apci3120_addon_write(struct comedi_device *dev, - unsigned int val, unsigned int reg) -{ - struct apci3120_private *devpriv = dev->private; - - /* 16-bit interface for AMCC add-on registers */ - - outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG); - outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); - - outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG); - outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); -} - static int apci3120_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 4f1ec0bc645f..dab81cbe79da 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -163,6 +163,20 @@ struct apci3120_private { unsigned short ctrl; }; +static void apci3120_addon_write(struct comedi_device *dev, + unsigned int val, unsigned int reg) +{ + struct apci3120_private *devpriv = dev->private; + + /* 16-bit interface for AMCC add-on registers */ + + outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); + + outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG); + outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); +} + /* * There are three timers on the board. They all use the same base * clock with a fixed prescaler for each timer. The base clock used -- GitLab From ee844c51ef0451ff7646a075710b9646e943f1e7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:21 -0700 Subject: [PATCH 3826/9457] staging: comedi: addi_apci_3120: move apci3120_init_dma() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 32 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 1799833cde32..a241368d79e1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -26,38 +26,6 @@ static int apci3120_cancel(struct comedi_device *dev, return 0; } -static void apci3120_init_dma(struct comedi_device *dev, - struct apci3120_dmabuf *dmabuf) -{ - struct apci3120_private *devpriv = dev->private; - - /* AMCC - enable transfer count and reset A2P FIFO */ - outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - devpriv->amcc + AMCC_OP_REG_AGCSTS); - - /* Add-On - enable transfer count and reset A2P FIFO */ - apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, - AMCC_OP_REG_AGCSTS); - - /* AMCC - enable transfers and reset A2P flags */ - outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, - devpriv->amcc + AMCC_OP_REG_MCSR); - - /* Add-On - DMA start address */ - apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR); - - /* Add-On - Number of acquisitions */ - apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC); - - /* AMCC - enable write complete (DMA) and set FIFO advance */ - outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, - devpriv->amcc + AMCC_OP_REG_INTCSR); - - /* Add-On - enable DMA */ - outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, - devpriv->addon + APCI3120_ADDON_CTRL_REG); -} - static void apci3120_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index dab81cbe79da..d66e91084bf7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -177,6 +177,38 @@ static void apci3120_addon_write(struct comedi_device *dev, outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG); } +static void apci3120_init_dma(struct comedi_device *dev, + struct apci3120_dmabuf *dmabuf) +{ + struct apci3120_private *devpriv = dev->private; + + /* AMCC - enable transfer count and reset A2P FIFO */ + outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + devpriv->amcc + AMCC_OP_REG_AGCSTS); + + /* Add-On - enable transfer count and reset A2P FIFO */ + apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO, + AMCC_OP_REG_AGCSTS); + + /* AMCC - enable transfers and reset A2P flags */ + outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS, + devpriv->amcc + AMCC_OP_REG_MCSR); + + /* Add-On - DMA start address */ + apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR); + + /* Add-On - Number of acquisitions */ + apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC); + + /* AMCC - enable write complete (DMA) and set FIFO advance */ + outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL, + devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* Add-On - enable DMA */ + outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA, + devpriv->addon + APCI3120_ADDON_CTRL_REG); +} + /* * There are three timers on the board. They all use the same base * clock with a fixed prescaler for each timer. The base clock used -- GitLab From 45062492281d2ce9fba14dc700add6abec3e5726 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:22 -0700 Subject: [PATCH 3827/9457] staging: comedi: addi_apci_3120: move apci3120_setup_dma() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 51 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a241368d79e1..771ac870eb87 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -26,57 +26,6 @@ static int apci3120_cancel(struct comedi_device *dev, return 0; } -static void apci3120_setup_dma(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct apci3120_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; - struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; - unsigned int dmalen0 = dmabuf0->size; - unsigned int dmalen1 = dmabuf1->size; - unsigned int scan_bytes; - - scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); - - if (cmd->stop_src == TRIG_COUNT) { - /* - * Must we fill full first buffer? And must we fill - * full second buffer when first is once filled? - */ - if (dmalen0 > (cmd->stop_arg * scan_bytes)) - dmalen0 = cmd->stop_arg * scan_bytes; - else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0)) - dmalen1 = cmd->stop_arg * scan_bytes - dmalen0; - } - - if (cmd->flags & CMDF_WAKE_EOS) { - /* don't we want wake up every scan? */ - if (dmalen0 > scan_bytes) { - dmalen0 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen0 += 2; - } - if (dmalen1 > scan_bytes) { - dmalen1 = scan_bytes; - if (cmd->scan_end_arg & 1) - dmalen1 -= 2; - if (dmalen1 < 4) - dmalen1 = 4; - } - } else { - /* isn't output buff smaller that our DMA buff? */ - if (dmalen0 > s->async->prealloc_bufsz) - dmalen0 = s->async->prealloc_bufsz; - if (dmalen1 > s->async->prealloc_bufsz) - dmalen1 = s->async->prealloc_bufsz; - } - dmabuf0->use_size = dmalen0; - dmabuf1->use_size = dmalen1; - - apci3120_init_dma(dev, dmabuf0); -} - static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d66e91084bf7..b5ac5b8cf05f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -209,6 +209,57 @@ static void apci3120_init_dma(struct comedi_device *dev, devpriv->addon + APCI3120_ADDON_CTRL_REG); } +static void apci3120_setup_dma(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; + struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; + unsigned int dmalen0 = dmabuf0->size; + unsigned int dmalen1 = dmabuf1->size; + unsigned int scan_bytes; + + scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg); + + if (cmd->stop_src == TRIG_COUNT) { + /* + * Must we fill full first buffer? And must we fill + * full second buffer when first is once filled? + */ + if (dmalen0 > (cmd->stop_arg * scan_bytes)) + dmalen0 = cmd->stop_arg * scan_bytes; + else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0)) + dmalen1 = cmd->stop_arg * scan_bytes - dmalen0; + } + + if (cmd->flags & CMDF_WAKE_EOS) { + /* don't we want wake up every scan? */ + if (dmalen0 > scan_bytes) { + dmalen0 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen0 += 2; + } + if (dmalen1 > scan_bytes) { + dmalen1 = scan_bytes; + if (cmd->scan_end_arg & 1) + dmalen1 -= 2; + if (dmalen1 < 4) + dmalen1 = 4; + } + } else { + /* isn't output buff smaller that our DMA buff? */ + if (dmalen0 > s->async->prealloc_bufsz) + dmalen0 = s->async->prealloc_bufsz; + if (dmalen1 > s->async->prealloc_bufsz) + dmalen1 = s->async->prealloc_bufsz; + } + dmabuf0->use_size = dmalen0; + dmabuf1->use_size = dmalen1; + + apci3120_init_dma(dev, dmabuf0); +} + /* * There are three timers on the board. They all use the same base * clock with a fixed prescaler for each timer. The base clock used -- GitLab From 18e3b50367c68fa2cbb7a93d4aa8393fcedcbab3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:23 -0700 Subject: [PATCH 3828/9457] staging: comedi: addi_apci_3120: move apci3120_ai_cmd() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 56 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 771ac870eb87..396aa47a6b08 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -26,62 +26,6 @@ static int apci3120_cancel(struct comedi_device *dev, return 0; } -static int apci3120_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct apci3120_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - unsigned int divisor; - - /* set default mode bits */ - devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | - APCI3120_MODE_TIMER2_AS_TIMER; - - /* AMCC- Clear write complete interrupt (DMA) */ - outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); - - devpriv->cur_dmabuf = 0; - - /* load chanlist for command scan */ - apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); - - if (cmd->start_src == TRIG_EXT) - apci3120_exttrig_enable(dev, true); - - if (cmd->scan_begin_src == TRIG_TIMER) { - /* - * Timer 1 is used in MODE2 (rate generator) to set the - * start time for each scan. - */ - divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, - cmd->flags); - apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); - apci3120_timer_write(dev, 1, divisor); - } - - /* - * Timer 0 is used in MODE2 (rate generator) to set the conversion - * time for each acquisition. - */ - divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); - apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); - apci3120_timer_write(dev, 0, divisor); - - if (devpriv->use_dma) - apci3120_setup_dma(dev, s); - else - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - - /* set mode to enable acquisition */ - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - if (cmd->scan_begin_src == TRIG_TIMER) - apci3120_timer_enable(dev, 1, true); - apci3120_timer_enable(dev, 0, true); - - return 0; -} - /* * This is a handler for the DMA interrupt. * This function copies the data to Comedi Buffer. diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index b5ac5b8cf05f..8fd498d0031a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -437,6 +437,62 @@ static void apci3120_set_chanlist(struct comedi_device *dev, #include "addi-data/hwdrv_apci3120.c" +static int apci3120_ai_cmd(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int divisor; + + /* set default mode bits */ + devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC | + APCI3120_MODE_TIMER2_AS_TIMER; + + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); + + devpriv->cur_dmabuf = 0; + + /* load chanlist for command scan */ + apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist); + + if (cmd->start_src == TRIG_EXT) + apci3120_exttrig_enable(dev, true); + + if (cmd->scan_begin_src == TRIG_TIMER) { + /* + * Timer 1 is used in MODE2 (rate generator) to set the + * start time for each scan. + */ + divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg, + cmd->flags); + apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2); + apci3120_timer_write(dev, 1, divisor); + } + + /* + * Timer 0 is used in MODE2 (rate generator) to set the conversion + * time for each acquisition. + */ + divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags); + apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2); + apci3120_timer_write(dev, 0, divisor); + + if (devpriv->use_dma) + apci3120_setup_dma(dev, s); + else + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; + + /* set mode to enable acquisition */ + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + if (cmd->scan_begin_src == TRIG_TIMER) + apci3120_timer_enable(dev, 1, true); + apci3120_timer_enable(dev, 0, true); + + return 0; +} + static int apci3120_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) -- GitLab From a68809bb8d97f6df3296298e932f07b33e939d00 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:24 -0700 Subject: [PATCH 3829/9457] staging: comedi: addi_apci_3120: use async->events to report hardware error In apci3120_interrupt_dma(), use the async->events to report the hardware error and allow the core to (*cancel) the command instead of calling the (*cancel) function directly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 396aa47a6b08..505901c6ec2a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -50,7 +50,7 @@ static void apci3120_interrupt_dma(int irq, void *d) dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); if (samplesinbuf & 1) { dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); - apci3120_cancel(dev, s); + async->events |= COMEDI_CB_ERROR; return; } samplesinbuf = samplesinbuf >> 1; /* number of received samples */ -- GitLab From 676caedabd62f23ce345c044de30ca3051d8d41b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:25 -0700 Subject: [PATCH 3830/9457] staging: comedi: addi_apci_3120: move apci3120_cancel() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 28 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 505901c6ec2a..66e71d5193a2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1,31 +1,3 @@ -static int apci3120_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct apci3120_private *devpriv = dev->private; - - /* Add-On - disable DMA */ - outw(0, devpriv->addon + 4); - - /* Add-On - disable bus master */ - apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS); - - /* AMCC - disable bus master */ - outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); - - /* disable all counters, ext trigger, and reset scan */ - devpriv->ctrl = 0; - outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); - - /* DISABLE_ALL_INTERRUPT */ - devpriv->mode = 0; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - - inw(dev->iobase + APCI3120_STATUS_REG); - devpriv->cur_dmabuf = 0; - - return 0; -} - /* * This is a handler for the DMA interrupt. * This function copies the data to Comedi Buffer. diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 8fd498d0031a..fd5306efc021 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -560,6 +560,34 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev, return 0; } +static int apci3120_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci3120_private *devpriv = dev->private; + + /* Add-On - disable DMA */ + outw(0, devpriv->addon + 4); + + /* Add-On - disable bus master */ + apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS); + + /* AMCC - disable bus master */ + outl(0, devpriv->amcc + AMCC_OP_REG_MCSR); + + /* disable all counters, ext trigger, and reset scan */ + devpriv->ctrl = 0; + outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); + + /* DISABLE_ALL_INTERRUPT */ + devpriv->mode = 0; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + + inw(dev->iobase + APCI3120_STATUS_REG); + devpriv->cur_dmabuf = 0; + + return 0; +} + static int apci3120_ai_eoc(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, -- GitLab From 76e6047088b75b773893ee23d4134ca7dc192c16 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:26 -0700 Subject: [PATCH 3831/9457] staging: comedi: addi_apci_3120: move apci3120_interrupt() to driver Move this function from the included source file to the main driver source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 72 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 72 +++++++++++++++++++ 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 66e71d5193a2..f18622c52e16 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -55,75 +55,3 @@ static void apci3120_interrupt_dma(int irq, void *d) apci3120_init_dma(dev, dmabuf); } } - -static irqreturn_t apci3120_interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct apci3120_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - unsigned int status; - unsigned int int_amcc; - - status = inw(dev->iobase + APCI3120_STATUS_REG); - int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); - - if (!(status & APCI3120_STATUS_INT_MASK) && - !(int_amcc & ANY_S593X_INT)) { - dev_err(dev->class_dev, "IRQ from unknown source\n"); - return IRQ_NONE; - } - - outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR); - - if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) - apci3120_exttrig_enable(dev, false); - - if (int_amcc & MASTER_ABORT_INT) - dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); - if (int_amcc & TARGET_ABORT_INT) - dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); - - if ((status & APCI3120_STATUS_EOC_INT) == 0 && - (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) { - /* nothing to do... EOC mode is not currently used */ - } - - if ((status & APCI3120_STATUS_EOS_INT) && - (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) { - unsigned short val; - int i; - - for (i = 0; i < cmd->chanlist_len; i++) { - val = inw(dev->iobase + APCI3120_AI_FIFO_REG); - comedi_buf_write_samples(s, &val, 1); - } - - devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; - outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); - } - - if (status & APCI3120_STATUS_TIMER2_INT) { - /* - * for safety... - * timer2 interrupts are not enabled in the driver - */ - apci3120_clr_timer2_interrupt(dev); - } - - if (status & APCI3120_STATUS_AMCC_INT) { - /* AMCC- Clear write complete interrupt (DMA) */ - outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); - - /* do some data transfer */ - apci3120_interrupt_dma(irq, d); - } - - if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) - async->events |= COMEDI_CB_EOA; - - comedi_handle_events(dev, s); - - return IRQ_HANDLED; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index fd5306efc021..fce177bd2db2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -437,6 +437,78 @@ static void apci3120_set_chanlist(struct comedi_device *dev, #include "addi-data/hwdrv_apci3120.c" +static irqreturn_t apci3120_interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + struct apci3120_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int status; + unsigned int int_amcc; + + status = inw(dev->iobase + APCI3120_STATUS_REG); + int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); + + if (!(status & APCI3120_STATUS_INT_MASK) && + !(int_amcc & ANY_S593X_INT)) { + dev_err(dev->class_dev, "IRQ from unknown source\n"); + return IRQ_NONE; + } + + outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR); + + if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG) + apci3120_exttrig_enable(dev, false); + + if (int_amcc & MASTER_ABORT_INT) + dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n"); + if (int_amcc & TARGET_ABORT_INT) + dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n"); + + if ((status & APCI3120_STATUS_EOC_INT) == 0 && + (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) { + /* nothing to do... EOC mode is not currently used */ + } + + if ((status & APCI3120_STATUS_EOS_INT) && + (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) { + unsigned short val; + int i; + + for (i = 0; i < cmd->chanlist_len; i++) { + val = inw(dev->iobase + APCI3120_AI_FIFO_REG); + comedi_buf_write_samples(s, &val, 1); + } + + devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA; + outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG); + } + + if (status & APCI3120_STATUS_TIMER2_INT) { + /* + * for safety... + * timer2 interrupts are not enabled in the driver + */ + apci3120_clr_timer2_interrupt(dev); + } + + if (status & APCI3120_STATUS_AMCC_INT) { + /* AMCC- Clear write complete interrupt (DMA) */ + outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); + + /* do some data transfer */ + apci3120_interrupt_dma(irq, d); + } + + if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + + comedi_handle_events(dev, s); + + return IRQ_HANDLED; +} + static int apci3120_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { -- GitLab From c78a1f487028775b146e3be89690f19b845409b7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:27 -0700 Subject: [PATCH 3832/9457] staging: comedi: addi_apci_3120: use comedi_bytes_to_samples() Use the helper function to calculate the number of samples in the DMA buffer. For aesthetics, tidy up the local variables. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f18622c52e16..c6008711c3d3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -12,20 +12,21 @@ static void apci3120_interrupt_dma(int irq, void *d) struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; struct apci3120_dmabuf *dmabuf; - unsigned int samplesinbuf; + unsigned int nbytes; + unsigned int nsamples; dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; - samplesinbuf = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); + nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); - if (samplesinbuf < dmabuf->use_size) + if (nbytes < dmabuf->use_size) dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); - if (samplesinbuf & 1) { + if (nbytes & 1) { dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); async->events |= COMEDI_CB_ERROR; return; } - samplesinbuf = samplesinbuf >> 1; /* number of received samples */ + nsamples = comedi_bytes_to_samples(s, nbytes); if (devpriv->use_double_buffer) { struct apci3120_dmabuf *next_dmabuf; @@ -36,8 +37,8 @@ static void apci3120_interrupt_dma(int irq, void *d) apci3120_init_dma(dev, next_dmabuf); } - if (samplesinbuf) { - comedi_buf_write_samples(s, dmabuf->virt, samplesinbuf); + if (nsamples) { + comedi_buf_write_samples(s, dmabuf->virt, nsamples); if (!(cmd->flags & CMDF_WAKE_EOS)) async->events |= COMEDI_CB_EOS; -- GitLab From cd68e0e2d00501ff7e59c8213bfb9bd31d42c820 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:28 -0700 Subject: [PATCH 3833/9457] staging: comedi: addi_apci_3120: move apci3120_interrupt_dma() to driver Move this function from the included source file to the main driver source file. Remove the now empty included source file. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 58 ------------------- .../staging/comedi/drivers/addi_apci_3120.c | 53 ++++++++++++++++- 2 files changed, 52 insertions(+), 59 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c deleted file mode 100644 index c6008711c3d3..000000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This is a handler for the DMA interrupt. - * This function copies the data to Comedi Buffer. - * For continuous DMA it reinitializes the DMA operation. - * For single mode DMA it stop the acquisition. - */ -static void apci3120_interrupt_dma(int irq, void *d) -{ - struct comedi_device *dev = d; - struct apci3120_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async = s->async; - struct comedi_cmd *cmd = &async->cmd; - struct apci3120_dmabuf *dmabuf; - unsigned int nbytes; - unsigned int nsamples; - - dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; - - nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); - - if (nbytes < dmabuf->use_size) - dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); - if (nbytes & 1) { - dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); - async->events |= COMEDI_CB_ERROR; - return; - } - nsamples = comedi_bytes_to_samples(s, nbytes); - - if (devpriv->use_double_buffer) { - struct apci3120_dmabuf *next_dmabuf; - - next_dmabuf = &devpriv->dmabuf[!devpriv->cur_dmabuf]; - - /* start DMA on next buffer */ - apci3120_init_dma(dev, next_dmabuf); - } - - if (nsamples) { - comedi_buf_write_samples(s, dmabuf->virt, nsamples); - - if (!(cmd->flags & CMDF_WAKE_EOS)) - async->events |= COMEDI_CB_EOS; - } - - if ((async->events & COMEDI_CB_CANCEL_MASK) || - (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)) - return; - - if (devpriv->use_double_buffer) { - /* switch dma buffers for next interrupt */ - devpriv->cur_dmabuf = !devpriv->cur_dmabuf; - } else { - /* restart DMA if is not using double buffering */ - apci3120_init_dma(dev, dmabuf); - } -} diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index fce177bd2db2..9bdd7277caa1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -435,7 +435,58 @@ static void apci3120_set_chanlist(struct comedi_device *dev, devpriv->mode |= APCI3120_MODE_SCAN_ENA; } -#include "addi-data/hwdrv_apci3120.c" +static void apci3120_interrupt_dma(int irq, void *d) +{ + struct comedi_device *dev = d; + struct apci3120_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + struct apci3120_dmabuf *dmabuf; + unsigned int nbytes; + unsigned int nsamples; + + dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; + + nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC); + + if (nbytes < dmabuf->use_size) + dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); + if (nbytes & 1) { + dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); + async->events |= COMEDI_CB_ERROR; + return; + } + nsamples = comedi_bytes_to_samples(s, nbytes); + + if (devpriv->use_double_buffer) { + struct apci3120_dmabuf *next_dmabuf; + + next_dmabuf = &devpriv->dmabuf[!devpriv->cur_dmabuf]; + + /* start DMA on next buffer */ + apci3120_init_dma(dev, next_dmabuf); + } + + if (nsamples) { + comedi_buf_write_samples(s, dmabuf->virt, nsamples); + + if (!(cmd->flags & CMDF_WAKE_EOS)) + async->events |= COMEDI_CB_EOS; + } + + if ((async->events & COMEDI_CB_CANCEL_MASK) || + (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)) + return; + + if (devpriv->use_double_buffer) { + /* switch dma buffers for next interrupt */ + devpriv->cur_dmabuf = !devpriv->cur_dmabuf; + } else { + /* restart DMA if is not using double buffering */ + apci3120_init_dma(dev, dmabuf); + } +} static irqreturn_t apci3120_interrupt(int irq, void *d) { -- GitLab From a93a0e9a30e7702229f68e516dc270507159f23b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:29 -0700 Subject: [PATCH 3834/9457] staging: comedi: addi_apci_3120: change params to apci3120_interrupt_dma() Pass the comedi_device and comedi_subdevice pointers to this function instead of the irq number and void pointer. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9bdd7277caa1..ea53694e0d32 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -435,11 +435,10 @@ static void apci3120_set_chanlist(struct comedi_device *dev, devpriv->mode |= APCI3120_MODE_SCAN_ENA; } -static void apci3120_interrupt_dma(int irq, void *d) +static void apci3120_interrupt_dma(struct comedi_device *dev, + struct comedi_subdevice *s) { - struct comedi_device *dev = d; struct apci3120_private *devpriv = dev->private; - struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; struct apci3120_dmabuf *dmabuf; @@ -549,7 +548,7 @@ static irqreturn_t apci3120_interrupt(int irq, void *d) outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR); /* do some data transfer */ - apci3120_interrupt_dma(irq, d); + apci3120_interrupt_dma(dev, s); } if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) -- GitLab From f50205f0478c35d9d6f3cc3e315ccdfcdaba17e4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:30 -0700 Subject: [PATCH 3835/9457] staging: comedi: addi_apci_3120: switch DMA buffers after writing samples Currently the DMA buffers are switched before writing the current samples to the async buffer. This works but when the EOA event happens we end up with an outstanding DMA operation in progress that gets terminated by the (*cancel). Avoid the outstanding DMA operation by switching the DMA buffers after writing the samples. The driver will detect the EOA event and not retart the DMA. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ea53694e0d32..ba96fe5910e1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -456,17 +456,8 @@ static void apci3120_interrupt_dma(struct comedi_device *dev, async->events |= COMEDI_CB_ERROR; return; } - nsamples = comedi_bytes_to_samples(s, nbytes); - - if (devpriv->use_double_buffer) { - struct apci3120_dmabuf *next_dmabuf; - - next_dmabuf = &devpriv->dmabuf[!devpriv->cur_dmabuf]; - - /* start DMA on next buffer */ - apci3120_init_dma(dev, next_dmabuf); - } + nsamples = comedi_bytes_to_samples(s, nbytes); if (nsamples) { comedi_buf_write_samples(s, dmabuf->virt, nsamples); @@ -479,10 +470,12 @@ static void apci3120_interrupt_dma(struct comedi_device *dev, return; if (devpriv->use_double_buffer) { - /* switch dma buffers for next interrupt */ + /* switch DMA buffers for next interrupt */ devpriv->cur_dmabuf = !devpriv->cur_dmabuf; + dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf]; + apci3120_init_dma(dev, dmabuf); } else { - /* restart DMA if is not using double buffering */ + /* restart DMA if not using double buffering */ apci3120_init_dma(dev, dmabuf); } } -- GitLab From c58f9bb622ca06387200a6f9ef77cdc5c531dfb2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:31 -0700 Subject: [PATCH 3836/9457] staging: comedi: addi_apci_3120: enable AI async commands The async command support should now work. Enable the hook up of the command support functions in apci3120_auto_attach(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index ba96fe5910e1..f00b9ba070b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1038,7 +1038,7 @@ static int apci3120_auto_attach(struct comedi_device *dev, s->maxdata = this_board->ai_is_16bit ? 0xffff : 0x0fff; s->range_table = &apci3120_ai_range; s->insn_read = apci3120_ai_insn_read; - if (0 /* dev->irq */) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->len_chanlist = s->n_chan; -- GitLab From 34216792e006d70bcfdf1931e24e4eb2e2af9498 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 4 Nov 2014 10:55:32 -0700 Subject: [PATCH 3837/9457] staging: comedi: addi_apci_3120: absorb apci3120_ai_reset_fifo() This function is only called by apci3120_set_chanlist(). Absorb it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f00b9ba070b7..e9816e7a235d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -395,12 +395,6 @@ static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable) outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG); } -static void apci3120_ai_reset_fifo(struct comedi_device *dev) -{ - /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */ - inw(dev->iobase + APCI3120_TIMER_MODE_REG); -} - static void apci3120_set_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist) @@ -424,7 +418,8 @@ static void apci3120_set_chanlist(struct comedi_device *dev, outw(val, dev->iobase + APCI3120_CHANLIST_REG); } - apci3120_ai_reset_fifo(dev); + /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */ + inw(dev->iobase + APCI3120_TIMER_MODE_REG); /* set scan length (PR) and scan start (PA) */ devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0); -- GitLab From 0a88818d093b4d5746d7b3af3acc2b2bddd59808 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 3 Nov 2014 14:37:38 +0100 Subject: [PATCH 3838/9457] drm/i915: Check pipe_config.has_dp_encoder instead of encoder types More concise. Noticed while reviewing Ander's patch which touched a lot of the pipe_has_type checks. v2: Use new_config in one place Ander spotted. Cc: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6bd290d902df..96663eb37533 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3786,9 +3786,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) intel_fdi_normal_train(crtc); /* For PCH DP, enable TRANS_DP_CTL */ - if (HAS_PCH_CPT(dev) && - (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_EDP))) { + if (HAS_PCH_CPT(dev) && intel_crtc->config.has_dp_encoder) { u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5; reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); @@ -5867,8 +5865,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x00d0000f); - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { + if (crtc->config.has_dp_encoder) { /* Use SSC source */ if (pipe == PIPE_A) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe), @@ -6058,7 +6055,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc, if (is_sdvo) dpll |= DPLL_SDVO_HIGH_SPEED; - if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (crtc->new_config->has_dp_encoder) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ -- GitLab From 1e6f2ddc88fec990ef4fb1aa3b7cb9941df0321b Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:31 +0200 Subject: [PATCH 3839/9457] drm/i915: Convert shared dpll reference count to a crtc mask This will be used in a follow up patch to properly release shared DPLLs without relying on the shared_dpll field in pipe_config. v2: Fix white space error (Ville) Use hweight32() (Ville) Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 50 +++++++++++++++------------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a79f83ce9c84..ce32ae788c3c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2630,8 +2630,8 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id); - seq_printf(m, " refcount: %i, active: %i, on: %s\n", pll->refcount, - pll->active, yesno(pll->on)); + seq_printf(m, " crtc_mask: 0x%08x, active: %d, on: %s\n", + pll->crtc_mask, pll->active, yesno(pll->on)); seq_printf(m, " tracked hardware state:\n"); seq_printf(m, " dpll: 0x%08x\n", pll->hw_state.dpll); seq_printf(m, " dpll_md: 0x%08x\n", pll->hw_state.dpll_md); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0e12c6ac2be5..4f4eef701ce0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -230,7 +230,7 @@ struct intel_dpll_hw_state { }; struct intel_shared_dpll { - int refcount; /* count of number of CRTCs sharing this PLL */ + unsigned crtc_mask; /* mask of CRTCs sharing this PLL */ int active; /* count of number of active CRTCs (i.e. DPMS on) */ bool on; /* is the PLL actually active? Disabled during modeset */ const char *name; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 96663eb37533..5219b29719ad 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1779,7 +1779,7 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - WARN_ON(!pll->refcount); + WARN_ON(!pll->crtc_mask); if (pll->active == 0) { DRM_DEBUG_DRIVER("setting up %s\n", pll->name); WARN_ON(pll->on); @@ -1806,7 +1806,7 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - if (WARN_ON(pll->refcount == 0)) + if (WARN_ON(pll->crtc_mask == 0)) return; DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", @@ -1838,7 +1838,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - if (WARN_ON(pll->refcount == 0)) + if (WARN_ON(pll->crtc_mask == 0)) return; DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", @@ -3846,12 +3846,13 @@ void intel_put_shared_dpll(struct intel_crtc *crtc) if (pll == NULL) return; - if (pll->refcount == 0) { - WARN(1, "bad %s refcount\n", pll->name); + if (!(pll->crtc_mask & (1 << crtc->pipe))) { + WARN(1, "bad %s crtc mask\n", pll->name); return; } - if (--pll->refcount == 0) { + pll->crtc_mask &= ~(1 << crtc->pipe); + if (pll->crtc_mask == 0) { WARN_ON(pll->on); WARN_ON(pll->active); } @@ -3879,7 +3880,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", crtc->base.base.id, pll->name); - WARN_ON(pll->refcount); + WARN_ON(pll->crtc_mask); goto found; } @@ -3888,14 +3889,15 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) pll = &dev_priv->shared_dplls[i]; /* Only want to check enabled timings first */ - if (pll->refcount == 0) + if (pll->crtc_mask == 0) continue; if (memcmp(&crtc->config.dpll_hw_state, &pll->hw_state, sizeof(pll->hw_state)) == 0) { - DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n", - crtc->base.base.id, - pll->name, pll->refcount, pll->active); + DRM_DEBUG_KMS("CRTC:%d sharing existing %s " + "(crtc_mask 0x%08x, active %d)\n", + crtc->base.base.id, pll->name, + pll->crtc_mask, pll->active); goto found; } @@ -3904,7 +3906,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) /* Ok no matching timings, maybe there's a free one? */ for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - if (pll->refcount == 0) { + if (pll->crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); goto found; @@ -3914,14 +3916,14 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) return NULL; found: - if (pll->refcount == 0) + if (pll->crtc_mask == 0) pll->hw_state = crtc->config.dpll_hw_state; crtc->config.shared_dpll = i; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - pll->refcount++; + pll->crtc_mask |= 1 << crtc->pipe; return pll; } @@ -10604,9 +10606,9 @@ check_shared_dpll_state(struct drm_device *dev) active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state); - WARN(pll->active > pll->refcount, + WARN(pll->active > hweight32(pll->crtc_mask), "more active pll users than references: %i vs %i\n", - pll->active, pll->refcount); + pll->active, hweight32(pll->crtc_mask)); WARN(pll->active && !pll->on, "pll in active use but not on in sw tracking\n"); WARN(pll->on && !pll->active, @@ -10624,9 +10626,9 @@ check_shared_dpll_state(struct drm_device *dev) WARN(pll->active != active_crtcs, "pll active crtcs mismatch (expected %i, found %i)\n", pll->active, active_crtcs); - WARN(pll->refcount != enabled_crtcs, + WARN(hweight32(pll->crtc_mask) != enabled_crtcs, "pll enabled crtcs mismatch (expected %i, found %i)\n", - pll->refcount, enabled_crtcs); + hweight32(pll->crtc_mask), enabled_crtcs); WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state, sizeof(dpll_hw_state)), @@ -13077,16 +13079,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) pll->on = pll->get_hw_state(dev_priv, pll, &pll->hw_state); pll->active = 0; + pll->crtc_mask = 0; for_each_intel_crtc(dev, crtc) { - if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) { pll->active++; + pll->crtc_mask |= 1 << crtc->pipe; + } } - pll->refcount = pll->active; - DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n", - pll->name, pll->refcount, pll->on); + DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n", + pll->name, pll->crtc_mask, pll->on); - if (pll->refcount) + if (pll->crtc_mask) intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); } -- GitLab From 3e369b76ceb625dffabef6f1c52e32fc0998843e Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:32 +0200 Subject: [PATCH 3840/9457] drm/i915: Move dpll crtc_mask and hw_state fields into separate struct The new struct will be used in a follow up patch to allow a current and a staged config to exist for the same shared DPLL. v2: Rebase on by mask_to_refcount()->hweight32() change. (Damien) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 13 +++--- drivers/gpu/drm/i915/i915_drv.h | 8 +++- drivers/gpu/drm/i915/intel_ddi.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 60 ++++++++++++++-------------- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ce32ae788c3c..0a6981399642 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2631,13 +2631,14 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id); seq_printf(m, " crtc_mask: 0x%08x, active: %d, on: %s\n", - pll->crtc_mask, pll->active, yesno(pll->on)); + pll->config.crtc_mask, pll->active, yesno(pll->on)); seq_printf(m, " tracked hardware state:\n"); - seq_printf(m, " dpll: 0x%08x\n", pll->hw_state.dpll); - seq_printf(m, " dpll_md: 0x%08x\n", pll->hw_state.dpll_md); - seq_printf(m, " fp0: 0x%08x\n", pll->hw_state.fp0); - seq_printf(m, " fp1: 0x%08x\n", pll->hw_state.fp1); - seq_printf(m, " wrpll: 0x%08x\n", pll->hw_state.wrpll); + seq_printf(m, " dpll: 0x%08x\n", pll->config.hw_state.dpll); + seq_printf(m, " dpll_md: 0x%08x\n", + pll->config.hw_state.dpll_md); + seq_printf(m, " fp0: 0x%08x\n", pll->config.hw_state.fp0); + seq_printf(m, " fp1: 0x%08x\n", pll->config.hw_state.fp1); + seq_printf(m, " wrpll: 0x%08x\n", pll->config.hw_state.wrpll); } drm_modeset_unlock_all(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4f4eef701ce0..62a8e058d7db 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -229,14 +229,18 @@ struct intel_dpll_hw_state { uint32_t wrpll; }; -struct intel_shared_dpll { +struct intel_shared_dpll_config { unsigned crtc_mask; /* mask of CRTCs sharing this PLL */ + struct intel_dpll_hw_state hw_state; +}; + +struct intel_shared_dpll { + struct intel_shared_dpll_config config; int active; /* count of number of active CRTCs (i.e. DPMS on) */ bool on; /* is the PLL actually active? Disabled during modeset */ const char *name; /* should match the index in the dev_priv->shared_dplls array */ enum intel_dpll_id id; - struct intel_dpll_hw_state hw_state; /* The mode_set hook is optional and should be used together with the * intel_prepare_shared_dpll function. */ void (*mode_set)(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index d41768846f18..6f9712bba210 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1312,7 +1312,7 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { - I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll); + I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll); POSTING_READ(WRPLL_CTL(pll->id)); udelay(20); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5219b29719ad..5eb475409657 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1779,7 +1779,7 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - WARN_ON(!pll->crtc_mask); + WARN_ON(!pll->config.crtc_mask); if (pll->active == 0) { DRM_DEBUG_DRIVER("setting up %s\n", pll->name); WARN_ON(pll->on); @@ -1806,7 +1806,7 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - if (WARN_ON(pll->crtc_mask == 0)) + if (WARN_ON(pll->config.crtc_mask == 0)) return; DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", @@ -1838,7 +1838,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll == NULL)) return; - if (WARN_ON(pll->crtc_mask == 0)) + if (WARN_ON(pll->config.crtc_mask == 0)) return; DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", @@ -3846,13 +3846,13 @@ void intel_put_shared_dpll(struct intel_crtc *crtc) if (pll == NULL) return; - if (!(pll->crtc_mask & (1 << crtc->pipe))) { + if (!(pll->config.crtc_mask & (1 << crtc->pipe))) { WARN(1, "bad %s crtc mask\n", pll->name); return; } - pll->crtc_mask &= ~(1 << crtc->pipe); - if (pll->crtc_mask == 0) { + pll->config.crtc_mask &= ~(1 << crtc->pipe); + if (pll->config.crtc_mask == 0) { WARN_ON(pll->on); WARN_ON(pll->active); } @@ -3880,7 +3880,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", crtc->base.base.id, pll->name); - WARN_ON(pll->crtc_mask); + WARN_ON(pll->config.crtc_mask); goto found; } @@ -3889,15 +3889,16 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) pll = &dev_priv->shared_dplls[i]; /* Only want to check enabled timings first */ - if (pll->crtc_mask == 0) + if (pll->config.crtc_mask == 0) continue; - if (memcmp(&crtc->config.dpll_hw_state, &pll->hw_state, - sizeof(pll->hw_state)) == 0) { + if (memcmp(&crtc->config.dpll_hw_state, + &pll->config.hw_state, + sizeof(pll->config.hw_state)) == 0) { DRM_DEBUG_KMS("CRTC:%d sharing existing %s " "(crtc_mask 0x%08x, active %d)\n", crtc->base.base.id, pll->name, - pll->crtc_mask, pll->active); + pll->config.crtc_mask, pll->active); goto found; } @@ -3906,7 +3907,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) /* Ok no matching timings, maybe there's a free one? */ for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - if (pll->crtc_mask == 0) { + if (pll->config.crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); goto found; @@ -3916,14 +3917,14 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) return NULL; found: - if (pll->crtc_mask == 0) - pll->hw_state = crtc->config.dpll_hw_state; + if (pll->config.crtc_mask == 0) + pll->config.hw_state = crtc->config.dpll_hw_state; crtc->config.shared_dpll = i; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - pll->crtc_mask |= 1 << crtc->pipe; + pll->config.crtc_mask |= 1 << crtc->pipe; return pll; } @@ -10606,9 +10607,9 @@ check_shared_dpll_state(struct drm_device *dev) active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state); - WARN(pll->active > hweight32(pll->crtc_mask), + WARN(pll->active > hweight32(pll->config.crtc_mask), "more active pll users than references: %i vs %i\n", - pll->active, hweight32(pll->crtc_mask)); + pll->active, hweight32(pll->config.crtc_mask)); WARN(pll->active && !pll->on, "pll in active use but not on in sw tracking\n"); WARN(pll->on && !pll->active, @@ -10626,11 +10627,11 @@ check_shared_dpll_state(struct drm_device *dev) WARN(pll->active != active_crtcs, "pll active crtcs mismatch (expected %i, found %i)\n", pll->active, active_crtcs); - WARN(hweight32(pll->crtc_mask) != enabled_crtcs, + WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs, "pll enabled crtcs mismatch (expected %i, found %i)\n", - hweight32(pll->crtc_mask), enabled_crtcs); + hweight32(pll->config.crtc_mask), enabled_crtcs); - WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state, + WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state, sizeof(dpll_hw_state)), "pll hw state mismatch\n"); } @@ -11305,8 +11306,8 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { - I915_WRITE(PCH_FP0(pll->id), pll->hw_state.fp0); - I915_WRITE(PCH_FP1(pll->id), pll->hw_state.fp1); + I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0); + I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1); } static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, @@ -11315,7 +11316,7 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, /* PCH refclock must be enabled first */ ibx_assert_pch_refclk_enabled(dev_priv); - I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll); + I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); /* Wait for the clocks to stabilize. */ POSTING_READ(PCH_DPLL(pll->id)); @@ -11326,7 +11327,7 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, * * So write it again. */ - I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll); + I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll); POSTING_READ(PCH_DPLL(pll->id)); udelay(200); } @@ -13077,20 +13078,21 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) for (i = 0; i < dev_priv->num_shared_dpll; i++) { struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; - pll->on = pll->get_hw_state(dev_priv, pll, &pll->hw_state); + pll->on = pll->get_hw_state(dev_priv, pll, + &pll->config.hw_state); pll->active = 0; - pll->crtc_mask = 0; + pll->config.crtc_mask = 0; for_each_intel_crtc(dev, crtc) { if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) { pll->active++; - pll->crtc_mask |= 1 << crtc->pipe; + pll->config.crtc_mask |= 1 << crtc->pipe; } } DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n", - pll->name, pll->crtc_mask, pll->on); + pll->name, pll->config.crtc_mask, pll->on); - if (pll->crtc_mask) + if (pll->config.crtc_mask) intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); } -- GitLab From 8bd31e67c9f737216cb25bcc008fed172b8a4375 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:33 +0200 Subject: [PATCH 3841/9457] drm/i915: Add infrastructure for choosing DPLLs before disabling crtcs It is possible for a mode set to fail if there aren't shared DPLLS that match the new configuration requirement or other errors in clock computation. If that step is executed after disabling crtcs, in the failure case the hardware configuration is changed and needs to be restored. Doing those things early will allow the mode set to fail before actually touching the hardware. Follow up patches will convert different platforms to use the new infrastructure. v2: Keep pll->new_config valid only during mode set (Ville) Use kmemdup() in i915_shared_dpll_start_config() (Ville) Restore old pll config if something fails before commit (Ville) Don't set compute_clock hooks since dev_priv is kzalloc()'d (Ville) Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 3 + drivers/gpu/drm/i915/intel_display.c | 142 +++++++++++++++++++++------ 2 files changed, 117 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 62a8e058d7db..4fb93e28b5ac 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -236,6 +236,8 @@ struct intel_shared_dpll_config { struct intel_shared_dpll { struct intel_shared_dpll_config config; + struct intel_shared_dpll_config *new_config; + int active; /* count of number of active CRTCs (i.e. DPMS on) */ bool on; /* is the PLL actually active? Disabled during modeset */ const char *name; @@ -484,6 +486,7 @@ struct drm_i915_display_funcs { struct intel_crtc_config *); void (*get_plane_config)(struct intel_crtc *, struct intel_plane_config *); + int (*crtc_compute_clock)(struct intel_crtc *crtc); int (*crtc_mode_set)(struct intel_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5eb475409657..4253f1288e73 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3863,15 +3863,9 @@ void intel_put_shared_dpll(struct intel_crtc *crtc) struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll; enum intel_dpll_id i; - if (pll) { - DRM_DEBUG_KMS("CRTC:%d dropping existing %s\n", - crtc->base.base.id, pll->name); - intel_put_shared_dpll(crtc); - } - if (HAS_PCH_IBX(dev_priv->dev)) { /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ i = (enum intel_dpll_id) crtc->pipe; @@ -3880,7 +3874,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", crtc->base.base.id, pll->name); - WARN_ON(pll->config.crtc_mask); + WARN_ON(pll->new_config->crtc_mask); goto found; } @@ -3889,17 +3883,16 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) pll = &dev_priv->shared_dplls[i]; /* Only want to check enabled timings first */ - if (pll->config.crtc_mask == 0) + if (pll->new_config->crtc_mask == 0) continue; - if (memcmp(&crtc->config.dpll_hw_state, - &pll->config.hw_state, - sizeof(pll->config.hw_state)) == 0) { - DRM_DEBUG_KMS("CRTC:%d sharing existing %s " - "(crtc_mask 0x%08x, active %d)\n", + if (memcmp(&crtc->new_config->dpll_hw_state, + &pll->new_config->hw_state, + sizeof(pll->new_config->hw_state)) == 0) { + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n", crtc->base.base.id, pll->name, - pll->config.crtc_mask, pll->active); - + pll->new_config->crtc_mask, + pll->active); goto found; } } @@ -3907,7 +3900,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) /* Ok no matching timings, maybe there's a free one? */ for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - if (pll->config.crtc_mask == 0) { + if (pll->new_config->crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); goto found; @@ -3917,18 +3910,85 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) return NULL; found: - if (pll->config.crtc_mask == 0) - pll->config.hw_state = crtc->config.dpll_hw_state; + if (pll->new_config->crtc_mask == 0) + pll->new_config->hw_state = crtc->new_config->dpll_hw_state; - crtc->config.shared_dpll = i; + crtc->new_config->shared_dpll = i; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - pll->config.crtc_mask |= 1 << crtc->pipe; + pll->new_config->crtc_mask |= 1 << crtc->pipe; return pll; } +/** + * intel_shared_dpll_start_config - start a new PLL staged config + * @dev_priv: DRM device + * @clear_pipes: mask of pipes that will have their PLLs freed + * + * Starts a new PLL staged config, copying the current config but + * releasing the references of pipes specified in clear_pipes. + */ +static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv, + unsigned clear_pipes) +{ + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + + pll->new_config = kmemdup(&pll->config, sizeof pll->config, + GFP_KERNEL); + if (!pll->new_config) + goto cleanup; + + pll->new_config->crtc_mask &= ~clear_pipes; + } + + return 0; + +cleanup: + while (--i >= 0) { + pll = &dev_priv->shared_dplls[i]; + pll->new_config = NULL; + } + + return -ENOMEM; +} + +static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv) +{ + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + + WARN_ON(pll->new_config == &pll->config); + + pll->config = *pll->new_config; + kfree(pll->new_config); + pll->new_config = NULL; + } +} + +static void intel_shared_dpll_abort_config(struct drm_i915_private *dev_priv) +{ + struct intel_shared_dpll *pll; + enum intel_dpll_id i; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + + WARN_ON(pll->new_config == &pll->config); + + kfree(pll->new_config); + pll->new_config = NULL; + } +} + static void cpt_verify_modeset(struct drm_device *dev, int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -5420,11 +5480,11 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config) { struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; /* FIXME should check pixel clock limits on all platforms */ if (INTEL_INFO(dev)->gen < 4) { - struct drm_i915_private *dev_priv = dev->dev_private; int clock_limit = dev_priv->display.get_display_clock_speed(dev); @@ -5474,10 +5534,11 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, hsw_compute_ips_config(crtc, pipe_config); /* - * XXX: PCH/WRPLL clock sharing is done in ->mode_set, so make sure the - * old clock survives for now. + * XXX: PCH/WRPLL clock sharing is done in ->mode_set if ->compute_clock is not + * set, so make sure the old clock survives for now. */ - if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev) || HAS_DDI(dev)) + if (dev_priv->display.crtc_compute_clock == NULL && + (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev) || HAS_DDI(dev))) pipe_config->shared_dpll = crtc->config.shared_dpll; if (pipe_config->has_pch_encoder) @@ -7405,6 +7466,9 @@ static int ironlake_crtc_mode_set(struct intel_crtc *crtc, else crtc->new_config->dpll_hw_state.fp1 = fp; + if (intel_crtc_to_shared_dpll(crtc)) + intel_put_shared_dpll(crtc); + pll = intel_get_shared_dpll(crtc); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", @@ -10749,6 +10813,22 @@ static int __intel_set_mode(struct drm_crtc *crtc, prepare_pipes &= ~disable_pipes; } + if (dev_priv->display.crtc_compute_clock) { + unsigned clear_pipes = modeset_pipes | disable_pipes; + + ret = intel_shared_dpll_start_config(dev_priv, clear_pipes); + if (ret) + goto done; + + for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { + ret = dev_priv->display.crtc_compute_clock(intel_crtc); + if (ret) { + intel_shared_dpll_abort_config(dev_priv); + goto done; + } + } + } + for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) intel_crtc_disable(&intel_crtc->base); @@ -10776,6 +10856,9 @@ static int __intel_set_mode(struct drm_crtc *crtc, &pipe_config->adjusted_mode); } + if (dev_priv->display.crtc_compute_clock) + intel_shared_dpll_commit(dev_priv); + /* Only after disabling all output pipelines that will be changed can we * update the the output configuration. */ intel_modeset_update_state(dev, prepare_pipes); @@ -10810,9 +10893,12 @@ static int __intel_set_mode(struct drm_crtc *crtc, crtc->x = x; crtc->y = y; - ret = dev_priv->display.crtc_mode_set(intel_crtc, x, y, fb); - if (ret) - goto done; + if (dev_priv->display.crtc_mode_set) { + ret = dev_priv->display.crtc_mode_set(intel_crtc, + x, y, fb); + if (ret) + goto done; + } } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -- GitLab From 797d02592304b15359f407bd0e52fa5143cb4c9f Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:34 +0200 Subject: [PATCH 3842/9457] drm/i915: Covert HSW+ to choose DPLLS before disabling CRTCs Use the infrastructure added in a previous patch to choose shared DPLLs and calculate clocks before touching the hardware. v2: Don't set mode_set hooks since dev_priv is kzalloc()'d (Ville) Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 2 -- drivers/gpu/drm/i915/intel_display.c | 7 +++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 6f9712bba210..a50df351d558 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -842,8 +842,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) intel_ddi_get_crtc_new_encoder(intel_crtc); int clock = intel_crtc->new_config->port_clock; - intel_put_shared_dpll(intel_crtc); - return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4253f1288e73..e4bff0b8740f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7975,9 +7975,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev) modeset_update_crtc_power_domains(dev); } -static int haswell_crtc_mode_set(struct intel_crtc *crtc, - int x, int y, - struct drm_framebuffer *fb) +static int haswell_crtc_compute_clock(struct intel_crtc *crtc) { if (!intel_ddi_pll_select(crtc)) return -EINVAL; @@ -12468,7 +12466,8 @@ static void intel_init_display(struct drm_device *dev) if (HAS_DDI(dev)) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.get_plane_config = ironlake_get_plane_config; - dev_priv->display.crtc_mode_set = haswell_crtc_mode_set; + dev_priv->display.crtc_compute_clock = + haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; dev_priv->display.off = ironlake_crtc_off; -- GitLab From 3fb37703683543725dec3d8bc5c5b3a930325d04 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:35 +0200 Subject: [PATCH 3843/9457] drm/i915: Covert ILK-IVB to choose DPLLS before disabling CRTCs Use the infrastructure added in a previous patch to choose shared DPLLs and calculate clocks before touching the hardware. v2: Don't set mode_set hooks since dev_priv is kzalloc()'d (Ville) Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e4bff0b8740f..ee5eba78334d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7418,9 +7418,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, return dpll | DPLL_VCO_ENABLE; } -static int ironlake_crtc_mode_set(struct intel_crtc *crtc, - int x, int y, - struct drm_framebuffer *fb) +static int ironlake_crtc_compute_clock(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; intel_clock_t clock, reduced_clock; @@ -7466,17 +7464,13 @@ static int ironlake_crtc_mode_set(struct intel_crtc *crtc, else crtc->new_config->dpll_hw_state.fp1 = fp; - if (intel_crtc_to_shared_dpll(crtc)) - intel_put_shared_dpll(crtc); - pll = intel_get_shared_dpll(crtc); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(crtc->pipe)); return -EINVAL; } - } else - intel_put_shared_dpll(crtc); + } if (is_lvds && has_reduced_clock && i915.powersave) crtc->lowfreq_avail = true; @@ -12480,7 +12474,8 @@ static void intel_init_display(struct drm_device *dev) } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.get_plane_config = ironlake_get_plane_config; - dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; + dev_priv->display.crtc_compute_clock = + ironlake_crtc_compute_clock; dev_priv->display.crtc_enable = ironlake_crtc_enable; dev_priv->display.crtc_disable = ironlake_crtc_disable; dev_priv->display.off = ironlake_crtc_off; -- GitLab From d6dfee7a038ed1d160a557de50926b04dbcfbb6a Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:36 +0200 Subject: [PATCH 3844/9457] drm/i915: Covert remaining platforms to choose DPLLS before disabling CRTCs Use the infrastructure added in a previous patch to choose shared DPLLs and calculate clocks before touching the hardware. v2: Don't set mode_set hooks since dev_priv is kzalloc()'d (Ville) Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee5eba78334d..5af00c489980 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6395,9 +6395,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) POSTING_READ(PIPECONF(intel_crtc->pipe)); } -static int i9xx_crtc_mode_set(struct intel_crtc *crtc, - int x, int y, - struct drm_framebuffer *fb) +static int i9xx_crtc_compute_clock(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -12484,7 +12482,7 @@ static void intel_init_display(struct drm_device *dev) } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_plane_config = i9xx_get_plane_config; - dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; + dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; dev_priv->display.off = i9xx_crtc_off; @@ -12493,7 +12491,7 @@ static void intel_init_display(struct drm_device *dev) } else { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_plane_config = i9xx_get_plane_config; - dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; + dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_enable = i9xx_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; dev_priv->display.off = i9xx_crtc_off; -- GitLab From f3019a4d92f08b2dd92443a4b567a066a51c6ec0 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:37 +0200 Subject: [PATCH 3845/9457] drm/i915: Remove crtc_mode_set() hook There's no users left after the conversion to calculate clocks before disabling crtcs during mode set. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 3 --- drivers/gpu/drm/i915/intel_display.c | 7 ------- 2 files changed, 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4fb93e28b5ac..03be342400bd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -487,9 +487,6 @@ struct drm_i915_display_funcs { void (*get_plane_config)(struct intel_crtc *, struct intel_plane_config *); int (*crtc_compute_clock)(struct intel_crtc *crtc); - int (*crtc_mode_set)(struct intel_crtc *crtc, - int x, int y, - struct drm_framebuffer *old_fb); void (*crtc_enable)(struct drm_crtc *crtc); void (*crtc_disable)(struct drm_crtc *crtc); void (*off)(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5af00c489980..200fcb163a2d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10882,13 +10882,6 @@ static int __intel_set_mode(struct drm_crtc *crtc, crtc->primary->fb = fb; crtc->x = x; crtc->y = y; - - if (dev_priv->display.crtc_mode_set) { - ret = dev_priv->display.crtc_mode_set(intel_crtc, - x, y, fb); - if (ret) - goto done; - } } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ -- GitLab From e9f1af393477bd4a60e23531b579b325cf1918da Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Wed, 29 Oct 2014 11:32:38 +0200 Subject: [PATCH 3846/9457] drm/i915: Don't store current shared DPLL in the new pipe_config Now that shared DPLLs configuration is staged, there's no need to track the current ones in the new pipe_config since those are released before making the new pipe_config effective. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 200fcb163a2d..be596178dca4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5533,14 +5533,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, if (HAS_IPS(dev)) hsw_compute_ips_config(crtc, pipe_config); - /* - * XXX: PCH/WRPLL clock sharing is done in ->mode_set if ->compute_clock is not - * set, so make sure the old clock survives for now. - */ - if (dev_priv->display.crtc_compute_clock == NULL && - (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev) || HAS_DDI(dev))) - pipe_config->shared_dpll = crtc->config.shared_dpll; - if (pipe_config->has_pch_encoder) return ironlake_fdi_compute_config(crtc, pipe_config); -- GitLab From ba41c0dec7786ca2d5f630d0f364c5f5331b34c1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 3 Nov 2014 15:04:55 +0100 Subject: [PATCH 3847/9457] drm/i915: Move pll state commit into intel_modeset_update_state It's really part of the "push all new_* state into current state pointers" done in that function. So let's move it there to make this clear. Also, with the conversion done the num_shared_dpll check the function does in it's loop is enough, so we can drop the check for the dpll compute callback, too. Cc: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index be596178dca4..a05a8573f1a3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10231,10 +10231,13 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc) static void intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) { + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *intel_encoder; struct intel_crtc *intel_crtc; struct drm_connector *connector; + intel_shared_dpll_commit(dev_priv); + for_each_intel_encoder(dev, intel_encoder) { if (!intel_encoder->base.crtc) continue; @@ -10838,9 +10841,6 @@ static int __intel_set_mode(struct drm_crtc *crtc, &pipe_config->adjusted_mode); } - if (dev_priv->display.crtc_compute_clock) - intel_shared_dpll_commit(dev_priv); - /* Only after disabling all output pipelines that will be changed can we * update the the output configuration. */ intel_modeset_update_state(dev, prepare_pipes); -- GitLab From 4093561b70adccec7d3c8fbb19a80d636fe0f562 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 29 Oct 2014 11:16:59 +0000 Subject: [PATCH 3848/9457] drm/i915: Make intel_pipe_has_type() take an output type enum As Paulo said when introducing the enum, having more types is really good to document what should go where (int foo(int, int, bool, bool). Cc: Paulo Zanoni Signed-off-by: Damien Lespiau Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_drv.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a05a8573f1a3..d7951426f347 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -408,7 +408,7 @@ static void vlv_clock(int refclk, intel_clock_t *clock) /** * Returns whether any output on the specified pipe is of the specified type */ -bool intel_pipe_has_type(struct intel_crtc *crtc, int type) +bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type) { struct drm_device *dev = crtc->base.dev; struct intel_encoder *encoder; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 82d89167cd2f..7fab2d808a40 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -881,7 +881,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe); -bool intel_pipe_has_type(struct intel_crtc *crtc, int type); +bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type); static inline void intel_wait_for_vblank(struct drm_device *dev, int pipe) { -- GitLab From 7637b6bd4e20b877f77a4e0bd1ac48b1b1b064e1 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Wed, 29 Oct 2014 12:03:45 +0000 Subject: [PATCH 3849/9457] drm/i915: Remove unused WATCH_GTT define Chris removed the code using it in: commit be2d599b5da3936ca92e0187ff50b34b6b8ff997 Author: Chris Wilson Date: Wed Sep 10 19:52:18 2014 +0100 drm/i915: Remove dead code, i915_gem_verify_gtt Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 03be342400bd..f4c2db458ddc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -284,7 +284,6 @@ void intel_link_compute_m_n(int bpp, int nlanes, #define DRIVER_PATCHLEVEL 0 #define WATCH_LISTS 0 -#define WATCH_GTT 0 struct opregion_header; struct opregion_acpi; -- GitLab From d6faadb7a2e9b56cf83e45205a97dde17aab71af Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 3 Nov 2014 11:39:24 +0100 Subject: [PATCH 3850/9457] drm/i915/dp: Don't stop the link when retraining On pre-ddi platforms we don't shut down the link when changing link training parameters. Except when clock recovery fails too hard and we restart with channel eq training. Which doesn't make a lot of sense really, since just stopping/restarting the DP port at this point violates the modeset sequence documented in the Bspec. So let's tempt fate and try this. This patch is motivated by a WARN_ON triggered by commit bc76e320f21f8bd790a72bd5dc06909617432352 Author: Daniel Vetter Date: Tue May 20 22:46:50 2014 +0200 drm/i915: Drop now misleading DDI comment from dp_link_down References: https://bugs.freedesktop.org/show_bug.cgi?id=85670 Signed-off-by: Daniel Vetter Acked-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ec80e828240e..5f2c206aef13 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3812,7 +3812,6 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) /* Try 5 times, then try clock recovery if that fails */ if (tries > 5) { - intel_dp_link_down(intel_dp); intel_dp_start_link_train(intel_dp); intel_dp_set_link_train(intel_dp, &DP, training_pattern | -- GitLab From 816a360489b08ccba323fa0d02fc03f85bd70321 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 1 Nov 2014 05:05:56 +0000 Subject: [PATCH 3851/9457] drm/i915: Removed orphaned prototype intel_dp_handle_hpd_irq() The function was removed in: commit 0e32b39ceed665bfa4a77a4bc307b6652b991632 Author: Dave Airlie Date: Fri May 2 14:02:48 2014 +1000 drm/i915: add DP 1.2 MST support (v0.7) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7fab2d808a40..dc53cfe949af 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -992,7 +992,6 @@ void intel_edp_psr_flush(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_psr_init(struct drm_device *dev); -int intel_dp_handle_hpd_irq(struct intel_digital_port *digport, bool long_hpd); void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector); void intel_dp_mst_suspend(struct drm_device *dev); void intel_dp_mst_resume(struct drm_device *dev); -- GitLab From 7f518dd09e246e96603533167d13b2ede27c20f7 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 1 Nov 2014 05:05:57 +0000 Subject: [PATCH 3852/9457] drm/i915: Remove orphaned prototype gen6_set_pm_mask() The function was removed in: commit 037bde19a43e299d30f0490bba9be32ab355975c Author: Chris Wilson Date: Thu Mar 27 08:24:19 2014 +0000 Revert "drm/i915: Disable/Enable PM Intrrupts based on the current freq." Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f4c2db458ddc..54691bcf1822 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2298,8 +2298,6 @@ __printf(3, 4) void i915_handle_error(struct drm_device *dev, bool wedged, const char *fmt, ...); -void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir, - int new_delay); extern void intel_irq_init(struct drm_i915_private *dev_priv); extern void intel_hpd_init(struct drm_i915_private *dev_priv); int intel_irq_install(struct drm_i915_private *dev_priv); -- GitLab From 1df06b75f0235c6c4f836e5c03fb499ba70a54bd Mon Sep 17 00:00:00 2001 From: Thomas Daniel Date: Wed, 29 Oct 2014 09:52:51 +0000 Subject: [PATCH 3853/9457] drm/i915/bdw: Setup global hardware status page in execlists mode Write HWS_PGA address even in execlists mode as the global hardware status page is still required. This address was previously uninitialized and HWSP writes would clobber whatever buffer happened to reside at GGTT address 0. v2: Break out hardware status page setup into a separate function. Issue: VIZ-2020 Signed-off-by: Thomas Daniel Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 70a6c63f3b9a..292beb0fa1dc 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1649,6 +1649,27 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) return ret; } +static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring, + struct drm_i915_gem_object *default_ctx_obj) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + + /* The status page is offset 0 from the default context object + * in LRC mode. */ + ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj); + ring->status_page.page_addr = + kmap(sg_page(default_ctx_obj->pages->sgl)); + if (ring->status_page.page_addr == NULL) + return -ENOMEM; + ring->status_page.obj = default_ctx_obj; + + I915_WRITE(RING_HWS_PGA(ring->mmio_base), + (u32)ring->status_page.gfx_addr); + POSTING_READ(RING_HWS_PGA(ring->mmio_base)); + + return 0; +} + /** * intel_lr_context_deferred_create() - create the LRC specific bits of a context * @ctx: LR context to create. @@ -1734,14 +1755,11 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ctx->engine[ring->id].state = ctx_obj; if (ctx == ring->default_context) { - /* The status page is offset 0 from the default context object - * in LRC mode. */ - ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(ctx_obj); - ring->status_page.page_addr = - kmap(sg_page(ctx_obj->pages->sgl)); - if (ring->status_page.page_addr == NULL) - return -ENOMEM; - ring->status_page.obj = ctx_obj; + ret = lrc_setup_hardware_status_page(ring, ctx_obj); + if (ret) { + DRM_ERROR("Failed to setup hardware status page\n"); + goto error; + } } if (ring->id == RCS && !ctx->rcs_initialized) { -- GitLab From 850c4cdc6c223d02748f20c8ee1b677fb42da1aa Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 30 Oct 2014 16:39:38 +0000 Subject: [PATCH 3854/9457] drm/i915: Make intel_pin_and_fence_fb_obj take plane and framebuffer It will help future code if this function knows something about of the context of the display setup object is being pinned for. Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 23 ++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_fbdev.c | 20 ++++++++++---------- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d7951426f347..44060fb020a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2194,11 +2194,13 @@ static int intel_align_height(struct drm_device *dev, int height, bool tiled) } int -intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_i915_gem_object *obj, +intel_pin_and_fence_fb_obj(struct drm_plane *plane, + struct drm_framebuffer *fb, struct intel_engine_cs *pipelined) { + struct drm_device *dev = fb->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); u32 alignment; int ret; @@ -2897,7 +2899,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; struct drm_framebuffer *old_fb = crtc->primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb); int ret; @@ -2920,9 +2921,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, } mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); + ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, NULL); if (ret == 0) - i915_gem_track_fb(old_obj, obj, + i915_gem_track_fb(old_obj, intel_fb_obj(fb), INTEL_FRONTBUFFER_PRIMARY(pipe)); mutex_unlock(&dev->struct_mutex); if (ret != 0) { @@ -9689,7 +9690,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ring = &dev_priv->ring[RCS]; } - ret = intel_pin_and_fence_fb_obj(dev, obj, ring); + ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, ring); if (ret) goto cleanup_pending; @@ -10857,9 +10858,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, struct drm_i915_gem_object *obj = intel_fb_obj(fb); mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, - obj, - NULL); + ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, NULL); if (ret != 0) { DRM_ERROR("pin & fence failed\n"); mutex_unlock(&dev->struct_mutex); @@ -11525,7 +11524,7 @@ intel_prepare_primary_plane(struct drm_plane *plane, if (old_obj != obj) { mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); + ret = intel_pin_and_fence_fb_obj(plane, fb, NULL); if (ret == 0) i915_gem_track_fb(old_obj, obj, INTEL_FRONTBUFFER_PRIMARY(pipe)); @@ -13293,7 +13292,9 @@ void intel_modeset_gem_init(struct drm_device *dev) if (obj == NULL) continue; - if (intel_pin_and_fence_fb_obj(dev, obj, NULL)) { + if (intel_pin_and_fence_fb_obj(c->primary, + c->primary->fb, + NULL)) { DRM_ERROR("failed to pin boot fb on pipe %d\n", to_intel_crtc(c)->pipe); drm_framebuffer_unreference(c->primary->fb); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index dc53cfe949af..ae75b9950f01 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -896,8 +896,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx); void intel_release_load_detect_pipe(struct drm_connector *connector, struct intel_load_detect_pipe *old); -int intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_i915_gem_object *obj, +int intel_pin_and_fence_fb_obj(struct drm_plane *plane, + struct drm_framebuffer *fb, struct intel_engine_cs *pipelined); void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); struct drm_framebuffer * diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 9b584f3fbb99..f2183b554cbc 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -119,25 +119,25 @@ static int intelfb_alloc(struct drm_fb_helper *helper, goto out; } - /* Flush everything out, we'll be doing GTT only from now on */ - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - if (ret) { - DRM_ERROR("failed to pin obj: %d\n", ret); - goto out_unref; - } - fb = __intel_framebuffer_create(dev, &mode_cmd, obj); if (IS_ERR(fb)) { ret = PTR_ERR(fb); - goto out_unpin; + goto out_unref; + } + + /* Flush everything out, we'll be doing GTT only from now on */ + ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL); + if (ret) { + DRM_ERROR("failed to pin obj: %d\n", ret); + goto out_fb; } ifbdev->fb = to_intel_framebuffer(fb); return 0; -out_unpin: - i915_gem_object_ggtt_unpin(obj); +out_fb: + drm_framebuffer_remove(fb); out_unref: drm_gem_object_unreference(&obj->base); out: diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index bf1eb158e624..8c70c54e048d 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1256,7 +1256,7 @@ intel_prepare_sprite_plane(struct drm_plane *plane, * the sprite planes only require 128KiB alignment and 32 PTE * padding. */ - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); + ret = intel_pin_and_fence_fb_obj(plane, fb, NULL); if (ret == 0) i915_gem_track_fb(old_obj, obj, INTEL_FRONTBUFFER_SPRITE(pipe)); -- GitLab From 7d1bd53931e5afe5b2549c045ed4afad71ee6e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:50 +0200 Subject: [PATCH 3855/9457] drm/i915: Apply some ocd for IMR vs. IER order during irq enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When disabling interrupts we do the writes in this order: IMR,IER,IIR,IIR. But when enabling interrupts we don't do use the mirrored order, and instead do IIR,IIR,IMR,IER. I like consistency unless there's a good reason against it, which I can't think of here, so change the enable order to IIR,IIR,IER,IMR. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a2b013d97fb6..98a8d650768b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -126,16 +126,16 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ GEN5_ASSERT_IIR_IS_ZERO(GEN8_##type##_IIR(which)); \ - I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ - POSTING_READ(GEN8_##type##_IER(which)); \ + I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ + POSTING_READ(GEN8_##type##_IMR(which)); \ } while (0) #define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \ GEN5_ASSERT_IIR_IS_ZERO(type##IIR); \ - I915_WRITE(type##IMR, (imr_val)); \ I915_WRITE(type##IER, (ier_val)); \ - POSTING_READ(type##IER); \ + I915_WRITE(type##IMR, (imr_val)); \ + POSTING_READ(type##IMR); \ } while (0) /* For display hotplug interrupt */ -- GitLab From 7c4cde39684cffc6aaae4f34f2bcd987a86befe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:51 +0200 Subject: [PATCH 3856/9457] drm/i915: Use DPINVGTT_STATUS_MASK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some has given a name for the DPINVGTT status bitmask, so let's use it instead of the magic number. Looks more like the chv code now. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 98a8d650768b..e41272da67c9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3122,7 +3122,7 @@ static void valleyview_irq_preinstall(struct drm_device *dev) gen5_gt_irq_reset(dev); - I915_WRITE(DPINVGTT, 0xff); + I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK); I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); -- GitLab From a2c30fbafceb937eb3c3535a21810d4458628e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:52 +0200 Subject: [PATCH 3857/9457] drm/i915: Use gen8_gt_irq_reset() in cherryview_irq_uninstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hand rolled macros with gen8_gt_irq_reset() and GEN5_IRQ_RESET() in cherryview_irq_uninstall(). Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e41272da67c9..1ec4ebbb89f3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3625,33 +3625,9 @@ static void cherryview_irq_uninstall(struct drm_device *dev) I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); -#define GEN8_IRQ_FINI_NDX(type, which) \ -do { \ - I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ - I915_WRITE(GEN8_##type##_IER(which), 0); \ - I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ - POSTING_READ(GEN8_##type##_IIR(which)); \ - I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ -} while (0) - -#define GEN8_IRQ_FINI(type) \ -do { \ - I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ - I915_WRITE(GEN8_##type##_IER, 0); \ - I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ - POSTING_READ(GEN8_##type##_IIR); \ - I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ -} while (0) - - GEN8_IRQ_FINI_NDX(GT, 0); - GEN8_IRQ_FINI_NDX(GT, 1); - GEN8_IRQ_FINI_NDX(GT, 2); - GEN8_IRQ_FINI_NDX(GT, 3); - - GEN8_IRQ_FINI(PCU); + gen8_gt_irq_reset(dev_priv); -#undef GEN8_IRQ_FINI -#undef GEN8_IRQ_FINI_NDX + GEN5_IRQ_RESET(GEN8_PCU_); I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); -- GitLab From 8e20599ae1327ef3f0cf6a080fc3a39c882f4718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:53 +0200 Subject: [PATCH 3858/9457] drm/i915: Drop the extra GEN8_PCU_IIR posting read from cherryview_irq_preinstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like a leftover POSTING_READ(GEN8_PCU_IIR) in cherryview_irq_preinstall() from some earlier age. GEN5_IRQ_RESET() already does the posting read so this changes nothing, so kill it. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1ec4ebbb89f3..1e4062d09616 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3188,8 +3188,6 @@ static void cherryview_irq_preinstall(struct drm_device *dev) GEN5_IRQ_RESET(GEN8_PCU_); - POSTING_READ(GEN8_PCU_IIR); - I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); I915_WRITE(PORT_HOTPLUG_EN, 0); -- GitLab From 76e418605448597159c5decf4e060d41d3618831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:54 +0200 Subject: [PATCH 3859/9457] drm/i915: Use a consistent order between IIR, IER, IMR writes on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the same ordering rules for the IIR,IER,IMR writes on vlv/chv that we do on other gen5+ platforms. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1e4062d09616..589ae51de8dd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3128,10 +3128,11 @@ static void valleyview_irq_preinstall(struct drm_device *dev) I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); - I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IMR, 0xffffffff); I915_WRITE(VLV_IER, 0x0); - POSTING_READ(VLV_IER); + I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); + POSTING_READ(VLV_IIR); } static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) @@ -3199,6 +3200,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev) I915_WRITE(VLV_IMR, 0xffffffff); I915_WRITE(VLV_IER, 0x0); I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); POSTING_READ(VLV_IIR); } @@ -3362,9 +3364,9 @@ static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv) I915_WRITE(VLV_IIR, iir_mask); I915_WRITE(VLV_IIR, iir_mask); - I915_WRITE(VLV_IMR, dev_priv->irq_mask); I915_WRITE(VLV_IER, ~dev_priv->irq_mask); - POSTING_READ(VLV_IER); + I915_WRITE(VLV_IMR, dev_priv->irq_mask); + POSTING_READ(VLV_IMR); } static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) @@ -3377,8 +3379,8 @@ static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; dev_priv->irq_mask |= iir_mask; - I915_WRITE(VLV_IER, ~dev_priv->irq_mask); I915_WRITE(VLV_IMR, dev_priv->irq_mask); + I915_WRITE(VLV_IER, ~dev_priv->irq_mask); I915_WRITE(VLV_IIR, iir_mask); I915_WRITE(VLV_IIR, iir_mask); POSTING_READ(VLV_IIR); @@ -3432,10 +3434,11 @@ static int valleyview_irq_postinstall(struct drm_device *dev) I915_WRITE(PORT_HOTPLUG_EN, 0); POSTING_READ(PORT_HOTPLUG_EN); - I915_WRITE(VLV_IMR, dev_priv->irq_mask); - I915_WRITE(VLV_IER, ~dev_priv->irq_mask); I915_WRITE(VLV_IIR, 0xffffffff); - POSTING_READ(VLV_IER); + I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IER, ~dev_priv->irq_mask); + I915_WRITE(VLV_IMR, dev_priv->irq_mask); + POSTING_READ(VLV_IMR); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -3559,8 +3562,10 @@ static int cherryview_irq_postinstall(struct drm_device *dev) spin_unlock_irq(&dev_priv->irq_lock); I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IMR, dev_priv->irq_mask); + I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IER, enable_mask); + I915_WRITE(VLV_IMR, dev_priv->irq_mask); + POSTING_READ(VLV_IMR); gen8_gt_irq_postinstall(dev_priv); @@ -3606,10 +3611,11 @@ static void valleyview_irq_uninstall(struct drm_device *dev) dev_priv->irq_mask = 0; - I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IMR, 0xffffffff); I915_WRITE(VLV_IER, 0x0); - POSTING_READ(VLV_IER); + I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); + POSTING_READ(VLV_IIR); } static void cherryview_irq_uninstall(struct drm_device *dev) @@ -3636,6 +3642,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) I915_WRITE(VLV_IMR, 0xffffffff); I915_WRITE(VLV_IER, 0x0); I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); POSTING_READ(VLV_IIR); } -- GitLab From 23a09c76cc37c132844345cec94abc1edf570b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:55 +0200 Subject: [PATCH 3860/9457] drm/i915: Use GEN5_IRQ_RESET() on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hand rolled IIR,IER,IMR disable sequences with GEN5_IRQ_RESET(). Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 589ae51de8dd..c106bba3f97c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3128,11 +3128,8 @@ static void valleyview_irq_preinstall(struct drm_device *dev) I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); - I915_WRITE(VLV_IMR, 0xffffffff); - I915_WRITE(VLV_IER, 0x0); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); - POSTING_READ(VLV_IIR); + + GEN5_IRQ_RESET(VLV_); } static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) @@ -3197,11 +3194,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev) for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); - I915_WRITE(VLV_IMR, 0xffffffff); - I915_WRITE(VLV_IER, 0x0); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); - POSTING_READ(VLV_IIR); + GEN5_IRQ_RESET(VLV_); } static void ibx_hpd_irq_setup(struct drm_device *dev) @@ -3611,11 +3604,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev) dev_priv->irq_mask = 0; - I915_WRITE(VLV_IMR, 0xffffffff); - I915_WRITE(VLV_IER, 0x0); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); - POSTING_READ(VLV_IIR); + GEN5_IRQ_RESET(VLV_); } static void cherryview_irq_uninstall(struct drm_device *dev) @@ -3639,11 +3628,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); - I915_WRITE(VLV_IMR, 0xffffffff); - I915_WRITE(VLV_IER, 0x0); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); - POSTING_READ(VLV_IIR); + GEN5_IRQ_RESET(VLV_); } static void ironlake_irq_uninstall(struct drm_device *dev) -- GitLab From 893fce8edae9feabb5515b982285e5af72fcfa95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:56 +0200 Subject: [PATCH 3861/9457] drm/i915: Call gen5_gt_irq_reset() from valleyview_irq_uninstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like we forgot to call gen5_gt_irq_reset() for vlv in the uninstall phase. Do so. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c106bba3f97c..67c046b8ce0d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3588,6 +3588,8 @@ static void valleyview_irq_uninstall(struct drm_device *dev) I915_WRITE(VLV_MASTER_IER, 0); + gen5_gt_irq_reset(dev); + for_each_pipe(dev_priv, pipe) I915_WRITE(PIPESTAT(pipe), 0xffff); -- GitLab From 120dda4f638fe65d69674a674c3c1d639b31b4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:57 +0200 Subject: [PATCH 3862/9457] drm/i915: Make valleyview_display_irqs_(un)install() work for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Genralize valleyview_display_irqs_install() and valleyview_display_irqs_uninstall() enough so that they work on chv. The only difference to vlv here being the third pipe that chv brings. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 67c046b8ce0d..50431f68a84d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3335,24 +3335,27 @@ static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv) { u32 pipestat_mask; u32 iir_mask; + enum pipe pipe; pipestat_mask = PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS; - I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); - I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); + for_each_pipe(dev_priv, pipe) + I915_WRITE(PIPESTAT(pipe), pipestat_mask); POSTING_READ(PIPESTAT(PIPE_A)); pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | PIPE_CRC_DONE_INTERRUPT_STATUS; - i915_enable_pipestat(dev_priv, PIPE_A, pipestat_mask | - PIPE_GMBUS_INTERRUPT_STATUS); - i915_enable_pipestat(dev_priv, PIPE_B, pipestat_mask); + i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); + for_each_pipe(dev_priv, pipe) + i915_enable_pipestat(dev_priv, pipe, pipestat_mask); iir_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; + if (IS_CHERRYVIEW(dev_priv)) + iir_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; dev_priv->irq_mask &= ~iir_mask; I915_WRITE(VLV_IIR, iir_mask); @@ -3366,10 +3369,13 @@ static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) { u32 pipestat_mask; u32 iir_mask; + enum pipe pipe; iir_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; + if (IS_CHERRYVIEW(dev_priv)) + iir_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; dev_priv->irq_mask |= iir_mask; I915_WRITE(VLV_IMR, dev_priv->irq_mask); @@ -3381,14 +3387,15 @@ static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | PIPE_CRC_DONE_INTERRUPT_STATUS; - i915_disable_pipestat(dev_priv, PIPE_A, pipestat_mask | - PIPE_GMBUS_INTERRUPT_STATUS); - i915_disable_pipestat(dev_priv, PIPE_B, pipestat_mask); + i915_disable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); + for_each_pipe(dev_priv, pipe) + i915_disable_pipestat(dev_priv, pipe, pipestat_mask); pipestat_mask = PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS; - I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); - I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); + + for_each_pipe(dev_priv, pipe) + I915_WRITE(PIPESTAT(pipe), pipestat_mask); POSTING_READ(PIPESTAT(PIPE_A)); } -- GitLab From 70591a4101a4e5c1b89dc98a706406368a23c8ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:58 +0200 Subject: [PATCH 3863/9457] drm/i915: Refactor vlv_display_irq_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the vlv display irq reset code to a new functions. The aim is to share the code with chv. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 40 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 50431f68a84d..38e57dd0db1a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3105,10 +3105,22 @@ static void ironlake_irq_reset(struct drm_device *dev) ibx_irq_reset(dev); } +static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) +{ + enum pipe pipe; + + I915_WRITE(PORT_HOTPLUG_EN, 0); + I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); + + for_each_pipe(dev_priv, pipe) + I915_WRITE(PIPESTAT(pipe), 0xffff); + + GEN5_IRQ_RESET(VLV_); +} + static void valleyview_irq_preinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; /* VLV magic */ I915_WRITE(VLV_IMR, 0); @@ -3124,12 +3136,7 @@ static void valleyview_irq_preinstall(struct drm_device *dev) I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK); - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0xffff); - - GEN5_IRQ_RESET(VLV_); + vlv_display_irq_reset(dev_priv); } static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) @@ -3177,7 +3184,6 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) static void cherryview_irq_preinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); @@ -3188,13 +3194,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev) I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0xffff); - - GEN5_IRQ_RESET(VLV_); + vlv_display_irq_reset(dev_priv); } static void ibx_hpd_irq_setup(struct drm_device *dev) @@ -3588,7 +3588,6 @@ static void gen8_irq_uninstall(struct drm_device *dev) static void valleyview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; if (!dev_priv) return; @@ -3597,12 +3596,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev) gen5_gt_irq_reset(dev); - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0xffff); - I915_WRITE(HWSTAM, 0xffffffff); - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -3611,9 +3605,9 @@ static void valleyview_irq_uninstall(struct drm_device *dev) valleyview_display_irqs_uninstall(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - dev_priv->irq_mask = 0; + vlv_display_irq_reset(dev_priv); - GEN5_IRQ_RESET(VLV_); + dev_priv->irq_mask = 0; } static void cherryview_irq_uninstall(struct drm_device *dev) -- GitLab From 0e6c9a9eb85b1cb38a7194630cb14c293614da8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:43:00 +0200 Subject: [PATCH 3864/9457] drm/i914: Refactor vlv_display_irq_postinstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the vlv display irq postinstall code to a separate function so that we can share it with chv. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 38e57dd0db1a..297c9b1246da 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3425,10 +3425,8 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) valleyview_display_irqs_uninstall(dev_priv); } -static int valleyview_irq_postinstall(struct drm_device *dev) +static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->irq_mask = ~0; I915_WRITE(PORT_HOTPLUG_EN, 0); @@ -3449,6 +3447,13 @@ static int valleyview_irq_postinstall(struct drm_device *dev) I915_WRITE(VLV_IIR, 0xffffffff); I915_WRITE(VLV_IIR, 0xffffffff); +} + +static int valleyview_irq_postinstall(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + vlv_display_irq_postinstall(dev_priv); gen5_gt_irq_postinstall(dev); -- GitLab From 9b2e8c9411a81daf4772fbe30e0953f781f9b440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:43:01 +0200 Subject: [PATCH 3865/9457] drm/i915: Drop useless VLV_IIR writes from vlv_display_irq_postinstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The extra VLV_IIR writes at the end of vlv_display_irq_postinstall() serve no purpose. Remove them. The VLV_IMR/IER/IIR setup at the start of the function also seems a bit pointless since it doesn't unmask/enable anything. But leave it be for now. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 297c9b1246da..f2a45f14ab44 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3444,9 +3444,6 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) if (dev_priv->display_irqs_enabled) valleyview_display_irqs_install(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); } static int valleyview_irq_postinstall(struct drm_device *dev) -- GitLab From 5eba929d1bb8fb662594b44d02f54fbaa7557a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 31 Oct 2014 11:53:06 +0200 Subject: [PATCH 3866/9457] drm/i915: Kill leftover GTIIR writes from valleyview_irq_preinstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two leftover GTIIR writes in valleyview_irq_preinstall(). Looks like the were originally left behind by: commit d18ea1b58a5003eb6fca03aff03c4c01321e6cb1 Author: Daniel Vetter Date: Fri Jul 12 22:43:25 2013 +0200 drm/i915: unify PM interrupt preinstall sequence and then the GTIIR reset was added back here: commit f86f3fb005d0c907285fa8685badcb24ec31ee59 Author: Paulo Zanoni Date: Tue Apr 1 15:37:14 2014 -0300 drm/i915: properly clear IIR at irq_uninstall on Gen5+ so we can kill the leftovers from the vlv code. Cc: Paulo Zanoni Suggested-by: Paulo Zanoni Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f2a45f14ab44..318a6a0724d0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3128,10 +3128,6 @@ static void valleyview_irq_preinstall(struct drm_device *dev) I915_WRITE(RING_IMR(GEN6_BSD_RING_BASE), 0); I915_WRITE(RING_IMR(BLT_RING_BASE), 0); - /* and GT */ - I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIIR, I915_READ(GTIIR)); - gen5_gt_irq_reset(dev); I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK); -- GitLab From 59a5d2907f652249209453af9748a8ca8ccf8655 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 30 Oct 2014 15:52:45 -0200 Subject: [PATCH 3867/9457] drm/i915: fix "Unexpected fault" error message line break Fix the message, not the fault :) This is what I see: [ 282.108597] [drm:i915_check_and_clear_faults] Unexpected fault [ 282.108597] Addr: 0x00000000\n Address space: PPGTT [ 282.108597] Source ID: 24 [ 282.108597] Type: 0 Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index cb7adabc4e44..de12017c809b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1266,7 +1266,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) fault_reg = I915_READ(RING_FAULT_REG(ring)); if (fault_reg & RING_FAULT_VALID) { DRM_DEBUG_DRIVER("Unexpected fault\n" - "\tAddr: 0x%08lx\\n" + "\tAddr: 0x%08lx\n" "\tAddress space: %s\n" "\tSource ID: %d\n" "\tType: %d\n", -- GitLab From fac6adb06a530ead523a60c975bae633e44335ca Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 30 Oct 2014 15:59:31 -0200 Subject: [PATCH 3868/9457] drm/i915: fix RPS on runtime suspend With this patch, the RPS sequence for runtime suspend/resume is exactly like the sequence for S3 suspend/resume: - flush_delayed_work(&dev_priv->rps.delayed_resume_work) - intel_runtime_pm_disable_interrupts() - intel_suspend_gt_powersave() (suspended) - intel_runtime_pm_enable_interrupts() - intel_enable_gt_powersave() With this, we get rid of WARNs that are currently intermittently triggered by the system-suspend-execbuf subtest of runtime PM. Notice that these WARNs could also be triggered in other ways that involved doing lots of RPM suspend/resume cycles just after a system S3 resume. Testcase: igt/pm_rpm/system-suspend-execbuf Signed-off-by: Paulo Zanoni Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939 Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0c7cf480e854..2404b2baa01e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1395,13 +1395,9 @@ static int intel_runtime_suspend(struct device *device) i915_gem_release_all_mmaps(dev_priv); mutex_unlock(&dev->struct_mutex); - /* - * rps.work can't be rearmed here, since we get here only after making - * sure the GPU is idle and the RPS freq is set to the minimum. See - * intel_mark_idle(). - */ - cancel_work_sync(&dev_priv->rps.work); + flush_delayed_work(&dev_priv->rps.delayed_resume_work); intel_runtime_pm_disable_interrupts(dev_priv); + intel_suspend_gt_powersave(dev); ret = intel_suspend_complete(dev_priv); if (ret) { @@ -1473,7 +1469,7 @@ static int intel_runtime_resume(struct device *device) gen6_update_ring_freq(dev); intel_runtime_pm_enable_interrupts(dev_priv); - intel_reset_gt_powersave(dev); + intel_enable_gt_powersave(dev); if (ret) DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret); -- GitLab From 8e63954903779f0f70b4564d5cb0accb4b065c64 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Thu, 30 Oct 2014 18:40:53 +0000 Subject: [PATCH 3869/9457] drm/i915: Remove redundant parameter to i915_gem_object_wait_rendering__tail() An earlier commit (c8725f3dc0911d4354315a65150aecd8b7d0d74a: Do not call retire_requests from wait_for_rendering) removed the use of the ring parameter within wait_rendering__tail() but did not remove the parameter itself. As the plan is to remove obj->ring which is where this parameter comes from, it is simpler to just remove the parameter completely than to update it with a new source. For: VIZ-4377 Signed-off-by: John Harrison CC: Chris Wilson CC: Brad Volkin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7e919784b112..c2456c2be732 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1281,8 +1281,7 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) } static int -i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj, - struct intel_engine_cs *ring) +i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj) { if (!obj->active) return 0; @@ -1319,7 +1318,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, if (ret) return ret; - return i915_gem_object_wait_rendering__tail(obj, ring); + return i915_gem_object_wait_rendering__tail(obj); } /* A nonblocking variant of the above wait. This is a highly dangerous routine @@ -1359,7 +1358,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, if (ret) return ret; - return i915_gem_object_wait_rendering__tail(obj, ring); + return i915_gem_object_wait_rendering__tail(obj); } /** -- GitLab From 26ff2762108010976e2785c605cdc7ac6882da11 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 28 Oct 2014 15:10:12 +0200 Subject: [PATCH 3870/9457] drm/i915: Add kerneldoc for intel_pipe_update_{start, end} Note that a later patch will use these functions in some other file and drop the static. Hence the kerneldoc looks appropriate. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Paulo Zanoni [danvet: Add comment that the functions will become non-static shortly.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 8c70c54e048d..c692adea4332 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -60,6 +60,22 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); } +/** + * intel_pipe_update_start() - start update of a set of display registers + * @crtc: the crtc of which the registers are going to be updated + * @start_vbl_count: vblank counter return pointer used for error checking + * + * Mark the start of an update to pipe registers that should be updated + * atomically regarding vblank. If the next vblank will happens within + * the next 100 us, this function waits until the vblank passes. + * + * After a successful call to this function, interrupts will be disabled + * until a subsequent call to intel_pipe_update_end(). That is done to + * avoid random delays. The value written to @start_vbl_count should be + * supplied to intel_pipe_update_end() for error checking. + * + * Return: true if the call was successful + */ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) { struct drm_device *dev = crtc->base.dev; @@ -126,6 +142,15 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl return true; } +/** + * intel_pipe_update_end() - end update of a set of display registers + * @crtc: the crtc of which the registers were updated + * @start_vbl_count: start vblank counter (used for error checking) + * + * Mark the end of an update started with intel_pipe_update_start(). This + * re-enables interrupts and verifies the update was actually completed + * before a vblank using the value of @start_vbl_count. + */ static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) { struct drm_device *dev = crtc->base.dev; -- GitLab From 0594a3d9c0072f198462e8dbc56cb64b7d872d90 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 28 Oct 2014 15:10:13 +0200 Subject: [PATCH 3871/9457] drm/i915: Remove modeset lock check from intel_pipe_update_start() A follow up patch will call this funcion from a work context for the mmio flip, in which case we cannot acquire the modeset locks. That's not a problem though, since the check is there to protect vblank and the mode, but the code that changes that waits for pending flips first. Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index c692adea4332..0068fefd952e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -86,8 +86,6 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); DEFINE_WAIT(wait); - WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); - vblank_start = mode->crtc_vblank_start; if (mode->flags & DRM_MODE_FLAG_INTERLACE) vblank_start = DIV_ROUND_UP(vblank_start, 2); -- GitLab From 9362c7c576d39ebca81f82e931ab109c065d42be Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 28 Oct 2014 15:10:14 +0200 Subject: [PATCH 3872/9457] drm/i915: Use vblank evade mechanism in mmio_flip Currently we program just DPSCNTR and DSPSTRIDE directly from the ring interrupt handler, which is fine since the hardware guarantees that those are update atomically. When we have atomic page flips we'll want to be able to update also the offset registers, and then we need to use the vblank evade mechanism to guarantee atomicity. Since that mechanism introduces a wait, we need to do the actual register write from a work when it is triggered by the ring interrupt. v2: Explain the need for mmio_flip.work in the commit message (Paulo) Initialize the mmio_flip work in intel_crtc_init() (Paulo) Prevent new flips the previous flip work finishes (Paulo) Don't acquire modeset locks for mmio flip work Note: Paulo had reservations about the work item leaking over a plane disable. But insofar as we do lack these checks that issue is already present with the existing code. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 12 ++++++++++- drivers/gpu/drm/i915/intel_sprite.c | 4 ++-- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 44060fb020a8..84f4f0504bbb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9401,11 +9401,15 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) struct intel_framebuffer *intel_fb = to_intel_framebuffer(intel_crtc->base.primary->fb); struct drm_i915_gem_object *obj = intel_fb->obj; + bool atomic_update; + u32 start_vbl_count; u32 dspcntr; u32 reg; intel_mark_page_flip_active(intel_crtc); + atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); + reg = DSPCNTR(intel_crtc->plane); dspcntr = I915_READ(reg); @@ -9419,6 +9423,21 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) I915_WRITE(DSPSURF(intel_crtc->plane), intel_crtc->unpin_work->gtt_offset); POSTING_READ(DSPSURF(intel_crtc->plane)); + + if (atomic_update) + intel_pipe_update_end(intel_crtc, start_vbl_count); + + spin_lock_irq(&dev_priv->mmio_flip_lock); + intel_crtc->mmio_flip.status = INTEL_MMIO_FLIP_IDLE; + spin_unlock_irq(&dev_priv->mmio_flip_lock); +} + +static void intel_mmio_flip_work_func(struct work_struct *work) +{ + struct intel_crtc *intel_crtc = + container_of(work, struct intel_crtc, mmio_flip.work); + + intel_do_mmio_flip(intel_crtc); } static int intel_postpone_flip(struct drm_i915_gem_object *obj) @@ -9461,15 +9480,15 @@ void intel_notify_mmio_flip(struct intel_engine_cs *ring) struct intel_mmio_flip *mmio_flip; mmio_flip = &intel_crtc->mmio_flip; - if (mmio_flip->seqno == 0) + if (mmio_flip->status != INTEL_MMIO_FLIP_WAIT_RING) continue; if (ring->id != mmio_flip->ring_id) continue; if (i915_seqno_passed(seqno, mmio_flip->seqno)) { - intel_do_mmio_flip(intel_crtc); - mmio_flip->seqno = 0; + schedule_work(&intel_crtc->mmio_flip.work); + mmio_flip->status = INTEL_MMIO_FLIP_WORK_SCHEDULED; ring->irq_put(ring); } } @@ -9487,7 +9506,7 @@ static int intel_queue_mmio_flip(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int ret; - if (WARN_ON(intel_crtc->mmio_flip.seqno)) + if (WARN_ON(intel_crtc->mmio_flip.status != INTEL_MMIO_FLIP_IDLE)) return -EBUSY; ret = intel_postpone_flip(obj); @@ -9499,6 +9518,7 @@ static int intel_queue_mmio_flip(struct drm_device *dev, } spin_lock_irq(&dev_priv->mmio_flip_lock); + intel_crtc->mmio_flip.status = INTEL_MMIO_FLIP_WAIT_RING; intel_crtc->mmio_flip.seqno = obj->last_write_seqno; intel_crtc->mmio_flip.ring_id = obj->ring->id; spin_unlock_irq(&dev_priv->mmio_flip_lock); @@ -11983,6 +12003,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; + INIT_WORK(&intel_crtc->mmio_flip.work, intel_mmio_flip_work_func); + drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ae75b9950f01..c8ddde68a24e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -399,9 +399,17 @@ struct intel_pipe_wm { bool sprites_scaled; }; +enum intel_mmio_flip_status { + INTEL_MMIO_FLIP_IDLE = 0, + INTEL_MMIO_FLIP_WAIT_RING, + INTEL_MMIO_FLIP_WORK_SCHEDULED, +}; + struct intel_mmio_flip { u32 seqno; u32 ring_id; + enum intel_mmio_flip_status status; + struct work_struct work; }; struct intel_crtc { @@ -1167,7 +1175,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); int intel_sprite_get_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); - +bool intel_pipe_update_start(struct intel_crtc *crtc, + uint32_t *start_vbl_count); +void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count); /* intel_tv.c */ void intel_tv_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0068fefd952e..64076555153a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -76,7 +76,7 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) * * Return: true if the call was successful */ -static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) +bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) { struct drm_device *dev = crtc->base.dev; const struct drm_display_mode *mode = &crtc->config.adjusted_mode; @@ -149,7 +149,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl * re-enables interrupts and verifies the update was actually completed * before a vblank using the value of @start_vbl_count. */ -static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) +void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) { struct drm_device *dev = crtc->base.dev; enum pipe pipe = crtc->pipe; -- GitLab From ef79e17ccef32599f3cec3842f81d70117181291 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 31 Oct 2014 13:53:52 +0000 Subject: [PATCH 3873/9457] drm/i915: Only mark as map-and-fenceable when bound into the GGTT We use the obj->map_and_fenceable hint for when we already have a valid mapping of this object in the aperture. This hint can only apply to the GGTT and not to the aliasing-ppGTT. One user of the hint is execbuffer relocation, which began to fail when it tried to follow the hint and perform the relocate through the non-existent GGTT mapping. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85671 Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 39 +++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c2456c2be732..0c6ef667d256 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3476,20 +3476,6 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); list_add_tail(&vma->mm_list, &vm->inactive_list); - if (i915_is_ggtt(vm)) { - bool mappable, fenceable; - - fenceable = (vma->node.size == fence_size && - (vma->node.start & (fence_alignment - 1)) == 0); - - mappable = (vma->node.start + obj->base.size <= - dev_priv->gtt.mappable_end); - - obj->map_and_fenceable = mappable && fenceable; - } - - WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable); - trace_i915_vma_bind(vma, flags); vma->bind_vma(vma, obj->cache_level, flags & (PIN_MAPPABLE | PIN_GLOBAL) ? GLOBAL_BIND : 0); @@ -4061,6 +4047,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, { struct drm_i915_private *dev_priv = obj->base.dev->dev_private; struct i915_vma *vma; + unsigned bound; int ret; if (WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base)) @@ -4090,6 +4077,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, } } + bound = vma ? vma->bound : 0; if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags); if (IS_ERR(vma)) @@ -4099,6 +4087,29 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND)) vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); + if ((bound ^ vma->bound) & GLOBAL_BIND) { + bool mappable, fenceable; + u32 fence_size, fence_alignment; + + fence_size = i915_gem_get_gtt_size(obj->base.dev, + obj->base.size, + obj->tiling_mode); + fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev, + obj->base.size, + obj->tiling_mode, + true); + + fenceable = (vma->node.size == fence_size && + (vma->node.start & (fence_alignment - 1)) == 0); + + mappable = (vma->node.start + obj->base.size <= + dev_priv->gtt.mappable_end); + + obj->map_and_fenceable = mappable && fenceable; + } + + WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable); + vma->pin_count++; if (flags & PIN_MAPPABLE) obj->pin_mappable |= true; -- GitLab From c826c4493851913e57dd47a7fbfe07156ac9f91d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 31 Oct 2014 13:53:53 +0000 Subject: [PATCH 3874/9457] drm/i915: Request PIN_GLOBAL when pinning a vma for GTT relocations Always require PIN_GLOBAL when we want a mappable offset (PIN_MAPPABLE). This causes the pin to fixup the global binding in cases were the vma was already bound (and due to the proceeding bug, we considered it to be already mappable). References: https://bugs.freedesktop.org/show_bug.cgi?id=85671 Signed-off-by: Chris Wilson [danvet: Add WARN_ON to check that PIN_MAP implies PIN_GLOBAL as discussed on irc.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 5 ++++- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0c6ef667d256..1de94cc63517 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3478,7 +3478,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, trace_i915_vma_bind(vma, flags); vma->bind_vma(vma, obj->cache_level, - flags & (PIN_MAPPABLE | PIN_GLOBAL) ? GLOBAL_BIND : 0); + flags & PIN_GLOBAL ? GLOBAL_BIND : 0); return vma; @@ -4056,6 +4056,9 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, if (WARN_ON(flags & (PIN_GLOBAL | PIN_MAPPABLE) && !i915_is_ggtt(vm))) return -EINVAL; + if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE)) + return -EINVAL; + vma = i915_gem_obj_to_vma(obj, vm); if (vma) { if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4b7f5c104ce0..e1ed85a6dc6d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -528,7 +528,7 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags = 0; if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) - flags |= PIN_MAPPABLE; + flags |= PIN_GLOBAL | PIN_MAPPABLE; if (entry->flags & EXEC_OBJECT_NEEDS_GTT) flags |= PIN_GLOBAL; if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) -- GitLab From 70f2f5c70440feff01d9ba7c8b4432eb72bd69eb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Oct 2014 12:11:11 +0100 Subject: [PATCH 3875/9457] drm/i915: Report the actual swizzling back to userspace Userspace cares about whether or not swizzling depends on the page address for its direct access into bound objects. Extend the get_tiling ioctl to report the physical swizzling value in addition to the logical swizzling value so that userspace can accurately determine when it is possible for manual detiling. Signed-off-by: Chris Wilson Cc: Akash Goel Cc: Daniel Vetter Testcase: igt/gem_tiled_wc Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_tiling.c | 1 + include/uapi/drm/i915_drm.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index d1e7a3e088aa..749ab485569e 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -458,6 +458,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, } /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ + args->phys_swizzle_mode = args->swizzle_mode; if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) args->swizzle_mode = I915_BIT_6_SWIZZLE_9; if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index ff57f07c3249..2ec0efcaa719 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -876,6 +876,12 @@ struct drm_i915_gem_get_tiling { * mmap mapping. */ __u32 swizzle_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping whilst bound. + */ + __u32 phys_swizzle_mode; }; struct drm_i915_gem_get_aperture { -- GitLab From c46f111f5171b63572fae3f79bcfe578bc96c603 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:52 +0200 Subject: [PATCH 3876/9457] drm/i915: clean up and clarify audio related register defines Make audio related register defines conform to existing style: Add _MASK where relevant, indent the defines for register contents, don't indent the defines for register addresses, prefix pipe specific register address defines with underscores, drop self explanatory comments. No functional changes. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 165 +++++++++++++++-------------- drivers/gpu/drm/i915/intel_audio.c | 12 +-- 2 files changed, 89 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2a4bdd56c4e0..cfc6554f762b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6011,57 +6011,58 @@ enum punit_power_well { #define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8) #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) +/* Audio */ #define G4X_AUD_VID_DID (dev_priv->info.display_mmio_offset + 0x62020) -#define INTEL_AUDIO_DEVCL 0x808629FB -#define INTEL_AUDIO_DEVBLC 0x80862801 -#define INTEL_AUDIO_DEVCTG 0x80862802 +#define INTEL_AUDIO_DEVCL 0x808629FB +#define INTEL_AUDIO_DEVBLC 0x80862801 +#define INTEL_AUDIO_DEVCTG 0x80862802 #define G4X_AUD_CNTL_ST 0x620B4 -#define G4X_ELDV_DEVCL_DEVBLC (1 << 13) -#define G4X_ELDV_DEVCTG (1 << 14) -#define G4X_ELD_ADDR (0xf << 5) -#define G4X_ELD_ACK (1 << 4) +#define G4X_ELDV_DEVCL_DEVBLC (1 << 13) +#define G4X_ELDV_DEVCTG (1 << 14) +#define G4X_ELD_ADDR_MASK (0xf << 5) +#define G4X_ELD_ACK (1 << 4) #define G4X_HDMIW_HDMIEDID 0x6210C -#define IBX_HDMIW_HDMIEDID_A 0xE2050 -#define IBX_HDMIW_HDMIEDID_B 0xE2150 +#define _IBX_HDMIW_HDMIEDID_A 0xE2050 +#define _IBX_HDMIW_HDMIEDID_B 0xE2150 #define IBX_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ - IBX_HDMIW_HDMIEDID_A, \ - IBX_HDMIW_HDMIEDID_B) -#define IBX_AUD_CNTL_ST_A 0xE20B4 -#define IBX_AUD_CNTL_ST_B 0xE21B4 + _IBX_HDMIW_HDMIEDID_A, \ + _IBX_HDMIW_HDMIEDID_B) +#define _IBX_AUD_CNTL_ST_A 0xE20B4 +#define _IBX_AUD_CNTL_ST_B 0xE21B4 #define IBX_AUD_CNTL_ST(pipe) _PIPE(pipe, \ - IBX_AUD_CNTL_ST_A, \ - IBX_AUD_CNTL_ST_B) -#define IBX_ELD_BUFFER_SIZE (0x1f << 10) -#define IBX_ELD_ADDRESS (0x1f << 5) -#define IBX_ELD_ACK (1 << 4) + _IBX_AUD_CNTL_ST_A, \ + _IBX_AUD_CNTL_ST_B) +#define IBX_ELD_BUFFER_SIZE_MASK (0x1f << 10) +#define IBX_ELD_ADDRESS_MASK (0x1f << 5) +#define IBX_ELD_ACK (1 << 4) #define IBX_AUD_CNTL_ST2 0xE20C0 -#define IBX_ELD_VALIDB (1 << 0) -#define IBX_CP_READYB (1 << 1) +#define IBX_ELD_VALIDB (1 << 0) +#define IBX_CP_READYB (1 << 1) -#define CPT_HDMIW_HDMIEDID_A 0xE5050 -#define CPT_HDMIW_HDMIEDID_B 0xE5150 +#define _CPT_HDMIW_HDMIEDID_A 0xE5050 +#define _CPT_HDMIW_HDMIEDID_B 0xE5150 #define CPT_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ - CPT_HDMIW_HDMIEDID_A, \ - CPT_HDMIW_HDMIEDID_B) -#define CPT_AUD_CNTL_ST_A 0xE50B4 -#define CPT_AUD_CNTL_ST_B 0xE51B4 + _CPT_HDMIW_HDMIEDID_A, \ + _CPT_HDMIW_HDMIEDID_B) +#define _CPT_AUD_CNTL_ST_A 0xE50B4 +#define _CPT_AUD_CNTL_ST_B 0xE51B4 #define CPT_AUD_CNTL_ST(pipe) _PIPE(pipe, \ - CPT_AUD_CNTL_ST_A, \ - CPT_AUD_CNTL_ST_B) + _CPT_AUD_CNTL_ST_A, \ + _CPT_AUD_CNTL_ST_B) #define CPT_AUD_CNTRL_ST2 0xE50C0 -#define VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050) -#define VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150) +#define _VLV_HDMIW_HDMIEDID_A (VLV_DISPLAY_BASE + 0x62050) +#define _VLV_HDMIW_HDMIEDID_B (VLV_DISPLAY_BASE + 0x62150) #define VLV_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \ - VLV_HDMIW_HDMIEDID_A, \ - VLV_HDMIW_HDMIEDID_B) -#define VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4) -#define VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4) + _VLV_HDMIW_HDMIEDID_A, \ + _VLV_HDMIW_HDMIEDID_B) +#define _VLV_AUD_CNTL_ST_A (VLV_DISPLAY_BASE + 0x620B4) +#define _VLV_AUD_CNTL_ST_B (VLV_DISPLAY_BASE + 0x621B4) #define VLV_AUD_CNTL_ST(pipe) _PIPE(pipe, \ - VLV_AUD_CNTL_ST_A, \ - VLV_AUD_CNTL_ST_B) + _VLV_AUD_CNTL_ST_A, \ + _VLV_AUD_CNTL_ST_B) #define VLV_AUD_CNTL_ST2 (VLV_DISPLAY_BASE + 0x620C0) /* These are the 4 32-bit write offset registers for each stream @@ -6070,28 +6071,28 @@ enum punit_power_well { */ #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) -#define IBX_AUD_CONFIG_A 0xe2000 -#define IBX_AUD_CONFIG_B 0xe2100 +#define _IBX_AUD_CONFIG_A 0xe2000 +#define _IBX_AUD_CONFIG_B 0xe2100 #define IBX_AUD_CFG(pipe) _PIPE(pipe, \ - IBX_AUD_CONFIG_A, \ - IBX_AUD_CONFIG_B) -#define CPT_AUD_CONFIG_A 0xe5000 -#define CPT_AUD_CONFIG_B 0xe5100 + _IBX_AUD_CONFIG_A, \ + _IBX_AUD_CONFIG_B) +#define _CPT_AUD_CONFIG_A 0xe5000 +#define _CPT_AUD_CONFIG_B 0xe5100 #define CPT_AUD_CFG(pipe) _PIPE(pipe, \ - CPT_AUD_CONFIG_A, \ - CPT_AUD_CONFIG_B) -#define VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000) -#define VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100) + _CPT_AUD_CONFIG_A, \ + _CPT_AUD_CONFIG_B) +#define _VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000) +#define _VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100) #define VLV_AUD_CFG(pipe) _PIPE(pipe, \ - VLV_AUD_CONFIG_A, \ - VLV_AUD_CONFIG_B) + _VLV_AUD_CONFIG_A, \ + _VLV_AUD_CONFIG_B) #define AUD_CONFIG_N_VALUE_INDEX (1 << 29) #define AUD_CONFIG_N_PROG_ENABLE (1 << 28) #define AUD_CONFIG_UPPER_N_SHIFT 20 -#define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) +#define AUD_CONFIG_UPPER_N_MASK (0xff << 20) #define AUD_CONFIG_LOWER_N_SHIFT 4 -#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) +#define AUD_CONFIG_LOWER_N_MASK (0xfff << 4) #define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16 #define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK (0xf << 16) #define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 (0 << 16) @@ -6107,40 +6108,40 @@ enum punit_power_well { #define AUD_CONFIG_DISABLE_NCTS (1 << 3) /* HSW Audio */ -#define HSW_AUD_CONFIG_A 0x65000 /* Audio Configuration Transcoder A */ -#define HSW_AUD_CONFIG_B 0x65100 /* Audio Configuration Transcoder B */ -#define HSW_AUD_CFG(pipe) _PIPE(pipe, \ - HSW_AUD_CONFIG_A, \ - HSW_AUD_CONFIG_B) - -#define HSW_AUD_MISC_CTRL_A 0x65010 /* Audio Misc Control Convert 1 */ -#define HSW_AUD_MISC_CTRL_B 0x65110 /* Audio Misc Control Convert 2 */ -#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \ - HSW_AUD_MISC_CTRL_A, \ - HSW_AUD_MISC_CTRL_B) - -#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 /* Audio DIP and ELD Control State Transcoder A */ -#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 /* Audio DIP and ELD Control State Transcoder B */ -#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \ - HSW_AUD_DIP_ELD_CTRL_ST_A, \ - HSW_AUD_DIP_ELD_CTRL_ST_B) +#define _HSW_AUD_CONFIG_A 0x65000 +#define _HSW_AUD_CONFIG_B 0x65100 +#define HSW_AUD_CFG(pipe) _PIPE(pipe, \ + _HSW_AUD_CONFIG_A, \ + _HSW_AUD_CONFIG_B) + +#define _HSW_AUD_MISC_CTRL_A 0x65010 +#define _HSW_AUD_MISC_CTRL_B 0x65110 +#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \ + _HSW_AUD_MISC_CTRL_A, \ + _HSW_AUD_MISC_CTRL_B) + +#define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 +#define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 +#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \ + _HSW_AUD_DIP_ELD_CTRL_ST_A, \ + _HSW_AUD_DIP_ELD_CTRL_ST_B) /* Audio Digital Converter */ -#define HSW_AUD_DIG_CNVT_1 0x65080 /* Audio Converter 1 */ -#define HSW_AUD_DIG_CNVT_2 0x65180 /* Audio Converter 1 */ -#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \ - HSW_AUD_DIG_CNVT_1, \ - HSW_AUD_DIG_CNVT_2) -#define DIP_PORT_SEL_MASK 0x3 - -#define HSW_AUD_EDID_DATA_A 0x65050 -#define HSW_AUD_EDID_DATA_B 0x65150 -#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \ - HSW_AUD_EDID_DATA_A, \ - HSW_AUD_EDID_DATA_B) - -#define HSW_AUD_PIPE_CONV_CFG 0x6507c /* Audio pipe and converter configs */ -#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 /* Audio ELD and CP Ready Status */ +#define _HSW_AUD_DIG_CNVT_1 0x65080 +#define _HSW_AUD_DIG_CNVT_2 0x65180 +#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \ + _HSW_AUD_DIG_CNVT_1, \ + _HSW_AUD_DIG_CNVT_2) +#define DIP_PORT_SEL_MASK 0x3 + +#define _HSW_AUD_EDID_DATA_A 0x65050 +#define _HSW_AUD_EDID_DATA_B 0x65150 +#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \ + _HSW_AUD_EDID_DATA_A, \ + _HSW_AUD_EDID_DATA_B) + +#define HSW_AUD_PIPE_CONV_CFG 0x6507c +#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 #define AUDIO_INACTIVE_C (1<<11) #define AUDIO_INACTIVE_B (1<<7) #define AUDIO_INACTIVE_A (1<<3) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 7580b3823e30..821514c95229 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -111,12 +111,12 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, if (intel_eld_uptodate(connector, G4X_AUD_CNTL_ST, eldv, - G4X_AUD_CNTL_ST, G4X_ELD_ADDR, + G4X_AUD_CNTL_ST, G4X_ELD_ADDR_MASK, G4X_HDMIW_HDMIEDID)) return; tmp = I915_READ(G4X_AUD_CNTL_ST); - tmp &= ~(eldv | G4X_ELD_ADDR); + tmp &= ~(eldv | G4X_ELD_ADDR_MASK); len = (tmp >> 9) & 0x1f; /* ELD buffer size */ I915_WRITE(G4X_AUD_CNTL_ST, tmp); @@ -193,7 +193,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS, + aud_cntl_st, IBX_ELD_ADDRESS_MASK, hdmiw_hdmiedid)) return; @@ -202,7 +202,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); tmp = I915_READ(aud_cntl_st); - tmp &= ~IBX_ELD_ADDRESS; + tmp &= ~IBX_ELD_ADDRESS_MASK; I915_WRITE(aud_cntl_st, tmp); port = (tmp >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ DRM_DEBUG_DRIVER("port num:%d\n", port); @@ -287,7 +287,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS, + aud_cntl_st, IBX_ELD_ADDRESS_MASK, hdmiw_hdmiedid)) return; @@ -296,7 +296,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, I915_WRITE(aud_cntrl_st2, tmp); tmp = I915_READ(aud_cntl_st); - tmp &= ~IBX_ELD_ADDRESS; + tmp &= ~IBX_ELD_ADDRESS_MASK; I915_WRITE(aud_cntl_st, tmp); len = min_t(int, eld[2], 21); /* 84 bytes of hw ELD buffer */ -- GitLab From 5fad84a7530f8e7664cdc6f490cb90653fed1266 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Nov 2014 10:30:23 +0200 Subject: [PATCH 3877/9457] drm/i915: rewrite hsw/bdw audio codec enable/disable sequences There's some serious confusion regarding ELD valid bit that gets set and cleared back and forth etc. Rewrite it all based on the documented audio codec enable/disable sequences. v3: replace vblank wait with a comment v4: expand the comment on what should be done with the vblank wait Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 115 +++++++++++++---------------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 821514c95229..4dcfc46d5725 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -132,14 +132,26 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, static void hsw_audio_codec_disable(struct intel_encoder *encoder) { - struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->base.crtc; - enum pipe pipe = to_intel_crtc(crtc)->pipe; + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + enum pipe pipe = intel_crtc->pipe; uint32_t tmp; + DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); + + /* Disable timestamps */ + tmp = I915_READ(HSW_AUD_CFG(pipe)); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX; + tmp |= AUD_CONFIG_N_PROG_ENABLE; + tmp &= ~AUD_CONFIG_UPPER_N_MASK; + tmp &= ~AUD_CONFIG_LOWER_N_MASK; + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + tmp |= AUD_CONFIG_N_VALUE_INDEX; + I915_WRITE(HSW_AUD_CFG(pipe), tmp); + + /* Invalidate ELD */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); + tmp &= ~(AUDIO_ELD_VALID_A << (pipe * 4)); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); } @@ -149,77 +161,52 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, { struct drm_i915_private *dev_priv = connector->dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - uint8_t *eld = connector->eld; - uint32_t eldv; + enum pipe pipe = intel_crtc->pipe; + const uint8_t *eld = connector->eld; uint32_t tmp; int len, i; - enum pipe pipe = intel_crtc->pipe; - enum port port; - int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); - int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); - int aud_config = HSW_AUD_CFG(pipe); - int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD; - /* Audio output enable */ - DRM_DEBUG_DRIVER("HDMI audio: enable codec\n"); - tmp = I915_READ(aud_cntrl_st2); - tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4)); - I915_WRITE(aud_cntrl_st2, tmp); - POSTING_READ(aud_cntrl_st2); - - /* Set ELD valid state */ - tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); - tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); - I915_WRITE(aud_cntrl_st2, tmp); - tmp = I915_READ(aud_cntrl_st2); - DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp); - - /* Enable HDMI mode */ - tmp = I915_READ(aud_config); - DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp); - /* clear N_programing_enable and N_value_index */ - tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); - I915_WRITE(aud_config, tmp); + DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n", + pipe_name(pipe), eld[2]); - DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); - - eldv = AUDIO_ELD_VALID_A << (pipe * 4); - - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) - I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - else - I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - - if (intel_eld_uptodate(connector, - aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS_MASK, - hdmiw_hdmiedid)) - return; + /* Enable audio presence detect, invalidate ELD */ + tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); + tmp |= AUDIO_OUTPUT_ENABLE_A << (pipe * 4); + tmp &= ~(AUDIO_ELD_VALID_A << (pipe * 4)); + I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); - tmp = I915_READ(aud_cntrl_st2); - tmp &= ~eldv; - I915_WRITE(aud_cntrl_st2, tmp); + /* + * FIXME: We're supposed to wait for vblank here, but we have vblanks + * disabled during the mode set. The proper fix would be to push the + * rest of the setup into a vblank work item, queued here, but the + * infrastructure is not there yet. + */ - tmp = I915_READ(aud_cntl_st); + /* Reset ELD write address */ + tmp = I915_READ(HSW_AUD_DIP_ELD_CTRL(pipe)); tmp &= ~IBX_ELD_ADDRESS_MASK; - I915_WRITE(aud_cntl_st, tmp); - port = (tmp >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ - DRM_DEBUG_DRIVER("port num:%d\n", port); + I915_WRITE(HSW_AUD_DIP_ELD_CTRL(pipe), tmp); - len = min_t(int, eld[2], 21); /* 84 bytes of hw ELD buffer */ - DRM_DEBUG_DRIVER("ELD size %d\n", len); + /* Up to 84 bytes of hw ELD buffer */ + len = min_t(int, eld[2], 21); for (i = 0; i < len; i++) - I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - - tmp = I915_READ(aud_cntrl_st2); - tmp |= eldv; - I915_WRITE(aud_cntrl_st2, tmp); + I915_WRITE(HSW_AUD_EDID_DATA(pipe), *((uint32_t *)eld + i)); - /* XXX: Transitional */ + /* ELD valid */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); + tmp |= AUDIO_ELD_VALID_A << (pipe * 4); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); + + /* Enable timestamps */ + tmp = I915_READ(HSW_AUD_CFG(pipe)); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX; + tmp &= ~AUD_CONFIG_N_PROG_ENABLE; + tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + tmp |= AUD_CONFIG_N_VALUE_INDEX; + else + tmp |= audio_config_hdmi_pixel_clock(mode); + I915_WRITE(HSW_AUD_CFG(pipe), tmp); } static void ilk_audio_codec_enable(struct drm_connector *connector, -- GitLab From 2af30a5c40bff540f13106961662d000b1bc8cd7 Mon Sep 17 00:00:00 2001 From: Pradeep Bhat Date: Tue, 4 Nov 2014 17:06:38 +0000 Subject: [PATCH 3878/9457] drm/i915/skl: Read the Memory Latency Values for WM computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch reads the memory latency values for all the 8 levels for SKL. These values are needed for the Watermark computation. v2: Incorporated the review comments from Damien on register indentation. v3: Updated the code to use the sandybridge_pcode_read for reading memory latencies for GEN9. v4: Don't put gen 9 in the middle of an ordered list of ifs (Damien) v5: take the rps.hw_lock around sandybridge_pcode_read() (Damien) v6: Use gen >= 9 in the pcode_read() function for data1. Move the defines near the gen6 ones and prefix them with PCODE. Remove unused timeout define (the pcode_read() code has a larger timeout already). Reviewed-by: Ville Syrjälä Signed-off-by: Pradeep Bhat Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/i915_reg.h | 7 +++ drivers/gpu/drm/i915/intel_pm.c | 76 ++++++++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54691bcf1822..05fcbe5c6e38 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1678,6 +1678,12 @@ struct drm_i915_private { uint16_t spr_latency[5]; /* cursor */ uint16_t cur_latency[5]; + /* + * Raw watermark memory latency values + * for SKL for all 8 levels + * in 1us units. + */ + uint16_t skl_latency[8]; /* current hardware state */ struct ilk_wm_values hw; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cfc6554f762b..db7d8fd5b7f5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5957,6 +5957,13 @@ enum punit_power_well { #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 +#define GEN9_PCODE_DATA1 0x13812C +#define GEN9_PCODE_READ_MEM_LATENCY 0x6 +#define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF +#define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8 +#define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16 +#define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24 + #define GEN6_GT_CORE_STATUS 0x138060 #define GEN6_CORE_CPD_STATE_MASK (7<<4) #define GEN6_RCn_MASK 7 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7a69eba533c7..761c884211c5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2271,11 +2271,56 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) PIPE_WM_LINETIME_TIME(linetime); } -static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) +static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + if (IS_GEN9(dev)) { + uint32_t val; + int ret; + + /* read the first set of memory latencies[0:3] */ + val = 0; /* data0 to be programmed to 0 for first set */ + mutex_lock(&dev_priv->rps.hw_lock); + ret = sandybridge_pcode_read(dev_priv, + GEN9_PCODE_READ_MEM_LATENCY, + &val); + mutex_unlock(&dev_priv->rps.hw_lock); + + if (ret) { + DRM_ERROR("SKL Mailbox read error = %d\n", ret); + return; + } + + wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK; + wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + + /* read the second set of memory latencies[4:7] */ + val = 1; /* data0 to be programmed to 1 for second set */ + mutex_lock(&dev_priv->rps.hw_lock); + ret = sandybridge_pcode_read(dev_priv, + GEN9_PCODE_READ_MEM_LATENCY, + &val); + mutex_unlock(&dev_priv->rps.hw_lock); + if (ret) { + DRM_ERROR("SKL Mailbox read error = %d\n", ret); + return; + } + + wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK; + wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK; + + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { uint64_t sskpd = I915_READ64(MCH_SSKPD); wm[0] = (sskpd >> 56) & 0xFF; @@ -2323,7 +2368,9 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5]) int ilk_wm_max_level(const struct drm_device *dev) { /* how many WM levels are we expecting */ - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + if (IS_GEN9(dev)) + return 7; + else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) return 4; else if (INTEL_INFO(dev)->gen >= 6) return 3; @@ -2333,7 +2380,7 @@ int ilk_wm_max_level(const struct drm_device *dev) static void intel_print_wm_latency(struct drm_device *dev, const char *name, - const uint16_t wm[5]) + const uint16_t wm[8]) { int level, max_level = ilk_wm_max_level(dev); @@ -2346,8 +2393,13 @@ static void intel_print_wm_latency(struct drm_device *dev, continue; } - /* WM1+ latency values in 0.5us units */ - if (level > 0) + /* + * - latencies are in us on gen9. + * - before then, WM1+ latency values are in 0.5us units + */ + if (IS_GEN9(dev)) + latency *= 10; + else if (level > 0) latency *= 5; DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n", @@ -2415,6 +2467,14 @@ static void ilk_setup_wm_latency(struct drm_device *dev) snb_wm_latency_quirk(dev); } +static void skl_setup_wm_latency(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + intel_read_wm_latency(dev, dev_priv->wm.skl_latency); + intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); +} + static void ilk_compute_wm_parameters(struct drm_crtc *crtc, struct ilk_pipe_wm_parameters *p) { @@ -6127,6 +6187,8 @@ void intel_init_pm(struct drm_device *dev) /* For FIFO watermark updates */ if (IS_GEN9(dev)) { + skl_setup_wm_latency(dev); + dev_priv->display.init_clock_gating = gen9_init_clock_gating; } else if (HAS_PCH_SPLIT(dev)) { ilk_setup_wm_latency(dev); @@ -6219,6 +6281,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) } I915_WRITE(GEN6_PCODE_DATA, *val); + if (INTEL_INFO(dev_priv)->gen >= 9) + I915_WRITE(GEN9_PCODE_DATA1, 0); I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, -- GitLab From fae1267df8a14140544204c65258867d72f287bb Mon Sep 17 00:00:00 2001 From: Pradeep Bhat Date: Tue, 4 Nov 2014 17:06:39 +0000 Subject: [PATCH 3879/9457] drm/i915/skl: Register definitions and macros for SKL Watermark regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch defines SKL specific PLANE_WM Watermark registers. It also defines macros to get the addresses of different LP levels within a pipe. v2: Reworked the register definitions and associated macros to make it more generic and be able to use for_each_pipe in values computation. Incorporated Damien's review comments and indentation. v3: Added default values for lines and blocks. Provided mask for blocks. v4: Prefix intermedidate (internal-only) macros with _ (Ville) v5: Remove the lines and block defaults value (Ville) Reviewed-by: Ville Syrjälä (v4) Signed-off-by: Pradeep Bhat Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index db7d8fd5b7f5..ccbaeb35d695 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4102,6 +4102,41 @@ enum punit_power_well { #define I965_CURSOR_MAX_WM 32 #define I965_CURSOR_DFT_WM 8 +/* Watermark register definitions for SKL */ +#define CUR_WM_A_0 0x70140 +#define CUR_WM_B_0 0x71140 +#define PLANE_WM_1_A_0 0x70240 +#define PLANE_WM_1_B_0 0x71240 +#define PLANE_WM_2_A_0 0x70340 +#define PLANE_WM_2_B_0 0x71340 +#define PLANE_WM_TRANS_1_A_0 0x70268 +#define PLANE_WM_TRANS_1_B_0 0x71268 +#define PLANE_WM_TRANS_2_A_0 0x70368 +#define PLANE_WM_TRANS_2_B_0 0x71368 +#define CUR_WM_TRANS_A_0 0x70168 +#define CUR_WM_TRANS_B_0 0x71168 +#define PLANE_WM_EN (1 << 31) +#define PLANE_WM_LINES_SHIFT 14 +#define PLANE_WM_LINES_MASK 0x1f +#define PLANE_WM_BLOCKS_MASK 0x3ff + +#define CUR_WM_0(pipe) _PIPE(pipe, CUR_WM_A_0, CUR_WM_B_0) +#define CUR_WM(pipe, level) (CUR_WM_0(pipe) + ((4) * (level))) +#define CUR_WM_TRANS(pipe) _PIPE(pipe, CUR_WM_TRANS_A_0, CUR_WM_TRANS_B_0) + +#define _PLANE_WM_1(pipe) _PIPE(pipe, PLANE_WM_1_A_0, PLANE_WM_1_B_0) +#define _PLANE_WM_2(pipe) _PIPE(pipe, PLANE_WM_2_A_0, PLANE_WM_2_B_0) +#define _PLANE_WM_BASE(pipe, plane) \ + _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe)) +#define PLANE_WM(pipe, plane, level) \ + (_PLANE_WM_BASE(pipe, plane) + ((4) * (level))) +#define _PLANE_WM_TRANS_1(pipe) \ + _PIPE(pipe, PLANE_WM_TRANS_1_A_0, PLANE_WM_TRANS_1_B_0) +#define _PLANE_WM_TRANS_2(pipe) \ + _PIPE(pipe, PLANE_WM_TRANS_2_A_0, PLANE_WM_TRANS_2_B_0) +#define PLANE_WM_TRANS(pipe, plane) \ + _PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe)) + /* define the Watermark register on Ironlake */ #define WM0_PIPEA_ILK 0x45100 #define WM0_PIPE_PLANE_MASK (0xffff<<16) -- GitLab From 2ac96d2a6e102ec64a568a470a6d9c50b9c02e59 Mon Sep 17 00:00:00 2001 From: Pradeep Bhat Date: Tue, 4 Nov 2014 17:06:40 +0000 Subject: [PATCH 3880/9457] drm/i915/skl: Definition of SKL WM param structs for pipe/plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch defines the structures needed for computation of watermarks of pipes and planes for SKL. v2: Incorporated Damien's review comments and removed unused fields in structs for future features like rotation, drrs and scaling. The skl_wm_values struct is now made more generic across planes and cursor planes for all pipes. v3: implemented the plane/cursor split. v4: Change the wm union back to a structure (Ville, Daniel) Reviewed-by: Ville Syrjälä Signed-off-by: Pradeep Bhat Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 18 ++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++ drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 05fcbe5c6e38..19bc2d057a87 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1387,6 +1387,24 @@ struct ilk_wm_values { enum intel_ddb_partitioning partitioning; }; +struct skl_wm_values { + bool dirty[I915_MAX_PIPES]; + uint32_t wm_linetime[I915_MAX_PIPES]; + uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8]; + uint32_t cursor[I915_MAX_PIPES][8]; + uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES]; + uint32_t cursor_trans[I915_MAX_PIPES]; +}; + +struct skl_wm_level { + bool plane_en[I915_MAX_PLANES]; + uint16_t plane_res_b[I915_MAX_PLANES]; + uint8_t plane_res_l[I915_MAX_PLANES]; + bool cursor_en; + uint16_t cursor_res_b; + uint8_t cursor_res_l; +}; + /* * This struct helps tracking the state needed for runtime PM, which puts the * device in PCI D3 state. Notice that when this happens, nothing on the diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c8ddde68a24e..446be27ce76f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -412,6 +412,12 @@ struct intel_mmio_flip { struct work_struct work; }; +struct skl_pipe_wm { + struct skl_wm_level wm[8]; + struct skl_wm_level trans_wm; + uint32_t linetime; +}; + struct intel_crtc { struct drm_crtc base; enum pipe pipe; @@ -459,6 +465,8 @@ struct intel_crtc { struct { /* watermarks currently being used */ struct intel_pipe_wm active; + /* SKL wm values currently in use */ + struct skl_pipe_wm skl_active; } wm; int scanline_offset; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 761c884211c5..ca2080bf486f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1960,6 +1960,14 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; } +struct skl_pipe_wm_parameters { + bool active; + uint32_t pipe_htotal; + uint32_t pixel_rate; /* in KHz */ + struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; + struct intel_plane_wm_parameters cursor; +}; + struct ilk_pipe_wm_parameters { bool active; uint32_t pipe_htotal; -- GitLab From c193924e9cef42995cbd204253520efc9d8ad1ba Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:41 +0000 Subject: [PATCH 3881/9457] drm/i915/skl: Add DDB allocation management structures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now need to allocate space in the DDB for planes being scanned out ourselves. The data structure to represent an allocation mirrors what we'll need to write in the registers later on: (start, end). We add that allocation datat to the skl_wm_values structure as part of the values to program the hardware with. v2: Split planes and cursor for consistency. v3: Make the skl_ddb_entry_size() parameter const Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 19bc2d057a87..aa8607a9e49c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1387,8 +1387,27 @@ struct ilk_wm_values { enum intel_ddb_partitioning partitioning; }; +struct skl_ddb_entry { + uint16_t start, end; /* in number of blocks */ +}; + +static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry) +{ + /* end not set, clearly no allocation here. start can be 0 though */ + if (entry->end == 0) + return 0; + + return entry->end - entry->start + 1; +} + +struct skl_ddb_allocation { + struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; + struct skl_ddb_entry cursor[I915_MAX_PIPES]; +}; + struct skl_wm_values { bool dirty[I915_MAX_PIPES]; + struct skl_ddb_allocation ddb; uint32_t wm_linetime[I915_MAX_PIPES]; uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8]; uint32_t cursor[I915_MAX_PIPES][8]; -- GitLab From 2d41c0b59afcdd87d689212cdb929709ffc27d08 Mon Sep 17 00:00:00 2001 From: Pradeep Bhat Date: Tue, 4 Nov 2014 17:06:42 +0000 Subject: [PATCH 3882/9457] drm/i915/skl: SKL Watermark Computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements the watermark algorithm and its necessary functions. Two function pointers skl_update_wm and skl_update_sprite_wm are provided. The skl_update_wm will update the watermarks for the crtc provided as an argument and then checks for change in DDB allocation for other active pipes and recomputes the watermarks for those Pipes and planes as well. Finally it does the register programming for all dirty pipes. The trigger of the Watermark double buffer registers will have to be once the plane configurations are done by the caller. v2: fixed the divide-by-0 error in the results computation func. Also reworked the PLANE_WM register values computation func to make it more compact. Incorporated all other review comments from Damien. v3: Changed the skl_compute_plane_wm function to now return success or failure. Also the result blocks and lines are computed here instead of in skl_compute_wm_results function. v4: Adjust skl_ddb_alloc_changed() to the new planes/cursor split (Damien) v5: Reworked the affected functions to implement new plane/cursor split. v6: Rework the logic that triggers the DDB allocation and WM computation of skl_update_other_pipe_wm() to not depend on non-computed DDB values. Always give a valid cursor_width (at boot it's 0) to keep the invariant that we consider the cursor plane always enabled. Otherwise we end up dividing by 0 in skl_compute_plane_wm() (Damien Lespiau) v7: Spell out allocation skl_ddb_ functions should have the ddb as first argument Make the skl_ddb_alloc_changed() parameters const (Damien) v8: Rebase on top of the crtc->primary changes v9: Split the staging results structure to not exceed the 1Kb stack allocation in skl_update_wm() v10: Make skl_pipe_pixel_rate() take a pointer to the pipe config Add a comment about overflow considerations for skl_wm_method1() Various additions of const Various use of sizeof(variable) instead of sizeof(type) Various move of variable definitons to a narrower scope Zero initialize some stack allocated structures to make sure we don't have garbage in case we don't write all the values (Ville) v11: Remove non-necessary default number of blocks/lines when the plane is disabled (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Pradeep Bhat Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 12 +- drivers/gpu/drm/i915/intel_pm.c | 422 ++++++++++++++++++++++++++++++++ 2 files changed, 433 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aa8607a9e49c..fbe18aed254d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1722,8 +1722,18 @@ struct drm_i915_private { */ uint16_t skl_latency[8]; + /* + * The skl_wm_values structure is a bit too big for stack + * allocation, so we keep the staging struct where we store + * intermediate results here instead. + */ + struct skl_wm_values skl_results; + /* current hardware state */ - struct ilk_wm_values hw; + union { + struct ilk_wm_values hw; + struct skl_wm_values skl_hw; + }; } wm; struct i915_runtime_pm pm; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ca2080bf486f..5500c5343e0e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2973,6 +2973,426 @@ static bool ilk_disable_lp_wm(struct drm_device *dev) return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } +static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config) +{ + /* TODO: Take into account the scalers once we support them */ + return config->adjusted_mode.crtc_clock; +} + +/* + * The max latency should be 257 (max the punit can code is 255 and we add 2us + * for the read latency) and bytes_per_pixel should always be <= 8, so that + * should allow pixel_rate up to ~2 GHz which seems sufficient since max + * 2xcdclk is 1350 MHz and the pixel rate should never exceed that. +*/ +static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + uint32_t latency) +{ + uint32_t wm_intermediate_val, ret; + + if (latency == 0) + return UINT_MAX; + + wm_intermediate_val = latency * pixel_rate * bytes_per_pixel; + ret = DIV_ROUND_UP(wm_intermediate_val, 1000); + + return ret; +} + +static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + uint32_t horiz_pixels, uint8_t bytes_per_pixel, + uint32_t latency) +{ + uint32_t ret, plane_bytes_per_line, wm_intermediate_val; + + if (latency == 0) + return UINT_MAX; + + plane_bytes_per_line = horiz_pixels * bytes_per_pixel; + wm_intermediate_val = latency * pixel_rate; + ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) * + plane_bytes_per_line; + + return ret; +} + +static void skl_compute_transition_wm(struct drm_crtc *crtc, + struct skl_pipe_wm_parameters *params, + struct skl_pipe_wm *pipe_wm) +{ + /* + * For now it is suggested to use the LP0 wm val of corresponding + * plane as transition wm val. This is done while computing results. + */ + if (!params->active) + return; +} + +static uint32_t +skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) +{ + if (!intel_crtc_active(crtc)) + return 0; + + return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); + +} + +static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb, + const struct intel_crtc *intel_crtc) +{ + struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; + enum pipe pipe = intel_crtc->pipe; + + if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], + sizeof(new_ddb->plane[pipe]))) + return true; + + if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe], + sizeof(new_ddb->cursor[pipe]))) + return true; + + return false; +} + +static void skl_compute_wm_global_parameters(struct drm_device *dev, + struct intel_wm_config *config) +{ + struct drm_crtc *crtc; + struct drm_plane *plane; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + config->num_pipes_active += intel_crtc_active(crtc); + + /* FIXME: I don't think we need those two global parameters on SKL */ + list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + struct intel_plane *intel_plane = to_intel_plane(plane); + + config->sprites_enabled |= intel_plane->wm.enabled; + config->sprites_scaled |= intel_plane->wm.scaled; + } +} + +static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, + struct skl_pipe_wm_parameters *p) +{ + struct drm_device *dev = crtc->dev; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct drm_plane *plane; + int i = 1; /* Index for sprite planes start */ + + p->active = intel_crtc_active(crtc); + if (p->active) { + p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; + p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config); + + /* + * For now, assume primary and cursor planes are always enabled. + */ + p->plane[0].enabled = true; + p->plane[0].bytes_per_pixel = + crtc->primary->fb->bits_per_pixel / 8; + p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w; + p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h; + + p->cursor.enabled = true; + p->cursor.bytes_per_pixel = 4; + p->cursor.horiz_pixels = intel_crtc->cursor_width ? + intel_crtc->cursor_width : 64; + } + + list_for_each_entry(plane, &dev->mode_config.plane_list, head) { + struct intel_plane *intel_plane = to_intel_plane(plane); + + if (intel_plane->pipe == pipe) + p->plane[i++] = intel_plane->wm; + } +} + +static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, + struct intel_plane_wm_parameters *p_params, + uint16_t max_page_buff_alloc, + uint32_t mem_value, + uint16_t *res_blocks, /* out */ + uint8_t *res_lines /* out */) +{ + uint32_t method1, method2, plane_bytes_per_line; + uint32_t result_bytes; + + if (!p->active || !p_params->enabled) + return false; + + method1 = skl_wm_method1(p->pixel_rate, + p_params->bytes_per_pixel, + mem_value); + method2 = skl_wm_method2(p->pixel_rate, + p->pipe_htotal, + p_params->horiz_pixels, + p_params->bytes_per_pixel, + mem_value); + + plane_bytes_per_line = p_params->horiz_pixels * + p_params->bytes_per_pixel; + + /* For now xtile and linear */ + if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1) + result_bytes = min(method1, method2); + else + result_bytes = method1; + + *res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1; + *res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line); + + return true; +} + +static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb, + struct skl_pipe_wm_parameters *p, + enum pipe pipe, + int level, + int num_planes, + struct skl_wm_level *result) +{ + uint16_t latency = dev_priv->wm.skl_latency[level]; + uint16_t ddb_blocks; + int i; + + for (i = 0; i < num_planes; i++) { + ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); + + result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i], + ddb_blocks, + latency, + &result->plane_res_b[i], + &result->plane_res_l[i]); + } + + ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]); + result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks, + latency, &result->cursor_res_b, + &result->cursor_res_l); +} + +static void skl_compute_pipe_wm(struct drm_crtc *crtc, + struct skl_ddb_allocation *ddb, + struct skl_pipe_wm_parameters *params, + struct skl_pipe_wm *pipe_wm) +{ + struct drm_device *dev = crtc->dev; + const struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int level, max_level = ilk_wm_max_level(dev); + + for (level = 0; level <= max_level; level++) { + skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe, + level, intel_num_planes(intel_crtc), + &pipe_wm->wm[level]); + } + pipe_wm->linetime = skl_compute_linetime_wm(crtc, params); + + skl_compute_transition_wm(crtc, params, pipe_wm); +} + +static void skl_compute_wm_results(struct drm_device *dev, + struct skl_pipe_wm_parameters *p, + struct skl_pipe_wm *p_wm, + struct skl_wm_values *r, + struct intel_crtc *intel_crtc) +{ + int level, max_level = ilk_wm_max_level(dev); + enum pipe pipe = intel_crtc->pipe; + + for (level = 0; level <= max_level; level++) { + uint16_t ddb_blocks; + uint32_t temp; + int i; + + for (i = 0; i < intel_num_planes(intel_crtc); i++) { + temp = 0; + ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]); + + if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) || + (p_wm->wm[level].plane_res_l[i] > 31)) + p_wm->wm[level].plane_en[i] = false; + + temp |= p_wm->wm[level].plane_res_l[i] << + PLANE_WM_LINES_SHIFT; + temp |= p_wm->wm[level].plane_res_b[i]; + if (p_wm->wm[level].plane_en[i]) + temp |= PLANE_WM_EN; + + r->plane[pipe][i][level] = temp; + /* Use the LP0 WM value for transition WM for now. */ + if (level == 0) + r->plane_trans[pipe][i] = temp; + } + + temp = 0; + ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]); + + if ((p_wm->wm[level].cursor_res_b > ddb_blocks) || + (p_wm->wm[level].cursor_res_l > 31)) + p_wm->wm[level].cursor_en = false; + + temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT; + temp |= p_wm->wm[level].cursor_res_b; + + if (p_wm->wm[level].cursor_en) + temp |= PLANE_WM_EN; + + r->cursor[pipe][level] = temp; + /* Use the LP0 WM value for transition WM for now. */ + if (level == 0) + r->cursor_trans[pipe] = temp; + + } + + r->wm_linetime[pipe] = p_wm->linetime; +} + +static void skl_write_wm_values(struct drm_i915_private *dev_priv, + const struct skl_wm_values *new) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { + int i, level, max_level = ilk_wm_max_level(dev); + enum pipe pipe = crtc->pipe; + + if (new->dirty[pipe]) { + I915_WRITE(PIPE_WM_LINETIME(pipe), + new->wm_linetime[pipe]); + + for (level = 0; level <= max_level; level++) { + for (i = 0; i < intel_num_planes(crtc); i++) + I915_WRITE(PLANE_WM(pipe, i, level), + new->plane[pipe][i][level]); + I915_WRITE(CUR_WM(pipe, level), + new->cursor[pipe][level]); + } + for (i = 0; i < intel_num_planes(crtc); i++) + I915_WRITE(PLANE_WM_TRANS(pipe, i), + new->plane_trans[pipe][i]); + I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); + } + } + + dev_priv->wm.skl_hw = *new; +} + +static bool skl_update_pipe_wm(struct drm_crtc *crtc, + struct skl_pipe_wm_parameters *params, + struct intel_wm_config *config, + struct skl_ddb_allocation *ddb, /* out */ + struct skl_pipe_wm *pipe_wm /* out */) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + skl_compute_wm_pipe_parameters(crtc, params); + skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); + + if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) + return false; + + intel_crtc->wm.skl_active = *pipe_wm; + return true; +} + +static void skl_update_other_pipe_wm(struct drm_device *dev, + struct drm_crtc *crtc, + struct intel_wm_config *config, + struct skl_wm_values *r) +{ + struct intel_crtc *intel_crtc; + struct intel_crtc *this_crtc = to_intel_crtc(crtc); + + /* + * If the WM update hasn't changed the allocation for this_crtc (the + * crtc we are currently computing the new WM values for), other + * enabled crtcs will keep the same allocation and we don't need to + * recompute anything for them. + */ + if (!skl_ddb_allocation_changed(&r->ddb, this_crtc)) + return; + + /* + * Otherwise, because of this_crtc being freshly enabled/disabled, the + * other active pipes need new DDB allocation and WM values. + */ + list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, + base.head) { + struct skl_pipe_wm_parameters params = {}; + struct skl_pipe_wm pipe_wm = {}; + bool wm_changed; + + if (this_crtc->pipe == intel_crtc->pipe) + continue; + + if (!intel_crtc->active) + continue; + + wm_changed = skl_update_pipe_wm(&intel_crtc->base, + ¶ms, config, + &r->ddb, &pipe_wm); + + /* + * If we end up re-computing the other pipe WM values, it's + * because it was really needed, so we expect the WM values to + * be different. + */ + WARN_ON(!wm_changed); + + skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); + r->dirty[intel_crtc->pipe] = true; + } +} + +static void skl_update_wm(struct drm_crtc *crtc) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct skl_pipe_wm_parameters params = {}; + struct skl_wm_values *results = &dev_priv->wm.skl_results; + struct skl_pipe_wm pipe_wm = {}; + struct intel_wm_config config = {}; + + memset(results, 0, sizeof(*results)); + + skl_compute_wm_global_parameters(dev, &config); + + if (!skl_update_pipe_wm(crtc, ¶ms, &config, + &results->ddb, &pipe_wm)) + return; + + skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc); + results->dirty[intel_crtc->pipe] = true; + + skl_update_other_pipe_wm(dev, crtc, &config, results); + skl_write_wm_values(dev_priv, results); +} + +static void +skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, + uint32_t sprite_width, uint32_t sprite_height, + int pixel_size, bool enabled, bool scaled) +{ + struct intel_plane *intel_plane = to_intel_plane(plane); + + intel_plane->wm.enabled = enabled; + intel_plane->wm.scaled = scaled; + intel_plane->wm.horiz_pixels = sprite_width; + intel_plane->wm.vert_pixels = sprite_height; + intel_plane->wm.bytes_per_pixel = pixel_size; + + skl_update_wm(crtc); +} + static void ilk_update_wm(struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -6198,6 +6618,8 @@ void intel_init_pm(struct drm_device *dev) skl_setup_wm_latency(dev); dev_priv->display.init_clock_gating = gen9_init_clock_gating; + dev_priv->display.update_wm = skl_update_wm; + dev_priv->display.update_sprite_wm = skl_update_sprite_wm; } else if (HAS_PCH_SPLIT(dev)) { ilk_setup_wm_latency(dev); -- GitLab From b9cec07585cf1f554810097b8088b8e1f3f5137b Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:43 +0000 Subject: [PATCH 3883/9457] drm/i915/skl: Allocate DDB portions for display planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Fix the 3rd plane/cursor logic (Pradeep Bhat) v3: Fix one-by-one error in the DDB allocation code v4: Rebase on top of the skl_pipe_pixel_rate() argument change v5: Replace the available/start/end output parameters of skl_ddb_get_pipe_allocation_limits() by a single ddb entry constify a few arguments Make nth_active_pipe 0 indexed Use sizeof(variable) instead of sizeof(type) (Ville) v6: Use the for_each_crtc() macro instead of list_for_each_entry() Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 148 ++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5500c5343e0e..b5c7c4b4c091 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2973,6 +2973,153 @@ static bool ilk_disable_lp_wm(struct drm_device *dev) return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } +/* + * On gen9, we need to allocate Display Data Buffer (DDB) portions to the + * different active planes. + */ + +#define SKL_DDB_SIZE 896 /* in blocks */ + +static void +skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, + struct drm_crtc *for_crtc, + const struct intel_wm_config *config, + const struct skl_pipe_wm_parameters *params, + struct skl_ddb_entry *alloc /* out */) +{ + struct drm_crtc *crtc; + unsigned int pipe_size, ddb_size; + int nth_active_pipe; + + if (!params->active) { + alloc->start = 0; + alloc->end = 0; + return; + } + + ddb_size = SKL_DDB_SIZE; + + ddb_size -= 4; /* 4 blocks for bypass path allocation */ + + nth_active_pipe = 0; + for_each_crtc(dev, crtc) { + if (!intel_crtc_active(crtc)) + continue; + + if (crtc == for_crtc) + break; + + nth_active_pipe++; + } + + pipe_size = ddb_size / config->num_pipes_active; + alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active; + alloc->end = alloc->start + pipe_size - 1; +} + +static unsigned int skl_cursor_allocation(const struct intel_wm_config *config) +{ + if (config->num_pipes_active == 1) + return 32; + + return 8; +} + +static unsigned int +skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p) +{ + return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; +} + +/* + * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching + * a 8192x4096@32bpp framebuffer: + * 3 * 4096 * 8192 * 4 < 2^32 + */ +static unsigned int +skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, + const struct skl_pipe_wm_parameters *params) +{ + unsigned int total_data_rate = 0; + int plane; + + for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { + const struct intel_plane_wm_parameters *p; + + p = ¶ms->plane[plane]; + if (!p->enabled) + continue; + + total_data_rate += skl_plane_relative_data_rate(p); + } + + return total_data_rate; +} + +static void +skl_allocate_pipe_ddb(struct drm_crtc *crtc, + const struct intel_wm_config *config, + const struct skl_pipe_wm_parameters *params, + struct skl_ddb_allocation *ddb /* out */) +{ + struct drm_device *dev = crtc->dev; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct skl_ddb_entry alloc; + uint16_t alloc_size, start, cursor_blocks; + unsigned int total_data_rate; + int plane; + + skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc); + alloc_size = skl_ddb_entry_size(&alloc); + if (alloc_size == 0) { + memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); + memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); + return; + } + + cursor_blocks = skl_cursor_allocation(config); + ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1; + ddb->cursor[pipe].end = alloc.end; + + alloc_size -= cursor_blocks; + alloc.end -= cursor_blocks; + + /* + * Each active plane get a portion of the remaining space, in + * proportion to the amount of data they need to fetch from memory. + * + * FIXME: we may not allocate every single block here. + */ + total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); + + start = alloc.start; + for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { + const struct intel_plane_wm_parameters *p; + unsigned int data_rate; + uint16_t plane_blocks; + + p = ¶ms->plane[plane]; + if (!p->enabled) + continue; + + data_rate = skl_plane_relative_data_rate(p); + + /* + * promote the expression to 64 bits to avoid overflowing, the + * result is < available as data_rate / total_data_rate < 1 + */ + plane_blocks = div_u64((uint64_t)alloc_size * data_rate, + total_data_rate); + + ddb->plane[pipe][plane].start = start; + ddb->plane[pipe][plane].end = start + plane_blocks - 1; + + start += plane_blocks; + } + +} + static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config) { /* TODO: Take into account the scalers once we support them */ @@ -3294,6 +3441,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); skl_compute_wm_pipe_parameters(crtc, params); + skl_allocate_pipe_ddb(crtc, config, params, ddb); skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) -- GitLab From 8211bd5bdf5e1cf860616138ed71600a24a827bd Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:44 +0000 Subject: [PATCH 3884/9457] drm/i915/skl: Program the DDB allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Adapt to the planes/cursor split Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++++++++++ drivers/gpu/drm/i915/intel_pm.c | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ccbaeb35d695..ea22e09bd4c5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4696,6 +4696,8 @@ enum punit_power_well { #define _PLANE_KEYMSK_2_A 0x70298 #define _PLANE_KEYMAX_1_A 0x701a0 #define _PLANE_KEYMAX_2_A 0x702a0 +#define _PLANE_BUF_CFG_1_A 0x7027c +#define _PLANE_BUF_CFG_2_A 0x7037c #define _PLANE_CTL_1_B 0x71180 #define _PLANE_CTL_2_B 0x71280 @@ -4773,6 +4775,20 @@ enum punit_power_well { #define PLANE_KEYMAX(pipe, plane) \ _PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe)) +#define _PLANE_BUF_CFG_1_B 0x7127c +#define _PLANE_BUF_CFG_2_B 0x7137c +#define _PLANE_BUF_CFG_1(pipe) \ + _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B) +#define _PLANE_BUF_CFG_2(pipe) \ + _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B) +#define PLANE_BUF_CFG(pipe, plane) \ + _PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe)) + +/* SKL new cursor registers */ +#define _CUR_BUF_CFG_A 0x7017c +#define _CUR_BUF_CFG_B 0x7117c +#define CUR_BUF_CFG(pipe) _PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B) + /* VBIOS regs */ #define VGACNTRL 0x71400 # define VGA_DISP_DISABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b5c7c4b4c091..c2f1441138be 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3426,6 +3426,15 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, I915_WRITE(PLANE_WM_TRANS(pipe, i), new->plane_trans[pipe][i]); I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); + + for (i = 0; i < intel_num_planes(crtc); i++) + I915_WRITE(PLANE_BUF_CFG(pipe, i), + new->ddb.plane[pipe][i].end << 16 | + new->ddb.plane[pipe][i].start); + + I915_WRITE(CUR_BUF_CFG(pipe), + new->ddb.cursor[pipe].end << 16 | + new->ddb.cursor[pipe].start); } } -- GitLab From 3078999f2a4ee4aaabf9df2166e4e43581bb357a Mon Sep 17 00:00:00 2001 From: Pradeep Bhat Date: Tue, 4 Nov 2014 17:06:45 +0000 Subject: [PATCH 3885/9457] drm/i915/skl: Read the pipe WM HW state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch provides the implementation for reading the pipe wm HW state. v2: Incorporated Damien's review comments and also made modifications to incorporate the plane/cursor split. v3: No need to ident a line that was fitting 80 chars Return early instead of indenting the remaining of a function (Damien) v4: Rebase on top of nightly (minor conflict in intel_drv.h) v5: Rebase on top of nightly (minor conflict in intel_drv.h) v6: Rebase on top of nightly (minor conflict in intel_drv.h) Reviewed-by: Ville Syrjälä Signed-off-by: Pradeep Bhat Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 104 +++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 84f4f0504bbb..01bc55850070 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13266,7 +13266,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, pll->on = false; } - if (HAS_PCH_SPLIT(dev)) + if (IS_GEN9(dev)) + skl_wm_get_hw_state(dev); + else if (HAS_PCH_SPLIT(dev)) ilk_wm_get_hw_state(dev); if (force_restore) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 446be27ce76f..1cdd6f95a445 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1164,6 +1164,7 @@ void gen6_update_ring_freq(struct drm_device *dev); void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_boost(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_device *dev); +void skl_wm_get_hw_state(struct drm_device *dev); /* intel_sdvo.c */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c2f1441138be..09a81b3a754d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3624,6 +3624,110 @@ ilk_update_sprite_wm(struct drm_plane *plane, ilk_update_wm(crtc); } +static void skl_pipe_wm_active_state(uint32_t val, + struct skl_pipe_wm *active, + bool is_transwm, + bool is_cursor, + int i, + int level) +{ + bool is_enabled = (val & PLANE_WM_EN) != 0; + + if (!is_transwm) { + if (!is_cursor) { + active->wm[level].plane_en[i] = is_enabled; + active->wm[level].plane_res_b[i] = + val & PLANE_WM_BLOCKS_MASK; + active->wm[level].plane_res_l[i] = + (val >> PLANE_WM_LINES_SHIFT) & + PLANE_WM_LINES_MASK; + } else { + active->wm[level].cursor_en = is_enabled; + active->wm[level].cursor_res_b = + val & PLANE_WM_BLOCKS_MASK; + active->wm[level].cursor_res_l = + (val >> PLANE_WM_LINES_SHIFT) & + PLANE_WM_LINES_MASK; + } + } else { + if (!is_cursor) { + active->trans_wm.plane_en[i] = is_enabled; + active->trans_wm.plane_res_b[i] = + val & PLANE_WM_BLOCKS_MASK; + active->trans_wm.plane_res_l[i] = + (val >> PLANE_WM_LINES_SHIFT) & + PLANE_WM_LINES_MASK; + } else { + active->trans_wm.cursor_en = is_enabled; + active->trans_wm.cursor_res_b = + val & PLANE_WM_BLOCKS_MASK; + active->trans_wm.cursor_res_l = + (val >> PLANE_WM_LINES_SHIFT) & + PLANE_WM_LINES_MASK; + } + } +} + +static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct skl_wm_values *hw = &dev_priv->wm.skl_hw; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct skl_pipe_wm *active = &intel_crtc->wm.skl_active; + enum pipe pipe = intel_crtc->pipe; + int level, i, max_level; + uint32_t temp; + + max_level = ilk_wm_max_level(dev); + + hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); + + for (level = 0; level <= max_level; level++) { + for (i = 0; i < intel_num_planes(intel_crtc); i++) + hw->plane[pipe][i][level] = + I915_READ(PLANE_WM(pipe, i, level)); + hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level)); + } + + for (i = 0; i < intel_num_planes(intel_crtc); i++) + hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); + hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe)); + + if (!intel_crtc_active(crtc)) + return; + + hw->dirty[pipe] = true; + + active->linetime = hw->wm_linetime[pipe]; + + for (level = 0; level <= max_level; level++) { + for (i = 0; i < intel_num_planes(intel_crtc); i++) { + temp = hw->plane[pipe][i][level]; + skl_pipe_wm_active_state(temp, active, false, + false, i, level); + } + temp = hw->cursor[pipe][level]; + skl_pipe_wm_active_state(temp, active, false, true, i, level); + } + + for (i = 0; i < intel_num_planes(intel_crtc); i++) { + temp = hw->plane_trans[pipe][i]; + skl_pipe_wm_active_state(temp, active, true, false, i, 0); + } + + temp = hw->cursor_trans[pipe]; + skl_pipe_wm_active_state(temp, active, true, true, i, 0); +} + +void skl_wm_get_hw_state(struct drm_device *dev) +{ + struct drm_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + skl_pipe_wm_get_hw_state(crtc); +} + static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; -- GitLab From 367294be7c257dd4d8d8f0e296aa9824eae18568 Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Tue, 4 Nov 2014 17:06:46 +0000 Subject: [PATCH 3886/9457] drm/i915/gen9: Add 2us read latency to WM level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the updated Bspec, The mailbox response data is not currently accounting for memory read latency. Add 2 microseconds to the result for each level. This patch adds 2us to latency of level 0 for all cases and for all other levels (1-7) only if latency[level] > 0. v2: Slightly rework the patch and add a big comment (Damien) v3: Rebase on top of the renames of the memory latency defines Signed-off-by: Vandana Kannan (v1) Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä (v2) Reviewed-by: M, Satheeshakrishna (v1) Cc: Lespiau, Damien Cc: M, Satheeshakrishna Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 09a81b3a754d..44fecfc3fc52 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2286,6 +2286,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) if (IS_GEN9(dev)) { uint32_t val; int ret; + int level, max_level = ilk_wm_max_level(dev); /* read the first set of memory latencies[0:3] */ val = 0; /* data0 to be programmed to 0 for first set */ @@ -2328,6 +2329,21 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & GEN9_MEM_LATENCY_LEVEL_MASK; + /* + * punit doesn't take into account the read latency so we need + * to add 2us to the various latency levels we retrieve from + * the punit. + * - W0 is a bit special in that it's the only level that + * can't be disabled if we want to have display working, so + * we always add 2us there. + * - For levels >=1, punit returns 0us latency when they are + * disabled, so we respect that and don't add 2us then + */ + wm[0] += 2; + for (level = 1; level <= max_level; level++) + if (wm[level] != 0) + wm[level] += 2; + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { uint64_t sskpd = I915_READ64(MCH_SSKPD); -- GitLab From 4f94738674b813fe0ef8e7dbef8a24aeb8c2271a Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Tue, 4 Nov 2014 17:06:47 +0000 Subject: [PATCH 3887/9457] drm/i915/gen9: Disable WM if corresponding latency is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to updated BSpec, If level 1 or any higher level has a value of 0x00, that level and any higher levels are unused and the associated watermark registers must not be enabled. This patch checks for latency 0 for level >=1 and does not enable WM corresponding to level m | m>=n, if level n (n != 0) has a 0us latency. v2: Satheesh's review comments - zero-out latency values (for all higher levels if latency of given level is zero ) in read_wm_latency() function itself v3: removed redundant check as per Satheesh's observation. v4: rebase on top before merging (Damien) v5: Rebase on top of the default value removal (Ville) Reviewed-by: Satheeshakrishna M (v3) Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Vandana Kannan Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 44fecfc3fc52..bf2cd650880e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2285,7 +2285,7 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) if (IS_GEN9(dev)) { uint32_t val; - int ret; + int ret, i; int level, max_level = ilk_wm_max_level(dev); /* read the first set of memory latencies[0:3] */ @@ -2338,12 +2338,22 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) * we always add 2us there. * - For levels >=1, punit returns 0us latency when they are * disabled, so we respect that and don't add 2us then + * + * Additionally, if a level n (n > 1) has a 0us latency, all + * levels m (m >= n) need to be disabled. We make sure to + * sanitize the values out of the punit to satisfy this + * requirement. */ wm[0] += 2; for (level = 1; level <= max_level; level++) if (wm[level] != 0) wm[level] += 2; + else { + for (i = level + 1; i <= max_level; i++) + wm[i] = 0; + break; + } } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { uint64_t sskpd = I915_READ64(MCH_SSKPD); @@ -3285,7 +3295,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, uint32_t method1, method2, plane_bytes_per_line; uint32_t result_bytes; - if (!p->active || !p_params->enabled) + if (mem_value == 0 || !p->active || !p_params->enabled) return false; method1 = skl_wm_method1(p->pixel_rate, -- GitLab From 53b0deb4cba206c6f8cf9225080ac49e02183376 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:48 +0000 Subject: [PATCH 3888/9457] drm/i915/skl: Store the new WM state at the very end of the update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're going to add a new step, let's not hide the copy of the new WM state inside one inner function, but as a 1st level operation in the WM update. v2: Split the staging results structure to not exceed the 1Kb stack allocation in skl_update_wm() Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index bf2cd650880e..a4294b1b93ca 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3463,8 +3463,6 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, new->ddb.cursor[pipe].start); } } - - dev_priv->wm.skl_hw = *new; } static bool skl_update_pipe_wm(struct drm_crtc *crtc, @@ -3558,6 +3556,9 @@ static void skl_update_wm(struct drm_crtc *crtc) skl_update_other_pipe_wm(dev, crtc, &config, results); skl_write_wm_values(dev_priv, results); + + /* store the new configuration */ + dev_priv->wm.skl_hw = *results; } static void -- GitLab From a269c5839bc4e3a997228314cb2efbddc9da604a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:49 +0000 Subject: [PATCH 3889/9457] drm/i915/skl: Read back the DDB allocation hw state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This logically belongs to the WM state, so do it there. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a4294b1b93ca..8b7abc7c5604 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3051,6 +3051,32 @@ static unsigned int skl_cursor_allocation(const struct intel_wm_config *config) return 8; } +static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) +{ + entry->start = reg & 0x3ff; + entry->end = (reg >> 16) & 0x3ff; +} + +static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */) +{ + struct drm_device *dev = dev_priv->dev; + enum pipe pipe; + int plane; + u32 val; + + for_each_pipe(dev_priv, pipe) { + for_each_plane(pipe, plane) { + val = I915_READ(PLANE_BUF_CFG(pipe, plane)); + skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane], + val); + } + + val = I915_READ(CUR_BUF_CFG(pipe)); + skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val); + } +} + static unsigned int skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p) { @@ -3749,8 +3775,11 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) void skl_wm_get_hw_state(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; struct drm_crtc *crtc; + skl_ddb_get_hw_state(dev_priv, ddb); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) skl_pipe_wm_get_hw_state(crtc); } -- GitLab From 97e94b22ed4fe116beadbdbe4667f2a2f9aa9fd0 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:50 +0000 Subject: [PATCH 3890/9457] drm/i915/skl: Augment the latency debugfs files for SKL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Use the gen >= 9 in the debugfs file condition (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 76 +++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0a6981399642..b1cbfbf84fe1 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3523,7 +3523,7 @@ static const struct file_operations i915_display_crc_ctl_fops = { .write = display_crc_ctl_write }; -static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) +static void wm_latency_show(struct seq_file *m, const uint16_t wm[8]) { struct drm_device *dev = m->private; int num_levels = ilk_wm_max_level(dev) + 1; @@ -3534,13 +3534,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) for (level = 0; level < num_levels; level++) { unsigned int latency = wm[level]; - /* WM1+ latency values in 0.5us units */ - if (level > 0) + /* + * - WM1+ latency values in 0.5us units + * - latencies are in us on gen9 + */ + if (INTEL_INFO(dev)->gen >= 9) + latency *= 10; + else if (level > 0) latency *= 5; seq_printf(m, "WM%d %u (%u.%u usec)\n", - level, wm[level], - latency / 10, latency % 10); + level, wm[level], latency / 10, latency % 10); } drm_modeset_unlock_all(dev); @@ -3549,8 +3553,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) static int pri_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + const uint16_t *latencies; + + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.pri_latency; - wm_latency_show(m, to_i915(dev)->wm.pri_latency); + wm_latency_show(m, latencies); return 0; } @@ -3558,8 +3569,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data) static int spr_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + const uint16_t *latencies; + + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.spr_latency; - wm_latency_show(m, to_i915(dev)->wm.spr_latency); + wm_latency_show(m, latencies); return 0; } @@ -3567,8 +3585,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data) static int cur_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + const uint16_t *latencies; + + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.cur_latency; - wm_latency_show(m, to_i915(dev)->wm.cur_latency); + wm_latency_show(m, latencies); return 0; } @@ -3604,11 +3629,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file) } static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, - size_t len, loff_t *offp, uint16_t wm[5]) + size_t len, loff_t *offp, uint16_t wm[8]) { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; - uint16_t new[5] = { 0 }; + uint16_t new[8] = { 0 }; int num_levels = ilk_wm_max_level(dev) + 1; int level; int ret; @@ -3622,7 +3647,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, tmp[len] = '\0'; - ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]); + ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu", + &new[0], &new[1], &new[2], &new[3], + &new[4], &new[5], &new[6], &new[7]); if (ret != num_levels) return -EINVAL; @@ -3642,8 +3669,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + uint16_t *latencies; - return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency); + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.pri_latency; + + return wm_latency_write(file, ubuf, len, offp, latencies); } static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, @@ -3651,8 +3685,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + uint16_t *latencies; - return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency); + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.spr_latency; + + return wm_latency_write(file, ubuf, len, offp, latencies); } static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, @@ -3660,8 +3701,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; + struct drm_i915_private *dev_priv = dev->dev_private; + uint16_t *latencies; + + if (INTEL_INFO(dev)->gen >= 9) + latencies = dev_priv->wm.skl_latency; + else + latencies = to_i915(dev)->wm.cur_latency; - return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency); + return wm_latency_write(file, ubuf, len, offp, latencies); } static const struct file_operations i915_pri_wm_latency_fops = { -- GitLab From c5511e44e8a643cf6400e8dbf9e4f6d348786112 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:51 +0000 Subject: [PATCH 3891/9457] drm/i915/skl: Add a debugfs file to dump the DDB allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: minor conflict in i915_debugfs.c v3: Rebase on top of the for_each_pipe() change adding dev_priv as first argument. v4: minor conflict in the i915_debugfs_files array v5: minor conflict in the i915_debugfs_files array Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b1cbfbf84fe1..319da61354b0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2679,6 +2679,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused) return 0; } +static int i915_ddb_info(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct skl_ddb_allocation *ddb; + struct skl_ddb_entry *entry; + enum pipe pipe; + int plane; + + drm_modeset_lock_all(dev); + + ddb = &dev_priv->wm.skl_hw.ddb; + + seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); + + for_each_pipe(dev_priv, pipe) { + seq_printf(m, "Pipe %c\n", pipe_name(pipe)); + + for_each_plane(pipe, plane) { + entry = &ddb->plane[pipe][plane]; + seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1, + entry->start, entry->end, + skl_ddb_entry_size(entry)); + } + + entry = &ddb->cursor[pipe]; + seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start, + entry->end, skl_ddb_entry_size(entry)); + } + + drm_modeset_unlock_all(dev); + + return 0; +} + struct pipe_crc_info { const char *name; struct drm_device *dev; @@ -4252,6 +4288,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_wa_registers", i915_wa_registers, 0}, + {"i915_ddb_info", i915_ddb_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- GitLab From 08db665203d5e587efc391afc405a9317d29fe17 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:52 +0000 Subject: [PATCH 3892/9457] drm/i915/skl: Check the DDB state at modeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Don't check DDB on pre-SKL platforms Don't check DDB state on disabled pipes v3: Squash "Expose skl_ddb_get_hw_state()" Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 9 +++++ drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_pm.c | 4 +-- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fbe18aed254d..ee744a2c2085 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1400,6 +1400,15 @@ static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry) return entry->end - entry->start + 1; } +static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, + const struct skl_ddb_entry *e2) +{ + if (e1->start == e2->start && e1->end == e2->end) + return true; + + return false; +} + struct skl_ddb_allocation { struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; struct skl_ddb_entry cursor[I915_MAX_PIPES]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 01bc55850070..07fb0ff66f5d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10511,6 +10511,56 @@ intel_pipe_config_compare(struct drm_device *dev, return true; } +static void check_wm_state(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct skl_ddb_allocation hw_ddb, *sw_ddb; + struct intel_crtc *intel_crtc; + int plane; + + if (INTEL_INFO(dev)->gen < 9) + return; + + skl_ddb_get_hw_state(dev_priv, &hw_ddb); + sw_ddb = &dev_priv->wm.skl_hw.ddb; + + for_each_intel_crtc(dev, intel_crtc) { + struct skl_ddb_entry *hw_entry, *sw_entry; + const enum pipe pipe = intel_crtc->pipe; + + if (!intel_crtc->active) + continue; + + /* planes */ + for_each_plane(pipe, plane) { + hw_entry = &hw_ddb.plane[pipe][plane]; + sw_entry = &sw_ddb->plane[pipe][plane]; + + if (skl_ddb_entry_equal(hw_entry, sw_entry)) + continue; + + DRM_ERROR("mismatch in DDB state pipe %c plane %d " + "(expected (%u,%u), found (%u,%u))\n", + pipe_name(pipe), plane + 1, + sw_entry->start, sw_entry->end, + hw_entry->start, hw_entry->end); + } + + /* cursor */ + hw_entry = &hw_ddb.cursor[pipe]; + sw_entry = &sw_ddb->cursor[pipe]; + + if (skl_ddb_entry_equal(hw_entry, sw_entry)) + continue; + + DRM_ERROR("mismatch in DDB state pipe %c cursor " + "(expected (%u,%u), found (%u,%u))\n", + pipe_name(pipe), + sw_entry->start, sw_entry->end, + hw_entry->start, hw_entry->end); + } +} + static void check_connector_state(struct drm_device *dev) { @@ -10710,6 +10760,7 @@ check_shared_dpll_state(struct drm_device *dev) void intel_modeset_check_state(struct drm_device *dev) { + check_wm_state(dev); check_connector_state(dev); check_encoder_state(dev); check_crtc_state(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1cdd6f95a445..cb0e9dbf1c96 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1165,6 +1165,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_boost(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_device *dev); void skl_wm_get_hw_state(struct drm_device *dev); +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */); /* intel_sdvo.c */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 8b7abc7c5604..159c2e083e54 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3057,8 +3057,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) entry->end = (reg >> 16) & 0x3ff; } -static void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb /* out */) +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */) { struct drm_device *dev = dev_priv->dev; enum pipe pipe; -- GitLab From 16160e3dd32343de9d6115353408728adecdecfb Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:53 +0000 Subject: [PATCH 3893/9457] drm/i915/skl: Make 'end' of the DDB allocation entry exclusive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ville suggested that we should use the same semantics as C arrays to reduce the number of those pesky +1/-1 in the allocation code. This patch leaves the debugfs file as is, showing the internal DDB allocation structure, not the values written in the registers. v2: Remove the test on ->end in skl_ddb_entry_size() (Ville) Reviewed-by: Ville Syrjälä Suggested-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 8 ++------ drivers/gpu/drm/i915/intel_pm.c | 28 +++++++++++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ee744a2c2085..84e8cdb1c571 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1388,16 +1388,12 @@ struct ilk_wm_values { }; struct skl_ddb_entry { - uint16_t start, end; /* in number of blocks */ + uint16_t start, end; /* in number of blocks, 'end' is exclusive */ }; static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry) { - /* end not set, clearly no allocation here. start can be 0 though */ - if (entry->end == 0) - return 0; - - return entry->end - entry->start + 1; + return entry->end - entry->start; } static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 159c2e083e54..e417a6a301d1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3040,7 +3040,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, pipe_size = ddb_size / config->num_pipes_active; alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active; - alloc->end = alloc->start + pipe_size - 1; + alloc->end = alloc->start + pipe_size; } static unsigned int skl_cursor_allocation(const struct intel_wm_config *config) @@ -3055,6 +3055,8 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) { entry->start = reg & 0x3ff; entry->end = (reg >> 16) & 0x3ff; + if (entry->end) + entry->end += 1; } void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, @@ -3131,7 +3133,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, } cursor_blocks = skl_cursor_allocation(config); - ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1; + ddb->cursor[pipe].start = alloc.end - cursor_blocks; ddb->cursor[pipe].end = alloc.end; alloc_size -= cursor_blocks; @@ -3165,7 +3167,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, total_data_rate); ddb->plane[pipe][plane].start = start; - ddb->plane[pipe][plane].end = start + plane_blocks - 1; + ddb->plane[pipe][plane].end = start + plane_blocks; start += plane_blocks; } @@ -3453,6 +3455,15 @@ static void skl_compute_wm_results(struct drm_device *dev, r->wm_linetime[pipe] = p_wm->linetime; } +static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, uint32_t reg, + const struct skl_ddb_entry *entry) +{ + if (entry->end) + I915_WRITE(reg, (entry->end - 1) << 16 | entry->start); + else + I915_WRITE(reg, 0); +} + static void skl_write_wm_values(struct drm_i915_private *dev_priv, const struct skl_wm_values *new) { @@ -3480,13 +3491,12 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); for (i = 0; i < intel_num_planes(crtc); i++) - I915_WRITE(PLANE_BUF_CFG(pipe, i), - new->ddb.plane[pipe][i].end << 16 | - new->ddb.plane[pipe][i].start); + skl_ddb_entry_write(dev_priv, + PLANE_BUF_CFG(pipe, i), + &new->ddb.plane[pipe][i]); - I915_WRITE(CUR_BUF_CFG(pipe), - new->ddb.cursor[pipe].end << 16 | - new->ddb.cursor[pipe].start); + skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), + &new->ddb.cursor[pipe]); } } } -- GitLab From 21fca258bc09b951b66ff5c501a37b56be4d4310 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:54 +0000 Subject: [PATCH 3894/9457] drm/i915/skl: Use a more descriptive parameter name in skl_compute_plane_wm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What we're talking about here is the DDB allocation (in blocks). That's more descriptive than 'max_page_buff_alloc'. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e417a6a301d1..0142ad146224 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3315,7 +3315,7 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, struct intel_plane_wm_parameters *p_params, - uint16_t max_page_buff_alloc, + uint16_t ddb_allocation, uint32_t mem_value, uint16_t *res_blocks, /* out */ uint8_t *res_lines /* out */) @@ -3339,7 +3339,7 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, p_params->bytes_per_pixel; /* For now xtile and linear */ - if (((max_page_buff_alloc * 512) / plane_bytes_per_line) >= 1) + if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1) result_bytes = min(method1, method2); else result_bytes = method1; -- GitLab From e6d6617152def4f9d46fb9c5cba3e322bedc27c2 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:55 +0000 Subject: [PATCH 3895/9457] drm/i915/skl: Make res_blocks/lines intermediate values 32 bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To align with the ilk WM code and because it makes sense to test against the upper bounds as soon as possible on variables that are bigger than the number of bits in the register, let's move the maximum checks from skl_compute_wm_results() to skl_compute_plane_wm(). v2: Leave the result values to 0 when overflowing the limits (Ville) Use 32 bits intermediate variables (Damien) Instead of using the 16 and 8 bits space we have in the result structure, use 32 bits local variables until we're sure they fit into the constraints. Suggested-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0142ad146224..858029878d38 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3317,10 +3317,10 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, struct intel_plane_wm_parameters *p_params, uint16_t ddb_allocation, uint32_t mem_value, - uint16_t *res_blocks, /* out */ - uint8_t *res_lines /* out */) + uint16_t *out_blocks, /* out */ + uint8_t *out_lines /* out */) { - uint32_t method1, method2, plane_bytes_per_line; + uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines; uint32_t result_bytes; if (mem_value == 0 || !p->active || !p_params->enabled) @@ -3344,8 +3344,14 @@ static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, else result_bytes = method1; - *res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1; - *res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line); + res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1; + res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line); + + if (res_blocks > ddb_allocation || res_lines > 31) + return false; + + *out_blocks = res_blocks; + *out_lines = res_lines; return true; } @@ -3408,17 +3414,11 @@ static void skl_compute_wm_results(struct drm_device *dev, enum pipe pipe = intel_crtc->pipe; for (level = 0; level <= max_level; level++) { - uint16_t ddb_blocks; uint32_t temp; int i; for (i = 0; i < intel_num_planes(intel_crtc); i++) { temp = 0; - ddb_blocks = skl_ddb_entry_size(&r->ddb.plane[pipe][i]); - - if ((p_wm->wm[level].plane_res_b[i] > ddb_blocks) || - (p_wm->wm[level].plane_res_l[i] > 31)) - p_wm->wm[level].plane_en[i] = false; temp |= p_wm->wm[level].plane_res_l[i] << PLANE_WM_LINES_SHIFT; @@ -3433,11 +3433,6 @@ static void skl_compute_wm_results(struct drm_device *dev, } temp = 0; - ddb_blocks = skl_ddb_entry_size(&r->ddb.cursor[pipe]); - - if ((p_wm->wm[level].cursor_res_b > ddb_blocks) || - (p_wm->wm[level].cursor_res_l > 31)) - p_wm->wm[level].cursor_en = false; temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT; temp |= p_wm->wm[level].cursor_res_b; -- GitLab From b99f58dabb9dae18c97a9e3812ba9961b207fd45 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:56 +0000 Subject: [PATCH 3896/9457] drm/i915/skl: Reduce the number of holes in struct skl_wm_level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 84e8cdb1c571..cf84b6d30eae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1422,9 +1422,9 @@ struct skl_wm_values { struct skl_wm_level { bool plane_en[I915_MAX_PLANES]; + bool cursor_en; uint16_t plane_res_b[I915_MAX_PLANES]; uint8_t plane_res_l[I915_MAX_PLANES]; - bool cursor_en; uint16_t cursor_res_b; uint8_t cursor_res_l; }; -- GitLab From 407b50f31ba19317cdc30530d30220182e42fa3d Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:57 +0000 Subject: [PATCH 3897/9457] drm/i915/skl: Move all the WM compute functions in one place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DDB allocation code managed to split in two the compute functions. Bring back skl_compute_transition_wm() and skl_compute_linetime_wm() with their little friends. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 858029878d38..66f142bcbee4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3217,28 +3217,6 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, return ret; } -static void skl_compute_transition_wm(struct drm_crtc *crtc, - struct skl_pipe_wm_parameters *params, - struct skl_pipe_wm *pipe_wm) -{ - /* - * For now it is suggested to use the LP0 wm val of corresponding - * plane as transition wm val. This is done while computing results. - */ - if (!params->active) - return; -} - -static uint32_t -skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) -{ - if (!intel_crtc_active(crtc)) - return 0; - - return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); - -} - static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb, const struct intel_crtc *intel_crtc) { @@ -3384,6 +3362,28 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, &result->cursor_res_l); } +static uint32_t +skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) +{ + if (!intel_crtc_active(crtc)) + return 0; + + return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); + +} + +static void skl_compute_transition_wm(struct drm_crtc *crtc, + struct skl_pipe_wm_parameters *params, + struct skl_pipe_wm *pipe_wm) +{ + /* + * For now it is suggested to use the LP0 wm val of corresponding + * plane as transition wm val. + */ + if (!params->active) + return; +} + static void skl_compute_pipe_wm(struct drm_crtc *crtc, struct skl_ddb_allocation *ddb, struct skl_pipe_wm_parameters *params, -- GitLab From 9414f563f3857018d87e480b7cd13636b0c00ce6 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:58 +0000 Subject: [PATCH 3898/9457] drm/i915/skl: Rework when the transition WMs are computed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The transition WMs code was doing a shortcut and the values were copied from the WM0 ones at compute_wm_results() time. Going forward, we want to compute them like the other WMs and resolve their final register values in the same way as well. This patch does just that and isolate the transtion WM compute code in skl_compute_transition_wm() while skl_compute_wm_results() takes care of the register values. We also take the opportunity to disable the transition WMs for now. We've noticed underruns and they seem to be the culprit. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 46 ++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 66f142bcbee4..41cfb2624cdc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3374,14 +3374,18 @@ skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) static void skl_compute_transition_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *params, - struct skl_pipe_wm *pipe_wm) + struct skl_wm_level *trans_wm /* out */) { - /* - * For now it is suggested to use the LP0 wm val of corresponding - * plane as transition wm val. - */ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int i; + if (!params->active) return; + + /* Until we know more, just disable transition WMs */ + for (i = 0; i < intel_num_planes(intel_crtc); i++) + trans_wm->plane_en[i] = false; + trans_wm->cursor_en = false; } static void skl_compute_pipe_wm(struct drm_crtc *crtc, @@ -3401,7 +3405,7 @@ static void skl_compute_pipe_wm(struct drm_crtc *crtc, } pipe_wm->linetime = skl_compute_linetime_wm(crtc, params); - skl_compute_transition_wm(crtc, params, pipe_wm); + skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm); } static void skl_compute_wm_results(struct drm_device *dev, @@ -3412,11 +3416,10 @@ static void skl_compute_wm_results(struct drm_device *dev, { int level, max_level = ilk_wm_max_level(dev); enum pipe pipe = intel_crtc->pipe; + uint32_t temp; + int i; for (level = 0; level <= max_level; level++) { - uint32_t temp; - int i; - for (i = 0; i < intel_num_planes(intel_crtc); i++) { temp = 0; @@ -3427,9 +3430,6 @@ static void skl_compute_wm_results(struct drm_device *dev, temp |= PLANE_WM_EN; r->plane[pipe][i][level] = temp; - /* Use the LP0 WM value for transition WM for now. */ - if (level == 0) - r->plane_trans[pipe][i] = temp; } temp = 0; @@ -3441,12 +3441,28 @@ static void skl_compute_wm_results(struct drm_device *dev, temp |= PLANE_WM_EN; r->cursor[pipe][level] = temp; - /* Use the LP0 WM value for transition WM for now. */ - if (level == 0) - r->cursor_trans[pipe] = temp; } + /* transition WMs */ + for (i = 0; i < intel_num_planes(intel_crtc); i++) { + temp = 0; + temp |= p_wm->trans_wm.plane_res_l[i] << PLANE_WM_LINES_SHIFT; + temp |= p_wm->trans_wm.plane_res_b[i]; + if (p_wm->trans_wm.plane_en[i]) + temp |= PLANE_WM_EN; + + r->plane_trans[pipe][i] = temp; + } + + temp = 0; + temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT; + temp |= p_wm->trans_wm.cursor_res_b; + if (p_wm->trans_wm.cursor_en) + temp |= PLANE_WM_EN; + + r->cursor_trans[pipe] = temp; + r->wm_linetime[pipe] = p_wm->linetime; } -- GitLab From afb024aa656b7d13392430a254b341728806c540 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:06:59 +0000 Subject: [PATCH 3899/9457] drm/i915/skl: Correctly align skl_compute_plane_wm() arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 41cfb2624cdc..176e9ef9b266 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3292,11 +3292,11 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, } static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, - struct intel_plane_wm_parameters *p_params, - uint16_t ddb_allocation, - uint32_t mem_value, - uint16_t *out_blocks, /* out */ - uint8_t *out_lines /* out */) + struct intel_plane_wm_parameters *p_params, + uint16_t ddb_allocation, + uint32_t mem_value, + uint16_t *out_blocks, /* out */ + uint8_t *out_lines /* out */) { uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines; uint32_t result_bytes; -- GitLab From 5d374d9638924ff8c91a87f55dc895be7ab163f8 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:07:00 +0000 Subject: [PATCH 3900/9457] drm/i915/skl: Reduce the indentation level in skl_write_wm_values() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can reduce the indentation level by continuing early. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 176e9ef9b266..7fdccba93385 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3485,30 +3485,30 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, int i, level, max_level = ilk_wm_max_level(dev); enum pipe pipe = crtc->pipe; - if (new->dirty[pipe]) { - I915_WRITE(PIPE_WM_LINETIME(pipe), - new->wm_linetime[pipe]); - - for (level = 0; level <= max_level; level++) { - for (i = 0; i < intel_num_planes(crtc); i++) - I915_WRITE(PLANE_WM(pipe, i, level), - new->plane[pipe][i][level]); - I915_WRITE(CUR_WM(pipe, level), - new->cursor[pipe][level]); - } - for (i = 0; i < intel_num_planes(crtc); i++) - I915_WRITE(PLANE_WM_TRANS(pipe, i), - new->plane_trans[pipe][i]); - I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); + if (!new->dirty[pipe]) + continue; - for (i = 0; i < intel_num_planes(crtc); i++) - skl_ddb_entry_write(dev_priv, - PLANE_BUF_CFG(pipe, i), - &new->ddb.plane[pipe][i]); + I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]); - skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), - &new->ddb.cursor[pipe]); + for (level = 0; level <= max_level; level++) { + for (i = 0; i < intel_num_planes(crtc); i++) + I915_WRITE(PLANE_WM(pipe, i, level), + new->plane[pipe][i][level]); + I915_WRITE(CUR_WM(pipe, level), + new->cursor[pipe][level]); } + for (i = 0; i < intel_num_planes(crtc); i++) + I915_WRITE(PLANE_WM_TRANS(pipe, i), + new->plane_trans[pipe][i]); + I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); + + for (i = 0; i < intel_num_planes(crtc); i++) + skl_ddb_entry_write(dev_priv, + PLANE_BUF_CFG(pipe, i), + &new->ddb.plane[pipe][i]); + + skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), + &new->ddb.cursor[pipe]); } } -- GitLab From 34bb56af7fae9d4d6a33bf6f5f915e75a4023e02 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:07:01 +0000 Subject: [PATCH 3901/9457] drm/i915/skl: Stage the pipe DDB allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To correctly flush the new DDB allocation we need to know about the pipe allocation layout inside the DDB in order to sequence the re-allocation to not cause a newly allocated pipe to fetch from a space that was previously allocated to another pipe. This patch preserves the per-pipe (start,end) allocation to be used in the flush. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cf84b6d30eae..01d741d37a85 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1406,6 +1406,7 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, } struct skl_ddb_allocation { + struct skl_ddb_entry pipe[I915_MAX_PIPES]; struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; struct skl_ddb_entry cursor[I915_MAX_PIPES]; }; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7fdccba93385..cd2b3351ff45 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3119,13 +3119,13 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; - struct skl_ddb_entry alloc; + struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; uint16_t alloc_size, start, cursor_blocks; unsigned int total_data_rate; int plane; - skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc); - alloc_size = skl_ddb_entry_size(&alloc); + skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); + alloc_size = skl_ddb_entry_size(alloc); if (alloc_size == 0) { memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); @@ -3133,11 +3133,11 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, } cursor_blocks = skl_cursor_allocation(config); - ddb->cursor[pipe].start = alloc.end - cursor_blocks; - ddb->cursor[pipe].end = alloc.end; + ddb->cursor[pipe].start = alloc->end - cursor_blocks; + ddb->cursor[pipe].end = alloc->end; alloc_size -= cursor_blocks; - alloc.end -= cursor_blocks; + alloc->end -= cursor_blocks; /* * Each active plane get a portion of the remaining space, in @@ -3147,7 +3147,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, */ total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); - start = alloc.start; + start = alloc->start; for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { const struct intel_plane_wm_parameters *p; unsigned int data_rate; -- GitLab From 0e8fb7ba7ca5410b2a8adc7f19eeb229ed01a32e Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:07:02 +0000 Subject: [PATCH 3902/9457] drm/i915/skl: Flush the WM configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we write new values for the DDB allocation and WM parameters, we now need to trigger the double buffer update for the pipe to take the new configuration into account. As the DDB is a global resource shared between planes, enabling or disabling one plane will result in changes for all planes that are currently in use, thus the need write PLANE_SURF/CUR_BASE for more than the plane we're touching. v2: Don't wait for pipes that are off v3: Split the staging results structure to not exceed the 1Kb stack allocation in skl_update_wm() v4: Rework and document the algorithm after Ville found that it was all wrong. Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cd2b3351ff45..ec7b86bfe701 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3512,6 +3512,140 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, } } +/* + * When setting up a new DDB allocation arrangement, we need to correctly + * sequence the times at which the new allocations for the pipes are taken into + * account or we'll have pipes fetching from space previously allocated to + * another pipe. + * + * Roughly the sequence looks like: + * 1. re-allocate the pipe(s) with the allocation being reduced and not + * overlapping with a previous light-up pipe (another way to put it is: + * pipes with their new allocation strickly included into their old ones). + * 2. re-allocate the other pipes that get their allocation reduced + * 3. allocate the pipes having their allocation increased + * + * Steps 1. and 2. are here to take care of the following case: + * - Initially DDB looks like this: + * | B | C | + * - enable pipe A. + * - pipe B has a reduced DDB allocation that overlaps with the old pipe C + * allocation + * | A | B | C | + * + * We need to sequence the re-allocation: C, B, A (and not B, C, A). + */ + +static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +{ + struct drm_device *dev = dev_priv->dev; + int plane; + + for_each_plane(pipe, plane) { + I915_WRITE(PLANE_SURF(pipe, plane), + I915_READ(PLANE_SURF(pipe, plane))); + } + I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); +} + +static bool +skl_ddb_allocation_included(const struct skl_ddb_allocation *old, + const struct skl_ddb_allocation *new, + enum pipe pipe) +{ + uint16_t old_size, new_size; + + old_size = skl_ddb_entry_size(&old->pipe[pipe]); + new_size = skl_ddb_entry_size(&new->pipe[pipe]); + + return old_size != new_size && + new->pipe[pipe].start >= old->pipe[pipe].start && + new->pipe[pipe].end <= old->pipe[pipe].end; +} + +static void skl_flush_wm_values(struct drm_i915_private *dev_priv, + struct skl_wm_values *new_values) +{ + struct drm_device *dev = dev_priv->dev; + struct skl_ddb_allocation *cur_ddb, *new_ddb; + bool reallocated[I915_MAX_PIPES] = {false, false, false}; + struct intel_crtc *crtc; + enum pipe pipe; + + new_ddb = &new_values->ddb; + cur_ddb = &dev_priv->wm.skl_hw.ddb; + + /* + * First pass: flush the pipes with the new allocation contained into + * the old space. + * + * We'll wait for the vblank on those pipes to ensure we can safely + * re-allocate the freed space without this pipe fetching from it. + */ + for_each_intel_crtc(dev, crtc) { + if (!crtc->active) + continue; + + pipe = crtc->pipe; + + if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) + continue; + + skl_wm_flush_pipe(dev_priv, pipe); + intel_wait_for_vblank(dev, pipe); + + reallocated[pipe] = true; + } + + + /* + * Second pass: flush the pipes that are having their allocation + * reduced, but overlapping with a previous allocation. + * + * Here as well we need to wait for the vblank to make sure the freed + * space is not used anymore. + */ + for_each_intel_crtc(dev, crtc) { + if (!crtc->active) + continue; + + pipe = crtc->pipe; + + if (reallocated[pipe]) + continue; + + if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < + skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { + skl_wm_flush_pipe(dev_priv, pipe); + intel_wait_for_vblank(dev, pipe); + } + + reallocated[pipe] = true; + } + + /* + * Third pass: flush the pipes that got more space allocated. + * + * We don't need to actively wait for the update here, next vblank + * will just get more DDB space with the correct WM values. + */ + for_each_intel_crtc(dev, crtc) { + if (!crtc->active) + continue; + + pipe = crtc->pipe; + + /* + * At this point, only the pipes more space than before are + * left to re-allocate. + */ + if (reallocated[pipe]) + continue; + + skl_wm_flush_pipe(dev_priv, pipe); + } +} + static bool skl_update_pipe_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *params, struct intel_wm_config *config, @@ -3603,6 +3737,7 @@ static void skl_update_wm(struct drm_crtc *crtc) skl_update_other_pipe_wm(dev, crtc, &config, results); skl_write_wm_values(dev_priv, results); + skl_flush_wm_values(dev_priv, results); /* store the new configuration */ dev_priv->wm.skl_hw = *results; -- GitLab From d21b795c419a7f59b4921b1ab5ff40d9a5eef05a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 4 Nov 2014 17:07:03 +0000 Subject: [PATCH 3903/9457] drm/i915/skl: Log the order in which we flush the pipes in the WM code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ec7b86bfe701..d0dbd656eecb 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3536,11 +3536,14 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, * We need to sequence the re-allocation: C, B, A (and not B, C, A). */ -static void skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) +static void +skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) { struct drm_device *dev = dev_priv->dev; int plane; + DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); + for_each_plane(pipe, plane) { I915_WRITE(PLANE_SURF(pipe, plane), I915_READ(PLANE_SURF(pipe, plane))); @@ -3591,7 +3594,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe)) continue; - skl_wm_flush_pipe(dev_priv, pipe); + skl_wm_flush_pipe(dev_priv, pipe, 1); intel_wait_for_vblank(dev, pipe); reallocated[pipe] = true; @@ -3616,7 +3619,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { - skl_wm_flush_pipe(dev_priv, pipe); + skl_wm_flush_pipe(dev_priv, pipe, 2); intel_wait_for_vblank(dev, pipe); } @@ -3642,7 +3645,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, if (reallocated[pipe]) continue; - skl_wm_flush_pipe(dev_priv, pipe); + skl_wm_flush_pipe(dev_priv, pipe, 3); } } -- GitLab From 38cff0b15756dae3c7452618e6673f77d87e7220 Mon Sep 17 00:00:00 2001 From: Zhe Wang Date: Tue, 4 Nov 2014 17:07:04 +0000 Subject: [PATCH 3904/9457] drm/i915/skl: Gen9 Forcewake Implement common forcewake functions shared by Gen9 features. v2: Make the focewake_{get,put} functions static (Mika) Small coding style fix in the function definition (Damien) Reviewed-by: Mika Kuoppala Signed-off-by: Zhe Wang (v1) Signed-off-by: Damien Lespiau (v2) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 5 +- drivers/gpu/drm/i915/i915_reg.h | 6 + drivers/gpu/drm/i915/intel_uncore.c | 175 +++++++++++++++++++++++++++- 3 files changed, 184 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 01d741d37a85..0f00e5830625 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -549,6 +549,7 @@ struct intel_uncore { unsigned fw_rendercount; unsigned fw_mediacount; + unsigned fw_blittercount; struct timer_list force_wake_timer; }; @@ -2979,7 +2980,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); #define FORCEWAKE_RENDER (1 << 0) #define FORCEWAKE_MEDIA (1 << 1) -#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA) +#define FORCEWAKE_BLITTER (1 << 2) +#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \ + FORCEWAKE_BLITTER) #define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ea22e09bd4c5..77461cec70fa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5833,6 +5833,12 @@ enum punit_power_well { #define VLV_GTLC_PW_MEDIA_STATUS_MASK (1 << 5) #define VLV_GTLC_PW_RENDER_STATUS_MASK (1 << 7) #define FORCEWAKE_MT 0xa188 /* multi-threaded */ +#define FORCEWAKE_MEDIA_GEN9 0xa270 +#define FORCEWAKE_RENDER_GEN9 0xa278 +#define FORCEWAKE_BLITTER_GEN9 0xa188 +#define FORCEWAKE_ACK_MEDIA_GEN9 0x0D88 +#define FORCEWAKE_ACK_RENDER_GEN9 0x0D84 +#define FORCEWAKE_ACK_BLITTER_GEN9 0x130044 #define FORCEWAKE_KERNEL 0x1 #define FORCEWAKE_USER 0x2 #define FORCEWAKE_MT_ACK 0x130040 diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 94276419c13f..68e722b780a1 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -296,6 +296,154 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } +static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) +{ + __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9, + _MASKED_BIT_DISABLE(0xffff)); + + __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9, + _MASKED_BIT_DISABLE(0xffff)); + + __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9, + _MASKED_BIT_DISABLE(0xffff)); +} + +static void +__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) +{ + /* Check for Render Engine */ + if (FORCEWAKE_RENDER & fw_engine) { + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_RENDER_GEN9) & + FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: Render forcewake old ack to clear.\n"); + + __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9, + _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); + + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_RENDER_GEN9) & + FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: waiting for Render to ack.\n"); + } + + /* Check for Media Engine */ + if (FORCEWAKE_MEDIA & fw_engine) { + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_MEDIA_GEN9) & + FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: Media forcewake old ack to clear.\n"); + + __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9, + _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); + + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_MEDIA_GEN9) & + FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: waiting for Media to ack.\n"); + } + + /* Check for Blitter Engine */ + if (FORCEWAKE_BLITTER & fw_engine) { + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_BLITTER_GEN9) & + FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n"); + + __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9, + _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); + + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_BLITTER_GEN9) & + FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: waiting for Blitter to ack.\n"); + } +} + +static void +__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) +{ + /* Check for Render Engine */ + if (FORCEWAKE_RENDER & fw_engine) + __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9, + _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); + + /* Check for Media Engine */ + if (FORCEWAKE_MEDIA & fw_engine) + __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9, + _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); + + /* Check for Blitter Engine */ + if (FORCEWAKE_BLITTER & fw_engine) + __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9, + _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); +} + +static void +gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) +{ + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + + if (FORCEWAKE_RENDER & fw_engine) { + if (dev_priv->uncore.fw_rendercount++ == 0) + dev_priv->uncore.funcs.force_wake_get(dev_priv, + FORCEWAKE_RENDER); + } + + if (FORCEWAKE_MEDIA & fw_engine) { + if (dev_priv->uncore.fw_mediacount++ == 0) + dev_priv->uncore.funcs.force_wake_get(dev_priv, + FORCEWAKE_MEDIA); + } + + if (FORCEWAKE_BLITTER & fw_engine) { + if (dev_priv->uncore.fw_blittercount++ == 0) + dev_priv->uncore.funcs.force_wake_get(dev_priv, + FORCEWAKE_BLITTER); + } + + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); +} + +static void +gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) +{ + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + + if (FORCEWAKE_RENDER & fw_engine) { + WARN_ON(dev_priv->uncore.fw_rendercount == 0); + if (--dev_priv->uncore.fw_rendercount == 0) + dev_priv->uncore.funcs.force_wake_put(dev_priv, + FORCEWAKE_RENDER); + } + + if (FORCEWAKE_MEDIA & fw_engine) { + WARN_ON(dev_priv->uncore.fw_mediacount == 0); + if (--dev_priv->uncore.fw_mediacount == 0) + dev_priv->uncore.funcs.force_wake_put(dev_priv, + FORCEWAKE_MEDIA); + } + + if (FORCEWAKE_BLITTER & fw_engine) { + WARN_ON(dev_priv->uncore.fw_blittercount == 0); + if (--dev_priv->uncore.fw_blittercount == 0) + dev_priv->uncore.funcs.force_wake_put(dev_priv, + FORCEWAKE_BLITTER); + } + + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); +} + static void gen6_force_wake_timer(unsigned long arg) { struct drm_i915_private *dev_priv = (void *)arg; @@ -334,6 +482,9 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) __gen7_gt_force_wake_mt_reset(dev_priv); + if (IS_GEN9(dev)) + __gen9_gt_force_wake_mt_reset(dev_priv); + if (restore) { /* If reset with a user forcewake, try to restore */ unsigned fw = 0; @@ -343,6 +494,15 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) if (dev_priv->uncore.fw_mediacount) fw |= FORCEWAKE_MEDIA; + } else if (IS_GEN9(dev)) { + if (dev_priv->uncore.fw_rendercount) + fw |= FORCEWAKE_RENDER; + + if (dev_priv->uncore.fw_mediacount) + fw |= FORCEWAKE_MEDIA; + + if (dev_priv->uncore.fw_blittercount) + fw |= FORCEWAKE_BLITTER; } else { if (dev_priv->uncore.forcewake_count) fw = FORCEWAKE_ALL; @@ -414,6 +574,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) intel_runtime_pm_get(dev_priv); + /* Redirect to Gen9 specific routine */ + if (IS_GEN9(dev_priv->dev)) + return gen9_force_wake_get(dev_priv, fw_engine); + /* Redirect to VLV specific routine */ if (IS_VALLEYVIEW(dev_priv->dev)) return vlv_force_wake_get(dev_priv, fw_engine); @@ -435,6 +599,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) if (!dev_priv->uncore.funcs.force_wake_put) return; + /* Redirect to Gen9 specific routine */ + if (IS_GEN9(dev_priv->dev)) { + gen9_force_wake_put(dev_priv, fw_engine); + goto out; + } + /* Redirect to VLV specific routine */ if (IS_VALLEYVIEW(dev_priv->dev)) { vlv_force_wake_put(dev_priv, fw_engine); @@ -855,7 +1025,10 @@ void intel_uncore_init(struct drm_device *dev) __intel_uncore_early_sanitize(dev, false); - if (IS_VALLEYVIEW(dev)) { + if (IS_GEN9(dev)) { + dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get; + dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put; + } else if (IS_VALLEYVIEW(dev)) { dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put; } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { -- GitLab From 20e4936693ea8a727e35d0f2b840670a0576b706 Mon Sep 17 00:00:00 2001 From: Zhe Wang Date: Tue, 4 Nov 2014 17:07:05 +0000 Subject: [PATCH 3905/9457] drm/i915/skl: Enable Gen9 RC6 Configure and enable RC6 for Gen9. v2: Rebase on top of BDW rc6 support (Damien) Reviewed-by: Mika Kuoppala Signed-off-by: Zhe Wang Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d0dbd656eecb..300d7e503f96 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4539,6 +4539,13 @@ static void gen8_disable_rps_interrupts(struct drm_device *dev) I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); } +static void gen9_disable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_RC_CONTROL, 0); +} + static void gen6_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4699,6 +4706,45 @@ static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_c dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; } +static void gen9_enable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring; + uint32_t rc6_mask = 0; + int unused; + + /* 1a: Software RC state - RC0 */ + I915_WRITE(GEN6_RC_STATE, 0); + + /* 1b: Get forcewake during program sequence. Although the driver + * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ + gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); + + /* 2a: Disable RC states. */ + I915_WRITE(GEN6_RC_CONTROL, 0); + + /* 2b: Program RC6 thresholds.*/ + I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); + I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ + I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ + for_each_ring(ring, dev_priv, unused) + I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); + I915_WRITE(GEN6_RC_SLEEP, 0); + I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ + + /* 3a: Enable RC6 */ + if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) + rc6_mask = GEN6_RC_CTL_RC6_ENABLE; + DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? + "on" : "off"); + I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | + GEN6_RC_CTL_EI_MODE(1) | + rc6_mask); + + gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); + +} + static void gen8_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6233,7 +6279,9 @@ void intel_disable_gt_powersave(struct drm_device *dev) intel_suspend_gt_powersave(dev); mutex_lock(&dev_priv->rps.hw_lock); - if (IS_CHERRYVIEW(dev)) + if (INTEL_INFO(dev)->gen >= 9) + gen9_disable_rps(dev); + else if (IS_CHERRYVIEW(dev)) cherryview_disable_rps(dev); else if (IS_VALLEYVIEW(dev)) valleyview_disable_rps(dev); @@ -6257,6 +6305,8 @@ static void intel_gen6_powersave_work(struct work_struct *work) cherryview_enable_rps(dev); } else if (IS_VALLEYVIEW(dev)) { valleyview_enable_rps(dev); + } else if (INTEL_INFO(dev)->gen >= 9) { + gen9_enable_rps(dev); } else if (IS_BROADWELL(dev)) { gen8_enable_rps(dev); __gen6_update_ring_freq(dev); -- GitLab From c6bde93b922586245ba1083c35b1139d6498eabb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Nov 2014 10:31:28 +0200 Subject: [PATCH 3906/9457] drm/i915/audio: rewrite vlv/chv and gen 5-7 audio codec enable sequence Similar to the hsw/bdw enable sequence rewrite. v3: replace vblank wait with a comment v4: expand the comment on what should be done with the vblank wait Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 63 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 4dcfc46d5725..8759fc509783 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -215,6 +215,10 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, { struct drm_i915_private *dev_priv = connector->dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_digital_port *intel_dig_port = + enc_to_dig_port(&encoder->base); + enum port port = intel_dig_port->port; + enum pipe pipe = intel_crtc->pipe; uint8_t *eld = connector->eld; uint32_t eldv; uint32_t tmp; @@ -223,8 +227,16 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, int aud_config; int aud_cntl_st; int aud_cntrl_st2; - enum pipe pipe = intel_crtc->pipe; - enum port port; + + DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n", + port_name(port), pipe_name(pipe), eld[2]); + + /* + * FIXME: We're supposed to wait for vblank here, but we have vblanks + * disabled during the mode set. The proper fix would be to push the + * rest of the setup into a vblank work item, queued here, but the + * infrastructure is not there yet. + */ if (HAS_PCH_IBX(connector->dev)) { hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); @@ -243,57 +255,44 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; } - DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); - - if (IS_VALLEYVIEW(connector->dev)) { - struct intel_digital_port *intel_dig_port; - - intel_dig_port = enc_to_dig_port(&encoder->base); - port = intel_dig_port->port; - } else { - tmp = I915_READ(aud_cntl_st); - port = (tmp >> 29) & DIP_PORT_SEL_MASK; - /* DIP_Port_Select, 0x1 = PortB */ - } - - if (!port) { - DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); - /* operate blindly on all ports */ + if (WARN_ON(!port)) { eldv = IBX_ELD_VALIDB; eldv |= IBX_ELD_VALIDB << 4; eldv |= IBX_ELD_VALIDB << 8; } else { - DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(port)); eldv = IBX_ELD_VALIDB << ((port - 1) * 4); } - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) - I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - else - I915_WRITE(aud_config, audio_config_hdmi_pixel_clock(mode)); - - if (intel_eld_uptodate(connector, - aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS_MASK, - hdmiw_hdmiedid)) - return; - + /* Invalidate ELD */ tmp = I915_READ(aud_cntrl_st2); tmp &= ~eldv; I915_WRITE(aud_cntrl_st2, tmp); + /* Reset ELD write address */ tmp = I915_READ(aud_cntl_st); tmp &= ~IBX_ELD_ADDRESS_MASK; I915_WRITE(aud_cntl_st, tmp); - len = min_t(int, eld[2], 21); /* 84 bytes of hw ELD buffer */ - DRM_DEBUG_DRIVER("ELD size %d\n", len); + /* Up to 84 bytes of hw ELD buffer */ + len = min_t(int, eld[2], 21); for (i = 0; i < len; i++) I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); + /* ELD valid */ tmp = I915_READ(aud_cntrl_st2); tmp |= eldv; I915_WRITE(aud_cntrl_st2, tmp); + + /* Enable timestamps */ + tmp = I915_READ(aud_config); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX; + tmp &= ~AUD_CONFIG_N_PROG_ENABLE; + tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + tmp |= AUD_CONFIG_N_VALUE_INDEX; + else + tmp |= audio_config_hdmi_pixel_clock(mode); + I915_WRITE(aud_config, tmp); } /** -- GitLab From 495a5bb81d3469495d81dbec6290dbb1dfebd673 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:55 +0200 Subject: [PATCH 3907/9457] drm/i915/audio: add vlv/chv/gen5-7 audio codec disable sequence Add support for disabling the audio codec on vlv/chv/gen5-7, similar to hsw/bdw. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 52 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 4 +++ drivers/gpu/drm/i915/intel_hdmi.c | 4 +++ 3 files changed, 60 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 8759fc509783..5c2d06c71ae7 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -209,6 +209,56 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, I915_WRITE(HSW_AUD_CFG(pipe), tmp); } +static void ilk_audio_codec_disable(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_digital_port *intel_dig_port = + enc_to_dig_port(&encoder->base); + enum port port = intel_dig_port->port; + enum pipe pipe = intel_crtc->pipe; + uint32_t tmp, eldv; + int aud_config; + int aud_cntrl_st2; + + DRM_DEBUG_KMS("Disable audio codec on port %c, pipe %c\n", + port_name(port), pipe_name(pipe)); + + if (HAS_PCH_IBX(dev_priv->dev)) { + aud_config = IBX_AUD_CFG(pipe); + aud_cntrl_st2 = IBX_AUD_CNTL_ST2; + } else if (IS_VALLEYVIEW(dev_priv)) { + aud_config = VLV_AUD_CFG(pipe); + aud_cntrl_st2 = VLV_AUD_CNTL_ST2; + } else { + aud_config = CPT_AUD_CFG(pipe); + aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; + } + + /* Disable timestamps */ + tmp = I915_READ(aud_config); + tmp &= ~AUD_CONFIG_N_VALUE_INDEX; + tmp |= AUD_CONFIG_N_PROG_ENABLE; + tmp &= ~AUD_CONFIG_UPPER_N_MASK; + tmp &= ~AUD_CONFIG_LOWER_N_MASK; + if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + tmp |= AUD_CONFIG_N_VALUE_INDEX; + I915_WRITE(aud_config, tmp); + + if (WARN_ON(!port)) { + eldv = IBX_ELD_VALIDB; + eldv |= IBX_ELD_VALIDB << 4; + eldv |= IBX_ELD_VALIDB << 8; + } else { + eldv = IBX_ELD_VALIDB << ((port - 1) * 4); + } + + /* Invalidate ELD */ + tmp = I915_READ(aud_cntrl_st2); + tmp &= ~eldv; + I915_WRITE(aud_cntrl_st2, tmp); +} + static void ilk_audio_codec_enable(struct drm_connector *connector, struct intel_encoder *encoder, struct drm_display_mode *mode) @@ -360,10 +410,12 @@ void intel_init_audio(struct drm_device *dev) dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; } else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) { dev_priv->display.audio_codec_enable = hsw_audio_codec_enable; dev_priv->display.audio_codec_disable = hsw_audio_codec_disable; } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5f2c206aef13..f48a1aae2b65 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2454,6 +2454,10 @@ static void intel_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct drm_device *dev = encoder->base.dev; + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + + if (crtc->config.has_audio) + intel_audio_codec_disable(encoder); /* Make sure the panel is off before trying to change the mode. But also * ensure that we have vdd while we switch off the panel. */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f29026a1157d..f89f71e1f2ce 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -802,9 +802,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); u32 temp; u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE; + if (crtc->config.has_audio) + intel_audio_codec_disable(encoder); + temp = I915_READ(intel_hdmi->hdmi_reg); /* HW workaround for IBX, we need to move the port to transcoder A -- GitLab From c1dec79aaee69042986247658ffdf51ee81017c2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:56 +0200 Subject: [PATCH 3908/9457] drm/i915: enable audio codec after port As per spec, and similar to DDI. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 13 ++++++++----- drivers/gpu/drm/i915/intel_hdmi.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f48a1aae2b65..464eea0f7136 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1324,12 +1324,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder) intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count); - if (crtc->config.has_audio) { - DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", - pipe_name(crtc->pipe)); + if (crtc->config.has_audio) intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; - intel_audio_codec_enable(encoder); - } /* Split out the IBX/CPU vs CPT settings */ @@ -2636,6 +2632,7 @@ static void intel_enable_dp(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); uint32_t dp_reg = I915_READ(intel_dp->output_reg); if (WARN_ON(dp_reg & DP_PORT_EN)) @@ -2661,6 +2658,12 @@ static void intel_enable_dp(struct intel_encoder *encoder) intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); + + if (crtc->config.has_audio) { + DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", + pipe_name(crtc->pipe)); + intel_audio_codec_enable(encoder); + } } static void g4x_enable_dp(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f89f71e1f2ce..29baa53aef90 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -661,14 +661,6 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) if (crtc->config.has_hdmi_sink) hdmi_val |= HDMI_MODE_SELECT_HDMI; - if (crtc->config.has_audio) { - WARN_ON(!crtc->config.has_hdmi_sink); - DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", - pipe_name(crtc->pipe)); - hdmi_val |= SDVO_AUDIO_ENABLE; - intel_audio_codec_enable(encoder); - } - if (HAS_PCH_CPT(dev)) hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe); else if (IS_CHERRYVIEW(dev)) @@ -791,6 +783,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder) I915_WRITE(intel_hdmi->hdmi_reg, temp); POSTING_READ(intel_hdmi->hdmi_reg); } + + if (intel_crtc->config.has_audio) { + WARN_ON(!intel_crtc->config.has_hdmi_sink); + DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", + pipe_name(intel_crtc->pipe)); + intel_audio_codec_enable(encoder); + } } static void vlv_enable_hdmi(struct intel_encoder *encoder) -- GitLab From 76d8d3e5b57d7938613e4018eddbf0a16913338a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:57 +0200 Subject: [PATCH 3909/9457] drm/i915/audio: add audio codec disable on g4x This not based on any documentation... Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 5c2d06c71ae7..fa0eecf6a792 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -93,6 +93,25 @@ static bool intel_eld_uptodate(struct drm_connector *connector, return true; } +static void g4x_audio_codec_disable(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + uint32_t eldv, tmp; + + DRM_DEBUG_KMS("Disable audio codec\n"); + + tmp = I915_READ(G4X_AUD_VID_DID); + if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) + eldv = G4X_ELDV_DEVCL_DEVBLC; + else + eldv = G4X_ELDV_DEVCTG; + + /* Invalidate ELD */ + tmp = I915_READ(G4X_AUD_CNTL_ST); + tmp &= ~eldv; + I915_WRITE(G4X_AUD_CNTL_ST, tmp); +} + static void g4x_audio_codec_enable(struct drm_connector *connector, struct intel_encoder *encoder, struct drm_display_mode *mode) @@ -408,6 +427,7 @@ void intel_init_audio(struct drm_device *dev) if (IS_G4X(dev)) { dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; + dev_priv->display.audio_codec_disable = g4x_audio_codec_disable; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; -- GitLab From d5ee08de1bbeac867818c37b5b8413f68c742703 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:58 +0200 Subject: [PATCH 3910/9457] drm/i915/audio: add audio codec enable debug log for g4x Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index fa0eecf6a792..c4c036a86d75 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -122,6 +122,8 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, uint32_t tmp; int len, i; + DRM_DEBUG_KMS("Enable audio codec, %u bytes ELD\n", eld[2]); + tmp = I915_READ(G4X_AUD_VID_DID); if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) eldv = G4X_ELDV_DEVCL_DEVBLC; -- GitLab From 82910ac6d575d4ce4bd4dcefb61923623b263e00 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:26:59 +0200 Subject: [PATCH 3911/9457] drm/i915: make pipe/port based audio valid accessors easier to use Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 20 ++++++-------------- drivers/gpu/drm/i915/intel_audio.c | 22 ++++++++++------------ drivers/gpu/drm/i915/intel_ddi.c | 2 +- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 77461cec70fa..b250d96ab7a1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6102,8 +6102,8 @@ enum punit_power_well { #define IBX_ELD_ADDRESS_MASK (0x1f << 5) #define IBX_ELD_ACK (1 << 4) #define IBX_AUD_CNTL_ST2 0xE20C0 -#define IBX_ELD_VALIDB (1 << 0) -#define IBX_CP_READYB (1 << 1) +#define IBX_CP_READY(port) ((1 << 1) << (((port) - 1) * 4)) +#define IBX_ELD_VALID(port) ((1 << 0) << (((port) - 1) * 4)) #define _CPT_HDMIW_HDMIEDID_A 0xE5050 #define _CPT_HDMIW_HDMIEDID_B 0xE5150 @@ -6206,18 +6206,10 @@ enum punit_power_well { #define HSW_AUD_PIPE_CONV_CFG 0x6507c #define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 -#define AUDIO_INACTIVE_C (1<<11) -#define AUDIO_INACTIVE_B (1<<7) -#define AUDIO_INACTIVE_A (1<<3) -#define AUDIO_OUTPUT_ENABLE_A (1<<2) -#define AUDIO_OUTPUT_ENABLE_B (1<<6) -#define AUDIO_OUTPUT_ENABLE_C (1<<10) -#define AUDIO_ELD_VALID_A (1<<0) -#define AUDIO_ELD_VALID_B (1<<4) -#define AUDIO_ELD_VALID_C (1<<8) -#define AUDIO_CP_READY_A (1<<1) -#define AUDIO_CP_READY_B (1<<5) -#define AUDIO_CP_READY_C (1<<9) +#define AUDIO_INACTIVE(trans) ((1 << 3) << ((trans) * 4)) +#define AUDIO_OUTPUT_ENABLE(trans) ((1 << 2) << ((trans) * 4)) +#define AUDIO_CP_READY(trans) ((1 << 1) << ((trans) * 4)) +#define AUDIO_ELD_VALID(trans) ((1 << 0) << ((trans) * 4)) /* HSW Power Wells */ #define HSW_PWR_WELL_BIOS 0x45400 /* CTL1 */ diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index c4c036a86d75..9181b85d86c4 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -172,7 +172,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) /* Invalidate ELD */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp &= ~(AUDIO_ELD_VALID_A << (pipe * 4)); + tmp &= ~AUDIO_ELD_VALID(pipe); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); } @@ -192,8 +192,8 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, /* Enable audio presence detect, invalidate ELD */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp |= AUDIO_OUTPUT_ENABLE_A << (pipe * 4); - tmp &= ~(AUDIO_ELD_VALID_A << (pipe * 4)); + tmp |= AUDIO_OUTPUT_ENABLE(pipe); + tmp &= ~AUDIO_ELD_VALID(pipe); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); /* @@ -215,7 +215,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, /* ELD valid */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - tmp |= AUDIO_ELD_VALID_A << (pipe * 4); + tmp |= AUDIO_ELD_VALID(pipe); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); /* Enable timestamps */ @@ -267,11 +267,10 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder) I915_WRITE(aud_config, tmp); if (WARN_ON(!port)) { - eldv = IBX_ELD_VALIDB; - eldv |= IBX_ELD_VALIDB << 4; - eldv |= IBX_ELD_VALIDB << 8; + eldv = IBX_ELD_VALID(PORT_B) | IBX_ELD_VALID(PORT_C) | + IBX_ELD_VALID(PORT_D); } else { - eldv = IBX_ELD_VALIDB << ((port - 1) * 4); + eldv = IBX_ELD_VALID(port); } /* Invalidate ELD */ @@ -327,11 +326,10 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, } if (WARN_ON(!port)) { - eldv = IBX_ELD_VALIDB; - eldv |= IBX_ELD_VALIDB << 4; - eldv |= IBX_ELD_VALIDB << 8; + eldv = IBX_ELD_VALID(PORT_B) | IBX_ELD_VALID(PORT_C) | + IBX_ELD_VALID(PORT_D); } else { - eldv = IBX_ELD_VALIDB << ((port - 1) * 4); + eldv = IBX_ELD_VALID(port); } /* Invalidate ELD */ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a50df351d558..68703cecdefc 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1523,7 +1523,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); - if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe * 4))) + if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe)) pipe_config->has_audio = true; } -- GitLab From 28855d2ac349b3fbb285c38493429dd1aa503523 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Oct 2014 16:27:00 +0200 Subject: [PATCH 3912/9457] drm/i915/audio: add DOC comment describing HDA over HDMI/DP v2: include the section in the drm docbook. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 5 +++++ drivers/gpu/drm/i915/intel_audio.c | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index f6a9d7b21380..01b8ca5f1a3d 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3854,6 +3854,11 @@ int num_ioctls; probing, so those sections fully apply. + + High Definition Audio +!Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port +!Idrivers/gpu/drm/i915/intel_audio.c + DPIO !Pdrivers/gpu/drm/i915/i915_reg.h DPIO diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 9181b85d86c4..44c49dfe1096 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -28,6 +28,27 @@ #include "intel_drv.h" #include "i915_drv.h" +/** + * DOC: High Definition Audio over HDMI and Display Port + * + * The graphics and audio drivers together support High Definition Audio over + * HDMI and Display Port. The audio programming sequences are divided into audio + * codec and controller enable and disable sequences. The graphics driver + * handles the audio codec sequences, while the audio driver handles the audio + * controller sequences. + * + * The disable sequences must be performed before disabling the transcoder or + * port. The enable sequences may only be performed after enabling the + * transcoder and port, and after completed link training. + * + * The codec and controller sequences could be done either parallel or serial, + * but generally the ELDV/PD change in the codec sequence indicates to the audio + * driver that the controller sequence should start. Indeed, most of the + * co-operation between the graphics and audio drivers is handled via audio + * related registers. (The notable exception is the power management, not + * covered here.) + */ + static const struct { int clock; u32 config; -- GitLab From 50f6e502718fd187f8e11a7b5048b21f85ac77e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Nov 2014 14:49:12 +0200 Subject: [PATCH 3913/9457] drm/i915: Move the .global_resources() hook call into modeset_update_crtc_power_domains() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may need to access various hardware bits in the .global_resources() hook, so move the call to occur after enabling all the newly required power wells, but before disabling all the now unneeded wells. This should guarantee that we have all the sufficient hardware resources available during the .global_resources() call. And if not, any additional resources must be explicitly acquired by the .global_resorces() hook. For instance on VLV/CHV we need to access the gunit mailbox so that we can talk to punit/cck over sideband. In addition some PFI credit reprogramming may need to be addes as well, which may require the disp2d well. This should also make the power domain refcounts consistent on platforms which don't have a .global_resource() hook since now they too will call modeset_update_crtc_power_domains() which will drop the init power. Previously init power was just left enabled for such platforms. Cc: Imre Deak Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07fb0ff66f5d..18ad2bc8550b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4683,6 +4683,9 @@ static void modeset_update_crtc_power_domains(struct drm_device *dev) intel_display_power_get(dev_priv, domain); } + if (dev_priv->display.modeset_global_resources) + dev_priv->display.modeset_global_resources(dev); + for_each_intel_crtc(dev, crtc) { enum intel_display_power_domain domain; @@ -4910,8 +4913,6 @@ static void valleyview_modeset_global_resources(struct drm_device *dev) else valleyview_set_cdclk(dev, req_cdclk); } - - modeset_update_crtc_power_domains(dev); } static void valleyview_crtc_enable(struct drm_crtc *crtc) @@ -7950,16 +7951,6 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv) intel_prepare_ddi(dev); } -static void snb_modeset_global_resources(struct drm_device *dev) -{ - modeset_update_crtc_power_domains(dev); -} - -static void haswell_modeset_global_resources(struct drm_device *dev) -{ - modeset_update_crtc_power_domains(dev); -} - static int haswell_crtc_compute_clock(struct intel_crtc *crtc) { if (!intel_ddi_pll_select(crtc)) @@ -10917,8 +10908,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, * update the the output configuration. */ intel_modeset_update_state(dev, prepare_pipes); - if (dev_priv->display.modeset_global_resources) - dev_priv->display.modeset_global_resources(dev); + modeset_update_crtc_power_domains(dev); /* Set up the DPLL and any encoders state that needs to adjust or depend * on the DPLL. @@ -12589,8 +12579,6 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.fdi_link_train = ironlake_fdi_link_train; } else if (IS_GEN6(dev)) { dev_priv->display.fdi_link_train = gen6_fdi_link_train; - dev_priv->display.modeset_global_resources = - snb_modeset_global_resources; } else if (IS_IVYBRIDGE(dev)) { /* FIXME: detect B0+ stepping and use auto training */ dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; @@ -12598,14 +12586,9 @@ static void intel_init_display(struct drm_device *dev) ivb_modeset_global_resources; } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { dev_priv->display.fdi_link_train = hsw_fdi_link_train; - dev_priv->display.modeset_global_resources = - haswell_modeset_global_resources; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.modeset_global_resources = valleyview_modeset_global_resources; - } else if (INTEL_INFO(dev)->gen >= 9) { - dev_priv->display.modeset_global_resources = - haswell_modeset_global_resources; } /* Default just returns -ENODEV to indicate unsupported */ -- GitLab From 16e9a21f33cda9d48b70ff54e1ed2e4a77497bc6 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Thu, 6 Nov 2014 09:26:38 +0200 Subject: [PATCH 3914/9457] drm/i915: Make __wait_seqno non-static and rename to __i915_wait_seqno So that it can be used by the flip code to wait for rendering without holding any locks. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/i915_gem.c | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0f00e5830625..2dc888ca3394 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2595,6 +2595,11 @@ int __i915_add_request(struct intel_engine_cs *ring, u32 *seqno); #define i915_add_request(ring, seqno) \ __i915_add_request(ring, NULL, NULL, seqno) +int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, + unsigned reset_counter, + bool interruptible, + s64 *timeout, + struct drm_i915_file_private *file_priv); int __must_check i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1de94cc63517..3e0cabe9b544 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1134,7 +1134,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) } /** - * __wait_seqno - wait until execution of seqno has finished + * __i915_wait_seqno - wait until execution of seqno has finished * @ring: the ring expected to report seqno * @seqno: duh! * @reset_counter: reset sequence associated with the given seqno @@ -1151,7 +1151,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) * Returns 0 if the seqno was found within the alloted time. Else returns the * errno with remaining time filled in timeout argument. */ -static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno, +int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno, unsigned reset_counter, bool interruptible, s64 *timeout, @@ -1262,6 +1262,7 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; bool interruptible = dev_priv->mm.interruptible; + unsigned reset_counter; int ret; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -1275,9 +1276,9 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) if (ret) return ret; - return __wait_seqno(ring, seqno, - atomic_read(&dev_priv->gpu_error.reset_counter), - interruptible, NULL, NULL); + reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); + return __i915_wait_seqno(ring, seqno, reset_counter, interruptible, + NULL, NULL); } static int @@ -1353,7 +1354,8 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); mutex_unlock(&dev->struct_mutex); - ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, file_priv); + ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, + file_priv); mutex_lock(&dev->struct_mutex); if (ret) return ret; @@ -2847,8 +2849,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); mutex_unlock(&dev->struct_mutex); - return __wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns, - file->driver_priv); + return __i915_wait_seqno(ring, seqno, reset_counter, true, + &args->timeout_ns, file->driver_priv); out: drm_gem_object_unreference(&obj->base); @@ -4013,7 +4015,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) if (seqno == 0) return 0; - ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, NULL); + ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, NULL); if (ret == 0) queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); -- GitLab From 536f5b5e86b225dab94c7ff8061ae482b6077387 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Thu, 6 Nov 2014 11:03:40 +0200 Subject: [PATCH 3915/9457] drm/i915: Make mmio flip wait for seqno in the work function This simplifies the code quite a bit compared to iterating over all rings during the ring interrupt. Also, it allows us to drop the mmio_flip spinlock, since the mmio_flip struct is only accessed in two places. The first is when the flip is queued and the other when the mmio writes are done. Since a flip cannot be queued while there is a pending flip, the two paths shouldn't ever run in parallel. We might need to revisit that if support for replacing flips is implemented though. v2: Don't hold dev->struct_mutext while waiting (Chris) v3: Make the wait uninterruptable (Chris) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 3 - drivers/gpu/drm/i915/intel_display.c | 90 ++++------------------------ drivers/gpu/drm/i915/intel_drv.h | 9 +-- 3 files changed, 12 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 318a6a0724d0..5fff2870a17b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -979,9 +979,6 @@ static void notify_ring(struct drm_device *dev, trace_i915_gem_request_complete(ring); - if (drm_core_check_feature(dev, DRIVER_MODESET)) - intel_notify_mmio_flip(ring); - wake_up_all(&ring->irq_queue); i915_queue_hangcheck(dev); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 18ad2bc8550b..cb0f32fd3b5c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9417,73 +9417,24 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) if (atomic_update) intel_pipe_update_end(intel_crtc, start_vbl_count); - - spin_lock_irq(&dev_priv->mmio_flip_lock); - intel_crtc->mmio_flip.status = INTEL_MMIO_FLIP_IDLE; - spin_unlock_irq(&dev_priv->mmio_flip_lock); } static void intel_mmio_flip_work_func(struct work_struct *work) { struct intel_crtc *intel_crtc = container_of(work, struct intel_crtc, mmio_flip.work); - - intel_do_mmio_flip(intel_crtc); -} - -static int intel_postpone_flip(struct drm_i915_gem_object *obj) -{ struct intel_engine_cs *ring; - int ret; - - lockdep_assert_held(&obj->base.dev->struct_mutex); - - if (!obj->last_write_seqno) - return 0; - - ring = obj->ring; - - if (i915_seqno_passed(ring->get_seqno(ring, true), - obj->last_write_seqno)) - return 0; - - ret = i915_gem_check_olr(ring, obj->last_write_seqno); - if (ret) - return ret; - - if (WARN_ON(!ring->irq_get(ring))) - return 0; - - return 1; -} + uint32_t seqno; -void intel_notify_mmio_flip(struct intel_engine_cs *ring) -{ - struct drm_i915_private *dev_priv = to_i915(ring->dev); - struct intel_crtc *intel_crtc; - unsigned long irq_flags; - u32 seqno; - - seqno = ring->get_seqno(ring, false); + seqno = intel_crtc->mmio_flip.seqno; + ring = intel_crtc->mmio_flip.ring; - spin_lock_irqsave(&dev_priv->mmio_flip_lock, irq_flags); - for_each_intel_crtc(ring->dev, intel_crtc) { - struct intel_mmio_flip *mmio_flip; + if (seqno) + WARN_ON(__i915_wait_seqno(ring, seqno, + intel_crtc->reset_counter, + false, NULL, NULL) != 0); - mmio_flip = &intel_crtc->mmio_flip; - if (mmio_flip->status != INTEL_MMIO_FLIP_WAIT_RING) - continue; - - if (ring->id != mmio_flip->ring_id) - continue; - - if (i915_seqno_passed(seqno, mmio_flip->seqno)) { - schedule_work(&intel_crtc->mmio_flip.work); - mmio_flip->status = INTEL_MMIO_FLIP_WORK_SCHEDULED; - ring->irq_put(ring); - } - } - spin_unlock_irqrestore(&dev_priv->mmio_flip_lock, irq_flags); + intel_do_mmio_flip(intel_crtc); } static int intel_queue_mmio_flip(struct drm_device *dev, @@ -9493,32 +9444,13 @@ static int intel_queue_mmio_flip(struct drm_device *dev, struct intel_engine_cs *ring, uint32_t flags) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int ret; - - if (WARN_ON(intel_crtc->mmio_flip.status != INTEL_MMIO_FLIP_IDLE)) - return -EBUSY; - - ret = intel_postpone_flip(obj); - if (ret < 0) - return ret; - if (ret == 0) { - intel_do_mmio_flip(intel_crtc); - return 0; - } - spin_lock_irq(&dev_priv->mmio_flip_lock); - intel_crtc->mmio_flip.status = INTEL_MMIO_FLIP_WAIT_RING; intel_crtc->mmio_flip.seqno = obj->last_write_seqno; - intel_crtc->mmio_flip.ring_id = obj->ring->id; - spin_unlock_irq(&dev_priv->mmio_flip_lock); + intel_crtc->mmio_flip.ring = obj->ring; + + schedule_work(&intel_crtc->mmio_flip.work); - /* - * Double check to catch cases where irq fired before - * mmio flip data was ready - */ - intel_notify_mmio_flip(obj->ring); return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cb0e9dbf1c96..5c622ad2e9aa 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -399,16 +399,9 @@ struct intel_pipe_wm { bool sprites_scaled; }; -enum intel_mmio_flip_status { - INTEL_MMIO_FLIP_IDLE = 0, - INTEL_MMIO_FLIP_WAIT_RING, - INTEL_MMIO_FLIP_WORK_SCHEDULED, -}; - struct intel_mmio_flip { u32 seqno; - u32 ring_id; - enum intel_mmio_flip_status status; + struct intel_engine_cs *ring; struct work_struct work; }; -- GitLab From 9500986159d9017f9277f9e42a1f9b13b5e0e666 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 5 Nov 2014 17:30:52 +0200 Subject: [PATCH 3916/9457] Revert "drm/i915/vlv: Remove check for Old Ack during forcewake" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5cb13c07dae73380d8b3ddc792740487b8742938. While the relevance for WaRsDontPollForAckOnClearingFWBits is under investigation, revert this as regression. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85684 Tested-by: Tested-by: lu hua Cc: Chris Wilson Cc: Ville Syrjälä Cc: S, Deepak Signed-off-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 68e722b780a1..6a0c3fb2cbf0 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -194,15 +194,13 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) { - /* - * WaRsDontPollForAckOnClearingFWBits:vlv - * Hardware clears ack bits lazily (only when all ack - * bits become 0) so don't poll for individiual ack - * bits to be clear here like on other platforms. - */ - /* Check for Render Engine */ if (FORCEWAKE_RENDER & fw_engine) { + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_VLV) & + FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: Render forcewake old ack to clear.\n"); __raw_i915_write32(dev_priv, FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); @@ -216,6 +214,11 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, /* Check for Media Engine */ if (FORCEWAKE_MEDIA & fw_engine) { + if (wait_for_atomic((__raw_i915_read32(dev_priv, + FORCEWAKE_ACK_MEDIA_VLV) & + FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out: Media forcewake old ack to clear.\n"); __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); -- GitLab From 6bcda4f0dfcbe78349b5b283af892913299c8b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 7 Oct 2014 17:41:22 +0300 Subject: [PATCH 3917/9457] drm/i915: Cache HPLL frequency on VLV/CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need the HPLL frequency when calculating cdclk. Currently we read that out from the hardware every single time, which isn't going to fly very well if the device is runtime suspended. So cache the HPLL frequency in dev_priv and use the cached value. Signed-off-by: Ville Syrjälä Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939 Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2dc888ca3394..8fb8eba08dc6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1613,6 +1613,7 @@ struct drm_i915_private { unsigned int fsb_freq, mem_freq, is_ddr3; unsigned int vlv_cdclk_freq; + unsigned int hpll_freq; /** * wq - Driver workqueue for GEM. diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cb0f32fd3b5c..3f4a5b83bea4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4756,10 +4756,9 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) mutex_unlock(&dev_priv->rps.hw_lock); if (cdclk == 400000) { - u32 divider, vco; + u32 divider; - vco = valleyview_get_vco(dev_priv); - divider = DIV_ROUND_CLOSEST(vco << 1, cdclk) - 1; + divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1; mutex_lock(&dev_priv->dpio_lock); /* adjust cdclk divider */ @@ -4838,8 +4837,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, int max_pixclk) { - int vco = valleyview_get_vco(dev_priv); - int freq_320 = (vco << 1) % 320000 != 0 ? 333333 : 320000; + int freq_320 = (dev_priv->hpll_freq << 1) % 320000 != 0 ? 333333 : 320000; /* FIXME: Punit isn't quite ready yet */ if (IS_CHERRYVIEW(dev_priv->dev)) @@ -5544,7 +5542,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, static int valleyview_get_display_clock_speed(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int vco = valleyview_get_vco(dev_priv); u32 val; int divider; @@ -5552,6 +5549,9 @@ static int valleyview_get_display_clock_speed(struct drm_device *dev) if (IS_CHERRYVIEW(dev)) return 400000; + if (dev_priv->hpll_freq == 0) + dev_priv->hpll_freq = valleyview_get_vco(dev_priv); + mutex_lock(&dev_priv->dpio_lock); val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL); mutex_unlock(&dev_priv->dpio_lock); @@ -5562,7 +5562,7 @@ static int valleyview_get_display_clock_speed(struct drm_device *dev) (divider << DISPLAY_FREQUENCY_STATUS_SHIFT), "cdclk change in progress\n"); - return DIV_ROUND_CLOSEST(vco << 1, divider + 1); + return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1); } static int i945_get_display_clock_speed(struct drm_device *dev) -- GitLab From 0b5492d6b53251acab99b1906a328fac56e08be3 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Thu, 6 Nov 2014 13:03:46 +0200 Subject: [PATCH 3918/9457] drm/i915: Add gen to the gpu hang ecode for the Brothers in Triage Signed-off-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index d17360bc1cd1..89a2f3dbf956 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1242,7 +1242,8 @@ static void i915_error_capture_msg(struct drm_device *dev, ecode = i915_error_generate_code(dev_priv, error, &ring_id); len = scnprintf(error->error_msg, sizeof(error->error_msg), - "GPU HANG: ecode %d:0x%08x", ring_id, ecode); + "GPU HANG: ecode %d:%d:0x%08x", + INTEL_INFO(dev)->gen, ring_id, ecode); if (ring_id != -1 && error->ring[ring_id].pid != -1) len += scnprintf(error->error_msg + len, -- GitLab From c78a964c251bb82aa3454440e082b91a836105ae Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 7 Nov 2014 16:50:45 +0530 Subject: [PATCH 3919/9457] staging: rtl8188eu: unneeded return variable a variable is declared and initialized and then never updated in the function.This default value is then used as the return from the function. So removed that unneeded return variable and returning that default initial value directly. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 6 ++---- drivers/staging/rtl8188eu/core/rtw_recv.c | 6 ++---- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 4 ++-- drivers/staging/rtl8188eu/os_dep/os_intfs.c | 9 +++------ 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index b0e92372fa5e..990c168d3d6d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -371,7 +371,6 @@ static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_c int init_mlme_ext_priv(struct adapter *padapter) { - int res = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); @@ -397,7 +396,7 @@ int init_mlme_ext_priv(struct adapter *padapter) pmlmeext->active_keep_alive_check = true; - return res; + return _SUCCESS; } void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) @@ -1554,7 +1553,6 @@ unsigned int OnAtim(struct adapter *padapter, struct recv_frame *precv_frame) unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_frame) { - unsigned int ret = _FAIL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; u8 *pframe = precv_frame->rx_data; @@ -1587,7 +1585,7 @@ unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_f } exit: - return ret; + return _FAIL; } unsigned int OnAction_qos(struct adapter *padapter, struct recv_frame *precv_frame) diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index a1619b88733f..bd79e9e7105a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -1373,7 +1373,6 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) u8 *psnap_type; struct ieee80211_snap_hdr *psnap; - int ret = _SUCCESS; struct adapter *adapter = precvframe->adapter; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; u8 *ptr = precvframe->rx_data; @@ -1428,7 +1427,7 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe) memcpy(ptr+12, &be_tmp, 2); } - return ret; + return _SUCCESS; } /* perform defrag */ @@ -1624,7 +1623,6 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue); - int ret = _SUCCESS; nr_subframes = 0; pattrib = &prframe->attrib; @@ -1728,7 +1726,7 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe) prframe->len = 0; rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ - return ret; + return _SUCCESS; } static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index f34fb29ae225..24a8f5ac96e5 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -1416,7 +1416,7 @@ static int rtw_wx_set_rate(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) { - int i, ret = 0; + int i; u8 datarates[NumRates]; u32 target_rate = wrqu->bitrate.value; u32 fixed = wrqu->bitrate.fixed; @@ -1489,7 +1489,7 @@ static int rtw_wx_set_rate(struct net_device *dev, RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i])); } - return ret; + return 0; } static int rtw_wx_get_rate(struct net_device *dev, diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 0b488d29bd37..88a909c9e457 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -512,7 +512,6 @@ void rtw_proc_remove_one(struct net_device *dev) static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) { - uint status = _SUCCESS; struct registry_priv *registry_par = &padapter->registrypriv; @@ -582,7 +581,7 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev) snprintf(registry_par->ifname, 16, "%s", ifname); snprintf(registry_par->if2name, 16, "%s", if2name); registry_par->notch_filter = (u8)rtw_notch_filter; - return status; + return _SUCCESS; } static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) @@ -760,7 +759,6 @@ void rtw_stop_drv_threads(struct adapter *padapter) static u8 rtw_init_default_value(struct adapter *padapter) { - u8 ret = _SUCCESS; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; @@ -803,12 +801,11 @@ static u8 rtw_init_default_value(struct adapter *padapter) padapter->bWritePortCancel = false; padapter->bRxRSSIDisplay = 0; padapter->bNotifyChannelChange = 0; - return ret; + return _SUCCESS; } u8 rtw_reset_drv_sw(struct adapter *padapter) { - u8 ret8 = _SUCCESS; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; @@ -833,7 +830,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter) rtw_set_signal_stat_timer(&padapter->recvpriv); - return ret8; + return _SUCCESS; } u8 rtw_init_drv_sw(struct adapter *padapter) -- GitLab From d48037f9169f653d1124eb75157293d875e7e57f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 7 Nov 2014 16:50:46 +0530 Subject: [PATCH 3920/9457] staging: rtl8188eu: unneeded NULL check before these NULL checks we are already checking it for NULL, and if it is NULL then we are jumping to the error label and handling the error before returning. So we can reach this part of the code only if the variable is known to be not NULL, and if we already know that it is not NULL, then no need to check it again. Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_xmit.c | 4 +-- drivers/staging/rtl8188eu/hal/rtl8188e_dm.c | 30 ++++++++++----------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index a0bbf9093338..7a71df167464 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -1025,8 +1025,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct /* adding icv, if necessary... */ if (pattrib->iv_len) { - if (psta != NULL) { - switch (pattrib->encrypt) { + switch (pattrib->encrypt) { case _WEP40_: case _WEP104_: WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); @@ -1043,7 +1042,6 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct else AES_IV(pattrib->iv, psta->dot11txpn, 0); break; - } } memcpy(pframe, pattrib->iv, pattrib->iv_len); diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c index dab4c337a863..01566210bbd2 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c @@ -155,6 +155,8 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter) bool fw_ps_awake = true; u8 hw_init_completed = false; struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = NULL; + u8 bLinked = false; hw_init_completed = Adapter->hw_init_completed; @@ -170,22 +172,20 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter) fw_ps_awake = false; /* ODM */ - if (hw_init_completed) { - struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; - u8 bLinked = false; - - if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) { - if (Adapter->stapriv.asoc_sta_count > 2) - bLinked = true; - } else {/* Station mode */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) - bLinked = true; - } - - ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); - ODM_DMWatchdog(&hal_data->odmpriv); + pmlmepriv = &Adapter->mlmepriv; + + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | + WIFI_ADHOC_MASTER_STATE))) { + if (Adapter->stapriv.asoc_sta_count > 2) + bLinked = true; + } else {/* Station mode */ + if (check_fwstate(pmlmepriv, _FW_LINKED)) + bLinked = true; } + + ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked); + ODM_DMWatchdog(&hal_data->odmpriv); skip_dm: /* Check GPIO to determine current RF on/off and Pbc status. */ /* Check Hardware Radio ON/OFF or not */ -- GitLab From 49af54ff0fc7abb6457caed982ddfcfda487e3f7 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 24 Sep 2014 17:33:55 +0800 Subject: [PATCH 3921/9457] misc: atmel-ssc: prepare clock only when request Prepare SSC clock only when request SSC channel, the clock will be enabled when initialize the SSC. Signed-off-by: Bo Shen Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/misc/atmel-ssc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 60843a275abd..f9807a76bbc7 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -57,7 +57,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num) ssc->user++; spin_unlock(&user_lock); - clk_prepare_enable(ssc->clk); + clk_prepare(ssc->clk); return ssc; } @@ -77,7 +77,7 @@ void ssc_free(struct ssc_device *ssc) spin_unlock(&user_lock); if (disable_clk) - clk_disable_unprepare(ssc->clk); + clk_unprepare(ssc->clk); } EXPORT_SYMBOL(ssc_free); -- GitLab From 24fe1f03e4ef838adb21205d004ec2c3396a3ad9 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Sat, 27 Sep 2014 16:30:45 +0200 Subject: [PATCH 3922/9457] checkkconfigsymbols.sh: reimplementation in python MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The scripts/checkkconfigsymbols.sh script searches Kconfig features in the source code that are not defined in Kconfig. Such identifiers always evaluate to false and are the source of various kinds of bugs. However, the shell script is slow and it does not detect such broken references in Kbuild and Kconfig files (e.g., ``depends on UNDEFINED´´). Furthermore, it generates false positives. The script is also hard to read and understand, and is thereby difficult to maintain. This patch replaces the shell script with an implementation in Python, which: (a) detects the same bugs, but does not report previous false positives (b) additionally detects broken references in Kconfig and all non-Kconfig files, such as Kbuild, .[cSh], .txt, .sh, defconfig, etc. (c) is up to 75 times faster than the shell script (d) only checks files under version control The new script reduces the runtime on my machine (i7-2620M, 8GB RAM, SSD) from 3m47s to 0m3s, and reports 938 broken references in Linux v3.17-rc1; 419 additional reports of which 16 are located in Kconfig files, 287 in defconfigs, 63 in ./Documentation, 1 in Kbuild. Moreover, we intentionally include references in comments, which have been ignored until now. Such comments may be leftovers of features that have been removed or renamed in Kconfig (e.g., ``#endif /* CONFIG_MPC52xx */´´). These references can be misleading and should be removed or replaced. Note that the output format changed from (file list feature) to (feature file list) as it simplifies the detection of the Kconfig feature for long file lists. Signed-off-by: Valentin Rothberg Signed-off-by: Stefan Hengelein Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 142 +++++++++++++++++++++++++++++++++ scripts/checkkconfigsymbols.sh | 59 -------------- 2 files changed, 142 insertions(+), 59 deletions(-) create mode 100644 scripts/checkkconfigsymbols.py delete mode 100755 scripts/checkkconfigsymbols.sh diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py new file mode 100644 index 000000000000..f9440891d048 --- /dev/null +++ b/scripts/checkkconfigsymbols.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +"""Find Kconfig identifieres that are referenced but not defined.""" + +# Copyright (C) 2014 Valentin Rothberg +# Copyright (C) 2014 Stefan Hengelein +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + + +import os +import re +from subprocess import Popen, PIPE, STDOUT + +# REGEX EXPRESSIONS +OPERATORS = r"&|\(|\)|\||\!" +FEATURE = r"\w*[A-Z]{1}\w*" +CONFIG_DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" +EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" +STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR + +# REGEX OBJECTS +REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") +REGEX_FEATURE = re.compile(r"(" + FEATURE + r")") +REGEX_SOURCE_FEATURE = re.compile(r"(?:D|\W|\b)+CONFIG_(" + FEATURE + r")") +REGEX_KCONFIG_DEF = re.compile(CONFIG_DEF) +REGEX_KCONFIG_EXPR = re.compile(EXPR) +REGEX_KCONFIG_STMT = re.compile(STMT) +REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") +REGEX_FILTER_FEATURES = re.compile(r"[A-Za-z0-9]$") + + +def main(): + """Main function of this module.""" + source_files = [] + kconfig_files = [] + defined_features = set() + referenced_features = dict() + + # use 'git ls-files' to get the worklist + pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) + (stdout, _) = pop.communicate() # wait until finished + if len(stdout) > 0 and stdout[-1] == "\n": + stdout = stdout[:-1] + + for gitfile in stdout.rsplit("\n"): + if ".git" in gitfile or "ChangeLog" in gitfile or \ + os.path.isdir(gitfile): + continue + if REGEX_FILE_KCONFIG.match(gitfile): + kconfig_files.append(gitfile) + else: + # All non-Kconfig files are checked for consistency + source_files.append(gitfile) + + for sfile in source_files: + parse_source_file(sfile, referenced_features) + + for kfile in kconfig_files: + parse_kconfig_file(kfile, defined_features, referenced_features) + + print "Undefined symbol used\tFile list" + for feature in sorted(referenced_features): + if feature not in defined_features: + if feature.endswith("_MODULE"): + # Avoid false positives for kernel modules + if feature[:-len("_MODULE")] in defined_features: + continue + if "FOO" in feature or "BAR" in feature: + continue + files = referenced_features.get(feature) + print "%s:\t%s" % (feature, ", ".join(files)) + + +def parse_source_file(sfile, referenced_features): + """Parse @sfile for referenced Kconfig features.""" + lines = [] + with open(sfile, "r") as stream: + lines = stream.readlines() + + for line in lines: + if not "CONFIG_" in line: + continue + features = REGEX_SOURCE_FEATURE.findall(line) + for feature in features: + if not REGEX_FILTER_FEATURES.search(feature): + continue + paths = referenced_features.get(feature, set()) + paths.add(sfile) + referenced_features[feature] = paths + + +def get_features_in_line(line): + """Return mentioned Kconfig features in @line.""" + return REGEX_FEATURE.findall(line) + + +def parse_kconfig_file(kfile, defined_features, referenced_features): + """Parse @kfile and update feature definitions and references.""" + lines = [] + skip = False + + with open(kfile, "r") as stream: + lines = stream.readlines() + + for i in range(len(lines)): + line = lines[i] + line = line.strip('\n') + line = line.split("#")[0] # Ignore Kconfig comments + + if REGEX_KCONFIG_DEF.match(line): + feature_def = REGEX_KCONFIG_DEF.findall(line) + defined_features.add(feature_def[0]) + skip = False + elif REGEX_KCONFIG_HELP.match(line): + skip = True + elif skip: + # Ignore content of help messages + pass + elif REGEX_KCONFIG_STMT.match(line): + features = get_features_in_line(line) + # Multi-line statements + while line.endswith("\\"): + i += 1 + line = lines[i] + line = line.strip('\n') + features.extend(get_features_in_line(line)) + for feature in set(features): + paths = referenced_features.get(feature, set()) + paths.add(kfile) + referenced_features[feature] = paths + + +if __name__ == "__main__": + main() diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh deleted file mode 100755 index ccb3391882d1..000000000000 --- a/scripts/checkkconfigsymbols.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -# Find Kconfig variables used in source code but never defined in Kconfig -# Copyright (C) 2007, Paolo 'Blaisorblade' Giarrusso - -# Tested with dash. -paths="$@" -[ -z "$paths" ] && paths=. - -# Doing this once at the beginning saves a lot of time, on a cache-hot tree. -Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`" - -printf "File list \tundefined symbol used\n" -find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i -do - # Output the bare Kconfig variable and the filename; the _MODULE part at - # the end is not removed here (would need perl an not-hungry regexp for that). - sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i -done | \ -# Smart "sort|uniq" implemented in awk and tuned to collect the names of all -# files which use a given symbol -awk '{map[$1, count[$1]++] = $2; } -END { - for (combIdx in map) { - split(combIdx, separate, SUBSEP); - # The value may have been removed. - if (! ( (separate[1], separate[2]) in map ) ) - continue; - symb=separate[1]; - printf "%s ", symb; - #Use gawk extension to delete the names vector - delete names; - #Portably delete the names vector - #split("", names); - for (i=0; i < count[symb]; i++) { - names[map[symb, i]] = 1; - # Unfortunately, we may still encounter symb, i in the - # outside iteration. - delete map[symb, i]; - } - i=0; - for (name in names) { - if (i > 0) - printf ", %s", name; - else - printf "%s", name; - i++; - } - printf "\n"; - } -}' | -while read symb files; do - # Remove the _MODULE suffix when checking the variable name. This should - # be done only on tristate symbols, actually, but Kconfig parsing is - # beyond the purpose of this script. - symb_bare=`echo $symb | sed -e 's/_MODULE//'` - if ! grep -q "\<$symb_bare\>" $Kconfigs; then - printf "$files: \t$symb\n" - fi -done|sort -- GitLab From 0f352239de1628d38ff35adb91842a732f4453cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 10 Oct 2014 11:12:47 +0200 Subject: [PATCH 3923/9457] i8k: Add support for Dell Latitude E6440 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dell Latitude E6440 needs same settings as E6540. Signed-off-by: Pali Rohár Acked-by: Guenter Roeck Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/char/i8k.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 34174d01462e..471f985e38d2 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -710,6 +710,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = { }, .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520], }, + { + .ident = "Dell Latitude E6440", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6440"), + }, + .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_E6540], + }, { .ident = "Dell Latitude E6540", .matches = { -- GitLab From 148b1fda69a816cae613f7a74b1423d65fa1621f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 18 Oct 2014 00:17:49 +0200 Subject: [PATCH 3924/9457] i8k: Add MODULE_DEVICE_TABLE macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds MODULE_DEVICE_TABLE macro so i8k.ko module can be automatically loaded based on dmi system alias. Signed-off-by: Pali Rohár Acked-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/char/i8k.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 471f985e38d2..7272b08dbd6c 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -796,6 +796,8 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = { { } }; +MODULE_DEVICE_TABLE(dmi, i8k_dmi_table); + /* * Probe for the presence of a supported laptop. */ -- GitLab From a176c24dc9a82b3304a31233bfc37e97c42de09b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 5 Nov 2014 18:18:52 +0200 Subject: [PATCH 3925/9457] mei: nfc: clean nfc internal struct on host exit NFC internal structure cleaning was dropped by commit commit 487056932d372cc4f6c636f21a928d6667b151d7 Author: Tomas Winkler Date: Mon Feb 17 15:13:19 2014 +0200 mei: Remove all bus devices from the mei_dev list when stopping the MEI When stopping the MEI, we should remove and potentially unregister all bus devices queued on the mei_dev linked list. We allocate nfc_dev and free it across the reset so we do not keep it in dirty state Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 4 +-- drivers/misc/mei/mei_dev.h | 1 + drivers/misc/mei/nfc.c | 52 +++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 4d20d60ca38d..b3a72bca5242 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -140,7 +140,7 @@ static struct device_type mei_cl_device_type = { .release = mei_cl_dev_release, }; -static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, +struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev, uuid_le uuid) { struct mei_cl *cl; @@ -160,7 +160,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, struct mei_cl *cl; int status; - cl = mei_bus_find_mei_cl_by_uuid(dev, uuid); + cl = mei_cl_bus_find_cl_by_uuid(dev, uuid); if (cl == NULL) return NULL; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 71744b16cc8c..1288a5cf60b9 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -349,6 +349,7 @@ void mei_cl_bus_rx_event(struct mei_cl *cl); void mei_cl_bus_remove_devices(struct mei_device *dev); int mei_cl_bus_init(void); void mei_cl_bus_exit(void); +struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev, uuid_le uuid); /** diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 622654323177..60ca9240368e 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -117,8 +117,6 @@ struct mei_nfc_dev { u16 recv_req_id; }; -static struct mei_nfc_dev nfc_dev; - /* UUIDs for NFC F/W clients */ const uuid_le mei_nfc_guid = UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, 0xd4, 0x50, 0x26, @@ -138,6 +136,9 @@ static const uuid_le mei_nfc_info_guid = UUID_LE(0xd2de1625, 0x382d, 0x417d, static void mei_nfc_free(struct mei_nfc_dev *ndev) { + if (!ndev) + return; + if (ndev->cl) { list_del(&ndev->cl->device_link); mei_cl_unlink(ndev->cl); @@ -150,7 +151,7 @@ static void mei_nfc_free(struct mei_nfc_dev *ndev) kfree(ndev->cl_info); } - memset(ndev, 0, sizeof(struct mei_nfc_dev)); + kfree(ndev); } static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) @@ -319,9 +320,10 @@ static int mei_nfc_if_version(struct mei_nfc_dev *ndev) static int mei_nfc_enable(struct mei_cl_device *cldev) { struct mei_device *dev; - struct mei_nfc_dev *ndev = &nfc_dev; + struct mei_nfc_dev *ndev; int ret; + ndev = (struct mei_nfc_dev *)cldev->priv_data; dev = ndev->cl->dev; ret = mei_nfc_connect(ndev); @@ -479,15 +481,25 @@ static void mei_nfc_init(struct work_struct *work) int mei_nfc_host_init(struct mei_device *dev) { - struct mei_nfc_dev *ndev = &nfc_dev; + struct mei_nfc_dev *ndev; struct mei_cl *cl_info, *cl = NULL; struct mei_me_client *me_cl; int ret; - /* already initialized */ - if (ndev->cl_info) + + /* in case of internal reset bail out + * as the device is already setup + */ + cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid); + if (cl) return 0; + ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL); + if (!ndev) { + ret = -ENOMEM; + goto err; + } + ndev->cl_info = mei_cl_allocate(dev); ndev->cl = mei_cl_allocate(dev); @@ -550,9 +562,31 @@ int mei_nfc_host_init(struct mei_device *dev) void mei_nfc_host_exit(struct mei_device *dev) { - struct mei_nfc_dev *ndev = &nfc_dev; + struct mei_nfc_dev *ndev; + struct mei_cl *cl; + struct mei_cl_device *cldev; + + cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid); + if (!cl) + return; + + cldev = cl->device; + if (!cldev) + return; - cancel_work_sync(&ndev->init_work); + ndev = (struct mei_nfc_dev *)cldev->priv_data; + if (ndev) + cancel_work_sync(&ndev->init_work); + + cldev->priv_data = NULL; + + mutex_lock(&dev->device_lock); + /* Need to remove the device here + * since mei_nfc_free will unlink the clients + */ + mei_cl_remove_device(cldev); + mei_nfc_free(ndev); + mutex_unlock(&dev->device_lock); } -- GitLab From 5ebdc364588a5b988fdaf56e2ec01815f1876e9a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 5 Nov 2014 11:44:48 +0200 Subject: [PATCH 3926/9457] mei: fix hbm MEI_HBM_STARTED ambiguity We have MEI_HBM_STARTED in two contexts one after start message was received and second after enumeration was completed. Because after start message reception we move immediately to the enumeration state, we need only the later meaning. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 2 -- drivers/misc/mei/hbm.h | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 256fc4673782..239d7f5d6a92 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -806,8 +806,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) return -EPROTO; } - dev->hbm_state = MEI_HBM_STARTED; - if (mei_hbm_enum_clients_req(dev)) { dev_err(dev->dev, "hbm: start: failed to send enumeration request\n"); return -EIO; diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h index b7cd3d857fd5..2544db7d1649 100644 --- a/drivers/misc/mei/hbm.h +++ b/drivers/misc/mei/hbm.h @@ -26,17 +26,17 @@ struct mei_cl; * * @MEI_HBM_IDLE : protocol not started * @MEI_HBM_STARTING : start request message was sent - * @MEI_HBM_STARTED : start reply message was received * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties + * @MEI_HBM_STARTED : enumeration was completed * @MEI_HBM_STOPPED : stopping exchange */ enum mei_hbm_state { MEI_HBM_IDLE = 0, MEI_HBM_STARTING, - MEI_HBM_STARTED, MEI_HBM_ENUM_CLIENTS, MEI_HBM_CLIENT_PROPERTIES, + MEI_HBM_STARTED, MEI_HBM_STOPPED, }; -- GitLab From 69f627f56fac212c1e49cd0d285e3f8cd264dd0c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 7 Nov 2014 19:03:19 +0100 Subject: [PATCH 3927/9457] drm/i915: Update DRIVER_DATE to 20141107 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8fb8eba08dc6..f830596faa9e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -55,7 +55,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20141024" +#define DRIVER_DATE "20141107" #undef WARN_ON #define WARN_ON(x) WARN(x, "WARN_ON(" #x ")") -- GitLab From 5559b7bc42f1ff85759246e40ef73abf3171d8d9 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Tue, 7 Oct 2014 18:25:43 +0300 Subject: [PATCH 3928/9457] devres: support sizes greater than an unsigned long As in 4f452e8aa492c0b8028ca9b4bdb4d018ba28c6c7, use resource_size_t to accomodate sizes greater than the size of an unsigned long int on platforms that have more than 32 bit physical addresses. Signed-off-by: Cristian Stoica Signed-off-by: Greg Kroah-Hartman --- include/linux/io.h | 4 ++-- lib/devres.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/io.h b/include/linux/io.h index d5fc9b8d8b03..fa02e55e5a2e 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -61,9 +61,9 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr) #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err) void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, - unsigned long size); + resource_size_t size); void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, - unsigned long size); + resource_size_t size); void devm_iounmap(struct device *dev, void __iomem *addr); int check_signature(const volatile void __iomem *io_addr, const unsigned char *signature, int length); diff --git a/lib/devres.c b/lib/devres.c index f4a195a6efe4..0f1dd2e9d2c1 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -23,7 +23,7 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data) * Managed ioremap(). Map is automatically unmapped on driver detach. */ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, - unsigned long size) + resource_size_t size) { void __iomem **ptr, *addr; @@ -52,7 +52,7 @@ EXPORT_SYMBOL(devm_ioremap); * detach. */ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, - unsigned long size) + resource_size_t size) { void __iomem **ptr, *addr; -- GitLab From e0f1147cc9512d3610d2f2a0f069690661444703 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Thu, 9 Oct 2014 15:00:27 +0300 Subject: [PATCH 3929/9457] uio: support memory sizes larger than 32 bits This is a completion to 27a90700a4275c5178b883b65927affdafa5185c The size field is also increased to allow values larger than 32 bits on platforms that have more than 32 bit physical addresses. Signed-off-by: Cristian Stoica Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/uio-howto.tmpl | 2 +- drivers/uio/uio.c | 4 ++-- include/linux/uio_driver.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index bbe9c1fd5cef..1fdc246e4256 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -540,7 +540,7 @@ appears in sysfs. -unsigned long size: Fill in the size of the +resource_size_t size: Fill in the size of the memory block that addr points to. If size is zero, the mapping is considered unused. Note that you must initialize size with zero for diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 60fa6278fbce..6276f13e9e12 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -56,12 +56,12 @@ static ssize_t map_name_show(struct uio_mem *mem, char *buf) static ssize_t map_addr_show(struct uio_mem *mem, char *buf) { - return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr); + return sprintf(buf, "%pa\n", &mem->addr); } static ssize_t map_size_show(struct uio_mem *mem, char *buf) { - return sprintf(buf, "0x%lx\n", mem->size); + return sprintf(buf, "%pa\n", &mem->size); } static ssize_t map_offset_show(struct uio_mem *mem, char *buf) diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index baa81718d985..32c0e83d6239 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -35,7 +35,7 @@ struct uio_map; struct uio_mem { const char *name; phys_addr_t addr; - unsigned long size; + resource_size_t size; int memtype; void __iomem *internal_addr; struct uio_map *map; -- GitLab From 4f689190bb55d171d2f6614f8a6cbd4b868e48bd Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Thu, 25 Sep 2014 21:52:04 -0700 Subject: [PATCH 3930/9457] Tools: hv: vssdaemon: ignore the EBUSY on multiple freezing the same partition If a partition appears mounted more than once in /proc/mounts, vss_do_freeze() succeeds only for the first time and gets EBUSY (on freeze) or EINVAL (on thaw) for the second time. The patch ignores these to make the backup feature work. Also improved the error handling in case a freeze operation fails. Signed-off-by: Dexuan Cui Reviewed-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_vss_daemon.c | 48 +++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 6a213b8cd7b9..1db9430d3fe4 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -44,21 +44,39 @@ static struct sockaddr_nl addr; #endif -static int vss_do_freeze(char *dir, unsigned int cmd, char *fs_op) +/* Don't use syslog() in the function since that can cause write to disk */ +static int vss_do_freeze(char *dir, unsigned int cmd) { int ret, fd = open(dir, O_RDONLY); if (fd < 0) return 1; + ret = ioctl(fd, cmd, 0); - syslog(LOG_INFO, "VSS: %s of %s: %s\n", fs_op, dir, strerror(errno)); + + /* + * If a partition is mounted more than once, only the first + * FREEZE/THAW can succeed and the later ones will get + * EBUSY/EINVAL respectively: there could be 2 cases: + * 1) a user may mount the same partition to differnt directories + * by mistake or on purpose; + * 2) The subvolume of btrfs appears to have the same partition + * mounted more than once. + */ + if (ret) { + if ((cmd == FIFREEZE && errno == EBUSY) || + (cmd == FITHAW && errno == EINVAL)) { + close(fd); + return 0; + } + } + close(fd); return !!ret; } static int vss_operate(int operation) { - char *fs_op; char match[] = "/dev/"; FILE *mounts; struct mntent *ent; @@ -68,11 +86,9 @@ static int vss_operate(int operation) switch (operation) { case VSS_OP_FREEZE: cmd = FIFREEZE; - fs_op = "freeze"; break; case VSS_OP_THAW: cmd = FITHAW; - fs_op = "thaw"; break; default: return -1; @@ -93,14 +109,22 @@ static int vss_operate(int operation) root_seen = 1; continue; } - error |= vss_do_freeze(ent->mnt_dir, cmd, fs_op); + error |= vss_do_freeze(ent->mnt_dir, cmd); + if (error && operation == VSS_OP_FREEZE) + goto err; } endmntent(mounts); if (root_seen) { - error |= vss_do_freeze("/", cmd, fs_op); + error |= vss_do_freeze("/", cmd); + if (error && operation == VSS_OP_FREEZE) + goto err; } + return error; +err: + endmntent(mounts); + vss_operate(VSS_OP_THAW); return error; } @@ -249,8 +273,16 @@ int main(void) case VSS_OP_FREEZE: case VSS_OP_THAW: error = vss_operate(op); - if (error) + syslog(LOG_INFO, "VSS: op=%s: %s\n", + op == VSS_OP_FREEZE ? "FREEZE" : "THAW", + error ? "failed" : "succeeded"); + + if (error) { error = HV_E_FAIL; + syslog(LOG_ERR, "op=%d failed!", op); + syslog(LOG_ERR, "report it with these files:"); + syslog(LOG_ERR, "/etc/fstab and /proc/mounts"); + } break; default: syslog(LOG_ERR, "Illegal op:%d\n", op); -- GitLab From 170f4bea2008054e5098f99359e29823a7b4b1b9 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 22 Oct 2014 18:07:11 +0200 Subject: [PATCH 3931/9457] tools: hv: introduce -n/--no-daemon option All tools/hv daemons do mandatory daemon() on startup. However, no pidfile is created, this make it difficult for an init system to track such daemons. Modern linux distros use systemd as their init system. It can handle the daemonizing by itself, however, it requires a daemon to stay in foreground for that. Some distros already carry distro-specific patch for hv tools which switches off daemon(). Introduce -n/--no-daemon option for all 3 daemons in hv/tools. Parse options with getopt() to make this part easily expandable. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_fcopy_daemon.c | 33 +++++++++++++++++++++++++++++++-- tools/hv/hv_kvp_daemon.c | 34 ++++++++++++++++++++++++++++++++-- tools/hv/hv_vss_daemon.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index 8f96b3ee0724..f437d739f37d 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -33,6 +33,7 @@ #include #include #include +#include static int target_fd; static char target_fname[W_MAX_PATH]; @@ -126,15 +127,43 @@ static int hv_copy_cancel(void) } -int main(void) +void print_usage(char *argv[]) +{ + fprintf(stderr, "Usage: %s [options]\n" + "Options are:\n" + " -n, --no-daemon stay in foreground, don't daemonize\n" + " -h, --help print this help\n", argv[0]); +} + +int main(int argc, char *argv[]) { int fd, fcopy_fd, len; int error; + int daemonize = 1, long_index = 0, opt; int version = FCOPY_CURRENT_VERSION; char *buffer[4096 * 2]; struct hv_fcopy_hdr *in_msg; - if (daemon(1, 0)) { + static struct option long_options[] = { + {"help", no_argument, 0, 'h' }, + {"no-daemon", no_argument, 0, 'n' }, + {0, 0, 0, 0 } + }; + + while ((opt = getopt_long(argc, argv, "hn", long_options, + &long_index)) != -1) { + switch (opt) { + case 'n': + daemonize = 0; + break; + case 'h': + default: + print_usage(argv); + exit(EXIT_FAILURE); + } + } + + if (daemonize && daemon(1, 0)) { syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno)); exit(EXIT_FAILURE); } diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 4088b816a3ee..22b076419c80 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -43,6 +43,7 @@ #include #include #include +#include /* * KVP protocol: The user mode component first registers with the @@ -1417,7 +1418,15 @@ netlink_send(int fd, struct cn_msg *msg) return sendmsg(fd, &message, 0); } -int main(void) +void print_usage(char *argv[]) +{ + fprintf(stderr, "Usage: %s [options]\n" + "Options are:\n" + " -n, --no-daemon stay in foreground, don't daemonize\n" + " -h, --help print this help\n", argv[0]); +} + +int main(int argc, char *argv[]) { int fd, len, nl_group; int error; @@ -1435,9 +1444,30 @@ int main(void) struct hv_kvp_ipaddr_value *kvp_ip_val; char *kvp_recv_buffer; size_t kvp_recv_buffer_len; + int daemonize = 1, long_index = 0, opt; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h' }, + {"no-daemon", no_argument, 0, 'n' }, + {0, 0, 0, 0 } + }; + + while ((opt = getopt_long(argc, argv, "hn", long_options, + &long_index)) != -1) { + switch (opt) { + case 'n': + daemonize = 0; + break; + case 'h': + default: + print_usage(argv); + exit(EXIT_FAILURE); + } + } - if (daemon(1, 0)) + if (daemonize && daemon(1, 0)) return 1; + openlog("KVP", 0, LOG_USER); syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 1db9430d3fe4..b720d8f0f901 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -36,6 +36,7 @@ #include #include #include +#include static struct sockaddr_nl addr; @@ -155,7 +156,15 @@ static int netlink_send(int fd, struct cn_msg *msg) return sendmsg(fd, &message, 0); } -int main(void) +void print_usage(char *argv[]) +{ + fprintf(stderr, "Usage: %s [options]\n" + "Options are:\n" + " -n, --no-daemon stay in foreground, don't daemonize\n" + " -h, --help print this help\n", argv[0]); +} + +int main(int argc, char *argv[]) { int fd, len, nl_group; int error; @@ -167,8 +176,28 @@ int main(void) struct hv_vss_msg *vss_msg; char *vss_recv_buffer; size_t vss_recv_buffer_len; + int daemonize = 1, long_index = 0, opt; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h' }, + {"no-daemon", no_argument, 0, 'n' }, + {0, 0, 0, 0 } + }; + + while ((opt = getopt_long(argc, argv, "hn", long_options, + &long_index)) != -1) { + switch (opt) { + case 'n': + daemonize = 0; + break; + case 'h': + default: + print_usage(argv); + exit(EXIT_FAILURE); + } + } - if (daemon(1, 0)) + if (daemonize && daemon(1, 0)) return 1; openlog("Hyper-V VSS", 0, LOG_USER); -- GitLab From 31d4ea1a093fcf668d5f95af44b8d41488bdb7ec Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 24 Oct 2014 12:20:27 +0200 Subject: [PATCH 3932/9457] Drivers: hv: util: make struct hv_do_fcopy match Hyper-V host messages An attempt to fix fcopy on i586 (bc5a5b0 Drivers: hv: util: Properly pack the data for file copy functionality) led to a regression on x86_64 (and actually didn't fix i586 breakage). Fcopy messages from Hyper-V host come in the following format: struct do_fcopy_hdr | 36 bytes 0000 | 4 bytes offset | 8 bytes size | 4 bytes data | 6144 bytes On x86_64 struct hv_do_fcopy matched this format without ' __attribute__((packed))' and on i586 adding ' __attribute__((packed))' to it doesn't change anything. Keep the structure packed and add padding to match re reality. Tested both i586 and x86_64 on Hyper-V Server 2012 R2. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Cc: Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/hyperv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index 0a8e6badb29b..bb1cb73c927a 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -134,6 +134,7 @@ struct hv_start_fcopy { struct hv_do_fcopy { struct hv_fcopy_hdr hdr; + __u32 pad; __u64 offset; __u32 size; __u8 data[DATA_FRAGMENT]; -- GitLab From 04a258c162a85c0f4ae56be67634dc43c9a4fa9b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 4 Nov 2014 13:40:11 +0100 Subject: [PATCH 3933/9457] Drivers: hv: vmbus: Fix a race condition when unregistering a device When build with Debug the following crash is sometimes observed: Call Trace: [] string+0x40/0x100 [] vsnprintf+0x218/0x5e0 [] ? trace_hardirqs_off+0xd/0x10 [] vscnprintf+0x11/0x30 [] vprintk+0xd0/0x5c0 [] ? vmbus_process_rescind_offer+0x0/0x110 [hv_vmbus] [] printk+0x41/0x45 [] vmbus_device_unregister+0x2c/0x40 [hv_vmbus] [] vmbus_process_rescind_offer+0x2b/0x110 [hv_vmbus] ... This happens due to the following race: between 'if (channel->device_obj)' check in vmbus_process_rescind_offer() and pr_debug() in vmbus_device_unregister() the device can disappear. Fix the issue by taking an additional reference to the device before proceeding to vmbus_device_unregister(). Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index a2d1a9612c86..d36ce6835fb7 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -216,9 +216,16 @@ static void vmbus_process_rescind_offer(struct work_struct *work) unsigned long flags; struct vmbus_channel *primary_channel; struct vmbus_channel_relid_released msg; + struct device *dev; + + if (channel->device_obj) { + dev = get_device(&channel->device_obj->device); + if (dev) { + vmbus_device_unregister(channel->device_obj); + put_device(dev); + } + } - if (channel->device_obj) - vmbus_device_unregister(channel->device_obj); memset(&msg, 0, sizeof(struct vmbus_channel_relid_released)); msg.child_relid = channel->offermsg.child_relid; msg.header.msgtype = CHANNELMSG_RELID_RELEASED; -- GitLab From 32eca22180804f71b06b63fd29b72f58be8b3c47 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 29 Oct 2014 20:22:56 +0100 Subject: [PATCH 3934/9457] misc: always assign miscdevice to file->private_data in open() As of now, a miscdevice driver has to provide an implementation of the open() file operation if it wants to have misc_open() assign a pointer to struct miscdevice to file->private_data for other file operations to use (given the user calls open()). This leads to situations where a miscdevice driver that doesn't need internal operations during open() has to implement open() that only returns immediately, in order to use the data in private_data in other fops. This provides consistent behaviour for miscdevice developers and will always provide the pointer in private_data. A driver's open() fop would, of course, just overwrite it, when using private_data itself. Signed-off-by: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/char/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index ffa97d261cf3..205ad4c58470 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -142,8 +142,8 @@ static int misc_open(struct inode * inode, struct file * file) err = 0; replace_fops(file, new_fops); + file->private_data = c; if (file->f_op->open) { - file->private_data = c; err = file->f_op->open(inode,file); } fail: -- GitLab From 2bfeeca107591134bf9a40945c50d337bf858612 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 29 Oct 2014 20:22:57 +0100 Subject: [PATCH 3935/9457] fbdev: pxa3xx-gcu: remove redundant implementation of open() the miscdevice core now does the work in any case. Signed-off-by: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/pxa3xx-gcu.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c index 4df3657fe221..7678a94cea7f 100644 --- a/drivers/video/fbdev/pxa3xx-gcu.c +++ b/drivers/video/fbdev/pxa3xx-gcu.c @@ -373,15 +373,6 @@ static inline struct pxa3xx_gcu_priv *to_pxa3xx_gcu_priv(struct file *file) return container_of(dev, struct pxa3xx_gcu_priv, misc_dev); } -/* - * provide an empty .open callback, so the core sets file->private_data - * for us. - */ -static int pxa3xx_gcu_open(struct inode *inode, struct file *file) -{ - return 0; -} - static ssize_t pxa3xx_gcu_write(struct file *file, const char *buff, size_t count, loff_t *offp) @@ -580,7 +571,6 @@ pxa3xx_gcu_free_buffers(struct device *dev, static const struct file_operations pxa3xx_gcu_miscdev_fops = { .owner = THIS_MODULE, - .open = pxa3xx_gcu_open, .write = pxa3xx_gcu_write, .unlocked_ioctl = pxa3xx_gcu_ioctl, .mmap = pxa3xx_gcu_mmap, -- GitLab From 965ab29ba09d75056a6c9b0f707cd1c2cc91188f Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 29 Oct 2014 20:22:58 +0100 Subject: [PATCH 3936/9457] char: misc: document behaviour of open() an open syscall now assignes file->private_data to a pointer to the miscdevice structure. This reminds driver developers not to duplicate code if they need this. Signed-off-by: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/char/misc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 205ad4c58470..69a08a6b43aa 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -169,7 +169,9 @@ static const struct file_operations misc_fops = { * the minor number requested is used. * * The structure passed is linked into the kernel and may not be - * destroyed until it has been unregistered. + * destroyed until it has been unregistered. By default, an open() + * syscall to the device sets file->private_data to point to the + * structure. * * A zero is returned on success and a negative errno code for * failure. -- GitLab From cf35d6e0475982667b0d2d318fb27be4b8849827 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 6 Nov 2014 16:23:39 +0000 Subject: [PATCH 3937/9457] misc: genwqe: check for error from get_user_pages_fast() `genwqe_user_vmap()` calls `get_user_pages_fast()` and if the return value is less than the number of pages requested, it frees the pages and returns an error (`-EFAULT`). However, it fails to consider a negative error return value from `get_user_pages_fast()`. In that case, the test `if (rc < m->nr_pages)` will be false (due to promotion of `rc` to a large `unsigned int`) and the code will continue on to call `genwqe_map_pages()` with an invalid list of page pointers. Fix it by bailing out if `get_user_pages_fast()` returns a negative error value. Signed-off-by: Ian Abbott Cc: # 3.14.x # 3.15.x # 3.16.x # 3.17.x Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 7cb3b7e41739..1ca94e6fa8fb 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -590,6 +590,8 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, m->nr_pages, 1, /* write by caller */ m->page_list); /* ptrs to pages */ + if (rc < 0) + goto fail_get_user_pages; /* assumption: get_user_pages can be killed by signals. */ if (rc < m->nr_pages) { -- GitLab From 7750efd59a290ab089bfc5c121787f4c630fe606 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 2 Oct 2014 09:26:16 +0200 Subject: [PATCH 3938/9457] pch_phub: Build context save/restore only for PM The pch_phub_save_reg_conf() and pch_phub_restore_reg_conf() functions are only used for suspend/resume support (i.e. when PM is enabled). If PM is disabled they don't need to be built. Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pch_phub.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 956597321d2a..9a17a9bab8d6 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -158,6 +158,7 @@ static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip, iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr); } +#ifdef CONFIG_PM /* pch_phub_save_reg_conf - saves register configuration */ static void pch_phub_save_reg_conf(struct pci_dev *pdev) { @@ -280,6 +281,7 @@ static void pch_phub_restore_reg_conf(struct pci_dev *pdev) if ((chip->ioh_type == 2) || (chip->ioh_type == 4)) iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET); } +#endif /** * pch_phub_read_serial_rom() - Reading Serial ROM -- GitLab From 41fb96a4b619afd2272acb6e981a7581efa8e118 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Wed, 24 Sep 2014 16:25:54 +0530 Subject: [PATCH 3939/9457] kobject: fix NULL pointer derefernce in kobj_child_ns_ops We will hit NULL pointer dereference if we call platform_device_register_simple or platform_device_add at very early stage. I have observed following crash when called platform_device_add from "init_irq" hook of machine_desc. This patch fixes this issue and let system handle this case gracefully instead of kernel panic. [0.000000] Unable to handle kernel NULL pointer dereference at virtual address 0000000c [0.000000] pgd = c0004000 [0.000000] [0000000c] *pgd=00000000 [0.000000] Internal error: Oops: 5 [#1] PREEMPT ARM [0.000000] Modules linked in: [0.000000] CPU: 0 PID: 0 Comm: swapper Tainted: G W 3.17.0-rc6-00198-ga1603f1-dirty #319 [0.000000] task: c05b23f0 ti: c05a8000 task.ti: c05a8000 [0.000000] PC is at kobject_namespace+0x18/0x58 [0.000000] LR is at kobject_add_internal+0x90/0x2ec [snip] [0.000000] [] (kobject_namespace) from [] (kobject_add_internal+0x90/0x2ec) [0.000000] [] (kobject_add_internal) from [] (kobject_add+0x4c/0x98) [0.000000] [] (kobject_add) from [] (device_add+0xe8/0x51c) [0.000000] [] (device_add) from [] (platform_device_add+0xb4/0x214) [0.000000] [] (platform_device_add) from [] (platform_device_register_full+0xb8/0xdc) [0.000000] [] (platform_device_register_full) from [] (exynos_init_irq+0x90/0x9c) [0.000000] [] (exynos_init_irq) from [] (init_IRQ+0x2c/0x78) [0.000000] [] (init_IRQ) from [] (start_kernel+0x22c/0x378) [0.000000] [] (start_kernel) from [<40008070>] (0x40008070) [0.000000] Code: e590000c e3500000 0a00000e e5903014 (e593300c) Signed-off-by: Pankaj Dubey Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kobject.c b/lib/kobject.c index 58751bb80a7c..03d4ab349fa7 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -976,7 +976,7 @@ const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent) { const struct kobj_ns_type_operations *ops = NULL; - if (parent && parent->ktype->child_ns_type) + if (parent && parent->ktype && parent->ktype->child_ns_type) ops = parent->ktype->child_ns_type(parent); return ops; -- GitLab From 0936896056365349afa867c16e9f9100a6707cbf Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 24 Sep 2014 18:21:04 +0300 Subject: [PATCH 3940/9457] fs: sysfs: return EGBIG on write if offset is larger than file size According to the user expectations common utilities like dd or sh redirection operator > should work correctly over binary files from sysfs. At the moment doing excessive write can not be completed: write(1, "\0\0\0\0\0\0\0\0", 8) = 4 write(1, "\0\0\0\0", 4) = 0 write(1, "\0\0\0\0", 4) = 0 write(1, "\0\0\0\0", 4) = 0 ... Fix the problem by returning EFBIG described in man 2 write. Signed-off-by: Vladimir Zapolskiy Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index e9ef59b3abb1..589abee16a39 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -125,7 +125,7 @@ static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf, if (size) { if (size <= pos) - return 0; + return -EFBIG; count = min_t(ssize_t, count, size - pos); } if (!count) -- GitLab From 2b75869bba676c248d8d25ae6d2bd9221dfffdb6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 13 Oct 2014 16:41:28 +1100 Subject: [PATCH 3941/9457] sysfs/kernfs: allow attributes to request write buffer be pre-allocated. md/raid allows metadata management to be performed in user-space. A various times, particularly on device failure, the metadata needs to be updated before further writes can be permitted. This means that the user-space program which updates metadata much not block on writeout, and so must not allocate memory. mlockall(MCL_CURRENT|MCL_FUTURE) and pre-allocation can avoid all memory allocation issues for user-memory, but that does not help kernel memory. Several kernel objects can be pre-allocated. e.g. files opened before any writes to the array are permitted. However some kernel allocation happens in places that cannot be pre-allocated. In particular, writes to sysfs files (to tell md that it can now allow writes to the array) allocate a buffer using GFP_KERNEL. This patch allows attributes to be marked as "PREALLOC". In that case the maximal buffer is allocated when the file is opened, and then used on each write instead of allocating a new buffer. As the same buffer is now shared for all writes on the same file description, the mutex is extended to cover full use of the buffer including the copy_from_user(). The new __ATTR_PREALLOC() 'or's a new flag in to the 'mode', which is inspected by sysfs_add_file_mode_ns() to determine if the file should be marked as requiring prealloc. Despite the comment, we *do* use ->seq_show together with ->prealloc in this patch. The next patch fixes that. Signed-off-by: NeilBrown Reviewed-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 45 ++++++++++++++++++++++++++++-------------- fs/sysfs/file.c | 31 ++++++++++++++++++++++------- include/linux/kernfs.h | 8 ++++++++ include/linux/sysfs.h | 9 +++++++++ 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 4429d6d9217f..70186e2e692a 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -106,7 +106,7 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos) const struct kernfs_ops *ops; /* - * @of->mutex nests outside active ref and is just to ensure that + * @of->mutex nests outside active ref and is primarily to ensure that * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); @@ -194,7 +194,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, return -ENOMEM; /* - * @of->mutex nests outside active ref and is just to ensure that + * @of->mutex nests outside active ref and is primarily to ensure that * the ops aren't called concurrently for the same open file. */ mutex_lock(&of->mutex); @@ -278,19 +278,16 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, len = min_t(size_t, count, PAGE_SIZE); } - buf = kmalloc(len + 1, GFP_KERNEL); + buf = of->prealloc_buf; + if (!buf) + buf = kmalloc(len + 1, GFP_KERNEL); if (!buf) return -ENOMEM; - if (copy_from_user(buf, user_buf, len)) { - len = -EFAULT; - goto out_free; - } - buf[len] = '\0'; /* guarantee string termination */ - /* - * @of->mutex nests outside active ref and is just to ensure that - * the ops aren't called concurrently for the same open file. + * @of->mutex nests outside active ref and is used both to ensure that + * the ops aren't called concurrently for the same open file, and + * to provide exclusive access to ->prealloc_buf (when that exists). */ mutex_lock(&of->mutex); if (!kernfs_get_active(of->kn)) { @@ -299,19 +296,27 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, goto out_free; } + if (copy_from_user(buf, user_buf, len)) { + len = -EFAULT; + goto out_unlock; + } + buf[len] = '\0'; /* guarantee string termination */ + ops = kernfs_ops(of->kn); if (ops->write) len = ops->write(of, buf, len, *ppos); else len = -EINVAL; - kernfs_put_active(of->kn); - mutex_unlock(&of->mutex); - if (len > 0) *ppos += len; + +out_unlock: + kernfs_put_active(of->kn); + mutex_unlock(&of->mutex); out_free: - kfree(buf); + if (buf != of->prealloc_buf) + kfree(buf); return len; } @@ -685,6 +690,14 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) */ of->atomic_write_len = ops->atomic_write_len; + if (ops->prealloc) { + int len = of->atomic_write_len ?: PAGE_SIZE; + of->prealloc_buf = kmalloc(len + 1, GFP_KERNEL); + error = -ENOMEM; + if (!of->prealloc_buf) + goto err_free; + } + /* * Always instantiate seq_file even if read access doesn't use * seq_file or is not requested. This unifies private data access @@ -715,6 +728,7 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) err_close: seq_release(inode, file); err_free: + kfree(of->prealloc_buf); kfree(of); err_out: kernfs_put_active(kn); @@ -728,6 +742,7 @@ static int kernfs_fop_release(struct inode *inode, struct file *filp) kernfs_put_open_node(kn, of); seq_release(inode, filp); + kfree(of->prealloc_buf); kfree(of); return 0; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 589abee16a39..4ad3721a991c 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -184,6 +184,17 @@ static const struct kernfs_ops sysfs_file_kfops_rw = { .write = sysfs_kf_write, }; +static const struct kernfs_ops sysfs_prealloc_kfops_wo = { + .write = sysfs_kf_write, + .prealloc = true, +}; + +static const struct kernfs_ops sysfs_prealloc_kfops_rw = { + .seq_show = sysfs_kf_seq_show, + .write = sysfs_kf_write, + .prealloc = true, +}; + static const struct kernfs_ops sysfs_bin_kfops_ro = { .read = sysfs_kf_bin_read, }; @@ -222,13 +233,19 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, kobject_name(kobj))) return -EINVAL; - if (sysfs_ops->show && sysfs_ops->store) - ops = &sysfs_file_kfops_rw; - else if (sysfs_ops->show) + if (sysfs_ops->show && sysfs_ops->store) { + if (mode & SYSFS_PREALLOC) + ops = &sysfs_prealloc_kfops_rw; + else + ops = &sysfs_file_kfops_rw; + } else if (sysfs_ops->show) ops = &sysfs_file_kfops_ro; - else if (sysfs_ops->store) - ops = &sysfs_file_kfops_wo; - else + else if (sysfs_ops->store) { + if (mode & SYSFS_PREALLOC) + ops = &sysfs_prealloc_kfops_wo; + else + ops = &sysfs_file_kfops_wo; + } else ops = &sysfs_file_kfops_empty; size = PAGE_SIZE; @@ -253,7 +270,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif - kn = __kernfs_create_file(parent, attr->name, mode, size, ops, + kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops, (void *)attr, ns, true, key); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 30faf797c2c3..d4e01b358341 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -179,6 +179,7 @@ struct kernfs_open_file { struct mutex mutex; int event; struct list_head list; + char *prealloc_buf; size_t atomic_write_len; bool mmapped; @@ -214,6 +215,13 @@ struct kernfs_ops { * larger ones are rejected with -E2BIG. */ size_t atomic_write_len; + /* + * "prealloc" causes a buffer to be allocated at open for + * all read/write requests. As ->seq_show uses seq_read() + * which does its own allocation, it is incompatible with + * ->prealloc. Provide ->read and ->write with ->prealloc. + */ + bool prealloc; ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes, loff_t off); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index f97d0dbb59fa..ddad16148bd6 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -70,6 +70,8 @@ struct attribute_group { * for examples.. */ +#define SYSFS_PREALLOC 010000 + #define __ATTR(_name, _mode, _show, _store) { \ .attr = {.name = __stringify(_name), \ .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ @@ -77,6 +79,13 @@ struct attribute_group { .store = _store, \ } +#define __ATTR_PREALLOC(_name, _mode, _show, _store) { \ + .attr = {.name = __stringify(_name), \ + .mode = SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\ + .show = _show, \ + .store = _store, \ +} + #define __ATTR_RO(_name) { \ .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ .show = _name##_show, \ -- GitLab From 4ef67a8c95f32ed0c8c6ed5fe01d1dd16358350e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 14 Oct 2014 16:57:26 +1100 Subject: [PATCH 3942/9457] sysfs/kernfs: make read requests on pre-alloc files use the buffer. To match the previous patch which used the pre-alloc buffer for writes, this patch causes reads to use the same buffer. This is not strictly necessary as the current seq_read() will allocate on first read, so user-space can trigger the required pre-alloc. But consistency is valuable. The read function is somewhat simpler than seq_read() and, for example, does not support reading from an offset into the file: reads must be at the start of the file. As seq_read() does not use the prealloc buffer, ->seq_show is incompatible with ->prealloc and caused an EINVAL return from open(). sysfs code which calls into kernfs always chooses the correct function. As the buffer is shared with writes and other reads, the mutex is extended to cover the copy_to_user. Signed-off-by: NeilBrown Reviewed-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 30 +++++++++++++++++++++--------- fs/sysfs/file.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 70186e2e692a..697390ea47b8 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -189,13 +189,16 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, const struct kernfs_ops *ops; char *buf; - buf = kmalloc(len, GFP_KERNEL); + buf = of->prealloc_buf; + if (!buf) + buf = kmalloc(len, GFP_KERNEL); if (!buf) return -ENOMEM; /* - * @of->mutex nests outside active ref and is primarily to ensure that - * the ops aren't called concurrently for the same open file. + * @of->mutex nests outside active ref and is used both to ensure that + * the ops aren't called concurrently for the same open file, and + * to provide exclusive access to ->prealloc_buf (when that exists). */ mutex_lock(&of->mutex); if (!kernfs_get_active(of->kn)) { @@ -210,21 +213,22 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, else len = -EINVAL; - kernfs_put_active(of->kn); - mutex_unlock(&of->mutex); - if (len < 0) - goto out_free; + goto out_unlock; if (copy_to_user(user_buf, buf, len)) { len = -EFAULT; - goto out_free; + goto out_unlock; } *ppos += len; + out_unlock: + kernfs_put_active(of->kn); + mutex_unlock(&of->mutex); out_free: - kfree(buf); + if (buf != of->prealloc_buf) + kfree(buf); return len; } @@ -690,6 +694,14 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) */ of->atomic_write_len = ops->atomic_write_len; + error = -EINVAL; + /* + * ->seq_show is incompatible with ->prealloc, + * as seq_read does its own allocation. + * ->read must be used instead. + */ + if (ops->prealloc && ops->seq_show) + goto err_free; if (ops->prealloc) { int len = of->atomic_write_len ?: PAGE_SIZE; of->prealloc_buf = kmalloc(len + 1, GFP_KERNEL); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 4ad3721a991c..dfe928a9540f 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -102,6 +102,22 @@ static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, return battr->read(of->file, kobj, battr, buf, pos, count); } +/* kernfs read callback for regular sysfs files with pre-alloc */ +static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, + size_t count, loff_t pos) +{ + const struct sysfs_ops *ops = sysfs_file_ops(of->kn); + struct kobject *kobj = of->kn->parent->priv; + + /* + * If buf != of->prealloc_buf, we don't know how + * large it is, so cannot safely pass it to ->show + */ + if (pos || WARN_ON_ONCE(buf != of->prealloc_buf)) + return 0; + return ops->show(kobj, of->kn->priv, buf); +} + /* kernfs write callback for regular sysfs files */ static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf, size_t count, loff_t pos) @@ -184,13 +200,18 @@ static const struct kernfs_ops sysfs_file_kfops_rw = { .write = sysfs_kf_write, }; +static const struct kernfs_ops sysfs_prealloc_kfops_ro = { + .read = sysfs_kf_read, + .prealloc = true, +}; + static const struct kernfs_ops sysfs_prealloc_kfops_wo = { .write = sysfs_kf_write, .prealloc = true, }; static const struct kernfs_ops sysfs_prealloc_kfops_rw = { - .seq_show = sysfs_kf_seq_show, + .read = sysfs_kf_read, .write = sysfs_kf_write, .prealloc = true, }; @@ -238,9 +259,12 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, ops = &sysfs_prealloc_kfops_rw; else ops = &sysfs_file_kfops_rw; - } else if (sysfs_ops->show) - ops = &sysfs_file_kfops_ro; - else if (sysfs_ops->store) { + } else if (sysfs_ops->show) { + if (mode & SYSFS_PREALLOC) + ops = &sysfs_prealloc_kfops_ro; + else + ops = &sysfs_file_kfops_ro; + } else if (sysfs_ops->store) { if (mode & SYSFS_PREALLOC) ops = &sysfs_prealloc_kfops_wo; else -- GitLab From 0cd75047de7f54d6fb4aba0ec5818f8194815a5a Mon Sep 17 00:00:00 2001 From: Sergey Klyaus Date: Wed, 8 Oct 2014 11:31:54 +0400 Subject: [PATCH 3943/9457] driver core: fix race with userland in device_add() bus_add_device() should be called before devtmpfs_create_node(), so when userland application opens device from devtmpfs, it wouldn't get ENODEV from kernel, because device_add() wasn't completed. Signed-off-by: Sergey Klyaus Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 14d162952c3b..00ec7ce6f3e3 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1019,18 +1019,6 @@ int device_add(struct device *dev) if (error) goto attrError; - if (MAJOR(dev->devt)) { - error = device_create_file(dev, &dev_attr_dev); - if (error) - goto ueventattrError; - - error = device_create_sys_dev_entry(dev); - if (error) - goto devtattrError; - - devtmpfs_create_node(dev); - } - error = device_add_class_symlinks(dev); if (error) goto SymlinkError; @@ -1045,6 +1033,18 @@ int device_add(struct device *dev) goto DPMError; device_pm_add(dev); + if (MAJOR(dev->devt)) { + error = device_create_file(dev, &dev_attr_dev); + if (error) + goto DevAttrError; + + error = device_create_sys_dev_entry(dev); + if (error) + goto SysEntryError; + + devtmpfs_create_node(dev); + } + /* Notify clients of device addition. This call must come * after dpm_sysfs_add() and before kobject_uevent(). */ @@ -1074,6 +1074,12 @@ int device_add(struct device *dev) done: put_device(dev); return error; + SysEntryError: + if (MAJOR(dev->devt)) + device_remove_file(dev, &dev_attr_dev); + DevAttrError: + device_pm_remove(dev); + dpm_sysfs_remove(dev); DPMError: bus_remove_device(dev); BusError: @@ -1081,14 +1087,6 @@ int device_add(struct device *dev) AttrsError: device_remove_class_symlinks(dev); SymlinkError: - if (MAJOR(dev->devt)) - devtmpfs_delete_node(dev); - if (MAJOR(dev->devt)) - device_remove_sys_dev_entry(dev); - devtattrError: - if (MAJOR(dev->devt)) - device_remove_file(dev, &dev_attr_dev); - ueventattrError: device_remove_file(dev, &dev_attr_uevent); attrError: kobject_uevent(&dev->kobj, KOBJ_REMOVE); -- GitLab From 0372ffb35d00288802265586a29c117911d02fb8 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 31 Oct 2014 11:13:07 -0600 Subject: [PATCH 3944/9457] driver core: Fix unbalanced device reference in drivers_probe bus_find_device_by_name() acquires a device reference which is never released. This results in an object leak, which on older kernels results in failure to release all resources of PCI devices. libvirt uses drivers_probe to re-attach devices to the host after assignment and is therefore a common trigger for this leak. Example: # cd /sys/bus/pci/ # dmesg -C # echo 1 > devices/0000\:01\:00.0/sriov_numvfs # echo 0 > devices/0000\:01\:00.0/sriov_numvfs # dmesg | grep 01:10 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_cleanup, parent (null) kobject: '0000:01:10.0' (ffff8801d79cd0a8): calling ktype release kobject: '0000:01:10.0': free name [kobject freed as expected] # dmesg -C # echo 1 > devices/0000\:01\:00.0/sriov_numvfs # echo 0000:01:10.0 > drivers_probe # echo 0 > devices/0000\:01\:00.0/sriov_numvfs # dmesg | grep 01:10 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' [no free] Signed-off-by: Alex Williamson Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 83e910a57563..876bae5ade33 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -254,13 +254,15 @@ static ssize_t store_drivers_probe(struct bus_type *bus, const char *buf, size_t count) { struct device *dev; + int err = -EINVAL; dev = bus_find_device_by_name(bus, NULL, buf); if (!dev) return -ENODEV; - if (bus_rescan_devices_helper(dev, NULL) != 0) - return -EINVAL; - return count; + if (bus_rescan_devices_helper(dev, NULL) == 0) + err = count; + put_device(dev); + return err; } static struct device *next_device(struct klist_iter *i) -- GitLab From bb34cb6bbd287b57e955bc5cfd42fcde6aaca279 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 31 Oct 2014 11:13:07 -0600 Subject: [PATCH 3945/9457] driver core: Fix unbalanced device reference in drivers_probe bus_find_device_by_name() acquires a device reference which is never released. This results in an object leak, which on older kernels results in failure to release all resources of PCI devices. libvirt uses drivers_probe to re-attach devices to the host after assignment and is therefore a common trigger for this leak. Example: # cd /sys/bus/pci/ # dmesg -C # echo 1 > devices/0000\:01\:00.0/sriov_numvfs # echo 0 > devices/0000\:01\:00.0/sriov_numvfs # dmesg | grep 01:10 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000 kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_cleanup, parent (null) kobject: '0000:01:10.0' (ffff8801d79cd0a8): calling ktype release kobject: '0000:01:10.0': free name [kobject freed as expected] # dmesg -C # echo 1 > devices/0000\:01\:00.0/sriov_numvfs # echo 0000:01:10.0 > drivers_probe # echo 0 > devices/0000\:01\:00.0/sriov_numvfs # dmesg | grep 01:10 pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000 kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0' [no free] Signed-off-by: Alex Williamson Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 83e910a57563..876bae5ade33 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -254,13 +254,15 @@ static ssize_t store_drivers_probe(struct bus_type *bus, const char *buf, size_t count) { struct device *dev; + int err = -EINVAL; dev = bus_find_device_by_name(bus, NULL, buf); if (!dev) return -ENODEV; - if (bus_rescan_devices_helper(dev, NULL) != 0) - return -EINVAL; - return count; + if (bus_rescan_devices_helper(dev, NULL) == 0) + err = count; + put_device(dev); + return err; } static struct device *next_device(struct klist_iter *i) -- GitLab From d25221525e0e2cfd70e4ec7216549c06609a8bd2 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Sat, 25 Oct 2014 14:26:13 +0200 Subject: [PATCH 3946/9457] W1: ds2490: Increase timeout when waiting for status Adjust the bulk message timeout to the other ones (1000ms). Otherwise the following dmesg errors can be seen on a Raspberry Pi: [ 31.492386] Failed to read 1-wire data from 0x81: err=-110. [ 31.504168] 0x81: count=-110, status: [ 31.613404] Failed to read 1-wire data from 0x81: err=-110. [ 31.621915] 0x81: count=-110, status: [ 43.260968] Failed to read 1-wire data from 0x81: err=-110. [ 43.270998] 0x81: count=-110, status: [ 43.379959] Failed to read 1-wire data from 0x81: err=-110. [ 43.388854] 0x81: count=-110, status: Signed-off-by: Alexander Stein Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/ds2490.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index 1de6df87bfa3..049a884a756f 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -253,7 +253,7 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, count = 0; err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev, - dev->ep[EP_STATUS]), buf, size, &count, 100); + dev->ep[EP_STATUS]), buf, size, &count, 1000); if (err < 0) { pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); -- GitLab From d0439a5442cf43434d87faf34f4d2c19d3aba88a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 29 Oct 2014 11:42:50 +0300 Subject: [PATCH 3947/9457] hangcheck-timer: cleanup casting in hangcheck_init() The 32 bit addition "(hangcheck_margin + hangcheck_tick)" could potentially overflow. It triggers a static checker warning to have an overflowed addition followed by a no-op cast. I have moved the cast so that the addition can't overflow. Also I removed the unneeded cast on the following line since both "hangcheck_tsc_margin" and "TIMER_FREQ" are already 64 bit types. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/char/hangcheck-timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index ebc4c73d8ca4..a7c5c59675f0 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c @@ -168,8 +168,8 @@ static int __init hangcheck_init(void) printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", VERSION_STR, hangcheck_tick, hangcheck_margin); hangcheck_tsc_margin = - (unsigned long long)(hangcheck_margin + hangcheck_tick); - hangcheck_tsc_margin *= (unsigned long long)TIMER_FREQ; + (unsigned long long)hangcheck_margin + hangcheck_tick; + hangcheck_tsc_margin *= TIMER_FREQ; hangcheck_tsc = ktime_get_ns(); mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); -- GitLab From cfd1f008c4ee7ba4567f8488fb2dc740bd787151 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 21 Oct 2014 00:29:23 +0400 Subject: [PATCH 3948/9457] pcmcia: sa1111: pass sa1111_dev to badge4-specific code Pass sa1111_dev to platform-specific init code, as it is done by lubbock and neponset. This removes a compilation warnings: drivers/pcmcia/sa1111_badge4.c: In function 'pcmcia_badge4_init': drivers/pcmcia/sa1111_badge4.c:147:5: warning: passing argument 1 of 'sa1111_pcmcia_add' from incompatible pointer type [enabled by default] In file included from drivers/pcmcia/sa1111_badge4.c:26:0: drivers/pcmcia/sa1111_generic.h:15:5: note: expected 'struct sa1111_dev *' but argument is of type 'struct device *' Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/sa1111_badge4.c | 2 +- drivers/pcmcia/sa1111_generic.c | 2 +- drivers/pcmcia/sa1111_generic.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c index 4d206f4dd67b..12f0dd091477 100644 --- a/drivers/pcmcia/sa1111_badge4.c +++ b/drivers/pcmcia/sa1111_badge4.c @@ -132,7 +132,7 @@ static struct pcmcia_low_level badge4_pcmcia_ops = { .nr = 2, }; -int pcmcia_badge4_init(struct device *dev) +int pcmcia_badge4_init(struct sa1111_dev *dev) { int ret = -ENODEV; diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 65b02c3e14ce..a353186509cf 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -197,7 +197,7 @@ static int pcmcia_probe(struct sa1111_dev *dev) sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); #ifdef CONFIG_SA1100_BADGE4 - pcmcia_badge4_init(&dev->dev); + pcmcia_badge4_init(dev); #endif #ifdef CONFIG_SA1100_JORNADA720 pcmcia_jornada720_init(&dev->dev); diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index f6376e34a7e4..86b9cc883420 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h @@ -18,7 +18,7 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); -extern int pcmcia_badge4_init(struct device *); +extern int pcmcia_badge4_init(struct sa1111_dev *); extern int pcmcia_jornada720_init(struct device *); extern int pcmcia_lubbock_init(struct sa1111_dev *); extern int pcmcia_neponset_init(struct sa1111_dev *); -- GitLab From 4bc9ef297e3e85deeae81d1156fac89012c7db9a Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 21 Oct 2014 00:29:24 +0400 Subject: [PATCH 3949/9457] pcmcia: sa1111: pass sa1111_dev to jornada720 code All other sa1111 platforms pass sa1111_dev instance to platform-specific code. Follow this approach for Jornada720 platform code. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/sa1111_generic.c | 2 +- drivers/pcmcia/sa1111_generic.h | 2 +- drivers/pcmcia/sa1111_jornada720.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index a353186509cf..53299f866c5d 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -200,7 +200,7 @@ static int pcmcia_probe(struct sa1111_dev *dev) pcmcia_badge4_init(dev); #endif #ifdef CONFIG_SA1100_JORNADA720 - pcmcia_jornada720_init(&dev->dev); + pcmcia_jornada720_init(dev); #endif #ifdef CONFIG_ARCH_LUBBOCK pcmcia_lubbock_init(dev); diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index 86b9cc883420..e74ecfdc1b26 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h @@ -19,7 +19,7 @@ extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); extern int pcmcia_badge4_init(struct sa1111_dev *); -extern int pcmcia_jornada720_init(struct device *); +extern int pcmcia_jornada720_init(struct sa1111_dev *); extern int pcmcia_lubbock_init(struct sa1111_dev *); extern int pcmcia_neponset_init(struct sa1111_dev *); diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c index 40e040314503..c2c30580c83f 100644 --- a/drivers/pcmcia/sa1111_jornada720.c +++ b/drivers/pcmcia/sa1111_jornada720.c @@ -92,10 +92,9 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = { .nr = 2, }; -int pcmcia_jornada720_init(struct device *dev) +int pcmcia_jornada720_init(struct sa1111_dev *sadev) { int ret = -ENODEV; - struct sa1111_dev *sadev = SA1111_DEV(dev); if (machine_is_jornada720()) { unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; -- GitLab From f4c9485f9f5d816bb21333b517d0e3d2746dd285 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Nov 2014 11:26:15 -0800 Subject: [PATCH 3950/9457] Revert "driver core: Fix unbalanced device reference in drivers_probe" This reverts commit bb34cb6bbd287b57e955bc5cfd42fcde6aaca279. Wrong patch for the wrong branch, sorry for the noise... Cc: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 876bae5ade33..83e910a57563 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -254,15 +254,13 @@ static ssize_t store_drivers_probe(struct bus_type *bus, const char *buf, size_t count) { struct device *dev; - int err = -EINVAL; dev = bus_find_device_by_name(bus, NULL, buf); if (!dev) return -ENODEV; - if (bus_rescan_devices_helper(dev, NULL) == 0) - err = count; - put_device(dev); - return err; + if (bus_rescan_devices_helper(dev, NULL) != 0) + return -EINVAL; + return count; } static struct device *next_device(struct klist_iter *i) -- GitLab From 5aaba36318e5995e8c95d077a46d9a4d00fcc1cd Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 30 Sep 2014 14:48:22 +0100 Subject: [PATCH 3951/9457] cpumask: factor out show_cpumap into separate helper function Many sysfs *_show function use cpu{list,mask}_scnprintf to copy cpumap to the buffer aligned to PAGE_SIZE, append '\n' and '\0' to return null terminated buffer with newline. This patch creates a new helper function cpumap_print_to_pagebuf in cpumask.h using newly added bitmap_print_to_pagebuf and consolidates most of those sysfs functions using the new helper function. Signed-off-by: Sudeep Holla Suggested-by: Stephen Boyd Tested-by: Stephen Boyd Acked-by: "Rafael J. Wysocki" Acked-by: Bjorn Helgaas Acked-by: Peter Zijlstra (Intel) Cc: Greg Kroah-Hartman Cc: x86@kernel.org Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/perf_event_amd_iommu.c | 5 +-- arch/x86/kernel/cpu/perf_event_amd_uncore.c | 6 +-- arch/x86/kernel/cpu/perf_event_intel_rapl.c | 6 +-- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 6 +-- drivers/acpi/acpi_pad.c | 8 ++-- drivers/base/cpu.c | 5 +-- drivers/base/node.c | 14 ++----- drivers/base/topology.c | 22 +---------- drivers/pci/pci-sysfs.c | 39 +++++-------------- include/linux/bitmap.h | 3 ++ include/linux/cpumask.h | 17 ++++++++ lib/bitmap.c | 29 ++++++++++++++ 12 files changed, 73 insertions(+), 87 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c b/arch/x86/kernel/cpu/perf_event_amd_iommu.c index 639d1289b1ba..97242a9242bd 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c +++ b/arch/x86/kernel/cpu/perf_event_amd_iommu.c @@ -130,10 +130,7 @@ static ssize_t _iommu_cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &iommu_cpumask); - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask); } static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL); diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c index 30790d798e6b..cc6cedb8f25d 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_amd_uncore.c @@ -219,7 +219,6 @@ static ssize_t amd_uncore_attr_show_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { - int n; cpumask_t *active_mask; struct pmu *pmu = dev_get_drvdata(dev); @@ -230,10 +229,7 @@ static ssize_t amd_uncore_attr_show_cpumask(struct device *dev, else return 0; - n = cpulist_scnprintf(buf, PAGE_SIZE - 2, active_mask); - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(true, buf, active_mask); } static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL); diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index d64f275fe274..673f930c700f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -365,11 +365,7 @@ static void rapl_pmu_event_read(struct perf_event *event) static ssize_t rapl_get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { - int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &rapl_cpu_mask); - - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask); } static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 9762dbd9f3f7..08f3fed2b0f2 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -647,11 +647,7 @@ static int uncore_pmu_event_init(struct perf_event *event) static ssize_t uncore_get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { - int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &uncore_cpu_mask); - - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask); } static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL); diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index f148a0580e04..c7b105c0e1d3 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -350,12 +350,10 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev, static ssize_t acpi_pad_idlecpus_show(struct device *dev, struct device_attribute *attr, char *buf) { - int n = 0; - n = cpumask_scnprintf(buf, PAGE_SIZE-2, to_cpumask(pad_busy_cpus_bits)); - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(false, buf, + to_cpumask(pad_busy_cpus_bits)); } + static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, acpi_pad_idlecpus_show, acpi_pad_idlecpus_store); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 006b1bc5297d..4d8a56406fbb 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -207,11 +207,8 @@ static ssize_t show_cpus_attr(struct device *dev, char *buf) { struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr); - int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map)); - buf[n++] = '\n'; - buf[n] = '\0'; - return n; + return cpumap_print_to_pagebuf(true, buf, *ca->map); } #define _CPU_ATTR(name, map) \ diff --git a/drivers/base/node.c b/drivers/base/node.c index 472168cd0c97..a3b82e9c7f20 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -25,32 +25,26 @@ static struct bus_type node_subsys = { }; -static ssize_t node_read_cpumap(struct device *dev, int type, char *buf) +static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf) { struct node *node_dev = to_node(dev); const struct cpumask *mask = cpumask_of_node(node_dev->dev.id); - int len; /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */ BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1)); - len = type? - cpulist_scnprintf(buf, PAGE_SIZE-2, mask) : - cpumask_scnprintf(buf, PAGE_SIZE-2, mask); - buf[len++] = '\n'; - buf[len] = '\0'; - return len; + return cpumap_print_to_pagebuf(list, buf, mask); } static inline ssize_t node_read_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { - return node_read_cpumap(dev, 0, buf); + return node_read_cpumap(dev, false, buf); } static inline ssize_t node_read_cpulist(struct device *dev, struct device_attribute *attr, char *buf) { - return node_read_cpumap(dev, 1, buf); + return node_read_cpumap(dev, true, buf); } static DEVICE_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL); diff --git a/drivers/base/topology.c b/drivers/base/topology.c index be7c1fb7c0c9..f7c353843ddf 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -42,29 +42,11 @@ static ssize_t show_##name(struct device *dev, \ return sprintf(buf, "%d\n", topology_##name(dev->id)); \ } -#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \ - defined(topology_book_cpumask) -static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf) -{ - ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; - int n = 0; - - if (len > 1) { - n = type? - cpulist_scnprintf(buf, len-2, mask) : - cpumask_scnprintf(buf, len-2, mask); - buf[n++] = '\n'; - buf[n] = '\0'; - } - return n; -} -#endif - #define define_siblings_show_map(name) \ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ - return show_cpumap(0, topology_##name(dev->id), buf); \ + return cpumap_print_to_pagebuf(false, buf, topology_##name(dev->id));\ } #define define_siblings_show_list(name) \ @@ -72,7 +54,7 @@ static ssize_t show_##name##_list(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ - return show_cpumap(1, topology_##name(dev->id), buf); \ + return cpumap_print_to_pagebuf(true, buf, topology_##name(dev->id));\ } #define define_siblings_show_func(name) \ diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 2c6643fdc0cf..368bdac42603 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -77,11 +77,10 @@ static ssize_t broken_parity_status_store(struct device *dev, } static DEVICE_ATTR_RW(broken_parity_status); -static ssize_t pci_dev_show_local_cpu(struct device *dev, int type, +static ssize_t pci_dev_show_local_cpu(struct device *dev, bool list, struct device_attribute *attr, char *buf) { const struct cpumask *mask; - int len; #ifdef CONFIG_NUMA mask = (dev_to_node(dev) == -1) ? cpu_online_mask : @@ -89,59 +88,41 @@ static ssize_t pci_dev_show_local_cpu(struct device *dev, int type, #else mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); #endif - len = type ? - cpumask_scnprintf(buf, PAGE_SIZE-2, mask) : - cpulist_scnprintf(buf, PAGE_SIZE-2, mask); - - buf[len++] = '\n'; - buf[len] = '\0'; - return len; + return cpumap_print_to_pagebuf(list, buf, mask); } static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf) { - return pci_dev_show_local_cpu(dev, 1, attr, buf); + return pci_dev_show_local_cpu(dev, false, attr, buf); } static DEVICE_ATTR_RO(local_cpus); static ssize_t local_cpulist_show(struct device *dev, struct device_attribute *attr, char *buf) { - return pci_dev_show_local_cpu(dev, 0, attr, buf); + return pci_dev_show_local_cpu(dev, true, attr, buf); } static DEVICE_ATTR_RO(local_cpulist); /* * PCI Bus Class Devices */ -static ssize_t pci_bus_show_cpuaffinity(struct device *dev, int type, - struct device_attribute *attr, - char *buf) -{ - int ret; - const struct cpumask *cpumask; - - cpumask = cpumask_of_pcibus(to_pci_bus(dev)); - ret = type ? - cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask) : - cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask); - buf[ret++] = '\n'; - buf[ret] = '\0'; - return ret; -} - static ssize_t cpuaffinity_show(struct device *dev, struct device_attribute *attr, char *buf) { - return pci_bus_show_cpuaffinity(dev, 0, attr, buf); + const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev)); + + return cpumap_print_to_pagebuf(false, buf, cpumask); } static DEVICE_ATTR_RO(cpuaffinity); static ssize_t cpulistaffinity_show(struct device *dev, struct device_attribute *attr, char *buf) { - return pci_bus_show_cpuaffinity(dev, 1, attr, buf); + const struct cpumask *cpumask = cpumask_of_pcibus(to_pci_bus(dev)); + + return cpumap_print_to_pagebuf(true, buf, cpumask); } static DEVICE_ATTR_RO(cpulistaffinity); diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index e1c8d080c427..9d5c3224a1e2 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -60,6 +60,7 @@ * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region * bitmap_release_region(bitmap, pos, order) Free specified bit region * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region + * bitmap_print_to_pagebuf(list, buf, mask, nbits) Print bitmap src as list/hex */ /* @@ -145,6 +146,8 @@ extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int o extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order); extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); extern int bitmap_ord_to_pos(const unsigned long *bitmap, int n, int bits); +extern int bitmap_print_to_pagebuf(bool list, char *buf, + const unsigned long *maskp, int nmaskbits); #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) #define BITMAP_LAST_WORD_MASK(nbits) \ diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 0a9a6da21e74..b950e9d6008b 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -803,6 +803,23 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu) } #endif /* NR_CPUS > BITS_PER_LONG */ +/** + * cpumap_print_to_pagebuf - copies the cpumask into the buffer either + * as comma-separated list of cpus or hex values of cpumask + * @list: indicates whether the cpumap must be list + * @mask: the cpumask to copy + * @buf: the buffer to copy into + * + * Returns the length of the (null-terminated) @buf string, zero if + * nothing is copied. + */ +static inline ssize_t +cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) +{ + return bitmap_print_to_pagebuf(list, buf, cpumask_bits(mask), + nr_cpumask_bits); +} + /* * * From here down, all obsolete. Use cpumask_ variants! diff --git a/lib/bitmap.c b/lib/bitmap.c index b499ab6ada29..5bc7a1128fe8 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -12,6 +12,8 @@ #include #include #include + +#include #include /* @@ -583,6 +585,33 @@ int bitmap_scnlistprintf(char *buf, unsigned int buflen, } EXPORT_SYMBOL(bitmap_scnlistprintf); +/** + * bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string + * @list: indicates whether the bitmap must be list + * @buf: page aligned buffer into which string is placed + * @maskp: pointer to bitmap to convert + * @nmaskbits: size of bitmap, in bits + * + * Output format is a comma-separated list of decimal numbers and + * ranges if list is specified or hex digits grouped into comma-separated + * sets of 8 digits/set. Returns the number of characters written to buf. + */ +int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, + int nmaskbits) +{ + ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf - 2; + int n = 0; + + if (len > 1) { + n = list ? bitmap_scnlistprintf(buf, len, maskp, nmaskbits) : + bitmap_scnprintf(buf, len, maskp, nmaskbits); + buf[n++] = '\n'; + buf[n] = '\0'; + } + return n; +} +EXPORT_SYMBOL(bitmap_print_to_pagebuf); + /** * __bitmap_parselist - convert list format ASCII string to bitmap * @buf: read nul-terminated user string from this buffer -- GitLab From d6ea8d01d1893e1299a4016d62fdda870b8cc215 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 30 Sep 2014 14:48:23 +0100 Subject: [PATCH 3952/9457] topology: replace custom attribute macros with standard DEVICE_ATTR* Currently couple of custom macros are defined to declare the device attributes. However there are already standard macros defined in device.h that suffice the need and these custom macros can be removed. This patch replaces custom attribute macros with standard DEVICE_ATTR_RO attribute Signed-off-by: Sudeep Holla Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 53 +++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/base/topology.c b/drivers/base/topology.c index f7c353843ddf..6491f45200a7 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -29,57 +29,52 @@ #include #include -#define define_one_ro_named(_name, _func) \ - static DEVICE_ATTR(_name, 0444, _func, NULL) - -#define define_one_ro(_name) \ - static DEVICE_ATTR(_name, 0444, show_##_name, NULL) - #define define_id_show_func(name) \ -static ssize_t show_##name(struct device *dev, \ +static ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ return sprintf(buf, "%d\n", topology_##name(dev->id)); \ } -#define define_siblings_show_map(name) \ -static ssize_t show_##name(struct device *dev, \ +#define define_siblings_show_map(name, mask) \ +static ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ - return cpumap_print_to_pagebuf(false, buf, topology_##name(dev->id));\ + return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\ } -#define define_siblings_show_list(name) \ -static ssize_t show_##name##_list(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ +#define define_siblings_show_list(name, mask) \ +static ssize_t name##_list_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ { \ - return cpumap_print_to_pagebuf(true, buf, topology_##name(dev->id));\ + return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\ } -#define define_siblings_show_func(name) \ - define_siblings_show_map(name); define_siblings_show_list(name) +#define define_siblings_show_func(name, mask) \ + define_siblings_show_map(name, mask); \ + define_siblings_show_list(name, mask) define_id_show_func(physical_package_id); -define_one_ro(physical_package_id); +static DEVICE_ATTR_RO(physical_package_id); define_id_show_func(core_id); -define_one_ro(core_id); +static DEVICE_ATTR_RO(core_id); -define_siblings_show_func(thread_cpumask); -define_one_ro_named(thread_siblings, show_thread_cpumask); -define_one_ro_named(thread_siblings_list, show_thread_cpumask_list); +define_siblings_show_func(thread_siblings, thread_cpumask); +static DEVICE_ATTR_RO(thread_siblings); +static DEVICE_ATTR_RO(thread_siblings_list); -define_siblings_show_func(core_cpumask); -define_one_ro_named(core_siblings, show_core_cpumask); -define_one_ro_named(core_siblings_list, show_core_cpumask_list); +define_siblings_show_func(core_siblings, core_cpumask); +static DEVICE_ATTR_RO(core_siblings); +static DEVICE_ATTR_RO(core_siblings_list); #ifdef CONFIG_SCHED_BOOK define_id_show_func(book_id); -define_one_ro(book_id); -define_siblings_show_func(book_cpumask); -define_one_ro_named(book_siblings, show_book_cpumask); -define_one_ro_named(book_siblings_list, show_book_cpumask_list); +static DEVICE_ATTR_RO(book_id); +define_siblings_show_func(book_siblings, book_cpumask); +static DEVICE_ATTR_RO(book_siblings); +static DEVICE_ATTR_RO(book_siblings_list); #endif static struct attribute *default_attrs[] = { -- GitLab From 3d52943b3a51497a777e6d7d840a38596a92cee9 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 30 Sep 2014 14:48:24 +0100 Subject: [PATCH 3953/9457] drivers: base: add cpu_device_create to support per-cpu devices This patch adds a new function to create per-cpu devices. This helps in: 1. reusing the device infrastructure to create any cpu related attributes and corresponding sysfs instead of creating and dealing with raw kobjects directly 2. retaining the legacy path(/sys/devices/system/cpu/..) to support existing sysfs ABI 3. avoiding to create links in the bus directory pointing to the device as there would be per-cpu instance of these devices with the same name since dev->bus is not populated to cpu_sysbus on purpose Signed-off-by: Sudeep Holla Tested-by: Stephen Boyd Cc: Greg Kroah-Hartman Cc: David Herrmann Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/cpu.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/cpu.h | 4 ++++ 2 files changed, 58 insertions(+) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4d8a56406fbb..f829a4c71749 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -363,6 +363,60 @@ struct device *get_cpu_device(unsigned cpu) } EXPORT_SYMBOL_GPL(get_cpu_device); +static void device_create_release(struct device *dev) +{ + kfree(dev); +} + +static struct device * +__cpu_device_create(struct device *parent, void *drvdata, + const struct attribute_group **groups, + const char *fmt, va_list args) +{ + struct device *dev = NULL; + int retval = -ENODEV; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + retval = -ENOMEM; + goto error; + } + + device_initialize(dev); + dev->parent = parent; + dev->groups = groups; + dev->release = device_create_release; + dev_set_drvdata(dev, drvdata); + + retval = kobject_set_name_vargs(&dev->kobj, fmt, args); + if (retval) + goto error; + + retval = device_add(dev); + if (retval) + goto error; + + return dev; + +error: + put_device(dev); + return ERR_PTR(retval); +} + +struct device *cpu_device_create(struct device *parent, void *drvdata, + const struct attribute_group **groups, + const char *fmt, ...) +{ + va_list vargs; + struct device *dev; + + va_start(vargs, fmt); + dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs); + va_end(vargs); + return dev; +} +EXPORT_SYMBOL_GPL(cpu_device_create); + #ifdef CONFIG_GENERIC_CPU_AUTOPROBE static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); #endif diff --git a/include/linux/cpu.h b/include/linux/cpu.h index b2d9a43012b2..4260e8594bd7 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -19,6 +19,7 @@ struct device; struct device_node; +struct attribute_group; struct cpu { int node_id; /* The node which contains the CPU */ @@ -39,6 +40,9 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); extern int cpu_add_dev_attr_group(struct attribute_group *attrs); extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); +extern struct device *cpu_device_create(struct device *parent, void *drvdata, + const struct attribute_group **groups, + const char *fmt, ...); #ifdef CONFIG_HOTPLUG_CPU extern void unregister_cpu(struct cpu *cpu); extern ssize_t arch_cpu_probe(const char *, size_t); -- GitLab From 246246cbde5e840012f853e27630ebb59f409486 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 30 Sep 2014 14:48:25 +0100 Subject: [PATCH 3954/9457] drivers: base: support cpu cache information interface to userspace via sysfs This patch adds initial support for providing processor cache information to userspace through sysfs interface. This is based on already existing implementations(x86, ia64, s390 and powerpc) and hence the interface is intended to be fully compatible. The main purpose of this generic support is to avoid further code duplication to support new architectures and also to unify all the existing different implementations. This implementation maintains the hierarchy of cache objects which reflects the system's cache topology. Cache devices are instantiated as needed as CPUs come online. The cache information is replicated per-cpu even if they are shared. A per-cpu array of cache information maintained is used mainly for sysfs-related book keeping. It also implements the shared_cpu_map attribute, which is essential for enabling both kernel and user-space to discover the system's overall cache topology. This patch also add the missing ABI documentation for the cacheinfo sysfs interface already, which is well defined and widely used. Signed-off-by: Sudeep Holla Reviewed-by: Stephen Boyd Tested-by: Stephen Boyd Cc: Greg Kroah-Hartman Cc: linux-api@vger.kernel.org Cc: linux390@de.ibm.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-ia64@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-s390@vger.kernel.org Cc: x86@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-devices-system-cpu | 47 ++ drivers/base/Makefile | 2 +- drivers/base/cacheinfo.c | 541 ++++++++++++++++++ include/linux/cacheinfo.h | 100 ++++ 4 files changed, 689 insertions(+), 1 deletion(-) create mode 100644 drivers/base/cacheinfo.c create mode 100644 include/linux/cacheinfo.h diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index acb9bfc89b48..99983e67c13c 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -224,3 +224,50 @@ Description: Parameters for the Intel P-state driver frequency range. More details can be found in Documentation/cpu-freq/intel-pstate.txt + +What: /sys/devices/system/cpu/cpu*/cache/index*/ +Date: July 2014(documented, existed before August 2008) +Contact: Sudeep Holla + Linux kernel mailing list +Description: Parameters for the CPU cache attributes + + allocation_policy: + - WriteAllocate: allocate a memory location to a cache line + on a cache miss because of a write + - ReadAllocate: allocate a memory location to a cache line + on a cache miss because of a read + - ReadWriteAllocate: both writeallocate and readallocate + + attributes: LEGACY used only on IA64 and is same as write_policy + + coherency_line_size: the minimum amount of data in bytes that gets + transferred from memory to cache + + level: the cache hierarcy in the multi-level cache configuration + + number_of_sets: total number of sets in the cache, a set is a + collection of cache lines with the same cache index + + physical_line_partition: number of physical cache line per cache tag + + shared_cpu_list: the list of logical cpus sharing the cache + + shared_cpu_map: logical cpu mask containing the list of cpus sharing + the cache + + size: the total cache size in kB + + type: + - Instruction: cache that only holds instructions + - Data: cache that only caches data + - Unified: cache that holds both data and instructions + + ways_of_associativity: degree of freedom in placing a particular block + of memory in the cache + + write_policy: + - WriteThrough: data is written to both the cache line + and to the block in the lower-level memory + - WriteBack: data is written only to the cache line and + the modified cache line is written to main + memory only when it is replaced diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 6922cd6850a2..e81a55ca513c 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o \ - topology.o container.o + topology.o container.o cacheinfo.o obj-$(CONFIG_DEVTMPFS) += devtmpfs.o obj-$(CONFIG_DMA_CMA) += dma-contiguous.o obj-y += power/ diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c new file mode 100644 index 000000000000..8ed4ea1f3716 --- /dev/null +++ b/drivers/base/cacheinfo.c @@ -0,0 +1,541 @@ +/* + * cacheinfo support - processor cache information via sysfs + * + * Based on arch/x86/kernel/cpu/intel_cacheinfo.c + * Author: Sudeep Holla + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* pointer to per cpu cacheinfo */ +static DEFINE_PER_CPU(struct cpu_cacheinfo, ci_cpu_cacheinfo); +#define ci_cacheinfo(cpu) (&per_cpu(ci_cpu_cacheinfo, cpu)) +#define cache_leaves(cpu) (ci_cacheinfo(cpu)->num_leaves) +#define per_cpu_cacheinfo(cpu) (ci_cacheinfo(cpu)->info_list) + +struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu) +{ + return ci_cacheinfo(cpu); +} + +#ifdef CONFIG_OF +static int cache_setup_of_node(unsigned int cpu) +{ + struct device_node *np; + struct cacheinfo *this_leaf; + struct device *cpu_dev = get_cpu_device(cpu); + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + unsigned int index = 0; + + /* skip if of_node is already populated */ + if (this_cpu_ci->info_list->of_node) + return 0; + + if (!cpu_dev) { + pr_err("No cpu device for CPU %d\n", cpu); + return -ENODEV; + } + np = cpu_dev->of_node; + if (!np) { + pr_err("Failed to find cpu%d device node\n", cpu); + return -ENOENT; + } + + while (np && index < cache_leaves(cpu)) { + this_leaf = this_cpu_ci->info_list + index; + if (this_leaf->level != 1) + np = of_find_next_cache_node(np); + else + np = of_node_get(np);/* cpu node itself */ + this_leaf->of_node = np; + index++; + } + return 0; +} + +static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, + struct cacheinfo *sib_leaf) +{ + return sib_leaf->of_node == this_leaf->of_node; +} +#else +static inline int cache_setup_of_node(unsigned int cpu) { return 0; } +static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, + struct cacheinfo *sib_leaf) +{ + /* + * For non-DT systems, assume unique level 1 cache, system-wide + * shared caches for all other levels. This will be used only if + * arch specific code has not populated shared_cpu_map + */ + return !(this_leaf->level == 1); +} +#endif + +static int cache_shared_cpu_map_setup(unsigned int cpu) +{ + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cacheinfo *this_leaf, *sib_leaf; + unsigned int index; + int ret; + + ret = cache_setup_of_node(cpu); + if (ret) + return ret; + + for (index = 0; index < cache_leaves(cpu); index++) { + unsigned int i; + + this_leaf = this_cpu_ci->info_list + index; + /* skip if shared_cpu_map is already populated */ + if (!cpumask_empty(&this_leaf->shared_cpu_map)) + continue; + + cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); + for_each_online_cpu(i) { + struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); + + if (i == cpu || !sib_cpu_ci->info_list) + continue;/* skip if itself or no cacheinfo */ + sib_leaf = sib_cpu_ci->info_list + index; + if (cache_leaves_are_shared(this_leaf, sib_leaf)) { + cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map); + cpumask_set_cpu(i, &this_leaf->shared_cpu_map); + } + } + } + + return 0; +} + +static void cache_shared_cpu_map_remove(unsigned int cpu) +{ + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + struct cacheinfo *this_leaf, *sib_leaf; + unsigned int sibling, index; + + for (index = 0; index < cache_leaves(cpu); index++) { + this_leaf = this_cpu_ci->info_list + index; + for_each_cpu(sibling, &this_leaf->shared_cpu_map) { + struct cpu_cacheinfo *sib_cpu_ci; + + if (sibling == cpu) /* skip itself */ + continue; + sib_cpu_ci = get_cpu_cacheinfo(sibling); + sib_leaf = sib_cpu_ci->info_list + index; + cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); + cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); + } + of_node_put(this_leaf->of_node); + } +} + +static void free_cache_attributes(unsigned int cpu) +{ + cache_shared_cpu_map_remove(cpu); + + kfree(per_cpu_cacheinfo(cpu)); + per_cpu_cacheinfo(cpu) = NULL; +} + +int __weak init_cache_level(unsigned int cpu) +{ + return -ENOENT; +} + +int __weak populate_cache_leaves(unsigned int cpu) +{ + return -ENOENT; +} + +static int detect_cache_attributes(unsigned int cpu) +{ + int ret; + + if (init_cache_level(cpu)) + return -ENOENT; + + per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), + sizeof(struct cacheinfo), GFP_KERNEL); + if (per_cpu_cacheinfo(cpu) == NULL) + return -ENOMEM; + + ret = populate_cache_leaves(cpu); + if (ret) + goto free_ci; + /* + * For systems using DT for cache hierarcy, of_node and shared_cpu_map + * will be set up here only if they are not populated already + */ + ret = cache_shared_cpu_map_setup(cpu); + if (ret) + goto free_ci; + return 0; + +free_ci: + free_cache_attributes(cpu); + return ret; +} + +/* pointer to cpuX/cache device */ +static DEFINE_PER_CPU(struct device *, ci_cache_dev); +#define per_cpu_cache_dev(cpu) (per_cpu(ci_cache_dev, cpu)) + +static cpumask_t cache_dev_map; + +/* pointer to array of devices for cpuX/cache/indexY */ +static DEFINE_PER_CPU(struct device **, ci_index_dev); +#define per_cpu_index_dev(cpu) (per_cpu(ci_index_dev, cpu)) +#define per_cache_index_dev(cpu, idx) ((per_cpu_index_dev(cpu))[idx]) + +#define show_one(file_name, object) \ +static ssize_t file_name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ + return sprintf(buf, "%u\n", this_leaf->object); \ +} + +show_one(level, level); +show_one(coherency_line_size, coherency_line_size); +show_one(number_of_sets, number_of_sets); +show_one(physical_line_partition, physical_line_partition); +show_one(ways_of_associativity, ways_of_associativity); + +static ssize_t size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + + return sprintf(buf, "%uK\n", this_leaf->size >> 10); +} + +static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) +{ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + const struct cpumask *mask = &this_leaf->shared_cpu_map; + + return cpumap_print_to_pagebuf(list, buf, mask); +} + +static ssize_t shared_cpu_map_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return shared_cpumap_show_func(dev, false, buf); +} + +static ssize_t shared_cpu_list_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return shared_cpumap_show_func(dev, true, buf); +} + +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + + switch (this_leaf->type) { + case CACHE_TYPE_DATA: + return sprintf(buf, "Data\n"); + case CACHE_TYPE_INST: + return sprintf(buf, "Instruction\n"); + case CACHE_TYPE_UNIFIED: + return sprintf(buf, "Unified\n"); + default: + return -EINVAL; + } +} + +static ssize_t allocation_policy_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + unsigned int ci_attr = this_leaf->attributes; + int n = 0; + + if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE)) + n = sprintf(buf, "ReadWriteAllocate\n"); + else if (ci_attr & CACHE_READ_ALLOCATE) + n = sprintf(buf, "ReadAllocate\n"); + else if (ci_attr & CACHE_WRITE_ALLOCATE) + n = sprintf(buf, "WriteAllocate\n"); + return n; +} + +static ssize_t write_policy_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + unsigned int ci_attr = this_leaf->attributes; + int n = 0; + + if (ci_attr & CACHE_WRITE_THROUGH) + n = sprintf(buf, "WriteThrough\n"); + else if (ci_attr & CACHE_WRITE_BACK) + n = sprintf(buf, "WriteBack\n"); + return n; +} + +static DEVICE_ATTR_RO(level); +static DEVICE_ATTR_RO(type); +static DEVICE_ATTR_RO(coherency_line_size); +static DEVICE_ATTR_RO(ways_of_associativity); +static DEVICE_ATTR_RO(number_of_sets); +static DEVICE_ATTR_RO(size); +static DEVICE_ATTR_RO(allocation_policy); +static DEVICE_ATTR_RO(write_policy); +static DEVICE_ATTR_RO(shared_cpu_map); +static DEVICE_ATTR_RO(shared_cpu_list); +static DEVICE_ATTR_RO(physical_line_partition); + +static struct attribute *cache_default_attrs[] = { + &dev_attr_type.attr, + &dev_attr_level.attr, + &dev_attr_shared_cpu_map.attr, + &dev_attr_shared_cpu_list.attr, + &dev_attr_coherency_line_size.attr, + &dev_attr_ways_of_associativity.attr, + &dev_attr_number_of_sets.attr, + &dev_attr_size.attr, + &dev_attr_allocation_policy.attr, + &dev_attr_write_policy.attr, + &dev_attr_physical_line_partition.attr, + NULL +}; + +static umode_t +cache_default_attrs_is_visible(struct kobject *kobj, + struct attribute *attr, int unused) +{ + struct device *dev = kobj_to_dev(kobj); + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + const struct cpumask *mask = &this_leaf->shared_cpu_map; + umode_t mode = attr->mode; + + if ((attr == &dev_attr_type.attr) && this_leaf->type) + return mode; + if ((attr == &dev_attr_level.attr) && this_leaf->level) + return mode; + if ((attr == &dev_attr_shared_cpu_map.attr) && !cpumask_empty(mask)) + return mode; + if ((attr == &dev_attr_shared_cpu_list.attr) && !cpumask_empty(mask)) + return mode; + if ((attr == &dev_attr_coherency_line_size.attr) && + this_leaf->coherency_line_size) + return mode; + if ((attr == &dev_attr_ways_of_associativity.attr) && + this_leaf->size) /* allow 0 = full associativity */ + return mode; + if ((attr == &dev_attr_number_of_sets.attr) && + this_leaf->number_of_sets) + return mode; + if ((attr == &dev_attr_size.attr) && this_leaf->size) + return mode; + if ((attr == &dev_attr_write_policy.attr) && + (this_leaf->attributes & CACHE_WRITE_POLICY_MASK)) + return mode; + if ((attr == &dev_attr_allocation_policy.attr) && + (this_leaf->attributes & CACHE_ALLOCATE_POLICY_MASK)) + return mode; + if ((attr == &dev_attr_physical_line_partition.attr) && + this_leaf->physical_line_partition) + return mode; + + return 0; +} + +static const struct attribute_group cache_default_group = { + .attrs = cache_default_attrs, + .is_visible = cache_default_attrs_is_visible, +}; + +static const struct attribute_group *cache_default_groups[] = { + &cache_default_group, + NULL, +}; + +static const struct attribute_group *cache_private_groups[] = { + &cache_default_group, + NULL, /* Place holder for private group */ + NULL, +}; + +const struct attribute_group * +__weak cache_get_priv_group(struct cacheinfo *this_leaf) +{ + return NULL; +} + +static const struct attribute_group ** +cache_get_attribute_groups(struct cacheinfo *this_leaf) +{ + const struct attribute_group *priv_group = + cache_get_priv_group(this_leaf); + + if (!priv_group) + return cache_default_groups; + + if (!cache_private_groups[1]) + cache_private_groups[1] = priv_group; + + return cache_private_groups; +} + +/* Add/Remove cache interface for CPU device */ +static void cpu_cache_sysfs_exit(unsigned int cpu) +{ + int i; + struct device *ci_dev; + + if (per_cpu_index_dev(cpu)) { + for (i = 0; i < cache_leaves(cpu); i++) { + ci_dev = per_cache_index_dev(cpu, i); + if (!ci_dev) + continue; + device_unregister(ci_dev); + } + kfree(per_cpu_index_dev(cpu)); + per_cpu_index_dev(cpu) = NULL; + } + device_unregister(per_cpu_cache_dev(cpu)); + per_cpu_cache_dev(cpu) = NULL; +} + +static int cpu_cache_sysfs_init(unsigned int cpu) +{ + struct device *dev = get_cpu_device(cpu); + + if (per_cpu_cacheinfo(cpu) == NULL) + return -ENOENT; + + per_cpu_cache_dev(cpu) = cpu_device_create(dev, NULL, NULL, "cache"); + if (IS_ERR(per_cpu_cache_dev(cpu))) + return PTR_ERR(per_cpu_cache_dev(cpu)); + + /* Allocate all required memory */ + per_cpu_index_dev(cpu) = kcalloc(cache_leaves(cpu), + sizeof(struct device *), GFP_KERNEL); + if (unlikely(per_cpu_index_dev(cpu) == NULL)) + goto err_out; + + return 0; + +err_out: + cpu_cache_sysfs_exit(cpu); + return -ENOMEM; +} + +static int cache_add_dev(unsigned int cpu) +{ + unsigned int i; + int rc; + struct device *ci_dev, *parent; + struct cacheinfo *this_leaf; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + const struct attribute_group **cache_groups; + + rc = cpu_cache_sysfs_init(cpu); + if (unlikely(rc < 0)) + return rc; + + parent = per_cpu_cache_dev(cpu); + for (i = 0; i < cache_leaves(cpu); i++) { + this_leaf = this_cpu_ci->info_list + i; + if (this_leaf->disable_sysfs) + continue; + cache_groups = cache_get_attribute_groups(this_leaf); + ci_dev = cpu_device_create(parent, this_leaf, cache_groups, + "index%1u", i); + if (IS_ERR(ci_dev)) { + rc = PTR_ERR(ci_dev); + goto err; + } + per_cache_index_dev(cpu, i) = ci_dev; + } + cpumask_set_cpu(cpu, &cache_dev_map); + + return 0; +err: + cpu_cache_sysfs_exit(cpu); + return rc; +} + +static void cache_remove_dev(unsigned int cpu) +{ + if (!cpumask_test_cpu(cpu, &cache_dev_map)) + return; + cpumask_clear_cpu(cpu, &cache_dev_map); + + cpu_cache_sysfs_exit(cpu); +} + +static int cacheinfo_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + int rc = 0; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_ONLINE: + rc = detect_cache_attributes(cpu); + if (!rc) + rc = cache_add_dev(cpu); + break; + case CPU_DEAD: + cache_remove_dev(cpu); + if (per_cpu_cacheinfo(cpu)) + free_cache_attributes(cpu); + break; + } + return notifier_from_errno(rc); +} + +static int __init cacheinfo_sysfs_init(void) +{ + int cpu, rc = 0; + + cpu_notifier_register_begin(); + + for_each_online_cpu(cpu) { + rc = detect_cache_attributes(cpu); + if (rc) { + pr_err("error detecting cacheinfo..cpu%d\n", cpu); + goto out; + } + rc = cache_add_dev(cpu); + if (rc) { + free_cache_attributes(cpu); + pr_err("error populating cacheinfo..cpu%d\n", cpu); + goto out; + } + } + __hotcpu_notifier(cacheinfo_cpu_callback, 0); + +out: + cpu_notifier_register_done(); + return rc; +} + +device_initcall(cacheinfo_sysfs_init); diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h new file mode 100644 index 000000000000..3daf5ed392c9 --- /dev/null +++ b/include/linux/cacheinfo.h @@ -0,0 +1,100 @@ +#ifndef _LINUX_CACHEINFO_H +#define _LINUX_CACHEINFO_H + +#include +#include +#include + +struct device_node; +struct attribute; + +enum cache_type { + CACHE_TYPE_NOCACHE = 0, + CACHE_TYPE_INST = BIT(0), + CACHE_TYPE_DATA = BIT(1), + CACHE_TYPE_SEPARATE = CACHE_TYPE_INST | CACHE_TYPE_DATA, + CACHE_TYPE_UNIFIED = BIT(2), +}; + +/** + * struct cacheinfo - represent a cache leaf node + * @type: type of the cache - data, inst or unified + * @level: represents the hierarcy in the multi-level cache + * @coherency_line_size: size of each cache line usually representing + * the minimum amount of data that gets transferred from memory + * @number_of_sets: total number of sets, a set is a collection of cache + * lines sharing the same index + * @ways_of_associativity: number of ways in which a particular memory + * block can be placed in the cache + * @physical_line_partition: number of physical cache lines sharing the + * same cachetag + * @size: Total size of the cache + * @shared_cpu_map: logical cpumask representing all the cpus sharing + * this cache node + * @attributes: bitfield representing various cache attributes + * @of_node: if devicetree is used, this represents either the cpu node in + * case there's no explicit cache node or the cache node itself in the + * device tree + * @disable_sysfs: indicates whether this node is visible to the user via + * sysfs or not + * @priv: pointer to any private data structure specific to particular + * cache design + * + * While @of_node, @disable_sysfs and @priv are used for internal book + * keeping, the remaining members form the core properties of the cache + */ +struct cacheinfo { + enum cache_type type; + unsigned int level; + unsigned int coherency_line_size; + unsigned int number_of_sets; + unsigned int ways_of_associativity; + unsigned int physical_line_partition; + unsigned int size; + cpumask_t shared_cpu_map; + unsigned int attributes; +#define CACHE_WRITE_THROUGH BIT(0) +#define CACHE_WRITE_BACK BIT(1) +#define CACHE_WRITE_POLICY_MASK \ + (CACHE_WRITE_THROUGH | CACHE_WRITE_BACK) +#define CACHE_READ_ALLOCATE BIT(2) +#define CACHE_WRITE_ALLOCATE BIT(3) +#define CACHE_ALLOCATE_POLICY_MASK \ + (CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE) + + struct device_node *of_node; + bool disable_sysfs; + void *priv; +}; + +struct cpu_cacheinfo { + struct cacheinfo *info_list; + unsigned int num_levels; + unsigned int num_leaves; +}; + +/* + * Helpers to make sure "func" is executed on the cpu whose cache + * attributes are being detected + */ +#define DEFINE_SMP_CALL_CACHE_FUNCTION(func) \ +static inline void _##func(void *ret) \ +{ \ + int cpu = smp_processor_id(); \ + *(int *)ret = __##func(cpu); \ +} \ + \ +int func(unsigned int cpu) \ +{ \ + int ret; \ + smp_call_function_single(cpu, _##func, &ret, true); \ + return ret; \ +} + +struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); +int init_cache_level(unsigned int cpu); +int populate_cache_leaves(unsigned int cpu); + +const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf); + +#endif /* _LINUX_CACHEINFO_H */ -- GitLab From df32dd2054b6edcbdfd3a31aec24e7fd0edba2ac Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 3 Nov 2014 12:42:34 -0800 Subject: [PATCH 3955/9457] uapi: resort Kbuild entries The entries in the Kbuild files are incorrectly sorted. Matters for aesthetics only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/uapi/linux/Kbuild | 88 +++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 4c94f31a8c99..72298b6887ac 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -37,27 +37,27 @@ header-y += aio_abi.h header-y += apm_bios.h header-y += arcfb.h header-y += atalk.h -header-y += atm.h -header-y += atm_eni.h -header-y += atm_he.h -header-y += atm_idt77105.h -header-y += atm_nicstar.h -header-y += atm_tcp.h -header-y += atm_zatm.h header-y += atmapi.h header-y += atmarp.h header-y += atmbr2684.h header-y += atmclip.h header-y += atmdev.h +header-y += atm_eni.h +header-y += atm.h +header-y += atm_he.h +header-y += atm_idt77105.h header-y += atmioc.h header-y += atmlec.h header-y += atmmpc.h +header-y += atm_nicstar.h header-y += atmppp.h header-y += atmsap.h header-y += atmsvc.h +header-y += atm_tcp.h +header-y += atm_zatm.h header-y += audit.h -header-y += auto_fs.h header-y += auto_fs4.h +header-y += auto_fs.h header-y += auxvec.h header-y += ax25.h header-y += b1lli.h @@ -67,8 +67,8 @@ header-y += bfs_fs.h header-y += binfmts.h header-y += blkpg.h header-y += blktrace_api.h -header-y += bpf.h header-y += bpf_common.h +header-y += bpf.h header-y += bpqether.h header-y += bsg.h header-y += btrfs.h @@ -93,21 +93,21 @@ header-y += cyclades.h header-y += cycx_cfm.h header-y += dcbnl.h header-y += dccp.h -header-y += dlm.h +header-y += dlmconstants.h header-y += dlm_device.h +header-y += dlm.h header-y += dlm_netlink.h header-y += dlm_plock.h -header-y += dlmconstants.h header-y += dm-ioctl.h header-y += dm-log-userspace.h header-y += dn.h header-y += dqblk_xfs.h header-y += edd.h header-y += efs_fs_sb.h +header-y += elfcore.h header-y += elf-em.h header-y += elf-fdpic.h header-y += elf.h -header-y += elfcore.h header-y += errno.h header-y += errqueue.h header-y += ethtool.h @@ -131,15 +131,15 @@ header-y += fsl_hypervisor.h header-y += fuse.h header-y += futex.h header-y += gameport.h -header-y += gen_stats.h header-y += genetlink.h +header-y += gen_stats.h header-y += gfs2_ondisk.h header-y += gigaset_dev.h -header-y += hdlc.h header-y += hdlcdrv.h +header-y += hdlc.h header-y += hdreg.h -header-y += hid.h header-y += hiddev.h +header-y += hid.h header-y += hidraw.h header-y += hpet.h header-y += hsr_netlink.h @@ -151,7 +151,6 @@ header-y += i2o-dev.h header-y += i8k.h header-y += icmp.h header-y += icmpv6.h -header-y += if.h header-y += if_addr.h header-y += if_addrlabel.h header-y += if_alg.h @@ -165,6 +164,7 @@ header-y += if_ether.h header-y += if_fc.h header-y += if_fddi.h header-y += if_frad.h +header-y += if.h header-y += if_hippi.h header-y += if_infiniband.h header-y += if_link.h @@ -182,40 +182,40 @@ header-y += if_tunnel.h header-y += if_vlan.h header-y += if_x25.h header-y += igmp.h -header-y += in.h header-y += in6.h -header-y += in_route.h header-y += inet_diag.h +header-y += in.h header-y += inotify.h header-y += input.h +header-y += in_route.h header-y += ioctl.h -header-y += ip.h header-y += ip6_tunnel.h -header-y += ip_vs.h header-y += ipc.h +header-y += ip.h header-y += ipmi.h header-y += ipmi_msgdefs.h header-y += ipsec.h header-y += ipv6.h header-y += ipv6_route.h +header-y += ip_vs.h header-y += ipx.h header-y += irda.h header-y += irqnr.h -header-y += isdn.h header-y += isdn_divertif.h -header-y += isdn_ppp.h +header-y += isdn.h header-y += isdnif.h +header-y += isdn_ppp.h header-y += iso_fs.h -header-y += ivtv.h header-y += ivtvfb.h +header-y += ivtv.h header-y += ixjuser.h header-y += jffs2.h header-y += joystick.h -header-y += kd.h header-y += kdev_t.h -header-y += kernel-page-flags.h -header-y += kernel.h +header-y += kd.h header-y += kernelcapi.h +header-y += kernel.h +header-y += kernel-page-flags.h header-y += kexec.h header-y += keyboard.h header-y += keyctl.h @@ -231,6 +231,7 @@ ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm_para.h \ header-y += kvm_para.h endif +header-y += hw_breakpoint.h header-y += l2tp.h header-y += libc-compat.h header-y += limits.h @@ -255,43 +256,43 @@ header-y += mman.h header-y += mmtimer.h header-y += mpls.h header-y += mqueue.h -header-y += mroute.h header-y += mroute6.h +header-y += mroute.h header-y += msdos_fs.h header-y += msg.h header-y += mtio.h -header-y += n_r3964.h header-y += nbd.h -header-y += ncp.h header-y += ncp_fs.h +header-y += ncp.h header-y += ncp_mount.h header-y += ncp_no.h header-y += neighbour.h -header-y += net.h -header-y += net_dropmon.h -header-y += net_tstamp.h header-y += netconf.h header-y += netdevice.h -header-y += netlink_diag.h -header-y += netfilter.h +header-y += net_dropmon.h header-y += netfilter_arp.h header-y += netfilter_bridge.h header-y += netfilter_decnet.h +header-y += netfilter.h header-y += netfilter_ipv4.h header-y += netfilter_ipv6.h +header-y += net.h +header-y += netlink_diag.h header-y += netlink.h header-y += netrom.h +header-y += net_tstamp.h header-y += nfc.h -header-y += nfs.h header-y += nfs2.h header-y += nfs3.h header-y += nfs4.h header-y += nfs4_mount.h +header-y += nfsacl.h header-y += nfs_fs.h +header-y += nfs.h header-y += nfs_idmap.h header-y += nfs_mount.h -header-y += nfsacl.h header-y += nl80211.h +header-y += n_r3964.h header-y += nubus.h header-y += nvme.h header-y += nvram.h @@ -311,16 +312,16 @@ header-y += pfkeyv2.h header-y += pg.h header-y += phantom.h header-y += phonet.h +header-y += pktcdvd.h header-y += pkt_cls.h header-y += pkt_sched.h -header-y += pktcdvd.h header-y += pmu.h header-y += poll.h header-y += posix_types.h header-y += ppdev.h header-y += ppp-comp.h -header-y += ppp-ioctl.h header-y += ppp_defs.h +header-y += ppp-ioctl.h header-y += pps.h header-y += prctl.h header-y += psci.h @@ -352,13 +353,13 @@ header-y += seccomp.h header-y += securebits.h header-y += selinux_netlink.h header-y += sem.h -header-y += serial.h header-y += serial_core.h +header-y += serial.h header-y += serial_reg.h header-y += serio.h header-y += shm.h -header-y += signal.h header-y += signalfd.h +header-y += signal.h header-y += smiapp.h header-y += snmp.h header-y += sock_diag.h @@ -367,8 +368,8 @@ header-y += sockios.h header-y += som.h header-y += sonet.h header-y += sonypi.h -header-y += sound.h header-y += soundcard.h +header-y += sound.h header-y += stat.h header-y += stddef.h header-y += string.h @@ -387,11 +388,11 @@ header-y += time.h header-y += times.h header-y += timex.h header-y += tiocl.h -header-y += tipc.h header-y += tipc_config.h +header-y += tipc.h header-y += toshiba.h -header-y += tty.h header-y += tty_flags.h +header-y += tty.h header-y += types.h header-y += udf_fs_i.h header-y += udp.h @@ -437,6 +438,5 @@ header-y += wireless.h header-y += x25.h header-y += xattr.h header-y += xfrm.h -header-y += hw_breakpoint.h header-y += zorro.h header-y += zorro_ids.h -- GitLab From f46ad73ac6965f71d1a2ba217c4eb5b644e62949 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 6 Nov 2014 15:19:14 +0100 Subject: [PATCH 3956/9457] cdc-ether: implement MULTICAST flag on the device Olivier having laid the groundwork this patch transmits the multicast flag to the device to save some bus traffic. Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index d3920b54a92c..9311a08565be 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -71,18 +71,19 @@ static void usbnet_cdc_update_filter(struct usbnet *dev) { struct cdc_state *info = (void *) &dev->data; struct usb_interface *intf = info->control; + struct net_device *net = dev->net; - u16 cdc_filter = - USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | - USB_CDC_PACKET_TYPE_BROADCAST; + u16 cdc_filter = USB_CDC_PACKET_TYPE_DIRECTED + | USB_CDC_PACKET_TYPE_BROADCAST; - if (dev->net->flags & IFF_PROMISC) - cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS; - - /* FIXME cdc-ether has some multicast code too, though it complains - * in routine cases. info->ether describes the multicast support. - * Implement that here, manipulating the cdc filter as needed. + /* filtering on the device is an optional feature and not worth + * the hassle so we just roughly care about snooping and if any + * multicast is requested, we take every multicast */ + if (net->flags & IFF_PROMISC) + cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS; + if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) + cdc_filter |= USB_CDC_PACKET_TYPE_ALL_MULTICAST; usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), -- GitLab From 36cbb2452cbafca64dcdd3578047433787900cf0 Mon Sep 17 00:00:00 2001 From: Rick Jones Date: Thu, 6 Nov 2014 10:37:54 -0800 Subject: [PATCH 3957/9457] udp: Increment UDP_MIB_IGNOREDMULTI for arriving unmatched multicasts As NIC multicast filtering isn't perfect, and some platforms are quite content to spew broadcasts, we should not trigger an event for skb:kfree_skb when we do not have a match for such an incoming datagram. We do though want to avoid sweeping the matter under the rug entirely, so increment a suitable statistic. This incorporates feedback from David L. Stevens, Karl Neiss and Eric Dumazet. V3 - use bool per David Miller Signed-off-by: Rick Jones Signed-off-by: David S. Miller --- include/uapi/linux/snmp.h | 1 + net/ipv4/proc.c | 1 + net/ipv4/udp.c | 12 +++++++++--- net/ipv6/proc.c | 1 + net/ipv6/udp.c | 11 ++++++++--- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h index df40137f33dd..30f541b32895 100644 --- a/include/uapi/linux/snmp.h +++ b/include/uapi/linux/snmp.h @@ -156,6 +156,7 @@ enum UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */ UDP_MIB_SNDBUFERRORS, /* SndbufErrors */ UDP_MIB_CSUMERRORS, /* InCsumErrors */ + UDP_MIB_IGNOREDMULTI, /* IgnoredMulti */ __UDP_MIB_MAX }; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index f0d4eb8b99b9..6513ade8d6dc 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -181,6 +181,7 @@ static const struct snmp_mib snmp4_udp_list[] = { SNMP_MIB_ITEM("RcvbufErrors", UDP_MIB_RCVBUFERRORS), SNMP_MIB_ITEM("SndbufErrors", UDP_MIB_SNDBUFERRORS), SNMP_MIB_ITEM("InCsumErrors", UDP_MIB_CSUMERRORS), + SNMP_MIB_ITEM("IgnoredMulti", UDP_MIB_IGNOREDMULTI), SNMP_MIB_SENTINEL }; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index df19027f44f3..5d0fdca8e965 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1647,7 +1647,8 @@ static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, struct udphdr *uh, __be32 saddr, __be32 daddr, - struct udp_table *udptable) + struct udp_table *udptable, + int proto) { struct sock *sk, *stack[256 / sizeof(struct sock *)]; struct hlist_nulls_node *node; @@ -1656,6 +1657,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, int dif = skb->dev->ifindex; unsigned int count = 0, offset = offsetof(typeof(*sk), sk_nulls_node); unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10); + bool inner_flushed = false; if (use_hash2) { hash2_any = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum) & @@ -1674,6 +1676,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, dif, hnum)) { if (unlikely(count == ARRAY_SIZE(stack))) { flush_stack(stack, count, skb, ~0); + inner_flushed = true; count = 0; } stack[count++] = sk; @@ -1695,7 +1698,10 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, if (count) { flush_stack(stack, count, skb, count - 1); } else { - kfree_skb(skb); + if (!inner_flushed) + UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, + proto == IPPROTO_UDPLITE); + consume_skb(skb); } return 0; } @@ -1781,7 +1787,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) return __udp4_lib_mcast_deliver(net, skb, uh, - saddr, daddr, udptable); + saddr, daddr, udptable, proto); sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); if (sk != NULL) { diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 1752cd0b4882..679253d0af84 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -136,6 +136,7 @@ static const struct snmp_mib snmp6_udp6_list[] = { SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS), SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS), SNMP_MIB_ITEM("Udp6InCsumErrors", UDP_MIB_CSUMERRORS), + SNMP_MIB_ITEM("Udp6IgnoredMulti", UDP_MIB_IGNOREDMULTI), SNMP_MIB_SENTINEL }; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 9b6809232b17..b756355e9739 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -771,7 +771,7 @@ static void udp6_csum_zero_error(struct sk_buff *skb) */ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, const struct in6_addr *saddr, const struct in6_addr *daddr, - struct udp_table *udptable) + struct udp_table *udptable, int proto) { struct sock *sk, *stack[256 / sizeof(struct sock *)]; const struct udphdr *uh = udp_hdr(skb); @@ -781,6 +781,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, int dif = inet6_iif(skb); unsigned int count = 0, offset = offsetof(typeof(*sk), sk_nulls_node); unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10); + bool inner_flushed = false; if (use_hash2) { hash2_any = udp6_portaddr_hash(net, &in6addr_any, hnum) & @@ -803,6 +804,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, (uh->check || udp_sk(sk)->no_check6_rx)) { if (unlikely(count == ARRAY_SIZE(stack))) { flush_stack(stack, count, skb, ~0); + inner_flushed = true; count = 0; } stack[count++] = sk; @@ -821,7 +823,10 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, if (count) { flush_stack(stack, count, skb, count - 1); } else { - kfree_skb(skb); + if (!inner_flushed) + UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, + proto == IPPROTO_UDPLITE); + consume_skb(skb); } return 0; } @@ -873,7 +878,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, */ if (ipv6_addr_is_multicast(daddr)) return __udp6_lib_mcast_deliver(net, skb, - saddr, daddr, udptable); + saddr, daddr, udptable, proto); /* Unicast */ -- GitLab From 72c72bdf7bf53353d2d8e055194d27f0128be92b Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 7 Nov 2014 14:44:25 -0500 Subject: [PATCH 3958/9457] VFS: Rename do_fallocate() to vfs_fallocate() This function needs to be exported so it can be used by the NFSD module when responding to the new ALLOCATE and DEALLOCATE operations in NFS v4.2. Christoph Hellwig suggested renaming the function to stay consistent with how other vfs functions are named. Signed-off-by: Anna Schumaker Signed-off-by: J. Bruce Fields --- drivers/staging/android/ashmem.c | 2 +- fs/ioctl.c | 2 +- fs/open.c | 5 +++-- include/linux/fs.h | 2 +- mm/madvise.c | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index ad4f5790a76f..27eecfe1c410 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -446,7 +446,7 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) loff_t start = range->pgstart * PAGE_SIZE; loff_t end = (range->pgend + 1) * PAGE_SIZE; - do_fallocate(range->asma->file, + vfs_fallocate(range->asma->file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, end - start); range->purged = ASHMEM_WAS_PURGED; diff --git a/fs/ioctl.c b/fs/ioctl.c index 8ac3fad36192..0bd6142183ee 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -443,7 +443,7 @@ int ioctl_preallocate(struct file *filp, void __user *argp) return -EINVAL; } - return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); + return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); } static int file_ioctl(struct file *filp, unsigned int cmd, diff --git a/fs/open.c b/fs/open.c index d6fd3acde134..c94449b2e582 100644 --- a/fs/open.c +++ b/fs/open.c @@ -222,7 +222,7 @@ SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length) #endif /* BITS_PER_LONG == 32 */ -int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) +int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); long ret; @@ -298,6 +298,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) sb_end_write(inode->i_sb); return ret; } +EXPORT_SYMBOL_GPL(vfs_fallocate); SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) { @@ -305,7 +306,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) int error = -EBADF; if (f.file) { - error = do_fallocate(f.file, mode, offset, len); + error = vfs_fallocate(f.file, mode, offset, len); fdput(f); } return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index a957d4366c24..a88718677579 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2032,7 +2032,7 @@ struct filename { extern long vfs_truncate(struct path *, loff_t); extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, struct file *filp); -extern int do_fallocate(struct file *file, int mode, loff_t offset, +extern int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len); extern long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode); diff --git a/mm/madvise.c b/mm/madvise.c index 0938b30da4ab..a271adc93289 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -326,7 +326,7 @@ static long madvise_remove(struct vm_area_struct *vma, */ get_file(f); up_read(¤t->mm->mmap_sem); - error = do_fallocate(f, + error = vfs_fallocate(f, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, end - start); fput(f); -- GitLab From 95d871f03cae6b49de040265cf88cbe2a16b9f05 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 7 Nov 2014 14:44:26 -0500 Subject: [PATCH 3959/9457] nfsd: Add ALLOCATE support The ALLOCATE operation is used to preallocate space in a file. I can do this by using vfs_fallocate() to do the actual preallocation. ALLOCATE only returns a status indicator, so we don't need to write a special encode() function. Signed-off-by: Anna Schumaker Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 36 ++++++++++++++++++++++++++++++++++++ fs/nfsd/nfs4xdr.c | 19 ++++++++++++++++++- fs/nfsd/vfs.c | 21 +++++++++++++++++++++ fs/nfsd/vfs.h | 2 ++ fs/nfsd/xdr4.h | 8 ++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0beb023f25ac..a261f1800922 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1013,6 +1013,36 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } +static __be32 +nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_fallocate *fallocate, int flags) +{ + __be32 status = nfserr_notsupp; + struct file *file; + + status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate, + &fallocate->falloc_stateid, + WR_STATE, &file); + if (status != nfs_ok) { + dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); + return status; + } + + status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file, + fallocate->falloc_offset, + fallocate->falloc_length, + flags); + fput(file); + return status; +} + +static __be32 +nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_fallocate *fallocate) +{ + return nfsd4_fallocate(rqstp, cstate, fallocate, 0); +} + static __be32 nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_seek *seek) @@ -1929,6 +1959,12 @@ static struct nfsd4_operation nfsd4_ops[] = { }, /* NFSv4.2 operations */ + [OP_ALLOCATE] = { + .op_func = (nfsd4op_func)nfsd4_allocate, + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, + .op_name = "OP_ALLOCATE", + .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, + }, [OP_SEEK] = { .op_func = (nfsd4op_func)nfsd4_seek, .op_name = "OP_SEEK", diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index eeea7a90eb87..a60cff86fc28 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1513,6 +1513,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str DECODE_TAIL; } +static __be32 +nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp, + struct nfsd4_fallocate *fallocate) +{ + DECODE_HEAD; + + status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid); + if (status) + return status; + + READ_BUF(16); + p = xdr_decode_hyper(p, &fallocate->falloc_offset); + xdr_decode_hyper(p, &fallocate->falloc_length); + + DECODE_TAIL; +} + static __be32 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) { @@ -1604,7 +1621,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, /* new operations for NFSv4.2 */ - [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d16076bd9a7a..f1999619d516 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, } #endif +__be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct file *file, loff_t offset, loff_t len, + int flags) +{ + __be32 err; + int error; + + if (!S_ISREG(file_inode(file)->i_mode)) + return nfserr_inval; + + err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, NFSD_MAY_WRITE); + if (err) + return err; + + error = vfs_fallocate(file, flags, offset, len); + if (!error) + error = commit_metadata(fhp); + + return nfserrno(error); +} #endif /* defined(CONFIG_NFSD_V4) */ #ifdef CONFIG_NFSD_V3 diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index c2ff3f14e5f6..7ffdb144e486 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *); #ifdef CONFIG_NFSD_V4 __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, struct xdr_netobj *); +__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, + struct file *, loff_t, loff_t, int); #endif /* CONFIG_NFSD_V4 */ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 5720e9457f33..eeaa0d0c4f79 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete { u32 rca_one_fs; }; +struct nfsd4_fallocate { + /* request */ + stateid_t falloc_stateid; + loff_t falloc_offset; + u64 falloc_length; +}; + struct nfsd4_seek { /* request */ stateid_t seek_stateid; @@ -486,6 +493,7 @@ struct nfsd4_op { struct nfsd4_free_stateid free_stateid; /* NFSv4.2 */ + struct nfsd4_fallocate allocate; struct nfsd4_seek seek; } u; struct nfs4_replay * replay; -- GitLab From b0cb9085239a20b7482ddd4839dd1d5476801dfa Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 7 Nov 2014 14:44:27 -0500 Subject: [PATCH 3960/9457] nfsd: Add DEALLOCATE support DEALLOCATE only returns a status value, meaning we can use the noop() xdr encoder to reply to the client. Signed-off-by: Anna Schumaker Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 15 +++++++++++++++ fs/nfsd/nfs4xdr.c | 2 +- fs/nfsd/xdr4.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a261f1800922..74fb15eefc31 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -33,6 +33,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include "idmap.h" @@ -1043,6 +1044,14 @@ nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return nfsd4_fallocate(rqstp, cstate, fallocate, 0); } +static __be32 +nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_fallocate *fallocate) +{ + return nfsd4_fallocate(rqstp, cstate, fallocate, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE); +} + static __be32 nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_seek *seek) @@ -1965,6 +1974,12 @@ static struct nfsd4_operation nfsd4_ops[] = { .op_name = "OP_ALLOCATE", .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, }, + [OP_DEALLOCATE] = { + .op_func = (nfsd4op_func)nfsd4_deallocate, + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, + .op_name = "OP_DEALLOCATE", + .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, + }, [OP_SEEK] = { .op_func = (nfsd4op_func)nfsd4_seek, .op_name = "OP_SEEK", diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index a60cff86fc28..0622d4f4a9a2 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1624,7 +1624,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, - [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index eeaa0d0c4f79..90a5925bd6ab 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -494,6 +494,7 @@ struct nfsd4_op { /* NFSv4.2 */ struct nfsd4_fallocate allocate; + struct nfsd4_fallocate deallocate; struct nfsd4_seek seek; } u; struct nfs4_replay * replay; -- GitLab From 5b095e99928cc13332d364f7cca7a9ca684369b4 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 23 Oct 2014 08:01:02 -0400 Subject: [PATCH 3961/9457] nfsd: convert nfs4_file searches to use RCU The global state_lock protects the file_hashtbl, and that has the potential to be a scalability bottleneck. Address this by making the file_hashtbl use RCU. Add a rcu_head to the nfs4_file and use that when freeing ones that have been hashed. In order to conserve space, we union the fi_rcu field with the fi_delegations list_head which must be clear by the time the last reference to the file is dropped. Convert find_file_locked to use RCU lookup primitives and not to require that the state_lock be held, and convert find_file to do a lockless lookup. Convert find_or_add_file to attempt a lockless lookup first, and then fall back to doing a locked search and insert if that fails to find anything. Also, minimize the number of times we need to calculate the hash value by passing it in as an argument to the search and insert functions, and optimize the order of arguments in nfsd4_init_file. Reviewed-by: Christoph Hellwig Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 51 ++++++++++++++++++++++++++------------------- fs/nfsd/state.h | 5 ++++- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1afd7d4420bd..1379d86f7b4f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -275,9 +275,11 @@ opaque_hashval(const void *ptr, int nbytes) return x; } -static void nfsd4_free_file(struct nfs4_file *f) +static void nfsd4_free_file_rcu(struct rcu_head *rcu) { - kmem_cache_free(file_slab, f); + struct nfs4_file *fp = container_of(rcu, struct nfs4_file, fi_rcu); + + kmem_cache_free(file_slab, fp); } static inline void @@ -286,9 +288,10 @@ put_nfs4_file(struct nfs4_file *fi) might_lock(&state_lock); if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { - hlist_del(&fi->fi_hash); + hlist_del_rcu(&fi->fi_hash); spin_unlock(&state_lock); - nfsd4_free_file(fi); + WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); + call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); } } @@ -3057,10 +3060,9 @@ static struct nfs4_file *nfsd4_alloc_file(void) } /* OPEN Share state helper functions */ -static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh) +static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, + struct nfs4_file *fp) { - unsigned int hashval = file_hashval(fh); - lockdep_assert_held(&state_lock); atomic_set(&fp->fi_ref, 1); @@ -3073,7 +3075,7 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh) fp->fi_share_deny = 0; memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); memset(fp->fi_access, 0, sizeof(fp->fi_access)); - hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]); + hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]); } void @@ -3294,17 +3296,14 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) /* search file_hashtbl[] for file */ static struct nfs4_file * -find_file_locked(struct knfsd_fh *fh) +find_file_locked(struct knfsd_fh *fh, unsigned int hashval) { - unsigned int hashval = file_hashval(fh); struct nfs4_file *fp; - lockdep_assert_held(&state_lock); - - hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) { + hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) { if (nfsd_fh_match(&fp->fi_fhandle, fh)) { - get_nfs4_file(fp); - return fp; + if (atomic_inc_not_zero(&fp->fi_ref)) + return fp; } } return NULL; @@ -3314,10 +3313,11 @@ static struct nfs4_file * find_file(struct knfsd_fh *fh) { struct nfs4_file *fp; + unsigned int hashval = file_hashval(fh); - spin_lock(&state_lock); - fp = find_file_locked(fh); - spin_unlock(&state_lock); + rcu_read_lock(); + fp = find_file_locked(fh, hashval); + rcu_read_unlock(); return fp; } @@ -3325,11 +3325,18 @@ static struct nfs4_file * find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh) { struct nfs4_file *fp; + unsigned int hashval = file_hashval(fh); + + rcu_read_lock(); + fp = find_file_locked(fh, hashval); + rcu_read_unlock(); + if (fp) + return fp; spin_lock(&state_lock); - fp = find_file_locked(fh); - if (fp == NULL) { - nfsd4_init_file(new, fh); + fp = find_file_locked(fh, hashval); + if (likely(fp == NULL)) { + nfsd4_init_file(fh, hashval, new); fp = new; } spin_unlock(&state_lock); @@ -4127,7 +4134,7 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, nfs4_put_stateowner(so); } if (open->op_file) - nfsd4_free_file(open->op_file); + kmem_cache_free(file_slab, open->op_file); if (open->op_stp) nfs4_put_stid(&open->op_stp->st_stid); } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 8e85e07efce6..9d3be371240a 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -477,7 +477,10 @@ struct nfs4_file { spinlock_t fi_lock; struct hlist_node fi_hash; /* hash on fi_fhandle */ struct list_head fi_stateids; - struct list_head fi_delegations; + union { + struct list_head fi_delegations; + struct rcu_head fi_rcu; + }; /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ struct file * fi_fds[3]; /* -- GitLab From d1f931be7cfb5458d90a4642fda8b4da6b266a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Thu, 30 Oct 2014 14:26:13 +0100 Subject: [PATCH 3962/9457] clk: rockchip: fix rk3188 hsadc_frac definition The arguments to COMPOSITE_FRAC for hsadc_frac were mangled, leaving out the the general clock flags argument. This results in strange effects, as only sometimes a zero-division is reported as the wrong register is read. Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 4dfd5e249347..f88eb7dacd97 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -320,9 +320,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), - COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", + COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0, RK2928_CLKSEL_CON(23), 0, - RK2928_CLKGATE_CON(2), 7, 0, GFLAGS), + RK2928_CLKGATE_CON(2), 7, GFLAGS), MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0, RK2928_CLKSEL_CON(22), 4, 2, MFLAGS), -- GitLab From a06ae8609b3dd06b957a6e4e965772a8a14d3af5 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:35 -0700 Subject: [PATCH 3963/9457] coresight: add CoreSight core layer framework CoreSight components are compliant with the ARM CoreSight architecture specification and can be connected in various topologies to suit a particular SoC tracing needs. These trace components can generally be classified as sources, links and sinks. Trace data produced by one or more sources flows through the intermediate links connecting the source to the currently selected sink. The CoreSight framework provides an interface for the CoreSight trace drivers to register themselves with. It's intended to build up a topological view of the CoreSight components and configure the correct serie of components on user input via sysfs. For eg., when enabling a source, the framework builds up a path consisting of all the components connecting the source to the currently selected sink(s) and enables all of them. The framework also supports switching between available sinks and provides status information to user space applications through the debugfs interface. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 + arch/arm/Kconfig.debug | 9 + drivers/Makefile | 1 + drivers/amba/bus.c | 2 +- drivers/coresight/Makefile | 5 + drivers/coresight/coresight-priv.h | 63 +++ drivers/coresight/coresight.c | 717 +++++++++++++++++++++++++++++ drivers/coresight/of_coresight.c | 204 ++++++++ include/linux/amba/bus.h | 1 + include/linux/coresight.h | 263 +++++++++++ 10 files changed, 1272 insertions(+), 1 deletion(-) create mode 100644 drivers/coresight/Makefile create mode 100644 drivers/coresight/coresight-priv.h create mode 100644 drivers/coresight/coresight.c create mode 100644 drivers/coresight/of_coresight.c create mode 100644 include/linux/coresight.h diff --git a/MAINTAINERS b/MAINTAINERS index 3c6427190be2..39952634be8a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -918,6 +918,14 @@ M: Hubert Feurstein S: Maintained F: arch/arm/mach-ep93xx/micro9.c +ARM/CORESIGHT FRAMEWORK AND DRIVERS +M: Mathieu Poirier +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/coresight/* +F: Documentation/trace/coresight.txt +F: Documentation/devicetree/bindings/arm/coresight.txt + ARM/CORGI MACHINE SUPPORT M: Richard Purdie S: Maintained diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 03dc4c1a8736..cd3890e3110e 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1331,4 +1331,13 @@ config DEBUG_SET_MODULE_RONX against certain classes of kernel exploits. If in doubt, say "N". +menuconfig CORESIGHT + bool "CoreSight Tracing Support" + select ARM_AMBA + help + This framework provides a kernel interface for the CoreSight debug + and trace drivers to register themselves with. It's intended to build + a topological view of the CoreSight components based on a DT + specification and configure the right serie of components when a + trace source gets enabled. endmenu diff --git a/drivers/Makefile b/drivers/Makefile index ebee55537a05..628b512b625b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -161,3 +161,4 @@ obj-$(CONFIG_POWERCAP) += powercap/ obj-$(CONFIG_MCB) += mcb/ obj-$(CONFIG_RAS) += ras/ obj-$(CONFIG_THUNDERBOLT) += thunderbolt/ +obj-$(CONFIG_CORESIGHT) += coresight/ diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 47bbdc1b5be3..a4ac490dd784 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -336,7 +336,7 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) amba_put_disable_pclk(dev); - if (cid == AMBA_CID) + if (cid == AMBA_CID || cid == CORESIGHT_CID) dev->periphid = pid; if (!dev->periphid) diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile new file mode 100644 index 000000000000..218e3b589f93 --- /dev/null +++ b/drivers/coresight/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for CoreSight drivers. +# +obj-$(CONFIG_CORESIGHT) += coresight.o +obj-$(CONFIG_OF) += of_coresight.o diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h new file mode 100644 index 000000000000..8d1180c47c0b --- /dev/null +++ b/drivers/coresight/coresight-priv.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CORESIGHT_PRIV_H +#define _CORESIGHT_PRIV_H + +#include +#include +#include + +/* + * Coresight management registers (0xf00-0xfcc) + * 0xfa0 - 0xfa4: Management registers in PFTv1.0 + * Trace registers in PFTv1.1 + */ +#define CORESIGHT_ITCTRL 0xf00 +#define CORESIGHT_CLAIMSET 0xfa0 +#define CORESIGHT_CLAIMCLR 0xfa4 +#define CORESIGHT_LAR 0xfb0 +#define CORESIGHT_LSR 0xfb4 +#define CORESIGHT_AUTHSTATUS 0xfb8 +#define CORESIGHT_DEVID 0xfc8 +#define CORESIGHT_DEVTYPE 0xfcc + +#define TIMEOUT_US 100 +#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) + +static inline void CS_LOCK(void __iomem *addr) +{ + do { + /* Wait for things to settle */ + mb(); + writel_relaxed(0x0, addr + CORESIGHT_LAR); + } while (0); +} + +static inline void CS_UNLOCK(void __iomem *addr) +{ + do { + writel_relaxed(CORESIGHT_UNLOCK, addr + CORESIGHT_LAR); + /* Make sure eveyone has seen this */ + mb(); + } while (0); +} + +#ifdef CONFIG_CORESIGHT_SOURCE_ETM3X +extern int etm_readl_cp14(u32 off, unsigned int *val); +extern int etm_writel_cp14(u32 off, u32 val); +#else +static inline int etm_readl_cp14(u32 off, unsigned int *val) { return 0; } +static inline int etm_writel_cp14(u32 val, u32 off) { return 0; } +#endif + +#endif diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c new file mode 100644 index 000000000000..6e0181f84425 --- /dev/null +++ b/drivers/coresight/coresight.c @@ -0,0 +1,717 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +static DEFINE_MUTEX(coresight_mutex); + +static int coresight_id_match(struct device *dev, void *data) +{ + int trace_id, i_trace_id; + struct coresight_device *csdev, *i_csdev; + + csdev = data; + i_csdev = to_coresight_device(dev); + + /* + * No need to care about oneself and components that are not + * sources or not enabled + */ + if (i_csdev == csdev || !i_csdev->enable || + i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE) + return 0; + + /* Get the source ID for both compoment */ + trace_id = source_ops(csdev)->trace_id(csdev); + i_trace_id = source_ops(i_csdev)->trace_id(i_csdev); + + /* All you need is one */ + if (trace_id == i_trace_id) + return 1; + + return 0; +} + +static int coresight_source_is_unique(struct coresight_device *csdev) +{ + int trace_id = source_ops(csdev)->trace_id(csdev); + + /* this shouldn't happen */ + if (trace_id < 0) + return 0; + + return !bus_for_each_dev(&coresight_bustype, NULL, + csdev, coresight_id_match); +} + +static int coresight_find_link_inport(struct coresight_device *csdev) +{ + int i; + struct coresight_device *parent; + struct coresight_connection *conn; + + parent = container_of(csdev->path_link.next, + struct coresight_device, path_link); + + for (i = 0; i < parent->nr_outport; i++) { + conn = &parent->conns[i]; + if (conn->child_dev == csdev) + return conn->child_port; + } + + dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", + dev_name(&parent->dev), dev_name(&csdev->dev)); + + return 0; +} + +static int coresight_find_link_outport(struct coresight_device *csdev) +{ + int i; + struct coresight_device *child; + struct coresight_connection *conn; + + child = container_of(csdev->path_link.prev, + struct coresight_device, path_link); + + for (i = 0; i < csdev->nr_outport; i++) { + conn = &csdev->conns[i]; + if (conn->child_dev == child) + return conn->outport; + } + + dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", + dev_name(&csdev->dev), dev_name(&child->dev)); + + return 0; +} + +static int coresight_enable_sink(struct coresight_device *csdev) +{ + int ret; + + if (!csdev->enable) { + if (sink_ops(csdev)->enable) { + ret = sink_ops(csdev)->enable(csdev); + if (ret) + return ret; + } + csdev->enable = true; + } + + atomic_inc(csdev->refcnt); + + return 0; +} + +static void coresight_disable_sink(struct coresight_device *csdev) +{ + if (atomic_dec_return(csdev->refcnt) == 0) { + if (sink_ops(csdev)->disable) { + sink_ops(csdev)->disable(csdev); + csdev->enable = false; + } + } +} + +static int coresight_enable_link(struct coresight_device *csdev) +{ + int ret; + int link_subtype; + int refport, inport, outport; + + inport = coresight_find_link_inport(csdev); + outport = coresight_find_link_outport(csdev); + link_subtype = csdev->subtype.link_subtype; + + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) + refport = inport; + else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) + refport = outport; + else + refport = 0; + + if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { + if (link_ops(csdev)->enable) { + ret = link_ops(csdev)->enable(csdev, inport, outport); + if (ret) + return ret; + } + } + + csdev->enable = true; + + return 0; +} + +static void coresight_disable_link(struct coresight_device *csdev) +{ + int i, nr_conns; + int link_subtype; + int refport, inport, outport; + + inport = coresight_find_link_inport(csdev); + outport = coresight_find_link_outport(csdev); + link_subtype = csdev->subtype.link_subtype; + + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { + refport = inport; + nr_conns = csdev->nr_inport; + } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { + refport = outport; + nr_conns = csdev->nr_outport; + } else { + refport = 0; + nr_conns = 1; + } + + if (atomic_dec_return(&csdev->refcnt[refport]) == 0) { + if (link_ops(csdev)->disable) + link_ops(csdev)->disable(csdev, inport, outport); + } + + for (i = 0; i < nr_conns; i++) + if (atomic_read(&csdev->refcnt[i]) != 0) + return; + + csdev->enable = false; +} + +static int coresight_enable_source(struct coresight_device *csdev) +{ + int ret; + + if (!coresight_source_is_unique(csdev)) { + dev_warn(&csdev->dev, "traceID %d not unique\n", + source_ops(csdev)->trace_id(csdev)); + return -EINVAL; + } + + if (!csdev->enable) { + if (source_ops(csdev)->enable) { + ret = source_ops(csdev)->enable(csdev); + if (ret) + return ret; + } + csdev->enable = true; + } + + atomic_inc(csdev->refcnt); + + return 0; +} + +static void coresight_disable_source(struct coresight_device *csdev) +{ + if (atomic_dec_return(csdev->refcnt) == 0) { + if (source_ops(csdev)->disable) { + source_ops(csdev)->disable(csdev); + csdev->enable = false; + } + } +} + +static int coresight_enable_path(struct list_head *path) +{ + int ret = 0; + struct coresight_device *cd; + + list_for_each_entry(cd, path, path_link) { + if (cd == list_first_entry(path, struct coresight_device, + path_link)) { + ret = coresight_enable_sink(cd); + } else if (list_is_last(&cd->path_link, path)) { + /* + * Don't enable the source just yet - this needs to + * happen at the very end when all links and sink + * along the path have been configured properly. + */ + ; + } else { + ret = coresight_enable_link(cd); + } + if (ret) + goto err; + } + + return 0; +err: + list_for_each_entry_continue_reverse(cd, path, path_link) { + if (cd == list_first_entry(path, struct coresight_device, + path_link)) { + coresight_disable_sink(cd); + } else if (list_is_last(&cd->path_link, path)) { + ; + } else { + coresight_disable_link(cd); + } + } + + return ret; +} + +static int coresight_disable_path(struct list_head *path) +{ + struct coresight_device *cd; + + list_for_each_entry_reverse(cd, path, path_link) { + if (cd == list_first_entry(path, struct coresight_device, + path_link)) { + coresight_disable_sink(cd); + } else if (list_is_last(&cd->path_link, path)) { + /* + * The source has already been stopped, no need + * to do it again here. + */ + ; + } else { + coresight_disable_link(cd); + } + } + + return 0; +} + +static int coresight_build_paths(struct coresight_device *csdev, + struct list_head *path, + bool enable) +{ + int i, ret = -EINVAL; + struct coresight_connection *conn; + + list_add(&csdev->path_link, path); + + if (csdev->type == CORESIGHT_DEV_TYPE_SINK && csdev->activated) { + if (enable) + ret = coresight_enable_path(path); + else + ret = coresight_disable_path(path); + } else { + for (i = 0; i < csdev->nr_outport; i++) { + conn = &csdev->conns[i]; + if (coresight_build_paths(conn->child_dev, + path, enable) == 0) + ret = 0; + } + } + + if (list_first_entry(path, struct coresight_device, path_link) != csdev) + dev_err(&csdev->dev, "wrong device in %s\n", __func__); + + list_del(&csdev->path_link); + + return ret; +} + +int coresight_enable(struct coresight_device *csdev) +{ + int ret = 0; + LIST_HEAD(path); + + mutex_lock(&coresight_mutex); + if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) { + ret = -EINVAL; + dev_err(&csdev->dev, "wrong device type in %s\n", __func__); + goto out; + } + if (csdev->enable) + goto out; + + if (coresight_build_paths(csdev, &path, true)) { + dev_err(&csdev->dev, "building path(s) failed\n"); + goto out; + } + + if (coresight_enable_source(csdev)) + dev_err(&csdev->dev, "source enable failed\n"); +out: + mutex_unlock(&coresight_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(coresight_enable); + +void coresight_disable(struct coresight_device *csdev) +{ + LIST_HEAD(path); + + mutex_lock(&coresight_mutex); + if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) { + dev_err(&csdev->dev, "wrong device type in %s\n", __func__); + goto out; + } + if (!csdev->enable) + goto out; + + coresight_disable_source(csdev); + if (coresight_build_paths(csdev, &path, false)) + dev_err(&csdev->dev, "releasing path(s) failed\n"); + +out: + mutex_unlock(&coresight_mutex); +} +EXPORT_SYMBOL_GPL(coresight_disable); + +static ssize_t enable_sink_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev = to_coresight_device(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->activated); +} + +static ssize_t enable_sink_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct coresight_device *csdev = to_coresight_device(dev); + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val) + csdev->activated = true; + else + csdev->activated = false; + + return size; + +} +static DEVICE_ATTR_RW(enable_sink); + +static ssize_t enable_source_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev = to_coresight_device(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->enable); +} + +static ssize_t enable_source_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = 0; + unsigned long val; + struct coresight_device *csdev = to_coresight_device(dev); + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val) { + ret = coresight_enable(csdev); + if (ret) + return ret; + } else { + coresight_disable(csdev); + } + + return size; +} +static DEVICE_ATTR_RW(enable_source); + +static struct attribute *coresight_sink_attrs[] = { + &dev_attr_enable_sink.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_sink); + +static struct attribute *coresight_source_attrs[] = { + &dev_attr_enable_source.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_source); + +static struct device_type coresight_dev_type[] = { + { + .name = "none", + }, + { + .name = "sink", + .groups = coresight_sink_groups, + }, + { + .name = "link", + }, + { + .name = "linksink", + .groups = coresight_sink_groups, + }, + { + .name = "source", + .groups = coresight_source_groups, + }, +}; + +static void coresight_device_release(struct device *dev) +{ + struct coresight_device *csdev = to_coresight_device(dev); + + kfree(csdev); +} + +static int coresight_orphan_match(struct device *dev, void *data) +{ + int i; + bool still_orphan = false; + struct coresight_device *csdev, *i_csdev; + struct coresight_connection *conn; + + csdev = data; + i_csdev = to_coresight_device(dev); + + /* No need to check oneself */ + if (csdev == i_csdev) + return 0; + + /* Move on to another component if no connection is orphan */ + if (!i_csdev->orphan) + return 0; + /* + * Circle throuch all the connection of that component. If we find + * an orphan connection whose name matches @csdev, link it. + */ + for (i = 0; i < i_csdev->nr_outport; i++) { + conn = &i_csdev->conns[i]; + + /* We have found at least one orphan connection */ + if (conn->child_dev == NULL) { + /* Does it match this newly added device? */ + if (!strcmp(dev_name(&csdev->dev), conn->child_name)) + conn->child_dev = csdev; + } else { + /* Too bad, this component still has an orphan */ + still_orphan = true; + } + } + + i_csdev->orphan = still_orphan; + + /* + * Returning '0' ensures that all known component on the + * bus will be checked. + */ + return 0; +} + +static void coresight_fixup_orphan_conns(struct coresight_device *csdev) +{ + /* + * No need to check for a return value as orphan connection(s) + * are hooked-up with each newly added component. + */ + bus_for_each_dev(&coresight_bustype, NULL, + csdev, coresight_orphan_match); +} + + +static int coresight_name_match(struct device *dev, void *data) +{ + char *to_match; + struct coresight_device *i_csdev; + + to_match = data; + i_csdev = to_coresight_device(dev); + + if (!strcmp(to_match, dev_name(&i_csdev->dev))) + return 1; + + return 0; +} + +static void coresight_fixup_device_conns(struct coresight_device *csdev) +{ + int i; + struct device *dev = NULL; + struct coresight_connection *conn; + + for (i = 0; i < csdev->nr_outport; i++) { + conn = &csdev->conns[i]; + dev = bus_find_device(&coresight_bustype, NULL, + (void *)conn->child_name, + coresight_name_match); + + if (dev) { + conn->child_dev = to_coresight_device(dev); + } else { + csdev->orphan = true; + conn->child_dev = NULL; + } + } +} + +/** + * coresight_timeout - loop until a bit has changed to a specific state. + * @addr: base address of the area of interest. + * @offset: address of a register, starting from @addr. + * @position: the position of the bit of interest. + * @value: the value the bit should have. + * + * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if + * TIMEOUT_US has elapsed, which ever happens first. + */ + +int coresight_timeout(void __iomem *addr, u32 offset, int position, int value) +{ + int i; + u32 val; + + for (i = TIMEOUT_US; i > 0; i--) { + val = __raw_readl(addr + offset); + /* waiting on the bit to go from 0 to 1 */ + if (value) { + if (val & BIT(position)) + return 0; + /* waiting on the bit to go from 1 to 0 */ + } else { + if (!(val & BIT(position))) + return 0; + } + + /* + * Delay is arbitrary - the specification doesn't say how long + * we are expected to wait. Extra check required to make sure + * we don't wait needlessly on the last iteration. + */ + if (i - 1) + udelay(1); + } + + return -EAGAIN; +} + +struct bus_type coresight_bustype = { + .name = "coresight", +}; + +static int __init coresight_init(void) +{ + return bus_register(&coresight_bustype); +} +postcore_initcall(coresight_init); + +struct coresight_device *coresight_register(struct coresight_desc *desc) +{ + int i; + int ret; + int link_subtype; + int nr_refcnts = 1; + atomic_t *refcnts = NULL; + struct coresight_device *csdev; + struct coresight_connection *conns; + + csdev = kzalloc(sizeof(*csdev), GFP_KERNEL); + if (!csdev) { + ret = -ENOMEM; + goto err_kzalloc_csdev; + } + + if (desc->type == CORESIGHT_DEV_TYPE_LINK || + desc->type == CORESIGHT_DEV_TYPE_LINKSINK) { + link_subtype = desc->subtype.link_subtype; + + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) + nr_refcnts = desc->pdata->nr_inport; + else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) + nr_refcnts = desc->pdata->nr_outport; + } + + refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); + if (!refcnts) { + ret = -ENOMEM; + goto err_kzalloc_refcnts; + } + + csdev->refcnt = refcnts; + + csdev->nr_inport = desc->pdata->nr_inport; + csdev->nr_outport = desc->pdata->nr_outport; + conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL); + if (!conns) { + ret = -ENOMEM; + goto err_kzalloc_conns; + } + + for (i = 0; i < csdev->nr_outport; i++) { + conns[i].outport = desc->pdata->outports[i]; + conns[i].child_name = desc->pdata->child_names[i]; + conns[i].child_port = desc->pdata->child_ports[i]; + } + + csdev->conns = conns; + + csdev->type = desc->type; + csdev->subtype = desc->subtype; + csdev->ops = desc->ops; + csdev->orphan = false; + + csdev->dev.type = &coresight_dev_type[desc->type]; + csdev->dev.groups = desc->groups; + csdev->dev.parent = desc->dev; + csdev->dev.release = coresight_device_release; + csdev->dev.bus = &coresight_bustype; + dev_set_name(&csdev->dev, "%s", desc->pdata->name); + + ret = device_register(&csdev->dev); + if (ret) + goto err_device_register; + + mutex_lock(&coresight_mutex); + + coresight_fixup_device_conns(csdev); + coresight_fixup_orphan_conns(csdev); + + mutex_unlock(&coresight_mutex); + + return csdev; + +err_device_register: + kfree(conns); +err_kzalloc_conns: + kfree(refcnts); +err_kzalloc_refcnts: + kfree(csdev); +err_kzalloc_csdev: + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(coresight_register); + +void coresight_unregister(struct coresight_device *csdev) +{ + mutex_lock(&coresight_mutex); + + kfree(csdev->conns); + device_unregister(&csdev->dev); + + mutex_unlock(&coresight_mutex); +} +EXPORT_SYMBOL_GPL(coresight_unregister); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/coresight/of_coresight.c b/drivers/coresight/of_coresight.c new file mode 100644 index 000000000000..5030c0734508 --- /dev/null +++ b/drivers/coresight/of_coresight.c @@ -0,0 +1,204 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int of_dev_node_match(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static struct device * +of_coresight_get_endpoint_device(struct device_node *endpoint) +{ + struct device *dev = NULL; + + /* + * If we have a non-configuable replicator, it will be found on the + * platform bus. + */ + dev = bus_find_device(&platform_bus_type, NULL, + endpoint, of_dev_node_match); + if (dev) + return dev; + + /* + * We have a configurable component - circle through the AMBA bus + * looking for the device that matches the endpoint node. + */ + return bus_find_device(&amba_bustype, NULL, + endpoint, of_dev_node_match); +} + +static struct device_node *of_get_coresight_endpoint( + const struct device_node *parent, struct device_node *prev) +{ + struct device_node *node = of_graph_get_next_endpoint(parent, prev); + + of_node_put(prev); + return node; +} + +static void of_coresight_get_ports(struct device_node *node, + int *nr_inport, int *nr_outport) +{ + struct device_node *ep = NULL; + int in = 0, out = 0; + + do { + ep = of_get_coresight_endpoint(node, ep); + if (!ep) + break; + + if (of_property_read_bool(ep, "slave-mode")) + in++; + else + out++; + + } while (ep); + + *nr_inport = in; + *nr_outport = out; +} + +static int of_coresight_alloc_memory(struct device *dev, + struct coresight_platform_data *pdata) +{ + /* List of output port on this component */ + pdata->outports = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->outports), + GFP_KERNEL); + if (!pdata->outports) + return -ENOMEM; + + /* Children connected to this component via @outport */ + pdata->child_names = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->child_names), + GFP_KERNEL); + if (!pdata->child_names) + return -ENOMEM; + + /* Port number on the child this component is connected to */ + pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->child_ports), + GFP_KERNEL); + if (!pdata->child_ports) + return -ENOMEM; + + return 0; +} + +struct coresight_platform_data *of_get_coresight_platform_data( + struct device *dev, struct device_node *node) +{ + int i = 0, ret = 0; + struct coresight_platform_data *pdata; + struct of_endpoint endpoint, rendpoint; + struct device *rdev; + struct device_node *cpu; + struct device_node *ep = NULL; + struct device_node *rparent = NULL; + struct device_node *rport = NULL; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + /* Use device name as debugfs handle */ + pdata->name = dev_name(dev); + + /* Get the number of input and output port for this component */ + of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); + + if (pdata->nr_outport) { + ret = of_coresight_alloc_memory(dev, pdata); + if (ret) + return ERR_PTR(ret); + + /* Iterate through each port to discover topology */ + do { + /* Get a handle on a port */ + ep = of_get_coresight_endpoint(node, ep); + if (!ep) + break; + + /* + * No need to deal with input ports, processing for as + * processing for output ports will deal with them. + */ + if (of_find_property(ep, "slave-mode", NULL)) + continue; + + /* Get a handle on the local endpoint */ + ret = of_graph_parse_endpoint(ep, &endpoint); + + if (ret) + continue; + + /* The local out port number */ + pdata->outports[i] = endpoint.id; + + /* + * Get a handle on the remote port and parent + * attached to it. + */ + rparent = of_graph_get_remote_port_parent(ep); + rport = of_graph_get_remote_port(ep); + + if (!rparent || !rport) + continue; + + if (of_graph_parse_endpoint(rport, &rendpoint)) + continue; + + rdev = of_coresight_get_endpoint_device(rparent); + if (!dev) + continue; + + pdata->child_names[i] = dev_name(rdev); + pdata->child_ports[i] = rendpoint.id; + + i++; + } while (ep); + } + + /* Affinity defaults to CPU0 */ + pdata->cpu = 0; + cpu = of_parse_phandle(node, "cpu", 0); + if (cpu) { + const u32 *mpidr; + int len, index; + + mpidr = of_get_property(cpu, "reg", &len); + if (mpidr && len == 4) { + index = get_logical_index(be32_to_cpup(mpidr)); + if (index != -EINVAL) + pdata->cpu = index; + } + } + + return pdata; +} +EXPORT_SYMBOL_GPL(of_get_coresight_platform_data); diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index c324f5700d1a..d024bd9c9d9b 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -23,6 +23,7 @@ #define AMBA_NR_IRQS 9 #define AMBA_CID 0xb105f00d +#define CORESIGHT_CID 0xb105900d struct clk; diff --git a/include/linux/coresight.h b/include/linux/coresight.h new file mode 100644 index 000000000000..bdde4199c74a --- /dev/null +++ b/include/linux/coresight.h @@ -0,0 +1,263 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_CORESIGHT_H +#define _LINUX_CORESIGHT_H + +#include + +/* Peripheral id registers (0xFD0-0xFEC) */ +#define CORESIGHT_PERIPHIDR4 0xfd0 +#define CORESIGHT_PERIPHIDR5 0xfd4 +#define CORESIGHT_PERIPHIDR6 0xfd8 +#define CORESIGHT_PERIPHIDR7 0xfdC +#define CORESIGHT_PERIPHIDR0 0xfe0 +#define CORESIGHT_PERIPHIDR1 0xfe4 +#define CORESIGHT_PERIPHIDR2 0xfe8 +#define CORESIGHT_PERIPHIDR3 0xfeC +/* Component id registers (0xFF0-0xFFC) */ +#define CORESIGHT_COMPIDR0 0xff0 +#define CORESIGHT_COMPIDR1 0xff4 +#define CORESIGHT_COMPIDR2 0xff8 +#define CORESIGHT_COMPIDR3 0xffC + +#define ETM_ARCH_V3_3 0x23 +#define ETM_ARCH_V3_5 0x25 +#define PFT_ARCH_V1_0 0x30 +#define PFT_ARCH_V1_1 0x31 + +#define CORESIGHT_UNLOCK 0xc5acce55 + +extern struct bus_type coresight_bustype; + +enum coresight_dev_type { + CORESIGHT_DEV_TYPE_NONE, + CORESIGHT_DEV_TYPE_SINK, + CORESIGHT_DEV_TYPE_LINK, + CORESIGHT_DEV_TYPE_LINKSINK, + CORESIGHT_DEV_TYPE_SOURCE, +}; + +enum coresight_dev_subtype_sink { + CORESIGHT_DEV_SUBTYPE_SINK_NONE, + CORESIGHT_DEV_SUBTYPE_SINK_PORT, + CORESIGHT_DEV_SUBTYPE_SINK_BUFFER, +}; + +enum coresight_dev_subtype_link { + CORESIGHT_DEV_SUBTYPE_LINK_NONE, + CORESIGHT_DEV_SUBTYPE_LINK_MERG, + CORESIGHT_DEV_SUBTYPE_LINK_SPLIT, + CORESIGHT_DEV_SUBTYPE_LINK_FIFO, +}; + +enum coresight_dev_subtype_source { + CORESIGHT_DEV_SUBTYPE_SOURCE_NONE, + CORESIGHT_DEV_SUBTYPE_SOURCE_PROC, + CORESIGHT_DEV_SUBTYPE_SOURCE_BUS, + CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE, +}; + +/** + * struct coresight_dev_subtype - further characterisation of a type + * @sink_subtype: type of sink this component is, as defined + by @coresight_dev_subtype_sink. + * @link_subtype: type of link this component is, as defined + by @coresight_dev_subtype_link. + * @source_subtype: type of source this component is, as defined + by @coresight_dev_subtype_source. + */ +struct coresight_dev_subtype { + enum coresight_dev_subtype_sink sink_subtype; + enum coresight_dev_subtype_link link_subtype; + enum coresight_dev_subtype_source source_subtype; +}; + +/** + * struct coresight_platform_data - data harvested from the DT specification + * @cpu: the CPU a source belongs to. Only applicable for ETM/PTMs. + * @name: name of the component as shown under sysfs. + * @nr_inport: number of input ports for this component. + * @outports: list of remote enpoint port number. + * @child_names:name of all child components connected to this device. + * @child_ports:child component port number the current component is + connected to. + * @nr_outport: number of output ports for this component. + * @clk: The clock this component is associated to. + */ +struct coresight_platform_data { + int cpu; + const char *name; + int nr_inport; + int *outports; + const char **child_names; + int *child_ports; + int nr_outport; + struct clk *clk; +}; + +/** + * struct coresight_desc - description of a component required from drivers + * @type: as defined by @coresight_dev_type. + * @subtype: as defined by @coresight_dev_subtype. + * @ops: generic operations for this component, as defined + by @coresight_ops. + * @pdata: platform data collected from DT. + * @dev: The device entity associated to this component. + * @groups :operations specific to this component. These will end up + in the component's sysfs sub-directory. + */ +struct coresight_desc { + enum coresight_dev_type type; + struct coresight_dev_subtype subtype; + const struct coresight_ops *ops; + struct coresight_platform_data *pdata; + struct device *dev; + const struct attribute_group **groups; +}; + +/** + * struct coresight_connection - representation of a single connection + * @ref_count: keeping count a port' references. + * @outport: a connection's output port number. + * @chid_name: remote component's name. + * @child_port: remote component's port number @output is connected to. + * @child_dev: a @coresight_device representation of the component + connected to @outport. + */ +struct coresight_connection { + int outport; + const char *child_name; + int child_port; + struct coresight_device *child_dev; +}; + +/** + * struct coresight_device - representation of a device as used by the framework + * @nr_inport: number of input port associated to this component. + * @nr_outport: number of output port associated to this component. + * @type: as defined by @coresight_dev_type. + * @subtype: as defined by @coresight_dev_subtype. + * @ops: generic operations for this component, as defined + by @coresight_ops. + * @dev: The device entity associated to this component. + * @refcnt: keep track of what is in use. + * @path_link: link of current component into the path being enabled. + * @orphan: true if the component has connections that haven't been linked. + * @enable: 'true' if component is currently part of an active path. + * @activated: 'true' only if a _sink_ has been activated. A sink can be + activated but not yet enabled. Enabling for a _sink_ + happens when a source has been selected for that it. + */ +struct coresight_device { + struct coresight_connection *conns; + int nr_inport; + int nr_outport; + enum coresight_dev_type type; + struct coresight_dev_subtype subtype; + const struct coresight_ops *ops; + struct device dev; + atomic_t *refcnt; + struct list_head path_link; + bool orphan; + bool enable; /* true only if configured as part of a path */ + bool activated; /* true only if a sink is part of a path */ +}; + +#define to_coresight_device(d) container_of(d, struct coresight_device, dev) + +#define source_ops(csdev) csdev->ops->source_ops +#define sink_ops(csdev) csdev->ops->sink_ops +#define link_ops(csdev) csdev->ops->link_ops + +#define CORESIGHT_DEBUGFS_ENTRY(__name, __entry_name, \ + __mode, __get, __set, __fmt) \ +DEFINE_SIMPLE_ATTRIBUTE(__name ## _ops, __get, __set, __fmt); \ +static const struct coresight_ops_entry __name ## _entry = { \ + .name = __entry_name, \ + .mode = __mode, \ + .ops = &__name ## _ops \ +} + +/** + * struct coresight_ops_sink - basic operations for a sink + * Operations available for sinks + * @enable: enables the sink. + * @disable: disables the sink. + */ +struct coresight_ops_sink { + int (*enable)(struct coresight_device *csdev); + void (*disable)(struct coresight_device *csdev); +}; + +/** + * struct coresight_ops_link - basic operations for a link + * Operations available for links. + * @enable: enables flow between iport and oport. + * @disable: disables flow between iport and oport. + */ +struct coresight_ops_link { + int (*enable)(struct coresight_device *csdev, int iport, int oport); + void (*disable)(struct coresight_device *csdev, int iport, int oport); +}; + +/** + * struct coresight_ops_source - basic operations for a source + * Operations available for sources. + * @trace_id: returns the value of the component's trace ID as known + to the HW. + * @enable: enables tracing from a source. + * @disable: disables tracing for a source. + */ +struct coresight_ops_source { + int (*trace_id)(struct coresight_device *csdev); + int (*enable)(struct coresight_device *csdev); + void (*disable)(struct coresight_device *csdev); +}; + +struct coresight_ops { + const struct coresight_ops_sink *sink_ops; + const struct coresight_ops_link *link_ops; + const struct coresight_ops_source *source_ops; +}; + +#ifdef CONFIG_CORESIGHT +extern struct coresight_device * +coresight_register(struct coresight_desc *desc); +extern void coresight_unregister(struct coresight_device *csdev); +extern int coresight_enable(struct coresight_device *csdev); +extern void coresight_disable(struct coresight_device *csdev); +extern int coresight_is_bit_set(u32 val, int position, int value); +extern int coresight_timeout(void __iomem *addr, u32 offset, + int position, int value); +#ifdef CONFIG_OF +extern struct coresight_platform_data *of_get_coresight_platform_data( + struct device *dev, struct device_node *node); +#endif +#else +static inline struct coresight_device * +coresight_register(struct coresight_desc *desc) { return NULL; } +static inline void coresight_unregister(struct coresight_device *csdev) {} +static inline int +coresight_enable(struct coresight_device *csdev) { return -ENOSYS; } +static inline void coresight_disable(struct coresight_device *csdev) {} +static inline int coresight_is_bit_set(u32 val, int position, int value) + { return 0; } +static inline int coresight_timeout(void __iomem *addr, u32 offset, + int position, int value) { return 1; } +#ifdef CONFIG_OF +static inline struct coresight_platform_data *of_get_coresight_platform_data( + struct device *dev, struct device_node *node) { return NULL; } +#endif +#endif + +#endif -- GitLab From bc4bf7fe98daf4e64cc5ffc6cdc0e820f4d99c14 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:36 -0700 Subject: [PATCH 3964/9457] coresight-tmc: add CoreSight TMC driver This driver manages CoreSight TMC (Trace Memory Controller) which can act as a link or a sink depending upon its configuration. It can present itself as an ETF (Embedded Trace FIFO) or ETR (Embedded Trace Router). ETF when configured in circular buffer mode acts as a trace collection sink. When configured in HW fifo mode it acts as link. ETR always acts as a sink and can be used to route data to memory allocated in RAM. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig.debug | 20 + drivers/coresight/Makefile | 1 + drivers/coresight/coresight-tmc.c | 776 ++++++++++++++++++++++++++++++ 3 files changed, 797 insertions(+) create mode 100644 drivers/coresight/coresight-tmc.c diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index cd3890e3110e..092b6728af55 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1340,4 +1340,24 @@ menuconfig CORESIGHT a topological view of the CoreSight components based on a DT specification and configure the right serie of components when a trace source gets enabled. + +if CORESIGHT +config CORESIGHT_LINKS_AND_SINKS + bool "CoreSight Link and Sink drivers" + help + This enables support for CoreSight link and sink drivers that are + responsible for transporting and collecting the trace data + respectively. Link and sinks are dynamically aggregated with a trace + entity at run time to form a complete trace path. + +config CORESIGHT_LINK_AND_SINK_TMC + bool "Coresight generic TMC driver" + depends on CORESIGHT_LINKS_AND_SINKS + help + This enables support for the Trace Memory Controller driver. Depending + on its configuration the device can act as a link (embedded trace router + - ETR) or sink (embedded trace FIFO). The driver complies with the + generic implementation of the component without special enhancement or + added features. +endif endmenu diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index 218e3b589f93..d26bd0e78122 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_CORESIGHT) += coresight.o obj-$(CONFIG_OF) += of_coresight.o +obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c new file mode 100644 index 000000000000..ce2c293f1707 --- /dev/null +++ b/drivers/coresight/coresight-tmc.c @@ -0,0 +1,776 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +#define TMC_RSZ 0x004 +#define TMC_STS 0x00c +#define TMC_RRD 0x010 +#define TMC_RRP 0x014 +#define TMC_RWP 0x018 +#define TMC_TRG 0x01c +#define TMC_CTL 0x020 +#define TMC_RWD 0x024 +#define TMC_MODE 0x028 +#define TMC_LBUFLEVEL 0x02c +#define TMC_CBUFLEVEL 0x030 +#define TMC_BUFWM 0x034 +#define TMC_RRPHI 0x038 +#define TMC_RWPHI 0x03c +#define TMC_AXICTL 0x110 +#define TMC_DBALO 0x118 +#define TMC_DBAHI 0x11c +#define TMC_FFSR 0x300 +#define TMC_FFCR 0x304 +#define TMC_PSCR 0x308 +#define TMC_ITMISCOP0 0xee0 +#define TMC_ITTRFLIN 0xee8 +#define TMC_ITATBDATA0 0xeec +#define TMC_ITATBCTR2 0xef0 +#define TMC_ITATBCTR1 0xef4 +#define TMC_ITATBCTR0 0xef8 + +/* register description */ +/* TMC_CTL - 0x020 */ +#define TMC_CTL_CAPT_EN BIT(0) +/* TMC_STS - 0x00C */ +#define TMC_STS_TRIGGERED BIT(1) +/* TMC_AXICTL - 0x110 */ +#define TMC_AXICTL_PROT_CTL_B0 BIT(0) +#define TMC_AXICTL_PROT_CTL_B1 BIT(1) +#define TMC_AXICTL_SCT_GAT_MODE BIT(7) +#define TMC_AXICTL_WR_BURST_LEN 0xF00 +/* TMC_FFCR - 0x304 */ +#define TMC_FFCR_EN_FMT BIT(0) +#define TMC_FFCR_EN_TI BIT(1) +#define TMC_FFCR_FON_FLIN BIT(4) +#define TMC_FFCR_FON_TRIG_EVT BIT(5) +#define TMC_FFCR_FLUSHMAN BIT(6) +#define TMC_FFCR_TRIGON_TRIGIN BIT(8) +#define TMC_FFCR_STOP_ON_FLUSH BIT(12) + +#define TMC_STS_TRIGGERED_BIT 2 +#define TMC_FFCR_FLUSHMAN_BIT 6 + +enum tmc_config_type { + TMC_CONFIG_TYPE_ETB, + TMC_CONFIG_TYPE_ETR, + TMC_CONFIG_TYPE_ETF, +}; + +enum tmc_mode { + TMC_MODE_CIRCULAR_BUFFER, + TMC_MODE_SOFTWARE_FIFO, + TMC_MODE_HARDWARE_FIFO, +}; + +enum tmc_mem_intf_width { + TMC_MEM_INTF_WIDTH_32BITS = 0x2, + TMC_MEM_INTF_WIDTH_64BITS = 0x3, + TMC_MEM_INTF_WIDTH_128BITS = 0x4, + TMC_MEM_INTF_WIDTH_256BITS = 0x5, +}; + +/** + * struct tmc_drvdata - specifics associated to an TMC component + * @base: memory mapped base address for this component. + * @dev: the device entity associated to this component. + * @csdev: component vitals needed by the framework. + * @miscdev: specifics to handle "/dev/xyz.tmc" entry. + * @clk: the clock this component is associated to. + * @spinlock: only one at a time pls. + * @read_count: manages preparation of buffer for reading. + * @buf: area of memory where trace data get sent. + * @paddr: DMA start location in RAM. + * @vaddr: virtual representation of @paddr. + * @size: @buf size. + * @enable: this TMC is being used. + * @config_type: TMC variant, must be of type @tmc_config_type. + * @trigger_cntr: amount of words to store after a trigger. + */ +struct tmc_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + struct miscdevice miscdev; + struct clk *clk; + spinlock_t spinlock; + int read_count; + bool reading; + char *buf; + dma_addr_t paddr; + void __iomem *vaddr; + u32 size; + bool enable; + enum tmc_config_type config_type; + u32 trigger_cntr; +}; + +static void tmc_wait_for_ready(struct tmc_drvdata *drvdata) +{ + /* Ensure formatter, unformatter and hardware fifo are empty */ + if (coresight_timeout(drvdata->base, + TMC_STS, TMC_STS_TRIGGERED_BIT, 1)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", + TMC_STS); + } +} + +static void tmc_flush_and_stop(struct tmc_drvdata *drvdata) +{ + u32 ffcr; + + ffcr = readl_relaxed(drvdata->base + TMC_FFCR); + ffcr |= TMC_FFCR_STOP_ON_FLUSH; + writel_relaxed(ffcr, drvdata->base + TMC_FFCR); + ffcr |= TMC_FFCR_FLUSHMAN; + writel_relaxed(ffcr, drvdata->base + TMC_FFCR); + /* Ensure flush completes */ + if (coresight_timeout(drvdata->base, + TMC_FFCR, TMC_FFCR_FLUSHMAN_BIT, 0)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", + TMC_FFCR); + } + + tmc_wait_for_ready(drvdata); +} + +static void tmc_enable_hw(struct tmc_drvdata *drvdata) +{ + writel_relaxed(TMC_CTL_CAPT_EN, drvdata->base + TMC_CTL); +} + +static void tmc_disable_hw(struct tmc_drvdata *drvdata) +{ + writel_relaxed(0x0, drvdata->base + TMC_CTL); +} + +static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) +{ + /* Zero out the memory to help with debug */ + memset(drvdata->buf, 0, drvdata->size); + + CS_UNLOCK(drvdata->base); + + writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); + writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | + TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT | + TMC_FFCR_TRIGON_TRIGIN, + drvdata->base + TMC_FFCR); + + writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG); + tmc_enable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) +{ + u32 axictl; + + /* Zero out the memory to help with debug */ + memset(drvdata->vaddr, 0, drvdata->size); + + CS_UNLOCK(drvdata->base); + + writel_relaxed(drvdata->size / 4, drvdata->base + TMC_RSZ); + writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); + + axictl = readl_relaxed(drvdata->base + TMC_AXICTL); + axictl |= TMC_AXICTL_WR_BURST_LEN; + writel_relaxed(axictl, drvdata->base + TMC_AXICTL); + axictl &= ~TMC_AXICTL_SCT_GAT_MODE; + writel_relaxed(axictl, drvdata->base + TMC_AXICTL); + axictl = (axictl & + ~(TMC_AXICTL_PROT_CTL_B0 | TMC_AXICTL_PROT_CTL_B1)) | + TMC_AXICTL_PROT_CTL_B1; + writel_relaxed(axictl, drvdata->base + TMC_AXICTL); + + writel_relaxed(drvdata->paddr, drvdata->base + TMC_DBALO); + writel_relaxed(0x0, drvdata->base + TMC_DBAHI); + writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | + TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT | + TMC_FFCR_TRIGON_TRIGIN, + drvdata->base + TMC_FFCR); + writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG); + tmc_enable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + writel_relaxed(TMC_MODE_HARDWARE_FIFO, drvdata->base + TMC_MODE); + writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI, + drvdata->base + TMC_FFCR); + writel_relaxed(0x0, drvdata->base + TMC_BUFWM); + tmc_enable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode) +{ + int ret; + unsigned long flags; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (drvdata->reading) { + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); + return -EBUSY; + } + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + tmc_etb_enable_hw(drvdata); + } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + tmc_etr_enable_hw(drvdata); + } else { + if (mode == TMC_MODE_CIRCULAR_BUFFER) + tmc_etb_enable_hw(drvdata); + else + tmc_etf_enable_hw(drvdata); + } + drvdata->enable = true; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + dev_info(drvdata->dev, "TMC enabled\n"); + return 0; +} + +static int tmc_enable_sink(struct coresight_device *csdev) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + return tmc_enable(drvdata, TMC_MODE_CIRCULAR_BUFFER); +} + +static int tmc_enable_link(struct coresight_device *csdev, int inport, + int outport) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + return tmc_enable(drvdata, TMC_MODE_HARDWARE_FIFO); +} + +static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) +{ + enum tmc_mem_intf_width memwidth; + u8 memwords; + char *bufp; + u32 read_data; + int i; + + memwidth = BMVAL(readl_relaxed(drvdata->base + CORESIGHT_DEVID), 8, 10); + if (memwidth == TMC_MEM_INTF_WIDTH_32BITS) + memwords = 1; + else if (memwidth == TMC_MEM_INTF_WIDTH_64BITS) + memwords = 2; + else if (memwidth == TMC_MEM_INTF_WIDTH_128BITS) + memwords = 4; + else + memwords = 8; + + bufp = drvdata->buf; + while (1) { + for (i = 0; i < memwords; i++) { + read_data = readl_relaxed(drvdata->base + TMC_RRD); + if (read_data == 0xFFFFFFFF) + return; + memcpy(bufp, &read_data, 4); + bufp += 4; + } + } +} + +static void tmc_etb_disable_hw(struct tmc_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + tmc_flush_and_stop(drvdata); + tmc_etb_dump_hw(drvdata); + tmc_disable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) +{ + u32 rwp, val; + + rwp = readl_relaxed(drvdata->base + TMC_RWP); + val = readl_relaxed(drvdata->base + TMC_STS); + + /* How much memory do we still have */ + if (val & BIT(0)) + drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr; + else + drvdata->buf = drvdata->vaddr; +} + +static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + tmc_flush_and_stop(drvdata); + tmc_etr_dump_hw(drvdata); + tmc_disable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + tmc_flush_and_stop(drvdata); + tmc_disable_hw(drvdata); + + CS_LOCK(drvdata->base); +} + +static void tmc_disable(struct tmc_drvdata *drvdata, enum tmc_mode mode) +{ + unsigned long flags; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (drvdata->reading) + goto out; + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + tmc_etb_disable_hw(drvdata); + } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + tmc_etr_disable_hw(drvdata); + } else { + if (mode == TMC_MODE_CIRCULAR_BUFFER) + tmc_etb_disable_hw(drvdata); + else + tmc_etf_disable_hw(drvdata); + } +out: + drvdata->enable = false; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + clk_disable_unprepare(drvdata->clk); + + dev_info(drvdata->dev, "TMC disabled\n"); +} + +static void tmc_disable_sink(struct coresight_device *csdev) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + tmc_disable(drvdata, TMC_MODE_CIRCULAR_BUFFER); +} + +static void tmc_disable_link(struct coresight_device *csdev, int inport, + int outport) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + tmc_disable(drvdata, TMC_MODE_HARDWARE_FIFO); +} + +static const struct coresight_ops_sink tmc_sink_ops = { + .enable = tmc_enable_sink, + .disable = tmc_disable_sink, +}; + +static const struct coresight_ops_link tmc_link_ops = { + .enable = tmc_enable_link, + .disable = tmc_disable_link, +}; + +static const struct coresight_ops tmc_etb_cs_ops = { + .sink_ops = &tmc_sink_ops, +}; + +static const struct coresight_ops tmc_etr_cs_ops = { + .sink_ops = &tmc_sink_ops, +}; + +static const struct coresight_ops tmc_etf_cs_ops = { + .sink_ops = &tmc_sink_ops, + .link_ops = &tmc_link_ops, +}; + +static int tmc_read_prepare(struct tmc_drvdata *drvdata) +{ + int ret; + unsigned long flags; + enum tmc_mode mode; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (!drvdata->enable) + goto out; + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + tmc_etb_disable_hw(drvdata); + } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + tmc_etr_disable_hw(drvdata); + } else { + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode == TMC_MODE_CIRCULAR_BUFFER) { + tmc_etb_disable_hw(drvdata); + } else { + ret = -ENODEV; + goto err; + } + } +out: + drvdata->reading = true; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + dev_info(drvdata->dev, "TMC read start\n"); + return 0; +err: + spin_unlock_irqrestore(&drvdata->spinlock, flags); + return ret; +} + +static void tmc_read_unprepare(struct tmc_drvdata *drvdata) +{ + unsigned long flags; + enum tmc_mode mode; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (!drvdata->enable) + goto out; + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + tmc_etb_enable_hw(drvdata); + } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + tmc_etr_enable_hw(drvdata); + } else { + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode == TMC_MODE_CIRCULAR_BUFFER) + tmc_etb_enable_hw(drvdata); + } +out: + drvdata->reading = false; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + dev_info(drvdata->dev, "TMC read end\n"); +} + +static int tmc_open(struct inode *inode, struct file *file) +{ + struct tmc_drvdata *drvdata = container_of(file->private_data, + struct tmc_drvdata, miscdev); + int ret = 0; + + if (drvdata->read_count++) + goto out; + + ret = tmc_read_prepare(drvdata); + if (ret) + return ret; +out: + nonseekable_open(inode, file); + + dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__); + return 0; +} + +static ssize_t tmc_read(struct file *file, char __user *data, size_t len, + loff_t *ppos) +{ + struct tmc_drvdata *drvdata = container_of(file->private_data, + struct tmc_drvdata, miscdev); + char *bufp = drvdata->buf + *ppos; + + if (*ppos + len > drvdata->size) + len = drvdata->size - *ppos; + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + if (bufp == (char *)(drvdata->vaddr + drvdata->size)) + bufp = drvdata->vaddr; + else if (bufp > (char *)(drvdata->vaddr + drvdata->size)) + bufp -= drvdata->size; + if ((bufp + len) > (char *)(drvdata->vaddr + drvdata->size)) + len = (char *)(drvdata->vaddr + drvdata->size) - bufp; + } + + if (copy_to_user(data, bufp, len)) { + dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__); + return -EFAULT; + } + + *ppos += len; + + dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n", + __func__, len, (int) (drvdata->size - *ppos)); + return len; +} + +static int tmc_release(struct inode *inode, struct file *file) +{ + struct tmc_drvdata *drvdata = container_of(file->private_data, + struct tmc_drvdata, miscdev); + + if (--drvdata->read_count) { + if (drvdata->read_count < 0) { + dev_err(drvdata->dev, "mismatched close\n"); + drvdata->read_count = 0; + } + goto out; + } + + tmc_read_unprepare(drvdata); +out: + dev_dbg(drvdata->dev, "%s: released\n", __func__); + return 0; +} + +static const struct file_operations tmc_fops = { + .owner = THIS_MODULE, + .open = tmc_open, + .read = tmc_read, + .release = tmc_release, + .llseek = no_llseek, +}; + +static ssize_t trigger_cntr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val = drvdata->trigger_cntr; + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t trigger_cntr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->trigger_cntr = val; + return size; +} +static DEVICE_ATTR_RW(trigger_cntr); + +static struct attribute *coresight_etb_attrs[] = { + &dev_attr_trigger_cntr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_etb); + +static struct attribute *coresight_etr_attrs[] = { + &dev_attr_trigger_cntr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_etr); + +static struct attribute *coresight_etf_attrs[] = { + &dev_attr_trigger_cntr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_etf); + +static int tmc_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret = 0; + u32 devid; + void __iomem *base; + struct device *dev = &adev->dev; + struct coresight_platform_data *pdata = NULL; + struct tmc_drvdata *drvdata; + struct resource *res = &adev->res; + struct coresight_desc *desc; + struct device_node *np = adev->dev.of_node; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + + spin_lock_init(&drvdata->spinlock); + + drvdata->clk = adev->pclk; + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); + drvdata->config_type = BMVAL(devid, 6, 7); + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + if (np) + ret = of_property_read_u32(np, + "arm,buffer-size", + &drvdata->size); + if (ret) + drvdata->size = SZ_1M; + } else { + drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; + } + + clk_disable_unprepare(drvdata->clk); + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + drvdata->vaddr = dma_alloc_coherent(dev, drvdata->size, + &drvdata->paddr, GFP_KERNEL); + if (!drvdata->vaddr) + return -ENOMEM; + + memset(drvdata->vaddr, 0, drvdata->size); + drvdata->buf = drvdata->vaddr; + } else { + drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL); + if (!drvdata->buf) + return -ENOMEM; + } + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) { + ret = -ENOMEM; + goto err_devm_kzalloc; + } + + desc->pdata = pdata; + desc->dev = dev; + desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; + + if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + desc->type = CORESIGHT_DEV_TYPE_SINK; + desc->ops = &tmc_etb_cs_ops; + desc->groups = coresight_etb_groups; + } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + desc->type = CORESIGHT_DEV_TYPE_SINK; + desc->ops = &tmc_etr_cs_ops; + desc->groups = coresight_etr_groups; + } else { + desc->type = CORESIGHT_DEV_TYPE_LINKSINK; + desc->subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; + desc->ops = &tmc_etf_cs_ops; + desc->groups = coresight_etf_groups; + } + + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err_devm_kzalloc; + } + + drvdata->miscdev.name = pdata->name; + drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; + drvdata->miscdev.fops = &tmc_fops; + ret = misc_register(&drvdata->miscdev); + if (ret) + goto err_misc_register; + + dev_info(dev, "TMC initialized\n"); + return 0; + +err_misc_register: + coresight_unregister(drvdata->csdev); +err_devm_kzalloc: + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) + dma_free_coherent(dev, drvdata->size, + &drvdata->paddr, GFP_KERNEL); + return ret; +} + +static int tmc_remove(struct amba_device *adev) +{ + struct tmc_drvdata *drvdata = amba_get_drvdata(adev); + + misc_deregister(&drvdata->miscdev); + coresight_unregister(drvdata->csdev); + if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) + dma_free_coherent(drvdata->dev, drvdata->size, + &drvdata->paddr, GFP_KERNEL); + + return 0; +} + +static struct amba_id tmc_ids[] = { + { + .id = 0x0003b961, + .mask = 0x0003ffff, + }, + { 0, 0}, +}; + +static struct amba_driver tmc_driver = { + .drv = { + .name = "coresight-tmc", + .owner = THIS_MODULE, + }, + .probe = tmc_probe, + .remove = tmc_remove, + .id_table = tmc_ids, +}; + +static int __init tmc_init(void) +{ + return amba_driver_register(&tmc_driver); +} +module_init(tmc_init); + +static void __exit tmc_exit(void) +{ + amba_driver_unregister(&tmc_driver); +} +module_exit(tmc_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Trace Memory Controller driver"); -- GitLab From dc161b9f01142c6b2c985290b7aa3e58e2408036 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:37 -0700 Subject: [PATCH 3965/9457] coresight-tpiu: add CoreSight TPIU driver This driver manages CoreSight TPIU (Trace Port Interface Unit) which acts as a sink. TPIU is typically connected to some offchip hardware hosting a storage buffer. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig.debug | 9 ++ drivers/coresight/Makefile | 1 + drivers/coresight/coresight-tpiu.c | 217 +++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 drivers/coresight/coresight-tpiu.c diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 092b6728af55..4815efbbb55d 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1359,5 +1359,14 @@ config CORESIGHT_LINK_AND_SINK_TMC - ETR) or sink (embedded trace FIFO). The driver complies with the generic implementation of the component without special enhancement or added features. + +config CORESIGHT_SINK_TPIU + bool "Coresight generic TPIU driver" + depends on CORESIGHT_LINKS_AND_SINKS + help + This enables support for the Trace Port Interface Unit driver, responsible + for bridging the gap between the on-chip coresight components and a trace + port collection engine, typically connected to an external host for use + case capturing more traces than the on-board coresight memory can handle. endif endmenu diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index d26bd0e78122..41ab769b4822 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_CORESIGHT) += coresight.o obj-$(CONFIG_OF) += of_coresight.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o +obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o diff --git a/drivers/coresight/coresight-tpiu.c b/drivers/coresight/coresight-tpiu.c new file mode 100644 index 000000000000..ae101082791a --- /dev/null +++ b/drivers/coresight/coresight-tpiu.c @@ -0,0 +1,217 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +#define TPIU_SUPP_PORTSZ 0x000 +#define TPIU_CURR_PORTSZ 0x004 +#define TPIU_SUPP_TRIGMODES 0x100 +#define TPIU_TRIG_CNTRVAL 0x104 +#define TPIU_TRIG_MULT 0x108 +#define TPIU_SUPP_TESTPATM 0x200 +#define TPIU_CURR_TESTPATM 0x204 +#define TPIU_TEST_PATREPCNTR 0x208 +#define TPIU_FFSR 0x300 +#define TPIU_FFCR 0x304 +#define TPIU_FSYNC_CNTR 0x308 +#define TPIU_EXTCTL_INPORT 0x400 +#define TPIU_EXTCTL_OUTPORT 0x404 +#define TPIU_ITTRFLINACK 0xee4 +#define TPIU_ITTRFLIN 0xee8 +#define TPIU_ITATBDATA0 0xeec +#define TPIU_ITATBCTR2 0xef0 +#define TPIU_ITATBCTR1 0xef4 +#define TPIU_ITATBCTR0 0xef8 + +/** register definition **/ +/* FFCR - 0x304 */ +#define FFCR_FON_MAN BIT(6) + +/** + * @base: memory mapped base address for this component. + * @dev: the device entity associated to this component. + * @csdev: component vitals needed by the framework. + * @clk: the clock this component is associated to. + */ +struct tpiu_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + struct clk *clk; +}; + +static void tpiu_enable_hw(struct tpiu_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + /* TODO: fill this up */ + + CS_LOCK(drvdata->base); +} + +static int tpiu_enable(struct coresight_device *csdev) +{ + struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + tpiu_enable_hw(drvdata); + + dev_info(drvdata->dev, "TPIU enabled\n"); + return 0; +} + +static void tpiu_disable_hw(struct tpiu_drvdata *drvdata) +{ + CS_UNLOCK(drvdata->base); + + /* Clear formatter controle reg. */ + writel_relaxed(0x0, drvdata->base + TPIU_FFCR); + /* Generate manual flush */ + writel_relaxed(FFCR_FON_MAN, drvdata->base + TPIU_FFCR); + + CS_LOCK(drvdata->base); +} + +static void tpiu_disable(struct coresight_device *csdev) +{ + struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + tpiu_disable_hw(drvdata); + + clk_disable_unprepare(drvdata->clk); + + dev_info(drvdata->dev, "TPIU disabled\n"); +} + +static const struct coresight_ops_sink tpiu_sink_ops = { + .enable = tpiu_enable, + .disable = tpiu_disable, +}; + +static const struct coresight_ops tpiu_cs_ops = { + .sink_ops = &tpiu_sink_ops, +}; + +static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + void __iomem *base; + struct device *dev = &adev->dev; + struct coresight_platform_data *pdata = NULL; + struct tpiu_drvdata *drvdata; + struct resource *res = &adev->res; + struct coresight_desc *desc; + struct device_node *np = adev->dev.of_node; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + + drvdata->clk = adev->pclk; + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + /* Disable tpiu to support older devices */ + tpiu_disable_hw(drvdata); + + clk_disable_unprepare(drvdata->clk); + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->type = CORESIGHT_DEV_TYPE_SINK; + desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT; + desc->ops = &tpiu_cs_ops; + desc->pdata = pdata; + desc->dev = dev; + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + dev_info(dev, "TPIU initialized\n"); + return 0; +} + +static int tpiu_remove(struct amba_device *adev) +{ + struct tpiu_drvdata *drvdata = amba_get_drvdata(adev); + + coresight_unregister(drvdata->csdev); + return 0; +} + +static struct amba_id tpiu_ids[] = { + { + .id = 0x0003b912, + .mask = 0x0003ffff, + }, + { 0, 0}, +}; + +static struct amba_driver tpiu_driver = { + .drv = { + .name = "coresight-tpiu", + .owner = THIS_MODULE, + }, + .probe = tpiu_probe, + .remove = tpiu_remove, + .id_table = tpiu_ids, +}; + +static int __init tpiu_init(void) +{ + return amba_driver_register(&tpiu_driver); +} +module_init(tpiu_init); + +static void __exit tpiu_exit(void) +{ + amba_driver_unregister(&tpiu_driver); +} +module_exit(tpiu_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Trace Port Interface Unit driver"); -- GitLab From fdfc0d8a06b56c3ca8fc3d7d271b3c8e99e6d55c Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:38 -0700 Subject: [PATCH 3966/9457] coresight-etb: add CoreSight ETB driver This driver manages CoreSight ETB (Embedded Trace Buffer) which acts as a circular buffer sink collecting generated trace data. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig.debug | 8 + drivers/coresight/Makefile | 1 + drivers/coresight/coresight-etb10.c | 537 ++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+) create mode 100644 drivers/coresight/coresight-etb10.c diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 4815efbbb55d..db6717079e31 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1368,5 +1368,13 @@ config CORESIGHT_SINK_TPIU for bridging the gap between the on-chip coresight components and a trace port collection engine, typically connected to an external host for use case capturing more traces than the on-board coresight memory can handle. + +config CORESIGHT_SINK_ETBV10 + bool "Coresight ETBv1.0 driver" + depends on CORESIGHT_LINKS_AND_SINKS + help + This enables support for the Embedded Trace Buffer version 1.0 driver + that complies with the generic implementation of the component without + special enhancement or added features. endif endmenu diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index 41ab769b4822..4c43dade4c14 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_CORESIGHT) += coresight.o obj-$(CONFIG_OF) += of_coresight.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o +obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o diff --git a/drivers/coresight/coresight-etb10.c b/drivers/coresight/coresight-etb10.c new file mode 100644 index 000000000000..c922d4aded8a --- /dev/null +++ b/drivers/coresight/coresight-etb10.c @@ -0,0 +1,537 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +#define ETB_RAM_DEPTH_REG 0x004 +#define ETB_STATUS_REG 0x00c +#define ETB_RAM_READ_DATA_REG 0x010 +#define ETB_RAM_READ_POINTER 0x014 +#define ETB_RAM_WRITE_POINTER 0x018 +#define ETB_TRG 0x01c +#define ETB_CTL_REG 0x020 +#define ETB_RWD_REG 0x024 +#define ETB_FFSR 0x300 +#define ETB_FFCR 0x304 +#define ETB_ITMISCOP0 0xee0 +#define ETB_ITTRFLINACK 0xee4 +#define ETB_ITTRFLIN 0xee8 +#define ETB_ITATBDATA0 0xeeC +#define ETB_ITATBCTR2 0xef0 +#define ETB_ITATBCTR1 0xef4 +#define ETB_ITATBCTR0 0xef8 + +/* register description */ +/* STS - 0x00C */ +#define ETB_STATUS_RAM_FULL BIT(0) +/* CTL - 0x020 */ +#define ETB_CTL_CAPT_EN BIT(0) +/* FFCR - 0x304 */ +#define ETB_FFCR_EN_FTC BIT(0) +#define ETB_FFCR_FON_MAN BIT(6) +#define ETB_FFCR_STOP_FI BIT(12) +#define ETB_FFCR_STOP_TRIGGER BIT(13) + +#define ETB_FFCR_BIT 6 +#define ETB_FFSR_BIT 1 +#define ETB_FRAME_SIZE_WORDS 4 + +/** + * struct etb_drvdata - specifics associated to an ETB component + * @base: memory mapped base address for this component. + * @dev: the device entity associated to this component. + * @csdev: component vitals needed by the framework. + * @miscdev: specifics to handle "/dev/xyz.etb" entry. + * @clk: the clock this component is associated to. + * @spinlock: only one at a time pls. + * @in_use: synchronise user space access to etb buffer. + * @buf: area of memory where ETB buffer content gets sent. + * @buffer_depth: size of @buf. + * @enable: this ETB is being used. + * @trigger_cntr: amount of words to store after a trigger. + */ +struct etb_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + struct miscdevice miscdev; + struct clk *clk; + spinlock_t spinlock; + atomic_t in_use; + u8 *buf; + u32 buffer_depth; + bool enable; + u32 trigger_cntr; +}; + +static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata) +{ + int ret; + u32 depth = 0; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + /* RO registers don't need locking */ + depth = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG); + + clk_disable_unprepare(drvdata->clk); + return depth; +} + +static void etb_enable_hw(struct etb_drvdata *drvdata) +{ + int i; + u32 depth; + + CS_UNLOCK(drvdata->base); + + depth = drvdata->buffer_depth; + /* reset write RAM pointer address */ + writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); + /* clear entire RAM buffer */ + for (i = 0; i < depth; i++) + writel_relaxed(0x0, drvdata->base + ETB_RWD_REG); + + /* reset write RAM pointer address */ + writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); + /* reset read RAM pointer address */ + writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); + + writel_relaxed(drvdata->trigger_cntr, drvdata->base + ETB_TRG); + writel_relaxed(ETB_FFCR_EN_FTC | ETB_FFCR_STOP_TRIGGER, + drvdata->base + ETB_FFCR); + /* ETB trace capture enable */ + writel_relaxed(ETB_CTL_CAPT_EN, drvdata->base + ETB_CTL_REG); + + CS_LOCK(drvdata->base); +} + +static int etb_enable(struct coresight_device *csdev) +{ + struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret; + unsigned long flags; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + etb_enable_hw(drvdata); + drvdata->enable = true; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + dev_info(drvdata->dev, "ETB enabled\n"); + return 0; +} + +static void etb_disable_hw(struct etb_drvdata *drvdata) +{ + u32 ffcr; + + CS_UNLOCK(drvdata->base); + + ffcr = readl_relaxed(drvdata->base + ETB_FFCR); + /* stop formatter when a stop has completed */ + ffcr |= ETB_FFCR_STOP_FI; + writel_relaxed(ffcr, drvdata->base + ETB_FFCR); + /* manually generate a flush of the system */ + ffcr |= ETB_FFCR_FON_MAN; + writel_relaxed(ffcr, drvdata->base + ETB_FFCR); + + if (coresight_timeout(drvdata->base, ETB_FFCR, ETB_FFCR_BIT, 0)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", + ETB_FFCR); + } + + /* disable trace capture */ + writel_relaxed(0x0, drvdata->base + ETB_CTL_REG); + + if (coresight_timeout(drvdata->base, ETB_FFSR, ETB_FFSR_BIT, 1)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", + ETB_FFCR); + } + + CS_LOCK(drvdata->base); +} + +static void etb_dump_hw(struct etb_drvdata *drvdata) +{ + int i; + u8 *buf_ptr; + u32 read_data, depth; + u32 read_ptr, write_ptr; + u32 frame_off, frame_endoff; + + CS_UNLOCK(drvdata->base); + + read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); + write_ptr = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER); + + frame_off = write_ptr % ETB_FRAME_SIZE_WORDS; + frame_endoff = ETB_FRAME_SIZE_WORDS - frame_off; + if (frame_off) { + dev_err(drvdata->dev, + "write_ptr: %lu not aligned to formatter frame size\n", + (unsigned long)write_ptr); + dev_err(drvdata->dev, "frameoff: %lu, frame_endoff: %lu\n", + (unsigned long)frame_off, (unsigned long)frame_endoff); + write_ptr += frame_endoff; + } + + if ((readl_relaxed(drvdata->base + ETB_STATUS_REG) + & ETB_STATUS_RAM_FULL) == 0) + writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); + else + writel_relaxed(write_ptr, drvdata->base + ETB_RAM_READ_POINTER); + + depth = drvdata->buffer_depth; + buf_ptr = drvdata->buf; + for (i = 0; i < depth; i++) { + read_data = readl_relaxed(drvdata->base + + ETB_RAM_READ_DATA_REG); + *buf_ptr++ = read_data >> 0; + *buf_ptr++ = read_data >> 8; + *buf_ptr++ = read_data >> 16; + *buf_ptr++ = read_data >> 24; + } + + if (frame_off) { + buf_ptr -= (frame_endoff * 4); + for (i = 0; i < frame_endoff; i++) { + *buf_ptr++ = 0x0; + *buf_ptr++ = 0x0; + *buf_ptr++ = 0x0; + *buf_ptr++ = 0x0; + } + } + + writel_relaxed(read_ptr, drvdata->base + ETB_RAM_READ_POINTER); + + CS_LOCK(drvdata->base); +} + +static void etb_disable(struct coresight_device *csdev) +{ + struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + + spin_lock_irqsave(&drvdata->spinlock, flags); + etb_disable_hw(drvdata); + etb_dump_hw(drvdata); + drvdata->enable = false; + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + clk_disable_unprepare(drvdata->clk); + + dev_info(drvdata->dev, "ETB disabled\n"); +} + +static const struct coresight_ops_sink etb_sink_ops = { + .enable = etb_enable, + .disable = etb_disable, +}; + +static const struct coresight_ops etb_cs_ops = { + .sink_ops = &etb_sink_ops, +}; + +static void etb_dump(struct etb_drvdata *drvdata) +{ + unsigned long flags; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (drvdata->enable) { + etb_disable_hw(drvdata); + etb_dump_hw(drvdata); + etb_enable_hw(drvdata); + } + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + dev_info(drvdata->dev, "ETB dumped\n"); +} + +static int etb_open(struct inode *inode, struct file *file) +{ + struct etb_drvdata *drvdata = container_of(file->private_data, + struct etb_drvdata, miscdev); + + if (atomic_cmpxchg(&drvdata->in_use, 0, 1)) + return -EBUSY; + + dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__); + return 0; +} + +static ssize_t etb_read(struct file *file, char __user *data, + size_t len, loff_t *ppos) +{ + u32 depth; + struct etb_drvdata *drvdata = container_of(file->private_data, + struct etb_drvdata, miscdev); + + etb_dump(drvdata); + + depth = drvdata->buffer_depth; + if (*ppos + len > depth * 4) + len = depth * 4 - *ppos; + + if (copy_to_user(data, drvdata->buf + *ppos, len)) { + dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__); + return -EFAULT; + } + + *ppos += len; + + dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n", + __func__, len, (int) (depth * 4 - *ppos)); + return len; +} + +static int etb_release(struct inode *inode, struct file *file) +{ + struct etb_drvdata *drvdata = container_of(file->private_data, + struct etb_drvdata, miscdev); + atomic_set(&drvdata->in_use, 0); + + dev_dbg(drvdata->dev, "%s: released\n", __func__); + return 0; +} + +static const struct file_operations etb_fops = { + .owner = THIS_MODULE, + .open = etb_open, + .read = etb_read, + .release = etb_release, + .llseek = no_llseek, +}; + +static ssize_t status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned long flags; + u32 etb_rdr, etb_sr, etb_rrp, etb_rwp; + u32 etb_trg, etb_cr, etb_ffsr, etb_ffcr; + struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + goto out; + + spin_lock_irqsave(&drvdata->spinlock, flags); + CS_UNLOCK(drvdata->base); + + etb_rdr = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG); + etb_sr = readl_relaxed(drvdata->base + ETB_STATUS_REG); + etb_rrp = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); + etb_rwp = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER); + etb_trg = readl_relaxed(drvdata->base + ETB_TRG); + etb_cr = readl_relaxed(drvdata->base + ETB_CTL_REG); + etb_ffsr = readl_relaxed(drvdata->base + ETB_FFSR); + etb_ffcr = readl_relaxed(drvdata->base + ETB_FFCR); + + CS_LOCK(drvdata->base); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + clk_disable_unprepare(drvdata->clk); + + return sprintf(buf, + "Depth:\t\t0x%x\n" + "Status:\t\t0x%x\n" + "RAM read ptr:\t0x%x\n" + "RAM wrt ptr:\t0x%x\n" + "Trigger cnt:\t0x%x\n" + "Control:\t0x%x\n" + "Flush status:\t0x%x\n" + "Flush ctrl:\t0x%x\n", + etb_rdr, etb_sr, etb_rrp, etb_rwp, + etb_trg, etb_cr, etb_ffsr, etb_ffcr); +out: + return -EINVAL; +} +static DEVICE_ATTR_RO(status); + +static ssize_t trigger_cntr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val = drvdata->trigger_cntr; + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t trigger_cntr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->trigger_cntr = val; + return size; +} +static DEVICE_ATTR_RW(trigger_cntr); + +static struct attribute *coresight_etb_attrs[] = { + &dev_attr_trigger_cntr.attr, + &dev_attr_status.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_etb); + +static int etb_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + void __iomem *base; + struct device *dev = &adev->dev; + struct coresight_platform_data *pdata = NULL; + struct etb_drvdata *drvdata; + struct resource *res = &adev->res; + struct coresight_desc *desc; + struct device_node *np = adev->dev.of_node; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + /* validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + + spin_lock_init(&drvdata->spinlock); + + drvdata->clk = adev->pclk; + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + drvdata->buffer_depth = etb_get_buffer_depth(drvdata); + clk_disable_unprepare(drvdata->clk); + + if (drvdata->buffer_depth < 0) + return -EINVAL; + + drvdata->buf = devm_kzalloc(dev, + drvdata->buffer_depth * 4, GFP_KERNEL); + if (!drvdata->buf) + return -ENOMEM; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->type = CORESIGHT_DEV_TYPE_SINK; + desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; + desc->ops = &etb_cs_ops; + desc->pdata = pdata; + desc->dev = dev; + desc->groups = coresight_etb_groups; + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + drvdata->miscdev.name = pdata->name; + drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; + drvdata->miscdev.fops = &etb_fops; + ret = misc_register(&drvdata->miscdev); + if (ret) + goto err_misc_register; + + dev_info(dev, "ETB initialized\n"); + return 0; + +err_misc_register: + coresight_unregister(drvdata->csdev); + return ret; +} + +static int etb_remove(struct amba_device *adev) +{ + struct etb_drvdata *drvdata = amba_get_drvdata(adev); + + misc_deregister(&drvdata->miscdev); + coresight_unregister(drvdata->csdev); + return 0; +} + +static struct amba_id etb_ids[] = { + { + .id = 0x0003b907, + .mask = 0x0003ffff, + }, + { 0, 0}, +}; + +static struct amba_driver etb_driver = { + .drv = { + .name = "coresight-etb10", + .owner = THIS_MODULE, + }, + .probe = etb_probe, + .remove = etb_remove, + .id_table = etb_ids, +}; + +static int __init etb_init(void) +{ + return amba_driver_register(&etb_driver); +} +module_init(etb_init); + +static void __exit etb_exit(void) +{ + amba_driver_unregister(&etb_driver); +} +module_exit(etb_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver"); -- GitLab From 6e21e3451556af6ada01e2206d5949fc654d75e1 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:39 -0700 Subject: [PATCH 3967/9457] coresight-funnel: add CoreSight Funnel driver This driver manages CoreSight Funnel which acts as a link. Funnels have multiple input ports (typically 8) each of which represents an input trace data stream. These multiple input trace data streams are interleaved into a single output stream coming out of the Funnel. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/coresight/Makefile | 1 + drivers/coresight/coresight-funnel.c | 268 +++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 drivers/coresight/coresight-funnel.c diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index 4c43dade4c14..05b8a1c75f73 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_OF) += of_coresight.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o +obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o diff --git a/drivers/coresight/coresight-funnel.c b/drivers/coresight/coresight-funnel.c new file mode 100644 index 000000000000..2108edffe1f4 --- /dev/null +++ b/drivers/coresight/coresight-funnel.c @@ -0,0 +1,268 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +#define FUNNEL_FUNCTL 0x000 +#define FUNNEL_PRICTL 0x004 + +#define FUNNEL_HOLDTIME_MASK 0xf00 +#define FUNNEL_HOLDTIME_SHFT 0x8 +#define FUNNEL_HOLDTIME (0x7 << FUNNEL_HOLDTIME_SHFT) + +/** + * struct funnel_drvdata - specifics associated to a funnel component + * @base: memory mapped base address for this component. + * @dev: the device entity associated to this component. + * @csdev: component vitals needed by the framework. + * @clk: the clock this component is associated to. + * @priority: port selection order. + */ +struct funnel_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + struct clk *clk; + unsigned long priority; +}; + +static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port) +{ + u32 functl; + + CS_UNLOCK(drvdata->base); + + functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); + functl &= ~FUNNEL_HOLDTIME_MASK; + functl |= FUNNEL_HOLDTIME; + functl |= (1 << port); + writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); + writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL); + + CS_LOCK(drvdata->base); +} + +static int funnel_enable(struct coresight_device *csdev, int inport, + int outport) +{ + struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + funnel_enable_hw(drvdata, inport); + + dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport); + return 0; +} + +static void funnel_disable_hw(struct funnel_drvdata *drvdata, int inport) +{ + u32 functl; + + CS_UNLOCK(drvdata->base); + + functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); + functl &= ~(1 << inport); + writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); + + CS_LOCK(drvdata->base); +} + +static void funnel_disable(struct coresight_device *csdev, int inport, + int outport) +{ + struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + funnel_disable_hw(drvdata, inport); + + clk_disable_unprepare(drvdata->clk); + + dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport); +} + +static const struct coresight_ops_link funnel_link_ops = { + .enable = funnel_enable, + .disable = funnel_disable, +}; + +static const struct coresight_ops funnel_cs_ops = { + .link_ops = &funnel_link_ops, +}; + +static ssize_t priority_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val = drvdata->priority; + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t priority_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->priority = val; + return size; +} +static DEVICE_ATTR_RW(priority); + +static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata) +{ + u32 functl; + + CS_UNLOCK(drvdata->base); + functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); + CS_LOCK(drvdata->base); + + return functl; +} + +static ssize_t funnel_ctrl_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + u32 val; + struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + val = get_funnel_ctrl_hw(drvdata); + clk_disable_unprepare(drvdata->clk); + + return sprintf(buf, "%#x\n", val); +} +static DEVICE_ATTR_RO(funnel_ctrl); + +static struct attribute *coresight_funnel_attrs[] = { + &dev_attr_funnel_ctrl.attr, + &dev_attr_priority.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_funnel); + +static int funnel_probe(struct amba_device *adev, const struct amba_id *id) +{ + void __iomem *base; + struct device *dev = &adev->dev; + struct coresight_platform_data *pdata = NULL; + struct funnel_drvdata *drvdata; + struct resource *res = &adev->res; + struct coresight_desc *desc; + struct device_node *np = adev->dev.of_node; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + + drvdata->clk = adev->pclk; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->type = CORESIGHT_DEV_TYPE_LINK; + desc->subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; + desc->ops = &funnel_cs_ops; + desc->pdata = pdata; + desc->dev = dev; + desc->groups = coresight_funnel_groups; + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + dev_info(dev, "FUNNEL initialized\n"); + return 0; +} + +static int funnel_remove(struct amba_device *adev) +{ + struct funnel_drvdata *drvdata = amba_get_drvdata(adev); + + coresight_unregister(drvdata->csdev); + return 0; +} + +static struct amba_id funnel_ids[] = { + { + .id = 0x0003b908, + .mask = 0x0003ffff, + }, + { 0, 0}, +}; + +static struct amba_driver funnel_driver = { + .drv = { + .name = "coresight-funnel", + .owner = THIS_MODULE, + }, + .probe = funnel_probe, + .remove = funnel_remove, + .id_table = funnel_ids, +}; + +static int __init funnel_init(void) +{ + return amba_driver_register(&funnel_driver); +} +module_init(funnel_init); + +static void __exit funnel_exit(void) +{ + amba_driver_unregister(&funnel_driver); +} +module_exit(funnel_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Funnel driver"); -- GitLab From ceacc1d9b7ae41e4be185596306be17537682fb1 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:40 -0700 Subject: [PATCH 3968/9457] coresight-replicator: add CoreSight Replicator driver This driver manages non-configurable CoreSight Replicator that takes a single input trace data stream and replicates it to produce two identical trace data output streams. Replicators are typically used to route single interleaved trace data stream to two or more sinks. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/coresight/Makefile | 3 +- drivers/coresight/coresight-replicator.c | 138 +++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 drivers/coresight/coresight-replicator.c diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index 05b8a1c75f73..574d5fa496fa 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_OF) += of_coresight.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o -obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o +obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \ + coresight-replicator.o diff --git a/drivers/coresight/coresight-replicator.c b/drivers/coresight/coresight-replicator.c new file mode 100644 index 000000000000..c879039d59cc --- /dev/null +++ b/drivers/coresight/coresight-replicator.c @@ -0,0 +1,138 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +/** + * struct replicator_drvdata - specifics associated to a replicator component + * @dev: the device entity associated with this component + * @csdev: component vitals needed by the framework + */ +struct replicator_drvdata { + struct device *dev; + struct coresight_device *csdev; +}; + +static int replicator_enable(struct coresight_device *csdev, int inport, + int outport) +{ + struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + dev_info(drvdata->dev, "REPLICATOR enabled\n"); + return 0; +} + +static void replicator_disable(struct coresight_device *csdev, int inport, + int outport) +{ + struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + dev_info(drvdata->dev, "REPLICATOR disabled\n"); +} + +static const struct coresight_ops_link replicator_link_ops = { + .enable = replicator_enable, + .disable = replicator_disable, +}; + +static const struct coresight_ops replicator_cs_ops = { + .link_ops = &replicator_link_ops, +}; + +static int replicator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct coresight_platform_data *pdata = NULL; + struct replicator_drvdata *drvdata; + struct coresight_desc *desc; + struct device_node *np = pdev->dev.of_node; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + pdev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &pdev->dev; + platform_set_drvdata(pdev, drvdata); + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->type = CORESIGHT_DEV_TYPE_LINK; + desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; + desc->ops = &replicator_cs_ops; + desc->pdata = pdev->dev.platform_data; + desc->dev = &pdev->dev; + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + dev_info(dev, "REPLICATOR initialized\n"); + return 0; +} + +static int replicator_remove(struct platform_device *pdev) +{ + struct replicator_drvdata *drvdata = platform_get_drvdata(pdev); + + coresight_unregister(drvdata->csdev); + return 0; +} + +static struct of_device_id replicator_match[] = { + {.compatible = "arm,coresight-replicator"}, + {} +}; + +static struct platform_driver replicator_driver = { + .probe = replicator_probe, + .remove = replicator_remove, + .driver = { + .name = "coresight-replicator", + .owner = THIS_MODULE, + .of_match_table = replicator_match, + }, +}; + +static int __init replicator_init(void) +{ + return platform_driver_register(&replicator_driver); +} +module_init(replicator_init); + +static void __exit replicator_exit(void) +{ + platform_driver_unregister(&replicator_driver); +} +module_exit(replicator_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Replicator driver"); -- GitLab From a939fc5a71ad531633610242400c262e78731532 Mon Sep 17 00:00:00 2001 From: Pratik Patel Date: Mon, 3 Nov 2014 11:07:41 -0700 Subject: [PATCH 3969/9457] coresight-etm: add CoreSight ETM/PTM driver This driver manages CoreSight ETM (Embedded Trace Macrocell) that supports processor tracing. Currently supported version are ARM ETMv3.x and PTM1.x. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier coresight-etm3x: adding missing error checking Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig.debug | 9 + arch/arm/include/asm/hardware/cp14.h | 542 +++++++ drivers/coresight/Makefile | 1 + drivers/coresight/coresight-etm-cp14.c | 591 ++++++++ drivers/coresight/coresight-etm.h | 251 +++ drivers/coresight/coresight-etm3x.c | 1928 ++++++++++++++++++++++++ 6 files changed, 3322 insertions(+) create mode 100644 arch/arm/include/asm/hardware/cp14.h create mode 100644 drivers/coresight/coresight-etm-cp14.c create mode 100644 drivers/coresight/coresight-etm.h create mode 100644 drivers/coresight/coresight-etm3x.c diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index db6717079e31..871404bc9e47 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1376,5 +1376,14 @@ config CORESIGHT_SINK_ETBV10 This enables support for the Embedded Trace Buffer version 1.0 driver that complies with the generic implementation of the component without special enhancement or added features. + +config CORESIGHT_SOURCE_ETM3X + bool "CoreSight Embedded Trace Macrocell 3.x driver" + select CORESIGHT_LINKS_AND_SINKS + help + This driver provides support for processor ETM3.x and PTM1.x modules, + which allows tracing the instructions that a processor is executing + This is primarily useful for instruction level tracing. Depending + the ETM version data tracing may also be available. endif endmenu diff --git a/arch/arm/include/asm/hardware/cp14.h b/arch/arm/include/asm/hardware/cp14.h new file mode 100644 index 000000000000..61576dc58ede --- /dev/null +++ b/arch/arm/include/asm/hardware/cp14.h @@ -0,0 +1,542 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_HARDWARE_CP14_H +#define __ASM_HARDWARE_CP14_H + +#include + +/* Accessors for CP14 registers */ +#define dbg_read(reg) RCP14_##reg() +#define dbg_write(val, reg) WCP14_##reg(val) +#define etm_read(reg) RCP14_##reg() +#define etm_write(val, reg) WCP14_##reg(val) + +/* MRC14 and MCR14 */ +#define MRC14(op1, crn, crm, op2) \ +({ \ +u32 val; \ +asm volatile("mrc p14, "#op1", %0, "#crn", "#crm", "#op2 : "=r" (val)); \ +val; \ +}) + +#define MCR14(val, op1, crn, crm, op2) \ +({ \ +asm volatile("mcr p14, "#op1", %0, "#crn", "#crm", "#op2 : : "r" (val));\ +}) + +/* + * Debug Registers + * + * Available only in DBGv7 + * DBGECR, DBGDSCCR, DBGDSMCR, DBGDRCR + * + * Available only in DBGv7.1 + * DBGBXVRm, DBGOSDLR, DBGDEVID2, DBGDEVID1 + * + * Read only + * DBGDIDR, DBGDSCRint, DBGDTRRXint, DBGDRAR, DBGOSLSR, DBGOSSRR, DBGPRSR, + * DBGPRSR, DBGDSAR, DBGAUTHSTATUS, DBGDEVID2, DBGDEVID1, DBGDEVID + * + * Write only + * DBGDTRTXint, DBGOSLAR + */ +#define RCP14_DBGDIDR() MRC14(0, c0, c0, 0) +#define RCP14_DBGDSCRint() MRC14(0, c0, c1, 0) +#define RCP14_DBGDTRRXint() MRC14(0, c0, c5, 0) +#define RCP14_DBGWFAR() MRC14(0, c0, c6, 0) +#define RCP14_DBGVCR() MRC14(0, c0, c7, 0) +#define RCP14_DBGECR() MRC14(0, c0, c9, 0) +#define RCP14_DBGDSCCR() MRC14(0, c0, c10, 0) +#define RCP14_DBGDSMCR() MRC14(0, c0, c11, 0) +#define RCP14_DBGDTRRXext() MRC14(0, c0, c0, 2) +#define RCP14_DBGDSCRext() MRC14(0, c0, c2, 2) +#define RCP14_DBGDTRTXext() MRC14(0, c0, c3, 2) +#define RCP14_DBGDRCR() MRC14(0, c0, c4, 2) +#define RCP14_DBGBVR0() MRC14(0, c0, c0, 4) +#define RCP14_DBGBVR1() MRC14(0, c0, c1, 4) +#define RCP14_DBGBVR2() MRC14(0, c0, c2, 4) +#define RCP14_DBGBVR3() MRC14(0, c0, c3, 4) +#define RCP14_DBGBVR4() MRC14(0, c0, c4, 4) +#define RCP14_DBGBVR5() MRC14(0, c0, c5, 4) +#define RCP14_DBGBVR6() MRC14(0, c0, c6, 4) +#define RCP14_DBGBVR7() MRC14(0, c0, c7, 4) +#define RCP14_DBGBVR8() MRC14(0, c0, c8, 4) +#define RCP14_DBGBVR9() MRC14(0, c0, c9, 4) +#define RCP14_DBGBVR10() MRC14(0, c0, c10, 4) +#define RCP14_DBGBVR11() MRC14(0, c0, c11, 4) +#define RCP14_DBGBVR12() MRC14(0, c0, c12, 4) +#define RCP14_DBGBVR13() MRC14(0, c0, c13, 4) +#define RCP14_DBGBVR14() MRC14(0, c0, c14, 4) +#define RCP14_DBGBVR15() MRC14(0, c0, c15, 4) +#define RCP14_DBGBCR0() MRC14(0, c0, c0, 5) +#define RCP14_DBGBCR1() MRC14(0, c0, c1, 5) +#define RCP14_DBGBCR2() MRC14(0, c0, c2, 5) +#define RCP14_DBGBCR3() MRC14(0, c0, c3, 5) +#define RCP14_DBGBCR4() MRC14(0, c0, c4, 5) +#define RCP14_DBGBCR5() MRC14(0, c0, c5, 5) +#define RCP14_DBGBCR6() MRC14(0, c0, c6, 5) +#define RCP14_DBGBCR7() MRC14(0, c0, c7, 5) +#define RCP14_DBGBCR8() MRC14(0, c0, c8, 5) +#define RCP14_DBGBCR9() MRC14(0, c0, c9, 5) +#define RCP14_DBGBCR10() MRC14(0, c0, c10, 5) +#define RCP14_DBGBCR11() MRC14(0, c0, c11, 5) +#define RCP14_DBGBCR12() MRC14(0, c0, c12, 5) +#define RCP14_DBGBCR13() MRC14(0, c0, c13, 5) +#define RCP14_DBGBCR14() MRC14(0, c0, c14, 5) +#define RCP14_DBGBCR15() MRC14(0, c0, c15, 5) +#define RCP14_DBGWVR0() MRC14(0, c0, c0, 6) +#define RCP14_DBGWVR1() MRC14(0, c0, c1, 6) +#define RCP14_DBGWVR2() MRC14(0, c0, c2, 6) +#define RCP14_DBGWVR3() MRC14(0, c0, c3, 6) +#define RCP14_DBGWVR4() MRC14(0, c0, c4, 6) +#define RCP14_DBGWVR5() MRC14(0, c0, c5, 6) +#define RCP14_DBGWVR6() MRC14(0, c0, c6, 6) +#define RCP14_DBGWVR7() MRC14(0, c0, c7, 6) +#define RCP14_DBGWVR8() MRC14(0, c0, c8, 6) +#define RCP14_DBGWVR9() MRC14(0, c0, c9, 6) +#define RCP14_DBGWVR10() MRC14(0, c0, c10, 6) +#define RCP14_DBGWVR11() MRC14(0, c0, c11, 6) +#define RCP14_DBGWVR12() MRC14(0, c0, c12, 6) +#define RCP14_DBGWVR13() MRC14(0, c0, c13, 6) +#define RCP14_DBGWVR14() MRC14(0, c0, c14, 6) +#define RCP14_DBGWVR15() MRC14(0, c0, c15, 6) +#define RCP14_DBGWCR0() MRC14(0, c0, c0, 7) +#define RCP14_DBGWCR1() MRC14(0, c0, c1, 7) +#define RCP14_DBGWCR2() MRC14(0, c0, c2, 7) +#define RCP14_DBGWCR3() MRC14(0, c0, c3, 7) +#define RCP14_DBGWCR4() MRC14(0, c0, c4, 7) +#define RCP14_DBGWCR5() MRC14(0, c0, c5, 7) +#define RCP14_DBGWCR6() MRC14(0, c0, c6, 7) +#define RCP14_DBGWCR7() MRC14(0, c0, c7, 7) +#define RCP14_DBGWCR8() MRC14(0, c0, c8, 7) +#define RCP14_DBGWCR9() MRC14(0, c0, c9, 7) +#define RCP14_DBGWCR10() MRC14(0, c0, c10, 7) +#define RCP14_DBGWCR11() MRC14(0, c0, c11, 7) +#define RCP14_DBGWCR12() MRC14(0, c0, c12, 7) +#define RCP14_DBGWCR13() MRC14(0, c0, c13, 7) +#define RCP14_DBGWCR14() MRC14(0, c0, c14, 7) +#define RCP14_DBGWCR15() MRC14(0, c0, c15, 7) +#define RCP14_DBGDRAR() MRC14(0, c1, c0, 0) +#define RCP14_DBGBXVR0() MRC14(0, c1, c0, 1) +#define RCP14_DBGBXVR1() MRC14(0, c1, c1, 1) +#define RCP14_DBGBXVR2() MRC14(0, c1, c2, 1) +#define RCP14_DBGBXVR3() MRC14(0, c1, c3, 1) +#define RCP14_DBGBXVR4() MRC14(0, c1, c4, 1) +#define RCP14_DBGBXVR5() MRC14(0, c1, c5, 1) +#define RCP14_DBGBXVR6() MRC14(0, c1, c6, 1) +#define RCP14_DBGBXVR7() MRC14(0, c1, c7, 1) +#define RCP14_DBGBXVR8() MRC14(0, c1, c8, 1) +#define RCP14_DBGBXVR9() MRC14(0, c1, c9, 1) +#define RCP14_DBGBXVR10() MRC14(0, c1, c10, 1) +#define RCP14_DBGBXVR11() MRC14(0, c1, c11, 1) +#define RCP14_DBGBXVR12() MRC14(0, c1, c12, 1) +#define RCP14_DBGBXVR13() MRC14(0, c1, c13, 1) +#define RCP14_DBGBXVR14() MRC14(0, c1, c14, 1) +#define RCP14_DBGBXVR15() MRC14(0, c1, c15, 1) +#define RCP14_DBGOSLSR() MRC14(0, c1, c1, 4) +#define RCP14_DBGOSSRR() MRC14(0, c1, c2, 4) +#define RCP14_DBGOSDLR() MRC14(0, c1, c3, 4) +#define RCP14_DBGPRCR() MRC14(0, c1, c4, 4) +#define RCP14_DBGPRSR() MRC14(0, c1, c5, 4) +#define RCP14_DBGDSAR() MRC14(0, c2, c0, 0) +#define RCP14_DBGITCTRL() MRC14(0, c7, c0, 4) +#define RCP14_DBGCLAIMSET() MRC14(0, c7, c8, 6) +#define RCP14_DBGCLAIMCLR() MRC14(0, c7, c9, 6) +#define RCP14_DBGAUTHSTATUS() MRC14(0, c7, c14, 6) +#define RCP14_DBGDEVID2() MRC14(0, c7, c0, 7) +#define RCP14_DBGDEVID1() MRC14(0, c7, c1, 7) +#define RCP14_DBGDEVID() MRC14(0, c7, c2, 7) + +#define WCP14_DBGDTRTXint(val) MCR14(val, 0, c0, c5, 0) +#define WCP14_DBGWFAR(val) MCR14(val, 0, c0, c6, 0) +#define WCP14_DBGVCR(val) MCR14(val, 0, c0, c7, 0) +#define WCP14_DBGECR(val) MCR14(val, 0, c0, c9, 0) +#define WCP14_DBGDSCCR(val) MCR14(val, 0, c0, c10, 0) +#define WCP14_DBGDSMCR(val) MCR14(val, 0, c0, c11, 0) +#define WCP14_DBGDTRRXext(val) MCR14(val, 0, c0, c0, 2) +#define WCP14_DBGDSCRext(val) MCR14(val, 0, c0, c2, 2) +#define WCP14_DBGDTRTXext(val) MCR14(val, 0, c0, c3, 2) +#define WCP14_DBGDRCR(val) MCR14(val, 0, c0, c4, 2) +#define WCP14_DBGBVR0(val) MCR14(val, 0, c0, c0, 4) +#define WCP14_DBGBVR1(val) MCR14(val, 0, c0, c1, 4) +#define WCP14_DBGBVR2(val) MCR14(val, 0, c0, c2, 4) +#define WCP14_DBGBVR3(val) MCR14(val, 0, c0, c3, 4) +#define WCP14_DBGBVR4(val) MCR14(val, 0, c0, c4, 4) +#define WCP14_DBGBVR5(val) MCR14(val, 0, c0, c5, 4) +#define WCP14_DBGBVR6(val) MCR14(val, 0, c0, c6, 4) +#define WCP14_DBGBVR7(val) MCR14(val, 0, c0, c7, 4) +#define WCP14_DBGBVR8(val) MCR14(val, 0, c0, c8, 4) +#define WCP14_DBGBVR9(val) MCR14(val, 0, c0, c9, 4) +#define WCP14_DBGBVR10(val) MCR14(val, 0, c0, c10, 4) +#define WCP14_DBGBVR11(val) MCR14(val, 0, c0, c11, 4) +#define WCP14_DBGBVR12(val) MCR14(val, 0, c0, c12, 4) +#define WCP14_DBGBVR13(val) MCR14(val, 0, c0, c13, 4) +#define WCP14_DBGBVR14(val) MCR14(val, 0, c0, c14, 4) +#define WCP14_DBGBVR15(val) MCR14(val, 0, c0, c15, 4) +#define WCP14_DBGBCR0(val) MCR14(val, 0, c0, c0, 5) +#define WCP14_DBGBCR1(val) MCR14(val, 0, c0, c1, 5) +#define WCP14_DBGBCR2(val) MCR14(val, 0, c0, c2, 5) +#define WCP14_DBGBCR3(val) MCR14(val, 0, c0, c3, 5) +#define WCP14_DBGBCR4(val) MCR14(val, 0, c0, c4, 5) +#define WCP14_DBGBCR5(val) MCR14(val, 0, c0, c5, 5) +#define WCP14_DBGBCR6(val) MCR14(val, 0, c0, c6, 5) +#define WCP14_DBGBCR7(val) MCR14(val, 0, c0, c7, 5) +#define WCP14_DBGBCR8(val) MCR14(val, 0, c0, c8, 5) +#define WCP14_DBGBCR9(val) MCR14(val, 0, c0, c9, 5) +#define WCP14_DBGBCR10(val) MCR14(val, 0, c0, c10, 5) +#define WCP14_DBGBCR11(val) MCR14(val, 0, c0, c11, 5) +#define WCP14_DBGBCR12(val) MCR14(val, 0, c0, c12, 5) +#define WCP14_DBGBCR13(val) MCR14(val, 0, c0, c13, 5) +#define WCP14_DBGBCR14(val) MCR14(val, 0, c0, c14, 5) +#define WCP14_DBGBCR15(val) MCR14(val, 0, c0, c15, 5) +#define WCP14_DBGWVR0(val) MCR14(val, 0, c0, c0, 6) +#define WCP14_DBGWVR1(val) MCR14(val, 0, c0, c1, 6) +#define WCP14_DBGWVR2(val) MCR14(val, 0, c0, c2, 6) +#define WCP14_DBGWVR3(val) MCR14(val, 0, c0, c3, 6) +#define WCP14_DBGWVR4(val) MCR14(val, 0, c0, c4, 6) +#define WCP14_DBGWVR5(val) MCR14(val, 0, c0, c5, 6) +#define WCP14_DBGWVR6(val) MCR14(val, 0, c0, c6, 6) +#define WCP14_DBGWVR7(val) MCR14(val, 0, c0, c7, 6) +#define WCP14_DBGWVR8(val) MCR14(val, 0, c0, c8, 6) +#define WCP14_DBGWVR9(val) MCR14(val, 0, c0, c9, 6) +#define WCP14_DBGWVR10(val) MCR14(val, 0, c0, c10, 6) +#define WCP14_DBGWVR11(val) MCR14(val, 0, c0, c11, 6) +#define WCP14_DBGWVR12(val) MCR14(val, 0, c0, c12, 6) +#define WCP14_DBGWVR13(val) MCR14(val, 0, c0, c13, 6) +#define WCP14_DBGWVR14(val) MCR14(val, 0, c0, c14, 6) +#define WCP14_DBGWVR15(val) MCR14(val, 0, c0, c15, 6) +#define WCP14_DBGWCR0(val) MCR14(val, 0, c0, c0, 7) +#define WCP14_DBGWCR1(val) MCR14(val, 0, c0, c1, 7) +#define WCP14_DBGWCR2(val) MCR14(val, 0, c0, c2, 7) +#define WCP14_DBGWCR3(val) MCR14(val, 0, c0, c3, 7) +#define WCP14_DBGWCR4(val) MCR14(val, 0, c0, c4, 7) +#define WCP14_DBGWCR5(val) MCR14(val, 0, c0, c5, 7) +#define WCP14_DBGWCR6(val) MCR14(val, 0, c0, c6, 7) +#define WCP14_DBGWCR7(val) MCR14(val, 0, c0, c7, 7) +#define WCP14_DBGWCR8(val) MCR14(val, 0, c0, c8, 7) +#define WCP14_DBGWCR9(val) MCR14(val, 0, c0, c9, 7) +#define WCP14_DBGWCR10(val) MCR14(val, 0, c0, c10, 7) +#define WCP14_DBGWCR11(val) MCR14(val, 0, c0, c11, 7) +#define WCP14_DBGWCR12(val) MCR14(val, 0, c0, c12, 7) +#define WCP14_DBGWCR13(val) MCR14(val, 0, c0, c13, 7) +#define WCP14_DBGWCR14(val) MCR14(val, 0, c0, c14, 7) +#define WCP14_DBGWCR15(val) MCR14(val, 0, c0, c15, 7) +#define WCP14_DBGBXVR0(val) MCR14(val, 0, c1, c0, 1) +#define WCP14_DBGBXVR1(val) MCR14(val, 0, c1, c1, 1) +#define WCP14_DBGBXVR2(val) MCR14(val, 0, c1, c2, 1) +#define WCP14_DBGBXVR3(val) MCR14(val, 0, c1, c3, 1) +#define WCP14_DBGBXVR4(val) MCR14(val, 0, c1, c4, 1) +#define WCP14_DBGBXVR5(val) MCR14(val, 0, c1, c5, 1) +#define WCP14_DBGBXVR6(val) MCR14(val, 0, c1, c6, 1) +#define WCP14_DBGBXVR7(val) MCR14(val, 0, c1, c7, 1) +#define WCP14_DBGBXVR8(val) MCR14(val, 0, c1, c8, 1) +#define WCP14_DBGBXVR9(val) MCR14(val, 0, c1, c9, 1) +#define WCP14_DBGBXVR10(val) MCR14(val, 0, c1, c10, 1) +#define WCP14_DBGBXVR11(val) MCR14(val, 0, c1, c11, 1) +#define WCP14_DBGBXVR12(val) MCR14(val, 0, c1, c12, 1) +#define WCP14_DBGBXVR13(val) MCR14(val, 0, c1, c13, 1) +#define WCP14_DBGBXVR14(val) MCR14(val, 0, c1, c14, 1) +#define WCP14_DBGBXVR15(val) MCR14(val, 0, c1, c15, 1) +#define WCP14_DBGOSLAR(val) MCR14(val, 0, c1, c0, 4) +#define WCP14_DBGOSSRR(val) MCR14(val, 0, c1, c2, 4) +#define WCP14_DBGOSDLR(val) MCR14(val, 0, c1, c3, 4) +#define WCP14_DBGPRCR(val) MCR14(val, 0, c1, c4, 4) +#define WCP14_DBGITCTRL(val) MCR14(val, 0, c7, c0, 4) +#define WCP14_DBGCLAIMSET(val) MCR14(val, 0, c7, c8, 6) +#define WCP14_DBGCLAIMCLR(val) MCR14(val, 0, c7, c9, 6) + +/* + * ETM Registers + * + * Available only in ETMv3.3, 3.4, 3.5 + * ETMASICCR, ETMTECR2, ETMFFRR, ETMVDEVR, ETMVDCR1, ETMVDCR2, ETMVDCR3, + * ETMDCVRn, ETMDCMRn + * + * Available only in ETMv3.5 as read only + * ETMIDR2 + * + * Available only in ETMv3.5, PFTv1.0, 1.1 + * ETMTSEVR, ETMVMIDCVR, ETMPDCR + * + * Read only + * ETMCCR, ETMSCR, ETMIDR, ETMCCER, ETMOSLSR + * ETMLSR, ETMAUTHSTATUS, ETMDEVID, ETMDEVTYPE, ETMPIDR4, ETMPIDR5, ETMPIDR6, + * ETMPIDR7, ETMPIDR0, ETMPIDR1, ETMPIDR2, ETMPIDR2, ETMPIDR3, ETMCIDR0, + * ETMCIDR1, ETMCIDR2, ETMCIDR3 + * + * Write only + * ETMOSLAR, ETMLAR + * Note: ETMCCER[11] controls WO nature of certain regs. Refer ETM arch spec. + */ +#define RCP14_ETMCR() MRC14(1, c0, c0, 0) +#define RCP14_ETMCCR() MRC14(1, c0, c1, 0) +#define RCP14_ETMTRIGGER() MRC14(1, c0, c2, 0) +#define RCP14_ETMASICCR() MRC14(1, c0, c3, 0) +#define RCP14_ETMSR() MRC14(1, c0, c4, 0) +#define RCP14_ETMSCR() MRC14(1, c0, c5, 0) +#define RCP14_ETMTSSCR() MRC14(1, c0, c6, 0) +#define RCP14_ETMTECR2() MRC14(1, c0, c7, 0) +#define RCP14_ETMTEEVR() MRC14(1, c0, c8, 0) +#define RCP14_ETMTECR1() MRC14(1, c0, c9, 0) +#define RCP14_ETMFFRR() MRC14(1, c0, c10, 0) +#define RCP14_ETMFFLR() MRC14(1, c0, c11, 0) +#define RCP14_ETMVDEVR() MRC14(1, c0, c12, 0) +#define RCP14_ETMVDCR1() MRC14(1, c0, c13, 0) +#define RCP14_ETMVDCR2() MRC14(1, c0, c14, 0) +#define RCP14_ETMVDCR3() MRC14(1, c0, c15, 0) +#define RCP14_ETMACVR0() MRC14(1, c0, c0, 1) +#define RCP14_ETMACVR1() MRC14(1, c0, c1, 1) +#define RCP14_ETMACVR2() MRC14(1, c0, c2, 1) +#define RCP14_ETMACVR3() MRC14(1, c0, c3, 1) +#define RCP14_ETMACVR4() MRC14(1, c0, c4, 1) +#define RCP14_ETMACVR5() MRC14(1, c0, c5, 1) +#define RCP14_ETMACVR6() MRC14(1, c0, c6, 1) +#define RCP14_ETMACVR7() MRC14(1, c0, c7, 1) +#define RCP14_ETMACVR8() MRC14(1, c0, c8, 1) +#define RCP14_ETMACVR9() MRC14(1, c0, c9, 1) +#define RCP14_ETMACVR10() MRC14(1, c0, c10, 1) +#define RCP14_ETMACVR11() MRC14(1, c0, c11, 1) +#define RCP14_ETMACVR12() MRC14(1, c0, c12, 1) +#define RCP14_ETMACVR13() MRC14(1, c0, c13, 1) +#define RCP14_ETMACVR14() MRC14(1, c0, c14, 1) +#define RCP14_ETMACVR15() MRC14(1, c0, c15, 1) +#define RCP14_ETMACTR0() MRC14(1, c0, c0, 2) +#define RCP14_ETMACTR1() MRC14(1, c0, c1, 2) +#define RCP14_ETMACTR2() MRC14(1, c0, c2, 2) +#define RCP14_ETMACTR3() MRC14(1, c0, c3, 2) +#define RCP14_ETMACTR4() MRC14(1, c0, c4, 2) +#define RCP14_ETMACTR5() MRC14(1, c0, c5, 2) +#define RCP14_ETMACTR6() MRC14(1, c0, c6, 2) +#define RCP14_ETMACTR7() MRC14(1, c0, c7, 2) +#define RCP14_ETMACTR8() MRC14(1, c0, c8, 2) +#define RCP14_ETMACTR9() MRC14(1, c0, c9, 2) +#define RCP14_ETMACTR10() MRC14(1, c0, c10, 2) +#define RCP14_ETMACTR11() MRC14(1, c0, c11, 2) +#define RCP14_ETMACTR12() MRC14(1, c0, c12, 2) +#define RCP14_ETMACTR13() MRC14(1, c0, c13, 2) +#define RCP14_ETMACTR14() MRC14(1, c0, c14, 2) +#define RCP14_ETMACTR15() MRC14(1, c0, c15, 2) +#define RCP14_ETMDCVR0() MRC14(1, c0, c0, 3) +#define RCP14_ETMDCVR2() MRC14(1, c0, c2, 3) +#define RCP14_ETMDCVR4() MRC14(1, c0, c4, 3) +#define RCP14_ETMDCVR6() MRC14(1, c0, c6, 3) +#define RCP14_ETMDCVR8() MRC14(1, c0, c8, 3) +#define RCP14_ETMDCVR10() MRC14(1, c0, c10, 3) +#define RCP14_ETMDCVR12() MRC14(1, c0, c12, 3) +#define RCP14_ETMDCVR14() MRC14(1, c0, c14, 3) +#define RCP14_ETMDCMR0() MRC14(1, c0, c0, 4) +#define RCP14_ETMDCMR2() MRC14(1, c0, c2, 4) +#define RCP14_ETMDCMR4() MRC14(1, c0, c4, 4) +#define RCP14_ETMDCMR6() MRC14(1, c0, c6, 4) +#define RCP14_ETMDCMR8() MRC14(1, c0, c8, 4) +#define RCP14_ETMDCMR10() MRC14(1, c0, c10, 4) +#define RCP14_ETMDCMR12() MRC14(1, c0, c12, 4) +#define RCP14_ETMDCMR14() MRC14(1, c0, c14, 4) +#define RCP14_ETMCNTRLDVR0() MRC14(1, c0, c0, 5) +#define RCP14_ETMCNTRLDVR1() MRC14(1, c0, c1, 5) +#define RCP14_ETMCNTRLDVR2() MRC14(1, c0, c2, 5) +#define RCP14_ETMCNTRLDVR3() MRC14(1, c0, c3, 5) +#define RCP14_ETMCNTENR0() MRC14(1, c0, c4, 5) +#define RCP14_ETMCNTENR1() MRC14(1, c0, c5, 5) +#define RCP14_ETMCNTENR2() MRC14(1, c0, c6, 5) +#define RCP14_ETMCNTENR3() MRC14(1, c0, c7, 5) +#define RCP14_ETMCNTRLDEVR0() MRC14(1, c0, c8, 5) +#define RCP14_ETMCNTRLDEVR1() MRC14(1, c0, c9, 5) +#define RCP14_ETMCNTRLDEVR2() MRC14(1, c0, c10, 5) +#define RCP14_ETMCNTRLDEVR3() MRC14(1, c0, c11, 5) +#define RCP14_ETMCNTVR0() MRC14(1, c0, c12, 5) +#define RCP14_ETMCNTVR1() MRC14(1, c0, c13, 5) +#define RCP14_ETMCNTVR2() MRC14(1, c0, c14, 5) +#define RCP14_ETMCNTVR3() MRC14(1, c0, c15, 5) +#define RCP14_ETMSQ12EVR() MRC14(1, c0, c0, 6) +#define RCP14_ETMSQ21EVR() MRC14(1, c0, c1, 6) +#define RCP14_ETMSQ23EVR() MRC14(1, c0, c2, 6) +#define RCP14_ETMSQ31EVR() MRC14(1, c0, c3, 6) +#define RCP14_ETMSQ32EVR() MRC14(1, c0, c4, 6) +#define RCP14_ETMSQ13EVR() MRC14(1, c0, c5, 6) +#define RCP14_ETMSQR() MRC14(1, c0, c7, 6) +#define RCP14_ETMEXTOUTEVR0() MRC14(1, c0, c8, 6) +#define RCP14_ETMEXTOUTEVR1() MRC14(1, c0, c9, 6) +#define RCP14_ETMEXTOUTEVR2() MRC14(1, c0, c10, 6) +#define RCP14_ETMEXTOUTEVR3() MRC14(1, c0, c11, 6) +#define RCP14_ETMCIDCVR0() MRC14(1, c0, c12, 6) +#define RCP14_ETMCIDCVR1() MRC14(1, c0, c13, 6) +#define RCP14_ETMCIDCVR2() MRC14(1, c0, c14, 6) +#define RCP14_ETMCIDCMR() MRC14(1, c0, c15, 6) +#define RCP14_ETMIMPSPEC0() MRC14(1, c0, c0, 7) +#define RCP14_ETMIMPSPEC1() MRC14(1, c0, c1, 7) +#define RCP14_ETMIMPSPEC2() MRC14(1, c0, c2, 7) +#define RCP14_ETMIMPSPEC3() MRC14(1, c0, c3, 7) +#define RCP14_ETMIMPSPEC4() MRC14(1, c0, c4, 7) +#define RCP14_ETMIMPSPEC5() MRC14(1, c0, c5, 7) +#define RCP14_ETMIMPSPEC6() MRC14(1, c0, c6, 7) +#define RCP14_ETMIMPSPEC7() MRC14(1, c0, c7, 7) +#define RCP14_ETMSYNCFR() MRC14(1, c0, c8, 7) +#define RCP14_ETMIDR() MRC14(1, c0, c9, 7) +#define RCP14_ETMCCER() MRC14(1, c0, c10, 7) +#define RCP14_ETMEXTINSELR() MRC14(1, c0, c11, 7) +#define RCP14_ETMTESSEICR() MRC14(1, c0, c12, 7) +#define RCP14_ETMEIBCR() MRC14(1, c0, c13, 7) +#define RCP14_ETMTSEVR() MRC14(1, c0, c14, 7) +#define RCP14_ETMAUXCR() MRC14(1, c0, c15, 7) +#define RCP14_ETMTRACEIDR() MRC14(1, c1, c0, 0) +#define RCP14_ETMIDR2() MRC14(1, c1, c2, 0) +#define RCP14_ETMVMIDCVR() MRC14(1, c1, c0, 1) +#define RCP14_ETMOSLSR() MRC14(1, c1, c1, 4) +/* Not available in PFTv1.1 */ +#define RCP14_ETMOSSRR() MRC14(1, c1, c2, 4) +#define RCP14_ETMPDCR() MRC14(1, c1, c4, 4) +#define RCP14_ETMPDSR() MRC14(1, c1, c5, 4) +#define RCP14_ETMITCTRL() MRC14(1, c7, c0, 4) +#define RCP14_ETMCLAIMSET() MRC14(1, c7, c8, 6) +#define RCP14_ETMCLAIMCLR() MRC14(1, c7, c9, 6) +#define RCP14_ETMLSR() MRC14(1, c7, c13, 6) +#define RCP14_ETMAUTHSTATUS() MRC14(1, c7, c14, 6) +#define RCP14_ETMDEVID() MRC14(1, c7, c2, 7) +#define RCP14_ETMDEVTYPE() MRC14(1, c7, c3, 7) +#define RCP14_ETMPIDR4() MRC14(1, c7, c4, 7) +#define RCP14_ETMPIDR5() MRC14(1, c7, c5, 7) +#define RCP14_ETMPIDR6() MRC14(1, c7, c6, 7) +#define RCP14_ETMPIDR7() MRC14(1, c7, c7, 7) +#define RCP14_ETMPIDR0() MRC14(1, c7, c8, 7) +#define RCP14_ETMPIDR1() MRC14(1, c7, c9, 7) +#define RCP14_ETMPIDR2() MRC14(1, c7, c10, 7) +#define RCP14_ETMPIDR3() MRC14(1, c7, c11, 7) +#define RCP14_ETMCIDR0() MRC14(1, c7, c12, 7) +#define RCP14_ETMCIDR1() MRC14(1, c7, c13, 7) +#define RCP14_ETMCIDR2() MRC14(1, c7, c14, 7) +#define RCP14_ETMCIDR3() MRC14(1, c7, c15, 7) + +#define WCP14_ETMCR(val) MCR14(val, 1, c0, c0, 0) +#define WCP14_ETMTRIGGER(val) MCR14(val, 1, c0, c2, 0) +#define WCP14_ETMASICCR(val) MCR14(val, 1, c0, c3, 0) +#define WCP14_ETMSR(val) MCR14(val, 1, c0, c4, 0) +#define WCP14_ETMTSSCR(val) MCR14(val, 1, c0, c6, 0) +#define WCP14_ETMTECR2(val) MCR14(val, 1, c0, c7, 0) +#define WCP14_ETMTEEVR(val) MCR14(val, 1, c0, c8, 0) +#define WCP14_ETMTECR1(val) MCR14(val, 1, c0, c9, 0) +#define WCP14_ETMFFRR(val) MCR14(val, 1, c0, c10, 0) +#define WCP14_ETMFFLR(val) MCR14(val, 1, c0, c11, 0) +#define WCP14_ETMVDEVR(val) MCR14(val, 1, c0, c12, 0) +#define WCP14_ETMVDCR1(val) MCR14(val, 1, c0, c13, 0) +#define WCP14_ETMVDCR2(val) MCR14(val, 1, c0, c14, 0) +#define WCP14_ETMVDCR3(val) MCR14(val, 1, c0, c15, 0) +#define WCP14_ETMACVR0(val) MCR14(val, 1, c0, c0, 1) +#define WCP14_ETMACVR1(val) MCR14(val, 1, c0, c1, 1) +#define WCP14_ETMACVR2(val) MCR14(val, 1, c0, c2, 1) +#define WCP14_ETMACVR3(val) MCR14(val, 1, c0, c3, 1) +#define WCP14_ETMACVR4(val) MCR14(val, 1, c0, c4, 1) +#define WCP14_ETMACVR5(val) MCR14(val, 1, c0, c5, 1) +#define WCP14_ETMACVR6(val) MCR14(val, 1, c0, c6, 1) +#define WCP14_ETMACVR7(val) MCR14(val, 1, c0, c7, 1) +#define WCP14_ETMACVR8(val) MCR14(val, 1, c0, c8, 1) +#define WCP14_ETMACVR9(val) MCR14(val, 1, c0, c9, 1) +#define WCP14_ETMACVR10(val) MCR14(val, 1, c0, c10, 1) +#define WCP14_ETMACVR11(val) MCR14(val, 1, c0, c11, 1) +#define WCP14_ETMACVR12(val) MCR14(val, 1, c0, c12, 1) +#define WCP14_ETMACVR13(val) MCR14(val, 1, c0, c13, 1) +#define WCP14_ETMACVR14(val) MCR14(val, 1, c0, c14, 1) +#define WCP14_ETMACVR15(val) MCR14(val, 1, c0, c15, 1) +#define WCP14_ETMACTR0(val) MCR14(val, 1, c0, c0, 2) +#define WCP14_ETMACTR1(val) MCR14(val, 1, c0, c1, 2) +#define WCP14_ETMACTR2(val) MCR14(val, 1, c0, c2, 2) +#define WCP14_ETMACTR3(val) MCR14(val, 1, c0, c3, 2) +#define WCP14_ETMACTR4(val) MCR14(val, 1, c0, c4, 2) +#define WCP14_ETMACTR5(val) MCR14(val, 1, c0, c5, 2) +#define WCP14_ETMACTR6(val) MCR14(val, 1, c0, c6, 2) +#define WCP14_ETMACTR7(val) MCR14(val, 1, c0, c7, 2) +#define WCP14_ETMACTR8(val) MCR14(val, 1, c0, c8, 2) +#define WCP14_ETMACTR9(val) MCR14(val, 1, c0, c9, 2) +#define WCP14_ETMACTR10(val) MCR14(val, 1, c0, c10, 2) +#define WCP14_ETMACTR11(val) MCR14(val, 1, c0, c11, 2) +#define WCP14_ETMACTR12(val) MCR14(val, 1, c0, c12, 2) +#define WCP14_ETMACTR13(val) MCR14(val, 1, c0, c13, 2) +#define WCP14_ETMACTR14(val) MCR14(val, 1, c0, c14, 2) +#define WCP14_ETMACTR15(val) MCR14(val, 1, c0, c15, 2) +#define WCP14_ETMDCVR0(val) MCR14(val, 1, c0, c0, 3) +#define WCP14_ETMDCVR2(val) MCR14(val, 1, c0, c2, 3) +#define WCP14_ETMDCVR4(val) MCR14(val, 1, c0, c4, 3) +#define WCP14_ETMDCVR6(val) MCR14(val, 1, c0, c6, 3) +#define WCP14_ETMDCVR8(val) MCR14(val, 1, c0, c8, 3) +#define WCP14_ETMDCVR10(val) MCR14(val, 1, c0, c10, 3) +#define WCP14_ETMDCVR12(val) MCR14(val, 1, c0, c12, 3) +#define WCP14_ETMDCVR14(val) MCR14(val, 1, c0, c14, 3) +#define WCP14_ETMDCMR0(val) MCR14(val, 1, c0, c0, 4) +#define WCP14_ETMDCMR2(val) MCR14(val, 1, c0, c2, 4) +#define WCP14_ETMDCMR4(val) MCR14(val, 1, c0, c4, 4) +#define WCP14_ETMDCMR6(val) MCR14(val, 1, c0, c6, 4) +#define WCP14_ETMDCMR8(val) MCR14(val, 1, c0, c8, 4) +#define WCP14_ETMDCMR10(val) MCR14(val, 1, c0, c10, 4) +#define WCP14_ETMDCMR12(val) MCR14(val, 1, c0, c12, 4) +#define WCP14_ETMDCMR14(val) MCR14(val, 1, c0, c14, 4) +#define WCP14_ETMCNTRLDVR0(val) MCR14(val, 1, c0, c0, 5) +#define WCP14_ETMCNTRLDVR1(val) MCR14(val, 1, c0, c1, 5) +#define WCP14_ETMCNTRLDVR2(val) MCR14(val, 1, c0, c2, 5) +#define WCP14_ETMCNTRLDVR3(val) MCR14(val, 1, c0, c3, 5) +#define WCP14_ETMCNTENR0(val) MCR14(val, 1, c0, c4, 5) +#define WCP14_ETMCNTENR1(val) MCR14(val, 1, c0, c5, 5) +#define WCP14_ETMCNTENR2(val) MCR14(val, 1, c0, c6, 5) +#define WCP14_ETMCNTENR3(val) MCR14(val, 1, c0, c7, 5) +#define WCP14_ETMCNTRLDEVR0(val) MCR14(val, 1, c0, c8, 5) +#define WCP14_ETMCNTRLDEVR1(val) MCR14(val, 1, c0, c9, 5) +#define WCP14_ETMCNTRLDEVR2(val) MCR14(val, 1, c0, c10, 5) +#define WCP14_ETMCNTRLDEVR3(val) MCR14(val, 1, c0, c11, 5) +#define WCP14_ETMCNTVR0(val) MCR14(val, 1, c0, c12, 5) +#define WCP14_ETMCNTVR1(val) MCR14(val, 1, c0, c13, 5) +#define WCP14_ETMCNTVR2(val) MCR14(val, 1, c0, c14, 5) +#define WCP14_ETMCNTVR3(val) MCR14(val, 1, c0, c15, 5) +#define WCP14_ETMSQ12EVR(val) MCR14(val, 1, c0, c0, 6) +#define WCP14_ETMSQ21EVR(val) MCR14(val, 1, c0, c1, 6) +#define WCP14_ETMSQ23EVR(val) MCR14(val, 1, c0, c2, 6) +#define WCP14_ETMSQ31EVR(val) MCR14(val, 1, c0, c3, 6) +#define WCP14_ETMSQ32EVR(val) MCR14(val, 1, c0, c4, 6) +#define WCP14_ETMSQ13EVR(val) MCR14(val, 1, c0, c5, 6) +#define WCP14_ETMSQR(val) MCR14(val, 1, c0, c7, 6) +#define WCP14_ETMEXTOUTEVR0(val) MCR14(val, 1, c0, c8, 6) +#define WCP14_ETMEXTOUTEVR1(val) MCR14(val, 1, c0, c9, 6) +#define WCP14_ETMEXTOUTEVR2(val) MCR14(val, 1, c0, c10, 6) +#define WCP14_ETMEXTOUTEVR3(val) MCR14(val, 1, c0, c11, 6) +#define WCP14_ETMCIDCVR0(val) MCR14(val, 1, c0, c12, 6) +#define WCP14_ETMCIDCVR1(val) MCR14(val, 1, c0, c13, 6) +#define WCP14_ETMCIDCVR2(val) MCR14(val, 1, c0, c14, 6) +#define WCP14_ETMCIDCMR(val) MCR14(val, 1, c0, c15, 6) +#define WCP14_ETMIMPSPEC0(val) MCR14(val, 1, c0, c0, 7) +#define WCP14_ETMIMPSPEC1(val) MCR14(val, 1, c0, c1, 7) +#define WCP14_ETMIMPSPEC2(val) MCR14(val, 1, c0, c2, 7) +#define WCP14_ETMIMPSPEC3(val) MCR14(val, 1, c0, c3, 7) +#define WCP14_ETMIMPSPEC4(val) MCR14(val, 1, c0, c4, 7) +#define WCP14_ETMIMPSPEC5(val) MCR14(val, 1, c0, c5, 7) +#define WCP14_ETMIMPSPEC6(val) MCR14(val, 1, c0, c6, 7) +#define WCP14_ETMIMPSPEC7(val) MCR14(val, 1, c0, c7, 7) +/* Can be read only in ETMv3.4, ETMv3.5 */ +#define WCP14_ETMSYNCFR(val) MCR14(val, 1, c0, c8, 7) +#define WCP14_ETMEXTINSELR(val) MCR14(val, 1, c0, c11, 7) +#define WCP14_ETMTESSEICR(val) MCR14(val, 1, c0, c12, 7) +#define WCP14_ETMEIBCR(val) MCR14(val, 1, c0, c13, 7) +#define WCP14_ETMTSEVR(val) MCR14(val, 1, c0, c14, 7) +#define WCP14_ETMAUXCR(val) MCR14(val, 1, c0, c15, 7) +#define WCP14_ETMTRACEIDR(val) MCR14(val, 1, c1, c0, 0) +#define WCP14_ETMIDR2(val) MCR14(val, 1, c1, c2, 0) +#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c0, 1) +#define WCP14_ETMOSLAR(val) MCR14(val, 1, c1, c0, 4) +/* Not available in PFTv1.1 */ +#define WCP14_ETMOSSRR(val) MCR14(val, 1, c1, c2, 4) +#define WCP14_ETMPDCR(val) MCR14(val, 1, c1, c4, 4) +#define WCP14_ETMPDSR(val) MCR14(val, 1, c1, c5, 4) +#define WCP14_ETMITCTRL(val) MCR14(val, 1, c7, c0, 4) +#define WCP14_ETMCLAIMSET(val) MCR14(val, 1, c7, c8, 6) +#define WCP14_ETMCLAIMCLR(val) MCR14(val, 1, c7, c9, 6) +/* Writes to this from CP14 interface are ignored */ +#define WCP14_ETMLAR(val) MCR14(val, 1, c7, c12, 6) + +#endif diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile index 574d5fa496fa..4b4bec890ef5 100644 --- a/drivers/coresight/Makefile +++ b/drivers/coresight/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \ coresight-replicator.o +obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o diff --git a/drivers/coresight/coresight-etm-cp14.c b/drivers/coresight/coresight-etm-cp14.c new file mode 100644 index 000000000000..12a220682117 --- /dev/null +++ b/drivers/coresight/coresight-etm-cp14.c @@ -0,0 +1,591 @@ +/* Copyright (c) 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include + +#include "coresight-etm.h" + +int etm_readl_cp14(u32 reg, unsigned int *val) +{ + switch (reg) { + case ETMCR: + *val = etm_read(ETMCR); + return 0; + case ETMCCR: + *val = etm_read(ETMCCR); + return 0; + case ETMTRIGGER: + *val = etm_read(ETMTRIGGER); + return 0; + case ETMSR: + *val = etm_read(ETMSR); + return 0; + case ETMSCR: + *val = etm_read(ETMSCR); + return 0; + case ETMTSSCR: + *val = etm_read(ETMTSSCR); + return 0; + case ETMTEEVR: + *val = etm_read(ETMTEEVR); + return 0; + case ETMTECR1: + *val = etm_read(ETMTECR1); + return 0; + case ETMFFLR: + *val = etm_read(ETMFFLR); + return 0; + case ETMACVRn(0): + *val = etm_read(ETMACVR0); + return 0; + case ETMACVRn(1): + *val = etm_read(ETMACVR1); + return 0; + case ETMACVRn(2): + *val = etm_read(ETMACVR2); + return 0; + case ETMACVRn(3): + *val = etm_read(ETMACVR3); + return 0; + case ETMACVRn(4): + *val = etm_read(ETMACVR4); + return 0; + case ETMACVRn(5): + *val = etm_read(ETMACVR5); + return 0; + case ETMACVRn(6): + *val = etm_read(ETMACVR6); + return 0; + case ETMACVRn(7): + *val = etm_read(ETMACVR7); + return 0; + case ETMACVRn(8): + *val = etm_read(ETMACVR8); + return 0; + case ETMACVRn(9): + *val = etm_read(ETMACVR9); + return 0; + case ETMACVRn(10): + *val = etm_read(ETMACVR10); + return 0; + case ETMACVRn(11): + *val = etm_read(ETMACVR11); + return 0; + case ETMACVRn(12): + *val = etm_read(ETMACVR12); + return 0; + case ETMACVRn(13): + *val = etm_read(ETMACVR13); + return 0; + case ETMACVRn(14): + *val = etm_read(ETMACVR14); + return 0; + case ETMACVRn(15): + *val = etm_read(ETMACVR15); + return 0; + case ETMACTRn(0): + *val = etm_read(ETMACTR0); + return 0; + case ETMACTRn(1): + *val = etm_read(ETMACTR1); + return 0; + case ETMACTRn(2): + *val = etm_read(ETMACTR2); + return 0; + case ETMACTRn(3): + *val = etm_read(ETMACTR3); + return 0; + case ETMACTRn(4): + *val = etm_read(ETMACTR4); + return 0; + case ETMACTRn(5): + *val = etm_read(ETMACTR5); + return 0; + case ETMACTRn(6): + *val = etm_read(ETMACTR6); + return 0; + case ETMACTRn(7): + *val = etm_read(ETMACTR7); + return 0; + case ETMACTRn(8): + *val = etm_read(ETMACTR8); + return 0; + case ETMACTRn(9): + *val = etm_read(ETMACTR9); + return 0; + case ETMACTRn(10): + *val = etm_read(ETMACTR10); + return 0; + case ETMACTRn(11): + *val = etm_read(ETMACTR11); + return 0; + case ETMACTRn(12): + *val = etm_read(ETMACTR12); + return 0; + case ETMACTRn(13): + *val = etm_read(ETMACTR13); + return 0; + case ETMACTRn(14): + *val = etm_read(ETMACTR14); + return 0; + case ETMACTRn(15): + *val = etm_read(ETMACTR15); + return 0; + case ETMCNTRLDVRn(0): + *val = etm_read(ETMCNTRLDVR0); + return 0; + case ETMCNTRLDVRn(1): + *val = etm_read(ETMCNTRLDVR1); + return 0; + case ETMCNTRLDVRn(2): + *val = etm_read(ETMCNTRLDVR2); + return 0; + case ETMCNTRLDVRn(3): + *val = etm_read(ETMCNTRLDVR3); + return 0; + case ETMCNTENRn(0): + *val = etm_read(ETMCNTENR0); + return 0; + case ETMCNTENRn(1): + *val = etm_read(ETMCNTENR1); + return 0; + case ETMCNTENRn(2): + *val = etm_read(ETMCNTENR2); + return 0; + case ETMCNTENRn(3): + *val = etm_read(ETMCNTENR3); + return 0; + case ETMCNTRLDEVRn(0): + *val = etm_read(ETMCNTRLDEVR0); + return 0; + case ETMCNTRLDEVRn(1): + *val = etm_read(ETMCNTRLDEVR1); + return 0; + case ETMCNTRLDEVRn(2): + *val = etm_read(ETMCNTRLDEVR2); + return 0; + case ETMCNTRLDEVRn(3): + *val = etm_read(ETMCNTRLDEVR3); + return 0; + case ETMCNTVRn(0): + *val = etm_read(ETMCNTVR0); + return 0; + case ETMCNTVRn(1): + *val = etm_read(ETMCNTVR1); + return 0; + case ETMCNTVRn(2): + *val = etm_read(ETMCNTVR2); + return 0; + case ETMCNTVRn(3): + *val = etm_read(ETMCNTVR3); + return 0; + case ETMSQ12EVR: + *val = etm_read(ETMSQ12EVR); + return 0; + case ETMSQ21EVR: + *val = etm_read(ETMSQ21EVR); + return 0; + case ETMSQ23EVR: + *val = etm_read(ETMSQ23EVR); + return 0; + case ETMSQ31EVR: + *val = etm_read(ETMSQ31EVR); + return 0; + case ETMSQ32EVR: + *val = etm_read(ETMSQ32EVR); + return 0; + case ETMSQ13EVR: + *val = etm_read(ETMSQ13EVR); + return 0; + case ETMSQR: + *val = etm_read(ETMSQR); + return 0; + case ETMEXTOUTEVRn(0): + *val = etm_read(ETMEXTOUTEVR0); + return 0; + case ETMEXTOUTEVRn(1): + *val = etm_read(ETMEXTOUTEVR1); + return 0; + case ETMEXTOUTEVRn(2): + *val = etm_read(ETMEXTOUTEVR2); + return 0; + case ETMEXTOUTEVRn(3): + *val = etm_read(ETMEXTOUTEVR3); + return 0; + case ETMCIDCVRn(0): + *val = etm_read(ETMCIDCVR0); + return 0; + case ETMCIDCVRn(1): + *val = etm_read(ETMCIDCVR1); + return 0; + case ETMCIDCVRn(2): + *val = etm_read(ETMCIDCVR2); + return 0; + case ETMCIDCMR: + *val = etm_read(ETMCIDCMR); + return 0; + case ETMIMPSPEC0: + *val = etm_read(ETMIMPSPEC0); + return 0; + case ETMIMPSPEC1: + *val = etm_read(ETMIMPSPEC1); + return 0; + case ETMIMPSPEC2: + *val = etm_read(ETMIMPSPEC2); + return 0; + case ETMIMPSPEC3: + *val = etm_read(ETMIMPSPEC3); + return 0; + case ETMIMPSPEC4: + *val = etm_read(ETMIMPSPEC4); + return 0; + case ETMIMPSPEC5: + *val = etm_read(ETMIMPSPEC5); + return 0; + case ETMIMPSPEC6: + *val = etm_read(ETMIMPSPEC6); + return 0; + case ETMIMPSPEC7: + *val = etm_read(ETMIMPSPEC7); + return 0; + case ETMSYNCFR: + *val = etm_read(ETMSYNCFR); + return 0; + case ETMIDR: + *val = etm_read(ETMIDR); + return 0; + case ETMCCER: + *val = etm_read(ETMCCER); + return 0; + case ETMEXTINSELR: + *val = etm_read(ETMEXTINSELR); + return 0; + case ETMTESSEICR: + *val = etm_read(ETMTESSEICR); + return 0; + case ETMEIBCR: + *val = etm_read(ETMEIBCR); + return 0; + case ETMTSEVR: + *val = etm_read(ETMTSEVR); + return 0; + case ETMAUXCR: + *val = etm_read(ETMAUXCR); + return 0; + case ETMTRACEIDR: + *val = etm_read(ETMTRACEIDR); + return 0; + case ETMVMIDCVR: + *val = etm_read(ETMVMIDCVR); + return 0; + case ETMOSLSR: + *val = etm_read(ETMOSLSR); + return 0; + case ETMOSSRR: + *val = etm_read(ETMOSSRR); + return 0; + case ETMPDCR: + *val = etm_read(ETMPDCR); + return 0; + case ETMPDSR: + *val = etm_read(ETMPDSR); + return 0; + default: + *val = 0; + return -EINVAL; + } +} + +int etm_writel_cp14(u32 reg, u32 val) +{ + switch (reg) { + case ETMCR: + etm_write(val, ETMCR); + break; + case ETMTRIGGER: + etm_write(val, ETMTRIGGER); + break; + case ETMSR: + etm_write(val, ETMSR); + break; + case ETMTSSCR: + etm_write(val, ETMTSSCR); + break; + case ETMTEEVR: + etm_write(val, ETMTEEVR); + break; + case ETMTECR1: + etm_write(val, ETMTECR1); + break; + case ETMFFLR: + etm_write(val, ETMFFLR); + break; + case ETMACVRn(0): + etm_write(val, ETMACVR0); + break; + case ETMACVRn(1): + etm_write(val, ETMACVR1); + break; + case ETMACVRn(2): + etm_write(val, ETMACVR2); + break; + case ETMACVRn(3): + etm_write(val, ETMACVR3); + break; + case ETMACVRn(4): + etm_write(val, ETMACVR4); + break; + case ETMACVRn(5): + etm_write(val, ETMACVR5); + break; + case ETMACVRn(6): + etm_write(val, ETMACVR6); + break; + case ETMACVRn(7): + etm_write(val, ETMACVR7); + break; + case ETMACVRn(8): + etm_write(val, ETMACVR8); + break; + case ETMACVRn(9): + etm_write(val, ETMACVR9); + break; + case ETMACVRn(10): + etm_write(val, ETMACVR10); + break; + case ETMACVRn(11): + etm_write(val, ETMACVR11); + break; + case ETMACVRn(12): + etm_write(val, ETMACVR12); + break; + case ETMACVRn(13): + etm_write(val, ETMACVR13); + break; + case ETMACVRn(14): + etm_write(val, ETMACVR14); + break; + case ETMACVRn(15): + etm_write(val, ETMACVR15); + break; + case ETMACTRn(0): + etm_write(val, ETMACTR0); + break; + case ETMACTRn(1): + etm_write(val, ETMACTR1); + break; + case ETMACTRn(2): + etm_write(val, ETMACTR2); + break; + case ETMACTRn(3): + etm_write(val, ETMACTR3); + break; + case ETMACTRn(4): + etm_write(val, ETMACTR4); + break; + case ETMACTRn(5): + etm_write(val, ETMACTR5); + break; + case ETMACTRn(6): + etm_write(val, ETMACTR6); + break; + case ETMACTRn(7): + etm_write(val, ETMACTR7); + break; + case ETMACTRn(8): + etm_write(val, ETMACTR8); + break; + case ETMACTRn(9): + etm_write(val, ETMACTR9); + break; + case ETMACTRn(10): + etm_write(val, ETMACTR10); + break; + case ETMACTRn(11): + etm_write(val, ETMACTR11); + break; + case ETMACTRn(12): + etm_write(val, ETMACTR12); + break; + case ETMACTRn(13): + etm_write(val, ETMACTR13); + break; + case ETMACTRn(14): + etm_write(val, ETMACTR14); + break; + case ETMACTRn(15): + etm_write(val, ETMACTR15); + break; + case ETMCNTRLDVRn(0): + etm_write(val, ETMCNTRLDVR0); + break; + case ETMCNTRLDVRn(1): + etm_write(val, ETMCNTRLDVR1); + break; + case ETMCNTRLDVRn(2): + etm_write(val, ETMCNTRLDVR2); + break; + case ETMCNTRLDVRn(3): + etm_write(val, ETMCNTRLDVR3); + break; + case ETMCNTENRn(0): + etm_write(val, ETMCNTENR0); + break; + case ETMCNTENRn(1): + etm_write(val, ETMCNTENR1); + break; + case ETMCNTENRn(2): + etm_write(val, ETMCNTENR2); + break; + case ETMCNTENRn(3): + etm_write(val, ETMCNTENR3); + break; + case ETMCNTRLDEVRn(0): + etm_write(val, ETMCNTRLDEVR0); + break; + case ETMCNTRLDEVRn(1): + etm_write(val, ETMCNTRLDEVR1); + break; + case ETMCNTRLDEVRn(2): + etm_write(val, ETMCNTRLDEVR2); + break; + case ETMCNTRLDEVRn(3): + etm_write(val, ETMCNTRLDEVR3); + break; + case ETMCNTVRn(0): + etm_write(val, ETMCNTVR0); + break; + case ETMCNTVRn(1): + etm_write(val, ETMCNTVR1); + break; + case ETMCNTVRn(2): + etm_write(val, ETMCNTVR2); + break; + case ETMCNTVRn(3): + etm_write(val, ETMCNTVR3); + break; + case ETMSQ12EVR: + etm_write(val, ETMSQ12EVR); + break; + case ETMSQ21EVR: + etm_write(val, ETMSQ21EVR); + break; + case ETMSQ23EVR: + etm_write(val, ETMSQ23EVR); + break; + case ETMSQ31EVR: + etm_write(val, ETMSQ31EVR); + break; + case ETMSQ32EVR: + etm_write(val, ETMSQ32EVR); + break; + case ETMSQ13EVR: + etm_write(val, ETMSQ13EVR); + break; + case ETMSQR: + etm_write(val, ETMSQR); + break; + case ETMEXTOUTEVRn(0): + etm_write(val, ETMEXTOUTEVR0); + break; + case ETMEXTOUTEVRn(1): + etm_write(val, ETMEXTOUTEVR1); + break; + case ETMEXTOUTEVRn(2): + etm_write(val, ETMEXTOUTEVR2); + break; + case ETMEXTOUTEVRn(3): + etm_write(val, ETMEXTOUTEVR3); + break; + case ETMCIDCVRn(0): + etm_write(val, ETMCIDCVR0); + break; + case ETMCIDCVRn(1): + etm_write(val, ETMCIDCVR1); + break; + case ETMCIDCVRn(2): + etm_write(val, ETMCIDCVR2); + break; + case ETMCIDCMR: + etm_write(val, ETMCIDCMR); + break; + case ETMIMPSPEC0: + etm_write(val, ETMIMPSPEC0); + break; + case ETMIMPSPEC1: + etm_write(val, ETMIMPSPEC1); + break; + case ETMIMPSPEC2: + etm_write(val, ETMIMPSPEC2); + break; + case ETMIMPSPEC3: + etm_write(val, ETMIMPSPEC3); + break; + case ETMIMPSPEC4: + etm_write(val, ETMIMPSPEC4); + break; + case ETMIMPSPEC5: + etm_write(val, ETMIMPSPEC5); + break; + case ETMIMPSPEC6: + etm_write(val, ETMIMPSPEC6); + break; + case ETMIMPSPEC7: + etm_write(val, ETMIMPSPEC7); + break; + case ETMSYNCFR: + etm_write(val, ETMSYNCFR); + break; + case ETMEXTINSELR: + etm_write(val, ETMEXTINSELR); + break; + case ETMTESSEICR: + etm_write(val, ETMTESSEICR); + break; + case ETMEIBCR: + etm_write(val, ETMEIBCR); + break; + case ETMTSEVR: + etm_write(val, ETMTSEVR); + break; + case ETMAUXCR: + etm_write(val, ETMAUXCR); + break; + case ETMTRACEIDR: + etm_write(val, ETMTRACEIDR); + break; + case ETMVMIDCVR: + etm_write(val, ETMVMIDCVR); + break; + case ETMOSLAR: + etm_write(val, ETMOSLAR); + break; + case ETMOSSRR: + etm_write(val, ETMOSSRR); + break; + case ETMPDCR: + etm_write(val, ETMPDCR); + break; + case ETMPDSR: + etm_write(val, ETMPDSR); + break; + default: + return -EINVAL; + } + + return 0; +} diff --git a/drivers/coresight/coresight-etm.h b/drivers/coresight/coresight-etm.h new file mode 100644 index 000000000000..501c5fac8a45 --- /dev/null +++ b/drivers/coresight/coresight-etm.h @@ -0,0 +1,251 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CORESIGHT_CORESIGHT_ETM_H +#define _CORESIGHT_CORESIGHT_ETM_H + +#include +#include "coresight-priv.h" + +/* + * Device registers: + * 0x000 - 0x2FC: Trace registers + * 0x300 - 0x314: Management registers + * 0x318 - 0xEFC: Trace registers + * + * Coresight registers + * 0xF00 - 0xF9C: Management registers + * 0xFA0 - 0xFA4: Management registers in PFTv1.0 + * Trace registers in PFTv1.1 + * 0xFA8 - 0xFFC: Management registers + */ + +/* Trace registers (0x000-0x2FC) */ +#define ETMCR 0x000 +#define ETMCCR 0x004 +#define ETMTRIGGER 0x008 +#define ETMSR 0x010 +#define ETMSCR 0x014 +#define ETMTSSCR 0x018 +#define ETMTECR2 0x01c +#define ETMTEEVR 0x020 +#define ETMTECR1 0x024 +#define ETMFFLR 0x02c +#define ETMACVRn(n) (0x040 + (n * 4)) +#define ETMACTRn(n) (0x080 + (n * 4)) +#define ETMCNTRLDVRn(n) (0x140 + (n * 4)) +#define ETMCNTENRn(n) (0x150 + (n * 4)) +#define ETMCNTRLDEVRn(n) (0x160 + (n * 4)) +#define ETMCNTVRn(n) (0x170 + (n * 4)) +#define ETMSQ12EVR 0x180 +#define ETMSQ21EVR 0x184 +#define ETMSQ23EVR 0x188 +#define ETMSQ31EVR 0x18c +#define ETMSQ32EVR 0x190 +#define ETMSQ13EVR 0x194 +#define ETMSQR 0x19c +#define ETMEXTOUTEVRn(n) (0x1a0 + (n * 4)) +#define ETMCIDCVRn(n) (0x1b0 + (n * 4)) +#define ETMCIDCMR 0x1bc +#define ETMIMPSPEC0 0x1c0 +#define ETMIMPSPEC1 0x1c4 +#define ETMIMPSPEC2 0x1c8 +#define ETMIMPSPEC3 0x1cc +#define ETMIMPSPEC4 0x1d0 +#define ETMIMPSPEC5 0x1d4 +#define ETMIMPSPEC6 0x1d8 +#define ETMIMPSPEC7 0x1dc +#define ETMSYNCFR 0x1e0 +#define ETMIDR 0x1e4 +#define ETMCCER 0x1e8 +#define ETMEXTINSELR 0x1ec +#define ETMTESSEICR 0x1f0 +#define ETMEIBCR 0x1f4 +#define ETMTSEVR 0x1f8 +#define ETMAUXCR 0x1fc +#define ETMTRACEIDR 0x200 +#define ETMVMIDCVR 0x240 +/* Management registers (0x300-0x314) */ +#define ETMOSLAR 0x300 +#define ETMOSLSR 0x304 +#define ETMOSSRR 0x308 +#define ETMPDCR 0x310 +#define ETMPDSR 0x314 +#define ETM_MAX_ADDR_CMP 16 +#define ETM_MAX_CNTR 4 +#define ETM_MAX_CTXID_CMP 3 + +/* Register definition */ +/* ETMCR - 0x00 */ +#define ETMCR_PWD_DWN BIT(0) +#define ETMCR_STALL_MODE BIT(7) +#define ETMCR_ETM_PRG BIT(10) +#define ETMCR_ETM_EN BIT(11) +#define ETMCR_CYC_ACC BIT(12) +#define ETMCR_CTXID_SIZE (BIT(14)|BIT(15)) +#define ETMCR_TIMESTAMP_EN BIT(28) +/* ETMCCR - 0x04 */ +#define ETMCCR_FIFOFULL BIT(23) +/* ETMPDCR - 0x310 */ +#define ETMPDCR_PWD_UP BIT(3) +/* ETMTECR1 - 0x024 */ +#define ETMTECR1_ADDR_COMP_1 BIT(0) +#define ETMTECR1_INC_EXC BIT(24) +#define ETMTECR1_START_STOP BIT(25) +/* ETMCCER - 0x1E8 */ +#define ETMCCER_TIMESTAMP BIT(22) + +#define ETM_MODE_EXCLUDE BIT(0) +#define ETM_MODE_CYCACC BIT(1) +#define ETM_MODE_STALL BIT(2) +#define ETM_MODE_TIMESTAMP BIT(3) +#define ETM_MODE_CTXID BIT(4) +#define ETM_MODE_ALL 0x1f + +#define ETM_SQR_MASK 0x3 +#define ETM_TRACEID_MASK 0x3f +#define ETM_EVENT_MASK 0x1ffff +#define ETM_SYNC_MASK 0xfff +#define ETM_ALL_MASK 0xffffffff + +#define ETMSR_PROG_BIT 1 +#define ETM_SEQ_STATE_MAX_VAL (0x2) +#define PORT_SIZE_MASK (GENMASK(21, 21) | GENMASK(6, 4)) + +#define ETM_HARD_WIRE_RES_A /* Hard wired, always true */ \ + ((0x0f << 0) | \ + /* Resource index A */ \ + (0x06 << 4)) + +#define ETM_ADD_COMP_0 /* Single addr comparator 1 */ \ + ((0x00 << 7) | \ + /* Resource index B */ \ + (0x00 << 11)) + +#define ETM_EVENT_NOT_A BIT(14) /* NOT(A) */ + +#define ETM_DEFAULT_EVENT_VAL (ETM_HARD_WIRE_RES_A | \ + ETM_ADD_COMP_0 | \ + ETM_EVENT_NOT_A) +/** + * struct etm_drvdata - specifics associated to an ETM component + * @base: memory mapped base address for this component. + * @dev: the device entity associated to this component. + * @csdev: component vitals needed by the framework. + * @clk: the clock this component is associated to. + * @spinlock: only one at a time pls. + * @cpu: the cpu this component is affined to. + * @port_size: port size as reported by ETMCR bit 4-6 and 21. + * @arch: ETM/PTM version number. + * @use_cpu14: true if management registers need to be accessed via CP14. + * @enable: is this ETM/PTM currently tracing. + * @sticky_enable: true if ETM base configuration has been done. + * @boot_enable:true if we should start tracing at boot time. + * @os_unlock: true if access to management registers is allowed. + * @nr_addr_cmp:Number of pairs of address comparators as found in ETMCCR. + * @nr_cntr: Number of counters as found in ETMCCR bit 13-15. + * @nr_ext_inp: Number of external input as found in ETMCCR bit 17-19. + * @nr_ext_out: Number of external output as found in ETMCCR bit 20-22. + * @nr_ctxid_cmp: Number of contextID comparators as found in ETMCCR bit 24-25. + * @etmccr: value of register ETMCCR. + * @etmccer: value of register ETMCCER. + * @traceid: value of the current ID for this component. + * @mode: controls various modes supported by this ETM/PTM. + * @ctrl: used in conjunction with @mode. + * @trigger_event: setting for register ETMTRIGGER. + * @startstop_ctrl: setting for register ETMTSSCR. + * @enable_event: setting for register ETMTEEVR. + * @enable_ctrl1: setting for register ETMTECR1. + * @fifofull_level: setting for register ETMFFLR. + * @addr_idx: index for the address comparator selection. + * @addr_val: value for address comparator register. + * @addr_acctype: access type for address comparator register. + * @addr_type: current status of the comparator register. + * @cntr_idx: index for the counter register selection. + * @cntr_rld_val: reload value of a counter register. + * @cntr_event: control for counter enable register. + * @cntr_rld_event: value for counter reload event register. + * @cntr_val: counter value register. + * @seq_12_event: event causing the transition from 1 to 2. + * @seq_21_event: event causing the transition from 2 to 1. + * @seq_23_event: event causing the transition from 2 to 3. + * @seq_31_event: event causing the transition from 3 to 1. + * @seq_32_event: event causing the transition from 3 to 2. + * @seq_13_event: event causing the transition from 1 to 3. + * @seq_curr_state: current value of the sequencer register. + * @ctxid_idx: index for the context ID registers. + * @ctxid_val: value for the context ID to trigger on. + * @ctxid_mask: mask applicable to all the context IDs. + * @sync_freq: Synchronisation frequency. + * @timestamp_event: Defines an event that requests the insertion + of a timestamp into the trace stream. + */ +struct etm_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + struct clk *clk; + spinlock_t spinlock; + int cpu; + int port_size; + u8 arch; + bool use_cp14; + bool enable; + bool sticky_enable; + bool boot_enable; + bool os_unlock; + u8 nr_addr_cmp; + u8 nr_cntr; + u8 nr_ext_inp; + u8 nr_ext_out; + u8 nr_ctxid_cmp; + u32 etmccr; + u32 etmccer; + u32 traceid; + u32 mode; + u32 ctrl; + u32 trigger_event; + u32 startstop_ctrl; + u32 enable_event; + u32 enable_ctrl1; + u32 fifofull_level; + u8 addr_idx; + u32 addr_val[ETM_MAX_ADDR_CMP]; + u32 addr_acctype[ETM_MAX_ADDR_CMP]; + u32 addr_type[ETM_MAX_ADDR_CMP]; + u8 cntr_idx; + u32 cntr_rld_val[ETM_MAX_CNTR]; + u32 cntr_event[ETM_MAX_CNTR]; + u32 cntr_rld_event[ETM_MAX_CNTR]; + u32 cntr_val[ETM_MAX_CNTR]; + u32 seq_12_event; + u32 seq_21_event; + u32 seq_23_event; + u32 seq_31_event; + u32 seq_32_event; + u32 seq_13_event; + u32 seq_curr_state; + u8 ctxid_idx; + u32 ctxid_val[ETM_MAX_CTXID_CMP]; + u32 ctxid_mask; + u32 sync_freq; + u32 timestamp_event; +}; + +enum etm_addr_type { + ETM_ADDR_TYPE_NONE, + ETM_ADDR_TYPE_SINGLE, + ETM_ADDR_TYPE_RANGE, + ETM_ADDR_TYPE_START, + ETM_ADDR_TYPE_STOP, +}; +#endif diff --git a/drivers/coresight/coresight-etm3x.c b/drivers/coresight/coresight-etm3x.c new file mode 100644 index 000000000000..d9e3ed6aa857 --- /dev/null +++ b/drivers/coresight/coresight-etm3x.c @@ -0,0 +1,1928 @@ +/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-etm.h" + +#ifdef CONFIG_CORESIGHT_SOURCE_ETM_DEFAULT_ENABLE +static int boot_enable = 1; +#else +static int boot_enable; +#endif +module_param_named( + boot_enable, boot_enable, int, S_IRUGO +); + +/* The number of ETM/PTM currently registered */ +static int etm_count; +static struct etm_drvdata *etmdrvdata[NR_CPUS]; + +static inline void etm_writel(struct etm_drvdata *drvdata, + u32 val, u32 off) +{ + if (drvdata->use_cp14) { + if (etm_writel_cp14(off, val)) { + dev_err(drvdata->dev, + "invalid CP14 access to ETM reg: %#x", off); + } + } else { + writel_relaxed(val, drvdata->base + off); + } +} + +static inline unsigned int etm_readl(struct etm_drvdata *drvdata, u32 off) +{ + u32 val; + + if (drvdata->use_cp14) { + if (etm_readl_cp14(off, &val)) { + dev_err(drvdata->dev, + "invalid CP14 access to ETM reg: %#x", off); + } + } else { + val = readl_relaxed(drvdata->base + off); + } + + return val; +} + +/* + * Memory mapped writes to clear os lock are not supported on some processors + * and OS lock must be unlocked before any memory mapped access on such + * processors, otherwise memory mapped reads/writes will be invalid. + */ +static void etm_os_unlock(void *info) +{ + struct etm_drvdata *drvdata = (struct etm_drvdata *)info; + /* Writing any value to ETMOSLAR unlocks the trace registers */ + etm_writel(drvdata, 0x0, ETMOSLAR); + isb(); +} + +static void etm_set_pwrdwn(struct etm_drvdata *drvdata) +{ + u32 etmcr; + + /* Ensure pending cp14 accesses complete before setting pwrdwn */ + mb(); + isb(); + etmcr = etm_readl(drvdata, ETMCR); + etmcr |= ETMCR_PWD_DWN; + etm_writel(drvdata, etmcr, ETMCR); +} + +static void etm_clr_pwrdwn(struct etm_drvdata *drvdata) +{ + u32 etmcr; + + etmcr = etm_readl(drvdata, ETMCR); + etmcr &= ~ETMCR_PWD_DWN; + etm_writel(drvdata, etmcr, ETMCR); + /* Ensure pwrup completes before subsequent cp14 accesses */ + mb(); + isb(); +} + +static void etm_set_pwrup(struct etm_drvdata *drvdata) +{ + u32 etmpdcr; + + etmpdcr = readl_relaxed(drvdata->base + ETMPDCR); + etmpdcr |= ETMPDCR_PWD_UP; + writel_relaxed(etmpdcr, drvdata->base + ETMPDCR); + /* Ensure pwrup completes before subsequent cp14 accesses */ + mb(); + isb(); +} + +static void etm_clr_pwrup(struct etm_drvdata *drvdata) +{ + u32 etmpdcr; + + /* Ensure pending cp14 accesses complete before clearing pwrup */ + mb(); + isb(); + etmpdcr = readl_relaxed(drvdata->base + ETMPDCR); + etmpdcr &= ~ETMPDCR_PWD_UP; + writel_relaxed(etmpdcr, drvdata->base + ETMPDCR); +} + +/** + * coresight_timeout_etm - loop until a bit has changed to a specific state. + * @drvdata: etm's private data structure. + * @offset: address of a register, starting from @addr. + * @position: the position of the bit of interest. + * @value: the value the bit should have. + * + * Basically the same as @coresight_timeout except for the register access + * method where we have to account for CP14 configurations. + + * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if + * TIMEOUT_US has elapsed, which ever happens first. + */ + +static int coresight_timeout_etm(struct etm_drvdata *drvdata, u32 offset, + int position, int value) +{ + int i; + u32 val; + + for (i = TIMEOUT_US; i > 0; i--) { + val = etm_readl(drvdata, offset); + /* Waiting on the bit to go from 0 to 1 */ + if (value) { + if (val & BIT(position)) + return 0; + /* Waiting on the bit to go from 1 to 0 */ + } else { + if (!(val & BIT(position))) + return 0; + } + + /* + * Delay is arbitrary - the specification doesn't say how long + * we are expected to wait. Extra check required to make sure + * we don't wait needlessly on the last iteration. + */ + if (i - 1) + udelay(1); + } + + return -EAGAIN; +} + + +static void etm_set_prog(struct etm_drvdata *drvdata) +{ + u32 etmcr; + + etmcr = etm_readl(drvdata, ETMCR); + etmcr |= ETMCR_ETM_PRG; + etm_writel(drvdata, etmcr, ETMCR); + /* + * Recommended by spec for cp14 accesses to ensure etmcr write is + * complete before polling etmsr + */ + isb(); + if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 1)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", ETMSR); + } +} + +static void etm_clr_prog(struct etm_drvdata *drvdata) +{ + u32 etmcr; + + etmcr = etm_readl(drvdata, ETMCR); + etmcr &= ~ETMCR_ETM_PRG; + etm_writel(drvdata, etmcr, ETMCR); + /* + * Recommended by spec for cp14 accesses to ensure etmcr write is + * complete before polling etmsr + */ + isb(); + if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 0)) { + dev_err(drvdata->dev, + "timeout observed when probing at offset %#x\n", ETMSR); + } +} + +static void etm_set_default(struct etm_drvdata *drvdata) +{ + int i; + + drvdata->trigger_event = ETM_DEFAULT_EVENT_VAL; + drvdata->enable_event = ETM_HARD_WIRE_RES_A; + + drvdata->seq_12_event = ETM_DEFAULT_EVENT_VAL; + drvdata->seq_21_event = ETM_DEFAULT_EVENT_VAL; + drvdata->seq_23_event = ETM_DEFAULT_EVENT_VAL; + drvdata->seq_31_event = ETM_DEFAULT_EVENT_VAL; + drvdata->seq_32_event = ETM_DEFAULT_EVENT_VAL; + drvdata->seq_13_event = ETM_DEFAULT_EVENT_VAL; + drvdata->timestamp_event = ETM_DEFAULT_EVENT_VAL; + + for (i = 0; i < drvdata->nr_cntr; i++) { + drvdata->cntr_rld_val[i] = 0x0; + drvdata->cntr_event[i] = ETM_DEFAULT_EVENT_VAL; + drvdata->cntr_rld_event[i] = ETM_DEFAULT_EVENT_VAL; + drvdata->cntr_val[i] = 0x0; + } + + drvdata->seq_curr_state = 0x0; + drvdata->ctxid_idx = 0x0; + for (i = 0; i < drvdata->nr_ctxid_cmp; i++) + drvdata->ctxid_val[i] = 0x0; + drvdata->ctxid_mask = 0x0; +} + +static void etm_enable_hw(void *info) +{ + int i; + u32 etmcr; + struct etm_drvdata *drvdata = info; + + CS_UNLOCK(drvdata->base); + + /* Turn engine on */ + etm_clr_pwrdwn(drvdata); + /* Apply power to trace registers */ + etm_set_pwrup(drvdata); + /* Make sure all registers are accessible */ + etm_os_unlock(drvdata); + + etm_set_prog(drvdata); + + etmcr = etm_readl(drvdata, ETMCR); + etmcr &= (ETMCR_PWD_DWN | ETMCR_ETM_PRG); + etmcr |= drvdata->port_size; + etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR); + etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER); + etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR); + etm_writel(drvdata, drvdata->enable_event, ETMTEEVR); + etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1); + etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR); + for (i = 0; i < drvdata->nr_addr_cmp; i++) { + etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i)); + etm_writel(drvdata, drvdata->addr_acctype[i], ETMACTRn(i)); + } + for (i = 0; i < drvdata->nr_cntr; i++) { + etm_writel(drvdata, drvdata->cntr_rld_val[i], ETMCNTRLDVRn(i)); + etm_writel(drvdata, drvdata->cntr_event[i], ETMCNTENRn(i)); + etm_writel(drvdata, drvdata->cntr_rld_event[i], + ETMCNTRLDEVRn(i)); + etm_writel(drvdata, drvdata->cntr_val[i], ETMCNTVRn(i)); + } + etm_writel(drvdata, drvdata->seq_12_event, ETMSQ12EVR); + etm_writel(drvdata, drvdata->seq_21_event, ETMSQ21EVR); + etm_writel(drvdata, drvdata->seq_23_event, ETMSQ23EVR); + etm_writel(drvdata, drvdata->seq_31_event, ETMSQ31EVR); + etm_writel(drvdata, drvdata->seq_32_event, ETMSQ32EVR); + etm_writel(drvdata, drvdata->seq_13_event, ETMSQ13EVR); + etm_writel(drvdata, drvdata->seq_curr_state, ETMSQR); + for (i = 0; i < drvdata->nr_ext_out; i++) + etm_writel(drvdata, ETM_DEFAULT_EVENT_VAL, ETMEXTOUTEVRn(i)); + for (i = 0; i < drvdata->nr_ctxid_cmp; i++) + etm_writel(drvdata, drvdata->ctxid_val[i], ETMCIDCVRn(i)); + etm_writel(drvdata, drvdata->ctxid_mask, ETMCIDCMR); + etm_writel(drvdata, drvdata->sync_freq, ETMSYNCFR); + /* No external input selected */ + etm_writel(drvdata, 0x0, ETMEXTINSELR); + etm_writel(drvdata, drvdata->timestamp_event, ETMTSEVR); + /* No auxiliary control selected */ + etm_writel(drvdata, 0x0, ETMAUXCR); + etm_writel(drvdata, drvdata->traceid, ETMTRACEIDR); + /* No VMID comparator value selected */ + etm_writel(drvdata, 0x0, ETMVMIDCVR); + + /* Ensures trace output is enabled from this ETM */ + etm_writel(drvdata, drvdata->ctrl | ETMCR_ETM_EN | etmcr, ETMCR); + + etm_clr_prog(drvdata); + CS_LOCK(drvdata->base); + + dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu); +} + +static int etm_trace_id_simple(struct etm_drvdata *drvdata) +{ + if (!drvdata->enable) + return drvdata->traceid; + + return (etm_readl(drvdata, ETMTRACEIDR) & ETM_TRACEID_MASK); +} + +static int etm_trace_id(struct coresight_device *csdev) +{ + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + int trace_id = -1; + + if (!drvdata->enable) + return drvdata->traceid; + + if (clk_prepare_enable(drvdata->clk)) + goto out; + + spin_lock_irqsave(&drvdata->spinlock, flags); + + CS_UNLOCK(drvdata->base); + trace_id = (etm_readl(drvdata, ETMTRACEIDR) & ETM_TRACEID_MASK); + CS_LOCK(drvdata->base); + + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); +out: + return trace_id; +} + +static int etm_enable(struct coresight_device *csdev) +{ + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + int ret; + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + goto err_clk; + + spin_lock(&drvdata->spinlock); + + /* + * Configure the ETM only if the CPU is online. If it isn't online + * hw configuration will take place when 'CPU_STARTING' is received + * in @etm_cpu_callback. + */ + if (cpu_online(drvdata->cpu)) { + ret = smp_call_function_single(drvdata->cpu, + etm_enable_hw, drvdata, 1); + if (ret) + goto err; + } + + drvdata->enable = true; + drvdata->sticky_enable = true; + + spin_unlock(&drvdata->spinlock); + + dev_info(drvdata->dev, "ETM tracing enabled\n"); + return 0; +err: + spin_unlock(&drvdata->spinlock); + clk_disable_unprepare(drvdata->clk); +err_clk: + return ret; +} + +static void etm_disable_hw(void *info) +{ + int i; + struct etm_drvdata *drvdata = info; + + CS_UNLOCK(drvdata->base); + etm_set_prog(drvdata); + + /* Program trace enable to low by using always false event */ + etm_writel(drvdata, ETM_HARD_WIRE_RES_A | ETM_EVENT_NOT_A, ETMTEEVR); + + /* Read back sequencer and counters for post trace analysis */ + drvdata->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK); + + for (i = 0; i < drvdata->nr_cntr; i++) + drvdata->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i)); + + etm_set_pwrdwn(drvdata); + CS_LOCK(drvdata->base); + + dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu); +} + +static void etm_disable(struct coresight_device *csdev) +{ + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + /* + * Taking hotplug lock here protects from clocks getting disabled + * with tracing being left on (crash scenario) if user disable occurs + * after cpu online mask indicates the cpu is offline but before the + * DYING hotplug callback is serviced by the ETM driver. + */ + get_online_cpus(); + spin_lock(&drvdata->spinlock); + + /* + * Executing etm_disable_hw on the cpu whose ETM is being disabled + * ensures that register writes occur when cpu is powered. + */ + smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1); + drvdata->enable = false; + + spin_unlock(&drvdata->spinlock); + put_online_cpus(); + + clk_disable_unprepare(drvdata->clk); + + dev_info(drvdata->dev, "ETM tracing disabled\n"); +} + +static const struct coresight_ops_source etm_source_ops = { + .trace_id = etm_trace_id, + .enable = etm_enable, + .disable = etm_disable, +}; + +static const struct coresight_ops etm_cs_ops = { + .source_ops = &etm_source_ops, +}; + +static ssize_t nr_addr_cmp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->nr_addr_cmp; + return sprintf(buf, "%#lx\n", val); +} +static DEVICE_ATTR_RO(nr_addr_cmp); + +static ssize_t nr_cntr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->nr_cntr; + return sprintf(buf, "%#lx\n", val); +} +static DEVICE_ATTR_RO(nr_cntr); + +static ssize_t nr_ctxid_cmp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->nr_ctxid_cmp; + return sprintf(buf, "%#lx\n", val); +} +static DEVICE_ATTR_RO(nr_ctxid_cmp); + +static ssize_t etmsr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned long flags, val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + CS_UNLOCK(drvdata->base); + + val = etm_readl(drvdata, ETMSR); + + CS_LOCK(drvdata->base); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); + + return sprintf(buf, "%#lx\n", val); +} +static DEVICE_ATTR_RO(etmsr); + +static ssize_t reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int i, ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + if (val) { + spin_lock(&drvdata->spinlock); + drvdata->mode = ETM_MODE_EXCLUDE; + drvdata->ctrl = 0x0; + drvdata->trigger_event = ETM_DEFAULT_EVENT_VAL; + drvdata->startstop_ctrl = 0x0; + drvdata->addr_idx = 0x0; + for (i = 0; i < drvdata->nr_addr_cmp; i++) { + drvdata->addr_val[i] = 0x0; + drvdata->addr_acctype[i] = 0x0; + drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE; + } + drvdata->cntr_idx = 0x0; + + etm_set_default(drvdata); + spin_unlock(&drvdata->spinlock); + } + + return size; +} +static DEVICE_ATTR_WO(reset); + +static ssize_t mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->mode; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->mode = val & ETM_MODE_ALL; + + if (drvdata->mode & ETM_MODE_EXCLUDE) + drvdata->enable_ctrl1 |= ETMTECR1_INC_EXC; + else + drvdata->enable_ctrl1 &= ~ETMTECR1_INC_EXC; + + if (drvdata->mode & ETM_MODE_CYCACC) + drvdata->ctrl |= ETMCR_CYC_ACC; + else + drvdata->ctrl &= ~ETMCR_CYC_ACC; + + if (drvdata->mode & ETM_MODE_STALL) { + if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) { + dev_warn(drvdata->dev, "stall mode not supported\n"); + return -EINVAL; + } + drvdata->ctrl |= ETMCR_STALL_MODE; + } else + drvdata->ctrl &= ~ETMCR_STALL_MODE; + + if (drvdata->mode & ETM_MODE_TIMESTAMP) { + if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) { + dev_warn(drvdata->dev, "timestamp not supported\n"); + return -EINVAL; + } + drvdata->ctrl |= ETMCR_TIMESTAMP_EN; + } else + drvdata->ctrl &= ~ETMCR_TIMESTAMP_EN; + + if (drvdata->mode & ETM_MODE_CTXID) + drvdata->ctrl |= ETMCR_CTXID_SIZE; + else + drvdata->ctrl &= ~ETMCR_CTXID_SIZE; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(mode); + +static ssize_t trigger_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->trigger_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t trigger_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->trigger_event = val & ETM_EVENT_MASK; + + return size; +} +static DEVICE_ATTR_RW(trigger_event); + +static ssize_t enable_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->enable_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t enable_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->enable_event = val & ETM_EVENT_MASK; + + return size; +} +static DEVICE_ATTR_RW(enable_event); + +static ssize_t fifofull_level_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->fifofull_level; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t fifofull_level_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->fifofull_level = val; + + return size; +} +static DEVICE_ATTR_RW(fifofull_level); + +static ssize_t addr_idx_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->addr_idx; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t addr_idx_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + if (val >= drvdata->nr_addr_cmp) + return -EINVAL; + + /* + * Use spinlock to ensure index doesn't change while it gets + * dereferenced multiple times within a spinlock block elsewhere. + */ + spin_lock(&drvdata->spinlock); + drvdata->addr_idx = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_idx); + +static ssize_t addr_single_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 idx; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) { + spin_unlock(&drvdata->spinlock); + return -EINVAL; + } + + val = drvdata->addr_val[idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t addr_single_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 idx; + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) { + spin_unlock(&drvdata->spinlock); + return -EINVAL; + } + + drvdata->addr_val[idx] = val; + drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_single); + +static ssize_t addr_range_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 idx; + unsigned long val1, val2; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (idx % 2 != 0) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE && + drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) || + (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE && + drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + val1 = drvdata->addr_val[idx]; + val2 = drvdata->addr_val[idx + 1]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx %#lx\n", val1, val2); +} + +static ssize_t addr_range_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 idx; + unsigned long val1, val2; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (sscanf(buf, "%lx %lx", &val1, &val2) != 2) + return -EINVAL; + /* Lower address comparator cannot have a higher address value */ + if (val1 > val2) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (idx % 2 != 0) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE && + drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) || + (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE && + drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + drvdata->addr_val[idx] = val1; + drvdata->addr_type[idx] = ETM_ADDR_TYPE_RANGE; + drvdata->addr_val[idx + 1] = val2; + drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE; + drvdata->enable_ctrl1 |= (1 << (idx/2)); + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_range); + +static ssize_t addr_start_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 idx; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + val = drvdata->addr_val[idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t addr_start_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 idx; + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + drvdata->addr_val[idx] = val; + drvdata->addr_type[idx] = ETM_ADDR_TYPE_START; + drvdata->startstop_ctrl |= (1 << idx); + drvdata->enable_ctrl1 |= BIT(25); + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_start); + +static ssize_t addr_stop_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 idx; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + val = drvdata->addr_val[idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t addr_stop_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 idx; + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + idx = drvdata->addr_idx; + if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE || + drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) { + spin_unlock(&drvdata->spinlock); + return -EPERM; + } + + drvdata->addr_val[idx] = val; + drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP; + drvdata->startstop_ctrl |= (1 << (idx + 16)); + drvdata->enable_ctrl1 |= ETMTECR1_START_STOP; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_stop); + +static ssize_t addr_acctype_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + val = drvdata->addr_acctype[drvdata->addr_idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t addr_acctype_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->addr_acctype[drvdata->addr_idx] = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(addr_acctype); + +static ssize_t cntr_idx_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->cntr_idx; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t cntr_idx_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + if (val >= drvdata->nr_cntr) + return -EINVAL; + /* + * Use spinlock to ensure index doesn't change while it gets + * dereferenced multiple times within a spinlock block elsewhere. + */ + spin_lock(&drvdata->spinlock); + drvdata->cntr_idx = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(cntr_idx); + +static ssize_t cntr_rld_val_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + val = drvdata->cntr_rld_val[drvdata->cntr_idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t cntr_rld_val_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->cntr_rld_val[drvdata->cntr_idx] = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(cntr_rld_val); + +static ssize_t cntr_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + val = drvdata->cntr_event[drvdata->cntr_idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t cntr_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->cntr_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(cntr_event); + +static ssize_t cntr_rld_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + val = drvdata->cntr_rld_event[drvdata->cntr_idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t cntr_rld_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->cntr_rld_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(cntr_rld_event); + +static ssize_t cntr_val_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, ret = 0; + u32 val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (!drvdata->enable) { + spin_lock(&drvdata->spinlock); + for (i = 0; i < drvdata->nr_cntr; i++) + ret += sprintf(buf, "counter %d: %x\n", + i, drvdata->cntr_val[i]); + spin_unlock(&drvdata->spinlock); + return ret; + } + + for (i = 0; i < drvdata->nr_cntr; i++) { + val = etm_readl(drvdata, ETMCNTVRn(i)); + ret += sprintf(buf, "counter %d: %x\n", i, val); + } + + return ret; +} + +static ssize_t cntr_val_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->cntr_val[drvdata->cntr_idx] = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(cntr_val); + +static ssize_t seq_12_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_12_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_12_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_12_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_12_event); + +static ssize_t seq_21_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_21_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_21_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_21_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_21_event); + +static ssize_t seq_23_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_23_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_23_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_23_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_23_event); + +static ssize_t seq_31_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_31_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_31_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_31_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_31_event); + +static ssize_t seq_32_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_32_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_32_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_32_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_32_event); + +static ssize_t seq_13_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->seq_13_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_13_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->seq_13_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(seq_13_event); + +static ssize_t seq_curr_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned long val, flags; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (!drvdata->enable) { + val = drvdata->seq_curr_state; + goto out; + } + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + + CS_UNLOCK(drvdata->base); + val = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK); + CS_LOCK(drvdata->base); + + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); +out: + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t seq_curr_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + if (val > ETM_SEQ_STATE_MAX_VAL) + return -EINVAL; + + drvdata->seq_curr_state = val; + + return size; +} +static DEVICE_ATTR_RW(seq_curr_state); + +static ssize_t ctxid_idx_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->ctxid_idx; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t ctxid_idx_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + if (val >= drvdata->nr_ctxid_cmp) + return -EINVAL; + + /* + * Use spinlock to ensure index doesn't change while it gets + * dereferenced multiple times within a spinlock block elsewhere. + */ + spin_lock(&drvdata->spinlock); + drvdata->ctxid_idx = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(ctxid_idx); + +static ssize_t ctxid_val_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + val = drvdata->ctxid_val[drvdata->ctxid_idx]; + spin_unlock(&drvdata->spinlock); + + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t ctxid_val_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + spin_lock(&drvdata->spinlock); + drvdata->ctxid_val[drvdata->ctxid_idx] = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(ctxid_val); + +static ssize_t ctxid_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->ctxid_mask; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t ctxid_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->ctxid_mask = val; + return size; +} +static DEVICE_ATTR_RW(ctxid_mask); + +static ssize_t sync_freq_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->sync_freq; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t sync_freq_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->sync_freq = val & ETM_SYNC_MASK; + return size; +} +static DEVICE_ATTR_RW(sync_freq); + +static ssize_t timestamp_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->timestamp_event; + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t timestamp_event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->timestamp_event = val & ETM_EVENT_MASK; + return size; +} +static DEVICE_ATTR_RW(timestamp_event); + +static ssize_t status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned long flags; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + + CS_UNLOCK(drvdata->base); + ret = sprintf(buf, + "ETMCCR: 0x%08x\n" + "ETMCCER: 0x%08x\n" + "ETMSCR: 0x%08x\n" + "ETMIDR: 0x%08x\n" + "ETMCR: 0x%08x\n" + "ETMTRACEIDR: 0x%08x\n" + "Enable event: 0x%08x\n" + "Enable start/stop: 0x%08x\n" + "Enable control: CR1 0x%08x CR2 0x%08x\n" + "CPU affinity: %d\n", + drvdata->etmccr, drvdata->etmccer, + etm_readl(drvdata, ETMSCR), etm_readl(drvdata, ETMIDR), + etm_readl(drvdata, ETMCR), etm_trace_id_simple(drvdata), + etm_readl(drvdata, ETMTEEVR), + etm_readl(drvdata, ETMTSSCR), + etm_readl(drvdata, ETMTECR1), + etm_readl(drvdata, ETMTECR2), + drvdata->cpu); + CS_LOCK(drvdata->base); + + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); + + return ret; +} +static DEVICE_ATTR_RO(status); + +static ssize_t traceid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned long val, flags; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (!drvdata->enable) { + val = drvdata->traceid; + goto out; + } + + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + spin_lock_irqsave(&drvdata->spinlock, flags); + CS_UNLOCK(drvdata->base); + + val = (etm_readl(drvdata, ETMTRACEIDR) & ETM_TRACEID_MASK); + + CS_LOCK(drvdata->base); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + clk_disable_unprepare(drvdata->clk); +out: + return sprintf(buf, "%#lx\n", val); +} + +static ssize_t traceid_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 16, &val); + if (ret) + return ret; + + drvdata->traceid = val & ETM_TRACEID_MASK; + return size; +} +static DEVICE_ATTR_RW(traceid); + +static struct attribute *coresight_etm_attrs[] = { + &dev_attr_nr_addr_cmp.attr, + &dev_attr_nr_cntr.attr, + &dev_attr_nr_ctxid_cmp.attr, + &dev_attr_etmsr.attr, + &dev_attr_reset.attr, + &dev_attr_mode.attr, + &dev_attr_trigger_event.attr, + &dev_attr_enable_event.attr, + &dev_attr_fifofull_level.attr, + &dev_attr_addr_idx.attr, + &dev_attr_addr_single.attr, + &dev_attr_addr_range.attr, + &dev_attr_addr_start.attr, + &dev_attr_addr_stop.attr, + &dev_attr_addr_acctype.attr, + &dev_attr_cntr_idx.attr, + &dev_attr_cntr_rld_val.attr, + &dev_attr_cntr_event.attr, + &dev_attr_cntr_rld_event.attr, + &dev_attr_cntr_val.attr, + &dev_attr_seq_12_event.attr, + &dev_attr_seq_21_event.attr, + &dev_attr_seq_23_event.attr, + &dev_attr_seq_31_event.attr, + &dev_attr_seq_32_event.attr, + &dev_attr_seq_13_event.attr, + &dev_attr_seq_curr_state.attr, + &dev_attr_ctxid_idx.attr, + &dev_attr_ctxid_val.attr, + &dev_attr_ctxid_mask.attr, + &dev_attr_sync_freq.attr, + &dev_attr_timestamp_event.attr, + &dev_attr_status.attr, + &dev_attr_traceid.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_etm); + +static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action, + void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + if (!etmdrvdata[cpu]) + goto out; + + switch (action & (~CPU_TASKS_FROZEN)) { + case CPU_STARTING: + spin_lock(&etmdrvdata[cpu]->spinlock); + if (!etmdrvdata[cpu]->os_unlock) { + etm_os_unlock(etmdrvdata[cpu]); + etmdrvdata[cpu]->os_unlock = true; + } + + if (etmdrvdata[cpu]->enable) + etm_enable_hw(etmdrvdata[cpu]); + spin_unlock(&etmdrvdata[cpu]->spinlock); + break; + + case CPU_ONLINE: + if (etmdrvdata[cpu]->boot_enable && + !etmdrvdata[cpu]->sticky_enable) + coresight_enable(etmdrvdata[cpu]->csdev); + break; + + case CPU_DYING: + spin_lock(&etmdrvdata[cpu]->spinlock); + if (etmdrvdata[cpu]->enable) + etm_disable_hw(etmdrvdata[cpu]); + spin_unlock(&etmdrvdata[cpu]->spinlock); + break; + } +out: + return NOTIFY_OK; +} + +static struct notifier_block etm_cpu_notifier = { + .notifier_call = etm_cpu_callback, +}; + +static bool etm_arch_supported(u8 arch) +{ + switch (arch) { + case ETM_ARCH_V3_3: + break; + case ETM_ARCH_V3_5: + break; + case PFT_ARCH_V1_0: + break; + case PFT_ARCH_V1_1: + break; + default: + return false; + } + return true; +} + +static void etm_init_arch_data(void *info) +{ + u32 etmidr; + u32 etmccr; + struct etm_drvdata *drvdata = info; + + CS_UNLOCK(drvdata->base); + + /* First dummy read */ + (void)etm_readl(drvdata, ETMPDSR); + /* Provide power to ETM: ETMPDCR[3] == 1 */ + etm_set_pwrup(drvdata); + /* + * Clear power down bit since when this bit is set writes to + * certain registers might be ignored. + */ + etm_clr_pwrdwn(drvdata); + /* + * Set prog bit. It will be set from reset but this is included to + * ensure it is set + */ + etm_set_prog(drvdata); + + /* Find all capabilities */ + etmidr = etm_readl(drvdata, ETMIDR); + drvdata->arch = BMVAL(etmidr, 4, 11); + drvdata->port_size = etm_readl(drvdata, ETMCR) & PORT_SIZE_MASK; + + drvdata->etmccer = etm_readl(drvdata, ETMCCER); + etmccr = etm_readl(drvdata, ETMCCR); + drvdata->etmccr = etmccr; + drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2; + drvdata->nr_cntr = BMVAL(etmccr, 13, 15); + drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19); + drvdata->nr_ext_out = BMVAL(etmccr, 20, 22); + drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25); + + etm_set_pwrdwn(drvdata); + etm_clr_pwrup(drvdata); + CS_LOCK(drvdata->base); +} + +static void etm_init_default_data(struct etm_drvdata *drvdata) +{ + static int etm3x_traceid; + + u32 flags = (1 << 0 | /* instruction execute*/ + 3 << 3 | /* ARM instruction */ + 0 << 5 | /* No data value comparison */ + 0 << 7 | /* No exact mach */ + 0 << 8 | /* Ignore context ID */ + 0 << 10); /* Security ignored */ + + /* + * Initial configuration only - guarantees sources handled by + * this driver have a unique ID at startup time but not between + * all other types of sources. For that we lean on the core + * framework. + */ + drvdata->traceid = etm3x_traceid++; + drvdata->ctrl = (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN); + drvdata->enable_ctrl1 = ETMTECR1_ADDR_COMP_1; + if (drvdata->nr_addr_cmp >= 2) { + drvdata->addr_val[0] = (u32) _stext; + drvdata->addr_val[1] = (u32) _etext; + drvdata->addr_acctype[0] = flags; + drvdata->addr_acctype[1] = flags; + drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE; + drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE; + } + + etm_set_default(drvdata); +} + +static int etm_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + void __iomem *base; + struct device *dev = &adev->dev; + struct coresight_platform_data *pdata = NULL; + struct etm_drvdata *drvdata; + struct resource *res = &adev->res; + struct coresight_desc *desc; + struct device_node *np = adev->dev.of_node; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + + adev->dev.platform_data = pdata; + drvdata->use_cp14 = of_property_read_bool(np, "arm,cp14"); + } + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + + spin_lock_init(&drvdata->spinlock); + + drvdata->clk = adev->pclk; + ret = clk_prepare_enable(drvdata->clk); + if (ret) + return ret; + + drvdata->cpu = pdata ? pdata->cpu : 0; + + get_online_cpus(); + etmdrvdata[drvdata->cpu] = drvdata; + + if (!smp_call_function_single(drvdata->cpu, etm_os_unlock, drvdata, 1)) + drvdata->os_unlock = true; + + if (smp_call_function_single(drvdata->cpu, + etm_init_arch_data, drvdata, 1)) + dev_err(dev, "ETM arch init failed\n"); + + if (!etm_count++) + register_hotcpu_notifier(&etm_cpu_notifier); + + put_online_cpus(); + + if (etm_arch_supported(drvdata->arch) == false) { + ret = -EINVAL; + goto err_arch_supported; + } + etm_init_default_data(drvdata); + + clk_disable_unprepare(drvdata->clk); + + desc->type = CORESIGHT_DEV_TYPE_SOURCE; + desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; + desc->ops = &etm_cs_ops; + desc->pdata = pdata; + desc->dev = dev; + desc->groups = coresight_etm_groups; + drvdata->csdev = coresight_register(desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err_arch_supported; + } + + dev_info(dev, "ETM initialized\n"); + + if (boot_enable) { + coresight_enable(drvdata->csdev); + drvdata->boot_enable = true; + } + + return 0; + +err_arch_supported: + clk_disable_unprepare(drvdata->clk); + if (--etm_count == 0) + unregister_hotcpu_notifier(&etm_cpu_notifier); + return ret; +} + +static int etm_remove(struct amba_device *adev) +{ + struct etm_drvdata *drvdata = amba_get_drvdata(adev); + + coresight_unregister(drvdata->csdev); + if (--etm_count == 0) + unregister_hotcpu_notifier(&etm_cpu_notifier); + + return 0; +} + +static struct amba_id etm_ids[] = { + { /* ETM 3.3 */ + .id = 0x0003b921, + .mask = 0x0003ffff, + }, + { /* ETM 3.5 */ + .id = 0x0003b956, + .mask = 0x0003ffff, + }, + { /* PTM 1.0 */ + .id = 0x0003b950, + .mask = 0x0003ffff, + }, + { /* PTM 1.1 */ + .id = 0x0003b95f, + .mask = 0x0003ffff, + }, + { 0, 0}, +}; + +static struct amba_driver etm_driver = { + .drv = { + .name = "coresight-etm3x", + .owner = THIS_MODULE, + }, + .probe = etm_probe, + .remove = etm_remove, + .id_table = etm_ids, +}; + +int __init etm_init(void) +{ + return amba_driver_register(&etm_driver); +} +module_init(etm_init); + +void __exit etm_exit(void) +{ + amba_driver_unregister(&etm_driver); +} +module_exit(etm_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CoreSight Program Flow Trace driver"); -- GitLab From 872234d3fb32e26d3377590c396858d2324b8c16 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 3 Nov 2014 11:07:42 -0700 Subject: [PATCH 3970/9457] coresight: documentation for coresight framework and drivers Documentation containing an explanation on what the framework provides and the drivers working with it. A minimal example on how to use the functionality is also provided. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- Documentation/trace/coresight.txt | 299 ++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 Documentation/trace/coresight.txt diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight.txt new file mode 100644 index 000000000000..bba7dbfc49ed --- /dev/null +++ b/Documentation/trace/coresight.txt @@ -0,0 +1,299 @@ + Coresight - HW Assisted Tracing on ARM + ====================================== + + Author: Mathieu Poirier + Date: September 11th, 2014 + +Introduction +------------ + +Coresight is an umbrella of technologies allowing for the debugging of ARM +based SoC. It includes solutions for JTAG and HW assisted tracing. This +document is concerned with the latter. + +HW assisted tracing is becoming increasingly useful when dealing with systems +that have many SoCs and other components like GPU and DMA engines. ARM has +developed a HW assisted tracing solution by means of different components, each +being added to a design at systhesis time to cater to specific tracing needs. +Compoments are generally categorised as source, link and sinks and are +(usually) discovered using the AMBA bus. + +"Sources" generate a compressed stream representing the processor instruction +path based on tracing scenarios as configured by users. From there the stream +flows through the coresight system (via ATB bus) using links that are connecting +the emanating source to a sink(s). Sinks serve as endpoints to the coresight +implementation, either storing the compressed stream in a memory buffer or +creating an interface to the outside world where data can be transferred to a +host without fear of filling up the onboard coresight memory buffer. + +At typical coresight system would look like this: + + ***************************************************************** + **************************** AMBA AXI ****************************===|| + ***************************************************************** || + ^ ^ | || + | | * ** + 0000000 ::::: 0000000 ::::: ::::: @@@@@@@ |||||||||||| + 0 CPU 0<-->: C : 0 CPU 0<-->: C : : C : @ STM @ || System || + |->0000000 : T : |->0000000 : T : : T :<--->@@@@@ || Memory || + | #######<-->: I : | #######<-->: I : : I : @@@<-| |||||||||||| + | # ETM # ::::: | # PTM # ::::: ::::: @ | + | ##### ^ ^ | ##### ^ ! ^ ! . | ||||||||| + | |->### | ! | |->### | ! | ! . | || DAP || + | | # | ! | | # | ! | ! . | ||||||||| + | | . | ! | | . | ! | ! . | | | + | | . | ! | | . | ! | ! . | | * + | | . | ! | | . | ! | ! . | | SWD/ + | | . | ! | | . | ! | ! . | | JTAG + *****************************************************************<-| + *************************** AMBA Debug ABP ************************ + ***************************************************************** + | . ! . ! ! . | + | . * . * * . | + ***************************************************************** + ******************** Cross Trigger Matrix (CTM) ******************* + ***************************************************************** + | . ^ . . | + | * ! * * | + ***************************************************************** + ****************** AMBA Advanced Trace Bus (ATB) ****************** + ***************************************************************** + | ! =============== | + | * ===== F =====<---------| + | ::::::::: ==== U ==== + |-->:: CTI ::&& ETB &&<......II I ======= + | ! &&&&&&&&& II I . + | ! I I . + | ! I REP I<.......... + | ! I I + | !!>&&&&&&&&& II I *Source: ARM ltd. + |------>& TPIU &<......II I DAP = Debug Access Port + &&&&&&&&& IIIIIII ETM = Embedded Trace Macrocell + ; PTM = Program Trace Macrocell + ; CTI = Cross Trigger Interface + * ETB = Embedded Trace Buffer + To trace port TPIU= Trace Port Interface Unit + SWD = Serial Wire Debug + +While on target configuration of the components is done via the ABP bus, +all trace data are carried out-of-band on the ATB bus. The CTM provides +a way to aggregate and distribute signals between CoreSight components. + +The coresight framework provides a central point to represent, configure and +manage coresight devices on a platform. This first implementation centers on +the basic tracing functionality, enabling components such ETM/PTM, funnel, +replicator, TMC, TPIU and ETB. Future work will enable more +intricate IP blocks such as STM and CTI. + + +Acronyms and Classification +--------------------------- + +Acronyms: + +PTM: Program Trace Macrocell +ETM: Embedded Trace Macrocell +STM: System trace Macrocell +ETB: Embedded Trace Buffer +ITM: Instrumentation Trace Macrocell +TPIU: Trace Port Interface Unit +TMC-ETR: Trace Memory Controller, configured as Embedded Trace Router +TMC-ETF: Trace Memory Controller, configured as Embedded Trace FIFO +CTI: Cross Trigger Interface + +Classification: + +Source: + ETMv3.x ETMv4, PTMv1.0, PTMv1.1, STM, STM500, ITM +Link: + Funnel, replicator (intelligent or not), TMC-ETR +Sinks: + ETBv1.0, ETB1.1, TPIU, TMC-ETF +Misc: + CTI + + +Device Tree Bindings +---------------------- + +See Documentation/devicetree/bindings/arm/coresight.txt for details. + +As of this writing drivers for ITM, STMs and CTIs are not provided but are +expected to be added as the solution matures. + + +Framework and implementation +---------------------------- + +The coresight framework provides a central point to represent, configure and +manage coresight devices on a platform. Any coresight compliant device can +register with the framework for as long as they use the right APIs: + +struct coresight_device *coresight_register(struct coresight_desc *desc); +void coresight_unregister(struct coresight_device *csdev); + +The registering function is taking a "struct coresight_device *csdev" and +register the device with the core framework. The unregister function takes +a reference to a "strut coresight_device", obtained at registration time. + +If everything goes well during the registration process the new devices will +show up under /sys/bus/coresight/devices, as showns here for a TC2 platform: + +root:~# ls /sys/bus/coresight/devices/ +replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm +20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm +root:~# + +The functions take a "struct coresight_device", which looks like this: + +struct coresight_desc { + enum coresight_dev_type type; + struct coresight_dev_subtype subtype; + const struct coresight_ops *ops; + struct coresight_platform_data *pdata; + struct device *dev; + const struct attribute_group **groups; +}; + + +The "coresight_dev_type" identifies what the device is, i.e, source link or +sink while the "coresight_dev_subtype" will characterise that type further. + +The "struct coresight_ops" is mandatory and will tell the framework how to +perform base operations related to the components, each component having +a different set of requirement. For that "struct coresight_ops_sink", +"struct coresight_ops_link" and "struct coresight_ops_source" have been +provided. + +The next field, "struct coresight_platform_data *pdata" is acquired by calling +"of_get_coresight_platform_data()", as part of the driver's _probe routine and +"struct device *dev" gets the device reference embedded in the "amba_device": + +static int etm_probe(struct amba_device *adev, const struct amba_id *id) +{ + ... + ... + drvdata->dev = &adev->dev; + ... +} + +Specific class of device (source, link, or sink) have generic operations +that can be performed on them (see "struct coresight_ops"). The +"**groups" is a list of sysfs entries pertaining to operations +specific to that component only. "Implementation defined" customisations are +expected to be accessed and controlled using those entries. + +Last but not least, "struct module *owner" is expected to be set to reflect +the information carried in "THIS_MODULE". + +How to use +---------- + +Before trace collection can start, a coresight sink needs to be identify. +There is no limit on the amount of sinks (nor sources) that can be enabled at +any given moment. As a generic operation, all device pertaining to the sink +class will have an "active" entry in sysfs: + +root:/sys/bus/coresight/devices# ls +replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm +20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm +root:/sys/bus/coresight/devices# ls 20010000.etb +enable_sink status trigger_cntr +root:/sys/bus/coresight/devices# echo 1 > 20010000.etb/enable_sink +root:/sys/bus/coresight/devices# cat 20010000.etb/enable_sink +1 +root:/sys/bus/coresight/devices# + +At boot time the current etm3x driver will configure the first address +comparator with "_stext" and "_etext", essentially tracing any instruction +that falls within that range. As such "enabling" a source will immediately +trigger a trace capture: + +root:/sys/bus/coresight/devices# echo 1 > 2201c000.ptm/enable_source +root:/sys/bus/coresight/devices# cat 2201c000.ptm/enable_source +1 +root:/sys/bus/coresight/devices# cat 20010000.etb/status +Depth: 0x2000 +Status: 0x1 +RAM read ptr: 0x0 +RAM wrt ptr: 0x19d3 <----- The write pointer is moving +Trigger cnt: 0x0 +Control: 0x1 +Flush status: 0x0 +Flush ctrl: 0x2001 +root:/sys/bus/coresight/devices# + +Trace collection is stopped the same way: + +root:/sys/bus/coresight/devices# echo 0 > 2201c000.ptm/enable_source +root:/sys/bus/coresight/devices# + +The content of the ETB buffer can be harvested directly from /dev: + +root:/sys/bus/coresight/devices# dd if=/dev/20010000.etb \ +of=~/cstrace.bin + +64+0 records in +64+0 records out +32768 bytes (33 kB) copied, 0.00125258 s, 26.2 MB/s +root:/sys/bus/coresight/devices# + +The file cstrace.bin can be decompressed using "ptm2human", DS-5 or Trace32. + +Following is a DS-5 output of an experimental loop that increments a variable up +to a certain value. The example is simple and yet provides a glimpse of the +wealth of possibilities that coresight provides. + +Info Tracing enabled +Instruction 106378866 0x8026B53C E52DE004 false PUSH {lr} +Instruction 0 0x8026B540 E24DD00C false SUB sp,sp,#0xc +Instruction 0 0x8026B544 E3A03000 false MOV r3,#0 +Instruction 0 0x8026B548 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Timestamp Timestamp: 17106715833 +Instruction 319 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Instruction 9 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Instruction 7 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Instruction 10 0x8026B54C E59D3004 false LDR r3,[sp,#4] +Instruction 0 0x8026B550 E3530004 false CMP r3,#4 +Instruction 0 0x8026B554 E2833001 false ADD r3,r3,#1 +Instruction 0 0x8026B558 E58D3004 false STR r3,[sp,#4] +Instruction 0 0x8026B55C DAFFFFFA true BLE {pc}-0x10 ; 0x8026b54c +Instruction 6 0x8026B560 EE1D3F30 false MRC p15,#0x0,r3,c13,c0,#1 +Instruction 0 0x8026B564 E1A0100D false MOV r1,sp +Instruction 0 0x8026B568 E3C12D7F false BIC r2,r1,#0x1fc0 +Instruction 0 0x8026B56C E3C2203F false BIC r2,r2,#0x3f +Instruction 0 0x8026B570 E59D1004 false LDR r1,[sp,#4] +Instruction 0 0x8026B574 E59F0010 false LDR r0,[pc,#16] ; [0x8026B58C] = 0x80550368 +Instruction 0 0x8026B578 E592200C false LDR r2,[r2,#0xc] +Instruction 0 0x8026B57C E59221D0 false LDR r2,[r2,#0x1d0] +Instruction 0 0x8026B580 EB07A4CF true BL {pc}+0x1e9344 ; 0x804548c4 +Info Tracing enabled +Instruction 13570831 0x8026B584 E28DD00C false ADD sp,sp,#0xc +Instruction 0 0x8026B588 E8BD8000 true LDM sp!,{pc} +Timestamp Timestamp: 17107041535 -- GitLab From 9d31620268a71f4d9ad1f6b72b3fff7b25cd02b9 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 3 Nov 2014 11:07:43 -0700 Subject: [PATCH 3971/9457] coresight: adding support for beagle and beagleXM Currently supporting ETM and ETB. Support for TPIU and SDTI are yet to be added. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/omap3-beagle-xm.dts | 28 +++++++++++++++++++++++++++ arch/arm/boot/dts/omap3-beagle.dts | 28 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 06a8aec4e6ea..25f7b0a22114 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -145,6 +145,34 @@ }; }; }; + + etb@5401b000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0x5401b000 0x1000>; + + coresight-default-sink; + clocks = <&emu_src_ck>; + clock-names = "apb_pclk"; + port { + etb_in: endpoint { + slave-mode; + remote-endpoint = <&etm_out>; + }; + }; + }; + + etm@54010000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0x54010000 0x1000>; + + clocks = <&emu_src_ck>; + clock-names = "apb_pclk"; + port { + etm_out: endpoint { + remote-endpoint = <&etb_in>; + }; + }; + }; }; &omap3_pmx_wkup { diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index a9aae88b74f5..c792391ef090 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -140,6 +140,34 @@ }; }; }; + + etb@540000000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0x5401b000 0x1000>; + + coresight-default-sink; + clocks = <&emu_src_ck>; + clock-names = "apb_pclk"; + port { + etb_in: endpoint { + slave-mode; + remote-endpoint = <&etm_out>; + }; + }; + }; + + etm@54010000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0x54010000 0x1000>; + + clocks = <&emu_src_ck>; + clock-names = "apb_pclk"; + port { + etm_out: endpoint { + remote-endpoint = <&etb_in>; + }; + }; + }; }; &omap3_pmx_wkup { -- GitLab From 0bec8d82bd112f6aa0e16cab5d840bd7f5d3a7ce Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 3 Nov 2014 11:07:44 -0700 Subject: [PATCH 3972/9457] coresight: adding basic support for Vexpress TC2 Support for the 2 PTMs, 3 ETMs, funnel, TPIU and replicator connected to the ETB are included. Proper handling of the ITM and the replicator linked to it along with the CTIs and SWO are not included. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 199 +++++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 322fd1519b09..33920df03640 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -358,6 +358,205 @@ }; }; + etb@0,20010000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0x20010000 0 0x1000>; + + coresight-default-sink; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + etb_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator_out_port0>; + }; + }; + }; + + tpiu@0,20030000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0 0x20030000 0 0x1000>; + + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + tpiu_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator_out_port1>; + }; + }; + }; + + replicator { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator_out_port0: endpoint { + remote-endpoint = <&etb_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator_out_port1: endpoint { + remote-endpoint = <&tpiu_in_port>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator_in_port0: endpoint { + slave-mode; + remote-endpoint = <&funnel_out_port0>; + }; + }; + }; + }; + + funnel@0,20040000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0x20040000 0 0x1000>; + + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel_out_port0: endpoint { + remote-endpoint = + <&replicator_in_port0>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel_in_port0: endpoint { + slave-mode; + remote-endpoint = <&ptm0_out_port>; + }; + }; + + port@2 { + reg = <1>; + funnel_in_port1: endpoint { + slave-mode; + remote-endpoint = <&ptm1_out_port>; + }; + }; + + port@3 { + reg = <2>; + funnel_in_port2: endpoint { + slave-mode; + remote-endpoint = <&etm0_out_port>; + }; + }; + + /* Input port #3 is for ITM, not supported here */ + + port@4 { + reg = <4>; + funnel_in_port4: endpoint { + slave-mode; + remote-endpoint = <&etm1_out_port>; + }; + }; + + port@5 { + reg = <5>; + funnel_in_port5: endpoint { + slave-mode; + remote-endpoint = <&etm2_out_port>; + }; + }; + }; + }; + + ptm@0,2201c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2201c000 0 0x1000>; + + cpu = <&cpu0>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + ptm0_out_port: endpoint { + remote-endpoint = <&funnel_in_port0>; + }; + }; + }; + + ptm@0,2201d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2201d000 0 0x1000>; + + cpu = <&cpu1>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + ptm1_out_port: endpoint { + remote-endpoint = <&funnel_in_port1>; + }; + }; + }; + + etm@0,2203c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203c000 0 0x1000>; + + cpu = <&cpu2>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + etm0_out_port: endpoint { + remote-endpoint = <&funnel_in_port2>; + }; + }; + }; + + etm@0,2203d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203d000 0 0x1000>; + + cpu = <&cpu3>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + etm1_out_port: endpoint { + remote-endpoint = <&funnel_in_port4>; + }; + }; + }; + + etm@0,2203e000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203e000 0 0x1000>; + + cpu = <&cpu4>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + port { + etm2_out_port: endpoint { + remote-endpoint = <&funnel_in_port5>; + }; + }; + }; + smb { compatible = "simple-bus"; -- GitLab From 4d5616ca59350c47e4b00d17c1480d8b44d3c535 Mon Sep 17 00:00:00 2001 From: Xia Kaixu Date: Mon, 3 Nov 2014 11:07:45 -0700 Subject: [PATCH 3973/9457] coresight: adding basic support for D01 board Support for 16 PTMs, funnel, TPIU and replicator connected to the ETB are included. Signed-off-by: Xia Kaixu Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/hip04.dtsi | 717 +++++++++++++++++++++++++++++++++++ 1 file changed, 717 insertions(+) diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi index 93b6c909e991..238814596a87 100644 --- a/arch/arm/boot/dts/hip04.dtsi +++ b/arch/arm/boot/dts/hip04.dtsi @@ -190,6 +190,12 @@ clock-frequency = <168000000>; }; + clk_375m: clk_375m { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <375000000>; + }; + soc { /* It's a 32-bit SoC. */ #address-cells = <1>; @@ -264,4 +270,715 @@ }; }; + + etb@0,e3c42000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0xe3c42000 0 0x1000>; + + coresight-default-sink; + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + port { + etb0_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator0_out_port0>; + }; + }; + }; + + etb@0,e3c82000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0xe3c82000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + port { + etb1_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator1_out_port0>; + }; + }; + }; + + etb@0,e3cc2000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0xe3cc2000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + port { + etb2_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator2_out_port0>; + }; + }; + }; + + etb@0,e3d02000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0xe3d02000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + port { + etb3_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&replicator3_out_port0>; + }; + }; + }; + + tpiu@0,e3c05000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0 0xe3c05000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + port { + tpiu_in_port: endpoint@0 { + slave-mode; + remote-endpoint = <&funnel4_out_port0>; + }; + }; + }; + + replicator0 { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator0_out_port0: endpoint { + remote-endpoint = <&etb0_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator0_out_port1: endpoint { + remote-endpoint = <&funnel4_in_port0>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator0_in_port0: endpoint { + slave-mode; + remote-endpoint = <&funnel0_out_port0>; + }; + }; + }; + }; + + replicator1 { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator1_out_port0: endpoint { + remote-endpoint = <&etb1_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator1_out_port1: endpoint { + remote-endpoint = <&funnel4_in_port1>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator1_in_port0: endpoint { + slave-mode; + remote-endpoint = <&funnel1_out_port0>; + }; + }; + }; + }; + + replicator2 { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator2_out_port0: endpoint { + remote-endpoint = <&etb2_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator2_out_port1: endpoint { + remote-endpoint = <&funnel4_in_port2>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator2_in_port0: endpoint { + slave-mode; + remote-endpoint = <&funnel2_out_port0>; + }; + }; + }; + }; + + replicator3 { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* replicator output ports */ + port@0 { + reg = <0>; + replicator3_out_port0: endpoint { + remote-endpoint = <&etb3_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator3_out_port1: endpoint { + remote-endpoint = <&funnel4_in_port3>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator3_in_port0: endpoint { + slave-mode; + remote-endpoint = <&funnel3_out_port0>; + }; + }; + }; + }; + + funnel@0,e3c41000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0xe3c41000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel0_out_port0: endpoint { + remote-endpoint = + <&replicator0_in_port0>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel0_in_port0: endpoint { + slave-mode; + remote-endpoint = <&ptm0_out_port>; + }; + }; + + port@2 { + reg = <1>; + funnel0_in_port1: endpoint { + slave-mode; + remote-endpoint = <&ptm1_out_port>; + }; + }; + + port@3 { + reg = <2>; + funnel0_in_port2: endpoint { + slave-mode; + remote-endpoint = <&ptm2_out_port>; + }; + }; + + port@4 { + reg = <3>; + funnel0_in_port3: endpoint { + slave-mode; + remote-endpoint = <&ptm3_out_port>; + }; + }; + }; + }; + + funnel@0,e3c81000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0xe3c81000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel1_out_port0: endpoint { + remote-endpoint = + <&replicator1_in_port0>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel1_in_port0: endpoint { + slave-mode; + remote-endpoint = <&ptm4_out_port>; + }; + }; + + port@2 { + reg = <1>; + funnel1_in_port1: endpoint { + slave-mode; + remote-endpoint = <&ptm5_out_port>; + }; + }; + + port@3 { + reg = <2>; + funnel1_in_port2: endpoint { + slave-mode; + remote-endpoint = <&ptm6_out_port>; + }; + }; + + port@4 { + reg = <3>; + funnel1_in_port3: endpoint { + slave-mode; + remote-endpoint = <&ptm7_out_port>; + }; + }; + }; + }; + + funnel@0,e3cc1000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0xe3cc1000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel2_out_port0: endpoint { + remote-endpoint = + <&replicator2_in_port0>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel2_in_port0: endpoint { + slave-mode; + remote-endpoint = <&ptm8_out_port>; + }; + }; + + port@2 { + reg = <1>; + funnel2_in_port1: endpoint { + slave-mode; + remote-endpoint = <&ptm9_out_port>; + }; + }; + + port@3 { + reg = <2>; + funnel2_in_port2: endpoint { + slave-mode; + remote-endpoint = <&ptm10_out_port>; + }; + }; + + port@4 { + reg = <3>; + funnel2_in_port3: endpoint { + slave-mode; + remote-endpoint = <&ptm11_out_port>; + }; + }; + }; + }; + + funnel@0,e3d01000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0xe3d01000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel3_out_port0: endpoint { + remote-endpoint = + <&replicator3_in_port0>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel3_in_port0: endpoint { + slave-mode; + remote-endpoint = <&ptm12_out_port>; + }; + }; + + port@2 { + reg = <1>; + funnel3_in_port1: endpoint { + slave-mode; + remote-endpoint = <&ptm13_out_port>; + }; + }; + + port@3 { + reg = <2>; + funnel3_in_port2: endpoint { + slave-mode; + remote-endpoint = <&ptm14_out_port>; + }; + }; + + port@4 { + reg = <3>; + funnel3_in_port3: endpoint { + slave-mode; + remote-endpoint = <&ptm15_out_port>; + }; + }; + }; + }; + + funnel@0,e3c04000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0xe3c04000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* funnel output port */ + port@0 { + reg = <0>; + funnel4_out_port0: endpoint { + remote-endpoint = <&tpiu_in_port>; + }; + }; + + /* funnel input ports */ + port@1 { + reg = <0>; + funnel4_in_port0: endpoint { + slave-mode; + remote-endpoint = + <&replicator0_out_port1>; + }; + }; + + port@2 { + reg = <1>; + funnel4_in_port1: endpoint { + slave-mode; + remote-endpoint = + <&replicator1_out_port1>; + }; + }; + + port@3 { + reg = <2>; + funnel4_in_port2: endpoint { + slave-mode; + remote-endpoint = + <&replicator2_out_port1>; + }; + }; + + port@4 { + reg = <3>; + funnel4_in_port3: endpoint { + slave-mode; + remote-endpoint = + <&replicator3_out_port1>; + }; + }; + }; + }; + + ptm@0,e3c7c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3c7c000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU0>; + port { + ptm0_out_port: endpoint { + remote-endpoint = <&funnel0_in_port0>; + }; + }; + }; + + ptm@0,e3c7d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3c7d000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU1>; + port { + ptm1_out_port: endpoint { + remote-endpoint = <&funnel0_in_port1>; + }; + }; + }; + + ptm@0,e3c7e000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3c7e000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU2>; + port { + ptm2_out_port: endpoint { + remote-endpoint = <&funnel0_in_port2>; + }; + }; + }; + + ptm@0,e3c7f000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3c7f000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU3>; + port { + ptm3_out_port: endpoint { + remote-endpoint = <&funnel0_in_port3>; + }; + }; + }; + + ptm@0,e3cbc000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cbc000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU4>; + port { + ptm4_out_port: endpoint { + remote-endpoint = <&funnel1_in_port0>; + }; + }; + }; + + ptm@0,e3cbd000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cbd000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU5>; + port { + ptm5_out_port: endpoint { + remote-endpoint = <&funnel1_in_port1>; + }; + }; + }; + + ptm@0,e3cbe000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cbe000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU6>; + port { + ptm6_out_port: endpoint { + remote-endpoint = <&funnel1_in_port2>; + }; + }; + }; + + ptm@0,e3cbf000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cbf000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU7>; + port { + ptm7_out_port: endpoint { + remote-endpoint = <&funnel1_in_port3>; + }; + }; + }; + + ptm@0,e3cfc000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cfc000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU8>; + port { + ptm8_out_port: endpoint { + remote-endpoint = <&funnel2_in_port0>; + }; + }; + }; + + ptm@0,e3cfd000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cfd000 0 0x1000>; + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU9>; + port { + ptm9_out_port: endpoint { + remote-endpoint = <&funnel2_in_port1>; + }; + }; + }; + + ptm@0,e3cfe000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cfe000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU10>; + port { + ptm10_out_port: endpoint { + remote-endpoint = <&funnel2_in_port2>; + }; + }; + }; + + ptm@0,e3cff000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3cff000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU11>; + port { + ptm11_out_port: endpoint { + remote-endpoint = <&funnel2_in_port3>; + }; + }; + }; + + ptm@0,e3d3c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3d3c000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU12>; + port { + ptm12_out_port: endpoint { + remote-endpoint = <&funnel3_in_port0>; + }; + }; + }; + + ptm@0,e3d3d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3d3d000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU13>; + port { + ptm13_out_port: endpoint { + remote-endpoint = <&funnel3_in_port1>; + }; + }; + }; + + ptm@0,e3d3e000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3d3e000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU14>; + port { + ptm14_out_port: endpoint { + remote-endpoint = <&funnel3_in_port2>; + }; + }; + }; + + ptm@0,e3d3f000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0xe3d3f000 0 0x1000>; + + clocks = <&clk_375m>; + clock-names = "apb_pclk"; + cpu = <&CPU15>; + port { + ptm15_out_port: endpoint { + remote-endpoint = <&funnel3_in_port3>; + }; + }; + }; }; -- GitLab From 184901a06a366d40386e07307bcadc9eeaabbd39 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 3 Nov 2014 11:07:46 -0700 Subject: [PATCH 3974/9457] ARM: removing support for etb/etm in "arch/arm/kernel/" Removing minimal support for etb/etm to favour an implementation that is more flexible, extensible and capable of handling more platforms. Also removing the only client of the old driver. That code can easily be replaced by entries for etb/etm in the device tree. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- arch/arm/Kconfig.debug | 8 - arch/arm/include/asm/hardware/coresight.h | 157 ------ arch/arm/kernel/Makefile | 1 - arch/arm/kernel/etm.c | 654 ---------------------- arch/arm/kernel/hw_breakpoint.c | 4 +- arch/arm/mach-omap2/Kconfig | 8 - arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/emu.c | 50 -- 8 files changed, 2 insertions(+), 881 deletions(-) delete mode 100644 arch/arm/include/asm/hardware/coresight.h delete mode 100644 arch/arm/kernel/etm.c delete mode 100644 arch/arm/mach-omap2/emu.c diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 871404bc9e47..8226788390a6 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1297,14 +1297,6 @@ config EARLY_PRINTK kernel low-level debugging functions. Add earlyprintk to your kernel parameters to enable this console. -config OC_ETM - bool "On-chip ETM and ETB" - depends on ARM_AMBA - help - Enables the on-chip embedded trace macrocell and embedded trace - buffer driver that will allow you to collect traces of the - kernel code. - config ARM_KPROBES_TEST tristate "Kprobes test module" depends on KPROBES && MODULES diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h deleted file mode 100644 index ad774f37c47c..000000000000 --- a/arch/arm/include/asm/hardware/coresight.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * linux/arch/arm/include/asm/hardware/coresight.h - * - * CoreSight components' registers - * - * Copyright (C) 2009 Nokia Corporation. - * Alexander Shishkin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_HARDWARE_CORESIGHT_H -#define __ASM_HARDWARE_CORESIGHT_H - -#define TRACER_ACCESSED_BIT 0 -#define TRACER_RUNNING_BIT 1 -#define TRACER_CYCLE_ACC_BIT 2 -#define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT) -#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) -#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) - -#define TRACER_TIMEOUT 10000 - -#define etm_writel(t, v, x) \ - (writel_relaxed((v), (t)->etm_regs + (x))) -#define etm_readl(t, x) (readl_relaxed((t)->etm_regs + (x))) - -/* CoreSight Management Registers */ -#define CSMR_LOCKACCESS 0xfb0 -#define CSMR_LOCKSTATUS 0xfb4 -#define CSMR_AUTHSTATUS 0xfb8 -#define CSMR_DEVID 0xfc8 -#define CSMR_DEVTYPE 0xfcc -/* CoreSight Component Registers */ -#define CSCR_CLASS 0xff4 - -#define CS_LAR_KEY 0xc5acce55 - -/* ETM control register, "ETM Architecture", 3.3.1 */ -#define ETMR_CTRL 0 -#define ETMCTRL_POWERDOWN 1 -#define ETMCTRL_PROGRAM (1 << 10) -#define ETMCTRL_PORTSEL (1 << 11) -#define ETMCTRL_DO_CONTEXTID (3 << 14) -#define ETMCTRL_PORTMASK1 (7 << 4) -#define ETMCTRL_PORTMASK2 (1 << 21) -#define ETMCTRL_PORTMASK (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2) -#define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21) -#define ETMCTRL_DO_CPRT (1 << 1) -#define ETMCTRL_DATAMASK (3 << 2) -#define ETMCTRL_DATA_DO_DATA (1 << 2) -#define ETMCTRL_DATA_DO_ADDR (1 << 3) -#define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR) -#define ETMCTRL_BRANCH_OUTPUT (1 << 8) -#define ETMCTRL_CYCLEACCURATE (1 << 12) - -/* ETM configuration code register */ -#define ETMR_CONFCODE (0x04) - -/* ETM trace start/stop resource control register */ -#define ETMR_TRACESSCTRL (0x18) - -/* ETM trigger event register */ -#define ETMR_TRIGEVT (0x08) - -/* address access type register bits, "ETM architecture", - * table 3-27 */ -/* - access type */ -#define ETMAAT_IFETCH 0 -#define ETMAAT_IEXEC 1 -#define ETMAAT_IEXECPASS 2 -#define ETMAAT_IEXECFAIL 3 -#define ETMAAT_DLOADSTORE 4 -#define ETMAAT_DLOAD 5 -#define ETMAAT_DSTORE 6 -/* - comparison access size */ -#define ETMAAT_JAVA (0 << 3) -#define ETMAAT_THUMB (1 << 3) -#define ETMAAT_ARM (3 << 3) -/* - data value comparison control */ -#define ETMAAT_NOVALCMP (0 << 5) -#define ETMAAT_VALMATCH (1 << 5) -#define ETMAAT_VALNOMATCH (3 << 5) -/* - exact match */ -#define ETMAAT_EXACTMATCH (1 << 7) -/* - context id comparator control */ -#define ETMAAT_IGNCONTEXTID (0 << 8) -#define ETMAAT_VALUE1 (1 << 8) -#define ETMAAT_VALUE2 (2 << 8) -#define ETMAAT_VALUE3 (3 << 8) -/* - security level control */ -#define ETMAAT_IGNSECURITY (0 << 10) -#define ETMAAT_NSONLY (1 << 10) -#define ETMAAT_SONLY (2 << 10) - -#define ETMR_COMP_VAL(x) (0x40 + (x) * 4) -#define ETMR_COMP_ACC_TYPE(x) (0x80 + (x) * 4) - -/* ETM status register, "ETM Architecture", 3.3.2 */ -#define ETMR_STATUS (0x10) -#define ETMST_OVERFLOW BIT(0) -#define ETMST_PROGBIT BIT(1) -#define ETMST_STARTSTOP BIT(2) -#define ETMST_TRIGGER BIT(3) - -#define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT) -#define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP) -#define etm_triggered(t) (etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER) - -#define ETMR_TRACEENCTRL2 0x1c -#define ETMR_TRACEENCTRL 0x24 -#define ETMTE_INCLEXCL BIT(24) -#define ETMR_TRACEENEVT 0x20 -#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \ - ETMCTRL_DATA_DO_ADDR | \ - ETMCTRL_BRANCH_OUTPUT | \ - ETMCTRL_DO_CONTEXTID) - -/* ETM management registers, "ETM Architecture", 3.5.24 */ -#define ETMMR_OSLAR 0x300 -#define ETMMR_OSLSR 0x304 -#define ETMMR_OSSRR 0x308 -#define ETMMR_PDSR 0x314 - -/* ETB registers, "CoreSight Components TRM", 9.3 */ -#define ETBR_DEPTH 0x04 -#define ETBR_STATUS 0x0c -#define ETBR_READMEM 0x10 -#define ETBR_READADDR 0x14 -#define ETBR_WRITEADDR 0x18 -#define ETBR_TRIGGERCOUNT 0x1c -#define ETBR_CTRL 0x20 -#define ETBR_FORMATTERCTRL 0x304 -#define ETBFF_ENFTC 1 -#define ETBFF_ENFCONT BIT(1) -#define ETBFF_FONFLIN BIT(4) -#define ETBFF_MANUAL_FLUSH BIT(6) -#define ETBFF_TRIGIN BIT(8) -#define ETBFF_TRIGEVT BIT(9) -#define ETBFF_TRIGFL BIT(10) - -#define etb_writel(t, v, x) \ - (writel_relaxed((v), (t)->etb_regs + (x))) -#define etb_readl(t, x) (readl_relaxed((t)->etb_regs + (x))) - -#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) -#define etm_unlock(t) \ - do { etm_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0) - -#define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) -#define etb_unlock(t) \ - do { etb_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0) - -#endif /* __ASM_HARDWARE_CORESIGHT_H */ - diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 38ddd9f83d0e..9e80b984219a 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -30,7 +30,6 @@ else obj-y += entry-armv.o endif -obj-$(CONFIG_OC_ETM) += etm.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_FIQ) += fiq.o fiqasm.o diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c deleted file mode 100644 index 131a6ab5f355..000000000000 --- a/arch/arm/kernel/etm.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * linux/arch/arm/kernel/etm.c - * - * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer. - * - * Copyright (C) 2009 Nokia Corporation. - * Alexander Shishkin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Alexander Shishkin"); - -/* - * ETM tracer state - */ -struct tracectx { - unsigned int etb_bufsz; - void __iomem *etb_regs; - void __iomem *etm_regs; - unsigned long flags; - int ncmppairs; - int etm_portsz; - struct device *dev; - struct clk *emu_clk; - struct mutex mutex; -}; - -static struct tracectx tracer; - -static inline bool trace_isrunning(struct tracectx *t) -{ - return !!(t->flags & TRACER_RUNNING); -} - -static int etm_setup_address_range(struct tracectx *t, int n, - unsigned long start, unsigned long end, int exclude, int data) -{ - u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \ - ETMAAT_NOVALCMP; - - if (n < 1 || n > t->ncmppairs) - return -EINVAL; - - /* comparators and ranges are numbered starting with 1 as opposed - * to bits in a word */ - n--; - - if (data) - flags |= ETMAAT_DLOADSTORE; - else - flags |= ETMAAT_IEXEC; - - /* first comparator for the range */ - etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2)); - etm_writel(t, start, ETMR_COMP_VAL(n * 2)); - - /* second comparator is right next to it */ - etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1)); - etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1)); - - flags = exclude ? ETMTE_INCLEXCL : 0; - etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL); - - return 0; -} - -static int trace_start(struct tracectx *t) -{ - u32 v; - unsigned long timeout = TRACER_TIMEOUT; - - etb_unlock(t); - - etb_writel(t, 0, ETBR_FORMATTERCTRL); - etb_writel(t, 1, ETBR_CTRL); - - etb_lock(t); - - /* configure etm */ - v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz); - - if (t->flags & TRACER_CYCLE_ACC) - v |= ETMCTRL_CYCLEACCURATE; - - etm_unlock(t); - - etm_writel(t, v, ETMR_CTRL); - - while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) - ; - if (!timeout) { - dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); - etm_lock(t); - return -EFAULT; - } - - etm_setup_address_range(t, 1, (unsigned long)_stext, - (unsigned long)_etext, 0, 0); - etm_writel(t, 0, ETMR_TRACEENCTRL2); - etm_writel(t, 0, ETMR_TRACESSCTRL); - etm_writel(t, 0x6f, ETMR_TRACEENEVT); - - v &= ~ETMCTRL_PROGRAM; - v |= ETMCTRL_PORTSEL; - - etm_writel(t, v, ETMR_CTRL); - - timeout = TRACER_TIMEOUT; - while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout) - ; - if (!timeout) { - dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n"); - etm_lock(t); - return -EFAULT; - } - - etm_lock(t); - - t->flags |= TRACER_RUNNING; - - return 0; -} - -static int trace_stop(struct tracectx *t) -{ - unsigned long timeout = TRACER_TIMEOUT; - - etm_unlock(t); - - etm_writel(t, 0x440, ETMR_CTRL); - while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) - ; - if (!timeout) { - dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); - etm_lock(t); - return -EFAULT; - } - - etm_lock(t); - - etb_unlock(t); - etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL); - - timeout = TRACER_TIMEOUT; - while (etb_readl(t, ETBR_FORMATTERCTRL) & - ETBFF_MANUAL_FLUSH && --timeout) - ; - if (!timeout) { - dev_dbg(t->dev, "Waiting for formatter flush to commence " - "timed out\n"); - etb_lock(t); - return -EFAULT; - } - - etb_writel(t, 0, ETBR_CTRL); - - etb_lock(t); - - t->flags &= ~TRACER_RUNNING; - - return 0; -} - -static int etb_getdatalen(struct tracectx *t) -{ - u32 v; - int rp, wp; - - v = etb_readl(t, ETBR_STATUS); - - if (v & 1) - return t->etb_bufsz; - - rp = etb_readl(t, ETBR_READADDR); - wp = etb_readl(t, ETBR_WRITEADDR); - - if (rp > wp) { - etb_writel(t, 0, ETBR_READADDR); - etb_writel(t, 0, ETBR_WRITEADDR); - - return 0; - } - - return wp - rp; -} - -/* sysrq+v will always stop the running trace and leave it at that */ -static void etm_dump(void) -{ - struct tracectx *t = &tracer; - u32 first = 0; - int length; - - if (!t->etb_regs) { - printk(KERN_INFO "No tracing hardware found\n"); - return; - } - - if (trace_isrunning(t)) - trace_stop(t); - - etb_unlock(t); - - length = etb_getdatalen(t); - - if (length == t->etb_bufsz) - first = etb_readl(t, ETBR_WRITEADDR); - - etb_writel(t, first, ETBR_READADDR); - - printk(KERN_INFO "Trace buffer contents length: %d\n", length); - printk(KERN_INFO "--- ETB buffer begin ---\n"); - for (; length; length--) - printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); - printk(KERN_INFO "\n--- ETB buffer end ---\n"); - - /* deassert the overflow bit */ - etb_writel(t, 1, ETBR_CTRL); - etb_writel(t, 0, ETBR_CTRL); - - etb_writel(t, 0, ETBR_TRIGGERCOUNT); - etb_writel(t, 0, ETBR_READADDR); - etb_writel(t, 0, ETBR_WRITEADDR); - - etb_lock(t); -} - -static void sysrq_etm_dump(int key) -{ - dev_dbg(tracer.dev, "Dumping ETB buffer\n"); - etm_dump(); -} - -static struct sysrq_key_op sysrq_etm_op = { - .handler = sysrq_etm_dump, - .help_msg = "etm-buffer-dump(v)", - .action_msg = "etm", -}; - -static int etb_open(struct inode *inode, struct file *file) -{ - if (!tracer.etb_regs) - return -ENODEV; - - file->private_data = &tracer; - - return nonseekable_open(inode, file); -} - -static ssize_t etb_read(struct file *file, char __user *data, - size_t len, loff_t *ppos) -{ - int total, i; - long length; - struct tracectx *t = file->private_data; - u32 first = 0; - u32 *buf; - - mutex_lock(&t->mutex); - - if (trace_isrunning(t)) { - length = 0; - goto out; - } - - etb_unlock(t); - - total = etb_getdatalen(t); - if (total == t->etb_bufsz) - first = etb_readl(t, ETBR_WRITEADDR); - - etb_writel(t, first, ETBR_READADDR); - - length = min(total * 4, (int)len); - buf = vmalloc(length); - - dev_dbg(t->dev, "ETB buffer length: %d\n", total); - dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS)); - for (i = 0; i < length / 4; i++) - buf[i] = etb_readl(t, ETBR_READMEM); - - /* the only way to deassert overflow bit in ETB status is this */ - etb_writel(t, 1, ETBR_CTRL); - etb_writel(t, 0, ETBR_CTRL); - - etb_writel(t, 0, ETBR_WRITEADDR); - etb_writel(t, 0, ETBR_READADDR); - etb_writel(t, 0, ETBR_TRIGGERCOUNT); - - etb_lock(t); - - length -= copy_to_user(data, buf, length); - vfree(buf); - -out: - mutex_unlock(&t->mutex); - - return length; -} - -static int etb_release(struct inode *inode, struct file *file) -{ - /* there's nothing to do here, actually */ - return 0; -} - -static const struct file_operations etb_fops = { - .owner = THIS_MODULE, - .read = etb_read, - .open = etb_open, - .release = etb_release, - .llseek = no_llseek, -}; - -static struct miscdevice etb_miscdev = { - .name = "tracebuf", - .minor = 0, - .fops = &etb_fops, -}; - -static int etb_probe(struct amba_device *dev, const struct amba_id *id) -{ - struct tracectx *t = &tracer; - int ret = 0; - - ret = amba_request_regions(dev, NULL); - if (ret) - goto out; - - t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); - if (!t->etb_regs) { - ret = -ENOMEM; - goto out_release; - } - - amba_set_drvdata(dev, t); - - etb_miscdev.parent = &dev->dev; - - ret = misc_register(&etb_miscdev); - if (ret) - goto out_unmap; - - t->emu_clk = clk_get(&dev->dev, "emu_src_ck"); - if (IS_ERR(t->emu_clk)) { - dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n"); - return -EFAULT; - } - - clk_enable(t->emu_clk); - - etb_unlock(t); - t->etb_bufsz = etb_readl(t, ETBR_DEPTH); - dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz); - - /* make sure trace capture is disabled */ - etb_writel(t, 0, ETBR_CTRL); - etb_writel(t, 0x1000, ETBR_FORMATTERCTRL); - etb_lock(t); - - dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n"); - -out: - return ret; - -out_unmap: - iounmap(t->etb_regs); - -out_release: - amba_release_regions(dev); - - return ret; -} - -static int etb_remove(struct amba_device *dev) -{ - struct tracectx *t = amba_get_drvdata(dev); - - iounmap(t->etb_regs); - t->etb_regs = NULL; - - clk_disable(t->emu_clk); - clk_put(t->emu_clk); - - amba_release_regions(dev); - - return 0; -} - -static struct amba_id etb_ids[] = { - { - .id = 0x0003b907, - .mask = 0x0007ffff, - }, - { 0, 0 }, -}; - -static struct amba_driver etb_driver = { - .drv = { - .name = "etb", - .owner = THIS_MODULE, - }, - .probe = etb_probe, - .remove = etb_remove, - .id_table = etb_ids, -}; - -/* use a sysfs file "trace_running" to start/stop tracing */ -static ssize_t trace_running_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%x\n", trace_isrunning(&tracer)); -} - -static ssize_t trace_running_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t n) -{ - unsigned int value; - int ret; - - if (sscanf(buf, "%u", &value) != 1) - return -EINVAL; - - mutex_lock(&tracer.mutex); - ret = value ? trace_start(&tracer) : trace_stop(&tracer); - mutex_unlock(&tracer.mutex); - - return ret ? : n; -} - -static struct kobj_attribute trace_running_attr = - __ATTR(trace_running, 0644, trace_running_show, trace_running_store); - -static ssize_t trace_info_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st; - int datalen; - - etb_unlock(&tracer); - datalen = etb_getdatalen(&tracer); - etb_wa = etb_readl(&tracer, ETBR_WRITEADDR); - etb_ra = etb_readl(&tracer, ETBR_READADDR); - etb_st = etb_readl(&tracer, ETBR_STATUS); - etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL); - etb_lock(&tracer); - - etm_unlock(&tracer); - etm_ctrl = etm_readl(&tracer, ETMR_CTRL); - etm_st = etm_readl(&tracer, ETMR_STATUS); - etm_lock(&tracer); - - return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n" - "ETBR_WRITEADDR:\t%08x\n" - "ETBR_READADDR:\t%08x\n" - "ETBR_STATUS:\t%08x\n" - "ETBR_FORMATTERCTRL:\t%08x\n" - "ETMR_CTRL:\t%08x\n" - "ETMR_STATUS:\t%08x\n", - datalen, - tracer.ncmppairs, - etb_wa, - etb_ra, - etb_st, - etb_fc, - etm_ctrl, - etm_st - ); -} - -static struct kobj_attribute trace_info_attr = - __ATTR(trace_info, 0444, trace_info_show, NULL); - -static ssize_t trace_mode_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d %d\n", - !!(tracer.flags & TRACER_CYCLE_ACC), - tracer.etm_portsz); -} - -static ssize_t trace_mode_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t n) -{ - unsigned int cycacc, portsz; - - if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2) - return -EINVAL; - - mutex_lock(&tracer.mutex); - if (cycacc) - tracer.flags |= TRACER_CYCLE_ACC; - else - tracer.flags &= ~TRACER_CYCLE_ACC; - - tracer.etm_portsz = portsz & 0x0f; - mutex_unlock(&tracer.mutex); - - return n; -} - -static struct kobj_attribute trace_mode_attr = - __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); - -static int etm_probe(struct amba_device *dev, const struct amba_id *id) -{ - struct tracectx *t = &tracer; - int ret = 0; - - if (t->etm_regs) { - dev_dbg(&dev->dev, "ETM already initialized\n"); - ret = -EBUSY; - goto out; - } - - ret = amba_request_regions(dev, NULL); - if (ret) - goto out; - - t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); - if (!t->etm_regs) { - ret = -ENOMEM; - goto out_release; - } - - amba_set_drvdata(dev, t); - - mutex_init(&t->mutex); - t->dev = &dev->dev; - t->flags = TRACER_CYCLE_ACC; - t->etm_portsz = 1; - - etm_unlock(t); - (void)etm_readl(t, ETMMR_PDSR); - /* dummy first read */ - (void)etm_readl(&tracer, ETMMR_OSSRR); - - t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf; - etm_writel(t, 0x440, ETMR_CTRL); - etm_lock(t); - - ret = sysfs_create_file(&dev->dev.kobj, - &trace_running_attr.attr); - if (ret) - goto out_unmap; - - /* failing to create any of these two is not fatal */ - ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr); - if (ret) - dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n"); - - ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr); - if (ret) - dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n"); - - dev_dbg(t->dev, "ETM AMBA driver initialized.\n"); - -out: - return ret; - -out_unmap: - iounmap(t->etm_regs); - -out_release: - amba_release_regions(dev); - - return ret; -} - -static int etm_remove(struct amba_device *dev) -{ - struct tracectx *t = amba_get_drvdata(dev); - - iounmap(t->etm_regs); - t->etm_regs = NULL; - - amba_release_regions(dev); - - sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr); - sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr); - - return 0; -} - -static struct amba_id etm_ids[] = { - { - .id = 0x0003b921, - .mask = 0x0007ffff, - }, - { 0, 0 }, -}; - -static struct amba_driver etm_driver = { - .drv = { - .name = "etm", - .owner = THIS_MODULE, - }, - .probe = etm_probe, - .remove = etm_remove, - .id_table = etm_ids, -}; - -static int __init etm_init(void) -{ - int retval; - - retval = amba_driver_register(&etb_driver); - if (retval) { - printk(KERN_ERR "Failed to register etb\n"); - return retval; - } - - retval = amba_driver_register(&etm_driver); - if (retval) { - amba_driver_unregister(&etb_driver); - printk(KERN_ERR "Failed to probe etm\n"); - return retval; - } - - /* not being able to install this handler is not fatal */ - (void)register_sysrq_key('v', &sysrq_etm_op); - - return 0; -} - -device_initcall(etm_init); - diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index b5b452f90f76..7fc70ae21185 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,6 @@ #include #include #include -#include /* Breakpoint currently in use for each BRP. */ static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); @@ -976,7 +976,7 @@ static void reset_ctrl_regs(void *unused) * Unconditionally clear the OS lock by writing a value * other than CS_LAR_KEY to the access register. */ - ARM_DBG_WRITE(c1, c0, 4, ~CS_LAR_KEY); + ARM_DBG_WRITE(c1, c0, 4, ~CORESIGHT_UNLOCK); isb(); /* diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index f4d06aea8460..06020fe77e57 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -292,14 +292,6 @@ config MACH_TI8148EVM depends on SOC_TI81XX default y -config OMAP3_EMU - bool "OMAP3 debugging peripherals" - depends on ARCH_OMAP3 - select ARM_AMBA - select OC_ETM - help - Say Y here to enable debugging hardware of omap3 - config OMAP3_SDRC_AC_TIMING bool "Enable SDRC AC timing register changes" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d9e94122073e..87255a3d8849 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -228,7 +228,6 @@ obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o # EMU peripherals -obj-$(CONFIG_OMAP3_EMU) += emu.o obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c deleted file mode 100644 index cbeaca2d7695..000000000000 --- a/arch/arm/mach-omap2/emu.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * emu.c - * - * ETM and ETB CoreSight components' resources as found in OMAP3xxx. - * - * Copyright (C) 2009 Nokia Corporation. - * Alexander Shishkin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "soc.h" -#include "iomap.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Alexander Shishkin"); - -/* Cortex CoreSight components within omap3xxx EMU */ -#define ETM_BASE (L4_EMU_34XX_PHYS + 0x10000) -#define DBG_BASE (L4_EMU_34XX_PHYS + 0x11000) -#define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) -#define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) - -static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL); -static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL); - -static int __init emu_init(void) -{ - if (!cpu_is_omap34xx()) - return -ENODEV; - - amba_device_register(&omap3_etb_device, &iomem_resource); - amba_device_register(&omap3_etm_device, &iomem_resource); - - return 0; -} - -omap_subsys_initcall(emu_init); -- GitLab From 7439b37e7579543226cb30eeefdf989bed391997 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:06 +0200 Subject: [PATCH 3975/9457] powerpc/8xx: exception InstructionAccess does not exist on MPC8xx Exception InstructionAccess does not exist on MPC8xx. No need to branch there from somewhere else. Handling can be done directly in InstructionTLBError Exception. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index fafff8dbd5d9..d30f703790f4 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -234,15 +234,10 @@ DataAccess: EXC_XFER_LITE(0x300, handle_page_fault) /* Instruction access exception. - * This is "never generated" by the MPC8xx. We jump to it for other - * translation errors. + * This is "never generated" by the MPC8xx. */ . = 0x400 InstructionAccess: - EXCEPTION_PROLOG - mr r4,r12 - mr r5,r9 - EXC_XFER_LITE(0x400, handle_page_fault) /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -382,7 +377,7 @@ InstructionTLBMiss: #endif mfspr r10, SPRN_SPRG_SCRATCH2 EXCEPTION_EPILOG_0 - b InstructionAccess + b InstructionTLBError . = 0x1200 DataStoreTLBMiss: @@ -477,7 +472,11 @@ DataStoreTLBMiss: */ . = 0x1300 InstructionTLBError: - b InstructionAccess + EXCEPTION_PROLOG + mr r4,r12 + mr r5,r9 + /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */ + EXC_XFER_LITE(0x400, handle_page_fault) /* This is the data TLB error on the MPC8xx. This could be due to * many reasons, including a dirty update to a pte. We bail out to -- GitLab From 749137a2516aea627cbdd49140e60bb60d80f18e Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:07 +0200 Subject: [PATCH 3976/9457] powerpc/8xx: DataAccess exception not generated by MPC8xx DataAccess exception is never generated by MPC8xx so do the job directly where it is used to avoid an unnecessary branching. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index d30f703790f4..464be24fd3eb 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -219,19 +219,10 @@ MachineCheck: EXC_XFER_STD(0x200, machine_check_exception) /* Data access exception. - * This is "never generated" by the MPC8xx. We jump to it for other - * translation errors. + * This is "never generated" by the MPC8xx. */ . = 0x300 DataAccess: - EXCEPTION_PROLOG - mfspr r10,SPRN_DSISR - stw r10,_DSISR(r11) - mr r5,r10 - mfspr r4,SPRN_DAR - li r10,0x00f0 - mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ - EXC_XFER_LITE(0x300, handle_page_fault) /* Instruction access exception. * This is "never generated" by the MPC8xx. @@ -491,7 +482,15 @@ DataTLBError: beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ DARFixed:/* Return from dcbx instruction bug workaround */ EXCEPTION_EPILOG_0 - b DataAccess + EXCEPTION_PROLOG + mfspr r10,SPRN_DSISR + stw r10,_DSISR(r11) + mr r5,r10 + mfspr r4,SPRN_DAR + li r10,0x00f0 + mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ + /* 0x300 is DataAccess exception, needed by bad_page_fault() */ + EXC_XFER_LITE(0x300, handle_page_fault) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) -- GitLab From 6cde2b6f399e7d68a4b482680850a077104f9068 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:08 +0200 Subject: [PATCH 3977/9457] powerpc/8xx: No need to restore registers and save them again. In DTLBError handler there is not need to restore r10, r11 and cr registers after fixing DAR as they are saved again to the same place just after. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 464be24fd3eb..c061bc8d9045 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -481,8 +481,8 @@ DataTLBError: cmpwi cr0, r11, 0x00f0 beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ DARFixed:/* Return from dcbx instruction bug workaround */ - EXCEPTION_EPILOG_0 - EXCEPTION_PROLOG + EXCEPTION_PROLOG_1 + EXCEPTION_PROLOG_2 mfspr r10,SPRN_DSISR stw r10,_DSISR(r11) mr r5,r10 -- GitLab From cbc130f120d5e180a70a0fa4a8b4191e44548a87 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:08 +0200 Subject: [PATCH 3978/9457] powerpc/8xx: Use M_TW instead of M_TWB Use M_TW instead of M_TWB for storing Level 1 table address as M_TWB requires 4k aligned tables, which is only the case with 4k pages. Consequently, we have to calculate the level 1 table index by ourselves. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 48 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index c061bc8d9045..c78f7fd342cb 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -278,8 +278,8 @@ SystemCall: . = 0x1100 /* * For the MPC8xx, this is a software tablewalk to load the instruction - * TLB. It is modelled after the example in the Motorola manual. The task - * switch loads the M_TWB register with the pointer to the first level table. + * TLB. The task switch loads the M_TW register with the pointer to the first + * level table. * If we discover there is no second level table (value is zero) or if there * is an invalid pte, we load that into the TLB, which causes another fault * into the TLB Error interrupt where we can handle such problems. @@ -301,7 +301,6 @@ InstructionTLBMiss: #endif DO_8xx_CPU6(0x3780, r3) mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */ - mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ /* If we are faulting a kernel address, we have to use the * kernel page tables. @@ -309,14 +308,17 @@ InstructionTLBMiss: #ifdef CONFIG_MODULES /* Only modules will cause ITLB Misses as we always * pin the first 8MB of kernel memory */ - andi. r11, r10, 0x0800 /* Address >= 0x80000000 */ + andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ +#endif + mfspr r11, SPRN_M_TW /* Get level 1 table base address */ +#ifdef CONFIG_MODULES beq 3f - lis r11, swapper_pg_dir@h - ori r11, r11, swapper_pg_dir@l - rlwimi r10, r11, 0, 2, 19 + lis r11, (swapper_pg_dir-PAGE_OFFSET)@h + ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 3: #endif - lwz r11, 0(r10) /* Get the level 1 entry */ + rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + lwzx r11, r10, r11 /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ @@ -377,18 +379,19 @@ DataStoreTLBMiss: #endif EXCEPTION_PROLOG_0 mtspr SPRN_SPRG_SCRATCH2, r10 - mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ + mfspr r10, SPRN_MD_EPN /* If we are faulting a kernel address, we have to use the * kernel page tables. */ - andi. r11, r10, 0x0800 + andis. r11, r10, 0x8000 + mfspr r11, SPRN_M_TW /* Get level 1 table base address */ beq 3f - lis r11, swapper_pg_dir@h - ori r11, r11, swapper_pg_dir@l - rlwimi r10, r11, 0, 2, 19 + lis r11, (swapper_pg_dir-PAGE_OFFSET)@h + ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 3: - lwz r11, 0(r10) /* Get the level 1 entry */ + rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + lwzx r11, r10, r11 /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ @@ -527,12 +530,12 @@ FixupDAR:/* Entry point for dcbx workaround. */ andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ DO_8xx_CPU6(0x3780, r3) mtspr SPRN_MD_EPN, r10 - mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */ + mfspr r11, SPRN_M_TW /* Get level 1 table base address */ beq- 3f /* Branch if user space */ lis r11, (swapper_pg_dir-PAGE_OFFSET)@h ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l - rlwimi r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */ -3: lwz r11, 0(r11) /* Get the level 1 entry */ +3: rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + lwzx r11, r10, r11 /* Get the level 1 entry */ DO_8xx_CPU6(0x3b80, r3) mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ @@ -541,6 +544,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ lwz r3, 8(r0) /* restore r3 from memory */ #endif /* concat physical page address(r11) and page offset(r10) */ + mfspr r10, SPRN_SRR0 rlwimi r11, r10, 0, 20, 31 lwz r11,0(r11) /* Check if it really is a dcbx instruction. */ @@ -696,11 +700,11 @@ start_here: #ifdef CONFIG_8xx_CPU6 lis r4, cpu6_errata_word@h ori r4, r4, cpu6_errata_word@l - li r3, 0x3980 + li r3, 0x3f80 stw r3, 12(r4) lwz r3, 12(r4) #endif - mtspr SPRN_M_TWB, r6 + mtspr SPRN_M_TW, r6 lis r4,2f@h ori r4,r4,2f@l tophys(r4,r4) @@ -874,10 +878,10 @@ _GLOBAL(set_context) lis r6, cpu6_errata_word@h ori r6, r6, cpu6_errata_word@l tophys (r4, r4) - li r7, 0x3980 + li r7, 0x3f80 stw r7, 12(r6) lwz r7, 12(r6) - mtspr SPRN_M_TWB, r4 /* Update MMU base address */ + mtspr SPRN_M_TW, r4 /* Update MMU base address */ li r7, 0x3380 stw r7, 12(r6) lwz r7, 12(r6) @@ -885,7 +889,7 @@ _GLOBAL(set_context) #else mtspr SPRN_M_CASID,r3 /* Update context */ tophys (r4, r4) - mtspr SPRN_M_TWB, r4 /* and pgd */ + mtspr SPRN_M_TW, r4 /* and pgd */ #endif SYNC blr -- GitLab From 33fb845a6f019001b8ca3f532eb1a4de34547f42 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:08 +0200 Subject: [PATCH 3979/9457] powerpc/8xx: Don't use MD_TWC for walk MD_TWC can only be used properly with 4k pages. So lets calculate level 2 table index by ourselves. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index c78f7fd342cb..3eea29ad1fcf 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -299,8 +299,6 @@ InstructionTLBMiss: addi r11, r10, -0x1000 tlbie r11 #endif - DO_8xx_CPU6(0x3780, r3) - mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */ /* If we are faulting a kernel address, we have to use the * kernel page tables. @@ -328,10 +326,9 @@ InstructionTLBMiss: ori r11,r11,1 /* Set valid bit */ DO_8xx_CPU6(0x2b80, r3) mtspr SPRN_MI_TWC, r11 /* Set segment attributes */ - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ - mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ - lwz r10, 0(r11) /* Get the pte */ + mfspr r11, SPRN_SRR0 /* Get effective address of fault */ + rlwinm r11, r11, 22, 20, 29 /* Extract level 2 index */ + lwzx r10, r10, r11 /* Get the pte */ #ifdef CONFIG_SWAP andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT @@ -397,12 +394,13 @@ DataStoreTLBMiss: /* We have a pte table, so load fetch the pte from the table. */ - ori r11, r11, 1 /* Set valid bit in physical L2 page */ - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ - mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ + mfspr r10, SPRN_MD_EPN /* Get address of fault */ + /* Extract level 2 index */ + rlwinm r10, r10, 22, 20, 29 + rlwimi r10, r11, 0, 0, 19 /* Add level 2 base */ lwz r10, 0(r10) /* Get the pte */ + ori r11, r11, 1 /* Set valid bit in physical L2 page */ /* Insert the Guarded flag into the TWC from the Linux PTE. * It is bit 27 of both the Linux PTE and the TWC (at least * I got that right :-). It will be better when we can put @@ -528,18 +526,16 @@ FixupDAR:/* Entry point for dcbx workaround. */ /* fetch instruction from memory. */ mfspr r10, SPRN_SRR0 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ - DO_8xx_CPU6(0x3780, r3) - mtspr SPRN_MD_EPN, r10 mfspr r11, SPRN_M_TW /* Get level 1 table base address */ beq- 3f /* Branch if user space */ lis r11, (swapper_pg_dir-PAGE_OFFSET)@h ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 3: rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ lwzx r11, r10, r11 /* Get the level 1 entry */ - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ - mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ - lwz r11, 0(r11) /* Get the pte */ + rlwinm r10, r11,0,0,19 /* Extract page descriptor page address */ + mfspr r11, SPRN_SRR0 /* Get effective address of fault */ + rlwinm r11, r11, 22, 20, 29 /* Extract level 2 index */ + lwzx r11, r10, r11 /* Get the pte */ #ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) /* restore r3 from memory */ #endif -- GitLab From d14068035c3f6fd0d6514e061e4324a277be83e2 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3980/9457] powerpc/8xx: Use PAGE size related consts For PAGE size related operations, use PAGE size consts in order to be able to use different page size in the futur. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 3eea29ad1fcf..e126adf15528 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -294,9 +294,9 @@ InstructionTLBMiss: mtspr SPRN_SPRG_SCRATCH2, r10 mfspr r10, SPRN_SRR0 /* Get effective address of fault */ #ifdef CONFIG_8xx_CPU15 - addi r11, r10, 0x1000 + addi r11, r10, PAGE_SIZE tlbie r11 - addi r11, r10, -0x1000 + addi r11, r10, -PAGE_SIZE tlbie r11 #endif @@ -315,7 +315,8 @@ InstructionTLBMiss: ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 3: #endif - rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + /* Extract level 1 index */ + rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 lwzx r11, r10, r11 /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ @@ -327,7 +328,8 @@ InstructionTLBMiss: DO_8xx_CPU6(0x2b80, r3) mtspr SPRN_MI_TWC, r11 /* Set segment attributes */ mfspr r11, SPRN_SRR0 /* Get effective address of fault */ - rlwinm r11, r11, 22, 20, 29 /* Extract level 2 index */ + /* Extract level 2 index */ + rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 lwzx r10, r10, r11 /* Get the pte */ #ifdef CONFIG_SWAP @@ -387,7 +389,8 @@ DataStoreTLBMiss: lis r11, (swapper_pg_dir-PAGE_OFFSET)@h ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 3: - rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + /* Extract level 1 index */ + rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 lwzx r11, r10, r11 /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ @@ -396,8 +399,8 @@ DataStoreTLBMiss: */ mfspr r10, SPRN_MD_EPN /* Get address of fault */ /* Extract level 2 index */ - rlwinm r10, r10, 22, 20, 29 - rlwimi r10, r11, 0, 0, 19 /* Add level 2 base */ + rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 + rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */ lwz r10, 0(r10) /* Get the pte */ ori r11, r11, 1 /* Set valid bit in physical L2 page */ @@ -530,18 +533,20 @@ FixupDAR:/* Entry point for dcbx workaround. */ beq- 3f /* Branch if user space */ lis r11, (swapper_pg_dir-PAGE_OFFSET)@h ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l -3: rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ + /* Extract level 1 index */ +3: rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 lwzx r11, r10, r11 /* Get the level 1 entry */ rlwinm r10, r11,0,0,19 /* Extract page descriptor page address */ mfspr r11, SPRN_SRR0 /* Get effective address of fault */ - rlwinm r11, r11, 22, 20, 29 /* Extract level 2 index */ + /* Extract level 2 index */ + rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 lwzx r11, r10, r11 /* Get the pte */ #ifdef CONFIG_8xx_CPU6 lwz r3, 8(r0) /* restore r3 from memory */ #endif /* concat physical page address(r11) and page offset(r10) */ mfspr r10, SPRN_SRR0 - rlwimi r11, r10, 0, 20, 31 + rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31 lwz r11,0(r11) /* Check if it really is a dcbx instruction. */ /* dcbt and dcbtst does not generate DTLB Misses/Errors, @@ -917,12 +922,13 @@ set_dec_cpu6: .globl sdata sdata: .globl empty_zero_page + .align PAGE_SHIFT empty_zero_page: - .space 4096 + .space PAGE_SIZE .globl swapper_pg_dir swapper_pg_dir: - .space 4096 + .space PGD_TABLE_SIZE /* Room for two PTE table poiners, usually the kernel and current user * pointer to their respective root page table (pgdir). -- GitLab From ac21951fa8a356e2aab6e93a61aa99b561100e67 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3981/9457] powerpc/8xx: Const for TLB RPN forced value Value 0x00f0 is used to force bits in TLB level 2 entry. This value is linked to the page size and will vary when we change the page size. Lets define a const for it in order to have it at only one place. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index e126adf15528..38efa8622176 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -40,6 +40,13 @@ #else #define DO_8xx_CPU6(val, reg) #endif + +/* + * Value for the bits that have fixed value in RPN entries. + * Also used for tagging DAR for DTLBerror. + */ +#define RPN_PATTERN 0x00f0 + __HEAD _ENTRY(_stext); _ENTRY(_start); @@ -211,7 +218,7 @@ MachineCheck: EXCEPTION_PROLOG mfspr r4,SPRN_DAR stw r4,_DAR(r11) - li r5,0x00f0 + li r5,RPN_PATTERN mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) @@ -239,7 +246,7 @@ Alignment: EXCEPTION_PROLOG mfspr r4,SPRN_DAR stw r4,_DAR(r11) - li r5,0x00f0 + li r5,RPN_PATTERN mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) @@ -343,7 +350,7 @@ InstructionTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r11, 0x00f0 + li r11, RPN_PATTERN rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */ DO_8xx_CPU6(0x2d80, r3) mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ @@ -447,7 +454,7 @@ DataStoreTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ -2: li r11, 0x00f0 +2: li r11, RPN_PATTERN rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ DO_8xx_CPU6(0x3d80, r3) mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ @@ -482,7 +489,7 @@ DataTLBError: EXCEPTION_PROLOG_0 mfspr r11, SPRN_DAR - cmpwi cr0, r11, 0x00f0 + cmpwi cr0, r11, RPN_PATTERN beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ DARFixed:/* Return from dcbx instruction bug workaround */ EXCEPTION_PROLOG_1 @@ -491,7 +498,7 @@ DARFixed:/* Return from dcbx instruction bug workaround */ stw r10,_DSISR(r11) mr r5,r10 mfspr r4,SPRN_DAR - li r10,0x00f0 + li r10,RPN_PATTERN mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ /* 0x300 is DataAccess exception, needed by bad_page_fault() */ EXC_XFER_LITE(0x300, handle_page_fault) -- GitLab From 959d6173b5cccceff47cc2d25feeaac2f96df0e0 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3982/9457] powerpc/8xx: Implement 16k pages This patch activates the handling of 16k pages on the MPC8xx. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/mmu-8xx.h | 2 ++ arch/powerpc/kernel/head_8xx.S | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 88eace4e28c3..abb8709d8b2a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -549,7 +549,7 @@ config PPC_4K_PAGES bool "4k page size" config PPC_16K_PAGES - bool "16k page size" if 44x + bool "16k page size" if 44x || PPC_8xx config PPC_64K_PAGES bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64 diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index 3d11d3ce79ec..986b9e1e1044 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h @@ -56,6 +56,7 @@ * additional information from the MI_EPN, and MI_TWC registers. */ #define SPRN_MI_RPN 790 +#define MI_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ /* Define an RPN value for mapping kernel memory to large virtual * pages for boot initialization. This has real page number of 0, @@ -129,6 +130,7 @@ * additional information from the MD_EPN, and MD_TWC registers. */ #define SPRN_MD_RPN 798 +#define MD_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */ /* This is a temporary storage register that could be used to save * a processor working register during a tablewalk. diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 38efa8622176..84b0b9778065 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -45,7 +45,11 @@ * Value for the bits that have fixed value in RPN entries. * Also used for tagging DAR for DTLBerror. */ +#ifdef CONFIG_PPC_16K_PAGES +#define RPN_PATTERN (0x00f0 | MD_SPS16K) +#else #define RPN_PATTERN 0x00f0 +#endif __HEAD _ENTRY(_stext); -- GitLab From d3e40262e7d05236bf4c2c4fdf007589ba8af97a Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3983/9457] powerpc/8xx: Better readibility of ERRATA CPU6 handling This patch hiddes that SPR address needed for CPU6 ERRATA handling in the macro. Then we don't have to worry about this address directly in the code. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 84b0b9778065..6e9124177f19 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -33,12 +33,19 @@ /* Macro to make the code more readable. */ #ifdef CONFIG_8xx_CPU6 -#define DO_8xx_CPU6(val, reg) \ - li reg, val; \ - stw reg, 12(r0); \ - lwz reg, 12(r0); +#define SPRN_MI_TWC_ADDR 0x2b80 +#define SPRN_MI_RPN_ADDR 0x2d80 +#define SPRN_MD_TWC_ADDR 0x3b80 +#define SPRN_MD_RPN_ADDR 0x3d80 + +#define MTSPR_CPU6(spr, reg, treg) \ + li treg, spr##_ADDR; \ + stw treg, 12(r0); \ + lwz treg, 12(r0); \ + mtspr spr, reg #else -#define DO_8xx_CPU6(val, reg) +#define MTSPR_CPU6(spr, reg, treg) \ + mtspr spr, reg #endif /* @@ -336,8 +343,7 @@ InstructionTLBMiss: * for this "segment." */ ori r11,r11,1 /* Set valid bit */ - DO_8xx_CPU6(0x2b80, r3) - mtspr SPRN_MI_TWC, r11 /* Set segment attributes */ + MTSPR_CPU6(SPRN_MI_TWC, r11, r3) /* Set segment attributes */ mfspr r11, SPRN_SRR0 /* Get effective address of fault */ /* Extract level 2 index */ rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 @@ -356,8 +362,7 @@ InstructionTLBMiss: */ li r11, RPN_PATTERN rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */ - DO_8xx_CPU6(0x2d80, r3) - mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ + MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ #ifdef CONFIG_8xx_CPU6 @@ -426,8 +431,7 @@ DataStoreTLBMiss: * It is bit 25 in the Linux PTE and bit 30 in the TWC */ rlwimi r11, r10, 32-5, 30, 30 - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 + MTSPR_CPU6(SPRN_MD_TWC, r11, r3) /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set. * We also need to know if the insn is a load/store, so: @@ -460,8 +464,7 @@ DataStoreTLBMiss: */ 2: li r11, RPN_PATTERN rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ - DO_8xx_CPU6(0x3d80, r3) - mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ + MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ #ifdef CONFIG_8xx_CPU6 -- GitLab From 4094f28f90adab007eca9babf28f606a40a83032 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3984/9457] powerpc/8xx: set PTE bit 22 off TLBmiss No need to re-set this bit at each TLB miss. Let's set it in the PTE. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/include/asm/pgtable-ppc32.h | 20 ++++++++++++++++++++ arch/powerpc/include/asm/pte-8xx.h | 7 +++++-- arch/powerpc/kernel/head_8xx.S | 10 ++-------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index 945e47adf7db..234e07c47803 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -170,6 +170,25 @@ static inline unsigned long pte_update(pte_t *p, #ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; +#ifdef CONFIG_PPC_8xx + unsigned long tmp2; + + __asm__ __volatile__("\ +1: lwarx %0,0,%4\n\ + andc %1,%0,%5\n\ + or %1,%1,%6\n\ + /* 0x200 == Extended encoding, bit 22 */ \ + /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ \ + rlwimi %1,%1,32-2,0x200\n /* get _PAGE_USER */ \ + rlwinm %3,%1,32-1,0x200\n /* get _PAGE_RW */ \ + or %1,%3,%1\n\ + xori %1,%1,0x200\n" +" stwcx. %1,0,%4\n\ + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*p), "=&r" (tmp2) + : "r" (p), "r" (clr), "r" (set), "m" (*p) + : "cc" ); +#else /* CONFIG_PPC_8xx */ __asm__ __volatile__("\ 1: lwarx %0,0,%3\n\ andc %1,%0,%4\n\ @@ -180,6 +199,7 @@ static inline unsigned long pte_update(pte_t *p, : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p) : "cc" ); +#endif /* CONFIG_PPC_8xx */ #else /* PTE_ATOMIC_UPDATES */ unsigned long old = pte_val(*p); *p = __pte((old & ~clr) | set); diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h index d44826e4ff97..daa4616e61c4 100644 --- a/arch/powerpc/include/asm/pte-8xx.h +++ b/arch/powerpc/include/asm/pte-8xx.h @@ -48,19 +48,22 @@ */ #define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */ #define _PAGE_USER 0x0800 /* msb PP bits */ +/* set when neither _PAGE_USER nor _PAGE_RW are set */ +#define _PAGE_KNLRO 0x0200 #define _PMD_PRESENT 0x0001 #define _PMD_BAD 0x0ff0 #define _PMD_PAGE_MASK 0x000c #define _PMD_PAGE_8M 0x000c -#define _PTE_NONE_MASK _PAGE_ACCESSED +#define _PTE_NONE_MASK _PAGE_KNLRO /* Until my rework is finished, 8xx still needs atomic PTE updates */ #define PTE_ATOMIC_UPDATES 1 /* We need to add _PAGE_SHARED to kernel pages */ -#define _PAGE_KERNEL_RO (_PAGE_SHARED) +#define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_KNLRO) +#define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_KNLRO) #define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 6e9124177f19..8d6e6830a675 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -447,14 +447,8 @@ DataStoreTLBMiss: and r11, r11, r10 rlwimi r10, r11, 0, _PAGE_PRESENT #endif - /* Honour kernel RO, User NA */ - /* 0x200 == Extended encoding, bit 22 */ - rlwimi r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */ - /* r11 = (r10 & _PAGE_RW) >> 1 */ - rlwinm r11, r10, 32-1, 0x200 - or r10, r11, r10 - /* invert RW and 0x200 bits */ - xori r10, r10, _PAGE_RW | 0x200 + /* invert RW */ + xori r10, r10, _PAGE_RW /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 22 and 28 must be clear. -- GitLab From c9a803fb17bcec0e7527dc8fa055e56a9691abbb Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:09 +0200 Subject: [PATCH 3985/9457] powerpc/8xx: _PMD_PRESENT already set in level 1 entries When a PMD entry is valid, _PMD_PRESENT is set. Therefore, forcing that bit during TLB loading is useless. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 8d6e6830a675..46b47e1fe2a9 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -342,7 +342,6 @@ InstructionTLBMiss: /* We have a pte table, so load the MI_TWC with the attributes * for this "segment." */ - ori r11,r11,1 /* Set valid bit */ MTSPR_CPU6(SPRN_MI_TWC, r11, r3) /* Set segment attributes */ mfspr r11, SPRN_SRR0 /* Get effective address of fault */ /* Extract level 2 index */ @@ -419,7 +418,6 @@ DataStoreTLBMiss: rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */ lwz r10, 0(r10) /* Get the pte */ - ori r11, r11, 1 /* Set valid bit in physical L2 page */ /* Insert the Guarded flag into the TWC from the Linux PTE. * It is bit 27 of both the Linux PTE and the TWC (at least * I got that right :-). It will be better when we can put -- GitLab From b0168eb97b8b02594f47ce44faf1502f79e540df Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:10 +0200 Subject: [PATCH 3986/9457] powerpc/8xx: Don't restore regs to save them again. There is not need to restore r10, r11 and cr registers at this end of ITLBmiss handler as they are saved again to the same place in ITLBError handler we are jumping to. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 46b47e1fe2a9..330d54418494 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -383,8 +383,7 @@ InstructionTLBMiss: lwz r3, 8(r0) #endif mfspr r10, SPRN_SPRG_SCRATCH2 - EXCEPTION_EPILOG_0 - b InstructionTLBError + b InstructionTLBError1 . = 0x1200 DataStoreTLBMiss: @@ -473,7 +472,10 @@ DataStoreTLBMiss: */ . = 0x1300 InstructionTLBError: - EXCEPTION_PROLOG + EXCEPTION_PROLOG_0 +InstructionTLBError1: + EXCEPTION_PROLOG_1 + EXCEPTION_PROLOG_2 mr r4,r12 mr r5,r9 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */ -- GitLab From 83c17ba35e0306e671b5c9ab622535f23a9a3e78 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:10 +0200 Subject: [PATCH 3987/9457] powerpc/8xx: Use DAR to save r3 for CPU6 ERRATA As we are not using anymore DAR to save registers, it is now available for saving the r3 register used for CPU6 ERRATA handling. Therefore we can remove the major hack which was to use memory location 0 to save r3. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 330d54418494..acf6d7eab6d5 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -83,13 +83,6 @@ _ENTRY(_start); * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to * the "internal" processor registers before MMU_init is called. * - * The TLB code currently contains a major hack. Since I use the condition - * code register, I have to save and restore it. I am out of registers, so - * I just store it in memory location 0 (the TLB handlers are not reentrant). - * To avoid making any decisions, I need to use the "segment" valid bit - * in the first level table, but that would require many changes to the - * Linux page directory/table functions that I don't want to do right now. - * * -- Dan */ .globl __start @@ -306,7 +299,7 @@ SystemCall: */ InstructionTLBMiss: #ifdef CONFIG_8xx_CPU6 - stw r3, 8(r0) + mtspr SPRN_DAR, r3 #endif EXCEPTION_PROLOG_0 mtspr SPRN_SPRG_SCRATCH2, r10 @@ -351,7 +344,10 @@ InstructionTLBMiss: #ifdef CONFIG_SWAP andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT + li r11, RPN_PATTERN bne- cr0, 2f +#else + li r11, RPN_PATTERN #endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 21 and 28 must be clear. @@ -359,28 +355,29 @@ InstructionTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r11, RPN_PATTERN rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */ MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ #ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) + mfspr r3, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ #endif mfspr r10, SPRN_SPRG_SCRATCH2 EXCEPTION_EPILOG_0 rfi 2: - mfspr r11, SPRN_SRR1 + mfspr r10, SPRN_SRR1 /* clear all error bits as TLB Miss * sets a few unconditionally */ - rlwinm r11, r11, 0, 0xffff - mtspr SPRN_SRR1, r11 + rlwinm r10, r10, 0, 0xffff + mtspr SPRN_SRR1, r10 /* Restore registers */ #ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) + mfspr r3, SPRN_DAR + mtspr SPRN_DAR, r11 /* Tag DAR */ #endif mfspr r10, SPRN_SPRG_SCRATCH2 b InstructionTLBError1 @@ -388,7 +385,7 @@ InstructionTLBMiss: . = 0x1200 DataStoreTLBMiss: #ifdef CONFIG_8xx_CPU6 - stw r3, 8(r0) + mtspr SPRN_DAR, r3 #endif EXCEPTION_PROLOG_0 mtspr SPRN_SPRG_SCRATCH2, r10 @@ -459,7 +456,7 @@ DataStoreTLBMiss: /* Restore registers */ #ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) + mfspr r3, SPRN_DAR #endif mtspr SPRN_DAR, r11 /* Tag DAR */ mfspr r10, SPRN_SPRG_SCRATCH2 @@ -531,7 +528,7 @@ DARFixed:/* Return from dcbx instruction bug workaround */ #define NO_SELF_MODIFYING_CODE FixupDAR:/* Entry point for dcbx workaround. */ #ifdef CONFIG_8xx_CPU6 - stw r3, 8(r0) + mtspr SPRN_DAR, r3 #endif mtspr SPRN_SPRG_SCRATCH2, r10 /* fetch instruction from memory. */ @@ -550,7 +547,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 lwzx r11, r10, r11 /* Get the pte */ #ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) /* restore r3 from memory */ + mfspr r3, SPRN_DAR #endif /* concat physical page address(r11) and page offset(r10) */ mfspr r10, SPRN_SRR0 -- GitLab From c51a6821bdbc9068adda93b3b8ee65df8e4642a6 Mon Sep 17 00:00:00 2001 From: LEROY Christophe Date: Fri, 19 Sep 2014 10:36:10 +0200 Subject: [PATCH 3988/9457] powerpc/8xx: Invalidate non present TLB as early as possible 8xx sometimes need to load a invalid/non-present TLBs in it DTLB asm handler. These must be invalidated separaly as linux mm doesn't. Commit 5efab4a02c89c252fb4cce097aafde5f8208dbfe was invalidating them in arch/powerpc/mm/fault.c. This patch does the invalidation earlier in order to free the TLB as soon as possible. This also has the advantage of removing some 8xx specific code from fault.c Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- arch/powerpc/kernel/head_8xx.S | 15 ++++++++++----- arch/powerpc/mm/fault.c | 7 ------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index acf6d7eab6d5..d99aac0d69f1 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -475,8 +475,11 @@ InstructionTLBError1: EXCEPTION_PROLOG_2 mr r4,r12 mr r5,r9 + andis. r10,r5,0x4000 + beq+ 1f + tlbie r4 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */ - EXC_XFER_LITE(0x400, handle_page_fault) +1: EXC_XFER_LITE(0x400, handle_page_fault) /* This is the data TLB error on the MPC8xx. This could be due to * many reasons, including a dirty update to a pte. We bail out to @@ -492,11 +495,13 @@ DataTLBError: DARFixed:/* Return from dcbx instruction bug workaround */ EXCEPTION_PROLOG_1 EXCEPTION_PROLOG_2 - mfspr r10,SPRN_DSISR - stw r10,_DSISR(r11) - mr r5,r10 + mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) mfspr r4,SPRN_DAR - li r10,RPN_PATTERN + andis. r10,r5,0x4000 + beq+ 1f + tlbie r4 +1: li r10,RPN_PATTERN mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ /* 0x300 is DataAccess exception, needed by bad_page_fault() */ EXC_XFER_LITE(0x300, handle_page_fault) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 08d659a9fcdb..eb79907f34fa 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -43,7 +43,6 @@ #include #include #include -#include #include "icswx.h" @@ -380,12 +379,6 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, goto bad_area; #endif /* CONFIG_6xx */ #if defined(CONFIG_8xx) - /* 8xx sometimes need to load a invalid/non-present TLBs. - * These must be invalidated separately as linux mm don't. - */ - if (error_code & 0x40000000) /* no translation? */ - _tlbil_va(address, 0, 0, 0); - /* The MPC8xx seems to always set 0x80000000, which is * "undefined". Of those that can be set, this is the only * one which seems bad. -- GitLab From 6f2ce34dd7a2cd34b937a149e5513edd9d9ba724 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 24 Sep 2014 10:06:19 +0200 Subject: [PATCH 3989/9457] powerpc/8xx: Remove Kconfig symbol FADS Commit 39eb56da2b53 ("pcmcia: Remove m8xx_pcmcia driver") removed the only driver that used CONFIG_FADS. Setting the Kconfig symbol FADS is pointless since that commit. Remove it. Signed-off-by: Paul Bolle Signed-off-by: Scott Wood --- arch/powerpc/platforms/8xx/Kconfig | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index bd6f1a1cf922..157250426b56 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -1,6 +1,3 @@ -config FADS - bool - config CPM1 bool select CPM @@ -13,7 +10,6 @@ choice config MPC8XXFADS bool "FADS" - select FADS config MPC86XADS bool "MPC86XADS" -- GitLab From 45c22ed7446fd6acdaaac673ccf5b63862a3e988 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Tue, 7 Oct 2014 18:04:36 +0530 Subject: [PATCH 3990/9457] powerpc/mpc85xx: Remove SPI and NAND partition from bsc9131rdb.dtsi * Run "mtdparts default" on u-boot to create dynamic partitions * Or use dynamic mtd partition with the help of bootargs in u-boot Append bootargs with: "mtdparts=ff800000.flash:1m(nand_uboot),512K(nand_dtb),8m(nand_kernel),-(fs);\ spiff707000.0:1m(spi_uboot),4m(spi_kernel),512k(spi_dtb),-(fs)'" Signed-off-by: Ashish Kumar Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/bsc9131rdb.dtsi | 50 --------------------------- 1 file changed, 50 deletions(-) diff --git a/arch/powerpc/boot/dts/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/bsc9131rdb.dtsi index 9e6c01339ccc..45efcbadb23c 100644 --- a/arch/powerpc/boot/dts/bsc9131rdb.dtsi +++ b/arch/powerpc/boot/dts/bsc9131rdb.dtsi @@ -40,31 +40,6 @@ compatible = "fsl,ifc-nand"; reg = <0x0 0x0 0x4000>; - partition@0 { - /* This location must not be altered */ - /* 3MB for u-boot Bootloader Image */ - reg = <0x0 0x00300000>; - label = "NAND U-Boot Image"; - read-only; - }; - - partition@300000 { - /* 1MB for DTB Image */ - reg = <0x00300000 0x00100000>; - label = "NAND DTB Image"; - }; - - partition@400000 { - /* 8MB for Linux Kernel Image */ - reg = <0x00400000 0x00800000>; - label = "NAND Linux Kernel Image"; - }; - - partition@c00000 { - /* Rest space for Root file System Image */ - reg = <0x00c00000 0x07400000>; - label = "NAND RFS Image"; - }; }; }; @@ -82,31 +57,6 @@ reg = <0>; spi-max-frequency = <50000000>; - /* 512KB for u-boot Bootloader Image */ - partition@0 { - reg = <0x0 0x00080000>; - label = "SPI Flash U-Boot Image"; - read-only; - }; - - /* 512KB for DTB Image */ - partition@80000 { - reg = <0x00080000 0x00080000>; - label = "SPI Flash DTB Image"; - }; - - /* 4MB for Linux Kernel Image */ - partition@100000 { - reg = <0x00100000 0x00400000>; - label = "SPI Flash Kernel Image"; - }; - - /*11MB for RFS Image */ - partition@500000 { - reg = <0x00500000 0x00B00000>; - label = "SPI Flash RFS Image"; - }; - }; }; -- GitLab From 19bc4808f9ecdef9ca3f3b3807a5228b00d74f83 Mon Sep 17 00:00:00 2001 From: Igal Liberman Date: Thu, 30 Oct 2014 11:15:47 +0200 Subject: [PATCH 3991/9457] powerpc/fsl: Added rcw registers to global utility registers The RCW registers are required for the future clock binding implementation. Signed-off-by: Igal Liberman Change-Id: Ic36dd8bc2959aa7f97fb6fd7bbb8420822fef0a9 Signed-off-by: Scott Wood --- arch/powerpc/include/asm/fsl_guts.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 77ced0b3d81d..43b6bb1a4a9c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -68,7 +68,10 @@ struct ccsr_guts { u8 res0b4[0xc0 - 0xb4]; __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register Called 'elbcvselcr' on 86xx SOCs */ - u8 res0c4[0x224 - 0xc4]; + u8 res0c4[0x100 - 0xc4]; + __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers + There are 16 registers */ + u8 res140[0x224 - 0x140]; __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ u8 res22c[0x604 - 0x22c]; -- GitLab From 3b6b17900bfa3c1929741e720495beaa559b2aff Mon Sep 17 00:00:00 2001 From: Hongtao Jia Date: Wed, 5 Nov 2014 14:59:52 +0800 Subject: [PATCH 3992/9457] powerpc: Add ADT7461 to device tree for supported boards Including: T104xRDB T208xQDS B4QDS Signed-off-by: Jia Hongtao Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/b4qds.dtsi | 11 +++++++++++ arch/powerpc/boot/dts/t104xrdb.dtsi | 7 +++++++ arch/powerpc/boot/dts/t208xqds.dtsi | 11 +++++++++++ 3 files changed, 29 insertions(+) diff --git a/arch/powerpc/boot/dts/b4qds.dtsi b/arch/powerpc/boot/dts/b4qds.dtsi index 8b47edcfabf0..bccc9867bc6b 100644 --- a/arch/powerpc/boot/dts/b4qds.dtsi +++ b/arch/powerpc/boot/dts/b4qds.dtsi @@ -152,6 +152,17 @@ reg = <0x68>; }; }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + + adt7461@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/t104xrdb.dtsi b/arch/powerpc/boot/dts/t104xrdb.dtsi index 1cf0f3c5f7e5..187add885cae 100644 --- a/arch/powerpc/boot/dts/t104xrdb.dtsi +++ b/arch/powerpc/boot/dts/t104xrdb.dtsi @@ -83,6 +83,13 @@ }; }; + i2c@118000 { + adt7461@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + }; + i2c@118100 { pca9546@77 { compatible = "nxp,pca9546"; diff --git a/arch/powerpc/boot/dts/t208xqds.dtsi b/arch/powerpc/boot/dts/t208xqds.dtsi index 555dc6e03d89..59061834d54e 100644 --- a/arch/powerpc/boot/dts/t208xqds.dtsi +++ b/arch/powerpc/boot/dts/t208xqds.dtsi @@ -169,6 +169,17 @@ shunt-resistor = <1000>; }; }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + + adt7461@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + }; }; }; -- GitLab From 94701fcb2f085cef29b29051f21de7fc3718217a Mon Sep 17 00:00:00 2001 From: Hongtao Jia Date: Wed, 5 Nov 2014 14:59:53 +0800 Subject: [PATCH 3993/9457] powerpc: Add INA220 to device tree for supported boards Including: P3041DS P5020DS P5040DS B4QDS Signed-off-by: Jia Hongtao Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/b4qds.dtsi | 12 ++++++++++++ arch/powerpc/boot/dts/p3041ds.dts | 20 ++++++++++++++++++++ arch/powerpc/boot/dts/p5020ds.dts | 20 ++++++++++++++++++++ arch/powerpc/boot/dts/p5040ds.dts | 20 ++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/arch/powerpc/boot/dts/b4qds.dtsi b/arch/powerpc/boot/dts/b4qds.dtsi index bccc9867bc6b..e5bde0b85135 100644 --- a/arch/powerpc/boot/dts/b4qds.dtsi +++ b/arch/powerpc/boot/dts/b4qds.dtsi @@ -153,6 +153,18 @@ }; }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2>; + + ina220@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + }; + i2c@3 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts index 2fed3bc0b990..394ea9c943c9 100644 --- a/arch/powerpc/boot/dts/p3041ds.dts +++ b/arch/powerpc/boot/dts/p3041ds.dts @@ -98,6 +98,26 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; + ina220@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + ina220@41 { + compatible = "ti,ina220"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + ina220@44 { + compatible = "ti,ina220"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + ina220@45 { + compatible = "ti,ina220"; + reg = <0x45>; + shunt-resistor = <1000>; + }; adt7461@4c { compatible = "adi,adt7461"; reg = <0x4c>; diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts index 2869fea717dd..b7f3057cd894 100644 --- a/arch/powerpc/boot/dts/p5020ds.dts +++ b/arch/powerpc/boot/dts/p5020ds.dts @@ -98,6 +98,26 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; + ina220@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + ina220@41 { + compatible = "ti,ina220"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + ina220@44 { + compatible = "ti,ina220"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + ina220@45 { + compatible = "ti,ina220"; + reg = <0x45>; + shunt-resistor = <1000>; + }; adt7461@4c { compatible = "adi,adt7461"; reg = <0x4c>; diff --git a/arch/powerpc/boot/dts/p5040ds.dts b/arch/powerpc/boot/dts/p5040ds.dts index 860b5ccf76c0..7e04bf487c04 100644 --- a/arch/powerpc/boot/dts/p5040ds.dts +++ b/arch/powerpc/boot/dts/p5040ds.dts @@ -95,6 +95,26 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; + ina220@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + ina220@41 { + compatible = "ti,ina220"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + ina220@44 { + compatible = "ti,ina220"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + ina220@45 { + compatible = "ti,ina220"; + reg = <0x45>; + shunt-resistor = <1000>; + }; adt7461@4c { compatible = "adi,adt7461"; reg = <0x4c>; -- GitLab From eaffcb0f1bebbcfd38ecc9bdca105f7123115ab1 Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Thu, 6 Nov 2014 09:48:11 -0600 Subject: [PATCH 3994/9457] powerpc/dts: Factorize the clock control node Signed-off-by: Emil Medve Change-Id: I25ce24a25862b4ca460164159867abefe00ccdd1 Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/b4860emu.dts | 4 +- arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | 28 +------ arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | 28 +------ arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | 48 +----------- arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | 48 +----------- arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | 48 +----------- arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 48 +----------- arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | 48 +----------- .../powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi | 78 +++++++++++++++++++ .../powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi | 61 +++++++++++++++ arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 30 +------ arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 29 +------ arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 29 +------ arch/powerpc/boot/dts/t4240emu.dts | 4 +- 14 files changed, 163 insertions(+), 368 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi diff --git a/arch/powerpc/boot/dts/b4860emu.dts b/arch/powerpc/boot/dts/b4860emu.dts index 85646b4f96e1..2aa5cd318ce8 100644 --- a/arch/powerpc/boot/dts/b4860emu.dts +++ b/arch/powerpc/boot/dts/b4860emu.dts @@ -193,9 +193,9 @@ fsl,liodn-bits = <12>; }; - clockgen: global-utilities@e1000 { +/include/ "fsl/qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0"; - reg = <0xe1000 0x1000>; }; /include/ "fsl/qoriq-dma-0.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi index d67894459ac8..86161ae6c966 100644 --- a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi @@ -80,33 +80,9 @@ compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0"; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0"; - ranges = <0x0 0xe1000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-2.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2", "pll0-div4"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2", "pll1-div4"; - }; mux0: mux0@0 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi index 582381dba1d7..65100b9636b7 100644 --- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi @@ -124,33 +124,9 @@ compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0"; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0"; - ranges = <0x0 0xe1000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-2.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2", "pll0-div4"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2", "pll1-div4"; - }; mux0: mux0@0 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 69ce1026c948..efd74db4f9b0 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -305,53 +305,9 @@ #sleep-cells = <2>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen1.dtsi" + global-utilities@e1000 { compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-1.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2"; - }; - - mux0: mux0@0 { - #clock-cells = <0>; - reg = <0x0 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux0"; - }; - - mux1: mux1@20 { - #clock-cells = <0>; - reg = <0x20 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux1"; - }; mux2: mux2@40 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi index cd63cb1b1042..d7425ef1ae41 100644 --- a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi @@ -332,53 +332,9 @@ #sleep-cells = <2>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen1.dtsi" + global-utilities@e1000 { compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-1.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2"; - }; - - mux0: mux0@0 { - #clock-cells = <0>; - reg = <0x0 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux0"; - }; - - mux1: mux1@20 { - #clock-cells = <0>; - reg = <0x20 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux1"; - }; mux2: mux2@40 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi index 12947ccddf25..7005a4a4cef0 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi @@ -352,35 +352,9 @@ #sleep-cells = <2>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen1.dtsi" + global-utilities@e1000 { compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-1.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2"; - }; pll2: pll2@840 { #clock-cells = <1>; @@ -398,24 +372,6 @@ clock-output-names = "pll3", "pll3-div2"; }; - mux0: mux0@0 { - #clock-cells = <0>; - reg = <0x0 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux0"; - }; - - mux1: mux1@20 { - #clock-cells = <0>; - reg = <0x20 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux1"; - }; - mux2: mux2@40 { #clock-cells = <0>; reg = <0x40 0x4>; diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi index 4c4a2b0436b2..55834211bd28 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi @@ -337,53 +337,9 @@ #sleep-cells = <2>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen1.dtsi" + global-utilities@e1000 { compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-1.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2"; - }; - - mux0: mux0@0 { - #clock-cells = <0>; - reg = <0x0 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux0"; - }; - - mux1: mux1@20 { - #clock-cells = <0>; - reg = <0x20 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux1"; - }; }; rcpm: global-utilities@e2000 { diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi index 67296fdd9698..6e4cd6ce363c 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi @@ -297,53 +297,9 @@ #sleep-cells = <2>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen1.dtsi" + global-utilities@e1000 { compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-1.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-1.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2"; - }; - - mux0: mux0@0 { - #clock-cells = <0>; - reg = <0x0 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux0"; - }; - - mux1: mux1@20 { - #clock-cells = <0>; - reg = <0x20 0x4>; - compatible = "fsl,qoriq-core-mux-1.0"; - clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; - clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; - clock-output-names = "cmux1"; - }; mux2: mux2@40 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi new file mode 100644 index 000000000000..48710482806e --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi @@ -0,0 +1,78 @@ +/* + * QorIQ clock control device tree stub [ controller @ offset 0xe1000 ] + * + * Copyright 2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +global-utilities@e1000 { + compatible = "fsl,qoriq-clockgen-1.0"; + ranges = <0x0 0xe1000 0x1000>; + reg = <0xe1000 0x1000>; + clock-frequency = <0>; + #address-cells = <1>; + #size-cells = <1>; + + sysclk: sysclk { + #clock-cells = <0>; + compatible = "fsl,qoriq-sysclk-1.0", "fixed-clock"; + clock-output-names = "sysclk"; + }; + pll0: pll0@800 { + #clock-cells = <1>; + reg = <0x800 0x4>; + compatible = "fsl,qoriq-core-pll-1.0"; + clocks = <&sysclk>; + clock-output-names = "pll0", "pll0-div2"; + }; + pll1: pll1@820 { + #clock-cells = <1>; + reg = <0x820 0x4>; + compatible = "fsl,qoriq-core-pll-1.0"; + clocks = <&sysclk>; + clock-output-names = "pll1", "pll1-div2"; + }; + mux0: mux0@0 { + #clock-cells = <0>; + reg = <0x0 0x4>; + compatible = "fsl,qoriq-core-mux-1.0"; + clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; + clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; + clock-output-names = "cmux0"; + }; + mux1: mux1@20 { + #clock-cells = <0>; + reg = <0x20 0x4>; + compatible = "fsl,qoriq-core-mux-1.0"; + clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>; + clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; + clock-output-names = "cmux1"; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi new file mode 100644 index 000000000000..5d18d2a6cf52 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi @@ -0,0 +1,61 @@ +/* + * QorIQ clock control device tree stub [ controller @ offset 0xe1000 ] + * + * Copyright 2014 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +global-utilities@e1000 { + compatible = "fsl,qoriq-clockgen-2.0"; + ranges = <0x0 0xe1000 0x1000>; + reg = <0xe1000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + sysclk: sysclk { + #clock-cells = <0>; + compatible = "fsl,qoriq-sysclk-2.0", "fixed-clock"; + clock-output-names = "sysclk"; + }; + pll0: pll0@800 { + #clock-cells = <1>; + reg = <0x800 0x4>; + compatible = "fsl,qoriq-core-pll-2.0"; + clocks = <&sysclk>; + clock-output-names = "pll0", "pll0-div2", "pll0-div4"; + }; + pll1: pll1@820 { + #clock-cells = <1>; + reg = <0x820 0x4>; + compatible = "fsl,qoriq-core-pll-2.0"; + clocks = <&sysclk>; + clock-output-names = "pll1", "pll1-div2", "pll1-div4"; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi index 12e597eea3c8..15ae462e758f 100644 --- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi @@ -281,35 +281,9 @@ fsl,liodn-bits = <12>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,t1040-clockgen", "fsl,qoriq-clockgen-2.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-2.0"; - clock-output-names = "sysclk", "fixed-clock"; - }; - - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2", "pll0-div4"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2", "pll1-div4"; - }; mux0: mux0@0 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi index aecee9690a88..1ce91e3485a9 100644 --- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi @@ -305,34 +305,9 @@ fsl,liodn-bits = <12>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-2.0"; - clock-output-names = "sysclk", "fixed-clock"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2", "pll0-div4"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2", "pll1-div4"; - }; mux0: mux0@0 { #clock-cells = <0>; diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index 7e2fc7cdce48..0e96fcabe812 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi @@ -368,34 +368,9 @@ fsl,liodn-bits = <12>; }; - clockgen: global-utilities@e1000 { +/include/ "qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; - ranges = <0x0 0xe1000 0x1000>; - reg = <0xe1000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - - sysclk: sysclk { - #clock-cells = <0>; - compatible = "fsl,qoriq-sysclk-2.0"; - clock-output-names = "sysclk"; - }; - - pll0: pll0@800 { - #clock-cells = <1>; - reg = <0x800 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll0", "pll0-div2", "pll0-div4"; - }; - - pll1: pll1@820 { - #clock-cells = <1>; - reg = <0x820 0x4>; - compatible = "fsl,qoriq-core-pll-2.0"; - clocks = <&sysclk>; - clock-output-names = "pll1", "pll1-div2", "pll1-div4"; - }; pll2: pll2@840 { #clock-cells = <1>; diff --git a/arch/powerpc/boot/dts/t4240emu.dts b/arch/powerpc/boot/dts/t4240emu.dts index bc12127a03fb..decaf357db9c 100644 --- a/arch/powerpc/boot/dts/t4240emu.dts +++ b/arch/powerpc/boot/dts/t4240emu.dts @@ -250,9 +250,9 @@ fsl,liodn-bits = <12>; }; - clockgen: global-utilities@e1000 { +/include/ "fsl/qoriq-clockgen2.dtsi" + global-utilities@e1000 { compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; - reg = <0xe1000 0x1000>; }; /include/ "fsl/qoriq-dma-0.dtsi" -- GitLab From f1aa77c9703148fad7d819d9d764dae0cb82d141 Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Thu, 6 Nov 2014 09:48:12 -0600 Subject: [PATCH 3995/9457] dt/bindings: qoriq-clock: Add binding for the platform PLL Signed-off-by: Emil Medve Change-Id: I7950afa9650d15ec7ce2cca89bb2a1e38586d4a5 Signed-off-by: Scott Wood --- .../devicetree/bindings/clock/qoriq-clock.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt index 5666812fc42b..266ff9d23229 100644 --- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt @@ -62,6 +62,8 @@ Required properties: It takes parent's clock-frequency as its clock. * "fsl,qoriq-sysclk-2.0": for input system clock (v2.0). It takes parent's clock-frequency as its clock. + * "fsl,qoriq-platform-pll-1.0" for the platform PLL clock (v1.0) + * "fsl,qoriq-platform-pll-2.0" for the platform PLL clock (v2.0) - #clock-cells: From common clock binding. The number of cells in a clock-specifier. Should be <0> for "fsl,qoriq-sysclk-[1,2].0" clocks, or <1> for "fsl,qoriq-core-pll-[1,2].0" clocks. @@ -128,8 +130,16 @@ Example for clock block and clock provider: clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; clock-output-names = "cmux1"; }; + + platform-pll: platform-pll@c00 { + #clock-cells = <1>; + reg = <0xc00 0x4>; + compatible = "fsl,qoriq-platform-pll-1.0"; + clocks = <&sysclk>; + clock-output-names = "platform-pll", "platform-pll-div2"; + }; }; - } +}; Example for clock consumer: @@ -139,4 +149,4 @@ Example for clock consumer: clocks = <&mux0>; ... }; - } +}; -- GitLab From 58810cb7f66e47fce2e8945deeab5a4226e3975c Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Thu, 6 Nov 2014 09:48:13 -0600 Subject: [PATCH 3996/9457] powerpc/dts: Add node(s) for the platform PLL Signed-off-by: Emil Medve Change-Id: If76cd705a01813abe53396c1486bc13c4289ee92 Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi | 7 +++++++ arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi index 48710482806e..4ece1edbff63 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi @@ -75,4 +75,11 @@ global-utilities@e1000 { clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2"; clock-output-names = "cmux1"; }; + platform_pll: platform-pll@c00 { + #clock-cells = <1>; + reg = <0xc00 0x4>; + compatible = "fsl,qoriq-platform-pll-1.0"; + clocks = <&sysclk>; + clock-output-names = "platform-pll", "platform-pll-div2"; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi index 5d18d2a6cf52..48e0b6e4ce33 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi @@ -58,4 +58,11 @@ global-utilities@e1000 { clocks = <&sysclk>; clock-output-names = "pll1", "pll1-div2", "pll1-div4"; }; + platform_pll: platform-pll@c00 { + #clock-cells = <1>; + reg = <0xc00 0x4>; + compatible = "fsl,qoriq-platform-pll-2.0"; + clocks = <&sysclk>; + clock-output-names = "platform-pll", "platform-pll-div2"; + }; }; -- GitLab From d14cb5df59037f690e62f828c9977c23b1a59e0b Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:58 +0200 Subject: [PATCH 3997/9457] KVM: x86: Emulator mis-decodes VEX instructions on real-mode Commit 7fe864dc942c (KVM: x86: Mark VEX-prefix instructions emulation as unimplemented, 2014-06-02) marked VEX instructions as such in protected mode. VEX-prefix instructions are not supported relevant on real-mode and VM86, but should cause #UD instead of being decoded as LES/LDS. Fix this behaviour to be consistent with real hardware. Signed-off-by: Nadav Amit [Check for mod == 3, rather than 2 or 3. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 765f1897814b..bf4d23e0f76e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -4517,8 +4517,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) /* vex-prefix instructions are not implemented */ if (ctxt->opcode_len == 1 && (ctxt->b == 0xc5 || ctxt->b == 0xc4) && - (mode == X86EMUL_MODE_PROT64 || - (mode >= X86EMUL_MODE_PROT16 && (ctxt->modrm & 0x80)))) { + (mode == X86EMUL_MODE_PROT64 || (ctxt->modrm & 0xc0) == 0xc0)) { ctxt->d = NotImpl; } -- GitLab From db324fe6f20b0ad118d230da23107ddb12784e8c Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:59 +0200 Subject: [PATCH 3998/9457] KVM: x86: Warn on APIC base relocation APIC base relocation is unsupported by KVM. If anyone uses it, the least should be to report a warning in the hypervisor. Note that KVM-unit-tests uses this feature for some reason, so running the tests triggers the warning. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e7f7fc632a9b..344e7d36d0e8 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1457,6 +1457,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) apic->base_address = apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_BASE; + if ((value & MSR_IA32_APICBASE_ENABLE) && + apic->base_address != APIC_DEFAULT_PHYS_BASE) + pr_warn_once("APIC base relocation is unsupported by KVM"); + /* with FSB delivery interrupt, we can restart APIC functionality */ apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is " "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address); -- GitLab From b2c9d43e6c0f821bde0c1c840038d159d18f1519 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:55:01 +0200 Subject: [PATCH 3999/9457] KVM: x86: Return UNHANDLABLE on unsupported SYSENTER Now that KVM injects #UD on "unhandlable" error, it makes better sense to return such error on sysenter instead of directly injecting #UD to the guest. This allows to track more easily the unhandlable cases the emulator does not support. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index bf4d23e0f76e..dab9b74c29de 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2358,11 +2358,9 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) && !vendor_intel(ctxt)) return emulate_ud(ctxt); - /* XXX sysenter/sysexit have not been tested in 64bit mode. - * Therefore, we inject an #UD. - */ + /* sysenter/sysexit have not been tested in 64bit mode. */ if (ctxt->mode == X86EMUL_MODE_PROT64) - return emulate_ud(ctxt); + return X86EMUL_UNHANDLEABLE; setup_syscalls_segments(ctxt, &cs, &ss); -- GitLab From 7f187922ddf6b67f2999a76dcb71663097b75497 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 4 Nov 2014 21:30:44 -0200 Subject: [PATCH 4000/9457] KVM: x86: update masterclock values on TSC writes When the guest writes to the TSC, the masterclock TSC copy must be updated as well along with the TSC_OFFSET update, otherwise a negative tsc_timestamp is calculated at kvm_guest_time_update. Once "if (!vcpus_matched && ka->use_master_clock)" is simplified to "if (ka->use_master_clock)", the corresponding "if (!ka->use_master_clock)" becomes redundant, so remove the do_request boolean and collapse everything into a single condition. Signed-off-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index da1591eeb477..e0260ccd78a4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1235,21 +1235,22 @@ void kvm_track_tsc_matching(struct kvm_vcpu *vcpu) { #ifdef CONFIG_X86_64 bool vcpus_matched; - bool do_request = false; struct kvm_arch *ka = &vcpu->kvm->arch; struct pvclock_gtod_data *gtod = &pvclock_gtod_data; vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 == atomic_read(&vcpu->kvm->online_vcpus)); - if (vcpus_matched && gtod->clock.vclock_mode == VCLOCK_TSC) - if (!ka->use_master_clock) - do_request = 1; - - if (!vcpus_matched && ka->use_master_clock) - do_request = 1; - - if (do_request) + /* + * Once the masterclock is enabled, always perform request in + * order to update it. + * + * In order to enable masterclock, the host clocksource must be TSC + * and the vcpus need to have matched TSCs. When that happens, + * perform request to enable masterclock. + */ + if (ka->use_master_clock || + (gtod->clock.vclock_mode == VCLOCK_TSC && vcpus_matched)) kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc, -- GitLab From ed9aad215ff3374ffd720b83d26fda91e4367090 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:55:00 +0200 Subject: [PATCH 4001/9457] KVM: x86: MOVNTI emulation min opsize is not respected Commit 3b32004a66e9 ("KVM: x86: movnti minimum op size of 32-bit is not kept") did not fully fix the minimum operand size of MONTI emulation. Still, MOVNTI may be mistakenly performed using 16-bit opsize. This patch add No16 flag to mark an instruction does not support 16-bits operand size. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index dab9b74c29de..e020fed0b019 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -167,6 +167,7 @@ #define NoBigReal ((u64)1 << 50) /* No big real mode */ #define PrivUD ((u64)1 << 51) /* #UD instead of #GP on CPL > 0 */ #define NearBranch ((u64)1 << 52) /* Near branches */ +#define No16 ((u64)1 << 53) /* No 16 bit operand */ #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) @@ -4134,7 +4135,7 @@ static const struct opcode twobyte_table[256] = { D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xC7 */ F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), - N, D(DstMem | SrcReg | ModRM | Mov), + N, I(DstMem | SrcReg | ModRM | No16 | Mov, em_mov), N, N, N, GD(0, &group9), /* 0xC8 - 0xCF */ X8(I(DstReg, em_bswap)), @@ -4571,7 +4572,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) return EMULATION_FAILED; if (unlikely(ctxt->d & - (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch))) { + (NotImpl|Stack|Op3264|Sse|Mmx|Intercept|CheckPerm|NearBranch| + No16))) { /* * These are copied unconditionally here, and checked unconditionally * in x86_emulate_insn. @@ -4596,6 +4598,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) ctxt->op_bytes = 4; } + if ((ctxt->d & No16) && ctxt->op_bytes == 2) + ctxt->op_bytes = 4; + if (ctxt->d & Sse) ctxt->op_bytes = 16; else if (ctxt->d & Mmx) @@ -5061,11 +5066,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : (s16) ctxt->src.val; break; - case 0xc3: /* movnti */ - ctxt->dst.bytes = ctxt->op_bytes; - ctxt->dst.val = (ctxt->op_bytes == 8) ? (u64) ctxt->src.val : - (u32) ctxt->src.val; - break; default: goto cannot_emulate; } -- GitLab From 09a0c3f110b2fbe3bd03817c416d00968666fd74 Mon Sep 17 00:00:00 2001 From: Owen Hofmann Date: Mon, 3 Nov 2014 16:57:18 -0800 Subject: [PATCH 4002/9457] kvm: x86: Fix kvm clock versioning. kvm updates the version number for the guest paravirt clock structure by incrementing the version of its private copy. It does not read the guest version, so will write version = 2 in the first update for every new VM, including after restoring a saved state. If guest state is saved during reading the clock, it could read and accept struct fields and guest TSC from two different updates. This changes the code to increment the guest version and write it back. Signed-off-by: Owen Hofmann Reviewed-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e0260ccd78a4..8bf37d0ab404 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1636,16 +1636,16 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset; vcpu->last_guest_tsc = tsc_timestamp; + if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time, + &guest_hv_clock, sizeof(guest_hv_clock)))) + return 0; + /* * The interface expects us to write an even number signaling that the * update is finished. Since the guest won't see the intermediate * state, we just increase by 2 at the end. */ - vcpu->hv_clock.version += 2; - - if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time, - &guest_hv_clock, sizeof(guest_hv_clock)))) - return 0; + vcpu->hv_clock.version = guest_hv_clock.version + 2; /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */ pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED); -- GitLab From ce1a5e60a62f21a6b5ad3e1dee60c10f0cb2aa37 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 5 Nov 2014 11:46:42 -0800 Subject: [PATCH 4003/9457] kvm: x86: add trace event for pvclock updates The new trace event records: * the id of vcpu being updated * the pvclock_vcpu_time_info struct being written to guest memory This is useful for debugging pvclock bugs, such as the bug fixed by "[PATCH] kvm: x86: Fix kvm clock versioning.". Signed-off-by: David Matlack Signed-off-by: Paolo Bonzini --- arch/x86/kvm/trace.h | 37 +++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 2 ++ 2 files changed, 39 insertions(+) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 6b06ab8748dd..c2a34bb5ad93 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -5,6 +5,7 @@ #include #include #include +#include #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm @@ -877,6 +878,42 @@ TRACE_EVENT(kvm_ple_window, #define trace_kvm_ple_window_shrink(vcpu_id, new, old) \ trace_kvm_ple_window(false, vcpu_id, new, old) +TRACE_EVENT(kvm_pvclock_update, + TP_PROTO(unsigned int vcpu_id, struct pvclock_vcpu_time_info *pvclock), + TP_ARGS(vcpu_id, pvclock), + + TP_STRUCT__entry( + __field( unsigned int, vcpu_id ) + __field( __u32, version ) + __field( __u64, tsc_timestamp ) + __field( __u64, system_time ) + __field( __u32, tsc_to_system_mul ) + __field( __s8, tsc_shift ) + __field( __u8, flags ) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->version = pvclock->version; + __entry->tsc_timestamp = pvclock->tsc_timestamp; + __entry->system_time = pvclock->system_time; + __entry->tsc_to_system_mul = pvclock->tsc_to_system_mul; + __entry->tsc_shift = pvclock->tsc_shift; + __entry->flags = pvclock->flags; + ), + + TP_printk("vcpu_id %u, pvclock { version %u, tsc_timestamp 0x%llx, " + "system_time 0x%llx, tsc_to_system_mul 0x%x, tsc_shift %d, " + "flags 0x%x }", + __entry->vcpu_id, + __entry->version, + __entry->tsc_timestamp, + __entry->system_time, + __entry->tsc_to_system_mul, + __entry->tsc_shift, + __entry->flags) +); + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8bf37d0ab404..f85da5cb6aa6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1661,6 +1661,8 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) vcpu->hv_clock.flags = pvclock_flags; + trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock); + kvm_write_guest_cached(v->kvm, &vcpu->pv_time, &vcpu->hv_clock, sizeof(vcpu->hv_clock)); -- GitLab From cfb4bbd8fbed76a6b715916fabeca4597cb38721 Mon Sep 17 00:00:00 2001 From: Torsten Fleischer Date: Fri, 7 Nov 2014 18:11:58 +0100 Subject: [PATCH 4004/9457] spi: spi-gpio: Fix compiler warning when building for 64 bit systems The assignment of SPI_GPIO_NO_CHIPSELECT to cs_gpios[0] causes the following compiler warning, when building for 64 bit systems: "warning: overflow in implicit constant conversion [-Woverflow]". This is because the SPI_GPIO_NO_CHIPSELECT flag is a '-1' type casted to unsigned long and cs_gpios is of the type int. Furthermore the chip select's GPIO number is locally stored as unsigned int and compared with SPI_GPIO_NO_CHIPSELECT. Thus the result of the comparison is always false, if unsigned long and unsigned int have a different size. As part of the fix this patch adds a check for the device tree's cs-gpios property. Reported-by: kbuild test robot Signed-off-by: Torsten Fleischer Signed-off-by: Mark Brown --- drivers/spi/spi-gpio.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index f0492c99d145..4b600d4f8548 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c @@ -48,7 +48,7 @@ struct spi_gpio { struct spi_bitbang bitbang; struct spi_gpio_platform_data pdata; struct platform_device *pdev; - int cs_gpios[0]; + unsigned long cs_gpios[0]; }; /*----------------------------------------------------------------------*/ @@ -220,7 +220,7 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, static void spi_gpio_chipselect(struct spi_device *spi, int is_active) { struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); - unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; + unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; /* set initial clock polarity */ if (is_active) @@ -234,7 +234,7 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) static int spi_gpio_setup(struct spi_device *spi) { - unsigned int cs; + unsigned long cs; int status = 0; struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); struct device_node *np = spi->master->dev.of_node; @@ -249,7 +249,7 @@ static int spi_gpio_setup(struct spi_device *spi) /* * ... otherwise, take it from spi->controller_data */ - cs = (unsigned int)(uintptr_t) spi->controller_data; + cs = (uintptr_t) spi->controller_data; } if (!spi->controller_state) { @@ -277,7 +277,7 @@ static int spi_gpio_setup(struct spi_device *spi) static void spi_gpio_cleanup(struct spi_device *spi) { struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); - unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; + unsigned long cs = spi_gpio->cs_gpios[spi->chip_select]; if (cs != SPI_GPIO_NO_CHIPSELECT) gpio_free(cs); @@ -437,7 +437,7 @@ static int spi_gpio_probe(struct platform_device *pdev) return status; master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + - (sizeof(int) * num_devices)); + (sizeof(unsigned long) * num_devices)); if (!master) { status = -ENOMEM; goto gpio_free; @@ -470,9 +470,15 @@ static int spi_gpio_probe(struct platform_device *pdev) if (!SPI_N_CHIPSEL) spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT; else - for (i = 0; i < SPI_N_CHIPSEL; i++) - spi_gpio->cs_gpios[i] = - of_get_named_gpio(np, "cs-gpios", i); + for (i = 0; i < SPI_N_CHIPSEL; i++) { + status = of_get_named_gpio(np, "cs-gpios", i); + if (status < 0) { + dev_err(&pdev->dev, + "invalid cs-gpios property\n"); + goto gpio_free; + } + spi_gpio->cs_gpios[i] = status; + } } #endif -- GitLab From cf1f2ebe8d6176de80ef9d9c979f998ec38fb265 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Nov 2014 19:33:03 +0100 Subject: [PATCH 4005/9457] ASoC: wm9712/wm9713: Replace virtual registers with custom put/get callbacks The wm9712/wm9713 has separate mixers for the left and the right channel, but the inputs to the mixers are enabled/disabled by the same control. Currently this is implemented by the driver by registering two virtual controls for each physical control, one for the left mixer and one for the right mixer. Using virtual registers will no longer work when the driver has been converted to regmap. This patch converts the driver to use controls with custom put/get callbacks instead which implement the logic making sure that the physical control is unmuted when either the left or the right control is unmuted. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 163 ++++++++++++++++++++++++-------------- sound/soc/codecs/wm9713.c | 153 ++++++++++++++++++++--------------- 2 files changed, 194 insertions(+), 122 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index f3aab6e1d92a..3fad37e0d33d 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -23,6 +23,11 @@ #include #include "wm9712.h" +struct wm9712_priv { + unsigned int hp_mixer[2]; + struct mutex lock; +}; + static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg); static int ac97_write(struct snd_soc_codec *codec, @@ -48,12 +53,10 @@ static const u16 wm9712_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */ 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */ 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */ - 0x0000, 0x0000 /* virtual hp mixers */ }; -/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 +#define HPL_MIXER 0x0 +#define HPR_MIXER 0x1 static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"}; static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"}; @@ -157,75 +160,108 @@ SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv), SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv), }; +static const unsigned int wm9712_mixer_mute_regs[] = { + AC97_VIDEO, + AC97_PCM, + AC97_LINE, + AC97_PHONE, + AC97_CD, + AC97_PC_BEEP, +}; + /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ -static int mixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) +static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - u16 l, r, beep, line, phone, mic, pcm, aux; - - l = ac97_read(w->codec, HPL_MIXER); - r = ac97_read(w->codec, HPR_MIXER); - beep = ac97_read(w->codec, AC97_PC_BEEP); - mic = ac97_read(w->codec, AC97_VIDEO); - phone = ac97_read(w->codec, AC97_PHONE); - line = ac97_read(w->codec, AC97_LINE); - pcm = ac97_read(w->codec, AC97_PCM); - aux = ac97_read(w->codec, AC97_CD); - - if (l & 0x1 || r & 0x1) - ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + unsigned int val = ucontrol->value.enumerated.item[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int mixer, mask, shift, old; + struct snd_soc_dapm_update update; + bool change; + + mixer = mc->shift >> 8; + shift = mc->shift & 0xff; + mask = 1 << shift; + + mutex_lock(&wm9712->lock); + old = wm9712->hp_mixer[mixer]; + if (ucontrol->value.enumerated.item[0]) + wm9712->hp_mixer[mixer] |= mask; else - ac97_write(w->codec, AC97_VIDEO, mic | 0x8000); + wm9712->hp_mixer[mixer] &= ~mask; + + change = old != wm9712->hp_mixer[mixer]; + if (change) { + update.kcontrol = kcontrol; + update.reg = wm9712_mixer_mute_regs[shift]; + update.mask = 0x8000; + if ((wm9712->hp_mixer[0] & mask) || + (wm9712->hp_mixer[1] & mask)) + update.val = 0x0; + else + update.val = 0x8000; + + snd_soc_dapm_mixer_update_power(dapm, kcontrol, val, + &update); + } - if (l & 0x2 || r & 0x2) - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff); - else - ac97_write(w->codec, AC97_PCM, pcm | 0x8000); + mutex_unlock(&wm9712->lock); - if (l & 0x4 || r & 0x4) - ac97_write(w->codec, AC97_LINE, line & 0x7fff); - else - ac97_write(w->codec, AC97_LINE, line | 0x8000); + return change; +} - if (l & 0x8 || r & 0x8) - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff); - else - ac97_write(w->codec, AC97_PHONE, phone | 0x8000); +static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int shift, mixer; - if (l & 0x10 || r & 0x10) - ac97_write(w->codec, AC97_CD, aux & 0x7fff); - else - ac97_write(w->codec, AC97_CD, aux | 0x8000); + mixer = mc->shift >> 8; + shift = mc->shift & 0xff; - if (l & 0x20 || r & 0x20) - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff); - else - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000); + ucontrol->value.enumerated.item[0] = + (wm9712->hp_mixer[mixer] >> shift) & 1; return 0; } +#define WM9712_HP_MIXER_CTRL(xname, xmixer, xshift) { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, \ + .get = wm9712_hp_mixer_get, .put = wm9712_hp_mixer_put, \ + .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, \ + (xmixer << 8) | xshift, 1, 0, 0) \ +} + /* Left Headphone Mixers */ static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0), + WM9712_HP_MIXER_CTRL("PCBeep Bypass Switch", HPL_MIXER, 5), + WM9712_HP_MIXER_CTRL("Aux Playback Switch", HPL_MIXER, 4), + WM9712_HP_MIXER_CTRL("Phone Bypass Switch", HPL_MIXER, 3), + WM9712_HP_MIXER_CTRL("Line Bypass Switch", HPL_MIXER, 2), + WM9712_HP_MIXER_CTRL("PCM Playback Switch", HPL_MIXER, 1), + WM9712_HP_MIXER_CTRL("Mic Sidetone Switch", HPL_MIXER, 0), }; /* Right Headphone Mixers */ static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0), + WM9712_HP_MIXER_CTRL("PCBeep Bypass Switch", HPR_MIXER, 5), + WM9712_HP_MIXER_CTRL("Aux Playback Switch", HPR_MIXER, 4), + WM9712_HP_MIXER_CTRL("Phone Bypass Switch", HPR_MIXER, 3), + WM9712_HP_MIXER_CTRL("Line Bypass Switch", HPR_MIXER, 2), + WM9712_HP_MIXER_CTRL("PCM Playback Switch", HPR_MIXER, 1), + WM9712_HP_MIXER_CTRL("Mic Sidetone Switch", HPR_MIXER, 0), }; /* Speaker Mixer */ @@ -299,12 +335,10 @@ SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, &wm9712_diff_sel_controls), SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1, - &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1, - &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_INT_PAGING, 9, 1, + &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls)), +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_INT_PAGING, 8, 1, + &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls)), SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1, &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)), SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1, @@ -471,8 +505,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, { u16 *cache = codec->reg_cache; - if (reg < 0x7c) - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(codec->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; @@ -684,6 +717,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { static int wm9712_probe(struct platform_device *pdev) { + struct wm9712_priv *wm9712; + + wm9712 = devm_kzalloc(&pdev->dev, sizeof(*wm9712), GFP_KERNEL); + if (wm9712 == NULL) + return -ENOMEM; + + mutex_init(&wm9712->lock); + + platform_set_drvdata(pdev, wm9712); + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai)); } diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ac13fc8f5c70..998e4c7b6b12 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -31,6 +31,8 @@ struct wm9713_priv { u32 pll_in; /* PLL input frequency */ + unsigned int hp_mixer[2]; + struct mutex lock; }; static unsigned int ac97_read(struct snd_soc_codec *codec, @@ -59,12 +61,10 @@ static const u16 wm9713_reg[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0001, 0x0000, 0x574d, 0x4c13, - 0x0000, 0x0000 }; -/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 +#define HPL_MIXER 0 +#define HPR_MIXER 1 static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; @@ -233,6 +233,14 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, return 0; } +static const unsigned int wm9713_mixer_mute_regs[] = { + AC97_PC_BEEP, + AC97_MASTER_TONE, + AC97_PHONE, + AC97_REC_SEL, + AC97_PCM, + AC97_AUX, +}; /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. @@ -240,73 +248,95 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, * register map, thus we add a new (virtual) register to help determine the * audio route within the device. */ -static int mixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - u16 l, r, beep, tone, phone, rec, pcm, aux; - - l = ac97_read(w->codec, HPL_MIXER); - r = ac97_read(w->codec, HPR_MIXER); - beep = ac97_read(w->codec, AC97_PC_BEEP); - tone = ac97_read(w->codec, AC97_MASTER_TONE); - phone = ac97_read(w->codec, AC97_PHONE); - rec = ac97_read(w->codec, AC97_REC_SEL); - pcm = ac97_read(w->codec, AC97_PCM); - aux = ac97_read(w->codec, AC97_AUX); - - if (event & SND_SOC_DAPM_PRE_REG) - return 0; - if ((l & 0x1) || (r & 0x1)) - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff); + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); + unsigned int val = ucontrol->value.enumerated.item[0]; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int mixer, mask, shift, old; + struct snd_soc_dapm_update update; + bool change; + + mixer = mc->shift >> 8; + shift = mc->shift & 0xff; + mask = (1 << shift); + + mutex_lock(&wm9713->lock); + old = wm9713->hp_mixer[mixer]; + if (ucontrol->value.enumerated.item[0]) + wm9713->hp_mixer[mixer] |= mask; else - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000); + wm9713->hp_mixer[mixer] &= ~mask; + + change = old != wm9713->hp_mixer[mixer]; + if (change) { + update.kcontrol = kcontrol; + update.reg = wm9713_mixer_mute_regs[shift]; + update.mask = 0x8000; + if ((wm9713->hp_mixer[0] & mask) || + (wm9713->hp_mixer[1] & mask)) + update.val = 0x0; + else + update.val = 0x8000; + + snd_soc_dapm_mixer_update_power(dapm, kcontrol, val, + &update); + } - if ((l & 0x2) || (r & 0x2)) - ac97_write(w->codec, AC97_MASTER_TONE, tone & 0x7fff); - else - ac97_write(w->codec, AC97_MASTER_TONE, tone | 0x8000); + mutex_unlock(&wm9713->lock); - if ((l & 0x4) || (r & 0x4)) - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff); - else - ac97_write(w->codec, AC97_PHONE, phone | 0x8000); + return change; +} - if ((l & 0x8) || (r & 0x8)) - ac97_write(w->codec, AC97_REC_SEL, rec & 0x7fff); - else - ac97_write(w->codec, AC97_REC_SEL, rec | 0x8000); +static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int mixer, shift; - if ((l & 0x10) || (r & 0x10)) - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff); - else - ac97_write(w->codec, AC97_PCM, pcm | 0x8000); + mixer = mc->shift >> 8; + shift = mc->shift & 0xff; - if ((l & 0x20) || (r & 0x20)) - ac97_write(w->codec, AC97_AUX, aux & 0x7fff); - else - ac97_write(w->codec, AC97_AUX, aux | 0x8000); + ucontrol->value.enumerated.item[0] = + (wm9713->hp_mixer[mixer] >> shift) & 1; return 0; } +#define WM9713_HP_MIXER_CTRL(xname, xmixer, xshift) { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, \ + .get = wm9713_hp_mixer_get, .put = wm9713_hp_mixer_put, \ + .private_value = SOC_DOUBLE_VALUE(SND_SOC_NOPM, \ + xshift, xmixer, 1, 0, 0) \ +} + /* Left Headphone Mixers */ static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { -SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0), -SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPL_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0), +WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPL_MIXER, 5), +WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPL_MIXER, 4), +WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPL_MIXER, 3), +WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPL_MIXER, 2), +WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPL_MIXER, 1), +WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPL_MIXER, 0), }; /* Right Headphone Mixers */ static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = { -SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0), -SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0), -SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0), -SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPR_MIXER, 1, 1, 0), -SOC_DAPM_SINGLE("Bypass Playback Switch", HPR_MIXER, 0, 1, 0), +WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPR_MIXER, 5), +WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPR_MIXER, 4), +WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPR_MIXER, 3), +WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPR_MIXER, 2), +WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPR_MIXER, 1), +WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPR_MIXER, 0), }; /* headphone capture mux */ @@ -428,12 +458,10 @@ SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0, &wm9713_mic_sel_mux_controls), SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0, &wm9713_micb_sel_mux_controls), -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_EXTENDED_MID, 3, 1, - &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_EXTENDED_MID, 2, 1, - &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_EXTENDED_MID, 3, 1, + &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls)), +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_EXTENDED_MID, 2, 1, + &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls)), SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1, &wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)), SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1, @@ -666,8 +694,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { u16 *cache = codec->reg_cache; - if (reg < 0x7c) - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(codec->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9713_reg))) cache[reg] = val; @@ -1251,6 +1278,8 @@ static int wm9713_probe(struct platform_device *pdev) if (wm9713 == NULL) return -ENOMEM; + mutex_init(&wm9713->lock); + platform_set_drvdata(pdev, wm9713); return snd_soc_register_codec(&pdev->dev, -- GitLab From 1f999d14fc7f772fbdd19151ebe5ee081f53dd49 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 8 Nov 2014 17:54:51 +0900 Subject: [PATCH 4006/9457] Documentation: power: Fix typo in Documentation/power This patch fix spelling typos found in Documentation/power. Signed-off-by: Masanari Iida Signed-off-by: Jonathan Corbet --- Documentation/power/runtime_pm.txt | 6 +++--- Documentation/power/suspend-and-interrupts.txt | 2 +- Documentation/power/userland-swsusp.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index f32ce5419573..0e5ea26b255a 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -229,13 +229,13 @@ defined in include/linux/pm.h: - if set, the value of child_count is ignored (but still updated) unsigned int disable_depth; - - used for disabling the helper funcions (they work normally if this is + - used for disabling the helper functions (they work normally if this is equal to zero); the initial value of it is 1 (i.e. runtime PM is initially disabled for all devices) int runtime_error; - if set, there was a fatal error (one of the callbacks returned error code - as described in Section 2), so the helper funtions will not work until + as described in Section 2), so the helper functions will not work until this flag is cleared; this is the error code returned by the failing callback @@ -524,7 +524,7 @@ pm_runtime_put_sync_autosuspend() 5. Runtime PM Initialization, Device Probing and Removal Initially, the runtime PM is disabled for all devices, which means that the -majority of the runtime PM helper funtions described in Section 4 will return +majority of the runtime PM helper functions described in Section 4 will return -EAGAIN until pm_runtime_enable() is called for the device. In addition to that, the initial runtime PM status of all devices is diff --git a/Documentation/power/suspend-and-interrupts.txt b/Documentation/power/suspend-and-interrupts.txt index 69663640dea5..2f9c5a5fcb25 100644 --- a/Documentation/power/suspend-and-interrupts.txt +++ b/Documentation/power/suspend-and-interrupts.txt @@ -77,7 +77,7 @@ Calling enable_irq_wake() causes suspend_device_irqs() to treat the given IRQ in a special way. Namely, the IRQ remains enabled, by on the first interrupt it will be disabled, marked as pending and "suspended" so that it will be re-enabled by resume_device_irqs() during the subsequent system resume. Also -the PM core is notified about the event which casues the system suspend in +the PM core is notified about the event which causes the system suspend in progress to be aborted (that doesn't have to happen immediately, but at one of the points where the suspend thread looks for pending wakeup events). diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt index 0e870825c1b9..bbfcd1bbedc5 100644 --- a/Documentation/power/userland-swsusp.txt +++ b/Documentation/power/userland-swsusp.txt @@ -99,7 +99,7 @@ SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to The device's read() operation can be used to transfer the snapshot image from the kernel. It has the following limitations: - you cannot read() more than one virtual memory page at a time -- read()s across page boundaries are impossible (ie. if ypu read() 1/2 of +- read()s across page boundaries are impossible (ie. if you read() 1/2 of a page in the previous call, you will only be able to read() _at_ _most_ 1/2 of the page in the next call) -- GitLab From b0c42cd7b210efc74aa4bfc3e39a2814dfaa9b89 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 8 Oct 2014 10:24:53 +0200 Subject: [PATCH 4007/9457] Bluetooth: 6lowpan: fix skb_unshare behaviour This patch reverts commit: a7807d73 ("Bluetooth: 6lowpan: Avoid memory leak if memory allocation fails") which was wrong suggested by Alexander Aring. The function skb_unshare run also kfree_skb on failure. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 3.18.x --- net/bluetooth/6lowpan.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index dc23c55f1ab6..3f20dce9d671 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -614,17 +614,13 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) int err = 0; bdaddr_t addr; u8 addr_type; - struct sk_buff *tmpskb; /* We must take a copy of the skb before we modify/replace the ipv6 * header as the header could be used elsewhere */ - tmpskb = skb_unshare(skb, GFP_ATOMIC); - if (!tmpskb) { - kfree_skb(skb); + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) return NET_XMIT_DROP; - } - skb = tmpskb; /* Return values from setup_header() * <0 - error, packet is dropped -- GitLab From c0560b9c523341516eabf0f3b51832256caa7bbb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 6 Nov 2014 12:53:41 -0800 Subject: [PATCH 4008/9457] dccp: Convert DCCP_WARN to net_warn_ratelimited Remove the dependency on the "warning" sysctl (net_msg_warn) which is only used by the LIMIT_NETDEBUG macro. Convert the LIMIT_NETDEBUG use in DCCP_WARN to the more common net_warn_ratelimited mechanism. This still ratelimits based on the net_ratelimit() function, but removes the check for the sysctl. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/dccp/dccp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index c67816647cce..e4c144fa706f 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -22,8 +22,8 @@ /* * DCCP - specific warning and debugging macros. */ -#define DCCP_WARN(fmt, a...) LIMIT_NETDEBUG(KERN_WARNING "%s: " fmt, \ - __func__, ##a) +#define DCCP_WARN(fmt, ...) \ + net_warn_ratelimited("%s: " fmt, __func__, ##__VA_ARGS__) #define DCCP_CRIT(fmt, a...) printk(KERN_CRIT fmt " at %s:%d/%s()\n", ##a, \ __FILE__, __LINE__, __func__) #define DCCP_BUG(a...) do { DCCP_CRIT("BUG: " a); dump_stack(); } while(0) -- GitLab From cc641d5529965fbd01edbdf289951fb95d3de1b8 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Sat, 8 Nov 2014 20:56:35 +0100 Subject: [PATCH 4009/9457] checkkconfigsymbols.py: improve detection of defects This patch improves the detection of defects by updating the regular expression to find Kconfig identifiers in the source code, and fixes some cases of false positives. The following changes are made: - improve regex to find Kconfig identifiers in the source - exclude .log files from analysis - improve filtering of false positives (e.g, CONFIG_XXX) - change output format from (feature:\tlist) to (feature\tlist) Signed-off-by: Valentin Rothberg Signed-off-by: Greg Kroah-Hartman --- scripts/checkkconfigsymbols.py | 57 ++++++++++++++++------------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index f9440891d048..e9cc689033fe 100644 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -1,36 +1,31 @@ #!/usr/bin/env python -"""Find Kconfig identifieres that are referenced but not defined.""" +"""Find Kconfig identifiers that are referenced but not defined.""" -# Copyright (C) 2014 Valentin Rothberg -# Copyright (C) 2014 Stefan Hengelein +# (c) 2014 Valentin Rothberg +# (c) 2014 Stefan Hengelein # -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. -# -# This program is distributed in the hope it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. +# Licensed under the terms of the GNU GPL License version 2 import os import re from subprocess import Popen, PIPE, STDOUT -# REGEX EXPRESSIONS + +# regex expressions OPERATORS = r"&|\(|\)|\||\!" -FEATURE = r"\w*[A-Z]{1}\w*" -CONFIG_DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" +FEATURE = r"(?:\w*[A-Z0-9]\w*){2,}" +DEF = r"^\s*(?:menu){,1}config\s+(" + FEATURE + r")\s*" EXPR = r"(?:" + OPERATORS + r"|\s|" + FEATURE + r")+" STMT = r"^\s*(?:if|select|depends\s+on)\s+" + EXPR +SOURCE_FEATURE = r"(?:\W|\b)+[D]{,1}CONFIG_(" + FEATURE + r")" -# REGEX OBJECTS +# regex objects REGEX_FILE_KCONFIG = re.compile(r".*Kconfig[\.\w+\-]*$") REGEX_FEATURE = re.compile(r"(" + FEATURE + r")") -REGEX_SOURCE_FEATURE = re.compile(r"(?:D|\W|\b)+CONFIG_(" + FEATURE + r")") -REGEX_KCONFIG_DEF = re.compile(CONFIG_DEF) +REGEX_SOURCE_FEATURE = re.compile(SOURCE_FEATURE) +REGEX_KCONFIG_DEF = re.compile(DEF) REGEX_KCONFIG_EXPR = re.compile(EXPR) REGEX_KCONFIG_STMT = re.compile(STMT) REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$") @@ -42,7 +37,7 @@ def main(): source_files = [] kconfig_files = [] defined_features = set() - referenced_features = dict() + referenced_features = dict() # {feature: [files]} # use 'git ls-files' to get the worklist pop = Popen("git ls-files", stdout=PIPE, stderr=STDOUT, shell=True) @@ -52,12 +47,12 @@ def main(): for gitfile in stdout.rsplit("\n"): if ".git" in gitfile or "ChangeLog" in gitfile or \ - os.path.isdir(gitfile): + ".log" in gitfile or os.path.isdir(gitfile): continue if REGEX_FILE_KCONFIG.match(gitfile): kconfig_files.append(gitfile) else: - # All non-Kconfig files are checked for consistency + # all non-Kconfig files are checked for consistency source_files.append(gitfile) for sfile in source_files: @@ -68,15 +63,17 @@ def main(): print "Undefined symbol used\tFile list" for feature in sorted(referenced_features): + # filter some false positives + if feature == "FOO" or feature == "BAR" or \ + feature == "FOO_BAR" or feature == "XXX": + continue if feature not in defined_features: if feature.endswith("_MODULE"): - # Avoid false positives for kernel modules + # avoid false positives for kernel modules if feature[:-len("_MODULE")] in defined_features: continue - if "FOO" in feature or "BAR" in feature: - continue files = referenced_features.get(feature) - print "%s:\t%s" % (feature, ", ".join(files)) + print "%s\t%s" % (feature, ", ".join(files)) def parse_source_file(sfile, referenced_features): @@ -92,9 +89,9 @@ def parse_source_file(sfile, referenced_features): for feature in features: if not REGEX_FILTER_FEATURES.search(feature): continue - paths = referenced_features.get(feature, set()) - paths.add(sfile) - referenced_features[feature] = paths + sfiles = referenced_features.get(feature, set()) + sfiles.add(sfile) + referenced_features[feature] = sfiles def get_features_in_line(line): @@ -113,7 +110,7 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): for i in range(len(lines)): line = lines[i] line = line.strip('\n') - line = line.split("#")[0] # Ignore Kconfig comments + line = line.split("#")[0] # ignore comments if REGEX_KCONFIG_DEF.match(line): feature_def = REGEX_KCONFIG_DEF.findall(line) @@ -122,11 +119,11 @@ def parse_kconfig_file(kfile, defined_features, referenced_features): elif REGEX_KCONFIG_HELP.match(line): skip = True elif skip: - # Ignore content of help messages + # ignore content of help messages pass elif REGEX_KCONFIG_STMT.match(line): features = get_features_in_line(line) - # Multi-line statements + # multi-line statements while line.endswith("\\"): i += 1 line = lines[i] -- GitLab From 6cc79294efefde2593eaf72effebc8b1cc71d5ac Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 8 Nov 2014 16:38:06 +0100 Subject: [PATCH 4010/9457] ASoC: Forward calls to snd_soc_cache_sync() to regcache_sync() For convenience for drivers that do not want to keep their own pointer to regmap struct around forward calls to snd_soc_cache_sync() to regcache_sync() if the driver is using regmap. This is similar to what we do for snd_soc_read()/snd_soc_write(). This patch also fixes drivers which already have been converted to regmap, but still use snd_soc_cache_sync() for trying to the sync the cache. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index a9f82b5aba9d..6dab81799b9a 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -187,6 +187,9 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) const char *name = "flat"; int ret; + if (codec->component.regmap) + return regcache_sync(codec->component.regmap); + if (!codec->cache_sync) return 0; -- GitLab From 427d204c86e095bb91eb8af381bd90a48376a860 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 8 Nov 2014 16:38:07 +0100 Subject: [PATCH 4011/9457] ASoC: Remove snd_soc_cache_sync() implementation This function has no more non regmap user, which means we can remove the implementation of the function and associated functions and structure fields. For convenience we keep a static inline version of the function that forwards calls to regcache_sync() unconditionally. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 19 +++-- include/trace/events/asoc.h | 25 ------ sound/soc/soc-cache.c | 152 ------------------------------------ sound/soc/soc-core.c | 4 - 4 files changed, 12 insertions(+), 188 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..fadcb351f3e1 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -409,13 +409,9 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_component(struct device *dev); -int snd_soc_cache_sync(struct snd_soc_codec *codec); int snd_soc_cache_init(struct snd_soc_codec *codec); int snd_soc_cache_exit(struct snd_soc_codec *codec); -int snd_soc_cache_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value); -int snd_soc_cache_read(struct snd_soc_codec *codec, - unsigned int reg, unsigned int *value); + int snd_soc_platform_read(struct snd_soc_platform *platform, unsigned int reg); int snd_soc_platform_write(struct snd_soc_platform *platform, @@ -791,13 +787,11 @@ struct snd_soc_codec { unsigned int ac97_registered:1; /* Codec has been AC97 registered */ unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int cache_init:1; /* codec cache has been initialized */ - u32 cache_sync; /* Cache needs to be synced to hardware */ /* codec IO */ void *control_data; /* codec control (i2c/3wire) data */ hw_write_t hw_write; void *reg_cache; - struct mutex cache_rw_mutex; /* component */ struct snd_soc_component component; @@ -1264,6 +1258,17 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val); +/** + * snd_soc_cache_sync() - Sync the register cache with the hardware + * @codec: CODEC to sync + * + * Note: This function will call regcache_sync() + */ +static inline int snd_soc_cache_sync(struct snd_soc_codec *codec) +{ + return regcache_sync(codec->component.regmap); +} + /* component IO */ int snd_soc_component_read(struct snd_soc_component *component, unsigned int reg, unsigned int *val); diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index b04ee7e5a466..88cf39d96d0f 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h @@ -288,31 +288,6 @@ TRACE_EVENT(snd_soc_jack_notify, TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) ); -TRACE_EVENT(snd_soc_cache_sync, - - TP_PROTO(struct snd_soc_codec *codec, const char *type, - const char *status), - - TP_ARGS(codec, type, status), - - TP_STRUCT__entry( - __string( name, codec->component.name) - __string( status, status ) - __string( type, type ) - __field( int, id ) - ), - - TP_fast_assign( - __assign_str(name, codec->component.name); - __assign_str(status, status); - __assign_str(type, type); - __entry->id = codec->component.id; - ), - - TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), - (int)__entry->id, __get_str(type), __get_str(status)) -); - #endif /* _TRACE_ASOC_H */ /* This part must be outside protection */ diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 6dab81799b9a..07f43356f963 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -15,56 +15,6 @@ #include #include -#include - -static bool snd_soc_set_cache_val(void *base, unsigned int idx, - unsigned int val, unsigned int word_size) -{ - switch (word_size) { - case 1: { - u8 *cache = base; - if (cache[idx] == val) - return true; - cache[idx] = val; - break; - } - case 2: { - u16 *cache = base; - if (cache[idx] == val) - return true; - cache[idx] = val; - break; - } - default: - WARN(1, "Invalid word_size %d\n", word_size); - break; - } - return false; -} - -static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx, - unsigned int word_size) -{ - if (!base) - return -1; - - switch (word_size) { - case 1: { - const u8 *cache = base; - return cache[idx]; - } - case 2: { - const u16 *cache = base; - return cache[idx]; - } - default: - WARN(1, "Invalid word_size %d\n", word_size); - break; - } - /* unreachable */ - return -1; -} - int snd_soc_cache_init(struct snd_soc_codec *codec) { const struct snd_soc_codec_driver *codec_drv = codec->driver; @@ -75,8 +25,6 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) if (!reg_size) return 0; - mutex_init(&codec->cache_rw_mutex); - dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n", codec->component.name); @@ -103,103 +51,3 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) codec->reg_cache = NULL; return 0; } - -/** - * snd_soc_cache_read: Fetch the value of a given register from the cache. - * - * @codec: CODEC to configure. - * @reg: The register index. - * @value: The value to be returned. - */ -int snd_soc_cache_read(struct snd_soc_codec *codec, - unsigned int reg, unsigned int *value) -{ - if (!value) - return -EINVAL; - - mutex_lock(&codec->cache_rw_mutex); - if (!ZERO_OR_NULL_PTR(codec->reg_cache)) - *value = snd_soc_get_cache_val(codec->reg_cache, reg, - codec->driver->reg_word_size); - mutex_unlock(&codec->cache_rw_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_cache_read); - -/** - * snd_soc_cache_write: Set the value of a given register in the cache. - * - * @codec: CODEC to configure. - * @reg: The register index. - * @value: The new register value. - */ -int snd_soc_cache_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - mutex_lock(&codec->cache_rw_mutex); - if (!ZERO_OR_NULL_PTR(codec->reg_cache)) - snd_soc_set_cache_val(codec->reg_cache, reg, value, - codec->driver->reg_word_size); - mutex_unlock(&codec->cache_rw_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_cache_write); - -static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) -{ - int i; - int ret; - const struct snd_soc_codec_driver *codec_drv; - unsigned int val; - - codec_drv = codec->driver; - for (i = 0; i < codec_drv->reg_cache_size; ++i) { - ret = snd_soc_cache_read(codec, i, &val); - if (ret) - return ret; - if (codec_drv->reg_cache_default) - if (snd_soc_get_cache_val(codec_drv->reg_cache_default, - i, codec_drv->reg_word_size) == val) - continue; - - ret = snd_soc_write(codec, i, val); - if (ret) - return ret; - dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n", - i, val); - } - return 0; -} - -/** - * snd_soc_cache_sync: Sync the register cache with the hardware. - * - * @codec: CODEC to configure. - * - * Any registers that should not be synced should be marked as - * volatile. In general drivers can choose not to use the provided - * syncing functionality if they so require. - */ -int snd_soc_cache_sync(struct snd_soc_codec *codec) -{ - const char *name = "flat"; - int ret; - - if (codec->component.regmap) - return regcache_sync(codec->component.regmap); - - if (!codec->cache_sync) - return 0; - - dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n", - codec->component.name); - trace_snd_soc_cache_sync(codec, name, "start"); - ret = snd_soc_flat_cache_sync(codec); - if (!ret) - codec->cache_sync = 0; - trace_snd_soc_cache_sync(codec, name, "end"); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_cache_sync); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..4e0e32bb9910 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -309,9 +309,6 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root, - &codec->cache_sync); - codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, codec->component.debugfs_root, codec, &codec_reg_fops); @@ -656,7 +653,6 @@ int snd_soc_suspend(struct device *dev) if (codec->driver->suspend) codec->driver->suspend(codec); codec->suspended = 1; - codec->cache_sync = 1; if (codec->component.regmap) regcache_mark_dirty(codec->component.regmap); /* deactivate pins to sleep state */ -- GitLab From fbace43e8817113475ebda00e28593baa436a131 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sat, 8 Nov 2014 14:40:17 +0100 Subject: [PATCH 4012/9457] ASoC: tfa9879: New driver for NXP Semiconductors TFA9879 amplifier. Signed-off-by: Peter Rosin Signed-off-by: Mark Brown --- MAINTAINERS | 6 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tfa9879.c | 328 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/tfa9879.h | 202 +++++++++++++++++++++++ 5 files changed, 543 insertions(+) create mode 100644 sound/soc/codecs/tfa9879.c create mode 100644 sound/soc/codecs/tfa9879.h diff --git a/MAINTAINERS b/MAINTAINERS index a20df9bf8ab0..28a33296a468 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6565,6 +6565,12 @@ S: Supported F: drivers/gpu/drm/i2c/tda998x_drv.c F: include/drm/i2c/tda998x.h +NXP TFA9879 DRIVER +M: Peter Rosin +L: alsa-devel@alsa-project.org (moderated for non-subscribers) +S: Maintained +F: sound/soc/codecs/tfa9879* + OMAP SUPPORT M: Tony Lindgren L: linux-omap@vger.kernel.org diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..99b34a97499f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -101,6 +101,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TAS2552 if I2C select SND_SOC_TAS5086 if I2C + select SND_SOC_TFA9879 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER select SND_SOC_TLV320AIC26 if SPI_MASTER @@ -577,6 +578,10 @@ config SND_SOC_TAS5086 tristate "Texas Instruments TAS5086 speaker amplifier" depends on I2C +config SND_SOC_TFA9879 + tristate "NXP Semiconductors TFA9879 amplifier" + depends on I2C + config SND_SOC_TLV320AIC23 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 5dce451661e4..ccfa2ab158be 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -101,6 +101,7 @@ snd-soc-sta350-objs := sta350.o snd-soc-sta529-objs := sta529.o snd-soc-stac9766-objs := stac9766.o snd-soc-tas5086-objs := tas5086.o +snd-soc-tfa9879-objs := tfa9879.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o @@ -274,6 +275,7 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o +obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c new file mode 100644 index 000000000000..16f1b71edb55 --- /dev/null +++ b/sound/soc/codecs/tfa9879.c @@ -0,0 +1,328 @@ +/* + * tfa9879.c -- driver for NXP Semiconductors TFA9879 + * + * Copyright (C) 2014 Axentia Technologies AB + * Author: Peter Rosin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tfa9879.h" + +struct tfa9879_priv { + struct regmap *regmap; + int lsb_justified; +}; + +static int tfa9879_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec); + int fs; + int i2s_set = 0; + + switch (params_rate(params)) { + case 8000: + fs = TFA9879_I2S_FS_8000; + break; + case 11025: + fs = TFA9879_I2S_FS_11025; + break; + case 12000: + fs = TFA9879_I2S_FS_12000; + break; + case 16000: + fs = TFA9879_I2S_FS_16000; + break; + case 22050: + fs = TFA9879_I2S_FS_22050; + break; + case 24000: + fs = TFA9879_I2S_FS_24000; + break; + case 32000: + fs = TFA9879_I2S_FS_32000; + break; + case 44100: + fs = TFA9879_I2S_FS_44100; + break; + case 48000: + fs = TFA9879_I2S_FS_48000; + break; + case 64000: + fs = TFA9879_I2S_FS_64000; + break; + case 88200: + fs = TFA9879_I2S_FS_88200; + break; + case 96000: + fs = TFA9879_I2S_FS_96000; + break; + default: + return -EINVAL; + } + + switch (params_width(params)) { + case 16: + i2s_set = TFA9879_I2S_SET_LSB_J_16; + break; + case 24: + i2s_set = TFA9879_I2S_SET_LSB_J_24; + break; + default: + return -EINVAL; + } + + if (tfa9879->lsb_justified) + snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1, + TFA9879_I2S_SET_MASK, + i2s_set << TFA9879_I2S_SET_SHIFT); + + snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1, + TFA9879_I2S_FS_MASK, + fs << TFA9879_I2S_FS_SHIFT); + return 0; +} + +static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + + snd_soc_update_bits(codec, TFA9879_MISC_CONTROL, + TFA9879_S_MUTE_MASK, + !!mute << TFA9879_S_MUTE_SHIFT); + + return 0; +} + +static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec); + int i2s_set; + int sck_pol; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + sck_pol = TFA9879_SCK_POL_NORMAL; + break; + case SND_SOC_DAIFMT_IB_NF: + sck_pol = TFA9879_SCK_POL_INVERSE; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + tfa9879->lsb_justified = 0; + i2s_set = TFA9879_I2S_SET_I2S_24; + break; + case SND_SOC_DAIFMT_LEFT_J: + tfa9879->lsb_justified = 0; + i2s_set = TFA9879_I2S_SET_MSB_J_24; + break; + case SND_SOC_DAIFMT_RIGHT_J: + tfa9879->lsb_justified = 1; + i2s_set = TFA9879_I2S_SET_LSB_J_24; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1, + TFA9879_SCK_POL_MASK, + sck_pol << TFA9879_SCK_POL_SHIFT); + snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1, + TFA9879_I2S_SET_MASK, + i2s_set << TFA9879_I2S_SET_SHIFT); + return 0; +} + +static struct reg_default tfa9879_regs[] = { + { TFA9879_DEVICE_CONTROL, 0x0000 }, /* 0x00 */ + { TFA9879_SERIAL_INTERFACE_1, 0x0a18 }, /* 0x01 */ + { TFA9879_PCM_IOM2_FORMAT_1, 0x0007 }, /* 0x02 */ + { TFA9879_SERIAL_INTERFACE_2, 0x0a18 }, /* 0x03 */ + { TFA9879_PCM_IOM2_FORMAT_2, 0x0007 }, /* 0x04 */ + { TFA9879_EQUALIZER_A1, 0x59dd }, /* 0x05 */ + { TFA9879_EQUALIZER_A2, 0xc63e }, /* 0x06 */ + { TFA9879_EQUALIZER_B1, 0x651a }, /* 0x07 */ + { TFA9879_EQUALIZER_B2, 0xe53e }, /* 0x08 */ + { TFA9879_EQUALIZER_C1, 0x4616 }, /* 0x09 */ + { TFA9879_EQUALIZER_C2, 0xd33e }, /* 0x0a */ + { TFA9879_EQUALIZER_D1, 0x4df3 }, /* 0x0b */ + { TFA9879_EQUALIZER_D2, 0xea3e }, /* 0x0c */ + { TFA9879_EQUALIZER_E1, 0x5ee0 }, /* 0x0d */ + { TFA9879_EQUALIZER_E2, 0xf93e }, /* 0x0e */ + { TFA9879_BYPASS_CONTROL, 0x0093 }, /* 0x0f */ + { TFA9879_DYNAMIC_RANGE_COMPR, 0x92ba }, /* 0x10 */ + { TFA9879_BASS_TREBLE, 0x12a5 }, /* 0x11 */ + { TFA9879_HIGH_PASS_FILTER, 0x0004 }, /* 0x12 */ + { TFA9879_VOLUME_CONTROL, 0x10bd }, /* 0x13 */ + { TFA9879_MISC_CONTROL, 0x0000 }, /* 0x14 */ +}; + +static bool tfa9879_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == TFA9879_MISC_STATUS; +} + +static const DECLARE_TLV_DB_SCALE(volume_tlv, -7050, 50, 1); +static const DECLARE_TLV_DB_SCALE(tb_gain_tlv, -1800, 200, 0); +static const char * const tb_freq_text[] = { + "Low", "Mid", "High" +}; +static const struct soc_enum treble_freq_enum = + SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_TRBLE_SHIFT, + ARRAY_SIZE(tb_freq_text), tb_freq_text); +static const struct soc_enum bass_freq_enum = + SOC_ENUM_SINGLE(TFA9879_BASS_TREBLE, TFA9879_F_BASS_SHIFT, + ARRAY_SIZE(tb_freq_text), tb_freq_text); + +static const struct snd_kcontrol_new tfa9879_controls[] = { + SOC_SINGLE_TLV("PCM Playback Volume", TFA9879_VOLUME_CONTROL, + TFA9879_VOL_SHIFT, 0xbd, 1, volume_tlv), + SOC_SINGLE_TLV("Treble Volume", TFA9879_BASS_TREBLE, + TFA9879_G_TRBLE_SHIFT, 18, 0, tb_gain_tlv), + SOC_SINGLE_TLV("Bass Volume", TFA9879_BASS_TREBLE, + TFA9879_G_BASS_SHIFT, 18, 0, tb_gain_tlv), + SOC_ENUM("Treble Corner Freq", treble_freq_enum), + SOC_ENUM("Bass Corner Freq", bass_freq_enum), +}; + +static const struct snd_soc_dapm_widget tfa9879_dapm_widgets[] = { +SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_DAC("DAC", NULL, TFA9879_DEVICE_CONTROL, TFA9879_OPMODE_SHIFT, 0), +SND_SOC_DAPM_OUTPUT("LINEOUT"), +SND_SOC_DAPM_SUPPLY("POWER", TFA9879_DEVICE_CONTROL, TFA9879_POWERUP_SHIFT, 0, + NULL, 0), +}; + +static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = { + { "DAC", NULL, "AIFINL" }, + { "DAC", NULL, "AIFINR" }, + + { "LINEOUT", NULL, "DAC" }, + + { "DAC", NULL, "POWER" }, +}; + +static const struct snd_soc_codec_driver tfa9879_codec = { + .controls = tfa9879_controls, + .num_controls = ARRAY_SIZE(tfa9879_controls), + + .dapm_widgets = tfa9879_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), + .dapm_routes = tfa9879_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), +}; + +static const struct regmap_config tfa9879_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .volatile_reg = tfa9879_volatile_reg, + .max_register = TFA9879_MISC_STATUS, + .reg_defaults = tfa9879_regs, + .num_reg_defaults = ARRAY_SIZE(tfa9879_regs), + .cache_type = REGCACHE_RBTREE, +}; + +static const struct snd_soc_dai_ops tfa9879_dai_ops = { + .hw_params = tfa9879_hw_params, + .digital_mute = tfa9879_digital_mute, + .set_fmt = tfa9879_set_fmt, +}; + +#define TFA9879_RATES SNDRV_PCM_RATE_8000_96000 + +#define TFA9879_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_driver tfa9879_dai = { + .name = "tfa9879-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = TFA9879_RATES, + .formats = TFA9879_FORMATS, }, + .ops = &tfa9879_dai_ops, +}; + +static int tfa9879_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tfa9879_priv *tfa9879; + int i; + + tfa9879 = devm_kzalloc(&i2c->dev, sizeof(*tfa9879), GFP_KERNEL); + if (IS_ERR(tfa9879)) + return PTR_ERR(tfa9879); + + i2c_set_clientdata(i2c, tfa9879); + + tfa9879->regmap = devm_regmap_init_i2c(i2c, &tfa9879_regmap); + if (IS_ERR(tfa9879->regmap)) + return PTR_ERR(tfa9879->regmap); + + /* Ensure the device is in reset state */ + for (i = 0; i < ARRAY_SIZE(tfa9879_regs); i++) + regmap_write(tfa9879->regmap, + tfa9879_regs[i].reg, tfa9879_regs[i].def); + + return snd_soc_register_codec(&i2c->dev, &tfa9879_codec, + &tfa9879_dai, 1); +} + +static int tfa9879_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + + return 0; +} + +static const struct i2c_device_id tfa9879_i2c_id[] = { + { "tfa9879", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tfa9879_i2c_id); + +static struct i2c_driver tfa9879_i2c_driver = { + .driver = { + .name = "tfa9879", + .owner = THIS_MODULE, + }, + .probe = tfa9879_i2c_probe, + .remove = tfa9879_i2c_remove, + .id_table = tfa9879_i2c_id, +}; + +module_i2c_driver(tfa9879_i2c_driver); + +MODULE_DESCRIPTION("ASoC NXP Semiconductors TFA9879 driver"); +MODULE_AUTHOR("Peter Rosin "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tfa9879.h b/sound/soc/codecs/tfa9879.h new file mode 100644 index 000000000000..3408c90c4628 --- /dev/null +++ b/sound/soc/codecs/tfa9879.h @@ -0,0 +1,202 @@ +/* + * tfa9879.h -- driver for NXP Semiconductors TFA9879 + * + * Copyright (C) 2014 Axentia Technologies AB + * Author: Peter Rosin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef _TFA9879_H +#define _TFA9879_H + +#define TFA9879_DEVICE_CONTROL 0x00 +#define TFA9879_SERIAL_INTERFACE_1 0x01 +#define TFA9879_PCM_IOM2_FORMAT_1 0x02 +#define TFA9879_SERIAL_INTERFACE_2 0x03 +#define TFA9879_PCM_IOM2_FORMAT_2 0x04 +#define TFA9879_EQUALIZER_A1 0x05 +#define TFA9879_EQUALIZER_A2 0x06 +#define TFA9879_EQUALIZER_B1 0x07 +#define TFA9879_EQUALIZER_B2 0x08 +#define TFA9879_EQUALIZER_C1 0x09 +#define TFA9879_EQUALIZER_C2 0x0a +#define TFA9879_EQUALIZER_D1 0x0b +#define TFA9879_EQUALIZER_D2 0x0c +#define TFA9879_EQUALIZER_E1 0x0d +#define TFA9879_EQUALIZER_E2 0x0e +#define TFA9879_BYPASS_CONTROL 0x0f +#define TFA9879_DYNAMIC_RANGE_COMPR 0x10 +#define TFA9879_BASS_TREBLE 0x11 +#define TFA9879_HIGH_PASS_FILTER 0x12 +#define TFA9879_VOLUME_CONTROL 0x13 +#define TFA9879_MISC_CONTROL 0x14 +#define TFA9879_MISC_STATUS 0x15 + +/* TFA9879_DEVICE_CONTROL */ +#define TFA9879_INPUT_SEL_MASK 0x0010 +#define TFA9879_INPUT_SEL_SHIFT 4 +#define TFA9879_OPMODE_MASK 0x0008 +#define TFA9879_OPMODE_SHIFT 3 +#define TFA9879_RESET_MASK 0x0002 +#define TFA9879_RESET_SHIFT 1 +#define TFA9879_POWERUP_MASK 0x0001 +#define TFA9879_POWERUP_SHIFT 0 + +/* TFA9879_SERIAL_INTERFACE */ +#define TFA9879_MONO_SEL_MASK 0x0c00 +#define TFA9879_MONO_SEL_SHIFT 10 +#define TFA9879_MONO_SEL_LEFT 0 +#define TFA9879_MONO_SEL_RIGHT 1 +#define TFA9879_MONO_SEL_BOTH 2 +#define TFA9879_I2S_FS_MASK 0x03c0 +#define TFA9879_I2S_FS_SHIFT 6 +#define TFA9879_I2S_FS_8000 0 +#define TFA9879_I2S_FS_11025 1 +#define TFA9879_I2S_FS_12000 2 +#define TFA9879_I2S_FS_16000 3 +#define TFA9879_I2S_FS_22050 4 +#define TFA9879_I2S_FS_24000 5 +#define TFA9879_I2S_FS_32000 6 +#define TFA9879_I2S_FS_44100 7 +#define TFA9879_I2S_FS_48000 8 +#define TFA9879_I2S_FS_64000 9 +#define TFA9879_I2S_FS_88200 10 +#define TFA9879_I2S_FS_96000 11 +#define TFA9879_I2S_SET_MASK 0x0038 +#define TFA9879_I2S_SET_SHIFT 3 +#define TFA9879_I2S_SET_MSB_J_24 2 +#define TFA9879_I2S_SET_I2S_24 3 +#define TFA9879_I2S_SET_LSB_J_16 4 +#define TFA9879_I2S_SET_LSB_J_18 5 +#define TFA9879_I2S_SET_LSB_J_20 6 +#define TFA9879_I2S_SET_LSB_J_24 7 +#define TFA9879_SCK_POL_MASK 0x0004 +#define TFA9879_SCK_POL_SHIFT 2 +#define TFA9879_SCK_POL_NORMAL 0 +#define TFA9879_SCK_POL_INVERSE 1 +#define TFA9879_I_MODE_MASK 0x0003 +#define TFA9879_I_MODE_SHIFT 0 +#define TFA9879_I_MODE_I2S 0 +#define TFA9879_I_MODE_PCM_IOM2_SHORT 1 +#define TFA9879_I_MODE_PCM_IOM2_LONG 2 + +/* TFA9879_PCM_IOM2_FORMAT */ +#define TFA9879_PCM_FS_MASK 0x0800 +#define TFA9879_PCM_FS_SHIFT 11 +#define TFA9879_A_LAW_MASK 0x0400 +#define TFA9879_A_LAW_SHIFT 10 +#define TFA9879_PCM_COMP_MASK 0x0200 +#define TFA9879_PCM_COMP_SHIFT 9 +#define TFA9879_PCM_DL_MASK 0x0100 +#define TFA9879_PCM_DL_SHIFT 8 +#define TFA9879_D1_SLOT_MASK 0x00f0 +#define TFA9879_D1_SLOT_SHIFT 4 +#define TFA9879_D2_SLOT_MASK 0x000f +#define TFA9879_D2_SLOT_SHIFT 0 + +/* TFA9879_EQUALIZER_X1 */ +#define TFA9879_T1_MASK 0x8000 +#define TFA9879_T1_SHIFT 15 +#define TFA9879_K1M_MASK 0x7ff0 +#define TFA9879_K1M_SHIFT 4 +#define TFA9879_K1E_MASK 0x000f +#define TFA9879_K1E_SHIFT 0 + +/* TFA9879_EQUALIZER_X2 */ +#define TFA9879_T2_MASK 0x8000 +#define TFA9879_T2_SHIFT 15 +#define TFA9879_K2M_MASK 0x7800 +#define TFA9879_K2M_SHIFT 11 +#define TFA9879_K2E_MASK 0x0700 +#define TFA9879_K2E_SHIFT 8 +#define TFA9879_K0_MASK 0x00fe +#define TFA9879_K0_SHIFT 1 +#define TFA9879_S_MASK 0x0001 +#define TFA9879_S_SHIFT 0 + +/* TFA9879_BYPASS_CONTROL */ +#define TFA9879_L_OCP_MASK 0x00c0 +#define TFA9879_L_OCP_SHIFT 6 +#define TFA9879_L_OTP_MASK 0x0030 +#define TFA9879_L_OTP_SHIFT 4 +#define TFA9879_CLIPCTRL_MASK 0x0008 +#define TFA9879_CLIPCTRL_SHIFT 3 +#define TFA9879_HPF_BP_MASK 0x0004 +#define TFA9879_HPF_BP_SHIFT 2 +#define TFA9879_DRC_BP_MASK 0x0002 +#define TFA9879_DRC_BP_SHIFT 1 +#define TFA9879_EQ_BP_MASK 0x0001 +#define TFA9879_EQ_BP_SHIFT 0 + +/* TFA9879_DYNAMIC_RANGE_COMPR */ +#define TFA9879_AT_LVL_MASK 0xf000 +#define TFA9879_AT_LVL_SHIFT 12 +#define TFA9879_AT_RATE_MASK 0x0f00 +#define TFA9879_AT_RATE_SHIFT 8 +#define TFA9879_RL_LVL_MASK 0x00f0 +#define TFA9879_RL_LVL_SHIFT 4 +#define TFA9879_RL_RATE_MASK 0x000f +#define TFA9879_RL_RATE_SHIFT 0 + +/* TFA9879_BASS_TREBLE */ +#define TFA9879_G_TRBLE_MASK 0x3e00 +#define TFA9879_G_TRBLE_SHIFT 9 +#define TFA9879_F_TRBLE_MASK 0x0180 +#define TFA9879_F_TRBLE_SHIFT 7 +#define TFA9879_G_BASS_MASK 0x007c +#define TFA9879_G_BASS_SHIFT 2 +#define TFA9879_F_BASS_MASK 0x0003 +#define TFA9879_F_BASS_SHIFT 0 + +/* TFA9879_HIGH_PASS_FILTER */ +#define TFA9879_HP_CTRL_MASK 0x00ff +#define TFA9879_HP_CTRL_SHIFT 0 + +/* TFA9879_VOLUME_CONTROL */ +#define TFA9879_ZR_CRSS_MASK 0x1000 +#define TFA9879_ZR_CRSS_SHIFT 12 +#define TFA9879_VOL_MASK 0x00ff +#define TFA9879_VOL_SHIFT 0 + +/* TFA9879_MISC_CONTROL */ +#define TFA9879_DE_PHAS_MASK 0x0c00 +#define TFA9879_DE_PHAS_SHIFT 10 +#define TFA9879_H_MUTE_MASK 0x0200 +#define TFA9879_H_MUTE_SHIFT 9 +#define TFA9879_S_MUTE_MASK 0x0100 +#define TFA9879_S_MUTE_SHIFT 8 +#define TFA9879_P_LIM_MASK 0x00ff +#define TFA9879_P_LIM_SHIFT 0 + +/* TFA9879_MISC_STATUS */ +#define TFA9879_PS_MASK 0x4000 +#define TFA9879_PS_SHIFT 14 +#define TFA9879_PORA_MASK 0x2000 +#define TFA9879_PORA_SHIFT 13 +#define TFA9879_AMP_MASK 0x0600 +#define TFA9879_AMP_SHIFT 9 +#define TFA9879_IBP_2_MASK 0x0100 +#define TFA9879_IBP_2_SHIFT 8 +#define TFA9879_OFP_2_MASK 0x0080 +#define TFA9879_OFP_2_SHIFT 7 +#define TFA9879_UFP_2_MASK 0x0040 +#define TFA9879_UFP_2_SHIFT 6 +#define TFA9879_IBP_1_MASK 0x0020 +#define TFA9879_IBP_1_SHIFT 5 +#define TFA9879_OFP_1_MASK 0x0010 +#define TFA9879_OFP_1_SHIFT 4 +#define TFA9879_UFP_1_MASK 0x0008 +#define TFA9879_UFP_1_SHIFT 3 +#define TFA9879_OCPOKA_MASK 0x0004 +#define TFA9879_OCPOKA_SHIFT 2 +#define TFA9879_OCPOKB_MASK 0x0002 +#define TFA9879_OCPOKB_SHIFT 1 +#define TFA9879_OTPOK_MASK 0x0001 +#define TFA9879_OTPOK_SHIFT 0 + +#endif -- GitLab From 87993273feb7f9379ec79cd9c25d195c4b93b7da Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 23 Sep 2014 21:05:37 +0200 Subject: [PATCH 4013/9457] pinctrl: samsung: Make samsung_pinctrl_get_soc_data use ERR_PTR() Currently the function returns a valid pointer on success and NULL on error, so exact error code is lost. This patch changes return convention of the function to use ERR_PTR() on error instead. Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-samsung.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 2d37c8f49f3c..8ac750329f58 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -981,7 +981,7 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( id = of_alias_get_id(node, "pinctrl"); if (id < 0) { dev_err(&pdev->dev, "failed to get alias id\n"); - return NULL; + return ERR_PTR(-ENOENT); } match = of_match_node(samsung_pinctrl_dt_match, node); ctrl = (struct samsung_pin_ctrl *)match->data + id; @@ -1033,9 +1033,9 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) } ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev); - if (!ctrl) { + if (IS_ERR(ctrl)) { dev_err(&pdev->dev, "driver data not available\n"); - return -EINVAL; + return PTR_ERR(ctrl); } drvdata->ctrl = ctrl; drvdata->dev = dev; -- GitLab From e06deff967d29beffceeaffc4cdc90aacbd34898 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 23 Sep 2014 21:05:38 +0200 Subject: [PATCH 4014/9457] pinctrl: samsung: Drop unused label field in samsung_pin_ctrl struct There is no code using it and in fact there are pin controller variants that do not even have this field initialized in their init data. This patch removes it completely. Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 22 ---------------------- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 4 ---- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 1 - drivers/pinctrl/samsung/pinctrl-samsung.h | 3 --- 4 files changed, 30 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d7154ed0b0eb..7e6463f970ff 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -682,7 +682,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "s5pv210-gpio-ctrl0", }, }; @@ -729,7 +728,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos3250-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos3250_pin_banks1, @@ -738,7 +736,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos3250-gpio-ctrl1", }, }; @@ -803,7 +800,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4210-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos4210_pin_banks1, @@ -812,12 +808,10 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4210-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos4210_pin_banks2, .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2), - .label = "exynos4210-gpio-ctrl2", }, }; @@ -891,7 +885,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4x12-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos4x12_pin_banks1, @@ -900,7 +893,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4x12-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos4x12_pin_banks2, @@ -908,7 +900,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4x12-gpio-ctrl2", }, { /* pin-controller instance 3 data */ .pin_banks = exynos4x12_pin_banks3, @@ -916,7 +907,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos4x12-gpio-ctrl3", }, }; @@ -989,7 +979,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos5250-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos5250_pin_banks1, @@ -997,7 +986,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos5250-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos5250_pin_banks2, @@ -1005,7 +993,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos5250-gpio-ctrl2", }, { /* pin-controller instance 3 data */ .pin_banks = exynos5250_pin_banks3, @@ -1013,7 +1000,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, - .label = "exynos5250-gpio-ctrl3", }, }; @@ -1068,19 +1054,16 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { .nr_banks = ARRAY_SIZE(exynos5260_pin_banks0), .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, - .label = "exynos5260-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos5260_pin_banks1, .nr_banks = ARRAY_SIZE(exynos5260_pin_banks1), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5260-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos5260_pin_banks2, .nr_banks = ARRAY_SIZE(exynos5260_pin_banks2), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5260-gpio-ctrl2", }, }; @@ -1151,30 +1134,25 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { .nr_banks = ARRAY_SIZE(exynos5420_pin_banks0), .eint_gpio_init = exynos_eint_gpio_init, .eint_wkup_init = exynos_eint_wkup_init, - .label = "exynos5420-gpio-ctrl0", }, { /* pin-controller instance 1 data */ .pin_banks = exynos5420_pin_banks1, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks1), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5420-gpio-ctrl1", }, { /* pin-controller instance 2 data */ .pin_banks = exynos5420_pin_banks2, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks2), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5420-gpio-ctrl2", }, { /* pin-controller instance 3 data */ .pin_banks = exynos5420_pin_banks3, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks3), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5420-gpio-ctrl3", }, { /* pin-controller instance 4 data */ .pin_banks = exynos5420_pin_banks4, .nr_banks = ARRAY_SIZE(exynos5420_pin_banks4), .eint_gpio_init = exynos_eint_gpio_init, - .label = "exynos5420-gpio-ctrl4", }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index ad3eaad17001..e38925906bd3 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -578,7 +578,6 @@ struct samsung_pin_ctrl s3c2412_pin_ctrl[] = { .pin_banks = s3c2412_pin_banks, .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), .eint_wkup_init = s3c24xx_eint_init, - .label = "S3C2412-GPIO", }, }; @@ -601,7 +600,6 @@ struct samsung_pin_ctrl s3c2416_pin_ctrl[] = { .pin_banks = s3c2416_pin_banks, .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), .eint_wkup_init = s3c24xx_eint_init, - .label = "S3C2416-GPIO", }, }; @@ -622,7 +620,6 @@ struct samsung_pin_ctrl s3c2440_pin_ctrl[] = { .pin_banks = s3c2440_pin_banks, .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), .eint_wkup_init = s3c24xx_eint_init, - .label = "S3C2440-GPIO", }, }; @@ -646,6 +643,5 @@ struct samsung_pin_ctrl s3c2450_pin_ctrl[] = { .pin_banks = s3c2450_pin_banks, .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), .eint_wkup_init = s3c24xx_eint_init, - .label = "S3C2450-GPIO", }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 89143c903000..fcf8c36e727e 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -811,6 +811,5 @@ struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = { .nr_banks = ARRAY_SIZE(s3c64xx_pin_banks0), .eint_gpio_init = s3c64xx_eint_gpio_init, .eint_wkup_init = s3c64xx_eint_eint0_init, - .label = "S3C64xx-GPIO", }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 5cedc9d26390..da527b390513 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -161,7 +161,6 @@ struct samsung_pin_bank { * interrupts for the controller. * @eint_wkup_init: platform specific callback to setup the external wakeup * interrupts for the controller. - * @label: for debug information. */ struct samsung_pin_ctrl { struct samsung_pin_bank *pin_banks; @@ -174,8 +173,6 @@ struct samsung_pin_ctrl { int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); void (*suspend)(struct samsung_pinctrl_drv_data *); void (*resume)(struct samsung_pinctrl_drv_data *); - - char *label; }; /** -- GitLab From 94ce944bed8a849a9b83b4e66f0e6e4abc16c457 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 23 Sep 2014 21:05:39 +0200 Subject: [PATCH 4015/9457] pinctrl: samsung: Constify samsung_pin_bank_type struct This structure is not intended to be modified at runtime and functions as constant data shared between multiple pin banks. This patch makes all instances of it constant across the driver. Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 8 ++++---- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 6 +++--- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 14 +++++++------- drivers/pinctrl/samsung/pinctrl-samsung.c | 20 +++++++++----------- drivers/pinctrl/samsung/pinctrl-samsung.h | 2 +- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 7e6463f970ff..0202e0016233 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -46,12 +46,12 @@ static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip) return container_of(chip, struct exynos_irq_chip, chip); } -static struct samsung_pin_bank_type bank_type_off = { +static const struct samsung_pin_bank_type bank_type_off = { .fld_width = { 4, 1, 2, 2, 2, 2, }, .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, }, }; -static struct samsung_pin_bank_type bank_type_alive = { +static const struct samsung_pin_bank_type bank_type_alive = { .fld_width = { 4, 1, 2, 2, }, .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, }; @@ -171,7 +171,7 @@ static int exynos_irq_request_resources(struct irq_data *irqd) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank_type *bank_type = bank->type; + const struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned long reg_con = our_chip->eint_con + bank->eint_offset; @@ -210,7 +210,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pin_bank_type *bank_type = bank->type; + const struct samsung_pin_bank_type *bank_type = bank->type; struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned long reg_con = our_chip->eint_con + bank->eint_offset; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index e38925906bd3..9db6cf5c8823 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -44,12 +44,12 @@ #define EINT_EDGE_BOTH 6 #define EINT_MASK 0xf -static struct samsung_pin_bank_type bank_type_1bit = { +static const struct samsung_pin_bank_type bank_type_1bit = { .fld_width = { 1, 1, }, .reg_offset = { 0x00, 0x04, }, }; -static struct samsung_pin_bank_type bank_type_2bit = { +static const struct samsung_pin_bank_type bank_type_2bit = { .fld_width = { 2, 1, 2, }, .reg_offset = { 0x00, 0x04, 0x08, }, }; @@ -143,7 +143,7 @@ static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type) static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, struct samsung_pin_bank *bank, int pin) { - struct samsung_pin_bank_type *bank_type = bank->type; + const struct samsung_pin_bank_type *bank_type = bank->type; unsigned long flags; void __iomem *reg; u8 shift; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index fcf8c36e727e..2a14db2826d8 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -68,32 +68,32 @@ #define EINT_CON_MASK 0xF #define EINT_CON_LEN 4 -static struct samsung_pin_bank_type bank_type_4bit_off = { +static const struct samsung_pin_bank_type bank_type_4bit_off = { .fld_width = { 4, 1, 2, 0, 2, 2, }, .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, }; -static struct samsung_pin_bank_type bank_type_4bit_alive = { +static const struct samsung_pin_bank_type bank_type_4bit_alive = { .fld_width = { 4, 1, 2, }, .reg_offset = { 0x00, 0x04, 0x08, }, }; -static struct samsung_pin_bank_type bank_type_4bit2_off = { +static const struct samsung_pin_bank_type bank_type_4bit2_off = { .fld_width = { 4, 1, 2, 0, 2, 2, }, .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, }, }; -static struct samsung_pin_bank_type bank_type_4bit2_alive = { +static const struct samsung_pin_bank_type bank_type_4bit2_alive = { .fld_width = { 4, 1, 2, }, .reg_offset = { 0x00, 0x08, 0x0c, }, }; -static struct samsung_pin_bank_type bank_type_2bit_off = { +static const struct samsung_pin_bank_type bank_type_2bit_off = { .fld_width = { 2, 1, 2, 0, 2, 2, }, .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, }, }; -static struct samsung_pin_bank_type bank_type_2bit_alive = { +static const struct samsung_pin_bank_type bank_type_2bit_alive = { .fld_width = { 2, 1, 2, }, .reg_offset = { 0x00, 0x04, 0x08, }, }; @@ -272,7 +272,7 @@ static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type) static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, struct samsung_pin_bank *bank, int pin) { - struct samsung_pin_bank_type *bank_type = bank->type; + const struct samsung_pin_bank_type *bank_type = bank->type; unsigned long flags; void __iomem *reg; u8 shift; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 8ac750329f58..63a97f1d8a21 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -366,7 +366,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, unsigned group, bool enable) { struct samsung_pinctrl_drv_data *drvdata; - struct samsung_pin_bank_type *type; + const struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; void __iomem *reg; u32 mask, shift, data, pin_offset; @@ -422,7 +422,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config, bool set) { struct samsung_pinctrl_drv_data *drvdata; - struct samsung_pin_bank_type *type; + const struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; void __iomem *reg_base; enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); @@ -528,7 +528,7 @@ static const struct pinconf_ops samsung_pinconf_ops = { static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gc_to_pin_bank(gc); - struct samsung_pin_bank_type *type = bank->type; + const struct samsung_pin_bank_type *type = bank->type; unsigned long flags; void __iomem *reg; u32 data; @@ -552,7 +552,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) void __iomem *reg; u32 data; struct samsung_pin_bank *bank = gc_to_pin_bank(gc); - struct samsung_pin_bank_type *type = bank->type; + const struct samsung_pin_bank_type *type = bank->type; reg = bank->drvdata->virt_base + bank->pctl_offset; @@ -569,7 +569,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) static int samsung_gpio_set_direction(struct gpio_chip *gc, unsigned offset, bool input) { - struct samsung_pin_bank_type *type; + const struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; struct samsung_pinctrl_drv_data *drvdata; void __iomem *reg; @@ -1089,9 +1089,8 @@ static void samsung_pinctrl_suspend_dev( for (i = 0; i < ctrl->nr_banks; i++) { struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; void __iomem *reg = virt_base + bank->pctl_offset; - - u8 *offs = bank->type->reg_offset; - u8 *widths = bank->type->fld_width; + const u8 *offs = bank->type->reg_offset; + const u8 *widths = bank->type->fld_width; enum pincfg_type type; /* Registers without a powerdown config aren't lost */ @@ -1140,9 +1139,8 @@ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) for (i = 0; i < ctrl->nr_banks; i++) { struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; void __iomem *reg = virt_base + bank->pctl_offset; - - u8 *offs = bank->type->reg_offset; - u8 *widths = bank->type->fld_width; + const u8 *offs = bank->type->reg_offset; + const u8 *widths = bank->type->fld_width; enum pincfg_type type; /* Registers without a powerdown config aren't lost */ diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index da527b390513..c67738597d2a 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -131,7 +131,7 @@ struct samsung_pin_bank_type { * @pm_save: saved register values during suspend */ struct samsung_pin_bank { - struct samsung_pin_bank_type *type; + const struct samsung_pin_bank_type *type; u32 pctl_offset; u32 pin_base; u8 nr_pins; -- GitLab From 1bf00d7a6dbff0a29eff4f8c022653b2bc9f5b97 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 23 Sep 2014 21:05:40 +0200 Subject: [PATCH 4016/9457] pinctrl: samsung: Constify samsung_pin_ctrl struct In order to separate initialization constants from runtime data, this patch modifies the driver to store only constant data in samsung_pin_ctrl struct and copy data required at runtime to samsung_pinctrl_drv_data struct. This makes it possible to mark all existing instances of samsung_pin_ctrl struct as const and __initconst. Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 39 +++++----- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 12 ++-- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 14 ++-- drivers/pinctrl/samsung/pinctrl-samsung.c | 87 ++++++++++++----------- drivers/pinctrl/samsung/pinctrl-samsung.h | 40 ++++++----- 5 files changed, 97 insertions(+), 95 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 0202e0016233..552f7c75243d 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -277,8 +277,7 @@ static const struct irq_domain_ops exynos_gpio_irqd_ops = { static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) { struct samsung_pinctrl_drv_data *d = data; - struct samsung_pin_ctrl *ctrl = d->ctrl; - struct samsung_pin_bank *bank = ctrl->pin_banks; + struct samsung_pin_bank *bank = d->pin_banks; unsigned int svc, group, pin, virq; svc = readl(d->virt_base + EXYNOS_SVC_OFFSET); @@ -325,8 +324,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) return -ENXIO; } - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { if (bank->eint_type != EINT_TYPE_GPIO) continue; bank->irq_domain = irq_domain_add_linear(bank->of_node, @@ -498,8 +497,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) if (!wkup_np) return -ENODEV; - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { if (bank->eint_type != EINT_TYPE_WKUP) continue; @@ -556,9 +555,9 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); irq_set_handler_data(irq, muxed_data); - bank = d->ctrl->pin_banks; + bank = d->pin_banks; idx = 0; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + for (i = 0; i < d->nr_banks; ++i, ++bank) { if (bank->eint_type != EINT_TYPE_WKUP_MUX) continue; @@ -590,11 +589,10 @@ static void exynos_pinctrl_suspend_bank( static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; - struct samsung_pin_bank *bank = ctrl->pin_banks; + struct samsung_pin_bank *bank = drvdata->pin_banks; int i; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) + for (i = 0; i < drvdata->nr_banks; ++i, ++bank) if (bank->eint_type == EINT_TYPE_GPIO) exynos_pinctrl_suspend_bank(drvdata, bank); } @@ -626,11 +624,10 @@ static void exynos_pinctrl_resume_bank( static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; - struct samsung_pin_bank *bank = ctrl->pin_banks; + struct samsung_pin_bank *bank = drvdata->pin_banks; int i; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) + for (i = 0; i < drvdata->nr_banks; ++i, ++bank) if (bank->eint_type == EINT_TYPE_GPIO) exynos_pinctrl_resume_bank(drvdata, bank); } @@ -673,7 +670,7 @@ static struct samsung_pin_bank s5pv210_pin_bank[] = { EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c), }; -struct samsung_pin_ctrl s5pv210_pin_ctrl[] = { +const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = s5pv210_pin_bank, @@ -720,7 +717,7 @@ static struct samsung_pin_bank exynos3250_pin_banks1[] = { * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes * two gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos3250_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos3250_pin_banks0, @@ -792,7 +789,7 @@ static struct samsung_pin_bank exynos4210_pin_banks2[] = { * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes * three gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos4210_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos4210_pin_banks0, @@ -877,7 +874,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks3[] = { * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes * four gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos4x12_pin_banks0, @@ -970,7 +967,7 @@ static struct samsung_pin_bank exynos5250_pin_banks3[] = { * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes * four gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos5250_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos5250_pin_banks0, @@ -1047,7 +1044,7 @@ static struct samsung_pin_bank exynos5260_pin_banks2[] = { * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes * three gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos5260_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos5260_pin_banks0, @@ -1127,7 +1124,7 @@ static struct samsung_pin_bank exynos5420_pin_banks4[] = { * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes * four gpio/pin-mux/pinconfig controllers. */ -struct samsung_pin_ctrl exynos5420_pin_ctrl[] = { +const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { { /* pin-controller instance 0 data */ .pin_banks = exynos5420_pin_banks0, diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 9db6cf5c8823..c0c7924657e6 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -518,8 +518,8 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d) irq_set_handler_data(irq, eint_data); } - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { struct s3c24xx_eint_domain_data *ddata; unsigned int mask; unsigned int irq; @@ -573,7 +573,7 @@ static struct samsung_pin_bank s3c2412_pin_banks[] = { PIN_BANK_2BIT(13, 0x080, "gpj"), }; -struct samsung_pin_ctrl s3c2412_pin_ctrl[] = { +const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { { .pin_banks = s3c2412_pin_banks, .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), @@ -595,7 +595,7 @@ static struct samsung_pin_bank s3c2416_pin_banks[] = { PIN_BANK_2BIT(2, 0x100, "gpm"), }; -struct samsung_pin_ctrl s3c2416_pin_ctrl[] = { +const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { { .pin_banks = s3c2416_pin_banks, .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), @@ -615,7 +615,7 @@ static struct samsung_pin_bank s3c2440_pin_banks[] = { PIN_BANK_2BIT(13, 0x0d0, "gpj"), }; -struct samsung_pin_ctrl s3c2440_pin_ctrl[] = { +const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { { .pin_banks = s3c2440_pin_banks, .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), @@ -638,7 +638,7 @@ static struct samsung_pin_bank s3c2450_pin_banks[] = { PIN_BANK_2BIT(2, 0x100, "gpm"), }; -struct samsung_pin_ctrl s3c2450_pin_ctrl[] = { +const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = { { .pin_banks = s3c2450_pin_banks, .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 2a14db2826d8..14c3f9823cc5 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -468,8 +468,8 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) } nr_domains = 0; - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { unsigned int nr_eints; unsigned int mask; @@ -497,9 +497,9 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d) } data->drvdata = d; - bank = d->ctrl->pin_banks; + bank = d->pin_banks; nr_domains = 0; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + for (i = 0; i < d->nr_banks; ++i, ++bank) { if (bank->eint_type != EINT_TYPE_GPIO) continue; @@ -735,8 +735,8 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d) irq_set_handler_data(irq, data); } - bank = d->ctrl->pin_banks; - for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { struct s3c64xx_eint0_domain_data *ddata; unsigned int nr_eints; unsigned int mask; @@ -804,7 +804,7 @@ static struct samsung_pin_bank s3c64xx_pin_banks0[] = { * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes * one gpio/pin-mux/pinconfig controller. */ -struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = { +const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = { { /* pin-controller instance 1 data */ .pin_banks = s3c64xx_pin_banks0, diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 63a97f1d8a21..6e14811d1316 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -349,7 +349,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, { struct samsung_pin_bank *b; - b = drvdata->ctrl->pin_banks; + b = drvdata->pin_banks; while ((pin >= b->pin_base) && ((b->pin_base + b->nr_pins - 1) < pin)) @@ -378,7 +378,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, func = &drvdata->pmx_functions[selector]; grp = &drvdata->pin_groups[group]; - pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base, + pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->pin_base, ®, &pin_offset, &bank); type = bank->type; mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; @@ -431,7 +431,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long flags; drvdata = pinctrl_dev_get_drvdata(pctldev); - pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, + pin_to_reg_bank(drvdata, pin - drvdata->pin_base, ®_base, &pin_offset, &bank); type = bank->type; @@ -834,32 +834,32 @@ static int samsung_pinctrl_register(struct platform_device *pdev, ctrldesc->confops = &samsung_pinconf_ops; pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * - drvdata->ctrl->nr_pins, GFP_KERNEL); + drvdata->nr_pins, GFP_KERNEL); if (!pindesc) { dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); return -ENOMEM; } ctrldesc->pins = pindesc; - ctrldesc->npins = drvdata->ctrl->nr_pins; + ctrldesc->npins = drvdata->nr_pins; /* dynamically populate the pin number and pin name for pindesc */ for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++) - pdesc->number = pin + drvdata->ctrl->base; + pdesc->number = pin + drvdata->pin_base; /* * allocate space for storing the dynamically generated names for all * the pins which belong to this pin-controller. */ pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH * - drvdata->ctrl->nr_pins, GFP_KERNEL); + drvdata->nr_pins, GFP_KERNEL); if (!pin_names) { dev_err(&pdev->dev, "mem alloc for pin names failed\n"); return -ENOMEM; } /* for each pin, the name of the pin is pin-bank name + pin number */ - for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) { - pin_bank = &drvdata->ctrl->pin_banks[bank]; + for (bank = 0; bank < drvdata->nr_banks; bank++) { + pin_bank = &drvdata->pin_banks[bank]; for (pin = 0; pin < pin_bank->nr_pins; pin++) { sprintf(pin_names, "%s-%d", pin_bank->name, pin); pdesc = pindesc + pin_bank->pin_base + pin; @@ -878,11 +878,11 @@ static int samsung_pinctrl_register(struct platform_device *pdev, return -EINVAL; } - for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) { - pin_bank = &drvdata->ctrl->pin_banks[bank]; + for (bank = 0; bank < drvdata->nr_banks; ++bank) { + pin_bank = &drvdata->pin_banks[bank]; pin_bank->grange.name = pin_bank->name; pin_bank->grange.id = bank; - pin_bank->grange.pin_base = drvdata->ctrl->base + pin_bank->grange.pin_base = drvdata->pin_base + pin_bank->pin_base; pin_bank->grange.base = pin_bank->gpio_chip.base; pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; @@ -918,17 +918,16 @@ static const struct gpio_chip samsung_gpiolib_chip = { static int samsung_gpiolib_register(struct platform_device *pdev, struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; - struct samsung_pin_bank *bank = ctrl->pin_banks; + struct samsung_pin_bank *bank = drvdata->pin_banks; struct gpio_chip *gc; int ret; int i; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { + for (i = 0; i < drvdata->nr_banks; ++i, ++bank) { bank->gpio_chip = samsung_gpiolib_chip; gc = &bank->gpio_chip; - gc->base = ctrl->base + bank->pin_base; + gc->base = drvdata->pin_base + bank->pin_base; gc->ngpio = bank->nr_pins; gc->dev = &pdev->dev; gc->of_node = bank->of_node; @@ -954,27 +953,27 @@ static int samsung_gpiolib_register(struct platform_device *pdev, static int samsung_gpiolib_unregister(struct platform_device *pdev, struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; - struct samsung_pin_bank *bank = ctrl->pin_banks; + struct samsung_pin_bank *bank = drvdata->pin_banks; int i; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) + for (i = 0; i < drvdata->nr_banks; ++i, ++bank) gpiochip_remove(&bank->gpio_chip); + return 0; } static const struct of_device_id samsung_pinctrl_dt_match[]; /* retrieve the soc specific data */ -static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( - struct samsung_pinctrl_drv_data *d, - struct platform_device *pdev) +static const struct samsung_pin_ctrl * +samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, + struct platform_device *pdev) { int id; const struct of_device_id *match; struct device_node *node = pdev->dev.of_node; struct device_node *np; - struct samsung_pin_ctrl *ctrl; + const struct samsung_pin_ctrl *ctrl; struct samsung_pin_bank *bank; int i; @@ -986,19 +985,24 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( match = of_match_node(samsung_pinctrl_dt_match, node); ctrl = (struct samsung_pin_ctrl *)match->data + id; - bank = ctrl->pin_banks; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { + d->suspend = ctrl->suspend; + d->resume = ctrl->resume; + d->pin_banks = ctrl->pin_banks; + d->nr_banks = ctrl->nr_banks; + + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { spin_lock_init(&bank->slock); bank->drvdata = d; - bank->pin_base = ctrl->nr_pins; - ctrl->nr_pins += bank->nr_pins; + bank->pin_base = d->nr_pins; + d->nr_pins += bank->nr_pins; } for_each_child_of_node(node, np) { if (!of_find_property(np, "gpio-controller", NULL)) continue; - bank = ctrl->pin_banks; - for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) { if (!strcmp(bank->name, np->name)) { bank->of_node = np; break; @@ -1006,8 +1010,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( } } - ctrl->base = pin_base; - pin_base += ctrl->nr_pins; + d->pin_base = pin_base; + pin_base += d->nr_pins; return ctrl; } @@ -1015,8 +1019,8 @@ static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data( static int samsung_pinctrl_probe(struct platform_device *pdev) { struct samsung_pinctrl_drv_data *drvdata; + const struct samsung_pin_ctrl *ctrl; struct device *dev = &pdev->dev; - struct samsung_pin_ctrl *ctrl; struct resource *res; int ret; @@ -1037,7 +1041,6 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) dev_err(&pdev->dev, "driver data not available\n"); return PTR_ERR(ctrl); } - drvdata->ctrl = ctrl; drvdata->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1082,12 +1085,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) static void samsung_pinctrl_suspend_dev( struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; void __iomem *virt_base = drvdata->virt_base; int i; - for (i = 0; i < ctrl->nr_banks; i++) { - struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; + for (i = 0; i < drvdata->nr_banks; i++) { + struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; void __iomem *reg = virt_base + bank->pctl_offset; const u8 *offs = bank->type->reg_offset; const u8 *widths = bank->type->fld_width; @@ -1115,8 +1117,8 @@ static void samsung_pinctrl_suspend_dev( } } - if (ctrl->suspend) - ctrl->suspend(drvdata); + if (drvdata->suspend) + drvdata->suspend(drvdata); } /** @@ -1129,15 +1131,14 @@ static void samsung_pinctrl_suspend_dev( */ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) { - struct samsung_pin_ctrl *ctrl = drvdata->ctrl; void __iomem *virt_base = drvdata->virt_base; int i; - if (ctrl->resume) - ctrl->resume(drvdata); + if (drvdata->resume) + drvdata->resume(drvdata); - for (i = 0; i < ctrl->nr_banks; i++) { - struct samsung_pin_bank *bank = &ctrl->pin_banks[i]; + for (i = 0; i < drvdata->nr_banks; i++) { + struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; void __iomem *reg = virt_base + bank->pctl_offset; const u8 *offs = bank->type->reg_offset; const u8 *widths = bank->type->fld_width; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index c67738597d2a..cf2d61d0f001 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -155,8 +155,6 @@ struct samsung_pin_bank { * struct samsung_pin_ctrl: represent a pin controller. * @pin_banks: list of pin banks included in this controller. * @nr_banks: number of pin banks. - * @base: starting system wide pin number. - * @nr_pins: number of pins supported by the controller. * @eint_gpio_init: platform specific callback to setup the external gpio * interrupts for the controller. * @eint_wkup_init: platform specific callback to setup the external wakeup @@ -166,9 +164,6 @@ struct samsung_pin_ctrl { struct samsung_pin_bank *pin_banks; u32 nr_banks; - u32 base; - u32 nr_pins; - int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); void (*suspend)(struct samsung_pinctrl_drv_data *); @@ -188,6 +183,8 @@ struct samsung_pin_ctrl { * @nr_groups: number of such pin groups. * @pmx_functions: list of pin functions available to the driver. * @nr_function: number of such pin functions. + * @pin_base: starting system wide pin number. + * @nr_pins: number of pins supported by the controller. */ struct samsung_pinctrl_drv_data { struct list_head node; @@ -195,7 +192,6 @@ struct samsung_pinctrl_drv_data { struct device *dev; int irq; - struct samsung_pin_ctrl *ctrl; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; @@ -203,6 +199,14 @@ struct samsung_pinctrl_drv_data { unsigned int nr_groups; const struct samsung_pmx_func *pmx_functions; unsigned int nr_functions; + + struct samsung_pin_bank *pin_banks; + u32 nr_banks; + unsigned int pin_base; + unsigned int nr_pins; + + void (*suspend)(struct samsung_pinctrl_drv_data *); + void (*resume)(struct samsung_pinctrl_drv_data *); }; /** @@ -233,17 +237,17 @@ struct samsung_pmx_func { }; /* list of all exported SoC specific data */ -extern struct samsung_pin_ctrl exynos3250_pin_ctrl[]; -extern struct samsung_pin_ctrl exynos4210_pin_ctrl[]; -extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; -extern struct samsung_pin_ctrl exynos5250_pin_ctrl[]; -extern struct samsung_pin_ctrl exynos5260_pin_ctrl[]; -extern struct samsung_pin_ctrl exynos5420_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c2412_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c2416_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c2440_pin_ctrl[]; -extern struct samsung_pin_ctrl s3c2450_pin_ctrl[]; -extern struct samsung_pin_ctrl s5pv210_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; +extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; +extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; +extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[]; +extern const struct samsung_pin_ctrl s3c2440_pin_ctrl[]; +extern const struct samsung_pin_ctrl s3c2450_pin_ctrl[]; +extern const struct samsung_pin_ctrl s5pv210_pin_ctrl[]; #endif /* __PINCTRL_SAMSUNG_H */ -- GitLab From 8100cf47698fedbde6dc3fa540b1fefcee69fd40 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 23 Sep 2014 21:05:41 +0200 Subject: [PATCH 4017/9457] pinctrl: samsung: Separate per-bank init and runtime data Currently the driver mixes constant init data with runtime data, which is far from being elegant and can invite potential hard to track issues. This patch intends to solve this by introducing a new samsung_pin_bank_data structure to hold only constant data known at compile time, which can be copied to main samsung_pin_bank struct used at runtime. In addition, thanks to this change, all per-bank initdata can be marked with const and __initconst keywords and dropped after init completes. Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 44 +++++++++++------------ drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 8 ++--- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 2 +- drivers/pinctrl/samsung/pinctrl-samsung.c | 18 ++++++++-- drivers/pinctrl/samsung/pinctrl-samsung.h | 33 ++++++++++++++--- 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 552f7c75243d..b4490cb2a439 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -633,7 +633,7 @@ static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) } /* pin banks of s5pv210 pin-controller */ -static struct samsung_pin_bank s5pv210_pin_bank[] = { +static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), @@ -683,7 +683,7 @@ const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = { }; /* pin banks of exynos3250 pin-controller 0 */ -static struct samsung_pin_bank exynos3250_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos3250_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), @@ -694,7 +694,7 @@ static struct samsung_pin_bank exynos3250_pin_banks0[] = { }; /* pin banks of exynos3250 pin-controller 1 */ -static struct samsung_pin_bank exynos3250_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos3250_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"), EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"), EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"), @@ -737,7 +737,7 @@ const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = { }; /* pin banks of exynos4210 pin-controller 0 */ -static struct samsung_pin_bank exynos4210_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), @@ -757,7 +757,7 @@ static struct samsung_pin_bank exynos4210_pin_banks0[] = { }; /* pin banks of exynos4210 pin-controller 1 */ -static struct samsung_pin_bank exynos4210_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos4210_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00), EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04), EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), @@ -781,7 +781,7 @@ static struct samsung_pin_bank exynos4210_pin_banks1[] = { }; /* pin banks of exynos4210 pin-controller 2 */ -static struct samsung_pin_bank exynos4210_pin_banks2[] = { +static const struct samsung_pin_bank_data exynos4210_pin_banks2[] __initconst = { EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"), }; @@ -813,7 +813,7 @@ const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = { }; /* pin banks of exynos4x12 pin-controller 0 */ -static struct samsung_pin_bank exynos4x12_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), @@ -830,7 +830,7 @@ static struct samsung_pin_bank exynos4x12_pin_banks0[] = { }; /* pin banks of exynos4x12 pin-controller 1 */ -static struct samsung_pin_bank exynos4x12_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos4x12_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08), EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), @@ -857,12 +857,12 @@ static struct samsung_pin_bank exynos4x12_pin_banks1[] = { }; /* pin banks of exynos4x12 pin-controller 2 */ -static struct samsung_pin_bank exynos4x12_pin_banks2[] = { +static const struct samsung_pin_bank_data exynos4x12_pin_banks2[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), }; /* pin banks of exynos4x12 pin-controller 3 */ -static struct samsung_pin_bank exynos4x12_pin_banks3[] = { +static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08), @@ -908,7 +908,7 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { }; /* pin banks of exynos5250 pin-controller 0 */ -static struct samsung_pin_bank exynos5250_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), @@ -937,7 +937,7 @@ static struct samsung_pin_bank exynos5250_pin_banks0[] = { }; /* pin banks of exynos5250 pin-controller 1 */ -static struct samsung_pin_bank exynos5250_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos5250_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08), @@ -950,7 +950,7 @@ static struct samsung_pin_bank exynos5250_pin_banks1[] = { }; /* pin banks of exynos5250 pin-controller 2 */ -static struct samsung_pin_bank exynos5250_pin_banks2[] = { +static const struct samsung_pin_bank_data exynos5250_pin_banks2[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00), EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08), @@ -959,7 +959,7 @@ static struct samsung_pin_bank exynos5250_pin_banks2[] = { }; /* pin banks of exynos5250 pin-controller 3 */ -static struct samsung_pin_bank exynos5250_pin_banks3[] = { +static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), }; @@ -1001,7 +1001,7 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = { }; /* pin banks of exynos5260 pin-controller 0 */ -static struct samsung_pin_bank exynos5260_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), @@ -1026,7 +1026,7 @@ static struct samsung_pin_bank exynos5260_pin_banks0[] = { }; /* pin banks of exynos5260 pin-controller 1 */ -static struct samsung_pin_bank exynos5260_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos5260_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04), EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), @@ -1035,7 +1035,7 @@ static struct samsung_pin_bank exynos5260_pin_banks1[] = { }; /* pin banks of exynos5260 pin-controller 2 */ -static struct samsung_pin_bank exynos5260_pin_banks2[] = { +static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), }; @@ -1065,7 +1065,7 @@ const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = { }; /* pin banks of exynos5420 pin-controller 0 */ -static struct samsung_pin_bank exynos5420_pin_banks0[] = { +static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00), EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), @@ -1074,7 +1074,7 @@ static struct samsung_pin_bank exynos5420_pin_banks0[] = { }; /* pin banks of exynos5420 pin-controller 1 */ -static struct samsung_pin_bank exynos5420_pin_banks1[] = { +static const struct samsung_pin_bank_data exynos5420_pin_banks1[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00), EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04), EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08), @@ -1091,7 +1091,7 @@ static struct samsung_pin_bank exynos5420_pin_banks1[] = { }; /* pin banks of exynos5420 pin-controller 2 */ -static struct samsung_pin_bank exynos5420_pin_banks2[] = { +static const struct samsung_pin_bank_data exynos5420_pin_banks2[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00), EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04), EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08), @@ -1103,7 +1103,7 @@ static struct samsung_pin_bank exynos5420_pin_banks2[] = { }; /* pin banks of exynos5420 pin-controller 3 */ -static struct samsung_pin_bank exynos5420_pin_banks3[] = { +static const struct samsung_pin_bank_data exynos5420_pin_banks3[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08), @@ -1116,7 +1116,7 @@ static struct samsung_pin_bank exynos5420_pin_banks3[] = { }; /* pin banks of exynos5420 pin-controller 4 */ -static struct samsung_pin_bank exynos5420_pin_banks4[] = { +static const struct samsung_pin_bank_data exynos5420_pin_banks4[] __initconst = { EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), }; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index c0c7924657e6..f1993f42114c 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -561,7 +561,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d) return 0; } -static struct samsung_pin_bank s3c2412_pin_banks[] = { +static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = { PIN_BANK_A(23, 0x000, "gpa"), PIN_BANK_2BIT(11, 0x010, "gpb"), PIN_BANK_2BIT(16, 0x020, "gpc"), @@ -581,7 +581,7 @@ const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { }, }; -static struct samsung_pin_bank s3c2416_pin_banks[] = { +static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { PIN_BANK_A(27, 0x000, "gpa"), PIN_BANK_2BIT(11, 0x010, "gpb"), PIN_BANK_2BIT(16, 0x020, "gpc"), @@ -603,7 +603,7 @@ const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { }, }; -static struct samsung_pin_bank s3c2440_pin_banks[] = { +static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { PIN_BANK_A(25, 0x000, "gpa"), PIN_BANK_2BIT(11, 0x010, "gpb"), PIN_BANK_2BIT(16, 0x020, "gpc"), @@ -623,7 +623,7 @@ const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { }, }; -static struct samsung_pin_bank s3c2450_pin_banks[] = { +static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { PIN_BANK_A(28, 0x000, "gpa"), PIN_BANK_2BIT(11, 0x010, "gpb"), PIN_BANK_2BIT(16, 0x020, "gpc"), diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 14c3f9823cc5..7756c1e9e763 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -780,7 +780,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d) } /* pin banks of s3c64xx pin-controller 0 */ -static struct samsung_pin_bank s3c64xx_pin_banks0[] = { +static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = { PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0), PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8), PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16), diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 6e14811d1316..96ef6e50f1f6 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -973,6 +973,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, const struct of_device_id *match; struct device_node *node = pdev->dev.of_node; struct device_node *np; + const struct samsung_pin_bank_data *bdata; const struct samsung_pin_ctrl *ctrl; struct samsung_pin_bank *bank; int i; @@ -987,11 +988,24 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, d->suspend = ctrl->suspend; d->resume = ctrl->resume; - d->pin_banks = ctrl->pin_banks; d->nr_banks = ctrl->nr_banks; + d->pin_banks = devm_kcalloc(&pdev->dev, d->nr_banks, + sizeof(*d->pin_banks), GFP_KERNEL); + if (!d->pin_banks) + return ERR_PTR(-ENOMEM); bank = d->pin_banks; - for (i = 0; i < d->nr_banks; ++i, ++bank) { + bdata = ctrl->pin_banks; + for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) { + bank->type = bdata->type; + bank->pctl_offset = bdata->pctl_offset; + bank->nr_pins = bdata->nr_pins; + bank->eint_func = bdata->eint_func; + bank->eint_type = bdata->eint_type; + bank->eint_mask = bdata->eint_mask; + bank->eint_offset = bdata->eint_offset; + bank->name = bdata->name; + spin_lock_init(&bank->slock); bank->drvdata = d; bank->pin_base = d->nr_pins; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index cf2d61d0f001..ec43b7d49fb9 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -112,16 +112,40 @@ struct samsung_pin_bank_type { u8 reg_offset[PINCFG_TYPE_NUM]; }; +/** + * struct samsung_pin_bank_data: represent a controller pin-bank (init data). + * @type: type of the bank (register offsets and bitfield widths) + * @pctl_offset: starting offset of the pin-bank registers. + * @nr_pins: number of pins included in this bank. + * @eint_func: function to set in CON register to configure pin as EINT. + * @eint_type: type of the external interrupt supported by the bank. + * @eint_mask: bit mask of pins which support EINT function. + * @eint_offset: SoC-specific EINT register or interrupt offset of bank. + * @name: name to be prefixed for each pin in this pin bank. + */ +struct samsung_pin_bank_data { + const struct samsung_pin_bank_type *type; + u32 pctl_offset; + u8 nr_pins; + u8 eint_func; + enum eint_type eint_type; + u32 eint_mask; + u32 eint_offset; + const char *name; +}; + /** * struct samsung_pin_bank: represent a controller pin-bank. * @type: type of the bank (register offsets and bitfield widths) * @pctl_offset: starting offset of the pin-bank registers. - * @pin_base: starting pin number of the bank. * @nr_pins: number of pins included in this bank. * @eint_func: function to set in CON register to configure pin as EINT. * @eint_type: type of the external interrupt supported by the bank. * @eint_mask: bit mask of pins which support EINT function. + * @eint_offset: SoC-specific EINT register or interrupt offset of bank. * @name: name to be prefixed for each pin in this pin bank. + * @pin_base: starting pin number of the bank. + * @soc_priv: per-bank private data for SoC-specific code. * @of_node: OF node of the bank. * @drvdata: link to controller driver data * @irq_domain: IRQ domain of the bank. @@ -133,13 +157,14 @@ struct samsung_pin_bank_type { struct samsung_pin_bank { const struct samsung_pin_bank_type *type; u32 pctl_offset; - u32 pin_base; u8 nr_pins; u8 eint_func; enum eint_type eint_type; u32 eint_mask; u32 eint_offset; - char *name; + const char *name; + + u32 pin_base; void *soc_priv; struct device_node *of_node; struct samsung_pinctrl_drv_data *drvdata; @@ -161,7 +186,7 @@ struct samsung_pin_bank { * interrupts for the controller. */ struct samsung_pin_ctrl { - struct samsung_pin_bank *pin_banks; + const struct samsung_pin_bank_data *pin_banks; u32 nr_banks; int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); -- GitLab From 0d3d30db93635936652417efd0f4a3e9049d0938 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Thu, 9 Oct 2014 19:24:29 +0530 Subject: [PATCH 4018/9457] pinctrl: exynos: Generalize the eint16_31 demux code The function exynos_irq_demux_eint16_31 uses pre-defined offsets for external interrupt pending status and mask registers. So this function is not extensible for Exynos7 SoC which has these registers at different offsets. Generalize the exynos_irq_demux_eint16_31 function by using the pending/mask register offset values from the exynos_irq_chip structure. This is done by adding a irq_chip field to the samsung_pin_bank struct. Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Acked-by: Tomasz Figa Cc: Linus Walleij Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 14 ++++++++++---- drivers/pinctrl/samsung/pinctrl-samsung.h | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index b4490cb2a439..954e555766df 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -260,7 +260,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, struct samsung_pin_bank *b = h->host_data; irq_set_chip_data(virq, b); - irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip, + irq_set_chip_and_handler(virq, &b->irq_chip->chip, handle_level_irq); set_irq_flags(virq, IRQF_VALID); return 0; @@ -343,6 +343,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) ret = -ENOMEM; goto err_domains; } + + bank->irq_chip = &exynos_gpio_irq_chip; } return 0; @@ -444,9 +446,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) for (i = 0; i < eintd->nr_banks; ++i) { struct samsung_pin_bank *b = eintd->banks[i]; - pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET + pend = readl(d->virt_base + b->irq_chip->eint_pend + b->eint_offset); - mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET + mask = readl(d->virt_base + b->irq_chip->eint_mask + b->eint_offset); exynos_irq_demux_eint(pend & ~mask, b->irq_domain); } @@ -457,7 +459,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { - irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip, + struct samsung_pin_bank *b = h->host_data; + + irq_set_chip_and_handler(virq, &b->irq_chip->chip, handle_level_irq); irq_set_chip_data(virq, h->host_data); set_irq_flags(virq, IRQF_VALID); @@ -509,6 +513,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) return -ENXIO; } + bank->irq_chip = &exynos_wkup_irq_chip; + if (!of_find_property(bank->of_node, "interrupts", NULL)) { bank->eint_type = EINT_TYPE_WKUP_MUX; ++muxed_banks; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index ec43b7d49fb9..3076b8b591c7 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -151,6 +151,7 @@ struct samsung_pin_bank_data { * @irq_domain: IRQ domain of the bank. * @gpio_chip: GPIO chip of the bank. * @grange: linux gpio pin range supported by this bank. + * @irq_chip: link to irq chip for external gpio and wakeup interrupts. * @slock: spinlock protecting bank registers * @pm_save: saved register values during suspend */ @@ -171,6 +172,7 @@ struct samsung_pin_bank { struct irq_domain *irq_domain; struct gpio_chip gpio_chip; struct pinctrl_gpio_range grange; + struct exynos_irq_chip *irq_chip; spinlock_t slock; u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ -- GitLab From 6f5e41bd8fc6d34bc9a2aabe75b5f67b6f99cda9 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Thu, 9 Oct 2014 19:24:30 +0530 Subject: [PATCH 4019/9457] pinctrl: exynos: Consolidate irq domain callbacks Adding a irq_chip field to the samsung_pin_bank struct helps in consolidating the irq domain callbacks for external gpio and wakeup interrupt controllers. The exynos_wkup_irqd_ops and exynos_gpio_irqd_ops have now been merged into a single exynos_eint_irqd_ops. Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Acked-by: Tomasz Figa Cc: Linus Walleij Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 32 +++++------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 954e555766df..7a7eb6a271eb 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -254,7 +254,7 @@ static struct exynos_irq_chip exynos_gpio_irq_chip = { .eint_pend = EXYNOS_GPIO_EPEND_OFFSET, }; -static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, +static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct samsung_pin_bank *b = h->host_data; @@ -267,10 +267,10 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, } /* - * irq domain callbacks for external gpio interrupt controller. + * irq domain callbacks for external gpio and wakeup interrupt controllers. */ -static const struct irq_domain_ops exynos_gpio_irqd_ops = { - .map = exynos_gpio_irq_map, +static const struct irq_domain_ops exynos_eint_irqd_ops = { + .map = exynos_eint_irq_map, .xlate = irq_domain_xlate_twocell, }; @@ -329,7 +329,7 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) if (bank->eint_type != EINT_TYPE_GPIO) continue; bank->irq_domain = irq_domain_add_linear(bank->of_node, - bank->nr_pins, &exynos_gpio_irqd_ops, bank); + bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { dev_err(dev, "gpio irq domain add failed\n"); ret = -ENXIO; @@ -456,26 +456,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) chained_irq_exit(chip, desc); } -static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct samsung_pin_bank *b = h->host_data; - - irq_set_chip_and_handler(virq, &b->irq_chip->chip, - handle_level_irq); - irq_set_chip_data(virq, h->host_data); - set_irq_flags(virq, IRQF_VALID); - return 0; -} - -/* - * irq domain callbacks for external wakeup interrupt controller. - */ -static const struct irq_domain_ops exynos_wkup_irqd_ops = { - .map = exynos_wkup_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - /* * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. * @d: driver data of samsung pinctrl driver. @@ -507,7 +487,7 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) continue; bank->irq_domain = irq_domain_add_linear(bank->of_node, - bank->nr_pins, &exynos_wkup_irqd_ops, bank); + bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { dev_err(dev, "wkup irq domain add failed\n"); return -ENXIO; -- GitLab From 14c255d35b25126149fb2fd199b030404229af65 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Thu, 9 Oct 2014 19:24:31 +0530 Subject: [PATCH 4020/9457] pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts Exynos7 uses different offsets for wakeup interrupt configuration registers. So a new irq_chip instance for Exynos7 wakeup interrupts is added. The irq_chip selection is now based on the wakeup interrupt controller compatible string. Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Acked-by: Tomasz Figa Cc: Linus Walleij Signed-off-by: Tomasz Figa --- .../bindings/pinctrl/samsung-pinctrl.txt | 2 + drivers/pinctrl/samsung/pinctrl-exynos.c | 45 ++++++++++++++----- drivers/pinctrl/samsung/pinctrl-exynos.h | 3 ++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index e82aaf492517..f80519a98df8 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -136,6 +136,8 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a found on Samsung S3C64xx SoCs, - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller found on Samsung Exynos4210 and S5PC110/S5PV210 SoCs. + - samsung,exynos7-wakeup-eint: represents wakeup interrupt controller + found on Samsung Exynos7 SoC. - interrupt-parent: phandle of the interrupt parent to which the external wakeup interrupts are forwarded to. - interrupts: interrupt used by multiplexed wakeup interrupts. diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 7a7eb6a271eb..d97765c20466 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -56,12 +56,6 @@ static const struct samsung_pin_bank_type bank_type_alive = { .reg_offset = { 0x00, 0x04, 0x08, 0x0c, }, }; -/* list of external wakeup controllers supported */ -static const struct of_device_id exynos_wkup_irq_ids[] = { - { .compatible = "samsung,exynos4210-wakeup-eint", }, - { } -}; - static void exynos_irq_mask(struct irq_data *irqd) { struct irq_chip *chip = irq_data_get_irq_chip(irqd); @@ -384,9 +378,9 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) /* * irq_chip for wakeup interrupts */ -static struct exynos_irq_chip exynos_wkup_irq_chip = { +static struct exynos_irq_chip exynos4210_wkup_irq_chip __initdata = { .chip = { - .name = "exynos_wkup_irq_chip", + .name = "exynos4210_wkup_irq_chip", .irq_unmask = exynos_irq_unmask, .irq_mask = exynos_irq_mask, .irq_ack = exynos_irq_ack, @@ -400,6 +394,31 @@ static struct exynos_irq_chip exynos_wkup_irq_chip = { .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, }; +static struct exynos_irq_chip exynos7_wkup_irq_chip __initdata = { + .chip = { + .name = "exynos7_wkup_irq_chip", + .irq_unmask = exynos_irq_unmask, + .irq_mask = exynos_irq_mask, + .irq_ack = exynos_irq_ack, + .irq_set_type = exynos_irq_set_type, + .irq_set_wake = exynos_wkup_irq_set_wake, + .irq_request_resources = exynos_irq_request_resources, + .irq_release_resources = exynos_irq_release_resources, + }, + .eint_con = EXYNOS7_WKUP_ECON_OFFSET, + .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET, + .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, +}; + +/* list of external wakeup controllers supported */ +static const struct of_device_id exynos_wkup_irq_ids[] = { + { .compatible = "samsung,exynos4210-wakeup-eint", + .data = &exynos4210_wkup_irq_chip }, + { .compatible = "samsung,exynos7-wakeup-eint", + .data = &exynos7_wkup_irq_chip }, + { } +}; + /* interrupt handler for wakeup interrupts 0..15 */ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) { @@ -468,12 +487,18 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) struct samsung_pin_bank *bank; struct exynos_weint_data *weint_data; struct exynos_muxed_weint_data *muxed_data; + struct exynos_irq_chip *irq_chip; unsigned int muxed_banks = 0; unsigned int i; int idx, irq; for_each_child_of_node(dev->of_node, np) { - if (of_match_node(exynos_wkup_irq_ids, np)) { + const struct of_device_id *match; + + match = of_match_node(exynos_wkup_irq_ids, np); + if (match) { + irq_chip = kmemdup(match->data, + sizeof(*irq_chip), GFP_KERNEL); wkup_np = np; break; } @@ -493,7 +518,7 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) return -ENXIO; } - bank->irq_chip = &exynos_wkup_irq_chip; + bank->irq_chip = irq_chip; if (!of_find_property(bank->of_node, "interrupts", NULL)) { bank->eint_type = EINT_TYPE_WKUP_MUX; diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h index 3c91c357792f..0f0f7cedb2dc 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.h +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h @@ -25,6 +25,9 @@ #define EXYNOS_WKUP_ECON_OFFSET 0xE00 #define EXYNOS_WKUP_EMASK_OFFSET 0xF00 #define EXYNOS_WKUP_EPEND_OFFSET 0xF40 +#define EXYNOS7_WKUP_ECON_OFFSET 0x700 +#define EXYNOS7_WKUP_EMASK_OFFSET 0x900 +#define EXYNOS7_WKUP_EPEND_OFFSET 0xA00 #define EXYNOS_SVC_OFFSET 0xB08 #define EXYNOS_EINT_FUNC 0xF -- GitLab From 50cea0cff7131b364c0ff80dedf8e91212b18a26 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Ch Date: Thu, 9 Oct 2014 19:24:32 +0530 Subject: [PATCH 4021/9457] pinctrl: exynos: Add initial driver data for Exynos7 This patch adds initial driver data for Exynos7 pinctrl support. Signed-off-by: Naveen Krishna Ch Signed-off-by: Abhilash Kesavan Reviewed-by: Thomas Abraham Tested-by: Thomas Abraham Acked-by: Tomasz Figa Cc: Linus Walleij Signed-off-by: Tomasz Figa --- .../bindings/pinctrl/samsung-pinctrl.txt | 1 + drivers/pinctrl/samsung/pinctrl-exynos.c | 105 ++++++++++++++++++ drivers/pinctrl/samsung/pinctrl-samsung.c | 2 + drivers/pinctrl/samsung/pinctrl-samsung.h | 1 + 4 files changed, 109 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt index f80519a98df8..8425838a6dff 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt @@ -18,6 +18,7 @@ Required Properties: - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller. - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller. - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller. + - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller. - reg: Base address of the pin controller hardware module and length of the address space it occupies. diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d97765c20466..5622d8a3e478 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -1164,3 +1164,108 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, }, }; + +/* pin banks of exynos7 pin-controller - ALIVE */ +static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { + EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), + EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), + EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), + EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), +}; + +/* pin banks of exynos7 pin-controller - BUS0 */ +static const struct samsung_pin_bank_data exynos7_pin_banks1[] __initconst = { + EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00), + EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc0", 0x04), + EXYNOS_PIN_BANK_EINTG(2, 0x040, "gpc1", 0x08), + EXYNOS_PIN_BANK_EINTG(6, 0x060, "gpc2", 0x0c), + EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpc3", 0x10), + EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14), + EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18), + EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpd2", 0x1c), + EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpd4", 0x20), + EXYNOS_PIN_BANK_EINTG(4, 0x120, "gpd5", 0x24), + EXYNOS_PIN_BANK_EINTG(6, 0x140, "gpd6", 0x28), + EXYNOS_PIN_BANK_EINTG(3, 0x160, "gpd7", 0x2c), + EXYNOS_PIN_BANK_EINTG(2, 0x180, "gpd8", 0x30), + EXYNOS_PIN_BANK_EINTG(2, 0x1a0, "gpg0", 0x34), + EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpg3", 0x38), +}; + +/* pin banks of exynos7 pin-controller - NFC */ +static const struct samsung_pin_bank_data exynos7_pin_banks2[] __initconst = { + EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), +}; + +/* pin banks of exynos7 pin-controller - TOUCH */ +static const struct samsung_pin_bank_data exynos7_pin_banks3[] __initconst = { + EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), +}; + +/* pin banks of exynos7 pin-controller - FF */ +static const struct samsung_pin_bank_data exynos7_pin_banks4[] __initconst = { + EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpg4", 0x00), +}; + +/* pin banks of exynos7 pin-controller - ESE */ +static const struct samsung_pin_bank_data exynos7_pin_banks5[] __initconst = { + EXYNOS_PIN_BANK_EINTG(5, 0x000, "gpv7", 0x00), +}; + +/* pin banks of exynos7 pin-controller - FSYS0 */ +static const struct samsung_pin_bank_data exynos7_pin_banks6[] __initconst = { + EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpr4", 0x00), +}; + +/* pin banks of exynos7 pin-controller - FSYS1 */ +static const struct samsung_pin_bank_data exynos7_pin_banks7[] __initconst = { + EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpr0", 0x00), + EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpr1", 0x04), + EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr2", 0x08), + EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr3", 0x0c), +}; + +const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { + { + /* pin-controller instance 0 Alive data */ + .pin_banks = exynos7_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks0), + .eint_gpio_init = exynos_eint_gpio_init, + .eint_wkup_init = exynos_eint_wkup_init, + }, { + /* pin-controller instance 1 BUS0 data */ + .pin_banks = exynos7_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks1), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 2 NFC data */ + .pin_banks = exynos7_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks2), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 3 TOUCH data */ + .pin_banks = exynos7_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks3), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 4 FF data */ + .pin_banks = exynos7_pin_banks4, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks4), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 5 ESE data */ + .pin_banks = exynos7_pin_banks5, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks5), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 6 FSYS0 data */ + .pin_banks = exynos7_pin_banks6, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks6), + .eint_gpio_init = exynos_eint_gpio_init, + }, { + /* pin-controller instance 7 FSYS1 data */ + .pin_banks = exynos7_pin_banks7, + .nr_banks = ARRAY_SIZE(exynos7_pin_banks7), + .eint_gpio_init = exynos_eint_gpio_init, + }, +}; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 96ef6e50f1f6..e5a81503f533 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1239,6 +1239,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = (void *)exynos5420_pin_ctrl }, { .compatible = "samsung,s5pv210-pinctrl", .data = (void *)s5pv210_pin_ctrl }, + { .compatible = "samsung,exynos7-pinctrl", + .data = (void *)exynos7_pin_ctrl }, #endif #ifdef CONFIG_PINCTRL_S3C64XX { .compatible = "samsung,s3c64xx-pinctrl", diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 3076b8b591c7..29004be52eaa 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -270,6 +270,7 @@ extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos7_pin_ctrl[]; extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[]; -- GitLab From 2891ba2906b6d2fd453042f410a11e6fc3edc37d Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Mon, 27 Oct 2014 10:21:18 +0900 Subject: [PATCH 4022/9457] pinctrl: exynos: Add support for Exynos4415 The pin controllers of Exynos4415 are similar to Exynos4412, but certain differences cause the need to create separate driver data for it. This patch adds pin controller and bank descriptor arrays to the driver to support the new SoC. Cc: Tomasz Figa Cc: Thomas Abraham Cc: Linus Walleij Signed-off-by: Tomasz Figa [cw00.choi: Rebase it on mainline kernel] Signed-off-by: Chanwoo Choi Acked-by: Kyungmin Park [tomasz.figa@gmail.com: Resolved merge with earlier clean-up series.] Signed-off-by: Tomasz Figa --- drivers/pinctrl/samsung/pinctrl-exynos.c | 75 +++++++++++++++++++++++ drivers/pinctrl/samsung/pinctrl-samsung.c | 2 + drivers/pinctrl/samsung/pinctrl-samsung.h | 1 + 3 files changed, 78 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 5622d8a3e478..d5d4cfc55873 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -918,6 +918,81 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = { }, }; +/* pin banks of exynos4415 pin-controller 0 */ +static const struct samsung_pin_bank_data exynos4415_pin_banks0[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), + EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04), + EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08), + EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c), + EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10), + EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14), + EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18), + EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30), + EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34), + EXYNOS_PIN_BANK_EINTG(1, 0x1C0, "gpf2", 0x38), +}; + +/* pin banks of exynos4415 pin-controller 1 */ +static const struct samsung_pin_bank_data exynos4415_pin_banks1[] = { + EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08), + EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c), + EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10), + EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14), + EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpl0", 0x18), + EXYNOS_PIN_BANK_EINTN(6, 0x120, "mp00"), + EXYNOS_PIN_BANK_EINTN(4, 0x140, "mp01"), + EXYNOS_PIN_BANK_EINTN(6, 0x160, "mp02"), + EXYNOS_PIN_BANK_EINTN(8, 0x180, "mp03"), + EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "mp04"), + EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "mp05"), + EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "mp06"), + EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24), + EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28), + EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c), + EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30), + EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34), + EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00), + EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04), + EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08), + EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c), +}; + +/* pin banks of exynos4415 pin-controller 2 */ +static const struct samsung_pin_bank_data exynos4415_pin_banks2[] = { + EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00), + EXYNOS_PIN_BANK_EINTN(2, 0x000, "etc1"), +}; + +/* + * Samsung pinctrl driver data for Exynos4415 SoC. Exynos4415 SoC includes + * three gpio/pin-mux/pinconfig controllers. + */ +const struct samsung_pin_ctrl exynos4415_pin_ctrl[] = { + { + /* pin-controller instance 0 data */ + .pin_banks = exynos4415_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos4415_pin_banks0), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 1 data */ + .pin_banks = exynos4415_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos4415_pin_banks1), + .eint_gpio_init = exynos_eint_gpio_init, + .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 2 data */ + .pin_banks = exynos4415_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos4415_pin_banks2), + .eint_gpio_init = exynos_eint_gpio_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, +}; + /* pin banks of exynos5250 pin-controller 0 */ static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = { EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00), diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index e5a81503f533..32940a01a84f 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1231,6 +1231,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = (void *)exynos4210_pin_ctrl }, { .compatible = "samsung,exynos4x12-pinctrl", .data = (void *)exynos4x12_pin_ctrl }, + { .compatible = "samsung,exynos4415-pinctrl", + .data = (void *)exynos4415_pin_ctrl }, { .compatible = "samsung,exynos5250-pinctrl", .data = (void *)exynos5250_pin_ctrl }, { .compatible = "samsung,exynos5260-pinctrl", diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 29004be52eaa..1b8c0139d604 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -267,6 +267,7 @@ struct samsung_pmx_func { extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[]; +extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; -- GitLab From ce674173e9f4ef7fd0dc04ea0773cdedfbf8e366 Mon Sep 17 00:00:00 2001 From: Ana Rey Date: Mon, 3 Nov 2014 18:10:50 +0100 Subject: [PATCH 4023/9457] netfilter: nft_meta: add cgroup support This allows you to filter traffic by process control group (cgroup). Signed-off-by: Ana Rey Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter/nf_tables.h | 2 ++ net/netfilter/nft_meta.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 16f62a5cf04d..832bc46db78b 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -579,6 +579,7 @@ enum nft_exthdr_attributes { * @NFT_META_CPU: cpu id through smp_processor_id() * @NFT_META_IIFGROUP: packet input interface group * @NFT_META_OIFGROUP: packet output interface group + * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid) */ enum nft_meta_keys { NFT_META_LEN, @@ -604,6 +605,7 @@ enum nft_meta_keys { NFT_META_CPU, NFT_META_IIFGROUP, NFT_META_OIFGROUP, + NFT_META_CGROUP, }; /** diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 1e7c076ca63a..e99911eda915 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -165,6 +165,12 @@ void nft_meta_get_eval(const struct nft_expr *expr, goto err; dest->data[0] = out->group; break; + case NFT_META_CGROUP: + if (skb->sk == NULL) + break; + + dest->data[0] = skb->sk->sk_classid; + break; default: WARN_ON(1); goto err; @@ -240,6 +246,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx, case NFT_META_CPU: case NFT_META_IIFGROUP: case NFT_META_OIFGROUP: + case NFT_META_CGROUP: break; default: return -EOPNOTSUPP; -- GitLab From 1fb8510cdb5b7befe8a59f533c7fc12ef0dac73e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Nov 2014 17:08:28 +0100 Subject: [PATCH 4024/9457] ALSA: pcm: Add snd_pcm_stop_xrun() helper Add a new helper function snd_pcm_stop_xrun() to the standard sequnce lock/snd_pcm_stop(XRUN)/unlock by a single call, and replace the existing open codes with this helper. The function checks the PCM running state to prevent setting the wrong state, too, for more safety. Signed-off-by: Takashi Iwai --- drivers/media/pci/saa7134/saa7134-alsa.c | 4 +--- include/sound/pcm.h | 1 + sound/arm/pxa2xx-pcm-lib.c | 4 +--- sound/core/pcm_native.c | 23 +++++++++++++++++++++++ sound/firewire/amdtp.c | 8 ++------ sound/firewire/isight.c | 10 ++-------- sound/pci/asihpi/asihpi.c | 5 +---- sound/pci/atiixp.c | 4 +--- sound/pci/atiixp_modem.c | 4 +--- sound/soc/atmel/atmel-pcm-dma.c | 4 +--- sound/soc/fsl/fsl_dma.c | 9 +-------- sound/usb/6fire/pcm.c | 17 ++++------------- sound/usb/endpoint.c | 4 +--- sound/usb/misc/ua101.c | 18 ++++-------------- sound/usb/usx2y/usbusx2yaudio.c | 9 ++------- 15 files changed, 46 insertions(+), 78 deletions(-) diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index 40569894c1c9..ac3cd74e824e 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -173,9 +173,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev, dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, dev->dmasound.bufsize, dev->dmasound.blocks); spin_unlock(&dev->slock); - snd_pcm_stream_lock(dev->dmasound.substream); - snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock(dev->dmasound.substream); + snd_pcm_stop_xrun(dev->dmasound.substream); return; } diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0b8daeed0a33..40289ec2451c 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -506,6 +506,7 @@ int snd_pcm_status(struct snd_pcm_substream *substream, int snd_pcm_start(struct snd_pcm_substream *substream); int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); int snd_pcm_drain_done(struct snd_pcm_substream *substream); +int snd_pcm_stop_xrun(struct snd_pcm_substream *substream); #ifdef CONFIG_PM int snd_pcm_suspend(struct snd_pcm_substream *substream); int snd_pcm_suspend_all(struct snd_pcm *pcm); diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index a61d7a9a995e..01f8fdc42b1b 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c @@ -200,9 +200,7 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) } else { printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n", dma_ch, dcsr); - snd_pcm_stream_lock(substream); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock(substream); + snd_pcm_stop_xrun(substream); } } EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index dfb5031969f8..a3d122109704 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1098,6 +1098,29 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream) SNDRV_PCM_STATE_SETUP); } +/** + * snd_pcm_stop_xrun - stop the running streams as XRUN + * @substream: the PCM substream instance + * @state: PCM state after stopping the stream + * + * This stops the given running substream (and all linked substreams) as XRUN. + * Unlike snd_pcm_stop(), this function takes the substream lock by itself. + * + * Return: Zero if successful, or a negative error code. + */ +int snd_pcm_stop_xrun(struct snd_pcm_substream *substream) +{ + unsigned long flags; + int ret = 0; + + snd_pcm_stream_lock_irqsave(substream, flags); + if (snd_pcm_running(substream)) + ret = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); + snd_pcm_stream_unlock_irqrestore(substream, flags); + return ret; +} +EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun); + /* * pause callbacks */ diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 95fc2eaf11dc..3badc70124ab 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -1006,11 +1006,7 @@ void amdtp_stream_pcm_abort(struct amdtp_stream *s) struct snd_pcm_substream *pcm; pcm = ACCESS_ONCE(s->pcm); - if (pcm) { - snd_pcm_stream_lock_irq(pcm); - if (snd_pcm_running(pcm)) - snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irq(pcm); - } + if (pcm) + snd_pcm_stop_xrun(pcm); } EXPORT_SYMBOL(amdtp_stream_pcm_abort); diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 7ac94439e758..48d6dca471c6 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -131,14 +131,8 @@ static void isight_samples(struct isight *isight, static void isight_pcm_abort(struct isight *isight) { - unsigned long flags; - - if (ACCESS_ONCE(isight->pcm_active)) { - snd_pcm_stream_lock_irqsave(isight->pcm, flags); - if (snd_pcm_running(isight->pcm)) - snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); - } + if (ACCESS_ONCE(isight->pcm_active)) + snd_pcm_stop_xrun(isight->pcm); } static void isight_dropped_samples(struct isight *isight, unsigned int total) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index ac66b3228a34..ff9f9f1c0391 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -769,10 +769,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) s->number); ds->drained_count++; if (ds->drained_count > 20) { - unsigned long flags; - snd_pcm_stream_lock_irqsave(s, flags); - snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(s, flags); + snd_pcm_stop_xrun(s); continue; } } else { diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 7895c5d300c7..9c1c4452a8ee 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -688,9 +688,7 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) if (! dma->substream || ! dma->running) return; dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); - snd_pcm_stream_lock(dma->substream); - snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock(dma->substream); + snd_pcm_stop_xrun(dma->substream); } /* diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 3c3241309a30..b2f63e0727de 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -638,9 +638,7 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip, if (! dma->substream || ! dma->running) return; dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); - snd_pcm_stream_lock(dma->substream); - snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock(dma->substream); + snd_pcm_stop_xrun(dma->substream); } /* diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index b79a2a864513..33fb3bb133df 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -80,9 +80,7 @@ static void atmel_pcm_dma_irq(u32 ssc_sr, /* stop RX and capture: will be enabled again at restart */ ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); - snd_pcm_stream_lock(substream); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock(substream); + snd_pcm_stop_xrun(substream); /* now drain RHR and read status to remove xrun condition */ ssc_readx(prtd->ssc->regs, SSC_RHR); diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index a609aafc994d..b2b108805b24 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -151,14 +151,7 @@ static const struct snd_pcm_hardware fsl_dma_hardware = { */ static void fsl_dma_abort_stream(struct snd_pcm_substream *substream) { - unsigned long flags; - - snd_pcm_stream_lock_irqsave(substream, flags); - - if (snd_pcm_running(substream)) - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - - snd_pcm_stream_unlock_irqrestore(substream, flags); + snd_pcm_stop_xrun(substream); } /** diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index ba40489b2de4..36f4115eb1cd 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -679,25 +679,16 @@ int usb6fire_pcm_init(struct sfire_chip *chip) void usb6fire_pcm_abort(struct sfire_chip *chip) { struct pcm_runtime *rt = chip->pcm; - unsigned long flags; int i; if (rt) { rt->panic = true; - if (rt->playback.instance) { - snd_pcm_stream_lock_irqsave(rt->playback.instance, flags); - snd_pcm_stop(rt->playback.instance, - SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags); - } + if (rt->playback.instance) + snd_pcm_stop_xrun(rt->playback.instance); - if (rt->capture.instance) { - snd_pcm_stream_lock_irqsave(rt->capture.instance, flags); - snd_pcm_stop(rt->capture.instance, - SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags); - } + if (rt->capture.instance) + snd_pcm_stop_xrun(rt->capture.instance); for (i = 0; i < PCM_N_URBS; i++) { usb_poison_urb(&rt->in_urbs[i].instance); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index a4679913b0aa..03b074419964 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -391,9 +391,7 @@ static void snd_complete_urb(struct urb *urb) usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); if (ep->data_subs && ep->data_subs->pcm_substream) { substream = ep->data_subs->pcm_substream; - snd_pcm_stream_lock_irqsave(substream, flags); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(substream, flags); + snd_pcm_stop_xrun(substream); } exit_clear: diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index a1bab149df4d..9581089c28c5 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -613,24 +613,14 @@ static int start_usb_playback(struct ua101 *ua) static void abort_alsa_capture(struct ua101 *ua) { - unsigned long flags; - - if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) { - snd_pcm_stream_lock_irqsave(ua->capture.substream, flags); - snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags); - } + if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) + snd_pcm_stop_xrun(ua->capture.substream); } static void abort_alsa_playback(struct ua101 *ua) { - unsigned long flags; - - if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) { - snd_pcm_stream_lock_irqsave(ua->playback.substream, flags); - snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags); - } + if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) + snd_pcm_stop_xrun(ua->playback.substream); } static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index a63330dd1407..61d5dc2a3421 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -272,13 +272,8 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y) for (s = 0; s < 4; s++) { struct snd_usX2Y_substream *subs = usX2Y->subs[s]; if (subs) { - if (atomic_read(&subs->state) >= state_PRERUNNING) { - unsigned long flags; - - snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags); - snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); - snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags); - } + if (atomic_read(&subs->state) >= state_PRERUNNING) + snd_pcm_stop_xrun(subs->pcm_substream); for (u = 0; u < NRURBS; u++) { struct urb *urb = subs->urb[u]; if (NULL != urb) -- GitLab From d4b8fc66f770e9b79830cfe6c342846293b99fda Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 9 Nov 2014 18:21:23 +0100 Subject: [PATCH 4025/9457] ALSA: usb-audio: Allow multiple entries for the same iface in composite quirk Currently the composite quirk doesn't work when multiple entries are assigned to the same interface because it marks the interface as claimed then checks whether the interface has been already claimed for the secondary entry. But, if you look at the code, you'll notice that multiple entries are allowed if the entry is the current interface; i.e. the current behavior is anyway inconsistent, and this is an unintended shortcoming. This patch fixes the problem by marking the relevant interfaces as claimed after applying the all composite entries. This fix will be needed for the upcoming enhancements for Digidesign Mbox 1 quirks. Reviewed-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index d2aa45a8d895..e9ff3a6c60e4 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -58,9 +58,17 @@ static int create_composite_quirk(struct snd_usb_audio *chip, err = snd_usb_create_quirk(chip, iface, driver, quirk); if (err < 0) return err; - if (quirk->ifnum != probed_ifnum) + } + + for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { + iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); + if (!iface) + continue; + if (quirk->ifnum != probed_ifnum && + !usb_interface_claimed(iface)) usb_driver_claim_interface(driver, iface, (void *)-1L); } + return 0; } -- GitLab From 863e88f255dac0657e57d5f1a1f95ee8733f8c13 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:45 +0100 Subject: [PATCH 4026/9457] mac802154: move mac pib attributes into wpan_dev This patch moves all mac pib attributes into the wpan_dev struct. Furthermore we can easier access these attributes over the netdev 802154_ptr pointer. Currently this is only possible over a complicated callback structure in mac802154 because subif data structure is accessable inside mac802154 only. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 24 ++++++++++++---- net/mac802154/ieee802154_i.h | 10 ------- net/mac802154/iface.c | 55 ++++++++++++++++++++---------------- net/mac802154/mib.c | 10 +++---- net/mac802154/rx.c | 7 +++-- 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 9d99b9655760..ac8dd3b8669d 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -52,14 +52,9 @@ struct wpan_phy { u32 channels_supported[32]; s8 transmit_power; u8 cca_mode; - u8 min_be; - u8 max_be; - u8 csma_retries; - s8 frame_retries; __le64 perm_extended_addr; - bool lbt; s32 cca_ed_level; struct device dev; @@ -69,6 +64,25 @@ struct wpan_phy { struct wpan_dev { struct wpan_phy *wpan_phy; + + /* MAC PIB */ + __le16 pan_id; + __le16 short_addr; + __le64 extended_addr; + + /* MAC BSN field */ + u8 bsn; + /* MAC DSN field */ + u8 dsn; + + u8 min_be; + u8 max_be; + u8 csma_retries; + s8 frame_retries; + + bool lbt; + + bool promiscuous_mode; }; #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4acacea0d371..803f529e2c45 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -84,18 +84,8 @@ struct ieee802154_sub_if_data { spinlock_t mib_lock; - __le16 pan_id; - __le16 short_addr; - __le64 extended_addr; - bool promiscuous_mode; - struct ieee802154_mac_params mac_params; - /* MAC BSN field */ - u8 bsn; - /* MAC DSN field */ - u8 dsn; - /* protects sec from concurrent access by netlink. access by * encrypt/decrypt/header_create safe without additional protection. */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 384f4bb3c99b..6669da7446f2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -35,16 +35,17 @@ static int mac802154_wpan_update_llsec(struct net_device *dev) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); + struct wpan_dev *wpan_dev = &sdata->wpan_dev; int rc = 0; if (ops->llsec) { struct ieee802154_llsec_params params; int changed = 0; - params.pan_id = sdata->pan_id; + params.pan_id = wpan_dev->pan_id; changed |= IEEE802154_LLSEC_PARAM_PAN_ID; - params.hwaddr = sdata->extended_addr; + params.hwaddr = wpan_dev->extended_addr; changed |= IEEE802154_LLSEC_PARAM_HWADDR; rc = ops->llsec->set_params(dev, ¶ms, changed); @@ -57,6 +58,7 @@ static int mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct wpan_dev *wpan_dev = &sdata->wpan_dev; struct sockaddr_ieee802154 *sa = (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; @@ -68,8 +70,8 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { u16 pan_id, short_addr; - pan_id = le16_to_cpu(sdata->pan_id); - short_addr = le16_to_cpu(sdata->short_addr); + pan_id = le16_to_cpu(wpan_dev->pan_id); + short_addr = le16_to_cpu(wpan_dev->short_addr); if (pan_id == IEEE802154_PANID_BROADCAST || short_addr == IEEE802154_ADDR_BROADCAST) { err = -EADDRNOTAVAIL; @@ -96,8 +98,8 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; } - sdata->pan_id = cpu_to_le16(sa->addr.pan_id); - sdata->short_addr = cpu_to_le16(sa->addr.short_addr); + wpan_dev->pan_id = cpu_to_le16(sa->addr.pan_id); + wpan_dev->short_addr = cpu_to_le16(sa->addr.short_addr); err = mac802154_wpan_update_llsec(dev); break; @@ -121,7 +123,7 @@ static int mac802154_wpan_mac_addr(struct net_device *dev, void *p) return -EINVAL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - sdata->extended_addr = extended_addr; + sdata->wpan_dev.extended_addr = extended_addr; return mac802154_wpan_update_llsec(dev); } @@ -172,6 +174,7 @@ static int mac802154_wpan_open(struct net_device *dev) int rc; struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; + struct wpan_dev *wpan_dev = &sdata->wpan_dev; struct wpan_phy *phy = sdata->local->phy; rc = mac802154_slave_open(dev); @@ -181,21 +184,22 @@ static int mac802154_wpan_open(struct net_device *dev) mutex_lock(&phy->pib_lock); if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { - rc = drv_set_promiscuous_mode(local, sdata->promiscuous_mode); + rc = drv_set_promiscuous_mode(local, + wpan_dev->promiscuous_mode); if (rc < 0) goto out; } if (local->hw.flags & IEEE802154_HW_AFILT) { - rc = drv_set_pan_id(local, sdata->pan_id); + rc = drv_set_pan_id(local, wpan_dev->pan_id); if (rc < 0) goto out; - rc = drv_set_extended_addr(local, sdata->extended_addr); + rc = drv_set_extended_addr(local, wpan_dev->extended_addr); if (rc < 0) goto out; - rc = drv_set_short_addr(local, sdata->short_addr); + rc = drv_set_short_addr(local, wpan_dev->short_addr); if (rc < 0) goto out; } @@ -288,6 +292,7 @@ static int mac802154_header_create(struct sk_buff *skb, { struct ieee802154_hdr hdr; struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct wpan_dev *wpan_dev = &sdata->wpan_dev; struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; @@ -306,17 +311,17 @@ static int mac802154_header_create(struct sk_buff *skb, if (!saddr) { spin_lock_bh(&sdata->mib_lock); - if (sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || - sdata->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || - sdata->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { + if (wpan_dev->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || + wpan_dev->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || + wpan_dev->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { hdr.source.mode = IEEE802154_ADDR_LONG; - hdr.source.extended_addr = sdata->extended_addr; + hdr.source.extended_addr = wpan_dev->extended_addr; } else { hdr.source.mode = IEEE802154_ADDR_SHORT; - hdr.source.short_addr = sdata->short_addr; + hdr.source.short_addr = wpan_dev->short_addr; } - hdr.source.pan_id = sdata->pan_id; + hdr.source.pan_id = wpan_dev->pan_id; spin_unlock_bh(&sdata->mib_lock); } else { @@ -396,11 +401,13 @@ static void ieee802154_if_setup(struct net_device *dev) static int ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) { + struct wpan_dev *wpan_dev = &sdata->wpan_dev; + /* set some type-dependent values */ sdata->vif.type = type; - get_random_bytes(&sdata->bsn, 1); - get_random_bytes(&sdata->dsn, 1); + get_random_bytes(&wpan_dev->bsn, 1); + get_random_bytes(&wpan_dev->dsn, 1); /* defaults per 802.15.4-2011 */ sdata->mac_params.min_be = 3; @@ -409,9 +416,9 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) /* for compatibility, actual default is 3 */ sdata->mac_params.frame_retries = -1; - ieee802154_be64_to_le64(&sdata->extended_addr, sdata->dev->dev_addr); - sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); - sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); + ieee802154_be64_to_le64(&wpan_dev->extended_addr, sdata->dev->dev_addr); + wpan_dev->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); + wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); switch (type) { case IEEE802154_DEV_WPAN: @@ -419,7 +426,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) sdata->dev->destructor = mac802154_wpan_free; sdata->dev->netdev_ops = &mac802154_wpan_ops; sdata->dev->ml_priv = &mac802154_mlme_wpan; - sdata->promiscuous_mode = false; + wpan_dev->promiscuous_mode = false; spin_lock_init(&sdata->mib_lock); mutex_init(&sdata->sec_mtx); @@ -429,7 +436,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) case IEEE802154_DEV_MONITOR: sdata->dev->destructor = free_netdev; sdata->dev->netdev_ops = &mac802154_monitor_ops; - sdata->promiscuous_mode = true; + wpan_dev->promiscuous_mode = true; break; default: BUG(); diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c index 6fa749154baf..3596b29ead6b 100644 --- a/net/mac802154/mib.c +++ b/net/mac802154/mib.c @@ -33,7 +33,7 @@ void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) BUG_ON(dev->type != ARPHRD_IEEE802154); spin_lock_bh(&sdata->mib_lock); - sdata->short_addr = val; + sdata->wpan_dev.short_addr = val; spin_unlock_bh(&sdata->mib_lock); } @@ -45,7 +45,7 @@ __le16 mac802154_dev_get_short_addr(const struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); spin_lock_bh(&sdata->mib_lock); - ret = sdata->short_addr; + ret = sdata->wpan_dev.short_addr; spin_unlock_bh(&sdata->mib_lock); return ret; @@ -59,7 +59,7 @@ __le16 mac802154_dev_get_pan_id(const struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); spin_lock_bh(&sdata->mib_lock); - ret = sdata->pan_id; + ret = sdata->wpan_dev.pan_id; spin_unlock_bh(&sdata->mib_lock); return ret; @@ -72,7 +72,7 @@ void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) BUG_ON(dev->type != ARPHRD_IEEE802154); spin_lock_bh(&sdata->mib_lock); - sdata->pan_id = val; + sdata->wpan_dev.pan_id = val; spin_unlock_bh(&sdata->mib_lock); } @@ -82,7 +82,7 @@ u8 mac802154_dev_get_dsn(const struct net_device *dev) BUG_ON(dev->type != ARPHRD_IEEE802154); - return sdata->dsn++; + return sdata->wpan_dev.dsn++; } void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 4b54cf33e562..b18e755c38ce 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -42,6 +42,7 @@ static int ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, const struct ieee802154_hdr *hdr) { + struct wpan_dev *wpan_dev = &sdata->wpan_dev; __le16 span, sshort; int rc; @@ -49,8 +50,8 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, spin_lock_bh(&sdata->mib_lock); - span = sdata->pan_id; - sshort = sdata->short_addr; + span = wpan_dev->pan_id; + sshort = wpan_dev->short_addr; switch (mac_cb(skb)->dest.mode) { case IEEE802154_ADDR_NONE: @@ -65,7 +66,7 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, if (mac_cb(skb)->dest.pan_id != span && mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) skb->pkt_type = PACKET_OTHERHOST; - else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) + else if (mac_cb(skb)->dest.extended_addr == wpan_dev->extended_addr) skb->pkt_type = PACKET_HOST; else skb->pkt_type = PACKET_OTHERHOST; -- GitLab From 5fb3f026ae15827fe32e34adafce0d0f63ad0366 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:46 +0100 Subject: [PATCH 4027/9457] mac802154: remove mac_params in sdata This patch removes the mac_params from subif data struct. Instead we manipulate the wpan attributes directly. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 2 -- net/mac802154/iface.c | 19 +++++++++---------- net/mac802154/mac_cmd.c | 26 ++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 803f529e2c45..e22f509af72b 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -84,8 +84,6 @@ struct ieee802154_sub_if_data { spinlock_t mib_lock; - struct ieee802154_mac_params mac_params; - /* protects sec from concurrent access by netlink. access by * encrypt/decrypt/header_create safe without additional protection. */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 6669da7446f2..c0b96cf525d6 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -205,22 +205,21 @@ static int mac802154_wpan_open(struct net_device *dev) } if (local->hw.flags & IEEE802154_HW_LBT) { - rc = drv_set_lbt_mode(local, sdata->mac_params.lbt); + rc = drv_set_lbt_mode(local, wpan_dev->lbt); if (rc < 0) goto out; } if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { - rc = drv_set_csma_params(local, sdata->mac_params.min_be, - sdata->mac_params.max_be, - sdata->mac_params.csma_retries); + rc = drv_set_csma_params(local, wpan_dev->min_be, + wpan_dev->max_be, + wpan_dev->csma_retries); if (rc < 0) goto out; } if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { - rc = drv_set_max_frame_retries(local, - sdata->mac_params.frame_retries); + rc = drv_set_max_frame_retries(local, wpan_dev->frame_retries); if (rc < 0) goto out; } @@ -410,11 +409,11 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) get_random_bytes(&wpan_dev->dsn, 1); /* defaults per 802.15.4-2011 */ - sdata->mac_params.min_be = 3; - sdata->mac_params.max_be = 5; - sdata->mac_params.csma_retries = 4; + wpan_dev->min_be = 3; + wpan_dev->max_be = 5; + wpan_dev->csma_retries = 4; /* for compatibility, actual default is 3 */ - sdata->mac_params.frame_retries = -1; + wpan_dev->frame_retries = -1; ieee802154_be64_to_le64(&wpan_dev->extended_addr, sdata->dev->dev_addr); wpan_dev->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index 00b2b214770e..b8bd95263aab 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -72,10 +72,21 @@ static int mac802154_set_mac_params(struct net_device *dev, { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct ieee802154_local *local = sdata->local; + struct wpan_dev *wpan_dev = &sdata->wpan_dev; int ret; mutex_lock(&sdata->local->iflist_mtx); - sdata->mac_params = *params; + /* PHY */ + wpan_dev->wpan_phy->transmit_power = params->transmit_power; + wpan_dev->wpan_phy->cca_mode = params->cca_mode; + wpan_dev->wpan_phy->cca_ed_level = params->cca_ed_level; + + /* MAC */ + wpan_dev->min_be = params->min_be; + wpan_dev->max_be = params->max_be; + wpan_dev->csma_retries = params->csma_retries; + wpan_dev->frame_retries = params->frame_retries; + wpan_dev->lbt = params->lbt; mutex_unlock(&sdata->local->iflist_mtx); if (local->hw.flags & IEEE802154_HW_TXPOWER) { @@ -103,9 +114,20 @@ static void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_mac_params *params) { struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); + struct wpan_dev *wpan_dev = &sdata->wpan_dev; mutex_lock(&sdata->local->iflist_mtx); - *params = sdata->mac_params; + /* PHY */ + params->transmit_power = wpan_dev->wpan_phy->transmit_power; + params->cca_mode = wpan_dev->wpan_phy->cca_mode; + params->cca_ed_level = wpan_dev->wpan_phy->cca_ed_level; + + /* MAC */ + params->min_be = wpan_dev->min_be; + params->max_be = wpan_dev->max_be; + params->csma_retries = wpan_dev->csma_retries; + params->frame_retries = wpan_dev->frame_retries; + params->lbt = wpan_dev->lbt; mutex_unlock(&sdata->local->iflist_mtx); } -- GitLab From f601379fa113906b8bf4389a62002def283519c9 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:47 +0100 Subject: [PATCH 4028/9457] ieee802154: rename wpan_phy_alloc This patch renames the wpan_phy_alloc function to wpan_phy_new. This naming convention is like wireless and "wiphy_new" function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 2 +- net/ieee802154/core.c | 4 ++-- net/mac802154/main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index ac8dd3b8669d..72c4723a1206 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -88,7 +88,7 @@ struct wpan_dev { #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) struct wpan_phy * -wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size); +wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size); static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) { phy->dev.parent = dev; diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index d1cd0edfb149..a3aa23f8c36c 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -70,7 +70,7 @@ int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), EXPORT_SYMBOL(wpan_phy_for_each); struct wpan_phy * -wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size) +wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size) { static atomic_t wpan_phy_counter = ATOMIC_INIT(0); struct cfg802154_registered_device *rdev; @@ -105,7 +105,7 @@ wpan_phy_alloc(const struct cfg802154_ops *ops, size_t priv_size) return &rdev->wpan_phy; } -EXPORT_SYMBOL(wpan_phy_alloc); +EXPORT_SYMBOL(wpan_phy_new); int wpan_phy_register(struct wpan_phy *phy) { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 7d0ff7fd2cd4..234084d26906 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -86,7 +86,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; - phy = wpan_phy_alloc(&mac802154_config_ops, priv_size); + phy = wpan_phy_new(&mac802154_config_ops, priv_size); if (!phy) { pr_err("failure to allocate master IEEE802.15.4 device\n"); return NULL; -- GitLab From f3ada640c25f2d57beef79b7b98619748be3f3ca Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:48 +0100 Subject: [PATCH 4029/9457] ieee802154: add cfg802154_registered_device list This patch adds a new cfg802154_rdev_list to remember all registered cfg802154_registered_device structs. This is needed to prepare the upcomming nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/core.c | 45 ++++++++++++++++++++++++++++++++++++++++++- net/ieee802154/core.h | 1 + 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index a3aa23f8c36c..11a1d2ed5b26 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -18,11 +18,16 @@ #include #include +#include #include "ieee802154.h" #include "sysfs.h" #include "core.h" +/* RCU-protected (and RTNL for writers) */ +static LIST_HEAD(cfg802154_rdev_list); +static int cfg802154_rdev_list_generation; + static int wpan_phy_match(struct device *dev, const void *data) { return !strcmp(dev_name(dev), (const char *)data); @@ -109,13 +114,51 @@ EXPORT_SYMBOL(wpan_phy_new); int wpan_phy_register(struct wpan_phy *phy) { - return device_add(&phy->dev); + struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(phy); + int ret; + + rtnl_lock(); + ret = device_add(&phy->dev); + if (ret) { + rtnl_unlock(); + return ret; + } + + list_add_rcu(&rdev->list, &cfg802154_rdev_list); + cfg802154_rdev_list_generation++; + + /* TODO phy registered lock */ + rtnl_unlock(); + + /* TODO nl802154 phy notify */ + + return 0; } EXPORT_SYMBOL(wpan_phy_register); void wpan_phy_unregister(struct wpan_phy *phy) { + struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(phy); + + /* TODO open count */ + + rtnl_lock(); + /* TODO nl802154 phy notify */ + /* TODO phy registered lock */ + + /* TODO WARN_ON wpan_dev_list */ + + /* First remove the hardware from everywhere, this makes + * it impossible to find from userspace. + */ + list_del_rcu(&rdev->list); + synchronize_rcu(); + + cfg802154_rdev_list_generation++; + device_del(&phy->dev); + + rtnl_unlock(); } EXPORT_SYMBOL(wpan_phy_unregister); diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index fea60b3a8846..38887cb2eaf4 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -5,6 +5,7 @@ struct cfg802154_registered_device { const struct cfg802154_ops *ops; + struct list_head list; /* wpan_phy index, internal only */ int wpan_phy_idx; -- GitLab From 190ac1ca33442dc25a172ece0f34746a7e1514f3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:49 +0100 Subject: [PATCH 4030/9457] ieee802154: add iftype to wpan_dev This patch adds an iftype argument to the wpan_dev. This is needed to get the interface type from netdev ieee802154_ptr. The subif data struct can only accessible in mac802154 branch. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 1 + net/mac802154/iface.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 72c4723a1206..7e1bc21423b0 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -64,6 +64,7 @@ struct wpan_phy { struct wpan_dev { struct wpan_phy *wpan_phy; + int iftype; /* MAC PIB */ __le16 pan_id; diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index c0b96cf525d6..4630ceb25ad2 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -404,6 +404,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) /* set some type-dependent values */ sdata->vif.type = type; + sdata->wpan_dev.iftype = type; get_random_bytes(&wpan_dev->bsn, 1); get_random_bytes(&wpan_dev->dsn, 1); -- GitLab From fcf39e6e88e9492f6688ec8ba4e1be622b904232 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:50 +0100 Subject: [PATCH 4031/9457] ieee802154: add wpan_dev_list This patch adds a wpan_dev_list list into cfg802154_registered_device struct. Also adding new wpan_dev into this list while cfg802154_netdev_notifier_call. This behaviour is mostly grab from wireless core.c implementation and is needed for preparing nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 6 +++ net/ieee802154/core.c | 95 +++++++++++++++++++++++++++++++++++++++-- net/ieee802154/core.h | 11 +++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 7e1bc21423b0..e5570e011116 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -66,6 +66,12 @@ struct wpan_dev { struct wpan_phy *wpan_phy; int iftype; + /* the remainder of this struct should be private to cfg802154 */ + struct list_head list; + struct net_device *netdev; + + u32 identifier; + /* MAC PIB */ __le16 pan_id; __le16 short_addr; diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 11a1d2ed5b26..3ee00bf0e514 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -102,12 +102,15 @@ wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size) mutex_init(&rdev->wpan_phy.pib_lock); + INIT_LIST_HEAD(&rdev->wpan_dev_list); device_initialize(&rdev->wpan_phy.dev); dev_set_name(&rdev->wpan_phy.dev, "wpan-phy%d", rdev->wpan_phy_idx); rdev->wpan_phy.dev.class = &wpan_phy_class; rdev->wpan_phy.dev.platform_data = rdev; + init_waitqueue_head(&rdev->dev_wait); + return &rdev->wpan_phy; } EXPORT_SYMBOL(wpan_phy_new); @@ -140,13 +143,18 @@ void wpan_phy_unregister(struct wpan_phy *phy) { struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(phy); - /* TODO open count */ + wait_event(rdev->dev_wait, ({ + int __count; + rtnl_lock(); + __count = rdev->opencount; + rtnl_unlock(); + __count == 0; })); rtnl_lock(); /* TODO nl802154 phy notify */ /* TODO phy registered lock */ - /* TODO WARN_ON wpan_dev_list */ + WARN_ON(!list_empty(&rdev->wpan_dev_list)); /* First remove the hardware from everywhere, this makes * it impossible to find from userspace. @@ -173,6 +181,79 @@ void cfg802154_dev_free(struct cfg802154_registered_device *rdev) kfree(rdev); } +static void +cfg802154_update_iface_num(struct cfg802154_registered_device *rdev, + int iftype, int num) +{ + ASSERT_RTNL(); + + rdev->num_running_ifaces += num; +} + +static int cfg802154_netdev_notifier_call(struct notifier_block *nb, + unsigned long state, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + struct cfg802154_registered_device *rdev; + + if (!wpan_dev) + return NOTIFY_DONE; + + rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy); + + /* TODO WARN_ON unspec type */ + + switch (state) { + /* TODO NETDEV_DEVTYPE */ + case NETDEV_REGISTER: + wpan_dev->identifier = ++rdev->wpan_dev_id; + list_add_rcu(&wpan_dev->list, &rdev->wpan_dev_list); + rdev->devlist_generation++; + + wpan_dev->netdev = dev; + break; + case NETDEV_DOWN: + cfg802154_update_iface_num(rdev, wpan_dev->iftype, -1); + + rdev->opencount--; + wake_up(&rdev->dev_wait); + break; + case NETDEV_UP: + cfg802154_update_iface_num(rdev, wpan_dev->iftype, 1); + + rdev->opencount++; + break; + case NETDEV_UNREGISTER: + /* It is possible to get NETDEV_UNREGISTER + * multiple times. To detect that, check + * that the interface is still on the list + * of registered interfaces, and only then + * remove and clean it up. + */ + if (!list_empty(&wpan_dev->list)) { + list_del_rcu(&wpan_dev->list); + rdev->devlist_generation++; + } + /* synchronize (so that we won't find this netdev + * from other code any more) and then clear the list + * head so that the above code can safely check for + * !list_empty() to avoid double-cleanup. + */ + synchronize_rcu(); + INIT_LIST_HEAD(&wpan_dev->list); + break; + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block cfg802154_netdev_notifier = { + .notifier_call = cfg802154_netdev_notifier_call, +}; + static int __init wpan_phy_class_init(void) { int rc; @@ -181,11 +262,18 @@ static int __init wpan_phy_class_init(void) if (rc) goto err; - rc = ieee802154_nl_init(); + rc = register_netdevice_notifier(&cfg802154_netdev_notifier); if (rc) goto err_nl; + rc = ieee802154_nl_init(); + if (rc) + goto err_notifier; + return 0; + +err_notifier: + unregister_netdevice_notifier(&cfg802154_netdev_notifier); err_nl: wpan_phy_sysfs_exit(); err: @@ -196,6 +284,7 @@ subsys_initcall(wpan_phy_class_init); static void __exit wpan_phy_class_exit(void) { ieee802154_nl_exit(); + unregister_netdevice_notifier(&cfg802154_netdev_notifier); wpan_phy_sysfs_exit(); } module_exit(wpan_phy_class_exit); diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index 38887cb2eaf4..e708d9d5878b 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -10,6 +10,17 @@ struct cfg802154_registered_device { /* wpan_phy index, internal only */ int wpan_phy_idx; + /* also protected by devlist_mtx */ + int opencount; + wait_queue_head_t dev_wait; + + /* protected by RTNL only */ + int num_running_ifaces; + + /* associated wpan interfaces, protected by rtnl or RCU */ + struct list_head wpan_dev_list; + int devlist_generation, wpan_dev_id; + /* must be last because of the way we do wpan_phy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ -- GitLab From a6fd693f6b862cd73fc90849353492406cfba5f6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:51 +0100 Subject: [PATCH 4032/9457] ieee802154: sysfs add wpan_phy index and name This patch adds new sysfs entries for wpan_phy index and name. This needed for the new 802.15.4 userspace tool. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/sysfs.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/net/ieee802154/sysfs.c b/net/ieee802154/sysfs.c index 88199980dae9..1613b9c65dfa 100644 --- a/net/ieee802154/sysfs.c +++ b/net/ieee802154/sysfs.c @@ -27,6 +27,27 @@ dev_to_rdev(struct device *dev) wpan_phy.dev); } +#define SHOW_FMT(name, fmt, member) \ +static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ +} \ +static DEVICE_ATTR_RO(name) + +SHOW_FMT(index, "%d", wpan_phy_idx); + +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct wpan_phy *wpan_phy = &dev_to_rdev(dev)->wpan_phy; + + return sprintf(buf, "%s\n", dev_name(&wpan_phy->dev)); +} +static DEVICE_ATTR_RO(name); + #define MASTER_SHOW_COMPLEX(name, format_string, args...) \ static ssize_t name ## _show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -78,6 +99,9 @@ static void wpan_phy_release(struct device *dev) } static struct attribute *pmib_attrs[] = { + &dev_attr_index.attr, + &dev_attr_name.attr, + /* below will be removed soon */ &dev_attr_current_channel.attr, &dev_attr_current_page.attr, &dev_attr_channels_supported.attr, -- GitLab From 3ae75e02c34b5b8d521b0470522e540512ce24e3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:52 +0100 Subject: [PATCH 4033/9457] ieee802154: add new nl802154 header This patch adds the new userspace header for nl802154. We don't place this header in include/uapi now. This header could be modified in the next time. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- MAINTAINERS | 1 + include/net/nl802154.h | 122 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 include/net/nl802154.h diff --git a/MAINTAINERS b/MAINTAINERS index b42eb50b7426..7ec37a396ffe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4699,6 +4699,7 @@ F: net/mac802154/ F: drivers/net/ieee802154/ F: include/linux/nl802154.h F: include/linux/ieee802154.h +F: include/net/nl802154.h F: include/net/mac802154.h F: include/net/af_ieee802154.h F: include/net/cfg802154.h diff --git a/include/net/nl802154.h b/include/net/nl802154.h new file mode 100644 index 000000000000..6dbd406ca41b --- /dev/null +++ b/include/net/nl802154.h @@ -0,0 +1,122 @@ +#ifndef __NL802154_H +#define __NL802154_H +/* + * 802.15.4 netlink interface public header + * + * Copyright 2014 Alexander Aring + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#define NL802154_GENL_NAME "nl802154" + +enum nl802154_commands { +/* don't change the order or add anything between, this is ABI! */ +/* currently we don't shipping this file via uapi, ignore the above one */ + NL802154_CMD_UNSPEC, + + NL802154_CMD_GET_WPAN_PHY, /* can dump */ + NL802154_CMD_SET_WPAN_PHY, + NL802154_CMD_NEW_WPAN_PHY, + NL802154_CMD_DEL_WPAN_PHY, + + NL802154_CMD_GET_INTERFACE, /* can dump */ + NL802154_CMD_SET_INTERFACE, + NL802154_CMD_NEW_INTERFACE, + NL802154_CMD_DEL_INTERFACE, + + NL802154_CMD_SET_CHANNEL, + + NL802154_CMD_SET_PAN_ID, + NL802154_CMD_SET_SHORT_ADDR, + + NL802154_CMD_SET_TX_POWER, + NL802154_CMD_SET_CCA_MODE, + NL802154_CMD_SET_CCA_ED_LEVEL, + + NL802154_CMD_SET_MAX_FRAME_RETRIES, + + NL802154_CMD_SET_BACKOFF_EXPONENT, + NL802154_CMD_SET_MAX_CSMA_BACKOFFS, + + NL802154_CMD_SET_LBT_MODE, + + /* add new commands above here */ + + /* used to define NL802154_CMD_MAX below */ + __NL802154_CMD_AFTER_LAST, + NL802154_CMD_MAX = __NL802154_CMD_AFTER_LAST - 1 +}; + +enum nl802154_attrs { +/* don't change the order or add anything between, this is ABI! */ +/* currently we don't shipping this file via uapi, ignore the above one */ + NL802154_ATTR_UNSPEC, + + NL802154_ATTR_WPAN_PHY, + NL802154_ATTR_WPAN_PHY_NAME, + + NL802154_ATTR_IFINDEX, + NL802154_ATTR_IFNAME, + NL802154_ATTR_IFTYPE, + + NL802154_ATTR_WPAN_DEV, + + NL802154_ATTR_PAGE, + NL802154_ATTR_CHANNEL, + + NL802154_ATTR_PAN_ID, + NL802154_ATTR_SHORT_ADDR, + + NL802154_ATTR_TX_POWER, + + NL802154_ATTR_CCA_MODE, + NL802154_ATTR_CCA_MODE3_AND, + NL802154_ATTR_CCA_ED_LEVEL, + + NL802154_ATTR_MAX_FRAME_RETRIES, + + NL802154_ATTR_MAX_BE, + NL802154_ATTR_MIN_BE, + NL802154_ATTR_MAX_CSMA_BACKOFFS, + + NL802154_ATTR_LBT_MODE, + + NL802154_ATTR_GENERATION, + + NL802154_ATTR_CHANNELS_SUPPORTED, + NL802154_ATTR_SUPPORTED_CHANNEL, + + NL802154_ATTR_EXTENDED_ADDR, + + /* add attributes here, update the policy in nl802154.c */ + + __NL802154_ATTR_AFTER_LAST, + NL802154_ATTR_MAX = __NL802154_ATTR_AFTER_LAST - 1 +}; + +enum nl802154_iftype { + /* for backwards compatibility TODO */ + NL802154_IFTYPE_UNSPEC = -1, + + NL802154_IFTYPE_NODE, + NL802154_IFTYPE_MONITOR, + NL802154_IFTYPE_COORD, + + /* keep last */ + NUM_NL802154_IFTYPES, + NL802154_IFTYPE_MAX = NUM_NL802154_IFTYPES - 1 +}; + +#endif /* __NL802154_H */ -- GitLab From 79fe1a2aa7b504c68642e510154f17e2de60da60 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:53 +0100 Subject: [PATCH 4034/9457] ieee802154: add nl802154 framework This patch adds a basic nl802154 framework. Most of this code was grabbed from nl80211 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/Makefile | 2 +- net/ieee802154/core.c | 28 +++- net/ieee802154/core.h | 4 + net/ieee802154/ieee802154.h | 2 +- net/ieee802154/netlink.c | 2 +- net/ieee802154/nl802154.c | 309 ++++++++++++++++++++++++++++++++++++ net/ieee802154/nl802154.h | 7 + 7 files changed, 350 insertions(+), 4 deletions(-) create mode 100644 net/ieee802154/nl802154.c create mode 100644 net/ieee802154/nl802154.h diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index 38354d4a70cb..9f6970f2a28b 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ - header_ops.o sysfs.o + header_ops.o sysfs.o nl802154.o af_802154-y := af_ieee802154.o raw.o dgram.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index 3ee00bf0e514..ae5ecbc2ca0a 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -21,11 +21,12 @@ #include #include "ieee802154.h" +#include "nl802154.h" #include "sysfs.h" #include "core.h" /* RCU-protected (and RTNL for writers) */ -static LIST_HEAD(cfg802154_rdev_list); +LIST_HEAD(cfg802154_rdev_list); static int cfg802154_rdev_list_generation; static int wpan_phy_match(struct device *dev, const void *data) @@ -74,6 +75,23 @@ int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), } EXPORT_SYMBOL(wpan_phy_for_each); +struct cfg802154_registered_device * +cfg802154_rdev_by_wpan_phy_idx(int wpan_phy_idx) +{ + struct cfg802154_registered_device *result = NULL, *rdev; + + ASSERT_RTNL(); + + list_for_each_entry(rdev, &cfg802154_rdev_list, list) { + if (rdev->wpan_phy_idx == wpan_phy_idx) { + result = rdev; + break; + } + } + + return result; +} + struct wpan_phy * wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size) { @@ -270,8 +288,15 @@ static int __init wpan_phy_class_init(void) if (rc) goto err_notifier; + rc = nl802154_init(); + if (rc) + goto err_ieee802154_nl; + return 0; +err_ieee802154_nl: + ieee802154_nl_exit(); + err_notifier: unregister_netdevice_notifier(&cfg802154_netdev_notifier); err_nl: @@ -283,6 +308,7 @@ subsys_initcall(wpan_phy_class_init); static void __exit wpan_phy_class_exit(void) { + nl802154_exit(); ieee802154_nl_exit(); unregister_netdevice_notifier(&cfg802154_netdev_notifier); wpan_phy_sysfs_exit(); diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index e708d9d5878b..c8319bf1b61a 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -35,7 +35,11 @@ wpan_phy_to_rdev(struct wpan_phy *wpan_phy) wpan_phy); } +extern struct list_head cfg802154_rdev_list; + /* free object */ void cfg802154_dev_free(struct cfg802154_registered_device *rdev); +struct cfg802154_registered_device * +cfg802154_rdev_by_wpan_phy_idx(int wpan_phy_idx); #endif /* __IEEE802154_CORE_H */ diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h index 42ae63a345ab..a5d7515b7f62 100644 --- a/net/ieee802154/ieee802154.h +++ b/net/ieee802154/ieee802154.h @@ -15,7 +15,7 @@ #define IEEE_802154_LOCAL_H int __init ieee802154_nl_init(void); -void __exit ieee802154_nl_exit(void); +void ieee802154_nl_exit(void); #define IEEE802154_OP(_cmd, _func) \ { \ diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 6c3c2595a201..63ee7d66950e 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -155,7 +155,7 @@ int __init ieee802154_nl_init(void) ieee802154_mcgrps); } -void __exit ieee802154_nl_exit(void) +void ieee802154_nl_exit(void) { genl_unregister_family(&nl802154_family); } diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c new file mode 100644 index 000000000000..5dec0bb5bb55 --- /dev/null +++ b/net/ieee802154/nl802154.c @@ -0,0 +1,309 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Alexander Aring + * + * Based on: net/wireless/nl80211.c + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "nl802154.h" +#include "core.h" + +static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + +static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + +/* the netlink family */ +static struct genl_family nl802154_fam = { + .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ + .name = NL802154_GENL_NAME, /* have users key off the name instead */ + .hdrsize = 0, /* no private header */ + .version = 1, /* no particular meaning now */ + .maxattr = NL802154_ATTR_MAX, + .netnsok = true, + .pre_doit = nl802154_pre_doit, + .post_doit = nl802154_post_doit, +}; + +/* multicast groups */ +enum nl802154_multicast_groups { + NL802154_MCGRP_CONFIG, +}; + +static const struct genl_multicast_group nl802154_mcgrps[] = { + [NL802154_MCGRP_CONFIG] = { .name = "config", }, +}; + +/* returns ERR_PTR values */ +static struct wpan_dev * +__cfg802154_wpan_dev_from_attrs(struct net *netns, struct nlattr **attrs) +{ + struct cfg802154_registered_device *rdev; + struct wpan_dev *result = NULL; + bool have_ifidx = attrs[NL802154_ATTR_IFINDEX]; + bool have_wpan_dev_id = attrs[NL802154_ATTR_WPAN_DEV]; + u64 wpan_dev_id; + int wpan_phy_idx = -1; + int ifidx = -1; + + ASSERT_RTNL(); + + if (!have_ifidx && !have_wpan_dev_id) + return ERR_PTR(-EINVAL); + + if (have_ifidx) + ifidx = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]); + if (have_wpan_dev_id) { + wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]); + wpan_phy_idx = wpan_dev_id >> 32; + } + + list_for_each_entry(rdev, &cfg802154_rdev_list, list) { + struct wpan_dev *wpan_dev; + + /* TODO netns compare */ + + if (have_wpan_dev_id && rdev->wpan_phy_idx != wpan_phy_idx) + continue; + + list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) { + if (have_ifidx && wpan_dev->netdev && + wpan_dev->netdev->ifindex == ifidx) { + result = wpan_dev; + break; + } + if (have_wpan_dev_id && + wpan_dev->identifier == (u32)wpan_dev_id) { + result = wpan_dev; + break; + } + } + + if (result) + break; + } + + if (result) + return result; + + return ERR_PTR(-ENODEV); +} + +static struct cfg802154_registered_device * +__cfg802154_rdev_from_attrs(struct net *netns, struct nlattr **attrs) +{ + struct cfg802154_registered_device *rdev = NULL, *tmp; + struct net_device *netdev; + + ASSERT_RTNL(); + + if (!attrs[NL802154_ATTR_WPAN_PHY] && + !attrs[NL802154_ATTR_IFINDEX] && + !attrs[NL802154_ATTR_WPAN_DEV]) + return ERR_PTR(-EINVAL); + + if (attrs[NL802154_ATTR_WPAN_PHY]) + rdev = cfg802154_rdev_by_wpan_phy_idx( + nla_get_u32(attrs[NL802154_ATTR_WPAN_PHY])); + + if (attrs[NL802154_ATTR_WPAN_DEV]) { + u64 wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]); + struct wpan_dev *wpan_dev; + bool found = false; + + tmp = cfg802154_rdev_by_wpan_phy_idx(wpan_dev_id >> 32); + if (tmp) { + /* make sure wpan_dev exists */ + list_for_each_entry(wpan_dev, &tmp->wpan_dev_list, list) { + if (wpan_dev->identifier != (u32)wpan_dev_id) + continue; + found = true; + break; + } + + if (!found) + tmp = NULL; + + if (rdev && tmp != rdev) + return ERR_PTR(-EINVAL); + rdev = tmp; + } + } + + if (attrs[NL802154_ATTR_IFINDEX]) { + int ifindex = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]); + + netdev = __dev_get_by_index(netns, ifindex); + if (netdev) { + if (netdev->ieee802154_ptr) + tmp = wpan_phy_to_rdev( + netdev->ieee802154_ptr->wpan_phy); + else + tmp = NULL; + + /* not wireless device -- return error */ + if (!tmp) + return ERR_PTR(-EINVAL); + + /* mismatch -- return error */ + if (rdev && tmp != rdev) + return ERR_PTR(-EINVAL); + + rdev = tmp; + } + } + + if (!rdev) + return ERR_PTR(-ENODEV); + + /* TODO netns compare */ + + return rdev; +} + +/* This function returns a pointer to the driver + * that the genl_info item that is passed refers to. + * + * The result of this can be a PTR_ERR and hence must + * be checked with IS_ERR() for errors. + */ +static struct cfg802154_registered_device * +cfg802154_get_dev_from_info(struct net *netns, struct genl_info *info) +{ + return __cfg802154_rdev_from_attrs(netns, info->attrs); +} + +/* policy for the attributes */ +static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { +}; + +/* message building helper */ +static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq, + int flags, u8 cmd) +{ + /* since there is no private header just add the generic one */ + return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd); +} + +#define NL802154_FLAG_NEED_WPAN_PHY 0x01 +#define NL802154_FLAG_NEED_NETDEV 0x02 +#define NL802154_FLAG_NEED_RTNL 0x04 +#define NL802154_FLAG_CHECK_NETDEV_UP 0x08 +#define NL802154_FLAG_NEED_NETDEV_UP (NL802154_FLAG_NEED_NETDEV |\ + NL802154_FLAG_CHECK_NETDEV_UP) +#define NL802154_FLAG_NEED_WPAN_DEV 0x10 +#define NL802154_FLAG_NEED_WPAN_DEV_UP (NL802154_FLAG_NEED_WPAN_DEV |\ + NL802154_FLAG_CHECK_NETDEV_UP) + +static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg802154_registered_device *rdev; + struct wpan_dev *wpan_dev; + struct net_device *dev; + bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL; + + if (rtnl) + rtnl_lock(); + + if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) { + rdev = cfg802154_get_dev_from_info(genl_info_net(info), info); + if (IS_ERR(rdev)) { + if (rtnl) + rtnl_unlock(); + return PTR_ERR(rdev); + } + info->user_ptr[0] = rdev; + } else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV || + ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) { + ASSERT_RTNL(); + wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info), + info->attrs); + if (IS_ERR(wpan_dev)) { + if (rtnl) + rtnl_unlock(); + return PTR_ERR(wpan_dev); + } + + dev = wpan_dev->netdev; + rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy); + + if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) { + if (!dev) { + if (rtnl) + rtnl_unlock(); + return -EINVAL; + } + + info->user_ptr[1] = dev; + } else { + info->user_ptr[1] = wpan_dev; + } + + if (dev) { + if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP && + !netif_running(dev)) { + if (rtnl) + rtnl_unlock(); + return -ENETDOWN; + } + + dev_hold(dev); + } + + info->user_ptr[0] = rdev; + } + + return 0; +} + +static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + if (info->user_ptr[1]) { + if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) { + struct wpan_dev *wpan_dev = info->user_ptr[1]; + + if (wpan_dev->netdev) + dev_put(wpan_dev->netdev); + } else { + dev_put(info->user_ptr[1]); + } + } + + if (ops->internal_flags & NL802154_FLAG_NEED_RTNL) + rtnl_unlock(); +} + +static const struct genl_ops nl802154_ops[] = { +}; + +/* initialisation/exit functions */ +int nl802154_init(void) +{ + return genl_register_family_with_ops_groups(&nl802154_fam, nl802154_ops, + nl802154_mcgrps); +} + +void nl802154_exit(void) +{ + genl_unregister_family(&nl802154_fam); +} diff --git a/net/ieee802154/nl802154.h b/net/ieee802154/nl802154.h new file mode 100644 index 000000000000..3846a89d0958 --- /dev/null +++ b/net/ieee802154/nl802154.h @@ -0,0 +1,7 @@ +#ifndef __IEEE802154_NL802154_H +#define __IEEE802154_NL802154_H + +int nl802154_init(void); +void nl802154_exit(void); + +#endif /* __IEEE802154_NL802154_H */ -- GitLab From ca20ce201c8d4123de0fd2b0d59ea19b0160d88f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:54 +0100 Subject: [PATCH 4035/9457] ieee802154: add wpan_phy dump support This patch adds support for dumping wpan_phy attributes via nl802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/core.c | 2 +- net/ieee802154/core.h | 1 + net/ieee802154/nl802154.c | 221 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+), 1 deletion(-) diff --git a/net/ieee802154/core.c b/net/ieee802154/core.c index ae5ecbc2ca0a..18bc7e738507 100644 --- a/net/ieee802154/core.c +++ b/net/ieee802154/core.c @@ -27,7 +27,7 @@ /* RCU-protected (and RTNL for writers) */ LIST_HEAD(cfg802154_rdev_list); -static int cfg802154_rdev_list_generation; +int cfg802154_rdev_list_generation; static int wpan_phy_match(struct device *dev, const void *data) { diff --git a/net/ieee802154/core.h b/net/ieee802154/core.h index c8319bf1b61a..f3e95580caee 100644 --- a/net/ieee802154/core.h +++ b/net/ieee802154/core.h @@ -36,6 +36,7 @@ wpan_phy_to_rdev(struct wpan_phy *wpan_phy) } extern struct list_head cfg802154_rdev_list; +extern int cfg802154_rdev_list_generation; /* free object */ void cfg802154_dev_free(struct cfg802154_registered_device *rdev); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 5dec0bb5bb55..32e884732eb1 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -193,6 +193,22 @@ cfg802154_get_dev_from_info(struct net *netns, struct genl_info *info) /* policy for the attributes */ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { + [NL802154_ATTR_WPAN_PHY] = { .type = NLA_U32 }, + [NL802154_ATTR_WPAN_PHY_NAME] = { .type = NLA_NUL_STRING, + .len = 20-1 }, + + [NL802154_ATTR_IFINDEX] = { .type = NLA_U32 }, + + [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 }, + + [NL802154_ATTR_PAGE] = { .type = NLA_U8, }, + [NL802154_ATTR_CHANNEL] = { .type = NLA_U8, }, + + [NL802154_ATTR_TX_POWER] = { .type = NLA_S8, }, + + [NL802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, + + [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, }; /* message building helper */ @@ -203,6 +219,201 @@ static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq, return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd); } +static int +nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev, + struct sk_buff *msg) +{ + struct nlattr *nl_page; + unsigned long page; + + nl_page = nla_nest_start(msg, NL802154_ATTR_CHANNELS_SUPPORTED); + if (!nl_page) + return -ENOBUFS; + + for (page = 0; page < WPAN_NUM_PAGES; page++) { + if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL, + rdev->wpan_phy.channels_supported[page])) + return -ENOBUFS; + } + nla_nest_end(msg, nl_page); + + return 0; +} + +static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev, + enum nl802154_commands cmd, + struct sk_buff *msg, u32 portid, u32 seq, + int flags) +{ + void *hdr; + + hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); + if (!hdr) + return -ENOBUFS; + + if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) || + nla_put_string(msg, NL802154_ATTR_WPAN_PHY_NAME, + wpan_phy_name(&rdev->wpan_phy)) || + nla_put_u32(msg, NL802154_ATTR_GENERATION, + cfg802154_rdev_list_generation)) + goto nla_put_failure; + + if (cmd != NL802154_CMD_NEW_WPAN_PHY) + goto finish; + + /* DUMP PHY PIB */ + + /* current channel settings */ + if (nla_put_u8(msg, NL802154_ATTR_PAGE, + rdev->wpan_phy.current_page) || + nla_put_u8(msg, NL802154_ATTR_CHANNEL, + rdev->wpan_phy.current_channel)) + goto nla_put_failure; + + /* supported channels array */ + if (nl802154_send_wpan_phy_channels(rdev, msg)) + goto nla_put_failure; + + /* cca mode */ + if (nla_put_u8(msg, NL802154_ATTR_CCA_MODE, + rdev->wpan_phy.cca_mode)) + goto nla_put_failure; + + if (nla_put_s8(msg, NL802154_ATTR_TX_POWER, + rdev->wpan_phy.transmit_power)) + goto nla_put_failure; + +finish: + return genlmsg_end(msg, hdr); + +nla_put_failure: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +struct nl802154_dump_wpan_phy_state { + s64 filter_wpan_phy; + long start; + +}; + +static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb, + struct netlink_callback *cb, + struct nl802154_dump_wpan_phy_state *state) +{ + struct nlattr **tb = nl802154_fam.attrbuf; + int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl802154_fam.hdrsize, + tb, nl802154_fam.maxattr, nl802154_policy); + + /* TODO check if we can handle error here, + * we have no backward compatibility + */ + if (ret) + return 0; + + if (tb[NL802154_ATTR_WPAN_PHY]) + state->filter_wpan_phy = nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]); + if (tb[NL802154_ATTR_WPAN_DEV]) + state->filter_wpan_phy = nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]) >> 32; + if (tb[NL802154_ATTR_IFINDEX]) { + struct net_device *netdev; + struct cfg802154_registered_device *rdev; + int ifidx = nla_get_u32(tb[NL802154_ATTR_IFINDEX]); + + /* TODO netns */ + netdev = __dev_get_by_index(&init_net, ifidx); + if (!netdev) + return -ENODEV; + if (netdev->ieee802154_ptr) { + rdev = wpan_phy_to_rdev( + netdev->ieee802154_ptr->wpan_phy); + state->filter_wpan_phy = rdev->wpan_phy_idx; + } + } + + return 0; +} + +static int +nl802154_dump_wpan_phy(struct sk_buff *skb, struct netlink_callback *cb) +{ + int idx = 0, ret; + struct nl802154_dump_wpan_phy_state *state = (void *)cb->args[0]; + struct cfg802154_registered_device *rdev; + + rtnl_lock(); + if (!state) { + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) { + rtnl_unlock(); + return -ENOMEM; + } + state->filter_wpan_phy = -1; + ret = nl802154_dump_wpan_phy_parse(skb, cb, state); + if (ret) { + kfree(state); + rtnl_unlock(); + return ret; + } + cb->args[0] = (long)state; + } + + list_for_each_entry(rdev, &cfg802154_rdev_list, list) { + /* TODO net ns compare */ + if (++idx <= state->start) + continue; + if (state->filter_wpan_phy != -1 && + state->filter_wpan_phy != rdev->wpan_phy_idx) + continue; + /* attempt to fit multiple wpan_phy data chunks into the skb */ + ret = nl802154_send_wpan_phy(rdev, + NL802154_CMD_NEW_WPAN_PHY, + skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); + if (ret < 0) { + if ((ret == -ENOBUFS || ret == -EMSGSIZE) && + !skb->len && cb->min_dump_alloc < 4096) { + cb->min_dump_alloc = 4096; + rtnl_unlock(); + return 1; + } + idx--; + break; + } + break; + } + rtnl_unlock(); + + state->start = idx; + + return skb->len; +} + +static int nl802154_dump_wpan_phy_done(struct netlink_callback *cb) +{ + kfree((void *)cb->args[0]); + return 0; +} + +static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *msg; + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + if (nl802154_send_wpan_phy(rdev, NL802154_CMD_NEW_WPAN_PHY, msg, + info->snd_portid, info->snd_seq, 0) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } + + return genlmsg_reply(msg, info); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -294,6 +505,16 @@ static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb, } static const struct genl_ops nl802154_ops[] = { + { + .cmd = NL802154_CMD_GET_WPAN_PHY, + .doit = nl802154_get_wpan_phy, + .dumpit = nl802154_dump_wpan_phy, + .done = nl802154_dump_wpan_phy_done, + .policy = nl802154_policy, + /* can be retrieved by unprivileged users */ + .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ -- GitLab From 4b96aea0fcdbba18287f6cca87c8d796f33157b6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:55 +0100 Subject: [PATCH 4036/9457] ieee802154: add wpan_dev dump support This patch adds support for wpan_dev dump via nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/nl802154.c | 145 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 32e884732eb1..46df7dca92d9 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -198,6 +198,8 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { .len = 20-1 }, [NL802154_ATTR_IFINDEX] = { .type = NLA_U32 }, + [NL802154_ATTR_IFTYPE] = { .type = NLA_U32 }, + [NL802154_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 }, @@ -209,6 +211,18 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = { [NL802154_ATTR_CCA_MODE] = { .type = NLA_U8, }, [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, + + [NL802154_ATTR_PAN_ID] = { .type = NLA_U16, }, + [NL802154_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 }, + [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, }, + + [NL802154_ATTR_MIN_BE] = { .type = NLA_U8, }, + [NL802154_ATTR_MAX_BE] = { .type = NLA_U8, }, + [NL802154_ATTR_MAX_CSMA_BACKOFFS] = { .type = NLA_U8, }, + + [NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, }, + + [NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, }, }; /* message building helper */ @@ -414,6 +428,128 @@ static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info) return genlmsg_reply(msg, info); } +static inline u64 wpan_dev_id(struct wpan_dev *wpan_dev) +{ + return (u64)wpan_dev->identifier | + ((u64)wpan_phy_to_rdev(wpan_dev->wpan_phy)->wpan_phy_idx << 32); +} + +static int +nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, + struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + struct net_device *dev = wpan_dev->netdev; + void *hdr; + + hdr = nl802154hdr_put(msg, portid, seq, flags, + NL802154_CMD_NEW_INTERFACE); + if (!hdr) + return -1; + + if (dev && + (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex) || + nla_put_string(msg, NL802154_ATTR_IFNAME, dev->name))) + goto nla_put_failure; + + if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) || + nla_put_u32(msg, NL802154_ATTR_IFTYPE, wpan_dev->iftype) || + nla_put_u64(msg, NL802154_ATTR_WPAN_DEV, wpan_dev_id(wpan_dev)) || + nla_put_u32(msg, NL802154_ATTR_GENERATION, + rdev->devlist_generation ^ + (cfg802154_rdev_list_generation << 2))) + goto nla_put_failure; + + /* address settings */ + if (nla_put_le64(msg, NL802154_ATTR_EXTENDED_ADDR, + wpan_dev->extended_addr) || + nla_put_le16(msg, NL802154_ATTR_SHORT_ADDR, + wpan_dev->short_addr) || + nla_put_le16(msg, NL802154_ATTR_PAN_ID, wpan_dev->pan_id)) + goto nla_put_failure; + + /* ARET handling */ + if (nla_put_s8(msg, NL802154_ATTR_MAX_FRAME_RETRIES, + wpan_dev->frame_retries) || + nla_put_u8(msg, NL802154_ATTR_MAX_BE, wpan_dev->max_be) || + nla_put_u8(msg, NL802154_ATTR_MAX_CSMA_BACKOFFS, + wpan_dev->csma_retries) || + nla_put_u8(msg, NL802154_ATTR_MIN_BE, wpan_dev->min_be)) + goto nla_put_failure; + + /* listen before transmit */ + if (nla_put_u8(msg, NL802154_ATTR_LBT_MODE, wpan_dev->lbt)) + goto nla_put_failure; + + return genlmsg_end(msg, hdr); + +nla_put_failure: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int +nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) +{ + int wp_idx = 0; + int if_idx = 0; + int wp_start = cb->args[0]; + int if_start = cb->args[1]; + struct cfg802154_registered_device *rdev; + struct wpan_dev *wpan_dev; + + rtnl_lock(); + list_for_each_entry(rdev, &cfg802154_rdev_list, list) { + /* TODO netns compare */ + if (wp_idx < wp_start) { + wp_idx++; + continue; + } + if_idx = 0; + + list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) { + if (if_idx < if_start) { + if_idx++; + continue; + } + if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + rdev, wpan_dev) < 0) { + goto out; + } + if_idx++; + } + + wp_idx++; + } +out: + rtnl_unlock(); + + cb->args[0] = wp_idx; + cb->args[1] = if_idx; + + return skb->len; +} + +static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *msg; + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct wpan_dev *wdev = info->user_ptr[1]; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0, + rdev, wdev) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } + + return genlmsg_reply(msg, info); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -515,6 +651,15 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_GET_INTERFACE, + .doit = nl802154_get_interface, + .dumpit = nl802154_dump_interface, + .policy = nl802154_policy, + /* can be retrieved by unprivileged users */ + .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ -- GitLab From b03c9cccfa808f1b314097b162a36c3937cb818e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:56 +0100 Subject: [PATCH 4037/9457] mac820154: don't set monitor dev_addr This patch removes the setting of dev_addr on a monitor device. This address should be zero. A monitor should only sniff and send raw frames out. The address should be never used by upper layers and receiving frame parsing. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 4630ceb25ad2..d635f367b03f 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -416,12 +416,14 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) /* for compatibility, actual default is 3 */ wpan_dev->frame_retries = -1; - ieee802154_be64_to_le64(&wpan_dev->extended_addr, sdata->dev->dev_addr); wpan_dev->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); switch (type) { case IEEE802154_DEV_WPAN: + ieee802154_be64_to_le64(&wpan_dev->extended_addr, + sdata->dev->dev_addr); + sdata->dev->header_ops = &mac802154_header_ops; sdata->dev->destructor = mac802154_wpan_free; sdata->dev->netdev_ops = &mac802154_wpan_ops; -- GitLab From 7bea1ea7b4c16af7c9263648e10f7edc88e5fc21 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:57 +0100 Subject: [PATCH 4038/9457] ieee802154: netlink add rtnl lock This patch adds rtnl lock hold mechanism while accessing wpan_dev attributes. Furthermore these attributes should be protected by rtnl lock and netif_running only. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/nl-mac.c | 6 ++++++ net/mac802154/mac_cmd.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index 7127b9d1a684..50e9863823a5 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -113,7 +113,9 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid, if (ops->get_mac_params) { struct ieee802154_mac_params params; + rtnl_lock(); ops->get_mac_params(dev, ¶ms); + rtnl_unlock(); if (nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, params.transmit_power) || @@ -348,8 +350,10 @@ int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } + rtnl_lock(); ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page, bcn_ord, sf_ord, pan_coord, blx, coord_realign); + rtnl_unlock(); /* FIXME: add validation for unused parameters to be sane * for SoftMAC @@ -497,6 +501,7 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) phy = dev->ieee802154_ptr->wpan_phy; get_device(&phy->dev); + rtnl_lock(); ops->get_mac_params(dev, ¶ms); if (info->attrs[IEEE802154_ATTR_TXPOWER]) @@ -524,6 +529,7 @@ int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info) params.frame_retries = nla_get_s8(info->attrs[IEEE802154_ATTR_FRAME_RETRIES]); rc = ops->set_mac_params(dev, ¶ms); + rtnl_unlock(); wpan_phy_put(phy); dev_put(dev); diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c index b8bd95263aab..6aacb1816889 100644 --- a/net/mac802154/mac_cmd.c +++ b/net/mac802154/mac_cmd.c @@ -39,6 +39,8 @@ static int mac802154_mlme_start_req(struct net_device *dev, struct ieee802154_mlme_ops *ops = ieee802154_mlme_ops(dev); int rc = 0; + ASSERT_RTNL(); + BUG_ON(addr->mode != IEEE802154_ADDR_SHORT); mac802154_dev_set_pan_id(dev, addr->pan_id); @@ -75,7 +77,8 @@ static int mac802154_set_mac_params(struct net_device *dev, struct wpan_dev *wpan_dev = &sdata->wpan_dev; int ret; - mutex_lock(&sdata->local->iflist_mtx); + ASSERT_RTNL(); + /* PHY */ wpan_dev->wpan_phy->transmit_power = params->transmit_power; wpan_dev->wpan_phy->cca_mode = params->cca_mode; @@ -87,7 +90,6 @@ static int mac802154_set_mac_params(struct net_device *dev, wpan_dev->csma_retries = params->csma_retries; wpan_dev->frame_retries = params->frame_retries; wpan_dev->lbt = params->lbt; - mutex_unlock(&sdata->local->iflist_mtx); if (local->hw.flags & IEEE802154_HW_TXPOWER) { ret = drv_set_tx_power(local, params->transmit_power); @@ -116,7 +118,8 @@ static void mac802154_get_mac_params(struct net_device *dev, struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); struct wpan_dev *wpan_dev = &sdata->wpan_dev; - mutex_lock(&sdata->local->iflist_mtx); + ASSERT_RTNL(); + /* PHY */ params->transmit_power = wpan_dev->wpan_phy->transmit_power; params->cca_mode = wpan_dev->wpan_phy->cca_mode; @@ -128,7 +131,6 @@ static void mac802154_get_mac_params(struct net_device *dev, params->csma_retries = wpan_dev->csma_retries; params->frame_retries = wpan_dev->frame_retries; params->lbt = wpan_dev->lbt; - mutex_unlock(&sdata->local->iflist_mtx); } static struct ieee802154_llsec_ops mac802154_llsec_ops = { -- GitLab From 87023e1058c9ead2314c27761991816b48f949ef Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:58 +0100 Subject: [PATCH 4039/9457] ieee802154: fix iface dump with lowpan This patch adds a hacked solution for an interface dump with a running lowpan interface. This will crash because lowpan and wpan interface use the same arphdr. To change the arphdr will change the UAPI, this patch checks on mtu which should on lowpan interface always different than IEEE802154_MTU. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/nl-mac.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index 50e9863823a5..fe77f0c770b8 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -166,7 +166,10 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) if (!dev) return NULL; - if (dev->type != ARPHRD_IEEE802154) { + /* Check on mtu is currently a hacked solution because lowpan + * and wpan have the same ARPHRD type. + */ + if (dev->type != ARPHRD_IEEE802154 || dev->mtu != IEEE802154_MTU) { dev_put(dev); return NULL; } @@ -448,7 +451,11 @@ int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb) idx = 0; for_each_netdev(net, dev) { - if (idx < s_idx || (dev->type != ARPHRD_IEEE802154)) + /* Check on mtu is currently a hacked solution because lowpan + * and wpan have the same ARPHRD type. + */ + if (idx < s_idx || dev->type != ARPHRD_IEEE802154 || + dev->mtu != IEEE802154_MTU) goto cont; if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid, @@ -782,7 +789,11 @@ ieee802154_llsec_dump_table(struct sk_buff *skb, struct netlink_callback *cb, int rc; for_each_netdev(net, dev) { - if (idx < first_dev || dev->type != ARPHRD_IEEE802154) + /* Check on mtu is currently a hacked solution because lowpan + * and wpan have the same ARPHRD type. + */ + if (idx < first_dev || dev->type != ARPHRD_IEEE802154 || + dev->mtu != IEEE802154_MTU) goto skip; data.ops = ieee802154_mlme_ops(dev); -- GitLab From f7cb96f105fb406e8db5e68e0cdd5067e2556d34 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 9 Nov 2014 08:36:59 +0100 Subject: [PATCH 4040/9457] mac802154: protect address changes via ioctl This patch adds a netif_running check while trying to change the address attributes via ioctl. While netif_running is true these attributes should be only readable. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index d635f367b03f..83715b5ffe43 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -63,6 +63,8 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) (struct sockaddr_ieee802154 *)&ifr->ifr_addr; int err = -ENOIOCTLCMD; + ASSERT_RTNL(); + spin_lock_bh(&sdata->mib_lock); switch (cmd) { @@ -87,6 +89,11 @@ mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; } case SIOCSIFADDR: + if (netif_running(dev)) { + spin_unlock_bh(&sdata->mib_lock); + return -EBUSY; + } + dev_warn(&dev->dev, "Using DEBUGing ioctl SIOCSIFADDR isn't recommended!\n"); if (sa->family != AF_IEEE802154 || -- GitLab From 4307d8f6e5105d7f4baa8cc4f0b56aca048eb024 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 15:37:13 +0200 Subject: [PATCH 4041/9457] amdkfd: Fix sparse warnings in kfd_chardev.c Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 64c73bae960d..3b3fce733136 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -149,7 +149,9 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, } if ((args->ring_base_address) && - (!access_ok(VERIFY_WRITE, args->ring_base_address, sizeof(uint64_t)))) { + (!access_ok(VERIFY_WRITE, + (const void __user *) args->ring_base_address, + sizeof(uint64_t)))) { pr_err("kfd: can't access ring base address\n"); return -EFAULT; } @@ -159,12 +161,16 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, return -EINVAL; } - if (!access_ok(VERIFY_WRITE, args->read_pointer_address, sizeof(uint32_t))) { + if (!access_ok(VERIFY_WRITE, + (const void __user *) args->read_pointer_address, + sizeof(uint32_t))) { pr_err("kfd: can't access read pointer\n"); return -EFAULT; } - if (!access_ok(VERIFY_WRITE, args->write_pointer_address, sizeof(uint32_t))) { + if (!access_ok(VERIFY_WRITE, + (const void __user *) args->write_pointer_address, + sizeof(uint32_t))) { pr_err("kfd: can't access write pointer\n"); return -EFAULT; } @@ -325,7 +331,9 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, } if ((args.ring_base_address) && - (!access_ok(VERIFY_WRITE, args.ring_base_address, sizeof(uint64_t)))) { + (!access_ok(VERIFY_WRITE, + (const void __user *) args.ring_base_address, + sizeof(uint64_t)))) { pr_err("kfd: can't access ring base address\n"); return -EFAULT; } -- GitLab From 16b9201c620a83ebb4613161c974fd7926f22a31 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 15:41:33 +0200 Subject: [PATCH 4042/9457] amdkfd: Fix sparse warnings in kfd_topology.c Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 77cd7d55b39d..5733e2859e8a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -96,7 +96,7 @@ static int kfd_topology_get_crat_acpi(void *crat_image, size_t *size) return -EINVAL; } - if (*size >= crat_table->length && crat_image != 0) + if (*size >= crat_table->length && crat_image != NULL) memcpy(crat_image, crat_table, crat_table->length); *size = crat_table->length; @@ -183,7 +183,7 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) list_for_each_entry(dev, &topology_device_list, list) { if (mem->promixity_domain == i) { props = kfd_alloc_struct(props); - if (props == 0) + if (props == NULL) return -ENOMEM; if (dev->node_props.cpu_cores_count == 0) @@ -231,7 +231,7 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) if (id == dev->node_props.cpu_core_id_base || id == dev->node_props.simd_id_base) { props = kfd_alloc_struct(props); - if (props == 0) + if (props == NULL) return -ENOMEM; props->processor_id_low = id; @@ -282,7 +282,7 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) list_for_each_entry(dev, &topology_device_list, list) { if (id_from == i) { props = kfd_alloc_struct(props); - if (props == 0) + if (props == NULL) return -ENOMEM; props->node_from = id_from; @@ -415,9 +415,9 @@ static struct kfd_topology_device *kfd_create_topology_device(void) struct kfd_topology_device *dev; dev = kfd_alloc_struct(dev); - if (dev == 0) { + if (dev == NULL) { pr_err("No memory to allocate a topology device"); - return 0; + return NULL; } INIT_LIST_HEAD(&dev->mem_props); @@ -428,7 +428,7 @@ static struct kfd_topology_device *kfd_create_topology_device(void) sys_props.num_devices++; return dev; - } +} static int kfd_parse_crat_table(void *crat_image) { @@ -752,11 +752,11 @@ static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev) if (iolink->kobj) { kfd_remove_sysfs_file(iolink->kobj, &iolink->attr); - iolink->kobj = 0; + iolink->kobj = NULL; } kobject_del(dev->kobj_iolink); kobject_put(dev->kobj_iolink); - dev->kobj_iolink = 0; + dev->kobj_iolink = NULL; } if (dev->kobj_cache) { @@ -764,22 +764,22 @@ static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev) if (cache->kobj) { kfd_remove_sysfs_file(cache->kobj, &cache->attr); - cache->kobj = 0; + cache->kobj = NULL; } kobject_del(dev->kobj_cache); kobject_put(dev->kobj_cache); - dev->kobj_cache = 0; + dev->kobj_cache = NULL; } if (dev->kobj_mem) { list_for_each_entry(mem, &dev->mem_props, list) if (mem->kobj) { kfd_remove_sysfs_file(mem->kobj, &mem->attr); - mem->kobj = 0; + mem->kobj = NULL; } kobject_del(dev->kobj_mem); kobject_put(dev->kobj_mem); - dev->kobj_mem = 0; + dev->kobj_mem = NULL; } if (dev->kobj_node) { @@ -788,7 +788,7 @@ static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev) sysfs_remove_file(dev->kobj_node, &dev->attr_props); kobject_del(dev->kobj_node); kobject_put(dev->kobj_node); - dev->kobj_node = 0; + dev->kobj_node = NULL; } } @@ -939,7 +939,7 @@ static int kfd_topology_update_sysfs(void) int ret; pr_info("Creating topology SYSFS entries\n"); - if (sys_props.kobj_topology == 0) { + if (sys_props.kobj_topology == NULL) { sys_props.kobj_topology = kfd_alloc_struct(sys_props.kobj_topology); if (!sys_props.kobj_topology) @@ -989,17 +989,17 @@ static void kfd_topology_release_sysfs(void) if (sys_props.kobj_nodes) { kobject_del(sys_props.kobj_nodes); kobject_put(sys_props.kobj_nodes); - sys_props.kobj_nodes = 0; + sys_props.kobj_nodes = NULL; } kobject_del(sys_props.kobj_topology); kobject_put(sys_props.kobj_topology); - sys_props.kobj_topology = 0; + sys_props.kobj_topology = NULL; } } int kfd_topology_init(void) { - void *crat_image = 0; + void *crat_image = NULL; size_t image_size = 0; int ret; @@ -1094,12 +1094,12 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu) { struct kfd_topology_device *dev; - struct kfd_topology_device *out_dev = 0; + struct kfd_topology_device *out_dev = NULL; BUG_ON(!gpu); list_for_each_entry(dev, &topology_device_list, list) - if (dev->gpu == 0 && dev->node_props.simd_count > 0) { + if (dev->gpu == NULL && dev->node_props.simd_count > 0) { dev->gpu = gpu; out_dev = dev; break; -- GitLab From 5ef360eab7e6e634c22b5821468aae3af205d2fb Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 20 Nov 2014 16:08:14 +0800 Subject: [PATCH 4043/9457] amdkfd: test_kq() can be static Reviewed-by: Alex Deucher Signed-off-by: Fengguang Wu Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 555af4514237..424ddccafd4f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -321,7 +321,7 @@ void kernel_queue_uninit(struct kernel_queue *kq) kfree(kq); } -void test_kq(struct kfd_dev *dev) +static __attribute__((unused)) void test_kq(struct kfd_dev *dev) { struct kernel_queue *kq; uint32_t *buffer, i; -- GitLab From 7347a6cbf1b5672a87975e58c8b99d882b96e9b9 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 20 Nov 2014 17:16:23 +0800 Subject: [PATCH 4044/9457] amdkfd: pqm_get_kernel_queue() can be static Reviewed-by: Alex Deucher Signed-off-by: Fengguang Wu Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index c7859fcc25ce..de2c16345693 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -325,7 +325,8 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, return 0; } -struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm, +static __attribute__((unused)) struct kernel_queue *pqm_get_kernel_queue( + struct process_queue_manager *pqm, unsigned int qid) { struct process_queue_node *pqn; -- GitLab From 585dbf3842a37149410932f5fac2bfe68b9d86c4 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 15:49:49 +0200 Subject: [PATCH 4045/9457] amdkfd: Fix sparse warnings in kfd_flat_memory.c Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c index 2dfc4c0e85a4..66df4da01c29 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c @@ -276,21 +276,22 @@ */ #define MAKE_GPUVM_APP_BASE(gpu_num) \ - (((uint64_t)(gpu_num) << 61) + 0x1000000000000) + (((uint64_t)(gpu_num) << 61) + 0x1000000000000L) #define MAKE_GPUVM_APP_LIMIT(base) \ - (((uint64_t)(base) & 0xFFFFFF0000000000) | 0xFFFFFFFFFF) + (((uint64_t)(base) & \ + 0xFFFFFF0000000000UL) | 0xFFFFFFFFFFL) #define MAKE_SCRATCH_APP_BASE(gpu_num) \ - (((uint64_t)(gpu_num) << 61) + 0x100000000) + (((uint64_t)(gpu_num) << 61) + 0x100000000L) #define MAKE_SCRATCH_APP_LIMIT(base) \ - (((uint64_t)base & 0xFFFFFFFF00000000) | 0xFFFFFFFF) + (((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF) #define MAKE_LDS_APP_BASE(gpu_num) \ (((uint64_t)(gpu_num) << 61) + 0x0) #define MAKE_LDS_APP_LIMIT(base) \ - (((uint64_t)(base) & 0xFFFFFFFF00000000) | 0xFFFFFFFF) + (((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF) int kfd_init_apertures(struct kfd_process *process) { -- GitLab From 20981e68010c66187450b4a5a78b56b99d1f6f59 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 15:50:53 +0200 Subject: [PATCH 4046/9457] amdkfd: is_occupied() can be static Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index 59d240719a08..adc31474e786 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -179,9 +179,9 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, pipe_id, queue_id); } -bool is_occupied(struct mqd_manager *mm, void *mqd, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +static bool is_occupied(struct mqd_manager *mm, void *mqd, + uint64_t queue_address, uint32_t pipe_id, + uint32_t queue_id) { return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, -- GitLab From d80d19bd5064692d40e9190ebadbd381f20d2969 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 15:54:05 +0200 Subject: [PATCH 4047/9457] amdkfd: fence_wait_timeout() can be static Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 8c40d04932b2..718f50e81e28 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -789,8 +789,9 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, return retval; } -int fence_wait_timeout(unsigned int *fence_addr, unsigned int fence_value, - unsigned long timeout) +static int fence_wait_timeout(unsigned int *fence_addr, + unsigned int fence_value, + unsigned long timeout) { BUG_ON(!fence_addr); timeout += jiffies; -- GitLab From 5cd78de5267f36c090043836649b31c12533bbe9 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 20 Nov 2014 16:14:56 +0200 Subject: [PATCH 4048/9457] amdkfd: add __iomem attribute to doorbell_ptr This patch was done due to sparse warning. It changes the definition of doorbell_ptr in queue_properties to be with __iomem attribute, so it would match the type which the doorbell module functions are returning. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 9 ++++----- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 424ddccafd4f..5055fc9c8731 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -66,8 +66,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, if (kq->mqd == NULL) return false; - prop.doorbell_ptr = - (uint32_t *)kfd_get_kernel_doorbell(dev, &prop.doorbell_off); + prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off); if (prop.doorbell_ptr == NULL) goto err_get_kernel_doorbell; @@ -172,7 +171,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq); err_pq_allocate_vidmem: pr_err("kfd: error init pq\n"); - kfd_release_kernel_doorbell(dev, (u32 *)prop.doorbell_ptr); + kfd_release_kernel_doorbell(dev, prop.doorbell_ptr); err_get_kernel_doorbell: pr_err("kfd: error init doorbell"); return false; @@ -195,7 +194,7 @@ static void uninitialize(struct kernel_queue *kq) kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->wptr_mem); kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->pq); kfd_release_kernel_doorbell(kq->dev, - (u32 *)kq->queue->properties.doorbell_ptr); + kq->queue->properties.doorbell_ptr); uninit_queue(kq->queue); } @@ -255,7 +254,7 @@ static void submit_packet(struct kernel_queue *kq) #endif *kq->wptr_kernel = kq->pending_wptr; - write_kernel_doorbell((u32 *)kq->queue->properties.doorbell_ptr, + write_kernel_doorbell(kq->queue->properties.doorbell_ptr, kq->pending_wptr); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 41e608d684b1..d0bcafcf048f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -279,7 +279,7 @@ struct queue_properties { uint32_t queue_percent; uint32_t *read_ptr; uint32_t *write_ptr; - uint32_t *doorbell_ptr; + uint32_t __iomem *doorbell_ptr; uint32_t doorbell_off; bool is_interop; bool is_active; -- GitLab From f5d896bbd03a03bef436d9358599b50962095f38 Mon Sep 17 00:00:00 2001 From: Jay Cornwall Date: Thu, 20 Nov 2014 11:52:16 -0600 Subject: [PATCH 4049/9457] amdkfd: Fix memory leak on process deregistration struct device_process_node was allocated during process registration but not released at process deregistration. Reviewed-by: Alex Deucher Signed-off-by: Jay Cornwall Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 718f50e81e28..bc8961c3e073 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -409,6 +409,7 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm, list_for_each_entry_safe(cur, next, &dqm->queues, list) { if (qpd == cur->qpd) { list_del(&cur->list); + kfree(cur); dqm->processes_count--; goto out; } -- GitLab From 9a5634a72934a566b3e5fdb0e8f345846162f7d3 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Mon, 17 Nov 2014 13:18:32 +0200 Subject: [PATCH 4050/9457] amdkfd: use schedule() in sync_with_hw amdkfd uses cpu_relax() in its sync_with_hw() function. Because cpu_relax() is defined as 'REP; NOP' on x86_64, it will block the CPU from servicing IOMMU PPR requests. This may cause a deadlock, because sync_with_hw() won't be completed until the PPR request has been served. Therefore, we need to use schedule() instead of cpu_relax() as it is the minimum requirement to allow other threads to execute. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 5055fc9c8731..9abac48de499 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "kfd_kernel_queue.h" #include "kfd_priv.h" #include "kfd_device_queue_manager.h" @@ -274,7 +275,7 @@ static int sync_with_hw(struct kernel_queue *kq, unsigned long timeout_ms) *kq->wptr_kernel, *kq->rptr_kernel); return -ETIME; } - cpu_relax(); + schedule(); } return 0; -- GitLab From 52a5fdce136bcaabc719be6e8f141d68426b3c74 Mon Sep 17 00:00:00 2001 From: Alexey Skidanov Date: Wed, 19 Nov 2014 17:07:00 +0200 Subject: [PATCH 4051/9457] amdkfd: Instead of using get function, use container_of Reviewed-by: Alex Deucher Signed-off-by: Alexey Skidanov Signed-off-by: Oded Gabbay --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 21 ++++++++----------- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 ++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index bc8961c3e073..904eb38e3b9f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -67,26 +67,21 @@ static inline unsigned int get_pipes_num_cpsch(void) return PIPE_PER_ME_CP_SCHEDULING; } -static unsigned int get_sh_mem_bases_nybble_64(struct kfd_process *process, - struct kfd_dev *dev) +static inline unsigned int +get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) { - struct kfd_process_device *pdd; uint32_t nybble; - pdd = kfd_get_process_device_data(dev, process, 1); nybble = (pdd->lds_base >> 60) & 0x0E; return nybble; } -static unsigned int get_sh_mem_bases_32(struct kfd_process *process, - struct kfd_dev *dev) +static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) { - struct kfd_process_device *pdd; unsigned int shared_base; - pdd = kfd_get_process_device_data(dev, process, 1); shared_base = (pdd->lds_base >> 16) & 0xFF; return shared_base; @@ -96,10 +91,13 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble); static void init_process_memory(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { + struct kfd_process_device *pdd; unsigned int temp; BUG_ON(!dqm || !qpd); + pdd = qpd_to_pdd(qpd); + /* check if sh_mem_config register already configured */ if (qpd->sh_mem_config == 0) { qpd->sh_mem_config = @@ -111,11 +109,11 @@ static void init_process_memory(struct device_queue_manager *dqm, } if (qpd->pqm->process->is_32bit_user_mode) { - temp = get_sh_mem_bases_32(qpd->pqm->process, dqm->dev); + temp = get_sh_mem_bases_32(pdd); qpd->sh_mem_bases = SHARED_BASE(temp); qpd->sh_mem_config |= PTR32; } else { - temp = get_sh_mem_bases_nybble_64(qpd->pqm->process, dqm->dev); + temp = get_sh_mem_bases_nybble_64(pdd); qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); } @@ -707,8 +705,7 @@ static int stop_cpsch(struct device_queue_manager *dqm) destroy_queues_cpsch(dqm, true); list_for_each_entry(node, &dqm->queues, list) { - pdd = kfd_get_process_device_data(dqm->dev, - node->qpd->pqm->process, 1); + pdd = qpd_to_pdd(node->qpd); pdd->bound = false; } kfd2kgd->free_mem(dqm->dev->kgd, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index d0bcafcf048f..f9fb81e3bb09 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -414,6 +414,8 @@ struct kfd_process_device { bool bound; }; +#define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd) + /* Process data */ struct kfd_process { /* -- GitLab From abc9d3e3b9dc77d7b887ade9f5845a93ce743fd4 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Sun, 9 Nov 2014 22:36:22 +0200 Subject: [PATCH 4052/9457] amdkfd: Clear ctx cb before suspend Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 9beb6f7bba9d..43884ebd4303 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -267,6 +267,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd) if (kfd->init_complete) { kfd->dqm->stop(kfd->dqm); + amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL); amd_iommu_free_device(kfd->pdev); } } -- GitLab From 10239733ee8617bac3f1c1769af43a88ed979324 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 22:15:33 +1000 Subject: [PATCH 4053/9457] powerpc: Remove bootmem allocator At the moment we transition from the memblock alloctor to the bootmem allocator. Gitting rid of the bootmem allocator removes a bunch of complicated code (most of which I owe the dubious honour of being responsible for writing). Signed-off-by: Anton Blanchard Tested-by: Emil Medve Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/setup.h | 3 +- arch/powerpc/kernel/setup_32.c | 5 +- arch/powerpc/kernel/setup_64.c | 3 +- arch/powerpc/mm/init_32.c | 9 - arch/powerpc/mm/mem.c | 62 +---- arch/powerpc/mm/numa.c | 224 +++---------------- arch/powerpc/mm/pgtable_32.c | 3 +- arch/powerpc/mm/pgtable_64.c | 6 +- arch/powerpc/platforms/512x/mpc512x_shared.c | 9 +- 10 files changed, 47 insertions(+), 278 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 88eace4e28c3..98e9c548bd75 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -148,6 +148,7 @@ config PPC select HAVE_ARCH_AUDITSYSCALL select ARCH_SUPPORTS_ATOMIC_RMW select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN + select NO_BOOTMEM config GENERIC_CSUM def_bool CPU_LITTLE_ENDIAN diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index 11ba86e17631..fbdf18cf954c 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h @@ -8,7 +8,6 @@ extern void ppc_printk_progress(char *s, unsigned short hex); extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ -extern int init_bootmem_done; /* set once bootmem is available */ extern unsigned long long memory_limit; extern unsigned long klimit; extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); @@ -24,7 +23,7 @@ extern void reloc_got2(unsigned long); #define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) void check_for_initrd(void); -void do_init_bootmem(void); +void initmem_init(void); void setup_panic(void); #define ARCH_PANIC_TIMEOUT 180 diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 07831ed0d9ef..88a36e64bf9b 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -311,9 +311,8 @@ void __init setup_arch(char **cmdline_p) irqstack_early_init(); - /* set up the bootmem stuff with available memory */ - do_init_bootmem(); - if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); + initmem_init(); + if ( ppc_md.progress ) ppc_md.progress("setup_arch: initmem", 0x3eab); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 615aa904b216..91d9cfaffe6c 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -689,8 +689,7 @@ void __init setup_arch(char **cmdline_p) exc_lvl_early_init(); emergency_stack_init(); - /* set up the bootmem stuff with available memory */ - do_init_bootmem(); + initmem_init(); sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 415a51b028b9..3b3100433c18 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -195,15 +195,6 @@ void __init MMU_init(void) memblock_set_current_limit(lowmem_end_addr); } -/* This is only called until mem_init is done. */ -void __init *early_get_page(void) -{ - if (init_bootmem_done) - return alloc_bootmem_pages(PAGE_SIZE); - else - return __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE)); -} - #ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */ void setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 2add0b7b9f6d..e076d19c095b 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -61,7 +61,6 @@ #define CPU_FTR_NOEXECUTE 0 #endif -int init_bootmem_done; int mem_init_done; unsigned long long memory_limit; @@ -190,70 +189,22 @@ walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, } EXPORT_SYMBOL_GPL(walk_system_ram_range); -/* - * Initialize the bootmem system and give it all the memory we - * have available. If we are using highmem, we only put the - * lowmem into the bootmem system. - */ #ifndef CONFIG_NEED_MULTIPLE_NODES -void __init do_init_bootmem(void) +void __init initmem_init(void) { - unsigned long start, bootmap_pages; - unsigned long total_pages; - struct memblock_region *reg; - int boot_mapsize; - max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; - total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT; + min_low_pfn = MEMORY_START >> PAGE_SHIFT; #ifdef CONFIG_HIGHMEM - total_pages = total_lowmem >> PAGE_SHIFT; max_low_pfn = lowmem_end_addr >> PAGE_SHIFT; #endif - /* - * Find an area to use for the bootmem bitmap. Calculate the size of - * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE. - * Add 1 additional page in case the address isn't page-aligned. - */ - bootmap_pages = bootmem_bootmap_pages(total_pages); - - start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); - - min_low_pfn = MEMORY_START >> PAGE_SHIFT; - boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn); - /* Place all memblock_regions in the same node and merge contiguous * memblock_regions */ memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0); - /* Add all physical memory to the bootmem map, mark each area - * present. - */ -#ifdef CONFIG_HIGHMEM - free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT); - - /* reserve the sections we're already using */ - for_each_memblock(reserved, reg) { - unsigned long top = reg->base + reg->size - 1; - if (top < lowmem_end_addr) - reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); - else if (reg->base < lowmem_end_addr) { - unsigned long trunc_size = lowmem_end_addr - reg->base; - reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT); - } - } -#else - free_bootmem_with_active_regions(0, max_pfn); - - /* reserve the sections we're already using */ - for_each_memblock(reserved, reg) - reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); -#endif /* XXX need to clip this if using highmem? */ sparse_memory_present_with_active_regions(0); - - init_bootmem_done = 1; } /* mark pages that don't exist as nosave */ @@ -369,14 +320,6 @@ void __init paging_init(void) mark_nonram_nosave(); } -static void __init register_page_bootmem_info(void) -{ - int i; - - for_each_online_node(i) - register_page_bootmem_info_node(NODE_DATA(i)); -} - void __init mem_init(void) { /* @@ -389,7 +332,6 @@ void __init mem_init(void) swiotlb_init(0); #endif - register_page_bootmem_info(); high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); set_max_mapnr(max_pfn); free_all_bootmem(); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b9d1dfdbe5bb..2e9ad2d76b75 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -134,28 +134,6 @@ static int __init fake_numa_create_new_node(unsigned long end_pfn, return 0; } -/* - * get_node_active_region - Return active region containing pfn - * Active range returned is empty if none found. - * @pfn: The page to return the region for - * @node_ar: Returned set to the active region containing @pfn - */ -static void __init get_node_active_region(unsigned long pfn, - struct node_active_region *node_ar) -{ - unsigned long start_pfn, end_pfn; - int i, nid; - - for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { - if (pfn >= start_pfn && pfn < end_pfn) { - node_ar->nid = nid; - node_ar->start_pfn = start_pfn; - node_ar->end_pfn = end_pfn; - break; - } - } -} - static void reset_numa_cpu_lookup_table(void) { unsigned int cpu; @@ -928,134 +906,48 @@ static void __init dump_numa_memory_topology(void) } } -/* - * Allocate some memory, satisfying the memblock or bootmem allocator where - * required. nid is the preferred node and end is the physical address of - * the highest address in the node. - * - * Returns the virtual address of the memory. - */ -static void __init *careful_zallocation(int nid, unsigned long size, - unsigned long align, - unsigned long end_pfn) -{ - void *ret; - int new_nid; - unsigned long ret_paddr; - - ret_paddr = __memblock_alloc_base(size, align, end_pfn << PAGE_SHIFT); - - /* retry over all memory */ - if (!ret_paddr) - ret_paddr = __memblock_alloc_base(size, align, memblock_end_of_DRAM()); - - if (!ret_paddr) - panic("numa.c: cannot allocate %lu bytes for node %d", - size, nid); - - ret = __va(ret_paddr); - - /* - * We initialize the nodes in numeric order: 0, 1, 2... - * and hand over control from the MEMBLOCK allocator to the - * bootmem allocator. If this function is called for - * node 5, then we know that all nodes <5 are using the - * bootmem allocator instead of the MEMBLOCK allocator. - * - * So, check the nid from which this allocation came - * and double check to see if we need to use bootmem - * instead of the MEMBLOCK. We don't free the MEMBLOCK memory - * since it would be useless. - */ - new_nid = early_pfn_to_nid(ret_paddr >> PAGE_SHIFT); - if (new_nid < nid) { - ret = __alloc_bootmem_node(NODE_DATA(new_nid), - size, align, 0); - - dbg("alloc_bootmem %p %lx\n", ret, size); - } - - memset(ret, 0, size); - return ret; -} - static struct notifier_block ppc64_numa_nb = { .notifier_call = cpu_numa_callback, .priority = 1 /* Must run before sched domains notifier. */ }; -static void __init mark_reserved_regions_for_nid(int nid) +/* Initialize NODE_DATA for a node on the local memory */ +static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn) { - struct pglist_data *node = NODE_DATA(nid); - struct memblock_region *reg; - - for_each_memblock(reserved, reg) { - unsigned long physbase = reg->base; - unsigned long size = reg->size; - unsigned long start_pfn = physbase >> PAGE_SHIFT; - unsigned long end_pfn = PFN_UP(physbase + size); - struct node_active_region node_ar; - unsigned long node_end_pfn = pgdat_end_pfn(node); - - /* - * Check to make sure that this memblock.reserved area is - * within the bounds of the node that we care about. - * Checking the nid of the start and end points is not - * sufficient because the reserved area could span the - * entire node. - */ - if (end_pfn <= node->node_start_pfn || - start_pfn >= node_end_pfn) - continue; - - get_node_active_region(start_pfn, &node_ar); - while (start_pfn < end_pfn && - node_ar.start_pfn < node_ar.end_pfn) { - unsigned long reserve_size = size; - /* - * if reserved region extends past active region - * then trim size to active region - */ - if (end_pfn > node_ar.end_pfn) - reserve_size = (node_ar.end_pfn << PAGE_SHIFT) - - physbase; - /* - * Only worry about *this* node, others may not - * yet have valid NODE_DATA(). - */ - if (node_ar.nid == nid) { - dbg("reserve_bootmem %lx %lx nid=%d\n", - physbase, reserve_size, node_ar.nid); - reserve_bootmem_node(NODE_DATA(node_ar.nid), - physbase, reserve_size, - BOOTMEM_DEFAULT); - } - /* - * if reserved region is contained in the active region - * then done. - */ - if (end_pfn <= node_ar.end_pfn) - break; - - /* - * reserved region extends past the active region - * get next active region that contains this - * reserved region - */ - start_pfn = node_ar.end_pfn; - physbase = start_pfn << PAGE_SHIFT; - size = size - reserve_size; - get_node_active_region(start_pfn, &node_ar); - } - } + u64 spanned_pages = end_pfn - start_pfn; + const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES); + u64 nd_pa; + void *nd; + int tnid; + + if (spanned_pages) + pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n", + nid, start_pfn << PAGE_SHIFT, + (end_pfn << PAGE_SHIFT) - 1); + else + pr_info("Initmem setup node %d\n", nid); + + nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid); + nd = __va(nd_pa); + + /* report and initialize */ + pr_info(" NODE_DATA [mem %#010Lx-%#010Lx]\n", + nd_pa, nd_pa + nd_size - 1); + tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); + if (tnid != nid) + pr_info(" NODE_DATA(%d) on node %d\n", nid, tnid); + + node_data[nid] = nd; + memset(NODE_DATA(nid), 0, sizeof(pg_data_t)); + NODE_DATA(nid)->node_id = nid; + NODE_DATA(nid)->node_start_pfn = start_pfn; + NODE_DATA(nid)->node_spanned_pages = spanned_pages; } - -void __init do_init_bootmem(void) +void __init initmem_init(void) { int nid, cpu; - min_low_pfn = 0; max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; max_pfn = max_low_pfn; @@ -1064,64 +956,16 @@ void __init do_init_bootmem(void) else dump_numa_memory_topology(); + memblock_dump_all(); + for_each_online_node(nid) { unsigned long start_pfn, end_pfn; - void *bootmem_vaddr; - unsigned long bootmap_pages; get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); - - /* - * Allocate the node structure node local if possible - * - * Be careful moving this around, as it relies on all - * previous nodes' bootmem to be initialized and have - * all reserved areas marked. - */ - NODE_DATA(nid) = careful_zallocation(nid, - sizeof(struct pglist_data), - SMP_CACHE_BYTES, end_pfn); - - dbg("node %d\n", nid); - dbg("NODE_DATA() = %p\n", NODE_DATA(nid)); - - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; - NODE_DATA(nid)->node_start_pfn = start_pfn; - NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; - - if (NODE_DATA(nid)->node_spanned_pages == 0) - continue; - - dbg("start_paddr = %lx\n", start_pfn << PAGE_SHIFT); - dbg("end_paddr = %lx\n", end_pfn << PAGE_SHIFT); - - bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); - bootmem_vaddr = careful_zallocation(nid, - bootmap_pages << PAGE_SHIFT, - PAGE_SIZE, end_pfn); - - dbg("bootmap_vaddr = %p\n", bootmem_vaddr); - - init_bootmem_node(NODE_DATA(nid), - __pa(bootmem_vaddr) >> PAGE_SHIFT, - start_pfn, end_pfn); - - free_bootmem_with_active_regions(nid, end_pfn); - /* - * Be very careful about moving this around. Future - * calls to careful_zallocation() depend on this getting - * done correctly. - */ - mark_reserved_regions_for_nid(nid); + setup_node_data(nid, start_pfn, end_pfn); sparse_memory_present_with_active_regions(nid); } - init_bootmem_done = 1; - - /* - * Now bootmem is initialised we can create the node to cpumask - * lookup tables and setup the cpu callback to populate them. - */ setup_node_to_cpumask_map(); reset_numa_cpu_lookup_table(); diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index cf11342bf519..d545b1231594 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -100,12 +100,11 @@ __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add { pte_t *pte; extern int mem_init_done; - extern void *early_get_page(void); if (mem_init_done) { pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); } else { - pte = (pte_t *)early_get_page(); + pte = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE)); if (pte) clear_page(pte); } diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index c8d709ab489d..cdb19ab859d3 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -75,11 +75,7 @@ static __ref void *early_alloc_pgtable(unsigned long size) { void *pt; - if (init_bootmem_done) - pt = __alloc_bootmem(size, size, __pa(MAX_DMA_ADDRESS)); - else - pt = __va(memblock_alloc_base(size, size, - __pa(MAX_DMA_ADDRESS))); + pt = __va(memblock_alloc_base(size, size, __pa(MAX_DMA_ADDRESS))); memset(pt, 0, size); return pt; diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index e996e007bc44..711f3d352af7 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -297,14 +297,13 @@ static void __init mpc512x_setup_diu(void) * and so negatively affect boot time. Instead we reserve the * already configured frame buffer area so that it won't be * destroyed. The starting address of the area to reserve and - * also it's length is passed to reserve_bootmem(). It will be + * also it's length is passed to memblock_reserve(). It will be * freed later on first open of fbdev, when splash image is not * needed any more. */ if (diu_shared_fb.in_use) { - ret = reserve_bootmem(diu_shared_fb.fb_phys, - diu_shared_fb.fb_len, - BOOTMEM_EXCLUSIVE); + ret = memblock_reserve(diu_shared_fb.fb_phys, + diu_shared_fb.fb_len); if (ret) { pr_err("%s: reserve bootmem failed\n", __func__); diu_shared_fb.in_use = false; -- GitLab From 14ed740957704e8768523899e0fa31972577bf65 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 22:15:34 +1000 Subject: [PATCH 4054/9457] powerpc: Remove some old bootmem related comments Now bootmem is gone from powerpc we can remove comments mentioning it. Signed-off-by: Anton Blanchard Tested-by: Emil Medve Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom.c | 5 +---- arch/powerpc/kernel/rtas.c | 4 ++-- arch/powerpc/kvm/book3s_hv_builtin.c | 2 +- arch/powerpc/mm/hugetlbpage.c | 4 ++-- arch/powerpc/mm/pgtable_64.c | 4 ---- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 099f27e6d1b0..6af05fc1dec9 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -696,10 +696,7 @@ void __init early_init_devtree(void *params) reserve_crashkernel(); early_reserve_mem(); - /* - * Ensure that total memory size is page-aligned, because otherwise - * mark_bootmem() gets upset. - */ + /* Ensure that total memory size is page-aligned. */ limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE); memblock_enforce_memory_limit(limit); diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 8b4c857c1421..4af905e81ab0 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -1091,8 +1091,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) } /* - * Call early during boot, before mem init or bootmem, to retrieve the RTAS - * informations from the device-tree and allocate the RMO buffer for userland + * Call early during boot, before mem init, to retrieve the RTAS + * information from the device-tree and allocate the RMO buffer for userland * accesses. */ void __init rtas_initialize(void) diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 4fdc27c80f4c..e64868c0b8de 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -154,7 +154,7 @@ EXPORT_SYMBOL_GPL(kvm_release_hpt); * kvm_cma_reserve() - reserve area for kvm hash pagetable * * This function reserves memory from early allocator. It should be - * called by arch specific code once the early allocator (memblock or bootmem) + * called by arch specific code once the memblock allocator * has been activated and all other subsystems have already allocated/reserved * memory. */ diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 8aa04f03fd31..b460e723f0ec 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -276,7 +276,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz #ifdef CONFIG_PPC_FSL_BOOK3E /* Build list of addresses of gigantic pages. This function is used in early - * boot before the buddy or bootmem allocator is setup. + * boot before the buddy allocator is setup. */ void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) { @@ -399,7 +399,7 @@ void __init reserve_hugetlb_gpages(void) #else /* !PPC_FSL_BOOK3E */ /* Build list of addresses of gigantic pages. This function is used in early - * boot before the buddy or bootmem allocator is setup. + * boot before the buddy allocator is setup. */ void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) { diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index cdb19ab859d3..aa9173745cf4 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -109,10 +109,6 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags) __pgprot(flags))); } else { #ifdef CONFIG_PPC_MMU_NOHASH - /* Warning ! This will blow up if bootmem is not initialized - * which our ppc64 code is keen to do that, we'll need to - * fix it and/or be more careful - */ pgdp = pgd_offset_k(ea); #ifdef PUD_TABLE_SIZE if (pgd_none(*pgdp)) { -- GitLab From 68cf0d642f62267b960f947370539ff3582c4935 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 22:15:35 +1000 Subject: [PATCH 4055/9457] powerpc: Remove superfluous bootmem includes Lots of places included bootmem.h even when not using bootmem. Signed-off-by: Anton Blanchard Tested-by: Emil Medve Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/crash_dump.c | 1 - arch/powerpc/kernel/irq.c | 1 - arch/powerpc/kernel/pci_64.c | 1 - arch/powerpc/kernel/rtas_pci.c | 1 - arch/powerpc/kernel/setup_32.c | 1 - arch/powerpc/kernel/vdso.c | 1 - arch/powerpc/kvm/book3s_hv_builtin.c | 1 - arch/powerpc/mm/init_32.c | 1 - arch/powerpc/mm/init_64.c | 1 - arch/powerpc/mm/pgtable_64.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_epci.c | 1 - arch/powerpc/platforms/cell/celleb_scc_pciex.c | 1 - arch/powerpc/platforms/maple/pci.c | 1 - arch/powerpc/platforms/powermac/pci.c | 1 - arch/powerpc/platforms/powernv/eeh-ioda.c | 1 - arch/powerpc/platforms/powernv/pci.c | 1 - arch/powerpc/sysdev/fsl_msi.c | 1 - arch/powerpc/sysdev/ipic.c | 1 - arch/powerpc/sysdev/mpic.c | 1 - arch/powerpc/sysdev/mpic_pasemi_msi.c | 1 - arch/powerpc/sysdev/mpic_u3msi.c | 1 - arch/powerpc/sysdev/ppc4xx_msi.c | 1 - arch/powerpc/sysdev/ppc4xx_pci.c | 1 - arch/powerpc/sysdev/qe_lib/qe.c | 1 - arch/powerpc/sysdev/qe_lib/qe_ic.c | 1 - arch/powerpc/sysdev/uic.c | 1 - 26 files changed, 1 insertion(+), 26 deletions(-) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index c78e6dac4d7d..cfa0f81a5bb0 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -12,7 +12,6 @@ #undef DEBUG #include -#include #include #include #include diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 8d87bb162ecd..45096033d37b 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 155013da27e0..ba0f2d6fc27f 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 7c55b86206b3..ce230da2c015 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 88a36e64bf9b..ba3a3c3b8c66 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index f174351842cf..305eb0d9b768 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index e64868c0b8de..3f1bb5a36c27 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 3b3100433c18..a10be665b645 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 3481556a1880..10471f9bb63f 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index aa9173745cf4..e0c718543174 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include #include "mmu_decl.h" diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c index 844c0facb4f7..9438bbed402f 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_epci.c +++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 4278acfa2ede..f22387598040 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index f7136aae8bbf..d3a13067ec42 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 7e868ccf3b0d..04702db35d45 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index eba9cb10619c..db3803e21483 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -11,7 +11,6 @@ * (at your option) any later version. */ -#include #include #include #include diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b2187d0068b8..ba7452708db3 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index de40b48b460e..8f37204bf94f 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -13,7 +13,6 @@ * */ #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index b50f97811c25..b28733727ed3 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 89cec0ed6a58..c4648ad5c1f3 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 15dccd35fa11..428de9d23120 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -16,7 +16,6 @@ #undef DEBUG #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index 623d7fba15b4..4ce8f54f234c 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -10,7 +10,6 @@ */ #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 22b5200636e7..a59f2890897a 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c @@ -22,7 +22,6 @@ */ #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index df6e2fc4ff92..086aca69ecae 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 238a07b97f2c..b584debbcd9c 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index b2b87c30e266..543765e1ef14 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 92033936a8f7..7c37157d4c24 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include -- GitLab From 21098b9e07476deb3f40acd7e51cffbffb4ef865 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 22:15:36 +1000 Subject: [PATCH 4056/9457] powerpc: Move sparse_init() into initmem_init We did part of sparse initialisation in setup_arch and part in initmem_init. Put them together. Signed-off-by: Anton Blanchard Tested-by: Emil Medve Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/setup_64.c | 1 - arch/powerpc/mm/mem.c | 1 + arch/powerpc/mm/numa.c | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 91d9cfaffe6c..6e5310ddf8c7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -690,7 +690,6 @@ void __init setup_arch(char **cmdline_p) emergency_stack_init(); initmem_init(); - sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index e076d19c095b..b7285a5870f8 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -205,6 +205,7 @@ void __init initmem_init(void) /* XXX need to clip this if using highmem? */ sparse_memory_present_with_active_regions(0); + sparse_init(); } /* mark pages that don't exist as nosave */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 2e9ad2d76b75..417b0a523a47 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -966,6 +966,8 @@ void __init initmem_init(void) sparse_memory_present_with_active_regions(nid); } + sparse_init(); + setup_node_to_cpumask_map(); reset_numa_cpu_lookup_table(); -- GitLab From 6e4c632cdff7bf0238a2543dfe98bd1ad40313c2 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 22:15:37 +1000 Subject: [PATCH 4057/9457] powerpc: make __ffs return unsigned long I'm seeing a build warning in mm/nobootmem.c after removing bootmem: mm/nobootmem.c: In function '__free_pages_memory': include/linux/kernel.h:713:17: warning: comparison of distinct pointer types lacks a cast [enabled by default] (void) (&_min1 == &_min2); \ ^ mm/nobootmem.c:90:11: note: in expansion of macro 'min' order = min(MAX_ORDER - 1UL, __ffs(start)); ^ The rest of the worlds seems to define __ffs as returning unsigned long, so lets do that. Signed-off-by: Anton Blanchard Tested-by: Emil Medve Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/bitops.h | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index bd3bd573d0ae..c633f058ba43 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -213,7 +213,7 @@ static __inline__ unsigned long ffz(unsigned long x) return __ilog2(x & -x); } -static __inline__ int __ffs(unsigned long x) +static __inline__ unsigned long __ffs(unsigned long x) { return __ilog2(x & -x); } diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 65d2ed4549e6..d8484d7cffaa 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -152,7 +152,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci, flags |= 0x10000000; /* enable relaxed ordering */ for (i = 0; size > 0; i++) { - unsigned int bits = min(ilog2(size), + unsigned int bits = min_t(u32, ilog2(size), __ffs(pci_addr | phys_addr)); if (index + i >= 5) -- GitLab From 7d56c65a6ff9065c459fc63c509950d8ea66e00c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 17:07:03 +1000 Subject: [PATCH 4058/9457] powerpc/ftrace: Remove mod_return_to_handler mod_return_to_handler is the same as return_to_handler, except it handles the change of the TOC (r2). Add this into return_to_handler and remove mod_return_to_handler. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/entry_64.S | 24 +----------------------- arch/powerpc/kernel/ftrace.c | 14 ++------------ arch/powerpc/kernel/process.c | 9 +-------- 3 files changed, 4 insertions(+), 43 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 0905c8da90f1..66f7ed32848f 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -1240,28 +1240,6 @@ _GLOBAL(ftrace_graph_caller) blr _GLOBAL(return_to_handler) - /* need to save return values */ - std r4, -24(r1) - std r3, -16(r1) - std r31, -8(r1) - mr r31, r1 - stdu r1, -112(r1) - - bl ftrace_return_to_handler - nop - - /* return value has real return address */ - mtlr r3 - - ld r1, 0(r1) - ld r4, -24(r1) - ld r3, -16(r1) - ld r31, -8(r1) - - /* Jump back to real return address */ - blr - -_GLOBAL(mod_return_to_handler) /* need to save return values */ std r4, -32(r1) std r3, -24(r1) @@ -1272,7 +1250,7 @@ _GLOBAL(mod_return_to_handler) stdu r1, -112(r1) /* - * We are in a module using the module's TOC. + * We might be called from a module. * Switch to our TOC to run inside the core kernel. */ ld r2, PACATOC(r13) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 390311c0f03d..abf79213c356 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -510,10 +510,6 @@ int ftrace_disable_ftrace_graph_caller(void) } #endif /* CONFIG_DYNAMIC_FTRACE */ -#ifdef CONFIG_PPC64 -extern void mod_return_to_handler(void); -#endif - /* * Hook the return address and push it in the stack of return addrs * in current thread info. @@ -523,7 +519,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) unsigned long old; int faulted; struct ftrace_graph_ent trace; - unsigned long return_hooker = (unsigned long)&return_to_handler; + unsigned long return_hooker; if (unlikely(ftrace_graph_is_dead())) return; @@ -531,13 +527,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; -#ifdef CONFIG_PPC64 - /* non core kernel code needs to save and restore the TOC */ - if (REGION_ID(self_addr) != KERNEL_REGION_ID) - return_hooker = (unsigned long)&mod_return_to_handler; -#endif - - return_hooker = ppc_function_entry((void *)return_hooker); + return_hooker = ppc_function_entry(return_to_handler); /* * Protect against fault, even if it shouldn't diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 8c2691e445bd..f6b82152e7aa 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1527,13 +1527,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) int curr_frame = current->curr_ret_stack; extern void return_to_handler(void); unsigned long rth = (unsigned long)return_to_handler; - unsigned long mrth = -1; -#ifdef CONFIG_PPC64 - extern void mod_return_to_handler(void); - rth = *(unsigned long *)rth; - mrth = (unsigned long)mod_return_to_handler; - mrth = *(unsigned long *)mrth; -#endif #endif sp = (unsigned long) stack; @@ -1558,7 +1551,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) if (!firstframe || ip != lr) { printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); #ifdef CONFIG_FUNCTION_GRAPH_TRACER - if ((ip == rth || ip == mrth) && curr_frame >= 0) { + if ((ip == rth) && curr_frame >= 0) { printk(" (%pS)", (void *)current->ret_stack[curr_frame].ret); curr_frame--; -- GitLab From b3c18725a0eb7ea2458e9ae3b7e5a477f52e361f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 17 Sep 2014 17:07:04 +1000 Subject: [PATCH 4059/9457] powerpc/ftrace: simplify prepare_ftrace_return Instead of passing in the stack address of the link register to be modified, just pass in the old value and return the new value and rely on ftrace_graph_caller to do the modification. This removes the exception handling around the stack update - it isn't needed and we weren't consistent about it. Later on we would do an unprotected modification: if (!ftrace_graph_entry(&trace)) { *parent = old; Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/entry_32.S | 10 ++++-- arch/powerpc/kernel/entry_64.S | 11 +++++-- arch/powerpc/kernel/ftrace.c | 59 ++++++++-------------------------- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 22b45a4955cd..ad837d8a26d4 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -1424,12 +1424,18 @@ _GLOBAL(ftrace_graph_caller) lwz r4, 44(r1) subi r4, r4, MCOUNT_INSN_SIZE - /* get the parent address */ - addi r3, r1, 52 + /* Grab the LR out of the caller stack frame */ + lwz r3,52(r1) bl prepare_ftrace_return nop + /* + * prepare_ftrace_return gives us the address we divert to. + * Change the LR in the callers stack frame to this. + */ + stw r3,52(r1) + MCOUNT_RESTORE_FRAME /* old link register ends up in ctr reg */ bctr diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 66f7ed32848f..194e46dcf08d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -1227,13 +1227,20 @@ _GLOBAL(ftrace_graph_caller) ld r4, 128(r1) subi r4, r4, MCOUNT_INSN_SIZE - /* get the parent address */ + /* Grab the LR out of the caller stack frame */ ld r11, 112(r1) - addi r3, r11, 16 + ld r3, 16(r11) bl prepare_ftrace_return nop + /* + * prepare_ftrace_return gives us the address we divert to. + * Change the LR in the callers stack frame to this. + */ + ld r11, 112(r1) + std r3, 16(r11) + ld r0, 128(r1) mtlr r0 addi r1, r1, 112 diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index abf79213c356..d7950317d3a1 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -512,67 +512,34 @@ int ftrace_disable_ftrace_graph_caller(void) /* * Hook the return address and push it in the stack of return addrs - * in current thread info. + * in current thread info. Return the address we want to divert to. */ -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) +unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip) { - unsigned long old; - int faulted; struct ftrace_graph_ent trace; unsigned long return_hooker; if (unlikely(ftrace_graph_is_dead())) - return; + goto out; if (unlikely(atomic_read(¤t->tracing_graph_pause))) - return; + goto out; return_hooker = ppc_function_entry(return_to_handler); - /* - * Protect against fault, even if it shouldn't - * happen. This tool is too much intrusive to - * ignore such a protection. - */ - asm volatile( - "1: " PPC_LL "%[old], 0(%[parent])\n" - "2: " PPC_STL "%[return_hooker], 0(%[parent])\n" - " li %[faulted], 0\n" - "3:\n" - - ".section .fixup, \"ax\"\n" - "4: li %[faulted], 1\n" - " b 3b\n" - ".previous\n" - - ".section __ex_table,\"a\"\n" - PPC_LONG_ALIGN "\n" - PPC_LONG "1b,4b\n" - PPC_LONG "2b,4b\n" - ".previous" - - : [old] "=&r" (old), [faulted] "=r" (faulted) - : [parent] "r" (parent), [return_hooker] "r" (return_hooker) - : "memory" - ); - - if (unlikely(faulted)) { - ftrace_graph_stop(); - WARN_ON(1); - return; - } - - trace.func = self_addr; + trace.func = ip; trace.depth = current->curr_ret_stack + 1; /* Only trace if the calling function expects to */ - if (!ftrace_graph_entry(&trace)) { - *parent = old; - return; - } + if (!ftrace_graph_entry(&trace)) + goto out; + + if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) + goto out; - if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) - *parent = old; + parent = return_hooker; +out: + return parent; } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -- GitLab From dedd24a12fe6735898feeb06184ee346907abb5d Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 25 May 2013 12:54:25 -0400 Subject: [PATCH 4060/9457] powerpc: Remove unused devm_ioremap_prot() Added in 2008, but has never had any in-tree users, and no other architectures provide it. Signed-off-by: Kyle McMartin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/io.h | 3 --- arch/powerpc/lib/Makefile | 1 - arch/powerpc/lib/devres.c | 43 ----------------------------------- 3 files changed, 47 deletions(-) delete mode 100644 arch/powerpc/lib/devres.c diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 97d3869991ca..5f0ad8904f65 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -851,9 +851,6 @@ static inline void * bus_to_virt(unsigned long address) #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset, - size_t size, unsigned long flags); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_IO_H */ diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 9f342f134ae4..597562f69b2d 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -12,7 +12,6 @@ CFLAGS_REMOVE_feature-fixups.o = -pg obj-y := string.o alloc.o \ crtsavres.o ppc_ksyms.o obj-$(CONFIG_PPC32) += div64.o copy_32.o -obj-$(CONFIG_HAS_IOMEM) += devres.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ usercopy_64.o mem_64.o string.o \ diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c deleted file mode 100644 index 8df55fc3aad6..000000000000 --- a/arch/powerpc/lib/devres.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include /* devres_*(), devm_ioremap_release() */ -#include -#include /* ioremap_prot() */ -#include /* EXPORT_SYMBOL() */ - -/** - * devm_ioremap_prot - Managed ioremap_prot() - * @dev: Generic device to remap IO address for - * @offset: BUS offset to map - * @size: Size of map - * @flags: Page flags - * - * Managed ioremap_prot(). Map is automatically unmapped on driver - * detach. - */ -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset, - size_t size, unsigned long flags) -{ - void __iomem **ptr, *addr; - - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - addr = ioremap_prot(offset, size, flags); - if (addr) { - *ptr = addr; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return addr; -} -EXPORT_SYMBOL(devm_ioremap_prot); -- GitLab From 60878dfb11d47a9029581543ee2d2101faa88072 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 29 Apr 2014 09:24:06 +0200 Subject: [PATCH 4061/9457] powerpc/ftrace: Fix obsolete comment CONFIG_MCOUNT is not defined anymore, the corresponding #ifdef there is CONFIG_FUNCTION_TRACER. Signed-off-by: Jiri Slaby Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/entry_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index ad837d8a26d4..10a093579191 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -1463,4 +1463,4 @@ _GLOBAL(return_to_handler) blr #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -#endif /* CONFIG_MCOUNT */ +#endif /* CONFIG_FUNCTION_TRACER */ -- GitLab From 66f3d4fe0ba8f38df6141cc0b6ec145be6e63f0e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Oct 2014 16:35:14 +1100 Subject: [PATCH 4062/9457] powerpc: Remove CPU_FTR_HVMODE from CPU_FTRS_ALWAYS We potentially clear CPU_FTR_HVMODE at runtime in __init_hvmode_206(), so we must make sure it's not set in CPU_FTRS_ALWAYS. This doesn't hurt us in practice at the moment, because we don't support compiling only for CPUs that support CPU_FTR_HVMODE. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cputable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index daa5af91163c..42d8b33d1623 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -511,7 +511,7 @@ enum { (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ - CPU_FTRS_POWER8_DD1 & CPU_FTRS_POSSIBLE) + CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE) #endif #else enum { -- GitLab From 90029640fd5963343fb862d419db161bc0424120 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 6 Aug 2014 18:26:28 +1000 Subject: [PATCH 4063/9457] powerpc: Remove unused CPU_FTRS_A2 In commit fb5a515704d7 "Remove platforms/wsp and associated pieces" we removed the last user of CPU_FTRS_A2, so we should remove it too. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cputable.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 42d8b33d1623..22d5a7da9e68 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -448,13 +448,9 @@ extern const char *powerpc_base_platform; CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX) #define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2) -#define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \ - CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \ - CPU_FTR_ICSWX | CPU_FTR_DABRX ) - #ifdef __powerpc64__ #ifdef CONFIG_PPC_BOOK3E -#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500 | CPU_FTRS_A2) +#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500) #else #define CPU_FTRS_POSSIBLE \ (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ @@ -505,7 +501,7 @@ enum { #ifdef __powerpc64__ #ifdef CONFIG_PPC_BOOK3E -#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500 & CPU_FTRS_A2) +#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500) #else #define CPU_FTRS_ALWAYS \ (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ -- GitLab From 4b4b13d5fec8a82ed2780c487e49cfc4321a8c14 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Tue, 28 Oct 2014 12:19:00 +0100 Subject: [PATCH 4064/9457] powerpc/boot: Parse chosen/cmdline-timeout parameter On some platforms a 5 second timeout during boot might be quite long, so make it configurable. Run the loop at least once to let the user stop the boot by holding a key pressed. If the timeout is set to 0, don't wait for input, which can be used as a workaround if the boot hangs on random data coming in on the serial port. Signed-off-by: Simon Kagstrom [mpe: Changelog wording & whitespace] Signed-off-by: Michael Ellerman --- arch/powerpc/boot/main.c | 15 +++++++++++++-- arch/powerpc/boot/ops.h | 2 +- arch/powerpc/boot/serial.c | 6 +++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index d367a0aece2a..d80161b633f4 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -144,13 +144,24 @@ static char cmdline[BOOT_COMMAND_LINE_SIZE] static void prep_cmdline(void *chosen) { + unsigned int getline_timeout = 5000; + int v; + int n; + + /* Wait-for-input time */ + n = getprop(chosen, "linux,cmdline-timeout", &v, sizeof(v)); + if (n == sizeof(v)) + getline_timeout = v; + if (cmdline[0] == '\0') getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); printf("\n\rLinux/PowerPC load: %s", cmdline); + /* If possible, edit the command line */ - if (console_ops.edit_cmdline) - console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); + if (console_ops.edit_cmdline && getline_timeout) + console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE, getline_timeout); + printf("\n\r"); /* Put the command line back into the devtree for the kernel */ diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 8aad3c55aeda..5e75e1c5518e 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -58,7 +58,7 @@ extern struct dt_ops dt_ops; struct console_ops { int (*open)(void); void (*write)(const char *buf, int len); - void (*edit_cmdline)(char *buf, int len); + void (*edit_cmdline)(char *buf, int len, unsigned int getline_timeout); void (*close)(void); void *data; }; diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c index f2156f07571f..167ee9433de6 100644 --- a/arch/powerpc/boot/serial.c +++ b/arch/powerpc/boot/serial.c @@ -33,7 +33,7 @@ static void serial_write(const char *buf, int len) scdp->putc(*buf++); } -static void serial_edit_cmdline(char *buf, int len) +static void serial_edit_cmdline(char *buf, int len, unsigned int timeout) { int timer = 0, count; char ch, *cp; @@ -44,7 +44,7 @@ static void serial_edit_cmdline(char *buf, int len) cp = &buf[count]; count++; - while (timer++ < 5*1000) { + do { if (scdp->tstc()) { while (((ch = scdp->getc()) != '\n') && (ch != '\r')) { /* Test for backspace/delete */ @@ -70,7 +70,7 @@ static void serial_edit_cmdline(char *buf, int len) break; /* Exit 'timer' loop */ } udelay(1000); /* 1 msec */ - } + } while (timer++ < timeout); *cp = 0; } -- GitLab From 1bc9e47aa8e4b0f9629e218d4c7667308ca6af67 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 30 Oct 2014 15:43:43 +1100 Subject: [PATCH 4065/9457] powerpc/jump_label: Use HAVE_JUMP_LABEL Commit d4fe0965e208 ("powerpc/jump_label: use HAVE_JUMP_LABEL?") missed a few conversions. Change the remaining uses of CONFIG_JUMP_LABEL to HAVE_JUMP_LABEL. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal-wrappers.S | 2 +- arch/powerpc/platforms/pseries/hvCall.S | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index feb549aa3eea..cf7266de4c2f 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -18,7 +18,7 @@ .section ".text" #ifdef CONFIG_TRACEPOINTS -#ifdef CONFIG_JUMP_LABEL +#ifdef HAVE_JUMP_LABEL #define OPAL_BRANCH(LABEL) \ ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key) #else diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 3fda3f17b84e..ccd53f91e8aa 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -18,7 +18,7 @@ #ifdef CONFIG_TRACEPOINTS -#ifndef CONFIG_JUMP_LABEL +#ifndef HAVE_JUMP_LABEL .section ".toc","aw" .globl hcall_tracepoint_refcount @@ -78,7 +78,7 @@ hcall_tracepoint_refcount: mr r5,BUFREG; \ __HCALL_INST_POSTCALL -#ifdef CONFIG_JUMP_LABEL +#ifdef HAVE_JUMP_LABEL #define HCALL_BRANCH(LABEL) \ ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key) #else -- GitLab From e88f157de5e0b327b1b26e3260de4b16c07e2d19 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 27 Oct 2014 20:56:14 +1100 Subject: [PATCH 4066/9457] powerpc: Remove unused vgacon_remap_base & fix build break The build is broken with CONFIG_PPC32=y, CONFIG_FB_VGA16=y and CONFIG_VGA_CONSOLE=n. The problem is that vgacon_remap_base is not defined. It's used in: #define VGA_MAP_MEM(x,s) (x + vgacon_remap_base) Which is used in the vga16fb.c code. Digging down it seems vgacon_remap_base is never initialised. It used to be, back in arch/ppc (pplus.c and prep_setup.c), but none of that code ever made it to arch/powerpc. So given it's been unused for >6 years, remove it. Whether vga16fb.c works on 32-bit is another question, but this patch shouldn't affect it. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/vga.h | 4 +--- arch/powerpc/kernel/setup_32.c | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/vga.h b/arch/powerpc/include/asm/vga.h index a2eac409c1ec..e5f8dd366212 100644 --- a/arch/powerpc/include/asm/vga.h +++ b/arch/powerpc/include/asm/vga.h @@ -38,12 +38,10 @@ static inline u16 scr_readw(volatile const u16 *addr) #endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ -extern unsigned long vgacon_remap_base; - #ifdef __powerpc64__ #define VGA_MAP_MEM(x,s) ((unsigned long) ioremap((x), s)) #else -#define VGA_MAP_MEM(x,s) (x + vgacon_remap_base) +#define VGA_MAP_MEM(x,s) (x) #endif #define vga_readb(x) (*(x)) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index ba3a3c3b8c66..bb02e9f6944e 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -52,11 +52,6 @@ unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; -#ifdef CONFIG_VGA_CONSOLE -unsigned long vgacon_remap_base; -EXPORT_SYMBOL(vgacon_remap_base); -#endif - /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. -- GitLab From a3e5b356b3ab40b00ecb0f6fde445db719c100b5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 31 Oct 2014 14:47:25 +1100 Subject: [PATCH 4067/9457] powerpc: Don't use local named register variable in current_thread_info LLVM doesn't support local named register variables and is unlikely to. current_thread_info is using one, fix it by moving it out and calling it __current_r1(). I gave it a bit of an obscure name because we don't want anyone else using it - they should use current_stack_pointer(). This specific case is performance critical and we can't afford to call a function to get it. Furthermore it isn't important to know exactly where in the stack we are since we mask the lower bits. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/thread_info.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index b034ecdb7c74..ebc4f165690a 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -71,13 +71,12 @@ struct thread_info { #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) /* how to get the thread information struct from C */ +register unsigned long __current_r1 asm("r1"); static inline struct thread_info *current_thread_info(void) { - register unsigned long sp asm("r1"); - /* gcc4, at least, is smart enough to turn this into a single * rlwinm for ppc32 and clrrdi for ppc64 */ - return (struct thread_info *)(sp & ~(THREAD_SIZE-1)); + return (struct thread_info *)(__current_r1 & ~(THREAD_SIZE-1)); } #endif /* __ASSEMBLY__ */ -- GitLab From 6f791bef76d66923bc250cbbf4ddbf3f1c944686 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 31 Oct 2014 14:47:26 +1100 Subject: [PATCH 4068/9457] powerpc: Remove double braces in alignment code. Looks like I introduced this when adding LE support. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/align.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 34f55524d456..86150fbb42c3 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -908,7 +908,7 @@ int fix_alignment(struct pt_regs *regs) flush_fp_to_thread(current); } - if ((nb == 16)) { + if (nb == 16) { if (flags & F) { /* Special case for 16-byte FP loads and stores */ PPC_WARN_ALIGNMENT(fp_pair, regs); -- GitLab From ecaf5fa0a5096a237482ddc4b3c46becf531db1b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 31 Oct 2014 14:47:27 +1100 Subject: [PATCH 4069/9457] powerpc: LLVM complains about forward declaration of struct rtas_sensors Move the declaration up to silence the warning. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/rtas-proc.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 8777fb02349f..fb2fb3ea85e5 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -113,17 +113,6 @@ #define SENSOR_PREFIX "ibm,sensor-" #define cel_to_fahr(x) ((x*9/5)+32) - -/* Globals */ -static struct rtas_sensors sensors; -static struct device_node *rtas_node = NULL; -static unsigned long power_on_time = 0; /* Save the time the user set */ -static char progress_led[MAX_LINELENGTH]; - -static unsigned long rtas_tone_frequency = 1000; -static unsigned long rtas_tone_volume = 0; - -/* ****************STRUCTS******************************************* */ struct individual_sensor { unsigned int token; unsigned int quant; @@ -134,6 +123,15 @@ struct rtas_sensors { unsigned int quant; }; +/* Globals */ +static struct rtas_sensors sensors; +static struct device_node *rtas_node = NULL; +static unsigned long power_on_time = 0; /* Save the time the user set */ +static char progress_led[MAX_LINELENGTH]; + +static unsigned long rtas_tone_frequency = 1000; +static unsigned long rtas_tone_volume = 0; + /* ****************************************************************** */ /* Declarations */ static int ppc_rtas_sensors_show(struct seq_file *m, void *v); -- GitLab From 7aa189c8f57f2141b8655c2a13c7486d0844d490 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 3 Nov 2014 08:18:06 +1100 Subject: [PATCH 4070/9457] powerpc/pseries: Quieten ibm,pcie-link-speed-stats warning The ibm,pcie-link-speed-stats isn't mandatory, so we shouldn't print a high priority error message when missing. One example where we see this is QEMU. Reduce it to pr_debug. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 67e48594040c..fe16a50700de 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -134,7 +134,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) of_node_put(pdn); if (rc) { - pr_err("no ibm,pcie-link-speed-stats property\n"); + pr_debug("no ibm,pcie-link-speed-stats property\n"); return 0; } -- GitLab From 20f1aae6cb0120fa54c0fe81614f6983df3b420a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 3 Nov 2014 08:34:01 +1100 Subject: [PATCH 4071/9457] powerpc/pseries: Quieten relocation on exceptions warning The H_SET_MODE hcall returns H_P2 if a function is not implemented and all callers should handle this case. The call to enable relocation on exceptions currently prints an error message if the feature is not implemented. While H_SET_MODE was first introduced on POWER8 (which has relocation on exceptions), it has been now added on some POWER7 configurations (which does not). Check for H_P2 and print an informational message instead. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index db0fc0c07568..8b8fb19a4097 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -499,7 +499,11 @@ static void __init pSeries_setup_arch(void) if (firmware_has_feature(FW_FEATURE_SET_MODE)) { long rc; - if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) { + + rc = pSeries_enable_reloc_on_exc(); + if (rc == H_P2) { + pr_info("Relocation on exceptions not supported\n"); + } else if (rc != H_SUCCESS) { pr_warn("Unable to enable relocation on exceptions: " "%ld\n", rc); } -- GitLab From 0f9da5cb746581ae2de120c78a8afe29fb594fe4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:44 +0200 Subject: [PATCH 4072/9457] powerpc/4xx/cpm: delete unneeded test before of_node_put Simplify the error path to avoid calling of_node_put when it is not needed. Signed-off-by: Julia Lawall Acked-by: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman --- arch/powerpc/sysdev/ppc4xx_cpm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/sysdev/ppc4xx_cpm.c index 82e2cfe35c62..ba95adf81d8d 100644 --- a/arch/powerpc/sysdev/ppc4xx_cpm.c +++ b/arch/powerpc/sysdev/ppc4xx_cpm.c @@ -281,7 +281,7 @@ static int __init cpm_init(void) printk(KERN_ERR "cpm: could not parse dcr property for %s\n", np->full_name); ret = -EINVAL; - goto out; + goto node_put; } cpm.dcr_host = dcr_map(np, dcr_base, dcr_len); @@ -290,7 +290,7 @@ static int __init cpm_init(void) printk(KERN_ERR "cpm: failed to map dcr property for %s\n", np->full_name); ret = -EINVAL; - goto out; + goto node_put; } /* All 4xx SoCs with a CPM controller have one of two @@ -330,9 +330,9 @@ static int __init cpm_init(void) if (cpm.standby || cpm.suspend) suspend_set_ops(&cpm_suspend_ops); +node_put: + of_node_put(np); out: - if (np) - of_node_put(np); return ret; } -- GitLab From 4cdd641dddd0ecd93f7b84fc3622df83937f6094 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:45 +0200 Subject: [PATCH 4073/9457] powerpc/fsl: fsl_soc: delete unneeded test before of_node_put MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Of_node_put supports NULL as its argument, so the initial test is not necessary. Suggested by Uwe Kleine-König. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ -if (e) of_node_put(e); // Signed-off-by: Julia Lawall Acked-by: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman --- arch/powerpc/sysdev/fsl_soc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 1e04568da3b9..99269c041615 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -197,8 +197,7 @@ static int __init setup_rstcr(void) if (!rstcr && ppc_md.restart == fsl_rstcr_restart) printk(KERN_ERR "No RSTCR register, warm reboot won't work\n"); - if (np) - of_node_put(np); + of_node_put(np); return 0; } -- GitLab From 756d36790ad0fa221af650095fa52764474854b7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:46 +0200 Subject: [PATCH 4074/9457] powerpc/mpc5xxx: delete unneeded test before of_node_put MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Of_node_put supports NULL as its argument, so the initial test is not necessary. Suggested by Uwe Kleine-König. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ -if (e) of_node_put(e); // Signed-off-by: Julia Lawall Signed-off-by: Michael Ellerman --- arch/powerpc/sysdev/mpc5xxx_clocks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c index 5492dc5f56f4..f4f0301b9a60 100644 --- a/arch/powerpc/sysdev/mpc5xxx_clocks.c +++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c @@ -26,8 +26,7 @@ unsigned long mpc5xxx_get_bus_frequency(struct device_node *node) of_node_put(node); node = np; } - if (node) - of_node_put(node); + of_node_put(node); return p_bus_freq ? *p_bus_freq : 0; } -- GitLab From 498b65147247f61f3f7f4deb35484ff98556e798 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:47 +0200 Subject: [PATCH 4075/9457] powerpc/pseries: delete unneeded test before of_node_put MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Of_node_put supports NULL as its argument, so the initial test is not necessary. Suggested by Uwe Kleine-König. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ -if (e) of_node_put(e); // Signed-off-by: Julia Lawall Acked-by: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 49bcf7c09c49..1cc3db95ee71 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -574,8 +574,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) while (isa_dn && isa_dn != dn) isa_dn = isa_dn->parent; - if (isa_dn_orig) - of_node_put(isa_dn_orig); + of_node_put(isa_dn_orig); /* Count number of direct PCI children of the PHB. */ for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) -- GitLab From 6609ed14de75bde7a99b33e9be9f1873da91f07d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:48 +0200 Subject: [PATCH 4076/9457] powerpc/gamecube/wii: delete unneeded test before of_node_put Simplify the error path to avoid calling of_node_put when it is not needed. Signed-off-by: Julia Lawall Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c index 20a8ed91962e..7feb325b636b 100644 --- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c @@ -247,7 +247,7 @@ void __init ug_udbg_init(void) np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi"); if (!np) { udbg_printf("%s: EXI node not found\n", __func__); - goto done; + goto out; } exi_io_base = ug_udbg_setup_exi_io_base(np); @@ -267,8 +267,8 @@ void __init ug_udbg_init(void) } done: - if (np) - of_node_put(np); + of_node_put(np); +out: return; } -- GitLab From cc7096fb6d1dfbdac5e7e2675c046fd40646cc66 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 22 Oct 2014 12:03:04 +1000 Subject: [PATCH 4077/9457] drm/mode: document path property and function to set it. (v1.1) These two didn't get documented properly, do so. Pointed out by Daniel. v1.1: add missing boilerplate (Daniel) Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- Documentation/DocBook/drm.tmpl | 9 ++++++++- drivers/gpu/drm/drm_crtc.c | 13 +++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 64d9c1e6e6cd..b4d80a2d46d1 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2534,7 +2534,7 @@ void intel_crt_init(struct drm_device *dev) DRM - Generic + Generic “EDID” BLOB | IMMUTABLE 0 @@ -2549,6 +2549,13 @@ void intel_crt_init(struct drm_device *dev) Contains DPMS operation mode value. + “PATH” + BLOB | IMMUTABLE + 0 + Connector + Contains topology path to a connector. + + Plane “type” ENUM | IMMUTABLE diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 0f3c24c0981b..e6c169152bf1 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4005,6 +4005,19 @@ int drm_mode_getblob_ioctl(struct drm_device *dev, return ret; } +/** + * drm_mode_connector_set_path_property - set tile property on connector + * @connector: connector to set property on. + * @path: path to use for property. + * + * This creates a property to expose to userspace to specify a + * connector path. This is mainly used for DisplayPort MST where + * connectors have a topology and we want to allow userspace to give + * them more meaningful names. + * + * Returns: + * Zero on success, errno on failure. + */ int drm_mode_connector_set_path_property(struct drm_connector *connector, char *path) { -- GitLab From 9ba559d9ca3711940be3e7207dac13c4f0654d43 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 6 Nov 2014 06:44:27 -0800 Subject: [PATCH 4078/9457] openvswitch: Export symbols as GPL symbols. vport can be compiled as modules, therefore openvswitch needs to export few symbols. Export them as GPL symbols. CC: Thomas Graf Signed-off-by: Pravin B Shelar --- net/openvswitch/datapath.c | 4 ++-- net/openvswitch/vport.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 014485ec4b0d..6cfb44f3a7f0 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -59,7 +59,7 @@ #include "vport-netdev.h" int ovs_net_id __read_mostly; -EXPORT_SYMBOL(ovs_net_id); +EXPORT_SYMBOL_GPL(ovs_net_id); static struct genl_family dp_packet_genl_family; static struct genl_family dp_flow_genl_family; @@ -131,7 +131,7 @@ int lockdep_ovsl_is_held(void) else return 1; } -EXPORT_SYMBOL(lockdep_ovsl_is_held); +EXPORT_SYMBOL_GPL(lockdep_ovsl_is_held); #endif static struct vport *new_vport(const struct vport_parms *); diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 8168ef021337..4b5dd18953a6 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -90,7 +90,7 @@ int ovs_vport_ops_register(struct vport_ops *ops) ovs_unlock(); return err; } -EXPORT_SYMBOL(ovs_vport_ops_register); +EXPORT_SYMBOL_GPL(ovs_vport_ops_register); void ovs_vport_ops_unregister(struct vport_ops *ops) { @@ -98,7 +98,7 @@ void ovs_vport_ops_unregister(struct vport_ops *ops) list_del(&ops->list); ovs_unlock(); } -EXPORT_SYMBOL(ovs_vport_ops_unregister); +EXPORT_SYMBOL_GPL(ovs_vport_ops_unregister); /** * ovs_vport_locate - find a port that has already been created @@ -165,7 +165,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, return vport; } -EXPORT_SYMBOL(ovs_vport_alloc); +EXPORT_SYMBOL_GPL(ovs_vport_alloc); /** * ovs_vport_free - uninitialize and free vport @@ -186,7 +186,7 @@ void ovs_vport_free(struct vport *vport) free_percpu(vport->percpu_stats); kfree(vport); } -EXPORT_SYMBOL(ovs_vport_free); +EXPORT_SYMBOL_GPL(ovs_vport_free); static struct vport_ops *ovs_vport_lookup(const struct vport_parms *parms) { @@ -493,7 +493,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, } ovs_dp_process_packet(skb, &key); } -EXPORT_SYMBOL(ovs_vport_receive); +EXPORT_SYMBOL_GPL(ovs_vport_receive); /** * ovs_vport_send - send a packet on a device @@ -572,4 +572,4 @@ void ovs_vport_deferred_free(struct vport *vport) call_rcu(&vport->rcu, free_vport_rcu); } -EXPORT_SYMBOL(ovs_vport_deferred_free); +EXPORT_SYMBOL_GPL(ovs_vport_deferred_free); -- GitLab From 8f0aad6f35f7e8b3118b7b8a65e8e76b135cc4cb Mon Sep 17 00:00:00 2001 From: Wenyu Zhang Date: Thu, 6 Nov 2014 06:51:24 -0800 Subject: [PATCH 4079/9457] openvswitch: Extend packet attribute for egress tunnel info OVS vswitch has extended IPFIX exporter to export tunnel headers to improve network visibility. To export this information userspace needs to know egress tunnel for given packet. By extending packet attributes datapath can export egress tunnel info for given packet. So that userspace can ask for egress tunnel info in userspace action. This information is used to build IPFIX data for given flow. Signed-off-by: Wenyu Zhang Acked-by: Romain Lenglet Acked-by: Ben Pfaff Signed-off-by: Pravin B Shelar --- include/uapi/linux/openvswitch.h | 13 +++++++ net/openvswitch/actions.c | 19 ++++++++++ net/openvswitch/datapath.c | 21 ++++++++--- net/openvswitch/datapath.h | 2 ++ net/openvswitch/flow.h | 62 ++++++++++++++++++++++++-------- net/openvswitch/flow_netlink.c | 54 ++++++++++++++++++++++------ net/openvswitch/flow_netlink.h | 3 ++ net/openvswitch/vport-geneve.c | 21 ++++++++++- net/openvswitch/vport-gre.c | 12 ++++++- net/openvswitch/vport-vxlan.c | 24 ++++++++++++- net/openvswitch/vport.c | 61 +++++++++++++++++++++++++++++++ net/openvswitch/vport.h | 14 ++++++++ 12 files changed, 275 insertions(+), 31 deletions(-) diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index 26c36c4cf7e2..cf8185661e52 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -157,6 +157,11 @@ enum ovs_packet_cmd { * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an * %OVS_USERSPACE_ATTR_USERDATA attribute, with the same length and content * specified there. + * @OVS_PACKET_ATTR_EGRESS_TUN_KEY: Present for an %OVS_PACKET_CMD_ACTION + * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an + * %OVS_USERSPACE_ATTR_EGRESS_TUN_PORT attribute, which is sent only if the + * output port is actually a tunnel port. Contains the output tunnel key + * extracted from the packet as nested %OVS_TUNNEL_KEY_ATTR_* attributes. * * These attributes follow the &struct ovs_header within the Generic Netlink * payload for %OVS_PACKET_* commands. @@ -167,6 +172,8 @@ enum ovs_packet_attr { OVS_PACKET_ATTR_KEY, /* Nested OVS_KEY_ATTR_* attributes. */ OVS_PACKET_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ OVS_PACKET_ATTR_USERDATA, /* OVS_ACTION_ATTR_USERSPACE arg. */ + OVS_PACKET_ATTR_EGRESS_TUN_KEY, /* Nested OVS_TUNNEL_KEY_ATTR_* + attributes. */ __OVS_PACKET_ATTR_MAX }; @@ -315,6 +322,8 @@ enum ovs_tunnel_key_attr { OVS_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */ OVS_TUNNEL_KEY_ATTR_OAM, /* No argument. OAM frame. */ OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, /* Array of Geneve options. */ + OVS_TUNNEL_KEY_ATTR_TP_SRC, /* be16 src Transport Port. */ + OVS_TUNNEL_KEY_ATTR_TP_DST, /* be16 dst Transport Port. */ __OVS_TUNNEL_KEY_ATTR_MAX }; @@ -480,11 +489,15 @@ enum ovs_sample_attr { * message should be sent. Required. * @OVS_USERSPACE_ATTR_USERDATA: If present, its variable-length argument is * copied to the %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA. + * @OVS_USERSPACE_ATTR_EGRESS_TUN_PORT: If present, u32 output port to get + * tunnel info. */ enum ovs_userspace_attr { OVS_USERSPACE_ATTR_UNSPEC, OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */ OVS_USERSPACE_ATTR_USERDATA, /* Optional user-specified cookie. */ + OVS_USERSPACE_ATTR_EGRESS_TUN_PORT, /* Optional, u32 output port + * to get tunnel info. */ __OVS_USERSPACE_ATTR_MAX }; diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index f7e589159e4a..ceb618cf1292 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -564,6 +564,7 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port) static int output_userspace(struct datapath *dp, struct sk_buff *skb, struct sw_flow_key *key, const struct nlattr *attr) { + struct ovs_tunnel_info info; struct dp_upcall_info upcall; const struct nlattr *a; int rem; @@ -572,6 +573,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, upcall.key = key; upcall.userdata = NULL; upcall.portid = 0; + upcall.egress_tun_info = NULL; for (a = nla_data(attr), rem = nla_len(attr); rem > 0; a = nla_next(a, &rem)) { @@ -583,7 +585,24 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, case OVS_USERSPACE_ATTR_PID: upcall.portid = nla_get_u32(a); break; + + case OVS_USERSPACE_ATTR_EGRESS_TUN_PORT: { + /* Get out tunnel info. */ + struct vport *vport; + + vport = ovs_vport_rcu(dp, nla_get_u32(a)); + if (vport) { + int err; + + err = ovs_vport_get_egress_tun_info(vport, skb, + &info); + if (!err) + upcall.egress_tun_info = &info; + } + break; } + + } /* End of switch. */ } return ovs_dp_upcall(dp, skb, &upcall); diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 6cfb44f3a7f0..c2ac340e19fb 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -274,6 +274,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.key = key; upcall.userdata = NULL; upcall.portid = ovs_vport_find_upcall_portid(p, skb); + upcall.egress_tun_info = NULL; error = ovs_dp_upcall(dp, skb, &upcall); if (unlikely(error)) kfree_skb(skb); @@ -375,7 +376,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, return err; } -static size_t upcall_msg_size(const struct nlattr *userdata, +static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info, unsigned int hdrlen) { size_t size = NLMSG_ALIGN(sizeof(struct ovs_header)) @@ -383,8 +384,12 @@ static size_t upcall_msg_size(const struct nlattr *userdata, + nla_total_size(ovs_key_attr_size()); /* OVS_PACKET_ATTR_KEY */ /* OVS_PACKET_ATTR_USERDATA */ - if (userdata) - size += NLA_ALIGN(userdata->nla_len); + if (upcall_info->userdata) + size += NLA_ALIGN(upcall_info->userdata->nla_len); + + /* OVS_PACKET_ATTR_EGRESS_TUN_KEY */ + if (upcall_info->egress_tun_info) + size += nla_total_size(ovs_tun_key_attr_size()); return size; } @@ -440,7 +445,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, else hlen = skb->len; - len = upcall_msg_size(upcall_info->userdata, hlen); + len = upcall_msg_size(upcall_info, hlen); user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC); if (!user_skb) { err = -ENOMEM; @@ -461,6 +466,14 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, nla_len(upcall_info->userdata), nla_data(upcall_info->userdata)); + if (upcall_info->egress_tun_info) { + nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_EGRESS_TUN_KEY); + err = ovs_nla_put_egress_tunnel_key(user_skb, + upcall_info->egress_tun_info); + BUG_ON(err); + nla_nest_end(user_skb, nla); + } + /* Only reserve room for attribute header, packet data is added * in skb_zerocopy() */ if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) { diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 1c56a80d6677..2bc577bf9b31 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -114,12 +114,14 @@ struct ovs_skb_cb { * @pid: Netlink PID to which packet should be sent. If @pid is 0 then no * packet is sent and the packet is accounted in the datapath's @n_lost * counter. + * @egress_tun_info: If nonnull, becomes %OVS_PACKET_ATTR_EGRESS_TUN_KEY. */ struct dp_upcall_info { u8 cmd; const struct sw_flow_key *key; const struct nlattr *userdata; u32 portid; + const struct ovs_tunnel_info *egress_tun_info; }; /** diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 4962bee81a11..543b358ee57f 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -37,8 +37,8 @@ struct sk_buff; /* Used to memset ovs_key_ipv4_tunnel padding. */ #define OVS_TUNNEL_KEY_SIZE \ - (offsetof(struct ovs_key_ipv4_tunnel, ipv4_ttl) + \ - FIELD_SIZEOF(struct ovs_key_ipv4_tunnel, ipv4_ttl)) + (offsetof(struct ovs_key_ipv4_tunnel, tp_dst) + \ + FIELD_SIZEOF(struct ovs_key_ipv4_tunnel, tp_dst)) struct ovs_key_ipv4_tunnel { __be64 tun_id; @@ -47,6 +47,8 @@ struct ovs_key_ipv4_tunnel { __be16 tun_flags; u8 ipv4_tos; u8 ipv4_ttl; + __be16 tp_src; + __be16 tp_dst; } __packed __aligned(4); /* Minimize padding. */ struct ovs_tunnel_info { @@ -64,27 +66,59 @@ struct ovs_tunnel_info { FIELD_SIZEOF(struct sw_flow_key, tun_opts) - \ opt_len)) -static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, - const struct iphdr *iph, - __be64 tun_id, __be16 tun_flags, - struct geneve_opt *opts, - u8 opts_len) +static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, + __be32 saddr, __be32 daddr, + u8 tos, u8 ttl, + __be16 tp_src, + __be16 tp_dst, + __be64 tun_id, + __be16 tun_flags, + struct geneve_opt *opts, + u8 opts_len) { tun_info->tunnel.tun_id = tun_id; - tun_info->tunnel.ipv4_src = iph->saddr; - tun_info->tunnel.ipv4_dst = iph->daddr; - tun_info->tunnel.ipv4_tos = iph->tos; - tun_info->tunnel.ipv4_ttl = iph->ttl; + tun_info->tunnel.ipv4_src = saddr; + tun_info->tunnel.ipv4_dst = daddr; + tun_info->tunnel.ipv4_tos = tos; + tun_info->tunnel.ipv4_ttl = ttl; tun_info->tunnel.tun_flags = tun_flags; - /* clear struct padding. */ - memset((unsigned char *)&tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, 0, - sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE); + /* For the tunnel types on the top of IPsec, the tp_src and tp_dst of + * the upper tunnel are used. + * E.g: GRE over IPSEC, the tp_src and tp_port are zero. + */ + tun_info->tunnel.tp_src = tp_src; + tun_info->tunnel.tp_dst = tp_dst; + + /* Clear struct padding. */ + if (sizeof(tun_info->tunnel) != OVS_TUNNEL_KEY_SIZE) + memset((unsigned char *)&tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, + 0, sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE); tun_info->options = opts; tun_info->options_len = opts_len; } +static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, + const struct iphdr *iph, + __be16 tp_src, + __be16 tp_dst, + __be64 tun_id, + __be16 tun_flags, + struct geneve_opt *opts, + u8 opts_len) +{ + __ovs_flow_tun_info_init(tun_info, iph->saddr, iph->daddr, + iph->tos, iph->ttl, + tp_src, tp_dst, + tun_id, tun_flags, + opts, opts_len); +} + +#define OVS_SW_FLOW_KEY_METADATA_SIZE \ + (offsetof(struct sw_flow_key, recirc_id) + \ + FIELD_SIZEOF(struct sw_flow_key, recirc_id)) + struct sw_flow_key { u8 tun_opts[255]; u8 tun_opts_len; diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index ed3109761827..98a3e96b7d93 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -245,6 +245,24 @@ static bool match_validate(const struct sw_flow_match *match, return true; } +size_t ovs_tun_key_attr_size(void) +{ + /* Whenever adding new OVS_TUNNEL_KEY_ FIELDS, we should consider + * updating this function. + */ + return nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */ + + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */ + + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */ + + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */ + + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */ + + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */ + + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */ + + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */ + + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */ + + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */ + + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */ +} + size_t ovs_key_attr_size(void) { /* Whenever adding new OVS_KEY_ FIELDS, we should consider @@ -254,15 +272,7 @@ size_t ovs_key_attr_size(void) return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */ + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */ - + nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */ - + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */ - + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */ - + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */ - + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */ - + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */ - + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */ - + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */ - + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */ + + ovs_tun_key_attr_size() + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */ + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */ + nla_total_size(4) /* OVS_KEY_ATTR_DP_HASH */ @@ -393,6 +403,8 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, [OVS_TUNNEL_KEY_ATTR_TTL] = 1, [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0, [OVS_TUNNEL_KEY_ATTR_CSUM] = 0, + [OVS_TUNNEL_KEY_ATTR_TP_SRC] = sizeof(u16), + [OVS_TUNNEL_KEY_ATTR_TP_DST] = sizeof(u16), [OVS_TUNNEL_KEY_ATTR_OAM] = 0, [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = -1, }; @@ -440,6 +452,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, case OVS_TUNNEL_KEY_ATTR_CSUM: tun_flags |= TUNNEL_CSUM; break; + case OVS_TUNNEL_KEY_ATTR_TP_SRC: + SW_FLOW_KEY_PUT(match, tun_key.tp_src, + nla_get_be16(a), is_mask); + break; + case OVS_TUNNEL_KEY_ATTR_TP_DST: + SW_FLOW_KEY_PUT(match, tun_key.tp_dst, + nla_get_be16(a), is_mask); + break; case OVS_TUNNEL_KEY_ATTR_OAM: tun_flags |= TUNNEL_OAM; break; @@ -548,6 +568,12 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb, if ((output->tun_flags & TUNNEL_CSUM) && nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM)) return -EMSGSIZE; + if (output->tp_src && + nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_SRC, output->tp_src)) + return -EMSGSIZE; + if (output->tp_dst && + nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_DST, output->tp_dst)) + return -EMSGSIZE; if ((output->tun_flags & TUNNEL_OAM) && nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM)) return -EMSGSIZE; @@ -559,7 +585,6 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb, return 0; } - static int ipv4_tun_to_nlattr(struct sk_buff *skb, const struct ovs_key_ipv4_tunnel *output, const struct geneve_opt *tun_opts, @@ -580,6 +605,14 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb, return 0; } +int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb, + const struct ovs_tunnel_info *egress_tun_info) +{ + return __ipv4_tun_to_nlattr(skb, &egress_tun_info->tunnel, + egress_tun_info->options, + egress_tun_info->options_len); +} + static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, const struct nlattr **a, bool is_mask) { @@ -1653,6 +1686,7 @@ static int validate_userspace(const struct nlattr *attr) static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = { [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 }, [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC }, + [OVS_USERSPACE_ATTR_EGRESS_TUN_PORT] = {.type = NLA_U32 }, }; struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1]; int error; diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h index eb0b177300ad..90bbe3785504 100644 --- a/net/openvswitch/flow_netlink.h +++ b/net/openvswitch/flow_netlink.h @@ -37,6 +37,7 @@ #include "flow.h" +size_t ovs_tun_key_attr_size(void); size_t ovs_key_attr_size(void); void ovs_match_init(struct sw_flow_match *match, @@ -49,6 +50,8 @@ int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *); int ovs_nla_get_match(struct sw_flow_match *match, const struct nlattr *, const struct nlattr *); +int ovs_nla_put_egress_tunnel_key(struct sk_buff *, + const struct ovs_tunnel_info *); int ovs_nla_copy_actions(const struct nlattr *attr, const struct sw_flow_key *key, diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 70c9765011f4..e31f19c922e2 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c @@ -97,7 +97,9 @@ static void geneve_rcv(struct geneve_sock *gs, struct sk_buff *skb) key = vni_to_tunnel_id(geneveh->vni); - ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key, flags, + ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), + udp_hdr(skb)->source, udp_hdr(skb)->dest, + key, flags, geneveh->options, opts_len); ovs_vport_receive(vport, skb, &tun_info); @@ -228,6 +230,22 @@ static const char *geneve_get_name(const struct vport *vport) return geneve_port->name; } +static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, + struct ovs_tunnel_info *egress_tun_info) +{ + struct geneve_port *geneve_port = geneve_vport(vport); + struct net *net = ovs_dp_get_net(vport->dp); + __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport; + __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true); + + /* Get tp_src and tp_dst, refert to geneve_build_header(). + */ + return ovs_tunnel_get_egress_info(egress_tun_info, + ovs_dp_get_net(vport->dp), + OVS_CB(skb)->egress_tun_info, + IPPROTO_UDP, skb->mark, sport, dport); +} + static struct vport_ops ovs_geneve_vport_ops = { .type = OVS_VPORT_TYPE_GENEVE, .create = geneve_tnl_create, @@ -236,6 +254,7 @@ static struct vport_ops ovs_geneve_vport_ops = { .get_options = geneve_get_options, .send = geneve_tnl_send, .owner = THIS_MODULE, + .get_egress_tun_info = geneve_get_egress_tun_info, }; static int __init ovs_geneve_tnl_init(void) diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 00270b608844..8e61a5c6ae7c 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c @@ -108,7 +108,7 @@ static int gre_rcv(struct sk_buff *skb, return PACKET_REJECT; key = key_to_tunnel_id(tpi->key, tpi->seq); - ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key, + ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), 0, 0, key, filter_tnl_flags(tpi->flags), NULL, 0); ovs_vport_receive(vport, skb, &tun_info); @@ -284,12 +284,22 @@ static void gre_tnl_destroy(struct vport *vport) gre_exit(); } +static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, + struct ovs_tunnel_info *egress_tun_info) +{ + return ovs_tunnel_get_egress_info(egress_tun_info, + ovs_dp_get_net(vport->dp), + OVS_CB(skb)->egress_tun_info, + IPPROTO_GRE, skb->mark, 0, 0); +} + static struct vport_ops ovs_gre_vport_ops = { .type = OVS_VPORT_TYPE_GRE, .create = gre_create, .destroy = gre_tnl_destroy, .get_name = gre_get_name, .send = gre_tnl_send, + .get_egress_tun_info = gre_get_egress_tun_info, .owner = THIS_MODULE, }; diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 965e7500c5a6..38f95a52241b 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c @@ -69,7 +69,9 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni) /* Save outer tunnel values */ iph = ip_hdr(skb); key = cpu_to_be64(ntohl(vx_vni) >> 8); - ovs_flow_tun_info_init(&tun_info, iph, key, TUNNEL_KEY, NULL, 0); + ovs_flow_tun_info_init(&tun_info, iph, + udp_hdr(skb)->source, udp_hdr(skb)->dest, + key, TUNNEL_KEY, NULL, 0); ovs_vport_receive(vport, skb, &tun_info); } @@ -189,6 +191,25 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) return err; } +static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, + struct ovs_tunnel_info *egress_tun_info) +{ + struct net *net = ovs_dp_get_net(vport->dp); + struct vxlan_port *vxlan_port = vxlan_vport(vport); + __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport; + __be16 src_port; + int port_min; + int port_max; + + inet_get_local_port_range(net, &port_min, &port_max); + src_port = udp_flow_src_port(net, skb, 0, 0, true); + + return ovs_tunnel_get_egress_info(egress_tun_info, net, + OVS_CB(skb)->egress_tun_info, + IPPROTO_UDP, skb->mark, + src_port, dst_port); +} + static const char *vxlan_get_name(const struct vport *vport) { struct vxlan_port *vxlan_port = vxlan_vport(vport); @@ -202,6 +223,7 @@ static struct vport_ops ovs_vxlan_vport_ops = { .get_name = vxlan_get_name, .get_options = vxlan_get_options, .send = vxlan_tnl_send, + .get_egress_tun_info = vxlan_get_egress_tun_info, .owner = THIS_MODULE, }; diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 4b5dd18953a6..630e81984b65 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -573,3 +573,64 @@ void ovs_vport_deferred_free(struct vport *vport) call_rcu(&vport->rcu, free_vport_rcu); } EXPORT_SYMBOL_GPL(ovs_vport_deferred_free); + +int ovs_tunnel_get_egress_info(struct ovs_tunnel_info *egress_tun_info, + struct net *net, + const struct ovs_tunnel_info *tun_info, + u8 ipproto, + u32 skb_mark, + __be16 tp_src, + __be16 tp_dst) +{ + const struct ovs_key_ipv4_tunnel *tun_key; + struct rtable *rt; + struct flowi4 fl; + + if (unlikely(!tun_info)) + return -EINVAL; + + tun_key = &tun_info->tunnel; + + /* Route lookup to get srouce IP address. + * The process may need to be changed if the corresponding process + * in vports ops changed. + */ + memset(&fl, 0, sizeof(fl)); + fl.daddr = tun_key->ipv4_dst; + fl.saddr = tun_key->ipv4_src; + fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos); + fl.flowi4_mark = skb_mark; + fl.flowi4_proto = IPPROTO_GRE; + + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) + return PTR_ERR(rt); + + ip_rt_put(rt); + + /* Generate egress_tun_info based on tun_info, + * saddr, tp_src and tp_dst + */ + __ovs_flow_tun_info_init(egress_tun_info, + fl.saddr, tun_key->ipv4_dst, + tun_key->ipv4_tos, + tun_key->ipv4_ttl, + tp_src, tp_dst, + tun_key->tun_id, + tun_key->tun_flags, + tun_info->options, + tun_info->options_len); + + return 0; +} +EXPORT_SYMBOL_GPL(ovs_tunnel_get_egress_info); + +int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, + struct ovs_tunnel_info *info) +{ + /* get_egress_tun_info() is only implemented on tunnel ports. */ + if (unlikely(!vport->ops->get_egress_tun_info)) + return -EINVAL; + + return vport->ops->get_egress_tun_info(vport, skb, info); +} diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index e41c3facf799..0635d1d761e9 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h @@ -58,6 +58,16 @@ u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *); int ovs_vport_send(struct vport *, struct sk_buff *); +int ovs_tunnel_get_egress_info(struct ovs_tunnel_info *egress_tun_info, + struct net *net, + const struct ovs_tunnel_info *tun_info, + u8 ipproto, + u32 skb_mark, + __be16 tp_src, + __be16 tp_dst); +int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, + struct ovs_tunnel_info *info); + /* The following definitions are for implementers of vport devices: */ struct vport_err_stats { @@ -146,6 +156,8 @@ struct vport_parms { * @get_name: Get the device's name. * @send: Send a packet on the device. Returns the length of the packet sent, * zero for dropped packets or negative for error. + * @get_egress_tun_info: Get the egress tunnel 5-tuple and other info for + * a packet. */ struct vport_ops { enum ovs_vport_type type; @@ -161,6 +173,8 @@ struct vport_ops { const char *(*get_name)(const struct vport *); int (*send)(struct vport *, struct sk_buff *); + int (*get_egress_tun_info)(struct vport *, struct sk_buff *, + struct ovs_tunnel_info *); struct module *owner; struct list_head list; -- GitLab From fff06c36a2563214073707f6e6aea152713274d1 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 6 Nov 2014 06:55:14 -0800 Subject: [PATCH 4080/9457] openvswitch: Optimize recirc action. OVS need to flow key for flow lookup in recic action. OVS does key extract in recic action. Most of cases we could use OVS_CB packet key directly and can avoid packet flow key extract. SET action we can update flow-key along with packet to keep it consistent. But there are some action like MPLS pop which forces OVS to do flow-extract. In such cases we can mark flow key as invalid so that subsequent recirc action can do full flow extract. Signed-off-by: Pravin B Shelar Acked-by: Jarno Rajahalme Acked-by: Andy Zhou --- net/openvswitch/actions.c | 151 ++++++++++++++++++++++++++------------ 1 file changed, 106 insertions(+), 45 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index ceb618cf1292..d4c2f735d999 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -109,6 +109,16 @@ static struct deferred_action *add_deferred_actions(struct sk_buff *skb, return da; } +static void invalidate_flow_key(struct sw_flow_key *key) +{ + key->eth.type = htons(0); +} + +static bool is_flow_key_valid(const struct sw_flow_key *key) +{ + return !!key->eth.type; +} + static int make_writable(struct sk_buff *skb, int write_len) { if (!pskb_may_pull(skb, write_len)) @@ -120,7 +130,7 @@ static int make_writable(struct sk_buff *skb, int write_len) return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); } -static int push_mpls(struct sk_buff *skb, +static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_action_push_mpls *mpls) { __be32 *new_mpls_lse; @@ -151,10 +161,12 @@ static int push_mpls(struct sk_buff *skb, skb_set_inner_protocol(skb, skb->protocol); skb->protocol = mpls->mpls_ethertype; + invalidate_flow_key(key); return 0; } -static int pop_mpls(struct sk_buff *skb, const __be16 ethertype) +static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, + const __be16 ethertype) { struct ethhdr *hdr; int err; @@ -181,10 +193,13 @@ static int pop_mpls(struct sk_buff *skb, const __be16 ethertype) hdr->h_proto = ethertype; if (eth_p_mpls(skb->protocol)) skb->protocol = ethertype; + + invalidate_flow_key(key); return 0; } -static int set_mpls(struct sk_buff *skb, const __be32 *mpls_lse) +static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key, + const __be32 *mpls_lse) { __be32 *stack; int err; @@ -196,13 +211,12 @@ static int set_mpls(struct sk_buff *skb, const __be32 *mpls_lse) stack = (__be32 *)skb_mpls_header(skb); if (skb->ip_summed == CHECKSUM_COMPLETE) { __be32 diff[] = { ~(*stack), *mpls_lse }; - skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum); } *stack = *mpls_lse; - + key->mpls.top_lse = *mpls_lse; return 0; } @@ -237,7 +251,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) return 0; } -static int pop_vlan(struct sk_buff *skb) +static int pop_vlan(struct sk_buff *skb, struct sw_flow_key *key) { __be16 tci; int err; @@ -255,9 +269,12 @@ static int pop_vlan(struct sk_buff *skb) } /* move next vlan tag to hw accel tag */ if (likely(skb->protocol != htons(ETH_P_8021Q) || - skb->len < VLAN_ETH_HLEN)) + skb->len < VLAN_ETH_HLEN)) { + key->eth.tci = 0; return 0; + } + invalidate_flow_key(key); err = __pop_vlan_tci(skb, &tci); if (unlikely(err)) return err; @@ -266,7 +283,8 @@ static int pop_vlan(struct sk_buff *skb) return 0; } -static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan) +static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_action_push_vlan *vlan) { if (unlikely(vlan_tx_tag_present(skb))) { u16 current_tag; @@ -283,12 +301,15 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla skb->csum = csum_add(skb->csum, csum_partial(skb->data + (2 * ETH_ALEN), VLAN_HLEN, 0)); + invalidate_flow_key(key); + } else { + key->eth.tci = vlan->vlan_tci; } __vlan_hwaccel_put_tag(skb, vlan->vlan_tpid, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); return 0; } -static int set_eth_addr(struct sk_buff *skb, +static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_key_ethernet *eth_key) { int err; @@ -303,11 +324,13 @@ static int set_eth_addr(struct sk_buff *skb, ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); + ether_addr_copy(key->eth.src, eth_key->eth_src); + ether_addr_copy(key->eth.dst, eth_key->eth_dst); return 0; } static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, - __be32 *addr, __be32 new_addr) + __be32 *addr, __be32 new_addr) { int transport_len = skb->len - skb_transport_offset(skb); @@ -386,7 +409,8 @@ static void set_ip_ttl(struct sk_buff *skb, struct iphdr *nh, u8 new_ttl) nh->ttl = new_ttl; } -static int set_ipv4(struct sk_buff *skb, const struct ovs_key_ipv4 *ipv4_key) +static int set_ipv4(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_key_ipv4 *ipv4_key) { struct iphdr *nh; int err; @@ -398,22 +422,31 @@ static int set_ipv4(struct sk_buff *skb, const struct ovs_key_ipv4 *ipv4_key) nh = ip_hdr(skb); - if (ipv4_key->ipv4_src != nh->saddr) + if (ipv4_key->ipv4_src != nh->saddr) { set_ip_addr(skb, nh, &nh->saddr, ipv4_key->ipv4_src); + key->ipv4.addr.src = ipv4_key->ipv4_src; + } - if (ipv4_key->ipv4_dst != nh->daddr) + if (ipv4_key->ipv4_dst != nh->daddr) { set_ip_addr(skb, nh, &nh->daddr, ipv4_key->ipv4_dst); + key->ipv4.addr.dst = ipv4_key->ipv4_dst; + } - if (ipv4_key->ipv4_tos != nh->tos) + if (ipv4_key->ipv4_tos != nh->tos) { ipv4_change_dsfield(nh, 0, ipv4_key->ipv4_tos); + key->ip.tos = nh->tos; + } - if (ipv4_key->ipv4_ttl != nh->ttl) + if (ipv4_key->ipv4_ttl != nh->ttl) { set_ip_ttl(skb, nh, ipv4_key->ipv4_ttl); + key->ip.ttl = ipv4_key->ipv4_ttl; + } return 0; } -static int set_ipv6(struct sk_buff *skb, const struct ovs_key_ipv6 *ipv6_key) +static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_key_ipv6 *ipv6_key) { struct ipv6hdr *nh; int err; @@ -429,9 +462,12 @@ static int set_ipv6(struct sk_buff *skb, const struct ovs_key_ipv6 *ipv6_key) saddr = (__be32 *)&nh->saddr; daddr = (__be32 *)&nh->daddr; - if (memcmp(ipv6_key->ipv6_src, saddr, sizeof(ipv6_key->ipv6_src))) + if (memcmp(ipv6_key->ipv6_src, saddr, sizeof(ipv6_key->ipv6_src))) { set_ipv6_addr(skb, ipv6_key->ipv6_proto, saddr, ipv6_key->ipv6_src, true); + memcpy(&key->ipv6.addr.src, ipv6_key->ipv6_src, + sizeof(ipv6_key->ipv6_src)); + } if (memcmp(ipv6_key->ipv6_dst, daddr, sizeof(ipv6_key->ipv6_dst))) { unsigned int offset = 0; @@ -445,12 +481,18 @@ static int set_ipv6(struct sk_buff *skb, const struct ovs_key_ipv6 *ipv6_key) set_ipv6_addr(skb, ipv6_key->ipv6_proto, daddr, ipv6_key->ipv6_dst, recalc_csum); + memcpy(&key->ipv6.addr.dst, ipv6_key->ipv6_dst, + sizeof(ipv6_key->ipv6_dst)); } set_ipv6_tc(nh, ipv6_key->ipv6_tclass); + key->ip.tos = ipv6_get_dsfield(nh); + set_ipv6_fl(nh, ntohl(ipv6_key->ipv6_label)); - nh->hop_limit = ipv6_key->ipv6_hlimit; + key->ipv6.label = *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL); + nh->hop_limit = ipv6_key->ipv6_hlimit; + key->ip.ttl = ipv6_key->ipv6_hlimit; return 0; } @@ -478,7 +520,8 @@ static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port) } } -static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *udp_port_key) +static int set_udp(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_key_udp *udp_port_key) { struct udphdr *uh; int err; @@ -489,16 +532,21 @@ static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *udp_port_key) return err; uh = udp_hdr(skb); - if (udp_port_key->udp_src != uh->source) + if (udp_port_key->udp_src != uh->source) { set_udp_port(skb, &uh->source, udp_port_key->udp_src); + key->tp.src = udp_port_key->udp_src; + } - if (udp_port_key->udp_dst != uh->dest) + if (udp_port_key->udp_dst != uh->dest) { set_udp_port(skb, &uh->dest, udp_port_key->udp_dst); + key->tp.dst = udp_port_key->udp_dst; + } return 0; } -static int set_tcp(struct sk_buff *skb, const struct ovs_key_tcp *tcp_port_key) +static int set_tcp(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_key_tcp *tcp_port_key) { struct tcphdr *th; int err; @@ -509,17 +557,21 @@ static int set_tcp(struct sk_buff *skb, const struct ovs_key_tcp *tcp_port_key) return err; th = tcp_hdr(skb); - if (tcp_port_key->tcp_src != th->source) + if (tcp_port_key->tcp_src != th->source) { set_tp_port(skb, &th->source, tcp_port_key->tcp_src, &th->check); + key->tp.src = tcp_port_key->tcp_src; + } - if (tcp_port_key->tcp_dst != th->dest) + if (tcp_port_key->tcp_dst != th->dest) { set_tp_port(skb, &th->dest, tcp_port_key->tcp_dst, &th->check); + key->tp.dst = tcp_port_key->tcp_dst; + } return 0; } -static int set_sctp(struct sk_buff *skb, - const struct ovs_key_sctp *sctp_port_key) +static int set_sctp(struct sk_buff *skb, struct sw_flow_key *key, + const struct ovs_key_sctp *sctp_port_key) { struct sctphdr *sh; int err; @@ -546,6 +598,8 @@ static int set_sctp(struct sk_buff *skb, sh->checksum = old_csum ^ old_correct_csum ^ new_csum; skb_clear_hash(skb); + key->tp.src = sctp_port_key->sctp_src; + key->tp.dst = sctp_port_key->sctp_dst; } return 0; @@ -675,18 +729,20 @@ static void execute_hash(struct sk_buff *skb, struct sw_flow_key *key, key->ovs_flow_hash = hash; } -static int execute_set_action(struct sk_buff *skb, - const struct nlattr *nested_attr) +static int execute_set_action(struct sk_buff *skb, struct sw_flow_key *key, + const struct nlattr *nested_attr) { int err = 0; switch (nla_type(nested_attr)) { case OVS_KEY_ATTR_PRIORITY: skb->priority = nla_get_u32(nested_attr); + key->phy.priority = skb->priority; break; case OVS_KEY_ATTR_SKB_MARK: skb->mark = nla_get_u32(nested_attr); + key->phy.skb_mark = skb->mark; break; case OVS_KEY_ATTR_TUNNEL_INFO: @@ -694,31 +750,31 @@ static int execute_set_action(struct sk_buff *skb, break; case OVS_KEY_ATTR_ETHERNET: - err = set_eth_addr(skb, nla_data(nested_attr)); + err = set_eth_addr(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_IPV4: - err = set_ipv4(skb, nla_data(nested_attr)); + err = set_ipv4(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_IPV6: - err = set_ipv6(skb, nla_data(nested_attr)); + err = set_ipv6(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_TCP: - err = set_tcp(skb, nla_data(nested_attr)); + err = set_tcp(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_UDP: - err = set_udp(skb, nla_data(nested_attr)); + err = set_udp(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_SCTP: - err = set_sctp(skb, nla_data(nested_attr)); + err = set_sctp(skb, key, nla_data(nested_attr)); break; case OVS_KEY_ATTR_MPLS: - err = set_mpls(skb, nla_data(nested_attr)); + err = set_mpls(skb, key, nla_data(nested_attr)); break; } @@ -730,11 +786,15 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb, const struct nlattr *a, int rem) { struct deferred_action *da; - int err; - err = ovs_flow_key_update(skb, key); - if (err) - return err; + if (!is_flow_key_valid(key)) { + int err; + + err = ovs_flow_key_update(skb, key); + if (err) + return err; + } + BUG_ON(!is_flow_key_valid(key)); if (!nla_is_last(a, rem)) { /* Recirc action is the not the last action @@ -771,7 +831,8 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, /* Every output action needs a separate clone of 'skb', but the common * case is just a single output action, so that doing a clone and * then freeing the original skbuff is wasteful. So the following code - * is slightly obscure just to avoid that. */ + * is slightly obscure just to avoid that. + */ int prev_port = -1; const struct nlattr *a; int rem; @@ -803,21 +864,21 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, break; case OVS_ACTION_ATTR_PUSH_MPLS: - err = push_mpls(skb, nla_data(a)); + err = push_mpls(skb, key, nla_data(a)); break; case OVS_ACTION_ATTR_POP_MPLS: - err = pop_mpls(skb, nla_get_be16(a)); + err = pop_mpls(skb, key, nla_get_be16(a)); break; case OVS_ACTION_ATTR_PUSH_VLAN: - err = push_vlan(skb, nla_data(a)); + err = push_vlan(skb, key, nla_data(a)); if (unlikely(err)) /* skb already freed. */ return err; break; case OVS_ACTION_ATTR_POP_VLAN: - err = pop_vlan(skb); + err = pop_vlan(skb, key); break; case OVS_ACTION_ATTR_RECIRC: @@ -832,7 +893,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, break; case OVS_ACTION_ATTR_SET: - err = execute_set_action(skb, nla_data(a)); + err = execute_set_action(skb, key, nla_data(a)); break; case OVS_ACTION_ATTR_SAMPLE: -- GitLab From e8eedb85bd238613332570ac6ae683fee94fbe36 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 6 Nov 2014 06:57:27 -0800 Subject: [PATCH 4081/9457] openvswitch: Remove redundant key ref from upcall_info. struct dp_upcall_info has pointer to pkt_key which is already available in OVS_CB. This also simplifies upcall handling for gso packet. Signed-off-by: Pravin B Shelar Acked-by: Andy Zhou --- net/openvswitch/actions.c | 3 +-- net/openvswitch/datapath.c | 45 ++++++++++++++++++++++---------------- net/openvswitch/datapath.h | 12 +++++----- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index d4c2f735d999..10c94ac969f4 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -624,7 +624,6 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, int rem; upcall.cmd = OVS_PACKET_CMD_ACTION; - upcall.key = key; upcall.userdata = NULL; upcall.portid = 0; upcall.egress_tun_info = NULL; @@ -659,7 +658,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb, } /* End of switch. */ } - return ovs_dp_upcall(dp, skb, &upcall); + return ovs_dp_upcall(dp, skb, key, &upcall); } static int sample(struct datapath *dp, struct sk_buff *skb, diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index c2ac340e19fb..7146b38a954e 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -136,8 +136,10 @@ EXPORT_SYMBOL_GPL(lockdep_ovsl_is_held); static struct vport *new_vport(const struct vport_parms *); static int queue_gso_packets(struct datapath *dp, struct sk_buff *, + const struct sw_flow_key *, const struct dp_upcall_info *); static int queue_userspace_packet(struct datapath *dp, struct sk_buff *, + const struct sw_flow_key *, const struct dp_upcall_info *); /* Must be called with rcu_read_lock. */ @@ -271,11 +273,10 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) int error; upcall.cmd = OVS_PACKET_CMD_MISS; - upcall.key = key; upcall.userdata = NULL; upcall.portid = ovs_vport_find_upcall_portid(p, skb); upcall.egress_tun_info = NULL; - error = ovs_dp_upcall(dp, skb, &upcall); + error = ovs_dp_upcall(dp, skb, key, &upcall); if (unlikely(error)) kfree_skb(skb); else @@ -299,6 +300,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) } int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, + const struct sw_flow_key *key, const struct dp_upcall_info *upcall_info) { struct dp_stats_percpu *stats; @@ -310,9 +312,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, } if (!skb_is_gso(skb)) - err = queue_userspace_packet(dp, skb, upcall_info); + err = queue_userspace_packet(dp, skb, key, upcall_info); else - err = queue_gso_packets(dp, skb, upcall_info); + err = queue_gso_packets(dp, skb, key, upcall_info); if (err) goto err; @@ -329,39 +331,43 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, } static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, + const struct sw_flow_key *key, const struct dp_upcall_info *upcall_info) { unsigned short gso_type = skb_shinfo(skb)->gso_type; - struct dp_upcall_info later_info; struct sw_flow_key later_key; struct sk_buff *segs, *nskb; + struct ovs_skb_cb ovs_cb; int err; + ovs_cb = *OVS_CB(skb); segs = __skb_gso_segment(skb, NETIF_F_SG, false); + *OVS_CB(skb) = ovs_cb; if (IS_ERR(segs)) return PTR_ERR(segs); if (segs == NULL) return -EINVAL; + if (gso_type & SKB_GSO_UDP) { + /* The initial flow key extracted by ovs_flow_key_extract() + * in this case is for a first fragment, so we need to + * properly mark later fragments. + */ + later_key = *key; + later_key.ip.frag = OVS_FRAG_TYPE_LATER; + } + /* Queue all of the segments. */ skb = segs; do { - err = queue_userspace_packet(dp, skb, upcall_info); + *OVS_CB(skb) = ovs_cb; + if (gso_type & SKB_GSO_UDP && skb != segs) + key = &later_key; + + err = queue_userspace_packet(dp, skb, key, upcall_info); if (err) break; - if (skb == segs && gso_type & SKB_GSO_UDP) { - /* The initial flow key extracted by ovs_flow_extract() - * in this case is for a first fragment, so we need to - * properly mark later fragments. - */ - later_key = *upcall_info->key; - later_key.ip.frag = OVS_FRAG_TYPE_LATER; - - later_info = *upcall_info; - later_info.key = &later_key; - upcall_info = &later_info; - } } while ((skb = skb->next)); /* Free all of the segments. */ @@ -395,6 +401,7 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info, } static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, + const struct sw_flow_key *key, const struct dp_upcall_info *upcall_info) { struct ovs_header *upcall; @@ -457,7 +464,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, upcall->dp_ifindex = dp_ifindex; nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); - err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb); + err = ovs_nla_put_flow(key, key, user_skb); BUG_ON(err); nla_nest_end(user_skb, nla); diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 2bc577bf9b31..8de9f7e20ae9 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -108,20 +108,18 @@ struct ovs_skb_cb { /** * struct dp_upcall - metadata to include with a packet to send to userspace * @cmd: One of %OVS_PACKET_CMD_*. - * @key: Becomes %OVS_PACKET_ATTR_KEY. Must be nonnull. * @userdata: If nonnull, its variable-length value is passed to userspace as * %OVS_PACKET_ATTR_USERDATA. - * @pid: Netlink PID to which packet should be sent. If @pid is 0 then no - * packet is sent and the packet is accounted in the datapath's @n_lost + * @portid: Netlink portid to which packet should be sent. If @portid is 0 + * then no packet is sent and the packet is accounted in the datapath's @n_lost * counter. * @egress_tun_info: If nonnull, becomes %OVS_PACKET_ATTR_EGRESS_TUN_KEY. */ struct dp_upcall_info { - u8 cmd; - const struct sw_flow_key *key; + const struct ovs_tunnel_info *egress_tun_info; const struct nlattr *userdata; u32 portid; - const struct ovs_tunnel_info *egress_tun_info; + u8 cmd; }; /** @@ -187,7 +185,7 @@ extern struct genl_family dp_vport_genl_family; void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key); void ovs_dp_detach_port(struct vport *); int ovs_dp_upcall(struct datapath *, struct sk_buff *, - const struct dp_upcall_info *); + const struct sw_flow_key *, const struct dp_upcall_info *); const char *ovs_dp_name(const struct datapath *dp); struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq, -- GitLab From 12eb18f7115884b0c1513dda31b0051121116b3a Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 6 Nov 2014 06:58:52 -0800 Subject: [PATCH 4082/9457] openvswitch: Constify various function arguments Help produce better optimized code. Signed-off-by: Thomas Graf Signed-off-by: Pravin B Shelar --- net/openvswitch/actions.c | 7 ++++--- net/openvswitch/datapath.c | 10 +++++----- net/openvswitch/datapath.h | 4 ++-- net/openvswitch/flow.c | 4 ++-- net/openvswitch/flow.h | 11 ++++++----- net/openvswitch/flow_table.c | 12 ++++++------ net/openvswitch/flow_table.h | 8 ++++---- net/openvswitch/vport-geneve.c | 2 +- net/openvswitch/vport-netdev.c | 2 +- net/openvswitch/vport.c | 8 ++++---- net/openvswitch/vport.h | 6 +++--- 11 files changed, 38 insertions(+), 36 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 10c94ac969f4..394efa67934e 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -69,7 +69,7 @@ static void action_fifo_init(struct action_fifo *fifo) fifo->tail = 0; } -static bool action_fifo_is_empty(struct action_fifo *fifo) +static bool action_fifo_is_empty(const struct action_fifo *fifo) { return (fifo->head == fifo->tail); } @@ -92,7 +92,7 @@ static struct deferred_action *action_fifo_put(struct action_fifo *fifo) /* Return true if fifo is not full */ static struct deferred_action *add_deferred_actions(struct sk_buff *skb, - struct sw_flow_key *key, + const struct sw_flow_key *key, const struct nlattr *attr) { struct action_fifo *fifo; @@ -944,7 +944,8 @@ static void process_deferred_actions(struct datapath *dp) /* Execute a list of actions against 'skb'. */ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, - struct sw_flow_actions *acts, struct sw_flow_key *key) + const struct sw_flow_actions *acts, + struct sw_flow_key *key) { int level = this_cpu_read(exec_actions_level); int err; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 7146b38a954e..65561ebb489e 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -178,7 +178,7 @@ const char *ovs_dp_name(const struct datapath *dp) return vport->ops->get_name(vport); } -static int get_dpifindex(struct datapath *dp) +static int get_dpifindex(const struct datapath *dp) { struct vport *local; int ifindex; @@ -633,7 +633,7 @@ static struct genl_family dp_packet_genl_family = { .n_ops = ARRAY_SIZE(dp_packet_genl_ops), }; -static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats, +static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats, struct ovs_dp_megaflow_stats *mega_stats) { int i; @@ -1352,7 +1352,7 @@ static struct sk_buff *ovs_dp_cmd_alloc_info(struct genl_info *info) /* Called with rcu_read_lock or ovs_mutex. */ static struct datapath *lookup_datapath(struct net *net, - struct ovs_header *ovs_header, + const struct ovs_header *ovs_header, struct nlattr *a[OVS_DP_ATTR_MAX + 1]) { struct datapath *dp; @@ -1380,7 +1380,7 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *in dp->user_features = 0; } -static void ovs_dp_change(struct datapath *dp, struct nlattr **a) +static void ovs_dp_change(struct datapath *dp, struct nlattr *a[]) { if (a[OVS_DP_ATTR_USER_FEATURES]) dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]); @@ -1744,7 +1744,7 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid, /* Called with ovs_mutex or RCU read lock. */ static struct vport *lookup_vport(struct net *net, - struct ovs_header *ovs_header, + const struct ovs_header *ovs_header, struct nlattr *a[OVS_VPORT_ATTR_MAX + 1]) { struct datapath *dp; diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 8de9f7e20ae9..8389c1d68e57 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -149,7 +149,7 @@ int lockdep_ovsl_is_held(void); #define rcu_dereference_ovsl(p) \ rcu_dereference_check(p, lockdep_ovsl_is_held()) -static inline struct net *ovs_dp_get_net(struct datapath *dp) +static inline struct net *ovs_dp_get_net(const struct datapath *dp) { return read_pnet(&dp->net); } @@ -192,7 +192,7 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq, u8 cmd); int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, - struct sw_flow_actions *acts, struct sw_flow_key *); + const struct sw_flow_actions *, struct sw_flow_key *); void ovs_dp_notify_wq(struct work_struct *work); diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 90a21010fc8f..25e9abcd51f1 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -66,7 +66,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies) #define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF)) void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, - struct sk_buff *skb) + const struct sk_buff *skb) { struct flow_stats *stats; int node = numa_node_id(); @@ -679,7 +679,7 @@ int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key) return key_extract(skb, key); } -int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info, +int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info, struct sk_buff *skb, struct sw_flow_key *key) { /* Extract metadata from packet. */ diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 543b358ee57f..9e0a787c8627 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -53,7 +53,7 @@ struct ovs_key_ipv4_tunnel { struct ovs_tunnel_info { struct ovs_key_ipv4_tunnel tunnel; - struct geneve_opt *options; + const struct geneve_opt *options; u8 options_len; }; @@ -73,7 +73,7 @@ static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, __be16 tp_dst, __be64 tun_id, __be16 tun_flags, - struct geneve_opt *opts, + const struct geneve_opt *opts, u8 opts_len) { tun_info->tunnel.tun_id = tun_id; @@ -105,7 +105,7 @@ static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, __be16 tp_dst, __be64 tun_id, __be16 tun_flags, - struct geneve_opt *opts, + const struct geneve_opt *opts, u8 opts_len) { __ovs_flow_tun_info_init(tun_info, iph->saddr, iph->daddr, @@ -244,14 +244,15 @@ struct arp_eth_header { } __packed; void ovs_flow_stats_update(struct sw_flow *, __be16 tcp_flags, - struct sk_buff *); + const struct sk_buff *); void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, unsigned long *used, __be16 *tcp_flags); void ovs_flow_stats_clear(struct sw_flow *); u64 ovs_flow_used_time(unsigned long flow_jiffies); int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key); -int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info, struct sk_buff *skb, +int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info, + struct sk_buff *skb, struct sw_flow_key *key); /* Extract key from packet coming from userspace. */ int ovs_flow_key_extract_userspace(const struct nlattr *attr, diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index 90f8b40a350b..e0a7fefc1edf 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c @@ -107,7 +107,7 @@ struct sw_flow *ovs_flow_alloc(void) return ERR_PTR(-ENOMEM); } -int ovs_flow_tbl_count(struct flow_table *table) +int ovs_flow_tbl_count(const struct flow_table *table) { return table->count; } @@ -401,7 +401,7 @@ static bool flow_cmp_masked_key(const struct sw_flow *flow, } bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, - struct sw_flow_match *match) + const struct sw_flow_match *match) { struct sw_flow_key *key = match->key; int key_start = flow_key_start(key); @@ -412,7 +412,7 @@ bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, static struct sw_flow *masked_flow_lookup(struct table_instance *ti, const struct sw_flow_key *unmasked, - struct sw_flow_mask *mask) + const struct sw_flow_mask *mask) { struct sw_flow *flow; struct hlist_head *head; @@ -460,7 +460,7 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl, } struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, - struct sw_flow_match *match) + const struct sw_flow_match *match) { struct table_instance *ti = rcu_dereference_ovsl(tbl->ti); struct sw_flow_mask *mask; @@ -563,7 +563,7 @@ static struct sw_flow_mask *flow_mask_find(const struct flow_table *tbl, /* Add 'mask' into the mask list, if it is not already there. */ static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow, - struct sw_flow_mask *new) + const struct sw_flow_mask *new) { struct sw_flow_mask *mask; mask = flow_mask_find(tbl, new); @@ -586,7 +586,7 @@ static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow, /* Must be called with OVS mutex held. */ int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, - struct sw_flow_mask *mask) + const struct sw_flow_mask *mask) { struct table_instance *new_ti = NULL; struct table_instance *ti; diff --git a/net/openvswitch/flow_table.h b/net/openvswitch/flow_table.h index f682c8c07f44..309fa6415689 100644 --- a/net/openvswitch/flow_table.h +++ b/net/openvswitch/flow_table.h @@ -61,12 +61,12 @@ struct sw_flow *ovs_flow_alloc(void); void ovs_flow_free(struct sw_flow *, bool deferred); int ovs_flow_tbl_init(struct flow_table *); -int ovs_flow_tbl_count(struct flow_table *table); +int ovs_flow_tbl_count(const struct flow_table *table); void ovs_flow_tbl_destroy(struct flow_table *table); int ovs_flow_tbl_flush(struct flow_table *flow_table); int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, - struct sw_flow_mask *mask); + const struct sw_flow_mask *mask); void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow); int ovs_flow_tbl_num_masks(const struct flow_table *table); struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *table, @@ -77,9 +77,9 @@ struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *, struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *, const struct sw_flow_key *); struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl, - struct sw_flow_match *match); + const struct sw_flow_match *match); bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow, - struct sw_flow_match *match); + const struct sw_flow_match *match); void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src, const struct sw_flow_mask *mask); diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index e31f19c922e2..347fa2325b22 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c @@ -68,7 +68,7 @@ static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni) } /* Convert 24 bit VNI to 64 bit tunnel ID. */ -static __be64 vni_to_tunnel_id(__u8 *vni) +static __be64 vni_to_tunnel_id(const __u8 *vni) { #ifdef __BIG_ENDIAN return (vni[0] << 16) | (vni[1] << 8) | vni[2]; diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 877ee74b4f08..4776282c6417 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -77,7 +77,7 @@ static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb) return RX_HANDLER_CONSUMED; } -static struct net_device *get_dpdev(struct datapath *dp) +static struct net_device *get_dpdev(const struct datapath *dp) { struct vport *local; diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 630e81984b65..e771a46933e5 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -68,7 +68,7 @@ void ovs_vport_exit(void) kfree(dev_table); } -static struct hlist_head *hash_bucket(struct net *net, const char *name) +static struct hlist_head *hash_bucket(const struct net *net, const char *name) { unsigned int hash = jhash(name, strlen(name), (unsigned long) net); return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; @@ -107,7 +107,7 @@ EXPORT_SYMBOL_GPL(ovs_vport_ops_unregister); * * Must be called with ovs or RCU read lock. */ -struct vport *ovs_vport_locate(struct net *net, const char *name) +struct vport *ovs_vport_locate(const struct net *net, const char *name) { struct hlist_head *bucket = hash_bucket(net, name); struct vport *vport; @@ -380,7 +380,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb) * * Must be called with ovs_mutex. */ -int ovs_vport_set_upcall_portids(struct vport *vport, struct nlattr *ids) +int ovs_vport_set_upcall_portids(struct vport *vport, const struct nlattr *ids) { struct vport_portids *old, *vport_portids; @@ -471,7 +471,7 @@ u32 ovs_vport_find_upcall_portid(const struct vport *vport, struct sk_buff *skb) * skb->data should point to the Ethernet header. */ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, - struct ovs_tunnel_info *tun_info) + const struct ovs_tunnel_info *tun_info) { struct pcpu_sw_netstats *stats; struct sw_flow_key key; diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index 0635d1d761e9..99c8e71d9e6c 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h @@ -45,14 +45,14 @@ void ovs_vport_exit(void); struct vport *ovs_vport_add(const struct vport_parms *); void ovs_vport_del(struct vport *); -struct vport *ovs_vport_locate(struct net *net, const char *name); +struct vport *ovs_vport_locate(const struct net *net, const char *name); void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *); int ovs_vport_set_options(struct vport *, struct nlattr *options); int ovs_vport_get_options(const struct vport *, struct sk_buff *); -int ovs_vport_set_upcall_portids(struct vport *, struct nlattr *pids); +int ovs_vport_set_upcall_portids(struct vport *, const struct nlattr *pids); int ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *); u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *); @@ -224,7 +224,7 @@ static inline struct vport *vport_from_priv(void *priv) } void ovs_vport_receive(struct vport *, struct sk_buff *, - struct ovs_tunnel_info *); + const struct ovs_tunnel_info *); static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb, const void *start, unsigned int len) -- GitLab From 05da5898a96c05e32aa9850c9cd89eef29471b13 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Thu, 6 Nov 2014 07:03:05 -0800 Subject: [PATCH 4083/9457] openvswitch: Add support for OVS_FLOW_ATTR_PROBE. This new flag is useful for suppressing error logging while probing for datapath features using flow commands. For backwards compatibility reasons the commands are executed normally, but error logging is suppressed. Signed-off-by: Jarno Rajahalme Signed-off-by: Pravin B Shelar --- include/uapi/linux/openvswitch.h | 2 + net/openvswitch/datapath.c | 49 +++-- net/openvswitch/datapath.h | 6 +- net/openvswitch/flow.c | 4 +- net/openvswitch/flow.h | 2 +- net/openvswitch/flow_netlink.c | 303 +++++++++++++++++-------------- net/openvswitch/flow_netlink.h | 10 +- 7 files changed, 208 insertions(+), 168 deletions(-) diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index cf8185661e52..3a6dcaa359b7 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -457,6 +457,8 @@ enum ovs_flow_attr { OVS_FLOW_ATTR_USED, /* u64 msecs last used in monotonic time. */ OVS_FLOW_ATTR_CLEAR, /* Flag to clear stats, tcp_flags, used. */ OVS_FLOW_ATTR_MASK, /* Sequence of OVS_KEY_ATTR_* attributes. */ + OVS_FLOW_ATTR_PROBE, /* Flow operation is a feature probe, error + * logging should be suppressed. */ __OVS_FLOW_ATTR_MAX }; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 65561ebb489e..ab141d49bb9d 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -526,6 +526,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) struct vport *input_vport; int len; int err; + bool log = !a[OVS_FLOW_ATTR_PROBE]; err = -EINVAL; if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || @@ -559,12 +560,12 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) goto err_kfree_skb; err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet, - &flow->key); + &flow->key, log); if (err) goto err_flow_free; err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], - &flow->key, &acts); + &flow->key, &acts, log); if (err) goto err_flow_free; @@ -855,15 +856,16 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) struct sw_flow_actions *acts; struct sw_flow_match match; int error; + bool log = !a[OVS_FLOW_ATTR_PROBE]; /* Must have key and actions. */ error = -EINVAL; if (!a[OVS_FLOW_ATTR_KEY]) { - OVS_NLERR("Flow key attribute not present in new flow.\n"); + OVS_NLERR(log, "Flow key attr not present in new flow."); goto error; } if (!a[OVS_FLOW_ATTR_ACTIONS]) { - OVS_NLERR("Flow actions attribute not present in new flow.\n"); + OVS_NLERR(log, "Flow actions attr not present in new flow."); goto error; } @@ -878,8 +880,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) /* Extract key. */ ovs_match_init(&match, &new_flow->unmasked_key, &mask); - error = ovs_nla_get_match(&match, - a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]); + error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], + a[OVS_FLOW_ATTR_MASK], log); if (error) goto err_kfree_flow; @@ -887,9 +889,9 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) /* Validate actions. */ error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key, - &acts); + &acts, log); if (error) { - OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); + OVS_NLERR(log, "Flow actions may not be safe on all matching packets."); goto err_kfree_flow; } @@ -942,6 +944,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) } /* The unmasked key has to be the same for flow updates. */ if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) { + /* Look for any overlapping flow. */ flow = ovs_flow_tbl_lookup_exact(&dp->table, &match); if (!flow) { error = -ENOENT; @@ -984,16 +987,18 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) /* Factor out action copy to avoid "Wframe-larger-than=1024" warning. */ static struct sw_flow_actions *get_flow_actions(const struct nlattr *a, const struct sw_flow_key *key, - const struct sw_flow_mask *mask) + const struct sw_flow_mask *mask, + bool log) { struct sw_flow_actions *acts; struct sw_flow_key masked_key; int error; ovs_flow_mask_key(&masked_key, key, mask); - error = ovs_nla_copy_actions(a, &masked_key, &acts); + error = ovs_nla_copy_actions(a, &masked_key, &acts, log); if (error) { - OVS_NLERR("Actions may not be safe on all matching packets.\n"); + OVS_NLERR(log, + "Actions may not be safe on all matching packets"); return ERR_PTR(error); } @@ -1012,23 +1017,25 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) struct sw_flow_actions *old_acts = NULL, *acts = NULL; struct sw_flow_match match; int error; + bool log = !a[OVS_FLOW_ATTR_PROBE]; /* Extract key. */ error = -EINVAL; if (!a[OVS_FLOW_ATTR_KEY]) { - OVS_NLERR("Flow key attribute not present in set flow.\n"); + OVS_NLERR(log, "Flow key attribute not present in set flow."); goto error; } ovs_match_init(&match, &key, &mask); - error = ovs_nla_get_match(&match, - a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]); + error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], + a[OVS_FLOW_ATTR_MASK], log); if (error) goto error; /* Validate actions. */ if (a[OVS_FLOW_ATTR_ACTIONS]) { - acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask); + acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask, + log); if (IS_ERR(acts)) { error = PTR_ERR(acts); goto error; @@ -1109,14 +1116,16 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info) struct datapath *dp; struct sw_flow_match match; int err; + bool log = !a[OVS_FLOW_ATTR_PROBE]; if (!a[OVS_FLOW_ATTR_KEY]) { - OVS_NLERR("Flow get message rejected, Key attribute missing.\n"); + OVS_NLERR(log, + "Flow get message rejected, Key attribute missing."); return -EINVAL; } ovs_match_init(&match, &key, NULL); - err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); + err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, log); if (err) return err; @@ -1157,10 +1166,12 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info) struct datapath *dp; struct sw_flow_match match; int err; + bool log = !a[OVS_FLOW_ATTR_PROBE]; if (likely(a[OVS_FLOW_ATTR_KEY])) { ovs_match_init(&match, &key, NULL); - err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); + err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, + log); if (unlikely(err)) return err; } @@ -1250,8 +1261,10 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = { [OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED }, + [OVS_FLOW_ATTR_MASK] = { .type = NLA_NESTED }, [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED }, [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, + [OVS_FLOW_ATTR_PROBE] = { .type = NLA_FLAG }, }; static const struct genl_ops dp_flow_genl_ops[] = { diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 8389c1d68e57..3ece94563079 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -199,9 +199,9 @@ void ovs_dp_notify_wq(struct work_struct *work); int action_fifos_init(void); void action_fifos_exit(void); -#define OVS_NLERR(fmt, ...) \ +#define OVS_NLERR(logging_allowed, fmt, ...) \ do { \ - if (net_ratelimit()) \ - pr_info("netlink: " fmt, ##__VA_ARGS__); \ + if (logging_allowed && net_ratelimit()) \ + pr_info("netlink: " fmt "\n", ##__VA_ARGS__); \ } while (0) #endif /* datapath.h */ diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 25e9abcd51f1..70bef2ab7f2b 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -712,12 +712,12 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info, int ovs_flow_key_extract_userspace(const struct nlattr *attr, struct sk_buff *skb, - struct sw_flow_key *key) + struct sw_flow_key *key, bool log) { int err; /* Extract metadata from netlink attributes. */ - err = ovs_nla_get_flow_metadata(attr, key); + err = ovs_nla_get_flow_metadata(attr, key, log); if (err) return err; diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 9e0a787c8627..a8b30f334388 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -257,6 +257,6 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info, /* Extract key from packet coming from userspace. */ int ovs_flow_key_extract_userspace(const struct nlattr *attr, struct sk_buff *skb, - struct sw_flow_key *key); + struct sw_flow_key *key, bool log); #endif /* flow.h */ diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 98a3e96b7d93..c0d066def228 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -112,7 +112,7 @@ static void update_range(struct sw_flow_match *match, } while (0) static bool match_validate(const struct sw_flow_match *match, - u64 key_attrs, u64 mask_attrs) + u64 key_attrs, u64 mask_attrs, bool log) { u64 key_expected = 1 << OVS_KEY_ATTR_ETHERNET; u64 mask_allowed = key_attrs; /* At most allow all key attributes */ @@ -230,15 +230,17 @@ static bool match_validate(const struct sw_flow_match *match, if ((key_attrs & key_expected) != key_expected) { /* Key attributes check failed. */ - OVS_NLERR("Missing expected key attributes (key_attrs=%llx, expected=%llx).\n", - (unsigned long long)key_attrs, (unsigned long long)key_expected); + OVS_NLERR(log, "Missing key (keys=%llx, expected=%llx)", + (unsigned long long)key_attrs, + (unsigned long long)key_expected); return false; } if ((mask_attrs & mask_allowed) != mask_attrs) { /* Mask attributes check failed. */ - OVS_NLERR("Contain more than allowed mask fields (mask_attrs=%llx, mask_allowed=%llx).\n", - (unsigned long long)mask_attrs, (unsigned long long)mask_allowed); + OVS_NLERR(log, "Unexpected mask (mask=%llx, allowed=%llx)", + (unsigned long long)mask_attrs, + (unsigned long long)mask_allowed); return false; } @@ -328,7 +330,7 @@ static bool is_all_zero(const u8 *fp, size_t size) static int __parse_flow_nlattrs(const struct nlattr *attr, const struct nlattr *a[], - u64 *attrsp, bool nz) + u64 *attrsp, bool log, bool nz) { const struct nlattr *nla; u64 attrs; @@ -340,21 +342,20 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, int expected_len; if (type > OVS_KEY_ATTR_MAX) { - OVS_NLERR("Unknown key attribute (type=%d, max=%d).\n", + OVS_NLERR(log, "Key type %d is out of range max %d", type, OVS_KEY_ATTR_MAX); return -EINVAL; } if (attrs & (1 << type)) { - OVS_NLERR("Duplicate key attribute (type %d).\n", type); + OVS_NLERR(log, "Duplicate key (type %d).", type); return -EINVAL; } expected_len = ovs_key_lens[type]; if (nla_len(nla) != expected_len && expected_len != -1) { - OVS_NLERR("Key attribute has unexpected length (type=%d" - ", length=%d, expected=%d).\n", type, - nla_len(nla), expected_len); + OVS_NLERR(log, "Key %d has unexpected len %d expected %d", + type, nla_len(nla), expected_len); return -EINVAL; } @@ -364,7 +365,7 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, } } if (rem) { - OVS_NLERR("Message has %d unknown bytes.\n", rem); + OVS_NLERR(log, "Message has %d unknown bytes.", rem); return -EINVAL; } @@ -373,28 +374,84 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, } static int parse_flow_mask_nlattrs(const struct nlattr *attr, - const struct nlattr *a[], u64 *attrsp) + const struct nlattr *a[], u64 *attrsp, + bool log) { - return __parse_flow_nlattrs(attr, a, attrsp, true); + return __parse_flow_nlattrs(attr, a, attrsp, log, true); } static int parse_flow_nlattrs(const struct nlattr *attr, - const struct nlattr *a[], u64 *attrsp) + const struct nlattr *a[], u64 *attrsp, + bool log) { - return __parse_flow_nlattrs(attr, a, attrsp, false); + return __parse_flow_nlattrs(attr, a, attrsp, log, false); +} + +static int genev_tun_opt_from_nlattr(const struct nlattr *a, + struct sw_flow_match *match, bool is_mask, + bool log) +{ + unsigned long opt_key_offset; + + if (nla_len(a) > sizeof(match->key->tun_opts)) { + OVS_NLERR(log, "Geneve option length err (len %d, max %zu).", + nla_len(a), sizeof(match->key->tun_opts)); + return -EINVAL; + } + + if (nla_len(a) % 4 != 0) { + OVS_NLERR(log, "Geneve opt len %d is not a multiple of 4.", + nla_len(a)); + return -EINVAL; + } + + /* We need to record the length of the options passed + * down, otherwise packets with the same format but + * additional options will be silently matched. + */ + if (!is_mask) { + SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a), + false); + } else { + /* This is somewhat unusual because it looks at + * both the key and mask while parsing the + * attributes (and by extension assumes the key + * is parsed first). Normally, we would verify + * that each is the correct length and that the + * attributes line up in the validate function. + * However, that is difficult because this is + * variable length and we won't have the + * information later. + */ + if (match->key->tun_opts_len != nla_len(a)) { + OVS_NLERR(log, "Geneve option len %d != mask len %d", + match->key->tun_opts_len, nla_len(a)); + return -EINVAL; + } + + SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); + } + + opt_key_offset = (unsigned long)GENEVE_OPTS((struct sw_flow_key *)0, + nla_len(a)); + SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), + nla_len(a), is_mask); + return 0; } static int ipv4_tun_from_nlattr(const struct nlattr *attr, - struct sw_flow_match *match, bool is_mask) + struct sw_flow_match *match, bool is_mask, + bool log) { struct nlattr *a; int rem; bool ttl = false; __be16 tun_flags = 0; - unsigned long opt_key_offset; nla_for_each_nested(a, attr, rem) { int type = nla_type(a); + int err; + static const u32 ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { [OVS_TUNNEL_KEY_ATTR_ID] = sizeof(u64), [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = sizeof(u32), @@ -410,15 +467,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, }; if (type > OVS_TUNNEL_KEY_ATTR_MAX) { - OVS_NLERR("Unknown IPv4 tunnel attribute (type=%d, max=%d).\n", - type, OVS_TUNNEL_KEY_ATTR_MAX); + OVS_NLERR(log, "Tunnel attr %d out of range max %d", + type, OVS_TUNNEL_KEY_ATTR_MAX); return -EINVAL; } if (ovs_tunnel_key_lens[type] != nla_len(a) && ovs_tunnel_key_lens[type] != -1) { - OVS_NLERR("IPv4 tunnel attribute type has unexpected " - " length (type=%d, length=%d, expected=%d).\n", + OVS_NLERR(log, "Tunnel attr %d has unexpected len %d expected %d", type, nla_len(a), ovs_tunnel_key_lens[type]); return -EINVAL; } @@ -464,58 +520,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, tun_flags |= TUNNEL_OAM; break; case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS: - tun_flags |= TUNNEL_OPTIONS_PRESENT; - if (nla_len(a) > sizeof(match->key->tun_opts)) { - OVS_NLERR("Geneve option length exceeds maximum size (len %d, max %zu).\n", - nla_len(a), - sizeof(match->key->tun_opts)); - return -EINVAL; - } - - if (nla_len(a) % 4 != 0) { - OVS_NLERR("Geneve option length is not a multiple of 4 (len %d).\n", - nla_len(a)); - return -EINVAL; - } - - /* We need to record the length of the options passed - * down, otherwise packets with the same format but - * additional options will be silently matched. - */ - if (!is_mask) { - SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a), - false); - } else { - /* This is somewhat unusual because it looks at - * both the key and mask while parsing the - * attributes (and by extension assumes the key - * is parsed first). Normally, we would verify - * that each is the correct length and that the - * attributes line up in the validate function. - * However, that is difficult because this is - * variable length and we won't have the - * information later. - */ - if (match->key->tun_opts_len != nla_len(a)) { - OVS_NLERR("Geneve option key length (%d) is different from mask length (%d).", - match->key->tun_opts_len, - nla_len(a)); - return -EINVAL; - } - - SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, - true); - } + err = genev_tun_opt_from_nlattr(a, match, is_mask, log); + if (err) + return err; - opt_key_offset = (unsigned long)GENEVE_OPTS( - (struct sw_flow_key *)0, - nla_len(a)); - SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, - nla_data(a), nla_len(a), - is_mask); + tun_flags |= TUNNEL_OPTIONS_PRESENT; break; default: - OVS_NLERR("Unknown IPv4 tunnel attribute (%d).\n", + OVS_NLERR(log, "Unknown IPv4 tunnel attribute %d", type); return -EINVAL; } @@ -524,18 +536,19 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask); if (rem > 0) { - OVS_NLERR("IPv4 tunnel attribute has %d unknown bytes.\n", rem); + OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.", + rem); return -EINVAL; } if (!is_mask) { if (!match->key->tun_key.ipv4_dst) { - OVS_NLERR("IPv4 tunnel destination address is zero.\n"); + OVS_NLERR(log, "IPv4 tunnel dst address is zero"); return -EINVAL; } if (!ttl) { - OVS_NLERR("IPv4 tunnel TTL not specified.\n"); + OVS_NLERR(log, "IPv4 tunnel TTL not specified."); return -EINVAL; } } @@ -614,7 +627,8 @@ int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb, } static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, - const struct nlattr **a, bool is_mask) + const struct nlattr **a, bool is_mask, + bool log) { if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) { u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]); @@ -642,7 +656,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, if (is_mask) { in_port = 0xffffffff; /* Always exact match in_port. */ } else if (in_port >= DP_MAX_PORTS) { - OVS_NLERR("Port (%d) exceeds maximum allowable (%d).\n", + OVS_NLERR(log, "Port %d exceeds max allowable %d", in_port, DP_MAX_PORTS); return -EINVAL; } @@ -661,7 +675,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, } if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) { if (ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match, - is_mask)) + is_mask, log)) return -EINVAL; *attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL); } @@ -669,11 +683,12 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, } static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, - const struct nlattr **a, bool is_mask) + const struct nlattr **a, bool is_mask, + bool log) { int err; - err = metadata_from_nlattrs(match, &attrs, a, is_mask); + err = metadata_from_nlattrs(match, &attrs, a, is_mask, log); if (err) return err; @@ -694,9 +709,9 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); if (!(tci & htons(VLAN_TAG_PRESENT))) { if (is_mask) - OVS_NLERR("VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit.\n"); + OVS_NLERR(log, "VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit."); else - OVS_NLERR("VLAN TCI does not have VLAN_TAG_PRESENT bit set.\n"); + OVS_NLERR(log, "VLAN TCI does not have VLAN_TAG_PRESENT bit set."); return -EINVAL; } @@ -713,8 +728,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, /* Always exact match EtherType. */ eth_type = htons(0xffff); } else if (ntohs(eth_type) < ETH_P_802_3_MIN) { - OVS_NLERR("EtherType is less than minimum (type=%x, min=%x).\n", - ntohs(eth_type), ETH_P_802_3_MIN); + OVS_NLERR(log, "EtherType %x is less than min %x", + ntohs(eth_type), ETH_P_802_3_MIN); return -EINVAL; } @@ -729,8 +744,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, ipv4_key = nla_data(a[OVS_KEY_ATTR_IPV4]); if (!is_mask && ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX) { - OVS_NLERR("Unknown IPv4 fragment type (value=%d, max=%d).\n", - ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX); + OVS_NLERR(log, "IPv4 frag type %d is out of range max %d", + ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX); return -EINVAL; } SW_FLOW_KEY_PUT(match, ip.proto, @@ -753,8 +768,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, ipv6_key = nla_data(a[OVS_KEY_ATTR_IPV6]); if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX) { - OVS_NLERR("Unknown IPv6 fragment type (value=%d, max=%d).\n", - ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); + OVS_NLERR(log, "IPv6 frag type %d is out of range max %d", + ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); return -EINVAL; } SW_FLOW_KEY_PUT(match, ipv6.label, @@ -784,7 +799,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, arp_key = nla_data(a[OVS_KEY_ATTR_ARP]); if (!is_mask && (arp_key->arp_op & htons(0xff00))) { - OVS_NLERR("Unknown ARP opcode (opcode=%d).\n", + OVS_NLERR(log, "Unknown ARP opcode (opcode=%d).", arp_key->arp_op); return -EINVAL; } @@ -885,7 +900,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, } if (attrs != 0) { - OVS_NLERR("Unknown key attributes (%llx).\n", + OVS_NLERR(log, "Unknown key attributes %llx", (unsigned long long)attrs); return -EINVAL; } @@ -926,10 +941,14 @@ static void mask_set_nlattr(struct nlattr *attr, u8 val) * of this flow. * @mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink * attribute specifies the mask field of the wildcarded flow. + * @log: Boolean to allow kernel error logging. Normally true, but when + * probing for feature compatibility this should be passed in as false to + * suppress unnecessary error logging. */ int ovs_nla_get_match(struct sw_flow_match *match, const struct nlattr *nla_key, - const struct nlattr *nla_mask) + const struct nlattr *nla_mask, + bool log) { const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; const struct nlattr *encap; @@ -939,7 +958,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, bool encap_valid = false; int err; - err = parse_flow_nlattrs(nla_key, a, &key_attrs); + err = parse_flow_nlattrs(nla_key, a, &key_attrs, log); if (err) return err; @@ -950,7 +969,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) && (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) { - OVS_NLERR("Invalid Vlan frame.\n"); + OVS_NLERR(log, "Invalid Vlan frame."); return -EINVAL; } @@ -961,22 +980,22 @@ int ovs_nla_get_match(struct sw_flow_match *match, encap_valid = true; if (tci & htons(VLAN_TAG_PRESENT)) { - err = parse_flow_nlattrs(encap, a, &key_attrs); + err = parse_flow_nlattrs(encap, a, &key_attrs, log); if (err) return err; } else if (!tci) { /* Corner case for truncated 802.1Q header. */ if (nla_len(encap)) { - OVS_NLERR("Truncated 802.1Q header has non-zero encap attribute.\n"); + OVS_NLERR(log, "Truncated 802.1Q header has non-zero encap attribute."); return -EINVAL; } } else { - OVS_NLERR("Encap attribute is set for a non-VLAN frame.\n"); + OVS_NLERR(log, "Encap attr is set for non-VLAN frame"); return -EINVAL; } } - err = ovs_key_from_nlattrs(match, key_attrs, a, false); + err = ovs_key_from_nlattrs(match, key_attrs, a, false, log); if (err) return err; @@ -1010,7 +1029,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, nla_mask = newmask; } - err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs); + err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs, log); if (err) goto free_newmask; @@ -1022,7 +1041,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, __be16 tci = 0; if (!encap_valid) { - OVS_NLERR("Encap mask attribute is set for non-VLAN frame.\n"); + OVS_NLERR(log, "Encap mask attribute is set for non-VLAN frame."); err = -EINVAL; goto free_newmask; } @@ -1034,12 +1053,13 @@ int ovs_nla_get_match(struct sw_flow_match *match, if (eth_type == htons(0xffff)) { mask_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE); encap = a[OVS_KEY_ATTR_ENCAP]; - err = parse_flow_mask_nlattrs(encap, a, &mask_attrs); + err = parse_flow_mask_nlattrs(encap, a, + &mask_attrs, log); if (err) goto free_newmask; } else { - OVS_NLERR("VLAN frames must have an exact match on the TPID (mask=%x).\n", - ntohs(eth_type)); + OVS_NLERR(log, "VLAN frames must have an exact match on the TPID (mask=%x).", + ntohs(eth_type)); err = -EINVAL; goto free_newmask; } @@ -1048,18 +1068,19 @@ int ovs_nla_get_match(struct sw_flow_match *match, tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); if (!(tci & htons(VLAN_TAG_PRESENT))) { - OVS_NLERR("VLAN tag present bit must have an exact match (tci_mask=%x).\n", ntohs(tci)); + OVS_NLERR(log, "VLAN tag present bit must have an exact match (tci_mask=%x).", + ntohs(tci)); err = -EINVAL; goto free_newmask; } } - err = ovs_key_from_nlattrs(match, mask_attrs, a, true); + err = ovs_key_from_nlattrs(match, mask_attrs, a, true, log); if (err) goto free_newmask; } - if (!match_validate(match, key_attrs, mask_attrs)) + if (!match_validate(match, key_attrs, mask_attrs, log)) err = -EINVAL; free_newmask: @@ -1072,6 +1093,9 @@ int ovs_nla_get_match(struct sw_flow_match *match, * @key: Receives extracted in_port, priority, tun_key and skb_mark. * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute * sequence. + * @log: Boolean to allow kernel error logging. Normally true, but when + * probing for feature compatibility this should be passed in as false to + * suppress unnecessary error logging. * * This parses a series of Netlink attributes that form a flow key, which must * take the same form accepted by flow_from_nlattrs(), but only enough of it to @@ -1080,14 +1104,15 @@ int ovs_nla_get_match(struct sw_flow_match *match, */ int ovs_nla_get_flow_metadata(const struct nlattr *attr, - struct sw_flow_key *key) + struct sw_flow_key *key, + bool log) { const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; struct sw_flow_match match; u64 attrs = 0; int err; - err = parse_flow_nlattrs(attr, a, &attrs); + err = parse_flow_nlattrs(attr, a, &attrs, log); if (err) return -EINVAL; @@ -1096,7 +1121,7 @@ int ovs_nla_get_flow_metadata(const struct nlattr *attr, key->phy.in_port = DP_MAX_PORTS; - return metadata_from_nlattrs(&match, &attrs, a, false); + return metadata_from_nlattrs(&match, &attrs, a, false, log); } int ovs_nla_put_flow(const struct sw_flow_key *swkey, @@ -1316,12 +1341,12 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, #define MAX_ACTIONS_BUFSIZE (32 * 1024) -static struct sw_flow_actions *nla_alloc_flow_actions(int size) +static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log) { struct sw_flow_actions *sfa; if (size > MAX_ACTIONS_BUFSIZE) { - OVS_NLERR("Flow action size (%u bytes) exceeds maximum", size); + OVS_NLERR(log, "Flow action size %u bytes exceeds max", size); return ERR_PTR(-EINVAL); } @@ -1341,7 +1366,7 @@ void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts) } static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, - int attr_len) + int attr_len, bool log) { struct sw_flow_actions *acts; @@ -1361,7 +1386,7 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, new_acts_size = MAX_ACTIONS_BUFSIZE; } - acts = nla_alloc_flow_actions(new_acts_size); + acts = nla_alloc_flow_actions(new_acts_size, log); if (IS_ERR(acts)) return (void *)acts; @@ -1376,11 +1401,11 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, } static struct nlattr *__add_action(struct sw_flow_actions **sfa, - int attrtype, void *data, int len) + int attrtype, void *data, int len, bool log) { struct nlattr *a; - a = reserve_sfa_size(sfa, nla_attr_size(len)); + a = reserve_sfa_size(sfa, nla_attr_size(len), log); if (IS_ERR(a)) return a; @@ -1395,11 +1420,11 @@ static struct nlattr *__add_action(struct sw_flow_actions **sfa, } static int add_action(struct sw_flow_actions **sfa, int attrtype, - void *data, int len) + void *data, int len, bool log) { struct nlattr *a; - a = __add_action(sfa, attrtype, data, len); + a = __add_action(sfa, attrtype, data, len, log); if (IS_ERR(a)) return PTR_ERR(a); @@ -1407,12 +1432,12 @@ static int add_action(struct sw_flow_actions **sfa, int attrtype, } static inline int add_nested_action_start(struct sw_flow_actions **sfa, - int attrtype) + int attrtype, bool log) { int used = (*sfa)->actions_len; int err; - err = add_action(sfa, attrtype, NULL, 0); + err = add_action(sfa, attrtype, NULL, 0, log); if (err) return err; @@ -1431,12 +1456,12 @@ static inline void add_nested_action_end(struct sw_flow_actions *sfa, static int __ovs_nla_copy_actions(const struct nlattr *attr, const struct sw_flow_key *key, int depth, struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci); + __be16 eth_type, __be16 vlan_tci, bool log); static int validate_and_copy_sample(const struct nlattr *attr, const struct sw_flow_key *key, int depth, struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci) + __be16 eth_type, __be16 vlan_tci, bool log) { const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1]; const struct nlattr *probability, *actions; @@ -1462,19 +1487,19 @@ static int validate_and_copy_sample(const struct nlattr *attr, return -EINVAL; /* validation done, copy sample action. */ - start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE); + start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE, log); if (start < 0) return start; err = add_action(sfa, OVS_SAMPLE_ATTR_PROBABILITY, - nla_data(probability), sizeof(u32)); + nla_data(probability), sizeof(u32), log); if (err) return err; - st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS); + st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS, log); if (st_acts < 0) return st_acts; err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa, - eth_type, vlan_tci); + eth_type, vlan_tci, log); if (err) return err; @@ -1511,7 +1536,7 @@ void ovs_match_init(struct sw_flow_match *match, } static int validate_and_copy_set_tun(const struct nlattr *attr, - struct sw_flow_actions **sfa) + struct sw_flow_actions **sfa, bool log) { struct sw_flow_match match; struct sw_flow_key key; @@ -1520,7 +1545,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, int err, start; ovs_match_init(&match, &key, NULL); - err = ipv4_tun_from_nlattr(nla_data(attr), &match, false); + err = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log); if (err) return err; @@ -1549,12 +1574,12 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, key.tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0; }; - start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET); + start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log); if (start < 0) return start; a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL, - sizeof(*tun_info) + key.tun_opts_len); + sizeof(*tun_info) + key.tun_opts_len, log); if (IS_ERR(a)) return PTR_ERR(a); @@ -1582,7 +1607,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, static int validate_set(const struct nlattr *a, const struct sw_flow_key *flow_key, struct sw_flow_actions **sfa, - bool *set_tun, __be16 eth_type) + bool *set_tun, __be16 eth_type, bool log) { const struct nlattr *ovs_key = nla_data(a); int key_type = nla_type(ovs_key); @@ -1611,7 +1636,7 @@ static int validate_set(const struct nlattr *a, return -EINVAL; *set_tun = true; - err = validate_and_copy_set_tun(a, sfa); + err = validate_and_copy_set_tun(a, sfa, log); if (err) return err; break; @@ -1704,12 +1729,12 @@ static int validate_userspace(const struct nlattr *attr) } static int copy_action(const struct nlattr *from, - struct sw_flow_actions **sfa) + struct sw_flow_actions **sfa, bool log) { int totlen = NLA_ALIGN(from->nla_len); struct nlattr *to; - to = reserve_sfa_size(sfa, from->nla_len); + to = reserve_sfa_size(sfa, from->nla_len, log); if (IS_ERR(to)) return PTR_ERR(to); @@ -1720,7 +1745,7 @@ static int copy_action(const struct nlattr *from, static int __ovs_nla_copy_actions(const struct nlattr *attr, const struct sw_flow_key *key, int depth, struct sw_flow_actions **sfa, - __be16 eth_type, __be16 vlan_tci) + __be16 eth_type, __be16 vlan_tci, bool log) { const struct nlattr *a; bool out_tnl_port = false; @@ -1843,7 +1868,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, case OVS_ACTION_ATTR_SET: err = validate_set(a, key, sfa, - &out_tnl_port, eth_type); + &out_tnl_port, eth_type, log); if (err) return err; @@ -1852,18 +1877,18 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, case OVS_ACTION_ATTR_SAMPLE: err = validate_and_copy_sample(a, key, depth, sfa, - eth_type, vlan_tci); + eth_type, vlan_tci, log); if (err) return err; skip_copy = true; break; default: - OVS_NLERR("Unknown tunnel attribute (%d).\n", type); + OVS_NLERR(log, "Unknown Action type %d", type); return -EINVAL; } if (!skip_copy) { - err = copy_action(a, sfa); + err = copy_action(a, sfa, log); if (err) return err; } @@ -1877,16 +1902,16 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, int ovs_nla_copy_actions(const struct nlattr *attr, const struct sw_flow_key *key, - struct sw_flow_actions **sfa) + struct sw_flow_actions **sfa, bool log) { int err; - *sfa = nla_alloc_flow_actions(nla_len(attr)); + *sfa = nla_alloc_flow_actions(nla_len(attr), log); if (IS_ERR(*sfa)) return PTR_ERR(*sfa); err = __ovs_nla_copy_actions(attr, key, 0, sfa, key->eth.type, - key->eth.tci); + key->eth.tci, log); if (err) kfree(*sfa); diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h index 90bbe3785504..577f12be3459 100644 --- a/net/openvswitch/flow_netlink.h +++ b/net/openvswitch/flow_netlink.h @@ -45,17 +45,17 @@ void ovs_match_init(struct sw_flow_match *match, int ovs_nla_put_flow(const struct sw_flow_key *, const struct sw_flow_key *, struct sk_buff *); -int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *); +int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *, + bool log); -int ovs_nla_get_match(struct sw_flow_match *match, - const struct nlattr *, - const struct nlattr *); +int ovs_nla_get_match(struct sw_flow_match *, const struct nlattr *key, + const struct nlattr *mask, bool log); int ovs_nla_put_egress_tunnel_key(struct sk_buff *, const struct ovs_tunnel_info *); int ovs_nla_copy_actions(const struct nlattr *attr, const struct sw_flow_key *key, - struct sw_flow_actions **sfa); + struct sw_flow_actions **sfa, bool log); int ovs_nla_put_actions(const struct nlattr *attr, int len, struct sk_buff *skb); -- GitLab From 48b217aa43abc8c3545bb9b4d7a5b525b71d6ac2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 07:38:22 +0100 Subject: [PATCH 4084/9457] ALSA: pcm: Fix document for snd_pcm_stop_xrun() Fix a copy & paste error: Warning(sound/core/pcm_native.c:1112): Excess function parameter 'state' description in 'snd_pcm_stop_xrun' The state argument was dropped from snd_pcm_stop_xrun(). Reported-by: kbuild test robot Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a3d122109704..095d9572ad2b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1101,7 +1101,6 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream) /** * snd_pcm_stop_xrun - stop the running streams as XRUN * @substream: the PCM substream instance - * @state: PCM state after stopping the stream * * This stops the given running substream (and all linked substreams) as XRUN. * Unlike snd_pcm_stop(), this function takes the substream lock by itself. -- GitLab From 85a8181329a919d58b7ef99211251f47d5e1049e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 07:41:59 +0100 Subject: [PATCH 4085/9457] ALSA: usb-audio: Fix Oops by composite quirk enhancement The quirk argument itself was used as iterator, so it cannot be taken back to the original value, obviously. Fixes: d4b8fc66f770 ('ALSA: usb-audio: Allow multiple entries for the same iface in composite quirk') Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index e9ff3a6c60e4..809d7fab4633 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -43,12 +43,13 @@ static int create_composite_quirk(struct snd_usb_audio *chip, struct usb_interface *iface, struct usb_driver *driver, - const struct snd_usb_audio_quirk *quirk) + const struct snd_usb_audio_quirk *quirk_comp) { int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber; + const struct snd_usb_audio_quirk *quirk; int err; - for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { + for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) { iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); if (!iface) continue; @@ -60,7 +61,7 @@ static int create_composite_quirk(struct snd_usb_audio *chip, return err; } - for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { + for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) { iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); if (!iface) continue; -- GitLab From bd447b61c49fc26f0299587db3e6d66da49dc529 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 9 Nov 2014 13:31:11 -0800 Subject: [PATCH 4086/9457] Input: lifebook - use "static inline" instead of "inline" in lifebook.h For functions defined in header files we should use static inline rather than inline, which breaks under the latest upstream gcc (which is really gcc issue, but static inline is better suited regardless). The related error (with allmodconfig under tile): MODPOST 4002 modules ERROR: "lifebook_detect" [drivers/input/mouse/psmouse.ko] undefined! Signed-off-by: Chen Gang Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/lifebook.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index 4c4326c6f504..0baf02a70a99 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h @@ -16,14 +16,14 @@ void lifebook_module_init(void); int lifebook_detect(struct psmouse *psmouse, bool set_properties); int lifebook_init(struct psmouse *psmouse); #else -inline void lifebook_module_init(void) +static inline void lifebook_module_init(void) { } -inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) +static inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) { return -ENOSYS; } -inline int lifebook_init(struct psmouse *psmouse) +static inline int lifebook_init(struct psmouse *psmouse) { return -ENOSYS; } -- GitLab From b1cfa7b4388285c0f0b486f152ab0cb18612c779 Mon Sep 17 00:00:00 2001 From: Dudley Du Date: Sun, 9 Nov 2014 12:36:34 -0800 Subject: [PATCH 4087/9457] Input: cyapa - switch to using managed resources Use of managed resources simplifies error handling and device removal code. Signed-off-by: Dudley Du [Dmitry: added open/close methods so cyapa_remove is no longer needed.] Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cyapa.c | 184 ++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 79 deletions(-) diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 1d978c7289b4..c84a9ebeb2ff 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -577,10 +577,13 @@ static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) power = ret & ~PWR_MODE_MASK; power |= power_mode & PWR_MODE_MASK; ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); - if (ret < 0) + if (ret < 0) { dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", power_mode, ret); - return ret; + return ret; + } + + return 0; } static int cyapa_get_query_data(struct cyapa *cyapa) @@ -753,16 +756,40 @@ static u8 cyapa_check_adapter_functionality(struct i2c_client *client) return ret; } +static int cyapa_open(struct input_dev *input) +{ + struct cyapa *cyapa = input_get_drvdata(input); + struct i2c_client *client = cyapa->client; + int error; + + error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); + if (error) { + dev_err(&client->dev, "set active power failed: %d\n", error); + return error; + } + + enable_irq(client->irq); + return 0; +} + +static void cyapa_close(struct input_dev *input) +{ + struct cyapa *cyapa = input_get_drvdata(input); + + disable_irq(cyapa->client->irq); + cyapa_set_power_mode(cyapa, PWR_MODE_OFF); +} + static int cyapa_create_input_dev(struct cyapa *cyapa) { struct device *dev = &cyapa->client->dev; - int ret; struct input_dev *input; + int error; if (!cyapa->physical_size_x || !cyapa->physical_size_y) return -EINVAL; - input = cyapa->input = input_allocate_device(); + input = devm_input_allocate_device(dev); if (!input) { dev_err(dev, "allocate memory for input device failed\n"); return -ENOMEM; @@ -775,6 +802,9 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) input->id.product = 0; /* means any product in eventcomm. */ input->dev.parent = &cyapa->client->dev; + input->open = cyapa_open; + input->close = cyapa_close; + input_set_drvdata(input, cyapa); __set_bit(EV_ABS, input->evbit); @@ -802,34 +832,24 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); /* handle pointer emulation and unused slots in core */ - ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, - INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); - if (ret) { - dev_err(dev, "allocate memory for MT slots failed, %d\n", ret); - goto err_free_device; + error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, + INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(dev, "failed to initialize MT slots: %d\n", error); + return error; } - /* Register the device in input subsystem */ - ret = input_register_device(input); - if (ret) { - dev_err(dev, "input device register failed, %d\n", ret); - goto err_free_device; - } + cyapa->input = input; return 0; - -err_free_device: - input_free_device(input); - cyapa->input = NULL; - return ret; } static int cyapa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) { - int ret; - u8 adapter_func; - struct cyapa *cyapa; struct device *dev = &client->dev; + struct cyapa *cyapa; + u8 adapter_func; + int error; adapter_func = cyapa_check_adapter_functionality(client); if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { @@ -837,11 +857,9 @@ static int cyapa_probe(struct i2c_client *client, return -EIO; } - cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL); - if (!cyapa) { - dev_err(dev, "allocate memory for cyapa failed\n"); + cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); + if (!cyapa) return -ENOMEM; - } cyapa->gen = CYAPA_GEN3; cyapa->client = client; @@ -852,66 +870,61 @@ static int cyapa_probe(struct i2c_client *client, /* i2c isn't supported, use smbus */ if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) cyapa->smbus = true; + cyapa->state = CYAPA_STATE_NO_DEVICE; - ret = cyapa_check_is_operational(cyapa); - if (ret) { - dev_err(dev, "device not operational, %d\n", ret); - goto err_mem_free; - } - ret = cyapa_create_input_dev(cyapa); - if (ret) { - dev_err(dev, "create input_dev instance failed, %d\n", ret); - goto err_mem_free; + error = cyapa_check_is_operational(cyapa); + if (error) { + dev_err(dev, "device not operational, %d\n", error); + return error; } - ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); - if (ret) { - dev_err(dev, "set active power failed, %d\n", ret); - goto err_unregister_device; + /* Power down the device until we need it */ + error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF); + if (error) { + dev_err(dev, "failed to quiesce the device: %d\n", error); + return error; } - cyapa->irq = client->irq; - ret = request_threaded_irq(cyapa->irq, - NULL, - cyapa_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "cyapa", - cyapa); - if (ret) { - dev_err(dev, "IRQ request failed: %d\n, ", ret); - goto err_unregister_device; + error = cyapa_create_input_dev(cyapa); + if (error) + return error; + + error = devm_request_threaded_irq(dev, client->irq, + NULL, cyapa_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "cyapa", cyapa); + if (error) { + dev_err(dev, "IRQ request failed: %d\n, ", error); + return error; } - return 0; - -err_unregister_device: - input_unregister_device(cyapa->input); -err_mem_free: - kfree(cyapa); + /* Disable IRQ until the device is opened */ + disable_irq(client->irq); - return ret; -} - -static int cyapa_remove(struct i2c_client *client) -{ - struct cyapa *cyapa = i2c_get_clientdata(client); - - free_irq(cyapa->irq, cyapa); - input_unregister_device(cyapa->input); - cyapa_set_power_mode(cyapa, PWR_MODE_OFF); - kfree(cyapa); + /* Register the device in input subsystem */ + error = input_register_device(cyapa->input); + if (error) { + dev_err(dev, "failed to register input device: %d\n", error); + return error; + } return 0; } static int __maybe_unused cyapa_suspend(struct device *dev) { - int ret; + struct i2c_client *client = to_i2c_client(dev); + struct cyapa *cyapa = i2c_get_clientdata(client); + struct input_dev *input = cyapa->input; u8 power_mode; - struct cyapa *cyapa = dev_get_drvdata(dev); + int error; + + error = mutex_lock_interruptible(&input->mutex); + if (error) + return error; - disable_irq(cyapa->irq); + disable_irq(client->irq); /* * Set trackpad device to idle mode if wakeup is allowed, @@ -919,28 +932,42 @@ static int __maybe_unused cyapa_suspend(struct device *dev) */ power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE : PWR_MODE_OFF; - ret = cyapa_set_power_mode(cyapa, power_mode); - if (ret < 0) - dev_err(dev, "set power mode failed, %d\n", ret); + error = cyapa_set_power_mode(cyapa, power_mode); + if (error) + dev_err(dev, "resume: set power mode to %d failed: %d\n", + power_mode, error); if (device_may_wakeup(dev)) cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0); + + mutex_unlock(&input->mutex); + return 0; } static int __maybe_unused cyapa_resume(struct device *dev) { - int ret; - struct cyapa *cyapa = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct cyapa *cyapa = i2c_get_clientdata(client); + struct input_dev *input = cyapa->input; + u8 power_mode; + int error; + + mutex_lock(&input->mutex); if (device_may_wakeup(dev) && cyapa->irq_wake) disable_irq_wake(cyapa->irq); - ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); - if (ret) - dev_warn(dev, "resume active power failed, %d\n", ret); + power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF; + error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); + if (error) + dev_warn(dev, "resume: set power mode to %d failed: %d\n", + power_mode, error); enable_irq(cyapa->irq); + + mutex_unlock(&input->mutex); + return 0; } @@ -960,7 +987,6 @@ static struct i2c_driver cyapa_driver = { }, .probe = cyapa_probe, - .remove = cyapa_remove, .id_table = cyapa_id_table, }; -- GitLab From d4ffeecb3bb73a7fe3aa58a013b1b036996a75db Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 7 Nov 2014 00:44:34 -0200 Subject: [PATCH 4088/9457] i2c: imx+mxs: Use the preferred form for passing a size of a struct According to Documentation/CodingStyle - Chapter 14: "The preferred form for passing a size of a struct is the following: p = kmalloc(sizeof(*p), ...); The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not." So do it as recommeded. Signed-off-by: Fabio Estevam Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 3 +-- drivers/i2c/busses/i2c-mxs.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index e9fb7cf78612..3cbc09262326 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -668,8 +668,7 @@ static int i2c_imx_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - i2c_imx = devm_kzalloc(&pdev->dev, sizeof(struct imx_i2c_struct), - GFP_KERNEL); + i2c_imx = devm_kzalloc(&pdev->dev, sizeof(*i2c_imx), GFP_KERNEL); if (!i2c_imx) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 07e1be6f8992..3e7893aa97ef 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -811,7 +811,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) struct resource *res; int err, irq; - i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL); + i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; -- GitLab From fc3756faa71e51664e3d43b401c273723047a049 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Nov 2014 12:52:08 +0100 Subject: [PATCH 4089/9457] i2c: sh_mobile: Document SoC-specific bindings Explicitly list the various SoC-specific compatible properties. This allows checkpatch to validate DTSes. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt index d2153ce36fa8..c33e9a32d496 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt @@ -2,6 +2,15 @@ Device tree configuration for Renesas IIC (sh_mobile) driver Required properties: - compatible : "renesas,iic-". "renesas,rmobile-iic" as fallback + Examples with soctypes are: + - "renesas,iic-r8a73a4" (R-Mobile APE6) + - "renesas,iic-r8a7740" (R-Mobile A1) + - "renesas,iic-r8a7790" (R-Car H2) + - "renesas,iic-r8a7791" (R-Car M2-W) + - "renesas,iic-r8a7792" (R-Car V2H) + - "renesas,iic-r8a7793" (R-Car M2-N) + - "renesas,iic-r8a7794" (R-Car E2) + - "renesas,iic-sh73a0" (SH-Mobile AG5) - reg : address start and address range size of device - interrupts : interrupt of device - clocks : clock for device -- GitLab From 78df445e7807b1ed741d2571280a674f3e4a57bf Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Nov 2014 12:52:07 +0100 Subject: [PATCH 4090/9457] i2c: sh_mobile: Add support for r8a73a4 and sh73a0 Add support for r8a73a4 (R-Mobile APE6) and sh73a0 (SH-Mobile AG5). On these SoCs, the operating clock runs faster that on previous SoCs, and the internal SCL clock counter gets incremented every 2 clocks of the operating clock, just like on R-Car Gen2. Cfr. the "/2" in the calculation of ICCL/ICCH in section "I2C Bus Interface (IIC)", subsection "Transfer Rate" of the datasheets. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-sh_mobile.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 4855188747c9..2ee7547bebed 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -622,17 +622,19 @@ static const struct sh_mobile_dt_config default_dt_config = { .clks_per_count = 1, }; -static const struct sh_mobile_dt_config rcar_gen2_dt_config = { +static const struct sh_mobile_dt_config fast_clock_dt_config = { .clks_per_count = 2, }; static const struct of_device_id sh_mobile_i2c_dt_ids[] = { { .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, - { .compatible = "renesas,iic-r8a7790", .data = &rcar_gen2_dt_config }, - { .compatible = "renesas,iic-r8a7791", .data = &rcar_gen2_dt_config }, - { .compatible = "renesas,iic-r8a7792", .data = &rcar_gen2_dt_config }, - { .compatible = "renesas,iic-r8a7793", .data = &rcar_gen2_dt_config }, - { .compatible = "renesas,iic-r8a7794", .data = &rcar_gen2_dt_config }, + { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7793", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7794", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-sh73a0", .data = &fast_clock_dt_config }, {}, }; MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); -- GitLab From 9eb08fb3d15896bfff57fcd4c87e3fd5b19d8581 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Oct 2014 15:59:36 +0200 Subject: [PATCH 4091/9457] of/irq: Export of_irq_get() The function will be used by the I2C core which can be compiled as a module. Signed-off-by: Laurent Pinchart Acked-by: Rob Herring Acked-by: Grant Likely Signed-off-by: Wolfram Sang --- drivers/of/irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 1471e0a223a5..0d7765807f49 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -405,6 +405,7 @@ int of_irq_get(struct device_node *dev, int index) return irq_create_of_mapping(&oirq); } +EXPORT_SYMBOL_GPL(of_irq_get); /** * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number -- GitLab From 2fd36c55264926e268deb50f6de5f43fa5e490f7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Oct 2014 15:59:38 +0200 Subject: [PATCH 4092/9457] i2c: core: Map OF IRQ at probe time I2C clients instantiated from OF get their IRQ mapped at device registration time. This leads to the IRQ being silently ignored if the related irqchip hasn't been proved yet. Fix this by moving IRQ mapping at probe time using of_get_irq(). The function operates as irq_of_parse_and_map() but additionally returns -EPROBE_DEFER if the irqchip isn't available, allowing us to defer I2C client probing. Signed-off-by: Laurent Pinchart Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f43b4e11647a..a0768d6dffc2 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -626,6 +626,15 @@ static int i2c_device_probe(struct device *dev) if (!client) return 0; + if (!client->irq && dev->of_node) { + int irq = of_irq_get(dev->of_node, 0); + + if (irq < 0) + return irq; + + client->irq = irq; + } + driver = to_i2c_driver(dev->driver); if (!driver->probe || !driver->id_table) return -ENODEV; @@ -1407,7 +1416,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) continue; } - info.irq = irq_of_parse_and_map(node, 0); info.of_node = of_node_get(node); info.archdata = &dev_ad; @@ -1421,7 +1429,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) dev_err(&adap->dev, "of_i2c: Failure registering %s\n", node->full_name); of_node_put(node); - irq_dispose_mapping(info.irq); continue; } } -- GitLab From 194fa7ff67f102023d198dfe658614a31dcad8d4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 3 Oct 2014 13:57:14 +0200 Subject: [PATCH 4093/9457] i2c: exynos5: use proper errno for timeout Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-exynos5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index 81e6263cd7da..271533d564ec 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -457,7 +457,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) goto stop; } else if (int_status & HSI2C_INT_TIMEOUT) { dev_dbg(i2c->dev, "Accessing device timed out\n"); - i2c->state = -EAGAIN; + i2c->state = -ETIMEDOUT; goto stop; } } else if (int_status & HSI2C_INT_I2C) { @@ -476,7 +476,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) goto stop; } else if (trans_status & HSI2C_TIMEOUT_AUTO) { dev_dbg(i2c->dev, "Accessing device timed out\n"); - i2c->state = -EAGAIN; + i2c->state = -ETIMEDOUT; goto stop; } else if (trans_status & HSI2C_TRANS_DONE) { i2c->trans_done = 1; -- GitLab From d64a818859af3b6fbe0f6d61b4b82676b561ce5c Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Fri, 24 Oct 2014 14:50:15 +0800 Subject: [PATCH 4094/9457] i2c: at91: add support for runtime PM Drivers should put the device into low power states proactively whenever the device is not in use. Thus implement support for runtime PM and use the autosuspend feature to make sure that we can still perform well in case we see lots of i2c traffic within short period of time. Signed-off-by: Wenyou Yang Acked-by: Ludovic Desroches Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 38 +++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index e05a672db3e5..76d16713508f 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -31,10 +31,12 @@ #include #include #include +#include #define DEFAULT_TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ #define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ +#define AUTOSUSPEND_TIMEOUT 2000 /* AT91 TWI register definitions */ #define AT91_TWI_CR 0x0000 /* Control Register */ @@ -481,6 +483,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); + ret = pm_runtime_get_sync(dev->dev); + if (ret < 0) + goto out; + /* * The hardware can handle at most two messages concatenated by a * repeated start via it's internal address feature. @@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) if (num > 2) { dev_err(dev->dev, "cannot handle more than two concatenated messages.\n"); - return 0; + ret = 0; + goto out; } else if (num == 2) { int internal_address = 0; int i; if (msg->flags & I2C_M_RD) { dev_err(dev->dev, "first transfer must be write.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } if (msg->len > 3) { dev_err(dev->dev, "first message size must be <= 3.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* 1st msg is put into the internal address, start with 2nd */ @@ -523,7 +532,12 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) ret = at91_do_twi_transfer(dev); - return (ret < 0) ? ret : num; + ret = (ret < 0) ? ret : num; +out: + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + + return ret; } static u32 at91_twi_func(struct i2c_adapter *adapter) @@ -795,11 +809,20 @@ static int at91_twi_probe(struct platform_device *pdev) dev->adapter.timeout = AT91_I2C_TIMEOUT; dev->adapter.dev.of_node = pdev->dev.of_node; + pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev->dev); + pm_runtime_set_active(dev->dev); + pm_runtime_enable(dev->dev); + rc = i2c_add_numbered_adapter(&dev->adapter); if (rc) { dev_err(dev->dev, "Adapter %s registration failed\n", dev->adapter.name); clk_disable_unprepare(dev->clk); + + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return rc; } @@ -814,6 +837,9 @@ static int at91_twi_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); clk_disable_unprepare(dev->clk); + pm_runtime_disable(dev->dev); + pm_runtime_set_suspended(dev->dev); + return 0; } @@ -823,7 +849,7 @@ static int at91_twi_runtime_suspend(struct device *dev) { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - clk_disable(twi_dev->clk); + clk_disable_unprepare(twi_dev->clk); return 0; } @@ -832,7 +858,7 @@ static int at91_twi_runtime_resume(struct device *dev) { struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); - return clk_enable(twi_dev->clk); + return clk_prepare_enable(twi_dev->clk); } static const struct dev_pm_ops at91_twi_pm = { -- GitLab From 36765293cd50bd8dffd5f3225376789cacddfb00 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Fri, 24 Oct 2014 14:50:16 +0800 Subject: [PATCH 4095/9457] i2c: at91: add support for system PM Signed-off-by: Wenyou Yang Acked-by: Ludovic Desroches Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 76d16713508f..7c335f41dc3d 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -861,7 +861,33 @@ static int at91_twi_runtime_resume(struct device *dev) return clk_prepare_enable(twi_dev->clk); } +static int at91_twi_suspend_noirq(struct device *dev) +{ + if (!pm_runtime_status_suspended(dev)) + at91_twi_runtime_suspend(dev); + + return 0; +} + +static int at91_twi_resume_noirq(struct device *dev) +{ + int ret; + + if (!pm_runtime_status_suspended(dev)) { + ret = at91_twi_runtime_resume(dev); + if (ret) + return ret; + } + + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + + return 0; +} + static const struct dev_pm_ops at91_twi_pm = { + .suspend_noirq = at91_twi_suspend_noirq, + .resume_noirq = at91_twi_resume_noirq, .runtime_suspend = at91_twi_runtime_suspend, .runtime_resume = at91_twi_runtime_resume, }; -- GitLab From 900ef800a2a4c08aa28af4785a5b2d5d7e199103 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Fri, 14 Mar 2014 07:42:28 +0100 Subject: [PATCH 4096/9457] i2c: davinci: don't use interruptible completion When a signal is caught while the i2c-davinci bus driver is transferring, the driver just "abandons" the transfer and leaves the controller to fend for itself. The next I2C transaction will find the controller in an undefined state and often results in a stream of "initiating i2c bus recovery" messages until the controller arrives in a defined state. This behaviour also sends out "half" or possibly even mixed messages to I2C client devices which may put them in an undesired state as well. So, let's get simply uninterruptible. Signed-off-by: Mike Looijmans Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-davinci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index d15b7c9b9219..91c43decf327 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -368,8 +368,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) flag |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); - r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, - dev->adapter.timeout); + r = wait_for_completion_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); davinci_i2c_recover_bus(dev); @@ -380,7 +379,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) if (dev->buf_len) { /* This should be 0 if all bytes were transferred * or dev->cmd_err denotes an error. - * A signal may have aborted the transfer. */ if (r >= 0) { dev_err(dev->dev, "abnormal termination buf_len=%i\n", -- GitLab From 6bab3596bbede980c067eaeaf6a470c262888dac Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 20 Oct 2014 16:01:33 +0200 Subject: [PATCH 4097/9457] quota: Remove const from function declarations We don't use const through VFS too much so just remove it from quota function declarations. Signed-off-by: Jan Kara --- fs/quota/dquot.c | 4 ++-- include/linux/quotaops.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index a180b1d1a6c6..b1910c915c90 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1643,7 +1643,7 @@ EXPORT_SYMBOL(__dquot_alloc_space); /* * This operation can block, but only after everything is updated */ -int dquot_alloc_inode(const struct inode *inode) +int dquot_alloc_inode(struct inode *inode) { int cnt, ret = 0, index; struct dquot_warn warn[MAXQUOTAS]; @@ -1784,7 +1784,7 @@ EXPORT_SYMBOL(__dquot_free_space); /* * This operation can block, but only after everything is updated */ -void dquot_free_inode(const struct inode *inode) +void dquot_free_inode(struct inode *inode) { unsigned int cnt; struct dquot_warn warn[MAXQUOTAS]; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 1d3eee594cd6..f23538a6e411 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -64,10 +64,10 @@ void dquot_destroy(struct dquot *dquot); int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags); void __dquot_free_space(struct inode *inode, qsize_t number, int flags); -int dquot_alloc_inode(const struct inode *inode); +int dquot_alloc_inode(struct inode *inode); int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); -void dquot_free_inode(const struct inode *inode); +void dquot_free_inode(struct inode *inode); void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number); int dquot_disable(struct super_block *sb, int type, unsigned int flags); @@ -213,12 +213,12 @@ static inline void dquot_drop(struct inode *inode) { } -static inline int dquot_alloc_inode(const struct inode *inode) +static inline int dquot_alloc_inode(struct inode *inode) { return 0; } -static inline void dquot_free_inode(const struct inode *inode) +static inline void dquot_free_inode(struct inode *inode) { } -- GitLab From 2c5f648aa24a7c8f0668d8ce5722d69da5bef739 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 30 Sep 2014 10:43:09 +0200 Subject: [PATCH 4098/9457] quota: Allow each filesystem to specify which quota types it supports Currently all filesystems supporting VFS quota support user and group quotas. With introduction of project quotas this is going to change so make sure filesystem isn't called for quota type it doesn't support by introduction of a bitmask determining which quota types each filesystem supports. Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/quota.c | 13 +++++++++++-- fs/super.c | 6 ++++++ include/linux/fs.h | 1 + include/linux/quota.h | 5 +++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 75621649dbd7..2aa4151f99d2 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -47,8 +47,11 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd, static void quota_sync_one(struct super_block *sb, void *arg) { - if (sb->s_qcop && sb->s_qcop->quota_sync) - sb->s_qcop->quota_sync(sb, *(int *)arg); + int type = *(int *)arg; + + if (sb->s_qcop && sb->s_qcop->quota_sync && + (sb->s_quota_types & (1 << type))) + sb->s_qcop->quota_sync(sb, type); } static int quota_sync_all(int type) @@ -297,8 +300,14 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS)) return -EINVAL; + /* + * Quota not supported on this fs? Check this before s_quota_types + * since they needn't be set if quota is not supported at all. + */ if (!sb->s_qcop) return -ENOSYS; + if (!(sb->s_quota_types & (1 << type))) + return -EINVAL; ret = check_quotactl_permission(sb, type, cmd, id); if (ret < 0) diff --git a/fs/super.c b/fs/super.c index eae088f6aaae..4512281df8ff 100644 --- a/fs/super.c +++ b/fs/super.c @@ -218,6 +218,12 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); + /* + * For now MAXQUOTAS check in do_quotactl() will limit quota type + * appropriately. When each fs sets allowed_types, we can remove the + * line below + */ + s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; mutex_init(&s->s_dquot.dqio_mutex); mutex_init(&s->s_dquot.dqonoff_mutex); s->s_maxbytes = MAX_NON_LFS; diff --git a/include/linux/fs.h b/include/linux/fs.h index 9ab779e8a63c..cf55a5483d40 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1224,6 +1224,7 @@ struct super_block { struct backing_dev_info *s_bdi; struct mtd_info *s_mtd; struct hlist_node s_instances; + unsigned int s_quota_types; /* Bitmask of supported quota types */ struct quota_info s_dquot; /* Diskquota specific options */ struct sb_writers s_writers; diff --git a/include/linux/quota.h b/include/linux/quota.h index 80d345a3524c..50978b781a19 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -56,6 +56,11 @@ enum quota_type { PRJQUOTA = 2, /* element used for project quotas */ }; +/* Masks for quota types when used as a bitmask */ +#define QTYPE_MASK_USR (1 << USRQUOTA) +#define QTYPE_MASK_GRP (1 << GRPQUOTA) +#define QTYPE_MASK_PRJ (1 << PRJQUOTA) + typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ typedef long long qsize_t; /* Type in which we store sizes */ -- GitLab From de3b08d3ecf89dde63e8a0f3681f6cc74d230f1e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 30 Sep 2014 22:33:00 +0200 Subject: [PATCH 4099/9457] gfs2: Set allowed quota types We support user and group quotas. Tell vfs about it. Acked-by: Steven Whitehouse CC: cluster-devel@redhat.com Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/gfs2/ops_fstype.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index d3eae244076e..455bac77feb5 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1082,6 +1082,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent sb->s_export_op = &gfs2_export_ops; sb->s_xattr = gfs2_xattr_handlers; sb->s_qcop = &gfs2_quotactl_ops; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE; sb->s_time_gran = 1; sb->s_maxbytes = MAX_LFS_FILESIZE; -- GitLab From 17ef4fdd379dc7bcbdf46b2630d33958244d0053 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 30 Sep 2014 22:35:33 +0200 Subject: [PATCH 4100/9457] xfs: Set allowed quota types We support user, group, and project quotas. Tell VFS about it. CC: xfs@oss.sgi.com CC: Dave Chinner Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/xfs/xfs_super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 9f622feda6a4..206b97fd1d8a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1425,6 +1425,7 @@ xfs_fs_fill_super( sb->s_export_op = &xfs_export_operations; #ifdef CONFIG_XFS_QUOTA sb->s_qcop = &xfs_quotactl_operations; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; #endif sb->s_op = &xfs_super_operations; -- GitLab From 2d0fa467915ed0c5957c992011b7f142a7dedf8e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 25 Sep 2014 16:36:14 +0200 Subject: [PATCH 4101/9457] quota: Use function to provide i_dquot pointers i_dquot array is used by relatively few filesystems (ext?, ocfs2, jfs, reiserfs) so it is beneficial to move this array to fs-private part of the inode. We cannot just pass quota pointers from filesystems to quota functions because during quotaon and quotaoff we have to traverse list of all inodes and manipulate i_dquot pointers for each inode. So we provide a function which generic quota code can use to get pointer to the i_dquot array from the filesystem. Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/quota/dquot.c | 54 ++++++++++++++++++++++++++-------------------- include/linux/fs.h | 1 + 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index b1910c915c90..b80d1fe56f83 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -893,6 +893,14 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid) } EXPORT_SYMBOL(dqget); +static inline struct dquot **i_dquot(struct inode *inode) +{ + /* Temporary workaround until all filesystems are converted. */ + if (!inode->i_sb->s_op->get_dquots) + return inode->i_dquot; + return inode->i_sb->s_op->get_dquots(inode); +} + static int dqinit_needed(struct inode *inode, int type) { int cnt; @@ -900,9 +908,9 @@ static int dqinit_needed(struct inode *inode, int type) if (IS_NOQUOTA(inode)) return 0; if (type != -1) - return !inode->i_dquot[type]; + return !i_dquot(inode)[type]; for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (!inode->i_dquot[cnt]) + if (!i_dquot(inode)[cnt]) return 1; return 0; } @@ -965,9 +973,9 @@ static void add_dquot_ref(struct super_block *sb, int type) static void remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head) { - struct dquot *dquot = inode->i_dquot[type]; + struct dquot *dquot = i_dquot(inode)[type]; - inode->i_dquot[type] = NULL; + i_dquot(inode)[type] = NULL; if (!dquot) return; @@ -1402,7 +1410,7 @@ static void __dquot_initialize(struct inode *inode, int type) * we check it without locking here to avoid unnecessary * dqget()/dqput() calls. */ - if (inode->i_dquot[cnt]) + if (i_dquot(inode)[cnt]) continue; init_needed = 1; @@ -1433,8 +1441,8 @@ static void __dquot_initialize(struct inode *inode, int type) /* We could race with quotaon or dqget() could have failed */ if (!got[cnt]) continue; - if (!inode->i_dquot[cnt]) { - inode->i_dquot[cnt] = got[cnt]; + if (!i_dquot(inode)[cnt]) { + i_dquot(inode)[cnt] = got[cnt]; got[cnt] = NULL; /* * Make quota reservation system happy if someone @@ -1442,7 +1450,7 @@ static void __dquot_initialize(struct inode *inode, int type) */ rsv = inode_get_rsv_space(inode); if (unlikely(rsv)) - dquot_resv_space(inode->i_dquot[cnt], rsv); + dquot_resv_space(i_dquot(inode)[cnt], rsv); } } out_err: @@ -1472,8 +1480,8 @@ static void __dquot_drop(struct inode *inode) spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - put[cnt] = inode->i_dquot[cnt]; - inode->i_dquot[cnt] = NULL; + put[cnt] = i_dquot(inode)[cnt]; + i_dquot(inode)[cnt] = NULL; } spin_unlock(&dq_data_lock); dqput_all(put); @@ -1494,7 +1502,7 @@ void dquot_drop(struct inode *inode) * add quota pointers back anyway. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) + if (i_dquot(inode)[cnt]) break; } @@ -1595,7 +1603,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) { int cnt, ret = 0, index; struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = inode->i_dquot; + struct dquot **dquots = i_dquot(inode); int reserve = flags & DQUOT_SPACE_RESERVE; if (!dquot_active(inode)) { @@ -1647,7 +1655,7 @@ int dquot_alloc_inode(struct inode *inode) { int cnt, ret = 0, index; struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = inode->i_dquot; + struct dquot * const *dquots = i_dquot(inode); if (!dquot_active(inode)) return 0; @@ -1696,14 +1704,14 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) spin_lock(&dq_data_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) - dquot_claim_reserved_space(inode->i_dquot[cnt], + if (i_dquot(inode)[cnt]) + dquot_claim_reserved_space(i_dquot(inode)[cnt], number); } /* Update inode bytes */ inode_claim_rsv_space(inode, number); spin_unlock(&dq_data_lock); - mark_all_dquot_dirty(inode->i_dquot); + mark_all_dquot_dirty(i_dquot(inode)); srcu_read_unlock(&dquot_srcu, index); return 0; } @@ -1725,14 +1733,14 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) spin_lock(&dq_data_lock); /* Claim reserved quotas to allocated quotas */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt]) - dquot_reclaim_reserved_space(inode->i_dquot[cnt], + if (i_dquot(inode)[cnt]) + dquot_reclaim_reserved_space(i_dquot(inode)[cnt], number); } /* Update inode bytes */ inode_reclaim_rsv_space(inode, number); spin_unlock(&dq_data_lock); - mark_all_dquot_dirty(inode->i_dquot); + mark_all_dquot_dirty(i_dquot(inode)); srcu_read_unlock(&dquot_srcu, index); return; } @@ -1745,7 +1753,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) { unsigned int cnt; struct dquot_warn warn[MAXQUOTAS]; - struct dquot **dquots = inode->i_dquot; + struct dquot **dquots = i_dquot(inode); int reserve = flags & DQUOT_SPACE_RESERVE, index; if (!dquot_active(inode)) { @@ -1788,7 +1796,7 @@ void dquot_free_inode(struct inode *inode) { unsigned int cnt; struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots = inode->i_dquot; + struct dquot * const *dquots = i_dquot(inode); int index; if (!dquot_active(inode)) @@ -1865,7 +1873,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) if (!sb_has_quota_active(inode->i_sb, cnt)) continue; is_valid[cnt] = 1; - transfer_from[cnt] = inode->i_dquot[cnt]; + transfer_from[cnt] = i_dquot(inode)[cnt]; ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]); if (ret) goto over_quota; @@ -1901,7 +1909,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) dquot_incr_space(transfer_to[cnt], cur_space); dquot_resv_space(transfer_to[cnt], rsv_space); - inode->i_dquot[cnt] = transfer_to[cnt]; + i_dquot(inode)[cnt] = transfer_to[cnt]; } spin_unlock(&dq_data_lock); diff --git a/include/linux/fs.h b/include/linux/fs.h index cf55a5483d40..8c093ad49522 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1591,6 +1591,7 @@ struct super_operations { #ifdef CONFIG_QUOTA ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); + struct dquot **(*get_dquots)(struct inode *); #endif int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); long (*nr_cached_objects)(struct super_block *, int); -- GitLab From 64241118b718f6f1e7bbbad8c4567f36b65ca31a Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 25 Sep 2014 16:44:45 +0200 Subject: [PATCH 4102/9457] ext2: Convert to private i_dquot field CC: linux-ext4@vger.kernel.org Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/ext2.h | 3 +++ fs/ext2/super.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index d9a17d0b124d..e4279ead4a05 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -689,6 +689,9 @@ struct ext2_inode_info { struct mutex truncate_mutex; struct inode vfs_inode; struct list_head i_orphan; /* unlinked but open inodes */ +#ifdef CONFIG_QUOTA + struct dquot *i_dquot[MAXQUOTAS]; +#endif }; /* diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 170dc41e8bf4..ae55fddc26a9 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -166,6 +166,10 @@ static struct inode *ext2_alloc_inode(struct super_block *sb) return NULL; ei->i_block_alloc_info = NULL; ei->vfs_inode.i_version = 1; +#ifdef CONFIG_QUOTA + memset(&ei->i_dquot, 0, sizeof(ei->i_dquot)); +#endif + return &ei->vfs_inode; } @@ -303,6 +307,10 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root) #ifdef CONFIG_QUOTA static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); +static struct dquot **ext2_get_dquots(struct inode *inode) +{ + return EXT2_I(inode)->i_dquot; +} #endif static const struct super_operations ext2_sops = { @@ -320,6 +328,7 @@ static const struct super_operations ext2_sops = { #ifdef CONFIG_QUOTA .quota_read = ext2_quota_read, .quota_write = ext2_quota_write, + .get_dquots = ext2_get_dquots, #endif }; @@ -1090,6 +1099,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA sb->dq_op = &dquot_operations; sb->s_qcop = &dquot_quotactl_ops; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; #endif root = ext2_iget(sb, EXT2_ROOT_INO); -- GitLab From 4018cfbc8cc974d35c05d651456023426a12fbac Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 25 Sep 2014 16:52:38 +0200 Subject: [PATCH 4103/9457] ext3: Convert to private i_dquot field CC: linux-ext4@vger.kernel.org Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext3/ext3.h | 4 ++++ fs/ext3/super.c | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/fs/ext3/ext3.h b/fs/ext3/ext3.h index fc3cdcf24aed..f483a80b3fe7 100644 --- a/fs/ext3/ext3.h +++ b/fs/ext3/ext3.h @@ -615,6 +615,10 @@ struct ext3_inode_info { atomic_t i_sync_tid; atomic_t i_datasync_tid; +#ifdef CONFIG_QUOTA + struct dquot *i_dquot[MAXQUOTAS]; +#endif + struct inode vfs_inode; }; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index eb742d0e67ff..9b4e7d750d4f 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -485,6 +485,10 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) ei->vfs_inode.i_version = 1; atomic_set(&ei->i_datasync_tid, 0); atomic_set(&ei->i_sync_tid, 0); +#ifdef CONFIG_QUOTA + memset(&ei->i_dquot, 0, sizeof(ei->i_dquot)); +#endif + return &ei->vfs_inode; } @@ -764,6 +768,10 @@ static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); static ssize_t ext3_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); +static struct dquot **ext3_get_dquots(struct inode *inode) +{ + return EXT3_I(inode)->i_dquot; +} static const struct dquot_operations ext3_quota_operations = { .write_dquot = ext3_write_dquot, @@ -803,6 +811,7 @@ static const struct super_operations ext3_sops = { #ifdef CONFIG_QUOTA .quota_read = ext3_quota_read, .quota_write = ext3_quota_write, + .get_dquots = ext3_get_dquots, #endif .bdev_try_to_free_page = bdev_try_to_free_page, }; @@ -2001,6 +2010,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA sb->s_qcop = &ext3_qctl_operations; sb->dq_op = &ext3_quota_operations; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; #endif memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid)); INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ -- GitLab From 96c7e0d964e278858552b8d5497f440b9027b292 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 29 Sep 2014 14:58:25 +0200 Subject: [PATCH 4104/9457] ext4: Convert to private i_dquot field CC: linux-ext4@vger.kernel.org Acked-by: "Theodore Ts'o" Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext4/ext4.h | 4 ++++ fs/ext4/super.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c55a1faaed58..db3f772e57ae 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -941,6 +941,10 @@ struct ext4_inode_info { tid_t i_sync_tid; tid_t i_datasync_tid; +#ifdef CONFIG_QUOTA + struct dquot *i_dquot[MAXQUOTAS]; +#endif + /* Precomputed uuid+inum+igen checksum for seeding inode checksums */ __u32 i_csum_seed; }; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2c9e6864abd9..63e802b8ec68 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -892,6 +892,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) spin_lock_init(&(ei->i_block_reservation_lock)); #ifdef CONFIG_QUOTA ei->i_reserved_quota = 0; + memset(&ei->i_dquot, 0, sizeof(ei->i_dquot)); #endif ei->jinode = NULL; INIT_LIST_HEAD(&ei->i_rsv_conversion_list); @@ -1068,6 +1069,11 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id, unsigned int flags); static int ext4_enable_quotas(struct super_block *sb); +static struct dquot **ext4_get_dquots(struct inode *inode) +{ + return EXT4_I(inode)->i_dquot; +} + static const struct dquot_operations ext4_quota_operations = { .get_reserved_space = ext4_get_reserved_space, .write_dquot = ext4_write_dquot, @@ -1117,6 +1123,7 @@ static const struct super_operations ext4_sops = { #ifdef CONFIG_QUOTA .quota_read = ext4_quota_read, .quota_write = ext4_quota_write, + .get_dquots = ext4_get_dquots, #endif .bdev_try_to_free_page = bdev_try_to_free_page, }; @@ -3932,6 +3939,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_qcop = &ext4_qctl_sysfile_operations; else sb->s_qcop = &ext4_qctl_operations; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; #endif memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid)); -- GitLab From 1c92ec678f32a4fdb9c0f7294b4d6f506b9a4b84 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 29 Sep 2014 15:02:51 +0200 Subject: [PATCH 4105/9457] ocfs2: Convert to private i_dquot field CC: Mark Fasheh CC: Joel Becker CC: ocfs2-devel@oss.oracle.com Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ocfs2/inode.h | 2 ++ fs/ocfs2/super.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index a9b76de46047..ca3431ee7f24 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h @@ -80,6 +80,8 @@ struct ocfs2_inode_info */ tid_t i_sync_tid; tid_t i_datasync_tid; + + struct dquot *i_dquot[MAXQUOTAS]; }; /* diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 93c85bc745e1..0945814ddb7b 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -143,6 +143,11 @@ static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend); static int ocfs2_enable_quotas(struct ocfs2_super *osb); static void ocfs2_disable_quotas(struct ocfs2_super *osb); +static struct dquot **ocfs2_get_dquots(struct inode *inode) +{ + return OCFS2_I(inode)->i_dquot; +} + static const struct super_operations ocfs2_sops = { .statfs = ocfs2_statfs, .alloc_inode = ocfs2_alloc_inode, @@ -155,6 +160,7 @@ static const struct super_operations ocfs2_sops = { .show_options = ocfs2_show_options, .quota_read = ocfs2_quota_read, .quota_write = ocfs2_quota_write, + .get_dquots = ocfs2_get_dquots, }; enum { @@ -563,6 +569,7 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb) oi->i_sync_tid = 0; oi->i_datasync_tid = 0; + memset(&oi->i_dquot, 0, sizeof(oi->i_dquot)); jbd2_journal_init_jbd_inode(&oi->ip_jinode, &oi->vfs_inode); return &oi->vfs_inode; @@ -2073,6 +2080,7 @@ static int ocfs2_initialize_super(struct super_block *sb, sb->s_export_op = &ocfs2_export_ops; sb->s_qcop = &ocfs2_quotactl_ops; sb->dq_op = &ocfs2_quota_operations; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; sb->s_xattr = ocfs2_xattr_handlers; sb->s_time_gran = 1; sb->s_flags |= MS_NOATIME; -- GitLab From 53873638bd7cbcbf43cea72f0eb0d2ee9260f059 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 29 Sep 2014 15:08:19 +0200 Subject: [PATCH 4106/9457] reiserfs: Convert to private i_dquot field CC: reiserfs-devel@vger.kernel.org CC: Jeff Mahoney Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/reiserfs/reiserfs.h | 4 ++++ fs/reiserfs/super.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 1894d96ccb7c..bb79cddf0a1f 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -97,6 +97,10 @@ struct reiserfs_inode_info { #ifdef CONFIG_REISERFS_FS_XATTR struct rw_semaphore i_xattr_sem; #endif +#ifdef CONFIG_QUOTA + struct dquot *i_dquot[MAXQUOTAS]; +#endif + struct inode vfs_inode; }; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f1376c92cf74..ea63ab13ef92 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -594,6 +594,10 @@ static struct inode *reiserfs_alloc_inode(struct super_block *sb) return NULL; atomic_set(&ei->openers, 0); mutex_init(&ei->tailpack); +#ifdef CONFIG_QUOTA + memset(&ei->i_dquot, 0, sizeof(ei->i_dquot)); +#endif + return &ei->vfs_inode; } @@ -750,6 +754,11 @@ static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, size_t, loff_t); static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t, loff_t); + +static struct dquot **reiserfs_get_dquots(struct inode *inode) +{ + return REISERFS_I(inode)->i_dquot; +} #endif static const struct super_operations reiserfs_sops = { @@ -768,6 +777,7 @@ static const struct super_operations reiserfs_sops = { #ifdef CONFIG_QUOTA .quota_read = reiserfs_quota_read, .quota_write = reiserfs_quota_write, + .get_dquots = reiserfs_get_dquots, #endif }; @@ -1633,6 +1643,7 @@ static int read_super_block(struct super_block *s, int offset) #ifdef CONFIG_QUOTA s->s_qcop = &reiserfs_qctl_operations; s->dq_op = &reiserfs_quota_operations; + s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; #endif /* -- GitLab From 507e1fa697097b4885008f16354822f8d0c33a5d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 1 Oct 2014 11:19:12 +0200 Subject: [PATCH 4107/9457] jfs: Convert to private i_dquot field Acked-by: Dave Kleikamp CC: jfs-discussion@lists.sourceforge.net Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/jfs/jfs_incore.h | 3 +++ fs/jfs/super.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index cf47f09e8ac8..fa7e795bd8ae 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h @@ -94,6 +94,9 @@ struct jfs_inode_info { unchar _inline_ea[128]; /* 128: inline extended attr */ } link; } u; +#ifdef CONFIG_QUOTA + struct dquot *i_dquot[MAXQUOTAS]; +#endif u32 dev; /* will die when we get wide dev_t */ struct inode vfs_inode; }; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 93e897e588a8..16c3a9556634 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -117,6 +117,9 @@ static struct inode *jfs_alloc_inode(struct super_block *sb) jfs_inode = kmem_cache_alloc(jfs_inode_cachep, GFP_NOFS); if (!jfs_inode) return NULL; +#ifdef CONFIG_QUOTA + memset(&jfs_inode->i_dquot, 0, sizeof(jfs_inode->i_dquot)); +#endif return &jfs_inode->vfs_inode; } @@ -537,6 +540,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA sb->dq_op = &dquot_operations; sb->s_qcop = &dquot_quotactl_ops; + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; #endif /* @@ -836,6 +840,10 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type, return len - towrite; } +static struct dquot **jfs_get_dquots(struct inode *inode) +{ + return JFS_IP(inode)->i_dquot; +} #endif static const struct super_operations jfs_super_operations = { @@ -854,6 +862,7 @@ static const struct super_operations jfs_super_operations = { #ifdef CONFIG_QUOTA .quota_read = jfs_quota_read, .quota_write = jfs_quota_write, + .get_dquots = jfs_get_dquots, #endif }; -- GitLab From 75cbe701a4251fcd8b846d52ae42f88c9a8e5e93 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 29 Sep 2014 15:10:26 +0200 Subject: [PATCH 4108/9457] vfs: Remove i_dquot field from inode All filesystems using VFS quotas are now converted to use their private i_dquot fields. Remove the i_dquot field from generic inode structure. Acked-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/inode.c | 3 --- fs/quota/dquot.c | 3 --- fs/super.c | 6 ------ include/linux/fs.h | 3 --- 4 files changed, 15 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 26753ba7b6d6..2ed95f7caa4f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -143,9 +143,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_blocks = 0; inode->i_bytes = 0; inode->i_generation = 0; -#ifdef CONFIG_QUOTA - memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); -#endif inode->i_pipe = NULL; inode->i_bdev = NULL; inode->i_cdev = NULL; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index b80d1fe56f83..8f0acef3d184 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -895,9 +895,6 @@ EXPORT_SYMBOL(dqget); static inline struct dquot **i_dquot(struct inode *inode) { - /* Temporary workaround until all filesystems are converted. */ - if (!inode->i_sb->s_op->get_dquots) - return inode->i_dquot; return inode->i_sb->s_op->get_dquots(inode); } diff --git a/fs/super.c b/fs/super.c index 4512281df8ff..eae088f6aaae 100644 --- a/fs/super.c +++ b/fs/super.c @@ -218,12 +218,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); - /* - * For now MAXQUOTAS check in do_quotactl() will limit quota type - * appropriately. When each fs sets allowed_types, we can remove the - * line below - */ - s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ; mutex_init(&s->s_dquot.dqio_mutex); mutex_init(&s->s_dquot.dqonoff_mutex); s->s_maxbytes = MAX_NON_LFS; diff --git a/include/linux/fs.h b/include/linux/fs.h index 8c093ad49522..6eb5337688bd 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -606,9 +606,6 @@ struct inode { const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct file_lock *i_flock; struct address_space i_data; -#ifdef CONFIG_QUOTA - struct dquot *i_dquot[MAXQUOTAS]; -#endif struct list_head i_devices; union { struct pipe_inode_info *i_pipe; -- GitLab From 000baa5dfd99abe8a6e4ddbe900be5a570a1e20c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 7 Nov 2014 15:28:33 +0200 Subject: [PATCH 4109/9457] mac80211: fix order of setting ch_switch and drv_pre_channel_switch call There was a mistake when merging commit 6d027bcc (mac80211: add pre_channel_switch driver operation) for upstream. The assignment of the values in the ch_switch structure came below the call to drv_pre_channel_switch. Fix the order. Fixes: 6d027bcc (mac80211: add pre_channel_switch driver operation) Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 06185940cbb6..76e794edd960 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3158,6 +3158,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } + ch_switch.timestamp = 0; + ch_switch.device_timestamp = 0; + ch_switch.block_tx = params->block_tx; + ch_switch.chandef = params->chandef; + ch_switch.count = params->count; + err = drv_pre_channel_switch(sdata, &ch_switch); if (err) goto out; @@ -3175,12 +3181,6 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; } - ch_switch.timestamp = 0; - ch_switch.device_timestamp = 0; - ch_switch.block_tx = params->block_tx; - ch_switch.chandef = params->chandef; - ch_switch.count = params->count; - err = ieee80211_set_csa_beacon(sdata, params, &changed); if (err) { ieee80211_vif_unreserve_chanctx(sdata); -- GitLab From 127f10ec6069aa0ddc214f14cb424198e1741256 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 7 Nov 2014 15:28:34 +0200 Subject: [PATCH 4110/9457] mac80211: add device_timestamp to the drv_pre_channel_switch trace The device_timestamp value was left out of the event trace for drv_pre_channel_switch by mistake. Add it. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/trace.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 809a4983eb4a..96847e788488 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2140,6 +2140,7 @@ TRACE_EVENT(drv_pre_channel_switch, VIF_ENTRY CHANDEF_ENTRY __field(u64, timestamp) + __field(u32, device_timestamp) __field(bool, block_tx) __field(u8, count) ), @@ -2149,6 +2150,7 @@ TRACE_EVENT(drv_pre_channel_switch, VIF_ASSIGN; CHANDEF_ASSIGN(&ch_switch->chandef) __entry->timestamp = ch_switch->timestamp; + __entry->device_timestamp = ch_switch->device_timestamp; __entry->block_tx = ch_switch->block_tx; __entry->count = ch_switch->count; ), -- GitLab From f8d7552e945d38bd8d2e9c23aebf98042ce12302 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 7 Nov 2014 14:31:35 +0200 Subject: [PATCH 4111/9457] cfg80211: add channel switch started notification Add a new NL80211_CH_SWITCH_STARTED_NOTIFY message that can be sent to the userspace when a channel switch process has started. This allows userspace to take action, for instance, by requesting other interfaces to switch channel as necessary. This patch introduces a function that allows the drivers to send this notification. It should be used when the driver starts processing a channel switch initiated by a remote device (eg. when a STA receives a CSA from the AP) and when it successfully starts a userspace-triggered channel switch (eg. when hostapd triggers a channel swith in the AP). Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 14 ++++++++++++++ include/uapi/linux/nl80211.h | 11 +++++++++++ net/wireless/nl80211.c | 28 +++++++++++++++++++++++++--- net/wireless/trace.h | 16 ++++++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5c3acd07acd9..220d5f5f1aca 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4719,6 +4719,20 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, void cfg80211_ch_switch_notify(struct net_device *dev, struct cfg80211_chan_def *chandef); +/* + * cfg80211_ch_switch_started_notify - notify channel switch start + * @dev: the device on which the channel switch started + * @chandef: the future channel definition + * @count: the number of TBTTs until the channel switch happens + * + * Inform the userspace about the channel switch that has just + * started, so that it can take appropriate actions (eg. starting + * channel switch on other vifs), if necessary. + */ +void cfg80211_ch_switch_started_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, + u8 count); + /** * ieee80211_operating_class_to_band - convert operating class to band * diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 9b3025e4377a..354163433352 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -645,6 +645,15 @@ * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the * attributes determining channel width. * + * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch + * has been started on an interface, regardless of the initiator + * (ie. whether it was requested from a remote device or + * initiated on our own). It indicates that + * %NL80211_ATTR_IFINDEX will be on %NL80211_ATTR_WIPHY_FREQ + * after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's. The userspace may + * decide to react to this indication by requesting other + * interfaces to change channel as well. + * * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by * its %NL80211_ATTR_WDEV identifier. It must have been created with * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the @@ -930,6 +939,8 @@ enum nl80211_commands { NL80211_CMD_JOIN_OCB, NL80211_CMD_LEAVE_OCB, + NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 24549cbe0b54..24fd2925b281 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11653,7 +11653,9 @@ EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, struct cfg80211_chan_def *chandef, - gfp_t gfp) + gfp_t gfp, + enum nl80211_commands notif, + u8 count) { struct sk_buff *msg; void *hdr; @@ -11662,7 +11664,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, if (!msg) return; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY); + hdr = nl80211hdr_put(msg, 0, 0, 0, notif); if (!hdr) { nlmsg_free(msg); return; @@ -11674,6 +11676,10 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, if (nl80211_send_chandef(msg, chandef)) goto nla_put_failure; + if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) && + (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))) + goto nla_put_failure; + genlmsg_end(msg, hdr); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, @@ -11704,10 +11710,26 @@ void cfg80211_ch_switch_notify(struct net_device *dev, wdev->chandef = *chandef; wdev->preset_chandef = *chandef; - nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); + nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, + NL80211_CMD_CH_SWITCH_NOTIFY, 0); } EXPORT_SYMBOL(cfg80211_ch_switch_notify); +void cfg80211_ch_switch_started_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef, + u8 count) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + + trace_cfg80211_ch_switch_started_notify(dev, chandef); + + nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, + NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count); +} +EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); + void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, u32 num_packets, u32 rate, u32 intvl, gfp_t gfp) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 277a85df910e..6e25370d3ce7 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2355,6 +2355,22 @@ TRACE_EVENT(cfg80211_ch_switch_notify, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) ); +TRACE_EVENT(cfg80211_ch_switch_started_notify, + TP_PROTO(struct net_device *netdev, + struct cfg80211_chan_def *chandef), + TP_ARGS(netdev, chandef), + TP_STRUCT__entry( + NETDEV_ENTRY + CHAN_DEF_ENTRY + ), + TP_fast_assign( + NETDEV_ASSIGN; + CHAN_DEF_ASSIGN(chandef); + ), + TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT, + NETDEV_PR_ARG, CHAN_DEF_PR_ARG) +); + TRACE_EVENT(cfg80211_radar_event, TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), TP_ARGS(wiphy, chandef), -- GitLab From 2f4572930dbd79216294a94e331478513c65df78 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 7 Nov 2014 14:31:36 +0200 Subject: [PATCH 4112/9457] mac80211: send channel switch started notifications Send a channel switch notification to userspace when a channel switch is requested or when we react to a remote CSA. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 +++ net/mac80211/mlme.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 76e794edd960..a43a14863ecb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3195,6 +3195,9 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, ieee80211_stop_vif_queues(local, sdata, IEEE80211_QUEUE_STOP_REASON_CSA); + cfg80211_ch_switch_started_notify(sdata->dev, &sdata->csa_chandef, + params->count); + if (changed) { ieee80211_bss_info_change_notify(sdata, changed); drv_channel_switch_beacon(sdata, ¶ms->chandef); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 213a420704a6..947250077615 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1205,6 +1205,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, IEEE80211_QUEUE_STOP_REASON_CSA); mutex_unlock(&local->mtx); + cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, + csa_ie.count); + if (local->ops->channel_switch) { /* use driver's channel switch callback */ drv_channel_switch(local, sdata, &ch_switch); -- GitLab From d04b5ac9e70b2056a8a12f768f4b46773576025e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 7 Nov 2014 14:31:37 +0200 Subject: [PATCH 4113/9457] cfg80211/mac80211: allow any interface to send channel switch notifications For multi-vif channel switches, we want to send NL80211_CMD_CH_SWITCH_NOTIFY to the userspace to let it decide whether other interfaces need to be moved as well. This is needed when we want a P2P GO interface to follow the channel of a station, for example. Modify the code so that all interfaces can send CSA notifications. Additionally, send notifications for STA CSA as well. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 4 +++- net/mac80211/mlme.c | 2 ++ net/wireless/nl80211.c | 6 ------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 354163433352..a552736c3e59 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -643,7 +643,9 @@ * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels * independently of the userspace SME, send this event indicating * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the - * attributes determining channel width. + * attributes determining channel width. This indication may also be + * sent when a remotely-initiated switch (e.g., when a STA receives a CSA + * from the remote AP) is completed; * * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch * has been started on an interface, regardless of the initiator diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 947250077615..243539878991 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1049,6 +1049,8 @@ static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) sdata->csa_block_tx = false; } + cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef); + sdata->vif.csa_active = false; ifmgd->csa_waiting_bcn = false; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 24fd2925b281..d0a8361b3395 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11702,12 +11702,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, trace_cfg80211_ch_switch_notify(dev, chandef); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && - wdev->iftype != NL80211_IFTYPE_P2P_GO && - wdev->iftype != NL80211_IFTYPE_ADHOC && - wdev->iftype != NL80211_IFTYPE_MESH_POINT)) - return; - wdev->chandef = *chandef; wdev->preset_chandef = *chandef; nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, -- GitLab From 1f7bba79af57ceecf25c2b7d3e6a484efefe340f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 6 Nov 2014 22:56:36 +0100 Subject: [PATCH 4114/9457] mac80211: add back support for radiotap vendor namespace data Radiotap vendor namespace data might still be useful, but we reverted it because it used too much space in the RX status. Put it back, but address the space problem by using a single bit only and putting everything else into the skb->data. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 50 +++++++++++++ include/net/mac80211.h | 37 ++++++++++ net/mac80211/rx.c | 100 +++++++++++++++++++++----- 3 files changed, 169 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 209db62ee627..58f11bb0896f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -984,6 +984,53 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr, data->receive = true; } +static void mac80211_hwsim_add_vendor_rtap(struct sk_buff *skb) +{ + /* + * To enable this code, #define the HWSIM_RADIOTAP_OUI, + * e.g. like this: + * #define HWSIM_RADIOTAP_OUI "\x02\x00\x00" + * (but you should use a valid OUI, not that) + * + * If anyone wants to 'donate' a radiotap OUI/subns code + * please send a patch removing this #ifdef and changing + * the values accordingly. + */ +#ifdef HWSIM_RADIOTAP_OUI + struct ieee80211_vendor_radiotap *rtap; + + /* + * Note that this code requires the headroom in the SKB + * that was allocated earlier. + */ + rtap = (void *)skb_push(skb, sizeof(*rtap) + 8 + 4); + rtap->oui[0] = HWSIM_RADIOTAP_OUI[0]; + rtap->oui[1] = HWSIM_RADIOTAP_OUI[1]; + rtap->oui[2] = HWSIM_RADIOTAP_OUI[2]; + rtap->subns = 127; + + /* + * Radiotap vendor namespaces can (and should) also be + * split into fields by using the standard radiotap + * presence bitmap mechanism. Use just BIT(0) here for + * the presence bitmap. + */ + rtap->present = BIT(0); + /* We have 8 bytes of (dummy) data */ + rtap->len = 8; + /* For testing, also require it to be aligned */ + rtap->align = 8; + /* And also test that padding works, 4 bytes */ + rtap->pad = 4; + /* push the data */ + memcpy(rtap->data, "ABCDEFGH", 8); + /* make sure to clear padding, mac80211 doesn't */ + memset(rtap->data + 8, 0, 4); + + IEEE80211_SKB_RXCB(skb)->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA; +#endif +} + static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_channel *chan) @@ -1098,6 +1145,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, rx_status.mactime = now + data2->tsf_offset; memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); + + mac80211_hwsim_add_vendor_rtap(nskb); + data2->rx_pkts++; data2->rx_bytes += nskb->len; ieee80211_rx_irqsafe(data2->hw, nskb); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5f203a6a5e7e..83232aa2f077 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -882,6 +882,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * subframes share the same sequence number. Reported subframes can be * either regular MSDU or singly A-MSDUs. Subframes must not be * interleaved with other frames. + * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific + * radiotap data in the skb->data (before the frame) as described by + * the &struct ieee80211_vendor_radiotap. */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = BIT(0), @@ -911,6 +914,7 @@ enum mac80211_rx_flags { RX_FLAG_10MHZ = BIT(28), RX_FLAG_5MHZ = BIT(29), RX_FLAG_AMSDU_MORE = BIT(30), + RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31), }; #define RX_FLAG_STBC_SHIFT 26 @@ -981,6 +985,39 @@ struct ieee80211_rx_status { u8 ampdu_delimiter_crc; }; +/** + * struct ieee80211_vendor_radiotap - vendor radiotap data information + * @present: presence bitmap for this vendor namespace + * (this could be extended in the future if any vendor needs more + * bits, the radiotap spec does allow for that) + * @align: radiotap vendor namespace alignment. This defines the needed + * alignment for the @data field below, not for the vendor namespace + * description itself (which has a fixed 2-byte alignment) + * Must be a power of two, and be set to at least 1! + * @oui: radiotap vendor namespace OUI + * @subns: radiotap vendor sub namespace + * @len: radiotap vendor sub namespace skip length, if alignment is done + * then that's added to this, i.e. this is only the length of the + * @data field. + * @pad: number of bytes of padding after the @data, this exists so that + * the skb data alignment can be preserved even if the data has odd + * length + * @data: the actual vendor namespace data + * + * This struct, including the vendor data, goes into the skb->data before + * the 802.11 header. It's split up in mac80211 using the align/oui/subns + * data. + */ +struct ieee80211_vendor_radiotap { + u32 present; + u8 align; + u8 oui[3]; + u8 subns; + u8 pad; + u16 len; + u8 data[]; +} __packed; + /** * enum ieee80211_conf_flags - configuration flags * diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bc63aa0c5401..f57af5c7c12a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -39,7 +39,8 @@ * only useful for monitoring. */ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, - struct sk_buff *skb) + struct sk_buff *skb, + unsigned int rtap_vendor_space) { if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { if (likely(skb->len > FCS_LEN)) @@ -52,20 +53,25 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, } } + __pskb_pull(skb, rtap_vendor_space); + return skb; } -static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len) +static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len, + unsigned int rtap_vendor_space) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_hdr *hdr = (void *)skb->data; + struct ieee80211_hdr *hdr; + + hdr = (void *)(skb->data + rtap_vendor_space); if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC | RX_FLAG_AMPDU_IS_ZEROLEN)) return true; - if (unlikely(skb->len < 16 + present_fcs_len)) + if (unlikely(skb->len < 16 + present_fcs_len + rtap_vendor_space)) return true; if (ieee80211_is_ctl(hdr->frame_control) && @@ -77,8 +83,9 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len) } static int -ieee80211_rx_radiotap_space(struct ieee80211_local *local, - struct ieee80211_rx_status *status) +ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local, + struct ieee80211_rx_status *status, + struct sk_buff *skb) { int len; @@ -121,6 +128,21 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local, len += 2 * hweight8(status->chains); } + if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { + struct ieee80211_vendor_radiotap *rtap = (void *)skb->data; + + /* vendor presence bitmap */ + len += 4; + /* alignment for fixed 6-byte vendor data header */ + len = ALIGN(len, 2); + /* vendor data header */ + len += 6; + if (WARN_ON(rtap->align == 0)) + rtap->align = 1; + len = ALIGN(len, rtap->align); + len += rtap->len + rtap->pad; + } + return len; } @@ -144,13 +166,20 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, u16 channel_flags = 0; int mpdulen, chain; unsigned long chains = status->chains; + struct ieee80211_vendor_radiotap rtap = {}; + + if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { + rtap = *(struct ieee80211_vendor_radiotap *)skb->data; + /* rtap.len and rtap.pad are undone immediately */ + skb_pull(skb, sizeof(rtap) + rtap.len + rtap.pad); + } mpdulen = skb->len; if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS))) mpdulen += FCS_LEN; rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); - memset(rthdr, 0, rtap_len); + memset(rthdr, 0, rtap_len - rtap.len - rtap.pad); it_present = &rthdr->it_present; /* radiotap header, set always present flags */ @@ -172,6 +201,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL); } + if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { + it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | + BIT(IEEE80211_RADIOTAP_EXT); + put_unaligned_le32(it_present_val, it_present); + it_present++; + it_present_val = rtap.present; + } + put_unaligned_le32(it_present_val, it_present); pos = (void *)(it_present + 1); @@ -366,6 +403,22 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, *pos++ = status->chain_signal[chain]; *pos++ = chain; } + + if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { + /* ensure 2 byte alignment for the vendor field as required */ + if ((pos - (u8 *)rthdr) & 1) + *pos++ = 0; + *pos++ = rtap.oui[0]; + *pos++ = rtap.oui[1]; + *pos++ = rtap.oui[2]; + *pos++ = rtap.subns; + put_unaligned_le16(rtap.len, pos); + pos += 2; + /* align the actual payload as requested */ + while ((pos - (u8 *)rthdr) & (rtap.align - 1)) + *pos++ = 0; + /* data (and possible padding) already follows */ + } } /* @@ -379,10 +432,17 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); struct ieee80211_sub_if_data *sdata; - int needed_headroom; + int rt_hdrlen, needed_headroom; struct sk_buff *skb, *skb2; struct net_device *prev_dev = NULL; int present_fcs_len = 0; + unsigned int rtap_vendor_space = 0; + + if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) { + struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data; + + rtap_vendor_space = sizeof(*rtap) + rtap->len + rtap->pad; + } /* * First, we may need to make a copy of the skb because @@ -396,25 +456,27 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) present_fcs_len = FCS_LEN; - /* ensure hdr->frame_control is in skb head */ - if (!pskb_may_pull(origskb, 2)) { + /* ensure hdr->frame_control and vendor radiotap data are in skb head */ + if (!pskb_may_pull(origskb, 2 + rtap_vendor_space)) { dev_kfree_skb(origskb); return NULL; } if (!local->monitors) { - if (should_drop_frame(origskb, present_fcs_len)) { + if (should_drop_frame(origskb, present_fcs_len, + rtap_vendor_space)) { dev_kfree_skb(origskb); return NULL; } - return remove_monitor_info(local, origskb); + return remove_monitor_info(local, origskb, rtap_vendor_space); } /* room for the radiotap header based on driver features */ - needed_headroom = ieee80211_rx_radiotap_space(local, status); + rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, origskb); + needed_headroom = rt_hdrlen - rtap_vendor_space; - if (should_drop_frame(origskb, present_fcs_len)) { + if (should_drop_frame(origskb, present_fcs_len, rtap_vendor_space)) { /* only need to expand headroom if necessary */ skb = origskb; origskb = NULL; @@ -438,15 +500,15 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, */ skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); - origskb = remove_monitor_info(local, origskb); + origskb = remove_monitor_info(local, origskb, + rtap_vendor_space); if (!skb) return origskb; } /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, - true); + ieee80211_add_rx_radiotap_header(local, skb, rate, rt_hdrlen, true); skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2892,8 +2954,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, if (!local->cooked_mntrs) goto out_free_skb; + /* vendor data is long removed here */ + status->flag &= ~RX_FLAG_RADIOTAP_VENDOR_DATA; /* room for the radiotap header based on driver features */ - needed_headroom = ieee80211_rx_radiotap_space(local, status); + needed_headroom = ieee80211_rx_radiotap_hdrlen(local, status, skb); if (skb_headroom(skb) < needed_headroom && pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) -- GitLab From a6d4a534e15f0e1b13b518c31219f9fb7166412a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 23 Oct 2014 09:37:33 +0300 Subject: [PATCH 4115/9457] cfg80211: introduce regulatory flags controlling bw Allow setting bandwidth related regulatory flags. These flags are mapped to the corresponding channel flags in the specified range. Make sure the new flags are consulted when calculating the maximum bandwidth allowed by a regulatory-rule. Also allow propagating the GO_CONCURRENT modifier from a reg-rule to a channel. Signed-off-by: Arik Nemtsov Reviewed-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 12 ++++++++++++ net/wireless/reg.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index a552736c3e59..442369f69b4f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2665,6 +2665,11 @@ enum nl80211_sched_scan_match_attr { * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated * base on contiguous rules and wider channels will be allowed to cross * multiple contiguous/overlapping frequency ranges. + * @NL80211_RRF_GO_CONCURRENT: See &NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation + * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation + * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed + * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed */ enum nl80211_reg_rule_flags { NL80211_RRF_NO_OFDM = 1<<0, @@ -2677,11 +2682,18 @@ enum nl80211_reg_rule_flags { NL80211_RRF_NO_IR = 1<<7, __NL80211_RRF_NO_IBSS = 1<<8, NL80211_RRF_AUTO_BW = 1<<11, + NL80211_RRF_GO_CONCURRENT = 1<<12, + NL80211_RRF_NO_HT40MINUS = 1<<13, + NL80211_RRF_NO_HT40PLUS = 1<<14, + NL80211_RRF_NO_80MHZ = 1<<15, + NL80211_RRF_NO_160MHZ = 1<<16, }; #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR +#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ + NL80211_RRF_NO_HT40PLUS) /* For backport compatibility with older userspace */ #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b725a31a4751..7449a8c0f9fd 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -573,8 +573,9 @@ static const struct ieee80211_regdomain *reg_get_regdomain(struct wiphy *wiphy) return get_cfg80211_regdom(); } -unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, - const struct ieee80211_reg_rule *rule) +static unsigned int +reg_get_max_bandwidth_from_range(const struct ieee80211_regdomain *rd, + const struct ieee80211_reg_rule *rule) { const struct ieee80211_freq_range *freq_range = &rule->freq_range; const struct ieee80211_freq_range *freq_range_tmp; @@ -622,6 +623,27 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, return end_freq - start_freq; } +unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, + const struct ieee80211_reg_rule *rule) +{ + unsigned int bw = reg_get_max_bandwidth_from_range(rd, rule); + + if (rule->flags & NL80211_RRF_NO_160MHZ) + bw = min_t(unsigned int, bw, MHZ_TO_KHZ(80)); + if (rule->flags & NL80211_RRF_NO_80MHZ) + bw = min_t(unsigned int, bw, MHZ_TO_KHZ(40)); + + /* + * HT40+/HT40- limits are handled per-channel. Only limit BW if both + * are not allowed. + */ + if (rule->flags & NL80211_RRF_NO_HT40MINUS && + rule->flags & NL80211_RRF_NO_HT40PLUS) + bw = min_t(unsigned int, bw, MHZ_TO_KHZ(20)); + + return bw; +} + /* Sanity check on a regulatory rule */ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule) { @@ -946,6 +968,16 @@ static u32 map_regdom_flags(u32 rd_flags) channel_flags |= IEEE80211_CHAN_NO_OFDM; if (rd_flags & NL80211_RRF_NO_OUTDOOR) channel_flags |= IEEE80211_CHAN_INDOOR_ONLY; + if (rd_flags & NL80211_RRF_GO_CONCURRENT) + channel_flags |= IEEE80211_CHAN_GO_CONCURRENT; + if (rd_flags & NL80211_RRF_NO_HT40MINUS) + channel_flags |= IEEE80211_CHAN_NO_HT40MINUS; + if (rd_flags & NL80211_RRF_NO_HT40PLUS) + channel_flags |= IEEE80211_CHAN_NO_HT40PLUS; + if (rd_flags & NL80211_RRF_NO_80MHZ) + channel_flags |= IEEE80211_CHAN_NO_80MHZ; + if (rd_flags & NL80211_RRF_NO_160MHZ) + channel_flags |= IEEE80211_CHAN_NO_160MHZ; return channel_flags; } -- GitLab From 368494093354ac613a80c2e1d77602aa12473cf0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Nov 2014 12:27:33 +0200 Subject: [PATCH 4116/9457] ASoC: tlv320aic3x: Add TDM support TDM support is achieved using DSP transfer mode and setting a programmable offset which specifies where data begins with respect to the frame sync. It requires 256-clock mode if CODEC is master (not currently supported in the driver). No additional dependency if CODEC is slave. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 62 ++++++++++++++++++++++++++++++++-- sound/soc/codecs/tlv320aic3x.h | 1 + 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index f7c2a575a892..8770e28e53a4 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -78,6 +78,8 @@ struct aic3x_priv { struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; struct aic3x_setup_data *setup; unsigned int sysclk; + unsigned int dai_fmt; + unsigned int tdm_delay; struct list_head list; int master; int gpio_reset; @@ -1009,6 +1011,25 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, return 0; } +static int aic3x_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + int delay = 0; + + /* TDM slot selection only valid in DSP_A/_B mode */ + if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A) + delay += (aic3x->tdm_delay + 1); + else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B) + delay += aic3x->tdm_delay; + + /* Configure data delay */ + snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, aic3x->tdm_delay); + + return 0; +} + static int aic3x_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; @@ -1048,7 +1069,6 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); u8 iface_areg, iface_breg; - int delay = 0; iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f; iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f; @@ -1076,7 +1096,6 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF): break; case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF): - delay = 1; case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF): iface_breg |= (0x01 << 6); break; @@ -1090,10 +1109,45 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } + aic3x->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + /* set iface */ snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg); snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg); - snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); + + return 0; +} + +static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + unsigned int lsb; + + if (tx_mask != rx_mask) { + dev_err(codec->dev, "tx and rx masks must be symmetric\n"); + return -EINVAL; + } + + if (unlikely(!tx_mask)) { + dev_err(codec->dev, "tx and rx masks need to be non 0\n"); + return -EINVAL; + } + + /* TDM based on DSP mode requires slots to be adjacent */ + lsb = __ffs(tx_mask); + if ((lsb + 1) != __fls(tx_mask)) { + dev_err(codec->dev, "Invalid mask, slots must be adjacent\n"); + return -EINVAL; + } + + aic3x->tdm_delay = lsb * slot_width; + + /* DOUT in high-impedance on inactive bit clocks */ + snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA, + DOUT_TRISTATE, DOUT_TRISTATE); return 0; } @@ -1212,9 +1266,11 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, static const struct snd_soc_dai_ops aic3x_dai_ops = { .hw_params = aic3x_hw_params, + .prepare = aic3x_prepare, .digital_mute = aic3x_mute, .set_sysclk = aic3x_set_dai_sysclk, .set_fmt = aic3x_set_dai_fmt, + .set_tdm_slot = aic3x_set_dai_tdm_slot, }; static struct snd_soc_dai_driver aic3x_dai = { diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index e521ac3ddde8..89fa692df206 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -169,6 +169,7 @@ /* Audio serial data interface control register A bits */ #define BIT_CLK_MASTER 0x80 #define WORD_CLK_MASTER 0x40 +#define DOUT_TRISTATE 0x20 /* Codec Datapath setup register 7 */ #define FSREF_44100 (1 << 7) -- GitLab From ff7c532c3ae570981a46663d5810dda913d468d9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 9 Nov 2014 20:41:51 +0100 Subject: [PATCH 4117/9457] ASoC: omap: enable sound support on n900 on devicetree-based boot With device tree, it is possible (and encouraged) to build N900 kernels without CONFIG_MACH_NOKIA_RX51. Update config file to enable the driver build in this case. This makes sound work on my n900 under 3.18-rc1. Signed-off-by: Pavel Machek Signed-off-by: Mark Brown --- sound/soc/omap/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index d44463a7b0fa..2738b1984410 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -25,15 +25,15 @@ config SND_OMAP_SOC_N810 Say Y if you want to add support for SoC audio on Nokia N810. config SND_OMAP_SOC_RX51 - tristate "SoC Audio support for Nokia RX-51" - depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) && I2C + tristate "SoC Audio support for Nokia N900 (RX-51)" + depends on SND_OMAP_SOC && ARM && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC3X select SND_SOC_TPA6130A2 depends on GPIOLIB help - Say Y if you want to add support for SoC audio on Nokia RX-51 - hardware. This is also known as Nokia N900 product. + Say Y if you want to add support for SoC audio on Nokia N900 + cellphone. config SND_OMAP_SOC_AMS_DELTA tristate "SoC Audio support for Amstrad E3 (Delta) videophone" -- GitLab From ac146235d47c20dbb1da7f0f8ef35c73e24590e3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 10 Nov 2014 13:53:25 +0100 Subject: [PATCH 4118/9457] KVM: x86: fix warning on 32-bit compilation PCIDs are only supported in 64-bit mode. No need to clear bit 63 of CR3 unless the host is 64-bit. Reported by Fengguang Wu's autobuilder. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f85da5cb6aa6..aae5969370d1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -750,7 +750,9 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { +#ifdef CONFIG_X86_64 cr3 &= ~CR3_PCID_INVD; +#endif if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { kvm_mmu_sync_roots(vcpu); -- GitLab From 7771ef3286711a121b763c3620c4619f51b2acfd Mon Sep 17 00:00:00 2001 From: Anil Kumar Date: Sun, 9 Nov 2014 18:15:14 +0530 Subject: [PATCH 4119/9457] ASoC: davinvi-mcasp: Balance pm_runtime_enable() on probe failure If probe fails then we need to call pm_runtime_disable() to balance out the previous pm_runtime_enable() call. Signed-off-by: Anil Kumar Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 002351f9fc40..57f606e4cf02 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1225,6 +1225,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ret = pm_runtime_get_sync(&pdev->dev); if (IS_ERR_VALUE(ret)) { dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); + pm_runtime_disable(&pdev->dev); return ret; } -- GitLab From 62b62b6e5c574c1e70637d9d685b4b194c7ca48f Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 4 Nov 2014 03:08:09 +0100 Subject: [PATCH 4120/9457] crypto: drbg - add MODULE_ALIAS for all DRBG types The kernel module drbg.ko is currently not loaded automatically when a DRBG is requested by a consumer. This is due to missing MODULE_ALIAS flags for each of the implemented DRBG types. This patch adds aliases for each of the 22 defined DRBGs. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crypto/drbg.c b/crypto/drbg.c index 8c0a742b60f6..9fb38a55118a 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -291,6 +291,13 @@ static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf) #ifdef CONFIG_CRYPTO_DRBG_CTR #define CRYPTO_DRBG_CTR_STRING "CTR " +MODULE_ALIAS("drbg_pr_ctr_aes256"); +MODULE_ALIAS("drbg_nopr_ctr_aes256"); +MODULE_ALIAS("drbg_pr_ctr_aes192"); +MODULE_ALIAS("drbg_nopr_ctr_aes192"); +MODULE_ALIAS("drbg_pr_ctr_aes128"); +MODULE_ALIAS("drbg_nopr_ctr_aes128"); + static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, unsigned char *outval, const struct drbg_string *in); static int drbg_init_sym_kernel(struct drbg_state *drbg); @@ -651,6 +658,15 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg); #ifdef CONFIG_CRYPTO_DRBG_HMAC #define CRYPTO_DRBG_HMAC_STRING "HMAC " +MODULE_ALIAS("drbg_pr_hmac_sha512"); +MODULE_ALIAS("drbg_nopr_hmac_sha512"); +MODULE_ALIAS("drbg_pr_hmac_sha384"); +MODULE_ALIAS("drbg_nopr_hmac_sha384"); +MODULE_ALIAS("drbg_pr_hmac_sha256"); +MODULE_ALIAS("drbg_nopr_hmac_sha256"); +MODULE_ALIAS("drbg_pr_hmac_sha1"); +MODULE_ALIAS("drbg_nopr_hmac_sha1"); + /* update function of HMAC DRBG as defined in 10.1.2.2 */ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed, int reseed) @@ -762,6 +778,15 @@ static struct drbg_state_ops drbg_hmac_ops = { #ifdef CONFIG_CRYPTO_DRBG_HASH #define CRYPTO_DRBG_HASH_STRING "HASH " +MODULE_ALIAS("drbg_pr_sha512"); +MODULE_ALIAS("drbg_nopr_sha512"); +MODULE_ALIAS("drbg_pr_sha384"); +MODULE_ALIAS("drbg_nopr_sha384"); +MODULE_ALIAS("drbg_pr_sha256"); +MODULE_ALIAS("drbg_nopr_sha256"); +MODULE_ALIAS("drbg_pr_sha1"); +MODULE_ALIAS("drbg_nopr_sha1"); + /* * Increment buffer * -- GitLab From dbd8fbefd833da9f212d19e0034b62c02c644b70 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 6 Nov 2014 14:27:35 +0100 Subject: [PATCH 4121/9457] crypto: ux500/cryp - Silence compiler warning for !CONFIG_PM The system PM functions were unused when CONFIG_PM is unset. Let's move them inside CONFIG_PM_SLEEP to silence the compiler warning. Signed-off-by: Ulf Hansson Signed-off-by: Herbert Xu --- drivers/crypto/ux500/cryp/cryp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 92105f3dc8e0..83811aab207e 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c @@ -1688,6 +1688,7 @@ static void ux500_cryp_shutdown(struct platform_device *pdev) } +#ifdef CONFIG_PM_SLEEP static int ux500_cryp_suspend(struct device *dev) { int ret; @@ -1768,6 +1769,7 @@ static int ux500_cryp_resume(struct device *dev) return ret; } +#endif static SIMPLE_DEV_PM_OPS(ux500_cryp_pm, ux500_cryp_suspend, ux500_cryp_resume); -- GitLab From bdcf83b7831e41f666b50ee6cd946c733bbea1ef Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 6 Nov 2014 14:28:01 +0100 Subject: [PATCH 4122/9457] crypto: ux500/hash - Silence compiler warning for !CONFIG_PM The system PM functions were unused when CONFIG_PM is unset. Let's move them inside CONFIG_PM_SLEEP to silence the compiler warning. Signed-off-by: Ulf Hansson Signed-off-by: Herbert Xu --- drivers/crypto/ux500/hash/hash_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 1c73f4fbc252..5af53b5508b0 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1881,6 +1881,7 @@ static void ux500_hash_shutdown(struct platform_device *pdev) __func__); } +#ifdef CONFIG_PM_SLEEP /** * ux500_hash_suspend - Function that suspends the hash device. * @dev: Device to suspend. @@ -1949,6 +1950,7 @@ static int ux500_hash_resume(struct device *dev) return ret; } +#endif static SIMPLE_DEV_PM_OPS(ux500_hash_pm, ux500_hash_suspend, ux500_hash_resume); -- GitLab From edf387b6d1a6993103ec95ed934a6daf559535f4 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sat, 11 Oct 2014 16:46:26 +0300 Subject: [PATCH 4123/9457] backlight: pwm: Clean-up pwm requested using legacy API If PWM device is requested by means of legacy API pwm_request(), its resources are not freed on module unbind, which may cause an oops on access, e.g. by reading /sys/kernel/debug/pwm. Reported-by: Dmitry Eremin-Solenikov Signed-off-by: Vladimir Zapolskiy Signed-off-by: Lee Jones --- drivers/video/backlight/pwm_bl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index cb5ae4c08469..3a145a643e0d 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -34,6 +34,7 @@ struct pwm_bl_data { struct regulator *power_supply; struct gpio_desc *enable_gpio; unsigned int scale; + bool legacy; int (*notify)(struct device *, int brightness); void (*notify_after)(struct device *, @@ -274,7 +275,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(pb->pwm)) { dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); - + pb->legacy = true; pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); if (IS_ERR(pb->pwm)) { dev_err(&pdev->dev, "unable to request legacy PWM\n"); @@ -339,6 +340,8 @@ static int pwm_backlight_remove(struct platform_device *pdev) if (pb->exit) pb->exit(&pdev->dev); + if (pb->legacy) + pwm_free(pb->pwm); return 0; } -- GitLab From 2f97c326bf05ca2feeb95688da50c68671638b69 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 6 Nov 2014 17:21:24 -0800 Subject: [PATCH 4124/9457] f2fs: write node pages if checkpoint is not doing It needs to write node pages if checkpoint is not doing in order to avoid memory pressure. Reviewed-by: Changman Lee Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 4ea2c4728156..6f514fb5fd96 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1314,10 +1314,12 @@ static int f2fs_write_node_page(struct page *page, return 0; } - if (wbc->for_reclaim) - goto redirty_out; - - down_read(&sbi->node_write); + if (wbc->for_reclaim) { + if (!down_read_trylock(&sbi->node_write)) + goto redirty_out; + } else { + down_read(&sbi->node_write); + } set_page_writeback(page); write_node_page(sbi, page, &fio, nid, ni.blk_addr, &new_addr); set_node_addr(sbi, &ni, new_addr, is_fsync_dnode(page)); -- GitLab From 510184c89f21f40634e1585790714be060cd49c5 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 6 Nov 2014 17:23:08 -0800 Subject: [PATCH 4125/9457] f2fs: do not skip any writes under memory pressure Under memory pressure, let's avoid skipping data writes. Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 6723ccc17585..7f327c0ba4e3 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -711,6 +711,9 @@ static inline unsigned int max_hw_blocks(struct f2fs_sb_info *sbi) */ static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type) { + if (sbi->sb->s_bdi->dirty_exceeded) + return 0; + if (type == DATA) return sbi->blocks_per_seg; else if (type == NODE) -- GitLab From b7e1d800031c827a80c9a9d03cf15e4dd5405a44 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sun, 9 Nov 2014 22:15:31 -0800 Subject: [PATCH 4126/9457] f2fs: implement -o dirsync If a mount option has dirsync, we should call checkpoint for all the directory operations. Signed-off-by: Jaegeuk Kim --- fs/f2fs/namei.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 6312dd2e53f7..2bee559a690f 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -138,6 +138,9 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, stat_inc_inline_inode(inode); d_instantiate(dentry, inode); unlock_new_inode(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: handle_failed_inode(inode); @@ -164,6 +167,9 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, f2fs_unlock_op(sbi); d_instantiate(dentry, inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: clear_inode_flag(F2FS_I(inode), FI_INC_LINK); @@ -235,6 +241,9 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) /* In order to evict this inode, we set it dirty */ mark_inode_dirty(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); fail: trace_f2fs_unlink_exit(inode, err); return err; @@ -268,6 +277,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, d_instantiate(dentry, inode); unlock_new_inode(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return err; out: handle_failed_inode(inode); @@ -304,6 +316,8 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) d_instantiate(dentry, inode); unlock_new_inode(inode); + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out_fail: @@ -346,8 +360,12 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, f2fs_unlock_op(sbi); alloc_nid_done(sbi, inode->i_ino); + d_instantiate(dentry, inode); unlock_new_inode(inode); + + if (IS_DIRSYNC(dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out: handle_failed_inode(inode); @@ -461,6 +479,9 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, } f2fs_unlock_op(sbi); + + if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; put_out_dir: @@ -600,6 +621,9 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, update_inode_page(new_dir); f2fs_unlock_op(sbi); + + if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) + f2fs_sync_fs(sbi->sb, 1); return 0; out_undo: /* Still we may fail to recover name info of f2fs_inode here */ -- GitLab From 30cc4faf703955cd5cd07da489bd817ae43e3fec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 20:00:30 -0800 Subject: [PATCH 4127/9457] ASoC: rsnd: tidyup debug message format and timing Current Renesas R-Car sound driver debug message is using random format (ex "ssi0: xxx" / "SSI0 xxx" / "ssi[0]: xxx") and confusable timing ("xxx probe failed" and "xxx probed" are shown in same time) This patch fixes these Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 2 +- sound/soc/sh/rcar/dvc.c | 3 ++- sound/soc/sh/rcar/gen.c | 6 +++--- sound/soc/sh/rcar/src.c | 11 +++++++---- sound/soc/sh/rcar/ssi.c | 25 ++++++++++++++++--------- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 1922ec57d10a..5205618a1990 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -409,7 +409,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) ({ \ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ struct device *dev = rsnd_priv_to_dev(priv); \ - dev_dbg(dev, "%s [%d] %s\n", \ + dev_dbg(dev, "%s[%d] %s\n", \ rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ (mod)->ops->func(mod, rdai); \ }) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 8504f6b1c086..956b84eb3f20 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -85,7 +85,8 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); - dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod)); + dev_dbg(dev, "%s[%d] (Gen2) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 61dee68ffc0d..a0fed661142c 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -78,7 +78,7 @@ u32 rsnd_read(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return 0; - dev_dbg(dev, "r %s(%d) - %4d : %08x\n", + dev_dbg(dev, "r %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); @@ -96,7 +96,7 @@ void rsnd_write(struct rsnd_priv *priv, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "w %s(%d) - %4d : %08x\n", + dev_dbg(dev, "w %s[%d] - %4d : %08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); @@ -111,7 +111,7 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, if (!rsnd_is_accessible_reg(priv, gen, reg)) return; - dev_dbg(dev, "b %s(%d) - %4d : %08x/%08x\n", + dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n", rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 9183e0145503..46795019b2c7 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -438,7 +438,8 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod, struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); - dev_dbg(dev, "%s (Gen1) is probed\n", rsnd_mod_name(mod)); + dev_dbg(dev, "%s[%d] (Gen1) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; } @@ -578,9 +579,11 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, rsnd_info_is_playback(priv, src), src->info->dma_id); if (ret < 0) - dev_err(dev, "SRC DMA failed\n"); - - dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (Gen2) failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (Gen2) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 34e84009162b..cae08b7ffa53 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -159,7 +159,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(j); - dev_dbg(dev, "ssi%d outputs %u Hz\n", + dev_dbg(dev, "%s[%d] outputs %u Hz\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod), rate); return 0; @@ -206,7 +207,8 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ssi->usrcnt++; - dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod)); + dev_dbg(dev, "%s[%d] hw started\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); } static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, @@ -249,7 +251,8 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, clk_disable_unprepare(ssi->clk); } - dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); + dev_dbg(dev, "%s[%d] hw stopped\n", + rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); } /* @@ -385,9 +388,11 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, IRQF_SHARED, dev_name(dev), ssi); if (ret) - dev_err(dev, "SSI request interrupt failed\n"); - - dev_dbg(dev, "%s (PIO) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (PIO) request interrupt failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (PIO) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } @@ -448,9 +453,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, dma_id); if (ret < 0) - dev_err(dev, "SSI DMA failed\n"); - - dev_dbg(dev, "%s (DMA) is probed\n", rsnd_mod_name(mod)); + dev_err(dev, "%s[%d] (DMA) is failed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + else + dev_dbg(dev, "%s[%d] (DMA) is probed\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); return ret; } -- GitLab From d3a768233243b5892a9c74b85896b9e8c017b259 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 20:00:58 -0800 Subject: [PATCH 4128/9457] ASoC: rsnd: fallback to PIO mode if DMA mode was failed Current Renesas R-Car sound driver probe will be failed if it try to use DMA mode and it couldn't use for some reasons. But PIO mode works even though in such case. This patch try to fallback to PIO mode if DMA mode probing was failed. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 74 +++++++++++++++++++++++++++++++++++++--- sound/soc/sh/rcar/ssi.c | 15 ++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5205618a1990..110b99da7acd 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -349,7 +349,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, dma_name); if (!dma->chan) { dev_err(dev, "can't get dma channel\n"); - return -EIO; + goto rsnd_dma_channel_err; } ret = dmaengine_slave_config(dma->chan, &cfg); @@ -363,8 +363,15 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, rsnd_dma_init_err: rsnd_dma_quit(priv, dma); +rsnd_dma_channel_err: - return ret; + /* + * DMA failed. try to PIO mode + * see + * rsnd_ssi_dma_remove() + * rsnd_rdai_continuance_probe() + */ + return -EAGAIN; } void rsnd_dma_quit(struct rsnd_priv *priv, @@ -456,6 +463,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod, return 0; } +static void rsnd_dai_disconnect(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) +{ + mod->io = NULL; + io->mod[mod->type] = NULL; +} + int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) { int id = rdai - priv->rdai; @@ -686,6 +700,20 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { ret; \ }) +#define rsnd_path_break(priv, io, type) \ +{ \ + struct rsnd_mod *mod; \ + int id = -1; \ + \ + if (rsnd_is_enable_path(io, type)) { \ + id = rsnd_info_id(priv, io, type); \ + if (id >= 0) { \ + mod = rsnd_##type##_mod_get(priv, id); \ + rsnd_dai_disconnect(mod, io); \ + } \ + } \ +} + static int rsnd_path_init(struct rsnd_priv *priv, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -977,6 +1005,44 @@ static const struct snd_soc_component_driver rsnd_soc_component = { .name = "rsnd", }; +static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + int is_play) +{ + struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; + int ret; + + ret = rsnd_dai_call(probe, io, rdai); + if (ret == -EAGAIN) { + /* + * Fallback to PIO mode + */ + + /* + * call "remove" for SSI/SRC/DVC + * SSI will be switch to PIO mode if it was DMA mode + * see + * rsnd_dma_init() + * rsnd_ssi_dma_remove() + */ + rsnd_dai_call(remove, io, rdai); + + /* + * remove SRC/DVC from DAI, + */ + rsnd_path_break(priv, io, src); + rsnd_path_break(priv, io, dvc); + + /* + * retry to "probe". + * DAI has SSI which is PIO mode only now. + */ + ret = rsnd_dai_call(probe, io, rdai); + } + + return ret; +} + /* * rsnd probe */ @@ -1038,11 +1104,11 @@ static int rsnd_probe(struct platform_device *pdev) } for_each_rsnd_dai(rdai, priv, i) { - ret = rsnd_dai_call(probe, &rdai->playback, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 1); if (ret) goto exit_snd_probe; - ret = rsnd_dai_call(probe, &rdai->capture, rdai); + ret = rsnd_rdai_continuance_probe(priv, rdai, 0); if (ret) goto exit_snd_probe; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index cae08b7ffa53..346d3dc66d73 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -465,8 +465,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, struct rsnd_dai *rdai) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); + rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); + /* + * fallback to PIO + * + * SSI .probe might be called again. + * see + * rsnd_rdai_continuance_probe() + */ + mod->ops = &rsnd_ssi_pio_ops; + + dev_info(dev, "%s[%d] fallback to PIO mode\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + return 0; } -- GitLab From d75249f54577d489d1642a246d3702416daa68f9 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Nov 2014 12:32:18 +0200 Subject: [PATCH 4129/9457] ASoC: davinci-mcasp: Symmetric sample bits for IIS mode In IIS mode the tx and rx configuration is symmetric, the BCLK and FSYNC is shared. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 57f606e4cf02..80c54ede5737 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -961,6 +961,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }, .ops = &davinci_mcasp_dai_ops, + .symmetric_samplebits = 1, }, { .name = "davinci-mcasp.1", -- GitLab From d742b925244ce91f16d380befdca473e4536359b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Nov 2014 12:32:19 +0200 Subject: [PATCH 4130/9457] ASoC: davinci-mcasp: Fix rx format when more bclk is used on the bus When the bus is configured to have more BCLK then the data type demands we need to use the rotation to move the data to correct place. Reported-by: Misael Lopez Cruz Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 80c54ede5737..ea3ad747d092 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -490,8 +490,17 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, * both left and right channels), so it has to be divided by number of * tdm-slots (for I2S - divided by 2). */ - if (mcasp->bclk_lrclk_ratio) - word_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots; + if (mcasp->bclk_lrclk_ratio) { + u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots; + + /* + * When we have more bclk then it is needed for the data, we + * need to use the rotation to move the received samples to have + * correct alignment. + */ + rx_rotate = (slot_length - word_length) / 4; + word_length = slot_length; + } /* mapping of the XSSZ bit-field as described in the datasheet */ fmt = (word_length >> 1) - 1; -- GitLab From 0285f8f5fd7cf7f458e13d9189eb735dacc244b5 Mon Sep 17 00:00:00 2001 From: addy ke Date: Tue, 14 Oct 2014 14:09:21 +0800 Subject: [PATCH 4131/9457] i2c: rk3x: adjust the LOW divison based on characteristics of SCL As show in I2C specification: - Standard-mode: the minimum HIGH period of the scl clock is 4.0us the minimum LOW period of the scl clock is 4.7us - Fast-mode: the minimum HIGH period of the scl clock is 0.6us the minimum LOW period of the scl clock is 1.3us I have measured i2c SCL waveforms in fast-mode by oscilloscope on rk3288-pinky board. the LOW period of the scl clock is 1.3us. It is so critical that we must adjust LOW division to increase the LOW period of the scl clock. Thanks Doug for the suggestion about division formulas. Signed-off-by: Addy Ke Tested-by: Heiko Stuebner Reviewed-by: Doug Anderson Reviewed-by: Max Schwarz Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rk3x.c | 162 ++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index f486d0eac4d0..e276ffbfbd1a 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Register Map */ @@ -428,18 +429,158 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) return IRQ_HANDLED; } -static void rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate) +static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, + unsigned long *div_low, unsigned long *div_high) { - unsigned long i2c_rate = clk_get_rate(i2c->clk); - unsigned int div; + unsigned long min_low_ns, min_high_ns; + unsigned long max_data_hold_ns; + unsigned long data_hold_buffer_ns; + unsigned long max_low_ns, min_total_ns; + + unsigned long i2c_rate_khz, scl_rate_khz; + + unsigned long min_low_div, min_high_div; + unsigned long max_low_div; + + unsigned long min_div_for_hold, min_total_div; + unsigned long extra_div, extra_low_div, ideal_low_div; + + /* Only support standard-mode and fast-mode */ + if (WARN_ON(scl_rate > 400000)) + scl_rate = 400000; + + /* prevent scl_rate_khz from becoming 0 */ + if (WARN_ON(scl_rate < 1000)) + scl_rate = 1000; + + /* + * min_low_ns: The minimum number of ns we need to hold low + * to meet i2c spec + * min_high_ns: The minimum number of ns we need to hold high + * to meet i2c spec + * max_low_ns: The maximum number of ns we can hold low + * to meet i2c spec + * + * Note: max_low_ns should be (max data hold time * 2 - buffer) + * This is because the i2c host on Rockchip holds the data line + * for half the low time. + */ + if (scl_rate <= 100000) { + min_low_ns = 4700; + min_high_ns = 4000; + max_data_hold_ns = 3450; + data_hold_buffer_ns = 50; + } else { + min_low_ns = 1300; + min_high_ns = 600; + max_data_hold_ns = 900; + data_hold_buffer_ns = 50; + } + max_low_ns = max_data_hold_ns * 2 - data_hold_buffer_ns; + min_total_ns = min_low_ns + min_high_ns; + + /* Adjust to avoid overflow */ + i2c_rate_khz = DIV_ROUND_UP(i2c_rate, 1000); + scl_rate_khz = scl_rate / 1000; - /* set DIV = DIVH = DIVL - * SCL rate = (clk rate) / (8 * (DIVH + 1 + DIVL + 1)) - * = (clk rate) / (16 * (DIV + 1)) + /* + * We need the total div to be >= this number + * so we don't clock too fast. + */ + min_total_div = DIV_ROUND_UP(i2c_rate_khz, scl_rate_khz * 8); + + /* These are the min dividers needed for min hold times. */ + min_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, 8 * 1000000); + min_high_div = DIV_ROUND_UP(i2c_rate_khz * min_high_ns, 8 * 1000000); + min_div_for_hold = (min_low_div + min_high_div); + + /* + * This is the maximum divider so we don't go over the max. + * We don't round up here (we round down) since this is a max. */ - div = DIV_ROUND_UP(i2c_rate, scl_rate * 16) - 1; + max_low_div = i2c_rate_khz * max_low_ns / (8 * 1000000); + + if (min_low_div > max_low_div) { + WARN_ONCE(true, + "Conflicting, min_low_div %lu, max_low_div %lu\n", + min_low_div, max_low_div); + max_low_div = min_low_div; + } - i2c_writel(i2c, (div << 16) | (div & 0xffff), REG_CLKDIV); + if (min_div_for_hold > min_total_div) { + /* + * Time needed to meet hold requirements is important. + * Just use that. + */ + *div_low = min_low_div; + *div_high = min_high_div; + } else { + /* + * We've got to distribute some time among the low and high + * so we don't run too fast. + */ + extra_div = min_total_div - min_div_for_hold; + + /* + * We'll try to split things up perfectly evenly, + * biasing slightly towards having a higher div + * for low (spend more time low). + */ + ideal_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, + scl_rate_khz * 8 * min_total_ns); + + /* Don't allow it to go over the max */ + if (ideal_low_div > max_low_div) + ideal_low_div = max_low_div; + + /* + * Handle when the ideal low div is going to take up + * more than we have. + */ + if (ideal_low_div > min_low_div + extra_div) + ideal_low_div = min_low_div + extra_div; + + /* Give low the "ideal" and give high whatever extra is left */ + extra_low_div = ideal_low_div - min_low_div; + *div_low = ideal_low_div; + *div_high = min_high_div + (extra_div - extra_low_div); + } + + /* + * Adjust to the fact that the hardware has an implicit "+1". + * NOTE: Above calculations always produce div_low > 0 and div_high > 0. + */ + *div_low = *div_low - 1; + *div_high = *div_high - 1; + + if (*div_low >= 0xffff || *div_high >= 0xffff) + return -EINVAL; + else + return 0; +} + +static int rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate) +{ + unsigned long i2c_rate = clk_get_rate(i2c->clk); + unsigned long div_low, div_high; + u64 t_low_ns, t_high_ns; + int ret = 0; + + ret = rk3x_i2c_calc_divs(i2c_rate, scl_rate, &div_low, &div_high); + if (ret < 0) + return ret; + + i2c_writel(i2c, (div_high << 16) | (div_low & 0xffff), REG_CLKDIV); + + t_low_ns = div_u64(((u64)div_low + 1) * 8 * 1000000000, i2c_rate); + t_high_ns = div_u64(((u64)div_high + 1) * 8 * 1000000000, i2c_rate); + dev_dbg(i2c->dev, + "CLK %lukhz, Req %luns, Act low %lluns high %lluns\n", + i2c_rate / 1000, + 1000000000 / scl_rate, + t_low_ns, t_high_ns); + + return ret; } /** @@ -537,7 +678,9 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap, clk_enable(i2c->clk); /* The clock rate might have changed, so setup the divider again */ - rk3x_i2c_set_scl_rate(i2c, i2c->scl_frequency); + ret = rk3x_i2c_set_scl_rate(i2c, i2c->scl_frequency); + if (ret < 0) + goto exit; i2c->is_last_msg = false; @@ -585,6 +728,7 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap, } } +exit: clk_disable(i2c->clk); spin_unlock_irqrestore(&i2c->lock, flags); -- GitLab From 1a5923da4e2e6997f03545a2b88f2cd2dea1a5c2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Nov 2014 12:32:15 +0200 Subject: [PATCH 4132/9457] ASoC: davinci-mcasp: Validate tdm_slots parameter at probe time Instead of validating the tdm_slots parameter every time at hw_params we can do it once during probe. If the parameter is not valid (<2 or >32) print an error and fix it up. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 6b1bfd9de57d..10c264738a0b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -632,13 +632,7 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) u32 mask = 0; u32 busel = 0; - if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) { - dev_err(mcasp->dev, "tdm slot %d not supported\n", - mcasp->tdm_slots); - return -EINVAL; - } - - active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; + active_slots = mcasp->tdm_slots; for (i = 0; i < active_slots; i++) mask |= (1 << i); @@ -650,12 +644,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, - FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); + FSXMOD(active_slots), FSXMOD(0x1FF)); mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, - FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); + FSRMOD(active_slots), FSRMOD(0x1FF)); return 0; } @@ -1237,7 +1231,21 @@ static int davinci_mcasp_probe(struct platform_device *pdev) } mcasp->op_mode = pdata->op_mode; - mcasp->tdm_slots = pdata->tdm_slots; + /* sanity check for tdm slots parameter */ + if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { + if (pdata->tdm_slots < 2) { + dev_err(&pdev->dev, "invalid tdm slots: %d\n", + pdata->tdm_slots); + mcasp->tdm_slots = 2; + } else if (pdata->tdm_slots > 32) { + dev_err(&pdev->dev, "invalid tdm slots: %d\n", + pdata->tdm_slots); + mcasp->tdm_slots = 32; + } else { + mcasp->tdm_slots = pdata->tdm_slots; + } + } + mcasp->num_serializer = pdata->num_serializer; #ifdef CONFIG_PM_SLEEP mcasp->context.xrsr_regs = devm_kzalloc(&pdev->dev, -- GitLab From 11277833ce8018ddd18925d2f85037bf02dcba63 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Nov 2014 12:32:16 +0200 Subject: [PATCH 4133/9457] ASoC: davinci-mcasp: Place constraint on number of channels In IIS (I2S, TDM, etc) mode the maximum number of allowed channels for either direction can be: number of serializers for the direction * tdm_slots. This constraint applicable for the first stream, while consequent stream should not have more channels then the first stream. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 10c264738a0b..10ae75e19d99 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -90,6 +90,9 @@ struct davinci_mcasp { bool dat_port; + /* Used for comstraint setting on the second stream */ + u32 channels; + #ifdef CONFIG_PM_SLEEP struct davinci_mcasp_context context; #endif @@ -811,6 +814,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, davinci_config_channel_size(mcasp, word_length); + if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) + mcasp->channels = channels; + return 0; } @@ -839,7 +845,61 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, return ret; } +static int davinci_mcasp_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + u32 max_channels = 0; + int i, dir; + + if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) + return 0; + + /* + * Limit the maximum allowed channels for the first stream: + * number of serializers for the direction * tdm slots per serializer + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dir = TX_MODE; + else + dir = RX_MODE; + + for (i = 0; i < mcasp->num_serializer; i++) { + if (mcasp->serial_dir[i] == dir) + max_channels++; + } + max_channels *= mcasp->tdm_slots; + /* + * If the already active stream has less channels than the calculated + * limnit based on the seirializers * tdm_slots, we need to use that as + * a constraint for the second stream. + * Otherwise (first stream or less allowed channels) we use the + * calculated constraint. + */ + if (mcasp->channels && mcasp->channels < max_channels) + max_channels = mcasp->channels; + + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + 2, max_channels); + return 0; +} + +static void davinci_mcasp_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + + if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) + return; + + if (!cpu_dai->active) + mcasp->channels = 0; +} + static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { + .startup = davinci_mcasp_startup, + .shutdown = davinci_mcasp_shutdown, .trigger = davinci_mcasp_trigger, .hw_params = davinci_mcasp_hw_params, .set_fmt = davinci_mcasp_set_dai_fmt, -- GitLab From 18a4f55756ac945bd89d1fe63dafe36462ecba86 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Mon, 10 Nov 2014 12:32:17 +0200 Subject: [PATCH 4134/9457] ASoC: davinci-mcasp: Active slots depend on active serializers Active slots count depends on the number of channels in the stream and the number of active serializers. Each serializer will handle at most the number of channels specified via 'tdm-slots' parameter in DT. There are two possible scenarios: - Single serializer: channel count fits in the max slots supported by McASP serializers, active slots is same as channel count - Multiple serializers: channel count is bigger than max slots supported by a serializer. Channel count determines how many serializers are needed at their max slot count configuration Signed-off-by: Misael Lopez Cruz Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 10ae75e19d99..a9822c7bbb0b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -629,13 +629,29 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return 0; } -static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) +static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, + int channels) { int i, active_slots; + int total_slots; + int active_serializers; u32 mask = 0; u32 busel = 0; - active_slots = mcasp->tdm_slots; + total_slots = mcasp->tdm_slots; + + /* + * If more than one serializer is needed, then use them with + * their specified tdm_slots count. Otherwise, one serializer + * can cope with the transaction using as many slots as channels + * in the stream, requires channels symmetry + */ + active_serializers = (channels + total_slots - 1) / total_slots; + if (active_serializers == 1) + active_slots = channels; + else + active_slots = total_slots; + for (i = 0; i < active_slots; i++) mask |= (1 << i); @@ -647,12 +663,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, - FSXMOD(active_slots), FSXMOD(0x1FF)); + FSXMOD(total_slots), FSXMOD(0x1FF)); mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, - FSRMOD(active_slots), FSRMOD(0x1FF)); + FSRMOD(total_slots), FSRMOD(0x1FF)); return 0; } @@ -766,7 +782,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) ret = mcasp_dit_hw_param(mcasp, params_rate(params)); else - ret = mcasp_i2s_hw_param(mcasp, substream->stream); + ret = mcasp_i2s_hw_param(mcasp, substream->stream, + channels); if (ret) return ret; -- GitLab From 3539cacff2031f6d47881c5f3a4932b0ad5ec224 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 9 Nov 2014 19:52:06 -0800 Subject: [PATCH 4135/9457] ASoC: rsnd: Add Volume Ramp support This patch adds Volume Ramp to Renesas sound driver. amixer set "DVC Out" 100% amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" amixer set "DVC Out Ramp" on aplay xxx.wav & amixer set "DVC Out" 80% // Volume Down amixer set "DVC Out" 100% // Volume Up Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/dvc.c | 87 ++++++++++++++++++++++++++++++++++++++-- sound/soc/sh/rcar/gen.c | 3 ++ sound/soc/sh/rcar/rsnd.h | 6 +++ 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 956b84eb3f20..e2c8473267b6 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -38,6 +38,9 @@ struct rsnd_dvc { struct clk *clk; struct rsnd_dvc_cfg_m volume; struct rsnd_dvc_cfg_m mute; + struct rsnd_dvc_cfg_s ren; /* Ramp Enable */ + struct rsnd_dvc_cfg_s rup; /* Ramp Rate Up */ + struct rsnd_dvc_cfg_s rdown; /* Ramp Rate Down */ }; #define rsnd_mod_to_dvc(_mod) \ @@ -49,9 +52,37 @@ struct rsnd_dvc { ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ i++) +static const char const *dvc_ramp_rate[] = { + "128 dB/1 step", /* 00000 */ + "64 dB/1 step", /* 00001 */ + "32 dB/1 step", /* 00010 */ + "16 dB/1 step", /* 00011 */ + "8 dB/1 step", /* 00100 */ + "4 dB/1 step", /* 00101 */ + "2 dB/1 step", /* 00110 */ + "1 dB/1 step", /* 00111 */ + "0.5 dB/1 step", /* 01000 */ + "0.25 dB/1 step", /* 01001 */ + "0.125 dB/1 step", /* 01010 */ + "0.125 dB/2 steps", /* 01011 */ + "0.125 dB/4 steps", /* 01100 */ + "0.125 dB/8 steps", /* 01101 */ + "0.125 dB/16 steps", /* 01110 */ + "0.125 dB/32 steps", /* 01111 */ + "0.125 dB/64 steps", /* 10000 */ + "0.125 dB/128 steps", /* 10001 */ + "0.125 dB/256 steps", /* 10010 */ + "0.125 dB/512 steps", /* 10011 */ + "0.125 dB/1024 steps", /* 10100 */ + "0.125 dB/2048 steps", /* 10101 */ + "0.125 dB/4096 steps", /* 10110 */ + "0.125 dB/8192 steps", /* 10111 */ +}; + static void rsnd_dvc_volume_update(struct rsnd_mod *mod) { struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u32 val[RSND_DVC_CHANNELS]; u32 dvucr = 0; u32 mute = 0; int i; @@ -62,10 +93,35 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) /* Disable DVC Register access */ rsnd_mod_write(mod, DVC_DVUER, 0); + /* Enable Ramp */ + if (dvc->ren.val) { + dvucr |= 0x10; + + /* Digital Volume Max */ + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.cfg.max; + + rsnd_mod_write(mod, DVC_VRCTR, 0xff); + rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 | + dvc->rdown.val); + /* + * FIXME !! + * use scale-downed Digital Volume + * as Volume Ramp + * 7F FFFF -> 3FF + */ + rsnd_mod_write(mod, DVC_VRDBR, + 0x3ff - (dvc->volume.val[0] >> 13)); + + } else { + for (i = 0; i < RSND_DVC_CHANNELS; i++) + val[i] = dvc->volume.val[i]; + } + /* Enable Digital Volume */ - dvucr = 0x100; - rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); - rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); + dvucr |= 0x100; + rsnd_mod_write(mod, DVC_VOL0R, val[0]); + rsnd_mod_write(mod, DVC_VOL1R, val[1]); /* Enable Mute */ if (mute) { @@ -324,6 +380,31 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, if (ret < 0) return ret; + /* Ramp */ + ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Switch" : "DVC In Ramp Switch", + &dvc->ren, 1); + if (ret < 0) + return ret; + + ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", + &dvc->rup, + dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + if (ret < 0) + return ret; + + ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", + &dvc->rdown, + dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + + if (ret < 0) + return ret; + return 0; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index a0fed661142c..87a6f2d62775 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -324,6 +324,9 @@ static int rsnd_gen2_probe(struct platform_device *pdev, RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100), RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100), + RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100), + RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100), + RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index d119adf97c9c..ed44ca8af057 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -91,6 +91,9 @@ enum rsnd_reg { RSND_REG_SHARE20, RSND_REG_SHARE21, RSND_REG_SHARE22, + RSND_REG_SHARE23, + RSND_REG_SHARE24, + RSND_REG_SHARE25, RSND_REG_MAX, }; @@ -129,6 +132,9 @@ enum rsnd_reg { #define RSND_REG_CMD_CTRL RSND_REG_SHARE20 #define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 #define RSND_REG_BUSIF_DALIGN RSND_REG_SHARE22 +#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 +#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 +#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 struct rsnd_of_data; struct rsnd_priv; -- GitLab From a64e6bb4db601b561f2d3a80dfc554ddfe73db74 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 5 Nov 2014 18:47:07 +0800 Subject: [PATCH 4136/9457] NVMe: __nvme_submit_admin_cmd() can be static drivers/block/nvme-core.c:865:5: sparse: symbol '__nvme_submit_admin_cmd' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index f7a87173e3f0..8393f91b2721 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -862,7 +862,7 @@ static int nvme_submit_admin_async_cmd(struct nvme_dev *dev, return nvme_submit_cmd(nvmeq, cmd); } -int __nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, +static int __nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, u32 *result, unsigned timeout) { int res; -- GitLab From 179e20b8df97e0c7541a1bae30cad53ecc7a5e86 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 10 Nov 2014 17:21:09 +0100 Subject: [PATCH 4137/9457] drbd: Minor cleanups . Update comments . drbd_set_{in,out_of}_sync(): Remove unused parameters . Move common code into adm_del_resource() . Redefine ERR_MINOR_EXISTS -> ERR_MINOR_OR_VOLUME_EXISTS Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_actlog.c | 3 +- drivers/block/drbd/drbd_int.h | 9 +++-- drivers/block/drbd/drbd_main.c | 6 ++-- drivers/block/drbd/drbd_nl.c | 60 ++++++++++++++------------------ include/linux/drbd.h | 2 +- 5 files changed, 35 insertions(+), 45 deletions(-) diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index a2dfa169237d..1318e3217cb0 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -827,8 +827,7 @@ static int update_sync_bits(struct drbd_device *device, * */ int __drbd_change_sync(struct drbd_device *device, sector_t sector, int size, - enum update_sync_bits_mode mode, - const char *file, const unsigned int line) + enum update_sync_bits_mode mode) { /* Is called from worker and receiver context _only_ */ unsigned long sbnr, ebnr, lbnr; diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 9b22f8f01b57..c14b718c2fab 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1662,14 +1662,13 @@ extern void drbd_advance_rs_marks(struct drbd_device *device, unsigned long stil enum update_sync_bits_mode { RECORD_RS_FAILED, SET_OUT_OF_SYNC, SET_IN_SYNC }; extern int __drbd_change_sync(struct drbd_device *device, sector_t sector, int size, - enum update_sync_bits_mode mode, - const char *file, const unsigned int line); + enum update_sync_bits_mode mode); #define drbd_set_in_sync(device, sector, size) \ - __drbd_change_sync(device, sector, size, SET_IN_SYNC, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, SET_IN_SYNC) #define drbd_set_out_of_sync(device, sector, size) \ - __drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, SET_OUT_OF_SYNC) #define drbd_rs_failed_io(device, sector, size) \ - __drbd_change_sync(device, sector, size, RECORD_RS_FAILED, __FILE__, __LINE__) + __drbd_change_sync(device, sector, size, RECORD_RS_FAILED) extern void drbd_al_shrink(struct drbd_device *device); extern int drbd_initialize_al(struct drbd_device *, void *); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 973c185c9cfe..cce25a5eb157 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2731,7 +2731,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig device = minor_to_device(minor); if (device) - return ERR_MINOR_EXISTS; + return ERR_MINOR_OR_VOLUME_EXISTS; /* GFP_KERNEL, we are outside of all write-out paths */ device = kzalloc(sizeof(struct drbd_device), GFP_KERNEL); @@ -2794,7 +2794,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id = idr_alloc(&drbd_devices, device, minor, minor + 1, GFP_KERNEL); if (id < 0) { if (id == -ENOSPC) { - err = ERR_MINOR_EXISTS; + err = ERR_MINOR_OR_VOLUME_EXISTS; drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); } goto out_no_minor_idr; @@ -2804,7 +2804,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id = idr_alloc(&resource->devices, device, vnr, vnr + 1, GFP_KERNEL); if (id < 0) { if (id == -ENOSPC) { - err = ERR_MINOR_EXISTS; + err = ERR_MINOR_OR_VOLUME_EXISTS; drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); } goto out_idr_remove_minor; diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 1cd47df44bda..c145619f1ccb 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2052,7 +2052,7 @@ check_net_options(struct drbd_connection *connection, struct net_conf *new_net_c rv = _check_net_options(connection, rcu_dereference(connection->net_conf), new_net_conf); rcu_read_unlock(); - /* connection->volumes protected by genl_lock() here */ + /* connection->peer_devices protected by genl_lock() here */ idr_for_each_entry(&connection->peer_devices, peer_device, i) { struct drbd_device *device = peer_device->device; if (!device->bitmap) { @@ -3483,7 +3483,7 @@ int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info) * that first_peer_device(device)->connection and device->vnr match the request. */ if (adm_ctx.device) { if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) - retcode = ERR_MINOR_EXISTS; + retcode = ERR_MINOR_OR_VOLUME_EXISTS; /* else: still NO_ERROR */ goto out; } @@ -3530,6 +3530,27 @@ int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info) return 0; } +static int adm_del_resource(struct drbd_resource *resource) +{ + struct drbd_connection *connection; + + for_each_connection(connection, resource) { + if (connection->cstate > C_STANDALONE) + return ERR_NET_CONFIGURED; + } + if (!idr_is_empty(&resource->devices)) + return ERR_RES_IN_USE; + + list_del_rcu(&resource->resources); + /* Make sure all threads have actually stopped: state handling only + * does drbd_thread_stop_nowait(). */ + list_for_each_entry(connection, &resource->connections, connections) + drbd_thread_stop(&connection->worker); + synchronize_rcu(); + drbd_free_resource(resource); + return NO_ERROR; +} + int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) { struct drbd_config_context adm_ctx; @@ -3575,14 +3596,6 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } - /* If we reach this, all volumes (of this connection) are Secondary, - * Disconnected, Diskless, aka Unconfigured. Make sure all threads have - * actually stopped, state handling only does drbd_thread_stop_nowait(). */ - for_each_connection(connection, resource) - drbd_thread_stop(&connection->worker); - - /* Now, nothing can fail anymore */ - /* delete volumes */ idr_for_each_entry(&resource->devices, device, i) { retcode = adm_del_minor(device); @@ -3593,10 +3606,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info) } } - list_del_rcu(&resource->resources); - synchronize_rcu(); - drbd_free_resource(resource); - retcode = NO_ERROR; + retcode = adm_del_resource(resource); out: mutex_unlock(&resource->adm_mutex); finish: @@ -3608,7 +3618,6 @@ int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) { struct drbd_config_context adm_ctx; struct drbd_resource *resource; - struct drbd_connection *connection; enum drbd_ret_code retcode; retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_RESOURCE); @@ -3616,27 +3625,10 @@ int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info) return retcode; if (retcode != NO_ERROR) goto finish; - resource = adm_ctx.resource; - mutex_lock(&resource->adm_mutex); - for_each_connection(connection, resource) { - if (connection->cstate > C_STANDALONE) { - retcode = ERR_NET_CONFIGURED; - goto out; - } - } - if (!idr_is_empty(&resource->devices)) { - retcode = ERR_RES_IN_USE; - goto out; - } - list_del_rcu(&resource->resources); - for_each_connection(connection, resource) - drbd_thread_stop(&connection->worker); - synchronize_rcu(); - drbd_free_resource(resource); - retcode = NO_ERROR; -out: + mutex_lock(&resource->adm_mutex); + retcode = adm_del_resource(resource); mutex_unlock(&resource->adm_mutex); finish: drbd_adm_finish(&adm_ctx, info, retcode); diff --git a/include/linux/drbd.h b/include/linux/drbd.h index debb70d40547..8723f2a99e15 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -172,7 +172,7 @@ enum drbd_ret_code { ERR_RES_NOT_KNOWN = 158, ERR_RES_IN_USE = 159, ERR_MINOR_CONFIGURED = 160, - ERR_MINOR_EXISTS = 161, + ERR_MINOR_OR_VOLUME_EXISTS = 161, ERR_INVALID_REQUEST = 162, ERR_NEED_APV_100 = 163, ERR_NEED_ALLOW_TWO_PRI = 164, -- GitLab From f221f4bcc5f40e2967e4596ef167bdbc987c8e9d Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 10 Nov 2014 17:21:10 +0100 Subject: [PATCH 4138/9457] drbd: Only use drbd_msg_put_info() in drbd_nl.c Avoid generic netlink calls in other parts of the code base. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 1 - drivers/block/drbd/drbd_main.c | 17 +++-------------- drivers/block/drbd/drbd_nl.c | 2 +- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c14b718c2fab..d2a7589c4bca 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1454,7 +1454,6 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t); /* drbd_nl.c */ -extern int drbd_msg_put_info(struct sk_buff *skb, const char *info); extern void drbd_suspend_io(struct drbd_device *device); extern void drbd_resume_io(struct drbd_device *device); extern char *ppsize(char *buf, unsigned long long size); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index cce25a5eb157..1fc83427199c 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2532,10 +2532,6 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op if (!zalloc_cpumask_var(&new_cpu_mask, GFP_KERNEL)) return -ENOMEM; - /* - retcode = ERR_NOMEM; - drbd_msg_put_info("unable to allocate cpumask"); - */ /* silently ignore cpu mask on UP kernel */ if (nr_cpu_ids > 1 && res_opts->cpu_mask[0] != 0) { @@ -2793,20 +2789,16 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id = idr_alloc(&drbd_devices, device, minor, minor + 1, GFP_KERNEL); if (id < 0) { - if (id == -ENOSPC) { + if (id == -ENOSPC) err = ERR_MINOR_OR_VOLUME_EXISTS; - drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); - } goto out_no_minor_idr; } kref_get(&device->kref); id = idr_alloc(&resource->devices, device, vnr, vnr + 1, GFP_KERNEL); if (id < 0) { - if (id == -ENOSPC) { + if (id == -ENOSPC) err = ERR_MINOR_OR_VOLUME_EXISTS; - drbd_msg_put_info(adm_ctx->reply_skb, "requested minor exists already"); - } goto out_idr_remove_minor; } kref_get(&device->kref); @@ -2825,10 +2817,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL); if (id < 0) { - if (id == -ENOSPC) { + if (id == -ENOSPC) err = ERR_INVALID_REQUEST; - drbd_msg_put_info(adm_ctx->reply_skb, "requested volume exists already"); - } goto out_idr_remove_from_resource; } kref_get(&connection->kref); @@ -2836,7 +2826,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig if (init_submitter(device)) { err = ERR_NOMEM; - drbd_msg_put_info(adm_ctx->reply_skb, "unable to create submit workqueue"); goto out_idr_remove_vol; } diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index c145619f1ccb..4782d074c8cd 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -92,7 +92,7 @@ static void drbd_adm_send_reply(struct sk_buff *skb, struct genl_info *info) /* Used on a fresh "drbd_adm_prepare"d reply_skb, this cannot fail: The only * reason it could fail was no space in skb, and there are 4k available. */ -int drbd_msg_put_info(struct sk_buff *skb, const char *info) +static int drbd_msg_put_info(struct sk_buff *skb, const char *info) { struct nlattr *nla; int err = -EMSGSIZE; -- GitLab From a88215312c5ed74697973f6c9f0fce718bcf18ad Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 10 Nov 2014 17:21:11 +0100 Subject: [PATCH 4139/9457] drbd: fix race between role change and handshake Symptoms: If DRBD was "cleanly shut down" (all in sync, both Secondary before disconnect, identical data generation uuids), and then one side was promoted *during* the next connection handshake, the role change could confuse the handshake. The Primary would get stuck in WFBitmapS, the Secondary would log unexpected cstate (Connected) in receive_bitmap and get stuck in WFBitmapT. Fix: The test in is_valid_soft_transition wrong. It works because the not allowed actions (promote/attach) do not touch the cstate. The previous condition failed to demand a cstate change in one clause. In order to avoid deadlocks give up the state_mutex while waiting for the transient state to go away. Conflicts: drbd/drbd_state.c drbd/drbd_state.h drbd/drbd_wrappers.h Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_nl.c | 2 +- drivers/block/drbd/drbd_state.c | 41 +++++++++++++++++++++++++++------ drivers/block/drbd/drbd_state.h | 5 ++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 4782d074c8cd..74df8cfad414 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -588,7 +588,7 @@ drbd_set_role(struct drbd_device *const device, enum drbd_role new_role, int for val.i = 0; val.role = new_role; while (try++ < max_tries) { - rv = _drbd_request_state(device, mask, val, CS_WAIT_COMPLETE); + rv = _drbd_request_state_holding_state_mutex(device, mask, val, CS_WAIT_COMPLETE); /* in case we first succeeded to outdate, * but now suddenly could establish a connection */ diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 84b11f887d73..4529d9282cef 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -215,6 +215,18 @@ static bool no_peer_wf_report_params(struct drbd_connection *connection) return rv; } +static void wake_up_all_devices(struct drbd_connection *connection) +{ + struct drbd_peer_device *peer_device; + int vnr; + + rcu_read_lock(); + idr_for_each_entry(&connection->peer_devices, peer_device, vnr) + wake_up(&peer_device->device->state_wait); + rcu_read_unlock(); + +} + /** * cl_wide_st_chg() - true if the state change is a cluster wide one @@ -410,6 +422,22 @@ _drbd_request_state(struct drbd_device *device, union drbd_state mask, return rv; } +enum drbd_state_rv +_drbd_request_state_holding_state_mutex(struct drbd_device *device, union drbd_state mask, + union drbd_state val, enum chg_state_flags f) +{ + enum drbd_state_rv rv; + + BUG_ON(f & CS_SERIALIZE); + + wait_event_cmd(device->state_wait, + (rv = drbd_req_state(device, mask, val, f)) != SS_IN_TRANSIENT_STATE, + mutex_unlock(device->state_mutex), + mutex_lock(device->state_mutex)); + + return rv; +} + static void print_st(struct drbd_device *device, const char *name, union drbd_state ns) { drbd_err(device, " %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c%c%c }\n", @@ -629,14 +657,11 @@ is_valid_soft_transition(union drbd_state os, union drbd_state ns, struct drbd_c if (ns.conn == C_DISCONNECTING && os.conn == C_UNCONNECTED) rv = SS_IN_TRANSIENT_STATE; - /* if (ns.conn == os.conn && ns.conn == C_WF_REPORT_PARAMS) - rv = SS_IN_TRANSIENT_STATE; */ - /* While establishing a connection only allow cstate to change. - Delay/refuse role changes, detach attach etc... */ + Delay/refuse role changes, detach attach etc... (they do not touch cstate) */ if (test_bit(STATE_SENT, &connection->flags) && - !(os.conn == C_WF_REPORT_PARAMS || - (ns.conn == C_WF_REPORT_PARAMS && os.conn == C_WF_CONNECTION))) + !((ns.conn == C_WF_REPORT_PARAMS && os.conn == C_WF_CONNECTION) || + (ns.conn >= C_CONNECTED && os.conn == C_WF_REPORT_PARAMS))) rv = SS_IN_TRANSIENT_STATE; if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && os.conn < C_CONNECTED) @@ -1032,8 +1057,10 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, /* Wake up role changes, that were delayed because of connection establishing */ if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS && - no_peer_wf_report_params(connection)) + no_peer_wf_report_params(connection)) { clear_bit(STATE_SENT, &connection->flags); + wake_up_all_devices(connection); + } wake_up(&device->misc_wait); wake_up(&device->state_wait); diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h index cc41605ba21c..7f53c40823cd 100644 --- a/drivers/block/drbd/drbd_state.h +++ b/drivers/block/drbd/drbd_state.h @@ -117,6 +117,11 @@ extern enum drbd_state_rv _drbd_request_state(struct drbd_device *, union drbd_state, union drbd_state, enum chg_state_flags); + +extern enum drbd_state_rv +_drbd_request_state_holding_state_mutex(struct drbd_device *, union drbd_state, + union drbd_state, enum chg_state_flags); + extern enum drbd_state_rv __drbd_set_state(struct drbd_device *, union drbd_state, enum chg_state_flags, struct completion *done); -- GitLab From ff8bd88b73fad369a12465dfa52ad5c0bf088ced Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 10 Nov 2014 17:21:12 +0100 Subject: [PATCH 4140/9457] drbd: fix resync throttling initialization If for some reason DRBD resync was the only activity on a backend device, drbd_rs_c_min_rate_throttle() would mistakenly decide that it is still initialization time, and keep throttling the resync. This patch explicitly initializes ->rs_last_events to the current backend event counters, and drops the rs_last_events == 0 from the throttle condition. Reported-by: Mikhail Sugakov Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_state.c | 1 - drivers/block/drbd/drbd_worker.c | 5 ++++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6960fb064731..d169b4a79267 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2482,7 +2482,7 @@ bool drbd_rs_c_min_rate_throttle(struct drbd_device *device) atomic_read(&device->rs_sect_ev); if (atomic_read(&device->ap_actlog_cnt) - || !device->rs_last_events || curr_events - device->rs_last_events > 64) { + || curr_events - device->rs_last_events > 64) { unsigned long rs_left; int i; diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 4529d9282cef..2d7dd269b6a8 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -1099,7 +1099,6 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns, set_ov_position(device, ns.conn); device->rs_start = now; - device->rs_last_events = 0; device->rs_last_sect_ev = 0; device->ov_last_oos_size = 0; device->ov_last_oos_start = 0; diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index d2d1f97511bd..d0fae55d871d 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -1592,11 +1592,15 @@ void drbd_resync_after_changed(struct drbd_device *device) void drbd_rs_controller_reset(struct drbd_device *device) { + struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk; struct fifo_buffer *plan; atomic_set(&device->rs_sect_in, 0); atomic_set(&device->rs_sect_ev, 0); device->rs_in_flight = 0; + device->rs_last_events = + (int)part_stat_read(&disk->part0, sectors[0]) + + (int)part_stat_read(&disk->part0, sectors[1]); /* Updating the RCU protected object in place is necessary since this function gets called from atomic context. @@ -1743,7 +1747,6 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side) device->rs_failed = 0; device->rs_paused = 0; device->rs_same_csum = 0; - device->rs_last_events = 0; device->rs_last_sect_ev = 0; device->rs_total = tw; device->rs_start = now; -- GitLab From 3b9d35d744bb5139f9fed57f38c019bb8c7d351c Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 10 Nov 2014 17:21:13 +0100 Subject: [PATCH 4141/9457] drbd: merge_bvec_fn: properly remap bvm->bi_bdev This was not noticed for many years. Affects operation if md raid is used a backing device for DRBD. CC: stable@kernel.org # v3.2+ Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 5a01c53dddeb..90319b14d5ee 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1545,6 +1545,7 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct struct request_queue * const b = device->ldev->backing_bdev->bd_disk->queue; if (b->merge_bvec_fn) { + bvm->bi_bdev = device->ldev->backing_bdev; backing_limit = b->merge_bvec_fn(b, bvm, bvec); limit = min(limit, backing_limit); } -- GitLab From 9581f97a687724ea41cf2e145dda4751161198c1 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 10 Nov 2014 17:21:14 +0100 Subject: [PATCH 4142/9457] drbd: Fix state change in case of connection timeout A connection timeout affects all volumes of a resource! Under the following conditions: A resource with multiple volumes AND ko-count >=1 AND a write request triggers the timeout (ko-count * timeout) DRBD's internal state gets confused. That in turn may lead to very miss leading follow up failures. E.g. "BUG: scheduling while atomic" CC: stable@kernel.org # v3.17 Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 90319b14d5ee..3b797cd5a407 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1629,7 +1629,7 @@ void request_timer_fn(unsigned long data) time_after(now, req_peer->pre_send_jif + ent) && !time_in_range(now, connection->last_reconnect_jif, connection->last_reconnect_jif + ent)) { drbd_warn(device, "Remote failed to finish a request within ko-count * timeout\n"); - _drbd_set_state(_NS(device, conn, C_TIMEOUT), CS_VERBOSE | CS_HARD, NULL); + _conn_request_state(connection, NS(conn, C_TIMEOUT), CS_VERBOSE | CS_HARD); } if (dt && oldest_submit_jif != now && time_after(now, oldest_submit_jif + dt) && -- GitLab From e805b983d3fc852b80e30327e42c8c5f0c55c62c Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 10 Nov 2014 17:21:15 +0100 Subject: [PATCH 4143/9457] drbd: Remove an useless copy of kernel_setsockopt() Old backward-compat cruft Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index d2a7589c4bca..b905e9888b88 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1557,52 +1557,31 @@ extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled); extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed); extern int drbd_connected(struct drbd_peer_device *); -/* Yes, there is kernel_setsockopt, but only since 2.6.18. - * So we have our own copy of it here. */ -static inline int drbd_setsockopt(struct socket *sock, int level, int optname, - char *optval, int optlen) -{ - mm_segment_t oldfs = get_fs(); - char __user *uoptval; - int err; - - uoptval = (char __user __force *)optval; - - set_fs(KERNEL_DS); - if (level == SOL_SOCKET) - err = sock_setsockopt(sock, level, optname, uoptval, optlen); - else - err = sock->ops->setsockopt(sock, level, optname, uoptval, - optlen); - set_fs(oldfs); - return err; -} - static inline void drbd_tcp_cork(struct socket *sock) { int val = 1; - (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, + (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK, (char*)&val, sizeof(val)); } static inline void drbd_tcp_uncork(struct socket *sock) { int val = 0; - (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, + (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK, (char*)&val, sizeof(val)); } static inline void drbd_tcp_nodelay(struct socket *sock) { int val = 1; - (void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY, + (void) kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char*)&val, sizeof(val)); } static inline void drbd_tcp_quickack(struct socket *sock) { int val = 2; - (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, + (void) kernel_setsockopt(sock, SOL_TCP, TCP_QUICKACK, (char*)&val, sizeof(val)); } -- GitLab From be955b2984822e2a66176bccb3e0dbaf9cd569b6 Mon Sep 17 00:00:00 2001 From: Dave Taht Date: Thu, 6 Nov 2014 08:10:14 -0800 Subject: [PATCH 4144/9457] rtnetlink: add babel protocol recognition Babel uses rt_proto 42. Add to userspace visible header file. Signed-off-by: Dave Taht Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/uapi/linux/rtnetlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index eb0f1a554d7b..9c9b8b4480cd 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -235,6 +235,7 @@ enum { #define RTPROT_NTK 15 /* Netsukuku */ #define RTPROT_DHCP 16 /* DHCP client */ #define RTPROT_MROUTED 17 /* Multicast daemon */ +#define RTPROT_BABEL 42 /* Babel daemon */ /* rtm_scope -- GitLab From 3b47d30396bae4f0bd1ff0dbcd7c4f5077e7df4e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 6 Nov 2014 21:09:44 -0800 Subject: [PATCH 4145/9457] net: gro: add a per device gro flush timer Tuning coalescing parameters on NIC can be really hard. Servers can handle both bulk and RPC like traffic, with conflicting goals : bulk flows want as big GRO packets as possible, RPC want minimal latencies. To reach big GRO packets on 10Gbe NIC, one can use : ethtool -C eth0 rx-usecs 4 rx-frames 44 But this penalizes rpc sessions, with an increase of latencies, up to 50% in some cases, as NICs generally do not force an interrupt when a packet with TCP Push flag is received. Some NICs do not have an absolute timer, only a timer rearmed for every incoming packet. This patch uses a different strategy : Let GRO stack decides what do do, based on traffic pattern. Packets with Push flag wont be delayed. Packets without Push flag might be held in GRO engine, if we keep receiving data. This new mechanism is off by default, and shall be enabled by setting /sys/class/net/ethX/gro_flush_timeout to a value in nanosecond. To fully enable this mechanism, drivers should use napi_complete_done() instead of napi_complete(). Tested: Ran 200 netperf TCP_STREAM from A to B (10Gbe mlx4 link, 8 RX queues) Without this feature, we send back about 305,000 ACK per second. GRO aggregation ratio is low (811/305 = 2.65 segments per GRO packet) Setting a timer of 2000 nsec is enough to increase GRO packet sizes and reduce number of ACK packets. (811/19.2 = 42) Receiver performs less calls to upper stacks, less wakes up. This also reduces cpu usage on the sender, as it receives less ACK packets. Note that reducing number of wakes up increases cpu efficiency, but can decrease QPS, as applications wont have the chance to warmup cpu caches doing a partial read of RPC requests/answers if they fit in one skb. B:~# sar -n DEV 1 10 | grep eth0 | tail -1 Average: eth0 811269.80 305732.30 1199462.57 19705.72 0.00 0.00 0.50 B:~# echo 2000 >/sys/class/net/eth0/gro_flush_timeout B:~# sar -n DEV 1 10 | grep eth0 | tail -1 Average: eth0 811577.30 19230.80 1199916.51 1239.80 0.00 0.00 0.50 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 20 ++++++++--------- net/core/dev.c | 45 +++++++++++++++++++++++++++++++++++---- net/core/net-sysfs.c | 18 ++++++++++++++++ 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 90ac95900a11..888d5513fa4a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -314,6 +314,7 @@ struct napi_struct { struct net_device *dev; struct sk_buff *gro_list; struct sk_buff *skb; + struct hrtimer timer; struct list_head dev_list; struct hlist_node napi_hash_node; unsigned int napi_id; @@ -443,14 +444,19 @@ static inline bool napi_reschedule(struct napi_struct *napi) return false; } +void __napi_complete(struct napi_struct *n); +void napi_complete_done(struct napi_struct *n, int work_done); /** * napi_complete - NAPI processing complete * @n: napi context * * Mark NAPI processing as complete. + * Consider using napi_complete_done() instead. */ -void __napi_complete(struct napi_struct *n); -void napi_complete(struct napi_struct *n); +static inline void napi_complete(struct napi_struct *n) +{ + return napi_complete_done(n, 0); +} /** * napi_by_id - lookup a NAPI by napi_id @@ -485,14 +491,7 @@ void napi_hash_del(struct napi_struct *napi); * Stop NAPI from being scheduled on this context. * Waits till any outstanding processing completes. */ -static inline void napi_disable(struct napi_struct *n) -{ - might_sleep(); - set_bit(NAPI_STATE_DISABLE, &n->state); - while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) - msleep(1); - clear_bit(NAPI_STATE_DISABLE, &n->state); -} +void napi_disable(struct napi_struct *n); /** * napi_enable - enable NAPI scheduling @@ -1603,6 +1602,7 @@ struct net_device { #endif + unsigned long gro_flush_timeout; rx_handler_func_t __rcu *rx_handler; void __rcu *rx_handler_data; diff --git a/net/core/dev.c b/net/core/dev.c index 70bb609c283d..bb09b0364619 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -134,6 +134,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -4412,7 +4413,6 @@ EXPORT_SYMBOL(__napi_schedule_irqoff); void __napi_complete(struct napi_struct *n) { BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); - BUG_ON(n->gro_list); list_del_init(&n->poll_list); smp_mb__before_atomic(); @@ -4420,7 +4420,7 @@ void __napi_complete(struct napi_struct *n) } EXPORT_SYMBOL(__napi_complete); -void napi_complete(struct napi_struct *n) +void napi_complete_done(struct napi_struct *n, int work_done) { unsigned long flags; @@ -4431,8 +4431,18 @@ void napi_complete(struct napi_struct *n) if (unlikely(test_bit(NAPI_STATE_NPSVC, &n->state))) return; - napi_gro_flush(n, false); + if (n->gro_list) { + unsigned long timeout = 0; + if (work_done) + timeout = n->dev->gro_flush_timeout; + + if (timeout) + hrtimer_start(&n->timer, ns_to_ktime(timeout), + HRTIMER_MODE_REL_PINNED); + else + napi_gro_flush(n, false); + } if (likely(list_empty(&n->poll_list))) { WARN_ON_ONCE(!test_and_clear_bit(NAPI_STATE_SCHED, &n->state)); } else { @@ -4442,7 +4452,7 @@ void napi_complete(struct napi_struct *n) local_irq_restore(flags); } } -EXPORT_SYMBOL(napi_complete); +EXPORT_SYMBOL(napi_complete_done); /* must be called under rcu_read_lock(), as we dont take a reference */ struct napi_struct *napi_by_id(unsigned int napi_id) @@ -4496,10 +4506,23 @@ void napi_hash_del(struct napi_struct *napi) } EXPORT_SYMBOL_GPL(napi_hash_del); +static enum hrtimer_restart napi_watchdog(struct hrtimer *timer) +{ + struct napi_struct *napi; + + napi = container_of(timer, struct napi_struct, timer); + if (napi->gro_list) + napi_schedule(napi); + + return HRTIMER_NORESTART; +} + void netif_napi_add(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight) { INIT_LIST_HEAD(&napi->poll_list); + hrtimer_init(&napi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); + napi->timer.function = napi_watchdog; napi->gro_count = 0; napi->gro_list = NULL; napi->skb = NULL; @@ -4518,6 +4541,20 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, } EXPORT_SYMBOL(netif_napi_add); +void napi_disable(struct napi_struct *n) +{ + might_sleep(); + set_bit(NAPI_STATE_DISABLE, &n->state); + + while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) + msleep(1); + + hrtimer_cancel(&n->timer); + + clear_bit(NAPI_STATE_DISABLE, &n->state); +} +EXPORT_SYMBOL(napi_disable); + void netif_napi_del(struct napi_struct *napi) { list_del_init(&napi->dev_list); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 9dd06699b09c..1a24602cd54e 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -325,6 +325,23 @@ static ssize_t tx_queue_len_store(struct device *dev, } NETDEVICE_SHOW_RW(tx_queue_len, fmt_ulong); +static int change_gro_flush_timeout(struct net_device *dev, unsigned long val) +{ + dev->gro_flush_timeout = val; + return 0; +} + +static ssize_t gro_flush_timeout_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + return netdev_store(dev, attr, buf, len, change_gro_flush_timeout); +} +NETDEVICE_SHOW_RW(gro_flush_timeout, fmt_ulong); + static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -422,6 +439,7 @@ static struct attribute *net_class_attrs[] = { &dev_attr_mtu.attr, &dev_attr_flags.attr, &dev_attr_tx_queue_len.attr, + &dev_attr_gro_flush_timeout.attr, &dev_attr_phys_port_id.attr, NULL, }; -- GitLab From 1a2881728211f0915c0fa1364770b9c73a67a073 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 6 Nov 2014 21:10:11 -0800 Subject: [PATCH 4146/9457] mlx4: use napi_complete_done() To enable gro_flush_timeout, a driver has to use napi_complete_done() instead of napi_complete(). Tested: Ran 200 netperf TCP_STREAM from A to B (10Gbe mlx4 link, 8 RX queues) Without this feature, we send back about 305,000 ACK per second. GRO aggregation ratio is low (811/305 = 2.65 segments per GRO packet) Setting a timer of 2000 nsec is enough to increase GRO packet sizes and reduce number of ACK packets. (811/19.2 = 42) Receiver performs less calls to upper stacks, less wakes up. This also reduces cpu usage on the sender, as it receives less ACK packets. Note that reducing number of wakes up increases cpu efficiency, but can decrease QPS, as applications wont have the chance to warmup cpu caches doing a partial read of RPC requests/answers if they fit in one skb. B:~# sar -n DEV 1 10 | grep eth0 | tail -1 Average: eth0 811269.80 305732.30 1199462.57 19705.72 0.00 0.00 0.50 B:~# echo 2000 >/sys/class/net/eth0/gro_flush_timeout B:~# sar -n DEV 1 10 | grep eth0 | tail -1 Average: eth0 811577.30 19230.80 1199916.51 1239.80 0.00 0.00 0.50 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b173a0cf44e0..46ee78326f1f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -915,15 +915,12 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget) * probably affinity changed. need to stop this NAPI * poll, and restart it on the right CPU */ - napi_complete(napi); - mlx4_en_arm_cq(priv, cq); - return 0; + done = 0; } - } else { - /* Done for now */ - napi_complete(napi); - mlx4_en_arm_cq(priv, cq); } + /* Done for now */ + napi_complete_done(napi, done); + mlx4_en_arm_cq(priv, cq); return done; } -- GitLab From fd88b31a1d49f08911ed291e46e5bc6e8afabdfa Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 7 Nov 2014 09:35:23 +0530 Subject: [PATCH 4147/9457] cxgb4: Add cxgb4_debugfs.c, move all debugfs code to new file Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/Makefile | 1 + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 158 ++++++++++++++++++ .../ethernet/chelsio/cxgb4/cxgb4_debugfs.h | 52 ++++++ .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 97 +---------- 5 files changed, 217 insertions(+), 92 deletions(-) create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile index 1df65c915b99..b85280775997 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/Makefile +++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_CHELSIO_T4) += cxgb4.o cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o +cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 3c481b260745..dad1ea930e05 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1085,4 +1085,5 @@ void t4_db_dropped(struct adapter *adapter); int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, u32 addr, u32 val); void t4_sge_decode_idma_state(struct adapter *adapter, int state); +void t4_free_mem(void *addr); #endif /* __CXGB4_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c new file mode 100644 index 000000000000..e86b5fe334e6 --- /dev/null +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -0,0 +1,158 @@ +/* + * This file is part of the Chelsio T4 Ethernet driver for Linux. + * + * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include "cxgb4.h" +#include "t4_regs.h" +#include "t4fw_api.h" +#include "cxgb4_debugfs.h" +#include "l2t.h" + +static ssize_t mem_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + loff_t pos = *ppos; + loff_t avail = file_inode(file)->i_size; + unsigned int mem = (uintptr_t)file->private_data & 3; + struct adapter *adap = file->private_data - mem; + __be32 *data; + int ret; + + if (pos < 0) + return -EINVAL; + if (pos >= avail) + return 0; + if (count > avail - pos) + count = avail - pos; + + data = t4_alloc_mem(count); + if (!data) + return -ENOMEM; + + spin_lock(&adap->win0_lock); + ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ); + spin_unlock(&adap->win0_lock); + if (ret) { + t4_free_mem(data); + return ret; + } + ret = copy_to_user(buf, data, count); + + t4_free_mem(data); + if (ret) + return -EFAULT; + + *ppos = pos + count; + return count; +} + +static const struct file_operations mem_debugfs_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = mem_read, + .llseek = default_llseek, +}; + +static void add_debugfs_mem(struct adapter *adap, const char *name, + unsigned int idx, unsigned int size_mb) +{ + struct dentry *de; + + de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, + (void *)adap + idx, &mem_debugfs_fops); + if (de && de->d_inode) + de->d_inode->i_size = size_mb << 20; +} + +/* Add an array of Debug FS files. + */ +void add_debugfs_files(struct adapter *adap, + struct t4_debugfs_entry *files, + unsigned int nfiles) +{ + int i; + + /* debugfs support is best effort */ + for (i = 0; i < nfiles; i++) + debugfs_create_file(files[i].name, files[i].mode, + adap->debugfs_root, + (void *)adap + files[i].data, + files[i].ops); +} + +int t4_setup_debugfs(struct adapter *adap) +{ + int i; + u32 size; + + static struct t4_debugfs_entry t4_debugfs_files[] = { + { "l2t", &t4_l2t_fops, S_IRUSR, 0}, + }; + + add_debugfs_files(adap, + t4_debugfs_files, + ARRAY_SIZE(t4_debugfs_files)); + + i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); + if (i & EDRAM0_ENABLE) { + size = t4_read_reg(adap, MA_EDRAM0_BAR); + add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM_SIZE_GET(size)); + } + if (i & EDRAM1_ENABLE) { + size = t4_read_reg(adap, MA_EDRAM1_BAR); + add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); + } + if (is_t4(adap->params.chip)) { + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + if (i & EXT_MEM_ENABLE) + add_debugfs_mem(adap, "mc", MEM_MC, + EXT_MEM_SIZE_GET(size)); + } else { + if (i & EXT_MEM_ENABLE) { + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + add_debugfs_mem(adap, "mc0", MEM_MC0, + EXT_MEM_SIZE_GET(size)); + } + if (i & EXT_MEM1_ENABLE) { + size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR); + add_debugfs_mem(adap, "mc1", MEM_MC1, + EXT_MEM_SIZE_GET(size)); + } + } + return 0; +} diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h new file mode 100644 index 000000000000..a3d8867efd3d --- /dev/null +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h @@ -0,0 +1,52 @@ +/* + * This file is part of the Chelsio T4 Ethernet driver for Linux. + * + * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __CXGB4_DEBUGFS_H +#define __CXGB4_DEBUGFS_H + +#include + +struct t4_debugfs_entry { + const char *name; + const struct file_operations *ops; + mode_t mode; + unsigned char data; +}; + +int t4_setup_debugfs(struct adapter *adap); +void add_debugfs_files(struct adapter *adap, + struct t4_debugfs_entry *files, + unsigned int nfiles); + +#endif diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 8520d5529df8..172f68b6d592 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -68,6 +68,7 @@ #include "t4_msg.h" #include "t4fw_api.h" #include "cxgb4_dcb.h" +#include "cxgb4_debugfs.h" #include "l2t.h" #include <../drivers/net/bonding/bonding.h> @@ -1287,7 +1288,7 @@ void *t4_alloc_mem(size_t size) /* * Free memory allocated through alloc_mem(). */ -static void t4_free_mem(void *addr) +void t4_free_mem(void *addr) { if (is_vmalloc_addr(addr)) vfree(addr); @@ -3127,102 +3128,14 @@ static const struct ethtool_ops cxgb_ethtool_ops = { .flash_device = set_flash, }; -/* - * debugfs support - */ -static ssize_t mem_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - loff_t pos = *ppos; - loff_t avail = file_inode(file)->i_size; - unsigned int mem = (uintptr_t)file->private_data & 3; - struct adapter *adap = file->private_data - mem; - __be32 *data; - int ret; - - if (pos < 0) - return -EINVAL; - if (pos >= avail) - return 0; - if (count > avail - pos) - count = avail - pos; - - data = t4_alloc_mem(count); - if (!data) - return -ENOMEM; - - spin_lock(&adap->win0_lock); - ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ); - spin_unlock(&adap->win0_lock); - if (ret) { - t4_free_mem(data); - return ret; - } - ret = copy_to_user(buf, data, count); - - t4_free_mem(data); - if (ret) - return -EFAULT; - - *ppos = pos + count; - return count; -} - -static const struct file_operations mem_debugfs_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mem_read, - .llseek = default_llseek, -}; - -static void add_debugfs_mem(struct adapter *adap, const char *name, - unsigned int idx, unsigned int size_mb) -{ - struct dentry *de; - - de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, - (void *)adap + idx, &mem_debugfs_fops); - if (de && de->d_inode) - de->d_inode->i_size = size_mb << 20; -} - static int setup_debugfs(struct adapter *adap) { - int i; - u32 size; - if (IS_ERR_OR_NULL(adap->debugfs_root)) return -1; - i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); - if (i & EDRAM0_ENABLE) { - size = t4_read_reg(adap, MA_EDRAM0_BAR); - add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM_SIZE_GET(size)); - } - if (i & EDRAM1_ENABLE) { - size = t4_read_reg(adap, MA_EDRAM1_BAR); - add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); - } - if (is_t4(adap->params.chip)) { - size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); - if (i & EXT_MEM_ENABLE) - add_debugfs_mem(adap, "mc", MEM_MC, - EXT_MEM_SIZE_GET(size)); - } else { - if (i & EXT_MEM_ENABLE) { - size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); - add_debugfs_mem(adap, "mc0", MEM_MC0, - EXT_MEM_SIZE_GET(size)); - } - if (i & EXT_MEM1_ENABLE) { - size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR); - add_debugfs_mem(adap, "mc1", MEM_MC1, - EXT_MEM_SIZE_GET(size)); - } - } - if (adap->l2t) - debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap, - &t4_l2t_fops); +#ifdef CONFIG_DEBUG_FS + t4_setup_debugfs(adap); +#endif return 0; } -- GitLab From 6559a7e8296002b4379e5f2c26a2a3a339d5e60a Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 7 Nov 2014 09:35:24 +0530 Subject: [PATCH 4148/9457] cxgb4: Cleanup macros so they follow the same style and look consistent Various patches have ended up changing the style of the symbolic macros/register to different style. As a result, the current kernel.org files are a mix of different macro styles. Since this macro/register defines is used by different drivers a few patch series have ended up adding duplicate macro/register define entries with different styles. This makes these register define/macro files a complete mess and we want to make them clean and consistent. This patch cleans up a part of it. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 32 ++++----- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 16 +++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 6 +- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 72 ++++++++++++++----- drivers/scsi/csiostor/csio_hw_t4.c | 15 ++-- drivers/scsi/csiostor/csio_hw_t5.c | 21 +++--- drivers/scsi/csiostor/csio_init.c | 6 +- 7 files changed, 106 insertions(+), 62 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index e86b5fe334e6..c98a350d857e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -128,30 +128,30 @@ int t4_setup_debugfs(struct adapter *adap) t4_debugfs_files, ARRAY_SIZE(t4_debugfs_files)); - i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); - if (i & EDRAM0_ENABLE) { - size = t4_read_reg(adap, MA_EDRAM0_BAR); - add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM_SIZE_GET(size)); + i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); + if (i & EDRAM0_ENABLE_F) { + size = t4_read_reg(adap, MA_EDRAM0_BAR_A); + add_debugfs_mem(adap, "edc0", MEM_EDC0, EDRAM0_SIZE_G(size)); } - if (i & EDRAM1_ENABLE) { - size = t4_read_reg(adap, MA_EDRAM1_BAR); - add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); + if (i & EDRAM1_ENABLE_F) { + size = t4_read_reg(adap, MA_EDRAM1_BAR_A); + add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM1_SIZE_G(size)); } if (is_t4(adap->params.chip)) { - size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); - if (i & EXT_MEM_ENABLE) + size = t4_read_reg(adap, MA_EXT_MEMORY_BAR_A); + if (i & EXT_MEM_ENABLE_F) add_debugfs_mem(adap, "mc", MEM_MC, - EXT_MEM_SIZE_GET(size)); + EXT_MEM_SIZE_G(size)); } else { - if (i & EXT_MEM_ENABLE) { - size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); + if (i & EXT_MEM0_ENABLE_F) { + size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); add_debugfs_mem(adap, "mc0", MEM_MC0, - EXT_MEM_SIZE_GET(size)); + EXT_MEM0_SIZE_G(size)); } - if (i & EXT_MEM1_ENABLE) { - size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR); + if (i & EXT_MEM1_ENABLE_F) { + size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); add_debugfs_mem(adap, "mc1", MEM_MC1, - EXT_MEM_SIZE_GET(size)); + EXT_MEM1_SIZE_G(size)); } } return 0; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 172f68b6d592..a2d6e5043ff6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3802,7 +3802,7 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte) { struct adapter *adap; u32 offset, memtype, memaddr; - u32 edc0_size, edc1_size, mc0_size, mc1_size; + u32 edc0_size, edc1_size, mc0_size, mc1_size, size; u32 edc0_end, edc1_end, mc0_end, mc1_end; int ret; @@ -3816,9 +3816,12 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte) * and EDC1. Some cards will have neither MC0 nor MC1, most cards have * MC0, and some have both MC0 and MC1. */ - edc0_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM0_BAR)) << 20; - edc1_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM1_BAR)) << 20; - mc0_size = EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)) << 20; + size = t4_read_reg(adap, MA_EDRAM0_BAR_A); + edc0_size = EDRAM0_SIZE_G(size) << 20; + size = t4_read_reg(adap, MA_EDRAM1_BAR_A); + edc1_size = EDRAM1_SIZE_G(size) << 20; + size = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); + mc0_size = EXT_MEM0_SIZE_G(size) << 20; edc0_end = edc0_size; edc1_end = edc0_end + edc1_size; @@ -3838,9 +3841,8 @@ int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte) /* T4 only has a single memory channel */ goto err; } else { - mc1_size = EXT_MEM_SIZE_GET( - t4_read_reg(adap, - MA_EXT_MEMORY1_BAR)) << 20; + size = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); + mc1_size = EXT_MEM1_SIZE_G(size) << 20; mc1_end = mc0_end + mc1_size; if (offset < mc1_end) { memtype = MEM_MC1; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index a9d9d74e4f09..945fd1401d6a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -483,12 +483,12 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, * MEM_MC0 = 2 -- For T5 * MEM_MC1 = 3 -- For T5 */ - edc_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM0_BAR)); + edc_size = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A)); if (mtype != MEM_MC1) memoffset = (mtype * (edc_size * 1024 * 1024)); else { - mc_size = EXT_MEM_SIZE_GET(t4_read_reg(adap, - MA_EXT_MEMORY_BAR)); + mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap, + MA_EXT_MEMORY1_BAR_A)); memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index a1024db5dc13..c8eb7ba225e1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -501,21 +501,62 @@ #define MC_BIST_STATUS_RDATA 0x7688 -#define MA_EDRAM0_BAR 0x77c0 -#define MA_EDRAM1_BAR 0x77c4 -#define EDRAM_SIZE_MASK 0xfffU -#define EDRAM_SIZE_GET(x) ((x) & EDRAM_SIZE_MASK) - -#define MA_EXT_MEMORY_BAR 0x77c8 -#define EXT_MEM_SIZE_MASK 0x00000fffU -#define EXT_MEM_SIZE_SHIFT 0 -#define EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT) - -#define MA_TARGET_MEM_ENABLE 0x77d8 -#define EXT_MEM1_ENABLE 0x00000010U -#define EXT_MEM_ENABLE 0x00000004U -#define EDRAM1_ENABLE 0x00000002U -#define EDRAM0_ENABLE 0x00000001U +#define MA_EDRAM0_BAR_A 0x77c0 + +#define EDRAM0_SIZE_S 0 +#define EDRAM0_SIZE_M 0xfffU +#define EDRAM0_SIZE_V(x) ((x) << EDRAM0_SIZE_S) +#define EDRAM0_SIZE_G(x) (((x) >> EDRAM0_SIZE_S) & EDRAM0_SIZE_M) + +#define MA_EDRAM1_BAR_A 0x77c4 + +#define EDRAM1_SIZE_S 0 +#define EDRAM1_SIZE_M 0xfffU +#define EDRAM1_SIZE_V(x) ((x) << EDRAM1_SIZE_S) +#define EDRAM1_SIZE_G(x) (((x) >> EDRAM1_SIZE_S) & EDRAM1_SIZE_M) + +#define MA_EXT_MEMORY_BAR_A 0x77c8 + +#define EXT_MEM_SIZE_S 0 +#define EXT_MEM_SIZE_M 0xfffU +#define EXT_MEM_SIZE_V(x) ((x) << EXT_MEM_SIZE_S) +#define EXT_MEM_SIZE_G(x) (((x) >> EXT_MEM_SIZE_S) & EXT_MEM_SIZE_M) + +#define MA_EXT_MEMORY1_BAR_A 0x7808 + +#define EXT_MEM1_SIZE_S 0 +#define EXT_MEM1_SIZE_M 0xfffU +#define EXT_MEM1_SIZE_V(x) ((x) << EXT_MEM1_SIZE_S) +#define EXT_MEM1_SIZE_G(x) (((x) >> EXT_MEM1_SIZE_S) & EXT_MEM1_SIZE_M) + +#define MA_EXT_MEMORY0_BAR_A 0x77c8 + +#define EXT_MEM0_SIZE_S 0 +#define EXT_MEM0_SIZE_M 0xfffU +#define EXT_MEM0_SIZE_V(x) ((x) << EXT_MEM0_SIZE_S) +#define EXT_MEM0_SIZE_G(x) (((x) >> EXT_MEM0_SIZE_S) & EXT_MEM0_SIZE_M) + +#define MA_TARGET_MEM_ENABLE_A 0x77d8 + +#define EXT_MEM_ENABLE_S 2 +#define EXT_MEM_ENABLE_V(x) ((x) << EXT_MEM_ENABLE_S) +#define EXT_MEM_ENABLE_F EXT_MEM_ENABLE_V(1U) + +#define EDRAM1_ENABLE_S 1 +#define EDRAM1_ENABLE_V(x) ((x) << EDRAM1_ENABLE_S) +#define EDRAM1_ENABLE_F EDRAM1_ENABLE_V(1U) + +#define EDRAM0_ENABLE_S 0 +#define EDRAM0_ENABLE_V(x) ((x) << EDRAM0_ENABLE_S) +#define EDRAM0_ENABLE_F EDRAM0_ENABLE_V(1U) + +#define EXT_MEM1_ENABLE_S 4 +#define EXT_MEM1_ENABLE_V(x) ((x) << EXT_MEM1_ENABLE_S) +#define EXT_MEM1_ENABLE_F EXT_MEM1_ENABLE_V(1U) + +#define EXT_MEM0_ENABLE_S 2 +#define EXT_MEM0_ENABLE_V(x) ((x) << EXT_MEM0_ENABLE_S) +#define EXT_MEM0_ENABLE_F EXT_MEM0_ENABLE_V(1U) #define MA_INT_CAUSE 0x77e0 #define MEM_PERR_INT_CAUSE 0x00000002U @@ -532,7 +573,6 @@ #define MA_PARITY_ERROR_STATUS 0x77f4 #define MA_PARITY_ERROR_STATUS2 0x7804 -#define MA_EXT_MEMORY1_BAR 0x7808 #define EDC_0_BASE_ADDR 0x7900 #define EDC_BIST_CMD 0x7904 diff --git a/drivers/scsi/csiostor/csio_hw_t4.c b/drivers/scsi/csiostor/csio_hw_t4.c index 89ecbac5478f..95d831857640 100644 --- a/drivers/scsi/csiostor/csio_hw_t4.c +++ b/drivers/scsi/csiostor/csio_hw_t4.c @@ -307,12 +307,12 @@ csio_t4_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr, * MEM_EDC1 = 1 * MEM_MC = 2 -- T4 */ - edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR)); + edc_size = EDRAM0_SIZE_G(csio_rd_reg32(hw, MA_EDRAM0_BAR_A)); if (mtype != MEM_MC1) memoffset = (mtype * (edc_size * 1024 * 1024)); else { - mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw, - MA_EXT_MEMORY_BAR)); + mc_size = EXT_MEM_SIZE_G(csio_rd_reg32(hw, + MA_EXT_MEMORY_BAR_A)); memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; } @@ -383,11 +383,12 @@ static void csio_t4_dfs_create_ext_mem(struct csio_hw *hw) { u32 size; - int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE); - if (i & EXT_MEM_ENABLE) { - size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR); + int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A); + + if (i & EXT_MEM_ENABLE_F) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR_A); csio_add_debugfs_mem(hw, "mc", MEM_MC, - EXT_MEM_SIZE_GET(size)); + EXT_MEM_SIZE_G(size)); } } diff --git a/drivers/scsi/csiostor/csio_hw_t5.c b/drivers/scsi/csiostor/csio_hw_t5.c index 27745c170c24..66e180a58718 100644 --- a/drivers/scsi/csiostor/csio_hw_t5.c +++ b/drivers/scsi/csiostor/csio_hw_t5.c @@ -298,12 +298,12 @@ csio_t5_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr, * MEM_MC0 = 2 -- For T5 * MEM_MC1 = 3 -- For T5 */ - edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR)); + edc_size = EDRAM0_SIZE_G(csio_rd_reg32(hw, MA_EDRAM0_BAR_A)); if (mtype != MEM_MC1) memoffset = (mtype * (edc_size * 1024 * 1024)); else { - mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw, - MA_EXT_MEMORY_BAR)); + mc_size = EXT_MEM_SIZE_G(csio_rd_reg32(hw, + MA_EXT_MEMORY_BAR_A)); memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; } @@ -372,16 +372,17 @@ static void csio_t5_dfs_create_ext_mem(struct csio_hw *hw) { u32 size; - int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE); - if (i & EXT_MEM_ENABLE) { - size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR); + int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A); + + if (i & EXT_MEM_ENABLE_F) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR_A); csio_add_debugfs_mem(hw, "mc0", MEM_MC0, - EXT_MEM_SIZE_GET(size)); + EXT_MEM_SIZE_G(size)); } - if (i & EXT_MEM1_ENABLE) { - size = csio_rd_reg32(hw, MA_EXT_MEMORY1_BAR); + if (i & EXT_MEM1_ENABLE_F) { + size = csio_rd_reg32(hw, MA_EXT_MEMORY1_BAR_A); csio_add_debugfs_mem(hw, "mc1", MEM_MC1, - EXT_MEM_SIZE_GET(size)); + EXT_MEM_SIZE_G(size)); } } diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 17794add855c..70e1eb6d9640 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -128,10 +128,10 @@ static int csio_setup_debugfs(struct csio_hw *hw) if (IS_ERR_OR_NULL(hw->debugfs_root)) return -1; - i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE); - if (i & EDRAM0_ENABLE) + i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A); + if (i & EDRAM0_ENABLE_F) csio_add_debugfs_mem(hw, "edc0", MEM_EDC0, 5); - if (i & EDRAM1_ENABLE) + if (i & EDRAM1_ENABLE_F) csio_add_debugfs_mem(hw, "edc1", MEM_EDC1, 5); hw->chip_ops->chip_dfs_create_ext_mem(hw); -- GitLab From e2ac9628959cc152a811931a6422757b137ac4a4 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 7 Nov 2014 09:35:25 +0530 Subject: [PATCH 4149/9457] cxgb4: Cleanup macros so they follow the same style and look consistent, part 2 Various patches have ended up changing the style of the symbolic macros/register defines to different style. As a result, the current kernel.org files are a mix of different macro styles. Since this macro/register defines is used by different drivers a few patch series have ended up adding duplicate macro/register define entries with different styles. This makes these register define/macro files a complete mess and we want to make them clean and consistent. This patch cleans up a part of it. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 56 +++--- drivers/infiniband/hw/cxgb4/cq.c | 8 +- drivers/infiniband/hw/cxgb4/mem.c | 14 +- drivers/infiniband/hw/cxgb4/qp.c | 26 +-- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 +- .../net/ethernet/chelsio/cxgb4/cxgb4_dcb.h | 6 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 60 +++--- .../net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 15 +- drivers/net/ethernet/chelsio/cxgb4/sge.c | 32 ++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 121 ++++++------ drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 142 +++++++++++---- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 32 ++-- .../ethernet/chelsio/cxgb4vf/t4vf_common.h | 2 +- .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 150 +++++++-------- drivers/scsi/csiostor/csio_attr.c | 8 +- drivers/scsi/csiostor/csio_hw.c | 14 +- drivers/scsi/csiostor/csio_lnode.c | 18 +- drivers/scsi/csiostor/csio_mb.c | 172 +++++++++--------- drivers/scsi/csiostor/csio_scsi.c | 24 +-- drivers/scsi/csiostor/csio_wr.h | 2 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 35 ++-- 21 files changed, 509 insertions(+), 430 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index fb61f6685809..a07d8e124a80 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -472,10 +472,10 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) skb = get_skb(skb, flowclen, GFP_KERNEL); flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen); - flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) | - FW_FLOWC_WR_NPARAMS(8)); - flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(flowclen, - 16)) | FW_WR_FLOWID(ep->hwtid)); + flowc->op_to_nparams = cpu_to_be32(FW_WR_OP_V(FW_FLOWC_WR) | + FW_FLOWC_WR_NPARAMS_V(8)); + flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(flowclen, + 16)) | FW_WR_FLOWID_V(ep->hwtid)); flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN; flowc->mnemval[0].val = cpu_to_be32(FW_PFVF_CMD_PFN @@ -803,16 +803,16 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb, req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen); memset(req, 0, wrlen); req->op_to_immdlen = cpu_to_be32( - FW_WR_OP(FW_OFLD_TX_DATA_WR) | - FW_WR_COMPL(1) | - FW_WR_IMMDLEN(mpalen)); + FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | + FW_WR_COMPL_F | + FW_WR_IMMDLEN_V(mpalen)); req->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(ep->hwtid) | - FW_WR_LEN16(wrlen >> 4)); + FW_WR_FLOWID_V(ep->hwtid) | + FW_WR_LEN16_V(wrlen >> 4)); req->plen = cpu_to_be32(mpalen); req->tunnel_to_proxy = cpu_to_be32( - FW_OFLD_TX_DATA_WR_FLUSH(1) | - FW_OFLD_TX_DATA_WR_SHOVE(1)); + FW_OFLD_TX_DATA_WR_FLUSH_F | + FW_OFLD_TX_DATA_WR_SHOVE_F); mpa = (struct mpa_message *)(req + 1); memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key)); @@ -897,16 +897,16 @@ static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen) req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen); memset(req, 0, wrlen); req->op_to_immdlen = cpu_to_be32( - FW_WR_OP(FW_OFLD_TX_DATA_WR) | - FW_WR_COMPL(1) | - FW_WR_IMMDLEN(mpalen)); + FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | + FW_WR_COMPL_F | + FW_WR_IMMDLEN_V(mpalen)); req->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(ep->hwtid) | - FW_WR_LEN16(wrlen >> 4)); + FW_WR_FLOWID_V(ep->hwtid) | + FW_WR_LEN16_V(wrlen >> 4)); req->plen = cpu_to_be32(mpalen); req->tunnel_to_proxy = cpu_to_be32( - FW_OFLD_TX_DATA_WR_FLUSH(1) | - FW_OFLD_TX_DATA_WR_SHOVE(1)); + FW_OFLD_TX_DATA_WR_FLUSH_F | + FW_OFLD_TX_DATA_WR_SHOVE_F); mpa = (struct mpa_message *)(req + 1); memset(mpa, 0, sizeof(*mpa)); @@ -977,16 +977,16 @@ static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen) req = (struct fw_ofld_tx_data_wr *) skb_put(skb, wrlen); memset(req, 0, wrlen); req->op_to_immdlen = cpu_to_be32( - FW_WR_OP(FW_OFLD_TX_DATA_WR) | - FW_WR_COMPL(1) | - FW_WR_IMMDLEN(mpalen)); + FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | + FW_WR_COMPL_F | + FW_WR_IMMDLEN_V(mpalen)); req->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(ep->hwtid) | - FW_WR_LEN16(wrlen >> 4)); + FW_WR_FLOWID_V(ep->hwtid) | + FW_WR_LEN16_V(wrlen >> 4)); req->plen = cpu_to_be32(mpalen); req->tunnel_to_proxy = cpu_to_be32( - FW_OFLD_TX_DATA_WR_FLUSH(1) | - FW_OFLD_TX_DATA_WR_SHOVE(1)); + FW_OFLD_TX_DATA_WR_FLUSH_F | + FW_OFLD_TX_DATA_WR_SHOVE_F); mpa = (struct mpa_message *)(req + 1); memset(mpa, 0, sizeof(*mpa)); @@ -1751,7 +1751,7 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) req = (struct fw_ofld_connection_wr *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR)); - req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16))); + req->len16_pkd = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*req), 16))); req->le.filter = cpu_to_be32(cxgb4_select_ntuple( ep->com.dev->rdev.lldi.ports[0], ep->l2t)); @@ -3537,8 +3537,8 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, req_skb = alloc_skb(sizeof(struct fw_ofld_connection_wr), GFP_KERNEL); req = (struct fw_ofld_connection_wr *)__skb_put(req_skb, sizeof(*req)); memset(req, 0, sizeof(*req)); - req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL(1)); - req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16))); + req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL_F); + req->len16_pkd = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*req), 16))); req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL); req->le.filter = (__force __be32) filter; req->le.lport = lport; diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 0f773e78e080..e9fd3a029296 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -51,9 +51,9 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len); memset(res_wr, 0, wr_len); res_wr->op_nres = cpu_to_be32( - FW_WR_OP(FW_RI_RES_WR) | + FW_WR_OP_V(FW_RI_RES_WR) | V_FW_RI_RES_WR_NRES(1) | - FW_WR_COMPL(1)); + FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); res_wr->cookie = (unsigned long) &wr_wait; res = res_wr->res; @@ -121,9 +121,9 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len); memset(res_wr, 0, wr_len); res_wr->op_nres = cpu_to_be32( - FW_WR_OP(FW_RI_RES_WR) | + FW_WR_OP_V(FW_RI_RES_WR) | V_FW_RI_RES_WR_NRES(1) | - FW_WR_COMPL(1)); + FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); res_wr->cookie = (unsigned long) &wr_wait; res = res_wr->res; diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index ec7a2988a703..9335148c1ad9 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -74,10 +74,10 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, req = (struct ulp_mem_io *)__skb_put(skb, wr_len); memset(req, 0, wr_len); INIT_ULPTX_WR(req, wr_len, 0, 0); - req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) | - (wait ? FW_WR_COMPL(1) : 0)); + req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | + (wait ? FW_WR_COMPL_F : 0)); req->wr.wr_lo = wait ? (__force __be64)(unsigned long) &wr_wait : 0L; - req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16))); + req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16))); req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1)); req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN(len>>5)); @@ -135,13 +135,13 @@ static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, INIT_ULPTX_WR(req, wr_len, 0, 0); if (i == (num_wqe-1)) { - req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) | - FW_WR_COMPL(1)); + req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | + FW_WR_COMPL_F); req->wr.wr_lo = (__force __be64)(unsigned long) &wr_wait; } else - req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR)); + req->wr.wr_hi = cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR)); req->wr.wr_mid = cpu_to_be32( - FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16))); + FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16))); req->cmd = cmd; req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN( diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 41cd6882b648..2ed3ece2b2ee 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -271,9 +271,9 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len); memset(res_wr, 0, wr_len); res_wr->op_nres = cpu_to_be32( - FW_WR_OP(FW_RI_RES_WR) | + FW_WR_OP_V(FW_RI_RES_WR) | V_FW_RI_RES_WR_NRES(2) | - FW_WR_COMPL(1)); + FW_WR_COMPL_F); res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); res_wr->cookie = (unsigned long) &wr_wait; res = res_wr->res; @@ -1082,10 +1082,10 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe, wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe)); memset(wqe, 0, sizeof *wqe); - wqe->op_compl = cpu_to_be32(FW_WR_OP(FW_RI_INIT_WR)); + wqe->op_compl = cpu_to_be32(FW_WR_OP_V(FW_RI_INIT_WR)); wqe->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(qhp->ep->hwtid) | - FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); + FW_WR_FLOWID_V(qhp->ep->hwtid) | + FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); wqe->u.terminate.type = FW_RI_TYPE_TERMINATE; wqe->u.terminate.immdlen = cpu_to_be32(sizeof *term); @@ -1204,11 +1204,11 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe)); memset(wqe, 0, sizeof *wqe); wqe->op_compl = cpu_to_be32( - FW_WR_OP(FW_RI_INIT_WR) | - FW_WR_COMPL(1)); + FW_WR_OP_V(FW_RI_INIT_WR) | + FW_WR_COMPL_F); wqe->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(ep->hwtid) | - FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); + FW_WR_FLOWID_V(ep->hwtid) | + FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); wqe->cookie = (unsigned long) &ep->com.wr_wait; wqe->u.fini.type = FW_RI_TYPE_FINI; @@ -1273,11 +1273,11 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe)); memset(wqe, 0, sizeof *wqe); wqe->op_compl = cpu_to_be32( - FW_WR_OP(FW_RI_INIT_WR) | - FW_WR_COMPL(1)); + FW_WR_OP_V(FW_RI_INIT_WR) | + FW_WR_COMPL_F); wqe->flowid_len16 = cpu_to_be32( - FW_WR_FLOWID(qhp->ep->hwtid) | - FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); + FW_WR_FLOWID_V(qhp->ep->hwtid) | + FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*wqe), 16))); wqe->cookie = (unsigned long) &qhp->ep->com.wr_wait; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index dad1ea930e05..a2196bc94485 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -354,7 +354,7 @@ struct link_config { unsigned char link_ok; /* link up? */ }; -#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16) +#define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16) enum { MAX_ETH_QSETS = 32, /* # of Ethernet Tx/Rx queue sets */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h index 2a6aa88984f4..c0724a5b5942 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h @@ -42,9 +42,9 @@ do { \ memset(&(__pcmd), 0, sizeof(__pcmd)); \ (__pcmd).op_to_portid = \ - cpu_to_be32(FW_CMD_OP(FW_PORT_CMD) | \ - FW_CMD_REQUEST | \ - FW_CMD_##__op | \ + cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | \ + FW_CMD_REQUEST_F | \ + FW_CMD_##__op##_F | \ FW_PORT_CMD_PORTID(__port)); \ (__pcmd).action_to_len16 = \ cpu_to_be32(FW_PORT_CMD_ACTION(__action) | \ diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a2d6e5043ff6..350f9c204402 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -833,7 +833,7 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, #ifdef CONFIG_CHELSIO_T4_DCB const struct fw_port_cmd *pcmd = (const void *)p->data; - unsigned int cmd = FW_CMD_OP_GET(ntohl(pcmd->op_to_portid)); + unsigned int cmd = FW_CMD_OP_G(ntohl(pcmd->op_to_portid)); unsigned int action = FW_PORT_CMD_ACTION_GET(ntohl(pcmd->action_to_len16)); @@ -1340,8 +1340,8 @@ static int set_filter_wr(struct adapter *adapter, int fidx) * filter specification structure but for now it's easiest to simply * put this fairly direct code in line ... */ - fwr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR)); - fwr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*fwr)/16)); + fwr->op_pkd = htonl(FW_WR_OP_V(FW_FILTER_WR)); + fwr->len16_pkd = htonl(FW_WR_LEN16_V(sizeof(*fwr)/16)); fwr->tid_to_iq = htonl(V_FW_FILTER_WR_TID(ftid) | V_FW_FILTER_WR_RQTYPE(f->fs.type) | @@ -3417,8 +3417,8 @@ int cxgb4_clip_get(const struct net_device *dev, adap = netdev2adap(dev); memset(&c, 0, sizeof(c)); - c.op_to_write = htonl(FW_CMD_OP(FW_CLIP_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); + c.op_to_write = htonl(FW_CMD_OP_V(FW_CLIP_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); c.alloc_to_len16 = htonl(F_FW_CLIP_CMD_ALLOC | FW_LEN16(c)); c.ip_hi = *(__be64 *)(lip->s6_addr); c.ip_lo = *(__be64 *)(lip->s6_addr + 8); @@ -3434,8 +3434,8 @@ int cxgb4_clip_release(const struct net_device *dev, adap = netdev2adap(dev); memset(&c, 0, sizeof(c)); - c.op_to_write = htonl(FW_CMD_OP(FW_CLIP_CMD) | - FW_CMD_REQUEST | FW_CMD_READ); + c.op_to_write = htonl(FW_CMD_OP_V(FW_CLIP_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F); c.alloc_to_len16 = htonl(F_FW_CLIP_CMD_FREE | FW_LEN16(c)); c.ip_hi = *(__be64 *)(lip->s6_addr); c.ip_lo = *(__be64 *)(lip->s6_addr + 8); @@ -4871,9 +4871,9 @@ static u32 t4_read_pcie_cfg4(struct adapter *adap, int reg) */ memset(&ldst_cmd, 0, sizeof(ldst_cmd)); ldst_cmd.op_to_addrspace = - htonl(FW_CMD_OP(FW_LDST_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + htonl(FW_CMD_OP_V(FW_LDST_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE)); ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd)); ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1); @@ -4965,8 +4965,8 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) /* get device capabilities */ memset(c, 0, sizeof(*c)); - c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_READ); + c->op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F); c->cfvalid_to_len16 = htonl(FW_LEN16(*c)); ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), c); if (ret < 0) @@ -4982,8 +4982,8 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) dev_err(adap->pdev_dev, "virtualization ACLs not supported"); return ret; } - c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); + c->op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), NULL); if (ret < 0) return ret; @@ -5209,9 +5209,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) */ memset(&caps_cmd, 0, sizeof(caps_cmd)); caps_cmd.op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); caps_cmd.cfvalid_to_len16 = htonl(FW_CAPS_CONFIG_CMD_CFVALID | FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | @@ -5229,9 +5229,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) if (ret == -ENOENT) { memset(&caps_cmd, 0, sizeof(caps_cmd)); caps_cmd.op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); @@ -5254,9 +5254,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) * And now tell the firmware to use the configuration we just loaded. */ caps_cmd.op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE); + htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F); caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), NULL); @@ -5327,8 +5327,8 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) * Get device capabilities and select which we'll be using. */ memset(&caps_cmd, 0, sizeof(caps_cmd)); - caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_READ); + caps_cmd.op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F); caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); @@ -5344,8 +5344,8 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) dev_err(adapter->pdev_dev, "virtualization ACLs not supported"); goto bye; } - caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); + caps_cmd.op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), NULL); if (ret < 0) @@ -5713,7 +5713,6 @@ static int adap_init0(struct adapter *adap) } else { dev_info(adap->pdev_dev, "Coming up as MASTER: "\ "Initializing adapter\n"); - /* * If the firmware doesn't support Configuration * Files warn user and exit, @@ -5757,6 +5756,7 @@ static int adap_init0(struct adapter *adap) "No Configuration File present " "on adapter. Using hard-wired " "configuration parameters.\n"); + goto bye; ret = adap_init0_no_config(adap, reset); } } @@ -5856,8 +5856,8 @@ static int adap_init0(struct adapter *adap) * to manage. */ memset(&caps_cmd, 0, sizeof(caps_cmd)); - caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_READ); + caps_cmd.op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F); caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h index 1366ba620c87..4eba7cb1b89c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -52,10 +52,10 @@ enum { }; #define INIT_TP_WR(w, tid) do { \ - (w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \ - FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \ - (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \ - FW_WR_FLOWID(tid)); \ + (w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_TP_WR) | \ + FW_WR_IMMDLEN_V(sizeof(*w) - sizeof(w->wr))); \ + (w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*w), 16)) | \ + FW_WR_FLOWID_V(tid)); \ (w)->wr.wr_lo = cpu_to_be64(0); \ } while (0) @@ -65,9 +65,10 @@ enum { } while (0) #define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \ - (w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \ - (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \ - FW_WR_FLOWID(tid)); \ + (w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_ULPTX_WR) | \ + FW_WR_ATOMIC_V(atomic)); \ + (w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(wrlen, 16)) | \ + FW_WR_FLOWID_V(tid)); \ (w)->wr.wr_lo = cpu_to_be64(0); \ } while (0) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 5e1b314e11af..6399e008a7f7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -1092,10 +1092,10 @@ out_free: dev_kfree_skb_any(skb); goto out_free; } - wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2)); + wr_mid = FW_WR_LEN16_V(DIV_ROUND_UP(flits, 2)); if (unlikely(credits < ETHTXQ_STOP_THRES)) { eth_txq_stop(q); - wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ; + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; } wr = (void *)&q->q.desc[q->q.pidx]; @@ -1112,8 +1112,8 @@ out_free: dev_kfree_skb_any(skb); int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN; len += sizeof(*lso); - wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) | - FW_WR_IMMDLEN(len)); + wr->op_immdlen = htonl(FW_WR_OP_V(FW_ETH_TX_PKT_WR) | + FW_WR_IMMDLEN_V(len)); lso->c.lso_ctrl = htonl(LSO_OPCODE(CPL_TX_PKT_LSO) | LSO_FIRST_SLICE | LSO_LAST_SLICE | LSO_IPV6(v6) | @@ -1135,8 +1135,8 @@ out_free: dev_kfree_skb_any(skb); q->tx_cso += ssi->gso_segs; } else { len += sizeof(*cpl); - wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) | - FW_WR_IMMDLEN(len)); + wr->op_immdlen = htonl(FW_WR_OP_V(FW_ETH_TX_PKT_WR) | + FW_WR_IMMDLEN_V(len)); cpl = (void *)(wr + 1); if (skb->ip_summed == CHECKSUM_PARTIAL) { cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS; @@ -1224,7 +1224,7 @@ static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr) { reclaim_completed_tx_imm(&q->q); if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) { - wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ); + wr->lo |= htonl(FW_WR_EQUEQ_F | FW_WR_EQUIQ_F); q->q.stops++; q->full = 1; } @@ -1406,7 +1406,7 @@ static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb) { struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data; - wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ); + wr->lo |= htonl(FW_WR_EQUEQ_F | FW_WR_EQUIQ_F); q->q.stops++; q->full = 1; } @@ -2297,8 +2297,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, return -ENOMEM; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_CMD_EXEC | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_CMD_EXEC_F | FW_IQ_CMD_PFN(adap->fn) | FW_IQ_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) | FW_LEN16(c)); @@ -2423,8 +2423,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, return -ENOMEM; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_CMD_EXEC | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_ETH_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_CMD_EXEC_F | FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); @@ -2476,8 +2476,8 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, if (!txq->q.desc) return -ENOMEM; - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_CMD_EXEC | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_CMD_EXEC_F | FW_EQ_CTRL_CMD_PFN(adap->fn) | FW_EQ_CTRL_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC | @@ -2530,8 +2530,8 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, return -ENOMEM; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_CMD_EXEC | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN(adap->fn) | FW_EQ_OFLD_CMD_VFN(0)); c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 945fd1401d6a..2bb4efa7db98 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -310,16 +310,17 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, } res = t4_read_reg64(adap, data_reg); - if (FW_CMD_OP_GET(res >> 32) == FW_DEBUG_CMD) { + if (FW_CMD_OP_G(res >> 32) == FW_DEBUG_CMD) { fw_asrt(adap, data_reg); - res = FW_CMD_RETVAL(EIO); - } else if (rpl) + res = FW_CMD_RETVAL_V(EIO); + } else if (rpl) { get_mbox_rpl(adap, rpl, size / 8, data_reg); + } - if (FW_CMD_RETVAL_GET((int)res)) + if (FW_CMD_RETVAL_G((int)res)) dump_mbox(adap, mbox, data_reg); t4_write_reg(adap, ctl_reg, 0); - return -FW_CMD_RETVAL_GET((int)res); + return -FW_CMD_RETVAL_G((int)res); } } @@ -1245,8 +1246,8 @@ int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, fc |= FW_PORT_CAP_FC_TX; memset(&c, 0, sizeof(c)); - c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_PORT_CMD_PORTID(port)); + c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_PORT_CMD_PORTID(port)); c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); @@ -1275,8 +1276,8 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port) struct fw_port_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_PORT_CMD_PORTID(port)); + c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_PORT_CMD_PORTID(port)); c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG); @@ -2071,8 +2072,8 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, struct fw_rss_ind_tbl_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = htonl(FW_CMD_OP(FW_RSS_IND_TBL_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE | + cmd.op_to_viid = htonl(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_RSS_IND_TBL_CMD_VIID(viid)); cmd.retval_len16 = htonl(FW_LEN16(cmd)); @@ -2126,8 +2127,8 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, struct fw_rss_glb_config_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); + c.op_to_write = htonl(FW_CMD_OP_V(FW_RSS_GLB_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); c.retval_len16 = htonl(FW_LEN16(c)); if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) { c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); @@ -2553,8 +2554,8 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid) { memset(wr, 0, sizeof(*wr)); - wr->op_pkd = htonl(FW_WR_OP(FW_FILTER_WR)); - wr->len16_pkd = htonl(FW_WR_LEN16(sizeof(*wr) / 16)); + wr->op_pkd = htonl(FW_WR_OP_V(FW_FILTER_WR)); + wr->len16_pkd = htonl(FW_WR_LEN16_V(sizeof(*wr) / 16)); wr->tid_to_iq = htonl(V_FW_FILTER_WR_TID(ftid) | V_FW_FILTER_WR_NOREPLY(qid < 0)); wr->del_filter_to_l2tix = htonl(F_FW_FILTER_WR_DEL_FILTER); @@ -2563,8 +2564,8 @@ void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid) } #define INIT_CMD(var, cmd, rd_wr) do { \ - (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \ - FW_CMD_REQUEST | FW_CMD_##rd_wr); \ + (var).op_to_write = htonl(FW_CMD_OP_V(FW_##cmd##_CMD) | \ + FW_CMD_REQUEST_F | FW_CMD_##rd_wr##_F); \ (var).retval_len16 = htonl(FW_LEN16(var)); \ } while (0) @@ -2574,8 +2575,8 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, struct fw_ldst_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | + c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE)); c.cycles_to_len16 = htonl(FW_LEN16(c)); c.u.addrval.addr = htonl(addr); @@ -2602,8 +2603,8 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, struct fw_ldst_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | - FW_CMD_READ | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); + c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); c.cycles_to_len16 = htonl(FW_LEN16(c)); c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | FW_LDST_CMD_MMD(mmd)); @@ -2632,8 +2633,8 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, struct fw_ldst_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); + c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); c.cycles_to_len16 = htonl(FW_LEN16(c)); c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | FW_LDST_CMD_MMD(mmd)); @@ -3211,8 +3212,8 @@ int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, return -EINVAL; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST | - FW_CMD_READ | FW_PARAMS_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_PARAMS_CMD_PFN(pf) | FW_PARAMS_CMD_VFN(vf)); c.retval_len16 = htonl(FW_LEN16(c)); for (i = 0; i < nparams; i++, p += 2) @@ -3251,8 +3252,8 @@ int t4_set_params_nosleep(struct adapter *adap, unsigned int mbox, return -EINVAL; memset(&c, 0, sizeof(c)); - c.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE | + c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_PARAMS_CMD_PFN(pf) | FW_PARAMS_CMD_VFN(vf)); c.retval_len16 = cpu_to_be32(FW_LEN16(c)); @@ -3289,8 +3290,8 @@ int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, return -EINVAL; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_PARAMS_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_PARAMS_CMD_PFN(pf) | FW_PARAMS_CMD_VFN(vf)); c.retval_len16 = htonl(FW_LEN16(c)); while (nparams--) { @@ -3331,8 +3332,8 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, struct fw_pfvf_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_PFVF_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PFVF_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_PFVF_CMD_PFN(pf) | FW_PFVF_CMD_VFN(vf)); c.retval_len16 = htonl(FW_LEN16(c)); c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) | @@ -3373,8 +3374,8 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, struct fw_vi_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_CMD_EXEC | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_VI_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_CMD_EXEC_F | FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf)); c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c)); c.portid_pkd = FW_VI_CMD_PORTID(port); @@ -3435,8 +3436,8 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid)); + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_RXMODE_CMD_VIID(viid)); c.retval_len16 = htonl(FW_LEN16(c)); c.mtu_to_vlanexen = htonl(FW_VI_RXMODE_CMD_MTU(mtu) | FW_VI_RXMODE_CMD_PROMISCEN(promisc) | @@ -3483,11 +3484,11 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, return -EINVAL; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | (free ? FW_CMD_EXEC : 0) | + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | (free ? FW_CMD_EXEC_F : 0) | FW_VI_MAC_CMD_VIID(viid)); c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) | - FW_CMD_LEN16((naddr + 2) / 2)); + FW_CMD_LEN16_V((naddr + 2) / 2)); for (i = 0, p = c.u.exact; i < naddr; i++, p++) { p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | @@ -3546,9 +3547,9 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_VI_MAC_CMD_VIID(viid)); - c.freemacs_to_len16 = htonl(FW_CMD_LEN16(1)); + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_MAC_CMD_VIID(viid)); + c.freemacs_to_len16 = htonl(FW_CMD_LEN16_V(1)); p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | FW_VI_MAC_CMD_SMAC_RESULT(mode) | FW_VI_MAC_CMD_IDX(idx)); @@ -3580,11 +3581,11 @@ int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, struct fw_vi_mac_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | - FW_CMD_WRITE | FW_VI_ENABLE_CMD_VIID(viid)); + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_ENABLE_CMD_VIID(viid)); c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN | FW_VI_MAC_CMD_HASHUNIEN(ucast) | - FW_CMD_LEN16(1)); + FW_CMD_LEN16_V(1)); c.u.hash.hashvec = cpu_to_be64(vec); return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); } @@ -3607,8 +3608,8 @@ int t4_enable_vi_params(struct adapter *adap, unsigned int mbox, struct fw_vi_enable_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) | FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c) | @@ -3647,8 +3648,8 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, struct fw_vi_enable_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); + c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); c.blinkdur = htons(nblinks); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); @@ -3674,8 +3675,8 @@ int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, struct fw_iq_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_IQ_CMD_PFN(pf) | FW_IQ_CMD_VFN(vf)); c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c)); c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype)); @@ -3701,8 +3702,8 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, struct fw_eq_eth_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_EQ_ETH_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_ETH_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_EQ_ETH_CMD_PFN(pf) | FW_EQ_ETH_CMD_VFN(vf)); c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c)); c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid)); @@ -3725,8 +3726,8 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, struct fw_eq_ctrl_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_EQ_CTRL_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_EQ_CTRL_CMD_PFN(pf) | FW_EQ_CTRL_CMD_VFN(vf)); c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c)); c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid)); @@ -3749,8 +3750,8 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, struct fw_eq_ofld_cmd c; memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_EQ_OFLD_CMD_PFN(pf) | + c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN(pf) | FW_EQ_OFLD_CMD_VFN(vf)); c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c)); c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid)); @@ -4082,8 +4083,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) while ((adap->params.portvec & (1 << j)) == 0) j++; - c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | - FW_CMD_REQUEST | FW_CMD_READ | + c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F | FW_PORT_CMD_PORTID(j)); c.action_to_len16 = htonl( FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | @@ -4109,8 +4110,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) p->port_type = FW_PORT_CMD_PTYPE_GET(ret); p->mod_type = FW_PORT_MOD_TYPE_NA; - rvc.op_to_viid = htonl(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | - FW_CMD_REQUEST | FW_CMD_READ | + rvc.op_to_viid = htonl(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F | FW_RSS_VI_CONFIG_CMD_VIID(p->viid)); rvc.retval_len16 = htonl(FW_LEN16(rvc)); ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 3409756a85b9..7cca67fde4f4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -109,18 +109,49 @@ struct fw_wr_hdr { __be32 lo; }; -#define FW_WR_OP(x) ((x) << 24) -#define FW_WR_OP_GET(x) (((x) >> 24) & 0xff) -#define FW_WR_ATOMIC(x) ((x) << 23) -#define FW_WR_FLUSH(x) ((x) << 22) -#define FW_WR_COMPL(x) ((x) << 21) -#define FW_WR_IMMDLEN_MASK 0xff -#define FW_WR_IMMDLEN(x) ((x) << 0) - -#define FW_WR_EQUIQ (1U << 31) -#define FW_WR_EQUEQ (1U << 30) -#define FW_WR_FLOWID(x) ((x) << 8) -#define FW_WR_LEN16(x) ((x) << 0) +/* work request opcode (hi) */ +#define FW_WR_OP_S 24 +#define FW_WR_OP_M 0xff +#define FW_WR_OP_V(x) ((x) << FW_WR_OP_S) +#define FW_WR_OP_G(x) (((x) >> FW_WR_OP_S) & FW_WR_OP_M) + +/* atomic flag (hi) - firmware encapsulates CPLs in CPL_BARRIER */ +#define FW_WR_ATOMIC_S 23 +#define FW_WR_ATOMIC_V(x) ((x) << FW_WR_ATOMIC_S) + +/* flush flag (hi) - firmware flushes flushable work request buffered + * in the flow context. + */ +#define FW_WR_FLUSH_S 22 +#define FW_WR_FLUSH_V(x) ((x) << FW_WR_FLUSH_S) + +/* completion flag (hi) - firmware generates a cpl_fw6_ack */ +#define FW_WR_COMPL_S 21 +#define FW_WR_COMPL_V(x) ((x) << FW_WR_COMPL_S) +#define FW_WR_COMPL_F FW_WR_COMPL_V(1U) + +/* work request immediate data length (hi) */ +#define FW_WR_IMMDLEN_S 0 +#define FW_WR_IMMDLEN_M 0xff +#define FW_WR_IMMDLEN_V(x) ((x) << FW_WR_IMMDLEN_S) + +/* egress queue status update to associated ingress queue entry (lo) */ +#define FW_WR_EQUIQ_S 31 +#define FW_WR_EQUIQ_V(x) ((x) << FW_WR_EQUIQ_S) +#define FW_WR_EQUIQ_F FW_WR_EQUIQ_V(1U) + +/* egress queue status update to egress queue status entry (lo) */ +#define FW_WR_EQUEQ_S 30 +#define FW_WR_EQUEQ_V(x) ((x) << FW_WR_EQUEQ_S) +#define FW_WR_EQUEQ_F FW_WR_EQUEQ_V(1U) + +/* flow context identifier (lo) */ +#define FW_WR_FLOWID_S 8 +#define FW_WR_FLOWID_V(x) ((x) << FW_WR_FLOWID_S) + +/* length in units of 16-bytes (lo) */ +#define FW_WR_LEN16_S 0 +#define FW_WR_LEN16_V(x) ((x) << FW_WR_LEN16_S) #define HW_TPL_FR_MT_PR_IV_P_FC 0X32B #define HW_TPL_FR_MT_PR_OV_P_FC 0X327 @@ -539,26 +570,47 @@ struct fw_flowc_mnemval { struct fw_flowc_wr { __be32 op_to_nparams; -#define FW_FLOWC_WR_NPARAMS(x) ((x) << 0) __be32 flowid_len16; struct fw_flowc_mnemval mnemval[0]; }; +#define FW_FLOWC_WR_NPARAMS_S 0 +#define FW_FLOWC_WR_NPARAMS_V(x) ((x) << FW_FLOWC_WR_NPARAMS_S) + struct fw_ofld_tx_data_wr { __be32 op_to_immdlen; __be32 flowid_len16; __be32 plen; __be32 tunnel_to_proxy; -#define FW_OFLD_TX_DATA_WR_TUNNEL(x) ((x) << 19) -#define FW_OFLD_TX_DATA_WR_SAVE(x) ((x) << 18) -#define FW_OFLD_TX_DATA_WR_FLUSH(x) ((x) << 17) -#define FW_OFLD_TX_DATA_WR_URGENT(x) ((x) << 16) -#define FW_OFLD_TX_DATA_WR_MORE(x) ((x) << 15) -#define FW_OFLD_TX_DATA_WR_SHOVE(x) ((x) << 14) -#define FW_OFLD_TX_DATA_WR_ULPMODE(x) ((x) << 10) -#define FW_OFLD_TX_DATA_WR_ULPSUBMODE(x) ((x) << 6) }; +#define FW_OFLD_TX_DATA_WR_TUNNEL_S 19 +#define FW_OFLD_TX_DATA_WR_TUNNEL_V(x) ((x) << FW_OFLD_TX_DATA_WR_TUNNEL_S) + +#define FW_OFLD_TX_DATA_WR_SAVE_S 18 +#define FW_OFLD_TX_DATA_WR_SAVE_V(x) ((x) << FW_OFLD_TX_DATA_WR_SAVE_S) + +#define FW_OFLD_TX_DATA_WR_FLUSH_S 17 +#define FW_OFLD_TX_DATA_WR_FLUSH_V(x) ((x) << FW_OFLD_TX_DATA_WR_FLUSH_S) +#define FW_OFLD_TX_DATA_WR_FLUSH_F FW_OFLD_TX_DATA_WR_FLUSH_V(1U) + +#define FW_OFLD_TX_DATA_WR_URGENT_S 16 +#define FW_OFLD_TX_DATA_WR_URGENT_V(x) ((x) << FW_OFLD_TX_DATA_WR_URGENT_S) + +#define FW_OFLD_TX_DATA_WR_MORE_S 15 +#define FW_OFLD_TX_DATA_WR_MORE_V(x) ((x) << FW_OFLD_TX_DATA_WR_MORE_S) + +#define FW_OFLD_TX_DATA_WR_SHOVE_S 14 +#define FW_OFLD_TX_DATA_WR_SHOVE_V(x) ((x) << FW_OFLD_TX_DATA_WR_SHOVE_S) +#define FW_OFLD_TX_DATA_WR_SHOVE_F FW_OFLD_TX_DATA_WR_SHOVE_V(1U) + +#define FW_OFLD_TX_DATA_WR_ULPMODE_S 10 +#define FW_OFLD_TX_DATA_WR_ULPMODE_V(x) ((x) << FW_OFLD_TX_DATA_WR_ULPMODE_S) + +#define FW_OFLD_TX_DATA_WR_ULPSUBMODE_S 6 +#define FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(x) \ + ((x) << FW_OFLD_TX_DATA_WR_ULPSUBMODE_S) + struct fw_cmd_wr { __be32 op_dma; #define FW_CMD_WR_DMA (1U << 17) @@ -566,6 +618,9 @@ struct fw_cmd_wr { __be64 cookie_daddr; }; +#define FW_CMD_WR_DMA_S 17 +#define FW_CMD_WR_DMA_V(x) ((x) << FW_CMD_WR_DMA_S) + struct fw_eth_tx_pkt_vm_wr { __be32 op_immdlen; __be32 equiq_to_len16; @@ -641,18 +696,39 @@ struct fw_cmd_hdr { __be32 lo; }; -#define FW_CMD_OP(x) ((x) << 24) -#define FW_CMD_OP_GET(x) (((x) >> 24) & 0xff) -#define FW_CMD_REQUEST (1U << 23) -#define FW_CMD_REQUEST_GET(x) (((x) >> 23) & 0x1) -#define FW_CMD_READ (1U << 22) -#define FW_CMD_WRITE (1U << 21) -#define FW_CMD_EXEC (1U << 20) -#define FW_CMD_RAMASK(x) ((x) << 20) -#define FW_CMD_RETVAL(x) ((x) << 8) -#define FW_CMD_RETVAL_GET(x) (((x) >> 8) & 0xff) -#define FW_CMD_LEN16(x) ((x) << 0) -#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16) +#define FW_CMD_OP_S 24 +#define FW_CMD_OP_M 0xff +#define FW_CMD_OP_V(x) ((x) << FW_CMD_OP_S) +#define FW_CMD_OP_G(x) (((x) >> FW_CMD_OP_S) & FW_CMD_OP_M) + +#define FW_CMD_REQUEST_S 23 +#define FW_CMD_REQUEST_V(x) ((x) << FW_CMD_REQUEST_S) +#define FW_CMD_REQUEST_F FW_CMD_REQUEST_V(1U) + +#define FW_CMD_READ_S 22 +#define FW_CMD_READ_V(x) ((x) << FW_CMD_READ_S) +#define FW_CMD_READ_F FW_CMD_READ_V(1U) + +#define FW_CMD_WRITE_S 21 +#define FW_CMD_WRITE_V(x) ((x) << FW_CMD_WRITE_S) +#define FW_CMD_WRITE_F FW_CMD_WRITE_V(1U) + +#define FW_CMD_EXEC_S 20 +#define FW_CMD_EXEC_V(x) ((x) << FW_CMD_EXEC_S) +#define FW_CMD_EXEC_F FW_CMD_EXEC_V(1U) + +#define FW_CMD_RAMASK_S 20 +#define FW_CMD_RAMASK_V(x) ((x) << FW_CMD_RAMASK_S) + +#define FW_CMD_RETVAL_S 8 +#define FW_CMD_RETVAL_M 0xff +#define FW_CMD_RETVAL_V(x) ((x) << FW_CMD_RETVAL_S) +#define FW_CMD_RETVAL_G(x) (((x) >> FW_CMD_RETVAL_S) & FW_CMD_RETVAL_M) + +#define FW_CMD_LEN16_S 0 +#define FW_CMD_LEN16_V(x) ((x) << FW_CMD_LEN16_S) + +#define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16) enum fw_ldst_addrspc { FW_LDST_ADDRSPC_FIRMWARE = 0x0001, diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 85036e6b42c4..0e8d5b72c9cc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -132,7 +132,7 @@ enum { * we can specify for immediate data in the firmware Ethernet TX * Work Request. */ - MAX_IMM_TX_PKT_LEN = FW_WR_IMMDLEN_MASK, + MAX_IMM_TX_PKT_LEN = FW_WR_IMMDLEN_M, /* * Max size of a WR sent through a control TX queue. @@ -1149,7 +1149,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) goto out_free; } - wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2)); + wr_mid = FW_WR_LEN16_V(DIV_ROUND_UP(flits, 2)); if (unlikely(credits < ETHTXQ_STOP_THRES)) { /* * After we're done injecting the Work Request for this @@ -1161,7 +1161,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) * has opened up. */ txq_stop(txq); - wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ; + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; } /* @@ -1191,9 +1191,9 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN; wr->op_immdlen = - cpu_to_be32(FW_WR_OP(FW_ETH_TX_PKT_VM_WR) | - FW_WR_IMMDLEN(sizeof(*lso) + - sizeof(*cpl))); + cpu_to_be32(FW_WR_OP_V(FW_ETH_TX_PKT_VM_WR) | + FW_WR_IMMDLEN_V(sizeof(*lso) + + sizeof(*cpl))); /* * Fill in the LSO CPL message. */ @@ -1228,8 +1228,8 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl); wr->op_immdlen = - cpu_to_be32(FW_WR_OP(FW_ETH_TX_PKT_VM_WR) | - FW_WR_IMMDLEN(len)); + cpu_to_be32(FW_WR_OP_V(FW_ETH_TX_PKT_VM_WR) | + FW_WR_IMMDLEN_V(len)); /* * Set up TX Packet CPL pointer, control word and perform @@ -2084,10 +2084,10 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, * into OS-independent common code ... */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_IQ_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) | FW_LEN16(cmd)); @@ -2246,10 +2246,10 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, * into the common code ... */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_EQ_ETH_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(cmd)); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 95df61dcb4ce..2cfa4396b003 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -67,7 +67,7 @@ enum chip_type { /* * The "len16" field of a Firmware Command Structure ... */ -#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16) +#define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16) /* * Per-VF statistics. diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index e984fdc48ba2..570b895ae06f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -204,20 +204,20 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, /* return value in low-order little-endian word */ v = t4_read_reg(adapter, mbox_data); - if (FW_CMD_RETVAL_GET(v)) + if (FW_CMD_RETVAL_G(v)) dump_mbox(adapter, "FW Error", mbox_data); if (rpl) { /* request bit in high-order BE word */ WARN_ON((be32_to_cpu(*(const u32 *)cmd) - & FW_CMD_REQUEST) == 0); + & FW_CMD_REQUEST_F) == 0); get_mbox_rpl(adapter, rpl, size, mbox_data); WARN_ON((be32_to_cpu(*(u32 *)rpl) - & FW_CMD_REQUEST) != 0); + & FW_CMD_REQUEST_F) != 0); } t4_write_reg(adapter, mbox_ctl, MBOWNER(MBOX_OWNER_NONE)); - return -FW_CMD_RETVAL_GET(v); + return -FW_CMD_RETVAL_G(v); } } @@ -287,9 +287,9 @@ int t4vf_port_init(struct adapter *adapter, int pidx) * like MAC address, etc. */ memset(&vi_cmd, 0, sizeof(vi_cmd)); - vi_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + vi_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd)); vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(pi->viid)); v = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl); @@ -308,9 +308,9 @@ int t4vf_port_init(struct adapter *adapter, int pidx) return 0; memset(&port_cmd, 0, sizeof(port_cmd)); - port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP(FW_PORT_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_PORT_CMD_PORTID(pi->port_id)); port_cmd.action_to_len16 = cpu_to_be32(FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | @@ -349,8 +349,8 @@ int t4vf_fw_reset(struct adapter *adapter) struct fw_reset_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) | - FW_CMD_WRITE); + cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RESET_CMD) | + FW_CMD_WRITE_F); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); } @@ -377,12 +377,12 @@ static int t4vf_query_params(struct adapter *adapter, unsigned int nparams, return -EINVAL; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd, param[nparams].mnem), 16); - cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16)); + cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) p->mnem = htonl(*params++); @@ -415,12 +415,12 @@ int t4vf_set_params(struct adapter *adapter, unsigned int nparams, return -EINVAL; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F); len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd, param[nparams]), 16); - cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16)); + cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) { p->mnem = cpu_to_be32(*params++); p->val = cpu_to_be32(*vals++); @@ -545,9 +545,9 @@ int t4vf_get_rss_glb_config(struct adapter *adapter) * our RSS configuration. */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RSS_GLB_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); if (v) @@ -621,9 +621,9 @@ int t4vf_get_vfres(struct adapter *adapter) * with error on command failure. */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PFVF_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); if (v) @@ -669,9 +669,9 @@ int t4vf_read_rss_vi_config(struct adapter *adapter, unsigned int viid, int v; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_RSS_VI_CONFIG_CMD_VIID(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); @@ -719,9 +719,9 @@ int t4vf_write_rss_vi_config(struct adapter *adapter, unsigned int viid, struct fw_rss_vi_config_cmd cmd, rpl; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_RSS_VI_CONFIG_CMD_VIID(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); switch (adapter->params.rss.mode) { @@ -777,9 +777,9 @@ int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid, * Initialize firmware command template to write the RSS table. */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_IND_TBL_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_RSS_IND_TBL_CMD_VIID(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); @@ -866,10 +866,10 @@ int t4vf_alloc_vi(struct adapter *adapter, int port_id) * VIID. */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) | FW_VI_CMD_ALLOC); cmd.portid_pkd = FW_VI_CMD_PORTID(port_id); @@ -896,9 +896,9 @@ int t4vf_free_vi(struct adapter *adapter, int viid) * Execute a VI command to free the Virtual Interface. */ memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) | FW_VI_CMD_FREE); cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(viid)); @@ -920,9 +920,9 @@ int t4vf_enable_vi(struct adapter *adapter, unsigned int viid, struct fw_vi_enable_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN(rx_en) | FW_VI_ENABLE_CMD_EEN(tx_en) | @@ -944,9 +944,9 @@ int t4vf_identify_port(struct adapter *adapter, unsigned int viid, struct fw_vi_enable_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED | FW_LEN16(cmd)); @@ -986,9 +986,9 @@ int t4vf_set_rxmode(struct adapter *adapter, unsigned int viid, vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_RXMODE_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_RXMODE_CMD_VIID(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); cmd.mtu_to_vlanexen = @@ -1046,14 +1046,14 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, int i; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | - (free ? FW_CMD_EXEC : 0) | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | + (free ? FW_CMD_EXEC_F : 0) | FW_VI_MAC_CMD_VIID(viid)); cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) | - FW_CMD_LEN16(len16)); + FW_CMD_LEN16_V(len16)); for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) { p->valid_to_idx = cpu_to_be16( @@ -1135,11 +1135,11 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid, idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_MAC_CMD_VIID(viid)); - cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16(len16)); + cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID | FW_VI_MAC_CMD_IDX(idx)); memcpy(p->macaddr, addr, sizeof(p->macaddr)); @@ -1172,13 +1172,13 @@ int t4vf_set_addr_hash(struct adapter *adapter, unsigned int viid, u.exact[0]), 16); memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_VI_ENABLE_CMD_VIID(viid)); cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN | FW_VI_MAC_CMD_HASHUNIEN(ucast) | - FW_CMD_LEN16(len16)); + FW_CMD_LEN16_V(len16)); cmd.u.hash.hashvec = cpu_to_be64(vec); return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok); } @@ -1214,11 +1214,11 @@ int t4vf_get_port_stats(struct adapter *adapter, int pidx, int ret; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_STATS_CMD) | + cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_STATS_CMD) | FW_VI_STATS_CMD_VIID(pi->viid) | - FW_CMD_REQUEST | - FW_CMD_READ); - cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16)); + FW_CMD_REQUEST_F | + FW_CMD_READ_F); + cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); cmd.u.ctl.nstats_ix = cpu_to_be16(FW_VI_STATS_CMD_IX(ix) | FW_VI_STATS_CMD_NSTATS(nstats)); @@ -1273,9 +1273,9 @@ int t4vf_iq_free(struct adapter *adapter, unsigned int iqtype, struct fw_iq_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_IQ_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE | FW_LEN16(cmd)); cmd.type_to_iqandstindex = @@ -1299,9 +1299,9 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) struct fw_eq_eth_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_EQ_ETH_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC); + cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE | FW_LEN16(cmd)); cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID(eqid)); @@ -1318,7 +1318,7 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) { const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl; - u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi)); + u8 opcode = FW_CMD_OP_G(be32_to_cpu(cmd_hdr->hi)); switch (opcode) { case FW_PORT_CMD: { diff --git a/drivers/scsi/csiostor/csio_attr.c b/drivers/scsi/csiostor/csio_attr.c index 065a87ace623..2d1c4ebd40f9 100644 --- a/drivers/scsi/csiostor/csio_attr.c +++ b/drivers/scsi/csiostor/csio_attr.c @@ -451,9 +451,9 @@ csio_fcoe_alloc_vnp(struct csio_hw *hw, struct csio_lnode *ln) /* Process Mbox response of VNP command */ rsp = (struct fw_fcoe_vnp_cmd *)(mbp->mb); - if (FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16)) != FW_SUCCESS) { + if (FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)) != FW_SUCCESS) { csio_ln_err(ln, "FCOE VNP ALLOC cmd returned 0x%x!\n", - FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16))); + FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16))); ret = -EINVAL; goto out_free; } @@ -526,9 +526,9 @@ csio_fcoe_free_vnp(struct csio_hw *hw, struct csio_lnode *ln) /* Process Mbox response of VNP command */ rsp = (struct fw_fcoe_vnp_cmd *)(mbp->mb); - if (FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16)) != FW_SUCCESS) { + if (FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)) != FW_SUCCESS) { csio_ln_err(ln, "FCOE VNP FREE cmd returned 0x%x!\n", - FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16))); + FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16))); ret = -EINVAL; } diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 0eaec4748957..5f06877aa7c4 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -1370,9 +1370,9 @@ csio_hw_fw_config_file(struct csio_hw *hw, caps_cmd = (struct fw_caps_config_cmd *)(mbp->mb); CSIO_INIT_MBP(mbp, caps_cmd, CSIO_MB_DEFAULT_TMO, hw, NULL, 1); caps_cmd->op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ); + htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F); caps_cmd->cfvalid_to_len16 = htonl(FW_CAPS_CONFIG_CMD_CFVALID | FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | @@ -1407,9 +1407,9 @@ csio_hw_fw_config_file(struct csio_hw *hw, * And now tell the firmware to use the configuration we just loaded. */ caps_cmd->op_to_write = - htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE); + htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F); caps_cmd->cfvalid_to_len16 = htonl(FW_LEN16(*caps_cmd)); if (csio_mb_issue(hw, mbp)) { @@ -1678,7 +1678,7 @@ csio_get_fcoe_resinfo(struct csio_hw *hw) } rsp = (struct fw_fcoe_res_info_cmd *)(mbp->mb); - retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16)); + retval = FW_CMD_RETVAL_G(ntohl(rsp->retval_len16)); if (retval != FW_SUCCESS) { csio_err(hw, "FW_FCOE_RES_INFO_CMD failed with ret x%x\n", retval); diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index ffe9be04dc39..48e45b1ea4e5 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -603,7 +603,7 @@ csio_ln_vnp_read_cbfn(struct csio_hw *hw, struct csio_mb *mbp) enum fw_retval retval; __be32 nport_id; - retval = FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16)); + retval = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (retval != FW_SUCCESS) { csio_err(hw, "FCOE VNP read cmd returned error:0x%x\n", retval); mempool_free(mbp, hw->mb_mempool); @@ -770,7 +770,7 @@ csio_ln_read_fcf_cbfn(struct csio_hw *hw, struct csio_mb *mbp) (struct fw_fcoe_fcf_cmd *)(mbp->mb); enum fw_retval retval; - retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16)); + retval = FW_CMD_RETVAL_G(ntohl(rsp->retval_len16)); if (retval != FW_SUCCESS) { csio_ln_err(ln, "FCOE FCF cmd failed with ret x%x\n", retval); @@ -1506,7 +1506,7 @@ csio_fcoe_fwevt_handler(struct csio_hw *hw, __u8 cpl_op, __be64 *cmd) } } else if (cpl_op == CPL_FW6_PLD) { wr = (struct fw_wr_hdr *) (cmd + 4); - if (FW_WR_OP_GET(be32_to_cpu(wr->hi)) + if (FW_WR_OP_G(be32_to_cpu(wr->hi)) == FW_RDEV_WR) { rdev_wr = (struct fw_rdev_wr *) (cmd + 4); @@ -1574,17 +1574,17 @@ csio_fcoe_fwevt_handler(struct csio_hw *hw, __u8 cpl_op, __be64 *cmd) return; } else { csio_warn(hw, "unexpected WR op(0x%x) recv\n", - FW_WR_OP_GET(be32_to_cpu((wr->hi)))); + FW_WR_OP_G(be32_to_cpu((wr->hi)))); CSIO_INC_STATS(hw, n_cpl_unexp); } } else if (cpl_op == CPL_FW6_MSG) { wr = (struct fw_wr_hdr *) (cmd); - if (FW_WR_OP_GET(be32_to_cpu(wr->hi)) == FW_FCOE_ELS_CT_WR) { + if (FW_WR_OP_G(be32_to_cpu(wr->hi)) == FW_FCOE_ELS_CT_WR) { csio_ln_mgmt_wr_handler(hw, wr, sizeof(struct fw_fcoe_els_ct_wr)); } else { csio_warn(hw, "unexpected WR op(0x%x) recv\n", - FW_WR_OP_GET(be32_to_cpu((wr->hi)))); + FW_WR_OP_G(be32_to_cpu((wr->hi)))); CSIO_INC_STATS(hw, n_cpl_unexp); } } else { @@ -1668,12 +1668,12 @@ csio_ln_prep_ecwr(struct csio_ioreq *io_req, uint32_t wr_len, __be32 port_id; wr = (struct fw_fcoe_els_ct_wr *)fw_wr; - wr->op_immdlen = cpu_to_be32(FW_WR_OP(FW_FCOE_ELS_CT_WR) | + wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_FCOE_ELS_CT_WR) | FW_FCOE_ELS_CT_WR_IMMDLEN(immd_len)); wr_len = DIV_ROUND_UP(wr_len, 16); - wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID(flow_id) | - FW_WR_LEN16(wr_len)); + wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(flow_id) | + FW_WR_LEN16_V(wr_len)); wr->els_ct_type = sub_op; wr->ctl_pri = 0; wr->cp_en_class = 0; diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index 15b635142546..ffa848987608 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -59,7 +59,7 @@ csio_mb_fw_retval(struct csio_mb *mbp) hdr = (struct fw_cmd_hdr *)(mbp->mb); - return FW_CMD_RETVAL_GET(ntohl(hdr->lo)); + return FW_CMD_RETVAL_G(ntohl(hdr->lo)); } /* @@ -81,9 +81,9 @@ csio_mb_hello(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_write = htonl(FW_CMD_OP(FW_HELLO_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->op_to_write = htonl(FW_CMD_OP_V(FW_HELLO_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->err_to_clearinit = htonl( FW_HELLO_CMD_MASTERDIS(master == CSIO_MASTER_CANT) | FW_HELLO_CMD_MASTERFORCE(master == CSIO_MASTER_MUST) | @@ -112,7 +112,7 @@ csio_mb_process_hello_rsp(struct csio_hw *hw, struct csio_mb *mbp, struct fw_hello_cmd *rsp = (struct fw_hello_cmd *)(mbp->mb); uint32_t value; - *retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16)); + *retval = FW_CMD_RETVAL_G(ntohl(rsp->retval_len16)); if (*retval == FW_SUCCESS) { hw->fwrev = ntohl(rsp->fwrev); @@ -144,9 +144,9 @@ csio_mb_bye(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_write = htonl(FW_CMD_OP(FW_BYE_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->op_to_write = htonl(FW_CMD_OP_V(FW_BYE_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } @@ -167,9 +167,9 @@ csio_mb_reset(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_write = htonl(FW_CMD_OP(FW_RESET_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->op_to_write = htonl(FW_CMD_OP_V(FW_RESET_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->val = htonl(reset); cmdp->halt_pkd = htonl(halt); @@ -202,12 +202,12 @@ csio_mb_params(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | - FW_CMD_REQUEST | - (wr ? FW_CMD_WRITE : FW_CMD_READ) | + cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | + FW_CMD_REQUEST_F | + (wr ? FW_CMD_WRITE_F : FW_CMD_READ_F) | FW_PARAMS_CMD_PFN(pf) | FW_PARAMS_CMD_VFN(vf)); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); /* Write Params */ if (wr) { @@ -245,7 +245,7 @@ csio_mb_process_read_params_rsp(struct csio_hw *hw, struct csio_mb *mbp, uint32_t i; __be32 *p = &rsp->param[0].val; - *retval = FW_CMD_RETVAL_GET(ntohl(rsp->retval_len16)); + *retval = FW_CMD_RETVAL_G(ntohl(rsp->retval_len16)); if (*retval == FW_SUCCESS) for (i = 0; i < nparams; i++, p += 2) @@ -271,9 +271,9 @@ csio_mb_ldst(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, int reg) * specified PCI-E Configuration Space register. */ ldst_cmd->op_to_addrspace = - htonl(FW_CMD_OP(FW_LDST_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + htonl(FW_CMD_OP_V(FW_LDST_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE)); ldst_cmd->cycles_to_len16 = htonl(FW_LEN16(struct fw_ldst_cmd)); ldst_cmd->u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1); @@ -306,10 +306,10 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, wr ? 0 : 1); - cmdp->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | - FW_CMD_REQUEST | - (wr ? FW_CMD_WRITE : FW_CMD_READ)); - cmdp->cfvalid_to_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->op_to_write = htonl(FW_CMD_OP_V(FW_CAPS_CONFIG_CMD) | + FW_CMD_REQUEST_F | + (wr ? FW_CMD_WRITE_F : FW_CMD_READ_F)); + cmdp->cfvalid_to_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); /* Read config */ if (!wr) @@ -351,21 +351,21 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | - FW_CMD_REQUEST | - (wr ? FW_CMD_EXEC : FW_CMD_READ) | + cmdp->op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | + FW_CMD_REQUEST_F | + (wr ? FW_CMD_EXEC_F : FW_CMD_READ_F) | FW_PORT_CMD_PORTID(portid)); if (!wr) { cmdp->action_to_len16 = htonl( FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); return; } /* Set port */ cmdp->action_to_len16 = htonl( FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); if (fc & PAUSE_RX) lfc |= FW_PORT_CAP_FC_RX; @@ -393,7 +393,7 @@ csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp, { struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb); - *retval = FW_CMD_RETVAL_GET(ntohl(rsp->action_to_len16)); + *retval = FW_CMD_RETVAL_G(ntohl(rsp->action_to_len16)); if (*retval == FW_SUCCESS) *caps = ntohs(rsp->u.info.pcap); @@ -415,9 +415,9 @@ csio_mb_initialize(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); - cmdp->op_to_write = htonl(FW_CMD_OP(FW_INITIALIZE_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->op_to_write = htonl(FW_CMD_OP_V(FW_INITIALIZE_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } @@ -443,13 +443,13 @@ csio_mb_iq_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | - FW_CMD_REQUEST | FW_CMD_EXEC | + cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | + FW_CMD_REQUEST_F | FW_CMD_EXEC_F | FW_IQ_CMD_PFN(iq_params->pfn) | FW_IQ_CMD_VFN(iq_params->vfn)); cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->type_to_iqandstindex = htonl( FW_IQ_CMD_VIID(iq_params->viid) | @@ -499,12 +499,12 @@ csio_mb_iq_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, if (!cascaded_req) CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn |= htonl(FW_CMD_OP(FW_IQ_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE | + cmdp->op_to_vfn |= htonl(FW_CMD_OP_V(FW_IQ_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_IQ_CMD_PFN(iq_params->pfn) | FW_IQ_CMD_VFN(iq_params->vfn)); cmdp->alloc_to_len16 |= htonl(iq_start_stop | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->iqid |= htons(iq_params->iqid); cmdp->fl0id |= htons(iq_params->fl0id); cmdp->fl1id |= htons(iq_params->fl1id); @@ -588,7 +588,7 @@ csio_mb_iq_alloc_write_rsp(struct csio_hw *hw, struct csio_mb *mbp, { struct fw_iq_cmd *rsp = (struct fw_iq_cmd *)(mbp->mb); - *ret_val = FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16)); + *ret_val = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (*ret_val == FW_SUCCESS) { iq_params->physiqid = ntohs(rsp->physiqid); iq_params->iqid = ntohs(rsp->iqid); @@ -622,12 +622,12 @@ csio_mb_iq_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | - FW_CMD_REQUEST | FW_CMD_EXEC | + cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | + FW_CMD_REQUEST_F | FW_CMD_EXEC_F | FW_IQ_CMD_PFN(iq_params->pfn) | FW_IQ_CMD_VFN(iq_params->vfn)); cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_FREE | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iq_params->type)); cmdp->iqid = htons(iq_params->iqid); @@ -657,12 +657,12 @@ csio_mb_eq_ofld_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv, struct fw_eq_ofld_cmd *cmdp = (struct fw_eq_ofld_cmd *)(mbp->mb); CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | - FW_CMD_REQUEST | FW_CMD_EXEC | + cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | + FW_CMD_REQUEST_F | FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } /* csio_mb_eq_ofld_alloc */ @@ -704,12 +704,12 @@ csio_mb_eq_ofld_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, if (!cascaded_req) CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn |= htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | - FW_CMD_REQUEST | FW_CMD_WRITE | + cmdp->op_to_vfn |= htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | + FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); cmdp->alloc_to_len16 |= htonl(eq_start_stop | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->eqid_pkd |= htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid)); @@ -773,7 +773,7 @@ csio_mb_eq_ofld_alloc_write_rsp(struct csio_hw *hw, { struct fw_eq_ofld_cmd *rsp = (struct fw_eq_ofld_cmd *)(mbp->mb); - *ret_val = FW_CMD_RETVAL_GET(ntohl(rsp->alloc_to_len16)); + *ret_val = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (*ret_val == FW_SUCCESS) { eq_ofld_params->eqid = FW_EQ_OFLD_CMD_EQID_GET( @@ -807,12 +807,12 @@ csio_mb_eq_ofld_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); - cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | - FW_CMD_REQUEST | FW_CMD_EXEC | + cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | + FW_CMD_REQUEST_F | FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid)); } /* csio_mb_eq_ofld_free */ @@ -840,15 +840,15 @@ csio_write_fcoe_link_cond_init_mb(struct csio_lnode *ln, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1); cmdp->op_to_portid = htonl(( - FW_CMD_OP(FW_FCOE_LINK_CMD) | - FW_CMD_REQUEST | - FW_CMD_WRITE | + FW_CMD_OP_V(FW_FCOE_LINK_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_WRITE_F | FW_FCOE_LINK_CMD_PORTID(port_id))); cmdp->sub_opcode_fcfi = htonl( FW_FCOE_LINK_CMD_SUB_OPCODE(sub_opcode) | FW_FCOE_LINK_CMD_FCFI(fcfi)); cmdp->lstatus = link_status; - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } /* csio_write_fcoe_link_cond_init_mb */ @@ -873,11 +873,11 @@ csio_fcoe_read_res_info_init_mb(struct csio_hw *hw, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, hw, cbfn, 1); - cmdp->op_to_read = htonl((FW_CMD_OP(FW_FCOE_RES_INFO_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ)); + cmdp->op_to_read = htonl((FW_CMD_OP_V(FW_FCOE_RES_INFO_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F)); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } /* csio_fcoe_read_res_info_init_mb */ @@ -908,13 +908,13 @@ csio_fcoe_vnp_alloc_init_mb(struct csio_lnode *ln, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1); - cmdp->op_to_fcfi = htonl((FW_CMD_OP(FW_FCOE_VNP_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC | + cmdp->op_to_fcfi = htonl((FW_CMD_OP_V(FW_FCOE_VNP_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_FCOE_VNP_CMD_FCFI(fcfi))); cmdp->alloc_to_len16 = htonl(FW_FCOE_VNP_CMD_ALLOC | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi)); @@ -948,11 +948,11 @@ csio_fcoe_vnp_read_init_mb(struct csio_lnode *ln, struct csio_mb *mbp, (struct fw_fcoe_vnp_cmd *)(mbp->mb); CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1); - cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_VNP_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + cmdp->op_to_fcfi = htonl(FW_CMD_OP_V(FW_FCOE_VNP_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_FCOE_VNP_CMD_FCFI(fcfi)); - cmdp->alloc_to_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->alloc_to_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi)); } @@ -978,12 +978,12 @@ csio_fcoe_vnp_free_init_mb(struct csio_lnode *ln, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1); - cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_VNP_CMD) | - FW_CMD_REQUEST | - FW_CMD_EXEC | + cmdp->op_to_fcfi = htonl(FW_CMD_OP_V(FW_FCOE_VNP_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_FCOE_VNP_CMD_FCFI(fcfi)); cmdp->alloc_to_len16 = htonl(FW_FCOE_VNP_CMD_FREE | - FW_CMD_LEN16(sizeof(*cmdp) / 16)); + FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->gen_wwn_to_vnpi = htonl(FW_FCOE_VNP_CMD_VNPI(vnpi)); } @@ -1009,11 +1009,11 @@ csio_fcoe_read_fcf_init_mb(struct csio_lnode *ln, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, ln, cbfn, 1); - cmdp->op_to_fcfi = htonl(FW_CMD_OP(FW_FCOE_FCF_CMD) | - FW_CMD_REQUEST | - FW_CMD_READ | + cmdp->op_to_fcfi = htonl(FW_CMD_OP_V(FW_FCOE_FCF_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | FW_FCOE_FCF_CMD_FCFI(fcfi)); - cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16)); + cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } /* csio_fcoe_read_fcf_init_mb */ @@ -1029,9 +1029,9 @@ csio_fcoe_read_portparams_init_mb(struct csio_hw *hw, struct csio_mb *mbp, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, hw, cbfn, 1); mbp->mb_size = 64; - cmdp->op_to_flowid = htonl(FW_CMD_OP(FW_FCOE_STATS_CMD) | - FW_CMD_REQUEST | FW_CMD_READ); - cmdp->free_to_len16 = htonl(FW_CMD_LEN16(CSIO_MAX_MB_SIZE/16)); + cmdp->op_to_flowid = htonl(FW_CMD_OP_V(FW_FCOE_STATS_CMD) | + FW_CMD_REQUEST_F | FW_CMD_READ_F); + cmdp->free_to_len16 = htonl(FW_CMD_LEN16_V(CSIO_MAX_MB_SIZE/16)); cmdp->u.ctl.nstats_port = FW_FCOE_STATS_CMD_NSTATS(portparams->nstats) | FW_FCOE_STATS_CMD_PORT(portparams->portid); @@ -1053,7 +1053,7 @@ csio_mb_process_portparams_rsp(struct csio_hw *hw, uint8_t *src; uint8_t *dst; - *retval = FW_CMD_RETVAL_GET(ntohl(rsp->free_to_len16)); + *retval = FW_CMD_RETVAL_G(ntohl(rsp->free_to_len16)); memset(&stats, 0, sizeof(struct fw_fcoe_port_stats)); @@ -1305,7 +1305,7 @@ csio_mb_issue(struct csio_hw *hw, struct csio_mb *mbp) hdr = cpu_to_be64(csio_rd_reg64(hw, data_reg)); fw_hdr = (struct fw_cmd_hdr *)&hdr; - switch (FW_CMD_OP_GET(ntohl(fw_hdr->hi))) { + switch (FW_CMD_OP_G(ntohl(fw_hdr->hi))) { case FW_DEBUG_CMD: csio_mb_debug_cmd_handler(hw); continue; @@ -1498,7 +1498,7 @@ csio_mb_isr_handler(struct csio_hw *hw) hdr = cpu_to_be64(csio_rd_reg64(hw, data_reg)); fw_hdr = (struct fw_cmd_hdr *)&hdr; - switch (FW_CMD_OP_GET(ntohl(fw_hdr->hi))) { + switch (FW_CMD_OP_G(ntohl(fw_hdr->hi))) { case FW_DEBUG_CMD: csio_mb_debug_cmd_handler(hw); return -EINVAL; @@ -1571,11 +1571,11 @@ csio_mb_tmo_handler(struct csio_hw *hw) fw_hdr = (struct fw_cmd_hdr *)(mbp->mb); csio_dbg(hw, "Mailbox num:%x op:0x%x timed out\n", hw->pfn, - FW_CMD_OP_GET(ntohl(fw_hdr->hi))); + FW_CMD_OP_G(ntohl(fw_hdr->hi))); mbm->mcurrent = NULL; CSIO_INC_STATS(mbm, n_tmo); - fw_hdr->lo = htonl(FW_CMD_RETVAL(FW_ETIMEDOUT)); + fw_hdr->lo = htonl(FW_CMD_RETVAL_V(FW_ETIMEDOUT)); return mbp; } @@ -1624,10 +1624,10 @@ csio_mb_cancel_all(struct csio_hw *hw, struct list_head *cbfn_q) hdr = (struct fw_cmd_hdr *)(mbp->mb); csio_dbg(hw, "Cancelling pending mailbox num %x op:%x\n", - hw->pfn, FW_CMD_OP_GET(ntohl(hdr->hi))); + hw->pfn, FW_CMD_OP_G(ntohl(hdr->hi))); CSIO_INC_STATS(mbm, n_cancel); - hdr->lo = htonl(FW_CMD_RETVAL(FW_HOSTERROR)); + hdr->lo = htonl(FW_CMD_RETVAL_V(FW_HOSTERROR)); } } diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 86103c8475d8..b37c69a2772a 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -230,10 +230,10 @@ csio_scsi_init_cmd_wr(struct csio_ioreq *req, void *addr, uint32_t size) struct csio_dma_buf *dma_buf; uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len; - wr->op_immdlen = cpu_to_be32(FW_WR_OP(FW_SCSI_CMD_WR) | + wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_CMD_WR) | FW_SCSI_CMD_WR_IMMDLEN(imm)); - wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID(rn->flowid) | - FW_WR_LEN16( + wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) | + FW_WR_LEN16_V( DIV_ROUND_UP(size, 16))); wr->cookie = (uintptr_t) req; @@ -391,10 +391,10 @@ csio_scsi_init_read_wr(struct csio_ioreq *req, void *wrp, uint32_t size) uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len; struct scsi_cmnd *scmnd = csio_scsi_cmnd(req); - wr->op_immdlen = cpu_to_be32(FW_WR_OP(FW_SCSI_READ_WR) | + wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_READ_WR) | FW_SCSI_READ_WR_IMMDLEN(imm)); - wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID(rn->flowid) | - FW_WR_LEN16(DIV_ROUND_UP(size, 16))); + wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) | + FW_WR_LEN16_V(DIV_ROUND_UP(size, 16))); wr->cookie = (uintptr_t)req; wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx)); wr->tmo_val = (uint8_t)(req->tmo); @@ -444,10 +444,10 @@ csio_scsi_init_write_wr(struct csio_ioreq *req, void *wrp, uint32_t size) uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len; struct scsi_cmnd *scmnd = csio_scsi_cmnd(req); - wr->op_immdlen = cpu_to_be32(FW_WR_OP(FW_SCSI_WRITE_WR) | + wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_WRITE_WR) | FW_SCSI_WRITE_WR_IMMDLEN(imm)); - wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID(rn->flowid) | - FW_WR_LEN16(DIV_ROUND_UP(size, 16))); + wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) | + FW_WR_LEN16_V(DIV_ROUND_UP(size, 16))); wr->cookie = (uintptr_t)req; wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx)); wr->tmo_val = (uint8_t)(req->tmo); @@ -674,9 +674,9 @@ csio_scsi_init_abrt_cls_wr(struct csio_ioreq *req, void *addr, uint32_t size, struct csio_rnode *rn = req->rnode; struct fw_scsi_abrt_cls_wr *wr = (struct fw_scsi_abrt_cls_wr *)addr; - wr->op_immdlen = cpu_to_be32(FW_WR_OP(FW_SCSI_ABRT_CLS_WR)); - wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID(rn->flowid) | - FW_WR_LEN16( + wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_ABRT_CLS_WR)); + wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) | + FW_WR_LEN16_V( DIV_ROUND_UP(size, 16))); wr->cookie = (uintptr_t) req; diff --git a/drivers/scsi/csiostor/csio_wr.h b/drivers/scsi/csiostor/csio_wr.h index 8d30e7ac1f5e..0c0dd9a658cc 100644 --- a/drivers/scsi/csiostor/csio_wr.h +++ b/drivers/scsi/csiostor/csio_wr.h @@ -101,7 +101,7 @@ /* WR status is at the same position as retval in a CMD header */ #define csio_wr_status(_wr) \ - (FW_CMD_RETVAL_GET(ntohl(((struct fw_cmd_hdr *)(_wr))->lo))) + (FW_CMD_RETVAL_G(ntohl(((struct fw_cmd_hdr *)(_wr))->lo))) struct csio_hw; diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 3e0a0d315f72..ccacf09c2c16 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -499,10 +499,10 @@ static inline void send_tx_flowc_wr(struct cxgbi_sock *csk) skb = alloc_wr(flowclen, 0, GFP_ATOMIC); flowc = (struct fw_flowc_wr *)skb->head; flowc->op_to_nparams = - htonl(FW_WR_OP(FW_FLOWC_WR) | FW_FLOWC_WR_NPARAMS(8)); + htonl(FW_WR_OP_V(FW_FLOWC_WR) | FW_FLOWC_WR_NPARAMS_V(8)); flowc->flowid_len16 = - htonl(FW_WR_LEN16(DIV_ROUND_UP(72, 16)) | - FW_WR_FLOWID(csk->tid)); + htonl(FW_WR_LEN16_V(DIV_ROUND_UP(72, 16)) | + FW_WR_FLOWID_V(csk->tid)); flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN; flowc->mnemval[0].val = htonl(csk->cdev->pfvf); flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH; @@ -542,30 +542,31 @@ static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb, { struct fw_ofld_tx_data_wr *req; unsigned int submode = cxgbi_skcb_ulp_mode(skb) & 3; - unsigned int wr_ulp_mode = 0; + unsigned int wr_ulp_mode = 0, val; req = (struct fw_ofld_tx_data_wr *)__skb_push(skb, sizeof(*req)); if (is_ofld_imm(skb)) { - req->op_to_immdlen = htonl(FW_WR_OP(FW_OFLD_TX_DATA_WR) | - FW_WR_COMPL(1) | - FW_WR_IMMDLEN(dlen)); - req->flowid_len16 = htonl(FW_WR_FLOWID(csk->tid) | - FW_WR_LEN16(credits)); + req->op_to_immdlen = htonl(FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | + FW_WR_COMPL_F | + FW_WR_IMMDLEN_V(dlen)); + req->flowid_len16 = htonl(FW_WR_FLOWID_V(csk->tid) | + FW_WR_LEN16_V(credits)); } else { req->op_to_immdlen = - cpu_to_be32(FW_WR_OP(FW_OFLD_TX_DATA_WR) | - FW_WR_COMPL(1) | - FW_WR_IMMDLEN(0)); + cpu_to_be32(FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | + FW_WR_COMPL_F | + FW_WR_IMMDLEN_V(0)); req->flowid_len16 = - cpu_to_be32(FW_WR_FLOWID(csk->tid) | - FW_WR_LEN16(credits)); + cpu_to_be32(FW_WR_FLOWID_V(csk->tid) | + FW_WR_LEN16_V(credits)); } if (submode) - wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE(ULP2_MODE_ISCSI) | - FW_OFLD_TX_DATA_WR_ULPSUBMODE(submode); + wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE_V(ULP2_MODE_ISCSI) | + FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(submode); + val = skb_peek(&csk->write_queue) ? 0 : 1; req->tunnel_to_proxy = htonl(wr_ulp_mode | - FW_OFLD_TX_DATA_WR_SHOVE(skb_peek(&csk->write_queue) ? 0 : 1)); + FW_OFLD_TX_DATA_WR_SHOVE_V(val)); req->plen = htonl(len); if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT); -- GitLab From 4483589f7123a73955095d8bb1e31390a48c7568 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 6 Nov 2014 20:46:14 -0800 Subject: [PATCH 4150/9457] cxgb4: Remove unnecessary struct in6_addr * casts Just use the address of the in6_addr. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 350f9c204402..a9c117fdf77c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4310,8 +4310,7 @@ static int clip_add(struct net_device *event_dev, struct inet6_ifaddr *ifa, if (cxgb4_netdev(event_dev)) { switch (event) { case NETDEV_UP: - ret = cxgb4_clip_get(event_dev, - (const struct in6_addr *)ifa->addr.s6_addr); + ret = cxgb4_clip_get(event_dev, &ifa->addr); if (ret < 0) { rcu_read_unlock(); return ret; @@ -4319,8 +4318,7 @@ static int clip_add(struct net_device *event_dev, struct inet6_ifaddr *ifa, ret = NOTIFY_OK; break; case NETDEV_DOWN: - cxgb4_clip_release(event_dev, - (const struct in6_addr *)ifa->addr.s6_addr); + cxgb4_clip_release(event_dev, &ifa->addr); ret = NOTIFY_OK; break; default: @@ -4389,8 +4387,7 @@ static int update_dev_clip(struct net_device *root_dev, struct net_device *dev) read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { - ret = cxgb4_clip_get(dev, - (const struct in6_addr *)ifa->addr.s6_addr); + ret = cxgb4_clip_get(dev, &ifa->addr); if (ret < 0) break; } -- GitLab From 1ef8019be8799c39f316a772ffdd705c46029752 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 10 Nov 2014 13:27:49 -0500 Subject: [PATCH 4151/9457] net: Move bonding headers under include/net This ways drivers like cxgb4 don't need to do ugly relative includes. Reported-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 4 ++-- drivers/net/bonding/bond_alb.c | 4 ++-- drivers/net/bonding/bond_debugfs.c | 4 ++-- drivers/net/bonding/bond_main.c | 6 +++--- drivers/net/bonding/bond_netlink.c | 2 +- drivers/net/bonding/bond_options.c | 2 +- drivers/net/bonding/bond_procfs.c | 2 +- drivers/net/bonding/bond_sysfs.c | 2 +- drivers/net/bonding/bond_sysfs_slave.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 +-- {drivers/net/bonding => include/net}/bond_3ad.h | 6 +++--- {drivers/net/bonding => include/net}/bond_alb.h | 6 +++--- {drivers/net/bonding => include/net}/bond_options.h | 6 +++--- {drivers/net/bonding => include/net}/bonding.h | 12 ++++++------ 14 files changed, 30 insertions(+), 31 deletions(-) rename {drivers/net/bonding => include/net}/bond_3ad.h (99%) rename {drivers/net/bonding => include/net}/bond_alb.h (98%) rename {drivers/net/bonding => include/net}/bond_options.h (97%) rename {drivers/net/bonding => include/net}/bonding.h (99%) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 2110215f3528..0a32143af12b 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -29,8 +29,8 @@ #include #include #include -#include "bonding.h" -#include "bond_3ad.h" +#include +#include /* General definitions */ #define AD_SHORT_TIMEOUT 1 diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index baa58e79256a..e1f1a006af85 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -37,8 +37,8 @@ #include #include #include -#include "bonding.h" -#include "bond_alb.h" +#include +#include diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c index 8f99082f90eb..e52e25a977fa 100644 --- a/drivers/net/bonding/bond_debugfs.c +++ b/drivers/net/bonding/bond_debugfs.c @@ -3,8 +3,8 @@ #include #include -#include "bonding.h" -#include "bond_alb.h" +#include +#include #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c7520082fb0d..b9b34566b9b8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -77,9 +77,9 @@ #include #include #include -#include "bonding.h" -#include "bond_3ad.h" -#include "bond_alb.h" +#include +#include +#include /*---------------------------- Module parameters ----------------------------*/ diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index c13d83e15ace..3e6eebd5be50 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -17,7 +17,7 @@ #include #include #include -#include "bonding.h" +#include static size_t bond_get_slave_size(const struct net_device *bond_dev, const struct net_device *slave_dev) diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index b62697f4a3de..1a61cc9b3402 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -16,7 +16,7 @@ #include #include #include -#include "bonding.h" +#include static int bond_option_active_slave_set(struct bonding *bond, const struct bond_opt_value *newval); diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index a3948f8d1e53..976f5ad2a0f2 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -2,7 +2,7 @@ #include #include #include -#include "bonding.h" +#include static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 8ffbafd500fd..7e9e151d4d61 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -40,7 +40,7 @@ #include #include -#include "bonding.h" +#include #define to_dev(obj) container_of(obj, struct device, kobj) #define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd)))) diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c index b01b0ce4d1be..23618a831612 100644 --- a/drivers/net/bonding/bond_sysfs_slave.c +++ b/drivers/net/bonding/bond_sysfs_slave.c @@ -12,7 +12,7 @@ #include #include -#include "bonding.h" +#include struct slave_attribute { struct attribute attr; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a9c117fdf77c..d13d36abe55c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include "cxgb4.h" @@ -71,8 +72,6 @@ #include "cxgb4_debugfs.h" #include "l2t.h" -#include <../drivers/net/bonding/bonding.h> - #ifdef DRV_VERSION #undef DRV_VERSION #endif diff --git a/drivers/net/bonding/bond_3ad.h b/include/net/bond_3ad.h similarity index 99% rename from drivers/net/bonding/bond_3ad.h rename to include/net/bond_3ad.h index c5f14ac63f3e..e01d903633ef 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/include/net/bond_3ad.h @@ -20,8 +20,8 @@ * */ -#ifndef __BOND_3AD_H__ -#define __BOND_3AD_H__ +#ifndef _NET_BOND_3AD_H +#define _NET_BOND_3AD_H #include #include @@ -279,5 +279,5 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); int bond_3ad_set_carrier(struct bonding *bond); void bond_3ad_update_lacp_rate(struct bonding *bond); -#endif /* __BOND_3AD_H__ */ +#endif /* _NET_BOND_3AD_H */ diff --git a/drivers/net/bonding/bond_alb.h b/include/net/bond_alb.h similarity index 98% rename from drivers/net/bonding/bond_alb.h rename to include/net/bond_alb.h index 1ad473b4ade5..313a8d3b3069 100644 --- a/drivers/net/bonding/bond_alb.h +++ b/include/net/bond_alb.h @@ -19,8 +19,8 @@ * */ -#ifndef __BOND_ALB_H__ -#define __BOND_ALB_H__ +#ifndef _NET_BOND_ALB_H +#define _NET_BOND_ALB_H #include @@ -177,5 +177,5 @@ int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev); void bond_alb_monitor(struct work_struct *); int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr); void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id); -#endif /* __BOND_ALB_H__ */ +#endif /* _NET_BOND_ALB_H */ diff --git a/drivers/net/bonding/bond_options.h b/include/net/bond_options.h similarity index 97% rename from drivers/net/bonding/bond_options.h rename to include/net/bond_options.h index 17ded5b29176..ea6546d2c946 100644 --- a/drivers/net/bonding/bond_options.h +++ b/include/net/bond_options.h @@ -8,8 +8,8 @@ * (at your option) any later version. */ -#ifndef _BOND_OPTIONS_H -#define _BOND_OPTIONS_H +#ifndef _NET_BOND_OPTIONS_H +#define _NET_BOND_OPTIONS_H #define BOND_OPT_MAX_NAMELEN 32 #define BOND_OPT_VALID(opt) ((opt) < BOND_OPT_LAST) @@ -127,4 +127,4 @@ static inline void __bond_opt_init(struct bond_opt_value *optval, void bond_option_arp_ip_targets_clear(struct bonding *bond); -#endif /* _BOND_OPTIONS_H */ +#endif /* _NET_BOND_OPTIONS_H */ diff --git a/drivers/net/bonding/bonding.h b/include/net/bonding.h similarity index 99% rename from drivers/net/bonding/bonding.h rename to include/net/bonding.h index bfb0b51c081a..983a94b86b95 100644 --- a/drivers/net/bonding/bonding.h +++ b/include/net/bonding.h @@ -12,8 +12,8 @@ * */ -#ifndef _LINUX_BONDING_H -#define _LINUX_BONDING_H +#ifndef _NET_BONDING_H +#define _NET_BONDING_H #include #include @@ -26,9 +26,9 @@ #include #include -#include "bond_3ad.h" -#include "bond_alb.h" -#include "bond_options.h" +#include +#include +#include #define DRV_VERSION "3.7.1" #define DRV_RELDATE "April 27, 2011" @@ -651,4 +651,4 @@ static inline void bond_tx_drop(struct net_device *dev, struct sk_buff *skb) dev_kfree_skb_any(skb); } -#endif /* _LINUX_BONDING_H */ +#endif /* _NET_BONDING_H */ -- GitLab From 0099c762855eeee8d3eacc11fcc1e0819e77b2ed Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 9 Nov 2014 12:38:56 +0100 Subject: [PATCH 4152/9457] ASoC: simple-card: Remove useless casts There is no need to cast the cpu_of_node or codec_of_node of the dai_links when calling of_put_node. Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 7 ++----- sound/soc/samsung/odroidx2_max98090.c | 4 ++-- sound/soc/ux500/mop500.c | 6 ++---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index cd49d5010e14..3e3fec4e5c4e 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -457,16 +457,13 @@ static int asoc_simple_card_unref(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct snd_soc_dai_link *dai_link; - struct device_node *np; int num_links; for (num_links = 0, dai_link = card->dai_link; num_links < card->num_links; num_links++, dai_link++) { - np = (struct device_node *) dai_link->cpu_of_node; - of_node_put(np); - np = (struct device_node *) dai_link->codec_of_node; - of_node_put(np); + of_node_put(dai_link->cpu_of_node); + of_node_put(dai_link->codec_of_node); } return 0; } diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index 3c8f60423e82..d7640e72cb1d 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c @@ -153,8 +153,8 @@ static int odroidx2_audio_remove(struct platform_device *pdev) snd_soc_unregister_card(card); - of_node_put((struct device_node *)odroidx2_dai[0].cpu_of_node); - of_node_put((struct device_node *)odroidx2_dai[0].codec_of_node); + of_node_put(odroidx2_dai[0].cpu_of_node); + of_node_put(odroidx2_dai[0].codec_of_node); return 0; } diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index b3b66aa98dce..ea9ba2844510 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -64,11 +64,9 @@ static void mop500_of_node_put(void) for (i = 0; i < 2; i++) { if (mop500_dai_links[i].cpu_of_node) - of_node_put((struct device_node *) - mop500_dai_links[i].cpu_of_node); + of_node_put(mop500_dai_links[i].cpu_of_node); if (mop500_dai_links[i].codec_of_node) - of_node_put((struct device_node *) - mop500_dai_links[i].codec_of_node); + of_node_put(mop500_dai_links[i].codec_of_node); } } -- GitLab From 52ef6284a840bdef50b6ed505bdda014dd769cab Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:00:57 +0100 Subject: [PATCH 4153/9457] ASoC: ab8500-codec: Move control lock to the driver level The ab8500 driver uses a driver specific lock to protect concurrent access to some of the control put/get handlers and uses the snd_soc_codec mutex for some others. This patch updates the driver to consistently use the driver specific lock for all controls. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index fd43827bb856..7dfbc9921e91 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -126,13 +126,13 @@ struct ab8500_codec_drvdata_dbg { /* Private data for AB8500 device-driver */ struct ab8500_codec_drvdata { struct regmap *regmap; + struct mutex ctrl_lock; /* Sidetone */ long *sid_fir_values; enum sid_state sid_status; /* ANC */ - struct mutex anc_lock; long *anc_fir_values; long *anc_iir_values; enum anc_state anc_status; @@ -1129,9 +1129,9 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); - mutex_lock(&codec->mutex); + mutex_lock(&drvdata->ctrl_lock); ucontrol->value.integer.value[0] = drvdata->sid_status; - mutex_unlock(&codec->mutex); + mutex_unlock(&drvdata->ctrl_lock); return 0; } @@ -1154,7 +1154,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol, return -EIO; } - mutex_lock(&codec->mutex); + mutex_lock(&drvdata->ctrl_lock); sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF); if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) { @@ -1185,7 +1185,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol, drvdata->sid_status = SID_FIR_CONFIGURED; out: - mutex_unlock(&codec->mutex); + mutex_unlock(&drvdata->ctrl_lock); dev_dbg(codec->dev, "%s: Exit\n", __func__); @@ -1198,9 +1198,9 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); - mutex_lock(&codec->mutex); + mutex_lock(&drvdata->ctrl_lock); ucontrol->value.integer.value[0] = drvdata->anc_status; - mutex_unlock(&codec->mutex); + mutex_unlock(&drvdata->ctrl_lock); return 0; } @@ -1217,7 +1217,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, dev_dbg(dev, "%s: Enter.\n", __func__); - mutex_lock(&drvdata->anc_lock); + mutex_lock(&drvdata->ctrl_lock); req = ucontrol->value.integer.value[0]; if (req >= ARRAY_SIZE(enum_anc_state)) { @@ -1244,9 +1244,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, } snd_soc_dapm_sync(&codec->dapm); - mutex_lock(&codec->mutex); anc_configure(codec, apply_fir, apply_iir); - mutex_unlock(&codec->mutex); if (apply_fir) { if (drvdata->anc_status == ANC_IIR_CONFIGURED) @@ -1265,7 +1263,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_sync(&codec->dapm); cleanup: - mutex_unlock(&drvdata->anc_lock); + mutex_unlock(&drvdata->ctrl_lock); if (status < 0) dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n", @@ -1294,14 +1292,15 @@ static int filter_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; - mutex_lock(&codec->mutex); + mutex_lock(&drvdata->ctrl_lock); for (i = 0; i < fc->count; i++) ucontrol->value.integer.value[i] = fc->value[i]; - mutex_unlock(&codec->mutex); + mutex_unlock(&drvdata->ctrl_lock); return 0; } @@ -1310,14 +1309,15 @@ static int filter_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; - mutex_lock(&codec->mutex); + mutex_lock(&drvdata->ctrl_lock); for (i = 0; i < fc->count; i++) fc->value[i] = ucontrol->value.integer.value[i]; - mutex_unlock(&codec->mutex); + mutex_unlock(&drvdata->ctrl_lock); return 0; } @@ -2545,7 +2545,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); - mutex_init(&drvdata->anc_lock); + mutex_init(&drvdata->ctrl_lock); return status; } -- GitLab From 210a5fae55c05174b8a5b571b6698626b3ae35d3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:00:58 +0100 Subject: [PATCH 4154/9457] ASoC: max98095: Move mutex to the driver level The max98095 uses the snd_soc_codec mutex to protect against concurrent access in some of its control put handlers. Move this mutex to the driver level so we can eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98095.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 0ee6797d5083..01f3cc9c780f 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ struct max98095_priv { unsigned int mic2pre; struct snd_soc_jack *headphone_jack; struct snd_soc_jack *mic_jack; + struct mutex lock; }; static const struct reg_default max98095_reg_def[] = { @@ -1803,7 +1805,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL); snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0); - mutex_lock(&codec->mutex); + mutex_lock(&max98095->lock); snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG); m98095_eq_band(codec, channel, 0, coef_set->band1); m98095_eq_band(codec, channel, 1, coef_set->band2); @@ -1811,7 +1813,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, m98095_eq_band(codec, channel, 3, coef_set->band4); m98095_eq_band(codec, channel, 4, coef_set->band5); snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0); - mutex_unlock(&codec->mutex); + mutex_unlock(&max98095->lock); /* Restore the original on/off state */ snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave); @@ -1957,12 +1959,12 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL); snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0); - mutex_lock(&codec->mutex); + mutex_lock(&max98095->lock); snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG); m98095_biquad_band(codec, channel, 0, coef_set->band1); m98095_biquad_band(codec, channel, 1, coef_set->band2); snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0); - mutex_unlock(&codec->mutex); + mutex_unlock(&max98095->lock); /* Restore the original on/off state */ snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave); @@ -2395,6 +2397,8 @@ static int max98095_i2c_probe(struct i2c_client *i2c, if (max98095 == NULL) return -ENOMEM; + mutex_init(&max98095->lock); + max98095->regmap = devm_regmap_init_i2c(i2c, &max98095_regmap); if (IS_ERR(max98095->regmap)) { ret = PTR_ERR(max98095->regmap); -- GitLab From d74bcaaeb66826192c9e361cbfe8fd1ffaccf74e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:00:59 +0100 Subject: [PATCH 4155/9457] ASoC: wm5102: Move ultrasonic response settings lock to the driver level The wm5102 driver currently uses the snd_soc_codec mutex to protect its ultrasonic response settings from concurrent access. This patch moves this lock to the driver level. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- include/linux/mfd/arizona/core.h | 1 + sound/soc/codecs/arizona.c | 4 ++-- sound/soc/codecs/wm5102.c | 16 ++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index f34723f7663c..910e3aa1e965 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -141,6 +141,7 @@ struct arizona { uint16_t dac_comp_coeff; uint8_t dac_comp_enabled; + struct mutex dac_comp_lock; }; int arizona_clk32k_enable(struct arizona *arizona); diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 0c05e7a7945f..730636c14f2e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1164,13 +1164,13 @@ static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec, { 0x80, 0x0 }, }; - mutex_lock(&codec->mutex); + mutex_lock(&arizona->dac_comp_lock); dac_comp[1].def = arizona->dac_comp_coeff; if (rate >= 176400) dac_comp[2].def = arizona->dac_comp_enabled; - mutex_unlock(&codec->mutex); + mutex_unlock(&arizona->dac_comp_lock); regmap_multi_reg_write(arizona->regmap, dac_comp, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index f60234962527..1f7553492667 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -619,10 +619,10 @@ static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, struct arizona *arizona = dev_get_drvdata(codec->dev->parent); uint16_t data; - mutex_lock(&codec->mutex); + mutex_lock(&arizona->dac_comp_lock); data = cpu_to_be16(arizona->dac_comp_coeff); memcpy(ucontrol->value.bytes.data, &data, sizeof(data)); - mutex_unlock(&codec->mutex); + mutex_unlock(&arizona->dac_comp_lock); return 0; } @@ -633,11 +633,11 @@ static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct arizona *arizona = dev_get_drvdata(codec->dev->parent); - mutex_lock(&codec->mutex); + mutex_lock(&arizona->dac_comp_lock); memcpy(&arizona->dac_comp_coeff, ucontrol->value.bytes.data, sizeof(arizona->dac_comp_coeff)); arizona->dac_comp_coeff = be16_to_cpu(arizona->dac_comp_coeff); - mutex_unlock(&codec->mutex); + mutex_unlock(&arizona->dac_comp_lock); return 0; } @@ -648,9 +648,9 @@ static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct arizona *arizona = dev_get_drvdata(codec->dev->parent); - mutex_lock(&codec->mutex); + mutex_lock(&arizona->dac_comp_lock); ucontrol->value.integer.value[0] = arizona->dac_comp_enabled; - mutex_unlock(&codec->mutex); + mutex_unlock(&arizona->dac_comp_lock); return 0; } @@ -661,9 +661,9 @@ static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct arizona *arizona = dev_get_drvdata(codec->dev->parent); - mutex_lock(&codec->mutex); + mutex_lock(&arizona->dac_comp_lock); arizona->dac_comp_enabled = ucontrol->value.integer.value[0]; - mutex_unlock(&codec->mutex); + mutex_unlock(&arizona->dac_comp_lock); return 0; } -- GitLab From a51ff30f45473a80f78b2572666473887e010d91 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:01:00 +0100 Subject: [PATCH 4156/9457] ASoC: wm8731: Move the deemph lock to the driver level The wm8731 uses the snd_soc_codec mutex to protect its deemph settings from concurrent access. This patch moves this lock to the driver level. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8731.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index eebb3280bfad..5dae9a6f8076 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ struct wm8731_priv { int sysclk_type; int playback_fs; bool deemph; + + struct mutex lock; }; @@ -138,7 +141,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, if (deemph > 1) return -EINVAL; - mutex_lock(&codec->mutex); + mutex_lock(&wm8731->lock); if (wm8731->deemph != deemph) { wm8731->deemph = deemph; @@ -146,7 +149,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, ret = 1; } - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8731->lock); return ret; } @@ -685,6 +688,8 @@ static int wm8731_spi_probe(struct spi_device *spi) if (wm8731 == NULL) return -ENOMEM; + mutex_init(&wm8731->lock); + wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); if (IS_ERR(wm8731->regmap)) { ret = PTR_ERR(wm8731->regmap); -- GitLab From 78660af7ba30e9d2cc9614465c8b65b3c85f49a9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:01:01 +0100 Subject: [PATCH 4157/9457] ASoC: wm8903: Move the deemph lock to the driver level The wm8903 uses the snd_soc_codec mutex to protect its deemph settings from concurrent access. This patch moves this lock to the driver level. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index c038b3e04398..ffbe6df3453a 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,7 @@ struct wm8903_priv { int sysclk; int irq; + struct mutex lock; int fs; int deemph; @@ -457,7 +459,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, if (deemph > 1) return -EINVAL; - mutex_lock(&codec->mutex); + mutex_lock(&wm8903->lock); if (wm8903->deemph != deemph) { wm8903->deemph = deemph; @@ -465,7 +467,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, ret = 1; } - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8903->lock); return ret; } @@ -2023,6 +2025,8 @@ static int wm8903_i2c_probe(struct i2c_client *i2c, GFP_KERNEL); if (wm8903 == NULL) return -ENOMEM; + + mutex_init(&wm8903->lock); wm8903->dev = &i2c->dev; wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap); -- GitLab From fabfad2f8b23529722c6ef5b3537c457e63d2c82 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:01:02 +0100 Subject: [PATCH 4158/9457] ASoC: wm8958: Move DSP firmware lock to driver level The wm8958 driver uses the snd_soc_codec mutex to protect the various firmware pointers from concurrent assignment. This patch moves this lock to the driver level. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8958-dsp2.c | 12 ++++++------ sound/soc/codecs/wm8994.c | 2 ++ sound/soc/codecs/wm8994.h | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 0dada7f0105e..3cbc82b33292 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -867,9 +867,9 @@ static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context) struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) { - mutex_lock(&codec->mutex); + mutex_lock(&wm8994->fw_lock); wm8994->enh_eq = fw; - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8994->fw_lock); } } @@ -879,9 +879,9 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) { - mutex_lock(&codec->mutex); + mutex_lock(&wm8994->fw_lock); wm8994->mbc_vss = fw; - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8994->fw_lock); } } @@ -891,9 +891,9 @@ static void wm8958_mbc_loaded(const struct firmware *fw, void *context) struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) { - mutex_lock(&codec->mutex); + mutex_lock(&wm8994->fw_lock); wm8994->mbc = fw; - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8994->fw_lock); } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1fcb9f3f3097..dbca6e0cc93a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4457,6 +4457,8 @@ static int wm8994_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, wm8994); + mutex_init(&wm8994->fw_lock); + wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); pm_runtime_enable(&pdev->dev); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 6536f8d45ac6..dd73387b1cc4 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "wm_hubs.h" @@ -156,6 +157,7 @@ struct wm8994_priv { unsigned int aif1clk_disable:1; unsigned int aif2clk_disable:1; + struct mutex fw_lock; int dsp_active; const struct firmware *cur_fw; const struct firmware *mbc; -- GitLab From 3e4199ef0105fb718b24cbcc837ad527fd60c880 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:01:03 +0100 Subject: [PATCH 4159/9457] ASoC: wm8962: Move DSP enable lock to the driver level The wm8962 uses the snd_soc_codec mutex to protect the wm8962_dsp2_ena_put() function from concurrent execution. This patch moves that lock to the driver level. This will allow us to eventually remove the snd_soc_codec mutex. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 9077411e62ce..61ca4a7cb6ea 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ struct wm8962_priv { int fll_fref; int fll_fout; + struct mutex dsp2_ena_lock; u16 dsp2_ena; struct delayed_work mic_work; @@ -1570,7 +1572,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) & WM8962_DSP2_ENA; - mutex_lock(&codec->mutex); + mutex_lock(&wm8962->dsp2_ena_lock); if (ucontrol->value.integer.value[0]) wm8962->dsp2_ena |= 1 << shift; @@ -1590,7 +1592,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, } out: - mutex_unlock(&codec->mutex); + mutex_unlock(&wm8962->dsp2_ena_lock); return ret; } @@ -3557,6 +3559,8 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, if (wm8962 == NULL) return -ENOMEM; + mutex_init(&wm8962->dsp2_ena_lock); + i2c_set_clientdata(i2c, wm8962); INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); -- GitLab From bd6b87c104bae49816808fde5f55a262093e85ed Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Nov 2014 17:01:04 +0100 Subject: [PATCH 4160/9457] ASoC: Remove CODEC mutex The CODEC mutex is now unused and can be removed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 1 - sound/soc/soc-core.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..5c91b06864ce 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -780,7 +780,6 @@ struct snd_soc_codec { struct device *dev; const struct snd_soc_codec_driver *driver; - struct mutex mutex; struct list_head list; struct list_head card_list; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..cc7bb7ad9677 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4362,7 +4362,6 @@ int snd_soc_register_codec(struct device *dev, codec->dev = dev; codec->driver = codec_drv; codec->component.val_bytes = codec_drv->reg_word_size; - mutex_init(&codec->mutex); #ifdef CONFIG_DEBUG_FS codec->component.init_debugfs = soc_init_codec_debugfs; -- GitLab From 32b5913a931fd753faf3d4e1124b2bc2edb364da Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:27:08 +0800 Subject: [PATCH 4161/9457] ipv4: Use standard iovec primitive in raw_probe_proto_opt The function raw_probe_proto_opt tries to extract the first two bytes from the user input in order to seed the IPsec lookup for ICMP packets. In doing so it's processing iovec by hand and overcomplicating things. This patch replaces the manual iovec processing with a call to memcpy_fromiovecend. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/raw.c | 50 +++++++++++--------------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index ee8fa4bf3b73..9be905057b24 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -422,48 +422,20 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, static int raw_probe_proto_opt(struct flowi4 *fl4, struct msghdr *msg) { - struct iovec *iov; - u8 __user *type = NULL; - u8 __user *code = NULL; - int probed = 0; - unsigned int i; + struct icmphdr icmph; + int err; - if (!msg->msg_iov) + if (fl4->flowi4_proto != IPPROTO_ICMP) return 0; - for (i = 0; i < msg->msg_iovlen; i++) { - iov = &msg->msg_iov[i]; - if (!iov) - continue; - - switch (fl4->flowi4_proto) { - case IPPROTO_ICMP: - /* check if one-byte field is readable or not. */ - if (iov->iov_base && iov->iov_len < 1) - break; - - if (!type) { - type = iov->iov_base; - /* check if code field is readable or not. */ - if (iov->iov_len > 1) - code = type + 1; - } else if (!code) - code = iov->iov_base; - - if (type && code) { - if (get_user(fl4->fl4_icmp_type, type) || - get_user(fl4->fl4_icmp_code, code)) - return -EFAULT; - probed = 1; - } - break; - default: - probed = 1; - break; - } - if (probed) - break; - } + /* We only need the first two bytes. */ + err = memcpy_fromiovecend((void *)&icmph, msg->msg_iov, 0, 2); + if (err) + return err; + + fl4->fl4_icmp_type = icmph.type; + fl4->fl4_icmp_code = icmph.code; + return 0; } -- GitLab From c008ba5bdc9fa830e1a349b20b0be5a137bdef7a Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 7 Nov 2014 21:27:09 +0800 Subject: [PATCH 4162/9457] ipv4: Avoid reading user iov twice after raw_probe_proto_opt Ever since raw_probe_proto_opt was added it had the problem of causing the user iov to be read twice, once during the probe for the protocol header and once again in ip_append_data. This is a potential security problem since it means that whatever we're probing may be invalid. This patch plugs the hole by firstly advancing the iov so we don't read the same spot again, and secondly saving what we read the first time around for use by ip_append_data. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/raw.c | 62 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 9be905057b24..43385a9fa441 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -79,6 +79,16 @@ #include #include #include +#include + +struct raw_frag_vec { + struct iovec *iov; + union { + struct icmphdr icmph; + char c[1]; + } hdr; + int hlen; +}; static struct raw_hashinfo raw_v4_hashinfo = { .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), @@ -420,25 +430,57 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, return err; } -static int raw_probe_proto_opt(struct flowi4 *fl4, struct msghdr *msg) +static int raw_probe_proto_opt(struct raw_frag_vec *rfv, struct flowi4 *fl4) { - struct icmphdr icmph; int err; if (fl4->flowi4_proto != IPPROTO_ICMP) return 0; /* We only need the first two bytes. */ - err = memcpy_fromiovecend((void *)&icmph, msg->msg_iov, 0, 2); + rfv->hlen = 2; + + err = memcpy_fromiovec(rfv->hdr.c, rfv->iov, rfv->hlen); if (err) return err; - fl4->fl4_icmp_type = icmph.type; - fl4->fl4_icmp_code = icmph.code; + fl4->fl4_icmp_type = rfv->hdr.icmph.type; + fl4->fl4_icmp_code = rfv->hdr.icmph.code; return 0; } +static int raw_getfrag(void *from, char *to, int offset, int len, int odd, + struct sk_buff *skb) +{ + struct raw_frag_vec *rfv = from; + + if (offset < rfv->hlen) { + int copy = min(rfv->hlen - offset, len); + + if (skb->ip_summed == CHECKSUM_PARTIAL) + memcpy(to, rfv->hdr.c + offset, copy); + else + skb->csum = csum_block_add( + skb->csum, + csum_partial_copy_nocheck(rfv->hdr.c + offset, + to, copy, 0), + odd); + + odd = 0; + offset += copy; + to += copy; + len -= copy; + + if (!len) + return 0; + } + + offset -= rfv->hlen; + + return ip_generic_getfrag(rfv->iov, to, offset, len, odd, skb); +} + static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { @@ -452,6 +494,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, u8 tos; int err; struct ip_options_data opt_copy; + struct raw_frag_vec rfv; err = -EMSGSIZE; if (len > 0xFFFF) @@ -557,7 +600,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, daddr, saddr, 0, 0); if (!inet->hdrincl) { - err = raw_probe_proto_opt(&fl4, msg); + rfv.iov = msg->msg_iov; + rfv.hlen = 0; + + err = raw_probe_proto_opt(&rfv, &fl4); if (err) goto done; } @@ -588,8 +634,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (!ipc.addr) ipc.addr = fl4.daddr; lock_sock(sk); - err = ip_append_data(sk, &fl4, ip_generic_getfrag, - msg->msg_iov, len, 0, + err = ip_append_data(sk, &fl4, raw_getfrag, + &rfv, len, 0, &ipc, &rt, msg->msg_flags); if (err) ip_flush_pending_frames(sk); -- GitLab From 617100c2711691e07728d3201fbcfa845a7c36d5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 10 Nov 2014 17:25:24 -0200 Subject: [PATCH 4163/9457] spi: spi-mxs: Register the irq with the device name Instead of registering the irq name with the driver name, it's better to pass the device name so that we have a more explicit indication as to what spi instance the irq is related: $ cat /proc/interrupts CPU0 ... 27: 0 - 98 80014000.ssp Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/spi/spi-mxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 51460878af04..a9e72f9d385e 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -511,7 +511,7 @@ static int mxs_spi_probe(struct platform_device *pdev) init_completion(&spi->c); ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0, - DRIVER_NAME, ssp); + dev_name(&pdev->dev), ssp); if (ret) goto out_master_free; -- GitLab From 33aa59c232adf9eb9be2936b9f5dc76850a050c1 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Fri, 7 Nov 2014 21:49:33 +0800 Subject: [PATCH 4164/9457] clk: rockchip: rk3288: add suspend and resume save and restore some clks, which might be changed in suspend. Signed-off-by: Tony Xie Signed-off-by: Chris Zhong Reviewed-by: Doug Anderson Tested-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index bd9534a00737..1a9d03cf2b00 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "clk.h" @@ -764,6 +765,64 @@ static const char *rk3288_critical_clocks[] __initconst = { "hclk_peri", }; +#ifdef CONFIG_PM_SLEEP +static void __iomem *rk3288_cru_base; + +/* Some CRU registers will be reset in maskrom when the system + * wakes up from fastboot. + * So save them before suspend, restore them after resume. + */ +static const int rk3288_saved_cru_reg_ids[] = { + RK3288_MODE_CON, + RK3288_CLKSEL_CON(0), + RK3288_CLKSEL_CON(1), + RK3288_CLKSEL_CON(10), + RK3288_CLKSEL_CON(33), + RK3288_CLKSEL_CON(37), +}; + +static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; + +static int rk3288_clk_suspend(void) +{ + int i, reg_id; + + for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + rk3288_saved_cru_regs[i] = + readl_relaxed(rk3288_cru_base + reg_id); + } + return 0; +} + +static void rk3288_clk_resume(void) +{ + int i, reg_id; + + for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000, + rk3288_cru_base + reg_id); + } +} + +static struct syscore_ops rk3288_clk_syscore_ops = { + .suspend = rk3288_clk_suspend, + .resume = rk3288_clk_resume, +}; + +static void rk3288_clk_sleep_init(void __iomem *reg_base) +{ + rk3288_cru_base = reg_base; + register_syscore_ops(&rk3288_clk_syscore_ops); +} + +#else /* CONFIG_PM_SLEEP */ +static void rk3288_clk_sleep_init(void __iomem *reg_base) {} +#endif + static void __init rk3288_clk_init(struct device_node *np) { void __iomem *reg_base; @@ -812,5 +871,6 @@ static void __init rk3288_clk_init(struct device_node *np) ROCKCHIP_SOFTRST_HIWORD_MASK); rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); + rk3288_clk_sleep_init(reg_base); } CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); -- GitLab From 8c2727f97b4825adaad43bf98632abc9940345a4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 10 Nov 2014 17:49:30 -0200 Subject: [PATCH 4165/9457] ASoC: mxs: mxs-saif: Register the irq with the device name Instead of registering the irq name with the driver name, it's better to pass the device name so that we have a more explicit indication as to what saif instance the irq is related: $ cat /proc/interrupts CPU0 ... 214: 4 - 59 80042000.saif 215: 0 - 58 80046000.saif Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 231d7e7b0711..83b2fea09219 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -773,7 +773,7 @@ static int mxs_saif_probe(struct platform_device *pdev) saif->dev = &pdev->dev; ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0, - "mxs-saif", saif); + dev_name(&pdev->dev), saif); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); return ret; -- GitLab From ef786f106fe878a90f90b67aa95201a266de12de Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sat, 8 Nov 2014 12:48:35 +0100 Subject: [PATCH 4166/9457] 8139too: Allow setting MTU larger than 1500 Replace the default ndo_change_mtu callback with one that allow setting MTU that the driver can handle. Signed-off-by: Alban Bedel Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/8139too.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 007b38cce69a..8387de985c06 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -185,6 +185,9 @@ static int debug = -1; /* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/ #define MAX_ETH_FRAME_SIZE 1536 +/* max supported payload size */ +#define MAX_ETH_DATA_SIZE (MAX_ETH_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN) + /* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */ #define TX_BUF_SIZE MAX_ETH_FRAME_SIZE #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC) @@ -920,11 +923,19 @@ static int rtl8139_set_features(struct net_device *dev, netdev_features_t featur return 0; } +static int rtl8139_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < 68 || new_mtu > MAX_ETH_DATA_SIZE) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + static const struct net_device_ops rtl8139_netdev_ops = { .ndo_open = rtl8139_open, .ndo_stop = rtl8139_close, .ndo_get_stats64 = rtl8139_get_stats64, - .ndo_change_mtu = eth_change_mtu, + .ndo_change_mtu = rtl8139_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = rtl8139_set_mac_address, .ndo_start_xmit = rtl8139_start_xmit, -- GitLab From 6f6e741f6de5ed5eedf7d19c9c0f8c73eaa0da7d Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sat, 8 Nov 2014 12:48:36 +0100 Subject: [PATCH 4167/9457] 8139too: Allow using the largest possible MTU This driver allows MTU up to 1518 bytes which is not enought to run batman-adv. Simply raise the maximum packet size up to the maximum allowed by the transmit descriptor, 1792 bytes, giving a maximum MTU of 1774 bytes. Signed-off-by: Alban Bedel Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/8139too.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 8387de985c06..e157541b842b 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -183,7 +183,7 @@ static int debug = -1; #define NUM_TX_DESC 4 /* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/ -#define MAX_ETH_FRAME_SIZE 1536 +#define MAX_ETH_FRAME_SIZE 1792 /* max supported payload size */ #define MAX_ETH_DATA_SIZE (MAX_ETH_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN) -- GitLab From 252670c421c785127cb55db03c48df5feb57ce12 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 10 Nov 2014 15:53:45 +0200 Subject: [PATCH 4168/9457] Bluetooth: Fix sparse warning in amp.c This fixes the following sparse warning: net/bluetooth/amp.c:152:53: warning: Variable length array is used. The warning itself is probably harmless since this kind of usage of shash_desc is present also in other places in the kernel (there's even a convenience macro SHASH_DESC_ON_STACK available for defining such stack variables). However, dynamically allocated versions are also used in several places of the kernel (e.g. kernel/kexec.c and lib/digsig.c) which have the benefit of not exhibiting the sparse warning. Since there are no more sparse warnings in the Bluetooth subsystem after fixing this one it is now easier to spot whenever new ones might get introduced by future patches. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/amp.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index 2640d78f30b8..ee016f039100 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c @@ -134,6 +134,7 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output) { struct crypto_shash *tfm; + struct shash_desc *shash; int ret; if (!ksize) @@ -148,18 +149,24 @@ static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output) ret = crypto_shash_setkey(tfm, key, ksize); if (ret) { BT_DBG("crypto_ahash_setkey failed: err %d", ret); - } else { - char desc[sizeof(struct shash_desc) + - crypto_shash_descsize(tfm)] CRYPTO_MINALIGN_ATTR; - struct shash_desc *shash = (struct shash_desc *)desc; - - shash->tfm = tfm; - shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + goto failed; + } - ret = crypto_shash_digest(shash, plaintext, psize, - output); + shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm), + GFP_KERNEL); + if (!shash) { + ret = -ENOMEM; + goto failed; } + shash->tfm = tfm; + shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + ret = crypto_shash_digest(shash, plaintext, psize, output); + + kfree(shash); + +failed: crypto_free_shash(tfm); return ret; } -- GitLab From 60f0e628c9940dc59463e986ddfa2c9e74ea89bb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 6 Nov 2014 11:32:35 -0600 Subject: [PATCH 4169/9457] arm: boot: dts: am4372: enable dwc3 suspend PHY quirk Whenever Suspend PHY bit is set on AM437x devices, USB will not work due to Set EP Configuration command always failing. This was only found after a recent commit 2164a47 (usb: dwc3: set SUSPHY bit for all cores, which will be merged for v3.19) added a missing *required* step to dwc3 initialization. Synopsys Databook requires that we enable Suspend PHY bit after initialization but that, unfortunately, breaks AM437x. Acked-by: Tony Lindgren Signed-off-by: Felipe Balbi --- arch/arm/boot/dts/am4372.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 46660ffd2b65..e19068d24737 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -817,6 +817,8 @@ maximum-speed = "high-speed"; dr_mode = "otg"; status = "disabled"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; @@ -839,6 +841,8 @@ maximum-speed = "high-speed"; dr_mode = "otg"; status = "disabled"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; -- GitLab From 004f7d457ef57d46ddf5f8380aa169214c166fca Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 29 Oct 2014 21:58:33 +0100 Subject: [PATCH 4170/9457] usb: gadget: pxa27x_udc: fix warning in non device-tree build The recent change bringing device-tree support triggers a warning in a non device-tree build : drivers/usb/gadget/udc/pxa27x_udc.c:2405:28: warning: 'udc_pxa_dt_ids' defined but not used [-Wunused-variable] Fix the warning with a preprocessor condition. Signed-off-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa27x_udc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 69e7b816d880..9b03fab13707 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2400,11 +2400,13 @@ static struct pxa_udc memory = { } }; +#if defined(CONFIG_OF) static struct of_device_id udc_pxa_dt_ids[] = { { .compatible = "marvell,pxa270-udc" }, {} }; MODULE_DEVICE_TABLE(of, udc_pxa_dt_ids); +#endif /** * pxa_udc_probe - probes the udc device -- GitLab From 8b9ca2767b2d1ea405287e530da3a7b234120b95 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 7 Nov 2014 09:06:04 -0600 Subject: [PATCH 4171/9457] phy: twl4030: Fix build breakage commit e47d925 (usb: move the OTG state from the USB PHY to the OTG structure) moved the OTG state field from struct usb_phy to struct usb_otg but, even though I fixed many other build breakages, I still missed one on phy-twl4030-usb.c. Fix the build breakage now. While at that, also a build warning introduced by the same commit. Cc: Kishon Vijay Abraham I Cc: Antoine Tenart Signed-off-by: Felipe Balbi --- drivers/phy/phy-twl4030-usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 7b04befd5271..e2698d29f436 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -606,7 +606,7 @@ static int twl4030_set_peripheral(struct usb_otg *otg, otg->gadget = gadget; if (!gadget) - otg->phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; return 0; } @@ -618,7 +618,7 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) otg->host = host; if (!host) - otg->phy->state = OTG_STATE_UNDEFINED; + otg->state = OTG_STATE_UNDEFINED; return 0; } @@ -676,7 +676,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) twl->phy.otg = otg; twl->phy.type = USB_PHY_TYPE_USB2; - otg->phy = &twl->phy; + otg->usb_phy = &twl->phy; otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; -- GitLab From 6876d58f2f0548ce130b388c323eed17dc5d8689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 3 Nov 2014 17:18:04 +0200 Subject: [PATCH 4172/9457] usb: gadget: dbgp: Fix endpoint config after USB disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SET_FEATURE request with DEBUG_MODE only worked the first time after module initialisation. Per the USB 2.0 debug device specification, said request is to be treated as if it were a SET_CONFIGURATION request, i.e. endpoint must be re-configured. As configure_endpoints() may now get called multiple times, move it outside __init and move serial_alloc_tty() call into __init. Code has assumption that endpoint mapping remains unchanged with consecutive calls of configure_endpoints(). Signed-off-by: Kyösti Mälkki Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/dbgp.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 1b075132f8f1..633683a72a11 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -237,7 +237,7 @@ static void dbgp_unbind(struct usb_gadget *gadget) static unsigned char tty_line; #endif -static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) +static int dbgp_configure_endpoints(struct usb_gadget *gadget) { int stp; @@ -273,19 +273,10 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) dbgp.serial->in->desc = &i_desc; dbgp.serial->out->desc = &o_desc; - - if (gserial_alloc_line(&tty_line)) { - stp = 3; - goto fail_3; - } +#endif return 0; -fail_3: - dbgp.o_ep->driver_data = NULL; -#else - return 0; -#endif fail_2: dbgp.i_ep->driver_data = NULL; fail_1: @@ -324,10 +315,17 @@ static int __init dbgp_bind(struct usb_gadget *gadget, err = -ENOMEM; goto fail; } + + if (gserial_alloc_line(&tty_line)) { + stp = 4; + err = -ENODEV; + goto fail; + } #endif + err = dbgp_configure_endpoints(gadget); if (err < 0) { - stp = 4; + stp = 5; goto fail; } @@ -383,6 +381,10 @@ static int dbgp_setup(struct usb_gadget *gadget, #ifdef CONFIG_USB_G_DBGP_PRINTK err = dbgp_enable_ep(); #else + err = dbgp_configure_endpoints(gadget); + if (err < 0) { + goto fail; + } err = gserial_connect(dbgp.serial, tty_line); #endif if (err < 0) -- GitLab From 8e74475b0e0ac2fd3634f3c1b9a109fb1d6269f7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 6 Nov 2014 14:27:53 +0800 Subject: [PATCH 4173/9457] usb: dwc3: gadget: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Felipe Balbi Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 398c12f5efe3..f03b136ecfce 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2041,6 +2041,17 @@ static void dwc3_resume_gadget(struct dwc3 *dwc) if (dwc->gadget_driver && dwc->gadget_driver->resume) { spin_unlock(&dwc->lock); dwc->gadget_driver->resume(&dwc->gadget); + } +} + +static void dwc3_reset_gadget(struct dwc3 *dwc) +{ + if (!dwc->gadget_driver) + return; + + if (dwc->gadget.speed != USB_SPEED_UNKNOWN) { + spin_unlock(&dwc->lock); + usb_gadget_udc_reset(&dwc->gadget, dwc->gadget_driver); spin_lock(&dwc->lock); } } @@ -2185,11 +2196,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_gadget_disconnect_interrupt(dwc); } - /* after reset -> Default State */ - usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); - - if (dwc->gadget.speed != USB_SPEED_UNKNOWN) - dwc3_disconnect_gadget(dwc); + dwc3_reset_gadget(dwc); reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; -- GitLab From 1189f7f6dcf045ff970f619734420c6dd3d8526e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 6 Nov 2014 14:27:54 +0800 Subject: [PATCH 4174/9457] usb: musb: gadget: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Felipe Balbi Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 56c31b769a54..49b04cb6f5ca 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -2083,9 +2083,12 @@ __acquires(musb->lock) : NULL ); - /* report disconnect, if we didn't already (flushing EP state) */ - if (musb->g.speed != USB_SPEED_UNKNOWN) - musb_g_disconnect(musb); + /* report reset, if we didn't already (flushing EP state) */ + if (musb->gadget_driver && musb->g.speed != USB_SPEED_UNKNOWN) { + spin_unlock(&musb->lock); + usb_gadget_udc_reset(&musb->g, musb->gadget_driver); + spin_lock(&musb->lock); + } /* clear HR */ else if (devctl & MUSB_DEVCTL_HR) -- GitLab From 8480484d6f4a5b7d50262702db082b0fd13e7df5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Nov 2014 14:27:55 +0800 Subject: [PATCH 4175/9457] usb: gadget: dummy-hcd: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi Signed-off-by: Peter chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 254b9e7659f3..1c69c760408e 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -367,19 +367,22 @@ static void set_link_state(struct dummy_hcd *dum_hcd) dum_hcd->active) dum_hcd->resuming = 0; - /* if !connected or reset */ + /* Currently !connected or in reset */ if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { - /* - * We're connected and not reset (reset occurred now), - * and driver attached - disconnect! - */ - if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) != 0 && - (dum_hcd->old_status & USB_PORT_STAT_RESET) == 0 && - dum->driver) { + unsigned disconnect = USB_PORT_STAT_CONNECTION & + dum_hcd->old_status & (~dum_hcd->port_status); + unsigned reset = USB_PORT_STAT_RESET & + (~dum_hcd->old_status) & dum_hcd->port_status; + + /* Report reset and disconnect events to the driver */ + if (dum->driver && (disconnect || reset)) { stop_activity(dum); spin_unlock(&dum->lock); - dum->driver->disconnect(&dum->gadget); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); + else + dum->driver->disconnect(&dum->gadget); spin_lock(&dum->lock); } } else if (dum_hcd->active != dum_hcd->old_active) { -- GitLab From b611e424f1ad189409dde50fe950eb8c05f75cab Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Nov 2014 14:27:56 +0800 Subject: [PATCH 4176/9457] usb: gadget: net2280: use udc-core's reset notifier This patch adds support for the new udc-core reset notifier to the net2280 driver. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 45 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index bd03a1b4192d..c49179493796 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -3308,17 +3308,42 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) * only indicates a change in the reset state). */ if (stat & tmp) { + bool reset = false; + bool disconnect = false; + + /* + * Ignore disconnects and resets if the speed hasn't been set. + * VBUS can bounce and there's always an initial reset. + */ writel(tmp, &dev->regs->irqstat1); - if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && - ((readl(&dev->usb->usbstat) & mask) == 0)) || - ((readl(&dev->usb->usbctl) & - BIT(VBUS_PIN)) == 0)) && - (dev->gadget.speed != USB_SPEED_UNKNOWN)) { - ep_dbg(dev, "disconnect %s\n", - dev->driver->driver.name); - stop_activity(dev, dev->driver); - ep0_start(dev); - return; + if (dev->gadget.speed != USB_SPEED_UNKNOWN) { + if ((stat & BIT(VBUS_INTERRUPT)) && + (readl(&dev->usb->usbctl) & + BIT(VBUS_PIN)) == 0) { + disconnect = true; + ep_dbg(dev, "disconnect %s\n", + dev->driver->driver.name); + } else if ((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && + (readl(&dev->usb->usbstat) & mask) + == 0) { + reset = true; + ep_dbg(dev, "reset %s\n", + dev->driver->driver.name); + } + + if (disconnect || reset) { + stop_activity(dev, dev->driver); + ep0_start(dev); + spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); + spin_lock(&dev->lock); + return; + } } stat &= ~tmp; -- GitLab From 5ca1ccdaa88ac15d1468c5e8bb40885dc6b8a364 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Nov 2014 14:27:57 +0800 Subject: [PATCH 4177/9457] usb: gadget: net2272: use udc-core's reset notifier This patch adds support for the new udc-core reset notifier to the net2272 driver. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2272.c | 45 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index ab3a73950d8f..3a90856625f2 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1982,17 +1982,42 @@ net2272_handle_stat1_irqs(struct net2272 *dev, u8 stat) mask = (1 << USB_HIGH_SPEED) | (1 << USB_FULL_SPEED); if (stat & tmp) { + bool reset = false; + bool disconnect = false; + + /* + * Ignore disconnects and resets if the speed hasn't been set. + * VBUS can bounce and there's always an initial reset. + */ net2272_write(dev, IRQSTAT1, tmp); - if ((((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) && - ((net2272_read(dev, USBCTL1) & mask) == 0)) - || ((net2272_read(dev, USBCTL1) & (1 << VBUS_PIN)) - == 0)) - && (dev->gadget.speed != USB_SPEED_UNKNOWN)) { - dev_dbg(dev->dev, "disconnect %s\n", - dev->driver->driver.name); - stop_activity(dev, dev->driver); - net2272_ep0_start(dev); - return; + if (dev->gadget.speed != USB_SPEED_UNKNOWN) { + if ((stat & (1 << VBUS_INTERRUPT)) && + (net2272_read(dev, USBCTL1) & + (1 << VBUS_PIN)) == 0) { + disconnect = true; + dev_dbg(dev->dev, "disconnect %s\n", + dev->driver->driver.name); + } else if ((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) && + (net2272_read(dev, USBCTL1) & mask) + == 0) { + reset = true; + dev_dbg(dev->dev, "reset %s\n", + dev->driver->driver.name); + } + + if (disconnect || reset) { + stop_activity(dev, dev->driver); + net2272_ep0_start(dev); + spin_unlock(&dev->lock); + if (reset) + usb_gadget_udc_reset + (&dev->gadget, dev->driver); + else + (dev->driver->disconnect) + (&dev->gadget); + spin_lock(&dev->lock); + return; + } } stat &= ~tmp; -- GitLab From afbe47758a5931aa1ddd71da53189092f564b230 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:27:58 +0800 Subject: [PATCH 4178/9457] usb: chipidea: gadget: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index a2d80ab3d9c4..bdaa7bac6f4a 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -692,10 +692,8 @@ __acquires(ci->lock) int retval; spin_unlock(&ci->lock); - if (ci->gadget.speed != USB_SPEED_UNKNOWN) { - if (ci->driver) - ci->driver->disconnect(&ci->gadget); - } + if (ci->gadget.speed != USB_SPEED_UNKNOWN) + usb_gadget_udc_reset(&ci->gadget, ci->driver); retval = _gadget_stop_activity(&ci->gadget); if (retval) @@ -709,8 +707,6 @@ __acquires(ci->lock) if (ci->status == NULL) retval = -ENOMEM; - usb_gadget_set_state(&ci->gadget, USB_STATE_DEFAULT); - done: spin_lock(&ci->lock); -- GitLab From 90834d3ecb952f8f0ab8a5687e58c472935a4e70 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:27:59 +0800 Subject: [PATCH 4179/9457] usb: gadget: pxa25x_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa25x_udc.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 2944092cd92e..8664b99f147f 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1283,6 +1283,33 @@ static int pxa25x_udc_start(struct usb_gadget *g, return retval; } +static void +reset_gadget(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) +{ + int i; + + /* don't disconnect drivers more than once */ + if (dev->gadget.speed == USB_SPEED_UNKNOWN) + driver = NULL; + dev->gadget.speed = USB_SPEED_UNKNOWN; + + /* prevent new request submissions, kill any outstanding requests */ + for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { + struct pxa25x_ep *ep = &dev->ep[i]; + + ep->stopped = 1; + nuke(ep, -ESHUTDOWN); + } + del_timer_sync(&dev->timer); + + /* report reset; the driver is already quiesced */ + if (driver) + usb_gadget_udc_reset(&dev->gadget, driver); + + /* re-init driver-visible data structures */ + udc_reinit(dev); +} + static void stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) { @@ -1721,7 +1748,7 @@ pxa25x_udc_irq(int irq, void *_dev) /* reset driver and endpoints, * in case that's not yet done */ - stop_activity (dev, dev->driver); + reset_gadget(dev, dev->driver); } else { DBG(DBG_VERBOSE, "USB reset end\n"); -- GitLab From 373ef692e00624b426271a22b8dadb92a46897ef Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:00 +0800 Subject: [PATCH 4180/9457] usb: gadget: m66592-udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/m66592-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 311ec5f1cbfe..ef3f73dd9099 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1142,7 +1142,7 @@ static void irq_device_state(struct m66592 *m66592) m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0); if (dvsq == M66592_DS_DFLT) { /* bus reset */ - m66592->driver->disconnect(&m66592->gadget); + usb_gadget_udc_reset(&m66592->gadget, m66592->driver); m66592_update_usb_speed(m66592); } if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) -- GitLab From 363ea206efb25dfcb09d57878fdbdb4cd6b01775 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:01 +0800 Subject: [PATCH 4181/9457] usb: gadget: fsl_udc_core: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_udc_core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index b184ed3ef37a..f340181da23c 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1771,7 +1771,7 @@ static void bus_resume(struct fsl_udc *udc) } /* Clear up all ep queues */ -static int reset_queues(struct fsl_udc *udc) +static int reset_queues(struct fsl_udc *udc, bool bus_reset) { u8 pipe; @@ -1780,7 +1780,10 @@ static int reset_queues(struct fsl_udc *udc) /* report disconnect; the driver is already quiesced */ spin_unlock(&udc->lock); - udc->driver->disconnect(&udc->gadget); + if (bus_reset) + usb_gadget_udc_reset(&udc->gadget, udc->driver); + else + udc->driver->disconnect(&udc->gadget); spin_lock(&udc->lock); return 0; @@ -1834,7 +1837,7 @@ static void reset_irq(struct fsl_udc *udc) udc->bus_reset = 1; /* Reset all the queues, include XD, dTD, EP queue * head and TR Queue */ - reset_queues(udc); + reset_queues(udc, true); udc->usb_state = USB_STATE_DEFAULT; } else { VDBG("Controller reset"); @@ -1843,7 +1846,7 @@ static void reset_irq(struct fsl_udc *udc) dr_controller_setup(udc); /* Reset all internal used Queues */ - reset_queues(udc); + reset_queues(udc, false); ep0_setup(udc); -- GitLab From 236e5064fc06ce3609b3521ca148ad0f8c3c18f6 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:02 +0800 Subject: [PATCH 4182/9457] usb: gadget: at91_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index f47f16c25f15..753e93b5440c 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -840,6 +840,31 @@ static void udc_reinit(struct at91_udc *udc) } } +static void reset_gadget(struct at91_udc *udc) +{ + struct usb_gadget_driver *driver = udc->driver; + int i; + + if (udc->gadget.speed == USB_SPEED_UNKNOWN) + driver = NULL; + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->suspended = 0; + + for (i = 0; i < NUM_ENDPOINTS; i++) { + struct at91_ep *ep = &udc->ep[i]; + + ep->stopped = 1; + nuke(ep, -ESHUTDOWN); + } + if (driver) { + spin_unlock(&udc->lock); + usb_gadget_udc_reset(&udc->gadget, driver); + spin_lock(&udc->lock); + } + + udc_reinit(udc); +} + static void stop_activity(struct at91_udc *udc) { struct usb_gadget_driver *driver = udc->driver; @@ -1426,7 +1451,7 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); VDBG("end bus reset\n"); udc->addr = 0; - stop_activity(udc); + reset_gadget(udc); /* enable ep0 */ at91_udp_write(udc, AT91_UDP_CSR(0), -- GitLab From 69aa1f9f5e210aac765e3595d3d67a7477ae431a Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:03 +0800 Subject: [PATCH 4183/9457] usb: gadget: mv_udc_core: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/mv_udc_core.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index f104ac090a99..d4edd763e963 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -1307,6 +1307,23 @@ static void nuke(struct mv_ep *ep, int status) } } +static void gadget_reset(struct mv_udc *udc, struct usb_gadget_driver *driver) +{ + struct mv_ep *ep; + + nuke(&udc->eps[0], -ESHUTDOWN); + + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { + nuke(ep, -ESHUTDOWN); + } + + /* report reset; the driver is already quiesced */ + if (driver) { + spin_unlock(&udc->lock); + usb_gadget_udc_reset(&udc->gadget, driver); + spin_lock(&udc->lock); + } +} /* stop all USB activities */ static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) { @@ -1881,7 +1898,7 @@ static void irq_process_reset(struct mv_udc *udc) dev_info(&udc->dev->dev, "usb bus reset\n"); udc->usb_state = USB_STATE_DEFAULT; /* reset all the queues, stop all USB activities */ - stop_activity(udc, udc->driver); + gadget_reset(udc, udc->driver); } else { dev_info(&udc->dev->dev, "USB reset portsc 0x%x\n", readl(&udc->op_regs->portsc)); -- GitLab From fba45ceac46e1508fdefd3fe501be04bb3399792 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:04 +0800 Subject: [PATCH 4184/9457] usb: gadget: fsl_qe_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_qe_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 01f29ef622bc..d201f9a89ce3 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -1917,7 +1917,7 @@ static int reset_queues(struct qe_udc *udc) /* report disconnect; the driver is already quiesced */ spin_unlock(&udc->lock); - udc->driver->disconnect(&udc->gadget); + usb_gadget_udc_reset(&udc->gadget, udc->driver); spin_lock(&udc->lock); return 0; -- GitLab From 7918d8c56a6681850c0c359c41d0669a86a514c6 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:05 +0800 Subject: [PATCH 4185/9457] usb: gadget: pch_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pch_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 6534f36866dc..1c7379ac2379 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -2592,9 +2592,9 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) /* Complete request queue */ empty_req_queue(ep); } - if (dev->driver && dev->driver->disconnect) { + if (dev->driver) { spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); + usb_gadget_udc_reset(&dev->gadget, dev->driver); spin_lock(&dev->lock); } } -- GitLab From 107d13c76f46a3b96decac828ac09a1a87e07014 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:06 +0800 Subject: [PATCH 4186/9457] usb: gadget: amd5536udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 606b9009861a..de7e5e2ccf1c 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -2871,7 +2871,7 @@ __acquires(dev->lock) dev->driver->resume(&dev->gadget); dev->sys_suspended = 0; } - dev->driver->disconnect(&dev->gadget); + usb_gadget_udc_reset(&dev->gadget, dev->driver); spin_lock(&dev->lock); /* disable ep0 to empty req queue */ -- GitLab From 5443a7915f8ac529fb868ba26992046f63402760 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:07 +0800 Subject: [PATCH 4187/9457] usb: gadget: r8a66597-udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/r8a66597-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index be31b57a8ba1..06870da0b988 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1345,7 +1345,7 @@ static void irq_device_state(struct r8a66597 *r8a66597) if (dvsq == DS_DFLT) { /* bus reset */ spin_unlock(&r8a66597->lock); - r8a66597->driver->disconnect(&r8a66597->gadget); + usb_gadget_udc_reset(&r8a66597->gadget, r8a66597->driver); spin_lock(&r8a66597->lock); r8a66597_update_usb_speed(r8a66597); } -- GitLab From 4f6bd9fd4a7bee9b0b1b432f96dfade2414930df Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:08 +0800 Subject: [PATCH 4188/9457] usb: gadget: bcm63xx_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/bcm63xx_udc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 9319ff27c73f..c790918b337b 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1962,7 +1962,7 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) { struct bcm63xx_udc *udc = dev_id; u32 stat; - bool disconnected = false; + bool disconnected = false, bus_reset = false; stat = usbd_readl(udc, USBD_EVENT_IRQ_STATUS_REG) & usbd_readl(udc, USBD_EVENT_IRQ_MASK_REG); @@ -1990,7 +1990,7 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) udc->ep0_req_reset = 1; schedule_work(&udc->ep0_wq); - disconnected = true; + bus_reset = true; } if (stat & BIT(USBD_EVENT_IRQ_SETUP)) { if (bcm63xx_update_link_speed(udc)) { @@ -2013,6 +2013,8 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) if (disconnected && udc->driver) udc->driver->disconnect(&udc->gadget); + else if (bus_reset && udc->driver) + usb_gadget_udc_reset(&udc->gadget, udc->driver); return IRQ_HANDLED; } -- GitLab From 39dd96d6c5451f5fa005b3581bc409b109a4f0c7 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 6 Nov 2014 14:28:09 +0800 Subject: [PATCH 4189/9457] usb: gadget: atmel_usba_udc: use udc-core's reset notifier Replace usb_gadget_driver's disconnect with udc-core's reset notifier at bus reset handler. Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/atmel_usba_udc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index c537a6604b46..990b26f33738 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1685,11 +1685,10 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) usba_writel(udc, INT_CLR, USBA_END_OF_RESET); reset_all_endpoints(udc); - if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver && udc->driver->disconnect) { + if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) { udc->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock(&udc->lock); - udc->driver->disconnect(&udc->gadget); + usb_gadget_udc_reset(&udc->gadget, udc->driver); spin_lock(&udc->lock); } -- GitLab From 7e1bbeb4292783dcc079156b8fa08d66d17219e0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 7 Nov 2014 19:43:45 -0600 Subject: [PATCH 4190/9457] usb: host: ohci: omap: fix build breakage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e47d925 (usb: move the OTG state from the USB PHY to the OTG structure) moved the OTG state field from struct usb_phy to struct usb_otg but, even though I fixed many other build breakages, I still missed one on ohci-omap.c. Fix the build breakage now. drivers/usb/host/ohci-omap.c: In function ‘start_hnp’: drivers/usb/host/ohci-omap.c:186:19: error: request for member ‘state’ in something not a structure or union hcd->usb_phy->otg.state = OTG_STATE_A_SUSPEND; Signed-off-by: Felipe Balbi --- drivers/usb/host/ohci-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index cf89b4b17f14..3e5df5af3740 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -183,7 +183,7 @@ static void start_hnp(struct ohci_hcd *ohci) otg_start_hnp(hcd->usb_phy->otg); local_irq_save(flags); - hcd->usb_phy->otg.state = OTG_STATE_A_SUSPEND; + hcd->usb_phy->otg->state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); l = omap_readl(OTG_CTRL); l &= ~OTG_A_BUSREQ; -- GitLab From f66261408615093e58e515a1cfefd597c9990e27 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Mon, 10 Nov 2014 14:51:49 +0800 Subject: [PATCH 4191/9457] Bluetooth: hci-uart-ath: Correct the comments in this driver Correct the comments in this driver. Set the CRTSCTS flag means automatic flow control is enabled. Signed-off-by: Fugang Duan Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 0bc8a6a6a148..2ff6dfd2d3f0 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -74,7 +74,7 @@ static int ath_wakeup_ar3k(struct tty_struct *tty) status = tty->driver->ops->tiocmget(tty); - /* Disable Automatic RTSCTS */ + /* Enable Automatic RTSCTS */ ktermios.c_cflag |= CRTSCTS; status = tty_set_termios(tty, &ktermios); -- GitLab From 36e8164882ca6d3c41cb91e6f09a3ed236841f80 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Thu, 30 Oct 2014 11:54:37 -0600 Subject: [PATCH 4192/9457] PCI: Restore detection of read-only BARs Commit 6ac665c63dca ("PCI: rewrite PCI BAR reading code") masked off low-order bits from 'l', but not from 'sz'. Both are passed to pci_size(), which compares 'base == maxbase' to check for read-only BARs. The masking of 'l' means that comparison will never be 'true', so the check for read-only BARs no longer works. Resolve this by also masking off the low-order bits of 'sz' before passing it into pci_size() as 'maxbase'. With this change, pci_size() will once again catch the problems that have been encountered to date: - AGP aperture BAR of AMD-7xx host bridges: if the AGP window is disabled, this BAR is read-only and read as 0x00000008 [1] - BARs 0-4 of ALi IDE controllers can be non-zero and read-only [1] - Intel Sandy Bridge - Thermal Management Controller [8086:0103]; BAR 0 returning 0xfed98004 [2] - Intel Xeon E5 v3/Core i7 Power Control Unit [8086:2fc0]; Bar 0 returning 0x00001a [3] Link: [1] https://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/drivers/pci/probe.c?id=1307ef6621991f1c4bc3cec1b5a4ebd6fd3d66b9 ("PCI: probing read-only BARs" (pre-git)) Link: [2] https://bugzilla.kernel.org/show_bug.cgi?id=43331 Link: [3] https://bugzilla.kernel.org/show_bug.cgi?id=85991 Reported-by: William Unruh Reported-by: Martin Lucina Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas CC: Matthew Wilcox CC: stable@vger.kernel.org # v2.6.27+ --- drivers/pci/probe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5ed99309c758..19dc247618f8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -216,14 +216,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= IORESOURCE_SIZEALIGN; if (res->flags & IORESOURCE_IO) { l &= PCI_BASE_ADDRESS_IO_MASK; + sz &= PCI_BASE_ADDRESS_IO_MASK; mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; } else { l &= PCI_BASE_ADDRESS_MEM_MASK; + sz &= PCI_BASE_ADDRESS_MEM_MASK; mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; } } else { res->flags |= (l & IORESOURCE_ROM_ENABLE); l &= PCI_ROM_ADDRESS_MASK; + sz &= PCI_ROM_ADDRESS_MASK; mask = (u32)PCI_ROM_ADDRESS_MASK; } -- GitLab From 57e2a2c0a698406e6206ab707bd7c3dcf248c738 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 10 Nov 2014 16:29:14 -0800 Subject: [PATCH 4193/9457] f2fs: reduce the number of inline_data inode before clearing it The # of inline_data inode is decreased only when it has inline_data. After clearing the flag, we can't decreased the number. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 8b6610906ea5..231067027745 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -116,8 +116,8 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) /* clear inline data and flag after data writeback */ truncate_inline_data(dn->inode_page, 0); clear_out: - f2fs_clear_inline_inode(dn->inode); stat_dec_inline_inode(dn->inode); + f2fs_clear_inline_inode(dn->inode); sync_inode_page(dn); f2fs_put_dnode(dn); return 0; -- GitLab From b0cffed54338e19e3cc46c9963478223eee0d560 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 8 Nov 2014 20:41:53 -0500 Subject: [PATCH 4194/9457] sunvnet: Fix race between vnet_start_xmit() and vnet_ack() When vnet_start_xmit() is concurrent with vnet_ack(), we may have a race that looks like: thread 1 thread 2 vnet_start_xmit vnet_event_napi -> vnet_rx __vnet_tx_trigger for some desc X at this point dr->prod == X peer sends back a stopped ack for X we process X, but X == dr->prod so we bail out in vnet_ack with !idx_is_pending update dr->prod As a result of the fact that we never processed the stopped ack for X, the Tx path is led to incorrectly believe that the peer is still "started" and reading, but the peer has stopped reading, which will ultimately end in flow-control assertions. The fix is to synchronize the above 2 paths on the netif_tx_lock. Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 5c5fb59adf76..deb395a82e50 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -559,15 +559,17 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) return 0; end = pkt->end_idx; - if (unlikely(!idx_is_pending(dr, end))) - return 0; - vp = port->vp; dev = vp->dev; + netif_tx_lock(dev); + if (unlikely(!idx_is_pending(dr, end))) { + netif_tx_unlock(dev); + return 0; + } + /* sync for race conditions with vnet_start_xmit() and tell xmit it * is time to send a trigger. */ - netif_tx_lock(dev); dr->cons = next_idx(end, dr); desc = vio_dring_entry(dr, dr->cons); if (desc->hdr.state == VIO_DESC_READY && port->start_cons) { -- GitLab From 777362d7215f63318fc4a6fae9b320328d92e9f6 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 8 Nov 2014 20:42:10 -0500 Subject: [PATCH 4195/9457] sunvnet: vnet_ack() should check if !start_cons to send a missed trigger As per comments in vnet_start_xmit, for the edge case when outgoing vnet_start_xmit() data and an incoming STOPPED ACK cross each other in flight, we may need to send the missed START trigger from maybe_tx_wakeup() after checking for a false value of start_cons Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index deb395a82e50..826b3852c7df 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -572,7 +572,7 @@ static int vnet_ack(struct vnet_port *port, void *msgbuf) */ dr->cons = next_idx(end, dr); desc = vio_dring_entry(dr, dr->cons); - if (desc->hdr.state == VIO_DESC_READY && port->start_cons) { + if (desc->hdr.state == VIO_DESC_READY && !port->start_cons) { /* vnet_start_xmit() just populated this dring but missed * sending the "start" LDC message to the consumer. * Send a "start" trigger on its behalf. -- GitLab From df20286ab1e36eaaf1f6c7e5e2c56bea1ffc26c0 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Sat, 8 Nov 2014 20:42:20 -0500 Subject: [PATCH 4196/9457] sunvnet: Add missing rcu_read_unlock() in vnet_start_xmit The out_dropped label will only do rcu_read_unlock for non-null port. So add the missing rcu_read_unlock() when bailing due to non-null port. Signed-off-by: Sowmini Varadhan Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunvnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 826b3852c7df..55d66c9a6627 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -981,8 +981,10 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) rcu_read_lock(); port = __tx_port_find(vp, skb); - if (unlikely(!port)) + if (unlikely(!port)) { + rcu_read_unlock(); goto out_dropped; + } if (skb->len > port->rmtu) { unsigned long localmtu = port->rmtu - ETH_HLEN; -- GitLab From 2e1af7d74f4f7b4d4c1b0fbf5da3b5f92d9c332f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 10 Nov 2014 14:07:20 -0800 Subject: [PATCH 4197/9457] mlx4: restore conditional call to napi_complete_done() After commit 1a28817282 ("mlx4: use napi_complete_done()") we ended up calling napi_complete_done() in the case NAPI poll consumed all its budget. This added extra interrupt pressure, this patch restores proper behavior. Signed-off-by: Eric Dumazet Fixes: 1a28817282 ("mlx4: use napi_complete_done()") Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 46ee78326f1f..5a193f40a14c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -910,13 +910,14 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget) cpu_curr = smp_processor_id(); aff = irq_desc_get_irq_data(cq->irq_desc)->affinity; - if (unlikely(!cpumask_test_cpu(cpu_curr, aff))) { - /* Current cpu is not according to smp_irq_affinity - - * probably affinity changed. need to stop this NAPI - * poll, and restart it on the right CPU - */ - done = 0; - } + if (likely(cpumask_test_cpu(cpu_curr, aff))) + return budget; + + /* Current cpu is not according to smp_irq_affinity - + * probably affinity changed. need to stop this NAPI + * poll, and restart it on the right CPU + */ + done = 0; } /* Done for now */ napi_complete_done(napi, done); -- GitLab From f795d86aaa578501551a2d1b463eac4bbea84db2 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Thu, 30 Oct 2014 11:54:43 -0600 Subject: [PATCH 4198/9457] PCI: Shrink decoding-disabled window while sizing BARs __pci_read_base() disables decoding while sizing device BARs. We can't print while decoding is disabled, which leads to some rather messy exit logic. Coalesce the sizing logic to minimize the time decoding is disabled. This lets us print errors where they're detected. The refactoring also takes advantage of the symmetry of obtaining the BAR's extent (pci_size) and storing the result as the 'region' for both the 32-bit and 64-bit BARs, consolidating both cases. No functional change intended. [bhelgaas: move pci_size() up, per Thomas Petazzoni, Thierry Reding, Kevin Hilman] Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas CC: Matthew Wilcox --- drivers/pci/probe.c | 77 ++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 19dc247618f8..529fcd782e43 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -175,7 +175,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, u64 l64, sz64, mask64; u16 orig_cmd; struct pci_bus_region region, inverted_region; - bool bar_too_big = false, bar_too_high = false, bar_invalid = false; mask = type ? PCI_ROM_ADDRESS_MASK : ~0; @@ -201,8 +200,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit * 1 must be clear. */ - if (!sz || sz == 0xffffffff) - goto fail; + if (sz == 0xffffffff) + sz = 0; /* * I don't know how l can have all bits set. Copied from old code. @@ -215,26 +214,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags = decode_bar(dev, l); res->flags |= IORESOURCE_SIZEALIGN; if (res->flags & IORESOURCE_IO) { - l &= PCI_BASE_ADDRESS_IO_MASK; - sz &= PCI_BASE_ADDRESS_IO_MASK; - mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; + l64 = l & PCI_BASE_ADDRESS_IO_MASK; + sz64 = sz & PCI_BASE_ADDRESS_IO_MASK; + mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT; } else { - l &= PCI_BASE_ADDRESS_MEM_MASK; - sz &= PCI_BASE_ADDRESS_MEM_MASK; - mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; + l64 = l & PCI_BASE_ADDRESS_MEM_MASK; + sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK; + mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; } } else { res->flags |= (l & IORESOURCE_ROM_ENABLE); - l &= PCI_ROM_ADDRESS_MASK; - sz &= PCI_ROM_ADDRESS_MASK; - mask = (u32)PCI_ROM_ADDRESS_MASK; + l64 = l & PCI_ROM_ADDRESS_MASK; + sz64 = sz & PCI_ROM_ADDRESS_MASK; + mask64 = (u32)PCI_ROM_ADDRESS_MASK; } if (res->flags & IORESOURCE_MEM_64) { - l64 = l; - sz64 = sz; - mask64 = mask | (u64)~0 << 32; - pci_read_config_dword(dev, pos + 4, &l); pci_write_config_dword(dev, pos + 4, ~0); pci_read_config_dword(dev, pos + 4, &sz); @@ -242,18 +237,27 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, l64 |= ((u64)l << 32); sz64 |= ((u64)sz << 32); + mask64 |= ((u64)~0 << 32); + } - sz64 = pci_size(l64, sz64, mask64); + if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE)) + pci_write_config_word(dev, PCI_COMMAND, orig_cmd); - if (!sz64) - goto fail; + if (!sz64) + goto fail; + + sz64 = pci_size(l64, sz64, mask64); + if (!sz64) + goto fail; + if (res->flags & IORESOURCE_MEM_64) { if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && sz64 > 0x100000000ULL) { res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; res->start = 0; res->end = 0; - bar_too_big = true; + dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", + pos, (unsigned long long)sz64); goto out; } @@ -262,22 +266,15 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= IORESOURCE_UNSET; res->start = 0; res->end = sz64; - bar_too_high = true; + dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n", + pos, (unsigned long long)l64); goto out; - } else { - region.start = l64; - region.end = l64 + sz64; } - } else { - sz = pci_size(l, sz, mask); - - if (!sz) - goto fail; - - region.start = l; - region.end = l + sz; } + region.start = l64; + region.end = l64 + sz64; + pcibios_bus_to_resource(dev->bus, res, ®ion); pcibios_resource_to_bus(dev->bus, &inverted_region, res); @@ -296,7 +293,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= IORESOURCE_UNSET; res->start = 0; res->end = region.end - region.start; - bar_invalid = true; + dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n", + pos, (unsigned long long)region.start); } goto out; @@ -305,19 +303,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, fail: res->flags = 0; out: - if (!dev->mmio_always_on && - (orig_cmd & PCI_COMMAND_DECODE_ENABLE)) - pci_write_config_word(dev, PCI_COMMAND, orig_cmd); - - if (bar_too_big) - dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", - pos, (unsigned long long) sz64); - if (bar_too_high) - dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n", - pos, (unsigned long long) l64); - if (bar_invalid) - dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n", - pos, (unsigned long long) region.start); if (res->flags) dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); -- GitLab From ff0387c3777f2438bad2088abe442c9f231b0be4 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 10 Nov 2014 21:02:17 -0700 Subject: [PATCH 4199/9457] PCI: Delete unnecessary NULL pointer checks The functions pci_dev_put(), pci_pme_wakeup_bus(), and put_device() return immediately if their argument is NULL. Thus the test before the call is not needed. Remove these unnecessary tests. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Bjorn Helgaas --- drivers/pci/pci-acpi.c | 3 +-- drivers/pci/probe.c | 3 +-- drivers/pci/search.c | 3 +-- drivers/pci/xen-pcifront.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 6ebf8edc5f3c..3542150fc8a3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -322,8 +322,7 @@ static void pci_acpi_wake_dev(struct work_struct *work) pci_wakeup_event(pci_dev); pm_runtime_resume(&pci_dev->dev); - if (pci_dev->subordinate) - pci_pme_wakeup_bus(pci_dev->subordinate); + pci_pme_wakeup_bus(pci_dev->subordinate); } /** diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5ed99309c758..eb927c04e290 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -87,8 +87,7 @@ static void release_pcibus_dev(struct device *dev) { struct pci_bus *pci_bus = to_pci_bus(dev); - if (pci_bus->bridge) - put_device(pci_bus->bridge); + put_device(pci_bus->bridge); pci_bus_remove_resources(pci_bus); pci_release_bus_of_node(pci_bus); kfree(pci_bus); diff --git a/drivers/pci/search.c b/drivers/pci/search.c index a81f413083e4..a20ce7d5e2a7 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -271,8 +271,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, match_pci_dev_by_id); if (dev) pdev = to_pci_dev(dev); - if (from) - pci_dev_put(from); + pci_dev_put(from); return pdev; } diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 116ca3746adb..f01b26dc83a4 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -596,8 +596,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, pcidev = pci_get_bus_and_slot(bus, devfn); if (!pcidev || !pcidev->driver) { dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); - if (pcidev) - pci_dev_put(pcidev); + pci_dev_put(pcidev); return result; } pdrv = pcidev->driver; -- GitLab From 754834b9caae8d1380f66a5f0337547e9361094d Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Thu, 6 Nov 2014 17:45:55 +0100 Subject: [PATCH 4200/9457] PCI: Simplify if-return sequences Simplify a trivial if-return sequence. Possibly combine with a preceding function call. Generated by: scripts/coccinelle/misc/simple_return.cocci Signed-off-by: Quentin Lambert Signed-off-by: Bjorn Helgaas --- drivers/pci/hotplug/ibmphp_res.c | 5 +---- drivers/pci/pci.c | 6 +----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index 219ba8090a37..f279060cf6e2 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c @@ -376,10 +376,7 @@ int __init ibmphp_rsrc_init (void) if (rc) return rc; } - rc = once_over (); /* This is to align ranges (so no -1) */ - if (rc) - return rc; - return 0; + return once_over (); /* This is to align ranges (so no -1) */ } /******************************************************************************** diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 625a4ace10b4..9a5871f530a7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1012,11 +1012,7 @@ int pci_save_state(struct pci_dev *dev) if (i != 0) return i; - i = pci_save_vc_state(dev); - if (i != 0) - return i; - - return 0; + return pci_save_vc_state(dev); } EXPORT_SYMBOL(pci_save_state); -- GitLab From 7992074960a8bea6467cab3555b80a404ebd9b82 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 3 Nov 2014 15:43:04 +0100 Subject: [PATCH 4201/9457] iwlwifi: mvm: use correct type for firmware status The status variable should be unsigned as the function call requires a u32 not int pointer, fix that. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/sta.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index dd0dc5bf8583..74a7c9138ce9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -1077,7 +1077,8 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, { struct iwl_mvm_add_sta_key_cmd cmd = {}; __le16 key_flags; - int ret, status; + int ret; + u32 status; u16 keyidx; int i; @@ -1285,7 +1286,8 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvm_sta; struct iwl_mvm_add_sta_key_cmd cmd = {}; __le16 key_flags; - int ret, status; + int ret; + u32 status; u8 sta_id; lockdep_assert_held(&mvm->mutex); -- GitLab From 6ce73e6569d45755483b44033b985abf29d5a4db Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 11 Sep 2014 13:00:19 +0300 Subject: [PATCH 4202/9457] iwlwifi: mvm: expose some static APIs for use by TDLS code Mostly functions related to building Tx-commands for sending to FW. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mvm.h | 12 +++++++++++ drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 4 ++-- drivers/net/wireless/iwlwifi/mvm/tx.c | 22 ++++++++++----------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 256765accbc6..1fc94e1db015 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -831,6 +831,16 @@ int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id, int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_sta *sta); int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb); +void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, u8 sta_id); +void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct iwl_tx_cmd *tx_cmd, + struct sk_buff *skb_frag); +void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, __le16 fc); #ifdef CONFIG_IWLWIFI_DEBUG const char *iwl_mvm_get_tx_fail_reason(u32 status); #else @@ -900,6 +910,8 @@ void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt); int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm); +u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef); +u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef); /* MAC (virtual interface) programming */ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 12283b55ee84..1c0d4a45c1a8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -68,7 +68,7 @@ #include "mvm.h" /* Maps the driver specific channel width definition to the the fw values */ -static inline u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) +u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) { switch (chandef->width) { case NL80211_CHAN_WIDTH_20_NOHT: @@ -90,7 +90,7 @@ static inline u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) * Maps the driver specific control channel position (relative to the center * freq) definitions to the the fw values */ -static inline u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef) +u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef) { switch (chandef->chan->center_freq - chandef->center_freq1) { case -70: diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 8d848735cdb8..4789c77632e5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -73,9 +73,9 @@ /* * Sets most of the Tx cmd's fields */ -static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, - struct iwl_tx_cmd *tx_cmd, - struct ieee80211_tx_info *info, u8 sta_id) +void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, u8 sta_id) { struct ieee80211_hdr *hdr = (void *)skb->data; __le16 fc = hdr->frame_control; @@ -149,11 +149,9 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, /* * Sets the fields in the Tx cmd that are rate related */ -static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, - struct iwl_tx_cmd *tx_cmd, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - __le16 fc) +void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, __le16 fc) { u32 rate_flags; int rate_idx; @@ -232,10 +230,10 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, /* * Sets the fields in the Tx cmd that are crypto related */ -static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, - struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd, - struct sk_buff *skb_frag) +void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct iwl_tx_cmd *tx_cmd, + struct sk_buff *skb_frag) { struct ieee80211_key_conf *keyconf = info->control.hw_key; -- GitLab From efad21d2a2e9b69dfeee576cd01831e94290241c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 3 Nov 2014 15:51:47 +0100 Subject: [PATCH 4203/9457] iwlwifi: mvm: rs: don't use shadowing variable The variable 'tid' is already defined in this function, so use just 't' for the new one. As we return from the function just overwriting 'tid' would be acceptable, but less obvious to the reader. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index ce884847cc8a..6775100a75e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1110,10 +1110,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (time_after(jiffies, (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) { - int tid; + int t; + IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); - for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) - ieee80211_stop_tx_ba_session(sta, tid); + for (t = 0; t < IWL_MAX_TID_COUNT; t++) + ieee80211_stop_tx_ba_session(sta, t); iwl_mvm_rs_rate_init(mvm, sta, info->band, false); return; -- GitLab From e4c787dac21e50ac9ef53fac91b9182d4fede465 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Nov 2014 14:22:01 +0900 Subject: [PATCH 4204/9457] Revert "serial: of-serial: fetch line number from DT" This reverts commit 1bd8324535ec1ff44aef55c0e40b9e7d56b310fb. To quote Olof: This commit broke a whole lot of tegra boards in last night's -next here. In particular, I've been looking at tegra20-seaboard, which now doesn't boot with console any more. Breaking existing systems is bad. Reported-by: Olof Johansson Cc: Lucas Stach Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 22f06a6479e6..fd00e2521584 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -102,10 +102,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_property_read_u32(np, "fifo-size", &prop) == 0) port->fifosize = prop; - /* Check for a fixed line number */ - if ((ret = of_alias_get_id(np, "serial")) >= 0) - port->line = ret; - port->irq = irq_of_parse_and_map(np, 0); port->iotype = UPIO_MEM; if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { -- GitLab From 6386a15c445c1cd0108671a0078a4b65af89799c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 11 Nov 2014 00:49:25 +0100 Subject: [PATCH 4205/9457] Revert "core: platform: add warning if driver has no owner" This is too noisy at the moment, triggered by codepaths not accessed on our test-systems. Needs more investigation. Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 6b10ff3bb410..9e29943e56ca 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -151,9 +151,6 @@ int driver_register(struct device_driver *drv) BUG_ON(!drv->bus->p); - if (!drv->owner) - printk(KERN_WARNING "Driver '%s' needs an owner", drv->name); - if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) -- GitLab From 4f48795b6154852d07d971e402c35ecc460ddcb6 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 10 Nov 2014 09:26:29 +1030 Subject: [PATCH 4206/9457] module: Wait for RCU synchronizing before releasing a module Wait for RCU synchronizing on failure path of module loading before releasing struct module, because the memory of mod->list can still be accessed by list walkers (e.g. kallsyms). Signed-off-by: Masami Hiramatsu Signed-off-by: Rusty Russell --- kernel/module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index 88cec1ddb1e3..331b03f6b411 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3326,6 +3326,8 @@ static int load_module(struct load_info *info, const char __user *uargs, /* Unlink carefully: kallsyms could be walking list. */ list_del_rcu(&mod->list); wake_up_all(&module_wq); + /* Wait for RCU synchronizing before releasing mod->list. */ + synchronize_rcu(); mutex_unlock(&module_mutex); free_module: module_deallocate(mod, info); -- GitLab From 461e34aed0550fee706a9a28fb453830b5079ea0 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 10 Nov 2014 09:27:29 +1030 Subject: [PATCH 4207/9457] module: Unlink module with RCU synchronizing instead of stop_machine Unlink module from module list with RCU synchronizing instead of using stop_machine(). Since module list is already protected by rcu, we don't need stop_machine() anymore. Signed-off-by: Masami Hiramatsu Signed-off-by: Rusty Russell --- kernel/module.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 331b03f6b411..bed608b8c8a6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1697,18 +1697,6 @@ static void mod_sysfs_teardown(struct module *mod) mod_sysfs_fini(mod); } -/* - * unlink the module with the whole machine is stopped with interrupts off - * - this defends against kallsyms not taking locks - */ -static int __unlink_module(void *_mod) -{ - struct module *mod = _mod; - list_del(&mod->list); - module_bug_cleanup(mod); - return 0; -} - #ifdef CONFIG_DEBUG_SET_MODULE_RONX /* * LKM RO/NX protection: protect module's text/ro-data @@ -1860,7 +1848,11 @@ static void free_module(struct module *mod) /* Now we can delete it from the lists */ mutex_lock(&module_mutex); - stop_machine(__unlink_module, mod, NULL); + /* Unlink carefully: kallsyms could be walking list. */ + list_del_rcu(&mod->list); + /* Wait for RCU synchronizing before releasing mod->list. */ + synchronize_rcu(); + module_bug_cleanup(mod); mutex_unlock(&module_mutex); /* This may be NULL, but that's OK */ -- GitLab From 0286b5ea125e58b4797747f688949c05394412e8 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 10 Nov 2014 09:28:29 +1030 Subject: [PATCH 4208/9457] lib/bug: Use RCU list ops for module_bug_list Actually since module_bug_list should be used in BUG context, we may not need this. But for someone who want to use this from normal context, this makes module_bug_list an RCU list. Signed-off-by: Masami Hiramatsu Signed-off-by: Rusty Russell --- kernel/module.c | 5 +++-- lib/bug.c | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index bed608b8c8a6..d596a306b0a1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1850,9 +1850,10 @@ static void free_module(struct module *mod) mutex_lock(&module_mutex); /* Unlink carefully: kallsyms could be walking list. */ list_del_rcu(&mod->list); - /* Wait for RCU synchronizing before releasing mod->list. */ - synchronize_rcu(); + /* Remove this module from bug list, this uses list_del_rcu */ module_bug_cleanup(mod); + /* Wait for RCU synchronizing before releasing mod->list and buglist. */ + synchronize_rcu(); mutex_unlock(&module_mutex); /* This may be NULL, but that's OK */ diff --git a/lib/bug.c b/lib/bug.c index d1d7c7878900..0c3bd9552b6f 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -64,16 +64,22 @@ static LIST_HEAD(module_bug_list); static const struct bug_entry *module_find_bug(unsigned long bugaddr) { struct module *mod; + const struct bug_entry *bug = NULL; - list_for_each_entry(mod, &module_bug_list, bug_list) { - const struct bug_entry *bug = mod->bug_table; + rcu_read_lock(); + list_for_each_entry_rcu(mod, &module_bug_list, bug_list) { unsigned i; + bug = mod->bug_table; for (i = 0; i < mod->num_bugs; ++i, ++bug) if (bugaddr == bug_addr(bug)) - return bug; + goto out; } - return NULL; + bug = NULL; +out: + rcu_read_unlock(); + + return bug; } void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, @@ -99,13 +105,15 @@ void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, * Strictly speaking this should have a spinlock to protect against * traversals, but since we only traverse on BUG()s, a spinlock * could potentially lead to deadlock and thus be counter-productive. + * Thus, this uses RCU to safely manipulate the bug list, since BUG + * must run in non-interruptive state. */ - list_add(&mod->bug_list, &module_bug_list); + list_add_rcu(&mod->bug_list, &module_bug_list); } void module_bug_cleanup(struct module *mod) { - list_del(&mod->bug_list); + list_del_rcu(&mod->bug_list); } #else -- GitLab From 2f35c41f58a978dfa44ffa102249d556caa99eeb Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 10 Nov 2014 09:29:29 +1030 Subject: [PATCH 4209/9457] module: Replace module_ref with atomic_t refcnt Replace module_ref per-cpu complex reference counter with an atomic_t simple refcnt. This is for code simplification. Signed-off-by: Masami Hiramatsu Signed-off-by: Rusty Russell --- include/linux/module.h | 16 +------------- include/trace/events/module.h | 2 +- kernel/module.c | 39 +++++------------------------------ 3 files changed, 7 insertions(+), 50 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 71f282a4e307..ebfb0e153c6a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -210,20 +210,6 @@ enum module_state { MODULE_STATE_UNFORMED, /* Still setting it up. */ }; -/** - * struct module_ref - per cpu module reference counts - * @incs: number of module get on this cpu - * @decs: number of module put on this cpu - * - * We force an alignment on 8 or 16 bytes, so that alloc_percpu() - * put @incs/@decs in same cache line, with no extra memory cost, - * since alloc_percpu() is fine grained. - */ -struct module_ref { - unsigned long incs; - unsigned long decs; -} __attribute((aligned(2 * sizeof(unsigned long)))); - struct module { enum module_state state; @@ -367,7 +353,7 @@ struct module { /* Destruction function. */ void (*exit)(void); - struct module_ref __percpu *refptr; + atomic_t refcnt; #endif #ifdef CONFIG_CONSTRUCTORS diff --git a/include/trace/events/module.h b/include/trace/events/module.h index 7c5cbfe3fc49..81c4c183d348 100644 --- a/include/trace/events/module.h +++ b/include/trace/events/module.h @@ -80,7 +80,7 @@ DECLARE_EVENT_CLASS(module_refcnt, TP_fast_assign( __entry->ip = ip; - __entry->refcnt = __this_cpu_read(mod->refptr->incs) - __this_cpu_read(mod->refptr->decs); + __entry->refcnt = atomic_read(&mod->refcnt); __assign_str(name, mod->name); ), diff --git a/kernel/module.c b/kernel/module.c index d596a306b0a1..b1d485df5ac1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -631,15 +631,11 @@ EXPORT_TRACEPOINT_SYMBOL(module_get); /* Init the unload section of the module. */ static int module_unload_init(struct module *mod) { - mod->refptr = alloc_percpu(struct module_ref); - if (!mod->refptr) - return -ENOMEM; - INIT_LIST_HEAD(&mod->source_list); INIT_LIST_HEAD(&mod->target_list); /* Hold reference count during initialization. */ - raw_cpu_write(mod->refptr->incs, 1); + atomic_set(&mod->refcnt, 1); return 0; } @@ -721,8 +717,6 @@ static void module_unload_free(struct module *mod) kfree(use); } mutex_unlock(&module_mutex); - - free_percpu(mod->refptr); } #ifdef CONFIG_MODULE_FORCE_UNLOAD @@ -772,28 +766,7 @@ static int try_stop_module(struct module *mod, int flags, int *forced) unsigned long module_refcount(struct module *mod) { - unsigned long incs = 0, decs = 0; - int cpu; - - for_each_possible_cpu(cpu) - decs += per_cpu_ptr(mod->refptr, cpu)->decs; - /* - * ensure the incs are added up after the decs. - * module_put ensures incs are visible before decs with smp_wmb. - * - * This 2-count scheme avoids the situation where the refcount - * for CPU0 is read, then CPU0 increments the module refcount, - * then CPU1 drops that refcount, then the refcount for CPU1 is - * read. We would record a decrement but not its corresponding - * increment so we would see a low count (disaster). - * - * Rare situation? But module_refcount can be preempted, and we - * might be tallying up 4096+ CPUs. So it is not impossible. - */ - smp_rmb(); - for_each_possible_cpu(cpu) - incs += per_cpu_ptr(mod->refptr, cpu)->incs; - return incs - decs; + return (unsigned long)atomic_read(&mod->refcnt); } EXPORT_SYMBOL(module_refcount); @@ -935,7 +908,7 @@ void __module_get(struct module *module) { if (module) { preempt_disable(); - __this_cpu_inc(module->refptr->incs); + atomic_inc(&module->refcnt); trace_module_get(module, _RET_IP_); preempt_enable(); } @@ -950,7 +923,7 @@ bool try_module_get(struct module *module) preempt_disable(); if (likely(module_is_live(module))) { - __this_cpu_inc(module->refptr->incs); + atomic_inc(&module->refcnt); trace_module_get(module, _RET_IP_); } else ret = false; @@ -965,9 +938,7 @@ void module_put(struct module *module) { if (module) { preempt_disable(); - smp_wmb(); /* see comment in module_refcount */ - __this_cpu_inc(module->refptr->decs); - + atomic_dec(&module->refcnt); trace_module_put(module, _RET_IP_); preempt_enable(); } -- GitLab From e513cc1c07e2ab93a4514eec9833e031df3e30bb Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 10 Nov 2014 09:30:29 +1030 Subject: [PATCH 4210/9457] module: Remove stop_machine from module unloading Remove stop_machine from module unloading by adding new reference counting algorithm. This atomic refcounter works like a semaphore, it can get (be incremented) only when the counter is not 0. When loading a module, kmodule subsystem sets the counter MODULE_REF_BASE (= 1). And when unloading the module, it subtracts MODULE_REF_BASE from the counter. If no one refers the module, the refcounter becomes 0 and we can remove the module safely. If someone referes it, we try to recover the counter by adding MODULE_REF_BASE unless the counter becomes 0, because the referrer can put the module right before recovering. If the recovering is failed, we can get the 0 refcount and it never be incremented again, it can be removed safely too. Note that __module_get() forcibly gets the module refcounter, users should use try_module_get() instead of that. Signed-off-by: Masami Hiramatsu Signed-off-by: Rusty Russell --- kernel/module.c | 67 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index b1d485df5ac1..e772595d73db 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -98,7 +97,7 @@ * 1) List of modules (also safely readable with preempt_disable), * 2) module_use links, * 3) module_addr_min/module_addr_max. - * (delete uses stop_machine/add uses RCU list operations). */ + * (delete and add uses RCU list operations). */ DEFINE_MUTEX(module_mutex); EXPORT_SYMBOL_GPL(module_mutex); static LIST_HEAD(modules); @@ -628,14 +627,23 @@ static char last_unloaded_module[MODULE_NAME_LEN+1]; EXPORT_TRACEPOINT_SYMBOL(module_get); +/* MODULE_REF_BASE is the base reference count by kmodule loader. */ +#define MODULE_REF_BASE 1 + /* Init the unload section of the module. */ static int module_unload_init(struct module *mod) { + /* + * Initialize reference counter to MODULE_REF_BASE. + * refcnt == 0 means module is going. + */ + atomic_set(&mod->refcnt, MODULE_REF_BASE); + INIT_LIST_HEAD(&mod->source_list); INIT_LIST_HEAD(&mod->target_list); /* Hold reference count during initialization. */ - atomic_set(&mod->refcnt, 1); + atomic_inc(&mod->refcnt); return 0; } @@ -734,39 +742,39 @@ static inline int try_force_unload(unsigned int flags) } #endif /* CONFIG_MODULE_FORCE_UNLOAD */ -struct stopref +/* Try to release refcount of module, 0 means success. */ +static int try_release_module_ref(struct module *mod) { - struct module *mod; - int flags; - int *forced; -}; + int ret; -/* Whole machine is stopped with interrupts off when this runs. */ -static int __try_stop_module(void *_sref) -{ - struct stopref *sref = _sref; + /* Try to decrement refcnt which we set at loading */ + ret = atomic_sub_return(MODULE_REF_BASE, &mod->refcnt); + BUG_ON(ret < 0); + if (ret) + /* Someone can put this right now, recover with checking */ + ret = atomic_add_unless(&mod->refcnt, MODULE_REF_BASE, 0); + + return ret; +} +static int try_stop_module(struct module *mod, int flags, int *forced) +{ /* If it's not unused, quit unless we're forcing. */ - if (module_refcount(sref->mod) != 0) { - if (!(*sref->forced = try_force_unload(sref->flags))) + if (try_release_module_ref(mod) != 0) { + *forced = try_force_unload(flags); + if (!(*forced)) return -EWOULDBLOCK; } /* Mark it as dying. */ - sref->mod->state = MODULE_STATE_GOING; - return 0; -} - -static int try_stop_module(struct module *mod, int flags, int *forced) -{ - struct stopref sref = { mod, flags, forced }; + mod->state = MODULE_STATE_GOING; - return stop_machine(__try_stop_module, &sref, NULL); + return 0; } unsigned long module_refcount(struct module *mod) { - return (unsigned long)atomic_read(&mod->refcnt); + return (unsigned long)atomic_read(&mod->refcnt) - MODULE_REF_BASE; } EXPORT_SYMBOL(module_refcount); @@ -921,11 +929,11 @@ bool try_module_get(struct module *module) if (module) { preempt_disable(); - - if (likely(module_is_live(module))) { - atomic_inc(&module->refcnt); + /* Note: here, we can fail to get a reference */ + if (likely(module_is_live(module) && + atomic_inc_not_zero(&module->refcnt) != 0)) trace_module_get(module, _RET_IP_); - } else + else ret = false; preempt_enable(); @@ -936,9 +944,12 @@ EXPORT_SYMBOL(try_module_get); void module_put(struct module *module) { + int ret; + if (module) { preempt_disable(); - atomic_dec(&module->refcnt); + ret = atomic_dec_if_positive(&module->refcnt); + WARN_ON(ret < 0); /* Failed to put refcount */ trace_module_put(module, _RET_IP_); preempt_enable(); } -- GitLab From 6da0b565150b32318757062bc75834113f0508d6 Mon Sep 17 00:00:00 2001 From: Ionut Alexa Date: Mon, 10 Nov 2014 09:31:29 +1030 Subject: [PATCH 4211/9457] kernel:module Fix coding style errors and warnings. Fixed codin style errors and warnings. Changes printk with print_debug/warn. Changed seq_printf to seq_puts. Signed-off-by: Ionut Alexa Signed-off-by: Rusty Russell (removed bogus KERN_DEFAULT conversion) --- kernel/module.c | 53 ++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index e772595d73db..381105b2aaae 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -157,13 +157,13 @@ static BLOCKING_NOTIFIER_HEAD(module_notify_list); * Protected by module_mutex. */ static unsigned long module_addr_min = -1UL, module_addr_max = 0; -int register_module_notifier(struct notifier_block * nb) +int register_module_notifier(struct notifier_block *nb) { return blocking_notifier_chain_register(&module_notify_list, nb); } EXPORT_SYMBOL(register_module_notifier); -int unregister_module_notifier(struct notifier_block * nb) +int unregister_module_notifier(struct notifier_block *nb) { return blocking_notifier_chain_unregister(&module_notify_list, nb); } @@ -858,8 +858,10 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod) seq_printf(m, " %lu ", module_refcount(mod)); - /* Always include a trailing , so userspace can differentiate - between this and the old multi-field proc format. */ + /* + * Always include a trailing , so userspace can differentiate + * between this and the old multi-field proc format. + */ list_for_each_entry(use, &mod->source_list, source_list) { printed_something = 1; seq_printf(m, "%s,", use->source->name); @@ -867,11 +869,11 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod) if (mod->init != NULL && mod->exit == NULL) { printed_something = 1; - seq_printf(m, "[permanent],"); + seq_puts(m, "[permanent],"); } if (!printed_something) - seq_printf(m, "-"); + seq_puts(m, "-"); } void __symbol_put(const char *symbol) @@ -960,7 +962,7 @@ EXPORT_SYMBOL(module_put); static inline void print_unload_info(struct seq_file *m, struct module *mod) { /* We don't know the usage count, or what modules are using. */ - seq_printf(m, " - -"); + seq_puts(m, " - -"); } static inline void module_unload_free(struct module *mod) @@ -1113,7 +1115,7 @@ static unsigned long maybe_relocated(unsigned long crc, static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, - struct module *mod, + struct module *mod, const unsigned long *crc, const struct module *crc_owner) { @@ -1147,7 +1149,7 @@ static int check_version(Elf_Shdr *sechdrs, return 0; bad_version: - printk("%s: disagrees about version of symbol %s\n", + pr_warn("%s: disagrees about version of symbol %s\n", mod->name, symname); return 0; } @@ -1182,7 +1184,7 @@ static inline int same_magic(const char *amagic, const char *bmagic, static inline int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, - struct module *mod, + struct module *mod, const unsigned long *crc, const struct module *crc_owner) { @@ -1270,15 +1272,13 @@ static inline bool sect_empty(const Elf_Shdr *sect) return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; } -struct module_sect_attr -{ +struct module_sect_attr { struct module_attribute mattr; char *name; unsigned long address; }; -struct module_sect_attrs -{ +struct module_sect_attrs { struct attribute_group grp; unsigned int nsections; struct module_sect_attr attrs[0]; @@ -1532,7 +1532,8 @@ static int module_add_modinfo_attrs(struct module *mod) (attr->test && attr->test(mod))) { memcpy(temp_attr, attr, sizeof(*temp_attr)); sysfs_attr_init(&temp_attr->attr); - error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr); + error = sysfs_create_file(&mod->mkobj.kobj, + &temp_attr->attr); ++temp_attr; } } @@ -1548,7 +1549,7 @@ static void module_remove_modinfo_attrs(struct module *mod) /* pick a field to test for end of list */ if (!attr->attr.name) break; - sysfs_remove_file(&mod->mkobj.kobj,&attr->attr); + sysfs_remove_file(&mod->mkobj.kobj, &attr->attr); if (attr->free) attr->free(mod); } @@ -1930,7 +1931,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) /* We compiled with -fno-common. These are not supposed to happen. */ pr_debug("Common symbol: %s\n", name); - printk("%s: please compile with -fno-common\n", + pr_warn("%s: please compile with -fno-common\n", mod->name); ret = -ENOEXEC; break; @@ -2234,7 +2235,7 @@ static char elf_type(const Elf_Sym *sym, const struct load_info *info) } static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, - unsigned int shnum) + unsigned int shnum) { const Elf_Shdr *sec; @@ -2710,7 +2711,7 @@ static int find_module_sections(struct module *mod, struct load_info *info) * This shouldn't happen with same compiler and binutils * building all parts of the module. */ - printk(KERN_WARNING "%s: has both .ctors and .init_array.\n", + pr_warn("%s: has both .ctors and .init_array.\n", mod->name); return -EINVAL; } @@ -2998,8 +2999,10 @@ static int do_init_module(struct module *mod) if (mod->init != NULL) ret = do_one_initcall(mod->init); if (ret < 0) { - /* Init routine failed: abort. Try to protect us from - buggy refcounters. */ + /* + * Init routine failed: abort. Try to protect us from + * buggy refcounters. + */ mod->state = MODULE_STATE_GOING; synchronize_sched(); module_put(mod); @@ -3151,7 +3154,7 @@ static int complete_formation(struct module *mod, struct load_info *info) static int unknown_module_param_cb(char *param, char *val, const char *modname) { - /* Check for magic 'dyndbg' arg */ + /* Check for magic 'dyndbg' arg */ int ret = ddebug_dyndbg_module_param_cb(param, val, modname); if (ret != 0) pr_warn("%s: unknown parameter '%s' ignored\n", modname, param); @@ -3636,8 +3639,8 @@ static int m_show(struct seq_file *m, void *p) /* Informative for users. */ seq_printf(m, " %s", - mod->state == MODULE_STATE_GOING ? "Unloading": - mod->state == MODULE_STATE_COMING ? "Loading": + mod->state == MODULE_STATE_GOING ? "Unloading" : + mod->state == MODULE_STATE_COMING ? "Loading" : "Live"); /* Used by oprofile and other similar tools. */ seq_printf(m, " 0x%pK", mod->module_core); @@ -3646,7 +3649,7 @@ static int m_show(struct seq_file *m, void *p) if (mod->taints) seq_printf(m, " %s", module_flags(mod, buf)); - seq_printf(m, "\n"); + seq_puts(m, "\n"); return 0; } -- GitLab From 18eb74fa94161380c1acc9cf562cb835c4e54a25 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 10 Nov 2014 09:32:29 +1030 Subject: [PATCH 4212/9457] params: cleanup sysfs allocation commit 63662139e519ce06090b2759cf4a1d291b9cc0e2 attempted to patch a leak (which would only happen on OOM, ie. never), but it didn't quite work. This rewrites the code to be as simple as possible. add_sysfs_param() adds a parameter. If it fails, it's the caller's responsibility to clean up the parameters which already exist. The kzalloc-then-always-krealloc pattern is perhaps overly simplistic, but this code has clearly confused people. It worked on me... Signed-off-by: Rusty Russell --- kernel/params.c | 95 +++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/kernel/params.c b/kernel/params.c index db97b791390f..795321aba29f 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -603,74 +603,65 @@ static __modinit int add_sysfs_param(struct module_kobject *mk, const struct kernel_param *kp, const char *name) { - struct module_param_attrs *new; - struct attribute **attrs; - int err, num; + struct module_param_attrs *new_mp; + struct attribute **new_attrs; + unsigned int i; /* We don't bother calling this with invisible parameters. */ BUG_ON(!kp->perm); if (!mk->mp) { - num = 0; - attrs = NULL; - } else { - num = mk->mp->num; - attrs = mk->mp->grp.attrs; + /* First allocation. */ + mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL); + if (!mk->mp) + return -ENOMEM; + mk->mp->grp.name = "parameters"; + /* NULL-terminated attribute array. */ + mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]), + GFP_KERNEL); + /* Caller will cleanup via free_module_param_attrs */ + if (!mk->mp->grp.attrs) + return -ENOMEM; } - /* Enlarge. */ - new = krealloc(mk->mp, - sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1), - GFP_KERNEL); - if (!new) { - kfree(attrs); - err = -ENOMEM; - goto fail; - } - /* Despite looking like the typical realloc() bug, this is safe. - * We *want* the old 'attrs' to be freed either way, and we'll store - * the new one in the success case. */ - attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL); - if (!attrs) { - err = -ENOMEM; - goto fail_free_new; - } + /* Enlarge allocations. */ + new_mp = krealloc(mk->mp, + sizeof(*mk->mp) + + sizeof(mk->mp->attrs[0]) * (mk->mp->num + 1), + GFP_KERNEL); + if (!new_mp) + return -ENOMEM; + mk->mp = new_mp; - /* Sysfs wants everything zeroed. */ - memset(new, 0, sizeof(*new)); - memset(&new->attrs[num], 0, sizeof(new->attrs[num])); - memset(&attrs[num], 0, sizeof(attrs[num])); - new->grp.name = "parameters"; - new->grp.attrs = attrs; + /* Extra pointer for NULL terminator */ + new_attrs = krealloc(mk->mp->grp.attrs, + sizeof(mk->mp->grp.attrs[0]) * (mk->mp->num + 2), + GFP_KERNEL); + if (!new_attrs) + return -ENOMEM; + mk->mp->grp.attrs = new_attrs; /* Tack new one on the end. */ - sysfs_attr_init(&new->attrs[num].mattr.attr); - new->attrs[num].param = kp; - new->attrs[num].mattr.show = param_attr_show; - new->attrs[num].mattr.store = param_attr_store; - new->attrs[num].mattr.attr.name = (char *)name; - new->attrs[num].mattr.attr.mode = kp->perm; - new->num = num+1; + sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr); + mk->mp->attrs[mk->mp->num].param = kp; + mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show; + mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store; + mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name; + mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm; + mk->mp->num++; /* Fix up all the pointers, since krealloc can move us */ - for (num = 0; num < new->num; num++) - new->grp.attrs[num] = &new->attrs[num].mattr.attr; - new->grp.attrs[num] = NULL; - - mk->mp = new; + for (i = 0; i < mk->mp->num; i++) + mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr; + mk->mp->grp.attrs[mk->mp->num] = NULL; return 0; - -fail_free_new: - kfree(new); -fail: - mk->mp = NULL; - return err; } #ifdef CONFIG_MODULES static void free_module_param_attrs(struct module_kobject *mk) { - kfree(mk->mp->grp.attrs); + if (mk->mp) + kfree(mk->mp->grp.attrs); kfree(mk->mp); mk->mp = NULL; } @@ -695,8 +686,10 @@ int module_param_sysfs_setup(struct module *mod, if (kparam[i].perm == 0) continue; err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name); - if (err) + if (err) { + free_module_param_attrs(&mod->mkobj); return err; + } params = true; } -- GitLab From cbd7f8d6825c6900daa9d6f1b363b592ea9ee1fa Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 10 Nov 2014 09:33:29 +1030 Subject: [PATCH 4213/9457] virtio: Fix comment typo 'CONFIG_S_FAILED' Without the VIRTIO_ prefix CONFIG_S_FAILED looks like a Kconfig macro. So use that prefix here too. Signed-off-by: Paul Bolle Acked-by: Cornelia Huck Signed-off-by: Rusty Russell --- include/linux/virtio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 65261a7244fc..abafae783058 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -78,7 +78,7 @@ bool virtqueue_is_broken(struct virtqueue *vq); /** * virtio_device - representation of a device using virtio * @index: unique position on the virtio bus - * @failed: saved value for CONFIG_S_FAILED bit (for restore) + * @failed: saved value for VIRTIO_CONFIG_S_FAILED bit (for restore) * @config_enabled: configuration change reporting enabled * @config_change_pending: configuration change reported while disabled * @config_lock: protects configuration change reporting -- GitLab From 46652a861b46cc62e9d983d5cf6d9532cd6fccab Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 10 Nov 2014 09:34:29 +1030 Subject: [PATCH 4214/9457] virtio_blk: fix race at module removal If a device appears while module is being removed, driver will get a callback after we've given up on the major number. In theory this means this major number can get reused by something else, resulting in a conflict. To fix, cleanup in reverse order of initialization. Signed-off-by: Michael S. Tsirkin Reviewed-by: Ming Lei Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c6a27d54ad62..ce848ac1e9a6 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -871,8 +871,8 @@ static int __init init(void) static void __exit fini(void) { - unregister_blkdev(major, "virtblk"); unregister_virtio_driver(&virtio_blk); + unregister_blkdev(major, "virtblk"); destroy_workqueue(virtblk_wq); } module_init(init); -- GitLab From 1fd9c67203af91977bf3b964ff3744cf74fc6f3f Mon Sep 17 00:00:00 2001 From: Raushaniya Maksudova Date: Mon, 10 Nov 2014 09:35:29 +1030 Subject: [PATCH 4215/9457] virtio_balloon: return the amount of freed memory from leak_balloon() This value would be useful in the next patch to provide the amount of the freed memory for OOM killer. Signed-off-by: Raushaniya Maksudova Signed-off-by: Denis V. Lunev CC: Rusty Russell CC: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/virtio/virtio_balloon.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c9703d4d6f67..ff71fdcf3345 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -168,8 +168,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) } } -static void leak_balloon(struct virtio_balloon *vb, size_t num) +static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) { + unsigned num_freed_pages; struct page *page; struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; @@ -186,6 +187,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; } + num_freed_pages = vb->num_pfns; /* * Note that if * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); @@ -195,6 +197,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) tell_host(vb, vb->deflate_vq); mutex_unlock(&vb->balloon_lock); release_pages_by_pfn(vb->pfns, vb->num_pfns); + return num_freed_pages; } static inline void update_stat(struct virtio_balloon *vb, int idx, -- GitLab From 5a10b7dbf904bfe01bb9fcc6298f7df09eed77d5 Mon Sep 17 00:00:00 2001 From: Raushaniya Maksudova Date: Mon, 10 Nov 2014 09:36:29 +1030 Subject: [PATCH 4216/9457] virtio_balloon: free some memory from balloon on OOM Excessive virtio_balloon inflation can cause invocation of OOM-killer, when Linux is under severe memory pressure. Various mechanisms are responsible for correct virtio_balloon memory management. Nevertheless it is often the case that these control tools does not have enough time to react on fast changing memory load. As a result OS runs out of memory and invokes OOM-killer. The balancing of memory by use of the virtio balloon should not cause the termination of processes while there are pages in the balloon. Now there is no way for virtio balloon driver to free some memory at the last moment before some process will be get killed by OOM-killer. This does not provide a security breach as balloon itself is running inside guest OS and is working in the cooperation with the host. Thus some improvements from guest side should be considered as normal. To solve the problem, introduce a virtio_balloon callback which is expected to be called from the oom notifier call chain in out_of_memory() function. If virtio balloon could release some memory, it will make the system to return and retry the allocation that forced the out of memory killer to run. Allocate virtio feature bit for this: it is not set by default, the the guest will not deflate virtio balloon on OOM without explicit permission from host. Signed-off-by: Raushaniya Maksudova Signed-off-by: Denis V. Lunev Acked-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/virtio/virtio_balloon.c | 52 +++++++++++++++++++++++++++++ include/uapi/linux/virtio_balloon.h | 1 + 2 files changed, 53 insertions(+) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index ff71fdcf3345..50c5f42d7a9f 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -28,6 +28,7 @@ #include #include #include +#include /* * Balloon device works in 4K page units. So each page is pointed to by @@ -36,6 +37,12 @@ */ #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256 +#define OOM_VBALLOON_DEFAULT_PAGES 256 +#define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80 + +static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES; +module_param(oom_pages, int, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(oom_pages, "pages to free on OOM"); struct virtio_balloon { @@ -71,6 +78,9 @@ struct virtio_balloon /* Memory statistics */ int need_stats_update; struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR]; + + /* To register callback in oom notifier call chain */ + struct notifier_block nb; }; static struct virtio_device_id id_table[] = { @@ -290,6 +300,38 @@ static void update_balloon_size(struct virtio_balloon *vb) &actual); } +/* + * virtballoon_oom_notify - release pages when system is under severe + * memory pressure (called from out_of_memory()) + * @self : notifier block struct + * @dummy: not used + * @parm : returned - number of freed pages + * + * The balancing of memory by use of the virtio balloon should not cause + * the termination of processes while there are pages in the balloon. + * If virtio balloon manages to release some memory, it will make the + * system return and retry the allocation that forced the OOM killer + * to run. + */ +static int virtballoon_oom_notify(struct notifier_block *self, + unsigned long dummy, void *parm) +{ + struct virtio_balloon *vb; + unsigned long *freed; + unsigned num_freed_pages; + + vb = container_of(self, struct virtio_balloon, nb); + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) + return NOTIFY_OK; + + freed = parm; + num_freed_pages = leak_balloon(vb, oom_pages); + update_balloon_size(vb); + *freed += num_freed_pages; + + return NOTIFY_OK; +} + static int balloon(void *_vballoon) { struct virtio_balloon *vb = _vballoon; @@ -446,6 +488,12 @@ static int virtballoon_probe(struct virtio_device *vdev) if (err) goto out_free_vb; + vb->nb.notifier_call = virtballoon_oom_notify; + vb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY; + err = register_oom_notifier(&vb->nb); + if (err < 0) + goto out_oom_notify; + vb->thread = kthread_run(balloon, vb, "vballoon"); if (IS_ERR(vb->thread)) { err = PTR_ERR(vb->thread); @@ -455,6 +503,8 @@ static int virtballoon_probe(struct virtio_device *vdev) return 0; out_del_vqs: + unregister_oom_notifier(&vb->nb); +out_oom_notify: vdev->config->del_vqs(vdev); out_free_vb: kfree(vb); @@ -479,6 +529,7 @@ static void virtballoon_remove(struct virtio_device *vdev) { struct virtio_balloon *vb = vdev->priv; + unregister_oom_notifier(&vb->nb); kthread_stop(vb->thread); remove_common(vb); kfree(vb); @@ -518,6 +569,7 @@ static int virtballoon_restore(struct virtio_device *vdev) static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_F_STATS_VQ, + VIRTIO_BALLOON_F_DEFLATE_ON_OOM, }; static struct virtio_driver virtio_balloon_driver = { diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h index 5e26f61b5df5..be40f7059e93 100644 --- a/include/uapi/linux/virtio_balloon.h +++ b/include/uapi/linux/virtio_balloon.h @@ -31,6 +31,7 @@ /* The feature bitmap for virtio balloon */ #define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */ #define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory Stats virtqueue */ +#define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2 /* Deflate balloon on OOM */ /* Size of a PFN in the balloon interface. */ #define VIRTIO_BALLOON_PFN_SHIFT 12 -- GitLab From 2a9e8df00951092e825144a9968285398f8aa162 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 16:46:35 +0100 Subject: [PATCH 4217/9457] ALSA: vx: Fix missing kerneldoc parameter descriptions The file isn't processed, but it's not bad to fix beforehand. Signed-off-by: Takashi Iwai --- sound/drivers/vx/vx_core.c | 10 ++++++++++ sound/pci/vx222/vx222_ops.c | 5 +++++ sound/pcmcia/vx/vxpocket.c | 1 + 3 files changed, 16 insertions(+) diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index e8cc16993903..fc05a37fd017 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -416,6 +416,7 @@ int vx_send_rih(struct vx_core *chip, int cmd) /** * snd_vx_boot_xilinx - boot up the xilinx interface + * @chip: VX core instance * @boot: the boot record to load */ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot) @@ -538,6 +539,8 @@ EXPORT_SYMBOL(snd_vx_threaded_irq_handler); /** * snd_vx_irq_handler - interrupt handler + * @irq: irq number + * @dev: VX core instance */ irqreturn_t snd_vx_irq_handler(int irq, void *dev) { @@ -649,6 +652,8 @@ static void vx_proc_init(struct vx_core *chip) /** * snd_vx_dsp_boot - load the DSP boot + * @chip: VX core instance + * @boot: firmware data */ int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot) { @@ -669,6 +674,8 @@ EXPORT_SYMBOL(snd_vx_dsp_boot); /** * snd_vx_dsp_load - load the DSP image + * @chip: VX core instance + * @dsp: firmware data */ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) { @@ -768,7 +775,10 @@ EXPORT_SYMBOL(snd_vx_resume); /** * snd_vx_create - constructor for struct vx_core + * @card: card instance * @hw: hardware specific record + * @ops: VX ops pointer + * @extra_size: extra byte size to allocate appending to chip * * this function allocates the instance and prepare for the hardware * initialization. diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 2d1570273e99..52c1a8d5b88a 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -92,6 +92,7 @@ static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg) /** * snd_vx_inb - read a byte from the register + * @chip: VX core instance * @offset: register enum */ static unsigned char vx2_inb(struct vx_core *chip, int offset) @@ -101,6 +102,7 @@ static unsigned char vx2_inb(struct vx_core *chip, int offset) /** * snd_vx_outb - write a byte on the register + * @chip: VX core instance * @offset: the register offset * @val: the value to write */ @@ -114,6 +116,7 @@ static void vx2_outb(struct vx_core *chip, int offset, unsigned char val) /** * snd_vx_inl - read a 32bit word from the register + * @chip: VX core instance * @offset: register enum */ static unsigned int vx2_inl(struct vx_core *chip, int offset) @@ -123,6 +126,7 @@ static unsigned int vx2_inl(struct vx_core *chip, int offset) /** * snd_vx_outl - write a 32bit word on the register + * @chip: VX core instance * @offset: the register enum * @val: the value to write */ @@ -223,6 +227,7 @@ static int vx2_test_xilinx(struct vx_core *_chip) /** * vx_setup_pseudo_dma - set up the pseudo dma read/write mode. + * @chip: VX core instance * @do_write: 0 = read, 1 = set up for DMA write */ static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write) diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 92ec11456e3a..b16f42deed67 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -174,6 +174,7 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, /** * snd_vxpocket_assign_resources - initialize the hardware and card instance. + * @chip: VX core instance * @port: i/o port for the card * @irq: irq number for the card * -- GitLab From e60b2c7fcdef03256cde864d678df240877a5e80 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 16:47:26 +0100 Subject: [PATCH 4218/9457] ALSA: hda - Fix kerneldoc errors in patch_ca0132.c Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_ca0132.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 4f7ffa8c4a0d..e0383eea9880 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2417,7 +2417,7 @@ static int dspxfr_one_seg(struct hda_codec *codec, * @reloc: Relocation address for loading single-segment overlays, or 0 for * no relocation * @sample_rate: sampling rate of the stream used for DSP download - * @number_channels: channels of the stream used for DSP download + * @channels: channels of the stream used for DSP download * @ovly: TRUE if overlay format is required * * Returns zero or a negative error code. @@ -2556,10 +2556,7 @@ static void dspload_post_setup(struct hda_codec *codec) } /** - * Download DSP from a DSP Image Fast Load structure. This structure is a - * linear, non-constant sized element array of structures, each of which - * contain the count of the data to be loaded, the data itself, and the - * corresponding starting chip address of the starting data location. + * dspload_image - Download DSP from a DSP Image Fast Load structure. * * @codec: the HDA codec * @fls: pointer to a fast load image @@ -2570,6 +2567,10 @@ static void dspload_post_setup(struct hda_codec *codec) * @router_chans: number of audio router channels to be allocated (0 means use * internal defaults; max is 32) * + * Download DSP from a DSP Image Fast Load structure. This structure is a + * linear, non-constant sized element array of structures, each of which + * contain the count of the data to be loaded, the data itself, and the + * corresponding starting chip address of the starting data location. * Returns zero or a negative error code. */ static int dspload_image(struct hda_codec *codec, -- GitLab From 3f60c87d129acbb232afbc7269c726d009a01869 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 17:09:22 +0100 Subject: [PATCH 4219/9457] ALSA: mixart: Fix kerneldoc comments Signed-off-by: Takashi Iwai --- sound/pci/mixart/mixart_hwdep.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 581e1e74863c..9996a4dead0f 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -37,10 +37,11 @@ /** * wait for a value on a peudo register, exit with a timeout * - * @param mgr pointer to miXart manager structure - * @param offset unsigned pseudo_register base + offset of value - * @param value value - * @param timeout timeout in centisenconds + * @mgr: pointer to miXart manager structure + * @offset: unsigned pseudo_register base + offset of value + * @is_egal: wait for the equal value + * @value: value + * @timeout: timeout in centisenconds */ static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr, u32 offset, int is_egal, -- GitLab From ddcecf6b6ae7b91c8735e52f50cd403ee9cbe298 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Nov 2014 17:24:26 +0100 Subject: [PATCH 4220/9457] ALSA: Fix invalid kerneldoc markers They are no real kerneldoc comments, so drop such markers. Signed-off-by: Takashi Iwai --- include/uapi/sound/hdspm.h | 12 ++++----- sound/pci/emu10k1/emu10k1x.c | 2 +- sound/pci/lx6464es/lx_defs.h | 2 +- sound/pci/rme9652/hdspm.c | 48 ++++++++++++++++++------------------ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/include/uapi/sound/hdspm.h b/include/uapi/sound/hdspm.h index d956c3593f65..b357f1a5e29c 100644 --- a/include/uapi/sound/hdspm.h +++ b/include/uapi/sound/hdspm.h @@ -74,14 +74,14 @@ struct hdspm_config { #define SNDRV_HDSPM_IOCTL_GET_CONFIG \ _IOR('H', 0x41, struct hdspm_config) -/** +/* * If there's a TCO (TimeCode Option) board installed, * there are further options and status data available. * The hdspm_ltc structure contains the current SMPTE * timecode and some status information and can be * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the * hdspm_status struct. - **/ + */ enum hdspm_ltc_format { format_invalid, @@ -113,11 +113,11 @@ struct hdspm_ltc { #define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc) -/** +/* * The status data reflects the device's current state * as determined by the card's configuration and * connection status. - **/ + */ enum hdspm_sync { hdspm_sync_no_lock = 0, @@ -171,9 +171,9 @@ struct hdspm_status { #define SNDRV_HDSPM_IOCTL_GET_STATUS \ _IOR('H', 0x47, struct hdspm_status) -/** +/* * Get information about the card and its add-ons. - **/ + */ #define HDSPM_ADDON_TCO 1 diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index e223de1408c0..15933f92f63a 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -180,7 +180,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); /* From 0x50 - 0x5f, last samples captured */ -/** +/* * The hardware has 3 channels for playback and 1 for capture. * - channel 0 is the front channel * - channel 1 is the rear channel diff --git a/sound/pci/lx6464es/lx_defs.h b/sound/pci/lx6464es/lx_defs.h index 49d36bdd512c..469bcc685edf 100644 --- a/sound/pci/lx6464es/lx_defs.h +++ b/sound/pci/lx6464es/lx_defs.h @@ -175,7 +175,7 @@ enum buffer_flags { BF_ZERO = 0x00, /* no flags (init).*/ }; -/** +/* * Stream Flags definitions */ enum stream_flags { diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index e09348c156d8..3342705a5715 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2201,10 +2201,10 @@ static inline int hdspm_get_pll_freq(struct hdspm *hdspm) return rate; } -/** +/* * Calculate the real sample rate from the * current DDS value. - **/ + */ static int hdspm_get_system_sample_rate(struct hdspm *hdspm) { unsigned int rate; @@ -2270,9 +2270,9 @@ static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol, } -/** +/* * Returns the WordClock sample rate class for the given card. - **/ + */ static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) { int status; @@ -2295,9 +2295,9 @@ static int hdspm_get_wc_sample_rate(struct hdspm *hdspm) } -/** +/* * Returns the TCO sample rate class for the given card. - **/ + */ static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) { int status; @@ -2321,9 +2321,9 @@ static int hdspm_get_tco_sample_rate(struct hdspm *hdspm) } -/** +/* * Returns the SYNC_IN sample rate class for the given card. - **/ + */ static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) { int status; @@ -2343,9 +2343,9 @@ static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm) return 0; } -/** +/* * Returns the AES sample rate class for the given card. - **/ + */ static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) { int timecode; @@ -2361,10 +2361,10 @@ static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) return 0; } -/** +/* * Returns the sample rate class for input source for * 'new style' cards like the AIO and RayDAT. - **/ + */ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) { int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2); @@ -2512,10 +2512,10 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, } -/** +/* * Returns the system clock mode for the given card. * @returns 0 - master, 1 - slave - **/ + */ static int hdspm_system_clock_mode(struct hdspm *hdspm) { switch (hdspm->io_type) { @@ -2534,10 +2534,10 @@ static int hdspm_system_clock_mode(struct hdspm *hdspm) } -/** +/* * Sets the system clock mode. * @param mode 0 - master, 1 - slave - **/ + */ static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) { hdspm_set_toggle_setting(hdspm, @@ -2692,11 +2692,11 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, } -/** +/* * Returns the current preferred sync reference setting. * The semantics of the return value are depending on the * card, please see the comments for clarification. - **/ + */ static int hdspm_pref_sync_ref(struct hdspm * hdspm) { switch (hdspm->io_type) { @@ -2795,11 +2795,11 @@ static int hdspm_pref_sync_ref(struct hdspm * hdspm) } -/** +/* * Set the preferred sync reference to . The semantics * of are depending on the card type, see the comments * for clarification. - **/ + */ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) { int p = 0; @@ -4101,9 +4101,9 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, -/** +/* * TCO controls - **/ + */ static void hdspm_tco_write(struct hdspm *hdspm) { unsigned int tc[4] = { 0, 0, 0, 0}; @@ -5403,7 +5403,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) HDSPM_midi2IRQPending | HDSPM_midi3IRQPending); /* now = get_cycles(); */ - /** + /* * LAT_2..LAT_0 period counter (win) counter (mac) * 6 4096 ~256053425 ~514672358 * 5 2048 ~128024983 ~257373821 @@ -5412,7 +5412,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) * 2 256 ~16003039 ~32260176 * 1 128 ~7998738 ~16194507 * 0 64 ~3998231 ~8191558 - **/ + */ /* dev_info(hdspm->card->dev, "snd_hdspm_interrupt %llu @ %llx\n", now-hdspm->last_interrupt, status & 0xFFC0); -- GitLab From 60cb49d2c92969f7b0e7da863fc0cbe3ec0c715c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 11 Nov 2014 11:33:24 +0200 Subject: [PATCH 4221/9457] Bluetooth: Fix mgmt connected notification This patch fixes a regression that was introduced by commit cb77c3ec075a50e9f956f62dc2e4c0394df1d578. In addition to BT_CONFIG, BT_CONNECTED is also a state in which we may get a remote name and need to indicate over mgmt the connection status. This scenario is particularly likely to happen for incoming connections that do not need authentication since there the hci_conn state will reach BT_CONNECTED before the remote name is received. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 68c882fd20fd..aec3b1dce1cc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1581,7 +1581,13 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, struct discovery_state *discov = &hdev->discovery; struct inquiry_entry *e; - if (conn && conn->state == BT_CONFIG && + /* Update the mgmt connected state if necessary. Be careful with + * conn objects that exist but are not (yet) connected however. + * Only those in BT_CONFIG or BT_CONNECTED states can be + * considered connected. + */ + if (conn && + (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, conn, 0, name, name_len); -- GitLab From 2fbbc96d16009276153fd33823616877dcca30d8 Mon Sep 17 00:00:00 2001 From: Gabriel FERNANDEZ Date: Tue, 4 Nov 2014 11:51:18 +0100 Subject: [PATCH 4222/9457] phy: Add PHY header file for DT x Driver defines This provides the shared header file which will be reference from both PHY driver and its associated Device Tree node(s). Signed-off-by: Gabriel Fernandez --- include/dt-bindings/phy/phy.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/dt-bindings/phy/phy.h diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h new file mode 100644 index 000000000000..e8c6a3f04b85 --- /dev/null +++ b/include/dt-bindings/phy/phy.h @@ -0,0 +1,18 @@ +/* + * + * This header provides constants for the phy framework + * + * Copyright (C) 2014 STMicroelectronics + * Author: Gabriel Fernandez + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef _DT_BINDINGS_PHY +#define _DT_BINDINGS_PHY + +#define PHY_TYPE_SATA 1 +#define PHY_TYPE_PCIE 2 +#define PHY_TYPE_USB2 3 +#define PHY_TYPE_USB3 4 + +#endif /* _DT_BINDINGS_PHY */ -- GitLab From fe4860af002a4516dd878f7297b61e186c475b35 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Sun, 3 Feb 2013 19:30:38 -0300 Subject: [PATCH 4223/9457] [media] [PATH,1/2] mxl5007 move reset to attach This patch move the soft reset to the attach function because with dual tuners, when one tuner do reset, the other one is perturbed, and the stream has errors. Signed-off-by: Jose Alberto Reguero Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/mxl5007t.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c index 69e453ef0a1a..eb61304c260d 100644 --- a/drivers/media/tuners/mxl5007t.c +++ b/drivers/media/tuners/mxl5007t.c @@ -531,10 +531,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state, struct reg_pair_t *init_regs; int ret; - ret = mxl5007t_soft_reset(state); - if (mxl_fail(ret)) - goto fail; - /* calculate initialization reg array */ init_regs = mxl5007t_calc_init_regs(state, mode); @@ -900,7 +896,20 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, /* existing tuner instance */ break; } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_soft_reset(state); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (mxl_fail(ret)) + goto fail; + fe->tuner_priv = state; + mutex_unlock(&mxl5007t_list_mutex); memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops, -- GitLab From 02f9cf96df57575acea2e6eb4041e9f3ecd32548 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Sun, 3 Feb 2013 19:40:24 -0300 Subject: [PATCH 4224/9457] [media] [PATH,2/2] mxl5007 move loop_thru to attach This patch move the loop_thru configuration to the attach function, because with dual tuners until loop_tru configuration the other tuner don't work. Signed-off-by: Jose Alberto Reguero Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/mxl5007t.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c index eb61304c260d..1810ad66888e 100644 --- a/drivers/media/tuners/mxl5007t.c +++ b/drivers/media/tuners/mxl5007t.c @@ -374,7 +374,6 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); - set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable); set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3); set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp); @@ -902,6 +901,18 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, ret = mxl5007t_soft_reset(state); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (mxl_fail(ret)) + goto fail; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_write_reg(state, 0x04, + state->config->loop_thru_enable); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- GitLab From be3b16341d5cd8cf2a64fcc7a604a8efe6599ff0 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Mon, 3 Nov 2014 18:26:12 -0800 Subject: [PATCH 4225/9457] HID: add support for MS Surface Pro 3 Type Cover Surface Pro 3 Type Cover that works with Ubuntu (and possibly Arch) from this thread. Both trackpad and keyboard work after compiling my own kernel. http://ubuntuforums.org/showthread.php?t=2231207&page=2&s=44910e0c56047e4f93dfd9fea58121ef Also includes Jarrad Whitaker's message which sources http://winaero.com/blog/how-to-install-linux-on-surface-pro-3/ which he says is sourced from a Russian site Signed-off-by: Alan Wu Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 6 ++++++ drivers/hid/hid-ids.h | 1 + drivers/hid/hid-microsoft.c | 2 ++ drivers/hid/usbhid/hid-quirks.c | 1 + 4 files changed, 10 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 73bd9e2e42bc..e94afcc19eda 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -702,6 +702,11 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && type == HID_COLLECTION_PHYSICAL) hid->group = HID_GROUP_SENSOR_HUB; + + if (hid->vendor == USB_VENDOR_ID_MICROSOFT && + hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 && + hid->group == HID_GROUP_MULTITOUCH) + hid->group = HID_GROUP_GENERIC; } static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) @@ -1861,6 +1866,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cd9c9e96cf0e..0d38df761e29 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -646,6 +646,7 @@ #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 +#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07dc #define USB_VENDOR_ID_MOJO 0x8282 #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 8ba17a946f2a..cacda43f6a6f 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -274,6 +274,8 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), .driver_data = MS_DUPLICATE_USAGES }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), + .driver_data = MS_HIDINPUT }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), .driver_data = MS_PRESENTER }, diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index f3cb5b0a4345..be6763524fe8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -75,6 +75,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, -- GitLab From 7041bc997db6a29af74499938987160bbe6654ef Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Wed, 22 Oct 2014 18:42:01 -0300 Subject: [PATCH 4226/9457] [media] media: davinci: vpbe: add support for VIDIOC_CREATE_BUFS this patch adds support for vidioc_create_bufs. Along side remove unneeded member numbuffers. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 10 +++++++--- include/media/davinci/vpbe_display.h | 2 -- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 3b607498bb48..78b9ffebc94e 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -244,12 +244,15 @@ vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n"); + if (fmt && fmt->fmt.pix.sizeimage < layer->pix_fmt.sizeimage) + return -EINVAL; + /* Store number of buffers allocated in numbuffer member */ - if (*nbuffers < VPBE_DEFAULT_NUM_BUFS) - *nbuffers = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS; + if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS) + *nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers; *nplanes = 1; - sizes[0] = layer->pix_fmt.sizeimage; + sizes[0] = fmt ? fmt->fmt.pix.sizeimage : layer->pix_fmt.sizeimage; alloc_ctxs[0] = layer->alloc_ctx; return 0; @@ -1241,6 +1244,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { .vidioc_try_fmt_vid_out = vpbe_display_try_fmt, .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, .vidioc_querybuf = vb2_ioctl_querybuf, .vidioc_qbuf = vb2_ioctl_qbuf, .vidioc_dqbuf = vb2_ioctl_dqbuf, diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h index 163a02b92c04..fa0247ad815f 100644 --- a/include/media/davinci/vpbe_display.h +++ b/include/media/davinci/vpbe_display.h @@ -70,8 +70,6 @@ struct vpbe_disp_buffer { /* vpbe display object structure */ struct vpbe_layer { - /* number of buffers in fbuffers */ - unsigned int numbuffers; /* Pointer to the vpbe_display */ struct vpbe_display *disp_dev; /* Pointer pointing to current v4l2_buffer */ -- GitLab From 85273c382e185236241f21e0d468f86ca76c1546 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 27 Oct 2014 02:25:01 -0300 Subject: [PATCH 4227/9457] [media] cx25840/cx18: Use standard ordering of mask and shift Precedence of & and >> is not the same and is not left to right. shift has higher precedence and should be done after the mask. This use has a mask then shift which is not the normal style. Move the shift before the mask to match nearly all the other uses in kernel. Signed-off-by: Joe Perches Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/cx25840/cx25840-core.c | 12 ++++++------ drivers/media/pci/cx18/cx18-av-core.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index e453a3ffe7d1..0327032cd1a7 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -879,7 +879,7 @@ void cx25840_std_setup(struct i2c_client *client) /* Sets horizontal blanking delay and active lines */ cx25840_write(client, 0x470, hblank); cx25840_write(client, 0x471, - 0xff & (((hblank >> 8) & 0x3) | (hactive << 4))); + (((hblank >> 8) & 0x3) | (hactive << 4)) & 0xff); cx25840_write(client, 0x472, hactive >> 4); /* Sets burst gate delay */ @@ -888,13 +888,13 @@ void cx25840_std_setup(struct i2c_client *client) /* Sets vertical blanking delay and active duration */ cx25840_write(client, 0x474, vblank); cx25840_write(client, 0x475, - 0xff & (((vblank >> 8) & 0x3) | (vactive << 4))); + (((vblank >> 8) & 0x3) | (vactive << 4)) & 0xff); cx25840_write(client, 0x476, vactive >> 4); cx25840_write(client, 0x477, vblank656); /* Sets src decimation rate */ - cx25840_write(client, 0x478, 0xff & src_decimation); - cx25840_write(client, 0x479, 0xff & (src_decimation >> 8)); + cx25840_write(client, 0x478, src_decimation & 0xff); + cx25840_write(client, 0x479, (src_decimation >> 8) & 0xff); /* Sets Luma and UV Low pass filters */ cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); @@ -904,8 +904,8 @@ void cx25840_std_setup(struct i2c_client *client) /* Sets SC Step*/ cx25840_write(client, 0x47c, sc); - cx25840_write(client, 0x47d, 0xff & sc >> 8); - cx25840_write(client, 0x47e, 0xff & sc >> 16); + cx25840_write(client, 0x47d, (sc >> 8) & 0xff); + cx25840_write(client, 0x47e, (sc >> 16) & 0xff); /* Sets VBI parameters */ if (std & V4L2_STD_625_50) { diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index 2d3afe0431a9..45be26cdb653 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -490,8 +490,8 @@ void cx18_av_std_setup(struct cx18 *cx) /* Sets horizontal blanking delay and active lines */ cx18_av_write(cx, 0x470, hblank); - cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) | - (hactive << 4))); + cx18_av_write(cx, 0x471, + (((hblank >> 8) & 0x3) | (hactive << 4)) & 0xff); cx18_av_write(cx, 0x472, hactive >> 4); /* Sets burst gate delay */ @@ -499,14 +499,14 @@ void cx18_av_std_setup(struct cx18 *cx) /* Sets vertical blanking delay and active duration */ cx18_av_write(cx, 0x474, vblank); - cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) | - (vactive << 4))); + cx18_av_write(cx, 0x475, + (((vblank >> 8) & 0x3) | (vactive << 4)) & 0xff); cx18_av_write(cx, 0x476, vactive >> 4); cx18_av_write(cx, 0x477, vblank656); /* Sets src decimation rate */ - cx18_av_write(cx, 0x478, 0xff & src_decimation); - cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8)); + cx18_av_write(cx, 0x478, src_decimation & 0xff); + cx18_av_write(cx, 0x479, (src_decimation >> 8) & 0xff); /* Sets Luma and UV Low pass filters */ cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); @@ -516,8 +516,8 @@ void cx18_av_std_setup(struct cx18 *cx) /* Sets SC Step*/ cx18_av_write(cx, 0x47c, sc); - cx18_av_write(cx, 0x47d, 0xff & sc >> 8); - cx18_av_write(cx, 0x47e, 0xff & sc >> 16); + cx18_av_write(cx, 0x47d, (sc >> 8) & 0xff); + cx18_av_write(cx, 0x47e, (sc >> 16) & 0xff); if (std & V4L2_STD_625_50) { state->slicer_line_delay = 1; -- GitLab From 9ccd180964baba5ae150ed91fb9649310f013a5b Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Thu, 6 Nov 2014 18:06:18 -0300 Subject: [PATCH 4228/9457] [media] solo6x10: clean up properly in stop_streaming This fixes warning from drivers/media/v4l2-core/videobuf2-core.c, WARN_ON(atomic_read(&q->owned_by_drv_count)). Signed-off-by: Andrey Utkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 28023f9f1dc7..6cd6a25b25d7 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -781,9 +781,19 @@ static int solo_enc_start_streaming(struct vb2_queue *q, unsigned int count) static void solo_enc_stop_streaming(struct vb2_queue *q) { struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); + unsigned long flags; + spin_lock_irqsave(&solo_enc->av_lock, flags); solo_enc_off(solo_enc); - INIT_LIST_HEAD(&solo_enc->vidq_active); + while (!list_empty(&solo_enc->vidq_active)) { + struct solo_vb2_buf *buf = list_entry( + solo_enc->vidq_active.next, + struct solo_vb2_buf, list); + + list_del(&buf->list); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irqrestore(&solo_enc->av_lock, flags); solo_ring_stop(solo_enc->solo_dev); } -- GitLab From 0cb2df380b8845f94f1b3c492ad3cc79f5112630 Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Wed, 29 Oct 2014 13:03:52 -0300 Subject: [PATCH 4229/9457] [media] solo6x10: free DMA allocation when releasing encoder Fixes this warning: [ 956.730136] ------------[ cut here ]------------ [ 956.730143] WARNING: CPU: 1 PID: 10134 at lib/dma-debug.c:963 dma_debug_device_change+0x191/0x1f0() [ 956.730146] pci 0000:07:05.0: DMA-API: device driver has pending DMA allocations while released from device [count=8] One of leaked entries details: [device address=0x00000000d3d57000] [size=512 bytes] [mapped with DMA_BIDIRECTIONAL] [mapped as coherent] [ 956.730147] Modules linked in: solo6x10(-) videobuf2_dma_contig videobuf2_dma_sg videobuf2_memops videobuf2_core ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat videobuf_vmalloc videobuf_core v4l2_common videodev rt2800usb rt2800lib rt2x00usb rt2x00lib mac80211 cfg80211 crc_ccitt usbkbd hid_a4tech hid_generic usbhid snd_hda_codec_hdmi snd_hda_codec_via snd_hda_codec_generic snd_hda_intel snd_hda_controller snd_hda_codec snd_hwdep snd_pcm x86_pkg_temp_thermal snd_timer snd soundcore [ 956.730172] CPU: 1 PID: 10134 Comm: rmmod Not tainted 3.18.0-rc1-next-20141023-zver-dirty #24 [ 956.730173] Hardware name: System manufacturer System Product Name/P8H77-V, BIOS 0501 02/28/2012 [ 956.730175] 0000000000000009 ffff8801df9e3c58 ffffffff817ffe6b 0000000000000001 [ 956.730177] ffff8801df9e3ca8 ffff8801df9e3c98 ffffffff81091ec7 0000000000000046 [ 956.730180] ffff880215457e90 0000000000000008 ffffffff81cbb10f ffff880215570098 [ 956.730183] Call Trace: [ 956.730188] [] dump_stack+0x4f/0x7c [ 956.730192] [] warn_slowpath_common+0x87/0xb0 [ 956.730194] [] warn_slowpath_fmt+0x41/0x50 [ 956.730197] [] ? dma_debug_device_change+0xb8/0x1f0 [ 956.730199] [] dma_debug_device_change+0x191/0x1f0 [ 956.730203] [] notifier_call_chain+0x4d/0x70 [ 956.730205] [] __blocking_notifier_call_chain+0x59/0x80 [ 956.730207] [] blocking_notifier_call_chain+0x11/0x20 [ 956.730211] [] __device_release_driver+0xcf/0xf0 [ 956.730213] [] driver_detach+0xc8/0xd0 [ 956.730215] [] bus_remove_driver+0x57/0xd0 [ 956.730218] [] driver_unregister+0x29/0x60 [ 956.730221] [] pci_unregister_driver+0x21/0x90 [ 956.730225] [] solo_pci_driver_exit+0x10/0x12 [solo6x10] [ 956.730228] [] SyS_delete_module+0x170/0x1f0 [ 956.730232] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 956.730234] [] system_call_fastpath+0x12/0x17 [ 956.730235] ---[ end trace e730af02713a6c53 ]--- [ 956.730237] Mapped at: [ 956.730238] [] debug_dma_alloc_coherent+0x3c/0xb0 [ 956.730240] [] solo_enc_v4l2_init+0x706/0xba0 [solo6x10] [ 956.730243] [] solo_pci_probe+0x503/0x700 [solo6x10] [ 956.730245] [] local_pci_probe+0x49/0xa0 [ 956.730248] [] pci_device_probe+0xd1/0x120 Signed-off-by: Andrey Utkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 6cd6a25b25d7..9afeb69c1d50 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -1385,6 +1385,9 @@ static void solo_enc_free(struct solo_enc_dev *solo_enc) if (solo_enc == NULL) return; + pci_free_consistent(solo_enc->solo_dev->pdev, + sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts, + solo_enc->desc_items, solo_enc->desc_dma); video_unregister_device(solo_enc->vfd); v4l2_ctrl_handler_free(&solo_enc->hdl); kfree(solo_enc); -- GitLab From 670390c2dc80de8695aafbe8c854da344738361d Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Wed, 29 Oct 2014 13:03:53 -0300 Subject: [PATCH 4230/9457] [media] solo6x10: bind start & stop of encoded frames processing thread to device (de)init Before, it was called from individual encoder (de)init procedures, which lead to spare threads running (which were actually lost, leaked). The current fix uses trivial approach, and the downside is that the processing thread is working always, even when there's no consumer. Signed-off-by: Andrey Utkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 9afeb69c1d50..b9b61b9a6919 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -770,12 +770,8 @@ static void solo_ring_stop(struct solo_dev *solo_dev) static int solo_enc_start_streaming(struct vb2_queue *q, unsigned int count) { struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); - int ret; - ret = solo_enc_on(solo_enc); - if (ret) - return ret; - return solo_ring_start(solo_enc->solo_dev); + return solo_enc_on(solo_enc); } static void solo_enc_stop_streaming(struct vb2_queue *q) @@ -794,7 +790,6 @@ static void solo_enc_stop_streaming(struct vb2_queue *q) vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } spin_unlock_irqrestore(&solo_enc->av_lock, flags); - solo_ring_stop(solo_enc->solo_dev); } static struct vb2_ops solo_enc_video_qops = { @@ -1432,13 +1427,15 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr) solo_dev->v4l2_enc[0]->vfd->num, solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num); - return 0; + return solo_ring_start(solo_dev); } void solo_enc_v4l2_exit(struct solo_dev *solo_dev) { int i; + solo_ring_stop(solo_dev); + for (i = 0; i < solo_dev->nr_chans; i++) solo_enc_free(solo_dev->v4l2_enc[i]); -- GitLab From 5556eb14b4cbf5dce840194ab591027322cbdb1f Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Sun, 9 Nov 2014 07:54:29 +0000 Subject: [PATCH 4231/9457] HID: lenovo: Move USB KEY_FILE to 0x00f9 to prevent scancode clash The bluetooth keyboard also generates 0x00fa when the middle button is pressed. Move the made-up report out of the way so we don't trigger KEY_FILE when middle button is pressed Signed-off-by: Jamie Lentin Signed-off-by: Jiri Kosina --- drivers/hid/hid-lenovo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index bf227f7679af..4716f1e59eca 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -85,13 +85,13 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ map_key_clear(KEY_SCALE); return 1; - case 0x00fa: /* Fn-Esc: Fn-lock toggle */ - map_key_clear(KEY_FN_ESC); - return 1; - case 0x00fb: /* Fn-F12: Open My computer (6 boxes) USB-only */ + case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ /* NB: This mapping is invented in raw_event below */ map_key_clear(KEY_FILE); return 1; + case 0x00fa: /* Fn-Esc: Fn-lock toggle */ + map_key_clear(KEY_FN_ESC); + return 1; } } @@ -207,8 +207,8 @@ static int lenovo_raw_event(struct hid_device *hdev, && data[0] == 0x15 && data[1] == 0x94 && data[2] == 0x01)) { - data[1] = 0x0; - data[2] = 0x4; + data[1] = 0x00; + data[2] = 0x01; } return 0; -- GitLab From c87d92b30208826a656d3cd63e6c96c56cf516a4 Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Sun, 9 Nov 2014 07:54:30 +0000 Subject: [PATCH 4232/9457] HID: lenovo: Don't set EV_REP to avoid repeating mice buttons On the USB keyboard, the VENDOR hotkeys share the same device as the mouse. Setting EV_REP also affects mouse buttons, so leave it off. The bluetooth keyboard still has autorepeating mouse buttons, as it only has one device and is set by the KEYBOARD pages. Signed-off-by: Jamie Lentin Signed-off-by: Jiri Kosina --- drivers/hid/hid-lenovo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 4716f1e59eca..4c55f4d95798 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -62,7 +62,6 @@ static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { - set_bit(EV_REP, hi->input->evbit); switch (usage->hid & HID_USAGE) { case 0x00f1: /* Fn-F4: Mic mute */ map_key_clear(KEY_MICMUTE); -- GitLab From 6db47fa1f1a214bc1ea5a59a32f58188f6b255e9 Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Wed, 29 Oct 2014 13:03:54 -0300 Subject: [PATCH 4233/9457] [media] solo6x10: don't turn off/on encoder interrupt in processing loop It makes no sense to block the SOLO_IRQ_ENCODER interrupt from being sent while processing an earlier interrupt. New interrupts will just kick the thread again once it is done processing. Signed-off-by: Andrey Utkin [hans.verkuil@cisco.com: fix commit description] Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index b9b61b9a6919..30e09d935ce1 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -703,9 +703,7 @@ static int solo_ring_thread(void *data) if (timeout == -ERESTARTSYS || kthread_should_stop()) break; - solo_irq_off(solo_dev, SOLO_IRQ_ENCODER); solo_handle_ring(solo_dev); - solo_irq_on(solo_dev, SOLO_IRQ_ENCODER); try_to_freeze(); } -- GitLab From 9694fbec951b9aa56815d423f2c53d17a4a9635c Mon Sep 17 00:00:00 2001 From: sensoray-dev Date: Tue, 4 Nov 2014 17:34:03 -0300 Subject: [PATCH 4234/9457] [media] s2255drv: fix spinlock issue qlock spinlock controls access to buf_list and sequence. qlock spinlock should not be locked during a copy to video buffers, an operation that may sleep. Signed-off-by: Dean Anderson Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index ccc00099b261..a56a05b0c4e1 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -558,27 +558,30 @@ static void s2255_fwchunk_complete(struct urb *urb) } -static int s2255_got_frame(struct s2255_vc *vc, int jpgsize) +static void s2255_got_frame(struct s2255_vc *vc, int jpgsize) { struct s2255_buffer *buf; struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev); unsigned long flags = 0; - int rc = 0; + spin_lock_irqsave(&vc->qlock, flags); if (list_empty(&vc->buf_list)) { dprintk(dev, 1, "No active queue to serve\n"); - rc = -1; - goto unlock; + spin_unlock_irqrestore(&vc->qlock, flags); + return; } buf = list_entry(vc->buf_list.next, struct s2255_buffer, list); list_del(&buf->list); v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + buf->vb.v4l2_buf.field = vc->field; + buf->vb.v4l2_buf.sequence = vc->frame_count; + spin_unlock_irqrestore(&vc->qlock, flags); + s2255_fillbuff(vc, buf, jpgsize); + /* tell v4l buffer was filled */ + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf); -unlock: - spin_unlock_irqrestore(&vc->qlock, flags); - return rc; } static const struct s2255_fmt *format_by_fourcc(int fourcc) @@ -649,11 +652,6 @@ static void s2255_fillbuff(struct s2255_vc *vc, } dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", (unsigned long)vbuf, pos); - /* tell v4l buffer was filled */ - buf->vb.v4l2_buf.field = vc->field; - buf->vb.v4l2_buf.sequence = vc->frame_count; - v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); - vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); } -- GitLab From 24c4942d29c8b7ae344d094495019b5587275490 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 6 Nov 2014 09:06:46 -0300 Subject: [PATCH 4235/9457] [media] vivid: add test array controls Add array controls to test support for such controls. There is one array with just one element, one 8x16 matrix control and one 4 dimensional 2x3x4x5 control. This makes it possible to experiment with such controls without requiring hard-to-get hardware. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-ctrls.c | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index d5cbf0038f24..d5847736792b 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -40,6 +40,9 @@ #define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5) #define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6) #define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7) +#define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8) +#define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9) +#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10) #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000) #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1) @@ -163,6 +166,42 @@ static const struct v4l2_ctrl_config vivid_ctrl_int64 = { .step = 1, }; +static const struct v4l2_ctrl_config vivid_ctrl_u32_array = { + .ops = &vivid_user_gen_ctrl_ops, + .id = VIVID_CID_U32_ARRAY, + .name = "U32 1 Element Array", + .type = V4L2_CTRL_TYPE_U32, + .def = 0x18, + .min = 0x10, + .max = 0x20000, + .step = 1, + .dims = { 1 }, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = { + .ops = &vivid_user_gen_ctrl_ops, + .id = VIVID_CID_U16_MATRIX, + .name = "U16 8x16 Matrix", + .type = V4L2_CTRL_TYPE_U16, + .def = 0x18, + .min = 0x10, + .max = 0x2000, + .step = 1, + .dims = { 8, 16 }, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = { + .ops = &vivid_user_gen_ctrl_ops, + .id = VIVID_CID_U8_4D_ARRAY, + .name = "U8 2x3x4x5 Array", + .type = V4L2_CTRL_TYPE_U8, + .def = 0x18, + .min = 0x10, + .max = 0x20, + .step = 1, + .dims = { 2, 3, 4, 5 }, +}; + static const char * const vivid_ctrl_menu_strings[] = { "Menu Item 0 (Skipped)", "Menu Item 1", @@ -1222,6 +1261,9 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL); dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL); dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL); + v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL); + v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL); + v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL); if (dev->has_vid_cap) { /* Image Processing Controls */ -- GitLab From 47efeb52f78fd37df91d13e15296f8070d549f81 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Thu, 6 Nov 2014 10:04:27 -0300 Subject: [PATCH 4236/9457] [media] media: davinci: vpbe: missing clk_put we are getting struct clk using clk_get before calling clk_prepare_enable. but if clk_prepare_enable fails, then we are jumping to fail_mutex_unlock where we are just unlocking the mutex, but we are not freeing the clock source. this patch just adds a call to clk_put before jumping to fail_mutex_unlock. Signed-off-by: Sudip Mukherjee Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 49d2de0eea2d..e5df9916b2a1 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -625,6 +625,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) } if (clk_prepare_enable(vpbe_dev->dac_clk)) { ret = -ENODEV; + clk_put(vpbe_dev->dac_clk); goto fail_mutex_unlock; } } -- GitLab From c909e5ba6b1d79edfa809150da36a2c0c9cb095e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Nov 2014 09:34:55 -0300 Subject: [PATCH 4237/9457] [media] adv7842: fix G/S_EDID behavior Make this pass the v4l2-compliance test. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 48b628bc6714..bed0586f72eb 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -2028,16 +2028,7 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) struct adv7842_state *state = to_state(sd); u8 *data = NULL; - if (edid->pad > ADV7842_EDID_PORT_VGA) - return -EINVAL; - if (edid->blocks == 0) - return -EINVAL; - if (edid->blocks > 2) - return -EINVAL; - if (edid->start_block > 1) - return -EINVAL; - if (edid->start_block == 1) - edid->blocks = 1; + memset(edid->reserved, 0, sizeof(edid->reserved)); switch (edid->pad) { case ADV7842_EDID_PORT_A: @@ -2052,12 +2043,23 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) default: return -EINVAL; } + + if (edid->start_block == 0 && edid->blocks == 0) { + edid->blocks = data ? 2 : 0; + return 0; + } + if (!data) return -ENODATA; - memcpy(edid->edid, - data + edid->start_block * 128, - edid->blocks * 128); + if (edid->start_block >= 2) + return -EINVAL; + + if (edid->start_block + edid->blocks > 2) + edid->blocks = 2 - edid->start_block; + + memcpy(edid->edid, data + edid->start_block * 128, edid->blocks * 128); + return 0; } @@ -2066,12 +2068,16 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) struct adv7842_state *state = to_state(sd); int err = 0; + memset(e->reserved, 0, sizeof(e->reserved)); + if (e->pad > ADV7842_EDID_PORT_VGA) return -EINVAL; if (e->start_block != 0) return -EINVAL; - if (e->blocks > 2) + if (e->blocks > 2) { + e->blocks = 2; return -E2BIG; + } /* todo, per edid */ state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], -- GitLab From c81285ae4780e5df83f191f545c156435fdb01ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Nov 2014 09:34:56 -0300 Subject: [PATCH 4238/9457] [media] adv7511: fix G/S_EDID behavior This fixes the v4l2-compliance failures. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7511.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index f98acf4aafd4..8acc8c5d67d7 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -779,21 +779,28 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) { struct adv7511_state *state = get_adv7511_state(sd); + memset(edid->reserved, 0, sizeof(edid->reserved)); + if (edid->pad != 0) return -EINVAL; - if ((edid->blocks == 0) || (edid->blocks > 256)) - return -EINVAL; - if (!state->edid.segments) { - v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); - return -ENODATA; + + if (edid->start_block == 0 && edid->blocks == 0) { + edid->blocks = state->edid.segments * 2; + return 0; } + + if (state->edid.segments == 0) + return -ENODATA; + if (edid->start_block >= state->edid.segments * 2) - return -E2BIG; - if ((edid->blocks + edid->start_block) >= state->edid.segments * 2) + return -EINVAL; + + if (edid->start_block + edid->blocks > state->edid.segments * 2) edid->blocks = state->edid.segments * 2 - edid->start_block; memcpy(edid->edid, &state->edid.data[edid->start_block * 128], 128 * edid->blocks); + return 0; } -- GitLab From dd9ac11aefd8f9286d3bc8988ca5a052312c3de6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Nov 2014 09:34:57 -0300 Subject: [PATCH 4239/9457] [media] adv7604: Correct G/S_EDID behaviour In order to have v4l2-compliance tool pass the G/S_EDID some modifications where needed in the driver. In particular, the edid.reserved zone must be blanked. Based on a patch from Jean-Michel Hautbois , but reworked it a bit. It should use 'data' (which depends on edid.present) instead of edid.blocks as the check whether edid data is present. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 47795ff71688..22e550acd233 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -1997,19 +1997,7 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) struct adv7604_state *state = to_state(sd); u8 *data = NULL; - if (edid->pad > ADV7604_PAD_HDMI_PORT_D) - return -EINVAL; - if (edid->blocks == 0) - return -EINVAL; - if (edid->blocks > 2) - return -EINVAL; - if (edid->start_block > 1) - return -EINVAL; - if (edid->start_block == 1) - edid->blocks = 1; - - if (edid->blocks > state->edid.blocks) - edid->blocks = state->edid.blocks; + memset(edid->reserved, 0, sizeof(edid->reserved)); switch (edid->pad) { case ADV7604_PAD_HDMI_PORT_A: @@ -2021,14 +2009,24 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) break; default: return -EINVAL; - break; } - if (!data) + + if (edid->start_block == 0 && edid->blocks == 0) { + edid->blocks = data ? state->edid.blocks : 0; + return 0; + } + + if (data == NULL) return -ENODATA; - memcpy(edid->edid, - data + edid->start_block * 128, - edid->blocks * 128); + if (edid->start_block >= state->edid.blocks) + return -EINVAL; + + if (edid->start_block + edid->blocks > state->edid.blocks) + edid->blocks = state->edid.blocks - edid->start_block; + + memcpy(edid->edid, data + edid->start_block * 128, edid->blocks * 128); + return 0; } @@ -2068,6 +2066,8 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) int err; int i; + memset(edid->reserved, 0, sizeof(edid->reserved)); + if (edid->pad > ADV7604_PAD_HDMI_PORT_D) return -EINVAL; if (edid->start_block != 0) @@ -2164,7 +2164,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) return -EIO; } - /* enable hotplug after 100 ms */ queue_delayed_work(state->work_queues, &state->delayed_work_enable_hotplug, HZ / 10); -- GitLab From 065e1477d277174242e73e7334c717b840d0693f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Nov 2014 11:39:46 -0300 Subject: [PATCH 4240/9457] [media] saa7164: fix sparse warnings Fix many sparse warnings: drivers/media/pci/saa7164/saa7164-core.c:97:18: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:122:31: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:122:31: warning: incorrect type in initializer (different address spaces) drivers/media/pci/saa7164/saa7164-core.c:122:31: expected unsigned char [noderef] [usertype] *bufcpu drivers/media/pci/saa7164/saa7164-core.c:122:31: got unsigned char [usertype] * drivers/media/pci/saa7164/saa7164-core.c:282:44: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:286:38: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:286:35: warning: incorrect type in assignment (different address spaces) drivers/media/pci/saa7164/saa7164-core.c:286:35: expected unsigned char [noderef] [usertype] *p drivers/media/pci/saa7164/saa7164-core.c:286:35: got unsigned char [usertype] * drivers/media/pci/saa7164/saa7164-core.c:352:44: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:527:53: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-core.c:129:30: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:133:38: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:133:72: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:134:35: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:287:61: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:288:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:289:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:290:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:291:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:292:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:293:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-core.c:294:65: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-fw.c:548:52: warning: incorrect type in argument 5 (different address spaces) drivers/media/pci/saa7164/saa7164-fw.c:548:52: expected unsigned char [usertype] *dst drivers/media/pci/saa7164/saa7164-fw.c:548:52: got unsigned char [noderef] [usertype] * drivers/media/pci/saa7164/saa7164-fw.c:579:44: warning: incorrect type in argument 5 (different address spaces) drivers/media/pci/saa7164/saa7164-fw.c:579:44: expected unsigned char [usertype] *dst drivers/media/pci/saa7164/saa7164-fw.c:579:44: got unsigned char [noderef] [usertype] * drivers/media/pci/saa7164/saa7164-fw.c:597:44: warning: incorrect type in argument 5 (different address spaces) drivers/media/pci/saa7164/saa7164-fw.c:597:44: expected unsigned char [usertype] *dst drivers/media/pci/saa7164/saa7164-fw.c:597:44: got unsigned char [noderef] [usertype] * drivers/media/pci/saa7164/saa7164-bus.c:36:36: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-bus.c:41:36: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-bus.c:151:19: warning: incorrect type in assignment (different base types) drivers/media/pci/saa7164/saa7164-bus.c:151:19: expected unsigned short [unsigned] [usertype] size drivers/media/pci/saa7164/saa7164-bus.c:151:19: got restricted __le16 [usertype] drivers/media/pci/saa7164/saa7164-bus.c:152:22: warning: incorrect type in assignment (different base types) drivers/media/pci/saa7164/saa7164-bus.c:152:22: expected unsigned int [unsigned] [usertype] command drivers/media/pci/saa7164/saa7164-bus.c:152:22: got restricted __le32 [usertype] drivers/media/pci/saa7164/saa7164-bus.c:153:30: warning: incorrect type in assignment (different base types) drivers/media/pci/saa7164/saa7164-bus.c:153:30: expected unsigned short [unsigned] [usertype] controlselector drivers/media/pci/saa7164/saa7164-bus.c:153:30: got restricted __le16 [usertype] drivers/media/pci/saa7164/saa7164-bus.c:172:20: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:173:20: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:206:28: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:287:9: warning: incorrect type in argument 1 (different base types) drivers/media/pci/saa7164/saa7164-bus.c:287:9: expected unsigned int [unsigned] val drivers/media/pci/saa7164/saa7164-bus.c:287:9: got restricted __le32 [usertype] drivers/media/pci/saa7164/saa7164-bus.c:339:20: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:340:20: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:463:9: warning: incorrect type in argument 1 (different base types) drivers/media/pci/saa7164/saa7164-bus.c:463:9: expected unsigned int [unsigned] val drivers/media/pci/saa7164/saa7164-bus.c:463:9: got restricted __le32 [usertype] drivers/media/pci/saa7164/saa7164-bus.c:466:21: warning: cast to restricted __le16 drivers/media/pci/saa7164/saa7164-bus.c:467:24: warning: cast to restricted __le32 drivers/media/pci/saa7164/saa7164-bus.c:468:32: warning: cast to restricted __le16 drivers/media/pci/saa7164/saa7164-buffer.c:122:18: warning: incorrect type in assignment (different address spaces) drivers/media/pci/saa7164/saa7164-buffer.c:122:18: expected unsigned long long [noderef] [usertype] *cpu drivers/media/pci/saa7164/saa7164-buffer.c:122:18: got void * drivers/media/pci/saa7164/saa7164-buffer.c:127:21: warning: incorrect type in assignment (different address spaces) drivers/media/pci/saa7164/saa7164-buffer.c:127:21: expected unsigned long long [noderef] [usertype] *pt_cpu drivers/media/pci/saa7164/saa7164-buffer.c:127:21: got void * drivers/media/pci/saa7164/saa7164-buffer.c:134:20: warning: cast removes address space of expression drivers/media/pci/saa7164/saa7164-buffer.c:156:63: warning: incorrect type in argument 3 (different address spaces) drivers/media/pci/saa7164/saa7164-buffer.c:156:63: expected void *vaddr drivers/media/pci/saa7164/saa7164-buffer.c:156:63: got unsigned long long [noderef] [usertype] *cpu drivers/media/pci/saa7164/saa7164-buffer.c:179:57: warning: incorrect type in argument 3 (different address spaces) drivers/media/pci/saa7164/saa7164-buffer.c:179:57: expected void *vaddr drivers/media/pci/saa7164/saa7164-buffer.c:179:57: got unsigned long long [noderef] [usertype] *cpu drivers/media/pci/saa7164/saa7164-buffer.c:180:56: warning: incorrect type in argument 3 (different address spaces) drivers/media/pci/saa7164/saa7164-buffer.c:180:56: expected void *vaddr drivers/media/pci/saa7164/saa7164-buffer.c:180:56: got unsigned long long [noderef] [usertype] *pt_cpu drivers/media/pci/saa7164/saa7164-buffer.c:84:17: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-buffer.c:147:31: warning: dereference of noderef expression drivers/media/pci/saa7164/saa7164-buffer.c:148:17: warning: dereference of noderef expression Most are caused by pointers marked as __iomem when they aren't or not marked as __iomem when they should. Also note that readl/writel already do endian conversion, so there is no need to do it again. saa7164_bus_set/get were a bit tricky: you have to make sure the msg endian conversion is done at the right time, and that the code isn't using fields that are still little endian instead of cpu-endianness. The approach chosen is to convert just before writing to the ring buffer and to convert it back right after reading from the ring buffer. Signed-off-by: Hans Verkuil Cc: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-buffer.c | 4 +- drivers/media/pci/saa7164/saa7164-bus.c | 101 ++++++++++++--------- drivers/media/pci/saa7164/saa7164-core.c | 13 ++- drivers/media/pci/saa7164/saa7164-fw.c | 6 +- drivers/media/pci/saa7164/saa7164-types.h | 4 +- drivers/media/pci/saa7164/saa7164.h | 4 +- 6 files changed, 74 insertions(+), 58 deletions(-) diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c index 66696fa8341d..9bd1f73f82da 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -130,9 +130,9 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port, goto fail2; /* init the buffers to a known pattern, easier during debugging */ - memset_io(buf->cpu, 0xff, buf->pci_size); + memset(buf->cpu, 0xff, buf->pci_size); buf->crc = crc32(0, buf->cpu, buf->actual_size); - memset_io(buf->pt_cpu, 0xff, buf->pt_size); + memset(buf->pt_cpu, 0xff, buf->pt_size); dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n", __func__, buf, params->numpagetables); diff --git a/drivers/media/pci/saa7164/saa7164-bus.c b/drivers/media/pci/saa7164/saa7164-bus.c index 5f6f3094c44e..6c73f5b155f6 100644 --- a/drivers/media/pci/saa7164/saa7164-bus.c +++ b/drivers/media/pci/saa7164/saa7164-bus.c @@ -33,12 +33,12 @@ int saa7164_bus_setup(struct saa7164_dev *dev) b->Type = TYPE_BUS_PCIe; b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE; - b->m_pdwSetRing = (u8 *)(dev->bmmio + + b->m_pdwSetRing = (u8 __iomem *)(dev->bmmio + ((u32)dev->busdesc.CommandRing)); b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE; - b->m_pdwGetRing = (u8 *)(dev->bmmio + + b->m_pdwGetRing = (u8 __iomem *)(dev->bmmio + ((u32)dev->busdesc.ResponseRing)); b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE; @@ -138,6 +138,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp; u32 new_swp, space_rem; int ret = SAA_ERR_BAD_PARAMETER; + u16 size; if (!msg) { printk(KERN_ERR "%s() !msg\n", __func__); @@ -148,10 +149,6 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, saa7164_bus_verify(dev); - msg->size = cpu_to_le16(msg->size); - msg->command = cpu_to_le32(msg->command); - msg->controlselector = cpu_to_le16(msg->controlselector); - if (msg->size > dev->bus.m_wMaxReqSize) { printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n", __func__); @@ -169,8 +166,8 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, bytes_to_write = sizeof(*msg) + msg->size; free_write_space = 0; timeout = SAA_BUS_TIMEOUT; - curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); - curr_swp = le32_to_cpu(saa7164_readl(bus->m_dwSetWritePos)); + curr_srp = saa7164_readl(bus->m_dwSetReadPos); + curr_swp = saa7164_readl(bus->m_dwSetWritePos); /* Deal with ring wrapping issues */ if (curr_srp > curr_swp) @@ -203,7 +200,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, mdelay(1); /* Check the space usage again */ - curr_srp = le32_to_cpu(saa7164_readl(bus->m_dwSetReadPos)); + curr_srp = saa7164_readl(bus->m_dwSetReadPos); /* Deal with ring wrapping issues */ if (curr_srp > curr_swp) @@ -223,6 +220,16 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__, bus->m_dwSizeSetRing); + /* + * Make a copy of msg->size before it is converted to le16 since it is + * used in the code below. + */ + size = msg->size; + /* Convert to le16/le32 */ + msg->size = (__force u16)cpu_to_le16(msg->size); + msg->command = (__force u32)cpu_to_le32(msg->command); + msg->controlselector = (__force u16)cpu_to_le16(msg->controlselector); + /* Mental Note: line 462 tmmhComResBusPCIe.cpp */ /* Check if we're going to wrap again */ @@ -243,28 +250,28 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, dprintk(DBGLVL_BUS, "%s() tr4\n", __func__); /* Split the msg into pieces as the ring wraps */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem); - memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem, + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, space_rem); + memcpy_toio(bus->m_pdwSetRing, (u8 *)msg + space_rem, sizeof(*msg) - space_rem); - memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem, - buf, msg->size); + memcpy_toio(bus->m_pdwSetRing + sizeof(*msg) - space_rem, + buf, size); } else if (space_rem == sizeof(*msg)) { dprintk(DBGLVL_BUS, "%s() tr5\n", __func__); /* Additional data at the beginning of the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing, buf, msg->size); + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + memcpy_toio(bus->m_pdwSetRing, buf, size); } else { /* Additional data wraps around the ring */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - if (msg->size > 0) { - memcpy(bus->m_pdwSetRing + curr_swp + + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + if (size > 0) { + memcpy_toio(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, space_rem - sizeof(*msg)); - memcpy(bus->m_pdwSetRing, (u8 *)buf + + memcpy_toio(bus->m_pdwSetRing, (u8 *)buf + space_rem - sizeof(*msg), bytes_to_write - space_rem); } @@ -276,15 +283,20 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, dprintk(DBGLVL_BUS, "%s() tr6\n", __func__); /* The ring buffer doesn't wrap, two simple copies */ - memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); - memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, - msg->size); + memcpy_toio(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg)); + memcpy_toio(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf, + size); } dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp); /* Update the bus write position */ - saa7164_writel(bus->m_dwSetWritePos, cpu_to_le32(new_swp)); + saa7164_writel(bus->m_dwSetWritePos, new_swp); + + /* Convert back to cpu after writing the msg to the ringbuffer. */ + msg->size = le16_to_cpu((__force __le16)msg->size); + msg->command = le32_to_cpu((__force __le32)msg->command); + msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector); ret = SAA_OK; out: @@ -336,8 +348,8 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, /* Peek the bus to see if a msg exists, if it's not what we're expecting * then return cleanly else read the message from the bus. */ - curr_gwp = le32_to_cpu(saa7164_readl(bus->m_dwGetWritePos)); - curr_grp = le32_to_cpu(saa7164_readl(bus->m_dwGetReadPos)); + curr_gwp = saa7164_readl(bus->m_dwGetWritePos); + curr_grp = saa7164_readl(bus->m_dwGetReadPos); if (curr_gwp == curr_grp) { ret = SAA_ERR_EMPTY; @@ -369,14 +381,18 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, new_grp -= bus->m_dwSizeGetRing; space_rem = bus->m_dwSizeGetRing - curr_grp; - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, + memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem); + memcpy_fromio((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing, bytes_to_read - space_rem); } else { /* No wrapping */ - memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); + memcpy_fromio(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read); } + /* Convert from little endian to CPU */ + msg_tmp.size = le16_to_cpu((__force __le16)msg_tmp.size); + msg_tmp.command = le32_to_cpu((__force __le32)msg_tmp.command); + msg_tmp.controlselector = le16_to_cpu((__force __le16)msg_tmp.controlselector); /* No need to update the read positions, because this was a peek */ /* If the caller specifically want to peek, return */ @@ -427,24 +443,24 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, if (space_rem < sizeof(*msg)) { /* msg wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem); - memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing, + memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, space_rem); + memcpy_fromio((u8 *)msg + space_rem, bus->m_pdwGetRing, sizeof(*msg) - space_rem); if (buf) - memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) - + memcpy_fromio(buf, bus->m_pdwGetRing + sizeof(*msg) - space_rem, buf_size); } else if (space_rem == sizeof(*msg)) { - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) - memcpy(buf, bus->m_pdwGetRing, buf_size); + memcpy_fromio(buf, bus->m_pdwGetRing, buf_size); } else { /* Additional data wraps around the ring */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) { - memcpy(buf, bus->m_pdwGetRing + curr_grp + + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), space_rem - sizeof(*msg)); - memcpy(buf + space_rem - sizeof(*msg), + memcpy_fromio(buf + space_rem - sizeof(*msg), bus->m_pdwGetRing, bytes_to_read - space_rem); } @@ -453,19 +469,20 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, } else { /* No wrapping */ - memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); + memcpy_fromio(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg)); if (buf) - memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), + memcpy_fromio(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg), buf_size); } + /* Convert from little endian to CPU */ + msg->size = le16_to_cpu((__force __le16)msg->size); + msg->command = le32_to_cpu((__force __le32)msg->command); + msg->controlselector = le16_to_cpu((__force __le16)msg->controlselector); /* Update the read positions, adjusting the ring */ - saa7164_writel(bus->m_dwGetReadPos, cpu_to_le32(new_grp)); + saa7164_writel(bus->m_dwGetReadPos, new_grp); peekout: - msg->size = le16_to_cpu(msg->size); - msg->command = le32_to_cpu(msg->command); - msg->controlselector = le16_to_cpu(msg->controlselector); ret = SAA_OK; out: mutex_unlock(&bus->lock); diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index cc1be8a7a451..4b0bec3766ed 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -119,7 +119,7 @@ static void saa7164_ts_verifier(struct saa7164_buffer *buf) u32 i; u8 cc, a; u16 pid; - u8 __iomem *bufcpu = (u8 *)buf->cpu; + u8 *bufcpu = (u8 *)buf->cpu; port->sync_errors = 0; port->v_cc_errors = 0; @@ -260,7 +260,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) struct saa7164_user_buffer *ubuf = NULL; struct list_head *c, *n; int i = 0; - u8 __iomem *p; + u8 *p; mutex_lock(&port->dmaqueue_lock); list_for_each_safe(c, n, &port->dmaqueue.list) { @@ -318,8 +318,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) if (buf->actual_size <= ubuf->actual_size) { - memcpy_fromio(ubuf->data, buf->cpu, - ubuf->actual_size); + memcpy(ubuf->data, buf->cpu, ubuf->actual_size); if (crc_checking) { /* Throw a new checksum on the read buffer */ @@ -346,7 +345,7 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) * with known bad data. We check for this data at a later point * in time. */ saa7164_buffer_zero_offsets(port, bufnr); - memset_io(buf->cpu, 0xff, buf->pci_size); + memset(buf->cpu, 0xff, buf->pci_size); if (crc_checking) { /* Throw yet aanother new checksum on the dma buffer */ buf->crc = crc32(0, buf->cpu, buf->actual_size); @@ -1096,7 +1095,7 @@ static int saa7164_proc_show(struct seq_file *m, void *v) if (c == 0) seq_printf(m, " %04x:", i); - seq_printf(m, " %02x", *(b->m_pdwSetRing + i)); + seq_printf(m, " %02x", readb(b->m_pdwSetRing + i)); if (++c == 16) { seq_printf(m, "\n"); @@ -1111,7 +1110,7 @@ static int saa7164_proc_show(struct seq_file *m, void *v) if (c == 0) seq_printf(m, " %04x:", i); - seq_printf(m, " %02x", *(b->m_pdwGetRing + i)); + seq_printf(m, " %02x", readb(b->m_pdwGetRing + i)); if (++c == 16) { seq_printf(m, "\n"); diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c index 86763203d61d..add06ab5124d 100644 --- a/drivers/media/pci/saa7164/saa7164-fw.c +++ b/drivers/media/pci/saa7164/saa7164-fw.c @@ -72,7 +72,7 @@ static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg) /* TODO: move dlflags into dev-> and change to write/readl/b */ /* TODO: Excessive levels of debug */ static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, - u32 dlflags, u8 *dst, u32 dstsize) + u32 dlflags, u8 __iomem *dst, u32 dstsize) { u32 reg, timeout, offset; u8 *srcbuf = NULL; @@ -136,7 +136,7 @@ static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, srcsize -= dstsize, offset += dstsize) { dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize); - memcpy(dst, srcbuf + offset, dstsize); + memcpy_toio(dst, srcbuf + offset, dstsize); /* Flag the data as ready */ saa7164_writel(drflag, 1); @@ -154,7 +154,7 @@ static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize, dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize); /* Write last block to the device */ - memcpy(dst, srcbuf+offset, srcsize); + memcpy_toio(dst, srcbuf+offset, srcsize); /* Flag the data as ready */ saa7164_writel(drflag, 1); diff --git a/drivers/media/pci/saa7164/saa7164-types.h b/drivers/media/pci/saa7164/saa7164-types.h index 1d2140a3eb38..f48ba978f835 100644 --- a/drivers/media/pci/saa7164/saa7164-types.h +++ b/drivers/media/pci/saa7164/saa7164-types.h @@ -78,9 +78,9 @@ enum tmBusType { struct tmComResBusInfo { enum tmBusType Type; u16 m_wMaxReqSize; - u8 *m_pdwSetRing; + u8 __iomem *m_pdwSetRing; u32 m_dwSizeSetRing; - u8 *m_pdwGetRing; + u8 __iomem *m_pdwGetRing; u32 m_dwSizeGetRing; u32 m_dwSetWritePos; u32 m_dwSetReadPos; diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h index 8b29e8990301..cd1a07ce27cb 100644 --- a/drivers/media/pci/saa7164/saa7164.h +++ b/drivers/media/pci/saa7164/saa7164.h @@ -313,13 +313,13 @@ struct saa7164_buffer { /* A block of page align PCI memory */ u32 pci_size; /* PCI allocation size in bytes */ - u64 __iomem *cpu; /* Virtual address */ + u64 *cpu; /* Virtual address */ dma_addr_t dma; /* Physical address */ u32 crc; /* Checksum for the entire buffer data */ /* A page table that splits the block into a number of entries */ u32 pt_size; /* PCI allocation size in bytes */ - u64 __iomem *pt_cpu; /* Virtual address */ + u64 *pt_cpu; /* Virtual address */ dma_addr_t pt_dma; /* Physical address */ /* Encoder fops */ -- GitLab From cba5480c1e01542a1eaf74b27b56e7d0a37c5b7b Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Wed, 5 Nov 2014 11:58:07 -0300 Subject: [PATCH 4241/9457] [media] cx23885: add DVBSky S950 support DVBSky S950 dvb-s/s2 PCIe card: 1>dvb frontend: M88TS2022(tuner),M88DS3103(demod) 2>PCIe bridge: cx23885 3>rc: cx23885 integrated. Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 20 ++++++++++++++++++++ drivers/media/pci/cx23885/cx23885-dvb.c | 9 ++++++--- drivers/media/pci/cx23885/cx23885-input.c | 3 +++ drivers/media/pci/cx23885/cx23885.h | 1 + 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 9c7e8ac31cce..4b9cb0795e7e 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -692,6 +692,10 @@ struct cx23885_board cx23885_boards[] = { .name = "Technotrend TT-budget CT2-4500 CI", .portb = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVBSKY_S950] = { + .name = "DVBSky S950", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -963,6 +967,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x13c2, .subdevice = 0x3013, .card = CX23885_BOARD_TT_CT2_4500_CI, + }, { + .subvendor = 0x4254, + .subdevice = 0x0950, + .card = CX23885_BOARD_DVBSKY_S950, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1597,6 +1605,13 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) /* enable irq */ cx_write(GPIO_ISM, 0x00000000); /* INTERRUPTS active low */ + break; + case CX23885_BOARD_DVBSKY_S950: + cx23885_gpio_enable(dev, GPIO_2, 1); + cx23885_gpio_clear(dev, GPIO_2); + msleep(100); + cx23885_gpio_set(dev, GPIO_2); + break; } } @@ -1681,6 +1696,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1731,6 +1747,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1782,6 +1799,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; @@ -1888,6 +1906,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -2009,6 +2028,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 9da5cf3cea8c..3410ab86bcf7 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1672,6 +1672,7 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_S950: i2c_bus = &dev->i2c_bus[0]; i2c_bus2 = &dev->i2c_bus[1]; switch (port->nr) { @@ -1922,7 +1923,8 @@ static int dvb_register(struct cx23885_tsport *port) memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); break; } - case CX23885_BOARD_DVBSKY_T9580: { + case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_S950: { u8 eeprom[256]; /* 24C02 i2c eeprom */ if (port->nr > 2) @@ -1932,8 +1934,9 @@ static int dvb_register(struct cx23885_tsport *port) dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "DVBSky T9580 port %d MAC address: %pM\n", - port->nr, eeprom + 0xc0 + (port->nr-1) * 8); + printk(KERN_INFO "%s port %d MAC address: %pM\n", + cx23885_boards[dev->board].name, port->nr, + eeprom + 0xc0 + (port->nr-1) * 8); memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 + (port->nr-1) * 8, 6); break; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 12d8a3de7df4..7523d0a8ae1d 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -91,6 +91,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -147,6 +148,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: + case CX23885_BOARD_DVBSKY_S950: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -316,6 +318,7 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: + case CX23885_BOARD_DVBSKY_S950: /* Integrated CX23885 IR controller */ driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 7eee2ea18ede..f9cd0da72d02 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -96,6 +96,7 @@ #define CX23885_BOARD_DVBSKY_T980C 46 #define CX23885_BOARD_DVBSKY_S950C 47 #define CX23885_BOARD_TT_CT2_4500_CI 48 +#define CX23885_BOARD_DVBSKY_S950 49 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From c29d6a83b3c14cf81a4c90a941eb923625192398 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Wed, 5 Nov 2014 11:58:38 -0300 Subject: [PATCH 4242/9457] [media] cx23885: add DVBSky S952 support DVBSky S952 dvb-s/s2 dual PCIe card: 1>dvb frontend: M88TS2022(tuner),M88DS3103(demod) 2>PCIe bridge: CX23885(port b: parallel mode, port c: serial mode) 3>rc: cx23885 integrated. Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 22 +++++ drivers/media/pci/cx23885/cx23885-dvb.c | 99 ++++++++++++++++++++++- drivers/media/pci/cx23885/cx23885-input.c | 3 + drivers/media/pci/cx23885/cx23885.h | 1 + 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 4b9cb0795e7e..4bad27d1caa2 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -696,6 +696,11 @@ struct cx23885_board cx23885_boards[] = { .name = "DVBSky S950", .portb = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVBSKY_S952] = { + .name = "DVBSky S952", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -971,6 +976,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x4254, .subdevice = 0x0950, .card = CX23885_BOARD_DVBSKY_S950, + }, { + .subvendor = 0x4254, + .subdevice = 0x0952, + .card = CX23885_BOARD_DVBSKY_S952, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1566,6 +1575,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(60); break; case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_S952: /* enable GPIO3-18 pins */ cx_write(MC417_CTL, 0x00000037); cx23885_gpio_enable(dev, GPIO_2 | GPIO_11, 1); @@ -1697,6 +1707,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1748,6 +1759,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1800,6 +1812,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; @@ -1962,6 +1975,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_DVBSKY_S952: + ts1->gen_ctrl_val = 0x5; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + ts2->gen_ctrl_val = 0xe; /* Serial bus */ + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: @@ -2029,6 +2050,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 3410ab86bcf7..2457b6483a40 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -617,6 +617,32 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe, return 0; } +static int dvbsky_s952_portc_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct cx23885_tsport *port = fe->dvb->priv; + struct cx23885_dev *dev = port->dev; + + cx23885_gpio_enable(dev, GPIO_12 | GPIO_13, 1); + + switch (voltage) { + case SEC_VOLTAGE_13: + cx23885_gpio_set(dev, GPIO_13); + cx23885_gpio_clear(dev, GPIO_12); + break; + case SEC_VOLTAGE_18: + cx23885_gpio_set(dev, GPIO_13); + cx23885_gpio_set(dev, GPIO_12); + break; + case SEC_VOLTAGE_OFF: + cx23885_gpio_clear(dev, GPIO_13); + cx23885_gpio_clear(dev, GPIO_12); + break; + } + /* call the frontend set_voltage function */ + return port->fe_set_voltage(fe, voltage); +} + static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr, u8 data, int *mem) { @@ -878,6 +904,19 @@ static const struct m88ds3103_config dvbsky_s950c_m88ds3103_config = { .agc = 0x99, }; +static const struct m88ds3103_config dvbsky_s952_portc_m88ds3103_config = { + .i2c_addr = 0x68, + .clock = 27000000, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_SERIAL, + .ts_clk = 96000, + .ts_clk_pol = 0, + .lnb_en_pol = 1, + .lnb_hv_pol = 0, + .agc = 0x99, +}; + static int netup_altera_fpga_rw(void *device, int flag, int data, int read) { struct cx23885_dev *dev = (struct cx23885_dev *)device; @@ -1034,6 +1073,8 @@ static int dvb_register(struct cx23885_tsport *port) struct i2c_board_info info; struct i2c_adapter *adapter; struct i2c_client *client_demod = NULL, *client_tuner = NULL, *client_ci = NULL; + const struct m88ds3103_config *p_m88ds3103_config = NULL; + int (*p_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage) = NULL; int mfe_shared = 0; /* bus not shared by default */ int ret; @@ -1847,6 +1888,61 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend->ops.read_signal_strength = fe0->dvb.frontend->ops.tuner_ops.get_rf_strength; + port->i2c_client_tuner = client_tuner; + break; + case CX23885_BOARD_DVBSKY_S952: + switch (port->nr) { + /* port b */ + case 1: + i2c_bus = &dev->i2c_bus[1]; + p_m88ds3103_config = &dvbsky_t9580_m88ds3103_config; + p_set_voltage = dvbsky_t9580_set_voltage; + break; + /* port c */ + case 2: + i2c_bus = &dev->i2c_bus[0]; + p_m88ds3103_config = &dvbsky_s952_portc_m88ds3103_config; + p_set_voltage = dvbsky_s952_portc_set_voltage; + break; + } + + /* attach frontend */ + fe0->dvb.frontend = dvb_attach(m88ds3103_attach, + p_m88ds3103_config, + &i2c_bus->i2c_adap, &adapter); + if (fe0->dvb.frontend == NULL) + break; + + /* attach tuner */ + memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); + m88ts2022_config.fe = fe0->dvb.frontend; + m88ts2022_config.clock = 27000000; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &m88ts2022_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) + goto frontend_detach; + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + goto frontend_detach; + } + + /* delegate signal strength measurement to tuner */ + fe0->dvb.frontend->ops.read_signal_strength = + fe0->dvb.frontend->ops.tuner_ops.get_rf_strength; + + /* + * for setting the voltage we need to set GPIOs on + * the card. + */ + port->fe_set_voltage = + fe0->dvb.frontend->ops.set_voltage; + fe0->dvb.frontend->ops.set_voltage = p_set_voltage; + port->i2c_client_tuner = client_tuner; break; default: @@ -1924,7 +2020,8 @@ static int dvb_register(struct cx23885_tsport *port) break; } case CX23885_BOARD_DVBSKY_T9580: - case CX23885_BOARD_DVBSKY_S950: { + case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: { u8 eeprom[256]; /* 24C02 i2c eeprom */ if (port->nr > 2) diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 7523d0a8ae1d..a1f489444355 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -92,6 +92,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -149,6 +150,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -319,6 +321,7 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_T980C: case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_DVBSKY_S952: /* Integrated CX23885 IR controller */ driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f9cd0da72d02..58c5038c816b 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -97,6 +97,7 @@ #define CX23885_BOARD_DVBSKY_S950C 47 #define CX23885_BOARD_TT_CT2_4500_CI 48 #define CX23885_BOARD_DVBSKY_S950 49 +#define CX23885_BOARD_DVBSKY_S952 50 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From b6851419409664bc564ce5148bbec1141944c710 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Wed, 5 Nov 2014 11:59:07 -0300 Subject: [PATCH 4243/9457] [media] m88ds3103: change ts clock config for serial mode 1> When m88ds3103 works in serial ts mode, its serial ts clock is equal to ts master clock and the clock divider is bypassed. 2> The serial ts clock is configed by the bridge driver just like parallel ts clock. Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 55 +++++++++++-------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 621d20fde2ab..0cd445cfeff6 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -245,9 +245,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, len; const struct m88ds3103_reg_val *init; - u8 u8tmp, u8tmp1, u8tmp2; + u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */ u8 buf[3]; - u16 u16tmp, divide_ratio; + u16 u16tmp, divide_ratio = 0; u32 tuner_frequency, target_mclk; s32 s32tmp; @@ -319,32 +319,29 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) /* set M88DS3103 mclk and ts mclk. */ priv->mclk_khz = 96000; - if (c->delivery_system == SYS_DVBS) - target_mclk = 96000; - else { - switch (priv->cfg->ts_mode) { - case M88DS3103_TS_SERIAL: - case M88DS3103_TS_SERIAL_D7: - if (c->symbol_rate < 18000000) - target_mclk = 96000; - else - target_mclk = 144000; - break; - case M88DS3103_TS_PARALLEL: - case M88DS3103_TS_CI: + switch (priv->cfg->ts_mode) { + case M88DS3103_TS_SERIAL: + case M88DS3103_TS_SERIAL_D7: + target_mclk = priv->cfg->ts_clk; + break; + case M88DS3103_TS_PARALLEL: + case M88DS3103_TS_CI: + if (c->delivery_system == SYS_DVBS) + target_mclk = 96000; + else { if (c->symbol_rate < 18000000) target_mclk = 96000; else if (c->symbol_rate < 28000000) target_mclk = 144000; else target_mclk = 192000; - break; - default: - dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", - __func__); - ret = -EINVAL; - goto err; } + break; + default: + dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", + __func__); + ret = -EINVAL; + goto err; } switch (target_mclk) { @@ -434,7 +431,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) goto err; } - u8tmp1 = 0; /* silence compiler warning */ switch (priv->cfg->ts_mode) { case M88DS3103_TS_SERIAL: u8tmp1 = 0x00; @@ -470,16 +466,15 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20); if (ret) goto err; - } - - if (priv->cfg->ts_clk) { - divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk); - u8tmp1 = divide_ratio / 2; - u8tmp2 = DIV_ROUND_UP(divide_ratio, 2); - } else { - divide_ratio = 0; u8tmp1 = 0; u8tmp2 = 0; + break; + default: + if (priv->cfg->ts_clk) { + divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk); + u8tmp1 = divide_ratio / 2; + u8tmp2 = DIV_ROUND_UP(divide_ratio, 2); + } } dev_dbg(&priv->i2c->dev, -- GitLab From 2500bcc9da4f9e18854b1c360b3939bf06d3c7b9 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Mon, 3 Nov 2014 11:05:25 -0800 Subject: [PATCH 4244/9457] pinctrl: pinconf-generic: Declare dt_params/conf_items const Signed-off-by: Soren Brinkmann Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index e28ef957ca2d..f78b416d7984 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -38,7 +38,7 @@ struct pin_config_item { #define PCONFDUMP(a, b, c, d) { .param = a, .display = b, .format = c, \ .has_arg = d } -static struct pin_config_item conf_items[] = { +static const struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false), @@ -159,7 +159,7 @@ struct pinconf_generic_dt_params { u32 default_value; }; -static struct pinconf_generic_dt_params dt_params[] = { +static const struct pinconf_generic_dt_params dt_params[] = { { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 }, { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, @@ -209,7 +209,7 @@ int pinconf_generic_parse_dt_config(struct device_node *np, return -ENOMEM; for (i = 0; i < ARRAY_SIZE(dt_params); i++) { - struct pinconf_generic_dt_params *par = &dt_params[i]; + const struct pinconf_generic_dt_params *par = &dt_params[i]; ret = of_property_read_u32(np, par->property, &val); /* property not found */ -- GitLab From 0cf1863219b474e82af9cb1f6715a0bbfa3fdf1a Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 11 Nov 2014 17:59:50 +0800 Subject: [PATCH 4245/9457] ASoC: rt5670: add rt5672 codec support rt5672 is very similar to rt5670. Therefore we use one codec driver to support both codecs. The difference between rt5670 and rt5672 is there is some difference in their dapm routing table. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 71 ++++++++++++++++++++++++++++++++------- sound/soc/codecs/rt5670.h | 6 ++++ 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index ba9d9b4d4857..066b58317c24 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -1595,29 +1595,40 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { /* PDM */ SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5670_PWR_DIG2, RT5670_PWR_PDM1_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5670_PWR_DIG2, - RT5670_PWR_PDM2_BIT, 0, NULL, 0), SND_SOC_DAPM_MUX("PDM1 L Mux", RT5670_PDM_OUT_CTRL, RT5670_M_PDM1_L_SFT, 1, &rt5670_pdm1_l_mux), SND_SOC_DAPM_MUX("PDM1 R Mux", RT5670_PDM_OUT_CTRL, RT5670_M_PDM1_R_SFT, 1, &rt5670_pdm1_r_mux), - SND_SOC_DAPM_MUX("PDM2 L Mux", RT5670_PDM_OUT_CTRL, - RT5670_M_PDM2_L_SFT, 1, &rt5670_pdm2_l_mux), - SND_SOC_DAPM_MUX("PDM2 R Mux", RT5670_PDM_OUT_CTRL, - RT5670_M_PDM2_R_SFT, 1, &rt5670_pdm2_r_mux), /* Output Lines */ SND_SOC_DAPM_OUTPUT("HPOL"), SND_SOC_DAPM_OUTPUT("HPOR"), SND_SOC_DAPM_OUTPUT("LOUTL"), SND_SOC_DAPM_OUTPUT("LOUTR"), +}; + +static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5670_PWR_DIG2, + RT5670_PWR_PDM2_BIT, 0, NULL, 0), + SND_SOC_DAPM_MUX("PDM2 L Mux", RT5670_PDM_OUT_CTRL, + RT5670_M_PDM2_L_SFT, 1, &rt5670_pdm2_l_mux), + SND_SOC_DAPM_MUX("PDM2 R Mux", RT5670_PDM_OUT_CTRL, + RT5670_M_PDM2_R_SFT, 1, &rt5670_pdm2_r_mux), SND_SOC_DAPM_OUTPUT("PDM1L"), SND_SOC_DAPM_OUTPUT("PDM1R"), SND_SOC_DAPM_OUTPUT("PDM2L"), SND_SOC_DAPM_OUTPUT("PDM2R"), }; +static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { + SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("SPOLP"), + SND_SOC_DAPM_OUTPUT("SPOLN"), + SND_SOC_DAPM_OUTPUT("SPORP"), + SND_SOC_DAPM_OUTPUT("SPORN"), +}; + static const struct snd_soc_dapm_route rt5670_dapm_routes[] = { { "ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc }, { "ADC Stereo2 Filter", NULL, "ADC STO2 ASRC", is_using_asrc }, @@ -1970,12 +1981,6 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = { { "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" }, { "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" }, { "PDM1 R Mux", NULL, "PDM1 Power" }, - { "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" }, - { "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" }, - { "PDM2 L Mux", NULL, "PDM2 Power" }, - { "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" }, - { "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" }, - { "PDM2 R Mux", NULL, "PDM2 Power" }, { "HP Amp", NULL, "HPO MIX" }, { "HP Amp", NULL, "Mic Det Power" }, @@ -1993,13 +1998,30 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = { { "LOUTR", NULL, "LOUT R Playback" }, { "LOUTL", NULL, "Improve HP Amp Drv" }, { "LOUTR", NULL, "Improve HP Amp Drv" }, +}; +static const struct snd_soc_dapm_route rt5670_specific_dapm_routes[] = { + { "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" }, + { "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" }, + { "PDM2 L Mux", NULL, "PDM2 Power" }, + { "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" }, + { "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" }, + { "PDM2 R Mux", NULL, "PDM2 Power" }, { "PDM1L", NULL, "PDM1 L Mux" }, { "PDM1R", NULL, "PDM1 R Mux" }, { "PDM2L", NULL, "PDM2 L Mux" }, { "PDM2R", NULL, "PDM2 R Mux" }, }; +static const struct snd_soc_dapm_route rt5672_specific_dapm_routes[] = { + { "SPO Amp", NULL, "PDM1 L Mux" }, + { "SPO Amp", NULL, "PDM1 R Mux" }, + { "SPOLP", NULL, "SPO Amp" }, + { "SPOLN", NULL, "SPO Amp" }, + { "SPORP", NULL, "SPO Amp" }, + { "SPORN", NULL, "SPO Amp" }, +}; + static int rt5670_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { @@ -2331,6 +2353,29 @@ static int rt5670_probe(struct snd_soc_codec *codec) { struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) { + case RT5670_ID_5670: + case RT5670_ID_5671: + snd_soc_dapm_new_controls(&codec->dapm, + rt5670_specific_dapm_widgets, + ARRAY_SIZE(rt5670_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5670_specific_dapm_routes, + ARRAY_SIZE(rt5670_specific_dapm_routes)); + break; + case RT5670_ID_5672: + snd_soc_dapm_new_controls(&codec->dapm, + rt5672_specific_dapm_widgets, + ARRAY_SIZE(rt5672_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5672_specific_dapm_routes, + ARRAY_SIZE(rt5672_specific_dapm_routes)); + break; + default: + dev_err(codec->dev, + "The driver is for RT5670 RT5671 or RT5672 only\n"); + return -ENODEV; + } rt5670->codec = codec; return 0; @@ -2452,6 +2497,8 @@ static const struct regmap_config rt5670_regmap = { static const struct i2c_device_id rt5670_i2c_id[] = { { "rt5670", 0 }, + { "rt5671", 0 }, + { "rt5672", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index a0b5c855b492..d11b9c207e26 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h @@ -228,6 +228,12 @@ #define RT5670_R_VOL_MASK (0x3f) #define RT5670_R_VOL_SFT 0 +/* SW Reset & Device ID (0x00) */ +#define RT5670_ID_MASK (0x3 << 1) +#define RT5670_ID_5670 (0x0 << 1) +#define RT5670_ID_5672 (0x1 << 1) +#define RT5670_ID_5671 (0x2 << 1) + /* Combo Jack Control 1 (0x0a) */ #define RT5670_CBJ_BST1_MASK (0xf << 12) #define RT5670_CBJ_BST1_SFT (12) -- GitLab From 5563502cb68d9520e13fe2350922ca88c4531c63 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 11 Nov 2014 11:31:28 +0800 Subject: [PATCH 4246/9457] ASoC: rt5645: remove unused rt5645_clk_sel_put Remove rt5645_clk_sel_put function since it is never used. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 59 --------------------------------------- 1 file changed, 59 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 1dbbebc83d41..665f8b64efe9 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -441,65 +441,6 @@ static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, RT5645_TDM_CTRL_1, 8, rt5645_tdm_adc_data_select); -static int rt5645_clk_sel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - unsigned int u_bit = 0, p_bit = 0; - struct soc_enum *em = - (struct soc_enum *)kcontrol->private_value; - - switch (em->reg) { - case RT5645_ASRC_2: - switch (em->shift_l) { - case 0: - u_bit = 0x8; - p_bit = RT5645_PWR_ADC_S1F; - break; - case 4: - u_bit = 0x100; - p_bit = RT5645_PWR_DAC_MF_R; - break; - case 8: - u_bit = 0x200; - p_bit = RT5645_PWR_DAC_MF_L; - break; - case 12: - u_bit = 0x400; - p_bit = RT5645_PWR_DAC_S1F; - break; - } - break; - case RT5645_ASRC_3: - switch (em->shift_l) { - case 0: - u_bit = 0x1; - p_bit = RT5645_PWR_ADC_MF_R; - break; - case 4: - u_bit = 0x2; - p_bit = RT5645_PWR_ADC_MF_L; - break; - } - break; - } - - if (u_bit || p_bit) { - switch (ucontrol->value.integer.value[0]) { - case 1 ... 4: /*enable*/ - if (snd_soc_read(codec, RT5645_PWR_DIG2) & p_bit) - snd_soc_update_bits(codec, - RT5645_ASRC_1, u_bit, u_bit); - break; - default: /*disable*/ - snd_soc_update_bits(codec, RT5645_ASRC_1, u_bit, 0); - break; - } - } - - return snd_soc_put_enum_double(kcontrol, ucontrol); -} - static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, -- GitLab From 4e7902267708e5a389398d9014455b2ed4892912 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 11 Nov 2014 14:16:29 +0200 Subject: [PATCH 4247/9457] Bluetooth: 6lowpan: Remove unnecessary RCU callback When kfree() is all that's needed to free an object protected by RCU there's a kfree_rcu() convenience function that can be used. This patch updates the 6lowpan code to use this, thereby eliminating the need for the separate peer_free() function. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 3f20dce9d671..3d8ceb251d75 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -87,13 +87,6 @@ struct lowpan_dev { struct delayed_work notify_peers; }; -static inline void peer_free(struct rcu_head *head) -{ - struct lowpan_peer *e = container_of(head, struct lowpan_peer, rcu); - - kfree(e); -} - static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) { return netdev_priv(netdev); @@ -108,7 +101,7 @@ static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) { list_del_rcu(&peer->list); - call_rcu(&peer->rcu, peer_free); + kfree_rcu(peer, rcu); module_put(THIS_MODULE); @@ -1219,7 +1212,7 @@ static void disconnect_all_peers(void) l2cap_chan_close(peer->chan, ENOENT); list_del_rcu(&peer->list); - call_rcu(&peer->rcu, peer_free); + kfree_rcu(peer, rcu); module_put(THIS_MODULE); } -- GitLab From a60e654be733a69879148cb4c56d0f58b749e3c4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 11 Nov 2014 10:59:00 +0200 Subject: [PATCH 4248/9457] ASoC: tlv320aic3x: Convert SOC_ENUM_SINGLE/DOUBLE arrays to individual It is easier to find the relevant enums in the code. Use the SOC_ENUM_*_DECL macro for the individual items. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 151 +++++++++++++++++---------------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 8770e28e53a4..990140058aa6 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -216,61 +216,68 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, return 0; } -static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; -static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; -static const char *aic3x_left_hpcom_mux[] = - { "differential of HPLOUT", "constant VCM", "single-ended" }; -static const char *aic3x_right_hpcom_mux[] = - { "differential of HPROUT", "constant VCM", "single-ended", - "differential of HPLCOM", "external feedback" }; -static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" }; -static const char *aic3x_adc_hpf[] = - { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" }; - -#define LDAC_ENUM 0 -#define RDAC_ENUM 1 -#define LHPCOM_ENUM 2 -#define RHPCOM_ENUM 3 -#define LINE1L_2_L_ENUM 4 -#define LINE1L_2_R_ENUM 5 -#define LINE1R_2_L_ENUM 6 -#define LINE1R_2_R_ENUM 7 -#define LINE2L_ENUM 8 -#define LINE2R_ENUM 9 -#define ADC_HPF_ENUM 10 - -static const struct soc_enum aic3x_enum[] = { - SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux), - SOC_ENUM_SINGLE(DAC_LINE_MUX, 4, 3, aic3x_right_dac_mux), - SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux), - SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux), - SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_SINGLE(LINE1L_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_SINGLE(LINE1R_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), - SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), -}; - -static const char *aic3x_agc_level[] = - { "-5.5dB", "-8dB", "-10dB", "-12dB", "-14dB", "-17dB", "-20dB", "-24dB" }; -static const struct soc_enum aic3x_agc_level_enum[] = { - SOC_ENUM_SINGLE(LAGC_CTRL_A, 4, 8, aic3x_agc_level), - SOC_ENUM_SINGLE(RAGC_CTRL_A, 4, 8, aic3x_agc_level), -}; - -static const char *aic3x_agc_attack[] = { "8ms", "11ms", "16ms", "20ms" }; -static const struct soc_enum aic3x_agc_attack_enum[] = { - SOC_ENUM_SINGLE(LAGC_CTRL_A, 2, 4, aic3x_agc_attack), - SOC_ENUM_SINGLE(RAGC_CTRL_A, 2, 4, aic3x_agc_attack), -}; - -static const char *aic3x_agc_decay[] = { "100ms", "200ms", "400ms", "500ms" }; -static const struct soc_enum aic3x_agc_decay_enum[] = { - SOC_ENUM_SINGLE(LAGC_CTRL_A, 0, 4, aic3x_agc_decay), - SOC_ENUM_SINGLE(RAGC_CTRL_A, 0, 4, aic3x_agc_decay), -}; +static const char * const aic3x_left_dac_mux[] = { + "DAC_L1", "DAC_L3", "DAC_L2" }; +static SOC_ENUM_SINGLE_DECL(aic3x_left_dac_enum, DAC_LINE_MUX, 6, + aic3x_left_dac_mux); + +static const char * const aic3x_right_dac_mux[] = { + "DAC_R1", "DAC_R3", "DAC_R2" }; +static SOC_ENUM_SINGLE_DECL(aic3x_right_dac_enum, DAC_LINE_MUX, 4, + aic3x_right_dac_mux); + +static const char * const aic3x_left_hpcom_mux[] = { + "differential of HPLOUT", "constant VCM", "single-ended" }; +static SOC_ENUM_SINGLE_DECL(aic3x_left_hpcom_enum, HPLCOM_CFG, 4, + aic3x_left_hpcom_mux); + +static const char * const aic3x_right_hpcom_mux[] = { + "differential of HPROUT", "constant VCM", "single-ended", + "differential of HPLCOM", "external feedback" }; +static SOC_ENUM_SINGLE_DECL(aic3x_right_hpcom_enum, HPRCOM_CFG, 3, + aic3x_right_hpcom_mux); + +static const char * const aic3x_linein_mode_mux[] = { + "single-ended", "differential" }; +static SOC_ENUM_SINGLE_DECL(aic3x_line1l_2_l_enum, LINE1L_2_LADC_CTRL, 7, + aic3x_linein_mode_mux); +static SOC_ENUM_SINGLE_DECL(aic3x_line1l_2_r_enum, LINE1L_2_RADC_CTRL, 7, + aic3x_linein_mode_mux); +static SOC_ENUM_SINGLE_DECL(aic3x_line1r_2_l_enum, LINE1R_2_LADC_CTRL, 7, + aic3x_linein_mode_mux); +static SOC_ENUM_SINGLE_DECL(aic3x_line1r_2_r_enum, LINE1R_2_RADC_CTRL, 7, + aic3x_linein_mode_mux); +static SOC_ENUM_SINGLE_DECL(aic3x_line2l_2_ldac_enum, LINE2L_2_LADC_CTRL, 7, + aic3x_linein_mode_mux); +static SOC_ENUM_SINGLE_DECL(aic3x_line2r_2_rdac_enum, LINE2R_2_RADC_CTRL, 7, + aic3x_linein_mode_mux); + +static const char * const aic3x_adc_hpf[] = { + "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" }; +static SOC_ENUM_DOUBLE_DECL(aic3x_adc_hpf_enum, AIC3X_CODEC_DFILT_CTRL, 6, 4, + aic3x_adc_hpf); + +static const char * const aic3x_agc_level[] = { + "-5.5dB", "-8dB", "-10dB", "-12dB", + "-14dB", "-17dB", "-20dB", "-24dB" }; +static SOC_ENUM_SINGLE_DECL(aic3x_lagc_level_enum, LAGC_CTRL_A, 4, + aic3x_agc_level); +static SOC_ENUM_SINGLE_DECL(aic3x_ragc_level_enum, RAGC_CTRL_A, 4, + aic3x_agc_level); + +static const char * const aic3x_agc_attack[] = { + "8ms", "11ms", "16ms", "20ms" }; +static SOC_ENUM_SINGLE_DECL(aic3x_lagc_attack_enum, LAGC_CTRL_A, 2, + aic3x_agc_attack); +static SOC_ENUM_SINGLE_DECL(aic3x_ragc_attack_enum, RAGC_CTRL_A, 2, + aic3x_agc_attack); + +static const char * const aic3x_agc_decay[] = { + "100ms", "200ms", "400ms", "500ms" }; +static SOC_ENUM_SINGLE_DECL(aic3x_lagc_decay_enum, LAGC_CTRL_A, 0, + aic3x_agc_decay); +static SOC_ENUM_SINGLE_DECL(aic3x_ragc_decay_enum, RAGC_CTRL_A, 0, + aic3x_agc_decay); /* * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps @@ -385,12 +392,12 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { * adjust PGA to max value when ADC is on and will never go back. */ SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), - SOC_ENUM("Left AGC Target level", aic3x_agc_level_enum[0]), - SOC_ENUM("Right AGC Target level", aic3x_agc_level_enum[1]), - SOC_ENUM("Left AGC Attack time", aic3x_agc_attack_enum[0]), - SOC_ENUM("Right AGC Attack time", aic3x_agc_attack_enum[1]), - SOC_ENUM("Left AGC Decay time", aic3x_agc_decay_enum[0]), - SOC_ENUM("Right AGC Decay time", aic3x_agc_decay_enum[1]), + SOC_ENUM("Left AGC Target level", aic3x_lagc_level_enum), + SOC_ENUM("Right AGC Target level", aic3x_ragc_level_enum), + SOC_ENUM("Left AGC Attack time", aic3x_lagc_attack_enum), + SOC_ENUM("Right AGC Attack time", aic3x_ragc_attack_enum), + SOC_ENUM("Left AGC Decay time", aic3x_lagc_decay_enum), + SOC_ENUM("Right AGC Decay time", aic3x_ragc_decay_enum), /* De-emphasis */ SOC_DOUBLE("De-emphasis Switch", AIC3X_CODEC_DFILT_CTRL, 2, 0, 0x01, 0), @@ -400,7 +407,7 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { 0, 119, 0, adc_tlv), SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), - SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), + SOC_ENUM("ADC HPF Cut-off", aic3x_adc_hpf_enum), }; static const struct snd_kcontrol_new aic3x_mono_controls[] = { @@ -427,19 +434,19 @@ static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = /* Left DAC Mux */ static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_left_dac_enum); /* Right DAC Mux */ static const struct snd_kcontrol_new aic3x_right_dac_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[RDAC_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_right_dac_enum); /* Left HPCOM Mux */ static const struct snd_kcontrol_new aic3x_left_hpcom_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LHPCOM_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_left_hpcom_enum); /* Right HPCOM Mux */ static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_right_hpcom_enum); /* Left Line Mixer */ static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = { @@ -531,23 +538,23 @@ static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = { /* Left Line1 Mux */ static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_L_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line1l_2_l_enum); static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_R_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line1l_2_r_enum); /* Right Line1 Mux */ static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_R_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line1r_2_r_enum); static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_L_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line1r_2_l_enum); /* Left Line2 Mux */ static const struct snd_kcontrol_new aic3x_left_line2_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE2L_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line2l_2_ldac_enum); /* Right Line2 Mux */ static const struct snd_kcontrol_new aic3x_right_line2_mux_controls = -SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]); +SOC_DAPM_ENUM("Route", aic3x_line2r_2_rdac_enum); static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { /* Left DAC to Left Outputs */ -- GitLab From 68d6626925c3529790a2055d41578415fa98495e Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Tue, 11 Nov 2014 10:59:01 +0200 Subject: [PATCH 4249/9457] ASoC: tlv320aic3x: Add output driver pop reduction controls Output driver has two parameters that can be configured to reduce pop noise: power-on delay and ramp-up step time. Two new kcontrols have been added to set these parameters. Signed-off-by: Misael Lopez Cruz Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 990140058aa6..f0a828119aba 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -279,6 +279,16 @@ static SOC_ENUM_SINGLE_DECL(aic3x_lagc_decay_enum, LAGC_CTRL_A, 0, static SOC_ENUM_SINGLE_DECL(aic3x_ragc_decay_enum, RAGC_CTRL_A, 0, aic3x_agc_decay); +static const char * const aic3x_poweron_time[] = { + "0us", "10us", "100us", "1ms", "10ms", "50ms", + "100ms", "200ms", "400ms", "800ms", "2s", "4s" }; +static SOC_ENUM_SINGLE_DECL(aic3x_poweron_time_enum, HPOUT_POP_REDUCTION, 4, + aic3x_poweron_time); + +static const char * const aic3x_rampup_step[] = { "0ms", "1ms", "2ms", "4ms" }; +static SOC_ENUM_SINGLE_DECL(aic3x_rampup_step_enum, HPOUT_POP_REDUCTION, 2, + aic3x_rampup_step); + /* * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps */ @@ -408,6 +418,10 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), SOC_ENUM("ADC HPF Cut-off", aic3x_adc_hpf_enum), + + /* Pop reduction */ + SOC_ENUM("Output Driver Power-On time", aic3x_poweron_time_enum), + SOC_ENUM("Output Driver Ramp-up step", aic3x_rampup_step_enum), }; static const struct snd_kcontrol_new aic3x_mono_controls[] = { -- GitLab From 0db4e162e6617ed0d0cb34756b86ab3dc6ad4fbf Mon Sep 17 00:00:00 2001 From: Kamil Krawczyk Date: Sat, 25 Oct 2014 03:24:30 +0000 Subject: [PATCH 4250/9457] i40e: poll firmware slower The code was polling the firmware tail register for completion every 10 microseconds, which is way faster than the firmware can respond. This changes the poll interval to 1ms, which reduces polling CPU utilization, and the number of times we loop. The maximum delay is still 100ms. Change-ID: I4bbfa6b66d802890baf8b4154061e55942b90958 Signed-off-by: Kamil Krawczyk Acked-by: Shannon Nelson Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq.c | 6 ++---- drivers/net/ethernet/intel/i40e/i40e_adminq.h | 2 +- drivers/net/ethernet/intel/i40evf/i40e_adminq.c | 6 ++---- drivers/net/ethernet/intel/i40evf/i40e_adminq.h | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index 72f5d25a222f..f7f6206368df 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -853,7 +853,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, */ if (!details->async && !details->postpone) { u32 total_delay = 0; - u32 delay_len = 10; do { /* AQ designers suggest use of head for better @@ -861,9 +860,8 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, */ if (i40e_asq_done(hw)) break; - /* ugh! delay while spin_lock */ - udelay(delay_len); - total_delay += delay_len; + usleep_range(1000, 2000); + total_delay++; } while (total_delay < hw->aq.asq_cmd_timeout); } diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h index ba38a89c79d6..df0bd09ed5d8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h @@ -141,7 +141,7 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc) /* general information */ #define I40E_AQ_LARGE_BUF 512 -#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ +#define I40E_ASQ_CMD_TIMEOUT 100 /* msecs */ void i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc, u16 opcode); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c index f206be917842..500ca2162708 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c @@ -801,7 +801,6 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw, */ if (!details->async && !details->postpone) { u32 total_delay = 0; - u32 delay_len = 10; do { /* AQ designers suggest use of head for better @@ -809,9 +808,8 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw, */ if (i40evf_asq_done(hw)) break; - /* ugh! delay while spin_lock */ - udelay(delay_len); - total_delay += delay_len; + usleep_range(1000, 2000); + total_delay++; } while (total_delay < hw->aq.asq_cmd_timeout); } diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h index 91a5c5bd80f3..f40cfac4b022 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h @@ -141,7 +141,7 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc) /* general information */ #define I40E_AQ_LARGE_BUF 512 -#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ +#define I40E_ASQ_CMD_TIMEOUT 100 /* msecs */ void i40evf_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc, u16 opcode); -- GitLab From 215367171badcc3c82e28be56620b9123aa8b528 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Sat, 25 Oct 2014 10:35:25 +0000 Subject: [PATCH 4251/9457] i40e: don't do link_status or stats collection on every ARQ The ARQ events cause a service_task execution, and we do a link_status check and full stats gathering for each service_task. However, when there are a lot of ARQ events, such as when doing an NVM update, we end up doing 10's if not 100's of these per second, thereby heavily abusing the PCI bus and especially the Firmware. This patch adds a check to keep the service_task from running these periodic tasks more than once per second, while still allowing quick action to service the events. Change-ID: Iec7670c37bfae9791c43fec26df48aea7f70b33e Signed-off-by: Shannon Nelson Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 3 ++- drivers/net/ethernet/intel/i40e/i40e_main.c | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index f1e33f896439..b7a807b380d7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -269,7 +269,8 @@ struct i40e_pf { u16 msg_enable; char misc_int_name[IFNAMSIZ + 9]; u16 adminq_work_limit; /* num of admin receive queue desc to process */ - int service_timer_period; + unsigned long service_timer_period; + unsigned long service_timer_previous; struct timer_list service_timer; struct work_struct service_task; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 1a98e2384b3b..de664631c807 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5449,7 +5449,7 @@ static void i40e_check_hang_subtask(struct i40e_pf *pf) } /** - * i40e_watchdog_subtask - Check and bring link up + * i40e_watchdog_subtask - periodic checks not using event driven response * @pf: board private structure **/ static void i40e_watchdog_subtask(struct i40e_pf *pf) @@ -5461,6 +5461,15 @@ static void i40e_watchdog_subtask(struct i40e_pf *pf) test_bit(__I40E_CONFIG_BUSY, &pf->state)) return; + /* make sure we don't do these things too often */ + if (time_before(jiffies, (pf->service_timer_previous + + pf->service_timer_period))) + return; + pf->service_timer_previous = jiffies; + + i40e_check_hang_subtask(pf); + i40e_link_event(pf); + /* Update the stats for active netdevs so the network stack * can look at updated numbers whenever it cares to */ @@ -6325,15 +6334,12 @@ static void i40e_service_task(struct work_struct *work) i40e_vc_process_vflr_event(pf); i40e_watchdog_subtask(pf); i40e_fdir_reinit_subtask(pf); - i40e_check_hang_subtask(pf); i40e_sync_filters_subtask(pf); #ifdef CONFIG_I40E_VXLAN i40e_sync_vxlan_filters_subtask(pf); #endif i40e_clean_adminq_subtask(pf); - i40e_link_event(pf); - i40e_service_event_complete(pf); /* If the tasks have taken longer than one timer cycle or there -- GitLab From 79442d38b370ed7317cd82fb2b6d1dafccaf44e5 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Sat, 25 Oct 2014 03:24:32 +0000 Subject: [PATCH 4252/9457] i40e: clean up throttle rate code The interrupt throttle rate minimum is actually 2us, so fix that define and while we are there, remove some unused defines. Change some strings in the function to be a bit less wrappy, and express the correct limits. Change-ID: I96829bbc77935e0b57c6f0fc1439fb4152b2960a Signed-off-by: Jesse Brandeburg Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 11 ++++------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 5 +---- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 5 +---- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index b6e745f277cc..afad5aa5a12b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1575,11 +1575,9 @@ static int i40e_set_coalesce(struct net_device *netdev, } else if (ec->rx_coalesce_usecs == 0) { vsi->rx_itr_setting = ec->rx_coalesce_usecs; if (ec->use_adaptive_rx_coalesce) - netif_info(pf, drv, netdev, - "Rx-secs=0, need to disable adaptive-Rx for a complete disable\n"); + netif_info(pf, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); } else { - netif_info(pf, drv, netdev, - "Invalid value, Rx-usecs range is 0, 8-8160\n"); + netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); return -EINVAL; } @@ -1589,11 +1587,10 @@ static int i40e_set_coalesce(struct net_device *netdev, } else if (ec->tx_coalesce_usecs == 0) { vsi->tx_itr_setting = ec->tx_coalesce_usecs; if (ec->use_adaptive_tx_coalesce) - netif_info(pf, drv, netdev, - "Tx-secs=0, need to disable adaptive-Tx for a complete disable\n"); + netif_info(pf, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n"); } else { netif_info(pf, drv, netdev, - "Invalid value, Tx-usecs range is 0, 8-8160\n"); + "Invalid value, tx-usecs range is 0-8160\n"); return -EINVAL; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index d7a625a6a14f..e60d3accb2e2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -30,10 +30,7 @@ /* Interrupt Throttling and Rate Limiting Goodies */ #define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */ -#define I40E_MIN_ITR 0x0004 /* reg uses 2 usec resolution */ -#define I40E_MAX_IRATE 0x03F -#define I40E_MIN_IRATE 0x001 -#define I40E_IRATE_USEC_RESOLUTION 4 +#define I40E_MIN_ITR 0x0001 /* reg uses 2 usec resolution */ #define I40E_ITR_100K 0x0005 #define I40E_ITR_20K 0x0019 #define I40E_ITR_8K 0x003E diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h index f6dcf9dd9290..c7f29626eada 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h @@ -30,10 +30,7 @@ /* Interrupt Throttling and Rate Limiting Goodies */ #define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */ -#define I40E_MIN_ITR 0x0004 /* reg uses 2 usec resolution */ -#define I40E_MAX_IRATE 0x03F -#define I40E_MIN_IRATE 0x001 -#define I40E_IRATE_USEC_RESOLUTION 4 +#define I40E_MIN_ITR 0x0001 /* reg uses 2 usec resolution */ #define I40E_ITR_100K 0x0005 #define I40E_ITR_20K 0x0019 #define I40E_ITR_8K 0x003E -- GitLab From f8d4db35e870896dd7b2ba70a30f4dfc53c39472 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Sat, 25 Oct 2014 03:24:33 +0000 Subject: [PATCH 4253/9457] i40evf: make early init processing more robust In early init, if we get an unexpected message from the PF (such as link status), we just kick an error back to the init task, causing it to restart its state machine and delaying initialization. Make the early init AQ message receive code more robust by handling messages in a loop, and ignoring those that we aren't interested in. This also gets rid of some scary log messages that really didn't indicate a problem. Change-ID: I620e8c72e49c49c665ef33eeab2425dd10e721cf Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- .../ethernet/intel/i40evf/i40evf_virtchnl.c | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 66d12f5b4ca8..ff8676147c14 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -89,6 +89,7 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter) struct i40e_virtchnl_version_info *pf_vvi; struct i40e_hw *hw = &adapter->hw; struct i40e_arq_event_info event; + enum i40e_virtchnl_ops op; i40e_status err; event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; @@ -98,18 +99,27 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter) goto out; } - err = i40evf_clean_arq_element(hw, &event, NULL); - if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) - goto out_alloc; + while (1) { + err = i40evf_clean_arq_element(hw, &event, NULL); + /* When the AQ is empty, i40evf_clean_arq_element will return + * nonzero and this loop will terminate. + */ + if (err) + goto out_alloc; + op = + (enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high); + if (op == I40E_VIRTCHNL_OP_VERSION) + break; + } + err = (i40e_status)le32_to_cpu(event.desc.cookie_low); if (err) goto out_alloc; - if ((enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high) != - I40E_VIRTCHNL_OP_VERSION) { + if (op != I40E_VIRTCHNL_OP_VERSION) { dev_info(&adapter->pdev->dev, "Invalid reply type %d from PF\n", - le32_to_cpu(event.desc.cookie_high)); + op); err = -EIO; goto out_alloc; } @@ -153,8 +163,9 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) { struct i40e_hw *hw = &adapter->hw; struct i40e_arq_event_info event; - u16 len; + enum i40e_virtchnl_ops op; i40e_status err; + u16 len; len = sizeof(struct i40e_virtchnl_vf_resource) + I40E_MAX_VF_VSI * sizeof(struct i40e_virtchnl_vsi_resource); @@ -165,29 +176,21 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) goto out; } - err = i40evf_clean_arq_element(hw, &event, NULL); - if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) - goto out_alloc; - - err = (i40e_status)le32_to_cpu(event.desc.cookie_low); - if (err) { - dev_err(&adapter->pdev->dev, - "%s: Error returned from PF, %d, %d\n", __func__, - le32_to_cpu(event.desc.cookie_high), - le32_to_cpu(event.desc.cookie_low)); - err = -EIO; - goto out_alloc; + while (1) { + event.msg_size = len; + /* When the AQ is empty, i40evf_clean_arq_element will return + * nonzero and this loop will terminate. + */ + err = i40evf_clean_arq_element(hw, &event, NULL); + if (err) + goto out_alloc; + op = + (enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high); + if (op == I40E_VIRTCHNL_OP_GET_VF_RESOURCES) + break; } - if ((enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high) != - I40E_VIRTCHNL_OP_GET_VF_RESOURCES) { - dev_err(&adapter->pdev->dev, - "%s: Invalid response from PF, %d, %d\n", __func__, - le32_to_cpu(event.desc.cookie_high), - le32_to_cpu(event.desc.cookie_low)); - err = -EIO; - goto out_alloc; - } + err = (i40e_status)le32_to_cpu(event.desc.cookie_low); memcpy(adapter->vf_res, event.msg_buf, min(event.msg_size, len)); i40e_vf_parse_hw_config(hw, adapter->vf_res); -- GitLab From cc0529271f23896208723e310fd75c2c88b3fd8c Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Sat, 25 Oct 2014 03:24:34 +0000 Subject: [PATCH 4254/9457] i40evf: don't use more queues than CPUs It's kind of silly to configure and attempt to use a bunch of queue pairs when you're running on a single (virtual) CPU. Instead of unconditionally configuring all of the queues that the PF gives us, clamp the number of queue pairs to the number of CPUs. Change-ID: I321714c9e15072ee76de8f95ab9a81f86ed347d1 Signed-off-by: Mitch Williams Signed-off-by: Patrick Lu Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf.h | 1 + .../ethernet/intel/i40evf/i40evf_ethtool.c | 16 +++--- .../net/ethernet/intel/i40evf/i40evf_main.c | 50 +++++++++++-------- .../ethernet/intel/i40evf/i40evf_virtchnl.c | 6 +-- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index 30ef519d4b91..1113f8a2d3b6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -191,6 +191,7 @@ struct i40evf_adapter { struct i40e_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; struct list_head vlan_filter_list; char misc_vector_name[IFNAMSIZ + 9]; + int num_active_queues; /* TX */ struct i40e_ring *tx_rings[I40E_MAX_VSI_QP]; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c index efee6b290c0f..876411c39ee0 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c @@ -59,7 +59,7 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = { #define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats) #define I40EVF_QUEUE_STATS_LEN(_dev) \ (((struct i40evf_adapter *) \ - netdev_priv(_dev))->vsi_res->num_queue_pairs \ + netdev_priv(_dev))->num_active_queues \ * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64))) #define I40EVF_STATS_LEN(_dev) \ (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev)) @@ -121,11 +121,11 @@ static void i40evf_get_ethtool_stats(struct net_device *netdev, p = (char *)adapter + i40evf_gstrings_stats[i].stat_offset; data[i] = *(u64 *)p; } - for (j = 0; j < adapter->vsi_res->num_queue_pairs; j++) { + for (j = 0; j < adapter->num_active_queues; j++) { data[i++] = adapter->tx_rings[j]->stats.packets; data[i++] = adapter->tx_rings[j]->stats.bytes; } - for (j = 0; j < adapter->vsi_res->num_queue_pairs; j++) { + for (j = 0; j < adapter->num_active_queues; j++) { data[i++] = adapter->rx_rings[j]->stats.packets; data[i++] = adapter->rx_rings[j]->stats.bytes; } @@ -151,13 +151,13 @@ static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data) ETH_GSTRING_LEN); p += ETH_GSTRING_LEN; } - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { snprintf(p, ETH_GSTRING_LEN, "tx-%u.packets", i); p += ETH_GSTRING_LEN; snprintf(p, ETH_GSTRING_LEN, "tx-%u.bytes", i); p += ETH_GSTRING_LEN; } - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { snprintf(p, ETH_GSTRING_LEN, "rx-%u.packets", i); p += ETH_GSTRING_LEN; snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i); @@ -430,7 +430,7 @@ static int i40evf_get_rxnfc(struct net_device *netdev, switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - cmd->data = adapter->vsi_res->num_queue_pairs; + cmd->data = adapter->num_active_queues; ret = 0; break; case ETHTOOL_GRXFH: @@ -598,12 +598,12 @@ static void i40evf_get_channels(struct net_device *netdev, struct i40evf_adapter *adapter = netdev_priv(netdev); /* Report maximum channels */ - ch->max_combined = adapter->vsi_res->num_queue_pairs; + ch->max_combined = adapter->num_active_queues; ch->max_other = NONQ_VECS; ch->other_count = NONQ_VECS; - ch->combined_count = adapter->vsi_res->num_queue_pairs; + ch->combined_count = adapter->num_active_queues; } /** diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index b2f01eb2f9e5..f0d07ad54198 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -397,8 +397,8 @@ static int i40evf_map_rings_to_vectors(struct i40evf_adapter *adapter) int q_vectors; int v_start = 0; int rxr_idx = 0, txr_idx = 0; - int rxr_remaining = adapter->vsi_res->num_queue_pairs; - int txr_remaining = adapter->vsi_res->num_queue_pairs; + int rxr_remaining = adapter->num_active_queues; + int txr_remaining = adapter->num_active_queues; int i, j; int rqpv, tqpv; int err = 0; @@ -584,7 +584,7 @@ static void i40evf_configure_tx(struct i40evf_adapter *adapter) { struct i40e_hw *hw = &adapter->hw; int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) + for (i = 0; i < adapter->num_active_queues; i++) adapter->tx_rings[i]->tail = hw->hw_addr + I40E_QTX_TAIL1(i); } @@ -629,7 +629,7 @@ static void i40evf_configure_rx(struct i40evf_adapter *adapter) rx_buf_len = ALIGN(max_frame, 1024); } - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { adapter->rx_rings[i]->tail = hw->hw_addr + I40E_QRX_TAIL1(i); adapter->rx_rings[i]->rx_buf_len = rx_buf_len; } @@ -918,7 +918,7 @@ static void i40evf_configure(struct i40evf_adapter *adapter) i40evf_configure_rx(adapter); adapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { struct i40e_ring *ring = adapter->rx_rings[i]; i40evf_alloc_rx_buffers(ring, ring->count); ring->next_to_use = ring->count - 1; @@ -950,7 +950,7 @@ static void i40evf_clean_all_rx_rings(struct i40evf_adapter *adapter) { int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) + for (i = 0; i < adapter->num_active_queues; i++) i40evf_clean_rx_ring(adapter->rx_rings[i]); } @@ -962,7 +962,7 @@ static void i40evf_clean_all_tx_rings(struct i40evf_adapter *adapter) { int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) + for (i = 0; i < adapter->num_active_queues; i++) i40evf_clean_tx_ring(adapter->tx_rings[i]); } @@ -1064,7 +1064,7 @@ static void i40evf_free_queues(struct i40evf_adapter *adapter) if (!adapter->vsi_res) return; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { if (adapter->tx_rings[i]) kfree_rcu(adapter->tx_rings[i], rcu); adapter->tx_rings[i] = NULL; @@ -1084,7 +1084,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter) { int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { struct i40e_ring *tx_ring; struct i40e_ring *rx_ring; @@ -1130,7 +1130,7 @@ static int i40evf_set_interrupt_capability(struct i40evf_adapter *adapter) err = -EIO; goto out; } - pairs = adapter->vsi_res->num_queue_pairs; + pairs = adapter->num_active_queues; /* It's easy to be greedy for MSI-X vectors, but it really * doesn't do us much good if we have a lot more vectors @@ -1210,7 +1210,7 @@ static void i40evf_free_q_vectors(struct i40evf_adapter *adapter) int napi_vectors; num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; - napi_vectors = adapter->vsi_res->num_queue_pairs; + napi_vectors = adapter->num_active_queues; for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { struct i40e_q_vector *q_vector = adapter->q_vector[q_idx]; @@ -1265,8 +1265,8 @@ int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter) } dev_info(&adapter->pdev->dev, "Multiqueue %s: Queue pair count = %u", - (adapter->vsi_res->num_queue_pairs > 1) ? "Enabled" : - "Disabled", adapter->vsi_res->num_queue_pairs); + (adapter->num_active_queues > 1) ? "Enabled" : + "Disabled", adapter->num_active_queues); return 0; err_alloc_queues: @@ -1425,7 +1425,7 @@ static int next_queue(struct i40evf_adapter *adapter, int j) { j += 1; - return j >= adapter->vsi_res->num_queue_pairs ? 0 : j; + return j >= adapter->num_active_queues ? 0 : j; } /** @@ -1446,9 +1446,14 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter) 0xc135cafa, 0x7a6f7e2d, 0xe7102d28, 0x163cd12e, 0x4954b126 }; - /* Hash type is configured by the PF - we just supply the key */ + /* No RSS for single queue. */ + if (adapter->num_active_queues == 1) { + wr32(hw, I40E_VFQF_HENA(0), 0); + wr32(hw, I40E_VFQF_HENA(1), 0); + return; + } - /* Fill out hash function seed */ + /* Hash type is configured by the PF - we just supply the key */ for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) wr32(hw, I40E_VFQF_HKEY(i), seed[i]); @@ -1458,7 +1463,7 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter) wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32)); /* Populate the LUT with max no. of queues in round robin fashion */ - j = adapter->vsi_res->num_queue_pairs; + j = adapter->num_active_queues; for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) { j = next_queue(adapter, j); lut = j; @@ -1703,7 +1708,7 @@ static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter) { int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) + for (i = 0; i < adapter->num_active_queues; i++) if (adapter->tx_rings[i]->desc) i40evf_free_tx_resources(adapter->tx_rings[i]); @@ -1723,7 +1728,7 @@ static int i40evf_setup_all_tx_resources(struct i40evf_adapter *adapter) { int i, err = 0; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { adapter->tx_rings[i]->count = adapter->tx_desc_count; err = i40evf_setup_tx_descriptors(adapter->tx_rings[i]); if (!err) @@ -1751,7 +1756,7 @@ static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter) { int i, err = 0; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + for (i = 0; i < adapter->num_active_queues; i++) { adapter->rx_rings[i]->count = adapter->rx_desc_count; err = i40evf_setup_rx_descriptors(adapter->rx_rings[i]); if (!err) @@ -1774,7 +1779,7 @@ static void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter) { int i; - for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) + for (i = 0; i < adapter->num_active_queues; i++) if (adapter->rx_rings[i]->desc) i40evf_free_rx_resources(adapter->rx_rings[i]); } @@ -2150,6 +2155,9 @@ static void i40evf_init_task(struct work_struct *work) adapter->watchdog_timer.data = (unsigned long)adapter; mod_timer(&adapter->watchdog_timer, jiffies + 1); + adapter->num_active_queues = min_t(int, + adapter->vsi_res->num_queue_pairs, + (int)(num_online_cpus())); adapter->tx_desc_count = I40EVF_DEFAULT_TXD; adapter->rx_desc_count = I40EVF_DEFAULT_RXD; err = i40evf_init_interrupt_scheme(adapter); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index ff8676147c14..49bfdb5421c8 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -210,7 +210,7 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter) { struct i40e_virtchnl_vsi_queue_config_info *vqci; struct i40e_virtchnl_queue_pair_info *vqpi; - int pairs = adapter->vsi_res->num_queue_pairs; + int pairs = adapter->num_active_queues; int i, len; if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { @@ -276,7 +276,7 @@ void i40evf_enable_queues(struct i40evf_adapter *adapter) } adapter->current_op = I40E_VIRTCHNL_OP_ENABLE_QUEUES; vqs.vsi_id = adapter->vsi_res->vsi_id; - vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1; + vqs.tx_queues = (1 << adapter->num_active_queues) - 1; vqs.rx_queues = vqs.tx_queues; adapter->aq_pending |= I40EVF_FLAG_AQ_ENABLE_QUEUES; adapter->aq_required &= ~I40EVF_FLAG_AQ_ENABLE_QUEUES; @@ -302,7 +302,7 @@ void i40evf_disable_queues(struct i40evf_adapter *adapter) } adapter->current_op = I40E_VIRTCHNL_OP_DISABLE_QUEUES; vqs.vsi_id = adapter->vsi_res->vsi_id; - vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1; + vqs.tx_queues = (1 << adapter->num_active_queues) - 1; vqs.rx_queues = vqs.tx_queues; adapter->aq_pending |= I40EVF_FLAG_AQ_DISABLE_QUEUES; adapter->aq_required &= ~I40EVF_FLAG_AQ_DISABLE_QUEUES; -- GitLab From 71bde60191a9fa44d33b582c5e3713ffe99b0fef Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 29 Oct 2014 07:23:41 +0000 Subject: [PATCH 4255/9457] ixgbe: fix X540 Completion timeout On topologies including few levels of PCIe switching X540 can run into an unexpected completion error. We get around this by waiting after enabling loopback a sufficient amount of time until Tx Data Fetch is sent. We then poll the pending transaction bit to ensure we received the completion. Only then do we go on to clear the buffers. Signed-of-by: Don Skidmore Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_common.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index b5f484bf3fda..040670876183 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -3583,7 +3583,8 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, **/ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) { - u32 gcr_ext, hlreg0; + u32 gcr_ext, hlreg0, i, poll; + u16 value; /* * If double reset is not requested then all transactions should @@ -3600,6 +3601,23 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw) hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK); + /* wait for a last completion before clearing buffers */ + IXGBE_WRITE_FLUSH(hw); + usleep_range(3000, 6000); + + /* Before proceeding, make sure that the PCIe block does not have + * transactions pending. + */ + poll = ixgbe_pcie_timeout_poll(hw); + for (i = 0; i < poll; i++) { + usleep_range(100, 200); + value = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_DEVICE_STATUS); + if (ixgbe_removed(hw->hw_addr)) + break; + if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) + break; + } + /* initiate cleaning flow for buffers in the PCIe transaction layer */ gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, -- GitLab From d497a82fb18ed4b73c08f8b5a0935f937e2ea1fb Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Wed, 12 Nov 2014 01:09:54 +1100 Subject: [PATCH 4256/9457] ALSA: usb-audio: Add mixer control for Digidesign Mbox 1 clock source This patch provides the infrastructure for the Digidesign Mbox 1 to have a mixer control for selecting the clock source. Valid options are Internal and S/PDIF external sync. A non-documented command is sent to the device to enable this feature found by reverse engineering and bus snooping. Signed-off-by: Damien Zammit Signed-off-by: Takashi Iwai --- sound/usb/mixer_maps.c | 9 +++ sound/usb/mixer_quirks.c | 129 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index d1d72ff50347..1994d41348f8 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -179,6 +179,11 @@ static struct usbmix_name_map audigy2nx_map[] = { { 0 } /* terminator */ }; +static struct usbmix_name_map mbox1_map[] = { + { 1, "Clock" }, + { 0 } /* terminator */ +}; + static struct usbmix_selector_map c400_selectors[] = { { .id = 0x80, @@ -415,6 +420,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x0ccd, 0x0028), .map = aureon_51_2_map, }, + { + .id = USB_ID(0x0dba, 0x1000), + .map = mbox1_map, + }, { .id = USB_ID(0x13e5, 0x0001), .map = scratch_live_map, diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 3980bf554c83..45203168ac6d 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -565,6 +565,131 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) return 0; } +/* Digidesign Mbox 1 clock source switch (internal/spdif) */ + +static int snd_mbox1_switch_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = kctl->private_value; + return 0; +} + +static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_usb_audio *chip; + struct usb_mixer_interface *mixer; + int err; + bool cur_val, new_val; + unsigned char buff[3]; + + cur_val = kctl->private_value; + new_val = ucontrol->value.enumerated.item[0]; + + mixer = snd_kcontrol_chip(kctl); + if (snd_BUG_ON(!mixer)) + return -EINVAL; + + chip = mixer->chip; + if (snd_BUG_ON(!chip)) + return -EINVAL; + + if (cur_val == new_val) + return 0; + + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) { + err = -ENODEV; + goto err; + } + + /* Prepare for magic command to toggle clock source */ + err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), 0x81, + USB_DIR_IN | + USB_TYPE_CLASS | + USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1); + if (err < 0) + goto err; + err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), 0x81, + USB_DIR_IN | + USB_TYPE_CLASS | + USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); + if (err < 0) + goto err; + + /* 2 possibilities: Internal -> send sample rate + * S/PDIF sync -> send zeroes + * NB: Sample rate locked to 48kHz on purpose to + * prevent user from resetting the sample rate + * while S/PDIF sync is enabled and confusing + * this configuration. + */ + if (new_val == 0) { + buff[0] = 0x80; + buff[1] = 0xbb; + buff[2] = 0x00; + } else { + buff[0] = buff[1] = buff[2] = 0x00; + } + + /* Send the magic command to toggle the clock source */ + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), 0x1, + USB_TYPE_CLASS | + USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); + if (err < 0) + goto err; + err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), 0x81, + USB_DIR_IN | + USB_TYPE_CLASS | + USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3); + if (err < 0) + goto err; + err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), 0x81, + USB_DIR_IN | + USB_TYPE_CLASS | + USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3); + if (err < 0) + goto err; + kctl->private_value = new_val; + +err: + up_read(&chip->shutdown_rwsem); + return err < 0 ? err : 1; +} + +static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char *const texts[2] = { + "Internal", + "S/PDIF" + }; + + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); +} + +static struct snd_kcontrol_new snd_mbox1_switch = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Clock Source", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_mbox1_switch_info, + .get = snd_mbox1_switch_get, + .put = snd_mbox1_switch_put, + .private_value = 0 +}; + +static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer) +{ + return snd_ctl_add(mixer->chip->card, + snd_ctl_new1(&snd_mbox1_switch, mixer)); +} + /* Native Instruments device quirks */ #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex)) @@ -1632,6 +1757,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err = snd_microii_controls_create(mixer); break; + case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */ + err = snd_mbox1_create_sync_switch(mixer); + break; + case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */ err = snd_nativeinstruments_create_mixer(mixer, snd_nativeinstruments_ta6_mixers, -- GitLab From c63fcb9b67777b906c4515a868afbd96bae4e799 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Wed, 12 Nov 2014 01:09:55 +1100 Subject: [PATCH 4257/9457] ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable mixer This patch provides duplex support for the Digidesign Mbox 1 sound card and has been a work in progress for about a year. Users have confirmed on my website that previous versions of this patch have worked on the hardware and I have been testing extensively. It also enables the mixer control for providing clock source selector based on the previous patch. The sample rate has been hardcoded to 48kHz because it works better with the S/PDIF sync mode when the sample rate is locked. This is the highest rate that the device supports and no loss of functionality is observed by restricting the sample rate apart from the inability to selec a lower rate. Signed-off-by: Damien Zammit Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 41 +++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c657752a420c..13f44fd0e930 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2944,7 +2944,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .data = (const struct snd_usb_audio_quirk[]){ { .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE, + .type = QUIRK_AUDIO_STANDARD_MIXER, }, { .ifnum = 1, @@ -2955,16 +2955,40 @@ YAMAHA_DEVICE(0x7010, "UB99"), .iface = 1, .altsetting = 1, .altset_idx = 1, - .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, + .attributes = 0x4, .endpoint = 0x02, - .ep_attr = 0x01, - .rates = SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 44100, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_SYNC, + .maxpacksize = 0x130, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, .rate_max = 48000, - .nr_rates = 2, + .nr_rates = 1, .rate_table = (unsigned int[]) { - 44100, 48000 + 48000 + } + } + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3BE, + .channels = 2, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0x4, + .endpoint = 0x81, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .maxpacksize = 0x130, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { + 48000 } } }, @@ -2972,7 +2996,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), .ifnum = -1 } } - } }, -- GitLab From 2b509c0cd2923f2ca6e7b13517e54b6a60e56e18 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Sat, 1 Nov 2014 01:06:57 +0000 Subject: [PATCH 4258/9457] ixgbe: cleanup ixgbe_ndo_set_vf_vlan Clean up functionality in ixgbe_ndo_set_vf_vlan that will simplify later patches. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 94 ++++++++++++------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 97c85b859536..07d1c047d1c6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1079,52 +1079,80 @@ int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) return ixgbe_set_vf_mac(adapter, vf, mac); } +static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf, + u16 vlan, u8 qos) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err = 0; + + if (adapter->vfinfo[vf].pf_vlan) + err = ixgbe_set_vf_vlan(adapter, false, + adapter->vfinfo[vf].pf_vlan, + vf); + if (err) + goto out; + ixgbe_set_vmvir(adapter, vlan, qos, vf); + ixgbe_set_vmolr(hw, vf, false); + if (adapter->vfinfo[vf].spoofchk_enabled) + hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); + adapter->vfinfo[vf].vlan_count++; + adapter->vfinfo[vf].pf_vlan = vlan; + adapter->vfinfo[vf].pf_qos = qos; + dev_info(&adapter->pdev->dev, + "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); + if (test_bit(__IXGBE_DOWN, &adapter->state)) { + dev_warn(&adapter->pdev->dev, + "The VF VLAN has been set, but the PF device is not up.\n"); + dev_warn(&adapter->pdev->dev, + "Bring the PF device up before attempting to use the VF device.\n"); + } + +out: + return err; +} + +static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + + err = ixgbe_set_vf_vlan(adapter, false, + adapter->vfinfo[vf].pf_vlan, vf); + ixgbe_clear_vmvir(adapter, vf); + ixgbe_set_vmolr(hw, vf, true); + hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); + if (adapter->vfinfo[vf].vlan_count) + adapter->vfinfo[vf].vlan_count--; + adapter->vfinfo[vf].pf_vlan = 0; + adapter->vfinfo[vf].pf_qos = 0; + + return err; +} + int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) { int err = 0; struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) return -EINVAL; if (vlan || qos) { + /* Check if there is already a port VLAN set, if so + * we have to delete the old one first before we + * can set the new one. The usage model had + * previously assumed the user would delete the + * old port VLAN before setting a new one but this + * is not necessarily the case. + */ if (adapter->vfinfo[vf].pf_vlan) - err = ixgbe_set_vf_vlan(adapter, false, - adapter->vfinfo[vf].pf_vlan, - vf); - if (err) - goto out; - err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); + err = ixgbe_disable_port_vlan(adapter, vf); if (err) goto out; - ixgbe_set_vmvir(adapter, vlan, qos, vf); - ixgbe_set_vmolr(hw, vf, false); - if (adapter->vfinfo[vf].spoofchk_enabled) - hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); - adapter->vfinfo[vf].vlan_count++; - adapter->vfinfo[vf].pf_vlan = vlan; - adapter->vfinfo[vf].pf_qos = qos; - dev_info(&adapter->pdev->dev, - "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); - if (test_bit(__IXGBE_DOWN, &adapter->state)) { - dev_warn(&adapter->pdev->dev, - "The VF VLAN has been set," - " but the PF device is not up.\n"); - dev_warn(&adapter->pdev->dev, - "Bring the PF device up before" - " attempting to use the VF device.\n"); - } + err = ixgbe_enable_port_vlan(adapter, vf, vlan, qos); } else { - err = ixgbe_set_vf_vlan(adapter, false, - adapter->vfinfo[vf].pf_vlan, vf); - ixgbe_clear_vmvir(adapter, vf); - ixgbe_set_vmolr(hw, vf, true); - hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); - if (adapter->vfinfo[vf].vlan_count) - adapter->vfinfo[vf].vlan_count--; - adapter->vfinfo[vf].pf_vlan = 0; - adapter->vfinfo[vf].pf_qos = 0; + err = ixgbe_disable_port_vlan(adapter, vf); } + out: return err; } -- GitLab From 8d697e7e54eed5528c3cd720607af6c1d6032d42 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 5 Nov 2014 04:52:09 +0000 Subject: [PATCH 4259/9457] ixgbe: cleanup move setting PFQDE.HIDE_VLAN to support function. Move setting of drop enable to support function. This not only makes the code more readable but is also prep for following patches that add additional MAC support. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 07d1c047d1c6..0c25df506247 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -618,6 +618,27 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) return 0; } +static inline void ixgbe_write_qde(struct ixgbe_adapter *adapter, u32 vf, + u32 qde) +{ + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; + u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask); + int i; + + for (i = vf * q_per_pool; i < ((vf + 1) * q_per_pool); i++) { + u32 reg; + + /* flush previous write */ + IXGBE_WRITE_FLUSH(hw); + + /* indicate to hardware that we want to set drop enable */ + reg = IXGBE_QDE_WRITE | IXGBE_QDE_ENABLE; + reg |= i << IXGBE_QDE_IDX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_QDE, reg); + } +} + static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; @@ -647,15 +668,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); /* force drop enable for all VF Rx queues */ - for (i = vf * q_per_pool; i < ((vf + 1) * q_per_pool); i++) { - /* flush previous write */ - IXGBE_WRITE_FLUSH(hw); - - /* indicate to hardware that we want to set drop enable */ - reg = IXGBE_QDE_WRITE | IXGBE_QDE_ENABLE; - reg |= i << IXGBE_QDE_IDX_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_QDE, reg); - } + ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE); /* enable receive for vf */ reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); -- GitLab From 9a75a1ac77fac4f63d7013c66c550fbf8e213715 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 7 Nov 2014 03:53:35 +0000 Subject: [PATCH 4260/9457] ixgbe: Add new support for X550 MAC's This patch will add in the new MAC defines and fit it into the switch cases throughout the driver. New functionality and enablement support will be added in following patches. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbe/ixgbe_common.c | 30 +++++-- drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c | 8 ++ .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 1 + .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 37 ++++++-- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 2 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 90 ++++++++++++++++--- drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c | 4 + drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 64 +++++++------ .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 6 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 45 ++++++++-- 10 files changed, 223 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 040670876183..0e754b4c4220 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -2799,6 +2799,8 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; break; @@ -3192,17 +3194,27 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, *link_up = false; } - if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_10G_82599) - *speed = IXGBE_LINK_SPEED_10GB_FULL; - else if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_1G_82599) + switch (links_reg & IXGBE_LINKS_SPEED_82599) { + case IXGBE_LINKS_SPEED_10G_82599: + if ((hw->mac.type >= ixgbe_mac_X550) && + (links_reg & IXGBE_LINKS_SPEED_NON_STD)) + *speed = IXGBE_LINK_SPEED_2_5GB_FULL; + else + *speed = IXGBE_LINK_SPEED_10GB_FULL; + break; + case IXGBE_LINKS_SPEED_1G_82599: *speed = IXGBE_LINK_SPEED_1GB_FULL; - else if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_100_82599) - *speed = IXGBE_LINK_SPEED_100_FULL; - else + break; + case IXGBE_LINKS_SPEED_100_82599: + if ((hw->mac.type >= ixgbe_mac_X550) && + (links_reg & IXGBE_LINKS_SPEED_NON_STD)) + *speed = IXGBE_LINK_SPEED_5GB_FULL; + else + *speed = IXGBE_LINK_SPEED_100_FULL; + break; + default: *speed = IXGBE_LINK_SPEED_UNKNOWN; + } return 0; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c index 48f35fc963f8..a507a6fe3624 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c @@ -286,6 +286,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, bwgid, ptype); case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max, bwgid, ptype, prio_tc); default: @@ -302,6 +304,8 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) return ixgbe_dcb_config_pfc_82598(hw, pfc_en); case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc); default: break; @@ -357,6 +361,8 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type, prio_tc); ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, @@ -385,6 +391,8 @@ void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map) switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_dcb_read_rtrup2tc_82599(hw, map); break; default: diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index 58a7f5312a96..2707bda37418 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -180,6 +180,7 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: for (j = 0; j < netdev->addr_len; j++, i++) perm_addr[i] = adapter->hw.mac.san_addr[j]; break; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 0ae038b9af90..26fd85e2bca5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -511,6 +511,8 @@ static void ixgbe_get_regs(struct net_device *netdev, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i)); regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i)); break; @@ -622,6 +624,8 @@ static void ixgbe_get_regs(struct net_device *netdev, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_RTTDCS); regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RTRPCS); for (i = 0; i < 8; i++) @@ -1406,6 +1410,8 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: toggle = 0x7FFFF30F; test = reg_test_82599; break; @@ -1644,6 +1650,8 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); @@ -1680,6 +1688,8 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); @@ -1733,12 +1743,16 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg_data); - /* X540 needs to set the MACC.FLU bit to force link up */ - if (adapter->hw.mac.type == ixgbe_mac_X540) { + /* X540 and X550 needs to set the MACC.FLU bit to force link up */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: reg_data = IXGBE_READ_REG(hw, IXGBE_MACC); reg_data |= IXGBE_MACC_FLU; IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data); - } else { + break; + default: if (hw->mac.orig_autoc) { reg_data = hw->mac.orig_autoc | IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_data); @@ -2776,7 +2790,14 @@ static int ixgbe_set_rss_hash_opt(struct ixgbe_adapter *adapter, /* if we changed something we need to update flags */ if (flags2 != adapter->flags2) { struct ixgbe_hw *hw = &adapter->hw; - u32 mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); + u32 mrqc; + unsigned int pf_pool = adapter->num_vfs; + + if ((hw->mac.type >= ixgbe_mac_X550) && + (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + mrqc = IXGBE_READ_REG(hw, IXGBE_PFVFMRQC(pf_pool)); + else + mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); if ((flags2 & UDP_RSS_FLAGS) && !(adapter->flags2 & UDP_RSS_FLAGS)) @@ -2799,7 +2820,11 @@ static int ixgbe_set_rss_hash_opt(struct ixgbe_adapter *adapter, if (flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + if ((hw->mac.type >= ixgbe_mac_X550) && + (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + IXGBE_WRITE_REG(hw, IXGBE_PFVFMRQC(pf_pool), mrqc); + else + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } return 0; @@ -2833,6 +2858,8 @@ static int ixgbe_get_ts_info(struct net_device *dev, struct ixgbe_adapter *adapter = netdev_priv(dev); switch (adapter->hw.mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: case ixgbe_mac_X540: case ixgbe_mac_82599EB: info->so_timestamping = diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index ce40c77381e9..68e1e757ecef 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -126,6 +126,8 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: if (num_tcs > 4) { /* * TCs : TC0/1 TC2/3 TC4-7 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d2df4e3d1032..355d1f79d274 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -835,6 +835,8 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: if (direction == -1) { /* other causes */ msix_vector |= IXGBE_IVAR_ALLOC_VAL; @@ -871,6 +873,8 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: mask = (qmask & 0xFFFFFFFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); mask = (qmask >> 32); @@ -2155,6 +2159,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_set_ivar(adapter, -1, 1, v_idx); break; default: @@ -2264,6 +2270,8 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: /* * set the WDIS bit to not clear the timer bits and cause an * immediate assertion of the interrupt @@ -2467,6 +2475,8 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: mask = (qmask & 0xFFFFFFFF); if (mask) IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); @@ -2493,6 +2503,8 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: mask = (qmask & 0xFFFFFFFF); if (mask) IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); @@ -2525,6 +2537,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, mask |= IXGBE_EIMS_GPI_SDP0; break; case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: mask |= IXGBE_EIMS_TS; break; default: @@ -2536,7 +2550,10 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, case ixgbe_mac_82599EB: mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; + /* fall through */ case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: mask |= IXGBE_EIMS_ECC; mask |= IXGBE_EIMS_MAILBOX; break; @@ -2544,9 +2561,6 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, break; } - if (adapter->hw.mac.type == ixgbe_mac_X540) - mask |= IXGBE_EIMS_TIMESYNC; - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) mask |= IXGBE_EIMS_FLOW_DIR; @@ -2592,6 +2606,8 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: if (eicr & IXGBE_EICR_ECC) { e_info(link, "Received ECC Err, initiating reset\n"); adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; @@ -2811,6 +2827,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data) ixgbe_check_sfp_event(adapter, eicr); /* Fall through */ case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: if (eicr & IXGBE_EICR_ECC) { e_info(link, "Received ECC Err, initiating reset\n"); adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; @@ -2905,6 +2923,8 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); @@ -3534,6 +3554,8 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: case ixgbe_mac_82598EB: /* * For VMDq support of different descriptor types or @@ -3657,6 +3679,8 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i]; @@ -3691,6 +3715,8 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i]; @@ -4112,6 +4138,8 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb) /* Calculate delay value for device */ switch (hw->mac.type) { case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: dv_id = IXGBE_DV_X540(link, tc); break; default: @@ -4170,6 +4198,8 @@ static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb) /* Calculate delay value for device */ switch (hw->mac.type) { case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: dv_id = IXGBE_LOW_DV_X540(tc); break; default: @@ -4606,6 +4636,8 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: default: IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); @@ -4948,10 +4980,12 @@ void ixgbe_down(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH); } - /* Disable the Tx DMA engine on 82599 and X540 */ + /* Disable the Tx DMA engine on 82599 and later MAC */ switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & ~IXGBE_DMATXCTL_TE)); @@ -5071,6 +5105,12 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) if (fwsm & IXGBE_FWSM_TS_ENABLED) adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550: +#ifdef CONFIG_IXGBE_DCA + adapter->flags &= ~IXGBE_FLAG_DCA_CAPABLE; +#endif + break; default: break; } @@ -5086,6 +5126,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) #ifdef CONFIG_IXGBE_DCB switch (hw->mac.type) { case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: adapter->dcb_cfg.num_tcs.pg_tcs = X540_TRAFFIC_CLASS; adapter->dcb_cfg.num_tcs.pfc_tcs = X540_TRAFFIC_CLASS; break; @@ -5675,6 +5717,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: pci_wake_from_d3(pdev, !!wufc); break; default: @@ -5806,6 +5850,8 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); break; @@ -5819,7 +5865,9 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); if ((hw->mac.type == ixgbe_mac_82599EB) || - (hw->mac.type == ixgbe_mac_X540)) { + (hw->mac.type == ixgbe_mac_X540) || + (hw->mac.type == ixgbe_mac_X550) || + (hw->mac.type == ixgbe_mac_X550EM_x)) { hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); /* to clear */ hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); @@ -5842,7 +5890,9 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); break; case ixgbe_mac_X540: - /* OS2BMC stats are X540 only*/ + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + /* OS2BMC stats are X540 and later */ hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC); hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC); hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC); @@ -6110,6 +6160,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) } break; case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: case ixgbe_mac_82599EB: { u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); @@ -6221,6 +6273,10 @@ static bool ixgbe_vf_tx_pending(struct ixgbe_adapter *adapter) if (!adapter->num_vfs) return false; + /* resetting the PF is only needed for MAC before X550 */ + if (hw->mac.type >= ixgbe_mac_X550) + return false; + for (i = 0; i < adapter->num_vfs; i++) { for (j = 0; j < q_per_pool; j++) { u32 h, t; @@ -6430,11 +6486,11 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) ciaa = (vf << 16) | 0x80000000; /* 32 bit read so align, we really want status at offset 6 */ ciaa |= PCI_COMMAND; - IXGBE_WRITE_REG(hw, IXGBE_CIAA_82599, ciaa); - ciad = IXGBE_READ_REG(hw, IXGBE_CIAD_82599); + IXGBE_WRITE_REG(hw, IXGBE_CIAA_BY_MAC(hw), ciaa); + ciad = IXGBE_READ_REG(hw, IXGBE_CIAD_BY_MAC(hw)); ciaa &= 0x7FFFFFFF; /* disable debug mode asap after reading data */ - IXGBE_WRITE_REG(hw, IXGBE_CIAA_82599, ciaa); + IXGBE_WRITE_REG(hw, IXGBE_CIAA_BY_MAC(hw), ciaa); /* Get the upper 16 bits which will be the PCI status reg */ ciad >>= 16; if (ciad & PCI_STATUS_REC_MASTER_ABORT) { @@ -6442,11 +6498,11 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) /* Issue VFLR */ ciaa = (vf << 16) | 0x80000000; ciaa |= 0xA8; - IXGBE_WRITE_REG(hw, IXGBE_CIAA_82599, ciaa); + IXGBE_WRITE_REG(hw, IXGBE_CIAA_BY_MAC(hw), ciaa); ciad = 0x00008000; /* VFLR */ - IXGBE_WRITE_REG(hw, IXGBE_CIAD_82599, ciad); + IXGBE_WRITE_REG(hw, IXGBE_CIAD_BY_MAC(hw), ciad); ciaa &= 0x7FFFFFFF; - IXGBE_WRITE_REG(hw, IXGBE_CIAA_82599, ciaa); + IXGBE_WRITE_REG(hw, IXGBE_CIAA_BY_MAC(hw), ciaa); } } } @@ -8098,6 +8154,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); break; default: @@ -8161,6 +8219,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: netdev->features |= NETIF_F_SCTP_CSUM; netdev->hw_features |= NETIF_F_SCTP_CSUM | NETIF_F_NTUPLE; @@ -8514,6 +8574,12 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, case ixgbe_mac_X540: device_id = IXGBE_X540_VF_DEVICE_ID; break; + case ixgbe_mac_X550: + device_id = IXGBE_DEV_ID_X550_VF; + break; + case ixgbe_mac_X550EM_x: + device_id = IXGBE_DEV_ID_X550EM_X_VF; + break; default: device_id = 0; break; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c index cc8f0128286c..9993a471d668 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c @@ -305,6 +305,8 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); break; case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); break; default: @@ -426,6 +428,8 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) struct ixgbe_mbx_info *mbx = &hw->mbx; if (hw->mac.type != ixgbe_mac_82599EB && + hw->mac.type != ixgbe_mac_X550 && + hw->mac.type != ixgbe_mac_X550EM_x && hw->mac.type != ixgbe_mac_X540) return; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index d47b19f27c35..dc97c03134ec 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -43,7 +43,7 @@ static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data); static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); -static bool ixgbe_get_i2c_data(u32 *i2cctl); +static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl); static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); @@ -576,6 +576,10 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, *speed |= IXGBE_LINK_SPEED_100_FULL; } + /* Internal PHY does not support 100 Mbps */ + if (hw->mac.type == ixgbe_mac_X550EM_x) + *speed &= ~IXGBE_LINK_SPEED_100_FULL; + return status; } @@ -632,10 +636,12 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, * @hw: pointer to hardware structure * * Restart autonegotiation and PHY and waits for completion. + * This function always returns success, this is nessary since + * it is called via a function pointer that could call other + * functions that could return an error. **/ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) { - s32 status; u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; bool autoneg = false; ixgbe_link_speed speed; @@ -701,7 +707,7 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg); - return status; + return 0; } /** @@ -1612,7 +1618,7 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, **/ static void ixgbe_i2c_start(struct ixgbe_hw *hw) { - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); /* Start condition must begin with data and clock high */ ixgbe_set_i2c_data(hw, &i2cctl, 1); @@ -1641,7 +1647,7 @@ static void ixgbe_i2c_start(struct ixgbe_hw *hw) **/ static void ixgbe_i2c_stop(struct ixgbe_hw *hw) { - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); /* Stop condition must begin with data low and clock high */ ixgbe_set_i2c_data(hw, &i2cctl, 0); @@ -1699,9 +1705,9 @@ static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data) } /* Release SDA line (set high) */ - i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); - i2cctl |= IXGBE_I2C_DATA_OUT; - IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl); + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), i2cctl); IXGBE_WRITE_FLUSH(hw); return status; @@ -1717,7 +1723,7 @@ static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) { s32 status = 0; u32 i = 0; - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); u32 timeout = 10; bool ack = true; @@ -1730,8 +1736,8 @@ static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) /* Poll for ACK. Note that ACK in I2C spec is * transition from 1 to 0 */ for (i = 0; i < timeout; i++) { - i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); - ack = ixgbe_get_i2c_data(&i2cctl); + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + ack = ixgbe_get_i2c_data(hw, &i2cctl); udelay(1); if (ack == 0) @@ -1760,15 +1766,15 @@ static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) **/ static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) { - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); ixgbe_raise_i2c_clk(hw, &i2cctl); /* Minimum high period of clock is 4us */ udelay(IXGBE_I2C_T_HIGH); - i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); - *data = ixgbe_get_i2c_data(&i2cctl); + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + *data = ixgbe_get_i2c_data(hw, &i2cctl); ixgbe_lower_i2c_clk(hw, &i2cctl); @@ -1788,7 +1794,7 @@ static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) { s32 status; - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); status = ixgbe_set_i2c_data(hw, &i2cctl, data); if (status == 0) { @@ -1824,14 +1830,14 @@ static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) u32 i2cctl_r = 0; for (i = 0; i < timeout; i++) { - *i2cctl |= IXGBE_I2C_CLK_OUT; - IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + *i2cctl |= IXGBE_I2C_CLK_OUT_BY_MAC(hw); + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); IXGBE_WRITE_FLUSH(hw); /* SCL rise time (1000ns) */ udelay(IXGBE_I2C_T_RISE); - i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL); - if (i2cctl_r & IXGBE_I2C_CLK_IN) + i2cctl_r = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + if (i2cctl_r & IXGBE_I2C_CLK_IN_BY_MAC(hw)) break; } } @@ -1846,9 +1852,9 @@ static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) { - *i2cctl &= ~IXGBE_I2C_CLK_OUT; + *i2cctl &= ~IXGBE_I2C_CLK_OUT_BY_MAC(hw); - IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); IXGBE_WRITE_FLUSH(hw); /* SCL fall time (300ns) */ @@ -1866,19 +1872,19 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) { if (data) - *i2cctl |= IXGBE_I2C_DATA_OUT; + *i2cctl |= IXGBE_I2C_DATA_OUT_BY_MAC(hw); else - *i2cctl &= ~IXGBE_I2C_DATA_OUT; + *i2cctl &= ~IXGBE_I2C_DATA_OUT_BY_MAC(hw); - IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL_BY_MAC(hw), *i2cctl); IXGBE_WRITE_FLUSH(hw); /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); /* Verify data was set correctly */ - *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); - if (data != ixgbe_get_i2c_data(i2cctl)) { + *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); + if (data != ixgbe_get_i2c_data(hw, i2cctl)) { hw_dbg(hw, "Error - I2C data was not set to %X.\n", data); return IXGBE_ERR_I2C; } @@ -1893,9 +1899,9 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) * * Returns the I2C data bit value **/ -static bool ixgbe_get_i2c_data(u32 *i2cctl) +static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl) { - if (*i2cctl & IXGBE_I2C_DATA_IN) + if (*i2cctl & IXGBE_I2C_DATA_IN_BY_MAC(hw)) return true; return false; } @@ -1909,7 +1915,7 @@ static bool ixgbe_get_i2c_data(u32 *i2cctl) **/ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) { - u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL_BY_MAC(hw)); u32 i; ixgbe_i2c_start(hw); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 0c25df506247..04eee7c7b653 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1109,6 +1109,12 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf, if (adapter->vfinfo[vf].spoofchk_enabled) hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); adapter->vfinfo[vf].vlan_count++; + + /* enable hide vlan on X550 */ + if (hw->mac.type >= ixgbe_mac_X550) + ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE | + IXGBE_QDE_HIDE_VLAN); + adapter->vfinfo[vf].pf_vlan = vlan; adapter->vfinfo[vf].pf_qos = qos; dev_info(&adapter->pdev->dev, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index dfd55d83bc03..64de20d1de56 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -77,6 +77,8 @@ /* VF Device IDs */ #define IXGBE_DEV_ID_82599_VF 0x10ED #define IXGBE_DEV_ID_X540_VF 0x1515 +#define IXGBE_DEV_ID_X550_VF 0x1565 +#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8 /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -84,7 +86,8 @@ #define IXGBE_CTRL_EXT 0x00018 #define IXGBE_ESDP 0x00020 #define IXGBE_EODSDP 0x00028 -#define IXGBE_I2CCTL 0x00028 +#define IXGBE_I2CCTL_BY_MAC(_hw)((((_hw)->mac.type >= ixgbe_mac_X550) ? \ + 0x15F5C : 0x00028)) #define IXGBE_LEDCTL 0x00200 #define IXGBE_FRTIMER 0x00048 #define IXGBE_TCPTIMER 0x0004C @@ -112,10 +115,14 @@ #define IXGBE_VPDDIAG1 0x10208 /* I2CCTL Bit Masks */ -#define IXGBE_I2C_CLK_IN 0x00000001 -#define IXGBE_I2C_CLK_OUT 0x00000002 -#define IXGBE_I2C_DATA_IN 0x00000004 -#define IXGBE_I2C_DATA_OUT 0x00000008 +#define IXGBE_I2C_CLK_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \ + 0x00004000 : 0x00000001) +#define IXGBE_I2C_CLK_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \ + 0x00000200 : 0x00000002) +#define IXGBE_I2C_DATA_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \ + 0x00001000 : 0x00000004) +#define IXGBE_I2C_DATA_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \ + 0x00000400 : 0x00000008) #define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT 500 #define IXGBE_I2C_THERMAL_SENSOR_ADDR 0xF8 @@ -292,6 +299,14 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ +/* Registers for setting up RSS on X550 with SRIOV + * _p - pool number (0..63) + * _i - index (0..10 for PFVFRSSRK, 0..15 for PFVFRETA) + */ +#define IXGBE_PFVFMRQC(_p) (0x03400 + ((_p) * 4)) +#define IXGBE_PFVFRSSRK(_i, _p) (0x018000 + ((_i) * 4) + ((_p) * 0x40)) +#define IXGBE_PFVFRETA(_i, _p) (0x019000 + ((_i) * 4) + ((_p) * 0x40)) + /* Flow Director registers */ #define IXGBE_FDIRCTRL 0x0EE00 #define IXGBE_FDIRHKEY 0x0EE68 @@ -798,6 +813,12 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_PBACLR_82599 0x11068 #define IXGBE_CIAA_82599 0x11088 #define IXGBE_CIAD_82599 0x1108C +#define IXGBE_CIAA_X550 0x11508 +#define IXGBE_CIAD_X550 0x11510 +#define IXGBE_CIAA_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \ + IXGBE_CIAA_X550 : IXGBE_CIAA_82599)) +#define IXGBE_CIAD_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \ + IXGBE_CIAD_X550 : IXGBE_CIAD_82599)) #define IXGBE_PICAUSE 0x110B0 #define IXGBE_PIENA 0x110B8 #define IXGBE_CDQ_MBR_82599 0x110B4 @@ -1632,6 +1653,7 @@ enum { #define IXGBE_LINKS_TL_FAULT 0x00001000 #define IXGBE_LINKS_SIGNAL 0x00000F00 +#define IXGBE_LINKS_SPEED_NON_STD 0x08000000 #define IXGBE_LINKS_SPEED_82599 0x30000000 #define IXGBE_LINKS_SPEED_10G_82599 0x30000000 #define IXGBE_LINKS_SPEED_1G_82599 0x20000000 @@ -2000,6 +2022,7 @@ enum { /* Queue Drop Enable */ #define IXGBE_QDE_ENABLE 0x00000001 +#define IXGBE_QDE_HIDE_VLAN 0x00000002 #define IXGBE_QDE_IDX_MASK 0x00007F00 #define IXGBE_QDE_IDX_SHIFT 8 #define IXGBE_QDE_WRITE 0x00010000 @@ -2437,10 +2460,12 @@ struct ixgbe_adv_tx_context_desc { typedef u32 ixgbe_autoneg_advertised; /* Link speed */ typedef u32 ixgbe_link_speed; -#define IXGBE_LINK_SPEED_UNKNOWN 0 -#define IXGBE_LINK_SPEED_100_FULL 0x0008 -#define IXGBE_LINK_SPEED_1GB_FULL 0x0020 -#define IXGBE_LINK_SPEED_10GB_FULL 0x0080 +#define IXGBE_LINK_SPEED_UNKNOWN 0 +#define IXGBE_LINK_SPEED_100_FULL 0x0008 +#define IXGBE_LINK_SPEED_1GB_FULL 0x0020 +#define IXGBE_LINK_SPEED_2_5GB_FULL 0x0400 +#define IXGBE_LINK_SPEED_5GB_FULL 0x0800 +#define IXGBE_LINK_SPEED_10GB_FULL 0x0080 #define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \ IXGBE_LINK_SPEED_10GB_FULL) #define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \ @@ -2588,6 +2613,8 @@ enum ixgbe_mac_type { ixgbe_mac_82598EB, ixgbe_mac_82599EB, ixgbe_mac_X540, + ixgbe_mac_X550, + ixgbe_mac_X550EM_x, ixgbe_num_macs }; -- GitLab From d1b849b9e994ef5a283efc288fc7da6a2471219b Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Sun, 9 Nov 2014 06:42:57 +0000 Subject: [PATCH 4261/9457] ixgbe: add helper function for setting RSS key in preparation of X550 Split off the setting of the RSS key into its own function. This will help when we add support for X550 which can have different RSS keys per pool. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 355d1f79d274..a5ca877eac1a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3210,14 +3210,10 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl); } -static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) +static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed) { struct ixgbe_hw *hw = &adapter->hw; - static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, - 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, - 0x6A3E67EA, 0x14364D17, 0x3BED200D}; - u32 mrqc = 0, reta = 0; - u32 rxcsum; + u32 reta = 0; int i, j; u16 rss_i = adapter->ring_feature[RING_F_RSS].indices; @@ -3243,6 +3239,16 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) if ((i & 3) == 3) IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); } +} + +static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, + 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, + 0x6A3E67EA, 0x14364D17, 0x3BED200D}; + u32 mrqc = 0, rss_field = 0; + u32 rxcsum; /* Disable indicating checksum in descriptor, enables RSS hash */ rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); @@ -3275,16 +3281,18 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) } /* Perform hash on these packet types */ - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 | - IXGBE_MRQC_RSS_FIELD_IPV4_TCP | - IXGBE_MRQC_RSS_FIELD_IPV6 | - IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + rss_field |= IXGBE_MRQC_RSS_FIELD_IPV4 | + IXGBE_MRQC_RSS_FIELD_IPV4_TCP | + IXGBE_MRQC_RSS_FIELD_IPV6 | + IXGBE_MRQC_RSS_FIELD_IPV6_TCP; if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV4_UDP) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; + rss_field |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP; if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; + ixgbe_setup_reta(adapter, seed); + mrqc |= rss_field; IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } -- GitLab From 93746e70be83a3f113134a16065957b324af50f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Thu, 6 Nov 2014 11:40:29 +0800 Subject: [PATCH 4262/9457] clk: sunxi: unify APB1 clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit unifies the APB1 mux with the APB1 clock, using the new factors infrastructure. Signed-off-by: Emilio López [wens@csie.org: Add mux mask bits] Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/clock/sunxi.txt | 1 - drivers/clk/sunxi/clk-sunxi.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 0455cb9caa97..6ddcf6e10eb8 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -45,7 +45,6 @@ Required properties: "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 - "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing "allwinner,sun4i-a10-apb1-gates-clk" - for the APB1 gates on A10 "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 20f47c68a946..4133e278212b 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -507,6 +507,8 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { }; static const struct factors_data sun4i_apb1_data __initconst = { + .mux = 24, + .muxmask = BIT(1) | BIT(0), .table = &sun4i_apb1_config, .getter = sun4i_get_apb1_factors, }; @@ -545,10 +547,6 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = { .shift = 12, }; -static const struct mux_data sun4i_apb1_mux_data __initconst = { - .shift = 24, -}; - static void __init sunxi_mux_clk_setup(struct device_node *node, struct mux_data *data) { @@ -1109,7 +1107,6 @@ static const struct of_device_id clk_divs_match[] __initconst = { /* Matches for mux clocks */ static const struct of_device_id clk_mux_match[] __initconst = { {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, - {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, {} }; -- GitLab From dd0a6fe2bc3055cd61e369f97982c88183b1f0a0 Mon Sep 17 00:00:00 2001 From: "nibble.max" Date: Sat, 8 Nov 2014 05:34:30 -0300 Subject: [PATCH 4263/9457] [media] dvb-usb-dvbsky: fix i2c adapter for sp2 device It is wrong that sp2 device uses the i2c adapter from m88ds3103 return. sp2 device sits on the same i2c bus with m88ds3103, not behind m88ds3103. Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvbsky.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index c67a118ef219..8be8447fb2be 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -479,7 +479,7 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) info.addr = 0x40; info.platform_data = &sp2_config; request_module("sp2"); - client_ci = i2c_new_device(i2c_adapter, &info); + client_ci = i2c_new_device(&d->i2c_adap, &info); if (client_ci == NULL || client_ci->dev.driver == NULL) { ret = -ENODEV; goto fail_ci_device; -- GitLab From b93b1fe3b5323d5418b151dd620c4eb80270f683 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Tue, 21 Oct 2014 15:01:50 +0200 Subject: [PATCH 4264/9457] iwlwifi: mvm: fix init_dbg flow to work as expected Even if running the driver with param init_dbg=1 - on INIT image error - iwl_trans_stop_device() was still called. This patch fixes that and calls iwl_trans_stop_device() on INIT image failure only if init_dbg=0. Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index bd52ecfabedb..8c5bdf9360f9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -524,7 +524,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mutex_lock(&mvm->mutex); err = iwl_run_init_mvm_ucode(mvm, true); - iwl_trans_stop_device(trans); + if (!err || !iwlmvm_mod_params.init_dbg) + iwl_trans_stop_device(trans); mutex_unlock(&mvm->mutex); /* returns 0 if successful, 1 if success but in rfkill */ if (err < 0 && !iwlmvm_mod_params.init_dbg) { -- GitLab From 1507fb757a0a706a9aae002d45ea7c12b076a482 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 5 Nov 2014 11:00:41 +0200 Subject: [PATCH 4265/9457] iwlwifi: mvm: rs: fix a WARNING in case of STBC and VHT This was taken care of in case we're doing STBC with HT but not when working with VHT. Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 6775100a75e9..cb18b609255d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -816,7 +816,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, if (nss == 1) { rate->type = LQ_VHT_SISO; - WARN_ON_ONCE(num_of_ant != 1); + WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); } else if (nss == 2) { rate->type = LQ_VHT_MIMO2; WARN_ON_ONCE(num_of_ant != 2); -- GitLab From f4cf8680dfa42c80476a9cc5b90f933b12cf6d29 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 4 Nov 2014 16:57:06 +0200 Subject: [PATCH 4266/9457] iwlwifi: mvm/trans: abort d0i3_enter in case of held ref Other contexts might call iwl_mvm_ref_sync() right before we set IWL_MVM_STATUS_IN_D0I3, and then assume the fw/bus is not in d0i3 state. However, since we currently don't check for held references in the d0i3_enter flow, we might enter d0i3 although there is an active reference. Solve it by aborting the d0i3 enter flow if there is an active reference. Since users are assumed to use iwl_mvm_ref_sync, which takes a ref before checking the flag, we don't need further locking. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 3 ++- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/iwlwifi/mvm/ops.c | 12 ++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index b6d666ee8359..17de6d46222a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -138,7 +138,8 @@ struct iwl_cfg; * @nic_config: configure NIC, called before firmware is started. * May sleep * @wimax_active: invoked when WiMax becomes active. May sleep - * @enter_d0i3: configure the fw to enter d0i3. May sleep. + * @enter_d0i3: configure the fw to enter d0i3. return 1 to indicate d0i3 + * entrance is aborted (e.g. due to held reference). May sleep. * @exit_d0i3: configure the fw to exit d0i3. May sleep. */ struct iwl_op_mode_ops { diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3276b31898da..4f9f77f1371d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -254,6 +254,26 @@ static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm, spin_unlock_bh(&mvm->refs_lock); } +bool iwl_mvm_ref_taken(struct iwl_mvm *mvm) +{ + int i; + bool taken = false; + + if (!iwl_mvm_is_d0i3_supported(mvm)) + return true; + + spin_lock_bh(&mvm->refs_lock); + for (i = 0; i < IWL_MVM_REF_COUNT; i++) { + if (mvm->refs[i]) { + taken = true; + break; + } + } + spin_unlock_bh(&mvm->refs_lock); + + return taken; +} + int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) { iwl_mvm_ref(mvm, ref_type); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 1fc94e1db015..c89ac95c3288 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1070,6 +1070,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); +bool iwl_mvm_ref_taken(struct iwl_mvm *mvm); void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 8c5bdf9360f9..be3dd4f5c7e1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -1041,6 +1041,18 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); synchronize_net(); + /* + * iwl_mvm_ref_sync takes a reference before checking the flag. + * so by checking there is no held reference we prevent a state + * in which iwl_mvm_ref_sync continues successfully while we + * configure the firmware to enter d0i3 + */ + if (iwl_mvm_ref_taken(mvm)) { + IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n"); + clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); + return 1; + } + ieee80211_iterate_active_interfaces_atomic(mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_enter_d0i3_iterator, -- GitLab From 26a2cc016f59839afb665ab29c7a40b91bcedf42 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 5 Nov 2014 12:03:59 +0200 Subject: [PATCH 4267/9457] iwlwifi: mvm: rs: fix getting stuck in a test window When Tx STBC is being used and RS switches to a search column using the alternate antenna from the current one there is a problem with using rs_rate_match to figure out which table is the active and which one is the search one. The root cause is because in STBC the antenna mask in the ucode rate is set to ANT_AB and in this specific scenario it matches both the active and search table (e.g. SISO_ANT_A and SISO_ANT_B). This leads to tx stats being updated in the wrong table and later on to getting stuck in a test window and not moving on to other columns. If this happens during the initial search cycle we never end it and therefore never enable aggregation which leads naturally to severe througput degradation. Fix it by deducing which table is which by knowing whether we're in a search or not like it's being done in rs_rate_scale_perform Signed-off-by: Eyal Shapira Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index cb18b609255d..bbd2f9b90688 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -506,7 +506,7 @@ static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, const char *prefix) { IWL_DEBUG_RATE(mvm, - "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d STBC %d\n", + "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d STBC: %d\n", prefix, rs_pretty_lq_type(rate->type), rate->index, rs_pretty_ant(rate->ant), rate->bw, rate->sgi, rate->ldpc, rate->stbc); @@ -1155,16 +1155,15 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, /* Rate did match, so reset the missed_rate_counter */ lq_sta->missed_rate_counter = 0; - /* Figure out if rate scale algorithm is in active or search table */ - if (rs_rate_match(&rate, - &(lq_sta->lq_info[lq_sta->active_tbl].rate))) { + if (!lq_sta->search_better_tbl) { curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); - } else if (rs_rate_match(&rate, - &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) { + } else { curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); - } else { + } + + if (WARN_ON_ONCE(!rs_rate_match(&rate, &curr_tbl->rate))) { IWL_DEBUG_RATE(mvm, "Neither active nor search matches tx rate\n"); tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); -- GitLab From 219fb66b49fac64bb87f030c133d2d32927b6fc4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 30 Oct 2014 11:59:40 +0200 Subject: [PATCH 4268/9457] iwlwifi: mvm: rs - don't use the shared antenna when BT load is high When we need only one antenna, we should refrain from using the antenna that is shared with BT if BT load is high. Fix this. Reviewed-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 6 ++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/rs.c | 16 ++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 508c81359e41..a3bfda45d9e6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -1137,6 +1137,22 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, return lut_type != BT_COEX_LOOSE_LUT; } +bool iwl_mvm_bt_coex_is_ant_avail(struct iwl_mvm *mvm, u8 ant) +{ + /* there is no other antenna, shared antenna is always available */ + if (mvm->cfg->bt_shared_single_ant) + return true; + + if (ant & mvm->cfg->non_shared_ant) + return true; + + if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) + return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm); + + return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < + BT_HIGH_TRAFFIC; +} + bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm) { /* there is no other antenna, shared antenna is always available */ diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index b571e1b0550c..cda5111bb775 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -1156,6 +1156,12 @@ bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm, return lut_type != BT_COEX_LOOSE_LUT; } +bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant) +{ + u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading); + return ag < BT_HIGH_TRAFFIC; +} + bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm) { u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index c89ac95c3288..105a76b75a53 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1086,12 +1086,14 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm, struct ieee80211_sta *sta); bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, struct ieee80211_sta *sta); +bool iwl_mvm_bt_coex_is_ant_avail(struct iwl_mvm *mvm, u8 ant); bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm); bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, enum ieee80211_band band); u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, struct ieee80211_tx_info *info, u8 ac); +bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant); bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm); void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm); int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index bbd2f9b90688..c05f5a509a5d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -158,6 +158,12 @@ struct rs_tx_column { allow_column_func_t checks[MAX_COLUMN_CHECKS]; }; +static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + struct iwl_scale_tbl_info *tbl) +{ + return iwl_mvm_bt_coex_is_ant_avail(mvm, tbl->rate.ant); +} + static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_scale_tbl_info *tbl) { @@ -218,6 +224,9 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_INVALID, RS_COLUMN_INVALID, }, + .checks = { + rs_ant_allow, + }, }, [RS_COLUMN_LEGACY_ANT_B] = { .mode = RS_LEGACY, @@ -231,6 +240,9 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_INVALID, RS_COLUMN_INVALID, }, + .checks = { + rs_ant_allow, + }, }, [RS_COLUMN_SISO_ANT_A] = { .mode = RS_SISO, @@ -246,6 +258,7 @@ static const struct rs_tx_column rs_tx_columns[] = { }, .checks = { rs_siso_allow, + rs_ant_allow, }, }, [RS_COLUMN_SISO_ANT_B] = { @@ -262,6 +275,7 @@ static const struct rs_tx_column rs_tx_columns[] = { }, .checks = { rs_siso_allow, + rs_ant_allow, }, }, [RS_COLUMN_SISO_ANT_A_SGI] = { @@ -279,6 +293,7 @@ static const struct rs_tx_column rs_tx_columns[] = { }, .checks = { rs_siso_allow, + rs_ant_allow, rs_sgi_allow, }, }, @@ -297,6 +312,7 @@ static const struct rs_tx_column rs_tx_columns[] = { }, .checks = { rs_siso_allow, + rs_ant_allow, rs_sgi_allow, }, }, -- GitLab From 58629d9d6a2d67a1aa736be898ab00250701716e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 6 Nov 2014 09:40:50 +0100 Subject: [PATCH 4269/9457] iwlwifi: mvm: don't capture firmware coredump for D3->D0 reconfig The code to capture firmware errors works during the reconfiguration phase after an error. As the D3->D0 transition uses the same flow to get the D0 image reconfigured, this triggered and caused a firmware coredump to be collected. This in turn, if it isn't picked up by userspace, can cause module unloading to fail, which is how the bug was detected. To fix this issue, introduce a new status flag (D3_RECONFIG) and use it to detect that during reconfiguration no coredump should be taken and reported. Reported-by: Avi Kraif Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 1 + drivers/net/wireless/iwlwifi/mvm/mac80211.c | 7 ++++++- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 3bbb511b0b38..b61075b567ad 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1651,6 +1651,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* return 1 to reconfigure the device */ set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); + set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); return 1; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 4f9f77f1371d..ed2c219cf543 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -839,7 +839,12 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) { - iwl_mvm_fw_error_dump(mvm); + /* clear the D3 reconfig, we only need it to avoid dumping a + * firmware coredump on reconfiguration, we shouldn't do that + * on D3->D0 transition + */ + if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) + iwl_mvm_fw_error_dump(mvm); iwl_trans_stop_device(mvm->trans); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 105a76b75a53..e56abdda0e7d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -750,6 +750,7 @@ enum iwl_mvm_status { IWL_MVM_STATUS_IN_HW_RESTART, IWL_MVM_STATUS_IN_D0I3, IWL_MVM_STATUS_ROC_AUX_RUNNING, + IWL_MVM_STATUS_D3_RECONFIG, }; static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) -- GitLab From fd1f75506d96481e61e86947a1aef85c130f714e Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 4 Nov 2014 16:17:46 +0200 Subject: [PATCH 4270/9457] iwlwifi: mvm: refactor temperature notification handling Refactor the temperature handling code so that it is easier to reuse it with other notification flows. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/iwlwifi/mvm/rx.c | 23 +----------- drivers/net/wireless/iwlwifi/mvm/tt.c | 51 ++++++++++++++++++++------ 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e56abdda0e7d..9ac2d4c59bc6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1210,6 +1210,7 @@ bool iwl_mvm_is_idle(struct iwl_mvm *mvm); /* Thermal management and CT-kill */ void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); +void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); void iwl_mvm_tt_handler(struct iwl_mvm *mvm); void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff); void iwl_mvm_tt_exit(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 3cf40f3f58ec..93d5b692cf92 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -500,29 +500,8 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, .mvm = mvm, }; - /* - * set temperature debug enabled - ignore FW temperature updates - * and use the user set temperature. - */ - if (mvm->temperature_test) { - if (mvm->temperature < le32_to_cpu(common->temperature)) - IWL_DEBUG_TEMP(mvm, - "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n", - mvm->temperature, - le32_to_cpu(common->temperature)); - /* - * skip iwl_mvm_tt_handler since we are in - * temperature debug mode and we are ignoring - * the new temperature value - */ - goto update; - } + iwl_mvm_tt_temp_changed(mvm, le32_to_cpu(common->temperature)); - if (mvm->temperature != le32_to_cpu(common->temperature)) { - mvm->temperature = le32_to_cpu(common->temperature); - iwl_mvm_tt_handler(mvm); - } -update: iwl_mvm_update_rx_statistics(mvm, stats); ieee80211_iterate_active_interfaces(mvm->hw, diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index d4f2c29025c7..35acf003cce8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c @@ -95,29 +95,58 @@ static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) iwl_mvm_set_hw_ctkill_state(mvm, false); } -static bool iwl_mvm_temp_notif(struct iwl_notif_wait_data *notif_wait, - struct iwl_rx_packet *pkt, void *data) +void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp) +{ + /* ignore the notification if we are in test mode */ + if (mvm->temperature_test) + return; + + if (mvm->temperature == temp) + return; + + mvm->temperature = temp; + iwl_mvm_tt_handler(mvm); +} + +static int iwl_mvm_temp_notif_parse(struct iwl_mvm *mvm, + struct iwl_rx_packet *pkt) { - struct iwl_mvm *mvm = - container_of(notif_wait, struct iwl_mvm, notif_wait); - int *temp = data; struct iwl_dts_measurement_notif *notif; int len = iwl_rx_packet_payload_len(pkt); + int temp; if (WARN_ON_ONCE(len != sizeof(*notif))) { IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n"); - return true; + return -EINVAL; } notif = (void *)pkt->data; - *temp = le32_to_cpu(notif->temp); + temp = le32_to_cpu(notif->temp); /* shouldn't be negative, but since it's s32, make sure it isn't */ - if (WARN_ON_ONCE(*temp < 0)) - *temp = 0; + if (WARN_ON_ONCE(temp < 0)) + temp = 0; + + IWL_DEBUG_TEMP(mvm, "DTS_MEASUREMENT_NOTIFICATION - %d\n", temp); + + return temp; +} + +static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt, void *data) +{ + struct iwl_mvm *mvm = + container_of(notif_wait, struct iwl_mvm, notif_wait); + int *temp = data; + int ret; + + ret = iwl_mvm_temp_notif_parse(mvm, pkt); + if (ret < 0) + return true; + + *temp = ret; - IWL_DEBUG_TEMP(mvm, "DTS_MEASUREMENT_NOTIFICATION - %d\n", *temp); return true; } @@ -141,7 +170,7 @@ int iwl_mvm_get_temp(struct iwl_mvm *mvm) iwl_init_notification_wait(&mvm->notif_wait, &wait_temp_notif, temp_notif, ARRAY_SIZE(temp_notif), - iwl_mvm_temp_notif, &temp); + iwl_mvm_temp_notif_wait, &temp); ret = iwl_mvm_get_temp_cmd(mvm); if (ret) { -- GitLab From ea9af24d03a905143544ba383e23c731ba3bc5bd Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 6 Nov 2014 10:34:49 +0200 Subject: [PATCH 4271/9457] iwlwifi: mvm: handle unsolicited DTS_MEASUREMENT_NOTIFICATIONs Currently, the firmware only sends temperature notificaitions inside RX statistics notifications, which are tied to beacon filtering. This is a problem because beacon filtering is not used with vifs that don't receive beacons (e.g. P2P GO and AP), so the driver doesn't receive temperature notifications in those cases. To solve that, the firmware will be changed so that it sends DTS_MEASUREMENT_NOTIFICATIONs, independently from the beacon filtering flows. To support that, the driver needs to also handle unsolicited DTS_MEASUREMENT_NOTIFICATIONs, that are not triggered by DTS_TRIGGER_CMD_FLAGS_TEMP requests. This change is backwards compatible and will simply not be used with firmware versions that do not send the notifications. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 ++ drivers/net/wireless/iwlwifi/mvm/tt.c | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 9ac2d4c59bc6..7d2c5289464b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1211,6 +1211,9 @@ bool iwl_mvm_is_idle(struct iwl_mvm *mvm); /* Thermal management and CT-kill */ void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); +int iwl_mvm_temp_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); void iwl_mvm_tt_handler(struct iwl_mvm *mvm); void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff); void iwl_mvm_tt_exit(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index be3dd4f5c7e1..737aac32a73d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -254,6 +254,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION, iwl_mvm_power_uapsd_misbehaving_ap_notif, false), + RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true), + }; #undef RX_HANDLER #define CMD(x) [x] = #x diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index 35acf003cce8..2b1e61fac34a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c @@ -150,6 +150,26 @@ static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait, return true; } +int iwl_mvm_temp_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + int temp; + + /* the notification is handled synchronously in ctkill, so skip here */ + if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) + return 0; + + temp = iwl_mvm_temp_notif_parse(mvm, pkt); + if (temp < 0) + return 0; + + iwl_mvm_tt_temp_changed(mvm, temp); + + return 0; +} + static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) { struct iwl_dts_measurement_cmd cmd = { -- GitLab From 01e58a281e6f0184e54af19a74de9a4012eeab25 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 27 Oct 2014 09:14:32 +0200 Subject: [PATCH 4272/9457] iwlwifi: pcie: introduce delay when waking up the device In some rare cases, the firmware can put the device to sleep after the driver requested the access. This is because the access request can take a short time to be propagated to the firmware. If that happens, the driver may think that it has access since the firmware hasn't put the device to sleep yet, but right after the driver's check, the firmware might put the device to sleep. Warn when this happens by allowing the firmware to finish the "put the device sleep" flow so that the driver will not get access to the device. This will make the issue visible. This still doesn't fix the race, but at least it makes it more visible. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 5 +++++ drivers/net/wireless/iwlwifi/pcie/tx.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 40a290603ead..d8727491fee5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1031,6 +1031,9 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) + udelay(2); + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, @@ -1233,6 +1236,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, /* this bit wakes up the NIC */ __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) + udelay(2); /* * These bits say the device is running, and should keep running for diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index eb8e2984c5e9..4a4104eda9b8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1431,6 +1431,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, trans_pcie->cmd_in_flight = true; __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) + udelay(2); + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | -- GitLab From 6a08f5144c871ea6ea1614f1bd742eb450d9325a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 4 Nov 2014 20:16:00 +0200 Subject: [PATCH 4273/9457] iwlwifi: pcie: newer platform needs a OS alive indication This is fully backward compatible with older platforms. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-csr.h | 4 ++++ drivers/net/wireless/iwlwifi/pcie/trans.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 3f6f015285e5..99657172ab85 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -129,6 +129,8 @@ #define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) #define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) +#define CSR_MBOX_SET_REG (CSR_BASE + 0x88) + #define CSR_LED_REG (CSR_BASE+0x094) #define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) #define CSR_MAC_SHADOW_REG_CTRL (CSR_BASE+0x0A8) /* 6000 and up */ @@ -184,6 +186,8 @@ #define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */ #define CSR_HW_IF_CONFIG_REG_PERSIST_MODE (0x40000000) /* PERSISTENCE */ +#define CSR_MBOX_SET_REG_OS_ALIVE BIT(5) + #define CSR_INT_PERIODIC_DIS (0x00) /* disable periodic int*/ #define CSR_INT_PERIODIC_ENA (0xFF) /* 255*32 usec ~ 8 msec*/ diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d8727491fee5..12cb427b742a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -512,6 +512,9 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); + if (ret >= 0) + iwl_set_bit(trans, CSR_MBOX_SET_REG, CSR_MBOX_SET_REG_OS_ALIVE); + IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret < 0 ? " not" : ""); return ret; } -- GitLab From caf1578aefe7ebbc22376737e91ffa29ac14a33f Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 9 Nov 2014 15:25:33 +0200 Subject: [PATCH 4274/9457] iwlwifi: mvm: wake up d0i3_exit_waitq when aborting d0i3 When aborting d0i3 due to taken refs, other threads might already wait on d0i3_exit_waitq for IWL_MVM_STATUS_IN_D0I3 to get cleared (it's somewhat likely, as synchronize_rcu() might take a while), so make sure to wake them up. Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 737aac32a73d..8664f617f6e7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -1052,6 +1052,7 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) if (iwl_mvm_ref_taken(mvm)) { IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n"); clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); + wake_up(&mvm->d0i3_exit_waitq); return 1; } -- GitLab From 0395442ad25853f50d515f4dc00e3475b0df920d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 11 Nov 2014 16:49:25 +0100 Subject: [PATCH 4275/9457] mac80211: refactor duplicate detection Put duplicate detection into its own RX handler, and separate out the conditions a bit to make the code more readable. Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f57af5c7c12a..0f4297e2aae2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1047,7 +1047,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, } static ieee80211_rx_result debug_noinline -ieee80211_rx_h_check(struct ieee80211_rx_data *rx) +ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); @@ -1056,10 +1056,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) * Drop duplicate 802.11 retransmissions * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery") */ - if (rx->skb->len >= 24 && rx->sta && - !ieee80211_is_ctl(hdr->frame_control) && - !ieee80211_is_qos_nullfunc(hdr->frame_control) && - !is_multicast_ether_addr(hdr->addr1)) { + + if (rx->skb->len < 24) + return RX_CONTINUE; + + if (ieee80211_is_ctl(hdr->frame_control) || + ieee80211_is_qos_nullfunc(hdr->frame_control) || + is_multicast_ether_addr(hdr->addr1)) + return RX_CONTINUE; + + if (rx->sta) { if (unlikely(ieee80211_has_retry(hdr->frame_control) && rx->sta->last_seq_ctrl[rx->seqno_idx] == hdr->seq_ctrl)) { @@ -1073,6 +1079,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) } } + return RX_CONTINUE; +} + +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_check(struct ieee80211_rx_data *rx) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + if (unlikely(rx->skb->len < 16)) { I802_DEBUG_INC(rx->local->rx_handlers_drop_short); return RX_DROP_MONITOR; @@ -3110,6 +3124,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) goto rxh_next; \ } while (0); + CALL_RXH(ieee80211_rx_h_check_dup) CALL_RXH(ieee80211_rx_h_check) ieee80211_rx_reorder_ampdu(rx, &reorder_release); -- GitLab From 12cce594fa8f12e002e7eb5d10141853c1e6a112 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 3 Jul 2014 15:48:16 -0400 Subject: [PATCH 4276/9457] ftrace/x86: Allow !CONFIG_PREEMPT dynamic ops to use allocated trampolines When the static ftrace_ops (like function tracer) enables tracing, and it is the only callback that is referencing a function, a trampoline is dynamically allocated to the function that calls the callback directly instead of calling a loop function that iterates over all the registered ftrace ops (if more than one ops is registered). But when it comes to dynamically allocated ftrace_ops, where they may be freed, on a CONFIG_PREEMPT kernel there's no way to know when it is safe to free the trampoline. If a task was preempted while executing on the trampoline, there's currently no way to know when it will be off that trampoline. But this is not true when it comes to !CONFIG_PREEMPT. The current method of calling schedule_on_each_cpu() will force tasks off the trampoline, becaues they can not schedule while on it (kernel preemption is not configured). That means it is safe to free a dynamically allocated ftrace ops trampoline when CONFIG_PREEMPT is not configured. Cc: H. Peter Anvin Cc: Paul E. McKenney Acked-by: Borislav Petkov Tested-by: Masami Hiramatsu Tested-by: Jiri Kosina Signed-off-by: Steven Rostedt --- arch/x86/kernel/ftrace.c | 8 ++++++++ kernel/trace/ftrace.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index ca17c20a1010..4cfeca6ffe11 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -913,6 +913,14 @@ void *arch_ftrace_trampoline_func(struct ftrace_ops *ops, struct dyn_ftrace *rec return addr_from_call((void *)ops->trampoline + offset); } +void arch_ftrace_trampoline_free(struct ftrace_ops *ops) +{ + if (!ops || !(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP)) + return; + + tramp_free((void *)ops->trampoline); + ops->trampoline = 0; +} #endif /* CONFIG_X86_64 */ #endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 422e1f8300b1..eab3123a1fbe 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2324,6 +2324,10 @@ static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, static ftrace_func_t saved_ftrace_func; static int ftrace_start_up; +void __weak arch_ftrace_trampoline_free(struct ftrace_ops *ops) +{ +} + static void control_ops_free(struct ftrace_ops *ops) { free_percpu(ops->disabled); @@ -2475,6 +2479,8 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) { schedule_on_each_cpu(ftrace_sync); + arch_ftrace_trampoline_free(ops); + if (ops->flags & FTRACE_OPS_FL_CONTROL) control_ops_free(ops); } @@ -4725,9 +4731,21 @@ void __weak arch_ftrace_update_trampoline(struct ftrace_ops *ops) static void ftrace_update_trampoline(struct ftrace_ops *ops) { + +/* + * Currently there's no safe way to free a trampoline when the kernel + * is configured with PREEMPT. That is because a task could be preempted + * when it jumped to the trampoline, it may be preempted for a long time + * depending on the system load, and currently there's no way to know + * when it will be off the trampoline. If the trampoline is freed + * too early, when the task runs again, it will be executing on freed + * memory and crash. + */ +#ifdef CONFIG_PREEMPT /* Currently, only non dynamic ops can have a trampoline */ if (ops->flags & FTRACE_OPS_FL_DYNAMIC) return; +#endif arch_ftrace_update_trampoline(ops); } -- GitLab From 4fd3279b48605ae3ea509b9b2c02e46aa0975930 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 24 Oct 2014 17:56:04 -0400 Subject: [PATCH 4277/9457] ftrace: Add more information to ftrace_bug() output With the introduction of the dynamic trampolines, it is useful that if things go wrong that ftrace_bug() produces more information about what the current state is. This can help debug issues that may arise. Ftrace has lots of checks to make sure that the state of the system it touchs is exactly what it expects it to be. When it detects an abnormality it calls ftrace_bug() and disables itself to prevent any further damage. It is crucial that ftrace_bug() produces sufficient information that can be used to debug the situation. Cc: Benjamin Herrenschmidt Acked-by: Borislav Petkov Tested-by: Masami Hiramatsu Tested-by: Jiri Kosina Signed-off-by: Steven Rostedt --- arch/powerpc/kernel/ftrace.c | 2 +- arch/x86/kernel/ftrace.c | 2 +- include/linux/ftrace.h | 4 +++- kernel/trace/ftrace.c | 38 +++++++++++++++++++++++++++--------- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 390311c0f03d..e66af6d265e8 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -449,7 +449,7 @@ void ftrace_replace_code(int enable) rec = ftrace_rec_iter_record(iter); ret = __ftrace_replace_code(rec, enable); if (ret) { - ftrace_bug(ret, rec->ip); + ftrace_bug(ret, rec); return; } } diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 4cfeca6ffe11..1aea94d336c7 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -583,7 +583,7 @@ void ftrace_replace_code(int enable) remove_breakpoints: pr_warn("Failed on %s (%d):\n", report, count); - ftrace_bug(ret, rec ? rec->ip : 0); + ftrace_bug(ret, rec); for_ftrace_rec_iter(iter) { rec = ftrace_rec_iter_record(iter); /* diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 06e3ca5a5083..619e37cc17fd 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -263,7 +263,9 @@ struct ftrace_func_command { int ftrace_arch_code_modify_prepare(void); int ftrace_arch_code_modify_post_process(void); -void ftrace_bug(int err, unsigned long ip); +struct dyn_ftrace; + +void ftrace_bug(int err, struct dyn_ftrace *rec); struct seq_file; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index eab3123a1fbe..4043332f6720 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1738,10 +1738,13 @@ static void print_ip_ins(const char *fmt, unsigned char *p) printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); } +static struct ftrace_ops * +ftrace_find_tramp_ops_any(struct dyn_ftrace *rec); + /** * ftrace_bug - report and shutdown function tracer * @failed: The failed type (EFAULT, EINVAL, EPERM) - * @ip: The address that failed + * @rec: The record that failed * * The arch code that enables or disables the function tracing * can call ftrace_bug() when it has detected a problem in @@ -1750,8 +1753,10 @@ static void print_ip_ins(const char *fmt, unsigned char *p) * EINVAL - if what is read at @ip is not what was expected * EPERM - if the problem happens on writting to the @ip address */ -void ftrace_bug(int failed, unsigned long ip) +void ftrace_bug(int failed, struct dyn_ftrace *rec) { + unsigned long ip = rec ? rec->ip : 0; + switch (failed) { case -EFAULT: FTRACE_WARN_ON_ONCE(1); @@ -1763,7 +1768,7 @@ void ftrace_bug(int failed, unsigned long ip) pr_info("ftrace failed to modify "); print_ip_sym(ip); print_ip_ins(" actual: ", (unsigned char *)ip); - printk(KERN_CONT "\n"); + pr_cont("\n"); break; case -EPERM: FTRACE_WARN_ON_ONCE(1); @@ -1775,6 +1780,24 @@ void ftrace_bug(int failed, unsigned long ip) pr_info("ftrace faulted on unknown error "); print_ip_sym(ip); } + if (rec) { + struct ftrace_ops *ops = NULL; + + pr_info("ftrace record flags: %lx\n", rec->flags); + pr_cont(" (%ld)%s", ftrace_rec_count(rec), + rec->flags & FTRACE_FL_REGS ? " R" : " "); + if (rec->flags & FTRACE_FL_TRAMP_EN) { + ops = ftrace_find_tramp_ops_any(rec); + if (ops) + pr_cont("\ttramp: %pS", + (void *)ops->trampoline); + else + pr_cont("\ttramp: ERROR!"); + + } + ip = ftrace_get_addr_curr(rec); + pr_cont(" expected tramp: %lx\n", ip); + } } static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) @@ -2097,7 +2120,7 @@ void __weak ftrace_replace_code(int enable) do_for_each_ftrace_rec(pg, rec) { failed = __ftrace_replace_code(rec, enable); if (failed) { - ftrace_bug(failed, rec->ip); + ftrace_bug(failed, rec); /* Stop processing */ return; } @@ -2179,17 +2202,14 @@ struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter) static int ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) { - unsigned long ip; int ret; - ip = rec->ip; - if (unlikely(ftrace_disabled)) return 0; ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); if (ret) { - ftrace_bug(ret, ip); + ftrace_bug(ret, rec); return 0; } return 1; @@ -2633,7 +2653,7 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs) if (ftrace_start_up && cnt) { int failed = __ftrace_replace_code(p, 1); if (failed) - ftrace_bug(failed, p->ip); + ftrace_bug(failed, p); } } } -- GitLab From 632537256e9f969a188cc4d0159e0027a459d3e7 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 23 Jul 2014 21:35:01 +0200 Subject: [PATCH 4278/9457] tracing: Kill tracing_{start,stop}_sched_switch_record() and tracing_sched_switch_assign_trace() tracing_{start,stop}_sched_switch_record() have no callers since 87d80de2800d "tracing: Remove obsolete sched_switch tracer". The last caller of tracing_sched_switch_assign_trace() was removed by 30dbb20e68e6 "tracing: Remove boot tracer". Link: http://lkml.kernel.org/p/20140723193501.GA30214@redhat.com Signed-off-by: Oleg Nesterov Signed-off-by: Steven Rostedt --- kernel/trace/trace.h | 3 -- kernel/trace/trace_sched_switch.c | 48 ------------------------------- 2 files changed, 51 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 385391fb1d3b..a3a82d5f25dc 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -597,9 +597,6 @@ void set_graph_array(struct trace_array *tr); void tracing_start_cmdline_record(void); void tracing_stop_cmdline_record(void); -void tracing_sched_switch_assign_trace(struct trace_array *tr); -void tracing_stop_sched_switch_record(void); -void tracing_start_sched_switch_record(void); int register_tracer(struct tracer *type); int is_tracing_stopped(void); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 3f34dc9b40f3..3b60301c59d2 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -197,51 +197,3 @@ void tracing_stop_cmdline_record(void) { tracing_stop_sched_switch(); } - -/** - * tracing_start_sched_switch_record - start tracing context switches - * - * Turns on context switch tracing for a tracer. - */ -void tracing_start_sched_switch_record(void) -{ - if (unlikely(!ctx_trace)) { - WARN_ON(1); - return; - } - - tracing_start_sched_switch(); - - mutex_lock(&sched_register_mutex); - tracer_enabled++; - mutex_unlock(&sched_register_mutex); -} - -/** - * tracing_stop_sched_switch_record - start tracing context switches - * - * Turns off context switch tracing for a tracer. - */ -void tracing_stop_sched_switch_record(void) -{ - mutex_lock(&sched_register_mutex); - tracer_enabled--; - WARN_ON(tracer_enabled < 0); - mutex_unlock(&sched_register_mutex); - - tracing_stop_sched_switch(); -} - -/** - * tracing_sched_switch_assign_trace - assign a trace array for ctx switch - * @tr: trace array pointer to assign - * - * Some tracers might want to record the context switches in their - * trace. This function lets those tracers assign the trace array - * to use. - */ -void tracing_sched_switch_assign_trace(struct trace_array *tr) -{ - ctx_trace = tr; -} - -- GitLab From 458faf0b88b19a46d51bb9760fa6e03a1bc6d97b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 23 Jul 2014 21:35:03 +0200 Subject: [PATCH 4279/9457] tracing: Kill the dead code in probe_sched_switch() and probe_sched_wakeup() After the previous patch it is clear that "tracer_enabled" can never be true, we can remove the "if (tracer_enabled)" code in probe_sched_switch() and probe_sched_wakeup(). Plus we can obviously remove tracer_enabled, ctx_trace, and sched_stopped as well. Link: http://lkml.kernel.org/p/20140723193503.GA30217@redhat.com Signed-off-by: Oleg Nesterov Signed-off-by: Steven Rostedt --- kernel/trace/trace_sched_switch.c | 40 ------------------------------- 1 file changed, 40 deletions(-) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 3b60301c59d2..f7c7f4f1544c 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -14,12 +14,8 @@ #include "trace.h" -static struct trace_array *ctx_trace; -static int __read_mostly tracer_enabled; static int sched_ref; static DEFINE_MUTEX(sched_register_mutex); -static int sched_stopped; - void tracing_sched_switch_trace(struct trace_array *tr, @@ -52,29 +48,11 @@ tracing_sched_switch_trace(struct trace_array *tr, static void probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) { - struct trace_array_cpu *data; - unsigned long flags; - int cpu; - int pc; - if (unlikely(!sched_ref)) return; tracing_record_cmdline(prev); tracing_record_cmdline(next); - - if (!tracer_enabled || sched_stopped) - return; - - pc = preempt_count(); - local_irq_save(flags); - cpu = raw_smp_processor_id(); - data = per_cpu_ptr(ctx_trace->trace_buffer.data, cpu); - - if (likely(!atomic_read(&data->disabled))) - tracing_sched_switch_trace(ctx_trace, prev, next, flags, pc); - - local_irq_restore(flags); } void @@ -108,28 +86,10 @@ tracing_sched_wakeup_trace(struct trace_array *tr, static void probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success) { - struct trace_array_cpu *data; - unsigned long flags; - int cpu, pc; - if (unlikely(!sched_ref)) return; tracing_record_cmdline(current); - - if (!tracer_enabled || sched_stopped) - return; - - pc = preempt_count(); - local_irq_save(flags); - cpu = raw_smp_processor_id(); - data = per_cpu_ptr(ctx_trace->trace_buffer.data, cpu); - - if (likely(!atomic_read(&data->disabled))) - tracing_sched_wakeup_trace(ctx_trace, wakee, current, - flags, pc); - - local_irq_restore(flags); } static int tracing_sched_register(void) -- GitLab From 243f7610a68a606eb1787c09450a440bf30bebe0 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 30 Oct 2014 20:44:53 -0400 Subject: [PATCH 4280/9457] tracing: Move tracing_sched_{switch,wakeup}() into wakeup tracer The only code that references tracing_sched_switch_trace() and tracing_sched_wakeup_trace() is the wakeup latency tracer. Those two functions use to belong to the sched_switch tracer which has long been removed. These functions were left behind because the wakeup latency tracer used them. But since the wakeup latency tracer is the only one to use them, they should be static functions inside that code. Signed-off-by: Steven Rostedt --- kernel/trace/trace.h | 9 ----- kernel/trace/trace_sched_switch.c | 56 ------------------------------- kernel/trace/trace_sched_wakeup.c | 56 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 65 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a3a82d5f25dc..3376de623ea0 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -569,15 +569,6 @@ void trace_init_global_iter(struct trace_iterator *iter); void tracing_iter_reset(struct trace_iterator *iter, int cpu); -void tracing_sched_switch_trace(struct trace_array *tr, - struct task_struct *prev, - struct task_struct *next, - unsigned long flags, int pc); - -void tracing_sched_wakeup_trace(struct trace_array *tr, - struct task_struct *wakee, - struct task_struct *cur, - unsigned long flags, int pc); void trace_function(struct trace_array *tr, unsigned long ip, unsigned long parent_ip, diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index f7c7f4f1544c..2e293beb186e 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -17,34 +17,6 @@ static int sched_ref; static DEFINE_MUTEX(sched_register_mutex); -void -tracing_sched_switch_trace(struct trace_array *tr, - struct task_struct *prev, - struct task_struct *next, - unsigned long flags, int pc) -{ - struct ftrace_event_call *call = &event_context_switch; - struct ring_buffer *buffer = tr->trace_buffer.buffer; - struct ring_buffer_event *event; - struct ctx_switch_entry *entry; - - event = trace_buffer_lock_reserve(buffer, TRACE_CTX, - sizeof(*entry), flags, pc); - if (!event) - return; - entry = ring_buffer_event_data(event); - entry->prev_pid = prev->pid; - entry->prev_prio = prev->prio; - entry->prev_state = prev->state; - entry->next_pid = next->pid; - entry->next_prio = next->prio; - entry->next_state = next->state; - entry->next_cpu = task_cpu(next); - - if (!call_filter_check_discard(call, entry, buffer, event)) - trace_buffer_unlock_commit(buffer, event, flags, pc); -} - static void probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) { @@ -55,34 +27,6 @@ probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *n tracing_record_cmdline(next); } -void -tracing_sched_wakeup_trace(struct trace_array *tr, - struct task_struct *wakee, - struct task_struct *curr, - unsigned long flags, int pc) -{ - struct ftrace_event_call *call = &event_wakeup; - struct ring_buffer_event *event; - struct ctx_switch_entry *entry; - struct ring_buffer *buffer = tr->trace_buffer.buffer; - - event = trace_buffer_lock_reserve(buffer, TRACE_WAKE, - sizeof(*entry), flags, pc); - if (!event) - return; - entry = ring_buffer_event_data(event); - entry->prev_pid = curr->pid; - entry->prev_prio = curr->prio; - entry->prev_state = curr->state; - entry->next_pid = wakee->pid; - entry->next_prio = wakee->prio; - entry->next_state = wakee->state; - entry->next_cpu = task_cpu(wakee); - - if (!call_filter_check_discard(call, entry, buffer, event)) - trace_buffer_unlock_commit(buffer, event, flags, pc); -} - static void probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success) { diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 19bd8928ce94..8fb84b362816 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -365,6 +365,62 @@ probe_wakeup_migrate_task(void *ignore, struct task_struct *task, int cpu) wakeup_current_cpu = cpu; } +static void +tracing_sched_switch_trace(struct trace_array *tr, + struct task_struct *prev, + struct task_struct *next, + unsigned long flags, int pc) +{ + struct ftrace_event_call *call = &event_context_switch; + struct ring_buffer *buffer = tr->trace_buffer.buffer; + struct ring_buffer_event *event; + struct ctx_switch_entry *entry; + + event = trace_buffer_lock_reserve(buffer, TRACE_CTX, + sizeof(*entry), flags, pc); + if (!event) + return; + entry = ring_buffer_event_data(event); + entry->prev_pid = prev->pid; + entry->prev_prio = prev->prio; + entry->prev_state = prev->state; + entry->next_pid = next->pid; + entry->next_prio = next->prio; + entry->next_state = next->state; + entry->next_cpu = task_cpu(next); + + if (!call_filter_check_discard(call, entry, buffer, event)) + trace_buffer_unlock_commit(buffer, event, flags, pc); +} + +static void +tracing_sched_wakeup_trace(struct trace_array *tr, + struct task_struct *wakee, + struct task_struct *curr, + unsigned long flags, int pc) +{ + struct ftrace_event_call *call = &event_wakeup; + struct ring_buffer_event *event; + struct ctx_switch_entry *entry; + struct ring_buffer *buffer = tr->trace_buffer.buffer; + + event = trace_buffer_lock_reserve(buffer, TRACE_WAKE, + sizeof(*entry), flags, pc); + if (!event) + return; + entry = ring_buffer_event_data(event); + entry->prev_pid = curr->pid; + entry->prev_prio = curr->prio; + entry->prev_state = curr->state; + entry->next_pid = wakee->pid; + entry->next_prio = wakee->prio; + entry->next_state = wakee->state; + entry->next_cpu = task_cpu(wakee); + + if (!call_filter_check_discard(call, entry, buffer, event)) + trace_buffer_unlock_commit(buffer, event, flags, pc); +} + static void notrace probe_wakeup_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) -- GitLab From 26488b3723270880a28b542ff2276689506d6a9f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 22 Aug 2013 20:59:39 +0800 Subject: [PATCH 4281/9457] tracing: Add entry->next_cpu to trace_ctxwake_bin() Function trace_ctxwake_bin() misses ctx_switch_entry->next_cpu field, so user will get stale value for "next_cpu". Link: http://lkml.kernel.org/p/1377176379-27908-1-git-send-email-liuj97@gmail.com Signed-off-by: Jiang Liu Signed-off-by: Steven Rostedt --- kernel/trace/trace_output.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index c6977d5a9b12..cfa91de22e27 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -976,6 +976,7 @@ static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, SEQ_PUT_FIELD_RET(s, field->prev_pid); SEQ_PUT_FIELD_RET(s, field->prev_prio); SEQ_PUT_FIELD_RET(s, field->prev_state); + SEQ_PUT_FIELD_RET(s, field->next_cpu); SEQ_PUT_FIELD_RET(s, field->next_pid); SEQ_PUT_FIELD_RET(s, field->next_prio); SEQ_PUT_FIELD_RET(s, field->next_state); -- GitLab From 3d97379a67486bc481ab5b8f7aa5b7ceb6154a95 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 11 Nov 2014 05:54:27 -0800 Subject: [PATCH 4282/9457] tcp: move sk_mark_napi_id() at the right place sk_mark_napi_id() is used to record for a flow napi id of incoming packets for busypoll sake. We should do this only on established flows, not on listeners. This was 'working' by virtue of the socket cloning, but doing this on SYN packets in unecessary cache line dirtying. Even if we move sk_napi_id in the same cache line than sk_lock, we are working to make SYN processing lockless, so it is desirable to set sk_napi_id only for established flows. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv6/tcp_ipv6.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c7d7621466b..8893598a4124 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1429,6 +1429,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) struct dst_entry *dst = sk->sk_rx_dst; sock_rps_save_rxhash(sk, skb); + sk_mark_napi_id(sk, skb); if (dst) { if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || dst->ops->check(dst, 0) == NULL) { @@ -1450,6 +1451,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) if (nsk != sk) { sock_rps_save_rxhash(nsk, skb); + sk_mark_napi_id(sk, skb); if (tcp_child_process(sk, nsk, skb)) { rsk = nsk; goto reset; @@ -1661,7 +1663,6 @@ int tcp_v4_rcv(struct sk_buff *skb) if (sk_filter(sk, skb)) goto discard_and_relse; - sk_mark_napi_id(sk, skb); skb->dev = NULL; bh_lock_sock_nested(sk); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ace29b60813c..fd8e50b380e7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1293,6 +1293,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) struct dst_entry *dst = sk->sk_rx_dst; sock_rps_save_rxhash(sk, skb); + sk_mark_napi_id(sk, skb); if (dst) { if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || dst->ops->check(dst, np->rx_dst_cookie) == NULL) { @@ -1322,6 +1323,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) */ if (nsk != sk) { sock_rps_save_rxhash(nsk, skb); + sk_mark_napi_id(sk, skb); if (tcp_child_process(sk, nsk, skb)) goto reset; if (opt_skb) @@ -1454,7 +1456,6 @@ static int tcp_v6_rcv(struct sk_buff *skb) if (sk_filter(sk, skb)) goto discard_and_relse; - sk_mark_napi_id(sk, skb); skb->dev = NULL; bh_lock_sock_nested(sk); -- GitLab From 2c8c56e15df3d4c2af3d656e44feb18789f75837 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 11 Nov 2014 05:54:28 -0800 Subject: [PATCH 4283/9457] net: introduce SO_INCOMING_CPU Alternative to RPS/RFS is to use hardware support for multiple queues. Then split a set of million of sockets into worker threads, each one using epoll() to manage events on its own socket pool. Ideally, we want one thread per RX/TX queue/cpu, but we have no way to know after accept() or connect() on which queue/cpu a socket is managed. We normally use one cpu per RX queue (IRQ smp_affinity being properly set), so remembering on socket structure which cpu delivered last packet is enough to solve the problem. After accept(), connect(), or even file descriptor passing around processes, applications can use : int cpu; socklen_t len = sizeof(cpu); getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, &len); And use this information to put the socket into the right silo for optimal performance, as all networking stack should run on the appropriate cpu, without need to send IPI (RPS/RFS). Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- arch/alpha/include/uapi/asm/socket.h | 2 ++ arch/avr32/include/uapi/asm/socket.h | 2 ++ arch/cris/include/uapi/asm/socket.h | 2 ++ arch/frv/include/uapi/asm/socket.h | 2 ++ arch/ia64/include/uapi/asm/socket.h | 2 ++ arch/m32r/include/uapi/asm/socket.h | 2 ++ arch/mips/include/uapi/asm/socket.h | 2 ++ arch/mn10300/include/uapi/asm/socket.h | 2 ++ arch/parisc/include/uapi/asm/socket.h | 2 ++ arch/powerpc/include/uapi/asm/socket.h | 2 ++ arch/s390/include/uapi/asm/socket.h | 2 ++ arch/sparc/include/uapi/asm/socket.h | 2 ++ arch/xtensa/include/uapi/asm/socket.h | 2 ++ include/net/sock.h | 12 ++++++++++++ include/uapi/asm-generic/socket.h | 2 ++ net/core/sock.c | 5 +++++ net/ipv4/tcp_ipv4.c | 1 + net/ipv4/udp.c | 1 + net/ipv6/tcp_ipv6.c | 1 + net/ipv6/udp.c | 1 + net/sctp/ulpqueue.c | 5 +++-- 21 files changed, 52 insertions(+), 2 deletions(-) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 3de1394bcab8..e2fe0700b3b4 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -87,4 +87,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index 6e6cd159924b..92121b0f5b98 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h @@ -80,4 +80,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _UAPI__ASM_AVR32_SOCKET_H */ diff --git a/arch/cris/include/uapi/asm/socket.h b/arch/cris/include/uapi/asm/socket.h index ed94e5ed0a23..60f60f5b9b35 100644 --- a/arch/cris/include/uapi/asm/socket.h +++ b/arch/cris/include/uapi/asm/socket.h @@ -82,6 +82,8 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index ca2c6e6f31c6..2c6890209ea6 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -80,5 +80,7 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index a1b49bac7951..09a93fb566f6 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -89,4 +89,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index 6c9a24b3aefa..e8589819c274 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -80,4 +80,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index a14baa218c76..2e9ee8c55a10 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -98,4 +98,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index 6aa3ce1854aa..f3492e8c9f70 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -80,4 +80,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index fe35ceacf0e7..7984a1cab3da 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -79,4 +79,6 @@ #define SO_BPF_EXTENSIONS 0x4029 +#define SO_INCOMING_CPU 0x402A + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index a9c3e2e18c05..3474e4ef166d 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h @@ -87,4 +87,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_POWERPC_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index e031332096d7..8457636c33e1 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -86,4 +86,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 54d9608681b6..4a8003a94163 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -76,6 +76,8 @@ #define SO_BPF_EXTENSIONS 0x0032 +#define SO_INCOMING_CPU 0x0033 + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index 39acec0cf0b1..c46f6a696849 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -91,4 +91,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* _XTENSA_SOCKET_H */ diff --git a/include/net/sock.h b/include/net/sock.h index 6767d75ecb17..7789b59c0c40 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -273,6 +273,7 @@ struct cg_proto; * @sk_rcvtimeo: %SO_RCVTIMEO setting * @sk_sndtimeo: %SO_SNDTIMEO setting * @sk_rxhash: flow hash received from netif layer + * @sk_incoming_cpu: record cpu processing incoming packets * @sk_txhash: computed flow hash for use on transmit * @sk_filter: socket filtering instructions * @sk_protinfo: private area, net family specific, when not using slab @@ -350,6 +351,12 @@ struct sock { #ifdef CONFIG_RPS __u32 sk_rxhash; #endif + u16 sk_incoming_cpu; + /* 16bit hole + * Warned : sk_incoming_cpu can be set from softirq, + * Do not use this hole without fully understanding possible issues. + */ + __u32 sk_txhash; #ifdef CONFIG_NET_RX_BUSY_POLL unsigned int sk_napi_id; @@ -833,6 +840,11 @@ static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb) return sk->sk_backlog_rcv(sk, skb); } +static inline void sk_incoming_cpu_update(struct sock *sk) +{ + sk->sk_incoming_cpu = raw_smp_processor_id(); +} + static inline void sock_rps_record_flow_hash(__u32 hash) { #ifdef CONFIG_RPS diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index ea0796bdcf88..f541ccefd4ac 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -82,4 +82,6 @@ #define SO_BPF_EXTENSIONS 48 +#define SO_INCOMING_CPU 49 + #endif /* __ASM_GENERIC_SOCKET_H */ diff --git a/net/core/sock.c b/net/core/sock.c index ac56dd06c306..0725cf0cb685 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1213,6 +1213,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val = sk->sk_max_pacing_rate; break; + case SO_INCOMING_CPU: + v.val = sk->sk_incoming_cpu; + break; + default: return -ENOPROTOOPT; } @@ -1517,6 +1521,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) newsk->sk_err = 0; newsk->sk_priority = 0; + newsk->sk_incoming_cpu = raw_smp_processor_id(); /* * Before updating sk_refcnt, we must commit prior changes to memory * (Documentation/RCU/rculist_nulls.txt for details) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 8893598a4124..2c6a955fd5c3 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1663,6 +1663,7 @@ int tcp_v4_rcv(struct sk_buff *skb) if (sk_filter(sk, skb)) goto discard_and_relse; + sk_incoming_cpu_update(sk); skb->dev = NULL; bh_lock_sock_nested(sk); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5d0fdca8e965..d13751685f44 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1445,6 +1445,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (inet_sk(sk)->inet_daddr) { sock_rps_save_rxhash(sk, skb); sk_mark_napi_id(sk, skb); + sk_incoming_cpu_update(sk); } rc = sock_queue_rcv_skb(sk, skb); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fd8e50b380e7..1985b4933a6b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1456,6 +1456,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) if (sk_filter(sk, skb)) goto discard_and_relse; + sk_incoming_cpu_update(sk); skb->dev = NULL; bh_lock_sock_nested(sk); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b756355e9739..d1fe36274906 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -577,6 +577,7 @@ static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (!ipv6_addr_any(&sk->sk_v6_daddr)) { sock_rps_save_rxhash(sk, skb); sk_mark_napi_id(sk, skb); + sk_incoming_cpu_update(sk); } rc = sock_queue_rcv_skb(sk, skb); diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index d49dc2ed30ad..ce469d648ffb 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -205,9 +205,10 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) if (sock_flag(sk, SOCK_DEAD) || (sk->sk_shutdown & RCV_SHUTDOWN)) goto out_free; - if (!sctp_ulpevent_is_notification(event)) + if (!sctp_ulpevent_is_notification(event)) { sk_mark_napi_id(sk, skb); - + sk_incoming_cpu_update(sk); + } /* Check if the user wishes to receive this event. */ if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe)) goto out_free; -- GitLab From 9169051617df7fca597274e9e43324332cb8f0ee Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 8 Nov 2014 10:28:10 +0000 Subject: [PATCH 4284/9457] spi: spidev: Don't mangle max_speed_hz in underlying spi device Currently spidev allows callers to set the default speed by overriding the max_speed_hz in the underlying device. This achieves the immediate goal but is not what devices expect and can easily lead to userspace trying to set unsupported speeds and succeeding, apart from anything else drivers can't set a limit on the speed using max_speed_hz as they'd expect and any other devices on the bus will be affected. Instead store the default speed in the spidev struct and fill this in on each transfer. Signed-off-by: Mark Brown --- drivers/spi/spidev.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e50039fb1474..6941e04afb8c 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -87,6 +87,7 @@ struct spidev_data { unsigned users; u8 *tx_buffer; u8 *rx_buffer; + u32 speed_hz; }; static LIST_HEAD(device_list); @@ -138,6 +139,7 @@ spidev_sync_write(struct spidev_data *spidev, size_t len) struct spi_transfer t = { .tx_buf = spidev->tx_buffer, .len = len, + .speed_hz = spidev->speed_hz, }; struct spi_message m; @@ -152,6 +154,7 @@ spidev_sync_read(struct spidev_data *spidev, size_t len) struct spi_transfer t = { .rx_buf = spidev->rx_buffer, .len = len, + .speed_hz = spidev->speed_hz, }; struct spi_message m; @@ -274,6 +277,8 @@ static int spidev_message(struct spidev_data *spidev, k_tmp->bits_per_word = u_tmp->bits_per_word; k_tmp->delay_usecs = u_tmp->delay_usecs; k_tmp->speed_hz = u_tmp->speed_hz; + if (!k_tmp->speed_hz) + k_tmp->speed_hz = spidev->speed_hz; #ifdef VERBOSE dev_dbg(&spidev->spi->dev, " xfer len %zd %s%s%s%dbits %u usec %uHz\n", @@ -377,7 +382,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = __put_user(spi->bits_per_word, (__u8 __user *)arg); break; case SPI_IOC_RD_MAX_SPEED_HZ: - retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg); + retval = __put_user(spidev->speed_hz, (__u32 __user *)arg); break; /* write requests */ @@ -441,10 +446,11 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) spi->max_speed_hz = tmp; retval = spi_setup(spi); - if (retval < 0) - spi->max_speed_hz = save; + if (retval >= 0) + spidev->speed_hz = tmp; else dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); + spi->max_speed_hz = save; } break; @@ -570,6 +576,8 @@ static int spidev_release(struct inode *inode, struct file *filp) kfree(spidev->rx_buffer); spidev->rx_buffer = NULL; + spidev->speed_hz = spidev->spi->max_speed_hz; + /* ... after we unbound from the underlying device? */ spin_lock_irq(&spidev->spi_lock); dofree = (spidev->spi == NULL); @@ -650,6 +658,8 @@ static int spidev_probe(struct spi_device *spi) } mutex_unlock(&device_list_lock); + spidev->speed_hz = spi->max_speed_hz; + if (status == 0) spi_set_drvdata(spi, spidev); else -- GitLab From 398205b8391b208f0034a392242867b28ad8af3d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Nov 2014 23:03:59 +0100 Subject: [PATCH 4285/9457] blk_mq: call preempt_disable/enable in blk_mq_run_hw_queue, and only if needed preempt_disable/enable surrounds every call to blk_mq_run_hw_queue, except the one in blk-flush.c. In fact that one is always asynchronous, and it does not need smp_processor_id(). We can do the same for all other calls, avoiding preempt_disable when async is true. This avoids peppering blk-mq.c with preemption-disabled regions. Cc: Jens Axboe Cc: Thomas Gleixner Reported-by: Clark Williams Tested-by: Clark Williams Signed-off-by: Paolo Bonzini Signed-off-by: Jens Axboe --- block/blk-mq.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index b355b5957cd7..8b309e81ed0f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -801,9 +801,18 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state))) return; - if (!async && cpumask_test_cpu(smp_processor_id(), hctx->cpumask)) - __blk_mq_run_hw_queue(hctx); - else if (hctx->queue->nr_hw_queues == 1) + if (!async) { + preempt_disable(); + if (cpumask_test_cpu(smp_processor_id(), hctx->cpumask)) { + __blk_mq_run_hw_queue(hctx); + preempt_enable(); + return; + } + + preempt_enable(); + } + + if (hctx->queue->nr_hw_queues == 1) kblockd_schedule_delayed_work(&hctx->run_work, 0); else { unsigned int cpu; @@ -824,9 +833,7 @@ void blk_mq_run_queues(struct request_queue *q, bool async) test_bit(BLK_MQ_S_STOPPED, &hctx->state)) continue; - preempt_disable(); blk_mq_run_hw_queue(hctx, async); - preempt_enable(); } } EXPORT_SYMBOL(blk_mq_run_queues); @@ -853,9 +860,7 @@ void blk_mq_start_hw_queue(struct blk_mq_hw_ctx *hctx) { clear_bit(BLK_MQ_S_STOPPED, &hctx->state); - preempt_disable(); blk_mq_run_hw_queue(hctx, false); - preempt_enable(); } EXPORT_SYMBOL(blk_mq_start_hw_queue); @@ -880,9 +885,7 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async) continue; clear_bit(BLK_MQ_S_STOPPED, &hctx->state); - preempt_disable(); blk_mq_run_hw_queue(hctx, async); - preempt_enable(); } } EXPORT_SYMBOL(blk_mq_start_stopped_hw_queues); -- GitLab From 2a90d4aae5509e9cf1ba848c5d0b3458201160a0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Nov 2014 23:04:00 +0100 Subject: [PATCH 4286/9457] blk-mq: use get_cpu/put_cpu instead of preempt_disable/preempt_enable blk-mq is using preempt_disable/enable in order to ensure that the queue runners are placed on the right CPU. This does not work with the RT patches, because __blk_mq_run_hw_queue takes a non-raw spinlock with the preemption-disabled region. If there is contention on the lock, this violates the rules for preemption-disabled regions. While this should be easily fixable within the RT patches just by doing migrate_disable/enable, we can do better and document _why_ this particular region runs with disabled preemption. After the previous patch, it is trivial to switch it to get/put_cpu; the RT patches then can change it to get_cpu_light, which lets virtio-blk run under RT kernels. Cc: Jens Axboe Cc: Thomas Gleixner Reported-by: Clark Williams Tested-by: Clark Williams Signed-off-by: Paolo Bonzini Signed-off-by: Jens Axboe --- block/blk-mq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 8b309e81ed0f..06ab0683a1f1 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -802,14 +802,14 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) return; if (!async) { - preempt_disable(); - if (cpumask_test_cpu(smp_processor_id(), hctx->cpumask)) { + int cpu = get_cpu(); + if (cpumask_test_cpu(cpu, hctx->cpumask)) { __blk_mq_run_hw_queue(hctx); - preempt_enable(); + put_cpu(); return; } - preempt_enable(); + put_cpu(); } if (hctx->queue->nr_hw_queues == 1) -- GitLab From dd65beac48a5259945846956d4b27344dfb73bd9 Mon Sep 17 00:00:00 2001 From: Shani Michaeli Date: Sun, 9 Nov 2014 13:51:52 +0200 Subject: [PATCH 4287/9457] net/mlx4_en: Extend usage of napi_gro_frags We can call napi_gro_frags for all the received traffic regardless of the checksum status. Specifically, received packets whose status is CHECKSUM_NONE (and soon to be added CHECKSUM_COMPLETE) are eligible for napi_gro_frags as well. Signed-off-by: Or Gerlitz Signed-off-by: Shani Michaeli Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 108 ++++++++++----------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 5a193f40a14c..df6d352c4e54 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -747,60 +747,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && (cqe->checksum == cpu_to_be16(0xffff))) { ring->csum_ok++; - /* This packet is eligible for GRO if it is: - * - DIX Ethernet (type interpretation) - * - TCP/IP (v4) - * - without IP options - * - not an IP fragment - * - no LLS polling in progress - */ - if (!mlx4_en_cq_busy_polling(cq) && - (dev->features & NETIF_F_GRO)) { - struct sk_buff *gro_skb = napi_get_frags(&cq->napi); - if (!gro_skb) - goto next; - - nr = mlx4_en_complete_rx_desc(priv, - rx_desc, frags, gro_skb, - length); - if (!nr) - goto next; - - skb_shinfo(gro_skb)->nr_frags = nr; - gro_skb->len = length; - gro_skb->data_len = length; - gro_skb->ip_summed = CHECKSUM_UNNECESSARY; - - if (l2_tunnel) - gro_skb->csum_level = 1; - if ((cqe->vlan_my_qpn & - cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)) && - (dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { - u16 vid = be16_to_cpu(cqe->sl_vid); - - __vlan_hwaccel_put_tag(gro_skb, htons(ETH_P_8021Q), vid); - } - - if (dev->features & NETIF_F_RXHASH) - skb_set_hash(gro_skb, - be32_to_cpu(cqe->immed_rss_invalid), - PKT_HASH_TYPE_L3); - - skb_record_rx_queue(gro_skb, cq->ring); - skb_mark_napi_id(gro_skb, &cq->napi); - - if (ring->hwtstamp_rx_filter == HWTSTAMP_FILTER_ALL) { - timestamp = mlx4_en_get_cqe_ts(cqe); - mlx4_en_fill_hwtstamps(mdev, - skb_hwtstamps(gro_skb), - timestamp); - } - - napi_gro_frags(&cq->napi); - goto next; - } - - /* GRO not possible, complete processing here */ ip_summed = CHECKSUM_UNNECESSARY; } else { ip_summed = CHECKSUM_NONE; @@ -811,6 +757,60 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud ring->csum_none++; } + /* This packet is eligible for GRO if it is: + * - DIX Ethernet (type interpretation) + * - TCP/IP (v4) + * - without IP options + * - not an IP fragment + * - no LLS polling in progress + */ + if (!mlx4_en_cq_busy_polling(cq) && + (dev->features & NETIF_F_GRO)) { + struct sk_buff *gro_skb = napi_get_frags(&cq->napi); + if (!gro_skb) + goto next; + + nr = mlx4_en_complete_rx_desc(priv, + rx_desc, frags, gro_skb, + length); + if (!nr) + goto next; + + skb_shinfo(gro_skb)->nr_frags = nr; + gro_skb->len = length; + gro_skb->data_len = length; + gro_skb->ip_summed = ip_summed; + + if (l2_tunnel && ip_summed == CHECKSUM_UNNECESSARY) + gro_skb->encapsulation = 1; + if ((cqe->vlan_my_qpn & + cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)) && + (dev->features & NETIF_F_HW_VLAN_CTAG_RX)) { + u16 vid = be16_to_cpu(cqe->sl_vid); + + __vlan_hwaccel_put_tag(gro_skb, htons(ETH_P_8021Q), vid); + } + + if (dev->features & NETIF_F_RXHASH) + skb_set_hash(gro_skb, + be32_to_cpu(cqe->immed_rss_invalid), + PKT_HASH_TYPE_L3); + + skb_record_rx_queue(gro_skb, cq->ring); + skb_mark_napi_id(gro_skb, &cq->napi); + + if (ring->hwtstamp_rx_filter == HWTSTAMP_FILTER_ALL) { + timestamp = mlx4_en_get_cqe_ts(cqe); + mlx4_en_fill_hwtstamps(mdev, + skb_hwtstamps(gro_skb), + timestamp); + } + + napi_gro_frags(&cq->napi); + goto next; + } + + /* GRO not possible, complete processing here */ skb = mlx4_en_rx_skb(priv, rx_desc, frags, length); if (!skb) { priv->stats.rx_dropped++; -- GitLab From f8c6455bb04b944edb69e9b074e28efee2c56bdd Mon Sep 17 00:00:00 2001 From: Shani Michaeli Date: Sun, 9 Nov 2014 13:51:53 +0200 Subject: [PATCH 4288/9457] net/mlx4_en: Extend checksum offloading by CHECKSUM COMPLETE When processing received traffic, pass CHECKSUM_COMPLETE status to the stack, with calculated checksum for non TCP/UDP packets (such as GRE or ICMP). Although the stack expects checksum which doesn't include the pseudo header, the HW adds it. To address that, we are subtracting the pseudo header checksum from the checksum value provided by the HW. In the IPv6 case, we also compute/add the IP header checksum which is not added by the HW for such packets. Cc: Jerry Chu Signed-off-by: Shani Michaeli Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 5 + drivers/net/ethernet/mellanox/mlx4/en_port.c | 2 + drivers/net/ethernet/mellanox/mlx4/en_rx.c | 126 +++++++++++++++++- drivers/net/ethernet/mellanox/mlx4/main.c | 9 ++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 5 +- include/linux/mlx4/device.h | 1 + 7 files changed, 142 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 8ea4d5be7376..6c643230a5ed 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -115,7 +115,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = { "tso_packets", "xmit_more", "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed", - "rx_csum_good", "rx_csum_none", "tx_chksum_offload", + "rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload", /* packet statistics */ "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3", diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 0efbae90f1ba..d1eb25dbff56 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1893,6 +1893,7 @@ static void mlx4_en_clear_stats(struct net_device *dev) priv->rx_ring[i]->packets = 0; priv->rx_ring[i]->csum_ok = 0; priv->rx_ring[i]->csum_none = 0; + priv->rx_ring[i]->csum_complete = 0; } } @@ -2503,6 +2504,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, /* Query for default mac and max mtu */ priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port]; + if (mdev->dev->caps.rx_checksum_flags_port[priv->port] & + MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP) + priv->flags |= MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP; + /* Set default MAC */ dev->addr_len = ETH_ALEN; mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index 134b12e17da5..6cb80072af6c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c @@ -155,11 +155,13 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) stats->rx_bytes = 0; priv->port_stats.rx_chksum_good = 0; priv->port_stats.rx_chksum_none = 0; + priv->port_stats.rx_chksum_complete = 0; for (i = 0; i < priv->rx_ring_num; i++) { stats->rx_packets += priv->rx_ring[i]->packets; stats->rx_bytes += priv->rx_ring[i]->bytes; priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok; priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none; + priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete; } stats->tx_packets = 0; stats->tx_bytes = 0; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index df6d352c4e54..ccd95177ea7c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -42,6 +42,10 @@ #include #include +#if IS_ENABLED(CONFIG_IPV6) +#include +#endif + #include "mlx4_en.h" static int mlx4_alloc_pages(struct mlx4_en_priv *priv, @@ -643,6 +647,86 @@ static void mlx4_en_refill_rx_buffers(struct mlx4_en_priv *priv, } } +/* When hardware doesn't strip the vlan, we need to calculate the checksum + * over it and add it to the hardware's checksum calculation + */ +static inline __wsum get_fixed_vlan_csum(__wsum hw_checksum, + struct vlan_hdr *vlanh) +{ + return csum_add(hw_checksum, *(__wsum *)vlanh); +} + +/* Although the stack expects checksum which doesn't include the pseudo + * header, the HW adds it. To address that, we are subtracting the pseudo + * header checksum from the checksum value provided by the HW. + */ +static void get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb, + struct iphdr *iph) +{ + __u16 length_for_csum = 0; + __wsum csum_pseudo_header = 0; + + length_for_csum = (be16_to_cpu(iph->tot_len) - (iph->ihl << 2)); + csum_pseudo_header = csum_tcpudp_nofold(iph->saddr, iph->daddr, + length_for_csum, iph->protocol, 0); + skb->csum = csum_sub(hw_checksum, csum_pseudo_header); +} + +#if IS_ENABLED(CONFIG_IPV6) +/* In IPv6 packets, besides subtracting the pseudo header checksum, + * we also compute/add the IP header checksum which + * is not added by the HW. + */ +static int get_fixed_ipv6_csum(__wsum hw_checksum, struct sk_buff *skb, + struct ipv6hdr *ipv6h) +{ + __wsum csum_pseudo_hdr = 0; + + if (ipv6h->nexthdr == IPPROTO_FRAGMENT || ipv6h->nexthdr == IPPROTO_HOPOPTS) + return -1; + hw_checksum = csum_add(hw_checksum, (__force __wsum)(ipv6h->nexthdr << 8)); + + csum_pseudo_hdr = csum_partial(&ipv6h->saddr, + sizeof(ipv6h->saddr) + sizeof(ipv6h->daddr), 0); + csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ipv6h->payload_len); + csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ntohs(ipv6h->nexthdr)); + + skb->csum = csum_sub(hw_checksum, csum_pseudo_hdr); + skb->csum = csum_add(skb->csum, csum_partial(ipv6h, sizeof(struct ipv6hdr), 0)); + return 0; +} +#endif +static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va, + int hwtstamp_rx_filter) +{ + __wsum hw_checksum = 0; + + void *hdr = (u8 *)va + sizeof(struct ethhdr); + + hw_checksum = csum_unfold((__force __sum16)cqe->checksum); + + if (((struct ethhdr *)va)->h_proto == htons(ETH_P_8021Q) && + hwtstamp_rx_filter != HWTSTAMP_FILTER_NONE) { + /* next protocol non IPv4 or IPv6 */ + if (((struct vlan_hdr *)hdr)->h_vlan_encapsulated_proto + != htons(ETH_P_IP) && + ((struct vlan_hdr *)hdr)->h_vlan_encapsulated_proto + != htons(ETH_P_IPV6)) + return -1; + hw_checksum = get_fixed_vlan_csum(hw_checksum, hdr); + hdr += sizeof(struct vlan_hdr); + } + + if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4)) + get_fixed_ipv4_csum(hw_checksum, skb, hdr); +#if IS_ENABLED(CONFIG_IPV6) + else if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV6)) + if (get_fixed_ipv6_csum(hw_checksum, skb, hdr)) + return -1; +#endif + return 0; +} + int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) { struct mlx4_en_priv *priv = netdev_priv(dev); @@ -744,13 +828,26 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud (cqe->vlan_my_qpn & cpu_to_be32(MLX4_CQE_L2_TUNNEL)); if (likely(dev->features & NETIF_F_RXCSUM)) { - if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && - (cqe->checksum == cpu_to_be16(0xffff))) { - ring->csum_ok++; - ip_summed = CHECKSUM_UNNECESSARY; + if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP | + MLX4_CQE_STATUS_UDP)) { + if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && + cqe->checksum == cpu_to_be16(0xffff)) { + ip_summed = CHECKSUM_UNNECESSARY; + ring->csum_ok++; + } else { + ip_summed = CHECKSUM_NONE; + ring->csum_none++; + } } else { - ip_summed = CHECKSUM_NONE; - ring->csum_none++; + if (priv->flags & MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP && + (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 | + MLX4_CQE_STATUS_IPV6))) { + ip_summed = CHECKSUM_COMPLETE; + ring->csum_complete++; + } else { + ip_summed = CHECKSUM_NONE; + ring->csum_none++; + } } } else { ip_summed = CHECKSUM_NONE; @@ -776,6 +873,15 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud if (!nr) goto next; + if (ip_summed == CHECKSUM_COMPLETE) { + void *va = skb_frag_address(skb_shinfo(gro_skb)->frags); + if (check_csum(cqe, gro_skb, va, ring->hwtstamp_rx_filter)) { + ip_summed = CHECKSUM_NONE; + ring->csum_none++; + ring->csum_complete--; + } + } + skb_shinfo(gro_skb)->nr_frags = nr; gro_skb->len = length; gro_skb->data_len = length; @@ -822,6 +928,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud goto next; } + if (ip_summed == CHECKSUM_COMPLETE) { + if (check_csum(cqe, skb, skb->data, ring->hwtstamp_rx_filter)) { + ip_summed = CHECKSUM_NONE; + ring->csum_complete--; + ring->csum_none++; + } + } + skb->ip_summed = ip_summed; skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 9f821964a1b9..2f6ba420ac03 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1629,6 +1629,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) struct mlx4_init_hca_param init_hca; u64 icm_size; int err; + struct mlx4_config_dev_params params; if (!mlx4_is_slave(dev)) { err = mlx4_QUERY_FW(dev); @@ -1762,6 +1763,14 @@ static int mlx4_init_hca(struct mlx4_dev *dev) goto unmap_bf; } + /* Query CONFIG_DEV parameters */ + err = mlx4_config_dev_retrieval(dev, ¶ms); + if (err && err != -ENOTSUPP) { + mlx4_err(dev, "Failed to query CONFIG_DEV parameters\n"); + } else if (!err) { + dev->caps.rx_checksum_flags_port[1] = params.rx_csum_flags_port_1; + dev->caps.rx_checksum_flags_port[2] = params.rx_csum_flags_port_2; + } priv->eq_table.inta_pin = adapter.inta_pin; memcpy(dev->board_id, adapter.board_id, sizeof dev->board_id); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index ef83d127f406..de456749ffae 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -326,6 +326,7 @@ struct mlx4_en_rx_ring { #endif unsigned long csum_ok; unsigned long csum_none; + unsigned long csum_complete; int hwtstamp_rx_filter; cpumask_var_t affinity_mask; }; @@ -449,6 +450,7 @@ struct mlx4_en_port_stats { unsigned long rx_alloc_failed; unsigned long rx_chksum_good; unsigned long rx_chksum_none; + unsigned long rx_chksum_complete; unsigned long tx_chksum_offload; #define NUM_PORT_STATS 9 }; @@ -507,7 +509,8 @@ enum { MLX4_EN_FLAG_ENABLE_HW_LOOPBACK = (1 << 2), /* whether we need to drop packets that hardware loopback-ed */ MLX4_EN_FLAG_RX_FILTER_NEEDED = (1 << 3), - MLX4_EN_FLAG_FORCE_PROMISC = (1 << 4) + MLX4_EN_FLAG_FORCE_PROMISC = (1 << 4), + MLX4_EN_FLAG_RX_CSUM_NON_TCP_UDP = (1 << 5), }; #define MLX4_EN_MAC_HASH_SIZE (1 << BITS_PER_BYTE) diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 5cc5eac47d1b..3d9bff00f24a 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -497,6 +497,7 @@ struct mlx4_caps { u16 hca_core_clock; u64 phys_port_id[MLX4_MAX_PORTS + 1]; int tunnel_offload_mode; + u8 rx_checksum_flags_port[MLX4_MAX_PORTS + 1]; }; struct mlx4_buf_list { -- GitLab From a2ae6007a442d6bb27d77bf20ec1b06cda9e306e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 9 Nov 2014 16:32:46 -0800 Subject: [PATCH 4289/9457] dsa: Use netdev_ instead of printk Neaten and standardize the logging output. Other miscellanea: o Use pr_notice_once instead of a guard flag. o Convert existing pr_ uses too. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/dsa/dsa.c | 28 ++++++++++++---------------- net/dsa/slave.c | 10 +++++----- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index dd646a8025cb..4648f12098ad 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -192,12 +192,12 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, */ drv = dsa_switch_probe(host_dev, pd->sw_addr, &name); if (drv == NULL) { - printk(KERN_ERR "%s[%d]: could not detect attached switch\n", - dst->master_netdev->name, index); + netdev_err(dst->master_netdev, "[%d]: could not detect attached switch\n", + index); return ERR_PTR(-EINVAL); } - printk(KERN_INFO "%s[%d]: detected a %s switch\n", - dst->master_netdev->name, index, name); + netdev_info(dst->master_netdev, "[%d]: detected a %s switch\n", + index, name); /* @@ -225,7 +225,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, if (!strcmp(name, "cpu")) { if (dst->cpu_switch != -1) { - printk(KERN_ERR "multiple cpu ports?!\n"); + netdev_err(dst->master_netdev, + "multiple cpu ports?!\n"); ret = -EINVAL; goto out; } @@ -320,10 +321,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index, slave_dev = dsa_slave_create(ds, parent, i, pd->port_names[i]); if (slave_dev == NULL) { - printk(KERN_ERR "%s[%d]: can't create dsa " - "slave device for port %d(%s)\n", - dst->master_netdev->name, - index, i, pd->port_names[i]); + netdev_err(dst->master_netdev, "[%d]: can't create dsa slave device for port %d(%s)\n", + index, i, pd->port_names[i]); continue; } @@ -701,15 +700,13 @@ static inline void dsa_of_remove(struct platform_device *pdev) static int dsa_probe(struct platform_device *pdev) { - static int dsa_version_printed; struct dsa_platform_data *pd = pdev->dev.platform_data; struct net_device *dev; struct dsa_switch_tree *dst; int i, ret; - if (!dsa_version_printed++) - printk(KERN_NOTICE "Distributed Switch Architecture " - "driver version %s\n", dsa_driver_version); + pr_notice_once("Distributed Switch Architecture driver version %s\n", + dsa_driver_version); if (pdev->dev.of_node) { ret = dsa_of_probe(pdev); @@ -753,9 +750,8 @@ static int dsa_probe(struct platform_device *pdev) ds = dsa_switch_setup(dst, i, &pdev->dev, pd->chip[i].host_dev); if (IS_ERR(ds)) { - printk(KERN_ERR "%s[%d]: couldn't create dsa switch " - "instance (error %ld)\n", dev->name, i, - PTR_ERR(ds)); + netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n", + i, PTR_ERR(ds)); continue; } diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 0ea466dad818..528380a3e296 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -532,7 +532,7 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p, */ ret = of_phy_register_fixed_link(port_dn); if (ret) { - pr_err("failed to register fixed PHY\n"); + netdev_err(slave_dev, "failed to register fixed PHY\n"); return; } phy_is_fixed = true; @@ -558,8 +558,8 @@ static void dsa_slave_phy_setup(struct dsa_slave_priv *p, phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link, p->phy_interface); } else { - pr_info("attached PHY at address %d [%s]\n", - p->phy->addr, p->phy->drv->name); + netdev_info(slave_dev, "attached PHY at address %d [%s]\n", + p->phy->addr, p->phy->drv->name); } } @@ -657,8 +657,8 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent, ret = register_netdev(slave_dev); if (ret) { - printk(KERN_ERR "%s: error %d registering interface %s\n", - master->name, ret, slave_dev->name); + netdev_err(master, "error %d registering interface %s\n", + ret, slave_dev->name); free_netdev(slave_dev); return NULL; } -- GitLab From 5b61c4db49e2530ed10631321d4c73f49d560a93 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 10 Nov 2014 08:59:43 +0300 Subject: [PATCH 4290/9457] PPC: bpf_jit_comp: add SKF_AD_HATYPE instruction Add BPF extension SKF_AD_HATYPE to ppc JIT to check the hw type of the interface Before: [ 57.723666] test_bpf: #20 LD_HATYPE [ 57.723675] BPF filter opcode 0020 (@0) unsupported [ 57.724168] 48 48 PASS After: [ 103.053184] test_bpf: #20 LD_HATYPE 7 6 PASS CC: Alexei Starovoitov CC: Daniel Borkmann CC: Philippe Bergheaud Signed-off-by: Denis Kirjanov v2: address Alexei's comments Acked-by: Alexei Starovoitov Signed-off-by: David S. Miller --- arch/powerpc/net/bpf_jit_comp.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index d110e288d7ac..d3fa80d04e6b 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -361,6 +361,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, protocol)); break; case BPF_ANC | SKF_AD_IFINDEX: + case BPF_ANC | SKF_AD_HATYPE: + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + ifindex) != 4); + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + type) != 2); PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, dev)); PPC_CMPDI(r_scratch1, 0); @@ -368,14 +373,18 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); } else { /* Exit, returning 0; first pass hits here. */ - PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); + PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12); PPC_LI(r_ret, 0); PPC_JMP(exit_addr); } - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - ifindex) != 4); - PPC_LWZ_OFFS(r_A, r_scratch1, + if (code == (BPF_ANC | SKF_AD_IFINDEX)) { + PPC_LWZ_OFFS(r_A, r_scratch1, offsetof(struct net_device, ifindex)); + } else { + PPC_LHZ_OFFS(r_A, r_scratch1, + offsetof(struct net_device, type)); + } + break; case BPF_ANC | SKF_AD_MARK: BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); -- GitLab From ba7a46f16dd29f93303daeb1fee8af316c5a07f4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 11 Nov 2014 10:59:17 -0800 Subject: [PATCH 4291/9457] net: Convert LIMIT_NETDEBUG to net_dbg_ratelimited Use the more common dynamic_debug capable net_dbg_ratelimited and remove the LIMIT_NETDEBUG macro. All messages are still ratelimited. Some KERN_ uses are changed to KERN_DEBUG. This may have some negative impact on messages that were emitted at KERN_INFO that are not not enabled at all unless DEBUG is defined or dynamic_debug is enabled. Even so, these messages are now _not_ emitted by default. This also eliminates the use of the net_msg_warn sysctl "/proc/sys/net/core/warnings". For backward compatibility, the sysctl is not removed, but it has no function. The extern declaration of net_msg_warn is removed from sock.h and made static in net/core/sysctl_net_core.c Miscellanea: o Update the sysctl documentation o Remove the embedded uses of pr_fmt o Coalesce format fragments o Realign arguments Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- Documentation/sysctl/net.txt | 12 ++++++++---- include/net/sock.h | 7 ------- include/net/udplite.h | 6 +++--- net/core/sysctl_net_core.c | 2 ++ net/core/utils.c | 3 --- net/ipv4/icmp.c | 8 ++++---- net/ipv4/inet_fragment.c | 2 +- net/ipv4/ip_fragment.c | 3 +-- net/ipv4/tcp_input.c | 8 ++++---- net/ipv4/tcp_timer.c | 18 ++++++++++-------- net/ipv4/udp.c | 30 +++++++++++++++--------------- net/ipv6/addrconf.c | 6 ++---- net/ipv6/ah6.c | 7 +++---- net/ipv6/datagram.c | 4 ++-- net/ipv6/esp6.c | 4 ++-- net/ipv6/exthdrs.c | 18 +++++++++--------- net/ipv6/icmp.c | 15 +++++++-------- net/ipv6/mip6.c | 11 ++++++----- net/ipv6/netfilter.c | 2 +- net/ipv6/udp.c | 31 +++++++++++++------------------ net/phonet/af_phonet.c | 9 +++++---- net/phonet/pep-gprs.c | 3 +-- net/phonet/pep.c | 12 ++++++------ 23 files changed, 105 insertions(+), 116 deletions(-) diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index 04892b821157..e26c607468a6 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -120,10 +120,14 @@ seconds. warnings -------- -This controls console messages from the networking stack that can occur because -of problems on the network like duplicate address or bad checksums. Normally, -this should be enabled, but if the problem persists the messages can be -disabled. +This sysctl is now unused. + +This was used to control console messages from the networking stack that +occur because of problems on the network like duplicate address or bad +checksums. + +These messages are now emitted at KERN_DEBUG and can generally be enabled +and controlled by the dynamic_debug facility. netdev_budget ------------- diff --git a/include/net/sock.h b/include/net/sock.h index 7789b59c0c40..83a669f83bae 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2288,13 +2288,6 @@ bool sk_ns_capable(const struct sock *sk, bool sk_capable(const struct sock *sk, int cap); bool sk_net_capable(const struct sock *sk, int cap); -/* - * Enable debug/info messages - */ -extern int net_msg_warn; -#define LIMIT_NETDEBUG(fmt, args...) \ - do { if (net_msg_warn && net_ratelimit()) printk(fmt,##args); } while(0) - extern __u32 sysctl_wmem_max; extern __u32 sysctl_rmem_max; diff --git a/include/net/udplite.h b/include/net/udplite.h index 2caadabcd07b..9a28a5179400 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h @@ -40,7 +40,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) * checksum. UDP-Lite (like IPv6) mandates checksums, hence packets * with a zero checksum field are illegal. */ if (uh->check == 0) { - LIMIT_NETDEBUG(KERN_DEBUG "UDPLite: zeroed checksum field\n"); + net_dbg_ratelimited("UDPLite: zeroed checksum field\n"); return 1; } @@ -52,8 +52,8 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) /* * Coverage length violates RFC 3828: log and discard silently. */ - LIMIT_NETDEBUG(KERN_DEBUG "UDPLite: bad csum coverage %d/%d\n", - cscov, skb->len); + net_dbg_ratelimited("UDPLite: bad csum coverage %d/%d\n", + cscov, skb->len); return 1; } else if (cscov < skb->len) { diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index cf9cd13509a7..f93f092fe226 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -26,6 +26,8 @@ static int zero = 0; static int one = 1; static int ushort_max = USHRT_MAX; +static int net_msg_warn; /* Unused, but still a sysctl */ + #ifdef CONFIG_RPS static int rps_sock_flow_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) diff --git a/net/core/utils.c b/net/core/utils.c index efc76dd9dcd1..7b803884c162 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -33,9 +33,6 @@ #include #include -int net_msg_warn __read_mostly = 1; -EXPORT_SYMBOL(net_msg_warn); - DEFINE_RATELIMIT_STATE(net_ratelimit_state, 5 * HZ, 10); /* * All net warning printk()s should be guarded by this function. diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 5882f584910e..36b7bfa609d6 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -784,8 +784,8 @@ static void icmp_unreach(struct sk_buff *skb) */ switch (net->ipv4.sysctl_ip_no_pmtu_disc) { default: - LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"), - &iph->daddr); + net_dbg_ratelimited("%pI4: fragmentation needed and DF set\n", + &iph->daddr); break; case 2: goto out; @@ -798,8 +798,8 @@ static void icmp_unreach(struct sk_buff *skb) } break; case ICMP_SR_FAILED: - LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: Source Route Failed\n"), - &iph->daddr); + net_dbg_ratelimited("%pI4: Source Route Failed\n", + &iph->daddr); break; default: break; diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 19419b60cb37..e7920352646a 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -458,6 +458,6 @@ void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q, ". Dropping fragment.\n"; if (PTR_ERR(q) == -ENOBUFS) - LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg); + net_dbg_ratelimited("%s%s", prefix, msg); } EXPORT_SYMBOL(inet_frag_maybe_warn_overflow); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 4d964dadd655..e5b6d0ddcb58 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -618,8 +618,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, return 0; out_nomem: - LIMIT_NETDEBUG(KERN_ERR pr_fmt("queue_glue: no memory for gluing queue %p\n"), - qp); + net_dbg_ratelimited("queue_glue: no memory for gluing queue %p\n", qp); err = -ENOMEM; goto out_fail; out_oversize: diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5f979c7f5135..d91436ba17ea 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5854,12 +5854,12 @@ static inline void pr_drop_req(struct request_sock *req, __u16 port, int family) struct inet_request_sock *ireq = inet_rsk(req); if (family == AF_INET) - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("drop open request from %pI4/%u\n"), - &ireq->ir_rmt_addr, port); + net_dbg_ratelimited("drop open request from %pI4/%u\n", + &ireq->ir_rmt_addr, port); #if IS_ENABLED(CONFIG_IPV6) else if (family == AF_INET6) - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("drop open request from %pI6/%u\n"), - &ireq->ir_v6_rmt_addr, port); + net_dbg_ratelimited("drop open request from %pI6/%u\n", + &ireq->ir_v6_rmt_addr, port); #endif } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 9b21ae8b2e31..1829c7fbc77e 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -374,17 +374,19 @@ void tcp_retransmit_timer(struct sock *sk) */ struct inet_sock *inet = inet_sk(sk); if (sk->sk_family == AF_INET) { - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n"), - &inet->inet_daddr, - ntohs(inet->inet_dport), inet->inet_num, - tp->snd_una, tp->snd_nxt); + net_dbg_ratelimited("Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", + &inet->inet_daddr, + ntohs(inet->inet_dport), + inet->inet_num, + tp->snd_una, tp->snd_nxt); } #if IS_ENABLED(CONFIG_IPV6) else if (sk->sk_family == AF_INET6) { - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n"), - &sk->sk_v6_daddr, - ntohs(inet->inet_dport), inet->inet_num, - tp->snd_una, tp->snd_nxt); + net_dbg_ratelimited("Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", + &sk->sk_v6_daddr, + ntohs(inet->inet_dport), + inet->inet_num, + tp->snd_una, tp->snd_nxt); } #endif if (tcp_time_stamp - tp->rcv_tstamp > TCP_RTO_MAX) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d13751685f44..1b6e9d5fadef 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1051,7 +1051,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* ... which is an evident application bug. --ANK */ release_sock(sk); - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("cork app bug 2\n")); + net_dbg_ratelimited("cork app bug 2\n"); err = -EINVAL; goto out; } @@ -1133,7 +1133,7 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset, if (unlikely(!up->pending)) { release_sock(sk); - LIMIT_NETDEBUG(KERN_DEBUG pr_fmt("udp cork app bug 3\n")); + net_dbg_ratelimited("udp cork app bug 3\n"); return -EINVAL; } @@ -1547,8 +1547,8 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) * provided by the application." */ if (up->pcrlen == 0) { /* full coverage was set */ - LIMIT_NETDEBUG(KERN_WARNING "UDPLite: partial coverage %d while full coverage %d requested\n", - UDP_SKB_CB(skb)->cscov, skb->len); + net_dbg_ratelimited("UDPLite: partial coverage %d while full coverage %d requested\n", + UDP_SKB_CB(skb)->cscov, skb->len); goto drop; } /* The next case involves violating the min. coverage requested @@ -1558,8 +1558,8 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) * Therefore the above ...()->partial_cov statement is essential. */ if (UDP_SKB_CB(skb)->cscov < up->pcrlen) { - LIMIT_NETDEBUG(KERN_WARNING "UDPLite: coverage %d too small, need min %d\n", - UDP_SKB_CB(skb)->cscov, up->pcrlen); + net_dbg_ratelimited("UDPLite: coverage %d too small, need min %d\n", + UDP_SKB_CB(skb)->cscov, up->pcrlen); goto drop; } } @@ -1828,11 +1828,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, return 0; short_packet: - LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u\n", - proto == IPPROTO_UDPLITE ? "Lite" : "", - &saddr, ntohs(uh->source), - ulen, skb->len, - &daddr, ntohs(uh->dest)); + net_dbg_ratelimited("UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u\n", + proto == IPPROTO_UDPLITE ? "Lite" : "", + &saddr, ntohs(uh->source), + ulen, skb->len, + &daddr, ntohs(uh->dest)); goto drop; csum_error: @@ -1840,10 +1840,10 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, * RFC1122: OK. Discards the bad packet silently (as far as * the network is concerned, anyway) as per 4.1.3.4 (MUST). */ - LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n", - proto == IPPROTO_UDPLITE ? "Lite" : "", - &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest), - ulen); + net_dbg_ratelimited("UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n", + proto == IPPROTO_UDPLITE ? "Lite" : "", + &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest), + ulen); UDP_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE); drop: UDP_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 06e897832a7a..251fcb48b216 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1411,10 +1411,8 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev, if (unlikely(score->addr_type == IPV6_ADDR_ANY || score->addr_type & IPV6_ADDR_MULTICAST)) { - LIMIT_NETDEBUG(KERN_DEBUG - "ADDRCONF: unspecified / multicast address " - "assigned as unicast address on %s", - dev->name); + net_dbg_ratelimited("ADDRCONF: unspecified / multicast address assigned as unicast address on %s", + dev->name); continue; } diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 6d16eb0e0c7f..8ab1989198f6 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -272,10 +272,9 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir) ipv6_rearrange_destopt(iph, exthdr.opth); case NEXTHDR_HOP: if (!zero_out_mutable_opts(exthdr.opth)) { - LIMIT_NETDEBUG( - KERN_WARNING "overrun %sopts\n", - nexthdr == NEXTHDR_HOP ? - "hop" : "dest"); + net_dbg_ratelimited("overrun %sopts\n", + nexthdr == NEXTHDR_HOP ? + "hop" : "dest"); return -EINVAL; } break; diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 5c6996e44b14..cc1139687fd7 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -893,8 +893,8 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk, break; } default: - LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", - cmsg->cmsg_type); + net_dbg_ratelimited("invalid cmsg type: %d\n", + cmsg->cmsg_type); err = -EINVAL; goto exit_f; } diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index d21d7b22eebc..d2c2d749b6db 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -286,8 +286,8 @@ static int esp_input_done2(struct sk_buff *skb, int err) err = -EINVAL; padlen = nexthdr[0]; if (padlen + 2 + alen >= elen) { - LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage " - "padlen=%d, elen=%d\n", padlen + 2, elen - alen); + net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d\n", + padlen + 2, elen - alen); goto out; } diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 601d896f22d0..a7bbbe45570b 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -184,7 +184,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) int ret; if (opt->dsthao) { - LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n"); + net_dbg_ratelimited("hao duplicated\n"); goto discard; } opt->dsthao = opt->dst1; @@ -193,14 +193,14 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff); if (hao->length != 16) { - LIMIT_NETDEBUG( - KERN_DEBUG "hao invalid option length = %d\n", hao->length); + net_dbg_ratelimited("hao invalid option length = %d\n", + hao->length); goto discard; } if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) { - LIMIT_NETDEBUG( - KERN_DEBUG "hao is not an unicast addr: %pI6\n", &hao->addr); + net_dbg_ratelimited("hao is not an unicast addr: %pI6\n", + &hao->addr); goto discard; } @@ -551,8 +551,8 @@ static bool ipv6_hop_ra(struct sk_buff *skb, int optoff) memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra)); return true; } - LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", - nh[optoff + 1]); + net_dbg_ratelimited("ipv6_hop_ra: wrong RA length %d\n", + nh[optoff + 1]); kfree_skb(skb); return false; } @@ -566,8 +566,8 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff) u32 pkt_len; if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { - LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", - nh[optoff+1]); + net_dbg_ratelimited("ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", + nh[optoff+1]); IP6_INC_STATS_BH(net, ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); goto drop; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 62c1037d9e83..092934032077 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -338,7 +338,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, * anycast. */ if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { - LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: acast source\n"); + net_dbg_ratelimited("icmp6_send: acast source\n"); dst_release(dst); return ERR_PTR(-EINVAL); } @@ -452,7 +452,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) * and anycast addresses will be checked later. */ if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { - LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: addr_any/mcast source\n"); + net_dbg_ratelimited("icmp6_send: addr_any/mcast source\n"); return; } @@ -460,7 +460,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) * Never answer to a ICMP packet. */ if (is_ineligible(skb)) { - LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: no reply to icmp error\n"); + net_dbg_ratelimited("icmp6_send: no reply to icmp error\n"); return; } @@ -509,7 +509,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) len = skb->len - msg.offset; len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr)); if (len < 0) { - LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n"); + net_dbg_ratelimited("icmp: len problem\n"); goto out_dst_release; } @@ -706,9 +706,8 @@ static int icmpv6_rcv(struct sk_buff *skb) daddr = &ipv6_hdr(skb)->daddr; if (skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo)) { - LIMIT_NETDEBUG(KERN_DEBUG - "ICMPv6 checksum failed [%pI6c > %pI6c]\n", - saddr, daddr); + net_dbg_ratelimited("ICMPv6 checksum failed [%pI6c > %pI6c]\n", + saddr, daddr); goto csum_error; } @@ -781,7 +780,7 @@ static int icmpv6_rcv(struct sk_buff *skb) if (type & ICMPV6_INFOMSG_MASK) break; - LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n"); + net_dbg_ratelimited("icmpv6: msg of unknown type\n"); /* * error of unknown type. diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index f61429d391d3..b9779d441b12 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -97,16 +97,17 @@ static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) return -1; if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) { - LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n", - mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type)); + net_dbg_ratelimited("mip6: MH message too short: %d vs >=%d\n", + mh->ip6mh_hdrlen, + mip6_mh_len(mh->ip6mh_type)); mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_hdrlen) + skb_network_header_len(skb)); return -1; } if (mh->ip6mh_proto != IPPROTO_NONE) { - LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", - mh->ip6mh_proto); + net_dbg_ratelimited("mip6: MH invalid payload proto = %d\n", + mh->ip6mh_proto); mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_proto) + skb_network_header_len(skb)); return -1; @@ -288,7 +289,7 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb, * XXX: packet if HAO exists. */ if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) { - LIMIT_NETDEBUG(KERN_WARNING "mip6: hao exists already, override\n"); + net_dbg_ratelimited("mip6: hao exists already, override\n"); return offset; } diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index d38e6a8d8b9f..398377a9d018 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -36,7 +36,7 @@ int ip6_route_me_harder(struct sk_buff *skb) err = dst->error; if (err) { IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); - LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); + net_dbg_ratelimited("ip6_route_me_harder: No more route\n"); dst_release(dst); return err; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d1fe36274906..0ba3de4f2368 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -660,15 +660,13 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if ((is_udplite & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { if (up->pcrlen == 0) { /* full coverage was set */ - LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: partial coverage" - " %d while full coverage %d requested\n", - UDP_SKB_CB(skb)->cscov, skb->len); + net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", + UDP_SKB_CB(skb)->cscov, skb->len); goto drop; } if (UDP_SKB_CB(skb)->cscov < up->pcrlen) { - LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: coverage %d " - "too small, need min %d\n", - UDP_SKB_CB(skb)->cscov, up->pcrlen); + net_dbg_ratelimited("UDPLITE6: coverage %d too small, need min %d\n", + UDP_SKB_CB(skb)->cscov, up->pcrlen); goto drop; } } @@ -761,9 +759,9 @@ static void udp6_csum_zero_error(struct sk_buff *skb) /* RFC 2460 section 8.1 says that we SHOULD log * this error. Well, it is reasonable. */ - LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0 for [%pI6c]:%u->[%pI6c]:%u\n", - &ipv6_hdr(skb)->saddr, ntohs(udp_hdr(skb)->source), - &ipv6_hdr(skb)->daddr, ntohs(udp_hdr(skb)->dest)); + net_dbg_ratelimited("IPv6: udp checksum is 0 for [%pI6c]:%u->[%pI6c]:%u\n", + &ipv6_hdr(skb)->saddr, ntohs(udp_hdr(skb)->source), + &ipv6_hdr(skb)->daddr, ntohs(udp_hdr(skb)->dest)); } /* @@ -931,14 +929,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, return 0; short_packet: - LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n", - proto == IPPROTO_UDPLITE ? "-Lite" : "", - saddr, - ntohs(uh->source), - ulen, - skb->len, - daddr, - ntohs(uh->dest)); + net_dbg_ratelimited("UDP%sv6: short packet: From [%pI6c]:%u %d/%d to [%pI6c]:%u\n", + proto == IPPROTO_UDPLITE ? "-Lite" : "", + saddr, ntohs(uh->source), + ulen, skb->len, + daddr, ntohs(uh->dest)); goto discard; csum_error: UDP6_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE); @@ -1290,7 +1285,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, /* ... which is an evident application bug. --ANK */ release_sock(sk); - LIMIT_NETDEBUG(KERN_DEBUG "udp cork app bug 2\n"); + net_dbg_ratelimited("udp cork app bug 2\n"); err = -EINVAL; goto out; } diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 5a940dbd74a3..32ab87d34828 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -426,16 +426,17 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev, out_dev = phonet_route_output(net, pn_sockaddr_get_addr(&sa)); if (!out_dev) { - LIMIT_NETDEBUG(KERN_WARNING"No Phonet route to %02X\n", - pn_sockaddr_get_addr(&sa)); + net_dbg_ratelimited("No Phonet route to %02X\n", + pn_sockaddr_get_addr(&sa)); goto out; } __skb_push(skb, sizeof(struct phonethdr)); skb->dev = out_dev; if (out_dev == dev) { - LIMIT_NETDEBUG(KERN_ERR"Phonet loop to %02X on %s\n", - pn_sockaddr_get_addr(&sa), dev->name); + net_dbg_ratelimited("Phonet loop to %02X on %s\n", + pn_sockaddr_get_addr(&sa), + dev->name); goto out_dev; } /* Some drivers (e.g. TUN) do not allocate HW header space */ diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c index e9a83a637185..fa8237fdc57b 100644 --- a/net/phonet/pep-gprs.c +++ b/net/phonet/pep-gprs.c @@ -203,8 +203,7 @@ static netdev_tx_t gprs_xmit(struct sk_buff *skb, struct net_device *dev) len = skb->len; err = pep_write(sk, skb); if (err) { - LIMIT_NETDEBUG(KERN_WARNING"%s: TX error (%d)\n", - dev->name, err); + net_dbg_ratelimited("%s: TX error (%d)\n", dev->name, err); dev->stats.tx_aborted_errors++; dev->stats.tx_errors++; } else { diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 44b2123e22b8..9cd069dfaf65 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -272,8 +272,8 @@ static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) hdr = pnp_hdr(skb); if (hdr->data[0] != PN_PEP_TYPE_COMMON) { - LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", - (unsigned int)hdr->data[0]); + net_dbg_ratelimited("Phonet unknown PEP type: %u\n", + (unsigned int)hdr->data[0]); return -EOPNOTSUPP; } @@ -304,8 +304,8 @@ static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) break; default: - LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP indication: %u\n", - (unsigned int)hdr->data[1]); + net_dbg_ratelimited("Phonet unknown PEP indication: %u\n", + (unsigned int)hdr->data[1]); return -EOPNOTSUPP; } if (wake) @@ -451,8 +451,8 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) break; default: - LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP message: %u\n", - hdr->message_id); + net_dbg_ratelimited("Phonet unknown PEP message: %u\n", + hdr->message_id); err = -EINVAL; } out: -- GitLab From b2e2f0c779fefede3a871781c8827bd8e76c7c0f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 10 Nov 2014 12:38:59 +0200 Subject: [PATCH 4292/9457] stmmac: split to core library and probe drivers Instead of registering the platform and PCI drivers in one module let's move necessary bits to where it belongs. During this procedure we convert the module registration part to use module_*_driver() macros which makes code simplier. >From now on the driver consists three parts: core library, PCI, and platform drivers. Signed-off-by: Andy Shevchenko Acked-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/Kconfig | 4 +- drivers/net/ethernet/stmicro/stmmac/Makefile | 15 +++-- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 61 ------------------- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 36 ++--------- .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +- .../ethernet/stmicro/stmmac/stmmac_platform.c | 13 ++-- 6 files changed, 25 insertions(+), 108 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 33b85bae6c21..7d3af190be55 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -14,7 +14,7 @@ config STMMAC_ETH if STMMAC_ETH config STMMAC_PLATFORM - bool "STMMAC Platform bus support" + tristate "STMMAC Platform bus support" depends on STMMAC_ETH default y ---help--- @@ -27,7 +27,7 @@ config STMMAC_PLATFORM If unsure, say N. config STMMAC_PCI - bool "STMMAC PCI bus support" + tristate "STMMAC PCI bus support" depends on STMMAC_ETH && PCI ---help--- This is to select the Synopsys DWMAC available on PCI devices, diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 034da704f22f..ac4d5629d905 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -1,9 +1,12 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o -stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o -stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o dwmac-meson.o \ - dwmac-sunxi.o dwmac-sti.o \ - dwmac-socfpga.o stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ - chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ - dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ + chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ + dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y) + +obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o +stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \ + dwmac-sti.o dwmac-socfpga.o + +obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o +stmmac-pci-objs:= stmmac_pci.o diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index bd75ee8b2757..c0a391983372 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -134,65 +134,4 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, void stmmac_disable_eee_mode(struct stmmac_priv *priv); bool stmmac_eee_init(struct stmmac_priv *priv); -#ifdef CONFIG_STMMAC_PLATFORM -extern struct platform_driver stmmac_pltfr_driver; - -static inline int stmmac_register_platform(void) -{ - int err; - - err = platform_driver_register(&stmmac_pltfr_driver); - if (err) - pr_err("stmmac: failed to register the platform driver\n"); - - return err; -} - -static inline void stmmac_unregister_platform(void) -{ - platform_driver_unregister(&stmmac_pltfr_driver); -} -#else -static inline int stmmac_register_platform(void) -{ - pr_debug("stmmac: do not register the platf driver\n"); - - return 0; -} - -static inline void stmmac_unregister_platform(void) -{ -} -#endif /* CONFIG_STMMAC_PLATFORM */ - -#ifdef CONFIG_STMMAC_PCI -extern struct pci_driver stmmac_pci_driver; -static inline int stmmac_register_pci(void) -{ - int err; - - err = pci_register_driver(&stmmac_pci_driver); - if (err) - pr_err("stmmac: failed to register the PCI driver\n"); - - return err; -} - -static inline void stmmac_unregister_pci(void) -{ - pci_unregister_driver(&stmmac_pci_driver); -} -#else -static inline int stmmac_register_pci(void) -{ - pr_debug("stmmac: do not register the PCI driver\n"); - - return 0; -} - -static inline void stmmac_unregister_pci(void) -{ -} -#endif /* CONFIG_STMMAC_PCI */ - #endif /* __STMMAC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 53db11b29e61..0f1c146fcce1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2885,6 +2885,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, return ERR_PTR(ret); } +EXPORT_SYMBOL_GPL(stmmac_dvr_probe); /** * stmmac_dvr_remove @@ -2914,8 +2915,8 @@ int stmmac_dvr_remove(struct net_device *ndev) return 0; } +EXPORT_SYMBOL_GPL(stmmac_dvr_remove); -#ifdef CONFIG_PM int stmmac_suspend(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); @@ -2957,6 +2958,7 @@ int stmmac_suspend(struct net_device *ndev) priv->oldduplex = -1; return 0; } +EXPORT_SYMBOL_GPL(stmmac_suspend); int stmmac_resume(struct net_device *ndev) { @@ -3003,37 +3005,7 @@ int stmmac_resume(struct net_device *ndev) return 0; } -#endif /* CONFIG_PM */ - -/* Driver can be configured w/ and w/ both PCI and Platf drivers - * depending on the configuration selected. - */ -static int __init stmmac_init(void) -{ - int ret; - - ret = stmmac_register_platform(); - if (ret) - goto err; - ret = stmmac_register_pci(); - if (ret) - goto err_pci; - return 0; -err_pci: - stmmac_unregister_platform(); -err: - pr_err("stmmac: driver registration failed\n"); - return ret; -} - -static void __exit stmmac_exit(void) -{ - stmmac_unregister_platform(); - stmmac_unregister_pci(); -} - -module_init(stmmac_init); -module_exit(stmmac_exit); +EXPORT_SYMBOL_GPL(stmmac_resume); #ifndef MODULE static int __init stmmac_cmdline_opt(char *str) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 5084699baeab..77a6d68f7189 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -158,7 +158,7 @@ static const struct pci_device_id stmmac_id_table[] = { MODULE_DEVICE_TABLE(pci, stmmac_id_table); -struct pci_driver stmmac_pci_driver = { +static struct pci_driver stmmac_pci_driver = { .name = STMMAC_RESOURCE_NAME, .id_table = stmmac_id_table, .probe = stmmac_pci_probe, @@ -168,6 +168,8 @@ struct pci_driver stmmac_pci_driver = { }, }; +module_pci_driver(stmmac_pci_driver); + MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); MODULE_AUTHOR("Rayagond Kokatanur "); MODULE_AUTHOR("Giuseppe Cavallaro "); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 9f18401022e1..e22a960f8bd7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -362,7 +362,7 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) return ret; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int stmmac_pltfr_suspend(struct device *dev) { int ret; @@ -388,13 +388,12 @@ static int stmmac_pltfr_resume(struct device *dev) return stmmac_resume(ndev); } - -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, - stmmac_pltfr_suspend, stmmac_pltfr_resume); + stmmac_pltfr_suspend, stmmac_pltfr_resume); -struct platform_driver stmmac_pltfr_driver = { +static struct platform_driver stmmac_pltfr_driver = { .probe = stmmac_pltfr_probe, .remove = stmmac_pltfr_remove, .driver = { @@ -402,9 +401,11 @@ struct platform_driver stmmac_pltfr_driver = { .owner = THIS_MODULE, .pm = &stmmac_pltfr_pm_ops, .of_match_table = of_match_ptr(stmmac_dt_ids), - }, + }, }; +module_platform_driver(stmmac_pltfr_driver); + MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver"); MODULE_AUTHOR("Giuseppe Cavallaro "); MODULE_LICENSE("GPL"); -- GitLab From d7480fd3b1738a8eae6a76098b17af318cf9b9cc Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Mon, 10 Nov 2014 15:59:36 -0800 Subject: [PATCH 4293/9457] neigh: remove dynamic neigh table registration support Currently there are only three neigh tables in the whole kernel: arp table, ndisc table and decnet neigh table. What's more, we don't support registering multiple tables per family. Therefore we can just make these tables statically built-in. Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- include/net/neighbour.h | 11 +- net/core/neighbour.c | 247 ++++++++++++++++++---------------------- net/decnet/dn_neigh.c | 4 +- net/ipv4/arp.c | 2 +- net/ipv6/ndisc.c | 4 +- 5 files changed, 126 insertions(+), 142 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index dedfb188b1a7..eb070b3674a1 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -220,6 +220,13 @@ struct neigh_table { struct pneigh_entry **phash_buckets; }; +enum { + NEIGH_ARP_TABLE = 0, + NEIGH_ND_TABLE = 1, + NEIGH_DN_TABLE = 2, + NEIGH_NR_TABLES, +}; + static inline int neigh_parms_family(struct neigh_parms *p) { return p->tbl->family; @@ -240,8 +247,8 @@ static inline void *neighbour_priv(const struct neighbour *n) #define NEIGH_UPDATE_F_ISROUTER 0x40000000 #define NEIGH_UPDATE_F_ADMIN 0x80000000 -void neigh_table_init(struct neigh_table *tbl); -int neigh_table_clear(struct neigh_table *tbl); +void neigh_table_init(int index, struct neigh_table *tbl); +int neigh_table_clear(int index, struct neigh_table *tbl); struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev); struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, diff --git a/net/core/neighbour.c b/net/core/neighbour.c index edd04116ecb7..8e38f17288d3 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -56,7 +56,6 @@ static void __neigh_notify(struct neighbour *n, int type, int flags); static void neigh_update_notify(struct neighbour *neigh); static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev); -static struct neigh_table *neigh_tables; #ifdef CONFIG_PROC_FS static const struct file_operations neigh_stat_seq_fops; #endif @@ -87,13 +86,8 @@ static const struct file_operations neigh_stat_seq_fops; the most complicated procedure, which we allow is dev->hard_header. It is supposed, that dev->hard_header is simplistic and does not make callbacks to neighbour tables. - - The last lock is neigh_tbl_lock. It is pure SMP lock, protecting - list of neighbour tables. This list is used only in process context, */ -static DEFINE_RWLOCK(neigh_tbl_lock); - static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb) { kfree_skb(skb); @@ -1520,7 +1514,9 @@ static void neigh_parms_destroy(struct neigh_parms *parms) static struct lock_class_key neigh_table_proxy_queue_class; -static void neigh_table_init_no_netlink(struct neigh_table *tbl) +static struct neigh_table *neigh_tables[NEIGH_NR_TABLES] __read_mostly; + +void neigh_table_init(int index, struct neigh_table *tbl) { unsigned long now = jiffies; unsigned long phsize; @@ -1566,34 +1562,14 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl) tbl->last_flush = now; tbl->last_rand = now + tbl->parms.reachable_time * 20; -} - -void neigh_table_init(struct neigh_table *tbl) -{ - struct neigh_table *tmp; - neigh_table_init_no_netlink(tbl); - write_lock(&neigh_tbl_lock); - for (tmp = neigh_tables; tmp; tmp = tmp->next) { - if (tmp->family == tbl->family) - break; - } - tbl->next = neigh_tables; - neigh_tables = tbl; - write_unlock(&neigh_tbl_lock); - - if (unlikely(tmp)) { - pr_err("Registering multiple tables for family %d\n", - tbl->family); - dump_stack(); - } + neigh_tables[index] = tbl; } EXPORT_SYMBOL(neigh_table_init); -int neigh_table_clear(struct neigh_table *tbl) +int neigh_table_clear(int index, struct neigh_table *tbl) { - struct neigh_table **tp; - + neigh_tables[index] = NULL; /* It is not clean... Fix it to unload IPv6 module safely */ cancel_delayed_work_sync(&tbl->gc_work); del_timer_sync(&tbl->proxy_timer); @@ -1601,14 +1577,6 @@ int neigh_table_clear(struct neigh_table *tbl) neigh_ifdown(tbl, NULL); if (atomic_read(&tbl->entries)) pr_crit("neighbour leakage\n"); - write_lock(&neigh_tbl_lock); - for (tp = &neigh_tables; *tp; tp = &(*tp)->next) { - if (*tp == tbl) { - *tp = tbl->next; - break; - } - } - write_unlock(&neigh_tbl_lock); call_rcu(&rcu_dereference_protected(tbl->nht, 1)->rcu, neigh_hash_free_rcu); @@ -1626,12 +1594,32 @@ int neigh_table_clear(struct neigh_table *tbl) } EXPORT_SYMBOL(neigh_table_clear); +static struct neigh_table *neigh_find_table(int family) +{ + struct neigh_table *tbl = NULL; + + switch (family) { + case AF_INET: + tbl = neigh_tables[NEIGH_ARP_TABLE]; + break; + case AF_INET6: + tbl = neigh_tables[NEIGH_ND_TABLE]; + break; + case AF_DECnet: + tbl = neigh_tables[NEIGH_DN_TABLE]; + break; + } + + return tbl; +} + static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *dst_attr; struct neigh_table *tbl; + struct neighbour *neigh; struct net_device *dev = NULL; int err = -EINVAL; @@ -1652,39 +1640,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh) } } - read_lock(&neigh_tbl_lock); - for (tbl = neigh_tables; tbl; tbl = tbl->next) { - struct neighbour *neigh; - - if (tbl->family != ndm->ndm_family) - continue; - read_unlock(&neigh_tbl_lock); - - if (nla_len(dst_attr) < tbl->key_len) - goto out; + tbl = neigh_find_table(ndm->ndm_family); + if (tbl == NULL) + return -EAFNOSUPPORT; - if (ndm->ndm_flags & NTF_PROXY) { - err = pneigh_delete(tbl, net, nla_data(dst_attr), dev); - goto out; - } + if (nla_len(dst_attr) < tbl->key_len) + goto out; - if (dev == NULL) - goto out; + if (ndm->ndm_flags & NTF_PROXY) { + err = pneigh_delete(tbl, net, nla_data(dst_attr), dev); + goto out; + } - neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); - if (neigh == NULL) { - err = -ENOENT; - goto out; - } + if (dev == NULL) + goto out; - err = neigh_update(neigh, NULL, NUD_FAILED, - NEIGH_UPDATE_F_OVERRIDE | - NEIGH_UPDATE_F_ADMIN); - neigh_release(neigh); + neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); + if (neigh == NULL) { + err = -ENOENT; goto out; } - read_unlock(&neigh_tbl_lock); - err = -EAFNOSUPPORT; + + err = neigh_update(neigh, NULL, NUD_FAILED, + NEIGH_UPDATE_F_OVERRIDE | + NEIGH_UPDATE_F_ADMIN); + neigh_release(neigh); out: return err; @@ -1692,11 +1672,14 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh) static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh) { + int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE; struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct neigh_table *tbl; struct net_device *dev = NULL; + struct neighbour *neigh; + void *dst, *lladdr; int err; ASSERT_RTNL(); @@ -1720,70 +1703,60 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh) goto out; } - read_lock(&neigh_tbl_lock); - for (tbl = neigh_tables; tbl; tbl = tbl->next) { - int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE; - struct neighbour *neigh; - void *dst, *lladdr; + tbl = neigh_find_table(ndm->ndm_family); + if (tbl == NULL) + return -EAFNOSUPPORT; - if (tbl->family != ndm->ndm_family) - continue; - read_unlock(&neigh_tbl_lock); + if (nla_len(tb[NDA_DST]) < tbl->key_len) + goto out; + dst = nla_data(tb[NDA_DST]); + lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; - if (nla_len(tb[NDA_DST]) < tbl->key_len) - goto out; - dst = nla_data(tb[NDA_DST]); - lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; + if (ndm->ndm_flags & NTF_PROXY) { + struct pneigh_entry *pn; + + err = -ENOBUFS; + pn = pneigh_lookup(tbl, net, dst, dev, 1); + if (pn) { + pn->flags = ndm->ndm_flags; + err = 0; + } + goto out; + } - if (ndm->ndm_flags & NTF_PROXY) { - struct pneigh_entry *pn; + if (dev == NULL) + goto out; - err = -ENOBUFS; - pn = pneigh_lookup(tbl, net, dst, dev, 1); - if (pn) { - pn->flags = ndm->ndm_flags; - err = 0; - } + neigh = neigh_lookup(tbl, dst, dev); + if (neigh == NULL) { + if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { + err = -ENOENT; goto out; } - if (dev == NULL) + neigh = __neigh_lookup_errno(tbl, dst, dev); + if (IS_ERR(neigh)) { + err = PTR_ERR(neigh); + goto out; + } + } else { + if (nlh->nlmsg_flags & NLM_F_EXCL) { + err = -EEXIST; + neigh_release(neigh); goto out; - - neigh = neigh_lookup(tbl, dst, dev); - if (neigh == NULL) { - if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { - err = -ENOENT; - goto out; - } - - neigh = __neigh_lookup_errno(tbl, dst, dev); - if (IS_ERR(neigh)) { - err = PTR_ERR(neigh); - goto out; - } - } else { - if (nlh->nlmsg_flags & NLM_F_EXCL) { - err = -EEXIST; - neigh_release(neigh); - goto out; - } - - if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) - flags &= ~NEIGH_UPDATE_F_OVERRIDE; } - if (ndm->ndm_flags & NTF_USE) { - neigh_event_send(neigh, NULL); - err = 0; - } else - err = neigh_update(neigh, lladdr, ndm->ndm_state, flags); - neigh_release(neigh); - goto out; + if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) + flags &= ~NEIGH_UPDATE_F_OVERRIDE; } - read_unlock(&neigh_tbl_lock); - err = -EAFNOSUPPORT; + if (ndm->ndm_flags & NTF_USE) { + neigh_event_send(neigh, NULL); + err = 0; + } else + err = neigh_update(neigh, lladdr, ndm->ndm_state, flags); + neigh_release(neigh); + out: return err; } @@ -1982,7 +1955,8 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) struct neigh_table *tbl; struct ndtmsg *ndtmsg; struct nlattr *tb[NDTA_MAX+1]; - int err; + bool found = false; + int err, tidx; err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX, nl_neightbl_policy); @@ -1995,19 +1969,21 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) } ndtmsg = nlmsg_data(nlh); - read_lock(&neigh_tbl_lock); - for (tbl = neigh_tables; tbl; tbl = tbl->next) { + + for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) { + tbl = neigh_tables[tidx]; + if (!tbl) + continue; if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family) continue; - - if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) + if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) { + found = true; break; + } } - if (tbl == NULL) { - err = -ENOENT; - goto errout_locked; - } + if (!found) + return -ENOENT; /* * We acquire tbl->lock to be nice to the periodic timers and @@ -2118,8 +2094,6 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) errout_tbl_lock: write_unlock_bh(&tbl->lock); -errout_locked: - read_unlock(&neigh_tbl_lock); errout: return err; } @@ -2134,10 +2108,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; - read_lock(&neigh_tbl_lock); - for (tbl = neigh_tables, tidx = 0; tbl; tbl = tbl->next, tidx++) { + for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) { struct neigh_parms *p; + tbl = neigh_tables[tidx]; + if (!tbl) + continue; + if (tidx < tbl_skip || (family && tbl->family != family)) continue; @@ -2168,7 +2145,6 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) neigh_skip = 0; } out: - read_unlock(&neigh_tbl_lock); cb->args[0] = tidx; cb->args[1] = nidx; @@ -2351,7 +2327,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) int proxy = 0; int err; - read_lock(&neigh_tbl_lock); family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; /* check for full ndmsg structure presence, family member is @@ -2363,8 +2338,11 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) s_t = cb->args[0]; - for (tbl = neigh_tables, t = 0; tbl; - tbl = tbl->next, t++) { + for (t = 0; t < NEIGH_NR_TABLES; t++) { + tbl = neigh_tables[t]; + + if (!tbl) + continue; if (t < s_t || (family && tbl->family != family)) continue; if (t > s_t) @@ -2377,7 +2355,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) if (err < 0) break; } - read_unlock(&neigh_tbl_lock); cb->args[0] = t; return skb->len; diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index c8121ceddb9e..7ca7c3143da3 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -591,7 +591,7 @@ static const struct file_operations dn_neigh_seq_fops = { void __init dn_neigh_init(void) { - neigh_table_init(&dn_neigh_table); + neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table); proc_create("decnet_neigh", S_IRUGO, init_net.proc_net, &dn_neigh_seq_fops); } @@ -599,5 +599,5 @@ void __init dn_neigh_init(void) void __exit dn_neigh_cleanup(void) { remove_proc_entry("decnet_neigh", init_net.proc_net); - neigh_table_clear(&dn_neigh_table); + neigh_table_clear(NEIGH_DN_TABLE, &dn_neigh_table); } diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 16acb59d665e..205e1472aa78 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1292,7 +1292,7 @@ static int arp_proc_init(void); void __init arp_init(void) { - neigh_table_init(&arp_tbl); + neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl); dev_add_pack(&arp_packet_type); arp_proc_init(); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 4cb45c1079a2..2c9f6bf57325 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1763,7 +1763,7 @@ int __init ndisc_init(void) /* * Initialize the neighbour table */ - neigh_table_init(&nd_tbl); + neigh_table_init(NEIGH_ND_TABLE, &nd_tbl); #ifdef CONFIG_SYSCTL err = neigh_sysctl_register(NULL, &nd_tbl.parms, @@ -1796,6 +1796,6 @@ void ndisc_cleanup(void) #ifdef CONFIG_SYSCTL neigh_sysctl_unregister(&nd_tbl.parms); #endif - neigh_table_clear(&nd_tbl); + neigh_table_clear(NEIGH_ND_TABLE, &nd_tbl); unregister_pernet_subsys(&ndisc_net_ops); } -- GitLab From ebd25caf7d511312d1a9724ab5752e9e661dfe60 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 9 Nov 2014 18:32:03 +0800 Subject: [PATCH 4294/9457] arch: tile: gxio: Export symbols for module using in 'mpipe.c' 'gxio_mpipe_adjust_timestamp', 'gxio_mpipe_link_instance', 'gxio_mpipe_get_timestamp', and 'gxio_mpipe_set_timestamp' may be use by other tile modules, so export them. The related error (with allmodconfig under tile): MODPOST 4002 modules ERROR: "gxio_mpipe_link_instance" [drivers/net/ethernet/tile/tile_net.ko] undefined! ERROR: "gxio_mpipe_get_timestamp" [drivers/net/ethernet/tile/tile_net.ko] undefined! ERROR: "gxio_mpipe_set_timestamp" [drivers/net/ethernet/tile/tile_net.ko] undefined! ERROR: "gxio_mpipe_adjust_timestamp" [drivers/net/ethernet/tile/tile_net.ko] undefined! Signed-off-by: Chen Gang Signed-off-by: Chris Metcalf --- arch/tile/gxio/mpipe.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/tile/gxio/mpipe.c b/arch/tile/gxio/mpipe.c index 320ff5e6e61e..6f00e9850636 100644 --- a/arch/tile/gxio/mpipe.c +++ b/arch/tile/gxio/mpipe.c @@ -463,6 +463,7 @@ int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context, (uint64_t)ts->tv_nsec, (uint64_t)cycles); } +EXPORT_SYMBOL_GPL(gxio_mpipe_set_timestamp); int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context, struct timespec *ts) @@ -485,11 +486,13 @@ int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context, } return ret; } +EXPORT_SYMBOL_GPL(gxio_mpipe_get_timestamp); int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, int64_t delta) { return gxio_mpipe_adjust_timestamp_aux(context, delta); } +EXPORT_SYMBOL_GPL(gxio_mpipe_adjust_timestamp); /* Get our internal context used for link name access. This context is * special in that it is not associated with an mPIPE service domain. @@ -542,6 +545,7 @@ int gxio_mpipe_link_instance(const char *link_name) return gxio_mpipe_info_instance_aux(context, name); } +EXPORT_SYMBOL_GPL(gxio_mpipe_link_instance); int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac) { -- GitLab From 74b51ee152b6d99e61ba329799a039453fb9438f Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Sun, 9 Nov 2014 13:53:37 +0400 Subject: [PATCH 4295/9457] ACPI / osl: speedup grace period in acpi_os_map_cleanup ACPI maintains cache of ioremap regions to speed up operations and access to them from irq context where ioremap() calls aren't allowed. This code abuses synchronize_rcu() on unmap path for synchronization with fast-path in acpi_os_read/write_memory which uses this cache. Since v3.10 CPUs are allowed to enter idle state even if they have RCU callbacks queued, see commit c0f4dfd4f90f1667d234d21f15153ea09a2eaa66 ("rcu: Make RCU_FAST_NO_HZ take advantage of numbered callbacks"). That change caused problems with nvidia proprietary driver which calls acpi_os_map/unmap_generic_address several times during initialization. Each unmap calls synchronize_rcu and adds significant delay. Totally initialization is slowed for a couple of seconds and that is enough to trigger timeout in hardware, gpu decides to "fell off the bus". Widely spread workaround is reducing "rcu_idle_gp_delay" from 4 to 1 jiffy. This patch replaces synchronize_rcu() with synchronize_rcu_expedited() which is much faster. Link: https://devtalk.nvidia.com/default/topic/567297/linux/linux-3-10-driver-crash/ Signed-off-by: Konstantin Khlebnikov Reported-and-tested-by: Alexander Monakov Reviewed-by: Paul E. McKenney Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 9964f70be98d..217713c11aaa 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -436,7 +436,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map) static void acpi_os_map_cleanup(struct acpi_ioremap *map) { if (!map->refcount) { - synchronize_rcu(); + synchronize_rcu_expedited(); acpi_unmap(map->phys, map->virt); kfree(map); } -- GitLab From f47436734dc89ece62654d4db8d08163a89dd7ca Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 31 Oct 2014 10:50:46 -0700 Subject: [PATCH 4296/9457] tile: Use the more common pr_warn instead of pr_warning And other message logging neatening. Other miscellanea: o coalesce formats o realign arguments o standardize a couple of macros o use __func__ instead of embedding the function name Signed-off-by: Joe Perches Signed-off-by: Chris Metcalf --- arch/tile/include/asm/io.h | 5 +- arch/tile/include/asm/pgtable.h | 4 +- arch/tile/include/asm/pgtable_64.h | 2 +- arch/tile/kernel/hardwall.c | 6 +- arch/tile/kernel/irq.c | 5 +- arch/tile/kernel/kprobes.c | 3 +- arch/tile/kernel/machine_kexec.c | 28 ++++----- arch/tile/kernel/messaging.c | 5 +- arch/tile/kernel/module.c | 12 ++-- arch/tile/kernel/pci.c | 7 +-- arch/tile/kernel/pci_gx.c | 95 ++++++++++++------------------ arch/tile/kernel/process.c | 16 +++-- arch/tile/kernel/setup.c | 36 +++++------ arch/tile/kernel/signal.c | 6 +- arch/tile/kernel/single_step.c | 6 +- arch/tile/kernel/smpboot.c | 5 +- arch/tile/kernel/stack.c | 7 +-- arch/tile/kernel/time.c | 4 +- arch/tile/kernel/traps.c | 10 ++-- arch/tile/kernel/unaligned.c | 22 ++++--- arch/tile/mm/fault.c | 34 +++++------ arch/tile/mm/homecache.c | 6 +- arch/tile/mm/hugetlbpage.c | 18 +++--- arch/tile/mm/init.c | 32 ++++------ arch/tile/mm/pgtable.c | 4 +- 25 files changed, 158 insertions(+), 220 deletions(-) diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index 9fe434969fab..4353539fb887 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h @@ -392,8 +392,7 @@ extern void ioport_unmap(void __iomem *addr); static inline long ioport_panic(void) { #ifdef __tilegx__ - panic("PCI IO space support is disabled. Configure the kernel with" - " CONFIG_TILE_PCI_IO to enable it"); + panic("PCI IO space support is disabled. Configure the kernel with CONFIG_TILE_PCI_IO to enable it"); #else panic("inb/outb and friends do not exist on tile"); #endif @@ -402,7 +401,7 @@ static inline long ioport_panic(void) static inline void __iomem *ioport_map(unsigned long port, unsigned int len) { - pr_info("ioport_map: mapping IO resources is unsupported on tile.\n"); + pr_info("ioport_map: mapping IO resources is unsupported on tile\n"); return NULL; } diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index 33587f16c152..5d1950788c69 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h @@ -235,9 +235,9 @@ static inline void __pte_clear(pte_t *ptep) #define pte_donemigrate(x) hv_pte_set_present(hv_pte_clear_migrating(x)) #define pte_ERROR(e) \ - pr_err("%s:%d: bad pte 0x%016llx.\n", __FILE__, __LINE__, pte_val(e)) + pr_err("%s:%d: bad pte 0x%016llx\n", __FILE__, __LINE__, pte_val(e)) #define pgd_ERROR(e) \ - pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) + pr_err("%s:%d: bad pgd 0x%016llx\n", __FILE__, __LINE__, pgd_val(e)) /* Return PA and protection info for a given kernel VA. */ int va_to_cpa_and_pte(void *va, phys_addr_t *cpa, pte_t *pte); diff --git a/arch/tile/include/asm/pgtable_64.h b/arch/tile/include/asm/pgtable_64.h index 2c8a9cd102d3..e96cec52f6d8 100644 --- a/arch/tile/include/asm/pgtable_64.h +++ b/arch/tile/include/asm/pgtable_64.h @@ -86,7 +86,7 @@ static inline int pud_huge_page(pud_t pud) } #define pmd_ERROR(e) \ - pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e)) + pr_err("%s:%d: bad pmd 0x%016llx\n", __FILE__, __LINE__, pmd_val(e)) static inline void pud_clear(pud_t *pudp) { diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index aca6000bca75..c4646bb99342 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c @@ -365,8 +365,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) * to quiesce. */ if (rect->teardown_in_progress) { - pr_notice("cpu %d: detected %s hardwall violation %#lx" - " while teardown already in progress\n", + pr_notice("cpu %d: detected %s hardwall violation %#lx while teardown already in progress\n", cpu, hwt->name, (long)mfspr_XDN(hwt, DIRECTION_PROTECT)); goto done; @@ -630,8 +629,7 @@ static void _hardwall_deactivate(struct hardwall_type *hwt, struct thread_struct *ts = &task->thread; if (cpumask_weight(&task->cpus_allowed) != 1) { - pr_err("pid %d (%s) releasing %s hardwall with" - " an affinity mask containing %d cpus!\n", + pr_err("pid %d (%s) releasing %s hardwall with an affinity mask containing %d cpus!\n", task->pid, task->comm, hwt->name, cpumask_weight(&task->cpus_allowed)); BUG(); diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index ba85765e1436..22044fc691ef 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c @@ -107,9 +107,8 @@ void tile_dev_intr(struct pt_regs *regs, int intnum) { long sp = stack_pointer - (long) current_thread_info(); if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { - pr_emerg("tile_dev_intr: " - "stack overflow: %ld\n", - sp - sizeof(struct thread_info)); + pr_emerg("%s: stack overflow: %ld\n", + __func__, sp - sizeof(struct thread_info)); dump_stack(); } } diff --git a/arch/tile/kernel/kprobes.c b/arch/tile/kernel/kprobes.c index 27cdcacbe81d..f8a45c51e9e4 100644 --- a/arch/tile/kernel/kprobes.c +++ b/arch/tile/kernel/kprobes.c @@ -90,8 +90,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return -EINVAL; if (insn_has_control(*p->addr)) { - pr_notice("Kprobes for control instructions are not " - "supported\n"); + pr_notice("Kprobes for control instructions are not supported\n"); return -EINVAL; } diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c index f0b54a934712..008aa2faef55 100644 --- a/arch/tile/kernel/machine_kexec.c +++ b/arch/tile/kernel/machine_kexec.c @@ -77,16 +77,13 @@ void machine_crash_shutdown(struct pt_regs *regs) int machine_kexec_prepare(struct kimage *image) { if (num_online_cpus() > 1) { - pr_warning("%s: detected attempt to kexec " - "with num_online_cpus() > 1\n", - __func__); + pr_warn("%s: detected attempt to kexec with num_online_cpus() > 1\n", + __func__); return -ENOSYS; } if (image->type != KEXEC_TYPE_DEFAULT) { - pr_warning("%s: detected attempt to kexec " - "with unsupported type: %d\n", - __func__, - image->type); + pr_warn("%s: detected attempt to kexec with unsupported type: %d\n", + __func__, image->type); return -ENOSYS; } return 0; @@ -131,8 +128,8 @@ static unsigned char *kexec_bn2cl(void *pg) */ csum = ip_compute_csum(pg, bhdrp->b_size); if (csum != 0) { - pr_warning("%s: bad checksum %#x (size %d)\n", - __func__, csum, bhdrp->b_size); + pr_warn("%s: bad checksum %#x (size %d)\n", + __func__, csum, bhdrp->b_size); return 0; } @@ -160,8 +157,7 @@ static unsigned char *kexec_bn2cl(void *pg) while (*desc != '\0') { desc++; if (((unsigned long)desc & PAGE_MASK) != (unsigned long)pg) { - pr_info("%s: ran off end of page\n", - __func__); + pr_info("%s: ran off end of page\n", __func__); return 0; } } @@ -195,20 +191,18 @@ static void kexec_find_and_set_command_line(struct kimage *image) } if (command_line != 0) { - pr_info("setting new command line to \"%s\"\n", - command_line); + pr_info("setting new command line to \"%s\"\n", command_line); hverr = hv_set_command_line( (HV_VirtAddr) command_line, strlen(command_line)); kunmap_atomic(command_line); } else { - pr_info("%s: no command line found; making empty\n", - __func__); + pr_info("%s: no command line found; making empty\n", __func__); hverr = hv_set_command_line((HV_VirtAddr) command_line, 0); } if (hverr) - pr_warning("%s: hv_set_command_line returned error: %d\n", - __func__, hverr); + pr_warn("%s: hv_set_command_line returned error: %d\n", + __func__, hverr); } /* diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c index ac950be1318e..7475af3aacec 100644 --- a/arch/tile/kernel/messaging.c +++ b/arch/tile/kernel/messaging.c @@ -59,9 +59,8 @@ void hv_message_intr(struct pt_regs *regs, int intnum) { long sp = stack_pointer - (long) current_thread_info(); if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { - pr_emerg("hv_message_intr: " - "stack overflow: %ld\n", - sp - sizeof(struct thread_info)); + pr_emerg("%s: stack overflow: %ld\n", + __func__, sp - sizeof(struct thread_info)); dump_stack(); } } diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c index d19b13e3a59f..96447c9160a0 100644 --- a/arch/tile/kernel/module.c +++ b/arch/tile/kernel/module.c @@ -96,8 +96,8 @@ void module_free(struct module *mod, void *module_region) static int validate_hw2_last(long value, struct module *me) { if (((value << 16) >> 16) != value) { - pr_warning("module %s: Out of range HW2_LAST value %#lx\n", - me->name, value); + pr_warn("module %s: Out of range HW2_LAST value %#lx\n", + me->name, value); return 0; } return 1; @@ -210,10 +210,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, value -= (unsigned long) location; /* pc-relative */ value = (long) value >> 3; /* count by instrs */ if (!validate_jumpoff(value)) { - pr_warning("module %s: Out of range jump to" - " %#llx at %#llx (%p)\n", me->name, - sym->st_value + rel[i].r_addend, - rel[i].r_offset, location); + pr_warn("module %s: Out of range jump to %#llx at %#llx (%p)\n", + me->name, + sym->st_value + rel[i].r_addend, + rel[i].r_offset, location); return -ENOEXEC; } MUNGE(create_JumpOff_X1); diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 1f80a88c75a6..f70c7892fa25 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -178,8 +178,8 @@ int __init tile_pci_init(void) continue; hv_cfg_fd1 = tile_pcie_open(i, 1); if (hv_cfg_fd1 < 0) { - pr_err("PCI: Couldn't open config fd to HV " - "for controller %d\n", i); + pr_err("PCI: Couldn't open config fd to HV for controller %d\n", + i); goto err_cont; } @@ -423,8 +423,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) for (i = 0; i < 6; i++) { r = &dev->resource[i]; if (r->flags & IORESOURCE_UNSET) { - pr_err("PCI: Device %s not available " - "because of resource collisions\n", + pr_err("PCI: Device %s not available because of resource collisions\n", pci_name(dev)); return -EINVAL; } diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index e39f9c542807..47e048e31641 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -131,8 +131,7 @@ static int tile_irq_cpu(int irq) count = cpumask_weight(&intr_cpus_map); if (unlikely(count == 0)) { - pr_warning("intr_cpus_map empty, interrupts will be" - " delievered to dataplane tiles\n"); + pr_warn("intr_cpus_map empty, interrupts will be delievered to dataplane tiles\n"); return irq % (smp_height * smp_width); } @@ -197,16 +196,16 @@ static int tile_pcie_open(int trio_index) /* Get the properties of the PCIe ports on this TRIO instance. */ ret = gxio_trio_get_port_property(context, &pcie_ports[trio_index]); if (ret < 0) { - pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d," - " on TRIO %d\n", ret, trio_index); + pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d, on TRIO %d\n", + ret, trio_index); goto get_port_property_failure; } context->mmio_base_mac = iorpc_ioremap(context->fd, 0, HV_TRIO_CONFIG_IOREMAP_SIZE); if (context->mmio_base_mac == NULL) { - pr_err("PCI: TRIO config space mapping failure, error %d," - " on TRIO %d\n", ret, trio_index); + pr_err("PCI: TRIO config space mapping failure, error %d, on TRIO %d\n", + ret, trio_index); ret = -ENOMEM; goto trio_mmio_mapping_failure; @@ -622,9 +621,8 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller) dev_control.max_read_req_sz, mac); if (err < 0) { - pr_err("PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, " - "MAC %d on TRIO %d\n", - mac, controller->trio_index); + pr_err("PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, MAC %d on TRIO %d\n", + mac, controller->trio_index); } } @@ -720,27 +718,24 @@ int __init pcibios_init(void) reg_offset); if (!port_status.dl_up) { if (rc_delay[trio_index][mac]) { - pr_info("Delaying PCIe RC TRIO init %d sec" - " on MAC %d on TRIO %d\n", + pr_info("Delaying PCIe RC TRIO init %d sec on MAC %d on TRIO %d\n", rc_delay[trio_index][mac], mac, trio_index); msleep(rc_delay[trio_index][mac] * 1000); } ret = gxio_trio_force_rc_link_up(trio_context, mac); if (ret < 0) - pr_err("PCI: PCIE_FORCE_LINK_UP failure, " - "MAC %d on TRIO %d\n", mac, trio_index); + pr_err("PCI: PCIE_FORCE_LINK_UP failure, MAC %d on TRIO %d\n", + mac, trio_index); } - pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i, - trio_index, controller->mac); + pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", + i, trio_index, controller->mac); /* Delay the bus probe if needed. */ if (rc_delay[trio_index][mac]) { - pr_info("Delaying PCIe RC bus enumerating %d sec" - " on MAC %d on TRIO %d\n", - rc_delay[trio_index][mac], mac, - trio_index); + pr_info("Delaying PCIe RC bus enumerating %d sec on MAC %d on TRIO %d\n", + rc_delay[trio_index][mac], mac, trio_index); msleep(rc_delay[trio_index][mac] * 1000); } else { /* @@ -758,11 +753,10 @@ int __init pcibios_init(void) if (pcie_ports[trio_index].ports[mac].removable) { pr_info("PCI: link is down, MAC %d on TRIO %d\n", mac, trio_index); - pr_info("This is expected if no PCIe card" - " is connected to this link\n"); + pr_info("This is expected if no PCIe card is connected to this link\n"); } else pr_err("PCI: link is down, MAC %d on TRIO %d\n", - mac, trio_index); + mac, trio_index); continue; } @@ -829,8 +823,8 @@ int __init pcibios_init(void) /* Alloc a PIO region for PCI config access per MAC. */ ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); if (ret < 0) { - pr_err("PCI: PCI CFG PIO alloc failure for mac %d " - "on TRIO %d, give up\n", mac, trio_index); + pr_err("PCI: PCI CFG PIO alloc failure for mac %d on TRIO %d, give up\n", + mac, trio_index); continue; } @@ -842,8 +836,8 @@ int __init pcibios_init(void) trio_context->pio_cfg_index[mac], mac, 0, HV_TRIO_PIO_FLAG_CONFIG_SPACE); if (ret < 0) { - pr_err("PCI: PCI CFG PIO init failure for mac %d " - "on TRIO %d, give up\n", mac, trio_index); + pr_err("PCI: PCI CFG PIO init failure for mac %d on TRIO %d, give up\n", + mac, trio_index); continue; } @@ -865,7 +859,7 @@ int __init pcibios_init(void) (TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT - 1))); if (trio_context->mmio_base_pio_cfg[mac] == NULL) { pr_err("PCI: PIO map failure for mac %d on TRIO %d\n", - mac, trio_index); + mac, trio_index); continue; } @@ -925,9 +919,8 @@ int __init pcibios_init(void) /* Alloc a PIO region for PCI memory access for each RC port. */ ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); if (ret < 0) { - pr_err("PCI: MEM PIO alloc failure on TRIO %d mac %d, " - "give up\n", controller->trio_index, - controller->mac); + pr_err("PCI: MEM PIO alloc failure on TRIO %d mac %d, give up\n", + controller->trio_index, controller->mac); continue; } @@ -944,9 +937,8 @@ int __init pcibios_init(void) 0, 0); if (ret < 0) { - pr_err("PCI: MEM PIO init failure on TRIO %d mac %d, " - "give up\n", controller->trio_index, - controller->mac); + pr_err("PCI: MEM PIO init failure on TRIO %d mac %d, give up\n", + controller->trio_index, controller->mac); continue; } @@ -957,9 +949,8 @@ int __init pcibios_init(void) */ ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); if (ret < 0) { - pr_err("PCI: I/O PIO alloc failure on TRIO %d mac %d, " - "give up\n", controller->trio_index, - controller->mac); + pr_err("PCI: I/O PIO alloc failure on TRIO %d mac %d, give up\n", + controller->trio_index, controller->mac); continue; } @@ -976,9 +967,8 @@ int __init pcibios_init(void) 0, HV_TRIO_PIO_FLAG_IO_SPACE); if (ret < 0) { - pr_err("PCI: I/O PIO init failure on TRIO %d mac %d, " - "give up\n", controller->trio_index, - controller->mac); + pr_err("PCI: I/O PIO init failure on TRIO %d mac %d, give up\n", + controller->trio_index, controller->mac); continue; } @@ -997,10 +987,9 @@ int __init pcibios_init(void) ret = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0); if (ret < 0) { - pr_err("PCI: Mem-Map alloc failure on TRIO %d " - "mac %d for MC %d, give up\n", - controller->trio_index, - controller->mac, j); + pr_err("PCI: Mem-Map alloc failure on TRIO %d mac %d for MC %d, give up\n", + controller->trio_index, controller->mac, + j); goto alloc_mem_map_failed; } @@ -1030,10 +1019,9 @@ int __init pcibios_init(void) j, GXIO_TRIO_ORDER_MODE_UNORDERED); if (ret < 0) { - pr_err("PCI: Mem-Map init failure on TRIO %d " - "mac %d for MC %d, give up\n", - controller->trio_index, - controller->mac, j); + pr_err("PCI: Mem-Map init failure on TRIO %d mac %d for MC %d, give up\n", + controller->trio_index, controller->mac, + j); goto alloc_mem_map_failed; } @@ -1510,9 +1498,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) * Most PCIe endpoint devices do support 64-bit message addressing. */ if (desc->msi_attrib.is_64 == 0) { - dev_printk(KERN_INFO, &pdev->dev, - "64-bit MSI message address not supported, " - "falling back to legacy interrupts.\n"); + dev_info(&pdev->dev, "64-bit MSI message address not supported, falling back to legacy interrupts\n"); ret = -ENOMEM; goto is_64_failure; @@ -1549,11 +1535,8 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) /* SQ regions are out, allocate from map mem regions. */ mem_map = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0); if (mem_map < 0) { - dev_printk(KERN_INFO, &pdev->dev, - "%s Mem-Map alloc failure. " - "Failed to initialize MSI interrupts. " - "Falling back to legacy interrupts.\n", - desc->msi_attrib.is_msix ? "MSI-X" : "MSI"); + dev_info(&pdev->dev, "%s Mem-Map alloc failure - failed to initialize MSI interrupts - falling back to legacy interrupts\n", + desc->msi_attrib.is_msix ? "MSI-X" : "MSI"); ret = -ENOMEM; goto msi_mem_map_alloc_failure; } @@ -1580,7 +1563,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) mem_map, mem_map_base, mem_map_limit, trio_context->asid); if (ret < 0) { - dev_printk(KERN_INFO, &pdev->dev, "HV MSI config failed.\n"); + dev_info(&pdev->dev, "HV MSI config failed\n"); goto hv_msi_config_failure; } diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 0050cbc1d9de..48e5773dd0b7 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -52,7 +52,7 @@ static int __init idle_setup(char *str) return -EINVAL; if (!strcmp(str, "poll")) { - pr_info("using polling idle threads.\n"); + pr_info("using polling idle threads\n"); cpu_idle_poll_ctrl(true); return 0; } else if (!strcmp(str, "halt")) { @@ -547,27 +547,25 @@ void show_regs(struct pt_regs *regs) struct task_struct *tsk = validate_current(); int i; - pr_err("\n"); if (tsk != &corrupt_current) show_regs_print_info(KERN_ERR); #ifdef __tilegx__ for (i = 0; i < 17; i++) - pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n", + pr_err(" r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT "\n", i, regs->regs[i], i+18, regs->regs[i+18], i+36, regs->regs[i+36]); - pr_err(" r17: "REGFMT" r35: "REGFMT" tp : "REGFMT"\n", + pr_err(" r17: " REGFMT " r35: " REGFMT " tp : " REGFMT "\n", regs->regs[17], regs->regs[35], regs->tp); - pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); + pr_err(" sp : " REGFMT " lr : " REGFMT "\n", regs->sp, regs->lr); #else for (i = 0; i < 13; i++) - pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT - " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", + pr_err(" r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT "\n", i, regs->regs[i], i+14, regs->regs[i+14], i+27, regs->regs[i+27], i+40, regs->regs[i+40]); - pr_err(" r13: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", + pr_err(" r13: " REGFMT " tp : " REGFMT " sp : " REGFMT " lr : " REGFMT "\n", regs->regs[13], regs->tp, regs->sp, regs->lr); #endif - pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", + pr_err(" pc : " REGFMT " ex1: %ld faultnum: %ld\n", regs->pc, regs->ex1, regs->faultnum); dump_stack_regs(regs); diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index b9736ded06f2..f183f1c92b4f 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -130,7 +130,7 @@ static int __init setup_maxmem(char *str) maxmem_pfn = (maxmem >> HPAGE_SHIFT) << (HPAGE_SHIFT - PAGE_SHIFT); pr_info("Forcing RAM used to no more than %dMB\n", - maxmem_pfn >> (20 - PAGE_SHIFT)); + maxmem_pfn >> (20 - PAGE_SHIFT)); return 0; } early_param("maxmem", setup_maxmem); @@ -149,7 +149,7 @@ static int __init setup_maxnodemem(char *str) maxnodemem_pfn[node] = (maxnodemem >> HPAGE_SHIFT) << (HPAGE_SHIFT - PAGE_SHIFT); pr_info("Forcing RAM used on node %ld to no more than %dMB\n", - node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT)); + node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT)); return 0; } early_param("maxnodemem", setup_maxnodemem); @@ -417,8 +417,7 @@ static void __init setup_memory(void) range.start = (start_pa + HPAGE_SIZE - 1) & HPAGE_MASK; range.size -= (range.start - start_pa); range.size &= HPAGE_MASK; - pr_err("Range not hugepage-aligned: %#llx..%#llx:" - " now %#llx-%#llx\n", + pr_err("Range not hugepage-aligned: %#llx..%#llx: now %#llx-%#llx\n", start_pa, start_pa + orig_size, range.start, range.start + range.size); } @@ -437,8 +436,8 @@ static void __init setup_memory(void) if (PFN_DOWN(range.size) > maxnodemem_pfn[i]) { int max_size = maxnodemem_pfn[i]; if (max_size > 0) { - pr_err("Maxnodemem reduced node %d to" - " %d pages\n", i, max_size); + pr_err("Maxnodemem reduced node %d to %d pages\n", + i, max_size); range.size = PFN_PHYS(max_size); } else { pr_err("Maxnodemem disabled node %d\n", i); @@ -490,8 +489,8 @@ static void __init setup_memory(void) NR_CPUS * (PFN_UP(per_cpu_size) >> PAGE_SHIFT); if (end < pci_reserve_end_pfn + percpu_pages) { end = pci_reserve_start_pfn; - pr_err("PCI mapping region reduced node %d to" - " %ld pages\n", i, end - start); + pr_err("PCI mapping region reduced node %d to %ld pages\n", + i, end - start); } } #endif @@ -556,10 +555,9 @@ static void __init setup_memory(void) MAXMEM_PFN : mappable_physpages; highmem_pages = (long) (physpages - lowmem_pages); - pr_notice("%ldMB HIGHMEM available.\n", - pages_to_mb(highmem_pages > 0 ? highmem_pages : 0)); - pr_notice("%ldMB LOWMEM available.\n", - pages_to_mb(lowmem_pages)); + pr_notice("%ldMB HIGHMEM available\n", + pages_to_mb(highmem_pages > 0 ? highmem_pages : 0)); + pr_notice("%ldMB LOWMEM available\n", pages_to_mb(lowmem_pages)); #else /* Set max_low_pfn based on what node 0 can directly address. */ max_low_pfn = node_end_pfn[0]; @@ -573,8 +571,8 @@ static void __init setup_memory(void) max_pfn = MAXMEM_PFN; node_end_pfn[0] = MAXMEM_PFN; } else { - pr_notice("%ldMB memory available.\n", - pages_to_mb(node_end_pfn[0])); + pr_notice("%ldMB memory available\n", + pages_to_mb(node_end_pfn[0])); } for (i = 1; i < MAX_NUMNODES; ++i) { node_start_pfn[i] = 0; @@ -589,8 +587,7 @@ static void __init setup_memory(void) if (pages) high_memory = pfn_to_kaddr(node_end_pfn[i]); } - pr_notice("%ldMB memory available.\n", - pages_to_mb(lowmem_pages)); + pr_notice("%ldMB memory available\n", pages_to_mb(lowmem_pages)); #endif #endif } @@ -1540,8 +1537,7 @@ static void __init pcpu_fc_populate_pte(unsigned long addr) BUG_ON(pgd_addr_invalid(addr)); if (addr < VMALLOC_START || addr >= VMALLOC_END) - panic("PCPU addr %#lx outside vmalloc range %#lx..%#lx;" - " try increasing CONFIG_VMALLOC_RESERVE\n", + panic("PCPU addr %#lx outside vmalloc range %#lx..%#lx; try increasing CONFIG_VMALLOC_RESERVE\n", addr, VMALLOC_START, VMALLOC_END); pgd = swapper_pg_dir + pgd_index(addr); @@ -1596,8 +1592,8 @@ void __init setup_per_cpu_areas(void) lowmem_va = (unsigned long)pfn_to_kaddr(pfn); ptep = virt_to_kpte(lowmem_va); if (pte_huge(*ptep)) { - printk(KERN_DEBUG "early shatter of huge page" - " at %#lx\n", lowmem_va); + printk(KERN_DEBUG "early shatter of huge page at %#lx\n", + lowmem_va); shatter_pmd((pmd_t *)ptep); ptep = virt_to_kpte(lowmem_va); BUG_ON(pte_huge(*ptep)); diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 491669065ffb..bb0a9ce7ae23 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -337,7 +337,6 @@ static void dump_mem(void __user *address) int i, j, k; int found_readable_mem = 0; - pr_err("\n"); if (!access_ok(VERIFY_READ, address, 1)) { pr_err("Not dumping at address 0x%lx (kernel address)\n", (unsigned long)address); @@ -359,7 +358,7 @@ static void dump_mem(void __user *address) (unsigned long)address); found_readable_mem = 1; } - j = sprintf(line, REGFMT":", (unsigned long)addr); + j = sprintf(line, REGFMT ":", (unsigned long)addr); for (k = 0; k < bytes_per_line; ++k) j += sprintf(&line[j], " %02x", buf[k]); pr_err("%s\n", line); @@ -403,8 +402,7 @@ void trace_unhandled_signal(const char *type, struct pt_regs *regs, case SIGFPE: case SIGSEGV: case SIGBUS: - pr_err("User crash: signal %d," - " trap %ld, address 0x%lx\n", + pr_err("User crash: signal %d, trap %ld, address 0x%lx\n", sig, regs->faultnum, address); show_regs(regs); dump_mem((void __user *)address); diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index 6cb2ce31b5a2..862973074bf9 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c @@ -222,11 +222,9 @@ static tilepro_bundle_bits rewrite_load_store_unaligned( } if (unaligned_printk || unaligned_fixup_count == 0) { - pr_info("Process %d/%s: PC %#lx: Fixup of" - " unaligned %s at %#lx.\n", + pr_info("Process %d/%s: PC %#lx: Fixup of unaligned %s at %#lx\n", current->pid, current->comm, regs->pc, - (mem_op == MEMOP_LOAD || - mem_op == MEMOP_LOAD_POSTINCR) ? + mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR ? "load" : "store", (unsigned long)addr); if (!unaligned_printk) { diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c index 0d59a1b60c74..20d52a98e171 100644 --- a/arch/tile/kernel/smpboot.c +++ b/arch/tile/kernel/smpboot.c @@ -127,8 +127,7 @@ static __init int reset_init_affinity(void) { long rc = sched_setaffinity(current->pid, &init_affinity); if (rc != 0) - pr_warning("couldn't reset init affinity (%ld)\n", - rc); + pr_warn("couldn't reset init affinity (%ld)\n", rc); return 0; } late_initcall(reset_init_affinity); @@ -174,7 +173,7 @@ static void start_secondary(void) /* Indicate that we're ready to come up. */ /* Must not do this before we're ready to receive messages */ if (cpumask_test_and_set_cpu(cpuid, &cpu_started)) { - pr_warning("CPU#%d already started!\n", cpuid); + pr_warn("CPU#%d already started!\n", cpuid); for (;;) local_irq_enable(); } diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index c93977a62116..7ff5afdbd3aa 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -387,9 +387,7 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) * then bust_spinlocks() spit out a space in front of us * and it will mess up our KERN_ERR. */ - pr_err("\n"); - pr_err("Starting stack dump of tid %d, pid %d (%s)" - " on cpu %d at cycle %lld\n", + pr_err("Starting stack dump of tid %d, pid %d (%s) on cpu %d at cycle %lld\n", kbt->task->pid, kbt->task->tgid, kbt->task->comm, raw_smp_processor_id(), get_cycles()); } @@ -411,8 +409,7 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) i++, address, namebuf, (unsigned long)(kbt->it.sp)); if (i >= 100) { - pr_err("Stack dump truncated" - " (%d frames)\n", i); + pr_err("Stack dump truncated (%d frames)\n", i); break; } } diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index b854a1cd0079..d412b0856c0a 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -98,8 +98,8 @@ void __init calibrate_delay(void) { loops_per_jiffy = get_clock_rate() / HZ; pr_info("Clock rate yields %lu.%02lu BogoMIPS (lpj=%lu)\n", - loops_per_jiffy/(500000/HZ), - (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); + loops_per_jiffy / (500000 / HZ), + (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy); } /* Called fairly late in init/main.c, but before we go smp. */ diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 86900ccd4977..bf841ca517bb 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c @@ -46,9 +46,9 @@ static int __init setup_unaligned_fixup(char *str) return 0; pr_info("Fixups for unaligned data accesses are %s\n", - unaligned_fixup >= 0 ? - (unaligned_fixup ? "enabled" : "disabled") : - "completely disabled"); + unaligned_fixup >= 0 ? + (unaligned_fixup ? "enabled" : "disabled") : + "completely disabled"); return 1; } __setup("unaligned_fixup=", setup_unaligned_fixup); @@ -305,8 +305,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, case INT_ILL: if (copy_from_user(&instr, (void __user *)regs->pc, sizeof(instr))) { - pr_err("Unreadable instruction for INT_ILL:" - " %#lx\n", regs->pc); + pr_err("Unreadable instruction for INT_ILL: %#lx\n", + regs->pc); do_exit(SIGKILL); return; } diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c index c02ea2a45f67..7d9a83be0aca 100644 --- a/arch/tile/kernel/unaligned.c +++ b/arch/tile/kernel/unaligned.c @@ -969,8 +969,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, unaligned_fixup_count++; if (unaligned_printk) { - pr_info("%s/%d. Unalign fixup for kernel access " - "to userspace %lx.", + pr_info("%s/%d - Unalign fixup for kernel access to userspace %lx\n", current->comm, current->pid, regs->regs[ra]); } @@ -985,7 +984,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, .si_addr = (unsigned char __user *)0 }; if (unaligned_printk) - pr_info("Unalign bundle: unexp @%llx, %llx", + pr_info("Unalign bundle: unexp @%llx, %llx\n", (unsigned long long)regs->pc, (unsigned long long)bundle); @@ -1370,8 +1369,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, frag.bundle = bundle; if (unaligned_printk) { - pr_info("%s/%d, Unalign fixup: pc=%lx " - "bundle=%lx %d %d %d %d %d %d %d %d.", + pr_info("%s/%d, Unalign fixup: pc=%lx bundle=%lx %d %d %d %d %d %d %d %d\n", current->comm, current->pid, (unsigned long)frag.pc, (unsigned long)frag.bundle, @@ -1380,8 +1378,8 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, (int)y1_lr, (int)y1_br, (int)x1_add); for (k = 0; k < n; k += 2) - pr_info("[%d] %016llx %016llx", k, - (unsigned long long)frag.insn[k], + pr_info("[%d] %016llx %016llx\n", + k, (unsigned long long)frag.insn[k], (unsigned long long)frag.insn[k+1]); } @@ -1402,7 +1400,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, .si_addr = (void __user *)&jit_code_area[idx] }; - pr_warn("Unalign fixup: pid=%d %s jit_code_area=%llx", + pr_warn("Unalign fixup: pid=%d %s jit_code_area=%llx\n", current->pid, current->comm, (unsigned long long)&jit_code_area[idx]); @@ -1485,7 +1483,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) /* If exception came from kernel, try fix it up. */ if (fixup_exception(regs)) { if (unaligned_printk) - pr_info("Unalign fixup: %d %llx @%llx", + pr_info("Unalign fixup: %d %llx @%llx\n", (int)unaligned_fixup, (unsigned long long)regs->ex1, (unsigned long long)regs->pc); @@ -1519,7 +1517,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) }; if (unaligned_printk) - pr_info("Unalign fixup: %d %llx @%llx", + pr_info("Unalign fixup: %d %llx @%llx\n", (int)unaligned_fixup, (unsigned long long)regs->ex1, (unsigned long long)regs->pc); @@ -1579,14 +1577,14 @@ void do_unaligned(struct pt_regs *regs, int vecnum) 0); if (IS_ERR((void __force *)user_page)) { - pr_err("Out of kernel pages trying do_mmap.\n"); + pr_err("Out of kernel pages trying do_mmap\n"); return; } /* Save the address in the thread_info struct */ info->unalign_jit_base = user_page; if (unaligned_printk) - pr_info("Unalign bundle: %d:%d, allocate page @%llx", + pr_info("Unalign bundle: %d:%d, allocate page @%llx\n", raw_smp_processor_id(), current->pid, (unsigned long long)user_page); } diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 6c0571216a9d..565e25a98334 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c @@ -169,8 +169,7 @@ static void wait_for_migration(pte_t *pte) while (pte_migrating(*pte)) { barrier(); if (++retries > bound) - panic("Hit migrating PTE (%#llx) and" - " page PFN %#lx still migrating", + panic("Hit migrating PTE (%#llx) and page PFN %#lx still migrating", pte->val, pte_pfn(*pte)); } } @@ -292,11 +291,10 @@ static int handle_page_fault(struct pt_regs *regs, */ stack_offset = stack_pointer & (THREAD_SIZE-1); if (stack_offset < THREAD_SIZE / 8) { - pr_alert("Potential stack overrun: sp %#lx\n", - stack_pointer); + pr_alert("Potential stack overrun: sp %#lx\n", stack_pointer); show_regs(regs); pr_alert("Killing current process %d/%s\n", - tsk->pid, tsk->comm); + tsk->pid, tsk->comm); do_group_exit(SIGKILL); } @@ -421,7 +419,7 @@ static int handle_page_fault(struct pt_regs *regs, } else if (write) { #ifdef TEST_VERIFY_AREA if (!is_page_fault && regs->cs == KERNEL_CS) - pr_err("WP fault at "REGFMT"\n", regs->eip); + pr_err("WP fault at " REGFMT "\n", regs->eip); #endif if (!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -519,16 +517,15 @@ static int handle_page_fault(struct pt_regs *regs, pte_t *pte = lookup_address(address); if (pte && pte_present(*pte) && !pte_exec_kernel(*pte)) - pr_crit("kernel tried to execute" - " non-executable page - exploit attempt?" - " (uid: %d)\n", current->uid); + pr_crit("kernel tried to execute non-executable page - exploit attempt? (uid: %d)\n", + current->uid); } #endif if (address < PAGE_SIZE) pr_alert("Unable to handle kernel NULL pointer dereference\n"); else pr_alert("Unable to handle kernel paging request\n"); - pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n", + pr_alert(" at virtual address " REGFMT ", pc " REGFMT "\n", address, regs->pc); show_regs(regs); @@ -575,9 +572,10 @@ static int handle_page_fault(struct pt_regs *regs, #ifndef __tilegx__ /* We must release ICS before panicking or we won't get anywhere. */ -#define ics_panic(fmt, ...) do { \ - __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \ - panic(fmt, __VA_ARGS__); \ +#define ics_panic(fmt, ...) \ +do { \ + __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \ + panic(fmt, ##__VA_ARGS__); \ } while (0) /* @@ -615,8 +613,7 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num, fault_num != INT_DTLB_ACCESS)) { unsigned long old_pc = regs->pc; regs->pc = pc; - ics_panic("Bad ICS page fault args:" - " old PC %#lx, fault %d/%d at %#lx\n", + ics_panic("Bad ICS page fault args: old PC %#lx, fault %d/%d at %#lx", old_pc, fault_num, write, address); } @@ -669,8 +666,8 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num, #endif fixup = search_exception_tables(pc); if (!fixup) - ics_panic("ICS atomic fault not in table:" - " PC %#lx, fault %d", pc, fault_num); + ics_panic("ICS atomic fault not in table: PC %#lx, fault %d", + pc, fault_num); regs->pc = fixup->fixup; regs->ex1 = PL_ICS_EX1(KERNEL_PL, 0); } @@ -826,8 +823,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, set_thread_flag(TIF_ASYNC_TLB); if (async->fault_num != 0) { - panic("Second async fault %d;" - " old fault was %d (%#lx/%ld)", + panic("Second async fault %d; old fault was %d (%#lx/%ld)", fault_num, async->fault_num, address, write); } diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c index 33294fdc402e..cd3387370ebb 100644 --- a/arch/tile/mm/homecache.c +++ b/arch/tile/mm/homecache.c @@ -152,12 +152,10 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control, cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy); cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy); - pr_err("hv_flush_remote(%#llx, %#lx, %p [%s]," - " %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n", + pr_err("hv_flush_remote(%#llx, %#lx, %p [%s], %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n", cache_pa, cache_control, cache_cpumask, cache_buf, (unsigned long)tlb_va, tlb_length, tlb_pgsize, - tlb_cpumask, tlb_buf, - asids, asidcount, rc); + tlb_cpumask, tlb_buf, asids, asidcount, rc); panic("Unsafe to continue."); } diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c index e514899e1100..3270e0019266 100644 --- a/arch/tile/mm/hugetlbpage.c +++ b/arch/tile/mm/hugetlbpage.c @@ -284,22 +284,21 @@ static __init int __setup_hugepagesz(unsigned long ps) int level, base_shift; if ((1UL << log_ps) != ps || (log_ps & 1) != 0) { - pr_warn("Not enabling %ld byte huge pages;" - " must be a power of four.\n", ps); + pr_warn("Not enabling %ld byte huge pages; must be a power of four\n", + ps); return -EINVAL; } if (ps > 64*1024*1024*1024UL) { - pr_warn("Not enabling %ld MB huge pages;" - " largest legal value is 64 GB .\n", ps >> 20); + pr_warn("Not enabling %ld MB huge pages; largest legal value is 64 GB\n", + ps >> 20); return -EINVAL; } else if (ps >= PUD_SIZE) { static long hv_jpage_size; if (hv_jpage_size == 0) hv_jpage_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO); if (hv_jpage_size != PUD_SIZE) { - pr_warn("Not enabling >= %ld MB huge pages:" - " hypervisor reports size %ld\n", + pr_warn("Not enabling >= %ld MB huge pages: hypervisor reports size %ld\n", PUD_SIZE >> 20, hv_jpage_size); return -EINVAL; } @@ -320,14 +319,13 @@ static __init int __setup_hugepagesz(unsigned long ps) int shift_val = log_ps - base_shift; if (huge_shift[level] != 0) { int old_shift = base_shift + huge_shift[level]; - pr_warn("Not enabling %ld MB huge pages;" - " already have size %ld MB.\n", + pr_warn("Not enabling %ld MB huge pages; already have size %ld MB\n", ps >> 20, (1UL << old_shift) >> 20); return -EINVAL; } if (hv_set_pte_super_shift(level, shift_val) != 0) { - pr_warn("Not enabling %ld MB huge pages;" - " no hypervisor support.\n", ps >> 20); + pr_warn("Not enabling %ld MB huge pages; no hypervisor support\n", + ps >> 20); return -EINVAL; } printk(KERN_DEBUG "Enabled %ld MB huge pages\n", ps >> 20); diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index caa270165f86..be240cc4978d 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -357,11 +357,11 @@ static int __init setup_ktext(char *str) cpulist_scnprintf(buf, sizeof(buf), &ktext_mask); if (cpumask_weight(&ktext_mask) > 1) { ktext_small = 1; - pr_info("ktext: using caching neighborhood %s " - "with small pages\n", buf); + pr_info("ktext: using caching neighborhood %s with small pages\n", + buf); } else { pr_info("ktext: caching on cpu %s with one huge page\n", - buf); + buf); } } @@ -413,19 +413,16 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) int rc, i; if (ktext_arg_seen && ktext_hash) { - pr_warning("warning: \"ktext\" boot argument ignored" - " if \"kcache_hash\" sets up text hash-for-home\n"); + pr_warn("warning: \"ktext\" boot argument ignored if \"kcache_hash\" sets up text hash-for-home\n"); ktext_small = 0; } if (kdata_arg_seen && kdata_hash) { - pr_warning("warning: \"kdata\" boot argument ignored" - " if \"kcache_hash\" sets up data hash-for-home\n"); + pr_warn("warning: \"kdata\" boot argument ignored if \"kcache_hash\" sets up data hash-for-home\n"); } if (kdata_huge && !hash_default) { - pr_warning("warning: disabling \"kdata=huge\"; requires" - " kcache_hash=all or =allbutstack\n"); + pr_warn("warning: disabling \"kdata=huge\"; requires kcache_hash=all or =allbutstack\n"); kdata_huge = 0; } @@ -470,8 +467,8 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) pte[pte_ofs] = pfn_pte(pfn, prot); } else { if (kdata_huge) - printk(KERN_DEBUG "pre-shattered huge" - " page at %#lx\n", address); + printk(KERN_DEBUG "pre-shattered huge page at %#lx\n", + address); for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE; pfn++, pte_ofs++, address += PAGE_SIZE) { pgprot_t prot = init_pgprot(address); @@ -501,8 +498,8 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) pr_info("ktext: not using unavailable cpus %s\n", buf); } if (cpumask_empty(&ktext_mask)) { - pr_warning("ktext: no valid cpus; caching on %d.\n", - smp_processor_id()); + pr_warn("ktext: no valid cpus; caching on %d\n", + smp_processor_id()); cpumask_copy(&ktext_mask, cpumask_of(smp_processor_id())); } @@ -798,11 +795,9 @@ void __init mem_init(void) #ifdef CONFIG_HIGHMEM /* check that fixmap and pkmap do not overlap */ if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) { - pr_err("fixmap and kmap areas overlap" - " - this will crash\n"); + pr_err("fixmap and kmap areas overlap - this will crash\n"); pr_err("pkstart: %lxh pkend: %lxh fixstart %lxh\n", - PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1), - FIXADDR_START); + PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1), FIXADDR_START); BUG(); } #endif @@ -926,8 +921,7 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) unsigned long addr = (unsigned long) begin; if (kdata_huge && !initfree) { - pr_warning("Warning: ignoring initfree=0:" - " incompatible with kdata=huge\n"); + pr_warn("Warning: ignoring initfree=0: incompatible with kdata=huge\n"); initfree = 1; } end = (end + PAGE_SIZE - 1) & PAGE_MASK; diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 5e86eac4bfae..7bf2491a9c1f 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c @@ -44,9 +44,7 @@ void show_mem(unsigned int filter) { struct zone *zone; - pr_err("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu" - " free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu" - " pagecache:%lu swap:%lu\n", + pr_err("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu pagecache:%lu swap:%lu\n", (global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE)), (global_page_state(NR_INACTIVE_ANON) + -- GitLab From d65c4e4e0aeb699e984bd4b382efffab418aa359 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 11 Nov 2014 13:13:41 -0800 Subject: [PATCH 4297/9457] irda: Simplify IRDA logging macros These are the same as net__ratelimited, so use the more common style in the macro definition. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/irda/irda.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index a059465101ff..42aa054aa67f 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -77,9 +77,9 @@ do { if(!(expr)) { \ #define IRDA_ASSERT_LABEL(label) #endif /* CONFIG_IRDA_DEBUG */ -#define IRDA_WARNING(args...) do { if (net_ratelimit()) printk(KERN_WARNING args); } while (0) -#define IRDA_MESSAGE(args...) do { if (net_ratelimit()) printk(KERN_INFO args); } while (0) -#define IRDA_ERROR(args...) do { if (net_ratelimit()) printk(KERN_ERR args); } while (0) +#define IRDA_ERROR net_err_ratelimited +#define IRDA_WARNING net_warn_ratelimited +#define IRDA_MESSAGE net_info_ratelimited /* * Magic numbers used by Linux-IrDA. Random numbers which must be unique to -- GitLab From 8bca81d9875c7768c40a19fb439eebaf6cec898d Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 11 Nov 2014 14:10:47 +0530 Subject: [PATCH 4298/9457] usbnet: smsc95xx: dereferencing NULL pointer we were dereferencing dev to initialize pdata. but just after that we have a BUG_ON(!dev). so we were basically dereferencing the pointer first and then tesing it for NULL. Signed-off-by: Sudip Mukherjee Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index d07bf4cb893f..26423adc35ee 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1670,12 +1670,14 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) static int smsc95xx_resume(struct usb_interface *intf) { struct usbnet *dev = usb_get_intfdata(intf); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - u8 suspend_flags = pdata->suspend_flags; + struct smsc95xx_priv *pdata; + u8 suspend_flags; int ret; u32 val; BUG_ON(!dev); + pdata = (struct smsc95xx_priv *)(dev->data[0]); + suspend_flags = pdata->suspend_flags; netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags); -- GitLab From 09626e9d153326ca82568e4e27f2daa53713992e Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Tue, 11 Nov 2014 13:29:42 -0800 Subject: [PATCH 4299/9457] net: kill netif_copy_real_num_queues() vlan was the only user of netif_copy_real_num_queues(), but it no longer calls it after commit 4af429d29b341bb1735f04c2fb960178 ("vlan: lockless transmit path"). So we can just remove it. Cc: Eric Dumazet Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- include/linux/netdevice.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 888d5513fa4a..4a6f770377d3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2762,23 +2762,6 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev, } #endif -static inline int netif_copy_real_num_queues(struct net_device *to_dev, - const struct net_device *from_dev) -{ - int err; - - err = netif_set_real_num_tx_queues(to_dev, - from_dev->real_num_tx_queues); - if (err) - return err; -#ifdef CONFIG_SYSFS - return netif_set_real_num_rx_queues(to_dev, - from_dev->real_num_rx_queues); -#else - return 0; -#endif -} - #ifdef CONFIG_SYSFS static inline unsigned int get_netdev_rx_queue_index( struct netdev_rx_queue *queue) -- GitLab From 85eb92e81801d64686eb78928d500a4c83ee9623 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 1 Nov 2014 16:54:55 +0100 Subject: [PATCH 4300/9457] bcma: make it possible to specify a IRQ num in bcma_core_irq() This moves bcma_core_irq() to main.c and add a extra parameter with a number so that we can return different irq number for devices with more than one. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/driver_chipcommon.c | 2 +- drivers/bcma/driver_gpio.c | 4 ++-- drivers/bcma/driver_mips.c | 11 ++--------- drivers/bcma/driver_pci_host.c | 4 ++-- drivers/bcma/main.c | 22 ++++++++++++++++++++++ include/linux/bcma/bcma.h | 2 ++ include/linux/bcma/bcma_driver_mips.h | 4 ++-- 7 files changed, 33 insertions(+), 16 deletions(-) diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index b068f98920a8..19f679667ca4 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -339,7 +339,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) return; } - irq = bcma_core_irq(cc->core); + irq = bcma_core_irq(cc->core, 0); /* Determine the registers of the UARTs */ cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 706b9ae0dcfb..598a6cd9028a 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -152,7 +152,7 @@ static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) handle_simple_irq); } - hwirq = bcma_core_irq(cc->core); + hwirq = bcma_core_irq(cc->core, 0); err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", cc); if (err) @@ -183,7 +183,7 @@ static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) return; bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); - free_irq(bcma_core_irq(cc->core), cc); + free_irq(bcma_core_irq(cc->core, 0), cc); for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_find_mapping(cc->irq_domain, gpio); diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 004d6aa671ce..5ec69c3d409d 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -115,7 +115,7 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev) * If disabled, 5 is returned. * If not supported, 6 is returned. */ -static unsigned int bcma_core_mips_irq(struct bcma_device *dev) +unsigned int bcma_core_mips_irq(struct bcma_device *dev) { struct bcma_device *mdev = dev->bus->drv_mips.core; u32 irqflag; @@ -133,13 +133,6 @@ static unsigned int bcma_core_mips_irq(struct bcma_device *dev) return 5; } -unsigned int bcma_core_irq(struct bcma_device *dev) -{ - unsigned int mips_irq = bcma_core_mips_irq(dev); - return mips_irq <= 4 ? mips_irq + 2 : 0; -} -EXPORT_SYMBOL(bcma_core_irq); - static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) { unsigned int oldirq = bcma_core_mips_irq(dev); @@ -423,7 +416,7 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) break; default: list_for_each_entry(core, &bus->cores, list) { - core->irq = bcma_core_irq(core); + core->irq = bcma_core_irq(core, 0); } bcma_err(bus, "Unknown device (0x%x) found, can not configure IRQs\n", diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index c3d7b03c2fdc..c8a6b741967b 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c @@ -593,7 +593,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev) pr_info("PCI: Fixing up device %s\n", pci_name(dev)); /* Fix up interrupt lines */ - dev->irq = bcma_core_irq(pc_host->pdev->core); + dev->irq = bcma_core_irq(pc_host->pdev->core, 0); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); readrq = pcie_get_readrq(dev); @@ -617,6 +617,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, pci_ops); - return bcma_core_irq(pc_host->pdev->core); + return bcma_core_irq(pc_host->pdev->core, 0); } EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 9b229c9c35e5..6d1cf5701452 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -169,6 +169,28 @@ static void bcma_of_fill_device(struct platform_device *parent, } #endif /* CONFIG_OF */ +unsigned int bcma_core_irq(struct bcma_device *core, int num) +{ + struct bcma_bus *bus = core->bus; + unsigned int mips_irq; + + switch (bus->hosttype) { + case BCMA_HOSTTYPE_PCI: + return bus->host_pci->irq; + case BCMA_HOSTTYPE_SOC: + if (bus->drv_mips.core && num == 0) { + mips_irq = bcma_core_mips_irq(core); + return mips_irq <= 4 ? mips_irq + 2 : 0; + } + break; + case BCMA_HOSTTYPE_SDIO: + return 0; + } + + return 0; +} +EXPORT_SYMBOL(bcma_core_irq); + void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) { core->dev.release = bcma_release_core_dev; diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 729f48e6b20b..eb1c6a47b67f 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -447,4 +447,6 @@ extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset); #define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */ extern u32 bcma_core_dma_translation(struct bcma_device *core); +extern unsigned int bcma_core_irq(struct bcma_device *core, int num); + #endif /* LINUX_BCMA_H_ */ diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h index fb61f3fb4ddb..0b3b32aeeb8a 100644 --- a/include/linux/bcma/bcma_driver_mips.h +++ b/include/linux/bcma/bcma_driver_mips.h @@ -43,12 +43,12 @@ struct bcma_drv_mips { extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); -extern unsigned int bcma_core_irq(struct bcma_device *core); +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); #else static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } -static inline unsigned int bcma_core_irq(struct bcma_device *core) +static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev) { return 0; } -- GitLab From 71783576b5345d63df048c0f18974037eea6e4f9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 1 Nov 2014 16:54:56 +0100 Subject: [PATCH 4301/9457] bcma: get IRQ numbers from dt It is not possible to auto detect the irq numbers used by the cores on an arm SoC. If bcma was registered with device tree it will search for some device tree nodes with the irq number and add it to the core configuration. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- .../devicetree/bindings/bus/bcma.txt | 21 ++++++++ drivers/bcma/main.c | 52 ++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/bus/bcma.txt b/Documentation/devicetree/bindings/bus/bcma.txt index 62a48348ac15..edd44d802139 100644 --- a/Documentation/devicetree/bindings/bus/bcma.txt +++ b/Documentation/devicetree/bindings/bus/bcma.txt @@ -8,6 +8,11 @@ Required properties: The cores on the AXI bus are automatically detected by bcma with the memory ranges they are using and they get registered afterwards. +Automatic detection of the IRQ number is not working on +BCM47xx/BCM53xx ARM SoCs. To assign IRQ numbers to the cores, provide +them manually through device tree. Use an interrupt-map to specify the +IRQ used by the devices on the bus. The first address is just an index, +because we do not have any special register. The top-level axi bus may contain children representing attached cores (devices). This is needed since some hardware details can't be auto @@ -22,6 +27,22 @@ Example: ranges = <0x00000000 0x18000000 0x00100000>; #address-cells = <1>; #size-cells = <1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0x000fffff 0xffff>; + interrupt-map = + /* Ethernet Controller 0 */ + <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, + + /* Ethernet Controller 1 */ + <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; + + /* PCIe Controller 0 */ + <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>, + <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>, + <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, + <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; chipcommon { reg = <0x00000000 0x1000>; diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 6d1cf5701452..122086ef9fe1 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -11,6 +11,7 @@ #include #include #include +#include MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); MODULE_LICENSE("GPL"); @@ -153,6 +154,46 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par return NULL; } +static int bcma_of_irq_parse(struct platform_device *parent, + struct bcma_device *core, + struct of_phandle_args *out_irq, int num) +{ + __be32 laddr[1]; + int rc; + + if (core->dev.of_node) { + rc = of_irq_parse_one(core->dev.of_node, num, out_irq); + if (!rc) + return rc; + } + + out_irq->np = parent->dev.of_node; + out_irq->args_count = 1; + out_irq->args[0] = num; + + laddr[0] = cpu_to_be32(core->addr); + return of_irq_parse_raw(laddr, out_irq); +} + +static unsigned int bcma_of_get_irq(struct platform_device *parent, + struct bcma_device *core, int num) +{ + struct of_phandle_args out_irq; + int ret; + + if (!parent || !parent->dev.of_node) + return 0; + + ret = bcma_of_irq_parse(parent, core, &out_irq, num); + if (ret) { + bcma_debug(core->bus, "bcma_of_get_irq() failed with rc=%d\n", + ret); + return 0; + } + + return irq_create_of_mapping(&out_irq); +} + static void bcma_of_fill_device(struct platform_device *parent, struct bcma_device *core) { @@ -161,12 +202,19 @@ static void bcma_of_fill_device(struct platform_device *parent, node = bcma_of_find_child_device(parent, core); if (node) core->dev.of_node = node; + + core->irq = bcma_of_get_irq(parent, core, 0); } #else static void bcma_of_fill_device(struct platform_device *parent, struct bcma_device *core) { } +static inline unsigned int bcma_of_get_irq(struct platform_device *parent, + struct bcma_device *core, int num) +{ + return 0; +} #endif /* CONFIG_OF */ unsigned int bcma_core_irq(struct bcma_device *core, int num) @@ -182,7 +230,9 @@ unsigned int bcma_core_irq(struct bcma_device *core, int num) mips_irq = bcma_core_mips_irq(core); return mips_irq <= 4 ? mips_irq + 2 : 0; } - break; + if (bus->host_pdev) + return bcma_of_get_irq(bus->host_pdev, core, num); + return 0; case BCMA_HOSTTYPE_SDIO: return 0; } -- GitLab From d385c5c2860075e1f3e03074f043dd8a828b2862 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 4 Nov 2014 16:56:57 +0100 Subject: [PATCH 4302/9457] ath9k: add support for reporting tx power to mac80211 Track it per channel context instead of in the softc Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/init.c | 25 ++++++++++++---------- drivers/net/wireless/ath/ath9k/main.c | 29 ++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 85d74ff0767c..adb49a9813f1 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -347,6 +347,7 @@ struct ath_chanctx { int flush_timeout; u16 txpower; + u16 cur_txpower; bool offchannel; bool stopped; bool active; @@ -987,7 +988,6 @@ struct ath_softc { u8 gtt_cnt; u32 intrstatus; u16 ps_flags; /* PS_* */ - u16 curtxpow; bool ps_enabled; bool ps_idle; short nbcnvifs; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 2294109f79e9..8d3c3364326a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -172,17 +172,20 @@ static void ath9k_reg_notifier(struct wiphy *wiphy, ath_reg_notifier_apply(wiphy, request, reg); /* Set tx power */ - if (ah->curchan) { - sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power; - ath9k_ps_wakeup(sc); - ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false); - sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; - /* synchronize DFS detector if regulatory domain changed */ - if (sc->dfs_detector != NULL) - sc->dfs_detector->set_dfs_domain(sc->dfs_detector, - request->dfs_region); - ath9k_ps_restore(sc); - } + if (!ah->curchan) + return; + + sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power; + ath9k_ps_wakeup(sc); + ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false); + ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, + sc->cur_chan->txpower, + &sc->cur_chan->cur_txpower); + /* synchronize DFS detector if regulatory domain changed */ + if (sc->dfs_detector != NULL) + sc->dfs_detector->set_dfs_domain(sc->dfs_detector, + request->dfs_region); + ath9k_ps_restore(sc); } /* diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 45465d8e3f0a..3ab5f630062b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -233,8 +233,9 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath9k_calculate_summary_state(sc, sc->cur_chan); ath_startrecv(sc); - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->cur_chan->txpower, &sc->curtxpow); + ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, + sc->cur_chan->txpower, + &sc->cur_chan->cur_txpower); clear_bit(ATH_OP_HW_RESET, &common->op_flags); if (!sc->cur_chan->offchannel && start) { @@ -1468,8 +1469,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_POWER) { ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level); sc->cur_chan->txpower = 2 * conf->power_level; - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->cur_chan->txpower, &sc->curtxpow); + ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower, + sc->cur_chan->txpower, + &sc->cur_chan->cur_txpower); } mutex_unlock(&sc->mutex); @@ -2591,6 +2593,24 @@ void ath9k_fill_chanctx_ops(void) #endif +static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int *dbm) +{ + struct ath_softc *sc = hw->priv; + struct ath_vif *avp = (void *)vif->drv_priv; + + mutex_lock(&sc->mutex); + if (avp->chanctx) + *dbm = avp->chanctx->cur_txpower; + else + *dbm = sc->cur_chan->cur_txpower; + mutex_unlock(&sc->mutex); + + *dbm /= 2; + + return 0; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2637,4 +2657,5 @@ struct ieee80211_ops ath9k_ops = { #endif .sw_scan_start = ath9k_sw_scan_start, .sw_scan_complete = ath9k_sw_scan_complete, + .get_txpower = ath9k_get_txpower, }; -- GitLab From ec4a16b4d287d4d0f7465ae7e61ce4e9021d715c Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 5 Nov 2014 17:04:27 +0530 Subject: [PATCH 4303/9457] mwifiex: rx workqueue support for USB interface This patch adds RX workqueue support for USB interfaces. Currently rx_pending is applicable for cmd/events and Rx data in USB interface. Let's use it only for Rx data. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 14 -------------- drivers/net/wireless/mwifiex/main.c | 8 +------- drivers/net/wireless/mwifiex/main.h | 6 +----- drivers/net/wireless/mwifiex/usb.c | 9 +++------ 4 files changed, 5 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 580aa45ec4bc..bd740b630b31 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -449,7 +449,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) spin_lock_init(&adapter->scan_pending_q_lock); spin_lock_init(&adapter->rx_proc_lock); - skb_queue_head_init(&adapter->usb_rx_data_q); skb_queue_head_init(&adapter->rx_data_q); for (i = 0; i < adapter->priv_num; ++i) { @@ -668,19 +667,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) spin_lock(&adapter->mwifiex_lock); - if (adapter->if_ops.data_complete) { - while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { - struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - - priv = adapter->priv[rx_info->bss_num]; - if (priv) - priv->stats.rx_dropped++; - - dev_kfree_skb_any(skb); - adapter->if_ops.data_complete(adapter); - } - } - mwifiex_adapter_cleanup(adapter); spin_unlock(&adapter->mwifiex_lock); diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f26420dbab6f..cb23ca3653b5 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -178,7 +178,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) { int ret = 0; unsigned long flags; - struct sk_buff *skb; spin_lock_irqsave(&adapter->main_proc_lock, flags); @@ -253,11 +252,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) } } - /* Check Rx data for USB */ - if (adapter->iface_type == MWIFIEX_USB) - while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) - mwifiex_handle_rx_packet(adapter, skb); - /* Check for event */ if (adapter->event_received) { adapter->event_received = false; @@ -864,7 +858,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, adapter->cmd_wait_q.status = 0; adapter->scan_wait_q_woken = false; - if (num_possible_cpus() > 1) { + if ((num_possible_cpus() > 1) || adapter->iface_type == MWIFIEX_USB) { adapter->rx_work_enabled = true; pr_notice("rx work enabled, cpus %d\n", num_possible_cpus()); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index fb47731d45a6..c7fdd8238f45 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -106,10 +106,7 @@ enum { */ #define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \ adapter->event_received || \ - ((adapter->iface_type != MWIFIEX_USB) && \ - adapter->data_received) || \ - ((adapter->iface_type == MWIFIEX_USB) && \ - !skb_queue_empty(&adapter->usb_rx_data_q))) + adapter->data_received) #define MWIFIEX_TYPE_CMD 1 #define MWIFIEX_TYPE_DATA 0 @@ -766,7 +763,6 @@ struct mwifiex_adapter { spinlock_t scan_pending_q_lock; /* spin lock for RX processing routine */ spinlock_t rx_proc_lock; - struct sk_buff_head usb_rx_data_q; u32 scan_processing; u16 region_code; struct mwifiex_802_11d_domain_reg domain_reg; diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 4371e12b36f3..00afcf63845e 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -125,8 +125,10 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, dev_err(dev, "DATA: skb->len too large\n"); return -1; } - skb_queue_tail(&adapter->usb_rx_data_q, skb); + + skb_queue_tail(&adapter->rx_data_q, skb); adapter->data_received = true; + atomic_inc(&adapter->rx_pending); break; default: dev_err(dev, "%s: unknown endport %#x\n", __func__, ep); @@ -176,7 +178,6 @@ static void mwifiex_usb_rx_complete(struct urb *urb) else skb_put(skb, recv_length - skb->len); - atomic_inc(&adapter->rx_pending); status = mwifiex_usb_recv(adapter, skb, context->ep); dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n", @@ -191,7 +192,6 @@ static void mwifiex_usb_rx_complete(struct urb *urb) if (card->rx_cmd_ep == context->ep) return; } else { - atomic_dec(&adapter->rx_pending); if (status == -1) dev_err(adapter->dev, "received data processing failed!\n"); @@ -962,7 +962,6 @@ static void mwifiex_submit_rx_urb(struct mwifiex_adapter *adapter, u8 ep) static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - atomic_dec(&adapter->rx_pending); mwifiex_submit_rx_urb(adapter, MWIFIEX_USB_EP_CMD_EVENT); return 0; @@ -970,8 +969,6 @@ static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter, static int mwifiex_usb_data_complete(struct mwifiex_adapter *adapter) { - atomic_dec(&adapter->rx_pending); - return 0; } -- GitLab From 041bfab5bbb6ec721c743f487e3e22b87f666996 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 5 Nov 2014 17:04:28 +0530 Subject: [PATCH 4304/9457] mwifiex: remove data_complete handler This patch removes redundant data complete handler. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.h | 1 - drivers/net/wireless/mwifiex/txrx.c | 4 ---- drivers/net/wireless/mwifiex/usb.c | 6 ------ 3 files changed, 11 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index c7fdd8238f45..4ef3c7a8f9fb 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -686,7 +686,6 @@ struct mwifiex_if_ops { void (*cleanup_mpa_buf) (struct mwifiex_adapter *); int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); - int (*data_complete) (struct mwifiex_adapter *); int (*init_fw_port) (struct mwifiex_adapter *); int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); void (*card_reset) (struct mwifiex_adapter *); diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 96a2126cc44b..a5983fc4e83a 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -64,10 +64,6 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, else ret = mwifiex_process_sta_rx_packet(priv, skb); - /* Decrement RX pending counter for each packet */ - if (adapter->if_ops.data_complete) - adapter->if_ops.data_complete(adapter); - return ret; } EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 00afcf63845e..08e9ec065275 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -967,11 +967,6 @@ static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter, return 0; } -static int mwifiex_usb_data_complete(struct mwifiex_adapter *adapter) -{ - return 0; -} - /* This function wakes up the card. */ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { @@ -993,7 +988,6 @@ static struct mwifiex_if_ops usb_ops = { .dnld_fw = mwifiex_usb_dnld_fw, .cmdrsp_complete = mwifiex_usb_cmd_event_complete, .event_complete = mwifiex_usb_cmd_event_complete, - .data_complete = mwifiex_usb_data_complete, .host_to_card = mwifiex_usb_host_to_card, }; -- GitLab From cf6a64fd603ae0f7391f7589b0f3568d4e79605c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 5 Nov 2014 17:04:29 +0530 Subject: [PATCH 4305/9457] mwifiex: fix out of memory issue observed for USB chipsets On some platforms, system goes out of memory during heavy Rx traffic with our USB chipsets. In case of SDIO/PCIe, after receiving 50 packets in Rx queue we stop processing interrupts till packets pending fall below low threshold i.e 20. We don't have similar logic for USB, so if host platform is slow, we would hit a case where firmware keeps on pushing packets at high speed than driver/kernel can process. We will stop submitting URBs for Rx data when pending packet count reaches high threshold and restart them when enough packets are consumed to solve the problem. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=85071 Reported-by: Marek Belisko Tested-by: Marek Belisko Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 2 ++ drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/usb.c | 23 ++++++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index cb23ca3653b5..2a5a59bec124 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -146,6 +146,8 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter) atomic_dec(&adapter->rx_pending); if (adapter->delay_main_work && (atomic_read(&adapter->rx_pending) < LOW_RX_PENDING)) { + if (adapter->if_ops.submit_rem_rx_urbs) + adapter->if_ops.submit_rem_rx_urbs(adapter); adapter->delay_main_work = false; queue_work(adapter->workqueue, &adapter->main_work); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 4ef3c7a8f9fb..eced41ef1967 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -692,6 +692,7 @@ struct mwifiex_if_ops { void (*fw_dump)(struct mwifiex_adapter *); int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); void (*iface_work)(struct work_struct *work); + void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); }; struct mwifiex_adapter { diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 08e9ec065275..6cc8519c0f40 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -222,7 +222,13 @@ static void mwifiex_usb_rx_complete(struct urb *urb) else size = MWIFIEX_RX_DATA_BUF_SIZE; - mwifiex_usb_submit_rx_urb(context, size); + if (card->rx_cmd_ep == context->ep) { + mwifiex_usb_submit_rx_urb(context, size); + } else { + context->skb = NULL; + if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING) + mwifiex_usb_submit_rx_urb(context, size); + } return; } @@ -978,6 +984,20 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) return 0; } +static void mwifiex_usb_submit_rem_rx_urbs(struct mwifiex_adapter *adapter) +{ + struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; + int i; + struct urb_context *ctx; + + for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) { + if (card->rx_data_list[i].skb) + continue; + ctx = &card->rx_data_list[i]; + mwifiex_usb_submit_rx_urb(ctx, MWIFIEX_RX_DATA_BUF_SIZE); + } +} + static struct mwifiex_if_ops usb_ops = { .register_dev = mwifiex_register_dev, .unregister_dev = mwifiex_unregister_dev, @@ -989,6 +1009,7 @@ static struct mwifiex_if_ops usb_ops = { .cmdrsp_complete = mwifiex_usb_cmd_event_complete, .event_complete = mwifiex_usb_cmd_event_complete, .host_to_card = mwifiex_usb_host_to_card, + .submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs, }; /* This function initializes the USB driver module. -- GitLab From bfd713bc1a5d7f01e3d7febe0849b21ae1355c7c Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 5 Nov 2014 17:04:30 +0530 Subject: [PATCH 4306/9457] mwifiex: do not setup AMPDU/AMSDU with broadcast receiver It is observed that device sometimes sends BA setup requests for broadcast mac address. This patch adds a check to avoid checking availability of AMPDU/AMSDU streams for broadcast mac address. Signed-off-by: Amitkumar Karwar Signed-off-by: Avinash Patil Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 2ee268b632be..f275675cdbd3 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -84,6 +84,8 @@ mwifiex_is_amsdu_in_ampdu_allowed(struct mwifiex_private *priv, { struct mwifiex_tx_ba_stream_tbl *tx_tbl; + if (is_broadcast_ether_addr(ptr->ra)) + return false; tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra); if (tx_tbl) return tx_tbl->amsdu; @@ -96,6 +98,8 @@ static inline u8 mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ptr, int tid) { + if (is_broadcast_ether_addr(ptr->ra)) + return false; if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { return mwifiex_is_station_ampdu_allowed(priv, ptr, tid); } else { -- GitLab From d7d8b83473e6932cfe9f89e6d839f27abf35b319 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 5 Nov 2014 17:04:31 +0530 Subject: [PATCH 4307/9457] mwifiex: fix warning while starting BSS We see this warning while starting mwifiex AP: Unsupported RX-STBC, default to 2x2 This was happening because of wrong offset while copying HT capabilities from BSS configuration of start_ap handler. Signed-off-by: Amitkumar Karwar Signed-off-by: Avinash Patil Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/uap_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 300bab438011..0f347fdefa0a 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -167,7 +167,7 @@ mwifiex_set_ht_params(struct mwifiex_private *priv, ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail, params->beacon.tail_len); if (ht_ie) { - memcpy(&bss_cfg->ht_cap, ht_ie + 2, + memcpy(&bss_cfg->ht_cap, ht_ie, sizeof(struct ieee80211_ht_cap)); cap_info = le16_to_cpu(bss_cfg->ht_cap.cap_info); memset(&bss_cfg->ht_cap.mcs, 0, -- GitLab From 911ea79f435302fabefa305d3649efd4e205672b Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:18 +0100 Subject: [PATCH 4308/9457] ath9k: add struct ath_spec_scan_priv and move rfs_chan_spec_scan to this struct. We will need it for common spectral scan code. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/spectral.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/spectral.h | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index adb49a9813f1..d6e4eb5f8441 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -1029,9 +1029,9 @@ struct ath_softc { u64 dfs_prev_pulse_ts; u32 wow_enabled; /* relay(fs) channel for spectral scan */ - struct rchan *rfs_chan_spec_scan; enum spectral_mode spectral_mode; struct ath_spec_scan spec_config; + struct ath_spec_scan_priv spec_priv; struct ieee80211_vif *tx99_vif; struct sk_buff *tx99_skb; diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 8f68426ca653..348dddd38952 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -28,12 +28,12 @@ static void ath_debug_send_fft_sample(struct ath_softc *sc, struct fft_sample_tlv *fft_sample_tlv) { int length; - if (!sc->rfs_chan_spec_scan) + if (!sc->spec_priv.rfs_chan_spec_scan) return; length = __be16_to_cpu(fft_sample_tlv->length) + sizeof(*fft_sample_tlv); - relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, length); + relay_write(sc->spec_priv.rfs_chan_spec_scan, fft_sample_tlv, length); } /* returns 1 if this was a spectral frame, even if not handled. */ @@ -508,15 +508,15 @@ static struct rchan_callbacks rfs_spec_scan_cb = { void ath9k_spectral_deinit_debug(struct ath_softc *sc) { - if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { - relay_close(sc->rfs_chan_spec_scan); - sc->rfs_chan_spec_scan = NULL; + if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->spec_priv.rfs_chan_spec_scan) { + relay_close(sc->spec_priv.rfs_chan_spec_scan); + sc->spec_priv.rfs_chan_spec_scan = NULL; } } void ath9k_spectral_init_debug(struct ath_softc *sc) { - sc->rfs_chan_spec_scan = relay_open("spectral_scan", + sc->spec_priv.rfs_chan_spec_scan = relay_open("spectral_scan", sc->debug.debugfs_phy, 1024, 256, &rfs_spec_scan_cb, NULL); diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 7b410c6858b0..533d8a1a8a9d 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -92,6 +92,9 @@ struct ath_ht20_40_fft_packet { struct ath_radar_info radar_info; } __packed; +struct ath_spec_scan_priv { + struct rchan *rfs_chan_spec_scan; +}; #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet)) -- GitLab From 8391f60194bd0d9ab489105381df6455afe1f39a Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:19 +0100 Subject: [PATCH 4309/9457] ath9k: move spectral_mode to ath_spec_scan_priv Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/channel.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- drivers/net/wireless/ath/ath9k/spectral.c | 2 +- drivers/net/wireless/ath/ath9k/spectral.h | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d6e4eb5f8441..859f93e9900e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -1029,7 +1029,6 @@ struct ath_softc { u64 dfs_prev_pulse_ts; u32 wow_enabled; /* relay(fs) channel for spectral scan */ - enum spectral_mode spectral_mode; struct ath_spec_scan spec_config; struct ath_spec_scan_priv spec_priv; diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index c7234d5dda34..25a21fa389ff 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -92,7 +92,7 @@ static int ath_set_channel(struct ath_softc *sc) } else { /* perform spectral scan if requested. */ if (test_bit(ATH_OP_SCANNING, &common->op_flags) && - sc->spectral_mode == SPECTRAL_CHANSCAN) + sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN) ath9k_spectral_scan_trigger(hw); } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3ab5f630062b..c074658dbf54 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1363,7 +1363,7 @@ void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) * configuration, otherwise the register will have its values reset * (on my ar9220 to value 0x01002310) */ - ath9k_spectral_scan_config(hw, sc->spectral_mode); + ath9k_spectral_scan_config(hw, sc->spec_priv.spectral_mode); ath9k_hw_ops(ah)->spectral_scan_trigger(ah); ath9k_ps_restore(sc); } @@ -1404,7 +1404,7 @@ int ath9k_spectral_scan_config(struct ieee80211_hw *hw, ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_config); ath9k_ps_restore(sc); - sc->spectral_mode = spectral_mode; + sc->spec_priv.spectral_mode = spectral_mode; return 0; } diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 348dddd38952..3a394e1fefdc 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -215,7 +215,7 @@ static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, char *mode = ""; unsigned int len; - switch (sc->spectral_mode) { + switch (sc->spec_priv.spectral_mode) { case SPECTRAL_DISABLED: mode = "disable"; break; diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 533d8a1a8a9d..0acdc432c771 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -94,6 +94,7 @@ struct ath_ht20_40_fft_packet { struct ath_spec_scan_priv { struct rchan *rfs_chan_spec_scan; + enum spectral_mode spectral_mode; }; #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet)) -- GitLab From 21af25d00b8bdf03a899b316d41d31ac3eafaf78 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:20 +0100 Subject: [PATCH 4310/9457] ath9k: move spec_config to ath_spec_scan_priv Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-- drivers/net/wireless/ath/ath9k/init.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/main.c | 12 ++++++------ drivers/net/wireless/ath/ath9k/spectral.c | 16 ++++++++-------- drivers/net/wireless/ath/ath9k/spectral.h | 2 ++ 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 859f93e9900e..dee1f2a58538 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -1028,8 +1028,7 @@ struct ath_softc { struct dfs_pattern_detector *dfs_detector; u64 dfs_prev_pulse_ts; u32 wow_enabled; - /* relay(fs) channel for spectral scan */ - struct ath_spec_scan spec_config; + struct ath_spec_scan_priv spec_priv; struct ieee80211_vif *tx99_vif; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 8d3c3364326a..aebafaa28dce 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -351,12 +351,12 @@ static void ath9k_init_misc(struct ath_softc *sc) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; - sc->spec_config.enabled = 0; - sc->spec_config.short_repeat = true; - sc->spec_config.count = 8; - sc->spec_config.endless = false; - sc->spec_config.period = 0xFF; - sc->spec_config.fft_period = 0xF; + sc->spec_priv.spec_config.enabled = 0; + sc->spec_priv.spec_config.short_repeat = true; + sc->spec_priv.spec_config.count = 8; + sc->spec_priv.spec_config.endless = false; + sc->spec_priv.spec_config.period = 0xFF; + sc->spec_priv.spec_config.fft_period = 0xF; } static void ath9k_init_pcoem_platform(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c074658dbf54..f9641ee6aeb6 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1382,26 +1382,26 @@ int ath9k_spectral_scan_config(struct ieee80211_hw *hw, switch (spectral_mode) { case SPECTRAL_DISABLED: - sc->spec_config.enabled = 0; + sc->spec_priv.spec_config.enabled = 0; break; case SPECTRAL_BACKGROUND: /* send endless samples. * TODO: is this really useful for "background"? */ - sc->spec_config.endless = 1; - sc->spec_config.enabled = 1; + sc->spec_priv.spec_config.endless = 1; + sc->spec_priv.spec_config.enabled = 1; break; case SPECTRAL_CHANSCAN: case SPECTRAL_MANUAL: - sc->spec_config.endless = 0; - sc->spec_config.enabled = 1; + sc->spec_priv.spec_config.endless = 0; + sc->spec_priv.spec_config.enabled = 1; break; default: return -1; } ath9k_ps_wakeup(sc); - ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_config); + ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_priv.spec_config); ath9k_ps_restore(sc); sc->spec_priv.spectral_mode = spectral_mode; diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 3a394e1fefdc..555fc2a6851e 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -292,7 +292,7 @@ static ssize_t read_file_spectral_short_repeat(struct file *file, char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_config.short_repeat); + len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.short_repeat); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -316,7 +316,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file, if (val > 1) return -EINVAL; - sc->spec_config.short_repeat = val; + sc->spec_priv.spec_config.short_repeat = val; return count; } @@ -340,7 +340,7 @@ static ssize_t read_file_spectral_count(struct file *file, char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_config.count); + len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.count); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -364,7 +364,7 @@ static ssize_t write_file_spectral_count(struct file *file, if (val > 255) return -EINVAL; - sc->spec_config.count = val; + sc->spec_priv.spec_config.count = val; return count; } @@ -388,7 +388,7 @@ static ssize_t read_file_spectral_period(struct file *file, char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_config.period); + len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.period); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -412,7 +412,7 @@ static ssize_t write_file_spectral_period(struct file *file, if (val > 255) return -EINVAL; - sc->spec_config.period = val; + sc->spec_priv.spec_config.period = val; return count; } @@ -436,7 +436,7 @@ static ssize_t read_file_spectral_fft_period(struct file *file, char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_config.fft_period); + len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.fft_period); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -460,7 +460,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file, if (val > 15) return -EINVAL; - sc->spec_config.fft_period = val; + sc->spec_priv.spec_config.fft_period = val; return count; } diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 0acdc432c771..dfe6f68cf5a3 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -93,8 +93,10 @@ struct ath_ht20_40_fft_packet { } __packed; struct ath_spec_scan_priv { + /* relay(fs) channel for spectral scan */ struct rchan *rfs_chan_spec_scan; enum spectral_mode spectral_mode; + struct ath_spec_scan spec_config; }; #define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet)) -- GitLab From c10b75af4344fe0e678d167cb401a94f565e978c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:21 +0100 Subject: [PATCH 4311/9457] ath9k: use struct dentry by ath9k_spectral_init_debug this will alow us to make ath_softc independent code. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 2 +- drivers/net/wireless/ath/ath9k/spectral.c | 14 +++++++------- drivers/net/wireless/ath/ath9k/spectral.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 2a2a17df5fb3..f0a802e8b0de 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1330,7 +1330,7 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_dfs_init_debug(sc); ath9k_tx99_init_debug(sc); - ath9k_spectral_init_debug(sc); + ath9k_spectral_init_debug(sc, sc->debug.debugfs_phy); debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_dma); diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 555fc2a6851e..d2723803494d 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -514,30 +514,30 @@ void ath9k_spectral_deinit_debug(struct ath_softc *sc) } } -void ath9k_spectral_init_debug(struct ath_softc *sc) +void ath9k_spectral_init_debug(struct ath_softc *sc, struct dentry *debugfs_phy) { sc->spec_priv.rfs_chan_spec_scan = relay_open("spectral_scan", - sc->debug.debugfs_phy, + debugfs_phy, 1024, 256, &rfs_spec_scan_cb, NULL); debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, + debugfs_phy, sc, &fops_spec_scan_ctl); debugfs_create_file("spectral_short_repeat", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, + debugfs_phy, sc, &fops_spectral_short_repeat); debugfs_create_file("spectral_count", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, + debugfs_phy, sc, &fops_spectral_count); debugfs_create_file("spectral_period", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, + debugfs_phy, sc, &fops_spectral_period); debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, + debugfs_phy, sc, &fops_spectral_fft_period); } diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index dfe6f68cf5a3..22695892963f 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -129,7 +129,7 @@ static inline u8 spectral_bitmap_weight(u8 *bins) return bins[0] & 0x3f; } -void ath9k_spectral_init_debug(struct ath_softc *sc); +void ath9k_spectral_init_debug(struct ath_softc *sc, struct dentry *debugfs_phy); void ath9k_spectral_deinit_debug(struct ath_softc *sc); void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); -- GitLab From dd7657be756551b23b3431d81e66a8d95a72c923 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:22 +0100 Subject: [PATCH 4312/9457] ath9k: add ath_hw to ath_spec_scan_priv spectral code mostly depends on ath_hw, not on ath_softc Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 1 + drivers/net/wireless/ath/ath9k/spectral.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index aebafaa28dce..d4a6092d4ddb 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -351,6 +351,7 @@ static void ath9k_init_misc(struct ath_softc *sc) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; + sc->spec_priv.ah = sc->sc_ah; sc->spec_priv.spec_config.enabled = 0; sc->spec_priv.spec_config.short_repeat = true; sc->spec_priv.spec_config.count = 8; diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 22695892963f..638320d4e381 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -93,6 +93,7 @@ struct ath_ht20_40_fft_packet { } __packed; struct ath_spec_scan_priv { + struct ath_hw *ah; /* relay(fs) channel for spectral scan */ struct rchan *rfs_chan_spec_scan; enum spectral_mode spectral_mode; -- GitLab From 1111d426ef6a62903a8427a80c2a20cdf0380349 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:23 +0100 Subject: [PATCH 4313/9457] ath9k: remove all struct ath_softc dependencies from spectral code Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 4 +- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/ath/ath9k/spectral.c | 87 ++++++++++++----------- drivers/net/wireless/ath/ath9k/spectral.h | 8 +-- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index f0a802e8b0de..6492619851a0 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1310,7 +1310,7 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, void ath9k_deinit_debug(struct ath_softc *sc) { - ath9k_spectral_deinit_debug(sc); + ath9k_spectral_deinit_debug(&sc->spec_priv); } int ath9k_init_debug(struct ath_hw *ah) @@ -1330,7 +1330,7 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_dfs_init_debug(sc); ath9k_tx99_init_debug(sc); - ath9k_spectral_init_debug(sc, sc->debug.debugfs_phy); + ath9k_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_dma); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6914e21816e4..e97c6936da0f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -870,7 +870,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, */ if (rx_stats->rs_status & ATH9K_RXERR_PHY) { ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime); - if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) + if (ath_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime)) RX_STAT_INC(rx_spectral); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index d2723803494d..50af6bcf18e5 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -24,23 +24,24 @@ static s8 fix_rssi_inv_only(u8 rssi_val) return (s8) rssi_val; } -static void ath_debug_send_fft_sample(struct ath_softc *sc, +static void ath_debug_send_fft_sample(struct ath_spec_scan_priv *spec_priv, struct fft_sample_tlv *fft_sample_tlv) { int length; - if (!sc->spec_priv.rfs_chan_spec_scan) + if (!spec_priv->rfs_chan_spec_scan) return; length = __be16_to_cpu(fft_sample_tlv->length) + sizeof(*fft_sample_tlv); - relay_write(sc->spec_priv.rfs_chan_spec_scan, fft_sample_tlv, length); + relay_write(spec_priv->rfs_chan_spec_scan, fft_sample_tlv, length); } /* returns 1 if this was a spectral frame, even if not handled. */ -int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, +int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf) { - struct ath_hw *ah = sc->sc_ah; + struct ath_hw *ah = spec_priv->ah; + struct ath_common *common = ath9k_hw_common(spec_priv->ah); u8 num_bins, *bins, *vdata = (u8 *)hdr; struct fft_sample_ht20 fft_sample_20; struct fft_sample_ht20_40 fft_sample_40; @@ -67,7 +68,7 @@ int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) return 0; - chan_type = cfg80211_get_chandef_type(&sc->hw->conf.chandef); + chan_type = cfg80211_get_chandef_type(&common->hw->conf.chandef); if ((chan_type == NL80211_CHAN_HT40MINUS) || (chan_type == NL80211_CHAN_HT40PLUS)) { fft_len = SPECTRAL_HT20_40_TOTAL_DATA_LEN; @@ -199,7 +200,7 @@ int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, tlv = (struct fft_sample_tlv *)&fft_sample_20; } - ath_debug_send_fft_sample(sc, tlv); + ath_debug_send_fft_sample(spec_priv, tlv); return 1; } @@ -211,11 +212,11 @@ int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; char *mode = ""; unsigned int len; - switch (sc->spec_priv.spectral_mode) { + switch (spec_priv->spectral_mode) { case SPECTRAL_DISABLED: mode = "disable"; break; @@ -237,8 +238,8 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_spec_scan_priv *spec_priv = file->private_data; + struct ath_common *common = ath9k_hw_common(spec_priv->ah); char buf[32]; ssize_t len; @@ -252,18 +253,18 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, buf[len] = '\0'; if (strncmp("trigger", buf, 7) == 0) { - ath9k_spectral_scan_trigger(sc->hw); + ath9k_spectral_scan_trigger(common->hw); } else if (strncmp("background", buf, 10) == 0) { - ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND); + ath9k_spectral_scan_config(common->hw, SPECTRAL_BACKGROUND); ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); } else if (strncmp("chanscan", buf, 8) == 0) { - ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN); + ath9k_spectral_scan_config(common->hw, SPECTRAL_CHANSCAN); ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n"); } else if (strncmp("manual", buf, 6) == 0) { - ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL); + ath9k_spectral_scan_config(common->hw, SPECTRAL_MANUAL); ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n"); } else if (strncmp("disable", buf, 7) == 0) { - ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED); + ath9k_spectral_scan_config(common->hw, SPECTRAL_DISABLED); ath_dbg(common, CONFIG, "spectral scan: disabled\n"); } else { return -EINVAL; @@ -288,11 +289,11 @@ static ssize_t read_file_spectral_short_repeat(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.short_repeat); + len = sprintf(buf, "%d\n", spec_priv->spec_config.short_repeat); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -300,7 +301,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; unsigned long val; char buf[32]; ssize_t len; @@ -316,7 +317,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file, if (val > 1) return -EINVAL; - sc->spec_priv.spec_config.short_repeat = val; + spec_priv->spec_config.short_repeat = val; return count; } @@ -336,11 +337,11 @@ static ssize_t read_file_spectral_count(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.count); + len = sprintf(buf, "%d\n", spec_priv->spec_config.count); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -348,7 +349,7 @@ static ssize_t write_file_spectral_count(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; unsigned long val; char buf[32]; ssize_t len; @@ -364,7 +365,7 @@ static ssize_t write_file_spectral_count(struct file *file, if (val > 255) return -EINVAL; - sc->spec_priv.spec_config.count = val; + spec_priv->spec_config.count = val; return count; } @@ -384,11 +385,11 @@ static ssize_t read_file_spectral_period(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.period); + len = sprintf(buf, "%d\n", spec_priv->spec_config.period); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -396,7 +397,7 @@ static ssize_t write_file_spectral_period(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; unsigned long val; char buf[32]; ssize_t len; @@ -412,7 +413,7 @@ static ssize_t write_file_spectral_period(struct file *file, if (val > 255) return -EINVAL; - sc->spec_priv.spec_config.period = val; + spec_priv->spec_config.period = val; return count; } @@ -432,11 +433,11 @@ static ssize_t read_file_spectral_fft_period(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; char buf[32]; unsigned int len; - len = sprintf(buf, "%d\n", sc->spec_priv.spec_config.fft_period); + len = sprintf(buf, "%d\n", spec_priv->spec_config.fft_period); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -444,7 +445,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct ath_softc *sc = file->private_data; + struct ath_spec_scan_priv *spec_priv = file->private_data; unsigned long val; char buf[32]; ssize_t len; @@ -460,7 +461,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file, if (val > 15) return -EINVAL; - sc->spec_priv.spec_config.fft_period = val; + spec_priv->spec_config.fft_period = val; return count; } @@ -506,38 +507,38 @@ static struct rchan_callbacks rfs_spec_scan_cb = { /* Debug Init/Deinit */ /*********************/ -void ath9k_spectral_deinit_debug(struct ath_softc *sc) +void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) { - if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->spec_priv.rfs_chan_spec_scan) { - relay_close(sc->spec_priv.rfs_chan_spec_scan); - sc->spec_priv.rfs_chan_spec_scan = NULL; + if (config_enabled(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) { + relay_close(spec_priv->rfs_chan_spec_scan); + spec_priv->rfs_chan_spec_scan = NULL; } } -void ath9k_spectral_init_debug(struct ath_softc *sc, struct dentry *debugfs_phy) +void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy) { - sc->spec_priv.rfs_chan_spec_scan = relay_open("spectral_scan", + spec_priv->rfs_chan_spec_scan = relay_open("spectral_scan", debugfs_phy, 1024, 256, &rfs_spec_scan_cb, NULL); debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, - debugfs_phy, sc, + debugfs_phy, spec_priv, &fops_spec_scan_ctl); debugfs_create_file("spectral_short_repeat", S_IRUSR | S_IWUSR, - debugfs_phy, sc, + debugfs_phy, spec_priv, &fops_spectral_short_repeat); debugfs_create_file("spectral_count", S_IRUSR | S_IWUSR, - debugfs_phy, sc, + debugfs_phy, spec_priv, &fops_spectral_count); debugfs_create_file("spectral_period", S_IRUSR | S_IWUSR, - debugfs_phy, sc, + debugfs_phy, spec_priv, &fops_spectral_period); debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR, - debugfs_phy, sc, + debugfs_phy, spec_priv, &fops_spectral_fft_period); } diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 638320d4e381..555fcbbbcddf 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -130,18 +130,18 @@ static inline u8 spectral_bitmap_weight(u8 *bins) return bins[0] & 0x3f; } -void ath9k_spectral_init_debug(struct ath_softc *sc, struct dentry *debugfs_phy); -void ath9k_spectral_deinit_debug(struct ath_softc *sc); +void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); +void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); int ath9k_spectral_scan_config(struct ieee80211_hw *hw, enum spectral_mode spectral_mode); #ifdef CONFIG_ATH9K_DEBUGFS -int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, +int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf); #else -static inline int ath_process_fft(struct ath_softc *sc, +static inline int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf) { -- GitLab From 0198c2e2987c5cd4980f15126d7c68759f4def95 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:24 +0100 Subject: [PATCH 4314/9457] ath: add struct ath_ps_ops we will need it to make common code Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 9c56ecbae37f..76668dc79c0e 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -134,6 +134,11 @@ struct ath_ops { struct ath_common; struct ath_bus_ops; +struct ath_ps_ops { + void (*wakeup)(struct ath_common *common); + void (*restore)(struct ath_common *common); +}; + struct ath_common { void *ah; void *priv; @@ -168,6 +173,7 @@ struct ath_common { struct ath_regulatory reg_world_copy; const struct ath_ops *ops; const struct ath_bus_ops *bus_ops; + const struct ath_ps_ops *ps_ops; bool btcoex_enabled; bool disable_ani; @@ -177,6 +183,11 @@ struct ath_common { struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; }; +static inline const struct ath_ps_ops *ath_ps_ops(struct ath_common *common) +{ + return common->ps_ops; +} + struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, u32 len, gfp_t gfp_mask); -- GitLab From 99d2217b731e664aa31001839f12944b1e114a08 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:25 +0100 Subject: [PATCH 4315/9457] ath9k: add ath_ps_ops bindings Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d4a6092d4ddb..4124140a4d35 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -88,6 +88,21 @@ static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { static void ath9k_deinit_softc(struct ath_softc *sc); +void ath9k_op_ps_wakeup(struct ath_common *common) +{ + ath9k_ps_wakeup((struct ath_softc *) common->priv); +} + +void ath9k_op_ps_restore(struct ath_common *common) +{ + ath9k_ps_restore((struct ath_softc *) common->priv); +} + +struct ath_ps_ops ath9k_ps_ops = { + .wakeup = ath9k_op_ps_wakeup, + .restore = ath9k_op_ps_restore, +}; + /* * Read and write, they both share the same lock. We do this to serialize * reads and writes on Atheros 802.11n PCI devices only. This is required @@ -543,6 +558,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, common->ops = &ah->reg_ops; common->bus_ops = bus_ops; + common->ps_ops = &ath9k_ps_ops; common->ah = ah; common->hw = sc->hw; common->priv = sc; -- GitLab From 934bdc73dd3029c1b91e1a3538268b4afccd58cf Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:26 +0100 Subject: [PATCH 4316/9457] ath9k: use ath_ps_ops in ath9k_spectral_scan_ Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f9641ee6aeb6..412b0a632f26 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1352,7 +1352,7 @@ void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) return; } - ath9k_ps_wakeup(sc); + ath_ps_ops(common)->wakeup(common); rxfilter = ath9k_hw_getrxfilter(ah); ath9k_hw_setrxfilter(ah, rxfilter | ATH9K_RX_FILTER_PHYRADAR | @@ -1365,7 +1365,7 @@ void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) */ ath9k_spectral_scan_config(hw, sc->spec_priv.spectral_mode); ath9k_hw_ops(ah)->spectral_scan_trigger(ah); - ath9k_ps_restore(sc); + ath_ps_ops(common)->restore(common); } int ath9k_spectral_scan_config(struct ieee80211_hw *hw, @@ -1400,9 +1400,9 @@ int ath9k_spectral_scan_config(struct ieee80211_hw *hw, return -1; } - ath9k_ps_wakeup(sc); + ath_ps_ops(common)->wakeup(common); ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_priv.spec_config); - ath9k_ps_restore(sc); + ath_ps_ops(common)->restore(common); sc->spec_priv.spectral_mode = spectral_mode; -- GitLab From ef948da55f20edbb68dac427b7e067c805c852f5 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:27 +0100 Subject: [PATCH 4317/9457] ath9k: use ath_common instead of ieee80211_hw in ath9k_spectral_scan_ we don't have here any ieee80211_hw dependencies any way. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 12 +++++------- drivers/net/wireless/ath/ath9k/spectral.c | 10 +++++----- drivers/net/wireless/ath/ath9k/spectral.h | 4 ++-- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 25a21fa389ff..814178ad36a7 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -93,7 +93,7 @@ static int ath_set_channel(struct ath_softc *sc) /* perform spectral scan if requested. */ if (test_bit(ATH_OP_SCANNING, &common->op_flags) && sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN) - ath9k_spectral_scan_trigger(hw); + ath9k_spectral_scan_trigger(common); } return 0; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 412b0a632f26..567fb5170d1b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1337,11 +1337,10 @@ static void ath9k_disable_ps(struct ath_softc *sc) ath_dbg(common, PS, "PowerSave disabled\n"); } -void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) +void ath9k_spectral_scan_trigger(struct ath_common *common) { - struct ath_softc *sc = hw->priv; + struct ath_softc *sc = common->priv; struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); u32 rxfilter; if (config_enabled(CONFIG_ATH9K_TX99)) @@ -1363,17 +1362,16 @@ void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) * configuration, otherwise the register will have its values reset * (on my ar9220 to value 0x01002310) */ - ath9k_spectral_scan_config(hw, sc->spec_priv.spectral_mode); + ath9k_spectral_scan_config(common, sc->spec_priv.spectral_mode); ath9k_hw_ops(ah)->spectral_scan_trigger(ah); ath_ps_ops(common)->restore(common); } -int ath9k_spectral_scan_config(struct ieee80211_hw *hw, +int ath9k_spectral_scan_config(struct ath_common *common, enum spectral_mode spectral_mode) { - struct ath_softc *sc = hw->priv; + struct ath_softc *sc = common->priv; struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { ath_err(common, "spectrum analyzer not implemented on this hardware\n"); diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 50af6bcf18e5..4549dce60c16 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -253,18 +253,18 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, buf[len] = '\0'; if (strncmp("trigger", buf, 7) == 0) { - ath9k_spectral_scan_trigger(common->hw); + ath9k_spectral_scan_trigger(common); } else if (strncmp("background", buf, 10) == 0) { - ath9k_spectral_scan_config(common->hw, SPECTRAL_BACKGROUND); + ath9k_spectral_scan_config(common, SPECTRAL_BACKGROUND); ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); } else if (strncmp("chanscan", buf, 8) == 0) { - ath9k_spectral_scan_config(common->hw, SPECTRAL_CHANSCAN); + ath9k_spectral_scan_config(common, SPECTRAL_CHANSCAN); ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n"); } else if (strncmp("manual", buf, 6) == 0) { - ath9k_spectral_scan_config(common->hw, SPECTRAL_MANUAL); + ath9k_spectral_scan_config(common, SPECTRAL_MANUAL); ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n"); } else if (strncmp("disable", buf, 7) == 0) { - ath9k_spectral_scan_config(common->hw, SPECTRAL_DISABLED); + ath9k_spectral_scan_config(common, SPECTRAL_DISABLED); ath_dbg(common, CONFIG, "spectral scan: disabled\n"); } else { return -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 555fcbbbcddf..53660e60dd25 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -133,8 +133,8 @@ static inline u8 spectral_bitmap_weight(u8 *bins) void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); -void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); -int ath9k_spectral_scan_config(struct ieee80211_hw *hw, +void ath9k_spectral_scan_trigger(struct ath_common *common); +int ath9k_spectral_scan_config(struct ath_common *common, enum spectral_mode spectral_mode); #ifdef CONFIG_ATH9K_DEBUGFS -- GitLab From 963916dfe2907d91eb8a250d12d2b5ae5a1bb343 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:28 +0100 Subject: [PATCH 4318/9457] ath9k: make ath9k_spectral_scan_ do not depend on ath_softc last preparation before moving ath9k_spectral_scan_ to spectral.c Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 26 +++++++++++------------ drivers/net/wireless/ath/ath9k/spectral.c | 10 ++++----- drivers/net/wireless/ath/ath9k/spectral.h | 4 +++- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 814178ad36a7..32ce931c2404 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -93,7 +93,7 @@ static int ath_set_channel(struct ath_softc *sc) /* perform spectral scan if requested. */ if (test_bit(ATH_OP_SCANNING, &common->op_flags) && sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN) - ath9k_spectral_scan_trigger(common); + ath9k_spectral_scan_trigger(common, &sc->spec_priv); } return 0; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 567fb5170d1b..54e3e41a591c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1337,10 +1337,10 @@ static void ath9k_disable_ps(struct ath_softc *sc) ath_dbg(common, PS, "PowerSave disabled\n"); } -void ath9k_spectral_scan_trigger(struct ath_common *common) +void ath9k_spectral_scan_trigger(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv) { - struct ath_softc *sc = common->priv; - struct ath_hw *ah = sc->sc_ah; + struct ath_hw *ah = spec_priv->ah; u32 rxfilter; if (config_enabled(CONFIG_ATH9K_TX99)) @@ -1362,16 +1362,16 @@ void ath9k_spectral_scan_trigger(struct ath_common *common) * configuration, otherwise the register will have its values reset * (on my ar9220 to value 0x01002310) */ - ath9k_spectral_scan_config(common, sc->spec_priv.spectral_mode); + ath9k_spectral_scan_config(common, spec_priv, spec_priv->spectral_mode); ath9k_hw_ops(ah)->spectral_scan_trigger(ah); ath_ps_ops(common)->restore(common); } int ath9k_spectral_scan_config(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv, enum spectral_mode spectral_mode) { - struct ath_softc *sc = common->priv; - struct ath_hw *ah = sc->sc_ah; + struct ath_hw *ah = spec_priv->ah; if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { ath_err(common, "spectrum analyzer not implemented on this hardware\n"); @@ -1380,29 +1380,29 @@ int ath9k_spectral_scan_config(struct ath_common *common, switch (spectral_mode) { case SPECTRAL_DISABLED: - sc->spec_priv.spec_config.enabled = 0; + spec_priv->spec_config.enabled = 0; break; case SPECTRAL_BACKGROUND: /* send endless samples. * TODO: is this really useful for "background"? */ - sc->spec_priv.spec_config.endless = 1; - sc->spec_priv.spec_config.enabled = 1; + spec_priv->spec_config.endless = 1; + spec_priv->spec_config.enabled = 1; break; case SPECTRAL_CHANSCAN: case SPECTRAL_MANUAL: - sc->spec_priv.spec_config.endless = 0; - sc->spec_priv.spec_config.enabled = 1; + spec_priv->spec_config.endless = 0; + spec_priv->spec_config.enabled = 1; break; default: return -1; } ath_ps_ops(common)->wakeup(common); - ath9k_hw_ops(ah)->spectral_scan_config(ah, &sc->spec_priv.spec_config); + ath9k_hw_ops(ah)->spectral_scan_config(ah, &spec_priv->spec_config); ath_ps_ops(common)->restore(common); - sc->spec_priv.spectral_mode = spectral_mode; + spec_priv->spectral_mode = spectral_mode; return 0; } diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 4549dce60c16..756d63ea6205 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -253,18 +253,18 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, buf[len] = '\0'; if (strncmp("trigger", buf, 7) == 0) { - ath9k_spectral_scan_trigger(common); + ath9k_spectral_scan_trigger(common, spec_priv); } else if (strncmp("background", buf, 10) == 0) { - ath9k_spectral_scan_config(common, SPECTRAL_BACKGROUND); + ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_BACKGROUND); ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); } else if (strncmp("chanscan", buf, 8) == 0) { - ath9k_spectral_scan_config(common, SPECTRAL_CHANSCAN); + ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_CHANSCAN); ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n"); } else if (strncmp("manual", buf, 6) == 0) { - ath9k_spectral_scan_config(common, SPECTRAL_MANUAL); + ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_MANUAL); ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n"); } else if (strncmp("disable", buf, 7) == 0) { - ath9k_spectral_scan_config(common, SPECTRAL_DISABLED); + ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_DISABLED); ath_dbg(common, CONFIG, "spectral scan: disabled\n"); } else { return -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index 53660e60dd25..77582cf743ac 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -133,8 +133,10 @@ static inline u8 spectral_bitmap_weight(u8 *bins) void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); -void ath9k_spectral_scan_trigger(struct ath_common *common); +void ath9k_spectral_scan_trigger(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv); int ath9k_spectral_scan_config(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv, enum spectral_mode spectral_mode); #ifdef CONFIG_ATH9K_DEBUGFS -- GitLab From f00a422cc81ef665f5098c0bc43cb0c616e55a9b Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:29 +0100 Subject: [PATCH 4319/9457] ath9k: move ath9k_spectral_scan_ from main.c to spectral.c Now we should be ready to make this code common. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 70 ----------------------- drivers/net/wireless/ath/ath9k/spectral.c | 70 +++++++++++++++++++++++ 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 54e3e41a591c..1a88614eb73e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1337,76 +1337,6 @@ static void ath9k_disable_ps(struct ath_softc *sc) ath_dbg(common, PS, "PowerSave disabled\n"); } -void ath9k_spectral_scan_trigger(struct ath_common *common, - struct ath_spec_scan_priv *spec_priv) -{ - struct ath_hw *ah = spec_priv->ah; - u32 rxfilter; - - if (config_enabled(CONFIG_ATH9K_TX99)) - return; - - if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { - ath_err(common, "spectrum analyzer not implemented on this hardware\n"); - return; - } - - ath_ps_ops(common)->wakeup(common); - rxfilter = ath9k_hw_getrxfilter(ah); - ath9k_hw_setrxfilter(ah, rxfilter | - ATH9K_RX_FILTER_PHYRADAR | - ATH9K_RX_FILTER_PHYERR); - - /* TODO: usually this should not be neccesary, but for some reason - * (or in some mode?) the trigger must be called after the - * configuration, otherwise the register will have its values reset - * (on my ar9220 to value 0x01002310) - */ - ath9k_spectral_scan_config(common, spec_priv, spec_priv->spectral_mode); - ath9k_hw_ops(ah)->spectral_scan_trigger(ah); - ath_ps_ops(common)->restore(common); -} - -int ath9k_spectral_scan_config(struct ath_common *common, - struct ath_spec_scan_priv *spec_priv, - enum spectral_mode spectral_mode) -{ - struct ath_hw *ah = spec_priv->ah; - - if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { - ath_err(common, "spectrum analyzer not implemented on this hardware\n"); - return -1; - } - - switch (spectral_mode) { - case SPECTRAL_DISABLED: - spec_priv->spec_config.enabled = 0; - break; - case SPECTRAL_BACKGROUND: - /* send endless samples. - * TODO: is this really useful for "background"? - */ - spec_priv->spec_config.endless = 1; - spec_priv->spec_config.enabled = 1; - break; - case SPECTRAL_CHANSCAN: - case SPECTRAL_MANUAL: - spec_priv->spec_config.endless = 0; - spec_priv->spec_config.enabled = 1; - break; - default: - return -1; - } - - ath_ps_ops(common)->wakeup(common); - ath9k_hw_ops(ah)->spectral_scan_config(ah, &spec_priv->spec_config); - ath_ps_ops(common)->restore(common); - - spec_priv->spectral_mode = spectral_mode; - - return 0; -} - static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { struct ath_softc *sc = hw->priv; diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 756d63ea6205..bf85740ab84b 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c @@ -234,6 +234,76 @@ static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, mode, len); } +void ath9k_spectral_scan_trigger(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv) +{ + struct ath_hw *ah = spec_priv->ah; + u32 rxfilter; + + if (config_enabled(CONFIG_ATH9K_TX99)) + return; + + if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { + ath_err(common, "spectrum analyzer not implemented on this hardware\n"); + return; + } + + ath_ps_ops(common)->wakeup(common); + rxfilter = ath9k_hw_getrxfilter(ah); + ath9k_hw_setrxfilter(ah, rxfilter | + ATH9K_RX_FILTER_PHYRADAR | + ATH9K_RX_FILTER_PHYERR); + + /* TODO: usually this should not be neccesary, but for some reason + * (or in some mode?) the trigger must be called after the + * configuration, otherwise the register will have its values reset + * (on my ar9220 to value 0x01002310) + */ + ath9k_spectral_scan_config(common, spec_priv, spec_priv->spectral_mode); + ath9k_hw_ops(ah)->spectral_scan_trigger(ah); + ath_ps_ops(common)->restore(common); +} + +int ath9k_spectral_scan_config(struct ath_common *common, + struct ath_spec_scan_priv *spec_priv, + enum spectral_mode spectral_mode) +{ + struct ath_hw *ah = spec_priv->ah; + + if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { + ath_err(common, "spectrum analyzer not implemented on this hardware\n"); + return -1; + } + + switch (spectral_mode) { + case SPECTRAL_DISABLED: + spec_priv->spec_config.enabled = 0; + break; + case SPECTRAL_BACKGROUND: + /* send endless samples. + * TODO: is this really useful for "background"? + */ + spec_priv->spec_config.endless = 1; + spec_priv->spec_config.enabled = 1; + break; + case SPECTRAL_CHANSCAN: + case SPECTRAL_MANUAL: + spec_priv->spec_config.endless = 0; + spec_priv->spec_config.enabled = 1; + break; + default: + return -1; + } + + ath_ps_ops(common)->wakeup(common); + ath9k_hw_ops(ah)->spectral_scan_config(ah, &spec_priv->spec_config); + ath_ps_ops(common)->restore(common); + + spec_priv->spectral_mode = spectral_mode; + + return 0; +} + static ssize_t write_file_spec_scan_ctl(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) -- GitLab From 67dc74f15f147b9f88702de2952d2951e3e000ec Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:30 +0100 Subject: [PATCH 4320/9457] ath9k: move spectral.* to common-spectral.* and rename exports from ath9k_spectral_* to ath9k_cmn_spectral_* Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 6 ++-- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/channel.c | 2 +- .../ath9k/{spectral.c => common-spectral.c} | 28 +++++++++++-------- .../ath9k/{spectral.h => common-spectral.h} | 12 ++++---- drivers/net/wireless/ath/ath9k/common.h | 1 + drivers/net/wireless/ath/ath9k/debug.c | 4 +-- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 8 files changed, 31 insertions(+), 25 deletions(-) rename drivers/net/wireless/ath/ath9k/{spectral.c => common-spectral.c} (94%) rename drivers/net/wireless/ath/ath9k/{spectral.h => common-spectral.h} (90%) diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 22b934b07bd4..473972288a84 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -16,8 +16,7 @@ ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o ath9k-$(CONFIG_ATH9K_TX99) += tx99.o ath9k-$(CONFIG_ATH9K_WOW) += wow.o -ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \ - spectral.o +ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o ath9k-$(CONFIG_ATH9K_STATION_STATISTICS) += debug_sta.o @@ -59,7 +58,8 @@ obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o ath9k_common-y:= common.o \ common-init.o \ common-beacon.o \ - common-debug.o + common-debug.o \ + common-spectral.o ath9k_htc-y += htc_hst.o \ hif_usb.o \ diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index dee1f2a58538..d5a2019921bd 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -28,7 +28,6 @@ #include "debug.h" #include "mci.h" #include "dfs.h" -#include "spectral.h" struct ath_node; struct ath_vif; diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 32ce931c2404..1dadf6d77a82 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -93,7 +93,7 @@ static int ath_set_channel(struct ath_softc *sc) /* perform spectral scan if requested. */ if (test_bit(ATH_OP_SCANNING, &common->op_flags) && sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN) - ath9k_spectral_scan_trigger(common, &sc->spec_priv); + ath9k_cmn_spectral_scan_trigger(common, &sc->spec_priv); } return 0; diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c similarity index 94% rename from drivers/net/wireless/ath/ath9k/spectral.c rename to drivers/net/wireless/ath/ath9k/common-spectral.c index bf85740ab84b..ec93ddf0863a 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/common-spectral.c @@ -37,7 +37,7 @@ static void ath_debug_send_fft_sample(struct ath_spec_scan_priv *spec_priv, } /* returns 1 if this was a spectral frame, even if not handled. */ -int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, +int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf) { struct ath_hw *ah = spec_priv->ah; @@ -204,6 +204,7 @@ int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr * return 1; } +EXPORT_SYMBOL(ath_cmn_process_fft); /*********************/ /* spectral_scan_ctl */ @@ -234,7 +235,7 @@ static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, mode, len); } -void ath9k_spectral_scan_trigger(struct ath_common *common, +void ath9k_cmn_spectral_scan_trigger(struct ath_common *common, struct ath_spec_scan_priv *spec_priv) { struct ath_hw *ah = spec_priv->ah; @@ -259,12 +260,13 @@ void ath9k_spectral_scan_trigger(struct ath_common *common, * configuration, otherwise the register will have its values reset * (on my ar9220 to value 0x01002310) */ - ath9k_spectral_scan_config(common, spec_priv, spec_priv->spectral_mode); + ath9k_cmn_spectral_scan_config(common, spec_priv, spec_priv->spectral_mode); ath9k_hw_ops(ah)->spectral_scan_trigger(ah); ath_ps_ops(common)->restore(common); } +EXPORT_SYMBOL(ath9k_cmn_spectral_scan_trigger); -int ath9k_spectral_scan_config(struct ath_common *common, +int ath9k_cmn_spectral_scan_config(struct ath_common *common, struct ath_spec_scan_priv *spec_priv, enum spectral_mode spectral_mode) { @@ -303,6 +305,7 @@ int ath9k_spectral_scan_config(struct ath_common *common, return 0; } +EXPORT_SYMBOL(ath9k_cmn_spectral_scan_config); static ssize_t write_file_spec_scan_ctl(struct file *file, const char __user *user_buf, @@ -323,18 +326,18 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, buf[len] = '\0'; if (strncmp("trigger", buf, 7) == 0) { - ath9k_spectral_scan_trigger(common, spec_priv); + ath9k_cmn_spectral_scan_trigger(common, spec_priv); } else if (strncmp("background", buf, 10) == 0) { - ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_BACKGROUND); + ath9k_cmn_spectral_scan_config(common, spec_priv, SPECTRAL_BACKGROUND); ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n"); } else if (strncmp("chanscan", buf, 8) == 0) { - ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_CHANSCAN); + ath9k_cmn_spectral_scan_config(common, spec_priv, SPECTRAL_CHANSCAN); ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n"); } else if (strncmp("manual", buf, 6) == 0) { - ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_MANUAL); + ath9k_cmn_spectral_scan_config(common, spec_priv, SPECTRAL_MANUAL); ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n"); } else if (strncmp("disable", buf, 7) == 0) { - ath9k_spectral_scan_config(common, spec_priv, SPECTRAL_DISABLED); + ath9k_cmn_spectral_scan_config(common, spec_priv, SPECTRAL_DISABLED); ath_dbg(common, CONFIG, "spectral scan: disabled\n"); } else { return -EINVAL; @@ -577,15 +580,17 @@ static struct rchan_callbacks rfs_spec_scan_cb = { /* Debug Init/Deinit */ /*********************/ -void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) +void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) { if (config_enabled(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) { relay_close(spec_priv->rfs_chan_spec_scan); spec_priv->rfs_chan_spec_scan = NULL; } } +EXPORT_SYMBOL(ath9k_cmn_spectral_deinit_debug); -void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy) +void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, + struct dentry *debugfs_phy) { spec_priv->rfs_chan_spec_scan = relay_open("spectral_scan", debugfs_phy, @@ -612,3 +617,4 @@ void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dent debugfs_phy, spec_priv, &fops_spectral_fft_period); } +EXPORT_SYMBOL(ath9k_cmn_spectral_init_debug); diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h similarity index 90% rename from drivers/net/wireless/ath/ath9k/spectral.h rename to drivers/net/wireless/ath/ath9k/common-spectral.h index 77582cf743ac..214c3baf5023 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/common-spectral.h @@ -130,20 +130,20 @@ static inline u8 spectral_bitmap_weight(u8 *bins) return bins[0] & 0x3f; } -void ath9k_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); -void ath9k_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); +void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); +void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); -void ath9k_spectral_scan_trigger(struct ath_common *common, +void ath9k_cmn_spectral_scan_trigger(struct ath_common *common, struct ath_spec_scan_priv *spec_priv); -int ath9k_spectral_scan_config(struct ath_common *common, +int ath9k_cmn_spectral_scan_config(struct ath_common *common, struct ath_spec_scan_priv *spec_priv, enum spectral_mode spectral_mode); #ifdef CONFIG_ATH9K_DEBUGFS -int ath_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, +int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf); #else -static inline int ath_process_fft(struct ath_spec_scan_priv *spec_priv, +static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf) { diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index ffc454b18637..2b79a568e803 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -24,6 +24,7 @@ #include "common-init.h" #include "common-beacon.h" #include "common-debug.h" +#include "common-spectral.h" /* Common header for Atheros 802.11n base driver cores */ diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 6492619851a0..db388405bf0c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1310,7 +1310,7 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw, void ath9k_deinit_debug(struct ath_softc *sc) { - ath9k_spectral_deinit_debug(&sc->spec_priv); + ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); } int ath9k_init_debug(struct ath_hw *ah) @@ -1330,7 +1330,7 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_dfs_init_debug(sc); ath9k_tx99_init_debug(sc); - ath9k_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); + ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_dma); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e97c6936da0f..7395afbc5124 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -870,7 +870,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, */ if (rx_stats->rs_status & ATH9K_RXERR_PHY) { ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime); - if (ath_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime)) + if (ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime)) RX_STAT_INC(rx_spectral); return -EINVAL; -- GitLab From 46140ddf169703ef0538bf00098233b24b2269e8 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:31 +0100 Subject: [PATCH 4321/9457] ath9k: For AR9271 chipsets, set count = 0 for endless samples. not sure why. Initially provided by Ashish Patro Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 9a2afa2c690b..fc08162b5820 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -643,9 +643,12 @@ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, * and fix otherwise. */ count = param->count; - if (param->endless) - count = 0x80; - else if (count & 0x80) + if (param->endless) { + if (AR_SREV_9271(ah)) + count = 0; + else + count = 0x80; + } else if (count & 0x80) count = 0x7f; REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -- GitLab From 525d09456b9fc2f769647c744c75629d9926fb9e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:32 +0100 Subject: [PATCH 4322/9457] ath9k_htc: fix rs_datalen conversation For some reason it didn't coused obvious problems. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index f0484b1b617e..2622002845ce 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -946,7 +946,7 @@ static inline void convert_htc_flag(struct ath_rx_status *rx_stats, static void rx_status_htc_to_ath(struct ath_rx_status *rx_stats, struct ath_htc_rx_status *rxstatus) { - rx_stats->rs_datalen = rxstatus->rs_datalen; + rx_stats->rs_datalen = be16_to_cpu(rxstatus->rs_datalen); rx_stats->rs_status = rxstatus->rs_status; rx_stats->rs_phyerr = rxstatus->rs_phyerr; rx_stats->rs_rssi = rxstatus->rs_rssi; -- GitLab From 94cd95c217a5ed4c45e2a8c97043c3efcd66dac9 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:33 +0100 Subject: [PATCH 4323/9457] ath9k_htc: add ath_ps_ops bindings Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 4014c4be6e79..f91b8e6b14bc 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -53,6 +53,21 @@ static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { }; #endif +void ath9k_htc_op_ps_wakeup(struct ath_common *common) +{ + ath9k_htc_ps_wakeup((struct ath9k_htc_priv *) common->priv); +} + +void ath9k_htc_op_ps_restore(struct ath_common *common) +{ + ath9k_htc_ps_restore((struct ath9k_htc_priv *) common->priv); +} + +struct ath_ps_ops ath9k_htc_ps_ops = { + .wakeup = ath9k_htc_op_ps_wakeup, + .restore = ath9k_htc_op_ps_restore, +}; + static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) { int time_left; @@ -478,6 +493,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common = ath9k_hw_common(ah); common->ops = &ah->reg_ops; + common->ps_ops = &ath9k_htc_ps_ops; common->bus_ops = &ath9k_usb_bus_ops; common->ah = ah; common->hw = priv->hw; -- GitLab From fe30e8bb5be52e2e6b913db77dda6c22b643dbd7 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:34 +0100 Subject: [PATCH 4324/9457] ath9k_htc: add struct ath_spec_scan_priv to ath9k_htc_priv Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 09a5d72f3ff5..1f019aa2d1f8 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -481,6 +481,7 @@ struct ath9k_htc_priv { unsigned long op_flags; struct ath9k_hw_cal_data caldata; + struct ath_spec_scan_priv spec_priv; spinlock_t beacon_lock; struct ath_beacon_config cur_beacon_conf; -- GitLab From 88a2e3fb7b7e9dd3c51ceef81e0415478c27910c Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:35 +0100 Subject: [PATCH 4325/9457] ath9k_htc: set initial spec_config values use values provided by Ashish Patro Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f91b8e6b14bc..285d0ada369f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -464,6 +464,14 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) common->last_rssi = ATH_RSSI_DUMMY_MARKER; priv->ah->opmode = NL80211_IFTYPE_STATION; + + priv->spec_priv.ah = priv->ah; + priv->spec_priv.spec_config.enabled = 0; + priv->spec_priv.spec_config.short_repeat = false; + priv->spec_priv.spec_config.count = 8; + priv->spec_priv.spec_config.endless = false; + priv->spec_priv.spec_config.period = 0x12; + priv->spec_priv.spec_config.fft_period = 0x02; } static int ath9k_init_priv(struct ath9k_htc_priv *priv, -- GitLab From 911544f6a8d66c27ff807f5d71e3f0f5a904c100 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:36 +0100 Subject: [PATCH 4326/9457] ath9k_htc: trigger spectral scan on set_channel Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 994fff1ff519..689ac998b87e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -314,6 +314,10 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, mod_timer(&priv->tx.cleanup_timer, jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + /* perform spectral scan if requested. */ + if (test_bit(ATH_OP_SCANNING, &common->op_flags) && + priv->spec_priv.spectral_mode == SPECTRAL_CHANSCAN) + ath9k_cmn_spectral_scan_trigger(common, &priv->spec_priv); err: ath9k_htc_ps_restore(priv); return ret; -- GitLab From 83fb287ecd8ae60ed79c647a5df8beacdf4f4807 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:37 +0100 Subject: [PATCH 4327/9457] ath9k_htc: process rx spectral packets use code provided by Ashish Patro Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2622002845ce..a0f58e2aa553 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1012,6 +1012,20 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, * separately to avoid doing two lookups for a rate for each frame. */ hdr = (struct ieee80211_hdr *)skb->data; + + /* + * Process PHY errors and return so that the packet + * can be dropped. + */ + if (rx_stats.rs_status & ATH9K_RXERR_PHY) { + /* TODO: Not using DFS processing now. */ + if (ath_cmn_process_fft(&priv->spec_priv, hdr, + &rx_stats, rx_status->mactime)) { + /* TODO: Code to collect spectral scan statistics */ + } + goto rx_next; + } + if (!ath9k_cmn_rx_accept(common, hdr, rx_status, &rx_stats, &decrypt_error, priv->rxfilter)) goto rx_next; -- GitLab From 3f2aa13f6d16a53a4cf5de369c685c6f75fe4d58 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 6 Nov 2014 08:53:38 +0100 Subject: [PATCH 4328/9457] ath9k_htc: add spectral scan debug interface Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 ++ drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 6 ++++++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1f019aa2d1f8..b34acdeb1f21 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -626,8 +626,10 @@ int ath9k_htc_resume(struct htc_target *htc_handle); #endif #ifdef CONFIG_ATH9K_HTC_DEBUGFS int ath9k_htc_init_debug(struct ath_hw *ah); +void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv); #else static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; +static inline void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv) { return 0; }; #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #endif /* HTC_H */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 8b529e4b8ac4..8cef1edcc621 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -490,6 +490,10 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, WARN_ON(i != ATH9K_HTC_SSTATS_LEN); } +void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv) +{ + ath9k_cmn_spectral_deinit_debug(&priv->spec_priv); +} int ath9k_htc_init_debug(struct ath_hw *ah) { @@ -501,6 +505,8 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_phy) return -ENOMEM; + ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); + debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, priv, &fops_tgt_int_stats); debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 285d0ada369f..ad8f1dcc9cd5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -102,6 +102,7 @@ static void ath9k_deinit_device(struct ath9k_htc_priv *priv) wiphy_rfkill_stop_polling(hw->wiphy); ath9k_deinit_leds(priv); + ath9k_htc_deinit_debug(priv); ieee80211_unregister_hw(hw); ath9k_rx_cleanup(priv); ath9k_tx_cleanup(priv); -- GitLab From 0d4b5c7c0892cb377cc71c388433425f598b902b Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 7 Nov 2014 02:14:52 -0800 Subject: [PATCH 4329/9457] mwifiex: fix version display problem on big endian platforms It's been observed that wrong firmware version (ex. 66.14.96.p9 instead of 14.66.9.p96) is displayed on big endian platforms. The problem is fixed here. Reported-by: Daniel Mosquera Tested-by: Daniel Mosquera Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 92f3eb839866..1626868a4b5c 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -1026,12 +1026,12 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, int max_len) { union { - u32 l; + __le32 l; u8 c[4]; } ver; char fw_ver[32]; - ver.l = adapter->fw_release_number; + ver.l = cpu_to_le32(adapter->fw_release_number); sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]); snprintf(version, max_len, driver_version, fw_ver); -- GitLab From f5b8f4790bb5dfd541f9d61589357ea6042cc668 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 09:25:17 +0200 Subject: [PATCH 4330/9457] wlcore: check minimum buffer size in some cmd_send functions Check for the minimum required buffer length in wlcore_cmd_send() and wlcore_cmd_configure_failsafe. This ensures that we will never try to use a buffer that is smaller than the required header. Reported-by: Dan Carpenter Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wlcore/cmd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 05604ee31224..5c6f3c84ad6f 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -64,6 +64,9 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf, id != CMD_STOP_FWLOGGER)) return -EIO; + if (WARN_ON_ONCE(len < sizeof(*cmd))) + return -EIO; + cmd = buf; cmd->id = cpu_to_le16(id); cmd->status = 0; @@ -891,6 +894,9 @@ int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf, wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id); + if (WARN_ON_ONCE(len < sizeof(*acx))) + return -EIO; + acx->id = cpu_to_le16(id); /* payload length, does not include any headers */ -- GitLab From d351f5fea44a7527819598070e11b5c9dc53c017 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 09:25:57 +0200 Subject: [PATCH 4331/9457] wlcore: make wlcore_cmd_send_failsafe() static The wlcore_cmd_send_failsafe() function is only called in the cmd.c file, where it is definde. Make it static. Additionally, move the EXPORT_SYMBOL macro for wl1271_cmd_send() to the right place. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wlcore/cmd.c | 7 ++++--- drivers/net/wireless/ti/wlcore/cmd.h | 2 -- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5c6f3c84ad6f..dd2e448c3e2b 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -131,8 +131,9 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf, * send command to fw and return cmd status on success * valid_rets contains a bitmap of allowed error codes */ -int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len, - size_t res_len, unsigned long valid_rets) +static int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, + size_t len, size_t res_len, + unsigned long valid_rets) { int ret = __wlcore_cmd_send(wl, id, buf, len, res_len); @@ -153,7 +154,6 @@ int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len, wl12xx_queue_recovery_work(wl); return ret; } -EXPORT_SYMBOL_GPL(wl1271_cmd_send); /* * wrapper for wlcore_cmd_send that accept only CMD_STATUS_SUCCESS @@ -168,6 +168,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, return ret; return 0; } +EXPORT_SYMBOL_GPL(wl1271_cmd_send); /* * Poll the mailbox event field until any of the bits in the mask is set or a diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index ca6a28b03f8f..453684a71d30 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h @@ -31,8 +31,6 @@ struct acx_header; int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, size_t res_len); -int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len, - size_t res_len, unsigned long valid_rets); int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, u8 *role_id); int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); -- GitLab From 4eed83a252257ad8ad41ba1c769341960ed4cdc5 Mon Sep 17 00:00:00 2001 From: James Cameron Date: Tue, 11 Nov 2014 16:21:28 +1100 Subject: [PATCH 4332/9457] mwifiex: simplify ad hoc join capability info While preparing an ad-hoc start command, the capability info bitmap is needlessly set from the command, and then the ESS bit cleared. Change to set the bitmap directly without reference to the command. Signed-off-by: James Cameron Acked-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/join.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 8d6c25908b6d..411a6c2f4aca 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -880,9 +880,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, /* Set Capability info */ bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS; - tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap); - tmp_cap &= ~WLAN_CAPABILITY_ESS; - tmp_cap |= WLAN_CAPABILITY_IBSS; + tmp_cap = WLAN_CAPABILITY_IBSS; /* Set up privacy in bss_desc */ if (priv->sec_info.encryption_mode) { -- GitLab From 619c144c84bd240487204e91dff88247cde68d92 Mon Sep 17 00:00:00 2001 From: Vince Hsu Date: Mon, 10 Nov 2014 14:14:50 +0800 Subject: [PATCH 4333/9457] cpufreq: respect the min/max settings from user space When the user space tries to set scaling_(max|min)_freq through sysfs, the cpufreq_set_policy() asks other driver's opinions for the max/min frequencies. Some device drivers, like Tegra CPU EDP which is not upstreamed yet though, may constrain the CPU maximum frequency dynamically because of board design. So if the user space access happens and some driver is capping the cpu frequency at the same time, the user_policy->(max|min) is overridden by the capped value, and that's not expected by the user space. And if the user space is not invoked again, the CPU will always be capped by the user_policy->(max|min) even no drivers limit the CPU frequency any more. This patch preserves the user specified min/max settings, so that every time the cpufreq policy is updated, the new max/min can be re-evaluated correctly based on the user's expection and the present device drivers' status. Signed-off-by: Vince Hsu Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 644b54e1e7d1..0721ab352e2a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -535,7 +535,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, static ssize_t store_##file_name \ (struct cpufreq_policy *policy, const char *buf, size_t count) \ { \ - int ret; \ + int ret, temp; \ struct cpufreq_policy new_policy; \ \ ret = cpufreq_get_policy(&new_policy, policy->cpu); \ @@ -546,8 +546,10 @@ static ssize_t store_##file_name \ if (ret != 1) \ return -EINVAL; \ \ + temp = new_policy.object; \ ret = cpufreq_set_policy(policy, &new_policy); \ - policy->user_policy.object = policy->object; \ + if (!ret) \ + policy->user_policy.object = temp; \ \ return ret ? ret : count; \ } -- GitLab From a15c706889753a92ccf90a55516a4f0c87a02201 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 11 Nov 2014 17:12:17 -0500 Subject: [PATCH 4334/9457] ath9k_htc: remove return of value in empty definintion of ath9k_htc_deinit_debug Cc: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b34acdeb1f21..9dde265d3f84 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -629,7 +629,9 @@ int ath9k_htc_init_debug(struct ath_hw *ah); void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv); #else static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; -static inline void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv) { return 0; }; +static inline void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv) +{ +} #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #endif /* HTC_H */ -- GitLab From 764d2c80401fcc7ee15933d604c6a783d5addc40 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 11 Nov 2014 11:01:01 -0800 Subject: [PATCH 4335/9457] f2fs: fix deadlock to grab 0'th data page The scenario is like this. One trhead triggers: f2fs_write_data_pages lock_page f2fs_write_data_page f2fs_lock_op <- wait The other thread triggers: f2fs_truncate truncate_blocks f2fs_lock_op truncate_partial_data_page lock_page <- wait for locking the page This patch resolves this bug by relocating truncate_partial_data_page. This function is just to truncate user data page and not related to FS consistency as well. And, we don't need to call truncate_inline_data. Rather than that, f2fs_write_data_page will finally update inline_data later. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 54722a0a5be5..edc3ce867e9c 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -477,8 +477,6 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) } if (f2fs_has_inline_data(inode)) { - truncate_inline_data(ipage, from); - update_inode(inode, ipage); f2fs_put_page(ipage, 1); goto out; } @@ -504,13 +502,13 @@ int truncate_blocks(struct inode *inode, u64 from, bool lock) f2fs_put_dnode(&dn); free_next: err = truncate_inode_blocks(inode, free_from); +out: + if (lock) + f2fs_unlock_op(sbi); /* lastly zero out the first data page */ if (!err) err = truncate_partial_data_page(inode, from); -out: - if (lock) - f2fs_unlock_op(sbi); trace_f2fs_truncate_blocks_exit(inode, err); return err; -- GitLab From 92dffd01790a5219d234fc83c3ba854f4490b7f4 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 11 Nov 2014 14:10:01 -0800 Subject: [PATCH 4336/9457] f2fs: convert inline_data when i_size becomes large If i_size becomes large outside of MAX_INLINE_DATA, we shoud convert the inode. Otherwise, we can make some dirty pages during the truncation, and those pages will be written through f2fs_write_data_page. At that moment, the inode has still inline_data, so that it tries to write non- zero pages into inline_data area. Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 6 ++++++ fs/f2fs/inline.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index edc3ce867e9c..7c2ec3ebebe0 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -522,6 +522,12 @@ void f2fs_truncate(struct inode *inode) trace_f2fs_truncate(inode); + /* we should check inline_data size */ + if (f2fs_has_inline_data(inode) && !f2fs_may_inline(inode)) { + if (f2fs_convert_inline_inode(inode)) + return; + } + if (!truncate_blocks(inode, i_size_read(inode), true)) { inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 231067027745..053d114f0528 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -24,6 +24,9 @@ bool f2fs_may_inline(struct inode *inode) if (!S_ISREG(inode->i_mode)) return false; + if (i_size_read(inode) > MAX_INLINE_DATA) + return false; + return true; } -- GitLab From 087e9cbab5022f8bb6dc9574ff5e320569903b80 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 7 Nov 2014 09:29:25 -0800 Subject: [PATCH 4337/9457] powercap / RAPL: abstract per cpu type functions RAPL implementations may vary slightly between Core and Atom CPUs. There are also potential differences among generations of CPUs within the family. This patch adds a per model structure to abstract the differences such that variations can be handled cleanly. Signed-off-by: Jacob Pan Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 45 +++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 45e05b32f9b6..256efed5b88f 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -188,6 +188,15 @@ struct rapl_package { */ struct list_head plist; }; + +struct rapl_defaults { + int (*check_unit)(struct rapl_package *rp, int cpu); + void (*set_floor_freq)(struct rapl_domain *rd, bool mode); + u64 (*compute_time_window)(struct rapl_package *rp, u64 val, + bool to_raw); +}; +static struct rapl_defaults *rapl_defaults; + #define PACKAGE_PLN_INT_SAVED BIT(0) #define MAX_PRIM_NAME (32) @@ -946,16 +955,28 @@ static void package_power_limit_irq_restore(int package_id) wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h); } +static const struct rapl_defaults rapl_defaults_core = { +}; + +static const struct rapl_defaults rapl_defaults_atom = { +}; + +#define RAPL_CPU(_model, _ops) { \ + .vendor = X86_VENDOR_INTEL, \ + .family = 6, \ + .model = _model, \ + .driver_data = (kernel_ulong_t)&_ops, \ + } + static const struct x86_cpu_id rapl_ids[] = { - { X86_VENDOR_INTEL, 6, 0x2a},/* Sandy Bridge */ - { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ - { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ - { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ - { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ - { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ - { X86_VENDOR_INTEL, 6, 0x3f},/* Haswell */ - { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ - /* TODO: Add more CPU IDs after testing */ + RAPL_CPU(0x2a, rapl_defaults_core),/* Sandy Bridge */ + RAPL_CPU(0x2d, rapl_defaults_core),/* Sandy Bridge EP */ + RAPL_CPU(0x37, rapl_defaults_atom),/* Valleyview */ + RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ + RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ + RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ + RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ + RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ {} }; MODULE_DEVICE_TABLE(x86cpu, rapl_ids); @@ -1358,14 +1379,18 @@ static struct notifier_block rapl_cpu_notifier = { static int __init rapl_init(void) { int ret = 0; + const struct x86_cpu_id *id; - if (!x86_match_cpu(rapl_ids)) { + id = x86_match_cpu(rapl_ids); + if (!id) { pr_err("driver does not support CPU family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model); return -ENODEV; } + rapl_defaults = (struct rapl_defaults *)id->driver_data; + cpu_notifier_register_begin(); /* prevent CPU hotplug during detection */ -- GitLab From 3c2c08454ce9cabf55ff927ecc240573c177a659 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 7 Nov 2014 09:29:26 -0800 Subject: [PATCH 4338/9457] powercap / RAPL: handle atom and core differences RAPL implementation on Atom has made some changes that are not compatible with Core CPUs. Specifically, it is different in the way units are computed as well as floor frequency is enforced. This patch uses the per CPU model functions to handle the differences. Intel Software Developers' Manual has also been updated to reflect the changes in Table 35-7 V3C. Signed-off-by: Ajay Thomas Signed-off-by: Jacob Pan Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 216 ++++++++++++++++++++++------------ 1 file changed, 139 insertions(+), 77 deletions(-) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 256efed5b88f..4631696a7ccf 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -70,11 +71,6 @@ #define RAPL_PRIMITIVE_DERIVED BIT(1) /* not from raw data */ #define RAPL_PRIMITIVE_DUMMY BIT(2) -/* scale RAPL units to avoid floating point math inside kernel */ -#define POWER_UNIT_SCALE (1000000) -#define ENERGY_UNIT_SCALE (1000000) -#define TIME_UNIT_SCALE (1000000) - #define TIME_WINDOW_MAX_MSEC 40000 #define TIME_WINDOW_MIN_MSEC 250 @@ -175,9 +171,9 @@ struct rapl_package { unsigned int id; /* physical package/socket id */ unsigned int nr_domains; unsigned long domain_map; /* bit map of active domains */ - unsigned int power_unit_divisor; - unsigned int energy_unit_divisor; - unsigned int time_unit_divisor; + unsigned int power_unit; + unsigned int energy_unit; + unsigned int time_unit; struct rapl_domain *domains; /* array of domains, sized at runtime */ struct powercap_zone *power_zone; /* keep track of parent zone */ int nr_cpus; /* active cpus on the package, topology info is lost during @@ -197,6 +193,9 @@ struct rapl_defaults { }; static struct rapl_defaults *rapl_defaults; +/* Sideband MBI registers */ +#define IOSF_CPU_POWER_BUDGET_CTL (0x2) + #define PACKAGE_PLN_INT_SAVED BIT(0) #define MAX_PRIM_NAME (32) @@ -348,23 +347,13 @@ static int find_nr_power_limit(struct rapl_domain *rd) static int set_domain_enable(struct powercap_zone *power_zone, bool mode) { struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone); - int nr_powerlimit; if (rd->state & DOMAIN_STATE_BIOS_LOCKED) return -EACCES; + get_online_cpus(); - nr_powerlimit = find_nr_power_limit(rd); - /* here we activate/deactivate the hardware for power limiting */ rapl_write_data_raw(rd, PL1_ENABLE, mode); - /* always enable clamp such that p-state can go below OS requested - * range. power capping priority over guranteed frequency. - */ - rapl_write_data_raw(rd, PL1_CLAMP, mode); - /* some domains have pl2 */ - if (nr_powerlimit > 1) { - rapl_write_data_raw(rd, PL2_ENABLE, mode); - rapl_write_data_raw(rd, PL2_CLAMP, mode); - } + rapl_defaults->set_floor_freq(rd, mode); put_online_cpus(); return 0; @@ -662,9 +651,7 @@ static void rapl_init_domains(struct rapl_package *rp) static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, int to_raw) { - u64 divisor = 1; - int scale = 1; /* scale to user friendly data without floating point */ - u64 f, y; /* fraction and exp. used for time unit */ + u64 units = 1; struct rapl_package *rp; rp = find_package_by_id(package); @@ -673,42 +660,24 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, switch (type) { case POWER_UNIT: - divisor = rp->power_unit_divisor; - scale = POWER_UNIT_SCALE; + units = rp->power_unit; break; case ENERGY_UNIT: - scale = ENERGY_UNIT_SCALE; - divisor = rp->energy_unit_divisor; + units = rp->energy_unit; break; case TIME_UNIT: - divisor = rp->time_unit_divisor; - scale = TIME_UNIT_SCALE; - /* special processing based on 2^Y*(1+F)/4 = val/divisor, refer - * to Intel Software Developer's manual Vol. 3a, CH 14.7.4. - */ - if (!to_raw) { - f = (value & 0x60) >> 5; - y = value & 0x1f; - value = (1 << y) * (4 + f) * scale / 4; - return div64_u64(value, divisor); - } else { - do_div(value, scale); - value *= divisor; - y = ilog2(value); - f = div64_u64(4 * (value - (1 << y)), 1 << y); - value = (y & 0x1f) | ((f & 0x3) << 5); - return value; - } - break; + return rapl_defaults->compute_time_window(rp, value, to_raw); case ARBITRARY_UNIT: default: return value; }; if (to_raw) - return div64_u64(value * divisor, scale); - else - return div64_u64(value * scale, divisor); + return div64_u64(value, units); + + value *= units; + + return value; } /* in the order of enum rapl_primitives */ @@ -842,12 +811,18 @@ static int rapl_write_data_raw(struct rapl_domain *rd, return 0; } -static const struct x86_cpu_id energy_unit_quirk_ids[] = { - { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ - {} -}; - -static int rapl_check_unit(struct rapl_package *rp, int cpu) +/* + * Raw RAPL data stored in MSRs are in certain scales. We need to + * convert them into standard units based on the units reported in + * the RAPL unit MSRs. This is specific to CPUs as the method to + * calculate units differ on different CPUs. + * We convert the units to below format based on CPUs. + * i.e. + * energy unit: microJoules : Represented in microJoules by default + * power unit : microWatts : Represented in milliWatts by default + * time unit : microseconds: Represented in seconds by default + */ +static int rapl_check_unit_core(struct rapl_package *rp, int cpu) { u64 msr_val; u32 value; @@ -858,36 +833,47 @@ static int rapl_check_unit(struct rapl_package *rp, int cpu) return -ENODEV; } - /* Raw RAPL data stored in MSRs are in certain scales. We need to - * convert them into standard units based on the divisors reported in - * the RAPL unit MSRs. - * i.e. - * energy unit: 1/enery_unit_divisor Joules - * power unit: 1/power_unit_divisor Watts - * time unit: 1/time_unit_divisor Seconds - */ value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; - /* some CPUs have different way to calculate energy unit */ - if (x86_match_cpu(energy_unit_quirk_ids)) - rp->energy_unit_divisor = 1000000 / (1 << value); - else - rp->energy_unit_divisor = 1 << value; + rp->energy_unit = 1000000 / (1 << value); value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; - rp->power_unit_divisor = 1 << value; + rp->power_unit = 1000000 / (1 << value); value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; - rp->time_unit_divisor = 1 << value; + rp->time_unit = 1000000 / (1 << value); - pr_debug("Physical package %d units: energy=%d, time=%d, power=%d\n", - rp->id, - rp->energy_unit_divisor, - rp->time_unit_divisor, - rp->power_unit_divisor); + pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n", + rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); return 0; } +static int rapl_check_unit_atom(struct rapl_package *rp, int cpu) +{ + u64 msr_val; + u32 value; + + if (rdmsrl_safe_on_cpu(cpu, MSR_RAPL_POWER_UNIT, &msr_val)) { + pr_err("Failed to read power unit MSR 0x%x on CPU %d, exit.\n", + MSR_RAPL_POWER_UNIT, cpu); + return -ENODEV; + } + value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; + rp->energy_unit = 1 << value; + + value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; + rp->power_unit = (1 << value) * 1000; + + value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; + rp->time_unit = 1000000 / (1 << value); + + pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n", + rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); + + return 0; +} + + /* REVISIT: * When package power limit is set artificially low by RAPL, LVT * thermal interrupt for package power limit should be ignored @@ -955,10 +941,86 @@ static void package_power_limit_irq_restore(int package_id) wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h); } +static void set_floor_freq_default(struct rapl_domain *rd, bool mode) +{ + int nr_powerlimit = find_nr_power_limit(rd); + + /* always enable clamp such that p-state can go below OS requested + * range. power capping priority over guranteed frequency. + */ + rapl_write_data_raw(rd, PL1_CLAMP, mode); + + /* some domains have pl2 */ + if (nr_powerlimit > 1) { + rapl_write_data_raw(rd, PL2_ENABLE, mode); + rapl_write_data_raw(rd, PL2_CLAMP, mode); + } +} + +static void set_floor_freq_atom(struct rapl_domain *rd, bool enable) +{ + static u32 power_ctrl_orig_val; + u32 mdata; + + if (!power_ctrl_orig_val) + iosf_mbi_read(BT_MBI_UNIT_PMC, BT_MBI_PMC_READ, + IOSF_CPU_POWER_BUDGET_CTL, &power_ctrl_orig_val); + mdata = power_ctrl_orig_val; + if (enable) { + mdata &= ~(0x7f << 8); + mdata |= 1 << 8; + } + iosf_mbi_write(BT_MBI_UNIT_PMC, BT_MBI_PMC_WRITE, + IOSF_CPU_POWER_BUDGET_CTL, mdata); +} + +static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, + bool to_raw) +{ + u64 f, y; /* fraction and exp. used for time unit */ + + /* + * Special processing based on 2^Y*(1+F/4), refer + * to Intel Software Developer's manual Vol.3B: CH 14.9.3. + */ + if (!to_raw) { + f = (value & 0x60) >> 5; + y = value & 0x1f; + value = (1 << y) * (4 + f) * rp->time_unit / 4; + } else { + do_div(value, rp->time_unit); + y = ilog2(value); + f = div64_u64(4 * (value - (1 << y)), 1 << y); + value = (y & 0x1f) | ((f & 0x3) << 5); + } + return value; +} + +static u64 rapl_compute_time_window_atom(struct rapl_package *rp, u64 value, + bool to_raw) +{ + /* + * Atom time unit encoding is straight forward val * time_unit, + * where time_unit is default to 1 sec. Never 0. + */ + if (!to_raw) + return (value) ? value *= rp->time_unit : rp->time_unit; + else + value = div64_u64(value, rp->time_unit); + + return value; +} + static const struct rapl_defaults rapl_defaults_core = { + .check_unit = rapl_check_unit_core, + .set_floor_freq = set_floor_freq_default, + .compute_time_window = rapl_compute_time_window_core, }; static const struct rapl_defaults rapl_defaults_atom = { + .check_unit = rapl_check_unit_atom, + .set_floor_freq = set_floor_freq_atom, + .compute_time_window = rapl_compute_time_window_atom, }; #define RAPL_CPU(_model, _ops) { \ @@ -1262,7 +1324,7 @@ static int rapl_detect_topology(void) /* check if the package contains valid domains */ if (rapl_detect_domains(new_package, i) || - rapl_check_unit(new_package, i)) { + rapl_defaults->check_unit(new_package, i)) { kfree(new_package->domains); kfree(new_package); /* free up the packages already initialized */ @@ -1317,7 +1379,7 @@ static int rapl_add_package(int cpu) rp->nr_cpus = 1; /* check if the package contains valid domains */ if (rapl_detect_domains(rp, cpu) || - rapl_check_unit(rp, cpu)) { + rapl_defaults->check_unit(rp, cpu)) { ret = -ENODEV; goto err_free_package; } -- GitLab From 74af752e489537391294b51d73fafbcd53672ea4 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Fri, 7 Nov 2014 09:29:27 -0800 Subject: [PATCH 4339/9457] powercap / RAPL: add new model ids Signed-off-by: Jacob Pan Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 4631696a7ccf..c71443c4f265 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -1039,6 +1039,9 @@ static const struct x86_cpu_id rapl_ids[] = { RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ + RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ + RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ + RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */ {} }; MODULE_DEVICE_TABLE(x86cpu, rapl_ids); -- GitLab From cb39dcdd4ef6a31028ecd663768b99e6230d3ee6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Nov 2014 18:34:45 +0200 Subject: [PATCH 4340/9457] ACPI / LPSS: add all LPSS devices to the specific power domain Currently the LPSS devices are located in the different power domains depends on LPSS_SAVE_CTX flag. We would like to use the specific power domain for all LPSS devices. The LPSS DMA controller has no knobs to control its power state. The specific power domain implementation will handle this case. The patch does a preparation for that. Signed-off-by: Andy Shevchenko Tested-by: Scott Ashcroft Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 53 ++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 93d160661f4c..f6b71afb80ea 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -499,14 +499,15 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val) /** * acpi_lpss_save_ctx() - Save the private registers of LPSS device * @dev: LPSS device + * @pdata: pointer to the private data of the LPSS device * * Most LPSS devices have private registers which may loose their context when * the device is powered down. acpi_lpss_save_ctx() saves those registers into * prv_reg_ctx array. */ -static void acpi_lpss_save_ctx(struct device *dev) +static void acpi_lpss_save_ctx(struct device *dev, + struct lpss_private_data *pdata) { - struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); unsigned int i; for (i = 0; i < LPSS_PRV_REG_COUNT; i++) { @@ -521,12 +522,13 @@ static void acpi_lpss_save_ctx(struct device *dev) /** * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device * @dev: LPSS device + * @pdata: pointer to the private data of the LPSS device * * Restores the registers that were previously stored with acpi_lpss_save_ctx(). */ -static void acpi_lpss_restore_ctx(struct device *dev) +static void acpi_lpss_restore_ctx(struct device *dev, + struct lpss_private_data *pdata) { - struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); unsigned int i; /* @@ -549,23 +551,31 @@ static void acpi_lpss_restore_ctx(struct device *dev) #ifdef CONFIG_PM_SLEEP static int acpi_lpss_suspend_late(struct device *dev) { - int ret = pm_generic_suspend_late(dev); + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + int ret; + ret = pm_generic_suspend_late(dev); if (ret) return ret; - acpi_lpss_save_ctx(dev); + if (pdata->dev_desc->flags & LPSS_SAVE_CTX) + acpi_lpss_save_ctx(dev, pdata); + return acpi_dev_suspend_late(dev); } static int acpi_lpss_resume_early(struct device *dev) { - int ret = acpi_dev_resume_early(dev); + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + int ret; + ret = acpi_dev_resume_early(dev); if (ret) return ret; - acpi_lpss_restore_ctx(dev); + if (pdata->dev_desc->flags & LPSS_SAVE_CTX) + acpi_lpss_restore_ctx(dev, pdata); + return pm_generic_resume_early(dev); } #endif /* CONFIG_PM_SLEEP */ @@ -573,23 +583,31 @@ static int acpi_lpss_resume_early(struct device *dev) #ifdef CONFIG_PM_RUNTIME static int acpi_lpss_runtime_suspend(struct device *dev) { - int ret = pm_generic_runtime_suspend(dev); + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + int ret; + ret = pm_generic_runtime_suspend(dev); if (ret) return ret; - acpi_lpss_save_ctx(dev); + if (pdata->dev_desc->flags & LPSS_SAVE_CTX) + acpi_lpss_save_ctx(dev, pdata); + return acpi_dev_runtime_suspend(dev); } static int acpi_lpss_runtime_resume(struct device *dev) { - int ret = acpi_dev_runtime_resume(dev); + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + int ret; + ret = acpi_dev_runtime_resume(dev); if (ret) return ret; - acpi_lpss_restore_ctx(dev); + if (pdata->dev_desc->flags & LPSS_SAVE_CTX) + acpi_lpss_restore_ctx(dev, pdata); + return pm_generic_runtime_resume(dev); } #endif /* CONFIG_PM_RUNTIME */ @@ -631,22 +649,21 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, return 0; pdata = acpi_driver_data(adev); - if (!pdata || !pdata->mmio_base) + if (!pdata) return 0; - if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { + if (pdata->mmio_base && + pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) { dev_err(&pdev->dev, "MMIO size insufficient to access LTR\n"); return 0; } switch (action) { case BUS_NOTIFY_BOUND_DRIVER: - if (pdata->dev_desc->flags & LPSS_SAVE_CTX) - pdev->dev.pm_domain = &acpi_lpss_pm_domain; + pdev->dev.pm_domain = &acpi_lpss_pm_domain; break; case BUS_NOTIFY_UNBOUND_DRIVER: - if (pdata->dev_desc->flags & LPSS_SAVE_CTX) - pdev->dev.pm_domain = NULL; + pdev->dev.pm_domain = NULL; break; case BUS_NOTIFY_ADD_DEVICE: if (pdata->dev_desc->flags & LPSS_LTR) -- GitLab From 01ac170ba29a9903ee590e1ef2d8e6b27b49a16c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Nov 2014 18:34:46 +0200 Subject: [PATCH 4341/9457] ACPI / LPSS: allow to use specific PM domain during ->probe() The LPSS DMA controller would like to use the specific PM domain callbacks during early stage, namely in ->probe(). This patch moves the specific PM domain assignment early to be accessible during a whole life time of the device in the system. Suggested-by: Rafael J. Wysocki Signed-off-by: Andy Shevchenko Tested-by: Scott Ashcroft Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index f6b71afb80ea..4804ae31b057 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -659,19 +659,17 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, } switch (action) { - case BUS_NOTIFY_BOUND_DRIVER: - pdev->dev.pm_domain = &acpi_lpss_pm_domain; - break; - case BUS_NOTIFY_UNBOUND_DRIVER: - pdev->dev.pm_domain = NULL; - break; case BUS_NOTIFY_ADD_DEVICE: + pdev->dev.pm_domain = &acpi_lpss_pm_domain; if (pdata->dev_desc->flags & LPSS_LTR) return sysfs_create_group(&pdev->dev.kobj, &lpss_attr_group); + break; case BUS_NOTIFY_DEL_DEVICE: if (pdata->dev_desc->flags & LPSS_LTR) sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group); + pdev->dev.pm_domain = NULL; + break; default: break; } -- GitLab From 6c17ee44d5240a247daef3cdc51a0c62d2b77d75 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Nov 2014 18:34:47 +0200 Subject: [PATCH 4342/9457] ACPI / LPSS: introduce a 'proxy' device to power on LPSS for DMA The LPSS DMA controller does not have _PS0 and _PS3 methods. Moreover it can be powered off automatically whenever the last LPSS device goes down. In case of no power any access to the DMA controller will hang the system. The behaviour is reproduced on some HP laptops based on Intel Bay Trail [1] as well as on Asus T100 transformer. This patch introduces a so called 'proxy' device that has the knobs to handle a power of the LPSS island. When the system needs to program the DMA controller it calls to the ACPI LPSS power domain callbacks that wake or suspend the 'proxy' device. [1] http://www.spinics.net/lists/dmaengine/msg01514.html Suggested-by: Rafael J. Wysocki Signed-off-by: Andy Shevchenko Tested-by: Scott Ashcroft Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 4804ae31b057..d1dd0ada14b7 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -1,7 +1,7 @@ /* * ACPI support for Intel Lynxpoint LPSS. * - * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2013, 2014, Intel Corporation * Authors: Mika Westerberg * Rafael J. Wysocki * @@ -60,6 +60,8 @@ ACPI_MODULE_NAME("acpi_lpss"); #define LPSS_CLK_DIVIDER BIT(2) #define LPSS_LTR BIT(3) #define LPSS_SAVE_CTX BIT(4) +#define LPSS_DEV_PROXY BIT(5) +#define LPSS_PROXY_REQ BIT(6) struct lpss_private_data; @@ -70,8 +72,10 @@ struct lpss_device_desc { void (*setup)(struct lpss_private_data *pdata); }; +static struct device *proxy_device; + static struct lpss_device_desc lpss_dma_desc = { - .flags = LPSS_CLK, + .flags = LPSS_CLK | LPSS_PROXY_REQ, }; struct lpss_private_data { @@ -146,22 +150,24 @@ static struct lpss_device_desc byt_pwm_dev_desc = { }; static struct lpss_device_desc byt_uart_dev_desc = { - .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, + .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX | + LPSS_DEV_PROXY, .prv_offset = 0x800, .setup = lpss_uart_setup, }; static struct lpss_device_desc byt_spi_dev_desc = { - .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, + .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX | + LPSS_DEV_PROXY, .prv_offset = 0x400, }; static struct lpss_device_desc byt_sdio_dev_desc = { - .flags = LPSS_CLK, + .flags = LPSS_CLK | LPSS_DEV_PROXY, }; static struct lpss_device_desc byt_i2c_dev_desc = { - .flags = LPSS_CLK | LPSS_SAVE_CTX, + .flags = LPSS_CLK | LPSS_SAVE_CTX | LPSS_DEV_PROXY, .prv_offset = 0x800, .setup = byt_i2c_setup, }; @@ -368,6 +374,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev, adev->driver_data = pdata; pdev = acpi_create_platform_device(adev); if (!IS_ERR_OR_NULL(pdev)) { + if (!proxy_device && dev_desc->flags & LPSS_DEV_PROXY) + proxy_device = &pdev->dev; return 1; } @@ -593,7 +601,14 @@ static int acpi_lpss_runtime_suspend(struct device *dev) if (pdata->dev_desc->flags & LPSS_SAVE_CTX) acpi_lpss_save_ctx(dev, pdata); - return acpi_dev_runtime_suspend(dev); + ret = acpi_dev_runtime_suspend(dev); + if (ret) + return ret; + + if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device) + return pm_runtime_put_sync_suspend(proxy_device); + + return 0; } static int acpi_lpss_runtime_resume(struct device *dev) @@ -601,6 +616,12 @@ static int acpi_lpss_runtime_resume(struct device *dev) struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; + if (pdata->dev_desc->flags & LPSS_PROXY_REQ && proxy_device) { + ret = pm_runtime_get_sync(proxy_device); + if (ret) + return ret; + } + ret = acpi_dev_runtime_resume(dev); if (ret) return ret; -- GitLab From bb32baf76e56cdb348633f4d789a93e81b975c47 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 5 Nov 2014 18:34:48 +0200 Subject: [PATCH 4343/9457] dmaengine: dw: enable runtime PM On runtime PM aware platforms the DMA have to manage its own power state. This patch enables runtime PM support and applies necessary calls wherever it's needed. Signed-off-by: Andy Shevchenko Acked-by: Vinod Koul Tested-by: Scott Ashcroft Signed-off-by: Rafael J. Wysocki --- drivers/dma/dw/core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 244722170410..380478562b7d 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "../dmaengine.h" #include "internal.h" @@ -1504,6 +1505,9 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->regs = chip->regs; chip->dw = dw; + pm_runtime_enable(chip->dev); + pm_runtime_get_sync(chip->dev); + dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); autocfg = dw_params >> DW_PARAMS_EN & 0x1; @@ -1667,11 +1671,14 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n", nr_channels); + pm_runtime_put_sync_suspend(chip->dev); + return 0; err_dma_register: free_irq(chip->irq, dw); err_pdata: + pm_runtime_put_sync_suspend(chip->dev); return err; } EXPORT_SYMBOL_GPL(dw_dma_probe); @@ -1681,6 +1688,8 @@ int dw_dma_remove(struct dw_dma_chip *chip) struct dw_dma *dw = chip->dw; struct dw_dma_chan *dwc, *_dwc; + pm_runtime_get_sync(chip->dev); + dw_dma_off(dw); dma_async_device_unregister(&dw->dma); @@ -1693,6 +1702,8 @@ int dw_dma_remove(struct dw_dma_chip *chip) channel_clear_bit(dw, CH_EN, dwc->mask); } + pm_runtime_put_sync_suspend(chip->dev); + pm_runtime_disable(chip->dev); return 0; } EXPORT_SYMBOL_GPL(dw_dma_remove); -- GitLab From 24119a8829cdaf299294095ec568bf49e863c5a5 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Thu, 30 Oct 2014 17:52:58 +0800 Subject: [PATCH 4344/9457] ACPI / processor: Update the comments in processor.h In commit 46ba51e (ACPI / processor: Introduce ARCH_MIGHT_HAVE_ACPI_PDC), acpi_processor_set_pdc() was moved to processor_pdc.c, so update the comments accordingly. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- include/acpi/processor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 9b9b6f29bbf3..cbb6cd3a98d7 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -313,11 +313,13 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) #endif /* CONFIG_CPU_FREQ */ /* in processor_core.c */ -void acpi_processor_set_pdc(acpi_handle handle); int acpi_get_apicid(acpi_handle, int type, u32 acpi_id); int acpi_map_cpuid(int apic_id, u32 acpi_id); int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); +/* in processor_pdc.c */ +void acpi_processor_set_pdc(acpi_handle handle); + /* in processor_throttling.c */ int acpi_processor_tstate_has_changed(struct acpi_processor *pr); int acpi_processor_get_throttling_info(struct acpi_processor *pr); -- GitLab From 90253a792ec23481402474704ef498ee81abe4e3 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 5 Nov 2014 15:06:13 +0800 Subject: [PATCH 4345/9457] ACPI / OSL: Add IRQ handler flushing support in the OSL. It is possible that a GPE handler or a fixed event handler still accessed after removing the handlers by invoking acpi_remove_gpe_handler() or acpi_remove_fixed_event_handler(), this possibility can crash OPSM after a module removal. In the Linux kernel, though all other GPE drivers are not modules, since the IPMI_SI (ipmi_si_intf.c) can be compiled as a module, we still need to consider a solution for this issue when the driver switches to ACPI_GPE_RAW_HANDLER mode in order to invoke GPE APIs. ACPICA expects acpi_os_wait_events_complete() to be invoked after GPE disabling so that OSPM can ensure all running GPE handlers have exitted. But currently acpi_os_wait_events_complete() can only flush _Lxx/_Exx evaluation work queue and this philosophy cannot work for drivers that have installed a dedicated GPE handler. The only way to protect a callback is to perform some state holders (reference count, state machine) before invoking the callback. Then this issue can only be fixed by the following means: 1. Flush GPE in ACPICA before invoking the GPE handler. But currently, there is no such implementation in acpi_ev_gpe_dispatch(). 2. Flush GPE in ACPICA OSL before invoking the SCI handler. But currently, there is no such implementation in acpi_irq(). 3. Flush IRQ in OSPM IRQ layer before invoking the IRQ handler. In Linus kernel, this can be done by synchronize_irq(). 4. Flush scheduling in OSPM vector entry layer before invoking the vector. In Linux, this can be done by synchronize_sched(). Since ACPICA expects the GPE handlers to be flushed by the ACPICA OSL or the GPE drivers. If it is implemented by the GPE driver, we should see synchronize_irq()/synchronize_sched() invoked in such drivers. If it is implemented by the ACPICA OSL, ACPICA currently provides acpi_os_wait_events_complete() hook to achieve this. After the following commit: Commit: 69c841b6dd8313c9a673246cc0e2535174272cab Author: Lv Zheng Subject: ACPICA: Update use of acpi_os_wait_events_complete interface. The OSL acpi_os_wait_events_complete() is invoked after a GPE handler is removed from acpi_remove_gpe_handler() or a fixed event handler is removed from acpi_remove_fixed_event_handler(). Thus it is possible to implement GPE handler flushing using this ACPICA OSL now. So the solution 1 is currently not taken into account. By examining the IPMI_SI driver, we noticed that the IPMI_SI driver: 1. Uses free_irq() to flush non GPE based IRQ handlers, in free_irq(), synchronize_irq() is invoked, and 2. Uses acpi_remove_gpe_handler() to flush GPE based IRQ handlers, for such IRQ handlers, there is no synchronize_irq() invoked. Since there isn't synchronize_sched() implemented for this driver, from the driver's perspective, acpi_remove_gpe_handler() should have properly flushed the GPE handlers for it. Since the driver doesn't invoke synchronize_irq(), the solution 3 is not what the drivers expect. This patch implements solution 2. But since given the fact that the GPE is managed inside of ACPICA, and implementing the GPE flushing requires to implement the whole GPE management code again in the OSL, instead of flushing GPE, this patch flushes IRQ in acpi_os_wait_events_complete(). The flushing could last longer than expected as though the target GPE/fixed event that is removed can be fastly flushed, other GPEs/fix events can still be issued during the flushing period. This patch fixes this issue by invoking synchronize_hardirq() in acpi_os_wait_events_complete(). The reason why we don't invoke synchronize_irq() is: currently ACPICA is not threaded IRQ capable and the only difference between synchronize_irq() and synchronize_hardirq() is synchronize_irq() also flushes threaded IRQ handlers. Thus using synchronize_hardirq() can help to reduce the overall synchronization time for the current ACPICA implementation. Signed-off-by: Lv Zheng Cc: Rafael J. Wysocki Cc: Len Brown Cc: Robert Moore Cc: Corey Minyard Cc: linux-acpi@vger.kernel.org Cc: devel@acpica.org Cc: openipmi-developer@lists.sourceforge.net Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 217713c11aaa..f9eeae871593 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1188,6 +1188,12 @@ EXPORT_SYMBOL(acpi_os_execute); void acpi_os_wait_events_complete(void) { + /* + * Make sure the GPE handler or the fixed event handler is not used + * on another CPU after removal. + */ + if (acpi_irq_handler) + synchronize_hardirq(acpi_gbl_FADT.sci_interrupt); flush_workqueue(kacpid_wq); flush_workqueue(kacpi_notify_wq); } -- GitLab From fefb391f8c15900477432a29d9c3527dd66a8415 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 11 Nov 2014 12:52:08 -0800 Subject: [PATCH 4346/9457] HID: wacom: Add support for Intuos Pen Medium Signed-off-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index d343a6ee5bf7..104829524bcd 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2881,6 +2881,10 @@ static const struct wacom_features wacom_features_0x30C = { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; +static const struct wacom_features wacom_features_0x323 = + { "Wacom Intuos P M", 21600, 13500, 1023, 31, + INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; static const struct wacom_features wacom_features_HID_ANY_ID = { "Wacom HID", .type = HID_GENERIC }; @@ -3025,6 +3029,7 @@ const struct hid_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x314) }, { USB_DEVICE_WACOM(0x315) }, { USB_DEVICE_WACOM(0x317) }, + { USB_DEVICE_WACOM(0x323) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, -- GitLab From 77873887729aaddec5cd27203a6ce8c4987733e4 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Thu, 6 Nov 2014 09:40:46 -0800 Subject: [PATCH 4347/9457] x86: Add support for Intel HWP feature detection. Add support of Hardware Managed Performance States (HWP) described in Volume 3 section 14.4 of the SDM. One bit CPUID.06H:EAX[bit 7] expresses the presence of the HWP feature on the processor. The remaining bits CPUID.06H:EAX[bit 8-11] denote the presense of various HWP features. Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/cpufeature.h | 5 +++++ arch/x86/kernel/cpu/scattered.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 0bb1335313b2..aede2c347bde 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -189,6 +189,11 @@ #define X86_FEATURE_DTHERM ( 7*32+ 7) /* Digital Thermal Sensor */ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +#define X86_FEATURE_HWP ( 7*32+ 10) /* "hwp" Intel HWP */ +#define X86_FEATURE_HWP_NOITFY ( 7*32+ 11) /* Intel HWP_NOTIFY */ +#define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12) /* Intel HWP_ACT_WINDOW */ +#define X86_FEATURE_HWP_EPP ( 7*32+13) /* Intel HWP_EPP */ +#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 4a8013d55947..60639093d536 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -36,6 +36,11 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c) { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, + { X86_FEATURE_HWP, CR_EAX, 7, 0x00000006, 0 }, + { X86_FEATURE_HWP_NOITFY, CR_EAX, 8, 0x00000006, 0 }, + { X86_FEATURE_HWP_ACT_WINDOW, CR_EAX, 9, 0x00000006, 0 }, + { X86_FEATURE_HWP_EPP, CR_EAX,10, 0x00000006, 0 }, + { X86_FEATURE_HWP_PKG_REQ, CR_EAX,11, 0x00000006, 0 }, { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, -- GitLab From 2f86dc4cddcb21290ca099e1dce2a53533c86e0b Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Thu, 6 Nov 2014 09:40:47 -0800 Subject: [PATCH 4348/9457] intel_pstate: Add support for HWP Add support of Hardware Managed Performance States (HWP) described in Volume 3 section 14.4 of the SDM. With HWP enbaled intel_pstate will no longer be responsible for selecting P states for the processor. intel_pstate will continue to register to the cpufreq core as the scaling driver for CPUs implementing HWP. In HWP mode intel_pstate provides three functions reporting frequency to the cpufreq core, support for the set_policy() interface from the core and maintaining the intel_pstate sysfs interface in /sys/devices/system/cpu/intel_pstate. User preferences expressed via the set_policy() interface or the sysfs interface are forwared to the CPU via the HWP MSR interface. Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/intel-pstate.txt | 37 ++++++--- Documentation/kernel-parameters.txt | 3 + arch/x86/include/uapi/asm/msr-index.h | 41 ++++++++++ drivers/cpufreq/intel_pstate.c | 100 +++++++++++++++++++++++- 4 files changed, 167 insertions(+), 14 deletions(-) diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt index a69ffe1d54d5..765d7fc0e692 100644 --- a/Documentation/cpu-freq/intel-pstate.txt +++ b/Documentation/cpu-freq/intel-pstate.txt @@ -1,17 +1,28 @@ Intel P-state driver -------------------- -This driver implements a scaling driver with an internal governor for -Intel Core processors. The driver follows the same model as the -Transmeta scaling driver (longrun.c) and implements the setpolicy() -instead of target(). Scaling drivers that implement setpolicy() are -assumed to implement internal governors by the cpufreq core. All the -logic for selecting the current P state is contained within the -driver; no external governor is used by the cpufreq core. - -Intel SandyBridge+ processors are supported. - -New sysfs files for controlling P state selection have been added to +This driver provides an interface to control the P state selection for +SandyBridge+ Intel processors. The driver can operate two different +modes based on the processor model legacy and Hardware P state (HWP) +mode. + +In legacy mode the driver implements a scaling driver with an internal +governor for Intel Core processors. The driver follows the same model +as the Transmeta scaling driver (longrun.c) and implements the +setpolicy() instead of target(). Scaling drivers that implement +setpolicy() are assumed to implement internal governors by the cpufreq +core. All the logic for selecting the current P state is contained +within the driver; no external governor is used by the cpufreq core. + +In HWP mode P state selection is implemented in the processor +itself. The driver provides the interfaces between the cpufreq core and +the processor to control P state selection based on user preferences +and reporting frequency to the cpufreq core. In this mode the +internal governor code is disabled. + +In addtion to the interfaces provided by the cpufreq core for +controlling frequency the driver provides sysfs files for +controlling P state selection. These files have been added to /sys/devices/system/cpu/intel_pstate/ max_perf_pct: limits the maximum P state that will be requested by @@ -33,7 +44,9 @@ frequency is fiction for Intel Core processors. Even if the scaling driver selects a single P state the actual frequency the processor will run at is selected by the processor itself. -New debugfs files have also been added to /sys/kernel/debug/pstate_snb/ +For legacy mode debugfs files have also been added to allow tuning of +the internal governor algorythm. These files are located at +/sys/kernel/debug/pstate_snb/ These files are NOT present in HWP mode. deadband d_gain_pct diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4c81a860cc2b..907a0f119bee 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1446,6 +1446,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. disable Do not enable intel_pstate as the default scaling driver for the supported processors + no_hwp + Do not enable hardware P state control (HWP) + if available. intremap= [X86-64, Intel-IOMMU] on enable Interrupt Remapping (default) diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index e21331ce368f..62838e54947d 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -152,6 +152,45 @@ #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 +/* Hardware P state interface */ +#define MSR_PPERF 0x0000064e +#define MSR_PERF_LIMIT_REASONS 0x0000064f +#define MSR_PM_ENABLE 0x00000770 +#define MSR_HWP_CAPABILITIES 0x00000771 +#define MSR_HWP_REQUEST_PKG 0x00000772 +#define MSR_HWP_INTERRUPT 0x00000773 +#define MSR_HWP_REQUEST 0x00000774 +#define MSR_HWP_STATUS 0x00000777 + +/* CPUID.6.EAX */ +#define HWP_BASE_BIT (1<<7) +#define HWP_NOTIFICATIONS_BIT (1<<8) +#define HWP_ACTIVITY_WINDOW_BIT (1<<9) +#define HWP_ENERGY_PERF_PREFERENCE_BIT (1<<10) +#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11) + +/* IA32_HWP_CAPABILITIES */ +#define HWP_HIGHEST_PERF(x) (x & 0xff) +#define HWP_GUARANTEED_PERF(x) ((x & (0xff << 8)) >>8) +#define HWP_MOSTEFFICIENT_PERF(x) ((x & (0xff << 16)) >>16) +#define HWP_LOWEST_PERF(x) ((x & (0xff << 24)) >>24) + +/* IA32_HWP_REQUEST */ +#define HWP_MIN_PERF(x) (x & 0xff) +#define HWP_MAX_PERF(x) ((x & 0xff) << 8) +#define HWP_DESIRED_PERF(x) ((x & 0xff) << 16) +#define HWP_ENERGY_PERF_PREFERENCE(x) ((x & 0xff) << 24) +#define HWP_ACTIVITY_WINDOW(x) ((x & 0xff3) << 32) +#define HWP_PACKAGE_CONTROL(x) ((x & 0x1) << 42) + +/* IA32_HWP_STATUS */ +#define HWP_GUARANTEED_CHANGE(x) (x & 0x1) +#define HWP_EXCURSION_TO_MINIMUM(x) (x & 0x4) + +/* IA32_HWP_INTERRUPT */ +#define HWP_CHANGE_TO_GUARANTEED_INT(x) (x & 0x1) +#define HWP_EXCURSION_TO_MINIMUM_INT(x) (x & 0x2) + #define MSR_AMD64_MC0_MASK 0xc0010044 #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) @@ -345,6 +384,8 @@ #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 +#define MSR_MISC_PWR_MGMT 0x000001aa + #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 #define ENERGY_PERF_BIAS_PERFORMANCE 0 #define ENERGY_PERF_BIAS_NORMAL 6 diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 27bb6d3877ed..ba35db092239 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -137,6 +137,7 @@ struct cpu_defaults { static struct pstate_adjust_policy pid_params; static struct pstate_funcs pstate_funcs; +static int hwp_active; struct perf_limits { int no_turbo; @@ -244,6 +245,34 @@ static inline void update_turbo_state(void) cpu->pstate.max_pstate == cpu->pstate.turbo_pstate); } +#define PCT_TO_HWP(x) (x * 255 / 100) +static void intel_pstate_hwp_set(void) +{ + int min, max, cpu; + u64 value, freq; + + get_online_cpus(); + + for_each_online_cpu(cpu) { + rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); + min = PCT_TO_HWP(limits.min_perf_pct); + value &= ~HWP_MIN_PERF(~0L); + value |= HWP_MIN_PERF(min); + + max = PCT_TO_HWP(limits.max_perf_pct); + if (limits.no_turbo) { + rdmsrl( MSR_HWP_CAPABILITIES, freq); + max = HWP_GUARANTEED_PERF(freq); + } + + value &= ~HWP_MAX_PERF(~0L); + value |= HWP_MAX_PERF(max); + wrmsrl_on_cpu(cpu, MSR_HWP_REQUEST, value); + } + + put_online_cpus(); +} + /************************** debugfs begin ************************/ static int pid_param_set(void *data, u64 val) { @@ -279,6 +308,8 @@ static void __init intel_pstate_debug_expose_params(void) struct dentry *debugfs_parent; int i = 0; + if (hwp_active) + return; debugfs_parent = debugfs_create_dir("pstate_snb", NULL); if (IS_ERR_OR_NULL(debugfs_parent)) return; @@ -329,8 +360,12 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); return -EPERM; } + limits.no_turbo = clamp_t(int, input, 0, 1); + if (hwp_active) + intel_pstate_hwp_set(); + return count; } @@ -348,6 +383,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); + if (hwp_active) + intel_pstate_hwp_set(); return count; } @@ -363,6 +400,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, limits.min_perf_pct = clamp_t(int, input, 0 , 100); limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); + if (hwp_active) + intel_pstate_hwp_set(); return count; } @@ -395,8 +434,16 @@ static void __init intel_pstate_sysfs_expose_params(void) rc = sysfs_create_group(intel_pstate_kobject, &intel_pstate_attr_group); BUG_ON(rc); } - /************************** sysfs end ************************/ + +static void intel_pstate_hwp_enable(void) +{ + hwp_active++; + pr_info("intel_pstate HWP enabled\n"); + + wrmsrl( MSR_PM_ENABLE, 0x1); +} + static int byt_get_min_pstate(void) { u64 value; @@ -648,6 +695,14 @@ static inline void intel_pstate_sample(struct cpudata *cpu) cpu->prev_mperf = mperf; } +static inline void intel_hwp_set_sample_time(struct cpudata *cpu) +{ + int delay; + + delay = msecs_to_jiffies(50); + mod_timer_pinned(&cpu->timer, jiffies + delay); +} + static inline void intel_pstate_set_sample_time(struct cpudata *cpu) { int delay; @@ -694,6 +749,14 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl); } +static void intel_hwp_timer_func(unsigned long __data) +{ + struct cpudata *cpu = (struct cpudata *) __data; + + intel_pstate_sample(cpu); + intel_hwp_set_sample_time(cpu); +} + static void intel_pstate_timer_func(unsigned long __data) { struct cpudata *cpu = (struct cpudata *) __data; @@ -737,6 +800,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { }; MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); +static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] = { + ICPU(0x56, core_params), + {} +}; + static int intel_pstate_init_cpu(unsigned int cpunum) { struct cpudata *cpu; @@ -753,9 +821,14 @@ static int intel_pstate_init_cpu(unsigned int cpunum) intel_pstate_get_cpu_pstates(cpu); init_timer_deferrable(&cpu->timer); - cpu->timer.function = intel_pstate_timer_func; cpu->timer.data = (unsigned long)cpu; cpu->timer.expires = jiffies + HZ/100; + + if (!hwp_active) + cpu->timer.function = intel_pstate_timer_func; + else + cpu->timer.function = intel_hwp_timer_func; + intel_pstate_busy_pid_reset(cpu); intel_pstate_sample(cpu); @@ -792,6 +865,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) limits.no_turbo = 0; return 0; } + limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); @@ -801,6 +875,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); + if (hwp_active) + intel_pstate_hwp_set(); + return 0; } @@ -823,6 +900,9 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy) pr_info("intel_pstate CPU %d exiting\n", cpu_num); del_timer_sync(&all_cpu_data[cpu_num]->timer); + if (hwp_active) + return; + intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); } @@ -866,6 +946,7 @@ static struct cpufreq_driver intel_pstate_driver = { }; static int __initdata no_load; +static int __initdata no_hwp; static int intel_pstate_msrs_not_valid(void) { @@ -959,6 +1040,15 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void) { struct acpi_table_header hdr; struct hw_vendor_info *v_info; + const struct x86_cpu_id *id; + u64 misc_pwr; + + id = x86_match_cpu(intel_pstate_cpu_oob_ids); + if (id) { + rdmsrl(MSR_MISC_PWR_MGMT, misc_pwr); + if ( misc_pwr & (1 << 8)) + return true; + } if (acpi_disabled || ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr))) @@ -982,6 +1072,7 @@ static int __init intel_pstate_init(void) int cpu, rc = 0; const struct x86_cpu_id *id; struct cpu_defaults *cpu_info; + struct cpuinfo_x86 *c = &boot_cpu_data; if (no_load) return -ENODEV; @@ -1011,6 +1102,9 @@ static int __init intel_pstate_init(void) if (!all_cpu_data) return -ENOMEM; + if (cpu_has(c,X86_FEATURE_HWP) && !no_hwp) + intel_pstate_hwp_enable(); + rc = cpufreq_register_driver(&intel_pstate_driver); if (rc) goto out; @@ -1041,6 +1135,8 @@ static int __init intel_pstate_setup(char *str) if (!strcmp(str, "disable")) no_load = 1; + if (!strcmp(str, "no_hwp")) + no_hwp = 1; return 0; } early_param("intel_pstate", intel_pstate_setup); -- GitLab From 43f8a966e91f387eabe85d2f2d12519c218f9dd0 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Thu, 6 Nov 2014 09:50:45 -0800 Subject: [PATCH 4349/9457] intel_pstate: Add CPUID for BDW-H CPU Add BDW-H to the list of supported processors. Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index ba35db092239..ab2e100a1807 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -793,6 +793,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(0x3f, core_params), ICPU(0x45, core_params), ICPU(0x46, core_params), + ICPU(0x47, core_params), ICPU(0x4c, byt_params), ICPU(0x4f, core_params), ICPU(0x56, core_params), -- GitLab From 6c91023dc35c88d5e6aebe4bfe6f1ed5ec2b84be Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 11 Nov 2014 13:37:30 -0800 Subject: [PATCH 4350/9457] irda: Remove IRDA_ logging macros And use the more common mechanisms directly. Other miscellanea: o Coalesce formats o Add missing newlines o Realign arguments o Remove unnecessary OOM message logging as there's a generic stack dump already on OOM. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/irda/act200l-sir.c | 3 +- drivers/net/irda/ali-ircc.c | 57 ++++++------ drivers/net/irda/girbil-sir.c | 6 +- drivers/net/irda/irda-usb.c | 47 +++++----- drivers/net/irda/irtty-sir.c | 10 +-- drivers/net/irda/ma600-sir.c | 6 +- drivers/net/irda/mcp2120-sir.c | 6 +- drivers/net/irda/mcs7780.c | 45 +++++----- drivers/net/irda/nsc-ircc.c | 66 +++++++------- drivers/net/irda/sir_dev.c | 35 ++++---- drivers/net/irda/smsc-ircc2.c | 130 +++++++++++++++------------- drivers/net/irda/tekram-sir.c | 3 +- drivers/net/irda/via-ircc.c | 21 ++--- drivers/net/irda/vlsi_ir.c | 118 +++++++++++++------------ drivers/net/irda/vlsi_ir.h | 3 +- drivers/net/irda/w83977af_ir.c | 9 +- include/net/irda/irda.h | 4 - net/irda/af_irda.c | 34 ++++---- net/irda/ircomm/ircomm_core.c | 5 +- net/irda/ircomm/ircomm_lmp.c | 2 +- net/irda/ircomm/ircomm_param.c | 3 +- net/irda/ircomm/ircomm_ttp.c | 10 +-- net/irda/ircomm/ircomm_tty.c | 21 +++-- net/irda/ircomm/ircomm_tty_attach.c | 12 +-- net/irda/ircomm/ircomm_tty_ioctl.c | 3 +- net/irda/irda_device.c | 18 ++-- net/irda/iriap.c | 24 +++-- net/irda/iriap_event.c | 4 +- net/irda/irias_object.c | 64 ++++++-------- net/irda/irlan/irlan_client.c | 22 ++--- net/irda/irlan/irlan_client_event.c | 4 +- net/irda/irlan/irlan_common.c | 3 +- net/irda/irlan/irlan_eth.c | 2 +- net/irda/irlap.c | 15 ++-- net/irda/irlap_event.c | 5 +- net/irda/irlap_frame.c | 30 +++---- net/irda/irlmp.c | 19 ++-- net/irda/irlmp_event.c | 8 +- net/irda/irttp.c | 31 +++---- net/irda/parameters.c | 39 ++++----- net/irda/qos.c | 12 +-- net/irda/wrapper.c | 6 +- 42 files changed, 486 insertions(+), 479 deletions(-) diff --git a/drivers/net/irda/act200l-sir.c b/drivers/net/irda/act200l-sir.c index 8ff084f1d236..a9116456bc9a 100644 --- a/drivers/net/irda/act200l-sir.c +++ b/drivers/net/irda/act200l-sir.c @@ -240,7 +240,8 @@ static int act200l_reset(struct sir_dev *dev) dev->speed = 9600; break; default: - IRDA_ERROR("%s(), unknown state %d\n", __func__, state); + net_err_ratelimited("%s(), unknown state %d\n", + __func__, state); ret = -1; break; } diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index befa45f809c3..7f23e5ff099e 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -158,8 +158,8 @@ static int __init ali_ircc_init(void) ret = platform_driver_register(&ali_ircc_driver); if (ret) { - IRDA_ERROR("%s, Can't register driver!\n", - ALI_IRCC_DRIVER_NAME); + net_err_ratelimited("%s, Can't register driver!\n", + ALI_IRCC_DRIVER_NAME); return ret; } @@ -292,8 +292,8 @@ static int ali_ircc_open(int i, chipio_t *info) IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__); if (i >= ARRAY_SIZE(dev_self)) { - IRDA_ERROR("%s(), maximum number of supported chips reached!\n", - __func__); + net_err_ratelimited("%s(), maximum number of supported chips reached!\n", + __func__); return -ENOMEM; } @@ -303,8 +303,8 @@ static int ali_ircc_open(int i, chipio_t *info) dev = alloc_irdadev(sizeof(*self)); if (dev == NULL) { - IRDA_ERROR("%s(), can't allocate memory for control block!\n", - __func__); + net_err_ratelimited("%s(), can't allocate memory for control block!\n", + __func__); return -ENOMEM; } @@ -328,8 +328,8 @@ static int ali_ircc_open(int i, chipio_t *info) /* Reserve the ioports that we need */ if (!request_region(self->io.fir_base, self->io.fir_ext, ALI_IRCC_DRIVER_NAME)) { - IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", __func__, - self->io.fir_base); + net_warn_ratelimited("%s(), can't get iobase of 0x%03x\n", + __func__, self->io.fir_base); err = -ENODEV; goto err_out1; } @@ -380,15 +380,17 @@ static int ali_ircc_open(int i, chipio_t *info) err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); + net_err_ratelimited("%s(), register_netdev() failed!\n", + __func__); goto err_out4; } - IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); + net_info_ratelimited("IrDA: Registered device %s\n", dev->name); /* Check dongle id */ dongle_id = ali_ircc_read_dongle_id(i, info); - IRDA_MESSAGE("%s(), %s, Found dongle: %s\n", __func__, - ALI_IRCC_DRIVER_NAME, dongle_types[dongle_id]); + net_info_ratelimited("%s(), %s, Found dongle: %s\n", + __func__, ALI_IRCC_DRIVER_NAME, + dongle_types[dongle_id]); self->io.dongle_id = dongle_id; @@ -521,7 +523,8 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info) info->dma = reg & 0x07; if(info->dma == 0x04) - IRDA_WARNING("%s(), No DMA channel assigned !\n", __func__); + net_warn_ratelimited("%s(), No DMA channel assigned !\n", + __func__); else IRDA_DEBUG(2, "%s(), probing dma=%d\n", __func__, info->dma); @@ -578,8 +581,8 @@ static int ali_ircc_setup(chipio_t *info) /* Should be 0x00 in the M1535/M1535D */ if(version != 0x00) { - IRDA_ERROR("%s, Wrong chip version %02x\n", - ALI_IRCC_DRIVER_NAME, version); + net_err_ratelimited("%s, Wrong chip version %02x\n", + ALI_IRCC_DRIVER_NAME, version); return -1; } @@ -612,8 +615,8 @@ static int ali_ircc_setup(chipio_t *info) /* Switch to SIR space */ FIR2SIR(iobase); - IRDA_MESSAGE("%s, driver loaded (Benjamin Kong)\n", - ALI_IRCC_DRIVER_NAME); + net_info_ratelimited("%s, driver loaded (Benjamin Kong)\n", + ALI_IRCC_DRIVER_NAME); /* Enable receive interrupts */ // outb(UART_IER_RDI, iobase+UART_IER); //benjamin 2000/11/23 01:25PM @@ -1352,9 +1355,8 @@ static int ali_ircc_net_open(struct net_device *dev) /* Request IRQ and install Interrupt Handler */ if (request_irq(self->io.irq, ali_ircc_interrupt, 0, dev->name, dev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", - ALI_IRCC_DRIVER_NAME, - self->io.irq); + net_warn_ratelimited("%s, unable to allocate irq=%d\n", + ALI_IRCC_DRIVER_NAME, self->io.irq); return -EAGAIN; } @@ -1363,9 +1365,8 @@ static int ali_ircc_net_open(struct net_device *dev) * failure. */ if (request_dma(self->io.dma, dev->name)) { - IRDA_WARNING("%s, unable to allocate dma=%d\n", - ALI_IRCC_DRIVER_NAME, - self->io.dma); + net_warn_ratelimited("%s, unable to allocate dma=%d\n", + ALI_IRCC_DRIVER_NAME, self->io.dma); free_irq(self->io.irq, dev); return -EAGAIN; } @@ -1671,7 +1672,8 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) if((inb(iobase+FIR_LSR) & LSR_FRAME_ABORT) == LSR_FRAME_ABORT) { - IRDA_ERROR("%s(), ********* LSR_FRAME_ABORT *********\n", __func__); + net_err_ratelimited("%s(), ********* LSR_FRAME_ABORT *********\n", + __func__); self->netdev->stats.tx_errors++; self->netdev->stats.tx_fifo_errors++; } @@ -1918,9 +1920,6 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) skb = dev_alloc_skb(len+1); if (skb == NULL) { - IRDA_WARNING("%s(), memory squeeze, " - "dropping frame.\n", - __func__); self->netdev->stats.rx_dropped++; return FALSE; @@ -2127,7 +2126,7 @@ static int ali_ircc_suspend(struct platform_device *dev, pm_message_t state) { struct ali_ircc_cb *self = platform_get_drvdata(dev); - IRDA_MESSAGE("%s, Suspending\n", ALI_IRCC_DRIVER_NAME); + net_info_ratelimited("%s, Suspending\n", ALI_IRCC_DRIVER_NAME); if (self->io.suspended) return 0; @@ -2148,7 +2147,7 @@ static int ali_ircc_resume(struct platform_device *dev) ali_ircc_net_open(self->netdev); - IRDA_MESSAGE("%s, Waking up\n", ALI_IRCC_DRIVER_NAME); + net_info_ratelimited("%s, Waking up\n", ALI_IRCC_DRIVER_NAME); self->io.suspended = 0; diff --git a/drivers/net/irda/girbil-sir.c b/drivers/net/irda/girbil-sir.c index 96cdecff349d..f0512ad7dae7 100644 --- a/drivers/net/irda/girbil-sir.c +++ b/drivers/net/irda/girbil-sir.c @@ -179,7 +179,8 @@ static int girbil_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s - undefined state %d\n", __func__, state); + net_err_ratelimited("%s - undefined state %d\n", + __func__, state); ret = -EINVAL; break; } @@ -241,7 +242,8 @@ static int girbil_reset(struct sir_dev *dev) break; default: - IRDA_ERROR("%s(), undefined state %d\n", __func__, state); + net_err_ratelimited("%s(), undefined state %d\n", + __func__, state); ret = -1; break; } diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 925b78cc9797..e9aedbe3fc92 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -307,7 +307,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Grab the speed URB */ urb = self->speed_urb; if (urb->status != 0) { - IRDA_WARNING("%s(), URB still in use!\n", __func__); + net_warn_ratelimited("%s(), URB still in use!\n", __func__); return; } @@ -333,7 +333,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Irq disabled -> GFP_ATOMIC */ if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Speed URB\n", __func__); + net_warn_ratelimited("%s(), failed Speed URB\n", __func__); } } @@ -435,7 +435,7 @@ static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb, } if (urb->status != 0) { - IRDA_WARNING("%s(), URB still in use!\n", __func__); + net_warn_ratelimited("%s(), URB still in use!\n", __func__); goto drop; } @@ -522,7 +522,7 @@ static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb, /* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */ if ((res = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Tx URB\n", __func__); + net_warn_ratelimited("%s(), failed Tx URB\n", __func__); netdev->stats.tx_errors++; /* Let USB recover : We will catch that in the watchdog */ /*netif_start_queue(netdev);*/ @@ -638,7 +638,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) /* self->present *MUST* be read under spinlock */ if (!self->present) { - IRDA_WARNING("%s(), device not present!\n", __func__); + net_warn_ratelimited("%s(), device not present!\n", __func__); netif_stop_queue(netdev); spin_unlock_irqrestore(&self->lock, flags); return; @@ -783,8 +783,8 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc if (ret) { /* If this ever happen, we are in deep s***. * Basically, the Rx path will stop... */ - IRDA_WARNING("%s(), Failed to submit Rx URB %d\n", - __func__, ret); + net_warn_ratelimited("%s(), Failed to submit Rx URB %d\n", + __func__, ret); } } @@ -859,7 +859,7 @@ static void irda_usb_receive(struct urb *urb) /* Check for empty frames */ if (urb->actual_length <= self->header_length) { - IRDA_WARNING("%s(), empty frame!\n", __func__); + net_warn_ratelimited("%s(), empty frame!\n", __func__); goto done; } @@ -1088,8 +1088,8 @@ static int stir421x_patch_device(struct irda_usb_cb *self) return ret; /* We get a patch from userspace */ - IRDA_MESSAGE("%s(): Received firmware %s (%zu bytes)\n", - __func__, stir421x_fw_name, fw->size); + net_info_ratelimited("%s(): Received firmware %s (%zu bytes)\n", + __func__, stir421x_fw_name, fw->size); ret = -EINVAL; @@ -1179,13 +1179,13 @@ static int irda_usb_net_open(struct net_device *netdev) /* Can only open the device if it's there */ if(!self->present) { spin_unlock_irqrestore(&self->lock, flags); - IRDA_WARNING("%s(), device not present!\n", __func__); + net_warn_ratelimited("%s(), device not present!\n", __func__); return -1; } if(self->needspatch) { spin_unlock_irqrestore(&self->lock, flags); - IRDA_WARNING("%s(), device needs patch\n", __func__) ; + net_warn_ratelimited("%s(), device needs patch\n", __func__); return -EIO ; } @@ -1227,8 +1227,6 @@ static int irda_usb_net_open(struct net_device *netdev) if (!skb) { /* If this ever happen, we are in deep s***. * Basically, we can't start the Rx path... */ - IRDA_WARNING("%s(), Failed to allocate Rx skb\n", - __func__); return -1; } //skb_reserve(newskb, USB_IRDA_HEADER - 1); @@ -1505,7 +1503,8 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ /* This is our interrupt endpoint */ self->bulk_int_ep = ep; } else { - IRDA_ERROR("%s(), Unrecognised endpoint %02X.\n", __func__, ep); + net_err_ratelimited("%s(), Unrecognised endpoint %02X\n", + __func__, ep); } } } @@ -1575,11 +1574,11 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf IRDA_DEBUG(1, "%s(), ret=%d\n", __func__, ret); if (ret < sizeof(*desc)) { - IRDA_WARNING("usb-irda: class_descriptor read %s (%d)\n", - (ret<0) ? "failed" : "too short", ret); + net_warn_ratelimited("usb-irda: class_descriptor read %s (%d)\n", + ret < 0 ? "failed" : "too short", ret); } else if (desc->bDescriptorType != USB_DT_IRDA) { - IRDA_WARNING("usb-irda: bad class_descriptor type\n"); + net_warn_ratelimited("usb-irda: bad class_descriptor type\n"); } else { #ifdef IU_DUMP_CLASS_DESC @@ -1622,9 +1621,9 @@ static int irda_usb_probe(struct usb_interface *intf, * don't need to check if the dongle is really ours. * Jean II */ - IRDA_MESSAGE("IRDA-USB found at address %d, Vendor: %x, Product: %x\n", - dev->devnum, le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); + net_info_ratelimited("IRDA-USB found at address %d, Vendor: %x, Product: %x\n", + dev->devnum, le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); net = alloc_irdadev(sizeof(*self)); if (!net) @@ -1700,7 +1699,7 @@ static int irda_usb_probe(struct usb_interface *intf, interface = intf->cur_altsetting; if(!irda_usb_parse_endpoints(self, interface->endpoint, interface->desc.bNumEndpoints)) { - IRDA_ERROR("%s(), Bogus endpoints...\n", __func__); + net_err_ratelimited("%s(), Bogus endpoints...\n", __func__); ret = -EIO; goto err_out_3; } @@ -1746,7 +1745,7 @@ static int irda_usb_probe(struct usb_interface *intf, if (ret) goto err_out_5; - IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); + net_info_ratelimited("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); if (self->needspatch) { @@ -1754,7 +1753,7 @@ static int irda_usb_probe(struct usb_interface *intf, ret = stir421x_patch_device(self); self->needspatch = (ret < 0); if (self->needspatch) { - IRDA_ERROR("STIR421X: Couldn't upload patch\n"); + net_err_ratelimited("STIR421X: Couldn't upload patch\n"); goto err_out_6; } diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 24b6dddd7f2f..abbb654c0666 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -231,7 +231,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, dev = priv->dev; if (!dev) { - IRDA_WARNING("%s(), not ready yet!\n", __func__); + net_warn_ratelimited("%s(), not ready yet!\n", __func__); return; } @@ -555,8 +555,8 @@ static int __init irtty_sir_init(void) int err; if ((err = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) - IRDA_ERROR("IrDA: can't register line discipline (err = %d)\n", - err); + net_err_ratelimited("IrDA: can't register line discipline (err = %d)\n", + err); return err; } @@ -565,8 +565,8 @@ static void __exit irtty_sir_cleanup(void) int err; if ((err = tty_unregister_ldisc(N_IRDA))) { - IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n", - __func__, err); + net_err_ratelimited("%s(), can't unregister line discipline (err = %d)\n", + __func__, err); } } diff --git a/drivers/net/irda/ma600-sir.c b/drivers/net/irda/ma600-sir.c index a9a81358477b..944d044510e3 100644 --- a/drivers/net/irda/ma600-sir.c +++ b/drivers/net/irda/ma600-sir.c @@ -198,9 +198,9 @@ static int ma600_change_speed(struct sir_dev *dev, unsigned speed) sirdev_raw_read(dev, &byte, sizeof(byte)); if (byte != get_control_byte(speed)) { - IRDA_WARNING("%s(): bad control byte read-back %02x != %02x\n", - __func__, (unsigned) byte, - (unsigned) get_control_byte(speed)); + net_warn_ratelimited("%s(): bad control byte read-back %02x != %02x\n", + __func__, (unsigned)byte, + (unsigned)get_control_byte(speed)); return -1; } else diff --git a/drivers/net/irda/mcp2120-sir.c b/drivers/net/irda/mcp2120-sir.c index 5e2f4859cee7..97674695211c 100644 --- a/drivers/net/irda/mcp2120-sir.c +++ b/drivers/net/irda/mcp2120-sir.c @@ -155,7 +155,8 @@ static int mcp2120_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s(), undefine state %d\n", __func__, state); + net_err_ratelimited("%s(), undefine state %d\n", + __func__, state); ret = -EINVAL; break; } @@ -213,7 +214,8 @@ static int mcp2120_reset(struct sir_dev *dev) break; default: - IRDA_ERROR("%s(), undefined state %d\n", __func__, state); + net_err_ratelimited("%s(), undefined state %d\n", + __func__, state); ret = -EINVAL; break; } diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 16f8ffb50e04..6cbd29dcf2d6 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -197,14 +197,14 @@ static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs) /* Setup a communication between mcs7780 and agilent chip. */ static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs) { - IRDA_WARNING("This transceiver type is not supported yet.\n"); + net_warn_ratelimited("This transceiver type is not supported yet\n"); return 1; } /* Setup a communication between mcs7780 and sharp chip. */ static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs) { - IRDA_WARNING("This transceiver type is not supported yet.\n"); + net_warn_ratelimited("This transceiver type is not supported yet\n"); return 1; } @@ -213,9 +213,9 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) { int ret = 0; __u16 rval; - char *msg; + const char *msg; - msg = "Basic transceiver setup error."; + msg = "Basic transceiver setup error"; /* read value of MODE Register, set the DRIVER and RESET bits * and write value back out to MODE Register @@ -261,7 +261,7 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) if(unlikely(ret)) goto error; - msg = "transceiver model specific setup error."; + msg = "transceiver model specific setup error"; switch (mcs->transceiver_type) { case MCS_TSC_VISHAY: ret = mcs_setup_transceiver_vishay(mcs); @@ -276,8 +276,8 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) break; default: - IRDA_WARNING("Unknown transceiver type: %d\n", - mcs->transceiver_type); + net_warn_ratelimited("Unknown transceiver type: %d\n", + mcs->transceiver_type); ret = 1; } if (unlikely(ret)) @@ -300,7 +300,7 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) goto error; } - msg = "transceiver reset."; + msg = "transceiver reset"; ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval); if (unlikely(ret != 2)) @@ -315,7 +315,7 @@ static inline int mcs_setup_transceiver(struct mcs_cb *mcs) return ret; error: - IRDA_ERROR("%s\n", msg); + net_err_ratelimited("%s\n", msg); return ret; } @@ -399,8 +399,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) new_len = len - 2; if(unlikely(new_len <= 0)) { - IRDA_ERROR("%s short frame length %d\n", - mcs->netdev->name, new_len); + net_err_ratelimited("%s short frame length %d\n", + mcs->netdev->name, new_len); ++mcs->netdev->stats.rx_errors; ++mcs->netdev->stats.rx_length_errors; return; @@ -409,8 +409,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) fcs = irda_calc_crc16(~fcs, buf, len); if(fcs != GOOD_FCS) { - IRDA_ERROR("crc error calc 0x%x len %d\n", - fcs, new_len); + net_err_ratelimited("crc error calc 0x%x len %d\n", + fcs, new_len); mcs->netdev->stats.rx_errors++; mcs->netdev->stats.rx_crc_errors++; return; @@ -452,8 +452,8 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) new_len = len - 4; if(unlikely(new_len <= 0)) { - IRDA_ERROR("%s short frame length %d\n", - mcs->netdev->name, new_len); + net_err_ratelimited("%s short frame length %d\n", + mcs->netdev->name, new_len); ++mcs->netdev->stats.rx_errors; ++mcs->netdev->stats.rx_length_errors; return; @@ -461,7 +461,8 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) fcs = ~(crc32_le(~0, buf, new_len)); if(fcs != get_unaligned_le32(buf + new_len)) { - IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); + net_err_ratelimited("crc error calc 0x%x len %d\n", + fcs, new_len); mcs->netdev->stats.rx_errors++; mcs->netdev->stats.rx_crc_errors++; return; @@ -583,7 +584,7 @@ static int mcs_speed_change(struct mcs_cb *mcs) } while(cnt++ < 100 && (rval & MCS_IRINTX)); if (cnt > 100) { - IRDA_ERROR("unable to change speed\n"); + net_err_ratelimited("unable to change speed\n"); ret = -EIO; goto error; } @@ -634,8 +635,8 @@ static int mcs_speed_change(struct mcs_cb *mcs) default: ret = 1; - IRDA_WARNING("Unknown transceiver type: %d\n", - mcs->transceiver_type); + net_warn_ratelimited("Unknown transceiver type: %d\n", + mcs->transceiver_type); } if (unlikely(ret)) goto error; @@ -731,7 +732,7 @@ static int mcs_net_open(struct net_device *netdev) sprintf(hwname, "usb#%d", mcs->usbdev->devnum); mcs->irlap = irlap_open(netdev, &mcs->qos, hwname); if (!mcs->irlap) { - IRDA_ERROR("mcs7780: irlap_open failed\n"); + net_err_ratelimited("mcs7780: irlap_open failed\n"); goto error2; } @@ -851,7 +852,7 @@ static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb, mcs->out_buf, wraplen, mcs_send_irq, mcs); if ((ret = usb_submit_urb(mcs->tx_urb, GFP_ATOMIC))) { - IRDA_ERROR("failed tx_urb: %d\n", ret); + net_err_ratelimited("failed tx_urb: %d\n", ret); switch (ret) { case -ENODEV: case -EPIPE: @@ -899,7 +900,7 @@ static int mcs_probe(struct usb_interface *intf, ret = usb_reset_configuration(udev); if (ret != 0) { - IRDA_ERROR("mcs7780: usb reset configuration failed\n"); + net_err_ratelimited("mcs7780: usb reset configuration failed\n"); goto error2; } diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 66bc03bdb138..c0a179098ea5 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -211,7 +211,8 @@ static int __init nsc_ircc_init(void) ret = platform_driver_register(&nsc_ircc_driver); if (ret) { - IRDA_ERROR("%s, Can't register driver!\n", driver_name); + net_err_ratelimited("%s, Can't register driver!\n", + driver_name); return ret; } @@ -260,7 +261,8 @@ static int __init nsc_ircc_init(void) info.irq = pnp_info.irq; if (info.fir_base < 0x2000) { - IRDA_MESSAGE("%s, chip->init\n", driver_name); + net_info_ratelimited("%s, chip->init\n", + driver_name); chip->init(chip, &info); } else chip->probe(chip, &info); @@ -370,22 +372,23 @@ static int __init nsc_ircc_open(chipio_t *info) } if (chip_index == ARRAY_SIZE(dev_self)) { - IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __func__); + net_err_ratelimited("%s(), maximum number of supported chips reached!\n", + __func__); return -ENOMEM; } - IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, - info->cfg_base); + net_info_ratelimited("%s, Found chip at base=0x%03x\n", + driver_name, info->cfg_base); if ((nsc_ircc_setup(info)) == -1) return -1; - IRDA_MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name); + net_info_ratelimited("%s, driver loaded (Dag Brattli)\n", driver_name); dev = alloc_irdadev(sizeof(struct nsc_ircc_cb)); if (dev == NULL) { - IRDA_ERROR("%s(), can't allocate memory for " - "control block!\n", __func__); + net_err_ratelimited("%s(), can't allocate memory for control block!\n", + __func__); return -ENOMEM; } @@ -408,8 +411,8 @@ static int __init nsc_ircc_open(chipio_t *info) /* Reserve the ioports that we need */ ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name); if (!ret) { - IRDA_WARNING("%s(), can't get iobase of 0x%03x\n", - __func__, self->io.fir_base); + net_warn_ratelimited("%s(), can't get iobase of 0x%03x\n", + __func__, self->io.fir_base); err = -ENODEV; goto out1; } @@ -460,21 +463,22 @@ static int __init nsc_ircc_open(chipio_t *info) err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); + net_err_ratelimited("%s(), register_netdev() failed!\n", + __func__); goto out4; } - IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); + net_info_ratelimited("IrDA: Registered device %s\n", dev->name); /* Check if user has supplied a valid dongle id or not */ if ((dongle_id <= 0) || (dongle_id >= ARRAY_SIZE(dongle_types))) { dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base); - IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name, - dongle_types[dongle_id]); + net_info_ratelimited("%s, Found dongle: %s\n", + driver_name, dongle_types[dongle_id]); } else { - IRDA_MESSAGE("%s, Using dongle: %s\n", driver_name, - dongle_types[dongle_id]); + net_info_ratelimited("%s, Using dongle: %s\n", + driver_name, dongle_types[dongle_id]); } self->io.dongle_id = dongle_id; @@ -567,7 +571,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 0x2e8: outb(0x15, cfg_base+1); break; case 0x3f8: outb(0x16, cfg_base+1); break; case 0x2f8: outb(0x17, cfg_base+1); break; - default: IRDA_ERROR("%s(), invalid base_address", __func__); + default: net_err_ratelimited("%s(), invalid base_address\n", __func__); } /* Control Signal Routing Register (CSRT) */ @@ -579,7 +583,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 9: temp = 0x05; break; case 11: temp = 0x06; break; case 15: temp = 0x07; break; - default: IRDA_ERROR("%s(), invalid irq", __func__); + default: net_err_ratelimited("%s(), invalid irq\n", __func__); } outb(CFG_108_CSRT, cfg_base); @@ -587,7 +591,7 @@ static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info) case 0: outb(0x08+temp, cfg_base+1); break; case 1: outb(0x10+temp, cfg_base+1); break; case 3: outb(0x18+temp, cfg_base+1); break; - default: IRDA_ERROR("%s(), invalid dma", __func__); + default: net_err_ratelimited("%s(), invalid dma\n", __func__); } outb(CFG_108_MCTL, cfg_base); /* Mode Control Register (MCTL) */ @@ -993,8 +997,8 @@ static int nsc_ircc_setup(chipio_t *info) /* Should be 0x2? */ if (0x20 != (version & 0xf0)) { - IRDA_ERROR("%s, Wrong chip version %02x\n", - driver_name, version); + net_err_ratelimited("%s, Wrong chip version %02x\n", + driver_name, version); return -1; } @@ -1872,9 +1876,6 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) skb = dev_alloc_skb(len+1); if (skb == NULL) { - IRDA_WARNING("%s(), memory squeeze, " - "dropping frame.\n", - __func__); self->netdev->stats.rx_dropped++; /* Restore bank register */ @@ -2063,9 +2064,8 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase, nsc_ircc_dma_receive(self); self->ier = IER_SFIF_IE; } else - IRDA_WARNING("%s(), potential " - "Tx queue lockup !\n", - __func__); + net_warn_ratelimited("%s(), potential Tx queue lockup !\n", + __func__); } } else { /* Not finished yet, so interrupt on DMA again */ @@ -2184,8 +2184,8 @@ static int nsc_ircc_net_open(struct net_device *dev) iobase = self->io.fir_base; if (request_irq(self->io.irq, nsc_ircc_interrupt, 0, dev->name, dev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", - driver_name, self->io.irq); + net_warn_ratelimited("%s, unable to allocate irq=%d\n", + driver_name, self->io.irq); return -EAGAIN; } /* @@ -2193,8 +2193,8 @@ static int nsc_ircc_net_open(struct net_device *dev) * failure. */ if (request_dma(self->io.dma, dev->name)) { - IRDA_WARNING("%s, unable to allocate dma=%d\n", - driver_name, self->io.dma); + net_warn_ratelimited("%s, unable to allocate dma=%d\n", + driver_name, self->io.dma); free_irq(self->io.irq, dev); return -EAGAIN; } @@ -2372,8 +2372,8 @@ static int nsc_ircc_resume(struct platform_device *dev) if (netif_running(self->netdev)) { if (request_irq(self->io.irq, nsc_ircc_interrupt, 0, self->netdev->name, self->netdev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", - driver_name, self->io.irq); + net_warn_ratelimited("%s, unable to allocate irq=%d\n", + driver_name, self->io.irq); /* * Don't fail resume process, just kill this diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 43e9ab4f4d7e..5bfcd25923b4 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -82,7 +82,7 @@ static int sirdev_tx_complete_fsm(struct sir_dev *dev) return 0; default: - IRDA_ERROR("%s - undefined state\n", __func__); + net_err_ratelimited("%s - undefined state\n", __func__); return -EINVAL; } fsm->substate = next_state; @@ -251,12 +251,13 @@ static void sirdev_config_fsm(struct work_struct *work) break; default: - IRDA_ERROR("%s - undefined state\n", __func__); + net_err_ratelimited("%s - undefined state\n", __func__); fsm->result = -EINVAL; /* fall thru */ case SIRDEV_STATE_ERROR: - IRDA_ERROR("%s - error: %d\n", __func__, fsm->result); + net_err_ratelimited("%s - error: %d\n", + __func__, fsm->result); #if 0 /* don't enable this before we have netdev->tx_timeout to recover */ netif_stop_queue(dev->netdev); @@ -299,7 +300,7 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par if (fsm->state == SIRDEV_STATE_DEAD) { /* race with sirdev_close should never happen */ - IRDA_ERROR("%s(), instance staled!\n", __func__); + net_err_ratelimited("%s(), instance staled!\n", __func__); up(&fsm->sem); return -ESTALE; /* or better EPIPE? */ } @@ -452,8 +453,8 @@ void sirdev_write_complete(struct sir_dev *dev) } else if (unlikely(actual<0)) { /* could be dropped later when we have tx_timeout to recover */ - IRDA_ERROR("%s: drv->do_write failed (%d)\n", - __func__, actual); + net_err_ratelimited("%s: drv->do_write failed (%d)\n", + __func__, actual); if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; dev_kfree_skb_any(skb); @@ -507,8 +508,8 @@ void sirdev_write_complete(struct sir_dev *dev) /* should never happen * forget the speed change and hope the stack recovers */ - IRDA_ERROR("%s - schedule speed change failed: %d\n", - __func__, err); + net_err_ratelimited("%s - schedule speed change failed: %d\n", + __func__, err); netif_wake_queue(dev->netdev); } /* else: success @@ -535,13 +536,13 @@ EXPORT_SYMBOL(sirdev_write_complete); int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) { if (!dev || !dev->netdev) { - IRDA_WARNING("%s(), not ready yet!\n", __func__); + net_warn_ratelimited("%s(), not ready yet!\n", __func__); return -1; } if (!dev->irlap) { - IRDA_WARNING("%s - too early: %p / %zd!\n", - __func__, cp, count); + net_warn_ratelimited("%s - too early: %p / %zd!\n", + __func__, cp, count); return -1; } @@ -661,8 +662,8 @@ static netdev_tx_t sirdev_hard_xmit(struct sk_buff *skb, } else if (unlikely(actual < 0)) { /* could be dropped later when we have tx_timeout to recover */ - IRDA_ERROR("%s: drv->do_write failed (%d)\n", - __func__, actual); + net_err_ratelimited("%s: drv->do_write failed (%d)\n", + __func__, actual); dev_kfree_skb_any(skb); dev->netdev->stats.tx_errors++; dev->netdev->stats.tx_dropped++; @@ -894,7 +895,8 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n */ ndev = alloc_irdadev(sizeof(*dev)); if (ndev == NULL) { - IRDA_ERROR("%s - Can't allocate memory for IrDA control block!\n", __func__); + net_err_ratelimited("%s - Can't allocate memory for IrDA control block!\n", + __func__); goto out; } dev = netdev_priv(ndev); @@ -919,7 +921,8 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n ndev->netdev_ops = &sirdev_ops; if (register_netdev(ndev)) { - IRDA_ERROR("%s(), register_netdev() failed!\n", __func__); + net_err_ratelimited("%s(), register_netdev() failed!\n", + __func__); goto out_freenetdev; } @@ -946,7 +949,7 @@ int sirdev_put_instance(struct sir_dev *dev) if (dev->dongle_drv) err = sirdev_schedule_dongle_close(dev); if (err) - IRDA_ERROR("%s - error %d\n", __func__, err); + net_err_ratelimited("%s - error %d\n", __func__, err); sirdev_close(dev->netdev); diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 282120430f12..a7f0f5214ad7 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -419,13 +419,16 @@ static int __init smsc_ircc_legacy_probe(void) #ifdef CONFIG_PCI if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { /* Ignore errors from preconfiguration */ - IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); + net_err_ratelimited("%s, Preconfiguration failed !\n", + driver_name); } #endif if (ircc_fir > 0 && ircc_sir > 0) { - IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); - IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); + net_info_ratelimited(" Overriding FIR address 0x%04x\n", + ircc_fir); + net_info_ratelimited(" Overriding SIR address 0x%04x\n", + ircc_sir); if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) ret = -ENODEV; @@ -434,8 +437,8 @@ static int __init smsc_ircc_legacy_probe(void) /* try user provided configuration register base address */ if (ircc_cfg > 0) { - IRDA_MESSAGE(" Overriding configuration address " - "0x%04x\n", ircc_cfg); + net_info_ratelimited(" Overriding configuration address 0x%04x\n", + ircc_cfg); if (!smsc_superio_fdc(ircc_cfg)) ret = 0; if (!smsc_superio_lpc(ircc_cfg)) @@ -462,7 +465,8 @@ static int __init smsc_ircc_init(void) ret = platform_driver_register(&smsc_ircc_driver); if (ret) { - IRDA_ERROR("%s, Can't register driver!\n", driver_name); + net_err_ratelimited("%s, Can't register driver!\n", + driver_name); return ret; } @@ -527,7 +531,7 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, err = -ENOMEM; if (dev_count >= ARRAY_SIZE(dev_self)) { - IRDA_WARNING("%s(), too many devices!\n", __func__); + net_warn_ratelimited("%s(), too many devices!\n", __func__); goto err_out1; } @@ -536,7 +540,8 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, */ dev = alloc_irdadev(sizeof(struct smsc_ircc_cb)); if (!dev) { - IRDA_WARNING("%s() can't allocate net device\n", __func__); + net_warn_ratelimited("%s() can't allocate net device\n", + __func__); goto err_out1; } @@ -588,8 +593,8 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, err = register_netdev(self->netdev); if (err) { - IRDA_ERROR("%s, Network device registration failed!\n", - driver_name); + net_err_ratelimited("%s, Network device registration failed!\n", + driver_name); goto err_out4; } @@ -601,7 +606,7 @@ static int smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, } platform_set_drvdata(self->pldev, self); - IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); + net_info_ratelimited("IrDA: Registered device %s\n", dev->name); dev_count++; return 0; @@ -637,15 +642,15 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) if (!request_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT, driver_name)) { - IRDA_WARNING("%s: can't get fir_base of 0x%03x\n", - __func__, fir_base); + net_warn_ratelimited("%s: can't get fir_base of 0x%03x\n", + __func__, fir_base); goto out1; } if (!request_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT, driver_name)) { - IRDA_WARNING("%s: can't get sir_base of 0x%03x\n", - __func__, sir_base); + net_warn_ratelimited("%s: can't get sir_base of 0x%03x\n", + __func__, sir_base); goto out2; } @@ -660,13 +665,13 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) irq = (config & IRCC_INTERFACE_IRQ_MASK) >> 4; if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { - IRDA_WARNING("%s(), addr 0x%04x - no device found!\n", - __func__, fir_base); + net_warn_ratelimited("%s(), addr 0x%04x - no device found!\n", + __func__, fir_base); goto out3; } - IRDA_MESSAGE("SMsC IrDA Controller found\n IrCC version %d.%d, " - "firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n", - chip & 0x0f, version, fir_base, sir_base, dma, irq); + net_info_ratelimited("SMsC IrDA Controller found\n IrCC version %d.%d, firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n", + chip & 0x0f, version, + fir_base, sir_base, dma, irq); return 0; @@ -704,16 +709,16 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, if (irq != IRQ_INVAL) { if (irq != chip_irq) - IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", - driver_name, chip_irq, irq); + net_info_ratelimited("%s, Overriding IRQ - chip says %d, using %d\n", + driver_name, chip_irq, irq); self->io.irq = irq; } else self->io.irq = chip_irq; if (dma != DMA_INVAL) { if (dma != chip_dma) - IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", - driver_name, chip_dma, dma); + net_info_ratelimited("%s, Overriding DMA - chip says %d, using %d\n", + driver_name, chip_dma, dma); self->io.dma = dma; } else self->io.dma = chip_dma; @@ -852,8 +857,8 @@ static void smsc_ircc_timeout(struct net_device *dev) struct smsc_ircc_cb *self = netdev_priv(dev); unsigned long flags; - IRDA_WARNING("%s: transmit timed out, changing speed to: %d\n", - dev->name, self->io.speed); + net_warn_ratelimited("%s: transmit timed out, changing speed to: %d\n", + dev->name, self->io.speed); spin_lock_irqsave(&self->lock, flags); smsc_ircc_sir_start(self); smsc_ircc_change_speed(self, self->io.speed); @@ -1442,17 +1447,15 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) len -= self->io.speed < 4000000 ? 2 : 4; if (len < 2 || len > 2050) { - IRDA_WARNING("%s(), bogus len=%d\n", __func__, len); + net_warn_ratelimited("%s(), bogus len=%d\n", __func__, len); return; } IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __func__, msgcnt, len); skb = dev_alloc_skb(len + 1); - if (!skb) { - IRDA_WARNING("%s(), memory squeeze, dropping frame.\n", - __func__); + if (!skb) return; - } + /* Make sure IP header gets aligned */ skb_reserve(skb, 1); @@ -1730,8 +1733,8 @@ static int smsc_ircc_net_open(struct net_device *dev) if (request_dma(self->io.dma, dev->name)) { smsc_ircc_net_close(dev); - IRDA_WARNING("%s(), unable to allocate DMA=%d\n", - __func__, self->io.dma); + net_warn_ratelimited("%s(), unable to allocate DMA=%d\n", + __func__, self->io.dma); return -EAGAIN; } @@ -2019,7 +2022,8 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) /* Tx FIFO should be empty! */ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE)) { - IRDA_WARNING("%s(), failed, fifo not empty!\n", __func__); + net_warn_ratelimited("%s(), failed, fifo not empty!\n", + __func__); return 0; } @@ -2058,14 +2062,14 @@ static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self) for (i = 0; smsc_transceivers[i].name != NULL; i++) if (smsc_transceivers[i].probe(self->io.fir_base)) { - IRDA_MESSAGE(" %s transceiver found\n", - smsc_transceivers[i].name); + net_info_ratelimited(" %s transceiver found\n", + smsc_transceivers[i].name); self->transceiver= i + 1; return; } - IRDA_MESSAGE("No transceiver found. Defaulting to %s\n", - smsc_transceivers[SMSC_IRCC2_C_DEFAULT_TRANSCEIVER].name); + net_info_ratelimited("No transceiver found. Defaulting to %s\n", + smsc_transceivers[SMSC_IRCC2_C_DEFAULT_TRANSCEIVER].name); self->transceiver = SMSC_IRCC2_C_DEFAULT_TRANSCEIVER; } @@ -2191,7 +2195,7 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor /*printk(KERN_WARNING "%s(): mode: 0x%02x\n", __func__, mode);*/ if (!(mode & SMSCSIOFLAT_UART2MODE_VAL_IRDA)) - IRDA_WARNING("%s(): IrDA not enabled\n", __func__); + net_warn_ratelimited("%s(): IrDA not enabled\n", __func__); outb(SMSCSIOFLAT_UART2BASEADDR_REG, cfgbase); sirbase = inb(cfgbase + 1) << 2; @@ -2208,7 +2212,8 @@ static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned shor outb(SMSCSIOFLAT_UARTIRQSELECT_REG, cfgbase); irq = inb(cfgbase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; - IRDA_MESSAGE("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", __func__, firbase, sirbase, dma, irq, mode); + net_info_ratelimited("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", + __func__, firbase, sirbase, dma, irq, mode); if (firbase && smsc_ircc_open(firbase, sirbase, dma, irq) == 0) ret = 0; @@ -2329,16 +2334,16 @@ static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, return NULL; } - IRDA_MESSAGE("found SMC SuperIO Chip (devid=0x%02x rev=%02X base=0x%04x): %s%s\n", - devid, rev, cfg_base, type, chip->name); + net_info_ratelimited("found SMC SuperIO Chip (devid=0x%02x rev=%02X base=0x%04x): %s%s\n", + devid, rev, cfg_base, type, chip->name); if (chip->rev > rev) { - IRDA_MESSAGE("Revision higher than expected\n"); + net_info_ratelimited("Revision higher than expected\n"); return NULL; } if (chip->flags & NoIRDA) - IRDA_MESSAGE("chipset does not support IRDA\n"); + net_info_ratelimited("chipset does not support IRDA\n"); return chip; } @@ -2348,8 +2353,8 @@ static int __init smsc_superio_fdc(unsigned short cfg_base) int ret = -1; if (!request_region(cfg_base, 2, driver_name)) { - IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", - __func__, cfg_base); + net_warn_ratelimited("%s: can't get cfg_base of 0x%03x\n", + __func__, cfg_base); } else { if (!smsc_superio_flat(fdc_chips_flat, cfg_base, "FDC") || !smsc_superio_paged(fdc_chips_paged, cfg_base, "FDC")) @@ -2366,8 +2371,8 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) int ret = -1; if (!request_region(cfg_base, 2, driver_name)) { - IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", - __func__, cfg_base); + net_warn_ratelimited("%s: can't get cfg_base of 0x%03x\n", + __func__, cfg_base); } else { if (!smsc_superio_flat(lpc_chips_flat, cfg_base, "LPC") || !smsc_superio_paged(lpc_chips_paged, cfg_base, "LPC")) @@ -2540,8 +2545,8 @@ static int __init preconfigure_smsc_chip(struct outb( (conf->sir_io >> 2), iobase + 1); // bits 2-9 of 0x3f8 tmpbyte = inb(iobase + 1); if (tmpbyte != (conf->sir_io >> 2) ) { - IRDA_WARNING("ERROR: could not configure SIR ioport.\n"); - IRDA_WARNING("Try to supply ircc_cfg argument.\n"); + net_warn_ratelimited("ERROR: could not configure SIR ioport\n"); + net_warn_ratelimited("Try to supply ircc_cfg argument\n"); return -ENXIO; } @@ -2553,7 +2558,7 @@ static int __init preconfigure_smsc_chip(struct outb(tmpbyte, iobase + 1); tmpbyte = inb(iobase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; if (tmpbyte != conf->fir_irq) { - IRDA_WARNING("ERROR: could not configure FIR IRQ channel.\n"); + net_warn_ratelimited("ERROR: could not configure FIR IRQ channel\n"); return -ENXIO; } @@ -2562,7 +2567,7 @@ static int __init preconfigure_smsc_chip(struct outb((conf->fir_io >> 3), iobase + 1); tmpbyte = inb(iobase + 1); if (tmpbyte != (conf->fir_io >> 3) ) { - IRDA_WARNING("ERROR: could not configure FIR I/O port.\n"); + net_warn_ratelimited("ERROR: could not configure FIR I/O port\n"); return -ENXIO; } @@ -2571,7 +2576,7 @@ static int __init preconfigure_smsc_chip(struct outb((conf->fir_dma & LPC47N227_FIRDMASELECT_MASK), iobase + 1); // DMA tmpbyte = inb(iobase + 1) & LPC47N227_FIRDMASELECT_MASK; if (tmpbyte != (conf->fir_dma & LPC47N227_FIRDMASELECT_MASK)) { - IRDA_WARNING("ERROR: could not configure FIR DMA channel.\n"); + net_warn_ratelimited("ERROR: could not configure FIR DMA channel\n"); return -ENXIO; } @@ -2628,7 +2633,7 @@ static int __init preconfigure_through_82801(struct pci_dev *dev, unsigned short tmpword; unsigned char tmpbyte; - IRDA_MESSAGE("Setting up Intel 82801 controller and SMSC device\n"); + net_info_ratelimited("Setting up Intel 82801 controller and SMSC device\n"); /* * Select the range for the COMA COM port (SIR) * Register COM_DEC: @@ -2699,8 +2704,8 @@ static int __init preconfigure_through_82801(struct pci_dev *dev, tmpword |= 0x0400; break; default: - IRDA_WARNING("Uncommon I/O base address: 0x%04x\n", - conf->cfg_base); + net_warn_ratelimited("Uncommon I/O base address: 0x%04x\n", + conf->cfg_base); break; } tmpword &= 0xfffd; /* disable LPC COMB */ @@ -2800,7 +2805,8 @@ static void __init preconfigure_ali_port(struct pci_dev *dev, mask = 0x08; break; default: - IRDA_ERROR("Failed to configure unsupported port on ALi 1533 bridge: 0x%04x\n", port); + net_err_ratelimited("Failed to configure unsupported port on ALi 1533 bridge: 0x%04x\n", + port); return; } @@ -2808,7 +2814,8 @@ static void __init preconfigure_ali_port(struct pci_dev *dev, /* Turn on the right bits */ tmpbyte |= mask; pci_write_config_byte(dev, reg, tmpbyte); - IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); + net_info_ratelimited("Activated ALi 1533 ISA bridge port 0x%04x\n", + port); } static int __init preconfigure_through_ali(struct pci_dev *dev, @@ -2877,7 +2884,8 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, if (ircc_irq != IRQ_INVAL) tmpconf.fir_irq = ircc_irq; - IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); + net_info_ratelimited("Detected unconfigured %s SMSC IrDA chip, pre-configuring device\n", + conf->name); if (conf->preconfigure) ret = conf->preconfigure(dev, &tmpconf); else @@ -2922,8 +2930,8 @@ static void smsc_ircc_set_transceiver_smsc_ircc_atc(int fir_base, u32 speed) /* empty */; if (val) - IRDA_WARNING("%s(): ATC: 0x%02x\n", __func__, - inb(fir_base + IRCC_ATC)); + net_warn_ratelimited("%s(): ATC: 0x%02x\n", + __func__, inb(fir_base + IRCC_ATC)); } /* diff --git a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c index 048a15422844..04db4eac9dc3 100644 --- a/drivers/net/irda/tekram-sir.c +++ b/drivers/net/irda/tekram-sir.c @@ -179,7 +179,8 @@ static int tekram_change_speed(struct sir_dev *dev, unsigned speed) break; default: - IRDA_ERROR("%s - undefined state %d\n", __func__, state); + net_err_ratelimited("%s - undefined state %d\n", + __func__, state); ret = -EINVAL; break; } diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 36e004288ea7..b07b4ccddcad 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -391,7 +391,8 @@ static int via_ircc_open(struct pci_dev *pdev, chipio_t *info, unsigned int id) if (err) goto err_out4; - IRDA_MESSAGE("IrDA: Registered device %s (via-ircc)\n", dev->name); + net_info_ratelimited("IrDA: Registered device %s (via-ircc)\n", + dev->name); /* Initialise the hardware.. */ @@ -510,7 +511,7 @@ static void via_hw_init(struct via_ircc_cb *self) */ static int via_ircc_read_dongle_id(int iobase) { - IRDA_ERROR("via-ircc: dongle probing not supported, please specify dongle_id module parameter.\n"); + net_err_ratelimited("via-ircc: dongle probing not supported, please specify dongle_id module parameter\n"); return 9; /* Default to IBM */ } @@ -652,8 +653,8 @@ static void via_ircc_change_dongle_speed(int iobase, int speed, break; default: - IRDA_ERROR("%s: Error: dongle_id %d unsupported !\n", - __func__, dongle_id); + net_err_ratelimited("%s: Error: dongle_id %d unsupported !\n", + __func__, dongle_id); } } @@ -1473,8 +1474,8 @@ static int via_ircc_net_open(struct net_device *dev) IRDA_ASSERT(self != NULL, return 0;); iobase = self->io.fir_base; if (request_irq(self->io.irq, via_ircc_interrupt, 0, dev->name, dev)) { - IRDA_WARNING("%s, unable to allocate irq=%d\n", driver_name, - self->io.irq); + net_warn_ratelimited("%s, unable to allocate irq=%d\n", + driver_name, self->io.irq); return -EAGAIN; } /* @@ -1482,15 +1483,15 @@ static int via_ircc_net_open(struct net_device *dev) * failure. */ if (request_dma(self->io.dma, dev->name)) { - IRDA_WARNING("%s, unable to allocate dma=%d\n", driver_name, - self->io.dma); + net_warn_ratelimited("%s, unable to allocate dma=%d\n", + driver_name, self->io.dma); free_irq(self->io.irq, dev); return -EAGAIN; } if (self->io.dma2 != self->io.dma) { if (request_dma(self->io.dma2, dev->name)) { - IRDA_WARNING("%s, unable to allocate dma2=%d\n", - driver_name, self->io.dma2); + net_warn_ratelimited("%s, unable to allocate dma2=%d\n", + driver_name, self->io.dma2); free_irq(self->io.irq, dev); free_dma(self->io.dma); return -EAGAIN; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index a2e556168286..fd4dedea8e08 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -429,8 +429,8 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr if (rd->buf == NULL || !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) { if (rd->buf) { - IRDA_ERROR("%s: failed to create PCI-MAP for %p", - __func__, rd->buf); + net_err_ratelimited("%s: failed to create PCI-MAP for %p\n", + __func__, rd->buf); kfree(rd->buf); rd->buf = NULL; } @@ -483,11 +483,8 @@ static int vlsi_create_hwif(vlsi_irda_dev_t *idev) ringarea = pci_zalloc_consistent(idev->pdev, HW_RING_AREA_SIZE, &idev->busaddr); - if (!ringarea) { - IRDA_ERROR("%s: insufficient memory for descriptor rings\n", - __func__); + if (!ringarea) goto out; - } hwmap = (struct ring_descr_hw *)ringarea; idev->rx_ring = vlsi_alloc_ring(idev->pdev, hwmap, ringsize[1], @@ -581,7 +578,7 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd) } if (!rd->skb) { - IRDA_WARNING("%s: rx packet lost\n", __func__); + net_warn_ratelimited("%s: rx packet lost\n", __func__); ret |= VLSI_RX_DROP; goto done; } @@ -610,8 +607,8 @@ static void vlsi_fill_rx(struct vlsi_ring *r) for (rd = ring_last(r); rd != NULL; rd = ring_put(r)) { if (rd_is_active(rd)) { - IRDA_WARNING("%s: driver bug: rx descr race with hw\n", - __func__); + net_warn_ratelimited("%s: driver bug: rx descr race with hw\n", + __func__); vlsi_ring_debug(r); break; } @@ -670,7 +667,7 @@ static void vlsi_rx_interrupt(struct net_device *ndev) if (ring_first(r) == NULL) { /* we are in big trouble, if this should ever happen */ - IRDA_ERROR("%s: rx ring exhausted!\n", __func__); + net_err_ratelimited("%s: rx ring exhausted!\n", __func__); vlsi_ring_debug(r); } else @@ -783,8 +780,8 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) config = IRCFG_SIR | IRCFG_SIRFILT | IRCFG_RXANY; switch(baudrate) { default: - IRDA_WARNING("%s: undefined baudrate %d - fallback to 9600!\n", - __func__, baudrate); + net_warn_ratelimited("%s: undefined baudrate %d - fallback to 9600!\n", + __func__, baudrate); baudrate = 9600; /* fallthru */ case 2400: @@ -825,14 +822,16 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase) config ^= IRENABLE_SIR_ON; if (config != (IRENABLE_PHYANDCLOCK|IRENABLE_ENRXST)) { - IRDA_WARNING("%s: failed to set %s mode!\n", __func__, - (mode==IFF_SIR)?"SIR":((mode==IFF_MIR)?"MIR":"FIR")); + net_warn_ratelimited("%s: failed to set %s mode!\n", + __func__, + mode == IFF_SIR ? "SIR" : + mode == IFF_MIR ? "MIR" : "FIR"); ret = -1; } else { if (inw(iobase+VLSI_PIO_PHYCTL) != nphyctl) { - IRDA_WARNING("%s: failed to apply baudrate %d\n", - __func__, baudrate); + net_warn_ratelimited("%s: failed to apply baudrate %d\n", + __func__, baudrate); ret = -1; } else { @@ -977,8 +976,8 @@ static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb, */ if (len >= r->len-5) - IRDA_WARNING("%s: possible buffer overflow with SIR wrapping!\n", - __func__); + net_warn_ratelimited("%s: possible buffer overflow with SIR wrapping!\n", + __func__); } else { /* hw deals with MIR/FIR mode wrapping */ @@ -1044,7 +1043,7 @@ static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb, drop_unlock: spin_unlock_irqrestore(&idev->lock, flags); drop: - IRDA_WARNING("%s: dropping packet - %s\n", __func__, msg); + net_warn_ratelimited("%s: dropping packet - %s\n", __func__, msg); dev_kfree_skb_any(skb); ndev->stats.tx_errors++; ndev->stats.tx_dropped++; @@ -1183,8 +1182,8 @@ static int vlsi_start_clock(struct pci_dev *pdev) } if (count < 3) { if (clksrc == 1) { /* explicitly asked for PLL hence bail out */ - IRDA_ERROR("%s: no PLL or failed to lock!\n", - __func__); + net_err_ratelimited("%s: no PLL or failed to lock!\n", + __func__); clkctl = CLKCTL_CLKSTP; pci_write_config_byte(pdev, VLSI_PCI_CLKCTL, clkctl); return -1; @@ -1265,7 +1264,7 @@ static int vlsi_init_chip(struct pci_dev *pdev) /* start the clock and clean the registers */ if (vlsi_start_clock(pdev)) { - IRDA_ERROR("%s: no valid clock source\n", __func__); + net_err_ratelimited("%s: no valid clock source\n", __func__); return -1; } iobase = ndev->base_addr; @@ -1389,8 +1388,8 @@ static void vlsi_tx_timeout(struct net_device *ndev) idev->new_baud = idev->baud; /* keep current baudrate */ if (vlsi_start_hw(idev)) - IRDA_ERROR("%s: failed to restart hw - %s(%s) unusable!\n", - __func__, pci_name(idev->pdev), ndev->name); + net_err_ratelimited("%s: failed to restart hw - %s(%s) unusable!\n", + __func__, pci_name(idev->pdev), ndev->name); else netif_start_queue(ndev); } @@ -1434,8 +1433,8 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) irq->ifr_receiving = (fifocnt!=0) ? 1 : 0; break; default: - IRDA_WARNING("%s: notsupp - cmd=%04x\n", - __func__, cmd); + net_warn_ratelimited("%s: notsupp - cmd=%04x\n", + __func__, cmd); ret = -EOPNOTSUPP; } @@ -1479,8 +1478,8 @@ static irqreturn_t vlsi_interrupt(int irq, void *dev_instance) spin_unlock_irqrestore(&idev->lock,flags); if (boguscount <= 0) - IRDA_MESSAGE("%s: too much work in interrupt!\n", - __func__); + net_info_ratelimited("%s: too much work in interrupt!\n", + __func__); return IRQ_RETVAL(handled); } @@ -1493,7 +1492,7 @@ static int vlsi_open(struct net_device *ndev) char hwname[32]; if (pci_request_regions(idev->pdev, drivername)) { - IRDA_WARNING("%s: io resource busy\n", __func__); + net_warn_ratelimited("%s: io resource busy\n", __func__); goto errout; } ndev->base_addr = pci_resource_start(idev->pdev,0); @@ -1507,8 +1506,8 @@ static int vlsi_open(struct net_device *ndev) if (request_irq(ndev->irq, vlsi_interrupt, IRQF_SHARED, drivername, ndev)) { - IRDA_WARNING("%s: couldn't get IRQ: %d\n", - __func__, ndev->irq); + net_warn_ratelimited("%s: couldn't get IRQ: %d\n", + __func__, ndev->irq); goto errout_io; } @@ -1529,7 +1528,8 @@ static int vlsi_open(struct net_device *ndev) netif_start_queue(ndev); - IRDA_MESSAGE("%s: device %s operational\n", __func__, ndev->name); + net_info_ratelimited("%s: device %s operational\n", + __func__, ndev->name); return 0; @@ -1563,7 +1563,7 @@ static int vlsi_close(struct net_device *ndev) pci_release_regions(idev->pdev); - IRDA_MESSAGE("%s: device %s stopped\n", __func__, ndev->name); + net_info_ratelimited("%s: device %s stopped\n", __func__, ndev->name); return 0; } @@ -1590,7 +1590,8 @@ static int vlsi_irda_init(struct net_device *ndev) if (pci_set_dma_mask(pdev,DMA_MASK_USED_BY_HW) || pci_set_dma_mask(pdev,DMA_MASK_MSTRPAGE)) { - IRDA_ERROR("%s: aborting due to PCI BM-DMA address limitations\n", __func__); + net_err_ratelimited("%s: aborting due to PCI BM-DMA address limitations\n", + __func__); return -1; } @@ -1632,19 +1633,19 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) else pdev->current_state = 0; /* hw must be running now */ - IRDA_MESSAGE("%s: IrDA PCI controller %s detected\n", - drivername, pci_name(pdev)); + net_info_ratelimited("%s: IrDA PCI controller %s detected\n", + drivername, pci_name(pdev)); if ( !pci_resource_start(pdev,0) || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { - IRDA_ERROR("%s: bar 0 invalid", __func__); + net_err_ratelimited("%s: bar 0 invalid", __func__); goto out_disable; } ndev = alloc_irdadev(sizeof(*idev)); if (ndev==NULL) { - IRDA_ERROR("%s: Unable to allocate device memory.\n", - __func__); + net_err_ratelimited("%s: Unable to allocate device memory.\n", + __func__); goto out_disable; } @@ -1659,7 +1660,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_freedev; if (register_netdev(ndev) < 0) { - IRDA_ERROR("%s: register_netdev failed\n", __func__); + net_err_ratelimited("%s: register_netdev failed\n", __func__); goto out_freedev; } @@ -1669,14 +1670,15 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) ent = proc_create_data(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root, VLSI_PROC_FOPS, ndev); if (!ent) { - IRDA_WARNING("%s: failed to create proc entry\n", - __func__); + net_warn_ratelimited("%s: failed to create proc entry\n", + __func__); } else { proc_set_size(ent, 0); } idev->proc_entry = ent; } - IRDA_MESSAGE("%s: registered device %s\n", drivername, ndev->name); + net_info_ratelimited("%s: registered device %s\n", + drivername, ndev->name); pci_set_drvdata(pdev, ndev); mutex_unlock(&idev->mtx); @@ -1698,7 +1700,7 @@ static void vlsi_irda_remove(struct pci_dev *pdev) vlsi_irda_dev_t *idev; if (!ndev) { - IRDA_ERROR("%s: lost netdevice?\n", drivername); + net_err_ratelimited("%s: lost netdevice?\n", drivername); return; } @@ -1714,7 +1716,7 @@ static void vlsi_irda_remove(struct pci_dev *pdev) free_netdev(ndev); - IRDA_MESSAGE("%s: %s removed\n", drivername, pci_name(pdev)); + net_info_ratelimited("%s: %s removed\n", drivername, pci_name(pdev)); } #ifdef CONFIG_PM @@ -1733,8 +1735,8 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) vlsi_irda_dev_t *idev; if (!ndev) { - IRDA_ERROR("%s - %s: no netdevice\n", - __func__, pci_name(pdev)); + net_err_ratelimited("%s - %s: no netdevice\n", + __func__, pci_name(pdev)); return 0; } idev = netdev_priv(ndev); @@ -1745,7 +1747,9 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) pdev->current_state = state.event; } else - IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __func__, pci_name(pdev), pdev->current_state, state.event); + net_err_ratelimited("%s - %s: invalid suspend request %u -> %u\n", + __func__, pci_name(pdev), + pdev->current_state, state.event); mutex_unlock(&idev->mtx); return 0; } @@ -1772,16 +1776,16 @@ static int vlsi_irda_resume(struct pci_dev *pdev) vlsi_irda_dev_t *idev; if (!ndev) { - IRDA_ERROR("%s - %s: no netdevice\n", - __func__, pci_name(pdev)); + net_err_ratelimited("%s - %s: no netdevice\n", + __func__, pci_name(pdev)); return 0; } idev = netdev_priv(ndev); mutex_lock(&idev->mtx); if (pdev->current_state == 0) { mutex_unlock(&idev->mtx); - IRDA_WARNING("%s - %s: already resumed\n", - __func__, pci_name(pdev)); + net_warn_ratelimited("%s - %s: already resumed\n", + __func__, pci_name(pdev)); return 0; } @@ -1800,7 +1804,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) * now we explicitly set pdev->current_state = 0 after enabling the * device and independently resume_ok should catch any garbage config. */ - IRDA_WARNING("%s - hm, nothing to resume?\n", __func__); + net_warn_ratelimited("%s - hm, nothing to resume?\n", __func__); mutex_unlock(&idev->mtx); return 0; } @@ -1837,7 +1841,8 @@ static int __init vlsi_mod_init(void) int i, ret; if (clksrc < 0 || clksrc > 3) { - IRDA_ERROR("%s: invalid clksrc=%d\n", drivername, clksrc); + net_err_ratelimited("%s: invalid clksrc=%d\n", + drivername, clksrc); return -1; } @@ -1850,7 +1855,10 @@ static int __init vlsi_mod_init(void) case 64: break; default: - IRDA_WARNING("%s: invalid %s ringsize %d, using default=8", drivername, (i)?"rx":"tx", ringsize[i]); + net_warn_ratelimited("%s: invalid %s ringsize %d, using default=8\n", + drivername, + i ? "rx" : "tx", + ringsize[i]); ringsize[i] = 8; break; } diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index 56399204e68c..f9119c6d2a09 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -615,7 +615,8 @@ static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s) */ if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { - IRDA_ERROR("%s: pci busaddr inconsistency!\n", __func__); + net_err_ratelimited("%s: pci busaddr inconsistency!\n", + __func__); dump_stack(); return; } diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 11dbdf36d9c1..86ca123887d6 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -236,10 +236,11 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, err = register_netdev(dev); if (err) { - IRDA_ERROR("%s(), register_netdevice() failed!\n", __func__); + net_err_ratelimited("%s(), register_netdevice() failed!\n", + __func__); goto err_out3; } - IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); + net_info_ratelimited("IrDA: Registered device %s\n", dev->name); /* Need to store self somewhere */ dev_self[i] = self; @@ -392,8 +393,8 @@ static int w83977af_probe(int iobase, int irq, int dma) switch_bank(iobase, SET7); outb(0x40, iobase+7); - IRDA_MESSAGE("W83977AF (IR) driver loaded. " - "Version: 0x%02x\n", version); + net_info_ratelimited("W83977AF (IR) driver loaded. Version: 0x%02x\n", + version); return 0; } else { diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 42aa054aa67f..4ff18bdc63df 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -77,10 +77,6 @@ do { if(!(expr)) { \ #define IRDA_ASSERT_LABEL(label) #endif /* CONFIG_IRDA_DEBUG */ -#define IRDA_ERROR net_err_ratelimited -#define IRDA_WARNING net_warn_ratelimited -#define IRDA_MESSAGE net_info_ratelimited - /* * Magic numbers used by Linux-IrDA. Random numbers which must be unique to * give the best protection diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 980bc2670a13..4b04ae06b288 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -201,16 +201,16 @@ static void irda_connect_confirm(void *instance, void *sap, switch (sk->sk_type) { case SOCK_STREAM: if (max_sdu_size != 0) { - IRDA_ERROR("%s: max_sdu_size must be 0\n", - __func__); + net_err_ratelimited("%s: max_sdu_size must be 0\n", + __func__); return; } self->max_data_size = irttp_get_max_seg_size(self->tsap); break; case SOCK_SEQPACKET: if (max_sdu_size == 0) { - IRDA_ERROR("%s: max_sdu_size cannot be 0\n", - __func__); + net_err_ratelimited("%s: max_sdu_size cannot be 0\n", + __func__); return; } self->max_data_size = max_sdu_size; @@ -262,8 +262,8 @@ static void irda_connect_indication(void *instance, void *sap, switch (sk->sk_type) { case SOCK_STREAM: if (max_sdu_size != 0) { - IRDA_ERROR("%s: max_sdu_size must be 0\n", - __func__); + net_err_ratelimited("%s: max_sdu_size must be 0\n", + __func__); kfree_skb(skb); return; } @@ -271,8 +271,8 @@ static void irda_connect_indication(void *instance, void *sap, break; case SOCK_SEQPACKET: if (max_sdu_size == 0) { - IRDA_ERROR("%s: max_sdu_size cannot be 0\n", - __func__); + net_err_ratelimited("%s: max_sdu_size cannot be 0\n", + __func__); kfree_skb(skb); return; } @@ -368,7 +368,7 @@ static void irda_getvalue_confirm(int result, __u16 obj_id, self = priv; if (!self) { - IRDA_WARNING("%s: lost myself!\n", __func__); + net_warn_ratelimited("%s: lost myself!\n", __func__); return; } @@ -417,7 +417,7 @@ static void irda_selective_discovery_indication(discinfo_t *discovery, self = priv; if (!self) { - IRDA_WARNING("%s: lost myself!\n", __func__); + net_warn_ratelimited("%s: lost myself!\n", __func__); return; } @@ -505,7 +505,7 @@ static int irda_open_lsap(struct irda_sock *self, int pid) notify_t notify; if (self->lsap) { - IRDA_WARNING("%s(), busy!\n", __func__); + net_warn_ratelimited("%s(), busy!\n", __func__); return -EBUSY; } @@ -541,8 +541,8 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name) IRDA_DEBUG(2, "%s(%p, %s)\n", __func__, self, name); if (self->iriap) { - IRDA_WARNING("%s(): busy with a previous query\n", - __func__); + net_warn_ratelimited("%s(): busy with a previous query\n", + __func__); return -EBUSY; } @@ -2129,8 +2129,8 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, __func__, opt); self->max_sdu_size_rx = opt; } else { - IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n", - __func__); + net_warn_ratelimited("%s: not allowed to set MAXSDUSIZE for this socket type!\n", + __func__); err = -ENOPROTOOPT; goto out; } @@ -2441,8 +2441,8 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, /* Check that we can proceed with IAP */ if (self->iriap) { - IRDA_WARNING("%s: busy with a previous query\n", - __func__); + net_warn_ratelimited("%s: busy with a previous query\n", + __func__); kfree(ias_opt); err = -EBUSY; goto out; diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index 4490a675b1bb..b77fe8c86238 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -69,7 +69,8 @@ static int __init ircomm_init(void) { ircomm = hashbin_new(HB_LOCK); if (ircomm == NULL) { - IRDA_ERROR("%s(), can't allocate hashbin!\n", __func__); + net_err_ratelimited("%s(), can't allocate hashbin!\n", + __func__); return -ENOMEM; } @@ -83,7 +84,7 @@ static int __init ircomm_init(void) } #endif /* CONFIG_PROC_FS */ - IRDA_MESSAGE("IrCOMM protocol (Dag Brattli)\n"); + net_info_ratelimited("IrCOMM protocol (Dag Brattli)\n"); return 0; } diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c index 6536114adf37..05767e3ef0d2 100644 --- a/net/irda/ircomm/ircomm_lmp.c +++ b/net/irda/ircomm/ircomm_lmp.c @@ -204,7 +204,7 @@ static int ircomm_lmp_data_request(struct ircomm_cb *self, } ret = irlmp_data_request(self->lsap, skb); if (ret) { - IRDA_ERROR("%s(), failed\n", __func__); + net_err_ratelimited("%s(), failed\n", __func__); /* irlmp_data_request already free the packet */ } diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index f80b1a6a244b..c203fbb8cdd5 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -130,7 +130,8 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) count = irda_param_insert(self, pi, skb_tail_pointer(skb), skb_tailroom(skb), &ircomm_param_info); if (count < 0) { - IRDA_WARNING("%s(), no room for parameter!\n", __func__); + net_warn_ratelimited("%s(), no room for parameter!\n", + __func__); spin_unlock_irqrestore(&self->spinlock, flags); return -1; } diff --git a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c index d362d711b79c..abe9a5ab8d34 100644 --- a/net/irda/ircomm/ircomm_ttp.c +++ b/net/irda/ircomm/ircomm_ttp.c @@ -188,7 +188,7 @@ static int ircomm_ttp_data_request(struct ircomm_cb *self, ret = irttp_data_request(self->tsap, skb); if (ret) { - IRDA_ERROR("%s(), failed\n", __func__); + net_err_ratelimited("%s(), failed\n", __func__); /* irttp_data_request already free the packet */ } @@ -237,8 +237,8 @@ static void ircomm_ttp_connect_confirm(void *instance, void *sap, IRDA_ASSERT(qos != NULL, goto out;); if (max_sdu_size != TTP_SAR_DISABLE) { - IRDA_ERROR("%s(), SAR not allowed for IrCOMM!\n", - __func__); + net_err_ratelimited("%s(), SAR not allowed for IrCOMM!\n", + __func__); goto out; } @@ -278,8 +278,8 @@ static void ircomm_ttp_connect_indication(void *instance, void *sap, IRDA_ASSERT(qos != NULL, goto out;); if (max_sdu_size != TTP_SAR_DISABLE) { - IRDA_ERROR("%s(), SAR not allowed for IrCOMM!\n", - __func__); + net_err_ratelimited("%s(), SAR not allowed for IrCOMM!\n", + __func__); goto out; } diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 61ceb4cdb4a2..11b0a5ed0252 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -147,7 +147,8 @@ static int __init ircomm_tty_init(void) return -ENOMEM; ircomm_tty = hashbin_new(HB_LOCK); if (ircomm_tty == NULL) { - IRDA_ERROR("%s(), can't allocate hashbin!\n", __func__); + net_err_ratelimited("%s(), can't allocate hashbin!\n", + __func__); put_tty_driver(driver); return -ENOMEM; } @@ -163,8 +164,8 @@ static int __init ircomm_tty_init(void) driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &ops); if (tty_register_driver(driver)) { - IRDA_ERROR("%s(): Couldn't register serial driver\n", - __func__); + net_err_ratelimited("%s(): Couldn't register serial driver\n", + __func__); put_tty_driver(driver); return -1; } @@ -199,8 +200,8 @@ static void __exit ircomm_tty_cleanup(void) ret = tty_unregister_driver(driver); if (ret) { - IRDA_ERROR("%s(), failed to unregister driver\n", - __func__); + net_err_ratelimited("%s(), failed to unregister driver\n", + __func__); return; } @@ -256,7 +257,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) /* Connect IrCOMM link with remote device */ ret = ircomm_tty_attach_cable(self); if (ret < 0) { - IRDA_ERROR("%s(), error attaching cable!\n", __func__); + net_err_ratelimited("%s(), error attaching cable!\n", __func__); goto err; } @@ -389,10 +390,8 @@ static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) if (!self) { /* No, so make new instance */ self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); - if (self == NULL) { - IRDA_ERROR("%s(), kmalloc failed!\n", __func__); + if (self == NULL) return -ENOMEM; - } tty_port_init(&self->port); self->port.ops = &ircomm_port_ops; @@ -469,8 +468,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) if (wait_event_interruptible(self->port.close_wait, !test_bit(ASYNCB_CLOSING, &self->port.flags))) { - IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", - __func__); + net_warn_ratelimited("%s - got signal while blocking on ASYNC_CLOSING!\n", + __func__); return -ERESTARTSYS; } diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index 2ee87bf387cc..211904419f68 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c @@ -694,8 +694,8 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, self->saddr = info->saddr; if (self->iriap) { - IRDA_WARNING("%s(), busy with a previous query\n", - __func__); + net_warn_ratelimited("%s(), busy with a previous query\n", + __func__); return -EBUSY; } @@ -752,8 +752,8 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self, self->saddr = info->saddr; if (self->iriap) { - IRDA_WARNING("%s(), busy with a previous query\n", - __func__); + net_warn_ratelimited("%s(), busy with a previous query\n", + __func__); return -EBUSY; } @@ -822,8 +822,8 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self, switch (event) { case IRCOMM_TTY_GOT_PARAMETERS: if (self->iriap) { - IRDA_WARNING("%s(), busy with a previous query\n", - __func__); + net_warn_ratelimited("%s(), busy with a previous query\n", + __func__); return -EBUSY; } diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index ce943853c38d..7eb06e08f8ed 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -93,7 +93,8 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self, self->settings.flow_control |= IRCOMM_RTS_CTS_IN; /* This got me. Bummer. Jean II */ if (self->service_type == IRCOMM_3_WIRE_RAW) - IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__); + net_warn_ratelimited("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", + __func__); } else { self->port.flags &= ~ASYNC_CTS_FLOW; self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index 9e0d909390fd..96788db1dc31 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -63,14 +63,14 @@ int __init irda_device_init( void) { dongles = hashbin_new(HB_NOLOCK); if (dongles == NULL) { - IRDA_WARNING("IrDA: Can't allocate dongles hashbin!\n"); + net_warn_ratelimited("IrDA: Can't allocate dongles hashbin!\n"); return -ENOMEM; } spin_lock_init(&dongles->hb_spinlock); tasks = hashbin_new(HB_LOCK); if (tasks == NULL) { - IRDA_WARNING("IrDA: Can't allocate tasks hashbin!\n"); + net_warn_ratelimited("IrDA: Can't allocate tasks hashbin!\n"); hashbin_delete(dongles, NULL); return -ENOMEM; } @@ -84,8 +84,8 @@ int __init irda_device_init( void) static void leftover_dongle(void *arg) { struct dongle_reg *reg = arg; - IRDA_WARNING("IrDA: Dongle type %x not unregistered\n", - reg->type); + net_warn_ratelimited("IrDA: Dongle type %x not unregistered\n", + reg->type); } void irda_device_cleanup(void) @@ -150,8 +150,8 @@ int irda_device_is_receiving(struct net_device *dev) IRDA_DEBUG(2, "%s()\n", __func__); if (!dev->netdev_ops->ndo_do_ioctl) { - IRDA_ERROR("%s: do_ioctl not impl. by device driver\n", - __func__); + net_err_ratelimited("%s: do_ioctl not impl. by device driver\n", + __func__); return -1; } @@ -201,15 +201,15 @@ static int irda_task_kick(struct irda_task *task) do { timeout = task->function(task); if (count++ > 100) { - IRDA_ERROR("%s: error in task handler!\n", - __func__); + net_err_ratelimited("%s: error in task handler!\n", + __func__); irda_task_delete(task); return TRUE; } } while ((timeout == 0) && (task->state != IRDA_TASK_DONE)); if (timeout < 0) { - IRDA_ERROR("%s: Error executing task!\n", __func__); + net_err_ratelimited("%s: Error executing task!\n", __func__); irda_task_delete(task); return TRUE; } diff --git a/net/irda/iriap.c b/net/irda/iriap.c index e1b37f5a2691..c2ea3443f669 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -110,8 +110,8 @@ int __init iriap_init(void) /* Object repository - defined in irias_object.c */ irias_objects = hashbin_new(HB_LOCK); if (!irias_objects) { - IRDA_WARNING("%s: Can't allocate irias_objects hashbin!\n", - __func__); + net_warn_ratelimited("%s: Can't allocate irias_objects hashbin!\n", + __func__); hashbin_delete(iriap, NULL); return -ENOMEM; } @@ -180,10 +180,8 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, IRDA_DEBUG(2, "%s()\n", __func__); self = kzalloc(sizeof(*self), GFP_ATOMIC); - if (!self) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + if (!self) return NULL; - } /* * Initialize instance @@ -283,7 +281,8 @@ static int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode) self->lsap = irlmp_open_lsap(slsap_sel, ¬ify, 0); if (self->lsap == NULL) { - IRDA_ERROR("%s: Unable to allocated LSAP!\n", __func__); + net_err_ratelimited("%s: Unable to allocated LSAP!\n", + __func__); return -1; } self->slsap_sel = self->lsap->slsap_sel; @@ -859,9 +858,8 @@ static int iriap_data_indication(void *instance, void *sap, } opcode = frame[0]; if (~opcode & IAP_LST) { - IRDA_WARNING("%s:, IrIAS multiframe commands or " - "results is not implemented yet!\n", - __func__); + net_warn_ratelimited("%s:, IrIAS multiframe commands or results is not implemented yet!\n", + __func__); goto out; } @@ -945,16 +943,16 @@ void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb) opcode = fp[0]; if (~opcode & 0x80) { - IRDA_WARNING("%s: IrIAS multiframe commands or results " - "is not implemented yet!\n", __func__); + net_warn_ratelimited("%s: IrIAS multiframe commands or results is not implemented yet!\n", + __func__); return; } opcode &= 0x7f; /* Mask away LST bit */ switch (opcode) { case GET_INFO_BASE: - IRDA_WARNING("%s: GetInfoBaseDetails not implemented yet!\n", - __func__); + net_warn_ratelimited("%s: GetInfoBaseDetails not implemented yet!\n", + __func__); break; case GET_VALUE_BY_CLASS: iriap_getvaluebyclass_indication(self, skb); diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c index 703774e29e32..09de4efc73a7 100644 --- a/net/irda/iriap_event.c +++ b/net/irda/iriap_event.c @@ -368,10 +368,8 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, switch (event) { case IAP_LM_CONNECT_INDICATION: tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC); - if (tx_skb == NULL) { - IRDA_WARNING("%s: unable to malloc!\n", __func__); + if (tx_skb == NULL) return; - } /* Reserve space for MUX_CONTROL and LAP header */ skb_reserve(tx_skb, LMP_MAX_HEADER); diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c index f07ed9fd5792..cd53692fe8c9 100644 --- a/net/irda/irias_object.c +++ b/net/irda/irias_object.c @@ -52,16 +52,16 @@ struct ias_object *irias_new_object( char *name, int id) obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC); if (obj == NULL) { - IRDA_WARNING("%s(), Unable to allocate object!\n", - __func__); + net_warn_ratelimited("%s(), Unable to allocate object!\n", + __func__); return NULL; } obj->magic = IAS_OBJECT_MAGIC; obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC); if (!obj->name) { - IRDA_WARNING("%s(), Unable to allocate name!\n", - __func__); + net_warn_ratelimited("%s(), Unable to allocate name!\n", + __func__); kfree(obj); return NULL; } @@ -73,8 +73,8 @@ struct ias_object *irias_new_object( char *name, int id) obj->attribs = hashbin_new(HB_LOCK); if (obj->attribs == NULL) { - IRDA_WARNING("%s(), Unable to allocate attribs!\n", - __func__); + net_warn_ratelimited("%s(), Unable to allocate attribs!\n", + __func__); kfree(obj->name); kfree(obj); return NULL; @@ -269,8 +269,8 @@ int irias_object_change_attribute(char *obj_name, char *attrib_name, /* Find object */ obj = hashbin_lock_find(irias_objects, 0, obj_name); if (obj == NULL) { - IRDA_WARNING("%s: Unable to find object: %s\n", __func__, - obj_name); + net_warn_ratelimited("%s: Unable to find object: %s\n", + __func__, obj_name); return -1; } @@ -280,8 +280,8 @@ int irias_object_change_attribute(char *obj_name, char *attrib_name, /* Find attribute */ attrib = hashbin_find(obj->attribs, 0, attrib_name); if (attrib == NULL) { - IRDA_WARNING("%s: Unable to find attribute: %s\n", - __func__, attrib_name); + net_warn_ratelimited("%s: Unable to find attribute: %s\n", + __func__, attrib_name); spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags); return -1; } @@ -322,8 +322,8 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); return; } @@ -333,8 +333,8 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, /* Insert value */ attrib->value = irias_new_integer_value(value); if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); if (attrib->value) irias_delete_value(attrib->value); kfree(attrib->name); @@ -366,8 +366,8 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); return; } @@ -376,8 +376,8 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, attrib->value = irias_new_octseq_value( octets, len); if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); if (attrib->value) irias_delete_value(attrib->value); kfree(attrib->name); @@ -408,8 +408,8 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); return; } @@ -418,8 +418,8 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, attrib->value = irias_new_string_value(value); if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __func__); + net_warn_ratelimited("%s: Unable to allocate attribute!\n", + __func__); if (attrib->value) irias_delete_value(attrib->value); kfree(attrib->name); @@ -442,10 +442,8 @@ struct ias_value *irias_new_integer_value(int integer) struct ias_value *value; value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); - if (value == NULL) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + if (value == NULL) return NULL; - } value->type = IAS_INTEGER; value->len = 4; @@ -467,16 +465,14 @@ struct ias_value *irias_new_string_value(char *string) struct ias_value *value; value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); - if (value == NULL) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + if (value == NULL) return NULL; - } value->type = IAS_STRING; value->charset = CS_ASCII; value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC); if (!value->t.string) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__); kfree(value); return NULL; } @@ -498,10 +494,8 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) struct ias_value *value; value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); - if (value == NULL) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + if (value == NULL) return NULL; - } value->type = IAS_OCT_SEQ; /* Check length */ @@ -511,7 +505,7 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) value->t.oct_seq = kmemdup(octseq, len, GFP_ATOMIC); if (value->t.oct_seq == NULL){ - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__); kfree(value); return NULL; } @@ -523,10 +517,8 @@ struct ias_value *irias_new_missing_value(void) struct ias_value *value; value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); - if (value == NULL) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); + if (value == NULL) return NULL; - } value->type = IAS_MISSING; diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c index 42cf1390ce9c..f8eea02843f5 100644 --- a/net/irda/irlan/irlan_client.c +++ b/net/irda/irlan/irlan_client.c @@ -323,34 +323,34 @@ static void print_ret_code(__u8 code) printk(KERN_INFO "Success\n"); break; case 1: - IRDA_WARNING("IrLAN: Insufficient resources\n"); + net_warn_ratelimited("IrLAN: Insufficient resources\n"); break; case 2: - IRDA_WARNING("IrLAN: Invalid command format\n"); + net_warn_ratelimited("IrLAN: Invalid command format\n"); break; case 3: - IRDA_WARNING("IrLAN: Command not supported\n"); + net_warn_ratelimited("IrLAN: Command not supported\n"); break; case 4: - IRDA_WARNING("IrLAN: Parameter not supported\n"); + net_warn_ratelimited("IrLAN: Parameter not supported\n"); break; case 5: - IRDA_WARNING("IrLAN: Value not supported\n"); + net_warn_ratelimited("IrLAN: Value not supported\n"); break; case 6: - IRDA_WARNING("IrLAN: Not open\n"); + net_warn_ratelimited("IrLAN: Not open\n"); break; case 7: - IRDA_WARNING("IrLAN: Authentication required\n"); + net_warn_ratelimited("IrLAN: Authentication required\n"); break; case 8: - IRDA_WARNING("IrLAN: Invalid password\n"); + net_warn_ratelimited("IrLAN: Invalid password\n"); break; case 9: - IRDA_WARNING("IrLAN: Protocol error\n"); + net_warn_ratelimited("IrLAN: Protocol error\n"); break; case 255: - IRDA_WARNING("IrLAN: Asynchronous status\n"); + net_warn_ratelimited("IrLAN: Asynchronous status\n"); break; } } @@ -380,7 +380,7 @@ void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb) IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); if (!skb) { - IRDA_ERROR("%s(), Got NULL skb!\n", __func__); + net_err_ratelimited("%s(), Got NULL skb!\n", __func__); return; } frame = skb->data; diff --git a/net/irda/irlan/irlan_client_event.c b/net/irda/irlan/irlan_client_event.c index 8d5a8ebc444f..f9d11bf38157 100644 --- a/net/irda/irlan/irlan_client_event.c +++ b/net/irda/irlan/irlan_client_event.c @@ -100,8 +100,8 @@ static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event, switch (event) { case IRLAN_DISCOVERY_INDICATION: if (self->client.iriap) { - IRDA_WARNING("%s(), busy with a previous query\n", - __func__); + net_warn_ratelimited("%s(), busy with a previous query\n", + __func__); return -EBUSY; } diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 5a2d0a695529..cc60b4a282ae 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -437,7 +437,8 @@ static void irlan_disconnect_indication(void *instance, IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __func__ ); break; default: - IRDA_ERROR("%s(), Unknown disconnect reason\n", __func__); + net_err_ratelimited("%s(), Unknown disconnect reason\n", + __func__); break; } diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index dc13f1a45f2f..94b948ef36f9 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -320,7 +320,7 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ - IRDA_WARNING("Promiscuous mode not implemented by IrLAN!\n"); + net_warn_ratelimited("Promiscuous mode not implemented by IrLAN!\n"); } else if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > HW_MAX_ADDRS) { /* Disable promiscuous mode, use normal mode. */ diff --git a/net/irda/irlap.c b/net/irda/irlap.c index a778df55f5d6..2e3bc6ccf4b5 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -85,8 +85,8 @@ int __init irlap_init(void) /* Allocate master array */ irlap = hashbin_new(HB_LOCK); if (irlap == NULL) { - IRDA_ERROR("%s: can't allocate irlap hashbin!\n", - __func__); + net_err_ratelimited("%s: can't allocate irlap hashbin!\n", + __func__); return -ENOMEM; } @@ -491,7 +491,8 @@ void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) reason, NULL); break; default: - IRDA_ERROR("%s: Unknown reason %d\n", __func__, reason); + net_err_ratelimited("%s: Unknown reason %d\n", + __func__, reason); } } @@ -540,8 +541,8 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) self->discovery_log = hashbin_new(HB_NOLOCK); if (self->discovery_log == NULL) { - IRDA_WARNING("%s(), Unable to allocate discovery log!\n", - __func__); + net_warn_ratelimited("%s(), Unable to allocate discovery log!\n", + __func__); return; } @@ -625,10 +626,10 @@ void irlap_status_indication(struct irlap_cb *self, int quality_of_link) { switch (quality_of_link) { case STATUS_NO_ACTIVITY: - IRDA_MESSAGE("IrLAP, no activity on link!\n"); + net_info_ratelimited("IrLAP, no activity on link!\n"); break; case STATUS_NOISY: - IRDA_MESSAGE("IrLAP, noisy link!\n"); + net_info_ratelimited("IrLAP, noisy link!\n"); break; default: break; diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index ccd214f9d196..5f4a84eb35c7 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -572,9 +572,8 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, info->discovery->data.daddr); if (!self->discovery_log) { - IRDA_WARNING("%s: discovery log is gone! " - "maybe the discovery timeout has been set" - " too short?\n", __func__); + net_warn_ratelimited("%s: discovery log is gone! maybe the discovery timeout has been set too short?\n", + __func__); break; } hashbin_insert(self->discovery_log, diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index a37998c6273d..90ef03658a74 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -421,7 +421,7 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, IRDA_ASSERT(self->magic == LAP_MAGIC, return;); if (!pskb_may_pull(skb, sizeof(struct xid_frame))) { - IRDA_ERROR("%s: frame too short!\n", __func__); + net_err_ratelimited("%s: frame too short!\n", __func__); return; } @@ -438,7 +438,7 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, } if ((discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { - IRDA_WARNING("%s: kmalloc failed!\n", __func__); + net_warn_ratelimited("%s: kmalloc failed!\n", __func__); return; } @@ -492,7 +492,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, char *text; if (!pskb_may_pull(skb, sizeof(struct xid_frame))) { - IRDA_ERROR("%s: frame too short!\n", __func__); + net_err_ratelimited("%s: frame too short!\n", __func__); return; } @@ -536,8 +536,8 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, /* Check if things are sane at this point... */ if((discovery_info == NULL) || !pskb_may_pull(skb, 3)) { - IRDA_ERROR("%s: discovery frame too short!\n", - __func__); + net_err_ratelimited("%s: discovery frame too short!\n", + __func__); return; } @@ -545,10 +545,8 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, * We now have some discovery info to deliver! */ discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC); - if (!discovery) { - IRDA_WARNING("%s: unable to malloc!\n", __func__); + if (!discovery) return; - } discovery->data.daddr = info->daddr; discovery->data.saddr = self->saddr; @@ -1170,7 +1168,7 @@ static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, IRDA_ASSERT(info != NULL, return;); if (!pskb_may_pull(skb, 4)) { - IRDA_ERROR("%s: frame too short!\n", __func__); + net_err_ratelimited("%s: frame too short!\n", __func__); return; } @@ -1259,7 +1257,7 @@ static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, IRDA_DEBUG(2, "%s()\n", __func__); if (!pskb_may_pull(skb, sizeof(*frame))) { - IRDA_ERROR("%s: frame too short!\n", __func__); + net_err_ratelimited("%s: frame too short!\n", __func__); return; } frame = (struct test_frame *) skb->data; @@ -1328,13 +1326,13 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, * share and non linear skbs. This should never happen, so * we don't need to be clever about it. Jean II */ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { - IRDA_ERROR("%s: can't clone shared skb!\n", __func__); + net_err_ratelimited("%s: can't clone shared skb!\n", __func__); goto err; } /* Check if frame is large enough for parsing */ if (!pskb_may_pull(skb, 2)) { - IRDA_ERROR("%s: frame too short!\n", __func__); + net_err_ratelimited("%s: frame too short!\n", __func__); goto err; } @@ -1383,8 +1381,8 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, irlap_recv_srej_frame(self, skb, &info, command); break; default: - IRDA_WARNING("%s: Unknown S-frame %02x received!\n", - __func__, info.control); + net_warn_ratelimited("%s: Unknown S-frame %02x received!\n", + __func__, info.control); break; } goto out; @@ -1421,8 +1419,8 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, irlap_recv_ui_frame(self, skb, &info); break; default: - IRDA_WARNING("%s: Unknown frame %02x received!\n", - __func__, info.control); + net_warn_ratelimited("%s: Unknown frame %02x received!\n", + __func__, info.control); break; } out: diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index a5f28d421ea8..6178e71f3a51 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -170,10 +170,8 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) /* Allocate new instance of a LSAP connection */ self = kzalloc(sizeof(struct lsap_cb), GFP_ATOMIC); - if (self == NULL) { - IRDA_ERROR("%s: can't allocate memory\n", __func__); + if (self == NULL) return NULL; - } self->magic = LMP_LSAP_MAGIC; self->slsap_sel = slsap_sel; @@ -297,10 +295,8 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) * Allocate new instance of a LSAP connection */ lap = kzalloc(sizeof(struct lap_cb), GFP_KERNEL); - if (lap == NULL) { - IRDA_ERROR("%s: unable to kmalloc\n", __func__); + if (lap == NULL) return; - } lap->irlap = irlap; lap->magic = LMP_LAP_MAGIC; @@ -311,7 +307,8 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) #endif lap->lsaps = hashbin_new(HB_LOCK); if (lap->lsaps == NULL) { - IRDA_WARNING("%s(), unable to kmalloc lsaps\n", __func__); + net_warn_ratelimited("%s(), unable to kmalloc lsaps\n", + __func__); kfree(lap); return; } @@ -852,8 +849,8 @@ void irlmp_do_discovery(int nslots) /* Make sure the value is sane */ if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){ - IRDA_WARNING("%s: invalid value for number of slots!\n", - __func__); + net_warn_ratelimited("%s: invalid value for number of slots!\n", + __func__); nslots = sysctl_discovery_slots = 8; } @@ -1799,8 +1796,8 @@ static __u8 irlmp_find_free_slsap(void) /* Make sure we terminate the loop */ if (wrapped++) { - IRDA_ERROR("%s: no more free LSAPs !\n", - __func__); + net_err_ratelimited("%s: no more free LSAPs !\n", + __func__); return 0; } } diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c index 9505a7d06f1a..30e51f9f4baf 100644 --- a/net/irda/irlmp_event.c +++ b/net/irda/irlmp_event.c @@ -508,8 +508,8 @@ static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event, IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __func__); if (self->conn_skb) { - IRDA_WARNING("%s: busy with another request!\n", - __func__); + net_warn_ratelimited("%s: busy with another request!\n", + __func__); return -EBUSY; } /* Don't forget to refcount it (see irlmp_connect_request()) */ @@ -525,8 +525,8 @@ static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event, break; case LM_CONNECT_INDICATION: if (self->conn_skb) { - IRDA_WARNING("%s: busy with another request!\n", - __func__); + net_warn_ratelimited("%s: busy with another request!\n", + __func__); return -EBUSY; } /* Don't forget to refcount it (see irlap_driver_rcv()) */ diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 85372cfa7b9f..e0b2b0d9af14 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -96,8 +96,8 @@ int __init irttp_init(void) irttp->tsaps = hashbin_new(HB_LOCK); if (!irttp->tsaps) { - IRDA_ERROR("%s: can't allocate IrTTP hashbin!\n", - __func__); + net_err_ratelimited("%s: can't allocate IrTTP hashbin!\n", + __func__); kfree(irttp); return -ENOMEM; } @@ -518,8 +518,8 @@ int irttp_close_tsap(struct tsap_cb *self) if (self->connected) { /* Check if disconnect is not pending */ if (!test_bit(0, &self->disconnect_pend)) { - IRDA_WARNING("%s: TSAP still connected!\n", - __func__); + net_warn_ratelimited("%s: TSAP still connected!\n", + __func__); irttp_disconnect_request(self, NULL, P_NORMAL); } self->close_pend = TRUE; @@ -568,13 +568,14 @@ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb) /* Check that nothing bad happens */ if (!self->connected) { - IRDA_WARNING("%s(), Not connected\n", __func__); + net_warn_ratelimited("%s(), Not connected\n", __func__); ret = -ENOTCONN; goto err; } if (skb->len > self->max_seg_size) { - IRDA_ERROR("%s(), UData is too large for IrLAP!\n", __func__); + net_err_ratelimited("%s(), UData is too large for IrLAP!\n", + __func__); ret = -EMSGSIZE; goto err; } @@ -617,7 +618,7 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) /* Check that nothing bad happens */ if (!self->connected) { - IRDA_WARNING("%s: Not connected\n", __func__); + net_warn_ratelimited("%s: Not connected\n", __func__); ret = -ENOTCONN; goto err; } @@ -627,8 +628,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) * inside an IrLAP frame */ if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) { - IRDA_ERROR("%s: SAR disabled, and data is too large for IrLAP!\n", - __func__); + net_err_ratelimited("%s: SAR disabled, and data is too large for IrLAP!\n", + __func__); ret = -EMSGSIZE; goto err; } @@ -640,8 +641,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) if ((self->tx_max_sdu_size != 0) && (self->tx_max_sdu_size != TTP_SAR_UNBOUND) && (skb->len > self->tx_max_sdu_size)) { - IRDA_ERROR("%s: SAR enabled, but data is larger than TxMaxSduSize!\n", - __func__); + net_err_ratelimited("%s: SAR enabled, but data is larger than TxMaxSduSize!\n", + __func__); ret = -EMSGSIZE; goto err; } @@ -1249,8 +1250,8 @@ static void irttp_connect_confirm(void *instance, void *sap, /* Any errors in the parameter list? */ if (ret < 0) { - IRDA_WARNING("%s: error extracting parameters\n", - __func__); + net_warn_ratelimited("%s: error extracting parameters\n", + __func__); dev_kfree_skb(skb); /* Do not accept this connection attempt */ @@ -1326,8 +1327,8 @@ static void irttp_connect_indication(void *instance, void *sap, /* Any errors in the parameter list? */ if (ret < 0) { - IRDA_WARNING("%s: error extracting parameters\n", - __func__); + net_warn_ratelimited("%s: error extracting parameters\n", + __func__); dev_kfree_skb(skb); /* Do not accept this connection attempt */ diff --git a/net/irda/parameters.c b/net/irda/parameters.c index 6d0869716bf6..d7a5778262ef 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -158,8 +158,8 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, } /* Check if buffer is long enough for insertion */ if (len < (2+p.pl)) { - IRDA_WARNING("%s: buffer too short for insertion!\n", - __func__); + net_warn_ratelimited("%s: buffer too short for insertion!\n", + __func__); return -1; } IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d, pi=%d\n", __func__, @@ -184,8 +184,8 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, break; default: - IRDA_WARNING("%s: length %d not supported\n", - __func__, p.pl); + net_warn_ratelimited("%s: length %d not supported\n", + __func__, p.pl); /* Skip parameter */ return -1; } @@ -214,9 +214,8 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { - IRDA_WARNING("%s: buffer too short for parsing! " - "Need %d bytes, but len is only %d\n", - __func__, p.pl, len); + net_warn_ratelimited("%s: buffer too short for parsing! Need %d bytes, but len is only %d\n", + __func__, p.pl, len); return -1; } @@ -226,9 +225,8 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, * PV_INTEGER means that the handler is flexible. */ if (((type & PV_MASK) != PV_INTEGER) && ((type & PV_MASK) != p.pl)) { - IRDA_ERROR("%s: invalid parameter length! " - "Expected %d bytes, but value had %d bytes!\n", - __func__, type & PV_MASK, p.pl); + net_err_ratelimited("%s: invalid parameter length! Expected %d bytes, but value had %d bytes!\n", + __func__, type & PV_MASK, p.pl); /* Most parameters are bit/byte fields or little endian, * so it's ok to only extract a subset of it (the subset @@ -265,8 +263,8 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, le32_to_cpus(&p.pv.i); break; default: - IRDA_WARNING("%s: length %d not supported\n", - __func__, p.pl); + net_warn_ratelimited("%s: length %d not supported\n", + __func__, p.pl); /* Skip parameter */ return p.pl+2; @@ -304,9 +302,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { - IRDA_WARNING("%s: buffer too short for parsing! " - "Need %d bytes, but len is only %d\n", - __func__, p.pl, len); + net_warn_ratelimited("%s: buffer too short for parsing! Need %d bytes, but len is only %d\n", + __func__, p.pl, len); return -1; } @@ -343,9 +340,8 @@ static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { - IRDA_WARNING("%s: buffer too short for parsing! " - "Need %d bytes, but len is only %d\n", - __func__, p.pl, len); + net_warn_ratelimited("%s: buffer too short for parsing! Need %d bytes, but len is only %d\n", + __func__, p.pl, len); return -1; } @@ -487,7 +483,8 @@ int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, /* Check if handler has been implemented */ if (!pi_minor_info->func) { - IRDA_MESSAGE("%s: no handler for pi=%#x\n", __func__, pi); + net_info_ratelimited("%s: no handler for pi=%#x\n", + __func__, pi); /* Skip this parameter */ return -1; } @@ -544,8 +541,8 @@ static int irda_param_extract(void *self, __u8 *buf, int len, /* Check if handler has been implemented */ if (!pi_minor_info->func) { - IRDA_MESSAGE("%s: no handler for pi=%#x\n", - __func__, buf[n]); + net_info_ratelimited("%s: no handler for pi=%#x\n", + __func__, buf[n]); /* Skip this parameter */ return 2 + buf[n + 1]; /* Continue */ } diff --git a/net/irda/qos.c b/net/irda/qos.c index 11a7cc0cbc28..f3b588c17d3b 100644 --- a/net/irda/qos.c +++ b/net/irda/qos.c @@ -200,8 +200,8 @@ static int msb_index (__u16 word) * able to check precisely what's going on. If a end user sees this, * it's very likely the peer. - Jean II */ if (word == 0) { - IRDA_WARNING("%s(), Detected buggy peer, adjust null PV to 0x1!\n", - __func__); + net_warn_ratelimited("%s(), Detected buggy peer, adjust null PV to 0x1!\n", + __func__); /* The only safe choice (we don't know the array size) */ word = 0x1; } @@ -351,8 +351,8 @@ static void irlap_adjust_qos_settings(struct qos_info *qos) if (sysctl_min_tx_turn_time > qos->min_turn_time.value) { int i; - IRDA_WARNING("%s(), Detected buggy peer, adjust mtt to %dus!\n", - __func__, sysctl_min_tx_turn_time); + net_warn_ratelimited("%s(), Detected buggy peer, adjust mtt to %dus!\n", + __func__, sysctl_min_tx_turn_time); /* We don't really need bits, but easier this way */ i = value_highest_bit(sysctl_min_tx_turn_time, min_turn_times, @@ -402,8 +402,8 @@ static void irlap_adjust_qos_settings(struct qos_info *qos) IRDA_DEBUG(2, "%s(), reducing data size to %d\n", __func__, qos->data_size.value); } else { - IRDA_WARNING("%s(), nothing more we can do!\n", - __func__); + net_warn_ratelimited("%s(), nothing more we can do!\n", + __func__); } } #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */ diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index fd0995b1323a..9efffeb8d0f1 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -134,8 +134,8 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) * transmitted after this point is 5. */ if(n >= (buffsize-5)) { - IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n", - __func__, n); + net_err_ratelimited("%s(), tx buffer overflow (n=%d)\n", + __func__, n); return n; } @@ -386,7 +386,7 @@ async_unwrap_ce(struct net_device *dev, break; case LINK_ESCAPE: - IRDA_WARNING("%s: state not defined\n", __func__); + net_warn_ratelimited("%s: state not defined\n", __func__); break; case BEGIN_FRAME: -- GitLab From cd32e2dcc9de6c27ecbbfc0e2079fb64b42bad5f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 11 Nov 2014 09:12:28 +1100 Subject: [PATCH 4351/9457] powerpc: Fix bad NULL pointer check in udbg_uart_getc_poll() We have some code in udbg_uart_getc_poll() that tries to protect against a NULL udbg_uart_in, but gets it all wrong. Found with the LLVM static analyzer (scan-build). Fixes: 309257484cc1 ("powerpc: Cleanup udbg_16550 and add support for LPC PIO-only UARTs") Signed-off-by: Anton Blanchard [mpe: Add some newlines for readability while we're here] Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/udbg_16550.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 6e7c4923b5ea..411116c38da4 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -69,8 +69,12 @@ static void udbg_uart_putc(char c) static int udbg_uart_getc_poll(void) { - if (!udbg_uart_in || !(udbg_uart_in(UART_LSR) & LSR_DR)) + if (!udbg_uart_in) + return -1; + + if (!(udbg_uart_in(UART_LSR) & LSR_DR)) return udbg_uart_in(UART_RBR); + return -1; } -- GitLab From d1d5304fcbc519f5fb12cbcca9c4fdd1d94447d7 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:29:28 +1100 Subject: [PATCH 4352/9457] powerpc/mm: Use PAGE_FACTOR PAGE_FACTOR was defined to reflect the difference between configured page size and fixed 4KB page size. Replace (PAGE_SHIFT - HW_PAGE_SHIFT) with PAGE_FACTOR. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hash_low_64.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 057cbbb4c576..5094f32b706e 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -514,7 +514,7 @@ htab_insert_pte: andis. r0,r31,_PAGE_4K_PFN@h srdi r5,r31,PTE_RPN_SHIFT bne- htab_special_pfn - sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT + sldi r5,r5,PAGE_FACTOR add r5,r5,r25 htab_special_pfn: sldi r5,r5,HW_PAGE_SHIFT @@ -544,7 +544,7 @@ htab_call_hpte_insert1: andis. r0,r31,_PAGE_4K_PFN@h srdi r5,r31,PTE_RPN_SHIFT bne- 3f - sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT + sldi r5,r5,PAGE_FACTOR add r5,r5,r25 3: sldi r5,r5,HW_PAGE_SHIFT -- GitLab From 592dfbfc72f5352437c883aa11ab579d10cdb595 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:48 +0100 Subject: [PATCH 4353/9457] mac820154: move interface unregistration into iface This patch move the iface unregistration into iface.c file to have a behaviour which is similar like mac80211. Also iface handling should be inside iface.c file only. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 1 + net/mac802154/iface.c | 13 +++++++++++++ net/mac802154/main.c | 9 +-------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index e22f509af72b..abb19701d494 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -172,5 +172,6 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, struct wpan_dev **new_wpan_dev, int type); +void ieee802154_remove_interfaces(struct ieee802154_local *local); #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 83715b5ffe43..8d90fbafda14 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -535,3 +535,16 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) synchronize_rcu(); unregister_netdevice(sdata->dev); } + +void ieee802154_remove_interfaces(struct ieee802154_local *local) +{ + struct ieee802154_sub_if_data *sdata, *next; + + list_for_each_entry_safe(sdata, next, &local->interfaces, list) { + mutex_lock(&sdata->local->iflist_mtx); + list_del(&sdata->list); + mutex_unlock(&sdata->local->iflist_mtx); + + unregister_netdevice(sdata->dev); + } +} diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 234084d26906..709dcc5f7f17 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -165,7 +165,6 @@ EXPORT_SYMBOL(ieee802154_register_hw); void ieee802154_unregister_hw(struct ieee802154_hw *hw) { struct ieee802154_local *local = hw_to_local(hw); - struct ieee802154_sub_if_data *sdata, *next; tasklet_kill(&local->tasklet); flush_workqueue(local->workqueue); @@ -173,13 +172,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) rtnl_lock(); - list_for_each_entry_safe(sdata, next, &local->interfaces, list) { - mutex_lock(&sdata->local->iflist_mtx); - list_del(&sdata->list); - mutex_unlock(&sdata->local->iflist_mtx); - - unregister_netdevice(sdata->dev); - } + ieee802154_remove_interfaces(local); rtnl_unlock(); -- GitLab From d14e1c71cfa870a2ed9f058a79b1c71decdaa9ba Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:49 +0100 Subject: [PATCH 4354/9457] mac820154: rename sdata next to tmp This patch is just a cleanup to name the temporary variable for protected list for each loop as tmp. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 8d90fbafda14..8b21d201fc97 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -538,9 +538,9 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata) void ieee802154_remove_interfaces(struct ieee802154_local *local) { - struct ieee802154_sub_if_data *sdata, *next; + struct ieee802154_sub_if_data *sdata, *tmp; - list_for_each_entry_safe(sdata, next, &local->interfaces, list) { + list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); -- GitLab From 2789e6297f8fd4943b8d63599a75c3e1cf4f8517 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:50 +0100 Subject: [PATCH 4355/9457] mac820154: move mutex locks out of loop Instead of always re-lock the iflist_mtx at multiple interfaces we lock the complete for each loop at start and at the end. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 8b21d201fc97..85d215562b4a 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -540,11 +540,11 @@ void ieee802154_remove_interfaces(struct ieee802154_local *local) { struct ieee802154_sub_if_data *sdata, *tmp; + mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { - mutex_lock(&sdata->local->iflist_mtx); list_del(&sdata->list); - mutex_unlock(&sdata->local->iflist_mtx); unregister_netdevice(sdata->dev); } + mutex_unlock(&local->iflist_mtx); } -- GitLab From 6322d50d879c7ad150164cedc64015a7817f7b28 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:51 +0100 Subject: [PATCH 4356/9457] mac802154: add wpan_phy priv id This patch adds an unique id for an wpan_phy. This behaviour is mostly grabbed from wireless stack. This is needed for upcomming patches which identify the wpan netdev while NETDEV_CHANGENAME in netdev notify function. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 8 ++++++++ net/mac802154/ieee802154_i.h | 3 +++ net/mac802154/main.c | 2 ++ net/mac802154/util.c | 3 +++ 4 files changed, 16 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index e5570e011116..369515231302 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -42,6 +42,14 @@ struct cfg802154_ops { struct wpan_phy { struct mutex pib_lock; + /* If multiple wpan_phys are registered and you're handed e.g. + * a regular netdev with assigned ieee802154_ptr, you won't + * know whether it points to a wpan_phy your driver has registered + * or not. Assign this to something global to your driver to + * help determine whether you own this wpan_phy or not. + */ + const void *privid; + /* * This is a PIB according to 802.15.4-2011. * We do not provide timing-related variables, as they diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index abb19701d494..4be5e23c7e8b 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -96,6 +96,9 @@ struct ieee802154_sub_if_data { #define MAC802154_CHAN_NONE 0xff /* No channel is assigned */ +/* utility functions/constants */ +extern const void *const mac802154_wpan_phy_privid; /* for wpan_phy privid */ + static inline struct ieee802154_local * hw_to_local(struct ieee802154_hw *hw) { diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 709dcc5f7f17..24e8ca6a669d 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -92,6 +92,8 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) return NULL; } + phy->privid = mac802154_wpan_phy_privid; + local = wpan_phy_priv(phy); local->phy = phy; local->hw.phy = local->phy; diff --git a/net/mac802154/util.c b/net/mac802154/util.c index 117e4eff4ca8..9a04e4a8e50f 100644 --- a/net/mac802154/util.c +++ b/net/mac802154/util.c @@ -15,6 +15,9 @@ #include "ieee802154_i.h" +/* privid for wpan_phys to determine whether they belong to us or not */ +const void *const mac802154_wpan_phy_privid = &mac802154_wpan_phy_privid; + void ieee802154_wake_queue(struct ieee802154_hw *hw) { struct ieee802154_local *local = hw_to_local(hw); -- GitLab From 912f67aec761ea4d2107ed0bcb5aef01ae1ecd2e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:52 +0100 Subject: [PATCH 4357/9457] mac802154: change module description This patch changes the module description like wireless which is IEEE 802.11 "subsystem" and not "implementation". Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 24e8ca6a669d..40a326402ec1 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -182,5 +182,5 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) } EXPORT_SYMBOL(ieee802154_unregister_hw); -MODULE_DESCRIPTION("IEEE 802.15.4 implementation"); +MODULE_DESCRIPTION("IEEE 802.15.4 subsystem"); MODULE_LICENSE("GPL v2"); -- GitLab From be4fd8e5d9f5cd3fdc368e32e7957bcb83bcbb8b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:53 +0100 Subject: [PATCH 4358/9457] mac802154: add ifname change notifier This patch adds a netdev notifier for interface renaming. We have a name attribute inside of subif data struct. This is needed to have always the actual netdev name in sdata name attribute. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 +++ net/mac802154/iface.c | 35 +++++++++++++++++++++++++++++++++++ net/mac802154/main.c | 15 +++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 4be5e23c7e8b..69cb585e162f 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -169,6 +169,9 @@ void mac802154_get_table(struct net_device *dev, struct ieee802154_llsec_table **t); void mac802154_unlock_table(struct net_device *dev); +/* interface handling */ +int ieee802154_iface_init(void); +void ieee802154_iface_exit(void); struct net_device * mac802154_add_iface(struct wpan_phy *phy, const char *name, int type); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 85d215562b4a..ec92b48d1b0b 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -548,3 +548,38 @@ void ieee802154_remove_interfaces(struct ieee802154_local *local) } mutex_unlock(&local->iflist_mtx); } + +static int netdev_notify(struct notifier_block *nb, + unsigned long state, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct ieee802154_sub_if_data *sdata; + + if (state != NETDEV_CHANGENAME) + return NOTIFY_DONE; + + if (!dev->ieee802154_ptr || !dev->ieee802154_ptr->wpan_phy) + return NOTIFY_DONE; + + if (dev->ieee802154_ptr->wpan_phy->privid != mac802154_wpan_phy_privid) + return NOTIFY_DONE; + + sdata = IEEE802154_DEV_TO_SUB_IF(dev); + memcpy(sdata->name, dev->name, IFNAMSIZ); + + return NOTIFY_OK; +} + +static struct notifier_block mac802154_netdev_notifier = { + .notifier_call = netdev_notify, +}; + +int ieee802154_iface_init(void) +{ + return register_netdevice_notifier(&mac802154_netdev_notifier); +} + +void ieee802154_iface_exit(void) +{ + unregister_netdevice_notifier(&mac802154_netdev_notifier); +} diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 40a326402ec1..46c76e005446 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -182,5 +182,20 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw) } EXPORT_SYMBOL(ieee802154_unregister_hw); +static int __init ieee802154_init(void) +{ + return ieee802154_iface_init(); +} + +static void __exit ieee802154_exit(void) +{ + ieee802154_iface_exit(); + + rcu_barrier(); +} + +subsys_initcall(ieee802154_init); +module_exit(ieee802154_exit); + MODULE_DESCRIPTION("IEEE 802.15.4 subsystem"); MODULE_LICENSE("GPL v2"); -- GitLab From 9d30a8cf98b2dd132d6e4503718df78ffc1b7f53 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:54 +0100 Subject: [PATCH 4359/9457] ieee802154: cleanup cfg802154 intendation This is patch is cleanup to have a similar indentation like cfg80211 implementation. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 369515231302..8a3edc5edad1 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -35,8 +35,8 @@ struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, int type); - void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, - struct net_device *dev); + void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, + struct net_device *dev); }; struct wpan_phy { -- GitLab From ab0bd561724bf3c09aa80e76ca0a187c6880bc5c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:55 +0100 Subject: [PATCH 4360/9457] ieee820154: add channel set support This patch adds page and channel setting support to nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 1 + net/ieee802154/nl802154.c | 28 ++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 24 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 8a3edc5edad1..391fdb37208d 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -37,6 +37,7 @@ struct cfg802154_ops { int type); void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, struct net_device *dev); + int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 46df7dca92d9..d8ef2c8a182f 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -23,6 +23,7 @@ #include #include "nl802154.h" +#include "rdev-ops.h" #include "core.h" static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, @@ -550,6 +551,25 @@ static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) return genlmsg_reply(msg, info); } +static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + u8 channel, page; + + if (!info->attrs[NL802154_ATTR_PAGE] || + !info->attrs[NL802154_ATTR_CHANNEL]) + return -EINVAL; + + page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]); + channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]); + + /* check 802.15.4 constraints */ + if (page >= WPAN_NUM_PAGES || channel >= WPAN_NUM_CHANNELS) + return -EINVAL; + + return rdev_set_channel(rdev, page, channel); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -660,6 +680,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_CHANNEL, + .doit = nl802154_set_channel, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index ac8824ec168c..8a3b0eb4e026 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -20,4 +20,11 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev); } +static inline int +rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page, + const u8 channel) +{ + return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index d2c4e8f89720..9d5b1895c752 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -17,6 +17,7 @@ #include #include "ieee802154_i.h" +#include "driver-ops.h" #include "cfg.h" static struct net_device * @@ -41,7 +42,30 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, ieee802154_if_remove(sdata); } +static int +ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page, + const u8 channel) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + int ret; + + ASSERT_RTNL(); + + /* check if phy support this setting */ + if (!(wpan_phy->channels_supported[page] & BIT(channel))) + return -EINVAL; + + ret = drv_set_channel(local, page, channel); + if (!ret) { + wpan_phy->current_page = page; + wpan_phy->current_channel = channel; + } + + return ret; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, + .set_channel = ieee802154_set_channel, }; -- GitLab From 820bd66fb28ce0c47cb024895d8bace58f5be56d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:56 +0100 Subject: [PATCH 4361/9457] ieee820154: remove valid page and channel checks This patch removes validation of page and channel while setting from driver layer. This is already handled by nl802154 and mac802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 14 +------------- drivers/net/ieee802154/fakelb.c | 3 --- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index ebcbeb3a06e8..f9e3bce8d63b 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1047,23 +1047,11 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel) struct at86rf230_local *lp = hw->priv; int rc; - if (page > 31 || - !(lp->hw->phy->channels_supported[page] & BIT(channel))) { - WARN_ON(1); - return -EINVAL; - } - rc = lp->data->set_channel(lp, page, channel); - if (rc < 0) - return rc; - /* Wait for PLL */ usleep_range(lp->data->t_channel_switch, lp->data->t_channel_switch + 10); - hw->phy->current_channel = channel; - hw->phy->current_page = page; - - return 0; + return rc; } static int diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 6e62286cef78..96947d724189 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -58,9 +58,6 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) { pr_debug("set channel to %d\n", channel); - hw->phy->current_page = page; - hw->phy->current_channel = channel; - return 0; } -- GitLab From 702bf371282f5912fe53f0b247fa2d7df9d7951f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:57 +0100 Subject: [PATCH 4362/9457] ieee820154: add pan_id setting support This patch adds support for setting pan_id via nl802154 framework. Adding a comment because setting 0xffff as pan_id seems to be valid setting. The pan_id 0xffff as source pan is invalid. I am not sure now about this setting but for the current netlink interface this is an invalid setting, so we do the same now. Maybe we need to change that when we have coordinator support and association support. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 2 ++ include/net/cfg802154.h | 2 ++ net/ieee802154/nl802154.c | 31 +++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 20 ++++++++++++++++++++ 5 files changed, 62 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index d043449a079d..d40379876b84 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -30,6 +30,8 @@ #define IEEE802154_MTU 127 #define IEEE802154_MIN_PSDU_LEN 5 +#define IEEE802154_PAN_ID_BROADCAST 0xffff + #define IEEE802154_EXTENDED_ADDR_LEN 8 #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 391fdb37208d..d07b0726b285 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -38,6 +38,8 @@ struct cfg802154_ops { void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, struct net_device *dev); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); + int (*set_pan_id)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, u16 pan_id); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index d8ef2c8a182f..88cd1293283a 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -570,6 +570,29 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) return rdev_set_channel(rdev, page, channel); } +static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + u16 pan_id; + + /* conflict here while tx/rx calls */ + if (netif_running(dev)) + return -EBUSY; + + /* don't change address fields on monitor */ + if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) + return -EINVAL; + + if (!info->attrs[NL802154_ATTR_PAN_ID]) + return -EINVAL; + + pan_id = nla_get_u16(info->attrs[NL802154_ATTR_PAN_ID]); + + return rdev_set_pan_id(rdev, wpan_dev, pan_id); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -688,6 +711,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_PAN_ID, + .doit = nl802154_set_pan_id, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 8a3b0eb4e026..4115ea264fd5 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -27,4 +27,11 @@ rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page, return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); } +static inline int +rdev_set_pan_id(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, u16 pan_id) +{ + return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 9d5b1895c752..db6e5e981a83 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -64,8 +64,28 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page, return ret; } +static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, const u16 pan_id) +{ + ASSERT_RTNL(); + + /* TODO + * I am not sure about to check here on broadcast pan_id. + * Broadcast is a valid setting, comment from 802.15.4: + * If this value is 0xffff, the device is not associated. + * + * This could useful to simple deassociate an device. + */ + if (pan_id == IEEE802154_PAN_ID_BROADCAST) + return -EINVAL; + + wpan_dev->pan_id = cpu_to_le16(pan_id); + return 0; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, .set_channel = ieee802154_set_channel, + .set_pan_id = ieee802154_set_pan_id, }; -- GitLab From 9830c62a0b3d57d9d00880989cfe987f581bc03f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:58 +0100 Subject: [PATCH 4363/9457] ieee820154: add short_addr setting support This patch adds support for setting short address via nl802154 framework. Also added a comment because a 0xffff seems to be valid address that we don't have a short address. This is a valid setting but we need more checks in upper layers to don't allow this address as source address. Also the current netlink interface doesn't allow to set the short_addr to 0xffff. Same for the 0xfffe short address which describes a not allocated short address. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 2 ++ include/net/cfg802154.h | 2 ++ net/ieee802154/nl802154.c | 31 +++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 26 ++++++++++++++++++++++++++ 5 files changed, 68 insertions(+) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index d40379876b84..ce0f96a55976 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -31,6 +31,8 @@ #define IEEE802154_MIN_PSDU_LEN 5 #define IEEE802154_PAN_ID_BROADCAST 0xffff +#define IEEE802154_ADDR_SHORT_BROADCAST 0xffff +#define IEEE802154_ADDR_SHORT_UNSPEC 0xfffe #define IEEE802154_EXTENDED_ADDR_LEN 8 diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index d07b0726b285..e8a4c2b70720 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -40,6 +40,8 @@ struct cfg802154_ops { int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_pan_id)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u16 pan_id); + int (*set_short_addr)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, u16 short_addr); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 88cd1293283a..2978c1a78017 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -593,6 +593,29 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) return rdev_set_pan_id(rdev, wpan_dev, pan_id); } +static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + u16 short_addr; + + /* conflict here while tx/rx calls */ + if (netif_running(dev)) + return -EBUSY; + + /* don't change address fields on monitor */ + if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) + return -EINVAL; + + if (!info->attrs[NL802154_ATTR_SHORT_ADDR]) + return -EINVAL; + + short_addr = nla_get_u16(info->attrs[NL802154_ATTR_SHORT_ADDR]); + + return rdev_set_short_addr(rdev, wpan_dev, short_addr); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -719,6 +742,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_SHORT_ADDR, + .doit = nl802154_set_short_addr, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 4115ea264fd5..16b0de06c3af 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -34,4 +34,11 @@ rdev_set_pan_id(struct cfg802154_registered_device *rdev, return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); } +static inline int +rdev_set_short_addr(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, u16 short_addr) +{ + return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index db6e5e981a83..df29976d1321 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -83,9 +83,35 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, return 0; } +static int +ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + const u16 short_addr) +{ + ASSERT_RTNL(); + + /* TODO + * I am not sure about to check here on broadcast short_addr. + * Broadcast is a valid setting, comment from 802.15.4: + * A value of 0xfffe indicates that the device has + * associated but has not been allocated an address. A + * value of 0xffff indicates that the device does not + * have a short address. + * + * I think we should allow to set these settings but + * don't allow to allow socket communication with it. + */ + if (short_addr == IEEE802154_ADDR_SHORT_UNSPEC || + short_addr == IEEE802154_ADDR_SHORT_BROADCAST) + return -EINVAL; + + wpan_dev->short_addr = cpu_to_le16(short_addr); + return 0; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, .set_channel = ieee802154_set_channel, .set_pan_id = ieee802154_set_pan_id, + .set_short_addr = ieee802154_set_short_addr, }; -- GitLab From 656a999e8701c1e3d17040f051d3a080ec6c710c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:36:59 +0100 Subject: [PATCH 4364/9457] ieee820154: add backoff exponent setting support This patch adds support for setting backoff exponents via nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 3 +++ net/ieee802154/nl802154.c | 34 ++++++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 9 +++++++++ net/mac802154/cfg.c | 18 ++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index e8a4c2b70720..27e98d10fb2c 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -42,6 +42,9 @@ struct cfg802154_ops { struct wpan_dev *wpan_dev, u16 pan_id); int (*set_short_addr)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u16 short_addr); + int (*set_backoff_exponent)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, u8 min_be, + u8 max_be); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 2978c1a78017..d1cf3021ff36 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -616,6 +616,32 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) return rdev_set_short_addr(rdev, wpan_dev, short_addr); } +static int +nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + u8 min_be, max_be; + + /* should be set on netif open inside phy settings */ + if (netif_running(dev)) + return -EBUSY; + + if (!info->attrs[NL802154_ATTR_MIN_BE] || + !info->attrs[NL802154_ATTR_MAX_BE]) + return -EINVAL; + + min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]); + max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]); + + /* check 802.15.4 constraints */ + if (max_be < 3 || max_be > 8 || min_be > max_be) + return -EINVAL; + + return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -750,6 +776,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_BACKOFF_EXPONENT, + .doit = nl802154_set_backoff_exponent, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 16b0de06c3af..dbccfa9383fd 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -41,4 +41,13 @@ rdev_set_short_addr(struct cfg802154_registered_device *rdev, return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); } +static inline int +rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, const u8 min_be, + const u8 max_be) +{ + return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev, + min_be, max_be); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index df29976d1321..67c96f981693 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -83,6 +83,23 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, return 0; } +static int +ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const u8 min_be, const u8 max_be) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + + ASSERT_RTNL(); + + if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS)) + return -EOPNOTSUPP; + + wpan_dev->min_be = min_be; + wpan_dev->max_be = max_be; + return 0; +} + static int ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, const u16 short_addr) @@ -114,4 +131,5 @@ const struct cfg802154_ops mac802154_config_ops = { .set_channel = ieee802154_set_channel, .set_pan_id = ieee802154_set_pan_id, .set_short_addr = ieee802154_set_short_addr, + .set_backoff_exponent = ieee802154_set_backoff_exponent, }; -- GitLab From a8d352d458bba4603abd996e541c7f206a101f26 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:00 +0100 Subject: [PATCH 4365/9457] at86rf230: remove invalid backoff exponent check This patch removes the invalid backoff exponent check from driver layer. This is already handled by nl802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index f9e3bce8d63b..05d4f8f2fc44 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1167,7 +1167,7 @@ at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, struct at86rf230_local *lp = hw->priv; int rc; - if (min_be > max_be || max_be > 8 || retries > 5) + if (retries > 5) return -EINVAL; rc = at86rf230_write_subreg(lp, SR_MIN_BE, min_be); -- GitLab From a01ba7652cda5602b248efff168450ec658640b8 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:01 +0100 Subject: [PATCH 4366/9457] ieee820154: add max csma backoffs setting support This patch add support for max csma backoffs setting via nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 3 +++ net/ieee802154/nl802154.c | 33 +++++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 9 +++++++++ net/mac802154/cfg.c | 16 ++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 27e98d10fb2c..79b9ae0abb3b 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -45,6 +45,9 @@ struct cfg802154_ops { int (*set_backoff_exponent)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u8 min_be, u8 max_be); + int (*set_max_csma_backoffs)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + u8 max_csma_backoffs); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index d1cf3021ff36..af383553bdd2 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -642,6 +642,31 @@ nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info) return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be); } +static int +nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + u8 max_csma_backoffs; + + /* conflict here while other running iface settings */ + if (netif_running(dev)) + return -EBUSY; + + if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]) + return -EINVAL; + + max_csma_backoffs = nla_get_u8( + info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]); + + /* check 802.15.4 constraints */ + if (max_csma_backoffs > 5) + return -EINVAL; + + return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -784,6 +809,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS, + .doit = nl802154_set_max_csma_backoffs, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index dbccfa9383fd..263095c8686c 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -50,4 +50,13 @@ rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev, min_be, max_be); } +static inline int +rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, + const u8 max_csma_backoffs) +{ + return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev, + max_csma_backoffs); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 67c96f981693..d72feebb939d 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -125,6 +125,21 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, return 0; } +static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const u8 max_csma_backoffs) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + + ASSERT_RTNL(); + + if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS)) + return -EOPNOTSUPP; + + wpan_dev->csma_retries = max_csma_backoffs; + return 0; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, @@ -132,4 +147,5 @@ const struct cfg802154_ops mac802154_config_ops = { .set_pan_id = ieee802154_set_pan_id, .set_short_addr = ieee802154_set_short_addr, .set_backoff_exponent = ieee802154_set_backoff_exponent, + .set_max_csma_backoffs = ieee802154_set_max_csma_backoffs, }; -- GitLab From 17561bfe6fe2cde8699b6c98d9078dfa3e36911d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:02 +0100 Subject: [PATCH 4367/9457] at86rf230: remove invalid max csma backoffs check This patch removes the invalid check on max csma backoffs in driver layer. This is already handled by nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 05d4f8f2fc44..aea00d36c057 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1167,9 +1167,6 @@ at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be, struct at86rf230_local *lp = hw->priv; int rc; - if (retries > 5) - return -EINVAL; - rc = at86rf230_write_subreg(lp, SR_MIN_BE, min_be); if (rc) return rc; -- GitLab From 17a3a46bfbf1c2b944812a81b11ffe255a55e9ca Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:03 +0100 Subject: [PATCH 4368/9457] ieee820154: add max frame retries setting support This patch add support for setting mac frame retries setting via nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 3 +++ net/ieee802154/nl802154.c | 32 ++++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 9 +++++++++ net/mac802154/cfg.c | 16 ++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 79b9ae0abb3b..5c3bc12706c2 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -48,6 +48,9 @@ struct cfg802154_ops { int (*set_max_csma_backoffs)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u8 max_csma_backoffs); + int (*set_max_frame_retries)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + s8 max_frame_retries); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index af383553bdd2..0e272c67c49b 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -667,6 +667,30 @@ nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info) return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs); } +static int +nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + s8 max_frame_retries; + + if (netif_running(dev)) + return -EBUSY; + + if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]) + return -EINVAL; + + max_frame_retries = nla_get_s8( + info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]); + + /* check 802.15.4 constraints */ + if (max_frame_retries < -1 || max_frame_retries > 7) + return -EINVAL; + + return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -817,6 +841,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES, + .doit = nl802154_set_max_frame_retries, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 263095c8686c..f9171aaf985e 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -59,4 +59,13 @@ rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev, max_csma_backoffs); } +static inline int +rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, + const s8 max_frame_retries) +{ + return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev, + max_frame_retries); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index d72feebb939d..a8f6eaa76d4d 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -140,6 +140,21 @@ static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy, return 0; } +static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const s8 max_frame_retries) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + + ASSERT_RTNL(); + + if (!(local->hw.flags & IEEE802154_HW_FRAME_RETRIES)) + return -EOPNOTSUPP; + + wpan_dev->frame_retries = max_frame_retries; + return 0; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, @@ -148,4 +163,5 @@ const struct cfg802154_ops mac802154_config_ops = { .set_short_addr = ieee802154_set_short_addr, .set_backoff_exponent = ieee802154_set_backoff_exponent, .set_max_csma_backoffs = ieee802154_set_max_csma_backoffs, + .set_max_frame_retries = ieee802154_set_max_frame_retries, }; -- GitLab From f426fd03da1ec3954cefb7867daca4b2ba9de36c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:04 +0100 Subject: [PATCH 4369/9457] at86rf230: remove invalid max frame retries check This patch removes the invalid max frame retries check from driver layer. This is already handled by nl802154 framework. Also the IEEE 802.15.4 standard doesn't allow a frame retries setting above 7. This seems to be valid for the at86rf230 transceiver but the chip running out of spec then. We only allow settings according 802.15.4 right now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index aea00d36c057..31d62f9c6ce8 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1184,9 +1184,6 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries) struct at86rf230_local *lp = hw->priv; int rc = 0; - if (retries < -1 || retries > 15) - return -EINVAL; - lp->tx_aret = retries >= 0; lp->max_frame_retries = retries; -- GitLab From c8937a1d112b1a948454f4fa2f9b747fee2a3f66 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 12 Nov 2014 03:37:05 +0100 Subject: [PATCH 4370/9457] ieee820154: add lbt setting support This patch adds support for setting listen before transmit mode via nl802154 framework. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 2 ++ net/ieee802154/nl802154.c | 25 +++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 16 ++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 5c3bc12706c2..fa0a9e519523 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -51,6 +51,8 @@ struct cfg802154_ops { int (*set_max_frame_retries)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, s8 max_frame_retries); + int (*set_lbt_mode)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, bool mode); }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 0e272c67c49b..ccdf33ecee0b 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -691,6 +691,23 @@ nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info) return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries); } +static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + bool mode; + + if (netif_running(dev)) + return -EBUSY; + + if (!info->attrs[NL802154_ATTR_LBT_MODE]) + return -EINVAL; + + mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]); + return rdev_set_lbt_mode(rdev, wpan_dev, mode); +} + #define NL802154_FLAG_NEED_WPAN_PHY 0x01 #define NL802154_FLAG_NEED_NETDEV 0x02 #define NL802154_FLAG_NEED_RTNL 0x04 @@ -849,6 +866,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_NETDEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_SET_LBT_MODE, + .doit = nl802154_set_lbt_mode, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_NETDEV | + NL802154_FLAG_NEED_RTNL, + }, }; /* initialisation/exit functions */ diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index f9171aaf985e..a78f700bc821 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -68,4 +68,11 @@ rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev, max_frame_retries); } +static inline int +rdev_set_lbt_mode(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev, const bool mode) +{ + return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode); +} + #endif /* __CFG802154_RDEV_OPS */ diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index a8f6eaa76d4d..5d669d87dd7d 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -155,6 +155,21 @@ static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy, return 0; } +static int ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const bool mode) +{ + struct ieee802154_local *local = wpan_phy_priv(wpan_phy); + + ASSERT_RTNL(); + + if (!(local->hw.flags & IEEE802154_HW_LBT)) + return -EOPNOTSUPP; + + wpan_dev->lbt = mode; + return 0; +} + const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, @@ -164,4 +179,5 @@ const struct cfg802154_ops mac802154_config_ops = { .set_backoff_exponent = ieee802154_set_backoff_exponent, .set_max_csma_backoffs = ieee802154_set_max_csma_backoffs, .set_max_frame_retries = ieee802154_set_max_frame_retries, + .set_lbt_mode = ieee802154_set_lbt_mode, }; -- GitLab From 8b91a2554610ac5e341de8fb0b5715fe90a0f2e2 Mon Sep 17 00:00:00 2001 From: "Suresh E. Warrier" Date: Mon, 3 Nov 2014 15:46:42 +1100 Subject: [PATCH 4371/9457] powerpc: Save/restore PPR for KVM hypercalls The system call FLIH (first-level interrupt handler) at 0xc00 unconditionally sets hardware priority to medium. For hypercalls, this means we lose guest OS priority. The front end (do_kvm_0x**) to the KVM interrupt handler always assumes that PPR priority is saved in PACA exception save area, so it copies this to the kvm_hstate structure. For hypercalls, this would be the saved priority from any previous exception. Eventually, the guest gets resumed with an incorrect priority. The fix is to save the PPR priority in PACA exception save area before switching HMT priorities in the FLIH so that existing code described above in the KVM interrupt handler can copy it from there into the VCPU's saved context. Signed-off-by: Suresh Warrier Signed-off-by: Paul Mackerras [mpe: Dropped HMT_MEDIUM_PPR_DISCARD and reworded comment] Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 72e783ea0681..a1d45c161e24 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -292,15 +292,26 @@ decrementer_pSeries: . = 0xc00 .globl system_call_pSeries system_call_pSeries: - HMT_MEDIUM + /* + * If CONFIG_KVM_BOOK3S_64_HANDLER is set, save the PPR (on systems + * that support it) before changing to HMT_MEDIUM. That allows the KVM + * code to save that value into the guest state (it is the guest's PPR + * value). Otherwise just change to HMT_MEDIUM as userspace has + * already saved the PPR. + */ #ifdef CONFIG_KVM_BOOK3S_64_HANDLER SET_SCRATCH0(r13) GET_PACA(r13) std r9,PACA_EXGEN+EX_R9(r13) + OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); + HMT_MEDIUM; std r10,PACA_EXGEN+EX_R10(r13) + OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r9, CPU_FTR_HAS_PPR); mfcr r9 KVMTEST(0xc00) GET_SCRATCH0(r13) +#else + HMT_MEDIUM; #endif SYSCALL_PSERIES_1 SYSCALL_PSERIES_2_RFID -- GitLab From 7048c846949ac1feb09d1b624ea0e8c351d92a7b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 3 Nov 2014 15:46:43 +1100 Subject: [PATCH 4372/9457] powerpc: Fix compilation of emulate_step() Commit be96f63375a1 ("powerpc: Split out instruction analysis part of emulate_step()") added some calls to do_fp_load() and do_fp_store(), which fail to compile on configs with CONFIG_PPC_FPU=n and CONFIG_PPC_EMULATE_SSTEP=y. This fixes the compile by adding #ifdef CONFIG_PPC_FPU around the code that calls these functions. Signed-off-by: Paul Mackerras Signed-off-by: Michael Ellerman --- arch/powerpc/lib/sstep.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 54651fc2d412..dc885b30f7a6 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1865,6 +1865,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) } goto ldst_done; +#ifdef CONFIG_PPC_FPU case LOAD_FP: if (regs->msr & MSR_LE) return 0; @@ -1873,7 +1874,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) else err = do_fp_load(op.reg, do_lfd, op.ea, size, regs); goto ldst_done; - +#endif #ifdef CONFIG_ALTIVEC case LOAD_VMX: if (regs->msr & MSR_LE) @@ -1919,6 +1920,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) err = write_mem(op.val, op.ea, size, regs); goto ldst_done; +#ifdef CONFIG_PPC_FPU case STORE_FP: if (regs->msr & MSR_LE) return 0; @@ -1927,7 +1929,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) else err = do_fp_store(op.reg, do_stfd, op.ea, size, regs); goto ldst_done; - +#endif #ifdef CONFIG_ALTIVEC case STORE_VMX: if (regs->msr & MSR_LE) -- GitLab From 71dfda58aaaf4bf6b1bc59f9d8afa635fa1337d4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 11 Nov 2014 09:26:34 -0800 Subject: [PATCH 4373/9457] net: Add device Rx page allocation function This patch implements __dev_alloc_pages and __dev_alloc_page. These are meant to replace the __skb_alloc_pages and __skb_alloc_page functions. The reason for doing this is that it occurred to me that __skb_alloc_page is supposed to be passed an sk_buff pointer, but it is NULL in all cases where it is used. Worse is that in the case of ixgbe it is passed NULL via the sk_buff pointer in the rx_buffer info structure which means the compiler is not correctly stripping it out. The naming for these functions is based on dev_alloc_skb and __dev_alloc_skb. There was originally a netdev_alloc_page, however that was passed a net_device pointer and this function is not so I thought it best to follow that naming scheme since that is the same difference between dev_alloc_skb and netdev_alloc_skb. In the case of anything greater than order 0 it is assumed that we want a compound page so __GFP_COMP is set for all allocations as we expect a compound page when assigning a page frag. The other change in this patch is to exploit the behaviors of the page allocator in how it handles flags. So for example we can always set __GFP_COMP and __GFP_MEMALLOC since they are ignored if they are not applicable or are overridden by another flag. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- include/linux/skbuff.h | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 103fbe8113f8..2e5221f1ec72 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2184,6 +2184,54 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, return __netdev_alloc_skb_ip_align(dev, length, GFP_ATOMIC); } +/** + * __dev_alloc_pages - allocate page for network Rx + * @gfp_mask: allocation priority. Set __GFP_NOMEMALLOC if not for network Rx + * @order: size of the allocation + * + * Allocate a new page. + * + * %NULL is returned if there is no free memory. +*/ +static inline struct page *__dev_alloc_pages(gfp_t gfp_mask, + unsigned int order) +{ + /* This piece of code contains several assumptions. + * 1. This is for device Rx, therefor a cold page is preferred. + * 2. The expectation is the user wants a compound page. + * 3. If requesting a order 0 page it will not be compound + * due to the check to see if order has a value in prep_new_page + * 4. __GFP_MEMALLOC is ignored if __GFP_NOMEMALLOC is set due to + * code in gfp_to_alloc_flags that should be enforcing this. + */ + gfp_mask |= __GFP_COLD | __GFP_COMP | __GFP_MEMALLOC; + + return alloc_pages_node(NUMA_NO_NODE, gfp_mask, order); +} + +static inline struct page *dev_alloc_pages(unsigned int order) +{ + return __dev_alloc_pages(GFP_ATOMIC, order); +} + +/** + * __dev_alloc_page - allocate a page for network Rx + * @gfp_mask: allocation priority. Set __GFP_NOMEMALLOC if not for network Rx + * + * Allocate a new page. + * + * %NULL is returned if there is no free memory. + */ +static inline struct page *__dev_alloc_page(gfp_t gfp_mask) +{ + return __dev_alloc_pages(gfp_mask, 0); +} + +static inline struct page *dev_alloc_page(void) +{ + return __dev_alloc_page(GFP_ATOMIC); +} + /** * __skb_alloc_pages - allocate pages for ps-rx on a skb and preserve pfmemalloc data * @gfp_mask: alloc_pages_node mask. Set __GFP_NOMEMALLOC if not for network packet RX -- GitLab From aa9cd31c3f3ee36dc459b6070bacc581c1bfc334 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 11 Nov 2014 09:26:42 -0800 Subject: [PATCH 4374/9457] cxgb4/cxgb4vf: Replace __skb_alloc_page with __dev_alloc_page Drop the bloated use of __skb_alloc_page and replace it with __dev_alloc_page. In addition update the one other spot that is allocating a page so that it allocates with the correct flags. Cc: Hariprasad S Cc: Casey Leedom Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 6 +++--- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 6399e008a7f7..dacd95008333 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -576,7 +576,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, __be64 *d = &q->desc[q->pidx]; struct rx_sw_desc *sd = &q->sdesc[q->pidx]; - gfp |= __GFP_NOWARN | __GFP_COLD; + gfp |= __GFP_NOWARN; if (s->fl_pg_order == 0) goto alloc_small_pages; @@ -585,7 +585,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, * Prefer large buffers */ while (n) { - pg = alloc_pages(gfp | __GFP_COMP, s->fl_pg_order); + pg = __dev_alloc_pages(gfp, s->fl_pg_order); if (unlikely(!pg)) { q->large_alloc_failed++; break; /* fall back to single pages */ @@ -615,7 +615,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, alloc_small_pages: while (n--) { - pg = __skb_alloc_page(gfp, NULL); + pg = __dev_alloc_page(gfp); if (unlikely(!pg)) { q->alloc_failed++; break; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 0e8d5b72c9cc..cd538afa40dd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -602,6 +602,8 @@ static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl, */ BUG_ON(fl->avail + n > fl->size - FL_PER_EQ_UNIT); + gfp |= __GFP_NOWARN; + /* * If we support large pages, prefer large buffers and fail over to * small pages if we can't allocate large pages to satisfy the refill. @@ -612,8 +614,7 @@ static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl, goto alloc_small_pages; while (n) { - page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN, - FL_PG_ORDER); + page = __dev_alloc_pages(gfp, FL_PG_ORDER); if (unlikely(!page)) { /* * We've failed inour attempt to allocate a "large @@ -657,7 +658,7 @@ static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl, alloc_small_pages: while (n--) { - page = __skb_alloc_page(gfp | __GFP_NOWARN, NULL); + page = __dev_alloc_page(gfp); if (unlikely(!page)) { fl->alloc_failed++; break; -- GitLab From 5693d284dd718313ca2f63a189193d4189889183 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 11 Nov 2014 09:26:50 -0800 Subject: [PATCH 4375/9457] phonet: Replace calls to __skb_alloc_page with __dev_alloc_page Replace the calls to __skb_alloc_page that are passed NULL with calls to __dev_alloc_page. In addition remove __GFP_COLD flag from allocations as we only want it for the Rx buffer which is taken care of by __dev_alloc_skb, not for any secondary allocations such as the queue element transmit descriptors. Cc: Oliver Neukum Cc: Felipe Balbi Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/usb/cdc-phonet.c | 6 +++--- drivers/usb/gadget/function/f_phonet.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 2ec1500d0077..415ce8b882c6 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -130,7 +130,7 @@ static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) struct page *page; int err; - page = __skb_alloc_page(gfp_flags | __GFP_NOMEMALLOC, NULL); + page = __dev_alloc_page(gfp_flags | __GFP_NOMEMALLOC); if (!page) return -ENOMEM; @@ -212,7 +212,7 @@ static void rx_complete(struct urb *req) if (page) put_page(page); if (req) - rx_submit(pnd, req, GFP_ATOMIC | __GFP_COLD); + rx_submit(pnd, req, GFP_ATOMIC); } static int usbpn_close(struct net_device *dev); @@ -231,7 +231,7 @@ static int usbpn_open(struct net_device *dev) for (i = 0; i < rxq_size; i++) { struct urb *req = usb_alloc_urb(0, GFP_KERNEL); - if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { + if (!req || rx_submit(pnd, req, GFP_KERNEL)) { usb_free_urb(req); usbpn_close(dev); return -ENOMEM; diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index b9cfc1571d71..cde73974a52e 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -303,7 +303,7 @@ pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags) struct page *page; int err; - page = __skb_alloc_page(gfp_flags | __GFP_NOMEMALLOC, NULL); + page = __dev_alloc_page(gfp_flags | __GFP_NOMEMALLOC); if (!page) return -ENOMEM; @@ -377,7 +377,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) if (page) put_page(page); if (req) - pn_rx_submit(fp, req, GFP_ATOMIC | __GFP_COLD); + pn_rx_submit(fp, req, GFP_ATOMIC); } /*-------------------------------------------------------------------------*/ @@ -437,7 +437,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) netif_carrier_on(dev); for (i = 0; i < phonet_rxq_size; i++) - pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC | __GFP_COLD); + pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC); } spin_unlock(&port->lock); return 0; -- GitLab From 42b17f09550170fd238d76368e8fa8dfcc893082 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 11 Nov 2014 09:26:57 -0800 Subject: [PATCH 4376/9457] fm10k/igb/ixgbe: Replace __skb_alloc_page with dev_alloc_page The Intel drivers were pretty much just using the plain vanilla GFP flags in their calls to __skb_alloc_page so this change makes it so that they use dev_alloc_page which just uses GFP_ATOMIC for the gfp_flags value. Cc: Jeff Kirsher Cc: Matthew Vick Cc: Don Skidmore Signed-off-by: Alexander Duyck Acked-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index e645af412e76..73457ede53ec 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -83,7 +83,7 @@ static bool fm10k_alloc_mapped_page(struct fm10k_ring *rx_ring, return true; /* alloc new page for storage */ - page = alloc_page(GFP_ATOMIC | __GFP_COLD); + page = dev_alloc_page(); if (unlikely(!page)) { rx_ring->rx_stats.alloc_failed++; return false; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index a2d72a87cbde..1e35fae7a62b 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6988,7 +6988,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, return true; /* alloc new page for storage */ - page = __skb_alloc_page(GFP_ATOMIC | __GFP_COLD, NULL); + page = dev_alloc_page(); if (unlikely(!page)) { rx_ring->rx_stats.alloc_failed++; return false; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index a5ca877eac1a..f5fcba4f9d21 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1444,8 +1444,7 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = __skb_alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, - bi->skb, ixgbe_rx_pg_order(rx_ring)); + page = dev_alloc_pages(ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; return false; -- GitLab From 160d2aba550b23c6a538158511d5adccc400f04c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 11 Nov 2014 09:27:05 -0800 Subject: [PATCH 4377/9457] net: Remove __skb_alloc_page and __skb_alloc_pages Remove the two functions which are now dead code. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- include/linux/skbuff.h | 43 ------------------------------------------ 1 file changed, 43 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 2e5221f1ec72..73c370e615de 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2232,49 +2232,6 @@ static inline struct page *dev_alloc_page(void) return __dev_alloc_page(GFP_ATOMIC); } -/** - * __skb_alloc_pages - allocate pages for ps-rx on a skb and preserve pfmemalloc data - * @gfp_mask: alloc_pages_node mask. Set __GFP_NOMEMALLOC if not for network packet RX - * @skb: skb to set pfmemalloc on if __GFP_MEMALLOC is used - * @order: size of the allocation - * - * Allocate a new page. - * - * %NULL is returned if there is no free memory. -*/ -static inline struct page *__skb_alloc_pages(gfp_t gfp_mask, - struct sk_buff *skb, - unsigned int order) -{ - struct page *page; - - gfp_mask |= __GFP_COLD; - - if (!(gfp_mask & __GFP_NOMEMALLOC)) - gfp_mask |= __GFP_MEMALLOC; - - page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, order); - if (skb && page && page->pfmemalloc) - skb->pfmemalloc = true; - - return page; -} - -/** - * __skb_alloc_page - allocate a page for ps-rx for a given skb and preserve pfmemalloc data - * @gfp_mask: alloc_pages_node mask. Set __GFP_NOMEMALLOC if not for network packet RX - * @skb: skb to set pfmemalloc on if __GFP_MEMALLOC is used - * - * Allocate a new page. - * - * %NULL is returned if there is no free memory. - */ -static inline struct page *__skb_alloc_page(gfp_t gfp_mask, - struct sk_buff *skb) -{ - return __skb_alloc_pages(gfp_mask, skb, 0); -} - /** * skb_propagate_pfmemalloc - Propagate pfmemalloc if skb is allocated after RX page * @page: The page that was allocated from skb_alloc_page -- GitLab From 608b286d1ddf38a7ceb624d2b689af095816d91c Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 6 Nov 2014 11:38:27 +0800 Subject: [PATCH 4378/9457] powerpc/powernv: Add OPAL IPMI interface Recent OPAL firmare adds a couple of functions to send and receive IPMI messages: https://github.com/open-power/skiboot/commit/b2a374da This change updates the token list and wrappers to suit, and adds the platform devices for any IPMI interfaces. Signed-off-by: Jeremy Kerr Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal.h | 17 +++++++++++++++++ arch/powerpc/platforms/powernv/opal-wrappers.S | 2 ++ arch/powerpc/platforms/powernv/opal.c | 14 ++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 9124b0ede1fc..5d073e50cac8 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -154,6 +154,8 @@ struct opal_sg_list { #define OPAL_HANDLE_HMI 98 #define OPAL_REGISTER_DUMP_REGION 101 #define OPAL_UNREGISTER_DUMP_REGION 102 +#define OPAL_IPMI_SEND 107 +#define OPAL_IPMI_RECV 108 #ifndef __ASSEMBLY__ @@ -452,6 +454,17 @@ struct opal_msg { __be64 params[8]; }; +enum { + OPAL_IPMI_MSG_FORMAT_VERSION_1 = 1, +}; + +struct opal_ipmi_msg { + uint8_t version; + uint8_t netfn; + uint8_t cmd; + uint8_t data[]; +}; + struct opal_machine_check_event { enum OpalMCE_Version version:8; /* 0x00 */ uint8_t in_use; /* 0x01 */ @@ -963,6 +976,10 @@ int64_t opal_handle_hmi(void); int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end); int64_t opal_unregister_dump_region(uint32_t id); int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t pe_number); +int64_t opal_ipmi_send(uint64_t interface, struct opal_ipmi_msg *msg, + uint64_t msg_len); +int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg, + uint64_t *msg_len); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index feb549aa3eea..4f4e4009c289 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -250,3 +250,5 @@ OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE); +OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); +OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index d019b081df9d..0297702e8ae9 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -644,6 +644,16 @@ static void __init opal_dump_region_init(void) pr_warn("DUMP: Failed to register kernel log buffer. " "rc = %d\n", rc); } + +static void opal_ipmi_init(struct device_node *opal_node) +{ + struct device_node *np; + + for_each_child_of_node(opal_node, np) + if (of_device_is_compatible(np, "ibm,opal-ipmi")) + of_platform_device_create(np, NULL, NULL); +} + static int __init opal_init(void) { struct device_node *np, *consoles; @@ -707,6 +717,8 @@ static int __init opal_init(void) opal_msglog_init(); } + opal_ipmi_init(opal_node); + return 0; } machine_subsys_initcall(powernv, opal_init); @@ -742,6 +754,8 @@ void opal_shutdown(void) /* Export this so that test modules can use it */ EXPORT_SYMBOL_GPL(opal_invalid_call); +EXPORT_SYMBOL_GPL(opal_ipmi_send); +EXPORT_SYMBOL_GPL(opal_ipmi_recv); /* Convert a region of vmalloc memory to an opal sg list */ struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, -- GitLab From e7a7a65ed2e90c41341aafef9458d0aa8143a558 Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Tue, 11 Nov 2014 12:50:22 +0800 Subject: [PATCH 4379/9457] powerpc: Fix comment typos in arch/powerpc/include/asm/bitops.h In arch/powerpc/include/asm/bitops.h, the comments about bit numbers in large (> 1 word) bitmaps have two typos: - On ppc64 system, the LSB of the 4th word should be bit 192 rather than 196, because if it's bit 196, bit 192-195 will be missing in the bitmap. - On ppc32 system, the LSB of the second word should be bit 32 rather than 31, because bit 31 is already in the first word. This patch fixes these typos. Signed-off-by: Boqun Feng Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/bitops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index c633f058ba43..59abc620f8e8 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -14,9 +14,9 @@ * * The bitop functions are defined to work on unsigned longs, so for a * ppc64 system the bits end up numbered: - * |63..............0|127............64|191...........128|255...........196| + * |63..............0|127............64|191...........128|255...........192| * and on ppc32: - * |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| + * |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224| * * There are a few little-endian macros used mostly for filesystem * bitmaps, these work on similar bit arrays layouts, but -- GitLab From d8ee6f34fdd28ade6b7b3a9be175bc5c0c3cfb38 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 12 Nov 2014 16:54:54 +1100 Subject: [PATCH 4380/9457] powerpc/xmon: Fix build when 4xx=y and 44x=n dump_tlb_44x() is only defined when 44x=y, but the ifdef in xmon.c checks for 4xx, leading to a build failure: arch/powerpc/xmon/xmon.c:912:4: error: implicit declaration of function 'dump_tlb_44x' Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 506d25681fe3..ef18021d52e1 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -907,7 +907,7 @@ cmds(struct pt_regs *excp) case 'u': dump_segments(); break; -#elif defined(CONFIG_4xx) +#elif defined(CONFIG_44x) case 'u': dump_tlb_44x(); break; -- GitLab From 5ee3229c87d396cab3c2dfc335b90320cc4a2f42 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 11 Nov 2014 19:38:59 -0500 Subject: [PATCH 4381/9457] drm: export atomic wait_for_vblanks helper (v2) v1: original v2: danvet's kerneldoc nitpicks Signed-off-by: Rob Clark Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic_helper.c | 17 ++++++++++++++--- include/drm/drm_atomic_helper.h | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ca839bd9bb0d..fad2b932cf72 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -754,8 +754,18 @@ static void wait_for_fences(struct drm_device *dev, } } -static void -wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state) +/** + * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs + * @dev: DRM device + * @old_state: atomic state object with old state structures + * + * Helper to, after atomic commit, wait for vblanks on all effected + * crtcs (ie. before cleaning up old framebuffers using + * drm_atomic_helper_cleanup_planes()) + */ +void +drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, + struct drm_atomic_state *old_state) { struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; @@ -800,6 +810,7 @@ wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state) drm_crtc_vblank_put(crtc); } } +EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks); /** * drm_atomic_helper_commit - commit validated state object @@ -859,7 +870,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, drm_atomic_helper_commit_post_planes(dev, state); - wait_for_vblanks(dev, state); + drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 67e3c4645ae0..64b4e91b93bc 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -34,6 +34,9 @@ int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool async); +void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, + struct drm_atomic_state *old_state); + void drm_atomic_helper_commit_pre_planes(struct drm_device *dev, struct drm_atomic_state *state); void drm_atomic_helper_commit_post_planes(struct drm_device *dev, -- GitLab From 4d02e2de0e80a786452e70d7f3a20a50641e6620 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 11 Nov 2014 10:12:00 +0100 Subject: [PATCH 4382/9457] drm: Per-plane locking Turned out to be much simpler on top of my latest atomic stuff than what I've feared. Some details: - Drop the modeset_lock_all snakeoil in drm_plane_init. Same justification as for the equivalent change in drm_crtc_init done in commit d0fa1af40e784aaf7ebb7ba8a17b229bb3fa4c21 Author: Daniel Vetter Date: Mon Sep 8 09:02:49 2014 +0200 drm: Drop modeset locking from crtc init function Without these the drm_modeset_lock_init would fall over the exact same way. - Since the atomic core code wraps the locking switching it to per-plane locks was a one-line change. - For the legacy ioctls add a plane argument to the locking helper so that we can grab the right plane lock (cursor or primary). Since the universal cursor plane might not be there, or someone really crazy might forgoe the primary plane even accept NULL. - Add some locking WARN_ON to the atomic helpers for good paranoid measure and to check that it all works out. Tested on my exynos atomic hackfest with full lockdep checks and ww backoff injection. v2: I've forgotten about the load-detect code in i915. v3: Thierry reported that in latest 3.18-rc vmwgfx doesn't compile any more due to commit 21e88620aa21b48d4f62d29275e3e2944a5ea2b5 Author: Rob Clark Date: Thu Oct 30 13:39:04 2014 -0400 drm/vmwgfx: fix lock breakage Rebased and fix this up. Cc: Thierry Reding Signed-off-by: Daniel Vetter Reviewed-by: Sean Paul Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic.c | 2 +- drivers/gpu/drm/drm_atomic_helper.c | 4 +++ drivers/gpu/drm/drm_crtc.c | 9 +++--- drivers/gpu/drm/drm_modeset_lock.c | 43 +++++++++++++++++++++------- drivers/gpu/drm/i915/intel_display.c | 6 ++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +-- include/drm/drm_crtc.h | 2 ++ include/drm/drm_modeset_lock.h | 4 ++- 8 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index ed991ba66e21..ed22a719440f 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -244,7 +244,7 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, * grab all crtc locks. Once we have per-plane locks we must update this * to only take the plane mutex. */ - ret = drm_modeset_lock_all_crtcs(state->dev, state->acquire_ctx); + ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index fad2b932cf72..c0a07cba3aaa 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1006,6 +1006,8 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (!crtc) continue; + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + funcs = crtc->helper_private; if (!funcs || !funcs->atomic_begin) @@ -1021,6 +1023,8 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (!plane) continue; + WARN_ON(!drm_modeset_is_locked(&plane->mutex)); + funcs = plane->helper_private; if (!funcs || !funcs->atomic_update) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e6c169152bf1..3652ed8dda80 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1152,12 +1152,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, { int ret; - drm_modeset_lock_all(dev); - ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) goto out; + drm_modeset_lock_init(&plane->mutex); + plane->base.properties = &plane->properties; plane->dev = dev; plane->funcs = funcs; @@ -1185,7 +1185,6 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, plane->type); out: - drm_modeset_unlock_all(dev); return ret; } @@ -2809,7 +2808,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, * If this crtc has a universal cursor plane, call that plane's update * handler rather than using legacy cursor handlers. */ - drm_modeset_lock_crtc(crtc); + drm_modeset_lock_crtc(crtc, crtc->cursor); if (crtc->cursor) { ret = drm_mode_cursor_universal(crtc, req, file_priv); goto out; @@ -4598,7 +4597,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (!crtc) return -ENOENT; - drm_modeset_lock_crtc(crtc); + drm_modeset_lock_crtc(crtc, crtc->primary); if (crtc->primary->fb == NULL) { /* The framebuffer is currently unbound, presumably * due to a hotplug event, that userspace has not diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 474e4d12a2d8..51cc47d827d8 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -157,14 +157,20 @@ void drm_modeset_unlock_all(struct drm_device *dev) EXPORT_SYMBOL(drm_modeset_unlock_all); /** - * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx - * @crtc: drm crtc + * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx for a plane update + * @crtc: DRM CRTC + * @plane: DRM plane to be updated on @crtc + * + * This function locks the given crtc and plane (which should be either the + * primary or cursor plane) using a hidden acquire context. This is necessary so + * that drivers internally using the atomic interfaces can grab further locks + * with the lock acquire context. * - * This function locks the given crtc using a hidden acquire context. This is - * necessary so that drivers internally using the atomic interfaces can grab - * further locks with the lock acquire context. + * Note that @plane can be NULL, e.g. when the cursor support hasn't yet been + * converted to universal planes yet. */ -void drm_modeset_lock_crtc(struct drm_crtc *crtc) +void drm_modeset_lock_crtc(struct drm_crtc *crtc, + struct drm_plane *plane) { struct drm_modeset_acquire_ctx *ctx; int ret; @@ -180,6 +186,18 @@ void drm_modeset_lock_crtc(struct drm_crtc *crtc) if (ret) goto fail; + if (plane) { + ret = drm_modeset_lock(&plane->mutex, ctx); + if (ret) + goto fail; + + if (plane->crtc) { + ret = drm_modeset_lock(&plane->crtc->mutex, ctx); + if (ret) + goto fail; + } + } + WARN_ON(crtc->acquire_ctx); /* now we hold the locks, so now that it is safe, stash the @@ -437,15 +455,14 @@ void drm_modeset_unlock(struct drm_modeset_lock *lock) } EXPORT_SYMBOL(drm_modeset_unlock); -/* Temporary.. until we have sufficiently fine grained locking, there - * are a couple scenarios where it is convenient to grab all crtc locks. - * It is planned to remove this: - */ +/* In some legacy codepaths it's convenient to just grab all the crtc and plane + * related locks. */ int drm_modeset_lock_all_crtcs(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx) { struct drm_mode_config *config = &dev->mode_config; struct drm_crtc *crtc; + struct drm_plane *plane; int ret = 0; list_for_each_entry(crtc, &config->crtc_list, head) { @@ -454,6 +471,12 @@ int drm_modeset_lock_all_crtcs(struct drm_device *dev, return ret; } + list_for_each_entry(plane, &config->plane_list, head) { + ret = drm_modeset_lock(&plane->mutex, ctx); + if (ret) + return ret; + } + return 0; } EXPORT_SYMBOL(drm_modeset_lock_all_crtcs); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 31bb1d7acf9b..5fae12cf1072 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8728,6 +8728,9 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, crtc = encoder->crtc; ret = drm_modeset_lock(&crtc->mutex, ctx); + if (ret) + goto fail_unlock; + ret = drm_modeset_lock(&crtc->primary->mutex, ctx); if (ret) goto fail_unlock; @@ -8765,6 +8768,9 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, } ret = drm_modeset_lock(&crtc->mutex, ctx); + if (ret) + goto fail_unlock; + ret = drm_modeset_lock(&crtc->primary->mutex, ctx); if (ret) goto fail_unlock; intel_encoder->new_crtc = to_intel_crtc(crtc); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 941a7bc0b791..3725b521d931 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -252,7 +252,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ret = 0; out: drm_modeset_unlock_all(dev_priv->dev); - drm_modeset_lock_crtc(crtc); + drm_modeset_lock_crtc(crtc, crtc->cursor); return ret; } @@ -281,7 +281,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) du->cursor_y + du->hotspot_y); drm_modeset_unlock_all(dev_priv->dev); - drm_modeset_lock_crtc(crtc); + drm_modeset_lock_crtc(crtc, crtc->cursor); return 0; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bc1cc3ce05c4..cbb475654b1c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -751,6 +751,8 @@ struct drm_plane { struct drm_device *dev; struct list_head head; + struct drm_modeset_lock mutex; + struct drm_mode_object base; uint32_t possible_crtcs; diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index 28931a23d96c..70595ff565ba 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -127,11 +127,13 @@ void drm_modeset_unlock(struct drm_modeset_lock *lock); struct drm_device; struct drm_crtc; +struct drm_plane; void drm_modeset_lock_all(struct drm_device *dev); int __drm_modeset_lock_all(struct drm_device *dev, bool trylock); void drm_modeset_unlock_all(struct drm_device *dev); -void drm_modeset_lock_crtc(struct drm_crtc *crtc); +void drm_modeset_lock_crtc(struct drm_crtc *crtc, + struct drm_plane *plane); void drm_modeset_unlock_crtc(struct drm_crtc *crtc); void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); struct drm_modeset_acquire_ctx * -- GitLab From fcf93f6948c3c29fd414bc00f1f713c501dfd22e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 12 Nov 2014 08:45:01 +0100 Subject: [PATCH 4383/9457] drm: More specific locking for get* ioctls Motivated by the per-plane locking I've gone through all the get* ioctls and reduced the locking to the bare minimum required. v2: Rebase and make it compile ... v3: Review from Sean: - Simplify return handling in getplane_res. - Add a comment to getplane_res that the plane list is invariant and can be walked locklessly. v4: Actually git add. Cc: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 58 +++++++++++++++----------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3652ed8dda80..2beb219df1bd 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1743,7 +1743,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, card_res->count_fbs = fb_count; mutex_unlock(&file_priv->fbs_lock); - drm_modeset_lock_all(dev); + /* mode_config.mutex protects the connector list against e.g. DP MST + * connector hot-adding. CRTC/Plane lists are invariant. */ + mutex_lock(&dev->mode_config.mutex); if (!drm_is_primary_client(file_priv)) { mode_group = NULL; @@ -1863,7 +1865,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, card_res->count_connectors, card_res->count_encoders); out: - drm_modeset_unlock_all(dev); + mutex_unlock(&dev->mode_config.mutex); return ret; } @@ -1890,14 +1892,11 @@ int drm_mode_getcrtc(struct drm_device *dev, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - drm_modeset_lock_all(dev); - crtc = drm_crtc_find(dev, crtc_resp->crtc_id); - if (!crtc) { - ret = -ENOENT; - goto out; - } + if (!crtc) + return -ENOENT; + drm_modeset_lock_crtc(crtc, crtc->primary); crtc_resp->x = crtc->x; crtc_resp->y = crtc->y; crtc_resp->gamma_size = crtc->gamma_size; @@ -1914,9 +1913,8 @@ int drm_mode_getcrtc(struct drm_device *dev, } else { crtc_resp->mode_valid = 0; } + drm_modeset_unlock_crtc(crtc); -out: - drm_modeset_unlock_all(dev); return ret; } @@ -2100,24 +2098,22 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - drm_modeset_lock_all(dev); encoder = drm_encoder_find(dev, enc_resp->encoder_id); - if (!encoder) { - ret = -ENOENT; - goto out; - } + if (!encoder) + return -ENOENT; + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); if (encoder->crtc) enc_resp->crtc_id = encoder->crtc->base.id; else enc_resp->crtc_id = 0; + drm_modeset_unlock(&dev->mode_config.connection_mutex); + enc_resp->encoder_type = encoder->encoder_type; enc_resp->encoder_id = encoder->base.id; enc_resp->possible_crtcs = encoder->possible_crtcs; enc_resp->possible_clones = encoder->possible_clones; -out: - drm_modeset_unlock_all(dev); return ret; } @@ -2141,13 +2137,12 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, struct drm_mode_config *config; struct drm_plane *plane; uint32_t __user *plane_ptr; - int copied = 0, ret = 0; + int copied = 0; unsigned num_planes; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - drm_modeset_lock_all(dev); config = &dev->mode_config; if (file_priv->universal_planes) @@ -2163,6 +2158,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, (plane_resp->count_planes >= num_planes)) { plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; + /* Plane lists are invariant, no locking needed. */ list_for_each_entry(plane, &config->plane_list, head) { /* * Unless userspace set the 'universal planes' @@ -2172,18 +2168,14 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, !file_priv->universal_planes) continue; - if (put_user(plane->base.id, plane_ptr + copied)) { - ret = -EFAULT; - goto out; - } + if (put_user(plane->base.id, plane_ptr + copied)) + return -EFAULT; copied++; } } plane_resp->count_planes = num_planes; -out: - drm_modeset_unlock_all(dev); - return ret; + return 0; } /** @@ -2210,13 +2202,11 @@ int drm_mode_getplane(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - drm_modeset_lock_all(dev); plane = drm_plane_find(dev, plane_resp->plane_id); - if (!plane) { - ret = -ENOENT; - goto out; - } + if (!plane) + return -ENOENT; + drm_modeset_lock(&plane->mutex, NULL); if (plane->crtc) plane_resp->crtc_id = plane->crtc->base.id; else @@ -2226,6 +2216,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, plane_resp->fb_id = plane->fb->base.id; else plane_resp->fb_id = 0; + drm_modeset_unlock(&plane->mutex); plane_resp->plane_id = plane->base.id; plane_resp->possible_crtcs = plane->possible_crtcs; @@ -2241,14 +2232,11 @@ int drm_mode_getplane(struct drm_device *dev, void *data, if (copy_to_user(format_ptr, plane->format_types, sizeof(uint32_t) * plane->format_count)) { - ret = -EFAULT; - goto out; + return -EFAULT; } } plane_resp->count_format_types = plane->format_count; -out: - drm_modeset_unlock_all(dev); return ret; } -- GitLab From f03567040cbf874834c9e3e52b72fdcb672b9bbb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 12 Nov 2014 09:15:50 +0200 Subject: [PATCH 4384/9457] Bluetooth: Fix l2cap_sock_teardown_cb lockdep warning Any code calling bt_accept_dequeue() to get a new child socket from a server socket should use lock_sock_nested to avoid lockdep warnings due to the parent and child sockets being locked at the same time. The l2cap_sock_accept() function is already doing this correctly but a second place calling bt_accept_dequeue() is the code path from l2cap_sock_teardown_cb() that calls l2cap_sock_cleanup_listen(). This patch fixes the proper nested locking annotation and thereby avoids the following style of lockdep warning. [ +0.000224] [ INFO: possible recursive locking detected ] [ +0.000222] 3.17.0+ #1153 Not tainted [ +0.000130] --------------------------------------------- [ +0.000227] l2cap-tester/562 is trying to acquire lock: [ +0.000210] (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [] bt_accept_dequeue+0x68/0x11b [ +0.000467] but task is already holding lock: [ +0.000186] (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [] lock_sock+0xa/0xc [ +0.000421] other info that might help us debug this: [ +0.000199] Possible unsafe locking scenario: [ +0.000117] CPU0 [ +0.000000] ---- [ +0.000000] lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); [ +0.000000] lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); [ +0.000000] *** DEADLOCK *** Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 31f106e61ca2..ad1cf82fee02 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1246,7 +1246,7 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) struct sock *sk = chan->data; struct sock *parent; - lock_sock(sk); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); parent = bt_sk(sk)->parent; -- GitLab From a930430b047a0cc118bfc47ca54fcdfbadf091d2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 12 Nov 2014 09:17:08 +0200 Subject: [PATCH 4385/9457] Bluetooth: Remove unnecessary hci_dev_lock/unlock in smp.c The mgmt_user_passkey_request and related functions do not do anything else except read access to hdev->id. This member never changes after the hdev creation so there is no need to acquire a lock to read it. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3ebf65b50881..3d38553eb526 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -514,8 +514,6 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, set_bit(SMP_FLAG_TK_VALID, &smp->flags); } - hci_dev_lock(hcon->hdev); - if (method == REQ_PASSKEY) ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type); @@ -528,8 +526,6 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, hcon->type, hcon->dst_type, passkey, 0); - hci_dev_unlock(hcon->hdev); - return ret; } -- GitLab From f354d733f680ec9f9afed0d0fa6429ed259f0a52 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Fri, 7 Nov 2014 14:07:41 +0200 Subject: [PATCH 4386/9457] drm/i915: Plug memory leak in intel_shared_dpll_start_config() The cleanup path would reset pll->new_config to NULL but wouldn't free the allocated memory. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3f4a5b83bea4..ea607f340c76 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3953,6 +3953,7 @@ static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv, cleanup: while (--i >= 0) { pll = &dev_priv->shared_dplls[i]; + kfree(pll->new_config); pll->new_config = NULL; } -- GitLab From f6c6339d5e945975066cb452c78a7cbe89413f37 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 12 Nov 2014 11:50:16 +0100 Subject: [PATCH 4387/9457] netfilter: fix unmet dependencies in NETFILTER_XT_TARGET_REDIRECT warning: (NETFILTER_XT_TARGET_REDIRECT) selects NF_NAT_REDIRECT_IPV4 which has unmet direct dependencies (NET && INET && NETFILTER && NF_NAT_IPV4) warning: (NETFILTER_XT_TARGET_REDIRECT) selects NF_NAT_REDIRECT_IPV6 which has unmet direct dependencies (NET && INET && IPV6 && NETFILTER && NF_NAT_IPV6) Fixes: 8b13edd ("netfilter: refactor NAT redirect IPv4 to use it from nf_tables") Fixes: 9de920e ("netfilter: refactor NAT redirect IPv6 code to use it from nf_tables") Reported-by: kbuild test robot Signed-off-by: Pablo Neira Ayuso --- net/netfilter/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 373486ae4159..57f15a9aa481 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -844,8 +844,8 @@ config NETFILTER_XT_TARGET_RATEEST config NETFILTER_XT_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT - select NF_NAT_REDIRECT_IPV4 - select NF_NAT_REDIRECT_IPV6 if IP6_NF_IPTABLES + select NF_NAT_REDIRECT_IPV4 if NF_NAT_IPV4 + select NF_NAT_REDIRECT_IPV6 if NF_NAT_IPV6 ---help--- REDIRECT is a special case of NAT: all incoming connections are mapped onto the incoming interface's address, causing the packets to -- GitLab From baf4750d92cdfb63d6535f7166c6189d07407b65 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 12 Nov 2014 11:56:47 +0100 Subject: [PATCH 4388/9457] netfilter: nft_redir: fix sparse warnings >> net/netfilter/nft_redir.c:39:26: sparse: incorrect type in assignment (different base types) net/netfilter/nft_redir.c:39:26: expected unsigned int [unsigned] [usertype] nla_be32 net/netfilter/nft_redir.c:39:26: got restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:40:40: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:46:34: sparse: incorrect type in assignment (different base types) net/netfilter/nft_redir.c:46:34: expected unsigned int [unsigned] [usertype] nla_be32 net/netfilter/nft_redir.c:46:34: got restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 >> net/netfilter/nft_redir.c:47:48: sparse: cast to restricted __be32 Fixes: e9105f1 ("netfilter: nf_tables: add new expression nft_redir") Reported-by: kbuild test robot Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_redir.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c index e27b4e35718a..9e8093f28311 100644 --- a/net/netfilter/nft_redir.c +++ b/net/netfilter/nft_redir.c @@ -28,7 +28,6 @@ int nft_redir_init(const struct nft_ctx *ctx, const struct nlattr * const tb[]) { struct nft_redir *priv = nft_expr_priv(expr); - u32 nla_be32; int err; err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); @@ -36,15 +35,17 @@ int nft_redir_init(const struct nft_ctx *ctx, return err; if (tb[NFTA_REDIR_REG_PROTO_MIN]) { - nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]); - priv->sreg_proto_min = ntohl(nla_be32); + priv->sreg_proto_min = + ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN])); + err = nft_validate_input_register(priv->sreg_proto_min); if (err < 0) return err; if (tb[NFTA_REDIR_REG_PROTO_MAX]) { - nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]); - priv->sreg_proto_max = ntohl(nla_be32); + priv->sreg_proto_max = + ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX])); + err = nft_validate_input_register(priv->sreg_proto_max); if (err < 0) return err; -- GitLab From f6577a5fa15d82217ca73c74cd2dcbc0f6c781dd Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Fri, 7 Nov 2014 18:25:18 -0800 Subject: [PATCH 4389/9457] x86, kvm, vmx: Always use LOAD_IA32_EFER if available At least on Sandy Bridge, letting the CPU switch IA32_EFER is much faster than switching it manually. I benchmarked this using the vmexit kvm-unit-test (single run, but GOAL multiplied by 5 to do more iterations): Test Before After Change cpuid 2000 1932 -3.40% vmcall 1914 1817 -5.07% mov_from_cr8 13 13 0.00% mov_to_cr8 19 19 0.00% inl_from_pmtimer 19164 10619 -44.59% inl_from_qemu 15662 10302 -34.22% inl_from_kernel 3916 3802 -2.91% outl_to_kernel 2230 2194 -1.61% mov_dr 172 176 2.33% ipi (skipped) (skipped) ipi+halt (skipped) (skipped) ple-round-robin 13 13 0.00% wr_tsc_adjust_msr 1920 1845 -3.91% rd_tsc_adjust_msr 1892 1814 -4.12% mmio-no-eventfd:pci-mem 16394 11165 -31.90% mmio-wildcard-eventfd:pci-mem 4607 4645 0.82% mmio-datamatch-eventfd:pci-mem 4601 4610 0.20% portio-no-eventfd:pci-io 11507 7942 -30.98% portio-wildcard-eventfd:pci-io 2239 2225 -0.63% portio-datamatch-eventfd:pci-io 2250 2234 -0.71% I haven't explicitly computed the significance of these numbers, but this isn't subtle. Signed-off-by: Andy Lutomirski [The results were reproducible on all of Nehalem, Sandy Bridge and Ivy Bridge. The slowness of manual switching is because writing to EFER with WRMSR triggers a TLB flush, even if the only bit you're touching is SCE (so the page table format is not affected). Doing the write as part of vmentry/vmexit, instead, does not flush the TLB, probably because all processors that have EPT also have VPID. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 284f5c2fdf0b..0d25fc16d98b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1662,8 +1662,14 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) vmx->guest_msrs[efer_offset].mask = ~ignore_bits; clear_atomic_switch_msr(vmx, MSR_EFER); - /* On ept, can't emulate nx, and must switch nx atomically */ - if (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX)) { + + /* + * On EPT, we can't emulate NX, so we must switch EFER atomically. + * On CPUs that support "load IA32_EFER", always switch EFER + * atomically, since it's faster than switching it manually. + */ + if (cpu_has_load_ia32_efer || + (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) { guest_efer = vmx->vcpu.arch.efer; if (!(guest_efer & EFER_LMA)) guest_efer &= ~EFER_LME; -- GitLab From 630d2d0de6b113748ce08d5f69e094eeed24accc Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 30 May 2014 16:26:22 +0530 Subject: [PATCH 4390/9457] OMAPDSS: DPI: Use DPI driver data DPI related data is currently a static global struct parameter. It is accessed directly by functions in the driver. This method won't work if we want the driver to support multiple DPI instances. Create struct dpi_data, and pass its pointer to functions which need to use it. We still have a static instance defined for dpi_data, which is accessed by top level DPI ops. This will be removed when the driver dynamically allocates dpi_data for each DPI instance. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/dpi.c | 187 ++++++++++++++++------------ 1 file changed, 107 insertions(+), 80 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index 4a3363dae74a..35285d8395b5 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -37,7 +37,7 @@ #include "dss.h" #include "dss_features.h" -static struct { +struct dpi_data { struct platform_device *pdev; struct regulator *vdds_dsi_reg; @@ -52,7 +52,9 @@ static struct { struct omap_dss_device output; bool port_initialized; -} dpi; +}; + +static struct dpi_data dpi_data; static struct platform_device *dpi_get_dsidev(enum omap_channel channel) { @@ -200,15 +202,16 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data) dpi_calc_dispc_cb, ctx); } -static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) +static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck, + struct dpi_clk_calc_ctx *ctx) { unsigned long clkin; unsigned long pll_min, pll_max; - clkin = dsi_get_pll_clkin(dpi.dsidev); + clkin = dsi_get_pll_clkin(dpi->dsidev); memset(ctx, 0, sizeof(*ctx)); - ctx->dsidev = dpi.dsidev; + ctx->dsidev = dpi->dsidev; ctx->pck_min = pck - 1000; ctx->pck_max = pck + 1000; ctx->dsi_cinfo.clkin = clkin; @@ -216,7 +219,7 @@ static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) pll_min = 0; pll_max = 0; - return dsi_pll_calc(dpi.dsidev, clkin, + return dsi_pll_calc(dpi->dsidev, clkin, pll_min, pll_max, dpi_calc_pll_cb, ctx); } @@ -252,7 +255,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) -static int dpi_set_dsi_clk(enum omap_channel channel, +static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel, unsigned long pck_req, unsigned long *fck, int *lck_div, int *pck_div) { @@ -260,18 +263,18 @@ static int dpi_set_dsi_clk(enum omap_channel channel, int r; bool ok; - ok = dpi_dsi_clk_calc(pck_req, &ctx); + ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx); if (!ok) return -EINVAL; - r = dsi_pll_set_clock_div(dpi.dsidev, &ctx.dsi_cinfo); + r = dsi_pll_set_clock_div(dpi->dsidev, &ctx.dsi_cinfo); if (r) return r; dss_select_lcd_clk_source(channel, dpi_get_alt_clk_src(channel)); - dpi.mgr_config.clock_info = ctx.dispc_cinfo; + dpi->mgr_config.clock_info = ctx.dispc_cinfo; *fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk; *lck_div = ctx.dispc_cinfo.lck_div; @@ -280,8 +283,8 @@ static int dpi_set_dsi_clk(enum omap_channel channel, return 0; } -static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, - int *lck_div, int *pck_div) +static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req, + unsigned long *fck, int *lck_div, int *pck_div) { struct dpi_clk_calc_ctx ctx; int r; @@ -295,7 +298,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, if (r) return r; - dpi.mgr_config.clock_info = ctx.dispc_cinfo; + dpi->mgr_config.clock_info = ctx.dispc_cinfo; *fck = ctx.fck; *lck_div = ctx.dispc_cinfo.lck_div; @@ -304,19 +307,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, return 0; } -static int dpi_set_mode(struct omap_overlay_manager *mgr) +static int dpi_set_mode(struct dpi_data *dpi) { - struct omap_video_timings *t = &dpi.timings; + struct omap_dss_device *out = &dpi->output; + struct omap_overlay_manager *mgr = out->manager; + struct omap_video_timings *t = &dpi->timings; int lck_div = 0, pck_div = 0; unsigned long fck = 0; unsigned long pck; int r = 0; - if (dpi.dsidev) - r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck, + if (dpi->dsidev) + r = dpi_set_dsi_clk(dpi, mgr->id, t->pixelclock, &fck, &lck_div, &pck_div); else - r = dpi_set_dispc_clk(t->pixelclock, &fck, + r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck, &lck_div, &pck_div); if (r) return r; @@ -335,28 +340,32 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr) return 0; } -static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr) +static void dpi_config_lcd_manager(struct dpi_data *dpi) { - dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; + struct omap_dss_device *out = &dpi->output; + struct omap_overlay_manager *mgr = out->manager; + + dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; - dpi.mgr_config.stallmode = false; - dpi.mgr_config.fifohandcheck = false; + dpi->mgr_config.stallmode = false; + dpi->mgr_config.fifohandcheck = false; - dpi.mgr_config.video_port_width = dpi.data_lines; + dpi->mgr_config.video_port_width = dpi->data_lines; - dpi.mgr_config.lcden_sig_polarity = 0; + dpi->mgr_config.lcden_sig_polarity = 0; - dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); + dss_mgr_set_lcd_config(mgr, &dpi->mgr_config); } static int dpi_display_enable(struct omap_dss_device *dssdev) { - struct omap_dss_device *out = &dpi.output; + struct dpi_data *dpi = &dpi_data; + struct omap_dss_device *out = &dpi->output; int r; - mutex_lock(&dpi.lock); + mutex_lock(&dpi->lock); - if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) { + if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) { DSSERR("no VDSS_DSI regulator\n"); r = -ENODEV; goto err_no_reg; @@ -369,7 +378,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) } if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { - r = regulator_enable(dpi.vdds_dsi_reg); + r = regulator_enable(dpi->vdds_dsi_reg); if (r) goto err_reg_enable; } @@ -382,21 +391,21 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_src_sel; - if (dpi.dsidev) { - r = dsi_runtime_get(dpi.dsidev); + if (dpi->dsidev) { + r = dsi_runtime_get(dpi->dsidev); if (r) goto err_get_dsi; - r = dsi_pll_init(dpi.dsidev, 0, 1); + r = dsi_pll_init(dpi->dsidev, 0, 1); if (r) goto err_dsi_pll_init; } - r = dpi_set_mode(out->manager); + r = dpi_set_mode(dpi); if (r) goto err_set_mode; - dpi_config_lcd_manager(out->manager); + dpi_config_lcd_manager(dpi); mdelay(2); @@ -404,78 +413,84 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_mgr_enable; - mutex_unlock(&dpi.lock); + mutex_unlock(&dpi->lock); return 0; err_mgr_enable: err_set_mode: - if (dpi.dsidev) - dsi_pll_uninit(dpi.dsidev, true); + if (dpi->dsidev) + dsi_pll_uninit(dpi->dsidev, true); err_dsi_pll_init: - if (dpi.dsidev) - dsi_runtime_put(dpi.dsidev); + if (dpi->dsidev) + dsi_runtime_put(dpi->dsidev); err_get_dsi: err_src_sel: dispc_runtime_put(); err_get_dispc: if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) - regulator_disable(dpi.vdds_dsi_reg); + regulator_disable(dpi->vdds_dsi_reg); err_reg_enable: err_no_out_mgr: err_no_reg: - mutex_unlock(&dpi.lock); + mutex_unlock(&dpi->lock); return r; } static void dpi_display_disable(struct omap_dss_device *dssdev) { - struct omap_overlay_manager *mgr = dpi.output.manager; + struct dpi_data *dpi = &dpi_data; + struct omap_overlay_manager *mgr = dpi->output.manager; - mutex_lock(&dpi.lock); + mutex_lock(&dpi->lock); dss_mgr_disable(mgr); - if (dpi.dsidev) { + if (dpi->dsidev) { dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); - dsi_pll_uninit(dpi.dsidev, true); - dsi_runtime_put(dpi.dsidev); + dsi_pll_uninit(dpi->dsidev, true); + dsi_runtime_put(dpi->dsidev); } dispc_runtime_put(); if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) - regulator_disable(dpi.vdds_dsi_reg); + regulator_disable(dpi->vdds_dsi_reg); - mutex_unlock(&dpi.lock); + mutex_unlock(&dpi->lock); } static void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { + struct dpi_data *dpi = &dpi_data; + DSSDBG("dpi_set_timings\n"); - mutex_lock(&dpi.lock); + mutex_lock(&dpi->lock); - dpi.timings = *timings; + dpi->timings = *timings; - mutex_unlock(&dpi.lock); + mutex_unlock(&dpi->lock); } static void dpi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - mutex_lock(&dpi.lock); + struct dpi_data *dpi = &dpi_data; + + mutex_lock(&dpi->lock); - *timings = dpi.timings; + *timings = dpi->timings; - mutex_unlock(&dpi.lock); + mutex_unlock(&dpi->lock); } static int dpi_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct omap_overlay_manager *mgr = dpi.output.manager; + struct dpi_data *dpi = &dpi_data; + struct omap_overlay_manager *mgr = dpi->output.manager; int lck_div, pck_div; unsigned long fck; unsigned long pck; @@ -488,8 +503,8 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, if (timings->pixelclock == 0) return -EINVAL; - if (dpi.dsidev) { - ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx); + if (dpi->dsidev) { + ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx); if (!ok) return -EINVAL; @@ -514,11 +529,13 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) { - mutex_lock(&dpi.lock); + struct dpi_data *dpi = &dpi_data; - dpi.data_lines = data_lines; + mutex_lock(&dpi->lock); - mutex_unlock(&dpi.lock); + dpi->data_lines = data_lines; + + mutex_unlock(&dpi->lock); } static int dpi_verify_dsi_pll(struct platform_device *dsidev) @@ -543,36 +560,36 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev) return 0; } -static int dpi_init_regulator(void) +static int dpi_init_regulator(struct dpi_data *dpi) { struct regulator *vdds_dsi; if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) return 0; - if (dpi.vdds_dsi_reg) + if (dpi->vdds_dsi_reg) return 0; - vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); + vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi"); if (IS_ERR(vdds_dsi)) { if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) DSSERR("can't get VDDS_DSI regulator\n"); return PTR_ERR(vdds_dsi); } - dpi.vdds_dsi_reg = vdds_dsi; + dpi->vdds_dsi_reg = vdds_dsi; return 0; } -static void dpi_init_pll(void) +static void dpi_init_pll(struct dpi_data *dpi) { struct platform_device *dsidev; - if (dpi.dsidev) + if (dpi->dsidev) return; - dsidev = dpi_get_dsidev(dpi.output.dispc_channel); + dsidev = dpi_get_dsidev(dpi->output.dispc_channel); if (!dsidev) return; @@ -581,7 +598,7 @@ static void dpi_init_pll(void) return; } - dpi.dsidev = dsidev; + dpi->dsidev = dsidev; } /* @@ -618,14 +635,15 @@ static enum omap_channel dpi_get_channel(void) static int dpi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { + struct dpi_data *dpi = &dpi_data; struct omap_overlay_manager *mgr; int r; - r = dpi_init_regulator(); + r = dpi_init_regulator(dpi); if (r) return r; - dpi_init_pll(); + dpi_init_pll(dpi); mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); if (!mgr) @@ -676,7 +694,8 @@ static const struct omapdss_dpi_ops dpi_ops = { static void dpi_init_output(struct platform_device *pdev) { - struct omap_dss_device *out = &dpi.output; + struct dpi_data *dpi = &dpi_data; + struct omap_dss_device *out = &dpi->output; out->dev = &pdev->dev; out->id = OMAP_DSS_OUTPUT_DPI; @@ -691,16 +710,21 @@ static void dpi_init_output(struct platform_device *pdev) static void __exit dpi_uninit_output(struct platform_device *pdev) { - struct omap_dss_device *out = &dpi.output; + struct dpi_data *dpi = &dpi_data; + struct omap_dss_device *out = &dpi->output; omapdss_unregister_output(out); } static int omap_dpi_probe(struct platform_device *pdev) { - dpi.pdev = pdev; + struct dpi_data *dpi = &dpi_data; + + dpi->pdev = pdev; - mutex_init(&dpi.lock); + dev_set_drvdata(&pdev->dev, dpi); + + mutex_init(&dpi->lock); dpi_init_output(pdev); @@ -736,6 +760,7 @@ void __exit dpi_uninit_platform_driver(void) int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) { + struct dpi_data *dpi = &dpi_data; struct device_node *ep; u32 datalines; int r; @@ -750,17 +775,17 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) goto err_datalines; } - dpi.data_lines = datalines; + dpi->data_lines = datalines; of_node_put(ep); - dpi.pdev = pdev; + dpi->pdev = pdev; - mutex_init(&dpi.lock); + mutex_init(&dpi->lock); dpi_init_output(pdev); - dpi.port_initialized = true; + dpi->port_initialized = true; return 0; @@ -772,8 +797,10 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) void __exit dpi_uninit_port(void) { - if (!dpi.port_initialized) + struct dpi_data *dpi = &dpi_data; + + if (!dpi->port_initialized) return; - dpi_uninit_output(dpi.pdev); + dpi_uninit_output(dpi->pdev); } -- GitLab From 2ac6a1aae8f038662b09f2755827dfbe9456894d Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sun, 1 Jun 2014 12:47:44 +0530 Subject: [PATCH 4391/9457] OMAPDSS: DPI: Allocate driver data Allocate driver data(dpi_data) for each DPI instance. It's allocated in omap_dpi_probe() when DT isn't used, and in dpi_init_port() when DT is used. The dpi_data struct instance is no longer global. In the case of DPI ops, it's retrieved from dpi_get_data_from_dssdev(). 'dssdev' passed by the connected encoder/panel driver is a pointer to the 'output' member in dpi_data, and thus can be used to get the DPI instance's driver data. In the case of probe/ini_port functions, it's set as DPI/DSS device's private data embedded in the platform_device struct. Having dpi_data as private data of the platform device will not work for multiple DPI instances in the DT case. This is because there is no corresponding platform_device for DPI or SDI, they exist only as ports under the parent DSS platform_device in the DT case. The DPI port's private data('data' member in device_node struct) will later be used to store dpi_data. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/dpi.c | 46 ++++++++++++++++++++--------- drivers/video/fbdev/omap2/dss/dss.c | 6 ++-- drivers/video/fbdev/omap2/dss/dss.h | 2 +- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index 35285d8395b5..c9face608b2a 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -54,7 +54,15 @@ struct dpi_data { bool port_initialized; }; -static struct dpi_data dpi_data; +static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev) +{ + return container_of(dssdev, struct dpi_data, output); +} + +static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev) +{ + return dev_get_drvdata(&pdev->dev); +} static struct platform_device *dpi_get_dsidev(enum omap_channel channel) { @@ -359,7 +367,7 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi) static int dpi_display_enable(struct omap_dss_device *dssdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct omap_dss_device *out = &dpi->output; int r; @@ -439,7 +447,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) static void dpi_display_disable(struct omap_dss_device *dssdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct omap_overlay_manager *mgr = dpi->output.manager; mutex_lock(&dpi->lock); @@ -463,7 +471,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) static void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); DSSDBG("dpi_set_timings\n"); @@ -477,7 +485,7 @@ static void dpi_set_timings(struct omap_dss_device *dssdev, static void dpi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); mutex_lock(&dpi->lock); @@ -489,7 +497,7 @@ static void dpi_get_timings(struct omap_dss_device *dssdev, static int dpi_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct omap_overlay_manager *mgr = dpi->output.manager; int lck_div, pck_div; unsigned long fck; @@ -529,7 +537,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); mutex_lock(&dpi->lock); @@ -635,7 +643,7 @@ static enum omap_channel dpi_get_channel(void) static int dpi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct omap_overlay_manager *mgr; int r; @@ -694,7 +702,7 @@ static const struct omapdss_dpi_ops dpi_ops = { static void dpi_init_output(struct platform_device *pdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); struct omap_dss_device *out = &dpi->output; out->dev = &pdev->dev; @@ -710,7 +718,7 @@ static void dpi_init_output(struct platform_device *pdev) static void __exit dpi_uninit_output(struct platform_device *pdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); struct omap_dss_device *out = &dpi->output; omapdss_unregister_output(out); @@ -718,7 +726,11 @@ static void __exit dpi_uninit_output(struct platform_device *pdev) static int omap_dpi_probe(struct platform_device *pdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi; + + dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); + if (!dpi) + return -ENOMEM; dpi->pdev = pdev; @@ -760,11 +772,15 @@ void __exit dpi_uninit_platform_driver(void) int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi; struct device_node *ep; u32 datalines; int r; + dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); + if (!dpi) + return -ENOMEM; + ep = omapdss_of_get_next_endpoint(port, NULL); if (!ep) return 0; @@ -787,6 +803,8 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) dpi->port_initialized = true; + dev_set_drvdata(&pdev->dev, dpi); + return 0; err_datalines: @@ -795,9 +813,9 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) return r; } -void __exit dpi_uninit_port(void) +void __exit dpi_uninit_port(struct platform_device *pdev) { - struct dpi_data *dpi = &dpi_data; + struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); if (!dpi->port_initialized) return; diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 14bcd6c43f72..8a4a6d2d1edf 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -820,10 +820,10 @@ static int __init dss_init_ports(struct platform_device *pdev) return 0; } -static void __exit dss_uninit_ports(void) +static void __exit dss_uninit_ports(struct platform_device *pdev) { #ifdef CONFIG_OMAP2_DSS_DPI - dpi_uninit_port(); + dpi_uninit_port(pdev); #endif #ifdef CONFIG_OMAP2_DSS_SDI @@ -910,7 +910,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) static int __exit omap_dsshw_remove(struct platform_device *pdev) { - dss_uninit_ports(); + dss_uninit_ports(pdev); pm_runtime_disable(&pdev->dev); diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index 8ff22c134c62..da7f5f9bc270 100644 --- a/drivers/video/fbdev/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h @@ -359,7 +359,7 @@ int dpi_init_platform_driver(void) __init; void dpi_uninit_platform_driver(void) __exit; int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; -void dpi_uninit_port(void) __exit; +void dpi_uninit_port(struct platform_device *pdev) __exit; /* DISPC */ int dispc_init_platform_driver(void) __init; -- GitLab From 80eb6751b7cde41cee766230fe07d982d13c1486 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 2 Jun 2014 14:11:51 +0530 Subject: [PATCH 4392/9457] OMAPDSS: DPI: Store dpi_data pointer in the DT port's data DPI and SDI ports are backed by only one parent DSS device. We don't have a corresponding platform_device for ports under DSS. In order to support multiple instances of DPI, we need to pass the driver data pointer through the DPI port's private data ('data' member in device_node struct). dpi_init_output/dpi_uninit_output are untouched and only used for non-DT case, these are called when the DPI platform device probed/removed. These funcs will be removed when non-DT mode is removed. dpi_init_output_port/dpi_uninit_output_port are created and used for the DT path, called when DSS inits/uninits it's ports. These new functions retrieve the dpi_data pointer from 'port->data', and not from the platform device's data(pdev->dev) like in the non-DT path. We add some code in dss_uninit_ports() to pass a pointer to the DPI port in dpi_uninit_port(). Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/dpi.c | 36 ++++++++++++++++++++++++----- drivers/video/fbdev/omap2/dss/dss.c | 12 +++++++++- drivers/video/fbdev/omap2/dss/dss.h | 2 +- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index c9face608b2a..224d7885eeeb 100644 --- a/drivers/video/fbdev/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -59,6 +59,7 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev) return container_of(dssdev, struct dpi_data, output); } +/* only used in non-DT mode */ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev) { return dev_get_drvdata(&pdev->dev); @@ -724,6 +725,30 @@ static void __exit dpi_uninit_output(struct platform_device *pdev) omapdss_unregister_output(out); } +static void dpi_init_output_port(struct platform_device *pdev, + struct device_node *port) +{ + struct dpi_data *dpi = port->data; + struct omap_dss_device *out = &dpi->output; + + out->dev = &pdev->dev; + out->id = OMAP_DSS_OUTPUT_DPI; + out->output_type = OMAP_DISPLAY_TYPE_DPI; + out->dispc_channel = dpi_get_channel(); + out->ops.dpi = &dpi_ops; + out->owner = THIS_MODULE; + + omapdss_register_output(out); +} + +static void __exit dpi_uninit_output_port(struct device_node *port) +{ + struct dpi_data *dpi = port->data; + struct omap_dss_device *out = &dpi->output; + + omapdss_unregister_output(out); +} + static int omap_dpi_probe(struct platform_device *pdev) { struct dpi_data *dpi; @@ -796,15 +821,14 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) of_node_put(ep); dpi->pdev = pdev; + port->data = dpi; mutex_init(&dpi->lock); - dpi_init_output(pdev); + dpi_init_output_port(pdev, port); dpi->port_initialized = true; - dev_set_drvdata(&pdev->dev, dpi); - return 0; err_datalines: @@ -813,12 +837,12 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) return r; } -void __exit dpi_uninit_port(struct platform_device *pdev) +void __exit dpi_uninit_port(struct device_node *port) { - struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); + struct dpi_data *dpi = port->data; if (!dpi->port_initialized) return; - dpi_uninit_output(dpi->pdev); + dpi_uninit_output_port(port); } diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 8a4a6d2d1edf..391a6da55e8d 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -822,8 +822,18 @@ static int __init dss_init_ports(struct platform_device *pdev) static void __exit dss_uninit_ports(struct platform_device *pdev) { + struct device_node *parent = pdev->dev.of_node; + struct device_node *port; + + if (parent == NULL) + return; + + port = omapdss_of_get_next_port(parent, NULL); + if (!port) + return; + #ifdef CONFIG_OMAP2_DSS_DPI - dpi_uninit_port(pdev); + dpi_uninit_port(port); #endif #ifdef CONFIG_OMAP2_DSS_SDI diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index da7f5f9bc270..5b9db95533bd 100644 --- a/drivers/video/fbdev/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h @@ -359,7 +359,7 @@ int dpi_init_platform_driver(void) __init; void dpi_uninit_platform_driver(void) __exit; int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; -void dpi_uninit_port(struct platform_device *pdev) __exit; +void dpi_uninit_port(struct device_node *port) __exit; /* DISPC */ int dispc_init_platform_driver(void) __init; -- GitLab From 387ce9f2f2bd78436538deab9ece94512e362deb Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 22 May 2014 17:01:57 +0530 Subject: [PATCH 4393/9457] OMAPDSS: DSS: init dss ports cleanly The init/uninit port functions are used to set up the DPI and SDI outputs under the dss platform device. A 'reg' property is used to determine the port number of the output. This tells us whether the port is DPI or SDI for OMAP34xx DSS revision. For other DSS revisions, we only have DPI outputs under the dss platform device. For multiple DPI output instances(introduced in DRA7xx DSS), we will use the the port number to specify which DPI output instance is being inited. The current functions work fine if there is only one DPI output instance in DSS. For multiple DPI instances, it would get complicated to figure out whether port number was used to specify whether the output is SDI, or another DPI instance. We create a list of port types supported for each DSS rev, with the index of the port in the list specifying the port number of the output for that DSS revision. This allows us to have a more generic way to init/uninit ports within DSS, and also support multiple DPI ports. We make the uninit_port functions iterative since we will have multiple DPI ports to uninit in the future. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/dss.c | 82 ++++++++++++++++++++++++----- drivers/video/fbdev/omap2/dss/dss.h | 24 ++++++++- drivers/video/fbdev/omap2/dss/sdi.c | 2 +- 3 files changed, 92 insertions(+), 16 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index 391a6da55e8d..7e86b8a78315 100644 --- a/drivers/video/fbdev/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -70,6 +70,8 @@ struct dss_features { u8 fck_div_max; u8 dss_fck_multiplier; const char *parent_clk_name; + enum omap_display_type *ports; + int num_ports; int (*dpi_select_source)(enum omap_channel channel); }; @@ -689,6 +691,16 @@ void dss_debug_dump_clocks(struct seq_file *s) } #endif + +static enum omap_display_type omap2plus_ports[] = { + OMAP_DISPLAY_TYPE_DPI, +}; + +static enum omap_display_type omap34xx_ports[] = { + OMAP_DISPLAY_TYPE_DPI, + OMAP_DISPLAY_TYPE_SDI, +}; + static const struct dss_features omap24xx_dss_feats __initconst = { /* * fck div max is really 16, but the divider range has gaps. The range @@ -698,6 +710,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = { .dss_fck_multiplier = 2, .parent_clk_name = "core_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, + .ports = omap2plus_ports, + .num_ports = ARRAY_SIZE(omap2plus_ports), }; static const struct dss_features omap34xx_dss_feats __initconst = { @@ -705,6 +719,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = { .dss_fck_multiplier = 2, .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, + .ports = omap34xx_ports, + .num_ports = ARRAY_SIZE(omap34xx_ports), }; static const struct dss_features omap3630_dss_feats __initconst = { @@ -712,6 +728,8 @@ static const struct dss_features omap3630_dss_feats __initconst = { .dss_fck_multiplier = 1, .parent_clk_name = "dpll4_ck", .dpi_select_source = &dss_dpi_select_source_omap2_omap3, + .ports = omap2plus_ports, + .num_ports = ARRAY_SIZE(omap2plus_ports), }; static const struct dss_features omap44xx_dss_feats __initconst = { @@ -719,6 +737,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = { .dss_fck_multiplier = 1, .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap4, + .ports = omap2plus_ports, + .num_ports = ARRAY_SIZE(omap2plus_ports), }; static const struct dss_features omap54xx_dss_feats __initconst = { @@ -726,6 +746,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = { .dss_fck_multiplier = 1, .parent_clk_name = "dpll_per_x2_ck", .dpi_select_source = &dss_dpi_select_source_omap5, + .ports = omap2plus_ports, + .num_ports = ARRAY_SIZE(omap2plus_ports), }; static const struct dss_features am43xx_dss_feats __initconst = { @@ -733,6 +755,8 @@ static const struct dss_features am43xx_dss_feats __initconst = { .dss_fck_multiplier = 0, .parent_clk_name = NULL, .dpi_select_source = &dss_dpi_select_source_omap2_omap3, + .ports = omap2plus_ports, + .num_ports = ARRAY_SIZE(omap2plus_ports), }; static int __init dss_init_features(struct platform_device *pdev) @@ -798,23 +822,32 @@ static int __init dss_init_ports(struct platform_device *pdev) if (!port) return 0; + if (dss.feat->num_ports == 0) + return 0; + do { + enum omap_display_type port_type; u32 reg; r = of_property_read_u32(port, "reg", ®); if (r) reg = 0; -#ifdef CONFIG_OMAP2_DSS_DPI - if (reg == 0) - dpi_init_port(pdev, port); -#endif + if (reg >= dss.feat->num_ports) + continue; -#ifdef CONFIG_OMAP2_DSS_SDI - if (reg == 1) - sdi_init_port(pdev, port); -#endif + port_type = dss.feat->ports[reg]; + switch (port_type) { + case OMAP_DISPLAY_TYPE_DPI: + dpi_init_port(pdev, port); + break; + case OMAP_DISPLAY_TYPE_SDI: + sdi_init_port(pdev, port); + break; + default: + break; + } } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); return 0; @@ -832,13 +865,34 @@ static void __exit dss_uninit_ports(struct platform_device *pdev) if (!port) return; -#ifdef CONFIG_OMAP2_DSS_DPI - dpi_uninit_port(port); -#endif + if (dss.feat->num_ports == 0) + return; -#ifdef CONFIG_OMAP2_DSS_SDI - sdi_uninit_port(); -#endif + do { + enum omap_display_type port_type; + u32 reg; + int r; + + r = of_property_read_u32(port, "reg", ®); + if (r) + reg = 0; + + if (reg >= dss.feat->num_ports) + continue; + + port_type = dss.feat->ports[reg]; + + switch (port_type) { + case OMAP_DISPLAY_TYPE_DPI: + dpi_uninit_port(port); + break; + case OMAP_DISPLAY_TYPE_SDI: + sdi_uninit_port(port); + break; + default: + break; + } + } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); } /* DSS HW IP initialisation */ diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index 5b9db95533bd..da4de14aaf17 100644 --- a/drivers/video/fbdev/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h @@ -244,8 +244,19 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min, int sdi_init_platform_driver(void) __init; void sdi_uninit_platform_driver(void) __exit; +#ifdef CONFIG_OMAP2_DSS_SDI int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; -void sdi_uninit_port(void) __exit; +void sdi_uninit_port(struct device_node *port) __exit; +#else +static inline int __init sdi_init_port(struct platform_device *pdev, + struct device_node *port) +{ + return 0; +} +static inline void __exit sdi_uninit_port(struct device_node *port) +{ +} +#endif /* DSI */ @@ -358,8 +369,19 @@ static inline bool dsi_pll_calc(struct platform_device *dsidev, int dpi_init_platform_driver(void) __init; void dpi_uninit_platform_driver(void) __exit; +#ifdef CONFIG_OMAP2_DSS_DPI int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; void dpi_uninit_port(struct device_node *port) __exit; +#else +static inline int __init dpi_init_port(struct platform_device *pdev, + struct device_node *port) +{ + return 0; +} +static inline void __exit dpi_uninit_port(struct device_node *port) +{ +} +#endif /* DISPC */ int dispc_init_platform_driver(void) __init; diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index 4c9c46d4ea60..d9b10f27be20 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -425,7 +425,7 @@ int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) return r; } -void __exit sdi_uninit_port(void) +void __exit sdi_uninit_port(struct device_node *port) { if (!sdi.port_initialized) return; -- GitLab From ef691ff48bc838e9fca54b58dccac0a7c36a3130 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Tue, 22 Apr 2014 17:43:48 +0530 Subject: [PATCH 4394/9457] OMAPDSS: DT: Get source endpoint by matching reg-id In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node, and then see what omapdss output has the matching device_node pointer in omap_dss_find_output_by_node. For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS device_node pointer. If the source is one of these outputs, the above method won't work. To get the correct output for ports within DSS(and in other cases in the future, where multiple ports might be under one device), we require additional information which is exclusive to the output port. We create a new field in omap_dss_device called 'port_num', this provides port number of the output port corresponding to this device. When searching for the source endpoint in DT, we extract the 'reg' property from the port corresponding to the endpoint source. From the list of registered outputs, we pick out that output which has both dev->of_node and port_num matching with the device_node pointer and 'reg' of the source endpoint node from DT. For encoder blocks(the ones which have both an input and output port), we need to set the port_num as the 'reg' property for the output port as defined in the DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- .../fbdev/omap2/displays-new/encoder-tfp410.c | 1 + .../omap2/displays-new/encoder-tpd12s015.c | 1 + drivers/video/fbdev/omap2/dss/dss-of.c | 58 +++++++++++++------ drivers/video/fbdev/omap2/dss/dss.h | 4 ++ drivers/video/fbdev/omap2/dss/output.c | 19 +++++- include/video/omapdss.h | 5 +- 6 files changed, 66 insertions(+), 22 deletions(-) diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c index 47ee7cdee1c5..e349064ed615 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c @@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev) dssdev->output_type = OMAP_DISPLAY_TYPE_DVI; dssdev->owner = THIS_MODULE; dssdev->phy.dpi.data_lines = ddata->data_lines; + dssdev->port_num = 1; r = omapdss_register_output(dssdev); if (r) { diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c index c4abd56dd846..1891967b650c 100644 --- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c @@ -409,6 +409,7 @@ static int tpd_probe(struct platform_device *pdev) dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; + dssdev->port_num = 1; in = ddata->in; diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c index a4b20aaf6142..928ee639c0c1 100644 --- a/drivers/video/fbdev/omap2/dss/dss-of.c +++ b/drivers/video/fbdev/omap2/dss/dss-of.c @@ -20,6 +20,8 @@ #include + + The ttm_global_reference structure is made up of several fields: + + + struct ttm_global_reference { + enum ttm_global_types global_type; + size_t size; + void *object; + int (*init) (struct ttm_global_reference *); + void (*release) (struct ttm_global_reference *); + }; + + + There should be one global reference structure for your memory + manager as a whole, and there will be others for each object + created by the memory manager at runtime. Your global TTM should + have a type of TTM_GLOBAL_TTM_MEM. The size field for the global + object should be sizeof(struct ttm_mem_global), and the init and + release hooks should point at your driver-specific init and + release routines, which probably eventually call + ttm_mem_global_init and ttm_mem_global_release, respectively. + + + Once your global TTM accounting structure is set up and initialized + by calling ttm_global_item_ref() on it, + you need to create a buffer object TTM to + provide a pool for buffer object allocation by clients and the + kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, + and its size should be sizeof(struct ttm_bo_global). Again, + driver-specific init and release functions may be provided, + likely eventually calling ttm_bo_global_init() and + ttm_bo_global_release(), respectively. Also, like the previous + object, ttm_global_item_ref() is used to create an initial reference + count for the TTM, which will call your initialization function. + @@ -566,19 +566,19 @@ char *date; using driver-specific ioctls. - On a fundamental level, GEM involves several operations: - - Memory allocation and freeing - Command execution - Aperture management at command execution time - - Buffer object allocation is relatively straightforward and largely + On a fundamental level, GEM involves several operations: + + Memory allocation and freeing + Command execution + Aperture management at command execution time + + Buffer object allocation is relatively straightforward and largely provided by Linux's shmem layer, which provides memory to back each object. Device-specific operations, such as command execution, pinning, buffer - read & write, mapping, and domain ownership transfers are left to + read & write, mapping, and domain ownership transfers are left to driver-specific ioctls. @@ -738,16 +738,16 @@ char *date; respectively. The conversion is handled by the DRM core without any driver-specific support. - - GEM also supports buffer sharing with dma-buf file descriptors through - PRIME. GEM-based drivers must use the provided helpers functions to - implement the exporting and importing correctly. See . - Since sharing file descriptors is inherently more secure than the - easily guessable and global GEM names it is the preferred buffer - sharing mechanism. Sharing buffers through GEM names is only supported - for legacy userspace. Furthermore PRIME also allows cross-device - buffer sharing since it is based on dma-bufs. - + + GEM also supports buffer sharing with dma-buf file descriptors through + PRIME. GEM-based drivers must use the provided helpers functions to + implement the exporting and importing correctly. See . + Since sharing file descriptors is inherently more secure than the + easily guessable and global GEM names it is the preferred buffer + sharing mechanism. Sharing buffers through GEM names is only supported + for legacy userspace. Furthermore PRIME also allows cross-device + buffer sharing since it is based on dma-bufs. + GEM Objects Mapping @@ -852,7 +852,7 @@ char *date; Command Execution - Perhaps the most important GEM function for GPU devices is providing a + Perhaps the most important GEM function for GPU devices is providing a command execution interface to clients. Client programs construct command buffers containing references to previously allocated memory objects, and then submit them to GEM. At that point, GEM takes care to @@ -874,95 +874,95 @@ char *date; GEM Function Reference !Edrivers/gpu/drm/drm_gem.c - - - VMA Offset Manager + + + VMA Offset Manager !Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager !Edrivers/gpu/drm/drm_vma_manager.c !Iinclude/drm/drm_vma_manager.h - - - PRIME Buffer Sharing - - PRIME is the cross device buffer sharing framework in drm, originally - created for the OPTIMUS range of multi-gpu platforms. To userspace - PRIME buffers are dma-buf based file descriptors. - - - Overview and Driver Interface - - Similar to GEM global names, PRIME file descriptors are - also used to share buffer objects across processes. They offer - additional security: as file descriptors must be explicitly sent over - UNIX domain sockets to be shared between applications, they can't be - guessed like the globally unique GEM names. - - - Drivers that support the PRIME - API must set the DRIVER_PRIME bit in the struct - drm_driver - driver_features field, and implement the - prime_handle_to_fd and - prime_fd_to_handle operations. - - - int (*prime_handle_to_fd)(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, - uint32_t flags, int *prime_fd); + + + PRIME Buffer Sharing + + PRIME is the cross device buffer sharing framework in drm, originally + created for the OPTIMUS range of multi-gpu platforms. To userspace + PRIME buffers are dma-buf based file descriptors. + + + Overview and Driver Interface + + Similar to GEM global names, PRIME file descriptors are + also used to share buffer objects across processes. They offer + additional security: as file descriptors must be explicitly sent over + UNIX domain sockets to be shared between applications, they can't be + guessed like the globally unique GEM names. + + + Drivers that support the PRIME + API must set the DRIVER_PRIME bit in the struct + drm_driver + driver_features field, and implement the + prime_handle_to_fd and + prime_fd_to_handle operations. + + + int (*prime_handle_to_fd)(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, + uint32_t flags, int *prime_fd); int (*prime_fd_to_handle)(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, - uint32_t *handle); - Those two operations convert a handle to a PRIME file descriptor and - vice versa. Drivers must use the kernel dma-buf buffer sharing framework - to manage the PRIME file descriptors. Similar to the mode setting - API PRIME is agnostic to the underlying buffer object manager, as - long as handles are 32bit unsigned integers. - - - While non-GEM drivers must implement the operations themselves, GEM - drivers must use the drm_gem_prime_handle_to_fd - and drm_gem_prime_fd_to_handle helper functions. - Those helpers rely on the driver - gem_prime_export and - gem_prime_import operations to create a dma-buf - instance from a GEM object (dma-buf exporter role) and to create a GEM - object from a dma-buf instance (dma-buf importer role). - - - struct dma_buf * (*gem_prime_export)(struct drm_device *dev, - struct drm_gem_object *obj, - int flags); + struct drm_file *file_priv, int prime_fd, + uint32_t *handle); + Those two operations convert a handle to a PRIME file descriptor and + vice versa. Drivers must use the kernel dma-buf buffer sharing framework + to manage the PRIME file descriptors. Similar to the mode setting + API PRIME is agnostic to the underlying buffer object manager, as + long as handles are 32bit unsigned integers. + + + While non-GEM drivers must implement the operations themselves, GEM + drivers must use the drm_gem_prime_handle_to_fd + and drm_gem_prime_fd_to_handle helper functions. + Those helpers rely on the driver + gem_prime_export and + gem_prime_import operations to create a dma-buf + instance from a GEM object (dma-buf exporter role) and to create a GEM + object from a dma-buf instance (dma-buf importer role). + + + struct dma_buf * (*gem_prime_export)(struct drm_device *dev, + struct drm_gem_object *obj, + int flags); struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, - struct dma_buf *dma_buf); - These two operations are mandatory for GEM drivers that support - PRIME. - - - - PRIME Helper Functions -!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers + struct dma_buf *dma_buf); + These two operations are mandatory for GEM drivers that support + PRIME. + - - - PRIME Function References + + PRIME Helper Functions +!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers + + + + PRIME Function References !Edrivers/gpu/drm/drm_prime.c - - - DRM MM Range Allocator - - Overview + + + DRM MM Range Allocator + + Overview !Pdrivers/gpu/drm/drm_mm.c Overview - - - LRU Scan/Eviction Support + + + LRU Scan/Eviction Support !Pdrivers/gpu/drm/drm_mm.c lru scan roaster - + - - DRM MM Range Allocator Function References + + DRM MM Range Allocator Function References !Edrivers/gpu/drm/drm_mm.c !Iinclude/drm/drm_mm.h - + -- GitLab From d7883f8759ab64e7df40f1cbd038745a0bfd9cb8 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 13:56:55 +0100 Subject: [PATCH 4578/9457] drm/doc: Add GEM/CMA helpers to kerneldoc Most of the functions already have the beginnings of kerneldoc comments but are using the wrong opening marker. Use the correct opening marker and flesh out the comments so that they can be integrated with the DRM DocBook document. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- Documentation/DocBook/drm.tmpl | 6 + drivers/gpu/drm/drm_gem_cma_helper.c | 220 ++++++++++++++++++++++----- include/drm/drm_gem_cma_helper.h | 25 ++- 3 files changed, 203 insertions(+), 48 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d21b1f84b838..a1a35b6daaf9 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -963,6 +963,12 @@ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, !Edrivers/gpu/drm/drm_mm.c !Iinclude/drm/drm_mm.h + + CMA Helper Functions Reference +!Pdrivers/gpu/drm/drm_gem_cma_helper.c cma helpers +!Edrivers/gpu/drm/drm_gem_cma_helper.c +!Iinclude/drm/drm_gem_cma_helper.h + diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 0316310e2cc4..7f986d7b8e22 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -29,18 +29,31 @@ #include #include -/* +/** + * DOC: cma helpers + * + * The Contiguous Memory Allocator reserves a pool of memory at early boot + * that is used to service requests for large blocks of contiguous memory. + * + * The DRM GEM/CMA helpers use this allocator as a means to provide buffer + * objects that are physically contiguous in memory. This is useful for + * display drivers that are unable to map scattered buffers via an IOMMU. + */ + +/** * __drm_gem_cma_create - Create a GEM CMA object without allocating memory - * @drm: The drm device - * @size: The GEM object size + * @drm: DRM device + * @size: size of the object to allocate * - * This function creates and initializes a GEM CMA object of the given size, but - * doesn't allocate any memory to back the object. + * This function creates and initializes a GEM CMA object of the given size, + * but doesn't allocate any memory to back the object. * - * Return a struct drm_gem_cma_object* on success or ERR_PTR values on failure. + * Returns: + * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative + * error code on failure. */ static struct drm_gem_cma_object * -__drm_gem_cma_create(struct drm_device *drm, unsigned int size) +__drm_gem_cma_create(struct drm_device *drm, size_t size) { struct drm_gem_cma_object *cma_obj; struct drm_gem_object *gem_obj; @@ -69,14 +82,21 @@ __drm_gem_cma_create(struct drm_device *drm, unsigned int size) return ERR_PTR(ret); } -/* +/** * drm_gem_cma_create - allocate an object with the given size + * @drm: DRM device + * @size: size of the object to allocate + * + * This function creates a CMA GEM object and allocates a contiguous chunk of + * memory as backing store. The backing memory has the writecombine attribute + * set. * - * returns a struct drm_gem_cma_object* on success or ERR_PTR values - * on failure. + * Returns: + * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative + * error code on failure. */ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, - unsigned int size) + size_t size) { struct drm_gem_cma_object *cma_obj; int ret; @@ -104,17 +124,26 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, } EXPORT_SYMBOL_GPL(drm_gem_cma_create); -/* - * drm_gem_cma_create_with_handle - allocate an object with the given - * size and create a gem handle on it +/** + * drm_gem_cma_create_with_handle - allocate an object with the given size and + * return a GEM handle to it + * @file_priv: DRM file-private structure to register the handle for + * @drm: DRM device + * @size: size of the object to allocate + * @handle: return location for the GEM handle + * + * This function creates a CMA GEM object, allocating a physically contiguous + * chunk of memory as backing store. The GEM object is then added to the list + * of object associated with the given file and a handle to it is returned. * - * returns a struct drm_gem_cma_object* on success or ERR_PTR values - * on failure. + * Returns: + * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative + * error code on failure. */ -static struct drm_gem_cma_object *drm_gem_cma_create_with_handle( - struct drm_file *file_priv, - struct drm_device *drm, unsigned int size, - unsigned int *handle) +static struct drm_gem_cma_object * +drm_gem_cma_create_with_handle(struct drm_file *file_priv, + struct drm_device *drm, size_t size, + uint32_t *handle) { struct drm_gem_cma_object *cma_obj; struct drm_gem_object *gem_obj; @@ -145,9 +174,14 @@ static struct drm_gem_cma_object *drm_gem_cma_create_with_handle( return ERR_PTR(ret); } -/* - * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback - * function +/** + * drm_gem_cma_free_object - free resources associated with a CMA GEM object + * @gem_obj: GEM object to free + * + * This function frees the backing memory of the CMA GEM object, cleans up the + * GEM object state and frees the memory used to store the object itself. + * Drivers using the CMA helpers should set this as their DRM driver's + * ->gem_free_object() callback. */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) { @@ -170,15 +204,23 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) } EXPORT_SYMBOL_GPL(drm_gem_cma_free_object); -/* - * drm_gem_cma_dumb_create - (struct drm_driver)->dumb_create callback - * function +/** + * drm_gem_cma_dumb_create - create a dumb buffer object + * @file_priv: DRM file-private structure to create the dumb buffer for + * @drm: DRM device + * @args: IOCTL data + * + * This function computes the pitch of the dumb buffer and rounds it up to an + * integer number of bytes per pixel. Drivers for hardware that doesn't have + * any additional restrictions on the pitch can directly use this function as + * their ->dumb_create() callback. * - * This aligns the pitch and size arguments to the minimum required. wrap - * this into your own function if you need bigger alignment. + * Returns: + * 0 on success or a negative error code on failure. */ int drm_gem_cma_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, struct drm_mode_create_dumb *args) + struct drm_device *drm, + struct drm_mode_create_dumb *args) { struct drm_gem_cma_object *cma_obj; int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); @@ -189,18 +231,30 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, if (args->size < args->pitch * args->height) args->size = args->pitch * args->height; - cma_obj = drm_gem_cma_create_with_handle(file_priv, dev, - args->size, &args->handle); + cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size, + &args->handle); return PTR_ERR_OR_ZERO(cma_obj); } EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create); -/* - * drm_gem_cma_dumb_map_offset - (struct drm_driver)->dumb_map_offset callback - * function +/** + * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM + * object + * @file_priv: DRM file-private structure containing the GEM object + * @drm: DRM device + * @handle: GEM object handle + * @offset: return location for the fake mmap offset + * + * This function look up an object by its handle and returns the fake mmap + * offset associated with it. Drivers using the CMA helpers should set this + * as their DRM driver's ->dumb_map_offset() callback. + * + * Returns: + * 0 on success or a negative error code on failure. */ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *drm, uint32_t handle, uint64_t *offset) + struct drm_device *drm, u32 handle, + u64 *offset) { struct drm_gem_object *gem_obj; @@ -208,7 +262,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, gem_obj = drm_gem_object_lookup(drm, file_priv, handle); if (!gem_obj) { - dev_err(drm->dev, "failed to lookup gem object\n"); + dev_err(drm->dev, "failed to lookup GEM object\n"); mutex_unlock(&drm->struct_mutex); return -EINVAL; } @@ -251,8 +305,20 @@ static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, return ret; } -/* - * drm_gem_cma_mmap - (struct file_operation)->mmap callback function +/** + * drm_gem_cma_mmap - memory-map a CMA GEM object + * @filp: file object + * @vma: VMA for the area to be mapped + * + * This function implements an augmented version of the GEM DRM file mmap + * operation for CMA objects: In addition to the usual GEM VMA setup it + * immediately faults in the entire object instead of using on-demaind + * faulting. Drivers which employ the CMA helpers should use this function + * as their ->mmap() handler in the DRM device file's file_operations + * structure. + * + * Returns: + * 0 on success or a negative error code on failure. */ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) { @@ -272,7 +338,16 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); #ifdef CONFIG_DEBUG_FS -void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m) +/** + * drm_gem_cma_describe - describe a CMA GEM object for debugfs + * @cma_obj: CMA GEM object + * @m: debugfs file handle + * + * This function can be used to dump a human-readable representation of the + * CMA GEM object into a synthetic file. + */ +void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, + struct seq_file *m) { struct drm_gem_object *obj = &cma_obj->base; struct drm_device *dev = obj->dev; @@ -291,7 +366,18 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m EXPORT_SYMBOL_GPL(drm_gem_cma_describe); #endif -/* low-level interface prime helpers */ +/** + * drm_gem_cma_prime_get_sg_table - provide a scatter/gather table of pinned + * pages for a CMA GEM object + * @obj: GEM object + * + * This function exports a scatter/gather table suitable for PRIME usage by + * calling the standard DMA mapping API. Drivers using the CMA helpers should + * set this as their DRM driver's ->gem_prime_get_sg_table() callback. + * + * Returns: + * A pointer to the scatter/gather table of pinned pages or NULL on failure. + */ struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj) { struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); @@ -315,6 +401,23 @@ struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj) } EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table); +/** + * drm_gem_cma_prime_import_sg_table - produce a CMA GEM object from another + * driver's scatter/gather table of pinned pages + * @dev: device to import into + * @attach: DMA-BUF attachment + * @sgt: scatter/gather table of pinned pages + * + * This function imports a scatter/gather table exported via DMA-BUF by + * another driver. Imported buffers must be physically contiguous in memory + * (i.e. the scatter/gather table must contain a single entry). Drivers that + * use the CMA helpers should set this as their DRM driver's + * ->gem_prime_import_sg_table() callback. + * + * Returns: + * A pointer to a newly created GEM object or an ERR_PTR-encoded negative + * error code on failure. + */ struct drm_gem_object * drm_gem_cma_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, @@ -339,6 +442,18 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, } EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); +/** + * drm_gem_cma_prime_mmap - memory-map an exported CMA GEM object + * @obj: GEM object + * @vma: VMA for the area to be mapped + * + * This function maps a buffer imported via DRM PRIME into a userspace + * process's address space. Drivers that use the CMA helpers should set this + * as their DRM driver's ->gem_prime_mmap() callback. + * + * Returns: + * 0 on success or a negative error code on failure. + */ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) { @@ -357,6 +472,20 @@ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, } EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); +/** + * drm_gem_cma_prime_vmap - map a CMA GEM object into the kernel's virtual + * address space + * @obj: GEM object + * + * This function maps a buffer exported via DRM PRIME into the kernel's + * virtual address space. Since the CMA buffers are already mapped into the + * kernel virtual address space this simply returns the cached virtual + * address. Drivers using the CMA helpers should set this as their DRM + * driver's ->gem_prime_vmap() callback. + * + * Returns: + * The kernel virtual address of the CMA GEM object's backing store. + */ void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj) { struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); @@ -365,6 +494,17 @@ void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj) } EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap); +/** + * drm_gem_cma_prime_vunmap - unmap a CMA GEM object from the kernel's virtual + * address space + * @obj: GEM object + * @vaddr: kernel virtual address where the CMA GEM object was mapped + * + * This function removes a buffer exported via DRM PRIME from the kernel's + * virtual address space. This is a no-op because CMA buffers cannot be + * unmapped from kernel space. Drivers using the CMA helpers should set this + * as their DRM driver's ->gem_prime_vunmap() callback. + */ void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr) { /* Nothing to do */ diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 2ff35f3de9c5..873d4eb7f125 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -4,6 +4,13 @@ #include #include +/** + * struct drm_gem_cma_object - GEM object backed by CMA memory allocations + * @base: base GEM object + * @paddr: physical address of the backing memory + * @sgt: scatter/gather table for imported PRIME buffers + * @vaddr: kernel virtual address of the backing memory + */ struct drm_gem_cma_object { struct drm_gem_object base; dma_addr_t paddr; @@ -19,23 +26,25 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem_obj) return container_of(gem_obj, struct drm_gem_cma_object, base); } -/* free gem object. */ +/* free GEM object */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj); -/* create memory region for drm framebuffer. */ +/* create memory region for DRM framebuffer */ int drm_gem_cma_dumb_create(struct drm_file *file_priv, - struct drm_device *drm, struct drm_mode_create_dumb *args); + struct drm_device *drm, + struct drm_mode_create_dumb *args); -/* map memory region for drm framebuffer to user space. */ +/* map memory region for DRM framebuffer to user space */ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *drm, uint32_t handle, uint64_t *offset); + struct drm_device *drm, u32 handle, + u64 *offset); -/* set vm_flags and we can change the vm attribute to other one at here. */ +/* set vm_flags and we can change the VM attribute to other one at here */ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); -/* allocate physical memory. */ +/* allocate physical memory */ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, - unsigned int size); + size_t size); extern const struct vm_operations_struct drm_gem_cma_vm_ops; -- GitLab From 6d1782919dc9b860c0a1d712f1e1f146af16f6c5 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 11:48:49 +0100 Subject: [PATCH 4579/9457] drm/cma: Introduce drm_gem_cma_dumb_create_internal() This function is similar to drm_gem_cma_dumb_create() but targetted at kernel internal users so that they can override the pitch and size requirements of the dumb buffer. It is important to make this difference because the IOCTL says that the pitch and size fields are to be considered outputs and therefore should not be used in computations of the framebuffer size. Internal users may still want to use this code to avoid duplication and at the same time pass on additional, driver-specific restrictions on the pitch and size. While at it, convert the R-Car DU driver, the single user that overrides the pitch, to use the new internal helper. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_gem_cma_helper.c | 45 +++++++++++++++++++++++---- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +- include/drm/drm_gem_cma_helper.h | 5 +++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 7f986d7b8e22..864b0863d042 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -204,6 +204,39 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) } EXPORT_SYMBOL_GPL(drm_gem_cma_free_object); +/** + * drm_gem_cma_dumb_create_internal - create a dumb buffer object + * @file_priv: DRM file-private structure to create the dumb buffer for + * @drm: DRM device + * @args: IOCTL data + * + * This aligns the pitch and size arguments to the minimum required. This is + * an internal helper that can be wrapped by a driver to account for hardware + * with more specific alignment requirements. It should not be used directly + * as the ->dumb_create() callback in a DRM driver. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +int drm_gem_cma_dumb_create_internal(struct drm_file *file_priv, + struct drm_device *drm, + struct drm_mode_create_dumb *args) +{ + unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + struct drm_gem_cma_object *cma_obj; + + if (args->pitch < min_pitch) + args->pitch = min_pitch; + + if (args->size < args->pitch * args->height) + args->size = args->pitch * args->height; + + cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size, + &args->handle); + return PTR_ERR_OR_ZERO(cma_obj); +} +EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create_internal); + /** * drm_gem_cma_dumb_create - create a dumb buffer object * @file_priv: DRM file-private structure to create the dumb buffer for @@ -215,6 +248,10 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_free_object); * any additional restrictions on the pitch can directly use this function as * their ->dumb_create() callback. * + * For hardware with additional restrictions, drivers can adjust the fields + * set up by userspace and pass the IOCTL data along to the + * drm_gem_cma_dumb_create_internal() function. + * * Returns: * 0 on success or a negative error code on failure. */ @@ -223,13 +260,9 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_mode_create_dumb *args) { struct drm_gem_cma_object *cma_obj; - int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); - if (args->pitch < min_pitch) - args->pitch = min_pitch; - - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; + args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + args->size = args->pitch * args->height; cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size, &args->handle); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 6c24ad7d03ef..5329491e32c3 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -128,7 +128,7 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, args->pitch = roundup(max(args->pitch, min_pitch), align); - return drm_gem_cma_dumb_create(file, dev, args); + return drm_gem_cma_dumb_create_internal(file, dev, args); } static struct drm_framebuffer * diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 873d4eb7f125..acd6af8a8e67 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -29,6 +29,11 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem_obj) /* free GEM object */ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj); +/* create memory region for DRM framebuffer */ +int drm_gem_cma_dumb_create_internal(struct drm_file *file_priv, + struct drm_device *drm, + struct drm_mode_create_dumb *args); + /* create memory region for DRM framebuffer */ int drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm, -- GitLab From bdb2b933f2622578b8f737ad21504eb83620024a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 11:57:33 +0100 Subject: [PATCH 4580/9457] drm/omap: gem: dumb: pitch is an output When creating a dumb buffer object using the DRM_IOCTL_MODE_CREATE_DUMB IOCTL, only the width, height, bpp and flags fields are inputs. The caller is not guaranteed to zero out or set handle, pitch and size. Drivers must not treat these values as possible inputs, otherwise they may use uninitialized memory during the computation of the framebuffer size. The OMAP driver uses the pitch field passed in by userspace as a minimum and only override it if the driver-computed pitch is larger than what userspace provided. To prevent this from causing overallocation, fix the minimum pitch to 0 to enforce the driver-computed pitch. Cc: Tomi Valkeinen Reviewed-by: Daniel Vetter Reviewed-by: Rob Clark Acked-by: Tomi Valkeinen Signed-off-by: Thierry Reding --- drivers/gpu/drm/omapdrm/omap_gem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index e4849413ee80..aeb91ed653c9 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -612,8 +612,7 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev, { union omap_gem_size gsize; - /* in case someone tries to feed us a completely bogus stride: */ - args->pitch = align_pitch(args->pitch, args->width, args->bpp); + args->pitch = align_pitch(0, args->width, args->bpp); args->size = PAGE_ALIGN(args->pitch * args->height); gsize = (union omap_gem_size){ -- GitLab From 7e295a36b3af5d588e585e2300febbb191463939 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 12:08:24 +0100 Subject: [PATCH 4581/9457] drm/rcar: gem: dumb: pitch is an output When creating a dumb buffer object using the DRM_IOCTL_MODE_CREATE_DUMB IOCTL, only the width, height, bpp and flags fields are inputs. The caller is not guaranteed to zero out or set handle, pitch and size. Drivers must not treat these values as possible inputs, otherwise they may use uninitialized memory during the computation of the framebuffer size. The R-Car DU driver treats the pitch passed in from userspace as minimum and will only overwrite it when the driver-computed pitch is larger, allowing userspace to, intentionally or not, overallocate framebuffers. Cc: Laurent Pinchart Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 5329491e32c3..6289e3797bc5 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -126,7 +126,7 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, else align = 16 * args->bpp / 8; - args->pitch = roundup(max(args->pitch, min_pitch), align); + args->pitch = roundup(min_pitch, align); return drm_gem_cma_dumb_create_internal(file, dev, args); } -- GitLab From f60859522a830c4d31337592b673799c3b914d0a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 11:14:14 +0100 Subject: [PATCH 4582/9457] drm: Sanitize DRM_IOCTL_MODE_CREATE_DUMB input Some drivers treat the pitch and size fields as inputs and will use them as minima provided by userspace so that they are only overwritten if the minimal requirements of the driver exceed them. This can cause strange behaviour when applications don't zero out these fields, causing whatever was on the stack to be passed to the IOCTL. In a typical case this would become visible as a failed allocation if the pitch or size were unusually high. But this could also cause more subtle bugs like overallocating dumb framebuffers. To prevent drivers from misusing these values, make the DRM core zero out the pitch and size fields before passing the structure to the driver implementation. While at it, also set the output handle field to zero for good measure, even though it's less likely to be abused. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_crtc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e79c8d3700d8..e2ea1512eb44 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4769,6 +4769,16 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, if (PAGE_ALIGN(size) == 0) return -EINVAL; + /* + * handle, pitch and size are output parameters. Zero them out to + * prevent drivers from accidentally using uninitialized data. Since + * not all existing userspace is clearing these fields properly we + * cannot reject IOCTL with garbage in them. + */ + args->handle = 0; + args->pitch = 0; + args->size = 0; + return dev->driver->dumb_create(file_priv, dev, args); } -- GitLab From 7ff7f0a1a934d0d073560dcabe7508e0a4f75f1c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 14:07:14 +0100 Subject: [PATCH 4583/9457] drm/cma: Remove call to drm_gem_free_mmap_offset() drm_gem_object_release() called later in the drm_gem_cma_free_object() function already calls this, so there's no need to do this explicitly. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_gem_cma_helper.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 864b0863d042..e419eedf751d 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -187,8 +187,6 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) { struct drm_gem_cma_object *cma_obj; - drm_gem_free_mmap_offset(gem_obj); - cma_obj = to_drm_gem_cma_obj(gem_obj); if (cma_obj->vaddr) { -- GitLab From 02acb76d72b3672330b6a20d2773048658b2d176 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 4 Nov 2014 14:59:14 +0100 Subject: [PATCH 4584/9457] drm/dsi: Introduce packet format helpers Add two helpers, mipi_dsi_packet_format_is_{short,long}(), that help in determining the format of a packet. Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 67 ++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 3 ++ 2 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index eb6dfe52cab2..adf056677498 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -198,6 +198,73 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) } EXPORT_SYMBOL(mipi_dsi_detach); +/** + * mipi_dsi_packet_format_is_short - check if a packet is of the short format + * @type: MIPI DSI data type of the packet + * + * Return: true if the packet for the given data type is a short packet, false + * otherwise. + */ +bool mipi_dsi_packet_format_is_short(u8 type) +{ + switch (type) { + case MIPI_DSI_V_SYNC_START: + case MIPI_DSI_V_SYNC_END: + case MIPI_DSI_H_SYNC_START: + case MIPI_DSI_H_SYNC_END: + case MIPI_DSI_END_OF_TRANSMISSION: + case MIPI_DSI_COLOR_MODE_OFF: + case MIPI_DSI_COLOR_MODE_ON: + case MIPI_DSI_SHUTDOWN_PERIPHERAL: + case MIPI_DSI_TURN_ON_PERIPHERAL: + case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: + case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: + case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: + case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: + case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: + case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: + case MIPI_DSI_DCS_SHORT_WRITE: + case MIPI_DSI_DCS_SHORT_WRITE_PARAM: + case MIPI_DSI_DCS_READ: + case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: + return true; + } + + return false; +} +EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); + +/** + * mipi_dsi_packet_format_is_long - check if a packet is of the long format + * @type: MIPI DSI data type of the packet + * + * Return: true if the packet for the given data type is a long packet, false + * otherwise. + */ +bool mipi_dsi_packet_format_is_long(u8 type) +{ + switch (type) { + case MIPI_DSI_NULL_PACKET: + case MIPI_DSI_BLANKING_PACKET: + case MIPI_DSI_GENERIC_LONG_WRITE: + case MIPI_DSI_DCS_LONG_WRITE: + case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: + case MIPI_DSI_PACKED_PIXEL_STREAM_30: + case MIPI_DSI_PACKED_PIXEL_STREAM_36: + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: + case MIPI_DSI_PACKED_PIXEL_STREAM_16: + case MIPI_DSI_PACKED_PIXEL_STREAM_18: + case MIPI_DSI_PIXEL_STREAM_3BYTE_18: + case MIPI_DSI_PACKED_PIXEL_STREAM_24: + return true; + } + + return false; +} +EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); + /** * mipi_dsi_dcs_write - send DCS write command * @dsi: DSI device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 8569dc5a1026..f1a07e302559 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -43,6 +43,9 @@ struct mipi_dsi_msg { void *rx_buf; }; +bool mipi_dsi_packet_format_is_short(u8 type); +bool mipi_dsi_packet_format_is_long(u8 type); + /** * struct mipi_dsi_host_ops - DSI bus operations * @attach: attach DSI device to DSI host -- GitLab From a52879e8d7cbeed69be5e54c69701e5edea8cc00 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 13:44:02 +0200 Subject: [PATCH 4585/9457] drm/dsi: Add message to packet translator This commit introduces a new function, mipi_dsi_create_packet(), which converts from a MIPI DSI message to a MIPI DSI packet. The MIPI DSI packet is as close to the protocol described in the DSI specification as possible and useful in drivers that need to write a DSI packet into a FIFO to send a message off to the peripheral. Suggested-by: Andrzej Hajda Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 53 ++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 18 ++++++++++++ 2 files changed, 71 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index adf056677498..44ff665f216f 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -265,6 +265,59 @@ bool mipi_dsi_packet_format_is_long(u8 type) } EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); +/** + * mipi_dsi_create_packet - create a packet from a message according to the + * DSI protocol + * @packet: pointer to a DSI packet structure + * @msg: message to translate into a packet + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, + const struct mipi_dsi_msg *msg) +{ + const u8 *tx = msg->tx_buf; + + if (!packet || !msg) + return -EINVAL; + + /* do some minimum sanity checking */ + if (!mipi_dsi_packet_format_is_short(msg->type) && + !mipi_dsi_packet_format_is_long(msg->type)) + return -EINVAL; + + if (msg->channel > 3) + return -EINVAL; + + memset(packet, 0, sizeof(*packet)); + packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); + + /* TODO: compute ECC if hardware support is not available */ + + /* + * Long write packets contain the word count in header bytes 1 and 2. + * The payload follows the header and is word count bytes long. + * + * Short write packets encode up to two parameters in header bytes 1 + * and 2. + */ + if (mipi_dsi_packet_format_is_long(msg->type)) { + packet->header[1] = (msg->tx_len >> 0) & 0xff; + packet->header[2] = (msg->tx_len >> 8) & 0xff; + + packet->payload_length = msg->tx_len; + packet->payload = tx; + } else { + packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; + packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; + } + + packet->size = sizeof(packet->header) + packet->payload_length; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_create_packet); + /** * mipi_dsi_dcs_write - send DCS write command * @dsi: DSI device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index f1a07e302559..6e3e3aadd2d7 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -46,6 +46,24 @@ struct mipi_dsi_msg { bool mipi_dsi_packet_format_is_short(u8 type); bool mipi_dsi_packet_format_is_long(u8 type); +/** + * struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format + * @size: size (in bytes) of the packet + * @header: the four bytes that make up the header (Data ID, Word Count or + * Packet Data, and ECC) + * @payload_length: number of bytes in the payload + * @payload: a pointer to a buffer containing the payload, if any + */ +struct mipi_dsi_packet { + size_t size; + u8 header[4]; + size_t payload_length; + const u8 *payload; +}; + +int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, + const struct mipi_dsi_msg *msg); + /** * struct mipi_dsi_host_ops - DSI bus operations * @attach: attach DSI device to DSI host -- GitLab From 9eb491f3eed26eb7edf4bf4b1a549895fb3301ea Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 14 Oct 2014 11:12:32 +0200 Subject: [PATCH 4586/9457] drm/dsi: Add DSI transfer helper A common pattern is starting to emerge for higher level transfer helpers. Create a new helper that encapsulates this pattern and avoids code duplication. Acked-by: Andrzej Hajda Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 44ff665f216f..0cc030a09c56 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -198,6 +198,20 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) } EXPORT_SYMBOL(mipi_dsi_detach); +static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, + struct mipi_dsi_msg *msg) +{ + const struct mipi_dsi_host_ops *ops = dsi->host->ops; + + if (!ops || !ops->transfer) + return -ENOSYS; + + if (dsi->mode_flags & MIPI_DSI_MODE_LPM) + msg->flags |= MIPI_DSI_MSG_USE_LPM; + + return ops->transfer(dsi->host, msg); +} + /** * mipi_dsi_packet_format_is_short - check if a packet is of the short format * @type: MIPI DSI data type of the packet @@ -327,16 +341,12 @@ EXPORT_SYMBOL(mipi_dsi_create_packet); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, size_t len) { - const struct mipi_dsi_host_ops *ops = dsi->host->ops; struct mipi_dsi_msg msg = { .channel = dsi->channel, .tx_buf = data, .tx_len = len }; - if (!ops || !ops->transfer) - return -ENOSYS; - switch (len) { case 0: return -EINVAL; @@ -351,10 +361,7 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, break; } - if (dsi->mode_flags & MIPI_DSI_MODE_LPM) - msg.flags = MIPI_DSI_MSG_USE_LPM; - - return ops->transfer(dsi->host, &msg); + return mipi_dsi_device_transfer(dsi, &msg); } EXPORT_SYMBOL(mipi_dsi_dcs_write); @@ -370,7 +377,6 @@ EXPORT_SYMBOL(mipi_dsi_dcs_write); ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, size_t len) { - const struct mipi_dsi_host_ops *ops = dsi->host->ops; struct mipi_dsi_msg msg = { .channel = dsi->channel, .type = MIPI_DSI_DCS_READ, @@ -380,13 +386,7 @@ ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, .rx_len = len }; - if (!ops || !ops->transfer) - return -ENOSYS; - - if (dsi->mode_flags & MIPI_DSI_MODE_LPM) - msg.flags = MIPI_DSI_MSG_USE_LPM; - - return ops->transfer(dsi->host, &msg); + return mipi_dsi_device_transfer(dsi, &msg); } EXPORT_SYMBOL(mipi_dsi_dcs_read); -- GitLab From 960dd616f61c8482b3f9d01fa6623576fb74503c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Jul 2014 15:47:10 +0200 Subject: [PATCH 4587/9457] drm/dsi: Make mipi_dsi_dcs_{read,write}() symmetrical Currently the mipi_dsi_dcs_write() function requires the DCS command byte to be embedded within the write buffer whereas mipi_dsi_dcs_read() has a separate parameter. Make them more symmetrical by adding an extra command parameter to mipi_dsi_dcs_write(). The S6E8AA0 driver relies on the old asymmetric API and there's concern that moving to the new API may be less efficient. Provide a new function with the old semantics for those cases and make the S6E8AA0 driver use it instead. Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 77 ++++++++++++++++++++++----- drivers/gpu/drm/panel/panel-s6e8aa0.c | 2 +- include/drm/drm_mipi_dsi.h | 6 ++- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 0cc030a09c56..388c3ab02500 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -333,13 +333,19 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, EXPORT_SYMBOL(mipi_dsi_create_packet); /** - * mipi_dsi_dcs_write - send DCS write command - * @dsi: DSI device - * @data: pointer to the command followed by parameters - * @len: length of @data + * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload + * @dsi: DSI peripheral device + * @data: buffer containing data to be transmitted + * @len: size of transmission buffer + * + * This function will automatically choose the right data type depending on + * the command payload length. + * + * Return: The number of bytes successfully transmitted or a negative error + * code on failure. */ -ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, - size_t len) +ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, + const void *data, size_t len) { struct mipi_dsi_msg msg = { .channel = dsi->channel, @@ -350,12 +356,15 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, switch (len) { case 0: return -EINVAL; + case 1: msg.type = MIPI_DSI_DCS_SHORT_WRITE; break; + case 2: msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; break; + default: msg.type = MIPI_DSI_DCS_LONG_WRITE; break; @@ -363,16 +372,60 @@ ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, return mipi_dsi_device_transfer(dsi, &msg); } +EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); + +/** + * mipi_dsi_dcs_write() - send DCS write command + * @dsi: DSI peripheral device + * @cmd: DCS command + * @data: buffer containing the command payload + * @len: command payload length + * + * This function will automatically choose the right data type depending on + * the command payload length. + * + * Return: The number of bytes successfully transmitted or a negative error + * code on failure. + */ +ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, + const void *data, size_t len) +{ + ssize_t err; + size_t size; + u8 *tx; + + if (len > 0) { + size = 1 + len; + + tx = kmalloc(size, GFP_KERNEL); + if (!tx) + return -ENOMEM; + + /* concatenate the DCS command byte and the payload */ + tx[0] = cmd; + memcpy(&tx[1], data, len); + } else { + tx = &cmd; + size = 1; + } + + err = mipi_dsi_dcs_write_buffer(dsi, tx, size); + + if (len > 0) + kfree(tx); + + return err; +} EXPORT_SYMBOL(mipi_dsi_dcs_write); /** - * mipi_dsi_dcs_read - send DCS read request command - * @dsi: DSI device - * @cmd: DCS read command - * @data: pointer to read buffer - * @len: length of @data + * mipi_dsi_dcs_read() - send DCS read request command + * @dsi: DSI peripheral device + * @cmd: DCS command + * @data: buffer in which to receive data + * @len: size of receive buffer * - * Function returns number of read bytes or error code. + * Return: The number of bytes read or a negative error code on failure. */ ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, size_t len) diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c index 96f4476609b0..17bc7991344d 100644 --- a/drivers/gpu/drm/panel/panel-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c @@ -141,7 +141,7 @@ static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len) if (ctx->error < 0) return; - ret = mipi_dsi_dcs_write(dsi, data, len); + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); if (ret < 0) { dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, (int)len, data); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 6e3e3aadd2d7..44cece97f333 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -153,8 +153,10 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi); -ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, - size_t len); +ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, + const void *data, size_t len); +ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, + const void *data, size_t len); ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, size_t len); -- GitLab From ed6ff40ee72cc6d384a0aea5efa10c526350e84a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 5 Aug 2014 11:27:56 +0200 Subject: [PATCH 4588/9457] drm/dsi: Constify mipi_dsi_msg struct mipi_dsi_msg is a read-only structure, drivers should never need to modify it. Make this explicit by making all references to the struct const. Acked-by: Andrzej Hajda Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 2 +- include/drm/drm_mipi_dsi.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 24741d8758e8..c5f3c76bfac3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1236,7 +1236,7 @@ static bool exynos_dsi_is_short_dsi_type(u8 type) } static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, - struct mipi_dsi_msg *msg) + const struct mipi_dsi_msg *msg) { struct exynos_dsi *dsi = host_to_dsi(host); struct exynos_dsi_transfer xfer; diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 44cece97f333..4eeb4a5ead8b 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -77,7 +77,7 @@ struct mipi_dsi_host_ops { int (*detach)(struct mipi_dsi_host *host, struct mipi_dsi_device *dsi); ssize_t (*transfer)(struct mipi_dsi_host *host, - struct mipi_dsi_msg *msg); + const struct mipi_dsi_msg *msg); }; /** -- GitLab From dbf30b695809b88fd650dab4028156fb85c5f2d9 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Tue, 5 Aug 2014 09:27:15 +0200 Subject: [PATCH 4589/9457] drm/dsi: Add mipi_dsi_set_maximum_return_packet_size() helper This function can be used to set the maximum return packet size for a MIPI DSI peripheral. Signed-off-by: YoungJun Cho Reviewed-by: Sean Paul [treding: endianess, kerneldoc, return value] Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 24 ++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 388c3ab02500..60177a3e16be 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -332,6 +332,30 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, } EXPORT_SYMBOL(mipi_dsi_create_packet); +/* + * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the + * the payload in a long packet transmitted from the peripheral back to the + * host processor + * @dsi: DSI peripheral device + * @value: the maximum size of the payload + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, + u16 value) +{ + u8 tx[2] = { value & 0xff, value >> 8 }; + struct mipi_dsi_msg msg = { + .channel = dsi->channel, + .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, + .tx_len = sizeof(tx), + .tx_buf = tx, + }; + + return mipi_dsi_device_transfer(dsi, &msg); +} +EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); + /** * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload * @dsi: DSI peripheral device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 4eeb4a5ead8b..4a4e9d7ccc16 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -153,6 +153,8 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi); +int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, + u16 value); ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -- GitLab From 8677affc6cc24ebc0c5728c8f11140f0c509152f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 6 Aug 2014 09:07:49 +0200 Subject: [PATCH 4590/9457] drm/panel: s6e8aa0: Use standard MIPI DSI function Use the newly introduced mipi_dsi_set_maximum_return_packet_size() function to replace an open-coded version. Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-s6e8aa0.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c index 17bc7991344d..373bcbdaeb61 100644 --- a/drivers/gpu/drm/panel/panel-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c @@ -800,27 +800,15 @@ static void s6e8aa0_panel_init(struct s6e8aa0 *ctx) } static void s6e8aa0_set_maximum_return_packet_size(struct s6e8aa0 *ctx, - int size) + u16 size) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - const struct mipi_dsi_host_ops *ops = dsi->host->ops; - u8 buf[] = {size, 0}; - struct mipi_dsi_msg msg = { - .channel = dsi->channel, - .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, - .tx_len = sizeof(buf), - .tx_buf = buf - }; int ret; if (ctx->error < 0) return; - if (!ops || !ops->transfer) - ret = -EIO; - else - ret = ops->transfer(dsi->host, &msg); - + ret = mipi_dsi_set_maximum_return_packet_size(dsi, size); if (ret < 0) { dev_err(ctx->dev, "error %d setting maximum return packet size to %d\n", -- GitLab From 550ab8483641c6d5f059d66816b1d32dad4bcfde Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 5 Aug 2014 10:36:21 +0200 Subject: [PATCH 4591/9457] drm/dsi: Implement generic read and write commands Implement generic read and write commands. Selection of the proper data type for packets is done automatically based on the number of parameters or payload length. Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 89 ++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 6 +++ 2 files changed, 95 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 60177a3e16be..dcc15e161816 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -356,6 +356,95 @@ int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); +/** + * mipi_dsi_generic_write() - transmit data using a generic write packet + * @dsi: DSI peripheral device + * @payload: buffer containing the payload + * @size: size of payload buffer + * + * This function will automatically choose the right data type depending on + * the payload length. + * + * Return: The number of bytes transmitted on success or a negative error code + * on failure. + */ +ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, + size_t size) +{ + struct mipi_dsi_msg msg = { + .channel = dsi->channel, + .tx_buf = payload, + .tx_len = size + }; + + switch (size) { + case 0: + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; + break; + + case 1: + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; + break; + + case 2: + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; + break; + + default: + msg.type = MIPI_DSI_GENERIC_LONG_WRITE; + break; + } + + return mipi_dsi_device_transfer(dsi, &msg); +} +EXPORT_SYMBOL(mipi_dsi_generic_write); + +/** + * mipi_dsi_generic_read() - receive data using a generic read packet + * @dsi: DSI peripheral device + * @params: buffer containing the request parameters + * @num_params: number of request parameters + * @data: buffer in which to return the received data + * @size: size of receive buffer + * + * This function will automatically choose the right data type depending on + * the number of parameters passed in. + * + * Return: The number of bytes successfully read or a negative error code on + * failure. + */ +ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, + size_t num_params, void *data, size_t size) +{ + struct mipi_dsi_msg msg = { + .channel = dsi->channel, + .tx_len = num_params, + .tx_buf = params, + .rx_len = size, + .rx_buf = data + }; + + switch (num_params) { + case 0: + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; + break; + + case 1: + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; + break; + + case 2: + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; + break; + + default: + return -EINVAL; + } + + return mipi_dsi_device_transfer(dsi, &msg); +} +EXPORT_SYMBOL(mipi_dsi_generic_read); + /** * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload * @dsi: DSI peripheral device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 4a4e9d7ccc16..524655509cf1 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -155,6 +155,12 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi); int mipi_dsi_detach(struct mipi_dsi_device *dsi); int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, u16 value); + +ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, + size_t size); +ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, + size_t num_params, void *data, size_t size); + ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, -- GitLab From 42fe1e755d08b80c8be8eec5120946142950b931 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Tue, 5 Aug 2014 10:38:31 +0200 Subject: [PATCH 4592/9457] drm/dsi: Implement some standard DCS commands Add helpers for the {enter,exit}_sleep_mode, set_display_{on,off} and set_tear_{on,off} DCS commands. Signed-off-by: YoungJun Cho Reviewed-by: Sean Paul [treding: kerneldoc and other minor cleanup] Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 118 +++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 19 ++++++ 2 files changed, 137 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index dcc15e161816..c7cc8fa23b58 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -556,6 +556,124 @@ ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, } EXPORT_SYMBOL(mipi_dsi_dcs_read); +/** + * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the + * display module except interface communication + * @dsi: DSI peripheral device + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) +{ + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); + +/** + * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display + * module + * @dsi: DSI peripheral device + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) +{ + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); + +/** + * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the + * display device + * @dsi: DSI peripheral device + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) +{ + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); + +/** + * mipi_dsi_dcs_set_display_on() - start displaying the image data on the + * display device + * @dsi: DSI peripheral device + * + * Return: 0 on success or a negative error code on failure + */ +int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) +{ + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); + +/** + * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect + * output signal on the TE signal line + * @dsi: DSI peripheral device + * + * Return: 0 on success or a negative error code on failure + */ +int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) +{ + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); + +/** + * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect + * output signal on the TE signal line. + * @dsi: DSI peripheral device + * @mode: the Tearing Effect Output Line mode + * + * Return: 0 on success or a negative error code on failure + */ +int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, + enum mipi_dsi_dcs_tear_mode mode) +{ + u8 value = mode; + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, + sizeof(value)); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); + static int mipi_dsi_drv_probe(struct device *dev) { struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 524655509cf1..b2106ad2dd7f 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -161,12 +161,31 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size); +/** + * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode + * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking + * information only + * @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both + * V-Blanking and H-Blanking information + */ +enum mipi_dsi_dcs_tear_mode { + MIPI_DSI_DCS_TEAR_MODE_VBLANK, + MIPI_DSI_DCS_TEAR_MODE_VHBLANK, +}; + ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, const void *data, size_t len); ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, size_t len); +int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); +int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); +int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); +int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); +int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); +int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, + enum mipi_dsi_dcs_tear_mode mode); /** * struct mipi_dsi_driver - DSI driver -- GitLab From 009081e0874d28b504ffa1842f6ddfafd2dd36fc Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 5 Aug 2014 10:41:13 +0200 Subject: [PATCH 4593/9457] drm/dsi: Add to DocBook documentation Integrate the MIPI DSI helpers into DocBook and clean up various kerneldoc warnings. Also add a brief DOC section and clarify some aspects of the mipi_dsi_host struct's .transfer() operation. Acked-by: Andrzej Hajda Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- Documentation/DocBook/drm.tmpl | 6 ++++++ drivers/gpu/drm/drm_mipi_dsi.c | 18 ++++++++++++++++-- include/drm/drm_mipi_dsi.h | 16 ++++++++++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index be35bc328b77..da733c28c92f 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2341,6 +2341,12 @@ void intel_crt_init(struct drm_device *dev) !Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper !Iinclude/drm/drm_dp_mst_helper.h !Edrivers/gpu/drm/drm_dp_mst_topology.c + + + MIPI DSI Helper Functions Reference +!Pdrivers/gpu/drm/drm_mipi_dsi.c dsi helpers +!Iinclude/drm/drm_mipi_dsi.h +!Edrivers/gpu/drm/drm_mipi_dsi.c EDID Helper Functions Reference diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index c7cc8fa23b58..431e96f19288 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -35,6 +35,16 @@ #include

+ smueller@chronox.de +
+ + + + Marek + Vasut + +
+ marek@denx.de +
+
+
+ + + + 2014 + Stephan Mueller + + + + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later + version. + + + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + + + + + + + Kernel Crypto API Interface Specification + + Introduction + + + The kernel crypto API offers a rich set of cryptographic ciphers as + well as other data transformation mechanisms and methods to invoke + these. This document contains a description of the API and provides + example code. + + + + To understand and properly use the kernel crypto API a brief + explanation of its structure is given. Based on the architecture, + the API can be separated into different components. Following the + architecture specification, hints to developers of ciphers are + provided. Pointers to the API function call documentation are + given at the end. + + + + The kernel crypto API refers to all algorithms as "transformations". + Therefore, a cipher handle variable usually has the name "tfm". + Besides cryptographic operations, the kernel crypto API also knows + compression transformations and handles them the same way as ciphers. + + + + The kernel crypto API serves the following entity types: + + + + consumers requesting cryptographic services + + + data transformation implementations (typically ciphers) + that can be called by consumers using the kernel crypto + API + + + + + + This specification is intended for consumers of the kernel crypto + API as well as for developers implementing ciphers. This API + specification, however, does not discusses all API calls available + to data transformation implementations (i.e. implementations of + ciphers and other transformations (such as CRC or even compression + algorithms) that can register with the kernel crypto API). + + + + Note: The terms "transformation" and cipher algorithm are used + interchangably. + + + + Terminology + + The transformation implementation is an actual code or interface + to hardware which implements a certain transformation with precisely + defined behavior. + + + + The transformation object (TFM) is an instance of a transformation + implementation. There can be multiple transformation objects + associated with a single transformation implementation. Each of + those transformation objects is held by a crypto API consumer or + another transformation. Transformation object is allocated when a + crypto API consumer requests a transformation implementation. + The consumer is then provided with a structure, which contains + a transformation object (TFM). + + + + The structure that contains transformation objects may also be + referred to as a "cipher handle". Such a cipher handle is always + subject to the following phases that are reflected in the API calls + applicable to such a cipher handle: + + + + + Initialization of a cipher handle. + + + Execution of all intended cipher operations applicable + for the handle where the cipher handle must be furnished to + every API call. + + + Destruction of a cipher handle. + + + + + When using the initialization API calls, a cipher handle is + created and returned to the consumer. Therefore, please refer + to all initialization API calls that refer to the data + structure type a consumer is expected to receive and subsequently + to use. The initialization API calls have all the same naming + conventions of crypto_alloc_*. + + + + The transformation context is private data associated with + the transformation object. + + + + + Kernel Crypto API Architecture + Cipher algorithm types + + The kernel crypto API provides different API calls for the + following cipher types: + + + Symmetric ciphers + AEAD ciphers + Message digest, including keyed message digest + Random number generation + User space interface + + + + + Ciphers And Templates + + The kernel crypto API provides implementations of single block + ciphers and message digests. In addition, the kernel crypto API + provides numerous "templates" that can be used in conjunction + with the single block ciphers and message digests. Templates + include all types of block chaining mode, the HMAC mechanism, etc. + + + + Single block ciphers and message digests can either be directly + used by a caller or invoked together with a template to form + multi-block ciphers or keyed message digests. + + + + A single block cipher may even be called with multiple templates. + However, templates cannot be used without a single cipher. + + + + See /proc/crypto and search for "name". For example: + + + aes + ecb(aes) + cmac(aes) + ccm(aes) + rfc4106(gcm(aes)) + sha1 + hmac(sha1) + authenc(hmac(sha1),cbc(aes)) + + + + + In these examples, "aes" and "sha1" are the ciphers and all + others are the templates. + + + + Synchronous And Asynchronous Operation + + The kernel crypto API provides synchronous and asynchronous + API operations. + + + + When using the synchronous API operation, the caller invokes + a cipher operation which is performed synchronously by the + kernel crypto API. That means, the caller waits until the + cipher operation completes. Therefore, the kernel crypto API + calls work like regular function calls. For synchronous + operation, the set of API calls is small and conceptually + similar to any other crypto library. + + + + Asynchronous operation is provided by the kernel crypto API + which implies that the invocation of a cipher operation will + complete almost instantly. That invocation triggers the + cipher operation but it does not signal its completion. Before + invoking a cipher operation, the caller must provide a callback + function the kernel crypto API can invoke to signal the + completion of the cipher operation. Furthermore, the caller + must ensure it can handle such asynchronous events by applying + appropriate locking around its data. The kernel crypto API + does not perform any special serialization operation to protect + the caller's data integrity. + + + + Crypto API Cipher References And Priority + + A cipher is referenced by the caller with a string. That string + has the following semantics: + + + template(single block cipher) + + + where "template" and "single block cipher" is the aforementioned + template and single block cipher, respectively. If applicable, + additional templates may enclose other templates, such as + + + template1(template2(single block cipher))) + + + + + The kernel crypto API may provide multiple implementations of a + template or a single block cipher. For example, AES on newer + Intel hardware has the following implementations: AES-NI, + assembler implementation, or straight C. Now, when using the + string "aes" with the kernel crypto API, which cipher + implementation is used? The answer to that question is the + priority number assigned to each cipher implementation by the + kernel crypto API. When a caller uses the string to refer to a + cipher during initialization of a cipher handle, the kernel + crypto API looks up all implementations providing an + implementation with that name and selects the implementation + with the highest priority. + + + + Now, a caller may have the need to refer to a specific cipher + implementation and thus does not want to rely on the + priority-based selection. To accommodate this scenario, the + kernel crypto API allows the cipher implementation to register + a unique name in addition to common names. When using that + unique name, a caller is therefore always sure to refer to + the intended cipher implementation. + + + + The list of available ciphers is given in /proc/crypto. However, + that list does not specify all possible permutations of + templates and ciphers. Each block listed in /proc/crypto may + contain the following information -- if one of the components + listed as follows are not applicable to a cipher, it is not + displayed: + + + + + name: the generic name of the cipher that is subject + to the priority-based selection -- this name can be used by + the cipher allocation API calls (all names listed above are + examples for such generic names) + + + driver: the unique name of the cipher -- this name can + be used by the cipher allocation API calls + + + module: the kernel module providing the cipher + implementation (or "kernel" for statically linked ciphers) + + + priority: the priority value of the cipher implementation + + + refcnt: the reference count of the respective cipher + (i.e. the number of current consumers of this cipher) + + + selftest: specification whether the self test for the + cipher passed + + + type: + + + blkcipher for synchronous block ciphers + + + ablkcipher for asynchronous block ciphers + + + cipher for single block ciphers that may be used with + an additional template + + + shash for synchronous message digest + + + ahash for asynchronous message digest + + + aead for AEAD cipher type + + + compression for compression type transformations + + + rng for random number generator + + + givcipher for cipher with associated IV generator + (see the geniv entry below for the specification of the + IV generator type used by the cipher implementation) + + + + + + blocksize: blocksize of cipher in bytes + + + keysize: key size in bytes + + + ivsize: IV size in bytes + + + seedsize: required size of seed data for random number + generator + + + digestsize: output size of the message digest + + + geniv: IV generation type: + + + eseqiv for encrypted sequence number based IV + generation + + + seqiv for sequence number based IV generation + + + chainiv for chain iv generation + + + <builtin> is a marker that the cipher implements + IV generation and handling as it is specific to the given + cipher + + + + + + + + Key Sizes + + When allocating a cipher handle, the caller only specifies the + cipher type. Symmetric ciphers, however, typically support + multiple key sizes (e.g. AES-128 vs. AES-192 vs. AES-256). + These key sizes are determined with the length of the provided + key. Thus, the kernel crypto API does not provide a separate + way to select the particular symmetric cipher key size. + + + + Cipher Allocation Type And Masks + + The different cipher handle allocation functions allow the + specification of a type and mask flag. Both parameters have + the following meaning (and are therefore not covered in the + subsequent sections). + + + + The type flag specifies the type of the cipher algorithm. + The caller usually provides a 0 when the caller wants the + default handling. Otherwise, the caller may provide the + following selections which match the the aforementioned + cipher types: + + + + + CRYPTO_ALG_TYPE_CIPHER Single block cipher + + + CRYPTO_ALG_TYPE_COMPRESS Compression + + + CRYPTO_ALG_TYPE_AEAD Authenticated Encryption with + Associated Data (MAC) + + + CRYPTO_ALG_TYPE_BLKCIPHER Synchronous multi-block cipher + + + CRYPTO_ALG_TYPE_ABLKCIPHER Asynchronous multi-block cipher + + + CRYPTO_ALG_TYPE_GIVCIPHER Asynchronous multi-block + cipher packed together with an IV generator (see geniv field + in the /proc/crypto listing for the known IV generators) + + + CRYPTO_ALG_TYPE_DIGEST Raw message digest + + + CRYPTO_ALG_TYPE_HASH Alias for CRYPTO_ALG_TYPE_DIGEST + + + CRYPTO_ALG_TYPE_SHASH Synchronous multi-block hash + + + CRYPTO_ALG_TYPE_AHASH Asynchronous multi-block hash + + + CRYPTO_ALG_TYPE_RNG Random Number Generation + + + CRYPTO_ALG_TYPE_PCOMPRESS Enhanced version of + CRYPTO_ALG_TYPE_COMPRESS allowing for segmented compression / + decompression instead of performing the operation on one + segment only. CRYPTO_ALG_TYPE_PCOMPRESS is intended to replace + CRYPTO_ALG_TYPE_COMPRESS once existing consumers are converted. + + + + + The mask flag restricts the type of cipher. The only allowed + flag is CRYPTO_ALG_ASYNC to restrict the cipher lookup function + to asynchronous ciphers. Usually, a caller provides a 0 for the + mask flag. + + + + When the caller provides a mask and type specification, the + caller limits the search the kernel crypto API can perform for + a suitable cipher implementation for the given cipher name. + That means, even when a caller uses a cipher name that exists + during its initialization call, the kernel crypto API may not + select it due to the used type and mask field. + + + + + Developing Cipher Algorithms + Registering And Unregistering Transformation + + There are three distinct types of registration functions in + the Crypto API. One is used to register a generic cryptographic + transformation, while the other two are specific to HASH + transformations and COMPRESSion. We will discuss the latter + two in a separate chapter, here we will only look at the + generic ones. + + + + Before discussing the register functions, the data structure + to be filled with each, struct crypto_alg, must be considered + -- see below for a description of this data structure. + + + + The generic registration functions can be found in + include/linux/crypto.h and their definition can be seen below. + The former function registers a single transformation, while + the latter works on an array of transformation descriptions. + The latter is useful when registering transformations in bulk. + + + + int crypto_register_alg(struct crypto_alg *alg); + int crypto_register_algs(struct crypto_alg *algs, int count); + + + + The counterparts to those functions are listed below. + + + + int crypto_unregister_alg(struct crypto_alg *alg); + int crypto_unregister_algs(struct crypto_alg *algs, int count); + + + + Notice that both registration and unregistration functions + do return a value, so make sure to handle errors. A return + code of zero implies success. Any return code < 0 implies + an error. + + + + The bulk registration / unregistration functions require + that struct crypto_alg is an array of count size. These + functions simply loop over that array and register / + unregister each individual algorithm. If an error occurs, + the loop is terminated at the offending algorithm definition. + That means, the algorithms prior to the offending algorithm + are successfully registered. Note, the caller has no way of + knowing which cipher implementations have successfully + registered. If this is important to know, the caller should + loop through the different implementations using the single + instance *_alg functions for each individual implementation. + + + + Single-Block Symmetric Ciphers [CIPHER] + + Example of transformations: aes, arc4, ... + + + + This section describes the simplest of all transformation + implementations, that being the CIPHER type used for symmetric + ciphers. The CIPHER type is used for transformations which + operate on exactly one block at a time and there are no + dependencies between blocks at all. + + + Registration specifics + + The registration of [CIPHER] algorithm is specific in that + struct crypto_alg field .cra_type is empty. The .cra_u.cipher + has to be filled in with proper callbacks to implement this + transformation. + + + + See struct cipher_alg below. + + + + Cipher Definition With struct cipher_alg + + Struct cipher_alg defines a single block cipher. + + + + Here are schematics of how these functions are called when + operated from other part of the kernel. Note that the + .cia_setkey() call might happen before or after any of these + schematics happen, but must not happen during any of these + are in-flight. + + + + + KEY ---. PLAINTEXT ---. + v v + .cia_setkey() -> .cia_encrypt() + | + '-----> CIPHERTEXT + + + + + Please note that a pattern where .cia_setkey() is called + multiple times is also valid: + + + + + + KEY1 --. PLAINTEXT1 --. KEY2 --. PLAINTEXT2 --. + v v v v + .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt() + | | + '---> CIPHERTEXT1 '---> CIPHERTEXT2 + + + + + + + Multi-Block Ciphers [BLKCIPHER] [ABLKCIPHER] + + Example of transformations: cbc(aes), ecb(arc4), ... + + + + This section describes the multi-block cipher transformation + implementations for both synchronous [BLKCIPHER] and + asynchronous [ABLKCIPHER] case. The multi-block ciphers are + used for transformations which operate on scatterlists of + data supplied to the transformation functions. They output + the result into a scatterlist of data as well. + + + Registration Specifics + + + The registration of [BLKCIPHER] or [ABLKCIPHER] algorithms + is one of the most standard procedures throughout the crypto API. + + + + Note, if a cipher implementation requires a proper alignment + of data, the caller should use the functions of + crypto_blkcipher_alignmask() or crypto_ablkcipher_alignmask() + respectively to identify a memory alignment mask. The kernel + crypto API is able to process requests that are unaligned. + This implies, however, additional overhead as the kernel + crypto API needs to perform the realignment of the data which + may imply moving of data. + + + + Cipher Definition With struct blkcipher_alg and ablkcipher_alg + + Struct blkcipher_alg defines a synchronous block cipher whereas + struct ablkcipher_alg defines an asynchronous block cipher. + + + + Please refer to the single block cipher description for schematics + of the block cipher usage. The usage patterns are exactly the same + for [ABLKCIPHER] and [BLKCIPHER] as they are for plain [CIPHER]. + + + + Specifics Of Asynchronous Multi-Block Cipher + + There are a couple of specifics to the [ABLKCIPHER] interface. + + + + First of all, some of the drivers will want to use the + Generic ScatterWalk in case the hardware needs to be fed + separate chunks of the scatterlist which contains the + plaintext and will contain the ciphertext. Please refer + to the ScatterWalk interface offered by the Linux kernel + scatter / gather list implementation. + + + + + Hashing [HASH] + + + Example of transformations: crc32, md5, sha1, sha256,... + + + Registering And Unregistering The Transformation + + + There are multiple ways to register a HASH transformation, + depending on whether the transformation is synchronous [SHASH] + or asynchronous [AHASH] and the amount of HASH transformations + we are registering. You can find the prototypes defined in + include/crypto/internal/hash.h: + + + + int crypto_register_ahash(struct ahash_alg *alg); + + int crypto_register_shash(struct shash_alg *alg); + int crypto_register_shashes(struct shash_alg *algs, int count); + + + + The respective counterparts for unregistering the HASH + transformation are as follows: + + + + int crypto_unregister_ahash(struct ahash_alg *alg); + + int crypto_unregister_shash(struct shash_alg *alg); + int crypto_unregister_shashes(struct shash_alg *algs, int count); + + + + Cipher Definition With struct shash_alg and ahash_alg + + Here are schematics of how these functions are called when + operated from other part of the kernel. Note that the .setkey() + call might happen before or after any of these schematics happen, + but must not happen during any of these are in-flight. Please note + that calling .init() followed immediately by .finish() is also a + perfectly valid transformation. + + + + I) DATA -----------. + v + .init() -> .update() -> .final() ! .update() might not be called + ^ | | at all in this scenario. + '----' '---> HASH + + II) DATA -----------.-----------. + v v + .init() -> .update() -> .finup() ! .update() may not be called + ^ | | at all in this scenario. + '----' '---> HASH + + III) DATA -----------. + v + .digest() ! The entire process is handled + | by the .digest() call. + '---------------> HASH + + + + Here is a schematic of how the .export()/.import() functions are + called when used from another part of the kernel. + + + + KEY--. DATA--. + v v ! .update() may not be called + .setkey() -> .init() -> .update() -> .export() at all in this scenario. + ^ | | + '-----' '--> PARTIAL_HASH + + ----------- other transformations happen here ----------- + + PARTIAL_HASH--. DATA1--. + v v + .import -> .update() -> .final() ! .update() may not be called + ^ | | at all in this scenario. + '----' '--> HASH1 + + PARTIAL_HASH--. DATA2-. + v v + .import -> .finup() + | + '---------------> HASH2 + + + + Specifics Of Asynchronous HASH Transformation + + Some of the drivers will want to use the Generic ScatterWalk + in case the implementation needs to be fed separate chunks of the + scatterlist which contains the input data. The buffer containing + the resulting hash will always be properly aligned to + .cra_alignmask so there is no need to worry about this. + + + + + + Programming Interface + Block Cipher Context Data Structures +!Pinclude/linux/crypto.h Block Cipher Context Data Structures +!Finclude/linux/crypto.h aead_request + + Block Cipher Algorithm Definitions +!Pinclude/linux/crypto.h Block Cipher Algorithm Definitions +!Finclude/linux/crypto.h crypto_alg +!Finclude/linux/crypto.h ablkcipher_alg +!Finclude/linux/crypto.h aead_alg +!Finclude/linux/crypto.h blkcipher_alg +!Finclude/linux/crypto.h cipher_alg +!Finclude/linux/crypto.h rng_alg + + Asynchronous Block Cipher API +!Pinclude/linux/crypto.h Asynchronous Block Cipher API +!Finclude/linux/crypto.h crypto_alloc_ablkcipher +!Finclude/linux/crypto.h crypto_free_ablkcipher +!Finclude/linux/crypto.h crypto_has_ablkcipher +!Finclude/linux/crypto.h crypto_ablkcipher_ivsize +!Finclude/linux/crypto.h crypto_ablkcipher_blocksize +!Finclude/linux/crypto.h crypto_ablkcipher_setkey +!Finclude/linux/crypto.h crypto_ablkcipher_reqtfm +!Finclude/linux/crypto.h crypto_ablkcipher_encrypt +!Finclude/linux/crypto.h crypto_ablkcipher_decrypt + + Asynchronous Cipher Request Handle +!Pinclude/linux/crypto.h Asynchronous Cipher Request Handle +!Finclude/linux/crypto.h crypto_ablkcipher_reqsize +!Finclude/linux/crypto.h ablkcipher_request_set_tfm +!Finclude/linux/crypto.h ablkcipher_request_alloc +!Finclude/linux/crypto.h ablkcipher_request_free +!Finclude/linux/crypto.h ablkcipher_request_set_callback +!Finclude/linux/crypto.h ablkcipher_request_set_crypt + + Authenticated Encryption With Associated Data (AEAD) Cipher API +!Pinclude/linux/crypto.h Authenticated Encryption With Associated Data (AEAD) Cipher API +!Finclude/linux/crypto.h crypto_alloc_aead +!Finclude/linux/crypto.h crypto_free_aead +!Finclude/linux/crypto.h crypto_aead_ivsize +!Finclude/linux/crypto.h crypto_aead_authsize +!Finclude/linux/crypto.h crypto_aead_blocksize +!Finclude/linux/crypto.h crypto_aead_setkey +!Finclude/linux/crypto.h crypto_aead_setauthsize +!Finclude/linux/crypto.h crypto_aead_encrypt +!Finclude/linux/crypto.h crypto_aead_decrypt + + Asynchronous AEAD Request Handle +!Pinclude/linux/crypto.h Asynchronous AEAD Request Handle +!Finclude/linux/crypto.h crypto_aead_reqsize +!Finclude/linux/crypto.h aead_request_set_tfm +!Finclude/linux/crypto.h aead_request_alloc +!Finclude/linux/crypto.h aead_request_free +!Finclude/linux/crypto.h aead_request_set_callback +!Finclude/linux/crypto.h aead_request_set_crypt +!Finclude/linux/crypto.h aead_request_set_assoc + + Synchronous Block Cipher API +!Pinclude/linux/crypto.h Synchronous Block Cipher API +!Finclude/linux/crypto.h crypto_alloc_blkcipher +!Finclude/linux/crypto.h crypto_free_blkcipher +!Finclude/linux/crypto.h crypto_has_blkcipher +!Finclude/linux/crypto.h crypto_blkcipher_name +!Finclude/linux/crypto.h crypto_blkcipher_ivsize +!Finclude/linux/crypto.h crypto_blkcipher_blocksize +!Finclude/linux/crypto.h crypto_blkcipher_setkey +!Finclude/linux/crypto.h crypto_blkcipher_encrypt +!Finclude/linux/crypto.h crypto_blkcipher_encrypt_iv +!Finclude/linux/crypto.h crypto_blkcipher_decrypt +!Finclude/linux/crypto.h crypto_blkcipher_decrypt_iv +!Finclude/linux/crypto.h crypto_blkcipher_set_iv +!Finclude/linux/crypto.h crypto_blkcipher_get_iv + + Single Block Cipher API +!Pinclude/linux/crypto.h Single Block Cipher API +!Finclude/linux/crypto.h crypto_alloc_cipher +!Finclude/linux/crypto.h crypto_free_cipher +!Finclude/linux/crypto.h crypto_has_cipher +!Finclude/linux/crypto.h crypto_cipher_blocksize +!Finclude/linux/crypto.h crypto_cipher_setkey +!Finclude/linux/crypto.h crypto_cipher_encrypt_one +!Finclude/linux/crypto.h crypto_cipher_decrypt_one + + Synchronous Message Digest API +!Pinclude/linux/crypto.h Synchronous Message Digest API +!Finclude/linux/crypto.h crypto_alloc_hash +!Finclude/linux/crypto.h crypto_free_hash +!Finclude/linux/crypto.h crypto_has_hash +!Finclude/linux/crypto.h crypto_hash_blocksize +!Finclude/linux/crypto.h crypto_hash_digestsize +!Finclude/linux/crypto.h crypto_hash_init +!Finclude/linux/crypto.h crypto_hash_update +!Finclude/linux/crypto.h crypto_hash_final +!Finclude/linux/crypto.h crypto_hash_digest +!Finclude/linux/crypto.h crypto_hash_setkey + + Message Digest Algorithm Definitions +!Pinclude/crypto/hash.h Message Digest Algorithm Definitions +!Finclude/crypto/hash.h hash_alg_common +!Finclude/crypto/hash.h ahash_alg +!Finclude/crypto/hash.h shash_alg + + Asynchronous Message Digest API +!Pinclude/crypto/hash.h Asynchronous Message Digest API +!Finclude/crypto/hash.h crypto_alloc_ahash +!Finclude/crypto/hash.h crypto_free_ahash +!Finclude/crypto/hash.h crypto_ahash_init +!Finclude/crypto/hash.h crypto_ahash_digestsize +!Finclude/crypto/hash.h crypto_ahash_reqtfm +!Finclude/crypto/hash.h crypto_ahash_reqsize +!Finclude/crypto/hash.h crypto_ahash_setkey +!Finclude/crypto/hash.h crypto_ahash_finup +!Finclude/crypto/hash.h crypto_ahash_final +!Finclude/crypto/hash.h crypto_ahash_digest +!Finclude/crypto/hash.h crypto_ahash_export +!Finclude/crypto/hash.h crypto_ahash_import + + Asynchronous Hash Request Handle +!Pinclude/crypto/hash.h Asynchronous Hash Request Handle +!Finclude/crypto/hash.h ahash_request_set_tfm +!Finclude/crypto/hash.h ahash_request_alloc +!Finclude/crypto/hash.h ahash_request_free +!Finclude/crypto/hash.h ahash_request_set_callback +!Finclude/crypto/hash.h ahash_request_set_crypt + + Synchronous Message Digest API +!Pinclude/crypto/hash.h Synchronous Message Digest API +!Finclude/crypto/hash.h crypto_alloc_shash +!Finclude/crypto/hash.h crypto_free_shash +!Finclude/crypto/hash.h crypto_shash_blocksize +!Finclude/crypto/hash.h crypto_shash_digestsize +!Finclude/crypto/hash.h crypto_shash_descsize +!Finclude/crypto/hash.h crypto_shash_setkey +!Finclude/crypto/hash.h crypto_shash_digest +!Finclude/crypto/hash.h crypto_shash_export +!Finclude/crypto/hash.h crypto_shash_import +!Finclude/crypto/hash.h crypto_shash_init +!Finclude/crypto/hash.h crypto_shash_update +!Finclude/crypto/hash.h crypto_shash_final +!Finclude/crypto/hash.h crypto_shash_finup + + Crypto API Random Number API +!Pinclude/crypto/rng.h Random number generator API +!Finclude/crypto/rng.h crypto_alloc_rng +!Finclude/crypto/rng.h crypto_rng_alg +!Finclude/crypto/rng.h crypto_free_rng +!Finclude/crypto/rng.h crypto_rng_get_bytes +!Finclude/crypto/rng.h crypto_rng_reset +!Finclude/crypto/rng.h crypto_rng_seedsize +!Cinclude/crypto/rng.h + + + + Code Examples + Code Example For Asynchronous Block Cipher Operation + + +struct tcrypt_result { + struct completion completion; + int err; +}; + +/* tie all data structures together */ +struct ablkcipher_def { + struct scatterlist sg; + struct crypto_ablkcipher *tfm; + struct ablkcipher_request *req; + struct tcrypt_result result; +}; + +/* Callback function */ +static void test_ablkcipher_cb(struct crypto_async_request *req, int error) +{ + struct tcrypt_result *result = req->data; + + if (error == -EINPROGRESS) + return; + result->err = error; + complete(&result->completion); + pr_info("Encryption finished successfully\n"); +} + +/* Perform cipher operation */ +static unsigned int test_ablkcipher_encdec(struct ablkcipher_def *ablk, + int enc) +{ + int rc = 0; + + if (enc) + rc = crypto_ablkcipher_encrypt(ablk->req); + else + rc = crypto_ablkcipher_decrypt(ablk->req); + + switch (rc) { + case 0: + break; + case -EINPROGRESS: + case -EBUSY: + rc = wait_for_completion_interruptible( + &ablk->result.completion); + if (!rc && !ablk->result.err) { + reinit_completion(&ablk->result.completion); + break; + } + default: + pr_info("ablkcipher encrypt returned with %d result %d\n", + rc, ablk->result.err); + break; + } + init_completion(&ablk->result.completion); + + return rc; +} + +/* Initialize and trigger cipher operation */ +static int test_ablkcipher(void) +{ + struct ablkcipher_def ablk; + struct crypto_ablkcipher *ablkcipher = NULL; + struct ablkcipher_request *req = NULL; + char *scratchpad = NULL; + char *ivdata = NULL; + unsigned char key[32]; + int ret = -EFAULT; + + ablkcipher = crypto_alloc_ablkcipher("cbc-aes-aesni", 0, 0); + if (IS_ERR(ablkcipher)) { + pr_info("could not allocate ablkcipher handle\n"); + return PTR_ERR(ablkcipher); + } + + req = ablkcipher_request_alloc(ablkcipher, GFP_KERNEL); + if (IS_ERR(req)) { + pr_info("could not allocate request queue\n"); + ret = PTR_ERR(req); + goto out; + } + + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + test_ablkcipher_cb, + &ablk.result); + + /* AES 256 with random key */ + get_random_bytes(&key, 32); + if (crypto_ablkcipher_setkey(ablkcipher, key, 32)) { + pr_info("key could not be set\n"); + ret = -EAGAIN; + goto out; + } + + /* IV will be random */ + ivdata = kmalloc(16, GFP_KERNEL); + if (!ivdata) { + pr_info("could not allocate ivdata\n"); + goto out; + } + get_random_bytes(ivdata, 16); + + /* Input data will be random */ + scratchpad = kmalloc(16, GFP_KERNEL); + if (!scratchpad) { + pr_info("could not allocate scratchpad\n"); + goto out; + } + get_random_bytes(scratchpad, 16); + + ablk.tfm = ablkcipher; + ablk.req = req; + + /* We encrypt one block */ + sg_init_one(&ablk.sg, scratchpad, 16); + ablkcipher_request_set_crypt(req, &ablk.sg, &ablk.sg, 16, ivdata); + init_completion(&ablk.result.completion); + + /* encrypt data */ + ret = test_ablkcipher_encdec(&ablk, 1); + if (ret) + goto out; + + pr_info("Encryption triggered successfully\n"); + +out: + if (ablkcipher) + crypto_free_ablkcipher(ablkcipher); + if (req) + ablkcipher_request_free(req); + if (ivdata) + kfree(ivdata); + if (scratchpad) + kfree(scratchpad); + return ret; +} + + + + Code Example For Synchronous Block Cipher Operation + + +static int test_blkcipher(void) +{ + struct crypto_blkcipher *blkcipher = NULL; + char *cipher = "cbc(aes)"; + // AES 128 + charkey = +"\x12\x34\x56\x78\x90\xab\xcd\xef\x12\x34\x56\x78\x90\xab\xcd\xef"; + chariv = +"\x12\x34\x56\x78\x90\xab\xcd\xef\x12\x34\x56\x78\x90\xab\xcd\xef"; + unsigned int ivsize = 0; + char *scratchpad = NULL; // holds plaintext and ciphertext + struct scatterlist sg; + struct blkcipher_desc desc; + int ret = -EFAULT; + + blkcipher = crypto_alloc_blkcipher(cipher, 0, 0); + if (IS_ERR(blkcipher)) { + printk("could not allocate blkcipher handle for %s\n", cipher); + return -PTR_ERR(blkcipher); + } + + if (crypto_blkcipher_setkey(blkcipher, key, strlen(key))) { + printk("key could not be set\n"); + ret = -EAGAIN; + goto out; + } + + ivsize = crypto_blkcipher_ivsize(blkcipher); + if (ivsize) { + if (ivsize != strlen(iv)) + printk("IV length differs from expected length\n"); + crypto_blkcipher_set_iv(blkcipher, iv, ivsize); + } + + scratchpad = kmalloc(crypto_blkcipher_blocksize(blkcipher), GFP_KERNEL); + if (!scratchpad) { + printk("could not allocate scratchpad for %s\n", cipher); + goto out; + } + /* get some random data that we want to encrypt */ + get_random_bytes(scratchpad, crypto_blkcipher_blocksize(blkcipher)); + + desc.flags = 0; + desc.tfm = blkcipher; + sg_init_one(&sg, scratchpad, crypto_blkcipher_blocksize(blkcipher)); + + /* encrypt data in place */ + crypto_blkcipher_encrypt(&desc, &sg, &sg, + crypto_blkcipher_blocksize(blkcipher)); + + /* decrypt data in place + * crypto_blkcipher_decrypt(&desc, &sg, &sg, + */ crypto_blkcipher_blocksize(blkcipher)); + + + printk("Cipher operation completed\n"); + return 0; + +out: + if (blkcipher) + crypto_free_blkcipher(blkcipher); + if (scratchpad) + kzfree(scratchpad); + return ret; +} + + + + Code Example For Use of Operational State Memory With SHASH + + +struct sdesc { + struct shash_desc shash; + char ctx[]; +}; + +static struct sdescinit_sdesc(struct crypto_shash *alg) +{ + struct sdescsdesc; + int size; + + size = sizeof(struct shash_desc) + crypto_shash_descsize(alg); + sdesc = kmalloc(size, GFP_KERNEL); + if (!sdesc) + return ERR_PTR(-ENOMEM); + sdesc->shash.tfm = alg; + sdesc->shash.flags = 0x0; + return sdesc; +} + +static int calc_hash(struct crypto_shashalg, + const unsigned chardata, unsigned int datalen, + unsigned chardigest) { + struct sdescsdesc; + int ret; + + sdesc = init_sdesc(alg); + if (IS_ERR(sdesc)) { + pr_info("trusted_key: can't alloc %s\n", hash_alg); + return PTR_ERR(sdesc); + } + + ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest); + kfree(sdesc); + return ret; +} + + + + Code Example For Random Number Generator Usage + + +static int get_random_numbers(u8 *buf, unsigned int len) +{ + struct crypto_rngrng = NULL; + chardrbg = "drbg_nopr_sha256"; /* Hash DRBG with SHA-256, no PR */ + int ret; + + if (!buf || !len) { + pr_debug("No output buffer provided\n"); + return -EINVAL; + } + + rng = crypto_alloc_rng(drbg, 0, 0); + if (IS_ERR(rng)) { + pr_debug("could not allocate RNG handle for %s\n", drbg); + return -PTR_ERR(rng); + } + + ret = crypto_rng_get_bytes(rng, buf, len); + if (ret < 0) + pr_debug("generation of random numbers failed\n"); + else if (ret == 0) + pr_debug("RNG returned no data"); + else + pr_debug("RNG returned %d bytes of data\n", ret); + +out: + crypto_free_rng(rng); + return ret; +} + + + + -- GitLab From e9a44230dbca10cb02daffd81f1f1073004a5b8b Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:24:12 +0100 Subject: [PATCH 4603/9457] crypto: doc - compile crypto API spec Add the crypto API documentation into the DocBook Makefile to allow it being compiled Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- Documentation/DocBook/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index bec06659e0eb..9c7d92d03f62 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -15,7 +15,7 @@ DOCBOOKS := z8530book.xml device-drivers.xml \ 80211.xml debugobjects.xml sh.xml regulator.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \ tracepoint.xml drm.xml media_api.xml w1.xml \ - writing_musb_glue_layer.xml + writing_musb_glue_layer.xml crypto-API.xml include Documentation/DocBook/media/Makefile -- GitLab From e63b673f601dda77c668e6fd5240425b5331ec7f Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:24:53 +0100 Subject: [PATCH 4604/9457] crypto: doc - userspace interface spec The userspace interface of the kernel crypto API is documented with * a general explanation * a discussion of the memory in-place operation * the description of the message digest API * the description of the symmetric cipher API The documentation refers to libkcapi as a working example on how to use the kernel crypto API from user space. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- Documentation/crypto/crypto-API-userspace.txt | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 Documentation/crypto/crypto-API-userspace.txt diff --git a/Documentation/crypto/crypto-API-userspace.txt b/Documentation/crypto/crypto-API-userspace.txt new file mode 100644 index 000000000000..ac619cd90300 --- /dev/null +++ b/Documentation/crypto/crypto-API-userspace.txt @@ -0,0 +1,205 @@ +Introduction +============ + +The concepts of the kernel crypto API visible to kernel space is fully +applicable to the user space interface as well. Therefore, the kernel crypto API +high level discussion for the in-kernel use cases applies here as well. + +The major difference, however, is that user space can only act as a consumer +and never as a provider of a transformation or cipher algorithm. + +The following covers the user space interface exported by the kernel crypto +API. A working example of this description is libkcapi that can be obtained from +[1]. That library can be used by user space applications that require +cryptographic services from the kernel. + +Some details of the in-kernel kernel crypto API aspects do not +apply to user space, however. This includes the difference between synchronous +and asynchronous invocations. The user space API call is fully synchronous. +In addition, only a subset of all cipher types are available as documented +below. + + +User space API general remarks +============================== + +The kernel crypto API is accessible from user space. Currently, the following +ciphers are accessible: + + * Message digest including keyed message digest (HMAC, CMAC) + + * Symmetric ciphers + +Note, AEAD ciphers are currently not supported via the symmetric cipher +interface. + +The interface is provided via Netlink using the type AF_ALG. In addition, the +setsockopt option type is SOL_ALG. In case the user space header files do not +export these flags yet, use the following macros: + +#ifndef AF_ALG +#define AF_ALG 38 +#endif +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + +A cipher is accessed with the same name as done for the in-kernel API calls. +This includes the generic vs. unique naming schema for ciphers as well as the +enforcement of priorities for generic names. + +To interact with the kernel crypto API, a Netlink socket must be created by +the user space application. User space invokes the cipher operation with the +send/write system call family. The result of the cipher operation is obtained +with the read/recv system call family. + +The following API calls assume that the Netlink socket descriptor is already +opened by the user space application and discusses only the kernel crypto API +specific invocations. + +To initialize a Netlink interface, the following sequence has to be performed +by the consumer: + + 1. Create a socket of type AF_ALG with the struct sockaddr_alg parameter + specified below for the different cipher types. + + 2. Invoke bind with the socket descriptor + + 3. Invoke accept with the socket descriptor. The accept system call + returns a new file descriptor that is to be used to interact with + the particular cipher instance. When invoking send/write or recv/read + system calls to send data to the kernel or obtain data from the + kernel, the file descriptor returned by accept must be used. + +In-place cipher operation +========================= + +Just like the in-kernel operation of the kernel crypto API, the user space +interface allows the cipher operation in-place. That means that the input buffer +used for the send/write system call and the output buffer used by the read/recv +system call may be one and the same. This is of particular interest for +symmetric cipher operations where a copying of the output data to its final +destination can be avoided. + +If a consumer on the other hand wants to maintain the plaintext and the +ciphertext in different memory locations, all a consumer needs to do is to +provide different memory pointers for the encryption and decryption operation. + +Message digest API +================== + +The message digest type to be used for the cipher operation is selected when +invoking the bind syscall. bind requires the caller to provide a filled +struct sockaddr data structure. This data structure must be filled as follows: + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "hash", /* this selects the hash logic in the kernel */ + .salg_name = "sha1" /* this is the cipher name */ +}; + +The salg_type value "hash" applies to message digests and keyed message digests. +Though, a keyed message digest is referenced by the appropriate salg_name. +Please see below for the setsockopt interface that explains how the key can be +set for a keyed message digest. + +Using the send() system call, the application provides the data that should be +processed with the message digest. The send system call allows the following +flags to be specified: + + * MSG_MORE: If this flag is set, the send system call acts like a + message digest update function where the final hash is not + yet calculated. If the flag is not set, the send system call + calculates the final message digest immediately. + +With the recv() system call, the application can read the message digest from +the kernel crypto API. If the buffer is too small for the message digest, the +flag MSG_TRUNC is set by the kernel. + +In order to set a message digest key, the calling application must use the +setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC operation is +performed without the initial HMAC state change caused by the key. + + +Symmetric cipher API +==================== + +The operation is very similar to the message digest discussion. During +initialization, the struct sockaddr data structure must be filled as follows: + +struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "skcipher", /* this selects the symmetric cipher */ + .salg_name = "cbc(aes)" /* this is the cipher name */ +}; + +Before data can be sent to the kernel using the write/send system call family, +the consumer must set the key. The key setting is described with the setsockopt +invocation below. + +Using the sendmsg() system call, the application provides the data that should +be processed for encryption or decryption. In addition, the IV is specified +with the data structure provided by the sendmsg() system call. + +The sendmsg system call parameter of struct msghdr is embedded into the +struct cmsghdr data structure. See recv(2) and cmsg(3) for more information +on how the cmsghdr data structure is used together with the send/recv system +call family. That cmsghdr data structure holds the following information +specified with a separate header instances: + + * specification of the cipher operation type with one of these flags: + ALG_OP_ENCRYPT - encryption of data + ALG_OP_DECRYPT - decryption of data + + * specification of the IV information marked with the flag ALG_SET_IV + +The send system call family allows the following flag to be specified: + + * MSG_MORE: If this flag is set, the send system call acts like a + cipher update function where more input data is expected + with a subsequent invocation of the send system call. + +Note: The kernel reports -EINVAL for any unexpected data. The caller must +make sure that all data matches the constraints given in /proc/crypto for the +selected cipher. + +With the recv() system call, the application can read the result of the +cipher operation from the kernel crypto API. The output buffer must be at least +as large as to hold all blocks of the encrypted or decrypted data. If the output +data size is smaller, only as many blocks are returned that fit into that +output buffer size. + +Setsockopt interface +==================== + +In addition to the read/recv and send/write system call handling to send and +retrieve data subject to the cipher operation, a consumer also needs to set +the additional information for the cipher operation. This additional information +is set using the setsockopt system call that must be invoked with the file +descriptor of the open cipher (i.e. the file descriptor returned by the +accept system call). + +Each setsockopt invocation must use the level SOL_ALG. + +The setsockopt interface allows setting the following data using the mentioned +optname: + + * ALG_SET_KEY -- Setting the key. Key setting is applicable to: + + - the skcipher cipher type (symmetric ciphers) + + - the hash cipher type (keyed message digests) + +User space API example +====================== + +Please see [1] for libkcapi which provides an easy-to-use wrapper around the +aforementioned Netlink kernel interface. [1] also contains a test application +that invokes all libkcapi API calls. + +[1] http://www.chronox.de/libkcapi.html + +Author +====== + +Stephan Mueller -- GitLab From aa1b6fbcbeaca21038db3e7a98d739786ae93511 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:25:31 +0100 Subject: [PATCH 4605/9457] crypto: doc - RNG API documentation The API function calls exported by the kernel crypto API for RNGs to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/rng.h | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/include/crypto/rng.h b/include/crypto/rng.h index c93f9b917925..a16fb10142bf 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -20,11 +20,38 @@ extern struct crypto_rng *crypto_default_rng; int crypto_get_default_rng(void); void crypto_put_default_rng(void); +/** + * DOC: Random number generator API + * + * The random number generator API is used with the ciphers of type + * CRYPTO_ALG_TYPE_RNG (listed as type "rng" in /proc/crypto) + */ + static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm) { return (struct crypto_rng *)tfm; } +/** + * crypto_alloc_rng() -- allocate RNG handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * message digest cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a random number generator. The returned struct + * crypto_rng is the cipher handle that is required for any subsequent + * API invocation for that random number generator. + * + * For all random number generators, this call creates a new private copy of + * the random number generator that does not share a state with other + * instances. The only exception is the "krng" random number generator which + * is a kernel crypto API use case for the get_random_bytes() function of the + * /dev/random driver. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask) { @@ -40,6 +67,14 @@ static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm) return &tfm->base; } +/** + * crypto_rng_alg - obtain name of RNG + * @tfm: cipher handle + * + * Return the generic name (cra_name) of the initialized random number generator + * + * Return: generic name string + */ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) { return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng; @@ -50,23 +85,68 @@ static inline struct rng_tfm *crypto_rng_crt(struct crypto_rng *tfm) return &crypto_rng_tfm(tfm)->crt_rng; } +/** + * crypto_free_rng() - zeroize and free RNG handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_rng(struct crypto_rng *tfm) { crypto_free_tfm(crypto_rng_tfm(tfm)); } +/** + * crypto_rng_get_bytes() - get random number + * @tfm: cipher handle + * @rdata: output buffer holding the random numbers + * @dlen: length of the output buffer + * + * This function fills the caller-allocated buffer with random numbers using the + * random number generator referenced by the cipher handle. + * + * Return: > 0 function was successful and returns the number of generated + * bytes; < 0 if an error occurred + */ static inline int crypto_rng_get_bytes(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen) { return crypto_rng_crt(tfm)->rng_gen_random(tfm, rdata, dlen); } +/** + * crypto_rng_reset() - re-initialize the RNG + * @tfm: cipher handle + * @seed: seed input data + * @slen: length of the seed input data + * + * The reset function completely re-initializes the random number generator + * referenced by the cipher handle by clearing the current state. The new state + * is initialized with the caller provided seed or automatically, depending + * on the random number generator type (the ANSI X9.31 RNG requires + * caller-provided seed, the SP800-90A DRBGs perform an automatic seeding). + * The seed is provided as a parameter to this function call. The provided seed + * should have the length of the seed size defined for the random number + * generator as defined by crypto_rng_seedsize. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_rng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) { return crypto_rng_crt(tfm)->rng_reset(tfm, seed, slen); } +/** + * crypto_rng_seedsize() - obtain seed size of RNG + * @tfm: cipher handle + * + * The function returns the seed size for the random number generator + * referenced by the cipher handle. This value may be zero if the random + * number generator does not implement or require a reseeding. For example, + * the SP800-90A DRBGs implement an automated reseeding after reaching a + * pre-defined threshold. + * + * Return: seed size for the random number generator + */ static inline int crypto_rng_seedsize(struct crypto_rng *tfm) { return crypto_rng_alg(tfm)->seedsize; -- GitLab From 5d8c723f61f2e6dacbd02d80a516115993c4f292 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:26:03 +0100 Subject: [PATCH 4606/9457] crypto: doc - hash data structures The hash data structures needed to be filled in by cipher developers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/hash.h | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/include/crypto/hash.h b/include/crypto/hash.h index 74b13ec1ebd4..bf458fc272aa 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -17,6 +17,28 @@ struct crypto_ahash; +/** + * DOC: Message Digest Algorithm Definitions + * + * These data structures define modular message digest algorithm + * implementations, managed via crypto_register_ahash(), + * crypto_register_shash(), crypto_unregister_ahash() and + * crypto_unregister_shash(). + */ + +/** + * struct hash_alg_common - define properties of message digest + * @digestsize: Size of the result of the transformation. A buffer of this size + * must be available to the @final and @finup calls, so they can + * store the resulting hash into it. For various predefined sizes, + * search include/crypto/ using + * git grep _DIGEST_SIZE include/crypto. + * @statesize: Size of the block for partial state of the transformation. A + * buffer of this size must be passed to the @export function as it + * will save the partial state of the transformation into it. On the + * other side, the @import function will load the state from a + * buffer of this size as well. + */ struct hash_alg_common { unsigned int digestsize; unsigned int statesize; @@ -37,6 +59,62 @@ struct ahash_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; +/** + * struct ahash_alg - asynchronous message digest definition + * @init: Initialize the transformation context. Intended only to initialize the + * state of the HASH transformation at the begining. This shall fill in + * the internal structures used during the entire duration of the whole + * transformation. No data processing happens at this point. + * @update: Push a chunk of data into the driver for transformation. This + * function actually pushes blocks of data from upper layers into the + * driver, which then passes those to the hardware as seen fit. This + * function must not finalize the HASH transformation by calculating the + * final message digest as this only adds more data into the + * transformation. This function shall not modify the transformation + * context, as this function may be called in parallel with the same + * transformation object. Data processing can happen synchronously + * [SHASH] or asynchronously [AHASH] at this point. + * @final: Retrieve result from the driver. This function finalizes the + * transformation and retrieves the resulting hash from the driver and + * pushes it back to upper layers. No data processing happens at this + * point. + * @finup: Combination of @update and @final. This function is effectively a + * combination of @update and @final calls issued in sequence. As some + * hardware cannot do @update and @final separately, this callback was + * added to allow such hardware to be used at least by IPsec. Data + * processing can happen synchronously [SHASH] or asynchronously [AHASH] + * at this point. + * @digest: Combination of @init and @update and @final. This function + * effectively behaves as the entire chain of operations, @init, + * @update and @final issued in sequence. Just like @finup, this was + * added for hardware which cannot do even the @finup, but can only do + * the whole transformation in one run. Data processing can happen + * synchronously [SHASH] or asynchronously [AHASH] at this point. + * @setkey: Set optional key used by the hashing algorithm. Intended to push + * optional key used by the hashing algorithm from upper layers into + * the driver. This function can store the key in the transformation + * context or can outright program it into the hardware. In the former + * case, one must be careful to program the key into the hardware at + * appropriate time and one must be careful that .setkey() can be + * called multiple times during the existence of the transformation + * object. Not all hashing algorithms do implement this function as it + * is only needed for keyed message digests. SHAx/MDx/CRCx do NOT + * implement this function. HMAC(MDx)/HMAC(SHAx)/CMAC(AES) do implement + * this function. This function must be called before any other of the + * @init, @update, @final, @finup, @digest is called. No data + * processing happens at this point. + * @export: Export partial state of the transformation. This function dumps the + * entire state of the ongoing transformation into a provided block of + * data so it can be @import 'ed back later on. This is useful in case + * you want to save partial result of the transformation after + * processing certain amount of data and reload this partial result + * multiple times later on for multiple re-use. No data processing + * happens at this point. + * @import: Import partial state of the transformation. This function loads the + * entire state of the ongoing transformation from a provided block of + * data so the transformation can continue from this point onward. No + * data processing happens at this point. + */ struct ahash_alg { int (*init)(struct ahash_request *req); int (*update)(struct ahash_request *req); @@ -63,6 +141,23 @@ struct shash_desc { crypto_shash_descsize(ctx)] CRYPTO_MINALIGN_ATTR; \ struct shash_desc *shash = (struct shash_desc *)__##shash##_desc +/** + * struct shash_alg - synchronous message digest definition + * @init: see struct ahash_alg + * @update: see struct ahash_alg + * @final: see struct ahash_alg + * @finup: see struct ahash_alg + * @digest: see struct ahash_alg + * @export: see struct ahash_alg + * @import: see struct ahash_alg + * @setkey: see struct ahash_alg + * @digestsize: see struct ahash_alg + * @statesize: see struct ahash_alg + * @dedcsize: Size of the operational state for the message digest. This state + * size is the memory size that needs to be allocated for + * shash_desc.__ctx + * @base: internally used + */ struct shash_alg { int (*init)(struct shash_desc *desc); int (*update)(struct shash_desc *desc, const u8 *data, -- GitLab From 90240ffb127729713cd7d9c1b5c1c0c9451681cd Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:26:41 +0100 Subject: [PATCH 4607/9457] crypto: doc - AHASH API documentation The API function calls exported by the kernel crypto API for AHASHes to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/hash.h | 228 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/include/crypto/hash.h b/include/crypto/hash.h index bf458fc272aa..b2c193acc1ab 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -202,11 +202,35 @@ struct crypto_shash { struct crypto_tfm base; }; +/** + * DOC: Asynchronous Message Digest API + * + * The asynchronous message digest API is used with the ciphers of type + * CRYPTO_ALG_TYPE_AHASH (listed as type "ahash" in /proc/crypto) + * + * The asynchronous cipher operation discussion provided for the + * CRYPTO_ALG_TYPE_ABLKCIPHER API applies here as well. + */ + static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) { return container_of(tfm, struct crypto_ahash, base); } +/** + * crypto_alloc_ahash() - allocate ahash cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * ahash cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for an ahash. The returned struct + * crypto_ahash is the cipher handle that is required for any subsequent + * API invocation for that ahash. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask); @@ -215,6 +239,10 @@ static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) return &tfm->base; } +/** + * crypto_free_ahash() - zeroize and free the ahash handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_ahash(struct crypto_ahash *tfm) { crypto_destroy_tfm(tfm, crypto_ahash_tfm(tfm)); @@ -238,6 +266,16 @@ static inline struct hash_alg_common *crypto_hash_alg_common( return __crypto_hash_alg_common(crypto_ahash_tfm(tfm)->__crt_alg); } +/** + * crypto_ahash_digestsize() - obtain message digest size + * @tfm: cipher handle + * + * The size for the message digest created by the message digest cipher + * referenced with the cipher handle is returned. + * + * + * Return: message digest size of cipher + */ static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) { return crypto_hash_alg_common(tfm)->digestsize; @@ -263,12 +301,32 @@ static inline void crypto_ahash_clear_flags(struct crypto_ahash *tfm, u32 flags) crypto_tfm_clear_flags(crypto_ahash_tfm(tfm), flags); } +/** + * crypto_ahash_reqtfm() - obtain cipher handle from request + * @req: asynchronous request handle that contains the reference to the ahash + * cipher handle + * + * Return the ahash cipher handle that is registered with the asynchronous + * request handle ahash_request. + * + * Return: ahash cipher handle + */ static inline struct crypto_ahash *crypto_ahash_reqtfm( struct ahash_request *req) { return __crypto_ahash_cast(req->base.tfm); } +/** + * crypto_ahash_reqsize() - obtain size of the request data structure + * @tfm: cipher handle + * + * Return the size of the ahash state size. With the crypto_ahash_export + * function, the caller can export the state into a buffer whose size is + * defined with this function. + * + * Return: size of the ahash state + */ static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) { return tfm->reqsize; @@ -279,38 +337,166 @@ static inline void *ahash_request_ctx(struct ahash_request *req) return req->__ctx; } +/** + * crypto_ahash_setkey - set key for cipher handle + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the ahash cipher. The cipher + * handle must point to a keyed hash in order for this function to succeed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen); + +/** + * crypto_ahash_finup() - update and finalize message digest + * @req: reference to the ahash_request handle that holds all information + * needed to perform the cipher operation + * + * This function is a "short-hand" for the function calls of + * crypto_ahash_update and crypto_shash_final. The parameters have the same + * meaning as discussed for those separate functions. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_ahash_finup(struct ahash_request *req); + +/** + * crypto_ahash_final() - calculate message digest + * @req: reference to the ahash_request handle that holds all information + * needed to perform the cipher operation + * + * Finalize the message digest operation and create the message digest + * based on all data added to the cipher handle. The message digest is placed + * into the output buffer registered with the ahash_request handle. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_ahash_final(struct ahash_request *req); + +/** + * crypto_ahash_digest() - calculate message digest for a buffer + * @req: reference to the ahash_request handle that holds all information + * needed to perform the cipher operation + * + * This function is a "short-hand" for the function calls of crypto_ahash_init, + * crypto_ahash_update and crypto_ahash_final. The parameters have the same + * meaning as discussed for those separate three functions. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_ahash_digest(struct ahash_request *req); +/** + * crypto_ahash_export() - extract current message digest state + * @req: reference to the ahash_request handle whose state is exported + * @out: output buffer of sufficient size that can hold the hash state + * + * This function exports the hash state of the ahash_request handle into the + * caller-allocated output buffer out which must have sufficient size (e.g. by + * calling crypto_ahash_reqsize). + * + * Return: 0 if the export was successful; < 0 if an error occurred + */ static inline int crypto_ahash_export(struct ahash_request *req, void *out) { return crypto_ahash_reqtfm(req)->export(req, out); } +/** + * crypto_ahash_import() - import message digest state + * @req: reference to ahash_request handle the state is imported into + * @in: buffer holding the state + * + * This function imports the hash state into the ahash_request handle from the + * input buffer. That buffer should have been generated with the + * crypto_ahash_export function. + * + * Return: 0 if the import was successful; < 0 if an error occurred + */ static inline int crypto_ahash_import(struct ahash_request *req, const void *in) { return crypto_ahash_reqtfm(req)->import(req, in); } +/** + * crypto_ahash_init() - (re)initialize message digest handle + * @req: ahash_request handle that already is initialized with all necessary + * data using the ahash_request_* API functions + * + * The call (re-)initializes the message digest referenced by the ahash_request + * handle. Any potentially existing state created by previous operations is + * discarded. + * + * Return: 0 if the message digest initialization was successful; < 0 if an + * error occurred + */ static inline int crypto_ahash_init(struct ahash_request *req) { return crypto_ahash_reqtfm(req)->init(req); } +/** + * crypto_ahash_update() - add data to message digest for processing + * @req: ahash_request handle that was previously initialized with the + * crypto_ahash_init call. + * + * Updates the message digest state of the &ahash_request handle. The input data + * is pointed to by the scatter/gather list registered in the &ahash_request + * handle + * + * Return: 0 if the message digest update was successful; < 0 if an error + * occurred + */ static inline int crypto_ahash_update(struct ahash_request *req) { return crypto_ahash_reqtfm(req)->update(req); } +/** + * DOC: Asynchronous Hash Request Handle + * + * The &ahash_request data structure contains all pointers to data + * required for the asynchronous cipher operation. This includes the cipher + * handle (which can be used by multiple &ahash_request instances), pointer + * to plaintext and the message digest output buffer, asynchronous callback + * function, etc. It acts as a handle to the ahash_request_* API calls in a + * similar way as ahash handle to the crypto_ahash_* API calls. + */ + +/** + * ahash_request_set_tfm() - update cipher handle reference in request + * @req: request handle to be modified + * @tfm: cipher handle that shall be added to the request handle + * + * Allow the caller to replace the existing ahash handle in the request + * data structure with a different one. + */ static inline void ahash_request_set_tfm(struct ahash_request *req, struct crypto_ahash *tfm) { req->base.tfm = crypto_ahash_tfm(tfm); } +/** + * ahash_request_alloc() - allocate request data structure + * @tfm: cipher handle to be registered with the request + * @gfp: memory allocation flag that is handed to kmalloc by the API call. + * + * Allocate the request data structure that must be used with the ahash + * message digest API calls. During + * the allocation, the provided ahash handle + * is registered in the request data structure. + * + * Return: allocated request handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct ahash_request *ahash_request_alloc( struct crypto_ahash *tfm, gfp_t gfp) { @@ -325,6 +511,10 @@ static inline struct ahash_request *ahash_request_alloc( return req; } +/** + * ahash_request_free() - zeroize and free the request data structure + * @req: request data structure cipher handle to be freed + */ static inline void ahash_request_free(struct ahash_request *req) { kzfree(req); @@ -336,6 +526,31 @@ static inline struct ahash_request *ahash_request_cast( return container_of(req, struct ahash_request, base); } +/** + * ahash_request_set_callback() - set asynchronous callback function + * @req: request handle + * @flags: specify zero or an ORing of the flags + * CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and + * increase the wait queue beyond the initial maximum size; + * CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep + * @compl: callback function pointer to be registered with the request handle + * @data: The data pointer refers to memory that is not used by the kernel + * crypto API, but provided to the callback function for it to use. Here, + * the caller can provide a reference to memory the callback function can + * operate on. As the callback function is invoked asynchronously to the + * related functionality, it may need to access data structures of the + * related functionality which can be referenced using this pointer. The + * callback function can access the memory via the "data" field in the + * &crypto_async_request data structure provided to the callback function. + * + * This function allows setting the callback function that is triggered once + * the cipher operation completes. + * + * The callback function is registered with the &ahash_request handle and + * must comply with the following template + * + * void callback_function(struct crypto_async_request *req, int error) + */ static inline void ahash_request_set_callback(struct ahash_request *req, u32 flags, crypto_completion_t compl, @@ -346,6 +561,19 @@ static inline void ahash_request_set_callback(struct ahash_request *req, req->base.flags = flags; } +/** + * ahash_request_set_crypt() - set data buffers + * @req: ahash_request handle to be updated + * @src: source scatter/gather list + * @result: buffer that is filled with the message digest -- the caller must + * ensure that the buffer has sufficient space by, for example, calling + * crypto_ahash_digestsize() + * @nbytes: number of bytes to process from the source scatter/gather list + * + * By using this call, the caller references the source scatter/gather list. + * The source scatter/gather list points to the data the message digest is to + * be calculated for. + */ static inline void ahash_request_set_crypt(struct ahash_request *req, struct scatterlist *src, u8 *result, unsigned int nbytes) -- GitLab From 968ab291078006de022b2245702a050ccdc32cd3 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:27:16 +0100 Subject: [PATCH 4608/9457] crypto: doc - SHASH API documentation The API function calls exported by the kernel crypto API for SHASHes to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/hash.h | 164 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/include/crypto/hash.h b/include/crypto/hash.h index b2c193acc1ab..3d66e8bd0932 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -583,6 +583,33 @@ static inline void ahash_request_set_crypt(struct ahash_request *req, req->result = result; } +/** + * DOC: Synchronous Message Digest API + * + * The synchronous message digest API is used with the ciphers of type + * CRYPTO_ALG_TYPE_SHASH (listed as type "shash" in /proc/crypto) + * + * The message digest API is able to maintain state information for the + * caller. + * + * The synchronous message digest API can store user-related context in in its + * shash_desc request data structure. + */ + +/** + * crypto_alloc_shash() - allocate message digest handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * message digest cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a message digest. The returned &struct + * crypto_shash is the cipher handle that is required for any subsequent + * API invocation for that message digest. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, u32 mask); @@ -591,6 +618,10 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) return &tfm->base; } +/** + * crypto_free_shash() - zeroize and free the message digest handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_shash(struct crypto_shash *tfm) { crypto_destroy_tfm(tfm, crypto_shash_tfm(tfm)); @@ -602,6 +633,15 @@ static inline unsigned int crypto_shash_alignmask( return crypto_tfm_alg_alignmask(crypto_shash_tfm(tfm)); } +/** + * crypto_shash_blocksize() - obtain block size for cipher + * @tfm: cipher handle + * + * The block size for the message digest cipher referenced with the cipher + * handle is returned. + * + * Return: block size of cipher + */ static inline unsigned int crypto_shash_blocksize(struct crypto_shash *tfm) { return crypto_tfm_alg_blocksize(crypto_shash_tfm(tfm)); @@ -617,6 +657,15 @@ static inline struct shash_alg *crypto_shash_alg(struct crypto_shash *tfm) return __crypto_shash_alg(crypto_shash_tfm(tfm)->__crt_alg); } +/** + * crypto_shash_digestsize() - obtain message digest size + * @tfm: cipher handle + * + * The size for the message digest created by the message digest cipher + * referenced with the cipher handle is returned. + * + * Return: digest size of cipher + */ static inline unsigned int crypto_shash_digestsize(struct crypto_shash *tfm) { return crypto_shash_alg(tfm)->digestsize; @@ -642,6 +691,21 @@ static inline void crypto_shash_clear_flags(struct crypto_shash *tfm, u32 flags) crypto_tfm_clear_flags(crypto_shash_tfm(tfm), flags); } +/** + * crypto_shash_descsize() - obtain the operational state size + * @tfm: cipher handle + * + * The size of the operational state the cipher needs during operation is + * returned for the hash referenced with the cipher handle. This size is + * required to calculate the memory requirements to allow the caller allocating + * sufficient memory for operational state. + * + * The operational state is defined with struct shash_desc where the size of + * that data structure is to be calculated as + * sizeof(struct shash_desc) + crypto_shash_descsize(alg) + * + * Return: size of the operational state + */ static inline unsigned int crypto_shash_descsize(struct crypto_shash *tfm) { return tfm->descsize; @@ -652,29 +716,129 @@ static inline void *shash_desc_ctx(struct shash_desc *desc) return desc->__ctx; } +/** + * crypto_shash_setkey() - set key for message digest + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the keyed message digest cipher. The + * cipher handle must point to a keyed message digest cipher in order for this + * function to succeed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen); + +/** + * crypto_shash_digest() - calculate message digest for buffer + * @desc: see crypto_shash_final() + * @data: see crypto_shash_update() + * @len: see crypto_shash_update() + * @out: see crypto_shash_final() + * + * This function is a "short-hand" for the function calls of crypto_shash_init, + * crypto_shash_update and crypto_shash_final. The parameters have the same + * meaning as discussed for those separate three functions. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_shash_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out); +/** + * crypto_shash_export() - extract operational state for message digest + * @desc: reference to the operational state handle whose state is exported + * @out: output buffer of sufficient size that can hold the hash state + * + * This function exports the hash state of the operational state handle into the + * caller-allocated output buffer out which must have sufficient size (e.g. by + * calling crypto_shash_descsize). + * + * Return: 0 if the export creation was successful; < 0 if an error occurred + */ static inline int crypto_shash_export(struct shash_desc *desc, void *out) { return crypto_shash_alg(desc->tfm)->export(desc, out); } +/** + * crypto_shash_import() - import operational state + * @desc: reference to the operational state handle the state imported into + * @in: buffer holding the state + * + * This function imports the hash state into the operational state handle from + * the input buffer. That buffer should have been generated with the + * crypto_ahash_export function. + * + * Return: 0 if the import was successful; < 0 if an error occurred + */ static inline int crypto_shash_import(struct shash_desc *desc, const void *in) { return crypto_shash_alg(desc->tfm)->import(desc, in); } +/** + * crypto_shash_init() - (re)initialize message digest + * @desc: operational state handle that is already filled + * + * The call (re-)initializes the message digest referenced by the + * operational state handle. Any potentially existing state created by + * previous operations is discarded. + * + * Return: 0 if the message digest initialization was successful; < 0 if an + * error occurred + */ static inline int crypto_shash_init(struct shash_desc *desc) { return crypto_shash_alg(desc->tfm)->init(desc); } +/** + * crypto_shash_update() - add data to message digest for processing + * @desc: operational state handle that is already initialized + * @data: input data to be added to the message digest + * @len: length of the input data + * + * Updates the message digest state of the operational state handle. + * + * Return: 0 if the message digest update was successful; < 0 if an error + * occurred + */ int crypto_shash_update(struct shash_desc *desc, const u8 *data, unsigned int len); + +/** + * crypto_shash_final() - calculate message digest + * @desc: operational state handle that is already filled with data + * @out: output buffer filled with the message digest + * + * Finalize the message digest operation and create the message digest + * based on all data added to the cipher handle. The message digest is placed + * into the output buffer. The caller must ensure that the output buffer is + * large enough by using crypto_shash_digestsize. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_shash_final(struct shash_desc *desc, u8 *out); + +/** + * crypto_shash_finup() - calculate message digest of buffer + * @desc: see crypto_shash_final() + * @data: see crypto_shash_update() + * @len: see crypto_shash_update() + * @out: see crypto_shash_final() + * + * This function is a "short-hand" for the function calls of + * crypto_shash_update and crypto_shash_final. The parameters have the same + * meaning as discussed for those separate functions. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ int crypto_shash_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out); -- GitLab From 0d7f488f0305a9caffab0a18a882f9980f8bc936 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:27:49 +0100 Subject: [PATCH 4609/9457] crypto: doc - cipher data structures The data structure of struct crypto_alg together with various other data structures needed by cipher developers is documented wit all parameters that can be set by a developer of a transformation. All parameters that are internal to the crypto API are marked as such. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 246 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 243 insertions(+), 3 deletions(-) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index d45e949699ea..752360e1e8fe 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -127,6 +127,13 @@ struct skcipher_givcrypt_request; typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err); +/** + * DOC: Block Cipher Context Data Structures + * + * These data structures define the operating context for each block cipher + * type. + */ + struct crypto_async_request { struct list_head list; crypto_completion_t complete; @@ -194,9 +201,63 @@ struct hash_desc { u32 flags; }; -/* - * Algorithms: modular crypto algorithm implementations, managed - * via crypto_register_alg() and crypto_unregister_alg(). +/** + * DOC: Block Cipher Algorithm Definitions + * + * These data structures define modular crypto algorithm implementations, + * managed via crypto_register_alg() and crypto_unregister_alg(). + */ + +/** + * struct ablkcipher_alg - asynchronous block cipher definition + * @min_keysize: Minimum key size supported by the transformation. This is the + * smallest key length supported by this transformation algorithm. + * This must be set to one of the pre-defined values as this is + * not hardware specific. Possible values for this field can be + * found via git grep "_MIN_KEY_SIZE" include/crypto/ + * @max_keysize: Maximum key size supported by the transformation. This is the + * largest key length supported by this transformation algorithm. + * This must be set to one of the pre-defined values as this is + * not hardware specific. Possible values for this field can be + * found via git grep "_MAX_KEY_SIZE" include/crypto/ + * @setkey: Set key for the transformation. This function is used to either + * program a supplied key into the hardware or store the key in the + * transformation context for programming it later. Note that this + * function does modify the transformation context. This function can + * be called multiple times during the existence of the transformation + * object, so one must make sure the key is properly reprogrammed into + * the hardware. This function is also responsible for checking the key + * length for validity. In case a software fallback was put in place in + * the @cra_init call, this function might need to use the fallback if + * the algorithm doesn't support all of the key sizes. + * @encrypt: Encrypt a scatterlist of blocks. This function is used to encrypt + * the supplied scatterlist containing the blocks of data. The crypto + * API consumer is responsible for aligning the entries of the + * scatterlist properly and making sure the chunks are correctly + * sized. In case a software fallback was put in place in the + * @cra_init call, this function might need to use the fallback if + * the algorithm doesn't support all of the key sizes. In case the + * key was stored in transformation context, the key might need to be + * re-programmed into the hardware in this function. This function + * shall not modify the transformation context, as this function may + * be called in parallel with the same transformation object. + * @decrypt: Decrypt a single block. This is a reverse counterpart to @encrypt + * and the conditions are exactly the same. + * @givencrypt: Update the IV for encryption. With this function, a cipher + * implementation may provide the function on how to update the IV + * for encryption. + * @givdecrypt: Update the IV for decryption. This is the reverse of + * @givencrypt . + * @geniv: The transformation implementation may use an "IV generator" provided + * by the kernel crypto API. Several use cases have a predefined + * approach how IVs are to be updated. For such use cases, the kernel + * crypto API provides ready-to-use implementations that can be + * referenced with this variable. + * @ivsize: IV size applicable for transformation. The consumer must provide an + * IV of exactly that size to perform the encrypt or decrypt operation. + * + * All fields except @givencrypt , @givdecrypt , @geniv and @ivsize are + * mandatory and must be filled. */ struct ablkcipher_alg { int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key, @@ -213,6 +274,32 @@ struct ablkcipher_alg { unsigned int ivsize; }; +/** + * struct aead_alg - AEAD cipher definition + * @maxauthsize: Set the maximum authentication tag size supported by the + * transformation. A transformation may support smaller tag sizes. + * As the authentication tag is a message digest to ensure the + * integrity of the encrypted data, a consumer typically wants the + * largest authentication tag possible as defined by this + * variable. + * @setauthsize: Set authentication size for the AEAD transformation. This + * function is used to specify the consumer requested size of the + * authentication tag to be either generated by the transformation + * during encryption or the size of the authentication tag to be + * supplied during the decryption operation. This function is also + * responsible for checking the authentication tag size for + * validity. + * @setkey: see struct ablkcipher_alg + * @encrypt: see struct ablkcipher_alg + * @decrypt: see struct ablkcipher_alg + * @givencrypt: see struct ablkcipher_alg + * @givdecrypt: see struct ablkcipher_alg + * @geniv: see struct ablkcipher_alg + * @ivsize: see struct ablkcipher_alg + * + * All fields except @givencrypt , @givdecrypt , @geniv and @ivsize are + * mandatory and must be filled. + */ struct aead_alg { int (*setkey)(struct crypto_aead *tfm, const u8 *key, unsigned int keylen); @@ -228,6 +315,18 @@ struct aead_alg { unsigned int maxauthsize; }; +/** + * struct blkcipher_alg - synchronous block cipher definition + * @min_keysize: see struct ablkcipher_alg + * @max_keysize: see struct ablkcipher_alg + * @setkey: see struct ablkcipher_alg + * @encrypt: see struct ablkcipher_alg + * @decrypt: see struct ablkcipher_alg + * @geniv: see struct ablkcipher_alg + * @ivsize: see struct ablkcipher_alg + * + * All fields except @geniv and @ivsize are mandatory and must be filled. + */ struct blkcipher_alg { int (*setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); @@ -245,6 +344,53 @@ struct blkcipher_alg { unsigned int ivsize; }; +/** + * struct cipher_alg - single-block symmetric ciphers definition + * @cia_min_keysize: Minimum key size supported by the transformation. This is + * the smallest key length supported by this transformation + * algorithm. This must be set to one of the pre-defined + * values as this is not hardware specific. Possible values + * for this field can be found via git grep "_MIN_KEY_SIZE" + * include/crypto/ + * @cia_max_keysize: Maximum key size supported by the transformation. This is + * the largest key length supported by this transformation + * algorithm. This must be set to one of the pre-defined values + * as this is not hardware specific. Possible values for this + * field can be found via git grep "_MAX_KEY_SIZE" + * include/crypto/ + * @cia_setkey: Set key for the transformation. This function is used to either + * program a supplied key into the hardware or store the key in the + * transformation context for programming it later. Note that this + * function does modify the transformation context. This function + * can be called multiple times during the existence of the + * transformation object, so one must make sure the key is properly + * reprogrammed into the hardware. This function is also + * responsible for checking the key length for validity. + * @cia_encrypt: Encrypt a single block. This function is used to encrypt a + * single block of data, which must be @cra_blocksize big. This + * always operates on a full @cra_blocksize and it is not possible + * to encrypt a block of smaller size. The supplied buffers must + * therefore also be at least of @cra_blocksize size. Both the + * input and output buffers are always aligned to @cra_alignmask. + * In case either of the input or output buffer supplied by user + * of the crypto API is not aligned to @cra_alignmask, the crypto + * API will re-align the buffers. The re-alignment means that a + * new buffer will be allocated, the data will be copied into the + * new buffer, then the processing will happen on the new buffer, + * then the data will be copied back into the original buffer and + * finally the new buffer will be freed. In case a software + * fallback was put in place in the @cra_init call, this function + * might need to use the fallback if the algorithm doesn't support + * all of the key sizes. In case the key was stored in + * transformation context, the key might need to be re-programmed + * into the hardware in this function. This function shall not + * modify the transformation context, as this function may be + * called in parallel with the same transformation object. + * @cia_decrypt: Decrypt a single block. This is a reverse counterpart to + * @cia_encrypt, and the conditions are exactly the same. + * + * All fields are mandatory and must be filled. + */ struct cipher_alg { unsigned int cia_min_keysize; unsigned int cia_max_keysize; @@ -261,6 +407,25 @@ struct compress_alg { unsigned int slen, u8 *dst, unsigned int *dlen); }; +/** + * struct rng_alg - random number generator definition + * @rng_make_random: The function defined by this variable obtains a random + * number. The random number generator transform must generate + * the random number out of the context provided with this + * call. + * @rng_reset: Reset of the random number generator by clearing the entire state. + * With the invocation of this function call, the random number + * generator shall completely reinitialize its state. If the random + * number generator requires a seed for setting up a new state, + * the seed must be provided by the consumer while invoking this + * function. The required size of the seed is defined with + * @seedsize . + * @seedsize: The seed size required for a random number generator + * initialization defined with this variable. Some random number + * generators like the SP800-90A DRBG does not require a seed as the + * seeding is implemented internally without the need of support by + * the consumer. In this case, the seed size is set to zero. + */ struct rng_alg { int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen); @@ -277,6 +442,81 @@ struct rng_alg { #define cra_compress cra_u.compress #define cra_rng cra_u.rng +/** + * struct crypto_alg - definition of a cryptograpic cipher algorithm + * @cra_flags: Flags describing this transformation. See include/linux/crypto.h + * CRYPTO_ALG_* flags for the flags which go in here. Those are + * used for fine-tuning the description of the transformation + * algorithm. + * @cra_blocksize: Minimum block size of this transformation. The size in bytes + * of the smallest possible unit which can be transformed with + * this algorithm. The users must respect this value. + * In case of HASH transformation, it is possible for a smaller + * block than @cra_blocksize to be passed to the crypto API for + * transformation, in case of any other transformation type, an + * error will be returned upon any attempt to transform smaller + * than @cra_blocksize chunks. + * @cra_ctxsize: Size of the operational context of the transformation. This + * value informs the kernel crypto API about the memory size + * needed to be allocated for the transformation context. + * @cra_alignmask: Alignment mask for the input and output data buffer. The data + * buffer containing the input data for the algorithm must be + * aligned to this alignment mask. The data buffer for the + * output data must be aligned to this alignment mask. Note that + * the Crypto API will do the re-alignment in software, but + * only under special conditions and there is a performance hit. + * The re-alignment happens at these occasions for different + * @cra_u types: cipher -- For both input data and output data + * buffer; ahash -- For output hash destination buf; shash -- + * For output hash destination buf. + * This is needed on hardware which is flawed by design and + * cannot pick data from arbitrary addresses. + * @cra_priority: Priority of this transformation implementation. In case + * multiple transformations with same @cra_name are available to + * the Crypto API, the kernel will use the one with highest + * @cra_priority. + * @cra_name: Generic name (usable by multiple implementations) of the + * transformation algorithm. This is the name of the transformation + * itself. This field is used by the kernel when looking up the + * providers of particular transformation. + * @cra_driver_name: Unique name of the transformation provider. This is the + * name of the provider of the transformation. This can be any + * arbitrary value, but in the usual case, this contains the + * name of the chip or provider and the name of the + * transformation algorithm. + * @cra_type: Type of the cryptographic transformation. This is a pointer to + * struct crypto_type, which implements callbacks common for all + * trasnformation types. There are multiple options: + * &crypto_blkcipher_type, &crypto_ablkcipher_type, + * &crypto_ahash_type, &crypto_aead_type, &crypto_rng_type. + * This field might be empty. In that case, there are no common + * callbacks. This is the case for: cipher, compress, shash. + * @cra_u: Callbacks implementing the transformation. This is a union of + * multiple structures. Depending on the type of transformation selected + * by @cra_type and @cra_flags above, the associated structure must be + * filled with callbacks. This field might be empty. This is the case + * for ahash, shash. + * @cra_init: Initialize the cryptographic transformation object. This function + * is used to initialize the cryptographic transformation object. + * This function is called only once at the instantiation time, right + * after the transformation context was allocated. In case the + * cryptographic hardware has some special requirements which need to + * be handled by software, this function shall check for the precise + * requirement of the transformation and put any software fallbacks + * in place. + * @cra_exit: Deinitialize the cryptographic transformation object. This is a + * counterpart to @cra_init, used to remove various changes set in + * @cra_init. + * @cra_module: Owner of this transformation implementation. Set to THIS_MODULE + * @cra_list: internally used + * @cra_users: internally used + * @cra_refcnt: internally used + * @cra_destroy: internally used + * + * The struct crypto_alg describes a generic Crypto API algorithm and is common + * for all of the transformations. Any variable not documented here shall not + * be used by a cipher implementation as it is internal to the Crypto API. + */ struct crypto_alg { struct list_head cra_list; struct list_head cra_users; -- GitLab From f13ec330a787c2653d4738be1ee887ead1fb3008 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:28:22 +0100 Subject: [PATCH 4610/9457] crypto: doc - ABLKCIPHER API documentation The API function calls exported by the kernel crypto API for asynchronous block ciphers to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 206 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 752360e1e8fe..39c8fc6d3313 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -821,6 +821,50 @@ static inline u32 crypto_skcipher_mask(u32 mask) return mask; } +/** + * DOC: Asynchronous Block Cipher API + * + * Asynchronous block cipher API is used with the ciphers of type + * CRYPTO_ALG_TYPE_ABLKCIPHER (listed as type "ablkcipher" in /proc/crypto). + * + * Asynchronous cipher operations imply that the function invocation for a + * cipher request returns immediately before the completion of the operation. + * The cipher request is scheduled as a separate kernel thread and therefore + * load-balanced on the different CPUs via the process scheduler. To allow + * the kernel crypto API to inform the caller about the completion of a cipher + * request, the caller must provide a callback function. That function is + * invoked with the cipher handle when the request completes. + * + * To support the asynchronous operation, additional information than just the + * cipher handle must be supplied to the kernel crypto API. That additional + * information is given by filling in the ablkcipher_request data structure. + * + * For the asynchronous block cipher API, the state is maintained with the tfm + * cipher handle. A single tfm can be used across multiple calls and in + * parallel. For asynchronous block cipher calls, context data supplied and + * only used by the caller can be referenced the request data structure in + * addition to the IV used for the cipher request. The maintenance of such + * state information would be important for a crypto driver implementer to + * have, because when calling the callback function upon completion of the + * cipher operation, that callback function may need some information about + * which operation just finished if it invoked multiple in parallel. This + * state information is unused by the kernel crypto API. + */ + +/** + * crypto_alloc_ablkcipher() - allocate asynchronous block cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * ablkcipher cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for an ablkcipher. The returned struct + * crypto_ablkcipher is the cipher handle that is required for any subsequent + * API invocation for that ablkcipher. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name, u32 type, u32 mask); @@ -830,11 +874,25 @@ static inline struct crypto_tfm *crypto_ablkcipher_tfm( return &tfm->base; } +/** + * crypto_free_ablkcipher() - zeroize and free cipher handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_ablkcipher(struct crypto_ablkcipher *tfm) { crypto_free_tfm(crypto_ablkcipher_tfm(tfm)); } +/** + * crypto_has_ablkcipher() - Search for the availability of an ablkcipher. + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * ablkcipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Return: true when the ablkcipher is known to the kernel crypto API; false + * otherwise + */ static inline int crypto_has_ablkcipher(const char *alg_name, u32 type, u32 mask) { @@ -848,12 +906,31 @@ static inline struct ablkcipher_tfm *crypto_ablkcipher_crt( return &crypto_ablkcipher_tfm(tfm)->crt_ablkcipher; } +/** + * crypto_ablkcipher_ivsize() - obtain IV size + * @tfm: cipher handle + * + * The size of the IV for the ablkcipher referenced by the cipher handle is + * returned. This IV size may be zero if the cipher does not need an IV. + * + * Return: IV size in bytes + */ static inline unsigned int crypto_ablkcipher_ivsize( struct crypto_ablkcipher *tfm) { return crypto_ablkcipher_crt(tfm)->ivsize; } +/** + * crypto_ablkcipher_blocksize() - obtain block size of cipher + * @tfm: cipher handle + * + * The block size for the ablkcipher referenced with the cipher handle is + * returned. The caller may use that information to allocate appropriate + * memory for the data returned by the encryption or decryption operation + * + * Return: block size of cipher + */ static inline unsigned int crypto_ablkcipher_blocksize( struct crypto_ablkcipher *tfm) { @@ -883,6 +960,22 @@ static inline void crypto_ablkcipher_clear_flags(struct crypto_ablkcipher *tfm, crypto_tfm_clear_flags(crypto_ablkcipher_tfm(tfm), flags); } +/** + * crypto_ablkcipher_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the ablkcipher referenced by the cipher + * handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_ablkcipher_setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen) { @@ -891,12 +984,32 @@ static inline int crypto_ablkcipher_setkey(struct crypto_ablkcipher *tfm, return crt->setkey(crt->base, key, keylen); } +/** + * crypto_ablkcipher_reqtfm() - obtain cipher handle from request + * @req: ablkcipher_request out of which the cipher handle is to be obtained + * + * Return the crypto_ablkcipher handle when furnishing an ablkcipher_request + * data structure. + * + * Return: crypto_ablkcipher handle + */ static inline struct crypto_ablkcipher *crypto_ablkcipher_reqtfm( struct ablkcipher_request *req) { return __crypto_ablkcipher_cast(req->base.tfm); } +/** + * crypto_ablkcipher_encrypt() - encrypt plaintext + * @req: reference to the ablkcipher_request handle that holds all information + * needed to perform the cipher operation + * + * Encrypt plaintext data using the ablkcipher_request handle. That data + * structure and how it is filled with data is discussed with the + * ablkcipher_request_* functions. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_ablkcipher_encrypt(struct ablkcipher_request *req) { struct ablkcipher_tfm *crt = @@ -904,6 +1017,17 @@ static inline int crypto_ablkcipher_encrypt(struct ablkcipher_request *req) return crt->encrypt(req); } +/** + * crypto_ablkcipher_decrypt() - decrypt ciphertext + * @req: reference to the ablkcipher_request handle that holds all information + * needed to perform the cipher operation + * + * Decrypt ciphertext data using the ablkcipher_request handle. That data + * structure and how it is filled with data is discussed with the + * ablkcipher_request_* functions. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req) { struct ablkcipher_tfm *crt = @@ -911,12 +1035,37 @@ static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req) return crt->decrypt(req); } +/** + * DOC: Asynchronous Cipher Request Handle + * + * The ablkcipher_request data structure contains all pointers to data + * required for the asynchronous cipher operation. This includes the cipher + * handle (which can be used by multiple ablkcipher_request instances), pointer + * to plaintext and ciphertext, asynchronous callback function, etc. It acts + * as a handle to the ablkcipher_request_* API calls in a similar way as + * ablkcipher handle to the crypto_ablkcipher_* API calls. + */ + +/** + * crypto_ablkcipher_reqsize() - obtain size of the request data structure + * @tfm: cipher handle + * + * Return: number of bytes + */ static inline unsigned int crypto_ablkcipher_reqsize( struct crypto_ablkcipher *tfm) { return crypto_ablkcipher_crt(tfm)->reqsize; } +/** + * ablkcipher_request_set_tfm() - update cipher handle reference in request + * @req: request handle to be modified + * @tfm: cipher handle that shall be added to the request handle + * + * Allow the caller to replace the existing ablkcipher handle in the request + * data structure with a different one. + */ static inline void ablkcipher_request_set_tfm( struct ablkcipher_request *req, struct crypto_ablkcipher *tfm) { @@ -929,6 +1078,18 @@ static inline struct ablkcipher_request *ablkcipher_request_cast( return container_of(req, struct ablkcipher_request, base); } +/** + * ablkcipher_request_alloc() - allocate request data structure + * @tfm: cipher handle to be registered with the request + * @gfp: memory allocation flag that is handed to kmalloc by the API call. + * + * Allocate the request data structure that must be used with the ablkcipher + * encrypt and decrypt API calls. During the allocation, the provided ablkcipher + * handle is registered in the request data structure. + * + * Return: allocated request handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct ablkcipher_request *ablkcipher_request_alloc( struct crypto_ablkcipher *tfm, gfp_t gfp) { @@ -943,11 +1104,40 @@ static inline struct ablkcipher_request *ablkcipher_request_alloc( return req; } +/** + * ablkcipher_request_free() - zeroize and free request data structure + * @req: request data structure cipher handle to be freed + */ static inline void ablkcipher_request_free(struct ablkcipher_request *req) { kzfree(req); } +/** + * ablkcipher_request_set_callback() - set asynchronous callback function + * @req: request handle + * @flags: specify zero or an ORing of the flags + * CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and + * increase the wait queue beyond the initial maximum size; + * CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep + * @compl: callback function pointer to be registered with the request handle + * @data: The data pointer refers to memory that is not used by the kernel + * crypto API, but provided to the callback function for it to use. Here, + * the caller can provide a reference to memory the callback function can + * operate on. As the callback function is invoked asynchronously to the + * related functionality, it may need to access data structures of the + * related functionality which can be referenced using this pointer. The + * callback function can access the memory via the "data" field in the + * crypto_async_request data structure provided to the callback function. + * + * This function allows setting the callback function that is triggered once the + * cipher operation completes. + * + * The callback function is registered with the ablkcipher_request handle and + * must comply with the following template: + * + * void callback_function(struct crypto_async_request *req, int error) + */ static inline void ablkcipher_request_set_callback( struct ablkcipher_request *req, u32 flags, crypto_completion_t compl, void *data) @@ -957,6 +1147,22 @@ static inline void ablkcipher_request_set_callback( req->base.flags = flags; } +/** + * ablkcipher_request_set_crypt() - set data buffers + * @req: request handle + * @src: source scatter / gather list + * @dst: destination scatter / gather list + * @nbytes: number of bytes to process from @src + * @iv: IV for the cipher operation which must comply with the IV size defined + * by crypto_ablkcipher_ivsize + * + * This function allows setting of the source data and destination data + * scatter / gather lists. + * + * For encryption, the source is treated as the plaintext and the + * destination is the ciphertext. For a decryption operation, the use is + * reversed: the source is the ciphertext and the destination is the plaintext. + */ static inline void ablkcipher_request_set_crypt( struct ablkcipher_request *req, struct scatterlist *src, struct scatterlist *dst, -- GitLab From fced7b02623e3ccace714f8adceed735698a9c8b Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:29:00 +0100 Subject: [PATCH 4611/9457] crypto: doc - AEAD API documentation The API function calls exported by the kernel crypto API for AEAD ciphers to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 251 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 39c8fc6d3313..4704e71a31fe 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -1174,11 +1174,55 @@ static inline void ablkcipher_request_set_crypt( req->info = iv; } +/** + * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API + * + * The AEAD cipher API is used with the ciphers of type CRYPTO_ALG_TYPE_AEAD + * (listed as type "aead" in /proc/crypto) + * + * The most prominent examples for this type of encryption is GCM and CCM. + * However, the kernel supports other types of AEAD ciphers which are defined + * with the following cipher string: + * + * authenc(keyed message digest, block cipher) + * + * For example: authenc(hmac(sha256), cbc(aes)) + * + * The example code provided for the asynchronous block cipher operation + * applies here as well. Naturally all *ablkcipher* symbols must be exchanged + * the *aead* pendants discussed in the following. In addtion, for the AEAD + * operation, the aead_request_set_assoc function must be used to set the + * pointer to the associated data memory location before performing the + * encryption or decryption operation. In case of an encryption, the associated + * data memory is filled during the encryption operation. For decryption, the + * associated data memory must contain data that is used to verify the integrity + * of the decrypted data. Another deviation from the asynchronous block cipher + * operation is that the caller should explicitly check for -EBADMSG of the + * crypto_aead_decrypt. That error indicates an authentication error, i.e. + * a breach in the integrity of the message. In essence, that -EBADMSG error + * code is the key bonus an AEAD cipher has over "standard" block chaining + * modes. + */ + static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) { return (struct crypto_aead *)tfm; } +/** + * crypto_alloc_aead() - allocate AEAD cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * AEAD cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for an AEAD. The returned struct + * crypto_aead is the cipher handle that is required for any subsequent + * API invocation for that AEAD. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask); static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) @@ -1186,6 +1230,10 @@ static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) return &tfm->base; } +/** + * crypto_free_aead() - zeroize and free aead handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_aead(struct crypto_aead *tfm) { crypto_free_tfm(crypto_aead_tfm(tfm)); @@ -1196,16 +1244,47 @@ static inline struct aead_tfm *crypto_aead_crt(struct crypto_aead *tfm) return &crypto_aead_tfm(tfm)->crt_aead; } +/** + * crypto_aead_ivsize() - obtain IV size + * @tfm: cipher handle + * + * The size of the IV for the aead referenced by the cipher handle is + * returned. This IV size may be zero if the cipher does not need an IV. + * + * Return: IV size in bytes + */ static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm) { return crypto_aead_crt(tfm)->ivsize; } +/** + * crypto_aead_authsize() - obtain maximum authentication data size + * @tfm: cipher handle + * + * The maximum size of the authentication data for the AEAD cipher referenced + * by the AEAD cipher handle is returned. The authentication data size may be + * zero if the cipher implements a hard-coded maximum. + * + * The authentication data may also be known as "tag value". + * + * Return: authentication data size / tag size in bytes + */ static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm) { return crypto_aead_crt(tfm)->authsize; } +/** + * crypto_aead_blocksize() - obtain block size of cipher + * @tfm: cipher handle + * + * The block size for the AEAD referenced with the cipher handle is returned. + * The caller may use that information to allocate appropriate memory for the + * data returned by the encryption or decryption operation + * + * Return: block size of cipher + */ static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm) { return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm)); @@ -1231,6 +1310,22 @@ static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags) crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags); } +/** + * crypto_aead_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the AEAD referenced by the cipher + * handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) { @@ -1239,6 +1334,16 @@ static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, return crt->setkey(crt->base, key, keylen); } +/** + * crypto_aead_setauthsize() - set authentication data size + * @tfm: cipher handle + * @authsize: size of the authentication data / tag in bytes + * + * Set the authentication data size / tag size. AEAD requires an authentication + * tag (or MAC) in addition to the associated data. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) @@ -1246,27 +1351,105 @@ static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) return __crypto_aead_cast(req->base.tfm); } +/** + * crypto_aead_encrypt() - encrypt plaintext + * @req: reference to the aead_request handle that holds all information + * needed to perform the cipher operation + * + * Encrypt plaintext data using the aead_request handle. That data structure + * and how it is filled with data is discussed with the aead_request_* + * functions. + * + * IMPORTANT NOTE The encryption operation creates the authentication data / + * tag. That data is concatenated with the created ciphertext. + * The ciphertext memory size is therefore the given number of + * block cipher blocks + the size defined by the + * crypto_aead_setauthsize invocation. The caller must ensure + * that sufficient memory is available for the ciphertext and + * the authentication tag. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_aead_encrypt(struct aead_request *req) { return crypto_aead_crt(crypto_aead_reqtfm(req))->encrypt(req); } +/** + * crypto_aead_decrypt() - decrypt ciphertext + * @req: reference to the ablkcipher_request handle that holds all information + * needed to perform the cipher operation + * + * Decrypt ciphertext data using the aead_request handle. That data structure + * and how it is filled with data is discussed with the aead_request_* + * functions. + * + * IMPORTANT NOTE The caller must concatenate the ciphertext followed by the + * authentication data / tag. That authentication data / tag + * must have the size defined by the crypto_aead_setauthsize + * invocation. + * + * + * Return: 0 if the cipher operation was successful; -EBADMSG: The AEAD + * cipher operation performs the authentication of the data during the + * decryption operation. Therefore, the function returns this error if + * the authentication of the ciphertext was unsuccessful (i.e. the + * integrity of the ciphertext or the associated data was violated); + * < 0 if an error occurred. + */ static inline int crypto_aead_decrypt(struct aead_request *req) { return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req); } +/** + * DOC: Asynchronous AEAD Request Handle + * + * The aead_request data structure contains all pointers to data required for + * the AEAD cipher operation. This includes the cipher handle (which can be + * used by multiple aead_request instances), pointer to plaintext and + * ciphertext, asynchronous callback function, etc. It acts as a handle to the + * aead_request_* API calls in a similar way as AEAD handle to the + * crypto_aead_* API calls. + */ + +/** + * crypto_aead_reqsize() - obtain size of the request data structure + * @tfm: cipher handle + * + * Return: number of bytes + */ static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) { return crypto_aead_crt(tfm)->reqsize; } +/** + * aead_request_set_tfm() - update cipher handle reference in request + * @req: request handle to be modified + * @tfm: cipher handle that shall be added to the request handle + * + * Allow the caller to replace the existing aead handle in the request + * data structure with a different one. + */ static inline void aead_request_set_tfm(struct aead_request *req, struct crypto_aead *tfm) { req->base.tfm = crypto_aead_tfm(crypto_aead_crt(tfm)->base); } +/** + * aead_request_alloc() - allocate request data structure + * @tfm: cipher handle to be registered with the request + * @gfp: memory allocation flag that is handed to kmalloc by the API call. + * + * Allocate the request data structure that must be used with the AEAD + * encrypt and decrypt API calls. During the allocation, the provided aead + * handle is registered in the request data structure. + * + * Return: allocated request handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm, gfp_t gfp) { @@ -1280,11 +1463,40 @@ static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm, return req; } +/** + * aead_request_free() - zeroize and free request data structure + * @req: request data structure cipher handle to be freed + */ static inline void aead_request_free(struct aead_request *req) { kzfree(req); } +/** + * aead_request_set_callback() - set asynchronous callback function + * @req: request handle + * @flags: specify zero or an ORing of the flags + * CRYPTO_TFM_REQ_MAY_BACKLOG the request queue may back log and + * increase the wait queue beyond the initial maximum size; + * CRYPTO_TFM_REQ_MAY_SLEEP the request processing may sleep + * @compl: callback function pointer to be registered with the request handle + * @data: The data pointer refers to memory that is not used by the kernel + * crypto API, but provided to the callback function for it to use. Here, + * the caller can provide a reference to memory the callback function can + * operate on. As the callback function is invoked asynchronously to the + * related functionality, it may need to access data structures of the + * related functionality which can be referenced using this pointer. The + * callback function can access the memory via the "data" field in the + * crypto_async_request data structure provided to the callback function. + * + * Setting the callback function that is triggered once the cipher operation + * completes + * + * The callback function is registered with the aead_request handle and + * must comply with the following template: + * + * void callback_function(struct crypto_async_request *req, int error) + */ static inline void aead_request_set_callback(struct aead_request *req, u32 flags, crypto_completion_t compl, @@ -1295,6 +1507,36 @@ static inline void aead_request_set_callback(struct aead_request *req, req->base.flags = flags; } +/** + * aead_request_set_crypt - set data buffers + * @req: request handle + * @src: source scatter / gather list + * @dst: destination scatter / gather list + * @cryptlen: number of bytes to process from @src + * @iv: IV for the cipher operation which must comply with the IV size defined + * by crypto_aead_ivsize() + * + * Setting the source data and destination data scatter / gather lists. + * + * For encryption, the source is treated as the plaintext and the + * destination is the ciphertext. For a decryption operation, the use is + * reversed: the source is the ciphertext and the destination is the plaintext. + * + * IMPORTANT NOTE AEAD requires an authentication tag (MAC). For decryption, + * the caller must concatenate the ciphertext followed by the + * authentication tag and provide the entire data stream to the + * decryption operation (i.e. the data length used for the + * initialization of the scatterlist and the data length for the + * decryption operation is identical). For encryption, however, + * the authentication tag is created while encrypting the data. + * The destination buffer must hold sufficient space for the + * ciphertext and the authentication tag while the encryption + * invocation must only point to the plaintext data size. The + * following code snippet illustrates the memory usage + * buffer = kmalloc(ptbuflen + (enc ? authsize : 0)); + * sg_init_one(&sg, buffer, ptbuflen + (enc ? authsize : 0)); + * aead_request_set_crypt(req, &sg, &sg, ptbuflen, iv); + */ static inline void aead_request_set_crypt(struct aead_request *req, struct scatterlist *src, struct scatterlist *dst, @@ -1306,6 +1548,15 @@ static inline void aead_request_set_crypt(struct aead_request *req, req->iv = iv; } +/** + * aead_request_set_assoc() - set the associated data scatter / gather list + * @req: request handle + * @assoc: associated data scatter / gather list + * @assoclen: number of bytes to process from @assoc + * + * For encryption, the memory is filled with the associated data. For + * decryption, the memory must point to the associated data. + */ static inline void aead_request_set_assoc(struct aead_request *req, struct scatterlist *assoc, unsigned int assoclen) -- GitLab From 58284f0d6c4a974d2d89446f3b3cbc51420432ea Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:29:36 +0100 Subject: [PATCH 4612/9457] crypto: doc - BLKCIPHER API documentation The API function calls exported by the kernel crypto API for synchronous block ciphers to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 188 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 4704e71a31fe..c9ebe456dc9e 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -1565,6 +1565,36 @@ static inline void aead_request_set_assoc(struct aead_request *req, req->assoclen = assoclen; } +/** + * DOC: Synchronous Block Cipher API + * + * The synchronous block cipher API is used with the ciphers of type + * CRYPTO_ALG_TYPE_BLKCIPHER (listed as type "blkcipher" in /proc/crypto) + * + * Synchronous calls, have a context in the tfm. But since a single tfm can be + * used in multiple calls and in parallel, this info should not be changeable + * (unless a lock is used). This applies, for example, to the symmetric key. + * However, the IV is changeable, so there is an iv field in blkcipher_tfm + * structure for synchronous blkcipher api. So, its the only state info that can + * be kept for synchronous calls without using a big lock across a tfm. + * + * The block cipher API allows the use of a complete cipher, i.e. a cipher + * consisting of a template (a block chaining mode) and a single block cipher + * primitive (e.g. AES). + * + * The plaintext data buffer and the ciphertext data buffer are pointed to + * by using scatter/gather lists. The cipher operation is performed + * on all segments of the provided scatter/gather lists. + * + * The kernel crypto API supports a cipher operation "in-place" which means that + * the caller may provide the same scatter/gather list for the plaintext and + * cipher text. After the completion of the cipher operation, the plaintext + * data is replaced with the ciphertext data in case of an encryption and vice + * versa for a decryption. The caller must ensure that the scatter/gather lists + * for the output data point to sufficiently large buffers, i.e. multiples of + * the block size of the cipher. + */ + static inline struct crypto_blkcipher *__crypto_blkcipher_cast( struct crypto_tfm *tfm) { @@ -1578,6 +1608,20 @@ static inline struct crypto_blkcipher *crypto_blkcipher_cast( return __crypto_blkcipher_cast(tfm); } +/** + * crypto_alloc_blkcipher() - allocate synchronous block cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * blkcipher cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a block cipher. The returned struct + * crypto_blkcipher is the cipher handle that is required for any subsequent + * API invocation for that block cipher. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct crypto_blkcipher *crypto_alloc_blkcipher( const char *alg_name, u32 type, u32 mask) { @@ -1594,11 +1638,25 @@ static inline struct crypto_tfm *crypto_blkcipher_tfm( return &tfm->base; } +/** + * crypto_free_blkcipher() - zeroize and free the block cipher handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm) { crypto_free_tfm(crypto_blkcipher_tfm(tfm)); } +/** + * crypto_has_blkcipher() - Search for the availability of a block cipher + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * block cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Return: true when the block cipher is known to the kernel crypto API; false + * otherwise + */ static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) { type &= ~CRYPTO_ALG_TYPE_MASK; @@ -1608,6 +1666,12 @@ static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) return crypto_has_alg(alg_name, type, mask); } +/** + * crypto_blkcipher_name() - return the name / cra_name from the cipher handle + * @tfm: cipher handle + * + * Return: The character string holding the name of the cipher + */ static inline const char *crypto_blkcipher_name(struct crypto_blkcipher *tfm) { return crypto_tfm_alg_name(crypto_blkcipher_tfm(tfm)); @@ -1625,11 +1689,30 @@ static inline struct blkcipher_alg *crypto_blkcipher_alg( return &crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher; } +/** + * crypto_blkcipher_ivsize() - obtain IV size + * @tfm: cipher handle + * + * The size of the IV for the block cipher referenced by the cipher handle is + * returned. This IV size may be zero if the cipher does not need an IV. + * + * Return: IV size in bytes + */ static inline unsigned int crypto_blkcipher_ivsize(struct crypto_blkcipher *tfm) { return crypto_blkcipher_alg(tfm)->ivsize; } +/** + * crypto_blkcipher_blocksize() - obtain block size of cipher + * @tfm: cipher handle + * + * The block size for the block cipher referenced with the cipher handle is + * returned. The caller may use that information to allocate appropriate + * memory for the data returned by the encryption or decryption operation. + * + * Return: block size of cipher + */ static inline unsigned int crypto_blkcipher_blocksize( struct crypto_blkcipher *tfm) { @@ -1659,6 +1742,22 @@ static inline void crypto_blkcipher_clear_flags(struct crypto_blkcipher *tfm, crypto_tfm_clear_flags(crypto_blkcipher_tfm(tfm), flags); } +/** + * crypto_blkcipher_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the block cipher referenced by the cipher + * handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_blkcipher_setkey(struct crypto_blkcipher *tfm, const u8 *key, unsigned int keylen) { @@ -1666,6 +1765,24 @@ static inline int crypto_blkcipher_setkey(struct crypto_blkcipher *tfm, key, keylen); } +/** + * crypto_blkcipher_encrypt() - encrypt plaintext + * @desc: reference to the block cipher handle with meta data + * @dst: scatter/gather list that is filled by the cipher operation with the + * ciphertext + * @src: scatter/gather list that holds the plaintext + * @nbytes: number of bytes of the plaintext to encrypt. + * + * Encrypt plaintext data using the IV set by the caller with a preceding + * call of crypto_blkcipher_set_iv. + * + * The blkcipher_desc data structure must be filled by the caller and can + * reside on the stack. The caller must fill desc as follows: desc.tfm is filled + * with the block cipher handle; desc.flags is filled with either + * CRYPTO_TFM_REQ_MAY_SLEEP or 0. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_blkcipher_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, @@ -1675,6 +1792,25 @@ static inline int crypto_blkcipher_encrypt(struct blkcipher_desc *desc, return crypto_blkcipher_crt(desc->tfm)->encrypt(desc, dst, src, nbytes); } +/** + * crypto_blkcipher_encrypt_iv() - encrypt plaintext with dedicated IV + * @desc: reference to the block cipher handle with meta data + * @dst: scatter/gather list that is filled by the cipher operation with the + * ciphertext + * @src: scatter/gather list that holds the plaintext + * @nbytes: number of bytes of the plaintext to encrypt. + * + * Encrypt plaintext data with the use of an IV that is solely used for this + * cipher operation. Any previously set IV is not used. + * + * The blkcipher_desc data structure must be filled by the caller and can + * reside on the stack. The caller must fill desc as follows: desc.tfm is filled + * with the block cipher handle; desc.info is filled with the IV to be used for + * the current operation; desc.flags is filled with either + * CRYPTO_TFM_REQ_MAY_SLEEP or 0. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_blkcipher_encrypt_iv(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, @@ -1683,6 +1819,23 @@ static inline int crypto_blkcipher_encrypt_iv(struct blkcipher_desc *desc, return crypto_blkcipher_crt(desc->tfm)->encrypt(desc, dst, src, nbytes); } +/** + * crypto_blkcipher_decrypt() - decrypt ciphertext + * @desc: reference to the block cipher handle with meta data + * @dst: scatter/gather list that is filled by the cipher operation with the + * plaintext + * @src: scatter/gather list that holds the ciphertext + * @nbytes: number of bytes of the ciphertext to decrypt. + * + * Decrypt ciphertext data using the IV set by the caller with a preceding + * call of crypto_blkcipher_set_iv. + * + * The blkcipher_desc data structure must be filled by the caller as documented + * for the crypto_blkcipher_encrypt call above. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + * + */ static inline int crypto_blkcipher_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, @@ -1692,6 +1845,22 @@ static inline int crypto_blkcipher_decrypt(struct blkcipher_desc *desc, return crypto_blkcipher_crt(desc->tfm)->decrypt(desc, dst, src, nbytes); } +/** + * crypto_blkcipher_decrypt_iv() - decrypt ciphertext with dedicated IV + * @desc: reference to the block cipher handle with meta data + * @dst: scatter/gather list that is filled by the cipher operation with the + * plaintext + * @src: scatter/gather list that holds the ciphertext + * @nbytes: number of bytes of the ciphertext to decrypt. + * + * Decrypt ciphertext data with the use of an IV that is solely used for this + * cipher operation. Any previously set IV is not used. + * + * The blkcipher_desc data structure must be filled by the caller as documented + * for the crypto_blkcipher_encrypt_iv call above. + * + * Return: 0 if the cipher operation was successful; < 0 if an error occurred + */ static inline int crypto_blkcipher_decrypt_iv(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, @@ -1700,12 +1869,31 @@ static inline int crypto_blkcipher_decrypt_iv(struct blkcipher_desc *desc, return crypto_blkcipher_crt(desc->tfm)->decrypt(desc, dst, src, nbytes); } +/** + * crypto_blkcipher_set_iv() - set IV for cipher + * @tfm: cipher handle + * @src: buffer holding the IV + * @len: length of the IV in bytes + * + * The caller provided IV is set for the block cipher referenced by the cipher + * handle. + */ static inline void crypto_blkcipher_set_iv(struct crypto_blkcipher *tfm, const u8 *src, unsigned int len) { memcpy(crypto_blkcipher_crt(tfm)->iv, src, len); } +/** + * crypto_blkcipher_get_iv() - obtain IV from cipher + * @tfm: cipher handle + * @dst: buffer filled with the IV + * @len: length of the buffer dst + * + * The caller can obtain the IV set for the block cipher referenced by the + * cipher handle and store it into the user-provided buffer. If the buffer + * has an insufficient space, the IV is truncated to fit the buffer. + */ static inline void crypto_blkcipher_get_iv(struct crypto_blkcipher *tfm, u8 *dst, unsigned int len) { -- GitLab From 16e61030aecb250766cf175141fc91d441361c43 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:30:06 +0100 Subject: [PATCH 4613/9457] crypto: doc - CIPHER API documentation The API function calls exported by the kernel crypto API for signle block ciphers to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index c9ebe456dc9e..0f95a07aa4df 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -1900,6 +1900,23 @@ static inline void crypto_blkcipher_get_iv(struct crypto_blkcipher *tfm, memcpy(dst, crypto_blkcipher_crt(tfm)->iv, len); } +/** + * DOC: Single Block Cipher API + * + * The single block cipher API is used with the ciphers of type + * CRYPTO_ALG_TYPE_CIPHER (listed as type "cipher" in /proc/crypto). + * + * Using the single block cipher API calls, operations with the basic cipher + * primitive can be implemented. These cipher primitives exclude any block + * chaining operations including IV handling. + * + * The purpose of this single block cipher API is to support the implementation + * of templates or other concepts that only need to perform the cipher operation + * on one block at a time. Templates invoke the underlying cipher primitive + * block-wise and process either the input or the output data of these cipher + * operations. + */ + static inline struct crypto_cipher *__crypto_cipher_cast(struct crypto_tfm *tfm) { return (struct crypto_cipher *)tfm; @@ -1911,6 +1928,20 @@ static inline struct crypto_cipher *crypto_cipher_cast(struct crypto_tfm *tfm) return __crypto_cipher_cast(tfm); } +/** + * crypto_alloc_cipher() - allocate single block cipher handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * single block cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a single block cipher. The returned struct + * crypto_cipher is the cipher handle that is required for any subsequent API + * invocation for that single block cipher. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask) { @@ -1926,11 +1957,25 @@ static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm) return &tfm->base; } +/** + * crypto_free_cipher() - zeroize and free the single block cipher handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_cipher(struct crypto_cipher *tfm) { crypto_free_tfm(crypto_cipher_tfm(tfm)); } +/** + * crypto_has_cipher() - Search for the availability of a single block cipher + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * single block cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Return: true when the single block cipher is known to the kernel crypto API; + * false otherwise + */ static inline int crypto_has_cipher(const char *alg_name, u32 type, u32 mask) { type &= ~CRYPTO_ALG_TYPE_MASK; @@ -1945,6 +1990,16 @@ static inline struct cipher_tfm *crypto_cipher_crt(struct crypto_cipher *tfm) return &crypto_cipher_tfm(tfm)->crt_cipher; } +/** + * crypto_cipher_blocksize() - obtain block size for cipher + * @tfm: cipher handle + * + * The block size for the single block cipher referenced with the cipher handle + * tfm is returned. The caller may use that information to allocate appropriate + * memory for the data returned by the encryption or decryption operation + * + * Return: block size of cipher + */ static inline unsigned int crypto_cipher_blocksize(struct crypto_cipher *tfm) { return crypto_tfm_alg_blocksize(crypto_cipher_tfm(tfm)); @@ -1972,6 +2027,22 @@ static inline void crypto_cipher_clear_flags(struct crypto_cipher *tfm, crypto_tfm_clear_flags(crypto_cipher_tfm(tfm), flags); } +/** + * crypto_cipher_setkey() - set key for cipher + * @tfm: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the single block cipher referenced by the + * cipher handle. + * + * Note, the key length determines the cipher type. Many block ciphers implement + * different cipher modes depending on the key size, such as AES-128 vs AES-192 + * vs. AES-256. When providing a 16 byte key for an AES cipher handle, AES-128 + * is performed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_cipher_setkey(struct crypto_cipher *tfm, const u8 *key, unsigned int keylen) { @@ -1979,6 +2050,15 @@ static inline int crypto_cipher_setkey(struct crypto_cipher *tfm, key, keylen); } +/** + * crypto_cipher_encrypt_one() - encrypt one block of plaintext + * @tfm: cipher handle + * @dst: points to the buffer that will be filled with the ciphertext + * @src: buffer holding the plaintext to be encrypted + * + * Invoke the encryption operation of one block. The caller must ensure that + * the plaintext and ciphertext buffers are at least one block in size. + */ static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src) { @@ -1986,6 +2066,15 @@ static inline void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, dst, src); } +/** + * crypto_cipher_decrypt_one() - decrypt one block of ciphertext + * @tfm: cipher handle + * @dst: points to the buffer that will be filled with the plaintext + * @src: buffer holding the ciphertext to be decrypted + * + * Invoke the decryption operation of one block. The caller must ensure that + * the plaintext and ciphertext buffers are at least one block in size. + */ static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src) { -- GitLab From 47ca5be9eb066befe284f4e03fc11f21b8321ddc Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Wed, 12 Nov 2014 05:30:42 +0100 Subject: [PATCH 4614/9457] crypto: doc - HASH API documentation The API function calls exported by the kernel crypto API for message digests to be used by consumers are documented. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/linux/crypto.h | 119 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 0f95a07aa4df..208a63290b23 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -2082,6 +2082,13 @@ static inline void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, dst, src); } +/** + * DOC: Synchronous Message Digest API + * + * The synchronous message digest API is used with the ciphers of type + * CRYPTO_ALG_TYPE_HASH (listed as type "hash" in /proc/crypto) + */ + static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm) { return (struct crypto_hash *)tfm; @@ -2094,6 +2101,20 @@ static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm) return __crypto_hash_cast(tfm); } +/** + * crypto_alloc_hash() - allocate synchronous message digest handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * message digest cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Allocate a cipher handle for a message digest. The returned struct + * crypto_hash is the cipher handle that is required for any subsequent + * API invocation for that message digest. + * + * Return: allocated cipher handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name, u32 type, u32 mask) { @@ -2110,11 +2131,25 @@ static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm) return &tfm->base; } +/** + * crypto_free_hash() - zeroize and free message digest handle + * @tfm: cipher handle to be freed + */ static inline void crypto_free_hash(struct crypto_hash *tfm) { crypto_free_tfm(crypto_hash_tfm(tfm)); } +/** + * crypto_has_hash() - Search for the availability of a message digest + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * message digest cipher + * @type: specifies the type of the cipher + * @mask: specifies the mask for the cipher + * + * Return: true when the message digest cipher is known to the kernel crypto + * API; false otherwise + */ static inline int crypto_has_hash(const char *alg_name, u32 type, u32 mask) { type &= ~CRYPTO_ALG_TYPE_MASK; @@ -2130,6 +2165,15 @@ static inline struct hash_tfm *crypto_hash_crt(struct crypto_hash *tfm) return &crypto_hash_tfm(tfm)->crt_hash; } +/** + * crypto_hash_blocksize() - obtain block size for message digest + * @tfm: cipher handle + * + * The block size for the message digest cipher referenced with the cipher + * handle is returned. + * + * Return: block size of cipher + */ static inline unsigned int crypto_hash_blocksize(struct crypto_hash *tfm) { return crypto_tfm_alg_blocksize(crypto_hash_tfm(tfm)); @@ -2140,6 +2184,15 @@ static inline unsigned int crypto_hash_alignmask(struct crypto_hash *tfm) return crypto_tfm_alg_alignmask(crypto_hash_tfm(tfm)); } +/** + * crypto_hash_digestsize() - obtain message digest size + * @tfm: cipher handle + * + * The size for the message digest created by the message digest cipher + * referenced with the cipher handle is returned. + * + * Return: message digest size + */ static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm) { return crypto_hash_crt(tfm)->digestsize; @@ -2160,11 +2213,38 @@ static inline void crypto_hash_clear_flags(struct crypto_hash *tfm, u32 flags) crypto_tfm_clear_flags(crypto_hash_tfm(tfm), flags); } +/** + * crypto_hash_init() - (re)initialize message digest handle + * @desc: cipher request handle that to be filled by caller -- + * desc.tfm is filled with the hash cipher handle; + * desc.flags is filled with either CRYPTO_TFM_REQ_MAY_SLEEP or 0. + * + * The call (re-)initializes the message digest referenced by the hash cipher + * request handle. Any potentially existing state created by previous + * operations is discarded. + * + * Return: 0 if the message digest initialization was successful; < 0 if an + * error occurred + */ static inline int crypto_hash_init(struct hash_desc *desc) { return crypto_hash_crt(desc->tfm)->init(desc); } +/** + * crypto_hash_update() - add data to message digest for processing + * @desc: cipher request handle + * @sg: scatter / gather list pointing to the data to be added to the message + * digest + * @nbytes: number of bytes to be processed from @sg + * + * Updates the message digest state of the cipher handle pointed to by the + * hash cipher request handle with the input data pointed to by the + * scatter/gather list. + * + * Return: 0 if the message digest update was successful; < 0 if an error + * occurred + */ static inline int crypto_hash_update(struct hash_desc *desc, struct scatterlist *sg, unsigned int nbytes) @@ -2172,11 +2252,39 @@ static inline int crypto_hash_update(struct hash_desc *desc, return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes); } +/** + * crypto_hash_final() - calculate message digest + * @desc: cipher request handle + * @out: message digest output buffer -- The caller must ensure that the out + * buffer has a sufficient size (e.g. by using the crypto_hash_digestsize + * function). + * + * Finalize the message digest operation and create the message digest + * based on all data added to the cipher handle. The message digest is placed + * into the output buffer. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ static inline int crypto_hash_final(struct hash_desc *desc, u8 *out) { return crypto_hash_crt(desc->tfm)->final(desc, out); } +/** + * crypto_hash_digest() - calculate message digest for a buffer + * @desc: see crypto_hash_final() + * @sg: see crypto_hash_update() + * @nbytes: see crypto_hash_update() + * @out: see crypto_hash_final() + * + * This function is a "short-hand" for the function calls of crypto_hash_init, + * crypto_hash_update and crypto_hash_final. The parameters have the same + * meaning as discussed for those separate three functions. + * + * Return: 0 if the message digest creation was successful; < 0 if an error + * occurred + */ static inline int crypto_hash_digest(struct hash_desc *desc, struct scatterlist *sg, unsigned int nbytes, u8 *out) @@ -2184,6 +2292,17 @@ static inline int crypto_hash_digest(struct hash_desc *desc, return crypto_hash_crt(desc->tfm)->digest(desc, sg, nbytes, out); } +/** + * crypto_hash_setkey() - set key for message digest + * @hash: cipher handle + * @key: buffer holding the key + * @keylen: length of the key in bytes + * + * The caller provided key is set for the message digest cipher. The cipher + * handle must point to a keyed hash in order for this function to succeed. + * + * Return: 0 if the setting of the key was successful; < 0 if an error occurred + */ static inline int crypto_hash_setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen) { -- GitLab From ce433f8090da6784cdee754defcbf325fc66f274 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Wed, 12 Nov 2014 15:00:06 -0500 Subject: [PATCH 4615/9457] tile: avoid undefined behavior with regs[TREG_TP] etc Recent compilers warn about accesses to arrays past the end, which is supported for pt_regs and sigcontext with the intended alias past the end of regs[] to sp, tp, and lr using TREG_SP, TREG_TP, and TREG_LR. Make the intended usage explict by providing an anonymous union of regs[56] on the one hand, and a short __regs[53] on the other followed by the sp, tp, and lr fields, so the aliasing is done explicitly and is visible to the compiler. Reviewed-by: Jeff Epler Signed-off-by: Chris Metcalf --- arch/tile/include/uapi/asm/ptrace.h | 16 ++++++++++------ arch/tile/include/uapi/asm/sigcontext.h | 14 ++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/tile/include/uapi/asm/ptrace.h b/arch/tile/include/uapi/asm/ptrace.h index 7757e1985fb6..d03b829857e8 100644 --- a/arch/tile/include/uapi/asm/ptrace.h +++ b/arch/tile/include/uapi/asm/ptrace.h @@ -52,12 +52,16 @@ typedef uint_reg_t pt_reg_t; * system call or exception. "struct sigcontext" has the same shape. */ struct pt_regs { - /* Saved main processor registers; 56..63 are special. */ - /* tp, sp, and lr must immediately follow regs[] for aliasing. */ - pt_reg_t regs[53]; - pt_reg_t tp; /* aliases regs[TREG_TP] */ - pt_reg_t sp; /* aliases regs[TREG_SP] */ - pt_reg_t lr; /* aliases regs[TREG_LR] */ + union { + /* Saved main processor registers; 56..63 are special. */ + pt_reg_t regs[56]; + struct { + pt_reg_t __regs[53]; + pt_reg_t tp; /* aliases regs[TREG_TP] */ + pt_reg_t sp; /* aliases regs[TREG_SP] */ + pt_reg_t lr; /* aliases regs[TREG_LR] */ + }; + }; /* Saved special registers. */ pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */ diff --git a/arch/tile/include/uapi/asm/sigcontext.h b/arch/tile/include/uapi/asm/sigcontext.h index 6348e59d3724..39ff5d1a232d 100644 --- a/arch/tile/include/uapi/asm/sigcontext.h +++ b/arch/tile/include/uapi/asm/sigcontext.h @@ -24,10 +24,16 @@ * but is simplified since we know the fault is from userspace. */ struct sigcontext { - __uint_reg_t gregs[53]; /* General-purpose registers. */ - __uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ - __uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ - __uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ + __extension__ union { + /* General-purpose registers. */ + __uint_reg_t gregs[56]; + __extension__ struct { + __uint_reg_t __gregs[53]; + __uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ + __uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ + __uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ + }; + }; __uint_reg_t pc; /* Program counter. */ __uint_reg_t ics; /* In Interrupt Critical Section? */ __uint_reg_t faultnum; /* Fault number. */ -- GitLab From c47b15c4928c46b889a1ea2e9b54f4110514e1c3 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Thu, 13 Nov 2014 09:41:58 -0500 Subject: [PATCH 4616/9457] arch/tile: update MAINTAINERS email to EZchip EZchip Semiconductor closed the acquisition of Tilera Corp last week, and tilera.com email addresses are now ezchip.com. http://www.ezchip.com/pr_141106.htm Signed-off-by: Chris Metcalf --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3c6427190be2..81764acd163d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9362,7 +9362,7 @@ F: include/uapi/linux/tipc*.h F: net/tipc/ TILE ARCHITECTURE -M: Chris Metcalf +M: Chris Metcalf W: http://www.tilera.com/scm/ S: Supported F: arch/tile/ -- GitLab From db4fd5197b8c7223af9be8cd3f8d8b7239e5d06c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 15:40:58 +0200 Subject: [PATCH 4617/9457] drm/tegra: Depend on COMMON_CLK The introduction of the COMPILE_TEST dependency in commit 158b50aefa14 (drm/tegra: Increase compile test coverage) removes the dependency on COMMON_CLK (implicitly selected via ARCH_TEGRA, ARCH_MULTI_V7 and ARCH_MULTIPLATFORM). Reported-by: Russell King Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 354ddb29231f..74d9d621453d 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -1,6 +1,7 @@ config DRM_TEGRA tristate "NVIDIA Tegra DRM" depends on ARCH_TEGRA || (ARM && COMPILE_TEST) + depends on COMMON_CLK depends on DRM depends on RESET_CONTROLLER select DRM_KMS_HELPER -- GitLab From b40d02bf96e05851d1d16b4a75f66a9e16cfb2fb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Jun 2014 13:14:50 +0200 Subject: [PATCH 4618/9457] gpu: host1x: Use struct host1x_bo pointers in traces Rather than cast to a u32 use the struct host1x_bo pointers directly. This avoid annoying warnings for 64-bit builds. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/channel_hw.c | 12 ++++++++---- include/trace/events/host1x.h | 27 +++++++++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 4608257ab656..946c332c3906 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -32,6 +32,7 @@ static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo, u32 offset, u32 words) { + struct device *dev = cdma_to_channel(cdma)->dev; void *mem = NULL; if (host1x_debug_trace_cmdbuf) @@ -44,11 +45,14 @@ static void trace_write_gather(struct host1x_cdma *cdma, struct host1x_bo *bo, * of how much you can output to ftrace at once. */ for (i = 0; i < words; i += TRACE_MAX_LENGTH) { - trace_host1x_cdma_push_gather( - dev_name(cdma_to_channel(cdma)->dev), - (u32)bo, min(words - i, TRACE_MAX_LENGTH), - offset + i * sizeof(u32), mem); + u32 num_words = min(words - i, TRACE_MAX_LENGTH); + offset += i * sizeof(u32); + + trace_host1x_cdma_push_gather(dev_name(dev), bo, + num_words, offset, + mem); } + host1x_bo_munmap(bo, mem); } } diff --git a/include/trace/events/host1x.h b/include/trace/events/host1x.h index 94db6a2c3540..63116362543c 100644 --- a/include/trace/events/host1x.h +++ b/include/trace/events/host1x.h @@ -29,6 +29,8 @@ #include #include +struct host1x_bo; + DECLARE_EVENT_CLASS(host1x, TP_PROTO(const char *name), TP_ARGS(name), @@ -79,14 +81,14 @@ TRACE_EVENT(host1x_cdma_push, ); TRACE_EVENT(host1x_cdma_push_gather, - TP_PROTO(const char *name, u32 mem_id, + TP_PROTO(const char *name, struct host1x_bo *bo, u32 words, u32 offset, void *cmdbuf), - TP_ARGS(name, mem_id, words, offset, cmdbuf), + TP_ARGS(name, bo, words, offset, cmdbuf), TP_STRUCT__entry( __field(const char *, name) - __field(u32, mem_id) + __field(struct host1x_bo *, bo) __field(u32, words) __field(u32, offset) __field(bool, cmdbuf) @@ -100,13 +102,13 @@ TRACE_EVENT(host1x_cdma_push_gather, } __entry->cmdbuf = cmdbuf; __entry->name = name; - __entry->mem_id = mem_id; + __entry->bo = bo; __entry->words = words; __entry->offset = offset; ), - TP_printk("name=%s, mem_id=%08x, words=%u, offset=%d, contents=[%s]", - __entry->name, __entry->mem_id, + TP_printk("name=%s, bo=%p, words=%u, offset=%d, contents=[%s]", + __entry->name, __entry->bo, __entry->words, __entry->offset, __print_hex(__get_dynamic_array(cmdbuf), __entry->cmdbuf ? __entry->words * 4 : 0)) @@ -221,12 +223,13 @@ TRACE_EVENT(host1x_syncpt_load_min, ); TRACE_EVENT(host1x_syncpt_wait_check, - TP_PROTO(void *mem_id, u32 offset, u32 syncpt_id, u32 thresh, u32 min), + TP_PROTO(struct host1x_bo *bo, u32 offset, u32 syncpt_id, u32 thresh, + u32 min), - TP_ARGS(mem_id, offset, syncpt_id, thresh, min), + TP_ARGS(bo, offset, syncpt_id, thresh, min), TP_STRUCT__entry( - __field(void *, mem_id) + __field(struct host1x_bo *, bo) __field(u32, offset) __field(u32, syncpt_id) __field(u32, thresh) @@ -234,15 +237,15 @@ TRACE_EVENT(host1x_syncpt_wait_check, ), TP_fast_assign( - __entry->mem_id = mem_id; + __entry->bo = bo; __entry->offset = offset; __entry->syncpt_id = syncpt_id; __entry->thresh = thresh; __entry->min = min; ), - TP_printk("mem_id=%p, offset=%05x, id=%d, thresh=%d, current=%d", - __entry->mem_id, __entry->offset, + TP_printk("bo=%p, offset=%05x, id=%d, thresh=%d, current=%d", + __entry->bo, __entry->offset, __entry->syncpt_id, __entry->thresh, __entry->min) ); -- GitLab From 0169b93f4492c74d046b456d93b37bd7b55ecd42 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Jun 2014 13:16:54 +0200 Subject: [PATCH 4619/9457] gpu: host1x: Make mapped field of push buffers void * This reduces the amount of casting that needs to be done to get rid of annoying warnings on 64-bit builds. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/cdma.c | 2 +- drivers/gpu/host1x/cdma.h | 2 +- drivers/gpu/host1x/hw/cdma_hw.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c index 3995255b16c7..5a8c8d55317a 100644 --- a/drivers/gpu/host1x/cdma.c +++ b/drivers/gpu/host1x/cdma.c @@ -97,7 +97,7 @@ static int host1x_pushbuffer_init(struct push_buffer *pb) static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2) { u32 pos = pb->pos; - u32 *p = (u32 *)((u32)pb->mapped + pos); + u32 *p = (u32 *)((void *)pb->mapped + pos); WARN_ON(pos == pb->fence); *(p++) = op1; *(p++) = op2; diff --git a/drivers/gpu/host1x/cdma.h b/drivers/gpu/host1x/cdma.h index 313c4b784348..470087af8fe5 100644 --- a/drivers/gpu/host1x/cdma.h +++ b/drivers/gpu/host1x/cdma.h @@ -42,7 +42,7 @@ struct host1x_job; */ struct push_buffer { - u32 *mapped; /* mapped pushbuffer memory */ + void *mapped; /* mapped pushbuffer memory */ dma_addr_t phys; /* physical address of pushbuffer */ u32 fence; /* index we've written */ u32 pos; /* index to write to */ diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c index 6b09b71940c2..a1197c40a454 100644 --- a/drivers/gpu/host1x/hw/cdma_hw.c +++ b/drivers/gpu/host1x/hw/cdma_hw.c @@ -30,7 +30,7 @@ */ static void push_buffer_init(struct push_buffer *pb) { - *(pb->mapped + (pb->size_bytes >> 2)) = host1x_opcode_restart(0); + *(u32 *)(pb->mapped + pb->size_bytes) = host1x_opcode_restart(0); } /* @@ -51,7 +51,7 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr, /* NOP all the PB slots */ while (nr_slots--) { - u32 *p = (u32 *)((u32)pb->mapped + getptr); + u32 *p = (u32 *)(pb->mapped + getptr); *(p++) = HOST1X_OPCODE_NOP; *(p++) = HOST1X_OPCODE_NOP; dev_dbg(host1x->dev, "%s: NOP at %#llx\n", __func__, -- GitLab From 7f27d60b28f6dbc9762407aac596b53f2a71a867 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Jun 2014 13:17:48 +0200 Subject: [PATCH 4620/9457] gpu: host1x: Fix typo in comment Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/cdma_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c index a1197c40a454..072d8209c06c 100644 --- a/drivers/gpu/host1x/hw/cdma_hw.c +++ b/drivers/gpu/host1x/hw/cdma_hw.c @@ -26,7 +26,7 @@ #include "../debug.h" /* - * Put the restart at the end of pushbuffer memor + * Put the restart at the end of pushbuffer memory */ static void push_buffer_init(struct push_buffer *pb) { -- GitLab From ba73fbc2ca221e80c6733e68496ad07bc3b58ff8 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Jun 2014 13:24:17 +0200 Subject: [PATCH 4621/9457] gpu: host1x: Print address/offset pairs consistently Consistently use a format of %pad+%#x to print address/offset in debug messages. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/cdma_hw.c | 4 ++-- drivers/gpu/host1x/hw/debug_hw.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c index 072d8209c06c..305ea8f3382d 100644 --- a/drivers/gpu/host1x/hw/cdma_hw.c +++ b/drivers/gpu/host1x/hw/cdma_hw.c @@ -54,8 +54,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr, u32 *p = (u32 *)(pb->mapped + getptr); *(p++) = HOST1X_OPCODE_NOP; *(p++) = HOST1X_OPCODE_NOP; - dev_dbg(host1x->dev, "%s: NOP at %#llx\n", __func__, - (u64)pb->phys + getptr); + dev_dbg(host1x->dev, "%s: NOP at %pad+%#x\n", __func__, + &pb->phys, getptr); getptr = (getptr + 8) & (pb->size_bytes - 1); } wmb(); diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index f72c873eff81..791de9351eeb 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -163,8 +163,8 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) continue; } - host1x_debug_output(o, " GATHER at %#llx+%04x, %d words\n", - (u64)g->base, g->offset, g->words); + host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n", + &g->base, g->offset, g->words); show_gather(o, g->base + g->offset, g->words, cdma, g->base, mapped); -- GitLab From 3880e95f2706e4ad9ba37e382e7f5bb82f911c68 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 12 Jun 2014 13:26:19 +0200 Subject: [PATCH 4622/9457] gpu: host1x: Make gather offsets unsigned Use the u32 type for the offset in the host1x_job_gather structure for consistentcy with other structures. Negative offsets don't make sense in this context. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/job.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/host1x/job.h b/drivers/gpu/host1x/job.h index 33a697d6dcef..8b3c15df0660 100644 --- a/drivers/gpu/host1x/job.h +++ b/drivers/gpu/host1x/job.h @@ -23,7 +23,7 @@ struct host1x_job_gather { u32 words; dma_addr_t base; struct host1x_bo *bo; - int offset; + u32 offset; bool handled; }; -- GitLab From 57b17ae71f412b870415b698655f00846e34ce0a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 2 Oct 2014 14:33:31 +0200 Subject: [PATCH 4623/9457] gpu: host1x: mipi: Registers are 32 bits wide On 64-bit platforms an unsigned long would be 64 bit and cause unnecessary casting when being passed to writel() or returned from readl(). Make register values 32 bits wide to avoid that. Signed-off-by: Thierry Reding --- drivers/gpu/host1x/mipi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 9882ea122024..a3e215a0116f 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -90,16 +90,16 @@ struct tegra_mipi_device { unsigned long pads; }; -static inline unsigned long tegra_mipi_readl(struct tegra_mipi *mipi, - unsigned long reg) +static inline u32 tegra_mipi_readl(struct tegra_mipi *mipi, + unsigned long offset) { - return readl(mipi->regs + (reg << 2)); + return readl(mipi->regs + (offset << 2)); } -static inline void tegra_mipi_writel(struct tegra_mipi *mipi, - unsigned long value, unsigned long reg) +static inline void tegra_mipi_writel(struct tegra_mipi *mipi, u32 value, + unsigned long offset) { - writel(value, mipi->regs + (reg << 2)); + writel(value, mipi->regs + (offset << 2)); } struct tegra_mipi_device *tegra_mipi_request(struct device *device) @@ -161,7 +161,7 @@ EXPORT_SYMBOL(tegra_mipi_free); static int tegra_mipi_wait(struct tegra_mipi *mipi) { unsigned long timeout = jiffies + msecs_to_jiffies(250); - unsigned long value; + u32 value; while (time_before(jiffies, timeout)) { value = tegra_mipi_readl(mipi, MIPI_CAL_STATUS); @@ -177,8 +177,8 @@ static int tegra_mipi_wait(struct tegra_mipi *mipi) int tegra_mipi_calibrate(struct tegra_mipi_device *device) { - unsigned long value; unsigned int i; + u32 value; int err; err = clk_enable(device->mipi->clk); -- GitLab From 26f7a92a3a275cad7b0f39063e8cd92e002aff1a Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 10 Sep 2014 10:52:03 -0400 Subject: [PATCH 4624/9457] gpu: host1x: mipi: Preserve the contents of MIPI_CAL_CTRL By paving the CTRL reg value, the current code changes MIPI_CAL_PRESCALE ("Auto-cal calibration step prescale") from 1us to 0.1us (val=0). In the description for PHY's noise filter (MIPI_CAL_NOISE_FLT), the TRM states that if the value of the prescale is 0 (or 0.1us), the filter should be set between 2-5. However, the current code sets it to 0. For now, let's keep the prescale and filter values as-is, which is most likely the power-on-reset values of 0x2 and 0xa, respectively. Signed-off-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/host1x/mipi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index a3e215a0116f..0d8c3ae8db6a 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -208,7 +208,9 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) tegra_mipi_writel(device->mipi, value, modules[i].reg); } - tegra_mipi_writel(device->mipi, MIPI_CAL_CTRL_START, MIPI_CAL_CTRL); + value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL); + value |= MIPI_CAL_CTRL_START; + tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL); err = tegra_mipi_wait(device->mipi); -- GitLab From 08a15cc34ddf7b7247122de44687364bcd82c2bf Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 10 Sep 2014 10:52:04 -0400 Subject: [PATCH 4625/9457] gpu: host1x: mipi: Calibrate clock lanes Include the clock lanes when calibrating the MIPI PHY on Tegra124 compatible devices. Signed-off-by: Sean Paul [treding@nvidia.com: bikeshedding] Signed-off-by: Thierry Reding --- drivers/gpu/host1x/mipi.c | 124 ++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 0d8c3ae8db6a..22e20c2399c5 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -49,11 +49,24 @@ #define MIPI_CAL_CONFIG_DSIC 0x10 #define MIPI_CAL_CONFIG_DSID 0x11 +#define MIPI_CAL_CONFIG_DSIAB_CLK 0x19 +#define MIPI_CAL_CONFIG_DSICD_CLK 0x1a +#define MIPI_CAL_CONFIG_CSIAB_CLK 0x1b +#define MIPI_CAL_CONFIG_CSICD_CLK 0x1c +#define MIPI_CAL_CONFIG_CSIE_CLK 0x1d + +/* for data and clock lanes */ #define MIPI_CAL_CONFIG_SELECT (1 << 21) + +/* for data lanes */ #define MIPI_CAL_CONFIG_HSPDOS(x) (((x) & 0x1f) << 16) #define MIPI_CAL_CONFIG_HSPUOS(x) (((x) & 0x1f) << 8) #define MIPI_CAL_CONFIG_TERMOS(x) (((x) & 0x1f) << 0) +/* for clock lanes */ +#define MIPI_CAL_CONFIG_HSCLKPDOSD(x) (((x) & 0x1f) << 8) +#define MIPI_CAL_CONFIG_HSCLKPUOSD(x) (((x) & 0x1f) << 0) + #define MIPI_CAL_BIAS_PAD_CFG0 0x16 #define MIPI_CAL_BIAS_PAD_PDVCLAMP (1 << 1) #define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF (1 << 0) @@ -63,21 +76,19 @@ #define MIPI_CAL_BIAS_PAD_CFG2 0x18 #define MIPI_CAL_BIAS_PAD_PDVREG (1 << 1) -static const struct module { - unsigned long reg; -} modules[] = { - { .reg = MIPI_CAL_CONFIG_CSIA }, - { .reg = MIPI_CAL_CONFIG_CSIB }, - { .reg = MIPI_CAL_CONFIG_CSIC }, - { .reg = MIPI_CAL_CONFIG_CSID }, - { .reg = MIPI_CAL_CONFIG_CSIE }, - { .reg = MIPI_CAL_CONFIG_DSIA }, - { .reg = MIPI_CAL_CONFIG_DSIB }, - { .reg = MIPI_CAL_CONFIG_DSIC }, - { .reg = MIPI_CAL_CONFIG_DSID }, +struct tegra_mipi_pad { + unsigned long data; + unsigned long clk; +}; + +struct tegra_mipi_soc { + bool has_clk_lane; + const struct tegra_mipi_pad *pads; + unsigned int num_pads; }; struct tegra_mipi { + const struct tegra_mipi_soc *soc; void __iomem *regs; struct mutex lock; struct clk *clk; @@ -117,36 +128,35 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device) dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { - of_node_put(args.np); err = -ENOMEM; goto out; } dev->pdev = of_find_device_by_node(args.np); if (!dev->pdev) { - of_node_put(args.np); err = -ENODEV; goto free; } - of_node_put(args.np); - dev->mipi = platform_get_drvdata(dev->pdev); if (!dev->mipi) { err = -EPROBE_DEFER; - goto pdev_put; + goto put; } + of_node_put(args.np); + dev->pads = args.args[0]; dev->device = device; return dev; -pdev_put: +put: platform_device_put(dev->pdev); free: kfree(dev); out: + of_node_put(args.np); return ERR_PTR(err); } EXPORT_SYMBOL(tegra_mipi_request); @@ -177,6 +187,7 @@ static int tegra_mipi_wait(struct tegra_mipi *mipi) int tegra_mipi_calibrate(struct tegra_mipi_device *device) { + const struct tegra_mipi_soc *soc = device->mipi->soc; unsigned int i; u32 value; int err; @@ -196,16 +207,23 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) value &= ~MIPI_CAL_BIAS_PAD_PDVREG; tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2); - for (i = 0; i < ARRAY_SIZE(modules); i++) { - if (device->pads & BIT(i)) - value = MIPI_CAL_CONFIG_SELECT | - MIPI_CAL_CONFIG_HSPDOS(0) | - MIPI_CAL_CONFIG_HSPUOS(4) | - MIPI_CAL_CONFIG_TERMOS(5); - else - value = 0; + for (i = 0; i < soc->num_pads; i++) { + u32 clk = 0, data = 0; + + if (device->pads & BIT(i)) { + data = MIPI_CAL_CONFIG_SELECT | + MIPI_CAL_CONFIG_HSPDOS(0) | + MIPI_CAL_CONFIG_HSPUOS(4) | + MIPI_CAL_CONFIG_TERMOS(5); + clk = MIPI_CAL_CONFIG_SELECT | + MIPI_CAL_CONFIG_HSCLKPDOSD(0) | + MIPI_CAL_CONFIG_HSCLKPUOSD(4); + } + + tegra_mipi_writel(device->mipi, data, soc->pads[i].data); - tegra_mipi_writel(device->mipi, value, modules[i].reg); + if (soc->has_clk_lane) + tegra_mipi_writel(device->mipi, clk, soc->pads[i].clk); } value = tegra_mipi_readl(device->mipi, MIPI_CAL_CTRL); @@ -221,16 +239,63 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) } EXPORT_SYMBOL(tegra_mipi_calibrate); +static const struct tegra_mipi_pad tegra114_mipi_pads[] = { + { .data = MIPI_CAL_CONFIG_CSIA }, + { .data = MIPI_CAL_CONFIG_CSIB }, + { .data = MIPI_CAL_CONFIG_CSIC }, + { .data = MIPI_CAL_CONFIG_CSID }, + { .data = MIPI_CAL_CONFIG_CSIE }, + { .data = MIPI_CAL_CONFIG_DSIA }, + { .data = MIPI_CAL_CONFIG_DSIB }, + { .data = MIPI_CAL_CONFIG_DSIC }, + { .data = MIPI_CAL_CONFIG_DSID }, +}; + +static const struct tegra_mipi_soc tegra114_mipi_soc = { + .has_clk_lane = false, + .pads = tegra114_mipi_pads, + .num_pads = ARRAY_SIZE(tegra114_mipi_pads), +}; + +static const struct tegra_mipi_pad tegra124_mipi_pads[] = { + { .data = MIPI_CAL_CONFIG_CSIA, .clk = MIPI_CAL_CONFIG_CSIAB_CLK }, + { .data = MIPI_CAL_CONFIG_CSIB, .clk = MIPI_CAL_CONFIG_CSIAB_CLK }, + { .data = MIPI_CAL_CONFIG_CSIC, .clk = MIPI_CAL_CONFIG_CSICD_CLK }, + { .data = MIPI_CAL_CONFIG_CSID, .clk = MIPI_CAL_CONFIG_CSICD_CLK }, + { .data = MIPI_CAL_CONFIG_CSIE, .clk = MIPI_CAL_CONFIG_CSIE_CLK }, + { .data = MIPI_CAL_CONFIG_DSIA, .clk = MIPI_CAL_CONFIG_DSIAB_CLK }, + { .data = MIPI_CAL_CONFIG_DSIB, .clk = MIPI_CAL_CONFIG_DSIAB_CLK }, +}; + +static const struct tegra_mipi_soc tegra124_mipi_soc = { + .has_clk_lane = true, + .pads = tegra124_mipi_pads, + .num_pads = ARRAY_SIZE(tegra124_mipi_pads), +}; + +static struct of_device_id tegra_mipi_of_match[] = { + { .compatible = "nvidia,tegra114-mipi", .data = &tegra114_mipi_soc }, + { .compatible = "nvidia,tegra124-mipi", .data = &tegra124_mipi_soc }, + { }, +}; + static int tegra_mipi_probe(struct platform_device *pdev) { + const struct of_device_id *match; struct tegra_mipi *mipi; struct resource *res; int err; + match = of_match_node(tegra_mipi_of_match, pdev->dev.of_node); + if (!match) + return -ENODEV; + mipi = devm_kzalloc(&pdev->dev, sizeof(*mipi), GFP_KERNEL); if (!mipi) return -ENOMEM; + mipi->soc = match->data; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mipi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mipi->regs)) @@ -262,11 +327,6 @@ static int tegra_mipi_remove(struct platform_device *pdev) return 0; } -static struct of_device_id tegra_mipi_of_match[] = { - { .compatible = "nvidia,tegra114-mipi", }, - { }, -}; - struct platform_driver tegra_mipi_driver = { .driver = { .name = "tegra-mipi", -- GitLab From b298e98ef6ab9c4279b427db717a1624ef722751 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 10 Sep 2014 10:52:05 -0400 Subject: [PATCH 4626/9457] gpu: host1x: mipi: Set MIPI_CAL_BIAS_PAD_CFG1 register During calibration, sets the "internal reference level for drive pull- down" to the value specified in the Tegra TRM. Signed-off-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/host1x/mipi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 22e20c2399c5..fbc6ee6ca337 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -72,6 +72,7 @@ #define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF (1 << 0) #define MIPI_CAL_BIAS_PAD_CFG1 0x17 +#define MIPI_CAL_BIAS_PAD_DRV_DN_REF(x) (((x) & 0x7) << 16) #define MIPI_CAL_BIAS_PAD_CFG2 0x18 #define MIPI_CAL_BIAS_PAD_PDVREG (1 << 1) @@ -203,6 +204,9 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) value |= MIPI_CAL_BIAS_PAD_E_VCLAMP_REF; tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG0); + tegra_mipi_writel(device->mipi, MIPI_CAL_BIAS_PAD_DRV_DN_REF(2), + MIPI_CAL_BIAS_PAD_CFG1); + value = tegra_mipi_readl(device->mipi, MIPI_CAL_BIAS_PAD_CFG2); value &= ~MIPI_CAL_BIAS_PAD_PDVREG; tegra_mipi_writel(device->mipi, value, MIPI_CAL_BIAS_PAD_CFG2); -- GitLab From 9c0127004ff4e891e475d6dfb22ddcbaeca6ec9b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 7 Jul 2014 15:32:53 +0200 Subject: [PATCH 4627/9457] drm/tegra: dc: Add powergate support Both display controllers are in their own power partition. Currently the driver relies on the assumption that these partitions are on (which is the hardware default). However some bootloaders may disable them, so the driver must make sure to turn them back on to avoid hangs. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 45 ++++++++++++++++++++++++++++++++++--- drivers/gpu/drm/tegra/drm.h | 1 + 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 6553fd238685..4a015232e2e8 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -11,6 +11,8 @@ #include #include +#include + #include "dc.h" #include "drm.h" #include "gem.h" @@ -20,6 +22,7 @@ struct tegra_dc_soc_info { bool supports_cursor; bool supports_block_linear; unsigned int pitch_align; + bool has_powergate; }; struct tegra_plane { @@ -1357,6 +1360,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = { .supports_cursor = false, .supports_block_linear = false, .pitch_align = 8, + .has_powergate = false, }; static const struct tegra_dc_soc_info tegra30_dc_soc_info = { @@ -1364,6 +1368,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = { .supports_cursor = false, .supports_block_linear = false, .pitch_align = 8, + .has_powergate = false, }; static const struct tegra_dc_soc_info tegra114_dc_soc_info = { @@ -1371,6 +1376,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = { .supports_cursor = false, .supports_block_linear = false, .pitch_align = 64, + .has_powergate = true, }; static const struct tegra_dc_soc_info tegra124_dc_soc_info = { @@ -1378,12 +1384,16 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = { .supports_cursor = true, .supports_block_linear = true, .pitch_align = 64, + .has_powergate = true, }; static const struct of_device_id tegra_dc_of_match[] = { { .compatible = "nvidia,tegra124-dc", .data = &tegra124_dc_soc_info, + }, { + .compatible = "nvidia,tegra114-dc", + .data = &tegra114_dc_soc_info, }, { .compatible = "nvidia,tegra30-dc", .data = &tegra30_dc_soc_info, @@ -1467,9 +1477,34 @@ static int tegra_dc_probe(struct platform_device *pdev) return PTR_ERR(dc->rst); } - err = clk_prepare_enable(dc->clk); - if (err < 0) - return err; + if (dc->soc->has_powergate) { + if (dc->pipe == 0) + dc->powergate = TEGRA_POWERGATE_DIS; + else + dc->powergate = TEGRA_POWERGATE_DISB; + + err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, + dc->rst); + if (err < 0) { + dev_err(&pdev->dev, "failed to power partition: %d\n", + err); + return err; + } + } else { + err = clk_prepare_enable(dc->clk); + if (err < 0) { + dev_err(&pdev->dev, "failed to enable clock: %d\n", + err); + return err; + } + + err = reset_control_deassert(dc->rst); + if (err < 0) { + dev_err(&pdev->dev, "failed to deassert reset: %d\n", + err); + return err; + } + } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); dc->regs = devm_ioremap_resource(&pdev->dev, regs); @@ -1523,6 +1558,10 @@ static int tegra_dc_remove(struct platform_device *pdev) } reset_control_assert(dc->rst); + + if (dc->soc->has_powergate) + tegra_powergate_power_off(dc->powergate); + clk_disable_unprepare(dc->clk); return 0; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index e89c70fa82d5..b994c017971d 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -101,6 +101,7 @@ struct tegra_dc { spinlock_t lock; struct drm_crtc base; + int powergate; int pipe; struct clk *clk; -- GitLab From dc670e49e75d63174b838fd9e3405f481e50ab19 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Oct 2014 16:26:24 +0200 Subject: [PATCH 4628/9457] drm/tegra: Do not enable output on .mode_set() The output is already enabled in .dpms(), doing it in .mode_set() too can cause noticeable flicker. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 0c67d7eebc94..6b393cfbb5e7 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -167,12 +167,6 @@ static void tegra_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted) { - struct tegra_output *output = encoder_to_output(encoder); - int err; - - err = tegra_output_enable(output); - if (err < 0) - dev_err(encoder->dev->dev, "tegra_output_enable(): %d\n", err); } static const struct drm_encoder_helper_funcs encoder_helper_funcs = { -- GitLab From 0bfad396715a24e28d12d35f4a6ce87f65194609 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 29 Oct 2014 15:33:35 -0400 Subject: [PATCH 4629/9457] drm/tegra: DPMS off/on in encoder prepare/commit Previously the panel and output were only enabled on encoder->dpms(). If userspace called dpms on before doing a modeset, the driver would get into a state where the connector had a dpms state of ON, but the encoder and output were not enabled (because the encoder is not yet attached to the connector). Subsequent dpms ON calls are ignored b/c the connector's state already matches the desired state. This patch enables/disables the panel and output on modeset as well, so we can catch the above case. Signed-off-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 6b393cfbb5e7..e6cfbde36f97 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -157,10 +157,12 @@ static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder, static void tegra_encoder_prepare(struct drm_encoder *encoder) { + tegra_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); } static void tegra_encoder_commit(struct drm_encoder *encoder) { + tegra_encoder_dpms(encoder, DRM_MODE_DPMS_ON); } static void tegra_encoder_mode_set(struct drm_encoder *encoder, -- GitLab From 976cebc35bed0456a42bf96073a26f251d23b264 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 6 Aug 2014 09:14:28 +0200 Subject: [PATCH 4630/9457] drm/tegra: dsi: Make FIFO depths host parameters Rather than hardcoding them as macros, make the host and video FIFO depths parameters so that they can be more easily adjusted if a new generation of the Tegra SoC changes them. While at it, set the depth of the video FIFO to the correct value of 1920 *words* rather than *bytes*. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index f7874458926a..584b771d8b2f 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -26,9 +26,6 @@ #include "dsi.h" #include "mipi-phy.h" -#define DSI_VIDEO_FIFO_DEPTH (1920 / 4) -#define DSI_HOST_FIFO_DEPTH 64 - struct tegra_dsi { struct host1x_client client; struct tegra_output output; @@ -54,6 +51,9 @@ struct tegra_dsi { struct regulator *vdd; bool enabled; + + unsigned int video_fifo_depth; + unsigned int host_fifo_depth; }; static inline struct tegra_dsi * @@ -467,7 +467,7 @@ static int tegra_output_dsi_enable(struct tegra_output *output) DSI_CONTROL_SOURCE(dc->pipe); tegra_dsi_writel(dsi, value, DSI_CONTROL); - tegra_dsi_writel(dsi, DSI_VIDEO_FIFO_DEPTH, DSI_MAX_THRESHOLD); + tegra_dsi_writel(dsi, dsi->video_fifo_depth, DSI_MAX_THRESHOLD); value = DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC; @@ -843,6 +843,8 @@ static int tegra_dsi_probe(struct platform_device *pdev) return -ENOMEM; dsi->output.dev = dsi->dev = &pdev->dev; + dsi->video_fifo_depth = 1920; + dsi->host_fifo_depth = 64; err = tegra_output_probe(&dsi->output); if (err < 0) -- GitLab From 183ef2883d060d69d17d63f7c56fbf1a5d65e3f9 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:27:29 +0100 Subject: [PATCH 4631/9457] drm/tegra: dsi: Do not manage clock on enable/disable In preparation for supporting command mode panels, don't disable the clock when the output is disabled. The output will be enabled only after the panel has been programmed in command mode, so the clock must always remain on. As a side-effect, pad calibration now only needs to be done at driver probe time, since neither power nor controller state will go away before driver removal. While at it, use a 32-bit variable to store register content because the registers are 32-bit even on 64-bit Tegra. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 584b771d8b2f..c62f68071ade 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -456,12 +456,6 @@ static int tegra_output_dsi_enable(struct tegra_output *output) if (err < 0) return err; - err = clk_enable(dsi->clk); - if (err < 0) - return err; - - reset_control_deassert(dsi->rst); - value = DSI_CONTROL_CHANNEL(0) | DSI_CONTROL_FORMAT(format) | DSI_CONTROL_LANES(dsi->lanes - 1) | DSI_CONTROL_SOURCE(dc->pipe); @@ -576,8 +570,6 @@ static int tegra_output_dsi_disable(struct tegra_output *output) tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); } - clk_disable(dsi->clk); - dsi->enabled = false; return 0; @@ -695,7 +687,7 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi) { - unsigned long value; + u32 value; tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0); tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1); @@ -736,12 +728,6 @@ static int tegra_dsi_init(struct host1x_client *client) dev_err(dsi->dev, "debugfs setup failed: %d\n", err); } - err = tegra_dsi_pad_calibrate(dsi); - if (err < 0) { - dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); - return err; - } - return 0; } @@ -863,6 +849,13 @@ static int tegra_dsi_probe(struct platform_device *pdev) if (IS_ERR(dsi->rst)) return PTR_ERR(dsi->rst); + err = reset_control_deassert(dsi->rst); + if (err < 0) { + dev_err(&pdev->dev, "failed to bring DSI out of reset: %d\n", + err); + return err; + } + dsi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dsi->clk)) { dev_err(&pdev->dev, "cannot get DSI clock\n"); @@ -926,6 +919,12 @@ static int tegra_dsi_probe(struct platform_device *pdev) if (IS_ERR(dsi->mipi)) return PTR_ERR(dsi->mipi); + err = tegra_dsi_pad_calibrate(dsi); + if (err < 0) { + dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); + return err; + } + dsi->host.ops = &tegra_dsi_host_ops; dsi->host.dev = &pdev->dev; -- GitLab From 41a8e72e0e32eca7acbcf11d4c75cf5d21d0c825 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:34:50 +0100 Subject: [PATCH 4632/9457] drm/tegra: dsi: Leave parent clock alone The common clock framework will take care of preparing and enabling the parent of the DSI clock automatically. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index c62f68071ade..e817ee11f0ec 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -886,12 +886,6 @@ static int tegra_dsi_probe(struct platform_device *pdev) return PTR_ERR(dsi->clk_parent); } - err = clk_prepare_enable(dsi->clk_parent); - if (err < 0) { - dev_err(&pdev->dev, "cannot enable parent clock\n"); - return err; - } - dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); if (IS_ERR(dsi->vdd)) { dev_err(&pdev->dev, "cannot get VDD supply\n"); @@ -966,7 +960,6 @@ static int tegra_dsi_remove(struct platform_device *pdev) tegra_mipi_free(dsi->mipi); regulator_disable(dsi->vdd); - clk_disable_unprepare(dsi->clk_parent); clk_disable_unprepare(dsi->clk_lp); clk_disable_unprepare(dsi->clk); reset_control_assert(dsi->rst); -- GitLab From ba3df9792207601762060a313d18efdd6ae83501 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:54:01 +0100 Subject: [PATCH 4633/9457] drm/tegra: dsi: Mark connector hotpluggable DSI panels can always be hotplugged via the DSI bus' attach/detach infrastructure, so unconditionally mark the connector hotpluggable. While at it, also make sure that when a panel is detached the connector is marked unconnected before calling into the DRM hotplug helpers to reflect the correct state. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index e817ee11f0ec..704267c39586 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -804,10 +804,10 @@ static int tegra_dsi_host_detach(struct mipi_dsi_host *host, struct tegra_output *output = &dsi->output; if (output->panel && &device->dev == output->panel->dev) { + output->panel = NULL; + if (output->connector.dev) drm_helper_hpd_irq_event(output->connector.dev); - - output->panel = NULL; } return 0; @@ -836,6 +836,8 @@ static int tegra_dsi_probe(struct platform_device *pdev) if (err < 0) return err; + dsi->output.connector.polled = DRM_CONNECTOR_POLL_HPD; + /* * Assume these values by default. When a DSI peripheral driver * attaches to the DSI host, the parameters will be taken from -- GitLab From d2d0a9d21285ace23b7e99c89a52ee9b5ceef792 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:58:27 +0100 Subject: [PATCH 4634/9457] drm/tegra: dsi: Properly cleanup on probe failure The driver wasn't even attempting to do any cleanup when probing failed. Fix this by releasing any resources acquired up to the point of failure and putting the device back into the original state (reset, clocks off). Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 52 ++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 704267c39586..5dae8053e8c9 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -861,64 +861,72 @@ static int tegra_dsi_probe(struct platform_device *pdev) dsi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dsi->clk)) { dev_err(&pdev->dev, "cannot get DSI clock\n"); - return PTR_ERR(dsi->clk); + err = PTR_ERR(dsi->clk); + goto reset; } err = clk_prepare_enable(dsi->clk); if (err < 0) { dev_err(&pdev->dev, "cannot enable DSI clock\n"); - return err; + goto reset; } dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); if (IS_ERR(dsi->clk_lp)) { dev_err(&pdev->dev, "cannot get low-power clock\n"); - return PTR_ERR(dsi->clk_lp); + err = PTR_ERR(dsi->clk_lp); + goto disable_clk; } err = clk_prepare_enable(dsi->clk_lp); if (err < 0) { dev_err(&pdev->dev, "cannot enable low-power clock\n"); - return err; + goto disable_clk; } dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); if (IS_ERR(dsi->clk_parent)) { dev_err(&pdev->dev, "cannot get parent clock\n"); - return PTR_ERR(dsi->clk_parent); + err = PTR_ERR(dsi->clk_parent); + goto disable_clk_lp; } dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); if (IS_ERR(dsi->vdd)) { dev_err(&pdev->dev, "cannot get VDD supply\n"); - return PTR_ERR(dsi->vdd); + err = PTR_ERR(dsi->vdd); + goto disable_clk_lp; } err = regulator_enable(dsi->vdd); if (err < 0) { dev_err(&pdev->dev, "cannot enable VDD supply\n"); - return err; + goto disable_clk_lp; } err = tegra_dsi_setup_clocks(dsi); if (err < 0) { dev_err(&pdev->dev, "cannot setup clocks\n"); - return err; + goto disable_vdd; } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->regs = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(dsi->regs)) - return PTR_ERR(dsi->regs); + if (IS_ERR(dsi->regs)) { + err = PTR_ERR(dsi->regs); + goto disable_vdd; + } dsi->mipi = tegra_mipi_request(&pdev->dev); - if (IS_ERR(dsi->mipi)) - return PTR_ERR(dsi->mipi); + if (IS_ERR(dsi->mipi)) { + err = PTR_ERR(dsi->mipi); + goto disable_vdd; + } err = tegra_dsi_pad_calibrate(dsi); if (err < 0) { dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); - return err; + goto mipi_free; } dsi->host.ops = &tegra_dsi_host_ops; @@ -927,7 +935,7 @@ static int tegra_dsi_probe(struct platform_device *pdev) err = mipi_dsi_host_register(&dsi->host); if (err < 0) { dev_err(&pdev->dev, "failed to register DSI host: %d\n", err); - return err; + goto mipi_free; } INIT_LIST_HEAD(&dsi->client.list); @@ -938,12 +946,26 @@ static int tegra_dsi_probe(struct platform_device *pdev) if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); - return err; + goto unregister; } platform_set_drvdata(pdev, dsi); return 0; + +unregister: + mipi_dsi_host_unregister(&dsi->host); +mipi_free: + tegra_mipi_free(dsi->mipi); +disable_vdd: + regulator_disable(dsi->vdd); +disable_clk_lp: + clk_disable_unprepare(dsi->clk_lp); +disable_clk: + clk_disable_unprepare(dsi->clk); +reset: + reset_control_assert(dsi->rst); + return err; } static int tegra_dsi_remove(struct platform_device *pdev) -- GitLab From 563eff1f989917779d8db4c5208e12adcbfcf655 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:44:27 +0100 Subject: [PATCH 4635/9457] drm/tegra: dsi: Refactor in preparation for command mode For command mode panels, the DSI controller needs to be enabled and configured so that panel drivers can send commands prior to the video stream being enabled. Move code from the monolithic output enable/disable functions into smaller, reusable units to allow more fine-grained control over the controller state. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 100 +++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 5dae8053e8c9..b91d9e4016bc 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -426,20 +426,24 @@ static int tegra_dsi_get_format(enum mipi_dsi_pixel_format format, return 0; } -static int tegra_output_dsi_enable(struct tegra_output *output) +static void tegra_dsi_enable(struct tegra_dsi *dsi) +{ + u32 value; + + value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); + value |= DSI_POWER_CONTROL_ENABLE; + tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); +} + +static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, + const struct drm_display_mode *mode) { - struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); - struct drm_display_mode *mode = &dc->base.mode; unsigned int hact, hsw, hbp, hfp, i, mul, div; - struct tegra_dsi *dsi = to_dsi(output); enum tegra_dsi_format format; - unsigned long value; const u32 *pkt_seq; + u32 value; int err; - if (dsi->enabled) - return 0; - if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n"); pkt_seq = pkt_seq_video_non_burst_sync_pulses; @@ -458,18 +462,19 @@ static int tegra_output_dsi_enable(struct tegra_output *output) value = DSI_CONTROL_CHANNEL(0) | DSI_CONTROL_FORMAT(format) | DSI_CONTROL_LANES(dsi->lanes - 1) | - DSI_CONTROL_SOURCE(dc->pipe); + DSI_CONTROL_SOURCE(pipe); tegra_dsi_writel(dsi, value, DSI_CONTROL); tegra_dsi_writel(dsi, dsi->video_fifo_depth, DSI_MAX_THRESHOLD); - value = DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | - DSI_HOST_CONTROL_ECC; + value = DSI_HOST_CONTROL_HS; tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL); value = tegra_dsi_readl(dsi, DSI_CONTROL); + if (dsi->flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) value |= DSI_CONTROL_HS_CLK_CTRL; + value &= ~DSI_CONTROL_TX_TRIG(3); value &= ~DSI_CONTROL_DCS_ENABLE; value |= DSI_CONTROL_VIDEO_ENABLE; @@ -503,9 +508,27 @@ static int tegra_output_dsi_enable(struct tegra_output *output) tegra_dsi_writel(dsi, hfp, DSI_PKT_LEN_4_5); tegra_dsi_writel(dsi, 0x0f0f << 16, DSI_PKT_LEN_6_7); - /* set SOL delay */ + /* set SOL delay (for non-burst mode only) */ tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY); + return 0; +} + +static int tegra_output_dsi_enable(struct tegra_output *output) +{ + struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); + const struct drm_display_mode *mode = &dc->base.mode; + struct tegra_dsi *dsi = to_dsi(output); + u32 value; + int err; + + if (dsi->enabled) + return 0; + + err = tegra_dsi_configure(dsi, dc->pipe, mode); + if (err < 0) + return err; + /* enable display controller */ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); value |= DSI_ENABLE; @@ -525,28 +548,61 @@ static int tegra_output_dsi_enable(struct tegra_output *output) tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); /* enable DSI controller */ - value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); - value |= DSI_POWER_CONTROL_ENABLE; - tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + tegra_dsi_enable(dsi); dsi->enabled = true; return 0; } +static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout) +{ + u32 value; + + timeout = jiffies + msecs_to_jiffies(timeout); + + while (time_before(jiffies, timeout)) { + value = tegra_dsi_readl(dsi, DSI_STATUS); + if (value & DSI_STATUS_IDLE) + return 0; + + usleep_range(1000, 2000); + } + + return -ETIMEDOUT; +} + +static void tegra_dsi_video_disable(struct tegra_dsi *dsi) +{ + u32 value; + + value = tegra_dsi_readl(dsi, DSI_CONTROL); + value &= ~DSI_CONTROL_VIDEO_ENABLE; + tegra_dsi_writel(dsi, value, DSI_CONTROL); +} + +static void tegra_dsi_disable(struct tegra_dsi *dsi) +{ + u32 value; + + value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); + value &= ~DSI_POWER_CONTROL_ENABLE; + tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + + usleep_range(5000, 10000); +} + static int tegra_output_dsi_disable(struct tegra_output *output) { struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); struct tegra_dsi *dsi = to_dsi(output); unsigned long value; + int err; if (!dsi->enabled) return 0; - /* disable DSI controller */ - value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); - value &= ~DSI_POWER_CONTROL_ENABLE; - tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + tegra_dsi_video_disable(dsi); /* * The following accesses registers of the display controller, so make @@ -570,6 +626,12 @@ static int tegra_output_dsi_disable(struct tegra_output *output) tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); } + err = tegra_dsi_wait_idle(dsi, 100); + if (err < 0) + dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err); + + tegra_dsi_disable(dsi); + dsi->enabled = false; return 0; -- GitLab From 337b443d58e2d7d04d23ed07ff61b1243d5f9f2d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 15:02:46 +0100 Subject: [PATCH 4636/9457] drm/tegra: dsi: Add command mode support Add support for DC-driven command mode. This is a mode where the video stream sent by the display controller is packed into DCS command packets (write_memory_start and write_memory_continue) by the DSI controller. It can be used for panels with a remote framebuffer and is useful to save power when used with a dynamic refresh rate (not yet supported by the driver). Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 82 ++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index b91d9e4016bc..50684a4aa4f0 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -318,6 +318,21 @@ static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = { [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4), }; +static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = { + [ 0] = 0, + [ 1] = 0, + [ 2] = 0, + [ 3] = 0, + [ 4] = 0, + [ 5] = 0, + [ 6] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(3) | PKT_LP, + [ 7] = 0, + [ 8] = 0, + [ 9] = 0, + [10] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(5) | PKT_LP, + [11] = 0, +}; + static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi) { struct mipi_dphy_timing timing; @@ -447,9 +462,12 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n"); pkt_seq = pkt_seq_video_non_burst_sync_pulses; - } else { + } else if (dsi->flags & MIPI_DSI_MODE_VIDEO) { DRM_DEBUG_KMS("Non-burst video mode with sync events\n"); pkt_seq = pkt_seq_video_non_burst_sync_events; + } else { + DRM_DEBUG_KMS("Command mode\n"); + pkt_seq = pkt_seq_command_mode; } err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); @@ -476,7 +494,13 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, value |= DSI_CONTROL_HS_CLK_CTRL; value &= ~DSI_CONTROL_TX_TRIG(3); - value &= ~DSI_CONTROL_DCS_ENABLE; + + /* enable DCS commands for command mode */ + if (dsi->flags & MIPI_DSI_MODE_VIDEO) + value &= ~DSI_CONTROL_DCS_ENABLE; + else + value |= DSI_CONTROL_DCS_ENABLE; + value |= DSI_CONTROL_VIDEO_ENABLE; value &= ~DSI_CONTROL_HOST_ENABLE; tegra_dsi_writel(dsi, value, DSI_CONTROL); @@ -488,28 +512,48 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, for (i = 0; i < NUM_PKT_SEQ; i++) tegra_dsi_writel(dsi, pkt_seq[i], DSI_PKT_SEQ_0_LO + i); - /* horizontal active pixels */ - hact = mode->hdisplay * mul / div; + if (dsi->flags & MIPI_DSI_MODE_VIDEO) { + /* horizontal active pixels */ + hact = mode->hdisplay * mul / div; + + /* horizontal sync width */ + hsw = (mode->hsync_end - mode->hsync_start) * mul / div; + hsw -= 10; + + /* horizontal back porch */ + hbp = (mode->htotal - mode->hsync_end) * mul / div; + hbp -= 14; + + /* horizontal front porch */ + hfp = (mode->hsync_start - mode->hdisplay) * mul / div; + hfp -= 8; - /* horizontal sync width */ - hsw = (mode->hsync_end - mode->hsync_start) * mul / div; - hsw -= 10; + tegra_dsi_writel(dsi, hsw << 16 | 0, DSI_PKT_LEN_0_1); + tegra_dsi_writel(dsi, hact << 16 | hbp, DSI_PKT_LEN_2_3); + tegra_dsi_writel(dsi, hfp, DSI_PKT_LEN_4_5); + tegra_dsi_writel(dsi, 0x0f0f << 16, DSI_PKT_LEN_6_7); - /* horizontal back porch */ - hbp = (mode->htotal - mode->hsync_end) * mul / div; - hbp -= 14; + /* set SOL delay (for non-burst mode only) */ + tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY); + } else { + u16 bytes; + + /* 1 byte (DCS command) + pixel data */ + bytes = 1 + mode->hdisplay * mul / div; - /* horizontal front porch */ - hfp = (mode->hsync_start - mode->hdisplay) * mul / div; - hfp -= 8; + tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_0_1); + tegra_dsi_writel(dsi, bytes << 16, DSI_PKT_LEN_2_3); + tegra_dsi_writel(dsi, bytes << 16, DSI_PKT_LEN_4_5); + tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_6_7); - tegra_dsi_writel(dsi, hsw << 16 | 0, DSI_PKT_LEN_0_1); - tegra_dsi_writel(dsi, hact << 16 | hbp, DSI_PKT_LEN_2_3); - tegra_dsi_writel(dsi, hfp, DSI_PKT_LEN_4_5); - tegra_dsi_writel(dsi, 0x0f0f << 16, DSI_PKT_LEN_6_7); + value = MIPI_DCS_WRITE_MEMORY_START << 8 | + MIPI_DCS_WRITE_MEMORY_CONTINUE; + tegra_dsi_writel(dsi, value, DSI_DCS_CMDS); - /* set SOL delay (for non-burst mode only) */ - tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY); + value = 8 * mul / div; + + tegra_dsi_writel(dsi, value, DSI_SOL_DELAY); + } return 0; } -- GitLab From 3f6b406f7d716310c7a63648bbe6b2a4a30c3077 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:50:33 +0100 Subject: [PATCH 4637/9457] drm/tegra: dsi: Split out tegra_dsi_set_timeout() In preparation for adding ganged-mode support, this commit splits out the tegra_dsi_set_timeout() function so that it can be reused for the slave DSI controller. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 38 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 50684a4aa4f0..46fcf62658cf 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -681,15 +681,35 @@ static int tegra_output_dsi_disable(struct tegra_output *output) return 0; } +static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, + unsigned int vrefresh) +{ + unsigned int timeout; + u32 value; + + /* one frame high-speed transmission timeout */ + timeout = (bclk / vrefresh) / 512; + value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout); + tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0); + + /* 2 ms peripheral timeout for panel */ + timeout = 2 * bclk / 512 * 1000; + value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000); + tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1); + + value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0); + tegra_dsi_writel(dsi, value, DSI_TO_TALLY); +} + static int tegra_output_dsi_setup_clock(struct tegra_output *output, struct clk *clk, unsigned long pclk, unsigned int *divp) { struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); struct drm_display_mode *mode = &dc->base.mode; - unsigned int timeout, mul, div, vrefresh; struct tegra_dsi *dsi = to_dsi(output); - unsigned long bclk, plld, value; + unsigned int mul, div, vrefresh; + unsigned long bclk, plld; int err; err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); @@ -744,19 +764,7 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, * XXX: Move the below somewhere else so that we don't need to have * access to the vrefresh in this function? */ - - /* one frame high-speed transmission timeout */ - timeout = (bclk / vrefresh) / 512; - value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout); - tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0); - - /* 2 ms peripheral timeout for panel */ - timeout = 2 * bclk / 512 * 1000; - value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000); - tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1); - - value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0); - tegra_dsi_writel(dsi, value, DSI_TO_TALLY); + tegra_dsi_set_timeout(dsi, bclk, vrefresh); return 0; } -- GitLab From e94236cde4d519cdecd45e2435defba33abdc99f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 7 Oct 2014 16:10:24 +0200 Subject: [PATCH 4638/9457] drm/tegra: dsi: Add ganged mode support Implement ganged mode support for the Tegra DSI driver. The DSI host controller to gang up with is specified via a phandle in the device tree and the resolved DSI host controller used for the programming of the ganged-mode registers. Signed-off-by: Thierry Reding --- .../bindings/gpu/nvidia,tegra20-host1x.txt | 2 + drivers/gpu/drm/tegra/dsi.c | 221 +++++++++++++++--- drivers/gpu/drm/tegra/dsi.h | 1 + 3 files changed, 195 insertions(+), 29 deletions(-) diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index b48f4ef31d93..4c32ef0b7db8 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -191,6 +191,8 @@ of the following host1x client modules: - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection - nvidia,edid: supplies a binary EDID blob - nvidia,panel: phandle of a display panel + - nvidia,ganged-mode: contains a phandle to a second DSI controller to gang + up with in order to support up to 8 data lanes - sor: serial output resource diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 46fcf62658cf..66816104ba72 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,10 @@ struct tegra_dsi { unsigned int video_fifo_depth; unsigned int host_fifo_depth; + + /* for ganged-mode support */ + struct tegra_dsi *master; + struct tegra_dsi *slave; }; static inline struct tegra_dsi * @@ -441,6 +446,18 @@ static int tegra_dsi_get_format(enum mipi_dsi_pixel_format format, return 0; } +static void tegra_dsi_ganged_enable(struct tegra_dsi *dsi, unsigned int start, + unsigned int size) +{ + u32 value; + + tegra_dsi_writel(dsi, start, DSI_GANGED_MODE_START); + tegra_dsi_writel(dsi, size << 16 | size, DSI_GANGED_MODE_SIZE); + + value = DSI_GANGED_MODE_CONTROL_ENABLE; + tegra_dsi_writel(dsi, value, DSI_GANGED_MODE_CONTROL); +} + static void tegra_dsi_enable(struct tegra_dsi *dsi) { u32 value; @@ -448,6 +465,20 @@ static void tegra_dsi_enable(struct tegra_dsi *dsi) value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); value |= DSI_POWER_CONTROL_ENABLE; tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + + if (dsi->slave) + tegra_dsi_enable(dsi->slave); +} + +static unsigned int tegra_dsi_get_lanes(struct tegra_dsi *dsi) +{ + if (dsi->master) + return dsi->master->lanes + dsi->lanes; + + if (dsi->slave) + return dsi->lanes + dsi->slave->lanes; + + return dsi->lanes; } static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, @@ -535,11 +566,20 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, /* set SOL delay (for non-burst mode only) */ tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY); + + /* TODO: implement ganged mode */ } else { u16 bytes; - /* 1 byte (DCS command) + pixel data */ - bytes = 1 + mode->hdisplay * mul / div; + if (dsi->master || dsi->slave) { + /* + * For ganged mode, assume symmetric left-right mode. + */ + bytes = 1 + (mode->hdisplay / 2) * mul / div; + } else { + /* 1 byte (DCS command) + pixel data */ + bytes = 1 + mode->hdisplay * mul / div; + } tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_0_1); tegra_dsi_writel(dsi, bytes << 16, DSI_PKT_LEN_2_3); @@ -550,11 +590,42 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, MIPI_DCS_WRITE_MEMORY_CONTINUE; tegra_dsi_writel(dsi, value, DSI_DCS_CMDS); - value = 8 * mul / div; + /* set SOL delay */ + if (dsi->master || dsi->slave) { + unsigned int lanes = tegra_dsi_get_lanes(dsi); + unsigned long delay, bclk, bclk_ganged; + + /* SOL to valid, valid to FIFO and FIFO write delay */ + delay = 4 + 4 + 2; + delay = DIV_ROUND_UP(delay * mul, div * lanes); + /* FIFO read delay */ + delay = delay + 6; + + bclk = DIV_ROUND_UP(mode->htotal * mul, div * lanes); + bclk_ganged = DIV_ROUND_UP(bclk * lanes / 2, lanes); + value = bclk - bclk_ganged + delay + 20; + } else { + /* TODO: revisit for non-ganged mode */ + value = 8 * mul / div; + } tegra_dsi_writel(dsi, value, DSI_SOL_DELAY); } + if (dsi->slave) { + err = tegra_dsi_configure(dsi->slave, pipe, mode); + if (err < 0) + return err; + + /* + * TODO: Support modes other than symmetrical left-right + * split. + */ + tegra_dsi_ganged_enable(dsi, 0, mode->hdisplay / 2); + tegra_dsi_ganged_enable(dsi->slave, mode->hdisplay / 2, + mode->hdisplay / 2); + } + return 0; } @@ -623,16 +694,34 @@ static void tegra_dsi_video_disable(struct tegra_dsi *dsi) value = tegra_dsi_readl(dsi, DSI_CONTROL); value &= ~DSI_CONTROL_VIDEO_ENABLE; tegra_dsi_writel(dsi, value, DSI_CONTROL); + + if (dsi->slave) + tegra_dsi_video_disable(dsi->slave); +} + +static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi) +{ + tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_START); + tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_SIZE); + tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL); } static void tegra_dsi_disable(struct tegra_dsi *dsi) { u32 value; + if (dsi->slave) { + tegra_dsi_ganged_disable(dsi->slave); + tegra_dsi_ganged_disable(dsi); + } + value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); value &= ~DSI_POWER_CONTROL_ENABLE; tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + if (dsi->slave) + tegra_dsi_disable(dsi->slave); + usleep_range(5000, 10000); } @@ -699,6 +788,9 @@ static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0); tegra_dsi_writel(dsi, value, DSI_TO_TALLY); + + if (dsi->slave) + tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh); } static int tegra_output_dsi_setup_clock(struct tegra_output *output, @@ -708,20 +800,22 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); struct drm_display_mode *mode = &dc->base.mode; struct tegra_dsi *dsi = to_dsi(output); - unsigned int mul, div, vrefresh; + unsigned int mul, div, vrefresh, lanes; unsigned long bclk, plld; int err; + lanes = tegra_dsi_get_lanes(dsi); + err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); if (err < 0) return err; - DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", mul, div, dsi->lanes); + DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", mul, div, lanes); vrefresh = drm_mode_vrefresh(mode); DRM_DEBUG_KMS("vrefresh: %u\n", vrefresh); /* compute byte clock */ - bclk = (pclk * mul) / (div * dsi->lanes); + bclk = (pclk * mul) / (div * lanes); /* * Compute bit clock and round up to the next MHz. @@ -758,7 +852,7 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, * not working properly otherwise. Perhaps the PLLs cannot generate * frequencies sufficiently high. */ - *divp = ((8 * mul) / (div * dsi->lanes)) - 2; + *divp = ((8 * mul) / (div * lanes)) - 2; /* * XXX: Move the below somewhere else so that we don't need to have @@ -826,14 +920,17 @@ static int tegra_dsi_init(struct host1x_client *client) struct tegra_dsi *dsi = host1x_client_to_dsi(client); int err; - dsi->output.type = TEGRA_OUTPUT_DSI; - dsi->output.dev = client->dev; - dsi->output.ops = &dsi_ops; - - err = tegra_output_init(drm, &dsi->output); - if (err < 0) { - dev_err(client->dev, "output setup failed: %d\n", err); - return err; + /* Gangsters must not register their own outputs. */ + if (!dsi->master) { + dsi->output.type = TEGRA_OUTPUT_DSI; + dsi->output.dev = client->dev; + dsi->output.ops = &dsi_ops; + + err = tegra_output_init(drm, &dsi->output); + if (err < 0) { + dev_err(client->dev, "output setup failed: %d\n", err); + return err; + } } if (IS_ENABLED(CONFIG_DEBUG_FS)) { @@ -856,16 +953,20 @@ static int tegra_dsi_exit(struct host1x_client *client) dev_err(dsi->dev, "debugfs cleanup failed: %d\n", err); } - err = tegra_output_disable(&dsi->output); - if (err < 0) { - dev_err(client->dev, "output failed to disable: %d\n", err); - return err; - } - - err = tegra_output_exit(&dsi->output); - if (err < 0) { - dev_err(client->dev, "output cleanup failed: %d\n", err); - return err; + if (!dsi->master) { + err = tegra_output_disable(&dsi->output); + if (err < 0) { + dev_err(client->dev, "output failed to disable: %d\n", + err); + return err; + } + + err = tegra_output_exit(&dsi->output); + if (err < 0) { + dev_err(client->dev, "output cleanup failed: %d\n", + err); + return err; + } } return 0; @@ -892,20 +993,58 @@ static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi) return 0; } +static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi) +{ + struct clk *parent; + int err; + + /* make sure both DSI controllers share the same PLL */ + parent = clk_get_parent(dsi->slave->clk); + if (!parent) + return -EINVAL; + + err = clk_set_parent(parent, dsi->clk_parent); + if (err < 0) + return err; + + return 0; +} + static int tegra_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct tegra_dsi *dsi = host_to_tegra(host); - struct tegra_output *output = &dsi->output; dsi->flags = device->mode_flags; dsi->format = device->format; dsi->lanes = device->lanes; - output->panel = of_drm_find_panel(device->dev.of_node); - if (output->panel) { - if (output->connector.dev) + if (dsi->slave) { + int err; + + dev_dbg(dsi->dev, "attaching dual-channel device %s\n", + dev_name(&device->dev)); + + err = tegra_dsi_ganged_setup(dsi); + if (err < 0) { + dev_err(dsi->dev, "failed to set up ganged mode: %d\n", + err); + return err; + } + } + + /* + * Slaves don't have a panel associated with them, so they provide + * merely the second channel. + */ + if (!dsi->master) { + struct tegra_output *output = &dsi->output; + + output->panel = of_drm_find_panel(device->dev.of_node); + if (output->panel && output->connector.dev) { + drm_panel_attach(output->panel, &output->connector); drm_helper_hpd_irq_event(output->connector.dev); + } } return 0; @@ -932,6 +1071,26 @@ static const struct mipi_dsi_host_ops tegra_dsi_host_ops = { .detach = tegra_dsi_host_detach, }; +static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) +{ + struct device_node *np; + + np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0); + if (np) { + struct platform_device *gangster = of_find_device_by_node(np); + + dsi->slave = platform_get_drvdata(gangster); + of_node_put(np); + + if (!dsi->slave) + return -EPROBE_DEFER; + + dsi->slave->master = dsi; + } + + return 0; +} + static int tegra_dsi_probe(struct platform_device *pdev) { struct tegra_dsi *dsi; @@ -946,6 +1105,10 @@ static int tegra_dsi_probe(struct platform_device *pdev) dsi->video_fifo_depth = 1920; dsi->host_fifo_depth = 64; + err = tegra_dsi_ganged_probe(dsi); + if (err < 0) + return err; + err = tegra_output_probe(&dsi->output); if (err < 0) return err; diff --git a/drivers/gpu/drm/tegra/dsi.h b/drivers/gpu/drm/tegra/dsi.h index 5ce610d08d77..1f6ca68108d8 100644 --- a/drivers/gpu/drm/tegra/dsi.h +++ b/drivers/gpu/drm/tegra/dsi.h @@ -104,6 +104,7 @@ #define DSI_PAD_CONTROL_3 0x51 #define DSI_PAD_CONTROL_4 0x52 #define DSI_GANGED_MODE_CONTROL 0x53 +#define DSI_GANGED_MODE_CONTROL_ENABLE (1 << 0) #define DSI_GANGED_MODE_START 0x54 #define DSI_GANGED_MODE_SIZE 0x55 #define DSI_RAW_DATA_BYTE_COUNT 0x56 -- GitLab From 0fffdf6ca9926243db9ca17701fcdc0a38c67d48 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 7 Nov 2014 17:25:26 +0100 Subject: [PATCH 4639/9457] drm/tegra: dsi: Implement host transfers Add support for sending MIPI DSI command packets from the host to a peripheral. This is required for panels that need configuration before they accept video data. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 267 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/dsi.h | 13 +- 2 files changed, 279 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 66816104ba72..6646fa2adc38 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -993,6 +993,272 @@ static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi) return 0; } +static const char * const error_report[16] = { + "SoT Error", + "SoT Sync Error", + "EoT Sync Error", + "Escape Mode Entry Command Error", + "Low-Power Transmit Sync Error", + "Peripheral Timeout Error", + "False Control Error", + "Contention Detected", + "ECC Error, single-bit", + "ECC Error, multi-bit", + "Checksum Error", + "DSI Data Type Not Recognized", + "DSI VC ID Invalid", + "Invalid Transmission Length", + "Reserved", + "DSI Protocol Violation", +}; + +static ssize_t tegra_dsi_read_response(struct tegra_dsi *dsi, + const struct mipi_dsi_msg *msg, + size_t count) +{ + u8 *rx = msg->rx_buf; + unsigned int i, j, k; + size_t size = 0; + u16 errors; + u32 value; + + /* read and parse packet header */ + value = tegra_dsi_readl(dsi, DSI_RD_DATA); + + switch (value & 0x3f) { + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: + errors = (value >> 8) & 0xffff; + dev_dbg(dsi->dev, "Acknowledge and error report: %04x\n", + errors); + for (i = 0; i < ARRAY_SIZE(error_report); i++) + if (errors & BIT(i)) + dev_dbg(dsi->dev, " %2u: %s\n", i, + error_report[i]); + break; + + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: + rx[0] = (value >> 8) & 0xff; + size = 1; + break; + + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE: + rx[0] = (value >> 8) & 0xff; + rx[1] = (value >> 16) & 0xff; + size = 2; + break; + + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE: + size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff); + break; + + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE: + size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff); + break; + + default: + dev_err(dsi->dev, "unhandled response type: %02x\n", + value & 0x3f); + return -EPROTO; + } + + size = min(size, msg->rx_len); + + if (msg->rx_buf && size > 0) { + for (i = 0, j = 0; i < count - 1; i++, j += 4) { + u8 *rx = msg->rx_buf + j; + + value = tegra_dsi_readl(dsi, DSI_RD_DATA); + + for (k = 0; k < 4 && (j + k) < msg->rx_len; k++) + rx[j + k] = (value >> (k << 3)) & 0xff; + } + } + + return size; +} + +static int tegra_dsi_transmit(struct tegra_dsi *dsi, unsigned long timeout) +{ + tegra_dsi_writel(dsi, DSI_TRIGGER_HOST, DSI_TRIGGER); + + timeout = jiffies + msecs_to_jiffies(timeout); + + while (time_before(jiffies, timeout)) { + u32 value = tegra_dsi_readl(dsi, DSI_TRIGGER); + if ((value & DSI_TRIGGER_HOST) == 0) + return 0; + + usleep_range(1000, 2000); + } + + DRM_DEBUG_KMS("timeout waiting for transmission to complete\n"); + return -ETIMEDOUT; +} + +static int tegra_dsi_wait_for_response(struct tegra_dsi *dsi, + unsigned long timeout) +{ + timeout = jiffies + msecs_to_jiffies(250); + + while (time_before(jiffies, timeout)) { + u32 value = tegra_dsi_readl(dsi, DSI_STATUS); + u8 count = value & 0x1f; + + if (count > 0) + return count; + + usleep_range(1000, 2000); + } + + DRM_DEBUG_KMS("peripheral returned no data\n"); + return -ETIMEDOUT; +} + +static void tegra_dsi_writesl(struct tegra_dsi *dsi, unsigned long offset, + const void *buffer, size_t size) +{ + const u8 *buf = buffer; + size_t i, j; + u32 value; + + for (j = 0; j < size; j += 4) { + value = 0; + + for (i = 0; i < 4 && j + i < size; i++) + value |= buf[j + i] << (i << 3); + + tegra_dsi_writel(dsi, value, DSI_WR_DATA); + } +} + +static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct tegra_dsi *dsi = host_to_tegra(host); + struct mipi_dsi_packet packet; + const u8 *header; + size_t count; + ssize_t err; + u32 value; + + err = mipi_dsi_create_packet(&packet, msg); + if (err < 0) + return err; + + header = packet.header; + + /* maximum FIFO depth is 1920 words */ + if (packet.size > dsi->video_fifo_depth * 4) + return -ENOSPC; + + /* reset underflow/overflow flags */ + value = tegra_dsi_readl(dsi, DSI_STATUS); + if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) { + value = DSI_HOST_CONTROL_FIFO_RESET; + tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL); + usleep_range(10, 20); + } + + value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); + value |= DSI_POWER_CONTROL_ENABLE; + tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); + + usleep_range(5000, 10000); + + value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | + DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC; + + if ((msg->flags & MIPI_DSI_MSG_USE_LPM) == 0) + value |= DSI_HOST_CONTROL_HS; + + /* + * The host FIFO has a maximum of 64 words, so larger transmissions + * need to use the video FIFO. + */ + if (packet.size > dsi->host_fifo_depth * 4) + value |= DSI_HOST_CONTROL_FIFO_SEL; + + tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL); + + /* + * For reads and messages with explicitly requested ACK, generate a + * BTA sequence after the transmission of the packet. + */ + if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) || + (msg->rx_buf && msg->rx_len > 0)) { + value = tegra_dsi_readl(dsi, DSI_HOST_CONTROL); + value |= DSI_HOST_CONTROL_PKT_BTA; + tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL); + } + + value = DSI_CONTROL_LANES(0) | DSI_CONTROL_HOST_ENABLE; + tegra_dsi_writel(dsi, value, DSI_CONTROL); + + /* write packet header, ECC is generated by hardware */ + value = header[2] << 16 | header[1] << 8 | header[0]; + tegra_dsi_writel(dsi, value, DSI_WR_DATA); + + /* write payload (if any) */ + if (packet.payload_length > 0) + tegra_dsi_writesl(dsi, DSI_WR_DATA, packet.payload, + packet.payload_length); + + err = tegra_dsi_transmit(dsi, 250); + if (err < 0) + return err; + + if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) || + (msg->rx_buf && msg->rx_len > 0)) { + err = tegra_dsi_wait_for_response(dsi, 250); + if (err < 0) + return err; + + count = err; + + value = tegra_dsi_readl(dsi, DSI_RD_DATA); + switch (value) { + case 0x84: + /* + dev_dbg(dsi->dev, "ACK\n"); + */ + break; + + case 0x87: + /* + dev_dbg(dsi->dev, "ESCAPE\n"); + */ + break; + + default: + dev_err(dsi->dev, "unknown status: %08x\n", value); + break; + } + + if (count > 1) { + err = tegra_dsi_read_response(dsi, msg, count); + if (err < 0) + dev_err(dsi->dev, + "failed to parse response: %zd\n", + err); + else { + /* + * For read commands, return the number of + * bytes returned by the peripheral. + */ + count = err; + } + } + } else { + /* + * For write commands, we have transmitted the 4-byte header + * plus the variable-length payload. + */ + count = 4 + packet.payload_length; + } + + return count; +} + static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi) { struct clk *parent; @@ -1069,6 +1335,7 @@ static int tegra_dsi_host_detach(struct mipi_dsi_host *host, static const struct mipi_dsi_host_ops tegra_dsi_host_ops = { .attach = tegra_dsi_host_attach, .detach = tegra_dsi_host_detach, + .transfer = tegra_dsi_host_transfer, }; static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) diff --git a/drivers/gpu/drm/tegra/dsi.h b/drivers/gpu/drm/tegra/dsi.h index 1f6ca68108d8..bad1006a5150 100644 --- a/drivers/gpu/drm/tegra/dsi.h +++ b/drivers/gpu/drm/tegra/dsi.h @@ -21,9 +21,16 @@ #define DSI_INT_STATUS 0x0d #define DSI_INT_MASK 0x0e #define DSI_HOST_CONTROL 0x0f +#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21) +#define DSI_HOST_CONTROL_CRC_RESET (1 << 20) +#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12) +#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12) +#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12) #define DSI_HOST_CONTROL_RAW (1 << 6) #define DSI_HOST_CONTROL_HS (1 << 5) -#define DSI_HOST_CONTROL_BTA (1 << 2) +#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4) +#define DSI_HOST_CONTROL_IMM_BTA (1 << 3) +#define DSI_HOST_CONTROL_PKT_BTA (1 << 2) #define DSI_HOST_CONTROL_CS (1 << 1) #define DSI_HOST_CONTROL_ECC (1 << 0) #define DSI_CONTROL 0x10 @@ -39,9 +46,13 @@ #define DSI_SOL_DELAY 0x11 #define DSI_MAX_THRESHOLD 0x12 #define DSI_TRIGGER 0x13 +#define DSI_TRIGGER_HOST (1 << 1) +#define DSI_TRIGGER_VIDEO (1 << 0) #define DSI_TX_CRC 0x14 #define DSI_STATUS 0x15 #define DSI_STATUS_IDLE (1 << 10) +#define DSI_STATUS_UNDERFLOW (1 << 9) +#define DSI_STATUS_OVERFLOW (1 << 8) #define DSI_INIT_SEQ_CONTROL 0x1a #define DSI_INIT_SEQ_DATA_0 0x1b #define DSI_INIT_SEQ_DATA_1 0x1c -- GitLab From 369bc65b6b996595310a4c6a73367332fc32b4df Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 7 Nov 2014 17:17:41 +0100 Subject: [PATCH 4640/9457] drm/tegra: dsi: Replace 1000000000UL by NSEC_PER_SEC Using the symbolic constant instantly provides a lot more context. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 6646fa2adc38..2f12258ecd74 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -349,7 +349,7 @@ static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi) if (rate < 0) return rate; - period = DIV_ROUND_CLOSEST(1000000000UL, rate * 2); + period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate * 2); err = mipi_dphy_timing_get_default(&timing, period); if (err < 0) -- GitLab From 030611ecc5d8b1daf8de110600c8771de45d398d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 13 Nov 2014 14:32:06 +0100 Subject: [PATCH 4641/9457] drm/tegra: dsi: Replace 1000000 by USEC_PER_SEC Using the symbolic constant instantly provides a lot more context. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 2f12258ecd74..8940360ccc9c 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -820,7 +820,7 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, /* * Compute bit clock and round up to the next MHz. */ - plld = DIV_ROUND_UP(bclk * 8, 1000000) * 1000000; + plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC; /* * We divide the frequency by two here, but we make up for that by -- GitLab From 7e3bc3a98fd1df5839cdc5cbce4dfdb9e4c03655 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 7 Oct 2014 16:04:42 +0200 Subject: [PATCH 4642/9457] drm/tegra: dsi: Set up PHY_TIMING & BTA_TIMING registers earlier Make sure the DSI PHY_TIMING and BTA_TIMING registers are initialized when the clocks are set up as opposed to when the output is enabled. This makes sure that the PHY timings are properly set up when the panel is prepared and that DCS commands sent at that time use the appropriate timings. Signed-off-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 8940360ccc9c..33f67fd601c6 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -389,6 +389,9 @@ static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi) DSI_TIMING_FIELD(timing.tago, period, 1); tegra_dsi_writel(dsi, value, DSI_BTA_TIMING); + if (dsi->slave) + return tegra_dsi_set_phy_timing(dsi->slave); + return 0; } @@ -536,10 +539,6 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, value &= ~DSI_CONTROL_HOST_ENABLE; tegra_dsi_writel(dsi, value, DSI_CONTROL); - err = tegra_dsi_set_phy_timing(dsi); - if (err < 0) - return err; - for (i = 0; i < NUM_PKT_SEQ; i++) tegra_dsi_writel(dsi, pkt_seq[i], DSI_PKT_SEQ_0_LO + i); @@ -860,6 +859,10 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, */ tegra_dsi_set_timeout(dsi, bclk, vrefresh); + err = tegra_dsi_set_phy_timing(dsi); + if (err < 0) + return err; + return 0; } -- GitLab From c28d4a317fef0401be180b34f48d193ff2a6787b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 14:18:50 +0200 Subject: [PATCH 4643/9457] drm/tegra: gem: Extract tegra_bo_alloc_object() This function implements the common buffer object allocation used for both allocation and import paths. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 77 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index ce023fa3e8ae..d86ded791935 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -91,6 +91,36 @@ static const struct host1x_bo_ops tegra_bo_ops = { .kunmap = tegra_bo_kunmap, }; +static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, + size_t size) +{ + struct tegra_bo *bo; + int err; + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (!bo) + return ERR_PTR(-ENOMEM); + + host1x_bo_init(&bo->base, &tegra_bo_ops); + size = round_up(size, PAGE_SIZE); + + err = drm_gem_object_init(drm, &bo->gem, size); + if (err < 0) + goto free; + + err = drm_gem_create_mmap_offset(&bo->gem); + if (err < 0) + goto release; + + return bo; + +release: + drm_gem_object_release(&bo->gem); +free: + kfree(bo); + return ERR_PTR(err); +} + static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo) { dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr); @@ -102,12 +132,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, struct tegra_bo *bo; int err; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - if (!bo) - return ERR_PTR(-ENOMEM); - - host1x_bo_init(&bo->base, &tegra_bo_ops); - size = round_up(size, PAGE_SIZE); + bo = tegra_bo_alloc_object(drm, size); + if (IS_ERR(bo)) + return bo; bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, GFP_KERNEL | __GFP_NOWARN); @@ -118,14 +145,6 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, goto err_dma; } - err = drm_gem_object_init(drm, &bo->gem, size); - if (err) - goto err_init; - - err = drm_gem_create_mmap_offset(&bo->gem); - if (err) - goto err_mmap; - if (flags & DRM_TEGRA_GEM_CREATE_TILED) bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED; @@ -134,10 +153,6 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, return bo; -err_mmap: - drm_gem_object_release(&bo->gem); -err_init: - tegra_bo_destroy(drm, bo); err_dma: kfree(bo); @@ -175,28 +190,16 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, { struct dma_buf_attachment *attach; struct tegra_bo *bo; - ssize_t size; int err; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - if (!bo) - return ERR_PTR(-ENOMEM); - - host1x_bo_init(&bo->base, &tegra_bo_ops); - size = round_up(buf->size, PAGE_SIZE); - - err = drm_gem_object_init(drm, &bo->gem, size); - if (err < 0) - goto free; - - err = drm_gem_create_mmap_offset(&bo->gem); - if (err < 0) - goto release; + bo = tegra_bo_alloc_object(drm, buf->size); + if (IS_ERR(bo)) + return bo; attach = dma_buf_attach(buf, drm->dev); if (IS_ERR(attach)) { err = PTR_ERR(attach); - goto free_mmap; + goto free; } get_dma_buf(buf); @@ -228,13 +231,9 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, dma_buf_detach(buf, attach); dma_buf_put(buf); -free_mmap: - drm_gem_free_mmap_offset(&bo->gem); -release: - drm_gem_object_release(&bo->gem); free: + drm_gem_object_release(&bo->gem); kfree(bo); - return ERR_PTR(err); } -- GitLab From a8b48df5925fad5ba9ebc49c80ef60774cc97628 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 14:22:50 +0200 Subject: [PATCH 4644/9457] drm/tegra: gem: Cleanup tegra_bo_create_with_handle() There is only a single location where the function needs to do cleanup. Skip the error unwinding path and call the cleanup function directly instead. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index d86ded791935..b1d778a7f3e7 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -166,23 +166,21 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, unsigned int *handle) { struct tegra_bo *bo; - int ret; + int err; bo = tegra_bo_create(drm, size, flags); if (IS_ERR(bo)) return bo; - ret = drm_gem_handle_create(file, &bo->gem, handle); - if (ret) - goto err; + err = drm_gem_handle_create(file, &bo->gem, handle); + if (err) { + tegra_bo_free_object(&bo->gem); + return ERR_PTR(err); + } drm_gem_object_unreference_unlocked(&bo->gem); return bo; - -err: - tegra_bo_free_object(&bo->gem); - return ERR_PTR(ret); } static struct tegra_bo *tegra_bo_import(struct drm_device *drm, -- GitLab From e55a8bd8ead046e5b7f78c321afc7594034257f9 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 16 Oct 2014 14:23:36 +0200 Subject: [PATCH 4645/9457] drm/tegra: gem: Remove redundant drm_gem_free_mmap_offset() The drm_gem_object_release() function already performs this cleanup, so there is no reason to do it explicitly. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index b1d778a7f3e7..a42d4c9a4d7d 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -247,9 +247,7 @@ void tegra_bo_free_object(struct drm_gem_object *gem) tegra_bo_destroy(gem->dev, bo); } - drm_gem_free_mmap_offset(gem); drm_gem_object_release(gem); - kfree(bo); } -- GitLab From 53ea72132df8dd62bb77b28df7b05074dcea96fe Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 24 Sep 2014 16:14:04 +0200 Subject: [PATCH 4646/9457] drm/tegra: gem: Use dma_mmap_writecombine() Use the existing API rather than open-coding equivalent functionality in the driver. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index a42d4c9a4d7d..9905598ebfc4 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -306,6 +306,7 @@ const struct vm_operations_struct tegra_bo_vm_ops = { int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) { + unsigned long vm_pgoff = vma->vm_pgoff; struct drm_gem_object *gem; struct tegra_bo *bo; int ret; @@ -317,12 +318,19 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) gem = vma->vm_private_data; bo = to_tegra_bo(gem); - ret = remap_pfn_range(vma, vma->vm_start, bo->paddr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); - if (ret) + vma->vm_flags &= ~VM_PFNMAP; + vma->vm_pgoff = 0; + + ret = dma_mmap_writecombine(gem->dev->dev, vma, bo->vaddr, bo->paddr, + gem->size); + if (ret) { drm_gem_vm_close(vma); + return ret; + } + + vma->vm_pgoff = vm_pgoff; - return ret; + return 0; } static struct sg_table * -- GitLab From 1d1e6fe9b5cd9e51c0b064b60f673a973cac38ba Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 14:12:08 +0100 Subject: [PATCH 4647/9457] drm/tegra: Fix error handling cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DRM driver's ->load() implementation didn't do a good job (no job at all really) cleaning up on failure. Fix that by undoing any prior setup when an error occurs. This requires a bit of rework to make it possible to clean up fbdev midway. This was tested by injecting errors at various points during the initialization sequence and verifying that error cleanup didn't crash and no memory leaked (using kmemleak). Reported-by: Stéphane Marchesin Reported-by: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 20 ++++++++++++++++---- drivers/gpu/drm/tegra/drm.h | 1 + drivers/gpu/drm/tegra/fb.c | 20 +++++++++++++++++--- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 59736bb810cd..e1632fb03a89 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -42,13 +42,13 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) err = tegra_drm_fb_prepare(drm); if (err < 0) - return err; + goto config; drm_kms_helper_poll_init(drm); err = host1x_device_init(device); if (err < 0) - return err; + goto fbdev; /* * We don't use the drm_irq_install() helpers provided by the DRM @@ -59,13 +59,25 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) err = drm_vblank_init(drm, drm->mode_config.num_crtc); if (err < 0) - return err; + goto device; err = tegra_drm_fb_init(drm); if (err < 0) - return err; + goto vblank; return 0; + +vblank: + drm_vblank_cleanup(drm); +device: + host1x_device_exit(device); +fbdev: + drm_kms_helper_poll_fini(drm); + tegra_drm_fb_free(drm); +config: + drm_mode_config_cleanup(drm); + kfree(tegra); + return err; } static int tegra_drm_unload(struct drm_device *drm) diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index b994c017971d..ef2faaef5936 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -288,6 +288,7 @@ bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer); int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer, struct tegra_bo_tiling *tiling); int tegra_drm_fb_prepare(struct drm_device *drm); +void tegra_drm_fb_free(struct drm_device *drm); int tegra_drm_fb_init(struct drm_device *drm); void tegra_drm_fb_exit(struct drm_device *drm); #ifdef CONFIG_DRM_TEGRA_FBDEV diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 3513d12d5aa1..0474241ac2a4 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -289,6 +289,11 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm) return fbdev; } +static void tegra_fbdev_free(struct tegra_fbdev *fbdev) +{ + kfree(fbdev); +} + static int tegra_fbdev_init(struct tegra_fbdev *fbdev, unsigned int preferred_bpp, unsigned int num_crtc, @@ -322,7 +327,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev, return err; } -static void tegra_fbdev_free(struct tegra_fbdev *fbdev) +static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { struct fb_info *info = fbdev->base.fbdev; @@ -345,7 +350,7 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev) } drm_fb_helper_fini(&fbdev->base); - kfree(fbdev); + tegra_fbdev_free(fbdev); } void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev) @@ -393,6 +398,15 @@ int tegra_drm_fb_prepare(struct drm_device *drm) return 0; } +void tegra_drm_fb_free(struct drm_device *drm) +{ +#ifdef CONFIG_DRM_TEGRA_FBDEV + struct tegra_drm *tegra = drm->dev_private; + + tegra_fbdev_free(tegra->fbdev); +#endif +} + int tegra_drm_fb_init(struct drm_device *drm) { #ifdef CONFIG_DRM_TEGRA_FBDEV @@ -413,6 +427,6 @@ void tegra_drm_fb_exit(struct drm_device *drm) #ifdef CONFIG_DRM_TEGRA_FBDEV struct tegra_drm *tegra = drm->dev_private; - tegra_fbdev_free(tegra->fbdev); + tegra_fbdev_exit(tegra->fbdev); #endif } -- GitLab From df06b759f2cf4690fa9991edb1504ba39932b2bb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 26 Jun 2014 21:41:53 +0200 Subject: [PATCH 4648/9457] drm/tegra: Add IOMMU support When an IOMMU device is available on the platform bus, allocate an IOMMU domain and attach the display controllers to it. The display controllers can then scan out non-contiguous buffers by mapping them through the IOMMU. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 17 +++ drivers/gpu/drm/tegra/drm.c | 24 ++++ drivers/gpu/drm/tegra/drm.h | 5 + drivers/gpu/drm/tegra/fb.c | 16 ++- drivers/gpu/drm/tegra/gem.c | 275 +++++++++++++++++++++++++++++++----- drivers/gpu/drm/tegra/gem.h | 6 + 6 files changed, 309 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 4a015232e2e8..5f138b7c81bf 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -1290,6 +1291,17 @@ static int tegra_dc_init(struct host1x_client *client) struct tegra_drm *tegra = drm->dev_private; int err; + if (tegra->domain) { + err = iommu_attach_device(tegra->domain, dc->dev); + if (err < 0) { + dev_err(dc->dev, "failed to attach to domain: %d\n", + err); + return err; + } + + dc->domain = tegra->domain; + } + drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); @@ -1347,6 +1359,11 @@ static int tegra_dc_exit(struct host1x_client *client) return err; } + if (dc->domain) { + iommu_detach_device(dc->domain, dc->dev); + dc->domain = NULL; + } + return 0; } diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index e1632fb03a89..6c9df794b3be 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -8,6 +8,7 @@ */ #include +#include #include "drm.h" #include "gem.h" @@ -33,6 +34,17 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) if (!tegra) return -ENOMEM; + if (iommu_present(&platform_bus_type)) { + tegra->domain = iommu_domain_alloc(&platform_bus_type); + if (IS_ERR(tegra->domain)) { + err = PTR_ERR(tegra->domain); + goto free; + } + + DRM_DEBUG("IOMMU context initialized\n"); + drm_mm_init(&tegra->mm, 0, SZ_2G); + } + mutex_init(&tegra->clients_lock); INIT_LIST_HEAD(&tegra->clients); drm->dev_private = tegra; @@ -76,6 +88,12 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) tegra_drm_fb_free(drm); config: drm_mode_config_cleanup(drm); + + if (tegra->domain) { + iommu_domain_free(tegra->domain); + drm_mm_takedown(&tegra->mm); + } +free: kfree(tegra); return err; } @@ -83,6 +101,7 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) static int tegra_drm_unload(struct drm_device *drm) { struct host1x_device *device = to_host1x_device(drm->dev); + struct tegra_drm *tegra = drm->dev_private; int err; drm_kms_helper_poll_fini(drm); @@ -94,6 +113,11 @@ static int tegra_drm_unload(struct drm_device *drm) if (err < 0) return err; + if (tegra->domain) { + iommu_domain_free(tegra->domain); + drm_mm_takedown(&tegra->mm); + } + return 0; } diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index ef2faaef5936..96ff47d586a2 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -39,6 +39,9 @@ struct tegra_fbdev { struct tegra_drm { struct drm_device *drm; + struct iommu_domain *domain; + struct drm_mm mm; + struct mutex clients_lock; struct list_head clients; @@ -121,6 +124,8 @@ struct tegra_dc { struct drm_pending_vblank_event *event; const struct tegra_dc_soc_info *soc; + + struct iommu_domain *domain; }; static inline struct tegra_dc * diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 0474241ac2a4..fab39eb2dae8 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -65,8 +65,12 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) for (i = 0; i < fb->num_planes; i++) { struct tegra_bo *bo = fb->planes[i]; - if (bo) + if (bo) { + if (bo->pages && bo->vaddr) + vunmap(bo->vaddr); + drm_gem_object_unreference_unlocked(&bo->gem); + } } drm_framebuffer_cleanup(framebuffer); @@ -254,6 +258,16 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, offset = info->var.xoffset * bytes_per_pixel + info->var.yoffset * fb->pitches[0]; + if (bo->pages) { + bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!bo->vaddr) { + dev_err(drm->dev, "failed to vmap() framebuffer\n"); + err = -ENOMEM; + goto destroy; + } + } + drm->mode_config.fb_base = (resource_size_t)bo->paddr; info->screen_base = (void __iomem *)bo->vaddr + offset; info->screen_size = size; diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 9905598ebfc4..8b1095d05c58 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -14,6 +14,7 @@ */ #include +#include #include #include "drm.h" @@ -91,6 +92,88 @@ static const struct host1x_bo_ops tegra_bo_ops = { .kunmap = tegra_bo_kunmap, }; +/* + * A generic iommu_map_sg() function is being reviewed and will hopefully be + * merged soon. At that point this function can be dropped in favour of the + * one provided by the IOMMU API. + */ +static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, + int prot) +{ + struct scatterlist *s; + size_t offset = 0; + unsigned int i; + int err; + + for_each_sg(sg, s, nents, i) { + phys_addr_t phys = page_to_phys(sg_page(s)); + size_t length = s->offset + s->length; + + err = iommu_map(domain, iova + offset, phys, length, prot); + if (err < 0) { + iommu_unmap(domain, iova, offset); + return err; + } + + offset += length; + } + + return offset; +} + +static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) +{ + int prot = IOMMU_READ | IOMMU_WRITE; + ssize_t err; + + if (bo->mm) + return -EBUSY; + + bo->mm = kzalloc(sizeof(*bo->mm), GFP_KERNEL); + if (!bo->mm) + return -ENOMEM; + + err = drm_mm_insert_node_generic(&tegra->mm, bo->mm, bo->gem.size, + PAGE_SIZE, 0, 0, 0); + if (err < 0) { + dev_err(tegra->drm->dev, "out of I/O virtual memory: %zd\n", + err); + goto free; + } + + bo->paddr = bo->mm->start; + + err = __iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl, + bo->sgt->nents, prot); + if (err < 0) { + dev_err(tegra->drm->dev, "failed to map buffer: %zd\n", err); + goto remove; + } + + bo->size = err; + + return 0; + +remove: + drm_mm_remove_node(bo->mm); +free: + kfree(bo->mm); + return err; +} + +static int tegra_bo_iommu_unmap(struct tegra_drm *tegra, struct tegra_bo *bo) +{ + if (!bo->mm) + return 0; + + iommu_unmap(tegra->domain, bo->paddr, bo->size); + drm_mm_remove_node(bo->mm); + kfree(bo->mm); + + return 0; +} + static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, size_t size) { @@ -121,9 +204,64 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, return ERR_PTR(err); } -static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo) +static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) +{ + if (bo->pages) { + drm_gem_put_pages(&bo->gem, bo->pages, true, true); + sg_free_table(bo->sgt); + kfree(bo->sgt); + } else { + dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, + bo->paddr); + } +} + +static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo, + size_t size) +{ + bo->pages = drm_gem_get_pages(&bo->gem); + if (IS_ERR(bo->pages)) + return PTR_ERR(bo->pages); + + bo->num_pages = size >> PAGE_SHIFT; + + bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); + if (IS_ERR(bo->sgt)) { + drm_gem_put_pages(&bo->gem, bo->pages, false, false); + return PTR_ERR(bo->sgt); + } + + return 0; +} + +static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, + size_t size) { - dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr); + struct tegra_drm *tegra = drm->dev_private; + int err; + + if (tegra->domain) { + err = tegra_bo_get_pages(drm, bo, size); + if (err < 0) + return err; + + err = tegra_bo_iommu_map(tegra, bo); + if (err < 0) { + tegra_bo_free(drm, bo); + return err; + } + } else { + bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, + GFP_KERNEL | __GFP_NOWARN); + if (!bo->vaddr) { + dev_err(drm->dev, + "failed to allocate buffer of size %zu\n", + size); + return -ENOMEM; + } + } + + return 0; } struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, @@ -136,14 +274,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, if (IS_ERR(bo)) return bo; - bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, - GFP_KERNEL | __GFP_NOWARN); - if (!bo->vaddr) { - dev_err(drm->dev, "failed to allocate buffer with size %u\n", - size); - err = -ENOMEM; - goto err_dma; - } + err = tegra_bo_alloc(drm, bo, size); + if (err < 0) + goto release; if (flags & DRM_TEGRA_GEM_CREATE_TILED) bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED; @@ -153,9 +286,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, return bo; -err_dma: +release: + drm_gem_object_release(&bo->gem); kfree(bo); - return ERR_PTR(err); } @@ -186,6 +319,7 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, static struct tegra_bo *tegra_bo_import(struct drm_device *drm, struct dma_buf *buf) { + struct tegra_drm *tegra = drm->dev_private; struct dma_buf_attachment *attach; struct tegra_bo *bo; int err; @@ -213,12 +347,19 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, goto detach; } - if (bo->sgt->nents > 1) { - err = -EINVAL; - goto detach; + if (tegra->domain) { + err = tegra_bo_iommu_map(tegra, bo); + if (err < 0) + goto detach; + } else { + if (bo->sgt->nents > 1) { + err = -EINVAL; + goto detach; + } + + bo->paddr = sg_dma_address(bo->sgt->sgl); } - bo->paddr = sg_dma_address(bo->sgt->sgl); bo->gem.import_attach = attach; return bo; @@ -237,14 +378,18 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, void tegra_bo_free_object(struct drm_gem_object *gem) { + struct tegra_drm *tegra = gem->dev->dev_private; struct tegra_bo *bo = to_tegra_bo(gem); + if (tegra->domain) + tegra_bo_iommu_unmap(tegra, bo); + if (gem->import_attach) { dma_buf_unmap_attachment(gem->import_attach, bo->sgt, DMA_TO_DEVICE); drm_prime_gem_destroy(gem, NULL); } else { - tegra_bo_destroy(gem->dev, bo); + tegra_bo_free(gem->dev, bo); } drm_gem_object_release(gem); @@ -299,14 +444,44 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, return 0; } +static int tegra_bo_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct drm_gem_object *gem = vma->vm_private_data; + struct tegra_bo *bo = to_tegra_bo(gem); + struct page *page; + pgoff_t offset; + int err; + + if (!bo->pages) + return VM_FAULT_SIGBUS; + + offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> PAGE_SHIFT; + page = bo->pages[offset]; + + err = vm_insert_page(vma, (unsigned long)vmf->virtual_address, page); + switch (err) { + case -EAGAIN: + case 0: + case -ERESTARTSYS: + case -EINTR: + case -EBUSY: + return VM_FAULT_NOPAGE; + + case -ENOMEM: + return VM_FAULT_OOM; + } + + return VM_FAULT_SIGBUS; +} + const struct vm_operations_struct tegra_bo_vm_ops = { + .fault = tegra_bo_fault, .open = drm_gem_vm_open, .close = drm_gem_vm_close, }; int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) { - unsigned long vm_pgoff = vma->vm_pgoff; struct drm_gem_object *gem; struct tegra_bo *bo; int ret; @@ -318,17 +493,28 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) gem = vma->vm_private_data; bo = to_tegra_bo(gem); - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_pgoff = 0; + if (!bo->pages) { + unsigned long vm_pgoff = vma->vm_pgoff; - ret = dma_mmap_writecombine(gem->dev->dev, vma, bo->vaddr, bo->paddr, - gem->size); - if (ret) { - drm_gem_vm_close(vma); - return ret; - } + vma->vm_flags &= ~VM_PFNMAP; + vma->vm_pgoff = 0; - vma->vm_pgoff = vm_pgoff; + ret = dma_mmap_writecombine(gem->dev->dev, vma, bo->vaddr, + bo->paddr, gem->size); + if (ret) { + drm_gem_vm_close(vma); + return ret; + } + + vma->vm_pgoff = vm_pgoff; + } else { + pgprot_t prot = vm_get_page_prot(vma->vm_flags); + + vma->vm_flags |= VM_MIXEDMAP; + vma->vm_flags &= ~VM_PFNMAP; + + vma->vm_page_prot = pgprot_writecombine(prot); + } return 0; } @@ -345,21 +531,44 @@ tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, if (!sgt) return NULL; - if (sg_alloc_table(sgt, 1, GFP_KERNEL)) { - kfree(sgt); - return NULL; - } + if (bo->pages) { + struct scatterlist *sg; + unsigned int i; + + if (sg_alloc_table(sgt, bo->num_pages, GFP_KERNEL)) + goto free; - sg_dma_address(sgt->sgl) = bo->paddr; - sg_dma_len(sgt->sgl) = gem->size; + for_each_sg(sgt->sgl, sg, bo->num_pages, i) + sg_set_page(sg, bo->pages[i], PAGE_SIZE, 0); + + if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) + goto free; + } else { + if (sg_alloc_table(sgt, 1, GFP_KERNEL)) + goto free; + + sg_dma_address(sgt->sgl) = bo->paddr; + sg_dma_len(sgt->sgl) = gem->size; + } return sgt; + +free: + sg_free_table(sgt); + kfree(sgt); + return NULL; } static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt, enum dma_data_direction dir) { + struct drm_gem_object *gem = attach->dmabuf->priv; + struct tegra_bo *bo = to_tegra_bo(gem); + + if (bo->pages) + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); + sg_free_table(sgt); kfree(sgt); } diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h index 6538b56780c2..3dd4165f812a 100644 --- a/drivers/gpu/drm/tegra/gem.h +++ b/drivers/gpu/drm/tegra/gem.h @@ -38,6 +38,12 @@ struct tegra_bo { dma_addr_t paddr; void *vaddr; + struct drm_mm_node *mm; + unsigned long num_pages; + struct page **pages; + /* size of IOMMU mapping */ + size_t size; + struct tegra_bo_tiling tiling; }; -- GitLab From 205d48edee844740041c07450fedd7314352ba44 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 21 Oct 2014 13:41:46 +0200 Subject: [PATCH 4649/9457] drm/tegra: dc: Factor out DC, window and cursor commit The sequence to commit changes to the DC, window or cursor configuration is repetitive and can be extracted into separate functions for ease of use. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 52 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 5f138b7c81bf..8fb815dde969 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -36,6 +36,26 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane) return container_of(plane, struct tegra_plane, base); } +static void tegra_dc_window_commit(struct tegra_dc *dc, unsigned int index) +{ + u32 value = WIN_A_ACT_REQ << index; + + tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); +} + +static void tegra_dc_cursor_commit(struct tegra_dc *dc) +{ + tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL); +} + +static void tegra_dc_commit(struct tegra_dc *dc) +{ + tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); + tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); +} + static unsigned int tegra_dc_format(uint32_t format, uint32_t *swap) { /* assume no swapping of fetched data */ @@ -307,8 +327,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, break; } - tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL); + tegra_dc_window_commit(dc, index); return 0; } @@ -379,8 +398,7 @@ static int tegra_plane_disable(struct drm_plane *plane) value &= ~WIN_ENABLE; tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); - tegra_dc_writel(dc, WIN_A_UPDATE << p->index, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, WIN_A_ACT_REQ << p->index, DC_CMD_STATE_CONTROL); + tegra_dc_window_commit(dc, p->index); return 0; } @@ -517,10 +535,8 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); - value = GENERAL_UPDATE | WIN_A_UPDATE; - tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); - value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; + tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); return 0; @@ -625,11 +641,8 @@ static int tegra_dc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file, tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); } - tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL); - - tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); + tegra_dc_cursor_commit(dc); + tegra_dc_commit(dc); return 0; } @@ -645,12 +658,9 @@ static int tegra_dc_cursor_move(struct drm_crtc *crtc, int x, int y) value = ((y & 0x3fff) << 16) | (x & 0x3fff); tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION); - tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL); - + tegra_dc_cursor_commit(dc); /* XXX: only required on generations earlier than Tegra124? */ - tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); - tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); + tegra_dc_commit(dc); return 0; } @@ -939,15 +949,9 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) static void tegra_crtc_commit(struct drm_crtc *crtc) { struct tegra_dc *dc = to_tegra_dc(crtc); - unsigned long value; - - value = GENERAL_UPDATE | WIN_A_UPDATE; - tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); - - value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; - tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); drm_vblank_post_modeset(crtc->dev, dc->pipe); + tegra_dc_commit(dc); } static void tegra_crtc_load_lut(struct drm_crtc *crtc) -- GitLab From 03a605697658ac7af722764cef3f0fed889d2033 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 21 Oct 2014 13:48:48 +0200 Subject: [PATCH 4650/9457] drm/tegra: dc: Registers are 32 bits wide Using an unsigned long type will cause these variables to become 64-bit on 64-bit SoCs. In practice this should always work, but there's no need for carrying around the additional 32 bits. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 2 +- drivers/gpu/drm/tegra/drm.h | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 8fb815dde969..517a257cccaf 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1005,7 +1005,7 @@ static int tegra_dc_show_regs(struct seq_file *s, void *data) struct tegra_dc *dc = node->info_ent->data; #define DUMP_REG(name) \ - seq_printf(s, "%-40s %#05x %08lx\n", #name, name, \ + seq_printf(s, "%-40s %#05x %08x\n", #name, name, \ tegra_dc_readl(dc, name)) DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT); diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 96ff47d586a2..3a3b2e7b5b3f 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -139,16 +139,15 @@ static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) return crtc ? container_of(crtc, struct tegra_dc, base) : NULL; } -static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value, - unsigned long reg) +static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value, + unsigned long offset) { - writel(value, dc->regs + (reg << 2)); + writel(value, dc->regs + (offset << 2)); } -static inline unsigned long tegra_dc_readl(struct tegra_dc *dc, - unsigned long reg) +static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned long offset) { - return readl(dc->regs + (reg << 2)); + return readl(dc->regs + (offset << 2)); } struct tegra_dc_window { -- GitLab From c7679306a923c2feb383f709446c1110db1c56e4 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 21 Oct 2014 13:51:53 +0200 Subject: [PATCH 4651/9457] drm/tegra: dc: Universal plane support This allows the primary plane and cursor to be exposed as regular DRM/KMS planes, which is a prerequisite for atomic modesetting and gives userspace more flexibility over controlling them. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 487 +++++++++++++++++++++++++------------ 1 file changed, 330 insertions(+), 157 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 517a257cccaf..7ef16a2409b1 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -332,11 +332,255 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, return 0; } -static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, - int crtc_y, unsigned int crtc_w, - unsigned int crtc_h, uint32_t src_x, - uint32_t src_y, uint32_t src_w, uint32_t src_h) +static int tegra_window_plane_disable(struct drm_plane *plane) +{ + struct tegra_dc *dc = to_tegra_dc(plane->crtc); + struct tegra_plane *p = to_tegra_plane(plane); + u32 value; + + if (!plane->crtc) + return 0; + + value = WINDOW_A_SELECT << p->index; + tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); + + value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); + value &= ~WIN_ENABLE; + tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); + + tegra_dc_window_commit(dc, p->index); + + return 0; +} + +static void tegra_plane_destroy(struct drm_plane *plane) +{ + struct tegra_plane *p = to_tegra_plane(plane); + + drm_plane_cleanup(plane); + kfree(p); +} + +static const u32 tegra_primary_plane_formats[] = { + DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_RGB565, +}; + +static int tegra_primary_plane_update(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, + int crtc_y, unsigned int crtc_w, + unsigned int crtc_h, uint32_t src_x, + uint32_t src_y, uint32_t src_w, + uint32_t src_h) +{ + struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); + struct tegra_plane *p = to_tegra_plane(plane); + struct tegra_dc *dc = to_tegra_dc(crtc); + struct tegra_dc_window window; + int err; + + memset(&window, 0, sizeof(window)); + window.src.x = src_x >> 16; + window.src.y = src_y >> 16; + window.src.w = src_w >> 16; + window.src.h = src_h >> 16; + window.dst.x = crtc_x; + window.dst.y = crtc_y; + window.dst.w = crtc_w; + window.dst.h = crtc_h; + window.format = tegra_dc_format(fb->pixel_format, &window.swap); + window.bits_per_pixel = fb->bits_per_pixel; + window.bottom_up = tegra_fb_is_bottom_up(fb); + + err = tegra_fb_get_tiling(fb, &window.tiling); + if (err < 0) + return err; + + window.base[0] = bo->paddr + fb->offsets[0]; + window.stride[0] = fb->pitches[0]; + + err = tegra_dc_setup_window(dc, p->index, &window); + if (err < 0) + return err; + + return 0; +} + +static void tegra_primary_plane_destroy(struct drm_plane *plane) +{ + tegra_window_plane_disable(plane); + tegra_plane_destroy(plane); +} + +static const struct drm_plane_funcs tegra_primary_plane_funcs = { + .update_plane = tegra_primary_plane_update, + .disable_plane = tegra_window_plane_disable, + .destroy = tegra_primary_plane_destroy, +}; + +static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, + struct tegra_dc *dc) +{ + struct tegra_plane *plane; + unsigned int num_formats; + const u32 *formats; + int err; + + plane = kzalloc(sizeof(*plane), GFP_KERNEL); + if (!plane) + return ERR_PTR(-ENOMEM); + + num_formats = ARRAY_SIZE(tegra_primary_plane_formats); + formats = tegra_primary_plane_formats; + + err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, + &tegra_primary_plane_funcs, formats, + num_formats, DRM_PLANE_TYPE_PRIMARY); + if (err < 0) { + kfree(plane); + return ERR_PTR(err); + } + + return &plane->base; +} + +static const u32 tegra_cursor_plane_formats[] = { + DRM_FORMAT_RGBA8888, +}; + +static int tegra_cursor_plane_update(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, + int crtc_y, unsigned int crtc_w, + unsigned int crtc_h, uint32_t src_x, + uint32_t src_y, uint32_t src_w, + uint32_t src_h) +{ + struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); + struct tegra_dc *dc = to_tegra_dc(crtc); + u32 value = CURSOR_CLIP_DISPLAY; + + /* scaling not supported for cursor */ + if ((src_w >> 16 != crtc_w) || (src_h >> 16 != crtc_h)) + return -EINVAL; + + /* only square cursors supported */ + if (src_w != src_h) + return -EINVAL; + + switch (crtc_w) { + case 32: + value |= CURSOR_SIZE_32x32; + break; + + case 64: + value |= CURSOR_SIZE_64x64; + break; + + case 128: + value |= CURSOR_SIZE_128x128; + break; + + case 256: + value |= CURSOR_SIZE_256x256; + break; + + default: + return -EINVAL; + } + + value |= (bo->paddr >> 10) & 0x3fffff; + tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR); + +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT + value = (bo->paddr >> 32) & 0x3; + tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI); +#endif + + /* enable cursor and set blend mode */ + value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); + value |= CURSOR_ENABLE; + tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); + + value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); + value &= ~CURSOR_DST_BLEND_MASK; + value &= ~CURSOR_SRC_BLEND_MASK; + value |= CURSOR_MODE_NORMAL; + value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC; + value |= CURSOR_SRC_BLEND_K1_TIMES_SRC; + value |= CURSOR_ALPHA; + tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL); + + /* position the cursor */ + value = (crtc_y & 0x3fff) << 16 | (crtc_x & 0x3fff); + tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION); + + /* apply changes */ + tegra_dc_cursor_commit(dc); + tegra_dc_commit(dc); + + return 0; +} + +static int tegra_cursor_plane_disable(struct drm_plane *plane) +{ + struct tegra_dc *dc = to_tegra_dc(plane->crtc); + u32 value; + + if (!plane->crtc) + return 0; + + value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); + value &= ~CURSOR_ENABLE; + tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); + + tegra_dc_cursor_commit(dc); + tegra_dc_commit(dc); + + return 0; +} + +static const struct drm_plane_funcs tegra_cursor_plane_funcs = { + .update_plane = tegra_cursor_plane_update, + .disable_plane = tegra_cursor_plane_disable, + .destroy = tegra_plane_destroy, +}; + +static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, + struct tegra_dc *dc) +{ + struct tegra_plane *plane; + unsigned int num_formats; + const u32 *formats; + int err; + + plane = kzalloc(sizeof(*plane), GFP_KERNEL); + if (!plane) + return ERR_PTR(-ENOMEM); + + num_formats = ARRAY_SIZE(tegra_cursor_plane_formats); + formats = tegra_cursor_plane_formats; + + err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, + &tegra_cursor_plane_funcs, formats, + num_formats, DRM_PLANE_TYPE_CURSOR); + if (err < 0) { + kfree(plane); + return ERR_PTR(err); + } + + return &plane->base; +} + +static int tegra_overlay_plane_update(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, + int crtc_y, unsigned int crtc_w, + unsigned int crtc_h, uint32_t src_x, + uint32_t src_y, uint32_t src_w, + uint32_t src_h) { struct tegra_plane *p = to_tegra_plane(plane); struct tegra_dc *dc = to_tegra_dc(crtc); @@ -382,43 +626,19 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return tegra_dc_setup_window(dc, p->index, &window); } -static int tegra_plane_disable(struct drm_plane *plane) -{ - struct tegra_dc *dc = to_tegra_dc(plane->crtc); - struct tegra_plane *p = to_tegra_plane(plane); - unsigned long value; - - if (!plane->crtc) - return 0; - - value = WINDOW_A_SELECT << p->index; - tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); - - value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); - value &= ~WIN_ENABLE; - tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); - - tegra_dc_window_commit(dc, p->index); - - return 0; -} - -static void tegra_plane_destroy(struct drm_plane *plane) +static void tegra_overlay_plane_destroy(struct drm_plane *plane) { - struct tegra_plane *p = to_tegra_plane(plane); - - tegra_plane_disable(plane); - drm_plane_cleanup(plane); - kfree(p); + tegra_window_plane_disable(plane); + tegra_plane_destroy(plane); } -static const struct drm_plane_funcs tegra_plane_funcs = { - .update_plane = tegra_plane_update, - .disable_plane = tegra_plane_disable, - .destroy = tegra_plane_destroy, +static const struct drm_plane_funcs tegra_overlay_plane_funcs = { + .update_plane = tegra_overlay_plane_update, + .disable_plane = tegra_window_plane_disable, + .destroy = tegra_overlay_plane_destroy, }; -static const uint32_t plane_formats[] = { +static const uint32_t tegra_overlay_plane_formats[] = { DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, @@ -428,27 +648,44 @@ static const uint32_t plane_formats[] = { DRM_FORMAT_YUV422, }; -static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) +static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, + struct tegra_dc *dc, + unsigned int index) { - unsigned int i; - int err = 0; + struct tegra_plane *plane; + unsigned int num_formats; + const u32 *formats; + int err; - for (i = 0; i < 2; i++) { - struct tegra_plane *plane; + plane = kzalloc(sizeof(*plane), GFP_KERNEL); + if (!plane) + return ERR_PTR(-ENOMEM); - plane = kzalloc(sizeof(*plane), GFP_KERNEL); - if (!plane) - return -ENOMEM; + plane->index = index; - plane->index = 1 + i; + num_formats = ARRAY_SIZE(tegra_overlay_plane_formats); + formats = tegra_overlay_plane_formats; - err = drm_plane_init(drm, &plane->base, 1 << dc->pipe, - &tegra_plane_funcs, plane_formats, - ARRAY_SIZE(plane_formats), false); - if (err < 0) { - kfree(plane); - return err; - } + err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, + &tegra_overlay_plane_funcs, formats, + num_formats, DRM_PLANE_TYPE_OVERLAY); + if (err < 0) { + kfree(plane); + return ERR_PTR(err); + } + + return &plane->base; +} + +static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) +{ + struct drm_plane *plane; + unsigned int i; + + for (i = 0; i < 2; i++) { + plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i); + if (IS_ERR(plane)) + return PTR_ERR(plane); } return 0; @@ -568,103 +805,6 @@ void tegra_dc_disable_vblank(struct tegra_dc *dc) spin_unlock_irqrestore(&dc->lock, flags); } -static int tegra_dc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file, - uint32_t handle, uint32_t width, - uint32_t height, int32_t hot_x, int32_t hot_y) -{ - unsigned long value = CURSOR_CLIP_DISPLAY; - struct tegra_dc *dc = to_tegra_dc(crtc); - struct drm_gem_object *gem; - struct tegra_bo *bo = NULL; - - if (!dc->soc->supports_cursor) - return -ENXIO; - - if (width != height) - return -EINVAL; - - switch (width) { - case 32: - value |= CURSOR_SIZE_32x32; - break; - - case 64: - value |= CURSOR_SIZE_64x64; - break; - - case 128: - value |= CURSOR_SIZE_128x128; - - case 256: - value |= CURSOR_SIZE_256x256; - break; - - default: - return -EINVAL; - } - - if (handle) { - gem = drm_gem_object_lookup(crtc->dev, file, handle); - if (!gem) - return -ENOENT; - - bo = to_tegra_bo(gem); - } - - if (bo) { - unsigned long addr = (bo->paddr & 0xfffffc00) >> 10; -#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - unsigned long high = (bo->paddr & 0xfffffffc) >> 32; -#endif - - tegra_dc_writel(dc, value | addr, DC_DISP_CURSOR_START_ADDR); - -#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - tegra_dc_writel(dc, high, DC_DISP_CURSOR_START_ADDR_HI); -#endif - - value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); - value |= CURSOR_ENABLE; - tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); - - value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); - value &= ~CURSOR_DST_BLEND_MASK; - value &= ~CURSOR_SRC_BLEND_MASK; - value |= CURSOR_MODE_NORMAL; - value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC; - value |= CURSOR_SRC_BLEND_K1_TIMES_SRC; - value |= CURSOR_ALPHA; - tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL); - } else { - value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); - value &= ~CURSOR_ENABLE; - tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); - } - - tegra_dc_cursor_commit(dc); - tegra_dc_commit(dc); - - return 0; -} - -static int tegra_dc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct tegra_dc *dc = to_tegra_dc(crtc); - unsigned long value; - - if (!dc->soc->supports_cursor) - return -ENXIO; - - value = ((y & 0x3fff) << 16) | (x & 0x3fff); - tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION); - - tegra_dc_cursor_commit(dc); - /* XXX: only required on generations earlier than Tegra124? */ - tegra_dc_commit(dc); - - return 0; -} - static void tegra_dc_finish_page_flip(struct tegra_dc *dc) { struct drm_device *drm = dc->base.dev; @@ -741,8 +881,6 @@ static void tegra_dc_destroy(struct drm_crtc *crtc) } static const struct drm_crtc_funcs tegra_crtc_funcs = { - .cursor_set2 = tegra_dc_cursor_set2, - .cursor_move = tegra_dc_cursor_move, .page_flip = tegra_dc_page_flip, .set_config = drm_crtc_helper_set_config, .destroy = tegra_dc_destroy, @@ -756,7 +894,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) { if (plane->crtc == crtc) { - tegra_plane_disable(plane); + tegra_window_plane_disable(plane); plane->crtc = NULL; if (plane->fb) { @@ -767,6 +905,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) } drm_vblank_off(drm, dc->pipe); + tegra_dc_commit(dc); } static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, @@ -1293,6 +1432,8 @@ static int tegra_dc_init(struct host1x_client *client) struct drm_device *drm = dev_get_drvdata(client->parent); struct tegra_dc *dc = host1x_client_to_dc(client); struct tegra_drm *tegra = drm->dev_private; + struct drm_plane *primary = NULL; + struct drm_plane *cursor = NULL; int err; if (tegra->domain) { @@ -1306,7 +1447,25 @@ static int tegra_dc_init(struct host1x_client *client) dc->domain = tegra->domain; } - drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); + primary = tegra_dc_primary_plane_create(drm, dc); + if (IS_ERR(primary)) { + err = PTR_ERR(primary); + goto cleanup; + } + + if (dc->soc->supports_cursor) { + cursor = tegra_dc_cursor_plane_create(drm, dc); + if (IS_ERR(cursor)) { + err = PTR_ERR(cursor); + goto cleanup; + } + } + + err = drm_crtc_init_with_planes(drm, &dc->base, primary, cursor, + &tegra_crtc_funcs); + if (err < 0) + goto cleanup; + drm_mode_crtc_set_gamma_size(&dc->base, 256); drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); @@ -1320,12 +1479,12 @@ static int tegra_dc_init(struct host1x_client *client) err = tegra_dc_rgb_init(drm, dc); if (err < 0 && err != -ENODEV) { dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); - return err; + goto cleanup; } err = tegra_dc_add_planes(drm, dc); if (err < 0) - return err; + goto cleanup; if (IS_ENABLED(CONFIG_DEBUG_FS)) { err = tegra_dc_debugfs_init(dc, drm->primary); @@ -1338,10 +1497,24 @@ static int tegra_dc_init(struct host1x_client *client) if (err < 0) { dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, err); - return err; + goto cleanup; } return 0; + +cleanup: + if (cursor) + drm_plane_cleanup(cursor); + + if (primary) + drm_plane_cleanup(primary); + + if (tegra->domain) { + iommu_detach_device(tegra->domain, dc->dev); + dc->domain = NULL; + } + + return err; } static int tegra_dc_exit(struct host1x_client *client) -- GitLab From 8fc8f7da9719c2d28fb32cdd74af9b6cd9bac20a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 21 Oct 2014 14:00:09 +0200 Subject: [PATCH 4652/9457] drm/tegra: Enable the hotplug interrupt only when necessary The hotplug handling needs access to the DRM device, which only appears at ->init() time. Disable interrupts up until that time. Similarly, when an output is removed, disable the hotplug interrupt again because the DRM device (and with it the hotplug infrastructure) is going away. Also make sure to only access the DRM device if it's available. Given the above change for the hotplug interrupt this should really never happen, but the extra check doesn't hurt either. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index e6cfbde36f97..022462d3a413 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -183,7 +183,8 @@ static irqreturn_t hpd_irq(int irq, void *data) { struct tegra_output *output = data; - drm_helper_hpd_irq_event(output->connector.dev); + if (output->connector.dev) + drm_helper_hpd_irq_event(output->connector.dev); return IRQ_HANDLED; } @@ -255,6 +256,13 @@ int tegra_output_probe(struct tegra_output *output) } output->connector.polled = DRM_CONNECTOR_POLL_HPD; + + /* + * Disable the interrupt until the connector has been + * initialized to avoid a race in the hotplug interrupt + * handler. + */ + disable_irq(output->hpd_irq); } return 0; @@ -320,10 +328,24 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) output->encoder.possible_crtcs = 0x3; + /* + * The connector is now registered and ready to receive hotplug events + * so the hotplug interrupt can be enabled. + */ + if (gpio_is_valid(output->hpd_gpio)) + enable_irq(output->hpd_irq); + return 0; } int tegra_output_exit(struct tegra_output *output) { + /* + * The connector is going away, so the interrupt must be disabled to + * prevent the hotplug interrupt handler from potentially crashing. + */ + if (gpio_is_valid(output->hpd_gpio)) + disable_irq(output->hpd_irq); + return 0; } -- GitLab From dc6057ecb39edb34b0461ca55382094410bd257a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 30 Oct 2014 15:32:56 +0100 Subject: [PATCH 4653/9457] drm/tegra: gem: dumb: pitch and size are outputs When creating a dumb buffer object using the DRM_IOCTL_MODE_CREATE_DUMB IOCTL, only the width, height, bpp and flags parameters are inputs. The caller is not guaranteed to zero out or set handle, pitch and size, so the driver must not treat these values as possible inputs. Fixes a bug where running the Weston compositor on Tegra DRM would cause an attempt to allocate a 3 GiB framebuffer to be allocated. Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb") Cc: stable@vger.kernel.org Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 8b1095d05c58..8348783f7d64 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -399,16 +399,12 @@ void tegra_bo_free_object(struct drm_gem_object *gem) int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, struct drm_mode_create_dumb *args) { - int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); struct tegra_drm *tegra = drm->dev_private; struct tegra_bo *bo; - min_pitch = round_up(min_pitch, tegra->pitch_align); - if (args->pitch < min_pitch) - args->pitch = min_pitch; - - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; + args->pitch = round_up(min_pitch, tegra->pitch_align); + args->size = args->pitch * args->height; bo = tegra_bo_create_with_handle(file, drm, args->size, 0, &args->handle); -- GitLab From 3feaf3e5ae89347a2ab3b9e994f1f3d85c09185f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 21 Oct 2014 13:56:59 +0200 Subject: [PATCH 4654/9457] drm/tegra: fb: Do not destroy framebuffer Drop a reference instead of directly calling the framebuffer .destroy() callback at fbdev free time. This is necessary to make sure the object isn't destroyed if anyone else still has a reference. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index fab39eb2dae8..ec5ae7cf4349 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -360,7 +360,7 @@ static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) if (fbdev->fb) { drm_framebuffer_unregister_private(&fbdev->fb->base); - tegra_fb_destroy(&fbdev->fb->base); + drm_framebuffer_remove(&fbdev->fb->base); } drm_fb_helper_fini(&fbdev->base); -- GitLab From 71c38629d6bd4be74009fc73946255254477c77e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 3 Nov 2014 13:23:02 +0100 Subject: [PATCH 4655/9457] drm/tegra: gem: Use more consistent data types Use size_t consistently for sizes and u32/u64 instead of uint32_t and uint64_t. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 8 ++++---- drivers/gpu/drm/tegra/gem.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 8348783f7d64..4a4f967c6397 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -264,7 +264,7 @@ static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, return 0; } -struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, +struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size, unsigned long flags) { struct tegra_bo *bo; @@ -294,9 +294,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, struct drm_device *drm, - unsigned int size, + size_t size, unsigned long flags, - unsigned int *handle) + u32 *handle) { struct tegra_bo *bo; int err; @@ -415,7 +415,7 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, } int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, - uint32_t handle, uint64_t *offset) + u32 handle, u64 *offset) { struct drm_gem_object *gem; struct tegra_bo *bo; diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h index 3dd4165f812a..6c5f12ac0087 100644 --- a/drivers/gpu/drm/tegra/gem.h +++ b/drivers/gpu/drm/tegra/gem.h @@ -52,18 +52,18 @@ static inline struct tegra_bo *to_tegra_bo(struct drm_gem_object *gem) return container_of(gem, struct tegra_bo, gem); } -struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, +struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size, unsigned long flags); struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, struct drm_device *drm, - unsigned int size, + size_t size, unsigned long flags, - unsigned int *handle); + u32 *handle); void tegra_bo_free_object(struct drm_gem_object *gem); int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, struct drm_mode_create_dumb *args); int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, - uint32_t handle, uint64_t *offset); + u32 handle, u64 *offset); int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma); -- GitLab From 1053f4dd82338ca82de46a23a11d51d7455b02c6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 4 Nov 2014 16:17:55 +0100 Subject: [PATCH 4656/9457] drm/tegra: Plug memory leak Free the DRM device-private memory upon driver unload to make sure the memory doesn't leak. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 6c9df794b3be..e549afeece1f 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -118,6 +118,8 @@ static int tegra_drm_unload(struct drm_device *drm) drm_mm_takedown(&tegra->mm); } + kfree(tegra); + return 0; } -- GitLab From 9aaa0cebcb3ebabd52a2a269a50fe3525d8deed1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 4 Nov 2014 16:20:20 +0100 Subject: [PATCH 4657/9457] drm/tegra: Detach panel when a connector is removed When the DRM device is torn down and the connector is removed, make sure to detach the panel to make sure there are no dangling pointers. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 022462d3a413..6a5c7b81fbc5 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -347,5 +347,8 @@ int tegra_output_exit(struct tegra_output *output) if (gpio_is_valid(output->hpd_gpio)) disable_irq(output->hpd_irq); + if (output->panel) + drm_panel_detach(output->panel); + return 0; } -- GitLab From b88f005ea38f29b50e55fc7eb25d92ea78a2eeab Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 14:33:19 +0100 Subject: [PATCH 4658/9457] drm/tegra: fb: Properly release GEM objects on failure When fbdev initialization fails, make sure to unreference the GEM objects properly. Note that we can't do this in the general error unwinding path because ownership of the GEM object references is transferred to the framebuffer upon creation. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/fb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index ec5ae7cf4349..a64f23af0841 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -227,7 +227,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info = framebuffer_alloc(0, drm->dev); if (!info) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); - tegra_bo_free_object(&bo->gem); + drm_gem_object_unreference_unlocked(&bo->gem); return -ENOMEM; } @@ -235,6 +235,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(fbdev->fb)) { dev_err(drm->dev, "failed to allocate DRM framebuffer\n"); err = PTR_ERR(fbdev->fb); + drm_gem_object_unreference_unlocked(&bo->gem); goto release; } -- GitLab From cb10c81fdf8c77df4fffc8cb740ddf33427869df Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 14:36:19 +0100 Subject: [PATCH 4659/9457] drm/tegra: fb: Add error codes to error messages This helps in determining what errors happened at specifics points in the initialization sequence. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/fb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index a64f23af0841..e9c715d89261 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -233,8 +233,9 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, fbdev->fb = tegra_fb_alloc(drm, &cmd, &bo, 1); if (IS_ERR(fbdev->fb)) { - dev_err(drm->dev, "failed to allocate DRM framebuffer\n"); err = PTR_ERR(fbdev->fb); + dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", + err); drm_gem_object_unreference_unlocked(&bo->gem); goto release; } @@ -319,19 +320,21 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev, err = drm_fb_helper_init(drm, &fbdev->base, num_crtc, max_connectors); if (err < 0) { - dev_err(drm->dev, "failed to initialize DRM FB helper\n"); + dev_err(drm->dev, "failed to initialize DRM FB helper: %d\n", + err); return err; } err = drm_fb_helper_single_add_all_connectors(&fbdev->base); if (err < 0) { - dev_err(drm->dev, "failed to add connectors\n"); + dev_err(drm->dev, "failed to add connectors: %d\n", err); goto fini; } err = drm_fb_helper_initial_config(&fbdev->base, preferred_bpp); if (err < 0) { - dev_err(drm->dev, "failed to set initial configuration\n"); + dev_err(drm->dev, "failed to set initial configuration: %d\n", + err); goto fini; } -- GitLab From 7e0180e3570cc791e95e6b6cd5fbeb0aedc62776 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 6 Nov 2014 14:41:31 +0100 Subject: [PATCH 4660/9457] drm/tegra: gem: Check before freeing CMA memory dma_free_writecombine() must not be called on a buffer that couldn't be allocated. Check for a valid virtual address before attempting to free the memory to avoid a crash. Reported-by: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 4a4f967c6397..da32086cbeaf 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -210,7 +210,7 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) drm_gem_put_pages(&bo->gem, bo->pages, true, true); sg_free_table(bo->sgt); kfree(bo->sgt); - } else { + } else if (bo->vaddr) { dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr); } -- GitLab From 62d0ff83c6e2221662fa0dccf2de096bdc7a2fc4 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Wed, 5 Nov 2014 16:45:11 +0800 Subject: [PATCH 4661/9457] PCI: layerscape: Add Freescale Layerscape PCIe driver Add support for Freescale Layerscape PCIe controller. This driver re-uses the Synopsis DesignWare core code. [bhelgaas: add Kconfig dependency on CONFIG_ARM] Signed-off-by: Minghuan Lian Signed-off-by: Bjorn Helgaas Acked-by: Arnd Bergmann --- .../bindings/pci/layerscape-pci.txt | 42 ++++ MAINTAINERS | 10 + drivers/pci/host/Kconfig | 8 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-layerscape.c | 179 ++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci.txt create mode 100644 drivers/pci/host/pci-layerscape.c diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt new file mode 100644 index 000000000000..6286f049bf18 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -0,0 +1,42 @@ +Freescale Layerscape PCIe controller + +This PCIe host controller is based on the Synopsis Designware PCIe IP +and thus inherits all the common properties defined in designware-pcie.txt. + +Required properties: +- compatible: should contain the platform identifier such as "fsl,ls1021a-pcie" +- reg: base addresses and lengths of the PCIe controller +- interrupts: A list of interrupt outputs of the controller. Must contain an + entry for each entry in the interrupt-names property. +- interrupt-names: Must include the following entries: + "intr": The interrupt that is asserted for controller interrupts +- fsl,pcie-scfg: Must include two entries. + The first entry must be a link to the SCFG device node + The second entry must be '0' or '1' based on physical PCIe controller index. + This is used to get SCFG PEXN registers + +Example: + + pcie@3400000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + fsl,pcie-scfg = <&scfg 0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0xc2000000 0x0 0x20000000 0x40 0x20000000 0x0 0x20000000 /* prefetchable memory */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a20df9bf8ab0..016e1ef1c16c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6983,6 +6983,16 @@ S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci.txt F: drivers/pci/host/pci-xgene.c +PCI DRIVER FOR FREESCALE LAYERSCAPE +M: Minghuan Lian +M: Mingkai Hu +M: Roy Zang +L: linuxppc-dev@lists.ozlabs.org +L: linux-pci@vger.kernel.org +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: drivers/pci/host/*layerscape* + PCI DRIVER FOR IMX6 M: Richard Zhu M: Lucas Stach diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 3dc25fad490c..67e2cc5a0bd4 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -91,4 +91,12 @@ config PCI_XGENE There are 5 internal PCIe ports available. Each port is GEN3 capable and have varied lanes from x1 to x8. +config PCI_LAYERSCAPE + bool "Freescale Layerscape PCIe controller" + depends on OF && ARM + select PCIE_DW + select MFD_SYSCON + help + Say Y here if you want PCIe controller support on Layerscape SoCs. + endmenu diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 26b3461d68d7..44c26998027f 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o obj-$(CONFIG_PCI_XGENE) += pci-xgene.o +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c new file mode 100644 index 000000000000..6697b1a4d4fa --- /dev/null +++ b/drivers/pci/host/pci-layerscape.c @@ -0,0 +1,179 @@ +/* + * PCIe host controller driver for Freescale Layerscape SoCs + * + * Copyright (C) 2014 Freescale Semiconductor. + * + * Author: Minghuan Lian + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-designware.h" + +/* PEX1/2 Misc Ports Status Register */ +#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) +#define LTSSM_STATE_SHIFT 20 +#define LTSSM_STATE_MASK 0x3f +#define LTSSM_PCIE_L0 0x11 /* L0 state */ + +/* Symbol Timer Register and Filter Mask Register 1 */ +#define PCIE_STRFMR1 0x71c + +struct ls_pcie { + struct list_head node; + struct device *dev; + struct pci_bus *bus; + void __iomem *dbi; + struct regmap *scfg; + struct pcie_port pp; + int index; + int msi_irq; +}; + +#define to_ls_pcie(x) container_of(x, struct ls_pcie, pp) + +static int ls_pcie_link_up(struct pcie_port *pp) +{ + u32 state; + struct ls_pcie *pcie = to_ls_pcie(pp); + + regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state); + state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK; + + if (state < LTSSM_PCIE_L0) + return 0; + + return 1; +} + +static void ls_pcie_host_init(struct pcie_port *pp) +{ + struct ls_pcie *pcie = to_ls_pcie(pp); + int count = 0; + u32 val; + + dw_pcie_setup_rc(pp); + + while (!ls_pcie_link_up(pp)) { + usleep_range(100, 1000); + count++; + if (count >= 200) { + dev_err(pp->dev, "phy link never came up\n"); + return; + } + } + + /* + * LS1021A Workaround for internal TKT228622 + * to fix the INTx hang issue + */ + val = ioread32(pcie->dbi + PCIE_STRFMR1); + val &= 0xffff; + iowrite32(val, pcie->dbi + PCIE_STRFMR1); +} + +static struct pcie_host_ops ls_pcie_host_ops = { + .link_up = ls_pcie_link_up, + .host_init = ls_pcie_host_init, +}; + +static int ls_add_pcie_port(struct ls_pcie *pcie) +{ + struct pcie_port *pp; + int ret; + + pp = &pcie->pp; + pp->dev = pcie->dev; + pp->dbi_base = pcie->dbi; + pp->root_bus_nr = -1; + pp->ops = &ls_pcie_host_ops; + + ret = dw_pcie_host_init(pp); + if (ret) { + dev_err(pp->dev, "failed to initialize host\n"); + return ret; + } + + return 0; +} + +static int __init ls_pcie_probe(struct platform_device *pdev) +{ + struct ls_pcie *pcie; + struct resource *dbi_base; + u32 index[2]; + int ret; + + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pcie->dev = &pdev->dev; + + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + if (!dbi_base) { + dev_err(&pdev->dev, "missing *regs* space\n"); + return -ENODEV; + } + + pcie->dbi = devm_ioremap_resource(&pdev->dev, dbi_base); + if (IS_ERR(pcie->dbi)) + return PTR_ERR(pcie->dbi); + + pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "fsl,pcie-scfg"); + if (IS_ERR(pcie->scfg)) { + dev_err(&pdev->dev, "No syscfg phandle specified\n"); + return PTR_ERR(pcie->scfg); + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "fsl,pcie-scfg", index, 2); + if (ret) + return ret; + pcie->index = index[1]; + + ret = ls_add_pcie_port(pcie); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, pcie); + + return 0; +} + +static const struct of_device_id ls_pcie_of_match[] = { + { .compatible = "fsl,ls1021a-pcie" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ls_pcie_of_match); + +static struct platform_driver ls_pcie_driver = { + .driver = { + .name = "layerscape-pcie", + .owner = THIS_MODULE, + .of_match_table = ls_pcie_of_match, + }, +}; + +module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); + +MODULE_AUTHOR("Minghuan Lian "); +MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 23926c8dbd6fdca3da884fa6c2daa0d6a3cbddec Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 6 Nov 2014 14:30:49 +0900 Subject: [PATCH 4662/9457] PCI: dra7xx: Rename add_pcie_port() to dra7xx_add_pcie_port() The add_pcie_port() function is dra7xx-specific. Add dra7xx prefix to avoid collision in global name space. Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Kishon Vijay Abraham I --- drivers/pci/host/pci-dra7xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 52b34fee07fd..5b4a644c8058 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -270,8 +270,8 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) return IRQ_HANDLED; } -static int add_pcie_port(struct dra7xx_pcie *dra7xx, - struct platform_device *pdev) +static int dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, + struct platform_device *pdev) { int ret; struct pcie_port *pp; @@ -398,7 +398,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dra7xx); - ret = add_pcie_port(dra7xx, pdev); + ret = dra7xx_add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_add_port; -- GitLab From a9875d83a0ae57a18f9c9f70c2ac524b81cc2cbe Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 6 Nov 2014 10:29:41 +0900 Subject: [PATCH 4663/9457] PCI: spear: Rename add_pcie_port(), pcie_init() to spear13xx_add_pcie_port(), etc. The add_pcie_port() and pcie_init() functions are SPEAr13xx-specific. Add spear13xx prefix to avoid collision in global name space. Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Viresh Kumar --- drivers/pci/host/pcie-spear13xx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 85f594e1708f..63f869f953e1 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -269,7 +269,8 @@ static struct pcie_host_ops spear13xx_pcie_host_ops = { .host_init = spear13xx_pcie_host_init, }; -static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev) +static int spear13xx_add_pcie_port(struct pcie_port *pp, + struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret; @@ -352,7 +353,7 @@ static int __init spear13xx_pcie_probe(struct platform_device *pdev) if (of_property_read_bool(np, "st,pcie-is-gen1")) spear13xx_pcie->is_gen1 = true; - ret = add_pcie_port(pp, pdev); + ret = spear13xx_add_pcie_port(pp, pdev); if (ret < 0) goto fail_clk; @@ -382,11 +383,11 @@ static struct platform_driver spear13xx_pcie_driver __initdata = { /* SPEAr13xx PCIe driver does not allow module unload */ -static int __init pcie_init(void) +static int __init spear13xx_pcie_init(void) { return platform_driver_register(&spear13xx_pcie_driver); } -module_init(pcie_init); +module_init(spear13xx_pcie_init); MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); MODULE_AUTHOR("Pratyush Anand "); -- GitLab From 992e7bd2be1817d6327febebcfff7ab836a3306c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 6 Nov 2014 14:38:18 +0900 Subject: [PATCH 4664/9457] PCI: spear: Add __init annotation to spear13xx_add_pcie_port() Add __init annotation to spear13xx_add_pcie_port(), because spear13xx_add_pcie_port() is called only by spear13xx_pcie_probe(), which is marked __init. This fixes a section mismatch warning: WARNING: drivers/pci/host/built-in.o(.text.unlikely+0x94): Section mismatch in reference from the function spear13xx_add_pcie_port() to the function .init.text:dw_pcie_host_init() Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Viresh Kumar --- drivers/pci/host/pcie-spear13xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 63f869f953e1..60f43cd96854 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -269,8 +269,8 @@ static struct pcie_host_ops spear13xx_pcie_host_ops = { .host_init = spear13xx_pcie_host_init, }; -static int spear13xx_add_pcie_port(struct pcie_port *pp, - struct platform_device *pdev) +static int __init spear13xx_add_pcie_port(struct pcie_port *pp, + struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret; -- GitLab From e73044a069c40b8c49c75f1869a07bd912801494 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 6 Nov 2014 14:37:39 +0900 Subject: [PATCH 4665/9457] PCI: dra7xx: Add __init annotation to dra7xx_add_pcie_port() Add __init annotation to dra7xx_add_pcie_port(), because dra7xx_add_pcie_port() is called only by dra7xx_pcie_probe() which is marked __init. This patch fixes a section mismatch warning: WARNING: drivers/pci/host/built-in.o(.text.unlikely+0xcc): Section mismatch in reference from the function dra7xx_add_pcie_port() to the function .init.text:dw_pcie_host_init() Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pci-dra7xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 5b4a644c8058..8c6969747acd 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -270,8 +270,8 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) return IRQ_HANDLED; } -static int dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, - struct platform_device *pdev) +static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, + struct platform_device *pdev) { int ret; struct pcie_port *pp; -- GitLab From bb383e283b2c2dca8eb5152a1a2477efcc469431 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:41:51 +1100 Subject: [PATCH 4666/9457] PCI: Make FLR and AF FLR reset warning messages different We have same warning message for FLR and AF FLR and users can't know which type of resets the PCI device is taking when there are pending transactions. Print different messages for FLR and AF FLR cases. [bhelgaas: make code structure parallel, add "anyway" to suggest risk] Signed-off-by: Gavin Shan Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9a5871f530a7..e8b3627e5474 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3140,12 +3140,10 @@ static int pcie_flr(struct pci_dev *dev, int probe) return 0; if (!pci_wait_for_pending_transaction(dev)) - dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); + dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n"); pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); - msleep(100); - return 0; } @@ -3170,16 +3168,12 @@ static int pci_af_flr(struct pci_dev *dev, int probe) * is used, so we use the conrol offset rather than status and shift * the test bit to match. */ - if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL, + if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL, PCI_AF_STATUS_TP << 8)) - goto clear; + dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n"); - dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); - -clear: pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); msleep(100); - return 0; } -- GitLab From a4acded086c4320bc58bd59ea746fd19de6dabb0 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:43:52 +1100 Subject: [PATCH 4667/9457] PCI: Remove unused and broken to_hotplug_slot() to_hotplug_slot() is unused and wouldn't work anyway, because struct hotplug_slot no longer contains a struct kobject (it was removed by f46753c5e354 ("PCI: introduce pci_slot")). Remove to_hotplug_slot(). [bhelgaas: changelog] Signed-off-by: Gavin Shan Signed-off-by: Bjorn Helgaas --- include/linux/pci_hotplug.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 2706ee9a4327..8c7895061121 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -109,7 +109,6 @@ struct hotplug_slot { struct list_head slot_list; struct pci_slot *pci_slot; }; -#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj) static inline const char *hotplug_slot_name(const struct hotplug_slot *slot) { -- GitLab From 6670070742991c69e02dde38c611a6c31ce8f30b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:22:56 +0900 Subject: [PATCH 4668/9457] PCI: keystone: Remove unnecessary OOM message The site-specific OOM messages are unnecessary because they duplicate the MM subsystem generic OOM message. This patch fixes the following checkpatch warning: WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pci-keystone.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 1b893bc8b842..62b9454c86fb 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c @@ -353,10 +353,9 @@ static int __init ks_pcie_probe(struct platform_device *pdev) ks_pcie = devm_kzalloc(&pdev->dev, sizeof(*ks_pcie), GFP_KERNEL); - if (!ks_pcie) { - dev_err(dev, "no memory for keystone pcie\n"); + if (!ks_pcie) return -ENOMEM; - } + pp = &ks_pcie->pp; /* initialize SerDes Phy if present */ -- GitLab From d88a7ef99e4c15985e0d726d4a4e4c1f0e4f0ad5 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:25:09 +0900 Subject: [PATCH 4669/9457] PCI: imx6: Use tabs for indentation This patch fixes the following checkpatch error: ERROR: code indent should use tabs where possible Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pci-imx6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 233fe8a88264..8a7530b3b62a 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -526,8 +526,8 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } ret = devm_request_irq(&pdev->dev, pp->msi_irq, - imx6_pcie_msi_handler, - IRQF_SHARED, "mx6-pcie-msi", pp); + imx6_pcie_msi_handler, + IRQF_SHARED, "mx6-pcie-msi", pp); if (ret) { dev_err(&pdev->dev, "failed to request MSI irq\n"); return -ENODEV; -- GitLab From bc512c5a8c78db6904de7275bce54ce5b1433893 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:25:38 +0900 Subject: [PATCH 4670/9457] PCI: exynos: Remove unnecessary return statement This patch fixes the following checkpatch warning: WARNING: void function return statements are not generally useful Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pci-exynos.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index 902d7cd3e760..850c9f951a3f 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -312,7 +312,6 @@ static void exynos_pcie_assert_reset(struct pcie_port *pp) if (exynos_pcie->reset_gpio >= 0) devm_gpio_request_one(pp->dev, exynos_pcie->reset_gpio, GPIOF_OUT_INIT_HIGH, "RESET"); - return; } static int exynos_pcie_establish_link(struct pcie_port *pp) @@ -388,7 +387,6 @@ static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp) val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_PULSE); exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_PULSE); - return; } static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp) @@ -400,7 +398,6 @@ static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp) val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | IRQ_INTC_ASSERT | IRQ_INTD_ASSERT, exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_PULSE); - return; } static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) @@ -429,7 +426,6 @@ static void exynos_pcie_msi_init(struct pcie_port *pp) val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_EN_LEVEL); val |= IRQ_MSI_ENABLE; exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_LEVEL); - return; } static void exynos_pcie_enable_interrupts(struct pcie_port *pp) @@ -438,8 +434,6 @@ static void exynos_pcie_enable_interrupts(struct pcie_port *pp) if (IS_ENABLED(CONFIG_PCI_MSI)) exynos_pcie_msi_init(pp); - - return; } static inline void exynos_pcie_readl_rc(struct pcie_port *pp, @@ -448,7 +442,6 @@ static inline void exynos_pcie_readl_rc(struct pcie_port *pp, exynos_pcie_sideband_dbi_r_mode(pp, true); *val = readl(dbi_base); exynos_pcie_sideband_dbi_r_mode(pp, false); - return; } static inline void exynos_pcie_writel_rc(struct pcie_port *pp, @@ -457,7 +450,6 @@ static inline void exynos_pcie_writel_rc(struct pcie_port *pp, exynos_pcie_sideband_dbi_w_mode(pp, true); writel(val, dbi_base); exynos_pcie_sideband_dbi_w_mode(pp, false); - return; } static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, -- GitLab From 2c992f3779e699a0f03dbfa39fcd96efee422bbe Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:27:04 +0900 Subject: [PATCH 4671/9457] PCI: designware: Add a blank line after declarations This patch fixes the following checkpatch warning: WARNING: Missing a blank line after declarations Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas --- drivers/pci/host/pcie-designware.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index dfed00aa3ac0..f9be37139429 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -380,6 +380,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) /* Get the I/O and memory ranges from DT */ for_each_of_pci_range(&parser, &range) { unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; + if (restype == IORESOURCE_IO) { of_pci_range_to_resource(&range, np, &pp->io); pp->io.name = "I/O"; -- GitLab From cf3a9d6bae51e3ff14196a4684c47c234fc34c27 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:27:54 +0900 Subject: [PATCH 4672/9457] PCI: mvebu: Add a blank line after declarations This patch fixes the following checkpatch warning: WARNING: Missing a blank line after declarations [bhelgaas: drop mvebu_pcie_add_bus() change because it's going away anyway] Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Jason Cooper --- drivers/pci/host/pci-mvebu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index b1315e197ffb..e45f88e1244f 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -622,6 +622,7 @@ static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie, for (i = 0; i < pcie->nports; i++) { struct mvebu_pcie_port *port = &pcie->ports[i]; + if (bus->number == 0 && port->devfn == devfn) return port; if (bus->number != 0 && @@ -751,6 +752,7 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) for (i = 0; i < pcie->nports; i++) { struct mvebu_pcie_port *port = &pcie->ports[i]; + if (!port->base) continue; mvebu_pcie_setup_hw(port); -- GitLab From 20f9ece101d8793331f61a234cef3ee000891085 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 12 Nov 2014 12:29:02 +0900 Subject: [PATCH 4673/9457] PCI: spear: Remove unnecessary OOM message The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. This patch fixes the following checkpatch warning: WARNING: Possible unnecessary 'out of memory' message Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas Acked-by: Viresh Kumar --- drivers/pci/host/pcie-spear13xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 60f43cd96854..2ca10cc887ee 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -309,10 +309,8 @@ static int __init spear13xx_pcie_probe(struct platform_device *pdev) int ret; spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL); - if (!spear13xx_pcie) { - dev_err(dev, "no memory for SPEAr13xx pcie\n"); + if (!spear13xx_pcie) return -ENOMEM; - } spear13xx_pcie->phy = devm_phy_get(dev, "pcie-phy"); if (IS_ERR(spear13xx_pcie->phy)) { -- GitLab From 9e6280cd44c1cceaaac921567ee8c5731b7cc72b Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:21 +0530 Subject: [PATCH 4674/9457] ASoC: rt5631: Add device tree binding documentation Document the device tree binding for the ALC5631 codec and update vendor specific prefix for the Realtek. Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/rt5631.txt | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/rt5631.txt diff --git a/Documentation/devicetree/bindings/sound/rt5631.txt b/Documentation/devicetree/bindings/sound/rt5631.txt new file mode 100644 index 000000000000..92b986ca337b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5631.txt @@ -0,0 +1,48 @@ +ALC5631/RT5631 audio CODEC + +This device supports I2C only. + +Required properties: + + - compatible : "realtek,alc5631" or "realtek,rt5631" + + - reg : the I2C address of the device. + +Pins on the device (for linking into audio routes): + + * SPK_OUT_R_P + * SPK_OUT_R_N + * SPK_OUT_L_P + * SPK_OUT_L_N + * HP_OUT_L + * HP_OUT_R + * AUX_OUT2_LP + * AUX_OUT2_RN + * AUX_OUT1_LP + * AUX_OUT1_RN + * AUX_IN_L_JD + * AUX_IN_R_JD + * MONO_IN_P + * MONO_IN_N + * MIC1_P + * MIC1_N + * MIC2_P + * MIC2_N + * MONO_OUT_P + * MONO_OUT_N + * MICBIAS1 + * MICBIAS2 + +Example: + +alc5631: alc5631@1a { + compatible = "realtek,alc5631"; + reg = <0x1a>; +}; + +or + +rt5631: rt5631@1a { + compatible = "realtek,rt5631"; + reg = <0x1a>; +}; -- GitLab From 86707f7fece1d3a34aeb1e9c7f2178fd5ff4e788 Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:23 +0530 Subject: [PATCH 4675/9457] ASoC: rt5631: Adding the description of the codec Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..7e43e97ef359 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -487,7 +487,8 @@ config SND_SOC_RT286 depends on I2C config SND_SOC_RT5631 - tristate + tristate "Realtek ALC5631/RT5631 CODEC" + depends on I2C config SND_SOC_RT5640 tristate -- GitLab From 189c88ced169d5197c806828e275c6f063b1d499 Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Thu, 13 Nov 2014 17:44:24 +0530 Subject: [PATCH 4676/9457] ASoC: rt5631: Adding Device Tree compatibility to Realtek's ALC5631/RT5631 codec driver Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown --- sound/soc/codecs/rt5631.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 1ba27db660a6..3b7d5e4a3ef6 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1686,10 +1686,18 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { static const struct i2c_device_id rt5631_i2c_id[] = { { "rt5631", 0 }, + { "alc5631", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); +static struct of_device_id rt5631_i2c_dt_ids[] = { + { .compatible = "realtek,rt5631"}, + { .compatible = "realtek,alc5631"}, + { } +}; +MODULE_DEVICE_TABLE(of, rt5631_i2c_dt_ids); + static const struct regmap_config rt5631_regmap_config = { .reg_bits = 8, .val_bits = 16, @@ -1734,6 +1742,7 @@ static struct i2c_driver rt5631_i2c_driver = { .driver = { .name = "rt5631", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rt5631_i2c_dt_ids), }, .probe = rt5631_i2c_probe, .remove = rt5631_i2c_remove, -- GitLab From 4407308b73a33dadfc72e5754f5bba5d5dec206f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Nov 2014 14:53:37 +0100 Subject: [PATCH 4677/9457] PCI: tegra: Do not build on 64-bit ARM 32-bit and 64-bit ARM use very different infrastructure to register a PCI host bridge. The Tegra PCIe host controller driver currently only supports the 32-bit ARM infrastructure, so prevent it from being built on 64-bit ARM where it will break. Signed-off-by: Thierry Reding Signed-off-by: Bjorn Helgaas --- drivers/pci/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 3dc25fad490c..9c56137e5e5e 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -32,7 +32,7 @@ config PCI_IMX6 config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" - depends on ARCH_TEGRA + depends on ARCH_TEGRA && !ARM64 config PCI_RCAR_GEN2 bool "Renesas R-Car Gen2 Internal PCI controller" -- GitLab From 6b1c4d7674edd213295befb9e007edd6aea857ff Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Nov 2014 14:53:38 +0100 Subject: [PATCH 4678/9457] PCI: tegra: Add Kconfig help text Add a standard help text to the Kconfig entry for the Tegra PCIe host controller driver. Signed-off-by: Thierry Reding Signed-off-by: Bjorn Helgaas --- drivers/pci/host/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 9c56137e5e5e..9dbb1fc68bc9 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -33,6 +33,9 @@ config PCI_IMX6 config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA && !ARM64 + help + Say Y here if you want support for the PCIe host controller found + on NVIDIA Tegra SoCs. config PCI_RCAR_GEN2 bool "Renesas R-Car Gen2 Internal PCI controller" -- GitLab From 882288c05ede954e797baa623062f5ea06663ae1 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 13 Nov 2014 12:48:21 +0100 Subject: [PATCH 4679/9457] FOU: Fix no return statement warning for !CONFIG_NET_FOU_IP_TUNNELS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/ipv4/fou.c: In function ‘ip_tunnel_encap_del_fou_ops’: net/ipv4/fou.c:861:1: warning: no return statement in function returning non-void [-Wreturn-type] Fixes: a8c5f90fb5 ("ip_tunnel: Ops registration for secondary encap (fou, gue)") Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv4/fou.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index fe0907774ce8..b0b436b0692c 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -856,7 +856,7 @@ static int ip_tunnel_encap_add_fou_ops(void) return 0; } -static int ip_tunnel_encap_del_fou_ops(void) +static void ip_tunnel_encap_del_fou_ops(void) { } -- GitLab From 8c847d254146d32c86574a1b16923ff91bb784dd Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 13 Nov 2014 16:54:14 +0800 Subject: [PATCH 4680/9457] tun: fix issues of iovec iterators using in tun_put_user() This patch fixes two issues after using iovec iterators: - vlan_offset should be initialized to zero, otherwise unexpected offset will be used in skb_copy_datagram_iter() - advance iovec iterator when vnet_hdr_sz is greater than sizeof(gso), this is the case when mergeable rx buffer were enabled for a virt guest. Fixes e0b46d0ee9c240c7430a47e9b0365674d4a04522 ("tun: Use iovec iterators") Cc: Herbert Xu Signed-off-by: Jason Wang Acked-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/tun.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2ff769bf3f35..e3fa65a4d96c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1235,7 +1235,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, { struct tun_pi pi = { 0, skb->protocol }; ssize_t total; - int vlan_offset; + int vlan_offset = 0; int vlan_hlen = 0; int vnet_hdr_sz = 0; @@ -1304,6 +1304,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (copy_to_iter(&gso, sizeof(gso), iter) != sizeof(gso)) return -EFAULT; + + iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); } if (vlan_hlen) { -- GitLab From d7990b0c34623cd54475a0562c607efbaba4899d Mon Sep 17 00:00:00 2001 From: Anish Bhatt Date: Wed, 12 Nov 2014 17:15:57 -0800 Subject: [PATCH 4681/9457] cxgb4i/cxgb4 : Refactor macros to conform to uniform standards Refactored all macros used in cxgb4i as part of previously started cxgb4 macro names cleanup. Makes them more uniform and avoids namespace collision. Minor changes in other drivers where required as some of these macros are used by multiple drivers, affected drivers are iw_cxgb4, cxgb4(vf) & csiostor Signed-off-by: Anish Bhatt Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 104 +++++++-------- drivers/infiniband/hw/cxgb4/mem.c | 20 +-- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 +- drivers/net/ethernet/chelsio/cxgb4/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 120 +++++++++++++----- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 6 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +- drivers/scsi/csiostor/csio_lnode.c | 2 +- drivers/scsi/csiostor/csio_scsi.c | 2 +- drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 78 ++++++------ 11 files changed, 200 insertions(+), 142 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index a07d8e124a80..83fa16fa4644 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -649,31 +649,31 @@ static int send_connect(struct c4iw_ep *ep) * remainder will be specified in the rx_data_ack. */ win = ep->rcv_win >> 10; - if (win > RCV_BUFSIZ_MASK) - win = RCV_BUFSIZ_MASK; + if (win > RCV_BUFSIZ_M) + win = RCV_BUFSIZ_M; opt0 = (nocong ? NO_CONG(1) : 0) | - KEEP_ALIVE(1) | + KEEP_ALIVE_F | DELACK(1) | - WND_SCALE(wscale) | - MSS_IDX(mtu_idx) | - L2T_IDX(ep->l2t->idx) | - TX_CHAN(ep->tx_chan) | - SMAC_SEL(ep->smac_idx) | + WND_SCALE_V(wscale) | + MSS_IDX_V(mtu_idx) | + L2T_IDX_V(ep->l2t->idx) | + TX_CHAN_V(ep->tx_chan) | + SMAC_SEL_V(ep->smac_idx) | DSCP(ep->tos) | - ULP_MODE(ULP_MODE_TCPDDP) | - RCV_BUFSIZ(win); - opt2 = RX_CHANNEL(0) | + ULP_MODE_V(ULP_MODE_TCPDDP) | + RCV_BUFSIZ_V(win); + opt2 = RX_CHANNEL_V(0) | CCTRL_ECN(enable_ecn) | - RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); + RSS_QUEUE_VALID_F | RSS_QUEUE_V(ep->rss_qid); if (enable_tcp_timestamps) opt2 |= TSTAMPS_EN(1); if (enable_tcp_sack) opt2 |= SACK_EN(1); if (wscale && enable_tcp_window_scaling) - opt2 |= WND_SCALE_EN(1); + opt2 |= WND_SCALE_EN_F; if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { - opt2 |= T5_OPT_2_VALID; + opt2 |= T5_OPT_2_VALID_F; opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE); opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ } @@ -736,7 +736,7 @@ static int send_connect(struct c4iw_ep *ep) t5_req->local_ip = la->sin_addr.s_addr; t5_req->peer_ip = ra->sin_addr.s_addr; t5_req->opt0 = cpu_to_be64(opt0); - t5_req->params = cpu_to_be64(V_FILTER_TUPLE( + t5_req->params = cpu_to_be64(FILTER_TUPLE_V( cxgb4_select_ntuple( ep->com.dev->rdev.lldi.ports[0], ep->l2t))); @@ -762,7 +762,7 @@ static int send_connect(struct c4iw_ep *ep) t5_req6->peer_ip_lo = *((__be64 *) (ra6->sin6_addr.s6_addr + 8)); t5_req6->opt0 = cpu_to_be64(opt0); - t5_req6->params = cpu_to_be64(V_FILTER_TUPLE( + t5_req6->params = cpu_to_be64(FILTER_TUPLE_V( cxgb4_select_ntuple( ep->com.dev->rdev.lldi.ports[0], ep->l2t))); @@ -1249,15 +1249,15 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits) * due to the limit in the number of bits in the RCV_BUFSIZ field, * then add the overage in to the credits returned. */ - if (ep->rcv_win > RCV_BUFSIZ_MASK * 1024) - credits += ep->rcv_win - RCV_BUFSIZ_MASK * 1024; + if (ep->rcv_win > RCV_BUFSIZ_M * 1024) + credits += ep->rcv_win - RCV_BUFSIZ_M * 1024; req = (struct cpl_rx_data_ack *) skb_put(skb, wrlen); memset(req, 0, wrlen); INIT_TP_WR(req, ep->hwtid); OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); - req->credit_dack = cpu_to_be32(credits | RX_FORCE_ACK(1) | + req->credit_dack = cpu_to_be32(credits | RX_FORCE_ACK_F | F_RX_DACK_CHANGE | V_RX_DACK_MODE(dack_mode)); set_wr_txq(skb, CPL_PRIORITY_ACK, ep->ctrlq_idx); @@ -1778,34 +1778,34 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) * remainder will be specified in the rx_data_ack. */ win = ep->rcv_win >> 10; - if (win > RCV_BUFSIZ_MASK) - win = RCV_BUFSIZ_MASK; + if (win > RCV_BUFSIZ_M) + win = RCV_BUFSIZ_M; req->tcb.opt0 = (__force __be64) (TCAM_BYPASS(1) | (nocong ? NO_CONG(1) : 0) | - KEEP_ALIVE(1) | + KEEP_ALIVE_F | DELACK(1) | - WND_SCALE(wscale) | - MSS_IDX(mtu_idx) | - L2T_IDX(ep->l2t->idx) | - TX_CHAN(ep->tx_chan) | - SMAC_SEL(ep->smac_idx) | + WND_SCALE_V(wscale) | + MSS_IDX_V(mtu_idx) | + L2T_IDX_V(ep->l2t->idx) | + TX_CHAN_V(ep->tx_chan) | + SMAC_SEL_V(ep->smac_idx) | DSCP(ep->tos) | - ULP_MODE(ULP_MODE_TCPDDP) | - RCV_BUFSIZ(win)); + ULP_MODE_V(ULP_MODE_TCPDDP) | + RCV_BUFSIZ_V(win)); req->tcb.opt2 = (__force __be32) (PACE(1) | TX_QUEUE(ep->com.dev->rdev.lldi.tx_modq[ep->tx_chan]) | - RX_CHANNEL(0) | + RX_CHANNEL_V(0) | CCTRL_ECN(enable_ecn) | - RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid)); + RSS_QUEUE_VALID_F | RSS_QUEUE_V(ep->rss_qid)); if (enable_tcp_timestamps) - req->tcb.opt2 |= (__force __be32) TSTAMPS_EN(1); + req->tcb.opt2 |= (__force __be32)TSTAMPS_EN(1); if (enable_tcp_sack) - req->tcb.opt2 |= (__force __be32) SACK_EN(1); + req->tcb.opt2 |= (__force __be32)SACK_EN(1); if (wscale && enable_tcp_window_scaling) - req->tcb.opt2 |= (__force __be32) WND_SCALE_EN(1); - req->tcb.opt0 = cpu_to_be64((__force u64) req->tcb.opt0); - req->tcb.opt2 = cpu_to_be32((__force u32) req->tcb.opt2); + req->tcb.opt2 |= (__force __be32)WND_SCALE_EN_F; + req->tcb.opt0 = cpu_to_be64((__force u64)req->tcb.opt0); + req->tcb.opt2 = cpu_to_be32((__force u32)req->tcb.opt2); set_wr_txq(skb, CPL_PRIORITY_CONTROL, ep->ctrlq_idx); set_bit(ACT_OFLD_CONN, &ep->com.history); c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t); @@ -2178,28 +2178,28 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, * remainder will be specified in the rx_data_ack. */ win = ep->rcv_win >> 10; - if (win > RCV_BUFSIZ_MASK) - win = RCV_BUFSIZ_MASK; + if (win > RCV_BUFSIZ_M) + win = RCV_BUFSIZ_M; opt0 = (nocong ? NO_CONG(1) : 0) | - KEEP_ALIVE(1) | + KEEP_ALIVE_F | DELACK(1) | - WND_SCALE(wscale) | - MSS_IDX(mtu_idx) | - L2T_IDX(ep->l2t->idx) | - TX_CHAN(ep->tx_chan) | - SMAC_SEL(ep->smac_idx) | + WND_SCALE_V(wscale) | + MSS_IDX_V(mtu_idx) | + L2T_IDX_V(ep->l2t->idx) | + TX_CHAN_V(ep->tx_chan) | + SMAC_SEL_V(ep->smac_idx) | DSCP(ep->tos >> 2) | - ULP_MODE(ULP_MODE_TCPDDP) | - RCV_BUFSIZ(win); - opt2 = RX_CHANNEL(0) | - RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); + ULP_MODE_V(ULP_MODE_TCPDDP) | + RCV_BUFSIZ_V(win); + opt2 = RX_CHANNEL_V(0) | + RSS_QUEUE_VALID_F | RSS_QUEUE_V(ep->rss_qid); if (enable_tcp_timestamps && req->tcpopt.tstamp) opt2 |= TSTAMPS_EN(1); if (enable_tcp_sack && req->tcpopt.sack) opt2 |= SACK_EN(1); if (wscale && enable_tcp_window_scaling) - opt2 |= WND_SCALE_EN(1); + opt2 |= WND_SCALE_EN_F; if (enable_ecn) { const struct tcphdr *tcph; u32 hlen = ntohl(req->hdr_len); @@ -2211,7 +2211,7 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, } if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { u32 isn = (prandom_u32() & ~7UL) - 1; - opt2 |= T5_OPT_2_VALID; + opt2 |= T5_OPT_2_VALID_F; opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE); opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */ rpl5 = (void *)rpl; @@ -3557,7 +3557,7 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, * We store the qid in opt2 which will be used by the firmware * to send us the wr response. */ - req->tcb.opt2 = htonl(V_RSS_QUEUE(rss_qid)); + req->tcb.opt2 = htonl(RSS_QUEUE_V(rss_qid)); /* * We initialize the MSS index in TCB to 0xF. @@ -3565,7 +3565,7 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, * TCB picks up the correct value. If this was 0 * TP will ignore any value > 0 for MSS index. */ - req->tcb.opt0 = cpu_to_be64(V_MSS_IDX(0xF)); + req->tcb.opt0 = cpu_to_be64(MSS_IDX_V(0xF)); req->cookie = (unsigned long)skb; set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id); diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 9335148c1ad9..0744455cd88b 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -78,14 +78,14 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, (wait ? FW_WR_COMPL_F : 0)); req->wr.wr_lo = wait ? (__force __be64)(unsigned long) &wr_wait : 0L; req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16))); - req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); + req->cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE)); req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1)); - req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN(len>>5)); + req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(len>>5)); req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), 16)); - req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR(addr)); + req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(addr)); sgl = (struct ulptx_sgl *)(req + 1); - sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_DSGL) | + sgl->cmd_nsge = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_NSGE(1)); sgl->len0 = cpu_to_be32(len); sgl->addr0 = cpu_to_be64(data); @@ -107,12 +107,12 @@ static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, u8 wr_len, *to_dp, *from_dp; int copy_len, num_wqe, i, ret = 0; struct c4iw_wr_wait wr_wait; - __be32 cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); + __be32 cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE)); if (is_t4(rdev->lldi.adapter_type)) - cmd |= cpu_to_be32(ULP_MEMIO_ORDER(1)); + cmd |= cpu_to_be32(ULP_MEMIO_ORDER_F); else - cmd |= cpu_to_be32(V_T5_ULP_MEMIO_IMM(1)); + cmd |= cpu_to_be32(T5_ULP_MEMIO_IMM_F); addr &= 0x7FFFFFF; PDBG("%s addr 0x%x len %u\n", __func__, addr, len); @@ -144,14 +144,14 @@ static int _c4iw_write_mem_inline(struct c4iw_rdev *rdev, u32 addr, u32 len, FW_WR_LEN16_V(DIV_ROUND_UP(wr_len, 16))); req->cmd = cmd; - req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN( + req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V( DIV_ROUND_UP(copy_len, T4_ULPTX_MIN_IO))); req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr), 16)); - req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR(addr + i * 3)); + req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(addr + i * 3)); sc = (struct ulptx_idata *)(req + 1); - sc->cmd_more = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_IMM)); + sc->cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM)); sc->len = cpu_to_be32(roundup(copy_len, T4_ULPTX_MIN_IO)); to_dp = (u8 *)(sc + 1); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 660bf0f79ac5..19ffe9bc1933 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3476,7 +3476,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid, req->local_ip = sip; req->peer_ip = htonl(0); chan = rxq_to_chan(&adap->sge, queue); - req->opt0 = cpu_to_be64(TX_CHAN(chan)); + req->opt0 = cpu_to_be64(TX_CHAN_V(chan)); req->opt1 = cpu_to_be64(CONN_POLICY_ASK | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); ret = t4_mgmt_tx(adap, skb); @@ -3519,7 +3519,7 @@ int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, req->peer_ip_hi = cpu_to_be64(0); req->peer_ip_lo = cpu_to_be64(0); chan = rxq_to_chan(&adap->sge, queue); - req->opt0 = cpu_to_be64(TX_CHAN(chan)); + req->opt0 = cpu_to_be64(TX_CHAN_V(chan)); req->opt1 = cpu_to_be64(CONN_POLICY_ASK | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); ret = t4_mgmt_tx(adap, skb); diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index 96041397ee15..1eca0e21f738 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -436,7 +436,7 @@ u64 cxgb4_select_ntuple(struct net_device *dev, if (tp->vnic_shift >= 0) { u32 viid = cxgb4_port_viid(dev); u32 vf = FW_VIID_VIN_GET(viid); - u32 pf = FW_VIID_PFN_GET(viid); + u32 pf = FW_VIID_PFN_G(viid); u32 vld = FW_VIID_VIVLD_GET(viid); ntuple |= (u64)(V_FT_VNID_ID_VF(vf) | diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index dacd95008333..91dbf98036cc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -816,7 +816,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, sgl->addr0 = cpu_to_be64(addr[1]); } - sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags)); + sgl->cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags)); if (likely(--nfrags == 0)) return; /* diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index 5f4db2398c71..0f89f68948ab 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -205,16 +205,62 @@ struct work_request_hdr { #define WR_HDR struct work_request_hdr wr /* option 0 fields */ -#define S_MSS_IDX 60 -#define M_MSS_IDX 0xF -#define V_MSS_IDX(x) ((__u64)(x) << S_MSS_IDX) -#define G_MSS_IDX(x) (((x) >> S_MSS_IDX) & M_MSS_IDX) +#define TX_CHAN_S 2 +#define TX_CHAN_V(x) ((x) << TX_CHAN_S) + +#define ULP_MODE_S 8 +#define ULP_MODE_V(x) ((x) << ULP_MODE_S) + +#define RCV_BUFSIZ_S 12 +#define RCV_BUFSIZ_M 0x3FFU +#define RCV_BUFSIZ_V(x) ((x) << RCV_BUFSIZ_S) + +#define SMAC_SEL_S 28 +#define SMAC_SEL_V(x) ((__u64)(x) << SMAC_SEL_S) + +#define L2T_IDX_S 36 +#define L2T_IDX_V(x) ((__u64)(x) << L2T_IDX_S) + +#define WND_SCALE_S 50 +#define WND_SCALE_V(x) ((__u64)(x) << WND_SCALE_S) + +#define KEEP_ALIVE_S 54 +#define KEEP_ALIVE_V(x) ((__u64)(x) << KEEP_ALIVE_S) +#define KEEP_ALIVE_F KEEP_ALIVE_V(1ULL) + +#define MSS_IDX_S 60 +#define MSS_IDX_M 0xF +#define MSS_IDX_V(x) ((__u64)(x) << MSS_IDX_S) +#define MSS_IDX_G(x) (((x) >> MSS_IDX_S) & MSS_IDX_M) /* option 2 fields */ -#define S_RSS_QUEUE 0 -#define M_RSS_QUEUE 0x3FF -#define V_RSS_QUEUE(x) ((x) << S_RSS_QUEUE) -#define G_RSS_QUEUE(x) (((x) >> S_RSS_QUEUE) & M_RSS_QUEUE) +#define RSS_QUEUE_S 0 +#define RSS_QUEUE_M 0x3FF +#define RSS_QUEUE_V(x) ((x) << RSS_QUEUE_S) +#define RSS_QUEUE_G(x) (((x) >> RSS_QUEUE_S) & RSS_QUEUE_M) + +#define RSS_QUEUE_VALID_S 10 +#define RSS_QUEUE_VALID_V(x) ((x) << RSS_QUEUE_VALID_S) +#define RSS_QUEUE_VALID_F RSS_QUEUE_VALID_V(1U) + +#define RX_FC_DISABLE_S 20 +#define RX_FC_DISABLE_V(x) ((x) << RX_FC_DISABLE_S) +#define RX_FC_DISABLE_F RX_FC_DISABLE_V(1U) + +#define RX_FC_VALID_S 22 +#define RX_FC_VALID_V(x) ((x) << RX_FC_VALID_S) +#define RX_FC_VALID_F RX_FC_VALID_V(1U) + +#define RX_CHANNEL_S 26 +#define RX_CHANNEL_V(x) ((x) << RX_CHANNEL_S) + +#define WND_SCALE_EN_S 28 +#define WND_SCALE_EN_V(x) ((x) << WND_SCALE_EN_S) +#define WND_SCALE_EN_F WND_SCALE_EN_V(1U) + +#define T5_OPT_2_VALID_S 31 +#define T5_OPT_2_VALID_V(x) ((x) << T5_OPT_2_VALID_S) +#define T5_OPT_2_VALID_F T5_OPT_2_VALID_V(1U) struct cpl_pass_open_req { WR_HDR; @@ -224,20 +270,11 @@ struct cpl_pass_open_req { __be32 local_ip; __be32 peer_ip; __be64 opt0; -#define TX_CHAN(x) ((x) << 2) #define NO_CONG(x) ((x) << 4) #define DELACK(x) ((x) << 5) -#define ULP_MODE(x) ((x) << 8) -#define RCV_BUFSIZ(x) ((x) << 12) -#define RCV_BUFSIZ_MASK 0x3FFU #define DSCP(x) ((x) << 22) -#define SMAC_SEL(x) ((u64)(x) << 28) -#define L2T_IDX(x) ((u64)(x) << 36) #define TCAM_BYPASS(x) ((u64)(x) << 48) #define NAGLE(x) ((u64)(x) << 49) -#define WND_SCALE(x) ((u64)(x) << 50) -#define KEEP_ALIVE(x) ((u64)(x) << 54) -#define MSS_IDX(x) ((u64)(x) << 60) __be64 opt1; #define SYN_RSS_ENABLE (1 << 0) #define SYN_RSS_QUEUE(x) ((x) << 2) @@ -267,20 +304,13 @@ struct cpl_pass_accept_rpl { WR_HDR; union opcode_tid ot; __be32 opt2; -#define RSS_QUEUE(x) ((x) << 0) -#define RSS_QUEUE_VALID (1 << 10) #define RX_COALESCE_VALID(x) ((x) << 11) #define RX_COALESCE(x) ((x) << 12) #define PACE(x) ((x) << 16) -#define RX_FC_VALID ((1U) << 19) -#define RX_FC_DISABLE ((1U) << 20) #define TX_QUEUE(x) ((x) << 23) -#define RX_CHANNEL(x) ((x) << 26) #define CCTRL_ECN(x) ((x) << 27) -#define WND_SCALE_EN(x) ((x) << 28) #define TSTAMPS_EN(x) ((x) << 29) #define SACK_EN(x) ((x) << 30) -#define T5_OPT_2_VALID ((1U) << 31) __be64 opt0; }; @@ -305,10 +335,10 @@ struct cpl_act_open_req { __be32 opt2; }; -#define S_FILTER_TUPLE 24 -#define M_FILTER_TUPLE 0xFFFFFFFFFF -#define V_FILTER_TUPLE(x) ((x) << S_FILTER_TUPLE) -#define G_FILTER_TUPLE(x) (((x) >> S_FILTER_TUPLE) & M_FILTER_TUPLE) +#define FILTER_TUPLE_S 24 +#define FILTER_TUPLE_M 0xFFFFFFFFFF +#define FILTER_TUPLE_V(x) ((x) << FILTER_TUPLE_S) +#define FILTER_TUPLE_G(x) (((x) >> FILTER_TUPLE_S) & FILTER_TUPLE_M) struct cpl_t5_act_open_req { WR_HDR; union opcode_tid ot; @@ -579,10 +609,16 @@ struct cpl_rx_data_ack { WR_HDR; union opcode_tid ot; __be32 credit_dack; -#define RX_CREDITS(x) ((x) << 0) -#define RX_FORCE_ACK(x) ((x) << 28) }; +/* cpl_rx_data_ack.ack_seq fields */ +#define RX_CREDITS_S 0 +#define RX_CREDITS_V(x) ((x) << RX_CREDITS_S) + +#define RX_FORCE_ACK_S 28 +#define RX_FORCE_ACK_V(x) ((x) << RX_FORCE_ACK_S) +#define RX_FORCE_ACK_F RX_FORCE_ACK_V(1U) + struct cpl_rx_pkt { struct rss_header rsshdr; u8 opcode; @@ -803,6 +839,9 @@ enum { ULP_TX_SC_ISGL = 0x83 }; +#define ULPTX_CMD_S 24 +#define ULPTX_CMD_V(x) ((x) << ULPTX_CMD_S) + struct ulptx_sge_pair { __be32 len[2]; __be64 addr[2]; @@ -810,7 +849,6 @@ struct ulptx_sge_pair { struct ulptx_sgl { __be32 cmd_nsge; -#define ULPTX_CMD(x) ((x) << 24) #define ULPTX_NSGE(x) ((x) << 0) #define ULPTX_MORE (1U << 23) __be32 len0; @@ -821,15 +859,21 @@ struct ulptx_sgl { struct ulp_mem_io { WR_HDR; __be32 cmd; -#define ULP_MEMIO_ORDER(x) ((x) << 23) __be32 len16; /* command length */ __be32 dlen; /* data length in 32-byte units */ -#define ULP_MEMIO_DATA_LEN(x) ((x) << 0) __be32 lock_addr; -#define ULP_MEMIO_ADDR(x) ((x) << 0) #define ULP_MEMIO_LOCK(x) ((x) << 31) }; +/* additional ulp_mem_io.cmd fields */ +#define ULP_MEMIO_ORDER_S 23 +#define ULP_MEMIO_ORDER_V(x) ((x) << ULP_MEMIO_ORDER_S) +#define ULP_MEMIO_ORDER_F ULP_MEMIO_ORDER_V(1U) + +#define T5_ULP_MEMIO_IMM_S 23 +#define T5_ULP_MEMIO_IMM_V(x) ((x) << T5_ULP_MEMIO_IMM_S) +#define T5_ULP_MEMIO_IMM_F T5_ULP_MEMIO_IMM_V(1U) + #define S_T5_ULP_MEMIO_IMM 23 #define V_T5_ULP_MEMIO_IMM(x) ((x) << S_T5_ULP_MEMIO_IMM) #define F_T5_ULP_MEMIO_IMM V_T5_ULP_MEMIO_IMM(1U) @@ -838,4 +882,12 @@ struct ulp_mem_io { #define V_T5_ULP_MEMIO_ORDER(x) ((x) << S_T5_ULP_MEMIO_ORDER) #define F_T5_ULP_MEMIO_ORDER V_T5_ULP_MEMIO_ORDER(1U) +/* ulp_mem_io.lock_addr fields */ +#define ULP_MEMIO_ADDR_S 0 +#define ULP_MEMIO_ADDR_V(x) ((x) << ULP_MEMIO_ADDR_S) + +/* ulp_mem_io.dlen fields */ +#define ULP_MEMIO_DATA_LEN_S 0 +#define ULP_MEMIO_DATA_LEN_V(x) ((x) << ULP_MEMIO_DATA_LEN_S) + #endif /* __T4_MSG_H */ diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 7cca67fde4f4..6fc46dc11988 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -1395,7 +1395,11 @@ struct fw_eq_ofld_cmd { * Macros for VIID parsing: * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number */ -#define FW_VIID_PFN_GET(x) (((x) >> 8) & 0x7) + +#define FW_VIID_PFN_S 8 +#define FW_VIID_PFN_M 0x7 +#define FW_VIID_PFN_G(x) (((x) >> FW_VIID_PFN_S) & FW_VIID_PFN_M) + #define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1) #define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index cd538afa40dd..aff6d37f2676 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -907,7 +907,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq, sgl->addr0 = cpu_to_be64(addr[1]); } - sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | + sgl->cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags)); if (likely(--nfrags == 0)) return; diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 48e45b1ea4e5..87f9280d9b43 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -1757,7 +1757,7 @@ csio_ln_mgmt_submit_wr(struct csio_mgmtm *mgmtm, struct csio_ioreq *io_req, csio_wr_copy_to_wrp(pld->vaddr, &wrp, wr_off, im_len); else { /* Program DSGL to dma payload */ - dsgl.cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | + dsgl.cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_MORE | ULPTX_NSGE(1)); dsgl.len0 = cpu_to_be32(pld_len); dsgl.addr0 = cpu_to_be64(pld->paddr); diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index b37c69a2772a..b9c012ba34f8 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -322,7 +322,7 @@ csio_scsi_init_ultptx_dsgl(struct csio_hw *hw, struct csio_ioreq *req, struct csio_dma_buf *dma_buf; struct scsi_cmnd *scmnd = csio_scsi_cmnd(req); - sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_MORE | + sgl->cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_MORE | ULPTX_NSGE(req->nsge)); /* Now add the data SGLs */ if (likely(!req->dcopy)) { diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index ccacf09c2c16..ed0e16866dc7 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -188,18 +188,18 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, unsigned int qid_atid = ((unsigned int)csk->atid) | (((unsigned int)csk->rss_qid) << 14); - opt0 = KEEP_ALIVE(1) | - WND_SCALE(wscale) | - MSS_IDX(csk->mss_idx) | - L2T_IDX(((struct l2t_entry *)csk->l2t)->idx) | - TX_CHAN(csk->tx_chan) | - SMAC_SEL(csk->smac_idx) | - ULP_MODE(ULP_MODE_ISCSI) | - RCV_BUFSIZ(cxgb4i_rcv_win >> 10); - opt2 = RX_CHANNEL(0) | - RSS_QUEUE_VALID | - (1 << 20) | - RSS_QUEUE(csk->rss_qid); + opt0 = KEEP_ALIVE_F | + WND_SCALE_V(wscale) | + MSS_IDX_V(csk->mss_idx) | + L2T_IDX_V(((struct l2t_entry *)csk->l2t)->idx) | + TX_CHAN_V(csk->tx_chan) | + SMAC_SEL_V(csk->smac_idx) | + ULP_MODE_V(ULP_MODE_ISCSI) | + RCV_BUFSIZ_V(cxgb4i_rcv_win >> 10); + opt2 = RX_CHANNEL_V(0) | + RSS_QUEUE_VALID_F | + (RX_FC_DISABLE_F) | + RSS_QUEUE_V(csk->rss_qid); if (is_t4(lldi->adapter_type)) { struct cpl_act_open_req *req = @@ -216,7 +216,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, req->params = cpu_to_be32(cxgb4_select_ntuple( csk->cdev->ports[csk->port_id], csk->l2t)); - opt2 |= 1 << 22; + opt2 |= RX_FC_VALID_F; req->opt2 = cpu_to_be32(opt2); log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, @@ -236,7 +236,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, req->local_ip = csk->saddr.sin_addr.s_addr; req->peer_ip = csk->daddr.sin_addr.s_addr; req->opt0 = cpu_to_be64(opt0); - req->params = cpu_to_be64(V_FILTER_TUPLE( + req->params = cpu_to_be64(FILTER_TUPLE_V( cxgb4_select_ntuple( csk->cdev->ports[csk->port_id], csk->l2t))); @@ -271,19 +271,19 @@ static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb, unsigned int qid_atid = ((unsigned int)csk->atid) | (((unsigned int)csk->rss_qid) << 14); - opt0 = KEEP_ALIVE(1) | - WND_SCALE(wscale) | - MSS_IDX(csk->mss_idx) | - L2T_IDX(((struct l2t_entry *)csk->l2t)->idx) | - TX_CHAN(csk->tx_chan) | - SMAC_SEL(csk->smac_idx) | - ULP_MODE(ULP_MODE_ISCSI) | - RCV_BUFSIZ(cxgb4i_rcv_win >> 10); + opt0 = KEEP_ALIVE_F | + WND_SCALE_V(wscale) | + MSS_IDX_V(csk->mss_idx) | + L2T_IDX_V(((struct l2t_entry *)csk->l2t)->idx) | + TX_CHAN_V(csk->tx_chan) | + SMAC_SEL_V(csk->smac_idx) | + ULP_MODE_V(ULP_MODE_ISCSI) | + RCV_BUFSIZ_V(cxgb4i_rcv_win >> 10); - opt2 = RX_CHANNEL(0) | - RSS_QUEUE_VALID | - RX_FC_DISABLE | - RSS_QUEUE(csk->rss_qid); + opt2 = RX_CHANNEL_V(0) | + RSS_QUEUE_VALID_F | + RX_FC_DISABLE_F | + RSS_QUEUE_V(csk->rss_qid); if (t4) { struct cpl_act_open_req6 *req = @@ -304,7 +304,7 @@ static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb, req->opt0 = cpu_to_be64(opt0); - opt2 |= RX_FC_VALID; + opt2 |= RX_FC_VALID_F; req->opt2 = cpu_to_be32(opt2); req->params = cpu_to_be32(cxgb4_select_ntuple( @@ -327,10 +327,10 @@ static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb, 8); req->opt0 = cpu_to_be64(opt0); - opt2 |= T5_OPT_2_VALID; + opt2 |= T5_OPT_2_VALID_F; req->opt2 = cpu_to_be32(opt2); - req->params = cpu_to_be64(V_FILTER_TUPLE(cxgb4_select_ntuple( + req->params = cpu_to_be64(FILTER_TUPLE_V(cxgb4_select_ntuple( csk->cdev->ports[csk->port_id], csk->l2t))); } @@ -451,7 +451,8 @@ static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits) INIT_TP_WR(req, csk->tid); OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK, csk->tid)); - req->credit_dack = cpu_to_be32(RX_CREDITS(credits) | RX_FORCE_ACK(1)); + req->credit_dack = cpu_to_be32(RX_CREDITS_V(credits) + | RX_FORCE_ACK_F); cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb); return credits; } @@ -1440,16 +1441,16 @@ static inline void ulp_mem_io_set_hdr(struct cxgb4_lld_info *lldi, INIT_ULPTX_WR(req, wr_len, 0, 0); if (is_t4(lldi->adapter_type)) - req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | - (ULP_MEMIO_ORDER(1))); + req->cmd = htonl(ULPTX_CMD_V(ULP_TX_MEM_WRITE) | + (ULP_MEMIO_ORDER_F)); else - req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | - (V_T5_ULP_MEMIO_IMM(1))); - req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5)); - req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5)); + req->cmd = htonl(ULPTX_CMD_V(ULP_TX_MEM_WRITE) | + (T5_ULP_MEMIO_IMM_F)); + req->dlen = htonl(ULP_MEMIO_DATA_LEN_V(dlen >> 5)); + req->lock_addr = htonl(ULP_MEMIO_ADDR_V(pm_addr >> 5)); req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16)); - idata->cmd_more = htonl(ULPTX_CMD(ULP_TX_SC_IMM)); + idata->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_IMM)); idata->len = htonl(dlen); } @@ -1673,7 +1674,8 @@ static void *t4_uld_add(const struct cxgb4_lld_info *lldi) cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr); cdev->itp = &cxgb4i_iscsi_transport; - cdev->pfvf = FW_VIID_PFN_GET(cxgb4_port_viid(lldi->ports[0])) << 8; + cdev->pfvf = FW_VIID_PFN_G(cxgb4_port_viid(lldi->ports[0])) + << FW_VIID_PFN_S; pr_info("cdev 0x%p,%s, pfvf %u.\n", cdev, lldi->ports[0]->name, cdev->pfvf); -- GitLab From b6267d3e803b9adf73893f932f7c7f3a2167c908 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Nov 2014 09:19:06 +0300 Subject: [PATCH 4682/9457] amd-xgbe: fix ->rss_hash_type There was a missing break statement so we set everything to PKT_HASH_TYPE_L3 even when we intended to use PKT_HASH_TYPE_L4. Fixes: 5b9dfe299e55 ('amd-xgbe: Provide support for receive side scaling') Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 7daa2cd9af5f..f6014d330b2e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1600,7 +1600,7 @@ static int xgbe_dev_read(struct xgbe_channel *channel) case RX_DESC3_L34T_IPV6_TCP: case RX_DESC3_L34T_IPV6_UDP: packet->rss_hash_type = PKT_HASH_TYPE_L4; - + break; default: packet->rss_hash_type = PKT_HASH_TYPE_L3; } -- GitLab From fbe168ba91f7c327856f205699404284c2f09e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= Date: Thu, 13 Nov 2014 07:54:50 +0100 Subject: [PATCH 4683/9457] net: generic dev_disable_lro() stacked device handling Large receive offloading is known to cause problems if received packets are passed to other host. Therefore the kernel disables it by calling dev_disable_lro() whenever a network device is enslaved in a bridge or forwarding is enabled for it (or globally). For virtual devices we need to disable LRO on the underlying physical device (which is actually receiving the packets). Current dev_disable_lro() code handles this propagation for a vlan (including 802.1ad nested vlan), macvlan or a vlan on top of a macvlan. It doesn't handle other stacked devices and their combinations, in particular propagation from a bond to its slaves which often causes problems in virtualization setups. As we now have generic data structures describing the upper-lower device relationship, dev_disable_lro() can be generalized to disable LRO also for all lower devices (if any) once it is disabled for the device itself. For bonding and teaming devices, it is necessary to disable LRO not only on current slaves at the moment when dev_disable_lro() is called but also on any slave (port) added later. v2: use lower device links for all devices (including vlan and macvlan) Signed-off-by: Michal Kubecek Acked-by: Veaceslav Falico Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 3 +++ drivers/net/team/team.c | 3 +++ net/core/dev.c | 15 +++++---------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b9b34566b9b8..8575fee8b359 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1526,6 +1526,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } #endif + if (!(bond_dev->features & NETIF_F_LRO)) + dev_disable_lro(slave_dev); + res = netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave); if (res) { diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 2368395d8ae5..93e224217e24 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1179,6 +1179,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_enable_netpoll; } + if (!(dev->features & NETIF_F_LRO)) + dev_disable_lro(port_dev); + err = netdev_rx_handler_register(port_dev, team_handle_frame, port); if (err) { diff --git a/net/core/dev.c b/net/core/dev.c index bb09b0364619..1ab168e0fdf7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1437,22 +1437,17 @@ EXPORT_SYMBOL(dev_close); */ void dev_disable_lro(struct net_device *dev) { - /* - * If we're trying to disable lro on a vlan device - * use the underlying physical device instead - */ - if (is_vlan_dev(dev)) - dev = vlan_dev_real_dev(dev); - - /* the same for macvlan devices */ - if (netif_is_macvlan(dev)) - dev = macvlan_dev_real_dev(dev); + struct net_device *lower_dev; + struct list_head *iter; dev->wanted_features &= ~NETIF_F_LRO; netdev_update_features(dev); if (unlikely(dev->features & NETIF_F_LRO)) netdev_WARN(dev, "failed to disable LRO!\n"); + + netdev_for_each_lower_dev(dev, lower_dev, iter) + dev_disable_lro(lower_dev); } EXPORT_SYMBOL(dev_disable_lro); -- GitLab From 966d6dbb6b3091e2046138161252a91b7171d156 Mon Sep 17 00:00:00 2001 From: Hisashi Nakamura Date: Thu, 13 Nov 2014 15:54:05 +0900 Subject: [PATCH 4684/9457] net: sh_eth: Add RMII mode setting in probe When using RMMI mode, it is necessary to change in probe. Signed-off-by: Hisashi Nakamura Signed-off-by: Yoshihiro Kaneko Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index dbe860650bfe..1f79ed61f9cd 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1,5 +1,6 @@ /* SuperH Ethernet device driver * + * Copyright (C) 2014 Renesas Electronics Corporation * Copyright (C) 2006-2012 Nobuhiro Iwamatsu * Copyright (C) 2008-2014 Renesas Solutions Corp. * Copyright (C) 2013-2014 Cogent Embedded, Inc. @@ -2883,6 +2884,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev) } } + if (mdp->cd->rmiimode) + sh_eth_write(ndev, 0x1, RMIIMODE); + /* MDIO bus init */ ret = sh_mdio_init(mdp, pd); if (ret) { -- GitLab From 9488e1e5b319751c71eebfd49027bf9e2377f38c Mon Sep 17 00:00:00 2001 From: Hisashi Nakamura Date: Thu, 13 Nov 2014 15:59:07 +0900 Subject: [PATCH 4685/9457] net: sh_eth: Add r8a7793 support The device tree probing for R-Car M2N (r8a7793) is added. Signed-off-by: Hisashi Nakamura Signed-off-by: Yoshihiro Kaneko Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/sh_eth.txt | 1 + drivers/net/ethernet/renesas/sh_eth.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/net/sh_eth.txt b/Documentation/devicetree/bindings/net/sh_eth.txt index 34d4db1a4e25..2f6ec85fda8e 100644 --- a/Documentation/devicetree/bindings/net/sh_eth.txt +++ b/Documentation/devicetree/bindings/net/sh_eth.txt @@ -9,6 +9,7 @@ Required properties: "renesas,ether-r8a7779" if the device is a part of R8A7779 SoC. "renesas,ether-r8a7790" if the device is a part of R8A7790 SoC. "renesas,ether-r8a7791" if the device is a part of R8A7791 SoC. + "renesas,ether-r8a7793" if the device is a part of R8A7793 SoC. "renesas,ether-r8a7794" if the device is a part of R8A7794 SoC. "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC. - reg: offset and length of (1) the E-DMAC/feLic register block (required), diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 1f79ed61f9cd..71f59ee51304 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2747,6 +2747,7 @@ static const struct of_device_id sh_eth_match_table[] = { { .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data }, { .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data }, { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data }, + { .compatible = "renesas,ether-r8a7793", .data = &r8a779x_data }, { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data }, { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data }, { } @@ -2973,6 +2974,7 @@ static struct platform_device_id sh_eth_id_table[] = { { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data }, { "r8a7790-ether", (kernel_ulong_t)&r8a779x_data }, { "r8a7791-ether", (kernel_ulong_t)&r8a779x_data }, + { "r8a7793-ether", (kernel_ulong_t)&r8a779x_data }, { "r8a7794-ether", (kernel_ulong_t)&r8a779x_data }, { } }; -- GitLab From 971275662040beef8f73f8e5dbcfb3d76a14bf04 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 13 Nov 2014 18:11:18 +0800 Subject: [PATCH 4686/9457] netlink: Move mutex_is_held under PROVE_LOCKING The rhashtable function mutex_is_held is only used when PROVE_LOCKING is enabled. This patch modifies netlink so that we can rhashtable.h itself can later make mutex_is_held optional depending on PROVE_LOCKING. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 580b79452bec..53b8ea793191 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -114,14 +114,14 @@ static atomic_t nl_table_users = ATOMIC_INIT(0); DEFINE_MUTEX(nl_sk_hash_lock); EXPORT_SYMBOL_GPL(nl_sk_hash_lock); +#ifdef CONFIG_PROVE_LOCKING static int lockdep_nl_sk_hash_is_held(void) { -#ifdef CONFIG_LOCKDEP if (debug_locks) return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock); -#endif return 1; } +#endif static ATOMIC_NOTIFIER_HEAD(netlink_chain); @@ -3133,7 +3133,9 @@ static int __init netlink_proto_init(void) .max_shift = 16, /* 64K */ .grow_decision = rht_grow_above_75, .shrink_decision = rht_shrink_below_30, +#ifdef CONFIG_PROVE_LOCKING .mutex_is_held = lockdep_nl_sk_hash_is_held, +#endif }; if (err != 0) -- GitLab From 1f501d62523f0d5fd152006e16938ee674932c1b Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 13 Nov 2014 18:11:19 +0800 Subject: [PATCH 4687/9457] netfilter: Move mutex_is_held under PROVE_LOCKING The rhashtable function mutex_is_held is only used when PROVE_LOCKING is enabled. This patch modifies netfilter so that we can rhashtable.h itself can later make mutex_is_held optional depending on PROVE_LOCKING. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/netfilter/nft_hash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 8892b7b6184a..b86305c86048 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -153,10 +153,12 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) return sizeof(struct rhashtable); } +#ifdef CONFIG_PROVE_LOCKING static int lockdep_nfnl_lock_is_held(void) { return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES); } +#endif static int nft_hash_init(const struct nft_set *set, const struct nft_set_desc *desc, @@ -171,7 +173,9 @@ static int nft_hash_init(const struct nft_set *set, .hashfn = jhash, .grow_decision = rht_grow_above_75, .shrink_decision = rht_shrink_below_30, +#ifdef CONFIG_PROVE_LOCKING .mutex_is_held = lockdep_nfnl_lock_is_held, +#endif }; return rhashtable_init(priv, ¶ms); -- GitLab From 1b2f309d70daf04b6a97b3753e375654532f6207 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 13 Nov 2014 18:11:20 +0800 Subject: [PATCH 4688/9457] rhashtable: Move mutex_is_held under PROVE_LOCKING The rhashtable function mutex_is_held is only used when PROVE_LOCKING is enabled. This patch makes the mutex_is_held field in rhashtable optional depending on PROVE_LOCKING. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/rhashtable.h | 2 ++ lib/rhashtable.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index fb298e9d6d3a..96ce8ceff554 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -65,7 +65,9 @@ struct rhashtable_params { size_t new_size); bool (*shrink_decision)(const struct rhashtable *ht, size_t new_size); +#ifdef CONFIG_PROVE_LOCKING int (*mutex_is_held)(void); +#endif }; /** diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 081be3ba9ea8..c7654b6f5f64 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -532,7 +532,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params) * .key_offset = offsetof(struct test_obj, key), * .key_len = sizeof(int), * .hashfn = arch_fast_hash, + * #ifdef CONFIG_PROVE_LOCKING * .mutex_is_held = &my_mutex_is_held, + * #endif * }; * * Configuration Example 2: Variable length keys @@ -552,7 +554,9 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params) * .head_offset = offsetof(struct test_obj, node), * .hashfn = arch_fast_hash, * .obj_hashfn = my_hash_fn, + * #ifdef CONFIG_PROVE_LOCKING * .mutex_is_held = &my_mutex_is_held, + * #endif * }; */ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) @@ -613,10 +617,12 @@ EXPORT_SYMBOL_GPL(rhashtable_destroy); #define TEST_PTR ((void *) 0xdeadbeef) #define TEST_NEXPANDS 4 +#ifdef CONFIG_PROVE_LOCKING static int test_mutex_is_held(void) { return 1; } +#endif struct test_obj { void *ptr; @@ -767,7 +773,9 @@ static int __init test_rht_init(void) .key_offset = offsetof(struct test_obj, value), .key_len = sizeof(int), .hashfn = arch_fast_hash, +#ifdef CONFIG_PROVE_LOCKING .mutex_is_held = &test_mutex_is_held, +#endif .grow_decision = rht_grow_above_75, .shrink_decision = rht_shrink_below_30, }; -- GitLab From 7b4ce2353467fdab6e003be7a3129fb09b09deac Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 13 Nov 2014 18:11:22 +0800 Subject: [PATCH 4689/9457] rhashtable: Add parent argument to mutex_is_held Currently mutex_is_held can only test locks in the that are global since it takes no arguments. This prevents rhashtable from being used in places where locks are lock, e.g., per-namespace locks. This patch adds a parent field to mutex_is_held and rhashtable_params so that local locks can be used (and tested). Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/rhashtable.h | 3 ++- lib/rhashtable.c | 4 ++-- net/netfilter/nft_hash.c | 2 +- net/netlink/af_netlink.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 96ce8ceff554..473e26bdb91d 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -66,7 +66,8 @@ struct rhashtable_params { bool (*shrink_decision)(const struct rhashtable *ht, size_t new_size); #ifdef CONFIG_PROVE_LOCKING - int (*mutex_is_held)(void); + int (*mutex_is_held)(void *parent); + void *parent; #endif }; diff --git a/lib/rhashtable.c b/lib/rhashtable.c index c7654b6f5f64..4b4b53bfa08b 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -32,7 +32,7 @@ #ifdef CONFIG_PROVE_LOCKING int lockdep_rht_mutex_is_held(const struct rhashtable *ht) { - return ht->p.mutex_is_held(); + return ht->p.mutex_is_held(ht->p.parent); } EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held); #endif @@ -618,7 +618,7 @@ EXPORT_SYMBOL_GPL(rhashtable_destroy); #define TEST_NEXPANDS 4 #ifdef CONFIG_PROVE_LOCKING -static int test_mutex_is_held(void) +static int test_mutex_is_held(void *parent) { return 1; } diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index b86305c86048..3f75aaaf9d06 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -154,7 +154,7 @@ static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) } #ifdef CONFIG_PROVE_LOCKING -static int lockdep_nfnl_lock_is_held(void) +static int lockdep_nfnl_lock_is_held(void *parent) { return lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES); } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 53b8ea793191..9e0628cfdf67 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -115,7 +115,7 @@ DEFINE_MUTEX(nl_sk_hash_lock); EXPORT_SYMBOL_GPL(nl_sk_hash_lock); #ifdef CONFIG_PROVE_LOCKING -static int lockdep_nl_sk_hash_is_held(void) +static int lockdep_nl_sk_hash_is_held(void *parent) { if (debug_locks) return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock); -- GitLab From 7c68dd435b3ea128550c3eed62cd3cb405431374 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:27 +0200 Subject: [PATCH 4690/9457] net/mlx4_core: Fix wrong reading of reserved_eqs We mistakenly read the reserved_eqs field as a standard numeric value rather than a log2 value. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index d6dba77ae4ba..9051b36cdad6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -611,7 +611,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MPT_OFFSET); dev_cap->max_mpts = 1 << (field & 0x3f); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); - dev_cap->reserved_eqs = field & 0xf; + dev_cap->reserved_eqs = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); dev_cap->max_eqs = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); -- GitLab From 225c6c8c6bbbc32455df3d1c0fb1e1e1fb51c533 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:28 +0200 Subject: [PATCH 4691/9457] net/mlx4_core: Use correct variable type for mlx4_slave_cap We've used an incorrect type for the loop counter and the mlx4_QUERY_FUNC_CAP function. The current input modifier is either a port or a boolean. Since the number of ports is always a positive value < 255, we should use u8 instead of an integer with casting. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +- drivers/net/ethernet/mellanox/mlx4/fw.h | 2 +- drivers/net/ethernet/mellanox/mlx4/main.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9051b36cdad6..f1a6718968fe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -335,7 +335,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, return err; } -int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, +int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, struct mlx4_func_cap *func_cap) { struct mlx4_cmd_mailbox *mailbox; diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 9b835aecac96..694557e5f4fb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -204,7 +204,7 @@ struct mlx4_set_ib_param { }; int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap); -int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u32 gen_or_port, +int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, struct mlx4_func_cap *func_cap); int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 2f6ba420ac03..71f1f3be4ebe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -631,7 +631,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) struct mlx4_dev_cap dev_cap; struct mlx4_func_cap func_cap; struct mlx4_init_hca_param hca_param; - int i; + u8 i; memset(&hca_param, 0, sizeof(hca_param)); err = mlx4_QUERY_HCA(dev, &hca_param); @@ -732,7 +732,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) } for (i = 1; i <= dev->caps.num_ports; ++i) { - err = mlx4_QUERY_FUNC_CAP(dev, (u32) i, &func_cap); + err = mlx4_QUERY_FUNC_CAP(dev, i, &func_cap); if (err) { mlx4_err(dev, "QUERY_FUNC_CAP port command failed for port %d, aborting (%d)\n", i, err); -- GitLab From ffc39f6d6fff2878c55ffa5ffb1828d7618c0a29 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:29 +0200 Subject: [PATCH 4692/9457] net/mlx4_core: Refactor mlx4_cmd_init and mlx4_cmd_cleanup Refactoring mlx4_cmd_init and mlx4_cmd_cleanup such that partial init and cleanup are possible. After this refactoring, calling mlx4_cmd_init several times is safe. This is necessary in the VF init flow when mlx4_init_hca returns -EACCESS, we need to issue cleanup and re-attempt to call it with the slave flag. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 76 +++++++++++++---------- drivers/net/ethernet/mellanox/mlx4/main.c | 6 +- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 11 +++- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 3c05e5878b49..5c93d1451c44 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -2117,50 +2117,52 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) int mlx4_cmd_init(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); + int flags = 0; + + if (!priv->cmd.initialized) { + mutex_init(&priv->cmd.hcr_mutex); + mutex_init(&priv->cmd.slave_cmd_mutex); + sema_init(&priv->cmd.poll_sem, 1); + priv->cmd.use_events = 0; + priv->cmd.toggle = 1; + priv->cmd.initialized = 1; + flags |= MLX4_CMD_CLEANUP_STRUCT; + } - mutex_init(&priv->cmd.hcr_mutex); - mutex_init(&priv->cmd.slave_cmd_mutex); - sema_init(&priv->cmd.poll_sem, 1); - priv->cmd.use_events = 0; - priv->cmd.toggle = 1; - - priv->cmd.hcr = NULL; - priv->mfunc.vhcr = NULL; - - if (!mlx4_is_slave(dev)) { + if (!mlx4_is_slave(dev) && !priv->cmd.hcr) { priv->cmd.hcr = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_HCR_BASE, MLX4_HCR_SIZE); if (!priv->cmd.hcr) { mlx4_err(dev, "Couldn't map command register\n"); - return -ENOMEM; + goto err; } + flags |= MLX4_CMD_CLEANUP_HCR; } - if (mlx4_is_mfunc(dev)) { + if (mlx4_is_mfunc(dev) && !priv->mfunc.vhcr) { priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE, &priv->mfunc.vhcr_dma, GFP_KERNEL); if (!priv->mfunc.vhcr) - goto err_hcr; + goto err; + + flags |= MLX4_CMD_CLEANUP_VHCR; } - priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev, - MLX4_MAILBOX_SIZE, - MLX4_MAILBOX_SIZE, 0); - if (!priv->cmd.pool) - goto err_vhcr; + if (!priv->cmd.pool) { + priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev, + MLX4_MAILBOX_SIZE, + MLX4_MAILBOX_SIZE, 0); + if (!priv->cmd.pool) + goto err; - return 0; + flags |= MLX4_CMD_CLEANUP_POOL; + } -err_vhcr: - if (mlx4_is_mfunc(dev)) - dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, - priv->mfunc.vhcr, priv->mfunc.vhcr_dma); - priv->mfunc.vhcr = NULL; + return 0; -err_hcr: - if (!mlx4_is_slave(dev)) - iounmap(priv->cmd.hcr); +err: + mlx4_cmd_cleanup(dev, flags); return -ENOMEM; } @@ -2184,18 +2186,28 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev) iounmap(priv->mfunc.comm); } -void mlx4_cmd_cleanup(struct mlx4_dev *dev) +void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask) { struct mlx4_priv *priv = mlx4_priv(dev); - pci_pool_destroy(priv->cmd.pool); + if (priv->cmd.pool && (cleanup_mask & MLX4_CMD_CLEANUP_POOL)) { + pci_pool_destroy(priv->cmd.pool); + priv->cmd.pool = NULL; + } - if (!mlx4_is_slave(dev)) + if (!mlx4_is_slave(dev) && priv->cmd.hcr && + (cleanup_mask & MLX4_CMD_CLEANUP_HCR)) { iounmap(priv->cmd.hcr); - if (mlx4_is_mfunc(dev)) + priv->cmd.hcr = NULL; + } + if (mlx4_is_mfunc(dev) && priv->mfunc.vhcr && + (cleanup_mask & MLX4_CMD_CLEANUP_VHCR)) { dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, priv->mfunc.vhcr, priv->mfunc.vhcr_dma); - priv->mfunc.vhcr = NULL; + priv->mfunc.vhcr = NULL; + } + if (priv->cmd.initialized && (cleanup_mask & MLX4_CMD_CLEANUP_STRUCT)) + priv->cmd.initialized = 0; } /* diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 71f1f3be4ebe..b2732eb82bf1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2396,7 +2396,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, if (err == -EACCES) { /* Not primary Physical function * Running in slave mode */ - mlx4_cmd_cleanup(dev); + mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); dev->flags |= MLX4_FLAG_SLAVE; dev->flags &= ~MLX4_FLAG_MASTER; goto slave_start; @@ -2561,7 +2561,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, mlx4_multi_func_cleanup(dev); err_cmd: - mlx4_cmd_cleanup(dev); + mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); err_sriov: if (dev->flags & MLX4_FLAG_SRIOV && !existing_vfs) @@ -2805,7 +2805,7 @@ static void mlx4_unload_one(struct pci_dev *pdev) mlx4_close_hca(dev); if (mlx4_is_slave(dev)) mlx4_multi_func_cleanup(dev); - mlx4_cmd_cleanup(dev); + mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); if (dev->flags & MLX4_FLAG_MSI_X) pci_disable_msix(pdev); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index f8fc7bd6f48b..f48e7c3eecf8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -606,6 +606,7 @@ struct mlx4_cmd { u8 use_events; u8 toggle; u8 comm_toggle; + u8 initialized; }; enum { @@ -1126,8 +1127,16 @@ int mlx4_QUERY_QP_wrapper(struct mlx4_dev *dev, int slave, int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe); +enum { + MLX4_CMD_CLEANUP_STRUCT = 1UL << 0, + MLX4_CMD_CLEANUP_POOL = 1UL << 1, + MLX4_CMD_CLEANUP_HCR = 1UL << 2, + MLX4_CMD_CLEANUP_VHCR = 1UL << 3, + MLX4_CMD_CLEANUP_ALL = (MLX4_CMD_CLEANUP_VHCR << 1) - 1 +}; + int mlx4_cmd_init(struct mlx4_dev *dev); -void mlx4_cmd_cleanup(struct mlx4_dev *dev); +void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask); int mlx4_multi_func_init(struct mlx4_dev *dev); void mlx4_multi_func_cleanup(struct mlx4_dev *dev); void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param); -- GitLab From a0eacca948d2d4531a393d82a736ff19b7b8fa0b Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:30 +0200 Subject: [PATCH 4693/9457] net/mlx4_core: Refactor mlx4_load_one Refactor mlx4_load_one, as a preparation step for a new and more complicated load function. The goal is to support both newer firmware that required init_hca to be done before enable_sriov and legacy firmwares that requires things to be done the other way around. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 141 +++++++++++++++------- 1 file changed, 99 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index b2732eb82bf1..43047b2a2aac 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1473,6 +1473,12 @@ static void mlx4_close_hca(struct mlx4_dev *dev) else { mlx4_CLOSE_HCA(dev, 0); mlx4_free_icms(dev); + } +} + +static void mlx4_close_fw(struct mlx4_dev *dev) +{ + if (!mlx4_is_slave(dev)) { mlx4_UNMAP_FA(dev); mlx4_free_icm(dev, mlx4_priv(dev)->fw.fw_icm, 0); } @@ -1619,17 +1625,10 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) ? "vxlan" : "none"); } -static int mlx4_init_hca(struct mlx4_dev *dev) +static int mlx4_init_fw(struct mlx4_dev *dev) { - struct mlx4_priv *priv = mlx4_priv(dev); - struct mlx4_adapter adapter; - struct mlx4_dev_cap dev_cap; struct mlx4_mod_stat_cfg mlx4_cfg; - struct mlx4_profile profile; - struct mlx4_init_hca_param init_hca; - u64 icm_size; - int err; - struct mlx4_config_dev_params params; + int err = 0; if (!mlx4_is_slave(dev)) { err = mlx4_QUERY_FW(dev); @@ -1652,7 +1651,23 @@ static int mlx4_init_hca(struct mlx4_dev *dev) err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg); if (err) mlx4_warn(dev, "Failed to override log_pg_sz parameter\n"); + } + + return err; +} + +static int mlx4_init_hca(struct mlx4_dev *dev) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_adapter adapter; + struct mlx4_dev_cap dev_cap; + struct mlx4_profile profile; + struct mlx4_init_hca_param init_hca; + u64 icm_size; + struct mlx4_config_dev_params params; + int err; + if (!mlx4_is_slave(dev)) { err = mlx4_dev_cap(dev, &dev_cap); if (err) { mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); @@ -2275,6 +2290,53 @@ static void mlx4_free_ownership(struct mlx4_dev *dev) iounmap(owner); } +#define SRIOV_VALID_STATE(flags) (!!((flags) & MLX4_FLAG_SRIOV) ==\ + !!((flags) & MLX4_FLAG_MASTER)) + +static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, + u8 total_vfs, int existing_vfs) +{ + u64 dev_flags = dev->flags; + + dev->dev_vfs = kzalloc( + total_vfs * sizeof(*dev->dev_vfs), + GFP_KERNEL); + if (NULL == dev->dev_vfs) { + mlx4_err(dev, "Failed to allocate memory for VFs\n"); + goto disable_sriov; + } else if (!(dev->flags & MLX4_FLAG_SRIOV)) { + int err = 0; + + atomic_inc(&pf_loading); + if (existing_vfs) { + if (existing_vfs != total_vfs) + mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n", + existing_vfs, total_vfs); + } else { + mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs); + err = pci_enable_sriov(pdev, total_vfs); + } + if (err) { + mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n", + err); + atomic_dec(&pf_loading); + goto disable_sriov; + } else { + mlx4_warn(dev, "Running in master mode\n"); + dev_flags |= MLX4_FLAG_SRIOV | + MLX4_FLAG_MASTER; + dev_flags &= ~MLX4_FLAG_SLAVE; + dev->num_vfs = total_vfs; + } + } + return dev_flags; + +disable_sriov: + dev->num_vfs = 0; + kfree(dev->dev_vfs); + return dev_flags & ~MLX4_FLAG_MASTER; +} + static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, int total_vfs, int *nvfs, struct mlx4_priv *priv) { @@ -2320,37 +2382,12 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, } if (total_vfs) { - mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", - total_vfs); - dev->dev_vfs = kzalloc( - total_vfs * sizeof(*dev->dev_vfs), - GFP_KERNEL); - if (NULL == dev->dev_vfs) { - mlx4_err(dev, "Failed to allocate memory for VFs\n"); - err = -ENOMEM; - goto err_free_own; - } else { - atomic_inc(&pf_loading); - existing_vfs = pci_num_vf(pdev); - if (existing_vfs) { - err = 0; - if (existing_vfs != total_vfs) - mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n", - existing_vfs, total_vfs); - } else { - err = pci_enable_sriov(pdev, total_vfs); - } - if (err) { - mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n", - err); - atomic_dec(&pf_loading); - } else { - mlx4_warn(dev, "Running in master mode\n"); - dev->flags |= MLX4_FLAG_SRIOV | - MLX4_FLAG_MASTER; - dev->num_vfs = total_vfs; - } - } + existing_vfs = pci_num_vf(pdev); + dev->flags = MLX4_FLAG_MASTER; + dev->flags = mlx4_enable_sriov(dev, pdev, total_vfs, + existing_vfs); + if (!SRIOV_VALID_STATE(dev->flags)) + goto err_sriov; } atomic_set(&priv->opreq_count, 0); @@ -2391,17 +2428,33 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, } } + err = mlx4_init_fw(dev); + if (err) { + mlx4_err(dev, "Failed to init fw, aborting.\n"); + goto err_mfunc; + } + err = mlx4_init_hca(dev); if (err) { if (err == -EACCES) { /* Not primary Physical function * Running in slave mode */ mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); + /* We're not a PF */ + if (dev->flags & MLX4_FLAG_SRIOV) { + if (!existing_vfs) + pci_disable_sriov(pdev); + if (mlx4_is_master(dev)) + atomic_dec(&pf_loading); + dev->flags &= ~MLX4_FLAG_SRIOV; + } + if (!mlx4_is_slave(dev)) + mlx4_free_ownership(dev); dev->flags |= MLX4_FLAG_SLAVE; dev->flags &= ~MLX4_FLAG_MASTER; goto slave_start; } else - goto err_mfunc; + goto err_fw; } /* check if the device is functioning at its maximum possible speed. @@ -2556,6 +2609,9 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, err_close: mlx4_close_hca(dev); +err_fw: + mlx4_close_fw(dev); + err_mfunc: if (mlx4_is_slave(dev)) mlx4_multi_func_cleanup(dev); @@ -2572,7 +2628,6 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, kfree(priv->dev.dev_vfs); -err_free_own: if (!mlx4_is_slave(dev)) mlx4_free_ownership(dev); @@ -2803,6 +2858,7 @@ static void mlx4_unload_one(struct pci_dev *pdev) if (mlx4_is_master(dev)) mlx4_multi_func_cleanup(dev); mlx4_close_hca(dev); + mlx4_close_fw(dev); if (mlx4_is_slave(dev)) mlx4_multi_func_cleanup(dev); mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); @@ -2812,6 +2868,7 @@ static void mlx4_unload_one(struct pci_dev *pdev) if (dev->flags & MLX4_FLAG_SRIOV && !active_vfs) { mlx4_warn(dev, "Disabling SR-IOV\n"); pci_disable_sriov(pdev); + dev->flags &= ~MLX4_FLAG_SRIOV; dev->num_vfs = 0; } -- GitLab From e8c4265bea8437f5583d0c2f272058200ebc10ff Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:31 +0200 Subject: [PATCH 4694/9457] net/mlx4_core: Add QUERY_FUNC firmware command QUERY_FUNC firmware command could be used in order to query the number of EQs, reserved EQs, etc for a specific function. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 56 +++++++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/fw.h | 11 +++++ 2 files changed, 67 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index f1a6718968fe..b3bbeb97da14 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -177,6 +177,62 @@ int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg) return err; } +int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave) +{ + struct mlx4_cmd_mailbox *mailbox; + u32 *outbox; + u8 in_modifier; + u8 field; + u16 field16; + int err; + +#define QUERY_FUNC_BUS_OFFSET 0x00 +#define QUERY_FUNC_DEVICE_OFFSET 0x01 +#define QUERY_FUNC_FUNCTION_OFFSET 0x01 +#define QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET 0x03 +#define QUERY_FUNC_RSVD_EQS_OFFSET 0x04 +#define QUERY_FUNC_MAX_EQ_OFFSET 0x06 +#define QUERY_FUNC_RSVD_UARS_OFFSET 0x0b + + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + outbox = mailbox->buf; + + in_modifier = slave; + mlx4_dbg(dev, "%s for VF %d\n", __func__, in_modifier); + + err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, + MLX4_CMD_QUERY_FUNC, + MLX4_CMD_TIME_CLASS_A, + MLX4_CMD_NATIVE); + if (err) + goto out; + + MLX4_GET(field, outbox, QUERY_FUNC_BUS_OFFSET); + func->bus = field & 0xf; + MLX4_GET(field, outbox, QUERY_FUNC_DEVICE_OFFSET); + func->device = field & 0xf1; + MLX4_GET(field, outbox, QUERY_FUNC_FUNCTION_OFFSET); + func->function = field & 0x7; + MLX4_GET(field, outbox, QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET); + func->physical_function = field & 0xf; + MLX4_GET(field16, outbox, QUERY_FUNC_RSVD_EQS_OFFSET); + func->rsvd_eqs = field16 & 0xffff; + MLX4_GET(field16, outbox, QUERY_FUNC_MAX_EQ_OFFSET); + func->max_eq = field16 & 0xffff; + MLX4_GET(field, outbox, QUERY_FUNC_RSVD_UARS_OFFSET); + func->rsvd_uars = field & 0x0f; + + mlx4_dbg(dev, "Bus: %d, Device: %d, Function: %d, Physical function: %d, Max EQs: %d, Reserved EQs: %d, Reserved UARs: %d\n", + func->bus, func->device, func->function, func->physical_function, + func->max_eq, func->rsvd_eqs, func->rsvd_uars); + +out: + mlx4_free_cmd_mailbox(dev, mailbox); + return err; +} + int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 694557e5f4fb..48c11b5e73e7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -145,6 +145,16 @@ struct mlx4_func_cap { u64 phys_port_id; }; +struct mlx4_func { + int bus; + int device; + int function; + int physical_function; + int rsvd_eqs; + int max_eq; + int rsvd_uars; +}; + struct mlx4_adapter { char board_id[MLX4_BOARD_ID_LEN]; u8 inta_pin; @@ -211,6 +221,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *outbox, struct mlx4_cmd_info *cmd); +int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave); int mlx4_MAP_FA(struct mlx4_dev *dev, struct mlx4_icm *icm); int mlx4_UNMAP_FA(struct mlx4_dev *dev); int mlx4_RUN_FW(struct mlx4_dev *dev); -- GitLab From 7ae0e400cd9396c41fe596d35dcc34feaa89a04f Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:32 +0200 Subject: [PATCH 4695/9457] net/mlx4_core: Flexible (asymmetric) allocation of EQs and MSI-X vectors for PF/VFs Previously, the driver queried the firmware in order to get the number of supported EQs. Under SRIOV, since this was done before the driver notified the firmware how many VFs it actually needs, the firmware had to take into account a worst case scenario and always allocated four EQs per VF, where one was used for events while the others were used for completions. Now, when the firmware supports the asymmetric allocation scheme, denoted by exposing num_sys_eqs > 0 (--> MLX4_DEV_CAP_FLAG2_SYS_EQS), we use the QUERY_FUNC command to query the firmware before enabling SRIOV. Thus we can get more EQs and MSI-X vectors per function. Moreover, when running in the new firmware/driver mode, the limitation that the number of EQs should be a power of two is lifted. Signed-off-by: Jack Morgenstein Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx4/main.c | 3 +- drivers/net/ethernet/mellanox/mlx4/eq.c | 8 +- drivers/net/ethernet/mellanox/mlx4/fw.c | 52 +++++-- drivers/net/ethernet/mellanox/mlx4/fw.h | 2 + drivers/net/ethernet/mellanox/mlx4/main.c | 144 ++++++++++++++++--- drivers/net/ethernet/mellanox/mlx4/profile.c | 19 ++- include/linux/mlx4/device.h | 4 +- 7 files changed, 190 insertions(+), 42 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 8b72cf392b34..0c3375524a64 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1975,8 +1975,7 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) dev->caps.num_ports > dev->caps.comp_pool) return; - eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ - dev->caps.num_ports); + eq_per_port = dev->caps.comp_pool / dev->caps.num_ports; /* Init eq table */ added_eqs = 0; diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 49290a405903..d68b264cee4d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -1123,8 +1123,12 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) goto err_out_free; } - err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs, - dev->caps.num_eqs - 1, dev->caps.reserved_eqs, 0); + err = mlx4_bitmap_init(&priv->eq_table.bitmap, + roundup_pow_of_two(dev->caps.num_eqs), + dev->caps.num_eqs - 1, + dev->caps.reserved_eqs, + roundup_pow_of_two(dev->caps.num_eqs) - + dev->caps.num_eqs); if (err) goto err_out_free; diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index b3bbeb97da14..d2f594fadfbf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -142,7 +142,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [13] = "Large cache line (>64B) EQE stride support", [14] = "Ethernet protocol control support", [15] = "Ethernet Backplane autoneg support", - [16] = "CONFIG DEV support" + [16] = "CONFIG DEV support", + [17] = "Asymmetric EQs support" }; int i; @@ -200,7 +201,6 @@ int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave) outbox = mailbox->buf; in_modifier = slave; - mlx4_dbg(dev, "%s for VF %d\n", __func__, in_modifier); err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, MLX4_CMD_QUERY_FUNC, @@ -243,6 +243,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, u8 field, port; u32 size, proxy_qp, qkey; int err = 0; + struct mlx4_func func; #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 @@ -287,6 +288,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, #define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 +#define QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS (1 << 31) if (vhcr->op_modifier == 1) { struct mlx4_active_ports actv_ports = @@ -365,11 +367,24 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, size = dev->caps.num_cqs; MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); - size = dev->caps.num_eqs; - MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); - - size = dev->caps.reserved_eqs; - MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); + if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) || + mlx4_QUERY_FUNC(dev, &func, slave)) { + size = vhcr->in_modifier & + QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? + dev->caps.num_eqs : + rounddown_pow_of_two(dev->caps.num_eqs); + MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); + size = dev->caps.reserved_eqs; + MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); + } else { + size = vhcr->in_modifier & + QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? + func.max_eq : + rounddown_pow_of_two(func.max_eq); + MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); + size = func.rsvd_eqs; + MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); + } size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); @@ -399,14 +414,17 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, u8 field, op_modifier; u32 size, qkey; int err = 0, quotas = 0; + u32 in_modifier; op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ + in_modifier = op_modifier ? gen_or_port : + QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS; mailbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); - err = mlx4_cmd_box(dev, 0, mailbox->dma, gen_or_port, op_modifier, + err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, op_modifier, MLX4_CMD_QUERY_FUNC_CAP, MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); if (err) @@ -578,6 +596,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET 0x21 #define QUERY_DEV_CAP_RSVD_MRW_OFFSET 0x22 #define QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET 0x23 +#define QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET 0x26 #define QUERY_DEV_CAP_MAX_AV_OFFSET 0x27 #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b @@ -678,6 +697,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->reserved_mrws = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET); dev_cap->max_mtt_seg = 1 << (field & 0x3f); + MLX4_GET(size, outbox, QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET); + dev_cap->num_sys_eqs = size & 0xfff; MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET); dev_cap->max_requester_per_qp = 1 << (field & 0x3f); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RES_QP_OFFSET); @@ -905,8 +926,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) * we can't use any EQs whose doorbell falls on that page, * even if the EQ itself isn't reserved. */ - dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, - dev_cap->reserved_eqs); + if (dev_cap->num_sys_eqs == 0) + dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, + dev_cap->reserved_eqs); + else + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS; mlx4_dbg(dev, "Max ICM size %lld MB\n", (unsigned long long) dev_cap->max_icm_sz >> 20); @@ -916,8 +940,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->max_srqs, dev_cap->reserved_srqs, dev_cap->srq_entry_sz); mlx4_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", dev_cap->max_cqs, dev_cap->reserved_cqs, dev_cap->cqc_entry_sz); - mlx4_dbg(dev, "Max EQs: %d, reserved EQs: %d, entry size: %d\n", - dev_cap->max_eqs, dev_cap->reserved_eqs, dev_cap->eqc_entry_sz); + mlx4_dbg(dev, "Num sys EQs: %d, max EQs: %d, reserved EQs: %d, entry size: %d\n", + dev_cap->num_sys_eqs, dev_cap->max_eqs, dev_cap->reserved_eqs, + dev_cap->eqc_entry_sz); mlx4_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", dev_cap->reserved_mrws, dev_cap->reserved_mtts); mlx4_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", @@ -1463,6 +1488,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) #define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) #define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) #define INIT_HCA_LOG_EQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x67) +#define INIT_HCA_NUM_SYS_EQS_OFFSET (INIT_HCA_QPC_OFFSET + 0x6a) #define INIT_HCA_RDMARC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x70) #define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) #define INIT_HCA_MCAST_OFFSET 0x0c0 @@ -1566,6 +1592,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) MLX4_PUT(inbox, param->auxc_base, INIT_HCA_AUXC_BASE_OFFSET); MLX4_PUT(inbox, param->eqc_base, INIT_HCA_EQC_BASE_OFFSET); MLX4_PUT(inbox, param->log_num_eqs, INIT_HCA_LOG_EQ_OFFSET); + MLX4_PUT(inbox, param->num_sys_eqs, INIT_HCA_NUM_SYS_EQS_OFFSET); MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); @@ -1676,6 +1703,7 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); + MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 48c11b5e73e7..475215ee370f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -56,6 +56,7 @@ struct mlx4_dev_cap { int max_mpts; int reserved_eqs; int max_eqs; + int num_sys_eqs; int reserved_mtts; int max_mrw_sz; int reserved_mrws; @@ -180,6 +181,7 @@ struct mlx4_init_hca_param { u8 log_num_srqs; u8 log_num_cqs; u8 log_num_eqs; + u16 num_sys_eqs; u8 log_rd_per_qp; u8 log_mc_table_sz; u8 log_mpt_sz; diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 43047b2a2aac..ebb279060a25 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -197,6 +197,29 @@ static void mlx4_set_port_mask(struct mlx4_dev *dev) dev->caps.port_mask[i] = dev->caps.port_type[i]; } +enum { + MLX4_QUERY_FUNC_NUM_SYS_EQS = 1 << 0, +}; + +static int mlx4_query_func(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) +{ + int err = 0; + struct mlx4_func func; + + if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { + err = mlx4_QUERY_FUNC(dev, &func, 0); + if (err) { + mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); + return err; + } + dev_cap->max_eqs = func.max_eq; + dev_cap->reserved_eqs = func.rsvd_eqs; + dev_cap->reserved_uars = func.rsvd_uars; + err |= MLX4_QUERY_FUNC_NUM_SYS_EQS; + } + return err; +} + static void mlx4_enable_cqe_eqe_stride(struct mlx4_dev *dev) { struct mlx4_caps *dev_cap = &dev->caps; @@ -261,7 +284,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) } dev->caps.num_ports = dev_cap->num_ports; - dev->phys_caps.num_phys_eqs = MLX4_MAX_EQ_NUM; + dev->caps.num_sys_eqs = dev_cap->num_sys_eqs; + dev->phys_caps.num_phys_eqs = dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS ? + dev->caps.num_sys_eqs : + MLX4_MAX_EQ_NUM; for (i = 1; i <= dev->caps.num_ports; ++i) { dev->caps.vl_cap[i] = dev_cap->max_vl[i]; dev->caps.ib_mtu_cap[i] = dev_cap->ib_mtu[i]; @@ -1130,8 +1156,7 @@ static int mlx4_init_cmpt_table(struct mlx4_dev *dev, u64 cmpt_base, if (err) goto err_srq; - num_eqs = (mlx4_is_master(dev)) ? dev->phys_caps.num_phys_eqs : - dev->caps.num_eqs; + num_eqs = dev->phys_caps.num_phys_eqs; err = mlx4_init_icm_table(dev, &priv->eq_table.cmpt_table, cmpt_base + ((u64) (MLX4_CMPT_TYPE_EQ * @@ -1193,8 +1218,7 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, } - num_eqs = (mlx4_is_master(dev)) ? dev->phys_caps.num_phys_eqs : - dev->caps.num_eqs; + num_eqs = dev->phys_caps.num_phys_eqs; err = mlx4_init_icm_table(dev, &priv->eq_table.table, init_hca->eqc_base, dev_cap->eqc_entry_sz, num_eqs, num_eqs, 0, 0); @@ -1719,6 +1743,19 @@ static int mlx4_init_hca(struct mlx4_dev *dev) mlx4_err(dev, "INIT_HCA command failed, aborting\n"); goto err_free_icm; } + + if (dev_cap.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { + err = mlx4_query_func(dev, &dev_cap); + if (err < 0) { + mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); + goto err_stop_fw; + } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { + dev->caps.num_eqs = dev_cap.max_eqs; + dev->caps.reserved_eqs = dev_cap.reserved_eqs; + dev->caps.reserved_uars = dev_cap.reserved_uars; + } + } + /* * If TS is supported by FW * read HCA frequency by QUERY_HCA command @@ -2085,12 +2122,11 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); struct msix_entry *entries; - int nreq = min_t(int, dev->caps.num_ports * - min_t(int, num_online_cpus() + 1, - MAX_MSIX_P_PORT) + MSIX_LEGACY_SZ, MAX_MSIX); int i; if (msi_x) { + int nreq = dev->caps.num_ports * num_online_cpus() + MSIX_LEGACY_SZ; + nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, nreq); @@ -2345,6 +2381,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, int err; int port; int i; + struct mlx4_dev_cap *dev_cap = NULL; int existing_vfs = 0; dev = &priv->dev; @@ -2381,15 +2418,6 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, } } - if (total_vfs) { - existing_vfs = pci_num_vf(pdev); - dev->flags = MLX4_FLAG_MASTER; - dev->flags = mlx4_enable_sriov(dev, pdev, total_vfs, - existing_vfs); - if (!SRIOV_VALID_STATE(dev->flags)) - goto err_sriov; - } - atomic_set(&priv->opreq_count, 0); INIT_WORK(&priv->opreq_task, mlx4_opreq_action); @@ -2403,6 +2431,12 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, mlx4_err(dev, "Failed to reset HCA, aborting\n"); goto err_sriov; } + + if (total_vfs) { + existing_vfs = pci_num_vf(pdev); + dev->flags = MLX4_FLAG_MASTER; + dev->num_vfs = total_vfs; + } } slave_start: @@ -2416,9 +2450,10 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, * before posting commands. Also, init num_slaves before calling * mlx4_init_hca */ if (mlx4_is_mfunc(dev)) { - if (mlx4_is_master(dev)) + if (mlx4_is_master(dev)) { dev->num_slaves = MLX4_MAX_NUM_SLAVES; - else { + + } else { dev->num_slaves = 0; err = mlx4_multi_func_init(dev); if (err) { @@ -2434,6 +2469,52 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, goto err_mfunc; } + if (mlx4_is_master(dev)) { + if (!dev_cap) { + dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); + + if (!dev_cap) { + err = -ENOMEM; + goto err_fw; + } + + err = mlx4_QUERY_DEV_CAP(dev, dev_cap); + if (err) { + mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); + goto err_fw; + } + + if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) { + u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs, + existing_vfs); + + mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL); + dev->flags = dev_flags; + if (!SRIOV_VALID_STATE(dev->flags)) { + mlx4_err(dev, "Invalid SRIOV state\n"); + goto err_sriov; + } + err = mlx4_reset(dev); + if (err) { + mlx4_err(dev, "Failed to reset HCA, aborting.\n"); + goto err_sriov; + } + goto slave_start; + } + } else { + /* Legacy mode FW requires SRIOV to be enabled before + * doing QUERY_DEV_CAP, since max_eq's value is different if + * SRIOV is enabled. + */ + memset(dev_cap, 0, sizeof(*dev_cap)); + err = mlx4_QUERY_DEV_CAP(dev, dev_cap); + if (err) { + mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); + goto err_fw; + } + } + } + err = mlx4_init_hca(dev); if (err) { if (err == -EACCES) { @@ -2457,6 +2538,30 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, goto err_fw; } + if (mlx4_is_master(dev) && (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) { + u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs, existing_vfs); + + if ((dev->flags ^ dev_flags) & (MLX4_FLAG_MASTER | MLX4_FLAG_SLAVE)) { + mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_VHCR); + dev->flags = dev_flags; + err = mlx4_cmd_init(dev); + if (err) { + /* Only VHCR is cleaned up, so could still + * send FW commands + */ + mlx4_err(dev, "Failed to init VHCR command interface, aborting\n"); + goto err_close; + } + } else { + dev->flags = dev_flags; + } + + if (!SRIOV_VALID_STATE(dev->flags)) { + mlx4_err(dev, "Invalid SRIOV state\n"); + goto err_close; + } + } + /* check if the device is functioning at its maximum possible speed. * No return code for this call, just warn the user in case of PCI * express device capabilities are under-satisfied by the bus. @@ -2631,6 +2736,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, if (!mlx4_is_slave(dev)) mlx4_free_ownership(dev); + kfree(dev_cap); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 14089d9e1667..2bf437aafc53 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c @@ -126,8 +126,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, profile[MLX4_RES_AUXC].num = request->num_qp; profile[MLX4_RES_SRQ].num = request->num_srq; profile[MLX4_RES_CQ].num = request->num_cq; - profile[MLX4_RES_EQ].num = mlx4_is_mfunc(dev) ? - dev->phys_caps.num_phys_eqs : + profile[MLX4_RES_EQ].num = mlx4_is_mfunc(dev) ? dev->phys_caps.num_phys_eqs : min_t(unsigned, dev_cap->max_eqs, MAX_MSIX); profile[MLX4_RES_DMPT].num = request->num_mpt; profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; @@ -216,10 +215,18 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, init_hca->log_num_cqs = profile[i].log_num; break; case MLX4_RES_EQ: - dev->caps.num_eqs = roundup_pow_of_two(min_t(unsigned, dev_cap->max_eqs, - MAX_MSIX)); - init_hca->eqc_base = profile[i].start; - init_hca->log_num_eqs = ilog2(dev->caps.num_eqs); + if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { + init_hca->log_num_eqs = 0x1f; + init_hca->eqc_base = profile[i].start; + init_hca->num_sys_eqs = dev_cap->num_sys_eqs; + } else { + dev->caps.num_eqs = roundup_pow_of_two( + min_t(unsigned, + dev_cap->max_eqs, + MAX_MSIX)); + init_hca->eqc_base = profile[i].start; + init_hca->log_num_eqs = ilog2(dev->caps.num_eqs); + } break; case MLX4_RES_DMPT: dev->caps.num_mpts = profile[i].num; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 3d9bff00f24a..1c560eb870ad 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -189,7 +189,8 @@ enum { MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13, MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, - MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16 + MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, + MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17 }; enum { @@ -443,6 +444,7 @@ struct mlx4_caps { int num_cqs; int max_cqes; int reserved_cqs; + int num_sys_eqs; int num_eqs; int reserved_eqs; int num_comp_vectors; -- GitLab From de966c5928026b100a989c8cef761d306310a184 Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Thu, 13 Nov 2014 14:45:33 +0200 Subject: [PATCH 4696/9457] net/mlx4_core: Support more than 64 VFs We now allow up to 126 VFs. Note though that certain firmware versions only allow up to 80 VFs. Moreover, old HCAs only support 64 VFs. In these cases, we limit the maximum number of VFs to 64. Signed-off-by: Matan Barak Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 5 ++++- drivers/net/ethernet/mellanox/mlx4/main.c | 24 +++++++++++++++++++++++ include/linux/mlx4/device.h | 5 +++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index d2f594fadfbf..4251f81a0275 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -143,7 +143,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [14] = "Ethernet protocol control support", [15] = "Ethernet Backplane autoneg support", [16] = "CONFIG DEV support", - [17] = "Asymmetric EQs support" + [17] = "Asymmetric EQs support", + [18] = "More than 80 VFs support" }; int i; @@ -860,6 +861,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL; if (field32 & (1 << 20)) dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FSM; + if (field32 & (1 << 21)) + dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_80_VFS; if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { for (i = 1; i <= dev_cap->num_ports; ++i) { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index ebb279060a25..3044f9e623cb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2373,6 +2373,24 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, return dev_flags & ~MLX4_FLAG_MASTER; } +enum { + MLX4_DEV_CAP_CHECK_NUM_VFS_ABOVE_64 = -1, +}; + +static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, + int *nvfs) +{ + int requested_vfs = nvfs[0] + nvfs[1] + nvfs[2]; + /* Checking for 64 VFs as a limitation of CX2 */ + if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_80_VFS) && + requested_vfs >= 64) { + mlx4_err(dev, "Requested %d VFs, but FW does not support more than 64\n", + requested_vfs); + return MLX4_DEV_CAP_CHECK_NUM_VFS_ABOVE_64; + } + return 0; +} + static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, int total_vfs, int *nvfs, struct mlx4_priv *priv) { @@ -2484,6 +2502,9 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, goto err_fw; } + if (mlx4_check_dev_cap(dev, dev_cap, nvfs)) + goto err_fw; + if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) { u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs, existing_vfs); @@ -2512,6 +2533,9 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); goto err_fw; } + + if (mlx4_check_dev_cap(dev, dev_cap, nvfs)) + goto err_fw; } } diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 1c560eb870ad..cf09e65c2901 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -95,7 +95,7 @@ enum { enum { MLX4_MAX_NUM_PF = 16, - MLX4_MAX_NUM_VF = 64, + MLX4_MAX_NUM_VF = 126, MLX4_MAX_NUM_VF_P_PORT = 64, MLX4_MFUNC_MAX = 80, MLX4_MAX_EQ_NUM = 1024, @@ -190,7 +190,8 @@ enum { MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL = 1LL << 14, MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, - MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17 + MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17, + MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18 }; enum { -- GitLab From 6eba82248ef47fd478f940a418429e3ec95cb3db Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 13 Nov 2014 13:45:46 +0100 Subject: [PATCH 4697/9457] rhashtable: Drop gfp_flags arg in insert/remove functions Reallocation is only required for shrinking and expanding and both rely on a mutex for synchronization and callers of rhashtable_init() are in non atomic context. Therefore, no reason to continue passing allocation hints through the API. Instead, use GFP_KERNEL and add __GFP_NOWARN | __GFP_NORETRY to allow for silent fall back to vzalloc() without the OOM killer jumping in as pointed out by Eric Dumazet and Eric W. Biederman. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/rhashtable.h | 10 +++++----- lib/rhashtable.c | 41 ++++++++++++++++---------------------- net/netfilter/nft_hash.c | 4 ++-- net/netlink/af_netlink.c | 4 ++-- 4 files changed, 26 insertions(+), 33 deletions(-) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 473e26bdb91d..b93fd89b2e5e 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -99,16 +99,16 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params); u32 rhashtable_hashfn(const struct rhashtable *ht, const void *key, u32 len); u32 rhashtable_obj_hashfn(const struct rhashtable *ht, void *ptr); -void rhashtable_insert(struct rhashtable *ht, struct rhash_head *node, gfp_t); -bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *node, gfp_t); +void rhashtable_insert(struct rhashtable *ht, struct rhash_head *node); +bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *node); void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj, - struct rhash_head __rcu **pprev, gfp_t flags); + struct rhash_head __rcu **pprev); bool rht_grow_above_75(const struct rhashtable *ht, size_t new_size); bool rht_shrink_below_30(const struct rhashtable *ht, size_t new_size); -int rhashtable_expand(struct rhashtable *ht, gfp_t flags); -int rhashtable_shrink(struct rhashtable *ht, gfp_t flags); +int rhashtable_expand(struct rhashtable *ht); +int rhashtable_shrink(struct rhashtable *ht); void *rhashtable_lookup(const struct rhashtable *ht, const void *key); void *rhashtable_lookup_compare(const struct rhashtable *ht, u32 hash, diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 4b4b53bfa08b..25e4c213b08a 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -107,13 +107,13 @@ static u32 head_hashfn(const struct rhashtable *ht, return obj_hashfn(ht, rht_obj(ht, he), hsize); } -static struct bucket_table *bucket_table_alloc(size_t nbuckets, gfp_t flags) +static struct bucket_table *bucket_table_alloc(size_t nbuckets) { struct bucket_table *tbl; size_t size; size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]); - tbl = kzalloc(size, flags); + tbl = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); if (tbl == NULL) tbl = vzalloc(size); @@ -200,7 +200,6 @@ static void hashtable_chain_unzip(const struct rhashtable *ht, /** * rhashtable_expand - Expand hash table while allowing concurrent lookups * @ht: the hash table to expand - * @flags: allocation flags * * A secondary bucket array is allocated and the hash entries are migrated * while keeping them on both lists until the end of the RCU grace period. @@ -211,7 +210,7 @@ static void hashtable_chain_unzip(const struct rhashtable *ht, * The caller must ensure that no concurrent table mutations take place. * It is however valid to have concurrent lookups if they are RCU protected. */ -int rhashtable_expand(struct rhashtable *ht, gfp_t flags) +int rhashtable_expand(struct rhashtable *ht) { struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht); struct rhash_head *he; @@ -223,7 +222,7 @@ int rhashtable_expand(struct rhashtable *ht, gfp_t flags) if (ht->p.max_shift && ht->shift >= ht->p.max_shift) return 0; - new_tbl = bucket_table_alloc(old_tbl->size * 2, flags); + new_tbl = bucket_table_alloc(old_tbl->size * 2); if (new_tbl == NULL) return -ENOMEM; @@ -281,7 +280,6 @@ EXPORT_SYMBOL_GPL(rhashtable_expand); /** * rhashtable_shrink - Shrink hash table while allowing concurrent lookups * @ht: the hash table to shrink - * @flags: allocation flags * * This function may only be called in a context where it is safe to call * synchronize_rcu(), e.g. not within a rcu_read_lock() section. @@ -289,7 +287,7 @@ EXPORT_SYMBOL_GPL(rhashtable_expand); * The caller must ensure that no concurrent table mutations take place. * It is however valid to have concurrent lookups if they are RCU protected. */ -int rhashtable_shrink(struct rhashtable *ht, gfp_t flags) +int rhashtable_shrink(struct rhashtable *ht) { struct bucket_table *ntbl, *tbl = rht_dereference(ht->tbl, ht); struct rhash_head __rcu **pprev; @@ -300,7 +298,7 @@ int rhashtable_shrink(struct rhashtable *ht, gfp_t flags) if (ht->shift <= ht->p.min_shift) return 0; - ntbl = bucket_table_alloc(tbl->size / 2, flags); + ntbl = bucket_table_alloc(tbl->size / 2); if (ntbl == NULL) return -ENOMEM; @@ -341,7 +339,6 @@ EXPORT_SYMBOL_GPL(rhashtable_shrink); * rhashtable_insert - insert object into hash hash table * @ht: hash table * @obj: pointer to hash head inside object - * @flags: allocation flags (table expansion) * * Will automatically grow the table via rhashtable_expand() if the the * grow_decision function specified at rhashtable_init() returns true. @@ -349,8 +346,7 @@ EXPORT_SYMBOL_GPL(rhashtable_shrink); * The caller must ensure that no concurrent table mutations occur. It is * however valid to have concurrent lookups if they are RCU protected. */ -void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj, - gfp_t flags) +void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj) { struct bucket_table *tbl = rht_dereference(ht->tbl, ht); u32 hash; @@ -363,7 +359,7 @@ void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj, ht->nelems++; if (ht->p.grow_decision && ht->p.grow_decision(ht, tbl->size)) - rhashtable_expand(ht, flags); + rhashtable_expand(ht); } EXPORT_SYMBOL_GPL(rhashtable_insert); @@ -372,14 +368,13 @@ EXPORT_SYMBOL_GPL(rhashtable_insert); * @ht: hash table * @obj: pointer to hash head inside object * @pprev: pointer to previous element - * @flags: allocation flags (table expansion) * * Identical to rhashtable_remove() but caller is alreayd aware of the element * in front of the element to be deleted. This is in particular useful for * deletion when combined with walking or lookup. */ void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj, - struct rhash_head __rcu **pprev, gfp_t flags) + struct rhash_head __rcu **pprev) { struct bucket_table *tbl = rht_dereference(ht->tbl, ht); @@ -390,7 +385,7 @@ void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj, if (ht->p.shrink_decision && ht->p.shrink_decision(ht, tbl->size)) - rhashtable_shrink(ht, flags); + rhashtable_shrink(ht); } EXPORT_SYMBOL_GPL(rhashtable_remove_pprev); @@ -398,7 +393,6 @@ EXPORT_SYMBOL_GPL(rhashtable_remove_pprev); * rhashtable_remove - remove object from hash table * @ht: hash table * @obj: pointer to hash head inside object - * @flags: allocation flags (table expansion) * * Since the hash chain is single linked, the removal operation needs to * walk the bucket chain upon removal. The removal operation is thus @@ -410,8 +404,7 @@ EXPORT_SYMBOL_GPL(rhashtable_remove_pprev); * The caller must ensure that no concurrent table mutations occur. It is * however valid to have concurrent lookups if they are RCU protected. */ -bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj, - gfp_t flags) +bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj) { struct bucket_table *tbl = rht_dereference(ht->tbl, ht); struct rhash_head __rcu **pprev; @@ -429,7 +422,7 @@ bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj, continue; } - rhashtable_remove_pprev(ht, he, pprev, flags); + rhashtable_remove_pprev(ht, he, pprev); return true; } @@ -576,7 +569,7 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) if (params->nelem_hint) size = rounded_hashtable_size(params); - tbl = bucket_table_alloc(size, GFP_KERNEL); + tbl = bucket_table_alloc(size); if (tbl == NULL) return -ENOMEM; @@ -713,7 +706,7 @@ static int __init test_rhashtable(struct rhashtable *ht) obj->ptr = TEST_PTR; obj->value = i * 2; - rhashtable_insert(ht, &obj->node, GFP_KERNEL); + rhashtable_insert(ht, &obj->node); } rcu_read_lock(); @@ -724,7 +717,7 @@ static int __init test_rhashtable(struct rhashtable *ht) for (i = 0; i < TEST_NEXPANDS; i++) { pr_info(" Table expansion iteration %u...\n", i); - rhashtable_expand(ht, GFP_KERNEL); + rhashtable_expand(ht); rcu_read_lock(); pr_info(" Verifying lookups...\n"); @@ -734,7 +727,7 @@ static int __init test_rhashtable(struct rhashtable *ht) for (i = 0; i < TEST_NEXPANDS; i++) { pr_info(" Table shrinkage iteration %u...\n", i); - rhashtable_shrink(ht, GFP_KERNEL); + rhashtable_shrink(ht); rcu_read_lock(); pr_info(" Verifying lookups...\n"); @@ -749,7 +742,7 @@ static int __init test_rhashtable(struct rhashtable *ht) obj = rhashtable_lookup(ht, &key); BUG_ON(!obj); - rhashtable_remove(ht, &obj->node, GFP_KERNEL); + rhashtable_remove(ht, &obj->node); kfree(obj); } diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 3f75aaaf9d06..1e316ce4cb5d 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -65,7 +65,7 @@ static int nft_hash_insert(const struct nft_set *set, if (set->flags & NFT_SET_MAP) nft_data_copy(he->data, &elem->data); - rhashtable_insert(priv, &he->node, GFP_KERNEL); + rhashtable_insert(priv, &he->node); return 0; } @@ -88,7 +88,7 @@ static void nft_hash_remove(const struct nft_set *set, pprev = elem->cookie; he = rht_dereference((*pprev), priv); - rhashtable_remove_pprev(priv, he, pprev, GFP_KERNEL); + rhashtable_remove_pprev(priv, he, pprev); synchronize_rcu(); kfree(he); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 9e0628cfdf67..a491c1a4861f 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1092,7 +1092,7 @@ static int netlink_insert(struct sock *sk, struct net *net, u32 portid) nlk_sk(sk)->portid = portid; sock_hold(sk); - rhashtable_insert(&table->hash, &nlk_sk(sk)->node, GFP_KERNEL); + rhashtable_insert(&table->hash, &nlk_sk(sk)->node); err = 0; err: mutex_unlock(&nl_sk_hash_lock); @@ -1105,7 +1105,7 @@ static void netlink_remove(struct sock *sk) mutex_lock(&nl_sk_hash_lock); table = &nl_table[sk->sk_protocol]; - if (rhashtable_remove(&table->hash, &nlk_sk(sk)->node, GFP_KERNEL)) { + if (rhashtable_remove(&table->hash, &nlk_sk(sk)->node)) { WARN_ON(atomic_read(&sk->sk_refcnt) == 1); __sock_put(sk); } -- GitLab From d649a7a81f3b5bacb1d60abd7529894d8234a666 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 13 Nov 2014 09:45:22 -0800 Subject: [PATCH 4698/9457] tcp: limit GSO packets to half cwnd In DC world, GSO packets initially cooked by tcp_sendmsg() are usually big, as sk_pacing_rate is high. When network is congested, cwnd can be smaller than the GSO packets found in socket write queue. tcp_write_xmit() splits GSO packets using the available cwnd, and we end up sending a single GSO packet, consuming all available cwnd. With GRO aggregation on the receiver, we might handle a single GRO packet, sending back a single ACK. 1) This single ACK might be lost TLP or RTO are forced to attempt a retransmit. 2) This ACK releases a full cwnd, sender sends another big GSO packet, in a ping pong mode. This behavior does not fill the pipes in the best way, because of scheduling artifacts. Make sure we always have at least two GSO packets in flight. This allows us to safely increase GRO efficiency without risking spurious retransmits. Signed-off-by: Eric Dumazet Acked-by: Neal Cardwell Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0b88158dd4a7..eb73a1dccf56 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1562,7 +1562,7 @@ static unsigned int tcp_mss_split_point(const struct sock *sk, static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb) { - u32 in_flight, cwnd; + u32 in_flight, cwnd, halfcwnd; /* Don't be strict about the congestion window for the final FIN. */ if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && @@ -1571,10 +1571,14 @@ static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, in_flight = tcp_packets_in_flight(tp); cwnd = tp->snd_cwnd; - if (in_flight < cwnd) - return (cwnd - in_flight); + if (in_flight >= cwnd) + return 0; - return 0; + /* For better scheduling, ensure we have at least + * 2 GSO packets in flight. + */ + halfcwnd = max(cwnd >> 1, 1U); + return min(halfcwnd, cwnd - in_flight); } /* Initialize TSO state of a skb. -- GitLab From 895b31f3b6b800b8f46569391f2396b1f221c602 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Nov 2014 19:37:39 +0100 Subject: [PATCH 4699/9457] PM / Domains: Make genpd parameter of pm_genpd_present() const The PM domain pointed to by the genpd parameter is never modified. Signed-off-by: Geert Uytterhoeven Acked-by: Kevin Hilman Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 40bc2f4072cc..28d6e8bf746c 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -753,9 +753,9 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {} * pm_genpd_present - Check if the given PM domain has been initialized. * @genpd: PM domain to check. */ -static bool pm_genpd_present(struct generic_pm_domain *genpd) +static bool pm_genpd_present(const struct generic_pm_domain *genpd) { - struct generic_pm_domain *gpd; + const struct generic_pm_domain *gpd; if (IS_ERR_OR_NULL(genpd)) return false; -- GitLab From c8f0ea45169c57f36e6d8c4dcf7ccf09de7f1c2c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Nov 2014 19:39:19 +0100 Subject: [PATCH 4700/9457] PM / Domains: Extract code to power off/on a PM domain PM domains are powered on/off from various places. Some callers do latency measurements, others don't. Consolidate using two helper functions, which always measure the latencies, and update the stored latencies when needed. Other minor changes: - Use pr_warn() instead of pr_warning(), - There's no need to check genpd->name, %s handles NULL pointers fine, - Make the warning format strings identical, to save memory. Signed-off-by: Geert Uytterhoeven Reviewed-by: Ulf Hansson Reviewed-by: Kevin Hilman Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 101 +++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 41 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 28d6e8bf746c..1d1f5cc4293d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -151,6 +151,59 @@ static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd) genpd->cpuidle_data->idle_state->exit_latency = usecs64; } +static int genpd_power_on(struct generic_pm_domain *genpd) +{ + ktime_t time_start; + s64 elapsed_ns; + int ret; + + if (!genpd->power_on) + return 0; + + time_start = ktime_get(); + ret = genpd->power_on(genpd); + if (ret) + return ret; + + elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); + if (elapsed_ns <= genpd->power_on_latency_ns) + return ret; + + genpd->power_on_latency_ns = elapsed_ns; + genpd->max_off_time_changed = true; + genpd_recalc_cpu_exit_latency(genpd); + pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", + genpd->name, "on", elapsed_ns); + + return ret; +} + +static int genpd_power_off(struct generic_pm_domain *genpd) +{ + ktime_t time_start; + s64 elapsed_ns; + int ret; + + if (!genpd->power_off) + return 0; + + time_start = ktime_get(); + ret = genpd->power_off(genpd); + if (ret == -EBUSY) + return ret; + + elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); + if (elapsed_ns <= genpd->power_off_latency_ns) + return ret; + + genpd->power_off_latency_ns = elapsed_ns; + genpd->max_off_time_changed = true; + pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n", + genpd->name, "off", elapsed_ns); + + return ret; +} + /** * __pm_genpd_poweron - Restore power to a given PM domain and its masters. * @genpd: PM domain to power up. @@ -222,25 +275,9 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd) } } - if (genpd->power_on) { - ktime_t time_start = ktime_get(); - s64 elapsed_ns; - - ret = genpd->power_on(genpd); - if (ret) - goto err; - - elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); - if (elapsed_ns > genpd->power_on_latency_ns) { - genpd->power_on_latency_ns = elapsed_ns; - genpd->max_off_time_changed = true; - genpd_recalc_cpu_exit_latency(genpd); - if (genpd->name) - pr_warning("%s: Power-on latency exceeded, " - "new value %lld ns\n", genpd->name, - elapsed_ns); - } - } + ret = genpd_power_on(genpd); + if (ret) + goto err; out: genpd_set_active(genpd); @@ -529,16 +566,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) } if (genpd->power_off) { - ktime_t time_start; - s64 elapsed_ns; - if (atomic_read(&genpd->sd_count) > 0) { ret = -EBUSY; goto out; } - time_start = ktime_get(); - /* * If sd_count > 0 at this point, one of the subdomains hasn't * managed to call pm_genpd_poweron() for the master yet after @@ -547,21 +579,11 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) * the pm_genpd_poweron() restore power for us (this shouldn't * happen very often). */ - ret = genpd->power_off(genpd); + ret = genpd_power_off(genpd); if (ret == -EBUSY) { genpd_set_active(genpd); goto out; } - - elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); - if (elapsed_ns > genpd->power_off_latency_ns) { - genpd->power_off_latency_ns = elapsed_ns; - genpd->max_off_time_changed = true; - if (genpd->name) - pr_warning("%s: Power-off latency exceeded, " - "new value %lld ns\n", genpd->name, - elapsed_ns); - } } genpd->status = GPD_STATE_POWER_OFF; @@ -796,8 +818,7 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd) || atomic_read(&genpd->sd_count) > 0) return; - if (genpd->power_off) - genpd->power_off(genpd); + genpd_power_off(genpd); genpd->status = GPD_STATE_POWER_OFF; @@ -828,8 +849,7 @@ static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd) genpd_sd_counter_inc(link->master); } - if (genpd->power_on) - genpd->power_on(genpd); + genpd_power_on(genpd); genpd->status = GPD_STATE_ACTIVE; } @@ -1251,8 +1271,7 @@ static int pm_genpd_restore_noirq(struct device *dev) * If the domain was off before the hibernation, make * sure it will be off going forward. */ - if (genpd->power_off) - genpd->power_off(genpd); + genpd_power_off(genpd); return 0; } -- GitLab From 7e7e8fe69820c6fa31395dbbd8e348e3c69cd2a9 Mon Sep 17 00:00:00 2001 From: Lenny Szubowicz Date: Thu, 13 Nov 2014 13:51:52 -0500 Subject: [PATCH 4701/9457] cpufreq: pcc: Enable autoload of pcc-cpufreq for ACPI processors The pcc-cpufreq driver is not automatically loaded on systems where the platform's power management setting requires this driver. Instead, on those systems no CPU frequency driver is registered and active. Make the autoloading matching criteria for loading the pcc-cpufreq driver the same as done in acpi-cpufreq by commit c655affbd524d01 ("ACPI / cpufreq: Add ACPI processor device IDs to acpi-cpufreq"). x86 CPU frequency drivers are now typically autoloaded by specifying MODULE_DEVICE_TABLE entries and x86cpu model specific matching. But pcc-cpufreq was omitted when acpi-cpufreq and other drivers were changed to use this approach. Both acpi-cpufreq and pcc-cpufreq depend on a distinct and mutually exclusive set of ACPI methods which are not directly tied to specific processor model numbers. Both of these drivers have init routines which look for their required ACPI methods. As a result, only the appropriate driver registers as the cpu frequency driver and the other one ends up being unloaded. Tested on various systems where acpi-cpufreq, intel_pstate, and pcc-cpufreq are the expected cpu frequency drivers. Signed-off-by: Lenny Szubowicz Signed-off-by: Joseph Szczypek Reported-by: Trinh Dao Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/pcc-cpufreq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 4d2c8e861089..2a0d58959acf 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -603,6 +603,13 @@ static void __exit pcc_cpufreq_exit(void) free_percpu(pcc_cpu_info); } +static const struct acpi_device_id processor_device_ids[] = { + {ACPI_PROCESSOR_OBJECT_HID, }, + {ACPI_PROCESSOR_DEVICE_HID, }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, processor_device_ids); + MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); MODULE_VERSION(PCC_VERSION); MODULE_DESCRIPTION("Processor Clocking Control interface driver"); -- GitLab From 0abc08baf2ddf61a37d375a9fb832be612f9c5a5 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:04 +0100 Subject: [PATCH 4702/9457] ARM: 8170/1: Add global named register current_stack_pointer for ARM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define a global named register for current_stack_pointer. The use of this new variable guarantees that both gcc and clang can access this register in C code. Signed-off-by: Behan Webster Reviewed-by: Jan-Simon Möller Reviewed-by: Mark Charlebois Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/thread_info.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index fc44d3761f9e..bb435152189f 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -100,6 +100,11 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) +/* + * how to get the current stack pointer in C + */ +register unsigned long current_stack_pointer asm ("sp"); + /* * how to get the thread information struct from C */ -- GitLab From a556ee1247b99720d9ba6d8a3ed43dd960575d07 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:07 +0100 Subject: [PATCH 4703/9457] ARM: 8171/1: Use current_stack_pointer for return_address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the global current_stack_pointer to get the value of the stack pointer. This change supports being able to compile the kernel with both gcc and Clang. Signed-off-by: Behan Webster Reviewed-by: Mark Charlebois Reviewed-by: Jan-Simon Möller Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/return_address.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index 98ea4b7eb406..24b4a04846eb 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -39,13 +39,12 @@ void *return_address(unsigned int level) { struct return_address_data data; struct stackframe frame; - register unsigned long current_sp asm ("sp"); data.level = level + 2; data.addr = NULL; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = current_stack_pointer; frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)return_address; -- GitLab From 74dbeee0fcded9525ddb42b53ee75dc62c8089d9 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:08 +0100 Subject: [PATCH 4704/9457] ARM: 8172/1: Use current_stack_pointer in save_stack_trace_tsk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the global current_stack_pointer to get the value of the stack pointer. This change supports being able to compile the kernel with both gcc and clang. Signed-off-by: Behan Webster Reviewed-by: Mark Charlebois Reviewed-by: Jan-Simon Möller Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/stacktrace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index f065eb05d254..92b72375c4c7 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -134,12 +134,10 @@ static noinline void __save_stack_trace(struct task_struct *tsk, frame.pc = thread_saved_pc(tsk); #endif } else { - register unsigned long current_sp asm ("sp"); - /* We don't want this function nor the caller */ data.skip += 2; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = current_stack_pointer; frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)__save_stack_trace; } -- GitLab From f6c9cbf091a4b0769180d663e37621569b054d11 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:09 +0100 Subject: [PATCH 4705/9457] ARM: 8173/1: Calculate current_thread_info from current_stack_pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the global current_stack_pointer to get the value of the stack pointer. This change supports being able to compile the kernel with both gcc and clang. Signed-off-by: Behan Webster Reviewed-by: Mark Charlebois Reviewed-by: Jan-Simon Möller Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/thread_info.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index bb435152189f..b9dc3dce59a6 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -112,8 +112,8 @@ static inline struct thread_info *current_thread_info(void) __attribute_const__; static inline struct thread_info *current_thread_info(void) { - register unsigned long sp asm ("sp"); - return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); + return (struct thread_info *) + (current_stack_pointer & ~(THREAD_SIZE - 1)); } #define thread_saved_pc(tsk) \ -- GitLab From ccbd2da50db2111f6d055e3201c39a37e542ceb6 Mon Sep 17 00:00:00 2001 From: Mark Charlebois Date: Sat, 27 Sep 2014 00:31:05 +0100 Subject: [PATCH 4706/9457] ARM: 8174/1: Use global stack register variable for percpu Using global current_stack_pointer works on both clang and gcc. current_stack_pointer is an unsigned long and needs to be cast as a pointer to dereference. Signed-off-by: Mark Charlebois Signed-off-by: Behan Webster Signed-off-by: Russell King --- arch/arm/include/asm/percpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h index 209e6504922e..a89b4076cde4 100644 --- a/arch/arm/include/asm/percpu.h +++ b/arch/arm/include/asm/percpu.h @@ -30,14 +30,14 @@ static inline void set_my_cpu_offset(unsigned long off) static inline unsigned long __my_cpu_offset(void) { unsigned long off; - register unsigned long *sp asm ("sp"); /* * Read TPIDRPRW. * We want to allow caching the value, so avoid using volatile and * instead use a fake stack read to hazard against barrier(). */ - asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp)); + asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) + : "Q" (*(const unsigned long *)current_stack_pointer)); return off; } -- GitLab From 0ebc1f5671dff84b7ba4dcc38ebce956e6dea5fa Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:06 +0100 Subject: [PATCH 4707/9457] ARM: 8175/1: Use current_stack_pointer to calculate pt_regs address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the global current_stack_pointer to calculate the end of the stack for current_pt_regs() Signed-off-by: Behan Webster Reviewed-by: Mark Charlebois Reviewed-by: Jan-Simon Möller Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/ptrace.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 601264d983fa..51622ba7c4a6 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -154,9 +154,8 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs) return regs->ARM_sp; } -#define current_pt_regs(void) ({ \ - register unsigned long sp asm ("sp"); \ - (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \ +#define current_pt_regs(void) ({ (struct pt_regs *) \ + ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \ }) #endif /* __ASSEMBLY__ */ -- GitLab From 0bf4954f248c59705470bae2210f67a4b03f8f3c Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Sat, 27 Sep 2014 00:31:10 +0100 Subject: [PATCH 4708/9457] ARM: 8176/1: Use current_stack_pointer in unwind_backtrace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the global current_stack_pointer to get the value of the stack pointer. This change supports being able to compile the kernel with both gcc and clang. Signed-off-by: Behan Webster Reviewed-by: Mark Charlebois Reviewed-by: Jan-Simon Möller Acked-by: Will Deacon Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/unwind.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index cbb85c5fabf9..0bee233fef9a 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -471,7 +471,6 @@ int unwind_frame(struct stackframe *frame) void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - register unsigned long current_sp asm ("sp"); pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); @@ -485,7 +484,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) frame.pc = regs->ARM_lr; } else if (tsk == current) { frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = current_stack_pointer; frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)unwind_backtrace; } else { -- GitLab From fe578ba36fe7a118298028031b3ce562e6ea1c4c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 13 Nov 2014 19:40:56 -0500 Subject: [PATCH 4709/9457] ftrace: Have the control_ops get a trampoline With the new logic, if only a single user of ftrace function hooks is used, it will get its own trampoline assigned to it. The problem is that the control_ops is an indirect ops that perf ops uses. What that means is that when perf registers its ops with register_ftrace_function(), it has the CONTROL flag set and gets added to the control list instead of the global ftrace list. The control_ops gets added to that instead and the mcount trampoline calls the control_ops function. The control_ops function will iterate the control list and call the ops functions that are attached to it. But currently the trampoline is added to the perf ops and not the control ops, and when ftrace tries to find a trampoline hook for it, it fails to find one and gives the following splat: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 10133 at kernel/trace/ftrace.c:2033 ftrace_get_addr_new+0x6f/0xc0() Modules linked in: [...] CPU: 0 PID: 10133 Comm: perf Tainted: P 3.18.0-rc1-test+ #388 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012 00000000000007f1 ffff8800c2643bc8 ffffffff814fca6e ffff88011ea0ed01 0000000000000000 ffff8800c2643c08 ffffffff81041ffd 0000000000000000 ffffffff810c388c ffffffff81a5a350 ffff880119b00000 ffffffff810001c8 Call Trace: [] dump_stack+0x46/0x58 [] warn_slowpath_common+0x81/0x9b [] ? ftrace_get_addr_new+0x6f/0xc0 [] ? 0xffffffff810001c8 [] warn_slowpath_null+0x1a/0x1c [] ftrace_get_addr_new+0x6f/0xc0 [] ftrace_replace_code+0xd6/0x334 [] ftrace_modify_all_code+0x41/0xc5 [] arch_ftrace_update_code+0x10/0x19 [] ftrace_run_update_code+0x21/0x42 [] ftrace_startup_enable+0x32/0x34 [] ftrace_startup+0x14e/0x15a [] register_ftrace_function+0x27/0x40 [] perf_ftrace_event_register+0x3e/0xee [] perf_trace_init+0x29d/0x2a9 [] perf_tp_event_init+0x27/0x3a [] perf_init_event+0x9e/0xed [] perf_event_alloc+0x299/0x330 [] SYSC_perf_event_open+0x3ee/0x816 [] ? mntput+0x2d/0x2f [] ? __fput+0xa7/0x1b2 [] ? do_gettimeofday+0x22/0x3a [] SyS_perf_event_open+0x9/0xb [] system_call_fastpath+0x12/0x17 ---[ end trace 81a53565150e4982 ]--- Bad trampoline accounting at: ffffffff810001c8 (run_init_process+0x0/0x2d) (10000001) Update the control_ops trampoline instead of the perf ops one. Reported-by: lkp@01.org Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4043332f6720..1a13e615a068 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -418,6 +418,8 @@ static int __register_ftrace_function(struct ftrace_ops *ops) if (control_ops_alloc(ops)) return -ENOMEM; add_ftrace_list_ops(&ftrace_control_list, &control_ops, ops); + /* The control_ops needs the trampoline update */ + ops = &control_ops; } else add_ftrace_ops(&ftrace_ops_list, ops); -- GitLab From baeb0d9b98c3450e22f8f8e4a6619b8b1d5106ff Mon Sep 17 00:00:00 2001 From: Michael Turquette Date: Thu, 13 Nov 2014 17:18:20 -0800 Subject: [PATCH 4710/9457] MAINTAINERS: clk framework git tree moved to kernel.org Signed-off-by: Michael Turquette --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 46d652f166ab..924499202dac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2493,7 +2493,7 @@ COMMON CLK FRAMEWORK M: Mike Turquette M: Stephen Boyd L: linux-kernel@vger.kernel.org -T: git git://git.linaro.org/people/mturquette/linux.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git S: Maintained F: drivers/clk/ X: drivers/clk/clkdev.c -- GitLab From 933ff9f20220e1339964c7a76a34ca9aaa4a8c37 Mon Sep 17 00:00:00 2001 From: "Luis Claudio R. Goncalves" Date: Wed, 12 Nov 2014 21:14:00 -0200 Subject: [PATCH 4711/9457] tracing: Fix traceoff_on_warning handling on boot command line According to the documentation, adding "traceoff_on_warning" to the boot command line should be enough to enable the feature. But right now it is necessary to specify "traceoff_on_warning=". Along with fixing that, also verify if the value passed, if any, is either "0" or "off". Link: http://lkml.kernel.org/r/20141112231400.GL12281@uudg.org Signed-off-by: Luis Claudio R. Goncalves Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8a528392b1f4..75798ab8eb88 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -155,10 +155,11 @@ __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); static int __init stop_trace_on_warning(char *str) { - __disable_trace_on_warning = 1; + if ((strcmp(str, "=0") != 0 && strcmp(str, "=off") != 0)) + __disable_trace_on_warning = 1; return 1; } -__setup("traceoff_on_warning=", stop_trace_on_warning); +__setup("traceoff_on_warning", stop_trace_on_warning); static int __init boot_alloc_snapshot(char *str) { -- GitLab From c270cc75cd22b606c901e606fbb93b002c2a655f Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Thu, 6 Nov 2014 12:41:55 +0000 Subject: [PATCH 4712/9457] tracing: kdb: Fix kernel panic during ftdump Currently kdb's ftdump command unconditionally crashes due to a null pointer de-reference whenever the command is run. This in turn causes the kernel to panic. The abridged stacktrace (gathered with ARCH=arm) is: --- cut here --- [] (panic) from [] (die+0x264/0x440) [] (die) from [] (__do_kernel_fault.part.11+0x74/0x84) [] (__do_kernel_fault.part.11) from [] (do_page_fault+0x1d0/0x3c4) [] (do_page_fault) from [] (do_DataAbort+0x48/0xac) [] (do_DataAbort) from [] (__dabt_svc+0x38/0x60) Exception stack(0xc0deba88 to 0xc0debad0) ba80: e8c29180 00000001 e9854304 e9854300 c0f567d8 c0df2580 baa0: 00000000 00000000 00000000 c0f117b8 c0e3a3c0 c0debb0c 00000000 c0debad0 bac0: 0000672e c02f4d60 60000193 ffffffff [] (__dabt_svc) from [] (kdb_ftdump+0x1e4/0x3d8) [] (kdb_ftdump) from [] (kdb_parse+0x2b8/0x698) [] (kdb_parse) from [] (kdb_main_loop+0x52c/0x784) [] (kdb_main_loop) from [] (kdb_stub+0x238/0x490) --- cut here --- The NULL deref occurs due to the initialized use of struct trace_iter's buffer_iter member. This is a regression, albeit a fairly elderly one. It was introduced by commit 6d158a813efc ("tracing: Remove NR_CPUS array from trace_iterator"). This patch solves this by providing a collection of ring_buffer_iter(s) and using this to initialize buffer_iter. Note that static allocation is used solely because the trace_iter itself is also static allocated. Static allocation also means that we have to NULL-ify the pointer during cleanup to avoid use-after-free problems. Link: http://lkml.kernel.org/r/1415277716-19419-2-git-send-email-daniel.thompson@linaro.org Cc: Jason Wessel Signed-off-by: Daniel Thompson Signed-off-by: Steven Rostedt --- kernel/trace/trace_kdb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index bd90e1b06088..8faa7ce58814 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -20,10 +20,12 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) { /* use static because iter can be a bit big for the stack */ static struct trace_iterator iter; + static struct ring_buffer_iter *buffer_iter[CONFIG_NR_CPUS]; unsigned int old_userobj; int cnt = 0, cpu; trace_init_global_iter(&iter); + iter.buffer_iter = buffer_iter; for_each_tracing_cpu(cpu) { atomic_inc(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled); @@ -86,9 +88,12 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled); } - for_each_tracing_cpu(cpu) - if (iter.buffer_iter[cpu]) + for_each_tracing_cpu(cpu) { + if (iter.buffer_iter[cpu]) { ring_buffer_read_finish(iter.buffer_iter[cpu]); + iter.buffer_iter[cpu] = NULL; + } + } } /* -- GitLab From 8520dedbbf7578a397ecdfcf6ab83f775f914cfe Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Thu, 6 Nov 2014 12:41:56 +0000 Subject: [PATCH 4713/9457] tracing: kdb: Fix kernel livelock with empty buffers Currently kdb's ftdump command will livelock by constantly printk'ing the empty string at KERN_EMERG level if it run when the ftrace system is not in use. This occurs because trace_empty() never returns false when the ring buffers are left at the start of a non-consuming read [launched by ring_buffer_read_start()]. This patch changes the loop exit condition to use the result of trace_find_next_entry_inc(). Effectively this switches the non-consuming kdb dumper to follow the approach of the non-consuming userspace interface [s_next()] rather than the consuming ftrace_dump(). Link: http://lkml.kernel.org/r/1415277716-19419-3-git-send-email-daniel.thompson@linaro.org Cc: Ingo Molnar Cc: Andrew Morton Cc: John Stultz Cc: Sumit Semwal Cc: Jason Wessel Signed-off-by: Daniel Thompson Signed-off-by: Steven Rostedt --- kernel/trace/trace_kdb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 8faa7ce58814..b0b1c44e923a 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -59,19 +59,19 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) ring_buffer_read_start(iter.buffer_iter[cpu_file]); tracing_iter_reset(&iter, cpu_file); } - if (!trace_empty(&iter)) - trace_find_next_entry_inc(&iter); - while (!trace_empty(&iter)) { + + while (trace_find_next_entry_inc(&iter)) { if (!cnt) kdb_printf("---------------------------------\n"); cnt++; - if (trace_find_next_entry_inc(&iter) != NULL && !skip_lines) + if (!skip_lines) { print_trace_line(&iter); - if (!skip_lines) trace_printk_seq(&iter.seq); - else + } else { skip_lines--; + } + if (KDB_FLAG(CMD_INTERRUPT)) goto out; } -- GitLab From fa6f0cc751d377af3f4f1484bceb47dc10163753 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 8 Nov 2014 21:42:10 +0100 Subject: [PATCH 4714/9457] tracing: Replace seq_printf by simpler equivalents Using seq_printf to print a simple string or a single character is a lot more expensive than it needs to be, since seq_puts and seq_putc exist. These patches do seq_printf(m, s) -> seq_puts(m, s) seq_printf(m, "%s", s) -> seq_puts(m, s) seq_printf(m, "%c", c) -> seq_putc(m, c) Subsequent patches will simplify further. Link: http://lkml.kernel.org/r/1415479332-25944-2-git-send-email-linux@rasmusvillemoes.dk Signed-off-by: Rasmus Villemoes Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 30 +++++++++---------- kernel/trace/trace.c | 44 ++++++++++++++-------------- kernel/trace/trace_branch.c | 26 ++++++++-------- kernel/trace/trace_events.c | 4 +-- kernel/trace/trace_events_trigger.c | 2 +- kernel/trace/trace_functions.c | 2 +- kernel/trace/trace_functions_graph.c | 28 +++++++++--------- kernel/trace/trace_kprobe.c | 4 +-- kernel/trace/trace_uprobe.c | 2 +- 9 files changed, 71 insertions(+), 71 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1a13e615a068..6233f9102179 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -571,13 +571,13 @@ static int function_stat_cmp(void *p1, void *p2) static int function_stat_headers(struct seq_file *m) { #ifdef CONFIG_FUNCTION_GRAPH_TRACER - seq_printf(m, " Function " - "Hit Time Avg s^2\n" - " -------- " - "--- ---- --- ---\n"); + seq_puts(m, " Function " + "Hit Time Avg s^2\n" + " -------- " + "--- ---- --- ---\n"); #else - seq_printf(m, " Function Hit\n" - " -------- ---\n"); + seq_puts(m, " Function Hit\n" + " -------- ---\n"); #endif return 0; } @@ -604,7 +604,7 @@ static int function_stat_show(struct seq_file *m, void *v) seq_printf(m, " %-30.30s %10lu", str, rec->counter); #ifdef CONFIG_FUNCTION_GRAPH_TRACER - seq_printf(m, " "); + seq_puts(m, " "); avg = rec->time; do_div(avg, rec->counter); @@ -3006,9 +3006,9 @@ static int t_show(struct seq_file *m, void *v) if (iter->flags & FTRACE_ITER_PRINTALL) { if (iter->flags & FTRACE_ITER_NOTRACE) - seq_printf(m, "#### no functions disabled ####\n"); + seq_puts(m, "#### no functions disabled ####\n"); else - seq_printf(m, "#### all functions enabled ####\n"); + seq_puts(m, "#### all functions enabled ####\n"); return 0; } @@ -3030,13 +3030,13 @@ static int t_show(struct seq_file *m, void *v) seq_printf(m, "\ttramp: %pS", (void *)ops->trampoline); else - seq_printf(m, "\ttramp: ERROR!"); + seq_puts(m, "\ttramp: ERROR!"); } add_trampoline_func(m, ops, rec); } - seq_printf(m, "\n"); + seq_putc(m, '\n'); return 0; } @@ -4233,9 +4233,9 @@ static int g_show(struct seq_file *m, void *v) struct ftrace_graph_data *fgd = m->private; if (fgd->table == ftrace_graph_funcs) - seq_printf(m, "#### all functions enabled ####\n"); + seq_puts(m, "#### all functions enabled ####\n"); else - seq_printf(m, "#### no functions disabled ####\n"); + seq_puts(m, "#### no functions disabled ####\n"); return 0; } @@ -5155,12 +5155,12 @@ static int fpid_show(struct seq_file *m, void *v) const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list); if (v == (void *)1) { - seq_printf(m, "no pid\n"); + seq_puts(m, "no pid\n"); return 0; } if (fpid->pid == ftrace_swapper_pid) - seq_printf(m, "swapper tasks\n"); + seq_puts(m, "swapper tasks\n"); else seq_printf(m, "%u\n", pid_vnr(fpid->pid)); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 75798ab8eb88..a419db75152c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2860,44 +2860,44 @@ static void test_ftrace_alive(struct seq_file *m) { if (!ftrace_is_dead()) return; - seq_printf(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); - seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n"); + seq_puts(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); + seq_puts(m, "# MAY BE MISSING FUNCTION EVENTS\n"); } #ifdef CONFIG_TRACER_MAX_TRACE static void show_snapshot_main_help(struct seq_file *m) { - seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); - seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); - seq_printf(m, "# Takes a snapshot of the main buffer.\n"); - seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n"); - seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); - seq_printf(m, "# is not a '0' or '1')\n"); + seq_puts(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); + seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); + seq_puts(m, "# Takes a snapshot of the main buffer.\n"); + seq_puts(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n"); + seq_puts(m, "# (Doesn't have to be '2' works with any number that\n"); + seq_puts(m, "# is not a '0' or '1')\n"); } static void show_snapshot_percpu_help(struct seq_file *m) { - seq_printf(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); + seq_puts(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP - seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); - seq_printf(m, "# Takes a snapshot of the main buffer for this cpu.\n"); + seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); + seq_puts(m, "# Takes a snapshot of the main buffer for this cpu.\n"); #else - seq_printf(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); - seq_printf(m, "# Must use main snapshot file to allocate.\n"); + seq_puts(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); + seq_puts(m, "# Must use main snapshot file to allocate.\n"); #endif - seq_printf(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); - seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); - seq_printf(m, "# is not a '0' or '1')\n"); + seq_puts(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); + seq_puts(m, "# (Doesn't have to be '2' works with any number that\n"); + seq_puts(m, "# is not a '0' or '1')\n"); } static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { if (iter->tr->allocated_snapshot) - seq_printf(m, "#\n# * Snapshot is allocated *\n#\n"); + seq_puts(m, "#\n# * Snapshot is allocated *\n#\n"); else - seq_printf(m, "#\n# * Snapshot is freed *\n#\n"); + seq_puts(m, "#\n# * Snapshot is freed *\n#\n"); - seq_printf(m, "# Snapshot commands:\n"); + seq_puts(m, "# Snapshot commands:\n"); if (iter->cpu_file == RING_BUFFER_ALL_CPUS) show_snapshot_main_help(m); else @@ -3251,7 +3251,7 @@ static int t_show(struct seq_file *m, void *v) if (!t) return 0; - seq_printf(m, "%s", t->name); + seq_puts(m, t->name); if (t->next) seq_putc(m, ' '); else @@ -5753,10 +5753,10 @@ ftrace_snapshot_print(struct seq_file *m, unsigned long ip, seq_printf(m, "%ps:", (void *)ip); - seq_printf(m, "snapshot"); + seq_puts(m, "snapshot"); if (count == -1) - seq_printf(m, ":unlimited\n"); + seq_puts(m, ":unlimited\n"); else seq_printf(m, ":count=%ld\n", count); diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index 697fb9bac8f0..126c622e4f42 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -233,12 +233,12 @@ extern unsigned long __stop_annotated_branch_profile[]; static int annotated_branch_stat_headers(struct seq_file *m) { - seq_printf(m, " correct incorrect %% "); - seq_printf(m, " Function " - " File Line\n" - " ------- --------- - " - " -------- " - " ---- ----\n"); + seq_puts(m, " correct incorrect % "); + seq_puts(m, " Function " + " File Line\n" + " ------- --------- - " + " -------- " + " ---- ----\n"); return 0; } @@ -274,7 +274,7 @@ static int branch_stat_show(struct seq_file *m, void *v) seq_printf(m, "%8lu %8lu ", p->correct, p->incorrect); if (percent < 0) - seq_printf(m, " X "); + seq_puts(m, " X "); else seq_printf(m, "%3ld ", percent); seq_printf(m, "%-30.30s %-20.20s %d\n", p->func, f, p->line); @@ -362,12 +362,12 @@ extern unsigned long __stop_branch_profile[]; static int all_branch_stat_headers(struct seq_file *m) { - seq_printf(m, " miss hit %% "); - seq_printf(m, " Function " - " File Line\n" - " ------- --------- - " - " -------- " - " ---- ----\n"); + seq_puts(m, " miss hit % "); + seq_puts(m, " Function " + " File Line\n" + " ------- --------- - " + " -------- " + " ---- ----\n"); return 0; } diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 0cc51edde3a8..f9d0cbe014b7 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -918,7 +918,7 @@ static int f_show(struct seq_file *m, void *v) case FORMAT_HEADER: seq_printf(m, "name: %s\n", ftrace_event_name(call)); seq_printf(m, "ID: %d\n", call->event.type); - seq_printf(m, "format:\n"); + seq_puts(m, "format:\n"); return 0; case FORMAT_FIELD_SEPERATOR: @@ -1988,7 +1988,7 @@ event_enable_print(struct seq_file *m, unsigned long ip, ftrace_event_name(data->file->event_call)); if (data->count == -1) - seq_printf(m, ":unlimited\n"); + seq_puts(m, ":unlimited\n"); else seq_printf(m, ":count=%ld\n", data->count); diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 4747b476a030..3d89ffc66740 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -373,7 +373,7 @@ event_trigger_print(const char *name, struct seq_file *m, { long count = (long)data; - seq_printf(m, "%s", name); + seq_puts(m, name); if (count == -1) seq_puts(m, ":unlimited"); diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 57f0ec962d2c..a8e0c7666164 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -361,7 +361,7 @@ ftrace_probe_print(const char *name, struct seq_file *m, seq_printf(m, "%ps:%s", (void *)ip, name); if (count == -1) - seq_printf(m, ":unlimited\n"); + seq_puts(m, ":unlimited\n"); else seq_printf(m, ":count=%ld\n", count); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index f0a0c982cde3..29ba611e6f57 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1407,32 +1407,32 @@ static void __print_graph_headers_flags(struct seq_file *s, u32 flags) print_lat_header(s, flags); /* 1st line */ - seq_printf(s, "#"); + seq_puts(s, "#"); if (flags & TRACE_GRAPH_PRINT_ABS_TIME) - seq_printf(s, " TIME "); + seq_puts(s, " TIME "); if (flags & TRACE_GRAPH_PRINT_CPU) - seq_printf(s, " CPU"); + seq_puts(s, " CPU"); if (flags & TRACE_GRAPH_PRINT_PROC) - seq_printf(s, " TASK/PID "); + seq_puts(s, " TASK/PID "); if (lat) - seq_printf(s, "||||"); + seq_puts(s, "||||"); if (flags & TRACE_GRAPH_PRINT_DURATION) - seq_printf(s, " DURATION "); - seq_printf(s, " FUNCTION CALLS\n"); + seq_puts(s, " DURATION "); + seq_puts(s, " FUNCTION CALLS\n"); /* 2nd line */ - seq_printf(s, "#"); + seq_puts(s, "#"); if (flags & TRACE_GRAPH_PRINT_ABS_TIME) - seq_printf(s, " | "); + seq_puts(s, " | "); if (flags & TRACE_GRAPH_PRINT_CPU) - seq_printf(s, " | "); + seq_puts(s, " | "); if (flags & TRACE_GRAPH_PRINT_PROC) - seq_printf(s, " | | "); + seq_puts(s, " | | "); if (lat) - seq_printf(s, "||||"); + seq_puts(s, "||||"); if (flags & TRACE_GRAPH_PRINT_DURATION) - seq_printf(s, " | | "); - seq_printf(s, " | | | |\n"); + seq_puts(s, " | | "); + seq_puts(s, " | | | |\n"); } static void print_graph_headers(struct seq_file *s) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 282f6e4e5539..240d27ddf82e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -826,7 +826,7 @@ static int probes_seq_show(struct seq_file *m, void *v) struct trace_kprobe *tk = v; int i; - seq_printf(m, "%c", trace_kprobe_is_return(tk) ? 'r' : 'p'); + seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p'); seq_printf(m, ":%s/%s", tk->tp.call.class->system, ftrace_event_name(&tk->tp.call)); @@ -840,7 +840,7 @@ static int probes_seq_show(struct seq_file *m, void *v) for (i = 0; i < tk->tp.nr_args; i++) seq_printf(m, " %s=%s", tk->tp.args[i].name, tk->tp.args[i].comm); - seq_printf(m, "\n"); + seq_putc(m, '\n'); return 0; } diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 33ff6a24b802..d22117beedd0 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -606,7 +606,7 @@ static int probes_seq_show(struct seq_file *m, void *v) for (i = 0; i < tu->tp.nr_args; i++) seq_printf(m, " %s=%s", tu->tp.args[i].name, tu->tp.args[i].comm); - seq_printf(m, "\n"); + seq_putc(m, '\n'); return 0; } -- GitLab From d79ac28fde9c245473ba5f337341eb5823c7ebfc Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 8 Nov 2014 21:42:11 +0100 Subject: [PATCH 4715/9457] tracing: Merge consecutive seq_puts calls Consecutive seq_puts calls with literal strings can be merged to a single call. This reduces the size of the generated code, and can also lead to slight .rodata reduction (because of fewer nul and padding bytes). It should also shave a off a few clock cycles. Link: http://lkml.kernel.org/r/1415479332-25944-3-git-send-email-linux@rasmusvillemoes.dk Signed-off-by: Rasmus Villemoes Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 64 ++++++++++++++++++------------------- kernel/trace/trace_branch.c | 14 ++++---- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a419db75152c..44d561426700 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2509,14 +2509,14 @@ get_total_entries(struct trace_buffer *buf, static void print_lat_help_header(struct seq_file *m) { - seq_puts(m, "# _------=> CPU# \n"); - seq_puts(m, "# / _-----=> irqs-off \n"); - seq_puts(m, "# | / _----=> need-resched \n"); - seq_puts(m, "# || / _---=> hardirq/softirq \n"); - seq_puts(m, "# ||| / _--=> preempt-depth \n"); - seq_puts(m, "# |||| / delay \n"); - seq_puts(m, "# cmd pid ||||| time | caller \n"); - seq_puts(m, "# \\ / ||||| \\ | / \n"); + seq_puts(m, "# _------=> CPU# \n" + "# / _-----=> irqs-off \n" + "# | / _----=> need-resched \n" + "# || / _---=> hardirq/softirq \n" + "# ||| / _--=> preempt-depth \n" + "# |||| / delay \n" + "# cmd pid ||||| time | caller \n" + "# \\ / ||||| \\ | / \n"); } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) @@ -2533,20 +2533,20 @@ static void print_event_info(struct trace_buffer *buf, struct seq_file *m) static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) { print_event_info(buf, m); - seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); - seq_puts(m, "# | | | | |\n"); + seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n" + "# | | | | |\n"); } static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) { print_event_info(buf, m); - seq_puts(m, "# _-----=> irqs-off\n"); - seq_puts(m, "# / _----=> need-resched\n"); - seq_puts(m, "# | / _---=> hardirq/softirq\n"); - seq_puts(m, "# || / _--=> preempt-depth\n"); - seq_puts(m, "# ||| / delay\n"); - seq_puts(m, "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n"); - seq_puts(m, "# | | | |||| | |\n"); + seq_puts(m, "# _-----=> irqs-off\n" + "# / _----=> need-resched\n" + "# | / _---=> hardirq/softirq\n" + "# || / _--=> preempt-depth\n" + "# ||| / delay\n" + "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n" + "# | | | |||| | |\n"); } void @@ -2860,34 +2860,34 @@ static void test_ftrace_alive(struct seq_file *m) { if (!ftrace_is_dead()) return; - seq_puts(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); - seq_puts(m, "# MAY BE MISSING FUNCTION EVENTS\n"); + seq_puts(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n" + "# MAY BE MISSING FUNCTION EVENTS\n"); } #ifdef CONFIG_TRACER_MAX_TRACE static void show_snapshot_main_help(struct seq_file *m) { - seq_puts(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); - seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); - seq_puts(m, "# Takes a snapshot of the main buffer.\n"); - seq_puts(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n"); - seq_puts(m, "# (Doesn't have to be '2' works with any number that\n"); - seq_puts(m, "# is not a '0' or '1')\n"); + seq_puts(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n" + "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n" + "# Takes a snapshot of the main buffer.\n" + "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n" + "# (Doesn't have to be '2' works with any number that\n" + "# is not a '0' or '1')\n"); } static void show_snapshot_percpu_help(struct seq_file *m) { seq_puts(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP - seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); - seq_puts(m, "# Takes a snapshot of the main buffer for this cpu.\n"); + seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n" + "# Takes a snapshot of the main buffer for this cpu.\n"); #else - seq_puts(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); - seq_puts(m, "# Must use main snapshot file to allocate.\n"); + seq_puts(m, "# echo 1 > snapshot : Not supported with this kernel.\n" + "# Must use main snapshot file to allocate.\n"); #endif - seq_puts(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); - seq_puts(m, "# (Doesn't have to be '2' works with any number that\n"); - seq_puts(m, "# is not a '0' or '1')\n"); + seq_puts(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n" + "# (Doesn't have to be '2' works with any number that\n" + "# is not a '0' or '1')\n"); } static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index 126c622e4f42..a3916f68a1c7 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -164,9 +164,9 @@ static enum print_line_t trace_branch_print(struct trace_iterator *iter, static void branch_print_header(struct seq_file *s) { seq_puts(s, "# TASK-PID CPU# TIMESTAMP CORRECT" - " FUNC:FILE:LINE\n"); - seq_puts(s, "# | | | | | " - " |\n"); + " FUNC:FILE:LINE\n" + "# | | | | | " + " |\n"); } static struct trace_event_functions trace_branch_funcs = { @@ -233,8 +233,8 @@ extern unsigned long __stop_annotated_branch_profile[]; static int annotated_branch_stat_headers(struct seq_file *m) { - seq_puts(m, " correct incorrect % "); - seq_puts(m, " Function " + seq_puts(m, " correct incorrect % " + " Function " " File Line\n" " ------- --------- - " " -------- " @@ -362,8 +362,8 @@ extern unsigned long __stop_branch_profile[]; static int all_branch_stat_headers(struct seq_file *m) { - seq_puts(m, " miss hit % "); - seq_puts(m, " Function " + seq_puts(m, " miss hit % " + " Function " " File Line\n" " ------- --------- - " " -------- " -- GitLab From 9e819963b45f79e87f5a8c44960a66c0727c80e6 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sun, 2 Nov 2014 20:02:42 +0530 Subject: [PATCH 4716/9457] powerpc: Disable CPU_FTR_TM if TM is disabled by firmware Firmware is allowed to communicate to us via the "ibm,pa-features" property that TM (Transactional Memory) support is disabled. Currently this doesn't happen on any platform we're aware of, but we should honor it anyway. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 6af05fc1dec9..6a799b3cc6b4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -160,6 +160,12 @@ static struct ibm_pa_feature { {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, + /* + * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n), + * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP + * which is 0 if the kernel doesn't support TM. + */ + {CPU_FTR_TM_COMP, 0, 0, 22, 0, 0}, }; static void __init scan_features(unsigned long node, const unsigned char *ftrs, -- GitLab From 06743521d0eae1263a09bccb1a92a9fbb94660b3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 5 Nov 2014 21:57:39 +0530 Subject: [PATCH 4717/9457] powerpc/mm: Add missing pmd accessors This patch add documentation and missing accessors. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pgtable-ppc64-4k.h | 16 +++++- arch/powerpc/include/asm/pgtable-ppc64-64k.h | 3 ++ arch/powerpc/include/asm/pgtable-ppc64.h | 51 +++++++++++++++----- arch/powerpc/mm/hugetlbpage.c | 3 ++ arch/powerpc/mm/pgtable_64.c | 22 +++++++-- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h index 7b935683f268..132ee1d482c2 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h +++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h @@ -57,7 +57,21 @@ #define pgd_present(pgd) (pgd_val(pgd) != 0) #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) #define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) -#define pgd_page(pgd) virt_to_page(pgd_page_vaddr(pgd)) + +#ifndef __ASSEMBLY__ + +static inline pte_t pgd_pte(pgd_t pgd) +{ + return __pte(pgd_val(pgd)); +} + +static inline pgd_t pte_pgd(pte_t pte) +{ + return __pgd(pte_val(pte)); +} +extern struct page *pgd_page(pgd_t pgd); + +#endif /* !__ASSEMBLY__ */ #define pud_offset(pgdp, addr) \ (((pud_t *) pgd_page_vaddr(*(pgdp))) + \ diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h index a56b82fb0609..1de35bbd02a6 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h +++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h @@ -38,4 +38,7 @@ /* Bits to mask out from a PGD/PUD to get to the PMD page */ #define PUD_MASKED_BITS 0x1ff +#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) +#define pte_pgd(pte) ((pgd_t)pte_pud(pte)) + #endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */ diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index ae153c40ab7c..d12092420560 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -152,7 +152,7 @@ #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ || (pmd_val(pmd) & PMD_BAD_BITS)) -#define pmd_present(pmd) (pmd_val(pmd) != 0) +#define pmd_present(pmd) (!pmd_none(pmd)) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) #define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) extern struct page *pmd_page(pmd_t pmd); @@ -164,9 +164,21 @@ extern struct page *pmd_page(pmd_t pmd); #define pud_present(pud) (pud_val(pud) != 0) #define pud_clear(pudp) (pud_val(*(pudp)) = 0) #define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) -#define pud_page(pud) virt_to_page(pud_page_vaddr(pud)) +extern struct page *pud_page(pud_t pud); + +static inline pte_t pud_pte(pud_t pud) +{ + return __pte(pud_val(pud)); +} + +static inline pud_t pte_pud(pte_t pte) +{ + return __pud(pte_val(pte)); +} +#define pud_write(pud) pte_write(pud_pte(pud)) #define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) +#define pgd_write(pgd) pte_write(pgd_pte(pgd)) /* * Find an entry in a page-table-directory. We combine the address region @@ -422,7 +434,22 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd); extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd); - +/* + * + * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs + * page. The hugetlbfs page table walking and mangling paths are totally + * separated form the core VM paths and they're differentiated by + * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run. + * + * pmd_trans_huge() is defined as false at build time if + * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build + * time in such case. + * + * For ppc64 we need to differntiate from explicit hugepages from THP, because + * for THP we also track the subpage details at the pmd level. We don't do + * that for explicit huge pages. + * + */ static inline int pmd_trans_huge(pmd_t pmd) { /* @@ -431,16 +458,6 @@ static inline int pmd_trans_huge(pmd_t pmd) return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); } -static inline int pmd_large(pmd_t pmd) -{ - /* - * leaf pte for huge page, bottom two bits != 00 - */ - if (pmd_trans_huge(pmd)) - return pmd_val(pmd) & _PAGE_PRESENT; - return 0; -} - static inline int pmd_trans_splitting(pmd_t pmd) { if (pmd_trans_huge(pmd)) @@ -451,6 +468,14 @@ static inline int pmd_trans_splitting(pmd_t pmd) extern int has_transparent_hugepage(void); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +static inline int pmd_large(pmd_t pmd) +{ + /* + * leaf pte for huge page, bottom two bits != 00 + */ + return ((pmd_val(pmd) & 0x3) != 0x0); +} + static inline pte_t pmd_pte(pmd_t pmd) { return __pte(pmd_val(pmd)); diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index b460e723f0ec..2b8e5ed28831 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -62,6 +62,9 @@ static unsigned nr_gpages; /* * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; + * + * Defined in such a way that we can optimize away code block at build time + * if CONFIG_HUGETLB_PAGE=n. */ int pmd_huge(pmd_t pmd) { diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index e0c718543174..87ff0c1908a9 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -344,16 +345,31 @@ EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(__iounmap); EXPORT_SYMBOL(__iounmap_at); +#ifndef __PAGETABLE_PUD_FOLDED +/* 4 level page table */ +struct page *pgd_page(pgd_t pgd) +{ + if (pgd_huge(pgd)) + return pte_page(pgd_pte(pgd)); + return virt_to_page(pgd_page_vaddr(pgd)); +} +#endif + +struct page *pud_page(pud_t pud) +{ + if (pud_huge(pud)) + return pte_page(pud_pte(pud)); + return virt_to_page(pud_page_vaddr(pud)); +} + /* * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address. */ struct page *pmd_page(pmd_t pmd) { -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - if (pmd_trans_huge(pmd)) + if (pmd_trans_huge(pmd) || pmd_huge(pmd)) return pfn_to_page(pmd_pfn(pmd)); -#endif return virt_to_page(pmd_page_vaddr(pmd)); } -- GitLab From f30c59e921f12b209852e1ddc197dc6a8fb0142b Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 5 Nov 2014 21:57:40 +0530 Subject: [PATCH 4718/9457] mm: Update generic gup implementation to handle hugepage directory Update generic gup implementation with powerpc specific details. On powerpc at pmd level we can have hugepte, normal pmd pointer or a pointer to the hugepage directory. Tested-by: Steve Capper Acked-by: Steve Capper Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/page.h | 1 + include/linux/hugetlb.h | 46 +++++++++++++++++++ mm/gup.c | 81 +++++++++++++++++++++++++++++---- 3 files changed, 120 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 26fe1ae15212..f973fce73a43 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -380,6 +380,7 @@ static inline int hugepd_ok(hugepd_t hpd) #endif #define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) +#define pgd_huge pgd_huge int pgd_huge(pgd_t pgd); #else /* CONFIG_HUGETLB_PAGE */ #define is_hugepd(pdep) 0 diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 6e6d338641fe..e6b62f30ab21 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -175,6 +175,52 @@ static inline void __unmap_hugepage_range(struct mmu_gather *tlb, } #endif /* !CONFIG_HUGETLB_PAGE */ +/* + * hugepages at page global directory. If arch support + * hugepages at pgd level, they need to define this. + */ +#ifndef pgd_huge +#define pgd_huge(x) 0 +#endif + +#ifndef pgd_write +static inline int pgd_write(pgd_t pgd) +{ + BUG(); + return 0; +} +#endif + +#ifndef pud_write +static inline int pud_write(pud_t pud) +{ + BUG(); + return 0; +} +#endif + +#ifndef is_hugepd +/* + * Some architectures requires a hugepage directory format that is + * required to support multiple hugepage sizes. For example + * a4fe3ce76 "powerpc/mm: Allow more flexible layouts for hugepage pagetables" + * introduced the same on powerpc. This allows for a more flexible hugepage + * pagetable layout. + */ +typedef struct { unsigned long pd; } hugepd_t; +#define is_hugepd(hugepd) (0) +#define __hugepd(x) ((hugepd_t) { (x) }) +static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr, + unsigned pdshift, unsigned long end, + int write, struct page **pages, int *nr) +{ + return 0; +} +#else +extern int gup_huge_pd(hugepd_t hugepd, unsigned long addr, + unsigned pdshift, unsigned long end, + int write, struct page **pages, int *nr); +#endif #define HUGETLB_ANON_FILE "anon_hugepage" diff --git a/mm/gup.c b/mm/gup.c index cd62c8c90d4a..0ca1df9075ab 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -12,6 +11,7 @@ #include #include +#include #include #include "internal.h" @@ -875,6 +875,49 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, return 1; } +static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, + unsigned long end, int write, + struct page **pages, int *nr) +{ + int refs; + struct page *head, *page, *tail; + + if (write && !pgd_write(orig)) + return 0; + + refs = 0; + head = pgd_page(orig); + page = head + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT); + tail = page; + do { + VM_BUG_ON_PAGE(compound_head(page) != head, page); + pages[*nr] = page; + (*nr)++; + page++; + refs++; + } while (addr += PAGE_SIZE, addr != end); + + if (!page_cache_add_speculative(head, refs)) { + *nr -= refs; + return 0; + } + + if (unlikely(pgd_val(orig) != pgd_val(*pgdp))) { + *nr -= refs; + while (refs--) + put_page(head); + return 0; + } + + while (refs--) { + if (PageTail(tail)) + get_huge_page_tail(tail); + tail++; + } + + return 1; +} + static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { @@ -902,6 +945,14 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, pages, nr)) return 0; + } else if (unlikely(is_hugepd(__hugepd(pmd_val(pmd))))) { + /* + * architecture have different format for hugetlbfs + * pmd format and THP pmd format + */ + if (!gup_huge_pd(__hugepd(pmd_val(pmd)), addr, + PMD_SHIFT, next, write, pages, nr)) + return 0; } else if (!gup_pte_range(pmd, addr, next, write, pages, nr)) return 0; } while (pmdp++, addr = next, addr != end); @@ -909,22 +960,26 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, return 1; } -static int gup_pud_range(pgd_t *pgdp, unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) +static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, + int write, struct page **pages, int *nr) { unsigned long next; pud_t *pudp; - pudp = pud_offset(pgdp, addr); + pudp = pud_offset(&pgd, addr); do { pud_t pud = ACCESS_ONCE(*pudp); next = pud_addr_end(addr, end); if (pud_none(pud)) return 0; - if (pud_huge(pud)) { + if (unlikely(pud_huge(pud))) { if (!gup_huge_pud(pud, pudp, addr, next, write, - pages, nr)) + pages, nr)) + return 0; + } else if (unlikely(is_hugepd(__hugepd(pud_val(pud))))) { + if (!gup_huge_pd(__hugepd(pud_val(pud)), addr, + PUD_SHIFT, next, write, pages, nr)) return 0; } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) return 0; @@ -970,10 +1025,20 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, local_irq_save(flags); pgdp = pgd_offset(mm, addr); do { + pgd_t pgd = ACCESS_ONCE(*pgdp); + next = pgd_addr_end(addr, end); - if (pgd_none(*pgdp)) + if (pgd_none(pgd)) break; - else if (!gup_pud_range(pgdp, addr, next, write, pages, &nr)) + if (unlikely(pgd_huge(pgd))) { + if (!gup_huge_pgd(pgd, pgdp, addr, next, write, + pages, &nr)) + break; + } else if (unlikely(is_hugepd(__hugepd(pgd_val(pgd))))) { + if (!gup_huge_pd(__hugepd(pgd_val(pgd)), addr, + PGDIR_SHIFT, next, write, pages, &nr)) + break; + } else if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) break; } while (pgdp++, addr = next, addr != end); local_irq_restore(flags); -- GitLab From b30e759072c182538abb6908681cfd49978ba5e2 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 5 Nov 2014 21:57:41 +0530 Subject: [PATCH 4719/9457] powerpc/mm: Switch to generic RCU get_user_pages_fast This patch switch the ppc arch to use the generic RCU based gup implementation. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/hugetlb.h | 8 +- arch/powerpc/include/asm/page.h | 3 +- arch/powerpc/include/asm/pgtable-ppc64.h | 1 - arch/powerpc/include/asm/pgtable.h | 6 +- arch/powerpc/mm/Makefile | 2 +- arch/powerpc/mm/gup.c | 235 ----------------------- arch/powerpc/mm/hugetlbpage.c | 33 ++-- 8 files changed, 22 insertions(+), 267 deletions(-) delete mode 100644 arch/powerpc/mm/gup.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 98e9c548bd75..46227336aacb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -149,6 +149,7 @@ config PPC select ARCH_SUPPORTS_ATOMIC_RMW select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN select NO_BOOTMEM + select HAVE_GENERIC_RCU_GUP config GENERIC_CSUM def_bool CPU_LITTLE_ENDIAN diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 766b77d527ac..1d53a65b4ec1 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -48,7 +48,7 @@ static inline unsigned int hugepd_shift(hugepd_t hpd) #endif /* CONFIG_PPC_BOOK3S_64 */ -static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, +static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr, unsigned pdshift) { /* @@ -58,9 +58,9 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, */ unsigned long idx = 0; - pte_t *dir = hugepd_page(*hpdp); + pte_t *dir = hugepd_page(hpd); #ifndef CONFIG_PPC_FSL_BOOK3E - idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp); + idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd); #endif return dir + idx; @@ -193,7 +193,7 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma, } #define hugepd_shift(x) 0 -static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, +static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr, unsigned pdshift) { return 0; diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index f973fce73a43..69c059887a2c 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -379,13 +379,14 @@ static inline int hugepd_ok(hugepd_t hpd) } #endif -#define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) +#define is_hugepd(hpd) (hugepd_ok(hpd)) #define pgd_huge pgd_huge int pgd_huge(pgd_t pgd); #else /* CONFIG_HUGETLB_PAGE */ #define is_hugepd(pdep) 0 #define pgd_huge(pgd) 0 #endif /* CONFIG_HUGETLB_PAGE */ +#define __hugepd(x) ((hugepd_t) { (x) }) struct page; extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index d12092420560..5600e434332f 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -600,6 +600,5 @@ static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, */ return true; } - #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */ diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 316f9a5da173..a8805fee0df9 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -274,11 +274,9 @@ extern void paging_init(void); */ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); -extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr); - extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr); + unsigned long end, int write, + struct page **pages, int *nr); #ifndef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_large(pmd) 0 #define has_transparent_hugepage() 0 diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 325e861616a1..438dcd3fd0d1 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -6,7 +6,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) -obj-y := fault.o mem.o pgtable.o gup.o mmap.o \ +obj-y := fault.o mem.o pgtable.o mmap.o \ init_$(CONFIG_WORD_SIZE).o \ pgtable_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c deleted file mode 100644 index d8746684f606..000000000000 --- a/arch/powerpc/mm/gup.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Lockless get_user_pages_fast for powerpc - * - * Copyright (C) 2008 Nick Piggin - * Copyright (C) 2008 Novell Inc. - */ -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __HAVE_ARCH_PTE_SPECIAL - -/* - * The performance critical leaf functions are made noinline otherwise gcc - * inlines everything into a single function which results in too much - * register pressure. - */ -static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr) -{ - unsigned long mask, result; - pte_t *ptep; - - result = _PAGE_PRESENT|_PAGE_USER; - if (write) - result |= _PAGE_RW; - mask = result | _PAGE_SPECIAL; - - ptep = pte_offset_kernel(&pmd, addr); - do { - pte_t pte = ACCESS_ONCE(*ptep); - struct page *page; - /* - * Similar to the PMD case, NUMA hinting must take slow path - */ - if (pte_numa(pte)) - return 0; - - if ((pte_val(pte) & mask) != result) - return 0; - VM_BUG_ON(!pfn_valid(pte_pfn(pte))); - page = pte_page(pte); - if (!page_cache_get_speculative(page)) - return 0; - if (unlikely(pte_val(pte) != pte_val(*ptep))) { - put_page(page); - return 0; - } - pages[*nr] = page; - (*nr)++; - - } while (ptep++, addr += PAGE_SIZE, addr != end); - - return 1; -} - -static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) -{ - unsigned long next; - pmd_t *pmdp; - - pmdp = pmd_offset(&pud, addr); - do { - pmd_t pmd = ACCESS_ONCE(*pmdp); - - next = pmd_addr_end(addr, end); - /* - * If we find a splitting transparent hugepage we - * return zero. That will result in taking the slow - * path which will call wait_split_huge_page() - * if the pmd is still in splitting state - */ - if (pmd_none(pmd) || pmd_trans_splitting(pmd)) - return 0; - if (pmd_huge(pmd) || pmd_large(pmd)) { - /* - * NUMA hinting faults need to be handled in the GUP - * slowpath for accounting purposes and so that they - * can be serialised against THP migration. - */ - if (pmd_numa(pmd)) - return 0; - - if (!gup_hugepte((pte_t *)pmdp, PMD_SIZE, addr, next, - write, pages, nr)) - return 0; - } else if (is_hugepd(pmdp)) { - if (!gup_hugepd((hugepd_t *)pmdp, PMD_SHIFT, - addr, next, write, pages, nr)) - return 0; - } else if (!gup_pte_range(pmd, addr, next, write, pages, nr)) - return 0; - } while (pmdp++, addr = next, addr != end); - - return 1; -} - -static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) -{ - unsigned long next; - pud_t *pudp; - - pudp = pud_offset(&pgd, addr); - do { - pud_t pud = ACCESS_ONCE(*pudp); - - next = pud_addr_end(addr, end); - if (pud_none(pud)) - return 0; - if (pud_huge(pud)) { - if (!gup_hugepte((pte_t *)pudp, PUD_SIZE, addr, next, - write, pages, nr)) - return 0; - } else if (is_hugepd(pudp)) { - if (!gup_hugepd((hugepd_t *)pudp, PUD_SHIFT, - addr, next, write, pages, nr)) - return 0; - } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) - return 0; - } while (pudp++, addr = next, addr != end); - - return 1; -} - -int __get_user_pages_fast(unsigned long start, int nr_pages, int write, - struct page **pages) -{ - struct mm_struct *mm = current->mm; - unsigned long addr, len, end; - unsigned long next; - unsigned long flags; - pgd_t *pgdp; - int nr = 0; - - pr_devel("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read"); - - start &= PAGE_MASK; - addr = start; - len = (unsigned long) nr_pages << PAGE_SHIFT; - end = start + len; - - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, - start, len))) - return 0; - - pr_devel(" aligned: %lx .. %lx\n", start, end); - - /* - * XXX: batch / limit 'nr', to avoid large irq off latency - * needs some instrumenting to determine the common sizes used by - * important workloads (eg. DB2), and whether limiting the batch size - * will decrease performance. - * - * It seems like we're in the clear for the moment. Direct-IO is - * the main guy that batches up lots of get_user_pages, and even - * they are limited to 64-at-a-time which is not so many. - */ - /* - * This doesn't prevent pagetable teardown, but does prevent - * the pagetables from being freed on powerpc. - * - * So long as we atomically load page table pointers versus teardown, - * we can follow the address down to the the page and take a ref on it. - */ - local_irq_save(flags); - - pgdp = pgd_offset(mm, addr); - do { - pgd_t pgd = ACCESS_ONCE(*pgdp); - - pr_devel(" %016lx: normal pgd %p\n", addr, - (void *)pgd_val(pgd)); - next = pgd_addr_end(addr, end); - if (pgd_none(pgd)) - break; - if (pgd_huge(pgd)) { - if (!gup_hugepte((pte_t *)pgdp, PGDIR_SIZE, addr, next, - write, pages, &nr)) - break; - } else if (is_hugepd(pgdp)) { - if (!gup_hugepd((hugepd_t *)pgdp, PGDIR_SHIFT, - addr, next, write, pages, &nr)) - break; - } else if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) - break; - } while (pgdp++, addr = next, addr != end); - - local_irq_restore(flags); - - return nr; -} - -int get_user_pages_fast(unsigned long start, int nr_pages, int write, - struct page **pages) -{ - struct mm_struct *mm = current->mm; - int nr, ret; - - start &= PAGE_MASK; - nr = __get_user_pages_fast(start, nr_pages, write, pages); - ret = nr; - - if (nr < nr_pages) { - pr_devel(" slow path ! nr = %d\n", nr); - - /* Try to get the remaining pages with get_user_pages */ - start += nr << PAGE_SHIFT; - pages += nr; - - down_read(&mm->mmap_sem); - ret = get_user_pages(current, mm, start, - nr_pages - nr, write, 0, pages, NULL); - up_read(&mm->mmap_sem); - - /* Have to be a bit careful with return values */ - if (nr > 0) { - if (ret < 0) - ret = nr; - else - ret += nr; - } - } - - return ret; -} - -#endif /* __HAVE_ARCH_PTE_SPECIAL */ diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 2b8e5ed28831..af56de82375d 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -233,7 +233,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift)) return NULL; - return hugepte_offset(hpdp, addr, pdshift); + return hugepte_offset(*hpdp, addr, pdshift); } #else @@ -273,7 +273,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift)) return NULL; - return hugepte_offset(hpdp, addr, pdshift); + return hugepte_offset(*hpdp, addr, pdshift); } #endif @@ -541,7 +541,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, do { pmd = pmd_offset(pud, addr); next = pmd_addr_end(addr, end); - if (!is_hugepd(pmd)) { + if (!is_hugepd(__hugepd(pmd_val(*pmd)))) { /* * if it is not hugepd pointer, we should already find * it cleared. @@ -590,7 +590,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, do { pud = pud_offset(pgd, addr); next = pud_addr_end(addr, end); - if (!is_hugepd(pud)) { + if (!is_hugepd(__hugepd(pud_val(*pud)))) { if (pud_none_or_clear_bad(pud)) continue; hugetlb_free_pmd_range(tlb, pud, addr, next, floor, @@ -656,7 +656,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, do { next = pgd_addr_end(addr, end); pgd = pgd_offset(tlb->mm, addr); - if (!is_hugepd(pgd)) { + if (!is_hugepd(__hugepd(pgd_val(*pgd)))) { if (pgd_none_or_clear_bad(pgd)) continue; hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); @@ -716,12 +716,11 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end, return (__boundary - 1 < end - 1) ? __boundary : end; } -int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, - unsigned long addr, unsigned long end, - int write, struct page **pages, int *nr) +int gup_huge_pd(hugepd_t hugepd, unsigned long addr, unsigned pdshift, + unsigned long end, int write, struct page **pages, int *nr) { pte_t *ptep; - unsigned long sz = 1UL << hugepd_shift(*hugepd); + unsigned long sz = 1UL << hugepd_shift(hugepd); unsigned long next; ptep = hugepte_offset(hugepd, addr, pdshift); @@ -964,7 +963,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift else if (pgd_huge(pgd)) { ret_pte = (pte_t *) pgdp; goto out; - } else if (is_hugepd(&pgd)) + } else if (is_hugepd(__hugepd(pgd_val(pgd)))) hpdp = (hugepd_t *)&pgd; else { /* @@ -981,7 +980,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift else if (pud_huge(pud)) { ret_pte = (pte_t *) pudp; goto out; - } else if (is_hugepd(&pud)) + } else if (is_hugepd(__hugepd(pud_val(pud)))) hpdp = (hugepd_t *)&pud; else { pdshift = PMD_SHIFT; @@ -1002,7 +1001,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift if (pmd_huge(pmd) || pmd_large(pmd)) { ret_pte = (pte_t *) pmdp; goto out; - } else if (is_hugepd(&pmd)) + } else if (is_hugepd(__hugepd(pmd_val(pmd)))) hpdp = (hugepd_t *)&pmd; else return pte_offset_kernel(&pmd, ea); @@ -1011,7 +1010,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift if (!hpdp) return NULL; - ret_pte = hugepte_offset(hpdp, ea, pdshift); + ret_pte = hugepte_offset(*hpdp, ea, pdshift); pdshift = hugepd_shift(*hpdp); out: if (shift) @@ -1041,14 +1040,6 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, if ((pte_val(pte) & mask) != mask) return 0; -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - /* - * check for splitting here - */ - if (pmd_trans_splitting(pte_pmd(pte))) - return 0; -#endif - /* hugepages are never "special" */ VM_BUG_ON(!pfn_valid(pte_pfn(pte))); -- GitLab From 1665c4a892983ae5c0efa6ef88c00266e3537717 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:04 +1100 Subject: [PATCH 4720/9457] powerpc/powernv: Check PHB type in advance The patch checks PHB type a bit early to save a bit cycles for P7 because we don't support M64 for P7IOC no matter what OPAL firmware we have. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 468a0f23c7f2..7ab1dd732993 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -313,6 +313,12 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) const u32 *r; u64 pci_addr; + /* FIXME: Support M64 for P7IOC */ + if (phb->type != PNV_PHB_IODA2) { + pr_info(" Not support M64 window\n"); + return; + } + if (!firmware_has_feature(FW_FEATURE_OPALv3)) { pr_info(" Firmware too old to support M64 window\n"); return; @@ -325,12 +331,6 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) return; } - /* FIXME: Support M64 for P7IOC */ - if (phb->type != PNV_PHB_IODA2) { - pr_info(" Not support M64 window\n"); - return; - } - res = &hose->mem_resources[1]; res->start = of_translate_address(dn, r + 2); res->end = res->start + of_read_number(r + 4, 2) - 1; -- GitLab From 9e9e8935215d164cea2f49a7679cc0663c2253b6 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:05 +1100 Subject: [PATCH 4721/9457] powerpc/powernv: Fix condition to remove M64 The M64 resource should be removed if we don't have hook to initialize it, or (not and) fail to do that. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7ab1dd732993..7aa040441c08 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2000,8 +2000,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET); } - /* Configure M64 window */ - if (phb->init_m64 && phb->init_m64(phb)) + /* Remove M64 resource if we can't configure it successfully */ + if (!phb->init_m64 || phb->init_m64(phb)) hose->mem_resources[1].flags = 0; } -- GitLab From 5ef73567813cddabe5fd1105e915be0851820f4f Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:06 +1100 Subject: [PATCH 4722/9457] powerpc/powernv: Rename alloc_m64_pe() to reserve_m64_pe() The patch renames alloc_m64_pe() to reserve_m64_pe() to reflect its real usage: We reserve PE numbers for M64 segments in advance and then pick up the reserved PE numbers when building the mapping between PE numbers and M64 segments. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++---- arch/powerpc/platforms/powernv/pci.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7aa040441c08..cf90cce3dc9f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -172,7 +172,7 @@ static int pnv_ioda2_init_m64(struct pnv_phb *phb) return -EIO; } -static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb) +static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb) { resource_size_t sgsz = phb->ioda.m64_segsize; struct pci_dev *pdev; @@ -345,7 +345,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) /* Use last M64 BAR to cover M64 window */ phb->ioda.m64_bar_idx = 15; phb->init_m64 = pnv_ioda2_init_m64; - phb->alloc_m64_pe = pnv_ioda2_alloc_m64_pe; + phb->reserve_m64_pe = pnv_ioda2_reserve_m64_pe; phb->pick_m64_pe = pnv_ioda2_pick_m64_pe; } @@ -837,8 +837,8 @@ static void pnv_pci_ioda_setup_PEs(void) phb = hose->private_data; /* M64 layout might affect PE allocation */ - if (phb->alloc_m64_pe) - phb->alloc_m64_pe(phb); + if (phb->reserve_m64_pe) + phb->reserve_m64_pe(phb); pnv_ioda_setup_PEs(hose->bus); } diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 34d29eb2a4de..6c02ff8dd69f 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -130,7 +130,7 @@ struct pnv_phb { u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); void (*shutdown)(struct pnv_phb *phb); int (*init_m64)(struct pnv_phb *phb); - void (*alloc_m64_pe)(struct pnv_phb *phb); + void (*reserve_m64_pe)(struct pnv_phb *phb); int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all); int (*get_pe_state)(struct pnv_phb *phb, int pe_no); void (*freeze_pe)(struct pnv_phb *phb, int pe_no); -- GitLab From 4b82ab18033a7e8434e568a6485e6e5c2e5adb02 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:07 +1100 Subject: [PATCH 4723/9457] powerpc/powernv: Initialize M64 PE in time The patch initializes PE instance when reserving PE number to keep consistent things as we did before. Also, it replaces the iteration on bridge's windows with the prefered way. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 27 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index cf90cce3dc9f..7a7a68873df4 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -91,6 +91,24 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long flags) (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)); } +static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no) +{ + if (!(pe_no >= 0 && pe_no < phb->ioda.total_pe)) { + pr_warn("%s: Invalid PE %d on PHB#%x\n", + __func__, pe_no, phb->hose->global_number); + return; + } + + if (test_and_set_bit(pe_no, phb->ioda.pe_alloc)) { + pr_warn("%s: PE %d was assigned on PHB#%x\n", + __func__, pe_no, phb->hose->global_number); + return; + } + + phb->ioda.pe_array[pe_no].phb = phb; + phb->ioda.pe_array[pe_no].pe_number = pe_no; +} + static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -185,16 +203,15 @@ static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb) * instead of root bus. */ list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) { - for (i = PCI_BRIDGE_RESOURCES; - i <= PCI_BRIDGE_RESOURCE_END; i++) { - r = &pdev->resource[i]; + for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { + r = &pdev->resource[PCI_BRIDGE_RESOURCES + i]; if (!r->parent || !pnv_pci_is_mem_pref_64(r->flags)) continue; base = (r->start - phb->ioda.m64_base) / sgsz; for (step = 0; step < resource_size(r) / sgsz; step++) - set_bit(base + step, phb->ioda.pe_alloc); + pnv_ioda_reserve_pe(phb, base + step); } } } @@ -287,8 +304,6 @@ static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb, while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) < phb->ioda.total_pe) { pe = &phb->ioda.pe_array[i]; - pe->phb = phb; - pe->pe_number = i; if (!master_pe) { pe->flags |= PNV_IODA_PE_MASTER; -- GitLab From b131a8425c34b41ab280edc211fb026451d43264 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:08 +1100 Subject: [PATCH 4724/9457] powerpc/powernv: Set PELTV for compound PEs Commit 262af55 ("powerpc/powernv: Enable M64 aperatus for PHB3") introduced compound PEs in order to support M64 aperatus on PHB3. However, we never configured PELTV for compound PEs. The patch fixes that by: parent PE can freeze all child compound PEs. Any compound PE affects the group. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 118 +++++++++++++++++++--- 1 file changed, 102 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7a7a68873df4..b96ba48462f7 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -522,6 +522,106 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev) } #endif /* CONFIG_PCI_MSI */ +static int pnv_ioda_set_one_peltv(struct pnv_phb *phb, + struct pnv_ioda_pe *parent, + struct pnv_ioda_pe *child, + bool is_add) +{ + const char *desc = is_add ? "adding" : "removing"; + uint8_t op = is_add ? OPAL_ADD_PE_TO_DOMAIN : + OPAL_REMOVE_PE_FROM_DOMAIN; + struct pnv_ioda_pe *slave; + long rc; + + /* Parent PE affects child PE */ + rc = opal_pci_set_peltv(phb->opal_id, parent->pe_number, + child->pe_number, op); + if (rc != OPAL_SUCCESS) { + pe_warn(child, "OPAL error %ld %s to parent PELTV\n", + rc, desc); + return -ENXIO; + } + + if (!(child->flags & PNV_IODA_PE_MASTER)) + return 0; + + /* Compound case: parent PE affects slave PEs */ + list_for_each_entry(slave, &child->slaves, list) { + rc = opal_pci_set_peltv(phb->opal_id, parent->pe_number, + slave->pe_number, op); + if (rc != OPAL_SUCCESS) { + pe_warn(slave, "OPAL error %ld %s to parent PELTV\n", + rc, desc); + return -ENXIO; + } + } + + return 0; +} + +static int pnv_ioda_set_peltv(struct pnv_phb *phb, + struct pnv_ioda_pe *pe, + bool is_add) +{ + struct pnv_ioda_pe *slave; + struct pci_dev *pdev; + int ret; + + /* + * Clear PE frozen state. If it's master PE, we need + * clear slave PE frozen state as well. + */ + if (is_add) { + opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + if (pe->flags & PNV_IODA_PE_MASTER) { + list_for_each_entry(slave, &pe->slaves, list) + opal_pci_eeh_freeze_clear(phb->opal_id, + slave->pe_number, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + } + } + + /* + * Associate PE in PELT. We need add the PE into the + * corresponding PELT-V as well. Otherwise, the error + * originated from the PE might contribute to other + * PEs. + */ + ret = pnv_ioda_set_one_peltv(phb, pe, pe, is_add); + if (ret) + return ret; + + /* For compound PEs, any one affects all of them */ + if (pe->flags & PNV_IODA_PE_MASTER) { + list_for_each_entry(slave, &pe->slaves, list) { + ret = pnv_ioda_set_one_peltv(phb, slave, pe, is_add); + if (ret) + return ret; + } + } + + if (pe->flags & (PNV_IODA_PE_BUS_ALL | PNV_IODA_PE_BUS)) + pdev = pe->pbus->self; + else + pdev = pe->pdev->bus->self; + while (pdev) { + struct pci_dn *pdn = pci_get_pdn(pdev); + struct pnv_ioda_pe *parent; + + if (pdn && pdn->pe_number != IODA_INVALID_PE) { + parent = &phb->ioda.pe_array[pdn->pe_number]; + ret = pnv_ioda_set_one_peltv(phb, parent, pe, is_add); + if (ret) + return ret; + } + + pdev = pdev->bus->self; + } + + return 0; +} + static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) { struct pci_dev *parent; @@ -576,23 +676,9 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) return -ENXIO; } - rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, - pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); - if (rc) - pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc); - opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, - OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + /* Configure PELTV */ + pnv_ioda_set_peltv(phb, pe, true); - /* Add to all parents PELT-V */ - while (parent) { - struct pci_dn *pdn = pci_get_pdn(parent); - if (pdn && pdn->pe_number != IODA_INVALID_PE) { - rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, - pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); - /* XXX What to do in case of error ? */ - } - parent = parent->bus->self; - } /* Setup reverse map */ for (rid = pe->rid; rid < rid_end; rid++) phb->ioda.pe_rmap[rid] = pe->pe_number; -- GitLab From 4773f76b61e5cbf41ad514978d9338d8a7ed49e1 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:09 +1100 Subject: [PATCH 4725/9457] powerpc/powernv: Simplify pnv_ioda_configure_pe() Nested if statements are always bad and the patch avoids one by checking PHB type and bail in advance if necessary. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b96ba48462f7..762ca14228ea 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -684,26 +684,28 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) phb->ioda.pe_rmap[rid] = pe->pe_number; /* Setup one MVTs on IODA1 */ - if (phb->type == PNV_PHB_IODA1) { - pe->mve_number = pe->pe_number; - rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, - pe->pe_number); + if (phb->type != PNV_PHB_IODA1) { + pe->mve_number = 0; + goto out; + } + + pe->mve_number = pe->pe_number; + rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, pe->pe_number); + if (rc != OPAL_SUCCESS) { + pe_err(pe, "OPAL error %ld setting up MVE %d\n", + rc, pe->mve_number); + pe->mve_number = -1; + } else { + rc = opal_pci_set_mve_enable(phb->opal_id, + pe->mve_number, OPAL_ENABLE_MVE); if (rc) { - pe_err(pe, "OPAL error %ld setting up MVE %d\n", + pe_err(pe, "OPAL error %ld enabling MVE %d\n", rc, pe->mve_number); pe->mve_number = -1; - } else { - rc = opal_pci_set_mve_enable(phb->opal_id, - pe->mve_number, OPAL_ENABLE_MVE); - if (rc) { - pe_err(pe, "OPAL error %ld enabling MVE %d\n", - rc, pe->mve_number); - pe->mve_number = -1; - } } - } else if (phb->type == PNV_PHB_IODA2) - pe->mve_number = 0; + } +out: return 0; } -- GitLab From ec8e4e9d3d83b7a973477c2cb4831511b0eec06e Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:10 +1100 Subject: [PATCH 4726/9457] powerpc/powernv: Bail upon invalid master PE When freezing compound PEs in pnv_ioda_freeze_pe(), we should bail upon illegal master PE. We needn't freeze slave PE because it should have been put into frozen state by hardware. Reported-by: Anton Blanchard Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 762ca14228ea..d03503515692 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -373,7 +373,9 @@ static void pnv_ioda_freeze_pe(struct pnv_phb *phb, int pe_no) /* Fetch master PE */ if (pe->flags & PNV_IODA_PE_SLAVE) { pe = pe->master; - WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER)); + if (WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER))) + return; + pe_no = pe->pe_number; } -- GitLab From cf2b1e0eb0c281122b001cc879ca0118bff71255 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 12 Nov 2014 13:36:11 +1100 Subject: [PATCH 4727/9457] powerpc/powernv: Fix potential zero devisor If there're no PHBs under P5IOC2 HUB device tree node, we should bail early to avoid zero devisor and allocating TCE tables. Reported-by: Anton Blanchard Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-p5ioc2.c | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 94ce3481490b..3336fcbdd08a 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c @@ -196,6 +196,22 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) hub_id = be64_to_cpup(prop64); pr_info(" HUB-ID : 0x%016llx\n", hub_id); + /* Count child PHBs and calculate TCE space per PHB */ + for_each_child_of_node(np, phbn) { + if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || + of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) + phb_count++; + } + + if (phb_count <= 0) { + pr_info(" No PHBs for Hub %s\n", np->full_name); + return; + } + + tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); + pr_info(" Allocating %lld MB of TCE memory per PHB\n", + tce_per_phb >> 20); + /* Currently allocate 16M of TCE memory for every Hub * * XXX TODO: Make it chip local if possible @@ -215,18 +231,6 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) return; } - /* Count child PHBs */ - for_each_child_of_node(np, phbn) { - if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || - of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) - phb_count++; - } - - /* Calculate how much TCE space we can give per PHB */ - tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); - pr_info(" Allocating %lld MB of TCE memory per PHB\n", - tce_per_phb >> 20); - /* Initialize PHBs */ for_each_child_of_node(np, phbn) { if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || -- GitLab From 8cd4313aa775537f724486d5b7503b4d46c9f012 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 13 Nov 2014 22:21:30 -0800 Subject: [PATCH 4728/9457] openvswitch: Fix build failure. Add dependency on INET to fix following build error. I have also fixed MPLS dependency. ERROR: "ip_route_output_flow" [net/openvswitch/openvswitch.ko] undefined! make[1]: *** [__modpost] Error 1 Reported-by: Jim Davis Signed-off-by: Pravin B Shelar Signed-off-by: David S. Miller --- net/openvswitch/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 454ce12efbbf..b7d818c59423 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig @@ -4,7 +4,9 @@ config OPENVSWITCH tristate "Open vSwitch" + depends on INET select LIBCRC32C + select NET_MPLS_GSO ---help--- Open vSwitch is a multilayer Ethernet switch targeted at virtualized environments. In addition to supporting a variety of features @@ -30,8 +32,6 @@ config OPENVSWITCH config OPENVSWITCH_GRE tristate "Open vSwitch GRE tunneling support" - select NET_MPLS_GSO - depends on INET depends on OPENVSWITCH depends on NET_IPGRE_DEMUX default OPENVSWITCH @@ -45,7 +45,6 @@ config OPENVSWITCH_GRE config OPENVSWITCH_VXLAN tristate "Open vSwitch VXLAN tunneling support" - depends on INET depends on OPENVSWITCH depends on VXLAN default OPENVSWITCH @@ -58,7 +57,6 @@ config OPENVSWITCH_VXLAN config OPENVSWITCH_GENEVE tristate "Open vSwitch Geneve tunneling support" - depends on INET depends on OPENVSWITCH depends on GENEVE default OPENVSWITCH -- GitLab From 9547c0999e50fd624cab52f94a79f0fd27a7cb84 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 28 Oct 2014 14:22:49 -0700 Subject: [PATCH 4729/9457] ALSA: 6fire: Convert byte_rev_table uses to bitrev8 Use the inline function instead of directly indexing the array. This allows some architectures with hardware instructions for bit reversals to eliminate the array. Signed-off-by: Joe Perches Signed-off-by: Takashi Iwai --- sound/usb/6fire/firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 3b02e54b8f6d..62c25e74f0e5 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -316,7 +316,7 @@ static int usb6fire_fw_fpga_upload( while (c != end) { for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) - buffer[i] = byte_rev_table[(u8) *c]; + buffer[i] = bitrev8((u8)*c); ret = usb6fire_fw_fpga_write(device, buffer, i); if (ret < 0) { -- GitLab From 1d4e7e3c0bca747d0fc54069a6ab8393349431c0 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 6 Nov 2014 15:52:47 +0000 Subject: [PATCH 4730/9457] kvm: x86: increase user memory slots to 509 With the 3 private slots, this gives us 512 slots total. Motivation for this is in addition to assigned devices support more memory hotplug slots, where 1 slot is used by a hotplugged memory stick. It will allow to support upto 256 hotplug memory slots and leave 253 slots for assigned devices and other devices that use them. Signed-off-by: Igor Mammedov Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index dc932d388c43..769db36a3001 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -33,7 +33,7 @@ #define KVM_MAX_VCPUS 255 #define KVM_SOFT_MAX_VCPUS 160 -#define KVM_USER_MEM_SLOTS 125 +#define KVM_USER_MEM_SLOTS 509 /* memory slots that are not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 3 #define KVM_MEM_SLOTS_NUM (KVM_USER_MEM_SLOTS + KVM_PRIVATE_MEM_SLOTS) -- GitLab From e1f234bde6edb2bcdb763c90076b9484e4c71a33 Mon Sep 17 00:00:00 2001 From: Bob Paauwe Date: Tue, 11 Nov 2014 09:29:18 -0800 Subject: [PATCH 4731/9457] drm/i915: Use correct pipe config to update pll dividers. V2 Use the new pipe config values to calculate the updated pll dividers. This regression was introduced in commit 0dbdf89f27b17ae1eceed6782c2917f74cbb5d59 Author: Ander Conselvan de Oliveira Date: Wed Oct 29 11:32:33 2014 +0200 drm/i915: Add infrastructure for choosing DPLLs before disabling crtcs and commit 00d958817dd3daaa452c221387ddaf23d1e4c06f Author: Ander Conselvan de Oliveira Date: Wed Oct 29 11:32:36 2014 +0200 drm/i915: Covert remaining platforms to choose DPLLS before disabling CRTCs v2: Use intel_pipe_will_have_type() to look at new configuration - Ander Signed-off-by: Bob Paauwe CC: Ander Conselvan de Oliveira Tested-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ea607f340c76..9480a6173d78 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5733,24 +5733,24 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, u32 fp, fp2 = 0; if (IS_PINEVIEW(dev)) { - fp = pnv_dpll_compute_fp(&crtc->config.dpll); + fp = pnv_dpll_compute_fp(&crtc->new_config->dpll); if (reduced_clock) fp2 = pnv_dpll_compute_fp(reduced_clock); } else { - fp = i9xx_dpll_compute_fp(&crtc->config.dpll); + fp = i9xx_dpll_compute_fp(&crtc->new_config->dpll); if (reduced_clock) fp2 = i9xx_dpll_compute_fp(reduced_clock); } - crtc->config.dpll_hw_state.fp0 = fp; + crtc->new_config->dpll_hw_state.fp0 = fp; crtc->lowfreq_avail = false; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) && reduced_clock && i915.powersave) { - crtc->config.dpll_hw_state.fp1 = fp2; + crtc->new_config->dpll_hw_state.fp1 = fp2; crtc->lowfreq_avail = true; } else { - crtc->config.dpll_hw_state.fp1 = fp; + crtc->new_config->dpll_hw_state.fp1 = fp; } } -- GitLab From 6ccb81f2171ab48592946efab0ce0fd41978f4ba Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 8 Nov 2014 01:41:23 +0300 Subject: [PATCH 4732/9457] drm/i915: avoid deadlock on failure paths in __intel_framebuffer_create() Since a8bb6818270c __intel_framebuffer_create() is called with struct_mutex held, so it should use drm_gem_object_unreference() instead of drm_gem_object_unreference_unlocked(). Found by Linux Driver Verification project (linuxtesting.org). This regression has been introduced in commit a8bb6818270c32126dba0fd2ddb139d885c5687d Author: Daniel Vetter Date: Mon Feb 10 18:00:39 2014 +0100 drm/i915: Fix error path leak in fbdev fb allocation Signed-off-by: Alexey Khoroshilov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9480a6173d78..1509ab494f27 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8421,7 +8421,7 @@ __intel_framebuffer_create(struct drm_device *dev, intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); if (!intel_fb) { - drm_gem_object_unreference_unlocked(&obj->base); + drm_gem_object_unreference(&obj->base); return ERR_PTR(-ENOMEM); } @@ -8431,7 +8431,7 @@ __intel_framebuffer_create(struct drm_device *dev, return &intel_fb->base; err: - drm_gem_object_unreference_unlocked(&obj->base); + drm_gem_object_unreference(&obj->base); kfree(intel_fb); return ERR_PTR(ret); -- GitLab From 938fd8aaf5d5489957255530d1866332aeca7009 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 28 Oct 2014 16:20:48 +0200 Subject: [PATCH 4733/9457] drm/edid: fix Baseline_ELD_Len field in drm_edid_to_eld() The Baseline_ELD_Len field does not include ELD Header Block size. From High Definition Audio Specification, Revision 1.0a: The header block is a fixed size of 4 bytes. The baseline block is variable size in multiple of 4 bytes, and its size is defined in the header block Baseline_ELD_Len field (in number of DWords). Do not include the header size in Baseline_ELD_Len field. Fix all known users of eld[2]. While at it, switch to DIV_ROUND_UP instead of open coding it. Signed-off-by: Jani Nikula Acked-by: Ben Skeggs Reviewed-by: Rodrigo Vivi Acked-by: Dave Airlie [danvet: Fix compile fail in nouveau.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_edid.c | 7 +++++-- drivers/gpu/drm/i915/intel_audio.c | 16 ++++++++-------- drivers/gpu/drm/nouveau/nv50_display.c | 3 ++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3bf999134bcc..45aaa6f5ef36 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3128,9 +3128,12 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) } } eld[5] |= sad_count << 4; - eld[2] = (20 + mnl + sad_count * 3 + 3) / 4; - DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count); + eld[DRM_ELD_BASELINE_ELD_LEN] = + DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4); + + DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", + drm_eld_size(eld), sad_count); } EXPORT_SYMBOL(drm_edid_to_eld); diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 44c49dfe1096..87750ef018e6 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -107,7 +107,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector, tmp &= ~bits_elda; I915_WRITE(reg_elda, tmp); - for (i = 0; i < eld[2]; i++) + for (i = 0; i < drm_eld_size(eld) / 4; i++) if (I915_READ(reg_edid) != *((uint32_t *)eld + i)) return false; @@ -162,7 +162,7 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, len = (tmp >> 9) & 0x1f; /* ELD buffer size */ I915_WRITE(G4X_AUD_CNTL_ST, tmp); - len = min_t(int, eld[2], len); + len = min(drm_eld_size(eld) / 4, len); DRM_DEBUG_DRIVER("ELD size %d\n", len); for (i = 0; i < len; i++) I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i)); @@ -209,7 +209,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, int len, i; DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n", - pipe_name(pipe), eld[2]); + pipe_name(pipe), drm_eld_size(eld)); /* Enable audio presence detect, invalidate ELD */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); @@ -230,8 +230,8 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, I915_WRITE(HSW_AUD_DIP_ELD_CTRL(pipe), tmp); /* Up to 84 bytes of hw ELD buffer */ - len = min_t(int, eld[2], 21); - for (i = 0; i < len; i++) + len = min(drm_eld_size(eld), 84); + for (i = 0; i < len / 4; i++) I915_WRITE(HSW_AUD_EDID_DATA(pipe), *((uint32_t *)eld + i)); /* ELD valid */ @@ -320,7 +320,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, int aud_cntrl_st2; DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n", - port_name(port), pipe_name(pipe), eld[2]); + port_name(port), pipe_name(pipe), drm_eld_size(eld)); /* * FIXME: We're supposed to wait for vblank here, but we have vblanks @@ -364,8 +364,8 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, I915_WRITE(aud_cntl_st, tmp); /* Up to 84 bytes of hw ELD buffer */ - len = min_t(int, eld[2], 21); - for (i = 0; i < len; i++) + len = min(drm_eld_size(eld), 84); + for (i = 0; i < len / 4; i++) I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); /* ELD valid */ diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 76b8c4f980ea..4d939a89a1f5 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1681,7 +1681,8 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) drm_edid_to_eld(&nv_connector->base, nv_connector->edid); memcpy(args.data, nv_connector->base.eld, sizeof(args.data)); - nvif_mthd(disp->disp, 0, &args, sizeof(args.base) + args.data[2] * 4); + nvif_mthd(disp->disp, 0, &args, + sizeof(args.base) + drm_eld_size(args.data)); } static void -- GitLab From 198c974d7e80a5135fc4a2e69a07ba3e64122f8a Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Mon, 10 Nov 2014 13:44:31 +0000 Subject: [PATCH 4734/9457] drm/i915: Add tracepoints to track a vm during its lifetime - ppgtt init/release: these tracepoints are useful for observing the creation and destruction of Full PPGTTs. - ctx create/free: we can use the ctx_free trace in combination with the ppgtt_release one to be sure that the ppgtt doesn't stay alive for too long after the ctx is destroyed. ctx_create is there for simmetry - switch_mm: important point in the lifetime of the vm v4: add DOC information v5: pull the DOC in drm.tmpl v6: clean ppgtt init/release traces + add ctx create/free and switch_mm tracepoints (Chris) v7: drop execlist_submit_context tracepoint Cc: Chris Wilson Signed-off-by: Daniele Ceraolo Spurio Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 21 +++++ drivers/gpu/drm/i915/i915_gem_context.c | 6 ++ drivers/gpu/drm/i915/i915_gem_gtt.c | 4 + drivers/gpu/drm/i915/i915_trace.h | 104 ++++++++++++++++++++++++ 4 files changed, 135 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9d9977211b23..9449cd65f1d0 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -4001,6 +4001,27 @@ int num_ioctls; !Idrivers/gpu/drm/i915/intel_lrc.c + + + Tracing + + This sections covers all things related to the tracepoints implemented in + the i915 driver. + + + i915_ppgtt_create and i915_ppgtt_release +!Pdrivers/gpu/drm/i915/i915_trace.h i915_ppgtt_create and i915_ppgtt_release tracepoints + + + i915_context_create and i915_context_free +!Pdrivers/gpu/drm/i915/i915_trace.h i915_context_create and i915_context_free tracepoints + + + switch_mm +!Pdrivers/gpu/drm/i915/i915_trace.h switch_mm tracepoint + + + !Cdrivers/gpu/drm/i915/i915_irq.c diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 7d3257111737..1fb00008623d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -88,6 +88,7 @@ #include #include #include "i915_drv.h" +#include "i915_trace.h" /* This is a HW constraint. The value below is the largest known requirement * I've seen in a spec to date, and that was a workaround for a non-shipping @@ -137,6 +138,8 @@ void i915_gem_context_free(struct kref *ctx_ref) struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); + trace_i915_context_free(ctx); + if (i915.enable_execlists) intel_lr_context_free(ctx); @@ -274,6 +277,8 @@ i915_gem_create_context(struct drm_device *dev, ctx->ppgtt = ppgtt; } + trace_i915_context_create(ctx); + return ctx; err_unpin: @@ -549,6 +554,7 @@ static int do_switch(struct intel_engine_cs *ring, from = ring->last_context; if (to->ppgtt) { + trace_switch_mm(ring, to); ret = to->ppgtt->switch_mm(to->ppgtt, ring); if (ret) goto unpin_out; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index de12017c809b..4498a068a5a7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1174,6 +1174,8 @@ i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv) ppgtt->file_priv = fpriv; + trace_i915_ppgtt_create(&ppgtt->base); + return ppgtt; } @@ -1182,6 +1184,8 @@ void i915_ppgtt_release(struct kref *kref) struct i915_hw_ppgtt *ppgtt = container_of(kref, struct i915_hw_ppgtt, ref); + trace_i915_ppgtt_release(&ppgtt->base); + /* vmas should already be unbound */ WARN_ON(!list_empty(&ppgtt->base.active_list)); WARN_ON(!list_empty(&ppgtt->base.inactive_list)); diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index f5aa0067755a..751d4ad14d62 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -587,6 +587,110 @@ TRACE_EVENT(intel_gpu_freq_change, TP_printk("new_freq=%u", __entry->freq) ); +/** + * DOC: i915_ppgtt_create and i915_ppgtt_release tracepoints + * + * With full ppgtt enabled each process using drm will allocate at least one + * translation table. With these traces it is possible to keep track of the + * allocation and of the lifetime of the tables; this can be used during + * testing/debug to verify that we are not leaking ppgtts. + * These traces identify the ppgtt through the vm pointer, which is also printed + * by the i915_vma_bind and i915_vma_unbind tracepoints. + */ +DECLARE_EVENT_CLASS(i915_ppgtt, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm), + + TP_STRUCT__entry( + __field(struct i915_address_space *, vm) + __field(u32, dev) + ), + + TP_fast_assign( + __entry->vm = vm; + __entry->dev = vm->dev->primary->index; + ), + + TP_printk("dev=%u, vm=%p", __entry->dev, __entry->vm) +) + +DEFINE_EVENT(i915_ppgtt, i915_ppgtt_create, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm) +); + +DEFINE_EVENT(i915_ppgtt, i915_ppgtt_release, + TP_PROTO(struct i915_address_space *vm), + TP_ARGS(vm) +); + +/** + * DOC: i915_context_create and i915_context_free tracepoints + * + * These tracepoints are used to track creation and deletion of contexts. + * If full ppgtt is enabled, they also print the address of the vm assigned to + * the context. + */ +DECLARE_EVENT_CLASS(i915_context, + TP_PROTO(struct intel_context *ctx), + TP_ARGS(ctx), + + TP_STRUCT__entry( + __field(u32, dev) + __field(struct intel_context *, ctx) + __field(struct i915_address_space *, vm) + ), + + TP_fast_assign( + __entry->ctx = ctx; + __entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL; + __entry->dev = ctx->file_priv->dev_priv->dev->primary->index; + ), + + TP_printk("dev=%u, ctx=%p, ctx_vm=%p", + __entry->dev, __entry->ctx, __entry->vm) +) + +DEFINE_EVENT(i915_context, i915_context_create, + TP_PROTO(struct intel_context *ctx), + TP_ARGS(ctx) +); + +DEFINE_EVENT(i915_context, i915_context_free, + TP_PROTO(struct intel_context *ctx), + TP_ARGS(ctx) +); + +/** + * DOC: switch_mm tracepoint + * + * This tracepoint allows tracking of the mm switch, which is an important point + * in the lifetime of the vm in the legacy submission path. This tracepoint is + * called only if full ppgtt is enabled. + */ +TRACE_EVENT(switch_mm, + TP_PROTO(struct intel_engine_cs *ring, struct intel_context *to), + + TP_ARGS(ring, to), + + TP_STRUCT__entry( + __field(u32, ring) + __field(struct intel_context *, to) + __field(struct i915_address_space *, vm) + __field(u32, dev) + ), + + TP_fast_assign( + __entry->ring = ring->id; + __entry->to = to; + __entry->vm = to->ppgtt? &to->ppgtt->base : NULL; + __entry->dev = ring->dev->primary->index; + ), + + TP_printk("dev=%u, ring=%u, ctx=%p, ctx_vm=%p", + __entry->dev, __entry->ring, __entry->to, __entry->vm) +); + #endif /* _I915_TRACE_H_ */ /* This part must be outside protection */ -- GitLab From b8bbac1d01397ead65516f11adba1c7baf76a016 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 10 Nov 2014 14:47:30 -0200 Subject: [PATCH 4735/9457] drm/i915: use the correct obj when preparing the sprite plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit "drm/i915: create a prepare phase for sprite plane updates" changed the old_obj pointer we use when committing sprite planes, which caused a WARN() and a BUG() to be triggered. Later, commit "drm/i915: use intel_fb_obj() macros to assign gem objects" introduced the same problem to function intel_commit_sprite_plane(). Regression introduced by: commit ec82cb793c9224e0692eed904f43490cf70e8258 Author: Gustavo Padovan Date: Fri Oct 24 14:51:32 2014 +0100 drm/i915: create a prepare phase for sprite plane updates and: commit 77cde95217484e845743818691df026cec2534f4 Author: Gustavo Padovan Date: Fri Oct 24 14:51:33 2014 +0100 drm/i915: use intel_fb_obj() macros to assign gem objects Credits to Imre Deak for pointing out the exact lines that were wrong. v2: Also fix intel_commit_sprite_plane() (Ville) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85634 Testcase: igt/pm_rpm/legacy-planes Testcase: igt/pm_rpm/legacy-planes-dpms Testcase: igt/pm_rpm/universal-planes Testcase: igt/pm_rpm/universal-planes-dpms Credits-to: Imre Deak Cc: Gustavo Padovan Cc: Ville Syrjälä Signed-off-by: Paulo Zanoni Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 64076555153a..7d9c340f7693 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1264,10 +1264,11 @@ intel_prepare_sprite_plane(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct drm_crtc *crtc = state->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_plane *intel_plane = to_intel_plane(plane); enum pipe pipe = intel_crtc->pipe; struct drm_framebuffer *fb = state->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); - struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); + struct drm_i915_gem_object *old_obj = intel_plane->obj; int ret; if (old_obj != obj) { @@ -1302,7 +1303,7 @@ intel_commit_sprite_plane(struct drm_plane *plane, enum pipe pipe = intel_crtc->pipe; struct drm_framebuffer *fb = state->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); - struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); + struct drm_i915_gem_object *old_obj = intel_plane->obj; int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; uint32_t src_x, src_y, src_w, src_h; -- GitLab From 3e470eaaee5c064045a88ecc7a9cf75105bb52d8 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Tue, 28 Oct 2014 18:33:12 +0000 Subject: [PATCH 4736/9457] drm/i915/chv: Remove pre-production workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -WaDisableDopClockGating:chv -WaDisableSamplerPowerBypass:chv -WaDisableGunitClockGating:chv -WaDisableFfDopClockGating:chv -WaDisableDopClockGating:chv v2: Remove pre-production WA instead of restricting them based on revision id (Ville) For: VIZ-4090 Signed-off-by: Arun Siluvery Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 12 ------------ drivers/gpu/drm/i915/intel_ringbuffer.c | 8 -------- 2 files changed, 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 300d7e503f96..5764936e3a22 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6958,18 +6958,6 @@ static void cherryview_init_clock_gating(struct drm_device *dev) /* WaDisableSDEUnitClockGating:chv */ I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - - /* WaDisableGunitClockGating:chv (pre-production hw) */ - I915_WRITE(VLV_GUNIT_CLOCK_GATE, I915_READ(VLV_GUNIT_CLOCK_GATE) | - GINT_DIS); - - /* WaDisableFfDopClockGating:chv (pre-production hw) */ - I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, - _MASKED_BIT_ENABLE(GEN8_FF_DOP_CLOCK_GATE_DISABLE)); - - /* WaDisableDopClockGating:chv (pre-production hw) */ - I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | - GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); } static void g4x_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f457146ff6a4..70fcf2aa0ca2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -795,14 +795,6 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); - /* WaDisableDopClockGating:chv (pre-production hw) */ - WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, - DOP_CLOCK_GATING_DISABLE); - - /* WaDisableSamplerPowerBypass:chv (pre-production hw) */ - WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, - GEN8_SAMPLER_POWER_BYPASS_DIS); - return 0; } -- GitLab From 605f143320b637846674299c323b1893c93d8494 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Tue, 28 Oct 2014 18:33:13 +0000 Subject: [PATCH 4737/9457] drm/i915/chv: Combine GEN8_ROW_CHICKEN w/a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WaDisablePartialInstShootdown:chv and WaDisableThreadStallDopClockGating:chv are related to the same register so combine them. Signed-off-by: Arun Siluvery Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 70fcf2aa0ca2..1df79a952291 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -788,12 +788,10 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) struct drm_i915_private *dev_priv = dev->dev_private; /* WaDisablePartialInstShootdown:chv */ - WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, - PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); - /* WaDisableThreadStallDopClockGating:chv */ WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, - STALL_DOP_GATING_DISABLE); + PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | + STALL_DOP_GATING_DISABLE); return 0; } -- GitLab From 952890098a14043fe7acc5f595c6306c69baf40d Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Tue, 28 Oct 2014 18:33:14 +0000 Subject: [PATCH 4738/9457] drm/i915/chv: Add new workarounds for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +WaForceEnableNonCoherent:chv +WaHdcDisableFetchWhenMasked:chv For: VIZ-4090 Signed-off-by: Arun Siluvery Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d43fa0e627f8..97d3479ad92e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5131,6 +5131,7 @@ enum punit_power_well { /* GEN8 chicken */ #define HDC_CHICKEN0 0x7300 #define HDC_FORCE_NON_COHERENT (1<<4) +#define HDC_DONOT_FETCH_MEM_WHEN_MASKED (1<<11) #define HDC_FENCE_DEST_SLM_DISABLE (1<<14) /* WaCatErrorRejectionIssue */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1df79a952291..a09aae70e579 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -793,6 +793,16 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | STALL_DOP_GATING_DISABLE); + /* Use Force Non-Coherent whenever executing a 3D context. This is a + * workaround for a possible hang in the unlikely event a TLB + * invalidation occurs during a PSD flush. + */ + /* WaForceEnableNonCoherent:chv */ + /* WaHdcDisableFetchWhenMasked:chv */ + WA_SET_BIT_MASKED(HDC_CHICKEN0, + HDC_FORCE_NON_COHERENT | + HDC_DONOT_FETCH_MEM_WHEN_MASKED); + return 0; } -- GitLab From a72fbc3a14f071d75bccb07ab5148d44f0af77eb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 5 Nov 2014 20:48:31 +0200 Subject: [PATCH 4739/9457] drm/i915: unify gen6/gen8 pm irq helpers The helpers to enable/disable PM IRQs for GEN6 and GEN8 are the same except for the PM interrupt mask register, so abstract away this register in the GEN6 versions and use these everywhere. No functional change. Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 59 ++++++-------------------------- drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_pm.c | 2 +- 3 files changed, 11 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5fff2870a17b..cf991bdebf54 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -200,6 +200,11 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) ilk_update_gt_irq(dev_priv, mask, 0); } +static u32 gen6_pm_imr(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; +} + /** * snb_update_pm_irq - update GEN6_PMIMR * @dev_priv: driver private @@ -223,8 +228,8 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->pm_irq_mask) { dev_priv->pm_irq_mask = new_val; - I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); - POSTING_READ(GEN6_PMIMR); + I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_irq_mask); + POSTING_READ(gen6_pm_imr(dev_priv)); } } @@ -238,46 +243,6 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) snb_update_pm_irq(dev_priv, mask, 0); } -/** - * bdw_update_pm_irq - update GT interrupt 2 - * @dev_priv: driver private - * @interrupt_mask: mask of interrupt bits to update - * @enabled_irq_mask: mask of interrupt bits to enable - * - * Copied from the snb function, updated with relevant register offsets - */ -static void bdw_update_pm_irq(struct drm_i915_private *dev_priv, - uint32_t interrupt_mask, - uint32_t enabled_irq_mask) -{ - uint32_t new_val; - - assert_spin_locked(&dev_priv->irq_lock); - - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return; - - new_val = dev_priv->pm_irq_mask; - new_val &= ~interrupt_mask; - new_val |= (~enabled_irq_mask & interrupt_mask); - - if (new_val != dev_priv->pm_irq_mask) { - dev_priv->pm_irq_mask = new_val; - I915_WRITE(GEN8_GT_IMR(2), dev_priv->pm_irq_mask); - POSTING_READ(GEN8_GT_IMR(2)); - } -} - -void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) -{ - bdw_update_pm_irq(dev_priv, mask, mask); -} - -void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) -{ - bdw_update_pm_irq(dev_priv, mask, 0); -} - /** * ibx_display_interrupt_update - update SDEIMR * @dev_priv: driver private @@ -1118,12 +1083,8 @@ static void gen6_pm_rps_work(struct work_struct *work) spin_lock_irq(&dev_priv->irq_lock); pm_iir = dev_priv->rps.pm_iir; dev_priv->rps.pm_iir = 0; - if (INTEL_INFO(dev_priv->dev)->gen >= 8) - gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - else { - /* Make sure not to corrupt PMIMR state used by ringbuffer */ - gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - } + /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ + gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); /* Make sure we didn't queue anything we're not going to process. */ @@ -1332,7 +1293,7 @@ static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) spin_lock(&dev_priv->irq_lock); dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; - gen8_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); + gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); spin_unlock(&dev_priv->irq_lock); queue_work(dev_priv->wq, &dev_priv->rps.work); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5c622ad2e9aa..d93697a41a13 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -784,8 +784,6 @@ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); -void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); -void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5764936e3a22..9851af776aad 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4669,7 +4669,7 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev) spin_lock_irq(&dev_priv->irq_lock); WARN_ON(dev_priv->rps.pm_iir); - gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); + gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); } -- GitLab From c9a9a2688256b32af05e4f8c792b243419e41311 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 5 Nov 2014 20:48:37 +0200 Subject: [PATCH 4740/9457] drm/i915: unify gen6/gen8 rps irq handler After the previous patch the GEN8 RPS handler became very similar to the GEN6 version, so unify the two functions. No functional change. Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni [danvet: Move one misplaced hunk from a later patch to fix a bisect issue as reported by Wu Fengguang's 0-day builder and fix suggested by Imre.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index cf991bdebf54..4cda40a1840a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -138,6 +138,8 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ POSTING_READ(type##IMR); \ } while (0) +static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); + /* For display hotplug interrupt */ void ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) @@ -1286,19 +1288,6 @@ static void snb_gt_irq_handler(struct drm_device *dev, ivybridge_parity_error_irq_handler(dev, gt_iir); } -static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) -{ - if ((pm_iir & dev_priv->pm_rps_events) == 0) - return; - - spin_lock(&dev_priv->irq_lock); - dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; - gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); - spin_unlock(&dev_priv->irq_lock); - - queue_work(dev_priv->wq, &dev_priv->rps.work); -} - static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) @@ -1360,7 +1349,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, I915_WRITE(GEN8_GT_IIR(2), tmp & dev_priv->pm_rps_events); ret = IRQ_HANDLED; - gen8_rps_irq_handler(dev_priv, tmp); + gen6_rps_irq_handler(dev_priv, tmp); } else DRM_ERROR("The master control interrupt lied (PM)!\n"); } @@ -1669,6 +1658,9 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) queue_work(dev_priv->wq, &dev_priv->rps.work); } + if (INTEL_INFO(dev_priv)->gen >= 8) + return; + if (HAS_VEBOX(dev_priv->dev)) { if (pm_iir & PM_VEBOX_USER_INTERRUPT) notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); -- GitLab From 20415c5d4ecc0075cc7f5cb3f876e3191e9433ce Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 5 Nov 2014 20:48:42 +0200 Subject: [PATCH 4741/9457] drm/i915: unify gen6/gen8 rps irq enable/disable The GEN6 and GEN8 versions differ only in the PM IIR and IER register addresses and that on GEN8 we need to keep the GEN8_PMINTR_REDIRECT_TO_NON_DISP PM interrupt unmasked. Abstract away these 3 things in the GEN6 versions of the helpers and use them everywhere. No functional change. Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 53 ++++++++++----------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9851af776aad..ad4ffa9afaea 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4519,24 +4519,14 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val)); } -static void gen8_disable_rps_interrupts(struct drm_device *dev) +static u32 gen6_pm_iir(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(GEN6_PMINTRMSK, ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); - I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) & - ~dev_priv->pm_rps_events); - /* Complete PM interrupt masking here doesn't race with the rps work - * item again unmasking PM interrupts because that is using a different - * register (GEN8_GT_IMR(2)) to mask PM interrupts. The only risk is in - * leaving stale bits in GEN8_GT_IIR(2) and GEN8_GT_IMR(2) which - * gen8_enable_rps will clean up. */ - - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->rps.pm_iir = 0; - spin_unlock_irq(&dev_priv->irq_lock); + return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; +} - I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); +static u32 gen6_pm_ier(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; } static void gen9_disable_rps(struct drm_device *dev) @@ -4550,8 +4540,9 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); - I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & + I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? + ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); + I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & ~dev_priv->pm_rps_events); /* Complete PM interrupt masking here doesn't race with the rps work * item again unmasking PM interrupts because that is using a different @@ -4562,7 +4553,7 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev) dev_priv->rps.pm_iir = 0; spin_unlock_irq(&dev_priv->irq_lock); - I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events); + I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); } static void gen6_disable_rps(struct drm_device *dev) @@ -4572,10 +4563,7 @@ static void gen6_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_CONTROL, 0); I915_WRITE(GEN6_RPNSWREQ, 1 << 31); - if (IS_BROADWELL(dev)) - gen8_disable_rps_interrupts(dev); - else - gen6_disable_rps_interrupts(dev); + gen6_disable_rps_interrupts(dev); } static void cherryview_disable_rps(struct drm_device *dev) @@ -4584,7 +4572,7 @@ static void cherryview_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_CONTROL, 0); - gen8_disable_rps_interrupts(dev); + gen6_disable_rps_interrupts(dev); } static void valleyview_disable_rps(struct drm_device *dev) @@ -4663,17 +4651,6 @@ int intel_enable_rc6(const struct drm_device *dev) return i915.enable_rc6; } -static void gen8_enable_rps_interrupts(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - spin_lock_irq(&dev_priv->irq_lock); - WARN_ON(dev_priv->rps.pm_iir); - gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); - spin_unlock_irq(&dev_priv->irq_lock); -} - static void gen6_enable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4681,7 +4658,7 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) spin_lock_irq(&dev_priv->irq_lock); WARN_ON(dev_priv->rps.pm_iir); gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events); + I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); } @@ -4823,7 +4800,7 @@ static void gen8_enable_rps(struct drm_device *dev) gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); - gen8_enable_rps_interrupts(dev); + gen6_enable_rps_interrupts(dev); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } @@ -5414,7 +5391,7 @@ static void cherryview_enable_rps(struct drm_device *dev) valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq); - gen8_enable_rps_interrupts(dev); + gen6_enable_rps_interrupts(dev); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } -- GitLab From b900b949674464d6ede123fb352d3a63690e31ab Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 5 Nov 2014 20:48:48 +0200 Subject: [PATCH 4742/9457] drm/i915: move rps irq enable/disable to i915_irq.c The logical place for these functions is in i915_irq.c next to the rest of PM interrupt handling functions. No functional change. Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 41 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_pm.c | 41 -------------------------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4cda40a1840a..96d150f575d3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -202,11 +202,21 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) ilk_update_gt_irq(dev_priv, mask, 0); } +static u32 gen6_pm_iir(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; +} + static u32 gen6_pm_imr(struct drm_i915_private *dev_priv) { return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; } +static u32 gen6_pm_ier(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; +} + /** * snb_update_pm_irq - update GEN6_PMIMR * @dev_priv: driver private @@ -245,6 +255,37 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) snb_update_pm_irq(dev_priv, mask, 0); } +void gen6_enable_rps_interrupts(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir); + gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); + I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); + spin_unlock_irq(&dev_priv->irq_lock); +} + +void gen6_disable_rps_interrupts(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? + ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); + I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & + ~dev_priv->pm_rps_events); + /* Complete PM interrupt masking here doesn't race with the rps work + * item again unmasking PM interrupts because that is using a different + * register (PMIMR) to mask PM interrupts. The only risk is in leaving + * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ + + spin_lock_irq(&dev_priv->irq_lock); + dev_priv->rps.pm_iir = 0; + spin_unlock_irq(&dev_priv->irq_lock); + + I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); +} + /** * ibx_display_interrupt_update - update SDEIMR * @dev_priv: driver private diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d93697a41a13..24993486fd24 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -784,6 +784,8 @@ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); +void gen6_enable_rps_interrupts(struct drm_device *dev); +void gen6_disable_rps_interrupts(struct drm_device *dev); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ad4ffa9afaea..62ffb1b81dff 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4519,16 +4519,6 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val)); } -static u32 gen6_pm_iir(struct drm_i915_private *dev_priv) -{ - return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; -} - -static u32 gen6_pm_ier(struct drm_i915_private *dev_priv) -{ - return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; -} - static void gen9_disable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4536,26 +4526,6 @@ static void gen9_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_CONTROL, 0); } -static void gen6_disable_rps_interrupts(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? - ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); - I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & - ~dev_priv->pm_rps_events); - /* Complete PM interrupt masking here doesn't race with the rps work - * item again unmasking PM interrupts because that is using a different - * register (PMIMR) to mask PM interrupts. The only risk is in leaving - * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ - - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->rps.pm_iir = 0; - spin_unlock_irq(&dev_priv->irq_lock); - - I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); -} - static void gen6_disable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4651,17 +4621,6 @@ int intel_enable_rc6(const struct drm_device *dev) return i915.enable_rc6; } -static void gen6_enable_rps_interrupts(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - spin_lock_irq(&dev_priv->irq_lock); - WARN_ON(dev_priv->rps.pm_iir); - gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); - spin_unlock_irq(&dev_priv->irq_lock); -} - static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_cap) { /* All of these values are in units of 50MHz */ -- GitLab From 132f3f1767dbabfb01f3c9bd63098c65d91eeac9 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 10 Nov 2014 15:34:33 +0200 Subject: [PATCH 4743/9457] drm/i915: WARN if we receive any gen9 rps interrupts Paulo noticed that we don't support RPS on GEN9 yet, so WARN for and ignore any RPS interrupts on that platform. Signed-off-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 96d150f575d3..729e9a329f76 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1690,6 +1690,11 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) * the work queue. */ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) { + /* TODO: RPS on GEN9 is not supported yet. */ + if (WARN_ONCE(INTEL_INFO(dev_priv)->gen == 9, + "GEN9: unexpected RPS IRQ\n")) + return; + if (pm_iir & dev_priv->pm_rps_events) { spin_lock(&dev_priv->irq_lock); dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; -- GitLab From 6a2c4232ece145d8b5a8f95f767bd6d0d2d2f2bb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 4 Nov 2014 04:51:40 -0800 Subject: [PATCH 4744/9457] drm/i915: Make the physical object coherent with GTT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently objects for which the hardware needs a contiguous physical address are allocated a shadow backing storage to satisfy the contraint. This shadow buffer is not wired into the normal obj->pages and so the physical object is incoherent with accesses via the GPU, GTT and CPU. By setting up the appropriate scatter-gather table, we can allow userspace to access the physical object via either a GTT mmaping of or by rendering into the GEM bo. However, keeping the CPU mmap of the shmemfs backing storage coherent with the contiguous shadow is not yet possible. Fortuituously, CPU mmaps of objects requiring physical addresses are not expected to be coherent anyway. This allows the physical constraint of the GEM object to be transparent to userspace and allow it to efficiently render into or update them via the GTT and GPU. v2: Fix leak of pci handle spotted by Ville v3: Remove the now duplicate call to detach_phys_object during free. v4: Wait for rendering before pwrite. As this patch makes it possible to render into the phys object, we should make it correct as well! Signed-off-by: Chris Wilson Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 + drivers/gpu/drm/i915/i915_drv.h | 6 +- drivers/gpu/drm/i915/i915_gem.c | 207 ++++++++++++++++++++++---------- include/uapi/drm/i915_drm.h | 1 + 4 files changed, 150 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9a7353302b3f..5dc37f0233b2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1027,6 +1027,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_CMD_PARSER_VERSION: value = i915_cmd_parser_get_version(); break; + case I915_PARAM_HAS_COHERENT_PHYS_GTT: + value = 1; + break; default: DRM_DEBUG("Unknown parameter %d\n", param->param); return -EINVAL; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f830596faa9e..3df9ef32d011 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1957,10 +1957,10 @@ struct drm_i915_gem_object { unsigned long user_pin_count; struct drm_file *pin_filp; - /** for phy allocated objects */ - struct drm_dma_handle *phys_handle; - union { + /** for phy allocated objects */ + struct drm_dma_handle *phys_handle; + struct i915_gem_userptr { uintptr_t ptr; unsigned read_only :1; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3e0cabe9b544..86cf428b6c4e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -208,40 +208,137 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, return 0; } -static void i915_gem_object_detach_phys(struct drm_i915_gem_object *obj) +static int +i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) { - drm_dma_handle_t *phys = obj->phys_handle; + struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; + char *vaddr = obj->phys_handle->vaddr; + struct sg_table *st; + struct scatterlist *sg; + int i; - if (!phys) - return; + if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) + return -EINVAL; + + for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { + struct page *page; + char *src; + + page = shmem_read_mapping_page(mapping, i); + if (IS_ERR(page)) + return PTR_ERR(page); + + src = kmap_atomic(page); + memcpy(vaddr, src, PAGE_SIZE); + drm_clflush_virt_range(vaddr, PAGE_SIZE); + kunmap_atomic(src); + + page_cache_release(page); + vaddr += PAGE_SIZE; + } + + i915_gem_chipset_flush(obj->base.dev); + + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) + return -ENOMEM; + + if (sg_alloc_table(st, 1, GFP_KERNEL)) { + kfree(st); + return -ENOMEM; + } + + sg = st->sgl; + sg->offset = 0; + sg->length = obj->base.size; - if (obj->madv == I915_MADV_WILLNEED) { + sg_dma_address(sg) = obj->phys_handle->busaddr; + sg_dma_len(sg) = obj->base.size; + + obj->pages = st; + obj->has_dma_mapping = true; + return 0; +} + +static void +i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) +{ + int ret; + + BUG_ON(obj->madv == __I915_MADV_PURGED); + + ret = i915_gem_object_set_to_cpu_domain(obj, true); + if (ret) { + /* In the event of a disaster, abandon all caches and + * hope for the best. + */ + WARN_ON(ret != -EIO); + obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; + } + + if (obj->madv == I915_MADV_DONTNEED) + obj->dirty = 0; + + if (obj->dirty) { struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; - char *vaddr = phys->vaddr; + char *vaddr = obj->phys_handle->vaddr; int i; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { - struct page *page = shmem_read_mapping_page(mapping, i); - if (!IS_ERR(page)) { - char *dst = kmap_atomic(page); - memcpy(dst, vaddr, PAGE_SIZE); - drm_clflush_virt_range(dst, PAGE_SIZE); - kunmap_atomic(dst); - - set_page_dirty(page); + struct page *page; + char *dst; + + page = shmem_read_mapping_page(mapping, i); + if (IS_ERR(page)) + continue; + + dst = kmap_atomic(page); + drm_clflush_virt_range(vaddr, PAGE_SIZE); + memcpy(dst, vaddr, PAGE_SIZE); + kunmap_atomic(dst); + + set_page_dirty(page); + if (obj->madv == I915_MADV_WILLNEED) mark_page_accessed(page); - page_cache_release(page); - } + page_cache_release(page); vaddr += PAGE_SIZE; } - i915_gem_chipset_flush(obj->base.dev); + obj->dirty = 0; } -#ifdef CONFIG_X86 - set_memory_wb((unsigned long)phys->vaddr, phys->size / PAGE_SIZE); -#endif - drm_pci_free(obj->base.dev, phys); - obj->phys_handle = NULL; + sg_free_table(obj->pages); + kfree(obj->pages); + + obj->has_dma_mapping = false; +} + +static void +i915_gem_object_release_phys(struct drm_i915_gem_object *obj) +{ + drm_pci_free(obj->base.dev, obj->phys_handle); +} + +static const struct drm_i915_gem_object_ops i915_gem_phys_ops = { + .get_pages = i915_gem_object_get_pages_phys, + .put_pages = i915_gem_object_put_pages_phys, + .release = i915_gem_object_release_phys, +}; + +static int +drop_pages(struct drm_i915_gem_object *obj) +{ + struct i915_vma *vma, *next; + int ret; + + drm_gem_object_reference(&obj->base); + list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) + if (i915_vma_unbind(vma)) + break; + + ret = i915_gem_object_put_pages(obj); + drm_gem_object_unreference(&obj->base); + + return ret; } int @@ -249,9 +346,7 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) { drm_dma_handle_t *phys; - struct address_space *mapping; - char *vaddr; - int i; + int ret; if (obj->phys_handle) { if ((unsigned long)obj->phys_handle->vaddr & (align -1)) @@ -266,41 +361,19 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, if (obj->base.filp == NULL) return -EINVAL; + ret = drop_pages(obj); + if (ret) + return ret; + /* create a new object */ phys = drm_pci_alloc(obj->base.dev, obj->base.size, align); if (!phys) return -ENOMEM; - vaddr = phys->vaddr; -#ifdef CONFIG_X86 - set_memory_wc((unsigned long)vaddr, phys->size / PAGE_SIZE); -#endif - mapping = file_inode(obj->base.filp)->i_mapping; - for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { - struct page *page; - char *src; - - page = shmem_read_mapping_page(mapping, i); - if (IS_ERR(page)) { -#ifdef CONFIG_X86 - set_memory_wb((unsigned long)phys->vaddr, phys->size / PAGE_SIZE); -#endif - drm_pci_free(obj->base.dev, phys); - return PTR_ERR(page); - } - - src = kmap_atomic(page); - memcpy(vaddr, src, PAGE_SIZE); - kunmap_atomic(src); - - mark_page_accessed(page); - page_cache_release(page); - - vaddr += PAGE_SIZE; - } - obj->phys_handle = phys; - return 0; + obj->ops = &i915_gem_phys_ops; + + return i915_gem_object_get_pages(obj); } static int @@ -311,6 +384,14 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, struct drm_device *dev = obj->base.dev; void *vaddr = obj->phys_handle->vaddr + args->offset; char __user *user_data = to_user_ptr(args->data_ptr); + int ret; + + /* We manually control the domain here and pretend that it + * remains coherent i.e. in the GTT domain, like shmem_pwrite. + */ + ret = i915_gem_object_wait_rendering(obj, false); + if (ret) + return ret; if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { unsigned long unwritten; @@ -326,6 +407,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, return -EFAULT; } + drm_clflush_virt_range(vaddr, args->size); i915_gem_chipset_flush(dev); return 0; } @@ -1046,11 +1128,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj->phys_handle) { - ret = i915_gem_phys_pwrite(obj, args, file); - goto out; - } - if (obj->tiling_mode == I915_TILING_NONE && obj->base.write_domain != I915_GEM_DOMAIN_CPU && cpu_write_needs_clflush(obj)) { @@ -1060,8 +1137,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * textures). Fallback to the shmem path in that case. */ } - if (ret == -EFAULT || ret == -ENOSPC) - ret = i915_gem_shmem_pwrite(dev, obj, args, file); + if (ret == -EFAULT || ret == -ENOSPC) { + if (obj->phys_handle) + ret = i915_gem_phys_pwrite(obj, args, file); + else + ret = i915_gem_shmem_pwrite(dev, obj, args, file); + } out: drm_gem_object_unreference(&obj->base); @@ -3509,7 +3590,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, * Stolen memory is always coherent with the GPU as it is explicitly * marked as wc by the system, or the system is cache-coherent. */ - if (obj->stolen) + if (obj->stolen || obj->phys_handle) return false; /* If the GPU is snooping the contents of the CPU cache, @@ -4471,8 +4552,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) } } - i915_gem_object_detach_phys(obj); - /* Stolen objects don't hold a ref, but do hold pin count. Fix that up * before progressing. */ if (obj->stolen) diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 2ec0efcaa719..250262265ee3 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -340,6 +340,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXEC_HANDLE_LUT 26 #define I915_PARAM_HAS_WT 27 #define I915_PARAM_CMD_PARSER_VERSION 28 +#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29 typedef struct drm_i915_getparam { int param; -- GitLab From 23ec0a8835f38c6e43570b54a786e058a9b9a268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 11:15:59 +0200 Subject: [PATCH 4745/9457] drm/i915: Warn if trying to poke a VLV backlight on invalid pipe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VLV/CHV have backlight controls only on pipes A and B. Bail out without touching registers that don't exist, and print a warning. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e18b3f49074c..ef646b139c4e 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -521,6 +521,9 @@ static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return 0; + return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; } @@ -602,6 +605,9 @@ static void vlv_set_backlight(struct intel_connector *connector, u32 level) enum pipe pipe = intel_get_pipe_from_connector(connector); u32 tmp; + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return; + tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); } @@ -717,6 +723,9 @@ static void vlv_disable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); u32 tmp; + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return; + intel_panel_actually_set_backlight(connector, 0); tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); @@ -906,6 +915,9 @@ static void vlv_enable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); u32 ctl, ctl2; + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return; + ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); if (ctl2 & BLM_PWM_ENABLE) { DRM_DEBUG_KMS("backlight already enabled\n"); -- GitLab From 2d72f6c7be9cd26485f88961f6a56fae3d9d17e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 15:18:45 +0200 Subject: [PATCH 4746/9457] drm/i915: Skip .get_backlight() when backlight isn't enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On VLV/CHV when the display is off, we can't read out the current backlight level from the hardware since we have no pipe to do so. Currently we end up reading a bigus register due to passing INVALID_PIPE to VLV_BLC_PWM_CTL(). Skip the entire .get_backlight() call if the backlight isn't enabled according to backlight.enabled. This problem can be reproduced simply by reading the backlight device actual_brightness file while the display is off. Cc: Jani Nikula Suggested-by: Jani Nikula Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index ef646b139c4e..4ec6c2feef42 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -539,12 +539,15 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; + struct intel_panel *panel = &connector->panel; + u32 val = 0; mutex_lock(&dev_priv->backlight_lock); - val = dev_priv->display.get_backlight(connector); - val = intel_panel_compute_brightness(connector, val); + if (panel->backlight.enabled) { + val = dev_priv->display.get_backlight(connector); + val = intel_panel_compute_brightness(connector, val); + } mutex_unlock(&dev_priv->backlight_lock); -- GitLab From d3babd3fcd92f345ab3c627ad6bfa1463de52ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 11:16:01 +0200 Subject: [PATCH 4747/9457] drm/i915: Don't deref NULL crtc in intel_get_pipe_from_connector() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the connector would have an encoder but the encoder didn't have a crtc we might dereference a NULL crtc here. I suppose that should never happen due to intel_sanitize_encoder(), but let's be a bit paranoid print a warning if we ever hit this and return INVALID_PIPE to the caller. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1509ab494f27..7c2ecbe43ca5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11999,7 +11999,7 @@ enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - if (!encoder) + if (!encoder || WARN_ON(!encoder->crtc)) return INVALID_PIPE; return to_intel_crtc(encoder->crtc)->pipe; -- GitLab From 6517d2734d22b09d3c9dc44fe6879f013a716d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 11:16:02 +0200 Subject: [PATCH 4748/9457] drm/i915: Pass the current pipe from eDP init to backlight setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On VLV/CHV both pipes A and B have their own backlight control registers. In order to correctly read out the current hardware state at init we need to know which pipe is driving the eDP port. Pass that information down from the eDP init code into the backlight code. To determine the correct pipe we first look at which pipe is currently configured in the port control register, if that look invalid we look at which pipe's PPS is currently controlling the port, and if that too looks invalid we just assume pipe A. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_dp.c | 22 ++++++++++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_lvds.c | 2 +- drivers/gpu/drm/i915/intel_panel.c | 31 ++++++++++++++++-------------- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3df9ef32d011..45ca10937e3e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -510,7 +510,7 @@ struct drm_i915_display_funcs { /* display clock increase/decrease */ /* pll clock increase/decrease */ - int (*setup_backlight)(struct intel_connector *connector); + int (*setup_backlight)(struct intel_connector *connector, enum pipe pipe); uint32_t (*get_backlight)(struct intel_connector *connector); void (*set_backlight)(struct intel_connector *connector, uint32_t level); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 464eea0f7136..a16193fbfd49 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5212,6 +5212,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, bool has_dpcd; struct drm_display_mode *scan; struct edid *edid; + enum pipe pipe = INVALID_PIPE; intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED; @@ -5280,11 +5281,30 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (IS_VALLEYVIEW(dev)) { intel_dp->edp_notifier.notifier_call = edp_notify_handler; register_reboot_notifier(&intel_dp->edp_notifier); + + /* + * Figure out the current pipe for the initial backlight setup. + * If the current pipe isn't valid, try the PPS pipe, and if that + * fails just assume pipe A. + */ + if (IS_CHERRYVIEW(dev)) + pipe = DP_PORT_TO_PIPE_CHV(intel_dp->DP); + else + pipe = PORT_TO_PIPE(intel_dp->DP); + + if (pipe != PIPE_A && pipe != PIPE_B) + pipe = intel_dp->pps_pipe; + + if (pipe != PIPE_A && pipe != PIPE_B) + pipe = PIPE_A; + + DRM_DEBUG_KMS("using pipe %c for initial backlight setup\n", + pipe_name(pipe)); } intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_connector->panel.backlight_power = intel_edp_backlight_power; - intel_panel_setup_backlight(connector); + intel_panel_setup_backlight(connector, pipe); return true; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 24993486fd24..ef5155739a1e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1096,7 +1096,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *crtc, int fitting_mode); void intel_panel_set_backlight_acpi(struct intel_connector *connector, u32 level, u32 max); -int intel_panel_setup_backlight(struct drm_connector *connector); +int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe); void intel_panel_enable_backlight(struct intel_connector *connector); void intel_panel_disable_backlight(struct intel_connector *connector); void intel_panel_destroy_backlight(struct drm_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2b50c98dd6b0..c03d457a5150 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1116,7 +1116,7 @@ void intel_lvds_init(struct drm_device *dev) drm_connector_register(connector); intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); - intel_panel_setup_backlight(connector); + intel_panel_setup_backlight(connector, INVALID_PIPE); return; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 4ec6c2feef42..69bbfbaa4680 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1117,7 +1117,7 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) 0, panel->backlight.max); } -static int bdw_setup_backlight(struct intel_connector *connector) +static int bdw_setup_backlight(struct intel_connector *connector, enum pipe unused) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1143,7 +1143,7 @@ static int bdw_setup_backlight(struct intel_connector *connector) return 0; } -static int pch_setup_backlight(struct intel_connector *connector) +static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1170,7 +1170,7 @@ static int pch_setup_backlight(struct intel_connector *connector) return 0; } -static int i9xx_setup_backlight(struct intel_connector *connector) +static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1202,7 +1202,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector) return 0; } -static int i965_setup_backlight(struct intel_connector *connector) +static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1232,37 +1232,40 @@ static int i965_setup_backlight(struct intel_connector *connector) return 0; } -static int vlv_setup_backlight(struct intel_connector *connector) +static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - enum pipe pipe; + enum pipe p; u32 ctl, ctl2, val; - for_each_pipe(dev_priv, pipe) { - u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe)); + for_each_pipe(dev_priv, p) { + u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(p)); /* Skip if the modulation freq is already set */ if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK) continue; cur_val &= BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) | + I915_WRITE(VLV_BLC_PWM_CTL(p), (0xf42 << 16) | cur_val); } - ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A)); + if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) + return -ENODEV; + + ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; - ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A)); + ctl = I915_READ(VLV_BLC_PWM_CTL(pipe)); panel->backlight.max = ctl >> 16; if (!panel->backlight.max) return -ENODEV; panel->backlight.min = get_backlight_min_vbt(connector); - val = _vlv_get_backlight(dev, PIPE_A); + val = _vlv_get_backlight(dev, pipe); panel->backlight.level = intel_panel_compute_brightness(connector, val); panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && @@ -1271,7 +1274,7 @@ static int vlv_setup_backlight(struct intel_connector *connector) return 0; } -int intel_panel_setup_backlight(struct drm_connector *connector) +int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1290,7 +1293,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector) /* set level and max in panel struct */ mutex_lock(&dev_priv->backlight_lock); - ret = dev_priv->display.setup_backlight(intel_connector); + ret = dev_priv->display.setup_backlight(intel_connector, pipe); mutex_unlock(&dev_priv->backlight_lock); if (ret) { -- GitLab From 0962c3c9c7d38d938b3b8ca861487b245ffdc150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 15:19:46 +0200 Subject: [PATCH 4749/9457] drm/i915: Register the backlight device after the modeset init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we register the backlight device as soon as we register the connector. That means we can get backlight requests from userspace already before reading out the current modeset hardware state. That means we don't yet know the current crtc->encoder->connector mapping, which causes problems for VLV/CHV which need to know the current pipe in order to figure out which BLC registers to poke. Currently we just ignore such requests fairly deep in the backlight code which means the backlight device brightness property will get out of sync with our backlight.level and the actual hardware state. Fix the problem by delaying the backlight device registration until the entire modeset init has been performed. And we also move the backlight unregisteration to happen as the first thing during the modeset cleanup so that we also won't be bothered with userspace backlight requested during teardown. This is a real world problem on machines using systemd, because systemd, for some reason, wants to restore the backlight to the level it used last time. And that happens as soon as it sees the backlight device appearing in the system. Sometimes the userspace access makes it through before the modeset init, sometimes not. v2: Do not lie to the user in the debug prints (Jani) Include connector name in the prints (Jani) Fix a typo in the commit message (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++++ drivers/gpu/drm/i915/intel_drv.h | 3 +++ drivers/gpu/drm/i915/intel_panel.c | 33 ++++++++++++++++++++++------ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7c2ecbe43ca5..983091224f11 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13293,6 +13293,8 @@ void intel_modeset_gem_init(struct drm_device *dev) } } mutex_unlock(&dev->struct_mutex); + + intel_backlight_register(dev); } void intel_connector_unregister(struct intel_connector *intel_connector) @@ -13308,6 +13310,8 @@ void intel_modeset_cleanup(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; + intel_backlight_unregister(dev); + /* * Interrupts and polling as the first thing to avoid creating havoc. * Too much stuff here (turning of rps, connectors, ...) would diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ef5155739a1e..3c324a806646 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1106,6 +1106,9 @@ extern struct drm_display_mode *intel_find_panel_downclock( struct drm_device *dev, struct drm_display_mode *fixed_mode, struct drm_connector *connector); +void intel_backlight_register(struct drm_device *dev); +void intel_backlight_unregister(struct drm_device *dev); + /* intel_runtime_pm.c */ int intel_power_domains_init(struct drm_i915_private *); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 69bbfbaa4680..708642a9e19b 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1041,6 +1041,9 @@ static int intel_backlight_device_register(struct intel_connector *connector) if (WARN_ON(panel->backlight.device)) return -ENODEV; + if (!panel->backlight.present) + return 0; + WARN_ON(panel->backlight.max == 0); memset(&props, 0, sizeof(props)); @@ -1076,6 +1079,10 @@ static int intel_backlight_device_register(struct intel_connector *connector) panel->backlight.device = NULL; return -ENODEV; } + + DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n", + connector->base.name); + return 0; } @@ -1302,15 +1309,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) return ret; } - intel_backlight_device_register(intel_connector); - panel->backlight.present = true; - DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, " - "sysfs interface %sregistered\n", + DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n", + connector->name, panel->backlight.enabled ? "enabled" : "disabled", - panel->backlight.level, panel->backlight.max, - panel->backlight.device ? "" : "not "); + panel->backlight.level, panel->backlight.max); return 0; } @@ -1321,7 +1325,6 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) struct intel_panel *panel = &intel_connector->panel; panel->backlight.present = false; - intel_backlight_device_unregister(intel_connector); } /* Set up chip specific backlight functions */ @@ -1384,3 +1387,19 @@ void intel_panel_fini(struct intel_panel *panel) drm_mode_destroy(intel_connector->base.dev, panel->downclock_mode); } + +void intel_backlight_register(struct drm_device *dev) +{ + struct intel_connector *connector; + + list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) + intel_backlight_device_register(connector); +} + +void intel_backlight_unregister(struct drm_device *dev) +{ + struct intel_connector *connector; + + list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) + intel_backlight_device_unregister(connector); +} -- GitLab From 260d8f98ef9deb71bee4d88f72cd90afe023b08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 15:20:23 +0200 Subject: [PATCH 4750/9457] drm/i915: Remove most INVALID_PIPE checks from the backlight code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the backlight device no longer gets registered too early we should be able to drop most of the INVALID_PIPE checks from the backlight code. The only exceptio is the opregion stuff where we may (in theory at least) get a request from the BIOS already during driver init as soon as the backlight setup has been done. In which case we can still get the INVALID_PIPE from intel_get_pipe_from_connector(). So leave that check in place, and add a comment explaining why. For the rest, if we still manage to get here with INVALID_PIPE on VLV/CHV we will now get a WARN from the lower level functions and can then actually investigate further. v2: Leave the check in the BIOS related code (Jani) Cc: Jani Nikula Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 708642a9e19b..c45b127ff2f5 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -634,10 +634,9 @@ static void intel_panel_set_backlight(struct intel_connector *connector, struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); u32 hw_level; - if (!panel->backlight.present || pipe == INVALID_PIPE) + if (!panel->backlight.present) return; mutex_lock(&dev_priv->backlight_lock); @@ -665,6 +664,12 @@ void intel_panel_set_backlight_acpi(struct intel_connector *connector, enum pipe pipe = intel_get_pipe_from_connector(connector); u32 hw_level; + /* + * INVALID_PIPE may occur during driver init because + * connection_mutex isn't held across the entire backlight + * setup + modeset readout, and the BIOS can issue the + * requests at any time. + */ if (!panel->backlight.present || pipe == INVALID_PIPE) return; @@ -740,9 +745,8 @@ void intel_panel_disable_backlight(struct intel_connector *connector) struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - enum pipe pipe = intel_get_pipe_from_connector(connector); - if (!panel->backlight.present || pipe == INVALID_PIPE) + if (!panel->backlight.present) return; /* @@ -949,7 +953,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - if (!panel->backlight.present || pipe == INVALID_PIPE) + if (!panel->backlight.present) return; DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); -- GitLab From 7f27126ea3db6ade886f18fd39caf0ff0cd1d37f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 5 Nov 2014 14:26:06 -0800 Subject: [PATCH 4751/9457] drm/i915: factor out compute_config from __intel_set_mode v3 This allows us to calculate the full pipe config before we do any mode setting work. v2: - clarify comments about global vs. per-crtc mode set (Ander) - clean up unnecessary pipe_config = NULL setting (Ander) v3: - fix pipe_config handling (alloc in compute_config, free in set_mode) (Jesse) - fix arg order in set_mode (Jesse) - fix failure path of set_config (Ander) Signed-off-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 105 +++++++++++++++++++-------- 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 983091224f11..6e8f9e295d01 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10741,45 +10741,60 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset = 1; } +static struct intel_crtc_config * +intel_modeset_compute_config(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_framebuffer *fb, + unsigned *modeset_pipes, + unsigned *prepare_pipes, + unsigned *disable_pipes) +{ + struct intel_crtc_config *pipe_config = NULL; + + intel_modeset_affected_pipes(crtc, modeset_pipes, + prepare_pipes, disable_pipes); + + if ((*modeset_pipes) == 0) + goto out; + + /* + * Note this needs changes when we start tracking multiple modes + * and crtcs. At that point we'll need to compute the whole config + * (i.e. one pipe_config for each crtc) rather than just the one + * for this crtc. + */ + pipe_config = intel_modeset_pipe_config(crtc, fb, mode); + if (IS_ERR(pipe_config)) { + goto out; + } + intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, + "[modeset]"); + to_intel_crtc(crtc)->new_config = pipe_config; + +out: + return pipe_config; +} + static int __intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, - int x, int y, struct drm_framebuffer *fb) + int x, int y, struct drm_framebuffer *fb, + struct intel_crtc_config *pipe_config, + unsigned modeset_pipes, + unsigned prepare_pipes, + unsigned disable_pipes) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *saved_mode; - struct intel_crtc_config *pipe_config = NULL; struct intel_crtc *intel_crtc; - unsigned disable_pipes, prepare_pipes, modeset_pipes; int ret = 0; saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL); if (!saved_mode) return -ENOMEM; - intel_modeset_affected_pipes(crtc, &modeset_pipes, - &prepare_pipes, &disable_pipes); - *saved_mode = crtc->mode; - /* Hack: Because we don't (yet) support global modeset on multiple - * crtcs, we don't keep track of the new mode for more than one crtc. - * Hence simply check whether any bit is set in modeset_pipes in all the - * pieces of code that are not yet converted to deal with mutliple crtcs - * changing their mode at the same time. */ - if (modeset_pipes) { - pipe_config = intel_modeset_pipe_config(crtc, fb, mode); - if (IS_ERR(pipe_config)) { - ret = PTR_ERR(pipe_config); - pipe_config = NULL; - - goto out; - } - intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, - "[modeset]"); - to_intel_crtc(crtc)->new_config = pipe_config; - } - /* * See if the config requires any additional preparation, e.g. * to adjust global state with pipes off. We need to do this @@ -10820,6 +10835,10 @@ static int __intel_set_mode(struct drm_crtc *crtc, /* crtc->mode is already used by the ->mode_set callbacks, hence we need * to set it here already despite that we pass it down the callchain. + * + * Note we'll need to fix this up when we start tracking multiple + * pipes; here we assume a single modeset_pipe and only track the + * single crtc and mode. */ if (modeset_pipes) { crtc->mode = *mode; @@ -10881,19 +10900,23 @@ static int __intel_set_mode(struct drm_crtc *crtc, if (ret && crtc->enabled) crtc->mode = *saved_mode; -out: kfree(pipe_config); kfree(saved_mode); return ret; } -static int intel_set_mode(struct drm_crtc *crtc, - struct drm_display_mode *mode, - int x, int y, struct drm_framebuffer *fb) +static int intel_set_mode_pipes(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, struct drm_framebuffer *fb, + struct intel_crtc_config *pipe_config, + unsigned modeset_pipes, + unsigned prepare_pipes, + unsigned disable_pipes) { int ret; - ret = __intel_set_mode(crtc, mode, x, y, fb); + ret = __intel_set_mode(crtc, mode, x, y, fb, pipe_config, modeset_pipes, + prepare_pipes, disable_pipes); if (ret == 0) intel_modeset_check_state(crtc->dev); @@ -10901,6 +10924,26 @@ static int intel_set_mode(struct drm_crtc *crtc, return ret; } +static int intel_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, struct drm_framebuffer *fb) +{ + struct intel_crtc_config *pipe_config; + unsigned modeset_pipes, prepare_pipes, disable_pipes; + + pipe_config = intel_modeset_compute_config(crtc, mode, fb, + &modeset_pipes, + &prepare_pipes, + &disable_pipes); + + if (IS_ERR(pipe_config)) + return PTR_ERR(pipe_config); + + return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config, + modeset_pipes, prepare_pipes, + disable_pipes); +} + void intel_crtc_restore_mode(struct drm_crtc *crtc) { intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb); @@ -13249,8 +13292,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, - crtc->primary->fb); + intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, + crtc->primary->fb); } } else { intel_modeset_update_staged_output_state(dev); -- GitLab From 50f5275698df4490046cc5b4ed2018abb642a803 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 7 Nov 2014 13:11:00 -0800 Subject: [PATCH 4752/9457] drm/i915: use compute_config in set_config v4 This will allow us to consult more info before deciding whether to flip or do a full mode set. v2: - don't use uninitialized or incorrect pipe masks in set_config failure path (Ander) v3: - fixup for pipe_config changes in compute_config (Jesse) v4: - drop spurious hunk in force restore path (Ander) Signed-off-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6e8f9e295d01..22ad01c38eef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11272,6 +11272,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set) struct drm_device *dev; struct drm_mode_set save_set; struct intel_set_config *config; + struct intel_crtc_config *pipe_config; + unsigned modeset_pipes, prepare_pipes, disable_pipes; int ret; BUG_ON(!set); @@ -11317,9 +11319,23 @@ static int intel_crtc_set_config(struct drm_mode_set *set) if (ret) goto fail; + pipe_config = intel_modeset_compute_config(set->crtc, set->mode, + set->fb, + &modeset_pipes, + &prepare_pipes, + &disable_pipes); + if (IS_ERR(pipe_config)) + goto fail; + + /* set_mode will free it in the mode_changed case */ + if (!config->mode_changed) + kfree(pipe_config); + if (config->mode_changed) { - ret = intel_set_mode(set->crtc, set->mode, - set->x, set->y, set->fb); + ret = intel_set_mode_pipes(set->crtc, set->mode, + set->x, set->y, set->fb, pipe_config, + modeset_pipes, prepare_pipes, + disable_pipes); } else if (config->fb_changed) { struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc); -- GitLab From e43823ecc24488c464587f7daf462548f2396e4f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 5 Nov 2014 14:26:08 -0800 Subject: [PATCH 4753/9457] drm/i915/hdmi: fetch infoframe status in get_config v2 This is useful for checking things later. v2: - fix hsw infoframe enabled check (Ander) Signed-off-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira [danvet: Add the missing PIPE_CONF_CHECK_I(has_infoframe); line to the hw state cross-checker.] [danet: Squash in fixup from Jesse to correctly compute has_infoframe in the hdmi compute_config function.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_hdmi.c | 65 ++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 22ad01c38eef..8b5efe6f3ee6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10362,6 +10362,7 @@ intel_pipe_config_compare(struct drm_device *dev, if ((INTEL_INFO(dev)->gen < 8 && !IS_HASWELL(dev)) || IS_VALLEYVIEW(dev)) PIPE_CONF_CHECK_I(limited_color_range); + PIPE_CONF_CHECK_I(has_infoframe); PIPE_CONF_CHECK_I(has_audio); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3c324a806646..8432ae2d41f0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -292,6 +292,9 @@ struct intel_crtc_config { * between pch encoders and cpu encoders. */ bool has_pch_encoder; + /* Are we sending infoframes on the attached port */ + bool has_infoframe; + /* CPU Transcoder for the pipe. Currently this can only differ from the * pipe on Haswell (where we have a special eDP transcoder). */ enum transcoder cpu_transcoder; @@ -552,6 +555,7 @@ struct intel_hdmi { void (*set_infoframes)(struct drm_encoder *encoder, bool enable, struct drm_display_mode *adjusted_mode); + bool (*infoframe_enabled)(struct drm_encoder *encoder); }; struct intel_dp_mst_encoder; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 29baa53aef90..f58e8834ebfb 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -166,6 +166,15 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, POSTING_READ(VIDEO_DIP_CTL); } +static bool g4x_infoframe_enabled(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val = I915_READ(VIDEO_DIP_CTL); + + return val & VIDEO_DIP_ENABLE; +} + static void ibx_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len) @@ -204,6 +213,17 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, POSTING_READ(reg); } +static bool ibx_infoframe_enabled(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + return val & VIDEO_DIP_ENABLE; +} + static void cpt_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len) @@ -245,6 +265,17 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, POSTING_READ(reg); } +static bool cpt_infoframe_enabled(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + return val & VIDEO_DIP_ENABLE; +} + static void vlv_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len) @@ -283,6 +314,17 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, POSTING_READ(reg); } +static bool vlv_infoframe_enabled(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + return val & VIDEO_DIP_ENABLE; +} + static void hsw_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len) @@ -320,6 +362,18 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, POSTING_READ(ctl_reg); } +static bool hsw_infoframe_enabled(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); + u32 val = I915_READ(ctl_reg); + + return val & (VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_SPD_HSW | + VIDEO_DIP_ENABLE_VS_HSW); +} + /* * The data we write to the DIP data buffer registers is 1 byte bigger than the * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting @@ -724,6 +778,9 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, if (tmp & HDMI_MODE_SELECT_HDMI) pipe_config->has_hdmi_sink = true; + if (intel_hdmi->infoframe_enabled(&encoder->base)) + pipe_config->has_infoframe = true; + if (tmp & SDVO_AUDIO_ENABLE) pipe_config->has_audio = true; @@ -925,6 +982,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, pipe_config->has_hdmi_sink = intel_hdmi->has_hdmi_sink; + if (pipe_config->has_hdmi_sink) + pipe_config->has_infoframe = true; + if (intel_hdmi->color_range_auto) { /* See CEA-861-E - 5.1 Default Encoding Parameters */ if (pipe_config->has_hdmi_sink && @@ -1619,18 +1679,23 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, if (IS_VALLEYVIEW(dev)) { intel_hdmi->write_infoframe = vlv_write_infoframe; intel_hdmi->set_infoframes = vlv_set_infoframes; + intel_hdmi->infoframe_enabled = vlv_infoframe_enabled; } else if (IS_G4X(dev)) { intel_hdmi->write_infoframe = g4x_write_infoframe; intel_hdmi->set_infoframes = g4x_set_infoframes; + intel_hdmi->infoframe_enabled = g4x_infoframe_enabled; } else if (HAS_DDI(dev)) { intel_hdmi->write_infoframe = hsw_write_infoframe; intel_hdmi->set_infoframes = hsw_set_infoframes; + intel_hdmi->infoframe_enabled = hsw_infoframe_enabled; } else if (HAS_PCH_IBX(dev)) { intel_hdmi->write_infoframe = ibx_write_infoframe; intel_hdmi->set_infoframes = ibx_set_infoframes; + intel_hdmi->infoframe_enabled = ibx_infoframe_enabled; } else { intel_hdmi->write_infoframe = cpt_write_infoframe; intel_hdmi->set_infoframes = cpt_set_infoframes; + intel_hdmi->infoframe_enabled = cpt_infoframe_enabled; } if (HAS_DDI(dev)) -- GitLab From 206645910b9796bff13fcdb67bdca166b724ba62 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 5 Nov 2014 14:26:09 -0800 Subject: [PATCH 4754/9457] drm/i915: check for audio and infoframe changes across mode sets v2 If these change (e.g. after a modeset following a fastboot), we need to do a full mode set. v2: - put under pipe_config check so we don't deref a null state (Jesse) Signed-off-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b5efe6f3ee6..e9b579fd9fc4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11325,8 +11325,18 @@ static int intel_crtc_set_config(struct drm_mode_set *set) &modeset_pipes, &prepare_pipes, &disable_pipes); - if (IS_ERR(pipe_config)) + if (IS_ERR(pipe_config)) { goto fail; + } else if (pipe_config) { + if (to_intel_crtc(set->crtc)->new_config->has_audio != + to_intel_crtc(set->crtc)->config.has_audio) + config->mode_changed = true; + + /* Force mode sets for any infoframe stuff */ + if (to_intel_crtc(set->crtc)->new_config->has_infoframe || + to_intel_crtc(set->crtc)->config.has_infoframe) + config->mode_changed = true; + } /* set_mode will free it in the mode_changed case */ if (!config->mode_changed) -- GitLab From 1f9954d0bbea3e8ec930e85b12cee6a71ed42b22 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 5 Nov 2014 14:26:10 -0800 Subject: [PATCH 4755/9457] drm/i915: update pipe size at set_config time This only affects the fastboot path as-is. In that case, we simply need to make sure that we update the pipe size at the first mode set. Rather than putting it off until we decide to flip (if indeed we do end up flipping), update the pipe size as appropriate a bit earlier in the set_config call. This sets us up for better pipe tracking in later patches. Signed-off-by: Jesse Barnes Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e9b579fd9fc4..e183a26cd738 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2931,8 +2931,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - intel_update_pipe_size(intel_crtc); - dev_priv->display.update_primary_plane(crtc, fb, x, y); if (intel_crtc->active) @@ -11342,6 +11340,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set) if (!config->mode_changed) kfree(pipe_config); + intel_update_pipe_size(to_intel_crtc(set->crtc)); + if (config->mode_changed) { ret = intel_set_mode_pipes(set->crtc, set->mode, set->x, set->y, set->fb, pipe_config, -- GitLab From f1f55cc0556031c8ee3fe99dae7251e78b9b653b Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Fri, 7 Nov 2014 19:00:26 +0000 Subject: [PATCH 4756/9457] drm/i915: Add the predicate source registers to the register whitelist The predicate source registers are needed to implement conditional rendering without stalling. The two source registers are used to load the previous values of the PS_DEPTH_COUNT register saved from PIPE_CONTROL commands. These can then be compared and used to set the predicate enable bit via the MI_PREDICATE command. The command parser version number is increased to 2 to make it easier to detect the new functionality in user space. Signed-off-by: Neil Roberts Reviewed-by: Brad Volkin (v1) Reviewed-by: Kenneth Graunke (v1) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 6 +++++- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 809bb957b452..22c992a78ac6 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -413,6 +413,8 @@ static const u32 gen7_render_regs[] = { REG64(PS_INVOCATION_COUNT), REG64(PS_DEPTH_COUNT), OACONTROL, /* Only allowed for LRI and SRM. See below. */ + REG64(MI_PREDICATE_SRC0), + REG64(MI_PREDICATE_SRC1), GEN7_3DPRIM_END_OFFSET, GEN7_3DPRIM_START_VERTEX, GEN7_3DPRIM_VERTEX_COUNT, @@ -1072,6 +1074,8 @@ int i915_cmd_parser_get_version(void) * * 1. Initial version. Checks batches and reports violations, but leaves * hardware parsing enabled (so does not allow new use cases). + * 2. Allow access to the MI_PREDICATE_SRC0 and + * MI_PREDICATE_SRC1 registers. */ - return 1; + return 2; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 97d3479ad92e..35cfc16814c0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -314,6 +314,8 @@ #define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */ #define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1) +#define MI_PREDICATE_SRC0 (0x2400) +#define MI_PREDICATE_SRC1 (0x2408) #define MI_PREDICATE_RESULT_2 (0x2214) #define LOWER_SLICE_ENABLED (1<<0) -- GitLab From c6e8f39db96d63a1b4eda32e7dfeac093edc09ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 21:33:43 +0200 Subject: [PATCH 4757/9457] drm/i915: Read the CCK fuse register from CCK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reading a CCK register we should obviously read it from CCK not Punit. This problem has been present ever since this of code was introduced in commit 67c3bf6f55a97a0915a0f9ea07278a3073cc9601 Author: Deepak S Date: Thu Jul 10 13:16:24 2014 +0530 drm/i915: populate mem_freq/cz_clock for chv The problem was raised during review by Mika [1] but somehow slipped through the cracks, and the patch got applied with the problem unfixed. [1] http://lists.freedesktop.org/archives/intel-gfx/2014-July/048937.html Cc: Deepak S Cc: Mika Kuoppala Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 62ffb1b81dff..9e87265f2448 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5195,7 +5195,10 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) mutex_lock(&dev_priv->rps.hw_lock); - val = vlv_punit_read(dev_priv, CCK_FUSE_REG); + mutex_lock(&dev_priv->dpio_lock); + val = vlv_cck_read(dev_priv, CCK_FUSE_REG); + mutex_unlock(&dev_priv->dpio_lock); + switch ((val >> 2) & 0x7) { case 0: case 1: -- GitLab From 771b9a532483cc45df19823b8dfaa0cecfd45836 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Tue, 11 Nov 2014 16:47:33 +0000 Subject: [PATCH 4758/9457] drm/i915: Initialize workarounds in logical ring mode too Following the legacy ring submission example, update the ring->init_context() hook to support the execlist submission mode. v2: update to use the new workaround macros and cleanup unused code. This takes care of both bdw and chv workarounds. v2.1: Add missing call to init_context() during deferred context creation. v3: Split init_context (emit) in legacy/lrc modes. For lrc, get the ringbuf from the context (Mika/Daniel). v4: Merge init_context interfaces back, the legacy mode only needs the ring, but the lrc mode needs the ring and context (Mika). Issue: VIZ-4092 Issue: GMIN-3475 Change-Id: Ie3d093b2542ab0e2a44b90460533e2f979788d6c Cc: Deepak S Cc: Mika Kuoppala Cc: Daniel Vetter Signed-off-by: Michel Thierry Signed-off-by: Arun Siluvery Reviewed-by: Mika Kuoppala [danvet: Align function paramater lists properly.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 47 ++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +-- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 1fb00008623d..d17ff435f276 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -635,7 +635,7 @@ static int do_switch(struct intel_engine_cs *ring, if (uninitialized) { if (ring->init_context) { - ret = ring->init_context(ring); + ret = ring->init_context(ring, to); if (ret) DRM_ERROR("ring init context: %d\n", ret); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6025ac754c37..2a1a71933420 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -989,6 +989,44 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords) return 0; } +static int intel_logical_ring_workarounds_emit(struct intel_engine_cs *ring, + struct intel_context *ctx) +{ + int ret, i; + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_workarounds *w = &dev_priv->workarounds; + + if (WARN_ON(w->count == 0)) + return 0; + + ring->gpu_caches_dirty = true; + ret = logical_ring_flush_all_caches(ringbuf); + if (ret) + return ret; + + ret = intel_logical_ring_begin(ringbuf, w->count * 2 + 2); + if (ret) + return ret; + + intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(w->count)); + for (i = 0; i < w->count; i++) { + intel_logical_ring_emit(ringbuf, w->reg[i].addr); + intel_logical_ring_emit(ringbuf, w->reg[i].value); + } + intel_logical_ring_emit(ringbuf, MI_NOOP); + + intel_logical_ring_advance(ringbuf); + + ring->gpu_caches_dirty = true; + ret = logical_ring_flush_all_caches(ringbuf); + if (ret) + return ret; + + return 0; +} + static int gen8_init_common_ring(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; @@ -1032,7 +1070,7 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); - return ret; + return init_workarounds_ring(ring); } static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf, @@ -1282,6 +1320,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; ring->init = gen8_init_render_ring; + ring->init_context = intel_logical_ring_workarounds_emit; ring->cleanup = intel_fini_pipe_control; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; @@ -1763,6 +1802,12 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, } if (ring->id == RCS && !ctx->rcs_initialized) { + if (ring->init_context) { + ret = ring->init_context(ring, ctx); + if (ret) + DRM_ERROR("ring init context: %d\n", ret); + } + ret = intel_lr_context_render_state_init(ring, ctx); if (ret) { DRM_ERROR("Init render state failed: %d\n", ret); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a09aae70e579..ae092589ea0c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -665,7 +665,8 @@ intel_init_pipe_control(struct intel_engine_cs *ring) return ret; } -static int intel_ring_workarounds_emit(struct intel_engine_cs *ring) +static int intel_ring_workarounds_emit(struct intel_engine_cs *ring, + struct intel_context *ctx) { int ret, i; struct drm_device *dev = ring->dev; @@ -806,7 +807,7 @@ static int chv_init_workarounds(struct intel_engine_cs *ring) return 0; } -static int init_workarounds_ring(struct intel_engine_cs *ring) +int init_workarounds_ring(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 96479c89f4bd..aab2e2f90a74 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -148,7 +148,8 @@ struct intel_engine_cs { int (*init)(struct intel_engine_cs *ring); - int (*init_context)(struct intel_engine_cs *ring); + int (*init_context)(struct intel_engine_cs *ring, + struct intel_context *ctx); void (*write_tail)(struct intel_engine_cs *ring, u32 value); @@ -424,6 +425,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev); u64 intel_ring_get_active_head(struct intel_engine_cs *ring); void intel_ring_setup_status_page(struct intel_engine_cs *ring); +int init_workarounds_ring(struct intel_engine_cs *ring); + static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf) { return ringbuf->tail; -- GitLab From c549f738e7469ace5b0ed9848aa55bff428d0b62 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Mon, 10 Nov 2014 04:52:50 -0800 Subject: [PATCH 4759/9457] drm/i915: Wait thread status on gen8+ fw sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per latest pm guide, we need to do this also on past hsw. Cc: Ville Syrjälä Cc: Chris Wilson Cc: Damien Lespiau Signed-off-by: Mika Kuoppala Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 6a0c3fb2cbf0..86a755a9b9d0 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -120,8 +120,7 @@ static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); /* WaRsForcewakeWaitTC0:ivb,hsw */ - if (INTEL_INFO(dev_priv->dev)->gen < 8) - __gen6_gt_wait_for_thread_c0(dev_priv); + __gen6_gt_wait_for_thread_c0(dev_priv); } static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) -- GitLab From c7e20736fa91729330becdfd67cb545220a0c904 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 11 Nov 2014 16:48:03 +0200 Subject: [PATCH 4760/9457] drm/i915/vlv: don't save panel power sequencer registers on suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't save the panel power sequencer register on vlv/chv for two simple reasons. First, these are the wrong registers to save to begin with. Second, they are not restored anyway. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 043123c77a1f..bd8adf2ca7d8 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -208,7 +208,6 @@ static void i915_save_display(struct drm_device *dev) if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); } else if (IS_VALLEYVIEW(dev)) { - dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); dev_priv->regfile.saveBLC_HIST_CTL = @@ -230,7 +229,7 @@ static void i915_save_display(struct drm_device *dev) dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); - } else { + } else if (!IS_VALLEYVIEW(dev)) { dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR); -- GitLab From c934a16732d781b29465ddff914b0c7c8fae28f1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 11 Nov 2014 16:48:04 +0200 Subject: [PATCH 4761/9457] drm/i915: restore RSTDBYCTL only on non-KMS paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since RSTDBYCTL is only saved on non-KMS path in within i915_save_state, move the restore in i915_restore_state for symmetry. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index bd8adf2ca7d8..26b6bf9261ca 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -271,8 +271,6 @@ static void i915_restore_display(struct drm_device *dev) I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL); - I915_WRITE(RSTDBYCTL, - dev_priv->regfile.saveMCHBAR_RENDER_STANDBY); } else if (IS_VALLEYVIEW(dev)) { I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A), dev_priv->regfile.saveBLC_HIST_CTL); @@ -367,6 +365,8 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(_FDI_RXA_IMR, dev_priv->regfile.saveFDI_RXA_IMR); I915_WRITE(_FDI_RXB_IMR, dev_priv->regfile.saveFDI_RXB_IMR); I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->regfile.savePCH_PORT_HOTPLUG); + I915_WRITE(RSTDBYCTL, + dev_priv->regfile.saveMCHBAR_RENDER_STANDBY); } else { I915_WRITE(IER, dev_priv->regfile.saveIER); I915_WRITE(IMR, dev_priv->regfile.saveIMR); -- GitLab From 5ea13be5badca78a11921b864db380274279c8b9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Nov 2014 14:48:52 +0200 Subject: [PATCH 4762/9457] drm/i915: remove the unnecessary block around display.hpd_irq_setup The block was added for spin_lock_irqsave flags, but since the locking was converted to spin_lock_irq variant, the block is no longer needed. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2404b2baa01e..122ea9549110 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -703,12 +703,10 @@ static int i915_drm_resume(struct drm_device *dev) intel_modeset_init_hw(dev); - { - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irq(&dev_priv->irq_lock); - } + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev); + spin_unlock_irq(&dev_priv->irq_lock); intel_dp_mst_resume(dev); drm_modeset_lock_all(dev); -- GitLab From f7faa1ef175d34d600df6eb21d16b596088a608e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Nov 2014 16:25:42 +0200 Subject: [PATCH 4763/9457] drm/i915: don't save/restore panel fitter registers AFAICT i9xx_pfit_disable() on the GMCH display crtc disable path in i9xx_crtc_disable() will always disable the panel fitter by writing 0 to PFIT_CONTROL. The register save will always save/restore 0. Also we completely recompue both in intel_gmch_panel_fitting so there's no way we depend upon leftover bits. Move the PFIT_CONTROL and PFIT_PGM_RATIOS save/restore to UMS code. While at it, save/restore them both under the same conditions. Signed-off-by: Jani Nikula [danvet: Make it a bit clearer that we nowhere depend upon these bits.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 10 ---------- drivers/gpu/drm/i915/i915_ums.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 26b6bf9261ca..df2b7f18a679 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -208,23 +208,17 @@ static void i915_save_display(struct drm_device *dev) if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); } else if (IS_VALLEYVIEW(dev)) { - dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); - dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(VLV_BLC_HIST_CTL(PIPE_A)); dev_priv->regfile.saveBLC_HIST_CTL_B = I915_READ(VLV_BLC_HIST_CTL(PIPE_B)); } else { dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); if (IS_MOBILE(dev) && !IS_I830(dev)) dev_priv->regfile.saveLVDS = I915_READ(LVDS); } - if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) - dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL); - if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); @@ -263,9 +257,6 @@ static void i915_restore_display(struct drm_device *dev) else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev)) I915_WRITE(LVDS, dev_priv->regfile.saveLVDS & mask); - if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) - I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL); - if (HAS_PCH_SPLIT(dev)) { I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); @@ -277,7 +268,6 @@ static void i915_restore_display(struct drm_device *dev) I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B), dev_priv->regfile.saveBLC_HIST_CTL); } else { - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS); I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL); I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c index 480da593e6c0..0e03c3610719 100644 --- a/drivers/gpu/drm/i915/i915_ums.c +++ b/drivers/gpu/drm/i915/i915_ums.c @@ -270,6 +270,12 @@ void i915_save_display_reg(struct drm_device *dev) } /* FIXME: regfile.save TV & SDVO state */ + /* Panel fitter */ + if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) { + dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL); + dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); + } + /* Backlight */ if (INTEL_INFO(dev)->gen <= 4) pci_read_config_byte(dev->pdev, PCI_LBPC, @@ -315,6 +321,12 @@ void i915_restore_display_reg(struct drm_device *dev) I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL); } + /* Panel fitter */ + if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) { + I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS); + I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL); + } + /* Display port ratios (must be done before clock is set) */ if (SUPPORTS_INTEGRATED_DP(dev)) { I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M); -- GitLab From b0cd324faed23d10d66ba6ade66579c681feef6f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Nov 2014 16:25:43 +0200 Subject: [PATCH 4764/9457] drm/i915: don't save/restore backlight hist ctl registers This is not used within the driver, and merely saving/restoring these registers isn't going to do any good anyway. In fact, it's possible it's actively harmful. Any code enabling the feature should handle this completely in the regular platform specific enable/disable backlight functions. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_suspend.c | 16 ++-------------- drivers/gpu/drm/i915/i915_ums.c | 2 ++ 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 45ca10937e3e..3f3035ce30e6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -799,7 +799,6 @@ struct i915_suspend_saved_registers { u32 saveBLC_HIST_CTL; u32 saveBLC_PWM_CTL; u32 saveBLC_PWM_CTL2; - u32 saveBLC_HIST_CTL_B; u32 saveBLC_CPU_PWM_CTL; u32 saveBLC_CPU_PWM_CTL2; u32 saveFPB0; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index df2b7f18a679..3c1fccfacac1 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -207,14 +207,8 @@ static void i915_save_display(struct drm_device *dev) dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL); if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); - } else if (IS_VALLEYVIEW(dev)) { - dev_priv->regfile.saveBLC_HIST_CTL = - I915_READ(VLV_BLC_HIST_CTL(PIPE_A)); - dev_priv->regfile.saveBLC_HIST_CTL_B = - I915_READ(VLV_BLC_HIST_CTL(PIPE_B)); - } else { + } else if (!IS_VALLEYVIEW(dev)) { dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); if (IS_MOBILE(dev) && !IS_I830(dev)) dev_priv->regfile.saveLVDS = I915_READ(LVDS); } @@ -262,13 +256,7 @@ static void i915_restore_display(struct drm_device *dev) I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL); - } else if (IS_VALLEYVIEW(dev)) { - I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A), - dev_priv->regfile.saveBLC_HIST_CTL); - I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B), - dev_priv->regfile.saveBLC_HIST_CTL); - } else { - I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL); + } else if (!IS_VALLEYVIEW(dev)) { I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); I915_WRITE(PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c index 0e03c3610719..d10fe3e9c49f 100644 --- a/drivers/gpu/drm/i915/i915_ums.c +++ b/drivers/gpu/drm/i915/i915_ums.c @@ -290,6 +290,7 @@ void i915_save_display_reg(struct drm_device *dev) dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); if (INTEL_INFO(dev)->gen >= 4) dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); } return; @@ -319,6 +320,7 @@ void i915_restore_display_reg(struct drm_device *dev) if (INTEL_INFO(dev)->gen >= 4) I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL); + I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL); } /* Panel fitter */ -- GitLab From 1c5bb42ce8eb8abf1c16d36368ab99bb32837cd4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 12 Nov 2014 17:01:10 +0200 Subject: [PATCH 4765/9457] drm/i915: unify remaining register save/restore code a bit Use the same conditions, group by features, add comments. Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_suspend.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 3c1fccfacac1..dfe661743398 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -203,21 +203,19 @@ static void i915_save_display(struct drm_device *dev) i915_save_display_reg(dev); /* LVDS state */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL); - if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) - dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); - } else if (!IS_VALLEYVIEW(dev)) { - dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); - if (IS_MOBILE(dev) && !IS_I830(dev)) - dev_priv->regfile.saveLVDS = I915_READ(LVDS); - } + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) + dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); + else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev)) + dev_priv->regfile.saveLVDS = I915_READ(LVDS); + /* Panel power sequencer */ if (HAS_PCH_SPLIT(dev)) { + dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL); dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); } else if (!IS_VALLEYVIEW(dev)) { + dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR); @@ -246,11 +244,13 @@ static void i915_restore_display(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) mask = ~LVDS_PORT_EN; + /* LVDS state */ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) I915_WRITE(PCH_LVDS, dev_priv->regfile.saveLVDS & mask); else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev)) I915_WRITE(LVDS, dev_priv->regfile.saveLVDS & mask); + /* Panel power sequencer */ if (HAS_PCH_SPLIT(dev)) { I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); -- GitLab From 3581f309a9c532cad6faea12ad1986da135e99b0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 12 Nov 2014 22:19:49 +0100 Subject: [PATCH 4766/9457] drm/i915: Delete outdated comment in byt_pte_encode This has been invalidated in commit 24f3a8cf7766e52a087904b4346794c7b410f957 Author: Akash Goel Date: Tue Jun 17 10:59:42 2014 +0530 drm/i915: Added write-enable pte bit supportt But despite that it's in the diff context no one noticed :( Cc: Akash Goel Cc: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 4498a068a5a7..68a27b2d3654 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -164,9 +164,6 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; pte |= GEN6_PTE_ADDR_ENCODE(addr); - /* Mark the page as writeable. Other platforms don't have a - * setting for read-only/writable, so this matches that behavior. - */ if (!(flags & PTE_READ_ONLY)) pte |= BYT_PTE_WRITEABLE; -- GitLab From 92122789b2d699a1e82dca502940e0dd37bf6f3b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 9 Oct 2014 12:57:42 -0700 Subject: [PATCH 4767/9457] drm/i915: preserve SSC if previously set v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some machines may have a broken VBT or no VBT at all, but we still want to use SSC there. So check for it and keep it enabled if we see it already on. Based on an earlier fix from Kristian. v2: honor modparam if set too (Daniel) read out at init time and store for panel_use_ssc() use (Jesse) v3: trust BIOS configuration over VBT like we do for DP (Jani) Reported-by: Kristian Høgsberg Signed-off-by: Jesse Barnes Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e183a26cd738..eac54c6db11f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13331,6 +13331,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, void intel_modeset_gem_init(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *c; struct drm_i915_gem_object *obj; @@ -13338,6 +13339,16 @@ void intel_modeset_gem_init(struct drm_device *dev) intel_init_gt_powersave(dev); mutex_unlock(&dev->struct_mutex); + /* + * There may be no VBT; and if the BIOS enabled SSC we can + * just keep using it to avoid unnecessary flicker. Whereas if the + * BIOS isn't using it, don't assume it will work even if the VBT + * indicates as much. + */ + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) + dev_priv->vbt.lvds_use_ssc = !!(I915_READ(PCH_DREF_CONTROL) & + DREF_SSC1_ENABLE); + intel_modeset_init_hw(dev); intel_setup_overlay(dev); -- GitLab From 063584d44377ebde5ebc6e99cedc1bc6561939d7 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 13 Nov 2014 23:00:13 +0000 Subject: [PATCH 4768/9457] kvm: memslots: replace heap sort with an insertion sort pass memslots is a sorted array. When a slot is changed, heapsort (lib/sort.c) would take O(n log n) time to update it; an optimized insertion sort will only cost O(n) on an array with just one item out of order. Replace sort() with a custom sort that takes advantage of memslots usage pattern and the known position of the changed slot. performance change of 128 memslots insertions with gradually increasing size (the worst case): heap sort custom sort max: 249747 2500 cycles with custom sort alg taking ~98% less then original update time. Signed-off-by: Igor Mammedov Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3a31ec6e396b..c0c2202e6c4f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -668,31 +668,37 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) return 0; } -static int cmp_memslot(const void *slot1, const void *slot2) -{ - struct kvm_memory_slot *s1, *s2; - - s1 = (struct kvm_memory_slot *)slot1; - s2 = (struct kvm_memory_slot *)slot2; - - if (s1->npages < s2->npages) - return 1; - if (s1->npages > s2->npages) - return -1; - - return 0; -} - /* - * Sort the memslots base on its size, so the larger slots - * will get better fit. + * Insert memslot and re-sort memslots based on their size, + * so the larger slots will get better fit. Sorting algorithm + * takes advantage of having initially sorted array and + * known changed memslot position. */ -static void sort_memslots(struct kvm_memslots *slots) +static void insert_memslot(struct kvm_memslots *slots, + struct kvm_memory_slot *new) { - int i; + int i = slots->id_to_index[new->id]; + struct kvm_memory_slot *old = id_to_memslot(slots, new->id); + struct kvm_memory_slot *mslots = slots->memslots; - sort(slots->memslots, KVM_MEM_SLOTS_NUM, - sizeof(struct kvm_memory_slot), cmp_memslot, NULL); + if (new->npages == old->npages) { + *old = *new; + return; + } + + while (1) { + if (i < (KVM_MEM_SLOTS_NUM - 1) && + new->npages < mslots[i + 1].npages) { + mslots[i] = mslots[i + 1]; + i++; + } else if (i > 0 && new->npages > mslots[i - 1].npages) { + mslots[i] = mslots[i - 1]; + i--; + } else { + mslots[i] = *new; + break; + } + } for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) slots->id_to_index[slots->memslots[i].id] = i; @@ -702,13 +708,7 @@ static void update_memslots(struct kvm_memslots *slots, struct kvm_memory_slot *new) { if (new) { - int id = new->id; - struct kvm_memory_slot *old = id_to_memslot(slots, id); - unsigned long npages = old->npages; - - *old = *new; - if (new->npages != npages) - sort_memslots(slots); + insert_memslot(slots, new); } } -- GitLab From 326ac39b68e6aeb57d81c60c6078989955c225b5 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:13 +0000 Subject: [PATCH 4769/9457] drm/i915/skl: Register definitions for SKL Clocks This patch defines the necessary SKL registers for implementing the new clocking mechanism. v2: Addressed review comments by Damien - Added code comment - Introduced enum for WRPLL values v3: Rebase on top of nightly (minor conflict in i915_reg.h) v4: Use 0x, not 0X (Ville) v5: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M (v2) Signed-off-by: Damien Lespiau (v3,v4) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 72 +++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 35cfc16814c0..ba7815d7881e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6430,6 +6430,78 @@ enum punit_power_well { #define LCPLL_CD_SOURCE_FCLK (1<<21) #define LCPLL_CD_SOURCE_FCLK_DONE (1<<19) +/* + * SKL Clocks + */ + +/* CDCLK_CTL */ +#define CDCLK_CTL 0x46000 +#define CDCLK_FREQ_SEL_MASK (3<<26) +#define CDCLK_FREQ_450_432 (0<<26) +#define CDCLK_FREQ_540 (1<<26) +#define CDCLK_FREQ_337_308 (2<<26) +#define CDCLK_FREQ_675_617 (3<<26) +#define CDCLK_FREQ_DECIMAL_MASK (0x7ff) + +/* LCPLL_CTL */ +#define LCPLL1_CTL 0x46010 +#define LCPLL2_CTL 0x46014 +#define LCPLL_PLL_ENABLE (1<<31) + +/* DPLL control1 */ +#define DPLL_CTRL1 0x6C058 +#define DPLL_CTRL1_HDMI_MODE(id) (1<<((id)*6+5)) +#define DPLL_CTRL1_SSC(id) (1<<((id)*6+4)) +#define DPLL_CRTL1_LINK_RATE_MASK(id) (7<<((id)*6+1)) +#define DPLL_CRTL1_LINK_RATE(linkrate, id) ((linkrate)<<((id)*6+1)) +#define DPLL_CTRL1_OVERRIDE(id) (1<<((id)*6)) +#define DPLL_CRTL1_LINK_RATE_2700 0 +#define DPLL_CRTL1_LINK_RATE_1350 1 +#define DPLL_CRTL1_LINK_RATE_810 2 +#define DPLL_CRTL1_LINK_RATE_1620 3 +#define DPLL_CRTL1_LINK_RATE_1080 4 +#define DPLL_CRTL1_LINK_RATE_2160 5 + +/* DPLL control2 */ +#define DPLL_CTRL2 0x6C05C +#define DPLL_CTRL2_DDI_CLK_OFF(port) (1<<(port+15)) +#define DPLL_CTRL2_DDI_CLK_SEL_MASK(port) (3<<((port)*3+1)) +#define DPLL_CTRL2_DDI_CLK_SEL(clk, port) (clk<<((port)*3+1)) +#define DPLL_CTRL2_DDI_SEL_OVERRIDE(port) (1<<((port)*3)) + +/* DPLL Status */ +#define DPLL_STATUS 0x6C060 +#define DPLL_LOCK(id) (1<<((id)*8)) + +/* DPLL cfg */ +#define DPLL1_CFGCR1 0x6C040 +#define DPLL2_CFGCR1 0x6C048 +#define DPLL3_CFGCR1 0x6C050 +#define DPLL_CFGCR1_FREQ_ENABLE (1<<31) +#define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff<<9) +#define DPLL_CFGCR1_DCO_FRACTION(x) (x<<9) +#define DPLL_CFGCR1_DCO_INTEGER_MASK (0x1ff) + +#define DPLL1_CFGCR2 0x6C044 +#define DPLL2_CFGCR2 0x6C04C +#define DPLL3_CFGCR2 0x6C054 +#define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff<<8) +#define DPLL_CFGCR2_QDIV_RATIO(x) (x<<8) +#define DPLL_CFGCR2_QDIV_MODE(x) (x<<7) +#define DPLL_CFGCR2_KDIV_MASK (3<<5) +#define DPLL_CFGCR2_KDIV(x) (x<<5) +#define DPLL_CFGCR2_KDIV_5 (0<<5) +#define DPLL_CFGCR2_KDIV_2 (1<<5) +#define DPLL_CFGCR2_KDIV_3 (2<<5) +#define DPLL_CFGCR2_KDIV_1 (3<<5) +#define DPLL_CFGCR2_PDIV_MASK (7<<2) +#define DPLL_CFGCR2_PDIV(x) (x<<2) +#define DPLL_CFGCR2_PDIV_1 (0<<2) +#define DPLL_CFGCR2_PDIV_2 (1<<2) +#define DPLL_CFGCR2_PDIV_3 (2<<2) +#define DPLL_CFGCR2_PDIV_7 (4<<2) +#define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) + /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, * since on HSW we can't write to it using I915_WRITE. */ #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) -- GitLab From 429d47d524b0c986d5354814077ac5beede5fb68 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:14 +0000 Subject: [PATCH 4770/9457] drm/i915/skl: Structure/enum definitions for SKL clocks Adding structure/enum for SKL clocking implementation. v2: Addressed Damien's comment - Removed internal structure from this header file v3: Stove this into the generic intel_dpll_id enum and give them the established DPLL_ID_ prefixes. (Daniel) v4: - We'll only try to share DPLL1/2/3, leaving DPLL0 to eDP - Use SKL in the skylake shared DPLL names - Re-add the skl_dpll enum (Damien) v5: Remove SKL_DPLL_NONE (Daniel) v6: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M (v2) Signed-off-by: Damien Lespiau (v4,v5) Signed-off-by: Daniel Vetter (v3) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3f3035ce30e6..08128fbe9181 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -213,10 +213,15 @@ enum intel_dpll_id { /* real shared dpll ids must be >= 0 */ DPLL_ID_PCH_PLL_A = 0, DPLL_ID_PCH_PLL_B = 1, + /* hsw/bdw */ DPLL_ID_WRPLL1 = 0, DPLL_ID_WRPLL2 = 1, + /* skl */ + DPLL_ID_SKL_DPLL1 = 0, + DPLL_ID_SKL_DPLL2 = 1, + DPLL_ID_SKL_DPLL3 = 2, }; -#define I915_NUM_PLLS 2 +#define I915_NUM_PLLS 3 struct intel_dpll_hw_state { /* i9xx, pch plls */ @@ -256,6 +261,11 @@ struct intel_shared_dpll { struct intel_dpll_hw_state *hw_state); }; +#define SKL_DPLL0 0 +#define SKL_DPLL1 1 +#define SKL_DPLL2 2 +#define SKL_DPLL3 3 + /* Used by dp and fdi links */ struct intel_link_m_n { uint32_t tu; -- GitLab From 121643c2c9f8d424d1e66ca635828361b687e903 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:15 +0000 Subject: [PATCH 4771/9457] drm/i915/skl: CD clock back calculation for SKL Determine programmed cd clock for SKL. v2: Fix the LCPLL1 enable warning logic v3: Rebase over the hsw pll rework. v4: Rebase on top of the per-platform split (Damien) v5: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 75 ++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 68703cecdefc..01c4f70c545b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1259,6 +1259,54 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) } } +static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv) +{ + uint32_t lcpll1 = I915_READ(LCPLL1_CTL); + uint32_t cdctl = I915_READ(CDCLK_CTL); + uint32_t linkrate; + + if (!(lcpll1 & LCPLL_PLL_ENABLE)) { + WARN(1, "LCPLL1 not enabled\n"); + return 24000; /* 24MHz is the cd freq with NSSC ref */ + } + + if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540) + return 540000; + + linkrate = (I915_READ(DPLL_CTRL1) & + DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1; + + if (linkrate == DPLL_CRTL1_LINK_RATE_2160 || + linkrate == DPLL_CRTL1_LINK_RATE_1080) { + /* vco 8640 */ + switch (cdctl & CDCLK_FREQ_SEL_MASK) { + case CDCLK_FREQ_450_432: + return 432000; + case CDCLK_FREQ_337_308: + return 308570; + case CDCLK_FREQ_675_617: + return 617140; + default: + WARN(1, "Unknown cd freq selection\n"); + } + } else { + /* vco 8100 */ + switch (cdctl & CDCLK_FREQ_SEL_MASK) { + case CDCLK_FREQ_450_432: + return 450000; + case CDCLK_FREQ_337_308: + return 337500; + case CDCLK_FREQ_675_617: + return 675000; + default: + WARN(1, "Unknown cd freq selection\n"); + } + } + + /* error case, do as if DPLL0 isn't enabled */ + return 24000; +} + static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv) { uint32_t lcpll = I915_READ(LCPLL_CTL); @@ -1300,6 +1348,9 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + if (IS_SKYLAKE(dev)) + return skl_get_cdclk_freq(dev_priv); + if (IS_BROADWELL(dev)) return bdw_get_cdclk_freq(dev_priv); @@ -1368,19 +1419,25 @@ void intel_ddi_pll_init(struct drm_device *dev) hsw_shared_dplls_init(dev_priv); - /* The LCPLL register should be turned on by the BIOS. For now let's - * just check its state and print errors in case something is wrong. - * Don't even try to turn it on. - */ - DRM_DEBUG_KMS("CDCLK running at %dKHz\n", intel_ddi_get_cdclk_freq(dev_priv)); - if (val & LCPLL_CD_SOURCE_FCLK) - DRM_ERROR("CDCLK source is not LCPLL\n"); + if (IS_SKYLAKE(dev)) { + if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE)) + DRM_ERROR("LCPLL1 is disabled\n"); + } else { + /* + * The LCPLL register should be turned on by the BIOS. For now + * let's just check its state and print errors in case + * something is wrong. Don't even try to turn it on. + */ + + if (val & LCPLL_CD_SOURCE_FCLK) + DRM_ERROR("CDCLK source is not LCPLL\n"); - if (val & LCPLL_PLL_DISABLE) - DRM_ERROR("LCPLL is disabled\n"); + if (val & LCPLL_PLL_DISABLE) + DRM_ERROR("LCPLL is disabled\n"); + } } void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) -- GitLab From 540e732c8e2d90a18c9a7798451c2cdf78b9acb6 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:16 +0000 Subject: [PATCH 4772/9457] drm/i915/skl: Determine enabled PLL and its linkrate/pixel clock v2: Fixup compilation due to the removal of the intel_ddi_dpll_id enum. And add a fixme about the abuse of pipe_config here. v3: Rebase on top of the hsw_ddi_clock_get() rename (Damien) v4: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M (v1) Signed-off-by: Damien Lespiau (v3) Signed-off-by: Daniel Vetter (v2) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 5 ++ drivers/gpu/drm/i915/intel_ddi.c | 115 ++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ba7815d7881e..c443008e99d8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6453,6 +6453,7 @@ enum punit_power_well { #define DPLL_CTRL1_HDMI_MODE(id) (1<<((id)*6+5)) #define DPLL_CTRL1_SSC(id) (1<<((id)*6+4)) #define DPLL_CRTL1_LINK_RATE_MASK(id) (7<<((id)*6+1)) +#define DPLL_CRTL1_LINK_RATE_SHIFT(id) ((id)*6+1) #define DPLL_CRTL1_LINK_RATE(linkrate, id) ((linkrate)<<((id)*6+1)) #define DPLL_CTRL1_OVERRIDE(id) (1<<((id)*6)) #define DPLL_CRTL1_LINK_RATE_2700 0 @@ -6466,6 +6467,7 @@ enum punit_power_well { #define DPLL_CTRL2 0x6C05C #define DPLL_CTRL2_DDI_CLK_OFF(port) (1<<(port+15)) #define DPLL_CTRL2_DDI_CLK_SEL_MASK(port) (3<<((port)*3+1)) +#define DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port) ((port)*3+1) #define DPLL_CTRL2_DDI_CLK_SEL(clk, port) (clk<<((port)*3+1)) #define DPLL_CTRL2_DDI_SEL_OVERRIDE(port) (1<<((port)*3)) @@ -6502,6 +6504,9 @@ enum punit_power_well { #define DPLL_CFGCR2_PDIV_7 (4<<2) #define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) +#define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - SKL_DPLL1) * 8) +#define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - SKL_DPLL1) * 8) + /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, * since on HSW we can't write to it using I915_WRITE. */ #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 01c4f70c545b..b06b21394d8d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -670,6 +670,115 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, return (refclk * n * 100) / (p * r); } +static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv, + uint32_t dpll) +{ + uint32_t cfgcr1_reg, cfgcr2_reg; + uint32_t cfgcr1_val, cfgcr2_val; + uint32_t p0, p1, p2, dco_freq; + + cfgcr1_reg = GET_CFG_CR1_REG(dpll); + cfgcr2_reg = GET_CFG_CR2_REG(dpll); + + cfgcr1_val = I915_READ(cfgcr1_reg); + cfgcr2_val = I915_READ(cfgcr2_reg); + + p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK; + p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK; + + if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1)) + p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8; + else + p1 = 1; + + + switch (p0) { + case DPLL_CFGCR2_PDIV_1: + p0 = 1; + break; + case DPLL_CFGCR2_PDIV_2: + p0 = 2; + break; + case DPLL_CFGCR2_PDIV_3: + p0 = 3; + break; + case DPLL_CFGCR2_PDIV_7: + p0 = 7; + break; + } + + switch (p2) { + case DPLL_CFGCR2_KDIV_5: + p2 = 5; + break; + case DPLL_CFGCR2_KDIV_2: + p2 = 2; + break; + case DPLL_CFGCR2_KDIV_3: + p2 = 3; + break; + case DPLL_CFGCR2_KDIV_1: + p2 = 1; + break; + } + + dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000; + + dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 * + 1000) / 0x8000; + + return dco_freq / (p0 * p1 * p2 * 5); +} + + +static void skl_ddi_clock_get(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + enum port port = intel_ddi_get_encoder_port(encoder); + int link_clock = 0; + uint32_t dpll_ctl1, dpll; + + /* FIXME: This should be tracked in the pipe config. */ + dpll = I915_READ(DPLL_CTRL2); + dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port); + dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); + + dpll_ctl1 = I915_READ(DPLL_CTRL1); + + if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) { + link_clock = skl_calc_wrpll_link(dev_priv, dpll); + } else { + link_clock = dpll_ctl1 & DPLL_CRTL1_LINK_RATE_MASK(dpll); + link_clock >>= DPLL_CRTL1_LINK_RATE_SHIFT(dpll); + + switch (link_clock) { + case DPLL_CRTL1_LINK_RATE_810: + link_clock = 81000; + break; + case DPLL_CRTL1_LINK_RATE_1350: + link_clock = 135000; + break; + case DPLL_CRTL1_LINK_RATE_2700: + link_clock = 270000; + break; + default: + WARN(1, "Unsupported link rate\n"); + break; + } + link_clock *= 2; + } + + pipe_config->port_clock = link_clock; + + if (pipe_config->has_dp_encoder) + pipe_config->adjusted_mode.crtc_clock = + intel_dotclock_calculate(pipe_config->port_clock, + &pipe_config->dp_m_n); + else + pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock; +} + static void hsw_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) { @@ -1533,6 +1642,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; u32 temp, flags = 0; + struct drm_device *dev = dev_priv->dev; temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (temp & TRANS_DDI_PHSYNC) @@ -1604,7 +1714,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder, dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; } - hsw_ddi_clock_get(encoder, pipe_config); + if (INTEL_INFO(dev)->gen <= 8) + hsw_ddi_clock_get(encoder, pipe_config); + else + skl_ddi_clock_get(encoder, pipe_config); } static void intel_ddi_destroy(struct drm_encoder *encoder) -- GitLab From 96b7dfb785f55b4bbe75e3c6673e2482d2955ad5 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:17 +0000 Subject: [PATCH 4773/9457] drm/i915/skl: Query DPLL attached to port on SKL Modify the implementation to query DPLL attached to a SKL port. v2: Rebase on top of the run-time PM on DPMS series (Damien) v3: Modified as per review comments from Paulo Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 29 +++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 5 ++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eac54c6db11f..c34d0883b251 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7960,6 +7960,30 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc) return 0; } +static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, + enum port port, + struct intel_crtc_config *pipe_config) +{ + u32 temp; + + temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); + pipe_config->ddi_pll_sel = temp >> (port * 3 + 1); + + switch (pipe_config->ddi_pll_sel) { + case SKL_DPLL1: + pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1; + break; + case SKL_DPLL2: + pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2; + break; + case SKL_DPLL3: + pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; + break; + default: + WARN(1, "Unknown DPLL programmed\n"); + } +} + static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_config *pipe_config) @@ -7989,7 +8013,10 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT; - haswell_get_ddi_pll(dev_priv, port, pipe_config); + if (IS_SKYLAKE(dev)) + skylake_get_ddi_pll(dev_priv, port, pipe_config); + else + haswell_get_ddi_pll(dev_priv, port, pipe_config); if (pipe_config->shared_dpll >= 0) { pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8432ae2d41f0..d67c59b15128 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -343,7 +343,10 @@ struct intel_crtc_config { /* Selected dpll when shared or DPLL_ID_PRIVATE. */ enum intel_dpll_id shared_dpll; - /* PORT_CLK_SEL for DDI ports. */ + /* + * - PORT_CLK_SEL for DDI ports on HSW/BDW. + * - enum skl_dpll on SKL + */ uint32_t ddi_pll_sel; /* Actual register state of the dpll, for shared dpll cross-checking. */ -- GitLab From d1a2dc7835f1258ac91cbdd8da1bc97b029b80f7 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:18 +0000 Subject: [PATCH 4774/9457] drm/i915/skl: Define shared DPLLs for Skylake On skylake, DPLL 1, 2 and 3 can be used for DP and HDMI. The shared dpll framework allows us to share those DPLLs among DDIs when possible. The most tricky part is to provide a DPLL state that can be easily compared. DPLL_CRTL1 is shared by all the DPLLs, 6 bits each. The per-dpll crtl1 field of the hw state is then normalized to be the same value if 2 DPLLs do indeed have identical values for those 6 bits. v2: Port the code to the shared DPLL infrastructure (Damien) v3: Rebase on top of Ander's clock computation staging work for atomic (Damien) Reviewed-by: Paulo Zanoni (v2) Signed-off-by: Satheeshakrishna M (v1) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 11 +++ drivers/gpu/drm/i915/intel_ddi.c | 126 ++++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 08128fbe9181..c4f2cb6f4234 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -232,6 +232,17 @@ struct intel_dpll_hw_state { /* hsw, bdw */ uint32_t wrpll; + + /* skl */ + /* + * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in + * lower part of crtl1 and they get shifted into position when writing + * the register. This allows us to easily compare the state to share + * the DPLL. + */ + uint32_t ctrl1; + /* HDMI only, 0 when used for DP */ + uint32_t cfgcr1, cfgcr2; }; struct intel_shared_dpll_config { diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b06b21394d8d..5391c1e19ec7 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1521,12 +1521,136 @@ static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) } } +static const char * const skl_ddi_pll_names[] = { + "DPLL 1", + "DPLL 2", + "DPLL 3", +}; + +struct skl_dpll_regs { + u32 ctl, cfgcr1, cfgcr2; +}; + +/* this array is indexed by the *shared* pll id */ +static const struct skl_dpll_regs skl_dpll_regs[3] = { + { + /* DPLL 1 */ + .ctl = LCPLL2_CTL, + .cfgcr1 = DPLL1_CFGCR1, + .cfgcr2 = DPLL1_CFGCR2, + }, + { + /* DPLL 2 */ + .ctl = WRPLL_CTL1, + .cfgcr1 = DPLL2_CFGCR1, + .cfgcr2 = DPLL2_CFGCR2, + }, + { + /* DPLL 3 */ + .ctl = WRPLL_CTL2, + .cfgcr1 = DPLL3_CFGCR1, + .cfgcr2 = DPLL3_CFGCR2, + }, +}; + +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + uint32_t val; + unsigned int dpll; + const struct skl_dpll_regs *regs = skl_dpll_regs; + + /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ + dpll = pll->id + 1; + + val = I915_READ(DPLL_CTRL1); + + val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) | + DPLL_CRTL1_LINK_RATE_MASK(dpll)); + val |= pll->config.hw_state.ctrl1 << (dpll * 6); + + I915_WRITE(DPLL_CTRL1, val); + POSTING_READ(DPLL_CTRL1); + + I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1); + I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2); + POSTING_READ(regs[pll->id].cfgcr1); + POSTING_READ(regs[pll->id].cfgcr2); + + /* the enable bit is always bit 31 */ + I915_WRITE(regs[pll->id].ctl, + I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); + + if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5)) + DRM_ERROR("DPLL %d not locked\n", dpll); +} + +static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + const struct skl_dpll_regs *regs = skl_dpll_regs; + + /* the enable bit is always bit 31 */ + I915_WRITE(regs[pll->id].ctl, + I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE); + POSTING_READ(regs[pll->id].ctl); +} + +static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + uint32_t val; + unsigned int dpll; + const struct skl_dpll_regs *regs = skl_dpll_regs; + + if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) + return false; + + /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ + dpll = pll->id + 1; + + val = I915_READ(regs[pll->id].ctl); + if (!(val & LCPLL_PLL_ENABLE)) + return false; + + val = I915_READ(DPLL_CTRL1); + hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; + + /* avoid reading back stale values if HDMI mode is not enabled */ + if (val & DPLL_CTRL1_HDMI_MODE(dpll)) { + hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); + hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); + } + + return true; +} + +static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) +{ + int i; + + dev_priv->num_shared_dpll = 3; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i]; + dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable; + dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable; + dev_priv->shared_dplls[i].get_hw_state = + skl_ddi_pll_get_hw_state; + } +} + void intel_ddi_pll_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t val = I915_READ(LCPLL_CTL); - hsw_shared_dplls_init(dev_priv); + if (IS_SKYLAKE(dev)) + skl_shared_dplls_init(dev_priv); + else + hsw_shared_dplls_init(dev_priv); DRM_DEBUG_KMS("CDCLK running at %dKHz\n", intel_ddi_get_cdclk_freq(dev_priv)); -- GitLab From efa80add54d12bdeba996220463b6ee4ff6b81ae Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:19 +0000 Subject: [PATCH 4775/9457] drm/i915/skl: Adjust the port PLL selection code Skylake deprecates the usage of PORT_CLK_SEL and we are advised to use the new DPLL_CRTL2 for the DDI->PLL mapping. v2: Modified as per review comments Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5391c1e19ec7..5f786b476a39 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1243,7 +1243,8 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; @@ -1253,8 +1254,22 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_edp_panel_on(intel_dp); } - WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE); - I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel); + if (IS_SKYLAKE(dev)) { + uint32_t dpll = crtc->config.ddi_pll_sel; + uint32_t val; + + val = I915_READ(DPLL_CTRL2); + + val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) | + DPLL_CTRL2_DDI_CLK_SEL_MASK(port)); + val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) | + DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); + + I915_WRITE(DPLL_CTRL2, val); + } else { + WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE); + I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel); + } if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1278,7 +1293,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; uint32_t val; @@ -1306,7 +1322,11 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) intel_edp_panel_off(intel_dp); } - I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); + if (IS_SKYLAKE(dev)) + I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) | + DPLL_CTRL2_DDI_CLK_OFF(port))); + else + I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); } static void intel_enable_ddi(struct intel_encoder *intel_encoder) -- GitLab From 82d35437018950c25200051733fb2fbf63cca86c Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Thu, 13 Nov 2014 14:55:20 +0000 Subject: [PATCH 4776/9457] drm/i915/skl: Implementation of SKL DPLL programming This patch implements SKL DPLL programming that includes: - DPLL allocation - wide range PLL calculation and programming - DP link rate programming - DDI to DPLL mapping v2: Incorporated following changes - Added vfunc for function required outside - Fixed multiple comments in WRPLL calculation v3: - Fix the DCO computation - Move the initialization up to not clobber the computed values - Use the correct macro for DP link rate programming. - Use wait_for() to wait for the PLL locked bit v4: Rebase on top of nigthly (Damien) v5: A few code cleanups in the WRPLL computation (Damien) - Use uint32_t when possible - Use abs_diff() in the WRPLL computation - Make the 64bits divisions use div64_u64() - Fix typo in dco_central_feq_deviation (freq) - Replace the chain of breaks with a goto v6: Port of the patch to work on top of the shared DPLLs (Damien) v7: Don't try to handle eDP in ddi_pll_select() (Damien) v8: Modified as per review comments from Paulo (Satheesh) v9: Rebase on top of Ander's clock computation staging work for atomic (Damien) Reviewed-by: Paulo Zanoni Signed-off-by: Satheeshakrishna M (v3) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 226 ++++++++++++++++++++++++++++++- 1 file changed, 225 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5f786b476a39..df4b608894e9 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -937,6 +937,226 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, return true; } +struct skl_wrpll_params { + uint32_t dco_fraction; + uint32_t dco_integer; + uint32_t qdiv_ratio; + uint32_t qdiv_mode; + uint32_t kdiv; + uint32_t pdiv; + uint32_t central_freq; +}; + +static void +skl_ddi_calculate_wrpll(int clock /* in Hz */, + struct skl_wrpll_params *wrpll_params) +{ + uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */ + uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000}; + uint32_t min_dco_deviation = 400; + uint32_t min_dco_index = 3; + uint32_t P0[4] = {1, 2, 3, 7}; + uint32_t P2[4] = {1, 2, 3, 5}; + bool found = false; + uint32_t candidate_p = 0; + uint32_t candidate_p0[3] = {0}, candidate_p1[3] = {0}; + uint32_t candidate_p2[3] = {0}; + uint32_t dco_central_freq_deviation[3]; + uint32_t i, P1, k, dco_count; + bool retry_with_odd = false; + uint64_t dco_freq; + + /* Determine P0, P1 or P2 */ + for (dco_count = 0; dco_count < 3; dco_count++) { + found = false; + candidate_p = + div64_u64(dco_central_freq[dco_count], afe_clock); + if (retry_with_odd == false) + candidate_p = (candidate_p % 2 == 0 ? + candidate_p : candidate_p + 1); + + for (P1 = 1; P1 < candidate_p; P1++) { + for (i = 0; i < 4; i++) { + if (!(P0[i] != 1 || P1 == 1)) + continue; + + for (k = 0; k < 4; k++) { + if (P1 != 1 && P2[k] != 2) + continue; + + if (candidate_p == P0[i] * P1 * P2[k]) { + /* Found possible P0, P1, P2 */ + found = true; + candidate_p0[dco_count] = P0[i]; + candidate_p1[dco_count] = P1; + candidate_p2[dco_count] = P2[k]; + goto found; + } + + } + } + } + +found: + if (found) { + dco_central_freq_deviation[dco_count] = + div64_u64(10000 * + abs_diff((candidate_p * afe_clock), + dco_central_freq[dco_count]), + dco_central_freq[dco_count]); + + if (dco_central_freq_deviation[dco_count] < + min_dco_deviation) { + min_dco_deviation = + dco_central_freq_deviation[dco_count]; + min_dco_index = dco_count; + } + } + + if (min_dco_index > 2 && dco_count == 2) { + retry_with_odd = true; + dco_count = 0; + } + } + + if (min_dco_index > 2) { + WARN(1, "No valid values found for the given pixel clock\n"); + } else { + wrpll_params->central_freq = dco_central_freq[min_dco_index]; + + switch (dco_central_freq[min_dco_index]) { + case 9600000000: + wrpll_params->central_freq = 0; + break; + case 9000000000: + wrpll_params->central_freq = 1; + break; + case 8400000000: + wrpll_params->central_freq = 3; + } + + switch (candidate_p0[min_dco_index]) { + case 1: + wrpll_params->pdiv = 0; + break; + case 2: + wrpll_params->pdiv = 1; + break; + case 3: + wrpll_params->pdiv = 2; + break; + case 7: + wrpll_params->pdiv = 4; + break; + default: + WARN(1, "Incorrect PDiv\n"); + } + + switch (candidate_p2[min_dco_index]) { + case 5: + wrpll_params->kdiv = 0; + break; + case 2: + wrpll_params->kdiv = 1; + break; + case 3: + wrpll_params->kdiv = 2; + break; + case 1: + wrpll_params->kdiv = 3; + break; + default: + WARN(1, "Incorrect KDiv\n"); + } + + wrpll_params->qdiv_ratio = candidate_p1[min_dco_index]; + wrpll_params->qdiv_mode = + (wrpll_params->qdiv_ratio == 1) ? 0 : 1; + + dco_freq = candidate_p0[min_dco_index] * + candidate_p1[min_dco_index] * + candidate_p2[min_dco_index] * afe_clock; + + /* + * Intermediate values are in Hz. + * Divide by MHz to match bsepc + */ + wrpll_params->dco_integer = div_u64(dco_freq, (24 * MHz(1))); + wrpll_params->dco_fraction = + div_u64(((div_u64(dco_freq, 24) - + wrpll_params->dco_integer * MHz(1)) * 0x8000), MHz(1)); + + } +} + + +static bool +skl_ddi_pll_select(struct intel_crtc *intel_crtc, + struct intel_encoder *intel_encoder, + int clock) +{ + struct intel_shared_dpll *pll; + uint32_t ctrl1, cfgcr1, cfgcr2; + + /* + * See comment in intel_dpll_hw_state to understand why we always use 0 + * as the DPLL id in this function. + */ + + ctrl1 = DPLL_CTRL1_OVERRIDE(0); + + if (intel_encoder->type == INTEL_OUTPUT_HDMI) { + struct skl_wrpll_params wrpll_params = { 0, }; + + ctrl1 |= DPLL_CTRL1_HDMI_MODE(0); + + skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params); + + cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE | + DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) | + wrpll_params.dco_integer; + + cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) | + DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) | + DPLL_CFGCR2_KDIV(wrpll_params.kdiv) | + DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | + wrpll_params.central_freq; + } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { + struct drm_encoder *encoder = &intel_encoder->base; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + switch (intel_dp->link_bw) { + case DP_LINK_BW_1_62: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, 0); + break; + case DP_LINK_BW_2_7: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, 0); + break; + case DP_LINK_BW_5_4: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, 0); + break; + } + + cfgcr1 = cfgcr2 = 0; + } else /* eDP */ + return true; + + intel_crtc->new_config->dpll_hw_state.ctrl1 = ctrl1; + intel_crtc->new_config->dpll_hw_state.cfgcr1 = cfgcr1; + intel_crtc->new_config->dpll_hw_state.cfgcr2 = cfgcr2; + + pll = intel_get_shared_dpll(intel_crtc); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(intel_crtc->pipe)); + return false; + } + + /* shared DPLL id 0 is DPLL 1 */ + intel_crtc->new_config->ddi_pll_sel = pll->id + 1; + + return true; +} /* * Tries to find a *shared* PLL for the CRTC and store it in @@ -947,11 +1167,15 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, */ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) { + struct drm_device *dev = intel_crtc->base.dev; struct intel_encoder *intel_encoder = intel_ddi_get_crtc_new_encoder(intel_crtc); int clock = intel_crtc->new_config->port_clock; - return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock); + if (IS_SKYLAKE(dev)) + return skl_ddi_pll_select(intel_crtc, intel_encoder, clock); + else + return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock); } void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) -- GitLab From 3f4cd19ff84232174fcf3ede12c612bdee420d4a Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 13 Nov 2014 14:55:21 +0000 Subject: [PATCH 4777/9457] drm/i915/skl: Provide skl-specific pll hw state cross-checking v2: rebase on top of the hw state flattening. Reviewed-by: Paulo Zanoni Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c34d0883b251..c60bfbd9b5f4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10444,6 +10444,9 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_X(dpll_hw_state.fp0); PIPE_CONF_CHECK_X(dpll_hw_state.fp1); PIPE_CONF_CHECK_X(dpll_hw_state.wrpll); + PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1); + PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1); + PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2); if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) PIPE_CONF_CHECK_I(pipe_bpp); -- GitLab From 23f08d8340e13c02fc2e5f64febc9fbd54e58770 Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Thu, 13 Nov 2014 14:55:22 +0000 Subject: [PATCH 4778/9457] drm/i915/skl: Apply eDP WA only for gen < 9 The eDP WA to stop link train based on port type is for HSW/BDW, not required for SKL+. Suggested by Satheesh v2: Simplified the check befoe stop_link_train. Suggested by Satheesh. v3: stop_link_train need not be called from intel_enable_ddi for gen >= 9 Suggested-by: Satheeshakrishna M Reviewed-by: Paulo Zanoni Reviewed-by: Satheeshakrishna M Signed-off-by: Vandana Kannan Cc: Satheeshakrishna M Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index df4b608894e9..17bf9116fab1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1503,7 +1503,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); - if (port != PORT_A) + if (port != PORT_A || INTEL_INFO(dev)->gen >= 9) intel_dp_stop_link_train(intel_dp); } else if (type == INTEL_OUTPUT_HDMI) { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); @@ -1577,7 +1577,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) } else if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (port == PORT_A) + if (port == PORT_A && INTEL_INFO(dev)->gen < 9) intel_dp_stop_link_train(intel_dp); intel_edp_backlight_on(intel_dp); -- GitLab From 830c81db2dc9dccc505adc7d4651324ea5332add Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 13 Nov 2014 17:51:46 +0000 Subject: [PATCH 4779/9457] drm/i915/skl: Implement queue_flip A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes. DE_RRMR seems to have kept its plane flip bits backward compatible. v2: Rebase on top of nightly v3: Rebase on top of nightly (minor conflict in i915_reg.h) v4: Remove code that is now part of intel_crtc_page_flip() Don't use BUG() in default: Use intel_crtc->unpin_work->gtt_offset (Paulo) Reviewed-by: Paulo Zanoni Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 10 +++++ drivers/gpu/drm/i915/intel_display.c | 66 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c443008e99d8..2bdfe0810684 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -248,6 +248,16 @@ #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) +/* SKL ones */ +#define MI_DISPLAY_FLIP_SKL_PLANE_1_A (0 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_1_B (1 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_1_C (2 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_A (4 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_B (5 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_C (6 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_A (7 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_B (8 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_C (9 << 8) #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */ #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) #define MI_SEMAPHORE_UPDATE (1<<21) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c60bfbd9b5f4..8f47b988a233 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9480,6 +9480,69 @@ static int intel_queue_mmio_flip(struct drm_device *dev, return 0; } +static int intel_gen9_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, + struct intel_engine_cs *ring, + uint32_t flags) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t plane = 0, stride; + int ret; + + switch(intel_crtc->pipe) { + case PIPE_A: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A; + break; + case PIPE_B: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B; + break; + case PIPE_C: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C; + break; + default: + WARN_ONCE(1, "unknown plane in flip command\n"); + return -ENODEV; + } + + switch (obj->tiling_mode) { + case I915_TILING_NONE: + stride = fb->pitches[0] >> 6; + break; + case I915_TILING_X: + stride = fb->pitches[0] >> 9; + break; + default: + WARN_ONCE(1, "unknown tiling in flip command\n"); + return -ENODEV; + } + + ret = intel_ring_begin(ring, 10); + if (ret) + return ret; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, DERRMR); + intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE | + DERRMR_PIPEB_PRI_FLIP_DONE | + DERRMR_PIPEC_PRI_FLIP_DONE)); + intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) | + MI_SRM_LRM_GLOBAL_GTT); + intel_ring_emit(ring, DERRMR); + intel_ring_emit(ring, ring->scratch.gtt_offset + 256); + intel_ring_emit(ring, 0); + + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane); + intel_ring_emit(ring, stride << 6 | obj->tiling_mode); + intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); + + intel_mark_page_flip_active(intel_crtc); + __intel_ring_advance(ring); + + return 0; +} + static int intel_default_queue_flip(struct drm_device *dev, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -12648,6 +12711,9 @@ static void intel_init_display(struct drm_device *dev) case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */ dev_priv->display.queue_flip = intel_gen7_queue_flip; break; + case 9: + dev_priv->display.queue_flip = intel_gen9_queue_flip; + break; } intel_panel_init_backlight_funcs(dev); -- GitLab From bd2e244f847d8e8067afc30fa979b3968085cbb2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 13 Nov 2014 17:51:47 +0000 Subject: [PATCH 4780/9457] drm/i915/skl: fetch, enable/disable pfit as needed v2 This moved around on SKL, so we need to make sure we read/write the correct regs. v2: fixup WIN_POS offsets (Paulo) zero out WIN_POS reg at disable time (Paulo) Reviewed-by: Paulo Zanoni Signed-off-by: Jesse Barnes Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++ drivers/gpu/drm/i915/intel_display.c | 62 ++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2bdfe0810684..afab1dcf2b58 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4916,6 +4916,18 @@ enum punit_power_well { #define PF_VSCALE(pipe) _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) #define PF_HSCALE(pipe) _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE) +#define _PSA_CTL 0x68180 +#define _PSB_CTL 0x68980 +#define PS_ENABLE (1<<31) +#define _PSA_WIN_SZ 0x68174 +#define _PSB_WIN_SZ 0x68974 +#define _PSA_WIN_POS 0x68170 +#define _PSB_WIN_POS 0x68970 + +#define PS_CTL(pipe) _PIPE(pipe, _PSA_CTL, _PSB_CTL) +#define PS_WIN_SZ(pipe) _PIPE(pipe, _PSA_WIN_SZ, _PSB_WIN_SZ) +#define PS_WIN_POS(pipe) _PIPE(pipe, _PSA_WIN_POS, _PSB_WIN_POS) + /* legacy palette */ #define _LGC_PALETTE_A 0x4a000 #define _LGC_PALETTE_B 0x4a800 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8f47b988a233..c42a0401bfa5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4003,6 +4003,19 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe) } } +static void skylake_pfit_enable(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + + if (crtc->config.pch_pfit.enabled) { + I915_WRITE(PS_CTL(pipe), PS_ENABLE); + I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos); + I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size); + } +} + static void ironlake_pfit_enable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -4386,7 +4399,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_ddi_enable_pipe_clock(intel_crtc); - ironlake_pfit_enable(intel_crtc); + if (IS_SKYLAKE(dev)) + skylake_pfit_enable(intel_crtc); + else + ironlake_pfit_enable(intel_crtc); /* * On ILK+ LUT must be loaded before the pipe is running but with @@ -4420,6 +4436,21 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_crtc_enable_planes(crtc); } +static void skylake_pfit_disable(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + + /* To avoid upsetting the power well on haswell only disable the pfit if + * it's in use. The hw state code will make sure we get this right. */ + if (crtc->config.pch_pfit.enabled) { + I915_WRITE(PS_CTL(pipe), 0); + I915_WRITE(PS_WIN_POS(pipe), 0); + I915_WRITE(PS_WIN_SZ(pipe), 0); + } +} + static void ironlake_pfit_disable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -4532,7 +4563,10 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); - ironlake_pfit_disable(intel_crtc); + if (IS_SKYLAKE(dev)) + skylake_pfit_disable(intel_crtc); + else + ironlake_pfit_disable(intel_crtc); intel_ddi_disable_pipe_clock(intel_crtc); @@ -7547,6 +7581,22 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc, &pipe_config->fdi_m_n, NULL); } +static void skylake_get_pfit_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + + tmp = I915_READ(PS_CTL(crtc->pipe)); + + if (tmp & PS_ENABLE) { + pipe_config->pch_pfit.enabled = true; + pipe_config->pch_pfit.pos = I915_READ(PS_WIN_POS(crtc->pipe)); + pipe_config->pch_pfit.size = I915_READ(PS_WIN_SZ(crtc->pipe)); + } +} + static void ironlake_get_pfit_config(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config) { @@ -8092,8 +8142,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, intel_get_pipe_timings(crtc, pipe_config); pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); - if (intel_display_power_is_enabled(dev_priv, pfit_domain)) - ironlake_get_pfit_config(crtc, pipe_config); + if (intel_display_power_is_enabled(dev_priv, pfit_domain)) { + if (IS_SKYLAKE(dev)) + skylake_get_pfit_config(crtc, pipe_config); + else + ironlake_get_pfit_config(crtc, pipe_config); + } if (IS_HASWELL(dev)) pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && -- GitLab From 88e047034084ca24d9b6a78843f83589ad296961 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 13 Nov 2014 17:51:48 +0000 Subject: [PATCH 4781/9457] drm/i915/skl: AUX irqs have moved Use the new AUX port irq bits where needed. v2: Rebase on top of upstream changes v3: Rebase on top of Oscar change to write IIR as soon as possible (Damien) v4: Rebase on top of the for_each_pipe() change adding dev_priv as first argument (Damien) Reviewed-by: Mika Kuoppala Signed-off-by: Jesse Barnes Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++++++---- drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 729e9a329f76..320b310ebff5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2221,6 +2221,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) irqreturn_t ret = IRQ_NONE; uint32_t tmp = 0; enum pipe pipe; + u32 aux_mask = GEN8_AUX_CHANNEL_A; + + if (IS_GEN9(dev)) + aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | + GEN9_AUX_CHANNEL_D; master_ctl = I915_READ(GEN8_MASTER_IRQ); master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; @@ -2253,7 +2258,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) if (tmp) { I915_WRITE(GEN8_DE_PORT_IIR, tmp); ret = IRQ_HANDLED; - if (tmp & GEN8_AUX_CHANNEL_A) + + if (tmp & aux_mask) dp_aux_irq_handler(dev); else DRM_ERROR("Unexpected DE Port interrupt\n"); @@ -3487,11 +3493,14 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) uint32_t de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; uint32_t de_pipe_enables; int pipe; + u32 aux_en = GEN8_AUX_CHANNEL_A; - if (IS_GEN9(dev_priv)) + if (IS_GEN9(dev_priv)) { de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE | GEN9_DE_PIPE_IRQ_FAULT_ERRORS; - else + aux_en |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | + GEN9_AUX_CHANNEL_D; + } else de_pipe_masked |= GEN8_PIPE_PRIMARY_FLIP_DONE | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; @@ -3509,7 +3518,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->de_irq_mask[pipe], de_pipe_enables); - GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A); + GEN5_IRQ_INIT(GEN8_DE_PORT_, ~aux_en, aux_en); } static int gen8_irq_postinstall(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index afab1dcf2b58..de24caf4b9af 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5072,6 +5072,9 @@ enum punit_power_well { #define GEN8_DE_PORT_IIR 0x44448 #define GEN8_DE_PORT_IER 0x4444c #define GEN8_PORT_DP_A_HOTPLUG (1 << 3) +#define GEN9_AUX_CHANNEL_D (1 << 27) +#define GEN9_AUX_CHANNEL_C (1 << 26) +#define GEN9_AUX_CHANNEL_B (1 << 25) #define GEN8_AUX_CHANNEL_A (1 << 0) #define GEN8_DE_MISC_ISR 0x44460 -- GitLab From 468c6816b502614f6d5881af220f34baf72cd285 Mon Sep 17 00:00:00 2001 From: "Michael H. Nguyen" Date: Thu, 13 Nov 2014 17:51:49 +0000 Subject: [PATCH 4782/9457] drm/i915/skl: Add Gen9 LRC size The LRC increased in size on gen9. Make sure we return the right size in get_lr_context_size() v2. Corrected the size, should be 22 pages. I unintentionally mailed out a test patch w/ size equaling 23 pages. Reviewed-by: Damien Lespiau Signed-off-by: Michael H. Nguyen Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2a1a71933420..af0c18a0aefe 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -136,6 +136,7 @@ #include #include "i915_drv.h" +#define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE) #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) #define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE) @@ -1671,11 +1672,14 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) { int ret = 0; - WARN_ON(INTEL_INFO(ring->dev)->gen != 8); + WARN_ON(INTEL_INFO(ring->dev)->gen < 8); switch (ring->id) { case RCS: - ret = GEN8_LR_CONTEXT_RENDER_SIZE; + if (INTEL_INFO(ring->dev)->gen >= 9) + ret = GEN9_LR_CONTEXT_RENDER_SIZE; + else + ret = GEN8_LR_CONTEXT_RENDER_SIZE; break; case VCS: case BCS: -- GitLab From dddab346d8285428ddfeab25c4156368bd37414d Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 13 Nov 2014 17:51:50 +0000 Subject: [PATCH 4783/9457] drm/i915: Clear PCODE_DATA1 on SNB+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ville found out that the DATA1 register exists since SNB with some scarce apparitions in the specs throughout the times. In his own words: Also according to Bspec the mailbox data1 register already existed since snb. The hsw cdclk change sequence also mentions that it should be set to 0, but eg. the bdw IPS sequence doesn't mention it. I guess in theory some pcode command might cause it to be clobbered, so I'm thinking we should just explicitly set it to 0 for all platforms in the pcode read/write functions Reviewed-by: Ville Syrjälä Suggested-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index de24caf4b9af..a143127eb451 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6041,8 +6041,8 @@ enum punit_power_well { #define GEN6_PCODE_DATA 0x138128 #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 +#define GEN6_PCODE_DATA1 0x13812C -#define GEN9_PCODE_DATA1 0x13812C #define GEN9_PCODE_READ_MEM_LATENCY 0x6 #define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF #define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9e87265f2448..0c705d9ba8be 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7164,8 +7164,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) } I915_WRITE(GEN6_PCODE_DATA, *val); - if (INTEL_INFO(dev_priv)->gen >= 9) - I915_WRITE(GEN9_PCODE_DATA1, 0); + I915_WRITE(GEN6_PCODE_DATA1, 0); I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, -- GitLab From 6e7cc470bc182389af15c9b7fe78bb40b7dc44e9 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 13 Nov 2014 17:51:51 +0000 Subject: [PATCH 4784/9457] drm/i915/skl: Use correct use counters for force wakes Write and reads following the block changed use engine specific use counters and unless that is matched here force wake use counting goes bad. Same force wake is attempted to be taken twice which leads to at least time outs. NOTE: Depending on feedback from hardware designers it may not be necessary to grab force wakes on Gen9 here. But for Gen8 it is needed due to a race between RC6 and ELSP writes. v2: Added blitter force wake engine and made more future proof. Added commit note. Reviewed-by: Damien Lespiau Signed-off-by: Tvrtko Ursulin Cc: Damien Lespiau Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index af0c18a0aefe..0eee4288519b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -276,7 +276,8 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, struct drm_i915_gem_object *ctx_obj0, struct drm_i915_gem_object *ctx_obj1) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; uint64_t temp = 0; uint32_t desc[4]; unsigned long flags; @@ -301,13 +302,18 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, * Instead, we do the runtime_pm_get/put when creating/destroying requests. */ spin_lock_irqsave(&dev_priv->uncore.lock, flags); - if (IS_CHERRYVIEW(dev_priv->dev)) { + if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) { if (dev_priv->uncore.fw_rendercount++ == 0) dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_RENDER); if (dev_priv->uncore.fw_mediacount++ == 0) dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_MEDIA); + if (INTEL_INFO(dev)->gen >= 9) { + if (dev_priv->uncore.fw_blittercount++ == 0) + dev_priv->uncore.funcs.force_wake_get(dev_priv, + FORCEWAKE_BLITTER); + } } else { if (dev_priv->uncore.forcewake_count++ == 0) dev_priv->uncore.funcs.force_wake_get(dev_priv, @@ -326,13 +332,18 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, /* Release Force Wakeup (see the big comment above). */ spin_lock_irqsave(&dev_priv->uncore.lock, flags); - if (IS_CHERRYVIEW(dev_priv->dev)) { + if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) { if (--dev_priv->uncore.fw_rendercount == 0) dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_RENDER); if (--dev_priv->uncore.fw_mediacount == 0) dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_MEDIA); + if (INTEL_INFO(dev)->gen >= 9) { + if (--dev_priv->uncore.fw_blittercount == 0) + dev_priv->uncore.funcs.force_wake_put(dev_priv, + FORCEWAKE_BLITTER); + } } else { if (--dev_priv->uncore.forcewake_count == 0) dev_priv->uncore.funcs.force_wake_put(dev_priv, -- GitLab From f5ed50cbffae17fb5c2a3b14869f0ebe21b0d561 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 13 Nov 2014 17:51:52 +0000 Subject: [PATCH 4785/9457] drm/i915: Let's hope future platforms will use the same WM code as SKL Given the history, there's some chance we'll keep the same WM code for a bit (previously, we were able to reuse the same WM code from ILK to BDW, so that sounds like a fair assumption). Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0c705d9ba8be..87bff1652cb0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7067,7 +7067,7 @@ void intel_init_pm(struct drm_device *dev) i915_ironlake_get_mem_freq(dev); /* For FIFO watermark updates */ - if (IS_GEN9(dev)) { + if (INTEL_INFO(dev)->gen >= 9) { skl_setup_wm_latency(dev); dev_priv->display.init_clock_gating = gen9_init_clock_gating; -- GitLab From 0605815e7ec21e048febcebb691d7f0cc3bdc36c Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Fri, 14 Nov 2014 15:51:34 +0800 Subject: [PATCH 4786/9457] ASoC: rt5670 : Add ACPI match ID for Intel CHT/BSW platforms This patch adds the ACPI match ID for rt5670/5672 codec. So on Intel CherryTrail/Braswell platforms, the codec can be enumerated from ACPI and depends on ACPI to get platform-specific info and power saving. Signed-off-by: Mengdong Lin Reviewed-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 066b58317c24..b0aabd497ae9 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -2503,6 +2504,14 @@ static const struct i2c_device_id rt5670_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); +#ifdef CONFIG_ACPI +static struct acpi_device_id rt5670_acpi_match[] = { + { "10EC5670", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); +#endif + static int rt5670_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2691,6 +2700,7 @@ static struct i2c_driver rt5670_i2c_driver = { .driver = { .name = "rt5670", .owner = THIS_MODULE, + .acpi_match_table = ACPI_PTR(rt5670_acpi_match), }, .probe = rt5670_i2c_probe, .remove = rt5670_i2c_remove, -- GitLab From 471f208af987a3741757c169c4e2ad984359000b Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 14 Nov 2014 14:25:37 +0800 Subject: [PATCH 4787/9457] ASoC: rt5645: two jacks for hp and mic Some OS need headphone and microphone to be separated. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 17 ++++++++--------- sound/soc/codecs/rt5645.h | 5 +++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 57afa12b2f54..ef88b506a017 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2201,8 +2201,7 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int rt5645_jack_detect(struct snd_soc_codec *codec, - struct snd_soc_jack *jack) +static int rt5645_jack_detect(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); int gpio_state, jack_type = 0; @@ -2245,19 +2244,19 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, snd_soc_dapm_sync(&codec->dapm); } - snd_soc_jack_report(rt5645->jack, jack_type, SND_JACK_HEADSET); - + snd_soc_jack_report(rt5645->hp_jack, jack_type, SND_JACK_HEADPHONE); + snd_soc_jack_report(rt5645->mic_jack, jack_type, SND_JACK_MICROPHONE); return 0; } int rt5645_set_jack_detect(struct snd_soc_codec *codec, - struct snd_soc_jack *jack) + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); - rt5645->jack = jack; - - rt5645_jack_detect(codec, rt5645->jack); + rt5645->hp_jack = hp_jack; + rt5645->mic_jack = mic_jack; + rt5645_jack_detect(codec); return 0; } @@ -2268,7 +2267,7 @@ static void rt5645_jack_detect_work(struct work_struct *work) struct rt5645_priv *rt5645 = container_of(work, struct rt5645_priv, jack_detect_work.work); - rt5645_jack_detect(rt5645->codec, rt5645->jack); + rt5645_jack_detect(rt5645->codec); } static irqreturn_t rt5645_irq(int irq, void *data) diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 196daf03fe28..c72220abdbc0 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -2173,7 +2173,8 @@ struct rt5645_priv { struct rt5645_platform_data pdata; struct regmap *regmap; struct i2c_client *i2c; - struct snd_soc_jack *jack; + struct snd_soc_jack *hp_jack; + struct snd_soc_jack *mic_jack; struct delayed_work jack_detect_work; int sysclk; @@ -2188,6 +2189,6 @@ struct rt5645_priv { }; int rt5645_set_jack_detect(struct snd_soc_codec *codec, - struct snd_soc_jack *jack); + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack); #endif /* __RT5645_H__ */ -- GitLab From 2880fc877971d6c14b0c76ac09744e3ff5b126d5 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Thu, 13 Nov 2014 11:18:29 -0800 Subject: [PATCH 4788/9457] ASoC: add TI ts3a227e headset chip driver The TS3A227E is an autonomous audio accessory detection and configuration switch that detects 3-pole or 4-pole audio accessories and configures internal switches to route the signals accordingly. This chip also has built-in support for the new button standard described in the Android "Wired audio headset specification" v1.0. These buttons will be reported on the jack as buttons 0-3 mapped to KEY_MEDIA, KEY_VOLUMEUP, KEY_VOLUMEDOWN, and KEY_VOICE_COMMAND. This will be added as an aux_dev and have the jack passed in from the machine driver. Signed-off-by: Dylan Reid Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/ts3a227e.txt | 26 ++ sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/ts3a227e.c | 314 ++++++++++++++++++ sound/soc/codecs/ts3a227e.h | 17 + 5 files changed, 364 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ts3a227e.txt create mode 100644 sound/soc/codecs/ts3a227e.c create mode 100644 sound/soc/codecs/ts3a227e.h diff --git a/Documentation/devicetree/bindings/sound/ts3a227e.txt b/Documentation/devicetree/bindings/sound/ts3a227e.txt new file mode 100644 index 000000000000..e8bf23eb1803 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ts3a227e.txt @@ -0,0 +1,26 @@ +Texas Instruments TS3A227E +Autonomous Audio Accessory Detection and Configuration Switch + +The TS3A227E detect headsets of 3-ring and 4-ring standards and +switches automatically to route the microphone correctly. It also +handles key press detection in accordance with the Android audio +headset specification v1.0. + +Required properties: + + - compatible: Should contain "ti,ts3a227e". + - reg: The i2c address. Should contain <0x3b>. + - interrupt-parent: The parent interrupt controller + - interrupts: Interrupt number for /INT pin from the 227e + + +Examples: + + i2c { + ts3a227e@3b { + compatible = "ti,ts3a227e"; + reg = <0x3b>; + interrupt-parent = <&gpio>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + }; + }; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..243ec862c426 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TLV320AIC3X if I2C select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C + select SND_SOC_TS3A227E if I2C select SND_SOC_TWL4030 if TWL4030_CORE select SND_SOC_TWL6040 if TWL6040_CORE select SND_SOC_UDA134X @@ -607,6 +608,10 @@ config SND_SOC_TLV320AIC3X config SND_SOC_TLV320DAC33 tristate +config SND_SOC_TS3A227E + tristate "TI Headset/Mic detect and keypress chip" + depends on I2C + config SND_SOC_TWL4030 select MFD_TWL4030_AUDIO tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 5dce451661e4..a1eb7ef3b90e 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -109,6 +109,7 @@ snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o snd-soc-tlv320dac33-objs := tlv320dac33.o +snd-soc-ts3a227e-objs := ts3a227e.o snd-soc-twl4030-objs := twl4030.o snd-soc-twl6040-objs := twl6040.o snd-soc-uda134x-objs := uda134x.o @@ -282,6 +283,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o +obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c new file mode 100644 index 000000000000..1d1205702d23 --- /dev/null +++ b/sound/soc/codecs/ts3a227e.c @@ -0,0 +1,314 @@ +/* + * TS3A227E Autonomous Audio Accessory Detection and Configuration Switch + * + * Copyright (C) 2014 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct ts3a227e { + struct regmap *regmap; + struct snd_soc_jack *jack; + bool plugged; + bool mic_present; + unsigned int buttons_held; +}; + +/* Button values to be reported on the jack */ +static const int ts3a227e_buttons[] = { + SND_JACK_BTN_0, + SND_JACK_BTN_1, + SND_JACK_BTN_2, + SND_JACK_BTN_3, +}; + +#define TS3A227E_NUM_BUTTONS 4 +#define TS3A227E_JACK_MASK (SND_JACK_HEADPHONE | \ + SND_JACK_MICROPHONE | \ + SND_JACK_BTN_0 | \ + SND_JACK_BTN_1 | \ + SND_JACK_BTN_2 | \ + SND_JACK_BTN_3) + +/* TS3A227E registers */ +#define TS3A227E_REG_DEVICE_ID 0x00 +#define TS3A227E_REG_INTERRUPT 0x01 +#define TS3A227E_REG_KP_INTERRUPT 0x02 +#define TS3A227E_REG_INTERRUPT_DISABLE 0x03 +#define TS3A227E_REG_SETTING_1 0x04 +#define TS3A227E_REG_SETTING_2 0x05 +#define TS3A227E_REG_SETTING_3 0x06 +#define TS3A227E_REG_SWITCH_CONTROL_1 0x07 +#define TS3A227E_REG_SWITCH_CONTROL_2 0x08 +#define TS3A227E_REG_SWITCH_STATUS_1 0x09 +#define TS3A227E_REG_SWITCH_STATUS_2 0x0a +#define TS3A227E_REG_ACCESSORY_STATUS 0x0b +#define TS3A227E_REG_ADC_OUTPUT 0x0c +#define TS3A227E_REG_KP_THRESHOLD_1 0x0d +#define TS3A227E_REG_KP_THRESHOLD_2 0x0e +#define TS3A227E_REG_KP_THRESHOLD_3 0x0f + +/* TS3A227E_REG_INTERRUPT 0x01 */ +#define INS_REM_EVENT 0x01 +#define DETECTION_COMPLETE_EVENT 0x02 + +/* TS3A227E_REG_KP_INTERRUPT 0x02 */ +#define PRESS_MASK(idx) (0x01 << (2 * (idx))) +#define RELEASE_MASK(idx) (0x02 << (2 * (idx))) + +/* TS3A227E_REG_INTERRUPT_DISABLE 0x03 */ +#define INS_REM_INT_DISABLE 0x01 +#define DETECTION_COMPLETE_INT_DISABLE 0x02 +#define ADC_COMPLETE_INT_DISABLE 0x04 +#define INTB_DISABLE 0x08 + +/* TS3A227E_REG_SETTING_2 0x05 */ +#define KP_ENABLE 0x04 + +/* TS3A227E_REG_ACCESSORY_STATUS 0x0b */ +#define TYPE_3_POLE 0x01 +#define TYPE_4_POLE_OMTP 0x02 +#define TYPE_4_POLE_STANDARD 0x04 +#define JACK_INSERTED 0x08 +#define EITHER_MIC_MASK (TYPE_4_POLE_OMTP | TYPE_4_POLE_STANDARD) + +static const struct reg_default ts3a227e_reg_defaults[] = { + { TS3A227E_REG_DEVICE_ID, 0x10 }, + { TS3A227E_REG_INTERRUPT, 0x00 }, + { TS3A227E_REG_KP_INTERRUPT, 0x00 }, + { TS3A227E_REG_INTERRUPT_DISABLE, 0x08 }, + { TS3A227E_REG_SETTING_1, 0x23 }, + { TS3A227E_REG_SETTING_2, 0x00 }, + { TS3A227E_REG_SETTING_3, 0x0e }, + { TS3A227E_REG_SWITCH_CONTROL_1, 0x00 }, + { TS3A227E_REG_SWITCH_CONTROL_2, 0x00 }, + { TS3A227E_REG_SWITCH_STATUS_1, 0x0c }, + { TS3A227E_REG_SWITCH_STATUS_2, 0x00 }, + { TS3A227E_REG_ACCESSORY_STATUS, 0x00 }, + { TS3A227E_REG_ADC_OUTPUT, 0x00 }, + { TS3A227E_REG_KP_THRESHOLD_1, 0x20 }, + { TS3A227E_REG_KP_THRESHOLD_2, 0x40 }, + { TS3A227E_REG_KP_THRESHOLD_3, 0x68 }, +}; + +static bool ts3a227e_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TS3A227E_REG_DEVICE_ID ... TS3A227E_REG_KP_THRESHOLD_3: + return true; + default: + return false; + } +} + +static bool ts3a227e_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TS3A227E_REG_INTERRUPT_DISABLE ... TS3A227E_REG_SWITCH_CONTROL_2: + case TS3A227E_REG_KP_THRESHOLD_1 ... TS3A227E_REG_KP_THRESHOLD_3: + return true; + default: + return false; + } +} + +static bool ts3a227e_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TS3A227E_REG_INTERRUPT ... TS3A227E_REG_INTERRUPT_DISABLE: + case TS3A227E_REG_SETTING_2: + case TS3A227E_REG_SWITCH_STATUS_1 ... TS3A227E_REG_ADC_OUTPUT: + return true; + default: + return false; + } +} + +static void ts3a227e_jack_report(struct ts3a227e *ts3a227e) +{ + unsigned int i; + int report = 0; + + if (!ts3a227e->jack) + return; + + if (ts3a227e->plugged) + report = SND_JACK_HEADPHONE; + if (ts3a227e->mic_present) + report |= SND_JACK_MICROPHONE; + for (i = 0; i < TS3A227E_NUM_BUTTONS; i++) { + if (ts3a227e->buttons_held & (1 << i)) + report |= ts3a227e_buttons[i]; + } + snd_soc_jack_report(ts3a227e->jack, report, TS3A227E_JACK_MASK); +} + +static void ts3a227e_new_jack_state(struct ts3a227e *ts3a227e, unsigned acc_reg) +{ + bool plugged, mic_present; + + plugged = !!(acc_reg & JACK_INSERTED); + mic_present = plugged && !!(acc_reg & EITHER_MIC_MASK); + + ts3a227e->plugged = plugged; + + if (mic_present != ts3a227e->mic_present) { + ts3a227e->mic_present = mic_present; + ts3a227e->buttons_held = 0; + if (mic_present) { + /* Enable key press detection. */ + regmap_update_bits(ts3a227e->regmap, + TS3A227E_REG_SETTING_2, + KP_ENABLE, KP_ENABLE); + } + } +} + +static irqreturn_t ts3a227e_interrupt(int irq, void *data) +{ + struct ts3a227e *ts3a227e = (struct ts3a227e *)data; + struct regmap *regmap = ts3a227e->regmap; + unsigned int int_reg, kp_int_reg, acc_reg, i; + + /* Check for plug/unplug. */ + regmap_read(regmap, TS3A227E_REG_INTERRUPT, &int_reg); + if (int_reg & (DETECTION_COMPLETE_EVENT | INS_REM_EVENT)) { + regmap_read(regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg); + ts3a227e_new_jack_state(ts3a227e, acc_reg); + } + + /* Report any key events. */ + regmap_read(regmap, TS3A227E_REG_KP_INTERRUPT, &kp_int_reg); + for (i = 0; i < TS3A227E_NUM_BUTTONS; i++) { + if (kp_int_reg & PRESS_MASK(i)) + ts3a227e->buttons_held |= (1 << i); + if (kp_int_reg & RELEASE_MASK(i)) + ts3a227e->buttons_held &= ~(1 << i); + } + + ts3a227e_jack_report(ts3a227e); + + return IRQ_HANDLED; +} + +/** + * ts3a227e_enable_jack_detect - Specify a jack for event reporting + * + * @component: component to register the jack with + * @jack: jack to use to report headset and button events on + * + * After this function has been called the headset insert/remove and button + * events 0-3 will be routed to the given jack. Jack can be null to stop + * reporting. + */ +int ts3a227e_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack) +{ + struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); + + ts3a227e->jack = jack; + ts3a227e_jack_report(ts3a227e); + + return 0; +} +EXPORT_SYMBOL_GPL(ts3a227e_enable_jack_detect); + +static struct snd_soc_component_driver ts3a227e_soc_driver; + +static const struct regmap_config ts3a227e_regmap_config = { + .val_bits = 8, + .reg_bits = 8, + + .max_register = TS3A227E_REG_KP_THRESHOLD_3, + .readable_reg = ts3a227e_readable_reg, + .writeable_reg = ts3a227e_writeable_reg, + .volatile_reg = ts3a227e_volatile_reg, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = ts3a227e_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ts3a227e_reg_defaults), +}; + +static int ts3a227e_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct ts3a227e *ts3a227e; + struct device *dev = &i2c->dev; + int ret; + + ts3a227e = devm_kzalloc(&i2c->dev, sizeof(*ts3a227e), GFP_KERNEL); + if (ts3a227e == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, ts3a227e); + + ts3a227e->regmap = devm_regmap_init_i2c(i2c, &ts3a227e_regmap_config); + if (IS_ERR(ts3a227e->regmap)) + return PTR_ERR(ts3a227e->regmap); + + ret = devm_request_threaded_irq(dev, i2c->irq, NULL, ts3a227e_interrupt, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "TS3A227E", ts3a227e); + if (ret) { + dev_err(dev, "Cannot request irq %d (%d)\n", i2c->irq, ret); + return ret; + } + + ret = devm_snd_soc_register_component(&i2c->dev, &ts3a227e_soc_driver, + NULL, 0); + if (ret) + return ret; + + /* Enable interrupts except for ADC complete. */ + regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_INTERRUPT_DISABLE, + INTB_DISABLE | ADC_COMPLETE_INT_DISABLE, + ADC_COMPLETE_INT_DISABLE); + + return 0; +} + +static const struct i2c_device_id ts3a227e_i2c_ids[] = { + { "ts3a227e", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ts3a227e_i2c_ids); + +static const struct of_device_id ts3a227e_of_match[] = { + { .compatible = "ti,ts3a227e", }, + { } +}; +MODULE_DEVICE_TABLE(of, ts3a227e_of_match); + +static struct i2c_driver ts3a227e_driver = { + .driver = { + .name = "ts3a227e", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ts3a227e_of_match), + }, + .probe = ts3a227e_i2c_probe, + .id_table = ts3a227e_i2c_ids, +}; +module_i2c_driver(ts3a227e_driver); + +MODULE_DESCRIPTION("ASoC ts3a227e driver"); +MODULE_AUTHOR("Dylan Reid "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/ts3a227e.h b/sound/soc/codecs/ts3a227e.h new file mode 100644 index 000000000000..e2acf9c5bebe --- /dev/null +++ b/sound/soc/codecs/ts3a227e.h @@ -0,0 +1,17 @@ +/* + * TS3A227E Autonous Audio Accessory Detection and Configureation Switch + * + * Copyright (C) 2014 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _TS3A227E_H +#define _TS3A227E_H + +int ts3a227e_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack); + +#endif -- GitLab From 336cfbb05edf7b122ea927dad6c746608723eb25 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 11 Nov 2014 16:36:28 +0530 Subject: [PATCH 4789/9457] ASoC: Intel: mrfld- add ACPI module Add the last ACPI module support which also uses core module like the PCI part Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 5 + sound/soc/intel/sst/Makefile | 4 +- sound/soc/intel/sst/sst.c | 22 +- sound/soc/intel/sst/sst.h | 1 + sound/soc/intel/sst/sst_acpi.c | 362 +++++++++++++++++++++++++++++++++ sound/soc/intel/sst/sst_pvt.c | 2 + 6 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 sound/soc/intel/sst/sst_acpi.c diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index c963a5d34111..a992e8572d89 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -20,6 +20,11 @@ config SND_SST_IPC_PCI tristate select SND_SST_IPC +config SND_SST_IPC_ACPI + tristate + select SND_SST_IPC + depends on ACPI + config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/sst/Makefile index b8aa1d35df74..fd21726361b5 100644 --- a/sound/soc/intel/sst/Makefile +++ b/sound/soc/intel/sst/Makefile @@ -1,7 +1,7 @@ snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o snd-intel-sst-pci-objs += sst_pci.o - +snd-intel-sst-acpi-objs += sst_acpi.o obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst-core.o obj-$(CONFIG_SND_SST_IPC_PCI) += snd-intel-sst-pci.o - +obj-$(CONFIG_SND_SST_IPC_ACPI) += snd-intel-sst-acpi.o diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index b97c231a4f39..b2b5604943b5 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +182,7 @@ int sst_driver_ops(struct intel_sst_drv *sst) switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: sst->tstamp = SST_TIME_STAMP_MRFLD; sst->ops = &mrfld_ops; return 0; @@ -323,7 +325,7 @@ EXPORT_SYMBOL_GPL(sst_context_init); void sst_context_cleanup(struct intel_sst_drv *ctx) { pm_runtime_get_noresume(ctx->dev); - pm_runtime_forbid(ctx->dev); + pm_runtime_disable(ctx->dev); sst_unregister(ctx->dev); sst_set_fw_state_locked(ctx, SST_SHUTDOWN); flush_scheduled_work(); @@ -371,8 +373,19 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) { pm_runtime_set_autosuspend_delay(ctx->dev, SST_SUSPEND_DELAY); pm_runtime_use_autosuspend(ctx->dev); - pm_runtime_allow(ctx->dev); - pm_runtime_put_noidle(ctx->dev); + /* + * For acpi devices, the actual physical device state is + * initially active. So change the state to active before + * enabling the pm + */ + if (acpi_disabled) { + pm_runtime_set_active(ctx->dev); + pm_runtime_enable(ctx->dev); + } else { + pm_runtime_allow(ctx->dev); + pm_runtime_put_noidle(ctx->dev); + } + sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); } EXPORT_SYMBOL_GPL(sst_configure_runtime_pm); @@ -395,6 +408,9 @@ static int intel_sst_runtime_suspend(struct device *dev) synchronize_irq(ctx->irq_num); flush_workqueue(ctx->post_msg_wq); + /* save the shim registers because PMC doesn't save state */ + sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); + return ret; } diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index 2dcbf479df28..683dc717e4e8 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h @@ -29,6 +29,7 @@ /* driver names */ #define SST_DRV_NAME "intel_sst_driver" #define SST_MRFLD_PCI_ID 0x119A +#define SST_BYT_ACPI_ID 0x80860F28 #define SST_SUSPEND_DELAY 2000 #define FW_CONTEXT_MEM (64*1024) diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c new file mode 100644 index 000000000000..2b1c5d907014 --- /dev/null +++ b/sound/soc/intel/sst/sst_acpi.c @@ -0,0 +1,362 @@ +/* + * sst_acpi.c - SST (LPE) driver init file for ACPI enumeration. + * + * Copyright (c) 2013, Intel Corporation. + * + * Authors: Ramesh Babu K V + * Authors: Omair Mohammed Abdullah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sst-mfld-platform.h" +#include "../sst-dsp.h" +#include "sst.h" + +struct sst_machines { + char codec_id[32]; + char board[32]; + char machine[32]; + void (*machine_quirk)(void); + char firmware[32]; + struct sst_platform_info *pdata; + +}; + +/* LPE viewpoint addresses */ +#define SST_BYT_IRAM_PHY_START 0xff2c0000 +#define SST_BYT_IRAM_PHY_END 0xff2d4000 +#define SST_BYT_DRAM_PHY_START 0xff300000 +#define SST_BYT_DRAM_PHY_END 0xff320000 +#define SST_BYT_IMR_VIRT_START 0xc0000000 /* virtual addr in LPE */ +#define SST_BYT_IMR_VIRT_END 0xc01fffff +#define SST_BYT_SHIM_PHY_ADDR 0xff340000 +#define SST_BYT_MBOX_PHY_ADDR 0xff344000 +#define SST_BYT_DMA0_PHY_ADDR 0xff298000 +#define SST_BYT_DMA1_PHY_ADDR 0xff29c000 +#define SST_BYT_SSP0_PHY_ADDR 0xff2a0000 +#define SST_BYT_SSP2_PHY_ADDR 0xff2a2000 + +#define BYT_FW_MOD_TABLE_OFFSET 0x80000 +#define BYT_FW_MOD_TABLE_SIZE 0x100 +#define BYT_FW_MOD_OFFSET (BYT_FW_MOD_TABLE_OFFSET + BYT_FW_MOD_TABLE_SIZE) + +static const struct sst_info byt_fwparse_info = { + .use_elf = false, + .max_streams = 25, + .iram_start = SST_BYT_IRAM_PHY_START, + .iram_end = SST_BYT_IRAM_PHY_END, + .iram_use = true, + .dram_start = SST_BYT_DRAM_PHY_START, + .dram_end = SST_BYT_DRAM_PHY_END, + .dram_use = true, + .imr_start = SST_BYT_IMR_VIRT_START, + .imr_end = SST_BYT_IMR_VIRT_END, + .imr_use = true, + .mailbox_start = SST_BYT_MBOX_PHY_ADDR, + .num_probes = 0, + .lpe_viewpt_rqd = true, +}; + +static const struct sst_ipc_info byt_ipc_info = { + .ipc_offset = 0, + .mbox_recv_off = 0x400, +}; + +static const struct sst_lib_dnld_info byt_lib_dnld_info = { + .mod_base = SST_BYT_IMR_VIRT_START, + .mod_end = SST_BYT_IMR_VIRT_END, + .mod_table_offset = BYT_FW_MOD_TABLE_OFFSET, + .mod_table_size = BYT_FW_MOD_TABLE_SIZE, + .mod_ddr_dnld = false, +}; + +static const struct sst_res_info byt_rvp_res_info = { + .shim_offset = 0x140000, + .shim_size = 0x000100, + .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, + .ssp0_offset = 0xa0000, + .ssp0_size = 0x1000, + .dma0_offset = 0x98000, + .dma0_size = 0x4000, + .dma1_offset = 0x9c000, + .dma1_size = 0x4000, + .iram_offset = 0x0c0000, + .iram_size = 0x14000, + .dram_offset = 0x100000, + .dram_size = 0x28000, + .mbox_offset = 0x144000, + .mbox_size = 0x1000, + .acpi_lpe_res_index = 0, + .acpi_ddr_index = 2, + .acpi_ipc_irq_index = 5, +}; + +struct sst_platform_info byt_rvp_platform_data = { + .probe_data = &byt_fwparse_info, + .ipc_info = &byt_ipc_info, + .lib_info = &byt_lib_dnld_info, + .res_info = &byt_rvp_res_info, + .platform = "sst-mfld-platform", +}; + +static int sst_platform_get_resources(struct intel_sst_drv *ctx) +{ + struct resource *rsrc; + struct platform_device *pdev = to_platform_device(ctx->dev); + + /* All ACPI resource request here */ + /* Get Shim addr */ + rsrc = platform_get_resource(pdev, IORESOURCE_MEM, + ctx->pdata->res_info->acpi_lpe_res_index); + if (!rsrc) { + dev_err(ctx->dev, "Invalid SHIM base from IFWI"); + return -EIO; + } + dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, + (unsigned int)resource_size(rsrc)); + + ctx->iram_base = rsrc->start + ctx->pdata->res_info->iram_offset; + ctx->iram_end = ctx->iram_base + ctx->pdata->res_info->iram_size - 1; + dev_info(ctx->dev, "IRAM base: %#x", ctx->iram_base); + ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, + ctx->pdata->res_info->iram_size); + if (!ctx->iram) { + dev_err(ctx->dev, "unable to map IRAM"); + return -EIO; + } + + ctx->dram_base = rsrc->start + ctx->pdata->res_info->dram_offset; + ctx->dram_end = ctx->dram_base + ctx->pdata->res_info->dram_size - 1; + dev_info(ctx->dev, "DRAM base: %#x", ctx->dram_base); + ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, + ctx->pdata->res_info->dram_size); + if (!ctx->dram) { + dev_err(ctx->dev, "unable to map DRAM"); + return -EIO; + } + + ctx->shim_phy_add = rsrc->start + ctx->pdata->res_info->shim_offset; + dev_info(ctx->dev, "SHIM base: %#x", ctx->shim_phy_add); + ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, + ctx->pdata->res_info->shim_size); + if (!ctx->shim) { + dev_err(ctx->dev, "unable to map SHIM"); + return -EIO; + } + + /* reassign physical address to LPE viewpoint address */ + ctx->shim_phy_add = ctx->pdata->res_info->shim_phy_addr; + + /* Get mailbox addr */ + ctx->mailbox_add = rsrc->start + ctx->pdata->res_info->mbox_offset; + dev_info(ctx->dev, "Mailbox base: %#x", ctx->mailbox_add); + ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, + ctx->pdata->res_info->mbox_size); + if (!ctx->mailbox) { + dev_err(ctx->dev, "unable to map mailbox"); + return -EIO; + } + + /* reassign physical address to LPE viewpoint address */ + ctx->mailbox_add = ctx->info.mailbox_start; + + rsrc = platform_get_resource(pdev, IORESOURCE_MEM, + ctx->pdata->res_info->acpi_ddr_index); + if (!rsrc) { + dev_err(ctx->dev, "Invalid DDR base from IFWI"); + return -EIO; + } + ctx->ddr_base = rsrc->start; + ctx->ddr_end = rsrc->end; + dev_info(ctx->dev, "DDR base: %#x", ctx->ddr_base); + ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, + resource_size(rsrc)); + if (!ctx->ddr) { + dev_err(ctx->dev, "unable to map DDR"); + return -EIO; + } + + /* Find the IRQ */ + ctx->irq_num = platform_get_irq(pdev, + ctx->pdata->res_info->acpi_ipc_irq_index); + return 0; +} + +static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level, + void *context, void **ret) +{ + *(bool *)context = true; + return AE_OK; +} + +static struct sst_machines *sst_acpi_find_machine( + struct sst_machines *machines) +{ + struct sst_machines *mach; + bool found = false; + + for (mach = machines; mach->codec_id; mach++) + if (ACPI_SUCCESS(acpi_get_devices(mach->codec_id, + sst_acpi_mach_match, + &found, NULL)) && found) + return mach; + + return NULL; +} + +int sst_acpi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret = 0; + struct intel_sst_drv *ctx; + const struct acpi_device_id *id; + struct sst_machines *mach; + struct platform_device *mdev; + struct platform_device *plat_dev; + unsigned int dev_id; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return -ENODEV; + dev_dbg(dev, "for %s", id->id); + + mach = (struct sst_machines *)id->driver_data; + mach = sst_acpi_find_machine(mach); + if (mach == NULL) { + dev_err(dev, "No matching machine driver found\n"); + return -ENODEV; + } + + ret = kstrtouint(id->id, 16, &dev_id); + if (ret < 0) { + dev_err(dev, "Unique device id conversion error: %d\n", ret); + return ret; + } + + dev_dbg(dev, "ACPI device id: %x\n", dev_id); + + plat_dev = platform_device_register_data(dev, mach->pdata->platform, -1, NULL, 0); + if (plat_dev == NULL) { + dev_err(dev, "Failed to create machine device: %s\n", mach->pdata->platform); + return -ENODEV; + } + + /* Create platform device for sst machine driver */ + mdev = platform_device_register_data(dev, mach->machine, -1, NULL, 0); + if (mdev == NULL) { + dev_err(dev, "Failed to create machine device: %s\n", mach->machine); + return -ENODEV; + } + + ret = sst_alloc_drv_context(&ctx, dev, dev_id); + if (ret < 0) + return ret; + + /* Fill sst platform data */ + ctx->pdata = mach->pdata; + strcpy(ctx->firmware_name, mach->firmware); + + ret = sst_platform_get_resources(ctx); + if (ret) + return ret; + + ret = sst_context_init(ctx); + if (ret < 0) + return ret; + + /* need to save shim registers in BYT */ + ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64), + GFP_KERNEL); + if (!ctx->shim_regs64) { + return -ENOMEM; + goto do_sst_cleanup; + } + + sst_configure_runtime_pm(ctx); + platform_set_drvdata(pdev, ctx); + return ret; + +do_sst_cleanup: + sst_context_cleanup(ctx); + platform_set_drvdata(pdev, NULL); + dev_err(ctx->dev, "failed with %d\n", ret); + return ret; +} + +/** +* intel_sst_remove - remove function +* +* @pdev: platform device structure +* +* This function is called by OS when a device is unloaded +* This frees the interrupt etc +*/ +int sst_acpi_remove(struct platform_device *pdev) +{ + struct intel_sst_drv *ctx; + + ctx = platform_get_drvdata(pdev); + sst_context_cleanup(ctx); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct sst_machines sst_acpi_bytcr[] = { + {"10EC5640", "T100", "bytt100_rt5640", NULL, "fw_sst_0f28.bin", + &byt_rvp_platform_data }, + {}, +}; + +static const struct acpi_device_id sst_acpi_ids[] = { + { "80860F28", (unsigned long)&sst_acpi_bytcr}, + { }, +}; + +static struct platform_driver sst_acpi_driver = { + .driver = { + .name = "intel_sst_acpi", + .owner = THIS_MODULE, + .acpi_match_table = ACPI_PTR(sst_acpi_ids), + .pm = &intel_sst_pm, + }, + .probe = sst_acpi_probe, + .remove = sst_acpi_remove, +}; + +module_platform_driver(sst_acpi_driver); + +MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine ACPI Driver"); +MODULE_AUTHOR("Ramesh Babu K V"); +MODULE_AUTHOR("Omair Mohammed Abdullah"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("sst"); diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/sst/sst_pvt.c index 9a5df1936516..4b7720864492 100644 --- a/sound/soc/intel/sst/sst_pvt.c +++ b/sound/soc/intel/sst/sst_pvt.c @@ -117,6 +117,7 @@ unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr) switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: val = sst_shim_read64(sst->shim, addr); break; } @@ -128,6 +129,7 @@ void write_shim_data(struct intel_sst_drv *sst, int addr, { switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: sst_shim_write64(sst->shim, addr, (u64) data); break; } -- GitLab From 044b724ada4448174f3f7510b791df0bdcb834ee Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 12 Nov 2014 19:54:30 +0800 Subject: [PATCH 4790/9457] ASoC: rt5670: make bias level more reasonable This patah separate bias level off to standby and off. The standby level will provide the necessary power for JD and push button functions. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index b0aabd497ae9..5e54ac957e47 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2310,6 +2310,8 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int rt5670_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + switch (level) { case SND_SOC_BIAS_PREPARE: if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { @@ -2331,16 +2333,27 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec, } break; case SND_SOC_BIAS_STANDBY: - snd_soc_write(codec, RT5670_PWR_DIG1, 0x0000); - snd_soc_write(codec, RT5670_PWR_DIG2, 0x0001); - snd_soc_write(codec, RT5670_PWR_VOL, 0x0000); - snd_soc_write(codec, RT5670_PWR_MIXER, 0x0001); - snd_soc_write(codec, RT5670_PWR_ANLG1, 0x2800); - snd_soc_write(codec, RT5670_PWR_ANLG2, 0x0004); - snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x0); + snd_soc_update_bits(codec, RT5670_PWR_ANLG1, + RT5670_PWR_VREF1 | RT5670_PWR_VREF2 | + RT5670_PWR_FV1 | RT5670_PWR_FV2, 0); snd_soc_update_bits(codec, RT5670_PWR_ANLG1, RT5670_LDO_SEL_MASK, 0x1); break; + case SND_SOC_BIAS_OFF: + if (rt5670->pdata.jd_mode) + snd_soc_update_bits(codec, RT5670_PWR_ANLG1, + RT5670_PWR_VREF1 | RT5670_PWR_MB | + RT5670_PWR_BG | RT5670_PWR_VREF2 | + RT5670_PWR_FV1 | RT5670_PWR_FV2, + RT5670_PWR_MB | RT5670_PWR_BG); + else + snd_soc_update_bits(codec, RT5670_PWR_ANLG1, + RT5670_PWR_VREF1 | RT5670_PWR_MB | + RT5670_PWR_BG | RT5670_PWR_VREF2 | + RT5670_PWR_FV1 | RT5670_PWR_FV2, 0); + + snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x0); + break; default: break; -- GitLab From 1177e4364154a00baf2c9eb72fd960f0c5a8de84 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 8 Nov 2014 21:42:12 +0100 Subject: [PATCH 4791/9457] trace: Replace single-character seq_puts with seq_putc Printing a single character to a seqfile might as well be done with seq_putc instead of seq_puts; this avoids a strlen() call and a memory access. It also shaves another few bytes off the generated code. Link: http://lkml.kernel.org/r/1415479332-25944-4-git-send-email-linux@rasmusvillemoes.dk Signed-off-by: Rasmus Villemoes Signed-off-by: Steven Rostedt --- kernel/trace/trace_events_trigger.c | 4 ++-- kernel/trace/trace_functions_graph.c | 4 ++-- kernel/trace/trace_kprobe.c | 8 ++++---- kernel/trace/trace_printk.c | 2 +- kernel/trace/trace_uprobe.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 3d89ffc66740..8712df9decb4 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -383,7 +383,7 @@ event_trigger_print(const char *name, struct seq_file *m, if (filter_str) seq_printf(m, " if %s\n", filter_str); else - seq_puts(m, "\n"); + seq_putc(m, '\n'); return 0; } @@ -1105,7 +1105,7 @@ event_enable_trigger_print(struct seq_file *m, struct event_trigger_ops *ops, if (data->filter_str) seq_printf(m, " if %s\n", data->filter_str); else - seq_puts(m, "\n"); + seq_putc(m, '\n'); return 0; } diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 29ba611e6f57..a82d1d3bd76d 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1407,7 +1407,7 @@ static void __print_graph_headers_flags(struct seq_file *s, u32 flags) print_lat_header(s, flags); /* 1st line */ - seq_puts(s, "#"); + seq_putc(s, '#'); if (flags & TRACE_GRAPH_PRINT_ABS_TIME) seq_puts(s, " TIME "); if (flags & TRACE_GRAPH_PRINT_CPU) @@ -1421,7 +1421,7 @@ static void __print_graph_headers_flags(struct seq_file *s, u32 flags) seq_puts(s, " FUNCTION CALLS\n"); /* 2nd line */ - seq_puts(s, "#"); + seq_putc(s, '#'); if (flags & TRACE_GRAPH_PRINT_ABS_TIME) seq_puts(s, " | "); if (flags & TRACE_GRAPH_PRINT_CPU) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 240d27ddf82e..ef7e7f16ed1a 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1030,7 +1030,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags, if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) goto partial; - if (!trace_seq_puts(s, ")")) + if (!trace_seq_putc(s, ')')) goto partial; data = (u8 *)&field[1]; @@ -1039,7 +1039,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags, data + tp->args[i].offset, field)) goto partial; - if (!trace_seq_puts(s, "\n")) + if (!trace_seq_putc(s, '\n')) goto partial; return TRACE_TYPE_HANDLED; @@ -1072,7 +1072,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET)) goto partial; - if (!trace_seq_puts(s, ")")) + if (!trace_seq_putc(s, ')')) goto partial; data = (u8 *)&field[1]; @@ -1081,7 +1081,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, data + tp->args[i].offset, field)) goto partial; - if (!trace_seq_puts(s, "\n")) + if (!trace_seq_putc(s, '\n')) goto partial; return TRACE_TYPE_HANDLED; diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 2900817ba65c..c4e70b6bd7fa 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c @@ -305,7 +305,7 @@ static int t_show(struct seq_file *m, void *v) seq_puts(m, "\\t"); break; case '\\': - seq_puts(m, "\\"); + seq_putc(m, '\\'); break; case '"': seq_puts(m, "\\\""); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index d22117beedd0..e35327c787f7 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -872,7 +872,7 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e goto partial; } - if (trace_seq_puts(s, "\n")) + if (trace_seq_putc(s, '\n')) return TRACE_TYPE_HANDLED; partial: -- GitLab From 678f845ed0f40c29a74cd8dd60c48f2a6db44dc9 Mon Sep 17 00:00:00 2001 From: Daniel Bristot de Oliveira Date: Thu, 6 Nov 2014 15:25:09 -0200 Subject: [PATCH 4792/9457] ftrace-graph: show latency-format on print_graph_irq() On the function_graph tracer, the print_graph_irq() function prints a trace line with the flag ==========> on an irq handler entry, and the flag <========== on an irq handler return. But when the latency-format is enable, it is not printing the latency-format flags, causing the following error in the trace output: 0) ==========> | 0) d... | smp_apic_timer_interrupt() { This patch fixes this issue by printing the latency-format flags when it is enable. Link: http://lkml.kernel.org/r/7c2e226dac20c940b6242178fab7f0e3c9b5ce58.1415233316.git.bristot@redhat.com Reviewed-by: Luis Claudio R. Goncalves Signed-off-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt --- kernel/trace/trace_functions_graph.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index a82d1d3bd76d..93ebba09622e 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -699,6 +699,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr, { int ret; struct trace_seq *s = &iter->seq; + struct trace_entry *ent = iter->ent; if (addr < (unsigned long)__irqentry_text_start || addr >= (unsigned long)__irqentry_text_end) @@ -728,6 +729,14 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr, if (!ret) return TRACE_TYPE_PARTIAL_LINE; } + + /* Latency format */ + if (trace_flags & TRACE_ITER_LATENCY_FMT) { + ret = print_graph_lat_fmt(s, ent); + if (ret == TRACE_TYPE_PARTIAL_LINE) + return TRACE_TYPE_PARTIAL_LINE; + } + } /* No overhead */ -- GitLab From 4526d0676a150dce7a93ad93e03bef7f77e7c906 Mon Sep 17 00:00:00 2001 From: Byungchul Park Date: Wed, 5 Nov 2014 16:18:44 +0900 Subject: [PATCH 4793/9457] function_graph: Fix micro seconds notations Usually, "msecs" notation means milli-seconds, and "usecs" notation means micro-seconds. Since the unit used in the code is micro-seconds, the notation should be replaced from msecs to usecs. Link: http://lkml.kernel.org/r/1415171926-9782-2-git-send-email-byungchul.park@lge.com Signed-off-by: Byungchul Park Signed-off-by: Steven Rostedt --- kernel/trace/trace_functions_graph.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 93ebba09622e..55bdf9d7f714 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -768,19 +768,19 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s) { unsigned long nsecs_rem = do_div(duration, 1000); /* log10(ULONG_MAX) + '\0' */ - char msecs_str[21]; + char usecs_str[21]; char nsecs_str[5]; int ret, len; int i; - sprintf(msecs_str, "%lu", (unsigned long) duration); + sprintf(usecs_str, "%lu", (unsigned long) duration); /* Print msecs */ - ret = trace_seq_printf(s, "%s", msecs_str); + ret = trace_seq_printf(s, "%s", usecs_str); if (!ret) return TRACE_TYPE_PARTIAL_LINE; - len = strlen(msecs_str); + len = strlen(usecs_str); /* Print nsecs (we don't want to exceed 7 numbers) */ if (len < 7) { @@ -831,10 +831,10 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s, /* Signal a overhead of time execution to the output */ if (flags & TRACE_GRAPH_PRINT_OVERHEAD) { - /* Duration exceeded 100 msecs */ + /* Duration exceeded 100 usecs */ if (duration > 100000ULL) ret = trace_seq_puts(s, "! "); - /* Duration exceeded 10 msecs */ + /* Duration exceeded 10 usecs */ else if (duration > 10000ULL) ret = trace_seq_puts(s, "+ "); } -- GitLab From 387417b56295ef93d7cb38e1721826c85dfe897c Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 14 Nov 2014 16:09:05 +0530 Subject: [PATCH 4794/9457] ALSA: ice1712: remove unneeded return statement the functions: snd_ice1712_akm4xxx_build_controls snd_ice1712_build_pro_mixer snd_ctl_add snd_ak4114_build prodigy192_ak4114_init snd_ak4113_build are all returning either 0 or a negetive error value. so we can easily remove the check for a negative value and return the value instead. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/ice1712/hoontech.c | 6 +----- sound/pci/ice1712/ice1712.c | 19 ++++++------------- sound/pci/ice1712/ice1724.c | 7 ++----- sound/pci/ice1712/juli.c | 5 +---- sound/pci/ice1712/prodigy192.c | 4 +--- sound/pci/ice1712/quartet.c | 5 +---- 6 files changed, 12 insertions(+), 34 deletions(-) diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 59e37c581691..a40001c1d9e8 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -309,11 +309,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice) return err; /* ak4524 controls */ - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - - return 0; + return snd_ice1712_akm4xxx_build_controls(ice); } static int snd_ice1712_ez8_init(struct snd_ice1712 *ice) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 48a0c330da24..597533490f2d 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -1295,10 +1295,7 @@ static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd return err; } - err = snd_ice1712_build_pro_mixer(ice); - if (err < 0) - return err; - return 0; + return snd_ice1712_build_pro_mixer(ice); } /* @@ -1545,10 +1542,9 @@ static int snd_ice1712_ac97_mixer(struct snd_ice1712 *ice) dev_warn(ice->card->dev, "cannot initialize ac97 for consumer, skipped\n"); else { - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice)); - if (err < 0) - return err; - return 0; + return snd_ctl_add(ice->card, + snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, + ice)); } } @@ -2497,11 +2493,8 @@ static int snd_ice1712_build_controls(struct snd_ice1712 *ice) err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice)); if (err < 0) return err; - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); - if (err < 0) - return err; - - return 0; + return snd_ctl_add(ice->card, + snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice)); } static int snd_ice1712_free(struct snd_ice1712 *ice) diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index f633e3bb4c43..ea53167081b8 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2497,11 +2497,8 @@ static int snd_vt1724_build_controls(struct snd_ice1712 *ice) return err; } - err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice)); - if (err < 0) - return err; - - return 0; + return snd_ctl_add(ice->card, + snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice)); } static int snd_vt1724_free(struct snd_ice1712 *ice) diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 7a6c0786c55c..a1536c1a7ed4 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -475,11 +475,8 @@ static int juli_add_controls(struct snd_ice1712 *ice) return err; /* only capture SPDIF over AK4114 */ - err = snd_ak4114_build(spec->ak4114, NULL, + return snd_ak4114_build(spec->ak4114, NULL, ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); - if (err < 0) - return err; - return 0; } /* diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 1eb151aaa965..3919aed39ca0 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -758,10 +758,8 @@ static int prodigy192_init(struct snd_ice1712 *ice) "AK4114 initialized with status %d\n", err); } else dev_dbg(ice->card->dev, "AK4114 not found\n"); - if (err < 0) - return err; - return 0; + return err; } diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index d4caf9d05922..6f55e02e5c84 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -833,11 +833,8 @@ static int qtet_add_controls(struct snd_ice1712 *ice) if (err < 0) return err; /* only capture SPDIF over AK4113 */ - err = snd_ak4113_build(spec->ak4113, + return snd_ak4113_build(spec->ak4113, ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); - if (err < 0) - return err; - return 0; } static inline int qtet_is_spdif_master(struct snd_ice1712 *ice) -- GitLab From b393df0145e271724fee10f93c023662f8557bb9 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 14 Nov 2014 16:09:07 +0530 Subject: [PATCH 4795/9457] ALSA: ice1712: remove unused variable buf_size was initialized with snd_pcm_lib_buffer_bytes, but never used. and so it is safe to be deleted. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/ice1712/ice1712.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 597533490f2d..65251911cf6f 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -620,10 +620,9 @@ static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream) { struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - u32 period_size, buf_size, rate, tmp, chn; + u32 period_size, rate, tmp, chn; period_size = snd_pcm_lib_period_bytes(substream) - 1; - buf_size = snd_pcm_lib_buffer_bytes(substream) - 1; tmp = 0x0064; if (snd_pcm_format_width(runtime->format) == 16) tmp &= ~0x04; -- GitLab From b8eca77e54525c818f35f51afb64fc13205443a3 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 14 Nov 2014 18:12:21 +0530 Subject: [PATCH 4796/9457] ALSA: ice1712: consider error value earlier we were ignoring the return value of snd_ak4114_create and always returning 0. now we are returning the actual status. revo_init is calling this function, and revo_init is checking the return value. Signed-off-by: Sudip Mukherjee Signed-off-by: Takashi Iwai --- sound/pci/ice1712/revo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 1112ec1953be..1d81ae677573 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -494,11 +494,13 @@ static int ap192_ak4114_init(struct snd_ice1712 *ice) ap192_ak4114_write, ak4114_init_vals, ak4114_init_txcsb, ice, &spec->ak4114); + if (err < 0) + return err; /* AK4114 in Revo cannot detect external rate correctly. * No reason to stop capture stream due to incorrect checks */ spec->ak4114->check_flags = AK4114_CHECK_NO_RATE; - return 0; /* error ignored; it's no fatal error */ + return 0; } static int revo_init(struct snd_ice1712 *ice) -- GitLab From 6f15b602b8f93e1d199a85b95183d7a5836b3152 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:46 +0100 Subject: [PATCH 4797/9457] simplefb: Add simplefb MAINTAINERS entry During the discussion about adding clock handling code to simplefb, it became clear that simplefb currently does not have an active maintainer. I've discussed this with Stephen Warren , the original author of simplefb, and with his permisson I'm picking up maintainership of simplefb. Cc: Stephen Warren Signed-off-by: Hans de Goede Acked-by: Geert Uytterhoeven Acked-by: Stephen Warren Reviewed-by: Maxime Ripard Reviewed-by: David Herrmann Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3c6427190be2..d348ccc162fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8442,6 +8442,14 @@ F: drivers/media/usb/siano/ F: drivers/media/usb/siano/ F: drivers/media/mmc/siano/ +SIMPLEFB FB DRIVER +M: Hans de Goede +L: linux-fbdev@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/video/simple-framebuffer.txt +F: drivers/video/fbdev/simplefb.c +F: include/linux/platform_data/simplefb.h + SH_VEU V4L2 MEM2MEM DRIVER L: linux-media@vger.kernel.org S: Orphan -- GitLab From 9ee4cd1aa3eec2f405652dc51779612104feebef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:47 +0100 Subject: [PATCH 4798/9457] dt-bindings: Add a clocks property to the simple-framebuffer binding A simple-framebuffer node represents a framebuffer setup by the firmware / bootloader. Such a framebuffer may have a number of clocks in use, add a property to communicate this to the OS. Signed-off-by: Hans de Goede Reviewed-by: Mike Turquette Acked-by: Geert Uytterhoeven Reviewed-by: Maxime Ripard Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- .../devicetree/bindings/video/simple-framebuffer.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt index 70c26f3a5b9a..8f35718f4f5b 100644 --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -1,8 +1,8 @@ Simple Framebuffer -A simple frame-buffer describes a raw memory region that may be rendered to, -with the assumption that the display hardware has already been set up to scan -out from that buffer. +A simple frame-buffer describes a frame-buffer setup by firmware or +the bootloader, with the assumption that the display hardware has already +been set up to scan out from the memory pointed to by the reg property. Required properties: - compatible: "simple-framebuffer" @@ -14,6 +14,12 @@ Required properties: - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r). +Optional properties: +- clocks : List of clocks used by the framebuffer. Clocks listed here + are expected to already be configured correctly. The OS must + ensure these clocks are not modified or disabled while the + simple framebuffer remains active. + Example: framebuffer { -- GitLab From 1270be4a4fb852630280638cbb169b67c485b3e3 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Fri, 14 Nov 2014 13:26:48 +0100 Subject: [PATCH 4799/9457] simplefb: formalize pseudo palette handling Add a proper struct describing simplefb private data, with the palette in there, instead of directly storing the palette in the fb_info->par pointer. Signed-off-by: Luc Verhaegen Acked-by: Stephen Warren [hdegoede@redhat.com: drop unnecessary void * cast] Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Acked-by: Geert Uytterhoeven Reviewed-by: Maxime Ripard Reviewed-by: David Herrmann Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 210f3a02121a..ec112c13eb05 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -41,6 +41,8 @@ static struct fb_var_screeninfo simplefb_var = { .vmode = FB_VMODE_NONINTERLACED, }; +#define PSEUDO_PALETTE_SIZE 16 + static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { @@ -50,7 +52,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u32 cb = blue >> (16 - info->var.blue.length); u32 value; - if (regno >= 16) + if (regno >= PSEUDO_PALETTE_SIZE) return -EINVAL; value = (cr << info->var.red.offset) | @@ -163,11 +165,16 @@ static int simplefb_parse_pd(struct platform_device *pdev, return 0; } +struct simplefb_par { + u32 palette[PSEUDO_PALETTE_SIZE]; +}; + static int simplefb_probe(struct platform_device *pdev) { int ret; struct simplefb_params params; struct fb_info *info; + struct simplefb_par *par; struct resource *mem; if (fb_get_options("simplefb", NULL)) @@ -188,11 +195,13 @@ static int simplefb_probe(struct platform_device *pdev) return -EINVAL; } - info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); + info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev); if (!info) return -ENOMEM; platform_set_drvdata(pdev, info); + par = info->par; + info->fix = simplefb_fix; info->fix.smem_start = mem->start; info->fix.smem_len = resource_size(mem); @@ -225,7 +234,7 @@ static int simplefb_probe(struct platform_device *pdev) framebuffer_release(info); return -ENODEV; } - info->pseudo_palette = (void *)(info + 1); + info->pseudo_palette = par->palette; dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", info->fix.smem_start, info->fix.smem_len, -- GitLab From bf2fda157a9ab50f65da60a365ede3a5b529d025 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Fri, 14 Nov 2014 13:26:49 +0100 Subject: [PATCH 4800/9457] simplefb: add goto error path to probe Use the usual kernel style of goto error_foo to free resources on probe error. This is a preparation patch for adding clocks support. While at it also update ioremap_wc error return from ENODEV to ENOMEM. Signed-off-by: Luc Verhaegen Acked-by: Stephen Warren Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Acked-by: Geert Uytterhoeven Reviewed-by: Maxime Ripard Reviewed-by: David Herrmann Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index ec112c13eb05..cdcf1fe46eae 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -220,8 +220,8 @@ static int simplefb_probe(struct platform_device *pdev) info->apertures = alloc_apertures(1); if (!info->apertures) { - framebuffer_release(info); - return -ENOMEM; + ret = -ENOMEM; + goto error_fb_release; } info->apertures->ranges[0].base = info->fix.smem_start; info->apertures->ranges[0].size = info->fix.smem_len; @@ -231,8 +231,8 @@ static int simplefb_probe(struct platform_device *pdev) info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len); if (!info->screen_base) { - framebuffer_release(info); - return -ENODEV; + ret = -ENOMEM; + goto error_fb_release; } info->pseudo_palette = par->palette; @@ -247,14 +247,18 @@ static int simplefb_probe(struct platform_device *pdev) ret = register_framebuffer(info); if (ret < 0) { dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); - iounmap(info->screen_base); - framebuffer_release(info); - return ret; + goto error_unmap; } dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); return 0; + +error_unmap: + iounmap(info->screen_base); +error_fb_release: + framebuffer_release(info); + return ret; } static int simplefb_remove(struct platform_device *pdev) -- GitLab From fc219bfd5b2e488e3c246990869cfde5ca235c89 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Fri, 14 Nov 2014 13:26:50 +0100 Subject: [PATCH 4801/9457] simplefb: add clock handling code This claims and enables clocks listed in the simple framebuffer dt node. This is needed so that the display engine, in case the required clocks are known by the kernel code and are described in the dt, will remain properly enabled. Signed-off-by: Luc Verhaegen [hdegoede@redhat.com: Change clks from list to dynamic array] Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Acked-by: Geert Uytterhoeven Reviewed-by: Maxime Ripard Reviewed-by: David Herrmann Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 108 ++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index cdcf1fe46eae..d19294635a42 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -26,6 +26,7 @@ #include #include #include +#include static struct fb_fix_screeninfo simplefb_fix = { .id = "simple", @@ -167,8 +168,105 @@ static int simplefb_parse_pd(struct platform_device *pdev, struct simplefb_par { u32 palette[PSEUDO_PALETTE_SIZE]; +#ifdef CONFIG_OF + int clk_count; + struct clk **clks; +#endif }; +#ifdef CONFIG_OF +/* + * Clock handling code. + * + * Here we handle the clocks property of our "simple-framebuffer" dt node. + * This is necessary so that we can make sure that any clocks needed by + * the display engine that the bootloader set up for us (and for which it + * provided a simplefb dt node), stay up, for the life of the simplefb + * driver. + * + * When the driver unloads, we cleanly disable, and then release the clocks. + * + * We only complain about errors here, no action is taken as the most likely + * error can only happen due to a mismatch between the bootloader which set + * up simplefb, and the clock definitions in the device tree. Chances are + * that there are no adverse effects, and if there are, a clean teardown of + * the fb probe will not help us much either. So just complain and carry on, + * and hope that the user actually gets a working fb at the end of things. + */ +static int simplefb_clocks_init(struct simplefb_par *par, + struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clock; + int i, ret; + + if (dev_get_platdata(&pdev->dev) || !np) + return 0; + + par->clk_count = of_clk_get_parent_count(np); + if (par->clk_count <= 0) + return 0; + + par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL); + if (!par->clks) + return -ENOMEM; + + for (i = 0; i < par->clk_count; i++) { + clock = of_clk_get(np, i); + if (IS_ERR(clock)) { + if (PTR_ERR(clock) == -EPROBE_DEFER) { + while (--i >= 0) { + if (par->clks[i]) + clk_put(par->clks[i]); + } + kfree(par->clks); + return -EPROBE_DEFER; + } + dev_err(&pdev->dev, "%s: clock %d not found: %ld\n", + __func__, i, PTR_ERR(clock)); + continue; + } + par->clks[i] = clock; + } + + for (i = 0; i < par->clk_count; i++) { + if (par->clks[i]) { + ret = clk_prepare_enable(par->clks[i]); + if (ret) { + dev_err(&pdev->dev, + "%s: failed to enable clock %d: %d\n", + __func__, i, ret); + clk_put(par->clks[i]); + par->clks[i] = NULL; + } + } + } + + return 0; +} + +static void simplefb_clocks_destroy(struct simplefb_par *par) +{ + int i; + + if (!par->clks) + return; + + for (i = 0; i < par->clk_count; i++) { + if (par->clks[i]) { + clk_disable_unprepare(par->clks[i]); + clk_put(par->clks[i]); + } + } + + kfree(par->clks); +} +#else +static int simplefb_clocks_init(struct simplefb_par *par, + struct platform_device *pdev) { return 0; } +static void simplefb_clocks_destroy(struct simplefb_par *par) { } +#endif + static int simplefb_probe(struct platform_device *pdev) { int ret; @@ -236,6 +334,10 @@ static int simplefb_probe(struct platform_device *pdev) } info->pseudo_palette = par->palette; + ret = simplefb_clocks_init(par, pdev); + if (ret < 0) + goto error_unmap; + dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", info->fix.smem_start, info->fix.smem_len, info->screen_base); @@ -247,13 +349,15 @@ static int simplefb_probe(struct platform_device *pdev) ret = register_framebuffer(info); if (ret < 0) { dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); - goto error_unmap; + goto error_clocks; } dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); return 0; +error_clocks: + simplefb_clocks_destroy(par); error_unmap: iounmap(info->screen_base); error_fb_release: @@ -264,8 +368,10 @@ static int simplefb_probe(struct platform_device *pdev) static int simplefb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); + struct simplefb_par *par = info->par; unregister_framebuffer(info); + simplefb_clocks_destroy(par); framebuffer_release(info); return 0; -- GitLab From 9bb5b20f5d983e98d9a1cc7b7af5877b0f1c791b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:51 +0100 Subject: [PATCH 4802/9457] dt-bindings: simplefb: Specify node location and handoff related properties Since simplefb nodes do not relate directly to hw typically they have been placed in the root of the devicetree. As the represent runtime information having them as sub-nodes of /chosen is more logical, specify this. Also specify when to set the chosen stdout-path property to a simplefb node. For reliable handover to a hardware specific driver, that driver needs to know which simplefb to unregister when taking over, specify how the hw driver can find the matching simplefb node. Last add some advice on how to fill and use simplefb nodes from a firmware pov. Signed-off-by: Hans de Goede Acked-by: Geert Uytterhoeven Acked-by: Maxime Ripard Signed-off-by: Tomi Valkeinen --- .../bindings/video/simple-framebuffer.txt | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt index 8f35718f4f5b..f8fb7e6e5609 100644 --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -4,6 +4,40 @@ A simple frame-buffer describes a frame-buffer setup by firmware or the bootloader, with the assumption that the display hardware has already been set up to scan out from the memory pointed to by the reg property. +Since simplefb nodes represent runtime information they must be sub-nodes of +the chosen node (*). Simplefb nodes must be named "framebuffer@
". + +If the devicetree contains nodes for the display hardware used by a simplefb, +then the simplefb node must contain a property called "display", which +contains a phandle pointing to the primary display hw node, so that the OS +knows which simplefb to disable when handing over control to a driver for the +real hardware. The bindings for the hw nodes must specify which node is +considered the primary node. + +It is advised to add display# aliases to help the OS determine how to number +things. If display# aliases are used, then if the simplefb node contains a +"display" property then the /aliases/display# path must point to the display +hw node the "display" property points to, otherwise it must point directly +to the simplefb node. + +If a simplefb node represents the preferred console for user interaction, +then the chosen node's stdout-path property should point to it, or to the +primary display hw node, as with display# aliases. If display aliases are +used then it should be set to the alias instead. + +It is advised that devicetree files contain pre-filled, disabled framebuffer +nodes, so that the firmware only needs to update the mode information and +enable them. This way if e.g. later on support for more display clocks get +added, the simplefb nodes will already contain this info and the firmware +does not need to be updated. + +If pre-filled framebuffer nodes are used, they should be named +"framebuffer#-", e.g. "framebuffer0-hdmi". The output should be +included in the name since different outputs typically require different +clocks and the clocks are part of the pre-populated nodes. The firmware must +rename the nodes to the standard "framebuffer@
" name using the +runtime chosen address when enabling the nodes. + Required properties: - compatible: "simple-framebuffer" - reg: Should contain the location and size of the framebuffer memory. @@ -19,14 +53,36 @@ Optional properties: are expected to already be configured correctly. The OS must ensure these clocks are not modified or disabled while the simple framebuffer remains active. +- display : phandle pointing to the primary display hardware node Example: - framebuffer { +aliases { + display0 = &lcdc0; +} + +chosen { + framebuffer0: framebuffer@1d385000 { compatible = "simple-framebuffer"; reg = <0x1d385000 (1600 * 1200 * 2)>; width = <1600>; height = <1200>; stride = <(1600 * 2)>; format = "r5g6b5"; + clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; + display = <&lcdc0>; + }; + stdout-path = "display0"; +}; + +soc@01c00000 { + lcdc0: lcdc@1c0c000 { + compatible = "allwinner,sun4i-a10-lcdc"; + ... }; +}; + + +*) Older devicetree files may have a compatible = "simple-framebuffer" node +in a different place, operating systems must first enumerate any compatible +nodes found under chosen and then check for other compatible nodes. -- GitLab From 6d09dc6b74caaca83e32e67f2454406041d58fb0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:52 +0100 Subject: [PATCH 4803/9457] of.h: Keep extern declaration of of_* variables when !CONFIG_OF Keep the extern declaration of of_allnodes and friends, when building without of support, this way code using them can be written like this: if (IS_ENABLED(CONFIG_OF_PLATFORM) && of_chosen) { for_each_child_of_node(of_chosen, np) ... } And rely on the compiler optimizing it away, avoiding the need for #ifdef-ery. Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen --- include/linux/of.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/of.h b/include/linux/of.h index 6545e7aec7bb..f83ca9dddcba 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -105,8 +105,6 @@ static inline struct device_node *of_node_get(struct device_node *node) static inline void of_node_put(struct device_node *node) { } #endif /* !CONFIG_OF_DYNAMIC */ -#ifdef CONFIG_OF - /* Pointer for first entry in chain of all nodes. */ extern struct device_node *of_allnodes; extern struct device_node *of_chosen; @@ -114,6 +112,7 @@ extern struct device_node *of_aliases; extern struct device_node *of_stdout; extern raw_spinlock_t devtree_lock; +#ifdef CONFIG_OF static inline bool of_have_populated_dt(void) { return of_allnodes != NULL; -- GitLab From 89c95001c00089836415aa7a78848ec2dec9f922 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:53 +0100 Subject: [PATCH 4804/9457] simplefb: Add support for enumerating simplefb dt nodes in /chosen Update simplefb to support the new preferred location for simplefb dt nodes under /chosen. Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index d19294635a42..74c5edd38518 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -27,6 +27,7 @@ #include #include #include +#include static struct fb_fix_screeninfo simplefb_fix = { .id = "simple", @@ -392,7 +393,27 @@ static struct platform_driver simplefb_driver = { .probe = simplefb_probe, .remove = simplefb_remove, }; -module_platform_driver(simplefb_driver); + +static int __init simplefb_init(void) +{ + int ret; + struct device_node *np; + + ret = platform_driver_register(&simplefb_driver); + if (ret) + return ret; + + if (IS_ENABLED(CONFIG_OF) && of_chosen) { + for_each_child_of_node(of_chosen, np) { + if (of_device_is_compatible(np, "simple-framebuffer")) + of_platform_device_create(np, NULL, NULL); + } + } + + return 0; +} + +module_init(simplefb_init); MODULE_AUTHOR("Stephen Warren "); MODULE_DESCRIPTION("Simple framebuffer driver"); -- GitLab From ba168a3c7ff6df2e346959445190484b8331eb3d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:54 +0100 Subject: [PATCH 4805/9457] fbcon: Change fbcon_init from module_init to fs_initcall Various fb drivers register themselves before module_init so as to have a console as early as possible, this is of little use if fbcon does not initialize early too. Fbcon cannot initialize earlier then fs_initcall, because then the creation of /sys/class/graphics/fbcon will fail. Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen --- drivers/video/console/fbcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index eb976ee3a02f..ea437245562e 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3624,7 +3624,7 @@ static int __init fb_console_init(void) return 0; } -module_init(fb_console_init); +fs_initcall(fb_console_init); #ifdef MODULE -- GitLab From 0c5b240c7e0a7af56afd24db6570fa84d67728c2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 13:26:55 +0100 Subject: [PATCH 4806/9457] simplefb: Change simplefb_init from module_init to fs_initcall One of the reasons for having the simplefb nodes in /chosen, and doing explicit enumeration of the nodes there, is too allow enumerating them sooner, so that we get a console earlier on. Doing this earlier then fs_initcall is not useful, since the fb only turns into a console when fbcon intializes, which is a fs_initcall too. Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 74c5edd38518..8be9754c9fe9 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -413,7 +413,7 @@ static int __init simplefb_init(void) return 0; } -module_init(simplefb_init); +fs_initcall(simplefb_init); MODULE_AUTHOR("Stephen Warren "); MODULE_DESCRIPTION("Simple framebuffer driver"); -- GitLab From 9c9f1159a54c6163dd0b9d2085985d3c98dad11f Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Wed, 12 Nov 2014 17:24:03 +0000 Subject: [PATCH 4807/9457] GFS2: Use inode_newsize_ok and get_write_access in fallocate gfs2_fallocate wasn't checking inode_newsize_ok nor get_write_access. Split out the context setup and inode locking pieces into a separate function to make it more clear and add these missing calls. inode_newsize_ok is called conditional on FALLOC_FL_KEEP_SIZE as there is no need to enforce a file size limit if it isn't going to change. Signed-off-by: Andrew Price Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 66 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 5ebe56831794..3786579dd348 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -797,8 +797,7 @@ static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len, } } -static long gfs2_fallocate(struct file *file, int mode, loff_t offset, - loff_t len) +static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); struct gfs2_sbd *sdp = GFS2_SB(inode); @@ -812,14 +811,9 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; loff_t max_chunk_size = UINT_MAX & bsize_mask; - struct gfs2_holder gh; next = (next + 1) << sdp->sd_sb.sb_bsize_shift; - /* We only support the FALLOC_FL_KEEP_SIZE mode */ - if (mode & ~FALLOC_FL_KEEP_SIZE) - return -EOPNOTSUPP; - offset &= bsize_mask; len = next - offset; @@ -830,17 +824,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, if (bytes == 0) bytes = sdp->sd_sb.sb_bsize; - error = gfs2_rs_alloc(ip); - if (error) - return error; - - mutex_lock(&inode->i_mutex); - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - error = gfs2_glock_nq(&gh); - if (unlikely(error)) - goto out_uninit; - gfs2_size_hint(file, offset, len); while (len > 0) { @@ -853,8 +836,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, } error = gfs2_quota_lock_check(ip); if (error) - goto out_unlock; - + return error; retry: gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); @@ -898,18 +880,58 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, if (error == 0) error = generic_write_sync(file, pos, count); - goto out_unlock; + return error; out_trans_fail: gfs2_inplace_release(ip); out_qunlock: gfs2_quota_unlock(ip); + return error; +} + +static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t len) +{ + struct inode *inode = file_inode(file); + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + if (mode & ~FALLOC_FL_KEEP_SIZE) + return -EOPNOTSUPP; + + mutex_lock(&inode->i_mutex); + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + ret = gfs2_glock_nq(&gh); + if (ret) + goto out_uninit; + + if (!(mode & FALLOC_FL_KEEP_SIZE) && + (offset + len) > inode->i_size) { + ret = inode_newsize_ok(inode, offset + len); + if (ret) + goto out_unlock; + } + + ret = get_write_access(inode); + if (ret) + goto out_unlock; + + ret = gfs2_rs_alloc(ip); + if (ret) + goto out_putw; + + ret = __gfs2_fallocate(file, mode, offset, len); + if (ret) + gfs2_rs_deltree(ip->i_res); +out_putw: + put_write_access(inode); out_unlock: gfs2_glock_dq(&gh); out_uninit: gfs2_holder_uninit(&gh); mutex_unlock(&inode->i_mutex); - return error; + return ret; } #ifdef CONFIG_GFS2_FS_LOCKING_DLM -- GitLab From 1885867b84d58e3704ed175e0abac2f38889f34d Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Wed, 12 Nov 2014 17:24:04 +0000 Subject: [PATCH 4808/9457] GFS2: Update i_size properly on fallocate This addresses an issue caught by fsx where the inode size was not being updated to the expected value after fallocate(2) with mode 0. The problem was caused by the offset and len parameters being converted to multiples of the file system's block size, so i_size would be rounded up to the nearest block size multiple instead of the requested size. This replaces the per-chunk i_size updates with a single i_size_write on successful completion of the operation. With this patch gfs2 gets through a complete run of fsx. For clarity, the check for (error == 0) following the loop is removed as all failures before that point jump to out_* labels or return. Signed-off-by: Andrew Price Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 3786579dd348..118216419cef 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -729,7 +729,6 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len, struct gfs2_inode *ip = GFS2_I(inode); struct buffer_head *dibh; int error; - loff_t size = len; unsigned int nr_blks; sector_t lblock = offset >> inode->i_blkbits; @@ -763,11 +762,6 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len, goto out; } } - if (offset + size > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE)) - i_size_write(inode, offset + size); - - mark_inode_dirty(inode); - out: brelse(dibh); return error; @@ -878,9 +872,12 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t gfs2_quota_unlock(ip); } - if (error == 0) - error = generic_write_sync(file, pos, count); - return error; + if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) { + i_size_write(inode, pos + count); + mark_inode_dirty(inode); + } + + return generic_write_sync(file, pos, count); out_trans_fail: gfs2_inplace_release(ip); -- GitLab From 98f1a696a1b2f6cf0c1ce6850b1516beda9c1269 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Wed, 12 Nov 2014 17:24:05 +0000 Subject: [PATCH 4809/9457] GFS2: Update timestamps on fallocate gfs2_fallocate() wasn't updating ctime and mtime when modifying the inode. Add a call to file_update_time() to do that. Signed-off-by: Andrew Price Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 118216419cef..6e600abf694a 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -874,7 +874,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t if (!(mode & FALLOC_FL_KEEP_SIZE) && (pos + count) > inode->i_size) { i_size_write(inode, pos + count); - mark_inode_dirty(inode); + /* Marks the inode as dirty */ + file_update_time(file); } return generic_write_sync(file, pos, count); -- GitLab From 8593176c677226ead5b4effbd667dd19d5cba5ea Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 14 Nov 2014 10:22:07 +0100 Subject: [PATCH 4810/9457] kvm: memslots: track id_to_index changes during the insertion sort This completes the optimization from the previous patch, by removing the KVM_MEM_SLOTS_NUM-iteration loop from insert_memslot. Reviewed-by: Igor Mammedov Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c0c2202e6c4f..eae07f97ecf7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -677,31 +677,31 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) static void insert_memslot(struct kvm_memslots *slots, struct kvm_memory_slot *new) { - int i = slots->id_to_index[new->id]; - struct kvm_memory_slot *old = id_to_memslot(slots, new->id); + int id = new->id; + int i = slots->id_to_index[id]; struct kvm_memory_slot *mslots = slots->memslots; - if (new->npages == old->npages) { - *old = *new; - return; - } - - while (1) { - if (i < (KVM_MEM_SLOTS_NUM - 1) && - new->npages < mslots[i + 1].npages) { - mslots[i] = mslots[i + 1]; - i++; - } else if (i > 0 && new->npages > mslots[i - 1].npages) { - mslots[i] = mslots[i - 1]; - i--; + WARN_ON(mslots[i].id != id); + if (new->npages != mslots[i].npages) { + if (new->npages < mslots[i].npages) { + while (i < KVM_MEM_SLOTS_NUM - 1 && + new->npages < mslots[i + 1].npages) { + mslots[i] = mslots[i + 1]; + slots->id_to_index[mslots[i].id] = i; + i++; + } } else { - mslots[i] = *new; - break; + while (i > 0 && + new->npages > mslots[i - 1].npages) { + mslots[i] = mslots[i - 1]; + slots->id_to_index[mslots[i].id] = i; + i--; + } } } - for (i = 0; i < KVM_MEM_SLOTS_NUM; i++) - slots->id_to_index[slots->memslots[i].id] = i; + mslots[i] = *new; + slots->id_to_index[mslots[i].id] = i; } static void update_memslots(struct kvm_memslots *slots, -- GitLab From a720b41c41f5a7e4c51558cf087882c57331581f Mon Sep 17 00:00:00 2001 From: Antonios Motakis Date: Mon, 13 Oct 2014 14:06:16 +0100 Subject: [PATCH 4811/9457] iommu/arm-smmu: change IOMMU_EXEC to IOMMU_NOEXEC Exposing the XN flag of the SMMU driver as IOMMU_NOEXEC instead of IOMMU_EXEC makes it enforceable, since for IOMMUs that don't support the XN flag pages will always be executable. Signed-off-by: Antonios Motakis Acked-by: Joerg Roedel Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 9 +++++---- include/linux/iommu.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 60558f794922..566c1769d9bd 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1281,7 +1281,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, unsigned long pfn, int prot, int stage) { pte_t *pte, *start; - pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF | ARM_SMMU_PTE_XN; + pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF; if (pmd_none(*pmd)) { /* Allocate a new set of tables */ @@ -1315,10 +1315,11 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, pteval |= ARM_SMMU_PTE_MEMATTR_NC; } + if (prot & IOMMU_NOEXEC) + pteval |= ARM_SMMU_PTE_XN; + /* If no access, create a faulting entry to avoid TLB fills */ - if (prot & IOMMU_EXEC) - pteval &= ~ARM_SMMU_PTE_XN; - else if (!(prot & (IOMMU_READ | IOMMU_WRITE))) + if (!(prot & (IOMMU_READ | IOMMU_WRITE))) pteval &= ~ARM_SMMU_PTE_PAGE; pteval |= ARM_SMMU_PTE_SH_IS; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e6a7c9ff72f2..f47383a05d34 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -27,7 +27,7 @@ #define IOMMU_READ (1 << 0) #define IOMMU_WRITE (1 << 1) #define IOMMU_CACHE (1 << 2) /* DMA cache coherency */ -#define IOMMU_EXEC (1 << 3) +#define IOMMU_NOEXEC (1 << 3) struct iommu_ops; struct iommu_group; -- GitLab From c49866493b1ffb7c0a7963a1e3c0094e78760184 Mon Sep 17 00:00:00 2001 From: Antonios Motakis Date: Mon, 13 Oct 2014 14:06:17 +0100 Subject: [PATCH 4812/9457] iommu: add capability IOMMU_CAP_NOEXEC Some IOMMUs accept an IOMMU_NOEXEC protection flag in addition to IOMMU_READ and IOMMU_WRITE. Expose this as an IOMMU capability. Signed-off-by: Antonios Motakis Acked-by: Joerg Roedel Signed-off-by: Will Deacon --- include/linux/iommu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f47383a05d34..e438b30f062b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -61,6 +61,7 @@ enum iommu_cap { IOMMU_CAP_CACHE_COHERENCY, /* IOMMU can enforce cache coherent DMA transactions */ IOMMU_CAP_INTR_REMAP, /* IOMMU supports interrupt isolation */ + IOMMU_CAP_NOEXEC, /* IOMMU_NOEXEC flag */ }; /* -- GitLab From 0029a8dd6c807e04b119ec9416510d30936f45e6 Mon Sep 17 00:00:00 2001 From: Antonios Motakis Date: Mon, 13 Oct 2014 14:06:18 +0100 Subject: [PATCH 4813/9457] iommu/arm-smmu: add IOMMU_CAP_NOEXEC to the ARM SMMU driver The ARM SMMU supports the IOMMU_NOEXEC protection flag. Add the corresponding IOMMU capability. Signed-off-by: Antonios Motakis Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 566c1769d9bd..c8fc02f111c5 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1569,6 +1569,8 @@ static bool arm_smmu_capable(enum iommu_cap cap) return true; case IOMMU_CAP_INTR_REMAP: return true; /* MSIs are just memory writes */ + case IOMMU_CAP_NOEXEC: + return true; default: return false; } -- GitLab From cfdeec22e459e3c5081c8fc6d956c8ee68943397 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 27 Oct 2014 11:24:48 +0000 Subject: [PATCH 4814/9457] iommu/amd: remove compiler warning due to IOMMU_CAP_NOEXEC Some versions of GCC get unduly upset when confronted with a switch that doesn't explicitly handle all cases of an enum, despite having an implicit default case following the actualy switch statement: drivers/iommu/amd_iommu.c: In function 'amd_iommu_capable': >> drivers/iommu/amd_iommu.c:3409:2: warning: enumeration value 'IOMMU_CAP_NOEXEC' not handled in switch [-Wswitch] switch (cap) { This patch adds a case for IOMMU_CAP_NOEXEC to the amd IOMMU driver to remove this warning. Cc: Joerg Roedel Signed-off-by: Will Deacon --- drivers/iommu/amd_iommu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 505a9adac2d5..3d78a8fb5a6a 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3411,6 +3411,8 @@ static bool amd_iommu_capable(enum iommu_cap cap) return true; case IOMMU_CAP_INTR_REMAP: return (irq_remapping_enabled == 1); + case IOMMU_CAP_NOEXEC: + return false; } return false; -- GitLab From 0e7d37adbe45404a76d05d4ef11544f23cf639dd Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 7 Nov 2014 15:26:18 +0000 Subject: [PATCH 4815/9457] iommu/arm-smmu: Play nice on non-ARM/SMMU systems Currently the driver registers IOMMU bus operations for all busses even if no ARM SMMU is present on a system. Depending on the driver probing order this prevents the driver for the real IOMMU to register itself as the bus-wide IOMMU. Signed-off-by: Thierry Reding Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c8fc02f111c5..217581469f79 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -2075,8 +2075,20 @@ static struct platform_driver arm_smmu_driver = { static int __init arm_smmu_init(void) { + struct device_node *np; int ret; + /* + * Play nice with systems that don't have an ARM SMMU by checking that + * an ARM SMMU exists in the system before proceeding with the driver + * and IOMMU bus operation registration. + */ + np = of_find_matching_node(NULL, arm_smmu_of_match); + if (!np) + return 0; + + of_node_put(np); + ret = platform_driver_register(&arm_smmu_driver); if (ret) return ret; -- GitLab From c752ce45b213de8532baaf987ba930638f77c439 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 25 Jun 2014 22:46:31 +0100 Subject: [PATCH 4816/9457] iommu/arm-smmu: add support for DOMAIN_ATTR_NESTING attribute When domains are set with the DOMAIN_ATTR_NESTING flag, we must ensure that we allocate them to stage-2 context banks if the hardware permits it. This patch adds support for the attribute to the ARM SMMU driver, with the actual stage being determined depending on the features supported by the hardware. Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 110 ++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 217581469f79..7a80f710ba2d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -404,9 +404,16 @@ struct arm_smmu_cfg { #define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) #define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) +enum arm_smmu_domain_stage { + ARM_SMMU_DOMAIN_S1 = 0, + ARM_SMMU_DOMAIN_S2, + ARM_SMMU_DOMAIN_NESTED, +}; + struct arm_smmu_domain { struct arm_smmu_device *smmu; struct arm_smmu_cfg cfg; + enum arm_smmu_domain_stage stage; spinlock_t lock; }; @@ -906,19 +913,46 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (smmu_domain->smmu) goto out_unlock; - if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { + /* + * Mapping the requested stage onto what we support is surprisingly + * complicated, mainly because the spec allows S1+S2 SMMUs without + * support for nested translation. That means we end up with the + * following table: + * + * Requested Supported Actual + * S1 N S1 + * S1 S1+S2 S1 + * S1 S2 S2 + * S1 S1 S1 + * N N N + * N S1+S2 S2 + * N S2 S2 + * N S1 S1 + * + * Note that you can't actually request stage-2 mappings. + */ + if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) + smmu_domain->stage = ARM_SMMU_DOMAIN_S2; + if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2)) + smmu_domain->stage = ARM_SMMU_DOMAIN_S1; + + switch (smmu_domain->stage) { + case ARM_SMMU_DOMAIN_S1: + cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; + start = smmu->num_s2_context_banks; + break; + case ARM_SMMU_DOMAIN_NESTED: /* * We will likely want to change this if/when KVM gets * involved. */ - cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; - start = smmu->num_s2_context_banks; - } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) { - cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; - start = smmu->num_s2_context_banks; - } else { + case ARM_SMMU_DOMAIN_S2: cfg->cbar = CBAR_TYPE_S2_TRANS; start = 0; + break; + default: + ret = -EINVAL; + goto out_unlock; } ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, @@ -1647,20 +1681,56 @@ static void arm_smmu_remove_device(struct device *dev) iommu_group_remove_device(dev); } +static int arm_smmu_domain_get_attr(struct iommu_domain *domain, + enum iommu_attr attr, void *data) +{ + struct arm_smmu_domain *smmu_domain = domain->priv; + + switch (attr) { + case DOMAIN_ATTR_NESTING: + *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); + return 0; + default: + return -ENODEV; + } +} + +static int arm_smmu_domain_set_attr(struct iommu_domain *domain, + enum iommu_attr attr, void *data) +{ + struct arm_smmu_domain *smmu_domain = domain->priv; + + switch (attr) { + case DOMAIN_ATTR_NESTING: + if (smmu_domain->smmu) + return -EPERM; + if (*(int *)data) + smmu_domain->stage = ARM_SMMU_DOMAIN_NESTED; + else + smmu_domain->stage = ARM_SMMU_DOMAIN_S1; + + return 0; + default: + return -ENODEV; + } +} + static const struct iommu_ops arm_smmu_ops = { - .capable = arm_smmu_capable, - .domain_init = arm_smmu_domain_init, - .domain_destroy = arm_smmu_domain_destroy, - .attach_dev = arm_smmu_attach_dev, - .detach_dev = arm_smmu_detach_dev, - .map = arm_smmu_map, - .unmap = arm_smmu_unmap, - .iova_to_phys = arm_smmu_iova_to_phys, - .add_device = arm_smmu_add_device, - .remove_device = arm_smmu_remove_device, - .pgsize_bitmap = (SECTION_SIZE | - ARM_SMMU_PTE_CONT_SIZE | - PAGE_SIZE), + .capable = arm_smmu_capable, + .domain_init = arm_smmu_domain_init, + .domain_destroy = arm_smmu_domain_destroy, + .attach_dev = arm_smmu_attach_dev, + .detach_dev = arm_smmu_detach_dev, + .map = arm_smmu_map, + .unmap = arm_smmu_unmap, + .iova_to_phys = arm_smmu_iova_to_phys, + .add_device = arm_smmu_add_device, + .remove_device = arm_smmu_remove_device, + .domain_get_attr = arm_smmu_domain_get_attr, + .domain_set_attr = arm_smmu_domain_set_attr, + .pgsize_bitmap = (SECTION_SIZE | + ARM_SMMU_PTE_CONT_SIZE | + PAGE_SIZE), }; static void arm_smmu_device_reset(struct arm_smmu_device *smmu) -- GitLab From 5e9f36c59a4883c6d8db4a3c097e4fc2234742de Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 14 Nov 2014 09:10:59 -0700 Subject: [PATCH 4817/9457] drivers/vfio: allow type-1 IOMMU instantiation on top of an ARM SMMU The ARM SMMU driver is compatible with the notion of a type-1 IOMMU in VFIO. This patch allows VFIO_IOMMU_TYPE1 to be selected if ARM_SMMU=y. Signed-off-by: Will Deacon [aw: update for existing S390 patch] Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index b93c25901e89..14e27ab32456 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -16,7 +16,7 @@ config VFIO_SPAPR_EEH menuconfig VFIO tristate "VFIO Non-Privileged userspace driver framework" depends on IOMMU_API - select VFIO_IOMMU_TYPE1 if (X86 || S390) + select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM_SMMU) select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES) select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES) select ANON_INODES -- GitLab From 21318cce5a77ad3e90f6974119389ed632cc8b15 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 14 Nov 2014 14:20:27 +0000 Subject: [PATCH 4818/9457] drm/i915/skl: Fix big integer constant sparse warning intel_ddi.c:955:41: sparse: constant 8400000000 is so big it is long intel_ddi.c:955:53: sparse: constant 9000000000 is so big it is long intel_ddi.c:955:65: sparse: constant 9600000000 is so big it is long intel_ddi.c:1028:23: sparse: constant 9600000000 is so big it is long intel_ddi.c:1031:23: sparse: constant 9000000000 is so big it is long intel_ddi.c:1034:23: sparse: constant 8400000000 is so big it is long Signed-off-by: Damien Lespiau Reported-by: kbuild test robot Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 17bf9116fab1..ca33ee9477f1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -952,7 +952,9 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */, struct skl_wrpll_params *wrpll_params) { uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */ - uint64_t dco_central_freq[3] = {8400000000, 9000000000, 9600000000}; + uint64_t dco_central_freq[3] = {8400000000ULL, + 9000000000ULL, + 9600000000ULL}; uint32_t min_dco_deviation = 400; uint32_t min_dco_index = 3; uint32_t P0[4] = {1, 2, 3, 7}; @@ -1025,13 +1027,13 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */, wrpll_params->central_freq = dco_central_freq[min_dco_index]; switch (dco_central_freq[min_dco_index]) { - case 9600000000: + case 9600000000ULL: wrpll_params->central_freq = 0; break; - case 9000000000: + case 9000000000ULL: wrpll_params->central_freq = 1; break; - case 8400000000: + case 8400000000ULL: wrpll_params->central_freq = 3; } -- GitLab From 35c16a8f0b994461d49ce2479c67903f95045159 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Nov 2014 16:09:31 +0100 Subject: [PATCH 4819/9457] ahci_sunxi: Make AHCI_HFLAG_NO_PMP flag configurable with a module option The use of the AHCI_HFLAG_NO_PMP flag is something which we inherited from the Allwinner android kernel sources, and I've always wanted to test if this is really necessary. So recently I've bought a sata port multiplexer, and I've given this a test spin on both A10 and A20 devices, and it seems to work fine: [ 2.154456] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300) [ 2.161092] ata1.15: Port Multiplier 1.2, 0x197b:0x0325 r0, 5 ports, feat 0x5/0xf [ 2.175511] ata1.00: hard resetting link [ 2.524929] ata1.00: SATA link up 3.0 Gbps (SStatus 123 SControl 320) [ 2.531430] ata1.01: hard resetting link [ 2.974465] ata1.01: link resume succeeded after 1 retries [ 3.094932] ata1.01: SATA link up 3.0 Gbps (SStatus 123 SControl 300) [ 3.101431] ata1.02: hard resetting link [ 4.174466] ata1.02: failed to resume link (SControl 0) [ 4.180065] ata1.02: SATA link down (SStatus 0 SControl 0) (and the same for links 3 and 4) Once the NO_PMP flag is removed it correctly sees the 2 disks which I've attached, and I can mount and use them just fine. Unfortunately when I then directly attached a disk to the sata port on the sunxi SoC, and booted a kernel without the AHCI_HFLAG_NO_PMP flag, it would not recognize that disk. It turns out that the sata controller in the sunxi SoCs fails to handle soft-resets issued to directly attached disks, and when pmp support is enabled the kernel will always issue a soft-reset. So add a module parameter to enable pmp usage, and default this to off, so that directly attached disks keep working normally. Signed-off-by: Hans de Goede Signed-off-by: Tejun Heo --- drivers/ata/ahci_sunxi.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index e44d675a30ec..b5aedca5ea3c 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -27,6 +27,12 @@ #include #include "ahci.h" +/* Insmod parameters */ +static bool enable_pmp; +module_param(enable_pmp, bool, 0); +MODULE_PARM_DESC(enable_pmp, + "Enable support for sata port multipliers, only use if you use a pmp!"); + #define AHCI_BISTAFR 0x00a0 #define AHCI_BISTCR 0x00a4 #define AHCI_BISTFCTR 0x00a8 @@ -184,7 +190,15 @@ static int ahci_sunxi_probe(struct platform_device *pdev) goto disable_resources; hpriv->flags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | - AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ; + AHCI_HFLAG_YES_NCQ; + + /* + * The sunxi sata controller seems to be unable to successfully do a + * soft reset if no pmp is attached, so disable pmp use unless + * requested, otherwise directly attached disks do not work. + */ + if (!enable_pmp) + hpriv->flags |= AHCI_HFLAG_NO_PMP; rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info); if (rc) -- GitLab From 70ee45e10bd06d5c41c46bd0f685b7c04c72b52d Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 14 Nov 2014 15:05:59 +0000 Subject: [PATCH 4820/9457] drm/i915/skl: Don't allow disabling ppgtt and execlists on gen9+ Running the driver without execlists and hence PPGTT (either aliasing or full) isn't a supported configuration on gen9+. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 7 ++++++- drivers/gpu/drm/i915/intel_lrc.c | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 68a27b2d3654..29a4486c62ad 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -43,7 +43,12 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) if (IS_GEN8(dev)) has_full_ppgtt = false; /* XXX why? */ - if (enable_ppgtt == 0 || !has_aliasing_ppgtt) + /* + * We don't allow disabling PPGTT for gen9+ as it's a requirement for + * execlists, the sole mechanism available to submit work. + */ + if (INTEL_INFO(dev)->gen < 9 && + (enable_ppgtt == 0 || !has_aliasing_ppgtt)) return 0; if (enable_ppgtt == 1) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0eee4288519b..b7c4c9ab9012 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -220,6 +220,9 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists { WARN_ON(i915.enable_ppgtt == -1); + if (INTEL_INFO(dev)->gen >= 9) + return 1; + if (enable_execlists == 0) return 0; -- GitLab From cdcd7f7287532131d2075dd45f15aaf39dcfe983 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 14 Nov 2014 15:40:45 +0000 Subject: [PATCH 4821/9457] ASoC: wm_adsp: Use vmalloc to allocate firmware download buffer Use vmalloc to allocate the buffer for firmware/coefficient download and rely on the SPI core to split this up into DMA-able chunks. This should give better performance and means we no longer need to manually split the download into page size chunks to avoid allocating overly large continuous memory regions. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 56 +++++++++++++++----------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f412a9911a75..0a08ef5e27c8 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -169,11 +170,12 @@ static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, if (buf == NULL) return NULL; - buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA); + buf->buf = vmalloc(len); if (!buf->buf) { - kfree(buf); + vfree(buf); return NULL; } + memcpy(buf->buf, src, len); if (list) list_add_tail(&buf->list, list); @@ -188,7 +190,7 @@ static void wm_adsp_buf_free(struct list_head *list) struct wm_adsp_buf, list); list_del(&buf->list); - kfree(buf->buf); + vfree(buf->buf); kfree(buf); } } @@ -684,38 +686,24 @@ static int wm_adsp_load(struct wm_adsp *dsp) } if (reg) { - size_t to_write = PAGE_SIZE; - size_t remain = le32_to_cpu(region->len); - const u8 *data = region->data; - - while (remain > 0) { - if (remain < PAGE_SIZE) - to_write = remain; - - buf = wm_adsp_buf_alloc(data, - to_write, - &buf_list); - if (!buf) { - adsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; - } - - ret = regmap_raw_write_async(regmap, reg, - buf->buf, - to_write); - if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write %zd bytes at %d in %s: %d\n", - file, regions, - to_write, offset, - region_name, ret); - goto out_fw; - } + buf = wm_adsp_buf_alloc(region->data, + le32_to_cpu(region->len), + &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + } - data += to_write; - reg += to_write / 2; - remain -= to_write; + ret = regmap_raw_write_async(regmap, reg, buf->buf, + le32_to_cpu(region->len)); + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + le32_to_cpu(region->len), offset, + region_name, ret); + goto out_fw; } } -- GitLab From b78384d5334b10139c64db1ec13ea249b92b0ef6 Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Mon, 10 Nov 2014 19:42:29 +0100 Subject: [PATCH 4822/9457] sata_rcar: Add clocks to sata_rcar bindings Now that the clocks are available in the R-Car Gen2 DT, add clocks property description to the sata_rcar bindings. The clocks have been tested on r8a7791 so we use that as an example of the R-Car SATA node. Signed-off-by: Valentine Barshak [geert: Reworded clocks property] Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Tejun Heo --- Documentation/devicetree/bindings/ata/sata_rcar.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt index 80ae87a0784b..f09c1ee260ba 100644 --- a/Documentation/devicetree/bindings/ata/sata_rcar.txt +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt @@ -9,12 +9,14 @@ Required properties: - "renesas,sata-r8a7793" for R-Car M2-N - reg : address and length of the SATA registers; - interrupts : must consist of one interrupt specifier. +- clocks : must contain a reference to the functional clock. Example: -sata: sata@fc600000 { - compatible = "renesas,sata-r8a7779"; - reg = <0xfc600000 0x2000>; +sata0: sata@ee300000 { + compatible = "renesas,sata-r8a7791"; + reg = <0 0xee300000 0 0x2000>; interrupt-parent = <&gic>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp8_clks R8A7791_CLK_SATA0>; }; -- GitLab From 598e9a9005ef3ad7540227c9161f7cfbdccd0dbe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Nov 2014 19:42:30 +0100 Subject: [PATCH 4823/9457] sata_rcar: Document deprecated "renesas,rcar-sata" Commit e67adb4e669db834 ("sata_rcar: Add R-Car Gen2 SATA PHY support") deprecated "renesas,rcar-sata" in favor of "renesas,sata-r8a7779", but the deprecated value was never documented in the binding documentation, while it is still in active use. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Tejun Heo --- Documentation/devicetree/bindings/ata/sata_rcar.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt index f09c1ee260ba..2493a5a31655 100644 --- a/Documentation/devicetree/bindings/ata/sata_rcar.txt +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt @@ -3,6 +3,7 @@ Required properties: - compatible : should contain one of the following: - "renesas,sata-r8a7779" for R-Car H1 + ("renesas,rcar-sata" is deprecated) - "renesas,sata-r8a7790-es1" for R-Car H2 ES1 - "renesas,sata-r8a7790" for R-Car H2 other than ES1 - "renesas,sata-r8a7791" for R-Car M2-W -- GitLab From 8ea0be4f1c2ec7b750b7949c92f686be6ae4daab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:42:59 +0200 Subject: [PATCH 4824/9457] drm/i915: Refactor vlv_display_irq_uninstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the vlv display irq uninstall code into a separate function, for eventual sharing with chv. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 320b310ebff5..87b46b402bde 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3588,6 +3588,20 @@ static void gen8_irq_uninstall(struct drm_device *dev) gen8_irq_reset(dev); } +static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv) +{ + /* Interrupt setup is already guaranteed to be single-threaded, this is + * just to make the assert_spin_locked check happy. */ + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->display_irqs_enabled) + valleyview_display_irqs_uninstall(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + + vlv_display_irq_reset(dev_priv); + + dev_priv->irq_mask = 0; +} + static void valleyview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3601,16 +3615,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev) I915_WRITE(HWSTAM, 0xffffffff); - /* Interrupt setup is already guaranteed to be single-threaded, this is - * just to make the assert_spin_locked check happy. */ - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display_irqs_enabled) - valleyview_display_irqs_uninstall(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); - - vlv_display_irq_reset(dev_priv); - - dev_priv->irq_mask = 0; + vlv_display_irq_uninstall(dev_priv); } static void cherryview_irq_uninstall(struct drm_device *dev) -- GitLab From c2b66797cf34e4bc677c3a7cbb9ca5b1060031a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:43:02 +0200 Subject: [PATCH 4825/9457] drm/i915: Use vlv display irq setup code for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throw away the hand rolled display irq setup code on chv, and instead just call vlv_display_irq_postinstall() and vlv_display_irq_uninstall(). Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 37 ++------------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 87b46b402bde..5e5d3f709f0f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3541,34 +3541,8 @@ static int gen8_irq_postinstall(struct drm_device *dev) static int cherryview_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 enable_mask = I915_DISPLAY_PORT_INTERRUPT | - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | - I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; - u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | - PIPE_CRC_DONE_INTERRUPT_STATUS; - int pipe; - - /* - * Leave vblank interrupts masked initially. enable/disable will - * toggle them based on usage. - */ - dev_priv->irq_mask = ~enable_mask; - - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0xffff); - - spin_lock_irq(&dev_priv->irq_lock); - i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); - for_each_pipe(dev_priv, pipe) - i915_enable_pipestat(dev_priv, pipe, pipestat_enable); - spin_unlock_irq(&dev_priv->irq_lock); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IIR, 0xffffffff); - I915_WRITE(VLV_IER, enable_mask); - I915_WRITE(VLV_IMR, dev_priv->irq_mask); - POSTING_READ(VLV_IMR); + vlv_display_irq_postinstall(dev_priv); gen8_gt_irq_postinstall(dev_priv); @@ -3621,7 +3595,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev) static void cherryview_irq_uninstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; if (!dev_priv) return; @@ -3633,13 +3606,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) GEN5_IRQ_RESET(GEN8_PCU_); - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - - for_each_pipe(dev_priv, pipe) - I915_WRITE(PIPESTAT(pipe), 0xffff); - - GEN5_IRQ_RESET(VLV_); + vlv_display_irq_uninstall(dev_priv); } static void ironlake_irq_uninstall(struct drm_device *dev) -- GitLab From e671538d5110e913a0a3cd6122d7f70b71fc0728 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 13 Oct 2014 11:50:41 +0300 Subject: [PATCH 4826/9457] ARM: dts: dra7: fix DSS PLL clock mux registers The clock nodes for DSS VIDEO1/2 and HDMI have wrong register addresses. This patch fixes the addresses so that they point to CM_CLKSEL_VIDEO1_PLL_SYS, CM_CLKSEL_VIDEO2_PLL_SYS and CM_CLKSEL_HDMI_PLL_SYS. Reported-by: Somnath Mukherjee Signed-off-by: Tomi Valkeinen Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7xx-clocks.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index 2c05b3f017fa..4bdcbd61ce47 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -1042,7 +1042,7 @@ #clock-cells = <0>; compatible = "ti,mux-clock"; clocks = <&sys_clkin1>, <&sys_clkin2>; - reg = <0x01a4>; + reg = <0x0164>; }; mlb_clk: mlb_clk { @@ -1084,14 +1084,14 @@ #clock-cells = <0>; compatible = "ti,mux-clock"; clocks = <&sys_clkin1>, <&sys_clkin2>; - reg = <0x01d0>; + reg = <0x0168>; }; video2_dpll_clk_mux: video2_dpll_clk_mux { #clock-cells = <0>; compatible = "ti,mux-clock"; clocks = <&sys_clkin1>, <&sys_clkin2>; - reg = <0x01d4>; + reg = <0x016c>; }; wkupaon_iclk_mux: wkupaon_iclk_mux { -- GitLab From cf3d262e39941d8f148148e840c00fcbc35a8e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 14 Nov 2014 21:02:44 +0200 Subject: [PATCH 4827/9457] drm/i915: Fix comments about CHV snoop behaviour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the misinformed notes about CHV snoop behaviour with something that's hopefully closer to reality. Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 29a4486c62ad..2b008525bda2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1942,9 +1942,17 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) * Only the snoop bit has meaning for CHV, the rest is * ignored. * - * Note that the harware enforces snooping for all page - * table accesses. The snoop bit is actually ignored for - * PDEs. + * The hardware will never snoop for certain types of accesses: + * - CPU GTT (GMADR->GGTT->no snoop->memory) + * - PPGTT page tables + * - some other special cycles + * + * As with BDW, we also need to consider the following for GT accesses: + * "For GGTT, there is NO pat_sel[2:0] from the entry, + * so RTL will always use the value corresponding to + * pat_sel = 000". + * Which means we must set the snoop bit in PAT entry 0 + * in order to keep the global status page working. */ pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | GEN8_PPAT(1, 0) | -- GitLab From ca25cb54ace0e77fa559f3634380f4ed92c520d1 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 29 Nov 2013 16:19:50 -0300 Subject: [PATCH 4828/9457] [media] mn88472: Panasonic MN88472 demod driver (DVB-C only) Only DVB-C mode is supported, DVB-T and DVB-T2 are not supported. Very much feature reduced version, no signal statistics nor normal chip configuration options. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 7 + drivers/media/dvb-frontends/Makefile | 2 + drivers/media/dvb-frontends/mn88472.h | 46 +++ drivers/media/dvb-frontends/mn88472_c.c | 414 +++++++++++++++++++++ drivers/media/dvb-frontends/mn88472_priv.h | 36 ++ 5 files changed, 505 insertions(+) create mode 100644 drivers/media/dvb-frontends/mn88472.h create mode 100644 drivers/media/dvb-frontends/mn88472_c.c create mode 100644 drivers/media/dvb-frontends/mn88472_priv.h diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 6c75418222e2..02bada4d7c61 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -441,6 +441,13 @@ config DVB_CXD2820R help Say Y when you want to support this frontend. +config DVB_MN88472 + tristate "Panasonic MN88472" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Say Y when you want to support this frontend. + config DVB_RTL2830 tristate "Realtek RTL2830 DVB-T" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index ba59df63d050..27d82b6a7ff3 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -15,6 +15,7 @@ stv0900-objs := stv0900_core.o stv0900_sw.o drxd-objs := drxd_firm.o drxd_hard.o cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o drxk-objs := drxk_hard.o +mn88472-objs := mn88472_c.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o @@ -103,6 +104,7 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o obj-$(CONFIG_DVB_IX2505V) += ix2505v.o obj-$(CONFIG_DVB_STV0367) += stv0367.o obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o +obj-$(CONFIG_DVB_MN88472) += mn88472.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_SI2165) += si2165.o diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h new file mode 100644 index 000000000000..29aa48507173 --- /dev/null +++ b/drivers/media/dvb-frontends/mn88472.h @@ -0,0 +1,46 @@ +/* + * Panasonic MN88472 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2013 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MN88472_H +#define MN88472_H + +#include + +struct mn88472_c_config { + /* + * max bytes I2C client could write + * Value must be set. + */ + int i2c_wr_max; +}; + +#if IS_ENABLED(CONFIG_DVB_MN88472) +extern struct dvb_frontend *mn88472_c_attach( + const struct mn88472_c_config *cfg, + struct i2c_adapter *i2c +); +#else +static inline struct dvb_frontend *mn88472_c_attach( + const struct mn88472_c_config *cfg, + struct i2c_adapter *i2c +) +{ + dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472_c.c new file mode 100644 index 000000000000..59d48e75acc1 --- /dev/null +++ b/drivers/media/dvb-frontends/mn88472_c.c @@ -0,0 +1,414 @@ +/* + * Panasonic MN88472 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2013 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mn88472_priv.h" + +static struct dvb_frontend_ops mn88472_ops_c; + +/* write multiple registers */ +static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len) +{ +#define MAX_WR_LEN 21 +#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) + int ret; + u8 buf[MAX_WR_XFER_LEN]; + struct i2c_msg msg[1] = { + { + .addr = (reg >> 8) & 0xff, + .flags = 0, + .len = 1 + len, + .buf = buf, + } + }; + + if (WARN_ON(len > MAX_WR_LEN)) + return -EINVAL; + + buf[0] = (reg >> 0) & 0xff; + memcpy(&buf[1], val, len); + + ret = i2c_transfer(s->i2c, msg, 1); + if (ret == 1) { + ret = 0; + } else { + dev_warn(&s->i2c->dev, + "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* read multiple registers */ +static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len) +{ +#define MAX_RD_LEN 2 +#define MAX_RD_XFER_LEN (MAX_RD_LEN) + int ret; + u8 buf[MAX_RD_XFER_LEN]; + struct i2c_msg msg[2] = { + { + .addr = (reg >> 8) & 0xff, + .flags = 0, + .len = 1, + .buf = buf, + }, { + .addr = (reg >> 8) & 0xff, + .flags = I2C_M_RD, + .len = len, + .buf = buf, + } + }; + + if (WARN_ON(len > MAX_RD_LEN)) + return -EINVAL; + + buf[0] = (reg >> 0) & 0xff; + + ret = i2c_transfer(s->i2c, msg, 2); + if (ret == 2) { + memcpy(val, buf, len); + ret = 0; + } else { + dev_warn(&s->i2c->dev, + "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* write single register */ +static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val) +{ + return mn88472_wregs(s, reg, &val, 1); +} + +/* read single register */ +static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val) +{ + return mn88472_rregs(s, reg, val, 1); +} + +static int mn88472_set_frontend_c(struct dvb_frontend *fe) +{ + struct mn88472_state *s = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + u32 if_frequency = 0; + dev_dbg(&s->i2c->dev, + "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", + __func__, c->delivery_system, c->modulation, + c->frequency, c->symbol_rate, c->inversion); + + if (!s->warm) { + ret = -EAGAIN; + goto err; + } + + /* program tuner */ + if (fe->ops.tuner_ops.set_params) { + ret = fe->ops.tuner_ops.set_params(fe); + if (ret) + goto err; + } + + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); + if (ret) + goto err; + + dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n", + __func__, if_frequency); + } + + if (if_frequency != 5070000) { + dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n", + KBUILD_MODNAME, if_frequency); + ret = -EINVAL; + goto err; + } + + ret = mn88472_wregs(s, 0x1c08, "\x1d", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18d9, "\xe3", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1c83, "\x01", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1c10, + "\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1846, "\x00", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18ae, "\x00", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18b0, "\x0b", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18b4, "\x00", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18cd, "\x17", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18d4, "\x09", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x18d6, "\x48", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1a00, "\xb0", 1); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1); + if (ret) + goto err; + + s->delivery_system = c->delivery_system; + + return 0; +err: + dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88472_read_status_c(struct dvb_frontend *fe, fe_status_t *status) +{ + struct mn88472_state *s = fe->demodulator_priv; + int ret; + u8 u8tmp; + + *status = 0; + + if (!s->warm) { + ret = -EAGAIN; + goto err; + } + + ret = mn88472_rreg(s, 0x1a84, &u8tmp); + if (ret) + goto err; + + if (u8tmp == 0x08) + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + + return 0; +err: + dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88472_init_c(struct dvb_frontend *fe) +{ + struct mn88472_state *s = fe->demodulator_priv; + int ret, len, remaining; + const struct firmware *fw = NULL; + u8 *fw_file = MN88472_FIRMWARE; + dev_dbg(&s->i2c->dev, "%s:\n", __func__); + + /* set cold state by default */ + s->warm = false; + + /* power on */ + ret = mn88472_wreg(s, 0x1c05, 0x00); + if (ret) + goto err; + + ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2); + if (ret) + goto err; + + /* request the firmware, this will block and timeout */ + ret = request_firmware(&fw, fw_file, s->i2c->dev.parent); + if (ret) { + dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n", + KBUILD_MODNAME, fw_file); + goto err; + } + + dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n", + KBUILD_MODNAME, fw_file); + + ret = mn88472_wreg(s, 0x18f5, 0x03); + if (ret) + goto err; + + for (remaining = fw->size; remaining > 0; + remaining -= (s->cfg->i2c_wr_max - 1)) { + len = remaining; + if (len > (s->cfg->i2c_wr_max - 1)) + len = (s->cfg->i2c_wr_max - 1); + + ret = mn88472_wregs(s, 0x18f6, + &fw->data[fw->size - remaining], len); + if (ret) { + dev_err(&s->i2c->dev, + "%s: firmware download failed=%d\n", + KBUILD_MODNAME, ret); + goto err; + } + } + + ret = mn88472_wreg(s, 0x18f5, 0x00); + if (ret) + goto err; + + release_firmware(fw); + fw = NULL; + + /* warm state */ + s->warm = true; + + return 0; +err: + if (fw) + release_firmware(fw); + + dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88472_sleep_c(struct dvb_frontend *fe) +{ + struct mn88472_state *s = fe->demodulator_priv; + int ret; + dev_dbg(&s->i2c->dev, "%s:\n", __func__); + + /* power off */ + ret = mn88472_wreg(s, 0x1c0b, 0x30); + if (ret) + goto err; + + ret = mn88472_wreg(s, 0x1c05, 0x3e); + if (ret) + goto err; + + s->delivery_system = SYS_UNDEFINED; + + return 0; +err: + dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static void mn88472_release_c(struct dvb_frontend *fe) +{ + struct mn88472_state *s = fe->demodulator_priv; + kfree(s); +} + +struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg, + struct i2c_adapter *i2c) +{ + int ret; + struct mn88472_state *s; + u8 u8tmp; + dev_dbg(&i2c->dev, "%s:\n", __func__); + + /* allocate memory for the internal state */ + s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL); + if (!s) { + ret = -ENOMEM; + dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); + goto err; + } + + s->cfg = cfg; + s->i2c = i2c; + + /* check demod responds to I2C */ + ret = mn88472_rreg(s, 0x1c00, &u8tmp); + if (ret) + goto err; + + /* create dvb_frontend */ + memcpy(&s->fe.ops, &mn88472_ops_c, sizeof(struct dvb_frontend_ops)); + s->fe.demodulator_priv = s; + + return &s->fe; +err: + dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + kfree(s); + return NULL; +} +EXPORT_SYMBOL(mn88472_attach_c); + +static struct dvb_frontend_ops mn88472_ops_c = { + .delsys = {SYS_DVBC_ANNEX_A}, + .info = { + .name = "Panasonic MN88472", + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM + }, + + .release = mn88472_release_c, + + .init = mn88472_init_c, + .sleep = mn88472_sleep_c, + + .set_frontend = mn88472_set_frontend_c, +/* .get_frontend = mn88472_get_frontend_c, */ + + .read_status = mn88472_read_status_c, +/* .read_snr = mn88472_read_snr_c, */ +}; + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(MN88472_FIRMWARE); diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h new file mode 100644 index 000000000000..ecade84a0cf4 --- /dev/null +++ b/drivers/media/dvb-frontends/mn88472_priv.h @@ -0,0 +1,36 @@ +/* + * Panasonic MN88472 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2013 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MN88472_PRIV_H +#define MN88472_PRIV_H + +#include "dvb_frontend.h" +#include "mn88472.h" +#include "dvb_math.h" +#include +#include + +#define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw" + +struct mn88472_state { + struct i2c_adapter *i2c; + const struct mn88472_c_config *cfg; + struct dvb_frontend fe; + fe_delivery_system_t delivery_system; + bool warm; /* FW running */ +}; + +#endif -- GitLab From 64796a52885e017021deca1ca98f102c8481399e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 2 Dec 2013 20:19:52 -0300 Subject: [PATCH 4829/9457] [media] mn88472: correct attach symbol name Wrong symbol name causes demod attach failure. Reported-by: Benjamin Larsson Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h index 29aa48507173..c817bfba9681 100644 --- a/drivers/media/dvb-frontends/mn88472.h +++ b/drivers/media/dvb-frontends/mn88472.h @@ -28,12 +28,12 @@ struct mn88472_c_config { }; #if IS_ENABLED(CONFIG_DVB_MN88472) -extern struct dvb_frontend *mn88472_c_attach( +extern struct dvb_frontend *mn88472_attach_c( const struct mn88472_c_config *cfg, struct i2c_adapter *i2c ); #else -static inline struct dvb_frontend *mn88472_c_attach( +static inline struct dvb_frontend *mn88472_attach_c( const struct mn88472_c_config *cfg, struct i2c_adapter *i2c ) -- GitLab From 8e0d8572be05de0c3af04783775ce4037df96be8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 2 Dec 2013 20:28:58 -0300 Subject: [PATCH 4830/9457] [media] mn88472: add small delay to wait DVB-C lock 400ms delay seems to be enough in order to gain DVB-C lock. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472_c.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472_c.c index 59d48e75acc1..b5bd326d9e66 100644 --- a/drivers/media/dvb-frontends/mn88472_c.c +++ b/drivers/media/dvb-frontends/mn88472_c.c @@ -105,6 +105,13 @@ static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val) return mn88472_rregs(s, reg, val, 1); } +static int mn88472_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *s) +{ + s->min_delay_ms = 400; + return 0; +} + static int mn88472_set_frontend_c(struct dvb_frontend *fe) { struct mn88472_state *s = fe->demodulator_priv; @@ -398,6 +405,8 @@ static struct dvb_frontend_ops mn88472_ops_c = { .release = mn88472_release_c, + .get_tune_settings = mn88472_get_tune_settings, + .init = mn88472_init_c, .sleep = mn88472_sleep_c, -- GitLab From 5ef1ad351c3f02ea5be0268f5f71a2eefafcb166 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 25 Oct 2014 22:23:09 -0300 Subject: [PATCH 4831/9457] [media] mn88472: rename mn88472_c.c => mn88472.c Original plan was to implement driver as one file per used demod standard (mn88472_c.c, mn88472_t.c and mn88472_t2.c). However, that plan was a mistake as driver code differences are so small between different standards. Due to that rename this file and implement all the needed functionality to that file. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Makefile | 1 - .../dvb-frontends/{mn88472_c.c => mn88472.c} | 34 +++++++++---------- drivers/media/dvb-frontends/mn88472.h | 10 +++--- drivers/media/dvb-frontends/mn88472_priv.h | 2 +- 4 files changed, 23 insertions(+), 24 deletions(-) rename drivers/media/dvb-frontends/{mn88472_c.c => mn88472.c} (90%) diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 27d82b6a7ff3..b82225f6781c 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -15,7 +15,6 @@ stv0900-objs := stv0900_core.o stv0900_sw.o drxd-objs := drxd_firm.o drxd_hard.o cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o drxk-objs := drxk_hard.o -mn88472-objs := mn88472_c.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o diff --git a/drivers/media/dvb-frontends/mn88472_c.c b/drivers/media/dvb-frontends/mn88472.c similarity index 90% rename from drivers/media/dvb-frontends/mn88472_c.c rename to drivers/media/dvb-frontends/mn88472.c index b5bd326d9e66..a3c4ae15520e 100644 --- a/drivers/media/dvb-frontends/mn88472_c.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -16,7 +16,7 @@ #include "mn88472_priv.h" -static struct dvb_frontend_ops mn88472_ops_c; +static struct dvb_frontend_ops mn88472_ops; /* write multiple registers */ static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len) @@ -112,7 +112,7 @@ static int mn88472_get_tune_settings(struct dvb_frontend *fe, return 0; } -static int mn88472_set_frontend_c(struct dvb_frontend *fe) +static int mn88472_set_frontend(struct dvb_frontend *fe) { struct mn88472_state *s = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -216,7 +216,7 @@ static int mn88472_set_frontend_c(struct dvb_frontend *fe) return ret; } -static int mn88472_read_status_c(struct dvb_frontend *fe, fe_status_t *status) +static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct mn88472_state *s = fe->demodulator_priv; int ret; @@ -243,7 +243,7 @@ static int mn88472_read_status_c(struct dvb_frontend *fe, fe_status_t *status) return ret; } -static int mn88472_init_c(struct dvb_frontend *fe) +static int mn88472_init(struct dvb_frontend *fe) { struct mn88472_state *s = fe->demodulator_priv; int ret, len, remaining; @@ -313,7 +313,7 @@ static int mn88472_init_c(struct dvb_frontend *fe) return ret; } -static int mn88472_sleep_c(struct dvb_frontend *fe) +static int mn88472_sleep(struct dvb_frontend *fe) { struct mn88472_state *s = fe->demodulator_priv; int ret; @@ -336,13 +336,13 @@ static int mn88472_sleep_c(struct dvb_frontend *fe) return ret; } -static void mn88472_release_c(struct dvb_frontend *fe) +static void mn88472_release(struct dvb_frontend *fe) { struct mn88472_state *s = fe->demodulator_priv; kfree(s); } -struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg, +struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg, struct i2c_adapter *i2c) { int ret; @@ -367,7 +367,7 @@ struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg, goto err; /* create dvb_frontend */ - memcpy(&s->fe.ops, &mn88472_ops_c, sizeof(struct dvb_frontend_ops)); + memcpy(&s->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops)); s->fe.demodulator_priv = s; return &s->fe; @@ -376,9 +376,9 @@ struct dvb_frontend *mn88472_attach_c(const struct mn88472_c_config *cfg, kfree(s); return NULL; } -EXPORT_SYMBOL(mn88472_attach_c); +EXPORT_SYMBOL(mn88472_attach); -static struct dvb_frontend_ops mn88472_ops_c = { +static struct dvb_frontend_ops mn88472_ops = { .delsys = {SYS_DVBC_ANNEX_A}, .info = { .name = "Panasonic MN88472", @@ -403,18 +403,18 @@ static struct dvb_frontend_ops mn88472_ops_c = { FE_CAN_MULTISTREAM }, - .release = mn88472_release_c, + .release = mn88472_release, .get_tune_settings = mn88472_get_tune_settings, - .init = mn88472_init_c, - .sleep = mn88472_sleep_c, + .init = mn88472_init, + .sleep = mn88472_sleep, - .set_frontend = mn88472_set_frontend_c, -/* .get_frontend = mn88472_get_frontend_c, */ + .set_frontend = mn88472_set_frontend, +/* .get_frontend = mn88472_get_frontend, */ - .read_status = mn88472_read_status_c, -/* .read_snr = mn88472_read_snr_c, */ + .read_status = mn88472_read_status, +/* .read_snr = mn88472_read_snr, */ }; MODULE_AUTHOR("Antti Palosaari "); diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h index c817bfba9681..5ce6ac1a7f06 100644 --- a/drivers/media/dvb-frontends/mn88472.h +++ b/drivers/media/dvb-frontends/mn88472.h @@ -19,7 +19,7 @@ #include -struct mn88472_c_config { +struct mn88472_config { /* * max bytes I2C client could write * Value must be set. @@ -28,13 +28,13 @@ struct mn88472_c_config { }; #if IS_ENABLED(CONFIG_DVB_MN88472) -extern struct dvb_frontend *mn88472_attach_c( - const struct mn88472_c_config *cfg, +extern struct dvb_frontend *mn88472_attach( + const struct mn88472_config *cfg, struct i2c_adapter *i2c ); #else -static inline struct dvb_frontend *mn88472_attach_c( - const struct mn88472_c_config *cfg, +static inline struct dvb_frontend *mn88472_attach( + const struct mn88472_config *cfg, struct i2c_adapter *i2c ) { diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h index ecade84a0cf4..1aaa25fade4c 100644 --- a/drivers/media/dvb-frontends/mn88472_priv.h +++ b/drivers/media/dvb-frontends/mn88472_priv.h @@ -27,7 +27,7 @@ struct mn88472_state { struct i2c_adapter *i2c; - const struct mn88472_c_config *cfg; + const struct mn88472_config *cfg; struct dvb_frontend fe; fe_delivery_system_t delivery_system; bool warm; /* FW running */ -- GitLab From 0186e434a7f8c9520570a75775d8096ff3ccb454 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 25 Oct 2014 22:58:18 -0300 Subject: [PATCH 4832/9457] [media] mn88472: rename state to dev Rename state to dev. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.c | 141 +++++++++++---------- drivers/media/dvb-frontends/mn88472_priv.h | 2 +- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index a3c4ae15520e..1d72e0240ca7 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -19,7 +19,7 @@ static struct dvb_frontend_ops mn88472_ops; /* write multiple registers */ -static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int len) +static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int len) { #define MAX_WR_LEN 21 #define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) @@ -40,11 +40,11 @@ static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int le buf[0] = (reg >> 0) & 0xff; memcpy(&buf[1], val, len); - ret = i2c_transfer(s->i2c, msg, 1); + ret = i2c_transfer(dev->i2c, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&s->i2c->dev, + dev_warn(&dev->i2c->dev, "%s: i2c wr failed=%d reg=%02x len=%d\n", KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; @@ -54,7 +54,7 @@ static int mn88472_wregs(struct mn88472_state *s, u16 reg, const u8 *val, int le } /* read multiple registers */ -static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len) +static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len) { #define MAX_RD_LEN 2 #define MAX_RD_XFER_LEN (MAX_RD_LEN) @@ -79,12 +79,12 @@ static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len) buf[0] = (reg >> 0) & 0xff; - ret = i2c_transfer(s->i2c, msg, 2); + ret = i2c_transfer(dev->i2c, msg, 2); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&s->i2c->dev, + dev_warn(&dev->i2c->dev, "%s: i2c rd failed=%d reg=%02x len=%d\n", KBUILD_MODNAME, ret, reg, len); ret = -EREMOTEIO; @@ -94,15 +94,15 @@ static int mn88472_rregs(struct mn88472_state *s, u16 reg, u8 *val, int len) } /* write single register */ -static int mn88472_wreg(struct mn88472_state *s, u16 reg, u8 val) +static int mn88472_wreg(struct mn88472_dev *dev, u16 reg, u8 val) { - return mn88472_wregs(s, reg, &val, 1); + return mn88472_wregs(dev, reg, &val, 1); } /* read single register */ -static int mn88472_rreg(struct mn88472_state *s, u16 reg, u8 *val) +static int mn88472_rreg(struct mn88472_dev *dev, u16 reg, u8 *val) { - return mn88472_rregs(s, reg, val, 1); + return mn88472_rregs(dev, reg, val, 1); } static int mn88472_get_tune_settings(struct dvb_frontend *fe, @@ -114,16 +114,16 @@ static int mn88472_get_tune_settings(struct dvb_frontend *fe, static int mn88472_set_frontend(struct dvb_frontend *fe) { - struct mn88472_state *s = fe->demodulator_priv; + struct mn88472_dev *dev = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; u32 if_frequency = 0; - dev_dbg(&s->i2c->dev, + dev_dbg(&dev->i2c->dev, "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", __func__, c->delivery_system, c->modulation, c->frequency, c->symbol_rate, c->inversion); - if (!s->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } @@ -140,96 +140,96 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - dev_dbg(&s->i2c->dev, "%s: get_if_frequency=%d\n", + dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n", __func__, if_frequency); } if (if_frequency != 5070000) { - dev_err(&s->i2c->dev, "%s: IF frequency %d not supported\n", + dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n", KBUILD_MODNAME, if_frequency); ret = -EINVAL; goto err; } - ret = mn88472_wregs(s, 0x1c08, "\x1d", 1); + ret = mn88472_wregs(dev, 0x1c08, "\x1d", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18d9, "\xe3", 1); + ret = mn88472_wregs(dev, 0x18d9, "\xe3", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x1c83, "\x01", 1); + ret = mn88472_wregs(dev, 0x1c83, "\x01", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x1c00, "\x66\x00\x01\x04\x00", 5); + ret = mn88472_wregs(dev, 0x1c00, "\x66\x00\x01\x04\x00", 5); if (ret) goto err; - ret = mn88472_wregs(s, 0x1c10, + ret = mn88472_wregs(dev, 0x1c10, "\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10); if (ret) goto err; - ret = mn88472_wregs(s, 0x1846, "\x00", 1); + ret = mn88472_wregs(dev, 0x1846, "\x00", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18ae, "\x00", 1); + ret = mn88472_wregs(dev, 0x18ae, "\x00", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18b0, "\x0b", 1); + ret = mn88472_wregs(dev, 0x18b0, "\x0b", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18b4, "\x00", 1); + ret = mn88472_wregs(dev, 0x18b4, "\x00", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18cd, "\x17", 1); + ret = mn88472_wregs(dev, 0x18cd, "\x17", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18d4, "\x09", 1); + ret = mn88472_wregs(dev, 0x18d4, "\x09", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x18d6, "\x48", 1); + ret = mn88472_wregs(dev, 0x18d6, "\x48", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x1a00, "\xb0", 1); + ret = mn88472_wregs(dev, 0x1a00, "\xb0", 1); if (ret) goto err; - ret = mn88472_wregs(s, 0x1cf8, "\x9f", 1); + ret = mn88472_wregs(dev, 0x1cf8, "\x9f", 1); if (ret) goto err; - s->delivery_system = c->delivery_system; + dev->delivery_system = c->delivery_system; return 0; err: - dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; } static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) { - struct mn88472_state *s = fe->demodulator_priv; + struct mn88472_dev *dev = fe->demodulator_priv; int ret; u8 u8tmp; *status = 0; - if (!s->warm) { + if (!dev->warm) { ret = -EAGAIN; goto err; } - ret = mn88472_rreg(s, 0x1a84, &u8tmp); + ret = mn88472_rreg(dev, 0x1a84, &u8tmp); if (ret) goto err; @@ -239,62 +239,62 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; err: - dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; } static int mn88472_init(struct dvb_frontend *fe) { - struct mn88472_state *s = fe->demodulator_priv; + struct mn88472_dev *dev = fe->demodulator_priv; int ret, len, remaining; const struct firmware *fw = NULL; u8 *fw_file = MN88472_FIRMWARE; - dev_dbg(&s->i2c->dev, "%s:\n", __func__); + dev_dbg(&dev->i2c->dev, "%s:\n", __func__); /* set cold state by default */ - s->warm = false; + dev->warm = false; /* power on */ - ret = mn88472_wreg(s, 0x1c05, 0x00); + ret = mn88472_wreg(dev, 0x1c05, 0x00); if (ret) goto err; - ret = mn88472_wregs(s, 0x1c0b, "\x00\x00", 2); + ret = mn88472_wregs(dev, 0x1c0b, "\x00\x00", 2); if (ret) goto err; /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, s->i2c->dev.parent); + ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent); if (ret) { - dev_err(&s->i2c->dev, "%s: firmare file '%s' not found\n", + dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n", KBUILD_MODNAME, fw_file); goto err; } - dev_info(&s->i2c->dev, "%s: downloading firmware from file '%s'\n", + dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n", KBUILD_MODNAME, fw_file); - ret = mn88472_wreg(s, 0x18f5, 0x03); + ret = mn88472_wreg(dev, 0x18f5, 0x03); if (ret) goto err; for (remaining = fw->size; remaining > 0; - remaining -= (s->cfg->i2c_wr_max - 1)) { + remaining -= (dev->cfg->i2c_wr_max - 1)) { len = remaining; - if (len > (s->cfg->i2c_wr_max - 1)) - len = (s->cfg->i2c_wr_max - 1); + if (len > (dev->cfg->i2c_wr_max - 1)) + len = (dev->cfg->i2c_wr_max - 1); - ret = mn88472_wregs(s, 0x18f6, + ret = mn88472_wregs(dev, 0x18f6, &fw->data[fw->size - remaining], len); if (ret) { - dev_err(&s->i2c->dev, + dev_err(&dev->i2c->dev, "%s: firmware download failed=%d\n", KBUILD_MODNAME, ret); goto err; } } - ret = mn88472_wreg(s, 0x18f5, 0x00); + ret = mn88472_wreg(dev, 0x18f5, 0x00); if (ret) goto err; @@ -302,78 +302,79 @@ static int mn88472_init(struct dvb_frontend *fe) fw = NULL; /* warm state */ - s->warm = true; + dev->warm = true; return 0; err: if (fw) release_firmware(fw); - dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; } static int mn88472_sleep(struct dvb_frontend *fe) { - struct mn88472_state *s = fe->demodulator_priv; + struct mn88472_dev *dev = fe->demodulator_priv; int ret; - dev_dbg(&s->i2c->dev, "%s:\n", __func__); + dev_dbg(&dev->i2c->dev, "%s:\n", __func__); /* power off */ - ret = mn88472_wreg(s, 0x1c0b, 0x30); + ret = mn88472_wreg(dev, 0x1c0b, 0x30); if (ret) goto err; - ret = mn88472_wreg(s, 0x1c05, 0x3e); + ret = mn88472_wreg(dev, 0x1c05, 0x3e); if (ret) goto err; - s->delivery_system = SYS_UNDEFINED; + dev->delivery_system = SYS_UNDEFINED; return 0; err: - dev_dbg(&s->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; } static void mn88472_release(struct dvb_frontend *fe) { - struct mn88472_state *s = fe->demodulator_priv; - kfree(s); + struct mn88472_dev *dev = fe->demodulator_priv; + + kfree(dev); } struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg, struct i2c_adapter *i2c) { int ret; - struct mn88472_state *s; + struct mn88472_dev *dev; u8 u8tmp; dev_dbg(&i2c->dev, "%s:\n", __func__); /* allocate memory for the internal state */ - s = kzalloc(sizeof(struct mn88472_state), GFP_KERNEL); - if (!s) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { ret = -ENOMEM; dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); goto err; } - s->cfg = cfg; - s->i2c = i2c; + dev->cfg = cfg; + dev->i2c = i2c; /* check demod responds to I2C */ - ret = mn88472_rreg(s, 0x1c00, &u8tmp); + ret = mn88472_rreg(dev, 0x1c00, &u8tmp); if (ret) goto err; /* create dvb_frontend */ - memcpy(&s->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; + memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops)); + dev->fe.demodulator_priv = dev; - return &s->fe; + return &dev->fe; err: dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); - kfree(s); + kfree(dev); return NULL; } EXPORT_SYMBOL(mn88472_attach); diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h index 1aaa25fade4c..be31adb95ba2 100644 --- a/drivers/media/dvb-frontends/mn88472_priv.h +++ b/drivers/media/dvb-frontends/mn88472_priv.h @@ -25,7 +25,7 @@ #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw" -struct mn88472_state { +struct mn88472_dev { struct i2c_adapter *i2c; const struct mn88472_config *cfg; struct dvb_frontend fe; -- GitLab From 528af1952ec04c86d554992021f62cd76fc8b19c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 26 Oct 2014 23:01:07 -0300 Subject: [PATCH 4833/9457] [media] mn88472: convert driver to I2C client It uses I2C bus so better to implement it as a standard I2C driver model. It was using proprietary DVB binding. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.c | 241 +++++++++++++-------- drivers/media/dvb-frontends/mn88472.h | 30 +-- drivers/media/dvb-frontends/mn88472_priv.h | 6 +- 3 files changed, 165 insertions(+), 112 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index 1d72e0240ca7..a65741a58027 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -40,13 +40,13 @@ static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int le buf[0] = (reg >> 0) & 0xff; memcpy(&buf[1], val, len); - ret = i2c_transfer(dev->i2c, msg, 1); + ret = i2c_transfer(dev->client[0]->adapter, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&dev->i2c->dev, - "%s: i2c wr failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&dev->client[0]->dev, + "i2c wr failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -79,14 +79,14 @@ static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len) buf[0] = (reg >> 0) & 0xff; - ret = i2c_transfer(dev->i2c, msg, 2); + ret = i2c_transfer(dev->client[0]->adapter, msg, 2); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&dev->i2c->dev, - "%s: i2c rd failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&dev->client[0]->dev, + "i2c rd failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -114,13 +114,15 @@ static int mn88472_get_tune_settings(struct dvb_frontend *fe, static int mn88472_set_frontend(struct dvb_frontend *fe) { - struct mn88472_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88472_dev *dev = i2c_get_clientdata(client); struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; u32 if_frequency = 0; - dev_dbg(&dev->i2c->dev, - "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", - __func__, c->delivery_system, c->modulation, + + dev_dbg(&client->dev, + "delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", + c->delivery_system, c->modulation, c->frequency, c->symbol_rate, c->inversion); if (!dev->warm) { @@ -140,13 +142,12 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n", - __func__, if_frequency); + dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency); } if (if_frequency != 5070000) { - dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n", - KBUILD_MODNAME, if_frequency); + dev_err(&client->dev, "IF frequency %d not supported\n", + if_frequency); ret = -EINVAL; goto err; } @@ -212,13 +213,14 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) { - struct mn88472_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88472_dev *dev = i2c_get_clientdata(client); int ret; u8 u8tmp; @@ -239,17 +241,19 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88472_init(struct dvb_frontend *fe) { - struct mn88472_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88472_dev *dev = i2c_get_clientdata(client); int ret, len, remaining; const struct firmware *fw = NULL; u8 *fw_file = MN88472_FIRMWARE; - dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + + dev_dbg(&client->dev, "\n"); /* set cold state by default */ dev->warm = false; @@ -264,32 +268,31 @@ static int mn88472_init(struct dvb_frontend *fe) goto err; /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent); + ret = request_firmware(&fw, fw_file, &client->dev); if (ret) { - dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n", - KBUILD_MODNAME, fw_file); + dev_err(&client->dev, "firmare file '%s' not found\n", + fw_file); goto err; } - dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n", - KBUILD_MODNAME, fw_file); + dev_info(&client->dev, "downloading firmware from file '%s'\n", + fw_file); ret = mn88472_wreg(dev, 0x18f5, 0x03); if (ret) goto err; for (remaining = fw->size; remaining > 0; - remaining -= (dev->cfg->i2c_wr_max - 1)) { + remaining -= (dev->i2c_wr_max - 1)) { len = remaining; - if (len > (dev->cfg->i2c_wr_max - 1)) - len = (dev->cfg->i2c_wr_max - 1); + if (len > (dev->i2c_wr_max - 1)) + len = (dev->i2c_wr_max - 1); ret = mn88472_wregs(dev, 0x18f6, &fw->data[fw->size - remaining], len); if (ret) { - dev_err(&dev->i2c->dev, - "%s: firmware download failed=%d\n", - KBUILD_MODNAME, ret); + dev_err(&client->dev, + "firmware download failed=%d\n", ret); goto err; } } @@ -309,15 +312,17 @@ static int mn88472_init(struct dvb_frontend *fe) if (fw) release_firmware(fw); - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88472_sleep(struct dvb_frontend *fe) { - struct mn88472_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88472_dev *dev = i2c_get_clientdata(client); int ret; - dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + + dev_dbg(&client->dev, "\n"); /* power off */ ret = mn88472_wreg(dev, 0x1c0b, 0x30); @@ -332,91 +337,149 @@ static int mn88472_sleep(struct dvb_frontend *fe) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -static void mn88472_release(struct dvb_frontend *fe) -{ - struct mn88472_dev *dev = fe->demodulator_priv; +static struct dvb_frontend_ops mn88472_ops = { + .delsys = {SYS_DVBC_ANNEX_A}, + .info = { + .name = "Panasonic MN88472", + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM + }, - kfree(dev); -} + .get_tune_settings = mn88472_get_tune_settings, + + .init = mn88472_init, + .sleep = mn88472_sleep, + + .set_frontend = mn88472_set_frontend, + + .read_status = mn88472_read_status, +}; -struct dvb_frontend *mn88472_attach(const struct mn88472_config *cfg, - struct i2c_adapter *i2c) +static int mn88472_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int ret; + struct mn88472_config *config = client->dev.platform_data; struct mn88472_dev *dev; + int ret; u8 u8tmp; - dev_dbg(&i2c->dev, "%s:\n", __func__); - /* allocate memory for the internal state */ + dev_dbg(&client->dev, "\n"); + + /* Caller really need to provide pointer for frontend we create. */ + if (config->fe == NULL) { + dev_err(&client->dev, "frontend pointer not defined\n"); + ret = -EINVAL; + goto err; + } + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { ret = -ENOMEM; - dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); goto err; } - dev->cfg = cfg; - dev->i2c = i2c; + dev->client[0] = client; + dev->i2c_wr_max = config->i2c_wr_max; - /* check demod responds to I2C */ + /* check demod answers to I2C */ ret = mn88472_rreg(dev, 0x1c00, &u8tmp); if (ret) - goto err; + goto err_kfree; + + /* + * Chip has three I2C addresses for different register pages. Used + * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients, + * 0x1a and 0x1c, in order to get own I2C client for each register page. + */ + dev->client[1] = i2c_new_dummy(client->adapter, 0x1a); + if (dev->client[1] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "I2C registration failed\n"); + if (ret) + goto err_kfree; + } + i2c_set_clientdata(dev->client[1], dev); + + dev->client[2] = i2c_new_dummy(client->adapter, 0x1c); + if (dev->client[2] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "2nd I2C registration failed\n"); + if (ret) + goto err_client_1_i2c_unregister_device; + } + i2c_set_clientdata(dev->client[2], dev); /* create dvb_frontend */ memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops)); - dev->fe.demodulator_priv = dev; + dev->fe.demodulator_priv = client; + *config->fe = &dev->fe; + i2c_set_clientdata(client, dev); - return &dev->fe; -err: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_info(&client->dev, "Panasonic MN88472 successfully attached\n"); + return 0; + +err_client_1_i2c_unregister_device: + i2c_unregister_device(dev->client[1]); +err_kfree: kfree(dev); - return NULL; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; } -EXPORT_SYMBOL(mn88472_attach); -static struct dvb_frontend_ops mn88472_ops = { - .delsys = {SYS_DVBC_ANNEX_A}, - .info = { - .name = "Panasonic MN88472", - .caps = FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_MUTE_TS | - FE_CAN_2G_MODULATION | - FE_CAN_MULTISTREAM - }, +static int mn88472_remove(struct i2c_client *client) +{ + struct mn88472_dev *dev = i2c_get_clientdata(client); - .release = mn88472_release, + dev_dbg(&client->dev, "\n"); - .get_tune_settings = mn88472_get_tune_settings, + i2c_unregister_device(dev->client[2]); - .init = mn88472_init, - .sleep = mn88472_sleep, + i2c_unregister_device(dev->client[1]); - .set_frontend = mn88472_set_frontend, -/* .get_frontend = mn88472_get_frontend, */ + kfree(dev); - .read_status = mn88472_read_status, -/* .read_snr = mn88472_read_snr, */ + return 0; +} + +static const struct i2c_device_id mn88472_id_table[] = { + {"mn88472", 0}, + {} }; +MODULE_DEVICE_TABLE(i2c, mn88472_id_table); + +static struct i2c_driver mn88472_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mn88472", + }, + .probe = mn88472_probe, + .remove = mn88472_remove, + .id_table = mn88472_id_table, +}; + +module_i2c_driver(mn88472_driver); MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver"); diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h index 5ce6ac1a7f06..da4558bce60f 100644 --- a/drivers/media/dvb-frontends/mn88472.h +++ b/drivers/media/dvb-frontends/mn88472.h @@ -21,26 +21,18 @@ struct mn88472_config { /* - * max bytes I2C client could write - * Value must be set. + * Max num of bytes given I2C adapter could write at once. + * Default: none */ - int i2c_wr_max; -}; + u16 i2c_wr_max; -#if IS_ENABLED(CONFIG_DVB_MN88472) -extern struct dvb_frontend *mn88472_attach( - const struct mn88472_config *cfg, - struct i2c_adapter *i2c -); -#else -static inline struct dvb_frontend *mn88472_attach( - const struct mn88472_config *cfg, - struct i2c_adapter *i2c -) -{ - dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif + + /* Everything after that is returned by the driver. */ + + /* + * DVB frontend. + */ + struct dvb_frontend **fe; +}; #endif diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h index be31adb95ba2..0fde80cafa66 100644 --- a/drivers/media/dvb-frontends/mn88472_priv.h +++ b/drivers/media/dvb-frontends/mn88472_priv.h @@ -19,16 +19,14 @@ #include "dvb_frontend.h" #include "mn88472.h" -#include "dvb_math.h" #include -#include #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw" struct mn88472_dev { - struct i2c_adapter *i2c; - const struct mn88472_config *cfg; + struct i2c_client *client[3]; struct dvb_frontend fe; + u16 i2c_wr_max; fe_delivery_system_t delivery_system; bool warm; /* FW running */ }; -- GitLab From c1011fb8188819d554dcb01678b4c002f578bb7f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 26 Oct 2014 23:26:04 -0300 Subject: [PATCH 4834/9457] [media] mn88472: Convert driver to I2C RegMap API Convert driver to I2C RegMap API. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 1 + drivers/media/dvb-frontends/mn88472.c | 180 +++++++-------------- drivers/media/dvb-frontends/mn88472_priv.h | 2 + 3 files changed, 64 insertions(+), 119 deletions(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 02bada4d7c61..207843e2899c 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -444,6 +444,7 @@ config DVB_CXD2820R config DVB_MN88472 tristate "Panasonic MN88472" depends on DVB_CORE && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index a65741a58027..c68015472757 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -16,95 +16,6 @@ #include "mn88472_priv.h" -static struct dvb_frontend_ops mn88472_ops; - -/* write multiple registers */ -static int mn88472_wregs(struct mn88472_dev *dev, u16 reg, const u8 *val, int len) -{ -#define MAX_WR_LEN 21 -#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) - int ret; - u8 buf[MAX_WR_XFER_LEN]; - struct i2c_msg msg[1] = { - { - .addr = (reg >> 8) & 0xff, - .flags = 0, - .len = 1 + len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_WR_LEN)) - return -EINVAL; - - buf[0] = (reg >> 0) & 0xff; - memcpy(&buf[1], val, len); - - ret = i2c_transfer(dev->client[0]->adapter, msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&dev->client[0]->dev, - "i2c wr failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* read multiple registers */ -static int mn88472_rregs(struct mn88472_dev *dev, u16 reg, u8 *val, int len) -{ -#define MAX_RD_LEN 2 -#define MAX_RD_XFER_LEN (MAX_RD_LEN) - int ret; - u8 buf[MAX_RD_XFER_LEN]; - struct i2c_msg msg[2] = { - { - .addr = (reg >> 8) & 0xff, - .flags = 0, - .len = 1, - .buf = buf, - }, { - .addr = (reg >> 8) & 0xff, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_RD_LEN)) - return -EINVAL; - - buf[0] = (reg >> 0) & 0xff; - - ret = i2c_transfer(dev->client[0]->adapter, msg, 2); - if (ret == 2) { - memcpy(val, buf, len); - ret = 0; - } else { - dev_warn(&dev->client[0]->dev, - "i2c rd failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* write single register */ -static int mn88472_wreg(struct mn88472_dev *dev, u16 reg, u8 val) -{ - return mn88472_wregs(dev, reg, &val, 1); -} - -/* read single register */ -static int mn88472_rreg(struct mn88472_dev *dev, u16 reg, u8 *val) -{ - return mn88472_rregs(dev, reg, val, 1); -} - static int mn88472_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) { @@ -152,60 +63,61 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) goto err; } - ret = mn88472_wregs(dev, 0x1c08, "\x1d", 1); + ret = regmap_write(dev->regmap[2], 0x08, 0x1d); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18d9, "\xe3", 1); + ret = regmap_write(dev->regmap[0], 0xd9, 0xe3); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1c83, "\x01", 1); + ret = regmap_write(dev->regmap[2], 0x83, 0x01); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1c00, "\x66\x00\x01\x04\x00", 5); + ret = regmap_bulk_write(dev->regmap[2], 0x00, + "\x66\x00\x01\x04\x00", 5); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1c10, + ret = regmap_bulk_write(dev->regmap[2], 0x10, "\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1846, "\x00", 1); + ret = regmap_write(dev->regmap[0], 0x46, 0x00); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18ae, "\x00", 1); + ret = regmap_write(dev->regmap[0], 0xae, 0x00); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18b0, "\x0b", 1); + ret = regmap_write(dev->regmap[0], 0xb0, 0x0b); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18b4, "\x00", 1); + ret = regmap_write(dev->regmap[0], 0xb4, 0x00); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18cd, "\x17", 1); + ret = regmap_write(dev->regmap[0], 0xcd, 0x17); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18d4, "\x09", 1); + ret = regmap_write(dev->regmap[0], 0xd4, 0x09); if (ret) goto err; - ret = mn88472_wregs(dev, 0x18d6, "\x48", 1); + ret = regmap_write(dev->regmap[0], 0xd6, 0x48); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1a00, "\xb0", 1); + ret = regmap_write(dev->regmap[1], 0x00, 0xb0); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1cf8, "\x9f", 1); + ret = regmap_write(dev->regmap[2], 0xf8, 0x9f); if (ret) goto err; @@ -222,7 +134,7 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) struct i2c_client *client = fe->demodulator_priv; struct mn88472_dev *dev = i2c_get_clientdata(client); int ret; - u8 u8tmp; + unsigned int utmp; *status = 0; @@ -231,11 +143,11 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) goto err; } - ret = mn88472_rreg(dev, 0x1a84, &u8tmp); + ret = regmap_read(dev->regmap[1], 0x84, &utmp); if (ret) goto err; - if (u8tmp == 0x08) + if (utmp == 0x08) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; @@ -259,11 +171,11 @@ static int mn88472_init(struct dvb_frontend *fe) dev->warm = false; /* power on */ - ret = mn88472_wreg(dev, 0x1c05, 0x00); + ret = regmap_write(dev->regmap[2], 0x05, 0x00); if (ret) goto err; - ret = mn88472_wregs(dev, 0x1c0b, "\x00\x00", 2); + ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2); if (ret) goto err; @@ -278,7 +190,7 @@ static int mn88472_init(struct dvb_frontend *fe) dev_info(&client->dev, "downloading firmware from file '%s'\n", fw_file); - ret = mn88472_wreg(dev, 0x18f5, 0x03); + ret = regmap_write(dev->regmap[0], 0xf5, 0x03); if (ret) goto err; @@ -288,7 +200,7 @@ static int mn88472_init(struct dvb_frontend *fe) if (len > (dev->i2c_wr_max - 1)) len = (dev->i2c_wr_max - 1); - ret = mn88472_wregs(dev, 0x18f6, + ret = regmap_bulk_write(dev->regmap[0], 0xf6, &fw->data[fw->size - remaining], len); if (ret) { dev_err(&client->dev, @@ -297,7 +209,7 @@ static int mn88472_init(struct dvb_frontend *fe) } } - ret = mn88472_wreg(dev, 0x18f5, 0x00); + ret = regmap_write(dev->regmap[0], 0xf5, 0x00); if (ret) goto err; @@ -325,11 +237,12 @@ static int mn88472_sleep(struct dvb_frontend *fe) dev_dbg(&client->dev, "\n"); /* power off */ - ret = mn88472_wreg(dev, 0x1c0b, 0x30); + ret = regmap_write(dev->regmap[2], 0x0b, 0x30); + if (ret) goto err; - ret = mn88472_wreg(dev, 0x1c05, 0x3e); + ret = regmap_write(dev->regmap[2], 0x05, 0x3e); if (ret) goto err; @@ -382,7 +295,11 @@ static int mn88472_probe(struct i2c_client *client, struct mn88472_config *config = client->dev.platform_data; struct mn88472_dev *dev; int ret; - u8 u8tmp; + unsigned int utmp; + static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; dev_dbg(&client->dev, "\n"); @@ -399,13 +316,18 @@ static int mn88472_probe(struct i2c_client *client, goto err; } - dev->client[0] = client; dev->i2c_wr_max = config->i2c_wr_max; + dev->client[0] = client; + dev->regmap[0] = regmap_init_i2c(dev->client[0], ®map_config); + if (IS_ERR(dev->regmap[0])) { + ret = PTR_ERR(dev->regmap[0]); + goto err_kfree; + } /* check demod answers to I2C */ - ret = mn88472_rreg(dev, 0x1c00, &u8tmp); + ret = regmap_read(dev->regmap[0], 0x00, &utmp); if (ret) - goto err_kfree; + goto err_regmap_0_regmap_exit; /* * Chip has three I2C addresses for different register pages. Used @@ -417,7 +339,12 @@ static int mn88472_probe(struct i2c_client *client, ret = -ENODEV; dev_err(&client->dev, "I2C registration failed\n"); if (ret) - goto err_kfree; + goto err_regmap_0_regmap_exit; + } + dev->regmap[1] = regmap_init_i2c(dev->client[1], ®map_config); + if (IS_ERR(dev->regmap[1])) { + ret = PTR_ERR(dev->regmap[1]); + goto err_client_1_i2c_unregister_device; } i2c_set_clientdata(dev->client[1], dev); @@ -426,7 +353,12 @@ static int mn88472_probe(struct i2c_client *client, ret = -ENODEV; dev_err(&client->dev, "2nd I2C registration failed\n"); if (ret) - goto err_client_1_i2c_unregister_device; + goto err_regmap_1_regmap_exit; + } + dev->regmap[2] = regmap_init_i2c(dev->client[2], ®map_config); + if (IS_ERR(dev->regmap[2])) { + ret = PTR_ERR(dev->regmap[2]); + goto err_client_2_i2c_unregister_device; } i2c_set_clientdata(dev->client[2], dev); @@ -439,8 +371,14 @@ static int mn88472_probe(struct i2c_client *client, dev_info(&client->dev, "Panasonic MN88472 successfully attached\n"); return 0; +err_client_2_i2c_unregister_device: + i2c_unregister_device(dev->client[2]); +err_regmap_1_regmap_exit: + regmap_exit(dev->regmap[1]); err_client_1_i2c_unregister_device: i2c_unregister_device(dev->client[1]); +err_regmap_0_regmap_exit: + regmap_exit(dev->regmap[0]); err_kfree: kfree(dev); err: @@ -454,10 +392,14 @@ static int mn88472_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); + regmap_exit(dev->regmap[2]); i2c_unregister_device(dev->client[2]); + regmap_exit(dev->regmap[1]); i2c_unregister_device(dev->client[1]); + regmap_exit(dev->regmap[0]); + kfree(dev); return 0; diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h index 0fde80cafa66..1095949f040d 100644 --- a/drivers/media/dvb-frontends/mn88472_priv.h +++ b/drivers/media/dvb-frontends/mn88472_priv.h @@ -20,11 +20,13 @@ #include "dvb_frontend.h" #include "mn88472.h" #include +#include #define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw" struct mn88472_dev { struct i2c_client *client[3]; + struct regmap *regmap[3]; struct dvb_frontend fe; u16 i2c_wr_max; fe_delivery_system_t delivery_system; -- GitLab From 5048907076ea8b31aa15a3ec7a6ce9c341eb77ce Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 27 Oct 2014 20:39:40 -0300 Subject: [PATCH 4835/9457] [media] mn88472: implement DVB-T and DVB-T2 Implement initial support for DVB-T and DVB-T2 modes. Now driver has basic support for all the modes, DVB-C/T/T2. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.c | 176 ++++++++++++++++++++------ 1 file changed, 135 insertions(+), 41 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index c68015472757..52de8f85d36c 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -28,8 +28,9 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) struct i2c_client *client = fe->demodulator_priv; struct mn88472_dev *dev = i2c_get_clientdata(client); struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; + int ret, i; u32 if_frequency = 0; + u8 delivery_system_val, if_val[3], bw_val[7], bw_val2; dev_dbg(&client->dev, "delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", @@ -41,6 +42,55 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) goto err; } + switch (c->delivery_system) { + case SYS_DVBT: + delivery_system_val = 0x02; + break; + case SYS_DVBT2: + delivery_system_val = 0x03; + break; + case SYS_DVBC_ANNEX_A: + delivery_system_val = 0x04; + break; + default: + ret = -EINVAL; + goto err; + } + + switch (c->delivery_system) { + case SYS_DVBT: + case SYS_DVBT2: + if (c->bandwidth_hz <= 6000000) { + /* IF 3570000 Hz, BW 6000000 Hz */ + memcpy(if_val, "\x2c\x94\xdb", 3); + memcpy(bw_val, "\xbf\x55\x55\x15\x6b\x15\x6b", 7); + bw_val2 = 0x02; + } else if (c->bandwidth_hz <= 7000000) { + /* IF 4570000 Hz, BW 7000000 Hz */ + memcpy(if_val, "\x39\x11\xbc", 3); + memcpy(bw_val, "\xa4\x00\x00\x0f\x2c\x0f\x2c", 7); + bw_val2 = 0x01; + } else if (c->bandwidth_hz <= 8000000) { + /* IF 4570000 Hz, BW 8000000 Hz */ + memcpy(if_val, "\x39\x11\xbc", 3); + memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7); + bw_val2 = 0x00; + } else { + ret = -EINVAL; + goto err; + } + break; + case SYS_DVBC_ANNEX_A: + /* IF 5070000 Hz, BW 8000000 Hz */ + memcpy(if_val, "\x3f\x50\x2c", 3); + memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7); + bw_val2 = 0x00; + break; + default: + ret = -EINVAL; + goto err; + } + /* program tuner */ if (fe->ops.tuner_ops.set_params) { ret = fe->ops.tuner_ops.set_params(fe); @@ -56,67 +106,98 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency); } - if (if_frequency != 5070000) { + switch (if_frequency) { + case 3570000: + case 4570000: + case 5070000: + break; + default: dev_err(&client->dev, "IF frequency %d not supported\n", if_frequency); ret = -EINVAL; goto err; } - ret = regmap_write(dev->regmap[2], 0x08, 0x1d); - if (ret) - goto err; - - ret = regmap_write(dev->regmap[0], 0xd9, 0xe3); - if (ret) - goto err; - - ret = regmap_write(dev->regmap[2], 0x83, 0x01); + ret = regmap_write(dev->regmap[2], 0xfb, 0x13); + ret = regmap_write(dev->regmap[2], 0xef, 0x13); + ret = regmap_write(dev->regmap[2], 0xf9, 0x13); if (ret) goto err; - ret = regmap_bulk_write(dev->regmap[2], 0x00, - "\x66\x00\x01\x04\x00", 5); + ret = regmap_write(dev->regmap[2], 0x00, 0x66); if (ret) goto err; - - ret = regmap_bulk_write(dev->regmap[2], 0x10, - "\x3f\x50\x2c\x8f\x80\x00\x08\xee\x08\xee", 10); + ret = regmap_write(dev->regmap[2], 0x01, 0x00); if (ret) goto err; - - ret = regmap_write(dev->regmap[0], 0x46, 0x00); + ret = regmap_write(dev->regmap[2], 0x02, 0x01); if (ret) goto err; - - ret = regmap_write(dev->regmap[0], 0xae, 0x00); - if (ret) - goto err; - - ret = regmap_write(dev->regmap[0], 0xb0, 0x0b); - if (ret) - goto err; - - ret = regmap_write(dev->regmap[0], 0xb4, 0x00); + ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val); if (ret) goto err; - - ret = regmap_write(dev->regmap[0], 0xcd, 0x17); + ret = regmap_write(dev->regmap[2], 0x04, bw_val2); if (ret) goto err; - ret = regmap_write(dev->regmap[0], 0xd4, 0x09); - if (ret) - goto err; + for (i = 0; i < sizeof(if_val); i++) { + ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]); + if (ret) + goto err; + } - ret = regmap_write(dev->regmap[0], 0xd6, 0x48); - if (ret) - goto err; + for (i = 0; i < sizeof(bw_val); i++) { + ret = regmap_write(dev->regmap[2], 0x13 + i, bw_val[i]); + if (ret) + goto err; + } - ret = regmap_write(dev->regmap[1], 0x00, 0xb0); - if (ret) + switch (c->delivery_system) { + case SYS_DVBT: + ret = regmap_write(dev->regmap[0], 0x07, 0x26); + ret = regmap_write(dev->regmap[0], 0xb0, 0x0a); + ret = regmap_write(dev->regmap[0], 0xb4, 0x00); + ret = regmap_write(dev->regmap[0], 0xcd, 0x1f); + ret = regmap_write(dev->regmap[0], 0xd4, 0x0a); + ret = regmap_write(dev->regmap[0], 0xd6, 0x48); + ret = regmap_write(dev->regmap[0], 0x00, 0xba); + ret = regmap_write(dev->regmap[0], 0x01, 0x13); + if (ret) + goto err; + break; + case SYS_DVBT2: + ret = regmap_write(dev->regmap[2], 0x2b, 0x13); + ret = regmap_write(dev->regmap[2], 0x4f, 0x05); + ret = regmap_write(dev->regmap[1], 0xf6, 0x05); + ret = regmap_write(dev->regmap[0], 0xb0, 0x0a); + ret = regmap_write(dev->regmap[0], 0xb4, 0xf6); + ret = regmap_write(dev->regmap[0], 0xcd, 0x01); + ret = regmap_write(dev->regmap[0], 0xd4, 0x09); + ret = regmap_write(dev->regmap[0], 0xd6, 0x46); + ret = regmap_write(dev->regmap[2], 0x30, 0x80); + ret = regmap_write(dev->regmap[2], 0x32, 0x00); + if (ret) + goto err; + break; + case SYS_DVBC_ANNEX_A: + ret = regmap_write(dev->regmap[0], 0xb0, 0x0b); + ret = regmap_write(dev->regmap[0], 0xb4, 0x00); + ret = regmap_write(dev->regmap[0], 0xcd, 0x17); + ret = regmap_write(dev->regmap[0], 0xd4, 0x09); + ret = regmap_write(dev->regmap[0], 0xd6, 0x48); + ret = regmap_write(dev->regmap[1], 0x00, 0xb0); + if (ret) + goto err; + break; + default: + ret = -EINVAL; goto err; + } + ret = regmap_write(dev->regmap[0], 0x46, 0x00); + ret = regmap_write(dev->regmap[0], 0xae, 0x00); + ret = regmap_write(dev->regmap[2], 0x08, 0x1d); + ret = regmap_write(dev->regmap[0], 0xd9, 0xe3); ret = regmap_write(dev->regmap[2], 0xf8, 0x9f); if (ret) goto err; @@ -133,6 +214,7 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct i2c_client *client = fe->demodulator_priv; struct mn88472_dev *dev = i2c_get_clientdata(client); + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; unsigned int utmp; @@ -143,9 +225,21 @@ static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status) goto err; } - ret = regmap_read(dev->regmap[1], 0x84, &utmp); - if (ret) + switch (c->delivery_system) { + case SYS_DVBT: + case SYS_DVBT2: + /* FIXME: implement me */ + utmp = 0x08; /* DVB-C lock value */ + break; + case SYS_DVBC_ANNEX_A: + ret = regmap_read(dev->regmap[1], 0x84, &utmp); + if (ret) + goto err; + break; + default: + ret = -EINVAL; goto err; + } if (utmp == 0x08) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | @@ -255,7 +349,7 @@ static int mn88472_sleep(struct dvb_frontend *fe) } static struct dvb_frontend_ops mn88472_ops = { - .delsys = {SYS_DVBC_ANNEX_A}, + .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, .info = { .name = "Panasonic MN88472", .caps = FE_CAN_FEC_1_2 | -- GitLab From c867b265b15c2703fe07adcce064a2e3ba77ed13 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:01:44 -0300 Subject: [PATCH 4836/9457] [media] mn88472: move to staging It is not ready enough to be released on mainline. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 8 -------- drivers/media/dvb-frontends/Makefile | 1 - drivers/staging/media/Kconfig | 2 ++ drivers/staging/media/Makefile | 1 + drivers/staging/media/mn88472/Kconfig | 7 +++++++ drivers/staging/media/mn88472/Makefile | 5 +++++ .../dvb-frontends => staging/media/mn88472}/mn88472.c | 0 .../media/mn88472}/mn88472_priv.h | 0 8 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 drivers/staging/media/mn88472/Kconfig create mode 100644 drivers/staging/media/mn88472/Makefile rename drivers/{media/dvb-frontends => staging/media/mn88472}/mn88472.c (100%) rename drivers/{media/dvb-frontends => staging/media/mn88472}/mn88472_priv.h (100%) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 207843e2899c..6c75418222e2 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -441,14 +441,6 @@ config DVB_CXD2820R help Say Y when you want to support this frontend. -config DVB_MN88472 - tristate "Panasonic MN88472" - depends on DVB_CORE && I2C - select REGMAP_I2C - default m if !MEDIA_SUBDRV_AUTOSELECT - help - Say Y when you want to support this frontend. - config DVB_RTL2830 tristate "Realtek RTL2830 DVB-T" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index b82225f6781c..ba59df63d050 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -103,7 +103,6 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o obj-$(CONFIG_DVB_IX2505V) += ix2505v.o obj-$(CONFIG_DVB_STV0367) += stv0367.o obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o -obj-$(CONFIG_DVB_MN88472) += mn88472.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_SI2165) += si2165.o diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 655cf5037b0b..c2e675aa22c5 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -27,6 +27,8 @@ source "drivers/staging/media/davinci_vpfe/Kconfig" source "drivers/staging/media/dt3155v4l/Kconfig" +source "drivers/staging/media/mn88472/Kconfig" + source "drivers/staging/media/omap24xx/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 6dbe578178cd..e174c57331e1 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/ obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/ +obj-$(CONFIG_DVB_MN88472) += mn88472/ diff --git a/drivers/staging/media/mn88472/Kconfig b/drivers/staging/media/mn88472/Kconfig new file mode 100644 index 000000000000..a85c90a60bce --- /dev/null +++ b/drivers/staging/media/mn88472/Kconfig @@ -0,0 +1,7 @@ +config DVB_MN88472 + tristate "Panasonic MN88472" + depends on DVB_CORE && I2C + select REGMAP_I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Say Y when you want to support this frontend. diff --git a/drivers/staging/media/mn88472/Makefile b/drivers/staging/media/mn88472/Makefile new file mode 100644 index 000000000000..5987b7e6d82a --- /dev/null +++ b/drivers/staging/media/mn88472/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_DVB_MN88472) += mn88472.o + +ccflags-y += -Idrivers/media/dvb-core/ +ccflags-y += -Idrivers/media/dvb-frontends/ +ccflags-y += -Idrivers/media/tuners/ diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/staging/media/mn88472/mn88472.c similarity index 100% rename from drivers/media/dvb-frontends/mn88472.c rename to drivers/staging/media/mn88472/mn88472.c diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/staging/media/mn88472/mn88472_priv.h similarity index 100% rename from drivers/media/dvb-frontends/mn88472_priv.h rename to drivers/staging/media/mn88472/mn88472_priv.h -- GitLab From c8301777a23f058fe40f396e7465b6c9a20bf86e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:29:38 -0300 Subject: [PATCH 4837/9457] [media] mn88472: add staging TODO Add TODO for mainlining. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/mn88472/TODO | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 drivers/staging/media/mn88472/TODO diff --git a/drivers/staging/media/mn88472/TODO b/drivers/staging/media/mn88472/TODO new file mode 100644 index 000000000000..b90a14be3beb --- /dev/null +++ b/drivers/staging/media/mn88472/TODO @@ -0,0 +1,21 @@ +Driver general quality is not good enough for mainline. Also, other +device drivers (USB-bridge, tuner) needed for Astrometa receiver in +question could need some changes. However, if that driver is mainlined +due to some other device than Astrometa, unrelated TODOs could be +skipped. In that case rtl28xxu driver needs module parameter to prevent +driver loading. + +Required TODOs: +* missing lock flags +* I2C errors +* tuner sensitivity + +*Do not* send any patch fixing checkpatch.pl issues. Currently it passes +checkpatch.pl tests. I don't want waste my time to review this kind of +trivial stuff. *Do not* add missing register I/O error checks. Those are +missing for the reason it is much easier to compare I2C data sniffs when +there is less lines. Those error checks are about the last thing to be added. + +Patches should be submitted to: +linux-media@vger.kernel.org and Antti Palosaari + -- GitLab From 0ce277e45f85433dde044561ad3b3e876a9ee906 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:35:42 -0300 Subject: [PATCH 4838/9457] [media] MAINTAINERS: add mn88472 (Panasonic MN88472) Add mn88472 driver from staging. DVB-T/T2/C demodulator driver. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2a9cff1da54b..644a1aecf44a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6115,6 +6115,17 @@ S: Supported F: include/linux/mlx5/ F: drivers/infiniband/hw/mlx5/ +MN88472 MEDIA DRIVER +M: Antti Palosaari +L: linux-media@vger.kernel.org +W: http://linuxtv.org/ +W: http://palosaari.fi/linux/ +Q: http://patchwork.linuxtv.org/project/linux-media/list/ +T: git git://linuxtv.org/anttip/media_tree.git +S: Maintained +F: drivers/staging/media/mn88472/ +F: drivers/media/dvb-frontends/mn88472.h + MODULE SUPPORT M: Rusty Russell S: Maintained -- GitLab From dadb5bb473189ca7e80bf2190b44cf276ea42af2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 30 Sep 2014 01:01:47 -0300 Subject: [PATCH 4839/9457] [media] mn88473: Panasonic MN88473 DVB-T/T2/C demod driver Only DVB-C is implemented. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 7 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/mn88473.c | 393 +++++++++++++++++++++ drivers/media/dvb-frontends/mn88473.h | 46 +++ drivers/media/dvb-frontends/mn88473_priv.h | 34 ++ 5 files changed, 481 insertions(+) create mode 100644 drivers/media/dvb-frontends/mn88473.c create mode 100644 drivers/media/dvb-frontends/mn88473.h create mode 100644 drivers/media/dvb-frontends/mn88473_priv.h diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 6c75418222e2..2720b8f4491b 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -471,6 +471,13 @@ config DVB_SI2168 help Say Y when you want to support this frontend. +config DVB_MN88473 + tristate "Panasonic MN88473" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Say Y when you want to support this frontend. + config DVB_AS102_FE tristate depends on DVB_CORE diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index ba59df63d050..8be6eb0d440d 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -113,6 +113,7 @@ obj-$(CONFIG_DVB_RTL2830) += rtl2830.o obj-$(CONFIG_DVB_RTL2832) += rtl2832.o obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o +obj-$(CONFIG_DVB_MN88473) += mn88473.o obj-$(CONFIG_DVB_AF9033) += af9033.o obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o obj-$(CONFIG_DVB_TC90522) += tc90522.o diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c new file mode 100644 index 000000000000..afe59f3dfb19 --- /dev/null +++ b/drivers/media/dvb-frontends/mn88473.c @@ -0,0 +1,393 @@ +/* + * Panasonic MN88473 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2014 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mn88473_priv.h" + +static struct dvb_frontend_ops mn88473_ops; + +/* write multiple registers */ +static int mn88473_wregs(struct mn88473_dev *dev, u16 reg, const u8 *val, int len) +{ +#define MAX_WR_LEN 21 +#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) + int ret; + u8 buf[MAX_WR_XFER_LEN]; + struct i2c_msg msg[1] = { + { + .addr = (reg >> 8) & 0xff, + .flags = 0, + .len = 1 + len, + .buf = buf, + } + }; + + if (WARN_ON(len > MAX_WR_LEN)) + return -EINVAL; + + buf[0] = (reg >> 0) & 0xff; + memcpy(&buf[1], val, len); + + ret = i2c_transfer(dev->i2c, msg, 1); + if (ret == 1) { + ret = 0; + } else { + dev_warn(&dev->i2c->dev, + "%s: i2c wr failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* read multiple registers */ +static int mn88473_rregs(struct mn88473_dev *dev, u16 reg, u8 *val, int len) +{ +#define MAX_RD_LEN 2 +#define MAX_RD_XFER_LEN (MAX_RD_LEN) + int ret; + u8 buf[MAX_RD_XFER_LEN]; + struct i2c_msg msg[2] = { + { + .addr = (reg >> 8) & 0xff, + .flags = 0, + .len = 1, + .buf = buf, + }, { + .addr = (reg >> 8) & 0xff, + .flags = I2C_M_RD, + .len = len, + .buf = buf, + } + }; + + if (WARN_ON(len > MAX_RD_LEN)) + return -EINVAL; + + buf[0] = (reg >> 0) & 0xff; + + ret = i2c_transfer(dev->i2c, msg, 2); + if (ret == 2) { + memcpy(val, buf, len); + ret = 0; + } else { + dev_warn(&dev->i2c->dev, + "%s: i2c rd failed=%d reg=%02x len=%d\n", + KBUILD_MODNAME, ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +/* write single register */ +static int mn88473_wreg(struct mn88473_dev *dev, u16 reg, u8 val) +{ + return mn88473_wregs(dev, reg, &val, 1); +} + +/* read single register */ +static int mn88473_rreg(struct mn88473_dev *dev, u16 reg, u8 *val) +{ + return mn88473_rregs(dev, reg, val, 1); +} + +static int mn88473_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *s) +{ + s->min_delay_ms = 1000; + return 0; +} + +static int mn88473_set_frontend(struct dvb_frontend *fe) +{ + struct mn88473_dev *dev = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; + u32 if_frequency = 0; + + dev_dbg(&dev->i2c->dev, + "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", + __func__, c->delivery_system, c->modulation, + c->frequency, c->symbol_rate, c->inversion); + + if (!dev->warm) { + ret = -EAGAIN; + goto err; + } + + /* program tuner */ + if (fe->ops.tuner_ops.set_params) { + ret = fe->ops.tuner_ops.set_params(fe); + if (ret) + goto err; + } + + if (fe->ops.tuner_ops.get_if_frequency) { + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); + if (ret) + goto err; + + dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n", + __func__, if_frequency); + } + + if (if_frequency != 5070000) { + dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n", + KBUILD_MODNAME, if_frequency); + ret = -EINVAL; + goto err; + } + + ret = mn88473_wregs(dev, 0x1c05, "\x00", 1); + ret = mn88473_wregs(dev, 0x1cfb, "\x13", 1); + ret = mn88473_wregs(dev, 0x1cef, "\x13", 1); + ret = mn88473_wregs(dev, 0x1cf9, "\x13", 1); + ret = mn88473_wregs(dev, 0x1c00, "\x18", 1); + ret = mn88473_wregs(dev, 0x1c01, "\x01", 1); + ret = mn88473_wregs(dev, 0x1c02, "\x21", 1); + ret = mn88473_wregs(dev, 0x1c03, "\x04", 1); + ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1); + ret = mn88473_wregs(dev, 0x1c10, "\x33\xea\xb3\xaf\x00\x00\x11\xec\x11\xec", 10); + ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1); + ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1); + ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1); + ret = mn88473_wregs(dev, 0x1802, "\x13", 1); + ret = mn88473_wregs(dev, 0x1803, "\x80", 1); + ret = mn88473_wregs(dev, 0x1804, "\xba", 1); + ret = mn88473_wregs(dev, 0x1805, "\x91", 1); + ret = mn88473_wregs(dev, 0x1808, "\x28", 1); + ret = mn88473_wregs(dev, 0x180a, "\x1a", 1); + ret = mn88473_wregs(dev, 0x1813, "\x1f", 1); + ret = mn88473_wregs(dev, 0x1819, "\x03", 1); + ret = mn88473_wregs(dev, 0x181d, "\xb0", 1); + ret = mn88473_wregs(dev, 0x182a, "\x72", 1); + ret = mn88473_wregs(dev, 0x182d, "\x00", 1); + ret = mn88473_wregs(dev, 0x183c, "\x00", 1); + ret = mn88473_wregs(dev, 0x183f, "\xf8", 1); + ret = mn88473_wregs(dev, 0x1840, "\xf4", 1); + ret = mn88473_wregs(dev, 0x1841, "\x08", 1); + ret = mn88473_wregs(dev, 0x18d2, "\x29", 1); + ret = mn88473_wregs(dev, 0x18d4, "\x55", 1); + ret = mn88473_wregs(dev, 0x1a10, "\x10", 1); + ret = mn88473_wregs(dev, 0x1a11, "\xab", 1); + ret = mn88473_wregs(dev, 0x1a12, "\x0d", 1); + ret = mn88473_wregs(dev, 0x1a13, "\xae", 1); + ret = mn88473_wregs(dev, 0x1a14, "\x1d", 1); + ret = mn88473_wregs(dev, 0x1a15, "\x9d", 1); + ret = mn88473_wregs(dev, 0x1abe, "\x08", 1); + ret = mn88473_wregs(dev, 0x1c09, "\x08", 1); + ret = mn88473_wregs(dev, 0x1c08, "\x1d", 1); + ret = mn88473_wregs(dev, 0x18b2, "\x37", 1); + ret = mn88473_wregs(dev, 0x18d7, "\x04", 1); + ret = mn88473_wregs(dev, 0x1cf8, "\x9f", 1); + if (ret) + goto err; + + dev->delivery_system = c->delivery_system; + + return 0; +err: + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct mn88473_dev *dev = fe->demodulator_priv; + int ret; + + *status = 0; + + if (!dev->warm) { + ret = -EAGAIN; + goto err; + } + + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_LOCK; + + return 0; +err: + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_init(struct dvb_frontend *fe) +{ + struct mn88473_dev *dev = fe->demodulator_priv; + int ret, len, remaining; + const struct firmware *fw = NULL; + u8 *fw_file = MN88473_FIRMWARE; + + dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + + if (dev->warm) + return 0; + + /* request the firmware, this will block and timeout */ + ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent); + if (ret) { + dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n", + KBUILD_MODNAME, fw_file); + goto err; + } + + dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n", + KBUILD_MODNAME, fw_file); + + ret = mn88473_wreg(dev, 0x18f5, 0x03); + if (ret) + goto err; + + for (remaining = fw->size; remaining > 0; + remaining -= (dev->cfg->i2c_wr_max - 1)) { + len = remaining; + if (len > (dev->cfg->i2c_wr_max - 1)) + len = (dev->cfg->i2c_wr_max - 1); + + ret = mn88473_wregs(dev, 0x18f6, + &fw->data[fw->size - remaining], len); + if (ret) { + dev_err(&dev->i2c->dev, + "%s: firmware download failed=%d\n", + KBUILD_MODNAME, ret); + goto err; + } + } + + ret = mn88473_wreg(dev, 0x18f5, 0x00); + if (ret) + goto err; + + release_firmware(fw); + fw = NULL; + + /* warm state */ + dev->warm = true; + + return 0; +err: + if (fw) + release_firmware(fw); + + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static int mn88473_sleep(struct dvb_frontend *fe) +{ + struct mn88473_dev *dev = fe->demodulator_priv; + int ret; + + dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + + ret = mn88473_wreg(dev, 0x1c05, 0x3e); + if (ret) + goto err; + + dev->delivery_system = SYS_UNDEFINED; + + return 0; +err: + dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + +static void mn88473_release(struct dvb_frontend *fe) +{ + struct mn88473_dev *dev = fe->demodulator_priv; + kfree(dev); +} + +struct dvb_frontend *mn88473_attach(const struct mn88473_config *cfg, + struct i2c_adapter *i2c) +{ + int ret; + struct mn88473_dev *dev; + u8 u8tmp; + + dev_dbg(&i2c->dev, "%s:\n", __func__); + + /* allocate memory for the internal state */ + dev = kzalloc(sizeof(struct mn88473_dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); + goto err; + } + + dev->cfg = cfg; + dev->i2c = i2c; + + /* check demod responds to I2C */ + ret = mn88473_rreg(dev, 0x1c00, &u8tmp); + if (ret) + goto err; + + /* create dvb_frontend */ + memcpy(&dev->fe.ops, &mn88473_ops, sizeof(struct dvb_frontend_ops)); + dev->fe.demodulator_priv = dev; + + return &dev->fe; +err: + dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + kfree(dev); + return NULL; +} +EXPORT_SYMBOL(mn88473_attach); + +static struct dvb_frontend_ops mn88473_ops = { + .delsys = {SYS_DVBC_ANNEX_AC}, + .info = { + .name = "Panasonic MN88473", + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM + }, + + .release = mn88473_release, + + .get_tune_settings = mn88473_get_tune_settings, + + .init = mn88473_init, + .sleep = mn88473_sleep, + + .set_frontend = mn88473_set_frontend, + + .read_status = mn88473_read_status, +}; + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("Panasonic MN88473 DVB-T/T2/C demodulator driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(MN88473_FIRMWARE); diff --git a/drivers/media/dvb-frontends/mn88473.h b/drivers/media/dvb-frontends/mn88473.h new file mode 100644 index 000000000000..13b51b64b30f --- /dev/null +++ b/drivers/media/dvb-frontends/mn88473.h @@ -0,0 +1,46 @@ +/* + * Panasonic MN88473 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2014 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MN88473_H +#define MN88473_H + +#include + +struct mn88473_config { + /* + * max bytes I2C client could write + * Value must be set. + */ + int i2c_wr_max; +}; + +#if IS_ENABLED(CONFIG_DVB_MN88473) +extern struct dvb_frontend *mn88473_attach( + const struct mn88473_config *cfg, + struct i2c_adapter *i2c +); +#else +static inline struct dvb_frontend *mn88473_attach( + const struct mn88473_config *cfg, + struct i2c_adapter *i2c +) +{ + dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h new file mode 100644 index 000000000000..c40b3a53f50b --- /dev/null +++ b/drivers/media/dvb-frontends/mn88473_priv.h @@ -0,0 +1,34 @@ +/* + * Panasonic MN88473 DVB-T/T2/C demodulator driver + * + * Copyright (C) 2014 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MN88473_PRIV_H +#define MN88473_PRIV_H + +#include "dvb_frontend.h" +#include "mn88473.h" +#include + +#define MN88473_FIRMWARE "dvb-demod-mn88473-01.fw" + +struct mn88473_dev { + struct i2c_adapter *i2c; + const struct mn88473_config *cfg; + struct dvb_frontend fe; + fe_delivery_system_t delivery_system; + bool warm; /* FW running */ +}; + +#endif -- GitLab From c00a6b9f9f92a6138db8ad4bcc56c3402267695c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 30 Sep 2014 17:52:03 -0300 Subject: [PATCH 4840/9457] [media] mn88473: add support for DVB-T2 Add support for DVB-T2. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 45 ++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index afe59f3dfb19..68bfb6560eec 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -116,19 +116,38 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) { struct mn88473_dev *dev = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; + int ret, i; u32 if_frequency = 0; + u8 params[10], delivery_system; dev_dbg(&dev->i2c->dev, - "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", + "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n", __func__, c->delivery_system, c->modulation, - c->frequency, c->symbol_rate, c->inversion); + c->frequency, c->bandwidth_hz, c->symbol_rate, + c->inversion, c->stream_id); if (!dev->warm) { ret = -EAGAIN; goto err; } + switch (c->delivery_system) { + case SYS_DVBT2: + delivery_system = 0x03; + if (c->bandwidth_hz <= 7000000) + memcpy(params, "\x2e\xcb\xfb\xc8\x00\x00\x17\x0a\x17\x0a", 10); + else if (c->bandwidth_hz <= 8000000) + memcpy(params, "\x2e\xcb\xfb\xaf\x00\x00\x11\xec\x11\xec", 10); + break; + case SYS_DVBC_ANNEX_A: + delivery_system = 0x04; + memcpy(params, "\x33\xea\xb3\xaf\x00\x00\x11\xec\x11\xec", 10); + break; + default: + ret = -EINVAL; + goto err; + } + /* program tuner */ if (fe->ops.tuner_ops.set_params) { ret = fe->ops.tuner_ops.set_params(fe); @@ -145,7 +164,11 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) __func__, if_frequency); } - if (if_frequency != 5070000) { + switch (if_frequency) { + case 4570000: + case 5070000: + break; + default: dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n", KBUILD_MODNAME, if_frequency); ret = -EINVAL; @@ -159,9 +182,15 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) ret = mn88473_wregs(dev, 0x1c00, "\x18", 1); ret = mn88473_wregs(dev, 0x1c01, "\x01", 1); ret = mn88473_wregs(dev, 0x1c02, "\x21", 1); - ret = mn88473_wregs(dev, 0x1c03, "\x04", 1); + ret = mn88473_wreg(dev, 0x1c03, delivery_system); ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1); - ret = mn88473_wregs(dev, 0x1c10, "\x33\xea\xb3\xaf\x00\x00\x11\xec\x11\xec", 10); + + for (i = 0; i < 10; i++) { + ret = mn88473_wreg(dev, 0x1c10 + i, params[i]); + if (ret) + goto err; + } + ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1); ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1); ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1); @@ -193,6 +222,8 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) ret = mn88473_wregs(dev, 0x1c08, "\x1d", 1); ret = mn88473_wregs(dev, 0x18b2, "\x37", 1); ret = mn88473_wregs(dev, 0x18d7, "\x04", 1); + ret = mn88473_wregs(dev, 0x1c32, "\x80", 1); + ret = mn88473_wregs(dev, 0x1c36, "\x00", 1); ret = mn88473_wregs(dev, 0x1cf8, "\x9f", 1); if (ret) goto err; @@ -351,7 +382,7 @@ struct dvb_frontend *mn88473_attach(const struct mn88473_config *cfg, EXPORT_SYMBOL(mn88473_attach); static struct dvb_frontend_ops mn88473_ops = { - .delsys = {SYS_DVBC_ANNEX_AC}, + .delsys = {SYS_DVBT2, SYS_DVBC_ANNEX_AC}, .info = { .name = "Panasonic MN88473", .caps = FE_CAN_FEC_1_2 | -- GitLab From 6ebbe22d42f6f4a2940190b1dd98b7454b805a9c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 30 Sep 2014 19:56:22 -0300 Subject: [PATCH 4841/9457] [media] mn88473: implement DVB-T mode Implement DVB-T mode. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index 68bfb6560eec..cda0bdbeca18 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -132,6 +132,13 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) } switch (c->delivery_system) { + case SYS_DVBT: + delivery_system = 0x02; + if (c->bandwidth_hz <= 7000000) + memcpy(params, "\x2e\xcb\xfb\xc8\x00\x00\x17\x0a\x17\x0a", 10); + else if (c->bandwidth_hz <= 8000000) + memcpy(params, "\x2e\xcb\xfb\xaf\x00\x00\x11\xec\x11\xec", 10); + break; case SYS_DVBT2: delivery_system = 0x03; if (c->bandwidth_hz <= 7000000) @@ -194,10 +201,12 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1); ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1); ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1); + ret = mn88473_wregs(dev, 0x1801, "\xba", 1); ret = mn88473_wregs(dev, 0x1802, "\x13", 1); ret = mn88473_wregs(dev, 0x1803, "\x80", 1); ret = mn88473_wregs(dev, 0x1804, "\xba", 1); ret = mn88473_wregs(dev, 0x1805, "\x91", 1); + ret = mn88473_wregs(dev, 0x1807, "\xe7", 1); ret = mn88473_wregs(dev, 0x1808, "\x28", 1); ret = mn88473_wregs(dev, 0x180a, "\x1a", 1); ret = mn88473_wregs(dev, 0x1813, "\x1f", 1); @@ -382,7 +391,7 @@ struct dvb_frontend *mn88473_attach(const struct mn88473_config *cfg, EXPORT_SYMBOL(mn88473_attach); static struct dvb_frontend_ops mn88473_ops = { - .delsys = {SYS_DVBT2, SYS_DVBC_ANNEX_AC}, + .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_AC}, .info = { .name = "Panasonic MN88473", .caps = FE_CAN_FEC_1_2 | -- GitLab From df810e8a973aae5b551bf86d69311abaac22959b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 30 Sep 2014 23:19:30 -0300 Subject: [PATCH 4842/9457] [media] mn88473: improve IF frequency and BW handling Separate IF and BW based registers. Add support for DVB-T and DVB-T2 6MHz channel bandwidth. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 64 ++++++++++++++++++++------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index cda0bdbeca18..2c81a83d3d5d 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -117,8 +117,8 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) struct mn88473_dev *dev = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; - u32 if_frequency = 0; - u8 params[10], delivery_system; + u32 if_frequency; + u8 delivery_system_val, if_val[3], bw_val[7]; dev_dbg(&dev->i2c->dev, "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n", @@ -133,22 +133,43 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) switch (c->delivery_system) { case SYS_DVBT: - delivery_system = 0x02; - if (c->bandwidth_hz <= 7000000) - memcpy(params, "\x2e\xcb\xfb\xc8\x00\x00\x17\x0a\x17\x0a", 10); - else if (c->bandwidth_hz <= 8000000) - memcpy(params, "\x2e\xcb\xfb\xaf\x00\x00\x11\xec\x11\xec", 10); + delivery_system_val = 0x02; break; case SYS_DVBT2: - delivery_system = 0x03; - if (c->bandwidth_hz <= 7000000) - memcpy(params, "\x2e\xcb\xfb\xc8\x00\x00\x17\x0a\x17\x0a", 10); - else if (c->bandwidth_hz <= 8000000) - memcpy(params, "\x2e\xcb\xfb\xaf\x00\x00\x11\xec\x11\xec", 10); + delivery_system_val = 0x03; break; case SYS_DVBC_ANNEX_A: - delivery_system = 0x04; - memcpy(params, "\x33\xea\xb3\xaf\x00\x00\x11\xec\x11\xec", 10); + delivery_system_val = 0x04; + break; + default: + ret = -EINVAL; + goto err; + } + + switch (c->delivery_system) { + case SYS_DVBT: + case SYS_DVBT2: + if (c->bandwidth_hz <= 6000000) { + /* IF 3570000 Hz, BW 6000000 Hz */ + memcpy(if_val, "\x24\x8e\x8a", 3); + memcpy(bw_val, "\xe9\x55\x55\x1c\x29\x1c\x29", 7); + } else if (c->bandwidth_hz <= 7000000) { + /* IF 4570000 Hz, BW 7000000 Hz */ + memcpy(if_val, "\x2e\xcb\xfb", 3); + memcpy(bw_val, "\xc8\x00\x00\x17\x0a\x17\x0a", 7); + } else if (c->bandwidth_hz <= 8000000) { + /* IF 4570000 Hz, BW 8000000 Hz */ + memcpy(if_val, "\x2e\xcb\xfb", 3); + memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7); + } else { + ret = -EINVAL; + goto err; + } + break; + case SYS_DVBC_ANNEX_A: + /* IF 5070000 Hz, BW 8000000 Hz */ + memcpy(if_val, "\x33\xea\xb3", 3); + memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7); break; default: ret = -EINVAL; @@ -169,9 +190,12 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n", __func__, if_frequency); + } else { + if_frequency = 0; } switch (if_frequency) { + case 3570000: case 4570000: case 5070000: break; @@ -189,11 +213,17 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) ret = mn88473_wregs(dev, 0x1c00, "\x18", 1); ret = mn88473_wregs(dev, 0x1c01, "\x01", 1); ret = mn88473_wregs(dev, 0x1c02, "\x21", 1); - ret = mn88473_wreg(dev, 0x1c03, delivery_system); + ret = mn88473_wreg(dev, 0x1c03, delivery_system_val); ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1); - for (i = 0; i < 10; i++) { - ret = mn88473_wreg(dev, 0x1c10 + i, params[i]); + for (i = 0; i < sizeof(if_val); i++) { + ret = mn88473_wreg(dev, 0x1c10 + i, if_val[i]); + if (ret) + goto err; + } + + for (i = 0; i < sizeof(bw_val); i++) { + ret = mn88473_wreg(dev, 0x1c13 + i, bw_val[i]); if (ret) goto err; } -- GitLab From 01b4be1452431fae39250f8fb326c89d64a5a65c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 2 Oct 2014 22:41:26 -0300 Subject: [PATCH 4843/9457] [media] mn88473: convert driver to I2C binding Driver was using DVB proprietary binding model. As it is I2C device, we could change it to normal kernel I2C driver. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 238 +++++++++++++-------- drivers/media/dvb-frontends/mn88473.h | 30 +-- drivers/media/dvb-frontends/mn88473_priv.h | 4 +- 3 files changed, 162 insertions(+), 110 deletions(-) diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index 2c81a83d3d5d..ff67c4cf3c33 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -40,13 +40,13 @@ static int mn88473_wregs(struct mn88473_dev *dev, u16 reg, const u8 *val, int le buf[0] = (reg >> 0) & 0xff; memcpy(&buf[1], val, len); - ret = i2c_transfer(dev->i2c, msg, 1); + ret = i2c_transfer(dev->client[0]->adapter, msg, 1); if (ret == 1) { ret = 0; } else { - dev_warn(&dev->i2c->dev, - "%s: i2c wr failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&dev->client[0]->dev, + "i2c wr failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -79,14 +79,14 @@ static int mn88473_rregs(struct mn88473_dev *dev, u16 reg, u8 *val, int len) buf[0] = (reg >> 0) & 0xff; - ret = i2c_transfer(dev->i2c, msg, 2); + ret = i2c_transfer(dev->client[0]->adapter, msg, 2); if (ret == 2) { memcpy(val, buf, len); ret = 0; } else { - dev_warn(&dev->i2c->dev, - "%s: i2c rd failed=%d reg=%02x len=%d\n", - KBUILD_MODNAME, ret, reg, len); + dev_warn(&dev->client[0]->dev, + "i2c rd failed=%d reg=%02x len=%d\n", + ret, reg, len); ret = -EREMOTEIO; } @@ -114,15 +114,16 @@ static int mn88473_get_tune_settings(struct dvb_frontend *fe, static int mn88473_set_frontend(struct dvb_frontend *fe) { - struct mn88473_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u32 if_frequency; u8 delivery_system_val, if_val[3], bw_val[7]; - dev_dbg(&dev->i2c->dev, - "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n", - __func__, c->delivery_system, c->modulation, + dev_dbg(&client->dev, + "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n", + c->delivery_system, c->modulation, c->frequency, c->bandwidth_hz, c->symbol_rate, c->inversion, c->stream_id); @@ -188,8 +189,7 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n", - __func__, if_frequency); + dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency); } else { if_frequency = 0; } @@ -200,8 +200,8 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) case 5070000: break; default: - dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n", - KBUILD_MODNAME, if_frequency); + dev_err(&client->dev, "IF frequency %d not supported\n", + if_frequency); ret = -EINVAL; goto err; } @@ -271,13 +271,14 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status) { - struct mn88473_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); int ret; *status = 0; @@ -292,49 +293,48 @@ static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88473_init(struct dvb_frontend *fe) { - struct mn88473_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); int ret, len, remaining; const struct firmware *fw = NULL; u8 *fw_file = MN88473_FIRMWARE; - dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); if (dev->warm) return 0; /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent); + ret = request_firmware(&fw, fw_file, &client->dev); if (ret) { - dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n", - KBUILD_MODNAME, fw_file); + dev_err(&client->dev, "firmare file '%s' not found\n", fw_file); goto err; } - dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n", - KBUILD_MODNAME, fw_file); + dev_info(&client->dev, "downloading firmware from file '%s'\n", + fw_file); ret = mn88473_wreg(dev, 0x18f5, 0x03); if (ret) goto err; for (remaining = fw->size; remaining > 0; - remaining -= (dev->cfg->i2c_wr_max - 1)) { + remaining -= (dev->i2c_wr_max - 1)) { len = remaining; - if (len > (dev->cfg->i2c_wr_max - 1)) - len = (dev->cfg->i2c_wr_max - 1); + if (len > (dev->i2c_wr_max - 1)) + len = (dev->i2c_wr_max - 1); ret = mn88473_wregs(dev, 0x18f6, &fw->data[fw->size - remaining], len); if (ret) { - dev_err(&dev->i2c->dev, - "%s: firmware download failed=%d\n", - KBUILD_MODNAME, ret); + dev_err(&client->dev, "firmware download failed=%d\n", + ret); goto err; } } @@ -354,16 +354,17 @@ static int mn88473_init(struct dvb_frontend *fe) if (fw) release_firmware(fw); - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int mn88473_sleep(struct dvb_frontend *fe) { - struct mn88473_dev *dev = fe->demodulator_priv; + struct i2c_client *client = fe->demodulator_priv; + struct mn88473_dev *dev = i2c_get_clientdata(client); int ret; - dev_dbg(&dev->i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); ret = mn88473_wreg(dev, 0x1c05, 0x3e); if (ret) @@ -373,90 +374,149 @@ static int mn88473_sleep(struct dvb_frontend *fe) return 0; err: - dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -static void mn88473_release(struct dvb_frontend *fe) -{ - struct mn88473_dev *dev = fe->demodulator_priv; - kfree(dev); -} +static struct dvb_frontend_ops mn88473_ops = { + .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_AC}, + .info = { + .name = "Panasonic MN88473", + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | + FE_CAN_MUTE_TS | + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM + }, + + .get_tune_settings = mn88473_get_tune_settings, + + .init = mn88473_init, + .sleep = mn88473_sleep, -struct dvb_frontend *mn88473_attach(const struct mn88473_config *cfg, - struct i2c_adapter *i2c) + .set_frontend = mn88473_set_frontend, + + .read_status = mn88473_read_status, +}; + +static int mn88473_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int ret; + struct mn88473_config *config = client->dev.platform_data; struct mn88473_dev *dev; + int ret; u8 u8tmp; - dev_dbg(&i2c->dev, "%s:\n", __func__); + dev_dbg(&client->dev, "\n"); - /* allocate memory for the internal state */ - dev = kzalloc(sizeof(struct mn88473_dev), GFP_KERNEL); - if (!dev) { + /* Caller really need to provide pointer for frontend we create. */ + if (config->fe == NULL) { + dev_err(&client->dev, "frontend pointer not defined\n"); + ret = -EINVAL; + goto err; + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { ret = -ENOMEM; - dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); goto err; } - dev->cfg = cfg; - dev->i2c = i2c; + dev->client[0] = client; + dev->i2c_wr_max = config->i2c_wr_max; - /* check demod responds to I2C */ + /* check demod answers to I2C */ ret = mn88473_rreg(dev, 0x1c00, &u8tmp); if (ret) - goto err; + goto err_kfree; + + /* + * Chip has three I2C addresses for different register pages. Used + * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients, + * 0x1a and 0x1c, in order to get own I2C client for each register page. + */ + dev->client[1] = i2c_new_dummy(client->adapter, 0x1a); + if (dev->client[1] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "I2C registration failed\n"); + if (ret) + goto err_kfree; + } + i2c_set_clientdata(dev->client[1], dev); + + dev->client[2] = i2c_new_dummy(client->adapter, 0x1c); + if (dev->client[2] == NULL) { + ret = -ENODEV; + dev_err(&client->dev, "2nd I2C registration failed\n"); + if (ret) + goto err_client_1_i2c_unregister_device; + } + i2c_set_clientdata(dev->client[2], dev); /* create dvb_frontend */ memcpy(&dev->fe.ops, &mn88473_ops, sizeof(struct dvb_frontend_ops)); - dev->fe.demodulator_priv = dev; + dev->fe.demodulator_priv = client; + *config->fe = &dev->fe; + i2c_set_clientdata(client, dev); - return &dev->fe; -err: - dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_info(&dev->client[0]->dev, "Panasonic MN88473 successfully attached\n"); + return 0; + +err_client_1_i2c_unregister_device: + i2c_unregister_device(dev->client[1]); +err_kfree: kfree(dev); - return NULL; +err: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; } -EXPORT_SYMBOL(mn88473_attach); -static struct dvb_frontend_ops mn88473_ops = { - .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_AC}, - .info = { - .name = "Panasonic MN88473", - .caps = FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_MUTE_TS | - FE_CAN_2G_MODULATION | - FE_CAN_MULTISTREAM - }, +static int mn88473_remove(struct i2c_client *client) +{ + struct mn88473_dev *dev = i2c_get_clientdata(client); - .release = mn88473_release, + dev_dbg(&client->dev, "\n"); - .get_tune_settings = mn88473_get_tune_settings, + i2c_unregister_device(dev->client[2]); + i2c_unregister_device(dev->client[1]); - .init = mn88473_init, - .sleep = mn88473_sleep, + kfree(dev); - .set_frontend = mn88473_set_frontend, + return 0; +} - .read_status = mn88473_read_status, +static const struct i2c_device_id mn88473_id_table[] = { + {"mn88473", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, mn88473_id_table); + +static struct i2c_driver mn88473_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mn88473", + }, + .probe = mn88473_probe, + .remove = mn88473_remove, + .id_table = mn88473_id_table, }; +module_i2c_driver(mn88473_driver); + MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Panasonic MN88473 DVB-T/T2/C demodulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/mn88473.h b/drivers/media/dvb-frontends/mn88473.h index 13b51b64b30f..a373ec93cbe0 100644 --- a/drivers/media/dvb-frontends/mn88473.h +++ b/drivers/media/dvb-frontends/mn88473.h @@ -21,26 +21,18 @@ struct mn88473_config { /* - * max bytes I2C client could write - * Value must be set. + * Max num of bytes given I2C adapter could write at once. + * Default: none */ - int i2c_wr_max; -}; + u16 i2c_wr_max; -#if IS_ENABLED(CONFIG_DVB_MN88473) -extern struct dvb_frontend *mn88473_attach( - const struct mn88473_config *cfg, - struct i2c_adapter *i2c -); -#else -static inline struct dvb_frontend *mn88473_attach( - const struct mn88473_config *cfg, - struct i2c_adapter *i2c -) -{ - dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif + + /* Everything after that is returned by the driver. */ + + /* + * DVB frontend. + */ + struct dvb_frontend **fe; +}; #endif diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h index c40b3a53f50b..853043797656 100644 --- a/drivers/media/dvb-frontends/mn88473_priv.h +++ b/drivers/media/dvb-frontends/mn88473_priv.h @@ -24,9 +24,9 @@ #define MN88473_FIRMWARE "dvb-demod-mn88473-01.fw" struct mn88473_dev { - struct i2c_adapter *i2c; - const struct mn88473_config *cfg; + struct i2c_client *client[3]; struct dvb_frontend fe; + u16 i2c_wr_max; fe_delivery_system_t delivery_system; bool warm; /* FW running */ }; -- GitLab From 97de6e89d82ad9168a27b901acc39d45fb5adfcd Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Fri, 3 Oct 2014 00:28:18 -0300 Subject: [PATCH 4844/9457] [media] mn88473: convert to RegMap API Convert driver to I2C RegMap API. That offers unified register access routines, register value caching and more. We need 3 register maps, one for each register page, as chips has 3 I2C address. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 1 + drivers/media/dvb-frontends/mn88473.c | 233 ++++++++------------- drivers/media/dvb-frontends/mn88473_priv.h | 2 + 3 files changed, 90 insertions(+), 146 deletions(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 2720b8f4491b..e60614b476a1 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -474,6 +474,7 @@ config DVB_SI2168 config DVB_MN88473 tristate "Panasonic MN88473" depends on DVB_CORE && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index ff67c4cf3c33..165933540b34 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -16,95 +16,6 @@ #include "mn88473_priv.h" -static struct dvb_frontend_ops mn88473_ops; - -/* write multiple registers */ -static int mn88473_wregs(struct mn88473_dev *dev, u16 reg, const u8 *val, int len) -{ -#define MAX_WR_LEN 21 -#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) - int ret; - u8 buf[MAX_WR_XFER_LEN]; - struct i2c_msg msg[1] = { - { - .addr = (reg >> 8) & 0xff, - .flags = 0, - .len = 1 + len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_WR_LEN)) - return -EINVAL; - - buf[0] = (reg >> 0) & 0xff; - memcpy(&buf[1], val, len); - - ret = i2c_transfer(dev->client[0]->adapter, msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&dev->client[0]->dev, - "i2c wr failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* read multiple registers */ -static int mn88473_rregs(struct mn88473_dev *dev, u16 reg, u8 *val, int len) -{ -#define MAX_RD_LEN 2 -#define MAX_RD_XFER_LEN (MAX_RD_LEN) - int ret; - u8 buf[MAX_RD_XFER_LEN]; - struct i2c_msg msg[2] = { - { - .addr = (reg >> 8) & 0xff, - .flags = 0, - .len = 1, - .buf = buf, - }, { - .addr = (reg >> 8) & 0xff, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - - if (WARN_ON(len > MAX_RD_LEN)) - return -EINVAL; - - buf[0] = (reg >> 0) & 0xff; - - ret = i2c_transfer(dev->client[0]->adapter, msg, 2); - if (ret == 2) { - memcpy(val, buf, len); - ret = 0; - } else { - dev_warn(&dev->client[0]->dev, - "i2c rd failed=%d reg=%02x len=%d\n", - ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* write single register */ -static int mn88473_wreg(struct mn88473_dev *dev, u16 reg, u8 val) -{ - return mn88473_wregs(dev, reg, &val, 1); -} - -/* read single register */ -static int mn88473_rreg(struct mn88473_dev *dev, u16 reg, u8 *val) -{ - return mn88473_rregs(dev, reg, val, 1); -} - static int mn88473_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) { @@ -206,64 +117,64 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) goto err; } - ret = mn88473_wregs(dev, 0x1c05, "\x00", 1); - ret = mn88473_wregs(dev, 0x1cfb, "\x13", 1); - ret = mn88473_wregs(dev, 0x1cef, "\x13", 1); - ret = mn88473_wregs(dev, 0x1cf9, "\x13", 1); - ret = mn88473_wregs(dev, 0x1c00, "\x18", 1); - ret = mn88473_wregs(dev, 0x1c01, "\x01", 1); - ret = mn88473_wregs(dev, 0x1c02, "\x21", 1); - ret = mn88473_wreg(dev, 0x1c03, delivery_system_val); - ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1); + ret = regmap_write(dev->regmap[2], 0x05, 0x00); + ret = regmap_write(dev->regmap[2], 0xfb, 0x13); + ret = regmap_write(dev->regmap[2], 0xef, 0x13); + ret = regmap_write(dev->regmap[2], 0xf9, 0x13); + ret = regmap_write(dev->regmap[2], 0x00, 0x18); + ret = regmap_write(dev->regmap[2], 0x01, 0x01); + ret = regmap_write(dev->regmap[2], 0x02, 0x21); + ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val); + ret = regmap_write(dev->regmap[2], 0x0b, 0x00); for (i = 0; i < sizeof(if_val); i++) { - ret = mn88473_wreg(dev, 0x1c10 + i, if_val[i]); + ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]); if (ret) goto err; } for (i = 0; i < sizeof(bw_val); i++) { - ret = mn88473_wreg(dev, 0x1c13 + i, bw_val[i]); + ret = regmap_write(dev->regmap[2], 0x13 + i, bw_val[i]); if (ret) goto err; } - ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1); - ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1); - ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1); - ret = mn88473_wregs(dev, 0x1801, "\xba", 1); - ret = mn88473_wregs(dev, 0x1802, "\x13", 1); - ret = mn88473_wregs(dev, 0x1803, "\x80", 1); - ret = mn88473_wregs(dev, 0x1804, "\xba", 1); - ret = mn88473_wregs(dev, 0x1805, "\x91", 1); - ret = mn88473_wregs(dev, 0x1807, "\xe7", 1); - ret = mn88473_wregs(dev, 0x1808, "\x28", 1); - ret = mn88473_wregs(dev, 0x180a, "\x1a", 1); - ret = mn88473_wregs(dev, 0x1813, "\x1f", 1); - ret = mn88473_wregs(dev, 0x1819, "\x03", 1); - ret = mn88473_wregs(dev, 0x181d, "\xb0", 1); - ret = mn88473_wregs(dev, 0x182a, "\x72", 1); - ret = mn88473_wregs(dev, 0x182d, "\x00", 1); - ret = mn88473_wregs(dev, 0x183c, "\x00", 1); - ret = mn88473_wregs(dev, 0x183f, "\xf8", 1); - ret = mn88473_wregs(dev, 0x1840, "\xf4", 1); - ret = mn88473_wregs(dev, 0x1841, "\x08", 1); - ret = mn88473_wregs(dev, 0x18d2, "\x29", 1); - ret = mn88473_wregs(dev, 0x18d4, "\x55", 1); - ret = mn88473_wregs(dev, 0x1a10, "\x10", 1); - ret = mn88473_wregs(dev, 0x1a11, "\xab", 1); - ret = mn88473_wregs(dev, 0x1a12, "\x0d", 1); - ret = mn88473_wregs(dev, 0x1a13, "\xae", 1); - ret = mn88473_wregs(dev, 0x1a14, "\x1d", 1); - ret = mn88473_wregs(dev, 0x1a15, "\x9d", 1); - ret = mn88473_wregs(dev, 0x1abe, "\x08", 1); - ret = mn88473_wregs(dev, 0x1c09, "\x08", 1); - ret = mn88473_wregs(dev, 0x1c08, "\x1d", 1); - ret = mn88473_wregs(dev, 0x18b2, "\x37", 1); - ret = mn88473_wregs(dev, 0x18d7, "\x04", 1); - ret = mn88473_wregs(dev, 0x1c32, "\x80", 1); - ret = mn88473_wregs(dev, 0x1c36, "\x00", 1); - ret = mn88473_wregs(dev, 0x1cf8, "\x9f", 1); + ret = regmap_write(dev->regmap[2], 0x2d, 0x3b); + ret = regmap_write(dev->regmap[2], 0x2e, 0x00); + ret = regmap_write(dev->regmap[2], 0x56, 0x0d); + ret = regmap_write(dev->regmap[0], 0x01, 0xba); + ret = regmap_write(dev->regmap[0], 0x02, 0x13); + ret = regmap_write(dev->regmap[0], 0x03, 0x80); + ret = regmap_write(dev->regmap[0], 0x04, 0xba); + ret = regmap_write(dev->regmap[0], 0x05, 0x91); + ret = regmap_write(dev->regmap[0], 0x07, 0xe7); + ret = regmap_write(dev->regmap[0], 0x08, 0x28); + ret = regmap_write(dev->regmap[0], 0x0a, 0x1a); + ret = regmap_write(dev->regmap[0], 0x13, 0x1f); + ret = regmap_write(dev->regmap[0], 0x19, 0x03); + ret = regmap_write(dev->regmap[0], 0x1d, 0xb0); + ret = regmap_write(dev->regmap[0], 0x2a, 0x72); + ret = regmap_write(dev->regmap[0], 0x2d, 0x00); + ret = regmap_write(dev->regmap[0], 0x3c, 0x00); + ret = regmap_write(dev->regmap[0], 0x3f, 0xf8); + ret = regmap_write(dev->regmap[0], 0x40, 0xf4); + ret = regmap_write(dev->regmap[0], 0x41, 0x08); + ret = regmap_write(dev->regmap[0], 0xd2, 0x29); + ret = regmap_write(dev->regmap[0], 0xd4, 0x55); + ret = regmap_write(dev->regmap[1], 0x10, 0x10); + ret = regmap_write(dev->regmap[1], 0x11, 0xab); + ret = regmap_write(dev->regmap[1], 0x12, 0x0d); + ret = regmap_write(dev->regmap[1], 0x13, 0xae); + ret = regmap_write(dev->regmap[1], 0x14, 0x1d); + ret = regmap_write(dev->regmap[1], 0x15, 0x9d); + ret = regmap_write(dev->regmap[1], 0xbe, 0x08); + ret = regmap_write(dev->regmap[2], 0x09, 0x08); + ret = regmap_write(dev->regmap[2], 0x08, 0x1d); + ret = regmap_write(dev->regmap[0], 0xb2, 0x37); + ret = regmap_write(dev->regmap[0], 0xd7, 0x04); + ret = regmap_write(dev->regmap[2], 0x32, 0x80); + ret = regmap_write(dev->regmap[2], 0x36, 0x00); + ret = regmap_write(dev->regmap[2], 0xf8, 0x9f); if (ret) goto err; @@ -320,7 +231,7 @@ static int mn88473_init(struct dvb_frontend *fe) dev_info(&client->dev, "downloading firmware from file '%s'\n", fw_file); - ret = mn88473_wreg(dev, 0x18f5, 0x03); + ret = regmap_write(dev->regmap[0], 0xf5, 0x03); if (ret) goto err; @@ -330,7 +241,7 @@ static int mn88473_init(struct dvb_frontend *fe) if (len > (dev->i2c_wr_max - 1)) len = (dev->i2c_wr_max - 1); - ret = mn88473_wregs(dev, 0x18f6, + ret = regmap_bulk_write(dev->regmap[0], 0xf6, &fw->data[fw->size - remaining], len); if (ret) { dev_err(&client->dev, "firmware download failed=%d\n", @@ -339,7 +250,7 @@ static int mn88473_init(struct dvb_frontend *fe) } } - ret = mn88473_wreg(dev, 0x18f5, 0x00); + ret = regmap_write(dev->regmap[0], 0xf5, 0x00); if (ret) goto err; @@ -366,7 +277,7 @@ static int mn88473_sleep(struct dvb_frontend *fe) dev_dbg(&client->dev, "\n"); - ret = mn88473_wreg(dev, 0x1c05, 0x3e); + ret = regmap_write(dev->regmap[2], 0x05, 0x3e); if (ret) goto err; @@ -419,7 +330,11 @@ static int mn88473_probe(struct i2c_client *client, struct mn88473_config *config = client->dev.platform_data; struct mn88473_dev *dev; int ret; - u8 u8tmp; + unsigned int utmp; + static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; dev_dbg(&client->dev, "\n"); @@ -436,13 +351,18 @@ static int mn88473_probe(struct i2c_client *client, goto err; } - dev->client[0] = client; dev->i2c_wr_max = config->i2c_wr_max; + dev->client[0] = client; + dev->regmap[0] = regmap_init_i2c(dev->client[0], ®map_config); + if (IS_ERR(dev->regmap[0])) { + ret = PTR_ERR(dev->regmap[0]); + goto err_kfree; + } /* check demod answers to I2C */ - ret = mn88473_rreg(dev, 0x1c00, &u8tmp); + ret = regmap_read(dev->regmap[0], 0x00, &utmp); if (ret) - goto err_kfree; + goto err_regmap_0_regmap_exit; /* * Chip has three I2C addresses for different register pages. Used @@ -454,7 +374,12 @@ static int mn88473_probe(struct i2c_client *client, ret = -ENODEV; dev_err(&client->dev, "I2C registration failed\n"); if (ret) - goto err_kfree; + goto err_regmap_0_regmap_exit; + } + dev->regmap[1] = regmap_init_i2c(dev->client[1], ®map_config); + if (IS_ERR(dev->regmap[1])) { + ret = PTR_ERR(dev->regmap[1]); + goto err_client_1_i2c_unregister_device; } i2c_set_clientdata(dev->client[1], dev); @@ -463,7 +388,12 @@ static int mn88473_probe(struct i2c_client *client, ret = -ENODEV; dev_err(&client->dev, "2nd I2C registration failed\n"); if (ret) - goto err_client_1_i2c_unregister_device; + goto err_regmap_1_regmap_exit; + } + dev->regmap[2] = regmap_init_i2c(dev->client[2], ®map_config); + if (IS_ERR(dev->regmap[2])) { + ret = PTR_ERR(dev->regmap[2]); + goto err_client_2_i2c_unregister_device; } i2c_set_clientdata(dev->client[2], dev); @@ -476,8 +406,14 @@ static int mn88473_probe(struct i2c_client *client, dev_info(&dev->client[0]->dev, "Panasonic MN88473 successfully attached\n"); return 0; +err_client_2_i2c_unregister_device: + i2c_unregister_device(dev->client[2]); +err_regmap_1_regmap_exit: + regmap_exit(dev->regmap[1]); err_client_1_i2c_unregister_device: i2c_unregister_device(dev->client[1]); +err_regmap_0_regmap_exit: + regmap_exit(dev->regmap[0]); err_kfree: kfree(dev); err: @@ -491,9 +427,14 @@ static int mn88473_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); + regmap_exit(dev->regmap[2]); i2c_unregister_device(dev->client[2]); + + regmap_exit(dev->regmap[1]); i2c_unregister_device(dev->client[1]); + regmap_exit(dev->regmap[0]); + kfree(dev); return 0; diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h index 853043797656..78af112fb41d 100644 --- a/drivers/media/dvb-frontends/mn88473_priv.h +++ b/drivers/media/dvb-frontends/mn88473_priv.h @@ -20,11 +20,13 @@ #include "dvb_frontend.h" #include "mn88473.h" #include +#include #define MN88473_FIRMWARE "dvb-demod-mn88473-01.fw" struct mn88473_dev { struct i2c_client *client[3]; + struct regmap *regmap[3]; struct dvb_frontend fe; u16 i2c_wr_max; fe_delivery_system_t delivery_system; -- GitLab From 4f80d858818b70a8a4864f3350f54dbf6422ad7b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:51:44 -0300 Subject: [PATCH 4845/9457] [media] mn88473: move to staging It is not ready enough to be released on mainline. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 8 -------- drivers/media/dvb-frontends/Makefile | 1 - drivers/staging/media/Kconfig | 2 ++ drivers/staging/media/Makefile | 1 + drivers/staging/media/mn88473/Kconfig | 7 +++++++ drivers/staging/media/mn88473/Makefile | 5 +++++ .../dvb-frontends => staging/media/mn88473}/mn88473.c | 0 .../media/mn88473}/mn88473_priv.h | 0 8 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 drivers/staging/media/mn88473/Kconfig create mode 100644 drivers/staging/media/mn88473/Makefile rename drivers/{media/dvb-frontends => staging/media/mn88473}/mn88473.c (100%) rename drivers/{media/dvb-frontends => staging/media/mn88473}/mn88473_priv.h (100%) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index e60614b476a1..6c75418222e2 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -471,14 +471,6 @@ config DVB_SI2168 help Say Y when you want to support this frontend. -config DVB_MN88473 - tristate "Panasonic MN88473" - depends on DVB_CORE && I2C - select REGMAP_I2C - default m if !MEDIA_SUBDRV_AUTOSELECT - help - Say Y when you want to support this frontend. - config DVB_AS102_FE tristate depends on DVB_CORE diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 8be6eb0d440d..ba59df63d050 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -113,7 +113,6 @@ obj-$(CONFIG_DVB_RTL2830) += rtl2830.o obj-$(CONFIG_DVB_RTL2832) += rtl2832.o obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o -obj-$(CONFIG_DVB_MN88473) += mn88473.o obj-$(CONFIG_DVB_AF9033) += af9033.o obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o obj-$(CONFIG_DVB_TC90522) += tc90522.o diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index c2e675aa22c5..273c44c41a33 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -29,6 +29,8 @@ source "drivers/staging/media/dt3155v4l/Kconfig" source "drivers/staging/media/mn88472/Kconfig" +source "drivers/staging/media/mn88473/Kconfig" + source "drivers/staging/media/omap24xx/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index e174c57331e1..bb2180083b22 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/ obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/ obj-$(CONFIG_DVB_MN88472) += mn88472/ +obj-$(CONFIG_DVB_MN88473) += mn88473/ diff --git a/drivers/staging/media/mn88473/Kconfig b/drivers/staging/media/mn88473/Kconfig new file mode 100644 index 000000000000..6c9ebf51c2c7 --- /dev/null +++ b/drivers/staging/media/mn88473/Kconfig @@ -0,0 +1,7 @@ +config DVB_MN88473 + tristate "Panasonic MN88473" + depends on DVB_CORE && I2C + select REGMAP_I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + Say Y when you want to support this frontend. diff --git a/drivers/staging/media/mn88473/Makefile b/drivers/staging/media/mn88473/Makefile new file mode 100644 index 000000000000..fac55410ce55 --- /dev/null +++ b/drivers/staging/media/mn88473/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_DVB_MN88473) += mn88473.o + +ccflags-y += -Idrivers/media/dvb-core/ +ccflags-y += -Idrivers/media/dvb-frontends/ +ccflags-y += -Idrivers/media/tuners/ diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/staging/media/mn88473/mn88473.c similarity index 100% rename from drivers/media/dvb-frontends/mn88473.c rename to drivers/staging/media/mn88473/mn88473.c diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/staging/media/mn88473/mn88473_priv.h similarity index 100% rename from drivers/media/dvb-frontends/mn88473_priv.h rename to drivers/staging/media/mn88473/mn88473_priv.h -- GitLab From 0c5d216d567638b173cfdcb8926a801a10a707d5 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:52:50 -0300 Subject: [PATCH 4846/9457] [media] mn88473: add staging TODO Add TODO for mainlining. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/mn88473/TODO | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 drivers/staging/media/mn88473/TODO diff --git a/drivers/staging/media/mn88473/TODO b/drivers/staging/media/mn88473/TODO new file mode 100644 index 000000000000..b90a14be3beb --- /dev/null +++ b/drivers/staging/media/mn88473/TODO @@ -0,0 +1,21 @@ +Driver general quality is not good enough for mainline. Also, other +device drivers (USB-bridge, tuner) needed for Astrometa receiver in +question could need some changes. However, if that driver is mainlined +due to some other device than Astrometa, unrelated TODOs could be +skipped. In that case rtl28xxu driver needs module parameter to prevent +driver loading. + +Required TODOs: +* missing lock flags +* I2C errors +* tuner sensitivity + +*Do not* send any patch fixing checkpatch.pl issues. Currently it passes +checkpatch.pl tests. I don't want waste my time to review this kind of +trivial stuff. *Do not* add missing register I/O error checks. Those are +missing for the reason it is much easier to compare I2C data sniffs when +there is less lines. Those error checks are about the last thing to be added. + +Patches should be submitted to: +linux-media@vger.kernel.org and Antti Palosaari + -- GitLab From 4f4d238f81d3edf4ed019f3873cd49733471410f Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 12 Nov 2014 00:53:57 -0300 Subject: [PATCH 4847/9457] [media] MAINTAINERS: add mn88473 (Panasonic MN88473) Add mn88473 driver from staging. DVB-T/T2/C demodulator driver. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 644a1aecf44a..a6288cacde10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6126,6 +6126,17 @@ S: Maintained F: drivers/staging/media/mn88472/ F: drivers/media/dvb-frontends/mn88472.h +MN88473 MEDIA DRIVER +M: Antti Palosaari +L: linux-media@vger.kernel.org +W: http://linuxtv.org/ +W: http://palosaari.fi/linux/ +Q: http://patchwork.linuxtv.org/project/linux-media/list/ +T: git git://linuxtv.org/anttip/media_tree.git +S: Maintained +F: drivers/staging/media/mn88473/ +F: drivers/media/dvb-frontends/mn88473.h + MODULE SUPPORT M: Rusty Russell S: Maintained -- GitLab From b936d166080cf29ca300116add30826fbfd8c0e7 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 28 Nov 2013 14:11:33 -0300 Subject: [PATCH 4848/9457] [media] r820t: add DVB-C config Add config values for SYS_DVBC_ANNEX_A. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/r820t.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index a759742cae7b..8e040cf9cf13 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c @@ -959,6 +959,18 @@ static int r820t_set_tv_standard(struct r820t_priv *priv, lt_att = 0x00; /* r31[7], lt att enable */ flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */ polyfil_cur = 0x60; /* r25[6:5]:min */ + } else if (delsys == SYS_DVBC_ANNEX_A) { + if_khz = 5070; + filt_cal_lo = 73500; + filt_gain = 0x10; /* +3db, 6mhz on */ + img_r = 0x00; /* image negative */ + filt_q = 0x10; /* r10[4]:low q(1'b1) */ + hp_cor = 0x0b; /* 1.7m disable, +0cap, 1.0mhz */ + ext_enable = 0x40; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */ + loop_through = 0x00; /* r5[7], lt on */ + lt_att = 0x00; /* r31[7], lt att enable */ + flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */ + polyfil_cur = 0x60; /* r25[6:5]:min */ } else { if (bw <= 6) { if_khz = 3570; -- GitLab From 698f6260b886291e14706c57daec2e1560d59af5 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 27 Sep 2014 01:22:45 -0300 Subject: [PATCH 4849/9457] [media] rtl28xxu: enable demod ADC only when needed Enable integrated demod ADC only when demod is used. Keep integrated demod ADC disabled when external demod is used. This fixes corrupted stream in a case external demod was used. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 37 +++++++++++++++++-------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 27b1e0397e71..5ea52c7616f1 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1201,13 +1201,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) if (ret) goto err; - mdelay(5); - - /* enable ADC */ - ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48); - if (ret) - goto err; - /* streaming EP: clear stall & reset */ ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2); if (ret) @@ -1222,11 +1215,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) if (ret) goto err; - /* disable ADC */ - ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48); - if (ret) - goto err; - /* disable PLL */ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80); if (ret) @@ -1244,6 +1232,30 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) return ret; } +static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_device *d = fe_to_d(fe); + int ret; + u8 val; + + dev_dbg(&d->udev->dev, "%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); + + /* control internal demod ADC */ + if (fe->id == 0 && onoff) + val = 0x48; /* enable ADC */ + else + val = 0x00; /* disable ADC */ + + ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, val, 0x48); + if (ret) + goto err; + + return 0; +err: + dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + #if IS_ENABLED(CONFIG_RC_CORE) static int rtl2831u_rc_query(struct dvb_usb_device *d) { @@ -1467,6 +1479,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = { .size_of_priv = sizeof(struct rtl28xxu_priv), .power_ctrl = rtl2832u_power_ctrl, + .frontend_ctrl = rtl2832u_frontend_ctrl, .i2c_algo = &rtl28xxu_i2c_algo, .read_config = rtl2832u_read_config, .frontend_attach = rtl2832u_frontend_attach, -- GitLab From edcf58bc031e621f519c9dfce3c7e1ea6880c70a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:26 -0300 Subject: [PATCH 4850/9457] [media] Move mediabus format definition to a more standard place Define MEDIA_BUS_FMT macros (re-using the values defined in the v4l2_mbus_pixelcode enum) into a separate header file so that they can be used from the DRM/KMS subsystem without any reference to the V4L2 subsystem. Then set V4L2_MBUS_FMT definitions to the MEDIA_BUS_FMT values using the V4L2_MBUS_FROM_MEDIA_BUS_FMT macro. Signed-off-by: Boris Brezillon Acked-by: Guennadi Liakhovetski Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/Kbuild | 1 + include/uapi/linux/media-bus-format.h | 125 +++++++++++++++++ include/uapi/linux/v4l2-mediabus.h | 184 +++++++++++--------------- 3 files changed, 206 insertions(+), 104 deletions(-) create mode 100644 include/uapi/linux/media-bus-format.h diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index b70237e8bc37..ed39ac84c0f4 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -241,6 +241,7 @@ header-y += map_to_7segment.h header-y += matroxfb.h header-y += mdio.h header-y += media.h +header-y += media-bus-format.h header-y += mei.h header-y += memfd.h header-y += mempolicy.h diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h new file mode 100644 index 000000000000..23b40908be30 --- /dev/null +++ b/include/uapi/linux/media-bus-format.h @@ -0,0 +1,125 @@ +/* + * Media Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_MEDIA_BUS_FORMAT_H +#define __LINUX_MEDIA_BUS_FORMAT_H + +/* + * These bus formats uniquely identify data formats on the data bus. Format 0 + * is reserved, MEDIA_BUS_FMT_FIXED shall be used by host-client pairs, where + * the data format is fixed. Additionally, "2X8" means that one pixel is + * transferred in two 8-bit samples, "BE" or "LE" specify in which order those + * samples are transferred over the bus: "LE" means that the least significant + * bits are transferred first, "BE" means that the most significant bits are + * transferred first, and "PADHI" and "PADLO" define which bits - low or high, + * in the incomplete high byte, are filled with padding bits. + * + * The bus formats are grouped by type, bus_width, bits per component, samples + * per pixel and order of subsamples. Numerical values are sorted using generic + * numerical sort order (8 thus comes before 10). + * + * As their value can't change when a new bus format is inserted in the + * enumeration, the bus formats are explicitly given a numerical value. The next + * free values for each category are listed below, update them when inserting + * new pixel codes. + */ + +#define MEDIA_BUS_FMT_FIXED 0x0001 + +/* RGB - next is 0x100e */ +#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 +#define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 +#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003 +#define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004 +#define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005 +#define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006 +#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 +#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008 +#define MEDIA_BUS_FMT_RGB666_1X18 0x1009 +#define MEDIA_BUS_FMT_RGB888_1X24 0x100a +#define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b +#define MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c +#define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d + +/* YUV (including grey) - next is 0x2024 */ +#define MEDIA_BUS_FMT_Y8_1X8 0x2001 +#define MEDIA_BUS_FMT_UV8_1X8 0x2015 +#define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 +#define MEDIA_BUS_FMT_VYUY8_1_5X8 0x2003 +#define MEDIA_BUS_FMT_YUYV8_1_5X8 0x2004 +#define MEDIA_BUS_FMT_YVYU8_1_5X8 0x2005 +#define MEDIA_BUS_FMT_UYVY8_2X8 0x2006 +#define MEDIA_BUS_FMT_VYUY8_2X8 0x2007 +#define MEDIA_BUS_FMT_YUYV8_2X8 0x2008 +#define MEDIA_BUS_FMT_YVYU8_2X8 0x2009 +#define MEDIA_BUS_FMT_Y10_1X10 0x200a +#define MEDIA_BUS_FMT_UYVY10_2X10 0x2018 +#define MEDIA_BUS_FMT_VYUY10_2X10 0x2019 +#define MEDIA_BUS_FMT_YUYV10_2X10 0x200b +#define MEDIA_BUS_FMT_YVYU10_2X10 0x200c +#define MEDIA_BUS_FMT_Y12_1X12 0x2013 +#define MEDIA_BUS_FMT_UYVY8_1X16 0x200f +#define MEDIA_BUS_FMT_VYUY8_1X16 0x2010 +#define MEDIA_BUS_FMT_YUYV8_1X16 0x2011 +#define MEDIA_BUS_FMT_YVYU8_1X16 0x2012 +#define MEDIA_BUS_FMT_YDYUYDYV8_1X16 0x2014 +#define MEDIA_BUS_FMT_UYVY10_1X20 0x201a +#define MEDIA_BUS_FMT_VYUY10_1X20 0x201b +#define MEDIA_BUS_FMT_YUYV10_1X20 0x200d +#define MEDIA_BUS_FMT_YVYU10_1X20 0x200e +#define MEDIA_BUS_FMT_YUV10_1X30 0x2016 +#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 +#define MEDIA_BUS_FMT_UYVY12_2X12 0x201c +#define MEDIA_BUS_FMT_VYUY12_2X12 0x201d +#define MEDIA_BUS_FMT_YUYV12_2X12 0x201e +#define MEDIA_BUS_FMT_YVYU12_2X12 0x201f +#define MEDIA_BUS_FMT_UYVY12_1X24 0x2020 +#define MEDIA_BUS_FMT_VYUY12_1X24 0x2021 +#define MEDIA_BUS_FMT_YUYV12_1X24 0x2022 +#define MEDIA_BUS_FMT_YVYU12_1X24 0x2023 + +/* Bayer - next is 0x3019 */ +#define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 +#define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 +#define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 +#define MEDIA_BUS_FMT_SRGGB8_1X8 0x3014 +#define MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 0x3015 +#define MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 0x3016 +#define MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 0x3017 +#define MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 0x3018 +#define MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 0x300b +#define MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 0x300c +#define MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 0x3009 +#define MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 0x300d +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE 0x3003 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE 0x3004 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE 0x3005 +#define MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE 0x3006 +#define MEDIA_BUS_FMT_SBGGR10_1X10 0x3007 +#define MEDIA_BUS_FMT_SGBRG10_1X10 0x300e +#define MEDIA_BUS_FMT_SGRBG10_1X10 0x300a +#define MEDIA_BUS_FMT_SRGGB10_1X10 0x300f +#define MEDIA_BUS_FMT_SBGGR12_1X12 0x3008 +#define MEDIA_BUS_FMT_SGBRG12_1X12 0x3010 +#define MEDIA_BUS_FMT_SGRBG12_1X12 0x3011 +#define MEDIA_BUS_FMT_SRGGB12_1X12 0x3012 + +/* JPEG compressed formats - next is 0x4002 */ +#define MEDIA_BUS_FMT_JPEG_1X8 0x4001 + +/* Vendor specific formats - next is 0x5002 */ + +/* S5C73M3 sensor specific interleaved UYVY and JPEG */ +#define MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 0x5001 + +/* HSV - next is 0x6002 */ +#define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001 + +#endif /* __LINUX_MEDIA_BUS_FORMAT_H */ diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index 1445e858854f..26180844c6b8 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h @@ -11,120 +11,96 @@ #ifndef __LINUX_V4L2_MEDIABUS_H #define __LINUX_V4L2_MEDIABUS_H +#include #include #include -/* - * These pixel codes uniquely identify data formats on the media bus. Mostly - * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is - * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the - * data format is fixed. Additionally, "2X8" means that one pixel is transferred - * in two 8-bit samples, "BE" or "LE" specify in which order those samples are - * transferred over the bus: "LE" means that the least significant bits are - * transferred first, "BE" means that the most significant bits are transferred - * first, and "PADHI" and "PADLO" define which bits - low or high, in the - * incomplete high byte, are filled with padding bits. - * - * The pixel codes are grouped by type, bus_width, bits per component, samples - * per pixel and order of subsamples. Numerical values are sorted using generic - * numerical sort order (8 thus comes before 10). - * - * As their value can't change when a new pixel code is inserted in the - * enumeration, the pixel codes are explicitly given a numerical value. The next - * free values for each category are listed below, update them when inserting - * new pixel codes. - */ -enum v4l2_mbus_pixelcode { - V4L2_MBUS_FMT_FIXED = 0x0001, +#define V4L2_MBUS_FROM_MEDIA_BUS_FMT(name) \ + V4L2_MBUS_FMT_ ## name = MEDIA_BUS_FMT_ ## name - /* RGB - next is 0x100e */ - V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001, - V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002, - V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003, - V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004, - V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005, - V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006, - V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, - V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, - V4L2_MBUS_FMT_RGB666_1X18 = 0x1009, - V4L2_MBUS_FMT_RGB888_1X24 = 0x100a, - V4L2_MBUS_FMT_RGB888_2X12_BE = 0x100b, - V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c, - V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d, +enum v4l2_mbus_pixelcode { + V4L2_MBUS_FROM_MEDIA_BUS_FMT(FIXED), - /* YUV (including grey) - next is 0x2024 */ - V4L2_MBUS_FMT_Y8_1X8 = 0x2001, - V4L2_MBUS_FMT_UV8_1X8 = 0x2015, - V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, - V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, - V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004, - V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005, - V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006, - V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007, - V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008, - V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009, - V4L2_MBUS_FMT_Y10_1X10 = 0x200a, - V4L2_MBUS_FMT_UYVY10_2X10 = 0x2018, - V4L2_MBUS_FMT_VYUY10_2X10 = 0x2019, - V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, - V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, - V4L2_MBUS_FMT_Y12_1X12 = 0x2013, - V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, - V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, - V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, - V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, - V4L2_MBUS_FMT_YDYUYDYV8_1X16 = 0x2014, - V4L2_MBUS_FMT_UYVY10_1X20 = 0x201a, - V4L2_MBUS_FMT_VYUY10_1X20 = 0x201b, - V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, - V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, - V4L2_MBUS_FMT_YUV10_1X30 = 0x2016, - V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017, - V4L2_MBUS_FMT_UYVY12_2X12 = 0x201c, - V4L2_MBUS_FMT_VYUY12_2X12 = 0x201d, - V4L2_MBUS_FMT_YUYV12_2X12 = 0x201e, - V4L2_MBUS_FMT_YVYU12_2X12 = 0x201f, - V4L2_MBUS_FMT_UYVY12_1X24 = 0x2020, - V4L2_MBUS_FMT_VYUY12_1X24 = 0x2021, - V4L2_MBUS_FMT_YUYV12_1X24 = 0x2022, - V4L2_MBUS_FMT_YVYU12_1X24 = 0x2023, + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB444_2X8_PADHI_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB444_2X8_PADHI_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB555_2X8_PADHI_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB555_2X8_PADHI_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(BGR565_2X8_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(BGR565_2X8_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB565_2X8_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB565_2X8_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB666_1X18), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_1X24), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_2X12_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(RGB888_2X12_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(ARGB8888_1X32), - /* Bayer - next is 0x3019 */ - V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, - V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013, - V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, - V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014, - V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8 = 0x3015, - V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8 = 0x3016, - V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8 = 0x3017, - V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8 = 0x3018, - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, - V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, - V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d, - V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003, - V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004, - V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005, - V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006, - V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007, - V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e, - V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a, - V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f, - V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008, - V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010, - V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011, - V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012, + V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UV8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_1_5X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_1_5X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_1_5X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_1_5X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_2X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_2X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_2X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_2X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y10_1X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY10_2X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY10_2X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV10_2X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU10_2X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(Y12_1X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY8_1X16), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY8_1X16), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV8_1X16), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU8_1X16), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YDYUYDYV8_1X16), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY10_1X20), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY10_1X20), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV10_1X20), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU10_1X20), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUV10_1X30), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(AYUV8_1X32), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY12_2X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY12_2X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV12_2X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU12_2X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(UYVY12_1X24), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(VYUY12_1X24), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YUYV12_1X24), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(YVYU12_1X24), - /* JPEG compressed formats - next is 0x4002 */ - V4L2_MBUS_FMT_JPEG_1X8 = 0x4001, + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_ALAW8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_ALAW8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_ALAW8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_ALAW8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_DPCM8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_DPCM8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_DPCM8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_DPCM8_1X8), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADHI_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADHI_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADLO_BE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_2X8_PADLO_LE), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR10_1X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG10_1X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG10_1X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB10_1X10), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SBGGR12_1X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGBRG12_1X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SGRBG12_1X12), + V4L2_MBUS_FROM_MEDIA_BUS_FMT(SRGGB12_1X12), - /* Vendor specific formats - next is 0x5002 */ + V4L2_MBUS_FROM_MEDIA_BUS_FMT(JPEG_1X8), - /* S5C73M3 sensor specific interleaved UYVY and JPEG */ - V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 = 0x5001, + V4L2_MBUS_FROM_MEDIA_BUS_FMT(S5C_UYVY_JPEG_1X8), - /* HSV - next is 0x6002 */ - V4L2_MBUS_FMT_AHSV8888_1X32 = 0x6001, + V4L2_MBUS_FROM_MEDIA_BUS_FMT(AHSV8888_1X32), }; /** -- GitLab From 55b8cbf75fe714f283073048b560d30a0af13473 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:27 -0300 Subject: [PATCH 4851/9457] [media] v4l: Update subdev-formats doc with new MEDIA_BUS_FMT values In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed them with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Update the v4l documentation accordingly. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/subdev-formats.xml | 308 +++++++++--------- 1 file changed, 154 insertions(+), 154 deletions(-) diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml index b2d5a0363cba..18730b96e1e6 100644 --- a/Documentation/DocBook/media/v4l/subdev-formats.xml +++ b/Documentation/DocBook/media/v4l/subdev-formats.xml @@ -86,7 +86,7 @@ green and 5-bit blue values padded on the high bit, transferred as 2 8-bit samples per pixel with the most significant bits (padding, red and half of the green value) transferred first will be named - V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE. + MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE. The following tables list existing packed RGB formats. @@ -176,8 +176,8 @@ - - V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE + + MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 &dash-ent-24; @@ -204,8 +204,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE + + MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 &dash-ent-24; @@ -232,8 +232,8 @@ r1 r0 - - V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE + + MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003 &dash-ent-24; @@ -260,8 +260,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE + + MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004 &dash-ent-24; @@ -288,8 +288,8 @@ g4 g3 - - V4L2_MBUS_FMT_BGR565_2X8_BE + + MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005 &dash-ent-24; @@ -316,8 +316,8 @@ r1 r0 - - V4L2_MBUS_FMT_BGR565_2X8_LE + + MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006 &dash-ent-24; @@ -344,8 +344,8 @@ g4 g3 - - V4L2_MBUS_FMT_RGB565_2X8_BE + + MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 &dash-ent-24; @@ -372,8 +372,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB565_2X8_LE + + MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008 &dash-ent-24; @@ -400,8 +400,8 @@ g4 g3 - - V4L2_MBUS_FMT_RGB666_1X18 + + MEDIA_BUS_FMT_RGB666_1X18 0x1009 &dash-ent-14; @@ -424,8 +424,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB888_1X24 + + MEDIA_BUS_FMT_RGB888_1X24 0x100a &dash-ent-8; @@ -454,8 +454,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB888_2X12_BE + + MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b &dash-ent-20; @@ -490,8 +490,8 @@ b1 b0 - - V4L2_MBUS_FMT_RGB888_2X12_LE + + MEDIA_BUS_FMT_RGB888_2X12_LE 0x100c &dash-ent-20; @@ -526,8 +526,8 @@ g5 g4 - - V4L2_MBUS_FMT_ARGB888_1X32 + + MEDIA_BUS_FMT_ARGB888_1X32 0x100d a7 @@ -600,7 +600,7 @@ For instance, a format with uncompressed 10-bit Bayer components arranged in a red, green, green, blue pattern transferred as 2 8-bit samples per pixel with the least significant bits transferred first will - be named V4L2_MBUS_FMT_SRGGB10_2X8_PADHI_LE. + be named MEDIA_BUS_FMT_SRGGB10_2X8_PADHI_LE.
@@ -663,8 +663,8 @@ - - V4L2_MBUS_FMT_SBGGR8_1X8 + + MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 - @@ -680,8 +680,8 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG8_1X8 + + MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 - @@ -697,8 +697,8 @@ g1 g0 - - V4L2_MBUS_FMT_SGRBG8_1X8 + + MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 - @@ -714,8 +714,8 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB8_1X8 + + MEDIA_BUS_FMT_SRGGB8_1X8 0x3014 - @@ -731,8 +731,8 @@ r1 r0 - - V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8 + + MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 0x3015 - @@ -748,8 +748,8 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8 + + MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 0x3016 - @@ -765,8 +765,8 @@ g1 g0 - - V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8 + + MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 0x3017 - @@ -782,8 +782,8 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8 + + MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 0x3018 - @@ -799,8 +799,8 @@ r1 r0 - - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 + + MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 0x300b - @@ -816,8 +816,8 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 + + MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 0x300c - @@ -833,8 +833,8 @@ g1 g0 - - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 + + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 0x3009 - @@ -850,8 +850,8 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 + + MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 0x300d - @@ -867,8 +867,8 @@ r1 r0 - - V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE + + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE 0x3003 - @@ -901,8 +901,8 @@ b1 b0 - - V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE + + MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE 0x3004 - @@ -935,8 +935,8 @@ b9 b8 - - V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE + + MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE 0x3005 - @@ -969,8 +969,8 @@ 0 0 - - V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE + + MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE 0x3006 - @@ -1003,8 +1003,8 @@ b3 b2 - - V4L2_MBUS_FMT_SBGGR10_1X10 + + MEDIA_BUS_FMT_SBGGR10_1X10 0x3007 - @@ -1020,8 +1020,8 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG10_1X10 + + MEDIA_BUS_FMT_SGBRG10_1X10 0x300e - @@ -1037,8 +1037,8 @@ g1 g0 - - V4L2_MBUS_FMT_SGRBG10_1X10 + + MEDIA_BUS_FMT_SGRBG10_1X10 0x300a - @@ -1054,8 +1054,8 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB10_1X10 + + MEDIA_BUS_FMT_SRGGB10_1X10 0x300f - @@ -1071,8 +1071,8 @@ r1 r0 - - V4L2_MBUS_FMT_SBGGR12_1X12 + + MEDIA_BUS_FMT_SBGGR12_1X12 0x3008 b11 @@ -1088,8 +1088,8 @@ b1 b0 - - V4L2_MBUS_FMT_SGBRG12_1X12 + + MEDIA_BUS_FMT_SGBRG12_1X12 0x3010 g11 @@ -1105,8 +1105,8 @@ g1 g0 - - V4L2_MBUS_FMT_SGRBG12_1X12 + + MEDIA_BUS_FMT_SGRBG12_1X12 0x3011 g11 @@ -1122,8 +1122,8 @@ g1 g0 - - V4L2_MBUS_FMT_SRGGB12_1X12 + + MEDIA_BUS_FMT_SRGGB12_1X12 0x3012 r11 @@ -1175,7 +1175,7 @@ For instance, a format where pixels are encoded as 8-bit YUV values downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in the - U, Y, V, Y order will be named V4L2_MBUS_FMT_UYVY8_2X8. + U, Y, V, Y order will be named MEDIA_BUS_FMT_UYVY8_2X8. lists existing packed YUV @@ -1280,8 +1280,8 @@ - - V4L2_MBUS_FMT_Y8_1X8 + + MEDIA_BUS_FMT_Y8_1X8 0x2001 &dash-ent-24; @@ -1294,8 +1294,8 @@ y1 y0 - - V4L2_MBUS_FMT_UV8_1X8 + + MEDIA_BUS_FMT_UV8_1X8 0x2015 &dash-ent-24; @@ -1322,8 +1322,8 @@ v1 v0 - - V4L2_MBUS_FMT_UYVY8_1_5X8 + + MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 &dash-ent-24; @@ -1406,8 +1406,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY8_1_5X8 + + MEDIA_BUS_FMT_VYUY8_1_5X8 0x2003 &dash-ent-24; @@ -1490,8 +1490,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV8_1_5X8 + + MEDIA_BUS_FMT_YUYV8_1_5X8 0x2004 &dash-ent-24; @@ -1574,8 +1574,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU8_1_5X8 + + MEDIA_BUS_FMT_YVYU8_1_5X8 0x2005 &dash-ent-24; @@ -1658,8 +1658,8 @@ u1 u0 - - V4L2_MBUS_FMT_UYVY8_2X8 + + MEDIA_BUS_FMT_UYVY8_2X8 0x2006 &dash-ent-24; @@ -1714,8 +1714,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY8_2X8 + + MEDIA_BUS_FMT_VYUY8_2X8 0x2007 &dash-ent-24; @@ -1770,8 +1770,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV8_2X8 + + MEDIA_BUS_FMT_YUYV8_2X8 0x2008 &dash-ent-24; @@ -1826,8 +1826,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU8_2X8 + + MEDIA_BUS_FMT_YVYU8_2X8 0x2009 &dash-ent-24; @@ -1882,8 +1882,8 @@ u1 u0 - - V4L2_MBUS_FMT_Y10_1X10 + + MEDIA_BUS_FMT_Y10_1X10 0x200a &dash-ent-22; @@ -1898,8 +1898,8 @@ y1 y0 - - V4L2_MBUS_FMT_UYVY10_2X10 + + MEDIA_BUS_FMT_UYVY10_2X10 0x2018 &dash-ent-22; @@ -1962,8 +1962,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY10_2X10 + + MEDIA_BUS_FMT_VYUY10_2X10 0x2019 &dash-ent-22; @@ -2026,8 +2026,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV10_2X10 + + MEDIA_BUS_FMT_YUYV10_2X10 0x200b &dash-ent-22; @@ -2090,8 +2090,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU10_2X10 + + MEDIA_BUS_FMT_YVYU10_2X10 0x200c &dash-ent-22; @@ -2154,8 +2154,8 @@ u1 u0 - - V4L2_MBUS_FMT_Y12_1X12 + + MEDIA_BUS_FMT_Y12_1X12 0x2013 &dash-ent-20; @@ -2172,8 +2172,8 @@ y1 y0 - - V4L2_MBUS_FMT_UYVY8_1X16 + + MEDIA_BUS_FMT_UYVY8_1X16 0x200f &dash-ent-16; @@ -2216,8 +2216,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY8_1X16 + + MEDIA_BUS_FMT_VYUY8_1X16 0x2010 &dash-ent-16; @@ -2260,8 +2260,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV8_1X16 + + MEDIA_BUS_FMT_YUYV8_1X16 0x2011 &dash-ent-16; @@ -2304,8 +2304,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU8_1X16 + + MEDIA_BUS_FMT_YVYU8_1X16 0x2012 &dash-ent-16; @@ -2348,8 +2348,8 @@ u1 u0 - - V4L2_MBUS_FMT_YDYUYDYV8_1X16 + + MEDIA_BUS_FMT_YDYUYDYV8_1X16 0x2014 &dash-ent-16; @@ -2436,8 +2436,8 @@ v1 v0 - - V4L2_MBUS_FMT_UYVY10_1X20 + + MEDIA_BUS_FMT_UYVY10_1X20 0x201a &dash-ent-12; @@ -2488,8 +2488,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY10_1X20 + + MEDIA_BUS_FMT_VYUY10_1X20 0x201b &dash-ent-12; @@ -2540,8 +2540,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV10_1X20 + + MEDIA_BUS_FMT_YUYV10_1X20 0x200d &dash-ent-12; @@ -2592,8 +2592,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU10_1X20 + + MEDIA_BUS_FMT_YVYU10_1X20 0x200e &dash-ent-12; @@ -2644,8 +2644,8 @@ u1 u0 - - V4L2_MBUS_FMT_YUV10_1X30 + + MEDIA_BUS_FMT_YUV10_1X30 0x2016 - @@ -2681,8 +2681,8 @@ v1 v0 - - V4L2_MBUS_FMT_AYUV8_1X32 + + MEDIA_BUS_FMT_AYUV8_1X32 0x2017 a7 @@ -2718,8 +2718,8 @@ v1 v0 - - V4L2_MBUS_FMT_UYVY12_2X12 + + MEDIA_BUS_FMT_UYVY12_2X12 0x201c &dash-ent-20; @@ -2790,8 +2790,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY12_2X12 + + MEDIA_BUS_FMT_VYUY12_2X12 0x201d &dash-ent-20; @@ -2862,8 +2862,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV12_2X12 + + MEDIA_BUS_FMT_YUYV12_2X12 0x201e &dash-ent-20; @@ -2934,8 +2934,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU12_2X12 + + MEDIA_BUS_FMT_YVYU12_2X12 0x201f &dash-ent-20; @@ -3006,8 +3006,8 @@ u1 u0 - - V4L2_MBUS_FMT_UYVY12_1X24 + + MEDIA_BUS_FMT_UYVY12_1X24 0x2020 &dash-ent-8; @@ -3066,8 +3066,8 @@ y1 y0 - - V4L2_MBUS_FMT_VYUY12_1X24 + + MEDIA_BUS_FMT_VYUY12_1X24 0x2021 &dash-ent-8; @@ -3126,8 +3126,8 @@ y1 y0 - - V4L2_MBUS_FMT_YUYV12_1X24 + + MEDIA_BUS_FMT_YUYV12_1X24 0x2022 &dash-ent-8; @@ -3186,8 +3186,8 @@ v1 v0 - - V4L2_MBUS_FMT_YVYU12_1X24 + + MEDIA_BUS_FMT_YVYU12_1X24 0x2023 &dash-ent-8; @@ -3366,8 +3366,8 @@ - - V4L2_MBUS_FMT_AHSV8888_1X32 + + MEDIA_BUS_FMT_AHSV8888_1X32 0x6001 a7 @@ -3422,7 +3422,7 @@ For instance, for a JPEG baseline process and an 8-bit bus width - the format will be named V4L2_MBUS_FMT_JPEG_1X8. + the format will be named MEDIA_BUS_FMT_JPEG_1X8. The following table lists existing JPEG compressed formats. @@ -3441,8 +3441,8 @@ - - V4L2_MBUS_FMT_JPEG_1X8 + + MEDIA_BUS_FMT_JPEG_1X8 0x4001 Besides of its usage for the parallel bus this format is recommended for transmission of JPEG data over MIPI CSI bus @@ -3484,8 +3484,8 @@ interface and may change in the future. - - V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 + + MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 0x5001 Interleaved raw UYVY and JPEG image format with embedded -- GitLab From 32b32ce84a02d5e3538941e71d2792ebbef8f795 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:28 -0300 Subject: [PATCH 4852/9457] [media] Make use of the new media_bus_format definitions Replace references to the v4l2_mbus_pixelcode enum with the new media_bus_format enum in all common headers. Signed-off-by: Boris Brezillon Acked-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mediabus.h | 2 +- include/media/v4l2-subdev.h | 2 +- include/uapi/linux/v4l2-subdev.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 395c4a95a42a..59d7397fb0ea 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -98,7 +98,7 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, const struct v4l2_pix_format *pix_fmt, - enum v4l2_mbus_pixelcode code) + u32 code) { mbus_fmt->width = pix_fmt->width; mbus_fmt->height = pix_fmt->height; diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index d7465725773d..5860292d42eb 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -341,7 +341,7 @@ struct v4l2_subdev_video_ops { int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code); + u32 *code); int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); int (*g_mbus_fmt)(struct v4l2_subdev *sd, diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index a619cdd300ac..e0a7e3da498a 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -68,7 +68,7 @@ struct v4l2_subdev_crop { * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration * @pad: pad number, as reported by the media API * @index: format index during enumeration - * @code: format code (from enum v4l2_mbus_pixelcode) + * @code: format code (MEDIA_BUS_FMT_ definitions) */ struct v4l2_subdev_mbus_code_enum { __u32 pad; @@ -81,7 +81,7 @@ struct v4l2_subdev_mbus_code_enum { * struct v4l2_subdev_frame_size_enum - Media bus format enumeration * @pad: pad number, as reported by the media API * @index: format index during enumeration - * @code: format code (from enum v4l2_mbus_pixelcode) + * @code: format code (MEDIA_BUS_FMT_ definitions) */ struct v4l2_subdev_frame_size_enum { __u32 index; @@ -109,7 +109,7 @@ struct v4l2_subdev_frame_interval { * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration * @pad: pad number, as reported by the media API * @index: frame interval index during enumeration - * @code: format code (from enum v4l2_mbus_pixelcode) + * @code: format code (MEDIA_BUS_FMT_ definitions) * @width: frame width in pixels * @height: frame height in pixels * @interval: frame interval in seconds -- GitLab From f5fe58fd76a0d8e0dc4b0e1d4d43c40baf800961 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:29 -0300 Subject: [PATCH 4853/9457] [media] i2c: Make use of media_bus_format enum In order to have subsytem agnostic media bus format definitions we've moved media bus definitions to include/uapi/linux/media-bus-format.h and prefixed values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Replace all references to the old definitions in i2c drivers. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7170.c | 16 ++--- drivers/media/i2c/adv7175.c | 16 ++--- drivers/media/i2c/adv7180.c | 6 +- drivers/media/i2c/adv7183.c | 6 +- drivers/media/i2c/adv7604.c | 72 +++++++++++------------ drivers/media/i2c/adv7842.c | 6 +- drivers/media/i2c/ak881x.c | 8 +-- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 6 +- drivers/media/i2c/ml86v7667.c | 6 +- drivers/media/i2c/mt9m032.c | 6 +- drivers/media/i2c/mt9p031.c | 8 +-- drivers/media/i2c/mt9t001.c | 8 +-- drivers/media/i2c/mt9v011.c | 6 +- drivers/media/i2c/mt9v032.c | 12 ++-- drivers/media/i2c/noon010pc30.c | 12 ++-- drivers/media/i2c/ov7670.c | 16 ++--- drivers/media/i2c/ov9650.c | 10 ++-- drivers/media/i2c/s5c73m3/s5c73m3.h | 6 +- drivers/media/i2c/s5k4ecgx.c | 4 +- drivers/media/i2c/s5k5baf.c | 14 ++--- drivers/media/i2c/s5k6a3.c | 2 +- drivers/media/i2c/s5k6aa.c | 8 +-- drivers/media/i2c/saa6752hs.c | 6 +- drivers/media/i2c/saa7115.c | 2 +- drivers/media/i2c/saa717x.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 32 +++++----- drivers/media/i2c/soc_camera/imx074.c | 8 +-- drivers/media/i2c/soc_camera/mt9m001.c | 14 ++--- drivers/media/i2c/soc_camera/mt9m111.c | 70 +++++++++++----------- drivers/media/i2c/soc_camera/mt9t031.c | 10 ++-- drivers/media/i2c/soc_camera/mt9t112.c | 22 +++---- drivers/media/i2c/soc_camera/mt9v022.c | 26 ++++---- drivers/media/i2c/soc_camera/ov2640.c | 54 ++++++++--------- drivers/media/i2c/soc_camera/ov5642.c | 8 +-- drivers/media/i2c/soc_camera/ov6650.c | 58 +++++++++--------- drivers/media/i2c/soc_camera/ov772x.c | 20 +++---- drivers/media/i2c/soc_camera/ov9640.c | 40 ++++++------- drivers/media/i2c/soc_camera/ov9740.c | 12 ++-- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 54 ++++++++--------- drivers/media/i2c/soc_camera/tw9910.c | 10 ++-- drivers/media/i2c/sr030pc30.c | 14 ++--- drivers/media/i2c/tvp514x.c | 12 ++-- drivers/media/i2c/tvp5150.c | 6 +- drivers/media/i2c/tvp7002.c | 10 ++-- drivers/media/i2c/vs6624.c | 18 +++--- 46 files changed, 382 insertions(+), 382 deletions(-) diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index 04bb29720aaf..40a1a95c7ce9 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -63,9 +63,9 @@ static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd) static char *inputs[] = { "pass_through", "play_back" }; -static enum v4l2_mbus_pixelcode adv7170_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_1X16, +static u32 adv7170_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, }; /* ----------------------------------------------------------------------- */ @@ -263,7 +263,7 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, } static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(adv7170_codes)) return -EINVAL; @@ -278,9 +278,9 @@ static int adv7170_g_fmt(struct v4l2_subdev *sd, u8 val = adv7170_read(sd, 0x7); if ((val & 0x40) == (1 << 6)) - mf->code = V4L2_MBUS_FMT_UYVY8_1X16; + mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; mf->width = 0; @@ -297,11 +297,11 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd, int ret; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: val &= ~0x40; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: val |= 0x40; break; diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index b88f3b3d5ed9..d220af579a64 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -60,9 +60,9 @@ static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd) static char *inputs[] = { "pass_through", "play_back", "color_bar" }; -static enum v4l2_mbus_pixelcode adv7175_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_1X16, +static u32 adv7175_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_1X16, }; /* ----------------------------------------------------------------------- */ @@ -301,7 +301,7 @@ static int adv7175_s_routing(struct v4l2_subdev *sd, } static int adv7175_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(adv7175_codes)) return -EINVAL; @@ -316,9 +316,9 @@ static int adv7175_g_fmt(struct v4l2_subdev *sd, u8 val = adv7175_read(sd, 0x7); if ((val & 0x40) == (1 << 6)) - mf->code = V4L2_MBUS_FMT_UYVY8_1X16; + mf->code = MEDIA_BUS_FMT_UYVY8_1X16; else - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; mf->width = 0; @@ -335,11 +335,11 @@ static int adv7175_s_fmt(struct v4l2_subdev *sd, int ret; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: val &= ~0x40; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: val |= 0x40; break; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 821178dcb08e..bffe6eb528a3 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -422,12 +422,12 @@ static void adv7180_exit_controls(struct adv7180_state *state) } static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @@ -437,7 +437,7 @@ static int adv7180_mbus_fmt(struct v4l2_subdev *sd, { struct adv7180_state *state = to_state(sd); - fmt->code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; fmt->field = V4L2_FIELD_INTERLACED; fmt->width = 720; diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index df461b07b2f7..28940cc3a766 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -421,12 +421,12 @@ static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status) } static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -435,7 +435,7 @@ static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd, { struct adv7183 *decoder = to_adv7183(sd); - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; if (decoder->std & V4L2_STD_525_60) { fmt->field = V4L2_FIELD_SEQ_TB; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 22e550acd233..e43dd2e2a38a 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -88,7 +88,7 @@ struct adv7604_reg_seq { }; struct adv7604_format_info { - enum v4l2_mbus_pixelcode code; + u32 code; u8 op_ch_sel; bool rgb_out; bool swap_cb_cr; @@ -749,77 +749,77 @@ static void adv7604_write_reg_seq(struct v4l2_subdev *sd, */ static const struct adv7604_format_info adv7604_formats[] = { - { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, + { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, - { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, }; static const struct adv7604_format_info adv7611_formats[] = { - { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, + { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, - { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, + { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, + { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, + { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, - { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, + { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, }; static const struct adv7604_format_info * -adv7604_format_info(struct adv7604_state *state, enum v4l2_mbus_pixelcode code) +adv7604_format_info(struct adv7604_state *state, u32 code) { unsigned int i; @@ -1917,7 +1917,7 @@ static int adv7604_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, info = adv7604_format_info(state, format->format.code); if (info == NULL) - info = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); + info = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); adv7604_fill_format(state, &format->format); format->format.code = info->code; @@ -2806,7 +2806,7 @@ static int adv7604_probe(struct i2c_client *client, } state->timings = cea640x480; - state->format = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8); + state->format = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7604_ops); diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index bed0586f72eb..75d26dfd0939 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1877,12 +1877,12 @@ static int adv7842_s_routing(struct v4l2_subdev *sd, } static int adv7842_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; /* Good enough for now */ - *code = V4L2_MBUS_FMT_FIXED; + *code = MEDIA_BUS_FMT_FIXED; return 0; } @@ -1893,7 +1893,7 @@ static int adv7842_g_mbus_fmt(struct v4l2_subdev *sd, fmt->width = state->timings.bt.width; fmt->height = state->timings.bt.height; - fmt->code = V4L2_MBUS_FMT_FIXED; + fmt->code = MEDIA_BUS_FMT_FIXED; fmt->field = V4L2_FIELD_NONE; if (state->mode == ADV7842_MODE_SDP) { diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index c14e66756b98..69aeaf397624 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -102,7 +102,7 @@ static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd, v4l_bound_align_image(&mf->width, 0, 720, 2, &mf->height, 0, ak881x->lines, 1, 0); mf->field = V4L2_FIELD_INTERLACED; - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; @@ -112,19 +112,19 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { if (mf->field != V4L2_FIELD_INTERLACED || - mf->code != V4L2_MBUS_FMT_YUYV8_2X8) + mf->code != MEDIA_BUS_FMT_YUYV8_2X8) return -EINVAL; return ak881x_try_g_mbus_fmt(sd, mf); } static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 0327032cd1a7..573e08826b9b 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -1373,7 +1373,7 @@ static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 8d870b7b43ff..2820f7c38cba 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -57,14 +57,14 @@ static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = { [M5MOLS_RESTYPE_MONITOR] = { .width = 1920, .height = 1080, - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }, [M5MOLS_RESTYPE_CAPTURE] = { .width = 1920, .height = 1080, - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }, @@ -479,7 +479,7 @@ static int m5mols_get_version(struct v4l2_subdev *sd) * __find_restype - Lookup M-5MOLS resolution type according to pixel code * @code: pixel code */ -static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code) +static enum m5mols_restype __find_restype(u32 code) { enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR; diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index 2cace7313a22..d7307862c2c5 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c @@ -192,12 +192,12 @@ static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status) } static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV8_2X8; + *code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @@ -207,7 +207,7 @@ static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd, { struct ml86v7667_priv *priv = to_ml86v7667(sd); - fmt->code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; /* The top field is always transferred first by the chip */ fmt->field = V4L2_FIELD_INTERLACED_TB; diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c index 85ec3bacdf1c..45b3fca188ca 100644 --- a/drivers/media/i2c/mt9m032.c +++ b/drivers/media/i2c/mt9m032.c @@ -323,7 +323,7 @@ static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_Y8_1X8; + code->code = MEDIA_BUS_FMT_Y8_1X8; return 0; } @@ -331,7 +331,7 @@ static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8) + if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8) return -EINVAL; fse->min_width = MT9M032_COLUMN_SIZE_DEF; @@ -759,7 +759,7 @@ static int mt9m032_probe(struct i2c_client *client, sensor->format.width = sensor->crop.width; sensor->format.height = sensor->crop.height; - sensor->format.code = V4L2_MBUS_FMT_Y8_1X8; + sensor->format.code = MEDIA_BUS_FMT_Y8_1X8; sensor->format.field = V4L2_FIELD_NONE; sensor->format.colorspace = V4L2_COLORSPACE_SRGB; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index e18797ff7faf..edb76bd33d16 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -950,9 +950,9 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) format = v4l2_subdev_get_try_format(fh, 0); if (mt9p031->model == MT9P031_MODEL_MONOCHROME) - format->code = V4L2_MBUS_FMT_Y12_1X12; + format->code = MEDIA_BUS_FMT_Y12_1X12; else - format->code = V4L2_MBUS_FMT_SGRBG12_1X12; + format->code = MEDIA_BUS_FMT_SGRBG12_1X12; format->width = MT9P031_WINDOW_WIDTH_DEF; format->height = MT9P031_WINDOW_HEIGHT_DEF; @@ -1120,9 +1120,9 @@ static int mt9p031_probe(struct i2c_client *client, mt9p031->crop.top = MT9P031_ROW_START_DEF; if (mt9p031->model == MT9P031_MODEL_MONOCHROME) - mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12; + mt9p031->format.code = MEDIA_BUS_FMT_Y12_1X12; else - mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + mt9p031->format.code = MEDIA_BUS_FMT_SGRBG12_1X12; mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF; mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF; diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index 422e068f5f1b..d9e9889b579f 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c @@ -333,7 +333,7 @@ static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_SGRBG10_1X10; + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; return 0; } @@ -341,7 +341,7 @@ static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) + if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) return -EINVAL; fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index; @@ -792,7 +792,7 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; format = v4l2_subdev_get_try_format(fh, 0); - format->code = V4L2_MBUS_FMT_SGRBG10_1X10; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; format->width = MT9T001_WINDOW_WIDTH_DEF + 1; format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; format->field = V4L2_FIELD_NONE; @@ -917,7 +917,7 @@ static int mt9t001_probe(struct i2c_client *client, mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1; mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1; - mt9t001->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + mt9t001->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1; mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1; mt9t001->format.field = V4L2_FIELD_NONE; diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index 47e475319a24..a10f7f8f0558 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -325,18 +325,18 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) } static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index > 0) return -EINVAL; - *code = V4L2_MBUS_FMT_SGRBG8_1X8; + *code = MEDIA_BUS_FMT_SGRBG8_1X8; return 0; } static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8) + if (fmt->code != MEDIA_BUS_FMT_SGRBG8_1X8) return -EINVAL; v4l_bound_align_image(&fmt->width, 48, 639, 1, diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index d044bce312e0..93687c1e4097 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -454,7 +454,7 @@ static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_SGRBG10_1X10; + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; return 0; } @@ -462,7 +462,7 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= 3 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) + if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) return -EINVAL; fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index); @@ -814,9 +814,9 @@ static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) format = v4l2_subdev_get_try_format(fh, 0); if (mt9v032->model->color) - format->code = V4L2_MBUS_FMT_SGRBG10_1X10; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; else - format->code = V4L2_MBUS_FMT_Y10_1X10; + format->code = MEDIA_BUS_FMT_Y10_1X10; format->width = MT9V032_WINDOW_WIDTH_DEF; format->height = MT9V032_WINDOW_HEIGHT_DEF; @@ -966,9 +966,9 @@ static int mt9v032_probe(struct i2c_client *client, mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF; if (mt9v032->model->color) - mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + mt9v032->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; else - mt9v032->format.code = V4L2_MBUS_FMT_Y10_1X10; + mt9v032->format.code = MEDIA_BUS_FMT_Y10_1X10; mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF; mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF; diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 7eae48766e2b..00c7b26f4823 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -112,7 +112,7 @@ MODULE_PARM_DESC(debug, "Enable module debug trace. Set to 1 to enable."); #define REG_TERM 0xFFFF struct noon010_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 ispctl1_reg; }; @@ -175,23 +175,23 @@ static const struct noon010_frmsize noon010_sizes[] = { /* Supported pixel formats. */ static const struct noon010_format noon010_formats[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x03, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x02, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x01, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x40, }, diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index dd3db2458a4f..957927f7a353 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -632,31 +632,31 @@ static int ov7670_detect(struct v4l2_subdev *sd) * The magic matrix numbers come from OmniVision. */ static struct ov7670_format_struct { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; enum v4l2_colorspace colorspace; struct regval_list *regs; int cmatrix[CMATRIX_LEN]; } ov7670_formats[] = { { - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .regs = ov7670_fmt_yuv422, .cmatrix = { 128, -128, 0, -34, -94, 128 }, }, { - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_rgb444, .cmatrix = { 179, -179, 0, -61, -176, 228 }, }, { - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_rgb565, .cmatrix = { 179, -179, 0, -61, -176, 228 }, }, { - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_raw, .cmatrix = { 0, 0, 0, 0, 0, 0 }, @@ -772,7 +772,7 @@ static void ov7675_get_framerate(struct v4l2_subdev *sd, pll_factor = PLL_FACTOR; clkrc++; - if (info->fmt->mbus_code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (info->fmt->mbus_code == MEDIA_BUS_FMT_SBGGR8_1X8) clkrc = (clkrc >> 1); tpf->numerator = 1; @@ -810,7 +810,7 @@ static int ov7675_set_framerate(struct v4l2_subdev *sd, } else { clkrc = (5 * pll_factor * info->clock_speed * tpf->numerator) / (4 * tpf->denominator); - if (info->fmt->mbus_code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (info->fmt->mbus_code == MEDIA_BUS_FMT_SBGGR8_1X8) clkrc = (clkrc << 1); clkrc--; } @@ -900,7 +900,7 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= N_OV7670_FMTS) return -EINVAL; diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 4da90c621f7e..2246bd5436ad 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -384,17 +384,17 @@ static const struct ov965x_framesize ov965x_framesizes[] = { }; struct ov965x_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_TSLB value, only bits [3:2] may be set. */ u8 tslb_reg; }; static const struct ov965x_pixfmt ov965x_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 0x00}, - { V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG, 0x04}, - { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG, 0x0c}, - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 0x08}, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 0x00}, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG, 0x04}, + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG, 0x0c}, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 0x08}, }; /* diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h index 9656b6723dc6..13aed59f0f5d 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3.h +++ b/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -27,8 +27,8 @@ #define DRIVER_NAME "S5C73M3" -#define S5C73M3_ISP_FMT V4L2_MBUS_FMT_VYUY8_2X8 -#define S5C73M3_JPEG_FMT V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 +#define S5C73M3_ISP_FMT MEDIA_BUS_FMT_VYUY8_2X8 +#define S5C73M3_JPEG_FMT MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 /* Subdevs pad index definitions */ enum s5c73m3_pads { @@ -402,7 +402,7 @@ struct s5c73m3 { const struct s5c73m3_frame_size *sensor_pix_size[2]; const struct s5c73m3_frame_size *oif_pix_size[2]; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; const struct s5c73m3_interval *fiv; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 1fcc76fd1bbf..d1c50c9d43ae 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -151,7 +151,7 @@ static const struct s5k4ecgx_frmsize s5k4ecgx_prev_sizes[] = { #define S5K4ECGX_NUM_PREV ARRAY_SIZE(s5k4ecgx_prev_sizes) struct s5k4ecgx_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_TC_PCFG_Format register value */ u16 reg_p_format; @@ -159,7 +159,7 @@ struct s5k4ecgx_pixfmt { /* By default value, output from sensor will be YUV422 0-255 */ static const struct s5k4ecgx_pixfmt s5k4ecgx_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, }; static const char * const s5k4ecgx_supply_names[] = { diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 0e461a6fd065..60a74d8d38d5 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -248,7 +248,7 @@ enum s5k5baf_gpio_id { #define NUM_ISP_PADS 2 struct s5k5baf_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_P_FMT(x) register value */ u16 reg_p_fmt; @@ -331,10 +331,10 @@ struct s5k5baf { }; static const struct s5k5baf_pixfmt s5k5baf_formats[] = { - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 }, /* range 16-240 */ - { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 }, - { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, }; static struct v4l2_rect s5k5baf_cis_rect = { @@ -1206,7 +1206,7 @@ static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, if (code->pad == PAD_CIS) { if (code->index > 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_FIXED; + code->code = MEDIA_BUS_FMT_FIXED; return 0; } @@ -1227,7 +1227,7 @@ static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd, return -EINVAL; if (fse->pad == PAD_CIS) { - fse->code = V4L2_MBUS_FMT_FIXED; + fse->code = MEDIA_BUS_FMT_FIXED; fse->min_width = S5K5BAF_CIS_WIDTH; fse->max_width = S5K5BAF_CIS_WIDTH; fse->min_height = S5K5BAF_CIS_HEIGHT; @@ -1252,7 +1252,7 @@ static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf) { mf->width = S5K5BAF_CIS_WIDTH; mf->height = S5K5BAF_CIS_HEIGHT; - mf->code = V4L2_MBUS_FMT_FIXED; + mf->code = MEDIA_BUS_FMT_FIXED; mf->colorspace = V4L2_COLORSPACE_JPEG; mf->field = V4L2_FIELD_NONE; } diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index c11a40850ed1..91b841a1b850 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -80,7 +80,7 @@ static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd) static const struct v4l2_mbus_framefmt s5k6a3_formats[] = { { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .colorspace = V4L2_COLORSPACE_SRGB, .field = V4L2_FIELD_NONE, } diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 629a5cdadd3a..2851581e0061 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -191,7 +191,7 @@ struct s5k6aa_regval { }; struct s5k6aa_pixfmt { - enum v4l2_mbus_pixelcode code; + u32 code; u32 colorspace; /* REG_P_FMT(x) register value */ u16 reg_p_fmt; @@ -285,10 +285,10 @@ static struct s5k6aa_regval s5k6aa_analog_config[] = { /* TODO: Add RGB888 and Bayer format */ static const struct s5k6aa_pixfmt s5k6aa_formats[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 }, /* range 16-240 */ - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 }, - { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 }, + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 }, }; static const struct s5k6aa_interval s5k6aa_intervals[] = { diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index 4024ea6f1371..f14c0e6435a3 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -562,7 +562,7 @@ static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm h->video_format = SAA6752HS_VF_D1; f->width = v4l2_format_table[h->video_format].fmt.pix.width; f->height = v4l2_format_table[h->video_format].fmt.pix.height; - f->code = V4L2_MBUS_FMT_FIXED; + f->code = MEDIA_BUS_FMT_FIXED; f->field = V4L2_FIELD_INTERLACED; f->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; @@ -572,7 +572,7 @@ static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_frame { int dist_352, dist_480, dist_720; - f->code = V4L2_MBUS_FMT_FIXED; + f->code = MEDIA_BUS_FMT_FIXED; dist_352 = abs(f->width - 352); dist_480 = abs(f->width - 480); @@ -599,7 +599,7 @@ static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm { struct saa6752hs_state *h = to_state(sd); - if (f->code != V4L2_MBUS_FMT_FIXED) + if (f->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; /* diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 35a44648150e..7147c8b68fac 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1172,7 +1172,7 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index 6922a9f9a5cd..0d0f9a917cd3 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -998,7 +998,7 @@ static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt v4l2_dbg(1, debug, sd, "decoder set size\n"); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; /* FIXME need better bounds checking here */ diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index bcc5866175b7..193af1c82d37 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -330,22 +330,22 @@ static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor) * orders must be defined. */ static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = { - { V4L2_MBUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, }, - { V4L2_MBUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, }, - { V4L2_MBUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, }, - { V4L2_MBUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, }, - { V4L2_MBUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, }, + { MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, }, + { MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, }, + { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, }; const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" }; diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index 5b915936c3f3..ec89cfa927a2 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -71,7 +71,7 @@ /* IMX074 has only one fixed colorspace per pixelcode */ struct imx074_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; @@ -82,7 +82,7 @@ struct imx074 { }; static const struct imx074_datafmt imx074_colour_fmts[] = { - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static struct imx074 *to_imx074(const struct i2c_client *client) @@ -91,7 +91,7 @@ static struct imx074 *to_imx074(const struct i2c_client *client) } /* Find a data format by a pixel code in an array */ -static const struct imx074_datafmt *imx074_find_datafmt(enum v4l2_mbus_pixelcode code) +static const struct imx074_datafmt *imx074_find_datafmt(u32 code) { int i; @@ -236,7 +236,7 @@ static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) } static int imx074_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if ((unsigned int)index >= ARRAY_SIZE(imx074_colour_fmts)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index dbd8c142d6ef..2e9a53502551 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -53,13 +53,13 @@ /* MT9M001 has only one fixed colorspace per pixelcode */ struct mt9m001_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct mt9m001_datafmt *mt9m001_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt, + u32 code, const struct mt9m001_datafmt *fmt, int n) { int i; @@ -75,14 +75,14 @@ static const struct mt9m001_datafmt mt9m001_colour_fmts[] = { * Order important: first natively supported, * second supported with a GPIO extender */ - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { /* Order important - see above */ - {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, }; struct mt9m001 { @@ -563,7 +563,7 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { }; static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index b51e8562e775..5992ea93257a 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -182,23 +182,23 @@ static struct mt9m111_context context_b = { /* MT9M111 has only one fixed colorspace per pixelcode */ struct mt9m111_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, }; struct mt9m111 { @@ -218,7 +218,7 @@ struct mt9m111 { /* Find a data format by a pixel code */ static const struct mt9m111_datafmt *mt9m111_find_datafmt(struct mt9m111 *mt9m111, - enum v4l2_mbus_pixelcode code) + u32 code) { int i; for (i = 0; i < ARRAY_SIZE(mt9m111_colour_fmts); i++) @@ -331,7 +331,7 @@ static int mt9m111_setup_rect_ctx(struct mt9m111 *mt9m111, } static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rect, - int width, int height, enum v4l2_mbus_pixelcode code) + int width, int height, u32 code) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); int ret; @@ -345,7 +345,7 @@ static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rec if (!ret) ret = reg_write(WINDOW_HEIGHT, rect->height); - if (code != V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (code != MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* IFP in use, down-scaling possible */ if (!ret) ret = mt9m111_setup_rect_ctx(mt9m111, &context_b, @@ -393,8 +393,8 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* Bayer format - even size lengths */ rect.width = ALIGN(rect.width, 2); rect.height = ALIGN(rect.height, 2); @@ -462,7 +462,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, } static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, - enum v4l2_mbus_pixelcode code) + u32 code) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); u16 data_outfmt2, mask_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER | @@ -474,46 +474,46 @@ static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, int ret; switch (code) { - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: data_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB; break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: data_outfmt2 = MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; break; - case V4L2_MBUS_FMT_BGR565_2X8_BE: + case MEDIA_BUS_FMT_BGR565_2X8_BE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_BGR565_2X8_LE: + case MEDIA_BUS_FMT_BGR565_2X8_LE: data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: data_outfmt2 = 0; break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN | MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B; break; @@ -542,8 +542,8 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, fmt = mt9m111_find_datafmt(mt9m111, mf->code); - bayer = fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; + bayer = fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE; /* * With Bayer format enforce even side lengths, but let the user play @@ -554,7 +554,7 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd, rect->height = ALIGN(rect->height, 2); } - if (fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { + if (fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { /* IFP bypass mode, no scaling */ mf->width = rect->width; mf->height = rect->height; @@ -840,7 +840,7 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { }; static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(mt9m111_colour_fmts)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index f8358c4071a9..35d9c8d25589 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -345,7 +345,7 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd, mf->width = mt9t031->rect.width / mt9t031->xskip; mf->height = mt9t031->rect.height / mt9t031->yskip; - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; mf->field = V4L2_FIELD_NONE; @@ -367,7 +367,7 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT); - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; /* mt9t031_set_params() doesn't change width and height */ @@ -385,7 +385,7 @@ static int mt9t031_try_fmt(struct v4l2_subdev *sd, &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); - mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; + mf->code = MEDIA_BUS_FMT_SBGGR10_1X10; mf->colorspace = V4L2_COLORSPACE_SRGB; return 0; @@ -673,12 +673,12 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { }; static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_SBGGR10_1X10; + *code = MEDIA_BUS_FMT_SBGGR10_1X10; return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 996d7b4007a5..64f08365e6b2 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -77,7 +77,7 @@ struct ************************************************************************/ struct mt9t112_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 fmt; u16 order; @@ -103,32 +103,32 @@ struct mt9t112_priv { static const struct mt9t112_format mt9t112_cfmts[] = { { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 0, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 1, }, { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 2, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .fmt = 1, .order = 3, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .fmt = 8, .order = 2, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .fmt = 4, .order = 2, @@ -840,7 +840,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) static int mt9t112_set_params(struct mt9t112_priv *priv, const struct v4l2_rect *rect, - enum v4l2_mbus_pixelcode code) + u32 code) { int i; @@ -953,7 +953,7 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, break; if (i == priv->num_formats) { - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; } else { mf->colorspace = mt9t112_cfmts[i].colorspace; @@ -967,7 +967,7 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, } static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); @@ -1101,7 +1101,7 @@ static int mt9t112_probe(struct i2c_client *client, /* Cannot fail: using the default supported pixel code */ if (!ret) - mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); + mt9t112_set_params(priv, &rect, MEDIA_BUS_FMT_UYVY8_2X8); else v4l2_clk_put(priv->clk); diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index 99022c8d76eb..a246d4d64b8b 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -85,13 +85,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); /* MT9V022 has only one fixed colorspace per pixelcode */ struct mt9v022_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct mt9v022_datafmt *mt9v022_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt, + u32 code, const struct mt9v022_datafmt *fmt, int n) { int i; @@ -107,14 +107,14 @@ static const struct mt9v022_datafmt mt9v022_colour_fmts[] = { * Order important: first natively supported, * second supported with a GPIO extender */ - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, }; static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { /* Order important - see above */ - {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, }; /* only registers with different addresses on different mt9v02x sensors */ @@ -410,13 +410,13 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, * .try_mbus_fmt(), datawidth is from our supported format list */ switch (mf->code) { - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y10_1X10: if (mt9v022->model != MT9V022IX7ATM) return -EINVAL; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: if (mt9v022->model != MT9V022IX7ATC) return -EINVAL; break; @@ -443,8 +443,8 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); const struct mt9v022_datafmt *fmt; - int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || - mf->code == V4L2_MBUS_FMT_SBGGR10_1X10; + int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 || + mf->code == MEDIA_BUS_FMT_SBGGR10_1X10; v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH, align, @@ -759,7 +759,7 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { }; static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 6c6b1c3b45e3..6f2dd9093d94 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -302,7 +302,7 @@ struct ov2640_win_size { struct ov2640_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; - enum v4l2_mbus_pixelcode cfmt_code; + u32 cfmt_code; struct v4l2_clk *clk; const struct ov2640_win_size *win; }; @@ -623,11 +623,11 @@ static const struct regval_list ov2640_rgb565_le_regs[] = { ENDMARKER, }; -static enum v4l2_mbus_pixelcode ov2640_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_RGB565_2X8_BE, - V4L2_MBUS_FMT_RGB565_2X8_LE, +static u32 ov2640_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_RGB565_2X8_BE, + MEDIA_BUS_FMT_RGB565_2X8_LE, }; /* @@ -785,7 +785,7 @@ static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height) } static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, - enum v4l2_mbus_pixelcode code) + u32 code) { struct ov2640_priv *priv = to_ov2640(client); const struct regval_list *selected_cfmt_regs; @@ -797,20 +797,20 @@ static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, /* select format */ priv->cfmt_code = 0; switch (code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: dev_dbg(&client->dev, "%s: Selected cfmt RGB565 BE", __func__); selected_cfmt_regs = ov2640_rgb565_be_regs; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: dev_dbg(&client->dev, "%s: Selected cfmt RGB565 LE", __func__); selected_cfmt_regs = ov2640_rgb565_le_regs; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__); selected_cfmt_regs = ov2640_yuyv_regs; break; default: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__); selected_cfmt_regs = ov2640_uyvy_regs; } @@ -869,7 +869,7 @@ static int ov2640_g_fmt(struct v4l2_subdev *sd, if (!priv->win) { u32 width = W_SVGA, height = H_SVGA; priv->win = ov2640_select_win(&width, &height); - priv->cfmt_code = V4L2_MBUS_FMT_UYVY8_2X8; + priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; } mf->width = priv->win->width; @@ -877,13 +877,13 @@ static int ov2640_g_fmt(struct v4l2_subdev *sd, mf->code = priv->cfmt_code; switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } mf->field = V4L2_FIELD_NONE; @@ -899,14 +899,14 @@ static int ov2640_s_fmt(struct v4l2_subdev *sd, switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } @@ -926,14 +926,14 @@ static int ov2640_try_fmt(struct v4l2_subdev *sd, mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } @@ -941,7 +941,7 @@ static int ov2640_try_fmt(struct v4l2_subdev *sd, } static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov2640_codes)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index d2daa6a8f272..93ae031bdafb 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -602,7 +602,7 @@ static struct regval_list ov5642_default_regs_finalise[] = { }; struct ov5642_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; @@ -618,7 +618,7 @@ struct ov5642 { }; static const struct ov5642_datafmt ov5642_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, }; static struct ov5642 *to_ov5642(const struct i2c_client *client) @@ -628,7 +628,7 @@ static struct ov5642 *to_ov5642(const struct i2c_client *client) /* Find a data format by a pixel code in an array */ static const struct ov5642_datafmt - *ov5642_find_datafmt(enum v4l2_mbus_pixelcode code) + *ov5642_find_datafmt(u32 code) { int i; @@ -840,7 +840,7 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd, } static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov5642_colour_fmts)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index ab01598ec83f..f4eef2fa6f6f 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -202,18 +202,18 @@ struct ov6650 { unsigned long pclk_limit; /* from host */ unsigned long pclk_max; /* from resolution and format */ struct v4l2_fract tpf; /* as requested with s_parm */ - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; -static enum v4l2_mbus_pixelcode ov6650_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_YVYU8_2X8, - V4L2_MBUS_FMT_VYUY8_2X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_Y8_1X8, +static u32 ov6650_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_Y8_1X8, }; /* read a register */ @@ -555,29 +555,29 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) .height = mf->height << half_scale, }, }; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; unsigned long mclk, pclk; u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; int ret; /* select color matrix configuration for given color encoding */ switch (code) { - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; coma_set |= COMA_BW; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; coma_set |= COMA_WORD_SWAP; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | COMA_BYTE_SWAP; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); if (half_scale) { coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; @@ -587,7 +587,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; } break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); if (half_scale) { coma_mask |= COMA_RGB | COMA_BW; @@ -597,7 +597,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) coma_set |= COMA_BYTE_SWAP; } break; - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; coma_set |= COMA_RAW_RGB | COMA_RGB; @@ -608,8 +608,8 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) } priv->code = code; - if (code == V4L2_MBUS_FMT_Y8_1X8 || - code == V4L2_MBUS_FMT_SBGGR8_1X8) { + if (code == MEDIA_BUS_FMT_Y8_1X8 || + code == MEDIA_BUS_FMT_SBGGR8_1X8) { coml_mask = COML_ONE_CHANNEL; coml_set = 0; priv->pclk_max = 4000000; @@ -619,7 +619,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) priv->pclk_max = 8000000; } - if (code == V4L2_MBUS_FMT_SBGGR8_1X8) + if (code == MEDIA_BUS_FMT_SBGGR8_1X8) priv->colorspace = V4L2_COLORSPACE_SRGB; else if (code != 0) priv->colorspace = V4L2_COLORSPACE_JPEG; @@ -697,18 +697,18 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd, mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_Y10_1X10: - mf->code = V4L2_MBUS_FMT_Y8_1X8; - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_Y10_1X10: + mf->code = MEDIA_BUS_FMT_Y8_1X8; + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; break; default: - mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; - case V4L2_MBUS_FMT_SBGGR8_1X8: + mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; + case MEDIA_BUS_FMT_SBGGR8_1X8: mf->colorspace = V4L2_COLORSPACE_SRGB; break; } @@ -717,7 +717,7 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd, } static int ov6650_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov6650_codes)) return -EINVAL; @@ -1013,7 +1013,7 @@ static int ov6650_probe(struct i2c_client *client, priv->rect.width = W_CIF; priv->rect.height = H_CIF; priv->half_scale = false; - priv->code = V4L2_MBUS_FMT_YUYV8_2X8; + priv->code = MEDIA_BUS_FMT_YUYV8_2X8; priv->colorspace = V4L2_COLORSPACE_JPEG; priv->clk = v4l2_clk_get(&client->dev, "mclk"); diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index 970a04e1e56e..8daac88b33fe 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -376,7 +376,7 @@ */ struct ov772x_color_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u8 dsp3; u8 dsp4; @@ -408,7 +408,7 @@ struct ov772x_priv { */ static const struct ov772x_color_format ov772x_cfmts[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -416,7 +416,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = UV_ON, .dsp4 = DSP_OFMT_YUV, @@ -424,7 +424,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -432,7 +432,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -440,7 +440,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -448,7 +448,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -456,7 +456,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { .com7 = FMT_RGB565 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -468,7 +468,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = { * regardless of the COM7 value. We can thus only support 10-bit * Bayer until someone figures it out. */ - .code = V4L2_MBUS_FMT_SBGGR10_1X10, + .code = MEDIA_BUS_FMT_SBGGR10_1X10, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_RAW10, @@ -990,7 +990,7 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { }; static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov772x_cfmts)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index bc74224503e7..aa93d2e88572 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -159,10 +159,10 @@ static const struct ov9640_reg ov9640_regs_rgb[] = { { OV9640_MTXS, 0x65 }, }; -static enum v4l2_mbus_pixelcode ov9640_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, - V4L2_MBUS_FMT_RGB565_2X8_LE, +static u32 ov9640_codes[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + MEDIA_BUS_FMT_RGB565_2X8_LE, }; /* read a register */ @@ -351,22 +351,22 @@ static void ov9640_res_roundup(u32 *width, u32 *height) } /* Prepare necessary register changes depending on color encoding */ -static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, +static void ov9640_alter_regs(u32 code, struct ov9640_reg_alt *alt) { switch (code) { default: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: alt->com12 = OV9640_COM12_YUV_AVG; alt->com13 = OV9640_COM13_Y_DELAY_EN | OV9640_COM13_YUV_DLY(0x01); break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_555; break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: alt->com7 = OV9640_COM7_RGB; alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_565; @@ -376,7 +376,7 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, /* Setup registers according to resolution and color encoding */ static int ov9640_write_regs(struct i2c_client *client, u32 width, - enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts) + u32 code, struct ov9640_reg_alt *alts) { const struct ov9640_reg *ov9640_regs, *matrix_regs; int ov9640_regs_len, matrix_regs_len; @@ -419,7 +419,7 @@ static int ov9640_write_regs(struct i2c_client *client, u32 width, } /* select color matrix configuration for given color encoding */ - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_UYVY8_2X8) { matrix_regs = ov9640_regs_yuv; matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); } else { @@ -487,7 +487,7 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov9640_reg_alt alts = {0}; enum v4l2_colorspace cspace; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; int ret; ov9640_res_roundup(&mf->width, &mf->height); @@ -500,13 +500,13 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, return ret; switch (code) { - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: cspace = V4L2_COLORSPACE_SRGB; break; default: - code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: + code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_UYVY8_2X8: cspace = V4L2_COLORSPACE_JPEG; } @@ -527,13 +527,13 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, mf->field = V4L2_FIELD_NONE; switch (mf->code) { - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: mf->colorspace = V4L2_COLORSPACE_SRGB; break; default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; + case MEDIA_BUS_FMT_UYVY8_2X8: mf->colorspace = V4L2_COLORSPACE_JPEG; } @@ -541,7 +541,7 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, } static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov9640_codes)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index ee9eb635d540..841dc55457cf 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -392,8 +392,8 @@ static const struct ov9740_reg ov9740_defaults[] = { { OV9740_ISP_CTRL19, 0x02 }, }; -static enum v4l2_mbus_pixelcode ov9740_codes[] = { - V4L2_MBUS_FMT_YUYV8_2X8, +static u32 ov9740_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, }; /* read a register */ @@ -674,13 +674,13 @@ static int ov9740_s_fmt(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov9740_priv *priv = to_ov9740(sd); enum v4l2_colorspace cspace; - enum v4l2_mbus_pixelcode code = mf->code; + u32 code = mf->code; int ret; ov9740_res_roundup(&mf->width, &mf->height); switch (code) { - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cspace = V4L2_COLORSPACE_SRGB; break; default: @@ -710,14 +710,14 @@ static int ov9740_try_fmt(struct v4l2_subdev *sd, ov9740_res_roundup(&mf->width, &mf->height); mf->field = V4L2_FIELD_NONE; - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; mf->colorspace = V4L2_COLORSPACE_SRGB; return 0; } static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(ov9740_codes)) return -EINVAL; diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index 7e6d97847874..1752428c43c5 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -111,13 +111,13 @@ /* RJ54N1CB0C has only one fixed colorspace per pixelcode */ struct rj54n1_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; /* Find a data format by a pixel code in an array */ static const struct rj54n1_datafmt *rj54n1_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt, + u32 code, const struct rj54n1_datafmt *fmt, int n) { int i; @@ -129,15 +129,15 @@ static const struct rj54n1_datafmt *rj54n1_find_datafmt( } static const struct rj54n1_datafmt rj54n1_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, - {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, + {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, }; struct rj54n1_clock_div { @@ -486,7 +486,7 @@ static int reg_write_multiple(struct i2c_client *client, } static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(rj54n1_colour_fmts)) return -EINVAL; @@ -965,11 +965,11 @@ static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); const struct rj54n1_datafmt *fmt; - int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE || - mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE; + int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE || + mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE; dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", __func__, mf->code, mf->width, mf->height); @@ -1025,55 +1025,55 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ switch (mf->code) { - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: ret = reg_write(client, RJ54N1_OUT_SEL, 0); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: ret = reg_write(client, RJ54N1_OUT_SEL, 0); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); break; - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE: ret = reg_write(client, RJ54N1_OUT_SEL, 4); if (!ret) ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); if (!ret) ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); break; - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: ret = reg_write(client, RJ54N1_OUT_SEL, 5); break; default: @@ -1083,7 +1083,7 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, /* Special case: a raw mode with 10 bits of data per clock tick */ if (!ret) ret = reg_set(client, RJ54N1_OCLK_SEL_EN, - (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2); + (mf->code == MEDIA_BUS_FMT_SBGGR10_1X10) << 1, 2); if (ret < 0) return ret; diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 416402eb4f82..9b853215d146 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -705,7 +705,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd, mf->width = priv->scale->width; mf->height = priv->scale->height; - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; mf->field = V4L2_FIELD_INTERLACED_BT; @@ -724,7 +724,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, /* * check color format */ - if (mf->code != V4L2_MBUS_FMT_UYVY8_2X8) + if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8) return -EINVAL; mf->colorspace = V4L2_COLORSPACE_JPEG; @@ -751,7 +751,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd, return -EINVAL; } - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; + mf->code = MEDIA_BUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; /* @@ -822,12 +822,12 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { }; static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index 118f8ee88465..10c735c3a082 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c @@ -165,7 +165,7 @@ struct sr030pc30_info { }; struct sr030pc30_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u16 ispctl1_reg; }; @@ -201,23 +201,23 @@ static const struct sr030pc30_frmsize sr030pc30_sizes[] = { /* supported pixel formats */ static const struct sr030pc30_format sr030pc30_formats[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x03, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x02, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x01, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_JPEG, .ispctl1_reg = 0x40, }, @@ -472,7 +472,7 @@ static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl) } static int sr030pc30_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (!code || index >= ARRAY_SIZE(sr030pc30_formats)) return -EINVAL; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index b9dabc9f4050..204204259ac6 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -756,12 +756,12 @@ static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl) */ static int tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV10_2X10; + *code = MEDIA_BUS_FMT_YUYV10_2X10; return 0; } @@ -784,7 +784,7 @@ tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) /* Calculate height and width based on current standard */ current_std = decoder->current_std; - f->code = V4L2_MBUS_FMT_YUYV8_2X8; + f->code = MEDIA_BUS_FMT_YUYV8_2X8; f->width = decoder->std_list[current_std].width; f->height = decoder->std_list[current_std].height; f->field = V4L2_FIELD_INTERLACED; @@ -942,7 +942,7 @@ static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, if (index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_YUYV8_2X8; + code->code = MEDIA_BUS_FMT_YUYV8_2X8; return 0; } @@ -967,7 +967,7 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, return 0; } - format->format.code = V4L2_MBUS_FMT_YUYV8_2X8; + format->format.code = MEDIA_BUS_FMT_YUYV8_2X8; format->format.width = tvp514x_std_list[decoder->current_std].width; format->format.height = tvp514x_std_list[decoder->current_std].height; format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -991,7 +991,7 @@ static int tvp514x_set_pad_format(struct v4l2_subdev *sd, struct tvp514x_decoder *decoder = to_decoder(sd); if (fmt->format.field != V4L2_FIELD_INTERLACED || - fmt->format.code != V4L2_MBUS_FMT_YUYV8_2X8 || + fmt->format.code != MEDIA_BUS_FMT_YUYV8_2X8 || fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M || fmt->format.width != tvp514x_std_list[decoder->current_std].width || fmt->format.height != tvp514x_std_list[decoder->current_std].height) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 193e7d6c29c8..68cdab9c0903 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -818,12 +818,12 @@ static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd) } static int tvp5150_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_UYVY8_2X8; + *code = MEDIA_BUS_FMT_UYVY8_2X8; return 0; } @@ -840,7 +840,7 @@ static int tvp5150_mbus_fmt(struct v4l2_subdev *sd, f->width = decoder->rect.width; f->height = decoder->rect.height; - f->code = V4L2_MBUS_FMT_UYVY8_2X8; + f->code = MEDIA_BUS_FMT_UYVY8_2X8; f->field = V4L2_FIELD_SEQ_TB; f->colorspace = V4L2_COLORSPACE_SMPTE170M; diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 51bac762638b..fe4870e22cfe 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -626,7 +626,7 @@ static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f f->width = bt->width; f->height = bt->height; - f->code = V4L2_MBUS_FMT_YUYV10_1X20; + f->code = MEDIA_BUS_FMT_YUYV10_1X20; f->field = device->current_timings->scanmode; f->colorspace = device->current_timings->color_space; @@ -756,12 +756,12 @@ static int tvp7002_s_register(struct v4l2_subdev *sd, */ static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { /* Check requested format index is within range */ if (index) return -EINVAL; - *code = V4L2_MBUS_FMT_YUYV10_1X20; + *code = MEDIA_BUS_FMT_YUYV10_1X20; return 0; } @@ -859,7 +859,7 @@ tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, if (code->index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_YUYV10_1X20; + code->code = MEDIA_BUS_FMT_YUYV10_1X20; return 0; } @@ -878,7 +878,7 @@ tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, { struct tvp7002 *tvp7002 = to_tvp7002(sd); - fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20; + fmt->format.code = MEDIA_BUS_FMT_YUYV10_1X20; fmt->format.width = tvp7002->current_timings->timings.bt.width; fmt->format.height = tvp7002->current_timings->timings.bt.height; fmt->format.field = tvp7002->current_timings->scanmode; diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index 373f2df52492..00e7f043977e 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -45,19 +45,19 @@ struct vs6624 { }; static const struct vs6624_format { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; enum v4l2_colorspace colorspace; } vs6624_formats[] = { { - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, }, { - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, }, { - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, }, }; @@ -65,7 +65,7 @@ static const struct vs6624_format { static struct v4l2_mbus_framefmt vs6624_default_fmt = { .width = VGA_WIDTH, .height = VGA_HEIGHT, - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .field = V4L2_FIELD_NONE, .colorspace = V4L2_COLORSPACE_JPEG, }; @@ -558,7 +558,7 @@ static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl) } static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { if (index >= ARRAY_SIZE(vs6624_formats)) return -EINVAL; @@ -605,15 +605,15 @@ static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd, /* set image format */ switch (fmt->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: vs6624_write(sd, VS6624_IMG_FMT0, 0x0); vs6624_write(sd, VS6624_YUV_SETUP, 0x1); break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: vs6624_write(sd, VS6624_IMG_FMT0, 0x0); vs6624_write(sd, VS6624_YUV_SETUP, 0x3); break; - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: vs6624_write(sd, VS6624_IMG_FMT0, 0x4); vs6624_write(sd, VS6624_RGB_SETUP, 0x0); break; -- GitLab From 43ba464182cd7f9e8089e3d76af8ef265ff287dd Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:30 -0300 Subject: [PATCH 4854/9457] [media] pci: Make use of MEDIA_BUS_FMT definitions In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Replace all references to the old definitions in pci drivers. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-av-core.c | 2 +- drivers/media/pci/cx18/cx18-controls.c | 2 +- drivers/media/pci/cx18/cx18-ioctl.c | 2 +- drivers/media/pci/cx23885/cx23885-video.c | 2 +- drivers/media/pci/ivtv/ivtv-controls.c | 2 +- drivers/media/pci/ivtv/ivtv-ioctl.c | 2 +- drivers/media/pci/saa7134/saa7134-empress.c | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index 45be26cdb653..5a55630d09db 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -952,7 +952,7 @@ static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - if (fmt->code != V4L2_MBUS_FMT_FIXED) + if (fmt->code != MEDIA_BUS_FMT_FIXED) return -EINVAL; fmt->field = V4L2_FIELD_INTERLACED; diff --git a/drivers/media/pci/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c index 282a3d29fdaa..4aeb7c6b8ce1 100644 --- a/drivers/media/pci/cx18/cx18-controls.c +++ b/drivers/media/pci/cx18/cx18-controls.c @@ -98,7 +98,7 @@ static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt); return 0; } diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index 6f2b59042b73..71963db3d92b 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -294,7 +294,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, mbus_fmt.width = cx->cxhdl.width = w; mbus_fmt.height = cx->cxhdl.height = h; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 682a4f95df6b..091f5dbe65a8 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -608,7 +608,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->field = f->fmt.pix.field; dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, dev->width, dev->height, dev->field); - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); /* s_mbus_fmt overwrites f->fmt.pix.field, restore it */ diff --git a/drivers/media/pci/ivtv/ivtv-controls.c b/drivers/media/pci/ivtv/ivtv-controls.c index 2b0ab26e11e8..ccf548c255f1 100644 --- a/drivers/media/pci/ivtv/ivtv-controls.c +++ b/drivers/media/pci/ivtv/ivtv-controls.c @@ -69,7 +69,7 @@ static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); return 0; } diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 3e0cb77d5930..4d8ee18c3feb 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -595,7 +595,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f fmt->fmt.pix.width /= 2; mbus_fmt.width = fmt->fmt.pix.width; mbus_fmt.height = h; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); return ivtv_g_fmt_vid_cap(file, fh, fmt); } diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index e4ea85fd1b23..8b3bb78b503b 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -140,7 +140,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, struct saa7134_dev *dev = video_drvdata(file); struct v4l2_mbus_framefmt mbus_fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); @@ -157,7 +157,7 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv, struct saa7134_dev *dev = video_drvdata(file); struct v4l2_mbus_framefmt mbus_fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); -- GitLab From 27ffaeb0ab160852c87e2dfa505594020e9a3a06 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:31 -0300 Subject: [PATCH 4855/9457] [media] platform: Make use of media_bus_format enum In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Reference new definitions in all platform drivers. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Acked-by: Sekhar Nori Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/soc-camera.txt | 2 +- arch/arm/mach-davinci/board-dm355-evm.c | 2 +- arch/arm/mach-davinci/board-dm365-evm.c | 4 +- arch/arm/mach-davinci/dm355.c | 7 +- arch/arm/mach-davinci/dm365.c | 7 +- arch/arm/mach-shmobile/board-mackerel.c | 2 +- arch/sh/boards/mach-ap325rxa/setup.c | 2 +- .../media/platform/blackfin/bfin_capture.c | 14 +-- drivers/media/platform/davinci/vpbe.c | 2 +- drivers/media/platform/davinci/vpfe_capture.c | 4 +- drivers/media/platform/exynos-gsc/gsc-core.c | 8 +- drivers/media/platform/exynos-gsc/gsc-core.h | 2 +- .../media/platform/exynos4-is/fimc-capture.c | 2 +- drivers/media/platform/exynos4-is/fimc-core.c | 14 +-- drivers/media/platform/exynos4-is/fimc-core.h | 4 +- drivers/media/platform/exynos4-is/fimc-isp.c | 16 +-- .../media/platform/exynos4-is/fimc-lite-reg.c | 26 ++-- drivers/media/platform/exynos4-is/fimc-lite.c | 14 +-- drivers/media/platform/exynos4-is/fimc-reg.c | 14 +-- drivers/media/platform/exynos4-is/mipi-csis.c | 14 +-- .../media/platform/marvell-ccic/mcam-core.c | 21 ++-- .../media/platform/marvell-ccic/mcam-core.h | 2 +- drivers/media/platform/omap3isp/ispccdc.c | 112 +++++++++--------- drivers/media/platform/omap3isp/ispccp2.c | 18 +-- drivers/media/platform/omap3isp/ispcsi2.c | 42 +++---- drivers/media/platform/omap3isp/isppreview.c | 60 +++++----- drivers/media/platform/omap3isp/ispresizer.c | 19 ++- drivers/media/platform/omap3isp/ispvideo.c | 95 ++++++++------- drivers/media/platform/omap3isp/ispvideo.h | 10 +- .../media/platform/s3c-camif/camif-capture.c | 10 +- drivers/media/platform/s3c-camif/camif-regs.c | 8 +- drivers/media/platform/s5p-tv/hdmi_drv.c | 2 +- drivers/media/platform/s5p-tv/sdo_drv.c | 2 +- drivers/media/platform/sh_vou.c | 8 +- drivers/media/platform/soc_camera/atmel-isi.c | 22 ++-- .../media/platform/soc_camera/mx2_camera.c | 26 ++-- .../media/platform/soc_camera/mx3_camera.c | 6 +- .../media/platform/soc_camera/omap1_camera.c | 36 +++--- .../media/platform/soc_camera/pxa_camera.c | 16 +-- drivers/media/platform/soc_camera/rcar_vin.c | 14 +-- .../soc_camera/sh_mobile_ceu_camera.c | 20 ++-- .../platform/soc_camera/sh_mobile_csi2.c | 38 +++--- .../media/platform/soc_camera/soc_camera.c | 2 +- .../platform/soc_camera/soc_camera_platform.c | 2 +- .../media/platform/soc_camera/soc_mediabus.c | 78 ++++++------ drivers/media/platform/via-camera.c | 8 +- drivers/media/platform/vsp1/vsp1_bru.c | 14 +-- drivers/media/platform/vsp1/vsp1_hsit.c | 12 +- drivers/media/platform/vsp1/vsp1_lif.c | 10 +- drivers/media/platform/vsp1/vsp1_lut.c | 14 +-- drivers/media/platform/vsp1/vsp1_rwpf.c | 10 +- drivers/media/platform/vsp1/vsp1_sru.c | 12 +- drivers/media/platform/vsp1/vsp1_uds.c | 10 +- drivers/media/platform/vsp1/vsp1_video.c | 42 +++---- include/media/davinci/vpbe.h | 2 +- include/media/davinci/vpbe_venc.h | 5 +- include/media/exynos-fimc.h | 2 +- include/media/soc_camera.h | 2 +- include/media/soc_mediabus.h | 6 +- 59 files changed, 483 insertions(+), 495 deletions(-) diff --git a/Documentation/video4linux/soc-camera.txt b/Documentation/video4linux/soc-camera.txt index daa9e2ac162c..84f41cf1f3e8 100644 --- a/Documentation/video4linux/soc-camera.txt +++ b/Documentation/video4linux/soc-camera.txt @@ -151,7 +151,7 @@ they are transferred over a media bus. Soc-camera provides support to conveniently manage these formats. A table of standard transformations is maintained by soc-camera core, which describes, what FOURCC pixel format will be obtained, if a media-bus pixel format is stored in memory according to -certain rules. E.g. if V4L2_MBUS_FMT_YUYV8_2X8 data is sampled with 8 bits per +certain rules. E.g. if MEDIA_BUS_FMT_YUYV8_2X8 data is sampled with 8 bits per sample and stored in memory in the little-endian order with no gaps between bytes, data in memory will represent the V4L2_PIX_FMT_YUYV FOURCC format. These standard transformations will be used by soc-camera or by camera host drivers to diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 06d63d5651f3..b46b4d25f93e 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -294,7 +294,7 @@ static struct vpbe_output dm355evm_vpbe_outputs[] = { .default_mode = "ntsc", .num_modes = ARRAY_SIZE(dm355evm_enc_preset_timing), .modes = dm355evm_enc_preset_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, }; diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index e08a8684ead2..a756003595e9 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -485,7 +485,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = { .default_mode = "ntsc", .num_modes = ARRAY_SIZE(dm365evm_enc_std_timing), .modes = dm365evm_enc_std_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, { .output = { @@ -498,7 +498,7 @@ static struct vpbe_output dm365evm_vpbe_outputs[] = { .default_mode = "480p59_94", .num_modes = ARRAY_SIZE(dm365evm_enc_preset_timing), .modes = dm365evm_enc_preset_timing, - .if_params = V4L2_MBUS_FMT_FIXED, + .if_params = MEDIA_BUS_FMT_FIXED, }, }; diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 2f3ed3a58d57..9cbeda798584 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -785,14 +785,13 @@ static struct resource dm355_v4l2_disp_resources[] = { }, }; -static int dm355_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, - int field) +static int dm355_vpbe_setup_pinmux(u32 if_type, int field) { switch (if_type) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: davinci_cfg_reg(DM355_VOUT_FIELD_G70); break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: if (field) davinci_cfg_reg(DM355_VOUT_FIELD); else diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 0ae8114f5cc9..e3a3c54b6832 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1306,16 +1306,15 @@ static struct resource dm365_v4l2_disp_resources[] = { }, }; -static int dm365_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, - int field) +static int dm365_vpbe_setup_pinmux(u32 if_type, int field) { switch (if_type) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: davinci_cfg_reg(DM365_VOUT_FIELD_G81); davinci_cfg_reg(DM365_VOUT_COUTL_EN); davinci_cfg_reg(DM365_VOUT_COUTH_EN); break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: if (field) davinci_cfg_reg(DM365_VOUT_FIELD); else diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index ca5d34b92aa7..a673624878d1 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1153,7 +1153,7 @@ static struct soc_camera_platform_info camera_info = { .format_name = "UYVY", .format_depth = 16, .format = { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_SMPTE170M, .field = V4L2_FIELD_NONE, .width = 640, diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 5620e33c18a0..d4b01d4cc102 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -338,7 +338,7 @@ static struct soc_camera_platform_info camera_info = { .format_name = "UYVY", .format_depth = 16, .format = { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_SMPTE170M, .field = V4L2_FIELD_NONE, .width = 640, diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 9b5daa65841c..b3345b37bb10 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -49,7 +49,7 @@ struct bcap_format { char *desc; u32 pixelformat; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; int bpp; /* bits per pixel */ int dlen; /* data length for ppi in bits */ }; @@ -116,35 +116,35 @@ static const struct bcap_format bcap_formats[] = { { .desc = "YCbCr 4:2:2 Interleaved UYVY", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .bpp = 16, .dlen = 8, }, { .desc = "YCbCr 4:2:2 Interleaved YUYV", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 16, .dlen = 8, }, { .desc = "YCbCr 4:2:2 Interleaved UYVY", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16, + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .dlen = 16, }, { .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .bpp = 16, .dlen = 8, }, { .desc = "RGB 444", .pixelformat = V4L2_PIX_FMT_RGB444, - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 16, .dlen = 8, }, @@ -161,7 +161,7 @@ static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb) static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) { - enum v4l2_mbus_pixelcode code; + u32 code; struct bcap_format *sf; unsigned int num_formats = 0; int i, j; diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index e5df9916b2a1..244d3d6c244c 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -227,7 +227,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) vpbe_current_encoder_info(vpbe_dev); struct vpbe_config *cfg = vpbe_dev->cfg; struct venc_platform_data *venc_device = vpbe_dev->venc_device; - enum v4l2_mbus_pixelcode if_params; + u32 if_params; int enc_out_index; int sd_index; int ret = 0; diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index de55f47a77db..3d0e3ae1795c 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -414,13 +414,13 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev, /* assume V4L2_PIX_FMT_UYVY as default */ pix->pixelformat = V4L2_PIX_FMT_UYVY; v4l2_fill_mbus_format(&mbus_fmt, pix, - V4L2_MBUS_FMT_YUYV10_2X10); + MEDIA_BUS_FMT_YUYV10_2X10); } else { pix->field = V4L2_FIELD_NONE; /* assume V4L2_PIX_FMT_SBGGR8 */ pix->pixelformat = V4L2_PIX_FMT_SBGGR8; v4l2_fill_mbus_format(&mbus_fmt, pix, - V4L2_MBUS_FMT_SBGGR8_1X8); + MEDIA_BUS_FMT_SBGGR8_1X8); } /* if sub device supports g_mbus_fmt, override the defaults */ diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index b4c9f1d08968..91d226b8fe5c 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -54,7 +54,7 @@ static const struct gsc_fmt gsc_formats[] = { .corder = GSC_CBCR, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, }, { .name = "YUV 4:2:2 packed, CbYCrY", .pixelformat = V4L2_PIX_FMT_UYVY, @@ -64,7 +64,7 @@ static const struct gsc_fmt gsc_formats[] = { .corder = GSC_CBCR, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, }, { .name = "YUV 4:2:2 packed, CrYCbY", .pixelformat = V4L2_PIX_FMT_VYUY, @@ -74,7 +74,7 @@ static const struct gsc_fmt gsc_formats[] = { .corder = GSC_CRCB, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, }, { .name = "YUV 4:2:2 packed, YCrYCb", .pixelformat = V4L2_PIX_FMT_YVYU, @@ -84,7 +84,7 @@ static const struct gsc_fmt gsc_formats[] = { .corder = GSC_CRCB, .num_planes = 1, .num_comp = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, }, { .name = "YUV 4:4:4 planar, YCbYCr", .pixelformat = V4L2_PIX_FMT_YUV32, diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index ef0a6564cef9..0abdb17fb19c 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h @@ -117,7 +117,7 @@ enum gsc_yuv_fmt { * @flags: flags indicating which operation mode format applies to */ struct gsc_fmt { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; char *name; u32 pixelformat; u32 color; diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 3d2babd5067a..8a2fd8c33d42 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -749,7 +749,7 @@ static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv, return -EINVAL; strncpy(f->description, fmt->name, sizeof(f->description) - 1); f->pixelformat = fmt->fourcc; - if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8) + if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) f->flags |= V4L2_FMT_FLAG_COMPRESSED; return 0; } diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index aee92d908e49..dbd74d8dc2a8 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -81,7 +81,7 @@ static struct fimc_fmt fimc_formats[] = { .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, }, { .name = "YUV 4:4:4", - .mbus_code = V4L2_MBUS_FMT_YUV10_1X30, + .mbus_code = MEDIA_BUS_FMT_YUV10_1X30, .flags = FMT_FLAGS_WRITEBACK, }, { .name = "YUV 4:2:2 packed, YCbYCr", @@ -90,7 +90,7 @@ static struct fimc_fmt fimc_formats[] = { .color = FIMC_FMT_YCBYCR422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, CbYCrY", @@ -99,7 +99,7 @@ static struct fimc_fmt fimc_formats[] = { .color = FIMC_FMT_CBYCRY422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, CrYCbY", @@ -108,7 +108,7 @@ static struct fimc_fmt fimc_formats[] = { .color = FIMC_FMT_CRYCBY422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 packed, YCrYCb", @@ -117,7 +117,7 @@ static struct fimc_fmt fimc_formats[] = { .color = FIMC_FMT_YCRYCB422, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { .name = "YUV 4:2:2 planar, Y/Cb/Cr", @@ -190,7 +190,7 @@ static struct fimc_fmt fimc_formats[] = { .depth = { 8 }, .memplanes = 1, .colplanes = 1, - .mbus_code = V4L2_MBUS_FMT_JPEG_1X8, + .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED, }, { .name = "S5C73MX interleaved UYVY/JPEG", @@ -200,7 +200,7 @@ static struct fimc_fmt fimc_formats[] = { .memplanes = 2, .colplanes = 1, .mdataplanes = 0x2, /* plane 1 holds frame meta data */ - .mbus_code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, + .mbus_code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED, }, }; diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index 6c75c6ced1f7..7328f0845065 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h @@ -579,8 +579,8 @@ static inline bool fimc_jpeg_fourcc(u32 pixelformat) static inline bool fimc_user_defined_mbus_fmt(u32 code) { - return (code == V4L2_MBUS_FMT_JPEG_1X8 || - code == V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8); + return (code == MEDIA_BUS_FMT_JPEG_1X8 || + code == MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8); } /* Return the alpha component bit mask */ diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index be62d6b9ac48..60c744915549 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -41,21 +41,21 @@ static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = { .depth = { 8 }, .color = FIMC_FMT_RAW8, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, }, { .name = "RAW10 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG10, .depth = { 10 }, .color = FIMC_FMT_RAW10, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, }, { .name = "RAW12 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG12, .depth = { 12 }, .color = FIMC_FMT_RAW12, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, }, }; @@ -149,7 +149,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) { mf->colorspace = V4L2_COLORSPACE_JPEG; - mf->code = V4L2_MBUS_FMT_YUV10_1X30; + mf->code = MEDIA_BUS_FMT_YUV10_1X30; } } @@ -175,7 +175,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, FIMC_ISP_SINK_WIDTH_MAX, 0, &mf->height, FIMC_ISP_SINK_HEIGHT_MIN, FIMC_ISP_SINK_HEIGHT_MAX, 0, 0); - mf->code = V4L2_MBUS_FMT_SGRBG10_1X10; + mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; } else { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) format = v4l2_subdev_get_try_format(fh, @@ -188,7 +188,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT; if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) { - mf->code = V4L2_MBUS_FMT_YUV10_1X30; + mf->code = MEDIA_BUS_FMT_YUV10_1X30; mf->colorspace = V4L2_COLORSPACE_JPEG; } else { mf->code = format->code; @@ -680,11 +680,11 @@ static void __isp_subdev_set_default_format(struct fimc_isp *isp) FIMC_ISP_CAC_MARGIN_WIDTH; isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT; - isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10; + isp->sink_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10; isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; - isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10; + isp->src_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10; __is_set_frame_size(is, &isp->src_fmt); } diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c index bc3ec7d25a32..0477716a20db 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c @@ -112,24 +112,24 @@ void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on) } static const u32 src_pixfmt_map[8][3] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR, + { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB, + { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY, + { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY, + { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY, FLITE_REG_CIGCTRL_YUV422_1P }, - { V4L2_MBUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 }, - { V4L2_MBUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 }, - { V4L2_MBUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 }, - { V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) }, + { MEDIA_BUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 }, + { MEDIA_BUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) }, }; /* Set camera input pixel format and resolution */ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) { - enum v4l2_mbus_pixelcode pixelcode = f->fmt->mbus_code; + u32 pixelcode = f->fmt->mbus_code; int i = ARRAY_SIZE(src_pixfmt_map); u32 cfg; @@ -232,10 +232,10 @@ static void flite_hw_set_pack12(struct fimc_lite *dev, int on) static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) { static const u32 pixcode[4][2] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, - { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB }, - { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY }, - { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY }, + { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, + { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB }, + { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY }, + { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY }, }; u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT); int i = ARRAY_SIZE(pixcode); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index a97d2352f1d7..b7dca8b2d455 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -48,7 +48,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_YCBYCR422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, CbYCrY", @@ -57,7 +57,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_CBYCRY422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, + .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, CrYCbY", @@ -66,7 +66,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_CRYCBY422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, + .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "YUV 4:2:2 packed, YCrYCb", @@ -75,7 +75,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_YCRYCB422, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, + .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_YUV, }, { .name = "RAW8 (GRBG)", @@ -84,7 +84,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 8 }, .color = FIMC_FMT_RAW8, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, .flags = FMT_FLAGS_RAW_BAYER, }, { .name = "RAW10 (GRBG)", @@ -93,7 +93,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_RAW10, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, .flags = FMT_FLAGS_RAW_BAYER, }, { .name = "RAW12 (GRBG)", @@ -102,7 +102,7 @@ static const struct fimc_fmt fimc_lite_formats[] = { .depth = { 16 }, .color = FIMC_FMT_RAW12, .memplanes = 1, - .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, .flags = FMT_FLAGS_RAW_BAYER, }, }; diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c index 2d77fd8f440a..df0cbcb69b6b 100644 --- a/drivers/media/platform/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-reg.c @@ -592,10 +592,10 @@ struct mbus_pixfmt_desc { }; static const struct mbus_pixfmt_desc pix_desc[] = { - { V4L2_MBUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 }, - { V4L2_MBUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 }, - { V4L2_MBUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 }, - { V4L2_MBUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 }, + { MEDIA_BUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 }, + { MEDIA_BUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 }, + { MEDIA_BUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 }, + { MEDIA_BUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 }, }; int fimc_hw_set_camera_source(struct fimc_dev *fimc, @@ -689,11 +689,11 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc, /* TODO: add remaining supported formats. */ switch (vid_cap->ci_fmt.code) { - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT; break; - case V4L2_MBUS_FMT_JPEG_1X8: - case V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8: + case MEDIA_BUS_FMT_JPEG_1X8: + case MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8: tmp = FIMC_REG_CSIIMGFMT_USER(1); cfg |= FIMC_REG_CIGCTRL_CAM_JPEG; break; diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index db6fd14d1936..2f3fdfba1a45 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -238,34 +238,34 @@ struct csis_state { */ struct csis_pix_format { unsigned int pix_width_alignment; - enum v4l2_mbus_pixelcode code; + u32 code; u32 fmt_reg; u8 data_alignment; }; static const struct csis_pix_format s5pcsis_formats[] = { { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT, .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .fmt_reg = S5PCSIS_CFG_FMT_USER(1), .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, + .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, .fmt_reg = S5PCSIS_CFG_FMT_USER(1), .data_alignment = 32, }, { - .code = V4L2_MBUS_FMT_SGRBG8_1X8, + .code = MEDIA_BUS_FMT_SGRBG8_1X8, .fmt_reg = S5PCSIS_CFG_FMT_RAW8, .data_alignment = 24, }, { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .fmt_reg = S5PCSIS_CFG_FMT_RAW10, .data_alignment = 24, }, { - .code = V4L2_MBUS_FMT_SGRBG12_1X12, + .code = MEDIA_BUS_FMT_SGRBG12_1X12, .fmt_reg = S5PCSIS_CFG_FMT_RAW12, .data_alignment = 24, } diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 7a86c77bffa0..f0eeb6cd262c 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -106,61 +106,61 @@ static struct mcam_format_struct { __u32 pixelformat; int bpp; /* Bytes per pixel */ bool planar; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; } mcam_formats[] = { { .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { .desc = "UYVY 4:2:2", .pixelformat = V4L2_PIX_FMT_UYVY, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { .desc = "YUV 4:2:2 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV422P, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "YUV 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV420, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "YVU 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YVU420, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = true, }, { .desc = "RGB 444", .pixelformat = V4L2_PIX_FMT_RGB444, - .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 2, .planar = false, }, { .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, - .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .bpp = 2, .planar = false, }, { .desc = "Raw RGB Bayer", .pixelformat = V4L2_PIX_FMT_SBGGR8, - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 1, .planar = false, }, @@ -190,8 +190,7 @@ static const struct v4l2_pix_format mcam_def_pix_format = { .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, }; -static const enum v4l2_mbus_pixelcode mcam_def_mbus_code = - V4L2_MBUS_FMT_YUYV8_2X8; +static const u32 mcam_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; /* diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index e0e628cb98f9..60a8e1cfeff7 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h @@ -183,7 +183,7 @@ struct mcam_camera { /* Current operating parameters */ struct v4l2_pix_format pix_format; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; /* Locks */ struct mutex s_mutex; /* Access to this structure */ diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 81a9dc053d58..587489a072d5 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -36,23 +36,23 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, unsigned int pad, enum v4l2_subdev_format_whence which); static const unsigned int ccdc_fmts[] = { - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_SRGGB12_1X12, - V4L2_MBUS_FMT_SBGGR12_1X12, - V4L2_MBUS_FMT_SGBRG12_1X12, - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y12_1X12, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, }; /* @@ -266,10 +266,10 @@ static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable) __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE); - if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) && - (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) && - (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) && - (format->code != V4L2_MBUS_FMT_SGBRG10_1X10)) + if ((format->code != MEDIA_BUS_FMT_SGRBG10_1X10) && + (format->code != MEDIA_BUS_FMT_SRGGB10_1X10) && + (format->code != MEDIA_BUS_FMT_SBGGR10_1X10) && + (format->code != MEDIA_BUS_FMT_SGBRG10_1X10)) return -EINVAL; if (enable) @@ -971,8 +971,8 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, format = &ccdc->formats[CCDC_PAD_SINK]; - if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 || - format->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || + format->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* According to the OMAP3 TRM the input mode only affects SYNC * mode, enabling BT.656 mode should take precedence. However, * in practice setting the input mode to YCbCr data on 8 bits @@ -1020,7 +1020,7 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, /* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The * hardware seems to ignore it in all other input modes. */ - if (format->code == V4L2_MBUS_FMT_UYVY8_2X8) + if (format->code == MEDIA_BUS_FMT_UYVY8_2X8) isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_Y8POS); else @@ -1168,9 +1168,9 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) if (ccdc->bt656) bridge = ISPCTRL_PAR_BRIDGE_DISABLE; - else if (fmt_info->code == V4L2_MBUS_FMT_YUYV8_2X8) + else if (fmt_info->code == MEDIA_BUS_FMT_YUYV8_2X8) bridge = ISPCTRL_PAR_BRIDGE_LENDIAN; - else if (fmt_info->code == V4L2_MBUS_FMT_UYVY8_2X8) + else if (fmt_info->code == MEDIA_BUS_FMT_UYVY8_2X8) bridge = ISPCTRL_PAR_BRIDGE_BENDIAN; else bridge = ISPCTRL_PAR_BRIDGE_DISABLE; @@ -1199,16 +1199,16 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) /* Mosaic filter */ switch (format->code) { - case V4L2_MBUS_FMT_SRGGB10_1X10: - case V4L2_MBUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SRGGB12_1X12: ccdc_pattern = ccdc_srggb_pattern; break; - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR12_1X12: ccdc_pattern = ccdc_sbggr_pattern; break; - case V4L2_MBUS_FMT_SGBRG10_1X10: - case V4L2_MBUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGBRG12_1X12: ccdc_pattern = ccdc_sgbrg_pattern; break; default: @@ -1267,7 +1267,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) /* The CCDC outputs data in UYVY order by default. Swap bytes to get * YUYV. */ - if (format->code == V4L2_MBUS_FMT_YUYV8_1X16) + if (format->code == MEDIA_BUS_FMT_YUYV8_1X16) isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_BSWD); else @@ -1967,7 +1967,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, enum v4l2_subdev_format_whence which) { const struct isp_format_info *info; - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; unsigned int width = fmt->width; unsigned int height = fmt->height; struct v4l2_rect *crop; @@ -1983,7 +1983,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(ccdc_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; /* Clamp the input size. */ fmt->width = clamp_t(u32, width, 32, 4096); @@ -2007,19 +2007,19 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, * configured to pack bytes in BT.656, hiding the inaccuracy. * In all cases bytes can be swapped. */ - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 || - fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* Use the user requested format if YUV. */ - if (pixelcode == V4L2_MBUS_FMT_YUYV8_2X8 || - pixelcode == V4L2_MBUS_FMT_UYVY8_2X8 || - pixelcode == V4L2_MBUS_FMT_YUYV8_1X16 || - pixelcode == V4L2_MBUS_FMT_UYVY8_1X16) + if (pixelcode == MEDIA_BUS_FMT_YUYV8_2X8 || + pixelcode == MEDIA_BUS_FMT_UYVY8_2X8 || + pixelcode == MEDIA_BUS_FMT_YUYV8_1X16 || + pixelcode == MEDIA_BUS_FMT_UYVY8_1X16) fmt->code = pixelcode; - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8) - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; - else if (fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) - fmt->code = V4L2_MBUS_FMT_UYVY8_1X16; + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8) + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; + else if (fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) + fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; } /* Hardcode the output size to the crop rectangle size. */ @@ -2047,8 +2047,8 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, fmt->code = info->truncated; /* YUV formats are not supported by the video port. */ - if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 || - fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) + if (fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) fmt->code = 0; /* The number of lines that can be clocked out from the video @@ -2083,7 +2083,7 @@ static void ccdc_try_crop(struct isp_ccdc_device *ccdc, * to keep the Bayer pattern. */ info = omap3isp_video_format_info(sink->code); - if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) { + if (info->flavor != MEDIA_BUS_FMT_Y8_1X8) { crop->left &= ~1; crop->top &= ~1; } @@ -2103,7 +2103,7 @@ static void ccdc_try_crop(struct isp_ccdc_device *ccdc, sink->height - crop->top); /* Odd width/height values don't make sense for Bayer formats. */ - if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) { + if (info->flavor != MEDIA_BUS_FMT_Y8_1X8) { crop->width &= ~1; crop->height &= ~1; } @@ -2135,13 +2135,13 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, format = __ccdc_get_format(ccdc, fh, code->pad, V4L2_SUBDEV_FORMAT_TRY); - if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 || - format->code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || + format->code == MEDIA_BUS_FMT_UYVY8_2X8) { /* In YUV mode the CCDC can swap bytes. */ if (code->index == 0) - code->code = V4L2_MBUS_FMT_YUYV8_1X16; + code->code = MEDIA_BUS_FMT_YUYV8_1X16; else if (code->index == 1) - code->code = V4L2_MBUS_FMT_UYVY8_1X16; + code->code = MEDIA_BUS_FMT_UYVY8_1X16; else return -EINVAL; } else { @@ -2383,9 +2383,7 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, * return true if the combination is possible * return false otherwise */ -static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in, - enum v4l2_mbus_pixelcode out, - unsigned int additional_shift) +static bool ccdc_is_shiftable(u32 in, u32 out, unsigned int additional_shift) { const struct isp_format_info *in_info, *out_info; @@ -2452,7 +2450,7 @@ static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = CCDC_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ccdc_set_format(sd, fh, &format); diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 9cb49b3c04bd..f4aedb37e41e 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -289,10 +289,10 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2, u32 val, format; switch (config->format) { - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP; break; - case V4L2_MBUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: default: format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */ break; @@ -438,7 +438,7 @@ static void ccp2_mem_configure(struct isp_ccp2_device *ccp2, u32 val, hwords; if (sink_pixcode != source_pixcode && - sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8) + sink_pixcode == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) dpcm_decompress = 1; ccp2_pwr_cfg(ccp2); @@ -604,8 +604,8 @@ void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) */ static const unsigned int ccp2_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, }; /* @@ -643,8 +643,8 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, switch (pad) { case CCP2_PAD_SINK: - if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + if (fmt->code != MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; if (ccp2->input == CCP2_INPUT_SENSOR) { fmt->width = clamp_t(u32, fmt->width, @@ -671,7 +671,7 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, */ format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; break; } @@ -808,7 +808,7 @@ static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = CCP2_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ccp2_set_format(sd, fh, &format); diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 6530b255f103..09c686d96ae8 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -78,15 +78,15 @@ static void csi2_recv_config(struct isp_device *isp, } static const unsigned int csi2_input_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, - V4L2_MBUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_YUYV8_2X8, }; /* To set the format on the CSI2 requires a mapping function that takes @@ -171,19 +171,19 @@ static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2) int fmtidx, destidx, is_3630; switch (fmt->code) { - case V4L2_MBUS_FMT_SGRBG10_1X10: - case V4L2_MBUS_FMT_SRGGB10_1X10: - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: fmtidx = 0; break; - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: - case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: fmtidx = 1; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: fmtidx = 2; break; default: @@ -843,7 +843,7 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_mbus_framefmt *format; const struct isp_format_info *info; unsigned int i; @@ -858,7 +858,7 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(csi2_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; fmt->width = clamp_t(u32, fmt->width, 1, 8191); fmt->height = clamp_t(u32, fmt->height, 1, 8191); @@ -1029,7 +1029,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = CSI2_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; csi2_set_format(sd, fh, &format); diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 605f57ef0a49..dd9eed45d853 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -964,18 +964,16 @@ static void preview_setup_hw(struct isp_prev_device *prev, u32 update, * @prev: pointer to previewer private structure * @pixelcode: pixel code */ -static void -preview_config_ycpos(struct isp_prev_device *prev, - enum v4l2_mbus_pixelcode pixelcode) +static void preview_config_ycpos(struct isp_prev_device *prev, u32 pixelcode) { struct isp_device *isp = to_isp_device(prev); enum preview_ycpos_mode mode; switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: mode = YCPOS_CrYCbY; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: mode = YCPOS_YCrYCb; break; default: @@ -1028,16 +1026,16 @@ static void preview_config_input_format(struct isp_prev_device *prev, ISPPRV_PCR_WIDTH); switch (info->flavor) { - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: prev->params.cfa_order = 0; break; - case V4L2_MBUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: prev->params.cfa_order = 1; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: prev->params.cfa_order = 2; break; - case V4L2_MBUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: prev->params.cfa_order = 3; break; default: @@ -1078,8 +1076,8 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) unsigned int elv = prev->crop.top + prev->crop.height - 1; u32 features; - if (format->code != V4L2_MBUS_FMT_Y8_1X8 && - format->code != V4L2_MBUS_FMT_Y10_1X10) { + if (format->code != MEDIA_BUS_FMT_Y8_1X8 && + format->code != MEDIA_BUS_FMT_Y10_1X10) { sph -= 2; eph += 2; slv -= 2; @@ -1709,21 +1707,21 @@ __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, /* previewer format descriptions */ static const unsigned int preview_input_fmts[] = { - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, }; static const unsigned int preview_output_fmts[] = { - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; /* @@ -1742,7 +1740,7 @@ static void preview_try_format(struct isp_prev_device *prev, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_rect *crop; unsigned int i; @@ -1774,7 +1772,7 @@ static void preview_try_format(struct isp_prev_device *prev, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(preview_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; break; case PREV_PAD_SOURCE: @@ -1782,13 +1780,13 @@ static void preview_try_format(struct isp_prev_device *prev, *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which); switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: fmt->code = pixelcode; break; default: - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; break; } @@ -1843,8 +1841,8 @@ static void preview_try_crop(struct isp_prev_device *prev, * and no columns in other modes. Increase the margins based on the sink * format. */ - if (sink->code != V4L2_MBUS_FMT_Y8_1X8 && - sink->code != V4L2_MBUS_FMT_Y10_1X10) { + if (sink->code != MEDIA_BUS_FMT_Y8_1X8 && + sink->code != MEDIA_BUS_FMT_Y10_1X10) { left += 2; right -= 2; top += 2; @@ -2092,7 +2090,7 @@ static int preview_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = PREV_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; preview_set_format(sd, fh, &format); diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 05d1ace57451..2b9bc4839876 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -198,17 +198,16 @@ static void resizer_set_bilinear(struct isp_res_device *res, * @res: Device context. * @pixelcode: pixel code. */ -static void resizer_set_ycpos(struct isp_res_device *res, - enum v4l2_mbus_pixelcode pixelcode) +static void resizer_set_ycpos(struct isp_res_device *res, u32 pixelcode) { struct isp_device *isp = to_isp_device(res); switch (pixelcode) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_YCPOS); break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_YCPOS); break; @@ -1348,8 +1347,8 @@ static int resizer_set_selection(struct v4l2_subdev *sd, /* resizer pixel formats */ static const unsigned int resizer_formats[] = { - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; static unsigned int resizer_max_in_width(struct isp_res_device *res) @@ -1385,9 +1384,9 @@ static void resizer_try_format(struct isp_res_device *res, switch (pad) { case RESZ_PAD_SINK: - if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 && - fmt->code != V4L2_MBUS_FMT_UYVY8_1X16) - fmt->code = V4L2_MBUS_FMT_YUYV8_1X16; + if (fmt->code != MEDIA_BUS_FMT_YUYV8_1X16 && + fmt->code != MEDIA_BUS_FMT_UYVY8_1X16) + fmt->code = MEDIA_BUS_FMT_YUYV8_1X16; fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH, resizer_max_in_width(res)); @@ -1571,7 +1570,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESZ_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_YUYV8_1X16; + format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; format.format.width = 4096; format.format.height = 4096; resizer_set_format(sd, fh, &format); diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index bc38c88c7bd9..b463fe172d16 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -39,74 +39,74 @@ * corresponding in-memory formats to the table below!!! */ static struct isp_format_info formats[] = { - { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, 1, }, - { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y10, 10, 2, }, - { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y12, 12, 2, }, - { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8, 1, }, - { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8, 1, }, - { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8, 1, }, - { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8, 1, }, - { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR10_1X10, 0, + { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, 0, V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGBRG10_1X10, 0, + { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_1X10, 0, V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, 0, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, 0, V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, - V4L2_MBUS_FMT_SRGGB10_1X10, 0, + { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, 0, V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, }, - { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR10, 10, 2, }, - { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG10, 10, 2, }, - { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG10, 10, 2, }, - { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB10, 10, 2, }, - { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR12, 12, 2, }, - { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG12, 12, 2, }, - { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG12, 12, 2, }, - { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB12, 12, 2, }, - { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_UYVY8_1X16, 0, + { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, 0, V4L2_PIX_FMT_UYVY, 16, 2, }, - { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, 0, + { MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, 0, V4L2_PIX_FMT_YUYV, 16, 2, }, - { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, 0, + { MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, 0, V4L2_PIX_FMT_UYVY, 8, 2, }, - { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_YUYV8_2X8, 0, + { MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, 0, V4L2_PIX_FMT_YUYV, 8, 2, }, /* Empty entry to catch the unsupported pixel code (0) used by the CCDC * module and avoid NULL pointer dereferences. @@ -114,8 +114,7 @@ static struct isp_format_info formats[] = { { 0, } }; -const struct isp_format_info * -omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) +const struct isp_format_info *omap3isp_video_format_info(u32 code) { unsigned int i; diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h index 0b7efedc3da9..4071dd7060ea 100644 --- a/drivers/media/platform/omap3isp/ispvideo.h +++ b/drivers/media/platform/omap3isp/ispvideo.h @@ -44,10 +44,10 @@ struct v4l2_pix_format; * @bpp: Bytes per pixel (when stored in memory) */ struct isp_format_info { - enum v4l2_mbus_pixelcode code; - enum v4l2_mbus_pixelcode truncated; - enum v4l2_mbus_pixelcode uncompressed; - enum v4l2_mbus_pixelcode flavor; + u32 code; + u32 truncated; + u32 uncompressed; + u32 flavor; u32 pixelformat; unsigned int width; unsigned int bpp; @@ -206,6 +206,6 @@ void omap3isp_video_resume(struct isp_video *video, int continuous); struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); const struct isp_format_info * -omap3isp_video_format_info(enum v4l2_mbus_pixelcode code); +omap3isp_video_format_info(u32 code); #endif /* OMAP3_ISP_VIDEO_H */ diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 4f81b4c9d113..aa40c8269ab8 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -1218,11 +1218,11 @@ void s3c_camif_unregister_video_node(struct camif_dev *camif, int idx) } /* Media bus pixel formats supported at the camif input */ -static const enum v4l2_mbus_pixelcode camif_mbus_formats[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_YVYU8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_VYUY8_2X8, +static const u32 camif_mbus_formats[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, }; /* diff --git a/drivers/media/platform/s3c-camif/camif-regs.c b/drivers/media/platform/s3c-camif/camif-regs.c index 6e0c9988a191..812fb3a7c4e3 100644 --- a/drivers/media/platform/s3c-camif/camif-regs.c +++ b/drivers/media/platform/s3c-camif/camif-regs.c @@ -96,10 +96,10 @@ void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect, } static const u32 src_pixfmt_map[8][2] = { - { V4L2_MBUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR }, - { V4L2_MBUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB }, - { V4L2_MBUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY }, - { V4L2_MBUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY }, + { MEDIA_BUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR }, + { MEDIA_BUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB }, + { MEDIA_BUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY }, + { MEDIA_BUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY }, }; /* Set camera input pixel format and resolution */ diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c index 37c8bd694c5f..1d1ef211e113 100644 --- a/drivers/media/platform/s5p-tv/hdmi_drv.c +++ b/drivers/media/platform/s5p-tv/hdmi_drv.c @@ -660,7 +660,7 @@ static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd, memset(fmt, 0, sizeof(*fmt)); fmt->width = t->hact.end - t->hact.beg; fmt->height = t->vact[0].end - t->vact[0].beg; - fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */ + fmt->code = MEDIA_BUS_FMT_FIXED; /* means RGB888 */ fmt->colorspace = V4L2_COLORSPACE_SRGB; if (t->interlaced) { fmt->field = V4L2_FIELD_INTERLACED; diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c index 72cf892dd008..46f4d56aaa1b 100644 --- a/drivers/media/platform/s5p-tv/sdo_drv.c +++ b/drivers/media/platform/s5p-tv/sdo_drv.c @@ -170,7 +170,7 @@ static int sdo_g_mbus_fmt(struct v4l2_subdev *sd, /* all modes are 720 pixels wide */ fmt->width = 720; fmt->height = sdev->fmt->height; - fmt->code = V4L2_MBUS_FMT_FIXED; + fmt->code = MEDIA_BUS_FMT_FIXED; fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_JPEG; return 0; diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index e5f1d4c14f2c..047669609458 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -680,7 +680,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, struct sh_vou_geometry geo; struct v4l2_mbus_framefmt mbfmt = { /* Revisit: is this the correct code? */ - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .field = V4L2_FIELD_INTERLACED, .colorspace = V4L2_COLORSPACE_SMPTE170M, }; @@ -733,7 +733,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, /* Sanity checks */ if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || (unsigned)mbfmt.height > img_height_max || - mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) + mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; if (mbfmt.width != geo.output.width || @@ -943,7 +943,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) struct sh_vou_geometry geo; struct v4l2_mbus_framefmt mbfmt = { /* Revisit: is this the correct code? */ - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .field = V4L2_FIELD_INTERLACED, .colorspace = V4L2_COLORSPACE_SMPTE170M, }; @@ -994,7 +994,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) /* Sanity checks */ if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || (unsigned)mbfmt.height > img_height_max || - mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) + mbfmt.code != MEDIA_BUS_FMT_YUYV8_2X8) return -EIO; geo.output.width = mbfmt.width; diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c5291b001057..ee5650f4ea2d 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,25 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) } static int configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, enum v4l2_mbus_pixelcode code) + u32 height, u32 code) { u32 cfg2, cr; switch (code) { /* YUV, including grey */ - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: cr = ISI_CFG2_GRAYSCALE; break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_3; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_2; break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: cr = ISI_CFG2_YCC_SWAP_MODE_1; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cr = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ @@ -645,7 +645,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); int formats = 0, ret; /* sensor format */ - enum v4l2_mbus_pixelcode code; + u32 code; /* soc camera host format */ const struct soc_mbus_pixelfmt *fmt; @@ -670,10 +670,10 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, } switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: formats++; if (xlate) { xlate->host_fmt = &isi_camera_formats[0]; diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 2347612a4cc1..ce72bd26a6ac 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -211,7 +211,7 @@ struct emma_prp_resize { /* prp configuration for a client-host fmt pair */ struct mx2_fmt_cfg { - enum v4l2_mbus_pixelcode in_fmt; + u32 in_fmt; u32 out_fmt; struct mx2_prp_cfg cfg; }; @@ -309,7 +309,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { } }, { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, + .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8, .out_fmt = V4L2_PIX_FMT_YUYV, .cfg = { .channel = 1, @@ -323,7 +323,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { } }, { - .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8, + .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8, .out_fmt = V4L2_PIX_FMT_YUYV, .cfg = { .channel = 1, @@ -337,7 +337,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { } }, { - .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8, + .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8, .out_fmt = V4L2_PIX_FMT_YUV420, .cfg = { .channel = 2, @@ -351,7 +351,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { } }, { - .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, + .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8, .out_fmt = V4L2_PIX_FMT_YUV420, .cfg = { .channel = 2, @@ -366,9 +366,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { }, }; -static struct mx2_fmt_cfg *mx27_emma_prp_get_format( - enum v4l2_mbus_pixelcode in_fmt, - u32 out_fmt) +static struct mx2_fmt_cfg *mx27_emma_prp_get_format(u32 in_fmt, u32 out_fmt) { int i; @@ -945,7 +943,7 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_mbus_pixelfmt *fmt; struct device *dev = icd->parent; - enum v4l2_mbus_pixelcode code; + u32 code; int ret, formats = 0; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -959,8 +957,8 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, return 0; } - if (code == V4L2_MBUS_FMT_YUYV8_2X8 || - code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_YUYV8_2X8 || + code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { /* @@ -968,7 +966,7 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, * soc_mediabus.c */ xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_1_5X8); + soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_1_5X8); xlate->code = code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", xlate->host_fmt->name, code); @@ -976,11 +974,11 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, } } - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { + if (code == MEDIA_BUS_FMT_UYVY8_2X8) { formats++; if (xlate) { xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); + soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_2X8); xlate->code = code; dev_dbg(dev, "Providing host format %s for sensor code %d\n", xlate->host_fmt->name, code); diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 7696a873510d..8e52ccce66de 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -656,7 +656,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -677,7 +677,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id return 0; switch (code) { - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[0]; @@ -687,7 +687,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id mx3_camera_formats[0].name, code); } break; - case V4L2_MBUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_Y10_1X10: formats++; if (xlate) { xlate->host_fmt = &mx3_camera_formats[1]; diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 74ce8b6b79fa..e6b93281f246 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -140,7 +140,7 @@ /* buffer for one video frame */ struct omap1_cam_buf { struct videobuf_buffer vb; - enum v4l2_mbus_pixelcode code; + u32 code; int inwork; struct scatterlist *sgbuf; int sgcount; @@ -980,7 +980,7 @@ static void omap1_cam_clock_stop(struct soc_camera_host *ici) /* Duplicate standard formats based on host capability of byte swapping */ static const struct soc_mbus_lookup omap1_cam_formats[] = { { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV", @@ -990,7 +990,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU", @@ -1000,7 +1000,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY", @@ -1010,7 +1010,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY", @@ -1020,7 +1020,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, .name = "RGB555", @@ -1030,7 +1030,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555X, .name = "RGB555X", @@ -1040,7 +1040,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", @@ -1050,7 +1050,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565X, .name = "RGB565X", @@ -1068,7 +1068,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -1088,14 +1088,14 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd, return 0; switch (code) { - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: formats++; if (xlate) { xlate->host_fmt = soc_mbus_find_fmtdesc(code, diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 66178fc9f9eb..951226af0eba 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -187,7 +187,7 @@ struct pxa_cam_dma { struct pxa_buffer { /* common v4l buffer stuff -- must be first */ struct videobuf_buffer vb; - enum v4l2_mbus_pixelcode code; + u32 code; /* our descriptor lists for Y, U and V channels */ struct pxa_cam_dma dmas[3]; int inwork; @@ -1253,7 +1253,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id struct device *dev = icd->parent; int formats = 0, ret; struct pxa_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -1283,7 +1283,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id } switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: formats++; if (xlate) { xlate->host_fmt = &pxa_camera_formats[0]; @@ -1292,11 +1292,11 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id dev_dbg(dev, "Providing format %s using code %d\n", pxa_camera_formats[0].name, code); } - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_RGB565_2X8_LE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: if (xlate) dev_dbg(dev, "Providing format %s packed\n", fmt->name); diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 20defcb8b31b..8d8438b10b87 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -272,16 +272,16 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) /* input interface */ switch (icd->current_fmt->code) { - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; break; - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; @@ -921,7 +921,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, int ret, k, n; int formats = 0; struct rcar_vin_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -1010,9 +1010,9 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, cam->extra_fmt = NULL; switch (code) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV10_2X10: if (cam->extra_fmt) break; diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 20ad4a571d37..5f58ed995320 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -149,7 +149,7 @@ struct sh_mobile_ceu_cam { /* Camera cropping rectangle */ struct v4l2_rect rect; const struct soc_mbus_pixelfmt *extra_fmt; - enum v4l2_mbus_pixelcode code; + u32 code; }; static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb) @@ -861,16 +861,16 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV61: switch (cam->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ break; - case V4L2_MBUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ break; - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ break; default: @@ -1048,7 +1048,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int int ret, k, n; int formats = 0; struct sh_mobile_ceu_cam *cam; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); @@ -1141,10 +1141,10 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int cam->extra_fmt = NULL; switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: if (cam->extra_fmt) break; diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c index 05dd21a35d63..c738e27a75d7 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c @@ -59,28 +59,28 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd, switch (pdata->type) { case SH_CSI2C: switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */ - case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */ - case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */ - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_UYVY8_2X8: /* YUV422 */ + case MEDIA_BUS_FMT_YUYV8_1_5X8: /* YUV420 */ + case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: break; default: /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + mf->code = MEDIA_BUS_FMT_YUYV8_2X8; } break; case SH_CSI2I: switch (mf->code) { - case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */ - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: - case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */ - case V4L2_MBUS_FMT_SBGGR12_1X12: /* RAW12 */ + case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SBGGR10_1X10: /* RAW10 */ + case MEDIA_BUS_FMT_SBGGR12_1X12: /* RAW12 */ break; default: /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = V4L2_MBUS_FMT_SBGGR8_1X8; + mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; } break; } @@ -104,21 +104,21 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd, return -EINVAL; switch (mf->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: tmp |= 0x1e; /* YUV422 8 bit */ break; - case V4L2_MBUS_FMT_YUYV8_1_5X8: + case MEDIA_BUS_FMT_YUYV8_1_5X8: tmp |= 0x18; /* YUV420 8 bit */ break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: tmp |= 0x21; /* RGB555 */ break; - case V4L2_MBUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: tmp |= 0x22; /* RGB565 */ break; - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: tmp |= 0x2a; /* RAW8 */ break; default: diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 8e61b976da19..f4be2a1c659a 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -460,7 +460,7 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); unsigned int i, fmts = 0, raw_fmts = 0; int ret; - enum v4l2_mbus_pixelcode code; + u32 code; while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) raw_fmts++; diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index ceaddfb85e49..f2ce1ab06d53 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -62,7 +62,7 @@ static struct v4l2_subdev_core_ops platform_subdev_core_ops = { }; static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index dc02deca7563..1dbcd426683c 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -17,7 +17,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV", @@ -27,7 +27,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU", @@ -37,7 +37,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY", @@ -47,7 +47,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_2X8, + .code = MEDIA_BUS_FMT_VYUY8_2X8, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY", @@ -57,7 +57,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555, .name = "RGB555", @@ -67,7 +67,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB555X, .name = "RGB555X", @@ -77,7 +77,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565, .name = "RGB565", @@ -87,7 +87,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB565X, .name = "RGB565X", @@ -97,7 +97,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB666_1X18, + .code = MEDIA_BUS_FMT_RGB666_1X18, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB666/32bpp", @@ -106,7 +106,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_1X24, + .code = MEDIA_BUS_FMT_RGB888_1X24, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @@ -115,7 +115,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_2X12_BE, + .code = MEDIA_BUS_FMT_RGB888_2X12_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @@ -124,7 +124,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .order = SOC_MBUS_ORDER_BE, }, }, { - .code = V4L2_MBUS_FMT_RGB888_2X12_LE, + .code = MEDIA_BUS_FMT_RGB888_2X12_LE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB32, .name = "RGB888/32bpp", @@ -133,7 +133,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .order = SOC_MBUS_ORDER_LE, }, }, { - .code = V4L2_MBUS_FMT_SBGGR8_1X8, + .code = MEDIA_BUS_FMT_SBGGR8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR8, .name = "Bayer 8 BGGR", @@ -143,7 +143,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_1X10, + .code = MEDIA_BUS_FMT_SBGGR10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @@ -153,7 +153,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_Y8_1X8, + .code = MEDIA_BUS_FMT_Y8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_GREY, .name = "Grey", @@ -163,7 +163,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_Y10_1X10, + .code = MEDIA_BUS_FMT_Y10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_Y10, .name = "Grey 10bit", @@ -173,7 +173,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @@ -183,7 +183,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @@ -193,7 +193,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @@ -203,7 +203,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, + .code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR10, .name = "Bayer 10 BGGR", @@ -213,7 +213,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_JPEG_1X8, + .code = MEDIA_BUS_FMT_JPEG_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_JPEG, .name = "JPEG", @@ -223,7 +223,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, .fmt = { .fourcc = V4L2_PIX_FMT_RGB444, .name = "RGB444", @@ -233,7 +233,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_1_5X8, + .code = MEDIA_BUS_FMT_YUYV8_1_5X8, .fmt = { .fourcc = V4L2_PIX_FMT_YUV420, .name = "YUYV 4:2:0", @@ -243,7 +243,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_1_5X8, + .code = MEDIA_BUS_FMT_YVYU8_1_5X8, .fmt = { .fourcc = V4L2_PIX_FMT_YVU420, .name = "YVYU 4:2:0", @@ -253,7 +253,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_UYVY8_1X16, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_UYVY, .name = "UYVY 16bit", @@ -263,7 +263,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_VYUY8_1X16, + .code = MEDIA_BUS_FMT_VYUY8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_VYUY, .name = "VYUY 16bit", @@ -273,7 +273,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YUYV8_1X16, + .code = MEDIA_BUS_FMT_YUYV8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_YUYV, .name = "YUYV 16bit", @@ -283,7 +283,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_YVYU8_1X16, + .code = MEDIA_BUS_FMT_YVYU8_1X16, .fmt = { .fourcc = V4L2_PIX_FMT_YVYU, .name = "YVYU 16bit", @@ -293,7 +293,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG8_1X8, + .code = MEDIA_BUS_FMT_SGRBG8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG8, .name = "Bayer 8 GRBG", @@ -303,7 +303,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, + .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8, .name = "Bayer 10 BGGR DPCM 8", @@ -313,7 +313,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGBRG10_1X10, + .code = MEDIA_BUS_FMT_SGBRG10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SGBRG10, .name = "Bayer 10 GBRG", @@ -323,7 +323,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG10, .name = "Bayer 10 GRBG", @@ -333,7 +333,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SRGGB10_1X10, + .code = MEDIA_BUS_FMT_SRGGB10_1X10, .fmt = { .fourcc = V4L2_PIX_FMT_SRGGB10, .name = "Bayer 10 RGGB", @@ -343,7 +343,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SBGGR12_1X12, + .code = MEDIA_BUS_FMT_SBGGR12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SBGGR12, .name = "Bayer 12 BGGR", @@ -353,7 +353,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGBRG12_1X12, + .code = MEDIA_BUS_FMT_SGBRG12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SGBRG12, .name = "Bayer 12 GBRG", @@ -363,7 +363,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SGRBG12_1X12, + .code = MEDIA_BUS_FMT_SGRBG12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SGRBG12, .name = "Bayer 12 GRBG", @@ -373,7 +373,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = { .layout = SOC_MBUS_LAYOUT_PACKED, }, }, { - .code = V4L2_MBUS_FMT_SRGGB12_1X12, + .code = MEDIA_BUS_FMT_SRGGB12_1X12, .fmt = { .fourcc = V4L2_PIX_FMT_SRGGB12, .name = "Bayer 12 RGGB", @@ -458,7 +458,7 @@ s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, EXPORT_SYMBOL(soc_mbus_image_size); const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( - enum v4l2_mbus_pixelcode code, + u32 code, const struct soc_mbus_lookup *lookup, int n) { @@ -473,7 +473,7 @@ const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( EXPORT_SYMBOL(soc_mbus_find_fmtdesc); const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( - enum v4l2_mbus_pixelcode code) + u32 code) { return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt)); } diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index ae6870cb8339..2616483fce0b 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -101,7 +101,7 @@ struct via_camera { */ struct v4l2_pix_format sensor_format; struct v4l2_pix_format user_format; - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; }; /* @@ -143,12 +143,12 @@ static struct via_format { __u8 *desc; __u32 pixelformat; int bpp; /* Bytes per pixel */ - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; } via_formats[] = { { .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, }, /* RGB444 and Bayer should be doable, but have never been @@ -849,7 +849,7 @@ static const struct v4l2_pix_format viacam_def_pix_format = { .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, }; -static const enum v4l2_mbus_pixelcode via_def_mbus_code = V4L2_MBUS_FMT_YUYV8_2X8; +static const u32 via_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_fmtdesc *fmt) diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c index a0c1984c733e..b21f381a9862 100644 --- a/drivers/media/platform/vsp1/vsp1_bru.c +++ b/drivers/media/platform/vsp1/vsp1_bru.c @@ -187,8 +187,8 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @@ -215,8 +215,8 @@ static int bru_enum_frame_size(struct v4l2_subdev *subdev, if (fse->index) return -EINVAL; - if (fse->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fse->code != V4L2_MBUS_FMT_AYUV8_1X32) + if (fse->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fse->code != MEDIA_BUS_FMT_AYUV8_1X32) return -EINVAL; fse->min_width = BRU_MIN_SIZE; @@ -261,9 +261,9 @@ static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh, switch (pad) { case BRU_PAD_SINK(0): /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; break; default: diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c index db2950a73c60..80bedc554ee3 100644 --- a/drivers/media/platform/vsp1/vsp1_hsit.c +++ b/drivers/media/platform/vsp1/vsp1_hsit.c @@ -70,9 +70,9 @@ static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, if ((code->pad == HSIT_PAD_SINK && !hsit->inverse) | (code->pad == HSIT_PAD_SOURCE && hsit->inverse)) - code->code = V4L2_MBUS_FMT_ARGB8888_1X32; + code->code = MEDIA_BUS_FMT_ARGB8888_1X32; else - code->code = V4L2_MBUS_FMT_AHSV8888_1X32; + code->code = MEDIA_BUS_FMT_AHSV8888_1X32; return 0; } @@ -136,8 +136,8 @@ static int hsit_set_format(struct v4l2_subdev *subdev, return 0; } - format->code = hsit->inverse ? V4L2_MBUS_FMT_AHSV8888_1X32 - : V4L2_MBUS_FMT_ARGB8888_1X32; + format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32 + : MEDIA_BUS_FMT_ARGB8888_1X32; format->width = clamp_t(unsigned int, fmt->format.width, HSIT_MIN_SIZE, HSIT_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, @@ -151,8 +151,8 @@ static int hsit_set_format(struct v4l2_subdev *subdev, format = vsp1_entity_get_pad_format(&hsit->entity, fh, HSIT_PAD_SOURCE, fmt->which); *format = fmt->format; - format->code = hsit->inverse ? V4L2_MBUS_FMT_ARGB8888_1X32 - : V4L2_MBUS_FMT_AHSV8888_1X32; + format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 + : MEDIA_BUS_FMT_AHSV8888_1X32; return 0; } diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index d4fb23e9c4a8..17a6ca7dafe6 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c @@ -78,8 +78,8 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->pad == LIF_PAD_SINK) { @@ -147,9 +147,9 @@ static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_mbus_framefmt *format; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, fmt->which); diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c index fea36ebe2565..6f185c3621fe 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.c +++ b/drivers/media/platform/vsp1/vsp1_lut.c @@ -86,9 +86,9 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AHSV8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AHSV8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @@ -158,10 +158,10 @@ static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_mbus_framefmt *format; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AHSV8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, fmt->which); diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c index ec3dab6a9b9b..1f1ba26a834a 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.c +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c @@ -29,8 +29,8 @@ int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->index >= ARRAY_SIZE(codes)) @@ -103,9 +103,9 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_rect *crop; /* Default to YUV if the requested format is not supported. */ - if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, fmt->which); diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c index b7d3c8b9f189..1129494c7cfc 100644 --- a/drivers/media/platform/vsp1/vsp1_sru.c +++ b/drivers/media/platform/vsp1/vsp1_sru.c @@ -139,7 +139,7 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable) input = &sru->entity.formats[SRU_PAD_SINK]; output = &sru->entity.formats[SRU_PAD_SOURCE]; - if (input->code == V4L2_MBUS_FMT_ARGB8888_1X32) + if (input->code == MEDIA_BUS_FMT_ARGB8888_1X32) ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3 | VI6_SRU_CTRL0_PARAM4; else @@ -170,8 +170,8 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; struct v4l2_mbus_framefmt *format; @@ -248,9 +248,9 @@ static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh, switch (pad) { case SRU_PAD_SINK: /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; fmt->width = clamp(fmt->width, SRU_MIN_SIZE, SRU_MAX_SIZE); fmt->height = clamp(fmt->height, SRU_MIN_SIZE, SRU_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index de92ef4944b3..a4afec133800 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -173,8 +173,8 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { - V4L2_MBUS_FMT_ARGB8888_1X32, - V4L2_MBUS_FMT_AYUV8_1X32, + MEDIA_BUS_FMT_ARGB8888_1X32, + MEDIA_BUS_FMT_AYUV8_1X32, }; if (code->pad == UDS_PAD_SINK) { @@ -246,9 +246,9 @@ static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, switch (pad) { case UDS_PAD_SINK: /* Default to YUV if the requested format is not supported. */ - if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && - fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) - fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; + if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && + fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) + fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; fmt->width = clamp(fmt->width, UDS_MIN_SIZE, UDS_MAX_SIZE); fmt->height = clamp(fmt->height, UDS_MIN_SIZE, UDS_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 915a20eb003e..d91f19a9e1c1 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -48,85 +48,85 @@ */ static const struct vsp1_format_info vsp1_video_formats[] = { - { V4L2_PIX_FMT_RGB332, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 8, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ARGB444, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB444, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_ARGB555, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB555, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_RGB565, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS, 1, { 16, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_BGR24, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 24, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_RGB24, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 24, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ABGR32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, 1, { 32, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XBGR32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, 1, { 32, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_ARGB32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 32, 0, 0 }, false, false, 1, 1, true }, - { V4L2_PIX_FMT_XRGB32, V4L2_MBUS_FMT_ARGB8888_1X32, + { V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32, VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 32, 0, 0 }, false, false, 1, 1, false }, - { V4L2_PIX_FMT_UYVY, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, false, false, 2, 1, false }, - { V4L2_PIX_FMT_VYUY, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, false, true, 2, 1, false }, - { V4L2_PIX_FMT_YUYV, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, true, false, 2, 1, false }, - { V4L2_PIX_FMT_YVYU, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 1, { 16, 0, 0 }, true, true, 2, 1, false }, - { V4L2_PIX_FMT_NV12M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, false, 2, 2, false }, - { V4L2_PIX_FMT_NV21M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, true, 2, 2, false }, - { V4L2_PIX_FMT_NV16M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, false, 2, 1, false }, - { V4L2_PIX_FMT_NV61M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 2, { 8, 16, 0 }, false, true, 2, 1, false }, - { V4L2_PIX_FMT_YUV420M, V4L2_MBUS_FMT_AYUV8_1X32, + { V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32, VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, 3, { 8, 8, 8 }, false, false, 2, 2, false }, diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h index 57585c7004a4..4376beeb28c2 100644 --- a/include/media/davinci/vpbe.h +++ b/include/media/davinci/vpbe.h @@ -63,7 +63,7 @@ struct vpbe_output { * output basis. If per mode is needed, we may have to move this to * mode_info structure */ - enum v4l2_mbus_pixelcode if_params; + u32 if_params; }; /* encoder configuration info */ diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h index 476fafc2f522..3dbd20026107 100644 --- a/include/media/davinci/vpbe_venc.h +++ b/include/media/davinci/vpbe_venc.h @@ -30,11 +30,10 @@ #define VENC_SECOND_FIELD BIT(2) struct venc_platform_data { - int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type, - int field); + int (*setup_pinmux)(u32 if_type, int field); int (*setup_clock)(enum vpbe_enc_timings_type type, unsigned int pixclock); - int (*setup_if_config)(enum v4l2_mbus_pixelcode pixcode); + int (*setup_if_config)(u32 pixcode); /* Number of LCD outputs supported */ int num_lcd_outputs; struct vpbe_if_params *lcd_if_params; diff --git a/include/media/exynos-fimc.h b/include/media/exynos-fimc.h index aa44660e2041..69bcd2a07d5c 100644 --- a/include/media/exynos-fimc.h +++ b/include/media/exynos-fimc.h @@ -101,7 +101,7 @@ struct fimc_source_info { * @flags: flags indicating which operation mode format applies to */ struct fimc_fmt { - enum v4l2_mbus_pixelcode mbus_code; + u32 mbus_code; char *name; u32 fourcc; u32 color; diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 865246b00127..2f6261f3e570 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -296,7 +296,7 @@ const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( * format setup. */ struct soc_camera_format_xlate { - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *host_fmt; }; diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h index d33f6d059692..2ff773785fb6 100644 --- a/include/media/soc_mediabus.h +++ b/include/media/soc_mediabus.h @@ -91,16 +91,16 @@ struct soc_mbus_pixelfmt { * @fmt: pixel format description */ struct soc_mbus_lookup { - enum v4l2_mbus_pixelcode code; + u32 code; struct soc_mbus_pixelfmt fmt; }; const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( - enum v4l2_mbus_pixelcode code, + u32 code, const struct soc_mbus_lookup *lookup, int n); const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( - enum v4l2_mbus_pixelcode code); + u32 code); s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, u32 bytes_per_line, u32 height); -- GitLab From 18cb5ec38f427f4552b4435ce2021f6fb21743f4 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:32 -0300 Subject: [PATCH 4856/9457] [media] usb: Make use of media_bus_format enum In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed enum values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Reference new definitions in all usb drivers. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 4 ++-- drivers/media/usb/em28xx/em28xx-camera.c | 2 +- drivers/media/usb/go7007/go7007-v4l2.c | 2 +- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 8998fa4a43f6..3f295b4d1a3d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1887,7 +1887,7 @@ static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 4c5bba2e89f4..53ca12c1ff69 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -968,7 +968,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->height = f->fmt.pix.height; dev->format = fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); @@ -1013,7 +1013,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) resolution (since a standard change effects things like the number of lines in VACT, etc) */ memset(&mbus_fmt, 0, sizeof(mbus_fmt)); - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = dev->width; mbus_fmt.height = dev->height; call_all(dev, video, s_mbus_fmt, &mbus_fmt); diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 6d2ea9afd57b..38cf6c8491a4 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -430,7 +430,7 @@ int em28xx_init_camera(struct em28xx *dev) break; } - fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt.code = MEDIA_BUS_FMT_YUYV8_2X8; fmt.width = 640; fmt.height = 480; v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index ec799b4d88be..d6bf982efa42 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -252,7 +252,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { struct v4l2_mbus_framefmt mbus_fmt; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = fmt ? fmt->fmt.pix.width : width; mbus_fmt.height = height; go->encoder_h_halve = 0; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 9623b6218214..2fd9b5e0e2a9 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2966,7 +2966,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) memset(&fmt, 0, sizeof(fmt)); fmt.width = hdw->res_hor_val; fmt.height = hdw->res_ver_val; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", fmt.width, fmt.height); v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); -- GitLab From 3336f07aa6bccf86d59b16f91b8ecb95bf8c1910 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:33 -0300 Subject: [PATCH 4857/9457] [media] staging: media: Make use of MEDIA_BUS_FMT_ definitions In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Reference new definitions in all media drivers residing in staging. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Sakari Ailus Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/davinci_vpfe/dm365_ipipe.c | 18 ++-- .../media/davinci_vpfe/dm365_ipipe_hw.c | 26 ++--- .../media/davinci_vpfe/dm365_ipipeif.c | 100 +++++++++--------- .../staging/media/davinci_vpfe/dm365_isif.c | 90 ++++++++-------- .../media/davinci_vpfe/dm365_resizer.c | 98 ++++++++--------- .../media/davinci_vpfe/vpfe_mc_capture.c | 18 ++-- drivers/staging/media/omap4iss/iss_csi2.c | 62 +++++------ drivers/staging/media/omap4iss/iss_ipipe.c | 16 +-- drivers/staging/media/omap4iss/iss_ipipeif.c | 28 ++--- drivers/staging/media/omap4iss/iss_resizer.c | 26 ++--- drivers/staging/media/omap4iss/iss_video.c | 78 +++++++------- drivers/staging/media/omap4iss/iss_video.h | 10 +- 12 files changed, 285 insertions(+), 285 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index bdc7f005b3ba..704fa202ee18 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -37,15 +37,15 @@ /* ipipe input format's */ static const unsigned int ipipe_input_fmts[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, }; /* ipipe output format's */ static const unsigned int ipipe_output_fmts[] = { - V4L2_MBUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, }; static int ipipe_validate_lutdpc_params(struct vpfe_ipipe_lutdpc *lutdpc) @@ -1457,7 +1457,7 @@ ipipe_try_format(struct vpfe_ipipe_device *ipipe, /* If not found, use SBGGR10 as default */ if (i >= ARRAY_SIZE(ipipe_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG12_1X12; + fmt->code = MEDIA_BUS_FMT_SGRBG12_1X12; } else if (pad == IPIPE_PAD_SOURCE) { for (i = 0; i < ARRAY_SIZE(ipipe_output_fmts); i++) if (fmt->code == ipipe_output_fmts[i]) @@ -1465,7 +1465,7 @@ ipipe_try_format(struct vpfe_ipipe_device *ipipe, /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(ipipe_output_fmts)) - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; } fmt->width = clamp_t(u32, fmt->width, MIN_OUT_HEIGHT, max_out_width); @@ -1642,7 +1642,7 @@ ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = IPIPE_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A; ipipe_set_format(sd, fh, &format); @@ -1650,7 +1650,7 @@ ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = IPIPE_PAD_SOURCE; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A; ipipe_set_format(sd, fh, &format); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c index b2daf5e63f88..6461de1a61fd 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c @@ -196,12 +196,12 @@ ipipe_setup_resizer(void *__iomem rsz_base, struct resizer_params *params) rsz_set_rsz_regs(rsz_base, RSZ_B, params); } -static u32 ipipe_get_color_pat(enum v4l2_mbus_pixelcode pix) +static u32 ipipe_get_color_pat(u32 pix) { switch (pix) { - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG12_1X12: return ipipe_sgrbg_pattern; default: @@ -211,23 +211,23 @@ static u32 ipipe_get_color_pat(enum v4l2_mbus_pixelcode pix) static int ipipe_get_data_path(struct vpfe_ipipe_device *ipipe) { - enum v4l2_mbus_pixelcode temp_pix_fmt; + u32 temp_pix_fmt; switch (ipipe->formats[IPIPE_PAD_SINK].code) { - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG12_1X12: - temp_pix_fmt = V4L2_MBUS_FMT_SGRBG12_1X12; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG12_1X12: + temp_pix_fmt = MEDIA_BUS_FMT_SGRBG12_1X12; break; default: - temp_pix_fmt = V4L2_MBUS_FMT_UYVY8_2X8; + temp_pix_fmt = MEDIA_BUS_FMT_UYVY8_2X8; } - if (temp_pix_fmt == V4L2_MBUS_FMT_SGRBG12_1X12) { + if (temp_pix_fmt == MEDIA_BUS_FMT_SGRBG12_1X12) { if (ipipe->formats[IPIPE_PAD_SOURCE].code == - V4L2_MBUS_FMT_SGRBG12_1X12) + MEDIA_BUS_FMT_SGRBG12_1X12) return IPIPE_RAW2RAW; return IPIPE_RAW2YUV; } diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index 6d4893b44c1f..a86f16ff5818 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -23,42 +23,42 @@ #include "vpfe_mc_capture.h" static const unsigned int ipipeif_input_fmts[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_UV8_1X8, - V4L2_MBUS_FMT_YDYUYDYV8_1X16, - V4L2_MBUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_UV8_1X8, + MEDIA_BUS_FMT_YDYUYDYV8_1X16, + MEDIA_BUS_FMT_SBGGR8_1X8, }; static const unsigned int ipipeif_output_fmts[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_UV8_1X8, - V4L2_MBUS_FMT_YDYUYDYV8_1X16, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_UV8_1X8, + MEDIA_BUS_FMT_YDYUYDYV8_1X16, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, }; static int -ipipeif_get_pack_mode(enum v4l2_mbus_pixelcode in_pix_fmt) +ipipeif_get_pack_mode(u32 in_pix_fmt) { switch (in_pix_fmt) { - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_UV8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_UV8_1X8: return IPIPEIF_5_1_PACK_8_BIT; - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: return IPIPEIF_5_1_PACK_8_BIT_A_LAW; - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: return IPIPEIF_5_1_PACK_16_BIT; - case V4L2_MBUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SBGGR12_1X12: return IPIPEIF_5_1_PACK_12_BIT; default: @@ -107,8 +107,8 @@ ipipeif_get_cfg_src1(struct vpfe_ipipeif_device *ipipeif) informat = &ipipeif->formats[IPIPEIF_PAD_SINK]; if (ipipeif->input == IPIPEIF_INPUT_MEMORY && - (informat->code == V4L2_MBUS_FMT_Y8_1X8 || - informat->code == V4L2_MBUS_FMT_UV8_1X8)) + (informat->code == MEDIA_BUS_FMT_Y8_1X8 || + informat->code == MEDIA_BUS_FMT_UV8_1X8)) return IPIPEIF_CCDC; return IPIPEIF_SRC1_PARALLEL_PORT; @@ -122,11 +122,11 @@ ipipeif_get_data_shift(struct vpfe_ipipeif_device *ipipeif) informat = &ipipeif->formats[IPIPEIF_PAD_SINK]; switch (informat->code) { - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: return IPIPEIF_5_1_BITS11_0; - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_UV8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_UV8_1X8: return IPIPEIF_5_1_BITS11_0; default: @@ -143,7 +143,7 @@ ipipeif_get_source(struct vpfe_ipipeif_device *ipipeif) if (ipipeif->input == IPIPEIF_INPUT_ISIF) return IPIPEIF_CCDC; - if (informat->code == V4L2_MBUS_FMT_UYVY8_2X8) + if (informat->code == MEDIA_BUS_FMT_UYVY8_2X8) return IPIPEIF_SDRAM_YUV; return IPIPEIF_SDRAM_RAW; @@ -190,7 +190,7 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd) struct v4l2_mbus_framefmt *informat, *outformat; struct ipipeif_params params = ipipeif->config; enum ipipeif_input_source ipipeif_source; - enum v4l2_mbus_pixelcode isif_port_if; + u32 isif_port_if; void *ipipeif_base_addr; unsigned int val; int data_shift; @@ -268,16 +268,16 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd) ipipeif_write(val, ipipeif_base_addr, IPIPEIF_INIRSZ); isif_port_if = informat->code; - if (isif_port_if == V4L2_MBUS_FMT_Y8_1X8) - isif_port_if = V4L2_MBUS_FMT_YUYV8_1X16; - else if (isif_port_if == V4L2_MBUS_FMT_UV8_1X8) - isif_port_if = V4L2_MBUS_FMT_SGRBG12_1X12; + if (isif_port_if == MEDIA_BUS_FMT_Y8_1X8) + isif_port_if = MEDIA_BUS_FMT_YUYV8_1X16; + else if (isif_port_if == MEDIA_BUS_FMT_UV8_1X8) + isif_port_if = MEDIA_BUS_FMT_SGRBG12_1X12; /* Enable DPCM decompression */ switch (ipipeif_source) { case IPIPEIF_SDRAM_RAW: val = 0; - if (outformat->code == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8) { + if (outformat->code == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) { val = 1; val |= (IPIPEIF_DPCM_8BIT_10BIT & 1) << IPIPEIF_DPCM_BITS_SHIFT; @@ -296,9 +296,9 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd) /* configure CFG2 */ val = ipipeif_read(ipipeif_base_addr, IPIPEIF_CFG2); switch (isif_port_if) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_Y8_1X8: RESETBIT(val, IPIPEIF_CFG2_YUV8_SHIFT); SETBIT(val, IPIPEIF_CFG2_YUV16_SHIFT); ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2); @@ -344,16 +344,16 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd) val |= VPFE_PINPOL_POSITIVE << IPIPEIF_CFG2_VDPOL_SHIFT; switch (isif_port_if) { - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV10_1X20: RESETBIT(val, IPIPEIF_CFG2_YUV8_SHIFT); SETBIT(val, IPIPEIF_CFG2_YUV16_SHIFT); break; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YUYV10_2X10: SETBIT(val, IPIPEIF_CFG2_YUV8_SHIFT); SETBIT(val, IPIPEIF_CFG2_YUV16_SHIFT); val |= IPIPEIF_CBCR_Y << IPIPEIF_CFG2_YUV8P_SHIFT; @@ -625,7 +625,7 @@ ipipeif_try_format(struct vpfe_ipipeif_device *ipipeif, /* If not found, use SBGGR10 as default */ if (i >= ARRAY_SIZE(ipipeif_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG12_1X12; + fmt->code = MEDIA_BUS_FMT_SGRBG12_1X12; } else if (pad == IPIPEIF_PAD_SOURCE) { for (i = 0; i < ARRAY_SIZE(ipipeif_output_fmts); i++) if (fmt->code == ipipeif_output_fmts[i]) @@ -633,7 +633,7 @@ ipipeif_try_format(struct vpfe_ipipeif_device *ipipeif, /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(ipipeif_output_fmts)) - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; } fmt->width = clamp_t(u32, fmt->width, MIN_OUT_HEIGHT, max_out_width); @@ -770,7 +770,7 @@ ipipeif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = IPIPEIF_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A; ipipeif_set_format(sd, fh, &format); @@ -778,7 +778,7 @@ ipipeif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = IPIPEIF_PAD_SOURCE; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A; ipipeif_set_format(sd, fh, &format); @@ -805,9 +805,9 @@ ipipeif_video_in_queue(struct vpfe_device *vpfe_dev, unsigned long addr) return -EINVAL; switch (ipipeif->formats[IPIPEIF_PAD_SINK].code) { - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_UV8_1X8: - case V4L2_MBUS_FMT_YDYUYDYV8_1X16: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_UV8_1X8: + case MEDIA_BUS_FMT_YDYUYDYV8_1X16: adofs = ipipeif->formats[IPIPEIF_PAD_SINK].width; break; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 0d535b062e4e..fa26f63831b7 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -27,13 +27,13 @@ #define MAX_HEIGHT 4096 static const unsigned int isif_fmts[] = { - V4L2_MBUS_FMT_YUYV8_2X8, - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_YUYV8_1X16, - V4L2_MBUS_FMT_YUYV10_1X20, - V4L2_MBUS_FMT_SGRBG12_1X12, - V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV10_1X20, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, }; #define ISIF_COLPTN_R_Ye 0x0 @@ -154,7 +154,7 @@ enum v4l2_field vpfe_isif_get_fid(struct vpfe_device *vpfe_dev) static int isif_set_pixel_format(struct vpfe_isif_device *isif, unsigned int pixfmt) { - if (isif->formats[ISIF_PAD_SINK].code == V4L2_MBUS_FMT_SGRBG12_1X12) { + if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) { if (pixfmt == V4L2_PIX_FMT_SBGGR16) isif->isif_cfg.data_pack = ISIF_PACK_16BIT; else if ((pixfmt == V4L2_PIX_FMT_SGRBG10DPCM8) || @@ -184,7 +184,7 @@ static int isif_set_frame_format(struct vpfe_isif_device *isif, enum isif_frmfmt frm_fmt) { - if (isif->formats[ISIF_PAD_SINK].code == V4L2_MBUS_FMT_SGRBG12_1X12) + if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) isif->isif_cfg.bayer.frm_fmt = frm_fmt; else isif->isif_cfg.ycbcr.frm_fmt = frm_fmt; @@ -196,7 +196,7 @@ static int isif_set_image_window(struct vpfe_isif_device *isif) { struct v4l2_rect *win = &isif->crop; - if (isif->formats[ISIF_PAD_SINK].code == V4L2_MBUS_FMT_SGRBG12_1X12) { + if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) { isif->isif_cfg.bayer.win.top = win->top; isif->isif_cfg.bayer.win.left = win->left; isif->isif_cfg.bayer.win.width = win->width; @@ -214,7 +214,7 @@ static int isif_set_image_window(struct vpfe_isif_device *isif) static int isif_set_buftype(struct vpfe_isif_device *isif, enum isif_buftype buf_type) { - if (isif->formats[ISIF_PAD_SINK].code == V4L2_MBUS_FMT_SGRBG12_1X12) + if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) isif->isif_cfg.bayer.buf_type = buf_type; else isif->isif_cfg.ycbcr.buf_type = buf_type; @@ -296,7 +296,7 @@ isif_try_format(struct vpfe_isif_device *isif, struct v4l2_subdev_fh *fh, /* If not found, use YUYV8_2x8 as default */ if (i >= ARRAY_SIZE(isif_fmts)) - fmt->format.code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt->format.code = MEDIA_BUS_FMT_YUYV8_2X8; /* Clamp the size. */ fmt->format.width = clamp_t(u32, width, 32, MAX_WIDTH); @@ -429,7 +429,7 @@ static int isif_get_params(struct v4l2_subdev *sd, void *params) struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); /* only raw module parameters can be set through the IOCTL */ - if (isif->formats[ISIF_PAD_SINK].code != V4L2_MBUS_FMT_SGRBG12_1X12) + if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12) return -EINVAL; memcpy(params, &isif->isif_cfg.bayer.config_params, sizeof(isif->isif_cfg.bayer.config_params)); @@ -604,7 +604,7 @@ static int isif_set_params(struct v4l2_subdev *sd, void *params) int ret = -EINVAL; /* only raw module parameters can be set through the IOCTL */ - if (isif->formats[ISIF_PAD_SINK].code != V4L2_MBUS_FMT_SGRBG12_1X12) + if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12) return ret; memcpy(&isif_raw_params, params, sizeof(isif_raw_params)); @@ -1041,19 +1041,19 @@ isif_config_culling(struct vpfe_isif_device *isif, struct vpfe_isif_cul *cul) static int isif_get_pix_fmt(u32 mbus_code) { switch (mbus_code) { - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG12_1X12: return ISIF_PIXFMT_RAW; - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_YUYV10_2X10: - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_Y8_1X8: return ISIF_PIXFMT_YCBCR_8BIT; - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV10_1X20: return ISIF_PIXFMT_YCBCR_16BIT; default: @@ -1121,11 +1121,11 @@ static int isif_config_raw(struct v4l2_subdev *sd, int mode) ISIF_FRM_FMT_MASK) << ISIF_FRM_FMT_SHIFT) | ((pix_fmt & ISIF_INPUT_MASK) << ISIF_INPUT_SHIFT); - /* currently only V4L2_MBUS_FMT_SGRBG12_1X12 is + /* currently only MEDIA_BUS_FMT_SGRBG12_1X12 is * supported. shift appropriately depending on * different MBUS fmt's added */ - if (format->code == V4L2_MBUS_FMT_SGRBG12_1X12) + if (format->code == MEDIA_BUS_FMT_SGRBG12_1X12) val |= ((VPFE_ISIF_NO_SHIFT & ISIF_DATASFT_MASK) << ISIF_DATASFT_SHIFT); @@ -1154,7 +1154,7 @@ static int isif_config_raw(struct v4l2_subdev *sd, int mode) /* Configure Gain & Offset */ isif_config_gain_offset(isif); /* Configure Color pattern */ - if (format->code == V4L2_MBUS_FMT_SGRBG12_1X12) + if (format->code == MEDIA_BUS_FMT_SGRBG12_1X12) val = isif_sgrbg_pattern; else /* default set to rggb */ @@ -1254,8 +1254,8 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) (((params->vd_pol & ISIF_VD_POL_MASK) << ISIF_VD_POL_SHIFT)); /* pack the data to 8-bit CCDCCFG */ switch (format->code) { - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) { pr_debug("Invalid pix_fmt(input mode)\n"); return -EINVAL; @@ -1266,7 +1266,7 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) ccdcfg = ccdcfg | ISIF_PACK_8BIT | ISIF_YCINSWP_YCBCR; break; - case V4L2_MBUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV10_2X10: if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) { pr_debug("Invalid pix_fmt(input mode)\n"); return -EINVAL; @@ -1278,7 +1278,7 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) ISIF_BW656_ENABLE; break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: if (pix_fmt != ISIF_PIXFMT_YCBCR_16BIT) { pr_debug("Invalid pix_fmt(input mode)\n"); return -EINVAL; @@ -1286,7 +1286,7 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) isif_write(isif->isif_cfg.base_addr, 3, REC656IF); break; - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: ccdcfg |= ISIF_PACK_8BIT; ccdcfg |= ISIF_YCINSWP_YCBCR; if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) { @@ -1295,7 +1295,7 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) } break; - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: if (pix_fmt != ISIF_PIXFMT_YCBCR_16BIT) { pr_debug("Invalid pix_fmt(input mode)\n"); return -EINVAL; @@ -1313,8 +1313,8 @@ static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode) ISIF_PIX_ORDER_SHIFT; isif_write(isif->isif_cfg.base_addr, ccdcfg, CCDCFG); /* configure video window */ - if (format->code == V4L2_MBUS_FMT_YUYV10_1X20 || - format->code == V4L2_MBUS_FMT_YUYV8_1X16) + if (format->code == MEDIA_BUS_FMT_YUYV10_1X20 || + format->code == MEDIA_BUS_FMT_YUYV8_1X16) isif_setwin(isif, ¶ms->win, params->frm_fmt, 1, mode); else isif_setwin(isif, ¶ms->win, params->frm_fmt, 2, mode); @@ -1345,17 +1345,17 @@ static int isif_configure(struct v4l2_subdev *sd, int mode) format = &isif->formats[ISIF_PAD_SINK]; switch (format->code) { - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG12_1X12: return isif_config_raw(sd, mode); - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_YUYV10_2X10: - case V4L2_MBUS_FMT_Y8_1X8: - case V4L2_MBUS_FMT_YUYV8_1X16: - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV10_1X20: return isif_config_ycbcr(sd, mode); default: @@ -1630,7 +1630,7 @@ isif_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = ISIF_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12; format.format.width = MAX_WIDTH; format.format.height = MAX_HEIGHT; isif_set_format(sd, fh, &format); @@ -1638,7 +1638,7 @@ isif_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = ISIF_PAD_SOURCE; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG12_1X12; + format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12; format.format.width = MAX_WIDTH; format.format.height = MAX_HEIGHT; isif_set_format(sd, fh, &format); diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 8828d6c2aab1..e0b29c8ca221 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -35,18 +35,18 @@ #define MIN_OUT_HEIGHT 2 static const unsigned int resizer_input_formats[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_UV8_1X8, - V4L2_MBUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_UV8_1X8, + MEDIA_BUS_FMT_SGRBG12_1X12, }; static const unsigned int resizer_output_formats[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_UV8_1X8, - V4L2_MBUS_FMT_YDYUYDYV8_1X16, - V4L2_MBUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_UV8_1X8, + MEDIA_BUS_FMT_YDYUYDYV8_1X16, + MEDIA_BUS_FMT_SGRBG12_1X12, }; /* resizer_calculate_line_length() - This function calculates the line length of @@ -54,17 +54,17 @@ static const unsigned int resizer_output_formats[] = { * output. */ static void -resizer_calculate_line_length(enum v4l2_mbus_pixelcode pix, int width, - int height, int *line_len, int *line_len_c) +resizer_calculate_line_length(u32 pix, int width, int height, + int *line_len, int *line_len_c) { *line_len = 0; *line_len_c = 0; - if (pix == V4L2_MBUS_FMT_UYVY8_2X8 || - pix == V4L2_MBUS_FMT_SGRBG12_1X12) { + if (pix == MEDIA_BUS_FMT_UYVY8_2X8 || + pix == MEDIA_BUS_FMT_SGRBG12_1X12) { *line_len = width << 1; - } else if (pix == V4L2_MBUS_FMT_Y8_1X8 || - pix == V4L2_MBUS_FMT_UV8_1X8) { + } else if (pix == MEDIA_BUS_FMT_Y8_1X8 || + pix == MEDIA_BUS_FMT_UV8_1X8) { *line_len = width; *line_len_c = width; } else { @@ -85,11 +85,11 @@ resizer_validate_output_image_format(struct device *dev, struct v4l2_mbus_framefmt *format, int *in_line_len, int *in_line_len_c) { - if (format->code != V4L2_MBUS_FMT_UYVY8_2X8 && - format->code != V4L2_MBUS_FMT_Y8_1X8 && - format->code != V4L2_MBUS_FMT_UV8_1X8 && - format->code != V4L2_MBUS_FMT_YDYUYDYV8_1X16 && - format->code != V4L2_MBUS_FMT_SGRBG12_1X12) { + if (format->code != MEDIA_BUS_FMT_UYVY8_2X8 && + format->code != MEDIA_BUS_FMT_Y8_1X8 && + format->code != MEDIA_BUS_FMT_UV8_1X8 && + format->code != MEDIA_BUS_FMT_YDYUYDYV8_1X16 && + format->code != MEDIA_BUS_FMT_SGRBG12_1X12) { dev_err(dev, "Invalid Mbus format, %d\n", format->code); return -EINVAL; } @@ -281,7 +281,7 @@ resizer_calculate_sdram_offsets(struct vpfe_resizer_device *resizer, int index) param->ext_mem_param[index].c_offset = 0; param->ext_mem_param[index].flip_ofst_y = 0; param->ext_mem_param[index].flip_ofst_c = 0; - if (outformat->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) { + if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) { /* YUV 420 */ yuv_420 = 1; bytesperpixel = 1; @@ -322,7 +322,7 @@ static int resizer_configure_output_win(struct vpfe_resizer_device *resizer) outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE]; output_specs.vst_y = param->user_config.vst; - if (outformat->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) + if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) output_specs.vst_c = param->user_config.vst; configure_resizer_out_params(resizer, RSZ_A, &output_specs, 0, 0); @@ -336,7 +336,7 @@ static int resizer_configure_output_win(struct vpfe_resizer_device *resizer) if (param->rsz_en[RSZ_B]) resizer_calculate_resize_ratios(resizer, RSZ_B); - if (outformat->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) + if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) resizer_enable_422_420_conversion(param, RSZ_A, ENABLE); else resizer_enable_422_420_conversion(param, RSZ_A, DISABLE); @@ -447,26 +447,26 @@ resizer_configure_common_in_params(struct vpfe_resizer_device *resizer) param->rsz_common.source = IPIPE_DATA; switch (informat->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: param->rsz_common.src_img_fmt = RSZ_IMG_422; param->rsz_common.raw_flip = 0; break; - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: param->rsz_common.src_img_fmt = RSZ_IMG_420; /* Select y */ param->rsz_common.y_c = 0; param->rsz_common.raw_flip = 0; break; - case V4L2_MBUS_FMT_UV8_1X8: + case MEDIA_BUS_FMT_UV8_1X8: param->rsz_common.src_img_fmt = RSZ_IMG_420; /* Select y */ param->rsz_common.y_c = 1; param->rsz_common.raw_flip = 0; break; - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: param->rsz_common.raw_flip = 1; break; @@ -519,7 +519,7 @@ resizer_configure_in_continious_mode(struct vpfe_resizer_device *resizer) param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c; configure_resizer_out_params(resizer, RSZ_B, &cont_config->output2, 0, 1); - if (outformat2->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) + if (outformat2->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) resizer_enable_422_420_conversion(param, RSZ_B, ENABLE); else @@ -540,15 +540,15 @@ resizer_configure_in_continious_mode(struct vpfe_resizer_device *resizer) static inline int resizer_validate_input_image_format(struct device *dev, - enum v4l2_mbus_pixelcode pix, + u32 pix, int width, int height, int *line_len) { int val; - if (pix != V4L2_MBUS_FMT_UYVY8_2X8 && - pix != V4L2_MBUS_FMT_Y8_1X8 && - pix != V4L2_MBUS_FMT_UV8_1X8 && - pix != V4L2_MBUS_FMT_SGRBG12_1X12) { + if (pix != MEDIA_BUS_FMT_UYVY8_2X8 && + pix != MEDIA_BUS_FMT_Y8_1X8 && + pix != MEDIA_BUS_FMT_UV8_1X8 && + pix != MEDIA_BUS_FMT_SGRBG12_1X12) { dev_err(dev, "resizer validate output: pix format not supported, %d\n", pix); return -EINVAL; @@ -560,7 +560,7 @@ resizer_validate_input_image_format(struct device *dev, return -EINVAL; } - if (pix == V4L2_MBUS_FMT_UV8_1X8) + if (pix == MEDIA_BUS_FMT_UV8_1X8) resizer_calculate_line_length(pix, width, height, &val, line_len); else @@ -709,12 +709,12 @@ resizer_configure_in_single_shot_mode(struct vpfe_resizer_device *resizer) configure_resizer_out_params(resizer, RSZ_A, ¶m->user_config.output1, 0, 1); - if (outformat1->code == V4L2_MBUS_FMT_SGRBG12_1X12) + if (outformat1->code == MEDIA_BUS_FMT_SGRBG12_1X12) param->rsz_common.raw_flip = 1; else param->rsz_common.raw_flip = 0; - if (outformat1->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) + if (outformat1->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) resizer_enable_422_420_conversion(param, RSZ_A, ENABLE); else @@ -732,7 +732,7 @@ resizer_configure_in_single_shot_mode(struct vpfe_resizer_device *resizer) param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c; configure_resizer_out_params(resizer, RSZ_B, ¶m->user_config.output2, 0, 1); - if (outformat2->code == V4L2_MBUS_FMT_YDYUYDYV8_1X16) + if (outformat2->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) resizer_enable_422_420_conversion(param, RSZ_B, ENABLE); else @@ -745,7 +745,7 @@ resizer_configure_in_single_shot_mode(struct vpfe_resizer_device *resizer) resizer_calculate_resize_ratios(resizer, RSZ_A); resizer_calculate_sdram_offsets(resizer, RSZ_A); /* Overriding resize ratio calculation */ - if (informat->code == V4L2_MBUS_FMT_UV8_1X8) { + if (informat->code == MEDIA_BUS_FMT_UV8_1X8) { param->rsz_rsc_param[RSZ_A].v_dif = (((informat->height + 1) * 2) * 256) / (param->rsz_rsc_param[RSZ_A].o_vsz + 1); @@ -756,7 +756,7 @@ resizer_configure_in_single_shot_mode(struct vpfe_resizer_device *resizer) resizer_calculate_resize_ratios(resizer, RSZ_B); resizer_calculate_sdram_offsets(resizer, RSZ_B); /* Overriding resize ratio calculation */ - if (informat->code == V4L2_MBUS_FMT_UV8_1X8) { + if (informat->code == MEDIA_BUS_FMT_UV8_1X8) { param->rsz_rsc_param[RSZ_B].v_dif = (((informat->height + 1) * 2) * 256) / (param->rsz_rsc_param[RSZ_B].o_vsz + 1); @@ -1340,7 +1340,7 @@ resizer_try_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, } /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(resizer_input_formats)) - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH, MAX_IN_WIDTH); @@ -1357,7 +1357,7 @@ resizer_try_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, } /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(resizer_output_formats)) - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->width = clamp_t(u32, fmt->width, MIN_OUT_WIDTH, max_out_width); @@ -1375,7 +1375,7 @@ resizer_try_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, } /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(resizer_output_formats)) - fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; fmt->width = clamp_t(u32, fmt->width, MIN_OUT_WIDTH, max_out_width); @@ -1548,7 +1548,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_CROP_PAD_SINK; format.which = which; - format.format.code = V4L2_MBUS_FMT_YUYV8_2X8; + format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; format.format.width = MAX_IN_WIDTH; format.format.height = MAX_IN_HEIGHT; resizer_set_format(sd, fh, &format); @@ -1556,7 +1556,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_CROP_PAD_SOURCE; format.which = which; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = MAX_IN_WIDTH; format.format.height = MAX_IN_WIDTH; resizer_set_format(sd, fh, &format); @@ -1564,7 +1564,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_CROP_PAD_SOURCE2; format.which = which; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = MAX_IN_WIDTH; format.format.height = MAX_IN_WIDTH; resizer_set_format(sd, fh, &format); @@ -1572,7 +1572,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_PAD_SINK; format.which = which; - format.format.code = V4L2_MBUS_FMT_YUYV8_2X8; + format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; format.format.width = MAX_IN_WIDTH; format.format.height = MAX_IN_HEIGHT; resizer_set_format(sd, fh, &format); @@ -1580,7 +1580,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_PAD_SOURCE; format.which = which; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A; resizer_set_format(sd, fh, &format); @@ -1588,7 +1588,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_PAD_SINK; format.which = which; - format.format.code = V4L2_MBUS_FMT_YUYV8_2X8; + format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; format.format.width = MAX_IN_WIDTH; format.format.height = MAX_IN_HEIGHT; resizer_set_format(sd, fh, &format); @@ -1596,7 +1596,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_PAD_SOURCE; format.which = which; - format.format.code = V4L2_MBUS_FMT_UYVY8_2X8; + format.format.code = MEDIA_BUS_FMT_UYVY8_2X8; format.format.width = IPIPE_MAX_OUTPUT_WIDTH_B; format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_B; resizer_set_format(sd, fh, &format); diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index a862b28092e4..bf45d2cc5965 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -99,47 +99,47 @@ void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus, struct v4l2_pix_format *pix) { switch (mbus->code) { - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: pix->pixelformat = V4L2_PIX_FMT_UYVY; pix->bytesperline = pix->width * 2; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: pix->pixelformat = V4L2_PIX_FMT_YUYV; pix->bytesperline = pix->width * 2; break; - case V4L2_MBUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV10_1X20: pix->pixelformat = V4L2_PIX_FMT_UYVY; pix->bytesperline = pix->width * 2; break; - case V4L2_MBUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: pix->pixelformat = V4L2_PIX_FMT_SBGGR16; pix->bytesperline = pix->width * 2; break; - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8; pix->bytesperline = pix->width; break; - case V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8: + case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8: pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8; pix->bytesperline = pix->width; break; - case V4L2_MBUS_FMT_YDYUYDYV8_1X16: + case MEDIA_BUS_FMT_YDYUYDYV8_1X16: pix->pixelformat = V4L2_PIX_FMT_NV12; pix->bytesperline = pix->width; break; - case V4L2_MBUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_Y8_1X8: pix->pixelformat = V4L2_PIX_FMT_GREY; pix->bytesperline = pix->width; break; - case V4L2_MBUS_FMT_UV8_1X8: + case MEDIA_BUS_FMT_UV8_1X8: pix->pixelformat = V4L2_PIX_FMT_UV8; pix->bytesperline = pix->width; break; diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 92c2d5b743c7..7dbf68cd3566 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -93,20 +93,20 @@ static void csi2_recv_config(struct iss_csi2_device *csi2, } static const unsigned int csi2_input_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; /* To set the format on the CSI2 requires a mapping function that takes @@ -201,26 +201,26 @@ static u16 csi2_ctx_map_format(struct iss_csi2_device *csi2) int fmtidx, destidx; switch (fmt->code) { - case V4L2_MBUS_FMT_SGRBG10_1X10: - case V4L2_MBUS_FMT_SRGGB10_1X10: - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: fmtidx = 0; break; - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: - case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: fmtidx = 1; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGBRG8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: - case V4L2_MBUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: fmtidx = 2; break; - case V4L2_MBUS_FMT_UYVY8_1X16: - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: fmtidx = 3; break; default: @@ -817,7 +817,7 @@ csi2_try_format(struct iss_csi2_device *csi2, struct v4l2_subdev_fh *fh, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_mbus_framefmt *format; const struct iss_format_info *info; unsigned int i; @@ -832,7 +832,7 @@ csi2_try_format(struct iss_csi2_device *csi2, struct v4l2_subdev_fh *fh, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(csi2_input_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; fmt->width = clamp_t(u32, fmt->width, 1, 8191); fmt->height = clamp_t(u32, fmt->height, 1, 8191); @@ -1020,7 +1020,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = CSI2_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; csi2_set_format(sd, fh, &format); diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index 54042008154c..a1a46ef8319b 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -28,10 +28,10 @@ __ipipe_get_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh, unsigned int pad, enum v4l2_subdev_format_whence which); static const unsigned int ipipe_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, }; /* @@ -211,7 +211,7 @@ ipipe_try_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(ipipe_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; /* Clamp the input size. */ fmt->width = clamp_t(u32, width, 1, 8192); @@ -223,7 +223,7 @@ ipipe_try_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh, format = __ipipe_get_format(ipipe, fh, IPIPE_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); - fmt->code = V4L2_MBUS_FMT_UYVY8_1X16; + fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; fmt->width = clamp_t(u32, width, 32, fmt->width); fmt->height = clamp_t(u32, height, 32, fmt->height); fmt->colorspace = V4L2_COLORSPACE_JPEG; @@ -257,7 +257,7 @@ static int ipipe_enum_mbus_code(struct v4l2_subdev *sd, if (code->index != 0) return -EINVAL; - code->code = V4L2_MBUS_FMT_UYVY8_1X16; + code->code = MEDIA_BUS_FMT_UYVY8_1X16; break; default: @@ -385,7 +385,7 @@ static int ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) memset(&format, 0, sizeof(format)); format.pad = IPIPE_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ipipe_set_format(sd, fh, &format); diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 75f6a15ad202..32a748398ced 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -24,12 +24,12 @@ #include "iss_ipipeif.h" static const unsigned int ipipeif_fmts[] = { - V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; /* @@ -140,8 +140,8 @@ static void ipipeif_configure(struct iss_ipipeif_device *ipipeif) /* Select ISIF/IPIPEIF input format */ switch (format->code) { - case V4L2_MBUS_FMT_UYVY8_1X16: - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_MODESET, ISIF_MODESET_CCDMD | ISIF_MODESET_INPMOD_MASK | ISIF_MODESET_CCDW_MASK, @@ -151,25 +151,25 @@ static void ipipeif_configure(struct iss_ipipeif_device *ipipeif) IPIPEIF_CFG2_YUV8, IPIPEIF_CFG2_YUV16); break; - case V4L2_MBUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: isif_ccolp = ISIF_CCOLP_CP0_F0_GR | ISIF_CCOLP_CP1_F0_R | ISIF_CCOLP_CP2_F0_B | ISIF_CCOLP_CP3_F0_GB; goto cont_raw; - case V4L2_MBUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: isif_ccolp = ISIF_CCOLP_CP0_F0_R | ISIF_CCOLP_CP1_F0_GR | ISIF_CCOLP_CP2_F0_GB | ISIF_CCOLP_CP3_F0_B; goto cont_raw; - case V4L2_MBUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: isif_ccolp = ISIF_CCOLP_CP0_F0_B | ISIF_CCOLP_CP1_F0_GB | ISIF_CCOLP_CP2_F0_GR | ISIF_CCOLP_CP3_F0_R; goto cont_raw; - case V4L2_MBUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: isif_ccolp = ISIF_CCOLP_CP0_F0_GB | ISIF_CCOLP_CP1_F0_B | ISIF_CCOLP_CP2_F0_R | @@ -415,7 +415,7 @@ ipipeif_try_format(struct iss_ipipeif_device *ipipeif, /* If not found, use SGRBG10 as default */ if (i >= ARRAY_SIZE(ipipeif_fmts)) - fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; /* Clamp the input size. */ fmt->width = clamp_t(u32, width, 1, 8192); @@ -625,7 +625,7 @@ static int ipipeif_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = IPIPEIF_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; + format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; ipipeif_set_format(sd, fh, &format); diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index a21e356cce3a..88522a8cdf56 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -24,8 +24,8 @@ #include "iss_resizer.h" static const unsigned int resizer_fmts[] = { - V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, }; /* @@ -156,8 +156,8 @@ static void resizer_set_outaddr(struct iss_resizer_device *resizer, u32 addr) addr & 0xffff); /* Program UV buffer address... Hardcoded to be contiguous! */ - if ((informat->code == V4L2_MBUS_FMT_UYVY8_1X16) && - (outformat->code == V4L2_MBUS_FMT_YUYV8_1_5X8)) { + if ((informat->code == MEDIA_BUS_FMT_UYVY8_1X16) && + (outformat->code == MEDIA_BUS_FMT_YUYV8_1_5X8)) { u32 c_addr = addr + (resizer->video_out.bpl_value * (outformat->height - 1)); @@ -242,8 +242,8 @@ static void resizer_configure(struct iss_resizer_device *resizer) resizer->video_out.bpl_value); /* UYVY -> NV12 conversion */ - if ((informat->code == V4L2_MBUS_FMT_UYVY8_1X16) && - (outformat->code == V4L2_MBUS_FMT_YUYV8_1_5X8)) { + if ((informat->code == MEDIA_BUS_FMT_UYVY8_1X16) && + (outformat->code == MEDIA_BUS_FMT_YUYV8_1_5X8)) { iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_420, RSZ_420_CEN | RSZ_420_YEN); @@ -457,7 +457,7 @@ resizer_try_format(struct iss_resizer_device *resizer, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { - enum v4l2_mbus_pixelcode pixelcode; + u32 pixelcode; struct v4l2_mbus_framefmt *format; unsigned int width = fmt->width; unsigned int height = fmt->height; @@ -472,7 +472,7 @@ resizer_try_format(struct iss_resizer_device *resizer, /* If not found, use UYVY as default */ if (i >= ARRAY_SIZE(resizer_fmts)) - fmt->code = V4L2_MBUS_FMT_UYVY8_1X16; + fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; /* Clamp the input size. */ fmt->width = clamp_t(u32, width, 1, 8192); @@ -485,8 +485,8 @@ resizer_try_format(struct iss_resizer_device *resizer, which); memcpy(fmt, format, sizeof(*fmt)); - if ((pixelcode == V4L2_MBUS_FMT_YUYV8_1_5X8) && - (fmt->code == V4L2_MBUS_FMT_UYVY8_1X16)) + if ((pixelcode == MEDIA_BUS_FMT_YUYV8_1_5X8) && + (fmt->code == MEDIA_BUS_FMT_UYVY8_1X16)) fmt->code = pixelcode; /* The data formatter truncates the number of horizontal output @@ -537,9 +537,9 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, } switch (format->code) { - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: if (code->index == 1) - code->code = V4L2_MBUS_FMT_YUYV8_1_5X8; + code->code = MEDIA_BUS_FMT_YUYV8_1_5X8; else return -EINVAL; break; @@ -680,7 +680,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, memset(&format, 0, sizeof(format)); format.pad = RESIZER_PAD_SINK; format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - format.format.code = V4L2_MBUS_FMT_UYVY8_1X16; + format.format.code = MEDIA_BUS_FMT_UYVY8_1X16; format.format.width = 4096; format.format.height = 4096; resizer_set_format(sd, fh, &format); diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 5d6250337fec..cdee5966cbca 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -34,67 +34,67 @@ MODULE_PARM_DESC(debug, "activates debug info"); */ static struct iss_format_info formats[] = { - { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, - V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, + MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, "Greyscale 8 bpp", }, - { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y10, 10, "Greyscale 10 bpp", }, - { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, - V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, + { MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y10_1X10, + MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_Y12, 12, "Greyscale 12 bpp", }, - { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, - V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8, "BGGR Bayer 8 bpp", }, - { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, - V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8, "GBRG Bayer 8 bpp", }, - { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, - V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8, "GRBG Bayer 8 bpp", }, - { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, - V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8, "RGGB Bayer 8 bpp", }, - { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, - V4L2_MBUS_FMT_SGRBG10_1X10, 0, + { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + MEDIA_BUS_FMT_SGRBG10_1X10, 0, V4L2_PIX_FMT_SGRBG10DPCM8, 8, "GRBG Bayer 10 bpp DPCM8", }, - { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR10, 10, "BGGR Bayer 10 bpp", }, - { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG10, 10, "GBRG Bayer 10 bpp", }, - { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG10, 10, "GRBG Bayer 10 bpp", }, - { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB10, 10, "RGGB Bayer 10 bpp", }, - { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, - V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, + { MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR12, 12, "BGGR Bayer 12 bpp", }, - { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, - V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, + { MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG12, 12, "GBRG Bayer 12 bpp", }, - { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, - V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, + { MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG12, 12, "GRBG Bayer 12 bpp", }, - { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, - V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, + { MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB12, 12, "RGGB Bayer 12 bpp", }, - { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, - V4L2_MBUS_FMT_UYVY8_1X16, 0, + { MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_UYVY8_1X16, 0, V4L2_PIX_FMT_UYVY, 16, "YUV 4:2:2 (UYVY)", }, - { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, - V4L2_MBUS_FMT_YUYV8_1X16, 0, + { MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV8_1X16, 0, V4L2_PIX_FMT_YUYV, 16, "YUV 4:2:2 (YUYV)", }, - { V4L2_MBUS_FMT_YUYV8_1_5X8, V4L2_MBUS_FMT_YUYV8_1_5X8, - V4L2_MBUS_FMT_YUYV8_1_5X8, 0, + { MEDIA_BUS_FMT_YUYV8_1_5X8, MEDIA_BUS_FMT_YUYV8_1_5X8, + MEDIA_BUS_FMT_YUYV8_1_5X8, 0, V4L2_PIX_FMT_NV12, 8, "YUV 4:2:0 (NV12)", }, }; const struct iss_format_info * -omap4iss_video_format_info(enum v4l2_mbus_pixelcode code) +omap4iss_video_format_info(u32 code) { unsigned int i; diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h index 9dccdb154e1a..f11fce2cb977 100644 --- a/drivers/staging/media/omap4iss/iss_video.h +++ b/drivers/staging/media/omap4iss/iss_video.h @@ -43,10 +43,10 @@ struct v4l2_pix_format; * @description: Human-readable format description */ struct iss_format_info { - enum v4l2_mbus_pixelcode code; - enum v4l2_mbus_pixelcode truncated; - enum v4l2_mbus_pixelcode uncompressed; - enum v4l2_mbus_pixelcode flavor; + u32 code; + u32 truncated; + u32 uncompressed; + u32 flavor; u32 pixelformat; unsigned int bpp; const char *description; @@ -199,6 +199,6 @@ void omap4iss_video_cancel_stream(struct iss_video *video); struct media_pad *omap4iss_video_remote_pad(struct iss_video *video); const struct iss_format_info * -omap4iss_video_format_info(enum v4l2_mbus_pixelcode code); +omap4iss_video_format_info(u32 code); #endif /* OMAP4_ISS_VIDEO_H */ -- GitLab From 3e47608f2db93153bdaf3d78a604dcf8f8197059 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:34 -0300 Subject: [PATCH 4858/9457] [media] gpu: ipu-v3: Make use of media_bus_format enum In order to have subsytem agnostic media bus format definitions we've moved media bus definition to include/uapi/linux/media-bus-format.h and prefixed enum values with MEDIA_BUS_FMT instead of V4L2_MBUS_FMT. Reference new definitions in the ipu-v3 driver. Signed-off-by: Boris Brezillon Acked-by: Hans Verkuil Acked-by: Philipp Zabel Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/gpu/ipu-v3/ipu-csi.c | 66 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index d6f56471bd2a..752cdd2da89a 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c @@ -227,83 +227,83 @@ static int ipu_csi_set_testgen_mclk(struct ipu_csi *csi, u32 pixel_clk, static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) { switch (mbus_code) { - case V4L2_MBUS_FMT_BGR565_2X8_BE: - case V4L2_MBUS_FMT_BGR565_2X8_LE: - case V4L2_MBUS_FMT_RGB565_2X8_BE: - case V4L2_MBUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_BGR565_2X8_BE: + case MEDIA_BUS_FMT_BGR565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + case MEDIA_BUS_FMT_RGB565_2X8_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565; cfg->mipi_dt = MIPI_DT_RGB565; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB444; cfg->mipi_dt = MIPI_DT_RGB444; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE: - case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: + case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555; cfg->mipi_dt = MIPI_DT_RGB555; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_16; break; - case V4L2_MBUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; cfg->mipi_dt = MIPI_DT_YUV422; cfg->data_width = IPU_CSI_DATA_WIDTH_16; break; - case V4L2_MBUS_FMT_SBGGR8_1X8: - case V4L2_MBUS_FMT_SGBRG8_1X8: - case V4L2_MBUS_FMT_SGRBG8_1X8: - case V4L2_MBUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW8; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8: - case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: - case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: + case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: + case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE: + case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW10; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; - case V4L2_MBUS_FMT_SBGGR10_1X10: - case V4L2_MBUS_FMT_SGBRG10_1X10: - case V4L2_MBUS_FMT_SGRBG10_1X10: - case V4L2_MBUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW10; cfg->data_width = IPU_CSI_DATA_WIDTH_10; break; - case V4L2_MBUS_FMT_SBGGR12_1X12: - case V4L2_MBUS_FMT_SGBRG12_1X12: - case V4L2_MBUS_FMT_SGRBG12_1X12: - case V4L2_MBUS_FMT_SRGGB12_1X12: + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; cfg->mipi_dt = MIPI_DT_RAW12; cfg->data_width = IPU_CSI_DATA_WIDTH_12; break; - case V4L2_MBUS_FMT_JPEG_1X8: + case MEDIA_BUS_FMT_JPEG_1X8: /* TODO */ cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_JPEG; cfg->mipi_dt = MIPI_DT_RAW8; -- GitLab From aa1b4da6af67d5c6a4e933c2d30890c6f282f505 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Nov 2014 14:28:35 -0300 Subject: [PATCH 4859/9457] [media] v4l: Forbid usage of V4L2_MBUS_FMT definitions inside the kernel Place v4l2_mbus_pixelcode in a #ifndef __KERNEL__ section so that kernel users don't have access to these definitions. We have to keep this definition for user-space users even though they're encouraged to move to the new media_bus_format enum. Signed-off-by: Boris Brezillon Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-mediabus.h | 45 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index 26180844c6b8..b1934a3961e4 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h @@ -15,6 +15,33 @@ #include #include +/** + * struct v4l2_mbus_framefmt - frame format on the media bus + * @width: frame width + * @height: frame height + * @code: data format code (from enum v4l2_mbus_pixelcode) + * @field: used interlacing type (from enum v4l2_field) + * @colorspace: colorspace of the data (from enum v4l2_colorspace) + */ +struct v4l2_mbus_framefmt { + __u32 width; + __u32 height; + __u32 code; + __u32 field; + __u32 colorspace; + __u32 reserved[7]; +}; + +#ifndef __KERNEL__ +/* + * enum v4l2_mbus_pixelcode and its definitions are now deprecated, and + * MEDIA_BUS_FMT_ definitions (defined in media-bus-format.h) should be + * used instead. + * + * New defines should only be added to media-bus-format.h. The + * v4l2_mbus_pixelcode enum is frozen. + */ + #define V4L2_MBUS_FROM_MEDIA_BUS_FMT(name) \ V4L2_MBUS_FMT_ ## name = MEDIA_BUS_FMT_ ## name @@ -102,22 +129,6 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FROM_MEDIA_BUS_FMT(AHSV8888_1X32), }; - -/** - * struct v4l2_mbus_framefmt - frame format on the media bus - * @width: frame width - * @height: frame height - * @code: data format code (from enum v4l2_mbus_pixelcode) - * @field: used interlacing type (from enum v4l2_field) - * @colorspace: colorspace of the data (from enum v4l2_colorspace) - */ -struct v4l2_mbus_framefmt { - __u32 width; - __u32 height; - __u32 code; - __u32 field; - __u32 colorspace; - __u32 reserved[7]; -}; +#endif /* __KERNEL__ */ #endif -- GitLab From d4471deceba46ea6fd60f7fa5e8da3fb72bbbe44 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 21 Oct 2014 12:07:00 -0300 Subject: [PATCH 4860/9457] [media] si4713: switch to devm regulator API This switches back to the normal regulator API (but use managed variant) in preparation for device tree support. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil [hans.verkuil@cisco.com: fixed two trival compiler warnings] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 83 ++++++++++++++++++++--------- drivers/media/radio/si4713/si4713.h | 6 +-- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index b5765557ea3d..5c2a2fcb8965 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -366,13 +367,22 @@ static int si4713_powerup(struct si4713_device *sdev) if (sdev->power_state) return 0; - if (sdev->supplies) { - err = regulator_bulk_enable(sdev->supplies, sdev->supply_data); + if (sdev->vdd) { + err = regulator_enable(sdev->vdd); if (err) { - v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err); + v4l2_err(&sdev->sd, "Failed to enable vdd: %d\n", err); return err; } } + + if (sdev->vio) { + err = regulator_enable(sdev->vio); + if (err) { + v4l2_err(&sdev->sd, "Failed to enable vio: %d\n", err); + return err; + } + } + if (gpio_is_valid(sdev->gpio_reset)) { udelay(50); gpio_set_value(sdev->gpio_reset, 1); @@ -399,11 +409,18 @@ static int si4713_powerup(struct si4713_device *sdev) } if (gpio_is_valid(sdev->gpio_reset)) gpio_set_value(sdev->gpio_reset, 0); - if (sdev->supplies) { - err = regulator_bulk_disable(sdev->supplies, sdev->supply_data); + + + if (sdev->vdd) { + err = regulator_disable(sdev->vdd); if (err) - v4l2_err(&sdev->sd, - "Failed to disable supplies: %d\n", err); + v4l2_err(&sdev->sd, "Failed to disable vdd: %d\n", err); + } + + if (sdev->vio) { + err = regulator_disable(sdev->vio); + if (err) + v4l2_err(&sdev->sd, "Failed to disable vio: %d\n", err); } return err; @@ -432,12 +449,21 @@ static int si4713_powerdown(struct si4713_device *sdev) v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); if (gpio_is_valid(sdev->gpio_reset)) gpio_set_value(sdev->gpio_reset, 0); - if (sdev->supplies) { - err = regulator_bulk_disable(sdev->supplies, - sdev->supply_data); - if (err) + + if (sdev->vdd) { + err = regulator_disable(sdev->vdd); + if (err) { v4l2_err(&sdev->sd, - "Failed to disable supplies: %d\n", err); + "Failed to disable vdd: %d\n", err); + } + } + + if (sdev->vio) { + err = regulator_disable(sdev->vio); + if (err) { + v4l2_err(&sdev->sd, + "Failed to disable vio: %d\n", err); + } } sdev->power_state = POWER_OFF; } @@ -1422,7 +1448,7 @@ static int si4713_probe(struct i2c_client *client, struct si4713_device *sdev; struct si4713_platform_data *pdata = client->dev.platform_data; struct v4l2_ctrl_handler *hdl; - int rval, i; + int rval; sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); if (!sdev) { @@ -1441,17 +1467,26 @@ static int si4713_probe(struct i2c_client *client, } sdev->gpio_reset = pdata->gpio_reset; gpio_direction_output(sdev->gpio_reset, 0); - sdev->supplies = pdata->supplies; } - for (i = 0; i < sdev->supplies; i++) - sdev->supply_data[i].supply = pdata->supply_names[i]; + sdev->vdd = devm_regulator_get_optional(&client->dev, "vdd"); + if (IS_ERR(sdev->vdd)) { + rval = PTR_ERR(sdev->vdd); + if (rval == -EPROBE_DEFER) + goto exit; + + dev_dbg(&client->dev, "no vdd regulator found: %d\n", rval); + sdev->vdd = NULL; + } + + sdev->vio = devm_regulator_get_optional(&client->dev, "vio"); + if (IS_ERR(sdev->vio)) { + rval = PTR_ERR(sdev->vio); + if (rval == -EPROBE_DEFER) + goto exit; - rval = regulator_bulk_get(&client->dev, sdev->supplies, - sdev->supply_data); - if (rval) { - dev_err(&client->dev, "Cannot get regulators: %d\n", rval); - goto free_gpio; + dev_dbg(&client->dev, "no vio regulator found: %d\n", rval); + sdev->vio = NULL; } v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops); @@ -1559,7 +1594,7 @@ static int si4713_probe(struct i2c_client *client, client->name, sdev); if (rval < 0) { v4l2_err(&sdev->sd, "Could not request IRQ\n"); - goto put_reg; + goto free_ctrls; } v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n"); } else { @@ -1579,9 +1614,6 @@ static int si4713_probe(struct i2c_client *client, free_irq(client->irq, sdev); free_ctrls: v4l2_ctrl_handler_free(hdl); -put_reg: - regulator_bulk_free(sdev->supplies, sdev->supply_data); -free_gpio: if (gpio_is_valid(sdev->gpio_reset)) gpio_free(sdev->gpio_reset); free_sdev: @@ -1604,7 +1636,6 @@ static int si4713_remove(struct i2c_client *client) v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); - regulator_bulk_free(sdev->supplies, sdev->supply_data); if (gpio_is_valid(sdev->gpio_reset)) gpio_free(sdev->gpio_reset); kfree(sdev); diff --git a/drivers/media/radio/si4713/si4713.h b/drivers/media/radio/si4713/si4713.h index ed700e387605..ed28ed27c95f 100644 --- a/drivers/media/radio/si4713/si4713.h +++ b/drivers/media/radio/si4713/si4713.h @@ -190,8 +190,6 @@ #define MIN_ACOMP_THRESHOLD (-40) #define MAX_ACOMP_GAIN 20 -#define SI4713_NUM_SUPPLIES 2 - /* * si4713_device - private data */ @@ -236,8 +234,8 @@ struct si4713_device { struct v4l2_ctrl *tune_ant_cap; }; struct completion work; - unsigned supplies; - struct regulator_bulk_data supply_data[SI4713_NUM_SUPPLIES]; + struct regulator *vdd; + struct regulator *vio; int gpio_reset; u32 power_state; u32 rds_enabled; -- GitLab From fbe14a124c1616af65ddfc1add2fd323aaec67ae Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 21 Oct 2014 12:07:01 -0300 Subject: [PATCH 4861/9457] [media] si4713: switch reset gpio to devm_gpiod API This updates the driver to use the managed gpiod interface instead of the unmanged old GPIO API. This is a preperation for the introduction of device tree support. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil [hans.verkuil@cisco.com: fixed trivial compiler warning] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 38 +++++++++++++---------------- drivers/media/radio/si4713/si4713.h | 3 ++- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index 5c2a2fcb8965..952550e7be8f 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -383,9 +383,9 @@ static int si4713_powerup(struct si4713_device *sdev) } } - if (gpio_is_valid(sdev->gpio_reset)) { + if (!IS_ERR(sdev->gpio_reset)) { udelay(50); - gpio_set_value(sdev->gpio_reset, 1); + gpiod_set_value(sdev->gpio_reset, 1); } if (client->irq) @@ -407,8 +407,8 @@ static int si4713_powerup(struct si4713_device *sdev) SI4713_STC_INT | SI4713_CTS); return err; } - if (gpio_is_valid(sdev->gpio_reset)) - gpio_set_value(sdev->gpio_reset, 0); + if (!IS_ERR(sdev->gpio_reset)) + gpiod_set_value(sdev->gpio_reset, 0); if (sdev->vdd) { @@ -447,8 +447,8 @@ static int si4713_powerdown(struct si4713_device *sdev) v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", resp[0]); v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); - if (gpio_is_valid(sdev->gpio_reset)) - gpio_set_value(sdev->gpio_reset, 0); + if (!IS_ERR(sdev->gpio_reset)) + gpiod_set_value(sdev->gpio_reset, 0); if (sdev->vdd) { err = regulator_disable(sdev->vdd); @@ -1446,7 +1446,6 @@ static int si4713_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct si4713_device *sdev; - struct si4713_platform_data *pdata = client->dev.platform_data; struct v4l2_ctrl_handler *hdl; int rval; @@ -1457,16 +1456,17 @@ static int si4713_probe(struct i2c_client *client, goto exit; } - sdev->gpio_reset = -1; - if (pdata && gpio_is_valid(pdata->gpio_reset)) { - rval = gpio_request(pdata->gpio_reset, "si4713 reset"); - if (rval) { - dev_err(&client->dev, - "Failed to request gpio: %d\n", rval); - goto free_sdev; - } - sdev->gpio_reset = pdata->gpio_reset; - gpio_direction_output(sdev->gpio_reset, 0); + sdev->gpio_reset = devm_gpiod_get(&client->dev, "reset"); + if (!IS_ERR(sdev->gpio_reset)) { + gpiod_direction_output(sdev->gpio_reset, 0); + } else if (PTR_ERR(sdev->gpio_reset) == -ENOENT) { + dev_dbg(&client->dev, "No reset GPIO assigned\n"); + } else if (PTR_ERR(sdev->gpio_reset) == -ENOSYS) { + dev_dbg(&client->dev, "No reset GPIO support\n"); + } else { + rval = PTR_ERR(sdev->gpio_reset); + dev_err(&client->dev, "Failed to request gpio: %d\n", rval); + goto free_sdev; } sdev->vdd = devm_regulator_get_optional(&client->dev, "vdd"); @@ -1614,8 +1614,6 @@ static int si4713_probe(struct i2c_client *client, free_irq(client->irq, sdev); free_ctrls: v4l2_ctrl_handler_free(hdl); - if (gpio_is_valid(sdev->gpio_reset)) - gpio_free(sdev->gpio_reset); free_sdev: kfree(sdev); exit: @@ -1636,8 +1634,6 @@ static int si4713_remove(struct i2c_client *client) v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); - if (gpio_is_valid(sdev->gpio_reset)) - gpio_free(sdev->gpio_reset); kfree(sdev); return 0; diff --git a/drivers/media/radio/si4713/si4713.h b/drivers/media/radio/si4713/si4713.h index ed28ed27c95f..7c2479f42329 100644 --- a/drivers/media/radio/si4713/si4713.h +++ b/drivers/media/radio/si4713/si4713.h @@ -16,6 +16,7 @@ #define SI4713_I2C_H #include +#include #include #include #include @@ -236,7 +237,7 @@ struct si4713_device { struct completion work; struct regulator *vdd; struct regulator *vio; - int gpio_reset; + struct gpio_desc *gpio_reset; u32 power_state; u32 rds_enabled; u32 frequency; -- GitLab From 80cd5c7a4ed0561d52dbe71556f8b8ea5165d67b Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 21 Oct 2014 12:07:02 -0300 Subject: [PATCH 4862/9457] [media] si4713: use managed memory allocation Introduce the usage of managed memory allocation to simplify the code slightly. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index 952550e7be8f..afea1c311240 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -1449,7 +1449,7 @@ static int si4713_probe(struct i2c_client *client, struct v4l2_ctrl_handler *hdl; int rval; - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + sdev = devm_kzalloc(&client->dev, sizeof(*sdev), GFP_KERNEL); if (!sdev) { dev_err(&client->dev, "Failed to alloc video device.\n"); rval = -ENOMEM; @@ -1466,7 +1466,7 @@ static int si4713_probe(struct i2c_client *client, } else { rval = PTR_ERR(sdev->gpio_reset); dev_err(&client->dev, "Failed to request gpio: %d\n", rval); - goto free_sdev; + goto exit; } sdev->vdd = devm_regulator_get_optional(&client->dev, "vdd"); @@ -1614,8 +1614,6 @@ static int si4713_probe(struct i2c_client *client, free_irq(client->irq, sdev); free_ctrls: v4l2_ctrl_handler_free(hdl); -free_sdev: - kfree(sdev); exit: return rval; } @@ -1634,7 +1632,6 @@ static int si4713_remove(struct i2c_client *client) v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); - kfree(sdev); return 0; } -- GitLab From c3a5baf452df03e3d571298c86d2ed8638c9d18d Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 21 Oct 2014 12:07:03 -0300 Subject: [PATCH 4863/9457] [media] si4713: use managed irq request Introduce the usage of managed irq request to simplify the code slightly. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/si4713.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index afea1c311240..449f6cda2938 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -1589,7 +1589,7 @@ static int si4713_probe(struct i2c_client *client, sdev->sd.ctrl_handler = hdl; if (client->irq) { - rval = request_irq(client->irq, + rval = devm_request_irq(&client->dev, client->irq, si4713_handler, IRQF_TRIGGER_FALLING, client->name, sdev); if (rval < 0) { @@ -1604,14 +1604,11 @@ static int si4713_probe(struct i2c_client *client, rval = si4713_initialize(sdev); if (rval < 0) { v4l2_err(&sdev->sd, "Failed to probe device information.\n"); - goto free_irq; + goto free_ctrls; } return 0; -free_irq: - if (client->irq) - free_irq(client->irq, sdev); free_ctrls: v4l2_ctrl_handler_free(hdl); exit: @@ -1627,9 +1624,6 @@ static int si4713_remove(struct i2c_client *client) if (sdev->power_state) si4713_set_power_state(sdev, POWER_DOWN); - if (client->irq > 0) - free_irq(client->irq, sdev); - v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); -- GitLab From 98bea620c7ff301f9a7a6c31b2aca30964aa2fab Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 10 Nov 2014 17:34:41 -0300 Subject: [PATCH 4864/9457] [media] si4713: add device tree support Add device tree support by changing the device registration order. In the device tree the si4713 node is a normal I2C device, which will be probed as such. Thus the V4L device must be probed from the I2C device and not the other way around. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../radio/si4713/radio-platform-si4713.c | 28 ++++------------- drivers/media/radio/si4713/si4713.c | 28 +++++++++++++++++ drivers/media/radio/si4713/si4713.h | 6 ++++ include/media/radio-si4713.h | 30 ------------------- include/media/si4713.h | 1 + 5 files changed, 41 insertions(+), 52 deletions(-) delete mode 100644 include/media/radio-si4713.h diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c index a47502a330f0..2de5439b9c79 100644 --- a/drivers/media/radio/si4713/radio-platform-si4713.c +++ b/drivers/media/radio/si4713/radio-platform-si4713.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include "si4713.h" /* module parameters */ static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */ @@ -153,7 +153,6 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) { struct radio_si4713_platform_data *pdata = pdev->dev.platform_data; struct radio_si4713_device *rsdev; - struct i2c_adapter *adapter; struct v4l2_subdev *sd; int rval = 0; @@ -177,20 +176,11 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) goto exit; } - adapter = i2c_get_adapter(pdata->i2c_bus); - if (!adapter) { - dev_err(&pdev->dev, "Cannot get i2c adapter %d\n", - pdata->i2c_bus); - rval = -ENODEV; - goto unregister_v4l2_dev; - } - - sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, - pdata->subdev_board_info, NULL); - if (!sd) { + sd = i2c_get_clientdata(pdata->subdev); + rval = v4l2_device_register_subdev(&rsdev->v4l2_dev, sd); + if (rval) { dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n"); - rval = -ENODEV; - goto put_adapter; + goto unregister_v4l2_dev; } rsdev->radio_dev = radio_si4713_vdev_template; @@ -202,14 +192,12 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) if (video_register_device(&rsdev->radio_dev, VFL_TYPE_RADIO, radio_nr)) { dev_err(&pdev->dev, "Could not register video device.\n"); rval = -EIO; - goto put_adapter; + goto unregister_v4l2_dev; } dev_info(&pdev->dev, "New device successfully probed\n"); goto exit; -put_adapter: - i2c_put_adapter(adapter); unregister_v4l2_dev: v4l2_device_unregister(&rsdev->v4l2_dev); exit: @@ -220,14 +208,10 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev) static int radio_si4713_pdriver_remove(struct platform_device *pdev) { struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); - struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next, - struct v4l2_subdev, list); - struct i2c_client *client = v4l2_get_subdevdata(sd); struct radio_si4713_device *rsdev; rsdev = container_of(v4l2_dev, struct radio_si4713_device, v4l2_dev); video_unregister_device(&rsdev->radio_dev); - i2c_put_adapter(client->adapter); v4l2_device_unregister(&rsdev->v4l2_dev); return 0; diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index 449f6cda2938..c90004dac170 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c @@ -1447,6 +1447,10 @@ static int si4713_probe(struct i2c_client *client, { struct si4713_device *sdev; struct v4l2_ctrl_handler *hdl; + struct si4713_platform_data *pdata = client->dev.platform_data; + struct device_node *np = client->dev.of_node; + struct radio_si4713_platform_data si4713_pdev_pdata; + struct platform_device *si4713_pdev; int rval; sdev = devm_kzalloc(&client->dev, sizeof(*sdev), GFP_KERNEL); @@ -1607,8 +1611,30 @@ static int si4713_probe(struct i2c_client *client, goto free_ctrls; } + if (!np && (!pdata || !pdata->is_platform_device)) + return 0; + + si4713_pdev = platform_device_alloc("radio-si4713", -1); + if (!si4713_pdev) + goto put_main_pdev; + + si4713_pdev_pdata.subdev = client; + rval = platform_device_add_data(si4713_pdev, &si4713_pdev_pdata, + sizeof(si4713_pdev_pdata)); + if (rval) + goto put_main_pdev; + + rval = platform_device_add(si4713_pdev); + if (rval) + goto put_main_pdev; + + sdev->pd = si4713_pdev; + return 0; +put_main_pdev: + platform_device_put(si4713_pdev); + v4l2_device_unregister_subdev(&sdev->sd); free_ctrls: v4l2_ctrl_handler_free(hdl); exit: @@ -1621,6 +1647,8 @@ static int si4713_remove(struct i2c_client *client) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct si4713_device *sdev = to_si4713_device(sd); + platform_device_unregister(sdev->pd); + if (sdev->power_state) si4713_set_power_state(sdev, POWER_DOWN); diff --git a/drivers/media/radio/si4713/si4713.h b/drivers/media/radio/si4713/si4713.h index 7c2479f42329..8a376e142188 100644 --- a/drivers/media/radio/si4713/si4713.h +++ b/drivers/media/radio/si4713/si4713.h @@ -15,6 +15,7 @@ #ifndef SI4713_I2C_H #define SI4713_I2C_H +#include #include #include #include @@ -238,6 +239,7 @@ struct si4713_device { struct regulator *vdd; struct regulator *vio; struct gpio_desc *gpio_reset; + struct platform_device *pd; u32 power_state; u32 rds_enabled; u32 frequency; @@ -245,4 +247,8 @@ struct si4713_device { u32 stereo; u32 tune_rnl; }; + +struct radio_si4713_platform_data { + struct i2c_client *subdev; +}; #endif /* ifndef SI4713_I2C_H */ diff --git a/include/media/radio-si4713.h b/include/media/radio-si4713.h deleted file mode 100644 index f6aae29c7741..000000000000 --- a/include/media/radio-si4713.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * include/media/radio-si4713.h - * - * Board related data definitions for Si4713 radio transmitter chip. - * - * Copyright (c) 2009 Nokia Corporation - * Contact: Eduardo Valentin - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#ifndef RADIO_SI4713_H -#define RADIO_SI4713_H - -#include - -#define SI4713_NAME "radio-si4713" - -/* - * Platform dependent definition - */ -struct radio_si4713_platform_data { - int i2c_bus; - struct i2c_board_info *subdev_board_info; -}; - -#endif /* ifndef RADIO_SI4713_H*/ diff --git a/include/media/si4713.h b/include/media/si4713.h index f98a0a7af61c..343b8fb50b93 100644 --- a/include/media/si4713.h +++ b/include/media/si4713.h @@ -26,6 +26,7 @@ struct si4713_platform_data { const char * const *supply_names; unsigned supplies; int gpio_reset; /* < 0 if not used */ + bool is_platform_device; }; /* -- GitLab From 5325d844fdae416993c41271a6460fd1c81c6172 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 10 Nov 2014 17:34:42 -0300 Subject: [PATCH 4865/9457] [media] si4713: add DT binding documentation This patch adds the DT bindings documentation for Silicon Labs Si4713 FM radio transmitter. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/si4713.txt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/si4713.txt diff --git a/Documentation/devicetree/bindings/media/si4713.txt b/Documentation/devicetree/bindings/media/si4713.txt new file mode 100644 index 000000000000..5ee5552d3465 --- /dev/null +++ b/Documentation/devicetree/bindings/media/si4713.txt @@ -0,0 +1,30 @@ +* Silicon Labs FM Radio transmitter + +The Silicon Labs Si4713 is an FM radio transmitter with receive power scan +supporting 76-108 MHz. It includes an RDS encoder and has both, a stereo-analog +and a digital interface, which supports I2S, left-justified and a custom +DSP-mode format. It is programmable through an I2C interface. + +Required Properties: +- compatible: Should contain "silabs,si4713" +- reg: the I2C address of the device + +Optional Properties: +- interrupts-extended: Interrupt specifier for the chips interrupt +- reset-gpios: GPIO specifier for the chips reset line +- vdd-supply: phandle for Vdd regulator +- vio-supply: phandle for Vio regulator + +Example: + +&i2c2 { + fmtx: si4713@63 { + compatible = "silabs,si4713"; + reg = <0x63>; + + interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */ + reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */ + vio-supply = <&vio>; + vdd-supply = <&vaux1>; + }; +}; -- GitLab From 68a3c0433077b189e5adf3b267cd8db9b8b78d24 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 10 Nov 2014 17:34:43 -0300 Subject: [PATCH 4866/9457] [media] ARM: OMAP2: RX-51: update si4713 platform data This updates platform data related to Si4713, which has been updated to be compatible with DT interface. Signed-off-by: Sebastian Reichel Acked-by: Tony Lindgren Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/arm/mach-omap2/board-rx51-peripherals.c | 69 +++++++++----------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index ddfc8df83c6a..ec2e4101988b 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,6 @@ #include #include -#include #include #include @@ -760,46 +760,17 @@ static struct regulator_init_data rx51_vintdig = { }, }; -static const char * const si4713_supply_names[] = { - "vio", - "vdd", -}; - -static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = { - .supplies = ARRAY_SIZE(si4713_supply_names), - .supply_names = si4713_supply_names, - .gpio_reset = RX51_FMTX_RESET_GPIO, -}; - -static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = { - I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH), - .platform_data = &rx51_si4713_i2c_data, -}; - -static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = { - .i2c_bus = 2, - .subdev_board_info = &rx51_si4713_board_info, -}; - -static struct platform_device rx51_si4713_dev __initdata_or_module = { - .name = "radio-si4713", - .id = -1, - .dev = { - .platform_data = &rx51_si4713_data, +static struct gpiod_lookup_table rx51_fmtx_gpios_table = { + .dev_id = "2-0063", + .table = { + GPIO_LOOKUP("gpio.6", 3, "reset", GPIO_ACTIVE_HIGH), /* 163 */ + { }, }, }; -static __init void rx51_init_si4713(void) +static __init void rx51_gpio_init(void) { - int err; - - err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq"); - if (err) { - printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err); - return; - } - rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ); - platform_device_register(&rx51_si4713_dev); + gpiod_add_lookup_table(&rx51_fmtx_gpios_table); } static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) @@ -1029,7 +1000,17 @@ static struct aic3x_pdata rx51_aic3x_data2 = { .gpio_reset = 60, }; +static struct si4713_platform_data rx51_si4713_platform_data = { + .is_platform_device = true +}; + static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { +#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713) + { + I2C_BOARD_INFO("si4713", 0x63), + .platform_data = &rx51_si4713_platform_data, + }, +#endif { I2C_BOARD_INFO("tlv320aic3x", 0x18), .platform_data = &rx51_aic3x_data, @@ -1070,6 +1051,10 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = { static int __init rx51_i2c_init(void) { +#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713) + int err; +#endif + if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || system_rev >= SYSTEM_REV_B_USES_VAUX3) { rx51_twldata.vaux3 = &rx51_vaux3_mmc; @@ -1087,6 +1072,14 @@ static int __init rx51_i2c_init(void) rx51_twldata.vdac->constraints.name = "VDAC"; omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata); +#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713) + err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq"); + if (err) { + printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err); + return err; + } + rx51_peripherals_i2c_board_info_2[0].irq = gpio_to_irq(RX51_FMTX_IRQ); +#endif omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE) @@ -1300,6 +1293,7 @@ static void __init rx51_init_omap3_rom_rng(void) void __init rx51_peripherals_init(void) { + rx51_gpio_init(); rx51_i2c_init(); regulator_has_full_constraints(); gpmc_onenand_init(board_onenand_data); @@ -1307,7 +1301,6 @@ void __init rx51_peripherals_init(void) rx51_add_gpio_keys(); rx51_init_wl1251(); rx51_init_tsc2005(); - rx51_init_si4713(); rx51_init_lirc(); spi_register_board_info(rx51_peripherals_spi_board_info, ARRAY_SIZE(rx51_peripherals_spi_board_info)); -- GitLab From bf2b892e661213d4e94e2bff76dd13a23909228b Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 10 Nov 2014 17:34:44 -0300 Subject: [PATCH 4867/9457] [media] si4713: cleanup platform data Remove unreferenced members from the platform data's structure. Signed-off-by: Sebastian Reichel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/si4713.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/media/si4713.h b/include/media/si4713.h index 343b8fb50b93..be4f58e2440b 100644 --- a/include/media/si4713.h +++ b/include/media/si4713.h @@ -23,9 +23,6 @@ * Platform dependent definition */ struct si4713_platform_data { - const char * const *supply_names; - unsigned supplies; - int gpio_reset; /* < 0 if not used */ bool is_platform_device; }; -- GitLab From eab34eabe420cb9693b5195341d3e6fb090f8df6 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Mon, 10 Nov 2014 13:55:53 -0300 Subject: [PATCH 4868/9457] [media] media: vivid: use vb2_start_streaming_called() helper this patch adds support for using vb2_start_streaming_called() for vivid driver. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-ctrls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index d5847736792b..ad8df5ce823c 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -831,15 +831,15 @@ static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl) dev->start_streaming_error = true; break; case VIVID_CID_QUEUE_ERROR: - if (dev->vb_vid_cap_q.start_streaming_called) + if (vb2_start_streaming_called(&dev->vb_vid_cap_q)) vb2_queue_error(&dev->vb_vid_cap_q); - if (dev->vb_vbi_cap_q.start_streaming_called) + if (vb2_start_streaming_called(&dev->vb_vbi_cap_q)) vb2_queue_error(&dev->vb_vbi_cap_q); - if (dev->vb_vid_out_q.start_streaming_called) + if (vb2_start_streaming_called(&dev->vb_vid_out_q)) vb2_queue_error(&dev->vb_vid_out_q); - if (dev->vb_vbi_out_q.start_streaming_called) + if (vb2_start_streaming_called(&dev->vb_vbi_out_q)) vb2_queue_error(&dev->vb_vbi_out_q); - if (dev->vb_sdr_cap_q.start_streaming_called) + if (vb2_start_streaming_called(&dev->vb_sdr_cap_q)) vb2_queue_error(&dev->vb_sdr_cap_q); break; case VIVID_CID_SEQ_WRAP: -- GitLab From 7f56a4a710a19b6bce7a302485d000d3ab818592 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Mon, 10 Nov 2014 13:55:54 -0300 Subject: [PATCH 4869/9457] [media] media: cx88: use vb2_start_streaming_called() helper this patch adds support for using vb2_start_streaming_called() for cx88-blackbird driver. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index ff7978212e9d..4160ca4e5413 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -881,7 +881,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, return -EINVAL; if (unlikely(f->tuner != 0)) return -EINVAL; - streaming = dev->vb2_mpegq.start_streaming_called; + streaming = vb2_start_streaming_called(&dev->vb2_mpegq); if (streaming) blackbird_stop_codec(dev); -- GitLab From 9aa785b1500a7bd40b736f31b341e204bd5fb174 Mon Sep 17 00:00:00 2001 From: Wilson Michaels Date: Tue, 11 Nov 2014 19:43:51 -0300 Subject: [PATCH 4870/9457] [media] add "lgdt330x" device name i2c_devs array This patch adds "lgdt330x" device name i2c_devs array used for debugging Signed-off-by: Wilson Michaels Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 1048c1a23fb6..d22986dcd865 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -877,6 +877,7 @@ static struct i2c_client em28xx_client_template = { * incomplete list of known devices */ static char *i2c_devs[128] = { + [0x1c >> 1] = "lgdt330x", [0x3e >> 1] = "remote IR sensor", [0x4a >> 1] = "saa7113h", [0x52 >> 1] = "drxk", -- GitLab From c02ef64aab828d80040b5dce934729312e698c33 Mon Sep 17 00:00:00 2001 From: Nibble Max Date: Wed, 12 Nov 2014 01:23:12 -0300 Subject: [PATCH 4871/9457] [media] cx23885: add DVBSky T982(Dual DVB-T2/T/C) support DVBSky T982 DVB-T2/T/C dual PCIe card: 1>dvb frontend: SI2158A20(tuner),SI2168A30(demod) 2>PCIe bridge: CX23885(port b: parallel mode, port c: serial mode) 3>rc: cx23885 integrated. Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 15 ++++++ drivers/media/pci/cx23885/cx23885-dvb.c | 60 ++++++++++++++++++++++- drivers/media/pci/cx23885/cx23885-input.c | 3 ++ drivers/media/pci/cx23885/cx23885.h | 1 + 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 4bad27d1caa2..db99ca2613ba 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -701,6 +701,11 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVBSKY_T982] = { + .name = "DVBSky T982", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -980,6 +985,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x4254, .subdevice = 0x0952, .card = CX23885_BOARD_DVBSKY_S952, + }, { + .subvendor = 0x4254, + .subdevice = 0x0982, + .card = CX23885_BOARD_DVBSKY_T982, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -1576,6 +1585,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: /* enable GPIO3-18 pins */ cx_write(MC417_CTL, 0x00000037); cx23885_gpio_enable(dev, GPIO_2 | GPIO_11, 1); @@ -1708,6 +1718,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: if (!enable_885_ir) break; dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); @@ -1760,6 +1771,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: cx23885_irq_remove(dev, PCI_MSK_AV_CORE); /* sd_ir is a duplicate pointer to the AV Core, just clear it */ dev->sd_ir = NULL; @@ -1813,6 +1825,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: if (dev->sd_ir) cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); break; @@ -1968,6 +1981,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; case CX23885_BOARD_DVBSKY_T9580: + case CX23885_BOARD_DVBSKY_T982: ts1->gen_ctrl_val = 0x5; /* Parallel */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; @@ -2051,6 +2065,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 2457b6483a40..1ed92eeb46d1 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1943,6 +1943,63 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend->ops.set_voltage; fe0->dvb.frontend->ops.set_voltage = p_set_voltage; + port->i2c_client_tuner = client_tuner; + break; + case CX23885_BOARD_DVBSKY_T982: + memset(&si2168_config, 0, sizeof(si2168_config)); + switch (port->nr) { + /* port b */ + case 1: + i2c_bus = &dev->i2c_bus[1]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + break; + /* port c */ + case 2: + i2c_bus = &dev->i2c_bus[0]; + si2168_config.ts_mode = SI2168_TS_SERIAL; + break; + } + + /* attach frontend */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &fe0->dvb.frontend; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); + if (client_demod == NULL || + client_demod->dev.driver == NULL) + goto frontend_detach; + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + goto frontend_detach; + } + port->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = fe0->dvb.frontend; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + goto frontend_detach; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + port->i2c_client_demod = NULL; + goto frontend_detach; + } port->i2c_client_tuner = client_tuner; break; default: @@ -2021,7 +2078,8 @@ static int dvb_register(struct cx23885_tsport *port) } case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S950: - case CX23885_BOARD_DVBSKY_S952: { + case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: { u8 eeprom[256]; /* 24C02 i2c eeprom */ if (port->nr > 2) diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index a1f489444355..088799c3b49b 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -93,6 +93,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: /* * The only boards we handle right now. However other boards * using the CX2388x integrated IR controller should be similar @@ -151,6 +152,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) case CX23885_BOARD_TT_CT2_4500_CI: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: /* * The IR controller on this board only returns pulse widths. * Any other mode setting will fail to set up the device. @@ -322,6 +324,7 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S950C: case CX23885_BOARD_DVBSKY_S950: case CX23885_BOARD_DVBSKY_S952: + case CX23885_BOARD_DVBSKY_T982: /* Integrated CX23885 IR controller */ driver_type = RC_DRIVER_IR_RAW; allowed_protos = RC_BIT_ALL; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 58c5038c816b..cf4efa461ce2 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -98,6 +98,7 @@ #define CX23885_BOARD_TT_CT2_4500_CI 48 #define CX23885_BOARD_DVBSKY_S950 49 #define CX23885_BOARD_DVBSKY_S952 50 +#define CX23885_BOARD_DVBSKY_T982 51 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- GitLab From 941fcce4ff6701c5a7d673d0abb063a7de1234bf Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:33 -0600 Subject: [PATCH 4872/9457] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Signed-off-by: Dinh Nguyen Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 155 ++++++++++++++++++++------------------ drivers/usb/dwc2/gadget.c | 146 +++++++++++++++++------------------ 2 files changed, 153 insertions(+), 148 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 55c90c53f2d6..7bcdc10e4b01 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -84,7 +84,7 @@ static const char * const s3c_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 -struct s3c_hsotg; +struct dwc2_hsotg; struct s3c_hsotg_req; /** @@ -130,7 +130,7 @@ struct s3c_hsotg_req; struct s3c_hsotg_ep { struct usb_ep ep; struct list_head queue; - struct s3c_hsotg *parent; + struct dwc2_hsotg *parent; struct s3c_hsotg_req *req; struct dentry *debugfs; @@ -154,67 +154,6 @@ struct s3c_hsotg_ep { char name[10]; }; -/** - * struct s3c_hsotg - driver state. - * @dev: The parent device supplied to the probe function - * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @regs: The memory area mapped for accessing registers. - * @irq: The IRQ number we are using - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width - * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. - * @num_of_eps: Number of available EPs (excluding EP0) - * @debug_root: root directrory for debugfs. - * @debug_file: main status file for debugfs. - * @debug_fifo: FIFO status file for debugfs. - * @ep0_reply: Request used for ep0 reply. - * @ep0_buff: Buffer for EP0 reply data, if needed. - * @ctrl_buff: Buffer for EP0 control requests. - * @ctrl_req: Request for EP0 control packets. - * @setup: NAK management for EP0 SETUP - * @last_rst: Time of last reset - * @eps: The endpoints being supplied to the gadget framework - */ -struct s3c_hsotg { - struct device *dev; - struct usb_gadget_driver *driver; - struct phy *phy; - struct usb_phy *uphy; - struct s3c_hsotg_plat *plat; - - spinlock_t lock; - - void __iomem *regs; - int irq; - struct clk *clk; - - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; - - u32 phyif; - int fifo_mem; - unsigned int dedicated_fifos:1; - unsigned char num_of_eps; - u32 fifo_map; - - struct dentry *debug_root; - struct dentry *debug_file; - struct dentry *debug_fifo; - - struct usb_request *ep0_reply; - struct usb_request *ctrl_req; - u8 ep0_buff[8]; - u8 ctrl_buff[8]; - - struct usb_gadget gadget; - unsigned int setup; - unsigned long last_rst; - struct s3c_hsotg_ep *eps; -}; - /** * struct s3c_hsotg_req - data transfer request * @req: The USB gadget request @@ -229,6 +168,7 @@ struct s3c_hsotg_req { unsigned char mapped; }; +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) #define call_gadget(_hs, _entry) \ do { \ if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ @@ -238,6 +178,9 @@ do { \ spin_lock(&_hs->lock); \ } \ } while (0) +#else +#define call_gadget(_hs, _entry) do {} while (0) +#endif struct dwc2_hsotg; struct dwc2_host_chan; @@ -495,11 +438,13 @@ struct dwc2_hw_params { * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic * and periodic schedules * + * These are common for both host and peripheral modes: + * * @dev: The struct device pointer * @regs: Pointer to controller regs - * @core_params: Parameters that define how the core should be configured * @hw_params: Parameters that were autodetected from the * hardware registers + * @core_params: Parameters that define how the core should be configured * @op_state: The operational State, during transitions (a_host=> * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine @@ -508,6 +453,8 @@ struct dwc2_hw_params { * - USB_DR_MODE_PERIPHERAL * - USB_DR_MODE_HOST * - USB_DR_MODE_OTG + * @lock: Spinlock that protects all the driver data structures + * @priv: Stores a pointer to the struct usb_hcd * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success: Stores status of SRP request in the case of a FS PHY @@ -517,6 +464,9 @@ struct dwc2_hw_params { * interrupt * @wkp_timer: Timer object for handling Wakeup Detected interrupt * @lx_state: Lx state of connected device + * + * These are for host mode: + * * @flags: Flags for handling root port state changes * @non_periodic_sched_inactive: Inactive QHs in the non-periodic schedule. * Transfers associated with these QHs are not currently @@ -585,11 +535,31 @@ struct dwc2_hw_params { * @status_buf_dma: DMA address for status_buf * @start_work: Delayed work for handling host A-cable connection * @reset_work: Delayed work for handling a port reset - * @lock: Spinlock that protects all the driver data structures - * @priv: Stores a pointer to the struct usb_hcd * @otg_port: OTG port number * @frame_list: Frame list * @frame_list_dma: Frame list DMA address + * + * These are for peripheral mode: + * + * @driver: USB gadget driver + * @phy: The otg phy transceiver structure for phy control. + * @uphy: The otg phy transceiver structure for old USB phy control. + * @plat: The platform specific configuration data. This can be removed once + * all SoCs support usb transceiver. + * @supplies: Definition of USB power supplies + * @phyif: PHY interface width + * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. + * @num_of_eps: Number of available EPs (excluding EP0) + * @debug_root: Root directrory for debugfs. + * @debug_file: Main status file for debugfs. + * @debug_fifo: FIFO status file for debugfs. + * @ep0_reply: Request used for ep0 reply. + * @ep0_buff: Buffer for EP0 reply data, if needed. + * @ctrl_buff: Buffer for EP0 control requests. + * @ctrl_req: Request for EP0 control packets. + * @setup: NAK management for EP0 SETUP + * @last_rst: Time of last reset + * @eps: The endpoints being supplied to the gadget framework */ struct dwc2_hsotg { struct device *dev; @@ -601,6 +571,15 @@ struct dwc2_hsotg { enum usb_otg_state op_state; enum usb_dr_mode dr_mode; + struct phy *phy; + struct usb_phy *uphy; + struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; + + spinlock_t lock; + void *priv; + int irq; + struct clk *clk; + unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; @@ -609,6 +588,18 @@ struct dwc2_hsotg { struct timer_list wkp_timer; enum dwc2_lx_state lx_state; + struct dentry *debug_root; + struct dentry *debug_file; + struct dentry *debug_fifo; + + /* DWC OTG HW Release versions */ +#define DWC2_CORE_REV_2_71a 0x4f54271a +#define DWC2_CORE_REV_2_90a 0x4f54290a +#define DWC2_CORE_REV_2_92a 0x4f54292a +#define DWC2_CORE_REV_2_94a 0x4f54294a +#define DWC2_CORE_REV_3_00a 0x4f54300a + +#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) union dwc2_hcd_internal_flags { u32 d32; struct { @@ -655,19 +646,10 @@ struct dwc2_hsotg { struct delayed_work start_work; struct delayed_work reset_work; - spinlock_t lock; - void *priv; u8 otg_port; u32 *frame_list; dma_addr_t frame_list_dma; - /* DWC OTG HW Release versions */ -#define DWC2_CORE_REV_2_71a 0x4f54271a -#define DWC2_CORE_REV_2_90a 0x4f54290a -#define DWC2_CORE_REV_2_92a 0x4f54292a -#define DWC2_CORE_REV_2_94a 0x4f54294a -#define DWC2_CORE_REV_3_00a 0x4f54300a - #ifdef DEBUG u32 frrem_samples; u64 frrem_accum; @@ -686,6 +668,29 @@ struct dwc2_hsotg { u32 hfnum_other_samples_b; u64 hfnum_other_frrem_accum_b; #endif +#endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */ + +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) + /* Gadget structures */ + struct usb_gadget_driver *driver; + struct s3c_hsotg_plat *plat; + + u32 phyif; + int fifo_mem; + unsigned int dedicated_fifos:1; + unsigned char num_of_eps; + u32 fifo_map; + + struct usb_request *ep0_reply; + struct usb_request *ctrl_req; + u8 ep0_buff[8]; + u8 ctrl_buff[8]; + + struct usb_gadget gadget; + unsigned int setup; + unsigned long last_rst; + struct s3c_hsotg_ep *eps; +#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ }; /* Reasons for halting a host channel */ diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index fcd2bb55ccca..5a24e95ae1b0 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -36,6 +36,7 @@ #include #include "core.h" +#include "hw.h" /* conversion functions */ static inline struct s3c_hsotg_req *our_req(struct usb_request *req) @@ -48,9 +49,9 @@ static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep) return container_of(ep, struct s3c_hsotg_ep, ep); } -static inline struct s3c_hsotg *to_hsotg(struct usb_gadget *gadget) +static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget) { - return container_of(gadget, struct s3c_hsotg, gadget); + return container_of(gadget, struct dwc2_hsotg, gadget); } static inline void __orr32(void __iomem *ptr, u32 val) @@ -64,7 +65,7 @@ static inline void __bic32(void __iomem *ptr, u32 val) } /* forward decleration of functions */ -static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); +static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); /** * using_dma - return the DMA status of the driver. @@ -85,7 +86,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); * * Until this issue is sorted out, we always return 'false'. */ -static inline bool using_dma(struct s3c_hsotg *hsotg) +static inline bool using_dma(struct dwc2_hsotg *hsotg) { return false; /* support is not complete */ } @@ -95,7 +96,7 @@ static inline bool using_dma(struct s3c_hsotg *hsotg) * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) +static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; @@ -113,7 +114,7 @@ static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) +static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; @@ -134,7 +135,7 @@ static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) * Set or clear the mask for an individual endpoint's interrupt * request. */ -static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, +static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, unsigned int ep, unsigned int dir_in, unsigned int en) { @@ -159,7 +160,7 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, * s3c_hsotg_init_fifo - initialise non-periodic FIFOs * @hsotg: The device instance. */ -static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) +static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) { unsigned int ep; unsigned int addr; @@ -283,7 +284,7 @@ static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep) * This is the reverse of s3c_hsotg_map_dma(), called for the completion * of a request to ensure the buffer is ready for access by the caller. */ -static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, +static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) { @@ -312,7 +313,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, * * This routine is only needed for PIO */ -static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg, +static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) { @@ -517,7 +518,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) * Start the given request running by setting the endpoint registers * appropriately, and writing any data to the FIFOs. */ -static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, +static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req, bool continuing) @@ -707,7 +708,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, * DMA memory, then we map the memory and mark our request to allow us to * cleanup on completion. */ -static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg, +static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct usb_request *req) { @@ -736,7 +737,7 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, { struct s3c_hsotg_req *hs_req = our_req(req); struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hs = hs_ep->parent; + struct dwc2_hsotg *hs = hs_ep->parent; bool first; dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", @@ -768,7 +769,7 @@ static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hs = hs_ep->parent; + struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags = 0; int ret = 0; @@ -799,7 +800,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, struct usb_request *req) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hsotg = hs_ep->parent; + struct dwc2_hsotg *hsotg = hs_ep->parent; dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req); @@ -814,7 +815,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, * Convert the given wIndex into a pointer to an driver endpoint * structure, or return NULL if it is not a valid endpoint. */ -static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg, +static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, u32 windex) { struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F]; @@ -843,7 +844,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg, * Create a request and queue it on the given endpoint. This is useful as * an internal method of sending replies to certain control requests, etc. */ -static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg, +static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *ep, void *buff, int length) @@ -884,7 +885,7 @@ static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg, * @hsotg: The device state * @ctrl: USB control request */ -static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg, +static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; @@ -955,7 +956,7 @@ static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) * @hsotg: The device state * @ctrl: USB control request */ -static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, +static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; @@ -1028,8 +1029,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, return 1; } -static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); -static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); +static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); +static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg); /** * s3c_hsotg_stall_ep0 - stall ep0 @@ -1037,7 +1038,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); * * Set stall for ep0 as response for setup request. */ -static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) +static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) { struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; u32 reg; @@ -1076,7 +1077,7 @@ static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) * needs to work out what to do next (and whether to pass it on to the * gadget driver). */ -static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, +static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; @@ -1161,7 +1162,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep, struct usb_request *req) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hsotg = hs_ep->parent; + struct dwc2_hsotg *hsotg = hs_ep->parent; if (req->status < 0) { dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status); @@ -1183,7 +1184,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep, * Enqueue a request on EP0 if necessary to received any SETUP packets * received from the host. */ -static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) +static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) { struct usb_request *req = hsotg->ctrl_req; struct s3c_hsotg_req *hs_req = our_req(req); @@ -1226,7 +1227,7 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) * * Note, expects the ep to already be locked as appropriate. */ -static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, +static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req, int result) @@ -1291,7 +1292,7 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, * endpoint, so sort out whether we need to read the data into a request * that has been made for that endpoint. */ -static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) +static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) { struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx]; struct s3c_hsotg_req *hs_req = hs_ep->req; @@ -1356,7 +1357,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) * currently believed that we do not need to wait for any space in * the TxFIFO. */ -static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, +static void s3c_hsotg_send_zlp(struct dwc2_hsotg *hsotg, struct s3c_hsotg_req *req) { u32 ctrl; @@ -1398,7 +1399,7 @@ static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, * transfer for an OUT endpoint has been completed, either by a short * packet or by the finish of a transfer. */ -static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, +static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum, bool was_setup) { u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); @@ -1471,7 +1472,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, * * Return the current frame number */ -static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) +static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg) { u32 dsts; @@ -1498,7 +1499,7 @@ static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) * as the actual data should be sent to the memory directly and we turn * on the completion interrupts to get notifications of transfer completion. */ -static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg) +static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) { u32 grxstsr = readl(hsotg->regs + GRXSTSP); u32 epnum, status, size; @@ -1590,7 +1591,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps) * Configure the maximum packet size for the given endpoint, updating * the hardware control registers to reflect this. */ -static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, +static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, unsigned int ep, unsigned int mps) { struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; @@ -1645,7 +1646,7 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, * @hsotg: The driver state * @idx: The index for the endpoint (0..15) */ -static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) +static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) { int timeout; int val; @@ -1681,7 +1682,7 @@ static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) * Check to see if there is a request that has data to send, and if so * make an attempt to write data into the FIFO. */ -static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg, +static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep) { struct s3c_hsotg_req *hs_req = hs_ep->req; @@ -1714,7 +1715,7 @@ static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg, * An IN transfer has been completed, update the transfer's state and then * call the relevant completion routines. */ -static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, +static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep) { struct s3c_hsotg_req *hs_req = hs_ep->req; @@ -1791,7 +1792,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, * * Process and clear any interrupt pending for an individual endpoint */ -static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, +static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, int dir_in) { struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; @@ -1916,7 +1917,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, * Handle updating the device settings after the enumeration phase has * been completed. */ -static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) +static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) { u32 dsts = readl(hsotg->regs + DSTS); int ep0_mps = 0, ep_mps = 8; @@ -1993,7 +1994,7 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) * Go through the requests on the given endpoint and mark them * completed with the given result code. */ -static void kill_all_requests(struct s3c_hsotg *hsotg, +static void kill_all_requests(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *ep, int result, bool force) { @@ -2027,7 +2028,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, * transactions and signal the gadget driver that this * has happened. */ -static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg) +static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) { unsigned ep; @@ -2042,7 +2043,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg) * @hsotg: The device state: * @periodic: True if this is a periodic FIFO interrupt */ -static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) +static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) { struct s3c_hsotg_ep *ep; int epno, ret; @@ -2076,7 +2077,7 @@ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) * * Issue a soft reset to the core, and await the core finishing it. */ -static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) +static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) { int timeout; u32 grstctl; @@ -2124,7 +2125,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -static void s3c_hsotg_core_init_disconnected(struct s3c_hsotg *hsotg) +static void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) { s3c_hsotg_corereset(hsotg); @@ -2250,13 +2251,13 @@ static void s3c_hsotg_core_init_disconnected(struct s3c_hsotg *hsotg) hsotg->last_rst = jiffies; } -static void s3c_hsotg_core_disconnect(struct s3c_hsotg *hsotg) +static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) { /* set the soft-disconnect bit */ __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); } -static void s3c_hsotg_core_connect(struct s3c_hsotg *hsotg) +static void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) { /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); @@ -2269,7 +2270,7 @@ static void s3c_hsotg_core_connect(struct s3c_hsotg *hsotg) */ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) { - struct s3c_hsotg *hsotg = pw; + struct dwc2_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; @@ -2461,7 +2462,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hsotg = hs_ep->parent; + struct dwc2_hsotg *hsotg = hs_ep->parent; unsigned long flags; int index = hs_ep->index; u32 epctrl_reg; @@ -2604,7 +2605,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, static int s3c_hsotg_ep_disable(struct usb_ep *ep) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hsotg = hs_ep->parent; + struct dwc2_hsotg *hsotg = hs_ep->parent; int dir_in = hs_ep->dir_in; int index = hs_ep->index; unsigned long flags; @@ -2669,7 +2670,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct s3c_hsotg_req *hs_req = our_req(req); struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hs = hs_ep->parent; + struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags; dev_dbg(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); @@ -2695,7 +2696,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hs = hs_ep->parent; + struct dwc2_hsotg *hs = hs_ep->parent; int index = hs_ep->index; u32 epreg; u32 epctl; @@ -2759,7 +2760,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); - struct s3c_hsotg *hs = hs_ep->parent; + struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags = 0; int ret = 0; @@ -2788,7 +2789,7 @@ static struct usb_ep_ops s3c_hsotg_ep_ops = { * A wrapper for platform code responsible for controlling * low-level USB code */ -static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) +static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -2811,7 +2812,7 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) * A wrapper for platform code responsible for controlling * low-level USB code */ -static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) +static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -2829,7 +2830,7 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) * s3c_hsotg_init - initalize the usb core * @hsotg: The driver state */ -static void s3c_hsotg_init(struct s3c_hsotg *hsotg) +static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) { /* unmask subset of endpoint interrupts */ @@ -2879,7 +2880,7 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg) static int s3c_hsotg_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { - struct s3c_hsotg *hsotg = to_hsotg(gadget); + struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags; int ret; @@ -2942,7 +2943,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, */ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) { - struct s3c_hsotg *hsotg = to_hsotg(gadget); + struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; int ep; @@ -2989,7 +2990,7 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) */ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) { - struct s3c_hsotg *hsotg = to_hsotg(gadget); + struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on); @@ -3026,7 +3027,7 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { * creation) to give to the gadget driver. Setup the endpoint name, any * direction information and other state that may be required. */ -static void s3c_hsotg_initep(struct s3c_hsotg *hsotg, +static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, int epnum) { @@ -3075,7 +3076,7 @@ static void s3c_hsotg_initep(struct s3c_hsotg *hsotg, * * Read the USB core HW configuration registers */ -static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg) +static void s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) { u32 cfg2, cfg3, cfg4; /* check hardware configuration */ @@ -3099,7 +3100,7 @@ static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg) * s3c_hsotg_dump - dump state of the udc * @param: The device state */ -static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) +static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) { #ifdef DEBUG struct device *dev = hsotg->dev; @@ -3158,7 +3159,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) */ static int state_show(struct seq_file *seq, void *v) { - struct s3c_hsotg *hsotg = seq->private; + struct dwc2_hsotg *hsotg = seq->private; void __iomem *regs = hsotg->regs; int idx; @@ -3228,7 +3229,7 @@ static const struct file_operations state_fops = { */ static int fifo_show(struct seq_file *seq, void *v) { - struct s3c_hsotg *hsotg = seq->private; + struct dwc2_hsotg *hsotg = seq->private; void __iomem *regs = hsotg->regs; u32 val; int idx; @@ -3284,7 +3285,7 @@ static const char *decode_direction(int is_in) static int ep_show(struct seq_file *seq, void *v) { struct s3c_hsotg_ep *ep = seq->private; - struct s3c_hsotg *hsotg = ep->parent; + struct dwc2_hsotg *hsotg = ep->parent; struct s3c_hsotg_req *req; void __iomem *regs = hsotg->regs; int index = ep->index; @@ -3361,7 +3362,7 @@ static const struct file_operations ep_fops = { * with the same name as the device itself, in case we end up * with multiple blocks in future systems. */ -static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) +static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) { struct dentry *root; unsigned epidx; @@ -3407,7 +3408,7 @@ static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) * * Cleanup (remove) the debugfs files for use on module exit. */ -static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) +static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) { unsigned epidx; @@ -3425,7 +3426,6 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) * s3c_hsotg_probe - probe function for hsotg driver * @pdev: The platform information for the driver */ - static int s3c_hsotg_probe(struct platform_device *pdev) { struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev); @@ -3433,13 +3433,13 @@ static int s3c_hsotg_probe(struct platform_device *pdev) struct usb_phy *uphy; struct device *dev = &pdev->dev; struct s3c_hsotg_ep *eps; - struct s3c_hsotg *hsotg; + struct dwc2_hsotg *hsotg; struct resource *res; int epnum; int ret; int i; - hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); + hsotg = devm_kzalloc(&pdev->dev, sizeof(struct dwc2_hsotg), GFP_KERNEL); if (!hsotg) return -ENOMEM; @@ -3520,7 +3520,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { - dev_err(dev, "failed to request supplies: %d\n", ret); + dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); goto err_clk; } @@ -3528,7 +3528,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) hsotg->supplies); if (ret) { - dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret); + dev_err(dev, "failed to enable supplies: %d\n", ret); goto err_supplies; } @@ -3592,7 +3592,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { - dev_err(hsotg->dev, "failed to disable supplies: %d\n", ret); + dev_err(&pdev->dev, "failed to disable supplies: %d\n", ret); goto err_ep_mem; } @@ -3622,7 +3622,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) */ static int s3c_hsotg_remove(struct platform_device *pdev) { - struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); + struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); usb_del_gadget_udc(&hsotg->gadget); s3c_hsotg_delete_debug(hsotg); @@ -3633,7 +3633,7 @@ static int s3c_hsotg_remove(struct platform_device *pdev) static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) { - struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); + struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); unsigned long flags; int ret = 0; @@ -3664,7 +3664,7 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) static int s3c_hsotg_resume(struct platform_device *pdev) { - struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); + struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); unsigned long flags; int ret = 0; -- GitLab From 117777b2c3bb961ba1cb9943dee93f192d7a3abd Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:34 -0600 Subject: [PATCH 4873/9457] usb: dwc2: Move gadget probe function into platform code This patch will aggregate the probing of gadget/hcd driver into platform.c. The gadget probe funtion is converted into gadget_init that is now only responsible for gadget only initialization. All the gadget resources are now handled by platform.c Since the host workqueue will not get initialized if the driver is configured for peripheral mode only. Thus we need to check for wq_otg before calling queue_work(). Also, we move spin_lock_init to common location for both host and gadget that is either in platform.c or pci.c. We also move suspend/resume code to common platform code. Lastly, move the "samsung,s3c6400-hsotg" binding into dwc2_of_match_table. Signed-off-by: Dinh Nguyen Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 33 ++++++++++++ drivers/usb/dwc2/core_intr.c | 8 +-- drivers/usb/dwc2/gadget.c | 99 ++++++++---------------------------- drivers/usb/dwc2/hcd.c | 1 - drivers/usb/dwc2/hcd.h | 10 ---- drivers/usb/dwc2/pci.c | 1 + drivers/usb/dwc2/platform.c | 28 ++++++++++ 7 files changed, 88 insertions(+), 92 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 7bcdc10e4b01..4905d8880869 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -960,4 +960,37 @@ extern void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg); */ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); +/* Gadget defines */ +#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); +extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +#else +static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +{ return 0; } +static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) +{ return 0; } +#endif + +#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) +extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); +extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); +#else +static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} +static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, + const struct dwc2_core_params *params) +{ return 0; } +#endif + #endif /* __DWC2_CORE_H__ */ diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index c93918b70d03..b176c2fc34e5 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -287,9 +287,11 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) * Release lock before scheduling workq as it holds spinlock during * scheduling. */ - spin_unlock(&hsotg->lock); - queue_work(hsotg->wq_otg, &hsotg->wf_otg); - spin_lock(&hsotg->lock); + if (hsotg->wq_otg) { + spin_unlock(&hsotg->lock); + queue_work(hsotg->wq_otg, &hsotg->wf_otg); + spin_lock(&hsotg->lock); + } /* Clear interrupt */ writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5a24e95ae1b0..9caea513eb0c 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3423,26 +3423,21 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_probe - probe function for hsotg driver - * @pdev: The platform information for the driver + * dwc2_gadget_init - init function for gadget + * @dwc2: The data structure for the DWC2 driver. + * @irq: The IRQ number for the controller. */ -static int s3c_hsotg_probe(struct platform_device *pdev) +int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { - struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev); + struct device *dev = hsotg->dev; + struct s3c_hsotg_plat *plat = dev->platform_data; struct phy *phy; struct usb_phy *uphy; - struct device *dev = &pdev->dev; struct s3c_hsotg_ep *eps; - struct dwc2_hsotg *hsotg; - struct resource *res; int epnum; int ret; int i; - hsotg = devm_kzalloc(&pdev->dev, sizeof(struct dwc2_hsotg), GFP_KERNEL); - if (!hsotg) - return -ENOMEM; - /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; @@ -3450,14 +3445,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev) * Attempt to find a generic PHY, then look for an old style * USB PHY, finally fall back to pdata */ - phy = devm_phy_get(&pdev->dev, "usb2-phy"); + phy = devm_phy_get(dev, "usb2-phy"); if (IS_ERR(phy)) { uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); if (IS_ERR(uphy)) { /* Fallback for pdata */ - plat = dev_get_platdata(&pdev->dev); + plat = dev_get_platdata(dev); if (!plat) { - dev_err(&pdev->dev, + dev_err(dev, "no platform data or transceiver defined\n"); return -EPROBE_DEFER; } @@ -3474,36 +3469,12 @@ static int s3c_hsotg_probe(struct platform_device *pdev) hsotg->phyif = GUSBCFG_PHYIF8; } - hsotg->dev = dev; - - hsotg->clk = devm_clk_get(&pdev->dev, "otg"); + hsotg->clk = devm_clk_get(dev, "otg"); if (IS_ERR(hsotg->clk)) { dev_err(dev, "cannot get otg clock\n"); return PTR_ERR(hsotg->clk); } - platform_set_drvdata(pdev, hsotg); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - hsotg->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hsotg->regs)) { - ret = PTR_ERR(hsotg->regs); - goto err_clk; - } - - ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(dev, "cannot find IRQ\n"); - goto err_clk; - } - - spin_lock_init(&hsotg->lock); - - hsotg->irq = ret; - - dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); - hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); @@ -3520,7 +3491,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { - dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); + dev_err(dev, "failed to request supplies: %d\n", ret); goto err_clk; } @@ -3539,7 +3510,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) s3c_hsotg_hw_cfg(hsotg); s3c_hsotg_init(hsotg); - ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, + ret = devm_request_irq(dev, irq, s3c_hsotg_irq, 0, dev_name(dev), hsotg); if (ret < 0) { s3c_hsotg_phy_disable(hsotg); @@ -3592,11 +3563,11 @@ static int s3c_hsotg_probe(struct platform_device *pdev) ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { - dev_err(&pdev->dev, "failed to disable supplies: %d\n", ret); + dev_err(dev, "failed to disable supplies: %d\n", ret); goto err_ep_mem; } - ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); + ret = usb_add_gadget_udc(dev, &hsotg->gadget); if (ret) goto err_ep_mem; @@ -3615,25 +3586,24 @@ static int s3c_hsotg_probe(struct platform_device *pdev) return ret; } +EXPORT_SYMBOL_GPL(dwc2_gadget_init); /** * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int s3c_hsotg_remove(struct platform_device *pdev) +int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) { - struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); - usb_del_gadget_udc(&hsotg->gadget); s3c_hsotg_delete_debug(hsotg); clk_disable_unprepare(hsotg->clk); return 0; } +EXPORT_SYMBOL_GPL(s3c_hsotg_remove); -static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) +int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) { - struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); unsigned long flags; int ret = 0; @@ -3661,10 +3631,10 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) return ret; } +EXPORT_SYMBOL_GPL(s3c_hsotg_suspend); -static int s3c_hsotg_resume(struct platform_device *pdev) +int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) { - struct dwc2_hsotg *hsotg = platform_get_drvdata(pdev); unsigned long flags; int ret = 0; @@ -3686,31 +3656,4 @@ static int s3c_hsotg_resume(struct platform_device *pdev) return ret; } - -#ifdef CONFIG_OF -static const struct of_device_id s3c_hsotg_of_ids[] = { - { .compatible = "samsung,s3c6400-hsotg", }, - { .compatible = "snps,dwc2", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids); -#endif - -static struct platform_driver s3c_hsotg_driver = { - .driver = { - .name = "s3c-hsotg", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(s3c_hsotg_of_ids), - }, - .probe = s3c_hsotg_probe, - .remove = s3c_hsotg_remove, - .suspend = s3c_hsotg_suspend, - .resume = s3c_hsotg_resume, -}; - -module_platform_driver(s3c_hsotg_driver); - -MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c-hsotg"); +EXPORT_SYMBOL_GPL(s3c_hsotg_resume); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 74800786a169..e377f58f5f4d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2905,7 +2905,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, hcd->has_tt = 1; - spin_lock_init(&hsotg->lock); ((struct wrapper_priv_data *) &hcd->hcd_priv)->hsotg = hsotg; hsotg->priv = hcd; diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index a12bb1538666..e69a843d8928 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -668,9 +668,6 @@ extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg); */ extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg); -extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); -extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); - /** * dwc2_hcd_is_b_host() - Returns 1 if core currently is acting as B host, * and 0 otherwise @@ -679,13 +676,6 @@ extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); */ extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg); -/** - * dwc2_hcd_get_frame_number() - Returns current frame number - * - * @hsotg: The DWC2 HCD - */ -extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); - /** * dwc2_hcd_dump_state() - Dumps hsotg state * diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index c291fca5d21f..6d33ecf2e295 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -141,6 +141,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, pci_set_master(dev); + spin_lock_init(&hsotg->lock); retval = dwc2_hcd_init(hsotg, dev->irq, &dwc2_module_params); if (retval) { pci_disable_device(dev); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 121dbdafc06b..eeba8a44f799 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -121,6 +121,7 @@ static int dwc2_driver_remove(struct platform_device *dev) struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); dwc2_hcd_remove(hsotg); + s3c_hsotg_remove(hsotg); return 0; } @@ -129,6 +130,7 @@ static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, + { .compatible = "samsung,s3c6400-hsotg", .data = NULL}, {}, }; MODULE_DEVICE_TABLE(of, dwc2_of_match_table); @@ -204,6 +206,10 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + spin_lock_init(&hsotg->lock); + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + return retval; retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; @@ -213,6 +219,26 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } +static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_suspend(dwc2); + return ret; +} + +static int dwc2_resume(struct platform_device *dev) +{ + struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + int ret = 0; + + if (dwc2_is_device_mode(dwc2)) + ret = s3c_hsotg_resume(dwc2); + return ret; +} + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, @@ -220,6 +246,8 @@ static struct platform_driver dwc2_platform_driver = { }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, + .suspend = dwc2_suspend, + .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- GitLab From bcc06078ba4da9a8b92342e7005c65ba4c06bdb9 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:35 -0600 Subject: [PATCH 4874/9457] usb: dwc2: convert to use dev_pm_ops API Update suspend/resume to use dev_pm_ops API. Acked-by: Paul Zimmerman Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index eeba8a44f799..b94867ba9ccf 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -219,9 +219,9 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } -static int dwc2_suspend(struct platform_device *dev, pm_message_t state) +static int dwc2_suspend(struct device *dev) { - struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; if (dwc2_is_device_mode(dwc2)) @@ -229,9 +229,9 @@ static int dwc2_suspend(struct platform_device *dev, pm_message_t state) return ret; } -static int dwc2_resume(struct platform_device *dev) +static int dwc2_resume(struct device *dev) { - struct dwc2_hsotg *dwc2 = platform_get_drvdata(dev); + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; if (dwc2_is_device_mode(dwc2)) @@ -239,15 +239,18 @@ static int dwc2_resume(struct platform_device *dev) return ret; } +static const struct dev_pm_ops dwc2_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc2_suspend, dwc2_resume) +}; + static struct platform_driver dwc2_platform_driver = { .driver = { .name = dwc2_driver_name, .of_match_table = dwc2_of_match_table, + .pm = &dwc2_dev_pm_ops, }, .probe = dwc2_driver_probe, .remove = dwc2_driver_remove, - .suspend = dwc2_suspend, - .resume = dwc2_resume, }; module_platform_driver(dwc2_platform_driver); -- GitLab From 510ffaa48eac2587a4df9ec7668e3274e5f96ee3 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:36 -0600 Subject: [PATCH 4875/9457] usb: dwc2: Initialize the USB core for peripheral mode Initialize the USB driver to peripheral mode when a B-Device connector is attached. Signed-off-by: Dinh Nguyen Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 4 ++++ drivers/usb/dwc2/gadget.c | 4 ++-- drivers/usb/dwc2/hcd.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 4905d8880869..4710935fbad3 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -966,6 +966,8 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); +extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -975,6 +977,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } +static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 9caea513eb0c..ec853406a930 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2125,7 +2125,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -static void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) +void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) { s3c_hsotg_corereset(hsotg); @@ -2257,7 +2257,7 @@ static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); } -static void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) +void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) { /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index e377f58f5f4d..1a6dea323c8f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1371,6 +1371,8 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_connect(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg->dev, "connId A\n"); -- GitLab From db8178c33dbe9aba5e2c5d323625f9e6da55d7e6 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:37 -0600 Subject: [PATCH 4876/9457] usb: dwc2: Update common interrupt handler to call gadget interrupt handler Make dwc2_handle_common_intr call the gadget interrupt function when operating in peripheral mode. Remove the spinlock functions in s3c_hsotg_irq as dwc2_handle_common_intr() already has the spinlocks. Move the registeration of the IRQ to common code for platform and PCI. Remove duplicate interrupt conditions that was in gadget, as those are handled by dwc2 common interrupt handler. Acked-by: Paul Zimmerman Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 10 -------- drivers/usb/dwc2/gadget.c | 46 +++---------------------------------- drivers/usb/dwc2/pci.c | 6 +++++ drivers/usb/dwc2/platform.c | 8 +++++++ 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d9269459d481..7605850b7a9c 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -458,16 +458,6 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) /* Clear the SRP success bit for FS-I2c */ hsotg->srp_success = 0; - if (irq >= 0) { - dev_dbg(hsotg->dev, "registering common handler for irq%d\n", - irq); - retval = devm_request_irq(hsotg->dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg->dev), hsotg); - if (retval) - return retval; - } - /* Enable common interrupts */ dwc2_enable_common_interrupts(hsotg); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ec853406a930..37c791602d66 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2285,33 +2285,12 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) gintsts &= gintmsk; - if (gintsts & GINTSTS_OTGINT) { - u32 otgint = readl(hsotg->regs + GOTGINT); - - dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); - - writel(otgint, hsotg->regs + GOTGINT); - } - - if (gintsts & GINTSTS_SESSREQINT) { - dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__); - writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); - } - if (gintsts & GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } - if (gintsts & GINTSTS_CONIDSTSCHNG) { - dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n", - readl(hsotg->regs + DSTS), - readl(hsotg->regs + GOTGCTL)); - - writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); - } - if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { u32 daint = readl(hsotg->regs + DAINT); u32 daintmsk = readl(hsotg->regs + DAINTMSK); @@ -2392,25 +2371,6 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) s3c_hsotg_handle_rx(hsotg); } - if (gintsts & GINTSTS_MODEMIS) { - dev_warn(hsotg->dev, "warning, mode mismatch triggered\n"); - writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); - } - - if (gintsts & GINTSTS_USBSUSP) { - dev_info(hsotg->dev, "GINTSTS_USBSusp\n"); - writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); - - call_gadget(hsotg, suspend); - } - - if (gintsts & GINTSTS_WKUPINT) { - dev_info(hsotg->dev, "GINTSTS_WkUpIn\n"); - writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); - - call_gadget(hsotg, resume); - } - if (gintsts & GINTSTS_ERLYSUSP) { dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS); @@ -3510,14 +3470,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) s3c_hsotg_hw_cfg(hsotg); s3c_hsotg_init(hsotg); - ret = devm_request_irq(dev, irq, s3c_hsotg_irq, 0, - dev_name(dev), hsotg); + ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED, + dev_name(hsotg->dev), hsotg); if (ret < 0) { s3c_hsotg_phy_disable(hsotg); clk_disable_unprepare(hsotg->clk); regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - dev_err(dev, "cannot claim IRQ\n"); + dev_err(dev, "cannot claim IRQ for gadget\n"); goto err_clk; } diff --git a/drivers/usb/dwc2/pci.c b/drivers/usb/dwc2/pci.c index 6d33ecf2e295..a4e724b0a62e 100644 --- a/drivers/usb/dwc2/pci.c +++ b/drivers/usb/dwc2/pci.c @@ -141,6 +141,12 @@ static int dwc2_driver_probe(struct pci_dev *dev, pci_set_master(dev); + retval = devm_request_irq(hsotg->dev, dev->irq, + dwc2_handle_common_intr, IRQF_SHARED, + dev_name(hsotg->dev), hsotg); + if (retval) + return retval; + spin_lock_init(&hsotg->lock); retval = dwc2_hcd_init(hsotg, dev->irq, &dwc2_module_params); if (retval) { diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index b94867ba9ccf..3552602ddbf6 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -196,6 +196,14 @@ static int dwc2_driver_probe(struct platform_device *dev) return irq; } + dev_dbg(hsotg->dev, "registering common handler for irq%d\n", + irq); + retval = devm_request_irq(hsotg->dev, irq, + dwc2_handle_common_intr, IRQF_SHARED, + dev_name(hsotg->dev), hsotg); + if (retval) + return retval; + res = platform_get_resource(dev, IORESOURCE_MEM, 0); hsotg->regs = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(hsotg->regs)) -- GitLab From 8d736d8a9c44547f14711c52875c88d19d8b287b Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:38 -0600 Subject: [PATCH 4877/9457] usb: dwc2: gadget: Do not fail probe if there isn't a clock node Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. By assigning clk = NULL, this allows the driver, when configured for dual-role mode, to be able to continue loading the host portion of the driver when a clock node is not specified. Acked-by: Paul Zimmerman Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 37c791602d66..367689b3d645 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3431,6 +3431,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->clk = devm_clk_get(dev, "otg"); if (IS_ERR(hsotg->clk)) { + hsotg->clk = NULL; dev_err(dev, "cannot get otg clock\n"); return PTR_ERR(hsotg->clk); } -- GitLab From f5500ecc90a887d7e65274817733fbe477070559 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:39 -0600 Subject: [PATCH 4878/9457] usb: dwc2: move usb_disabled() call to host driver only Since platform.c will get built for both Host and Gadget, if we leave the usb_disabled() call in platform.c, it results in the following build error when (!USB && USB_GADGET) condition is met. ERROR: "usb_disabled" [drivers/usb/dwc2/dwc2_platform.ko] undefined! Since usb_disabled() is mostly used to disable USB host functionality, move the call the host portion for the DWC2 driver. Acked-by: Paul Zimmerman Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 3 +++ drivers/usb/dwc2/platform.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1a6dea323c8f..a0cd9db6f4cd 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2846,6 +2846,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, int i, num_channels; int retval; + if (usb_disabled()) + return -ENODEV; + dev_dbg(hsotg->dev, "DWC OTG HCD INIT\n"); /* Detect config values from hardware */ diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 3552602ddbf6..57eb8a3e022b 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -157,9 +157,6 @@ static int dwc2_driver_probe(struct platform_device *dev) int retval; int irq; - if (usb_disabled()) - return -ENODEV; - match = of_match_device(dwc2_of_match_table, &dev->dev); if (match && match->data) { params = match->data; -- GitLab From 5ee80705a5339270538119d1e8721b365eac5202 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 11 Nov 2014 11:13:40 -0600 Subject: [PATCH 4879/9457] usb: dwc2: Update Kconfig to support dual-role Update DWC2 kconfig and makefile to support dual-role mode. The platform file will always get compiled for the case where the controller is directly connected to the CPU. So for loadable modules, dwc2.ko is built for host, peripheral, and dual-role mode. The PCI bus interface will be called dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. Signed-off-by: Dinh Nguyen Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/Kconfig | 66 +++++++++++++++++++++++---------------- drivers/usb/dwc2/Makefile | 32 +++++++++---------- 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index 4d027180cea1..b323c4c11b0a 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,5 +1,5 @@ config USB_DWC2 - bool "DesignWare USB2 DRD Core Support" + tristate "DesignWare USB2 DRD Core Support" depends on USB || USB_GADGET help Say Y here if your system has a Dual Role Hi-Speed USB @@ -10,49 +10,61 @@ config USB_DWC2 bus interface module (if you have a PCI bus system) will be called dwc2_pci.ko, and the platform interface module (for controllers directly connected to the CPU) will be called - dwc2_platform.ko. For gadget mode, there will be a single - module called dwc2_gadget.ko. - - NOTE: The s3c-hsotg driver is now renamed to dwc2_gadget. The - host and gadget drivers are still currently separate drivers. - There are plans to merge the dwc2_gadget driver with the dwc2 - host driver in the near future to create a dual-role driver. + dwc2_platform.ko. For all modes(host, gadget and dual-role), there + will be an additional module named dwc2.ko. if USB_DWC2 +choice + bool "DWC2 Mode Selection" + default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET) + default USB_DWC2_HOST if (USB && !USB_GADGET) + default USB_DWC2_PERIPHERAL if (!USB && USB_GADGET) + config USB_DWC2_HOST - tristate "Host only mode" + bool "Host only mode" depends on USB help The Designware USB2.0 high-speed host controller - integrated into many SoCs. + integrated into many SoCs. Select this option if you want the + driver to operate in Host-only mode. -config USB_DWC2_PLATFORM - bool "DWC2 Platform" - depends on USB_DWC2_HOST - default USB_DWC2_HOST +comment "Gadget/Dual-role mode requires USB Gadget support to be enabled" + +config USB_DWC2_PERIPHERAL + bool "Gadget only mode" + depends on USB_GADGET=y || USB_GADGET=USB_DWC2 + help + The Designware USB2.0 high-speed gadget controller + integrated into many SoCs. Select this option if you want the + driver to operate in Peripheral-only mode. This option requires + USB_GADGET to be enabled. + +config USB_DWC2_DUAL_ROLE + bool "Dual Role mode" + depends on (USB=y || USB=USB_DWC2) && (USB_GADGET=y || USB_GADGET=USB_DWC2) help - The Designware USB2.0 platform interface module for - controllers directly connected to the CPU. This is only - used for host mode. + Select this option if you want the driver to work in a dual-role + mode. In this mode both host and gadget features are enabled, and + the role will be determined by the cable that gets plugged-in. This + option requires USB_GADGET to be enabled. +endchoice + +config USB_DWC2_PLATFORM + tristate "DWC2 Platform" + default USB_DWC2_HOST || USB_DWC2_PERIPHERAL + help + The Designware USB2.0 platform interface module for + controllers directly connected to the CPU. config USB_DWC2_PCI - bool "DWC2 PCI" + tristate "DWC2 PCI" depends on USB_DWC2_HOST && PCI default USB_DWC2_HOST help The Designware USB2.0 PCI interface module for controllers connected to a PCI bus. This is only used for host mode. -comment "Gadget mode requires USB Gadget support to be enabled" - -config USB_DWC2_PERIPHERAL - tristate "Gadget only mode" - depends on USB_GADGET - help - The Designware USB2.0 high-speed gadget controller - integrated into many SoCs. - config USB_DWC2_DEBUG bool "Enable Debugging Messages" help diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b73d2a527970..8f752679752a 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,28 +1,28 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG -obj-$(CONFIG_USB_DWC2_HOST) += dwc2.o +obj-$(CONFIG_USB_DWC2) += dwc2.o dwc2-y := core.o core_intr.o -dwc2-y += hcd.o hcd_intr.o -dwc2-y += hcd_queue.o hcd_ddma.o + +ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += hcd.o hcd_intr.o + dwc2-y += hcd_queue.o hcd_ddma.o +endif + +ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),) + dwc2-y += gadget.o +endif # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to # this location and renamed gadget.c. When building for dynamically linked -# modules, dwc2_gadget.ko will get built for peripheral mode. For host mode, -# the core module will be dwc2.ko, the PCI bus interface module will called -# dwc2_pci.ko and the platform interface module will be called dwc2_platform.ko. -# At present the host and gadget driver will be separate drivers, but there -# are plans in the near future to create a dual-role driver. +# modules, dwc2.ko will get built for host mode, peripheral mode, and dual-role +# mode. The PCI bus interface module will called dwc2_pci.ko and the platform +# interface module will be called dwc2_platform.ko. ifneq ($(CONFIG_USB_DWC2_PCI),) - obj-$(CONFIG_USB_DWC2_HOST) += dwc2_pci.o + obj-$(CONFIG_USB_DWC2) += dwc2_pci.o dwc2_pci-y := pci.o endif -ifneq ($(CONFIG_USB_DWC2_PLATFORM),) - obj-$(CONFIG_USB_DWC2_HOST) += dwc2_platform.o - dwc2_platform-y := platform.o -endif - -obj-$(CONFIG_USB_DWC2_PERIPHERAL) += dwc2_gadget.o -dwc2_gadget-y := gadget.o +obj-$(CONFIG_USB_DWC2_PLATFORM) += dwc2_platform.o +dwc2_platform-y := platform.o -- GitLab From a77f9c5dcdf8480a93332792c336fa2bf9d31229 Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Fri, 14 Nov 2014 11:05:06 -0800 Subject: [PATCH 4880/9457] Revert "fast_hash: avoid indirect function calls" This reverts commit e5a2c899957659cd1a9f789bc462f9c0b35f5150. Commit e5a2c899 introduced an alternative_call, arch_fast_hash2, that selects between __jhash2 and __intel_crc4_2_hash based on the X86_FEATURE_XMM4_2. Unfortunately, the alternative_call system does not appear to be suitable for use with C functions, as register usage is not handled properly for the called functions. The __jhash2 function in particular clobbers registers that are not preserved when called via alternative_call, resulting in a panic for direct callers of arch_fast_hash2 on older CPUs lacking sse4_2. It is possible that __intel_crc4_2_hash works merely by chance because it uses fewer registers. This commit was suggested as the source of the problem by Jesse Gross . Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- arch/x86/include/asm/hash.h | 51 ++++--------------------------------- arch/x86/lib/hash.c | 29 +++++++++------------ include/asm-generic/hash.h | 36 ++------------------------ include/linux/hash.h | 34 +++++++++++++++++++++++++ lib/Makefile | 2 +- lib/hash.c | 39 ++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 98 deletions(-) create mode 100644 lib/hash.c diff --git a/arch/x86/include/asm/hash.h b/arch/x86/include/asm/hash.h index a881d784f044..e8c58f88b1d4 100644 --- a/arch/x86/include/asm/hash.h +++ b/arch/x86/include/asm/hash.h @@ -1,48 +1,7 @@ -#ifndef __ASM_X86_HASH_H -#define __ASM_X86_HASH_H +#ifndef _ASM_X86_HASH_H +#define _ASM_X86_HASH_H -#include -#include +struct fast_hash_ops; +extern void setup_arch_fast_hash(struct fast_hash_ops *ops); -u32 __intel_crc4_2_hash(const void *data, u32 len, u32 seed); -u32 __intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed); - -/* - * non-inline versions of jhash so gcc does not need to generate - * duplicate code in every object file - */ -u32 __jhash(const void *data, u32 len, u32 seed); -u32 __jhash2(const u32 *data, u32 len, u32 seed); - -/* - * for documentation of these functions please look into - * - */ - -static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed) -{ - u32 hash; - - alternative_call(__jhash, __intel_crc4_2_hash, X86_FEATURE_XMM4_2, -#ifdef CONFIG_X86_64 - "=a" (hash), "D" (data), "S" (len), "d" (seed)); -#else - "=a" (hash), "a" (data), "d" (len), "c" (seed)); -#endif - return hash; -} - -static inline u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed) -{ - u32 hash; - - alternative_call(__jhash2, __intel_crc4_2_hash2, X86_FEATURE_XMM4_2, -#ifdef CONFIG_X86_64 - "=a" (hash), "D" (data), "S" (len), "d" (seed)); -#else - "=a" (hash), "a" (data), "d" (len), "c" (seed)); -#endif - return hash; -} - -#endif /* __ASM_X86_HASH_H */ +#endif /* _ASM_X86_HASH_H */ diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index e14327198835..ff4fa51a5b1f 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -31,13 +31,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + #include #include #include -#include -#include - static inline u32 crc32_u32(u32 crc, u32 val) { #ifdef CONFIG_AS_CRC32 @@ -48,7 +48,7 @@ static inline u32 crc32_u32(u32 crc, u32 val) return crc; } -u32 __intel_crc4_2_hash(const void *data, u32 len, u32 seed) +static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) { const u32 *p32 = (const u32 *) data; u32 i, tmp = 0; @@ -71,27 +71,22 @@ u32 __intel_crc4_2_hash(const void *data, u32 len, u32 seed) return seed; } -EXPORT_SYMBOL(__intel_crc4_2_hash); -u32 __intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) +static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) { + const u32 *p32 = (const u32 *) data; u32 i; for (i = 0; i < len; i++) - seed = crc32_u32(seed, *data++); + seed = crc32_u32(seed, *p32++); return seed; } -EXPORT_SYMBOL(__intel_crc4_2_hash2); -u32 __jhash(const void *data, u32 len, u32 seed) +void __init setup_arch_fast_hash(struct fast_hash_ops *ops) { - return jhash(data, len, seed); -} -EXPORT_SYMBOL(__jhash); - -u32 __jhash2(const u32 *data, u32 len, u32 seed) -{ - return jhash2(data, len, seed); + if (cpu_has_xmm4_2) { + ops->hash = intel_crc4_2_hash; + ops->hash2 = intel_crc4_2_hash2; + } } -EXPORT_SYMBOL(__jhash2); diff --git a/include/asm-generic/hash.h b/include/asm-generic/hash.h index 3c82760ff2a4..b6312843dbd9 100644 --- a/include/asm-generic/hash.h +++ b/include/asm-generic/hash.h @@ -1,41 +1,9 @@ #ifndef __ASM_GENERIC_HASH_H #define __ASM_GENERIC_HASH_H -#include - -/** - * arch_fast_hash - Caclulates a hash over a given buffer that can have - * arbitrary size. This function will eventually use an - * architecture-optimized hashing implementation if - * available, and trades off distribution for speed. - * - * @data: buffer to hash - * @len: length of buffer in bytes - * @seed: start seed - * - * Returns 32bit hash. - */ -static inline u32 arch_fast_hash(const void *data, u32 len, u32 seed) -{ - return jhash(data, len, seed); -} - -/** - * arch_fast_hash2 - Caclulates a hash over a given buffer that has a - * size that is of a multiple of 32bit words. This - * function will eventually use an architecture- - * optimized hashing implementation if available, - * and trades off distribution for speed. - * - * @data: buffer to hash (must be 32bit padded) - * @len: number of 32bit words - * @seed: start seed - * - * Returns 32bit hash. - */ -static inline u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed) +struct fast_hash_ops; +static inline void setup_arch_fast_hash(struct fast_hash_ops *ops) { - return jhash2(data, len, seed); } #endif /* __ASM_GENERIC_HASH_H */ diff --git a/include/linux/hash.h b/include/linux/hash.h index 6e8fb028848c..d0494c399392 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h @@ -84,4 +84,38 @@ static inline u32 hash32_ptr(const void *ptr) return (u32)val; } +struct fast_hash_ops { + u32 (*hash)(const void *data, u32 len, u32 seed); + u32 (*hash2)(const u32 *data, u32 len, u32 seed); +}; + +/** + * arch_fast_hash - Caclulates a hash over a given buffer that can have + * arbitrary size. This function will eventually use an + * architecture-optimized hashing implementation if + * available, and trades off distribution for speed. + * + * @data: buffer to hash + * @len: length of buffer in bytes + * @seed: start seed + * + * Returns 32bit hash. + */ +extern u32 arch_fast_hash(const void *data, u32 len, u32 seed); + +/** + * arch_fast_hash2 - Caclulates a hash over a given buffer that has a + * size that is of a multiple of 32bit words. This + * function will eventually use an architecture- + * optimized hashing implementation if available, + * and trades off distribution for speed. + * + * @data: buffer to hash (must be 32bit padded) + * @len: number of 32bit words + * @seed: start seed + * + * Returns 32bit hash. + */ +extern u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed); + #endif /* _LINUX_HASH_H */ diff --git a/lib/Makefile b/lib/Makefile index 04e53dd16070..7512dc978f18 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \ bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ - percpu-refcount.o percpu_ida.o rhashtable.o + percpu-refcount.o percpu_ida.o hash.o rhashtable.o obj-y += string_helpers.o obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o obj-y += kstrtox.o diff --git a/lib/hash.c b/lib/hash.c new file mode 100644 index 000000000000..fea973f4bd57 --- /dev/null +++ b/lib/hash.c @@ -0,0 +1,39 @@ +/* General purpose hashing library + * + * That's a start of a kernel hashing library, which can be extended + * with further algorithms in future. arch_fast_hash{2,}() will + * eventually resolve to an architecture optimized implementation. + * + * Copyright 2013 Francesco Fusco + * Copyright 2013 Daniel Borkmann + * Copyright 2013 Thomas Graf + * Licensed under the GNU General Public License, version 2.0 (GPLv2) + */ + +#include +#include +#include + +static struct fast_hash_ops arch_hash_ops __read_mostly = { + .hash = jhash, + .hash2 = jhash2, +}; + +u32 arch_fast_hash(const void *data, u32 len, u32 seed) +{ + return arch_hash_ops.hash(data, len, seed); +} +EXPORT_SYMBOL_GPL(arch_fast_hash); + +u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed) +{ + return arch_hash_ops.hash2(data, len, seed); +} +EXPORT_SYMBOL_GPL(arch_fast_hash2); + +static int __init hashlib_init(void) +{ + setup_arch_fast_hash(&arch_hash_ops); + return 0; +} +early_initcall(hashlib_init); -- GitLab From 29ce9feb65d377ea24cb0d3aabc63b090e56c152 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 24 Oct 2014 07:45:58 -0700 Subject: [PATCH 4881/9457] leds: regulator: Convert to devm_regulator_get_exclusive Signed-off-by: Axel Lin Signed-off-by: Bryan Wu --- drivers/leds/leds-regulator.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c index 358430db6e66..a6354f1ce7b2 100644 --- a/drivers/leds/leds-regulator.c +++ b/drivers/leds/leds-regulator.c @@ -153,24 +153,21 @@ static int regulator_led_probe(struct platform_device *pdev) return -ENODEV; } - vcc = regulator_get_exclusive(&pdev->dev, "vled"); + vcc = devm_regulator_get_exclusive(&pdev->dev, "vled"); if (IS_ERR(vcc)) { dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); return PTR_ERR(vcc); } led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); - if (led == NULL) { - ret = -ENOMEM; - goto err_vcc; - } + if (led == NULL) + return -ENOMEM; led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); if (pdata->brightness > led->cdev.max_brightness) { dev_err(&pdev->dev, "Invalid default brightness %d\n", pdata->brightness); - ret = -EINVAL; - goto err_vcc; + return -EINVAL; } led->value = pdata->brightness; @@ -191,7 +188,7 @@ static int regulator_led_probe(struct platform_device *pdev) ret = led_classdev_register(&pdev->dev, &led->cdev); if (ret < 0) { cancel_work_sync(&led->work); - goto err_vcc; + return ret; } /* to expose the default value to userspace */ @@ -201,10 +198,6 @@ static int regulator_led_probe(struct platform_device *pdev) regulator_led_set_value(led); return 0; - -err_vcc: - regulator_put(vcc); - return ret; } static int regulator_led_remove(struct platform_device *pdev) @@ -214,7 +207,6 @@ static int regulator_led_remove(struct platform_device *pdev) led_classdev_unregister(&led->cdev); cancel_work_sync(&led->work); regulator_led_disable(led); - regulator_put(led->vcc); return 0; } -- GitLab From 37fa70f026474db98fc395a45eda2bbceb210c74 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 24 Oct 2014 03:57:06 -0700 Subject: [PATCH 4882/9457] leds: delete copy/paste mistake A chunk of text followed the copied license text, ehm, sorry that kind of things happen from time to time. Signed-off-by: Linus Walleij Signed-off-by: Bryan Wu --- drivers/leds/leds-syscon.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c index 3afec79c43f4..e0ccfc872c2f 100644 --- a/drivers/leds/leds-syscon.c +++ b/drivers/leds/leds-syscon.c @@ -18,10 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * This driver provides system reboot functionality for APM X-Gene SoC. - * For system shutdown, this is board specify. If a board designer - * implements GPIO shutdown, use the gpio-poweroff.c driver. */ #include #include -- GitLab From 3f6e42c808409c40dd0d0f8fe2022d197b27455e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 24 Oct 2014 03:57:19 -0700 Subject: [PATCH 4883/9457] leds: syscon: handle multiple syscon instances Currently the syscon LED driver will only handle LEDs on the first syscon found in the system. But there can be several of them, so augment the driver to traverse all syscon nodes and check for syscon LEDs on them. Signed-off-by: Linus Walleij Signed-off-by: Bryan Wu --- drivers/leds/leds-syscon.c | 67 ++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c index e0ccfc872c2f..6896e2d9ba58 100644 --- a/drivers/leds/leds-syscon.c +++ b/drivers/leds/leds-syscon.c @@ -66,39 +66,13 @@ static void syscon_led_set(struct led_classdev *led_cdev, dev_err(sled->cdev.dev, "error updating LED status\n"); } -static const struct of_device_id syscon_match[] = { - { .compatible = "syscon", }, - {}, -}; - -static int __init syscon_leds_init(void) +static int __init syscon_leds_spawn(struct device_node *np, + struct device *dev, + struct regmap *map) { - const struct of_device_id *devid; - struct device_node *np; struct device_node *child; - struct regmap *map; - struct platform_device *pdev; - struct device *dev; int ret; - np = of_find_matching_node_and_match(NULL, syscon_match, - &devid); - if (!np) - return -ENODEV; - - map = syscon_node_to_regmap(np); - if (IS_ERR(map)) - return PTR_ERR(map); - - /* - * If the map is there, the device should be there, we allocate - * memory on the syscon device's behalf here. - */ - pdev = of_find_device_by_node(np); - if (!pdev) - return -ENODEV; - dev = &pdev->dev; - for_each_available_child_of_node(np, child) { struct syscon_led *sled; const char *state; @@ -146,7 +120,6 @@ static int __init syscon_leds_init(void) if (ret < 0) return ret; } - } sled->cdev.brightness_set = syscon_led_set; @@ -156,7 +129,39 @@ static int __init syscon_leds_init(void) dev_info(dev, "registered LED %s\n", sled->cdev.name); } + return 0; +} + +static int __init syscon_leds_init(void) +{ + struct device_node *np; + + for_each_of_allnodes(np) { + struct platform_device *pdev; + struct regmap *map; + int ret; + + if (!of_device_is_compatible(np, "syscon")) + continue; + + map = syscon_node_to_regmap(np); + if (IS_ERR(map)) { + pr_err("error getting regmap for syscon LEDs\n"); + continue; + } + + /* + * If the map is there, the device should be there, we allocate + * memory on the syscon device's behalf here. + */ + pdev = of_find_device_by_node(np); + if (!pdev) + return -ENODEV; + ret = syscon_leds_spawn(np, &pdev->dev, map); + if (ret) + dev_err(&pdev->dev, "could not spawn syscon LEDs\n"); + } - return 0; + return 0; } device_initcall(syscon_leds_init); -- GitLab From acd899e4f3066b6662f6047da5b795cc762093cb Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 22 Sep 2014 08:21:04 -0700 Subject: [PATCH 4884/9457] leds: implement sysfs interface locking mechanism Add a mechanism for locking LED subsystem sysfs interface. This patch prepares ground for addition of LED Flash Class extension, whose API will be integrated with V4L2 Flash API. Such a fusion enforces introducing a locking scheme, which will secure consistent access to the LED Flash Class device. The mechanism being introduced allows for disabling LED subsystem sysfs interface by calling led_sysfs_disable function and enabling it by calling led_sysfs_enable. The functions alter the LED_SYSFS_DISABLE flag state and must be called under mutex lock. The state of the lock is checked with use of led_sysfs_is_disabled function. Such a design allows for providing immediate feedback to the user space on whether the LED Flash Class device is available or is under V4L2 Flash sub-device control. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Richard Purdie Signed-off-by: Bryan Wu --- drivers/leds/led-class.c | 19 ++++++++++++++++--- drivers/leds/led-core.c | 18 ++++++++++++++++++ drivers/leds/led-triggers.c | 16 +++++++++++++--- include/linux/leds.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 6 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 7440c58b8e6f..65722deb8d28 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -40,17 +40,27 @@ static ssize_t brightness_store(struct device *dev, { struct led_classdev *led_cdev = dev_get_drvdata(dev); unsigned long state; - ssize_t ret = -EINVAL; + ssize_t ret; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } ret = kstrtoul(buf, 10, &state); if (ret) - return ret; + goto unlock; if (state == LED_OFF) led_trigger_remove(led_cdev); __led_set_brightness(led_cdev, state); - return size; + ret = size; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } static DEVICE_ATTR_RW(brightness); @@ -214,6 +224,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); #endif + mutex_init(&led_cdev->led_access); /* add to the list of leds */ down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); @@ -267,6 +278,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev) down_write(&leds_list_lock); list_del(&led_cdev->node); up_write(&leds_list_lock); + + mutex_destroy(&led_cdev->led_access); } EXPORT_SYMBOL_GPL(led_classdev_unregister); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index aaa8eba9099f..be6d9fa5e971 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -143,3 +143,21 @@ int led_update_brightness(struct led_classdev *led_cdev) return ret; } EXPORT_SYMBOL(led_update_brightness); + +/* Caller must ensure led_cdev->led_access held */ +void led_sysfs_disable(struct led_classdev *led_cdev) +{ + lockdep_assert_held(&led_cdev->led_access); + + led_cdev->flags |= LED_SYSFS_DISABLE; +} +EXPORT_SYMBOL_GPL(led_sysfs_disable); + +/* Caller must ensure led_cdev->led_access held */ +void led_sysfs_enable(struct led_classdev *led_cdev) +{ + lockdep_assert_held(&led_cdev->led_access); + + led_cdev->flags &= ~LED_SYSFS_DISABLE; +} +EXPORT_SYMBOL_GPL(led_sysfs_enable); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index c3734f10fdd5..e8b1120f486d 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -37,6 +37,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, char trigger_name[TRIG_NAME_MAX]; struct led_trigger *trig; size_t len; + int ret = count; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } trigger_name[sizeof(trigger_name) - 1] = '\0'; strncpy(trigger_name, buf, sizeof(trigger_name) - 1); @@ -47,7 +55,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, if (!strcmp(trigger_name, "none")) { led_trigger_remove(led_cdev); - return count; + goto unlock; } down_read(&triggers_list_lock); @@ -58,12 +66,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); - return count; + goto unlock; } } up_read(&triggers_list_lock); - return -EINVAL; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } EXPORT_SYMBOL_GPL(led_trigger_store); diff --git a/include/linux/leds.h b/include/linux/leds.h index a57611d0c94e..737f9b1051f2 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -13,6 +13,7 @@ #define __LINUX_LEDS_H_INCLUDED #include +#include #include #include #include @@ -42,6 +43,7 @@ struct led_classdev { #define LED_BLINK_ONESHOT (1 << 17) #define LED_BLINK_ONESHOT_STOP (1 << 18) #define LED_BLINK_INVERT (1 << 19) +#define LED_SYSFS_DISABLE (1 << 20) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ @@ -85,6 +87,9 @@ struct led_classdev { /* true if activated - deactivate routine uses it to do cleanup */ bool activated; #endif + + /* Ensures consistent access to the LED Flash Class device */ + struct mutex led_access; }; extern int led_classdev_register(struct device *parent, @@ -151,6 +156,33 @@ extern void led_set_brightness(struct led_classdev *led_cdev, */ extern int led_update_brightness(struct led_classdev *led_cdev); +/** + * led_sysfs_disable - disable LED sysfs interface + * @led_cdev: the LED to set + * + * Disable the led_cdev's sysfs interface. + */ +extern void led_sysfs_disable(struct led_classdev *led_cdev); + +/** + * led_sysfs_enable - enable LED sysfs interface + * @led_cdev: the LED to set + * + * Enable the led_cdev's sysfs interface. + */ +extern void led_sysfs_enable(struct led_classdev *led_cdev); + +/** + * led_sysfs_is_disabled - check if LED sysfs interface is disabled + * @led_cdev: the LED to query + * + * Returns: true if the led_cdev's sysfs interface is disabled. + */ +static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev) +{ + return led_cdev->flags & LED_SYSFS_DISABLE; +} + /* * LED Triggers */ -- GitLab From 4d71a4a12b130ad033219e6f58c74a64059415eb Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Fri, 14 Nov 2014 02:50:18 -0800 Subject: [PATCH 4885/9457] leds: Add support for setting brightness in a synchronous way There are use cases when setting a LED brightness has to have immediate effect (e.g. setting a torch LED brightness). This patch extends LED subsystem to support such operations. The LED subsystem internal API __led_set_brightness is changed to led_set_brightness_async and new led_set_brightness_sync API is added. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Richard Purdie Signed-off-by: Bryan Wu --- drivers/leds/led-class.c | 10 ++++++---- drivers/leds/led-core.c | 18 +++++++++++++++--- drivers/leds/leds.h | 20 ++++++++++++++++---- drivers/leds/trigger/ledtrig-backlight.c | 8 ++++---- drivers/leds/trigger/ledtrig-default-on.c | 2 +- drivers/leds/trigger/ledtrig-gpio.c | 6 +++--- drivers/leds/trigger/ledtrig-heartbeat.c | 2 +- drivers/leds/trigger/ledtrig-oneshot.c | 4 ++-- drivers/leds/trigger/ledtrig-transient.c | 10 ++++++---- include/linux/leds.h | 8 ++++++++ 10 files changed, 62 insertions(+), 26 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 65722deb8d28..dbeebac38d31 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -55,7 +55,7 @@ static ssize_t brightness_store(struct device *dev, if (state == LED_OFF) led_trigger_remove(led_cdev); - __led_set_brightness(led_cdev, state); + led_set_brightness(led_cdev, state); ret = size; unlock: @@ -109,7 +109,7 @@ static void led_timer_function(unsigned long data) unsigned long delay; if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return; } @@ -132,7 +132,7 @@ static void led_timer_function(unsigned long data) delay = led_cdev->blink_delay_off; } - __led_set_brightness(led_cdev, brightness); + led_set_brightness_async(led_cdev, brightness); /* Return in next iteration if led is in one-shot mode and we are in * the final blink state so that the led is toggled each delay_on + @@ -158,7 +158,7 @@ static void set_brightness_delayed(struct work_struct *ws) led_stop_software_blink(led_cdev); - __led_set_brightness(led_cdev, led_cdev->delayed_set_value); + led_set_brightness_async(led_cdev, led_cdev->delayed_set_value); } /** @@ -233,6 +233,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; + led_cdev->flags |= SET_BRIGHTNESS_ASYNC; + led_update_brightness(led_cdev); INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index be6d9fa5e971..9886dace5ad2 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -42,13 +42,13 @@ static void led_set_software_blink(struct led_classdev *led_cdev, /* never on - just set to off */ if (!delay_on) { - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return; } /* never off - just set to brightness */ if (!delay_off) { - __led_set_brightness(led_cdev, led_cdev->blink_brightness); + led_set_brightness_async(led_cdev, led_cdev->blink_brightness); return; } @@ -117,6 +117,8 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink); void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { + int ret = 0; + /* delay brightness setting if need to stop soft-blink timer */ if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { led_cdev->delayed_set_value = brightness; @@ -124,7 +126,17 @@ void led_set_brightness(struct led_classdev *led_cdev, return; } - __led_set_brightness(led_cdev, brightness); + if (led_cdev->flags & SET_BRIGHTNESS_ASYNC) { + led_set_brightness_async(led_cdev, brightness); + return; + } else if (led_cdev->flags & SET_BRIGHTNESS_SYNC) + ret = led_set_brightness_sync(led_cdev, brightness); + else + ret = -EINVAL; + + if (ret < 0) + dev_dbg(led_cdev->dev, "Setting LED brightness failed (%d)\n", + ret); } EXPORT_SYMBOL(led_set_brightness); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 4c50365344a9..2348dbda5269 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -17,16 +17,28 @@ #include #include -static inline void __led_set_brightness(struct led_classdev *led_cdev, +static inline void led_set_brightness_async(struct led_classdev *led_cdev, enum led_brightness value) { - if (value > led_cdev->max_brightness) - value = led_cdev->max_brightness; - led_cdev->brightness = value; + led_cdev->brightness = min(value, led_cdev->max_brightness); + if (!(led_cdev->flags & LED_SUSPENDED)) led_cdev->brightness_set(led_cdev, value); } +static inline int led_set_brightness_sync(struct led_classdev *led_cdev, + enum led_brightness value) +{ + int ret = 0; + + led_cdev->brightness = min(value, led_cdev->max_brightness); + + if (!(led_cdev->flags & LED_SUSPENDED)) + ret = led_cdev->brightness_set_sync(led_cdev, + led_cdev->brightness); + return ret; +} + static inline int led_get_brightness(struct led_classdev *led_cdev) { return led_cdev->brightness; diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c index 47e55aa9eefa..59eca17d9661 100644 --- a/drivers/leds/trigger/ledtrig-backlight.c +++ b/drivers/leds/trigger/ledtrig-backlight.c @@ -51,9 +51,9 @@ static int fb_notifier_callback(struct notifier_block *p, if ((n->old_status == UNBLANK) ^ n->invert) { n->brightness = led->brightness; - __led_set_brightness(led, LED_OFF); + led_set_brightness_async(led, LED_OFF); } else { - __led_set_brightness(led, n->brightness); + led_set_brightness_async(led, n->brightness); } n->old_status = new_status; @@ -89,9 +89,9 @@ static ssize_t bl_trig_invert_store(struct device *dev, /* After inverting, we need to update the LED. */ if ((n->old_status == BLANK) ^ n->invert) - __led_set_brightness(led, LED_OFF); + led_set_brightness_async(led, LED_OFF); else - __led_set_brightness(led, n->brightness); + led_set_brightness_async(led, n->brightness); return num; } diff --git a/drivers/leds/trigger/ledtrig-default-on.c b/drivers/leds/trigger/ledtrig-default-on.c index 81a91be8e18d..6f38f883aaf1 100644 --- a/drivers/leds/trigger/ledtrig-default-on.c +++ b/drivers/leds/trigger/ledtrig-default-on.c @@ -19,7 +19,7 @@ static void defon_trig_activate(struct led_classdev *led_cdev) { - __led_set_brightness(led_cdev, led_cdev->max_brightness); + led_set_brightness_async(led_cdev, led_cdev->max_brightness); } static struct led_trigger defon_led_trigger = { diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index c86c41826476..4cc7040746c6 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c @@ -54,12 +54,12 @@ static void gpio_trig_work(struct work_struct *work) if (tmp) { if (gpio_data->desired_brightness) - __led_set_brightness(gpio_data->led, + led_set_brightness_async(gpio_data->led, gpio_data->desired_brightness); else - __led_set_brightness(gpio_data->led, LED_FULL); + led_set_brightness_async(gpio_data->led, LED_FULL); } else { - __led_set_brightness(gpio_data->led, LED_OFF); + led_set_brightness_async(gpio_data->led, LED_OFF); } } diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c index 5c8464a33172..fea6871d2609 100644 --- a/drivers/leds/trigger/ledtrig-heartbeat.c +++ b/drivers/leds/trigger/ledtrig-heartbeat.c @@ -74,7 +74,7 @@ static void led_heartbeat_function(unsigned long data) break; } - __led_set_brightness(led_cdev, brightness); + led_set_brightness_async(led_cdev, brightness); mod_timer(&heartbeat_data->timer, jiffies + delay); } diff --git a/drivers/leds/trigger/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c index cb4c7466692a..fbd02cdc3ad7 100644 --- a/drivers/leds/trigger/ledtrig-oneshot.c +++ b/drivers/leds/trigger/ledtrig-oneshot.c @@ -63,9 +63,9 @@ static ssize_t led_invert_store(struct device *dev, oneshot_data->invert = !!state; if (oneshot_data->invert) - __led_set_brightness(led_cdev, LED_FULL); + led_set_brightness_async(led_cdev, LED_FULL); else - __led_set_brightness(led_cdev, LED_OFF); + led_set_brightness_async(led_cdev, LED_OFF); return size; } diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c index e5abc00bb00c..3c34de404d18 100644 --- a/drivers/leds/trigger/ledtrig-transient.c +++ b/drivers/leds/trigger/ledtrig-transient.c @@ -41,7 +41,7 @@ static void transient_timer_function(unsigned long data) struct transient_trig_data *transient_data = led_cdev->trigger_data; transient_data->activate = 0; - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, transient_data->restore_state); } static ssize_t transient_activate_show(struct device *dev, @@ -72,7 +72,8 @@ static ssize_t transient_activate_store(struct device *dev, if (state == 0 && transient_data->activate == 1) { del_timer(&transient_data->timer); transient_data->activate = state; - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, + transient_data->restore_state); return size; } @@ -80,7 +81,7 @@ static ssize_t transient_activate_store(struct device *dev, if (state == 1 && transient_data->activate == 0 && transient_data->duration != 0) { transient_data->activate = state; - __led_set_brightness(led_cdev, transient_data->state); + led_set_brightness_async(led_cdev, transient_data->state); transient_data->restore_state = (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL; mod_timer(&transient_data->timer, @@ -203,7 +204,8 @@ static void transient_trig_deactivate(struct led_classdev *led_cdev) if (led_cdev->activated) { del_timer_sync(&transient_data->timer); - __led_set_brightness(led_cdev, transient_data->restore_state); + led_set_brightness_async(led_cdev, + transient_data->restore_state); device_remove_file(led_cdev->dev, &dev_attr_activate); device_remove_file(led_cdev->dev, &dev_attr_duration); device_remove_file(led_cdev->dev, &dev_attr_state); diff --git a/include/linux/leds.h b/include/linux/leds.h index 737f9b1051f2..dfe70e928eae 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -44,11 +44,19 @@ struct led_classdev { #define LED_BLINK_ONESHOT_STOP (1 << 18) #define LED_BLINK_INVERT (1 << 19) #define LED_SYSFS_DISABLE (1 << 20) +#define SET_BRIGHTNESS_ASYNC (1 << 21) +#define SET_BRIGHTNESS_SYNC (1 << 22) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ void (*brightness_set)(struct led_classdev *led_cdev, enum led_brightness brightness); + /* + * Set LED brightness level immediately - it can block the caller for + * the time required for accessing a LED device register. + */ + int (*brightness_set_sync)(struct led_classdev *led_cdev, + enum led_brightness brightness); /* Get LED brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); -- GitLab From cdb83947ab78dac2477b3d27416fbd1cc480cead Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Fri, 14 Nov 2014 23:33:08 +0100 Subject: [PATCH 4886/9457] HSI: nokia-modem: setup default value for pm parameter The module documents, that 1 is the default, but it actually isn't. This updates the module to use pm=1 as default. Signed-off-by: Sebastian Reichel --- drivers/hsi/clients/nokia-modem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c index e43c3c9acec1..67b8e8f53a09 100644 --- a/drivers/hsi/clients/nokia-modem.c +++ b/drivers/hsi/clients/nokia-modem.c @@ -29,7 +29,7 @@ #include #include -static unsigned int pm; +static unsigned int pm = 1; module_param(pm, int, 0400); MODULE_PARM_DESC(pm, "Enable power management (0=disabled, 1=userland based [default])"); -- GitLab From d95dc9e388104488d0f5a5969c435e601840da2e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 14 Nov 2014 14:06:37 -0800 Subject: [PATCH 4887/9457] HSI: nokia-modem: fix error handling of irq_of_parse_and_map Return value of irq_of_parse_and_map() is unsigned int, with 0 indicating failure, so testing for negative result never works. Signed-off-by: Dmitry Torokhov Signed-off-by: Sebastian Reichel --- drivers/hsi/clients/nokia-modem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c index 67b8e8f53a09..f0c21458962c 100644 --- a/drivers/hsi/clients/nokia-modem.c +++ b/drivers/hsi/clients/nokia-modem.c @@ -164,9 +164,9 @@ static int nokia_modem_probe(struct device *dev) dev_set_drvdata(dev, modem); irq = irq_of_parse_and_map(np, 0); - if (irq < 0) { + if (!irq) { dev_err(dev, "Invalid rst_ind interrupt (%d)\n", irq); - return irq; + return -EINVAL; } modem->nokia_modem_rst_ind_irq = irq; pflags = irq_get_trigger_type(irq); -- GitLab From 8bd4ae202813ac04f35dacf43263e1cf96743292 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 14 Nov 2014 19:30:29 +0100 Subject: [PATCH 4888/9457] drm: rework flip-work helpers to avoid calling func when the FIFO is full Make use of lists instead of kfifo in order to dynamically allocate task entry when someone require some delayed work, and thus preventing drm_flip_work_queue from directly calling func instead of queuing this call. This allow drm_flip_work_queue to be safely called even within irq handlers. Add new helper functions to allocate a flip work task and queue it when needed. This prevents allocating data within irq context (which might impact the time spent in the irq handler). Signed-off-by: Boris BREZILLON Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_flip_work.c | 97 +++++++++++++++++++++++++-------- include/drm/drm_flip_work.h | 31 ++++++++--- 2 files changed, 96 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/drm_flip_work.c b/drivers/gpu/drm/drm_flip_work.c index f9c7fa3d0012..6f4ae5b655d3 100644 --- a/drivers/gpu/drm/drm_flip_work.c +++ b/drivers/gpu/drm/drm_flip_work.c @@ -24,6 +24,44 @@ #include "drmP.h" #include "drm_flip_work.h" +/** + * drm_flip_work_allocate_task - allocate a flip-work task + * @data: data associated to the task + * @flags: allocator flags + * + * Allocate a drm_flip_task object and attach private data to it. + */ +struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags) +{ + struct drm_flip_task *task; + + task = kzalloc(sizeof(*task), flags); + if (task) + task->data = data; + + return task; +} +EXPORT_SYMBOL(drm_flip_work_allocate_task); + +/** + * drm_flip_work_queue_task - queue a specific task + * @work: the flip-work + * @task: the task to handle + * + * Queues task, that will later be run (passed back to drm_flip_func_t + * func) on a work queue after drm_flip_work_commit() is called. + */ +void drm_flip_work_queue_task(struct drm_flip_work *work, + struct drm_flip_task *task) +{ + unsigned long flags; + + spin_lock_irqsave(&work->lock, flags); + list_add_tail(&task->node, &work->queued); + spin_unlock_irqrestore(&work->lock, flags); +} +EXPORT_SYMBOL(drm_flip_work_queue_task); + /** * drm_flip_work_queue - queue work * @work: the flip-work @@ -34,10 +72,14 @@ */ void drm_flip_work_queue(struct drm_flip_work *work, void *val) { - if (kfifo_put(&work->fifo, val)) { - atomic_inc(&work->pending); + struct drm_flip_task *task; + + task = drm_flip_work_allocate_task(val, + drm_can_sleep() ? GFP_KERNEL : GFP_ATOMIC); + if (task) { + drm_flip_work_queue_task(work, task); } else { - DRM_ERROR("%s fifo full!\n", work->name); + DRM_ERROR("%s could not allocate task!\n", work->name); work->func(work, val); } } @@ -56,9 +98,12 @@ EXPORT_SYMBOL(drm_flip_work_queue); void drm_flip_work_commit(struct drm_flip_work *work, struct workqueue_struct *wq) { - uint32_t pending = atomic_read(&work->pending); - atomic_add(pending, &work->count); - atomic_sub(pending, &work->pending); + unsigned long flags; + + spin_lock_irqsave(&work->lock, flags); + list_splice_tail(&work->queued, &work->commited); + INIT_LIST_HEAD(&work->queued); + spin_unlock_irqrestore(&work->lock, flags); queue_work(wq, &work->worker); } EXPORT_SYMBOL(drm_flip_work_commit); @@ -66,14 +111,26 @@ EXPORT_SYMBOL(drm_flip_work_commit); static void flip_worker(struct work_struct *w) { struct drm_flip_work *work = container_of(w, struct drm_flip_work, worker); - uint32_t count = atomic_read(&work->count); - void *val = NULL; + struct list_head tasks; + unsigned long flags; - atomic_sub(count, &work->count); + while (1) { + struct drm_flip_task *task, *tmp; - while(count--) - if (!WARN_ON(!kfifo_get(&work->fifo, &val))) - work->func(work, val); + INIT_LIST_HEAD(&tasks); + spin_lock_irqsave(&work->lock, flags); + list_splice_tail(&work->commited, &tasks); + INIT_LIST_HEAD(&work->commited); + spin_unlock_irqrestore(&work->lock, flags); + + if (list_empty(&tasks)) + break; + + list_for_each_entry_safe(task, tmp, &tasks, node) { + work->func(work, task->data); + kfree(task); + } + } } /** @@ -91,19 +148,12 @@ static void flip_worker(struct work_struct *w) int drm_flip_work_init(struct drm_flip_work *work, int size, const char *name, drm_flip_func_t func) { - int ret; - work->name = name; - atomic_set(&work->count, 0); - atomic_set(&work->pending, 0); + INIT_LIST_HEAD(&work->queued); + INIT_LIST_HEAD(&work->commited); + spin_lock_init(&work->lock); work->func = func; - ret = kfifo_alloc(&work->fifo, size, GFP_KERNEL); - if (ret) { - DRM_ERROR("could not allocate %s fifo\n", name); - return ret; - } - INIT_WORK(&work->worker, flip_worker); return 0; @@ -118,7 +168,6 @@ EXPORT_SYMBOL(drm_flip_work_init); */ void drm_flip_work_cleanup(struct drm_flip_work *work) { - WARN_ON(!kfifo_is_empty(&work->fifo)); - kfifo_free(&work->fifo); + WARN_ON(!list_empty(&work->queued) || !list_empty(&work->commited)); } EXPORT_SYMBOL(drm_flip_work_cleanup); diff --git a/include/drm/drm_flip_work.h b/include/drm/drm_flip_work.h index 9eed34dcd6af..3fcb4c44c9e0 100644 --- a/include/drm/drm_flip_work.h +++ b/include/drm/drm_flip_work.h @@ -25,6 +25,7 @@ #define DRM_FLIP_WORK_H #include +#include #include /** @@ -32,9 +33,9 @@ * * Util to queue up work to run from work-queue context after flip/vblank. * Typically this can be used to defer unref of framebuffer's, cursor - * bo's, etc until after vblank. The APIs are all safe (and lockless) - * for up to one producer and once consumer at a time. The single-consumer - * aspect is ensured by committing the queued work to a single work-queue. + * bo's, etc until after vblank. The APIs are all thread-safe. + * Moreover, drm_flip_work_queue_task and drm_flip_work_queue can be called + * in atomic context. */ struct drm_flip_work; @@ -50,23 +51,37 @@ struct drm_flip_work; */ typedef void (*drm_flip_func_t)(struct drm_flip_work *work, void *val); +/** + * struct drm_flip_task - flip work task + * @node: list entry element + * @data: data to pass to work->func + */ +struct drm_flip_task { + struct list_head node; + void *data; +}; + /** * struct drm_flip_work - flip work queue * @name: debug name - * @pending: number of queued but not committed items - * @count: number of committed items * @func: callback fxn called for each committed item * @worker: worker which calls @func - * @fifo: queue of committed items + * @queued: queued tasks + * @commited: commited tasks + * @lock: lock to access queued and commited lists */ struct drm_flip_work { const char *name; - atomic_t pending, count; drm_flip_func_t func; struct work_struct worker; - DECLARE_KFIFO_PTR(fifo, void *); + struct list_head queued; + struct list_head commited; + spinlock_t lock; }; +struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags); +void drm_flip_work_queue_task(struct drm_flip_work *work, + struct drm_flip_task *task); void drm_flip_work_queue(struct drm_flip_work *work, void *val); void drm_flip_work_commit(struct drm_flip_work *work, struct workqueue_struct *wq); -- GitLab From d7f8db5300d1f50b5631796086dbd4efc5b5d707 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 14 Nov 2014 19:30:30 +0100 Subject: [PATCH 4889/9457] drm: flip-work: change drm_flip_work_init prototype Now that we're using lists instead of kfifo to store drm flip-work tasks we do not need the size parameter passed to drm_flip_work_init function anymore. Moreover this function cannot fail anymore, we can thus remove the return code. Modify drm_flip_work_init users to take account of these changes. [airlied: fixed two unused variable warnings] Signed-off-by: Boris BREZILLON Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_flip_work.c | 8 +------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 20 ++++---------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 17 +++-------------- drivers/gpu/drm/omapdrm/omap_plane.c | 14 ++------------ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 6 +----- include/drm/drm_flip_work.h | 2 +- 6 files changed, 12 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/drm_flip_work.c b/drivers/gpu/drm/drm_flip_work.c index 6f4ae5b655d3..43d9b950ef9f 100644 --- a/drivers/gpu/drm/drm_flip_work.c +++ b/drivers/gpu/drm/drm_flip_work.c @@ -136,16 +136,12 @@ static void flip_worker(struct work_struct *w) /** * drm_flip_work_init - initialize flip-work * @work: the flip-work to initialize - * @size: the max queue depth * @name: debug name * @func: the callback work function * * Initializes/allocates resources for the flip-work - * - * RETURNS: - * Zero on success, error code on failure. */ -int drm_flip_work_init(struct drm_flip_work *work, int size, +void drm_flip_work_init(struct drm_flip_work *work, const char *name, drm_flip_func_t func) { work->name = name; @@ -155,8 +151,6 @@ int drm_flip_work_init(struct drm_flip_work *work, int size, work->func = func; INIT_WORK(&work->worker, flip_worker); - - return 0; } EXPORT_SYMBOL(drm_flip_work_init); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 7d00f7fb5773..1ca87ae53d35 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -757,13 +757,10 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, { struct drm_crtc *crtc = NULL; struct mdp4_crtc *mdp4_crtc; - int ret; mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL); - if (!mdp4_crtc) { - ret = -ENOMEM; - goto fail; - } + if (!mdp4_crtc) + return ERR_PTR(-ENOMEM); crtc = &mdp4_crtc->base; @@ -784,12 +781,9 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, spin_lock_init(&mdp4_crtc->cursor.lock); - ret = drm_flip_work_init(&mdp4_crtc->unref_fb_work, 16, + drm_flip_work_init(&mdp4_crtc->unref_fb_work, "unref fb", unref_fb_worker); - if (ret) - goto fail; - - ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64, + drm_flip_work_init(&mdp4_crtc->unref_cursor_work, "unref cursor", unref_cursor_worker); INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb); @@ -800,10 +794,4 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base); return crtc; - -fail: - if (crtc) - mdp4_crtc_destroy(crtc); - - return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index ebe2e60f3ab1..2979a2cc82a4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -534,13 +534,10 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, { struct drm_crtc *crtc = NULL; struct mdp5_crtc *mdp5_crtc; - int ret; mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL); - if (!mdp5_crtc) { - ret = -ENOMEM; - goto fail; - } + if (!mdp5_crtc) + return ERR_PTR(-ENOMEM); crtc = &mdp5_crtc->base; @@ -553,10 +550,8 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, snprintf(mdp5_crtc->name, sizeof(mdp5_crtc->name), "%s:%d", pipe2name(mdp5_plane_pipe(plane)), id); - ret = drm_flip_work_init(&mdp5_crtc->unref_fb_work, 16, + drm_flip_work_init(&mdp5_crtc->unref_fb_work, "unref fb", unref_fb_worker); - if (ret) - goto fail; INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); @@ -566,10 +561,4 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base); return crtc; - -fail: - if (crtc) - mdp5_crtc_destroy(crtc); - - return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 891a4dc608af..0ad740132ac3 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -394,14 +394,10 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); if (!omap_plane) - goto fail; + return NULL; - ret = drm_flip_work_init(&omap_plane->unpin_work, 16, + drm_flip_work_init(&omap_plane->unpin_work, "unpin", unpin_worker); - if (ret) { - dev_err(dev->dev, "could not allocate unpin FIFO\n"); - goto fail; - } omap_plane->nformats = omap_framebuffer_get_formats( omap_plane->formats, ARRAY_SIZE(omap_plane->formats), @@ -443,10 +439,4 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, omap_plane->info.zorder = id; return plane; - -fail: - if (plane) - omap_plane_destroy(plane); - - return NULL; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 29ec98baffd1..c73588483be0 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -665,12 +665,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; init_waitqueue_head(&tilcdc_crtc->frame_done_wq); - ret = drm_flip_work_init(&tilcdc_crtc->unref_work, 16, + drm_flip_work_init(&tilcdc_crtc->unref_work, "unref", unref_worker); - if (ret) { - dev_err(dev->dev, "could not allocate unref FIFO\n"); - goto fail; - } ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); if (ret < 0) diff --git a/include/drm/drm_flip_work.h b/include/drm/drm_flip_work.h index 3fcb4c44c9e0..d387cf06ae05 100644 --- a/include/drm/drm_flip_work.h +++ b/include/drm/drm_flip_work.h @@ -85,7 +85,7 @@ void drm_flip_work_queue_task(struct drm_flip_work *work, void drm_flip_work_queue(struct drm_flip_work *work, void *val); void drm_flip_work_commit(struct drm_flip_work *work, struct workqueue_struct *wq); -int drm_flip_work_init(struct drm_flip_work *work, int size, +void drm_flip_work_init(struct drm_flip_work *work, const char *name, drm_flip_func_t func); void drm_flip_work_cleanup(struct drm_flip_work *work); -- GitLab From db88362884b6c78f920c5ad03860295b9a224433 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 14 Nov 2014 17:12:59 -0500 Subject: [PATCH 4890/9457] drm/atomic: rip out unnecessary locking checks For async commit, it is *intentional* that those locks are not held. Reviewed-by: Daniel Vetter Signed-off-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic_helper.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c0a07cba3aaa..fad2b932cf72 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1006,8 +1006,6 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (!crtc) continue; - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - funcs = crtc->helper_private; if (!funcs || !funcs->atomic_begin) @@ -1023,8 +1021,6 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (!plane) continue; - WARN_ON(!drm_modeset_is_locked(&plane->mutex)); - funcs = plane->helper_private; if (!funcs || !funcs->atomic_update) -- GitLab From b853fdb3c0e7122193ea548aba42d1d63b6d4783 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 12 Nov 2014 10:13:37 +0000 Subject: [PATCH 4891/9457] drm/dp/mst: Handle invalid link bandwidth from DPCD gracefully Don't BUG out if the link reports an invalid (or plain unknown) bandwidth value, but report the failure and fail gracefully. Fixes a trivial compiler warning in case the BUG is ever compiled away. Link: http://lkml.kernel.org/p/1415785566-12758-1-git-send-email-geert@linux-m68k.org Signed-off-by: Chris Wilson Cc: Dave Airlie Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index dc98b8f78168..5682d7e9f1ec 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1799,17 +1799,27 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, return 0; } -static int drm_dp_get_vc_payload_bw(int dp_link_bw, int dp_link_count) +static bool drm_dp_get_vc_payload_bw(int dp_link_bw, + int dp_link_count, + int *out) { switch (dp_link_bw) { + default: + DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n", + dp_link_bw, dp_link_count); + return false; + case DP_LINK_BW_1_62: - return 3 * dp_link_count; + *out = 3 * dp_link_count; + break; case DP_LINK_BW_2_7: - return 5 * dp_link_count; + *out = 5 * dp_link_count; + break; case DP_LINK_BW_5_4: - return 10 * dp_link_count; + *out = 10 * dp_link_count; + break; } - BUG(); + return true; } /** @@ -1841,7 +1851,13 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms goto out_unlock; } - mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1], mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK); + if (!drm_dp_get_vc_payload_bw(mgr->dpcd[1], + mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, + &mgr->pbn_div)) { + ret = -EINVAL; + goto out_unlock; + } + mgr->total_pbn = 2560; mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div); mgr->avail_slots = mgr->total_slots; -- GitLab From 977d2fa6b2ace7e22302a55cdc5ee6110907a9d8 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 13 Nov 2014 14:28:20 -0800 Subject: [PATCH 4892/9457] PM / Runtime: Kconfig: move ia64 dependency to arch/ia64/Kconfig The IA64_HP_SIM dependency on PM_RUNTIME should be done in the arch Kconfig instead of in the PM core. Move it accordingly. NOTE: arch/ia64/Kconfig currently does a 'select PM', which since commit 1eb208aea317 (PM: Make CONFIG_PM depend on (CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME)) is effectively a noop unless PM_SLEEP or PM_RUNTIME are set elsewhere. Signed-off-by: Kevin Hilman Reviewed-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- arch/ia64/Kconfig | 1 + kernel/power/Kconfig | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index c84c88bbbbd7..55bc92ca2ce6 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -233,6 +233,7 @@ config IA64_SGI_UV config IA64_HP_SIM bool "Ski-simulator" select SWIOTLB + depends on !PM_RUNTIME endchoice diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index bbef57f5bdfd..3d39cc0228e9 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -131,7 +131,6 @@ config PM_WAKELOCKS_GC config PM_RUNTIME bool "Run-time PM core functionality" - depends on !IA64_HP_SIM ---help--- Enable functionality allowing I/O devices to be put into energy-saving (low power) states at run time (or autosuspended) after a specified -- GitLab From baf698b0496e93f2737b9046d3b1892c55133b0d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 12 Nov 2014 11:59:47 +0100 Subject: [PATCH 4893/9457] drm: Simplify return value handling in drm_crtc.c While looking through drm_crtc.c to double-check make locking changes I've noticed that there's a few other places that would now benefit from simplified return value handling. So let's flatten the control flow and replace and always 0 ret with 0 where possible. Signed-off-by: Daniel Vetter Reviewed-by: Sean Paul Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e8fc946ed59c..5a4be0398650 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -683,7 +683,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, drm_modeset_lock_init(&crtc->mutex); ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); if (ret) - goto out; + return ret; crtc->base.properties = &crtc->properties; @@ -697,9 +697,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, if (cursor) cursor->possible_crtcs = 1 << drm_crtc_index(crtc); - out: - - return ret; + return 0; } EXPORT_SYMBOL(drm_crtc_init_with_planes); @@ -1154,7 +1152,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) - goto out; + return ret; drm_modeset_lock_init(&plane->mutex); @@ -1166,8 +1164,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, if (!plane->format_types) { DRM_DEBUG_KMS("out of memory when allocating plane\n"); drm_mode_object_put(dev, &plane->base); - ret = -ENOMEM; - goto out; + return -ENOMEM; } memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); @@ -1184,9 +1181,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, dev->mode_config.plane_type_property, plane->type); - out: - - return ret; + return 0; } EXPORT_SYMBOL(drm_universal_plane_init); @@ -1888,7 +1883,6 @@ int drm_mode_getcrtc(struct drm_device *dev, { struct drm_mode_crtc *crtc_resp = data; struct drm_crtc *crtc; - int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -1916,7 +1910,7 @@ int drm_mode_getcrtc(struct drm_device *dev, } drm_modeset_unlock_crtc(crtc); - return ret; + return 0; } static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, @@ -2094,7 +2088,6 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, { struct drm_mode_get_encoder *enc_resp = data; struct drm_encoder *encoder; - int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -2115,7 +2108,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, enc_resp->possible_crtcs = encoder->possible_crtcs; enc_resp->possible_clones = encoder->possible_clones; - return ret; + return 0; } /** @@ -2198,7 +2191,6 @@ int drm_mode_getplane(struct drm_device *dev, void *data, struct drm_mode_get_plane *plane_resp = data; struct drm_plane *plane; uint32_t __user *format_ptr; - int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -2238,7 +2230,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, } plane_resp->count_format_types = plane->format_count; - return ret; + return 0; } /* @@ -2958,7 +2950,7 @@ int drm_mode_addfb(struct drm_device *dev, or->fb_id = r.fb_id; - return ret; + return 0; } static int format_check(const struct drm_mode_fb_cmd2 *r) -- GitLab From 5bb2bbf596a0ca35b8ba2b0d5b734a1f270040ff Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Nov 2014 10:18:15 +1000 Subject: [PATCH 4894/9457] drm: add properties for suggested x/y offset for connectors. (v2) Virtual GPUs would like to give the guest some indication where on the screen the outputs are layed out. So far we only provide modes, these properties could be exposed to userspace so the desktop environment could use them as hints to set the correct offsets. v2: rename properties to be more consistent. Signed-off-by: Dave Airlie --- Documentation/DocBook/drm.tmpl | 17 ++++++++++++++++- drivers/gpu/drm/drm_crtc.c | 24 ++++++++++++++++++++++++ include/drm/drm_crtc.h | 5 +++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d2fc43913d54..b8bfa8d1f289 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2539,7 +2539,7 @@ void intel_crt_init(struct drm_device *dev) Description/Restrictions - DRM + DRM Generic “EDID” BLOB | IMMUTABLE @@ -2677,6 +2677,21 @@ void intel_crt_init(struct drm_device *dev) TBD + Virtual GPU + “suggested X” + RANGE + Min=0, Max=0xffffffff + Connector + property to suggest an X offset for a connector + + + “suggested Y” + RANGE + Min=0, Max=0xffffffff + Connector + property to suggest an Y offset for a connector + + Optional “scaling mode” ENUM diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5a4be0398650..15f8b3bfd1ee 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1529,6 +1529,30 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev) } EXPORT_SYMBOL(drm_mode_create_dirty_info_property); +/** + * drm_mode_create_suggested_offset_properties - create suggests offset properties + * @dev: DRM device + * + * Create the the suggested x/y offset property for connectors. + */ +int drm_mode_create_suggested_offset_properties(struct drm_device *dev) +{ + if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property) + return 0; + + dev->mode_config.suggested_x_property = + drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff); + + dev->mode_config.suggested_y_property = + drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff); + + if (dev->mode_config.suggested_x_property == NULL || + dev->mode_config.suggested_y_property == NULL) + return -ENOMEM; + return 0; +} +EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties); + static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) { uint32_t total_objects = 0; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c95941076aaf..7b28ab032a88 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1038,6 +1038,10 @@ struct drm_mode_config { struct drm_property *aspect_ratio_property; struct drm_property *dirty_info_property; + /* properties for virtual machine layout */ + struct drm_property *suggested_x_property; + struct drm_property *suggested_y_property; + /* dumb ioctl parameters */ uint32_t preferred_depth, prefer_shadow; @@ -1231,6 +1235,7 @@ extern int drm_mode_create_tv_properties(struct drm_device *dev, extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev); extern int drm_mode_create_dirty_info_property(struct drm_device *dev); +extern int drm_mode_create_suggested_offset_properties(struct drm_device *dev); extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); -- GitLab From 7dea0941f8806e79fed562256822564d5f903edc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 28 Oct 2014 11:28:44 +1000 Subject: [PATCH 4895/9457] drm/qxl: use suggested x/y offset properties to pass guest prefs This passes the guest preferences for a where to place the outputs through to userspace. Userspace would need to be updated to take note of this information, X server and GNOME. Signed-off-by: Dave Airlie --- drivers/gpu/drm/qxl/qxl_display.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 8b7892880ad2..b8cf556b431c 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -101,14 +101,37 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev) return 0; } +static void qxl_update_offset_props(struct qxl_device *qdev) +{ + struct drm_device *dev = qdev->ddev; + struct drm_connector *connector; + struct qxl_output *output; + struct qxl_head *head; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + output = drm_connector_to_qxl_output(connector); + + head = &qdev->client_monitors_config->heads[output->index]; + + drm_object_property_set_value(&connector->base, + dev->mode_config.suggested_x_property, head->x); + drm_object_property_set_value(&connector->base, + dev->mode_config.suggested_y_property, head->y); + } +} + void qxl_display_read_client_monitors_config(struct qxl_device *qdev) { + struct drm_device *dev = qdev->ddev; while (qxl_display_copy_rom_client_monitors_config(qdev)) { qxl_io_log(qdev, "failed crc check for client_monitors_config," " retrying\n"); } + drm_modeset_lock_all(dev); + qxl_update_offset_props(qdev); + drm_modeset_unlock_all(dev); if (!drm_helper_hpd_irq_event(qdev->ddev)) { /* notify that the monitor configuration changed, to adjust at the arbitrary resolution */ @@ -952,6 +975,10 @@ static int qdev_output_init(struct drm_device *dev, int num_output) drm_object_attach_property(&connector->base, qdev->hotplug_mode_update_property, 0); + drm_object_attach_property(&connector->base, + dev->mode_config.suggested_x_property, 0); + drm_object_attach_property(&connector->base, + dev->mode_config.suggested_y_property, 0); drm_connector_register(connector); return 0; } @@ -1065,6 +1092,7 @@ int qxl_modeset_init(struct qxl_device *qdev) qdev->ddev->mode_config.fb_base = qdev->vram_base; + drm_mode_create_suggested_offset_properties(qdev->ddev); qxl_mode_create_hotplug_mode_update_property(qdev); for (i = 0 ; i < qxl_num_crtc; ++i) { -- GitLab From 967b8e04d7993e93a44ffb63cc6504b6eded899a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 15 Nov 2014 10:15:30 +1000 Subject: [PATCH 4896/9457] drm/qxl: drop unused mode private pointer This was pointless, forgot to remove the code. Signed-off-by: Dave Airlie --- drivers/gpu/drm/qxl/qxl_display.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index b8cf556b431c..4a0a8b29b0a1 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -592,7 +592,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct qxl_device *qdev = dev->dev_private; - struct qxl_mode *m = (void *)mode->private; struct qxl_framebuffer *qfb; struct qxl_bo *bo, *old_bo = NULL; struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); @@ -610,12 +609,6 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, } qfb = to_qxl_framebuffer(crtc->primary->fb); bo = gem_to_qxl_bo(qfb->obj); - if (!m) - /* and do we care? */ - DRM_DEBUG("%dx%d: not a native mode\n", x, y); - else - DRM_DEBUG("%dx%d: qxl id %d\n", - mode->hdisplay, mode->vdisplay, m->id); DRM_DEBUG("+%d+%d (%d,%d) => (%d,%d)\n", x, y, mode->hdisplay, mode->vdisplay, -- GitLab From a809eff11f81e2dcf1e792586ef70693c60d7dc8 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 14 Nov 2014 19:35:05 +0100 Subject: [PATCH 4897/9457] Bluetooth: hidp: replace kzalloc/copy_from_user by memdup_user use memdup_user for rd_data import. Signed-off-by: Fabian Frederick Signed-off-by: Marcel Holtmann --- net/bluetooth/hidp/core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 1b7d605706aa..cc25d0b74b36 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -736,14 +736,10 @@ static int hidp_setup_hid(struct hidp_session *session, struct hid_device *hid; int err; - session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); - if (!session->rd_data) - return -ENOMEM; + session->rd_data = memdup_user(req->rd_data, req->rd_size); + if (IS_ERR(session->rd_data)) + return PTR_ERR(session->rd_data); - if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) { - err = -EFAULT; - goto fault; - } session->rd_size = req->rd_size; hid = hid_allocate_device(); -- GitLab From fa37c1aa30e538329b64dd55f401334f4bff47f5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 10:55:17 +0200 Subject: [PATCH 4898/9457] Bluetooth: Fix sending incorrect LE CoC PDU in BT_CONNECT2 state For LE CoC L2CAP servers we don't do security level elevation during the BT_CONNECT2 state (instead LE CoC simply sends an immediate error response if the security level isn't high enough). Therefore if we get a security level change while an LE CoC channel is in the BT_CONNECT2 state we should simply do nothing. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 52e1871d6334..76045497eaa1 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7332,7 +7332,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) l2cap_start_connection(chan); else __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); - } else if (chan->state == BT_CONNECT2) { + } else if (chan->state == BT_CONNECT2 && + chan->mode != L2CAP_MODE_LE_FLOWCTL) { struct l2cap_conn_rsp rsp; __u16 res, stat; -- GitLab From 35dc6f834c9dc888391c7b700130d0831a907ca1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 10:55:18 +0200 Subject: [PATCH 4899/9457] Bluetooth: Add key preference parameter to smp_sufficient_security So far smp_sufficient_security() has returned false if we're encrypted with an STK but do have an LTK available. However, for the sake of LE CoC servers we do want to let the incoming connection through even though we're only encrypted with the STK. This patch adds a key preference parameter to smp_sufficient_security() with two possible values (enum used instead of bool for readability). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 ++- net/bluetooth/smp.c | 20 +++++++++++--------- net/bluetooth/smp.h | 9 ++++++++- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 76045497eaa1..a37f809591ad 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5391,7 +5391,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, mutex_lock(&conn->chan_lock); l2cap_chan_lock(pchan); - if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) { + if (!smp_sufficient_security(conn->hcon, pchan->sec_level, + SMP_ALLOW_STK)) { result = L2CAP_CR_AUTHENTICATION; chan = NULL; goto response_unlock; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3b63c7f09dd5..3dc5f0e66405 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1122,18 +1122,20 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) return true; } -bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level) +bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, + enum smp_key_pref key_pref) { if (sec_level == BT_SECURITY_LOW) return true; - /* If we're encrypted with an STK always claim insufficient - * security. This way we allow the connection to be re-encrypted - * with an LTK, even if the LTK provides the same level of - * security. Only exception is if we don't have an LTK (e.g. - * because of key distribution bits). + /* If we're encrypted with an STK but the caller prefers using + * LTK claim insufficient security. This way we allow the + * connection to be re-encrypted with an LTK, even if the LTK + * provides the same level of security. Only exception is if we + * don't have an LTK (e.g. because of key distribution bits). */ - if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && + if (key_pref == SMP_USE_LTK && + test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) return false; @@ -1167,7 +1169,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) else sec_level = authreq_to_seclevel(auth); - if (smp_sufficient_security(hcon, sec_level)) + if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) return 0; if (sec_level > hcon->pending_sec_level) @@ -1217,7 +1219,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) return 1; - if (smp_sufficient_security(hcon, sec_level)) + if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) return 1; if (sec_level > hcon->pending_sec_level) diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 86a683a8b491..f76083b85005 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -133,8 +133,15 @@ static inline u8 smp_ltk_sec_level(struct smp_ltk *key) return BT_SECURITY_MEDIUM; } +/* Key preferences for smp_sufficient security */ +enum smp_key_pref { + SMP_ALLOW_STK, + SMP_USE_LTK, +}; + /* SMP Commands */ -bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); +bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, + enum smp_key_pref key_pref); int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); -- GitLab From 3e64b7bd8234b459134b3059919828122e2fd79f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 10:55:19 +0200 Subject: [PATCH 4900/9457] Bluetooth: Trigger SMP for the appropriate LE CoC errors The insufficient authentication/encryption errors indicate to the L2CAP client that it should try to elevate the security level. Since there really isn't any exception to this rule it makes sense to fully handle it on the kernel side instead of pushing the responsibility to user space. This patch adds special handling of these two error codes and calls smp_conn_security() with the elevated security level if necessary. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a37f809591ad..15784d32108d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5218,9 +5218,10 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, u8 *data) { struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data; + struct hci_conn *hcon = conn->hcon; u16 dcid, mtu, mps, credits, result; struct l2cap_chan *chan; - int err; + int err, sec_level; if (cmd_len < sizeof(*rsp)) return -EPROTO; @@ -5259,6 +5260,26 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, l2cap_chan_ready(chan); break; + case L2CAP_CR_AUTHENTICATION: + case L2CAP_CR_ENCRYPTION: + /* If we already have MITM protection we can't do + * anything. + */ + if (hcon->sec_level > BT_SECURITY_MEDIUM) { + l2cap_chan_del(chan, ECONNREFUSED); + break; + } + + sec_level = hcon->sec_level + 1; + if (chan->sec_level < sec_level) + chan->sec_level = sec_level; + + /* We'll need to send a new Connect Request */ + clear_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags); + + smp_conn_security(hcon, chan->sec_level); + break; + default: l2cap_chan_del(chan, ECONNREFUSED); break; -- GitLab From 1b6f47537c86494bb525c31e695ae3a1dfd953ca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Nov 2014 16:48:56 -0800 Subject: [PATCH 4901/9457] Revert "char: misc: document behaviour of open()" This reverts commit 965ab29ba09d75056a6c9b0f707cd1c2cc91188f. This is causing way more problems than it is worth. Cc: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/char/misc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 69a08a6b43aa..205ad4c58470 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -169,9 +169,7 @@ static const struct file_operations misc_fops = { * the minor number requested is used. * * The structure passed is linked into the kernel and may not be - * destroyed until it has been unregistered. By default, an open() - * syscall to the device sets file->private_data to point to the - * structure. + * destroyed until it has been unregistered. * * A zero is returned on success and a negative errno code for * failure. -- GitLab From 4bc33a2cd5070188c79029a8a9f2058dfd2a79a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Nov 2014 16:49:20 -0800 Subject: [PATCH 4902/9457] Revert "fbdev: pxa3xx-gcu: remove redundant implementation of open()" This reverts commit 2bfeeca107591134bf9a40945c50d337bf858612. Not needed after the next patch is applied. Cc: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/pxa3xx-gcu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c index 7678a94cea7f..4df3657fe221 100644 --- a/drivers/video/fbdev/pxa3xx-gcu.c +++ b/drivers/video/fbdev/pxa3xx-gcu.c @@ -373,6 +373,15 @@ static inline struct pxa3xx_gcu_priv *to_pxa3xx_gcu_priv(struct file *file) return container_of(dev, struct pxa3xx_gcu_priv, misc_dev); } +/* + * provide an empty .open callback, so the core sets file->private_data + * for us. + */ +static int pxa3xx_gcu_open(struct inode *inode, struct file *file) +{ + return 0; +} + static ssize_t pxa3xx_gcu_write(struct file *file, const char *buff, size_t count, loff_t *offp) @@ -571,6 +580,7 @@ pxa3xx_gcu_free_buffers(struct device *dev, static const struct file_operations pxa3xx_gcu_miscdev_fops = { .owner = THIS_MODULE, + .open = pxa3xx_gcu_open, .write = pxa3xx_gcu_write, .unlocked_ioctl = pxa3xx_gcu_ioctl, .mmap = pxa3xx_gcu_mmap, -- GitLab From e88b1fc6a1c1d088824eb4869a70c374da9ebc86 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Nov 2014 16:49:49 -0800 Subject: [PATCH 4903/9457] Revert "misc: always assign miscdevice to file->private_data in open()" This reverts commit 32eca22180804f71b06b63fd29b72f58be8b3c47. Changing core kernel code to operate in a different manner, without a build-time breakage is tough to do and ensure you got it right. There are lots of problems popping up due to this change, so let's revert it for now as it is not safe to merge to the tree at this point in time. Cc: Martin Kepplinger Signed-off-by: Greg Kroah-Hartman --- drivers/char/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 205ad4c58470..ffa97d261cf3 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -142,8 +142,8 @@ static int misc_open(struct inode * inode, struct file * file) err = 0; replace_fops(file, new_fops); - file->private_data = c; if (file->f_op->open) { + file->private_data = c; err = file->f_op->open(inode,file); } fail: -- GitLab From 970d0f1b280372cfd46b6de5529d96f8448de943 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 14:37:47 +0200 Subject: [PATCH 4904/9457] Bluetooth: Convert LTK list to RCU This patch set converts the hdev->long_term_keys list to use RCU to eliminate the need to use hci_dev_lock/unlock. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 42 ++++++++++++++++++-------------- net/bluetooth/hci_event.c | 4 +-- net/bluetooth/smp.c | 10 +++----- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4e39a5adfcab..a4adef22ad7c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -108,6 +108,7 @@ struct smp_csrk { struct smp_ltk { struct list_head list; + struct rcu_head rcu; bdaddr_t bdaddr; u8 bdaddr_type; u8 authenticated; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 6c162c8809cf..c9495fb9f595 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -778,17 +778,15 @@ static const struct file_operations identity_resolving_keys_fops = { static int long_term_keys_show(struct seq_file *f, void *ptr) { struct hci_dev *hdev = f->private; - struct list_head *p, *n; + struct smp_ltk *ltk; - hci_dev_lock(hdev); - list_for_each_safe(p, n, &hdev->long_term_keys) { - struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); + rcu_read_lock(); + list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list) seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n", <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), __le64_to_cpu(ltk->rand), 16, ltk->val); - } - hci_dev_unlock(hdev); + rcu_read_unlock(); return 0; } @@ -3106,11 +3104,11 @@ void hci_link_keys_clear(struct hci_dev *hdev) void hci_smp_ltks_clear(struct hci_dev *hdev) { - struct smp_ltk *k, *tmp; + struct smp_ltk *k; - list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { - list_del(&k->list); - kfree(k); + list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { + list_del_rcu(&k->list); + kfree_rcu(k, rcu); } } @@ -3184,15 +3182,18 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, { struct smp_ltk *k; - list_for_each_entry(k, &hdev->long_term_keys, list) { + rcu_read_lock(); + list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { if (k->ediv != ediv || k->rand != rand) continue; if (ltk_role(k->type) != role) continue; + rcu_read_unlock(); return k; } + rcu_read_unlock(); return NULL; } @@ -3202,11 +3203,16 @@ struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, { struct smp_ltk *k; - list_for_each_entry(k, &hdev->long_term_keys, list) + rcu_read_lock(); + list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { if (addr_type == k->bdaddr_type && bacmp(bdaddr, &k->bdaddr) == 0 && - ltk_role(k->type) == role) + ltk_role(k->type) == role) { + rcu_read_unlock(); return k; + } + } + rcu_read_unlock(); return NULL; } @@ -3309,7 +3315,7 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, key = kzalloc(sizeof(*key), GFP_KERNEL); if (!key) return NULL; - list_add(&key->list, &hdev->long_term_keys); + list_add_rcu(&key->list, &hdev->long_term_keys); } bacpy(&key->bdaddr, bdaddr); @@ -3365,17 +3371,17 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) { - struct smp_ltk *k, *tmp; + struct smp_ltk *k; int removed = 0; - list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { + list_for_each_entry_rcu(k, &hdev->long_term_keys, list) { if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type) continue; BT_DBG("%s removing %pMR", hdev->name, bdaddr); - list_del(&k->list); - kfree(k); + list_del_rcu(&k->list); + kfree_rcu(k, rcu); removed++; } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index aec3b1dce1cc..09d76547d985 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4578,8 +4578,8 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) */ if (ltk->type == SMP_STK) { set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); - list_del(<k->list); - kfree(ltk); + list_del_rcu(<k->list); + kfree_rcu(ltk, rcu); } else { clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3dc5f0e66405..fd2dfe5222bc 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -383,13 +383,13 @@ static void smp_chan_destroy(struct l2cap_conn *conn) /* If pairing failed clean up any keys we might have */ if (!complete) { if (smp->ltk) { - list_del(&smp->ltk->list); - kfree(smp->ltk); + list_del_rcu(&smp->ltk->list); + kfree_rcu(smp->ltk, rcu); } if (smp->slave_ltk) { - list_del(&smp->slave_ltk->list); - kfree(smp->slave_ltk); + list_del_rcu(&smp->slave_ltk->list); + kfree_rcu(smp->slave_ltk, rcu); } if (smp->remote_irk) { @@ -1321,7 +1321,6 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) skb_pull(skb, sizeof(*rp)); - hci_dev_lock(hdev); authenticated = (hcon->sec_level == BT_SECURITY_HIGH); ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, authenticated, smp->tk, smp->enc_key_size, @@ -1329,7 +1328,6 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) smp->ltk = ltk; if (!(smp->remote_key_dist & KEY_DIST_MASK)) smp_distribute_keys(smp); - hci_dev_unlock(hdev); return 0; } -- GitLab From adae20cb2d20e5151b866945f802b0c2312f0f82 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 14:37:48 +0200 Subject: [PATCH 4905/9457] Bluetooth: Convert IRK list to RCU This patch set converts the hdev->identity_resolving_keys list to use RCU to eliminate the need to use hci_dev_lock/unlock. An additional change that must be done is to remove use of CRYPTO_ALG_ASYNC for the hdev-specific AES crypto context. The reason is that this context is used for matching RPAs and the loop that does the matching is under the RCU read lock, i.e. is an atomic section which cannot sleep. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 46 +++++++++++++++++++------------- net/bluetooth/smp.c | 10 +++---- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a4adef22ad7c..fe2d5f299e12 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -121,6 +121,7 @@ struct smp_ltk { struct smp_irk { struct list_head list; + struct rcu_head rcu; bdaddr_t rpa; bdaddr_t bdaddr; u8 addr_type; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c9495fb9f595..90ea0b7670d2 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -748,16 +748,15 @@ static const struct file_operations white_list_fops = { static int identity_resolving_keys_show(struct seq_file *f, void *ptr) { struct hci_dev *hdev = f->private; - struct list_head *p, *n; + struct smp_irk *irk; - hci_dev_lock(hdev); - list_for_each_safe(p, n, &hdev->identity_resolving_keys) { - struct smp_irk *irk = list_entry(p, struct smp_irk, list); + rcu_read_lock(); + list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &irk->bdaddr, irk->addr_type, 16, irk->val, &irk->rpa); } - hci_dev_unlock(hdev); + rcu_read_unlock(); return 0; } @@ -3114,11 +3113,11 @@ void hci_smp_ltks_clear(struct hci_dev *hdev) void hci_smp_irks_clear(struct hci_dev *hdev) { - struct smp_irk *k, *tmp; + struct smp_irk *k; - list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { - list_del(&k->list); - kfree(k); + list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { + list_del_rcu(&k->list); + kfree_rcu(k, rcu); } } @@ -3221,17 +3220,22 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) { struct smp_irk *irk; - list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { - if (!bacmp(&irk->rpa, rpa)) + rcu_read_lock(); + list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { + if (!bacmp(&irk->rpa, rpa)) { + rcu_read_unlock(); return irk; + } } - list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { + list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { if (smp_irk_matches(hdev, irk->val, rpa)) { bacpy(&irk->rpa, rpa); + rcu_read_unlock(); return irk; } } + rcu_read_unlock(); return NULL; } @@ -3245,11 +3249,15 @@ struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0) return NULL; - list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { + rcu_read_lock(); + list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) { if (addr_type == irk->addr_type && - bacmp(bdaddr, &irk->bdaddr) == 0) + bacmp(bdaddr, &irk->bdaddr) == 0) { + rcu_read_unlock(); return irk; + } } + rcu_read_unlock(); return NULL; } @@ -3344,7 +3352,7 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, bacpy(&irk->bdaddr, bdaddr); irk->addr_type = addr_type; - list_add(&irk->list, &hdev->identity_resolving_keys); + list_add_rcu(&irk->list, &hdev->identity_resolving_keys); } memcpy(irk->val, val, 16); @@ -3390,16 +3398,16 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type) void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) { - struct smp_irk *k, *tmp; + struct smp_irk *k; - list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { + list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) { if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type) continue; BT_DBG("%s removing %pMR", hdev->name, bdaddr); - list_del(&k->list); - kfree(k); + list_del_rcu(&k->list); + kfree_rcu(k, rcu); } } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fd2dfe5222bc..7b610f615257 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -393,8 +393,8 @@ static void smp_chan_destroy(struct l2cap_conn *conn) } if (smp->remote_irk) { - list_del(&smp->remote_irk->list); - kfree(smp->remote_irk); + list_del_rcu(&smp->remote_irk->list); + kfree_rcu(smp->remote_irk, rcu); } } @@ -655,8 +655,8 @@ static void smp_notify_keys(struct l2cap_conn *conn) * just remove it. */ if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { - list_del(&smp->remote_irk->list); - kfree(smp->remote_irk); + list_del_rcu(&smp->remote_irk->list); + kfree_rcu(smp->remote_irk, rcu); smp->remote_irk = NULL; } } @@ -1696,7 +1696,7 @@ int smp_register(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0); if (IS_ERR(tfm_aes)) { int err = PTR_ERR(tfm_aes); BT_ERR("Unable to create crypto context"); -- GitLab From d88b5bbf1a985c338967f3c41351b32b747a55fe Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 14:37:49 +0200 Subject: [PATCH 4906/9457] Bluetooth: Remove unnecessary hdev locking in smp.c Now that the SMP related key lists are converted to RCU there is nothing in smp_cmd_sign_info() or smp_cmd_ident_addr_info() that would require taking the hdev lock (including the smp_distribute_keys call). This patch removes this unnecessary locking. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 7b610f615257..069b76e03b57 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1374,8 +1374,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, skb_pull(skb, sizeof(*info)); - hci_dev_lock(hcon->hdev); - /* Strictly speaking the Core Specification (4.1) allows sending * an empty address which would force us to rely on just the IRK * as "identity information". However, since such @@ -1403,8 +1401,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, if (!(smp->remote_key_dist & KEY_DIST_MASK)) smp_distribute_keys(smp); - hci_dev_unlock(hcon->hdev); - return 0; } @@ -1413,7 +1409,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_cmd_sign_info *rp = (void *) skb->data; struct l2cap_chan *chan = conn->smp; struct smp_chan *smp = chan->data; - struct hci_dev *hdev = conn->hcon->hdev; struct smp_csrk *csrk; BT_DBG("conn %p", conn); @@ -1426,7 +1421,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) skb_pull(skb, sizeof(*rp)); - hci_dev_lock(hdev); csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); if (csrk) { csrk->master = 0x01; @@ -1434,7 +1428,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) } smp->csrk = csrk; smp_distribute_keys(smp); - hci_dev_unlock(hdev); return 0; } -- GitLab From 49d1174130df596fcfec3b6a56dce8aa5b997f2d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 13 Nov 2014 14:37:50 +0200 Subject: [PATCH 4907/9457] Bluetooth: Add debug logs to help track locking issues This patch adds some extra debug logs to L2CAP related code. These are mainly to help track locking issues but will probably be useful for debugging other types of issues as well. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 ++- net/bluetooth/l2cap_sock.c | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 15784d32108d..8e1273173020 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -570,7 +570,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) __clear_chan_timer(chan); - BT_DBG("chan %p, conn %p, err %d", chan, conn, err); + BT_DBG("chan %p, conn %p, err %d, state %s", chan, conn, err, + state_to_string(chan->state)); chan->ops->teardown(chan, err); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index a5aa9f92b5e2..b0efb7202957 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1102,6 +1102,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) chan = l2cap_pi(sk)->chan; conn = chan->conn; + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + if (conn) mutex_lock(&conn->chan_lock); @@ -1159,12 +1161,16 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) { struct sock *sk; - BT_DBG("parent %p", parent); + BT_DBG("parent %p state %s", parent, + state_to_string(parent->sk_state)); /* Close not yet accepted channels */ while ((sk = bt_accept_dequeue(parent, NULL))) { struct l2cap_chan *chan = l2cap_pi(sk)->chan; + BT_DBG("child chan %p state %s", chan, + state_to_string(chan->state)); + l2cap_chan_lock(chan); __clear_chan_timer(chan); l2cap_chan_close(chan, ECONNRESET); @@ -1252,6 +1258,8 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) struct sock *sk = chan->data; struct sock *parent; + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + /* This callback can be called both for server (BT_LISTEN) * sockets as well as "normal" ones. To avoid lockdep warnings * with child socket locking (through l2cap_sock_cleanup_listen) -- GitLab From eedbd5812c2afe79646a7c1c071875e46c867935 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 15 Nov 2014 09:34:23 +0200 Subject: [PATCH 4908/9457] Bluetooth: Fix clearing remote OOB data through mgmt When passed BDADDR_ANY the Remove Remote OOB Data comand is specified to clear all entries. This patch adds the necessary check and calls hci_remote_oob_data_clear() when necessary. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index ce0272c6f71f..b84c0923ec62 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3635,12 +3635,19 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); + if (!bacmp(&cp->addr.bdaddr, BDADDR_ANY)) { + hci_remote_oob_data_clear(hdev); + status = MGMT_STATUS_SUCCESS; + goto done; + } + err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr); if (err < 0) status = MGMT_STATUS_INVALID_PARAMS; else status = MGMT_STATUS_SUCCESS; +done: err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, status, &cp->addr, sizeof(cp->addr)); -- GitLab From 0132234160ae46d8bd4677e37adb0b4366e05b1e Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 13 Nov 2014 15:19:21 +0800 Subject: [PATCH 4909/9457] clk: rockchip: fix rk3288 clk_usbphy480m_gate bit location in register According to rk3288 trm, the clk_usbphy480m_gate is located at bit 14 of CRU_CLKGATE5_CON register. Signed-off-by: Kever Yang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index b4a74c2d79e0..f27cdae61fd5 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -588,7 +588,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0, RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, - RK3288_CLKGATE_CON(5), 15, GFLAGS), + RK3288_CLKGATE_CON(5), 14, GFLAGS), COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, RK3288_CLKGATE_CON(3), 6, GFLAGS), -- GitLab From 29e94468516cdf191ec839ee39f79e011817276d Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Thu, 13 Nov 2014 16:11:49 +0800 Subject: [PATCH 4910/9457] clk: rockchip: fix clock select order for rk3288 usbphy480m_src According to rk3288 trm, the mux selector locate at bit[12:11] of CRU_CLKSEL13_CON shows: 2'b00: select HOST0 USB pll clock (clk_otgphy1) 2'b01: select HOST1 USB pll clock (clk_otgphy2) 2'b10: select OTG USB pll clock (clk_otgphy0) The clock map is in Fig. 3-4 CRU Clock Architecture Diagram 3 - clk_otgphy0 -> USB PHY OTG - clk_otgphy1 -> USB PHY host0 - clk_otgphy2 -> USB PHY host1 Signed-off-by: Kever Yang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index f27cdae61fd5..174589c95e33 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,8 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1", - "sclk_otgphy2" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", + "sclk_otgphy0" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; -- GitLab From b7bbd6406ae82f4faa8a5e571866e44f4c49255d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 31 Oct 2014 12:19:40 -0400 Subject: [PATCH 4911/9457] drm/msm: select REGULATOR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a potential error, spotted by Felipe with randconfig: ----- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c: In function ‘mdp4_kms_init’: drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c:384:2: error: implicit declaration \ of function ‘devm_regulator_get_exclusive’ [-Werror=implicit-function-declaration] mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); ^ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c:384:16: error: assignment makes \ pointer from integer without a cast [-Werror] mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); ^ ----- Also add a brief comment explaining the use of _get_exclusive() Reported-by: Felipe Balbi Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9d907c526c94..5b2a1ff95d3d 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -3,6 +3,7 @@ config DRM_MSM tristate "MSM DRM" depends on DRM depends on ARCH_QCOM || (ARM && COMPILE_TEST) + select REGULATOR select DRM_KMS_HELPER select DRM_PANEL select SHMEM diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 79d804e61cc4..ac204720429e 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -381,6 +381,10 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) if (IS_ERR(mdp4_kms->dsi_pll_vddio)) mdp4_kms->dsi_pll_vddio = NULL; + /* NOTE: driver for this regulator still missing upstream.. use + * _get_exclusive() and ignore the error if it does not exist + * (and hope that the bootloader left it on for us) + */ mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); if (IS_ERR(mdp4_kms->vdd)) mdp4_kms->vdd = NULL; -- GitLab From 0122f96fc2c1f911cb5b4db0a6dc98ac367e7e44 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 31 Oct 2014 11:50:55 -0400 Subject: [PATCH 4912/9457] drm/msm/adreno: slight init order cleanup Move anything that can fail after call to base class msm_gpu_init(). This way, if we fail, active_list has already been initialized so we don't trip 'WARN_ON(!list_empty(&gpu->active_list))' in msm_gpu_cleanup(). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 6afa29167fee..dc807b23f77a 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -319,6 +319,12 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, DBG("fast_rate=%u, slow_rate=%u, bus_freq=%u", gpu->fast_rate, gpu->slow_rate, gpu->bus_freq); + ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, + adreno_gpu->info->name, "kgsl_3d0_reg_memory", "kgsl_3d0_irq", + RB_SIZE); + if (ret) + return ret; + ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", @@ -333,12 +339,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return ret; } - ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, - adreno_gpu->info->name, "kgsl_3d0_reg_memory", "kgsl_3d0_irq", - RB_SIZE); - if (ret) - return ret; - mmu = gpu->mmu; if (mmu) { ret = mmu->funcs->attach(mmu, iommu_ports, -- GitLab From bc00ae02e4a0b0d34a03bb25a8285b80e4f628c4 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 31 Oct 2014 12:54:25 -0400 Subject: [PATCH 4913/9457] drm/msm: update generated headers Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a2xx.xml.h | 26 +- drivers/gpu/drm/msm/adreno/a3xx.xml.h | 247 +- drivers/gpu/drm/msm/adreno/a4xx.xml.h | 2144 +++++++++++++++++ .../gpu/drm/msm/adreno/adreno_common.xml.h | 17 +- drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h | 75 +- drivers/gpu/drm/msm/dsi/dsi.xml.h | 8 +- drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | 8 +- drivers/gpu/drm/msm/dsi/sfpb.xml.h | 8 +- drivers/gpu/drm/msm/hdmi/hdmi.xml.h | 8 +- drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 8 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | 8 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 10 +- 12 files changed, 2459 insertions(+), 108 deletions(-) create mode 100644 drivers/gpu/drm/msm/adreno/a4xx.xml.h diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index a3104598c27f..22882cc0a573 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h @@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) Copyright (C) 2013-2014 by the following authors: - Rob Clark (robclark) @@ -926,11 +926,11 @@ static inline uint32_t A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE(enum pc_di_index_size #define A2XX_VGT_DRAW_INITIATOR_NOT_EOP 0x00001000 #define A2XX_VGT_DRAW_INITIATOR_SMALL_INDEX 0x00002000 #define A2XX_VGT_DRAW_INITIATOR_PRE_DRAW_INITIATOR_ENABLE 0x00004000 -#define A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK 0xffff0000 -#define A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT 16 -static inline uint32_t A2XX_VGT_DRAW_INITIATOR_NUM_INDICES(uint32_t val) +#define A2XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__MASK 0xff000000 +#define A2XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__SHIFT 24 +static inline uint32_t A2XX_VGT_DRAW_INITIATOR_NUM_INSTANCES(uint32_t val) { - return ((val) << A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT) & A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK; + return ((val) << A2XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__SHIFT) & A2XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__MASK; } #define REG_A2XX_VGT_IMMED_DATA 0x000021fd @@ -1243,13 +1243,13 @@ static inline uint32_t A2XX_CLEAR_COLOR_ALPHA(uint32_t val) #define A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT 0 static inline uint32_t A2XX_PA_SU_POINT_SIZE_HEIGHT(float val) { - return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK; + return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK; } #define A2XX_PA_SU_POINT_SIZE_WIDTH__MASK 0xffff0000 #define A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT 16 static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val) { - return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK; + return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK; } #define REG_A2XX_PA_SU_POINT_MINMAX 0x00002281 @@ -1257,13 +1257,13 @@ static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val) #define A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT 0 static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MIN(float val) { - return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK; + return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK; } #define A2XX_PA_SU_POINT_MINMAX_MAX__MASK 0xffff0000 #define A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT 16 static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val) { - return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK; + return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK; } #define REG_A2XX_PA_SU_LINE_CNTL 0x00002282 @@ -1271,7 +1271,7 @@ static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val) #define A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT 0 static inline uint32_t A2XX_PA_SU_LINE_CNTL_WIDTH(float val) { - return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK; + return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK; } #define REG_A2XX_PA_SC_LINE_STIPPLE 0x00002283 diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index 82d015279b47..109e9a263daf 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h @@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) Copyright (C) 2013-2014 by the following authors: - Rob Clark (robclark) @@ -86,6 +86,14 @@ enum a3xx_vtx_fmt { VFMT_NORM_USHORT_16_16 = 29, VFMT_NORM_USHORT_16_16_16 = 30, VFMT_NORM_USHORT_16_16_16_16 = 31, + VFMT_UINT_32 = 32, + VFMT_UINT_32_32 = 33, + VFMT_UINT_32_32_32 = 34, + VFMT_UINT_32_32_32_32 = 35, + VFMT_INT_32 = 36, + VFMT_INT_32_32 = 37, + VFMT_INT_32_32_32 = 38, + VFMT_INT_32_32_32_32 = 39, VFMT_UBYTE_8 = 40, VFMT_UBYTE_8_8 = 41, VFMT_UBYTE_8_8_8 = 42, @@ -112,7 +120,9 @@ enum a3xx_tex_fmt { TFMT_NORM_USHORT_565 = 4, TFMT_NORM_USHORT_5551 = 6, TFMT_NORM_USHORT_4444 = 7, + TFMT_NORM_USHORT_Z16 = 9, TFMT_NORM_UINT_X8Z24 = 10, + TFMT_FLOAT_Z32 = 11, TFMT_NORM_UINT_NV12_UV_TILED = 17, TFMT_NORM_UINT_NV12_Y_TILED = 19, TFMT_NORM_UINT_NV12_UV = 21, @@ -121,18 +131,38 @@ enum a3xx_tex_fmt { TFMT_NORM_UINT_I420_U = 26, TFMT_NORM_UINT_I420_V = 27, TFMT_NORM_UINT_2_10_10_10 = 41, + TFMT_FLOAT_9_9_9_E5 = 42, + TFMT_FLOAT_10_11_11 = 43, TFMT_NORM_UINT_A8 = 44, TFMT_NORM_UINT_L8_A8 = 47, TFMT_NORM_UINT_8 = 48, TFMT_NORM_UINT_8_8 = 49, TFMT_NORM_UINT_8_8_8 = 50, TFMT_NORM_UINT_8_8_8_8 = 51, + TFMT_NORM_SINT_8_8 = 53, + TFMT_NORM_SINT_8_8_8_8 = 55, + TFMT_UINT_8_8 = 57, + TFMT_UINT_8_8_8_8 = 59, + TFMT_SINT_8_8 = 61, + TFMT_SINT_8_8_8_8 = 63, TFMT_FLOAT_16 = 64, TFMT_FLOAT_16_16 = 65, TFMT_FLOAT_16_16_16_16 = 67, + TFMT_UINT_16 = 68, + TFMT_UINT_16_16 = 69, + TFMT_UINT_16_16_16_16 = 71, + TFMT_SINT_16 = 72, + TFMT_SINT_16_16 = 73, + TFMT_SINT_16_16_16_16 = 75, TFMT_FLOAT_32 = 84, TFMT_FLOAT_32_32 = 85, TFMT_FLOAT_32_32_32_32 = 87, + TFMT_UINT_32 = 88, + TFMT_UINT_32_32 = 89, + TFMT_UINT_32_32_32_32 = 91, + TFMT_SINT_32 = 92, + TFMT_SINT_32_32 = 93, + TFMT_SINT_32_32_32_32 = 95, }; enum a3xx_tex_fetchsize { @@ -145,19 +175,34 @@ enum a3xx_tex_fetchsize { }; enum a3xx_color_fmt { + RB_R5G6B5_UNORM = 0, + RB_R5G5B5A1_UNORM = 1, + RB_R4G4B4A4_UNORM = 3, RB_R8G8B8_UNORM = 4, RB_R8G8B8A8_UNORM = 8, - RB_Z16_UNORM = 12, + RB_R8G8B8A8_UINT = 10, + RB_R8G8B8A8_SINT = 11, + RB_R8G8_UNORM = 12, + RB_R8_UINT = 14, + RB_R8_SINT = 15, + RB_R10G10B10A2_UNORM = 16, RB_A8_UNORM = 20, + RB_R8_UNORM = 21, RB_R16G16B16A16_FLOAT = 27, + RB_R11G11B10_FLOAT = 28, + RB_R16_SINT = 40, + RB_R16G16_SINT = 41, + RB_R16G16B16A16_SINT = 43, + RB_R16_UINT = 44, + RB_R16G16_UINT = 45, + RB_R16G16B16A16_UINT = 47, RB_R32G32B32A32_FLOAT = 51, -}; - -enum a3xx_color_swap { - WZYX = 0, - WXYZ = 1, - ZYXW = 2, - XYZW = 3, + RB_R32_SINT = 52, + RB_R32G32_SINT = 53, + RB_R32G32B32A32_SINT = 55, + RB_R32_UINT = 56, + RB_R32G32_UINT = 57, + RB_R32G32B32A32_UINT = 59, }; enum a3xx_sp_perfcounter_select { @@ -194,6 +239,11 @@ enum a3xx_rb_blend_opcode { BLEND_MAX_DST_SRC = 4, }; +enum a3xx_intp_mode { + SMOOTH = 0, + FLAT = 1, +}; + enum a3xx_tex_filter { A3XX_TEX_NEAREST = 0, A3XX_TEX_LINEAR = 1, @@ -536,6 +586,10 @@ enum a3xx_tex_type { #define REG_A3XX_CP_MEQ_DATA 0x000001db +#define REG_A3XX_CP_WFI_PEND_CTR 0x000001f5 + +#define REG_A3XX_RBBM_PM_OVERRIDE2 0x0000039d + #define REG_A3XX_CP_PERFCOUNTER_SELECT 0x00000445 #define REG_A3XX_CP_HW_FAULT 0x0000045c @@ -550,6 +604,12 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460 #define REG_A3XX_CP_AHB_FAULT 0x0000054d +#define REG_A3XX_SQ_GPR_MANAGEMENT 0x00000d00 + +#define REG_A3XX_SQ_INST_STORE_MANAGMENT 0x00000d02 + +#define REG_A3XX_TP0_CHICKEN 0x00000e1e + #define REG_A3XX_SP_GLOBAL_MEM_SIZE 0x00000e22 #define REG_A3XX_SP_GLOBAL_MEM_ADDR 0x00000e23 @@ -632,13 +692,13 @@ static inline uint32_t A3XX_GRAS_CL_VPORT_ZSCALE(float val) #define A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT 0 static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MIN(float val) { - return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK; + return ((((uint32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK; } #define A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK 0xffff0000 #define A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT 16 static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MAX(float val) { - return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK; + return ((((uint32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK; } #define REG_A3XX_GRAS_SU_POINT_SIZE 0x00002069 @@ -646,7 +706,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MAX(float val) #define A3XX_GRAS_SU_POINT_SIZE__SHIFT 0 static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val) { - return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_SIZE__SHIFT) & A3XX_GRAS_SU_POINT_SIZE__MASK; + return ((((int32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_SIZE__SHIFT) & A3XX_GRAS_SU_POINT_SIZE__MASK; } #define REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE 0x0000206c @@ -654,7 +714,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val) #define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT 0 static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val) { - return ((((uint32_t)(val * 28.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK; + return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK; } #define REG_A3XX_GRAS_SU_POLY_OFFSET_OFFSET 0x0000206d @@ -662,7 +722,7 @@ static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val) #define A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT 0 static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val) { - return ((((uint32_t)(val * 28.0))) << A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK; + return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK; } #define REG_A3XX_GRAS_SU_MODE_CONTROL 0x00002070 @@ -673,7 +733,7 @@ static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val) #define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3 static inline uint32_t A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val) { - return ((((uint32_t)(val * 4.0))) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK; + return ((((int32_t)(val * 4.0))) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK; } #define A3XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800 @@ -863,6 +923,7 @@ static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(enum a3xx_color_swap val) { return ((val) << A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__SHIFT) & A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__MASK; } +#define A3XX_RB_MRT_BUF_INFO_COLOR_SRGB 0x00004000 #define A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__MASK 0xfffe0000 #define A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__SHIFT 17 static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(uint32_t val) @@ -1001,6 +1062,7 @@ static inline uint32_t A3XX_RB_COPY_CONTROL_FASTCLEAR(uint32_t val) { return ((val) << A3XX_RB_COPY_CONTROL_FASTCLEAR__SHIFT) & A3XX_RB_COPY_CONTROL_FASTCLEAR__MASK; } +#define A3XX_RB_COPY_CONTROL_UNK12 0x00001000 #define A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK 0xffffc000 #define A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT 14 static inline uint32_t A3XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val) @@ -1079,7 +1141,7 @@ static inline uint32_t A3XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val) #define REG_A3XX_RB_DEPTH_CLEAR 0x00002101 #define REG_A3XX_RB_DEPTH_INFO 0x00002102 -#define A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK 0x00000001 +#define A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK 0x00000003 #define A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT 0 static inline uint32_t A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_format val) { @@ -1265,6 +1327,7 @@ static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(enum adreno_pa_ { return ((val) << A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__MASK; } +#define A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART 0x00100000 #define A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST 0x02000000 #define A3XX_PC_PRIM_VTX_CNTL_PSIZE 0x04000000 @@ -1281,7 +1344,12 @@ static inline uint32_t A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(enum a3xx_threadsize #define A3XX_HLSQ_CONTROL_0_REG_SPSHADERRESTART 0x00000200 #define A3XX_HLSQ_CONTROL_0_REG_RESERVED2 0x00000400 #define A3XX_HLSQ_CONTROL_0_REG_CHUNKDISABLE 0x04000000 -#define A3XX_HLSQ_CONTROL_0_REG_CONSTSWITCHMODE 0x08000000 +#define A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK 0x08000000 +#define A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT 27 +static inline uint32_t A3XX_HLSQ_CONTROL_0_REG_CONSTMODE(uint32_t val) +{ + return ((val) << A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT) & A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK; +} #define A3XX_HLSQ_CONTROL_0_REG_LAZYUPDATEDISABLE 0x10000000 #define A3XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE 0x20000000 #define A3XX_HLSQ_CONTROL_0_REG_TPFULLUPDATE 0x40000000 @@ -1484,6 +1552,8 @@ static inline uint32_t A3XX_VFD_CONTROL_1_REGID4INST(uint32_t val) #define REG_A3XX_VFD_INDEX_OFFSET 0x00002245 +#define REG_A3XX_VFD_INDEX_OFFSET 0x00002245 + static inline uint32_t REG_A3XX_VFD_FETCH(uint32_t i0) { return 0x00002246 + 0x2*i0; } static inline uint32_t REG_A3XX_VFD_FETCH_INSTR_0(uint32_t i0) { return 0x00002246 + 0x2*i0; } @@ -1537,6 +1607,7 @@ static inline uint32_t A3XX_VFD_DECODE_INSTR_REGID(uint32_t val) { return ((val) << A3XX_VFD_DECODE_INSTR_REGID__SHIFT) & A3XX_VFD_DECODE_INSTR_REGID__MASK; } +#define A3XX_VFD_DECODE_INSTR_INT 0x00100000 #define A3XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000 #define A3XX_VFD_DECODE_INSTR_SWAP__SHIFT 22 static inline uint32_t A3XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val) @@ -1604,6 +1675,102 @@ static inline uint32_t A3XX_VPC_PACK_NUMNONPOSVSVAR(uint32_t val) static inline uint32_t REG_A3XX_VPC_VARYING_INTERP(uint32_t i0) { return 0x00002282 + 0x1*i0; } static inline uint32_t REG_A3XX_VPC_VARYING_INTERP_MODE(uint32_t i0) { return 0x00002282 + 0x1*i0; } +#define A3XX_VPC_VARYING_INTERP_MODE_C0__MASK 0x00000003 +#define A3XX_VPC_VARYING_INTERP_MODE_C0__SHIFT 0 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C0(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C0__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C0__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C1__MASK 0x0000000c +#define A3XX_VPC_VARYING_INTERP_MODE_C1__SHIFT 2 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C1(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C1__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C1__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C2__MASK 0x00000030 +#define A3XX_VPC_VARYING_INTERP_MODE_C2__SHIFT 4 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C2(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C2__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C2__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C3__MASK 0x000000c0 +#define A3XX_VPC_VARYING_INTERP_MODE_C3__SHIFT 6 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C3(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C3__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C3__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C4__MASK 0x00000300 +#define A3XX_VPC_VARYING_INTERP_MODE_C4__SHIFT 8 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C4(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C4__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C4__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C5__MASK 0x00000c00 +#define A3XX_VPC_VARYING_INTERP_MODE_C5__SHIFT 10 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C5(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C5__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C5__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C6__MASK 0x00003000 +#define A3XX_VPC_VARYING_INTERP_MODE_C6__SHIFT 12 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C6(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C6__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C6__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C7__MASK 0x0000c000 +#define A3XX_VPC_VARYING_INTERP_MODE_C7__SHIFT 14 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C7(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C7__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C7__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C8__MASK 0x00030000 +#define A3XX_VPC_VARYING_INTERP_MODE_C8__SHIFT 16 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C8(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C8__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C8__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_C9__MASK 0x000c0000 +#define A3XX_VPC_VARYING_INTERP_MODE_C9__SHIFT 18 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C9(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C9__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C9__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CA__MASK 0x00300000 +#define A3XX_VPC_VARYING_INTERP_MODE_CA__SHIFT 20 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CA(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CA__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CA__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CB__MASK 0x00c00000 +#define A3XX_VPC_VARYING_INTERP_MODE_CB__SHIFT 22 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CB(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CB__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CB__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CC__MASK 0x03000000 +#define A3XX_VPC_VARYING_INTERP_MODE_CC__SHIFT 24 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CC(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CC__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CC__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CD__MASK 0x0c000000 +#define A3XX_VPC_VARYING_INTERP_MODE_CD__SHIFT 26 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CD(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CD__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CD__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CE__MASK 0x30000000 +#define A3XX_VPC_VARYING_INTERP_MODE_CE__SHIFT 28 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CE(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CE__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CE__MASK; +} +#define A3XX_VPC_VARYING_INTERP_MODE_CF__MASK 0xc0000000 +#define A3XX_VPC_VARYING_INTERP_MODE_CF__SHIFT 30 +static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CF(enum a3xx_intp_mode val) +{ + return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CF__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CF__MASK; +} static inline uint32_t REG_A3XX_VPC_VARYING_PS_REPL(uint32_t i0) { return 0x00002286 + 0x1*i0; } @@ -1928,6 +2095,8 @@ static inline uint32_t A3XX_SP_FS_MRT_REG_REGID(uint32_t val) return ((val) << A3XX_SP_FS_MRT_REG_REGID__SHIFT) & A3XX_SP_FS_MRT_REG_REGID__MASK; } #define A3XX_SP_FS_MRT_REG_HALF_PRECISION 0x00000100 +#define A3XX_SP_FS_MRT_REG_SINT 0x00000400 +#define A3XX_SP_FS_MRT_REG_UINT 0x00000800 static inline uint32_t REG_A3XX_SP_FS_IMAGE_OUTPUT(uint32_t i0) { return 0x000022f4 + 0x1*i0; } @@ -1947,6 +2116,8 @@ static inline uint32_t A3XX_SP_FS_LENGTH_REG_SHADERLENGTH(uint32_t val) return ((val) << A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__SHIFT) & A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__MASK; } +#define REG_A3XX_PA_SC_AA_CONFIG 0x00002301 + #define REG_A3XX_TPL1_TP_VS_TEX_OFFSET 0x00002340 #define A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__MASK 0x000000ff #define A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__SHIFT 0 @@ -2297,11 +2468,11 @@ static inline uint32_t A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE(enum pc_di_index_size #define A3XX_VGT_DRAW_INITIATOR_NOT_EOP 0x00001000 #define A3XX_VGT_DRAW_INITIATOR_SMALL_INDEX 0x00002000 #define A3XX_VGT_DRAW_INITIATOR_PRE_DRAW_INITIATOR_ENABLE 0x00004000 -#define A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK 0xffff0000 -#define A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT 16 -static inline uint32_t A3XX_VGT_DRAW_INITIATOR_NUM_INDICES(uint32_t val) +#define A3XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__MASK 0xff000000 +#define A3XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__SHIFT 24 +static inline uint32_t A3XX_VGT_DRAW_INITIATOR_NUM_INSTANCES(uint32_t val) { - return ((val) << A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT) & A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK; + return ((val) << A3XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__SHIFT) & A3XX_VGT_DRAW_INITIATOR_NUM_INSTANCES__MASK; } #define REG_A3XX_VGT_IMMED_DATA 0x000021fd @@ -2347,17 +2518,23 @@ static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val #define A3XX_TEX_SAMP_0_UNNORM_COORDS 0x80000000 #define REG_A3XX_TEX_SAMP_1 0x00000001 +#define A3XX_TEX_SAMP_1_LOD_BIAS__MASK 0x000007ff +#define A3XX_TEX_SAMP_1_LOD_BIAS__SHIFT 0 +static inline uint32_t A3XX_TEX_SAMP_1_LOD_BIAS(float val) +{ + return ((((int32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_LOD_BIAS__SHIFT) & A3XX_TEX_SAMP_1_LOD_BIAS__MASK; +} #define A3XX_TEX_SAMP_1_MAX_LOD__MASK 0x003ff000 #define A3XX_TEX_SAMP_1_MAX_LOD__SHIFT 12 static inline uint32_t A3XX_TEX_SAMP_1_MAX_LOD(float val) { - return ((((uint32_t)(val * 12.0))) << A3XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A3XX_TEX_SAMP_1_MAX_LOD__MASK; + return ((((uint32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A3XX_TEX_SAMP_1_MAX_LOD__MASK; } #define A3XX_TEX_SAMP_1_MIN_LOD__MASK 0xffc00000 #define A3XX_TEX_SAMP_1_MIN_LOD__SHIFT 22 static inline uint32_t A3XX_TEX_SAMP_1_MIN_LOD(float val) { - return ((((uint32_t)(val * 12.0))) << A3XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A3XX_TEX_SAMP_1_MIN_LOD__MASK; + return ((((uint32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A3XX_TEX_SAMP_1_MIN_LOD__MASK; } #define REG_A3XX_TEX_CONST_0 0x00000000 @@ -2448,6 +2625,24 @@ static inline uint32_t A3XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val) } #define REG_A3XX_TEX_CONST_3 0x00000003 +#define A3XX_TEX_CONST_3_LAYERSZ1__MASK 0x0000000f +#define A3XX_TEX_CONST_3_LAYERSZ1__SHIFT 0 +static inline uint32_t A3XX_TEX_CONST_3_LAYERSZ1(uint32_t val) +{ + return ((val >> 12) << A3XX_TEX_CONST_3_LAYERSZ1__SHIFT) & A3XX_TEX_CONST_3_LAYERSZ1__MASK; +} +#define A3XX_TEX_CONST_3_DEPTH__MASK 0x0ffe0000 +#define A3XX_TEX_CONST_3_DEPTH__SHIFT 17 +static inline uint32_t A3XX_TEX_CONST_3_DEPTH(uint32_t val) +{ + return ((val) << A3XX_TEX_CONST_3_DEPTH__SHIFT) & A3XX_TEX_CONST_3_DEPTH__MASK; +} +#define A3XX_TEX_CONST_3_LAYERSZ2__MASK 0xf0000000 +#define A3XX_TEX_CONST_3_LAYERSZ2__SHIFT 28 +static inline uint32_t A3XX_TEX_CONST_3_LAYERSZ2(uint32_t val) +{ + return ((val >> 12) << A3XX_TEX_CONST_3_LAYERSZ2__SHIFT) & A3XX_TEX_CONST_3_LAYERSZ2__MASK; +} #endif /* A3XX_XML */ diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h new file mode 100644 index 000000000000..5a24c416d2dd --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h @@ -0,0 +1,2144 @@ +#ifndef A4XX_XML +#define A4XX_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git + +The rules-ng-ng source files this header was generated from are: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) + +Copyright (C) 2013-2014 by the following authors: +- Rob Clark (robclark) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +enum a4xx_color_fmt { + RB4_A8_UNORM = 1, + RB4_R5G6R5_UNORM = 14, + RB4_Z16_UNORM = 15, + RB4_R8G8B8_UNORM = 25, + RB4_R8G8B8A8_UNORM = 26, +}; + +enum a4xx_tile_mode { + TILE4_LINEAR = 0, + TILE4_3 = 3, +}; + +enum a4xx_rb_blend_opcode { + BLEND_DST_PLUS_SRC = 0, + BLEND_SRC_MINUS_DST = 1, + BLEND_DST_MINUS_SRC = 2, + BLEND_MIN_DST_SRC = 3, + BLEND_MAX_DST_SRC = 4, +}; + +enum a4xx_vtx_fmt { + VFMT4_FLOAT_32 = 1, + VFMT4_FLOAT_32_32 = 2, + VFMT4_FLOAT_32_32_32 = 3, + VFMT4_FLOAT_32_32_32_32 = 4, + VFMT4_FLOAT_16 = 5, + VFMT4_FLOAT_16_16 = 6, + VFMT4_FLOAT_16_16_16 = 7, + VFMT4_FLOAT_16_16_16_16 = 8, + VFMT4_FIXED_32 = 9, + VFMT4_FIXED_32_32 = 10, + VFMT4_FIXED_32_32_32 = 11, + VFMT4_FIXED_32_32_32_32 = 12, + VFMT4_SHORT_16 = 16, + VFMT4_SHORT_16_16 = 17, + VFMT4_SHORT_16_16_16 = 18, + VFMT4_SHORT_16_16_16_16 = 19, + VFMT4_USHORT_16 = 20, + VFMT4_USHORT_16_16 = 21, + VFMT4_USHORT_16_16_16 = 22, + VFMT4_USHORT_16_16_16_16 = 23, + VFMT4_NORM_SHORT_16 = 24, + VFMT4_NORM_SHORT_16_16 = 25, + VFMT4_NORM_SHORT_16_16_16 = 26, + VFMT4_NORM_SHORT_16_16_16_16 = 27, + VFMT4_NORM_USHORT_16 = 28, + VFMT4_NORM_USHORT_16_16 = 29, + VFMT4_NORM_USHORT_16_16_16 = 30, + VFMT4_NORM_USHORT_16_16_16_16 = 31, + VFMT4_UBYTE_8 = 40, + VFMT4_UBYTE_8_8 = 41, + VFMT4_UBYTE_8_8_8 = 42, + VFMT4_UBYTE_8_8_8_8 = 43, + VFMT4_NORM_UBYTE_8 = 44, + VFMT4_NORM_UBYTE_8_8 = 45, + VFMT4_NORM_UBYTE_8_8_8 = 46, + VFMT4_NORM_UBYTE_8_8_8_8 = 47, + VFMT4_BYTE_8 = 48, + VFMT4_BYTE_8_8 = 49, + VFMT4_BYTE_8_8_8 = 50, + VFMT4_BYTE_8_8_8_8 = 51, + VFMT4_NORM_BYTE_8 = 52, + VFMT4_NORM_BYTE_8_8 = 53, + VFMT4_NORM_BYTE_8_8_8 = 54, + VFMT4_NORM_BYTE_8_8_8_8 = 55, + VFMT4_UINT_10_10_10_2 = 60, + VFMT4_NORM_UINT_10_10_10_2 = 61, + VFMT4_INT_10_10_10_2 = 62, + VFMT4_NORM_INT_10_10_10_2 = 63, +}; + +enum a4xx_tex_fmt { + TFMT4_NORM_USHORT_565 = 11, + TFMT4_NORM_USHORT_5551 = 10, + TFMT4_NORM_USHORT_4444 = 8, + TFMT4_NORM_UINT_X8Z24 = 71, + TFMT4_NORM_UINT_2_10_10_10 = 33, + TFMT4_NORM_UINT_A8 = 3, + TFMT4_NORM_UINT_L8_A8 = 13, + TFMT4_NORM_UINT_8 = 4, + TFMT4_NORM_UINT_8_8_8_8 = 28, + TFMT4_FLOAT_16 = 20, + TFMT4_FLOAT_16_16 = 40, + TFMT4_FLOAT_16_16_16_16 = 53, + TFMT4_FLOAT_32 = 43, + TFMT4_FLOAT_32_32 = 56, + TFMT4_FLOAT_32_32_32_32 = 63, +}; + +enum a4xx_depth_format { + DEPTH4_NONE = 0, + DEPTH4_16 = 1, + DEPTH4_24_8 = 2, +}; + +enum a4xx_tex_filter { + A4XX_TEX_NEAREST = 0, + A4XX_TEX_LINEAR = 1, +}; + +enum a4xx_tex_clamp { + A4XX_TEX_REPEAT = 0, + A4XX_TEX_CLAMP_TO_EDGE = 1, + A4XX_TEX_MIRROR_REPEAT = 2, + A4XX_TEX_CLAMP_NONE = 3, +}; + +enum a4xx_tex_swiz { + A4XX_TEX_X = 0, + A4XX_TEX_Y = 1, + A4XX_TEX_Z = 2, + A4XX_TEX_W = 3, + A4XX_TEX_ZERO = 4, + A4XX_TEX_ONE = 5, +}; + +enum a4xx_tex_type { + A4XX_TEX_1D = 0, + A4XX_TEX_2D = 1, + A4XX_TEX_CUBE = 2, + A4XX_TEX_3D = 3, +}; + +#define A4XX_CGC_HLSQ_EARLY_CYC__MASK 0x00700000 +#define A4XX_CGC_HLSQ_EARLY_CYC__SHIFT 20 +static inline uint32_t A4XX_CGC_HLSQ_EARLY_CYC(uint32_t val) +{ + return ((val) << A4XX_CGC_HLSQ_EARLY_CYC__SHIFT) & A4XX_CGC_HLSQ_EARLY_CYC__MASK; +} +#define A4XX_INT0_RBBM_GPU_IDLE 0x00000001 +#define A4XX_INT0_RBBM_AHB_ERROR 0x00000002 +#define A4XX_INT0_RBBM_REG_TIMEOUT 0x00000004 +#define A4XX_INT0_RBBM_ME_MS_TIMEOUT 0x00000008 +#define A4XX_INT0_RBBM_PFP_MS_TIMEOUT 0x00000010 +#define A4XX_INT0_RBBM_ATB_BUS_OVERFLOW 0x00000020 +#define A4XX_INT0_VFD_ERROR 0x00000040 +#define A4XX_INT0_CP_SW_INT 0x00000080 +#define A4XX_INT0_CP_T0_PACKET_IN_IB 0x00000100 +#define A4XX_INT0_CP_OPCODE_ERROR 0x00000200 +#define A4XX_INT0_CP_RESERVED_BIT_ERROR 0x00000400 +#define A4XX_INT0_CP_HW_FAULT 0x00000800 +#define A4XX_INT0_CP_DMA 0x00001000 +#define A4XX_INT0_CP_IB2_INT 0x00002000 +#define A4XX_INT0_CP_IB1_INT 0x00004000 +#define A4XX_INT0_CP_RB_INT 0x00008000 +#define A4XX_INT0_CP_REG_PROTECT_FAULT 0x00010000 +#define A4XX_INT0_CP_RB_DONE_TS 0x00020000 +#define A4XX_INT0_CP_VS_DONE_TS 0x00040000 +#define A4XX_INT0_CP_PS_DONE_TS 0x00080000 +#define A4XX_INT0_CACHE_FLUSH_TS 0x00100000 +#define A4XX_INT0_CP_AHB_ERROR_HALT 0x00200000 +#define A4XX_INT0_MISC_HANG_DETECT 0x01000000 +#define A4XX_INT0_UCHE_OOB_ACCESS 0x02000000 +#define REG_A4XX_RB_GMEM_BASE_ADDR 0x00000cc0 + +#define REG_A4XX_RB_PERFCTR_RB_SEL_0 0x00000cc7 + +#define REG_A4XX_RB_PERFCTR_RB_SEL_1 0x00000cc8 + +#define REG_A4XX_RB_PERFCTR_RB_SEL_2 0x00000cc9 + +#define REG_A4XX_RB_PERFCTR_RB_SEL_3 0x00000cca + +#define REG_A4XX_RB_PERFCTR_RB_SEL_4 0x00000ccb + +#define REG_A4XX_RB_PERFCTR_RB_SEL_5 0x00000ccc + +#define REG_A4XX_RB_PERFCTR_RB_SEL_6 0x00000ccd + +#define REG_A4XX_RB_PERFCTR_RB_SEL_7 0x00000cce + +#define REG_A4XX_RB_PERFCTR_CCU_SEL_3 0x00000cd2 + +#define REG_A4XX_RB_FRAME_BUFFER_DIMENSION 0x00000ce0 +#define A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH__MASK 0x00003fff +#define A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH__SHIFT 0 +static inline uint32_t A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH(uint32_t val) +{ + return ((val) << A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH__SHIFT) & A4XX_RB_FRAME_BUFFER_DIMENSION_WIDTH__MASK; +} +#define A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT__MASK 0x3fff0000 +#define A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT__SHIFT 16 +static inline uint32_t A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT(uint32_t val) +{ + return ((val) << A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT__SHIFT) & A4XX_RB_FRAME_BUFFER_DIMENSION_HEIGHT__MASK; +} + +#define REG_A4XX_RB_CLEAR_COLOR_DW0 0x000020cc + +#define REG_A4XX_RB_CLEAR_COLOR_DW1 0x000020cd + +#define REG_A4XX_RB_CLEAR_COLOR_DW2 0x000020ce + +#define REG_A4XX_RB_CLEAR_COLOR_DW3 0x000020cf + +#define REG_A4XX_RB_MODE_CONTROL 0x000020a0 +#define A4XX_RB_MODE_CONTROL_WIDTH__MASK 0x0000003f +#define A4XX_RB_MODE_CONTROL_WIDTH__SHIFT 0 +static inline uint32_t A4XX_RB_MODE_CONTROL_WIDTH(uint32_t val) +{ + return ((val >> 5) << A4XX_RB_MODE_CONTROL_WIDTH__SHIFT) & A4XX_RB_MODE_CONTROL_WIDTH__MASK; +} +#define A4XX_RB_MODE_CONTROL_HEIGHT__MASK 0x00003f00 +#define A4XX_RB_MODE_CONTROL_HEIGHT__SHIFT 8 +static inline uint32_t A4XX_RB_MODE_CONTROL_HEIGHT(uint32_t val) +{ + return ((val >> 5) << A4XX_RB_MODE_CONTROL_HEIGHT__SHIFT) & A4XX_RB_MODE_CONTROL_HEIGHT__MASK; +} + +#define REG_A4XX_RB_RENDER_CONTROL 0x000020a1 +#define A4XX_RB_RENDER_CONTROL_BINNING_PASS 0x00000001 +#define A4XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE 0x00000020 + +#define REG_A4XX_RB_MSAA_CONTROL 0x000020a2 +#define A4XX_RB_MSAA_CONTROL_DISABLE 0x00001000 +#define A4XX_RB_MSAA_CONTROL_SAMPLES__MASK 0x0000e000 +#define A4XX_RB_MSAA_CONTROL_SAMPLES__SHIFT 13 +static inline uint32_t A4XX_RB_MSAA_CONTROL_SAMPLES(uint32_t val) +{ + return ((val) << A4XX_RB_MSAA_CONTROL_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL_SAMPLES__MASK; +} + +#define REG_A4XX_RB_MSAA_CONTROL2 0x000020a3 +#define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK 0x00000380 +#define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT 7 +static inline uint32_t A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES(uint32_t val) +{ + return ((val) << A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK; +} +#define A4XX_RB_MSAA_CONTROL2_VARYING 0x00001000 + +static inline uint32_t REG_A4XX_RB_MRT(uint32_t i0) { return 0x000020a4 + 0x5*i0; } + +static inline uint32_t REG_A4XX_RB_MRT_CONTROL(uint32_t i0) { return 0x000020a4 + 0x5*i0; } +#define A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE 0x00000008 +#define A4XX_RB_MRT_CONTROL_BLEND 0x00000010 +#define A4XX_RB_MRT_CONTROL_BLEND2 0x00000020 +#define A4XX_RB_MRT_CONTROL_FASTCLEAR 0x00000400 +#define A4XX_RB_MRT_CONTROL_B11 0x00000800 +#define A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK 0x0f000000 +#define A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__SHIFT 24 +static inline uint32_t A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(uint32_t val) +{ + return ((val) << A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__SHIFT) & A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK; +} + +static inline uint32_t REG_A4XX_RB_MRT_BUF_INFO(uint32_t i0) { return 0x000020a5 + 0x5*i0; } +#define A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK 0x0000003f +#define A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT__SHIFT 0 +static inline uint32_t A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT(enum a4xx_color_fmt val) +{ + return ((val) << A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT__SHIFT) & A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK; +} +#define A4XX_RB_MRT_BUF_INFO_DITHER_MODE__MASK 0x00000600 +#define A4XX_RB_MRT_BUF_INFO_DITHER_MODE__SHIFT 9 +static inline uint32_t A4XX_RB_MRT_BUF_INFO_DITHER_MODE(enum adreno_rb_dither_mode val) +{ + return ((val) << A4XX_RB_MRT_BUF_INFO_DITHER_MODE__SHIFT) & A4XX_RB_MRT_BUF_INFO_DITHER_MODE__MASK; +} +#define A4XX_RB_MRT_BUF_INFO_COLOR_SWAP__MASK 0x00001800 +#define A4XX_RB_MRT_BUF_INFO_COLOR_SWAP__SHIFT 11 +static inline uint32_t A4XX_RB_MRT_BUF_INFO_COLOR_SWAP(enum a3xx_color_swap val) +{ + return ((val) << A4XX_RB_MRT_BUF_INFO_COLOR_SWAP__SHIFT) & A4XX_RB_MRT_BUF_INFO_COLOR_SWAP__MASK; +} +#define A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__MASK 0x007fc000 +#define A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__SHIFT 14 +static inline uint32_t A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(uint32_t val) +{ + return ((val >> 4) << A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__SHIFT) & A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__MASK; +} + +static inline uint32_t REG_A4XX_RB_MRT_BASE(uint32_t i0) { return 0x000020a6 + 0x5*i0; } + +static inline uint32_t REG_A4XX_RB_MRT_CONTROL3(uint32_t i0) { return 0x000020a7 + 0x5*i0; } +#define A4XX_RB_MRT_CONTROL3_STRIDE__MASK 0x0001fff8 +#define A4XX_RB_MRT_CONTROL3_STRIDE__SHIFT 3 +static inline uint32_t A4XX_RB_MRT_CONTROL3_STRIDE(uint32_t val) +{ + return ((val) << A4XX_RB_MRT_CONTROL3_STRIDE__SHIFT) & A4XX_RB_MRT_CONTROL3_STRIDE__MASK; +} + +static inline uint32_t REG_A4XX_RB_MRT_BLEND_CONTROL(uint32_t i0) { return 0x000020a8 + 0x5*i0; } +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__MASK 0x0000001f +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__SHIFT 0 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(enum adreno_rb_blend_factor val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__MASK; +} +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK 0x000000e0 +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT 5 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(enum a4xx_rb_blend_opcode val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK; +} +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__MASK 0x00001f00 +#define A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__SHIFT 8 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(enum adreno_rb_blend_factor val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__MASK; +} +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__MASK 0x001f0000 +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__SHIFT 16 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(enum adreno_rb_blend_factor val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__MASK; +} +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK 0x00e00000 +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT 21 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(enum a4xx_rb_blend_opcode val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK; +} +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK 0x1f000000 +#define A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT 24 +static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(enum adreno_rb_blend_factor val) +{ + return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK; +} + +#define REG_A4XX_RB_ALPHA_CONTROL 0x000020f8 +#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST 0x00000100 +#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__MASK 0x00000e00 +#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__SHIFT 9 +static inline uint32_t A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(enum adreno_compare_func val) +{ + return ((val) << A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__SHIFT) & A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__MASK; +} + +#define REG_A4XX_RB_FS_OUTPUT 0x000020f9 +#define A4XX_RB_FS_OUTPUT_ENABLE_COLOR_PIPE 0x00000001 +#define A4XX_RB_FS_OUTPUT_FAST_CLEAR 0x00000100 +#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK 0xffff0000 +#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT 16 +static inline uint32_t A4XX_RB_FS_OUTPUT_SAMPLE_MASK(uint32_t val) +{ + return ((val) << A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT) & A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK; +} + +#define REG_A4XX_RB_RENDER_CONTROL3 0x000020fb +#define A4XX_RB_RENDER_CONTROL3_COMPONENT_ENABLE__MASK 0x0000001f +#define A4XX_RB_RENDER_CONTROL3_COMPONENT_ENABLE__SHIFT 0 +static inline uint32_t A4XX_RB_RENDER_CONTROL3_COMPONENT_ENABLE(uint32_t val) +{ + return ((val) << A4XX_RB_RENDER_CONTROL3_COMPONENT_ENABLE__SHIFT) & A4XX_RB_RENDER_CONTROL3_COMPONENT_ENABLE__MASK; +} + +#define REG_A4XX_RB_COPY_CONTROL 0x000020fc +#define A4XX_RB_COPY_CONTROL_MSAA_RESOLVE__MASK 0x00000003 +#define A4XX_RB_COPY_CONTROL_MSAA_RESOLVE__SHIFT 0 +static inline uint32_t A4XX_RB_COPY_CONTROL_MSAA_RESOLVE(enum a3xx_msaa_samples val) +{ + return ((val) << A4XX_RB_COPY_CONTROL_MSAA_RESOLVE__SHIFT) & A4XX_RB_COPY_CONTROL_MSAA_RESOLVE__MASK; +} +#define A4XX_RB_COPY_CONTROL_MODE__MASK 0x00000070 +#define A4XX_RB_COPY_CONTROL_MODE__SHIFT 4 +static inline uint32_t A4XX_RB_COPY_CONTROL_MODE(enum adreno_rb_copy_control_mode val) +{ + return ((val) << A4XX_RB_COPY_CONTROL_MODE__SHIFT) & A4XX_RB_COPY_CONTROL_MODE__MASK; +} +#define A4XX_RB_COPY_CONTROL_FASTCLEAR__MASK 0x00000f00 +#define A4XX_RB_COPY_CONTROL_FASTCLEAR__SHIFT 8 +static inline uint32_t A4XX_RB_COPY_CONTROL_FASTCLEAR(uint32_t val) +{ + return ((val) << A4XX_RB_COPY_CONTROL_FASTCLEAR__SHIFT) & A4XX_RB_COPY_CONTROL_FASTCLEAR__MASK; +} +#define A4XX_RB_COPY_CONTROL_GMEM_BASE__MASK 0xffffc000 +#define A4XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT 14 +static inline uint32_t A4XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val) +{ + return ((val >> 14) << A4XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT) & A4XX_RB_COPY_CONTROL_GMEM_BASE__MASK; +} + +#define REG_A4XX_RB_COPY_DEST_BASE 0x000020fd +#define A4XX_RB_COPY_DEST_BASE_BASE__MASK 0xfffffff0 +#define A4XX_RB_COPY_DEST_BASE_BASE__SHIFT 4 +static inline uint32_t A4XX_RB_COPY_DEST_BASE_BASE(uint32_t val) +{ + return ((val >> 4) << A4XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A4XX_RB_COPY_DEST_BASE_BASE__MASK; +} + +#define REG_A4XX_RB_COPY_DEST_PITCH 0x000020fe +#define A4XX_RB_COPY_DEST_PITCH_PITCH__MASK 0xffffffff +#define A4XX_RB_COPY_DEST_PITCH_PITCH__SHIFT 0 +static inline uint32_t A4XX_RB_COPY_DEST_PITCH_PITCH(uint32_t val) +{ + return ((val >> 5) << A4XX_RB_COPY_DEST_PITCH_PITCH__SHIFT) & A4XX_RB_COPY_DEST_PITCH_PITCH__MASK; +} + +#define REG_A4XX_RB_COPY_DEST_INFO 0x000020ff +#define A4XX_RB_COPY_DEST_INFO_FORMAT__MASK 0x000000fc +#define A4XX_RB_COPY_DEST_INFO_FORMAT__SHIFT 2 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_FORMAT(enum a4xx_color_fmt val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_FORMAT__SHIFT) & A4XX_RB_COPY_DEST_INFO_FORMAT__MASK; +} +#define A4XX_RB_COPY_DEST_INFO_SWAP__MASK 0x00000300 +#define A4XX_RB_COPY_DEST_INFO_SWAP__SHIFT 8 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_SWAP(enum a3xx_color_swap val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A4XX_RB_COPY_DEST_INFO_SWAP__MASK; +} +#define A4XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK 0x00000c00 +#define A4XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT 10 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_DITHER_MODE(enum adreno_rb_dither_mode val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT) & A4XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK; +} +#define A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__MASK 0x0003c000 +#define A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__SHIFT 14 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(uint32_t val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__SHIFT) & A4XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__MASK; +} +#define A4XX_RB_COPY_DEST_INFO_ENDIAN__MASK 0x001c0000 +#define A4XX_RB_COPY_DEST_INFO_ENDIAN__SHIFT 18 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_ENDIAN(enum adreno_rb_surface_endian val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_ENDIAN__SHIFT) & A4XX_RB_COPY_DEST_INFO_ENDIAN__MASK; +} +#define A4XX_RB_COPY_DEST_INFO_TILE__MASK 0x03000000 +#define A4XX_RB_COPY_DEST_INFO_TILE__SHIFT 24 +static inline uint32_t A4XX_RB_COPY_DEST_INFO_TILE(enum a4xx_tile_mode val) +{ + return ((val) << A4XX_RB_COPY_DEST_INFO_TILE__SHIFT) & A4XX_RB_COPY_DEST_INFO_TILE__MASK; +} + +#define REG_A4XX_RB_FS_OUTPUT_REG 0x00002100 +#define A4XX_RB_FS_OUTPUT_REG_COLOR_PIPE_ENABLE 0x00000001 +#define A4XX_RB_FS_OUTPUT_REG_FRAG_WRITES_Z 0x00000020 + +#define REG_A4XX_RB_DEPTH_CONTROL 0x00002101 +#define A4XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z 0x00000001 +#define A4XX_RB_DEPTH_CONTROL_Z_ENABLE 0x00000002 +#define A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE 0x00000004 +#define A4XX_RB_DEPTH_CONTROL_ZFUNC__MASK 0x00000070 +#define A4XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT 4 +static inline uint32_t A4XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val) +{ + return ((val) << A4XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT) & A4XX_RB_DEPTH_CONTROL_ZFUNC__MASK; +} +#define A4XX_RB_DEPTH_CONTROL_BF_ENABLE 0x00000080 +#define A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE 0x00010000 +#define A4XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE 0x80000000 + +#define REG_A4XX_RB_DEPTH_CLEAR 0x00002102 + +#define REG_A4XX_RB_DEPTH_INFO 0x00002103 +#define A4XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK 0x00000003 +#define A4XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT 0 +static inline uint32_t A4XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum a4xx_depth_format val) +{ + return ((val) << A4XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT) & A4XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK; +} +#define A4XX_RB_DEPTH_INFO_DEPTH_BASE__MASK 0xfffff000 +#define A4XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT 12 +static inline uint32_t A4XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val) +{ + return ((val >> 12) << A4XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A4XX_RB_DEPTH_INFO_DEPTH_BASE__MASK; +} + +#define REG_A4XX_RB_DEPTH_PITCH 0x00002104 +#define A4XX_RB_DEPTH_PITCH__MASK 0xffffffff +#define A4XX_RB_DEPTH_PITCH__SHIFT 0 +static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val) +{ + return ((val >> 4) << A4XX_RB_DEPTH_PITCH__SHIFT) & A4XX_RB_DEPTH_PITCH__MASK; +} + +#define REG_A4XX_RB_DEPTH_PITCH2 0x00002105 +#define A4XX_RB_DEPTH_PITCH2__MASK 0xffffffff +#define A4XX_RB_DEPTH_PITCH2__SHIFT 0 +static inline uint32_t A4XX_RB_DEPTH_PITCH2(uint32_t val) +{ + return ((val >> 4) << A4XX_RB_DEPTH_PITCH2__SHIFT) & A4XX_RB_DEPTH_PITCH2__MASK; +} + +#define REG_A4XX_RB_STENCIL_CONTROL 0x00002106 +#define A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE 0x00000001 +#define A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF 0x00000002 +#define A4XX_RB_STENCIL_CONTROL_STENCIL_READ 0x00000004 +#define A4XX_RB_STENCIL_CONTROL_FUNC__MASK 0x00000700 +#define A4XX_RB_STENCIL_CONTROL_FUNC__SHIFT 8 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_FUNC(enum adreno_compare_func val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_FUNC__SHIFT) & A4XX_RB_STENCIL_CONTROL_FUNC__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_FAIL__MASK 0x00003800 +#define A4XX_RB_STENCIL_CONTROL_FAIL__SHIFT 11 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_FAIL(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_FAIL__SHIFT) & A4XX_RB_STENCIL_CONTROL_FAIL__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_ZPASS__MASK 0x0001c000 +#define A4XX_RB_STENCIL_CONTROL_ZPASS__SHIFT 14 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_ZPASS(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_ZPASS__SHIFT) & A4XX_RB_STENCIL_CONTROL_ZPASS__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_ZFAIL__MASK 0x000e0000 +#define A4XX_RB_STENCIL_CONTROL_ZFAIL__SHIFT 17 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_ZFAIL(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_ZFAIL__SHIFT) & A4XX_RB_STENCIL_CONTROL_ZFAIL__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_FUNC_BF__MASK 0x00700000 +#define A4XX_RB_STENCIL_CONTROL_FUNC_BF__SHIFT 20 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_FUNC_BF(enum adreno_compare_func val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_FUNC_BF__SHIFT) & A4XX_RB_STENCIL_CONTROL_FUNC_BF__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_FAIL_BF__MASK 0x03800000 +#define A4XX_RB_STENCIL_CONTROL_FAIL_BF__SHIFT 23 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_FAIL_BF(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_FAIL_BF__SHIFT) & A4XX_RB_STENCIL_CONTROL_FAIL_BF__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK 0x1c000000 +#define A4XX_RB_STENCIL_CONTROL_ZPASS_BF__SHIFT 26 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_ZPASS_BF(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_ZPASS_BF__SHIFT) & A4XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK; +} +#define A4XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK 0xe0000000 +#define A4XX_RB_STENCIL_CONTROL_ZFAIL_BF__SHIFT 29 +static inline uint32_t A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(enum adreno_stencil_op val) +{ + return ((val) << A4XX_RB_STENCIL_CONTROL_ZFAIL_BF__SHIFT) & A4XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK; +} + +#define REG_A4XX_RB_STENCIL_CONTROL2 0x00002107 +#define A4XX_RB_STENCIL_CONTROL2_STENCIL_BUFFER 0x00000001 + +#define REG_A4XX_RB_STENCILREFMASK 0x0000210b +#define A4XX_RB_STENCILREFMASK_STENCILREF__MASK 0x000000ff +#define A4XX_RB_STENCILREFMASK_STENCILREF__SHIFT 0 +static inline uint32_t A4XX_RB_STENCILREFMASK_STENCILREF(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_STENCILREF__SHIFT) & A4XX_RB_STENCILREFMASK_STENCILREF__MASK; +} +#define A4XX_RB_STENCILREFMASK_STENCILMASK__MASK 0x0000ff00 +#define A4XX_RB_STENCILREFMASK_STENCILMASK__SHIFT 8 +static inline uint32_t A4XX_RB_STENCILREFMASK_STENCILMASK(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_STENCILMASK__SHIFT) & A4XX_RB_STENCILREFMASK_STENCILMASK__MASK; +} +#define A4XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK 0x00ff0000 +#define A4XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT 16 +static inline uint32_t A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT) & A4XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK; +} + +#define REG_A4XX_RB_STENCILREFMASK_BF 0x0000210c +#define A4XX_RB_STENCILREFMASK_BF_STENCILREF__MASK 0x000000ff +#define A4XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT 0 +static inline uint32_t A4XX_RB_STENCILREFMASK_BF_STENCILREF(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT) & A4XX_RB_STENCILREFMASK_BF_STENCILREF__MASK; +} +#define A4XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK 0x0000ff00 +#define A4XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT 8 +static inline uint32_t A4XX_RB_STENCILREFMASK_BF_STENCILMASK(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT) & A4XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK; +} +#define A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK 0x00ff0000 +#define A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT 16 +static inline uint32_t A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(uint32_t val) +{ + return ((val) << A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT) & A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK; +} + +#define REG_A4XX_RB_BIN_OFFSET 0x0000210d +#define A4XX_RB_BIN_OFFSET_WINDOW_OFFSET_DISABLE 0x80000000 +#define A4XX_RB_BIN_OFFSET_X__MASK 0x00007fff +#define A4XX_RB_BIN_OFFSET_X__SHIFT 0 +static inline uint32_t A4XX_RB_BIN_OFFSET_X(uint32_t val) +{ + return ((val) << A4XX_RB_BIN_OFFSET_X__SHIFT) & A4XX_RB_BIN_OFFSET_X__MASK; +} +#define A4XX_RB_BIN_OFFSET_Y__MASK 0x7fff0000 +#define A4XX_RB_BIN_OFFSET_Y__SHIFT 16 +static inline uint32_t A4XX_RB_BIN_OFFSET_Y(uint32_t val) +{ + return ((val) << A4XX_RB_BIN_OFFSET_Y__SHIFT) & A4XX_RB_BIN_OFFSET_Y__MASK; +} + +#define REG_A4XX_RB_VPORT_Z_CLAMP_MAX_15 0x0000213f + +#define REG_A4XX_RBBM_HW_VERSION 0x00000000 + +#define REG_A4XX_RBBM_HW_CONFIGURATION 0x00000002 + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_TP(uint32_t i0) { return 0x00000004 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_TP_REG(uint32_t i0) { return 0x00000004 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_TP(uint32_t i0) { return 0x00000008 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_TP_REG(uint32_t i0) { return 0x00000008 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_TP(uint32_t i0) { return 0x0000000c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_TP_REG(uint32_t i0) { return 0x0000000c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_TP(uint32_t i0) { return 0x00000010 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_TP_REG(uint32_t i0) { return 0x00000010 + 0x1*i0; } + +#define REG_A4XX_RBBM_CLOCK_CTL_UCHE 0x00000014 + +#define REG_A4XX_RBBM_CLOCK_CTL2_UCHE 0x00000015 + +#define REG_A4XX_RBBM_CLOCK_CTL3_UCHE 0x00000016 + +#define REG_A4XX_RBBM_CLOCK_CTL4_UCHE 0x00000017 + +#define REG_A4XX_RBBM_CLOCK_HYST_UCHE 0x00000018 + +#define REG_A4XX_RBBM_CLOCK_DELAY_UCHE 0x00000019 + +#define REG_A4XX_RBBM_CLOCK_MODE_GPC 0x0000001a + +#define REG_A4XX_RBBM_CLOCK_DELAY_GPC 0x0000001b + +#define REG_A4XX_RBBM_CLOCK_HYST_GPC 0x0000001c + +#define REG_A4XX_RBBM_CLOCK_CTL_TSE_RAS_RBBM 0x0000001d + +#define REG_A4XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM 0x0000001e + +#define REG_A4XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM 0x0000001f + +#define REG_A4XX_RBBM_CLOCK_CTL 0x00000020 + +#define REG_A4XX_RBBM_SP_HYST_CNT 0x00000021 + +#define REG_A4XX_RBBM_SW_RESET_CMD 0x00000022 + +#define REG_A4XX_RBBM_AHB_CTL0 0x00000023 + +#define REG_A4XX_RBBM_AHB_CTL1 0x00000024 + +#define REG_A4XX_RBBM_AHB_CMD 0x00000025 + +#define REG_A4XX_RBBM_RB_SUB_BLOCK_SEL_CTL 0x00000026 + +#define REG_A4XX_RBBM_RAM_ACC_63_32 0x00000028 + +#define REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL 0x0000002b + +#define REG_A4XX_RBBM_INTERFACE_HANG_INT_CTL 0x0000002f + +#define REG_A4XX_RBBM_INTERFACE_HANG_MASK_CTL4 0x00000034 + +#define REG_A4XX_RBBM_INT_CLEAR_CMD 0x00000036 + +#define REG_A4XX_RBBM_INT_0_MASK 0x00000037 + +#define REG_A4XX_RBBM_RBBM_CTL 0x0000003e + +#define REG_A4XX_RBBM_AHB_DEBUG_CTL 0x0000003f + +#define REG_A4XX_RBBM_VBIF_DEBUG_CTL 0x00000041 + +#define REG_A4XX_RBBM_CLOCK_CTL2 0x00000042 + +#define REG_A4XX_RBBM_BLOCK_SW_RESET_CMD 0x00000045 + +#define REG_A4XX_RBBM_RESET_CYCLES 0x00000047 + +#define REG_A4XX_RBBM_EXT_TRACE_BUS_CTL 0x00000049 + +#define REG_A4XX_RBBM_CFG_DEBBUS_SEL_A 0x0000004a + +#define REG_A4XX_RBBM_CFG_DEBBUS_SEL_B 0x0000004b + +#define REG_A4XX_RBBM_CFG_DEBBUS_SEL_C 0x0000004c + +#define REG_A4XX_RBBM_CFG_DEBBUS_SEL_D 0x0000004d + +#define REG_A4XX_RBBM_PERFCTR_CP_0_LO 0x0000009c + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_SP(uint32_t i0) { return 0x00000068 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_SP_REG(uint32_t i0) { return 0x00000068 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_SP(uint32_t i0) { return 0x0000006c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_SP_REG(uint32_t i0) { return 0x0000006c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_SP(uint32_t i0) { return 0x00000070 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_SP_REG(uint32_t i0) { return 0x00000070 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_SP(uint32_t i0) { return 0x00000074 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_SP_REG(uint32_t i0) { return 0x00000074 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_RB(uint32_t i0) { return 0x00000078 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_RB_REG(uint32_t i0) { return 0x00000078 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_RB(uint32_t i0) { return 0x0000007c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL2_RB_REG(uint32_t i0) { return 0x0000007c + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(uint32_t i0) { return 0x00000082 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU_REG(uint32_t i0) { return 0x00000082 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(uint32_t i0) { return 0x00000086 + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU_REG(uint32_t i0) { return 0x00000086 + 0x1*i0; } + +#define REG_A4XX_RBBM_CLOCK_HYST_COM_DCOM 0x00000080 + +#define REG_A4XX_RBBM_CLOCK_CTL_COM_DCOM 0x00000081 + +#define REG_A4XX_RBBM_CLOCK_CTL_HLSQ 0x0000008a + +#define REG_A4XX_RBBM_CLOCK_HYST_HLSQ 0x0000008b + +#define REG_A4XX_RBBM_CLOCK_DELAY_HLSQ 0x0000008c + +#define REG_A4XX_RBBM_CLOCK_DELAY_COM_DCOM 0x0000008d + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(uint32_t i0) { return 0x0000008e + 0x1*i0; } + +static inline uint32_t REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1_REG(uint32_t i0) { return 0x0000008e + 0x1*i0; } + +#define REG_A4XX_RBBM_PERFCTR_PWR_1_LO 0x00000168 + +#define REG_A4XX_RBBM_PERFCTR_CTL 0x00000170 + +#define REG_A4XX_RBBM_PERFCTR_LOAD_CMD0 0x00000171 + +#define REG_A4XX_RBBM_PERFCTR_LOAD_CMD1 0x00000172 + +#define REG_A4XX_RBBM_PERFCTR_LOAD_CMD2 0x00000173 + +#define REG_A4XX_RBBM_PERFCTR_LOAD_VALUE_LO 0x00000174 + +#define REG_A4XX_RBBM_PERFCTR_LOAD_VALUE_HI 0x00000175 + +#define REG_A4XX_RBBM_GPU_BUSY_MASKED 0x0000017a + +#define REG_A4XX_RBBM_INT_0_STATUS 0x0000017d + +#define REG_A4XX_RBBM_CLOCK_STATUS 0x00000182 + +#define REG_A4XX_RBBM_AHB_STATUS 0x00000189 + +#define REG_A4XX_RBBM_AHB_ME_SPLIT_STATUS 0x0000018c + +#define REG_A4XX_RBBM_AHB_PFP_SPLIT_STATUS 0x0000018d + +#define REG_A4XX_RBBM_AHB_ERROR_STATUS 0x0000018f + +#define REG_A4XX_RBBM_STATUS 0x00000191 +#define A4XX_RBBM_STATUS_HI_BUSY 0x00000001 +#define A4XX_RBBM_STATUS_CP_ME_BUSY 0x00000002 +#define A4XX_RBBM_STATUS_CP_PFP_BUSY 0x00000004 +#define A4XX_RBBM_STATUS_CP_NRT_BUSY 0x00004000 +#define A4XX_RBBM_STATUS_VBIF_BUSY 0x00008000 +#define A4XX_RBBM_STATUS_TSE_BUSY 0x00010000 +#define A4XX_RBBM_STATUS_RAS_BUSY 0x00020000 +#define A4XX_RBBM_STATUS_RB_BUSY 0x00040000 +#define A4XX_RBBM_STATUS_PC_DCALL_BUSY 0x00080000 +#define A4XX_RBBM_STATUS_PC_VSD_BUSY 0x00100000 +#define A4XX_RBBM_STATUS_VFD_BUSY 0x00200000 +#define A4XX_RBBM_STATUS_VPC_BUSY 0x00400000 +#define A4XX_RBBM_STATUS_UCHE_BUSY 0x00800000 +#define A4XX_RBBM_STATUS_SP_BUSY 0x01000000 +#define A4XX_RBBM_STATUS_TPL1_BUSY 0x02000000 +#define A4XX_RBBM_STATUS_MARB_BUSY 0x04000000 +#define A4XX_RBBM_STATUS_VSC_BUSY 0x08000000 +#define A4XX_RBBM_STATUS_ARB_BUSY 0x10000000 +#define A4XX_RBBM_STATUS_HLSQ_BUSY 0x20000000 +#define A4XX_RBBM_STATUS_GPU_BUSY_NOHC 0x40000000 +#define A4XX_RBBM_STATUS_GPU_BUSY 0x80000000 + +#define REG_A4XX_RBBM_INTERFACE_RRDY_STATUS5 0x0000019f + +#define REG_A4XX_CP_SCRATCH_UMASK 0x00000228 + +#define REG_A4XX_CP_SCRATCH_ADDR 0x00000229 + +#define REG_A4XX_CP_RB_BASE 0x00000200 + +#define REG_A4XX_CP_RB_CNTL 0x00000201 + +#define REG_A4XX_CP_RB_WPTR 0x00000205 + +#define REG_A4XX_CP_RB_RPTR_ADDR 0x00000203 + +#define REG_A4XX_CP_RB_RPTR 0x00000204 + +#define REG_A4XX_CP_IB1_BASE 0x00000206 + +#define REG_A4XX_CP_IB1_BUFSZ 0x00000207 + +#define REG_A4XX_CP_IB2_BASE 0x00000208 + +#define REG_A4XX_CP_IB2_BUFSZ 0x00000209 + +#define REG_A4XX_CP_ME_RB_DONE_DATA 0x00000217 + +#define REG_A4XX_CP_QUEUE_THRESH2 0x00000219 + +#define REG_A4XX_CP_MERCIU_SIZE 0x0000021b + +#define REG_A4XX_CP_ROQ_ADDR 0x0000021c + +#define REG_A4XX_CP_ROQ_DATA 0x0000021d + +#define REG_A4XX_CP_MEQ_ADDR 0x0000021e + +#define REG_A4XX_CP_MEQ_DATA 0x0000021f + +#define REG_A4XX_CP_MERCIU_ADDR 0x00000220 + +#define REG_A4XX_CP_MERCIU_DATA 0x00000221 + +#define REG_A4XX_CP_MERCIU_DATA2 0x00000222 + +#define REG_A4XX_CP_PFP_UCODE_ADDR 0x00000223 + +#define REG_A4XX_CP_PFP_UCODE_DATA 0x00000224 + +#define REG_A4XX_CP_ME_RAM_WADDR 0x00000225 + +#define REG_A4XX_CP_ME_RAM_RADDR 0x00000226 + +#define REG_A4XX_CP_ME_RAM_DATA 0x00000227 + +#define REG_A4XX_CP_PREEMPT 0x0000022a + +#define REG_A4XX_CP_CNTL 0x0000022c + +#define REG_A4XX_CP_ME_CNTL 0x0000022d + +#define REG_A4XX_CP_DEBUG 0x0000022e + +#define REG_A4XX_CP_DEBUG_ECO_CONTROL 0x00000231 + +#define REG_A4XX_CP_DRAW_STATE_ADDR 0x00000232 + +#define REG_A4XX_CP_PROTECT_REG_0 0x00000240 + +static inline uint32_t REG_A4XX_CP_PROTECT(uint32_t i0) { return 0x00000240 + 0x1*i0; } + +static inline uint32_t REG_A4XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000240 + 0x1*i0; } + +#define REG_A4XX_CP_PROTECT_CTRL 0x00000250 + +#define REG_A4XX_CP_ST_BASE 0x000004c0 + +#define REG_A4XX_CP_STQ_AVAIL 0x000004ce + +#define REG_A4XX_CP_MERCIU_STAT 0x000004d0 + +#define REG_A4XX_CP_WFI_PEND_CTR 0x000004d2 + +#define REG_A4XX_CP_HW_FAULT 0x000004d8 + +#define REG_A4XX_CP_PROTECT_STATUS 0x000004da + +#define REG_A4XX_CP_EVENTS_IN_FLIGHT 0x000004dd + +#define REG_A4XX_CP_PERFCTR_CP_SEL_0 0x00000500 + +#define REG_A4XX_CP_PERFCOMBINER_SELECT 0x0000050b + +static inline uint32_t REG_A4XX_CP_SCRATCH(uint32_t i0) { return 0x00000578 + 0x1*i0; } + +static inline uint32_t REG_A4XX_CP_SCRATCH_REG(uint32_t i0) { return 0x00000578 + 0x1*i0; } + +#define REG_A4XX_SP_VS_STATUS 0x00000ec0 + +#define REG_A4XX_SP_PERFCTR_SP_SEL_11 0x00000ecf + +#define REG_A4XX_SP_SP_CTRL_REG 0x000022c0 +#define A4XX_SP_SP_CTRL_REG_BINNING_PASS 0x00080000 + +#define REG_A4XX_SP_INSTR_CACHE_CTRL 0x000022c1 + +#define REG_A4XX_SP_VS_CTRL_REG0 0x000022c4 +#define A4XX_SP_VS_CTRL_REG0_THREADMODE__MASK 0x00000001 +#define A4XX_SP_VS_CTRL_REG0_THREADMODE__SHIFT 0 +static inline uint32_t A4XX_SP_VS_CTRL_REG0_THREADMODE(enum a3xx_threadmode val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG0_THREADMODE__SHIFT) & A4XX_SP_VS_CTRL_REG0_THREADMODE__MASK; +} +#define A4XX_SP_VS_CTRL_REG0_VARYING 0x00000002 +#define A4XX_SP_VS_CTRL_REG0_CACHEINVALID 0x00000004 +#define A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 +#define A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 +static inline uint32_t A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A4XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__MASK; +} +#define A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__MASK 0x0003fc00 +#define A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT 10 +static inline uint32_t A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A4XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__MASK; +} +#define A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__MASK 0x000c0000 +#define A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__SHIFT 18 +static inline uint32_t A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP(uint32_t val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__SHIFT) & A4XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__MASK; +} +#define A4XX_SP_VS_CTRL_REG0_THREADSIZE__MASK 0x00100000 +#define A4XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT 20 +static inline uint32_t A4XX_SP_VS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT) & A4XX_SP_VS_CTRL_REG0_THREADSIZE__MASK; +} +#define A4XX_SP_VS_CTRL_REG0_SUPERTHREADMODE 0x00200000 +#define A4XX_SP_VS_CTRL_REG0_PIXLODENABLE 0x00400000 + +#define REG_A4XX_SP_VS_CTRL_REG1 0x000022c5 +#define A4XX_SP_VS_CTRL_REG1_CONSTLENGTH__MASK 0x000000ff +#define A4XX_SP_VS_CTRL_REG1_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_SP_VS_CTRL_REG1_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG1_CONSTLENGTH__SHIFT) & A4XX_SP_VS_CTRL_REG1_CONSTLENGTH__MASK; +} +#define A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK 0x7f000000 +#define A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__SHIFT 24 +static inline uint32_t A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(uint32_t val) +{ + return ((val) << A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__SHIFT) & A4XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK; +} + +#define REG_A4XX_SP_VS_PARAM_REG 0x000022c6 +#define A4XX_SP_VS_PARAM_REG_POSREGID__MASK 0x000000ff +#define A4XX_SP_VS_PARAM_REG_POSREGID__SHIFT 0 +static inline uint32_t A4XX_SP_VS_PARAM_REG_POSREGID(uint32_t val) +{ + return ((val) << A4XX_SP_VS_PARAM_REG_POSREGID__SHIFT) & A4XX_SP_VS_PARAM_REG_POSREGID__MASK; +} +#define A4XX_SP_VS_PARAM_REG_PSIZEREGID__MASK 0x0000ff00 +#define A4XX_SP_VS_PARAM_REG_PSIZEREGID__SHIFT 8 +static inline uint32_t A4XX_SP_VS_PARAM_REG_PSIZEREGID(uint32_t val) +{ + return ((val) << A4XX_SP_VS_PARAM_REG_PSIZEREGID__SHIFT) & A4XX_SP_VS_PARAM_REG_PSIZEREGID__MASK; +} +#define A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__MASK 0xfff00000 +#define A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__SHIFT 20 +static inline uint32_t A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(uint32_t val) +{ + return ((val) << A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__SHIFT) & A4XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__MASK; +} + +static inline uint32_t REG_A4XX_SP_VS_OUT(uint32_t i0) { return 0x000022c7 + 0x1*i0; } + +static inline uint32_t REG_A4XX_SP_VS_OUT_REG(uint32_t i0) { return 0x000022c7 + 0x1*i0; } +#define A4XX_SP_VS_OUT_REG_A_REGID__MASK 0x000001ff +#define A4XX_SP_VS_OUT_REG_A_REGID__SHIFT 0 +static inline uint32_t A4XX_SP_VS_OUT_REG_A_REGID(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OUT_REG_A_REGID__SHIFT) & A4XX_SP_VS_OUT_REG_A_REGID__MASK; +} +#define A4XX_SP_VS_OUT_REG_A_COMPMASK__MASK 0x00001e00 +#define A4XX_SP_VS_OUT_REG_A_COMPMASK__SHIFT 9 +static inline uint32_t A4XX_SP_VS_OUT_REG_A_COMPMASK(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OUT_REG_A_COMPMASK__SHIFT) & A4XX_SP_VS_OUT_REG_A_COMPMASK__MASK; +} +#define A4XX_SP_VS_OUT_REG_B_REGID__MASK 0x01ff0000 +#define A4XX_SP_VS_OUT_REG_B_REGID__SHIFT 16 +static inline uint32_t A4XX_SP_VS_OUT_REG_B_REGID(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OUT_REG_B_REGID__SHIFT) & A4XX_SP_VS_OUT_REG_B_REGID__MASK; +} +#define A4XX_SP_VS_OUT_REG_B_COMPMASK__MASK 0x1e000000 +#define A4XX_SP_VS_OUT_REG_B_COMPMASK__SHIFT 25 +static inline uint32_t A4XX_SP_VS_OUT_REG_B_COMPMASK(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OUT_REG_B_COMPMASK__SHIFT) & A4XX_SP_VS_OUT_REG_B_COMPMASK__MASK; +} + +static inline uint32_t REG_A4XX_SP_VS_VPC_DST(uint32_t i0) { return 0x000022d8 + 0x1*i0; } + +static inline uint32_t REG_A4XX_SP_VS_VPC_DST_REG(uint32_t i0) { return 0x000022d8 + 0x1*i0; } +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC0__MASK 0x000000ff +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC0__SHIFT 0 +static inline uint32_t A4XX_SP_VS_VPC_DST_REG_OUTLOC0(uint32_t val) +{ + return ((val) << A4XX_SP_VS_VPC_DST_REG_OUTLOC0__SHIFT) & A4XX_SP_VS_VPC_DST_REG_OUTLOC0__MASK; +} +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC1__MASK 0x0000ff00 +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC1__SHIFT 8 +static inline uint32_t A4XX_SP_VS_VPC_DST_REG_OUTLOC1(uint32_t val) +{ + return ((val) << A4XX_SP_VS_VPC_DST_REG_OUTLOC1__SHIFT) & A4XX_SP_VS_VPC_DST_REG_OUTLOC1__MASK; +} +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC2__MASK 0x00ff0000 +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC2__SHIFT 16 +static inline uint32_t A4XX_SP_VS_VPC_DST_REG_OUTLOC2(uint32_t val) +{ + return ((val) << A4XX_SP_VS_VPC_DST_REG_OUTLOC2__SHIFT) & A4XX_SP_VS_VPC_DST_REG_OUTLOC2__MASK; +} +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC3__MASK 0xff000000 +#define A4XX_SP_VS_VPC_DST_REG_OUTLOC3__SHIFT 24 +static inline uint32_t A4XX_SP_VS_VPC_DST_REG_OUTLOC3(uint32_t val) +{ + return ((val) << A4XX_SP_VS_VPC_DST_REG_OUTLOC3__SHIFT) & A4XX_SP_VS_VPC_DST_REG_OUTLOC3__MASK; +} + +#define REG_A4XX_SP_VS_OBJ_OFFSET_REG 0x000022e0 +#define A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 +#define A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT 16 +static inline uint32_t A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK 0xfe000000 +#define A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT 25 +static inline uint32_t A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A4XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK; +} + +#define REG_A4XX_SP_VS_OBJ_START 0x000022e1 + +#define REG_A4XX_SP_VS_PVT_MEM_PARAM 0x000022e2 + +#define REG_A4XX_SP_VS_PVT_MEM_ADDR 0x000022e3 + +#define REG_A4XX_SP_VS_LENGTH_REG 0x000022e5 + +#define REG_A4XX_SP_FS_CTRL_REG0 0x000022e8 +#define A4XX_SP_FS_CTRL_REG0_THREADMODE__MASK 0x00000001 +#define A4XX_SP_FS_CTRL_REG0_THREADMODE__SHIFT 0 +static inline uint32_t A4XX_SP_FS_CTRL_REG0_THREADMODE(enum a3xx_threadmode val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG0_THREADMODE__SHIFT) & A4XX_SP_FS_CTRL_REG0_THREADMODE__MASK; +} +#define A4XX_SP_FS_CTRL_REG0_VARYING 0x00000002 +#define A4XX_SP_FS_CTRL_REG0_CACHEINVALID 0x00000004 +#define A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 +#define A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 +static inline uint32_t A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A4XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__MASK; +} +#define A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__MASK 0x0003fc00 +#define A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT 10 +static inline uint32_t A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A4XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__MASK; +} +#define A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__MASK 0x000c0000 +#define A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__SHIFT 18 +static inline uint32_t A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP(uint32_t val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__SHIFT) & A4XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__MASK; +} +#define A4XX_SP_FS_CTRL_REG0_THREADSIZE__MASK 0x00100000 +#define A4XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT 20 +static inline uint32_t A4XX_SP_FS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT) & A4XX_SP_FS_CTRL_REG0_THREADSIZE__MASK; +} +#define A4XX_SP_FS_CTRL_REG0_SUPERTHREADMODE 0x00200000 +#define A4XX_SP_FS_CTRL_REG0_PIXLODENABLE 0x00400000 + +#define REG_A4XX_SP_FS_CTRL_REG1 0x000022e9 +#define A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK 0x000000ff +#define A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_SP_FS_CTRL_REG1_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT) & A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK; +} +#define A4XX_SP_FS_CTRL_REG1_VARYING 0x00100000 + +#define REG_A4XX_SP_FS_OBJ_OFFSET_REG 0x000022ea +#define A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 +#define A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT 16 +static inline uint32_t A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK 0xfe000000 +#define A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT 25 +static inline uint32_t A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A4XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK; +} + +#define REG_A4XX_SP_FS_OBJ_START 0x000022eb + +#define REG_A4XX_SP_FS_PVT_MEM_PARAM 0x000022ec + +#define REG_A4XX_SP_FS_PVT_MEM_ADDR 0x000022ed + +#define REG_A4XX_SP_FS_LENGTH_REG 0x000022ef + +#define REG_A4XX_SP_FS_OUTPUT_REG 0x000022f0 +#define A4XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE 0x00000080 +#define A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID__MASK 0x0000ff00 +#define A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID__SHIFT 8 +static inline uint32_t A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID(uint32_t val) +{ + return ((val) << A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID__SHIFT) & A4XX_SP_FS_OUTPUT_REG_DEPTH_REGID__MASK; +} + +static inline uint32_t REG_A4XX_SP_FS_MRT(uint32_t i0) { return 0x000022f1 + 0x1*i0; } + +static inline uint32_t REG_A4XX_SP_FS_MRT_REG(uint32_t i0) { return 0x000022f1 + 0x1*i0; } +#define A4XX_SP_FS_MRT_REG_REGID__MASK 0x000000ff +#define A4XX_SP_FS_MRT_REG_REGID__SHIFT 0 +static inline uint32_t A4XX_SP_FS_MRT_REG_REGID(uint32_t val) +{ + return ((val) << A4XX_SP_FS_MRT_REG_REGID__SHIFT) & A4XX_SP_FS_MRT_REG_REGID__MASK; +} +#define A4XX_SP_FS_MRT_REG_HALF_PRECISION 0x00000100 +#define A4XX_SP_FS_MRT_REG_MRTFORMAT__MASK 0x0003f000 +#define A4XX_SP_FS_MRT_REG_MRTFORMAT__SHIFT 12 +static inline uint32_t A4XX_SP_FS_MRT_REG_MRTFORMAT(enum a4xx_color_fmt val) +{ + return ((val) << A4XX_SP_FS_MRT_REG_MRTFORMAT__SHIFT) & A4XX_SP_FS_MRT_REG_MRTFORMAT__MASK; +} + +#define REG_A4XX_SP_HS_OBJ_OFFSET_REG 0x0000230d +#define A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 +#define A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT 16 +static inline uint32_t A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_SP_HS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK 0xfe000000 +#define A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT 25 +static inline uint32_t A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A4XX_SP_HS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK; +} + +#define REG_A4XX_SP_DS_OBJ_OFFSET_REG 0x00002334 +#define A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 +#define A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT 16 +static inline uint32_t A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_SP_DS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK 0xfe000000 +#define A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT 25 +static inline uint32_t A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A4XX_SP_DS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK; +} + +#define REG_A4XX_SP_GS_OBJ_OFFSET_REG 0x0000235b +#define A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 +#define A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT 16 +static inline uint32_t A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_SP_GS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK 0xfe000000 +#define A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT 25 +static inline uint32_t A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A4XX_SP_GS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK; +} + +#define REG_A4XX_SP_GS_LENGTH_REG 0x00002360 + +#define REG_A4XX_VPC_DEBUG_RAM_SEL 0x00000e60 + +#define REG_A4XX_VPC_DEBUG_RAM_READ 0x00000e61 + +#define REG_A4XX_VPC_DEBUG_ECO_CONTROL 0x00000e64 + +#define REG_A4XX_VPC_PERFCTR_VPC_SEL_3 0x00000e68 + +#define REG_A4XX_VPC_ATTR 0x00002140 +#define A4XX_VPC_ATTR_TOTALATTR__MASK 0x000001ff +#define A4XX_VPC_ATTR_TOTALATTR__SHIFT 0 +static inline uint32_t A4XX_VPC_ATTR_TOTALATTR(uint32_t val) +{ + return ((val) << A4XX_VPC_ATTR_TOTALATTR__SHIFT) & A4XX_VPC_ATTR_TOTALATTR__MASK; +} +#define A4XX_VPC_ATTR_PSIZE 0x00000200 +#define A4XX_VPC_ATTR_THRDASSIGN__MASK 0x00003000 +#define A4XX_VPC_ATTR_THRDASSIGN__SHIFT 12 +static inline uint32_t A4XX_VPC_ATTR_THRDASSIGN(uint32_t val) +{ + return ((val) << A4XX_VPC_ATTR_THRDASSIGN__SHIFT) & A4XX_VPC_ATTR_THRDASSIGN__MASK; +} +#define A4XX_VPC_ATTR_ENABLE 0x02000000 + +#define REG_A4XX_VPC_PACK 0x00002141 +#define A4XX_VPC_PACK_NUMBYPASSVAR__MASK 0x000000ff +#define A4XX_VPC_PACK_NUMBYPASSVAR__SHIFT 0 +static inline uint32_t A4XX_VPC_PACK_NUMBYPASSVAR(uint32_t val) +{ + return ((val) << A4XX_VPC_PACK_NUMBYPASSVAR__SHIFT) & A4XX_VPC_PACK_NUMBYPASSVAR__MASK; +} +#define A4XX_VPC_PACK_NUMFPNONPOSVAR__MASK 0x0000ff00 +#define A4XX_VPC_PACK_NUMFPNONPOSVAR__SHIFT 8 +static inline uint32_t A4XX_VPC_PACK_NUMFPNONPOSVAR(uint32_t val) +{ + return ((val) << A4XX_VPC_PACK_NUMFPNONPOSVAR__SHIFT) & A4XX_VPC_PACK_NUMFPNONPOSVAR__MASK; +} +#define A4XX_VPC_PACK_NUMNONPOSVSVAR__MASK 0x00ff0000 +#define A4XX_VPC_PACK_NUMNONPOSVSVAR__SHIFT 16 +static inline uint32_t A4XX_VPC_PACK_NUMNONPOSVSVAR(uint32_t val) +{ + return ((val) << A4XX_VPC_PACK_NUMNONPOSVSVAR__SHIFT) & A4XX_VPC_PACK_NUMNONPOSVSVAR__MASK; +} + +static inline uint32_t REG_A4XX_VPC_VARYING_INTERP(uint32_t i0) { return 0x00002142 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VPC_VARYING_INTERP_MODE(uint32_t i0) { return 0x00002142 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VPC_VARYING_PS_REPL(uint32_t i0) { return 0x0000214a + 0x1*i0; } + +static inline uint32_t REG_A4XX_VPC_VARYING_PS_REPL_MODE(uint32_t i0) { return 0x0000214a + 0x1*i0; } + +#define REG_A4XX_VPC_SO_FLUSH_WADDR_3 0x0000216e + +#define REG_A4XX_VSC_BIN_SIZE 0x00000c00 +#define A4XX_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f +#define A4XX_VSC_BIN_SIZE_WIDTH__SHIFT 0 +static inline uint32_t A4XX_VSC_BIN_SIZE_WIDTH(uint32_t val) +{ + return ((val >> 5) << A4XX_VSC_BIN_SIZE_WIDTH__SHIFT) & A4XX_VSC_BIN_SIZE_WIDTH__MASK; +} +#define A4XX_VSC_BIN_SIZE_HEIGHT__MASK 0x000003e0 +#define A4XX_VSC_BIN_SIZE_HEIGHT__SHIFT 5 +static inline uint32_t A4XX_VSC_BIN_SIZE_HEIGHT(uint32_t val) +{ + return ((val >> 5) << A4XX_VSC_BIN_SIZE_HEIGHT__SHIFT) & A4XX_VSC_BIN_SIZE_HEIGHT__MASK; +} + +#define REG_A4XX_VSC_SIZE_ADDRESS 0x00000c01 + +#define REG_A4XX_VSC_SIZE_ADDRESS2 0x00000c02 + +#define REG_A4XX_VSC_DEBUG_ECO_CONTROL 0x00000c03 + +static inline uint32_t REG_A4XX_VSC_PIPE_CONFIG(uint32_t i0) { return 0x00000c08 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VSC_PIPE_CONFIG_REG(uint32_t i0) { return 0x00000c08 + 0x1*i0; } +#define A4XX_VSC_PIPE_CONFIG_REG_X__MASK 0x000003ff +#define A4XX_VSC_PIPE_CONFIG_REG_X__SHIFT 0 +static inline uint32_t A4XX_VSC_PIPE_CONFIG_REG_X(uint32_t val) +{ + return ((val) << A4XX_VSC_PIPE_CONFIG_REG_X__SHIFT) & A4XX_VSC_PIPE_CONFIG_REG_X__MASK; +} +#define A4XX_VSC_PIPE_CONFIG_REG_Y__MASK 0x000ffc00 +#define A4XX_VSC_PIPE_CONFIG_REG_Y__SHIFT 10 +static inline uint32_t A4XX_VSC_PIPE_CONFIG_REG_Y(uint32_t val) +{ + return ((val) << A4XX_VSC_PIPE_CONFIG_REG_Y__SHIFT) & A4XX_VSC_PIPE_CONFIG_REG_Y__MASK; +} +#define A4XX_VSC_PIPE_CONFIG_REG_W__MASK 0x00f00000 +#define A4XX_VSC_PIPE_CONFIG_REG_W__SHIFT 20 +static inline uint32_t A4XX_VSC_PIPE_CONFIG_REG_W(uint32_t val) +{ + return ((val) << A4XX_VSC_PIPE_CONFIG_REG_W__SHIFT) & A4XX_VSC_PIPE_CONFIG_REG_W__MASK; +} +#define A4XX_VSC_PIPE_CONFIG_REG_H__MASK 0x0f000000 +#define A4XX_VSC_PIPE_CONFIG_REG_H__SHIFT 24 +static inline uint32_t A4XX_VSC_PIPE_CONFIG_REG_H(uint32_t val) +{ + return ((val) << A4XX_VSC_PIPE_CONFIG_REG_H__SHIFT) & A4XX_VSC_PIPE_CONFIG_REG_H__MASK; +} + +static inline uint32_t REG_A4XX_VSC_PIPE_DATA_ADDRESS(uint32_t i0) { return 0x00000c10 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VSC_PIPE_DATA_ADDRESS_REG(uint32_t i0) { return 0x00000c10 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VSC_PIPE_DATA_LENGTH(uint32_t i0) { return 0x00000c18 + 0x1*i0; } + +static inline uint32_t REG_A4XX_VSC_PIPE_DATA_LENGTH_REG(uint32_t i0) { return 0x00000c18 + 0x1*i0; } + +#define REG_A4XX_VSC_PIPE_PARTIAL_POSN_1 0x00000c41 + +#define REG_A4XX_VSC_PERFCTR_VSC_SEL_0 0x00000c50 + +#define REG_A4XX_VSC_PERFCTR_VSC_SEL_1 0x00000c51 + +#define REG_A4XX_VFD_DEBUG_CONTROL 0x00000e40 + +#define REG_A4XX_VFD_PERFCTR_VFD_SEL_7 0x00000e4a + +#define REG_A4XX_VFD_CONTROL_0 0x00002200 +#define A4XX_VFD_CONTROL_0_TOTALATTRTOVS__MASK 0x000000ff +#define A4XX_VFD_CONTROL_0_TOTALATTRTOVS__SHIFT 0 +static inline uint32_t A4XX_VFD_CONTROL_0_TOTALATTRTOVS(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_0_TOTALATTRTOVS__SHIFT) & A4XX_VFD_CONTROL_0_TOTALATTRTOVS__MASK; +} +#define A4XX_VFD_CONTROL_0_BYPASSATTROVS__MASK 0x0001fe00 +#define A4XX_VFD_CONTROL_0_BYPASSATTROVS__SHIFT 9 +static inline uint32_t A4XX_VFD_CONTROL_0_BYPASSATTROVS(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_0_BYPASSATTROVS__SHIFT) & A4XX_VFD_CONTROL_0_BYPASSATTROVS__MASK; +} +#define A4XX_VFD_CONTROL_0_STRMDECINSTRCNT__MASK 0x03f00000 +#define A4XX_VFD_CONTROL_0_STRMDECINSTRCNT__SHIFT 20 +static inline uint32_t A4XX_VFD_CONTROL_0_STRMDECINSTRCNT(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_0_STRMDECINSTRCNT__SHIFT) & A4XX_VFD_CONTROL_0_STRMDECINSTRCNT__MASK; +} +#define A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__MASK 0xfc000000 +#define A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__SHIFT 26 +static inline uint32_t A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__SHIFT) & A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__MASK; +} + +#define REG_A4XX_VFD_CONTROL_1 0x00002201 +#define A4XX_VFD_CONTROL_1_MAXSTORAGE__MASK 0x0000ffff +#define A4XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT 0 +static inline uint32_t A4XX_VFD_CONTROL_1_MAXSTORAGE(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT) & A4XX_VFD_CONTROL_1_MAXSTORAGE__MASK; +} +#define A4XX_VFD_CONTROL_1_REGID4VTX__MASK 0x00ff0000 +#define A4XX_VFD_CONTROL_1_REGID4VTX__SHIFT 16 +static inline uint32_t A4XX_VFD_CONTROL_1_REGID4VTX(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_1_REGID4VTX__SHIFT) & A4XX_VFD_CONTROL_1_REGID4VTX__MASK; +} +#define A4XX_VFD_CONTROL_1_REGID4INST__MASK 0xff000000 +#define A4XX_VFD_CONTROL_1_REGID4INST__SHIFT 24 +static inline uint32_t A4XX_VFD_CONTROL_1_REGID4INST(uint32_t val) +{ + return ((val) << A4XX_VFD_CONTROL_1_REGID4INST__SHIFT) & A4XX_VFD_CONTROL_1_REGID4INST__MASK; +} + +#define REG_A4XX_VFD_CONTROL_2 0x00002202 + +#define REG_A4XX_VFD_CONTROL_3 0x00002203 + +#define REG_A4XX_VFD_CONTROL_4 0x00002204 + +#define REG_A4XX_VFD_INDEX_OFFSET 0x00002208 + +static inline uint32_t REG_A4XX_VFD_FETCH(uint32_t i0) { return 0x0000220a + 0x4*i0; } + +static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_0(uint32_t i0) { return 0x0000220a + 0x4*i0; } +#define A4XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK 0x0000007f +#define A4XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT 0 +static inline uint32_t A4XX_VFD_FETCH_INSTR_0_FETCHSIZE(uint32_t val) +{ + return ((val) << A4XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK; +} +#define A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK 0x0001ff80 +#define A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT 7 +static inline uint32_t A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val) +{ + return ((val) << A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK; +} +#define A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00080000 +#define A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK 0xff000000 +#define A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT 24 +static inline uint32_t A4XX_VFD_FETCH_INSTR_0_STEPRATE(uint32_t val) +{ + return ((val) << A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK; +} + +static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x0000220b + 0x4*i0; } + +static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_2(uint32_t i0) { return 0x0000220c + 0x4*i0; } +#define A4XX_VFD_FETCH_INSTR_2_SIZE__MASK 0xfffffff0 +#define A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT 4 +static inline uint32_t A4XX_VFD_FETCH_INSTR_2_SIZE(uint32_t val) +{ + return ((val >> 4) << A4XX_VFD_FETCH_INSTR_2_SIZE__SHIFT) & A4XX_VFD_FETCH_INSTR_2_SIZE__MASK; +} + +static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_3(uint32_t i0) { return 0x0000220d + 0x4*i0; } + +static inline uint32_t REG_A4XX_VFD_DECODE(uint32_t i0) { return 0x0000228a + 0x1*i0; } + +static inline uint32_t REG_A4XX_VFD_DECODE_INSTR(uint32_t i0) { return 0x0000228a + 0x1*i0; } +#define A4XX_VFD_DECODE_INSTR_WRITEMASK__MASK 0x0000000f +#define A4XX_VFD_DECODE_INSTR_WRITEMASK__SHIFT 0 +static inline uint32_t A4XX_VFD_DECODE_INSTR_WRITEMASK(uint32_t val) +{ + return ((val) << A4XX_VFD_DECODE_INSTR_WRITEMASK__SHIFT) & A4XX_VFD_DECODE_INSTR_WRITEMASK__MASK; +} +#define A4XX_VFD_DECODE_INSTR_CONSTFILL 0x00000010 +#define A4XX_VFD_DECODE_INSTR_FORMAT__MASK 0x00000fc0 +#define A4XX_VFD_DECODE_INSTR_FORMAT__SHIFT 6 +static inline uint32_t A4XX_VFD_DECODE_INSTR_FORMAT(enum a4xx_vtx_fmt val) +{ + return ((val) << A4XX_VFD_DECODE_INSTR_FORMAT__SHIFT) & A4XX_VFD_DECODE_INSTR_FORMAT__MASK; +} +#define A4XX_VFD_DECODE_INSTR_REGID__MASK 0x000ff000 +#define A4XX_VFD_DECODE_INSTR_REGID__SHIFT 12 +static inline uint32_t A4XX_VFD_DECODE_INSTR_REGID(uint32_t val) +{ + return ((val) << A4XX_VFD_DECODE_INSTR_REGID__SHIFT) & A4XX_VFD_DECODE_INSTR_REGID__MASK; +} +#define A4XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000 +#define A4XX_VFD_DECODE_INSTR_SWAP__SHIFT 22 +static inline uint32_t A4XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val) +{ + return ((val) << A4XX_VFD_DECODE_INSTR_SWAP__SHIFT) & A4XX_VFD_DECODE_INSTR_SWAP__MASK; +} +#define A4XX_VFD_DECODE_INSTR_SHIFTCNT__MASK 0x1f000000 +#define A4XX_VFD_DECODE_INSTR_SHIFTCNT__SHIFT 24 +static inline uint32_t A4XX_VFD_DECODE_INSTR_SHIFTCNT(uint32_t val) +{ + return ((val) << A4XX_VFD_DECODE_INSTR_SHIFTCNT__SHIFT) & A4XX_VFD_DECODE_INSTR_SHIFTCNT__MASK; +} +#define A4XX_VFD_DECODE_INSTR_LASTCOMPVALID 0x20000000 +#define A4XX_VFD_DECODE_INSTR_SWITCHNEXT 0x40000000 + +#define REG_A4XX_TPL1_DEBUG_ECO_CONTROL 0x00000f00 + +#define REG_A4XX_TPL1_PERFCTR_TP_SEL_7 0x00000f0b + +#define REG_A4XX_TPL1_TP_TEX_OFFSET 0x00002380 + +#define REG_A4XX_TPL1_TP_CS_TEXMEMOBJ_BASE_ADDR 0x000023a6 + +#define REG_A4XX_GRAS_TSE_STATUS 0x00000c80 + +#define REG_A4XX_GRAS_DEBUG_ECO_CONTROL 0x00000c81 + +#define REG_A4XX_GRAS_PERFCTR_TSE_SEL_0 0x00000c88 + +#define REG_A4XX_GRAS_PERFCTR_TSE_SEL_3 0x00000c8b + +#define REG_A4XX_GRAS_CL_CLIP_CNTL 0x00002000 + +#define REG_A4XX_GRAS_CLEAR_CNTL 0x00002003 +#define A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR 0x00000001 + +#define REG_A4XX_GRAS_CL_GB_CLIP_ADJ 0x00002004 +#define A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK 0x000003ff +#define A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ(uint32_t val) +{ + return ((val) << A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ__SHIFT) & A4XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK; +} +#define A4XX_GRAS_CL_GB_CLIP_ADJ_VERT__MASK 0x000ffc00 +#define A4XX_GRAS_CL_GB_CLIP_ADJ_VERT__SHIFT 10 +static inline uint32_t A4XX_GRAS_CL_GB_CLIP_ADJ_VERT(uint32_t val) +{ + return ((val) << A4XX_GRAS_CL_GB_CLIP_ADJ_VERT__SHIFT) & A4XX_GRAS_CL_GB_CLIP_ADJ_VERT__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_XOFFSET_0 0x00002008 +#define A4XX_GRAS_CL_VPORT_XOFFSET_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_XOFFSET_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_XOFFSET_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_XOFFSET_0__SHIFT) & A4XX_GRAS_CL_VPORT_XOFFSET_0__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_XSCALE_0 0x00002009 +#define A4XX_GRAS_CL_VPORT_XSCALE_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_XSCALE_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_XSCALE_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_XSCALE_0__SHIFT) & A4XX_GRAS_CL_VPORT_XSCALE_0__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_YOFFSET_0 0x0000200a +#define A4XX_GRAS_CL_VPORT_YOFFSET_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_YOFFSET_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_YOFFSET_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_YOFFSET_0__SHIFT) & A4XX_GRAS_CL_VPORT_YOFFSET_0__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_YSCALE_0 0x0000200b +#define A4XX_GRAS_CL_VPORT_YSCALE_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_YSCALE_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_YSCALE_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_YSCALE_0__SHIFT) & A4XX_GRAS_CL_VPORT_YSCALE_0__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_ZOFFSET_0 0x0000200c +#define A4XX_GRAS_CL_VPORT_ZOFFSET_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_ZOFFSET_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_ZOFFSET_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_ZOFFSET_0__SHIFT) & A4XX_GRAS_CL_VPORT_ZOFFSET_0__MASK; +} + +#define REG_A4XX_GRAS_CL_VPORT_ZSCALE_0 0x0000200d +#define A4XX_GRAS_CL_VPORT_ZSCALE_0__MASK 0xffffffff +#define A4XX_GRAS_CL_VPORT_ZSCALE_0__SHIFT 0 +static inline uint32_t A4XX_GRAS_CL_VPORT_ZSCALE_0(float val) +{ + return ((fui(val)) << A4XX_GRAS_CL_VPORT_ZSCALE_0__SHIFT) & A4XX_GRAS_CL_VPORT_ZSCALE_0__MASK; +} + +#define REG_A4XX_GRAS_SU_POINT_MINMAX 0x00002070 +#define A4XX_GRAS_SU_POINT_MINMAX_MIN__MASK 0x0000ffff +#define A4XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT 0 +static inline uint32_t A4XX_GRAS_SU_POINT_MINMAX_MIN(float val) +{ + return ((((uint32_t)(val * 16.0))) << A4XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A4XX_GRAS_SU_POINT_MINMAX_MIN__MASK; +} +#define A4XX_GRAS_SU_POINT_MINMAX_MAX__MASK 0xffff0000 +#define A4XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT 16 +static inline uint32_t A4XX_GRAS_SU_POINT_MINMAX_MAX(float val) +{ + return ((((uint32_t)(val * 16.0))) << A4XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A4XX_GRAS_SU_POINT_MINMAX_MAX__MASK; +} + +#define REG_A4XX_GRAS_SU_POINT_SIZE 0x00002071 +#define A4XX_GRAS_SU_POINT_SIZE__MASK 0xffffffff +#define A4XX_GRAS_SU_POINT_SIZE__SHIFT 0 +static inline uint32_t A4XX_GRAS_SU_POINT_SIZE(float val) +{ + return ((((int32_t)(val * 16.0))) << A4XX_GRAS_SU_POINT_SIZE__SHIFT) & A4XX_GRAS_SU_POINT_SIZE__MASK; +} + +#define REG_A4XX_GRAS_ALPHA_CONTROL 0x00002073 +#define A4XX_GRAS_ALPHA_CONTROL_ALPHA_TEST_ENABLE 0x00000004 + +#define REG_A4XX_GRAS_SU_POLY_OFFSET_SCALE 0x00002074 +#define A4XX_GRAS_SU_POLY_OFFSET_SCALE__MASK 0xffffffff +#define A4XX_GRAS_SU_POLY_OFFSET_SCALE__SHIFT 0 +static inline uint32_t A4XX_GRAS_SU_POLY_OFFSET_SCALE(float val) +{ + return ((fui(val)) << A4XX_GRAS_SU_POLY_OFFSET_SCALE__SHIFT) & A4XX_GRAS_SU_POLY_OFFSET_SCALE__MASK; +} + +#define REG_A4XX_GRAS_SU_POLY_OFFSET_OFFSET 0x00002075 +#define A4XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK 0xffffffff +#define A4XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A4XX_GRAS_SU_POLY_OFFSET_OFFSET(float val) +{ + return ((fui(val)) << A4XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A4XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK; +} + +#define REG_A4XX_GRAS_SC_EXTENT_WINDOW_TL 0x0000209f + +#define REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL 0x0000207c +#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000 +#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X__MASK 0x00007fff +#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X__SHIFT 0 +static inline uint32_t A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X__SHIFT) & A4XX_GRAS_SC_SCREEN_SCISSOR_TL_X__MASK; +} +#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__MASK 0x7fff0000 +#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__SHIFT 16 +static inline uint32_t A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__SHIFT) & A4XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__MASK; +} + +#define REG_A4XX_GRAS_SC_SCREEN_SCISSOR_BR 0x0000207d +#define A4XX_GRAS_SC_SCREEN_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000 +#define A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X__MASK 0x00007fff +#define A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X__SHIFT 0 +static inline uint32_t A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X__SHIFT) & A4XX_GRAS_SC_SCREEN_SCISSOR_BR_X__MASK; +} +#define A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__MASK 0x7fff0000 +#define A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__SHIFT 16 +static inline uint32_t A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__SHIFT) & A4XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__MASK; +} + +#define REG_A4XX_GRAS_SC_WINDOW_SCISSOR_BR 0x0000209c +#define A4XX_GRAS_SC_WINDOW_SCISSOR_BR_WINDOW_OFFSET_DISABLE 0x80000000 +#define A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X__MASK 0x00007fff +#define A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X__SHIFT 0 +static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_BR_X__MASK; +} +#define A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__MASK 0x7fff0000 +#define A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__SHIFT 16 +static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__MASK; +} + +#define REG_A4XX_GRAS_SC_WINDOW_SCISSOR_TL 0x0000209d +#define A4XX_GRAS_SC_WINDOW_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000 +#define A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X__MASK 0x00007fff +#define A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X__SHIFT 0 +static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_TL_X__MASK; +} +#define A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK 0x7fff0000 +#define A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT 16 +static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK; +} + +#define REG_A4XX_GRAS_DEPTH_CONTROL 0x00002077 +#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK 0x00000003 +#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT 0 +static inline uint32_t A4XX_GRAS_DEPTH_CONTROL_FORMAT(enum a4xx_depth_format val) +{ + return ((val) << A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT) & A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK; +} + +#define REG_A4XX_GRAS_SU_MODE_CONTROL 0x00002078 +#define A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001 +#define A4XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002 +#define A4XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004 +#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8 +#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3 +static inline uint32_t A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val) +{ + return ((((int32_t)(val * 4.0))) << A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK; +} +#define A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800 +#define A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS 0x00100000 + +#define REG_A4XX_GRAS_SC_CONTROL 0x0000207b +#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK 0x0000000c +#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT 2 +static inline uint32_t A4XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val) +{ + return ((val) << A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK; +} +#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK 0x00000380 +#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT 7 +static inline uint32_t A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK; +} +#define A4XX_GRAS_SC_CONTROL_MSAA_DISABLE 0x00000800 +#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK 0x0000f000 +#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT 12 +static inline uint32_t A4XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val) +{ + return ((val) << A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK; +} + +#define REG_A4XX_UCHE_CACHE_MODE_CONTROL 0x00000e80 + +#define REG_A4XX_UCHE_TRAP_BASE_LO 0x00000e83 + +#define REG_A4XX_UCHE_TRAP_BASE_HI 0x00000e84 + +#define REG_A4XX_UCHE_CACHE_STATUS 0x00000e88 + +#define REG_A4XX_UCHE_INVALIDATE0 0x00000e8a + +#define REG_A4XX_UCHE_INVALIDATE1 0x00000e8b + +#define REG_A4XX_UCHE_CACHE_WAYS_VFD 0x00000e8c + +#define REG_A4XX_UCHE_PERFCTR_UCHE_SEL_7 0x00000e95 + +#define REG_A4XX_HLSQ_TIMEOUT_THRESHOLD 0x00000e00 + +#define REG_A4XX_HLSQ_DEBUG_ECO_CONTROL 0x00000e04 + +#define REG_A4XX_HLSQ_PERF_PIPE_MASK 0x00000e0e + +#define REG_A4XX_HLSQ_CONTROL_0_REG 0x000023c0 +#define A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK 0x00000010 +#define A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT 4 +static inline uint32_t A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT) & A4XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK; +} +#define A4XX_HLSQ_CONTROL_0_REG_FSSUPERTHREADENABLE 0x00000040 +#define A4XX_HLSQ_CONTROL_0_REG_SPSHADERRESTART 0x00000200 +#define A4XX_HLSQ_CONTROL_0_REG_RESERVED2 0x00000400 +#define A4XX_HLSQ_CONTROL_0_REG_CHUNKDISABLE 0x04000000 +#define A4XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK 0x08000000 +#define A4XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT 27 +static inline uint32_t A4XX_HLSQ_CONTROL_0_REG_CONSTMODE(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT) & A4XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK; +} +#define A4XX_HLSQ_CONTROL_0_REG_LAZYUPDATEDISABLE 0x10000000 +#define A4XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE 0x20000000 +#define A4XX_HLSQ_CONTROL_0_REG_TPFULLUPDATE 0x40000000 +#define A4XX_HLSQ_CONTROL_0_REG_SINGLECONTEXT 0x80000000 + +#define REG_A4XX_HLSQ_CONTROL_1_REG 0x000023c1 +#define A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__MASK 0x00000040 +#define A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__SHIFT 6 +static inline uint32_t A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__SHIFT) & A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__MASK; +} +#define A4XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE 0x00000100 +#define A4XX_HLSQ_CONTROL_1_REG_RESERVED1 0x00000200 +#define A4XX_HLSQ_CONTROL_1_REG_ZWCOORD 0x02000000 + +#define REG_A4XX_HLSQ_CONTROL_2_REG 0x000023c2 +#define A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK 0xfc000000 +#define A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT 26 +static inline uint32_t A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK; +} + +#define REG_A4XX_HLSQ_CONTROL_3_REG 0x000023c3 +#define A4XX_HLSQ_CONTROL_3_REG_REGID__MASK 0x000000ff +#define A4XX_HLSQ_CONTROL_3_REG_REGID__SHIFT 0 +static inline uint32_t A4XX_HLSQ_CONTROL_3_REG_REGID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CONTROL_3_REG_REGID__SHIFT) & A4XX_HLSQ_CONTROL_3_REG_REGID__MASK; +} + +#define REG_A4XX_HLSQ_VS_CONTROL_REG 0x000023c5 +#define A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__MASK 0x000000ff +#define A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__SHIFT) & A4XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__MASK; +} +#define A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x0000ff00 +#define A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 8 +static inline uint32_t A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_HLSQ_VS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00fe0000 +#define A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 17 +static inline uint32_t A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A4XX_HLSQ_VS_CONTROL_REG_SHADEROBJOFFSET__MASK; +} +#define A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__MASK 0xff000000 +#define A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__SHIFT 24 +static inline uint32_t A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__SHIFT) & A4XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__MASK; +} + +#define REG_A4XX_HLSQ_FS_CONTROL_REG 0x000023c6 +#define A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__MASK 0x000000ff +#define A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__SHIFT) & A4XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__MASK; +} +#define A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x0000ff00 +#define A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 8 +static inline uint32_t A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_HLSQ_FS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00fe0000 +#define A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 17 +static inline uint32_t A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A4XX_HLSQ_FS_CONTROL_REG_SHADEROBJOFFSET__MASK; +} +#define A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__MASK 0xff000000 +#define A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__SHIFT 24 +static inline uint32_t A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__SHIFT) & A4XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__MASK; +} + +#define REG_A4XX_HLSQ_HS_CONTROL_REG 0x000023c7 +#define A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH__MASK 0x000000ff +#define A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH__SHIFT) & A4XX_HLSQ_HS_CONTROL_REG_CONSTLENGTH__MASK; +} +#define A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x0000ff00 +#define A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 8 +static inline uint32_t A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_HLSQ_HS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00fe0000 +#define A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 17 +static inline uint32_t A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A4XX_HLSQ_HS_CONTROL_REG_SHADEROBJOFFSET__MASK; +} +#define A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH__MASK 0xff000000 +#define A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH__SHIFT 24 +static inline uint32_t A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH__SHIFT) & A4XX_HLSQ_HS_CONTROL_REG_INSTRLENGTH__MASK; +} + +#define REG_A4XX_HLSQ_DS_CONTROL_REG 0x000023c8 +#define A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH__MASK 0x000000ff +#define A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH__SHIFT) & A4XX_HLSQ_DS_CONTROL_REG_CONSTLENGTH__MASK; +} +#define A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x0000ff00 +#define A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 8 +static inline uint32_t A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_HLSQ_DS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00fe0000 +#define A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 17 +static inline uint32_t A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A4XX_HLSQ_DS_CONTROL_REG_SHADEROBJOFFSET__MASK; +} +#define A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH__MASK 0xff000000 +#define A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH__SHIFT 24 +static inline uint32_t A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH__SHIFT) & A4XX_HLSQ_DS_CONTROL_REG_INSTRLENGTH__MASK; +} + +#define REG_A4XX_HLSQ_GS_CONTROL_REG 0x000023c9 +#define A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH__MASK 0x000000ff +#define A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH__SHIFT 0 +static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH__SHIFT) & A4XX_HLSQ_GS_CONTROL_REG_CONSTLENGTH__MASK; +} +#define A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK 0x0000ff00 +#define A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT 8 +static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__SHIFT) & A4XX_HLSQ_GS_CONTROL_REG_CONSTOBJECTOFFSET__MASK; +} +#define A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__MASK 0x00fe0000 +#define A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT 17 +static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET(uint32_t val) +{ + return ((val) << A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__SHIFT) & A4XX_HLSQ_GS_CONTROL_REG_SHADEROBJOFFSET__MASK; +} +#define A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH__MASK 0xff000000 +#define A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH__SHIFT 24 +static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(uint32_t val) +{ + return ((val) << A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH__SHIFT) & A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH__MASK; +} + +#define REG_A4XX_HLSQ_UPDATE_CONTROL 0x000023db + +#define REG_A4XX_PC_BINNING_COMMAND 0x00000d00 +#define A4XX_PC_BINNING_COMMAND_BINNING_ENABLE 0x00000001 + +#define REG_A4XX_PC_DRAWCALL_SETUP_OVERRIDE 0x00000d0c + +#define REG_A4XX_PC_PERFCTR_PC_SEL_0 0x00000d10 + +#define REG_A4XX_PC_PERFCTR_PC_SEL_7 0x00000d17 + +#define REG_A4XX_PC_BIN_BASE 0x000021c0 + +#define REG_A4XX_PC_PRIM_VTX_CNTL 0x000021c4 +#define A4XX_PC_PRIM_VTX_CNTL_VAROUT 0x00000001 +#define A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST 0x02000000 +#define A4XX_PC_PRIM_VTX_CNTL_PSIZE 0x04000000 + +#define REG_A4XX_UNKNOWN_21C5 0x000021c5 + +#define REG_A4XX_PC_RESTART_INDEX 0x000021c6 + +#define REG_A4XX_PC_GS_PARAM 0x000021e5 + +#define REG_A4XX_PC_HS_PARAM 0x000021e7 + +#define REG_A4XX_VBIF_VERSION 0x00003000 + +#define REG_A4XX_VBIF_CLKON 0x00003001 +#define A4XX_VBIF_CLKON_FORCE_ON_TESTBUS 0x00000001 + +#define REG_A4XX_VBIF_ABIT_SORT 0x0000301c + +#define REG_A4XX_VBIF_ABIT_SORT_CONF 0x0000301d + +#define REG_A4XX_VBIF_GATE_OFF_WRREQ_EN 0x0000302a + +#define REG_A4XX_VBIF_IN_RD_LIM_CONF0 0x0000302c + +#define REG_A4XX_VBIF_IN_RD_LIM_CONF1 0x0000302d + +#define REG_A4XX_VBIF_IN_WR_LIM_CONF0 0x00003030 + +#define REG_A4XX_VBIF_IN_WR_LIM_CONF1 0x00003031 + +#define REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB 0x00003049 + +#define REG_A4XX_UNKNOWN_0CC5 0x00000cc5 + +#define REG_A4XX_UNKNOWN_0CC6 0x00000cc6 + +#define REG_A4XX_UNKNOWN_0D01 0x00000d01 + +#define REG_A4XX_UNKNOWN_0E05 0x00000e05 + +#define REG_A4XX_UNKNOWN_0E42 0x00000e42 + +#define REG_A4XX_UNKNOWN_0EC2 0x00000ec2 + +#define REG_A4XX_UNKNOWN_0EC3 0x00000ec3 + +#define REG_A4XX_UNKNOWN_0F03 0x00000f03 + +#define REG_A4XX_UNKNOWN_2001 0x00002001 + +#define REG_A4XX_UNKNOWN_209B 0x0000209b + +#define REG_A4XX_UNKNOWN_20EF 0x000020ef + +#define REG_A4XX_UNKNOWN_20F0 0x000020f0 + +#define REG_A4XX_UNKNOWN_20F1 0x000020f1 + +#define REG_A4XX_UNKNOWN_20F2 0x000020f2 + +#define REG_A4XX_UNKNOWN_20F3 0x000020f3 + +#define REG_A4XX_UNKNOWN_20F4 0x000020f4 + +#define REG_A4XX_UNKNOWN_20F5 0x000020f5 + +#define REG_A4XX_UNKNOWN_20F6 0x000020f6 + +#define REG_A4XX_UNKNOWN_20F7 0x000020f7 + +#define REG_A4XX_UNKNOWN_2152 0x00002152 + +#define REG_A4XX_UNKNOWN_2153 0x00002153 + +#define REG_A4XX_UNKNOWN_2154 0x00002154 + +#define REG_A4XX_UNKNOWN_2155 0x00002155 + +#define REG_A4XX_UNKNOWN_2156 0x00002156 + +#define REG_A4XX_UNKNOWN_2157 0x00002157 + +#define REG_A4XX_UNKNOWN_21C3 0x000021c3 + +#define REG_A4XX_UNKNOWN_21E6 0x000021e6 + +#define REG_A4XX_UNKNOWN_2209 0x00002209 + +#define REG_A4XX_UNKNOWN_22D7 0x000022d7 + +#define REG_A4XX_UNKNOWN_2381 0x00002381 + +#define REG_A4XX_UNKNOWN_23A0 0x000023a0 + +#define REG_A4XX_TEX_SAMP_0 0x00000000 +#define A4XX_TEX_SAMP_0_XY_MAG__MASK 0x00000006 +#define A4XX_TEX_SAMP_0_XY_MAG__SHIFT 1 +static inline uint32_t A4XX_TEX_SAMP_0_XY_MAG(enum a4xx_tex_filter val) +{ + return ((val) << A4XX_TEX_SAMP_0_XY_MAG__SHIFT) & A4XX_TEX_SAMP_0_XY_MAG__MASK; +} +#define A4XX_TEX_SAMP_0_XY_MIN__MASK 0x00000018 +#define A4XX_TEX_SAMP_0_XY_MIN__SHIFT 3 +static inline uint32_t A4XX_TEX_SAMP_0_XY_MIN(enum a4xx_tex_filter val) +{ + return ((val) << A4XX_TEX_SAMP_0_XY_MIN__SHIFT) & A4XX_TEX_SAMP_0_XY_MIN__MASK; +} +#define A4XX_TEX_SAMP_0_WRAP_S__MASK 0x000000e0 +#define A4XX_TEX_SAMP_0_WRAP_S__SHIFT 5 +static inline uint32_t A4XX_TEX_SAMP_0_WRAP_S(enum a4xx_tex_clamp val) +{ + return ((val) << A4XX_TEX_SAMP_0_WRAP_S__SHIFT) & A4XX_TEX_SAMP_0_WRAP_S__MASK; +} +#define A4XX_TEX_SAMP_0_WRAP_T__MASK 0x00000700 +#define A4XX_TEX_SAMP_0_WRAP_T__SHIFT 8 +static inline uint32_t A4XX_TEX_SAMP_0_WRAP_T(enum a4xx_tex_clamp val) +{ + return ((val) << A4XX_TEX_SAMP_0_WRAP_T__SHIFT) & A4XX_TEX_SAMP_0_WRAP_T__MASK; +} +#define A4XX_TEX_SAMP_0_WRAP_R__MASK 0x00003800 +#define A4XX_TEX_SAMP_0_WRAP_R__SHIFT 11 +static inline uint32_t A4XX_TEX_SAMP_0_WRAP_R(enum a4xx_tex_clamp val) +{ + return ((val) << A4XX_TEX_SAMP_0_WRAP_R__SHIFT) & A4XX_TEX_SAMP_0_WRAP_R__MASK; +} + +#define REG_A4XX_TEX_SAMP_1 0x00000001 +#define A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK 0x0000000e +#define A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT 1 +static inline uint32_t A4XX_TEX_SAMP_1_COMPARE_FUNC(enum adreno_compare_func val) +{ + return ((val) << A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT) & A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK; +} +#define A4XX_TEX_SAMP_1_MAX_LOD__MASK 0x000fff00 +#define A4XX_TEX_SAMP_1_MAX_LOD__SHIFT 8 +static inline uint32_t A4XX_TEX_SAMP_1_MAX_LOD(float val) +{ + return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A4XX_TEX_SAMP_1_MAX_LOD__MASK; +} +#define A4XX_TEX_SAMP_1_MIN_LOD__MASK 0xfff00000 +#define A4XX_TEX_SAMP_1_MIN_LOD__SHIFT 20 +static inline uint32_t A4XX_TEX_SAMP_1_MIN_LOD(float val) +{ + return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A4XX_TEX_SAMP_1_MIN_LOD__MASK; +} + +#define REG_A4XX_TEX_CONST_0 0x00000000 +#define A4XX_TEX_CONST_0_TILED 0x00000001 +#define A4XX_TEX_CONST_0_SWIZ_X__MASK 0x00000070 +#define A4XX_TEX_CONST_0_SWIZ_X__SHIFT 4 +static inline uint32_t A4XX_TEX_CONST_0_SWIZ_X(enum a4xx_tex_swiz val) +{ + return ((val) << A4XX_TEX_CONST_0_SWIZ_X__SHIFT) & A4XX_TEX_CONST_0_SWIZ_X__MASK; +} +#define A4XX_TEX_CONST_0_SWIZ_Y__MASK 0x00000380 +#define A4XX_TEX_CONST_0_SWIZ_Y__SHIFT 7 +static inline uint32_t A4XX_TEX_CONST_0_SWIZ_Y(enum a4xx_tex_swiz val) +{ + return ((val) << A4XX_TEX_CONST_0_SWIZ_Y__SHIFT) & A4XX_TEX_CONST_0_SWIZ_Y__MASK; +} +#define A4XX_TEX_CONST_0_SWIZ_Z__MASK 0x00001c00 +#define A4XX_TEX_CONST_0_SWIZ_Z__SHIFT 10 +static inline uint32_t A4XX_TEX_CONST_0_SWIZ_Z(enum a4xx_tex_swiz val) +{ + return ((val) << A4XX_TEX_CONST_0_SWIZ_Z__SHIFT) & A4XX_TEX_CONST_0_SWIZ_Z__MASK; +} +#define A4XX_TEX_CONST_0_SWIZ_W__MASK 0x0000e000 +#define A4XX_TEX_CONST_0_SWIZ_W__SHIFT 13 +static inline uint32_t A4XX_TEX_CONST_0_SWIZ_W(enum a4xx_tex_swiz val) +{ + return ((val) << A4XX_TEX_CONST_0_SWIZ_W__SHIFT) & A4XX_TEX_CONST_0_SWIZ_W__MASK; +} +#define A4XX_TEX_CONST_0_FMT__MASK 0x1fc00000 +#define A4XX_TEX_CONST_0_FMT__SHIFT 22 +static inline uint32_t A4XX_TEX_CONST_0_FMT(enum a4xx_tex_fmt val) +{ + return ((val) << A4XX_TEX_CONST_0_FMT__SHIFT) & A4XX_TEX_CONST_0_FMT__MASK; +} +#define A4XX_TEX_CONST_0_TYPE__MASK 0x60000000 +#define A4XX_TEX_CONST_0_TYPE__SHIFT 29 +static inline uint32_t A4XX_TEX_CONST_0_TYPE(enum a4xx_tex_type val) +{ + return ((val) << A4XX_TEX_CONST_0_TYPE__SHIFT) & A4XX_TEX_CONST_0_TYPE__MASK; +} + +#define REG_A4XX_TEX_CONST_1 0x00000001 +#define A4XX_TEX_CONST_1_HEIGHT__MASK 0x00007fff +#define A4XX_TEX_CONST_1_HEIGHT__SHIFT 0 +static inline uint32_t A4XX_TEX_CONST_1_HEIGHT(uint32_t val) +{ + return ((val) << A4XX_TEX_CONST_1_HEIGHT__SHIFT) & A4XX_TEX_CONST_1_HEIGHT__MASK; +} +#define A4XX_TEX_CONST_1_WIDTH__MASK 0x1fff8000 +#define A4XX_TEX_CONST_1_WIDTH__SHIFT 15 +static inline uint32_t A4XX_TEX_CONST_1_WIDTH(uint32_t val) +{ + return ((val) << A4XX_TEX_CONST_1_WIDTH__SHIFT) & A4XX_TEX_CONST_1_WIDTH__MASK; +} + +#define REG_A4XX_TEX_CONST_2 0x00000002 +#define A4XX_TEX_CONST_2_PITCH__MASK 0x3ffffe00 +#define A4XX_TEX_CONST_2_PITCH__SHIFT 9 +static inline uint32_t A4XX_TEX_CONST_2_PITCH(uint32_t val) +{ + return ((val) << A4XX_TEX_CONST_2_PITCH__SHIFT) & A4XX_TEX_CONST_2_PITCH__MASK; +} +#define A4XX_TEX_CONST_2_SWAP__MASK 0xc0000000 +#define A4XX_TEX_CONST_2_SWAP__SHIFT 30 +static inline uint32_t A4XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val) +{ + return ((val) << A4XX_TEX_CONST_2_SWAP__SHIFT) & A4XX_TEX_CONST_2_SWAP__MASK; +} + +#define REG_A4XX_TEX_CONST_3 0x00000003 +#define A4XX_TEX_CONST_3_LAYERSZ__MASK 0x0000000f +#define A4XX_TEX_CONST_3_LAYERSZ__SHIFT 0 +static inline uint32_t A4XX_TEX_CONST_3_LAYERSZ(uint32_t val) +{ + return ((val >> 12) << A4XX_TEX_CONST_3_LAYERSZ__SHIFT) & A4XX_TEX_CONST_3_LAYERSZ__MASK; +} + +#define REG_A4XX_TEX_CONST_4 0x00000004 +#define A4XX_TEX_CONST_4_BASE__MASK 0xffffffff +#define A4XX_TEX_CONST_4_BASE__SHIFT 0 +static inline uint32_t A4XX_TEX_CONST_4_BASE(uint32_t val) +{ + return ((val) << A4XX_TEX_CONST_4_BASE__SHIFT) & A4XX_TEX_CONST_4_BASE__MASK; +} + +#define REG_A4XX_TEX_CONST_5 0x00000005 + +#define REG_A4XX_TEX_CONST_6 0x00000006 + +#define REG_A4XX_TEX_CONST_7 0x00000007 + + +#endif /* A4XX_XML */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index cc341bc62b51..a4b33af9338d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h @@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) Copyright (C) 2013-2014 by the following authors: - Rob Clark (robclark) @@ -105,6 +105,7 @@ enum adreno_rb_dither_mode { enum adreno_rb_depth_format { DEPTHX_16 = 0, DEPTHX_24_8 = 1, + DEPTHX_32 = 2, }; enum adreno_rb_copy_control_mode { @@ -132,6 +133,7 @@ enum a3xx_threadmode { }; enum a3xx_instrbuffermode { + CACHE = 0, BUFFER = 1, }; @@ -140,6 +142,13 @@ enum a3xx_threadsize { FOUR_QUADS = 1, }; +enum a3xx_color_swap { + WZYX = 0, + WXYZ = 1, + ZYXW = 2, + XYZW = 3, +}; + #define REG_AXXX_CP_RB_BASE 0x000001c0 #define REG_AXXX_CP_RB_CNTL 0x000001c1 diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index 6ef43f66c30a..6a75cee94d81 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h @@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) Copyright (C) 2013-2014 by the following authors: - Rob Clark (robclark) @@ -157,6 +157,7 @@ enum adreno_pm4_type3_packets { CP_IM_STORE = 44, CP_SET_DRAW_INIT_FLAGS = 75, CP_SET_PROTECTED_MODE = 95, + CP_BOOTSTRAP_UCODE = 111, CP_LOAD_STATE = 48, CP_COND_INDIRECT_BUFFER_PFE = 58, CP_COND_INDIRECT_BUFFER_PFD = 50, @@ -278,11 +279,11 @@ static inline uint32_t CP_DRAW_INDX_1_INDEX_SIZE(enum pc_di_index_size val) #define CP_DRAW_INDX_1_NOT_EOP 0x00001000 #define CP_DRAW_INDX_1_SMALL_INDEX 0x00002000 #define CP_DRAW_INDX_1_PRE_DRAW_INITIATOR_ENABLE 0x00004000 -#define CP_DRAW_INDX_1_NUM_INDICES__MASK 0xffff0000 -#define CP_DRAW_INDX_1_NUM_INDICES__SHIFT 16 -static inline uint32_t CP_DRAW_INDX_1_NUM_INDICES(uint32_t val) +#define CP_DRAW_INDX_1_NUM_INSTANCES__MASK 0xff000000 +#define CP_DRAW_INDX_1_NUM_INSTANCES__SHIFT 24 +static inline uint32_t CP_DRAW_INDX_1_NUM_INSTANCES(uint32_t val) { - return ((val) << CP_DRAW_INDX_1_NUM_INDICES__SHIFT) & CP_DRAW_INDX_1_NUM_INDICES__MASK; + return ((val) << CP_DRAW_INDX_1_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_1_NUM_INSTANCES__MASK; } #define REG_CP_DRAW_INDX_2 0x00000002 @@ -293,20 +294,20 @@ static inline uint32_t CP_DRAW_INDX_2_NUM_INDICES(uint32_t val) return ((val) << CP_DRAW_INDX_2_NUM_INDICES__SHIFT) & CP_DRAW_INDX_2_NUM_INDICES__MASK; } -#define REG_CP_DRAW_INDX_2 0x00000002 -#define CP_DRAW_INDX_2_INDX_BASE__MASK 0xffffffff -#define CP_DRAW_INDX_2_INDX_BASE__SHIFT 0 -static inline uint32_t CP_DRAW_INDX_2_INDX_BASE(uint32_t val) +#define REG_CP_DRAW_INDX_3 0x00000003 +#define CP_DRAW_INDX_3_INDX_BASE__MASK 0xffffffff +#define CP_DRAW_INDX_3_INDX_BASE__SHIFT 0 +static inline uint32_t CP_DRAW_INDX_3_INDX_BASE(uint32_t val) { - return ((val) << CP_DRAW_INDX_2_INDX_BASE__SHIFT) & CP_DRAW_INDX_2_INDX_BASE__MASK; + return ((val) << CP_DRAW_INDX_3_INDX_BASE__SHIFT) & CP_DRAW_INDX_3_INDX_BASE__MASK; } -#define REG_CP_DRAW_INDX_2 0x00000002 -#define CP_DRAW_INDX_2_INDX_SIZE__MASK 0xffffffff -#define CP_DRAW_INDX_2_INDX_SIZE__SHIFT 0 -static inline uint32_t CP_DRAW_INDX_2_INDX_SIZE(uint32_t val) +#define REG_CP_DRAW_INDX_4 0x00000004 +#define CP_DRAW_INDX_4_INDX_SIZE__MASK 0xffffffff +#define CP_DRAW_INDX_4_INDX_SIZE__SHIFT 0 +static inline uint32_t CP_DRAW_INDX_4_INDX_SIZE(uint32_t val) { - return ((val) << CP_DRAW_INDX_2_INDX_SIZE__SHIFT) & CP_DRAW_INDX_2_INDX_SIZE__MASK; + return ((val) << CP_DRAW_INDX_4_INDX_SIZE__SHIFT) & CP_DRAW_INDX_4_INDX_SIZE__MASK; } #define REG_CP_DRAW_INDX_2_0 0x00000000 @@ -345,11 +346,11 @@ static inline uint32_t CP_DRAW_INDX_2_1_INDEX_SIZE(enum pc_di_index_size val) #define CP_DRAW_INDX_2_1_NOT_EOP 0x00001000 #define CP_DRAW_INDX_2_1_SMALL_INDEX 0x00002000 #define CP_DRAW_INDX_2_1_PRE_DRAW_INITIATOR_ENABLE 0x00004000 -#define CP_DRAW_INDX_2_1_NUM_INDICES__MASK 0xffff0000 -#define CP_DRAW_INDX_2_1_NUM_INDICES__SHIFT 16 -static inline uint32_t CP_DRAW_INDX_2_1_NUM_INDICES(uint32_t val) +#define CP_DRAW_INDX_2_1_NUM_INSTANCES__MASK 0xff000000 +#define CP_DRAW_INDX_2_1_NUM_INSTANCES__SHIFT 24 +static inline uint32_t CP_DRAW_INDX_2_1_NUM_INSTANCES(uint32_t val) { - return ((val) << CP_DRAW_INDX_2_1_NUM_INDICES__SHIFT) & CP_DRAW_INDX_2_1_NUM_INDICES__MASK; + return ((val) << CP_DRAW_INDX_2_1_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_2_1_NUM_INSTANCES__MASK; } #define REG_CP_DRAW_INDX_2_2 0x00000002 @@ -388,11 +389,11 @@ static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum pc_di_index_size va #define CP_DRAW_INDX_OFFSET_0_NOT_EOP 0x00001000 #define CP_DRAW_INDX_OFFSET_0_SMALL_INDEX 0x00002000 #define CP_DRAW_INDX_OFFSET_0_PRE_DRAW_INITIATOR_ENABLE 0x00004000 -#define CP_DRAW_INDX_OFFSET_0_NUM_INDICES__MASK 0xffff0000 -#define CP_DRAW_INDX_OFFSET_0_NUM_INDICES__SHIFT 16 -static inline uint32_t CP_DRAW_INDX_OFFSET_0_NUM_INDICES(uint32_t val) +#define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK 0xffff0000 +#define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT 16 +static inline uint32_t CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES(uint32_t val) { - return ((val) << CP_DRAW_INDX_OFFSET_0_NUM_INDICES__SHIFT) & CP_DRAW_INDX_OFFSET_0_NUM_INDICES__MASK; + return ((val) << CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK; } #define REG_CP_DRAW_INDX_OFFSET_1 0x00000001 @@ -405,20 +406,22 @@ static inline uint32_t CP_DRAW_INDX_OFFSET_2_NUM_INDICES(uint32_t val) return ((val) << CP_DRAW_INDX_OFFSET_2_NUM_INDICES__SHIFT) & CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK; } -#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002 -#define CP_DRAW_INDX_OFFSET_2_INDX_BASE__MASK 0xffffffff -#define CP_DRAW_INDX_OFFSET_2_INDX_BASE__SHIFT 0 -static inline uint32_t CP_DRAW_INDX_OFFSET_2_INDX_BASE(uint32_t val) +#define REG_CP_DRAW_INDX_OFFSET_3 0x00000003 + +#define REG_CP_DRAW_INDX_OFFSET_4 0x00000004 +#define CP_DRAW_INDX_OFFSET_4_INDX_BASE__MASK 0xffffffff +#define CP_DRAW_INDX_OFFSET_4_INDX_BASE__SHIFT 0 +static inline uint32_t CP_DRAW_INDX_OFFSET_4_INDX_BASE(uint32_t val) { - return ((val) << CP_DRAW_INDX_OFFSET_2_INDX_BASE__SHIFT) & CP_DRAW_INDX_OFFSET_2_INDX_BASE__MASK; + return ((val) << CP_DRAW_INDX_OFFSET_4_INDX_BASE__SHIFT) & CP_DRAW_INDX_OFFSET_4_INDX_BASE__MASK; } -#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002 -#define CP_DRAW_INDX_OFFSET_2_INDX_SIZE__MASK 0xffffffff -#define CP_DRAW_INDX_OFFSET_2_INDX_SIZE__SHIFT 0 -static inline uint32_t CP_DRAW_INDX_OFFSET_2_INDX_SIZE(uint32_t val) +#define REG_CP_DRAW_INDX_OFFSET_5 0x00000005 +#define CP_DRAW_INDX_OFFSET_5_INDX_SIZE__MASK 0xffffffff +#define CP_DRAW_INDX_OFFSET_5_INDX_SIZE__SHIFT 0 +static inline uint32_t CP_DRAW_INDX_OFFSET_5_INDX_SIZE(uint32_t val) { - return ((val) << CP_DRAW_INDX_OFFSET_2_INDX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_2_INDX_SIZE__MASK; + return ((val) << CP_DRAW_INDX_OFFSET_5_INDX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_5_INDX_SIZE__MASK; } #define REG_CP_SET_DRAW_STATE_0 0x00000000 diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index e965898dfda6..448438b759b4 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h index f2bdda957205..c102a7f074ac 100644 --- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h index e5b071ffd865..a900134bdf33 100644 --- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h +++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 76fd0cfc6558..5b0844befbab 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index d53c29327df9..29bd796797de 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h index 03c0bd9cd5b9..a4a7f8c7122a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h @@ -10,12 +10,12 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20457 bytes, from 2014-08-01 12:22:48) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2014-07-17 15:34:33) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-07-17 15:34:33) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-08-01 12:23:53) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h index 67f4f896ba8c..e87ef5512cb0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h @@ -10,14 +10,14 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) -- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05) +- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) -- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44) +- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) Copyright (C) 2013-2014 by the following authors: - Rob Clark (robclark) -- GitLab From 067fef372c7356f64e4d307218df0fae49f9c88e Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 4 Nov 2014 13:33:14 -0500 Subject: [PATCH 4914/9457] drm/msm/hdmi: refactor bind/init Split up hdmi_init() into hdmi_init() (done at hdmi sub-device bind/probe time) and hdmi_modeset_init() done from master driver's modeset_init(). Anything that can fail due to dependencies on other drivers which may be missing or not probed yet should go in hdmi_init(), so that devm error/cleanup paths work properly. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi.c | 99 +++++++++++++++--------- drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 2 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 13 ++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 3 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 11 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 2 - drivers/gpu/drm/msm/msm_drv.h | 10 ++- 7 files changed, 85 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 9d00dcba6959..90077619029d 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -68,24 +68,17 @@ void hdmi_destroy(struct kref *kref) platform_set_drvdata(hdmi->pdev, NULL); } -/* initialize connector */ -struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) +/* construct hdmi at bind/probe time, grab all the resources. If + * we are to EPROBE_DEFER we want to do it here, rather than later + * at modeset_init() time + */ +static struct hdmi *hdmi_init(struct platform_device *pdev) { + struct hdmi_platform_config *config = pdev->dev.platform_data; struct hdmi *hdmi = NULL; - struct msm_drm_private *priv = dev->dev_private; - struct platform_device *pdev = priv->hdmi_pdev; - struct hdmi_platform_config *config; int i, ret; - if (!pdev) { - dev_err(dev->dev, "no hdmi device\n"); - ret = -ENXIO; - goto fail; - } - - config = pdev->dev.platform_data; - - hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) { ret = -ENOMEM; goto fail; @@ -93,12 +86,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) kref_init(&hdmi->refcount); - hdmi->dev = dev; hdmi->pdev = pdev; hdmi->config = config; - hdmi->encoder = encoder; - - hdmi_audio_infoframe_init(&hdmi->audio.infoframe); /* not sure about which phy maps to which msm.. probably I miss some */ if (config->phy_init) @@ -108,7 +97,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) if (IS_ERR(hdmi->phy)) { ret = PTR_ERR(hdmi->phy); - dev_err(dev->dev, "failed to load phy: %d\n", ret); + dev_err(&pdev->dev, "failed to load phy: %d\n", ret); hdmi->phy = NULL; goto fail; } @@ -127,7 +116,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) config->hpd_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev->dev, "failed to get hpd regulator: %s (%d)\n", + dev_err(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", config->hpd_reg_names[i], ret); goto fail; } @@ -143,7 +132,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) config->pwr_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev->dev, "failed to get pwr regulator: %s (%d)\n", + dev_err(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", config->pwr_reg_names[i], ret); goto fail; } @@ -158,7 +147,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) clk = devm_clk_get(&pdev->dev, config->hpd_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - dev_err(dev->dev, "failed to get hpd clk: %s (%d)\n", + dev_err(&pdev->dev, "failed to get hpd clk: %s (%d)\n", config->hpd_clk_names[i], ret); goto fail; } @@ -173,7 +162,7 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) clk = devm_clk_get(&pdev->dev, config->pwr_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - dev_err(dev->dev, "failed to get pwr clk: %s (%d)\n", + dev_err(&pdev->dev, "failed to get pwr clk: %s (%d)\n", config->pwr_clk_names[i], ret); goto fail; } @@ -184,11 +173,41 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) hdmi->i2c = hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { ret = PTR_ERR(hdmi->i2c); - dev_err(dev->dev, "failed to get i2c: %d\n", ret); + dev_err(&pdev->dev, "failed to get i2c: %d\n", ret); hdmi->i2c = NULL; goto fail; } + return hdmi; + +fail: + if (hdmi) + hdmi_destroy(&hdmi->refcount); + + return ERR_PTR(ret); +} + +/* Second part of initialization, the drm/kms level modeset_init, + * constructs/initializes mode objects, etc, is called from master + * driver (not hdmi sub-device's probe/bind!) + * + * Any resource (regulator/clk/etc) which could be missing at boot + * should be handled in hdmi_init() so that failure happens from + * hdmi sub-device's probe. + */ +int hdmi_modeset_init(struct hdmi *hdmi, + struct drm_device *dev, struct drm_encoder *encoder) +{ + struct msm_drm_private *priv = dev->dev_private; + struct platform_device *pdev = hdmi->pdev; + struct hdmi_platform_config *config = pdev->dev.platform_data; + int ret; + + hdmi->dev = dev; + hdmi->encoder = encoder; + + hdmi_audio_infoframe_init(&hdmi->audio.infoframe); + hdmi->bridge = hdmi_bridge_init(hdmi); if (IS_ERR(hdmi->bridge)) { ret = PTR_ERR(hdmi->bridge); @@ -230,19 +249,20 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) platform_set_drvdata(pdev, hdmi); - return hdmi; + return 0; fail: - if (hdmi) { - /* bridge/connector are normally destroyed by drm: */ - if (hdmi->bridge) - hdmi->bridge->funcs->destroy(hdmi->bridge); - if (hdmi->connector) - hdmi->connector->funcs->destroy(hdmi->connector); - hdmi_destroy(&hdmi->refcount); + /* bridge/connector are normally destroyed by drm: */ + if (hdmi->bridge) { + hdmi->bridge->funcs->destroy(hdmi->bridge); + hdmi->bridge = NULL; + } + if (hdmi->connector) { + hdmi->connector->funcs->destroy(hdmi->connector); + hdmi->connector = NULL; } - return ERR_PTR(ret); + return ret; } /* @@ -251,11 +271,10 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) #include -static void set_hdmi_pdev(struct drm_device *dev, - struct platform_device *pdev) +static void set_hdmi(struct drm_device *dev, struct hdmi *hdmi) { struct msm_drm_private *priv = dev->dev_private; - priv->hdmi_pdev = pdev; + priv->hdmi = hdmi; } #ifdef CONFIG_OF @@ -279,6 +298,7 @@ static int get_gpio(struct device *dev, struct device_node *of_node, const char static int hdmi_bind(struct device *dev, struct device *master, void *data) { static struct hdmi_platform_config config = {}; + struct hdmi *hdmi; #ifdef CONFIG_OF struct device_node *of_node = dev->of_node; @@ -369,14 +389,17 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) } #endif dev->platform_data = &config; - set_hdmi_pdev(dev_get_drvdata(master), to_platform_device(dev)); + hdmi = hdmi_init(to_platform_device(dev)); + if (IS_ERR(hdmi)) + return PTR_ERR(hdmi); + set_hdmi(dev_get_drvdata(master), hdmi); return 0; } static void hdmi_unbind(struct device *dev, struct device *master, void *data) { - set_hdmi_pdev(dev_get_drvdata(master), NULL); + set_hdmi(dev_get_drvdata(master), NULL); } static const struct component_ops hdmi_ops = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c index f408b69486a8..eeed006eed13 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c @@ -510,7 +510,7 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi) #ifdef CONFIG_COMMON_CLK phy_8960->pll_hw.init = &pll_init; - phy_8960->pll = devm_clk_register(hdmi->dev->dev, &phy_8960->pll_hw); + phy_8960->pll = devm_clk_register(&hdmi->pdev->dev, &phy_8960->pll_hw); if (IS_ERR(phy_8960->pll)) { ret = PTR_ERR(phy_8960->pll); phy_8960->pll = NULL; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index ac204720429e..a62109e4ae0d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -228,7 +228,6 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) struct drm_encoder *encoder; struct drm_connector *connector; struct drm_panel *panel; - struct hdmi *hdmi; int ret; /* construct non-private planes: */ @@ -326,11 +325,13 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) priv->crtcs[priv->num_crtcs++] = crtc; priv->encoders[priv->num_encoders++] = encoder; - hdmi = hdmi_init(dev, encoder); - if (IS_ERR(hdmi)) { - ret = PTR_ERR(hdmi); - dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); - goto fail; + if (priv->hdmi) { + /* Construct bridge/connector for HDMI: */ + ret = hdmi_modeset_init(priv->hdmi, dev, encoder); + if (ret) { + dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); + goto fail; + } } return 0; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index f2b985bc2adf..812c59bbaf7f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -82,6 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) { struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); + struct msm_drm_private *priv = mdp5_kms->dev->dev_private; uint32_t intr; intr = mdp5_read(mdp5_kms, REG_MDP5_HW_INTR_STATUS); @@ -92,7 +93,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) mdp5_irq_mdp(mdp_kms); if (intr & MDP5_HW_INTR_STATUS_INTR_HDMI) - hdmi_irq(0, mdp5_kms->hdmi); + hdmi_irq(0, priv->hdmi); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 31a2c6331a1d..ce0308124a72 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -324,11 +324,12 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) priv->encoders[priv->num_encoders++] = encoder; /* Construct bridge/connector for HDMI: */ - mdp5_kms->hdmi = hdmi_init(dev, encoder); - if (IS_ERR(mdp5_kms->hdmi)) { - ret = PTR_ERR(mdp5_kms->hdmi); - dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); - goto fail; + if (priv->hdmi) { + ret = hdmi_modeset_init(priv->hdmi, dev, encoder); + if (ret) { + dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); + goto fail; + } } return 0; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 5bf340dd0f00..c91101d5ac0f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -71,8 +71,6 @@ struct mdp5_kms { struct clk *lut_clk; struct clk *vsync_clk; - struct hdmi *hdmi; - struct mdp_irq error_handler; }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 67f9d0a2332c..a0398b72ea21 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -75,7 +75,12 @@ struct msm_drm_private { struct msm_kms *kms; /* subordinate devices, if present: */ - struct platform_device *hdmi_pdev, *gpu_pdev; + struct platform_device *gpu_pdev; + + /* possibly this should be in the kms component, but it is + * shared by both mdp4 and mdp5.. + */ + struct hdmi *hdmi; /* when we have more than one 'msm_gpu' these need to be an array: */ struct msm_gpu *gpu; @@ -202,7 +207,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev, struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); struct hdmi; -struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder); +int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, + struct drm_encoder *encoder); irqreturn_t hdmi_irq(int irq, void *dev_id); void __init hdmi_register(void); void __exit hdmi_unregister(void); -- GitLab From 77a147e742afe33a612d93d61ba153df668de428 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 12 Nov 2014 11:38:14 +0000 Subject: [PATCH 4915/9457] drm/msm: Allow exported dma-bufs to be mapped Currently msm does not implement gem_prime_mmap. Without this it is not possible to draw onto a dma-buf from userspace (making its very hard to implement the Android rendering model). Fixing this is just a matter of adding a little boilerplate. Signed-off-by: Daniel Thompson Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 1 + drivers/gpu/drm/msm/msm_drv.h | 3 +++ drivers/gpu/drm/msm/msm_gem_prime.c | 13 +++++++++++++ 3 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b67ef5985125..5717d4ec1a2c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -832,6 +832,7 @@ static struct drm_driver msm_driver = { .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, .gem_prime_vmap = msm_gem_prime_vmap, .gem_prime_vunmap = msm_gem_prime_vunmap, + .gem_prime_mmap = msm_gem_prime_mmap, #ifdef CONFIG_DEBUG_FS .debugfs_init = msm_debugfs_init, .debugfs_cleanup = msm_debugfs_cleanup, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index a0398b72ea21..c763c19405de 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -159,6 +159,8 @@ void msm_update_fence(struct drm_device *dev, uint32_t fence); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); +int msm_gem_mmap_obj(struct drm_gem_object *obj, + struct vm_area_struct *vma); int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma); int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); @@ -175,6 +177,7 @@ int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj); void *msm_gem_prime_vmap(struct drm_gem_object *obj); void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); +int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); int msm_gem_prime_pin(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c index ad772fe36115..dd7a7ab603e2 100644 --- a/drivers/gpu/drm/msm/msm_gem_prime.c +++ b/drivers/gpu/drm/msm/msm_gem_prime.c @@ -37,6 +37,19 @@ void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) /* TODO msm_gem_vunmap() */ } +int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + int ret; + + mutex_lock(&obj->dev->struct_mutex); + ret = drm_gem_mmap_obj(obj, obj->size, vma); + mutex_unlock(&obj->dev->struct_mutex); + if (ret < 0) + return ret; + + return msm_gem_mmap_obj(vma->vm_private_data, vma); +} + struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg) { -- GitLab From 95a9b8d10cb0ee78c1eb81ea51eeaf94be479416 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 17 Oct 2014 16:48:54 +0100 Subject: [PATCH 4916/9457] drm/msm: Fix fbdev for 16- and 24-bit modes. Currently forcing the video mode from the kernel command line (for example video=HDMI-A-1:1280x720-16@60) does not correctly set the number of bits per pixel. This is due to a rather aggressive override in msm_fbdev_create(). This is a particular problem for Android bring up because the software EGL fallbacks don't support 32bpp. Since the overrides are actually the default values anyway then this problem can be trivially fixed by removing the overrides completely. Change was tested by dd'ing a test image to /dev/fb0 with no video= (still 32bpp), video=1920x1080-32@60, video=1920x1080-24@60 and video=1920x1080-16@60 . Signed-off-by: Daniel Thompson Cc: David Airlie Cc: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fbdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index ab5bfd2d0ebf..94d55e526b4e 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -93,9 +93,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, uint32_t paddr; int ret, size; - sizes->surface_bpp = 32; - sizes->surface_depth = 24; - DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width, sizes->surface_height, sizes->surface_bpp, sizes->fb_width, sizes->fb_height); -- GitLab From 466c2686717ad643193c7a7dffe74697c841e77d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 7 Nov 2014 13:04:51 -0500 Subject: [PATCH 4917/9457] drm/msm/mdp4: drop private primary ptr Since primary-plane support in core, we can just use crtc->primary. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 1ca87ae53d35..5d2913f179b1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -25,7 +25,6 @@ struct mdp4_crtc { struct drm_crtc base; char name[8]; - struct drm_plane *plane; struct drm_plane *planes[8]; int id; int ovlp; @@ -188,7 +187,7 @@ static void pageflip_cb(struct msm_fence_cb *cb) return; drm_framebuffer_reference(fb); - mdp4_plane_set_scanout(mdp4_crtc->plane, fb); + mdp4_plane_set_scanout(crtc->primary, fb); update_scanout(crtc, fb); } @@ -353,7 +352,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, /* grab extra ref for update_scanout() */ drm_framebuffer_reference(crtc->primary->fb); - ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->primary->fb, + ret = mdp4_plane_mode_set(crtc->primary, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); @@ -419,8 +418,7 @@ static void mdp4_crtc_commit(struct drm_crtc *crtc) static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct drm_plane *plane = mdp4_crtc->plane; + struct drm_plane *plane = crtc->primary; struct drm_display_mode *mode = &crtc->mode; int ret; @@ -729,7 +727,7 @@ static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id, mdp4_crtc->planes[pipe_id] = plane; blend_setup(crtc); - if (mdp4_crtc->enabled && (plane != mdp4_crtc->plane)) + if (mdp4_crtc->enabled && (plane != crtc->primary)) crtc_flush(crtc); } @@ -741,7 +739,7 @@ void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) { /* don't actually detatch our primary plane: */ - if (to_mdp4_crtc(crtc)->plane == plane) + if (crtc->primary == plane) return; set_attach(crtc, mdp4_plane_pipe(plane), NULL); } @@ -764,7 +762,6 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, crtc = &mdp4_crtc->base; - mdp4_crtc->plane = plane; mdp4_crtc->id = id; mdp4_crtc->ovlp = ovlp_id; @@ -791,7 +788,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs); drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); - mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base); + mdp4_plane_install_properties(plane, &crtc->base); return crtc; } -- GitLab From 8845ef80413a6a63a7d91bf15ccbcc9df3466b0c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 12 Nov 2014 11:22:19 -0500 Subject: [PATCH 4918/9457] drm/msm/mdp5: drop private primary ptr Since primary-plane support in core, we can just use crtc->primary. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 2979a2cc82a4..12414472d55a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -25,7 +25,6 @@ struct mdp5_crtc { struct drm_crtc base; char name[8]; - struct drm_plane *plane; struct drm_plane *planes[8]; int id; bool enabled; @@ -176,7 +175,7 @@ static void pageflip_cb(struct msm_fence_cb *cb) return; drm_framebuffer_reference(fb); - mdp5_plane_set_scanout(mdp5_crtc->plane, fb); + mdp5_plane_set_scanout(crtc->primary, fb); update_scanout(crtc, fb); } @@ -289,7 +288,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, /* grab extra ref for update_scanout() */ drm_framebuffer_reference(crtc->primary->fb); - ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->primary->fb, + ret = mdp5_plane_mode_set(crtc->primary, crtc, crtc->primary->fb, 0, 0, mode->hdisplay, mode->vdisplay, x << 16, y << 16, mode->hdisplay << 16, mode->vdisplay << 16); @@ -330,8 +329,7 @@ static void mdp5_crtc_commit(struct drm_crtc *crtc) static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { - struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - struct drm_plane *plane = mdp5_crtc->plane; + struct drm_plane *plane = crtc->primary; struct drm_display_mode *mode = &crtc->mode; int ret; @@ -511,7 +509,7 @@ static void set_attach(struct drm_crtc *crtc, enum mdp5_pipe pipe_id, mdp5_crtc->planes[pipe_id] = plane; blend_setup(crtc); - if (mdp5_crtc->enabled && (plane != mdp5_crtc->plane)) + if (mdp5_crtc->enabled && (plane != crtc->primary)) crtc_flush(crtc); } @@ -523,7 +521,7 @@ void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) { /* don't actually detatch our primary plane: */ - if (to_mdp5_crtc(crtc)->plane == plane) + if (crtc->primary == plane) return; set_attach(crtc, mdp5_plane_pipe(plane), NULL); } @@ -541,7 +539,6 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, crtc = &mdp5_crtc->base; - mdp5_crtc->plane = plane; mdp5_crtc->id = id; mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq; @@ -558,7 +555,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); - mdp5_plane_install_properties(mdp5_crtc->plane, &crtc->base); + mdp5_plane_install_properties(plane, &crtc->base); return crtc; } -- GitLab From 88ff1c2f3b5d4826bbe3b6ec3cf12a223dc0cb22 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 7 Nov 2014 13:06:54 -0500 Subject: [PATCH 4919/9457] drm/msm/mdp4: don't care about fb in crtc Since we are configuring things via MDP4_PIPE regs in the plane, it seems like setting the dimensions of the primary plane on the OVLP/DMA regs in crtc is unnecessary. This will make life easier when we want to do a nofb modeset. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 5d2913f179b1..d0e6c279cc72 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -369,8 +369,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, /* take data from pipe: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0); - mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma), - crtc->primary->fb->pitches[0]); + mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma), 0); mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma), MDP4_DMA_DST_SIZE_WIDTH(0) | MDP4_DMA_DST_SIZE_HEIGHT(0)); @@ -379,8 +378,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, mdp4_write(mdp4_kms, REG_MDP4_OVLP_SIZE(ovlp), MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) | MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay)); - mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp), - crtc->primary->fb->pitches[0]); + mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp), 0); mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); -- GitLab From bb6c018d3556dd683e3f16d24f2e9d60bcaed1b2 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 7 Nov 2014 13:20:50 -0500 Subject: [PATCH 4920/9457] drm/msm/mdp4: drop attached planes table Simplify things a bit for atomic, gets rid of some bookkeeping, and makes the code cleaner. TODO move iterator macro somewhere common. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 41 +++++++++--------------- drivers/gpu/drm/msm/msm_kms.h | 5 +++ 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index d0e6c279cc72..a28b1615b3d4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -25,7 +25,6 @@ struct mdp4_crtc { struct drm_crtc base; char name[8]; - struct drm_plane *planes[8]; int id; int ovlp; enum mdp4_dma dma; @@ -96,15 +95,14 @@ static void crtc_flush(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); - uint32_t i, flush = 0; + struct drm_plane *plane; + uint32_t flush = 0; - for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { - struct drm_plane *plane = mdp4_crtc->planes[i]; - if (plane) { - enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); - flush |= pipe2flush(pipe_id); - } + for_each_plane_on_crtc(crtc, plane) { + enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); + flush |= pipe2flush(pipe_id); } + flush |= ovlp2flush(mdp4_crtc->ovlp); DBG("%s: flush=%08x", mdp4_crtc->name, flush); @@ -254,6 +252,7 @@ static void blend_setup(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); + struct drm_plane *plane; int i, ovlp = mdp4_crtc->ovlp; uint32_t mixer_cfg = 0; static const enum mdp_mixer_stage_id stages[] = { @@ -283,19 +282,16 @@ static void blend_setup(struct drm_crtc *crtc) mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0); mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0); - for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { - struct drm_plane *plane = mdp4_crtc->planes[i]; - if (plane) { - enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); - int idx = idxs[pipe_id]; - if (idx > 0) { - const struct mdp_format *format = + for_each_plane_on_crtc(crtc, plane) { + enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); + int idx = idxs[pipe_id]; + if (idx > 0) { + const struct mdp_format *format = to_mdp_format(msm_framebuffer_format(plane->fb)); - alpha[idx-1] = format->alpha_enable; - } - mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, - pipe_id, stages[idx]); + alpha[idx-1] = format->alpha_enable; } + mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, + pipe_id, stages[idx]); } /* this shouldn't happen.. and seems to cause underflow: */ @@ -718,12 +714,6 @@ static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id, { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - BUG_ON(pipe_id >= ARRAY_SIZE(mdp4_crtc->planes)); - - if (mdp4_crtc->planes[pipe_id] == plane) - return; - - mdp4_crtc->planes[pipe_id] = plane; blend_setup(crtc); if (mdp4_crtc->enabled && (plane != crtc->primary)) crtc_flush(crtc); @@ -785,6 +775,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs); drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); + plane->crtc = crtc; mdp4_plane_install_properties(plane, &crtc->base); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 06437745bc2c..15a0fec99c70 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -65,4 +65,9 @@ static inline void msm_kms_init(struct msm_kms *kms, struct msm_kms *mdp4_kms_init(struct drm_device *dev); struct msm_kms *mdp5_kms_init(struct drm_device *dev); +/* TODO move these helper iterator macro somewhere common: */ +#define for_each_plane_on_crtc(_crtc, _plane) \ + list_for_each_entry((_plane), &(_crtc)->dev->mode_config.plane_list, head) \ + if ((_plane)->crtc == (_crtc)) + #endif /* __MSM_KMS_H__ */ -- GitLab From 0372bf5c096217447157d41c3eee1fab1bac6c7e Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Fri, 14 Nov 2014 18:33:19 +0100 Subject: [PATCH 4921/9457] tipc: allow one link per bearer to neighboring nodes There is no reason to limit the amount of possible links to a neighboring node to 2. If we have more then two bearers we can also establish more links. Signed-off-by: Holger Brunck Reviewed-By: Jon Maloy cc: Ying Xue cc: Erik Hugne cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- net/tipc/link.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 1db162aa64a5..7cf8004577f1 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -224,9 +224,10 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, char addr_string[16]; u32 peer = n_ptr->addr; - if (n_ptr->link_cnt >= 2) { + if (n_ptr->link_cnt >= MAX_BEARERS) { tipc_addr_string_fill(addr_string, n_ptr->addr); - pr_err("Attempt to establish third link to %s\n", addr_string); + pr_err("Attempt to establish %uth link to %s. Max %u allowed.\n", + n_ptr->link_cnt, addr_string, MAX_BEARERS); return NULL; } -- GitLab From a8cecf33249b80d8a3c2ca5df1c45eb3b5231b28 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 12 Nov 2014 11:37:12 -0500 Subject: [PATCH 4922/9457] drm/msm/mdp5: drop attached planes table Simplify things a bit for atomic, gets rid of some bookkeeping, and makes the code cleaner. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 31 +++++++++--------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 12414472d55a..b7b32c47fd71 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -25,7 +25,6 @@ struct mdp5_crtc { struct drm_crtc base; char name[8]; - struct drm_plane *planes[8]; int id; bool enabled; @@ -77,15 +76,14 @@ static void crtc_flush(struct drm_crtc *crtc) struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_kms *mdp5_kms = get_kms(crtc); int id = mdp5_crtc->id; - uint32_t i, flush = 0; + struct drm_plane *plane; + uint32_t flush = 0; - for (i = 0; i < ARRAY_SIZE(mdp5_crtc->planes); i++) { - struct drm_plane *plane = mdp5_crtc->planes[i]; - if (plane) { - enum mdp5_pipe pipe = mdp5_plane_pipe(plane); - flush |= pipe2flush(pipe); - } + for_each_plane_on_crtc(crtc, plane) { + enum mdp5_pipe pipe = mdp5_plane_pipe(plane); + flush |= pipe2flush(pipe); } + flush |= mixer2flush(mdp5_crtc->id); flush |= MDP5_CTL_FLUSH_CTL; @@ -141,7 +139,8 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_pending_vblank_event *event; - unsigned long flags, i; + struct drm_plane *plane; + unsigned long flags; spin_lock_irqsave(&dev->event_lock, flags); event = mdp5_crtc->event; @@ -157,11 +156,8 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) } spin_unlock_irqrestore(&dev->event_lock, flags); - for (i = 0; i < ARRAY_SIZE(mdp5_crtc->planes); i++) { - struct drm_plane *plane = mdp5_crtc->planes[i]; - if (plane) - mdp5_plane_complete_flip(plane); - } + for_each_plane_on_crtc(crtc, plane) + mdp5_plane_complete_flip(plane); } static void pageflip_cb(struct msm_fence_cb *cb) @@ -502,12 +498,6 @@ static void set_attach(struct drm_crtc *crtc, enum mdp5_pipe pipe_id, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - BUG_ON(pipe_id >= ARRAY_SIZE(mdp5_crtc->planes)); - - if (mdp5_crtc->planes[pipe_id] == plane) - return; - - mdp5_crtc->planes[pipe_id] = plane; blend_setup(crtc); if (mdp5_crtc->enabled && (plane != crtc->primary)) crtc_flush(crtc); @@ -554,6 +544,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); + plane->crtc = crtc; mdp5_plane_install_properties(plane, &crtc->base); -- GitLab From 69193e5060dd1c8f7cd614bad05f33f3e042ae6d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 7 Nov 2014 18:10:04 -0500 Subject: [PATCH 4923/9457] drm/msm: small fence cleanup Give ourselves a way to wait for certain fence #.. makes it easier to wait on a set of bo's, which we'll need for atomic. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 20 ++++++++++++++++++++ drivers/gpu/drm/msm/msm_drv.h | 2 ++ drivers/gpu/drm/msm/msm_gem.c | 25 ++++--------------------- drivers/gpu/drm/msm/msm_gem.h | 13 +++++++++++++ 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 5717d4ec1a2c..1456b1c3e890 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -619,6 +619,26 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, return ret; } +int msm_queue_fence_cb(struct drm_device *dev, + struct msm_fence_cb *cb, uint32_t fence) +{ + struct msm_drm_private *priv = dev->dev_private; + int ret = 0; + + mutex_lock(&dev->struct_mutex); + if (!list_empty(&cb->work.entry)) { + ret = -EINVAL; + } else if (fence > priv->completed_fence) { + cb->fence = fence; + list_add_tail(&cb->work.entry, &priv->fence_cbs); + } else { + queue_work(priv->wq, &cb->work); + } + mutex_unlock(&dev->struct_mutex); + + return ret; +} + /* called from workqueue */ void msm_update_fence(struct drm_device *dev, uint32_t fence) { diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index c763c19405de..5901be444777 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -154,6 +154,8 @@ int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, struct timespec *timeout); +int msm_queue_fence_cb(struct drm_device *dev, + struct msm_fence_cb *cb, uint32_t fence); void msm_update_fence(struct drm_device *dev, uint32_t fence); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 4b1b82adabde..8207862b70d1 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -397,23 +397,10 @@ void *msm_gem_vaddr(struct drm_gem_object *obj) int msm_gem_queue_inactive_cb(struct drm_gem_object *obj, struct msm_fence_cb *cb) { - struct drm_device *dev = obj->dev; - struct msm_drm_private *priv = dev->dev_private; struct msm_gem_object *msm_obj = to_msm_bo(obj); - int ret = 0; - - mutex_lock(&dev->struct_mutex); - if (!list_empty(&cb->work.entry)) { - ret = -EINVAL; - } else if (is_active(msm_obj)) { - cb->fence = max(msm_obj->read_fence, msm_obj->write_fence); - list_add_tail(&cb->work.entry, &priv->fence_cbs); - } else { - queue_work(priv->wq, &cb->work); - } - mutex_unlock(&dev->struct_mutex); - - return ret; + uint32_t fence = msm_gem_fence(msm_obj, + MSM_PREP_READ | MSM_PREP_WRITE); + return msm_queue_fence_cb(obj->dev, cb, fence); } void msm_gem_move_to_active(struct drm_gem_object *obj, @@ -452,12 +439,8 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, int ret = 0; if (is_active(msm_obj)) { - uint32_t fence = 0; + uint32_t fence = msm_gem_fence(msm_obj, op); - if (op & MSM_PREP_READ) - fence = msm_obj->write_fence; - if (op & MSM_PREP_WRITE) - fence = max(fence, msm_obj->read_fence); if (op & MSM_PREP_NOSYNC) timeout = NULL; diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index bfb052688f8e..8fbbd0594c46 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -70,6 +70,19 @@ static inline bool is_active(struct msm_gem_object *msm_obj) return msm_obj->gpu != NULL; } +static inline uint32_t msm_gem_fence(struct msm_gem_object *msm_obj, + uint32_t op) +{ + uint32_t fence = 0; + + if (op & MSM_PREP_READ) + fence = msm_obj->write_fence; + if (op & MSM_PREP_WRITE) + fence = max(fence, msm_obj->read_fence); + + return fence; +} + #define MAX_CMDS 4 /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, -- GitLab From 032f8d5c41082ceb457a601f9c464233a3876291 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 7 Nov 2014 18:11:02 -0500 Subject: [PATCH 4924/9457] drm/msm: remove unused compile-test stub Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 5901be444777..5ab6c3dff3c0 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -32,15 +32,6 @@ #include #include - -#if defined(CONFIG_COMPILE_TEST) && !defined(CONFIG_ARCH_QCOM) -/* stubs we need for compile-test: */ -static inline struct device *msm_iommu_get_ctx(const char *ctx_name) -{ - return NULL; -} -#endif - #ifndef CONFIG_OF #include #include -- GitLab From 2638d90abbe7dc23448f6b6b723cb91344cf93aa Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 09:13:37 -0500 Subject: [PATCH 4925/9457] drm/msm: fb prepare/cleanup Atomic wants to split the prepare/pin from where we actually program the scanout address (so that any part that can fail is done synchronously). Add some fb/gem apis to make this easier to use from the kms parts. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 4 ++++ drivers/gpu/drm/msm/msm_fb.c | 36 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_gem.c | 11 +++++++++++ 3 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 5ab6c3dff3c0..4a7e8b8ff649 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -160,6 +160,7 @@ uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, uint32_t *iova); int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova); +uint32_t msm_gem_iova(struct drm_gem_object *obj, int id); struct page **msm_gem_get_pages(struct drm_gem_object *obj); void msm_gem_put_pages(struct drm_gem_object *obj); void msm_gem_put_iova(struct drm_gem_object *obj, int id); @@ -193,6 +194,9 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, struct drm_gem_object *msm_gem_import(struct drm_device *dev, uint32_t size, struct sg_table *sgt); +int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id); +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id); +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane); struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb); struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 81bafdf19ab3..acf34ec80a75 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -87,6 +87,42 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) } #endif +/* prepare/pin all the fb's bo's for scanout. Note that it is not valid + * to prepare an fb more multiple different initiator 'id's. But that + * should be fine, since only the scanout (mdpN) side of things needs + * this, the gpu doesn't care about fb's. + */ +int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id) +{ + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); + int ret, i, n = drm_format_num_planes(fb->pixel_format); + uint32_t iova; + + for (i = 0; i < n; i++) { + ret = msm_gem_get_iova(msm_fb->planes[i], id, &iova); + DBG("FB[%u]: iova[%d]: %08x (%d)", fb->base.id, i, iova, ret); + if (ret) + return ret; + } + + return 0; +} + +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id) +{ + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); + int i, n = drm_format_num_planes(fb->pixel_format); + + for (i = 0; i < n; i++) + msm_gem_put_iova(msm_fb->planes[i], id); +} + +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane) +{ + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); + return msm_gem_iova(msm_fb->planes[plane], id); +} + struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 8207862b70d1..aaa7898b0b6d 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -309,6 +309,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, return ret; } +/* get iova, taking a reference. Should have a matching put */ int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -328,6 +329,16 @@ int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova) return ret; } +/* get iova without taking a reference, used in places where you have + * already done a 'msm_gem_get_iova()'. + */ +uint32_t msm_gem_iova(struct drm_gem_object *obj, int id) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + WARN_ON(!msm_obj->domain[id].iova); + return msm_obj->domain[id].iova; +} + void msm_gem_put_iova(struct drm_gem_object *obj, int id) { // XXX TODO .. -- GitLab From 10291bff0a5f811310ac2f6d0e382d00907a2943 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 09:20:28 -0500 Subject: [PATCH 4926/9457] drm/msm: bit of fb error checking It's a problem that can't happen yet, since we don't support any multi-planar formats yet. But let's avoid nasty surprises when the time comes. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index acf34ec80a75..f4e42d506ff7 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -24,7 +24,7 @@ struct msm_framebuffer { struct drm_framebuffer base; const struct msm_format *format; - struct drm_gem_object *planes[2]; + struct drm_gem_object *planes[3]; }; #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) @@ -202,6 +202,11 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, msm_fb->format = format; + if (n > ARRAY_SIZE(msm_fb->planes)) { + ret = -EINVAL; + goto fail; + } + for (i = 0; i < n; i++) { unsigned int width = mode_cmd->width / (i ? hsub : 1); unsigned int height = mode_cmd->height / (i ? vsub : 1); -- GitLab From cf3a7e4ce08e6876cdcb80390876647f28a7cf8f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 13:21:06 -0500 Subject: [PATCH 4927/9457] drm/msm: atomic core bits The core parts for async commit. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/msm_atomic.c | 163 +++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_drv.c | 4 + drivers/gpu/drm/msm/msm_drv.h | 6 ++ 4 files changed, 174 insertions(+) create mode 100644 drivers/gpu/drm/msm/msm_atomic.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 6283dcb96af5..415a145a9829 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -30,6 +30,7 @@ msm-y := \ mdp/mdp5/mdp5_kms.o \ mdp/mdp5/mdp5_plane.o \ mdp/mdp5/mdp5_smp.o \ + msm_atomic.o \ msm_drv.o \ msm_fb.o \ msm_gem.o \ diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c new file mode 100644 index 000000000000..8cf3361daba3 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014 Red Hat + * Author: Rob Clark + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "msm_drv.h" +#include "msm_kms.h" +#include "msm_gem.h" + +struct msm_commit { + struct drm_atomic_state *state; + uint32_t fence; + struct msm_fence_cb fence_cb; +}; + +static void fence_cb(struct msm_fence_cb *cb); + +static struct msm_commit *new_commit(struct drm_atomic_state *state) +{ + struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); + + if (!c) + return NULL; + + c->state = state; + /* TODO we might need a way to indicate to run the cb on a + * different wq so wait_for_vblanks() doesn't block retiring + * bo's.. + */ + INIT_FENCE_CB(&c->fence_cb, fence_cb); + + return c; +} + +/* The (potentially) asynchronous part of the commit. At this point + * nothing can fail short of armageddon. + */ +static void complete_commit(struct msm_commit *c) +{ + struct drm_atomic_state *state = c->state; + struct drm_device *dev = state->dev; + + drm_atomic_helper_commit_pre_planes(dev, state); + + drm_atomic_helper_commit_planes(dev, state); + + drm_atomic_helper_commit_post_planes(dev, state); + + drm_atomic_helper_wait_for_vblanks(dev, state); + + drm_atomic_helper_cleanup_planes(dev, state); + + drm_atomic_state_free(state); + + kfree(c); +} + +static void fence_cb(struct msm_fence_cb *cb) +{ + struct msm_commit *c = + container_of(cb, struct msm_commit, fence_cb); + complete_commit(c); +} + +static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb) +{ + struct drm_gem_object *obj = msm_framebuffer_bo(fb, 0); + c->fence = max(c->fence, msm_gem_fence(to_msm_bo(obj), MSM_PREP_READ)); +} + + +/** + * drm_atomic_helper_commit - commit validated state object + * @dev: DRM device + * @state: the driver state object + * @async: asynchronous commit + * + * This function commits a with drm_atomic_helper_check() pre-validated state + * object. This can still fail when e.g. the framebuffer reservation fails. For + * now this doesn't implement asynchronous commits. + * + * RETURNS + * Zero for success or -errno. + */ +int msm_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, bool async) +{ + struct msm_commit *c; + int nplanes = dev->mode_config.num_total_plane; + int i, ret; + + ret = drm_atomic_helper_prepare_planes(dev, state); + if (ret) + return ret; + + c = new_commit(state); + + /* + * Figure out what fence to wait for: + */ + for (i = 0; i < nplanes; i++) { + struct drm_plane *plane = state->planes[i]; + struct drm_plane_state *new_state = state->plane_states[i]; + + if (!plane) + continue; + + if (plane->state->fb != new_state->fb) + add_fb(c, new_state->fb); + } + + /* + * This is the point of no return - everything below never fails except + * when the hw goes bonghits. Which means we can commit the new state on + * the software side now. + */ + + drm_atomic_helper_swap_state(dev, state); + + /* + * Everything below can be run asynchronously without the need to grab + * any modeset locks at all under one conditions: It must be guaranteed + * that the asynchronous work has either been cancelled (if the driver + * supports it, which at least requires that the framebuffers get + * cleaned up with drm_atomic_helper_cleanup_planes()) or completed + * before the new state gets committed on the software side with + * drm_atomic_helper_swap_state(). + * + * This scheme allows new atomic state updates to be prepared and + * checked in parallel to the asynchronous completion of the previous + * update. Which is important since compositors need to figure out the + * composition of the next frame right after having submitted the + * current layout. + */ + + if (async) { + msm_queue_fence_cb(dev, &c->fence_cb, c->fence); + return 0; + } + + ret = msm_wait_fence_interruptable(dev, c->fence, NULL); + if (ret) { + WARN_ON(ret); // TODO unswap state back? or?? + kfree(c); + return ret; + } + + complete_commit(c); + + return 0; +} diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 1456b1c3e890..d3b791b7ddef 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -29,6 +29,8 @@ static void msm_fb_output_poll_changed(struct drm_device *dev) static const struct drm_mode_config_funcs mode_config_funcs = { .fb_create = msm_framebuffer_create, .output_poll_changed = msm_fb_output_poll_changed, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = msm_atomic_commit, }; int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu) @@ -294,6 +296,8 @@ static int msm_load(struct drm_device *dev, unsigned long flags) goto fail; } + drm_mode_config_reset(dev); + #ifdef CONFIG_DRM_MSM_FBDEV priv->fbdev = msm_fbdev_init(dev); #endif diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 4a7e8b8ff649..4b52d752bb6e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -39,7 +39,10 @@ #endif #include +#include +#include #include +#include #include #include #include @@ -141,6 +144,9 @@ void __msm_fence_worker(struct work_struct *work); (_cb)->func = _func; \ } while (0) +int msm_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, bool async); + int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, -- GitLab From 3e7849efe0371fd63226a63be0ca87cd31705a37 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 13:23:07 -0500 Subject: [PATCH 4928/9457] drm/msm/hdmi: atomic Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index 4aca2a3c667c..0aecb2580072 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -401,6 +401,9 @@ static const struct drm_connector_funcs hdmi_connector_funcs = { .detect = hdmi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = hdmi_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { -- GitLab From e27c54ffd2b30f9e09f13211869449ec97c6e42f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 13:24:08 -0500 Subject: [PATCH 4929/9457] drm/msm/mdp4: atomic Convert mdp4 display controller backend to atomic helpers. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 216 ++++-------------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 10 - .../drm/msm/mdp/mdp4/mdp4_lvds_connector.c | 3 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 120 ++++++---- 4 files changed, 126 insertions(+), 223 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index a28b1615b3d4..fef22e8cabb6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -50,25 +50,11 @@ struct mdp4_crtc { /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; - struct msm_fence_cb pageflip_cb; #define PENDING_CURSOR 0x1 #define PENDING_FLIP 0x2 atomic_t pending; - /* the fb that we logically (from PoV of KMS API) hold a ref - * to. Which we may not yet be scanning out (we may still - * be scanning out previous in case of page_flip while waiting - * for gpu rendering to complete: - */ - struct drm_framebuffer *fb; - - /* the fb that we currently hold a scanout ref to: */ - struct drm_framebuffer *scanout_fb; - - /* for unref'ing framebuffers after scanout completes: */ - struct drm_flip_work unref_fb_work; - /* for unref'ing cursor bo's after scanout completes: */ struct drm_flip_work unref_cursor_work; @@ -110,47 +96,6 @@ static void crtc_flush(struct drm_crtc *crtc) mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush); } -static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) -{ - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct drm_framebuffer *old_fb = mdp4_crtc->fb; - - /* grab reference to incoming scanout fb: */ - drm_framebuffer_reference(new_fb); - mdp4_crtc->base.primary->fb = new_fb; - mdp4_crtc->fb = new_fb; - - if (old_fb) - drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb); -} - -/* unlike update_fb(), take a ref to the new scanout fb *before* updating - * plane, then call this. Needed to ensure we don't unref the buffer that - * is actually still being scanned out. - * - * Note that this whole thing goes away with atomic.. since we can defer - * calling into driver until rendering is done. - */ -static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) -{ - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - - /* flush updates, to make sure hw is updated to new scanout fb, - * so that we can safely queue unref to current fb (ie. next - * vblank we know hw is done w/ previous scanout_fb). - */ - crtc_flush(crtc); - - if (mdp4_crtc->scanout_fb) - drm_flip_work_queue(&mdp4_crtc->unref_fb_work, - mdp4_crtc->scanout_fb); - - mdp4_crtc->scanout_fb = fb; - - /* enable vblank to complete flip: */ - request_pending(crtc, PENDING_FLIP); -} - /* if file!=NULL, this is preclose potential cancel-flip path */ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) { @@ -168,38 +113,13 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) */ if (!file || (event->base.file_priv == file)) { mdp4_crtc->event = NULL; + DBG("%s: send event: %p", mdp4_crtc->name, event); drm_send_vblank_event(dev, mdp4_crtc->id, event); } } spin_unlock_irqrestore(&dev->event_lock, flags); } -static void pageflip_cb(struct msm_fence_cb *cb) -{ - struct mdp4_crtc *mdp4_crtc = - container_of(cb, struct mdp4_crtc, pageflip_cb); - struct drm_crtc *crtc = &mdp4_crtc->base; - struct drm_framebuffer *fb = crtc->primary->fb; - - if (!fb) - return; - - drm_framebuffer_reference(fb); - mdp4_plane_set_scanout(crtc->primary, fb); - update_scanout(crtc, fb); -} - -static void unref_fb_worker(struct drm_flip_work *work, void *val) -{ - struct mdp4_crtc *mdp4_crtc = - container_of(work, struct mdp4_crtc, unref_fb_work); - struct drm_device *dev = mdp4_crtc->base.dev; - - mutex_lock(&dev->mode_config.mutex); - drm_framebuffer_unreference(val); - mutex_unlock(&dev->mode_config.mutex); -} - static void unref_cursor_worker(struct drm_flip_work *work, void *val) { struct mdp4_crtc *mdp4_crtc = @@ -215,7 +135,6 @@ static void mdp4_crtc_destroy(struct drm_crtc *crtc) struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); drm_crtc_cleanup(crtc); - drm_flip_work_cleanup(&mdp4_crtc->unref_fb_work); drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work); kfree(mdp4_crtc); @@ -323,18 +242,18 @@ static void blend_setup(struct drm_crtc *crtc) mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); } -static int mdp4_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) +static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); enum mdp4_dma dma = mdp4_crtc->dma; - int ret, ovlp = mdp4_crtc->ovlp; + int ovlp = mdp4_crtc->ovlp; + struct drm_display_mode *mode; + + if (WARN_ON(!crtc->state)) + return; - mode = adjusted_mode; + mode = &crtc->state->adjusted_mode; DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", mdp4_crtc->name, mode->base.id, mode->name, @@ -345,20 +264,6 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, mode->vsync_end, mode->vtotal, mode->type, mode->flags); - /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->primary->fb); - - ret = mdp4_plane_mode_set(crtc->primary, crtc, crtc->primary->fb, - 0, 0, mode->hdisplay, mode->vdisplay, - x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16); - if (ret) { - drm_framebuffer_unreference(crtc->primary->fb); - dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", - mdp4_crtc->name, ret); - return ret; - } - mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); @@ -383,11 +288,6 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); } - - update_fb(crtc, crtc->primary->fb); - update_scanout(crtc, crtc->primary->fb); - - return 0; } static void mdp4_crtc_prepare(struct drm_crtc *crtc) @@ -409,59 +309,51 @@ static void mdp4_crtc_commit(struct drm_crtc *crtc) drm_crtc_vblank_put(crtc); } -static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) +static void mdp4_crtc_load_lut(struct drm_crtc *crtc) +{ +} + +static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) { - struct drm_plane *plane = crtc->primary; - struct drm_display_mode *mode = &crtc->mode; - int ret; + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct drm_device *dev = crtc->dev; - /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->primary->fb); + DBG("%s: check", mdp4_crtc->name); - ret = mdp4_plane_mode_set(plane, crtc, crtc->primary->fb, - 0, 0, mode->hdisplay, mode->vdisplay, - x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16); - if (ret) { - drm_framebuffer_unreference(crtc->primary->fb); - return ret; + if (mdp4_crtc->event) { + dev_err(dev->dev, "already pending flip!\n"); + return -EBUSY; } - update_fb(crtc, crtc->primary->fb); - update_scanout(crtc, crtc->primary->fb); + // TODO anything else to check? return 0; } -static void mdp4_crtc_load_lut(struct drm_crtc *crtc) +static void mdp4_crtc_atomic_begin(struct drm_crtc *crtc) { + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + DBG("%s: begin", mdp4_crtc->name); } -static int mdp4_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *new_fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) +static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_gem_object *obj; unsigned long flags; - if (mdp4_crtc->event) { - dev_err(dev->dev, "already pending flip!\n"); - return -EBUSY; - } + DBG("%s: flush", mdp4_crtc->name); - obj = msm_framebuffer_bo(new_fb, 0); + WARN_ON(mdp4_crtc->event); spin_lock_irqsave(&dev->event_lock, flags); - mdp4_crtc->event = event; + mdp4_crtc->event = crtc->state->event; spin_unlock_irqrestore(&dev->event_lock, flags); - update_fb(crtc, new_fb); - - return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); + blend_setup(crtc); + crtc_flush(crtc); + request_pending(crtc, PENDING_FLIP); } static int mdp4_crtc_set_property(struct drm_crtc *crtc, @@ -599,22 +491,29 @@ static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) } static const struct drm_crtc_funcs mdp4_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = mdp4_crtc_destroy, - .page_flip = mdp4_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, .set_property = mdp4_crtc_set_property, .cursor_set = mdp4_crtc_cursor_set, .cursor_move = mdp4_crtc_cursor_move, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = { .dpms = mdp4_crtc_dpms, .mode_fixup = mdp4_crtc_mode_fixup, - .mode_set = mdp4_crtc_mode_set, + .mode_set_nofb = mdp4_crtc_mode_set_nofb, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_base = drm_helper_crtc_mode_set_base, .prepare = mdp4_crtc_prepare, .commit = mdp4_crtc_commit, - .mode_set_base = mdp4_crtc_mode_set_base, .load_lut = mdp4_crtc_load_lut, + .atomic_check = mdp4_crtc_atomic_check, + .atomic_begin = mdp4_crtc_atomic_begin, + .atomic_flush = mdp4_crtc_atomic_flush, }; static void mdp4_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) @@ -630,7 +529,6 @@ static void mdp4_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) if (pending & PENDING_FLIP) { complete_flip(crtc, NULL); - drm_flip_work_commit(&mdp4_crtc->unref_fb_work, priv->wq); } if (pending & PENDING_CURSOR) { @@ -655,7 +553,8 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc) void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file) { - DBG("cancel: %p", file); + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + DBG("%s: cancel: %p", mdp4_crtc->name, file); complete_flip(crtc, file); } @@ -709,29 +608,6 @@ void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer) mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel); } -static void set_attach(struct drm_crtc *crtc, enum mdp4_pipe pipe_id, - struct drm_plane *plane) -{ - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - - blend_setup(crtc); - if (mdp4_crtc->enabled && (plane != crtc->primary)) - crtc_flush(crtc); -} - -void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) -{ - set_attach(crtc, mdp4_plane_pipe(plane), plane); -} - -void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) -{ - /* don't actually detatch our primary plane: */ - if (crtc->primary == plane) - return; - set_attach(crtc, mdp4_plane_pipe(plane), NULL); -} - static const char *dma_names[] = { "DMA_P", "DMA_S", "DMA_E", }; @@ -766,13 +642,9 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, spin_lock_init(&mdp4_crtc->cursor.lock); - drm_flip_work_init(&mdp4_crtc->unref_fb_work, - "unref fb", unref_fb_worker); drm_flip_work_init(&mdp4_crtc->unref_cursor_work, "unref cursor", unref_cursor_worker); - INIT_FENCE_CB(&mdp4_crtc->pageflip_cb, pageflip_cb); - drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs); drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); plane->crtc = crtc; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 9ff6e7ccfe90..770645296f11 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -194,14 +194,6 @@ uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats, void mdp4_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); -void mdp4_plane_set_scanout(struct drm_plane *plane, - struct drm_framebuffer *fb); -int mdp4_plane_mode_set(struct drm_plane *plane, - struct drm_crtc *crtc, struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane); struct drm_plane *mdp4_plane_init(struct drm_device *dev, enum mdp4_pipe pipe_id, bool private_plane); @@ -210,8 +202,6 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer); -void mdp4_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); -void mdp4_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, struct drm_plane *plane, int id, int ovlp_id, enum mdp4_dma dma_id); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c index 310034688c15..4ddc28e1275b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c @@ -98,6 +98,9 @@ static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { .detect = mdp4_lvds_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = mdp4_lvds_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = { diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 66f33dba1ebb..76d0a40c7138 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -31,47 +31,26 @@ struct mdp4_plane { }; #define to_mdp4_plane(x) container_of(x, struct mdp4_plane, base) -static struct mdp4_kms *get_kms(struct drm_plane *plane) -{ - struct msm_drm_private *priv = plane->dev->dev_private; - return to_mdp4_kms(to_mdp_kms(priv->kms)); -} - -static int mdp4_plane_update(struct drm_plane *plane, +static void mdp4_plane_set_scanout(struct drm_plane *plane, + struct drm_framebuffer *fb); +static int mdp4_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) -{ - struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); - - mdp4_plane->enabled = true; - - if (plane->fb) - drm_framebuffer_unreference(plane->fb); - - drm_framebuffer_reference(fb); - - return mdp4_plane_mode_set(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h); -} + uint32_t src_w, uint32_t src_h); -static int mdp4_plane_disable(struct drm_plane *plane) +static struct mdp4_kms *get_kms(struct drm_plane *plane) { - struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); - DBG("%s: disable", mdp4_plane->name); - if (plane->crtc) - mdp4_crtc_detach(plane->crtc, plane); - return 0; + struct msm_drm_private *priv = plane->dev->dev_private; + return to_mdp4_kms(to_mdp_kms(priv->kms)); } static void mdp4_plane_destroy(struct drm_plane *plane) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); - mdp4_plane_disable(plane); + drm_plane_helper_disable(plane); drm_plane_cleanup(plane); kfree(mdp4_plane); @@ -92,19 +71,74 @@ int mdp4_plane_set_property(struct drm_plane *plane, } static const struct drm_plane_funcs mdp4_plane_funcs = { - .update_plane = mdp4_plane_update, - .disable_plane = mdp4_plane_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = mdp4_plane_destroy, .set_property = mdp4_plane_set_property, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; -void mdp4_plane_set_scanout(struct drm_plane *plane, +static int mdp4_plane_prepare_fb(struct drm_plane *plane, + struct drm_framebuffer *fb) +{ + struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); + struct mdp4_kms *mdp4_kms = get_kms(plane); + + DBG("%s: prepare: FB[%u]", mdp4_plane->name, fb->base.id); + return msm_framebuffer_prepare(fb, mdp4_kms->id); +} + +static void mdp4_plane_cleanup_fb(struct drm_plane *plane, + struct drm_framebuffer *fb) +{ + struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); + struct mdp4_kms *mdp4_kms = get_kms(plane); + + DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); + msm_framebuffer_cleanup(fb, mdp4_kms->id); +} + + +static int mdp4_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + return 0; +} + +static void mdp4_plane_atomic_update(struct drm_plane *plane) +{ + struct drm_plane_state *state = plane->state; + int ret; + + ret = mdp4_plane_mode_set(plane, + state->crtc, state->fb, + state->crtc_x, state->crtc_y, + state->crtc_w, state->crtc_h, + state->src_x, state->src_y, + state->src_w, state->src_h); + /* atomic_check should have ensured that this doesn't fail */ + WARN_ON(ret < 0); +} + +static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = { + .prepare_fb = mdp4_plane_prepare_fb, + .cleanup_fb = mdp4_plane_cleanup_fb, + .atomic_check = mdp4_plane_atomic_check, + .atomic_update = mdp4_plane_atomic_update, +}; + +static void mdp4_plane_set_scanout(struct drm_plane *plane, struct drm_framebuffer *fb) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); enum mdp4_pipe pipe = mdp4_plane->pipe; - uint32_t iova; + uint32_t iova = msm_framebuffer_iova(fb, mdp4_kms->id, 0); + + DBG("%s: set_scanout: %08x (%u)", mdp4_plane->name, + iova, fb->pitches[0]); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | @@ -114,7 +148,6 @@ void mdp4_plane_set_scanout(struct drm_plane *plane, MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); - msm_gem_get_iova(msm_framebuffer_bo(fb, 0), mdp4_kms->id, &iova); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova); plane->fb = fb; @@ -122,7 +155,7 @@ void mdp4_plane_set_scanout(struct drm_plane *plane, #define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 -int mdp4_plane_mode_set(struct drm_plane *plane, +static int mdp4_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -137,6 +170,11 @@ int mdp4_plane_mode_set(struct drm_plane *plane, uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT; uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT; + if (!(crtc && fb)) { + DBG("%s: disabled!", mdp4_plane->name); + return 0; + } + /* src values are in Q16 fixed point, convert to integer: */ src_x = src_x >> 16; src_y = src_y >> 16; @@ -197,9 +235,6 @@ int mdp4_plane_mode_set(struct drm_plane *plane, mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step); mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step); - /* TODO detach from old crtc (if we had more than one) */ - mdp4_crtc_attach(crtc, plane); - return 0; } @@ -239,9 +274,12 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, ARRAY_SIZE(mdp4_plane->formats)); type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, - mdp4_plane->formats, mdp4_plane->nformats, - type); + ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, + mdp4_plane->formats, mdp4_plane->nformats, type); + if (ret) + goto fail; + + drm_plane_helper_add(plane, &mdp4_plane_helper_funcs); mdp4_plane_install_properties(plane, &plane->base); -- GitLab From 257d06f7043a432774a315223053730f8b170b0e Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 12 Nov 2014 15:25:50 -0500 Subject: [PATCH 4930/9457] drm/msm: small mmap offset cleanups Use pre-computed iova when unmapping, to reduce the places we assume iova and mmap offset are (at the moment) the same. And get rid of an extra drm_gem_free_mmap_offset() call (since it is already called from drm_gem_object_release()) Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index aaa7898b0b6d..4a6f0e49d5b5 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -519,13 +519,11 @@ void msm_gem_free_object(struct drm_gem_object *obj) for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) { struct msm_mmu *mmu = priv->mmus[id]; if (mmu && msm_obj->domain[id].iova) { - uint32_t offset = (uint32_t)mmap_offset(obj); + uint32_t offset = msm_obj->domain[id].iova; mmu->funcs->unmap(mmu, offset, msm_obj->sgt, obj->size); } } - drm_gem_free_mmap_offset(obj); - if (obj->import_attach) { if (msm_obj->vaddr) dma_buf_vunmap(obj->import_attach->dmabuf, msm_obj->vaddr); -- GitLab From 91b74e9761d785f41156383ad5ec7c437dfb2960 Mon Sep 17 00:00:00 2001 From: Aravind Ganesan Date: Mon, 8 Sep 2014 10:57:28 -0600 Subject: [PATCH 4931/9457] drm/msm: Handle register offset differences between a3xx and a4xx Register offsets have changed between a3xx and a4xx GPUs. To be able access these registers in common code, we create a lookup table, and set of read-write APIs to access the register through the lookup table. Signed-off-by: Aravind Ganesan [robclark: remove REG_ADRENO_UNDEFINED, just use zero, and minor tweaks for latest generated headers] Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 91 +++++++++++++++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 17 ++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 116 ++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 218c5b060398..b66c53bdc039 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -2,6 +2,8 @@ * Copyright (C) 2013 Red Hat * Author: Rob Clark * + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. @@ -406,6 +408,94 @@ static void a3xx_dump(struct msm_gpu *gpu) gpu_read(gpu, REG_A3XX_RBBM_STATUS)); adreno_dump(gpu); } +/* Register offset defines for A3XX */ +static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { + REG_ADRENO_DEFINE(REG_ADRENO_CP_DEBUG, REG_AXXX_CP_DEBUG), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_WADDR, REG_AXXX_CP_ME_RAM_WADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_DATA, REG_AXXX_CP_ME_RAM_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PFP_UCODE_DATA, + REG_A3XX_CP_PFP_UCODE_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PFP_UCODE_ADDR, + REG_A3XX_CP_PFP_UCODE_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_WFI_PEND_CTR, REG_A3XX_CP_WFI_PEND_CTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PROTECT_CTRL, REG_A3XX_CP_PROTECT_CTRL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_CNTL, REG_AXXX_CP_ME_CNTL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_AXXX_CP_RB_CNTL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB1_BASE, REG_AXXX_CP_IB1_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB1_BUFSZ, REG_AXXX_CP_IB1_BUFSZ), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB2_BASE, REG_AXXX_CP_IB2_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB2_BUFSZ, REG_AXXX_CP_IB2_BUFSZ), + REG_ADRENO_DEFINE(REG_ADRENO_CP_TIMESTAMP, REG_AXXX_CP_SCRATCH_REG0), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_RADDR, REG_AXXX_CP_ME_RAM_RADDR), + REG_ADRENO_DEFINE(REG_ADRENO_SCRATCH_ADDR, REG_AXXX_SCRATCH_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_SCRATCH_UMSK, REG_AXXX_SCRATCH_UMSK), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ROQ_ADDR, REG_A3XX_CP_ROQ_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ROQ_DATA, REG_A3XX_CP_ROQ_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_ADDR, REG_A3XX_CP_MERCIU_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_DATA, REG_A3XX_CP_MERCIU_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_DATA2, REG_A3XX_CP_MERCIU_DATA2), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MEQ_ADDR, REG_A3XX_CP_MEQ_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MEQ_DATA, REG_A3XX_CP_MEQ_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_HW_FAULT, REG_A3XX_CP_HW_FAULT), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PROTECT_STATUS, + REG_A3XX_CP_PROTECT_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_STATUS, REG_A3XX_RBBM_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_CTL, + REG_A3XX_RBBM_PERFCTR_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_CMD0, + REG_A3XX_RBBM_PERFCTR_LOAD_CMD0), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_CMD1, + REG_A3XX_RBBM_PERFCTR_LOAD_CMD1), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_PWR_1_LO, + REG_A3XX_RBBM_PERFCTR_PWR_1_LO), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_0_MASK, REG_A3XX_RBBM_INT_0_MASK), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_0_STATUS, + REG_A3XX_RBBM_INT_0_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_ERROR_STATUS, + REG_A3XX_RBBM_AHB_ERROR_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_CMD, REG_A3XX_RBBM_AHB_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_CLEAR_CMD, + REG_A3XX_RBBM_INT_CLEAR_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_CLOCK_CTL, REG_A3XX_RBBM_CLOCK_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_VPC_DEBUG_RAM_SEL, + REG_A3XX_VPC_VPC_DEBUG_RAM_SEL), + REG_ADRENO_DEFINE(REG_ADRENO_VPC_DEBUG_RAM_READ, + REG_A3XX_VPC_VPC_DEBUG_RAM_READ), + REG_ADRENO_DEFINE(REG_ADRENO_VSC_SIZE_ADDRESS, + REG_A3XX_VSC_SIZE_ADDRESS), + REG_ADRENO_DEFINE(REG_ADRENO_VFD_CONTROL_0, REG_A3XX_VFD_CONTROL_0), + REG_ADRENO_DEFINE(REG_ADRENO_VFD_INDEX_MAX, REG_A3XX_VFD_INDEX_MAX), + REG_ADRENO_DEFINE(REG_ADRENO_SP_VS_PVT_MEM_ADDR_REG, + REG_A3XX_SP_VS_PVT_MEM_ADDR_REG), + REG_ADRENO_DEFINE(REG_ADRENO_SP_FS_PVT_MEM_ADDR_REG, + REG_A3XX_SP_FS_PVT_MEM_ADDR_REG), + REG_ADRENO_DEFINE(REG_ADRENO_SP_VS_OBJ_START_REG, + REG_A3XX_SP_VS_OBJ_START_REG), + REG_ADRENO_DEFINE(REG_ADRENO_SP_FS_OBJ_START_REG, + REG_A3XX_SP_FS_OBJ_START_REG), + REG_ADRENO_DEFINE(REG_ADRENO_PA_SC_AA_CONFIG, REG_A3XX_PA_SC_AA_CONFIG), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PM_OVERRIDE2, + REG_A3XX_RBBM_PM_OVERRIDE2), + REG_ADRENO_DEFINE(REG_ADRENO_SCRATCH_REG2, REG_AXXX_CP_SCRATCH_REG2), + REG_ADRENO_DEFINE(REG_ADRENO_SQ_GPR_MANAGEMENT, + REG_A3XX_SQ_GPR_MANAGEMENT), + REG_ADRENO_DEFINE(REG_ADRENO_SQ_INST_STORE_MANAGMENT, + REG_A3XX_SQ_INST_STORE_MANAGMENT), + REG_ADRENO_DEFINE(REG_ADRENO_TP0_CHICKEN, REG_A3XX_TP0_CHICKEN), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_RBBM_CTL, REG_A3XX_RBBM_RBBM_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_SW_RESET_CMD, + REG_A3XX_RBBM_SW_RESET_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_UCHE_INVALIDATE0, + REG_A3XX_UCHE_CACHE_INVALIDATE0_REG), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_LO, + REG_A3XX_RBBM_PERFCTR_LOAD_VALUE_LO), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_HI, + REG_A3XX_RBBM_PERFCTR_LOAD_VALUE_HI), +}; static const struct adreno_gpu_funcs funcs = { .base = { @@ -463,6 +553,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs); adreno_gpu->registers = a3xx_registers; + adreno_gpu->reg_offsets = a3xx_register_offsets; ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); if (ret) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index dc807b23f77a..28e58477ecf4 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -2,6 +2,8 @@ * Copyright (C) 2013 Red Hat * Author: Rob Clark * + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. @@ -63,19 +65,21 @@ int adreno_hw_init(struct msm_gpu *gpu) } /* Setup REG_CP_RB_CNTL: */ - gpu_write(gpu, REG_AXXX_CP_RB_CNTL, + adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, /* size is log2(quad-words): */ AXXX_CP_RB_CNTL_BUFSZ(ilog2(gpu->rb->size / 8)) | AXXX_CP_RB_CNTL_BLKSZ(ilog2(RB_BLKSIZE / 8))); /* Setup ringbuffer address: */ - gpu_write(gpu, REG_AXXX_CP_RB_BASE, gpu->rb_iova); - gpu_write(gpu, REG_AXXX_CP_RB_RPTR_ADDR, rbmemptr(adreno_gpu, rptr)); + adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_BASE, gpu->rb_iova); + adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, + rbmemptr(adreno_gpu, rptr)); /* Setup scratch/timestamp: */ - gpu_write(gpu, REG_AXXX_SCRATCH_ADDR, rbmemptr(adreno_gpu, fence)); + adreno_gpu_write(adreno_gpu, REG_ADRENO_SCRATCH_ADDR, + rbmemptr(adreno_gpu, fence)); - gpu_write(gpu, REG_AXXX_SCRATCH_UMSK, 0x1); + adreno_gpu_write(adreno_gpu, REG_ADRENO_SCRATCH_UMSK, 0x1); return 0; } @@ -188,12 +192,13 @@ int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, void adreno_flush(struct msm_gpu *gpu) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); uint32_t wptr = get_wptr(gpu->rb); /* ensure writes to ringbuffer have hit system memory: */ mb(); - gpu_write(gpu, REG_AXXX_CP_RB_WPTR, wptr); + adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_WPTR, wptr); } void adreno_idle(struct msm_gpu *gpu) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 52f051579753..b9c05e32af52 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -2,6 +2,8 @@ * Copyright (C) 2013 Red Hat * Author: Rob Clark * + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. @@ -25,6 +27,81 @@ #include "adreno_common.xml.h" #include "adreno_pm4.xml.h" +#define REG_ADRENO_DEFINE(_offset, _reg) [_offset] = (_reg) + 1 +/** + * adreno_regs: List of registers that are used in across all + * 3D devices. Each device type has different offset value for the same + * register, so an array of register offsets are declared for every device + * and are indexed by the enumeration values defined in this enum + */ +enum adreno_regs { + REG_ADRENO_CP_DEBUG, + REG_ADRENO_CP_ME_RAM_WADDR, + REG_ADRENO_CP_ME_RAM_DATA, + REG_ADRENO_CP_PFP_UCODE_DATA, + REG_ADRENO_CP_PFP_UCODE_ADDR, + REG_ADRENO_CP_WFI_PEND_CTR, + REG_ADRENO_CP_RB_BASE, + REG_ADRENO_CP_RB_RPTR_ADDR, + REG_ADRENO_CP_RB_RPTR, + REG_ADRENO_CP_RB_WPTR, + REG_ADRENO_CP_PROTECT_CTRL, + REG_ADRENO_CP_ME_CNTL, + REG_ADRENO_CP_RB_CNTL, + REG_ADRENO_CP_IB1_BASE, + REG_ADRENO_CP_IB1_BUFSZ, + REG_ADRENO_CP_IB2_BASE, + REG_ADRENO_CP_IB2_BUFSZ, + REG_ADRENO_CP_TIMESTAMP, + REG_ADRENO_CP_ME_RAM_RADDR, + REG_ADRENO_CP_ROQ_ADDR, + REG_ADRENO_CP_ROQ_DATA, + REG_ADRENO_CP_MERCIU_ADDR, + REG_ADRENO_CP_MERCIU_DATA, + REG_ADRENO_CP_MERCIU_DATA2, + REG_ADRENO_CP_MEQ_ADDR, + REG_ADRENO_CP_MEQ_DATA, + REG_ADRENO_CP_HW_FAULT, + REG_ADRENO_CP_PROTECT_STATUS, + REG_ADRENO_SCRATCH_ADDR, + REG_ADRENO_SCRATCH_UMSK, + REG_ADRENO_SCRATCH_REG2, + REG_ADRENO_RBBM_STATUS, + REG_ADRENO_RBBM_PERFCTR_CTL, + REG_ADRENO_RBBM_PERFCTR_LOAD_CMD0, + REG_ADRENO_RBBM_PERFCTR_LOAD_CMD1, + REG_ADRENO_RBBM_PERFCTR_LOAD_CMD2, + REG_ADRENO_RBBM_PERFCTR_PWR_1_LO, + REG_ADRENO_RBBM_INT_0_MASK, + REG_ADRENO_RBBM_INT_0_STATUS, + REG_ADRENO_RBBM_AHB_ERROR_STATUS, + REG_ADRENO_RBBM_PM_OVERRIDE2, + REG_ADRENO_RBBM_AHB_CMD, + REG_ADRENO_RBBM_INT_CLEAR_CMD, + REG_ADRENO_RBBM_SW_RESET_CMD, + REG_ADRENO_RBBM_CLOCK_CTL, + REG_ADRENO_RBBM_AHB_ME_SPLIT_STATUS, + REG_ADRENO_RBBM_AHB_PFP_SPLIT_STATUS, + REG_ADRENO_VPC_DEBUG_RAM_SEL, + REG_ADRENO_VPC_DEBUG_RAM_READ, + REG_ADRENO_VSC_SIZE_ADDRESS, + REG_ADRENO_VFD_CONTROL_0, + REG_ADRENO_VFD_INDEX_MAX, + REG_ADRENO_SP_VS_PVT_MEM_ADDR_REG, + REG_ADRENO_SP_FS_PVT_MEM_ADDR_REG, + REG_ADRENO_SP_VS_OBJ_START_REG, + REG_ADRENO_SP_FS_OBJ_START_REG, + REG_ADRENO_PA_SC_AA_CONFIG, + REG_ADRENO_SQ_GPR_MANAGEMENT, + REG_ADRENO_SQ_INST_STORE_MANAGMENT, + REG_ADRENO_TP0_CHICKEN, + REG_ADRENO_RBBM_RBBM_CTL, + REG_ADRENO_UCHE_INVALIDATE0, + REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_LO, + REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_HI, + REG_ADRENO_REGISTER_MAX, +}; + struct adreno_rev { uint8_t core; uint8_t major; @@ -76,6 +153,13 @@ struct adreno_gpu { struct adreno_rbmemptrs *memptrs; struct drm_gem_object *memptrs_bo; uint32_t memptrs_iova; + + /* + * Register offsets are different between some GPUs. + * GPU specific offsets will be exported by GPU specific + * code (a3xx_gpu.c) and stored in this common location. + */ + const unsigned int *reg_offsets; }; #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) @@ -171,5 +255,37 @@ OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8)); } +/* + * adreno_checkreg_off() - Checks the validity of a register enum + * @gpu: Pointer to struct adreno_gpu + * @offset_name: The register enum that is checked + */ +static inline bool adreno_reg_check(struct adreno_gpu *gpu, + enum adreno_regs offset_name) +{ + if (offset_name >= REG_ADRENO_REGISTER_MAX || + !gpu->reg_offsets[offset_name]) { + BUG(); + } + return true; +} + +static inline u32 adreno_gpu_read(struct adreno_gpu *gpu, + enum adreno_regs offset_name) +{ + u32 reg = gpu->reg_offsets[offset_name]; + u32 val = 0; + if(adreno_reg_check(gpu,offset_name)) + val = gpu_read(&gpu->base, reg - 1); + return val; +} + +static inline void adreno_gpu_write(struct adreno_gpu *gpu, + enum adreno_regs offset_name, u32 data) +{ + u32 reg = gpu->reg_offsets[offset_name]; + if(adreno_reg_check(gpu, offset_name)) + gpu_write(&gpu->base, reg - 1, data); +} #endif /* __ADRENO_GPU_H__ */ -- GitLab From 23bd62fd419755b439152915f4df8ff26346f2b7 Mon Sep 17 00:00:00 2001 From: Aravind Ganesan Date: Mon, 8 Sep 2014 13:40:16 -0600 Subject: [PATCH 4932/9457] drm/msm: a4xx support for msm-drm Added a4xx GPU support. Signed-off-by: Aravind Ganesan Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 604 +++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 34 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 13 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 + 6 files changed, 663 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/adreno/a4xx_gpu.c create mode 100644 drivers/gpu/drm/msm/adreno/a4xx_gpu.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 415a145a9829..0d96132df059 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -7,6 +7,7 @@ msm-y := \ adreno/adreno_device.o \ adreno/adreno_gpu.o \ adreno/a3xx_gpu.o \ + adreno/a4xx_gpu.o \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c new file mode 100644 index 000000000000..91221836c5ad --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -0,0 +1,604 @@ +/* Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include "a4xx_gpu.h" +#ifdef CONFIG_MSM_OCMEM +# include +#endif + +#define A4XX_INT0_MASK \ + (A4XX_INT0_RBBM_AHB_ERROR | \ + A4XX_INT0_RBBM_ATB_BUS_OVERFLOW | \ + A4XX_INT0_CP_T0_PACKET_IN_IB | \ + A4XX_INT0_CP_OPCODE_ERROR | \ + A4XX_INT0_CP_RESERVED_BIT_ERROR | \ + A4XX_INT0_CP_HW_FAULT | \ + A4XX_INT0_CP_IB1_INT | \ + A4XX_INT0_CP_IB2_INT | \ + A4XX_INT0_CP_RB_INT | \ + A4XX_INT0_CP_REG_PROTECT_FAULT | \ + A4XX_INT0_CP_AHB_ERROR_HALT | \ + A4XX_INT0_UCHE_OOB_ACCESS) + +extern bool hang_debug; +static void a4xx_dump(struct msm_gpu *gpu); + +/* + * a4xx_enable_hwcg() - Program the clock control registers + * @device: The adreno device pointer + */ +static void a4xx_enable_hwcg(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + unsigned int i; + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TP(i), 0x02222202); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_TP(i), 0x00002222); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TP(i), 0x0E739CE7); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TP(i), 0x00111111); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_SP(i), 0x22222222); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_SP(i), 0x00222222); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_SP(i), 0x00000104); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_SP(i), 0x00000081); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_UCHE, 0x22222222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_UCHE, 0x02222222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL3_UCHE, 0x00000000); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL4_UCHE, 0x00000000); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_UCHE, 0x00004444); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_UCHE, 0x00001112); + for (i = 0; i < 4; i++) + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_RB(i), 0x22222222); + + /* Disable L1 clocking in A420 due to CCU issues with it */ + for (i = 0; i < 4; i++) { + if (adreno_is_a420(adreno_gpu)) { + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i), + 0x00002020); + } else { + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i), + 0x00022020); + } + } + + for (i = 0; i < 4; i++) { + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i), + 0x00000922); + } + + for (i = 0; i < 4; i++) { + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i), + 0x00000000); + } + + for (i = 0; i < 4; i++) { + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i), + 0x00000001); + } + + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_MODE_GPC, 0x02222222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_GPC, 0x04100104); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_GPC, 0x00022222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_COM_DCOM, 0x00000022); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_COM_DCOM, 0x0000010F); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_COM_DCOM, 0x00000022); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TSE_RAS_RBBM, 0x00222222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00004104); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000222); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_HLSQ , 0x00000000); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, 0x00020000); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA); + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2, 0); +} + +static void a4xx_me_init(struct msm_gpu *gpu) +{ + struct msm_ringbuffer *ring = gpu->rb; + + OUT_PKT3(ring, CP_ME_INIT, 17); + OUT_RING(ring, 0x000003f7); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000080); + OUT_RING(ring, 0x00000100); + OUT_RING(ring, 0x00000180); + OUT_RING(ring, 0x00006600); + OUT_RING(ring, 0x00000150); + OUT_RING(ring, 0x0000014e); + OUT_RING(ring, 0x00000154); + OUT_RING(ring, 0x00000001); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, 0x00000000); + + gpu->funcs->flush(gpu); + gpu->funcs->idle(gpu); +} + +static int a4xx_hw_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu); + uint32_t *ptr, len; + int i, ret; + + if (adreno_is_a4xx(adreno_gpu)) { + gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F); + gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4); + gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001); + gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818); + gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018); + gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818); + gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018); + gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003); + } else { + BUG(); + } + + /* Make all blocks contribute to the GPU BUSY perf counter */ + gpu_write(gpu, REG_A4XX_RBBM_GPU_BUSY_MASKED, 0xffffffff); + + /* Tune the hystersis counters for SP and CP idle detection */ + gpu_write(gpu, REG_A4XX_RBBM_SP_HYST_CNT, 0x10); + gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10); + + /* Enable the RBBM error reporting bits */ + gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL0, 0x00000001); + + /* Enable AHB error reporting*/ + gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL1, 0xa6ffffff); + + /* Enable power counters*/ + gpu_write(gpu, REG_A4XX_RBBM_RBBM_CTL, 0x00000030); + + /* + * Turn on hang detection - this spews a lot of useful information + * into the RBBM registers on a hang: + */ + gpu_write(gpu, REG_A4XX_RBBM_INTERFACE_HANG_INT_CTL, + (1 << 30) | 0xFFFF); + + gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, + (unsigned int)(a4xx_gpu->ocmem_base >> 14)); + + /* Turn on performance counters: */ + gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01); + + /* Disable L2 bypass to avoid UCHE out of bounds errors */ + gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_LO, 0xffff0000); + gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_HI, 0xffff0000); + + gpu_write(gpu, REG_A4XX_CP_DEBUG, (1 << 25) | + (adreno_is_a420(adreno_gpu) ? (1 << 29) : 0)); + + a4xx_enable_hwcg(gpu); + + /* + * For A420 set RBBM_CLOCK_DELAY_HLSQ.CGC_HLSQ_TP_EARLY_CYC >= 2 + * due to timing issue with HLSQ_TP_CLK_EN + */ + if (adreno_is_a420(adreno_gpu)) { + unsigned int val; + val = gpu_read(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ); + val &= ~A4XX_CGC_HLSQ_EARLY_CYC__MASK; + val |= 2 << A4XX_CGC_HLSQ_EARLY_CYC__SHIFT; + gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, val); + } + + ret = adreno_hw_init(gpu); + if (ret) + return ret; + + /* setup access protection: */ + gpu_write(gpu, REG_A4XX_CP_PROTECT_CTRL, 0x00000007); + + /* RBBM registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(0), 0x62000010); + gpu_write(gpu, REG_A4XX_CP_PROTECT(1), 0x63000020); + gpu_write(gpu, REG_A4XX_CP_PROTECT(2), 0x64000040); + gpu_write(gpu, REG_A4XX_CP_PROTECT(3), 0x65000080); + gpu_write(gpu, REG_A4XX_CP_PROTECT(4), 0x66000100); + gpu_write(gpu, REG_A4XX_CP_PROTECT(5), 0x64000200); + + /* CP registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(6), 0x67000800); + gpu_write(gpu, REG_A4XX_CP_PROTECT(7), 0x64001600); + + + /* RB registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(8), 0x60003300); + + /* HLSQ registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(9), 0x60003800); + + /* VPC registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(10), 0x61003980); + + /* SMMU registers */ + gpu_write(gpu, REG_A4XX_CP_PROTECT(11), 0x6e010000); + + gpu_write(gpu, REG_A4XX_RBBM_INT_0_MASK, A4XX_INT0_MASK); + + ret = adreno_hw_init(gpu); + if (ret) + return ret; + + /* Load PM4: */ + ptr = (uint32_t *)(adreno_gpu->pm4->data); + len = adreno_gpu->pm4->size / 4; + DBG("loading PM4 ucode version: %u", ptr[0]); + gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]); + + /* Load PFP: */ + ptr = (uint32_t *)(adreno_gpu->pfp->data); + len = adreno_gpu->pfp->size / 4; + DBG("loading PFP ucode version: %u", ptr[0]); + + gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_DATA, ptr[i]); + + /* clear ME_HALT to start micro engine */ + gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0); + + a4xx_me_init(gpu); + return 0; +} + +static void a4xx_recover(struct msm_gpu *gpu) +{ + /* dump registers before resetting gpu, if enabled: */ + if (hang_debug) + a4xx_dump(gpu); + + gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 1); + gpu_read(gpu, REG_A4XX_RBBM_SW_RESET_CMD); + gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 0); + adreno_recover(gpu); +} + +static void a4xx_destroy(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu); + + DBG("%s", gpu->name); + + adreno_gpu_cleanup(adreno_gpu); + +#ifdef CONFIG_MSM_OCMEM + if (a4xx_gpu->ocmem_base) + ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl); +#endif + + kfree(a4xx_gpu); +} + +static void a4xx_idle(struct msm_gpu *gpu) +{ + /* wait for ringbuffer to drain: */ + adreno_idle(gpu); + + /* then wait for GPU to finish: */ + if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) & + A4XX_RBBM_STATUS_GPU_BUSY))) + DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); + + /* TODO maybe we need to reset GPU here to recover from hang? */ +} + +static irqreturn_t a4xx_irq(struct msm_gpu *gpu) +{ + uint32_t status; + + status = gpu_read(gpu, REG_A4XX_RBBM_INT_0_STATUS); + DBG("%s: Int status %08x", gpu->name, status); + + gpu_write(gpu, REG_A4XX_RBBM_INT_CLEAR_CMD, status); + + msm_gpu_retire(gpu); + + return IRQ_HANDLED; +} + +static const unsigned int a4xx_registers[] = { + /* RBBM */ + 0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026, + 0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066, + 0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF, + /* CP */ + 0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B, + 0x0578, 0x058F, + /* VSC */ + 0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51, + /* GRAS */ + 0x0C80, 0x0C81, 0x0C88, 0x0C8F, + /* RB */ + 0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2, + /* PC */ + 0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23, + /* VFD */ + 0x0E40, 0x0E4A, + /* VPC */ + 0x0E60, 0x0E61, 0x0E63, 0x0E68, + /* UCHE */ + 0x0E80, 0x0E84, 0x0E88, 0x0E95, + /* VMIDMT */ + 0x1000, 0x1000, 0x1002, 0x1002, 0x1004, 0x1004, 0x1008, 0x100A, + 0x100C, 0x100D, 0x100F, 0x1010, 0x1012, 0x1016, 0x1024, 0x1024, + 0x1027, 0x1027, 0x1100, 0x1100, 0x1102, 0x1102, 0x1104, 0x1104, + 0x1110, 0x1110, 0x1112, 0x1116, 0x1124, 0x1124, 0x1300, 0x1300, + 0x1380, 0x1380, + /* GRAS CTX 0 */ + 0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E, + /* PC CTX 0 */ + 0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7, + /* VFD CTX 0 */ + 0x2200, 0x2204, 0x2208, 0x22A9, + /* GRAS CTX 1 */ + 0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E, + /* PC CTX 1 */ + 0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7, + /* VFD CTX 1 */ + 0x2600, 0x2604, 0x2608, 0x26A9, + /* XPU */ + 0x2C00, 0x2C01, 0x2C10, 0x2C10, 0x2C12, 0x2C16, 0x2C1D, 0x2C20, + 0x2C28, 0x2C28, 0x2C30, 0x2C30, 0x2C32, 0x2C36, 0x2C40, 0x2C40, + 0x2C50, 0x2C50, 0x2C52, 0x2C56, 0x2C80, 0x2C80, 0x2C94, 0x2C95, + /* VBIF */ + 0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x301D, 0x3020, 0x3022, + 0x3024, 0x3026, 0x3028, 0x302A, 0x302C, 0x302D, 0x3030, 0x3031, + 0x3034, 0x3036, 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040, + 0x3049, 0x3049, 0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068, + 0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094, + 0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8, + 0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100, + 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120, + 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x330C, 0x330C, + 0x3310, 0x3310, 0x3400, 0x3401, 0x3410, 0x3410, 0x3412, 0x3416, + 0x341D, 0x3420, 0x3428, 0x3428, 0x3430, 0x3430, 0x3432, 0x3436, + 0x3440, 0x3440, 0x3450, 0x3450, 0x3452, 0x3456, 0x3480, 0x3480, + 0x3494, 0x3495, 0x4000, 0x4000, 0x4002, 0x4002, 0x4004, 0x4004, + 0x4008, 0x400A, 0x400C, 0x400D, 0x400F, 0x4012, 0x4014, 0x4016, + 0x401D, 0x401D, 0x4020, 0x4027, 0x4060, 0x4062, 0x4200, 0x4200, + 0x4300, 0x4300, 0x4400, 0x4400, 0x4500, 0x4500, 0x4800, 0x4802, + 0x480F, 0x480F, 0x4811, 0x4811, 0x4813, 0x4813, 0x4815, 0x4816, + 0x482B, 0x482B, 0x4857, 0x4857, 0x4883, 0x4883, 0x48AF, 0x48AF, + 0x48C5, 0x48C5, 0x48E5, 0x48E5, 0x4905, 0x4905, 0x4925, 0x4925, + 0x4945, 0x4945, 0x4950, 0x4950, 0x495B, 0x495B, 0x4980, 0x498E, + 0x4B00, 0x4B00, 0x4C00, 0x4C00, 0x4D00, 0x4D00, 0x4E00, 0x4E00, + 0x4E80, 0x4E80, 0x4F00, 0x4F00, 0x4F08, 0x4F08, 0x4F10, 0x4F10, + 0x4F18, 0x4F18, 0x4F20, 0x4F20, 0x4F30, 0x4F30, 0x4F60, 0x4F60, + 0x4F80, 0x4F81, 0x4F88, 0x4F89, 0x4FEE, 0x4FEE, 0x4FF3, 0x4FF3, + 0x6000, 0x6001, 0x6008, 0x600F, 0x6014, 0x6016, 0x6018, 0x601B, + 0x61FD, 0x61FD, 0x623C, 0x623C, 0x6380, 0x6380, 0x63A0, 0x63A0, + 0x63C0, 0x63C1, 0x63C8, 0x63C9, 0x63D0, 0x63D4, 0x63D6, 0x63D6, + 0x63EE, 0x63EE, 0x6400, 0x6401, 0x6408, 0x640F, 0x6414, 0x6416, + 0x6418, 0x641B, 0x65FD, 0x65FD, 0x663C, 0x663C, 0x6780, 0x6780, + 0x67A0, 0x67A0, 0x67C0, 0x67C1, 0x67C8, 0x67C9, 0x67D0, 0x67D4, + 0x67D6, 0x67D6, 0x67EE, 0x67EE, 0x6800, 0x6801, 0x6808, 0x680F, + 0x6814, 0x6816, 0x6818, 0x681B, 0x69FD, 0x69FD, 0x6A3C, 0x6A3C, + 0x6B80, 0x6B80, 0x6BA0, 0x6BA0, 0x6BC0, 0x6BC1, 0x6BC8, 0x6BC9, + 0x6BD0, 0x6BD4, 0x6BD6, 0x6BD6, 0x6BEE, 0x6BEE, + ~0 /* sentinel */ +}; + +#ifdef CONFIG_DEBUG_FS +static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m) +{ + gpu->funcs->pm_resume(gpu); + + seq_printf(m, "status: %08x\n", + gpu_read(gpu, REG_A4XX_RBBM_STATUS)); + gpu->funcs->pm_suspend(gpu); + + adreno_show(gpu, m); + +} +#endif + +/* Register offset defines for A4XX, in order of enum adreno_regs */ +static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { + REG_ADRENO_DEFINE(REG_ADRENO_CP_DEBUG, REG_A4XX_CP_DEBUG), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_WADDR, REG_A4XX_CP_ME_RAM_WADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_DATA, REG_A4XX_CP_ME_RAM_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PFP_UCODE_DATA, + REG_A4XX_CP_PFP_UCODE_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PFP_UCODE_ADDR, + REG_A4XX_CP_PFP_UCODE_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_WFI_PEND_CTR, REG_A4XX_CP_WFI_PEND_CTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A4XX_CP_RB_RPTR_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A4XX_CP_RB_RPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A4XX_CP_RB_WPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PROTECT_CTRL, REG_A4XX_CP_PROTECT_CTRL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_CNTL, REG_A4XX_CP_ME_CNTL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A4XX_CP_RB_CNTL), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB1_BASE, REG_A4XX_CP_IB1_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB1_BUFSZ, REG_A4XX_CP_IB1_BUFSZ), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB2_BASE, REG_A4XX_CP_IB2_BASE), + REG_ADRENO_DEFINE(REG_ADRENO_CP_IB2_BUFSZ, REG_A4XX_CP_IB2_BUFSZ), + REG_ADRENO_DEFINE(REG_ADRENO_CP_TIMESTAMP, REG_AXXX_CP_SCRATCH_REG0), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ME_RAM_RADDR, REG_A4XX_CP_ME_RAM_RADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ROQ_ADDR, REG_A4XX_CP_ROQ_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_ROQ_DATA, REG_A4XX_CP_ROQ_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_ADDR, REG_A4XX_CP_MERCIU_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_DATA, REG_A4XX_CP_MERCIU_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MERCIU_DATA2, REG_A4XX_CP_MERCIU_DATA2), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MEQ_ADDR, REG_A4XX_CP_MEQ_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_MEQ_DATA, REG_A4XX_CP_MEQ_DATA), + REG_ADRENO_DEFINE(REG_ADRENO_CP_HW_FAULT, REG_A4XX_CP_HW_FAULT), + REG_ADRENO_DEFINE(REG_ADRENO_CP_PROTECT_STATUS, + REG_A4XX_CP_PROTECT_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_SCRATCH_ADDR, REG_A4XX_CP_SCRATCH_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_SCRATCH_UMSK, REG_A4XX_CP_SCRATCH_UMASK), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_STATUS, REG_A4XX_RBBM_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_CTL, + REG_A4XX_RBBM_PERFCTR_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_CMD0, + REG_A4XX_RBBM_PERFCTR_LOAD_CMD0), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_CMD1, + REG_A4XX_RBBM_PERFCTR_LOAD_CMD1), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_CMD2, + REG_A4XX_RBBM_PERFCTR_LOAD_CMD2), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_PWR_1_LO, + REG_A4XX_RBBM_PERFCTR_PWR_1_LO), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_0_MASK, REG_A4XX_RBBM_INT_0_MASK), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_0_STATUS, + REG_A4XX_RBBM_INT_0_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_ERROR_STATUS, + REG_A4XX_RBBM_AHB_ERROR_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_CMD, REG_A4XX_RBBM_AHB_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_CLOCK_CTL, REG_A4XX_RBBM_CLOCK_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_ME_SPLIT_STATUS, + REG_A4XX_RBBM_AHB_ME_SPLIT_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_AHB_PFP_SPLIT_STATUS, + REG_A4XX_RBBM_AHB_PFP_SPLIT_STATUS), + REG_ADRENO_DEFINE(REG_ADRENO_VPC_DEBUG_RAM_SEL, + REG_A4XX_VPC_DEBUG_RAM_SEL), + REG_ADRENO_DEFINE(REG_ADRENO_VPC_DEBUG_RAM_READ, + REG_A4XX_VPC_DEBUG_RAM_READ), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_INT_CLEAR_CMD, + REG_A4XX_RBBM_INT_CLEAR_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_VSC_SIZE_ADDRESS, + REG_A4XX_VSC_SIZE_ADDRESS), + REG_ADRENO_DEFINE(REG_ADRENO_VFD_CONTROL_0, REG_A4XX_VFD_CONTROL_0), + REG_ADRENO_DEFINE(REG_ADRENO_SP_VS_PVT_MEM_ADDR_REG, + REG_A4XX_SP_VS_PVT_MEM_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_SP_FS_PVT_MEM_ADDR_REG, + REG_A4XX_SP_FS_PVT_MEM_ADDR), + REG_ADRENO_DEFINE(REG_ADRENO_SP_VS_OBJ_START_REG, + REG_A4XX_SP_VS_OBJ_START), + REG_ADRENO_DEFINE(REG_ADRENO_SP_FS_OBJ_START_REG, + REG_A4XX_SP_FS_OBJ_START), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_RBBM_CTL, REG_A4XX_RBBM_RBBM_CTL), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_SW_RESET_CMD, + REG_A4XX_RBBM_SW_RESET_CMD), + REG_ADRENO_DEFINE(REG_ADRENO_UCHE_INVALIDATE0, + REG_A4XX_UCHE_INVALIDATE0), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_LO, + REG_A4XX_RBBM_PERFCTR_LOAD_VALUE_LO), + REG_ADRENO_DEFINE(REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_HI, + REG_A4XX_RBBM_PERFCTR_LOAD_VALUE_HI), +}; + +static void a4xx_dump(struct msm_gpu *gpu) +{ + adreno_dump(gpu); + printk("status: %08x\n", + gpu_read(gpu, REG_A4XX_RBBM_STATUS)); + adreno_dump(gpu); +} + +static const struct adreno_gpu_funcs funcs = { + .base = { + .get_param = adreno_get_param, + .hw_init = a4xx_hw_init, + .pm_suspend = msm_gpu_pm_suspend, + .pm_resume = msm_gpu_pm_resume, + .recover = a4xx_recover, + .last_fence = adreno_last_fence, + .submit = adreno_submit, + .flush = adreno_flush, + .idle = a4xx_idle, + .irq = a4xx_irq, + .destroy = a4xx_destroy, +#ifdef CONFIG_DEBUG_FS + .show = a4xx_show, +#endif + }, +}; + +struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) +{ + struct a4xx_gpu *a4xx_gpu = NULL; + struct adreno_gpu *adreno_gpu; + struct msm_gpu *gpu; + struct msm_drm_private *priv = dev->dev_private; + struct platform_device *pdev = priv->gpu_pdev; + int ret; + + if (!pdev) { + dev_err(dev->dev, "no a4xx device\n"); + ret = -ENXIO; + goto fail; + } + + a4xx_gpu = kzalloc(sizeof(*a4xx_gpu), GFP_KERNEL); + if (!a4xx_gpu) { + ret = -ENOMEM; + goto fail; + } + + adreno_gpu = &a4xx_gpu->base; + gpu = &adreno_gpu->base; + + a4xx_gpu->pdev = pdev; + + gpu->perfcntrs = NULL; + gpu->num_perfcntrs = 0; + + adreno_gpu->registers = a4xx_registers; + adreno_gpu->reg_offsets = a4xx_register_offsets; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); + if (ret) + goto fail; + + /* if needed, allocate gmem: */ + if (adreno_is_a4xx(adreno_gpu)) { +#ifdef CONFIG_MSM_OCMEM + /* TODO this is different/missing upstream: */ + struct ocmem_buf *ocmem_hdl = + ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); + + a4xx_gpu->ocmem_hdl = ocmem_hdl; + a4xx_gpu->ocmem_base = ocmem_hdl->addr; + adreno_gpu->gmem = ocmem_hdl->len; + DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, + a4xx_gpu->ocmem_base); +#endif + } + + if (!gpu->mmu) { + /* TODO we think it is possible to configure the GPU to + * restrict access to VRAM carveout. But the required + * registers are unknown. For now just bail out and + * limp along with just modesetting. If it turns out + * to not be possible to restrict access, then we must + * implement a cmdstream validator. + */ + dev_err(dev->dev, "No memory protection without IOMMU\n"); + ret = -ENXIO; + goto fail; + } + + return gpu; + +fail: + if (a4xx_gpu) + a4xx_destroy(&a4xx_gpu->base.base); + + return ERR_PTR(ret); +} diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h new file mode 100644 index 000000000000..01247204ac92 --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __A4XX_GPU_H__ +#define __A4XX_GPU_H__ + +#include "adreno_gpu.h" + +/* arrg, somehow fb.h is getting pulled in: */ +#undef ROP_COPY +#undef ROP_XOR + +#include "a4xx.xml.h" + +struct a4xx_gpu { + struct adreno_gpu base; + struct platform_device *pdev; + + /* if OCMEM is used for GMEM: */ + uint32_t ocmem_base; + void *ocmem_hdl; +}; +#define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base) + +#endif /* __A4XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 7ab85af3a7db..be83dee83d08 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -2,6 +2,8 @@ * Copyright (C) 2013-2014 Red Hat * Author: Rob Clark * + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. @@ -28,6 +30,7 @@ MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow! module_param_named(hang_debug, hang_debug, bool, 0600); struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); +struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); static const struct adreno_info gpulist[] = { { @@ -54,6 +57,14 @@ static const struct adreno_info gpulist[] = { .pfpfw = "a330_pfp.fw", .gmem = SZ_1M, .init = a3xx_gpu_init, + }, { + .rev = ADRENO_REV(4, 2, 0, ANY_ID), + .revn = 420, + .name = "A420", + .pm4fw = "a420_pm4.fw", + .pfpfw = "a420_pfp.fw", + .gmem = (SZ_1M + SZ_512K), + .init = a4xx_gpu_init, }, }; @@ -61,6 +72,8 @@ MODULE_FIRMWARE("a300_pm4.fw"); MODULE_FIRMWARE("a300_pfp.fw"); MODULE_FIRMWARE("a330_pm4.fw"); MODULE_FIRMWARE("a330_pfp.fw"); +MODULE_FIRMWARE("a420_pm4.fw"); +MODULE_FIRMWARE("a420_pfp.fw"); static inline bool _rev_match(uint8_t entry, uint8_t id) { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 28e58477ecf4..aa873048308b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -155,7 +155,7 @@ int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1); OUT_RING(ring, submit->fence); - if (adreno_is_a3xx(adreno_gpu)) { + if (adreno_is_a3xx(adreno_gpu) || adreno_is_a4xx(adreno_gpu)) { /* Flush HLSQ lazy updates to make sure there is nothing * pending for indirect loads after the timestamp has * passed: diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index b9c05e32af52..a0cc30977e67 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -212,6 +212,16 @@ static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) return adreno_is_a330(gpu) && (gpu->rev.patchid > 0); } +static inline bool adreno_is_a4xx(struct adreno_gpu *gpu) +{ + return (gpu->revn >= 400) && (gpu->revn < 500); +} + +static inline int adreno_is_a420(struct adreno_gpu *gpu) +{ + return gpu->revn == 420; +} + int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); int adreno_hw_init(struct msm_gpu *gpu); uint32_t adreno_last_fence(struct msm_gpu *gpu); -- GitLab From f35423c137b0e64155f52c166db1d13834a551f2 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 14 Nov 2014 19:32:58 +0100 Subject: [PATCH 4933/9457] openvswitch: use PTR_ERR_OR_ZERO Signed-off-by: Fabian Frederick Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- net/openvswitch/flow_netlink.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index c0d066def228..c8fccdded865 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1425,10 +1425,8 @@ static int add_action(struct sw_flow_actions **sfa, int attrtype, struct nlattr *a; a = __add_action(sfa, attrtype, data, len, log); - if (IS_ERR(a)) - return PTR_ERR(a); - return 0; + return PTR_ERR_OR_ZERO(a); } static inline int add_nested_action_start(struct sw_flow_actions **sfa, -- GitLab From 5bc4b46a70eab74d642c726d99433166d3f65e45 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 14 Nov 2014 19:36:42 +0100 Subject: [PATCH 4934/9457] net: dsa: replace count*size kmalloc by kmalloc_array kmalloc_array manages count*sizeof overflow. Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dsa/dsa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 4648f12098ad..c00cca3e1913 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -526,7 +526,8 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, /* First time routing table allocation */ if (!cd->rtable) { - cd->rtable = kmalloc(pd->nr_chips * sizeof(s8), GFP_KERNEL); + cd->rtable = kmalloc_array(pd->nr_chips, sizeof(s8), + GFP_KERNEL); if (!cd->rtable) return -ENOMEM; -- GitLab From 6f2aed6ad7242ead0db1278b4b48fabb81bbc6a7 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Fri, 14 Nov 2014 19:38:23 +0100 Subject: [PATCH 4935/9457] net: dsa: replace count*size kzalloc by kcalloc kcalloc manages count*sizeof overflow. Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dsa/dsa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index c00cca3e1913..322c778487e7 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -607,8 +607,8 @@ static int dsa_of_probe(struct platform_device *pdev) if (pd->nr_chips > DSA_MAX_SWITCHES) pd->nr_chips = DSA_MAX_SWITCHES; - pd->chip = kzalloc(pd->nr_chips * sizeof(struct dsa_chip_data), - GFP_KERNEL); + pd->chip = kcalloc(pd->nr_chips, sizeof(struct dsa_chip_data), + GFP_KERNEL); if (!pd->chip) { ret = -ENOMEM; goto out_free; -- GitLab From eaa237657b97068db0eb49bae86714e9324cff9a Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 15 Nov 2014 22:24:51 +0100 Subject: [PATCH 4936/9457] net: dsa: Centralise code for reading the temperature sensor The method to read the temperature used in the mve6123_61_65 driver can also be used for other chips. Move the code into the shared code base of mv88e6xxx.c. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123_61_65.c | 50 +------------------------------ drivers/net/dsa/mv88e6xxx.c | 48 +++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 1 + 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c index 9a3f9e0b0532..e9c736e1cef3 100644 --- a/drivers/net/dsa/mv88e6123_61_65.c +++ b/drivers/net/dsa/mv88e6123_61_65.c @@ -291,54 +291,6 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p) return 0; } -#ifdef CONFIG_NET_DSA_HWMON - -static int mv88e6123_61_65_get_temp(struct dsa_switch *ds, int *temp) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int ret; - int val; - - *temp = 0; - - mutex_lock(&ps->phy_mutex); - - ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); - if (ret < 0) - goto error; - - /* Enable temperature sensor */ - ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a); - if (ret < 0) - goto error; - - ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); - if (ret < 0) - goto error; - - /* Wait for temperature to stabilize */ - usleep_range(10000, 12000); - - val = mv88e6xxx_phy_read(ds, 0x0, 0x1a); - if (val < 0) { - ret = val; - goto error; - } - - /* Disable temperature sensor */ - ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); - if (ret < 0) - goto error; - - *temp = ((val & 0x1f) - 5) * 5; - -error: - mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); - mutex_unlock(&ps->phy_mutex); - return ret; -} -#endif /* CONFIG_NET_DSA_HWMON */ - static int mv88e6123_61_65_setup(struct dsa_switch *ds) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); @@ -471,7 +423,7 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = { .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats, .get_sset_count = mv88e6123_61_65_get_sset_count, #ifdef CONFIG_NET_DSA_HWMON - .get_temp = mv88e6123_61_65_get_temp, + .get_temp = mv88e6xxx_get_temp, #endif .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index da558d887dad..cd6807c6b4ed 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -539,6 +539,54 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, } } +#ifdef CONFIG_NET_DSA_HWMON + +int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ret; + int val; + + *temp = 0; + + mutex_lock(&ps->phy_mutex); + + ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); + if (ret < 0) + goto error; + + /* Enable temperature sensor */ + ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a); + if (ret < 0) + goto error; + + ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); + if (ret < 0) + goto error; + + /* Wait for temperature to stabilize */ + usleep_range(10000, 12000); + + val = mv88e6xxx_phy_read(ds, 0x0, 0x1a); + if (val < 0) { + ret = val; + goto error; + } + + /* Disable temperature sensor */ + ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); + if (ret < 0) + goto error; + + *temp = ((val & 0x1f) - 5) * 5; + +error: + mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); + mutex_unlock(&ps->phy_mutex); + return ret; +} +#endif /* CONFIG_NET_DSA_HWMON */ + static int __init mv88e6xxx_init(void) { #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index a0780b08bb4c..03e397efde36 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -81,6 +81,7 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port); void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, struct ethtool_regs *regs, void *_p); +int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); extern struct dsa_switch_driver mv88e6131_switch_driver; extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; -- GitLab From 4dd38cdb42c31a4ba69fbccf826fd4cd5e488edb Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 15 Nov 2014 22:24:52 +0100 Subject: [PATCH 4937/9457] net: dsa: mv88e6171: Add support for reading the temperature This chip also has a temperature sensor which can be read using the common code. In order to use it, add the needed mutex protection for accessing registers via the shared code. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6171.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 537eeedece21..ed4c79778823 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -316,6 +316,8 @@ static int mv88e6171_setup(struct dsa_switch *ds) return ret; } + mutex_init(&ps->phy_mutex); + return 0; } @@ -329,18 +331,28 @@ static int mv88e6171_port_to_phy_addr(int port) static int mv88e6171_phy_read(struct dsa_switch *ds, int port, int regnum) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int addr = mv88e6171_port_to_phy_addr(port); + int ret; - return mv88e6xxx_phy_read(ds, addr, regnum); + mutex_lock(&ps->phy_mutex); + ret = mv88e6xxx_phy_read(ds, addr, regnum); + mutex_unlock(&ps->phy_mutex); + return ret; } static int mv88e6171_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) { + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int addr = mv88e6171_port_to_phy_addr(port); + int ret; - return mv88e6xxx_phy_write(ds, addr, regnum, val); + mutex_lock(&ps->phy_mutex); + ret = mv88e6xxx_phy_write(ds, addr, regnum, val); + mutex_unlock(&ps->phy_mutex); + return ret; } static struct mv88e6xxx_hw_stat mv88e6171_hw_stats[] = { @@ -408,6 +420,9 @@ struct dsa_switch_driver mv88e6171_switch_driver = { .get_strings = mv88e6171_get_strings, .get_ethtool_stats = mv88e6171_get_ethtool_stats, .get_sset_count = mv88e6171_get_sset_count, +#ifdef CONFIG_NET_DSA_HWMON + .get_temp = mv88e6xxx_get_temp, +#endif }; MODULE_ALIAS("platform:mv88e6171"); -- GitLab From 03d6faa98097c0321a95b64b22b03011466ceb60 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 15 Nov 2014 22:24:53 +0100 Subject: [PATCH 4938/9457] net: dsa: mv88e6171: Add support for reading switch registers The infrastructure can now report switch registers to ethtool. Add support for it to the mv88e6171 driver. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6171.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index ed4c79778823..aa33d16f2e22 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -423,6 +423,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { #ifdef CONFIG_NET_DSA_HWMON .get_temp = mv88e6xxx_get_temp, #endif + .get_regs_len = mv88e6xxx_get_regs_len, + .get_regs = mv88e6xxx_get_regs, }; MODULE_ALIAS("platform:mv88e6171"); -- GitLab From 960fb622f85180f36d3aff82af53e2be3db2f888 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:05 -0800 Subject: [PATCH 4939/9457] net: provide a per host RSS key generic infrastructure RSS (Receive Side Scaling) typically uses Toeplitz hash and a 40 or 52 bytes RSS key. Some drivers use a constant (and well known key), some drivers use a random key per port, making bonding setups hard to tune. Well known keys increase attack surface, considering that number of queues is usually a power of two. This patch provides infrastructure to help drivers doing the right thing. netdev_rss_key_fill() should be used by drivers to initialize their RSS key, even if they provide ethtool -X support to let user redefine the key later. A new /proc/sys/net/core/netdev_rss_key file can be used to get the host RSS key even for drivers not providing ethtool -x support, in case some applications want to precisely setup flows to match some RX queues. Tested: myhost:~# cat /proc/sys/net/core/netdev_rss_key 11:63:99:bb:79:fb:a5:a7:07:45:b2:20:bf:02:42:2d:08:1a:dd:19:2b:6b:23:ac:56:28:9d:70:c3:ac:e8:16:4b:b7:c1:10:53:a4:78:41:36:40:74:b6:15:ca:27:44:aa:b3:4d:72 myhost:~# ethtool -x eth0 RX flow hash indirection table for eth0 with 8 RX ring(s): 0: 0 1 2 3 4 5 6 7 RSS hash key: 11:63:99:bb:79:fb:a5:a7:07:45:b2:20:bf:02:42:2d:08:1a:dd:19:2b:6b:23:ac:56:28:9d:70:c3:ac:e8:16:4b:b7:c1:10:53:a4:78:41 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- Documentation/sysctl/net.txt | 22 ++++++++++++++++++++++ include/linux/netdevice.h | 6 ++++++ net/core/ethtool.c | 11 +++++++++++ net/core/sysctl_net_core.c | 19 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index e26c607468a6..666594b43cff 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -142,6 +142,28 @@ netdev_max_backlog Maximum number of packets, queued on the INPUT side, when the interface receives packets faster than kernel can process them. +netdev_rss_key +-------------- + +RSS (Receive Side Scaling) enabled drivers use a 40 bytes host key that is +randomly generated. +Some user space might need to gather its content even if drivers do not +provide ethtool -x support yet. + +myhost:~# cat /proc/sys/net/core/netdev_rss_key +84:50:f4:00:a8:15:d1:a7:e9:7f:1d:60:35:c7:47:25:42:97:74:ca:56:bb:b6:a1:d8: ... (52 bytes total) + +File contains nul bytes if no driver ever called netdev_rss_key_fill() function. +Note: +/proc/sys/net/core/netdev_rss_key contains 52 bytes of key, +but most drivers only use 40 bytes of it. + +myhost:~# ethtool -x eth0 +RX flow hash indirection table for eth0 with 8 RX ring(s): + 0: 0 1 2 3 4 5 6 7 +RSS hash key: +84:50:f4:00:a8:15:d1:a7:e9:7f:1d:60:35:c7:47:25:42:97:74:ca:56:bb:b6:a1:d8:43:e3:c9:0c:fd:17:55:c2:3a:4d:69:ed:f1:42:89 + netdev_tstamp_prequeue ---------------------- diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4a6f770377d3..db63cf459ba1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3422,6 +3422,12 @@ void netdev_upper_dev_unlink(struct net_device *dev, void netdev_adjacent_rename_links(struct net_device *dev, char *oldname); void *netdev_lower_dev_get_private(struct net_device *dev, struct net_device *lower_dev); + +/* RSS keys are 40 or 52 bytes long */ +#define NETDEV_RSS_KEY_LEN 52 +extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN]; +void netdev_rss_key_fill(void *buffer, size_t len); + int dev_get_nest_level(struct net_device *dev, bool (*type_check)(struct net_device *dev)); int skb_checksum_help(struct sk_buff *skb); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index b0f84f5ddda8..715f51f321e9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * Some useful ethtool_ops methods that're device independent. @@ -573,6 +574,16 @@ static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr, return 0; } +u8 netdev_rss_key[NETDEV_RSS_KEY_LEN]; + +void netdev_rss_key_fill(void *buffer, size_t len) +{ + BUG_ON(len > sizeof(netdev_rss_key)); + net_get_random_once(netdev_rss_key, sizeof(netdev_rss_key)); + memcpy(buffer, netdev_rss_key, len); +} +EXPORT_SYMBOL(netdev_rss_key_fill); + static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, void __user *useraddr) { diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index f93f092fe226..31baba2a71ce 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -217,6 +217,18 @@ static int set_default_qdisc(struct ctl_table *table, int write, } #endif +static int proc_do_rss_key(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct ctl_table fake_table; + char buf[NETDEV_RSS_KEY_LEN * 3]; + + snprintf(buf, sizeof(buf), "%*phC", NETDEV_RSS_KEY_LEN, netdev_rss_key); + fake_table.data = buf; + fake_table.maxlen = sizeof(buf); + return proc_dostring(&fake_table, write, buffer, lenp, ppos); +} + static struct ctl_table net_core_table[] = { #ifdef CONFIG_NET { @@ -265,6 +277,13 @@ static struct ctl_table net_core_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "netdev_rss_key", + .data = &netdev_rss_key, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = proc_do_rss_key, + }, #ifdef CONFIG_BPF_JIT { .procname = "bpf_jit_enable", -- GitLab From b23063034f1116a64b864e2cab1b238125096776 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:06 -0800 Subject: [PATCH 4940/9457] amd-xgbe: use netdev_rss_key_fill() helper Use netdev_rss_key_fill() helper, as it provides better support for some bonding setups. Signed-off-by: Eric Dumazet Cc: Lendacky, Thomas Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 05fbdf96e77e..dbd3850b8b0a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c @@ -338,7 +338,7 @@ static int xgbe_probe(struct platform_device *pdev) } /* Initialize RSS hash key and lookup table */ - get_random_bytes(pdata->rss_key, sizeof(pdata->rss_key)); + netdev_rss_key_fill(pdata->rss_key, sizeof(pdata->rss_key)); for (i = 0; i < XGBE_RSS_MAX_TABLE_SIZE; i++) XGMAC_SET_BITS(pdata->rss_table[i], MAC_RSSDR, DMCH, -- GitLab From e3ec69ca80a202f3a685c50daa18b63fbafcc536 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:07 -0800 Subject: [PATCH 4941/9457] bnx2x: use netdev_rss_key_fill() helper Use netdev_rss_key_fill() helper, as it provides better support for some bonding setups. Signed-off-by: Eric Dumazet Cc: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e9af4af5edba..b4d71fd909ee 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2099,7 +2099,7 @@ int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj, if (config_hash) { /* RSS keys */ - prandom_bytes(params.rss_key, T_ETH_RSS_KEY * 4); + netdev_rss_key_fill(params.rss_key, T_ETH_RSS_KEY * 4); __set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags); } -- GitLab From 3964835644091b57cf24c33ea95de4b5a26a5b1f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:08 -0800 Subject: [PATCH 4942/9457] tg3: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Prashant Sreedharan Cc: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index dbb41c1923e6..2dc001559a97 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -10540,19 +10540,14 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) udelay(100); if (tg3_flag(tp, ENABLE_RSS)) { + u32 rss_key[10]; + tg3_rss_write_indir_tbl(tp); - /* Setup the "secret" hash key. */ - tw32(MAC_RSS_HASH_KEY_0, 0x5f865437); - tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc); - tw32(MAC_RSS_HASH_KEY_2, 0x50103a45); - tw32(MAC_RSS_HASH_KEY_3, 0x36621985); - tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8); - tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e); - tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556); - tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe); - tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7); - tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481); + netdev_rss_key_fill(rss_key, 10 * sizeof(u32)); + + for (i = 0; i < 10 ; i++) + tw32(MAC_RSS_HASH_KEY_0 + i*4, rss_key[i]); } tp->rx_mode = RX_MODE_ENABLE; -- GitLab From 0fa6aa4ac4e00237f9e682ef315f51da3f840aa6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:09 -0800 Subject: [PATCH 4943/9457] bna: use netdev_rss_key_fill() helper Use netdev_rss_key_fill() helper, as it provides better support for some bonding setups. Signed-off-by: Eric Dumazet Cc: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/ethernet/brocade/bna/bnad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index c3861de9dc81..323721838cf9 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -2054,7 +2054,7 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config) BFI_ENET_RSS_IPV4_TCP); rx_config->rss_config.hash_mask = bnad->num_rxp_per_rx - 1; - get_random_bytes(rx_config->rss_config.toeplitz_hash_key, + netdev_rss_key_fill(rx_config->rss_config.toeplitz_hash_key, sizeof(rx_config->rss_config.toeplitz_hash_key)); } else { rx_config->rss_status = BNA_STATUS_T_DISABLED; -- GitLab From 1dcf7b1c5f5735d806c72505ddb451f2716ce46f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:10 -0800 Subject: [PATCH 4944/9457] be2net:use netdev_rss_key_fill() helper Use netdev_rss_key_fill() helper, as it provides better support for some bonding setups. Rename rss_hkey local variable to rss_key to have consistent name among drivers. Signed-off-by: Eric Dumazet Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 9a18e7930b31..54160cc62656 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2853,10 +2853,10 @@ static int be_close(struct net_device *netdev) static int be_rx_qs_create(struct be_adapter *adapter) { + struct rss_info *rss = &adapter->rss_info; + u8 rss_key[RSS_HASH_KEY_LEN]; struct be_rx_obj *rxo; int rc, i, j; - u8 rss_hkey[RSS_HASH_KEY_LEN]; - struct rss_info *rss = &adapter->rss_info; for_all_rx_queues(adapter, rxo, i) { rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN, @@ -2901,15 +2901,15 @@ static int be_rx_qs_create(struct be_adapter *adapter) rss->rss_flags = RSS_ENABLE_NONE; } - get_random_bytes(rss_hkey, RSS_HASH_KEY_LEN); + netdev_rss_key_fill(rss_key, RSS_HASH_KEY_LEN); rc = be_cmd_rss_config(adapter, rss->rsstable, rss->rss_flags, - 128, rss_hkey); + 128, rss_key); if (rc) { rss->rss_flags = RSS_ENABLE_NONE; return rc; } - memcpy(rss->rss_hkey, rss_hkey, RSS_HASH_KEY_LEN); + memcpy(rss->rss_hkey, rss_key, RSS_HASH_KEY_LEN); /* First time posting */ for_all_rx_queues(adapter, rxo, i) -- GitLab From 5c8d19da950861d0482abc0ac3481acca34b008f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:11 -0800 Subject: [PATCH 4945/9457] e100e: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Jeff Kirsher Cc: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/e1000e/netdev.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 247335d2c7ec..370cfa275ddb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3449,15 +3449,12 @@ static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 mrqc, rxcsum; + u32 rss_key[10]; int i; - static const u32 rsskey[10] = { - 0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0, - 0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe - }; - /* Fill out hash function seed */ + netdev_rss_key_fill(rss_key, sizeof(rss_key)); for (i = 0; i < 10; i++) - ew32(RSSRK(i), rsskey[i]); + ew32(RSSRK(i), rss_key[i]); /* Direct all traffic to queue 0 */ for (i = 0; i < 32; i++) -- GitLab From c41a4fba4a220c644ba6641c779cf427729f2eec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:12 -0800 Subject: [PATCH 4946/9457] fm10k: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Jeff Kirsher Cc: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index a0cb74ab3dc6..4f5892cc32d7 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -1551,15 +1551,11 @@ void fm10k_down(struct fm10k_intfc *interface) static int fm10k_sw_init(struct fm10k_intfc *interface, const struct pci_device_id *ent) { - static const u32 seed[FM10K_RSSRK_SIZE] = { 0xda565a6d, 0xc20e5b25, - 0x3d256741, 0xb08fa343, - 0xcb2bcad0, 0xb4307bae, - 0xa32dcb77, 0x0cf23080, - 0x3bb7426a, 0xfa01acbe }; const struct fm10k_info *fi = fm10k_info_tbl[ent->driver_data]; struct fm10k_hw *hw = &interface->hw; struct pci_dev *pdev = interface->pdev; struct net_device *netdev = interface->netdev; + u32 rss_key[FM10K_RSSRK_SIZE]; unsigned int rss; int err; @@ -1673,8 +1669,8 @@ static int fm10k_sw_init(struct fm10k_intfc *interface, /* initialize vxlan_port list */ INIT_LIST_HEAD(&interface->vxlan_port); - /* initialize RSS key */ - memcpy(interface->rssrk, seed, sizeof(seed)); + netdev_rss_key_fill(rss_key, sizeof(rss_key)); + memcpy(interface->rssrk, rss_key, sizeof(rss_key)); /* Start off interface as being down */ set_bit(__FM10K_DOWN, &interface->state); -- GitLab From 22f258a1cc2f35d2f5800276360c2aeed385b24e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:13 -0800 Subject: [PATCH 4947/9457] i40e: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Jeff Kirsher Cc: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++------- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 11 +++-------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index de664631c807..a0bee83ab2de 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7002,20 +7002,16 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) **/ static int i40e_config_rss(struct i40e_pf *pf) { - /* Set of random keys generated using kernel random number generator */ - static const u32 seed[I40E_PFQF_HKEY_MAX_INDEX + 1] = {0x41b01687, - 0x183cfd8c, 0xce880440, 0x580cbc3c, 0x35897377, - 0x328b25e1, 0x4fa98922, 0xb7d90c14, 0xd5bad70d, - 0xcd15a2c1, 0xe8580225, 0x4a1e9d11, 0xfe5731be}; + u32 rss_key[I40E_PFQF_HKEY_MAX_INDEX + 1]; struct i40e_hw *hw = &pf->hw; u32 lut = 0; int i, j; u64 hena; u32 reg_val; - /* Fill out hash function seed */ + netdev_rss_key_fill(rss_key, sizeof(rss_key)); for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) - wr32(hw, I40E_PFQF_HKEY(i), seed[i]); + wr32(hw, I40E_PFQF_HKEY(i), rss_key[i]); /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */ hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) | diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index f0d07ad54198..489227891ffb 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1434,18 +1434,12 @@ static int next_queue(struct i40evf_adapter *adapter, int j) **/ static void i40evf_configure_rss(struct i40evf_adapter *adapter) { + u32 rss_key[I40E_VFQF_HKEY_MAX_INDEX + 1]; struct i40e_hw *hw = &adapter->hw; u32 lut = 0; int i, j; u64 hena; - /* Set of random keys generated using kernel random number generator */ - static const u32 seed[I40E_VFQF_HKEY_MAX_INDEX + 1] = { - 0x794221b4, 0xbca0c5ab, 0x6cd5ebd9, 0x1ada6127, - 0x983b3aa1, 0x1c4e71eb, 0x7f6328b2, 0xfcdc0da0, - 0xc135cafa, 0x7a6f7e2d, 0xe7102d28, 0x163cd12e, - 0x4954b126 }; - /* No RSS for single queue. */ if (adapter->num_active_queues == 1) { wr32(hw, I40E_VFQF_HENA(0), 0); @@ -1454,8 +1448,9 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter) } /* Hash type is configured by the PF - we just supply the key */ + netdev_rss_key_fill(rss_key, sizeof(rss_key)); for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) - wr32(hw, I40E_VFQF_HKEY(i), seed[i]); + wr32(hw, I40E_VFQF_HKEY(i), rss_key[i]); /* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */ hena = I40E_DEFAULT_RSS_HENA; -- GitLab From eb31f8493eee1efcc194fdc98df830a503f572f1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:14 -0800 Subject: [PATCH 4948/9457] igb: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Jeff Kirsher Cc: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/igb/igb_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 1e35fae7a62b..b0e12e7c4a3d 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3372,14 +3372,11 @@ static void igb_setup_mrqc(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 mrqc, rxcsum; u32 j, num_rx_queues; - static const u32 rsskey[10] = { 0xDA565A6D, 0xC20E5B25, 0x3D256741, - 0xB08FA343, 0xCB2BCAD0, 0xB4307BAE, - 0xA32DCB77, 0x0CF23080, 0x3BB7426A, - 0xFA01ACBE }; + u32 rss_key[10]; - /* Fill out hash function seeds */ + netdev_rss_key_fill(rss_key, sizeof(rss_key)); for (j = 0; j < 10; j++) - wr32(E1000_RSSRK(j), rsskey[j]); + wr32(E1000_RSSRK(j), rss_key[j]); num_rx_queues = adapter->rss_queues; -- GitLab From 9913c61c4486e2452ca848729dede6038adb6ec2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:15 -0800 Subject: [PATCH 4949/9457] ixgbe: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Jeff Kirsher Cc: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index f5fcba4f9d21..932f77961d66 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3243,10 +3243,8 @@ static void ixgbe_setup_reta(struct ixgbe_adapter *adapter, const u32 *seed) static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, - 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, - 0x6A3E67EA, 0x14364D17, 0x3BED200D}; u32 mrqc = 0, rss_field = 0; + u32 rss_key[10]; u32 rxcsum; /* Disable indicating checksum in descriptor, enables RSS hash */ @@ -3290,7 +3288,8 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) if (adapter->flags2 & IXGBE_FLAG2_RSS_FIELD_IPV6_UDP) rss_field |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP; - ixgbe_setup_reta(adapter, seed); + netdev_rss_key_fill(rss_key, sizeof(rss_key)); + ixgbe_setup_reta(adapter, rss_key); mrqc |= rss_field; IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } -- GitLab From b9d1ab7eb42ede51ffbb6cafffd0a521b30c12e1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:16 -0800 Subject: [PATCH 4950/9457] mlx4: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Also provide ethtool -x support to fetch RSS key Signed-off-by: Eric Dumazet Cc: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 9 ++++++++- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 6 +----- include/linux/mlx4/qp.h | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 6c643230a5ed..710cf309962a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -973,6 +973,11 @@ static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev) return priv->rx_ring_num; } +static u32 mlx4_en_get_rxfh_key_size(struct net_device *netdev) +{ + return MLX4_EN_RSS_KEY_SIZE; +} + static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) { struct mlx4_en_priv *priv = netdev_priv(dev); @@ -988,7 +993,8 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) ring_index[n] = rss_map->qps[n % rss_rings].qpn - rss_map->base_qpn; } - + if (key) + netdev_rss_key_fill(key, MLX4_EN_RSS_KEY_SIZE); return err; } @@ -1799,6 +1805,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_rxnfc = mlx4_en_get_rxnfc, .set_rxnfc = mlx4_en_set_rxnfc, .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, + .get_rxfh_key_size = mlx4_en_get_rxfh_key_size, .get_rxfh = mlx4_en_get_rxfh, .set_rxfh = mlx4_en_set_rxfh, .get_channels = mlx4_en_get_channels, diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index ccd95177ea7c..b7bda8956011 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -1169,9 +1169,6 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) int i, qpn; int err = 0; int good_qps = 0; - static const u32 rsskey[10] = { 0xD181C62C, 0xF7F4DB5B, 0x1983A2FC, - 0x943E1ADB, 0xD9389E6B, 0xD1039C2C, 0xA74499AD, - 0x593D56D9, 0xF3253C06, 0x2ADC1FFC}; en_dbg(DRV, priv, "Configuring rss steering\n"); err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num, @@ -1226,8 +1223,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) rss_context->flags = rss_mask; rss_context->hash_fn = MLX4_RSS_HASH_TOP; - for (i = 0; i < 10; i++) - rss_context->rss_key[i] = cpu_to_be32(rsskey[i]); + netdev_rss_key_fill(rss_context->rss_key, MLX4_EN_RSS_KEY_SIZE); err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index 5f4e36cf0091..467ccdf94c98 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h @@ -120,13 +120,15 @@ enum { MLX4_RSS_QPC_FLAG_OFFSET = 13, }; +#define MLX4_EN_RSS_KEY_SIZE 40 + struct mlx4_rss_context { __be32 base_qpn; __be32 default_qpn; u16 reserved; u8 hash_fn; u8 flags; - __be32 rss_key[10]; + __be32 rss_key[MLX4_EN_RSS_KEY_SIZE / sizeof(__be32)]; __be32 base_qpn_udp; }; -- GitLab From 7a20db379ce7baeb258631a4fd1971d18f3af422 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:17 -0800 Subject: [PATCH 4951/9457] sfc: use netdev_rss_key_fill() helper Use netdev_rss_key_fill() helper, as it provides better support for some bonding setups. Signed-off-by: Eric Dumazet Cc: Shradha Shah Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/efx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index b49d04886d4f..238482495e81 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1616,7 +1616,7 @@ static int efx_probe_nic(struct efx_nic *efx) goto fail2; if (efx->n_channels > 1) - get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); + netdev_rss_key_fill(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++) efx->rx_indir_table[i] = ethtool_rxfh_indir_default(i, efx->rss_spread); -- GitLab From 6bf79cdddd50e90cbba7471623c129dadf9c873b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Nov 2014 06:23:18 -0800 Subject: [PATCH 4952/9457] vmxnet3: use netdev_rss_key_fill() helper Use of well known RSS key increases attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Shreyas Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 6dfcbf523936..afd295348ddb 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2199,13 +2199,6 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) if (adapter->rss) { struct UPT1_RSSConf *rssConf = adapter->rss_conf; - static const uint8_t rss_key[UPT1_RSS_MAX_KEY_SIZE] = { - 0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac, - 0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28, - 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70, - 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3, - 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9, - }; devRead->misc.uptFeatures |= UPT1_F_RSS; devRead->misc.numRxQueues = adapter->num_rx_queues; @@ -2216,7 +2209,7 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ; rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE; rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE; - memcpy(rssConf->hashKey, rss_key, sizeof(rss_key)); + netdev_rss_key_fill(rssConf->hashKey, sizeof(rssConf->hashKey)); for (i = 0; i < rssConf->indTableSize; i++) rssConf->indTable[i] = ethtool_rxfh_indir_default( -- GitLab From 15962df86e0e89055f9a519f149201ee33d96091 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 23 Sep 2014 22:42:14 +0200 Subject: [PATCH 4953/9457] dt-bindings: document gpio-charger bindings This documents the binding for the gpio-charger power-supply. Signed-off-by: Heiko Stuebner Reviewed-by: Doug Anderson --- .../bindings/power_supply/gpio-charger.txt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/power_supply/gpio-charger.txt diff --git a/Documentation/devicetree/bindings/power_supply/gpio-charger.txt b/Documentation/devicetree/bindings/power_supply/gpio-charger.txt new file mode 100644 index 000000000000..adbb5dc5b6e9 --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/gpio-charger.txt @@ -0,0 +1,27 @@ +gpio-charger + +Required properties : + - compatible : "gpio-charger" + - gpios : GPIO indicating the charger presence. + See GPIO binding in bindings/gpio/gpio.txt . + - charger-type : power supply type, one of + unknown + battery + ups + mains + usb-sdp (USB standard downstream port) + usb-dcp (USB dedicated charging port) + usb-cdp (USB charging downstream port) + usb-aca (USB accessory charger adapter) + +Example: + + usb_charger: charger { + compatible = "gpio-charger"; + charger-type = "usb-sdp"; + gpios = <&gpf0 2 0 0 0>; + } + + battery { + power-supplies = <&usb_charger>; + }; -- GitLab From c8dd9cce4f3fedf5e333bb8623cb7da6d7e3ea91 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 23 Sep 2014 22:42:15 +0200 Subject: [PATCH 4954/9457] power: gpio-charger: add device tree support Add the ability to parse gpio-charger data from a devicetree node. Signed-off-by: Heiko Stuebner Reviewed-by: Doug Anderson Tested-by: Doug Anderson --- drivers/power/gpio-charger.c | 72 +++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 7536933d0ab9..df984ecad1cc 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include @@ -69,6 +71,59 @@ static enum power_supply_property gpio_charger_properties[] = { POWER_SUPPLY_PROP_ONLINE, }; +static +struct gpio_charger_platform_data *gpio_charger_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct gpio_charger_platform_data *pdata; + const char *chargetype; + enum of_gpio_flags flags; + int ret; + + if (!np) + return ERR_PTR(-ENOENT); + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->name = np->name; + + pdata->gpio = of_get_gpio_flags(np, 0, &flags); + if (pdata->gpio < 0) { + if (pdata->gpio != -EPROBE_DEFER) + dev_err(dev, "could not get charger gpio\n"); + return ERR_PTR(pdata->gpio); + } + + pdata->gpio_active_low = !!(flags & OF_GPIO_ACTIVE_LOW); + + pdata->type = POWER_SUPPLY_TYPE_UNKNOWN; + ret = of_property_read_string(np, "charger-type", &chargetype); + if (ret >= 0) { + if (!strncmp("unknown", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_UNKNOWN; + else if (!strncmp("battery", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_BATTERY; + else if (!strncmp("ups", chargetype, 3)) + pdata->type = POWER_SUPPLY_TYPE_UPS; + else if (!strncmp("mains", chargetype, 5)) + pdata->type = POWER_SUPPLY_TYPE_MAINS; + else if (!strncmp("usb-sdp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB; + else if (!strncmp("usb-dcp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_DCP; + else if (!strncmp("usb-cdp", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_CDP; + else if (!strncmp("usb-aca", chargetype, 7)) + pdata->type = POWER_SUPPLY_TYPE_USB_ACA; + else + dev_warn(dev, "unknown charger type %s\n", chargetype); + } + + return pdata; +} + static int gpio_charger_probe(struct platform_device *pdev) { const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; @@ -78,8 +133,13 @@ static int gpio_charger_probe(struct platform_device *pdev) int irq; if (!pdata) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; + pdata = gpio_charger_parse_dt(&pdev->dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "No platform data\n"); + return ret; + } } if (!gpio_is_valid(pdata->gpio)) { @@ -103,6 +163,7 @@ static int gpio_charger_probe(struct platform_device *pdev) charger->get_property = gpio_charger_get_property; charger->supplied_to = pdata->supplied_to; charger->num_supplicants = pdata->num_supplicants; + charger->of_node = pdev->dev.of_node; ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); if (ret) { @@ -189,6 +250,12 @@ static int gpio_charger_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, gpio_charger_suspend, gpio_charger_resume); +static const struct of_device_id gpio_charger_match[] = { + { .compatible = "gpio-charger" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpio_charger_match); + static struct platform_driver gpio_charger_driver = { .probe = gpio_charger_probe, .remove = gpio_charger_remove, @@ -196,6 +263,7 @@ static struct platform_driver gpio_charger_driver = { .name = "gpio-charger", .owner = THIS_MODULE, .pm = &gpio_charger_pm_ops, + .of_match_table = gpio_charger_match, }, }; -- GitLab From b8e64eea41ea71b58e61e35ee347464efd60ca21 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Fri, 26 Sep 2014 11:59:06 +0800 Subject: [PATCH 4955/9457] power: reset: imx-snvs-poweroff: add power off driver for i.mx6 This driver register pm_power_off with snvs power off function. If your boards NOT use PMIC_ON_REQ to turn on/off external pmic, or use other pin to do, please disable the driver in dts, otherwise, your pm_power_off maybe overwrote by this driver. Signed-off-by: Robin Gong Signed-off-by: Sebastian Reichel --- .../power_supply/imx-snvs-poweroff.txt | 23 +++++++ drivers/power/reset/Kconfig | 9 +++ drivers/power/reset/Makefile | 1 + drivers/power/reset/imx-snvs-poweroff.c | 66 +++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt create mode 100644 drivers/power/reset/imx-snvs-poweroff.c diff --git a/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt new file mode 100644 index 000000000000..dc7c9bad63ea --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt @@ -0,0 +1,23 @@ +i.mx6 Poweroff Driver + +SNVS_LPCR in SNVS module can power off the whole system by pull +PMIC_ON_REQ low if PMIC_ON_REQ is connected with external PMIC. +If you don't want to use PMIC_ON_REQ as power on/off control, +please set status='disabled' to disable this driver. + +Required Properties: +-compatible: "fsl,sec-v4.0-poweroff" +-reg: Specifies the physical address of the SNVS_LPCR register + +Example: + snvs@020cc000 { + compatible = "fsl,sec-v4.0-mon", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x020cc000 0x4000>; + ..... + snvs_poweroff: snvs-poweroff@38 { + compatible = "fsl,sec-v4.0-poweroff"; + reg = <0x38 0x4>; + }; + } diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index f65ff49bb275..028e76504519 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -71,6 +71,15 @@ config POWER_RESET_HISI help Reboot support for Hisilicon boards. +config POWER_RESET_IMX + bool "IMX6 power-off driver" + depends on POWER_RESET && SOC_IMX6 + help + This driver support power off external PMIC by PMIC_ON_REQ on i.mx6 + boards.If you want to use other pin to control external power,please + say N here or disable in dts to make sure pm_power_off never be + overwrote wrongly by this driver. + config POWER_RESET_MSM bool "Qualcomm MSM power-off driver" depends on ARCH_QCOM diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 76ce1c59469b..1d4804d6b323 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o +obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o diff --git a/drivers/power/reset/imx-snvs-poweroff.c b/drivers/power/reset/imx-snvs-poweroff.c new file mode 100644 index 000000000000..ad6ce5020ea7 --- /dev/null +++ b/drivers/power/reset/imx-snvs-poweroff.c @@ -0,0 +1,66 @@ +/* Power off driver for i.mx6 + * Copyright (c) 2014, FREESCALE CORPORATION. All rights reserved. + * + * based on msm-poweroff.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void __iomem *snvs_base; + +static void do_imx_poweroff(void) +{ + u32 value = readl(snvs_base); + + /* set TOP and DP_EN bit */ + writel(value | 0x60, snvs_base); +} + +static int imx_poweroff_probe(struct platform_device *pdev) +{ + snvs_base = of_iomap(pdev->dev.of_node, 0); + if (!snvs_base) { + dev_err(&pdev->dev, "failed to get memory\n"); + return -ENODEV; + } + + pm_power_off = do_imx_poweroff; + return 0; +} + +static const struct of_device_id of_imx_poweroff_match[] = { + { .compatible = "fsl,sec-v4.0-poweroff", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_imx_poweroff_match); + +static struct platform_driver imx_poweroff_driver = { + .probe = imx_poweroff_probe, + .driver = { + .name = "imx-snvs-poweroff", + .of_match_table = of_match_ptr(of_imx_poweroff_match), + }, +}; + +static int __init imx_poweroff_init(void) +{ + return platform_driver_register(&imx_poweroff_driver); +} +device_initcall(imx_poweroff_init); -- GitLab From 46c99ac66222aed719f26835eae4946d72880cbe Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:27 -0700 Subject: [PATCH 4956/9457] power/reset: vexpress: Register with kernel restart handler Use the kernel restart handler instead of setting arm_pm_restart directly. This allows for more than one restart handler in the system. Signed-off-by: Guenter Roeck --- drivers/power/reset/vexpress-poweroff.c | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index 4dc102e2b230..9dfc9cee3232 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c @@ -12,14 +12,14 @@ */ #include +#include #include #include #include +#include #include #include -#include - static void vexpress_reset_do(struct device *dev, const char *what) { int err = -ENOENT; @@ -43,11 +43,19 @@ static void vexpress_power_off(void) static struct device *vexpress_restart_device; -static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd) +static int vexpress_restart(struct notifier_block *this, unsigned long mode, + void *cmd) { vexpress_reset_do(vexpress_restart_device, "restart"); + + return NOTIFY_DONE; } +static struct notifier_block vexpress_restart_nb = { + .notifier_call = vexpress_restart, + .priority = 128, +}; + static ssize_t vexpress_reset_active_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -86,12 +94,28 @@ static struct of_device_id vexpress_reset_of_match[] = { {} }; +static int _vexpress_register_restart_handler(struct device *dev) +{ + int err; + + vexpress_restart_device = dev; + err = register_restart_handler(&vexpress_restart_nb); + if (err) { + dev_err(dev, "cannot register restart handler (err=%d)\n", err); + return err; + } + device_create_file(dev, &dev_attr_active); + + return 0; +} + static int vexpress_reset_probe(struct platform_device *pdev) { enum vexpress_reset_func func; const struct of_device_id *match = of_match_device(vexpress_reset_of_match, &pdev->dev); struct regmap *regmap; + int ret = 0; if (match) func = (enum vexpress_reset_func)match->data; @@ -110,18 +134,14 @@ static int vexpress_reset_probe(struct platform_device *pdev) break; case FUNC_RESET: if (!vexpress_restart_device) - vexpress_restart_device = &pdev->dev; - arm_pm_restart = vexpress_restart; - device_create_file(&pdev->dev, &dev_attr_active); + ret = _vexpress_register_restart_handler(&pdev->dev); break; case FUNC_REBOOT: - vexpress_restart_device = &pdev->dev; - arm_pm_restart = vexpress_restart; - device_create_file(&pdev->dev, &dev_attr_active); + ret = _vexpress_register_restart_handler(&pdev->dev); break; }; - return 0; + return ret; } static const struct platform_device_id vexpress_reset_id_table[] = { -- GitLab From ef288f9f656cdf46cb7788b6bb18da1c3b722feb Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:28 -0700 Subject: [PATCH 4957/9457] power/reset: xgene: Return -ENOMEM if out of memory It is customary to return an error code of -ENOMEM if the system is out of memory. Also, in that case, the infrastructure will report an error, so it is unnecessary to report it again. Cc: Loc Ho Signed-off-by: Guenter Roeck --- drivers/power/reset/xgene-reboot.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index 6b49be6867ab..6ca4bf99bbdd 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -61,10 +61,8 @@ static int xgene_reboot_probe(struct platform_device *pdev) struct xgene_reboot_context *ctx; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - dev_err(&pdev->dev, "out of memory for context\n"); - return -ENODEV; - } + if (!ctx) + return -ENOMEM; ctx->csr = of_iomap(pdev->dev.of_node, 0); if (!ctx->csr) { -- GitLab From 22ecd65f4067461f0488bc9b1f2c26eb70f69fa5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:29 -0700 Subject: [PATCH 4958/9457] power/reset: xgene: Drop devm_kfree Calling devm_kfree is unnecessary. Drop it. Cc: Loc Ho Signed-off-by: Guenter Roeck --- drivers/power/reset/xgene-reboot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index 6ca4bf99bbdd..c49a3fee65e7 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -66,7 +66,6 @@ static int xgene_reboot_probe(struct platform_device *pdev) ctx->csr = of_iomap(pdev->dev.of_node, 0); if (!ctx->csr) { - devm_kfree(&pdev->dev, ctx); dev_err(&pdev->dev, "can not map resource\n"); return -ENODEV; } -- GitLab From 43160718d95db9e2336cd787fa8fcad39660b883 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:30 -0700 Subject: [PATCH 4959/9457] power/reset: xgene: Use local variable dev instead of pdev->dev Using a local variable dev to point to the device is simpler then repeatedly dereferencing pdev->dev. Cc: Loc Ho Signed-off-by: Guenter Roeck --- drivers/power/reset/xgene-reboot.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index c49a3fee65e7..94f10ad4100c 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -33,7 +33,7 @@ #include struct xgene_reboot_context { - struct platform_device *pdev; + struct device *dev; void *csr; u32 mask; }; @@ -53,27 +53,28 @@ static void xgene_restart(enum reboot_mode mode, const char *cmd) while (time_before(jiffies, timeout)) cpu_relax(); - dev_emerg(&ctx->pdev->dev, "Unable to restart system\n"); + dev_emerg(ctx->dev, "Unable to restart system\n"); } static int xgene_reboot_probe(struct platform_device *pdev) { struct xgene_reboot_context *ctx; + struct device *dev = &pdev->dev; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; - ctx->csr = of_iomap(pdev->dev.of_node, 0); + ctx->csr = of_iomap(dev->of_node, 0); if (!ctx->csr) { - dev_err(&pdev->dev, "can not map resource\n"); + dev_err(dev, "can not map resource\n"); return -ENODEV; } - if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask)) + if (of_property_read_u32(dev->of_node, "mask", &ctx->mask)) ctx->mask = 0xFFFFFFFF; - ctx->pdev = pdev; + ctx->dev = dev; arm_pm_restart = xgene_restart; xgene_restart_ctx = ctx; -- GitLab From 745e19764a0cff55a55010cfabe7e9ff77fa72a5 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:31 -0700 Subject: [PATCH 4960/9457] power/reset: xgene: Use mdelay instead of jiffies based timeout jiffies are not running at this stage of system shutdown, meaning an error in the reset function would never be reported. Replace with mdelay(). Cc: Loc Ho Signed-off-by: Guenter Roeck --- drivers/power/reset/xgene-reboot.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index 94f10ad4100c..9da341d11caf 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -24,6 +24,7 @@ * For system shutdown, this is board specify. If a board designer * implements GPIO shutdown, use the gpio-poweroff.c driver. */ +#include #include #include #include @@ -43,15 +44,12 @@ static struct xgene_reboot_context *xgene_restart_ctx; static void xgene_restart(enum reboot_mode mode, const char *cmd) { struct xgene_reboot_context *ctx = xgene_restart_ctx; - unsigned long timeout; /* Issue the reboot */ if (ctx) writel(ctx->mask, ctx->csr); - timeout = jiffies + HZ; - while (time_before(jiffies, timeout)) - cpu_relax(); + mdelay(1000); dev_emerg(ctx->dev, "Unable to restart system\n"); } -- GitLab From 8f57f2310f6b5f787a29e4eb440afd8b3f6b2554 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:32 -0700 Subject: [PATCH 4961/9457] power/reset: xgene: Register with kernel restart handler Register with kernel restart handler instead of setting arm_pm_restart directly. This patch also addresses the following compile warning. drivers/power/reset/xgene-reboot.c: In function 'xgene_reboot_probe': drivers/power/reset/xgene-reboot.c:77:17: warning: assignment from incompatible pointer type [enabled by default] The warning was due to a mismatch between the type of arm_pm_restart and the restart function. Cc: Loc Ho Signed-off-by: Guenter Roeck --- drivers/power/reset/xgene-reboot.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c index 9da341d11caf..b0e5002f8deb 100644 --- a/drivers/power/reset/xgene-reboot.c +++ b/drivers/power/reset/xgene-reboot.c @@ -26,38 +26,43 @@ */ #include #include +#include #include #include #include +#include #include #include -#include struct xgene_reboot_context { struct device *dev; void *csr; u32 mask; + struct notifier_block restart_handler; }; -static struct xgene_reboot_context *xgene_restart_ctx; - -static void xgene_restart(enum reboot_mode mode, const char *cmd) +static int xgene_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { - struct xgene_reboot_context *ctx = xgene_restart_ctx; + struct xgene_reboot_context *ctx = + container_of(this, struct xgene_reboot_context, + restart_handler); /* Issue the reboot */ - if (ctx) - writel(ctx->mask, ctx->csr); + writel(ctx->mask, ctx->csr); mdelay(1000); dev_emerg(ctx->dev, "Unable to restart system\n"); + + return NOTIFY_DONE; } static int xgene_reboot_probe(struct platform_device *pdev) { struct xgene_reboot_context *ctx; struct device *dev = &pdev->dev; + int err; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -73,10 +78,13 @@ static int xgene_reboot_probe(struct platform_device *pdev) ctx->mask = 0xFFFFFFFF; ctx->dev = dev; - arm_pm_restart = xgene_restart; - xgene_restart_ctx = ctx; + ctx->restart_handler.notifier_call = xgene_restart_handler; + ctx->restart_handler.priority = 128; + err = register_restart_handler(&ctx->restart_handler); + if (err) + dev_err(dev, "cannot register restart handler (err=%d)\n", err); - return 0; + return err; } static struct of_device_id xgene_reboot_of_match[] = { -- GitLab From fcf01c51f0f5565a184638b7d055e590aad6c0f8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:33 -0700 Subject: [PATCH 4962/9457] power/reset: axxia: Register with kernel restart handler Register with kernel restart handler instead of setting arm_pm_restart directly. Cc: Anders Berg Tested-by: Anders Berg Signed-off-by: Guenter Roeck --- drivers/power/reset/axxia-reset.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c index 3b1f8d601784..4e4cd1c8fe50 100644 --- a/drivers/power/reset/axxia-reset.c +++ b/drivers/power/reset/axxia-reset.c @@ -19,14 +19,12 @@ #include #include #include +#include #include #include #include #include -#include - - #define SC_CRIT_WRITE_KEY 0x1000 #define SC_LATCH_ON_RESET 0x1004 #define SC_RESET_CONTROL 0x1008 @@ -39,7 +37,8 @@ static struct regmap *syscon; -static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) +static int axxia_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { /* Access Key (0xab) */ regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab); @@ -50,11 +49,19 @@ static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) /* Assert chip reset */ regmap_update_bits(syscon, SC_RESET_CONTROL, RSTCTL_RST_CHIP, RSTCTL_RST_CHIP); + + return NOTIFY_DONE; } +static struct notifier_block axxia_restart_nb = { + .notifier_call = axxia_restart_handler, + .priority = 128, +}; + static int axxia_reset_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + int err; syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); if (IS_ERR(syscon)) { @@ -62,9 +69,11 @@ static int axxia_reset_probe(struct platform_device *pdev) return PTR_ERR(syscon); } - arm_pm_restart = do_axxia_restart; + err = register_restart_handler(&axxia_restart_nb); + if (err) + dev_err(dev, "cannot register restart handler (err=%d)\n", err); - return 0; + return err; } static const struct of_device_id of_axxia_reset_match[] = { -- GitLab From f59a42d4e177564b9892112af7a4e73d0c91f9b4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:34 -0700 Subject: [PATCH 4963/9457] power/reset: keystone: Register with kernel restart handler Register with kernel restart handler instead of setting arm_pm_restart directly. Move notifier registration to the end of the probe function to avoid having to implement error handling. Cc: Ivan Khoronzhuk Cc: Santosh Shilimkar Acked-by: Santosh Shilimkar Tested-by: Ivan Khoronzhuk Signed-off-by: Guenter Roeck --- drivers/power/reset/keystone-reset.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/power/reset/keystone-reset.c b/drivers/power/reset/keystone-reset.c index 408a18fd91cb..4b6b12e74477 100644 --- a/drivers/power/reset/keystone-reset.c +++ b/drivers/power/reset/keystone-reset.c @@ -12,9 +12,9 @@ #include #include +#include #include #include -#include #include #include @@ -52,7 +52,8 @@ static inline int rsctrl_enable_rspll_write(void) RSCTRL_KEY_MASK, RSCTRL_KEY); } -static void rsctrl_restart(enum reboot_mode mode, const char *cmd) +static int rsctrl_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { /* enable write access to RSTCTRL */ rsctrl_enable_rspll_write(); @@ -60,8 +61,15 @@ static void rsctrl_restart(enum reboot_mode mode, const char *cmd) /* reset the SOC */ regmap_update_bits(pllctrl_regs, rspll_offset + RSCTRL_RG, RSCTRL_RESET_MASK, 0); + + return NOTIFY_DONE; } +static struct notifier_block rsctrl_restart_nb = { + .notifier_call = rsctrl_restart_handler, + .priority = 128, +}; + static struct of_device_id rsctrl_of_match[] = { {.compatible = "ti,keystone-reset", }, {}, @@ -114,8 +122,6 @@ static int rsctrl_probe(struct platform_device *pdev) if (ret) return ret; - arm_pm_restart = rsctrl_restart; - /* disable a reset isolation for all module clocks */ ret = regmap_write(pllctrl_regs, rspll_offset + RSISO_RG, 0); if (ret) @@ -147,7 +153,11 @@ static int rsctrl_probe(struct platform_device *pdev) return ret; } - return 0; + ret = register_restart_handler(&rsctrl_restart_nb); + if (ret) + dev_err(dev, "cannot register restart handler (err=%d)\n", ret); + + return ret; } static struct platform_driver rsctrl_driver = { -- GitLab From 6724534c79ead70e310616d0e4380bb9fbb67c15 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:35 -0700 Subject: [PATCH 4964/9457] power/reset: hisi: Register with kernel restart handler Register with kernel restart handler instead of setting arm_pm_restart directly. Cc: Haojian Zhuang Signed-off-by: Guenter Roeck --- drivers/power/reset/hisi-reboot.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/power/reset/hisi-reboot.c b/drivers/power/reset/hisi-reboot.c index 0c91d0231d36..5385460e23bb 100644 --- a/drivers/power/reset/hisi-reboot.c +++ b/drivers/power/reset/hisi-reboot.c @@ -14,27 +14,36 @@ #include #include #include +#include #include #include #include #include -#include static void __iomem *base; static u32 reboot_offset; -static void hisi_restart(enum reboot_mode mode, const char *cmd) +static int hisi_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { writel_relaxed(0xdeadbeef, base + reboot_offset); while (1) cpu_do_idle(); + + return NOTIFY_DONE; } +static struct notifier_block hisi_restart_nb = { + .notifier_call = hisi_restart_handler, + .priority = 128, +}; + static int hisi_reboot_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + int err; base = of_iomap(np, 0); if (!base) { @@ -47,9 +56,12 @@ static int hisi_reboot_probe(struct platform_device *pdev) return -EINVAL; } - arm_pm_restart = hisi_restart; + err = register_restart_handler(&hisi_restart_nb); + if (err) + dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n", + err); - return 0; + return err; } static struct of_device_id hisi_reboot_of_match[] = { -- GitLab From 6136c41ae9c7af4bd89d845bda5dd84b9c9f3138 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 30 Sep 2014 10:48:36 -0700 Subject: [PATCH 4965/9457] power/reset: brcmstb: Register with kernel restart handler Register with kernel restart handler instead of setting arm_pm_restart directly. Cc: Marc Carino Cc: Brian Norris Signed-off-by: Guenter Roeck --- drivers/power/reset/brcmstb-reboot.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c index 3f236924742a..1ad56298c6c7 100644 --- a/drivers/power/reset/brcmstb-reboot.c +++ b/drivers/power/reset/brcmstb-reboot.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -26,8 +27,6 @@ #include #include -#include - #define RESET_SOURCE_ENABLE_REG 1 #define SW_MASTER_RESET_REG 2 @@ -35,7 +34,8 @@ static struct regmap *regmap; static u32 rst_src_en; static u32 sw_mstr_rst; -static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) +static int brcmstb_restart_handler(struct notifier_block *this, + unsigned long mode, void *cmd) { int rc; u32 tmp; @@ -43,31 +43,38 @@ static void brcmstb_reboot(enum reboot_mode mode, const char *cmd) rc = regmap_write(regmap, rst_src_en, 1); if (rc) { pr_err("failed to write rst_src_en (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_read(regmap, rst_src_en, &tmp); if (rc) { pr_err("failed to read rst_src_en (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_write(regmap, sw_mstr_rst, 1); if (rc) { pr_err("failed to write sw_mstr_rst (%d)\n", rc); - return; + return NOTIFY_DONE; } rc = regmap_read(regmap, sw_mstr_rst, &tmp); if (rc) { pr_err("failed to read sw_mstr_rst (%d)\n", rc); - return; + return NOTIFY_DONE; } while (1) ; + + return NOTIFY_DONE; } +static struct notifier_block brcmstb_restart_nb = { + .notifier_call = brcmstb_restart_handler, + .priority = 128, +}; + static int brcmstb_reboot_probe(struct platform_device *pdev) { int rc; @@ -93,9 +100,12 @@ static int brcmstb_reboot_probe(struct platform_device *pdev) return -EINVAL; } - arm_pm_restart = brcmstb_reboot; + rc = register_restart_handler(&brcmstb_restart_nb); + if (rc) + dev_err(&pdev->dev, + "cannot register restart handler (err=%d)\n", rc); - return 0; + return rc; } static const struct of_device_id of_match[] = { -- GitLab From 99a79565e6db676bca8c7aeddd9fec44e730965e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 9 Oct 2014 19:50:26 -0300 Subject: [PATCH 4966/9457] power: ds2782_battery: Simplify the PM hooks The SIMPLE_DEV_PM_OPS() macro already takes care of the CONFIG_PM_SLEEP=n case, so we can simplify the code a little bit. Signed-off-by: Fabio Estevam Signed-off-by: Sebastian Reichel --- drivers/power/ds2782_battery.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index 041f9b638d28..39694883d3bf 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -351,13 +351,9 @@ static int ds278x_resume(struct device *dev) schedule_delayed_work(&info->bat_work, DS278x_DELAY); return 0; } +#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume); -#define DS278X_BATTERY_PM_OPS (&ds278x_battery_pm_ops) - -#else -#define DS278X_BATTERY_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ enum ds278x_num_id { DS2782 = 0, @@ -460,7 +456,7 @@ MODULE_DEVICE_TABLE(i2c, ds278x_id); static struct i2c_driver ds278x_battery_driver = { .driver = { .name = "ds2782-battery", - .pm = DS278X_BATTERY_PM_OPS, + .pm = &ds278x_battery_pm_ops, }, .probe = ds278x_battery_probe, .remove = ds278x_battery_remove, -- GitLab From 5447326ff7e42ae36b85caedb2a787ff4db646f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Sun, 16 Nov 2014 18:16:12 -0800 Subject: [PATCH 4967/9457] Input: atkbd - correct MSC_SCAN events for force_release keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the change either no scancode would be reported on release of force_release keys, or - if the key is marked as force_release erroneously - the release event and the scancode would be reported in separate reports to the input layer. Signed-off-by: Stefan Brüns Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6f5d79569136..e27a25892db4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -456,8 +456,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, keycode = atkbd->keycode[code]; - if (keycode != ATKBD_KEY_NULL) - input_event(dev, EV_MSC, MSC_SCAN, code); + if (!(atkbd->release && test_bit(code, atkbd->force_release_mask))) + if (keycode != ATKBD_KEY_NULL) + input_event(dev, EV_MSC, MSC_SCAN, code); switch (keycode) { case ATKBD_KEY_NULL: @@ -511,6 +512,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, input_sync(dev); if (value && test_bit(code, atkbd->force_release_mask)) { + input_event(dev, EV_MSC, MSC_SCAN, code); input_report_key(dev, keycode, 0); input_sync(dev); } -- GitLab From 59994fb01a102a448ba758c9b824a29b4a99cc1b Mon Sep 17 00:00:00 2001 From: Vineeth Vijayan Date: Fri, 14 Nov 2014 14:42:05 +0530 Subject: [PATCH 4968/9457] powerpc: Use generic PIE randomization Back in 2009 we merged 501cb16d3cfd "Randomise PIEs", which added support for randomizing PIE (Position Independent Executable) binaries. That commit added randomize_et_dyn(), which correctly randomized the addresses, but failed to honor PF_RANDOMIZE. That means it was not possible to disable PIE randomization via the personality flag, or /proc/sys/kernel/randomize_va_space. Since then there has been generic support for PIE randomization added to binfmt_elf.c, selectable via ARCH_BINFMT_ELF_RANDOMIZE_PIE. Enabling that allows us to drop randomize_et_dyn(), which means we start honoring PF_RANDOMIZE correctly. It also causes a fairly major change to how we layout PIE binaries. Currently we will place the binary at 512MB-520MB for 32 bit binaries, or 512MB-1.5GB for 64 bit binaries, eg: $ cat /proc/$$/maps 4e550000-4e580000 r-xp 00000000 08:02 129813 /bin/dash 4e580000-4e590000 rw-p 00020000 08:02 129813 /bin/dash 10014110000-10014140000 rw-p 00000000 00:00 0 [heap] 3fffaa3f0000-3fffaa5a0000 r-xp 00000000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so 3fffaa5a0000-3fffaa5b0000 rw-p 001a0000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so 3fffaa5c0000-3fffaa5d0000 rw-p 00000000 00:00 0 3fffaa5d0000-3fffaa5f0000 r-xp 00000000 00:00 0 [vdso] 3fffaa5f0000-3fffaa620000 r-xp 00000000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so 3fffaa620000-3fffaa630000 rw-p 00020000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so 3ffffc340000-3ffffc370000 rw-p 00000000 00:00 0 [stack] With this commit applied we don't do any special randomisation for the binary, and instead rely on mmap randomisation. This means the binary ends up at high addresses, eg: $ cat /proc/$$/maps 3fff99820000-3fff999d0000 r-xp 00000000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so 3fff999d0000-3fff999e0000 rw-p 001a0000 08:02 921 /lib/powerpc64le-linux-gnu/libc-2.19.so 3fff999f0000-3fff99a00000 rw-p 00000000 00:00 0 3fff99a00000-3fff99a20000 r-xp 00000000 00:00 0 [vdso] 3fff99a20000-3fff99a50000 r-xp 00000000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so 3fff99a50000-3fff99a60000 rw-p 00020000 08:02 1246 /lib/powerpc64le-linux-gnu/ld-2.19.so 3fff99a60000-3fff99a90000 r-xp 00000000 08:02 129813 /bin/dash 3fff99a90000-3fff99aa0000 rw-p 00020000 08:02 129813 /bin/dash 3fffc3de0000-3fffc3e10000 rw-p 00000000 00:00 0 [stack] 3fffc55e0000-3fffc5610000 rw-p 00000000 00:00 0 [heap] Although this should be OK, it's possible it might break badly written binaries that make assumptions about the address space layout. Signed-off-by: Vineeth Vijayan [mpe: Rewrite changelog] Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/elf.h | 3 +-- arch/powerpc/kernel/process.c | 9 --------- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 46227336aacb..421df5cc6d18 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -88,6 +88,7 @@ config PPC select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select BINFMT_ELF + select ARCH_BINFMT_ELF_RANDOMIZE_PIE select OF select OF_EARLY_FLATTREE select OF_RESERVED_MEM diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 888d8f3f2524..57d289acb803 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -28,8 +28,7 @@ the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ -extern unsigned long randomize_et_dyn(unsigned long base); -#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000)) +#define ELF_ET_DYN_BASE 0x20000000 #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index f6b82152e7aa..b4cc7bef6b16 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1654,12 +1654,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) return ret; } -unsigned long randomize_et_dyn(unsigned long base) -{ - unsigned long ret = PAGE_ALIGN(base + brk_rnd()); - - if (ret < base) - return base; - - return ret; -} -- GitLab From 16b1d26e77b142546e2b9b6dc3b5aa5c44ae3b77 Mon Sep 17 00:00:00 2001 From: Neelesh Gupta Date: Tue, 14 Oct 2014 14:08:36 +0530 Subject: [PATCH 4969/9457] rtc/tpo: Driver to support rtc and wakeup on PowerNV platform The patch implements the OPAL rtc driver that binds with the rtc driver subsystem. The driver uses the platform device infrastructure to probe the rtc device and register it to rtc class framework. The 'wakeup' is supported depending upon the property 'has-tpo' present in the OF node. It provides a way to load the generic rtc driver in in the absence of an OPAL driver. The patch also moves the existing OPAL rtc get/set time interfaces to the new driver and exposes the necessary OPAL calls using EXPORT_SYMBOL_GPL. Test results: ------------- Host: [root@tul169p1 ~]# ls -l /sys/class/rtc/ total 0 lrwxrwxrwx 1 root root 0 Oct 14 03:07 rtc0 -> ../../devices/opal-rtc/rtc/rtc0 [root@tul169p1 ~]# cat /sys/devices/opal-rtc/rtc/rtc0/time 08:10:07 [root@tul169p1 ~]# echo `date '+%s' -d '+ 2 minutes'` > /sys/class/rtc/rtc0/wakealarm [root@tul169p1 ~]# cat /sys/class/rtc/rtc0/wakealarm 1413274345 [root@tul169p1 ~]# FSP: $ smgr mfgState standby $ rtim timeofday System time is valid: 2014/10/14 08:12:04.225115 $ smgr mfgState ipling $ CC: devicetree@vger.kernel.org CC: tglx@linutronix.de CC: rtc-linux@googlegroups.com CC: a.zummo@towertech.it Signed-off-by: Neelesh Gupta Signed-off-by: Michael Ellerman --- .../devicetree/bindings/rtc/rtc-opal.txt | 16 ++ arch/powerpc/include/asm/opal.h | 7 +- arch/powerpc/kernel/time.c | 1 + arch/powerpc/platforms/powernv/opal-async.c | 3 + arch/powerpc/platforms/powernv/opal-rtc.c | 65 ++--- .../powerpc/platforms/powernv/opal-wrappers.S | 2 + arch/powerpc/platforms/powernv/opal.c | 6 + arch/powerpc/platforms/powernv/setup.c | 2 - drivers/rtc/Kconfig | 11 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-opal.c | 261 ++++++++++++++++++ 11 files changed, 325 insertions(+), 50 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/rtc-opal.txt create mode 100644 drivers/rtc/rtc-opal.c diff --git a/Documentation/devicetree/bindings/rtc/rtc-opal.txt b/Documentation/devicetree/bindings/rtc/rtc-opal.txt new file mode 100644 index 000000000000..af87e5ecac54 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-opal.txt @@ -0,0 +1,16 @@ +IBM OPAL real-time clock +------------------------ + +Required properties: +- comapatible: Should be "ibm,opal-rtc" + +Optional properties: +- has-tpo: Decides if the wakeup is supported or not. + +Example: + rtc { + compatible = "ibm,opal-rtc"; + has-tpo; + phandle = <0x10000029>; + linux,phandle = <0x10000029>; + }; diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 5d073e50cac8..60250e2d1f0d 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -154,6 +154,8 @@ struct opal_sg_list { #define OPAL_HANDLE_HMI 98 #define OPAL_REGISTER_DUMP_REGION 101 #define OPAL_UNREGISTER_DUMP_REGION 102 +#define OPAL_WRITE_TPO 103 +#define OPAL_READ_TPO 104 #define OPAL_IPMI_SEND 107 #define OPAL_IPMI_RECV 108 @@ -832,6 +834,9 @@ int64_t opal_rtc_read(__be32 *year_month_day, __be64 *hour_minute_second_millisecond); int64_t opal_rtc_write(uint32_t year_month_day, uint64_t hour_minute_second_millisecond); +int64_t opal_tpo_read(uint64_t token, __be32 *year_mon_day, __be32 *hour_min); +int64_t opal_tpo_write(uint64_t token, uint32_t year_mon_day, + uint32_t hour_min); int64_t opal_cec_power_down(uint64_t request); int64_t opal_cec_reboot(void); int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); @@ -1009,8 +1014,6 @@ extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); struct rtc_time; -extern int opal_set_rtc_time(struct rtc_time *tm); -extern void opal_get_rtc_time(struct rtc_time *tm); extern unsigned long opal_get_boot_time(void); extern void opal_nvram_init(void); extern void opal_flash_init(void); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 9f8ea617ff2c..fa7c4f12104f 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -989,6 +989,7 @@ void GregorianDay(struct rtc_time * tm) tm->tm_wday = day % 7; } +EXPORT_SYMBOL_GPL(GregorianDay); void to_tm(int tim, struct rtc_time * tm) { diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c index e462ab947d16..693b6cdac691 100644 --- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -71,6 +71,7 @@ int opal_async_get_token_interruptible(void) return token; } +EXPORT_SYMBOL_GPL(opal_async_get_token_interruptible); int __opal_async_release_token(int token) { @@ -102,6 +103,7 @@ int opal_async_release_token(int token) return 0; } +EXPORT_SYMBOL_GPL(opal_async_release_token); int opal_async_wait_response(uint64_t token, struct opal_msg *msg) { @@ -120,6 +122,7 @@ int opal_async_wait_response(uint64_t token, struct opal_msg *msg) return 0; } +EXPORT_SYMBOL_GPL(opal_async_wait_response); static int opal_async_comp_event(struct notifier_block *nb, unsigned long msg_type, void *msg) diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c index 499707ddaa9c..37dbee15769f 100644 --- a/arch/powerpc/platforms/powernv/opal-rtc.c +++ b/arch/powerpc/platforms/powernv/opal-rtc.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -43,7 +45,7 @@ unsigned long __init opal_get_boot_time(void) long rc = OPAL_BUSY; if (!opal_check_token(OPAL_RTC_READ)) - goto out; + return 0; while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); @@ -53,62 +55,33 @@ unsigned long __init opal_get_boot_time(void) mdelay(10); } if (rc != OPAL_SUCCESS) - goto out; + return 0; y_m_d = be32_to_cpu(__y_m_d); h_m_s_ms = be64_to_cpu(__h_m_s_ms); opal_to_tm(y_m_d, h_m_s_ms, &tm); return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); -out: - ppc_md.get_rtc_time = NULL; - ppc_md.set_rtc_time = NULL; - return 0; } -void opal_get_rtc_time(struct rtc_time *tm) +static __init int opal_time_init(void) { - long rc = OPAL_BUSY; - u32 y_m_d; - u64 h_m_s_ms; - __be32 __y_m_d; - __be64 __h_m_s_ms; + struct platform_device *pdev; + struct device_node *rtc; - while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { - rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) - opal_poll_events(NULL); + rtc = of_find_node_by_path("/ibm,opal/rtc"); + if (rtc) { + pdev = of_platform_device_create(rtc, "opal-rtc", NULL); + of_node_put(rtc); + } else { + if (opal_check_token(OPAL_RTC_READ) || + opal_check_token(OPAL_READ_TPO)) + pdev = platform_device_register_simple("opal-rtc", -1, + NULL, 0); else - mdelay(10); + return -ENODEV; } - if (rc != OPAL_SUCCESS) - return; - y_m_d = be32_to_cpu(__y_m_d); - h_m_s_ms = be64_to_cpu(__h_m_s_ms); - opal_to_tm(y_m_d, h_m_s_ms, tm); -} - -int opal_set_rtc_time(struct rtc_time *tm) -{ - long rc = OPAL_BUSY; - u32 y_m_d = 0; - u64 h_m_s_ms = 0; - - y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24; - y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16; - y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8; - y_m_d |= ((u32)bin2bcd(tm->tm_mday)); - - h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56; - h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48; - h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40; - while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { - rc = opal_rtc_write(y_m_d, h_m_s_ms); - if (rc == OPAL_BUSY_EVENT) - opal_poll_events(NULL); - else - mdelay(10); - } - return rc == OPAL_SUCCESS ? 0 : -EIO; + return PTR_ERR_OR_ZERO(pdev); } +machine_subsys_initcall(powernv, opal_time_init); diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 59978af9babe..0a299be588af 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -250,5 +250,7 @@ OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE); +OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO); +OPAL_CALL(opal_tpo_read, OPAL_READ_TPO); OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 0297702e8ae9..a1c37f9d60d2 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -819,3 +819,9 @@ void opal_free_sg_list(struct opal_sg_list *sg) sg = NULL; } } + +EXPORT_SYMBOL_GPL(opal_poll_events); +EXPORT_SYMBOL_GPL(opal_rtc_read); +EXPORT_SYMBOL_GPL(opal_rtc_write); +EXPORT_SYMBOL_GPL(opal_tpo_read); +EXPORT_SYMBOL_GPL(opal_tpo_write); diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 941831d67cb2..30b1c3e298a6 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -265,8 +265,6 @@ static unsigned long pnv_memory_block_size(void) static void __init pnv_setup_machdep_opal(void) { ppc_md.get_boot_time = opal_get_boot_time; - ppc_md.get_rtc_time = opal_get_rtc_time; - ppc_md.set_rtc_time = opal_set_rtc_time; ppc_md.restart = pnv_restart; pm_power_off = pnv_power_off; ppc_md.halt = pnv_halt; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6dd12ddbabc6..c8f0ec7464ce 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -979,6 +979,17 @@ config RTC_DRV_NUC900 If you say yes here you get support for the RTC subsystem of the NUC910/NUC920 used in embedded systems. +config RTC_DRV_OPAL + tristate "IBM OPAL RTC driver" + depends on PPC_POWERNV + default y + help + If you say yes here you get support for the PowerNV platform RTC + driver based on OPAL interfaces. + + This driver can also be built as a module. If so, the module + will be called rtc-opal. + comment "on-CPU RTC drivers" config RTC_DRV_DAVINCI diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b188323c096a..c8ef3e1e6ccd 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -92,6 +92,7 @@ obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o +obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c new file mode 100644 index 000000000000..95f652165fe9 --- /dev/null +++ b/drivers/rtc/rtc-opal.c @@ -0,0 +1,261 @@ +/* + * IBM OPAL RTC driver + * Copyright (C) 2014 IBM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. + */ + +#define DRVNAME "rtc-opal" +#define pr_fmt(fmt) DRVNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm) +{ + tm->tm_year = ((bcd2bin(y_m_d >> 24) * 100) + + bcd2bin((y_m_d >> 16) & 0xff)) - 1900; + tm->tm_mon = bcd2bin((y_m_d >> 8) & 0xff) - 1; + tm->tm_mday = bcd2bin(y_m_d & 0xff); + tm->tm_hour = bcd2bin((h_m_s_ms >> 56) & 0xff); + tm->tm_min = bcd2bin((h_m_s_ms >> 48) & 0xff); + tm->tm_sec = bcd2bin((h_m_s_ms >> 40) & 0xff); + + GregorianDay(tm); +} + +static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) +{ + *y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24; + *y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16; + *y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8; + *y_m_d |= ((u32)bin2bcd(tm->tm_mday)); + + *h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56; + *h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48; + *h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40; +} + +static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) +{ + long rc = OPAL_BUSY; + u32 y_m_d; + u64 h_m_s_ms; + __be32 __y_m_d; + __be64 __h_m_s_ms; + + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { + rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); + if (rc == OPAL_BUSY_EVENT) + opal_poll_events(NULL); + else + msleep(10); + } + + if (rc != OPAL_SUCCESS) + return -EIO; + + y_m_d = be32_to_cpu(__y_m_d); + h_m_s_ms = be64_to_cpu(__h_m_s_ms); + opal_to_tm(y_m_d, h_m_s_ms, tm); + + return 0; +} + +static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm) +{ + long rc = OPAL_BUSY; + u32 y_m_d = 0; + u64 h_m_s_ms = 0; + + tm_to_opal(tm, &y_m_d, &h_m_s_ms); + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { + rc = opal_rtc_write(y_m_d, h_m_s_ms); + if (rc == OPAL_BUSY_EVENT) + opal_poll_events(NULL); + else + msleep(10); + } + + return rc == OPAL_SUCCESS ? 0 : -EIO; +} + +/* + * TPO Timed Power-On + * + * TPO get/set OPAL calls care about the hour and min and to make it consistent + * with the rtc utility time conversion functions, we use the 'u64' to store + * its value and perform bit shift by 32 before use.. + */ +static int opal_get_tpo_time(struct device *dev, struct rtc_wkalrm *alarm) +{ + __be32 __y_m_d, __h_m; + struct opal_msg msg; + int rc, token; + u64 h_m_s_ms; + u32 y_m_d; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + if (token != -ERESTARTSYS) + pr_err("Failed to get the async token\n"); + + return token; + } + + rc = opal_tpo_read(token, &__y_m_d, &__h_m); + if (rc != OPAL_ASYNC_COMPLETION) { + rc = -EIO; + goto exit; + } + + rc = opal_async_wait_response(token, &msg); + if (rc) { + rc = -EIO; + goto exit; + } + + rc = be64_to_cpu(msg.params[1]); + if (rc != OPAL_SUCCESS) { + rc = -EIO; + goto exit; + } + + y_m_d = be32_to_cpu(__y_m_d); + h_m_s_ms = ((u64)be32_to_cpu(__h_m) << 32); + opal_to_tm(y_m_d, h_m_s_ms, &alarm->time); + +exit: + opal_async_release_token(token); + return rc; +} + +/* Set Timed Power-On */ +static int opal_set_tpo_time(struct device *dev, struct rtc_wkalrm *alarm) +{ + u64 h_m_s_ms = 0, token; + struct opal_msg msg; + u32 y_m_d = 0; + int rc; + + tm_to_opal(&alarm->time, &y_m_d, &h_m_s_ms); + + token = opal_async_get_token_interruptible(); + if (token < 0) { + if (token != -ERESTARTSYS) + pr_err("Failed to get the async token\n"); + + return token; + } + + /* TPO, we care about hour and minute */ + rc = opal_tpo_write(token, y_m_d, + (u32)((h_m_s_ms >> 32) & 0xffff0000)); + if (rc != OPAL_ASYNC_COMPLETION) { + rc = -EIO; + goto exit; + } + + rc = opal_async_wait_response(token, &msg); + if (rc) { + rc = -EIO; + goto exit; + } + + rc = be64_to_cpu(msg.params[1]); + if (rc != OPAL_SUCCESS) + rc = -EIO; + +exit: + opal_async_release_token(token); + return rc; +} + +static const struct rtc_class_ops opal_rtc_ops = { + .read_time = opal_get_rtc_time, + .set_time = opal_set_rtc_time, + .read_alarm = opal_get_tpo_time, + .set_alarm = opal_set_tpo_time, +}; + +static int opal_rtc_probe(struct platform_device *pdev) +{ + struct rtc_device *rtc; + + if (pdev->dev.of_node && of_get_property(pdev->dev.of_node, "has-tpo", + NULL)) + device_set_wakeup_capable(&pdev->dev, true); + + rtc = devm_rtc_device_register(&pdev->dev, DRVNAME, &opal_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + rtc->uie_unsupported = 1; + + return 0; +} + +static const struct of_device_id opal_rtc_match[] = { + { + .compatible = "ibm,opal-rtc", + }, + { } +}; +MODULE_DEVICE_TABLE(of, opal_rtc_match); + +static const struct platform_device_id opal_rtc_driver_ids[] = { + { + .name = "opal-rtc", + }, + { } +}; +MODULE_DEVICE_TABLE(platform, opal_rtc_driver_ids); + +static struct platform_driver opal_rtc_driver = { + .probe = opal_rtc_probe, + .id_table = opal_rtc_driver_ids, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + .of_match_table = opal_rtc_match, + }, +}; + +static int __init opal_rtc_init(void) +{ + if (!firmware_has_feature(FW_FEATURE_OPAL)) + return -ENODEV; + + return platform_driver_register(&opal_rtc_driver); +} + +static void __exit opal_rtc_exit(void) +{ + platform_driver_unregister(&opal_rtc_driver); +} + +MODULE_AUTHOR("Neelesh Gupta "); +MODULE_DESCRIPTION("IBM OPAL RTC driver"); +MODULE_LICENSE("GPL"); + +module_init(opal_rtc_init); +module_exit(opal_rtc_exit); -- GitLab From afd6275dd12381a7bd3750c125b3b68b5f8b03ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 30 Oct 2014 19:43:03 +0200 Subject: [PATCH 4970/9457] drm/i915: Reinit display irqs and hpd from chv pipe-a power well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On chv the pipe-a power well is the new disp2d well, and it kills pretty much everything in the display block. So we need to do the the same dance that vlv does wrt. display irqs and hpd when the power well goes up or down. Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index dcbecffc6b5f..f5a78d53e297 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -577,6 +577,23 @@ static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, power_well->data != PIPE_C); chv_set_pipe_power_well(dev_priv, power_well, true); + + if (power_well->data == PIPE_A) { + spin_lock_irq(&dev_priv->irq_lock); + valleyview_enable_display_irqs(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + + /* + * During driver initialization/resume we can avoid restoring the + * part of the HW/SW state that will be inited anyway explicitly. + */ + if (dev_priv->power_domains.initializing) + return; + + intel_hpd_init(dev_priv); + + i915_redisable_vga_power_on(dev_priv->dev); + } } static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, @@ -586,6 +603,12 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, power_well->data != PIPE_B && power_well->data != PIPE_C); + if (power_well->data == PIPE_A) { + spin_lock_irq(&dev_priv->irq_lock); + valleyview_disable_display_irqs(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + } + chv_set_pipe_power_well(dev_priv, power_well, false); if (power_well->data == PIPE_A) -- GitLab From cee42392f5f0482d5cc71635a9c57b4ccdadb886 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Thu, 6 Nov 2014 11:39:47 +0000 Subject: [PATCH 4971/9457] dmaengine: pl330: Correct device assignment. Commit f6f2421c0a1c removed pl330_info structure by embedding it into pl330_dmac structure, but did not ensure that the dmac->ddma.dev pointer gets initialised before use. When dma_alloc_coherent() gets called on arm64 a WARN() gets triggered due to dev being NULL. ------------[ cut here ]------------ WARNING: CPU: 1 PID: 1 at arch/arm64/mm/dma-mapping.c:49 __dma_alloc_coherent+0xd0/0xe0() Use an actual device structure for DMA allocation Modules linked in: CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.17.0+ #5 Call trace: [] dump_backtrace+0x0/0x130 [] show_stack+0x10/0x1c [] dump_stack+0x74/0xb8 [] warn_slowpath_common+0x8c/0xb4 [] warn_slowpath_fmt+0x4c/0x58 [] __dma_alloc_coherent+0xcc/0xe0 [] __dma_alloc_noncoherent+0x64/0x158 [] pl330_probe+0x650/0x8f0 [] amba_probe+0xa0/0xc8 [] really_probe+0xc4/0x22c [] __driver_attach+0xa0/0xa8 [] bus_for_each_dev+0x54/0x98 [] driver_attach+0x1c/0x28 [] bus_add_driver+0x14c/0x204 [] driver_register+0x64/0x130 [] amba_driver_register+0x50/0x5c [] pl330_driver_init+0x10/0x1c [] do_one_initcall+0x88/0x19c [] kernel_init_freeable+0x140/0x1e0 [] kernel_init+0x10/0xd4 ---[ end trace 76f2d47a444e523e ]--- (NULL device *): dmac_alloc_resources:1821 Can't allocate memory! (NULL device *): Unable to create channels for DMAC This patch will also ensure that any dev_err messages are printed with the appropriate device name. Signed-off-by: Liviu Dudau Signed-off-by: Andrew Jackson Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 4839bfa74a10..83e2257c324a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2610,6 +2610,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) return -ENOMEM; } + pd = &pl330->ddma; + pd->dev = &adev->dev; + pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; res = &adev->res; @@ -2646,7 +2649,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) if (!add_desc(pl330, GFP_KERNEL, NR_DEFAULT_DESC)) dev_warn(&adev->dev, "unable to allocate desc\n"); - pd = &pl330->ddma; INIT_LIST_HEAD(&pd->channels); /* Initialize channel parameters */ @@ -2683,7 +2685,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) list_add_tail(&pch->chan.device_node, &pd->channels); } - pd->dev = &adev->dev; if (pdat) { pd->cap_mask = pdat->cap_mask; } else { -- GitLab From 19bfc7726506b48620106b0bb4d32eb37cbcb355 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 6 Nov 2014 10:10:09 +0900 Subject: [PATCH 4972/9457] dma: imx-sdma: remove incorrect __init annotation from sdma_init() When platform_driver_probe() is not used, sdma_probe() can be called by bind/unbind via sysfs. In addition, sdma_init() can be called by sdma_probe(). Thus, __init annotation should be removed from sdma_init(), Also, this patch fixes section mismatch warning. WARNING: drivers/dma/built-in.o(.text+0xd6e4): Section mismatch in reference from the function sdma_probe() to the function .init.text:sdma_init() The function sdma_probe() references the function __init sdma_init(). This is often because sdma_probe lacks a __init annotation or the annotation of sdma_init is wrong. Signed-off-by: Jingoo Han Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 88afc48c2ca7..99d8833edbd6 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1346,7 +1346,7 @@ static int sdma_get_firmware(struct sdma_engine *sdma, return ret; } -static int __init sdma_init(struct sdma_engine *sdma) +static int sdma_init(struct sdma_engine *sdma) { int i, ret; dma_addr_t ccb_phys; -- GitLab From 25a37c2f12351ada1e42d0663480a182f4e301db Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 7 Nov 2014 12:15:46 +0800 Subject: [PATCH 4973/9457] dmaengine: sun6i: support parameterized compatible strings This patch adds support for hardware parameters tied to compatible strings, so similar hardware can reuse the driver. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Vinod Koul --- drivers/dma/sun6i-dma.c | 94 ++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index a00157afc5b8..531abbf68a9d 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,24 +26,6 @@ #include "virt-dma.h" -/* - * There's 16 physical channels that can work in parallel. - * - * However we have 30 different endpoints for our requests. - * - * Since the channels are able to handle only an unidirectional - * transfer, we need to allocate more virtual channels so that - * everyone can grab one channel. - * - * Some devices can't work in both direction (mostly because it - * wouldn't make sense), so we have a bit fewer virtual channels than - * 2 channels per endpoints. - */ - -#define NR_MAX_CHANNELS 16 -#define NR_MAX_REQUESTS 30 -#define NR_MAX_VCHANS 53 - /* * Common registers */ @@ -101,6 +84,19 @@ #define NORMAL_WAIT 8 #define DRQ_SDRAM 1 +/* + * Hardware channels / ports representation + * + * The hardware is used in several SoCs, with differing numbers + * of channels and endpoints. This structure ties those numbers + * to a certain compatible string. + */ +struct sun6i_dma_config { + u32 nr_max_channels; + u32 nr_max_requests; + u32 nr_max_vchans; +}; + /* * Hardware representation of the LLI * @@ -159,6 +155,7 @@ struct sun6i_dma_dev { struct dma_pool *pool; struct sun6i_pchan *pchans; struct sun6i_vchan *vchans; + const struct sun6i_dma_config *cfg; }; static struct device *chan2dev(struct dma_chan *chan) @@ -432,6 +429,7 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan) static void sun6i_dma_tasklet(unsigned long data) { struct sun6i_dma_dev *sdev = (struct sun6i_dma_dev *)data; + const struct sun6i_dma_config *cfg = sdev->cfg; struct sun6i_vchan *vchan; struct sun6i_pchan *pchan; unsigned int pchan_alloc = 0; @@ -459,7 +457,7 @@ static void sun6i_dma_tasklet(unsigned long data) } spin_lock_irq(&sdev->lock); - for (pchan_idx = 0; pchan_idx < NR_MAX_CHANNELS; pchan_idx++) { + for (pchan_idx = 0; pchan_idx < cfg->nr_max_channels; pchan_idx++) { pchan = &sdev->pchans[pchan_idx]; if (pchan->vchan || list_empty(&sdev->pending)) @@ -480,7 +478,7 @@ static void sun6i_dma_tasklet(unsigned long data) } spin_unlock_irq(&sdev->lock); - for (pchan_idx = 0; pchan_idx < NR_MAX_CHANNELS; pchan_idx++) { + for (pchan_idx = 0; pchan_idx < cfg->nr_max_channels; pchan_idx++) { if (!(pchan_alloc & BIT(pchan_idx))) continue; @@ -502,7 +500,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id) int i, j, ret = IRQ_NONE; u32 status; - for (i = 0; i < 2; i++) { + for (i = 0; i < sdev->cfg->nr_max_channels / DMA_IRQ_CHAN_NR; i++) { status = readl(sdev->base + DMA_IRQ_STAT(i)); if (!status) continue; @@ -512,7 +510,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id) writel(status, sdev->base + DMA_IRQ_STAT(i)); - for (j = 0; (j < 8) && status; j++) { + for (j = 0; (j < DMA_IRQ_CHAN_NR) && status; j++) { if (status & DMA_IRQ_QUEUE) { pchan = sdev->pchans + j; vchan = pchan->vchan; @@ -525,7 +523,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id) } } - status = status >> 4; + status = status >> DMA_IRQ_CHAN_WIDTH; } if (!atomic_read(&sdev->tasklet_shutdown)) @@ -817,7 +815,7 @@ static struct dma_chan *sun6i_dma_of_xlate(struct of_phandle_args *dma_spec, struct dma_chan *chan; u8 port = dma_spec->args[0]; - if (port > NR_MAX_REQUESTS) + if (port > sdev->cfg->nr_max_requests) return NULL; chan = dma_get_any_slave_channel(&sdev->slave); @@ -850,7 +848,7 @@ static inline void sun6i_dma_free(struct sun6i_dma_dev *sdev) { int i; - for (i = 0; i < NR_MAX_VCHANS; i++) { + for (i = 0; i < sdev->cfg->nr_max_vchans; i++) { struct sun6i_vchan *vchan = &sdev->vchans[i]; list_del(&vchan->vc.chan.device_node); @@ -858,8 +856,36 @@ static inline void sun6i_dma_free(struct sun6i_dma_dev *sdev) } } +/* + * For A31: + * + * There's 16 physical channels that can work in parallel. + * + * However we have 30 different endpoints for our requests. + * + * Since the channels are able to handle only an unidirectional + * transfer, we need to allocate more virtual channels so that + * everyone can grab one channel. + * + * Some devices can't work in both direction (mostly because it + * wouldn't make sense), so we have a bit fewer virtual channels than + * 2 channels per endpoints. + */ + +static struct sun6i_dma_config sun6i_a31_dma_cfg = { + .nr_max_channels = 16, + .nr_max_requests = 30, + .nr_max_vchans = 53, +}; + +static struct of_device_id sun6i_dma_match[] = { + { .compatible = "allwinner,sun6i-a31-dma", .data = &sun6i_a31_dma_cfg }, + { /* sentinel */ } +}; + static int sun6i_dma_probe(struct platform_device *pdev) { + const struct of_device_id *device; struct sun6i_dma_dev *sdc; struct resource *res; int ret, i; @@ -868,6 +894,11 @@ static int sun6i_dma_probe(struct platform_device *pdev) if (!sdc) return -ENOMEM; + device = of_match_device(sun6i_dma_match, &pdev->dev); + if (!device) + return -ENODEV; + sdc->cfg = device->data; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sdc->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(sdc->base)) @@ -917,26 +948,26 @@ static int sun6i_dma_probe(struct platform_device *pdev) sdc->slave.dev = &pdev->dev; - sdc->pchans = devm_kcalloc(&pdev->dev, NR_MAX_CHANNELS, + sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels, sizeof(struct sun6i_pchan), GFP_KERNEL); if (!sdc->pchans) return -ENOMEM; - sdc->vchans = devm_kcalloc(&pdev->dev, NR_MAX_VCHANS, + sdc->vchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_vchans, sizeof(struct sun6i_vchan), GFP_KERNEL); if (!sdc->vchans) return -ENOMEM; tasklet_init(&sdc->task, sun6i_dma_tasklet, (unsigned long)sdc); - for (i = 0; i < NR_MAX_CHANNELS; i++) { + for (i = 0; i < sdc->cfg->nr_max_channels; i++) { struct sun6i_pchan *pchan = &sdc->pchans[i]; pchan->idx = i; pchan->base = sdc->base + 0x100 + i * 0x40; } - for (i = 0; i < NR_MAX_VCHANS; i++) { + for (i = 0; i < sdc->cfg->nr_max_vchans; i++) { struct sun6i_vchan *vchan = &sdc->vchans[i]; INIT_LIST_HEAD(&vchan->node); @@ -1008,11 +1039,6 @@ static int sun6i_dma_remove(struct platform_device *pdev) return 0; } -static struct of_device_id sun6i_dma_match[] = { - { .compatible = "allwinner,sun6i-a31-dma" }, - { /* sentinel */ } -}; - static struct platform_driver sun6i_dma_driver = { .probe = sun6i_dma_probe, .remove = sun6i_dma_remove, -- GitLab From 0b04ddf8638ca5652b1f7ab7794beb363942407d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 7 Nov 2014 12:15:47 +0800 Subject: [PATCH 4974/9457] dmaengine: sun6i: Add support for Allwinner A23 (sun8i) variant The A23 SoC has the same dma engine as the A31 (sun6i), with a reduced amount of endpoints and physical channels. Add the proper config data and compatible string to support it. A slight difference in sun8i is an undocumented register needs to be toggled for dma to function. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Vinod Koul --- .../devicetree/bindings/dma/sun6i-dma.txt | 2 +- drivers/dma/Kconfig | 4 +-- drivers/dma/sun6i-dma.c | 27 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt index 3e145c1675b1..9cdcba24d7c3 100644 --- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt +++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt @@ -4,7 +4,7 @@ This driver follows the generic DMA bindings defined in dma.txt. Required properties: -- compatible: Must be "allwinner,sun6i-a31-dma" +- compatible: Must be "allwinner,sun6i-a31-dma" or "allwinner,sun8i-a23-dma" - reg: Should contain the registers base address and length - interrupts: Should contain a reference to the interrupt used by this device - clocks: Should contain a reference to the parent AHB clock diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 607271a999a9..aef8b9dd4db6 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -402,12 +402,12 @@ config XILINX_VDMA config DMA_SUN6I tristate "Allwinner A31 SoCs DMA support" - depends on MACH_SUN6I || COMPILE_TEST + depends on MACH_SUN6I || MACH_SUN8I || COMPILE_TEST depends on RESET_CONTROLLER select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help - Support for the DMA engine for Allwinner A31 SoCs. + Support for the DMA engine first found in Allwinner A31 SoCs. config NBPFAXI_DMA tristate "Renesas Type-AXI NBPF DMA support" diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 531abbf68a9d..f9f8f4d9915f 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -42,6 +42,12 @@ #define DMA_STAT 0x30 +/* + * sun8i specific registers + */ +#define SUN8I_DMA_GATE 0x20 +#define SUN8I_DMA_GATE_ENABLE 0x4 + /* * Channels specific registers */ @@ -878,8 +884,20 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { .nr_max_vchans = 53, }; +/* + * The A23 only has 8 physical channels, a maximum DRQ port id of 24, + * and a total of 37 usable source and destination endpoints. + */ + +static struct sun6i_dma_config sun8i_a23_dma_cfg = { + .nr_max_channels = 8, + .nr_max_requests = 24, + .nr_max_vchans = 37, +}; + static struct of_device_id sun6i_dma_match[] = { { .compatible = "allwinner,sun6i-a31-dma", .data = &sun6i_a31_dma_cfg }, + { .compatible = "allwinner,sun8i-a23-dma", .data = &sun8i_a23_dma_cfg }, { /* sentinel */ } }; @@ -1007,6 +1025,15 @@ static int sun6i_dma_probe(struct platform_device *pdev) goto err_dma_unregister; } + /* + * sun8i variant requires us to toggle a dma gating register, + * as seen in Allwinner's SDK. This register is not documented + * in the A23 user manual. + */ + if (of_device_is_compatible(pdev->dev.of_node, + "allwinner,sun8i-a23-dma")) + writel(SUN8I_DMA_GATE_ENABLE, sdc->base + SUN8I_DMA_GATE); + return 0; err_dma_unregister: -- GitLab From fb93f520e0a5df581f5432bdb901539240391568 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 29 Sep 2014 10:03:07 +0530 Subject: [PATCH 4975/9457] dmaengine: qcom_bam_dma: Generalize BAM register offset calculations The BAM DMA IP comes in different versions. The register offset layout varies among these versions. The layouts depend on which generation/family of SoCs they belong to. The current SoCs(like 8084, 8074) have a layout where the Top level registers come in the beginning of the address range, followed by pipe and event registers. The BAM revision numbers fall above 1.4.0. The older SoCs (like 8064, 8960) have a layout where the pipe registers come first, and the top level come later. These have BAM revision numbers lesser than 1.4.0. It isn't suitable to have macros provide the register offsets with the layouts changed. Future BAM revisions may have different register layouts too. The register addresses are now calculated by referring a table which contains a base offset and multipliers for pipe/evnt/ee registers. We have a common function bam_addr() which computes addresses for all the registers. When computing address of top level/ee registers, we pass 0 to the pipe argument in addr() since they don't have any multiple instances. Some of the unused register definitions are removed. We can add new registers as we need them. Reviewed-by: Kumar Gala Reviewed-by: Andy Gross Signed-off-by: Archit Taneja Signed-off-by: Vinod Koul --- drivers/dma/qcom_bam_dma.c | 176 ++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 63 deletions(-) diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index 9d7b5542397c..d8fb4303bade 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c @@ -79,35 +79,68 @@ struct bam_async_desc { struct bam_desc_hw desc[0]; }; -#define BAM_CTRL 0x0000 -#define BAM_REVISION 0x0004 -#define BAM_SW_REVISION 0x0080 -#define BAM_NUM_PIPES 0x003C -#define BAM_TIMER 0x0040 -#define BAM_TIMER_CTRL 0x0044 -#define BAM_DESC_CNT_TRSHLD 0x0008 -#define BAM_IRQ_SRCS 0x000C -#define BAM_IRQ_SRCS_MSK 0x0010 -#define BAM_IRQ_SRCS_UNMASKED 0x0030 -#define BAM_IRQ_STTS 0x0014 -#define BAM_IRQ_CLR 0x0018 -#define BAM_IRQ_EN 0x001C -#define BAM_CNFG_BITS 0x007C -#define BAM_IRQ_SRCS_EE(ee) (0x0800 + ((ee) * 0x80)) -#define BAM_IRQ_SRCS_MSK_EE(ee) (0x0804 + ((ee) * 0x80)) -#define BAM_P_CTRL(pipe) (0x1000 + ((pipe) * 0x1000)) -#define BAM_P_RST(pipe) (0x1004 + ((pipe) * 0x1000)) -#define BAM_P_HALT(pipe) (0x1008 + ((pipe) * 0x1000)) -#define BAM_P_IRQ_STTS(pipe) (0x1010 + ((pipe) * 0x1000)) -#define BAM_P_IRQ_CLR(pipe) (0x1014 + ((pipe) * 0x1000)) -#define BAM_P_IRQ_EN(pipe) (0x1018 + ((pipe) * 0x1000)) -#define BAM_P_EVNT_DEST_ADDR(pipe) (0x182C + ((pipe) * 0x1000)) -#define BAM_P_EVNT_REG(pipe) (0x1818 + ((pipe) * 0x1000)) -#define BAM_P_SW_OFSTS(pipe) (0x1800 + ((pipe) * 0x1000)) -#define BAM_P_DATA_FIFO_ADDR(pipe) (0x1824 + ((pipe) * 0x1000)) -#define BAM_P_DESC_FIFO_ADDR(pipe) (0x181C + ((pipe) * 0x1000)) -#define BAM_P_EVNT_TRSHLD(pipe) (0x1828 + ((pipe) * 0x1000)) -#define BAM_P_FIFO_SIZES(pipe) (0x1820 + ((pipe) * 0x1000)) +enum bam_reg { + BAM_CTRL, + BAM_REVISION, + BAM_NUM_PIPES, + BAM_DESC_CNT_TRSHLD, + BAM_IRQ_SRCS, + BAM_IRQ_SRCS_MSK, + BAM_IRQ_SRCS_UNMASKED, + BAM_IRQ_STTS, + BAM_IRQ_CLR, + BAM_IRQ_EN, + BAM_CNFG_BITS, + BAM_IRQ_SRCS_EE, + BAM_IRQ_SRCS_MSK_EE, + BAM_P_CTRL, + BAM_P_RST, + BAM_P_HALT, + BAM_P_IRQ_STTS, + BAM_P_IRQ_CLR, + BAM_P_IRQ_EN, + BAM_P_EVNT_DEST_ADDR, + BAM_P_EVNT_REG, + BAM_P_SW_OFSTS, + BAM_P_DATA_FIFO_ADDR, + BAM_P_DESC_FIFO_ADDR, + BAM_P_EVNT_GEN_TRSHLD, + BAM_P_FIFO_SIZES, +}; + +struct reg_offset_data { + u32 base_offset; + unsigned int pipe_mult, evnt_mult, ee_mult; +}; + +static const struct reg_offset_data reg_info[] = { + [BAM_CTRL] = { 0x0000, 0x00, 0x00, 0x00 }, + [BAM_REVISION] = { 0x0004, 0x00, 0x00, 0x00 }, + [BAM_NUM_PIPES] = { 0x003C, 0x00, 0x00, 0x00 }, + [BAM_DESC_CNT_TRSHLD] = { 0x0008, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS] = { 0x000C, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_MSK] = { 0x0010, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_UNMASKED] = { 0x0030, 0x00, 0x00, 0x00 }, + [BAM_IRQ_STTS] = { 0x0014, 0x00, 0x00, 0x00 }, + [BAM_IRQ_CLR] = { 0x0018, 0x00, 0x00, 0x00 }, + [BAM_IRQ_EN] = { 0x001C, 0x00, 0x00, 0x00 }, + [BAM_CNFG_BITS] = { 0x007C, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_EE] = { 0x0800, 0x00, 0x00, 0x80 }, + [BAM_IRQ_SRCS_MSK_EE] = { 0x0804, 0x00, 0x00, 0x80 }, + [BAM_P_CTRL] = { 0x1000, 0x1000, 0x00, 0x00 }, + [BAM_P_RST] = { 0x1004, 0x1000, 0x00, 0x00 }, + [BAM_P_HALT] = { 0x1008, 0x1000, 0x00, 0x00 }, + [BAM_P_IRQ_STTS] = { 0x1010, 0x1000, 0x00, 0x00 }, + [BAM_P_IRQ_CLR] = { 0x1014, 0x1000, 0x00, 0x00 }, + [BAM_P_IRQ_EN] = { 0x1018, 0x1000, 0x00, 0x00 }, + [BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x1000, 0x00 }, + [BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x1000, 0x00 }, + [BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x1000, 0x00 }, + [BAM_P_DATA_FIFO_ADDR] = { 0x1824, 0x00, 0x1000, 0x00 }, + [BAM_P_DESC_FIFO_ADDR] = { 0x181C, 0x00, 0x1000, 0x00 }, + [BAM_P_EVNT_GEN_TRSHLD] = { 0x1828, 0x00, 0x1000, 0x00 }, + [BAM_P_FIFO_SIZES] = { 0x1820, 0x00, 0x1000, 0x00 }, +}; /* BAM CTRL */ #define BAM_SW_RST BIT(0) @@ -304,6 +337,23 @@ struct bam_device { struct tasklet_struct task; }; +/** + * bam_addr - returns BAM register address + * @bdev: bam device + * @pipe: pipe instance (ignored when register doesn't have multiple instances) + * @reg: register enum + */ +static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe, + enum bam_reg reg) +{ + const struct reg_offset_data r = reg_info[reg]; + + return bdev->regs + r.base_offset + + r.pipe_mult * pipe + + r.evnt_mult * pipe + + r.ee_mult * bdev->ee; +} + /** * bam_reset_channel - Reset individual BAM DMA channel * @bchan: bam channel @@ -317,8 +367,8 @@ static void bam_reset_channel(struct bam_chan *bchan) lockdep_assert_held(&bchan->vc.lock); /* reset channel */ - writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id)); - writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id)); + writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_RST)); + writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_RST)); /* don't allow cpu to reorder BAM register accesses done after this */ wmb(); @@ -347,17 +397,18 @@ static void bam_chan_init_hw(struct bam_chan *bchan, * because we allocated 1 more descriptor (8 bytes) than we can use */ writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)), - bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id)); - writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs + - BAM_P_FIFO_SIZES(bchan->id)); + bam_addr(bdev, bchan->id, BAM_P_DESC_FIFO_ADDR)); + writel_relaxed(BAM_DESC_FIFO_SIZE, + bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES)); /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */ - writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id)); + writel_relaxed(P_DEFAULT_IRQS_EN, + bam_addr(bdev, bchan->id, BAM_P_IRQ_EN)); /* unmask the specific pipe and EE combo */ - val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + val = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); val |= BIT(bchan->id); - writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + writel_relaxed(val, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); /* don't allow cpu to reorder the channel enable done below */ wmb(); @@ -367,7 +418,7 @@ static void bam_chan_init_hw(struct bam_chan *bchan, if (dir == DMA_DEV_TO_MEM) val |= P_DIRECTION; - writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id)); + writel_relaxed(val, bam_addr(bdev, bchan->id, BAM_P_CTRL)); bchan->initialized = 1; @@ -432,12 +483,12 @@ static void bam_free_chan(struct dma_chan *chan) bchan->fifo_virt = NULL; /* mask irq for pipe/channel */ - val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + val = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); val &= ~BIT(bchan->id); - writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + writel_relaxed(val, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); /* disable irq */ - writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id)); + writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN)); } /** @@ -583,14 +634,14 @@ static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, switch (cmd) { case DMA_PAUSE: spin_lock_irqsave(&bchan->vc.lock, flag); - writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id)); + writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); bchan->paused = 1; spin_unlock_irqrestore(&bchan->vc.lock, flag); break; case DMA_RESUME: spin_lock_irqsave(&bchan->vc.lock, flag); - writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id)); + writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); bchan->paused = 0; spin_unlock_irqrestore(&bchan->vc.lock, flag); break; @@ -626,7 +677,7 @@ static u32 process_channel_irqs(struct bam_device *bdev) unsigned long flags; struct bam_async_desc *async_desc; - srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(bdev->ee)); + srcs = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_EE)); /* return early if no pipe/channel interrupts are present */ if (!(srcs & P_IRQ)) @@ -639,11 +690,9 @@ static u32 process_channel_irqs(struct bam_device *bdev) continue; /* clear pipe irq */ - pipe_stts = readl_relaxed(bdev->regs + - BAM_P_IRQ_STTS(i)); + pipe_stts = readl_relaxed(bam_addr(bdev, i, BAM_P_IRQ_STTS)); - writel_relaxed(pipe_stts, bdev->regs + - BAM_P_IRQ_CLR(i)); + writel_relaxed(pipe_stts, bam_addr(bdev, i, BAM_P_IRQ_CLR)); spin_lock_irqsave(&bchan->vc.lock, flags); async_desc = bchan->curr_txd; @@ -694,12 +743,12 @@ static irqreturn_t bam_dma_irq(int irq, void *data) tasklet_schedule(&bdev->task); if (srcs & BAM_IRQ) - clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS); + clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS)); /* don't allow reorder of the various accesses to the BAM registers */ mb(); - writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR); + writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR)); return IRQ_HANDLED; } @@ -763,7 +812,7 @@ static void bam_apply_new_config(struct bam_chan *bchan, else maxburst = bchan->slave.dst_maxburst; - writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD); + writel_relaxed(maxburst, bam_addr(bdev, 0, BAM_DESC_CNT_TRSHLD)); bchan->reconfigure = 0; } @@ -830,7 +879,7 @@ static void bam_start_dma(struct bam_chan *bchan) /* ensure descriptor writes and dma start not reordered */ wmb(); writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw), - bdev->regs + BAM_P_EVNT_REG(bchan->id)); + bam_addr(bdev, bchan->id, BAM_P_EVNT_REG)); } /** @@ -918,43 +967,44 @@ static int bam_init(struct bam_device *bdev) u32 val; /* read revision and configuration information */ - val = readl_relaxed(bdev->regs + BAM_REVISION) >> NUM_EES_SHIFT; + val = readl_relaxed(bam_addr(bdev, 0, BAM_REVISION)) >> NUM_EES_SHIFT; val &= NUM_EES_MASK; /* check that configured EE is within range */ if (bdev->ee >= val) return -EINVAL; - val = readl_relaxed(bdev->regs + BAM_NUM_PIPES); + val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES)); bdev->num_channels = val & BAM_NUM_PIPES_MASK; /* s/w reset bam */ /* after reset all pipes are disabled and idle */ - val = readl_relaxed(bdev->regs + BAM_CTRL); + val = readl_relaxed(bam_addr(bdev, 0, BAM_CTRL)); val |= BAM_SW_RST; - writel_relaxed(val, bdev->regs + BAM_CTRL); + writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); val &= ~BAM_SW_RST; - writel_relaxed(val, bdev->regs + BAM_CTRL); + writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); /* make sure previous stores are visible before enabling BAM */ wmb(); /* enable bam */ val |= BAM_EN; - writel_relaxed(val, bdev->regs + BAM_CTRL); + writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); /* set descriptor threshhold, start with 4 bytes */ - writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD); + writel_relaxed(DEFAULT_CNT_THRSHLD, + bam_addr(bdev, 0, BAM_DESC_CNT_TRSHLD)); /* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */ - writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS); + writel_relaxed(BAM_CNFG_BITS_DEFAULT, bam_addr(bdev, 0, BAM_CNFG_BITS)); /* enable irqs for errors */ writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN, - bdev->regs + BAM_IRQ_EN); + bam_addr(bdev, 0, BAM_IRQ_EN)); /* unmask global bam interrupt */ - writel_relaxed(BAM_IRQ_MSK, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + writel_relaxed(BAM_IRQ_MSK, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); return 0; } @@ -1084,7 +1134,7 @@ static int bam_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&bdev->common); /* mask all interrupts for this execution environment */ - writel_relaxed(0, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); + writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); devm_free_irq(bdev->dev, bdev->irq, bdev); -- GitLab From f43669dee7c76dbf188ac9702b5bd22afc3e5469 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 29 Sep 2014 10:03:08 +0530 Subject: [PATCH 4976/9457] dmaengine: qcom_bam_dma: Add BAM v1.3.0 support We currently have register offset information only for BAM IPs with revision 1.4.0. We add register offset table entries for the legacy (v1.3.0) version of BAM IPs found on SoCs like APQ8064 and MSM8960. The register offset table pointers are stored in DT data corresponding to the BAM IP version specified in the compatible string. Reviewed-by: Kumar Gala Reviewed-by: Andy Gross Signed-off-by: Archit Taneja Signed-off-by: Vinod Koul --- drivers/dma/qcom_bam_dma.c | 58 ++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index d8fb4303bade..3122a99ec06b 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c @@ -113,7 +113,36 @@ struct reg_offset_data { unsigned int pipe_mult, evnt_mult, ee_mult; }; -static const struct reg_offset_data reg_info[] = { +static const struct reg_offset_data bam_v1_3_reg_info[] = { + [BAM_CTRL] = { 0x0F80, 0x00, 0x00, 0x00 }, + [BAM_REVISION] = { 0x0F84, 0x00, 0x00, 0x00 }, + [BAM_NUM_PIPES] = { 0x0FBC, 0x00, 0x00, 0x00 }, + [BAM_DESC_CNT_TRSHLD] = { 0x0F88, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS] = { 0x0F8C, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_MSK] = { 0x0F90, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_UNMASKED] = { 0x0FB0, 0x00, 0x00, 0x00 }, + [BAM_IRQ_STTS] = { 0x0F94, 0x00, 0x00, 0x00 }, + [BAM_IRQ_CLR] = { 0x0F98, 0x00, 0x00, 0x00 }, + [BAM_IRQ_EN] = { 0x0F9C, 0x00, 0x00, 0x00 }, + [BAM_CNFG_BITS] = { 0x0FFC, 0x00, 0x00, 0x00 }, + [BAM_IRQ_SRCS_EE] = { 0x1800, 0x00, 0x00, 0x80 }, + [BAM_IRQ_SRCS_MSK_EE] = { 0x1804, 0x00, 0x00, 0x80 }, + [BAM_P_CTRL] = { 0x0000, 0x80, 0x00, 0x00 }, + [BAM_P_RST] = { 0x0004, 0x80, 0x00, 0x00 }, + [BAM_P_HALT] = { 0x0008, 0x80, 0x00, 0x00 }, + [BAM_P_IRQ_STTS] = { 0x0010, 0x80, 0x00, 0x00 }, + [BAM_P_IRQ_CLR] = { 0x0014, 0x80, 0x00, 0x00 }, + [BAM_P_IRQ_EN] = { 0x0018, 0x80, 0x00, 0x00 }, + [BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x40, 0x00 }, + [BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x40, 0x00 }, + [BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x40, 0x00 }, + [BAM_P_DATA_FIFO_ADDR] = { 0x1024, 0x00, 0x40, 0x00 }, + [BAM_P_DESC_FIFO_ADDR] = { 0x101C, 0x00, 0x40, 0x00 }, + [BAM_P_EVNT_GEN_TRSHLD] = { 0x1028, 0x00, 0x40, 0x00 }, + [BAM_P_FIFO_SIZES] = { 0x1020, 0x00, 0x40, 0x00 }, +}; + +static const struct reg_offset_data bam_v1_4_reg_info[] = { [BAM_CTRL] = { 0x0000, 0x00, 0x00, 0x00 }, [BAM_REVISION] = { 0x0004, 0x00, 0x00, 0x00 }, [BAM_NUM_PIPES] = { 0x003C, 0x00, 0x00, 0x00 }, @@ -330,6 +359,8 @@ struct bam_device { /* execution environment ID, from DT */ u32 ee; + const struct reg_offset_data *layout; + struct clk *bamclk; int irq; @@ -346,7 +377,7 @@ struct bam_device { static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe, enum bam_reg reg) { - const struct reg_offset_data r = reg_info[reg]; + const struct reg_offset_data r = bdev->layout[reg]; return bdev->regs + r.base_offset + r.pipe_mult * pipe + @@ -1019,9 +1050,18 @@ static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan, bchan->vc.desc_free = bam_dma_free_desc; } +static const struct of_device_id bam_of_match[] = { + { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_reg_info }, + { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_reg_info }, + {} +}; + +MODULE_DEVICE_TABLE(of, bam_of_match); + static int bam_dma_probe(struct platform_device *pdev) { struct bam_device *bdev; + const struct of_device_id *match; struct resource *iores; int ret, i; @@ -1031,6 +1071,14 @@ static int bam_dma_probe(struct platform_device *pdev) bdev->dev = &pdev->dev; + match = of_match_node(bam_of_match, pdev->dev.of_node); + if (!match) { + dev_err(&pdev->dev, "Unsupported BAM module\n"); + return -ENODEV; + } + + bdev->layout = match->data; + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdev->regs = devm_ioremap_resource(&pdev->dev, iores); if (IS_ERR(bdev->regs)) @@ -1154,12 +1202,6 @@ static int bam_dma_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id bam_of_match[] = { - { .compatible = "qcom,bam-v1.4.0", }, - {} -}; -MODULE_DEVICE_TABLE(of, bam_of_match); - static struct platform_driver bam_dma_driver = { .probe = bam_dma_probe, .remove = bam_dma_remove, -- GitLab From ce9406380dea1e462ab609700c9daeb6c8b23766 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 29 Sep 2014 10:03:09 +0530 Subject: [PATCH 4977/9457] dt/bindings: dmaengine: qcom_bam_dma: Add compatible string for BAM v1.3.0 Add compatible string for BAM v1.3.0 in the DT bindings documentation. Mentioned a few more SoCs which have BAM v1.4.0 in them. Reviewed-by: Kumar Gala Reviewed-by: Andy Gross Signed-off-by: Archit Taneja Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/qcom_bam_dma.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt index d75a9d767022..f8c3311b7153 100644 --- a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt +++ b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt @@ -1,7 +1,9 @@ QCOM BAM DMA controller Required properties: -- compatible: must contain "qcom,bam-v1.4.0" for MSM8974 +- compatible: must be one of the following: + * "qcom,bam-v1.4.0" for MSM8974, APQ8074 and APQ8084 + * "qcom,bam-v1.3.0" for APQ8064, IPQ8064 and MSM8960 - reg: Address range for DMA registers - interrupts: Should contain the one interrupt shared by all channels - #dma-cells: must be <1>, the cell in the dmas property of the client device -- GitLab From 26fd830a999be08eb1453d6574b105b74fad65bb Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 9 Oct 2014 11:09:00 +0900 Subject: [PATCH 4978/9457] dmaengine: shdma: fix a race condition in __ld_cleanup() This patch fixes a race condition about a list of shdma-base driver. If we don't apply this patch, a dma slave driver (especially a usb peripheral driver) may not be able to start the transfer. If a dma slave driver has a callback, __ld_cleanup() will call the callback before this driver removes the list. After the callback, since the return value of __ld_cleanup() is not zero, shdma_chan_ld_cleanup() calls __ld_cleanup() again. And, __ld_clean() will removes the list. At this time, if a dma slave driver calls dmaengine_submit() before this driver removes the list, this driver will set schan->pm_state to SHDMA_PM_PENDING in shdma_tx_submit(). And then, even if a dma slave driver calls dma_async_issue_pending(), this driver don't start the transfer because the schan->pm_state is SHDMA_PM_PENDING in shdma_issue_pending(). So, this patch adds a new condition in __ld_clean() to check if the schan->pm_state is SHDMA_PM_PENDING or not. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Vinod Koul --- drivers/dma/sh/shdma-base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index ed5b0993edfa..3a2adb131d46 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c @@ -391,6 +391,8 @@ static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all) dev_dbg(schan->dev, "Bring down channel %d\n", schan->id); pm_runtime_put(schan->dev); schan->pm_state = SHDMA_PM_ESTABLISHED; + } else if (schan->pm_state == SHDMA_PM_PENDING) { + shdma_chan_xfer_ld_queue(schan); } } } -- GitLab From 29aebfde8802b64a5b505a1d8a6842c188abfdbc Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 24 Oct 2014 12:37:41 -0700 Subject: [PATCH 4979/9457] dmaengine: imx-sdma: Add a new DMATYPE for SAI This patch simply adds a new DMATYPE for SAI which's included in i.MX6 Solo X. Signed-off-by: Nicolin Chen Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + drivers/dma/imx-sdma.c | 1 + include/linux/platform_data/dma-imx.h | 1 + 3 files changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt index 4659fd952301..dc8d3aac1aa9 100644 --- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt @@ -48,6 +48,7 @@ The full ID of peripheral types can be found below. 21 ESAI 22 SSI Dual FIFO (needs firmware ver >= 2) 23 Shared ASRC + 24 SAI The third cell specifies the transfer priority as below. diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 99d8833edbd6..5b38f2bbd42a 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -729,6 +729,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, case IMX_DMATYPE_CSPI: case IMX_DMATYPE_EXT: case IMX_DMATYPE_SSI: + case IMX_DMATYPE_SAI: per_2_emi = sdma->script_addrs->app_2_mcu_addr; emi_2_per = sdma->script_addrs->mcu_2_app_addr; break; diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h index 6a1357d31871..7d964e787299 100644 --- a/include/linux/platform_data/dma-imx.h +++ b/include/linux/platform_data/dma-imx.h @@ -41,6 +41,7 @@ enum sdma_peripheral_type { IMX_DMATYPE_ESAI, /* ESAI */ IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */ IMX_DMATYPE_ASRC_SP, /* Shared ASRC */ + IMX_DMATYPE_SAI, /* SAI */ }; enum imx_dma_prio { -- GitLab From 33339684de46070d34e1dc11b590971b20a3d25b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 27 Oct 2014 21:35:13 +0900 Subject: [PATCH 4980/9457] dmaengine: sirf: Add CONFIG_PM_SLEEP to suspend/resume functions Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. This is because sleep PM callbacks defined by SET_SYSTEM_SLEEP_PM_OPS are only used when the CONFIG_PM_SLEEP is enabled. drivers/dma/sirf-dma.c:838:12: warning: 'sirfsoc_dma_pm_suspend' defined but not used [-Wunused-function] drivers/dma/sirf-dma.c:879:12: warning: 'sirfsoc_dma_pm_resume' defined but not used [-Wunused-function] Signed-off-by: Jingoo Han Signed-off-by: Vinod Koul --- drivers/dma/sirf-dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index fbe291584e8a..feb1e8ab8d7b 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -834,6 +834,7 @@ static int sirfsoc_dma_runtime_resume(struct device *dev) return 0; } +#ifdef CONFIG_PM_SLEEP static int sirfsoc_dma_pm_suspend(struct device *dev) { struct sirfsoc_dma *sdma = dev_get_drvdata(dev); @@ -915,6 +916,7 @@ static int sirfsoc_dma_pm_resume(struct device *dev) return 0; } +#endif static const struct dev_pm_ops sirfsoc_dma_pm_ops = { SET_RUNTIME_PM_OPS(sirfsoc_dma_runtime_suspend, sirfsoc_dma_runtime_resume, NULL) -- GitLab From af2d3139e19fd7da9a5d300a83812616b2d6694c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 27 Oct 2014 21:36:26 +0900 Subject: [PATCH 4981/9457] dmaengine: k3dma: Add CONFIG_PM_SLEEP to suspend/resume functions Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following build warning when CONFIG_PM_SLEEP is not selected. This is because sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when the CONFIG_PM_SLEEP is enabled. drivers/dma/k3dma.c:790:12: warning: 'k3_dma_suspend' defined but not used [-Wunused-function] drivers/dma/k3dma.c:806:12: warning: 'k3_dma_resume' defined but not used [-Wunused-function] Signed-off-by: Jingoo Han Acked-by: Zhangfei Gao Signed-off-by: Vinod Koul --- drivers/dma/k3dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index bd8e5f1e826f..a1de14ab2c51 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -786,6 +786,7 @@ static int k3_dma_remove(struct platform_device *op) return 0; } +#ifdef CONFIG_PM_SLEEP static int k3_dma_suspend(struct device *dev) { struct k3_dma_dev *d = dev_get_drvdata(dev); @@ -815,6 +816,7 @@ static int k3_dma_resume(struct device *dev) k3_dma_enable_dma(d, true); return 0; } +#endif static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume); -- GitLab From 5ac7d58280236ee4fa45202b82deabdfb4532f7a Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Thu, 6 Nov 2014 17:28:08 +0800 Subject: [PATCH 4982/9457] dmaengine: at_xdmac: fix semicolon.cocci warnings drivers/dma/at_xdmac.c:702:3-4: Unneeded semicolon Removes unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Signed-off-by: Fengguang Wu Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 4e9b023990ae..155577b98309 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -699,7 +699,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, desc->lld.mbr_sa = buf_addr + i * period_len; desc->lld.mbr_da = atchan->per_dst_addr; cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG]; - }; + } desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 | AT_XDMAC_MBR_UBC_NDEN | AT_XDMAC_MBR_UBC_NSEN -- GitLab From 2abd4198090fbe88af653a4a0be3735d286356b2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 6 Nov 2014 17:34:13 +0530 Subject: [PATCH 4983/9457] dmaengine: at_xdmac: fix usage of read, write wrappers This driver uses read_relaxed and writel_relaxed to read, write to IO memory. the config defines COMPILE_TEST so gets compiled on different archs. This causes issue as few archs like x86 etc don't define it. So use readl/writel which is defined in all archs Reported-by: kbuild test robot Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 155577b98309..44f212de5200 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -248,12 +248,12 @@ static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, uns return atxdmac->regs + (AT_XDMAC_CHAN_REG_BASE + chan_nb * 0x40); } -#define at_xdmac_read(atxdmac, reg) readl_relaxed((atxdmac)->regs + (reg)) +#define at_xdmac_read(atxdmac, reg) readl((atxdmac)->regs + (reg)) #define at_xdmac_write(atxdmac, reg, value) \ - writel_relaxed((value), (atxdmac)->regs + (reg)) + writel((value), (atxdmac)->regs + (reg)) -#define at_xdmac_chan_read(atchan, reg) readl_relaxed((atchan)->ch_regs + (reg)) -#define at_xdmac_chan_write(atchan, reg, value) writel_relaxed((value), (atchan)->ch_regs + (reg)) +#define at_xdmac_chan_read(atchan, reg) readl((atchan)->ch_regs + (reg)) +#define at_xdmac_chan_write(atchan, reg, value) writel((value), (atchan)->ch_regs + (reg)) static inline struct at_xdmac_chan *to_at_xdmac_chan(struct dma_chan *dchan) { -- GitLab From c66ec04ed73c2355fa17e8d114808eea90d95711 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 6 Nov 2014 17:37:48 +0530 Subject: [PATCH 4984/9457] dmaengine: xdmac: fix print warning on size_t variable As documented in printk-formats.txt the size_t should be printed with %zu/%zd specfiers. This way it works on all archs. make.cross ARCH=avr32 All warnings: drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_cyclic': >> drivers/dma/at_xdmac.c:663: warning: format '%d' expects type 'int', but argument 6 has type 'size_t' >> drivers/dma/at_xdmac.c:663: warning: format '%d' expects type 'int', but argument 7 has type 'size_t' drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_memcpy': >> drivers/dma/at_xdmac.c:765: warning: format '%d' expects type 'int', but argument 7 has type 'size_t' >> drivers/dma/at_xdmac.c:794: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'size_t' >> drivers/dma/at_xdmac.c:815: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'size_t' Reported-by: kbuild test robot Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 44f212de5200..0f947c8774bf 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -660,7 +660,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, int i; u32 cfg; - dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%d, period_len=%d, dir=%s, flags=0x%lx\n", + dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", __func__, buf_addr, buf_len, period_len, direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags); @@ -762,7 +762,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | AT_XDMAC_CC_MBSIZE_SIXTEEN | AT_XDMAC_CC_TYPE_MEM_TRAN; - dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%d, flags=0x%lx\n", + dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%zd, flags=0x%lx\n", __func__, src, dest, len, flags); if (unlikely(!len)) @@ -791,7 +791,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, while (remaining_size) { struct at_xdmac_desc *desc = NULL; - dev_dbg(chan2dev(chan), "%s: remaining_size=%u\n", __func__, remaining_size); + dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); spin_lock_bh(&atchan->lock); desc = at_xdmac_get_desc(atchan); @@ -812,7 +812,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, else xfer_size = remaining_size; - dev_dbg(chan2dev(chan), "%s: xfer_size=%u\n", __func__, xfer_size); + dev_dbg(chan2dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size); /* Check remaining length and change data width if needed. */ if (!((src_addr | dst_addr | xfer_size) & 7)) { -- GitLab From 82e2424635f4c0d9af6670638889be81f56ea225 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 6 Nov 2014 18:02:52 +0530 Subject: [PATCH 4985/9457] dmaengine: xdmac: fix print warning on dma_addr_t variable As documented in printk-formats.txt the dma_addr_t should be printed with %pad specfiers. This way it works on all archs. make.cross ARCH=s390 All warnings: drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_slave_sg': >> drivers/dma/at_xdmac.c:621:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ >> drivers/dma/at_xdmac.c:621:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] >> drivers/dma/at_xdmac.c:628:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_cyclic': >> drivers/dma/at_xdmac.c:663:2: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%d, period_len=%d, dir=%s, flags=0x%lx\n", ^ >> drivers/dma/at_xdmac.c:690:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ >> drivers/dma/at_xdmac.c:709:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ >> drivers/dma/at_xdmac.c:709:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] >> drivers/dma/at_xdmac.c:716:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), >> drivers/dma/at_xdmac.c:731:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_memcpy': >> drivers/dma/at_xdmac.c:765:2: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%d, flags=0x%lx\n", ^ >> drivers/dma/at_xdmac.c:765:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), "%s: remaining_size=%u\n", __func__, remaining_size); ^ >> drivers/dma/at_xdmac.c:845:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ >> drivers/dma/at_xdmac.c:845:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] >> drivers/dma/at_xdmac.c:852:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), ^ drivers/dma/at_xdmac.c: In function 'at_xdmac_tx_status': >> drivers/dma/at_xdmac.c:929:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=] dev_dbg(chan2dev(chan), Reported-by: kbuild test robot Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 0f947c8774bf..89c43be20a38 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -619,15 +619,15 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */ | len / (1 << at_xdmac_get_dwidth(cfg)); /* microblock length */ dev_dbg(chan2dev(chan), - "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x\n", - __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc); + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); /* Chain lld. */ if (prev) { prev->lld.mbr_nda = desc->tx_dma_desc.phys; dev_dbg(chan2dev(chan), - "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", - __func__, prev, prev->lld.mbr_nda); + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); } prev = desc; @@ -660,8 +660,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, int i; u32 cfg; - dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", - __func__, buf_addr, buf_len, period_len, + dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", + __func__, &buf_addr, buf_len, period_len, direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags); if (!is_slave_direction(direction)) { @@ -688,8 +688,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, } spin_unlock_bh(&atchan->lock); dev_dbg(chan2dev(chan), - "%s: desc=0x%p, tx_dma_desc.phys=0x%08x\n", - __func__, desc, desc->tx_dma_desc.phys); + "%s: desc=0x%p, tx_dma_desc.phys=%pad\n", + __func__, desc, &desc->tx_dma_desc.phys); if (direction == DMA_DEV_TO_MEM) { desc->lld.mbr_sa = atchan->per_src_addr; @@ -707,15 +707,15 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, | period_len >> at_xdmac_get_dwidth(cfg); dev_dbg(chan2dev(chan), - "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x\n", - __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc); + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); /* Chain lld. */ if (prev) { prev->lld.mbr_nda = desc->tx_dma_desc.phys; dev_dbg(chan2dev(chan), - "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", - __func__, prev, prev->lld.mbr_nda); + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); } prev = desc; @@ -729,8 +729,8 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, prev->lld.mbr_nda = first->tx_dma_desc.phys; dev_dbg(chan2dev(chan), - "%s: chain lld: prev=0x%p, mbr_nda=0x%08x\n", - __func__, prev, prev->lld.mbr_nda); + "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + __func__, prev, &prev->lld.mbr_nda); first->tx_dma_desc.flags = flags; first->xfer_size = buf_len; first->direction = direction; @@ -762,8 +762,8 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | AT_XDMAC_CC_MBSIZE_SIXTEEN | AT_XDMAC_CC_TYPE_MEM_TRAN; - dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%zd, flags=0x%lx\n", - __func__, src, dest, len, flags); + dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", + __func__, &src, &dest, len, flags); if (unlikely(!len)) return NULL; @@ -843,8 +843,8 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, desc->lld.mbr_cfg = chan_cc; dev_dbg(chan2dev(chan), - "%s: lld: mbr_sa=0x%08x, mbr_da=0x%08x, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", - __func__, desc->lld.mbr_sa, desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); + "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", + __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); /* Chain lld. */ if (prev) { @@ -927,8 +927,8 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, dma_set_residue(txstate, residue); dev_dbg(chan2dev(chan), - "%s: desc=0x%p, tx_dma_desc.phys=0x%08x, tx_status=%d, cookie=%d, residue=%d\n", - __func__, desc, desc->tx_dma_desc.phys, ret, cookie, residue); + "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n", + __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); return ret; } -- GitLab From 6e5ae29b6dbdb60ef60f769d7b80274d62e6fbcf Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 11:52:39 +0100 Subject: [PATCH 4986/9457] dmaengine: at_xdmac: prefer usage of readl/writel_relaxed _relaxed version of readl and writel are not implemented on all architecture so COMPILE_TEST has to be removed in order to not cause some build failures. Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 2 +- drivers/dma/at_xdmac.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 607271a999a9..8b6fb0f11007 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -109,7 +109,7 @@ config AT_HDMAC config AT_XDMAC tristate "Atmel XDMA support" - depends on (ARCH_AT91 || COMPILE_TEST) + depends on ARCH_AT91 select DMA_ENGINE help Support the Atmel XDMA controller. diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 89c43be20a38..1f53d92f63d3 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -248,12 +248,12 @@ static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, uns return atxdmac->regs + (AT_XDMAC_CHAN_REG_BASE + chan_nb * 0x40); } -#define at_xdmac_read(atxdmac, reg) readl((atxdmac)->regs + (reg)) +#define at_xdmac_read(atxdmac, reg) readl_relaxed((atxdmac)->regs + (reg)) #define at_xdmac_write(atxdmac, reg, value) \ - writel((value), (atxdmac)->regs + (reg)) + writel_relaxed((value), (atxdmac)->regs + (reg)) -#define at_xdmac_chan_read(atchan, reg) readl((atchan)->ch_regs + (reg)) -#define at_xdmac_chan_write(atchan, reg, value) writel((value), (atchan)->ch_regs + (reg)) +#define at_xdmac_chan_read(atchan, reg) readl_relaxed((atchan)->ch_regs + (reg)) +#define at_xdmac_chan_write(atchan, reg, value) writel_relaxed((value), (atchan)->ch_regs + (reg)) static inline struct at_xdmac_chan *to_at_xdmac_chan(struct dma_chan *dchan) { -- GitLab From 77e6c9bfaa622183c5fe9aa23be4822dd21038d1 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 11:52:40 +0100 Subject: [PATCH 4987/9457] dmaengine: at_xdmac: remove chancnt affectation Remove chancnt affectation since it is done in dma_async_device_regiser. Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 1f53d92f63d3..fcecbaddb351 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1393,7 +1393,6 @@ static int at_xdmac_probe(struct platform_device *pdev) atxdmac->dma.device_prep_dma_memcpy = at_xdmac_prep_dma_memcpy; atxdmac->dma.device_prep_slave_sg = at_xdmac_prep_slave_sg; atxdmac->dma.device_control = at_xdmac_control; - atxdmac->dma.chancnt = nr_channels; atxdmac->dma.device_slave_caps = at_xdmac_device_slave_caps; /* Disable all chans and interrupts. */ -- GitLab From 4e0978208d67730a316066911201a6252158d2fd Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Thu, 13 Nov 2014 11:52:41 +0100 Subject: [PATCH 4988/9457] dmaengine: at_xdmac: fix software lockup at_xdmac_tx_status() According to the Atmel eXtended DMA controller datasheet, requesting a DMA transfer flush for a channel is only revelant when this transfer is source peripheral synchronized. So we have to check this condition before requesting a channel flush by writing the channel bit into the Global channel SoftWare Flush (GSWF) register then waiting for flush to complete by monitoring the end of Flush Interrupt Status (FIS) bit in the Channel Interrupt Status (CIS) register. Indeed, for non source peripheral synchronized transfer, writing the channel bit into the GSWF register does nothing. Especially, the FIS bit is never set into the CIS register. The former code looped forever waiting for this bit to be set. Signed-off-by: Cyrille Pitchen Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index fcecbaddb351..fa9d75adf4d7 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -879,7 +879,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct list_head *descs_list; enum dma_status ret; int residue; - u32 cur_nda; + u32 cur_nda, mask, value; u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]); ret = dma_cookie_status(chan, cookie, txstate); @@ -903,10 +903,17 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, } residue = desc->xfer_size; - /* Flush FIFO. */ - at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); - while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) - cpu_relax(); + /* + * Flush FIFO: only relevant when the transfer is source peripheral + * synchronized. + */ + mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC; + value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM; + if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) { + at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); + while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) + cpu_relax(); + } cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; /* -- GitLab From 57819276db8ae06e231b884377b75860f267d984 Mon Sep 17 00:00:00 2001 From: Cyrille Pitchen Date: Thu, 13 Nov 2014 11:52:42 +0100 Subject: [PATCH 4989/9457] dmaengine: at_xdmac: fix a bug in transfer residue computation The total size of the transfer was wrong in at_xdmac_prep_slave_sg() resulting in bad computation of the transfer residue by at_xdmac_tx_status(). Signed-off-by: Cyrille Pitchen Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index fa9d75adf4d7..bf2aacbbf4cc 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -562,6 +562,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct scatterlist *sg; int i; u32 cfg; + unsigned int xfer_size = 0; if (!sgl) return NULL; @@ -637,12 +638,13 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); list_add_tail(&desc->desc_node, &first->descs_list); + xfer_size += len; } spin_unlock_bh(&atchan->lock); first->tx_dma_desc.flags = flags; - first->xfer_size = sg_len; + first->xfer_size = xfer_size; first->direction = direction; return &first->tx_dma_desc; -- GitLab From 87809839a56603b3ace6e7250a81afadcd916691 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 11:52:43 +0100 Subject: [PATCH 4990/9457] dmaengine: at_xdmac: fix missing spin_unlock Lock taken when entering the function but unlock missing before it returns. Signed-off-by: Ludovic Desroches Reported-by: Dan Carpenter Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index bf2aacbbf4cc..586275fe1120 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -901,6 +901,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, */ if (!desc->active_xfer) { dma_set_residue(txstate, desc->xfer_size); + spin_unlock_bh(&atchan->lock); return ret; } -- GitLab From 466b3cf17ea6bee26cf7a404f51a44f2e884b31e Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 11:52:44 +0100 Subject: [PATCH 4991/9457] ARM: dts: at_xdmac: fix bad value of dma-cells in documentation The dma-cells value in the example was 2 instead of 1. Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/atmel-xdma.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/atmel-xdma.txt b/Documentation/devicetree/bindings/dma/atmel-xdma.txt index e75c128c53fa..0eb2b3207e08 100644 --- a/Documentation/devicetree/bindings/dma/atmel-xdma.txt +++ b/Documentation/devicetree/bindings/dma/atmel-xdma.txt @@ -22,7 +22,7 @@ dma1: dma-controller@f0004000 { compatible = "atmel,sama5d4-dma"; reg = <0xf0004000 0x200>; interrupts = <50 4 0>; - #dma-cells = <2>; + #dma-cells = <1>; }; -- GitLab From fef4cbf2ab830fcd695d892927386ad9ccc46339 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 11:52:45 +0100 Subject: [PATCH 4992/9457] dmaengine: at_xdmac: Add DMA_PRIVATE same issue as commit 7f5ae3553685: "Without DMA_PRIVATE the driver is not able to allocate more than one channel. Since it uses dma_get_any_slave_channel that calls private_candidate, the second allocation fails at /* some channels are already publicly allocated */ " Signed-off-by: Ludovic Desroches Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 586275fe1120..b60d77a22df6 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1394,6 +1394,11 @@ static int at_xdmac_probe(struct platform_device *pdev) dma_cap_set(DMA_CYCLIC, atxdmac->dma.cap_mask); dma_cap_set(DMA_MEMCPY, atxdmac->dma.cap_mask); dma_cap_set(DMA_SLAVE, atxdmac->dma.cap_mask); + /* + * Without DMA_PRIVATE the driver is not able to allocate more than + * one channel, second allocation fails in private_candidate. + */ + dma_cap_set(DMA_PRIVATE, atxdmac->dma.cap_mask); atxdmac->dma.dev = &pdev->dev; atxdmac->dma.device_alloc_chan_resources = at_xdmac_alloc_chan_resources; atxdmac->dma.device_free_chan_resources = at_xdmac_free_chan_resources; -- GitLab From 197304b7a5e32a457eee0c0cf0f518fab65fffcc Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:43 +0100 Subject: [PATCH 4993/9457] mac802154: remove unused prototypes This patch removes some prototypes which are not used anymore. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index c5b231047b60..593339ad590b 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -120,14 +120,10 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) return test_bit(SDATA_STATE_RUNNING, &sdata->state); } -extern struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced; extern struct ieee802154_mlme_ops mac802154_mlme_wpan; -void mac802154_monitor_setup(struct net_device *dev); netdev_tx_t ieee802154_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); - -void mac802154_wpan_setup(struct net_device *dev); netdev_tx_t ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer); @@ -176,8 +172,6 @@ void mac802154_unlock_table(struct net_device *dev); /* interface handling */ int ieee802154_iface_init(void); void ieee802154_iface_exit(void); -struct net_device * -mac802154_add_iface(struct wpan_phy *phy, const char *name, int type); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, -- GitLab From 2d6dde29ae144cd87879963477cdedb96be542c7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:44 +0100 Subject: [PATCH 4994/9457] at86rf230: fix commentation for symbol duration This patch fix an copy&paste issue in the comment of setting symbol duration. These comments are more correct according the at86rf212 datasheet now. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 7278e1838c57..1c0135620c62 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1043,10 +1043,10 @@ at86rf212_set_channel(struct at86rf230_local *lp, u8 page, u8 channel) } } else { if (page == 0) - /* SUB:0 and BPSK:1 -> BPSK-20 */ + /* SUB:0 and BPSK:1 -> OQPSK-100/200/400 */ lp->hw->phy->symbol_duration = 40; else - /* SUB:1 and BPSK:1 -> BPSK-20 */ + /* SUB:1 and BPSK:1 -> OQPSK-250/500/1000 */ lp->hw->phy->symbol_duration = 16; } -- GitLab From 29cd54b9bfaccd8e1291e100a1cc9e42b7ff717e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:45 +0100 Subject: [PATCH 4995/9457] mac802154: remove const for non pointer in driver-ops This patches removes the const keyword in variables which are non pointers. There is no sense to declare call by value parameters as const. Signed-off-by: Alexander Aring Reported-by: Marc Kleine-Budde Signed-off-by: Marcel Holtmann --- net/mac802154/driver-ops.h | 46 +++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/net/mac802154/driver-ops.h b/net/mac802154/driver-ops.h index dfd29ffb8fee..f21e864613d0 100644 --- a/net/mac802154/driver-ops.h +++ b/net/mac802154/driver-ops.h @@ -50,16 +50,15 @@ static inline void drv_stop(struct ieee802154_local *local) local->started = false; } -static inline int drv_set_channel(struct ieee802154_local *local, - const u8 page, const u8 channel) +static inline int +drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel) { might_sleep(); return local->ops->set_channel(&local->hw, page, channel); } -static inline int drv_set_tx_power(struct ieee802154_local *local, - const s8 dbm) +static inline int drv_set_tx_power(struct ieee802154_local *local, s8 dbm) { might_sleep(); @@ -71,8 +70,7 @@ static inline int drv_set_tx_power(struct ieee802154_local *local, return local->ops->set_txpower(&local->hw, dbm); } -static inline int drv_set_cca_mode(struct ieee802154_local *local, - const u8 cca_mode) +static inline int drv_set_cca_mode(struct ieee802154_local *local, u8 cca_mode) { might_sleep(); @@ -84,8 +82,7 @@ static inline int drv_set_cca_mode(struct ieee802154_local *local, return local->ops->set_cca_mode(&local->hw, cca_mode); } -static inline int drv_set_lbt_mode(struct ieee802154_local *local, - const bool mode) +static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode) { might_sleep(); @@ -97,8 +94,8 @@ static inline int drv_set_lbt_mode(struct ieee802154_local *local, return local->ops->set_lbt(&local->hw, mode); } -static inline int drv_set_cca_ed_level(struct ieee802154_local *local, - const s32 ed_level) +static inline int +drv_set_cca_ed_level(struct ieee802154_local *local, s32 ed_level) { might_sleep(); @@ -110,8 +107,7 @@ static inline int drv_set_cca_ed_level(struct ieee802154_local *local, return local->ops->set_cca_ed_level(&local->hw, ed_level); } -static inline int drv_set_pan_id(struct ieee802154_local *local, - const __le16 pan_id) +static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id) { struct ieee802154_hw_addr_filt filt; @@ -128,8 +124,8 @@ static inline int drv_set_pan_id(struct ieee802154_local *local, IEEE802154_AFILT_PANID_CHANGED); } -static inline int drv_set_extended_addr(struct ieee802154_local *local, - const __le64 extended_addr) +static inline int +drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr) { struct ieee802154_hw_addr_filt filt; @@ -146,8 +142,8 @@ static inline int drv_set_extended_addr(struct ieee802154_local *local, IEEE802154_AFILT_IEEEADDR_CHANGED); } -static inline int drv_set_short_addr(struct ieee802154_local *local, - const __le16 short_addr) +static inline int +drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr) { struct ieee802154_hw_addr_filt filt; @@ -164,8 +160,8 @@ static inline int drv_set_short_addr(struct ieee802154_local *local, IEEE802154_AFILT_SADDR_CHANGED); } -static inline int drv_set_pan_coord(struct ieee802154_local *local, - const bool is_coord) +static inline int +drv_set_pan_coord(struct ieee802154_local *local, bool is_coord) { struct ieee802154_hw_addr_filt filt; @@ -182,9 +178,9 @@ static inline int drv_set_pan_coord(struct ieee802154_local *local, IEEE802154_AFILT_PANC_CHANGED); } -static inline int drv_set_csma_params(struct ieee802154_local *local, - u8 min_be, u8 max_be, - u8 max_csma_backoffs) +static inline int +drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be, + u8 max_csma_backoffs) { might_sleep(); @@ -197,8 +193,8 @@ static inline int drv_set_csma_params(struct ieee802154_local *local, max_csma_backoffs); } -static inline int drv_set_max_frame_retries(struct ieee802154_local *local, - s8 max_frame_retries) +static inline int +drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries) { might_sleep(); @@ -210,8 +206,8 @@ static inline int drv_set_max_frame_retries(struct ieee802154_local *local, return local->ops->set_frame_retries(&local->hw, max_frame_retries); } -static inline int drv_set_promiscuous_mode(struct ieee802154_local *local, - const bool on) +static inline int +drv_set_promiscuous_mode(struct ieee802154_local *local, bool on) { might_sleep(); -- GitLab From 6d5fb87745081b6fe5bae5cac6dc18a57bd40ca3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:46 +0100 Subject: [PATCH 4996/9457] mac802154: remove const for non pointer in cfg ops This patches removes the const keyword in variables which are non pointers. There is no sense to declare call by value parameters as const. Signed-off-by: Alexander Aring Reported-by: Marc Kleine-Budde Signed-off-by: Marcel Holtmann --- net/mac802154/cfg.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 5d669d87dd7d..2b3610c51489 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -43,8 +43,7 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, } static int -ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page, - const u8 channel) +ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); int ret; @@ -64,8 +63,9 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page, return ret; } -static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, const u16 pan_id) +static int +ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + u16 pan_id) { ASSERT_RTNL(); @@ -86,7 +86,7 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, static int ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, - const u8 min_be, const u8 max_be) + u8 min_be, u8 max_be) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); @@ -102,7 +102,7 @@ ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy, static int ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, - const u16 short_addr) + u16 short_addr) { ASSERT_RTNL(); @@ -125,9 +125,10 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, return 0; } -static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, - const u8 max_csma_backoffs) +static int +ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + u8 max_csma_backoffs) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); @@ -140,9 +141,10 @@ static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy, return 0; } -static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, - const s8 max_frame_retries) +static int +ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + s8 max_frame_retries) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); @@ -155,9 +157,9 @@ static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy, return 0; } -static int ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, - const bool mode) +static int +ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, + bool mode) { struct ieee802154_local *local = wpan_phy_priv(wpan_phy); -- GitLab From 628b1e1136515c096ba995df694294dbe4ac876d Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:47 +0100 Subject: [PATCH 4997/9457] mac802154: remove const for non pointer in rdev-ops This patches removes the const keyword in variables which are non pointers. There is no sense to declare call by value parameters as const. Signed-off-by: Alexander Aring Reported-by: Marc Kleine-Budde Signed-off-by: Marcel Holtmann --- net/ieee802154/rdev-ops.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index a78f700bc821..578bc41e92d3 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -21,8 +21,7 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, } static inline int -rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page, - const u8 channel) +rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) { return rdev->ops->set_channel(&rdev->wpan_phy, page, channel); } @@ -43,8 +42,7 @@ rdev_set_short_addr(struct cfg802154_registered_device *rdev, static inline int rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, const u8 min_be, - const u8 max_be) + struct wpan_dev *wpan_dev, u8 min_be, u8 max_be) { return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev, min_be, max_be); @@ -52,8 +50,7 @@ rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev, static inline int rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, - const u8 max_csma_backoffs) + struct wpan_dev *wpan_dev, u8 max_csma_backoffs) { return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev, max_csma_backoffs); @@ -61,8 +58,7 @@ rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev, static inline int rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, - const s8 max_frame_retries) + struct wpan_dev *wpan_dev, s8 max_frame_retries) { return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev, max_frame_retries); @@ -70,7 +66,7 @@ rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev, static inline int rdev_set_lbt_mode(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, const bool mode) + struct wpan_dev *wpan_dev, bool mode) { return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode); } -- GitLab From cd11d935f2df86b6a619e8721553b1d41633f0fd Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:48 +0100 Subject: [PATCH 4998/9457] mac802154: remove deprecated linux-zigbee info We don't and we can't name it zigbee anymore. This patch removes deprecated information for project website. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 0af1be64e8ad..5199f2115ee9 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -4,8 +4,6 @@ * Written by: * Alexander Smirnov * - * Based on the code from 'linux-zigbee.sourceforge.net' project. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. -- GitLab From 944742a36d784c2a36a141ac10ba5168b0313cec Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:49 +0100 Subject: [PATCH 4999/9457] mac802154: use new nl802154 iftype types This patch replace the depracted IEEE802154_DEV to the new introduced NL802154_IFTYPE_NODE types. There is a backwards compatibility to have the identical types for both enum definitions. Also remove some inlcude issue with "linux/nl802154.h", because the export nl_policy inside this header it was always necessary to have an include of "net/rtnetlink.h" before. The reason for this is more complicated. Nevertheless we removed this now, because "linux/nl802154.h" is the depracted netlink interface. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/ieee802154_i.h | 3 ++- net/mac802154/iface.c | 18 +++++++++--------- net/mac802154/main.c | 4 ++-- net/mac802154/rx.c | 7 +++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 593339ad590b..6ad5e8912a4c 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "llsec.h" @@ -175,7 +176,7 @@ void ieee802154_iface_exit(void); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - struct wpan_dev **new_wpan_dev, int type); + struct wpan_dev **new_wpan_dev, enum nl802154_iftype type); void ieee802154_remove_interfaces(struct ieee802154_local *local); #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index feb064715d1f..cc992e8405d3 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -22,8 +22,7 @@ #include #include -#include -#include +#include #include #include #include @@ -144,7 +143,7 @@ static int mac802154_slave_open(struct net_device *dev) ASSERT_RTNL(); - if (sdata->vif.type == IEEE802154_DEV_WPAN) { + if (sdata->vif.type == NL802154_IFTYPE_NODE) { mutex_lock(&sdata->local->iflist_mtx); list_for_each_entry(subif, &sdata->local->interfaces, list) { if (subif != sdata && @@ -407,7 +406,8 @@ static void ieee802154_if_setup(struct net_device *dev) } static int -ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) +ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, + enum nl802154_iftype type) { struct wpan_dev *wpan_dev = &sdata->wpan_dev; @@ -429,7 +429,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) wpan_dev->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); switch (type) { - case IEEE802154_DEV_WPAN: + case NL802154_IFTYPE_NODE: ieee802154_be64_to_le64(&wpan_dev->extended_addr, sdata->dev->dev_addr); @@ -444,7 +444,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) mac802154_llsec_init(&sdata->sec); break; - case IEEE802154_DEV_MONITOR: + case NL802154_IFTYPE_MONITOR: sdata->dev->destructor = free_netdev; sdata->dev->netdev_ops = &mac802154_monitor_ops; wpan_dev->promiscuous_mode = true; @@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type) struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - struct wpan_dev **new_wpan_dev, int type) + struct wpan_dev **new_wpan_dev, enum nl802154_iftype type) { struct net_device *ndev = NULL; struct ieee802154_sub_if_data *sdata = NULL; @@ -478,10 +478,10 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, goto err; switch (type) { - case IEEE802154_DEV_WPAN: + case NL802154_IFTYPE_NODE: ndev->type = ARPHRD_IEEE802154; break; - case IEEE802154_DEV_MONITOR: + case NL802154_IFTYPE_MONITOR: ndev->type = ARPHRD_IEEE802154_MONITOR; break; default: diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 5199f2115ee9..2e42fc2e430c 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -161,7 +161,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - dev = ieee802154_if_add(local, "wpan%d", NULL, IEEE802154_DEV_WPAN); + dev = ieee802154_if_add(local, "wpan%d", NULL, NL802154_IFTYPE_NODE); if (IS_ERR(dev)) { rtnl_unlock(); rc = PTR_ERR(dev); diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index b18e755c38ce..041dbd5958d4 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -25,8 +25,7 @@ #include #include -#include -#include +#include #include "ieee802154_i.h" @@ -209,7 +208,7 @@ __ieee802154_rx_handle_packet(struct ieee802154_local *local, } list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->vif.type != IEEE802154_DEV_WPAN || + if (sdata->vif.type != NL802154_IFTYPE_NODE || !netif_running(sdata->dev)) continue; @@ -234,7 +233,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) skb->protocol = htons(ETH_P_IEEE802154); list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->vif.type != IEEE802154_DEV_MONITOR) + if (sdata->vif.type != NL802154_IFTYPE_MONITOR) continue; if (!ieee802154_sdata_running(sdata)) -- GitLab From 133d3f31729a62908ab98d0b6562cc1a35d3dc39 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:50 +0100 Subject: [PATCH 5000/9457] mac802154: remove wpan_dev parameter in if_add This parameter was grabbed from wireless implementation with the identically wireless dev struct. We don't need this right now and so we remove it. Maybe we will add it later again if we found any real reason to have such parameter. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/cfg.c | 2 +- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 5 +---- net/mac802154/main.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 2b3610c51489..2abe7e5f0974 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -28,7 +28,7 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, struct net_device *dev; rtnl_lock(); - dev = ieee802154_if_add(local, name, NULL, type); + dev = ieee802154_if_add(local, name, type); rtnl_unlock(); return dev; diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 6ad5e8912a4c..46553830896d 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -176,7 +176,7 @@ void ieee802154_iface_exit(void); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - struct wpan_dev **new_wpan_dev, enum nl802154_iftype type); + enum nl802154_iftype type); void ieee802154_remove_interfaces(struct ieee802154_local *local); #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index cc992e8405d3..ba63ac93ae90 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - struct wpan_dev **new_wpan_dev, enum nl802154_iftype type) + enum nl802154_iftype type) { struct net_device *ndev = NULL; struct ieee802154_sub_if_data *sdata = NULL; @@ -516,9 +516,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, list_add_tail_rcu(&sdata->list, &local->interfaces); mutex_unlock(&local->iflist_mtx); - if (new_wpan_dev) - *new_wpan_dev = &sdata->wpan_dev; - return ndev; err: diff --git a/net/mac802154/main.c b/net/mac802154/main.c index 2e42fc2e430c..bbb19dd585a0 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -161,7 +161,7 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - dev = ieee802154_if_add(local, "wpan%d", NULL, NL802154_IFTYPE_NODE); + dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE); if (IS_ERR(dev)) { rtnl_unlock(); rc = PTR_ERR(dev); -- GitLab From f3ea5e44231a88eaea69a13410d1b80c19cfa1df Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:51 +0100 Subject: [PATCH 5001/9457] ieee802154: add new interface command This patch adds a new nl802154 command for adding a new interface according to a wpan phy via nl802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 5 +++++ net/ieee802154/nl802154.c | 34 ++++++++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 15 +++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 17b4fc0705b2..24c7321f3647 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -21,6 +21,8 @@ #include #include +#include + /* According to the IEEE 802.15.4 stadard the upper most significant bits of * the 32-bit channel bitmaps shall be used as an integer value to specify 32 * possible channel pages. The lower 27 bits of the channel bit map shall be @@ -37,6 +39,9 @@ struct cfg802154_ops { int type); void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, struct net_device *dev); + int (*add_virtual_intf)(struct wpan_phy *wpan_phy, + const char *name, + enum nl802154_iftype type); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_pan_id)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u16 pan_id); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index ccdf33ecee0b..e7224f3c1584 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -551,6 +551,32 @@ static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) return genlmsg_reply(msg, info); } +static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; + + /* TODO avoid failing a new interface + * creation due to pending removal? + */ + + if (!info->attrs[NL802154_ATTR_IFNAME]) + return -EINVAL; + + if (info->attrs[NL802154_ATTR_IFTYPE]) { + type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]); + if (type > NL802154_IFTYPE_MAX) + return -EINVAL; + } + + if (!rdev->ops->add_virtual_intf) + return -EOPNOTSUPP; + + return rdev_add_virtual_intf(rdev, + nla_data(info->attrs[NL802154_ATTR_IFNAME]), + type); +} + static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) { struct cfg802154_registered_device *rdev = info->user_ptr[0]; @@ -818,6 +844,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_NEW_INTERFACE, + .doit = nl802154_new_interface, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | + NL802154_FLAG_NEED_RTNL, + }, { .cmd = NL802154_CMD_SET_CHANNEL, .doit = nl802154_set_channel, diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 578bc41e92d3..d3a4f94c5fdc 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -20,6 +20,13 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev); } +static inline int +rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, + enum nl802154_iftype type) +{ + return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type); +} + static inline int rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) { diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 2abe7e5f0974..ae1a9ef2d42c 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -42,6 +42,20 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, ieee802154_if_remove(sdata); } +static int +ieee802154_add_iface(struct wpan_phy *phy, const char *name, + enum nl802154_iftype type) +{ + struct ieee802154_local *local = wpan_phy_priv(phy); + struct net_device *err; + + err = ieee802154_if_add(local, name, type); + if (IS_ERR(err)) + return PTR_ERR(err); + + return 0; +} + static int ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) { @@ -175,6 +189,7 @@ ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, + .add_virtual_intf = ieee802154_add_iface, .set_channel = ieee802154_set_channel, .set_pan_id = ieee802154_set_pan_id, .set_short_addr = ieee802154_set_short_addr, -- GitLab From 0e57547eb7f0aa99aba32b50c49dbd722a80d6fb Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:52 +0100 Subject: [PATCH 5002/9457] ieee802154: setting extended address while iface add This patch adds support for setting an extended address while registration a new interface. If ieee802154_is_valid_extended_addr getting as parameter and invalid extended address then the perm address is fallback. This is useful to make some default handling while for example default registration of a wpan interface while phy registration. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 3 ++- net/ieee802154/nl802154.c | 8 +++++++- net/ieee802154/rdev-ops.h | 5 +++-- net/mac802154/cfg.c | 7 ++++--- net/mac802154/ieee802154_i.h | 2 +- net/mac802154/iface.c | 12 ++++++++---- net/mac802154/main.c | 3 ++- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 24c7321f3647..4a9bb0e3db2b 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -41,7 +41,8 @@ struct cfg802154_ops { struct net_device *dev); int (*add_virtual_intf)(struct wpan_phy *wpan_phy, const char *name, - enum nl802154_iftype type); + enum nl802154_iftype type, + __le64 extended_addr); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_pan_id)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u16 pan_id); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index e7224f3c1584..49c4d8a5004a 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -555,6 +555,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg802154_registered_device *rdev = info->user_ptr[0]; enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; + __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL); /* TODO avoid failing a new interface * creation due to pending removal? @@ -569,12 +570,17 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } + /* TODO add nla_get_le64 to netlink */ + if (info->attrs[NL802154_ATTR_EXTENDED_ADDR]) + extended_addr = (__force __le64)nla_get_u64( + info->attrs[NL802154_ATTR_EXTENDED_ADDR]); + if (!rdev->ops->add_virtual_intf) return -EOPNOTSUPP; return rdev_add_virtual_intf(rdev, nla_data(info->attrs[NL802154_ATTR_IFNAME]), - type); + type, extended_addr); } static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index d3a4f94c5fdc..06e97542dafb 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -22,9 +22,10 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev, static inline int rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, - enum nl802154_iftype type) + enum nl802154_iftype type, __le64 extended_addr) { - return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type); + return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type, + extended_addr); } static inline int diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index ae1a9ef2d42c..568d712bfc8c 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -28,7 +28,8 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy, struct net_device *dev; rtnl_lock(); - dev = ieee802154_if_add(local, name, type); + dev = ieee802154_if_add(local, name, type, + cpu_to_le64(0x0000000000000000ULL)); rtnl_unlock(); return dev; @@ -44,12 +45,12 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy, static int ieee802154_add_iface(struct wpan_phy *phy, const char *name, - enum nl802154_iftype type) + enum nl802154_iftype type, __le64 extended_addr) { struct ieee802154_local *local = wpan_phy_priv(phy); struct net_device *err; - err = ieee802154_if_add(local, name, type); + err = ieee802154_if_add(local, name, type, extended_addr); if (IS_ERR(err)) return PTR_ERR(err); diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 46553830896d..cc691637d24b 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -176,7 +176,7 @@ void ieee802154_iface_exit(void); void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata); struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - enum nl802154_iftype type); + enum nl802154_iftype type, __le64 extended_addr); void ieee802154_remove_interfaces(struct ieee802154_local *local); #endif /* __IEEE802154_I_H */ diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index ba63ac93ae90..38dfc72d24b6 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -458,7 +458,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, struct net_device * ieee802154_if_add(struct ieee802154_local *local, const char *name, - enum nl802154_iftype type) + enum nl802154_iftype type, __le64 extended_addr) { struct net_device *ndev = NULL; struct ieee802154_sub_if_data *sdata = NULL; @@ -477,9 +477,16 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, if (ret < 0) goto err; + ieee802154_le64_to_be64(ndev->perm_addr, + &local->hw.phy->perm_extended_addr); switch (type) { case NL802154_IFTYPE_NODE: ndev->type = ARPHRD_IEEE802154; + if (ieee802154_is_valid_extended_addr(extended_addr)) + ieee802154_le64_to_be64(ndev->dev_addr, &extended_addr); + else + memcpy(ndev->dev_addr, ndev->perm_addr, + IEEE802154_EXTENDED_ADDR_LEN); break; case NL802154_IFTYPE_MONITOR: ndev->type = ARPHRD_IEEE802154_MONITOR; @@ -489,9 +496,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, goto err; } - ieee802154_le64_to_be64(ndev->perm_addr, - &local->hw.phy->perm_extended_addr); - memcpy(ndev->dev_addr, ndev->perm_addr, IEEE802154_EXTENDED_ADDR_LEN); /* TODO check this */ SET_NETDEV_DEV(ndev, &local->phy->dev); sdata = netdev_priv(ndev); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index bbb19dd585a0..8500378c8318 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -161,7 +161,8 @@ int ieee802154_register_hw(struct ieee802154_hw *hw) rtnl_lock(); - dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE); + dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE, + cpu_to_le64(0x0000000000000000ULL)); if (IS_ERR(dev)) { rtnl_unlock(); rc = PTR_ERR(dev); -- GitLab From b821ecd4c8a0b3b1fc1bdd191bb7d555d818cafe Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:53 +0100 Subject: [PATCH 5003/9457] ieee802154: add del interface command This patch adds support for deleting a wpan interface via nl802154. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 2 ++ net/ieee802154/nl802154.c | 28 ++++++++++++++++++++++++++++ net/ieee802154/rdev-ops.h | 7 +++++++ net/mac802154/cfg.c | 9 +++++++++ net/mac802154/ieee802154_i.h | 6 ++++++ 5 files changed, 52 insertions(+) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 4a9bb0e3db2b..507ac9d3d38a 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -43,6 +43,8 @@ struct cfg802154_ops { const char *name, enum nl802154_iftype type, __le64 extended_addr); + int (*del_virtual_intf)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_pan_id)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u16 pan_id); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 49c4d8a5004a..6b9bc93944a6 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -583,6 +583,26 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) type, extended_addr); } +static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg802154_registered_device *rdev = info->user_ptr[0]; + struct wpan_dev *wpan_dev = info->user_ptr[1]; + + if (!rdev->ops->del_virtual_intf) + return -EOPNOTSUPP; + + /* If we remove a wpan device without a netdev then clear + * user_ptr[1] so that nl802154_post_doit won't dereference it + * to check if it needs to do dev_put(). Otherwise it crashes + * since the wpan_dev has been freed, unlike with a netdev where + * we need the dev_put() for the netdev to really be freed. + */ + if (!wpan_dev->netdev) + info->user_ptr[1] = NULL; + + return rdev_del_virtual_intf(rdev, wpan_dev); +} + static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) { struct cfg802154_registered_device *rdev = info->user_ptr[0]; @@ -858,6 +878,14 @@ static const struct genl_ops nl802154_ops[] = { .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | NL802154_FLAG_NEED_RTNL, }, + { + .cmd = NL802154_CMD_DEL_INTERFACE, + .doit = nl802154_del_interface, + .policy = nl802154_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | + NL802154_FLAG_NEED_RTNL, + }, { .cmd = NL802154_CMD_SET_CHANNEL, .doit = nl802154_set_channel, diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 06e97542dafb..40ffbc0d8b85 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -28,6 +28,13 @@ rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name, extended_addr); } +static inline int +rdev_del_virtual_intf(struct cfg802154_registered_device *rdev, + struct wpan_dev *wpan_dev) +{ + return rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev); +} + static inline int rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) { diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 568d712bfc8c..7def2625eaca 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -57,6 +57,14 @@ ieee802154_add_iface(struct wpan_phy *phy, const char *name, return 0; } +static int +ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev) +{ + ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev)); + + return 0; +} + static int ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) { @@ -191,6 +199,7 @@ const struct cfg802154_ops mac802154_config_ops = { .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated, .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated, .add_virtual_intf = ieee802154_add_iface, + .del_virtual_intf = ieee802154_del_iface, .set_channel = ieee802154_set_channel, .set_pan_id = ieee802154_set_pan_id, .set_short_addr = ieee802154_set_short_addr, diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index cc691637d24b..bebd70ffc7a3 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -115,6 +115,12 @@ IEEE802154_DEV_TO_SUB_IF(const struct net_device *dev) return netdev_priv(dev); } +static inline struct ieee802154_sub_if_data * +IEEE802154_WPAN_DEV_TO_SUB_IF(struct wpan_dev *wpan_dev) +{ + return container_of(wpan_dev, struct ieee802154_sub_if_data, wpan_dev); +} + static inline bool ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) { -- GitLab From cb41c8dd01d74d091618f72e28f0282f064a9f0a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:54 +0100 Subject: [PATCH 5004/9457] ieee802154: rename and move WPAN_NUM_ defines This patch moves the 802.15.4 constraints WPAN_NUM_ defines into "net/ieee802154.h" which should contain all necessary 802.15.4 related information. Also rename these defines to a common name which is IEEE802154_MAX_CHANNEL and IEEE802154_MAX_PAGE. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/linux/ieee802154.h | 3 +++ include/net/cfg802154.h | 11 ++--------- net/ieee802154/nl802154.c | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h index 5a40c0418438..6e82d888287c 100644 --- a/include/linux/ieee802154.h +++ b/include/linux/ieee802154.h @@ -39,6 +39,9 @@ #define IEEE802154_LIFS_PERIOD 40 #define IEEE802154_SIFS_PERIOD 12 +#define IEEE802154_MAX_CHANNEL 26 +#define IEEE802154_MAX_PAGE 31 + #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ #define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ #define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 507ac9d3d38a..228f1f7668f7 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -17,20 +17,13 @@ #ifndef __NET_CFG802154_H #define __NET_CFG802154_H +#include #include #include #include #include -/* According to the IEEE 802.15.4 stadard the upper most significant bits of - * the 32-bit channel bitmaps shall be used as an integer value to specify 32 - * possible channel pages. The lower 27 bits of the channel bit map shall be - * used as a bit mask to specify channel numbers within a channel page. - */ -#define WPAN_NUM_CHANNELS 27 -#define WPAN_NUM_PAGES 32 - struct wpan_phy; struct cfg802154_ops { @@ -81,7 +74,7 @@ struct wpan_phy { */ u8 current_channel; u8 current_page; - u32 channels_supported[32]; + u32 channels_supported[IEEE802154_MAX_PAGE + 1]; s8 transmit_power; u8 cca_mode; diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 6b9bc93944a6..b82b01669a67 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -245,7 +245,7 @@ nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev, if (!nl_page) return -ENOBUFS; - for (page = 0; page < WPAN_NUM_PAGES; page++) { + for (page = 0; page <= IEEE802154_MAX_PAGE; page++) { if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL, rdev->wpan_phy.channels_supported[page])) return -ENOBUFS; @@ -616,7 +616,7 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]); /* check 802.15.4 constraints */ - if (page >= WPAN_NUM_PAGES || channel >= WPAN_NUM_CHANNELS) + if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL) return -EINVAL; return rdev_set_channel(rdev, page, channel); -- GitLab From ee7b9053bd69ff43cbc87a9bb987f4d92dc2c29f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 17 Nov 2014 08:20:55 +0100 Subject: [PATCH 5005/9457] ieee802154: fix byteorder for short address and panid This patch changes the byteorder handling for short and panid handling. We now except to get little endian in nl802154 for these attributes. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- include/net/cfg802154.h | 4 ++-- net/ieee802154/nl802154.c | 8 ++++---- net/ieee802154/rdev-ops.h | 4 ++-- net/mac802154/cfg.c | 14 +++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 228f1f7668f7..7f713acfa106 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -40,9 +40,9 @@ struct cfg802154_ops { struct wpan_dev *wpan_dev); int (*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel); int (*set_pan_id)(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, u16 pan_id); + struct wpan_dev *wpan_dev, __le16 pan_id); int (*set_short_addr)(struct wpan_phy *wpan_phy, - struct wpan_dev *wpan_dev, u16 short_addr); + struct wpan_dev *wpan_dev, __le16 short_addr); int (*set_backoff_exponent)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, u8 min_be, u8 max_be); diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index b82b01669a67..889647744697 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -627,7 +627,7 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) struct cfg802154_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct wpan_dev *wpan_dev = dev->ieee802154_ptr; - u16 pan_id; + __le16 pan_id; /* conflict here while tx/rx calls */ if (netif_running(dev)) @@ -640,7 +640,7 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL802154_ATTR_PAN_ID]) return -EINVAL; - pan_id = nla_get_u16(info->attrs[NL802154_ATTR_PAN_ID]); + pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]); return rdev_set_pan_id(rdev, wpan_dev, pan_id); } @@ -650,7 +650,7 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) struct cfg802154_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct wpan_dev *wpan_dev = dev->ieee802154_ptr; - u16 short_addr; + __le16 short_addr; /* conflict here while tx/rx calls */ if (netif_running(dev)) @@ -663,7 +663,7 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL802154_ATTR_SHORT_ADDR]) return -EINVAL; - short_addr = nla_get_u16(info->attrs[NL802154_ATTR_SHORT_ADDR]); + short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]); return rdev_set_short_addr(rdev, wpan_dev, short_addr); } diff --git a/net/ieee802154/rdev-ops.h b/net/ieee802154/rdev-ops.h index 40ffbc0d8b85..aff54fbd9264 100644 --- a/net/ieee802154/rdev-ops.h +++ b/net/ieee802154/rdev-ops.h @@ -43,14 +43,14 @@ rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel) static inline int rdev_set_pan_id(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, u16 pan_id) + struct wpan_dev *wpan_dev, __le16 pan_id) { return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id); } static inline int rdev_set_short_addr(struct cfg802154_registered_device *rdev, - struct wpan_dev *wpan_dev, u16 short_addr) + struct wpan_dev *wpan_dev, __le16 short_addr) { return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr); } diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 7def2625eaca..c035708ada16 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -88,7 +88,7 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel) static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, - u16 pan_id) + __le16 pan_id) { ASSERT_RTNL(); @@ -99,10 +99,10 @@ ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, * * This could useful to simple deassociate an device. */ - if (pan_id == IEEE802154_PAN_ID_BROADCAST) + if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST)) return -EINVAL; - wpan_dev->pan_id = cpu_to_le16(pan_id); + wpan_dev->pan_id = pan_id; return 0; } @@ -125,7 +125,7 @@ ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy, static int ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, - u16 short_addr) + __le16 short_addr) { ASSERT_RTNL(); @@ -140,11 +140,11 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, * I think we should allow to set these settings but * don't allow to allow socket communication with it. */ - if (short_addr == IEEE802154_ADDR_SHORT_UNSPEC || - short_addr == IEEE802154_ADDR_SHORT_BROADCAST) + if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) || + short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST)) return -EINVAL; - wpan_dev->short_addr = cpu_to_le16(short_addr); + wpan_dev->short_addr = short_addr; return 0; } -- GitLab From 6fdaac1c1ab4fee1619145487c5aaf1bd44acc7b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Nov 2014 09:37:34 +0100 Subject: [PATCH 5006/9457] ASoC: adav80x: Replace w->codec with snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adav80x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index ce3cdca9fc62..b67480f1b1aa 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -212,7 +212,7 @@ static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = { static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = source->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); const char *clk; @@ -236,7 +236,7 @@ static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source, static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = source->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL; -- GitLab From de172051af78883a4a2e7897e7af58ba49353b99 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Nov 2014 09:37:35 +0100 Subject: [PATCH 5007/9457] ASoC: adau1373: Replace w->codec with snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1373.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 7c784ad3e8b2..783dcb57043a 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -551,7 +551,7 @@ static const struct snd_kcontrol_new adau1373_drc_controls[] = { static int adau1373_pll_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); unsigned int pll_id = w->name[3] - '1'; unsigned int val; @@ -823,7 +823,7 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = source->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); unsigned int dai; const char *clk; @@ -844,7 +844,7 @@ static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source, static int adau1373_check_src(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = source->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); unsigned int dai; -- GitLab From d69db7f7cd57fdfc6ac64c4c8679eb7b80c84fc7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 17 Nov 2014 09:37:36 +0100 Subject: [PATCH 5008/9457] ASoC: adau17x1: Replace w->codec with snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1761.c | 3 ++- sound/soc/codecs/adau1781.c | 2 +- sound/soc/codecs/adau17x1.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 5518ebd6947c..3dddb286d08d 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -255,7 +255,8 @@ static const struct snd_kcontrol_new adau1761_input_mux_control = static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct adau *adau = snd_soc_codec_get_drvdata(w->codec); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct adau *adau = snd_soc_codec_get_drvdata(codec); /* After any power changes have been made the dejitter circuit * has to be reinitialized. */ diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index e9fc00fb13dd..aa6a37cc44b7 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -174,7 +174,7 @@ static const struct snd_kcontrol_new adau1781_mono_mixer_controls[] = { static int adau1781_dejitter_fixup(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct adau *adau = snd_soc_codec_get_drvdata(codec); /* After any power changes have been made the dejitter circuit diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 3e16c1c64115..427ad77bfe56 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -61,7 +61,8 @@ static const struct snd_kcontrol_new adau17x1_controls[] = { static int adau17x1_pll_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct adau *adau = snd_soc_codec_get_drvdata(w->codec); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct adau *adau = snd_soc_codec_get_drvdata(codec); int ret; if (SND_SOC_DAPM_EVENT_ON(event)) { -- GitLab From 48b6bca6b7b8309697fc8a101793befe92d249d9 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Nov 2014 20:42:03 -0600 Subject: [PATCH 5009/9457] fs: add freeze_super/thaw_super fs hooks Currently, freezing a filesystem involves calling freeze_super, which locks sb->s_umount and then calls the fs-specific freeze_fs hook. This makes it hard for gfs2 (and potentially other cluster filesystems) to use the vfs freezing code to do freezes on all the cluster nodes. In order to communicate that a freeze has been requested, and to make sure that only one node is trying to freeze at a time, gfs2 uses a glock (sd_freeze_gl). The problem is that there is no hook for gfs2 to acquire this lock before calling freeze_super. This means that two nodes can attempt to freeze the filesystem by both calling freeze_super, acquiring the sb->s_umount lock, and then attempting to grab the cluster glock sd_freeze_gl. Only one will succeed, and the other will be stuck in freeze_super, making it impossible to finish freezing the node. To solve this problem, this patch adds the freeze_super and thaw_super hooks. If a filesystem implements these hooks, they are called instead of the vfs freeze_super and thaw_super functions. This means that every filesystem that implements these hooks must call the vfs freeze_super and thaw_super functions itself within the hook function to make use of the vfs freezing code. Reviewed-by: Jan Kara Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/block_dev.c | 10 ++++++++-- fs/ioctl.c | 6 +++++- include/linux/fs.h | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 1d9c9f3754f8..b48c41bf0f86 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -235,7 +235,10 @@ struct super_block *freeze_bdev(struct block_device *bdev) sb = get_active_super(bdev); if (!sb) goto out; - error = freeze_super(sb); + if (sb->s_op->freeze_super) + error = sb->s_op->freeze_super(sb); + else + error = freeze_super(sb); if (error) { deactivate_super(sb); bdev->bd_fsfreeze_count--; @@ -272,7 +275,10 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) if (!sb) goto out; - error = thaw_super(sb); + if (sb->s_op->thaw_super) + error = sb->s_op->thaw_super(sb); + else + error = thaw_super(sb); if (error) { bdev->bd_fsfreeze_count++; mutex_unlock(&bdev->bd_fsfreeze_mutex); diff --git a/fs/ioctl.c b/fs/ioctl.c index 8ac3fad36192..77c9a7812542 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -518,10 +518,12 @@ static int ioctl_fsfreeze(struct file *filp) return -EPERM; /* If filesystem doesn't support freeze feature, return. */ - if (sb->s_op->freeze_fs == NULL) + if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL) return -EOPNOTSUPP; /* Freeze */ + if (sb->s_op->freeze_super) + return sb->s_op->freeze_super(sb); return freeze_super(sb); } @@ -533,6 +535,8 @@ static int ioctl_fsthaw(struct file *filp) return -EPERM; /* Thaw */ + if (sb->s_op->thaw_super) + return sb->s_op->thaw_super(sb); return thaw_super(sb); } diff --git a/include/linux/fs.h b/include/linux/fs.h index 9ab779e8a63c..b4a1d73c0d5d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1577,7 +1577,9 @@ struct super_operations { void (*evict_inode) (struct inode *); void (*put_super) (struct super_block *); int (*sync_fs)(struct super_block *sb, int wait); + int (*freeze_super) (struct super_block *); int (*freeze_fs) (struct super_block *); + int (*thaw_super) (struct super_block *); int (*unfreeze_fs) (struct super_block *); int (*statfs) (struct dentry *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); -- GitLab From 2e60d7683c8d2ea21317f6d9f4cd3bf5428ce162 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Nov 2014 20:42:04 -0600 Subject: [PATCH 5010/9457] GFS2: update freeze code to use freeze/thaw_super on all nodes The current gfs2 freezing code is considerably more complicated than it should be because it doesn't use the vfs freezing code on any node except the one that begins the freeze. This is because it needs to acquire a cluster glock before calling the vfs code to prevent a deadlock, and without the new freeze_super and thaw_super hooks, that was impossible. To deal with the issue, gfs2 had to do some hacky locking tricks to make sure that a frozen node couldn't be holding on a lock it needed to do the unfreeze ioctl. This patch makes use of the new hooks to simply the gfs2 locking code. Now, all the nodes in the cluster freeze and thaw in exactly the same way. Every node in the cluster caches the freeze glock in the shared state. The new freeze_super hook allows the freezing node to grab this freeze glock in the exclusive state without first calling the vfs freeze_super function. All the nodes in the cluster see this lock change, and call the vfs freeze_super function. The vfs locking code guarantees that the nodes can't get stuck holding the glocks necessary to unfreeze the system. To unfreeze, the freezing node uses the new thaw_super hook to drop the freeze glock. Again, all the nodes notice this, reacquire the glock in shared mode and call the vfs thaw_super function. Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse --- fs/gfs2/glops.c | 26 +++++----- fs/gfs2/glops.h | 2 + fs/gfs2/incore.h | 18 ++++--- fs/gfs2/inode.c | 40 ++++------------ fs/gfs2/log.c | 42 ++++++++-------- fs/gfs2/main.c | 11 ++++- fs/gfs2/ops_fstype.c | 18 ++----- fs/gfs2/super.c | 112 +++++++++++++++++++++++++++++-------------- fs/gfs2/super.h | 1 + fs/gfs2/trans.c | 17 +++++-- 10 files changed, 161 insertions(+), 126 deletions(-) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 1cc0bba6313f..fe91951c3361 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -28,6 +28,8 @@ #include "trans.h" #include "dir.h" +struct workqueue_struct *gfs2_freeze_wq; + static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) { fs_err(gl->gl_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page state 0x%lx\n", @@ -94,11 +96,8 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) * on the stack */ tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); tr.tr_ip = _RET_IP_; - sb_start_intwrite(sdp->sd_vfs); - if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) { - sb_end_intwrite(sdp->sd_vfs); + if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) return; - } WARN_ON_ONCE(current->journal_info); current->journal_info = &tr; @@ -469,20 +468,19 @@ static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) static void freeze_go_sync(struct gfs2_glock *gl) { + int error = 0; struct gfs2_sbd *sdp = gl->gl_sbd; - DEFINE_WAIT(wait); if (gl->gl_state == LM_ST_SHARED && test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { - atomic_set(&sdp->sd_log_freeze, 1); - wake_up(&sdp->sd_logd_waitq); - do { - prepare_to_wait(&sdp->sd_log_frozen_wait, &wait, - TASK_UNINTERRUPTIBLE); - if (atomic_read(&sdp->sd_log_freeze)) - io_schedule(); - } while(atomic_read(&sdp->sd_log_freeze)); - finish_wait(&sdp->sd_log_frozen_wait, &wait); + atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); + error = freeze_super(sdp->sd_vfs); + if (error) { + printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error); + gfs2_assert_withdraw(sdp, 0); + } + queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); + gfs2_log_flush(sdp, NULL, FREEZE_FLUSH); } } diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h index 7455d2629bcb..8ed1857c1a8d 100644 --- a/fs/gfs2/glops.h +++ b/fs/gfs2/glops.h @@ -12,6 +12,8 @@ #include "incore.h" +extern struct workqueue_struct *gfs2_freeze_wq; + extern const struct gfs2_glock_operations gfs2_meta_glops; extern const struct gfs2_glock_operations gfs2_inode_glops; extern const struct gfs2_glock_operations gfs2_rgrp_glops; diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 1b899187be5a..7a2dbbc0d634 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -588,6 +588,12 @@ enum { SDF_SKIP_DLM_UNLOCK = 8, }; +enum gfs2_freeze_state { + SFS_UNFROZEN = 0, + SFS_STARTING_FREEZE = 1, + SFS_FROZEN = 2, +}; + #define GFS2_FSNAME_LEN 256 struct gfs2_inum_host { @@ -685,6 +691,7 @@ struct gfs2_sbd { struct gfs2_holder sd_live_gh; struct gfs2_glock *sd_rename_gl; struct gfs2_glock *sd_freeze_gl; + struct work_struct sd_freeze_work; wait_queue_head_t sd_glock_wait; atomic_t sd_glock_disposal; struct completion sd_locking_init; @@ -789,6 +796,9 @@ struct gfs2_sbd { wait_queue_head_t sd_log_flush_wait; int sd_log_error; + atomic_t sd_reserving_log; + wait_queue_head_t sd_reserving_log_wait; + unsigned int sd_log_flush_head; u64 sd_log_flush_wrapped; @@ -798,12 +808,8 @@ struct gfs2_sbd { /* For quiescing the filesystem */ struct gfs2_holder sd_freeze_gh; - struct gfs2_holder sd_freeze_root_gh; - struct gfs2_holder sd_thaw_gh; - atomic_t sd_log_freeze; - atomic_t sd_frozen_root; - wait_queue_head_t sd_frozen_root_wait; - wait_queue_head_t sd_log_frozen_wait; + atomic_t sd_freeze_state; + struct mutex sd_freeze_mutex; char sd_fsname[GFS2_FSNAME_LEN]; char sd_table_name[GFS2_FSNAME_LEN]; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b41b5c7898da..04065e5af4b6 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1618,26 +1618,18 @@ int gfs2_permission(struct inode *inode, int mask) { struct gfs2_inode *ip; struct gfs2_holder i_gh; - struct gfs2_sbd *sdp = GFS2_SB(inode); int error; int unlock = 0; - int frozen_root = 0; ip = GFS2_I(inode); if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { - if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && - inode == sdp->sd_root_dir->d_inode && - atomic_inc_not_zero(&sdp->sd_frozen_root))) - frozen_root = 1; - else { - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return error; - unlock = 1; - } + if (mask & MAY_NOT_BLOCK) + return -ECHILD; + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + unlock = 1; } if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) @@ -1646,8 +1638,6 @@ int gfs2_permission(struct inode *inode, int mask) error = generic_permission(inode, mask); if (unlock) gfs2_glock_dq_uninit(&i_gh); - else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root)) - wake_up(&sdp->sd_frozen_root_wait); return error; } @@ -1820,29 +1810,19 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, struct inode *inode = dentry->d_inode; struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_holder gh; - struct gfs2_sbd *sdp = GFS2_SB(inode); int error; int unlock = 0; - int frozen_root = 0; if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { - if (unlikely(gfs2_glock_is_held_excl(sdp->sd_freeze_gl) && - inode == sdp->sd_root_dir->d_inode && - atomic_inc_not_zero(&sdp->sd_frozen_root))) - frozen_root = 1; - else { - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); - if (error) - return error; - unlock = 1; - } + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + if (error) + return error; + unlock = 1; } generic_fillattr(inode, stat); if (unlock) gfs2_glock_dq_uninit(&gh); - else if (frozen_root && atomic_dec_and_test(&sdp->sd_frozen_root)) - wake_up(&sdp->sd_frozen_root_wait); return 0; } diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 3966fadbcebd..536e7a6252cd 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -339,6 +339,7 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks) int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) { + int ret = 0; unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize); unsigned wanted = blks + reserved_blks; DEFINE_WAIT(wait); @@ -362,9 +363,13 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) } while(free_blocks <= wanted); finish_wait(&sdp->sd_log_waitq, &wait); } + atomic_inc(&sdp->sd_reserving_log); if (atomic_cmpxchg(&sdp->sd_log_blks_free, free_blocks, - free_blocks - blks) != free_blocks) + free_blocks - blks) != free_blocks) { + if (atomic_dec_and_test(&sdp->sd_reserving_log)) + wake_up(&sdp->sd_reserving_log_wait); goto retry; + } trace_gfs2_log_blocks(sdp, -blks); /* @@ -377,9 +382,11 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) down_read(&sdp->sd_log_flush_lock); if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) { gfs2_log_release(sdp, blks); - return -EROFS; + ret = -EROFS; } - return 0; + if (atomic_dec_and_test(&sdp->sd_reserving_log)) + wake_up(&sdp->sd_reserving_log_wait); + return ret; } /** @@ -652,9 +659,12 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) u32 hash; int rw = WRITE_FLUSH_FUA | REQ_META; struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); + enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); lh = page_address(page); clear_page(lh); + gfs2_assert_withdraw(sdp, (state != SFS_FROZEN)); + tail = current_tail(sdp); lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); @@ -695,6 +705,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, enum gfs2_flush_type type) { struct gfs2_trans *tr; + enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); down_write(&sdp->sd_log_flush_lock); @@ -713,8 +724,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, INIT_LIST_HEAD(&tr->tr_ail1_list); INIT_LIST_HEAD(&tr->tr_ail2_list); tr->tr_first = sdp->sd_log_flush_head; + if (unlikely (state == SFS_FROZEN)) + gfs2_assert_withdraw(sdp, !tr->tr_num_buf_new && !tr->tr_num_databuf_new); } + if (unlikely(state == SFS_FROZEN)) + gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); @@ -745,8 +760,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, spin_unlock(&sdp->sd_ail_lock); gfs2_log_unlock(sdp); - if (atomic_read(&sdp->sd_log_freeze)) - type = FREEZE_FLUSH; if (type != NORMAL_FLUSH) { if (!sdp->sd_log_idle) { for (;;) { @@ -763,21 +776,8 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, } if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH) gfs2_log_shutdown(sdp); - if (type == FREEZE_FLUSH) { - int error; - - atomic_set(&sdp->sd_log_freeze, 0); - wake_up(&sdp->sd_log_frozen_wait); - error = gfs2_glock_nq_init(sdp->sd_freeze_gl, - LM_ST_SHARED, 0, - &sdp->sd_thaw_gh); - if (error) { - printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error); - gfs2_assert_withdraw(sdp, 0); - } - else - gfs2_glock_dq_uninit(&sdp->sd_thaw_gh); - } + if (type == FREEZE_FLUSH) + atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); } trace_gfs2_log_flush(sdp, 0); @@ -888,7 +888,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) { - return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1) || atomic_read(&sdp->sd_log_freeze)); + return (atomic_read(&sdp->sd_log_pinned) >= atomic_read(&sdp->sd_log_thresh1)); } static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 82b6ac829656..241a399bf83d 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -30,6 +30,7 @@ #include "quota.h" #include "recovery.h" #include "dir.h" +#include "glops.h" struct workqueue_struct *gfs2_control_wq; @@ -161,9 +162,14 @@ static int __init init_gfs2_fs(void) if (!gfs2_control_wq) goto fail_recovery; + gfs2_freeze_wq = alloc_workqueue("freeze_workqueue", 0, 0); + + if (!gfs2_freeze_wq) + goto fail_control; + gfs2_page_pool = mempool_create_page_pool(64, 0); if (!gfs2_page_pool) - goto fail_control; + goto fail_freeze; gfs2_register_debugfs(); @@ -171,6 +177,8 @@ static int __init init_gfs2_fs(void) return 0; +fail_freeze: + destroy_workqueue(gfs2_freeze_wq); fail_control: destroy_workqueue(gfs2_control_wq); fail_recovery: @@ -224,6 +232,7 @@ static void __exit exit_gfs2_fs(void) unregister_filesystem(&gfs2meta_fs_type); destroy_workqueue(gfs_recovery_wq); destroy_workqueue(gfs2_control_wq); + destroy_workqueue(gfs2_freeze_wq); list_lru_destroy(&gfs2_qd_lru); rcu_barrier(); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index d3eae244076e..b5803acb8818 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -129,11 +129,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) init_rwsem(&sdp->sd_log_flush_lock); atomic_set(&sdp->sd_log_in_flight, 0); + atomic_set(&sdp->sd_reserving_log, 0); + init_waitqueue_head(&sdp->sd_reserving_log_wait); init_waitqueue_head(&sdp->sd_log_flush_wait); - init_waitqueue_head(&sdp->sd_log_frozen_wait); - atomic_set(&sdp->sd_log_freeze, 0); - atomic_set(&sdp->sd_frozen_root, 0); - init_waitqueue_head(&sdp->sd_frozen_root_wait); + atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN); + mutex_init(&sdp->sd_freeze_mutex); return sdp; } @@ -760,15 +760,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags); gfs2_glock_dq_uninit(&ji_gh); jindex = 0; - if (!sdp->sd_args.ar_spectator) { - error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, - &sdp->sd_thaw_gh); - if (error) { - fs_err(sdp, "can't acquire freeze glock: %d\n", error); - goto fail_jinode_gh; - } - } - gfs2_glock_dq_uninit(&sdp->sd_thaw_gh); + INIT_WORK(&sdp->sd_freeze_work, gfs2_freeze_func); return 0; fail_jinode_gh: diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index a346f56c4c6d..5b327f837de7 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -399,7 +400,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) { struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); struct gfs2_glock *j_gl = ip->i_gl; - struct gfs2_holder thaw_gh; + struct gfs2_holder freeze_gh; struct gfs2_log_header_host head; int error; @@ -408,7 +409,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) return error; error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, - &thaw_gh); + &freeze_gh); if (error) goto fail_threads; @@ -434,13 +435,13 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - gfs2_glock_dq_uninit(&thaw_gh); + gfs2_glock_dq_uninit(&freeze_gh); return 0; fail: - thaw_gh.gh_flags |= GL_NOCACHE; - gfs2_glock_dq_uninit(&thaw_gh); + freeze_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_dq_uninit(&freeze_gh); fail_threads: kthread_stop(sdp->sd_quotad_process); kthread_stop(sdp->sd_logd_process); @@ -580,14 +581,15 @@ int gfs2_statfs_sync(struct super_block *sb, int type) struct buffer_head *m_bh, *l_bh; int error; + sb_start_write(sb); error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, &gh); if (error) - return error; + goto out; error = gfs2_meta_inode_buffer(m_ip, &m_bh); if (error) - goto out; + goto out_unlock; spin_lock(&sdp->sd_statfs_spin); gfs2_statfs_change_in(m_sc, m_bh->b_data + @@ -615,8 +617,10 @@ int gfs2_statfs_sync(struct super_block *sb, int type) brelse(l_bh); out_bh: brelse(m_bh); -out: +out_unlock: gfs2_glock_dq_uninit(&gh); +out: + sb_end_write(sb); return error; } @@ -643,14 +647,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct lfcc *lfcc; LIST_HEAD(list); struct gfs2_log_header_host lh; - struct gfs2_inode *dip = GFS2_I(sdp->sd_root_dir->d_inode); int error; - error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, - &sdp->sd_freeze_root_gh); - if (error) - return error; - atomic_set(&sdp->sd_frozen_root, 1); list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); if (!lfcc) { @@ -692,11 +690,6 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, gfs2_glock_dq_uninit(&lfcc->gh); kfree(lfcc); } - if (error) { - atomic_dec(&sdp->sd_frozen_root); - wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0); - gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh); - } return error; } @@ -834,18 +827,14 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) { - struct gfs2_holder thaw_gh; + struct gfs2_holder freeze_gh; int error; error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE, - &thaw_gh); + &freeze_gh); if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) return error; - down_write(&sdp->sd_log_flush_lock); - clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - up_write(&sdp->sd_log_flush_lock); - kthread_stop(sdp->sd_quotad_process); kthread_stop(sdp->sd_logd_process); @@ -853,11 +842,16 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0); + down_write(&sdp->sd_log_flush_lock); + clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + up_write(&sdp->sd_log_flush_lock); + gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); + wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); - if (thaw_gh.gh_gl) - gfs2_glock_dq_uninit(&thaw_gh); + if (freeze_gh.gh_gl) + gfs2_glock_dq_uninit(&freeze_gh); gfs2_quota_cleanup(sdp); @@ -943,11 +937,41 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) struct gfs2_sbd *sdp = sb->s_fs_info; gfs2_quota_sync(sb, -1); - if (wait && sdp && !atomic_read(&sdp->sd_log_freeze)) + if (wait && sdp) gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); return 0; } +void gfs2_freeze_func(struct work_struct *work) +{ + int error; + struct gfs2_holder freeze_gh; + struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_freeze_work); + struct super_block *sb = sdp->sd_vfs; + + atomic_inc(&sb->s_active); + error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, + &freeze_gh); + if (error) { + printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error); + gfs2_assert_withdraw(sdp, 0); + } + else { + atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN); + error = thaw_super(sb); + if (error) { + printk(KERN_INFO "GFS2: couldn't thaw filesystem: %d\n", + error); + gfs2_assert_withdraw(sdp, 0); + } + if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) + freeze_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_dq_uninit(&freeze_gh); + } + deactivate_super(sb); + return; +} + /** * gfs2_freeze - prevent further writes to the filesystem * @sb: the VFS structure for the filesystem @@ -957,10 +981,16 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) static int gfs2_freeze(struct super_block *sb) { struct gfs2_sbd *sdp = sb->s_fs_info; - int error; + int error = 0; - if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) - return -EINVAL; + mutex_lock(&sdp->sd_freeze_mutex); + if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) + goto out; + + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + error = -EINVAL; + goto out; + } for (;;) { error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); @@ -980,7 +1010,10 @@ static int gfs2_freeze(struct super_block *sb) fs_err(sdp, "retrying...\n"); msleep(1000); } - return 0; + error = 0; +out: + mutex_unlock(&sdp->sd_freeze_mutex); + return error; } /** @@ -993,10 +1026,15 @@ static int gfs2_unfreeze(struct super_block *sb) { struct gfs2_sbd *sdp = sb->s_fs_info; + mutex_lock(&sdp->sd_freeze_mutex); + if (atomic_read(&sdp->sd_freeze_state) != SFS_FROZEN || + sdp->sd_freeze_gh.gh_gl == NULL) { + mutex_unlock(&sdp->sd_freeze_mutex); + return 0; + } + gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); - atomic_dec(&sdp->sd_frozen_root); - wait_event(sdp->sd_frozen_root_wait, atomic_read(&sdp->sd_frozen_root) == 0); - gfs2_glock_dq_uninit(&sdp->sd_freeze_root_gh); + mutex_unlock(&sdp->sd_freeze_mutex); return 0; } @@ -1618,8 +1656,8 @@ const struct super_operations gfs2_super_ops = { .evict_inode = gfs2_evict_inode, .put_super = gfs2_put_super, .sync_fs = gfs2_sync_fs, - .freeze_fs = gfs2_freeze, - .unfreeze_fs = gfs2_unfreeze, + .freeze_super = gfs2_freeze, + .thaw_super = gfs2_unfreeze, .statfs = gfs2_statfs, .remount_fs = gfs2_remount_fs, .drop_inode = gfs2_drop_inode, diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 90e3322ffa10..73c97dccae21 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h @@ -45,6 +45,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, struct buffer_head *l_bh); extern int gfs2_statfs_sync(struct super_block *sb, int type); +extern void gfs2_freeze_func(struct work_struct *work); extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 42bfd3361979..88bff2430669 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -89,14 +89,17 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) { struct gfs2_trans *tr = current->journal_info; s64 nbuf; + int alloced = tr->tr_alloced; + BUG_ON(!tr); current->journal_info = NULL; if (!tr->tr_touched) { gfs2_log_release(sdp, tr->tr_reserved); - if (tr->tr_alloced) + if (alloced) { kfree(tr); - sb_end_intwrite(sdp->sd_vfs); + sb_end_intwrite(sdp->sd_vfs); + } return; } @@ -109,13 +112,14 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) gfs2_print_trans(tr); gfs2_log_commit(sdp, tr); - if (tr->tr_alloced && !tr->tr_attached) + if (alloced && !tr->tr_attached) kfree(tr); up_read(&sdp->sd_log_flush_lock); if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); - sb_end_intwrite(sdp->sd_vfs); + if (alloced) + sb_end_intwrite(sdp->sd_vfs); } static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl, @@ -192,6 +196,7 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) { struct gfs2_meta_header *mh; struct gfs2_trans *tr; + enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); tr = current->journal_info; tr->tr_touched = 1; @@ -205,6 +210,10 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) (unsigned long long)bd->bd_bh->b_blocknr); BUG(); } + if (unlikely(state == SFS_FROZEN)) { + printk(KERN_INFO "GFS2:adding buf while frozen\n"); + gfs2_assert_withdraw(sdp, 0); + } gfs2_pin(sdp, bd->bd_bh); mh->__pad0 = cpu_to_be64(0); mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); -- GitLab From eb826a35d2578106cf6fbfb2a83eedd1c0c2c415 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Mon, 17 Nov 2014 14:36:40 +0800 Subject: [PATCH 5011/9457] ASoC: Intel: add missing ACPI device table The ACPI device table will generate the driver module alias for Intel audio devices enumerated from ACPI. Signed-off-by: Mengdong Lin Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_acpi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index 2b1c5d907014..b261821163fa 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c @@ -342,6 +342,8 @@ static const struct acpi_device_id sst_acpi_ids[] = { { }, }; +MODULE_DEVICE_TABLE(acpi, sst_acpi_ids); + static struct platform_driver sst_acpi_driver = { .driver = { .name = "intel_sst_acpi", -- GitLab From 6d3efa40790ad1286cfa032df6d3c9a2748a695e Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Sat, 15 Nov 2014 22:51:46 +0300 Subject: [PATCH 5012/9457] ASoC: pxa: prepare/unprepare clocks in pxa-ssp Change clk_enable/disable() calls to clk_prepare_enable() and clk_disable_unrepapre(). Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Mark Brown --- sound/soc/pxa/pxa-ssp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a8e097433074..cbba063a7210 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -97,7 +97,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, int ret = 0; if (!cpu_dai->active) { - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); pxa_ssp_disable(ssp); } @@ -121,7 +121,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, if (!cpu_dai->active) { pxa_ssp_disable(ssp); - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); } kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); @@ -136,7 +136,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) struct ssp_device *ssp = priv->ssp; if (!cpu_dai->active) - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0); priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1); @@ -144,7 +144,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) priv->psp = __raw_readl(ssp->mmio_base + SSPSP); pxa_ssp_disable(ssp); - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); return 0; } @@ -154,7 +154,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) struct ssp_device *ssp = priv->ssp; uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); __raw_writel(sssr, ssp->mmio_base + SSSR); __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); @@ -165,7 +165,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) if (cpu_dai->active) pxa_ssp_enable(ssp); else - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); return 0; } @@ -256,11 +256,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, /* The SSP clock must be disabled when changing SSP clock mode * on PXA2xx. On PXA3xx it must be enabled when doing so. */ if (ssp->type != PXA3xx_SSP) - clk_disable(ssp->clk); + clk_disable_unprepare(ssp->clk); val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; pxa_ssp_write_reg(ssp, SSCR0, val); if (ssp->type != PXA3xx_SSP) - clk_enable(ssp->clk); + clk_prepare_enable(ssp->clk); return 0; } -- GitLab From f2a81036516e2b97c07c49dd6d51d36bfa43593d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 14 Nov 2014 10:46:45 +0100 Subject: [PATCH 5013/9457] kvm: commonize allocation of the new memory slots The two kmemdup invocations can be unified. I find that the new placement of the comment makes it easier to see what happens. Reviewed-by: Igor Mammedov Reviewed-by: Takuya Yoshikawa Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index eae07f97ecf7..7fc77c0f98fb 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -866,11 +866,12 @@ int __kvm_set_memory_region(struct kvm *kvm, goto out_free; } + slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), + GFP_KERNEL); + if (!slots) + goto out_free; + if ((change == KVM_MR_DELETE) || (change == KVM_MR_MOVE)) { - slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), - GFP_KERNEL); - if (!slots) - goto out_free; slot = id_to_memslot(slots, mem->slot); slot->flags |= KVM_MEMSLOT_INVALID; @@ -886,6 +887,12 @@ int __kvm_set_memory_region(struct kvm *kvm, * - kvm_is_visible_gfn (mmu_check_roots) */ kvm_arch_flush_shadow_memslot(kvm, slot); + + /* + * We can re-use the old_memslots from above, the only difference + * from the currently installed memslots is the invalid flag. This + * will get overwritten by update_memslots anyway. + */ slots = old_memslots; } @@ -893,19 +900,6 @@ int __kvm_set_memory_region(struct kvm *kvm, if (r) goto out_slots; - r = -ENOMEM; - /* - * We can re-use the old_memslots from above, the only difference - * from the currently installed memslots is the invalid flag. This - * will get overwritten by update_memslots anyway. - */ - if (!slots) { - slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots), - GFP_KERNEL); - if (!slots) - goto out_free; - } - /* actual memory is freed via old in kvm_free_physmem_slot below */ if (change == KVM_MR_DELETE) { new.dirty_bitmap = NULL; -- GitLab From 5cc150279936a618187c42966a8a2f09177ac80a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 14 Nov 2014 10:55:31 +0100 Subject: [PATCH 5014/9457] kvm: simplify update_memslots invocation The update_memslots invocation is only needed in one case. Make the code clearer by moving it to __kvm_set_memory_region, and removing the wrapper around insert_memslot. Reviewed-by: Igor Mammedov Reviewed-by: Takuya Yoshikawa Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7fc77c0f98fb..751ece6a595c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -674,8 +674,8 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) * takes advantage of having initially sorted array and * known changed memslot position. */ -static void insert_memslot(struct kvm_memslots *slots, - struct kvm_memory_slot *new) +static void update_memslots(struct kvm_memslots *slots, + struct kvm_memory_slot *new) { int id = new->id; int i = slots->id_to_index[id]; @@ -704,14 +704,6 @@ static void insert_memslot(struct kvm_memslots *slots, slots->id_to_index[mslots[i].id] = i; } -static void update_memslots(struct kvm_memslots *slots, - struct kvm_memory_slot *new) -{ - if (new) { - insert_memslot(slots, new); - } -} - static int check_memory_region_flags(struct kvm_userspace_memory_region *mem) { u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES; @@ -727,7 +719,7 @@ static int check_memory_region_flags(struct kvm_userspace_memory_region *mem) } static struct kvm_memslots *install_new_memslots(struct kvm *kvm, - struct kvm_memslots *slots, struct kvm_memory_slot *new) + struct kvm_memslots *slots) { struct kvm_memslots *old_memslots = kvm->memslots; @@ -738,7 +730,6 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, WARN_ON(old_memslots->generation & 1); slots->generation = old_memslots->generation + 1; - update_memslots(slots, new); rcu_assign_pointer(kvm->memslots, slots); synchronize_srcu_expedited(&kvm->srcu); @@ -875,7 +866,7 @@ int __kvm_set_memory_region(struct kvm *kvm, slot = id_to_memslot(slots, mem->slot); slot->flags |= KVM_MEMSLOT_INVALID; - old_memslots = install_new_memslots(kvm, slots, NULL); + old_memslots = install_new_memslots(kvm, slots); /* slot was deleted or moved, clear iommu mapping */ kvm_iommu_unmap_pages(kvm, &old); @@ -906,7 +897,8 @@ int __kvm_set_memory_region(struct kvm *kvm, memset(&new.arch, 0, sizeof(new.arch)); } - old_memslots = install_new_memslots(kvm, slots, &new); + update_memslots(slots, &new); + old_memslots = install_new_memslots(kvm, slots); kvm_arch_commit_memory_region(kvm, mem, &old, change); -- GitLab From 173beedc1601f51dae9d579aa7a414c5aa8f700b Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 2 Nov 2014 11:54:54 +0200 Subject: [PATCH 5015/9457] KVM: x86: Software disabled APIC should still deliver NMIs Currently, the APIC logical map does not consider VCPUs whose local-apic is software-disabled. However, NMIs, INIT, etc. should still be delivered to such VCPUs. Therefore, the APIC mode should first be determined, and then the map, considering all VCPUs should be constructed. To address this issue, first find the APIC mode, and only then construct the logical map. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 344e7d36d0e8..c98b44d0ffe6 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -156,8 +156,6 @@ static void recalculate_apic_map(struct kvm *kvm) kvm_for_each_vcpu(i, vcpu, kvm) { struct kvm_lapic *apic = vcpu->arch.apic; - u16 cid, lid; - u32 ldr; if (!kvm_apic_present(vcpu)) continue; @@ -175,13 +173,22 @@ static void recalculate_apic_map(struct kvm *kvm) new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; new->lid_mask = 0xffff; new->broadcast = X2APIC_BROADCAST; - } else if (kvm_apic_sw_enabled(apic) && - !new->cid_mask /* flat mode */ && - kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { - new->cid_shift = 4; - new->cid_mask = 0xf; - new->lid_mask = 0xf; + break; + } else if (kvm_apic_sw_enabled(apic)) { + if (kvm_apic_get_reg(apic, APIC_DFR) == + APIC_DFR_CLUSTER) { + new->cid_shift = 4; + new->cid_mask = 0xf; + new->lid_mask = 0xf; + } + break; } + } + + kvm_for_each_vcpu(i, vcpu, kvm) { + struct kvm_lapic *apic = vcpu->arch.apic; + u16 cid, lid; + u32 ldr; new->phys_map[kvm_apic_id(apic)] = apic; -- GitLab From a3e339e1cec899908f516a4ebde64cac500b0c45 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 6 Nov 2014 10:51:45 +0100 Subject: [PATCH 5016/9457] KVM: compute correct map even if all APICs are software disabled Logical destination mode can be used to send NMI IPIs even when all APICs are software disabled, so if all APICs are software disabled we should still look at the DFRs. So the DFRs should all be the same, even if some or all APICs are software disabled. However, the SDM does not say this, so tweak the logic as follows: - if one APIC is enabled and has LDR != 0, use that one to build the map. This picks the right DFR in case an OS is only setting it for the software-enabled APICs, or in case an OS is using logical addressing on some APICs while leaving the rest in reset state (using LDR was suggested by Radim). - if all APICs are disabled, pick a random one to build the map. We use the last one with LDR != 0 for simplicity. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index c98b44d0ffe6..6e8ce5a1a05d 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -160,29 +160,34 @@ static void recalculate_apic_map(struct kvm *kvm) if (!kvm_apic_present(vcpu)) continue; - /* - * All APICs have to be configured in the same mode by an OS. - * We take advatage of this while building logical id loockup - * table. After reset APICs are in xapic/flat mode, so if we - * find apic with different setting we assume this is the mode - * OS wants all apics to be in; build lookup table accordingly. - */ if (apic_x2apic_mode(apic)) { new->ldr_bits = 32; new->cid_shift = 16; new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; new->lid_mask = 0xffff; new->broadcast = X2APIC_BROADCAST; - break; - } else if (kvm_apic_sw_enabled(apic)) { + } else if (kvm_apic_get_reg(apic, APIC_LDR)) { if (kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { new->cid_shift = 4; new->cid_mask = 0xf; new->lid_mask = 0xf; + } else { + new->cid_shift = 8; + new->cid_mask = 0; + new->lid_mask = 0xff; } - break; } + + /* + * All APICs have to be configured in the same mode by an OS. + * We take advatage of this while building logical id loockup + * table. After reset APICs are in software disabled mode, so if + * we find apic with different setting we assume this is the mode + * OS wants all apics to be in; build lookup table accordingly. + */ + if (kvm_apic_sw_enabled(apic)) + break; } kvm_for_each_vcpu(i, vcpu, kvm) { -- GitLab From f210f7572bedf3320599e8b2d8e8ec2d96270d0b Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Sun, 16 Nov 2014 23:49:07 +0200 Subject: [PATCH 5017/9457] KVM: x86: Fix lost interrupt on irr_pending race apic_find_highest_irr assumes irr_pending is set if any vector in APIC_IRR is set. If this assumption is broken and apicv is disabled, the injection of interrupts may be deferred until another interrupt is delivered to the guest. Ultimately, if no other interrupt should be injected to that vCPU, the pending interrupt may be lost. commit 56cc2406d68c ("KVM: nVMX: fix "acknowledge interrupt on exit" when APICv is in use") changed the behavior of apic_clear_irr so irr_pending is cleared after setting APIC_IRR vector. After this commit, if apic_set_irr and apic_clear_irr run simultaneously, a race may occur, resulting in APIC_IRR vector set, and irr_pending cleared. In the following example, assume a single vector is set in IRR prior to calling apic_clear_irr: apic_set_irr apic_clear_irr ------------ -------------- apic->irr_pending = true; apic_clear_vector(...); vec = apic_search_irr(apic); // => vec == -1 apic_set_vector(...); apic->irr_pending = (vec != -1); // => apic->irr_pending == false Nonetheless, it appears the race might even occur prior to this commit: apic_set_irr apic_clear_irr ------------ -------------- apic->irr_pending = true; apic->irr_pending = false; apic_clear_vector(...); if (apic_search_irr(apic) != -1) apic->irr_pending = true; // => apic->irr_pending == false apic_set_vector(...); Fixing this issue by: 1. Restoring the previous behavior of apic_clear_irr: clear irr_pending, call apic_clear_vector, and then if APIC_IRR is non-zero, set irr_pending. 2. On apic_set_irr: first call apic_set_vector, then set irr_pending. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 6e8ce5a1a05d..e0e5642dae41 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -341,8 +341,12 @@ EXPORT_SYMBOL_GPL(kvm_apic_update_irr); static inline void apic_set_irr(int vec, struct kvm_lapic *apic) { - apic->irr_pending = true; apic_set_vector(vec, apic->regs + APIC_IRR); + /* + * irr_pending must be true if any interrupt is pending; set it after + * APIC_IRR to avoid race with apic_clear_irr + */ + apic->irr_pending = true; } static inline int apic_search_irr(struct kvm_lapic *apic) @@ -374,13 +378,15 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) vcpu = apic->vcpu; - apic_clear_vector(vec, apic->regs + APIC_IRR); - if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) + if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) { /* try to update RVI */ + apic_clear_vector(vec, apic->regs + APIC_IRR); kvm_make_request(KVM_REQ_EVENT, vcpu); - else { - vec = apic_search_irr(apic); - apic->irr_pending = (vec != -1); + } else { + apic->irr_pending = false; + apic_clear_vector(vec, apic->regs + APIC_IRR); + if (apic_search_irr(apic) != -1) + apic->irr_pending = true; } } -- GitLab From e7e26bc75ba58ab85f329787cb072cf67dd5407f Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:15 +0200 Subject: [PATCH 5018/9457] can: c_can: Add timeout to c_can_hw_raminit_ti() TI's RAMINIT DONE mechanism is buggy on AM43xx SoC and may not always be set after the START bit is set. Although it seems to work fine even in that case. So add a timeout mechanism to c_can_hw_raminit_wait_ti(). Don't bail out in that failure case but just print an error message. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can_platform.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index fb279d6ae484..106c203fc5eb 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -75,10 +75,19 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv, static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask, u32 val) { + int timeout = 0; + /* We look only at the bits of our instance. */ val &= mask; - while ((readl(priv->raminit_ctrlreg) & mask) != val) + while ((readl(priv->raminit_ctrlreg) & mask) != val) { udelay(1); + timeout++; + + if (timeout == 1000) { + dev_err(&priv->dev->dev, "%s: time out\n", __func__); + break; + } + } } static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable) -- GitLab From 15151090579cab7c49d8af54a52f798ce8bda001 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:16 +0200 Subject: [PATCH 5019/9457] can: c_can: Introduce c_can_driver_data structure We want to have more data than just can_dev_id to be present in the driver data e.g. TI platforms need RAMINIT register description. Introduce the c_can_driver_data structure and move the can_dev_id into it. Tidy up the way it is used on probe(). Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.h | 4 ++ drivers/net/can/c_can/c_can_platform.c | 52 ++++++++++++++------------ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 99ad1aa576b0..26c975d914e3 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -169,6 +169,10 @@ enum c_can_dev_id { BOSCH_D_CAN, }; +struct c_can_driver_data { + enum c_can_dev_id id; +}; + /* c_can private data structure */ struct c_can_priv { struct can_priv can; /* must be the first member */ diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 106c203fc5eb..44c293926f78 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -168,26 +168,34 @@ static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable) } } +static const struct c_can_driver_data c_can_drvdata = { + .id = BOSCH_C_CAN, +}; + +static const struct c_can_driver_data d_can_drvdata = { + .id = BOSCH_D_CAN, +}; + static struct platform_device_id c_can_id_table[] = { - [BOSCH_C_CAN_PLATFORM] = { + { .name = KBUILD_MODNAME, - .driver_data = BOSCH_C_CAN, + .driver_data = (kernel_ulong_t)&c_can_drvdata, }, - [BOSCH_C_CAN] = { + { .name = "c_can", - .driver_data = BOSCH_C_CAN, + .driver_data = (kernel_ulong_t)&c_can_drvdata, }, - [BOSCH_D_CAN] = { + { .name = "d_can", - .driver_data = BOSCH_D_CAN, - }, { - } + .driver_data = (kernel_ulong_t)&d_can_drvdata, + }, + { /* sentinel */ }, }; MODULE_DEVICE_TABLE(platform, c_can_id_table); static const struct of_device_id c_can_of_table[] = { - { .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] }, - { .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] }, + { .compatible = "bosch,c_can", .data = &c_can_drvdata }, + { .compatible = "bosch,d_can", .data = &d_can_drvdata }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, c_can_of_table); @@ -199,21 +207,19 @@ static int c_can_plat_probe(struct platform_device *pdev) struct net_device *dev; struct c_can_priv *priv; const struct of_device_id *match; - const struct platform_device_id *id; struct resource *mem, *res; int irq; struct clk *clk; - - if (pdev->dev.of_node) { - match = of_match_device(c_can_of_table, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "Failed to find matching dt id\n"); - ret = -EINVAL; - goto exit; - } - id = match->data; + const struct c_can_driver_data *drvdata; + + match = of_match_device(c_can_of_table, &pdev->dev); + if (match) { + drvdata = match->data; + } else if (pdev->id_entry->driver_data) { + drvdata = (struct c_can_driver_data *) + platform_get_device_id(pdev)->driver_data; } else { - id = platform_get_device_id(pdev); + return -ENODEV; } /* get the appropriate clk */ @@ -245,7 +251,7 @@ static int c_can_plat_probe(struct platform_device *pdev) } priv = netdev_priv(dev); - switch (id->driver_data) { + switch (drvdata->id) { case BOSCH_C_CAN: priv->regs = reg_map_c_can; switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { @@ -304,7 +310,7 @@ static int c_can_plat_probe(struct platform_device *pdev) priv->device = &pdev->dev; priv->can.clock.freq = clk_get_rate(clk); priv->priv = clk; - priv->type = id->driver_data; + priv->type = drvdata->id; platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); -- GitLab From bbf914300509f038c807360d755bd606785be6c9 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:17 +0200 Subject: [PATCH 5020/9457] can: c_can: Add RAMINIT register information to driver data Some platforms (e.g. TI) need special RAMINIT register handling. Provide a way to store RAMINIT register description in driver data. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 26c975d914e3..3f111f4f0f6e 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -169,8 +169,18 @@ enum c_can_dev_id { BOSCH_D_CAN, }; +struct raminit_bits { + u8 start; + u8 done; +}; + struct c_can_driver_data { enum c_can_dev_id id; + + /* RAMINIT register description. Optional. */ + const struct raminit_bits *raminit_bits; /* Array of START/DONE bit positions */ + u8 raminit_num; /* Number of CAN instances on the SoC */ + bool raminit_pulse; /* If set, sets and clears START bit (pulse) */ }; /* c_can private data structure */ -- GitLab From 3ff9027ca6b00e194d2eae353febf7233cfcc1ea Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 14 Nov 2014 17:37:39 +0200 Subject: [PATCH 5021/9457] can: c_can: Add syscon/regmap RAMINIT mechanism Some TI SoCs like DRA7 have a RAMINIT register specification different from the other AMxx SoCs and as expected by the existing driver. To add more insanity, this register is shared with other IPs like DSS, PCIe and PWM. Provides a more generic mechanism to specify the RAMINIT register location and START/DONE bit position and use the syscon/regmap framework to access the register. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/net/can/c_can.txt | 3 + drivers/net/can/c_can/c_can.h | 10 +- drivers/net/can/c_can/c_can_platform.c | 109 +++++++++++------- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 8f1ae81228e3..a3ca3ee53546 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -12,6 +12,9 @@ Required properties: Optional properties: - ti,hwmods : Must be "d_can" or "c_can", n being the instance number +- syscon-raminit : Handle to system control region that contains the + RAMINIT register, register offset to the RAMINIT + register and the CAN instance number (0 offset). Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 3f111f4f0f6e..28a73d14ea8d 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -183,6 +183,13 @@ struct c_can_driver_data { bool raminit_pulse; /* If set, sets and clears START bit (pulse) */ }; +/* Out of band RAMINIT register access via syscon regmap */ +struct c_can_raminit { + struct regmap *syscon; /* for raminit ctrl. reg. access */ + unsigned int reg; /* register index within syscon */ + struct raminit_bits bits; +}; + /* c_can private data structure */ struct c_can_priv { struct can_priv can; /* must be the first member */ @@ -200,8 +207,7 @@ struct c_can_priv { const u16 *regs; void *priv; /* for board-specific data */ enum c_can_dev_id type; - u32 __iomem *raminit_ctrlreg; - int instance; + struct c_can_raminit raminit_sys; /* RAMINIT via syscon regmap */ void (*raminit) (const struct c_can_priv *priv, bool enable); u32 comm_rcv_high; u32 rxmasked; diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 44c293926f78..1fbfa1d59c29 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -32,14 +32,13 @@ #include #include #include +#include +#include #include #include "c_can.h" -#define CAN_RAMINIT_START_MASK(i) (0x001 << (i)) -#define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i)) -#define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i)) #define DCAN_RAM_INIT_BIT (1 << 3) static DEFINE_SPINLOCK(raminit_lock); /* @@ -72,48 +71,57 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv, writew(val, priv->base + 2 * priv->regs[index]); } -static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask, - u32 val) +static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv, + u32 mask, u32 val) { + const struct c_can_raminit *raminit = &priv->raminit_sys; int timeout = 0; + u32 ctrl = 0; /* We look only at the bits of our instance. */ val &= mask; - while ((readl(priv->raminit_ctrlreg) & mask) != val) { + do { udelay(1); timeout++; + regmap_read(raminit->syscon, raminit->reg, &ctrl); if (timeout == 1000) { dev_err(&priv->dev->dev, "%s: time out\n", __func__); break; } - } + } while ((ctrl & mask) != val); } -static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable) +static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) { - u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance); - u32 ctrl; + const struct c_can_raminit *raminit = &priv->raminit_sys; + u32 ctrl = 0; + u32 mask; spin_lock(&raminit_lock); - ctrl = readl(priv->raminit_ctrlreg); + mask = 1 << raminit->bits.start | 1 << raminit->bits.done; + regmap_read(raminit->syscon, raminit->reg, &ctrl); + /* We clear the done and start bit first. The start bit is * looking at the 0 -> transition, but is not self clearing; * And we clear the init done bit as well. + * NOTE: DONE must be written with 1 to clear it. */ - ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance); - ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); - writel(ctrl, priv->raminit_ctrlreg); - ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance); - c_can_hw_raminit_wait_ti(priv, mask, ctrl); + ctrl &= ~(1 << raminit->bits.start); + ctrl |= 1 << raminit->bits.done; + regmap_write(raminit->syscon, raminit->reg, ctrl); + + ctrl &= ~(1 << raminit->bits.done); + c_can_hw_raminit_wait_syscon(priv, mask, ctrl); if (enable) { /* Set start bit and wait for the done bit. */ - ctrl |= CAN_RAMINIT_START_MASK(priv->instance); - writel(ctrl, priv->raminit_ctrlreg); - ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance); - c_can_hw_raminit_wait_ti(priv, mask, ctrl); + ctrl |= 1 << raminit->bits.start; + regmap_write(raminit->syscon, raminit->reg, ctrl); + + ctrl |= 1 << raminit->bits.done; + c_can_hw_raminit_wait_syscon(priv, mask, ctrl); } spin_unlock(&raminit_lock); } @@ -207,10 +215,11 @@ static int c_can_plat_probe(struct platform_device *pdev) struct net_device *dev; struct c_can_priv *priv; const struct of_device_id *match; - struct resource *mem, *res; + struct resource *mem; int irq; struct clk *clk; const struct c_can_driver_data *drvdata; + struct device_node *np = pdev->dev.of_node; match = of_match_device(c_can_of_table, &pdev->dev); if (match) { @@ -278,27 +287,49 @@ static int c_can_plat_probe(struct platform_device *pdev) priv->read_reg32 = d_can_plat_read_reg32; priv->write_reg32 = d_can_plat_write_reg32; - if (pdev->dev.of_node) - priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can"); - else - priv->instance = pdev->id; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - /* Not all D_CAN modules have a separate register for the D_CAN - * RAM initialization. Use default RAM init bit in D_CAN module - * if not specified in DT. + /* Check if we need custom RAMINIT via syscon. Mostly for TI + * platforms. Only supported with DT boot. */ - if (!res) { + if (np && of_property_read_bool(np, "syscon-raminit")) { + u32 id; + struct c_can_raminit *raminit = &priv->raminit_sys; + + ret = -EINVAL; + raminit->syscon = syscon_regmap_lookup_by_phandle(np, + "syscon-raminit"); + if (IS_ERR(raminit->syscon)) { + /* can fail with -EPROBE_DEFER */ + ret = PTR_ERR(raminit->syscon); + free_c_can_dev(dev); + return ret; + } + + if (of_property_read_u32_index(np, "syscon-raminit", 1, + &raminit->reg)) { + dev_err(&pdev->dev, + "couldn't get the RAMINIT reg. offset!\n"); + goto exit_free_device; + } + + if (of_property_read_u32_index(np, "syscon-raminit", 2, + &id)) { + dev_err(&pdev->dev, + "couldn't get the CAN instance ID\n"); + goto exit_free_device; + } + + if (id >= drvdata->raminit_num) { + dev_err(&pdev->dev, + "Invalid CAN instance ID\n"); + goto exit_free_device; + } + + raminit->bits = drvdata->raminit_bits[id]; + + priv->raminit = c_can_hw_raminit_syscon; + } else { priv->raminit = c_can_hw_raminit; - break; } - - priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!priv->raminit_ctrlreg || priv->instance < 0) - dev_info(&pdev->dev, "control memory is not used for raminit\n"); - else - priv->raminit = c_can_hw_raminit_ti; break; default: ret = -EINVAL; -- GitLab From 0741bfb9395ad176be91f66d2ef3f6f669e27890 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:19 +0200 Subject: [PATCH 5022/9457] can: c_can: Add support for START pulse in RAMINIT sequence Some SoCs e.g. (TI DRA7xx) need a START pulse to start the RAMINIT sequence i.e. START bit must be set and cleared before checking for the DONE bit status. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.h | 1 + drivers/net/can/c_can/c_can_platform.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 28a73d14ea8d..8acdc7fa4792 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -188,6 +188,7 @@ struct c_can_raminit { struct regmap *syscon; /* for raminit ctrl. reg. access */ unsigned int reg; /* register index within syscon */ struct raminit_bits bits; + bool needs_pulse; }; /* c_can private data structure */ diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 1fbfa1d59c29..41fa460c3592 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -120,6 +120,12 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) ctrl |= 1 << raminit->bits.start; regmap_write(raminit->syscon, raminit->reg, ctrl); + /* clear START bit if start pulse is needed */ + if (raminit->needs_pulse) { + ctrl &= ~(1 << raminit->bits.start); + regmap_write(raminit->syscon, raminit->reg, ctrl); + } + ctrl |= 1 << raminit->bits.done; c_can_hw_raminit_wait_syscon(priv, mask, ctrl); } @@ -325,6 +331,7 @@ static int c_can_plat_probe(struct platform_device *pdev) } raminit->bits = drvdata->raminit_bits[id]; + raminit->needs_pulse = drvdata->raminit_pulse; priv->raminit = c_can_hw_raminit_syscon; } else { -- GitLab From 3973c526ae9cda5959bf6ef8ed936c46845eb774 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 14 Nov 2014 17:40:13 +0200 Subject: [PATCH 5023/9457] can: c_can: Disable pins when CAN interface is down DRA7 CAN IP suffers from a problem which causes it to be prevented from fully turning OFF (i.e. stuck in transition) if the module was disabled while there was traffic on the CAN_RX line. To work around this issue we select the SLEEP pin state by default on probe and use the DEFAULT pin state on CAN up and back to the SLEEP pin state on CAN down. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- drivers/net/can/c_can/c_can.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8e78bb48f5a4..f94a9fa60488 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -603,6 +604,8 @@ static int c_can_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; + /* activate pins */ + pinctrl_pm_select_default_state(dev->dev.parent); return 0; } @@ -611,6 +614,9 @@ static void c_can_stop(struct net_device *dev) struct c_can_priv *priv = netdev_priv(dev); c_can_irq_control(priv, false); + + /* deactivate pins */ + pinctrl_pm_select_sleep_state(dev->dev.parent); priv->can.state = CAN_STATE_STOPPED; } @@ -1244,6 +1250,13 @@ int register_c_can_dev(struct net_device *dev) struct c_can_priv *priv = netdev_priv(dev); int err; + /* Deactivate pins to prevent DRA7 DCAN IP from being + * stuck in transition when module is disabled. + * Pins are activated in c_can_start() and deactivated + * in c_can_stop() + */ + pinctrl_pm_select_sleep_state(dev->dev.parent); + c_can_pm_runtime_enable(priv); dev->flags |= IFF_ECHO; /* we support local echo */ -- GitLab From 0f4da3a8da5fe3a079b1adf613d121a0fafd63f1 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:21 +0200 Subject: [PATCH 5024/9457] can: c_can: Add support for TI DRA7 DCAN DRA7 SoC has 2 CAN IPs. Provide compatible IDs and RAMINIT register data for both. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/c_can.txt | 1 + drivers/net/can/c_can/c_can_platform.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index a3ca3ee53546..f682fdb6d921 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -4,6 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings Required properties: - compatible : Should be "bosch,c_can" for C_CAN controllers and "bosch,d_can" for D_CAN controllers. + Can be "ti,dra7-d_can". - reg : physical base address and size of the C_CAN/D_CAN registers map - interrupts : property with a value describing the interrupt diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 41fa460c3592..570da5f56aae 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -190,6 +190,18 @@ static const struct c_can_driver_data d_can_drvdata = { .id = BOSCH_D_CAN, }; +static const struct raminit_bits dra7_raminit_bits[] = { + [0] = { .start = 3, .done = 1, }, + [1] = { .start = 5, .done = 2, }, +}; + +static const struct c_can_driver_data dra7_dcan_drvdata = { + .id = BOSCH_D_CAN, + .raminit_num = ARRAY_SIZE(dra7_raminit_bits), + .raminit_bits = dra7_raminit_bits, + .raminit_pulse = true, +}; + static struct platform_device_id c_can_id_table[] = { { .name = KBUILD_MODNAME, @@ -210,6 +222,7 @@ MODULE_DEVICE_TABLE(platform, c_can_id_table); static const struct of_device_id c_can_of_table[] = { { .compatible = "bosch,c_can", .data = &c_can_drvdata }, { .compatible = "bosch,d_can", .data = &d_can_drvdata }, + { .compatible = "ti,dra7-d_can", .data = &dra7_dcan_drvdata }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, c_can_of_table); -- GitLab From c71d0b31bf71b84ad566292ea2412755da7934b2 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Fri, 7 Nov 2014 16:49:22 +0200 Subject: [PATCH 5025/9457] can: c_can: Add support for TI am3352 DCAN AM3352 SoC has 2 DCAN modules. Add compatible id and raminit driver data for am3352 DCAN. Signed-off-by: Roger Quadros Acked-by: Wolfram Sang Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/c_can.txt | 2 +- drivers/net/can/c_can/c_can_platform.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index f682fdb6d921..6731730eec0d 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -4,7 +4,7 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings Required properties: - compatible : Should be "bosch,c_can" for C_CAN controllers and "bosch,d_can" for D_CAN controllers. - Can be "ti,dra7-d_can". + Can be "ti,dra7-d_can" or "ti,am3352-d_can". - reg : physical base address and size of the C_CAN/D_CAN registers map - interrupts : property with a value describing the interrupt diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 570da5f56aae..f4488e5d5d68 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -202,6 +202,17 @@ static const struct c_can_driver_data dra7_dcan_drvdata = { .raminit_pulse = true, }; +static const struct raminit_bits am3352_raminit_bits[] = { + [0] = { .start = 0, .done = 8, }, + [1] = { .start = 1, .done = 9, }, +}; + +static const struct c_can_driver_data am3352_dcan_drvdata = { + .id = BOSCH_D_CAN, + .raminit_num = ARRAY_SIZE(am3352_raminit_bits), + .raminit_bits = am3352_raminit_bits, +}; + static struct platform_device_id c_can_id_table[] = { { .name = KBUILD_MODNAME, @@ -223,6 +234,7 @@ static const struct of_device_id c_can_of_table[] = { { .compatible = "bosch,c_can", .data = &c_can_drvdata }, { .compatible = "bosch,d_can", .data = &d_can_drvdata }, { .compatible = "ti,dra7-d_can", .data = &dra7_dcan_drvdata }, + { .compatible = "ti,am3352-d_can", .data = &am3352_dcan_drvdata }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, c_can_of_table); -- GitLab From e5a06dc5ac1f686d11b11488a88a63ab12e079cb Mon Sep 17 00:00:00 2001 From: Bart Tanghe Date: Wed, 8 Oct 2014 12:14:32 +0200 Subject: [PATCH 5026/9457] pwm: Add BCM2835 PWM driver Add PWM driver for Broadcom BCM2835 processor (Raspberry Pi) Signed-off-by: Bart Tanghe Acked-by: Stephen Warren Signed-off-by: Thierry Reding --- .../devicetree/bindings/pwm/pwm-bcm2835.txt | 30 +++ drivers/pwm/Kconfig | 9 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-bcm2835.c | 205 ++++++++++++++++++ 4 files changed, 245 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt create mode 100644 drivers/pwm/pwm-bcm2835.c diff --git a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt new file mode 100644 index 000000000000..fb6fb31bc4c4 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt @@ -0,0 +1,30 @@ +BCM2835 PWM controller (Raspberry Pi controller) + +Required properties: +- compatible: should be "brcm,bcm2835-pwm" +- reg: physical base address and length of the controller's registers +- clock: This clock defines the base clock frequency of the PWM hardware + system, the period and the duty_cycle of the PWM signal is a multiple of + the base period. +- #pwm-cells: Should be 2. See pwm.txt in this directory for a description of + the cells format. + +Examples: + +pwm@2020c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x2020c000 0x28>; + clocks = <&clk_pwm>; + #pwm-cells = <2>; +}; + +clocks { + .... + clk_pwm: pwm { + compatible = "fixed-clock"; + reg = <3>; + #clock-cells = <0>; + clock-frequency = <9200000>; + }; + .... +}; diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index ef2dd2e4754b..ddabe3983549 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -71,6 +71,15 @@ config PWM_BCM_KONA To compile this driver as a module, choose M here: the module will be called pwm-bcm-kona. +config PWM_BCM2835 + tristate "BCM2835 PWM support" + depends on ARCH_BCM2835 + help + PWM framework driver for BCM2835 controller (Raspberry Pi) + + To compile this driver as a module, choose M here: the module + will be called pwm-bcm2835. + config PWM_BFIN tristate "Blackfin PWM support" depends on BFIN_GPTIMERS diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index c458606c3755..88be33bbfdf6 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o +obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c new file mode 100644 index 000000000000..b4c7f956b6fa --- /dev/null +++ b/drivers/pwm/pwm-bcm2835.c @@ -0,0 +1,205 @@ +/* + * Copyright 2014 Bart Tanghe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PWM_CONTROL 0x000 +#define PWM_CONTROL_SHIFT(x) ((x) * 8) +#define PWM_CONTROL_MASK 0xff +#define PWM_MODE 0x80 /* set timer in PWM mode */ +#define PWM_ENABLE (1 << 0) +#define PWM_POLARITY (1 << 4) + +#define PERIOD(x) (((x) * 0x10) + 0x10) +#define DUTY(x) (((x) * 0x10) + 0x14) + +#define MIN_PERIOD 108 /* 9.2 MHz max. PWM clock */ + +struct bcm2835_pwm { + struct pwm_chip chip; + struct device *dev; + unsigned long scaler; + void __iomem *base; + struct clk *clk; +}; + +static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) +{ + return container_of(chip, struct bcm2835_pwm, chip); +} + +static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); + value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); +} + +static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + + if (period_ns <= MIN_PERIOD) { + dev_err(pc->dev, "period %d not supported, minimum %d\n", + period_ns, MIN_PERIOD); + return -EINVAL; + } + + writel(duty_ns / pc->scaler, pc->base + DUTY(pwm->hwpwm)); + writel(period_ns / pc->scaler, pc->base + PERIOD(pwm->hwpwm)); + + return 0; +} + +static int bcm2835_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm); + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static void bcm2835_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + value &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm)); + writel(value, pc->base + PWM_CONTROL); +} + +static int bcm2835_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + u32 value; + + value = readl(pc->base + PWM_CONTROL); + + if (polarity == PWM_POLARITY_NORMAL) + value &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else + value |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm); + + writel(value, pc->base + PWM_CONTROL); + + return 0; +} + +static const struct pwm_ops bcm2835_pwm_ops = { + .request = bcm2835_pwm_request, + .free = bcm2835_pwm_free, + .config = bcm2835_pwm_config, + .enable = bcm2835_pwm_enable, + .disable = bcm2835_pwm_disable, + .set_polarity = bcm2835_set_polarity, + .owner = THIS_MODULE, +}; + +static int bcm2835_pwm_probe(struct platform_device *pdev) +{ + struct bcm2835_pwm *pc; + struct resource *res; + int ret; + + pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + pc->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pc->base)) + return PTR_ERR(pc->base); + + pc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(pc->clk)) { + dev_err(&pdev->dev, "clock not found: %ld\n", PTR_ERR(pc->clk)); + return PTR_ERR(pc->clk); + } + + ret = clk_prepare_enable(pc->clk); + if (ret) + return ret; + + pc->scaler = NSEC_PER_SEC / clk_get_rate(pc->clk); + + pc->chip.dev = &pdev->dev; + pc->chip.ops = &bcm2835_pwm_ops; + pc->chip.npwm = 2; + + platform_set_drvdata(pdev, pc); + + ret = pwmchip_add(&pc->chip); + if (ret < 0) + goto add_fail; + + return 0; + +add_fail: + clk_disable_unprepare(pc->clk); + return ret; +} + +static int bcm2835_pwm_remove(struct platform_device *pdev) +{ + struct bcm2835_pwm *pc = platform_get_drvdata(pdev); + + clk_disable_unprepare(pc->clk); + + return pwmchip_remove(&pc->chip); +} + +static const struct of_device_id bcm2835_pwm_of_match[] = { + { .compatible = "brcm,bcm2835-pwm", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, bcm2835_pwm_of_match); + +static struct platform_driver bcm2835_pwm_driver = { + .driver = { + .name = "bcm2835-pwm", + .of_match_table = bcm2835_pwm_of_match, + }, + .probe = bcm2835_pwm_probe, + .remove = bcm2835_pwm_remove, +}; +module_platform_driver(bcm2835_pwm_driver); + +MODULE_AUTHOR("Bart Tanghe Date: Tue, 7 Oct 2014 15:38:14 +0200 Subject: [PATCH 5027/9457] pwm: add support for atmel-hlcdc-pwm device The HLCDC IP available in some Atmel SoCs (i.e. at91sam9x5, at91sam9n12 or sama5d3 families for instance) provides a PWM device. This driver add support for a PWM chip exposing a single PWM device (which will most likely be used to drive a backlight device). Signed-off-by: Boris Brezillon Tested-by: Anthony Harivel Tested-by: Ludovic Desroches Acked-by: Thierry Reding Acked-by: Nicolas Ferre Signed-off-by: Thierry Reding --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-atmel-hlcdc.c | 259 ++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 drivers/pwm/pwm-atmel-hlcdc.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index ddabe3983549..847a57d2cf1c 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -50,6 +50,17 @@ config PWM_ATMEL To compile this driver as a module, choose M here: the module will be called pwm-atmel. +config PWM_ATMEL_HLCDC_PWM + tristate "Atmel HLCDC PWM support" + depends on MFD_ATMEL_HLCDC + help + Generic PWM framework driver for the PWM output of the HLCDC + (Atmel High-end LCD Controller). This PWM output is mainly used + to control the LCD backlight. + + To compile this driver as a module, choose M here: the module + will be called pwm-atmel-hlcdc. + config PWM_ATMEL_TCB tristate "Atmel TC Block PWM support" depends on ATMEL_TCLIB && OF diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 88be33bbfdf6..65259ac1e8de 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PWM) += core.o obj-$(CONFIG_PWM_SYSFS) += sysfs.o obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o +obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c new file mode 100644 index 000000000000..eaf8b12ce1e5 --- /dev/null +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2014 Free Electrons + * Copyright (C) 2014 Atmel + * + * Author: Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ATMEL_HLCDC_PWMCVAL_MASK GENMASK(15, 8) +#define ATMEL_HLCDC_PWMCVAL(x) (((x) << 8) & ATMEL_HLCDC_PWMCVAL_MASK) +#define ATMEL_HLCDC_PWMPOL BIT(4) +#define ATMEL_HLCDC_PWMPS_MASK GENMASK(2, 0) +#define ATMEL_HLCDC_PWMPS_MAX 0x6 +#define ATMEL_HLCDC_PWMPS(x) ((x) & ATMEL_HLCDC_PWMPS_MASK) + +struct atmel_hlcdc_pwm { + struct pwm_chip chip; + struct atmel_hlcdc *hlcdc; + struct clk *cur_clk; +}; + +static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip) +{ + return container_of(chip, struct atmel_hlcdc_pwm, chip); +} + +static int atmel_hlcdc_pwm_config(struct pwm_chip *c, + struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + struct clk *new_clk = hlcdc->slow_clk; + u64 pwmcval = duty_ns * 256; + unsigned long clk_freq; + u64 clk_period_ns; + u32 pwmcfg; + int pres; + + clk_freq = clk_get_rate(new_clk); + clk_period_ns = (u64)NSEC_PER_SEC * 256; + do_div(clk_period_ns, clk_freq); + + if (clk_period_ns > period_ns) { + new_clk = hlcdc->sys_clk; + clk_freq = clk_get_rate(new_clk); + clk_period_ns = (u64)NSEC_PER_SEC * 256; + do_div(clk_period_ns, clk_freq); + } + + for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) + if ((clk_period_ns << pres) >= period_ns) + break; + + if (pres > ATMEL_HLCDC_PWMPS_MAX) + return -EINVAL; + + pwmcfg = ATMEL_HLCDC_PWMPS(pres); + + if (new_clk != chip->cur_clk) { + u32 gencfg = 0; + int ret; + + ret = clk_prepare_enable(new_clk); + if (ret) + return ret; + + clk_disable_unprepare(chip->cur_clk); + chip->cur_clk = new_clk; + + if (new_clk == hlcdc->sys_clk) + gencfg = ATMEL_HLCDC_CLKPWMSEL; + + ret = regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(0), + ATMEL_HLCDC_CLKPWMSEL, gencfg); + if (ret) + return ret; + } + + do_div(pwmcval, period_ns); + + /* + * The PWM duty cycle is configurable from 0/256 to 255/256 of the + * period cycle. Hence we can't set a duty cycle occupying the + * whole period cycle if we're asked to. + * Set it to 255 if pwmcval is greater than 256. + */ + if (pwmcval > 255) + pwmcval = 255; + + pwmcfg |= ATMEL_HLCDC_PWMCVAL(pwmcval); + + return regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(6), + ATMEL_HLCDC_PWMCVAL_MASK | + ATMEL_HLCDC_PWMPS_MASK, + pwmcfg); +} + +static int atmel_hlcdc_pwm_set_polarity(struct pwm_chip *c, + struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 cfg = 0; + + if (polarity == PWM_POLARITY_NORMAL) + cfg = ATMEL_HLCDC_PWMPOL; + + return regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(6), + ATMEL_HLCDC_PWMPOL, cfg); +} + +static int atmel_hlcdc_pwm_enable(struct pwm_chip *c, struct pwm_device *pwm) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 status; + int ret; + + ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PWM); + if (ret) + return ret; + + while (true) { + ret = regmap_read(hlcdc->regmap, ATMEL_HLCDC_SR, &status); + if (ret) + return ret; + + if ((status & ATMEL_HLCDC_PWM) != 0) + break; + + usleep_range(1, 10); + } + + return 0; +} + +static void atmel_hlcdc_pwm_disable(struct pwm_chip *c, + struct pwm_device *pwm) +{ + struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c); + struct atmel_hlcdc *hlcdc = chip->hlcdc; + u32 status; + int ret; + + ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PWM); + if (ret) + return; + + while (true) { + ret = regmap_read(hlcdc->regmap, ATMEL_HLCDC_SR, &status); + if (ret) + return; + + if ((status & ATMEL_HLCDC_PWM) == 0) + break; + + usleep_range(1, 10); + } +} + +static const struct pwm_ops atmel_hlcdc_pwm_ops = { + .config = atmel_hlcdc_pwm_config, + .set_polarity = atmel_hlcdc_pwm_set_polarity, + .enable = atmel_hlcdc_pwm_enable, + .disable = atmel_hlcdc_pwm_disable, + .owner = THIS_MODULE, +}; + +static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct atmel_hlcdc_pwm *chip; + struct atmel_hlcdc *hlcdc; + int ret; + + hlcdc = dev_get_drvdata(dev->parent); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + ret = clk_prepare_enable(hlcdc->periph_clk); + if (ret) + return ret; + + chip->hlcdc = hlcdc; + chip->chip.ops = &atmel_hlcdc_pwm_ops; + chip->chip.dev = dev; + chip->chip.base = -1; + chip->chip.npwm = 1; + chip->chip.of_xlate = of_pwm_xlate_with_flags; + chip->chip.of_pwm_n_cells = 3; + chip->chip.can_sleep = 1; + + ret = pwmchip_add(&chip->chip); + if (ret) { + clk_disable_unprepare(hlcdc->periph_clk); + return ret; + } + + platform_set_drvdata(pdev, chip); + + return 0; +} + +static int atmel_hlcdc_pwm_remove(struct platform_device *pdev) +{ + struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev); + int ret; + + ret = pwmchip_remove(&chip->chip); + if (ret) + return ret; + + clk_disable_unprepare(chip->hlcdc->periph_clk); + + return 0; +} + +static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = { + { .compatible = "atmel,hlcdc-pwm" }, + { /* sentinel */ }, +}; + +static struct platform_driver atmel_hlcdc_pwm_driver = { + .driver = { + .name = "atmel-hlcdc-pwm", + .of_match_table = atmel_hlcdc_pwm_dt_ids, + }, + .probe = atmel_hlcdc_pwm_probe, + .remove = atmel_hlcdc_pwm_remove, +}; +module_platform_driver(atmel_hlcdc_pwm_driver); + +MODULE_ALIAS("platform:atmel-hlcdc-pwm"); +MODULE_AUTHOR("Boris Brezillon "); +MODULE_DESCRIPTION("Atmel HLCDC PWM driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 2899e12fc9864db600b2fe9707ebb97203fe4c00 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 7 Oct 2014 15:38:15 +0200 Subject: [PATCH 5028/9457] pwm: add DT bindings documentation for atmel-hlcdc-pwm driver The HLCDC IP available in some Atmel SoCs (i.e. at91sam9x5, at91sam9n12 or sama5d3 families for instance) provides a PWM device. The DT bindings used for this PWM device is following the default 3 cells bindings described in Documentation/devicetree/bindings/pwm/pwm.txt. Signed-off-by: Boris Brezillon Acked-by: Thierry Reding Acked-by: Nicolas Ferre Signed-off-by: Thierry Reding --- .../bindings/pwm/atmel-hlcdc-pwm.txt | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt diff --git a/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt b/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt new file mode 100644 index 000000000000..cfda0d57d302 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt @@ -0,0 +1,29 @@ +Device-Tree bindings for Atmel's HLCDC (High-end LCD Controller) PWM driver + +The Atmel HLCDC PWM is subdevice of the HLCDC MFD device. +See ../mfd/atmel-hlcdc.txt for more details. + +Required properties: + - compatible: value should be one of the following: + "atmel,hlcdc-pwm" + - pinctr-names: the pin control state names. Should contain "default". + - pinctrl-0: should contain the pinctrl states described by pinctrl + default. + - #pwm-cells: should be set to 3. This PWM chip use the default 3 cells + bindings defined in pwm.txt in this directory. + +Example: + + hlcdc: hlcdc@f0030000 { + compatible = "atmel,sama5d3-hlcdc"; + reg = <0xf0030000 0x2000>; + clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; + clock-names = "periph_clk","sys_clk", "slow_clk"; + + hlcdc_pwm: hlcdc-pwm { + compatible = "atmel,hlcdc-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd_pwm>; + #pwm-cells = <3>; + }; + }; -- GitLab From 06e4cb6b1d5c9dba007b1f7a039384b2fc1a8827 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Fri, 31 Oct 2014 18:08:46 +0530 Subject: [PATCH 5029/9457] pwm: samsung: Allow Samsung PWM driver to be enabled on Exynos7 To re-use the existing PWM driver for 64-bit ARM based Exynos7 SoC, make the driver depend on ARCH_EXYNOS along with PLAT_SAMSUNG. Signed-off-by: Abhilash Kesavan Signed-off-by: Thierry Reding --- drivers/pwm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 847a57d2cf1c..a3ecf5809634 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -255,7 +255,7 @@ config PWM_ROCKCHIP config PWM_SAMSUNG tristate "Samsung PWM support" - depends on PLAT_SAMSUNG + depends on PLAT_SAMSUNG || ARCH_EXYNOS help Generic PWM framework driver for Samsung. -- GitLab From e59ea3df3fc290b91c52a250c19091c18b4e6d7e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 14 Nov 2014 13:21:48 +0100 Subject: [PATCH 5030/9457] netfilter: xt_connlimit: honor conntrack zone if available Currently all the conntrack lookups are done using default zone. In case the skb has a ct attached (e.g. template) we should use this zone for lookups instead. This makes connlimit work with connections assigned to other zones. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/xt_connlimit.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index fbc66bb250d5..29ba6218a820 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -134,6 +134,7 @@ static bool add_hlist(struct hlist_head *head, static unsigned int check_hlist(struct net *net, struct hlist_head *head, const struct nf_conntrack_tuple *tuple, + u16 zone, bool *addit) { const struct nf_conntrack_tuple_hash *found; @@ -147,8 +148,7 @@ static unsigned int check_hlist(struct net *net, /* check the saved connections */ hlist_for_each_entry_safe(conn, n, head, node) { - found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, - &conn->tuple); + found = nf_conntrack_find_get(net, zone, &conn->tuple); if (found == NULL) { hlist_del(&conn->node); kmem_cache_free(connlimit_conn_cachep, conn); @@ -201,7 +201,7 @@ static unsigned int count_tree(struct net *net, struct rb_root *root, const struct nf_conntrack_tuple *tuple, const union nf_inet_addr *addr, const union nf_inet_addr *mask, - u8 family) + u8 family, u16 zone) { struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES]; struct rb_node **rbnode, *parent; @@ -229,7 +229,7 @@ count_tree(struct net *net, struct rb_root *root, } else { /* same source network -> be counted! */ unsigned int count; - count = check_hlist(net, &rbconn->hhead, tuple, &addit); + count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit); tree_nodes_free(root, gc_nodes, gc_count); if (!addit) @@ -245,7 +245,7 @@ count_tree(struct net *net, struct rb_root *root, continue; /* only used for GC on hhead, retval and 'addit' ignored */ - check_hlist(net, &rbconn->hhead, tuple, &addit); + check_hlist(net, &rbconn->hhead, tuple, zone, &addit); if (hlist_empty(&rbconn->hhead)) gc_nodes[gc_count++] = rbconn; } @@ -290,7 +290,7 @@ static int count_them(struct net *net, const struct nf_conntrack_tuple *tuple, const union nf_inet_addr *addr, const union nf_inet_addr *mask, - u_int8_t family) + u_int8_t family, u16 zone) { struct rb_root *root; int count; @@ -306,7 +306,7 @@ static int count_them(struct net *net, spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); - count = count_tree(net, root, tuple, addr, mask, family); + count = count_tree(net, root, tuple, addr, mask, family, zone); spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); @@ -324,13 +324,16 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) enum ip_conntrack_info ctinfo; const struct nf_conn *ct; unsigned int connections; + u16 zone = NF_CT_DEFAULT_ZONE; ct = nf_ct_get(skb, &ctinfo); - if (ct != NULL) + if (ct != NULL) { tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), - par->family, &tuple)) + zone = nf_ct_zone(ct); + } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), + par->family, &tuple)) { goto hotdrop; + } if (par->family == NFPROTO_IPV6) { const struct ipv6hdr *iph = ipv6_hdr(skb); @@ -343,7 +346,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) } connections = count_them(net, info->data, tuple_ptr, &addr, - &info->mask, par->family); + &info->mask, par->family, zone); if (connections == 0) /* kmalloc failed, drop it entirely */ goto hotdrop; -- GitLab From 2c7b5d5dac0ddaa4e1109fb84dbbe91db3c6c6e5 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Thu, 13 Nov 2014 14:31:25 +0300 Subject: [PATCH 5031/9457] netfilter: nf_conntrack_h323: lookup route from proper net namespace Signed-off-by: Vasily Averin Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_h323_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 3a3a60b126e0..1d69f5b9748f 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -728,7 +728,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct, /* If the calling party is on the same side of the forward-to party, * we don't need to track the second call */ -static int callforward_do_filter(const union nf_inet_addr *src, +static int callforward_do_filter(struct net *net, + const union nf_inet_addr *src, const union nf_inet_addr *dst, u_int8_t family) { @@ -750,9 +751,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); fl2.daddr = dst->ip; - if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, + if (!afinfo->route(net, (struct dst_entry **)&rt1, flowi4_to_flowi(&fl1), false)) { - if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, + if (!afinfo->route(net, (struct dst_entry **)&rt2, flowi4_to_flowi(&fl2), false)) { if (rt_nexthop(rt1, fl1.daddr) == rt_nexthop(rt2, fl2.daddr) && @@ -774,9 +775,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); fl2.daddr = dst->in6; - if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, + if (!afinfo->route(net, (struct dst_entry **)&rt1, flowi6_to_flowi(&fl1), false)) { - if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, + if (!afinfo->route(net, (struct dst_entry **)&rt2, flowi6_to_flowi(&fl2), false)) { if (ipv6_addr_equal(rt6_nexthop(rt1), rt6_nexthop(rt2)) && @@ -807,6 +808,7 @@ static int expect_callforwarding(struct sk_buff *skb, __be16 port; union nf_inet_addr addr; struct nf_conntrack_expect *exp; + struct net *net = nf_ct_net(ct); typeof(nat_callforwarding_hook) nat_callforwarding; /* Read alternativeAddress */ @@ -816,7 +818,7 @@ static int expect_callforwarding(struct sk_buff *skb, /* If the calling party is on the same side of the forward-to party, * we don't need to track the second call */ if (callforward_filter && - callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3, + callforward_do_filter(net, &addr, &ct->tuplehash[!dir].tuple.src.u3, nf_ct_l3num(ct))) { pr_debug("nf_ct_q931: Call Forwarding not tracked\n"); return 0; -- GitLab From f0acd28c87ad2a5d1b40403fdd5defda2961b2a1 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 10:44:33 +0100 Subject: [PATCH 5032/9457] ALSA: hda: Deletion of unnecessary checks before two function calls The functions kfree() and release_firmware() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 3 +-- sound/pci/hda/hda_intel.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ca98f5209f8f..b2d58998dbdd 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -834,8 +834,7 @@ static void snd_hda_bus_free(struct hda_bus *bus) WARN_ON(!list_empty(&bus->codec_list)); if (bus->workq) flush_workqueue(bus->workq); - if (bus->unsol) - kfree(bus->unsol); + kfree(bus->unsol); if (bus->ops.private_free) bus->ops.private_free(bus); if (bus->workq) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9ab1e631cb32..91fa959d05fe 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1130,8 +1130,7 @@ static int azx_free(struct azx *chip) pci_disable_device(chip->pci); kfree(chip->azx_dev); #ifdef CONFIG_SND_HDA_PATCH_LOADER - if (chip->fw) - release_firmware(chip->fw); + release_firmware(chip->fw); #endif if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { hda_display_power(false); -- GitLab From ae1b22658e6d3ebc6af07a225c221d84fe8cb91f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 11:28:02 +0100 Subject: [PATCH 5033/9457] ALSA: ice17xx: Deletion of unnecessary checks before the function call "snd_ac97_resume" The snd_ac97_resume() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/pci/ice1712/ice1712.c | 3 +-- sound/pci/ice1712/ice1724.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 65251911cf6f..b039b46152c6 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2878,8 +2878,7 @@ static int snd_ice1712_resume(struct device *dev) outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); - if (ice->ac97) - snd_ac97_resume(ice->ac97); + snd_ac97_resume(ice->ac97); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index ea53167081b8..d73da157ea14 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2875,8 +2875,7 @@ static int snd_vt1724_resume(struct device *dev) outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG)); outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK)); - if (ice->ac97) - snd_ac97_resume(ice->ac97); + snd_ac97_resume(ice->ac97); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; -- GitLab From 6da95e1ea8e2492530eac9c51b293226e3f4ce94 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 12:42:16 +0100 Subject: [PATCH 5034/9457] ALSA: lola: Deletion of an unnecessary check before the function call "vfree" The vfree() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/pci/lola/lola_mixer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c index 782f4d8299ae..e7fe15dd5a90 100644 --- a/sound/pci/lola/lola_mixer.c +++ b/sound/pci/lola/lola_mixer.c @@ -108,8 +108,7 @@ int lola_init_pins(struct lola *chip, int dir, int *nidp) void lola_free_mixer(struct lola *chip) { - if (chip->mixer.array_saved) - vfree(chip->mixer.array_saved); + vfree(chip->mixer.array_saved); } int lola_init_mixer_widget(struct lola *chip, int nid) -- GitLab From c283661018e347bc72633969411974df8ec2ac92 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 13:04:14 +0100 Subject: [PATCH 5035/9457] ALSA: hdsp: Deletion of an unnecessary check before the function call "release_firmware" The release_firmware() function tests whether its argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 2eb8baf7b828..cf5a6c8b9a63 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -5307,8 +5307,7 @@ static int snd_hdsp_free(struct hdsp *hdsp) snd_hdsp_free_buffers(hdsp); - if (hdsp->firmware) - release_firmware(hdsp->firmware); + release_firmware(hdsp->firmware); vfree(hdsp->fw_uploaded); if (hdsp->iobase) -- GitLab From 1ea7a568c63a4735872fc091efbd22d2e4d9c972 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 13:35:54 +0100 Subject: [PATCH 5036/9457] ALSA: powermac: Deletion of an unnecessary check before the function call "pci_dev_put" The pci_dev_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/ppc/pmac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 8a431bcb056c..5a13b22748b2 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -887,8 +887,7 @@ static int snd_pmac_free(struct snd_pmac *chip) } } - if (chip->pdev) - pci_dev_put(chip->pdev); + pci_dev_put(chip->pdev); of_node_put(chip->node); kfree(chip); return 0; -- GitLab From 07a186893af5a274877d11ce9e5d81c142890cf6 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Fri, 14 Nov 2014 10:48:31 -0800 Subject: [PATCH 5037/9457] spi: Add binding document for IMG SPFI controller The Synchronous Peripheral Flash Interface (SPFI) controller found on IMG SoCs supports single, dual, and (optionally) quad mode SPI transfers. Signed-off-by: Andrew Bresticker Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-img-spfi.txt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-img-spfi.txt diff --git a/Documentation/devicetree/bindings/spi/spi-img-spfi.txt b/Documentation/devicetree/bindings/spi/spi-img-spfi.txt new file mode 100644 index 000000000000..c7dd50fb8eb2 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-img-spfi.txt @@ -0,0 +1,37 @@ +IMG Synchronous Peripheral Flash Interface (SPFI) controller + +Required properties: +- compatible: Must be "img,spfi". +- reg: Must contain the base address and length of the SPFI registers. +- interrupts: Must contain the SPFI interrupt. +- clocks: Must contain an entry for each entry in clock-names. + See ../clock/clock-bindings.txt for details. +- clock-names: Must include the following entries: + - spfi: SPI operating clock + - sys: SPI system interface clock +- dmas: Must contain an entry for each entry in dma-names. + See ../dma/dma.txt for details. +- dma-names: Must include the following entries: + - rx + - tx +- #address-cells: Must be 1. +- #size-cells: Must be 0. + +Optional properties: +- img,supports-quad-mode: Should be set if the interface supports quad mode + SPI transfers. + +Example: + +spi@18100f00 { + compatible = "img,spfi"; + reg = <0x18100f00 0x100>; + interrupts = ; + clocks = <&spi_clk>, <&system_clk>; + clock-names = "spfi", "sys"; + dmas = <&mdc 9 0xffffffff 0>, <&mdc 10 0xffffffff 0>; + dma-names = "rx", "tx"; + + #address-cells = <1>; + #size-cells = <0>; +}; -- GitLab From deba25800a12b99e1a68bc83d33709be4b9a40b7 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Fri, 14 Nov 2014 10:48:32 -0800 Subject: [PATCH 5038/9457] spi: Add driver for IMG SPFI controller Add support for the Synchronous Peripheral Flash Interface (SPFI) master controller found on IMG SoCs. The SPFI controller supports 5 chip-select lines and single/dual/quad mode SPI transfers. Signed-off-by: Andrew Bresticker Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi-img-spfi.c | 746 +++++++++++++++++++++++++++++++++++++ 3 files changed, 754 insertions(+) create mode 100644 drivers/spi/spi-img-spfi.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 84e7c9e6ccef..98de2074e8fe 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -225,6 +225,13 @@ config SPI_GPIO GPIO operations, you should be able to leverage that for better speed with a custom version of this driver; see the source code. +config SPI_IMG_SPFI + tristate "IMG SPFI controller" + depends on MIPS || COMPILE_TEST + help + This enables support for the SPFI master controller found on + IMG SoCs. + config SPI_IMX tristate "Freescale i.MX SPI controllers" depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 78f24ca36fcf..37dc2e7d2c7e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o +obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c new file mode 100644 index 000000000000..43781c9fe521 --- /dev/null +++ b/drivers/spi/spi-img-spfi.c @@ -0,0 +1,746 @@ +/* + * IMG SPFI controller driver + * + * Copyright (C) 2007,2008,2013 Imagination Technologies Ltd. + * Copyright (C) 2014 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPFI_DEVICE_PARAMETER(x) (0x00 + 0x4 * (x)) +#define SPFI_DEVICE_PARAMETER_BITCLK_SHIFT 24 +#define SPFI_DEVICE_PARAMETER_BITCLK_MASK 0xff +#define SPFI_DEVICE_PARAMETER_CSSETUP_SHIFT 16 +#define SPFI_DEVICE_PARAMETER_CSSETUP_MASK 0xff +#define SPFI_DEVICE_PARAMETER_CSHOLD_SHIFT 8 +#define SPFI_DEVICE_PARAMETER_CSHOLD_MASK 0xff +#define SPFI_DEVICE_PARAMETER_CSDELAY_SHIFT 0 +#define SPFI_DEVICE_PARAMETER_CSDELAY_MASK 0xff + +#define SPFI_CONTROL 0x14 +#define SPFI_CONTROL_CONTINUE BIT(12) +#define SPFI_CONTROL_SOFT_RESET BIT(11) +#define SPFI_CONTROL_SEND_DMA BIT(10) +#define SPFI_CONTROL_GET_DMA BIT(9) +#define SPFI_CONTROL_TMODE_SHIFT 5 +#define SPFI_CONTROL_TMODE_MASK 0x7 +#define SPFI_CONTROL_TMODE_SINGLE 0 +#define SPFI_CONTROL_TMODE_DUAL 1 +#define SPFI_CONTROL_TMODE_QUAD 2 +#define SPFI_CONTROL_SPFI_EN BIT(0) + +#define SPFI_TRANSACTION 0x18 +#define SPFI_TRANSACTION_TSIZE_SHIFT 16 +#define SPFI_TRANSACTION_TSIZE_MASK 0xffff + +#define SPFI_PORT_STATE 0x1c +#define SPFI_PORT_STATE_DEV_SEL_SHIFT 20 +#define SPFI_PORT_STATE_DEV_SEL_MASK 0x7 +#define SPFI_PORT_STATE_CK_POL(x) BIT(19 - (x)) +#define SPFI_PORT_STATE_CK_PHASE(x) BIT(14 - (x)) + +#define SPFI_TX_32BIT_VALID_DATA 0x20 +#define SPFI_TX_8BIT_VALID_DATA 0x24 +#define SPFI_RX_32BIT_VALID_DATA 0x28 +#define SPFI_RX_8BIT_VALID_DATA 0x2c + +#define SPFI_INTERRUPT_STATUS 0x30 +#define SPFI_INTERRUPT_ENABLE 0x34 +#define SPFI_INTERRUPT_CLEAR 0x38 +#define SPFI_INTERRUPT_IACCESS BIT(12) +#define SPFI_INTERRUPT_GDEX8BIT BIT(11) +#define SPFI_INTERRUPT_ALLDONETRIG BIT(9) +#define SPFI_INTERRUPT_GDFUL BIT(8) +#define SPFI_INTERRUPT_GDHF BIT(7) +#define SPFI_INTERRUPT_GDEX32BIT BIT(6) +#define SPFI_INTERRUPT_GDTRIG BIT(5) +#define SPFI_INTERRUPT_SDFUL BIT(3) +#define SPFI_INTERRUPT_SDHF BIT(2) +#define SPFI_INTERRUPT_SDE BIT(1) +#define SPFI_INTERRUPT_SDTRIG BIT(0) + +/* + * There are four parallel FIFOs of 16 bytes each. The word buffer + * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an + * effective FIFO size of 64 bytes. The byte buffer (*_8BIT_VALID_DATA) + * accesses only a single FIFO, resulting in an effective FIFO size of + * 16 bytes. + */ +#define SPFI_32BIT_FIFO_SIZE 64 +#define SPFI_8BIT_FIFO_SIZE 16 + +struct img_spfi { + struct device *dev; + struct spi_master *master; + spinlock_t lock; + + void __iomem *regs; + phys_addr_t phys; + int irq; + struct clk *spfi_clk; + struct clk *sys_clk; + + struct dma_chan *rx_ch; + struct dma_chan *tx_ch; + bool tx_dma_busy; + bool rx_dma_busy; +}; + +static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) +{ + return readl(spfi->regs + reg); +} + +static inline void spfi_writel(struct img_spfi *spfi, u32 val, u32 reg) +{ + writel(val, spfi->regs + reg); +} + +static inline void spfi_start(struct img_spfi *spfi) +{ + u32 val; + + val = spfi_readl(spfi, SPFI_CONTROL); + val |= SPFI_CONTROL_SPFI_EN; + spfi_writel(spfi, val, SPFI_CONTROL); +} + +static inline void spfi_stop(struct img_spfi *spfi) +{ + u32 val; + + val = spfi_readl(spfi, SPFI_CONTROL); + val &= ~SPFI_CONTROL_SPFI_EN; + spfi_writel(spfi, val, SPFI_CONTROL); +} + +static inline void spfi_reset(struct img_spfi *spfi) +{ + spfi_writel(spfi, SPFI_CONTROL_SOFT_RESET, SPFI_CONTROL); + udelay(1); + spfi_writel(spfi, 0, SPFI_CONTROL); +} + +static void spfi_flush_tx_fifo(struct img_spfi *spfi) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(10); + + spfi_writel(spfi, SPFI_INTERRUPT_SDE, SPFI_INTERRUPT_CLEAR); + while (time_before(jiffies, timeout)) { + if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & + SPFI_INTERRUPT_SDE) + return; + cpu_relax(); + } + + dev_err(spfi->dev, "Timed out waiting for FIFO to drain\n"); + spfi_reset(spfi); +} + +static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, + unsigned int max) +{ + unsigned int count = 0; + u32 status; + + while (count < max) { + spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); + status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); + if (status & SPFI_INTERRUPT_SDFUL) + break; + spfi_writel(spfi, buf[count / 4], SPFI_TX_32BIT_VALID_DATA); + count += 4; + } + + return count; +} + +static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, + unsigned int max) +{ + unsigned int count = 0; + u32 status; + + while (count < max) { + spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); + status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); + if (status & SPFI_INTERRUPT_SDFUL) + break; + spfi_writel(spfi, buf[count], SPFI_TX_8BIT_VALID_DATA); + count++; + } + + return count; +} + +static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf, + unsigned int max) +{ + unsigned int count = 0; + u32 status; + + while (count < max) { + spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, + SPFI_INTERRUPT_CLEAR); + status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); + if (!(status & SPFI_INTERRUPT_GDEX32BIT)) + break; + buf[count / 4] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA); + count += 4; + } + + return count; +} + +static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, + unsigned int max) +{ + unsigned int count = 0; + u32 status; + + while (count < max) { + spfi_writel(spfi, SPFI_INTERRUPT_GDEX8BIT, + SPFI_INTERRUPT_CLEAR); + status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); + if (!(status & SPFI_INTERRUPT_GDEX8BIT)) + break; + buf[count] = spfi_readl(spfi, SPFI_RX_8BIT_VALID_DATA); + count++; + } + + return count; +} + +static int img_spfi_start_pio(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct img_spfi *spfi = spi_master_get_devdata(spi->master); + unsigned int tx_bytes = 0, rx_bytes = 0; + const void *tx_buf = xfer->tx_buf; + void *rx_buf = xfer->rx_buf; + unsigned long timeout; + + if (tx_buf) + tx_bytes = xfer->len; + if (rx_buf) + rx_bytes = xfer->len; + + spfi_start(spfi); + + timeout = jiffies + + msecs_to_jiffies(xfer->len * 8 * 1000 / xfer->speed_hz + 100); + while ((tx_bytes > 0 || rx_bytes > 0) && + time_before(jiffies, timeout)) { + unsigned int tx_count, rx_count; + + switch (xfer->bits_per_word) { + case 32: + tx_count = spfi_pio_write32(spfi, tx_buf, tx_bytes); + rx_count = spfi_pio_read32(spfi, rx_buf, rx_bytes); + break; + case 8: + default: + tx_count = spfi_pio_write8(spfi, tx_buf, tx_bytes); + rx_count = spfi_pio_read8(spfi, rx_buf, rx_bytes); + break; + } + + tx_buf += tx_count; + rx_buf += rx_count; + tx_bytes -= tx_count; + rx_bytes -= rx_count; + + cpu_relax(); + } + + if (rx_bytes > 0 || tx_bytes > 0) { + dev_err(spfi->dev, "PIO transfer timed out\n"); + spfi_reset(spfi); + return -ETIMEDOUT; + } + + if (tx_buf) + spfi_flush_tx_fifo(spfi); + spfi_stop(spfi); + + return 0; +} + +static void img_spfi_dma_rx_cb(void *data) +{ + struct img_spfi *spfi = data; + unsigned long flags; + + spin_lock_irqsave(&spfi->lock, flags); + + spfi->rx_dma_busy = false; + if (!spfi->tx_dma_busy) { + spfi_stop(spfi); + spi_finalize_current_transfer(spfi->master); + } + + spin_unlock_irqrestore(&spfi->lock, flags); +} + +static void img_spfi_dma_tx_cb(void *data) +{ + struct img_spfi *spfi = data; + unsigned long flags; + + spfi_flush_tx_fifo(spfi); + + spin_lock_irqsave(&spfi->lock, flags); + + spfi->tx_dma_busy = false; + if (!spfi->rx_dma_busy) { + spfi_stop(spfi); + spi_finalize_current_transfer(spfi->master); + } + + spin_unlock_irqrestore(&spfi->lock, flags); +} + +static int img_spfi_start_dma(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct img_spfi *spfi = spi_master_get_devdata(spi->master); + struct dma_async_tx_descriptor *rxdesc = NULL, *txdesc = NULL; + struct dma_slave_config rxconf, txconf; + + spfi->rx_dma_busy = false; + spfi->tx_dma_busy = false; + + if (xfer->rx_buf) { + rxconf.direction = DMA_DEV_TO_MEM; + switch (xfer->bits_per_word) { + case 32: + rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; + rxconf.src_addr_width = 4; + rxconf.src_maxburst = 4; + break; + case 8: + default: + rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; + rxconf.src_addr_width = 1; + rxconf.src_maxburst = 1; + } + dmaengine_slave_config(spfi->rx_ch, &rxconf); + + rxdesc = dmaengine_prep_slave_sg(spfi->rx_ch, xfer->rx_sg.sgl, + xfer->rx_sg.nents, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + if (!rxdesc) + goto stop_dma; + + rxdesc->callback = img_spfi_dma_rx_cb; + rxdesc->callback_param = spfi; + } + + if (xfer->tx_buf) { + txconf.direction = DMA_MEM_TO_DEV; + switch (xfer->bits_per_word) { + case 32: + txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; + txconf.dst_addr_width = 4; + txconf.dst_maxburst = 4; + break; + case 8: + default: + txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; + txconf.dst_addr_width = 1; + txconf.dst_maxburst = 1; + break; + } + dmaengine_slave_config(spfi->tx_ch, &txconf); + + txdesc = dmaengine_prep_slave_sg(spfi->tx_ch, xfer->tx_sg.sgl, + xfer->tx_sg.nents, + DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT); + if (!txdesc) + goto stop_dma; + + txdesc->callback = img_spfi_dma_tx_cb; + txdesc->callback_param = spfi; + } + + if (xfer->rx_buf) { + spfi->rx_dma_busy = true; + dmaengine_submit(rxdesc); + dma_async_issue_pending(spfi->rx_ch); + } + + if (xfer->tx_buf) { + spfi->tx_dma_busy = true; + dmaengine_submit(txdesc); + dma_async_issue_pending(spfi->tx_ch); + } + + spfi_start(spfi); + + return 1; + +stop_dma: + dmaengine_terminate_all(spfi->rx_ch); + dmaengine_terminate_all(spfi->tx_ch); + return -EIO; +} + +static void img_spfi_config(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct img_spfi *spfi = spi_master_get_devdata(spi->master); + u32 val, div; + + /* + * output = spfi_clk * (BITCLK / 512), where BITCLK must be a + * power of 2 up to 256 (where 255 == 256 since BITCLK is 8 bits) + */ + div = DIV_ROUND_UP(master->max_speed_hz, xfer->speed_hz); + div = clamp(512 / (1 << get_count_order(div)), 1, 255); + + val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select)); + val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK << + SPFI_DEVICE_PARAMETER_BITCLK_SHIFT); + val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; + spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); + + val = spfi_readl(spfi, SPFI_CONTROL); + val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA); + if (xfer->tx_buf) + val |= SPFI_CONTROL_SEND_DMA; + if (xfer->rx_buf) + val |= SPFI_CONTROL_GET_DMA; + val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT); + if (xfer->tx_nbits == SPI_NBITS_DUAL && + xfer->rx_nbits == SPI_NBITS_DUAL) + val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT; + else if (xfer->tx_nbits == SPI_NBITS_QUAD && + xfer->rx_nbits == SPI_NBITS_QUAD) + val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT; + val &= ~SPFI_CONTROL_CONTINUE; + if (!xfer->cs_change && !list_is_last(&xfer->transfer_list, + &master->cur_msg->transfers)) + val |= SPFI_CONTROL_CONTINUE; + spfi_writel(spfi, val, SPFI_CONTROL); + + val = spfi_readl(spfi, SPFI_PORT_STATE); + if (spi->mode & SPI_CPHA) + val |= SPFI_PORT_STATE_CK_PHASE(spi->chip_select); + else + val &= ~SPFI_PORT_STATE_CK_PHASE(spi->chip_select); + if (spi->mode & SPI_CPOL) + val |= SPFI_PORT_STATE_CK_POL(spi->chip_select); + else + val &= ~SPFI_PORT_STATE_CK_POL(spi->chip_select); + spfi_writel(spfi, val, SPFI_PORT_STATE); + + spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT, + SPFI_TRANSACTION); +} + +static int img_spfi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct img_spfi *spfi = spi_master_get_devdata(spi->master); + bool dma_reset = false; + unsigned long flags; + int ret; + + /* + * Stop all DMA and reset the controller if the previous transaction + * timed-out and never completed it's DMA. + */ + spin_lock_irqsave(&spfi->lock, flags); + if (spfi->tx_dma_busy || spfi->rx_dma_busy) { + dev_err(spfi->dev, "SPI DMA still busy\n"); + dma_reset = true; + } + spin_unlock_irqrestore(&spfi->lock, flags); + + if (dma_reset) { + dmaengine_terminate_all(spfi->tx_ch); + dmaengine_terminate_all(spfi->rx_ch); + spfi_reset(spfi); + } + + img_spfi_config(master, spi, xfer); + if (master->can_dma && master->can_dma(master, spi, xfer)) + ret = img_spfi_start_dma(master, spi, xfer); + else + ret = img_spfi_start_pio(master, spi, xfer); + + return ret; +} + +static void img_spfi_set_cs(struct spi_device *spi, bool enable) +{ + struct img_spfi *spfi = spi_master_get_devdata(spi->master); + u32 val; + + val = spfi_readl(spfi, SPFI_PORT_STATE); + val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << SPFI_PORT_STATE_DEV_SEL_SHIFT); + val |= spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; + spfi_writel(spfi, val, SPFI_PORT_STATE); +} + +static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *xfer) +{ + if (xfer->bits_per_word == 8 && xfer->len > SPFI_8BIT_FIFO_SIZE) + return true; + if (xfer->bits_per_word == 32 && xfer->len > SPFI_32BIT_FIFO_SIZE) + return true; + return false; +} + +static irqreturn_t img_spfi_irq(int irq, void *dev_id) +{ + struct img_spfi *spfi = (struct img_spfi *)dev_id; + u32 status; + + status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); + if (status & SPFI_INTERRUPT_IACCESS) { + spfi_writel(spfi, SPFI_INTERRUPT_IACCESS, SPFI_INTERRUPT_CLEAR); + dev_err(spfi->dev, "Illegal access interrupt"); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int img_spfi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct img_spfi *spfi; + struct resource *res; + int ret; + + master = spi_alloc_master(&pdev->dev, sizeof(*spfi)); + if (!master) + return -ENOMEM; + platform_set_drvdata(pdev, master); + + spfi = spi_master_get_devdata(master); + spfi->dev = &pdev->dev; + spfi->master = master; + spin_lock_init(&spfi->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + spfi->regs = devm_ioremap_resource(spfi->dev, res); + if (IS_ERR(spfi->regs)) { + ret = PTR_ERR(spfi->regs); + goto put_spi; + } + spfi->phys = res->start; + + spfi->irq = platform_get_irq(pdev, 0); + if (spfi->irq < 0) { + ret = spfi->irq; + goto put_spi; + } + ret = devm_request_irq(spfi->dev, spfi->irq, img_spfi_irq, + IRQ_TYPE_LEVEL_HIGH, dev_name(spfi->dev), spfi); + if (ret) + goto put_spi; + + spfi->sys_clk = devm_clk_get(spfi->dev, "sys"); + if (IS_ERR(spfi->sys_clk)) { + ret = PTR_ERR(spfi->sys_clk); + goto put_spi; + } + spfi->spfi_clk = devm_clk_get(spfi->dev, "spfi"); + if (IS_ERR(spfi->spfi_clk)) { + ret = PTR_ERR(spfi->spfi_clk); + goto put_spi; + } + + ret = clk_prepare_enable(spfi->sys_clk); + if (ret) + goto put_spi; + ret = clk_prepare_enable(spfi->spfi_clk); + if (ret) + goto disable_pclk; + + spfi_reset(spfi); + /* + * Only enable the error (IACCESS) interrupt. In PIO mode we'll + * poll the status of the FIFOs. + */ + spfi_writel(spfi, SPFI_INTERRUPT_IACCESS, SPFI_INTERRUPT_ENABLE); + + master->auto_runtime_pm = true; + master->bus_num = pdev->id; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL; + if (of_property_read_bool(spfi->dev->of_node, "img,supports-quad-mode")) + master->mode_bits |= SPI_TX_QUAD | SPI_RX_QUAD; + master->num_chipselect = 5; + master->dev.of_node = pdev->dev.of_node; + master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(8); + master->max_speed_hz = clk_get_rate(spfi->spfi_clk); + master->min_speed_hz = master->max_speed_hz / 512; + + master->set_cs = img_spfi_set_cs; + master->transfer_one = img_spfi_transfer_one; + + spfi->tx_ch = dma_request_slave_channel(spfi->dev, "tx"); + spfi->rx_ch = dma_request_slave_channel(spfi->dev, "rx"); + if (!spfi->tx_ch || !spfi->rx_ch) { + if (spfi->tx_ch) + dma_release_channel(spfi->tx_ch); + if (spfi->rx_ch) + dma_release_channel(spfi->rx_ch); + dev_warn(spfi->dev, "Failed to get DMA channels, falling back to PIO mode\n"); + } else { + master->dma_tx = spfi->tx_ch; + master->dma_rx = spfi->rx_ch; + master->can_dma = img_spfi_can_dma; + } + + pm_runtime_set_active(spfi->dev); + pm_runtime_enable(spfi->dev); + + ret = devm_spi_register_master(spfi->dev, master); + if (ret) + goto disable_pm; + + return 0; + +disable_pm: + pm_runtime_disable(spfi->dev); + if (spfi->rx_ch) + dma_release_channel(spfi->rx_ch); + if (spfi->tx_ch) + dma_release_channel(spfi->tx_ch); + clk_disable_unprepare(spfi->spfi_clk); +disable_pclk: + clk_disable_unprepare(spfi->sys_clk); +put_spi: + spi_master_put(master); + + return ret; +} + +static int img_spfi_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + struct img_spfi *spfi = spi_master_get_devdata(master); + + if (spfi->tx_ch) + dma_release_channel(spfi->tx_ch); + if (spfi->rx_ch) + dma_release_channel(spfi->rx_ch); + + pm_runtime_disable(spfi->dev); + if (!pm_runtime_status_suspended(spfi->dev)) { + clk_disable_unprepare(spfi->spfi_clk); + clk_disable_unprepare(spfi->sys_clk); + } + + spi_master_put(master); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int img_spfi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct img_spfi *spfi = spi_master_get_devdata(master); + + clk_disable_unprepare(spfi->spfi_clk); + clk_disable_unprepare(spfi->sys_clk); + + return 0; +} + +static int img_spfi_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct img_spfi *spfi = spi_master_get_devdata(master); + int ret; + + ret = clk_prepare_enable(spfi->sys_clk); + if (ret) + return ret; + ret = clk_prepare_enable(spfi->spfi_clk); + if (ret) { + clk_disable_unprepare(spfi->sys_clk); + return ret; + } + + return 0; +} +#endif /* CONFIG_PM_RUNTIME */ + +#ifdef CONFIG_PM_SLEEP +static int img_spfi_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + + return spi_master_suspend(master); +} + +static int img_spfi_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct img_spfi *spfi = spi_master_get_devdata(master); + int ret; + + ret = pm_runtime_get_sync(dev); + if (ret) + return ret; + spfi_reset(spfi); + pm_runtime_put(dev); + + return spi_master_resume(master); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops img_spfi_pm_ops = { + SET_RUNTIME_PM_OPS(img_spfi_runtime_suspend, img_spfi_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(img_spfi_suspend, img_spfi_resume) +}; + +static const struct of_device_id img_spfi_of_match[] = { + { .compatible = "img,spfi", }, + { }, +}; +MODULE_DEVICE_TABLE(of, img_spfi_of_match); + +static struct platform_driver img_spfi_driver = { + .driver = { + .name = "img-spfi", + .pm = &img_spfi_pm_ops, + .of_match_table = of_match_ptr(img_spfi_of_match), + }, + .probe = img_spfi_probe, + .remove = img_spfi_remove, +}; +module_platform_driver(img_spfi_driver); + +MODULE_DESCRIPTION("IMG SPFI controller driver"); +MODULE_AUTHOR("Andrew Bresticker "); +MODULE_LICENSE("GPL v2"); -- GitLab From 9a3b9c7a645d2781ead28360dec7ceabef0daa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 21:33:42 +0200 Subject: [PATCH 5039/9457] drm/i915: Silence valleyview_set_rps() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even with the rps debug messages signficantly recuced by commit 67956867aa07c59d6d83628bbc9ee4bd9799a1e1 Author: Ville Syrjälä Date: Tue Sep 2 15:12:17 2014 +0300 drm/i915: Don't spam dmesg with rps messages on vlv/chv we still get an inordinate amount of spam from this. Just kill the debug print. If someone wants to observe it they can just use the tracepoint. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 87bff1652cb0..fcbe335e37a3 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4504,14 +4504,8 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) "Odd GPU freq value\n")) val &= ~1; - if (val != dev_priv->rps.cur_freq) { - DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", - vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), - dev_priv->rps.cur_freq, - vlv_gpu_freq(dev_priv, val), val); - + if (val != dev_priv->rps.cur_freq) vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); - } I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); -- GitLab From c8e9627d2ad9efed125bcee8587ea27889fb06d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 21:33:44 +0200 Subject: [PATCH 5040/9457] drm/i915: Add a name for the Punit GPLLENABLE bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the magic number for the GPLLENABLE bit by adding a name for it. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a143127eb451..faf61f5fc0ec 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -576,6 +576,7 @@ enum punit_power_well { #define PUNIT_REG_GPU_LFM 0xd3 #define PUNIT_REG_GPU_FREQ_REQ 0xd4 #define PUNIT_REG_GPU_FREQ_STS 0xd8 +#define GPLLENABLE (1<<4) #define GENFREQSTATUS (1<<0) #define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc #define PUNIT_REG_CZ_TIMESTAMP 0xce diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fcbe335e37a3..1f2441ffa6e4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5333,7 +5333,7 @@ static void cherryview_enable_rps(struct drm_device *dev) val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); - DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no"); + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); dev_priv->rps.cur_freq = (val >> 8) & 0xff; @@ -5413,7 +5413,7 @@ static void valleyview_enable_rps(struct drm_device *dev) val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); - DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no"); + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); dev_priv->rps.cur_freq = (val >> 8) & 0xff; -- GitLab From 8d40c3ae51483059733187ba8bc6e031764fafec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 21:33:45 +0200 Subject: [PATCH 5041/9457] drm/i915: Warn if GPLL isn't used on vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our freq<->opcode conversions assume that GPLL is always used. Apparently that should be the case always, but let's scream if we ever encounter something different. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1f2441ffa6e4..cbf84cc84e55 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5333,6 +5333,9 @@ static void cherryview_enable_rps(struct drm_device *dev) val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + /* RPS code assumes GPLL is used */ + WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); @@ -5413,6 +5416,9 @@ static void valleyview_enable_rps(struct drm_device *dev) val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + /* RPS code assumes GPLL is used */ + WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); -- GitLab From ce611ef81ff73fe64962fb1b22d8279aab205ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 7 Nov 2014 21:33:46 +0200 Subject: [PATCH 5042/9457] drm/i915: Improve PCBR debug information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always print the final PCBR register value on both vlv and chv, and also tell us whether the BIOS was a good citizen or not. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cbf84cc84e55..eaae801f317a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5062,12 +5062,15 @@ static void cherryview_setup_pctx(struct drm_device *dev) pcbr = I915_READ(VLV_PCBR); if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) { + DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n"); paddr = (dev_priv->mm.stolen_base + (gtt->stolen_size - pctx_size)); pctx_paddr = (paddr & (~4095)); I915_WRITE(VLV_PCBR, pctx_paddr); } + + DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR)); } static void valleyview_setup_pctx(struct drm_device *dev) @@ -5093,6 +5096,8 @@ static void valleyview_setup_pctx(struct drm_device *dev) goto out; } + DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n"); + /* * From the Gunit register HAS: * The Gfx driver is expected to program this register and ensure @@ -5111,6 +5116,7 @@ static void valleyview_setup_pctx(struct drm_device *dev) I915_WRITE(VLV_PCBR, pctx_paddr); out: + DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR)); dev_priv->vlv_pctx = pctx; } @@ -5302,8 +5308,6 @@ static void cherryview_enable_rps(struct drm_device *dev) /* For now we assume BIOS is allocating and populating the PCBR */ pcbr = I915_READ(VLV_PCBR); - DRM_DEBUG_DRIVER("PCBR offset : 0x%x\n", pcbr); - /* 3: Enable RC6 */ if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) && (pcbr >> VLV_PCBR_ADDR_SHIFT)) -- GitLab From f2bf2589834faec7af8c02c3949c90788d21b790 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 17 Nov 2014 14:09:03 +0200 Subject: [PATCH 5043/9457] net: can: c_can: Add support for TI am4372 DCAN AM4372 SoC has 2 DCAN modules. Add compatible id and raminit driver data for it. The driver data is same as AM3352 but this gives us flexibility to add AM4372 specific quirks if required later. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/c_can.txt | 3 ++- drivers/net/can/c_can/c_can_platform.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 6731730eec0d..5a1d8b0c39e9 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -4,7 +4,8 @@ Bosch C_CAN/D_CAN controller Device Tree Bindings Required properties: - compatible : Should be "bosch,c_can" for C_CAN controllers and "bosch,d_can" for D_CAN controllers. - Can be "ti,dra7-d_can" or "ti,am3352-d_can". + Can be "ti,dra7-d_can", "ti,am3352-d_can" or + "ti,am4372-d_can". - reg : physical base address and size of the C_CAN/D_CAN registers map - interrupts : property with a value describing the interrupt diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f4488e5d5d68..a4535d2142a7 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -235,6 +235,7 @@ static const struct of_device_id c_can_of_table[] = { { .compatible = "bosch,d_can", .data = &d_can_drvdata }, { .compatible = "ti,dra7-d_can", .data = &dra7_dcan_drvdata }, { .compatible = "ti,am3352-d_can", .data = &am3352_dcan_drvdata }, + { .compatible = "ti,am4372-d_can", .data = &am3352_dcan_drvdata }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, c_can_of_table); -- GitLab From dd06f88cd0c730421b575f423d8e75f6ed348804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 10 Nov 2014 22:55:12 +0200 Subject: [PATCH 5044/9457] drm/i915: Refactor vlv/chv GPU frequency divider setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The divider used in the GPU frequency calculations is compatible between vlv and chv. vlv just wants doubled values compared to chv. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 104 +++++++++++--------------------- 1 file changed, 35 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index eaae801f317a..feda281f7cc2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7206,99 +7206,65 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) return 0; } -static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) +static int vlv_gpu_freq_div(unsigned int czclk_freq) { - int div; - - /* 4 x czclk */ - switch (dev_priv->mem_freq) { - case 800: - div = 10; - break; - case 1066: - div = 12; - break; - case 1333: - div = 16; - break; + switch (czclk_freq) { + case 200: + return 10; + case 267: + return 12; + case 320: + case 333: + case 400: + return 16; default: return -1; } +} - return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div); +static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) +{ + int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); + + div = vlv_gpu_freq_div(czclk_freq); + if (div < 0) + return div; + + return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div); } static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) { - int mul; + int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); - /* 4 x czclk */ - switch (dev_priv->mem_freq) { - case 800: - mul = 10; - break; - case 1066: - mul = 12; - break; - case 1333: - mul = 16; - break; - default: - return -1; - } + mul = vlv_gpu_freq_div(czclk_freq); + if (mul < 0) + return mul; - return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6; + return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6; } static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) { - int div, freq; - - switch (dev_priv->rps.cz_freq) { - case 200: - div = 5; - break; - case 267: - div = 6; - break; - case 320: - case 333: - case 400: - div = 8; - break; - default: - return -1; - } + int div, czclk_freq = dev_priv->rps.cz_freq; - freq = (DIV_ROUND_CLOSEST((dev_priv->rps.cz_freq * val), 2 * div) / 2); + div = vlv_gpu_freq_div(czclk_freq) / 2; + if (div < 0) + return div; - return freq; + return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2; } static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) { - int mul, opcode; + int mul, czclk_freq = dev_priv->rps.cz_freq; - switch (dev_priv->rps.cz_freq) { - case 200: - mul = 5; - break; - case 267: - mul = 6; - break; - case 320: - case 333: - case 400: - mul = 8; - break; - default: - return -1; - } + mul = vlv_gpu_freq_div(czclk_freq) / 2; + if (mul < 0) + return mul; /* CHV needs even values */ - opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2); - - return opcode; + return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2; } int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) -- GitLab From 80b83b621732c3bb0ae617b4bb9cbb2f1436121d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 10 Nov 2014 22:55:14 +0200 Subject: [PATCH 5045/9457] drm/i915: Add missing newline to 'DDR speed' debug messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index feda281f7cc2..290af15af067 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5153,7 +5153,7 @@ static void valleyview_init_gt_powersave(struct drm_device *dev) dev_priv->mem_freq = 1333; break; } - DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); + DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; @@ -5222,7 +5222,7 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) dev_priv->mem_freq = 1600; break; } - DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); + DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; -- GitLab From ab3fb15730fd7a3d2d00c926bc95a81bb283a90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 10 Nov 2014 22:55:15 +0200 Subject: [PATCH 5046/9457] drm/i915: Change CHV SKU400 GPU freq divider to 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to "Cherryview_GFXclocks_y14w36d1.xlsx" the GPU frequency divider should be 10 in when the CZ clock is 400 MHz. Change the code to agree so that we report the correct frequencies. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 290af15af067..929648f2373f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7215,8 +7215,9 @@ static int vlv_gpu_freq_div(unsigned int czclk_freq) return 12; case 320: case 333: - case 400: return 16; + case 400: + return 20; default: return -1; } -- GitLab From 5ce8e7fdcc7a89f7d51065c92708f2a2234fdf41 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 5 Nov 2014 19:14:31 +0530 Subject: [PATCH 5047/9457] ath10k: handle ieee80211 header and payload tracing separately For packet log, the transmitted frame 802.11 header alone is sufficient. Recording entire packet is also consuming lot of disk space. To optimize this, tx and rx data tracepoints are splitted into header and payload tracepoints. To record tx ieee80211 headers trace-cmd record -e ath10k_tx_hdr To record complete packets trace-cmd record -e ath10k_tx_hdr -e ath10k_tx_payload Cc: Michal Kazior Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 +- drivers/net/wireless/ath/ath10k/htt_tx.c | 3 +- drivers/net/wireless/ath/ath10k/trace.h | 80 ++++++++++++++++++++---- drivers/net/wireless/ath/ath10k/wmi.c | 7 ++- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index a691fdf2fbae..52c630672718 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -297,8 +297,6 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) DMA_FROM_DEVICE); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ", msdu->data, msdu->len + skb_tailroom(msdu)); - trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len + - skb_tailroom(msdu)); return msdu; } @@ -903,6 +901,8 @@ static void ath10k_process_rx(struct ath10k *ar, !!(status->flag & RX_FLAG_AMSDU_MORE)); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", skb->data, skb->len); + trace_ath10k_rx_hdr(ar, skb->data, skb->len); + trace_ath10k_rx_payload(ar, skb->data, skb->len); ieee80211_rx(ar->hw, skb); } diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 1702c97b5ca5..5b7e42f7377c 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -563,7 +563,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) (u32)skb_cb->paddr, vdev_id, tid); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", msdu->data, msdu->len); - trace_ath10k_htt_tx_msdu(ar, msdu->data, msdu->len); + trace_ath10k_tx_hdr(ar, msdu->data, msdu->len); + trace_ath10k_tx_payload(ar, msdu->data, msdu->len); sg_items[0].transfer_id = 0; sg_items[0].transfer_context = NULL; diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index b9a2ba6bf6c0..ceea5668f3f6 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -20,6 +20,13 @@ #include #include "core.h" +#if !defined(_TRACE_H_) +static inline u32 ath10k_frm_hdr_len(void *buf) +{ + return ieee80211_hdrlen(((struct ieee80211_hdr *)buf)->frame_control); +} +#endif + #define _TRACE_H_ /* create empty functions when tracing is disabled */ @@ -341,7 +348,7 @@ TRACE_EVENT(ath10k_txrx_tx_unref, ) ); -DECLARE_EVENT_CLASS(ath10k_data_event, +DECLARE_EVENT_CLASS(ath10k_hdr_event, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len), @@ -350,14 +357,14 @@ DECLARE_EVENT_CLASS(ath10k_data_event, __string(device, dev_name(ar->dev)) __string(driver, dev_driver_string(ar->dev)) __field(size_t, len) - __dynamic_array(u8, data, len) + __dynamic_array(u8, data, ath10k_frm_hdr_len(data)) ), TP_fast_assign( __assign_str(device, dev_name(ar->dev)); __assign_str(driver, dev_driver_string(ar->dev)); - __entry->len = len; - memcpy(__get_dynamic_array(data), data, len); + __entry->len = ath10k_frm_hdr_len(data); + memcpy(__get_dynamic_array(data), data, __entry->len); ), TP_printk( @@ -368,30 +375,81 @@ DECLARE_EVENT_CLASS(ath10k_data_event, ) ); -DEFINE_EVENT(ath10k_data_event, ath10k_htt_tx_msdu, - TP_PROTO(struct ath10k *ar, void *data, size_t len), - TP_ARGS(ar, data, len) +DECLARE_EVENT_CLASS(ath10k_payload_event, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + + TP_ARGS(ar, data, len), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(size_t, len) + __dynamic_array(u8, payload, (len - ath10k_frm_hdr_len(data))) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->len = len - ath10k_frm_hdr_len(data); + memcpy(__get_dynamic_array(payload), + data + ath10k_frm_hdr_len(data), __entry->len); + ), + + TP_printk( + "%s %s len %zu\n", + __get_str(driver), + __get_str(device), + __entry->len + ) ); -DEFINE_EVENT(ath10k_data_event, ath10k_htt_rx_pop_msdu, +DEFINE_EVENT(ath10k_hdr_event, ath10k_tx_hdr, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len) ); -DEFINE_EVENT(ath10k_data_event, ath10k_wmi_mgmt_tx, +DEFINE_EVENT(ath10k_payload_event, ath10k_tx_payload, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len) ); -DEFINE_EVENT(ath10k_data_event, ath10k_wmi_bcn_tx, +DEFINE_EVENT(ath10k_hdr_event, ath10k_rx_hdr, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len) ); -DEFINE_EVENT(ath10k_data_event, ath10k_htt_rx_desc, +DEFINE_EVENT(ath10k_payload_event, ath10k_rx_payload, TP_PROTO(struct ath10k *ar, void *data, size_t len), TP_ARGS(ar, data, len) ); + +TRACE_EVENT(ath10k_htt_rx_desc, + TP_PROTO(struct ath10k *ar, void *data, size_t len), + + TP_ARGS(ar, data, len), + + TP_STRUCT__entry( + __string(device, dev_name(ar->dev)) + __string(driver, dev_driver_string(ar->dev)) + __field(u16, len) + __dynamic_array(u8, rxdesc, len) + ), + + TP_fast_assign( + __assign_str(device, dev_name(ar->dev)); + __assign_str(driver, dev_driver_string(ar->dev)); + __entry->len = len; + memcpy(__get_dynamic_array(rxdesc), data, len); + ), + + TP_printk( + "%s %s rxdesc len %d", + __get_str(driver), + __get_str(device), + __entry->len + ) +); + #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 5592844ce54b..fb63f3374f71 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -838,7 +838,8 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); - trace_ath10k_wmi_mgmt_tx(ar, skb->data, skb->len); + trace_ath10k_tx_hdr(ar, skb->data, skb->len); + trace_ath10k_tx_payload(ar, skb->data, skb->len); /* Send the management frame buffer to the target */ ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); @@ -1897,7 +1898,9 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) arvif->beacon = bcn; arvif->beacon_sent = false; - trace_ath10k_wmi_bcn_tx(ar, bcn->data, bcn->len); + trace_ath10k_tx_hdr(ar, bcn->data, bcn->len); + trace_ath10k_tx_payload(ar, bcn->data, bcn->len); + ath10k_wmi_tx_beacon_nowait(arvif); skip: spin_unlock_bh(&ar->data_lock); -- GitLab From 8868b12c0bb5e3d1be32353d54b5e84bb4b3bea1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 17 Nov 2014 16:44:14 +0200 Subject: [PATCH 5048/9457] ath10k: add modpram 'skip_otp' to ignore empty otp error during BMI This patch would help bring up wifi interface with default board data in case of failures in otp download. It is useful for initial calibration. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 6f2c459160f0..f660553c6c48 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -31,12 +31,17 @@ unsigned int ath10k_debug_mask; static bool uart_print; static unsigned int ath10k_p2p; +static bool skip_otp; + module_param_named(debug_mask, ath10k_debug_mask, uint, 0644); module_param(uart_print, bool, 0644); module_param_named(p2p, ath10k_p2p, uint, 0644); +module_param(skip_otp, bool, 0644); + MODULE_PARM_DESC(debug_mask, "Debugging mask"); MODULE_PARM_DESC(uart_print, "Uart target debugging"); MODULE_PARM_DESC(p2p, "Enable ath10k P2P support"); +MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); static const struct ath10k_hw_params ath10k_hw_params_list[] = { { @@ -280,7 +285,7 @@ static int ath10k_download_and_run_otp(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); - if (result != 0) { + if (!skip_otp && result != 0) { ath10k_err(ar, "otp calibration failed: %d", result); return -EINVAL; } -- GitLab From 78157a1c4478746b051e0932019b126b0c947e22 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 17 Nov 2014 16:44:15 +0200 Subject: [PATCH 5049/9457] ath10k: advertise support for AP mode channel width changes This will enable AP mode to change channel width dynamically based on 20/40 intolerance report sent by associated client. Signed-off-by: Rajkumar Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 9e4748fbcf8a..2a224f519d66 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4927,6 +4927,8 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->wiphy->max_remain_on_channel_duration = 5000; ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; + /* * on LL hardware queues are managed entirely by the FW * so we only advertise to mac we can do the queues thing -- GitLab From 9de8f26f0038133bdfb8cf847936645dab949d88 Mon Sep 17 00:00:00 2001 From: Peter Oh Date: Mon, 17 Nov 2014 16:44:15 +0200 Subject: [PATCH 5050/9457] ath10k: fix mismatched wmi api call Fix to use v10.2 wmi call for firmware v10.2. It turned out that peer association function was using v10.1 wmi call for v10.2 firmware during code review. Signed-off-by: Peter Oh Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index fb63f3374f71..c2bc8282f6cb 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -4194,9 +4194,9 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar, if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) - ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); - else ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); + else + ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); } else { ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); } -- GitLab From 187024b36c635bd454c1b1587b58c9439d3a46ad Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Mon, 17 Nov 2014 19:26:29 +0530 Subject: [PATCH 5051/9457] ASoC: rt5631: Fixing compilation warning when DT is disabled Fixes the following compilation warning: Warning: 'rt5631_i2c_dt_ids' defined but not used - when DT is not used. Signed-off-by: Claude Youn Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown --- sound/soc/codecs/rt5631.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 3b7d5e4a3ef6..9425545e8403 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1691,12 +1691,14 @@ static const struct i2c_device_id rt5631_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); +#ifdef CONFIG_OF static struct of_device_id rt5631_i2c_dt_ids[] = { { .compatible = "realtek,rt5631"}, { .compatible = "realtek,alc5631"}, { } }; MODULE_DEVICE_TABLE(of, rt5631_i2c_dt_ids); +#endif static const struct regmap_config rt5631_regmap_config = { .reg_bits = 8, -- GitLab From 4ba2a8b4d80a864a02d5d6898ae54f9d45afbb33 Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Thu, 13 Nov 2014 14:24:07 -0500 Subject: [PATCH 5052/9457] crypto: caam - Remove unnecessary smp_read_barrier_depends() Recently lockless_dereference() was added which can be used in place of hard-coding smp_read_barrier_depends(). The following PATCH makes the change. Signed-off-by: Pranith Kumar Reviewed-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/jr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 4d18e27ffa9e..9207c907a128 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -181,8 +181,6 @@ static void caam_jr_dequeue(unsigned long devarg) for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { sw_idx = (tail + i) & (JOBR_DEPTH - 1); - smp_read_barrier_depends(); - if (jrp->outring[hw_idx].desc == jrp->entinfo[sw_idx].desc_addr_dma) break; /* found */ @@ -218,7 +216,6 @@ static void caam_jr_dequeue(unsigned long devarg) if (sw_idx == tail) { do { tail = (tail + 1) & (JOBR_DEPTH - 1); - smp_read_barrier_depends(); } while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && jrp->entinfo[tail].desc_addr_dma == 0); -- GitLab From 52744af3af977ccbbf768be34650d7c75cfc1ad6 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Fri, 14 Nov 2014 05:26:21 +0100 Subject: [PATCH 5053/9457] crypto: doc - document uncovered member variables Fix documentation typo for shash_alg->descsize. Add documentation for initially uncovered member variables. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- include/crypto/hash.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/crypto/hash.h b/include/crypto/hash.h index 3d66e8bd0932..98abda9ed3aa 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -38,6 +38,10 @@ struct crypto_ahash; * will save the partial state of the transformation into it. On the * other side, the @import function will load the state from a * buffer of this size as well. + * @base: Start of data structure of cipher algorithm. The common data + * structure of crypto_alg contains information common to all ciphers. + * The hash_alg_common data structure now adds the hash-specific + * information. */ struct hash_alg_common { unsigned int digestsize; @@ -114,6 +118,7 @@ struct ahash_request { * entire state of the ongoing transformation from a provided block of * data so the transformation can continue from this point onward. No * data processing happens at this point. + * @halg: see struct hash_alg_common */ struct ahash_alg { int (*init)(struct ahash_request *req); @@ -153,7 +158,7 @@ struct shash_desc { * @setkey: see struct ahash_alg * @digestsize: see struct ahash_alg * @statesize: see struct ahash_alg - * @dedcsize: Size of the operational state for the message digest. This state + * @descsize: Size of the operational state for the message digest. This state * size is the memory size that needs to be allocated for * shash_desc.__ctx * @base: internally used -- GitLab From aa408d6019775c1b4362895df7929a043fa79804 Mon Sep 17 00:00:00 2001 From: "Struk, Tadeusz" Date: Fri, 14 Nov 2014 11:23:52 -0800 Subject: [PATCH 5054/9457] crypto: qat - Use memzero_explicit Use the new memzero_explicit function to cleanup sensitive data. Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- drivers/crypto/qat/qat_common/qat_algs.c | 36 +++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 25a409ca2d2a..31076eac0186 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -161,7 +161,7 @@ static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash, __be64 *hash512_state_out; int i, offset; - memset(auth_state.data, '\0', MAX_AUTH_STATE_SIZE + 64); + memzero_explicit(auth_state.data, MAX_AUTH_STATE_SIZE + 64); shash->tfm = ctx->hash_tfm; shash->flags = 0x0; @@ -174,13 +174,13 @@ static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash, memcpy(ipad, buff, digest_size); memcpy(opad, buff, digest_size); - memset(ipad + digest_size, 0, block_size - digest_size); - memset(opad + digest_size, 0, block_size - digest_size); + memzero_explicit(ipad + digest_size, block_size - digest_size); + memzero_explicit(opad + digest_size, block_size - digest_size); } else { memcpy(ipad, auth_key, auth_keylen); memcpy(opad, auth_key, auth_keylen); - memset(ipad + auth_keylen, 0, block_size - auth_keylen); - memset(opad + auth_keylen, 0, block_size - auth_keylen); + memzero_explicit(ipad + auth_keylen, block_size - auth_keylen); + memzero_explicit(opad + auth_keylen, block_size - auth_keylen); } for (i = 0; i < block_size; i++) { @@ -254,6 +254,8 @@ static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash, default: return -EFAULT; } + memzero_explicit(ipad, block_size); + memzero_explicit(opad, block_size); return 0; } @@ -492,12 +494,12 @@ static int qat_alg_setkey(struct crypto_aead *tfm, const uint8_t *key, if (ctx->enc_cd) { /* rekeying */ dev = &GET_DEV(ctx->inst->accel_dev); - memset(ctx->enc_cd, 0, sizeof(struct qat_alg_cd)); - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd)); - memset(&ctx->enc_fw_req_tmpl, 0, - sizeof(struct icp_qat_fw_la_bulk_req)); - memset(&ctx->dec_fw_req_tmpl, 0, - sizeof(struct icp_qat_fw_la_bulk_req)); + memzero_explicit(ctx->enc_cd, sizeof(struct qat_alg_cd)); + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd)); + memzero_explicit(&ctx->enc_fw_req_tmpl, + sizeof(struct icp_qat_fw_la_bulk_req)); + memzero_explicit(&ctx->dec_fw_req_tmpl, + sizeof(struct icp_qat_fw_la_bulk_req)); } else { /* new key */ int node = get_current_node(); @@ -534,10 +536,12 @@ static int qat_alg_setkey(struct crypto_aead *tfm, const uint8_t *key, return 0; out_free_all: + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd)); dma_free_coherent(dev, sizeof(struct qat_alg_cd), ctx->dec_cd, ctx->dec_cd_paddr); ctx->dec_cd = NULL; out_free_enc: + memzero_explicit(ctx->enc_cd, sizeof(struct qat_alg_cd)); dma_free_coherent(dev, sizeof(struct qat_alg_cd), ctx->enc_cd, ctx->enc_cd_paddr); ctx->enc_cd = NULL; @@ -832,7 +836,7 @@ static int qat_alg_init(struct crypto_tfm *tfm, { struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm); - memset(ctx, '\0', sizeof(*ctx)); + memzero_explicit(ctx, sizeof(*ctx)); ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); if (IS_ERR(ctx->hash_tfm)) return -EFAULT; @@ -872,12 +876,16 @@ static void qat_alg_exit(struct crypto_tfm *tfm) return; dev = &GET_DEV(inst->accel_dev); - if (ctx->enc_cd) + if (ctx->enc_cd) { + memzero_explicit(ctx->enc_cd, sizeof(struct qat_alg_cd)); dma_free_coherent(dev, sizeof(struct qat_alg_cd), ctx->enc_cd, ctx->enc_cd_paddr); - if (ctx->dec_cd) + } + if (ctx->dec_cd) { + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd)); dma_free_coherent(dev, sizeof(struct qat_alg_cd), ctx->dec_cd, ctx->dec_cd_paddr); + } qat_crypto_put_instance(inst); } -- GitLab From f5f7d3c6e46ec8d4f8a38055267de89ec57b42b9 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 14 Nov 2014 17:24:32 +0000 Subject: [PATCH 5055/9457] drm/i915/skl: Remove spurious warn in get_ddi_pll() When reading out a DDI config that uses a PLL that is not part of the shared_dpll scheme (DPLL0), it's totally normal to end up in the default: case of that switch. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c42a0401bfa5..7d58a64195d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8029,8 +8029,6 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, case SKL_DPLL3: pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; break; - default: - WARN(1, "Unknown DPLL programmed\n"); } } -- GitLab From 3c25fa14f0bfa21a0b8d5efc3174d0506682658d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 30 Oct 2014 16:43:48 -0600 Subject: [PATCH 5056/9457] selftests/user: move test out of Makefile into a shell script Currently user copy test is run from the Makefile. Move it out of the Makefile to be run from a shell script to allow the test to be run as stand-alone test, in addition to allowing the test run from a make target. Signed-off-by: Shuah Khan --- tools/testing/selftests/user/Makefile | 8 +------- tools/testing/selftests/user/test_user_copy.sh | 10 ++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100755 tools/testing/selftests/user/test_user_copy.sh diff --git a/tools/testing/selftests/user/Makefile b/tools/testing/selftests/user/Makefile index 396255bd720e..12c9d15bab07 100644 --- a/tools/testing/selftests/user/Makefile +++ b/tools/testing/selftests/user/Makefile @@ -4,10 +4,4 @@ all: run_tests: all - @if /sbin/modprobe test_user_copy ; then \ - rmmod test_user_copy; \ - echo "user_copy: ok"; \ - else \ - echo "user_copy: [FAIL]"; \ - exit 1; \ - fi + ./test_user_copy.sh diff --git a/tools/testing/selftests/user/test_user_copy.sh b/tools/testing/selftests/user/test_user_copy.sh new file mode 100755 index 000000000000..350107f40c1d --- /dev/null +++ b/tools/testing/selftests/user/test_user_copy.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# Runs copy_to/from_user infrastructure using test_user_copy kernel module + +if /sbin/modprobe -q test_user_copy; then + /sbin/modprobe -q -r test_user_copy + echo "user_copy: ok" +else + echo "user_copy: [FAIL]" + exit 1 +fi -- GitLab From 7fb2c3ea28bf7b748923a7cd58b6f49bce491bb7 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 3 Oct 2014 09:04:23 -0600 Subject: [PATCH 5057/9457] selftests: add kselftest framework for uniform test reporting Add kselftest framework for tests to use. This is a light weight framework provides a set of interfaces to report test results. Tests can use these interfaces to report pass, and fail cases as well as when failure is due to configuration problems such as missing modules, or when a test that is should fail, fails as expected, and a test that should fail, passes. The framework uses POSIX standard return codes for reporting results to address the needs of users that want to run the kernel selftests from their user-space test suites and want to know why a test failed. In addition, the framework includes interfaces to use to report test statistics on number of tests passed and failed. Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest.h | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 tools/testing/selftests/kselftest.h diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h new file mode 100644 index 000000000000..572c8888167a --- /dev/null +++ b/tools/testing/selftests/kselftest.h @@ -0,0 +1,62 @@ +/* + * kselftest.h: kselftest framework return codes to include from + * selftests. + * + * Copyright (c) 2014 Shuah Khan + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * This file is released under the GPLv2. + */ +#ifndef __KSELFTEST_H +#define __KSELFTEST_H + +#include +#include + +/* counters */ +struct ksft_count { + unsigned int ksft_pass; + unsigned int ksft_fail; + unsigned int ksft_xfail; + unsigned int ksft_xpass; + unsigned int ksft_xskip; +}; + +static struct ksft_count ksft_cnt; + +static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; } +static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; } +static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; } +static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; } +static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; } + +static inline void ksft_print_cnts(void) +{ + printf("Pass: %d Fail: %d Xfail: %d Xpass: %d, Xskip: %d\n", + ksft_cnt.ksft_pass, ksft_cnt.ksft_fail, + ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass, + ksft_cnt.ksft_xskip); +} + +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +static inline int ksft_exit_xfail(void) +{ + exit(2); +} +static inline int ksft_exit_xpass(void) +{ + exit(3); +} +static inline int ksft_exit_skip(void) +{ + exit(4); +} + +#endif /* __KSELFTEST_H */ -- GitLab From b36169041c07378aa17e8afff643aed89be9acd4 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 3 Oct 2014 09:06:22 -0600 Subject: [PATCH 5058/9457] selftests/breakpoints: change test to use ksft framework Change breakpoints test to use kselftest framework to report test results. Signed-off-by: Shuah Khan --- tools/testing/selftests/breakpoints/breakpoint_test.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/breakpoints/breakpoint_test.c b/tools/testing/selftests/breakpoints/breakpoint_test.c index a0743f3b2b57..120895ab5505 100644 --- a/tools/testing/selftests/breakpoints/breakpoint_test.c +++ b/tools/testing/selftests/breakpoints/breakpoint_test.c @@ -17,6 +17,8 @@ #include #include +#include "../kselftest.h" + /* Breakpoint access modes */ enum { @@ -42,7 +44,7 @@ static void set_breakpoint_addr(void *addr, int n) offsetof(struct user, u_debugreg[n]), addr); if (ret) { perror("Can't set breakpoint addr\n"); - exit(-1); + ksft_exit_fail(); } } @@ -105,7 +107,7 @@ static void toggle_breakpoint(int n, int type, int len, offsetof(struct user, u_debugreg[7]), dr7); if (ret) { perror("Can't set dr7"); - exit(-1); + ksft_exit_fail(); } } @@ -275,7 +277,7 @@ static void check_success(const char *msg) msg2 = "Ok"; if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) { perror("Can't poke\n"); - exit(-1); + ksft_exit_fail(); } } @@ -390,5 +392,5 @@ int main(int argc, char **argv) wait(NULL); - return 0; + return ksft_exit_pass(); } -- GitLab From 56661564e1fea94c42289edd59361a1f87932410 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 3 Oct 2014 09:07:12 -0600 Subject: [PATCH 5059/9457] selftests/ipc: change test to use ksft framework Change ipc test to use kselftest framework to report test results. With this change this test exits with EXIT_FAIL instead of -errno. Changed print errno in test fail messages to not loose that information. Signed-off-by: Shuah Khan --- tools/testing/selftests/ipc/msgque.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c index 552f0810bffb..1b2ce334bb3f 100644 --- a/tools/testing/selftests/ipc/msgque.c +++ b/tools/testing/selftests/ipc/msgque.c @@ -5,6 +5,8 @@ #include #include +#include "../kselftest.h" + #define MAX_MSG_SIZE 32 struct msg1 { @@ -195,58 +197,58 @@ int main(int argc, char **argv) if (getuid() != 0) { printf("Please run the test as root - Exiting.\n"); - exit(1); + return ksft_exit_fail(); } msgque.key = ftok(argv[0], 822155650); if (msgque.key == -1) { - printf("Can't make key\n"); - return -errno; + printf("Can't make key: %d\n", -errno); + return ksft_exit_fail(); } msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666); if (msgque.msq_id == -1) { err = -errno; - printf("Can't create queue\n"); + printf("Can't create queue: %d\n", err); goto err_out; } err = fill_msgque(&msgque); if (err) { - printf("Failed to fill queue\n"); + printf("Failed to fill queue: %d\n", err); goto err_destroy; } err = dump_queue(&msgque); if (err) { - printf("Failed to dump queue\n"); + printf("Failed to dump queue: %d\n", err); goto err_destroy; } err = check_and_destroy_queue(&msgque); if (err) { - printf("Failed to check and destroy queue\n"); + printf("Failed to check and destroy queue: %d\n", err); goto err_out; } err = restore_queue(&msgque); if (err) { - printf("Failed to restore queue\n"); + printf("Failed to restore queue: %d\n", err); goto err_destroy; } err = check_and_destroy_queue(&msgque); if (err) { - printf("Failed to test queue\n"); + printf("Failed to test queue: %d\n", err); goto err_out; } - return 0; + return ksft_exit_pass(); err_destroy: if (msgctl(msgque.msq_id, IPC_RMID, 0)) { printf("Failed to destroy queue: %d\n", -errno); - return -errno; + return ksft_exit_fail(); } err_out: - return err; + return ksft_exit_fail(); } -- GitLab From e061bcd88573863daef2c67888ced5333b2ba536 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 3 Oct 2014 09:08:14 -0600 Subject: [PATCH 5060/9457] selftests/kcmp: change test to use ksft framework Change kcmp test to use kselftest framework to report test results and test statistics. Signed-off-by: Shuah Khan --- tools/testing/selftests/kcmp/kcmp_test.c | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c index dbba4084869c..a5a4da856dfe 100644 --- a/tools/testing/selftests/kcmp/kcmp_test.c +++ b/tools/testing/selftests/kcmp/kcmp_test.c @@ -17,6 +17,8 @@ #include #include +#include "../kselftest.h" + static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2) { return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2); @@ -34,13 +36,13 @@ int main(int argc, char **argv) if (fd1 < 0) { perror("Can't create file"); - exit(1); + ksft_exit_fail(); } pid2 = fork(); if (pid2 < 0) { perror("fork failed"); - exit(1); + ksft_exit_fail(); } if (!pid2) { @@ -50,7 +52,7 @@ int main(int argc, char **argv) fd2 = open(kpath, O_RDWR, 0644); if (fd2 < 0) { perror("Can't open file"); - exit(1); + ksft_exit_fail(); } /* An example of output and arguments */ @@ -74,23 +76,34 @@ int main(int argc, char **argv) if (ret) { printf("FAIL: 0 expected but %d returned (%s)\n", ret, strerror(errno)); + ksft_inc_fail_cnt(); ret = -1; - } else + } else { printf("PASS: 0 returned as expected\n"); + ksft_inc_pass_cnt(); + } /* Compare with self */ ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0); if (ret) { printf("FAIL: 0 expected but %d returned (%s)\n", ret, strerror(errno)); + ksft_inc_fail_cnt(); ret = -1; - } else + } else { printf("PASS: 0 returned as expected\n"); + ksft_inc_pass_cnt(); + } + + ksft_print_cnts(); - exit(ret); + if (ret) + ksft_exit_fail(); + else + ksft_exit_pass(); } waitpid(pid2, &status, P_ALL); - return 0; + return ksft_exit_pass(); } -- GitLab From 884716497d4c777f4b8798fab361b4bad351f5bc Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 3 Oct 2014 09:08:56 -0600 Subject: [PATCH 5061/9457] selftests/timers: change test to use ksft framework Change timers test to use kselftest framework to report test results. Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/posix_timers.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index 41bd85559d4b..f87d970a485c 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -15,6 +15,8 @@ #include #include +#include "../kselftest.h" + #define DELAY 2 #define USECS_PER_SEC 1000000 @@ -194,16 +196,16 @@ int main(int argc, char **argv) printf("based timers if other threads run on the CPU...\n"); if (check_itimer(ITIMER_VIRTUAL) < 0) - return -1; + return ksft_exit_fail(); if (check_itimer(ITIMER_PROF) < 0) - return -1; + return ksft_exit_fail(); if (check_itimer(ITIMER_REAL) < 0) - return -1; + return ksft_exit_fail(); if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0) - return -1; + return ksft_exit_fail(); /* * It's unfortunately hard to reliably test a timer expiration @@ -215,7 +217,7 @@ int main(int argc, char **argv) * find a better solution. */ if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0) - return -1; + return ksft_exit_fail(); - return 0; + return ksft_exit_pass(); } -- GitLab From 1a3b595a281a44be4074fe33b317a0a4854b4197 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 17 Nov 2014 10:40:48 -0700 Subject: [PATCH 5062/9457] blk-mq: export blk_mq_free_request() Drivers that know they are blk-mq should just use this function instead of calling through blk_put_request(). Signed-off-by: Jens Axboe --- block/blk-mq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/blk-mq.c b/block/blk-mq.c index 06ab0683a1f1..fdf12152946e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -280,6 +280,7 @@ void blk_mq_free_request(struct request *rq) hctx = q->mq_ops->map_queue(q, ctx->cpu); __blk_mq_free_request(hctx, ctx, rq); } +EXPORT_SYMBOL_GPL(blk_mq_free_request); inline void __blk_mq_end_request(struct request *rq, int error) { -- GitLab From 7c7f2f2bc9a63f9605a16eabac59fc655dfe7c9a Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 17 Nov 2014 10:41:57 -0700 Subject: [PATCH 5063/9457] blk-mq: add blk_mq_free_hctx_request() It's silly to use blk_mq_free_request() which in turn maps the request to the hardware queue, for places where we already know what the hardware queue is. This saves us an extra mapping of a hardware queue on request completion, if the caller knows this information already. Signed-off-by: Jens Axboe --- block/blk-mq.c | 17 ++++++++++++----- include/linux/blk-mq.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index fdf12152946e..4347aa2be6ae 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -269,16 +269,23 @@ static void __blk_mq_free_request(struct blk_mq_hw_ctx *hctx, blk_mq_queue_exit(q); } -void blk_mq_free_request(struct request *rq) +void blk_mq_free_hctx_request(struct blk_mq_hw_ctx *hctx, struct request *rq) { struct blk_mq_ctx *ctx = rq->mq_ctx; - struct blk_mq_hw_ctx *hctx; - struct request_queue *q = rq->q; ctx->rq_completed[rq_is_sync(rq)]++; - - hctx = q->mq_ops->map_queue(q, ctx->cpu); __blk_mq_free_request(hctx, ctx, rq); + +} +EXPORT_SYMBOL_GPL(blk_mq_free_hctx_request); + +void blk_mq_free_request(struct request *rq) +{ + struct blk_mq_hw_ctx *hctx; + struct request_queue *q = rq->q; + + hctx = q->mq_ops->map_queue(q, rq->mq_ctx->cpu); + blk_mq_free_hctx_request(hctx, rq); } EXPORT_SYMBOL_GPL(blk_mq_free_request); diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index c3b64ec5321e..fb0a4fb3dc2b 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -169,6 +169,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule); void blk_mq_insert_request(struct request *, bool, bool, bool); void blk_mq_run_queues(struct request_queue *q, bool async); void blk_mq_free_request(struct request *rq); +void blk_mq_free_hctx_request(struct blk_mq_hw_ctx *, struct request *rq); bool blk_mq_can_queue(struct blk_mq_hw_ctx *); struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, bool reserved); -- GitLab From 9d135bb8c2a0d2e54b84ebc1b7d41852614fead8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 17 Nov 2014 10:43:42 -0700 Subject: [PATCH 5064/9457] NVMe: replace blk_put_request() with blk_mq_free_request() No point in using blk_put_request(), since we know we are blk-mq. This only makes sense in core code where we could be dealing with either legacy or blk-mq drivers. Additionally, use blk_mq_free_hctx_request() for the request completion fast path, where we already know the mapping from request to hardware queue. Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 8393f91b2721..bbac17f29fe7 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -262,7 +262,7 @@ static void async_req_completion(struct nvme_queue *nvmeq, void *ctx, dev_warn(nvmeq->q_dmadev, "async event result %08x\n", result); - blk_put_request(req); + blk_mq_free_hctx_request(nvmeq->hctx, req); } static void abort_completion(struct nvme_queue *nvmeq, void *ctx, @@ -273,7 +273,7 @@ static void abort_completion(struct nvme_queue *nvmeq, void *ctx, u16 status = le16_to_cpup(&cqe->status) >> 1; u32 result = le32_to_cpup(&cqe->result); - blk_put_request(req); + blk_mq_free_hctx_request(nvmeq->hctx, req); dev_warn(nvmeq->q_dmadev, "Abort status:%x result:%x", status, result); ++nvmeq->dev->abort_limit; @@ -286,7 +286,7 @@ static void async_completion(struct nvme_queue *nvmeq, void *ctx, cmdinfo->result = le32_to_cpup(&cqe->result); cmdinfo->status = le16_to_cpup(&cqe->status) >> 1; queue_kthread_work(cmdinfo->worker, &cmdinfo->work); - blk_put_request(cmdinfo->req); + blk_mq_free_hctx_request(nvmeq->hctx, cmdinfo->req); } static inline struct nvme_cmd_info *get_cmd_from_tag(struct nvme_queue *nvmeq, @@ -872,7 +872,7 @@ static int __nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cm if (!req) return -ENOMEM; res = nvme_submit_sync_cmd(req, cmd, result, timeout); - blk_put_request(req); + blk_mq_free_request(req); return res; } @@ -893,7 +893,7 @@ int nvme_submit_io_cmd(struct nvme_dev *dev, struct nvme_ns *ns, if (!req) return -ENOMEM; res = nvme_submit_sync_cmd(req, cmd, result, NVME_IO_TIMEOUT); - blk_put_request(req); + blk_mq_free_request(req); return res; } @@ -1047,7 +1047,7 @@ static void nvme_abort_req(struct request *req) dev_warn(nvmeq->q_dmadev, "Could not abort I/O %d QID %d", req->tag, nvmeq->qid); - blk_put_request(req); + blk_mq_free_request(req); } } @@ -1688,7 +1688,7 @@ static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns, else { status = nvme_submit_sync_cmd(req, &c, &cmd.result, timeout); - blk_put_request(req); + blk_mq_free_request(req); } } else status = __nvme_submit_admin_cmd(dev, &c, &cmd.result, timeout); -- GitLab From eb88bd1b47afd4d1f2754bbcc4bd1a5e57f31ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Nov 2014 22:12:52 +0200 Subject: [PATCH 5065/9457] drm/i915: Drop the HSW special case from __gen6_gt_wait_for_thread_c0() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bits [18:16] of GEN6_GT_THREAD_STATUS_REG have always had the same meaning since SNB. So treating them as something special for HSW doesn't make sense to me. Also the bits *seem* to work exactly the same way on IVB, HSW GT2 and HSW GT3. At least intel_reg_read gives the identical results on all platforms with and without forcewake. Also the HSW PM guide rev 0.99 (ww05 2013) doesn't say anything about those bits. It just says to poll for bits [2:0]. As does the more recent BDW PM guide. So just drop the HSW special case and treat all platforms the same way. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 - drivers/gpu/drm/i915/intel_uncore.c | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index faf61f5fc0ec..7a77cd5676c8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2326,7 +2326,6 @@ enum punit_power_well { #define GEN6_GT_THREAD_STATUS_REG 0x13805c #define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7 -#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16)) #define GEN6_GT_PERF_STATUS (MCHBAR_MIRROR_BASE_SNB + 0x5948) #define GEN6_RP_STATE_LIMITS (MCHBAR_MIRROR_BASE_SNB + 0x5994) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 86a755a9b9d0..5b3a49a476fe 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -49,17 +49,11 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv) static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) { - u32 gt_thread_status_mask; - - if (IS_HASWELL(dev_priv->dev)) - gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; - else - gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; - /* w/a for a sporadic read returning 0 by waiting for the GT * thread to wake up. */ - if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) + if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & + GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500)) DRM_ERROR("GT thread status wait timed out\n"); } -- GitLab From 2fe486c7eae9fc5b52297aed0e4008df6b66b01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Nov 2014 22:12:53 +0200 Subject: [PATCH 5066/9457] drm/i915: Drop WaRsForcewakeWaitTC0:vlv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GEN6_GT_THREAD_STATUS_REG doesn't seem to exist on VLV. Reads just give 0x0 no matter what the state of the render and media wells. There was also some hint in the Gunit HAS that thread status not being needed on VLV, and hence dropped when bringing stuff over from the IVB design. Not really a definite comment about the specific register itself though. Also the w/a itself is no longer listed for VLV in the database. It was there some time ago in the past, but I guess someone figured out the mistake and dropped it. So let's just drop it from the code as well. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 5b3a49a476fe..c98421dbfafd 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -222,10 +222,6 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, FORCEWAKE_ACK_TIMEOUT_MS)) DRM_ERROR("Timed out: waiting for media to ack.\n"); } - - /* WaRsForcewakeWaitTC0:vlv */ - if (!IS_CHERRYVIEW(dev_priv->dev)) - __gen6_gt_wait_for_thread_c0(dev_priv); } static void __vlv_force_wake_put(struct drm_i915_private *dev_priv, -- GitLab From a4f1289eaacdc2651355201b1ddded91710c89a2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 14 Nov 2014 08:52:27 -0800 Subject: [PATCH 5067/9457] drm/i915: Make dp aux pack/unpack public outside intel_dp.c No functional change. Just making it public for use outside intel_dp.c Allowing split psr functions. Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a16193fbfd49..a89585d809be 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -227,8 +227,7 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_OK; } -static uint32_t -pack_aux(const uint8_t *src, int src_bytes) +uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes) { int i; uint32_t v = 0; @@ -240,8 +239,7 @@ pack_aux(const uint8_t *src, int src_bytes) return v; } -static void -unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) +void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) { int i; if (dst_bytes > 4) @@ -863,7 +861,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, /* Load the send data into the aux channel data registers */ for (i = 0; i < send_bytes; i += 4) I915_WRITE(ch_data + i, - pack_aux(send + i, send_bytes - i)); + intel_dp_pack_aux(send + i, + send_bytes - i)); /* Send the command and wait for it to complete */ I915_WRITE(ch_ctl, send_ctl); @@ -917,8 +916,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, recv_bytes = recv_size; for (i = 0; i < recv_bytes; i += 4) - unpack_aux(I915_READ(ch_data + i), - recv + i, recv_bytes - i); + intel_dp_unpack_aux(I915_READ(ch_data + i), + recv + i, recv_bytes - i); ret = recv_bytes; out: @@ -2159,7 +2158,7 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) /* Setup AUX registers */ for (i = 0; i < sizeof(aux_msg); i += 4) I915_WRITE(EDP_PSR_AUX_DATA1(dev) + i, - pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); + intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); I915_WRITE(EDP_PSR_AUX_CTL(dev), DP_AUX_CH_CTL_TIME_OUT_400us | -- GitLab From 0bc12bcb1b9686d7011f16410ba17ed0740167c3 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 14 Nov 2014 08:52:28 -0800 Subject: [PATCH 5068/9457] drm/i915: Introduce intel_psr.c No functional changes. Just cleaning and reorganizing it. v2: Rebase it puting it to begin of psr rework. This helps to blame easily at least latest changes. Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_ddi.c | 4 +- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_dp.c | 381 +-------------------- drivers/gpu/drm/i915/intel_drv.h | 21 +- drivers/gpu/drm/i915/intel_frontbuffer.c | 4 +- drivers/gpu/drm/i915/intel_psr.c | 408 +++++++++++++++++++++++ 7 files changed, 428 insertions(+), 393 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_psr.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 891e584e97ea..e4083e41a600 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -51,6 +51,7 @@ i915-y += intel_audio.o \ intel_frontbuffer.o \ intel_modes.o \ intel_overlay.o \ + intel_psr.o \ intel_sideband.o \ intel_sprite.o i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ca33ee9477f1..3e4c63cfa415 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1583,7 +1583,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) intel_dp_stop_link_train(intel_dp); intel_edp_backlight_on(intel_dp); - intel_edp_psr_enable(intel_dp); + intel_psr_enable(intel_dp); } if (intel_crtc->config.has_audio) { @@ -1609,7 +1609,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_edp_psr_disable(intel_dp); + intel_psr_disable(intel_dp); intel_edp_backlight_off(intel_dp); } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7d58a64195d6..2632f2adc319 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12449,7 +12449,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (SUPPORTS_TV(dev)) intel_tv_init(dev); - intel_edp_psr_init(dev); + intel_psr_init(dev); for_each_intel_encoder(dev, encoder) { encoder->base.possible_crtcs = encoder->crtc_mask; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a89585d809be..7369e6f10117 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2066,385 +2066,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder, } } -static bool is_edp_psr(struct intel_dp *intel_dp) -{ - return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; -} - -static bool intel_edp_is_psr_enabled(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!HAS_PSR(dev)) - return false; - - return I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE; -} - -static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp, - struct edp_vsc_psr *vsc_psr) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); - u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); - u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); - uint32_t *data = (uint32_t *) vsc_psr; - unsigned int i; - - /* As per BSPec (Pipe Video Data Island Packet), we need to disable - the video DIP being updated before program video DIP data buffer - registers for DIP being updated. */ - I915_WRITE(ctl_reg, 0); - POSTING_READ(ctl_reg); - - for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { - if (i < sizeof(struct edp_vsc_psr)) - I915_WRITE(data_reg + i, *data++); - else - I915_WRITE(data_reg + i, 0); - } - - I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); - POSTING_READ(ctl_reg); -} - -static void intel_edp_psr_setup_vsc(struct intel_dp *intel_dp) -{ - struct edp_vsc_psr psr_vsc; - - /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ - memset(&psr_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - intel_edp_psr_write_vsc(intel_dp, &psr_vsc); -} - -static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t aux_clock_divider; - int precharge = 0x3; - bool only_standby = false; - static const uint8_t aux_msg[] = { - [0] = DP_AUX_NATIVE_WRITE << 4, - [1] = DP_SET_POWER >> 8, - [2] = DP_SET_POWER & 0xff, - [3] = 1 - 1, - [4] = DP_SET_POWER_D0, - }; - int i; - - BUILD_BUG_ON(sizeof(aux_msg) > 20); - - aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); - - if (IS_BROADWELL(dev) && dig_port->port != PORT_A) - only_standby = true; - - /* Enable PSR in sink */ - if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) - drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, - DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); - else - drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, - DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); - - /* Setup AUX registers */ - for (i = 0; i < sizeof(aux_msg); i += 4) - I915_WRITE(EDP_PSR_AUX_DATA1(dev) + i, - intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); - - I915_WRITE(EDP_PSR_AUX_CTL(dev), - DP_AUX_CH_CTL_TIME_OUT_400us | - (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); -} - -static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t max_sleep_time = 0x1f; - uint32_t idle_frames = 1; - uint32_t val = 0x0; - const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; - bool only_standby = false; - - if (IS_BROADWELL(dev) && dig_port->port != PORT_A) - only_standby = true; - - if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) { - val |= EDP_PSR_LINK_STANDBY; - val |= EDP_PSR_TP2_TP3_TIME_0us; - val |= EDP_PSR_TP1_TIME_0us; - val |= EDP_PSR_SKIP_AUX_EXIT; - val |= IS_BROADWELL(dev) ? BDW_PSR_SINGLE_FRAME : 0; - } else - val |= EDP_PSR_LINK_DISABLE; - - I915_WRITE(EDP_PSR_CTL(dev), val | - (IS_BROADWELL(dev) ? 0 : link_entry_time) | - max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | - idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | - EDP_PSR_ENABLE); -} - -static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) -{ - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dig_port->base.base.crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - lockdep_assert_held(&dev_priv->psr.lock); - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - - dev_priv->psr.source_ok = false; - - if (IS_HASWELL(dev) && dig_port->port != PORT_A) { - DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n"); - return false; - } - - if (!i915.enable_psr) { - DRM_DEBUG_KMS("PSR disable by flag\n"); - return false; - } - - /* Below limitations aren't valid for Broadwell */ - if (IS_BROADWELL(dev)) - goto out; - - if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) & - S3D_ENABLE) { - DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n"); - return false; - } - - if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { - DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); - return false; - } - - out: - dev_priv->psr.source_ok = true; - return true; -} - -static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) -{ - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); - WARN_ON(dev_priv->psr.active); - lockdep_assert_held(&dev_priv->psr.lock); - - /* Enable/Re-enable PSR on the host */ - intel_edp_psr_enable_source(intel_dp); - - dev_priv->psr.active = true; -} - -void intel_edp_psr_enable(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!HAS_PSR(dev)) { - DRM_DEBUG_KMS("PSR not supported on this platform\n"); - return; - } - - if (!is_edp_psr(intel_dp)) { - DRM_DEBUG_KMS("PSR not supported by this panel\n"); - return; - } - - mutex_lock(&dev_priv->psr.lock); - if (dev_priv->psr.enabled) { - DRM_DEBUG_KMS("PSR already in use\n"); - goto unlock; - } - - if (!intel_edp_psr_match_conditions(intel_dp)) - goto unlock; - - dev_priv->psr.busy_frontbuffer_bits = 0; - - intel_edp_psr_setup_vsc(intel_dp); - - /* Avoid continuous PSR exit by masking memup and hpd */ - I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | - EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); - - /* Enable PSR on the panel */ - intel_edp_psr_enable_sink(intel_dp); - - dev_priv->psr.enabled = intel_dp; -unlock: - mutex_unlock(&dev_priv->psr.lock); -} - -void intel_edp_psr_disable(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->psr.lock); - if (!dev_priv->psr.enabled) { - mutex_unlock(&dev_priv->psr.lock); - return; - } - - if (dev_priv->psr.active) { - I915_WRITE(EDP_PSR_CTL(dev), - I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE); - - /* Wait till PSR is idle */ - if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) & - EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) - DRM_ERROR("Timed out waiting for PSR Idle State\n"); - - dev_priv->psr.active = false; - } else { - WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); - } - - dev_priv->psr.enabled = NULL; - mutex_unlock(&dev_priv->psr.lock); - - cancel_delayed_work_sync(&dev_priv->psr.work); -} - -static void intel_edp_psr_work(struct work_struct *work) -{ - struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), psr.work.work); - struct intel_dp *intel_dp = dev_priv->psr.enabled; - - /* We have to make sure PSR is ready for re-enable - * otherwise it keeps disabled until next full enable/disable cycle. - * PSR might take some time to get fully disabled - * and be ready for re-enable. - */ - if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) & - EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { - DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); - return; - } - - mutex_lock(&dev_priv->psr.lock); - intel_dp = dev_priv->psr.enabled; - - if (!intel_dp) - goto unlock; - - /* - * The delayed work can race with an invalidate hence we need to - * recheck. Since psr_flush first clears this and then reschedules we - * won't ever miss a flush when bailing out here. - */ - if (dev_priv->psr.busy_frontbuffer_bits) - goto unlock; - - intel_edp_psr_do_enable(intel_dp); -unlock: - mutex_unlock(&dev_priv->psr.lock); -} - -static void intel_edp_psr_do_exit(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->psr.active) { - u32 val = I915_READ(EDP_PSR_CTL(dev)); - - WARN_ON(!(val & EDP_PSR_ENABLE)); - - I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE); - - dev_priv->psr.active = false; - } - -} - -void intel_edp_psr_invalidate(struct drm_device *dev, - unsigned frontbuffer_bits) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - enum pipe pipe; - - mutex_lock(&dev_priv->psr.lock); - if (!dev_priv->psr.enabled) { - mutex_unlock(&dev_priv->psr.lock); - return; - } - - crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; - pipe = to_intel_crtc(crtc)->pipe; - - intel_edp_psr_do_exit(dev); - - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); - - dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; - mutex_unlock(&dev_priv->psr.lock); -} - -void intel_edp_psr_flush(struct drm_device *dev, - unsigned frontbuffer_bits) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - enum pipe pipe; - - mutex_lock(&dev_priv->psr.lock); - if (!dev_priv->psr.enabled) { - mutex_unlock(&dev_priv->psr.lock); - return; - } - - crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; - pipe = to_intel_crtc(crtc)->pipe; - dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; - - /* - * On Haswell sprite plane updates don't result in a psr invalidating - * signal in the hardware. Which means we need to manually fake this in - * software for all flushes, not just when we've seen a preceding - * invalidation through frontbuffer rendering. - */ - if (IS_HASWELL(dev) && - (frontbuffer_bits & INTEL_FRONTBUFFER_SPRITE(pipe))) - intel_edp_psr_do_exit(dev); - - if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) - schedule_delayed_work(&dev_priv->psr.work, - msecs_to_jiffies(100)); - mutex_unlock(&dev_priv->psr.lock); -} - -void intel_edp_psr_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - INIT_DELAYED_WORK(&dev_priv->psr.work, intel_edp_psr_work); - mutex_init(&dev_priv->psr.lock); -} - static void intel_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); @@ -5095,7 +4716,7 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) * hard to tell without seeing the user of this function of this code. * Check locking and ordering once that lands. */ - if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) { + if (INTEL_INFO(dev)->gen < 8 && intel_psr_is_enabled(dev)) { DRM_DEBUG_KMS("DRRS is disabled as PSR is enabled\n"); return; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d67c59b15128..d1f9b639f0d1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -999,21 +999,16 @@ void intel_edp_backlight_off(struct intel_dp *intel_dp); void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); void intel_edp_panel_on(struct intel_dp *intel_dp); void intel_edp_panel_off(struct intel_dp *intel_dp); -void intel_edp_psr_enable(struct intel_dp *intel_dp); -void intel_edp_psr_disable(struct intel_dp *intel_dp); void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate); -void intel_edp_psr_invalidate(struct drm_device *dev, - unsigned frontbuffer_bits); -void intel_edp_psr_flush(struct drm_device *dev, - unsigned frontbuffer_bits); -void intel_edp_psr_init(struct drm_device *dev); - void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector); void intel_dp_mst_suspend(struct drm_device *dev); void intel_dp_mst_resume(struct drm_device *dev); int intel_dp_max_link_bw(struct intel_dp *intel_dp); void intel_dp_hot_plug(struct intel_encoder *intel_encoder); void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv); +uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes); +void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes); + /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); @@ -1117,6 +1112,16 @@ void intel_backlight_register(struct drm_device *dev); void intel_backlight_unregister(struct drm_device *dev); +/* intel_psr.c */ +bool intel_psr_is_enabled(struct drm_device *dev); +void intel_psr_enable(struct intel_dp *intel_dp); +void intel_psr_disable(struct intel_dp *intel_dp); +void intel_psr_invalidate(struct drm_device *dev, + unsigned frontbuffer_bits); +void intel_psr_flush(struct drm_device *dev, + unsigned frontbuffer_bits); +void intel_psr_init(struct drm_device *dev); + /* intel_runtime_pm.c */ int intel_power_domains_init(struct drm_i915_private *); void intel_power_domains_fini(struct drm_i915_private *); diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index 58cf2e6b78f4..79f6d72179c5 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -156,7 +156,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring); - intel_edp_psr_invalidate(dev, obj->frontbuffer_bits); + intel_psr_invalidate(dev, obj->frontbuffer_bits); } /** @@ -182,7 +182,7 @@ void intel_frontbuffer_flush(struct drm_device *dev, intel_mark_fb_busy(dev, frontbuffer_bits, NULL); - intel_edp_psr_flush(dev, frontbuffer_bits); + intel_psr_flush(dev, frontbuffer_bits); /* * FIXME: Unconditional fbc flushing here is a rather gross hack and diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c new file mode 100644 index 000000000000..7b3ed910bc48 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -0,0 +1,408 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "intel_drv.h" +#include "i915_drv.h" + +static bool is_edp_psr(struct intel_dp *intel_dp) +{ + return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; +} + +bool intel_psr_is_enabled(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!HAS_PSR(dev)) + return false; + + return I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE; +} + +static void intel_psr_write_vsc(struct intel_dp *intel_dp, + struct edp_vsc_psr *vsc_psr) +{ + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); + u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); + u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); + uint32_t *data = (uint32_t *) vsc_psr; + unsigned int i; + + /* As per BSPec (Pipe Video Data Island Packet), we need to disable + the video DIP being updated before program video DIP data buffer + registers for DIP being updated. */ + I915_WRITE(ctl_reg, 0); + POSTING_READ(ctl_reg); + + for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { + if (i < sizeof(struct edp_vsc_psr)) + I915_WRITE(data_reg + i, *data++); + else + I915_WRITE(data_reg + i, 0); + } + + I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); + POSTING_READ(ctl_reg); +} + +static void intel_psr_setup_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + +static void intel_psr_enable_sink(struct intel_dp *intel_dp) +{ + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t aux_clock_divider; + int precharge = 0x3; + bool only_standby = false; + static const uint8_t aux_msg[] = { + [0] = DP_AUX_NATIVE_WRITE << 4, + [1] = DP_SET_POWER >> 8, + [2] = DP_SET_POWER & 0xff, + [3] = 1 - 1, + [4] = DP_SET_POWER_D0, + }; + int i; + + BUILD_BUG_ON(sizeof(aux_msg) > 20); + + aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); + + if (IS_BROADWELL(dev) && dig_port->port != PORT_A) + only_standby = true; + + /* Enable PSR in sink */ + if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) + drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, + DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); + else + drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, + DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); + + /* Setup AUX registers */ + for (i = 0; i < sizeof(aux_msg); i += 4) + I915_WRITE(EDP_PSR_AUX_DATA1(dev) + i, + intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); + + I915_WRITE(EDP_PSR_AUX_CTL(dev), + DP_AUX_CH_CTL_TIME_OUT_400us | + (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | + (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | + (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); +} + +static void intel_psr_enable_source(struct intel_dp *intel_dp) +{ + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t max_sleep_time = 0x1f; + uint32_t idle_frames = 1; + uint32_t val = 0x0; + const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; + bool only_standby = false; + + if (IS_BROADWELL(dev) && dig_port->port != PORT_A) + only_standby = true; + + if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) { + val |= EDP_PSR_LINK_STANDBY; + val |= EDP_PSR_TP2_TP3_TIME_0us; + val |= EDP_PSR_TP1_TIME_0us; + val |= EDP_PSR_SKIP_AUX_EXIT; + val |= IS_BROADWELL(dev) ? BDW_PSR_SINGLE_FRAME : 0; + } else + val |= EDP_PSR_LINK_DISABLE; + + I915_WRITE(EDP_PSR_CTL(dev), val | + (IS_BROADWELL(dev) ? 0 : link_entry_time) | + max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | + idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | + EDP_PSR_ENABLE); +} + +static bool intel_psr_match_conditions(struct intel_dp *intel_dp) +{ + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dig_port->base.base.crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + lockdep_assert_held(&dev_priv->psr.lock); + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + + dev_priv->psr.source_ok = false; + + if (IS_HASWELL(dev) && dig_port->port != PORT_A) { + DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n"); + return false; + } + + if (!i915.enable_psr) { + DRM_DEBUG_KMS("PSR disable by flag\n"); + return false; + } + + /* Below limitations aren't valid for Broadwell */ + if (IS_BROADWELL(dev)) + goto out; + + if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) & + S3D_ENABLE) { + DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n"); + return false; + } + + if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { + DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); + return false; + } + + out: + dev_priv->psr.source_ok = true; + return true; +} + +static void intel_psr_do_enable(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); + WARN_ON(dev_priv->psr.active); + lockdep_assert_held(&dev_priv->psr.lock); + + /* Enable/Re-enable PSR on the host */ + intel_psr_enable_source(intel_dp); + + dev_priv->psr.active = true; +} + +void intel_psr_enable(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (!HAS_PSR(dev)) { + DRM_DEBUG_KMS("PSR not supported on this platform\n"); + return; + } + + if (!is_edp_psr(intel_dp)) { + DRM_DEBUG_KMS("PSR not supported by this panel\n"); + return; + } + + mutex_lock(&dev_priv->psr.lock); + if (dev_priv->psr.enabled) { + DRM_DEBUG_KMS("PSR already in use\n"); + goto unlock; + } + + if (!intel_psr_match_conditions(intel_dp)) + goto unlock; + + dev_priv->psr.busy_frontbuffer_bits = 0; + + intel_psr_setup_vsc(intel_dp); + + /* Avoid continuous PSR exit by masking memup and hpd */ + I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | + EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); + + /* Enable PSR on the panel */ + intel_psr_enable_sink(intel_dp); + + dev_priv->psr.enabled = intel_dp; +unlock: + mutex_unlock(&dev_priv->psr.lock); +} + +void intel_psr_disable(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev_priv->psr.lock); + if (!dev_priv->psr.enabled) { + mutex_unlock(&dev_priv->psr.lock); + return; + } + + if (dev_priv->psr.active) { + I915_WRITE(EDP_PSR_CTL(dev), + I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE); + + /* Wait till PSR is idle */ + if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) & + EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) + DRM_ERROR("Timed out waiting for PSR Idle State\n"); + + dev_priv->psr.active = false; + } else { + WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); + } + + dev_priv->psr.enabled = NULL; + mutex_unlock(&dev_priv->psr.lock); + + cancel_delayed_work_sync(&dev_priv->psr.work); +} + +static void intel_psr_work(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, typeof(*dev_priv), psr.work.work); + struct intel_dp *intel_dp = dev_priv->psr.enabled; + + /* We have to make sure PSR is ready for re-enable + * otherwise it keeps disabled until next full enable/disable cycle. + * PSR might take some time to get fully disabled + * and be ready for re-enable. + */ + if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) & + EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { + DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); + return; + } + + mutex_lock(&dev_priv->psr.lock); + intel_dp = dev_priv->psr.enabled; + + if (!intel_dp) + goto unlock; + + /* + * The delayed work can race with an invalidate hence we need to + * recheck. Since psr_flush first clears this and then reschedules we + * won't ever miss a flush when bailing out here. + */ + if (dev_priv->psr.busy_frontbuffer_bits) + goto unlock; + + intel_psr_do_enable(intel_dp); +unlock: + mutex_unlock(&dev_priv->psr.lock); +} + +static void intel_psr_exit(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->psr.active) { + u32 val = I915_READ(EDP_PSR_CTL(dev)); + + WARN_ON(!(val & EDP_PSR_ENABLE)); + + I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE); + + dev_priv->psr.active = false; + } + +} + +void intel_psr_invalidate(struct drm_device *dev, + unsigned frontbuffer_bits) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + enum pipe pipe; + + mutex_lock(&dev_priv->psr.lock); + if (!dev_priv->psr.enabled) { + mutex_unlock(&dev_priv->psr.lock); + return; + } + + crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; + pipe = to_intel_crtc(crtc)->pipe; + + intel_psr_exit(dev); + + frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); + + dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; + mutex_unlock(&dev_priv->psr.lock); +} + +void intel_psr_flush(struct drm_device *dev, + unsigned frontbuffer_bits) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + enum pipe pipe; + + mutex_lock(&dev_priv->psr.lock); + if (!dev_priv->psr.enabled) { + mutex_unlock(&dev_priv->psr.lock); + return; + } + + crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; + pipe = to_intel_crtc(crtc)->pipe; + dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; + + /* + * On Haswell sprite plane updates don't result in a psr invalidating + * signal in the hardware. Which means we need to manually fake this in + * software for all flushes, not just when we've seen a preceding + * invalidation through frontbuffer rendering. + */ + if (IS_HASWELL(dev) && + (frontbuffer_bits & INTEL_FRONTBUFFER_SPRITE(pipe))) + intel_psr_exit(dev); + + if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) + schedule_delayed_work(&dev_priv->psr.work, + msecs_to_jiffies(100)); + mutex_unlock(&dev_priv->psr.lock); +} + +void intel_psr_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); + mutex_init(&dev_priv->psr.lock); +} -- GitLab From b2b89f55dfe3f19c8028d6c907d1ab53766b534b Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 14 Nov 2014 08:52:29 -0800 Subject: [PATCH 5069/9457] drm/i915: Add PSR docbook Let's document PSR a bit. No functional changes. v2: Add actual DocBook entry and accept Daniel's improvements. Cc: Daniel Vetter Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 5 +++ drivers/gpu/drm/i915/intel_psr.c | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9449cd65f1d0..a1168a8e2279 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3891,6 +3891,11 @@ int num_ioctls; High Definition Audio !Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port !Idrivers/gpu/drm/i915/intel_audio.c + + + Panel Self Refresh PSR (PSR/SRD) +!Pdrivers/gpu/drm/i915/intel_psr.c Panel Self Refresh (PSR/SRD) +!Idrivers/gpu/drm/i915/intel_psr.c DPIO diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 7b3ed910bc48..716b8a961eea 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -21,6 +21,36 @@ * DEALINGS IN THE SOFTWARE. */ +/** + * DOC: Panel Self Refresh (PSR/SRD) + * + * Since Haswell Display controller supports Panel Self-Refresh on display + * panels witch have a remote frame buffer (RFB) implemented according to PSR + * spec in eDP1.3. PSR feature allows the display to go to lower standby states + * when system is idle but display is on as it eliminates display refresh + * request to DDR memory completely as long as the frame buffer for that + * display is unchanged. + * + * Panel Self Refresh must be supported by both Hardware (source) and + * Panel (sink). + * + * PSR saves power by caching the framebuffer in the panel RFB, which allows us + * to power down the link and memory controller. For DSI panels the same idea + * is called "manual mode". + * + * The implementation uses the hardware-based PSR support which automatically + * enters/exits self-refresh mode. The hardware takes care of sending the + * required DP aux message and could even retrain the link (that part isn't + * enabled yet though). The hardware also keeps track of any frontbuffer + * changes to know when to exit self-refresh mode again. Unfortunately that + * part doesn't work too well, hence why the i915 PSR support uses the + * software frontbuffer tracking to make sure it doesn't miss a screen + * update. For this integration intel_psr_invalidate() and intel_psr_flush() + * get called by the frontbuffer tracking code. Note that because of locking + * issues the self-refresh re-enable code is done from a work queue, which + * must be correctly synchronized/cancelled when shutting down the pipe." + */ + #include #include "intel_drv.h" @@ -217,6 +247,12 @@ static void intel_psr_do_enable(struct intel_dp *intel_dp) dev_priv->psr.active = true; } +/** + * intel_psr_enable - Enable PSR + * @intel_dp: Intel DP + * + * This function can only be called after the pipe is fully trained and enabled. + */ void intel_psr_enable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); @@ -258,6 +294,12 @@ void intel_psr_enable(struct intel_dp *intel_dp) mutex_unlock(&dev_priv->psr.lock); } +/** + * intel_psr_disable - Disable PSR + * @intel_dp: Intel DP + * + * This function needs to be called before disabling pipe. + */ void intel_psr_disable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); @@ -342,6 +384,18 @@ static void intel_psr_exit(struct drm_device *dev) } +/** + * intel_psr_invalidate - Invalidade PSR + * @dev: DRM device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * Since the hardware frontbuffer tracking has gaps we need to integrate + * with the software frontbuffer tracking. This function gets called every + * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be + * disabled if the frontbuffer mask contains a buffer relevant to PSR. + * + * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits." + */ void intel_psr_invalidate(struct drm_device *dev, unsigned frontbuffer_bits) { @@ -366,6 +420,18 @@ void intel_psr_invalidate(struct drm_device *dev, mutex_unlock(&dev_priv->psr.lock); } +/** + * intel_psr_flush - Flush PSR + * @dev: DRM device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * Since the hardware frontbuffer tracking has gaps we need to integrate + * with the software frontbuffer tracking. This function gets called every + * time frontbuffer rendering has completed and flushed out to memory. PSR + * can be enabled again if no other frontbuffer relevant to PSR is dirty. + * + * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits. + */ void intel_psr_flush(struct drm_device *dev, unsigned frontbuffer_bits) { @@ -399,6 +465,13 @@ void intel_psr_flush(struct drm_device *dev, mutex_unlock(&dev_priv->psr.lock); } +/** + * intel_psr_init - Init basic PSR work and mutex. + * @dev: DRM device + * + * This function is called only once at driver load to initialize basic + * PSR stuff. + */ void intel_psr_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; -- GitLab From 5416d871136d7cc674c508889b8abbf2469dd115 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 14 Nov 2014 17:24:33 +0000 Subject: [PATCH 5070/9457] drm/i915/skl: Set the eDP link rate on DPLL0 On SKL DPLL0 is used to derive CDCLK but can also be used to drive an eDP port (as long as we don't want SSC). DPLL0 is special enough to not be handled by the shared DPLL framework (drives CDCLK, not supposed to enable the HDMI mode), So we need to compute the configuration separately from the other DPLLs. Note that we don't need to reprogram DPLL0 (which would mean bringing down CDCLK) to support the various eDP 1.3 link rates as they all share the same VCO (8100). Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3e4c63cfa415..83eeecbaa4bb 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1484,6 +1484,25 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) uint32_t dpll = crtc->config.ddi_pll_sel; uint32_t val; + /* + * DPLL0 is used for eDP and is the only "private" DPLL (as + * opposed to shared) on SKL + */ + if (type == INTEL_OUTPUT_EDP) { + WARN_ON(dpll != SKL_DPLL0); + + val = I915_READ(DPLL_CTRL1); + + val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | + DPLL_CTRL1_SSC(dpll) | + DPLL_CRTL1_LINK_RATE_MASK(dpll)); + val |= crtc->config.dpll_hw_state.ctrl1 << (dpll * 6); + + I915_WRITE(DPLL_CTRL1, val); + POSTING_READ(DPLL_CTRL1); + } + + /* DDI -> PLL mapping */ val = I915_READ(DPLL_CTRL2); val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) | @@ -1492,6 +1511,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); I915_WRITE(DPLL_CTRL2, val); + } else { WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE); I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7369e6f10117..4e49caa5a1b3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1073,6 +1073,33 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector) intel_connector_unregister(intel_connector); } +static void +skl_edp_set_pll_config(struct intel_crtc_config *pipe_config, int link_bw) +{ + u32 ctrl1; + + pipe_config->ddi_pll_sel = SKL_DPLL0; + pipe_config->dpll_hw_state.cfgcr1 = 0; + pipe_config->dpll_hw_state.cfgcr2 = 0; + + ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0); + switch (link_bw) { + case DP_LINK_BW_1_62: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810, + SKL_DPLL0); + break; + case DP_LINK_BW_2_7: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350, + SKL_DPLL0); + break; + case DP_LINK_BW_5_4: + ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700, + SKL_DPLL0); + break; + } + pipe_config->dpll_hw_state.ctrl1 = ctrl1; +} + static void hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw) { @@ -1250,7 +1277,9 @@ intel_dp_compute_config(struct intel_encoder *encoder, &pipe_config->dp_m2_n2); } - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + if (IS_SKYLAKE(dev) && is_edp(intel_dp)) + skl_edp_set_pll_config(pipe_config, intel_dp->link_bw); + else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw); else intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); -- GitLab From 134ffa44d1ad244216a114506a67dcfc7c80a90f Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 14 Nov 2014 17:24:34 +0000 Subject: [PATCH 5071/9457] drm/i915/skl: Use the pipe config DPLL tracking to query the link clock Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 83eeecbaa4bb..86745da7b105 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -735,14 +735,10 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - enum port port = intel_ddi_get_encoder_port(encoder); int link_clock = 0; uint32_t dpll_ctl1, dpll; - /* FIXME: This should be tracked in the pipe config. */ - dpll = I915_READ(DPLL_CTRL2); - dpll &= DPLL_CTRL2_DDI_CLK_SEL_MASK(port); - dpll >>= DPLL_CTRL2_DDI_CLK_SEL_SHIFT(port); + dpll = pipe_config->ddi_pll_sel; dpll_ctl1 = I915_READ(DPLL_CTRL1); -- GitLab From 069fb0b63722f8c9f8b4bbce236793626c89af33 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 14 Nov 2014 10:51:45 -0800 Subject: [PATCH 5072/9457] syslog: Provide stub check_syslog_permissions When building without CONFIG_PRINTK, we need to provide a stub check_syslog_permissions. As there is no way to turn on the dmesg_restrict sysctl without CONFIG_PRINTK, return success. Reported-by: Jim Davis Signed-off-by: Sebastian Schmidt Acked-by: Kees Cook Signed-off-by: Tony Luck --- include/linux/syslog.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/syslog.h b/include/linux/syslog.h index 9def5297dbb7..4b7b875a7ce1 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h @@ -48,6 +48,14 @@ #define SYSLOG_FROM_PROC 1 int do_syslog(int type, char __user *buf, int count, bool from_file); + +#ifdef CONFIG_PRINTK int check_syslog_permissions(int type, bool from_file); +#else +static inline int check_syslog_permissions(int type, bool from_file) +{ + return 0; +} +#endif #endif /* _LINUX_SYSLOG_H */ -- GitLab From a839ce663b3183209fdf7b1fc4796bfe2a4679c3 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 9 Oct 2014 11:07:58 +0200 Subject: [PATCH 5073/9457] eeprom: at24: extend driver to allow writing via i2c_smbus_write_byte_data I have a at24 EEPROM connected via i2c bus provided by ISCH i2c bus driver. This bus driver does not support I2C_FUNC_SMBUS_WRITE_I2C_BLOCK and so I was looking for a way to be able to write the eeprom. This patch adds support for I2C_SMBUS_BYTE_DATA writing via i2c_smbus_write_byte_data. It is quite slow, but it works. Signed-off-by: Christian Gmeiner [wsa: s/use_smbuse_write/use_smbus_write/] Signed-off-by: Wolfram Sang --- drivers/misc/eeprom/at24.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index d87f77f790d6..2d3db81be099 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -56,6 +56,7 @@ struct at24_data { struct at24_platform_data chip; struct memory_accessor macc; int use_smbus; + int use_smbus_write; /* * Lock protects against activities from other Linux tasks, @@ -324,7 +325,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, { struct i2c_client *client; struct i2c_msg msg; - ssize_t status; + ssize_t status = 0; unsigned long timeout, write_time; unsigned next_page; @@ -365,9 +366,18 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, timeout = jiffies + msecs_to_jiffies(write_timeout); do { write_time = jiffies; - if (at24->use_smbus) { - status = i2c_smbus_write_i2c_block_data(client, - offset, count, buf); + if (at24->use_smbus_write) { + switch (at24->use_smbus_write) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, + offset, buf[0]); + break; + } + if (status == 0) status = count; } else { @@ -487,6 +497,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) struct at24_platform_data chip; bool writable; int use_smbus = 0; + int use_smbus_write = 0; struct at24_data *at24; int err; unsigned i, num_addresses; @@ -546,6 +557,18 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) } } + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + use_smbus_write = I2C_SMBUS_BYTE_DATA; + chip.page_size = 1; + } + } + if (chip.flags & AT24_FLAG_TAKE8ADDR) num_addresses = 8; else @@ -559,6 +582,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) mutex_init(&at24->lock); at24->use_smbus = use_smbus; + at24->use_smbus_write = use_smbus_write; at24->chip = chip; at24->num_addresses = num_addresses; @@ -576,8 +600,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) writable = !(chip.flags & AT24_FLAG_READONLY); if (writable) { - if (!use_smbus || i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + if (!use_smbus || use_smbus_write) { unsigned write_max = chip.page_size; -- GitLab From 48ef3ca98d92201c36f50ffb5409c38b02e2e953 Mon Sep 17 00:00:00 2001 From: Thomas Gessler Date: Mon, 13 Oct 2014 18:08:47 +0200 Subject: [PATCH 5074/9457] i2c: xiic: Fix big-endian register access The driver tried to access device registers with the (little-endian) iowrite/ioread functions. While this worked on little-endian machines (e.g. Microblaze with AXI bus), it made the driver unusable on big-endian machines (e.g. PPC405 with PLB). During the probe function, the driver tried to write a 32-bit reset mask into the reset register. This caused an error interrupt on big-endian systems, because the device detected an invalid (byte-swapped) reset mask. The result was an Oops. The patch implements an endianness detection similar to the one used in other Xilinx drivers like drivers/spi/spi-xilinx.c. It was tested on a PPC405/PLB system. Signed-off-by: Thomas Gessler Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 58 ++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index cc65ea0b818f..522916a33aa0 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -46,6 +46,11 @@ enum xilinx_i2c_state { STATE_START }; +enum xiic_endian { + LITTLE, + BIG +}; + /** * struct xiic_i2c - Internal representation of the XIIC I2C bus * @base: Memory base of the HW registers @@ -70,6 +75,7 @@ struct xiic_i2c { enum xilinx_i2c_state state; struct i2c_msg *rx_msg; int rx_pos; + enum xiic_endian endianness; }; @@ -170,29 +176,58 @@ struct xiic_i2c { static void xiic_start_xfer(struct xiic_i2c *i2c); static void __xiic_start_xfer(struct xiic_i2c *i2c); +/* + * For the register read and write functions, a little-endian and big-endian + * version are necessary. Endianness is detected during the probe function. + * Only the least significant byte [doublet] of the register are ever + * accessed. This requires an offset of 3 [2] from the base address for + * big-endian systems. + */ + static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value) { - iowrite8(value, i2c->base + reg); + if (i2c->endianness == LITTLE) + iowrite8(value, i2c->base + reg); + else + iowrite8(value, i2c->base + reg + 3); } static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg) { - return ioread8(i2c->base + reg); + u8 ret; + + if (i2c->endianness == LITTLE) + ret = ioread8(i2c->base + reg); + else + ret = ioread8(i2c->base + reg + 3); + return ret; } static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value) { - iowrite16(value, i2c->base + reg); + if (i2c->endianness == LITTLE) + iowrite16(value, i2c->base + reg); + else + iowrite16be(value, i2c->base + reg + 2); } static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value) { - iowrite32(value, i2c->base + reg); + if (i2c->endianness == LITTLE) + iowrite32(value, i2c->base + reg); + else + iowrite32be(value, i2c->base + reg); } static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg) { - return ioread32(i2c->base + reg); + u32 ret; + + if (i2c->endianness == LITTLE) + ret = ioread32(i2c->base + reg); + else + ret = ioread32be(i2c->base + reg); + return ret; } static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask) @@ -692,6 +727,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) struct resource *res; int ret, irq; u8 i; + u32 sr; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) @@ -724,6 +760,18 @@ static int xiic_i2c_probe(struct platform_device *pdev) return ret; } + /* + * Detect endianness + * Try to reset the TX FIFO. Then check the EMPTY flag. If it is not + * set, assume that the endianness was wrong and swap. + */ + i2c->endianness = LITTLE; + xiic_setreg32(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK); + /* Reset is cleared in xiic_reinit */ + sr = xiic_getreg32(i2c, XIIC_SR_REG_OFFSET); + if (!(sr & XIIC_SR_TX_FIFO_EMPTY_MASK)) + i2c->endianness = BIG; + xiic_reinit(i2c); /* add i2c adapter to i2c tree */ -- GitLab From 039e60ed6cb6715d168943de99a4aececcb65e15 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 13 Nov 2014 10:25:11 -0300 Subject: [PATCH 5075/9457] DT: i2c: Add binding document for IMG I2C SCB Introduce a devicetree binding for Imagination Technologies I2C SCB controller. Reviewed-by: Andrew Bresticker Signed-off-by: James Hogan Signed-off-by: Ezequiel Garcia Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-img-scb.txt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/i2c-img-scb.txt diff --git a/Documentation/devicetree/bindings/i2c/i2c-img-scb.txt b/Documentation/devicetree/bindings/i2c/i2c-img-scb.txt new file mode 100644 index 000000000000..b6461602dca5 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-img-scb.txt @@ -0,0 +1,26 @@ +IMG Serial Control Bus (SCB) I2C Controller + +Required Properties: +- compatible: "img,scb-i2c" +- reg: Physical base address and length of controller registers +- interrupts: Interrupt number used by the controller +- clocks : Should contain a clock specifier for each entry in clock-names +- clock-names : Should contain the following entries: + "scb", for the SCB core clock. + "sys", for the system clock. +- clock-frequency: The I2C bus frequency in Hz +- #address-cells: Should be <1> +- #size-cells: Should be <0> + +Example: + +i2c@18100000 { + compatible = "img,scb-i2c"; + reg = <0x18100000 0x200>; + interrupts = ; + clocks = <&i2c0_clk>, <&system_clk>; + clock-names = "scb", "sys"; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; +}; -- GitLab From 27bce457d5884dcae96df9a0d71de3647a538118 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Thu, 13 Nov 2014 15:32:21 -0300 Subject: [PATCH 5076/9457] i2c: img-scb: Add Imagination Technologies I2C SCB driver Add support for the IMG I2C Serial Control Bus (SCB) found on the Pistachio and TZ1090 SoCs. Reviewed-by: Andrew Bresticker Signed-off-by: James Hogan [Ezequiel: code cleaning and rebasing] Signed-off-by: Ezequiel Garcia Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-img-scb.c | 1412 ++++++++++++++++++++++++++++++ 3 files changed, 1423 insertions(+) create mode 100644 drivers/i2c/busses/i2c-img-scb.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 06e99eb64295..03c6119325ef 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -524,6 +524,16 @@ config I2C_IBM_IIC This driver can also be built as a module. If so, the module will be called i2c-ibm_iic. +config I2C_IMG + tristate "Imagination Technologies I2C SCB Controller" + depends on SOC_TZ1090 || COMPILE_TEST + help + Say Y here if you want to use the IMG I2C SCB controller, + available on the TZ1090 SoC. + + This driver can also be built as a module. If so, the module + will be called i2c-img-scb. + config I2C_IMX tristate "IMX I2C interface" depends on ARCH_MXC diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 78d56c54ba2b..84861ead6be9 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o +obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c new file mode 100644 index 000000000000..0fcc1694c607 --- /dev/null +++ b/drivers/i2c/busses/i2c-img-scb.c @@ -0,0 +1,1412 @@ +/* + * I2C adapter for the IMG Serial Control Bus (SCB) IP block. + * + * Copyright (C) 2009, 2010, 2012, 2014 Imagination Technologies Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * There are three ways that this I2C controller can be driven: + * + * - Raw control of the SDA and SCK signals. + * + * This corresponds to MODE_RAW, which takes control of the signals + * directly for a certain number of clock cycles (the INT_TIMING + * interrupt can be used for timing). + * + * - Atomic commands. A low level I2C symbol (such as generate + * start/stop/ack/nack bit, generate byte, receive byte, and receive + * ACK) is given to the hardware, with detection of completion by bits + * in the LINESTAT register. + * + * This mode of operation is used by MODE_ATOMIC, which uses an I2C + * state machine in the interrupt handler to compose/react to I2C + * transactions using atomic mode commands, and also by MODE_SEQUENCE, + * which emits a simple fixed sequence of atomic mode commands. + * + * Due to software control, the use of atomic commands usually results + * in suboptimal use of the bus, with gaps between the I2C symbols while + * the driver decides what to do next. + * + * - Automatic mode. A bus address, and whether to read/write is + * specified, and the hardware takes care of the I2C state machine, + * using a FIFO to send/receive bytes of data to an I2C slave. The + * driver just has to keep the FIFO drained or filled in response to the + * appropriate FIFO interrupts. + * + * This corresponds to MODE_AUTOMATIC, which manages the FIFOs and deals + * with control of repeated start bits between I2C messages. + * + * Use of automatic mode and the FIFO can make much more efficient use + * of the bus compared to individual atomic commands, with potentially + * no wasted time between I2C symbols or I2C messages. + * + * In most cases MODE_AUTOMATIC is used, however if any of the messages in + * a transaction are zero byte writes (e.g. used by i2cdetect for probing + * the bus), MODE_ATOMIC must be used since automatic mode is normally + * started by the writing of data into the FIFO. + * + * The other modes are used in specific circumstances where MODE_ATOMIC and + * MODE_AUTOMATIC aren't appropriate. MODE_RAW is used to implement a bus + * recovery routine. MODE_SEQUENCE is used to reset the bus and make sure + * it is in a sane state. + * + * Notice that the driver implements a timer-based timeout mechanism. + * The reason for this mechanism is to reduce the number of interrupts + * received in automatic mode. + * + * The driver would get a slave event and transaction done interrupts for + * each atomic mode command that gets completed. However, these events are + * not needed in automatic mode, becase those atomic mode commands are + * managed automatically by the hardware. + * + * In practice, normal I2C transactions will be complete well before you + * get the timer interrupt, as the timer is re-scheduled during FIFO + * maintenance and disabled after the transaction is complete. + * + * In this way normal automatic mode operation isn't impacted by + * unnecessary interrupts, but the exceptional abort condition can still be + * detected (with a slight delay). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register offsets */ + +#define SCB_STATUS_REG 0x00 +#define SCB_OVERRIDE_REG 0x04 +#define SCB_READ_ADDR_REG 0x08 +#define SCB_READ_COUNT_REG 0x0c +#define SCB_WRITE_ADDR_REG 0x10 +#define SCB_READ_DATA_REG 0x14 +#define SCB_WRITE_DATA_REG 0x18 +#define SCB_FIFO_STATUS_REG 0x1c +#define SCB_CONTROL_SOFT_RESET 0x1f +#define SCB_CLK_SET_REG 0x3c +#define SCB_INT_STATUS_REG 0x40 +#define SCB_INT_CLEAR_REG 0x44 +#define SCB_INT_MASK_REG 0x48 +#define SCB_CONTROL_REG 0x4c +#define SCB_TIME_TPL_REG 0x50 +#define SCB_TIME_TPH_REG 0x54 +#define SCB_TIME_TP2S_REG 0x58 +#define SCB_TIME_TBI_REG 0x60 +#define SCB_TIME_TSL_REG 0x64 +#define SCB_TIME_TDL_REG 0x68 +#define SCB_TIME_TSDL_REG 0x6c +#define SCB_TIME_TSDH_REG 0x70 +#define SCB_READ_XADDR_REG 0x74 +#define SCB_WRITE_XADDR_REG 0x78 +#define SCB_WRITE_COUNT_REG 0x7c +#define SCB_CORE_REV_REG 0x80 +#define SCB_TIME_TCKH_REG 0x84 +#define SCB_TIME_TCKL_REG 0x88 +#define SCB_FIFO_FLUSH_REG 0x8c +#define SCB_READ_FIFO_REG 0x94 +#define SCB_CLEAR_REG 0x98 + +/* SCB_CONTROL_REG bits */ + +#define SCB_CONTROL_CLK_ENABLE 0x1e0 +#define SCB_CONTROL_TRANSACTION_HALT 0x200 + +#define FIFO_READ_FULL BIT(0) +#define FIFO_READ_EMPTY BIT(1) +#define FIFO_WRITE_FULL BIT(2) +#define FIFO_WRITE_EMPTY BIT(3) + +/* SCB_CLK_SET_REG bits */ +#define SCB_FILT_DISABLE BIT(31) +#define SCB_FILT_BYPASS BIT(30) +#define SCB_FILT_INC_MASK 0x7f +#define SCB_FILT_INC_SHIFT 16 +#define SCB_INC_MASK 0x7f +#define SCB_INC_SHIFT 8 + +/* SCB_INT_*_REG bits */ + +#define INT_BUS_INACTIVE BIT(0) +#define INT_UNEXPECTED_START BIT(1) +#define INT_SCLK_LOW_TIMEOUT BIT(2) +#define INT_SDAT_LOW_TIMEOUT BIT(3) +#define INT_WRITE_ACK_ERR BIT(4) +#define INT_ADDR_ACK_ERR BIT(5) +#define INT_FIFO_FULL BIT(9) +#define INT_FIFO_FILLING BIT(10) +#define INT_FIFO_EMPTY BIT(11) +#define INT_FIFO_EMPTYING BIT(12) +#define INT_TRANSACTION_DONE BIT(15) +#define INT_SLAVE_EVENT BIT(16) +#define INT_TIMING BIT(18) + +#define INT_FIFO_FULL_FILLING (INT_FIFO_FULL | INT_FIFO_FILLING) +#define INT_FIFO_EMPTY_EMPTYING (INT_FIFO_EMPTY | INT_FIFO_EMPTYING) + +/* Level interrupts need clearing after handling instead of before */ +#define INT_LEVEL 0x01e00 + +/* Don't allow any interrupts while the clock may be off */ +#define INT_ENABLE_MASK_INACTIVE 0x00000 + +/* Interrupt masks for the different driver modes */ + +#define INT_ENABLE_MASK_RAW INT_TIMING + +#define INT_ENABLE_MASK_ATOMIC (INT_TRANSACTION_DONE | \ + INT_SLAVE_EVENT | \ + INT_ADDR_ACK_ERR | \ + INT_WRITE_ACK_ERR) + +#define INT_ENABLE_MASK_AUTOMATIC (INT_SCLK_LOW_TIMEOUT | \ + INT_ADDR_ACK_ERR | \ + INT_WRITE_ACK_ERR | \ + INT_FIFO_FULL | \ + INT_FIFO_FILLING | \ + INT_FIFO_EMPTY | \ + INT_FIFO_EMPTYING) + +#define INT_ENABLE_MASK_WAITSTOP (INT_SLAVE_EVENT | \ + INT_ADDR_ACK_ERR | \ + INT_WRITE_ACK_ERR) + +/* SCB_STATUS_REG fields */ + +#define LINESTAT_SCLK_LINE_STATUS BIT(0) +#define LINESTAT_SCLK_EN BIT(1) +#define LINESTAT_SDAT_LINE_STATUS BIT(2) +#define LINESTAT_SDAT_EN BIT(3) +#define LINESTAT_DET_START_STATUS BIT(4) +#define LINESTAT_DET_STOP_STATUS BIT(5) +#define LINESTAT_DET_ACK_STATUS BIT(6) +#define LINESTAT_DET_NACK_STATUS BIT(7) +#define LINESTAT_BUS_IDLE BIT(8) +#define LINESTAT_T_DONE_STATUS BIT(9) +#define LINESTAT_SCLK_OUT_STATUS BIT(10) +#define LINESTAT_SDAT_OUT_STATUS BIT(11) +#define LINESTAT_GEN_LINE_MASK_STATUS BIT(12) +#define LINESTAT_START_BIT_DET BIT(13) +#define LINESTAT_STOP_BIT_DET BIT(14) +#define LINESTAT_ACK_DET BIT(15) +#define LINESTAT_NACK_DET BIT(16) +#define LINESTAT_INPUT_HELD_V BIT(17) +#define LINESTAT_ABORT_DET BIT(18) +#define LINESTAT_ACK_OR_NACK_DET (LINESTAT_ACK_DET | LINESTAT_NACK_DET) +#define LINESTAT_INPUT_DATA 0xff000000 +#define LINESTAT_INPUT_DATA_SHIFT 24 + +#define LINESTAT_CLEAR_SHIFT 13 +#define LINESTAT_LATCHED (0x3f << LINESTAT_CLEAR_SHIFT) + +/* SCB_OVERRIDE_REG fields */ + +#define OVERRIDE_SCLK_OVR BIT(0) +#define OVERRIDE_SCLKEN_OVR BIT(1) +#define OVERRIDE_SDAT_OVR BIT(2) +#define OVERRIDE_SDATEN_OVR BIT(3) +#define OVERRIDE_MASTER BIT(9) +#define OVERRIDE_LINE_OVR_EN BIT(10) +#define OVERRIDE_DIRECT BIT(11) +#define OVERRIDE_CMD_SHIFT 4 +#define OVERRIDE_CMD_MASK 0x1f +#define OVERRIDE_DATA_SHIFT 24 + +#define OVERRIDE_SCLK_DOWN (OVERRIDE_LINE_OVR_EN | \ + OVERRIDE_SCLKEN_OVR) +#define OVERRIDE_SCLK_UP (OVERRIDE_LINE_OVR_EN | \ + OVERRIDE_SCLKEN_OVR | \ + OVERRIDE_SCLK_OVR) +#define OVERRIDE_SDAT_DOWN (OVERRIDE_LINE_OVR_EN | \ + OVERRIDE_SDATEN_OVR) +#define OVERRIDE_SDAT_UP (OVERRIDE_LINE_OVR_EN | \ + OVERRIDE_SDATEN_OVR | \ + OVERRIDE_SDAT_OVR) + +/* OVERRIDE_CMD values */ + +#define CMD_PAUSE 0x00 +#define CMD_GEN_DATA 0x01 +#define CMD_GEN_START 0x02 +#define CMD_GEN_STOP 0x03 +#define CMD_GEN_ACK 0x04 +#define CMD_GEN_NACK 0x05 +#define CMD_RET_DATA 0x08 +#define CMD_RET_ACK 0x09 + +/* Fixed timing values */ + +#define TIMEOUT_TBI 0x0 +#define TIMEOUT_TSL 0xffff +#define TIMEOUT_TDL 0x0 + +/* Transaction timeout */ + +#define IMG_I2C_TIMEOUT (msecs_to_jiffies(1000)) + +/* + * Worst incs are 1 (innacurate) and 16*256 (irregular). + * So a sensible inc is the logarithmic mean: 64 (2^6), which is + * in the middle of the valid range (0-127). + */ +#define SCB_OPT_INC 64 + +/* Setup the clock enable filtering for 25 ns */ +#define SCB_FILT_GLITCH 25 + +/* + * Bits to return from interrupt handler functions for different modes. + * This delays completion until we've finished with the registers, so that the + * function waiting for completion can safely disable the clock to save power. + */ +#define ISR_COMPLETE_M BIT(31) +#define ISR_FATAL_M BIT(30) +#define ISR_WAITSTOP BIT(29) +#define ISR_STATUS_M 0x0000ffff /* contains +ve errno */ +#define ISR_COMPLETE(err) (ISR_COMPLETE_M | (ISR_STATUS_M & (err))) +#define ISR_FATAL(err) (ISR_COMPLETE(err) | ISR_FATAL_M) + +#define REL_SOC_IP_SCB_2_2_1 0x00020201 + +enum img_i2c_mode { + MODE_INACTIVE, + MODE_RAW, + MODE_ATOMIC, + MODE_AUTOMATIC, + MODE_SEQUENCE, + MODE_FATAL, + MODE_WAITSTOP, + MODE_SUSPEND, +}; + +/* Timing parameters for i2c modes (in ns) */ +struct img_i2c_timings { + const char *name; + unsigned int max_bitrate; + unsigned int tckh, tckl, tsdh, tsdl; + unsigned int tp2s, tpl, tph; +}; + +/* The timings array must be ordered from slower to faster */ +static struct img_i2c_timings timings[] = { + /* Standard mode */ + { + .name = "standard", + .max_bitrate = 100000, + .tckh = 4000, + .tckl = 4700, + .tsdh = 4700, + .tsdl = 8700, + .tp2s = 4700, + .tpl = 4700, + .tph = 4000, + }, + /* Fast mode */ + { + .name = "fast", + .max_bitrate = 400000, + .tckh = 600, + .tckl = 1300, + .tsdh = 600, + .tsdl = 1200, + .tp2s = 1300, + .tpl = 600, + .tph = 600, + }, +}; + +/* Reset dance */ +static u8 img_i2c_reset_seq[] = { CMD_GEN_START, + CMD_GEN_DATA, 0xff, + CMD_RET_ACK, + CMD_GEN_START, + CMD_GEN_STOP, + 0 }; +/* Just issue a stop (after an abort condition) */ +static u8 img_i2c_stop_seq[] = { CMD_GEN_STOP, + 0 }; + +/* We're interested in different interrupts depending on the mode */ +static unsigned int img_i2c_int_enable_by_mode[] = { + [MODE_INACTIVE] = INT_ENABLE_MASK_INACTIVE, + [MODE_RAW] = INT_ENABLE_MASK_RAW, + [MODE_ATOMIC] = INT_ENABLE_MASK_ATOMIC, + [MODE_AUTOMATIC] = INT_ENABLE_MASK_AUTOMATIC, + [MODE_SEQUENCE] = INT_ENABLE_MASK_ATOMIC, + [MODE_FATAL] = 0, + [MODE_WAITSTOP] = INT_ENABLE_MASK_WAITSTOP, + [MODE_SUSPEND] = 0, +}; + +/* Atomic command names */ +static const char * const img_i2c_atomic_cmd_names[] = { + [CMD_PAUSE] = "PAUSE", + [CMD_GEN_DATA] = "GEN_DATA", + [CMD_GEN_START] = "GEN_START", + [CMD_GEN_STOP] = "GEN_STOP", + [CMD_GEN_ACK] = "GEN_ACK", + [CMD_GEN_NACK] = "GEN_NACK", + [CMD_RET_DATA] = "RET_DATA", + [CMD_RET_ACK] = "RET_ACK", +}; + +struct img_i2c { + struct i2c_adapter adap; + + void __iomem *base; + + /* + * The scb core clock is used to get the input frequency, and to disable + * it after every set of transactions to save some power. + */ + struct clk *scb_clk, *sys_clk; + unsigned int bitrate; + bool need_wr_rd_fence; + + /* state */ + struct completion msg_complete; + spinlock_t lock; /* lock before doing anything with the state */ + struct i2c_msg msg; + + /* After the last transaction, wait for a stop bit */ + bool last_msg; + int msg_status; + + enum img_i2c_mode mode; + u32 int_enable; /* depends on mode */ + u32 line_status; /* line status over command */ + + /* + * To avoid slave event interrupts in automatic mode, use a timer to + * poll the abort condition if we don't get an interrupt for too long. + */ + struct timer_list check_timer; + bool t_halt; + + /* atomic mode state */ + bool at_t_done; + bool at_slave_event; + int at_cur_cmd; + u8 at_cur_data; + + /* Sequence: either reset or stop. See img_i2c_sequence. */ + u8 *seq; + + /* raw mode */ + unsigned int raw_timeout; +}; + +static void img_i2c_writel(struct img_i2c *i2c, u32 offset, u32 value) +{ + writel(value, i2c->base + offset); +} + +static u32 img_i2c_readl(struct img_i2c *i2c, u32 offset) +{ + return readl(i2c->base + offset); +} + +/* + * The code to read from the master read fifo, and write to the master + * write fifo, checks a bit in an SCB register before every byte to + * ensure that the fifo is not full (write fifo) or empty (read fifo). + * Due to clock domain crossing inside the SCB block the updated value + * of this bit is only visible after 2 cycles. + * + * The scb_wr_rd_fence() function does 2 dummy writes (to the read-only + * revision register), and it's called after reading from or writing to the + * fifos to ensure that subsequent reads of the fifo status bits do not read + * stale values. + */ +static void img_i2c_wr_rd_fence(struct img_i2c *i2c) +{ + if (i2c->need_wr_rd_fence) { + img_i2c_writel(i2c, SCB_CORE_REV_REG, 0); + img_i2c_writel(i2c, SCB_CORE_REV_REG, 0); + } +} + +static void img_i2c_switch_mode(struct img_i2c *i2c, enum img_i2c_mode mode) +{ + i2c->mode = mode; + i2c->int_enable = img_i2c_int_enable_by_mode[mode]; + i2c->line_status = 0; +} + +static void img_i2c_raw_op(struct img_i2c *i2c) +{ + i2c->raw_timeout = 0; + img_i2c_writel(i2c, SCB_OVERRIDE_REG, + OVERRIDE_SCLKEN_OVR | + OVERRIDE_SDATEN_OVR | + OVERRIDE_MASTER | + OVERRIDE_LINE_OVR_EN | + OVERRIDE_DIRECT | + ((i2c->at_cur_cmd & OVERRIDE_CMD_MASK) << OVERRIDE_CMD_SHIFT) | + (i2c->at_cur_data << OVERRIDE_DATA_SHIFT)); +} + +static const char *img_i2c_atomic_op_name(unsigned int cmd) +{ + if (unlikely(cmd >= ARRAY_SIZE(img_i2c_atomic_cmd_names))) + return "UNKNOWN"; + return img_i2c_atomic_cmd_names[cmd]; +} + +/* Send a single atomic mode command to the hardware */ +static void img_i2c_atomic_op(struct img_i2c *i2c, int cmd, u8 data) +{ + i2c->at_cur_cmd = cmd; + i2c->at_cur_data = data; + + /* work around lack of data setup time when generating data */ + if (cmd == CMD_GEN_DATA && i2c->mode == MODE_ATOMIC) { + u32 line_status = img_i2c_readl(i2c, SCB_STATUS_REG); + + if (line_status & LINESTAT_SDAT_LINE_STATUS && !(data & 0x80)) { + /* hold the data line down for a moment */ + img_i2c_switch_mode(i2c, MODE_RAW); + img_i2c_raw_op(i2c); + return; + } + } + + dev_dbg(i2c->adap.dev.parent, + "atomic cmd=%s (%d) data=%#x\n", + img_i2c_atomic_op_name(cmd), cmd, data); + i2c->at_t_done = (cmd == CMD_RET_DATA || cmd == CMD_RET_ACK); + i2c->at_slave_event = false; + i2c->line_status = 0; + + img_i2c_writel(i2c, SCB_OVERRIDE_REG, + ((cmd & OVERRIDE_CMD_MASK) << OVERRIDE_CMD_SHIFT) | + OVERRIDE_MASTER | + OVERRIDE_DIRECT | + (data << OVERRIDE_DATA_SHIFT)); +} + +/* Start a transaction in atomic mode */ +static void img_i2c_atomic_start(struct img_i2c *i2c) +{ + img_i2c_switch_mode(i2c, MODE_ATOMIC); + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + img_i2c_atomic_op(i2c, CMD_GEN_START, 0x00); +} + +static void img_i2c_soft_reset(struct img_i2c *i2c) +{ + i2c->t_halt = false; + img_i2c_writel(i2c, SCB_CONTROL_REG, 0); + img_i2c_writel(i2c, SCB_CONTROL_REG, + SCB_CONTROL_CLK_ENABLE | SCB_CONTROL_SOFT_RESET); +} + +/* enable or release transaction halt for control of repeated starts */ +static void img_i2c_transaction_halt(struct img_i2c *i2c, bool t_halt) +{ + u32 val; + + if (i2c->t_halt == t_halt) + return; + i2c->t_halt = t_halt; + val = img_i2c_readl(i2c, SCB_CONTROL_REG); + if (t_halt) + val |= SCB_CONTROL_TRANSACTION_HALT; + else + val &= ~SCB_CONTROL_TRANSACTION_HALT; + img_i2c_writel(i2c, SCB_CONTROL_REG, val); +} + +/* Drain data from the FIFO into the buffer (automatic mode) */ +static void img_i2c_read_fifo(struct img_i2c *i2c) +{ + while (i2c->msg.len) { + u32 fifo_status; + u8 data; + + fifo_status = img_i2c_readl(i2c, SCB_FIFO_STATUS_REG); + if (fifo_status & FIFO_READ_EMPTY) + break; + + data = img_i2c_readl(i2c, SCB_READ_DATA_REG); + *i2c->msg.buf = data; + + img_i2c_writel(i2c, SCB_READ_FIFO_REG, 0xff); + img_i2c_wr_rd_fence(i2c); + i2c->msg.len--; + i2c->msg.buf++; + } +} + +/* Fill the FIFO with data from the buffer (automatic mode) */ +static void img_i2c_write_fifo(struct img_i2c *i2c) +{ + while (i2c->msg.len) { + u32 fifo_status; + + fifo_status = img_i2c_readl(i2c, SCB_FIFO_STATUS_REG); + if (fifo_status & FIFO_WRITE_FULL) + break; + + img_i2c_writel(i2c, SCB_WRITE_DATA_REG, *i2c->msg.buf); + img_i2c_wr_rd_fence(i2c); + i2c->msg.len--; + i2c->msg.buf++; + } + + /* Disable fifo emptying interrupt if nothing more to write */ + if (!i2c->msg.len) + i2c->int_enable &= ~INT_FIFO_EMPTYING; +} + +/* Start a read transaction in automatic mode */ +static void img_i2c_read(struct img_i2c *i2c) +{ + img_i2c_switch_mode(i2c, MODE_AUTOMATIC); + if (!i2c->last_msg) + i2c->int_enable |= INT_SLAVE_EVENT; + + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + img_i2c_writel(i2c, SCB_READ_ADDR_REG, i2c->msg.addr); + img_i2c_writel(i2c, SCB_READ_COUNT_REG, i2c->msg.len); + + img_i2c_transaction_halt(i2c, false); + mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); +} + +/* Start a write transaction in automatic mode */ +static void img_i2c_write(struct img_i2c *i2c) +{ + img_i2c_switch_mode(i2c, MODE_AUTOMATIC); + if (!i2c->last_msg) + i2c->int_enable |= INT_SLAVE_EVENT; + + img_i2c_writel(i2c, SCB_WRITE_ADDR_REG, i2c->msg.addr); + img_i2c_writel(i2c, SCB_WRITE_COUNT_REG, i2c->msg.len); + + img_i2c_transaction_halt(i2c, false); + mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); + img_i2c_write_fifo(i2c); + + /* img_i2c_write_fifo() may modify int_enable */ + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); +} + +/* + * Indicate that the transaction is complete. This is called from the + * ISR to wake up the waiting thread, after which the ISR must not + * access any more SCB registers. + */ +static void img_i2c_complete_transaction(struct img_i2c *i2c, int status) +{ + img_i2c_switch_mode(i2c, MODE_INACTIVE); + if (status) { + i2c->msg_status = status; + img_i2c_transaction_halt(i2c, false); + } + complete(&i2c->msg_complete); +} + +static unsigned int img_i2c_raw_atomic_delay_handler(struct img_i2c *i2c, + u32 int_status, u32 line_status) +{ + /* Stay in raw mode for this, so we don't just loop infinitely */ + img_i2c_atomic_op(i2c, i2c->at_cur_cmd, i2c->at_cur_data); + img_i2c_switch_mode(i2c, MODE_ATOMIC); + return 0; +} + +static unsigned int img_i2c_raw(struct img_i2c *i2c, u32 int_status, + u32 line_status) +{ + if (int_status & INT_TIMING) { + if (i2c->raw_timeout == 0) + return img_i2c_raw_atomic_delay_handler(i2c, + int_status, line_status); + --i2c->raw_timeout; + } + return 0; +} + +static unsigned int img_i2c_sequence(struct img_i2c *i2c, u32 int_status) +{ + static const unsigned int continue_bits[] = { + [CMD_GEN_START] = LINESTAT_START_BIT_DET, + [CMD_GEN_DATA] = LINESTAT_INPUT_HELD_V, + [CMD_RET_ACK] = LINESTAT_ACK_DET | LINESTAT_NACK_DET, + [CMD_RET_DATA] = LINESTAT_INPUT_HELD_V, + [CMD_GEN_STOP] = LINESTAT_STOP_BIT_DET, + }; + int next_cmd = -1; + u8 next_data = 0x00; + + if (int_status & INT_SLAVE_EVENT) + i2c->at_slave_event = true; + if (int_status & INT_TRANSACTION_DONE) + i2c->at_t_done = true; + + if (!i2c->at_slave_event || !i2c->at_t_done) + return 0; + + /* wait if no continue bits are set */ + if (i2c->at_cur_cmd >= 0 && + i2c->at_cur_cmd < ARRAY_SIZE(continue_bits)) { + unsigned int cont_bits = continue_bits[i2c->at_cur_cmd]; + + if (cont_bits) { + cont_bits |= LINESTAT_ABORT_DET; + if (!(i2c->line_status & cont_bits)) + return 0; + } + } + + /* follow the sequence of commands in i2c->seq */ + next_cmd = *i2c->seq; + /* stop on a nil */ + if (!next_cmd) { + img_i2c_writel(i2c, SCB_OVERRIDE_REG, 0); + return ISR_COMPLETE(0); + } + /* when generating data, the next byte is the data */ + if (next_cmd == CMD_GEN_DATA) { + ++i2c->seq; + next_data = *i2c->seq; + } + ++i2c->seq; + img_i2c_atomic_op(i2c, next_cmd, next_data); + + return 0; +} + +static void img_i2c_reset_start(struct img_i2c *i2c) +{ + /* Initiate the magic dance */ + img_i2c_switch_mode(i2c, MODE_SEQUENCE); + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + i2c->seq = img_i2c_reset_seq; + i2c->at_slave_event = true; + i2c->at_t_done = true; + i2c->at_cur_cmd = -1; + + /* img_i2c_reset_seq isn't empty so the following won't fail */ + img_i2c_sequence(i2c, 0); +} + +static void img_i2c_stop_start(struct img_i2c *i2c) +{ + /* Initiate a stop bit sequence */ + img_i2c_switch_mode(i2c, MODE_SEQUENCE); + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + i2c->seq = img_i2c_stop_seq; + i2c->at_slave_event = true; + i2c->at_t_done = true; + i2c->at_cur_cmd = -1; + + /* img_i2c_stop_seq isn't empty so the following won't fail */ + img_i2c_sequence(i2c, 0); +} + +static unsigned int img_i2c_atomic(struct img_i2c *i2c, + u32 int_status, + u32 line_status) +{ + int next_cmd = -1; + u8 next_data = 0x00; + + if (int_status & INT_SLAVE_EVENT) + i2c->at_slave_event = true; + if (int_status & INT_TRANSACTION_DONE) + i2c->at_t_done = true; + + if (!i2c->at_slave_event || !i2c->at_t_done) + goto next_atomic_cmd; + if (i2c->line_status & LINESTAT_ABORT_DET) { + dev_dbg(i2c->adap.dev.parent, "abort condition detected\n"); + next_cmd = CMD_GEN_STOP; + i2c->msg_status = -EIO; + goto next_atomic_cmd; + } + + /* i2c->at_cur_cmd may have completed */ + switch (i2c->at_cur_cmd) { + case CMD_GEN_START: + next_cmd = CMD_GEN_DATA; + next_data = (i2c->msg.addr << 1); + if (i2c->msg.flags & I2C_M_RD) + next_data |= 0x1; + break; + case CMD_GEN_DATA: + if (i2c->line_status & LINESTAT_INPUT_HELD_V) + next_cmd = CMD_RET_ACK; + break; + case CMD_RET_ACK: + if (i2c->line_status & LINESTAT_ACK_DET) { + if (i2c->msg.len == 0) { + next_cmd = CMD_GEN_STOP; + } else if (i2c->msg.flags & I2C_M_RD) { + next_cmd = CMD_RET_DATA; + } else { + next_cmd = CMD_GEN_DATA; + next_data = *i2c->msg.buf; + --i2c->msg.len; + ++i2c->msg.buf; + } + } else if (i2c->line_status & LINESTAT_NACK_DET) { + i2c->msg_status = -EIO; + next_cmd = CMD_GEN_STOP; + } + break; + case CMD_RET_DATA: + if (i2c->line_status & LINESTAT_INPUT_HELD_V) { + *i2c->msg.buf = (i2c->line_status & + LINESTAT_INPUT_DATA) + >> LINESTAT_INPUT_DATA_SHIFT; + --i2c->msg.len; + ++i2c->msg.buf; + if (i2c->msg.len) + next_cmd = CMD_GEN_ACK; + else + next_cmd = CMD_GEN_NACK; + } + break; + case CMD_GEN_ACK: + if (i2c->line_status & LINESTAT_ACK_DET) { + next_cmd = CMD_RET_DATA; + } else { + i2c->msg_status = -EIO; + next_cmd = CMD_GEN_STOP; + } + break; + case CMD_GEN_NACK: + next_cmd = CMD_GEN_STOP; + break; + case CMD_GEN_STOP: + img_i2c_writel(i2c, SCB_OVERRIDE_REG, 0); + return ISR_COMPLETE(0); + default: + dev_err(i2c->adap.dev.parent, "bad atomic command %d\n", + i2c->at_cur_cmd); + i2c->msg_status = -EIO; + next_cmd = CMD_GEN_STOP; + break; + } + +next_atomic_cmd: + if (next_cmd != -1) { + /* don't actually stop unless we're the last transaction */ + if (next_cmd == CMD_GEN_STOP && !i2c->msg_status && + !i2c->last_msg) + return ISR_COMPLETE(0); + img_i2c_atomic_op(i2c, next_cmd, next_data); + } + return 0; +} + +/* + * Timer function to check if something has gone wrong in automatic mode (so we + * don't have to handle so many interrupts just to catch an exception). + */ +static void img_i2c_check_timer(unsigned long arg) +{ + struct img_i2c *i2c = (struct img_i2c *)arg; + unsigned long flags; + unsigned int line_status; + + spin_lock_irqsave(&i2c->lock, flags); + line_status = img_i2c_readl(i2c, SCB_STATUS_REG); + + /* check for an abort condition */ + if (line_status & LINESTAT_ABORT_DET) { + dev_dbg(i2c->adap.dev.parent, + "abort condition detected by check timer\n"); + /* enable slave event interrupt mask to trigger irq */ + img_i2c_writel(i2c, SCB_INT_MASK_REG, + i2c->int_enable | INT_SLAVE_EVENT); + } + + spin_unlock_irqrestore(&i2c->lock, flags); +} + +static unsigned int img_i2c_auto(struct img_i2c *i2c, + unsigned int int_status, + unsigned int line_status) +{ + if (int_status & (INT_WRITE_ACK_ERR | INT_ADDR_ACK_ERR)) + return ISR_COMPLETE(EIO); + + if (line_status & LINESTAT_ABORT_DET) { + dev_dbg(i2c->adap.dev.parent, "abort condition detected\n"); + /* empty the read fifo */ + if ((i2c->msg.flags & I2C_M_RD) && + (int_status & INT_FIFO_FULL_FILLING)) + img_i2c_read_fifo(i2c); + /* use atomic mode and try to force a stop bit */ + i2c->msg_status = -EIO; + img_i2c_stop_start(i2c); + return 0; + } + + /* Enable transaction halt on start bit */ + if (!i2c->last_msg && i2c->line_status & LINESTAT_START_BIT_DET) { + img_i2c_transaction_halt(i2c, true); + /* we're no longer interested in the slave event */ + i2c->int_enable &= ~INT_SLAVE_EVENT; + } + + mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1)); + + if (i2c->msg.flags & I2C_M_RD) { + if (int_status & INT_FIFO_FULL_FILLING) { + img_i2c_read_fifo(i2c); + if (i2c->msg.len == 0) + return ISR_WAITSTOP; + } + } else { + if (int_status & INT_FIFO_EMPTY_EMPTYING) { + /* + * The write fifo empty indicates that we're in the + * last byte so it's safe to start a new write + * transaction without losing any bytes from the + * previous one. + * see 2.3.7 Repeated Start Transactions. + */ + if ((int_status & INT_FIFO_EMPTY) && + i2c->msg.len == 0) + return ISR_WAITSTOP; + img_i2c_write_fifo(i2c); + } + } + + return 0; +} + +static irqreturn_t img_i2c_isr(int irq, void *dev_id) +{ + struct img_i2c *i2c = (struct img_i2c *)dev_id; + u32 int_status, line_status; + /* We handle transaction completion AFTER accessing registers */ + unsigned int hret; + + /* Read interrupt status register. */ + int_status = img_i2c_readl(i2c, SCB_INT_STATUS_REG); + /* Clear detected interrupts. */ + img_i2c_writel(i2c, SCB_INT_CLEAR_REG, int_status); + + /* + * Read line status and clear it until it actually is clear. We have + * to be careful not to lose any line status bits that get latched. + */ + line_status = img_i2c_readl(i2c, SCB_STATUS_REG); + if (line_status & LINESTAT_LATCHED) { + img_i2c_writel(i2c, SCB_CLEAR_REG, + (line_status & LINESTAT_LATCHED) + >> LINESTAT_CLEAR_SHIFT); + img_i2c_wr_rd_fence(i2c); + } + + spin_lock(&i2c->lock); + + /* Keep track of line status bits received */ + i2c->line_status &= ~LINESTAT_INPUT_DATA; + i2c->line_status |= line_status; + + /* + * Certain interrupts indicate that sclk low timeout is not + * a problem. If any of these are set, just continue. + */ + if ((int_status & INT_SCLK_LOW_TIMEOUT) && + !(int_status & (INT_SLAVE_EVENT | + INT_FIFO_EMPTY | + INT_FIFO_FULL))) { + dev_crit(i2c->adap.dev.parent, + "fatal: clock low timeout occurred %s addr 0x%02x\n", + (i2c->msg.flags & I2C_M_RD) ? "reading" : "writing", + i2c->msg.addr); + hret = ISR_FATAL(EIO); + goto out; + } + + if (i2c->mode == MODE_ATOMIC) + hret = img_i2c_atomic(i2c, int_status, line_status); + else if (i2c->mode == MODE_AUTOMATIC) + hret = img_i2c_auto(i2c, int_status, line_status); + else if (i2c->mode == MODE_SEQUENCE) + hret = img_i2c_sequence(i2c, int_status); + else if (i2c->mode == MODE_WAITSTOP && (int_status & INT_SLAVE_EVENT) && + (line_status & LINESTAT_STOP_BIT_DET)) + hret = ISR_COMPLETE(0); + else if (i2c->mode == MODE_RAW) + hret = img_i2c_raw(i2c, int_status, line_status); + else + hret = 0; + + /* Clear detected level interrupts. */ + img_i2c_writel(i2c, SCB_INT_CLEAR_REG, int_status & INT_LEVEL); + +out: + if (hret & ISR_WAITSTOP) { + /* + * Only wait for stop on last message. + * Also we may already have detected the stop bit. + */ + if (!i2c->last_msg || i2c->line_status & LINESTAT_STOP_BIT_DET) + hret = ISR_COMPLETE(0); + else + img_i2c_switch_mode(i2c, MODE_WAITSTOP); + } + + /* now we've finished using regs, handle transaction completion */ + if (hret & ISR_COMPLETE_M) { + int status = -(hret & ISR_STATUS_M); + + img_i2c_complete_transaction(i2c, status); + if (hret & ISR_FATAL_M) + img_i2c_switch_mode(i2c, MODE_FATAL); + } + + /* Enable interrupts (int_enable may be altered by changing mode) */ + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + + spin_unlock(&i2c->lock); + + return IRQ_HANDLED; +} + +/* Force a bus reset sequence and wait for it to complete */ +static int img_i2c_reset_bus(struct img_i2c *i2c) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&i2c->lock, flags); + reinit_completion(&i2c->msg_complete); + img_i2c_reset_start(i2c); + spin_unlock_irqrestore(&i2c->lock, flags); + + ret = wait_for_completion_timeout(&i2c->msg_complete, IMG_I2C_TIMEOUT); + if (ret == 0) + return -ETIMEDOUT; + return 0; +} + +static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num) +{ + struct img_i2c *i2c = i2c_get_adapdata(adap); + bool atomic = false; + int i, ret; + + if (i2c->mode == MODE_SUSPEND) { + WARN(1, "refusing to service transaction in suspended state\n"); + return -EIO; + } + + if (i2c->mode == MODE_FATAL) + return -EIO; + + for (i = 0; i < num; i++) { + if (likely(msgs[i].len)) + continue; + /* + * 0 byte reads are not possible because the slave could try + * and pull the data line low, preventing a stop bit. + */ + if (unlikely(msgs[i].flags & I2C_M_RD)) + return -EIO; + /* + * 0 byte writes are possible and used for probing, but we + * cannot do them in automatic mode, so use atomic mode + * instead. + */ + atomic = true; + } + + ret = clk_prepare_enable(i2c->scb_clk); + if (ret) + return ret; + + for (i = 0; i < num; i++) { + struct i2c_msg *msg = &msgs[i]; + unsigned long flags; + + spin_lock_irqsave(&i2c->lock, flags); + + /* + * Make a copy of the message struct. We mustn't modify the + * original or we'll confuse drivers and i2c-dev. + */ + i2c->msg = *msg; + i2c->msg_status = 0; + + /* + * After the last message we must have waited for a stop bit. + * Not waiting can cause problems when the clock is disabled + * before the stop bit is sent, and the linux I2C interface + * requires separate transfers not to joined with repeated + * start. + */ + i2c->last_msg = (i == num - 1); + reinit_completion(&i2c->msg_complete); + + if (atomic) + img_i2c_atomic_start(i2c); + else if (msg->flags & I2C_M_RD) + img_i2c_read(i2c); + else + img_i2c_write(i2c); + spin_unlock_irqrestore(&i2c->lock, flags); + + ret = wait_for_completion_timeout(&i2c->msg_complete, + IMG_I2C_TIMEOUT); + del_timer_sync(&i2c->check_timer); + + if (ret == 0) { + dev_err(adap->dev.parent, "i2c transfer timed out\n"); + i2c->msg_status = -ETIMEDOUT; + break; + } + + if (i2c->msg_status) + break; + } + + clk_disable_unprepare(i2c->scb_clk); + + return i2c->msg_status ? i2c->msg_status : num; +} + +static u32 img_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm img_i2c_algo = { + .master_xfer = img_i2c_xfer, + .functionality = img_i2c_func, +}; + +static int img_i2c_init(struct img_i2c *i2c) +{ + unsigned int clk_khz, bitrate_khz, clk_period, tckh, tckl, tsdh; + unsigned int i, ret, data, prescale, inc, int_bitrate, filt; + struct img_i2c_timings timing; + u32 rev; + + ret = clk_prepare_enable(i2c->scb_clk); + if (ret) + return ret; + + rev = img_i2c_readl(i2c, SCB_CORE_REV_REG); + if ((rev & 0x00ffffff) < 0x00020200) { + dev_info(i2c->adap.dev.parent, + "Unknown hardware revision (%d.%d.%d.%d)\n", + (rev >> 24) & 0xff, (rev >> 16) & 0xff, + (rev >> 8) & 0xff, rev & 0xff); + clk_disable_unprepare(i2c->scb_clk); + return -EINVAL; + } + + if (rev == REL_SOC_IP_SCB_2_2_1) { + i2c->need_wr_rd_fence = true; + dev_info(i2c->adap.dev.parent, "fence quirk enabled"); + } + + bitrate_khz = i2c->bitrate / 1000; + clk_khz = clk_get_rate(i2c->scb_clk) / 1000; + + /* Determine what mode we're in from the bitrate */ + timing = timings[0]; + for (i = 0; i < ARRAY_SIZE(timings); i++) { + if (i2c->bitrate <= timings[i].max_bitrate) { + timing = timings[i]; + break; + } + } + + /* Find the prescale that would give us that inc (approx delay = 0) */ + prescale = SCB_OPT_INC * clk_khz / (256 * 16 * bitrate_khz); + prescale = clamp_t(unsigned int, prescale, 1, 8); + clk_khz /= prescale; + + /* Setup the clock increment value */ + inc = (256 * 16 * bitrate_khz) / clk_khz; + + /* + * The clock generation logic allows to filter glitches on the bus. + * This filter is able to remove bus glitches shorter than 50ns. + * If the clock enable rate is greater than 20 MHz, no filtering + * is required, so we need to disable it. + * If it's between the 20-40 MHz range, there's no need to divide + * the clock to get a filter. + */ + if (clk_khz < 20000) { + filt = SCB_FILT_DISABLE; + } else if (clk_khz < 40000) { + filt = SCB_FILT_BYPASS; + } else { + /* Calculate filter clock */ + filt = (64000 / ((clk_khz / 1000) * SCB_FILT_GLITCH)); + + /* Scale up if needed */ + if (64000 % ((clk_khz / 1000) * SCB_FILT_GLITCH)) + inc++; + + if (filt > SCB_FILT_INC_MASK) + filt = SCB_FILT_INC_MASK; + + filt = (filt & SCB_FILT_INC_MASK) << SCB_FILT_INC_SHIFT; + } + data = filt | ((inc & SCB_INC_MASK) << SCB_INC_SHIFT) | (prescale - 1); + img_i2c_writel(i2c, SCB_CLK_SET_REG, data); + + /* Obtain the clock period of the fx16 clock in ns */ + clk_period = (256 * 1000000) / (clk_khz * inc); + + /* Calculate the bitrate in terms of internal clock pulses */ + int_bitrate = 1000000 / (bitrate_khz * clk_period); + if ((1000000 % (bitrate_khz * clk_period)) >= + ((bitrate_khz * clk_period) / 2)) + int_bitrate++; + + /* Setup TCKH value */ + tckh = timing.tckh / clk_period; + if (timing.tckh % clk_period) + tckh++; + + if (tckh > 0) + data = tckh - 1; + else + data = 0; + + img_i2c_writel(i2c, SCB_TIME_TCKH_REG, data); + + /* Setup TCKL value */ + tckl = int_bitrate - tckh; + + if (tckl > 0) + data = tckl - 1; + else + data = 0; + + img_i2c_writel(i2c, SCB_TIME_TCKL_REG, data); + + /* Setup TSDH value */ + tsdh = timing.tsdh / clk_period; + if (timing.tsdh % clk_period) + tsdh++; + + if (tsdh > 1) + data = tsdh - 1; + else + data = 0x01; + img_i2c_writel(i2c, SCB_TIME_TSDH_REG, data); + + /* This value is used later */ + tsdh = data; + + /* Setup TPL value */ + data = timing.tpl / clk_period; + if (data > 0) + --data; + img_i2c_writel(i2c, SCB_TIME_TPL_REG, data); + + /* Setup TPH value */ + data = timing.tph / clk_period; + if (data > 0) + --data; + img_i2c_writel(i2c, SCB_TIME_TPH_REG, data); + + /* Setup TSDL value to TPL + TSDH + 2 */ + img_i2c_writel(i2c, SCB_TIME_TSDL_REG, data + tsdh + 2); + + /* Setup TP2S value */ + data = timing.tp2s / clk_period; + if (data > 0) + --data; + img_i2c_writel(i2c, SCB_TIME_TP2S_REG, data); + + img_i2c_writel(i2c, SCB_TIME_TBI_REG, TIMEOUT_TBI); + img_i2c_writel(i2c, SCB_TIME_TSL_REG, TIMEOUT_TSL); + img_i2c_writel(i2c, SCB_TIME_TDL_REG, TIMEOUT_TDL); + + /* Take module out of soft reset and enable clocks */ + img_i2c_soft_reset(i2c); + + /* Disable all interrupts */ + img_i2c_writel(i2c, SCB_INT_MASK_REG, 0); + + /* Clear all interrupts */ + img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0); + + /* Clear the scb_line_status events */ + img_i2c_writel(i2c, SCB_CLEAR_REG, ~0); + + /* Enable interrupts */ + img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable); + + /* Perform a synchronous sequence to reset the bus */ + ret = img_i2c_reset_bus(i2c); + + clk_disable_unprepare(i2c->scb_clk); + + return ret; +} + +static int img_i2c_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct img_i2c *i2c; + struct resource *res; + int irq, ret; + u32 val; + + i2c = devm_kzalloc(&pdev->dev, sizeof(struct img_i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + i2c->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "can't get irq number\n"); + return irq; + } + + i2c->sys_clk = devm_clk_get(&pdev->dev, "sys"); + if (IS_ERR(i2c->sys_clk)) { + dev_err(&pdev->dev, "can't get system clock\n"); + return PTR_ERR(i2c->sys_clk); + } + + i2c->scb_clk = devm_clk_get(&pdev->dev, "scb"); + if (IS_ERR(i2c->scb_clk)) { + dev_err(&pdev->dev, "can't get core clock\n"); + return PTR_ERR(i2c->scb_clk); + } + + ret = devm_request_irq(&pdev->dev, irq, img_i2c_isr, 0, + pdev->name, i2c); + if (ret) { + dev_err(&pdev->dev, "can't request irq %d\n", irq); + return ret; + } + + /* Set up the exception check timer */ + init_timer(&i2c->check_timer); + i2c->check_timer.function = img_i2c_check_timer; + i2c->check_timer.data = (unsigned long)i2c; + + i2c->bitrate = timings[0].max_bitrate; + if (!of_property_read_u32(node, "clock-frequency", &val)) + i2c->bitrate = val; + + i2c_set_adapdata(&i2c->adap, i2c); + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = node; + i2c->adap.owner = THIS_MODULE; + i2c->adap.algo = &img_i2c_algo; + i2c->adap.retries = 5; + i2c->adap.nr = pdev->id; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), "IMG SCB I2C"); + + img_i2c_switch_mode(i2c, MODE_INACTIVE); + spin_lock_init(&i2c->lock); + init_completion(&i2c->msg_complete); + + platform_set_drvdata(pdev, i2c); + + ret = clk_prepare_enable(i2c->sys_clk); + if (ret) + return ret; + + ret = img_i2c_init(i2c); + if (ret) + goto disable_clk; + + ret = i2c_add_numbered_adapter(&i2c->adap); + if (ret < 0) { + dev_err(&pdev->dev, "failed to add adapter\n"); + goto disable_clk; + } + + return 0; + +disable_clk: + clk_disable_unprepare(i2c->sys_clk); + return ret; +} + +static int img_i2c_remove(struct platform_device *dev) +{ + struct img_i2c *i2c = platform_get_drvdata(dev); + + i2c_del_adapter(&i2c->adap); + clk_disable_unprepare(i2c->sys_clk); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int img_i2c_suspend(struct device *dev) +{ + struct img_i2c *i2c = dev_get_drvdata(dev); + + img_i2c_switch_mode(i2c, MODE_SUSPEND); + + clk_disable_unprepare(i2c->sys_clk); + + return 0; +} + +static int img_i2c_resume(struct device *dev) +{ + struct img_i2c *i2c = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(i2c->sys_clk); + if (ret) + return ret; + + img_i2c_init(i2c); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(img_i2c_pm, img_i2c_suspend, img_i2c_resume); + +static const struct of_device_id img_scb_i2c_match[] = { + { .compatible = "img,scb-i2c" }, + { } +}; +MODULE_DEVICE_TABLE(of, img_scb_i2c_match); + +static struct platform_driver img_scb_i2c_driver = { + .driver = { + .name = "img-i2c-scb", + .of_match_table = img_scb_i2c_match, + .pm = &img_i2c_pm, + }, + .probe = img_i2c_probe, + .remove = img_i2c_remove, +}; +module_platform_driver(img_scb_i2c_driver); + +MODULE_AUTHOR("James Hogan "); +MODULE_DESCRIPTION("IMG host I2C driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 6f34be7400c68d3f761ceca405edabb94ccfcd03 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 17 Nov 2014 12:43:00 +0100 Subject: [PATCH 5077/9457] i2c: core: Fix probing of i2c slaves without interrupts Since commit 2fd36c55264926e2 ("i2c: core: Map OF IRQ at probe time"), i2c slaves without interrupts (e.g. da9210 and at24 on r8a7791/koelsch) fail to probe: at24: probe of 2-0050 failed with error -22 da9210: probe of 6-0068 failed with error -22 This happens because the call to of_irq_get() in i2c_device_probe() returns -EINVAL. If a device node does not have an "interrupts" property, of_irq_parse_one() fails. Unlike irq_of_parse_and_map(), of_irq_get() does not ignore errors from of_irq_parse_one(), but forwards them. Make i2c_device_probe() ignore all errors but -EPROBE_DEFER to fix this, just like platform_get_irq() and platform_get_irq_byname() already do. Fixes: 2fd36c55264926e2 ("i2c: core: Map OF IRQ at probe time") Signed-off-by: Geert Uytterhoeven Tested-by: Fabio Estevam Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a0768d6dffc2..cf830915713b 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -629,8 +629,10 @@ static int i2c_device_probe(struct device *dev) if (!client->irq && dev->of_node) { int irq = of_irq_get(dev->of_node, 0); - if (irq < 0) + if (irq == -EPROBE_DEFER) return irq; + if (irq < 0) + irq = 0; client->irq = irq; } -- GitLab From fe7710fae477f648773648ea0a05b079c5b66667 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 11 Nov 2014 15:53:25 +0100 Subject: [PATCH 5078/9457] clk: add pxa25x clock drivers Move pxa25x clock drivers from arch/arm/mach-pxa to driver/clk. In the move : - convert to new clock framework legacy clocks - provide clocks as before for platform data based boards - provide clocks through devicetree with clk-pxa-dt This is the preliminary step in the conversion. The remaining steps are : - pxa3xx - once PXA is fully converted to device tree, if that happens, clk-pxa2* and clk-pxa3* should only hold the core clocks which cannot be described in devicetree. Signed-off-by: Robert Jarzmik Tested-by: Dmitry Eremin-Solenikov Signed-off-by: Michael Turquette --- drivers/clk/pxa/Makefile | 1 + drivers/clk/pxa/clk-pxa25x.c | 273 +++++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 drivers/clk/pxa/clk-pxa25x.c diff --git a/drivers/clk/pxa/Makefile b/drivers/clk/pxa/Makefile index 4ff2abcd500b..38e915344605 100644 --- a/drivers/clk/pxa/Makefile +++ b/drivers/clk/pxa/Makefile @@ -1,2 +1,3 @@ obj-y += clk-pxa.o +obj-$(CONFIG_PXA25x) += clk-pxa25x.o obj-$(CONFIG_PXA27x) += clk-pxa27x.o diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c new file mode 100644 index 000000000000..6cd88d963a7f --- /dev/null +++ b/drivers/clk/pxa/clk-pxa25x.c @@ -0,0 +1,273 @@ +/* + * Marvell PXA25x family clocks + * + * Copyright (C) 2014 Robert Jarzmik + * + * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c. + * + * 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. + * + * For non-devicetree platforms. Once pxa is fully converted to devicetree, this + * should go away. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include "clk-pxa.h" + +#define KHz 1000 +#define MHz (1000 * 1000) + +enum { + PXA_CORE_RUN = 0, + PXA_CORE_TURBO, +}; + +/* + * Various clock factors driven by the CCCR register. + */ + +/* Crystal Frequency to Memory Frequency Multiplier (L) */ +static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; + +/* Memory Frequency to Run Mode Frequency Multiplier (M) */ +static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; + +/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ +/* Note: we store the value N * 2 here. */ +static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 }; + +static const char * const get_freq_khz[] = { + "core", "run", "cpll", "memory" +}; + +/* + * Get the clock frequency as reflected by CCCR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int pxa25x_get_clk_frequency_khz(int info) +{ + struct clk *clk; + unsigned long clks[5]; + int i; + + for (i = 0; i < ARRAY_SIZE(get_freq_khz); i++) { + clk = clk_get(NULL, get_freq_khz[i]); + if (IS_ERR(clk)) { + clks[i] = 0; + } else { + clks[i] = clk_get_rate(clk); + clk_put(clk); + } + } + + if (info) { + pr_info("Run Mode clock: %ld.%02ldMHz\n", + clks[1] / 1000000, (clks[1] % 1000000) / 10000); + pr_info("Turbo Mode clock: %ld.%02ldMHz\n", + clks[2] / 1000000, (clks[2] % 1000000) / 10000); + pr_info("Memory clock: %ld.%02ldMHz\n", + clks[3] / 1000000, (clks[3] % 1000000) / 10000); + } + + return (unsigned int)clks[0]; +} + +static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long cccr = CCCR; + unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; + + return parent_rate / m; +} +PARENTS(clk_pxa25x_memory) = { "run" }; +RATE_RO_OPS(clk_pxa25x_memory, "memory"); + +PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" }; +PARENTS(pxa25x_pbus147) = { "ppll_147_46mhz", "ppll_147_46mhz" }; +PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; + +#define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \ + bit, is_lp, flags) \ + PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \ + is_lp, &CKEN, CKEN_ ## bit, flags) +#define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ + PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \ + div_hp, bit, NULL, 0) +#define PXA25X_PBUS147_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)\ + PXA25X_CKEN(dev_id, con_id, pxa25x_pbus147_parents, mult_hp, \ + div_hp, bit, NULL, 0) +#define PXA25X_OSC3_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ + PXA25X_CKEN(dev_id, con_id, pxa25x_osc3_parents, mult_hp, \ + div_hp, bit, NULL, 0) + +#define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ + &CKEN, CKEN_ ## bit, 0) +#define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ + PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ + &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + +static struct desc_clk_cken pxa25x_clocks[] __initdata = { + PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0), + PXA25X_PBUS95_CKEN("pxa2xx-i2c.0", NULL, I2C, 1, 3, 0), + PXA25X_PBUS95_CKEN("pxa2xx-ir", "FICPCLK", FICP, 1, 2, 0), + PXA25X_PBUS95_CKEN("pxa25x-udc", NULL, USB, 1, 2, 5), + PXA25X_PBUS147_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-uart.3", NULL, HWUART, 1, 10, 1), + PXA25X_PBUS147_CKEN("pxa2xx-i2s", NULL, I2S, 1, 10, 0), + PXA25X_PBUS147_CKEN(NULL, "AC97CLK", AC97, 1, 12, 0), + PXA25X_OSC3_CKEN("pxa25x-ssp.0", NULL, SSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-nssp.1", NULL, NSSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-nssp.2", NULL, ASSP, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-pwm.0", NULL, PWM0, 1, 1, 0), + PXA25X_OSC3_CKEN("pxa25x-pwm.1", NULL, PWM1, 1, 1, 0), + + PXA25X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, clk_pxa25x_memory_parents, 0), + PXA25X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC, + clk_pxa25x_memory_parents, 0), +}; + +static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw) +{ + unsigned long clkcfg; + unsigned int t; + + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); + t = clkcfg & (1 << 0); + if (t) + return PXA_CORE_TURBO; + return PXA_CORE_RUN; +} + +static unsigned long clk_pxa25x_core_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} +PARENTS(clk_pxa25x_core) = { "run", "cpll" }; +MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core"); + +static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long cccr = CCCR; + unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; + + return (parent_rate / n2) * 2; +} +PARENTS(clk_pxa25x_run) = { "cpll" }; +RATE_RO_OPS(clk_pxa25x_run, "run"); + +static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long clkcfg, cccr = CCCR; + unsigned int l, m, n2, t; + + asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); + t = clkcfg & (1 << 0); + l = L_clk_mult[(cccr >> 0) & 0x1f]; + m = M_clk_mult[(cccr >> 5) & 0x03]; + n2 = N2_clk_mult[(cccr >> 7) & 0x07]; + + if (t) + return m * l * n2 * parent_rate / 2; + return m * l * parent_rate; +} +PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" }; +RATE_RO_OPS(clk_pxa25x_cpll, "cpll"); + +static void __init pxa25x_register_core(void) +{ + clk_register_clk_pxa25x_cpll(); + clk_register_clk_pxa25x_run(); + clkdev_pxa_register(CLK_CORE, "core", NULL, + clk_register_clk_pxa25x_core()); +} + +static void __init pxa25x_register_plls(void) +{ + clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + 3686400); + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, + CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + 32768); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", + 0, 26, 1); + clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz", + 0, 40, 1); +} + +static void __init pxa25x_base_clocks_init(void) +{ + pxa25x_register_plls(); + pxa25x_register_core(); + clk_register_clk_pxa25x_memory(); +} + +#define DUMMY_CLK(_con_id, _dev_id, _parent) \ + { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent } +struct dummy_clk { + const char *con_id; + const char *dev_id; + const char *parent; +}; +static struct dummy_clk dummy_clks[] __initdata = { + DUMMY_CLK(NULL, "pxa25x-gpio", "osc_32_768khz"), + DUMMY_CLK(NULL, "pxa26x-gpio", "osc_32_768khz"), + DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"), + DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"), + DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), + DUMMY_CLK("OSTIMER0", NULL, "osc_32_768khz"), + DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), +}; + +static void __init pxa25x_dummy_clocks_init(void) +{ + struct clk *clk; + struct dummy_clk *d; + const char *name; + int i; + + /* + * All pinctrl logic has been wiped out of the clock driver, especially + * for gpio11 and gpio12 outputs. Machine code should ensure proper pin + * control (ie. pxa2xx_mfp_config() invocation). + */ + for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { + d = &dummy_clks[i]; + name = d->dev_id ? d->dev_id : d->con_id; + clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1); + clk_register_clkdev(clk, d->con_id, d->dev_id); + } +} + +int __init pxa25x_clocks_init(void) +{ + pxa25x_base_clocks_init(); + pxa25x_dummy_clocks_init(); + return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks)); +} + +static void __init pxa25x_dt_clocks_init(struct device_node *np) +{ + pxa25x_clocks_init(); + clk_pxa_dt_common_init(np); +} +CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks", + pxa25x_dt_clocks_init); -- GitLab From 14dd5b01ae86760142157a5259b7f798eb840697 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 7 Oct 2014 01:07:58 +0200 Subject: [PATCH 5079/9457] clk: pxa: declare init function and data __init As the clock descriptions are constant and only usefull at init time, mark them as such by : - spliting clock description (desc) and clock private data (dynamic) - mark __initdata clock descriptions This makes all the register and descriptions of the clocks to go after kernel init phase. Signed-off-by: Robert Jarzmik Signed-off-by: Michael Turquette --- drivers/clk/pxa/clk-pxa.c | 42 +++++++++++++++++++++++------------- drivers/clk/pxa/clk-pxa.h | 8 +++---- drivers/clk/pxa/clk-pxa27x.c | 2 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c index ef3c05389c0a..994fd6fc266f 100644 --- a/drivers/clk/pxa/clk-pxa.c +++ b/drivers/clk/pxa/clk-pxa.c @@ -26,12 +26,20 @@ static struct clk_onecell_data onecell_data = { .clk_num = CLK_MAX, }; -#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw) +struct pxa_clk { + struct clk_hw hw; + struct clk_fixed_factor lp; + struct clk_fixed_factor hp; + struct clk_gate gate; + bool (*is_in_low_power)(void); +}; + +#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk, hw) static unsigned long cken_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct pxa_clk_cken *pclk = to_pxa_clk(hw); + struct pxa_clk *pclk = to_pxa_clk(hw); struct clk_fixed_factor *fix; if (!pclk->is_in_low_power || pclk->is_in_low_power()) @@ -48,7 +56,7 @@ static struct clk_ops cken_rate_ops = { static u8 cken_get_parent(struct clk_hw *hw) { - struct pxa_clk_cken *pclk = to_pxa_clk(hw); + struct pxa_clk *pclk = to_pxa_clk(hw); if (!pclk->is_in_low_power) return 0; @@ -69,23 +77,27 @@ void __init clkdev_pxa_register(int ckid, const char *con_id, clk_register_clkdev(clk, con_id, dev_id); } -int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks) +int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks) { int i; - struct pxa_clk_cken *pclk; + struct pxa_clk *pxa_clk; struct clk *clk; for (i = 0; i < nb_clks; i++) { - pclk = clks + i; - pclk->gate.lock = &lock; - clk = clk_register_composite(NULL, pclk->name, - pclk->parent_names, 2, - &pclk->hw, &cken_mux_ops, - &pclk->hw, &cken_rate_ops, - &pclk->gate.hw, &clk_gate_ops, - pclk->flags); - clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id, - clk); + pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL); + pxa_clk->is_in_low_power = clks[i].is_in_low_power; + pxa_clk->lp = clks[i].lp; + pxa_clk->hp = clks[i].hp; + pxa_clk->gate = clks[i].gate; + pxa_clk->gate.lock = &lock; + clk = clk_register_composite(NULL, clks[i].name, + clks[i].parent_names, 2, + &pxa_clk->hw, &cken_mux_ops, + &pxa_clk->hw, &cken_rate_ops, + &pxa_clk->gate.hw, &clk_gate_ops, + clks[i].flags); + clkdev_pxa_register(clks[i].ckid, clks[i].con_id, + clks[i].dev_id, clk); } return 0; } diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h index 5fe219d06b49..7b8d48e8e17e 100644 --- a/drivers/clk/pxa/clk-pxa.h +++ b/drivers/clk/pxa/clk-pxa.h @@ -25,7 +25,7 @@ static struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ - static struct clk *clk_register_ ## name(void) \ + static struct clk * __init clk_register_ ## name(void) \ { \ return clk_register_composite(NULL, clk_name, \ name ## _parents, \ @@ -40,7 +40,7 @@ static struct clk_ops name ## _rate_ops = { \ .recalc_rate = name ## _get_rate, \ }; \ - static struct clk *clk_register_ ## name(void) \ + static struct clk * __init clk_register_ ## name(void) \ { \ return clk_register_composite(NULL, clk_name, \ name ## _parents, \ @@ -66,7 +66,7 @@ * | Clock | --- | / div_hp | * +------------+ +-----------+ */ -struct pxa_clk_cken { +struct desc_clk_cken { struct clk_hw hw; int ckid; const char *name; @@ -102,6 +102,6 @@ static int dummy_clk_set_parent(struct clk_hw *hw, u8 index) extern void clkdev_pxa_register(int ckid, const char *con_id, const char *dev_id, struct clk *clk); -extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks); +extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); #endif diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index b345cc791e5d..24c1d2454c75 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -111,7 +111,7 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) -static struct pxa_clk_cken pxa27x_clocks[] = { +static struct desc_clk_cken pxa27x_clocks[] __initdata = { PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1), PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1), -- GitLab From 6f8a444aa6270e8d1aa4223ed856189108e1d401 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 7 Oct 2014 01:07:59 +0200 Subject: [PATCH 5080/9457] clk: pxa: keep clocks initialization separated per variant Have each pxa variant (pxa25x, pxa27x, pxa3xx) have its own device-tree clock initializing function, to be able to register its own specific core clocks. Apply that change specifically to pxa27x. Signed-off-by: Robert Jarzmik Signed-off-by: Michael Turquette --- drivers/clk/pxa/clk-pxa.c | 3 +-- drivers/clk/pxa/clk-pxa.h | 1 + drivers/clk/pxa/clk-pxa27x.c | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c index 994fd6fc266f..4e834753ab09 100644 --- a/drivers/clk/pxa/clk-pxa.c +++ b/drivers/clk/pxa/clk-pxa.c @@ -102,8 +102,7 @@ int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks) return 0; } -static void __init pxa_dt_clocks_init(struct device_node *np) +void __init clk_pxa_dt_common_init(struct device_node *np) { of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data); } -CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init); diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h index 7b8d48e8e17e..323965430111 100644 --- a/drivers/clk/pxa/clk-pxa.h +++ b/drivers/clk/pxa/clk-pxa.h @@ -103,5 +103,6 @@ static int dummy_clk_set_parent(struct clk_hw *hw, u8 index) extern void clkdev_pxa_register(int ckid, const char *con_id, const char *dev_id, struct clk *clk); extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); +void clk_pxa_dt_common_init(struct device_node *np); #endif diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 24c1d2454c75..bb8dfbc747ba 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -368,3 +368,10 @@ static int __init pxa27x_clocks_init(void) return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); } postcore_initcall(pxa27x_clocks_init); + +static void __init pxa27x_dt_clocks_init(struct device_node *np) +{ + pxa27x_clocks_init(); + clk_pxa_dt_common_init(np); +} +CLK_OF_DECLARE(pxa_clks, "marvell,pxa270-clocks", pxa27x_dt_clocks_init); -- GitLab From 6ac0483b35bfc7546398d1198b65ed7be17f3cc5 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 17 Nov 2014 09:59:28 -0800 Subject: [PATCH 5081/9457] drm/i915: Propagate invalid setcrtc cloning errors back to userspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When invalid cloning configurations were detected during modeset, we never copied the error code into the return value variable, leading us to return 0 (success) to userspace. This regression has been introduced in commit 50f5275698df4490046cc5b4ed2018abb642a803 Author: Jesse Barnes Date: Fri Nov 7 13:11:00 2014 -0800 drm/i915: use compute_config in set_config v4 Testcase: igt/kms_setmode Signed-off-by: Matt Roper Reviewed-by: Ville Syrjälä Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86226 Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2632f2adc319..f84738d5820e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11469,6 +11469,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set) &prepare_pipes, &disable_pipes); if (IS_ERR(pipe_config)) { + ret = PTR_ERR(pipe_config); goto fail; } else if (pipe_config) { if (to_intel_crtc(set->crtc)->new_config->has_audio != -- GitLab From 3fb1581ea1ab0aec6ac5430dc0e257a8c9b71680 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 14 Nov 2014 09:47:25 +0100 Subject: [PATCH 5082/9457] ARM: 8199/1: PM / Runtime: Add getter for querying the IRQ safe option v12 Add a simple getter pm_runtime_is_irq_safe() for querying whether runtime PM IRQ safe was set or not. Various bus drivers implementing runtime PM may use choose to suspend differently based on IRQ safeness status of child driver (e.g. do not unprepare the clock if IRQ safe is not set). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Ulf Hansson Acked-by: Rafael J. Wysocki Signed-off-by: Russell King --- Documentation/power/runtime_pm.txt | 4 ++++ include/linux/pm_runtime.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index f32ce5419573..397b81593142 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -468,6 +468,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: - set the power.irq_safe flag for the device, causing the runtime-PM callbacks to be invoked with interrupts off + bool pm_runtime_is_irq_safe(struct device *dev); + - return true if power.irq_safe flag was set for the device, causing + the runtime-PM callbacks to be invoked with interrupts off + void pm_runtime_mark_last_busy(struct device *dev); - set the power.last_busy field to the current time diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 367f49b9a1c9..44d74f0f182e 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -128,6 +128,11 @@ static inline void pm_runtime_mark_last_busy(struct device *dev) ACCESS_ONCE(dev->power.last_busy) = jiffies; } +static inline bool pm_runtime_is_irq_safe(struct device *dev) +{ + return dev->power.irq_safe; +} + #else /* !CONFIG_PM_RUNTIME */ static inline int __pm_runtime_idle(struct device *dev, int rpmflags) @@ -167,6 +172,7 @@ static inline bool pm_runtime_enabled(struct device *dev) { return false; } static inline void pm_runtime_no_callbacks(struct device *dev) {} static inline void pm_runtime_irq_safe(struct device *dev) {} +static inline bool pm_runtime_is_irq_safe(struct device *dev) { return false; } static inline bool pm_runtime_callbacks_present(struct device *dev) { return false; } static inline void pm_runtime_mark_last_busy(struct device *dev) {} -- GitLab From f560e3229564a673603541ebfb36118d7cd98038 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 14 Nov 2014 09:47:49 +0100 Subject: [PATCH 5083/9457] ARM: 8200/1: amba: Add helpers for (un)preparing AMBA clock v12 Add amba_pclk_prepare() and amba_pclk_unprepare() inline functions for handling the AMBA bus clock by device drivers. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Ulf Hansson Signed-off-by: Russell King --- include/linux/amba/bus.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index c324f5700d1a..ac02f9bd63dc 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -97,6 +97,16 @@ void amba_release_regions(struct amba_device *); #define amba_pclk_disable(d) \ do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) +static inline int amba_pclk_prepare(struct amba_device *dev) +{ + return clk_prepare(dev->pclk); +} + +static inline void amba_pclk_unprepare(struct amba_device *dev) +{ + clk_unprepare(dev->pclk); +} + /* Some drivers don't use the struct amba_device */ #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) -- GitLab From 5670c2a52f60418f67dd589e20d30600804fcfde Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 14 Nov 2014 09:48:27 +0100 Subject: [PATCH 5084/9457] ARM: 8201/1: amba: Don't unprepare the clocks if device driver wants IRQ safe runtime PM v12 The AMBA bus driver defines runtime Power Management functions which disable and unprepare AMBA bus clock. This is problematic for runtime PM because unpreparing a clock might sleep so it is not interrupt safe. However some drivers may want to implement runtime PM functions in interrupt-safe way (see pm_runtime_irq_safe()). In such case the AMBA bus driver should only disable/enable the clock in runtime suspend and resume callbacks. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Ulf Hansson Signed-off-by: Russell King --- drivers/amba/bus.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 47bbdc1b5be3..f8e3bb44938e 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -95,8 +95,12 @@ static int amba_pm_runtime_suspend(struct device *dev) struct amba_device *pcdev = to_amba_device(dev); int ret = pm_generic_runtime_suspend(dev); - if (ret == 0 && dev->driver) - clk_disable_unprepare(pcdev->pclk); + if (ret == 0 && dev->driver) { + if (pm_runtime_is_irq_safe(dev)) + clk_disable(pcdev->pclk); + else + clk_disable_unprepare(pcdev->pclk); + } return ret; } @@ -107,7 +111,10 @@ static int amba_pm_runtime_resume(struct device *dev) int ret; if (dev->driver) { - ret = clk_prepare_enable(pcdev->pclk); + if (pm_runtime_is_irq_safe(dev)) + ret = clk_enable(pcdev->pclk); + else + ret = clk_prepare_enable(pcdev->pclk); /* Failure is probably fatal to the system, but... */ if (ret) return ret; @@ -115,7 +122,7 @@ static int amba_pm_runtime_resume(struct device *dev) return pm_generic_runtime_resume(dev); } -#endif +#endif /* CONFIG_PM */ static const struct dev_pm_ops amba_pm = { .suspend = pm_generic_suspend, -- GitLab From ae43b3289186480f81c78bb63d788a85a3631f47 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 14 Nov 2014 09:48:57 +0100 Subject: [PATCH 5085/9457] ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12 This patch adds runtime PM support to pl330 DMA engine driver. The runtime power management for pl330 DMA driver allows gating of AMBA clock (PDMA) in FSYS clock domain, when the device is not processing any requests. This is necessary to enter low power modes on Exynos SoCs (e.g. LPA on Exynos4x12 or W-AFTR on Exynos3250). Runtime PM resuming of the device may happen in atomic context (during call device_issue_pending()) so pm_runtime_irq_safe() is used. This will lead only to disabling/enabling of the clock but this is sufficient for gating the clock and for reducing energy usage. Driver uses runtime PM callbacks from amba/bus.c driver only. Suggested-by: Bartlomiej Zolnierkiewicz Signed-off-by: Krzysztof Kozlowski Reviewed-by: Ulf Hansson Acked-by: Vinod Koul Signed-off-by: Russell King --- drivers/dma/pl330.c | 58 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 4839bfa74a10..39ea8d436b81 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "dmaengine.h" #define PL330_MAX_CHAN 8 @@ -265,6 +266,9 @@ static unsigned cmd_line; #define NR_DEFAULT_DESC 16 +/* Delay for runtime PM autosuspend, ms */ +#define PL330_AUTOSUSPEND_DELAY 20 + /* Populated by the PL330 core driver for DMA API driver's info */ struct pl330_config { u32 periph_id; @@ -1958,6 +1962,7 @@ static void pl330_tasklet(unsigned long data) struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; struct dma_pl330_desc *desc, *_dt; unsigned long flags; + bool power_down = false; spin_lock_irqsave(&pch->lock, flags); @@ -1972,10 +1977,17 @@ static void pl330_tasklet(unsigned long data) /* Try to submit a req imm. next to the last completed cookie */ fill_queue(pch); - /* Make sure the PL330 Channel thread is active */ - spin_lock(&pch->thread->dmac->lock); - _start(pch->thread); - spin_unlock(&pch->thread->dmac->lock); + if (list_empty(&pch->work_list)) { + spin_lock(&pch->thread->dmac->lock); + _stop(pch->thread); + spin_unlock(&pch->thread->dmac->lock); + power_down = true; + } else { + /* Make sure the PL330 Channel thread is active */ + spin_lock(&pch->thread->dmac->lock); + _start(pch->thread); + spin_unlock(&pch->thread->dmac->lock); + } while (!list_empty(&pch->completed_list)) { dma_async_tx_callback callback; @@ -1990,6 +2002,12 @@ static void pl330_tasklet(unsigned long data) if (pch->cyclic) { desc->status = PREP; list_move_tail(&desc->node, &pch->work_list); + if (power_down) { + spin_lock(&pch->thread->dmac->lock); + _start(pch->thread); + spin_unlock(&pch->thread->dmac->lock); + power_down = false; + } } else { desc->status = FREE; list_move_tail(&desc->node, &pch->dmac->desc_pool); @@ -2004,6 +2022,12 @@ static void pl330_tasklet(unsigned long data) } } spin_unlock_irqrestore(&pch->lock, flags); + + /* If work list empty, power down */ + if (power_down) { + pm_runtime_mark_last_busy(pch->dmac->ddma.dev); + pm_runtime_put_autosuspend(pch->dmac->ddma.dev); + } } bool pl330_filter(struct dma_chan *chan, void *param) @@ -2073,6 +2097,7 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned switch (cmd) { case DMA_TERMINATE_ALL: + pm_runtime_get_sync(pl330->ddma.dev); spin_lock_irqsave(&pch->lock, flags); spin_lock(&pl330->lock); @@ -2099,10 +2124,15 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned dma_cookie_complete(&desc->txd); } + if (!list_empty(&pch->work_list)) + pm_runtime_put(pl330->ddma.dev); + list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool); list_splice_tail_init(&pch->work_list, &pl330->desc_pool); list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); spin_unlock_irqrestore(&pch->lock, flags); + pm_runtime_mark_last_busy(pl330->ddma.dev); + pm_runtime_put_autosuspend(pl330->ddma.dev); break; case DMA_SLAVE_CONFIG: slave_config = (struct dma_slave_config *)arg; @@ -2138,6 +2168,7 @@ static void pl330_free_chan_resources(struct dma_chan *chan) tasklet_kill(&pch->task); + pm_runtime_get_sync(pch->dmac->ddma.dev); spin_lock_irqsave(&pch->lock, flags); pl330_release_channel(pch->thread); @@ -2147,6 +2178,8 @@ static void pl330_free_chan_resources(struct dma_chan *chan) list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); spin_unlock_irqrestore(&pch->lock, flags); + pm_runtime_mark_last_busy(pch->dmac->ddma.dev); + pm_runtime_put_autosuspend(pch->dmac->ddma.dev); } static enum dma_status @@ -2162,6 +2195,15 @@ static void pl330_issue_pending(struct dma_chan *chan) unsigned long flags; spin_lock_irqsave(&pch->lock, flags); + if (list_empty(&pch->work_list)) { + /* + * Warn on nothing pending. Empty submitted_list may + * break our pm_runtime usage counter as it is + * updated on work_list emptiness status. + */ + WARN_ON(list_empty(&pch->submitted_list)); + pm_runtime_get_sync(pch->dmac->ddma.dev); + } list_splice_tail_init(&pch->submitted_list, &pch->work_list); spin_unlock_irqrestore(&pch->lock, flags); @@ -2738,6 +2780,12 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan, pcfg->num_peri, pcfg->num_events); + pm_runtime_irq_safe(&adev->dev); + pm_runtime_use_autosuspend(&adev->dev); + pm_runtime_set_autosuspend_delay(&adev->dev, PL330_AUTOSUSPEND_DELAY); + pm_runtime_mark_last_busy(&adev->dev); + pm_runtime_put_autosuspend(&adev->dev); + return 0; probe_err3: /* Idle the DMAC */ @@ -2764,6 +2812,8 @@ static int pl330_remove(struct amba_device *adev) struct pl330_dmac *pl330 = amba_get_drvdata(adev); struct dma_pl330_chan *pch, *_p; + pm_runtime_get_noresume(pl330->ddma.dev); + if (adev->dev.of_node) of_dma_controller_free(adev->dev.of_node); -- GitLab From 325e188176681bdce0584154075e02c373794749 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 4 Nov 2014 15:22:49 -0800 Subject: [PATCH 5086/9457] ath9k: fix misc debugfs when not using chan context When channel-context is not enabled, all vifs belong to the first context, but it is not configured as 'assigned'. Fix misc debugfs file to print out info for non-assigned contexts, and also print whether ctx is assigned or not. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index db388405bf0c..3f21b1bbc52e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -828,13 +828,14 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, i = 0; ath_for_each_chanctx(sc, ctx) { - if (!ctx->assigned || list_empty(&ctx->vifs)) + if (list_empty(&ctx->vifs)) continue; ath9k_calculate_iter_data(sc, ctx, &iter_data); len += scnprintf(buf + len, sizeof(buf) - len, - "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i", - i++, iter_data.naps, iter_data.nstations, + "VIFS: CTX %i(%i) AP: %i STA: %i MESH: %i WDS: %i", + i++, (int)(ctx->assigned), iter_data.naps, + iter_data.nstations, iter_data.nmeshes, iter_data.nwds); len += scnprintf(buf + len, sizeof(buf) - len, " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", -- GitLab From 0013c7cebed676ea47d108176db138fe867ee401 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 5 Nov 2014 19:38:11 +0530 Subject: [PATCH 5087/9457] mwifiex: module load parameter for interface creation This patch adds module load parameter driver_mode for mwifiex which would enable driver to create AP or P2P client interface while loading module. driver_mode is bitmap of interface modes for station, AP and P2P client. Station interface is created by default and is unaffected by driver_mode parameter. Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 32 +++++++++++++++++++++++++++++ drivers/net/wireless/mwifiex/main.h | 5 +++++ 2 files changed, 37 insertions(+) diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 2a5a59bec124..2de8a6a84620 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -28,6 +28,11 @@ const char driver_version[] = "mwifiex " VERSION " (%s) "; static char *cal_data_cfg; module_param(cal_data_cfg, charp, 0); +static unsigned short driver_mode; +module_param(driver_mode, ushort, 0); +MODULE_PARM_DESC(driver_mode, + "station=0x1(default), ap-sta=0x3, station-p2p=0x5, ap-sta-p2p=0x7"); + /* * This function registers the device and performs all the necessary * initializations. @@ -449,6 +454,11 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto err_init_fw; } + if (driver_mode) { + driver_mode &= MWIFIEX_DRIVER_MODE_BITMASK; + driver_mode |= MWIFIEX_DRIVER_MODE_STA; + } + rtnl_lock(); /* Create station interface by default */ wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", @@ -458,6 +468,28 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) rtnl_unlock(); goto err_add_intf; } + + if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) { + wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", + NL80211_IFTYPE_AP, NULL, NULL); + if (IS_ERR(wdev)) { + dev_err(adapter->dev, "cannot create AP interface\n"); + rtnl_unlock(); + goto err_add_intf; + } + } + + if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) { + wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", + NL80211_IFTYPE_P2P_CLIENT, NULL, + NULL); + if (IS_ERR(wdev)) { + dev_err(adapter->dev, + "cannot create p2p client interface\n"); + rtnl_unlock(); + goto err_add_intf; + } + } rtnl_unlock(); mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index eced41ef1967..fa84888cf092 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -48,6 +48,11 @@ enum { MWIFIEX_SYNC_CMD }; +#define MWIFIEX_DRIVER_MODE_STA BIT(0) +#define MWIFIEX_DRIVER_MODE_UAP BIT(1) +#define MWIFIEX_DRIVER_MODE_P2P BIT(2) +#define MWIFIEX_DRIVER_MODE_BITMASK (BIT(0) | BIT(1) | BIT(2)) + #define MWIFIEX_MAX_AP 64 #define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) -- GitLab From d81f9a09bcd4fa3a4ba54bb02e94d2b6f30a889d Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 12 Nov 2014 06:19:48 +0800 Subject: [PATCH 5088/9457] ath9k: ath9k_op_ps_wakeup() can be static drivers/net/wireless/ath/ath9k/init.c:91:6: sparse: symbol 'ath9k_op_ps_wakeup' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/init.c:96:6: sparse: symbol 'ath9k_op_ps_restore' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/init.c:101:19: sparse: symbol 'ath9k_ps_ops' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 4124140a4d35..41736e5a49e0 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -88,17 +88,17 @@ static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { static void ath9k_deinit_softc(struct ath_softc *sc); -void ath9k_op_ps_wakeup(struct ath_common *common) +static void ath9k_op_ps_wakeup(struct ath_common *common) { ath9k_ps_wakeup((struct ath_softc *) common->priv); } -void ath9k_op_ps_restore(struct ath_common *common) +static void ath9k_op_ps_restore(struct ath_common *common) { ath9k_ps_restore((struct ath_softc *) common->priv); } -struct ath_ps_ops ath9k_ps_ops = { +static struct ath_ps_ops ath9k_ps_ops = { .wakeup = ath9k_op_ps_wakeup, .restore = ath9k_op_ps_restore, }; -- GitLab From 7d031552661ba61f9f258ec21272b4eafa9c21b4 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 12 Nov 2014 06:24:17 +0800 Subject: [PATCH 5089/9457] ath9k_htc: ath9k_htc_op_ps_wakeup() can be static drivers/net/wireless/ath/ath9k/htc_drv_init.c:56:6: sparse: symbol 'ath9k_htc_op_ps_wakeup' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/htc_drv_init.c:61:6: sparse: symbol 'ath9k_htc_op_ps_restore' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/htc_drv_init.c:66:19: sparse: symbol 'ath9k_htc_ps_ops' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index ad8f1dcc9cd5..e8fa9448da24 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -53,17 +53,17 @@ static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { }; #endif -void ath9k_htc_op_ps_wakeup(struct ath_common *common) +static void ath9k_htc_op_ps_wakeup(struct ath_common *common) { ath9k_htc_ps_wakeup((struct ath9k_htc_priv *) common->priv); } -void ath9k_htc_op_ps_restore(struct ath_common *common) +static void ath9k_htc_op_ps_restore(struct ath_common *common) { ath9k_htc_ps_restore((struct ath9k_htc_priv *) common->priv); } -struct ath_ps_ops ath9k_htc_ps_ops = { +static struct ath_ps_ops ath9k_htc_ps_ops = { .wakeup = ath9k_htc_op_ps_wakeup, .restore = ath9k_htc_op_ps_restore, }; -- GitLab From 2eaea3284b082271315be815b762fdd02b007c32 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 12 Nov 2014 08:32:08 +0100 Subject: [PATCH 5090/9457] ath9k: common-spectral: don't depend from ATH9K_DEBUGFS we can have here two variants. Add ATH9K_CMN_DEBUGFS y if ATH9K_CMN_DEBUGFS || ATH9K_HTC_DEBUGFS wich will add more configurations and testcases. Or remove ATH9K_HTC_DEBUGFS which need more time to be done. So, make common-spectral ignore ATH9K_DEBUGFS option for now. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common-spectral.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h index 214c3baf5023..82d9dd29652c 100644 --- a/drivers/net/wireless/ath/ath9k/common-spectral.h +++ b/drivers/net/wireless/ath/ath9k/common-spectral.h @@ -138,17 +138,7 @@ void ath9k_cmn_spectral_scan_trigger(struct ath_common *common, int ath9k_cmn_spectral_scan_config(struct ath_common *common, struct ath_spec_scan_priv *spec_priv, enum spectral_mode spectral_mode); - -#ifdef CONFIG_ATH9K_DEBUGFS int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr, struct ath_rx_status *rs, u64 tsf); -#else -static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, - struct ieee80211_hdr *hdr, - struct ath_rx_status *rs, u64 tsf) -{ - return 0; -} -#endif /* CONFIG_ATH9K_DEBUGFS */ #endif /* SPECTRAL_H */ -- GitLab From 4b870c26e082cc950d91e54acd265fd640b9a56d Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Wed, 12 Nov 2014 16:40:19 +0800 Subject: [PATCH 5091/9457] ath9k: fix the assignment of hw queues for mesh interface We need to assign the hw queues for mesh interface. Otherwise, we are not able to bring up the mesh interface due to the IEEE80211_INVAL_HW_QUEUE error. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1a88614eb73e..6aed6a236066 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1185,7 +1185,8 @@ static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, for (i = 0; i < IEEE80211_NUM_ACS; i++) vif->hw_queue[i] = i; - if (vif->type == NL80211_IFTYPE_AP) + if (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT) vif->cab_queue = hw->queues - 2; else vif->cab_queue = IEEE80211_INVAL_HW_QUEUE; -- GitLab From 9d31c1c76339695bfb0753a656dd98c78649478f Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:13 +0530 Subject: [PATCH 5092/9457] mwifiex: update rx packet descriptor structure to match FW RX packet descriptor structure has recently changed in FW. This patch updates rxpd accordingly. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 7f922a882c13..e095f371545a 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -584,6 +584,7 @@ struct rxpd { * [Bit 7] Reserved */ u8 ht_info; + u8 reserved[3]; u8 flags; } __packed; -- GitLab From 2848977f92ada21bcf2f450c87d42a786c78ada5 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:14 +0530 Subject: [PATCH 5093/9457] mwifiex: do not explicitly disable TDLS link during teardown When Teardown event from FW is indicated to userspace, userspace would trigger tdls_oper handler to disable TDLS link. We need not do this explicitly here. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_event.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index f1c240eca0cd..0efd6f0ffd38 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -163,9 +163,6 @@ static int mwifiex_parse_tdls_event(struct mwifiex_private *priv, NL80211_TDLS_TEARDOWN, le16_to_cpu(tdls_evt->u.reason_code), GFP_KERNEL); - ret = mwifiex_tdls_oper(priv, tdls_evt->peer_mac, - MWIFIEX_TDLS_DISABLE_LINK); - queue_work(adapter->workqueue, &adapter->main_work); break; default: break; -- GitLab From 16fa5e659f3c3b2a5edfd0a40fc8d0116d9cd52b Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:15 +0530 Subject: [PATCH 5094/9457] mwifiex: wmm support for TDLS link This patch adds WMM support for TDLS link. Patch add WMM info IE for TDLS setup request/response frames while WMM parameter for TDLS confirm frame. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/tdls.c | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index e2949077f5b5..93a492f5fa45 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -24,6 +24,7 @@ #define TDLS_REQ_FIX_LEN 6 #define TDLS_RESP_FIX_LEN 8 #define TDLS_CONFIRM_FIX_LEN 6 +#define MWIFIEX_TDLS_WMM_INFO_SIZE 7 static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv, const u8 *mac, u8 status) @@ -367,6 +368,55 @@ static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb) *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB; } +static void +mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb) +{ + struct ieee80211_wmm_param_ie *wmm; + u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00}; + u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00}; + u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00}; + u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00}; + + wmm = (void *)skb_put(skb, sizeof(*wmm)); + memset(wmm, 0, sizeof(*wmm)); + + wmm->element_id = WLAN_EID_VENDOR_SPECIFIC; + wmm->len = sizeof(*wmm) - 2; + wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */ + wmm->oui[1] = 0x50; + wmm->oui[2] = 0xf2; + wmm->oui_type = 2; /* WME */ + wmm->oui_subtype = 1; /* WME param */ + wmm->version = 1; /* WME ver */ + wmm->qos_info = 0; /* U-APSD not in use */ + + /* use default WMM AC parameters for TDLS link*/ + memcpy(&wmm->ac[0], ac_be, sizeof(ac_be)); + memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk)); + memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi)); + memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo)); +} + +static void +mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb, + u8 qosinfo) +{ + u8 *buf; + + buf = (void *)skb_put(skb, MWIFIEX_TDLS_WMM_INFO_SIZE + + sizeof(struct ieee_types_header)); + + *buf++ = WLAN_EID_VENDOR_SPECIFIC; + *buf++ = 7; /* len */ + *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */ + *buf++ = 0x50; + *buf++ = 0xf2; + *buf++ = 2; /* WME */ + *buf++ = 0; /* WME info */ + *buf++ = 1; /* WME ver */ + *buf++ = qosinfo; /* U-APSD no in use */ +} + static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, const u8 *peer, u8 action_code, u8 dialog_token, @@ -421,6 +471,7 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, mwifiex_tdls_add_ext_capab(priv, skb); mwifiex_tdls_add_qos_capab(skb); + mwifiex_add_wmm_info_ie(priv, skb, 0); break; case WLAN_TDLS_SETUP_RESPONSE: @@ -458,6 +509,7 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, mwifiex_tdls_add_ext_capab(priv, skb); mwifiex_tdls_add_qos_capab(skb); + mwifiex_add_wmm_info_ie(priv, skb, 0); break; case WLAN_TDLS_SETUP_CONFIRM: @@ -466,6 +518,8 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, skb_put(skb, sizeof(tf->u.setup_cfm)); tf->u.setup_cfm.status_code = cpu_to_le16(status_code); tf->u.setup_cfm.dialog_token = dialog_token; + + mwifiex_tdls_add_wmm_param_ie(priv, skb); if (priv->adapter->is_hw_11ac_capable) { ret = mwifiex_tdls_add_vht_oper(priv, peer, skb); if (ret) { @@ -544,6 +598,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, sizeof(struct ieee_types_bss_co_2040) + sizeof(struct ieee80211_ht_operation) + sizeof(struct ieee80211_tdls_lnkie) + + sizeof(struct ieee80211_wmm_param_ie) + extra_ies_len; if (priv->adapter->is_hw_11ac_capable) -- GitLab From 9927baa3c7244b1f80582fc7360a7662bcb648ba Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:16 +0530 Subject: [PATCH 5095/9457] mwifiex: add auto TDLS support This patch adds auto TDLS support to mwifiex. Auto TDLS functionality works as follows: 1. Whenever userspace application has triggered TDLS connection with any peer, driver would store this peer mac address details in its database. 2. After this driver whenever driver receives packet on direct link, it would store rssi and timestamp in peer information. 3. Whenever a packet is to be transmitted to non-AP peer in station mode, driver would check if TDLS link can be established by looking at peer RSSI information. Driver would initiate TDLS setup in such cases. 4. Periodic timer is used for updating peer information. 5. Auto TDLS peer list & timer are cleared during disconnection or driver unload. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 6 + drivers/net/wireless/mwifiex/decl.h | 5 + drivers/net/wireless/mwifiex/init.c | 6 + drivers/net/wireless/mwifiex/main.c | 7 + drivers/net/wireless/mwifiex/main.h | 31 ++- drivers/net/wireless/mwifiex/sta_event.c | 6 +- drivers/net/wireless/mwifiex/sta_rx.c | 3 + drivers/net/wireless/mwifiex/tdls.c | 233 +++++++++++++++++++++++ 8 files changed, 295 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index f63abfd8acd7..17f0ee02d6e7 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1806,6 +1806,10 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, dev_dbg(priv->adapter->dev, "info: associated to bssid %pM successfully\n", priv->cfg_bssid); + if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && + priv->adapter->auto_tdls && + priv->bss_type == MWIFIEX_BSS_TYPE_STA) + mwifiex_setup_auto_tdls_timer(priv); } else { dev_dbg(priv->adapter->dev, "info: association to bssid %pM failed\n", @@ -2677,11 +2681,13 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, dev_dbg(priv->adapter->dev, "Send TDLS Setup Request to %pM status_code=%d\n", peer, status_code); + mwifiex_add_auto_tdls_peer(priv, peer); ret = mwifiex_send_tdls_data_frame(priv, peer, action_code, dialog_token, status_code, extra_ies, extra_ies_len); break; case WLAN_TDLS_SETUP_RESPONSE: + mwifiex_add_auto_tdls_peer(priv, peer); dev_dbg(priv->adapter->dev, "Send TDLS Setup Response to %pM status_code=%d\n", peer, status_code); diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index f53e5b50d3d8..fc0b1ed80a6a 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -85,6 +85,11 @@ #define MWIFIEX_TDLS_CREATE_LINK 0x02 #define MWIFIEX_TDLS_CONFIG_LINK 0x03 +#define MWIFIEX_TDLS_RSSI_HIGH 50 +#define MWIFIEX_TDLS_RSSI_LOW 55 +#define MWIFIEX_TDLS_MAX_FAIL_COUNT 4 +#define MWIFIEX_AUTO_TDLS_IDLE_TIME 10 + enum mwifiex_bss_type { MWIFIEX_BSS_TYPE_STA = 0, MWIFIEX_BSS_TYPE_UAP = 1, diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index bd740b630b31..ee512425a938 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -137,6 +137,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv) priv->csa_expire_time = 0; priv->del_list_idx = 0; priv->hs2_enabled = false; + priv->check_tdls_tx = false; memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); return mwifiex_add_bss_prio_tbl(priv); @@ -248,6 +249,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->hw_dev_mcs_support = 0; adapter->sec_chan_offset = 0; adapter->adhoc_11n_enabled = false; + adapter->auto_tdls = false; mwifiex_wmm_init(adapter); @@ -366,6 +368,7 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) list_del(&priv->tx_ba_stream_tbl_ptr); list_del(&priv->rx_reorder_tbl_ptr); list_del(&priv->sta_list); + list_del(&priv->auto_tdls_list); } } } @@ -434,6 +437,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) spin_lock_init(&priv->wmm.ra_list_spinlock); spin_lock_init(&priv->curr_bcn_buf_lock); spin_lock_init(&priv->sta_list_spinlock); + spin_lock_init(&priv->auto_tdls_lock); } } @@ -465,6 +469,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); INIT_LIST_HEAD(&priv->sta_list); + INIT_LIST_HEAD(&priv->auto_tdls_list); skb_queue_head_init(&priv->tdls_txq); spin_lock_init(&priv->tx_ba_stream_tbl_lock); @@ -645,6 +650,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) if (adapter->priv[i]) { priv = adapter->priv[i]; + mwifiex_clean_auto_tdls(priv); mwifiex_clean_txrx(priv); mwifiex_delete_bss_prio_tbl(priv); } diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 2de8a6a84620..0e50120eb807 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -662,6 +662,13 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) */ __net_timestamp(skb); + if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && + priv->bss_type == MWIFIEX_BSS_TYPE_STA && + !ether_addr_equal_unaligned(priv->cfg_bssid, skb->data)) { + if (priv->adapter->auto_tdls && priv->check_tdls_tx) + mwifiex_tdls_check_tx(priv, skb); + } + mwifiex_queue_tx_pkt(priv, skb); return 0; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index fa84888cf092..51a67f34c8cb 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -506,8 +506,11 @@ struct mwifiex_private { struct mwifiex_wmm_desc wmm; atomic_t wmm_tx_pending[IEEE80211_NUM_ACS]; struct list_head sta_list; - /* spin lock for associated station list */ + /* spin lock for associated station/TDLS peers list */ spinlock_t sta_list_spinlock; + struct list_head auto_tdls_list; + /* spin lock for auto TDLS peer list */ + spinlock_t auto_tdls_lock; struct list_head tx_ba_stream_tbl_ptr; /* spin lock for tx_ba_stream_tbl_ptr queue */ spinlock_t tx_ba_stream_tbl_lock; @@ -572,6 +575,9 @@ struct mwifiex_private { bool hs2_enabled; struct station_parameters *sta_params; struct sk_buff_head tdls_txq; + u8 check_tdls_tx; + struct timer_list auto_tdls_timer; + bool auto_tdls_timer_active; }; enum mwifiex_ba_status { @@ -671,6 +677,17 @@ struct mwifiex_sta_node { struct mwifiex_tdls_capab tdls_cap; }; +struct mwifiex_auto_tdls_peer { + struct list_head list; + u8 mac_addr[ETH_ALEN]; + u8 tdls_status; + int rssi; + long rssi_jiffies; + u8 failure_count; + u8 do_discover; + u8 do_setup; +}; + struct mwifiex_if_ops { int (*init_if) (struct mwifiex_adapter *); void (*cleanup_if) (struct mwifiex_adapter *); @@ -848,6 +865,7 @@ struct mwifiex_adapter { struct mwifiex_chan_stats *chan_stats; u32 num_in_chan_stats; int survey_idx; + bool auto_tdls; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); @@ -1305,6 +1323,17 @@ u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, u32 pri_chan, u8 chan_bw); int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter); +int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb); +void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv); +void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, + const u8 *mac, u8 link_status); +void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, + u8 *mac, s8 snr, s8 nflr); +void mwifiex_check_auto_tdls(unsigned long context); +void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac); +void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv); +void mwifiex_clean_auto_tdls(struct mwifiex_private *priv); + #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); void mwifiex_debugfs_remove(void); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 0efd6f0ffd38..204ecc8faa5b 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -55,9 +55,13 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) priv->scan_block = false; if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) + ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) { mwifiex_disable_all_tdls_links(priv); + if (priv->adapter->auto_tdls) + mwifiex_clean_auto_tdls(priv); + } + /* Free Tx and Rx packets, report disconnect to upper layer */ mwifiex_clean_txrx(priv); diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 9ceb1dbe34c5..c2ad3b63ae70 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -232,6 +232,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, if (sta_ptr) sta_ptr->rx_seq[local_rx_pd->priority] = le16_to_cpu(local_rx_pd->seq_num); + mwifiex_auto_tdls_update_peer_signal(priv, ta, + local_rx_pd->snr, + local_rx_pd->nf); } } else { if (rx_pkt_type != PKT_TYPE_BAR) diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 93a492f5fa45..22884b429be7 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -1028,6 +1028,7 @@ mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) } mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); + mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP); memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN); tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK; return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER, @@ -1072,6 +1073,8 @@ mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq)); mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE); + mwifiex_auto_tdls_update_peer_status(priv, peer, + TDLS_SETUP_COMPLETE); } else { dev_dbg(priv->adapter->dev, "tdls: enable link %pM failed\n", peer); @@ -1085,6 +1088,8 @@ mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) mwifiex_del_sta_entry(priv, peer); } mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN); + mwifiex_auto_tdls_update_peer_status(priv, peer, + TDLS_NOT_SETUP); return -1; } @@ -1152,3 +1157,231 @@ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) mwifiex_del_all_sta_list(priv); } + +int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb) +{ + struct mwifiex_auto_tdls_peer *peer; + unsigned long flags; + u8 mac[ETH_ALEN]; + + ether_addr_copy(mac, skb->data); + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry(peer, &priv->auto_tdls_list, list) { + if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) { + if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && + peer->tdls_status == TDLS_NOT_SETUP && + (peer->failure_count < + MWIFIEX_TDLS_MAX_FAIL_COUNT)) { + peer->tdls_status = TDLS_SETUP_INPROGRESS; + dev_dbg(priv->adapter->dev, + "setup TDLS link, peer=%pM rssi=%d\n", + peer->mac_addr, peer->rssi); + + cfg80211_tdls_oper_request(priv->netdev, + peer->mac_addr, + NL80211_TDLS_SETUP, + 0, GFP_ATOMIC); + peer->do_setup = false; + priv->check_tdls_tx = false; + } else if (peer->failure_count < + MWIFIEX_TDLS_MAX_FAIL_COUNT && + peer->do_discover) { + mwifiex_send_tdls_data_frame(priv, + peer->mac_addr, + WLAN_TDLS_DISCOVERY_REQUEST, + 1, 0, NULL, 0); + peer->do_discover = false; + } + } + } + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); + + return 0; +} + +void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv) +{ + struct mwifiex_auto_tdls_peer *peer, *tmp_node; + unsigned long flags; + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) { + list_del(&peer->list); + kfree(peer); + } + + INIT_LIST_HEAD(&priv->auto_tdls_list); + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); + priv->check_tdls_tx = false; +} + +void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) +{ + struct mwifiex_auto_tdls_peer *tdls_peer; + unsigned long flags; + + if (!priv->adapter->auto_tdls) + return; + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { + if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) { + tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; + tdls_peer->rssi_jiffies = jiffies; + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); + return; + } + } + + /* create new TDLS peer */ + tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC); + if (tdls_peer) { + ether_addr_copy(tdls_peer->mac_addr, mac); + tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; + tdls_peer->rssi_jiffies = jiffies; + INIT_LIST_HEAD(&tdls_peer->list); + list_add_tail(&tdls_peer->list, &priv->auto_tdls_list); + dev_dbg(priv->adapter->dev, "Add auto TDLS peer= %pM to list\n", + mac); + } + + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); +} + +void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv, + const u8 *mac, u8 link_status) +{ + struct mwifiex_auto_tdls_peer *peer; + unsigned long flags; + + if (!priv->adapter->auto_tdls) + return; + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry(peer, &priv->auto_tdls_list, list) { + if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { + if ((link_status == TDLS_NOT_SETUP) && + (peer->tdls_status == TDLS_SETUP_INPROGRESS)) + peer->failure_count++; + else if (link_status == TDLS_SETUP_COMPLETE) + peer->failure_count = 0; + + peer->tdls_status = link_status; + break; + } + } + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); +} + +void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv, + u8 *mac, s8 snr, s8 nflr) +{ + struct mwifiex_auto_tdls_peer *peer; + unsigned long flags; + + if (!priv->adapter->auto_tdls) + return; + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry(peer, &priv->auto_tdls_list, list) { + if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) { + peer->rssi = nflr - snr; + peer->rssi_jiffies = jiffies; + break; + } + } + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); +} + +void mwifiex_check_auto_tdls(unsigned long context) +{ + struct mwifiex_private *priv = (struct mwifiex_private *)context; + struct mwifiex_auto_tdls_peer *tdls_peer; + unsigned long flags; + u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; + + if (WARN_ON_ONCE(!priv || !priv->adapter)) { + pr_err("mwifiex: %s: adapter or private structure is NULL\n", + __func__); + return; + } + + if (unlikely(!priv->adapter->auto_tdls)) + return; + + if (!priv->auto_tdls_timer_active) { + dev_dbg(priv->adapter->dev, + "auto TDLS timer inactive; return"); + return; + } + + priv->check_tdls_tx = false; + + if (list_empty(&priv->auto_tdls_list)) { + mod_timer(&priv->auto_tdls_timer, + jiffies + + msecs_to_jiffies(MWIFIEX_TIMER_10S)); + return; + } + + spin_lock_irqsave(&priv->auto_tdls_lock, flags); + list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) { + if ((jiffies - tdls_peer->rssi_jiffies) > + (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) { + tdls_peer->rssi = 0; + tdls_peer->do_discover = true; + priv->check_tdls_tx = true; + } + + if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) || + !tdls_peer->rssi) && + tdls_peer->tdls_status == TDLS_SETUP_COMPLETE) { + tdls_peer->tdls_status = TDLS_LINK_TEARDOWN; + dev_dbg(priv->adapter->dev, + "teardown TDLS link,peer=%pM rssi=%d\n", + tdls_peer->mac_addr, -tdls_peer->rssi); + tdls_peer->do_discover = true; + priv->check_tdls_tx = true; + cfg80211_tdls_oper_request(priv->netdev, + tdls_peer->mac_addr, + NL80211_TDLS_TEARDOWN, + reason, GFP_ATOMIC); + } else if (tdls_peer->rssi && + tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH && + tdls_peer->tdls_status == TDLS_NOT_SETUP && + tdls_peer->failure_count < + MWIFIEX_TDLS_MAX_FAIL_COUNT) { + priv->check_tdls_tx = true; + tdls_peer->do_setup = true; + dev_dbg(priv->adapter->dev, + "check TDLS with peer=%pM rssi=%d\n", + tdls_peer->mac_addr, -tdls_peer->rssi); + } + } + spin_unlock_irqrestore(&priv->auto_tdls_lock, flags); + + mod_timer(&priv->auto_tdls_timer, + jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); +} + +void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv) +{ + init_timer(&priv->auto_tdls_timer); + priv->auto_tdls_timer.function = mwifiex_check_auto_tdls; + priv->auto_tdls_timer.data = (unsigned long)priv; + priv->auto_tdls_timer_active = true; + mod_timer(&priv->auto_tdls_timer, + jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); +} + +void mwifiex_clean_auto_tdls(struct mwifiex_private *priv) +{ + if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && + priv->adapter->auto_tdls && + priv->bss_type == MWIFIEX_BSS_TYPE_STA) { + priv->auto_tdls_timer_active = false; + del_timer(&priv->auto_tdls_timer); + mwifiex_flush_auto_tdls_list(priv); + } +} -- GitLab From 72e5aa8d2a6dd9313fc0877ed9eb43398d18ac13 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:17 +0530 Subject: [PATCH 5096/9457] mwifiex: support for parsing TDLS discovery frames This patch adds support for parsing TDLS discovery frames. After parsing, we update peer RSSI information. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/util.c | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index ec79c49de097..a113ef8f0b8b 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -141,6 +141,38 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, return 0; } +static int +mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, + struct rxpd *rx_pd) +{ + u16 stype; + u8 category, action_code; + struct ieee80211_hdr *ieee_hdr = (void *)payload; + + stype = (cpu_to_le16(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); + + switch (stype) { + case IEEE80211_STYPE_ACTION: + category = *(payload + sizeof(struct ieee80211_hdr)); + action_code = *(payload + sizeof(struct ieee80211_hdr) + 1); + if (category == WLAN_CATEGORY_PUBLIC && + action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { + dev_dbg(priv->adapter->dev, + "TDLS discovery response %pM nf=%d, snr=%d\n", + ieee_hdr->addr2, rx_pd->nf, rx_pd->snr); + mwifiex_auto_tdls_update_peer_signal(priv, + ieee_hdr->addr2, + rx_pd->snr, + rx_pd->nf); + } + break; + default: + dev_dbg(priv->adapter->dev, + "unknown mgmt frame subytpe %#x\n", stype); + } + + return 0; +} /* * This function processes the received management packet and send it * to the kernel. @@ -151,6 +183,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, { struct rxpd *rx_pd; u16 pkt_len; + struct ieee80211_hdr *ieee_hdr; if (!skb) return -1; @@ -162,6 +195,11 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); + ieee_hdr = (void *)skb->data; + if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { + mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, + pkt_len, rx_pd); + } /* Remove address4 */ memmove(skb->data + sizeof(struct ieee80211_hdr_3addr), skb->data + sizeof(struct ieee80211_hdr), -- GitLab From 7bf165218b208f95565edfc15bffc5e384aae30f Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Thu, 13 Nov 2014 21:54:18 +0530 Subject: [PATCH 5097/9457] mwifiex: enable auto TDLS support for SD8887 Auto TDLS support is enabled per device. As of now add this feature only for SD8887. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 1 - drivers/net/wireless/mwifiex/sdio.c | 2 ++ drivers/net/wireless/mwifiex/sdio.h | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index ee512425a938..cc15ab81aa66 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -249,7 +249,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->hw_dev_mcs_support = 0; adapter->sec_chan_offset = 0; adapter->adhoc_11n_enabled = false; - adapter->auto_tdls = false; mwifiex_wmm_init(adapter); diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index b25766b43b9f..933dae137850 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -106,6 +106,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; card->supports_fw_dump = data->supports_fw_dump; + card->auto_tdls = data->auto_tdls; } sdio_claim_host(func); @@ -1880,6 +1881,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) return -1; } + adapter->auto_tdls = card->auto_tdls; return ret; } diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 20cd9adc98d3..54c07156dd78 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -246,6 +246,7 @@ struct sdio_mmc_card { u8 curr_wr_port; u8 *mp_regs; + u8 auto_tdls; struct mwifiex_sdio_mpa_tx mpa_tx; struct mwifiex_sdio_mpa_rx mpa_rx; @@ -262,6 +263,7 @@ struct mwifiex_sdio_device { u16 tx_buf_size; u32 mp_tx_agg_buf_size; u32 mp_rx_agg_buf_size; + u8 auto_tdls; }; static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = { @@ -387,6 +389,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .supports_fw_dump = false, + .auto_tdls = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { @@ -400,6 +403,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .supports_fw_dump = false, + .auto_tdls = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { @@ -413,6 +417,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, .supports_fw_dump = false, + .auto_tdls = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { @@ -426,6 +431,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, .supports_fw_dump = true, + .auto_tdls = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { @@ -439,6 +445,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, .supports_fw_dump = false, + .auto_tdls = true, }; /* -- GitLab From e6510b11209a4f4668924d9178ead304a692a9b2 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Sun, 16 Nov 2014 03:05:40 +0800 Subject: [PATCH 5098/9457] ath9k|ath9k_htc: Seperate the software crypto flag for Tx and Rx Use the sw_mgmt_crypto_tx flag to trigger the CCMP encryption for transmitted management frames to be done in software while the sw_mgmt_crypto_rx flag is used to trigger the CCMP decryption for received management frames to be done in software. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 9 ++++++--- drivers/net/wireless/ath/ath9k/hw.h | 3 ++- drivers/net/wireless/ath/ath9k/main.c | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index c6dd7f1fed65..eb62c58dd0f7 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -159,7 +159,7 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, if (test_bit(keyix, common->keymap)) rxs->flag |= RX_FLAG_DECRYPTED; } - if (ah->sw_mgmt_crypto && + if (ah->sw_mgmt_crypto_rx && (rxs->flag & RX_FLAG_DECRYPTED) && ieee80211_is_mgmt(fc)) /* Use software decrypt for management frames. */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 689ac998b87e..c7d12efaa86a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1447,7 +1447,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (priv->ah->sw_mgmt_crypto && + if (priv->ah->sw_mgmt_crypto_tx && key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index ee9fb52cec62..c1c2f2158b75 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1598,16 +1598,19 @@ static void ath9k_hw_init_mfp(struct ath_hw *ah) * frames when constructing CCMP AAD. */ REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, 0xc7ff); - ah->sw_mgmt_crypto = false; + ah->sw_mgmt_crypto_tx = false; + ah->sw_mgmt_crypto_rx = false; } else if (AR_SREV_9160_10_OR_LATER(ah)) { /* Disable hardware crypto for management frames */ REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); REG_SET_BIT(ah, AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); - ah->sw_mgmt_crypto = true; + ah->sw_mgmt_crypto_tx = true; + ah->sw_mgmt_crypto_rx = true; } else { - ah->sw_mgmt_crypto = true; + ah->sw_mgmt_crypto_tx = true; + ah->sw_mgmt_crypto_rx = true; } } diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e49721e85f6a..55ee0a5bc6fa 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -753,7 +753,8 @@ struct ath_hw { } eeprom; const struct eeprom_ops *eep_ops; - bool sw_mgmt_crypto; + bool sw_mgmt_crypto_tx; + bool sw_mgmt_crypto_rx; bool is_pciexpress; bool aspm_enabled; bool is_monitoring; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6aed6a236066..ca71f2fdc276 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1655,7 +1655,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (sc->sc_ah->sw_mgmt_crypto && + if (sc->sc_ah->sw_mgmt_crypto_tx && key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; -- GitLab From 60fc4962549cf3acad85b67c6934785afa014b8e Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Sun, 16 Nov 2014 03:05:41 +0800 Subject: [PATCH 5099/9457] ath9k_htc: Enable software crypto for mgmt frame in Tx for USB devices In secured mesh, the unicast mgmt frame is encrypted using the same key that used for encrypting the unicast data frame. This patch "ath9k_htc_firmware: fix the offset of CCMP header for mesh data frame" applied to open-ath9k-htc-firmware allows the ath9k_htc to be loaded without "nohwcrypt=1". Unfortunately, this is not working and we still need CCMP encryption of transmitted management frames to be done in software. So this patch allows the software encryption for transmitted management frame to be done in software but remain the hardware decryption for received management frame. This patch is tested with the following hardwares: - TP-Link TL-WN821N v3 802.11n [Atheros AR7010+AR9287] - AR9271 802.11n and managed to work with peer mesh STA equipped with ath9k. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c1c2f2158b75..fa9e5e998337 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1598,7 +1598,10 @@ static void ath9k_hw_init_mfp(struct ath_hw *ah) * frames when constructing CCMP AAD. */ REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, 0xc7ff); - ah->sw_mgmt_crypto_tx = false; + if (AR_SREV_9271(ah) || AR_DEVID_7010(ah)) + ah->sw_mgmt_crypto_tx = true; + else + ah->sw_mgmt_crypto_tx = false; ah->sw_mgmt_crypto_rx = false; } else if (AR_SREV_9160_10_OR_LATER(ah)) { /* Disable hardware crypto for management frames */ -- GitLab From 459b1ec62224cd1d1588551eb78b1b0d81205f31 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:00 +0530 Subject: [PATCH 5100/9457] ath9k: Update QCA953x initvals * Duplicates have been marked. * New initvals for 1.1 and 2.0 versions. * xPA support. * Fix for low power issue. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar953x_initvals.h | 498 ++++++++++++++++-- 1 file changed, 468 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h index 812a9d787bf3..159cc6fd2362 100644 --- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h @@ -20,6 +20,8 @@ #define qca953x_1p0_mac_postamble ar9300_2p2_mac_postamble +#define qca953x_1p0_soc_preamble ar955x_1p0_soc_preamble + #define qca953x_1p0_soc_postamble ar9300_2p2_soc_postamble #define qca953x_1p0_common_rx_gain_table ar9300Common_rx_gain_table_2p2 @@ -28,6 +30,10 @@ #define qca953x_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 +#define qca953x_1p0_common_wo_xlna_rx_gain_bounds ar955x_1p0_common_wo_xlna_rx_gain_bounds + +#define qca953x_1p0_common_rx_gain_bounds ar955x_1p0_common_rx_gain_bounds + static const u32 qca953x_1p0_mac_core[][2] = { /* Addr allmodes */ {0x00000008, 0x00000000}, @@ -490,35 +496,6 @@ static const u32 qca953x_1p0_radio_postamble[][5] = { {0x00016540, 0x10804008, 0x10804008, 0x50804000, 0x50804000}, }; -static const u32 qca953x_1p0_soc_preamble[][2] = { - /* Addr allmodes */ - {0x00007000, 0x00000000}, - {0x00007004, 0x00000000}, - {0x00007008, 0x00000000}, - {0x0000700c, 0x00000000}, - {0x0000701c, 0x00000000}, - {0x00007020, 0x00000000}, - {0x00007024, 0x00000000}, - {0x00007028, 0x00000000}, - {0x0000702c, 0x00000000}, - {0x00007030, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, - {0x00007048, 0x00000000}, -}; - -static const u32 qca953x_1p0_common_rx_gain_bounds[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302018, 0x50302018}, -}; - -static const u32 qca953x_1p0_common_wo_xlna_rx_gain_bounds[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, -}; - static const u32 qca953x_1p0_modes_xpa_tx_gain_table[][2] = { /* Addr allmodes */ {0x0000a2dc, 0xfffd5aaa}, @@ -715,8 +692,73 @@ static const u32 qca953x_1p1_modes_no_xpa_tx_gain_table[][2] = { {0x00016448, 0x6c927a70}, }; +static const u32 qca953x_1p1_modes_xpa_tx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a2dc, 0xfffb52aa}, + {0x0000a2e0, 0xfffd64cc}, + {0x0000a2e4, 0xfffe80f0}, + {0x0000a2e8, 0xffffff00}, + {0x0000a410, 0x000050d5}, + {0x0000a500, 0x00000000}, + {0x0000a504, 0x04000002}, + {0x0000a508, 0x08000004}, + {0x0000a50c, 0x0c000006}, + {0x0000a510, 0x1000000a}, + {0x0000a514, 0x1400000c}, + {0x0000a518, 0x1800000e}, + {0x0000a51c, 0x1c000048}, + {0x0000a520, 0x2000004a}, + {0x0000a524, 0x2400004c}, + {0x0000a528, 0x2800004e}, + {0x0000a52c, 0x2b00024a}, + {0x0000a530, 0x2f00024c}, + {0x0000a534, 0x3300024e}, + {0x0000a538, 0x36000668}, + {0x0000a53c, 0x38000669}, + {0x0000a540, 0x3a000868}, + {0x0000a544, 0x3d00086a}, + {0x0000a548, 0x4000086c}, + {0x0000a54c, 0x4200086e}, + {0x0000a550, 0x43000a6e}, + {0x0000a554, 0x43000a6e}, + {0x0000a558, 0x43000a6e}, + {0x0000a55c, 0x43000a6e}, + {0x0000a560, 0x43000a6e}, + {0x0000a564, 0x43000a6e}, + {0x0000a568, 0x43000a6e}, + {0x0000a56c, 0x43000a6e}, + {0x0000a570, 0x43000a6e}, + {0x0000a574, 0x43000a6e}, + {0x0000a578, 0x43000a6e}, + {0x0000a57c, 0x43000a6e}, + {0x0000a600, 0x00000000}, + {0x0000a604, 0x00000000}, + {0x0000a608, 0x00000000}, + {0x0000a60c, 0x03804000}, + {0x0000a610, 0x03804e01}, + {0x0000a614, 0x03804e01}, + {0x0000a618, 0x03804e01}, + {0x0000a61c, 0x04009002}, + {0x0000a620, 0x04009002}, + {0x0000a624, 0x04009002}, + {0x0000a628, 0x04009002}, + {0x0000a62c, 0x04009002}, + {0x0000a630, 0x04009002}, + {0x0000a634, 0x04009002}, + {0x0000a638, 0x04009002}, + {0x0000a63c, 0x04009002}, + {0x0000b2dc, 0xfffb52aa}, + {0x0000b2e0, 0xfffd64cc}, + {0x0000b2e4, 0xfffe80f0}, + {0x0000b2e8, 0xffffff00}, + {0x00016044, 0x024922db}, + {0x00016048, 0x6c927a70}, + {0x00016444, 0x024922db}, + {0x00016448, 0x6c927a70}, +}; + static const u32 qca953x_2p0_baseband_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00009800, 0xafe68e30}, {0x00009804, 0xfd14e000}, {0x00009808, 0x9c0a9f6b}, @@ -914,4 +956,400 @@ static const u32 qca953x_2p0_baseband_postamble[][5] = { {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, }; +static const u32 qca953x_2p0_common_wo_xlna_rx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 qca953x_2p0_common_wo_xlna_rx_gain_bounds[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, +}; + +static const u32 qca953x_2p0_modes_xpa_tx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a2dc, 0xfffb52aa}, + {0x0000a2e0, 0xfffd64cc}, + {0x0000a2e4, 0xfffe80f0}, + {0x0000a2e8, 0xffffff00}, + {0x0000a410, 0x000050d5}, + {0x0000a500, 0x00000000}, + {0x0000a504, 0x04000002}, + {0x0000a508, 0x08000004}, + {0x0000a50c, 0x0c000006}, + {0x0000a510, 0x1000000a}, + {0x0000a514, 0x1400000c}, + {0x0000a518, 0x1800000e}, + {0x0000a51c, 0x1c000048}, + {0x0000a520, 0x2000004a}, + {0x0000a524, 0x2400004c}, + {0x0000a528, 0x2800004e}, + {0x0000a52c, 0x2b00024a}, + {0x0000a530, 0x2f00024c}, + {0x0000a534, 0x3300024e}, + {0x0000a538, 0x36000668}, + {0x0000a53c, 0x38000669}, + {0x0000a540, 0x3a000868}, + {0x0000a544, 0x3d00086a}, + {0x0000a548, 0x4000086c}, + {0x0000a54c, 0x4200086e}, + {0x0000a550, 0x43000a6e}, + {0x0000a554, 0x43000a6e}, + {0x0000a558, 0x43000a6e}, + {0x0000a55c, 0x43000a6e}, + {0x0000a560, 0x43000a6e}, + {0x0000a564, 0x43000a6e}, + {0x0000a568, 0x43000a6e}, + {0x0000a56c, 0x43000a6e}, + {0x0000a570, 0x43000a6e}, + {0x0000a574, 0x43000a6e}, + {0x0000a578, 0x43000a6e}, + {0x0000a57c, 0x43000a6e}, + {0x0000a600, 0x00000000}, + {0x0000a604, 0x00000000}, + {0x0000a608, 0x00000000}, + {0x0000a60c, 0x03804000}, + {0x0000a610, 0x03804e01}, + {0x0000a614, 0x03804e01}, + {0x0000a618, 0x03804e01}, + {0x0000a61c, 0x04009002}, + {0x0000a620, 0x04009002}, + {0x0000a624, 0x04009002}, + {0x0000a628, 0x04009002}, + {0x0000a62c, 0x04009002}, + {0x0000a630, 0x04009002}, + {0x0000a634, 0x04009002}, + {0x0000a638, 0x04009002}, + {0x0000a63c, 0x04009002}, + {0x0000b2dc, 0xfffb52aa}, + {0x0000b2e0, 0xfffd64cc}, + {0x0000b2e4, 0xfffe80f0}, + {0x0000b2e8, 0xffffff00}, + {0x00016044, 0x024922db}, + {0x00016048, 0x6c927a70}, + {0x00016444, 0x024922db}, + {0x00016448, 0x6c927a70}, +}; + +static const u32 qca953x_2p0_modes_no_xpa_tx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a2dc, 0xffd5f552}, + {0x0000a2e0, 0xffe60664}, + {0x0000a2e4, 0xfff80780}, + {0x0000a2e8, 0xfffff800}, + {0x0000a410, 0x000050de}, + {0x0000a500, 0x00000061}, + {0x0000a504, 0x04000063}, + {0x0000a508, 0x08000065}, + {0x0000a50c, 0x0c000261}, + {0x0000a510, 0x10000263}, + {0x0000a514, 0x14000265}, + {0x0000a518, 0x18000482}, + {0x0000a51c, 0x1b000484}, + {0x0000a520, 0x1f000486}, + {0x0000a524, 0x240008c2}, + {0x0000a528, 0x28000cc1}, + {0x0000a52c, 0x2d000ce3}, + {0x0000a530, 0x31000ce5}, + {0x0000a534, 0x350010e5}, + {0x0000a538, 0x360012e5}, + {0x0000a53c, 0x380014e5}, + {0x0000a540, 0x3b0018e5}, + {0x0000a544, 0x3d001d04}, + {0x0000a548, 0x3e001d05}, + {0x0000a54c, 0x40001d07}, + {0x0000a550, 0x42001f27}, + {0x0000a554, 0x43001f67}, + {0x0000a558, 0x46001fe7}, + {0x0000a55c, 0x47001f2b}, + {0x0000a560, 0x49001f0d}, + {0x0000a564, 0x4b001ed2}, + {0x0000a568, 0x4c001ed4}, + {0x0000a56c, 0x4e001f15}, + {0x0000a570, 0x4f001ff6}, + {0x0000a574, 0x4f001ff6}, + {0x0000a578, 0x4f001ff6}, + {0x0000a57c, 0x4f001ff6}, + {0x0000a600, 0x00000000}, + {0x0000a604, 0x00000000}, + {0x0000a608, 0x00000000}, + {0x0000a60c, 0x00804201}, + {0x0000a610, 0x01008201}, + {0x0000a614, 0x0180c402}, + {0x0000a618, 0x0180c603}, + {0x0000a61c, 0x0180c603}, + {0x0000a620, 0x01c10603}, + {0x0000a624, 0x01c10704}, + {0x0000a628, 0x02c18b05}, + {0x0000a62c, 0x02c14c07}, + {0x0000a630, 0x01008704}, + {0x0000a634, 0x01c10402}, + {0x0000a638, 0x0301cc07}, + {0x0000a63c, 0x0301cc07}, + {0x0000b2dc, 0xffd5f552}, + {0x0000b2e0, 0xffe60664}, + {0x0000b2e4, 0xfff80780}, + {0x0000b2e8, 0xfffff800}, + {0x00016044, 0x049242db}, + {0x00016048, 0x6c927a70}, + {0x00016444, 0x049242db}, + {0x00016448, 0x6c927a70}, +}; + #endif /* INITVALS_953X_H */ -- GitLab From 46270d077a761e72fc6ea5ec5a76c5ef2e61782b Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Sun, 16 Nov 2014 06:11:01 +0530 Subject: [PATCH 5101/9457] ath9k: Use new QCA953x initvals This patch updates the initvals for QCA953x v1.1 and v2.0 Signed-off-by: Miaoqing Pan Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 51 +++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index cb09102245b2..06ad2172030e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -333,12 +333,29 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) qca953x_1p0_soc_preamble); INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], qca953x_1p0_soc_postamble); - INIT_INI_ARRAY(&ah->iniModesRxGain, - qca953x_1p0_common_wo_xlna_rx_gain_table); - INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, - qca953x_1p0_common_wo_xlna_rx_gain_bounds); - INIT_INI_ARRAY(&ah->iniModesTxGain, - qca953x_1p0_modes_no_xpa_tx_gain_table); + + if (AR_SREV_9531_20(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, + qca953x_2p0_common_wo_xlna_rx_gain_table); + INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, + qca953x_2p0_common_wo_xlna_rx_gain_bounds); + } else { + INIT_INI_ARRAY(&ah->iniModesRxGain, + qca953x_1p0_common_wo_xlna_rx_gain_table); + INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, + qca953x_1p0_common_wo_xlna_rx_gain_bounds); + } + + if (AR_SREV_9531_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_2p0_modes_no_xpa_tx_gain_table); + else if (AR_SREV_9531_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_1p1_modes_no_xpa_tx_gain_table); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_1p0_modes_no_xpa_tx_gain_table); + INIT_INI_ARRAY(&ah->iniModesFastClock, qca953x_1p0_modes_fast_clock); } else if (AR_SREV_9580(ah)) { @@ -518,9 +535,15 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) else if (AR_SREV_9550(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar955x_1p0_modes_xpa_tx_gain_table); - else if (AR_SREV_9531(ah)) + else if (AR_SREV_9531_10(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_1p0_modes_xpa_tx_gain_table); + else if (AR_SREV_9531_11(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, - qca953x_1p0_modes_xpa_tx_gain_table); + qca953x_1p1_modes_xpa_tx_gain_table); + else if (AR_SREV_9531_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_2p0_modes_xpa_tx_gain_table); else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9580_1p0_lowest_ob_db_tx_gain_table); @@ -562,7 +585,10 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar955x_1p0_modes_no_xpa_tx_gain_table); else if (AR_SREV_9531(ah)) { - if (AR_SREV_9531_11(ah)) + if (AR_SREV_9531_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + qca953x_2p0_modes_no_xpa_tx_gain_table); + else if (AR_SREV_9531_11(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, qca953x_1p1_modes_no_xpa_tx_gain_table); else @@ -789,11 +815,16 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) ar955x_1p0_common_wo_xlna_rx_gain_table); INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, ar955x_1p0_common_wo_xlna_rx_gain_bounds); - } else if (AR_SREV_9531(ah)) { + } else if (AR_SREV_9531_10(ah) || AR_SREV_9531_11(ah)) { INIT_INI_ARRAY(&ah->iniModesRxGain, qca953x_1p0_common_wo_xlna_rx_gain_table); INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, qca953x_1p0_common_wo_xlna_rx_gain_bounds); + } else if (AR_SREV_9531_20(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, + qca953x_2p0_common_wo_xlna_rx_gain_table); + INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, + qca953x_2p0_common_wo_xlna_rx_gain_bounds); } else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9580_1p0_wo_xlna_rx_gain_table); -- GitLab From aeeb2065794361f823e17a20af0db18b3a369845 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:02 +0530 Subject: [PATCH 5102/9457] ath9k: Fix LED configuration On some x86 platforms, the LED gpio is active high instead of active low. Identify such cards and modify the GPIO usage to make sure LED works properly. Cc: Russell Hu Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/gpio.c | 9 +++++++-- drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 3 +++ drivers/net/wireless/ath/ath9k/main.c | 6 ++++-- drivers/net/wireless/ath/ath9k/pci.c | 4 +++- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d5a2019921bd..0f6db12967d9 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -931,6 +931,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); #define ATH9K_PCI_AR9565_2ANT 0x0100 #define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 #define ATH9K_PCI_KILLER 0x0400 +#define ATH9K_PCI_LED_ACT_HI 0x0800 /* * Default cache line size, in bytes. diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index b1956bf6e01e..2fef7a480fec 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -25,7 +25,12 @@ static void ath_led_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); + u32 val = (brightness == LED_OFF); + + if (sc->sc_ah->config.led_active_high) + val = !val; + + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); } void ath_deinit_leds(struct ath_softc *sc) @@ -82,7 +87,7 @@ void ath_fill_led_pin(struct ath_softc *sc) ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); /* LED off, active low */ - ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1); } #endif diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 55ee0a5bc6fa..d2c044885aff 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -329,6 +329,7 @@ struct ath9k_ops_config { bool alt_mingainidx; bool no_pll_pwrsave; bool tx_gain_buffalo; + bool led_active_high; }; enum ath9k_int { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 41736e5a49e0..39157ca723d6 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -441,6 +441,9 @@ static void ath9k_init_pcoem_platform(struct ath_softc *sc) ah->config.no_pll_pwrsave = true; ath_info(common, "Disable PLL PowerSave\n"); } + + if (sc->driver_data & ATH9K_PCI_LED_ACT_HI) + ah->config.led_active_high = true; } static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ca71f2fdc276..5a2a8d288487 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -727,7 +727,8 @@ static int ath9k_start(struct ieee80211_hw *hw) if (ah->led_pin >= 0) { ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - ath9k_hw_set_gpio(ah, ah->led_pin, 0); + ath9k_hw_set_gpio(ah, ah->led_pin, + (ah->config.led_active_high) ? 1 : 0); } /* @@ -869,7 +870,8 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_lock_bh(&sc->sc_pcu_lock); if (ah->led_pin >= 0) { - ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_set_gpio(ah, ah->led_pin, + (ah->config.led_active_high) ? 0 : 1); ath9k_hw_cfg_gpio_input(ah, ah->led_pin); } diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index e3f60d5c5263..f009b5b57e5e 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -657,7 +657,9 @@ static const struct pci_device_id ath_pci_id_table[] = { 0x0036, PCI_VENDOR_ID_DELL, 0x020E), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + .driver_data = ATH9K_PCI_AR9565_2ANT | + ATH9K_PCI_BT_ANT_DIV | + ATH9K_PCI_LED_ACT_HI}, /* PCI-E AR9565 (WB335) */ { PCI_VDEVICE(ATHEROS, 0x0036), -- GitLab From f4c34af4fcb8d28547fb96512f2389d79992cfcd Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:03 +0530 Subject: [PATCH 5103/9457] ath9k: Enable TSF2 for generic HW timers The base TSF is used for HW timers 0..7, but chips in the AR9003 family and above can support more generic timers. To use them, however, a second HW TSF needs to be enabled. This patch allows usage of the extra timers by starting the second TSF properly. The extra set of HW timers is apparently also present in AR9287, but we enable it only for the AR9003 family. Cc: Kobi Cohen-Arazi Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 23 ++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/hw.h | 2 ++ drivers/net/wireless/ath/ath9k/reg.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fa9e5e998337..19004dd26092 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1960,6 +1960,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REGWRITE_BUFFER_FLUSH(ah); + ath9k_hw_gen_timer_start_tsf2(ah); + ath9k_hw_init_desc(ah); if (ath9k_hw_btcoex_is_enabled(ah)) @@ -2924,6 +2926,16 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_gettsf32); +void ath9k_hw_gen_timer_start_tsf2(struct ath_hw *ah) +{ + struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; + + if (timer_table->tsf2_enabled) { + REG_SET_BIT(ah, AR_DIRECT_CONNECT, AR_DC_AP_STA_EN); + REG_SET_BIT(ah, AR_RESET_TSF, AR_RESET_TSF2_ONCE); + } +} + struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, void (*trigger)(void *), void (*overflow)(void *), @@ -2934,7 +2946,11 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, struct ath_gen_timer *timer; if ((timer_index < AR_FIRST_NDP_TIMER) || - (timer_index >= ATH_MAX_GEN_TIMER)) + (timer_index >= ATH_MAX_GEN_TIMER)) + return NULL; + + if ((timer_index > AR_FIRST_NDP_TIMER) && + !AR_SREV_9300_20_OR_LATER(ah)) return NULL; timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); @@ -2948,6 +2964,11 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, timer->overflow = overflow; timer->arg = arg; + if ((timer_index > AR_FIRST_NDP_TIMER) && !timer_table->tsf2_enabled) { + timer_table->tsf2_enabled = true; + ath9k_hw_gen_timer_start_tsf2(ah); + } + return timer; } EXPORT_SYMBOL(ath_gen_timer_alloc); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index d2c044885aff..893584b37bca 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -525,6 +525,7 @@ struct ath_gen_timer { struct ath_gen_timer_table { struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER]; u16 timer_mask; + bool tsf2_enabled; }; struct ath_hw_antcomb_conf { @@ -1037,6 +1038,7 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, struct ath_gen_timer *timer, u32 timer_next, u32 timer_period); +void ath9k_hw_gen_timer_start_tsf2(struct ath_hw *ah); void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer); void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 1c0b1c1c5350..ced36b475acc 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1605,6 +1605,7 @@ enum { #define AR_RESET_TSF 0x8020 #define AR_RESET_TSF_ONCE 0x01000000 +#define AR_RESET_TSF2_ONCE 0x02000000 #define AR_MAX_CFP_DUR 0x8038 #define AR_CFP_VAL 0x0000FFFF @@ -1966,6 +1967,8 @@ enum { #define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 #define AR_MAC_PCU_GEN_TIMER_TSF_SEL 0x83d8 +#define AR_DIRECT_CONNECT 0x83a0 +#define AR_DC_AP_STA_EN 0x00000001 #define AR_AES_MUTE_MASK0 0x805c #define AR_AES_MUTE_MASK0_FC 0x0000FFFF -- GitLab From ee79ccd9ea8617220783ace007d722ed3815e00f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:04 +0530 Subject: [PATCH 5104/9457] ath9k: Store the chip chainmask in HW capabilities Cc: Miaoqing Pan Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 20 ++++++++++---------- drivers/net/wireless/ath/ath9k/hw.h | 1 + 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 19004dd26092..fbc78d80c559 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2341,7 +2341,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); - unsigned int chip_chainmask; u16 eeval; u8 ant_div_ctl1, tx_chainmask, rx_chainmask; @@ -2385,15 +2384,16 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) AR_SREV_9285(ah) || AR_SREV_9330(ah) || AR_SREV_9565(ah)) - chip_chainmask = 1; - else if (AR_SREV_9462(ah)) - chip_chainmask = 3; + pCap->chip_chainmask = 1; else if (!AR_SREV_9280_20_OR_LATER(ah)) - chip_chainmask = 7; - else if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9340(ah)) - chip_chainmask = 3; + pCap->chip_chainmask = 7; + else if (!AR_SREV_9300_20_OR_LATER(ah) || + AR_SREV_9340(ah) || + AR_SREV_9462(ah) || + AR_SREV_9531(ah)) + pCap->chip_chainmask = 3; else - chip_chainmask = 7; + pCap->chip_chainmask = 7; pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); /* @@ -2411,8 +2411,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) /* Use rx_chainmask from EEPROM. */ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); - pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask); - pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask); + pCap->tx_chainmask = fixup_chainmask(pCap->chip_chainmask, pCap->tx_chainmask); + pCap->rx_chainmask = fixup_chainmask(pCap->chip_chainmask, pCap->rx_chainmask); ah->txchainmask = pCap->tx_chainmask; ah->rxchainmask = pCap->rx_chainmask; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 893584b37bca..4cf9e0ac0743 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -276,6 +276,7 @@ struct ath9k_hw_capabilities { u16 rts_aggr_limit; u8 tx_chainmask; u8 rx_chainmask; + u8 chip_chainmask; u8 max_txchains; u8 max_rxchains; u8 num_gpio_pins; -- GitLab From 89b6e35c2032d74f51333fbf3635d980b3311c68 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:05 +0530 Subject: [PATCH 5105/9457] ath9k: Fix thermometer programming The registers that control the on-chip thermometer need to be programmed based on the chainmask that the solution supports, not the chainmask that is present in the eeprom. Cc: Miaoqing Pan Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 80c6eacbda53..e726e405152c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4079,27 +4079,28 @@ static int ar9003_hw_get_thermometer(struct ath_hw *ah) static void ar9003_hw_thermometer_apply(struct ath_hw *ah) { + struct ath9k_hw_capabilities *pCap = &ah->caps; int thermometer = ar9003_hw_get_thermometer(ah); u8 therm_on = (thermometer < 0) ? 0 : 1; REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); - if (ah->caps.tx_chainmask & BIT(1)) + if (pCap->chip_chainmask & BIT(1)) REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); - if (ah->caps.tx_chainmask & BIT(2)) + if (pCap->chip_chainmask & BIT(2)) REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); therm_on = (thermometer < 0) ? 0 : (thermometer == 0); REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); - if (ah->caps.tx_chainmask & BIT(1)) { + if (pCap->chip_chainmask & BIT(1)) { therm_on = (thermometer < 0) ? 0 : (thermometer == 1); REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); } - if (ah->caps.tx_chainmask & BIT(2)) { + if (pCap->chip_chainmask & BIT(2)) { therm_on = (thermometer < 0) ? 0 : (thermometer == 2); REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); -- GitLab From e21a1d8b2b92e78fca0b4ee48681aa03dd671f88 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:06 +0530 Subject: [PATCH 5106/9457] ath9k: Clear offchannel state properly When a pending roc or scan operation is cancelled, the offchannel operation is cleared, but the offchannel state in the main scheduler is not cleared. This causes problems since an active GO will try to process a stale offchannel request that was deferred earlier. Fix this by clearing the state when there is no pending offchannel (roc/scan) operation. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 1dadf6d77a82..ee76682cc058 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -900,6 +900,11 @@ void ath_offchannel_next(struct ath_softc *sc) sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); } else { + spin_lock_bh(&sc->chan_lock); + sc->sched.offchannel_pending = false; + sc->sched.wait_switch = false; + spin_unlock_bh(&sc->chan_lock); + ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false), NULL); sc->offchannel.state = ATH_OFFCHANNEL_IDLE; -- GitLab From 6185672abad996fa520b0b4c77c30258634ee07f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:07 +0530 Subject: [PATCH 5107/9457] ath9k: Cancel pending offchannel operations This patch makes sure that pending roc/scan operations are cancelled properly when a new context is assigned/unassigned. The flush_work() call to flush out any scheduled channel context work is removed, instead, sc->mutex is dropped to allow any pending work to get a chance to complete by the channel scheduler. Also, increase the timeout to allow a switch to an active GO. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 43 +++++++++++++++++++-------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5a2a8d288487..a6cb15c96052 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2196,6 +2196,28 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT +static void ath9k_cancel_pending_offchannel(struct ath_softc *sc) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + if (sc->offchannel.roc_vif) { + ath_dbg(common, CHAN_CTX, + "%s: Aborting RoC\n", __func__); + + del_timer_sync(&sc->offchannel.timer); + if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START) + ath_roc_complete(sc, true); + } + + if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { + ath_dbg(common, CHAN_CTX, + "%s: Aborting HW scan\n", __func__); + + del_timer_sync(&sc->offchannel.timer); + ath_scan_complete(sc, true); + } +} + static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *hw_req) { @@ -2382,6 +2404,8 @@ static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw, struct ath_chanctx *ctx = ath_chanctx_get(conf); int i; + ath9k_cancel_pending_offchannel(sc); + mutex_lock(&sc->mutex); ath_dbg(common, CHAN_CTX, @@ -2411,6 +2435,8 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ath_chanctx *ctx = ath_chanctx_get(conf); int ac; + ath9k_cancel_pending_offchannel(sc); + mutex_lock(&sc->mutex); ath_dbg(common, CHAN_CTX, @@ -2456,18 +2482,7 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, if (!changed) goto out; - if (test_bit(ATH_OP_SCANNING, &common->op_flags)) { - ath_dbg(common, CHAN_CTX, - "%s: Aborting HW scan\n", __func__); - - mutex_unlock(&sc->mutex); - - del_timer_sync(&sc->offchannel.timer); - ath_scan_complete(sc, true); - flush_work(&sc->chanctx_work); - - mutex_lock(&sc->mutex); - } + ath9k_cancel_pending_offchannel(sc); go_ctx = ath_is_go_chanctx_present(sc); @@ -2482,13 +2497,15 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, beacon_int = TU_TO_USEC(cur_conf->beacon_interval); spin_unlock_bh(&sc->chan_lock); - timeout = usecs_to_jiffies(beacon_int); + timeout = usecs_to_jiffies(beacon_int * 2); init_completion(&sc->go_beacon); + mutex_unlock(&sc->mutex); if (wait_for_completion_timeout(&sc->go_beacon, timeout) == 0) ath_dbg(common, CHAN_CTX, "Failed to send new NoA\n"); + mutex_lock(&sc->mutex); } ath_dbg(common, CHAN_CTX, -- GitLab From 2c3634a8d4c66f743d11dab03d0e66d77b6aac05 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:08 +0530 Subject: [PATCH 5108/9457] ath9k: Handle failure to send NoA If for some reason a beacon with a new NoA is not sent out, then reset the mgd_prepare_tx flag. Not doing this will result in a situation where a GO will send a new NoA when it shouldn't. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a6cb15c96052..5f16630f26ce 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2501,10 +2501,17 @@ static void ath9k_mgd_prepare_tx(struct ieee80211_hw *hw, init_completion(&sc->go_beacon); mutex_unlock(&sc->mutex); + if (wait_for_completion_timeout(&sc->go_beacon, - timeout) == 0) + timeout) == 0) { ath_dbg(common, CHAN_CTX, "Failed to send new NoA\n"); + + spin_lock_bh(&sc->chan_lock); + sc->sched.mgd_prepare_tx = false; + spin_unlock_bh(&sc->chan_lock); + } + mutex_lock(&sc->mutex); } -- GitLab From d9092c9873739429c9e97c4bc21ead9af2fb6aa1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:09 +0530 Subject: [PATCH 5109/9457] ath9k: Adjust tbtt delta properly In a GO/STA setup, when we switch to the STA context, the channel context timer is scheduled with a period of half the beacon interval. If a beacon is received in this duration, the timer is adjusted to accommodate TSF sync done by the HW. But, if the actual channel switch is delayed for some reason, we end up rearming the timer every time a new beacon is received. Avoid this by doing the adjustment only once. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/channel.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 0f6db12967d9..abe8bd6b972d 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -381,6 +381,7 @@ enum ath_chanctx_state { struct ath_chanctx_sched { bool beacon_pending; + bool beacon_adjust; bool offchannel_pending; bool wait_switch; bool force_noa_update; diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index ee76682cc058..99425fe13055 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -659,6 +659,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, sc->sched.beacon_miss = 0; if (sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE || + !sc->sched.beacon_adjust || !sc->cur_chan->tsf_val) break; @@ -672,7 +673,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL); tsf_time += ath9k_hw_gettsf32(ah); - + sc->sched.beacon_adjust = false; ath_chanctx_setup_timer(sc, tsf_time); break; case ATH_CHANCTX_EVENT_AUTHORIZED: @@ -717,6 +718,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, ath_chanctx_setup_timer(sc, tsf_time); sc->sched.beacon_pending = true; + sc->sched.beacon_adjust = true; break; case ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL: if (sc->cur_chan == &sc->offchannel.chan || -- GitLab From 47b6308b643302e642ca2a5cb6470926f7e1c428 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 16 Nov 2014 06:11:10 +0530 Subject: [PATCH 5110/9457] ath9k: Move roc completion to the offchannel timer Currently, when a roc period expires, the offchannel timer calls ieee80211_remain_on_channel_expired(), but the roc state is cleared only when the queued work to switch to the operating channel gets a chance to run. This race is a problem because mac80211 can issue a new roc request in this window. To avoid this, handle roc completion in the offchannel timer itself. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/channel.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 99425fe13055..794d52016437 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -926,8 +926,7 @@ void ath_roc_complete(struct ath_softc *sc, bool abort) sc->offchannel.roc_vif = NULL; sc->offchannel.roc_chan = NULL; - if (abort) - ieee80211_remain_on_channel_expired(sc->hw); + ieee80211_remain_on_channel_expired(sc->hw); ath_offchannel_next(sc); ath9k_ps_restore(sc); } @@ -1058,10 +1057,8 @@ static void ath_offchannel_timer(unsigned long data) break; case ATH_OFFCHANNEL_ROC_START: case ATH_OFFCHANNEL_ROC_WAIT: - ctx = ath_chanctx_get_oper_chan(sc, false); sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE; - ieee80211_remain_on_channel_expired(sc->hw); - ath_chanctx_switch(sc, ctx, NULL); + ath_roc_complete(sc, false); break; default: break; @@ -1191,7 +1188,6 @@ static void ath_offchannel_channel_change(struct ath_softc *sc) ieee80211_ready_on_channel(sc->hw); break; case ATH_OFFCHANNEL_ROC_DONE: - ath_roc_complete(sc, false); break; default: break; -- GitLab From 09415fa2c58b61ac766816e914ef5872011b4861 Mon Sep 17 00:00:00 2001 From: Yalin Wang Date: Thu, 6 Nov 2014 03:40:07 +0100 Subject: [PATCH 5111/9457] ARM: 8194/1: remove clear_thread_flag(TIF_UPROBE) This patch remove clear_thread_flag(TIF_UPROBE) in do_work_pending(), because uprobe_notify_resume() have do this. Signed-off-by: Yalin Wang Signed-off-by: Russell King --- arch/arm/kernel/signal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index bd1983437205..8aa6f1b87c9e 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -592,7 +592,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) } syscall = 0; } else if (thread_flags & _TIF_UPROBE) { - clear_thread_flag(TIF_UPROBE); uprobe_notify_resume(regs); } else { clear_thread_flag(TIF_NOTIFY_RESUME); -- GitLab From 1ca8bf6f7ba581d8b47144ff5a558e17fba3190d Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Mon, 10 Nov 2014 21:56:42 +0100 Subject: [PATCH 5112/9457] ARM: 8195/1: vfp: Bounce undefined instructions in vectored mode Certain ARM CPU implementations (e.g. Cortex-A15) may not raise a floating- point exception whenever deprecated short-vector VFP instructions are executed. Instead these instructions are treated as UNALLOCATED. Change the VFP exception handling code to emulate short-vector instructions even if FPEXC exception bits are not set. Signed-off-by: Stepan Moskovchenko Tested-by: Will Deacon Tested-by: Rob Clark Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/vfp/vfphw.S | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index cda654cbf2c2..f74a8f7e5f84 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -197,6 +197,12 @@ look_for_VFP_exceptions: tst r5, #FPSCR_IXE bne process_exception + tst r5, #FPSCR_LENGTH_MASK + beq skip + orr r1, r1, #FPEXC_DEX + b process_exception +skip: + @ Fall into hand on to next handler - appropriate coproc instr @ not recognised by VFP -- GitLab From 0288d7183c41c0192d2963d44590f346f4aee917 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Mon, 17 Nov 2014 15:51:01 -0500 Subject: [PATCH 5113/9457] audit: convert status version to a feature bitmap The version field defined in the audit status structure was found to have limitations in terms of its expressibility of features supported. This is distict from the get/set features call to be able to command those features that are present. Converting this field from a version number to a feature bitmap will allow distributions to selectively backport and support certain features and will allow upstream to be able to deprecate features in the future. It will allow userspace clients to first query the kernel for which features are actually present and supported. Currently, EINVAL is returned rather than EOPNOTSUP, which isn't helpful in determining if there was an error in the command, or if it simply isn't supported yet. Past features are not represented by this bitmap, but their use may be converted to EOPNOTSUP if needed in the future. Since "version" is too generic to convert with a #define, use a union in the struct status, introducing the member "feature_bitmap" unionized with "version". Convert existing AUDIT_VERSION_* macros over to AUDIT_FEATURE_BITMAP* counterparts, leaving the former for backwards compatibility. Signed-off-by: Richard Guy Briggs [PM: minor whitespace tweaks] Signed-off-by: Paul Moore --- include/uapi/linux/audit.h | 17 +++++++++++++---- kernel/audit.c | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 4d100c841c80..2ccf19e06e15 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -322,9 +322,15 @@ enum { #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 -#define AUDIT_VERSION_BACKLOG_LIMIT 1 -#define AUDIT_VERSION_BACKLOG_WAIT_TIME 2 -#define AUDIT_VERSION_LATEST AUDIT_VERSION_BACKLOG_WAIT_TIME +#define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001 +#define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002 +#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ + AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME) + +/* deprecated: AUDIT_VERSION_* */ +#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL +#define AUDIT_VERSION_BACKLOG_LIMIT AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT +#define AUDIT_VERSION_BACKLOG_WAIT_TIME AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME /* Failure-to-log actions */ #define AUDIT_FAIL_SILENT 0 @@ -403,7 +409,10 @@ struct audit_status { __u32 backlog_limit; /* waiting messages limit */ __u32 lost; /* messages lost */ __u32 backlog; /* messages waiting in queue */ - __u32 version; /* audit api version number */ + union { + __u32 version; /* deprecated: audit api version num */ + __u32 feature_bitmap; /* bitmap of kernel audit features */ + }; __u32 backlog_wait_time;/* message queue wait timeout */ }; diff --git a/kernel/audit.c b/kernel/audit.c index 53bb39bf79e2..7b83c557aee6 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -842,7 +842,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) s.backlog_limit = audit_backlog_limit; s.lost = atomic_read(&audit_lost); s.backlog = skb_queue_len(&audit_skb_queue); - s.version = AUDIT_VERSION_LATEST; + s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL; s.backlog_wait_time = audit_backlog_wait_time; audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s)); break; -- GitLab From 86ae04b174152147052adec7b95dba0c9cd7dff0 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Mon, 17 Nov 2014 10:18:11 +0800 Subject: [PATCH 5114/9457] ASoC: rt5677: Modify the default value of the MX-8E[4] for ASRC function Modify the default value of the MX-8E[4] to 1 for ASRC function. It could prevent the pop noise with ASRC function. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 5d317c68ca4e..9ae2e8468006 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -55,7 +55,8 @@ static const struct regmap_range_cfg rt5677_ranges[] = { }; static const struct reg_default init_list[] = { - {RT5677_PR_BASE + 0x3d, 0x364d}, + {RT5677_ASRC_12, 0x0018}, + {RT5677_PR_BASE + 0x3d, 0x364d}, {RT5677_PR_BASE + 0x17, 0x4fc0}, {RT5677_PR_BASE + 0x13, 0x0312}, {RT5677_PR_BASE + 0x1e, 0x0000}, @@ -173,7 +174,7 @@ static const struct reg_default rt5677_reg[] = { {RT5677_ASRC_9 , 0x0000}, {RT5677_ASRC_10 , 0x0000}, {RT5677_ASRC_11 , 0x0000}, - {RT5677_ASRC_12 , 0x0008}, + {RT5677_ASRC_12 , 0x0018}, {RT5677_ASRC_13 , 0x0000}, {RT5677_ASRC_14 , 0x0000}, {RT5677_ASRC_15 , 0x0000}, -- GitLab From 7e35ac81598c9a98dee4faa77b988c4ea919d1cd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 17 Nov 2014 00:16:19 -0200 Subject: [PATCH 5115/9457] ASoC: fsl_ssi: Remove comment about SSI running only in slave mode Current driver can also run in I2S master mode, so remove the old comment. Signed-off-by: Fabio Estevam Acked-by: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e6955170dc42..bc19849053a5 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -67,8 +67,6 @@ /** * FSLSSI_I2S_FORMATS: audio formats supported by the SSI * - * This driver currently only supports the SSI running in I2S slave mode. - * * The SSI has a limitation in that the samples must be in the same byte * order as the host CPU. This is because when multiple bytes are written * to the STX register, the bytes and bits must be written in the same -- GitLab From bb66f2dc197d9cf1daaa82609302204d71c70389 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 17 Nov 2014 14:05:27 +0100 Subject: [PATCH 5116/9457] ASoC: omap-mcbsp: Deletion of an unnecessary check before the function call "kfree" The kfree() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/mcbsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 86c75384c3c8..68a125205375 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -621,8 +621,7 @@ void omap_mcbsp_free(struct omap_mcbsp *mcbsp) mcbsp->reg_cache = NULL; spin_unlock(&mcbsp->lock); - if (reg_cache) - kfree(reg_cache); + kfree(reg_cache); } /* -- GitLab From 00e7c295968d74f4dbb00aef8334fafe788e3c89 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 14 Nov 2014 08:41:32 +0100 Subject: [PATCH 5117/9457] PM / Domains: Move struct pm_domain_data to pm_domain.h The definition of the struct pm_domain_data better belongs in the header for the PM domains, let's move it there. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 6 +----- include/linux/pm_domain.h | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/linux/pm.h b/include/linux/pm.h index 383fd68aaee1..45e3e78c1e3a 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -538,11 +538,7 @@ enum rpm_request { }; struct wakeup_source; - -struct pm_domain_data { - struct list_head list_node; - struct device *dev; -}; +struct pm_domain_data; struct pm_subsys_data { spinlock_t lock; diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 73e938b7e937..86689b59ce5b 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -98,6 +98,11 @@ struct gpd_timing_data { bool cached_stop_ok; }; +struct pm_domain_data { + struct list_head list_node; + struct device *dev; +}; + struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; -- GitLab From 99a33ffcf6b431e49cd04097b85f48aa17499a6a Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 14 Nov 2014 17:44:07 +0800 Subject: [PATCH 5118/9457] ACPI / Kconfig: Remove redundant depends on ACPI Since config ACPI_REDUCED_HARDWARE_ONLY is already depended on ACPI (inside if ACPI / endif), so depdens on ACPI is redundant, remove it and fix the minor syntax problem also. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b23fe37f67c0..79078b8f5697 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -360,15 +360,14 @@ config ACPI_BGRT config ACPI_REDUCED_HARDWARE_ONLY bool "Hardware-reduced ACPI support only" if EXPERT def_bool n - depends on ACPI help - This config item changes the way the ACPI code is built. When this - option is selected, the kernel will use a specialized version of - ACPICA that ONLY supports the ACPI "reduced hardware" mode. The - resulting kernel will be smaller but it will also be restricted to - running in ACPI reduced hardware mode ONLY. + This config item changes the way the ACPI code is built. When this + option is selected, the kernel will use a specialized version of + ACPICA that ONLY supports the ACPI "reduced hardware" mode. The + resulting kernel will be smaller but it will also be restricted to + running in ACPI reduced hardware mode ONLY. - If you are unsure what to do, do not enable this option. + If you are unsure what to do, do not enable this option. source "drivers/acpi/apei/Kconfig" -- GitLab From c19a495c8bccc15acd299f26d72b5d51eb3acb1d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 17 Nov 2014 20:52:19 +0200 Subject: [PATCH 5119/9457] Bluetooth: Fix BR/EDR-only address checks for remote OOB data For now the mgmt commands dealing with remote OOB data are strictly BR/EDR-only. This patch fixes missing checks for the passed address type so that any non-BR/EDR value triggers the appropriate error response. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/mgmt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b84c0923ec62..258c9826e78c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3589,6 +3589,14 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, struct mgmt_cp_add_remote_oob_data *cp = data; u8 status; + if (cp->addr.type != BDADDR_BREDR) { + err = cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); + goto unlock; + } + err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash, cp->randomizer); if (err < 0) @@ -3602,6 +3610,14 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, struct mgmt_cp_add_remote_oob_ext_data *cp = data; u8 status; + if (cp->addr.type != BDADDR_BREDR) { + err = cmd_complete(sk, hdev->id, + MGMT_OP_ADD_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); + goto unlock; + } + err = hci_add_remote_oob_ext_data(hdev, &cp->addr.bdaddr, cp->hash192, cp->randomizer192, @@ -3620,6 +3636,7 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, MGMT_STATUS_INVALID_PARAMS); } +unlock: hci_dev_unlock(hdev); return err; } @@ -3633,6 +3650,11 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); + if (cp->addr.type != BDADDR_BREDR) + return cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + MGMT_STATUS_INVALID_PARAMS, + &cp->addr, sizeof(cp->addr)); + hci_dev_lock(hdev); if (!bacmp(&cp->addr.bdaddr, BDADDR_ANY)) { -- GitLab From 38da1703060a520e69b00405f9bdf765d1396cd0 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 17 Nov 2014 20:52:20 +0200 Subject: [PATCH 5120/9457] Bluetooth: Use shorter "rand" name for "randomizer" The common short form of "randomizer" is "rand" in many places (including the Bluetooth specification). The shorter version also makes for easier to read code with less forced line breaks. This patch renames all occurences of "randomizer" to "rand" in the Bluetooth subsystem code. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci.h | 12 ++++++------ include/net/bluetooth/hci_core.h | 14 +++++++------- include/net/bluetooth/mgmt.h | 12 ++++++------ net/bluetooth/hci_core.c | 14 +++++++------- net/bluetooth/hci_event.c | 17 +++++++---------- net/bluetooth/mgmt.c | 23 +++++++++-------------- 6 files changed, 42 insertions(+), 50 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index d5f85d7746bc..e56f9099f8e3 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -639,7 +639,7 @@ struct hci_cp_user_passkey_reply { struct hci_cp_remote_oob_data_reply { bdaddr_t bdaddr; __u8 hash[16]; - __u8 randomizer[16]; + __u8 rand[16]; } __packed; #define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY 0x0433 @@ -731,9 +731,9 @@ struct hci_rp_set_csb { struct hci_cp_remote_oob_ext_data_reply { bdaddr_t bdaddr; __u8 hash192[16]; - __u8 randomizer192[16]; + __u8 rand192[16]; __u8 hash256[16]; - __u8 randomizer256[16]; + __u8 rand256[16]; } __packed; #define HCI_OP_SNIFF_MODE 0x0803 @@ -940,7 +940,7 @@ struct hci_cp_write_ssp_mode { struct hci_rp_read_local_oob_data { __u8 status; __u8 hash[16]; - __u8 randomizer[16]; + __u8 rand[16]; } __packed; #define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58 @@ -1024,9 +1024,9 @@ struct hci_cp_write_sc_support { struct hci_rp_read_local_oob_ext_data { __u8 status; __u8 hash192[16]; - __u8 randomizer192[16]; + __u8 rand192[16]; __u8 hash256[16]; - __u8 randomizer256[16]; + __u8 rand256[16]; } __packed; #define HCI_OP_READ_LOCAL_VERSION 0x1001 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index fe2d5f299e12..a805b3d97c0b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -140,9 +140,9 @@ struct oob_data { struct list_head list; bdaddr_t bdaddr; u8 hash192[16]; - u8 randomizer192[16]; + u8 rand192[16]; u8 hash256[16]; - u8 randomizer256[16]; + u8 rand256[16]; }; #define HCI_MAX_SHORT_NAME_LENGTH 10 @@ -943,10 +943,10 @@ void hci_remote_oob_data_clear(struct hci_dev *hdev); struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 *hash, u8 *randomizer); + u8 *hash, u8 *rand); int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 *hash192, u8 *randomizer192, - u8 *hash256, u8 *randomizer256); + u8 *hash192, u8 *rand192, + u8 *hash256, u8 *rand256); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); @@ -1374,8 +1374,8 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, u8 status); void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, - u8 *randomizer192, u8 *hash256, - u8 *randomizer256, u8 status); + u8 *rand192, u8 *hash256, u8 *rand256, + u8 status); void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 414cd2f9a437..b391fd663468 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -299,28 +299,28 @@ struct mgmt_cp_user_passkey_neg_reply { #define MGMT_READ_LOCAL_OOB_DATA_SIZE 0 struct mgmt_rp_read_local_oob_data { __u8 hash[16]; - __u8 randomizer[16]; + __u8 rand[16]; } __packed; struct mgmt_rp_read_local_oob_ext_data { __u8 hash192[16]; - __u8 randomizer192[16]; + __u8 rand192[16]; __u8 hash256[16]; - __u8 randomizer256[16]; + __u8 rand256[16]; } __packed; #define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021 struct mgmt_cp_add_remote_oob_data { struct mgmt_addr_info addr; __u8 hash[16]; - __u8 randomizer[16]; + __u8 rand[16]; } __packed; #define MGMT_ADD_REMOTE_OOB_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 32) struct mgmt_cp_add_remote_oob_ext_data { struct mgmt_addr_info addr; __u8 hash192[16]; - __u8 randomizer192[16]; + __u8 rand192[16]; __u8 hash256[16]; - __u8 randomizer256[16]; + __u8 rand256[16]; } __packed; #define MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 64) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 90ea0b7670d2..bbefb4eea36e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3469,7 +3469,7 @@ void hci_remote_oob_data_clear(struct hci_dev *hdev) } int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 *hash, u8 *randomizer) + u8 *hash, u8 *rand) { struct oob_data *data; @@ -3484,10 +3484,10 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, } memcpy(data->hash192, hash, sizeof(data->hash192)); - memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192)); + memcpy(data->rand192, rand, sizeof(data->rand192)); memset(data->hash256, 0, sizeof(data->hash256)); - memset(data->randomizer256, 0, sizeof(data->randomizer256)); + memset(data->rand256, 0, sizeof(data->rand256)); BT_DBG("%s for %pMR", hdev->name, bdaddr); @@ -3495,8 +3495,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, } int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 *hash192, u8 *randomizer192, - u8 *hash256, u8 *randomizer256) + u8 *hash192, u8 *rand192, + u8 *hash256, u8 *rand256) { struct oob_data *data; @@ -3511,10 +3511,10 @@ int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, } memcpy(data->hash192, hash192, sizeof(data->hash192)); - memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192)); + memcpy(data->rand192, rand192, sizeof(data->rand192)); memcpy(data->hash256, hash256, sizeof(data->hash256)); - memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256)); + memcpy(data->rand256, rand256, sizeof(data->rand256)); BT_DBG("%s for %pMR", hdev->name, bdaddr); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 09d76547d985..844f7d1ff1cd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -994,8 +994,8 @@ static void hci_cc_read_local_oob_data(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); hci_dev_lock(hdev); - mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer, - NULL, NULL, rp->status); + mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->rand, NULL, NULL, + rp->status); hci_dev_unlock(hdev); } @@ -1007,8 +1007,8 @@ static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); hci_dev_lock(hdev); - mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192, - rp->hash256, rp->randomizer256, + mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->rand192, + rp->hash256, rp->rand256, rp->status); hci_dev_unlock(hdev); } @@ -3996,11 +3996,9 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, bacpy(&cp.bdaddr, &ev->bdaddr); memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); - memcpy(cp.randomizer192, data->randomizer192, - sizeof(cp.randomizer192)); + memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); - memcpy(cp.randomizer256, data->randomizer256, - sizeof(cp.randomizer256)); + memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, sizeof(cp), &cp); @@ -4009,8 +4007,7 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, bacpy(&cp.bdaddr, &ev->bdaddr); memcpy(cp.hash, data->hash192, sizeof(cp.hash)); - memcpy(cp.randomizer, data->randomizer192, - sizeof(cp.randomizer)); + memcpy(cp.rand, data->rand192, sizeof(cp.rand)); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), &cp); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 258c9826e78c..cbeef5f62f3b 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -3598,7 +3598,7 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, } err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, - cp->hash, cp->randomizer); + cp->hash, cp->rand); if (err < 0) status = MGMT_STATUS_FAILED; else @@ -3619,10 +3619,8 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, } err = hci_add_remote_oob_ext_data(hdev, &cp->addr.bdaddr, - cp->hash192, - cp->randomizer192, - cp->hash256, - cp->randomizer256); + cp->hash192, cp->rand192, + cp->hash256, cp->rand256); if (err < 0) status = MGMT_STATUS_FAILED; else @@ -6771,8 +6769,8 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) } void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, - u8 *randomizer192, u8 *hash256, - u8 *randomizer256, u8 status) + u8 *rand192, u8 *hash256, u8 *rand256, + u8 status) { struct pending_cmd *cmd; @@ -6787,16 +6785,14 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, mgmt_status(status)); } else { if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && - hash256 && randomizer256) { + hash256 && rand256) { struct mgmt_rp_read_local_oob_ext_data rp; memcpy(rp.hash192, hash192, sizeof(rp.hash192)); - memcpy(rp.randomizer192, randomizer192, - sizeof(rp.randomizer192)); + memcpy(rp.rand192, rand192, sizeof(rp.rand192)); memcpy(rp.hash256, hash256, sizeof(rp.hash256)); - memcpy(rp.randomizer256, randomizer256, - sizeof(rp.randomizer256)); + memcpy(rp.rand256, rand256, sizeof(rp.rand256)); cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 0, @@ -6805,8 +6801,7 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, struct mgmt_rp_read_local_oob_data rp; memcpy(rp.hash, hash192, sizeof(rp.hash)); - memcpy(rp.randomizer, randomizer192, - sizeof(rp.randomizer)); + memcpy(rp.rand, rand192, sizeof(rp.rand)); cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 0, -- GitLab From d93de3455d0f04b1c5a60af41399b7f6f7b13c47 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sun, 16 Nov 2014 10:57:00 +0100 Subject: [PATCH 5121/9457] ACPI: remove unnecessary sizeof(u8) sizeof(u8) is always 1. Signed-off-by: Fabian Frederick Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 371ac12d25b1..dd8ff63ee2b4 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -136,8 +136,7 @@ acpi_extract_package(union acpi_object *package, break; case 'B': size_required += - sizeof(u8 *) + - (element->buffer.length * sizeof(u8)); + sizeof(u8 *) + element->buffer.length; tail_offset += sizeof(u8 *); break; default: @@ -255,7 +254,7 @@ acpi_extract_package(union acpi_object *package, memcpy(tail, element->buffer.pointer, element->buffer.length); head += sizeof(u8 *); - tail += element->buffer.length * sizeof(u8); + tail += element->buffer.length; break; default: /* Should never get here */ -- GitLab From 76f3e2929bb6b476fb02b519ad953e2e29ee7bd5 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Fri, 31 Jan 2014 15:10:14 +0530 Subject: [PATCH 5122/9457] powerpc/config: Enable memory driver As Freescale IFC controller has been moved to driver to driver/memory. So enable memory driver in powerpc config Signed-off-by: Prabhakar Kushwaha Signed-off-by: Scott Wood --- arch/powerpc/configs/corenet32_smp_defconfig | 1 + arch/powerpc/configs/corenet64_smp_defconfig | 1 + arch/powerpc/configs/mpc85xx_defconfig | 1 + arch/powerpc/configs/mpc85xx_smp_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index 688e9e4d29a1..611efe99faeb 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -144,6 +144,7 @@ CONFIG_RTC_DRV_DS1374=y CONFIG_RTC_DRV_DS3232=y CONFIG_UIO=y CONFIG_STAGING=y +CONFIG_MEMORY=y CONFIG_VIRT_DRIVERS=y CONFIG_FSL_HV_MANAGER=y CONFIG_EXT2_FS=y diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index 6db97e4414b2..be24a18c0d96 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -118,6 +118,7 @@ CONFIG_FSL_DMA=y CONFIG_VIRT_DRIVERS=y CONFIG_FSL_HV_MANAGER=y CONFIG_FSL_CORENET_CF=y +CONFIG_MEMORY=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=m diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index d2c415489f72..02395fab19bd 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -215,6 +215,7 @@ CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_CMOS=y CONFIG_DMADEVICES=y CONFIG_FSL_DMA=y +CONFIG_MEMORY=y # CONFIG_NET_DMA is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 87460083dbc7..b5d1b82a1b43 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -216,6 +216,7 @@ CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_CMOS=y CONFIG_DMADEVICES=y CONFIG_FSL_DMA=y +CONFIG_MEMORY=y # CONFIG_NET_DMA is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y -- GitLab From f41f4815f8e81e8745fca8396d842adb74689c88 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 15 Nov 2014 08:50:44 +0530 Subject: [PATCH 5123/9457] cpufreq: Kconfig: Remove architecture specific menu entries CPUFreq driver's Kconfig entries are added in Kconfig. files and they are all included from the main Kconfig file using a menu entry. This creates another level of (unnecessary) hierarchy within the menuconfig entries. The problem occurs when there are drivers usable across architectures. Either their config entry is duplicated in all the supported architectures or is put into the main Kconfig entry. With the later one, we have menuconfig entries for drivers at two levels then. Fix these issues by getting rid of another level of menuconfig hierarchy and populate all drivers within the main cpufreq menu. To clearly distinguish where the drivers start from, also add a comment that will appear in menuconfig. Reported-by: Tang Yuantian Suggested-by: Scott Wood Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig | 50 ++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4de4dfae4ccc..29b2ef5a68b9 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -182,6 +182,8 @@ config CPU_FREQ_GOV_CONSERVATIVE If in doubt, say N. +comment "CPU frequency scaling drivers" + config CPUFREQ_DT tristate "Generic DT based cpufreq driver" depends on HAVE_CLK && OF @@ -195,19 +197,19 @@ config CPUFREQ_DT If in doubt, say N. -menu "x86 CPU frequency scaling drivers" -depends on X86 +if X86 source "drivers/cpufreq/Kconfig.x86" -endmenu +endif -menu "ARM CPU frequency scaling drivers" -depends on ARM || ARM64 +if ARM || ARM64 source "drivers/cpufreq/Kconfig.arm" -endmenu +endif -menu "AVR32 CPU frequency scaling drivers" -depends on AVR32 +if PPC32 || PPC64 +source "drivers/cpufreq/Kconfig.powerpc" +endif +if AVR32 config AVR32_AT32AP_CPUFREQ bool "CPU frequency driver for AT32AP" depends on PLATFORM_AT32AP @@ -215,12 +217,9 @@ config AVR32_AT32AP_CPUFREQ help This enables the CPU frequency driver for AT32AP processors. If in doubt, say N. +endif -endmenu - -menu "CPUFreq processor drivers" -depends on IA64 - +if IA64 config IA64_ACPI_CPUFREQ tristate "ACPI Processor P-States driver" depends on ACPI_PROCESSOR @@ -231,12 +230,9 @@ config IA64_ACPI_CPUFREQ For details, take a look at . If in doubt, say N. +endif -endmenu - -menu "MIPS CPUFreq processor drivers" -depends on MIPS - +if MIPS config LOONGSON2_CPUFREQ tristate "Loongson2 CPUFreq Driver" help @@ -258,16 +254,9 @@ config LOONGSON1_CPUFREQ For details, take a look at . If in doubt, say N. +endif -endmenu - -menu "PowerPC CPU frequency scaling drivers" -depends on PPC32 || PPC64 -source "drivers/cpufreq/Kconfig.powerpc" -endmenu - -menu "SPARC CPU frequency scaling drivers" -depends on SPARC64 +if SPARC64 config SPARC_US3_CPUFREQ tristate "UltraSPARC-III CPU Frequency driver" help @@ -285,10 +274,9 @@ config SPARC_US2E_CPUFREQ For details, take a look at . If in doubt, say N. -endmenu +endif -menu "SH CPU Frequency scaling" -depends on SUPERH +if SUPERH config SH_CPU_FREQ tristate "SuperH CPU Frequency driver" help @@ -302,7 +290,7 @@ config SH_CPU_FREQ For details, take a look at . If unsure, say N. -endmenu +endif endif endmenu -- GitLab From 6c45de0d51a3d93267ee100bff8c4632b1d49e8f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 16 Nov 2014 14:18:28 +0100 Subject: [PATCH 5124/9457] PM / hibernate: Deletion of an unnecessary check before the function call "vfree" The vfree() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Rafael J. Wysocki --- kernel/power/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 2c9d6d50a816..570aff817543 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -1375,7 +1375,7 @@ static int load_image_lzo(struct swap_map_handle *handle, kthread_stop(data[thr].thr); vfree(data); } - if (page) vfree(page); + vfree(page); return ret; } -- GitLab From 7d3dcd042c328891a61cd69ee5a1f15a59facd1b Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Mon, 17 Nov 2014 11:42:44 +0530 Subject: [PATCH 5125/9457] PM: Kconfig: fix unmet dependency for CPU_PM If BL_SWITCHER is enabled but SUSPEND and CPU_IDLE is not enabled we are getting following config warning. warning: (BL_SWITCHER) selects CPU_PM which has unmet direct dependencies (SUSPEND || CPU_IDLE) It has been noticed that CPU_PM dependencies in this file are not really required so let's remove these dependencies from CPU_PM. Signed-off-by: Pankaj Dubey Acked-by: Nicolas Pitre Signed-off-by: Rafael J. Wysocki --- kernel/power/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index bbef57f5bdfd..1eb7da7bc8e8 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -308,4 +308,3 @@ config PM_GENERIC_DOMAINS_OF config CPU_PM bool - depends on SUSPEND || CPU_IDLE -- GitLab From bc78b05bb412fad135715551fc536ca511a3cff2 Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Fri, 14 Nov 2014 17:37:50 +1100 Subject: [PATCH 5126/9457] cxl: Return error to PSL if IRQ demultiplexing fails & print clearer warning If an AFU has a hardware bug that causes it to acknowledge a context terminate or remove while that context has outstanding transactions, it is possible for the kernel to receive an interrupt for that context after we have removed it from the context list. The kernel will not be able to demultiplex the interrupt (or worse - if we have already reallocated the process handle we could mis-attribute it to the new context), and printed a big scary warning. It did not acknowledge the interrupt, which would effectively halt further translation fault processing on the PSL. This patch makes the warning clearer about the likely cause of the issue (i.e. hardware bug) to make it obvious to future AFU designers of what needs to be fixed. It also prints out the process handle which can then be matched up with hardware and software traces for debugging. It also acknowledges the interrupt to the PSL with either an address error or acknowledge, so that the PSL can continue with other translations. Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 2 +- drivers/misc/cxl/irq.c | 46 ++++++++++++++++++++++++--------------- drivers/misc/cxl/native.c | 14 ++++++------ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 3d2b8677ec8a..64a4aa3a5c5d 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -612,7 +612,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr); int cxl_detach_process(struct cxl_context *ctx); -int cxl_get_irq(struct cxl_context *ctx, struct cxl_irq_info *info); +int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info); int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); int cxl_check_error(struct cxl_afu *afu); diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c index 336020c8e1af..35fcb3d43dc0 100644 --- a/drivers/misc/cxl/irq.c +++ b/drivers/misc/cxl/irq.c @@ -92,20 +92,13 @@ static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 da return IRQ_HANDLED; } -static irqreturn_t cxl_irq(int irq, void *data) +static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) { struct cxl_context *ctx = data; - struct cxl_irq_info irq_info; u64 dsisr, dar; - int result; - if ((result = cxl_get_irq(ctx, &irq_info))) { - WARN(1, "Unable to get CXL IRQ Info: %i\n", result); - return IRQ_HANDLED; - } - - dsisr = irq_info.dsisr; - dar = irq_info.dar; + dsisr = irq_info->dsisr; + dar = irq_info->dar; pr_devel("CXL interrupt %i for afu pe: %i DSISR: %#llx DAR: %#llx\n", irq, ctx->pe, dsisr, dar); @@ -149,9 +142,9 @@ static irqreturn_t cxl_irq(int irq, void *data) if (dsisr & CXL_PSL_DSISR_An_UR) pr_devel("CXL interrupt: AURP PTE not found\n"); if (dsisr & CXL_PSL_DSISR_An_PE) - return handle_psl_slice_error(ctx, dsisr, irq_info.errstat); + return handle_psl_slice_error(ctx, dsisr, irq_info->errstat); if (dsisr & CXL_PSL_DSISR_An_AE) { - pr_devel("CXL interrupt: AFU Error %.llx\n", irq_info.afu_err); + pr_devel("CXL interrupt: AFU Error %.llx\n", irq_info->afu_err); if (ctx->pending_afu_err) { /* @@ -163,10 +156,10 @@ static irqreturn_t cxl_irq(int irq, void *data) */ dev_err_ratelimited(&ctx->afu->dev, "CXL AFU Error " "undelivered to pe %i: %.llx\n", - ctx->pe, irq_info.afu_err); + ctx->pe, irq_info->afu_err); } else { spin_lock(&ctx->lock); - ctx->afu_err = irq_info.afu_err; + ctx->afu_err = irq_info->afu_err; ctx->pending_afu_err = 1; spin_unlock(&ctx->lock); @@ -182,24 +175,43 @@ static irqreturn_t cxl_irq(int irq, void *data) return IRQ_HANDLED; } +static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info) +{ + if (irq_info->dsisr & CXL_PSL_DSISR_TRANS) + cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE); + else + cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A); + + return IRQ_HANDLED; +} + static irqreturn_t cxl_irq_multiplexed(int irq, void *data) { struct cxl_afu *afu = data; struct cxl_context *ctx; + struct cxl_irq_info irq_info; int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff; int ret; + if ((ret = cxl_get_irq(afu, &irq_info))) { + WARN(1, "Unable to get CXL IRQ Info: %i\n", ret); + return fail_psl_irq(afu, &irq_info); + } + rcu_read_lock(); ctx = idr_find(&afu->contexts_idr, ph); if (ctx) { - ret = cxl_irq(irq, ctx); + ret = cxl_irq(irq, ctx, &irq_info); rcu_read_unlock(); return ret; } rcu_read_unlock(); - WARN(1, "Unable to demultiplex CXL PSL IRQ\n"); - return IRQ_HANDLED; + WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %.16llx DAR" + " %.16llx\n(Possible AFU HW issue - was a term/remove acked" + " with outstanding transactions?)\n", ph, irq_info.dsisr, + irq_info.dar); + return fail_psl_irq(afu, &irq_info); } static irqreturn_t cxl_irq_afu(int irq, void *data) diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index d47532e8f4f1..9a5a442269a8 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -637,18 +637,18 @@ int cxl_detach_process(struct cxl_context *ctx) return detach_process_native_afu_directed(ctx); } -int cxl_get_irq(struct cxl_context *ctx, struct cxl_irq_info *info) +int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) { u64 pidtid; - info->dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An); - info->dar = cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An); - info->dsr = cxl_p2n_read(ctx->afu, CXL_PSL_DSR_An); - pidtid = cxl_p2n_read(ctx->afu, CXL_PSL_PID_TID_An); + info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); + info->dar = cxl_p2n_read(afu, CXL_PSL_DAR_An); + info->dsr = cxl_p2n_read(afu, CXL_PSL_DSR_An); + pidtid = cxl_p2n_read(afu, CXL_PSL_PID_TID_An); info->pid = pidtid >> 32; info->tid = pidtid & 0xffffffff; - info->afu_err = cxl_p2n_read(ctx->afu, CXL_AFU_ERR_An); - info->errstat = cxl_p2n_read(ctx->afu, CXL_PSL_ErrStat_An); + info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An); + info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); return 0; } -- GitLab From 80fa93fce37d3490f4bb0da8a5b239a6745bc744 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 14 Nov 2014 18:09:28 +1100 Subject: [PATCH 5127/9457] cxl: Name interrupts in /proc/interrupt Currently all interrupts generated by cxl are named "cxl". This is not very informative as we can't distinguish between cards, AFUs, error interrupts, user contexts and user interrupts numbers. Being able to distinguish them is useful for setting affinity. This patch gives each of these names in /proc/interrupts. A two card CAPI system, with afu0.0 having 2 active contexts each with 4 user IRQs each, will now look like this: % grep cxl /proc/interrupts 444: 0 OPAL ICS 141312 Level cxl-card1-err 445: 0 OPAL ICS 141313 Level cxl-afu1.0-err 446: 0 OPAL ICS 141314 Level cxl-afu1.0 462: 0 OPAL ICS 2052 Level cxl-afu0.0-pe0-1 463: 75517 OPAL ICS 2053 Level cxl-afu0.0-pe0-2 468: 0 OPAL ICS 2054 Level cxl-afu0.0-pe0-3 469: 0 OPAL ICS 2055 Level cxl-afu0.0-pe0-4 470: 0 OPAL ICS 2056 Level cxl-afu0.0-pe1-1 471: 75506 OPAL ICS 2057 Level cxl-afu0.0-pe1-2 472: 0 OPAL ICS 2058 Level cxl-afu0.0-pe1-3 473: 0 OPAL ICS 2059 Level cxl-afu0.0-pe1-4 502: 1066 OPAL ICS 2050 Level cxl-afu0.0 514: 0 OPAL ICS 2048 Level cxl-card0-err 515: 0 OPAL ICS 2049 Level cxl-afu0.0-err Signed-off-by: Michael Neuling Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman --- drivers/misc/cxl/cxl.h | 13 ++++-- drivers/misc/cxl/irq.c | 98 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 98 insertions(+), 13 deletions(-) diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 64a4aa3a5c5d..b5b6bda44a00 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -336,6 +336,8 @@ struct cxl_sste { struct cxl_afu { irq_hw_number_t psl_hwirq; irq_hw_number_t serr_hwirq; + char *err_irq_name; + char *psl_irq_name; unsigned int serr_virq; void __iomem *p1n_mmio; void __iomem *p2n_mmio; @@ -379,6 +381,12 @@ struct cxl_afu { bool enabled; }; + +struct cxl_irq_name { + struct list_head list; + char *name; +}; + /* * This is a cxl context. If the PSL is in dedicated mode, there will be one * of these per AFU. If in AFU directed there can be lots of these. @@ -403,6 +411,7 @@ struct cxl_context { unsigned long *irq_bitmap; /* Accessed from IRQ context */ struct cxl_irq_ranges irqs; + struct list_head irq_names; u64 fault_addr; u64 fault_dsisr; u64 afu_err; @@ -444,6 +453,7 @@ struct cxl { struct dentry *trace; struct dentry *psl_err_chk; struct dentry *debugfs; + char *irq_name; struct bin_attribute cxl_attr; int adapter_num; int user_irqs; @@ -563,9 +573,6 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode); int cxl_afu_deactivate_mode(struct cxl_afu *afu); int cxl_afu_select_best_mode(struct cxl_afu *afu); -unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, - irq_handler_t handler, void *cookie); -void cxl_unmap_irq(unsigned int virq, void *cookie); int cxl_register_psl_irq(struct cxl_afu *afu); void cxl_release_psl_irq(struct cxl_afu *afu); int cxl_register_psl_err_irq(struct cxl *adapter); diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c index 35fcb3d43dc0..c294925f73ee 100644 --- a/drivers/misc/cxl/irq.c +++ b/drivers/misc/cxl/irq.c @@ -255,7 +255,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data) } unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, - irq_handler_t handler, void *cookie) + irq_handler_t handler, void *cookie, const char *name) { unsigned int virq; int result; @@ -271,7 +271,7 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); - result = request_irq(virq, handler, 0, "cxl", cookie); + result = request_irq(virq, handler, 0, name, cookie); if (result) { dev_warn(&adapter->dev, "cxl_map_irq: request_irq failed: %i\n", result); return 0; @@ -290,14 +290,15 @@ static int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler, void *cookie, irq_hw_number_t *dest_hwirq, - unsigned int *dest_virq) + unsigned int *dest_virq, + const char *name) { int hwirq, virq; if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) return hwirq; - if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie))) + if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) goto err; *dest_hwirq = hwirq; @@ -314,10 +315,19 @@ int cxl_register_psl_err_irq(struct cxl *adapter) { int rc; + adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", + dev_name(&adapter->dev)); + if (!adapter->irq_name) + return -ENOMEM; + if ((rc = cxl_register_one_irq(adapter, cxl_irq_err, adapter, &adapter->err_hwirq, - &adapter->err_virq))) + &adapter->err_virq, + adapter->irq_name))) { + kfree(adapter->irq_name); + adapter->irq_name = NULL; return rc; + } cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff); @@ -329,6 +339,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter) cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); cxl_unmap_irq(adapter->err_virq, adapter); cxl_release_one_irq(adapter, adapter->err_hwirq); + kfree(adapter->irq_name); } int cxl_register_serr_irq(struct cxl_afu *afu) @@ -336,10 +347,18 @@ int cxl_register_serr_irq(struct cxl_afu *afu) u64 serr; int rc; + afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err", + dev_name(&afu->dev)); + if (!afu->err_irq_name) + return -ENOMEM; + if ((rc = cxl_register_one_irq(afu->adapter, cxl_slice_irq_err, afu, &afu->serr_hwirq, - &afu->serr_virq))) + &afu->serr_virq, afu->err_irq_name))) { + kfree(afu->err_irq_name); + afu->err_irq_name = NULL; return rc; + } serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff); @@ -353,24 +372,50 @@ void cxl_release_serr_irq(struct cxl_afu *afu) cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); cxl_unmap_irq(afu->serr_virq, afu); cxl_release_one_irq(afu->adapter, afu->serr_hwirq); + kfree(afu->err_irq_name); } int cxl_register_psl_irq(struct cxl_afu *afu) { - return cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu, - &afu->psl_hwirq, &afu->psl_virq); + int rc; + + afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s", + dev_name(&afu->dev)); + if (!afu->psl_irq_name) + return -ENOMEM; + + if ((rc = cxl_register_one_irq(afu->adapter, cxl_irq_multiplexed, afu, + &afu->psl_hwirq, &afu->psl_virq, + afu->psl_irq_name))) { + kfree(afu->psl_irq_name); + afu->psl_irq_name = NULL; + } + return rc; } void cxl_release_psl_irq(struct cxl_afu *afu) { cxl_unmap_irq(afu->psl_virq, afu); cxl_release_one_irq(afu->adapter, afu->psl_hwirq); + kfree(afu->psl_irq_name); +} + +void afu_irq_name_free(struct cxl_context *ctx) +{ + struct cxl_irq_name *irq_name, *tmp; + + list_for_each_entry_safe(irq_name, tmp, &ctx->irq_names, list) { + kfree(irq_name->name); + list_del(&irq_name->list); + kfree(irq_name); + } } int afu_register_irqs(struct cxl_context *ctx, u32 count) { irq_hw_number_t hwirq; - int rc, r, i; + int rc, r, i, j = 1; + struct cxl_irq_name *irq_name; if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) return rc; @@ -384,15 +429,47 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count) sizeof(*ctx->irq_bitmap), GFP_KERNEL); if (!ctx->irq_bitmap) return -ENOMEM; + + /* + * Allocate names first. If any fail, bail out before allocating + * actual hardware IRQs. + */ + INIT_LIST_HEAD(&ctx->irq_names); + for (r = 1; r < CXL_IRQ_RANGES; r++) { + for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { + irq_name = kmalloc(sizeof(struct cxl_irq_name), + GFP_KERNEL); + if (!irq_name) + goto out; + irq_name->name = kasprintf(GFP_KERNEL, "cxl-%s-pe%i-%i", + dev_name(&ctx->afu->dev), + ctx->pe, j); + if (!irq_name->name) { + kfree(irq_name); + goto out; + } + /* Add to tail so next look get the correct order */ + list_add_tail(&irq_name->list, &ctx->irq_names); + j++; + } + } + + /* We've allocated all memory now, so let's do the irq allocations */ + irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list); for (r = 1; r < CXL_IRQ_RANGES; r++) { hwirq = ctx->irqs.offset[r]; for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) { cxl_map_irq(ctx->afu->adapter, hwirq, - cxl_irq_afu, ctx); + cxl_irq_afu, ctx, irq_name->name); + irq_name = list_next_entry(irq_name, list); } } return 0; + +out: + afu_irq_name_free(ctx); + return -ENOMEM; } void afu_release_irqs(struct cxl_context *ctx) @@ -410,5 +487,6 @@ void afu_release_irqs(struct cxl_context *ctx) } } + afu_irq_name_free(ctx); cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); } -- GitLab From e3c4abbfa97ed0b7aed36f18b32911ccf76d52c2 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:12 +0200 Subject: [PATCH 5128/9457] integrity: define a new function integrity_read_file() This patch defines a new function called integrity_read_file() to read file from the kernel into a buffer. Subsequent patches will read a file containing the public keys and load them onto the IMA keyring. This patch moves and renames ima_kernel_read(), the non-security checking version of kernel_read(), to integrity_kernel_read(). Changes in v3: * Patch descriptions improved (Mimi) * Add missing cast (kbuild test robot) Changes in v2: * configuration option removed * function declared as '__init' Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/iint.c | 78 +++++++++++++++++++++++++++++ security/integrity/ima/ima_crypto.c | 35 ++----------- security/integrity/integrity.h | 4 ++ 3 files changed, 85 insertions(+), 32 deletions(-) diff --git a/security/integrity/iint.c b/security/integrity/iint.c index cc3eb4de18a1..dbee618526b6 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "integrity.h" static struct rb_root integrity_iint_tree = RB_ROOT; @@ -167,3 +169,79 @@ static int __init integrity_iintcache_init(void) return 0; } security_initcall(integrity_iintcache_init); + + +/* + * integrity_kernel_read - read data from the file + * + * This is a function for reading file content instead of kernel_read(). + * It does not perform locking checks to ensure it cannot be blocked. + * It does not perform security checks because it is irrelevant for IMA. + * + */ +int integrity_kernel_read(struct file *file, loff_t offset, + char *addr, unsigned long count) +{ + mm_segment_t old_fs; + char __user *buf = (char __user *)addr; + ssize_t ret = -EINVAL; + + if (!(file->f_mode & FMODE_READ)) + return -EBADF; + + old_fs = get_fs(); + set_fs(get_ds()); + if (file->f_op->read) + ret = file->f_op->read(file, buf, count, &offset); + else if (file->f_op->aio_read) + ret = do_sync_read(file, buf, count, &offset); + else if (file->f_op->read_iter) + ret = new_sync_read(file, buf, count, &offset); + set_fs(old_fs); + return ret; +} + +/* + * integrity_read_file - read entire file content into the buffer + * + * This is function opens a file, allocates the buffer of required + * size, read entire file content to the buffer and closes the file + * + * It is used only by init code. + * + */ +int __init integrity_read_file(const char *path, char **data) +{ + struct file *file; + loff_t size; + char *buf; + int rc = -EINVAL; + + file = filp_open(path, O_RDONLY, 0); + if (IS_ERR(file)) { + rc = PTR_ERR(file); + pr_err("Unable to open file: %s (%d)", path, rc); + return rc; + } + + size = i_size_read(file_inode(file)); + if (size <= 0) + goto out; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) { + rc = -ENOMEM; + goto out; + } + + rc = integrity_kernel_read(file, 0, buf, size); + if (rc < 0) + kfree(buf); + else if (rc != size) + rc = -EIO; + else + *data = buf; +out: + fput(file); + return rc; +} diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index d34e7dfc1118..5df4d960d4dc 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -67,36 +67,6 @@ MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size"); static struct crypto_shash *ima_shash_tfm; static struct crypto_ahash *ima_ahash_tfm; -/** - * ima_kernel_read - read file content - * - * This is a function for reading file content instead of kernel_read(). - * It does not perform locking checks to ensure it cannot be blocked. - * It does not perform security checks because it is irrelevant for IMA. - * - */ -static int ima_kernel_read(struct file *file, loff_t offset, - char *addr, unsigned long count) -{ - mm_segment_t old_fs; - char __user *buf = addr; - ssize_t ret = -EINVAL; - - if (!(file->f_mode & FMODE_READ)) - return -EBADF; - - old_fs = get_fs(); - set_fs(get_ds()); - if (file->f_op->read) - ret = file->f_op->read(file, buf, count, &offset); - else if (file->f_op->aio_read) - ret = do_sync_read(file, buf, count, &offset); - else if (file->f_op->read_iter) - ret = new_sync_read(file, buf, count, &offset); - set_fs(old_fs); - return ret; -} - int __init ima_init_crypto(void) { long rc; @@ -324,7 +294,8 @@ static int ima_calc_file_hash_atfm(struct file *file, } /* read buffer */ rbuf_len = min_t(loff_t, i_size - offset, rbuf_size[active]); - rc = ima_kernel_read(file, offset, rbuf[active], rbuf_len); + rc = integrity_kernel_read(file, offset, rbuf[active], + rbuf_len); if (rc != rbuf_len) goto out3; @@ -417,7 +388,7 @@ static int ima_calc_file_hash_tfm(struct file *file, while (offset < i_size) { int rbuf_len; - rbuf_len = ima_kernel_read(file, offset, rbuf, PAGE_SIZE); + rbuf_len = integrity_kernel_read(file, offset, rbuf, PAGE_SIZE); if (rbuf_len < 0) { rc = rbuf_len; break; diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index f51ad65c894d..20d220481025 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -119,6 +119,10 @@ struct integrity_iint_cache { */ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); +int integrity_kernel_read(struct file *file, loff_t offset, + char *addr, unsigned long count); +int __init integrity_read_file(const char *path, char **data); + #define INTEGRITY_KEYRING_EVM 0 #define INTEGRITY_KEYRING_MODULE 1 #define INTEGRITY_KEYRING_IMA 2 -- GitLab From 65d543b2335ede80e5e66bc4f559f62db5f469bd Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:13 +0200 Subject: [PATCH 5129/9457] integrity: provide a function to load x509 certificate from the kernel Provide the function to load x509 certificates from the kernel into the integrity kernel keyring. Changes in v2: * configuration option removed * function declared as '__init' Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/digsig.c | 36 +++++++++++++++++++++++++++++++++- security/integrity/integrity.h | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 4f643d1b34dd..5e3bd72b299a 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -84,3 +84,37 @@ int __init integrity_init_keyring(const unsigned int id) } return err; } + +int __init integrity_load_x509(const unsigned int id, char *path) +{ + key_ref_t key; + char *data; + int rc; + + if (!keyring[id]) + return -EINVAL; + + rc = integrity_read_file(path, &data); + if (rc < 0) + return rc; + + key = key_create_or_update(make_key_ref(keyring[id], 1), + "asymmetric", + NULL, + data, + rc, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ), + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_TRUSTED); + if (IS_ERR(key)) { + rc = PTR_ERR(key); + pr_err("Problem loading X.509 certificate (%d): %s\n", + rc, path); + } else { + pr_notice("Loaded X.509 cert '%s': %s\n", + key_ref_to_ptr(key)->description, path); + key_ref_put(key); + } + kfree(data); + return 0; +} diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 20d220481025..1057abbd31cd 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -134,6 +134,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, const char *digest, int digestlen); int __init integrity_init_keyring(const unsigned int id); +int __init integrity_load_x509(const unsigned int id, char *path); #else static inline int integrity_digsig_verify(const unsigned int id, @@ -147,6 +148,7 @@ static inline int integrity_init_keyring(const unsigned int id) { return 0; } + #endif /* CONFIG_INTEGRITY_SIGNATURE */ #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS -- GitLab From fd5f4e9054acbf4f22fac81a358baf3c27aa42ac Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:14 +0200 Subject: [PATCH 5130/9457] ima: load x509 certificate from the kernel Define configuration option to load X509 certificate into the IMA trusted kernel keyring. It implements ima_load_x509() hook to load X509 certificate into the .ima trusted kernel keyring from the root filesystem. Changes in v3: * use ima_policy_flag in ima_get_action() ima_load_x509 temporarily clears ima_policy_flag to disable appraisal to load key. Use it to skip appraisal rules. * Key directory path changed to /etc/keys (Mimi) * Expand IMA_LOAD_X509 Kconfig help Changes in v2: * added '__init' * use ima_policy_flag to disable appraisal to load keys Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/Kconfig | 18 ++++++++++++++++++ security/integrity/ima/ima_api.c | 3 +-- security/integrity/ima/ima_init.c | 17 +++++++++++++++++ security/integrity/integrity.h | 8 ++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index e099875643c5..b0840f9a552f 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -131,3 +131,21 @@ config IMA_TRUSTED_KEYRING help This option requires that all keys added to the .ima keyring be signed by a key on the system trusted keyring. + +config IMA_LOAD_X509 + bool "Load X509 certificate onto the '.ima' trusted keyring" + depends on IMA_TRUSTED_KEYRING + default n + help + File signature verification is based on the public keys + loaded on the .ima trusted keyring. These public keys are + X509 certificates signed by a trusted key on the + .system keyring. This option enables X509 certificate + loading from the kernel onto the '.ima' trusted keyring. + +config IMA_X509_PATH + string "IMA X509 certificate path" + depends on IMA_LOAD_X509 + default "/etc/keys/x509_ima.der" + help + This option defines IMA X509 certificate path. diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index a99eb6d4bc09..b0dc922d8be3 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -173,8 +173,7 @@ int ima_get_action(struct inode *inode, int mask, int function) { int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; - if (!ima_appraise) - flags &= ~IMA_APPRAISE; + flags &= ima_policy_flag; return ima_match_policy(inode, function, mask, flags); } diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 9164fc8cac84..5e4c29d174ee 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -24,6 +24,12 @@ #include #include "ima.h" +#ifdef CONFIG_IMA_X509_PATH +#define IMA_X509_PATH CONFIG_IMA_X509_PATH +#else +#define IMA_X509_PATH "/etc/keys/x509_ima.der" +#endif + /* name for boot aggregate entry */ static const char *boot_aggregate_name = "boot_aggregate"; int ima_used_chip; @@ -91,6 +97,17 @@ static int __init ima_add_boot_aggregate(void) return result; } +#ifdef CONFIG_IMA_LOAD_X509 +void __init ima_load_x509(void) +{ + int unset_flags = ima_policy_flag & IMA_APPRAISE; + + ima_policy_flag &= ~unset_flags; + integrity_load_x509(INTEGRITY_KEYRING_IMA, IMA_X509_PATH); + ima_policy_flag |= unset_flags; +} +#endif + int __init ima_init(void) { u8 pcr_i[TPM_DIGEST_SIZE]; diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 1057abbd31cd..caa1f6ca72e9 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -162,6 +162,14 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig, } #endif +#ifdef CONFIG_IMA_LOAD_X509 +void __init ima_load_x509(void); +#else +static inline void ima_load_x509(void) +{ +} +#endif + #ifdef CONFIG_INTEGRITY_AUDIT /* declarations */ void integrity_audit_msg(int audit_msgno, struct inode *inode, -- GitLab From c9cd2ce2bc6313aafa33f8e28d29a8690252f219 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:15 +0200 Subject: [PATCH 5131/9457] integrity: provide a hook to load keys when rootfs is ready Keys can only be loaded once the rootfs is mounted. Initcalls are not suitable for that. This patch defines a special hook to load the x509 public keys onto the IMA keyring, before attempting to access any file. The keys are required for verifying the file's signature. The hook is called after the root filesystem is mounted and before the kernel calls 'init'. Changes in v3: * added more explanation to the patch description (Mimi) Changes in v2: * Hook renamed as 'integrity_load_keys()' to handle both IMA and EVM keys by integrity subsystem. * Hook patch moved after defining loading functions Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- include/linux/integrity.h | 6 ++++++ init/main.c | 6 +++++- security/integrity/iint.c | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/linux/integrity.h b/include/linux/integrity.h index 83222cebd47b..c2d6082a1a4c 100644 --- a/include/linux/integrity.h +++ b/include/linux/integrity.h @@ -24,6 +24,7 @@ enum integrity_status { #ifdef CONFIG_INTEGRITY extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode); extern void integrity_inode_free(struct inode *inode); +extern void __init integrity_load_keys(void); #else static inline struct integrity_iint_cache * @@ -36,5 +37,10 @@ static inline void integrity_inode_free(struct inode *inode) { return; } + +static inline void integrity_load_keys(void) +{ +} #endif /* CONFIG_INTEGRITY */ + #endif /* _LINUX_INTEGRITY_H */ diff --git a/init/main.c b/init/main.c index e8ae1fef0908..2c1928d08b78 100644 --- a/init/main.c +++ b/init/main.c @@ -78,6 +78,7 @@ #include #include #include +#include #include #include @@ -1026,8 +1027,11 @@ static noinline void __init kernel_init_freeable(void) * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. + * + * rootfs is available now, try loading the public keys + * and default modules */ - /* rootfs is available now, try loading default modules */ + integrity_load_keys(); load_default_modules(); } diff --git a/security/integrity/iint.c b/security/integrity/iint.c index dbee618526b6..df45640fbac6 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -245,3 +245,14 @@ int __init integrity_read_file(const char *path, char **data) fput(file); return rc; } + +/* + * integrity_load_keys - load integrity keys hook + * + * Hooks is called from init/main.c:kernel_init_freeable() + * when rootfs is ready + */ +void __init integrity_load_keys(void) +{ + ima_load_x509(); +} -- GitLab From c57782c13ecd7e7aca66cbf0139ad2a72317dc81 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:16 +0200 Subject: [PATCH 5132/9457] ima: require signature based appraisal This patch provides CONFIG_IMA_APPRAISE_SIGNED_INIT kernel configuration option to force IMA appraisal using signatures. This is useful, when EVM key is not initialized yet and we want securely initialize integrity or any other functionality. It forces embedded policy to require signature. Signed initialization script can initialize EVM key, update the IMA policy and change further requirement of everything to be signed. Changes in v3: * kernel parameter fixed to configuration option in the patch description Changes in v2: * policy change of this patch separated from the key loading patch Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- security/integrity/ima/Kconfig | 7 +++++++ security/integrity/ima/ima_policy.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index b0840f9a552f..b80a93ec1ccc 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -149,3 +149,10 @@ config IMA_X509_PATH default "/etc/keys/x509_ima.der" help This option defines IMA X509 certificate path. + +config IMA_APPRAISE_SIGNED_INIT + bool "Require signed user-space initialization" + depends on IMA_LOAD_X509 + default n + help + This option requires user-space init to be signed. diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 0d14d2591805..d1eefb9d65fb 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -100,7 +100,13 @@ static struct ima_rule_entry default_appraise_rules[] = { {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, +#ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, +#else + /* force signature */ + {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, + .flags = IMA_FOWNER | IMA_DIGSIG_REQUIRED}, +#endif }; static LIST_HEAD(ima_default_rules); -- GitLab From 6fb5032ebb1c5b852461d64ee33829081de8ca61 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 5 Nov 2014 17:01:17 +0200 Subject: [PATCH 5133/9457] VFS: refactor vfs_read() integrity_kernel_read() duplicates the file read operations code in vfs_read(). This patch refactors vfs_read() code creating a helper function __vfs_read(). It is used by both vfs_read() and integrity_kernel_read(). Signed-off-by: Dmitry Kasatkin Signed-off-by: Mimi Zohar --- fs/read_write.c | 24 ++++++++++++++++++------ include/linux/fs.h | 1 + security/integrity/iint.c | 10 +++------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 009d8542a889..f45b2ae5d5f1 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -412,6 +412,23 @@ ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *p EXPORT_SYMBOL(new_sync_read); +ssize_t __vfs_read(struct file *file, char __user *buf, size_t count, + loff_t *pos) +{ + ssize_t ret; + + if (file->f_op->read) + ret = file->f_op->read(file, buf, count, pos); + else if (file->f_op->aio_read) + ret = do_sync_read(file, buf, count, pos); + else if (file->f_op->read_iter) + ret = new_sync_read(file, buf, count, pos); + else + ret = -EINVAL; + + return ret; +} + ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; @@ -426,12 +443,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) ret = rw_verify_area(READ, file, pos, count); if (ret >= 0) { count = ret; - if (file->f_op->read) - ret = file->f_op->read(file, buf, count, pos); - else if (file->f_op->aio_read) - ret = do_sync_read(file, buf, count, pos); - else - ret = new_sync_read(file, buf, count, pos); + ret = __vfs_read(file, buf, count, pos); if (ret > 0) { fsnotify_access(file); add_rchar(current, ret); diff --git a/include/linux/fs.h b/include/linux/fs.h index e11d60cc867b..ac3a36e05da9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1527,6 +1527,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec *fast_pointer, struct iovec **ret_pointer); +extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t vfs_readv(struct file *, const struct iovec __user *, diff --git a/security/integrity/iint.c b/security/integrity/iint.c index df45640fbac6..dbb6d141c3db 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -184,20 +184,16 @@ int integrity_kernel_read(struct file *file, loff_t offset, { mm_segment_t old_fs; char __user *buf = (char __user *)addr; - ssize_t ret = -EINVAL; + ssize_t ret; if (!(file->f_mode & FMODE_READ)) return -EBADF; old_fs = get_fs(); set_fs(get_ds()); - if (file->f_op->read) - ret = file->f_op->read(file, buf, count, &offset); - else if (file->f_op->aio_read) - ret = do_sync_read(file, buf, count, &offset); - else if (file->f_op->read_iter) - ret = new_sync_read(file, buf, count, &offset); + ret = __vfs_read(file, buf, count, &offset); set_fs(old_fs); + return ret; } -- GitLab From 76727c02c1e14a2b561b806fa1d08acc1619ad27 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 18 Nov 2014 09:00:14 +0200 Subject: [PATCH 5134/9457] Bluetooth: Call drain_workqueue() before resetting state Doing things like hci_conn_hash_flush() while holding the hdev lock is risky since its synchronous pending work cancellation could cause the L2CAP layer to try to reacquire the hdev lock. Right now there doesn't seem to be any obvious places where this would for certain happen but it's already enough to cause lockdep to start warning against the hdev and the work struct locks being taken in the "wrong" order: [ +0.000373] mgmt-tester/1603 is trying to acquire lock: [ +0.000292] ((&conn->pending_rx_work)){+.+.+.}, at: [] flush_work+0x0/0x181 [ +0.000270] but task is already holding lock: [ +0.000000] (&hdev->lock){+.+.+.}, at: [] hci_dev_do_close+0x166/0x359 [ +0.000000] which lock already depends on the new lock. [ +0.000000] the existing dependency chain (in reverse order) is: [ +0.000000] -> #1 (&hdev->lock){+.+.+.}: [ +0.000000] [] lock_acquire+0xe3/0x156 [ +0.000000] [] mutex_lock_nested+0x54/0x375 [ +0.000000] [] l2cap_recv_frame+0x293/0x1a9c [ +0.000000] [] process_pending_rx+0x50/0x5e [ +0.000000] [] process_one_work+0x21c/0x436 [ +0.000000] [] worker_thread+0x1be/0x251 [ +0.000000] [] kthread+0x94/0x99 [ +0.000000] [] ret_from_kernel_thread+0x21/0x30 [ +0.000000] -> #0 ((&conn->pending_rx_work)){+.+.+.}: [ +0.000000] [] __lock_acquire+0xa07/0xc89 [ +0.000000] [] lock_acquire+0xe3/0x156 [ +0.000000] [] flush_work+0x29/0x181 [ +0.000000] [] __cancel_work_timer+0x76/0x8f [ +0.000000] [] cancel_work_sync+0xf/0x11 [ +0.000000] [] l2cap_conn_del+0x72/0x183 [ +0.000000] [] l2cap_disconn_cfm+0x49/0x55 [ +0.000000] [] hci_conn_hash_flush+0x7a/0xc3 [ +0.000000] [] hci_dev_do_close+0x1dc/0x359 [ +0.012038] [] hci_unregister_dev+0x6e/0x1a3 [ +0.000000] [] vhci_release+0x28/0x47 [ +0.000000] [] __fput+0xd6/0x154 [ +0.000000] [] ____fput+0xd/0xf [ +0.000000] [] task_work_run+0x6b/0x8d [ +0.000000] [] do_notify_resume+0x3c/0x3f [ +0.000000] [] work_notifysig+0x29/0x31 [ +0.000000] other info that might help us debug this: [ +0.000000] Possible unsafe locking scenario: [ +0.000000] CPU0 CPU1 [ +0.000000] ---- ---- [ +0.000000] lock(&hdev->lock); [ +0.000000] lock((&conn->pending_rx_work)); [ +0.000000] lock(&hdev->lock); [ +0.000000] lock((&conn->pending_rx_work)); [ +0.000000] *** DEADLOCK *** Fully fixing this would require some quite heavy refactoring to change how the hdev lock and hci_conn instances are handled together. A simpler solution for now which this patch takes is to try ensure that the hdev workqueue is empty before proceeding with the various cleanup calls, including hci_conn_hash_flush(). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bbefb4eea36e..d786958a1dec 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2561,6 +2561,11 @@ static int hci_dev_do_close(struct hci_dev *hdev) if (test_bit(HCI_MGMT, &hdev->dev_flags)) cancel_delayed_work_sync(&hdev->rpa_expired); + /* Avoid potential lockdep warnings from the *_flush() calls by + * ensuring the workqueue is empty up front. + */ + drain_workqueue(hdev->workqueue); + hci_dev_lock(hdev); hci_inquiry_cache_flush(hdev); hci_pend_le_actions_clear(hdev); @@ -2684,6 +2689,11 @@ int hci_dev_reset(__u16 dev) skb_queue_purge(&hdev->rx_q); skb_queue_purge(&hdev->cmd_q); + /* Avoid potential lockdep warnings from the *_flush() calls by + * ensuring the workqueue is empty up front. + */ + drain_workqueue(hdev->workqueue); + hci_dev_lock(hdev); hci_inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); -- GitLab From a86c02ea38c53b695209b1181f9e2e18d73eb4e8 Mon Sep 17 00:00:00 2001 From: Fabio K Date: Tue, 18 Nov 2014 00:46:28 -0200 Subject: [PATCH 5135/9457] Bluetooth: Add support for Broadcom BCM20702A1 variant This variant requires the flag BTUSB_BCM_PATCHRAM to work. Relevant details from /sys/kernel/debug/usb/devices: T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3404 Rev= 1.12 S: Manufacturer=Broadcom Corp S: Product=BCM20702A0 S: SerialNumber=240A646F1XXX C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) The firmware was extracted from a Windows 8.1 64-bit installation and converted from 'hex' to 'hcd' for use in Linux. Under Windows it also identifies itself as BCM20702A0, but the firmware is named "BCM20702A1_001.002.014.1315.1356.hex" and is located in "%SYSTEMROOT%\system32\drivers\" (md5 67cf6bfdae61c4bb819a66da984f7913) (sha1 5f74cc6a9a3bf19ee0f8c3d01e4be34c609b188f) The same firmware file is also available as a download at http://www.asrock.com/mb/Intel/Z87E-ITX/?cat=Download&os=All marked as "Bluetooth driver ver:12.0.0.7820" 'hcd' file should be placed at "brcm/BCM20702A0-13d3-3404.hcd" inside the firmware directory (e.g. "/lib/firmware") Signed-off-by: Fabio K Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cd634f3b76d3..7c13d7a8d83c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -106,6 +106,8 @@ static const struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0b05, 0x17b5) }, { USB_DEVICE(0x0b05, 0x17cb) }, { USB_DEVICE(0x413c, 0x8197) }, + { USB_DEVICE(0x13d3, 0x3404), + .driver_info = BTUSB_BCM_PATCHRAM }, /* Foxconn - Hon Hai */ { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) }, -- GitLab From 0f060deb5c5107486c5dadd5c715b3693d381e0a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:50 -0500 Subject: [PATCH 5136/9457] cgroup: separate out cgroup_calc_child_subsys_mask() from cgroup_refresh_child_subsys_mask() cgroup_refresh_child_subsys_mask() calculates and updates the effective @cgrp->child_subsys_maks according to the current @cgrp->subtree_control. Separate out the calculation part into cgroup_calc_child_subsys_mask(). This will be used to fix a bug in the async css offline wait logic. Signed-off-by: Tejun Heo Acked-by: Zefan Li --- kernel/cgroup.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 136eceadeed1..1dda601ec337 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1019,31 +1019,30 @@ static void cgroup_put(struct cgroup *cgrp) } /** - * cgroup_refresh_child_subsys_mask - update child_subsys_mask + * cgroup_calc_child_subsys_mask - calculate child_subsys_mask * @cgrp: the target cgroup + * @subtree_control: the new subtree_control mask to consider * * On the default hierarchy, a subsystem may request other subsystems to be * enabled together through its ->depends_on mask. In such cases, more * subsystems than specified in "cgroup.subtree_control" may be enabled. * - * This function determines which subsystems need to be enabled given the - * current @cgrp->subtree_control and records it in - * @cgrp->child_subsys_mask. The resulting mask is always a superset of - * @cgrp->subtree_control and follows the usual hierarchy rules. + * This function calculates which subsystems need to be enabled if + * @subtree_control is to be applied to @cgrp. The returned mask is always + * a superset of @subtree_control and follows the usual hierarchy rules. */ -static void cgroup_refresh_child_subsys_mask(struct cgroup *cgrp) +static unsigned int cgroup_calc_child_subsys_mask(struct cgroup *cgrp, + unsigned int subtree_control) { struct cgroup *parent = cgroup_parent(cgrp); - unsigned int cur_ss_mask = cgrp->subtree_control; + unsigned int cur_ss_mask = subtree_control; struct cgroup_subsys *ss; int ssid; lockdep_assert_held(&cgroup_mutex); - if (!cgroup_on_dfl(cgrp)) { - cgrp->child_subsys_mask = cur_ss_mask; - return; - } + if (!cgroup_on_dfl(cgrp)) + return cur_ss_mask; while (true) { unsigned int new_ss_mask = cur_ss_mask; @@ -1067,7 +1066,20 @@ static void cgroup_refresh_child_subsys_mask(struct cgroup *cgrp) cur_ss_mask = new_ss_mask; } - cgrp->child_subsys_mask = cur_ss_mask; + return cur_ss_mask; +} + +/** + * cgroup_refresh_child_subsys_mask - update child_subsys_mask + * @cgrp: the target cgroup + * + * Update @cgrp->child_subsys_mask according to the current + * @cgrp->subtree_control using cgroup_calc_child_subsys_mask(). + */ +static void cgroup_refresh_child_subsys_mask(struct cgroup *cgrp) +{ + cgrp->child_subsys_mask = + cgroup_calc_child_subsys_mask(cgrp, cgrp->subtree_control); } /** -- GitLab From 755bf5ee8633b97d8fd0ffbb4221662056dda22b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:50 -0500 Subject: [PATCH 5137/9457] cgroup: restructure child_subsys_mask handling in cgroup_subtree_control_write() Make cgroup_subtree_control_write() first calculate new subtree_control (new_sc), child_subsys_mask (new_ss) and css_enable/disable masks before applying them to the cgroup. Also, store the original subtree_control (old_sc) and child_subsys_mask (old_ss) and use them to restore the orignal state after failure. This patch shouldn't cause any behavior changes. This prepares for a fix for a bug in the async css offline wait logic. Signed-off-by: Tejun Heo Acked-by: Zefan Li --- kernel/cgroup.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 1dda601ec337..cbbb46f783de 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2653,7 +2653,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, loff_t off) { unsigned int enable = 0, disable = 0; - unsigned int css_enable, css_disable, old_ctrl, new_ctrl; + unsigned int css_enable, css_disable, old_sc, new_sc, old_ss, new_ss; struct cgroup *cgrp, *child; struct cgroup_subsys *ss; char *tok; @@ -2770,18 +2770,19 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, * subsystems than specified may need to be enabled or disabled * depending on subsystem dependencies. */ - cgrp->subtree_control |= enable; - cgrp->subtree_control &= ~disable; + old_sc = cgrp->subtree_control; + old_ss = cgrp->child_subsys_mask; + new_sc = (old_sc | enable) & ~disable; + new_ss = cgroup_calc_child_subsys_mask(cgrp, new_sc); - old_ctrl = cgrp->child_subsys_mask; - cgroup_refresh_child_subsys_mask(cgrp); - new_ctrl = cgrp->child_subsys_mask; - - css_enable = ~old_ctrl & new_ctrl; - css_disable = old_ctrl & ~new_ctrl; + css_enable = ~old_ss & new_ss; + css_disable = old_ss & ~new_ss; enable |= css_enable; disable |= css_disable; + cgrp->subtree_control = new_sc; + cgrp->child_subsys_mask = new_ss; + /* * Create new csses or make the existing ones visible. A css is * created invisible if it's being implicitly enabled through @@ -2844,9 +2845,8 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, return ret ?: nbytes; err_undo_css: - cgrp->subtree_control &= ~enable; - cgrp->subtree_control |= disable; - cgroup_refresh_child_subsys_mask(cgrp); + cgrp->subtree_control = old_sc; + cgrp->child_subsys_mask = old_ss; for_each_subsys(ss, ssid) { if (!(enable & (1 << ssid))) -- GitLab From db6e3053456800f0a7220b30355bece64764efe7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:51 -0500 Subject: [PATCH 5138/9457] cgroup: fix the async css offline wait logic in cgroup_subtree_control_write() When a subsystem is offlined, its entry on @cgrp->subsys[] is cleared asynchronously. If cgroup_subtree_control_write() is requested to enable the subsystem again before the entry is cleared, it has to wait for the previous offlining to finish and clear the @cgrp->subsys[] entry before trying to enable the subsystem again. This is currently done while verifying the input enable / disable parameters. This used to be correct but f63070d350e3 ("cgroup: make interface files visible iff enabled on cgroup->subtree_control") breaks it. The commit is one of the commits implementing subsystem dependency. Through subsystem dependency, some subsystems may be enabled and disabled implicitly in addition to the explicitly requested ones. The actual subsystems to be enabled and disabled are determined during @css_enable/disable calculation. The current offline wait logic skips the ones which are already implicitly enabled and then waits for subsystems in @enable; however, this misses the subsystems which may be implicitly enabled through dependency from @enable. If such implicitly subsystem hasn't yet finished offlining yet, the function ends up trying to create a css when its @cgrp->subsys[] slot is already occupied triggering BUG_ON() in init_and_link_css(). Fix it by moving the wait logic after @css_enable is calculated and waiting for all the subsystems in @css_enable. This fixes the above bug as the mask contains all subsystems which are to be enabled including the ones enabled through dependencies. Signed-off-by: Tejun Heo Fixes: f63070d350e3 ("cgroup: make interface files visible iff enabled on cgroup->subtree_control") Acked-by: Zefan Li --- kernel/cgroup.c | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index cbbb46f783de..dffa54041d4a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2705,36 +2705,6 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, ret = -ENOENT; goto out_unlock; } - - /* - * @ss is already enabled through dependency and - * we'll just make it visible. Skip draining. - */ - if (cgrp->child_subsys_mask & (1 << ssid)) - continue; - - /* - * Because css offlining is asynchronous, userland - * might try to re-enable the same controller while - * the previous instance is still around. In such - * cases, wait till it's gone using offline_waitq. - */ - cgroup_for_each_live_child(child, cgrp) { - DEFINE_WAIT(wait); - - if (!cgroup_css(child, ss)) - continue; - - cgroup_get(child); - prepare_to_wait(&child->offline_waitq, &wait, - TASK_UNINTERRUPTIBLE); - cgroup_kn_unlock(of->kn); - schedule(); - finish_wait(&child->offline_waitq, &wait); - cgroup_put(child); - - return restart_syscall(); - } } else if (disable & (1 << ssid)) { if (!(cgrp->subtree_control & (1 << ssid))) { disable &= ~(1 << ssid); @@ -2780,6 +2750,34 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, enable |= css_enable; disable |= css_disable; + /* + * Because css offlining is asynchronous, userland might try to + * re-enable the same controller while the previous instance is + * still around. In such cases, wait till it's gone using + * offline_waitq. + */ + for_each_subsys(ss, ssid) { + if (!(css_enable & (1 << ssid))) + continue; + + cgroup_for_each_live_child(child, cgrp) { + DEFINE_WAIT(wait); + + if (!cgroup_css(child, ss)) + continue; + + cgroup_get(child); + prepare_to_wait(&child->offline_waitq, &wait, + TASK_UNINTERRUPTIBLE); + cgroup_kn_unlock(of->kn); + schedule(); + finish_wait(&child->offline_waitq, &wait); + cgroup_put(child); + + return restart_syscall(); + } + } + cgrp->subtree_control = new_sc; cgrp->child_subsys_mask = new_ss; -- GitLab From 7d172cc89b8589e4173d0c73a1ddaae408f29c9d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:51 -0500 Subject: [PATCH 5139/9457] cgroup: add cgroup_subsys->css_released() Add a new cgroup subsys callback css_released(). This is called when the reference count of the css (cgroup_subsys_state) reaches zero before RCU scheduling free. Signed-off-by: Tejun Heo Acked-by: Zefan Li --- include/linux/cgroup.h | 1 + kernel/cgroup.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 1d5196889048..e717a39f22ea 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -612,6 +612,7 @@ struct cgroup_subsys { struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css); int (*css_online)(struct cgroup_subsys_state *css); void (*css_offline)(struct cgroup_subsys_state *css); + void (*css_released)(struct cgroup_subsys_state *css); void (*css_free)(struct cgroup_subsys_state *css); void (*css_reset)(struct cgroup_subsys_state *css); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index dffa54041d4a..c8558693102b 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4380,6 +4380,8 @@ static void css_release_work_fn(struct work_struct *work) if (ss) { /* css release path */ cgroup_idr_remove(&ss->css_idr, css->id); + if (ss->css_released) + ss->css_released(css); } else { /* cgroup release path */ cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id); -- GitLab From 56c807ba4e91f0980567b6a69de239677879b17f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:51 -0500 Subject: [PATCH 5140/9457] cgroup: add cgroup_subsys->css_e_css_changed() Add a new cgroup_subsys operatoin ->css_e_css_changed(). This is invoked if any of the effective csses seen from the css's cgroup may have changed. This will be used to implement cgroup writeback support. Signed-off-by: Tejun Heo Acked-by: Zefan Li --- include/linux/cgroup.h | 1 + kernel/cgroup.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index e717a39f22ea..3a04aeb8b5a1 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -615,6 +615,7 @@ struct cgroup_subsys { void (*css_released)(struct cgroup_subsys_state *css); void (*css_free)(struct cgroup_subsys_state *css); void (*css_reset)(struct cgroup_subsys_state *css); + void (*css_e_css_changed)(struct cgroup_subsys_state *css); int (*can_attach)(struct cgroup_subsys_state *css, struct cgroup_taskset *tset); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index c8558693102b..69f033582a1a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2836,6 +2836,24 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, } } + /* + * The effective csses of all the descendants (excluding @cgrp) may + * have changed. Subsystems can optionally subscribe to this event + * by implementing ->css_e_css_changed() which is invoked if any of + * the effective csses seen from the css's cgroup may have changed. + */ + for_each_subsys(ss, ssid) { + struct cgroup_subsys_state *this_css = cgroup_css(cgrp, ss); + struct cgroup_subsys_state *css; + + if (!ss->css_e_css_changed || !this_css) + continue; + + css_for_each_descendant_pre(css, this_css) + if (css != this_css) + ss->css_e_css_changed(css); + } + kernfs_activate(cgrp->kn); ret = 0; out_unlock: -- GitLab From eeecbd1971517103e06f11750dd1a9a1dc37e4e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 18 Nov 2014 02:49:52 -0500 Subject: [PATCH 5141/9457] cgroup: implement cgroup_get_e_css() Implement cgroup_get_e_css() which finds and gets the effective css for the specified cgroup and subsystem combination. This function always returns a valid pinned css. This will be used by cgroup writeback support. While at it, add comment to cgroup_e_css() to explain why that function is different from cgroup_get_e_css() and has to test cgrp->child_subsys_mask instead of cgroup_css(cgrp, ss). Signed-off-by: Tejun Heo Acked-by: Zefan Li --- include/linux/cgroup.h | 2 ++ kernel/cgroup.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 3a04aeb8b5a1..9fd99f5e699f 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -910,6 +910,8 @@ void css_task_iter_end(struct css_task_iter *it); int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from); +struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgroup, + struct cgroup_subsys *ss); struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry, struct cgroup_subsys *ss); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 69f033582a1a..bb263d0caab3 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -277,6 +277,10 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp, if (!(cgrp->root->subsys_mask & (1 << ss->id))) return NULL; + /* + * This function is used while updating css associations and thus + * can't test the csses directly. Use ->child_subsys_mask. + */ while (cgroup_parent(cgrp) && !(cgroup_parent(cgrp)->child_subsys_mask & (1 << ss->id))) cgrp = cgroup_parent(cgrp); @@ -284,6 +288,39 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp, return cgroup_css(cgrp, ss); } +/** + * cgroup_get_e_css - get a cgroup's effective css for the specified subsystem + * @cgrp: the cgroup of interest + * @ss: the subsystem of interest + * + * Find and get the effective css of @cgrp for @ss. The effective css is + * defined as the matching css of the nearest ancestor including self which + * has @ss enabled. If @ss is not mounted on the hierarchy @cgrp is on, + * the root css is returned, so this function always returns a valid css. + * The returned css must be put using css_put(). + */ +struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgrp, + struct cgroup_subsys *ss) +{ + struct cgroup_subsys_state *css; + + rcu_read_lock(); + + do { + css = cgroup_css(cgrp, ss); + + if (css && css_tryget_online(css)) + goto out_unlock; + cgrp = cgroup_parent(cgrp); + } while (cgrp); + + css = init_css_set.subsys[ss->id]; + css_get(css); +out_unlock: + rcu_read_unlock(); + return css; +} + /* convenient tests for these bits */ static inline bool cgroup_is_dead(const struct cgroup *cgrp) { -- GitLab From 70b0ea86568fc91e29742010c5dcf4b5b5661939 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 18 Nov 2014 09:09:32 +0100 Subject: [PATCH 5142/9457] drm/i915: Drop return value from lrc_setup_hardware_status_page kmap never fails. Spotted-by: Chris Wilson Cc: Chris Wilson Cc: Arun Siluvery Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index b7c4c9ab9012..3cf15c4da0e8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1706,7 +1706,7 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) return ret; } -static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring, +static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, struct drm_i915_gem_object *default_ctx_obj) { struct drm_i915_private *dev_priv = ring->dev->dev_private; @@ -1716,15 +1716,11 @@ static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring, ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj); ring->status_page.page_addr = kmap(sg_page(default_ctx_obj->pages->sgl)); - if (ring->status_page.page_addr == NULL) - return -ENOMEM; ring->status_page.obj = default_ctx_obj; I915_WRITE(RING_HWS_PGA(ring->mmio_base), (u32)ring->status_page.gfx_addr); POSTING_READ(RING_HWS_PGA(ring->mmio_base)); - - return 0; } /** @@ -1811,13 +1807,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ctx->engine[ring->id].ringbuf = ringbuf; ctx->engine[ring->id].state = ctx_obj; - if (ctx == ring->default_context) { - ret = lrc_setup_hardware_status_page(ring, ctx_obj); - if (ret) { - DRM_ERROR("Failed to setup hardware status page\n"); - goto error; - } - } + if (ctx == ring->default_context) + lrc_setup_hardware_status_page(ring, ctx_obj); if (ring->id == RCS && !ctx->rcs_initialized) { if (ring->init_context) { -- GitLab From cbc572a9a5a90aac54ff1a5c7356b6f6bda78264 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 17 Nov 2014 13:08:47 -0800 Subject: [PATCH 5143/9457] drm/i915/ddi: add break in DDI mode select switch The lack of a break here wasn't for falling through to some other important code, so made me do a double take. Add a break just to make things a little less confusing. Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 86745da7b105..07c562598596 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2062,6 +2062,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, switch (temp & TRANS_DDI_MODE_SELECT_MASK) { case TRANS_DDI_MODE_SELECT_HDMI: pipe_config->has_hdmi_sink = true; + break; case TRANS_DDI_MODE_SELECT_DVI: case TRANS_DDI_MODE_SELECT_FDI: break; -- GitLab From e684fa34c3a28b4893d43629a02a765a2a71e63e Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 11 Nov 2014 03:15:03 +0000 Subject: [PATCH 5144/9457] i40e: only warn once of PTP nonsupport in 100Mbit speed Only warn once that PTP is not supported when linked at 100Mbit. Yes, using a static this way means that this once-only message is not port specific, but once only for the life of the driver, regardless of the number of ports. That should be plenty. Change-ID: Ie6476530056df408452e195ef06afd4f57caa4b2 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ptp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index 537b6216971d..f91510370c35 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c @@ -382,11 +382,17 @@ void i40e_ptp_set_increment(struct i40e_pf *pf) incval = I40E_PTP_1GB_INCVAL; break; case I40E_LINK_SPEED_100MB: - dev_warn(&pf->pdev->dev, - "%s: 1588 functionality is not supported at 100 Mbps. Stopping the PHC.\n", - __func__); + { + static int warn_once; + + if (!warn_once) { + dev_warn(&pf->pdev->dev, + "1588 functionality is not supported at 100 Mbps. Stopping the PHC.\n"); + warn_once++; + } incval = 0; break; + } case I40E_LINK_SPEED_40GB: default: incval = I40E_PTP_40GB_INCVAL; -- GitLab From c5c2f7c360af164448d87cb618af2ee5dad3a01a Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 03:15:04 +0000 Subject: [PATCH 5145/9457] i40e: re-enable VFLR interrupt sooner VF interrupt processing takes a looooong time, and it's possible that we could lose a VFLR event if it happens while we're processing a VFLR on another VF. This would leave the VF in a semi-permanent reset state, which would not be cleared until yet another VF experiences a VFLR. To correct this situation, we enable the VFLR interrupt cause before we begin processing any pending resets. This means that any VFLR that occurs during reset processing will generate another interrupt and this routine will get called again. This change may cause a spurious interrupt when multiple VFLRs occur very close together in time. If this happens, then this routine will be called again and it will detect no outstanding VFLR events and do nothing. No harm, no foul. Change-ID: Id0451f3e6e73a2cf6db1668296c71e129b59dc19 Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index fff3c276736b..668d860275d6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -1869,6 +1869,12 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) if (!test_bit(__I40E_VFLR_EVENT_PENDING, &pf->state)) return 0; + /* re-enable vflr interrupt cause */ + reg = rd32(hw, I40E_PFINT_ICR0_ENA); + reg |= I40E_PFINT_ICR0_ENA_VFLR_MASK; + wr32(hw, I40E_PFINT_ICR0_ENA, reg); + i40e_flush(hw); + clear_bit(__I40E_VFLR_EVENT_PENDING, &pf->state); for (vf_id = 0; vf_id < pf->num_alloc_vfs; vf_id++) { reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32; @@ -1885,12 +1891,6 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf) } } - /* re-enable vflr interrupt cause */ - reg = rd32(hw, I40E_PFINT_ICR0_ENA); - reg |= I40E_PFINT_ICR0_ENA_VFLR_MASK; - wr32(hw, I40E_PFINT_ICR0_ENA, reg); - i40e_flush(hw); - return 0; } -- GitLab From 7bda87c7fb2eaab8e144d6d0a2638099d7b6e5f5 Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Tue, 11 Nov 2014 03:15:06 +0000 Subject: [PATCH 5146/9457] i40e: Bump version to 1.1.23 Bumping minor version as this will be the second SW release and it should be 1. Change-ID: If0bd102095d2f059ae0c9b7f4ad625535ffbbdee Signed-off-by: Catherine Sullivan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a0bee83ab2de..68c19c87ebed 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -38,8 +38,8 @@ static const char i40e_driver_string[] = #define DRV_KERN "-k" #define DRV_VERSION_MAJOR 1 -#define DRV_VERSION_MINOR 0 -#define DRV_VERSION_BUILD 21 +#define DRV_VERSION_MINOR 1 +#define DRV_VERSION_BUILD 23 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN -- GitLab From 2fd75f31f6bacaed38061f95f0fee26de3e01170 Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:20 +0000 Subject: [PATCH 5147/9457] i40e: Resume Port Tx after DCB event When there are DCB configuration changes based on DCBX the firmware suspends the port's Tx and generates an event to the PF. The PF is then responsible to reconfigure the PF VSIs and switching topology as per the updated DCB configuration and then resume the port's Tx by calling the "Resume Port Tx" AQ command. This patch adds this call to the flow that handles DCB re-configuration in the PF. Change-ID: I5b860ad48abfbf379b003143c4d3453e2ed5cc1c Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 20 ++++++++++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 31 ++++++++++++++++++- .../net/ethernet/intel/i40e/i40e_prototype.h | 2 ++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index c49416cfe616..76735d5f34eb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -3216,6 +3216,26 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw, return status; } +/** + * i40e_aq_resume_port_tx + * @hw: pointer to the hardware structure + * @cmd_details: pointer to command details structure or NULL + * + * Resume port's Tx traffic + **/ +i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + i40e_status status; + + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx); + + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); + + return status; +} + /** * i40e_set_pci_config_data - store PCI bus info * @hw: pointer to hardware structure diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 68c19c87ebed..185f977e8a98 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4381,6 +4381,31 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf) } } +/** + * i40e_resume_port_tx - Resume port Tx + * @pf: PF struct + * + * Resume a port's Tx and issue a PF reset in case of failure to + * resume. + **/ +static int i40e_resume_port_tx(struct i40e_pf *pf) +{ + struct i40e_hw *hw = &pf->hw; + int ret; + + ret = i40e_aq_resume_port_tx(hw, NULL); + if (ret) { + dev_info(&pf->pdev->dev, + "AQ command Resume Port Tx failed = %d\n", + pf->hw.aq.asq_last_status); + /* Schedule PF reset to recover */ + set_bit(__I40E_PF_RESET_REQUESTED, &pf->state); + i40e_service_event_schedule(pf); + } + + return ret; +} + /** * i40e_init_pf_dcb - Initialize DCB configuration * @pf: PF being configured @@ -5075,7 +5100,11 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, /* Changes in configuration update VEB/VSI */ i40e_dcb_reconfigure(pf); - i40e_pf_unquiesce_all_vsi(pf); + ret = i40e_resume_port_tx(pf); + + /* In case of error no point in resuming VSIs */ + if (!ret) + i40e_pf_unquiesce_all_vsi(pf); exit: return ret; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 246c27869a63..98a735cdf038 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -230,6 +230,8 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw, u16 seid, struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data, struct i40e_asq_cmd_details *cmd_details); +i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, + struct i40e_asq_cmd_details *cmd_details); /* i40e_common */ i40e_status i40e_init_shared_code(struct i40e_hw *hw); i40e_status i40e_pf_reset(struct i40e_hw *hw); -- GitLab From 9fa61dd2153a4ff3a57891d4866a2595eb9ac81a Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:25 +0000 Subject: [PATCH 5148/9457] i40e: Add support to firmware CEE DCBX mode This patch allows i40e driver to query and use DCB configuration from firmware when firmware DCBX agent is in CEE mode. Change-ID: I30f92a67eb890f0f024f35339696e6e83d49a274 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/i40e/i40e_adminq_cmd.h | 45 +++- drivers/net/ethernet/intel/i40e/i40e_common.c | 28 +++ drivers/net/ethernet/intel/i40e/i40e_dcb.c | 203 +++++++++++++++++- drivers/net/ethernet/intel/i40e/i40e_dcb.h | 5 + drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c | 8 +- .../net/ethernet/intel/i40e/i40e_debugfs.c | 2 + drivers/net/ethernet/intel/i40e/i40e_fcoe.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 26 ++- .../net/ethernet/intel/i40e/i40e_prototype.h | 3 + drivers/net/ethernet/intel/i40e/i40e_type.h | 41 ++-- 10 files changed, 328 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index a65bc4398971..8835aeeff23e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -255,6 +255,7 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_lldp_delete_tlv = 0x0A04, i40e_aqc_opc_lldp_stop = 0x0A05, i40e_aqc_opc_lldp_start = 0x0A06, + i40e_aqc_opc_get_cee_dcb_cfg = 0x0A07, /* Tunnel commands */ i40e_aqc_opc_add_udp_tunnel = 0x0B00, @@ -1987,10 +1988,50 @@ struct i40e_aqc_lldp_start { I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); -/* Apply MIB changes (0x0A07) - * uses the generic struc as it contains no data +/* Get CEE DCBX Oper Config (0x0A07) + * uses the generic descriptor struct + * returns below as indirect response */ +#define I40E_AQC_CEE_APP_FCOE_SHIFT 0x0 +#define I40E_AQC_CEE_APP_FCOE_MASK (0x7 << I40E_AQC_CEE_APP_FCOE_SHIFT) +#define I40E_AQC_CEE_APP_ISCSI_SHIFT 0x3 +#define I40E_AQC_CEE_APP_ISCSI_MASK (0x7 << I40E_AQC_CEE_APP_ISCSI_SHIFT) +#define I40E_AQC_CEE_APP_FIP_SHIFT 0x8 +#define I40E_AQC_CEE_APP_FIP_MASK (0x7 << I40E_AQC_CEE_APP_FIP_SHIFT) +#define I40E_AQC_CEE_PG_STATUS_SHIFT 0x0 +#define I40E_AQC_CEE_PG_STATUS_MASK (0x7 << I40E_AQC_CEE_PG_STATUS_SHIFT) +#define I40E_AQC_CEE_PFC_STATUS_SHIFT 0x3 +#define I40E_AQC_CEE_PFC_STATUS_MASK (0x7 << I40E_AQC_CEE_PFC_STATUS_SHIFT) +#define I40E_AQC_CEE_APP_STATUS_SHIFT 0x8 +#define I40E_AQC_CEE_APP_STATUS_MASK (0x7 << I40E_AQC_CEE_APP_STATUS_SHIFT) +struct i40e_aqc_get_cee_dcb_cfg_v1_resp { + u8 reserved1; + u8 oper_num_tc; + u8 oper_prio_tc[4]; + u8 reserved2; + u8 oper_tc_bw[8]; + u8 oper_pfc_en; + u8 reserved3; + __le16 oper_app_prio; + u8 reserved4; + __le16 tlv_status; +}; + +I40E_CHECK_STRUCT_LEN(0x18, i40e_aqc_get_cee_dcb_cfg_v1_resp); + +struct i40e_aqc_get_cee_dcb_cfg_resp { + u8 oper_num_tc; + u8 oper_prio_tc[4]; + u8 oper_tc_bw[8]; + u8 oper_pfc_en; + __le16 oper_app_prio; + __le32 tlv_status; + u8 reserved[12]; +}; + +I40E_CHECK_STRUCT_LEN(0x20, i40e_aqc_get_cee_dcb_cfg_resp); + /* Add Udp Tunnel command and completion (direct 0x0B00) */ struct i40e_aqc_add_udp_tunnel { __le16 udp_port; diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 76735d5f34eb..b601b3cfd92b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -2659,6 +2659,34 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, return status; } +/** + * i40e_aq_get_cee_dcb_config + * @hw: pointer to the hw struct + * @buff: response buffer that stores CEE operational configuration + * @buff_size: size of the buffer passed + * @cmd_details: pointer to command details structure or NULL + * + * Get CEE DCBX mode operational configuration from firmware + **/ +i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw, + void *buff, u16 buff_size, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + i40e_status status; + + if (buff_size == 0 || !buff) + return I40E_ERR_PARAM; + + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg); + + desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF); + status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size, + cmd_details); + + return status; +} + /** * i40e_aq_add_udp_tunnel * @hw: pointer to the hw struct diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c index 036570d76176..1396c70b871c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c @@ -59,7 +59,7 @@ i40e_status i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status) static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv, struct i40e_dcbx_config *dcbcfg) { - struct i40e_ieee_ets_config *etscfg; + struct i40e_dcb_ets_config *etscfg; u8 *buf = tlv->tlvinfo; u16 offset = 0; u8 priority; @@ -406,6 +406,166 @@ i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type, return ret; } +/** + * i40e_cee_to_dcb_v1_config + * @cee_cfg: pointer to CEE v1 response configuration struct + * @dcbcfg: DCB configuration struct + * + * Convert CEE v1 configuration from firmware to DCB configuration + **/ +static void i40e_cee_to_dcb_v1_config( + struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg, + struct i40e_dcbx_config *dcbcfg) +{ + u16 status, tlv_status = le16_to_cpu(cee_cfg->tlv_status); + u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio); + u8 i, tc, err, sync, oper; + + /* CEE PG data to ETS config */ + dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc; + + for (i = 0; i < 4; i++) { + tc = (u8)((cee_cfg->oper_prio_tc[i] & + I40E_CEE_PGID_PRIO_1_MASK) >> + I40E_CEE_PGID_PRIO_1_SHIFT); + dcbcfg->etscfg.prioritytable[i*2] = tc; + tc = (u8)((cee_cfg->oper_prio_tc[i] & + I40E_CEE_PGID_PRIO_0_MASK) >> + I40E_CEE_PGID_PRIO_0_SHIFT); + dcbcfg->etscfg.prioritytable[i*2 + 1] = tc; + } + + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) + dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i]; + + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { + if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) { + /* Map it to next empty TC */ + dcbcfg->etscfg.prioritytable[i] = + cee_cfg->oper_num_tc - 1; + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT; + } else { + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS; + } + } + + /* CEE PFC data to ETS config */ + dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en; + dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS; + + status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >> + I40E_AQC_CEE_APP_STATUS_SHIFT; + err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0; + sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0; + oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0; + /* Add APPs if Error is False and Oper/Sync is True */ + if (!err && sync && oper) { + /* CEE operating configuration supports FCoE/iSCSI/FIP only */ + dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS; + + /* FCoE APP */ + dcbcfg->app[0].priority = + (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >> + I40E_AQC_CEE_APP_FCOE_SHIFT; + dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE; + dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE; + + /* iSCSI APP */ + dcbcfg->app[1].priority = + (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >> + I40E_AQC_CEE_APP_ISCSI_SHIFT; + dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP; + dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI; + + /* FIP APP */ + dcbcfg->app[2].priority = + (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >> + I40E_AQC_CEE_APP_FIP_SHIFT; + dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE; + dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP; + } +} + +/** + * i40e_cee_to_dcb_config + * @cee_cfg: pointer to CEE configuration struct + * @dcbcfg: DCB configuration struct + * + * Convert CEE configuration from firmware to DCB configuration + **/ +static void i40e_cee_to_dcb_config( + struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg, + struct i40e_dcbx_config *dcbcfg) +{ + u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status); + u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio); + u8 i, tc, err, sync, oper; + + /* CEE PG data to ETS config */ + dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc; + + for (i = 0; i < 4; i++) { + tc = (u8)((cee_cfg->oper_prio_tc[i] & + I40E_CEE_PGID_PRIO_1_MASK) >> + I40E_CEE_PGID_PRIO_1_SHIFT); + dcbcfg->etscfg.prioritytable[i*2] = tc; + tc = (u8)((cee_cfg->oper_prio_tc[i] & + I40E_CEE_PGID_PRIO_0_MASK) >> + I40E_CEE_PGID_PRIO_0_SHIFT); + dcbcfg->etscfg.prioritytable[i*2 + 1] = tc; + } + + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) + dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i]; + + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { + if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) { + /* Map it to next empty TC */ + dcbcfg->etscfg.prioritytable[i] = + cee_cfg->oper_num_tc - 1; + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT; + } else { + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS; + } + } + + /* CEE PFC data to ETS config */ + dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en; + dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS; + + status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >> + I40E_AQC_CEE_APP_STATUS_SHIFT; + err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0; + sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0; + oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0; + /* Add APPs if Error is False and Oper/Sync is True */ + if (!err && sync && oper) { + /* CEE operating configuration supports FCoE/iSCSI/FIP only */ + dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS; + + /* FCoE APP */ + dcbcfg->app[0].priority = + (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >> + I40E_AQC_CEE_APP_FCOE_SHIFT; + dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE; + dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE; + + /* iSCSI APP */ + dcbcfg->app[1].priority = + (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >> + I40E_AQC_CEE_APP_ISCSI_SHIFT; + dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP; + dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI; + + /* FIP APP */ + dcbcfg->app[2].priority = + (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >> + I40E_AQC_CEE_APP_FIP_SHIFT; + dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE; + dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP; + } +} + /** * i40e_get_dcb_config * @hw: pointer to the hw struct @@ -415,7 +575,44 @@ i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type, i40e_status i40e_get_dcb_config(struct i40e_hw *hw) { i40e_status ret = 0; + struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg; + struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg; + + /* If Firmware version < v4.33 IEEE only */ + if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) || + (hw->aq.fw_maj_ver < 4)) + goto ieee; + + /* If Firmware version == v4.33 use old CEE struct */ + if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) { + ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg, + sizeof(cee_v1_cfg), NULL); + if (!ret) { + /* CEE mode */ + hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE; + i40e_cee_to_dcb_v1_config(&cee_v1_cfg, + &hw->local_dcbx_config); + } + } else { + ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg, + sizeof(cee_cfg), NULL); + if (!ret) { + /* CEE mode */ + hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE; + i40e_cee_to_dcb_config(&cee_cfg, + &hw->local_dcbx_config); + } + } + + /* CEE mode not enabled try querying IEEE data */ + if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) + goto ieee; + else + goto out; +ieee: + /* IEEE mode */ + hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE; /* Get Local DCB Config */ ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0, &hw->local_dcbx_config); @@ -426,6 +623,10 @@ i40e_status i40e_get_dcb_config(struct i40e_hw *hw) ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE, I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE, &hw->remote_dcbx_config); + /* Don't treat ENOENT as an error for Remote MIBs */ + if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) + ret = 0; + out: return ret; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.h b/drivers/net/ethernet/intel/i40e/i40e_dcb.h index 34cf1c30c7ff..e137e3fac8ee 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb.h +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.h @@ -65,6 +65,11 @@ #define I40E_IEEE_ETS_PRIO_0_MASK (0x7 << I40E_IEEE_ETS_PRIO_0_SHIFT) #define I40E_IEEE_ETS_PRIO_1_SHIFT 4 #define I40E_IEEE_ETS_PRIO_1_MASK (0x7 << I40E_IEEE_ETS_PRIO_1_SHIFT) +#define I40E_CEE_PGID_PRIO_0_SHIFT 0 +#define I40E_CEE_PGID_PRIO_0_MASK (0xF << I40E_CEE_PGID_PRIO_0_SHIFT) +#define I40E_CEE_PGID_PRIO_1_SHIFT 4 +#define I40E_CEE_PGID_PRIO_1_MASK (0xF << I40E_CEE_PGID_PRIO_1_SHIFT) +#define I40E_CEE_PGID_STRICT 15 /* Defines for IEEE TSA types */ #define I40E_IEEE_TSA_STRICT 0 diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c index 00bc0cdb3a03..183dcb63ce98 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c @@ -207,7 +207,7 @@ void i40e_dcbnl_set_all(struct i40e_vsi *vsi) * VSI **/ static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi, - struct i40e_ieee_app_priority_table *app) + struct i40e_dcb_app_priority_table *app) { struct net_device *dev = vsi->netdev; struct dcb_app sapp; @@ -229,7 +229,7 @@ static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi, * Delete given APP from all the VSIs for given PF **/ static void i40e_dcbnl_del_app(struct i40e_pf *pf, - struct i40e_ieee_app_priority_table *app) + struct i40e_dcb_app_priority_table *app) { int v, err; for (v = 0; v < pf->num_alloc_vsi; v++) { @@ -252,7 +252,7 @@ static void i40e_dcbnl_del_app(struct i40e_pf *pf, * Find given APP in the DCB configuration **/ static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg, - struct i40e_ieee_app_priority_table *app) + struct i40e_dcb_app_priority_table *app) { int i; @@ -277,7 +277,7 @@ static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg, void i40e_dcbnl_flush_apps(struct i40e_pf *pf, struct i40e_dcbx_config *new_cfg) { - struct i40e_ieee_app_priority_table app; + struct i40e_dcb_app_priority_table app; struct i40e_dcbx_config *dcbxcfg; struct i40e_hw *hw = &pf->hw; int i; diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index a03f4590cb0f..3a3c237b76d4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -1312,6 +1312,8 @@ static ssize_t i40e_dbg_command_write(struct file *filp, kfree(bw_data); bw_data = NULL; + dev_info(&pf->pdev->dev, + "port dcbx_mode=%d\n", cfg->dcbx_mode); dev_info(&pf->pdev->dev, "port ets_cfg: willing=%d cbs=%d, maxtcs=%d\n", cfg->etscfg.willing, cfg->etscfg.cbs, diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c index 5d01db1d789b..a8b8bd95108d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c +++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c @@ -343,7 +343,7 @@ int i40e_init_pf_fcoe(struct i40e_pf *pf) **/ u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf) { - struct i40e_ieee_app_priority_table app; + struct i40e_dcb_app_priority_table app; struct i40e_hw *hw = &pf->hw; u8 enabled_tc = 0; u8 tc, i; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 185f977e8a98..99b985cb53d5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4442,6 +4442,8 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf) /* Enable DCB tagging only when more than one TC */ if (i40e_dcb_get_num_tc(&hw->local_dcbx_config) > 1) pf->flags |= I40E_FLAG_DCB_ENABLED; + dev_dbg(&pf->pdev->dev, + "DCBX offload is supported for this PF.\n"); } } else { dev_info(&pf->pdev->dev, "AQ Querying DCB configuration failed: %d\n", @@ -5023,6 +5025,8 @@ bool i40e_dcb_need_reconfig(struct i40e_pf *pf, dev_dbg(&pf->pdev->dev, "APP Table change detected.\n"); } + dev_dbg(&pf->pdev->dev, "%s: need_reconfig=%d\n", __func__, + need_reconfig); return need_reconfig; } @@ -5050,11 +5054,16 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, /* Ignore if event is not for Nearest Bridge */ type = ((mib->type >> I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) & I40E_AQ_LLDP_BRIDGE_TYPE_MASK); + dev_dbg(&pf->pdev->dev, + "%s: LLDP event mib bridge type 0x%x\n", __func__, type); if (type != I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE) return ret; /* Check MIB Type and return if event for Remote MIB update */ type = mib->type & I40E_AQ_LLDP_MIB_TYPE_MASK; + dev_dbg(&pf->pdev->dev, + "%s: LLDP event mib type %s\n", __func__, + type ? "remote" : "local"); if (type == I40E_AQ_LLDP_MIB_REMOTE) { /* Update the remote cached instance and return */ ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE, @@ -5063,12 +5072,14 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, goto exit; } - /* Convert/store the DCBX data from LLDPDU temporarily */ memset(&tmp_dcbx_cfg, 0, sizeof(tmp_dcbx_cfg)); - ret = i40e_lldp_to_dcb_config(e->msg_buf, &tmp_dcbx_cfg); + /* Store the old configuration */ + tmp_dcbx_cfg = *dcbx_cfg; + + /* Get updated DCBX data from firmware */ + ret = i40e_get_dcb_config(&pf->hw); if (ret) { - /* Error in LLDPDU parsing return */ - dev_info(&pf->pdev->dev, "Failed parsing LLDPDU from event buffer\n"); + dev_info(&pf->pdev->dev, "Failed querying DCB configuration data from firmware.\n"); goto exit; } @@ -5078,12 +5089,9 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, goto exit; } - need_reconfig = i40e_dcb_need_reconfig(pf, dcbx_cfg, &tmp_dcbx_cfg); - - i40e_dcbnl_flush_apps(pf, &tmp_dcbx_cfg); + need_reconfig = i40e_dcb_need_reconfig(pf, &tmp_dcbx_cfg, dcbx_cfg); - /* Overwrite the new configuration */ - *dcbx_cfg = tmp_dcbx_cfg; + i40e_dcbnl_flush_apps(pf, dcbx_cfg); if (!need_reconfig) goto exit; diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 98a735cdf038..24bdc4333dc6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -175,6 +175,9 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, struct i40e_asq_cmd_details *cmd_details); +i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw, + void *buff, u16 buff_size, + struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw, u16 udp_port, u8 protocol_index, u8 *filter_index, diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 3a237c3d0dcb..afe2539b49d6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -381,9 +381,18 @@ struct i40e_fc_info { #define I40E_MAX_USER_PRIORITY 8 #define I40E_DCBX_MAX_APPS 32 #define I40E_LLDPDU_SIZE 1500 - -/* IEEE 802.1Qaz ETS Configuration data */ -struct i40e_ieee_ets_config { +#define I40E_TLV_STATUS_OPER 0x1 +#define I40E_TLV_STATUS_SYNC 0x2 +#define I40E_TLV_STATUS_ERR 0x4 +#define I40E_CEE_OPER_MAX_APPS 3 +#define I40E_APP_PROTOID_FCOE 0x8906 +#define I40E_APP_PROTOID_ISCSI 0x0cbc +#define I40E_APP_PROTOID_FIP 0x8914 +#define I40E_APP_SEL_ETHTYPE 0x1 +#define I40E_APP_SEL_TCPIP 0x2 + +/* CEE or IEEE 802.1Qaz ETS Configuration data */ +struct i40e_dcb_ets_config { u8 willing; u8 cbs; u8 maxtcs; @@ -392,34 +401,30 @@ struct i40e_ieee_ets_config { u8 tsatable[I40E_MAX_TRAFFIC_CLASS]; }; -/* IEEE 802.1Qaz ETS Recommendation data */ -struct i40e_ieee_ets_recommend { - u8 prioritytable[I40E_MAX_TRAFFIC_CLASS]; - u8 tcbwtable[I40E_MAX_TRAFFIC_CLASS]; - u8 tsatable[I40E_MAX_TRAFFIC_CLASS]; -}; - -/* IEEE 802.1Qaz PFC Configuration data */ -struct i40e_ieee_pfc_config { +/* CEE or IEEE 802.1Qaz PFC Configuration data */ +struct i40e_dcb_pfc_config { u8 willing; u8 mbc; u8 pfccap; u8 pfcenable; }; -/* IEEE 802.1Qaz Application Priority data */ -struct i40e_ieee_app_priority_table { +/* CEE or IEEE 802.1Qaz Application Priority data */ +struct i40e_dcb_app_priority_table { u8 priority; u8 selector; u16 protocolid; }; struct i40e_dcbx_config { + u8 dcbx_mode; +#define I40E_DCBX_MODE_CEE 0x1 +#define I40E_DCBX_MODE_IEEE 0x2 u32 numapps; - struct i40e_ieee_ets_config etscfg; - struct i40e_ieee_ets_recommend etsrec; - struct i40e_ieee_pfc_config pfc; - struct i40e_ieee_app_priority_table app[I40E_DCBX_MAX_APPS]; + struct i40e_dcb_ets_config etscfg; + struct i40e_dcb_ets_config etsrec; + struct i40e_dcb_pfc_config pfc; + struct i40e_dcb_app_priority_table app[I40E_DCBX_MAX_APPS]; }; /* Port hardware description */ -- GitLab From e1c4751ee22f5d5f6f6cfcb70614e18e4218892e Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:30 +0000 Subject: [PATCH 5149/9457] i40e: Check for LLDP AdminStatus before querying DCBX This patch adds a check whether LLDP Agent's default AdminStatus is enabled or disabled on a given port. If it is disabled then it sets the DCBX status to disabled as well; and would not query firmware for any DCBX configuration data. Change-ID: I73c0b9f0adbf4cae177d14914b20a48c9a8f50fd Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_dcb.c | 49 +++++++++++++++++++ .../net/ethernet/intel/i40e/i40e_prototype.h | 2 + drivers/net/ethernet/intel/i40e/i40e_type.h | 12 +++++ 3 files changed, 63 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb.c b/drivers/net/ethernet/intel/i40e/i40e_dcb.c index 1396c70b871c..3ce43588592d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_dcb.c +++ b/drivers/net/ethernet/intel/i40e/i40e_dcb.c @@ -640,10 +640,27 @@ i40e_status i40e_get_dcb_config(struct i40e_hw *hw) i40e_status i40e_init_dcb(struct i40e_hw *hw) { i40e_status ret = 0; + struct i40e_lldp_variables lldp_cfg; + u8 adminstatus = 0; if (!hw->func_caps.dcb) return ret; + /* Read LLDP NVM area */ + ret = i40e_read_lldp_cfg(hw, &lldp_cfg); + if (ret) + return ret; + + /* Get the LLDP AdminStatus for the current port */ + adminstatus = lldp_cfg.adminstatus >> (hw->port * 4); + adminstatus &= 0xF; + + /* LLDP agent disabled */ + if (!adminstatus) { + hw->dcbx_status = I40E_DCBX_STATUS_DISABLED; + return ret; + } + /* Get DCBX status */ ret = i40e_get_dcbx_status(hw, &hw->dcbx_status); if (ret) @@ -655,6 +672,8 @@ i40e_status i40e_init_dcb(struct i40e_hw *hw) case I40E_DCBX_STATUS_IN_PROGRESS: /* Get current DCBX configuration */ ret = i40e_get_dcb_config(hw); + if (ret) + return ret; break; case I40E_DCBX_STATUS_DISABLED: return ret; @@ -671,3 +690,33 @@ i40e_status i40e_init_dcb(struct i40e_hw *hw) return ret; } + +/** + * i40e_read_lldp_cfg - read LLDP Configuration data from NVM + * @hw: pointer to the HW structure + * @lldp_cfg: pointer to hold lldp configuration variables + * + * Reads the LLDP configuration data from NVM + **/ +i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw, + struct i40e_lldp_variables *lldp_cfg) +{ + i40e_status ret = 0; + u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR); + + if (!lldp_cfg) + return I40E_ERR_PARAM; + + ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); + if (ret) + goto err_lldp_cfg; + + ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset, + sizeof(struct i40e_lldp_variables), + (u8 *)lldp_cfg, + true, NULL); + i40e_release_nvm(hw); + +err_lldp_cfg: + return ret; +} diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 24bdc4333dc6..2fb4306597e8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -235,6 +235,8 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw, struct i40e_asq_cmd_details *cmd_details); i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, struct i40e_asq_cmd_details *cmd_details); +i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw, + struct i40e_lldp_variables *lldp_cfg); /* i40e_common */ i40e_status i40e_init_shared_code(struct i40e_hw *hw); i40e_status i40e_pf_reset(struct i40e_hw *hw); diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index afe2539b49d6..c85214373a51 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -1377,6 +1377,18 @@ enum i40e_reset_type { I40E_RESET_EMPR = 3, }; +/* IEEE 802.1AB LLDP Agent Variables from NVM */ +#define I40E_NVM_LLDP_CFG_PTR 0xD +struct i40e_lldp_variables { + u16 length; + u16 adminstatus; + u16 msgfasttx; + u16 msgtxinterval; + u16 txparams; + u16 timers; + u16 crc8; +}; + /* RSS Hash Table Size */ #define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000 #endif /* _I40E_TYPE_H_ */ -- GitLab From 23cd1f095adf110d118ef972914c714176cd48d0 Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:41 +0000 Subject: [PATCH 5150/9457] i40e: Update VEB's enabled_tc after reconfiguration When the port TC configuration changes as a result of DCBx the driver modifies the enabled TCs for the VEBs it manages. But, in the process it did not update the enabled_tc value that it caches on a per VEB basis. So, when the next reconfiguration event occurs where the number of TC value is same as the value cached in enabled_tc for a given VEB; driver does not modify it's TC configuration by calling appropriate AQ command believing it is running with the same configuration as requested. Now, as the VEB is not actually enabled for the TCs that are there any TC configuration command for VSI attached to that VEB with TCs that are not enabled for the VEB fails. This patch fixes this issue. Change-ID: Ife5694469b05494228e0d850429ea1734738cf29 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 99b985cb53d5..71ab3277a295 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8279,6 +8279,7 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb) veb->bw_limit = le16_to_cpu(ets_data.port_bw_limit); veb->bw_max_quanta = ets_data.tc_bw_max; veb->is_abs_credits = bw_data.absolute_credits_enable; + veb->enabled_tc = ets_data.tc_valid_bits; tc_bw_max = le16_to_cpu(bw_data.tc_bw_max[0]) | (le16_to_cpu(bw_data.tc_bw_max[1]) << 16); for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { -- GitLab From 69129dc39fac45e0ea1dbbca995abdac279df376 Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:46 +0000 Subject: [PATCH 5151/9457] i40e: Modify Tx disable wait flow in case of DCB reconfiguration When DCB TC configuration changes the firmware suspends the port's Tx. Now, as DCB TCs may have changed the PF driver tries to reconfigure the TC configuration of the VSIs it manages. As part of this process it disables the VSI queues but the Tx queue disable will not complete as the port's Tx has been suspended. So, waiting for Tx queues to go to disable state in this flow may lead to detection of Tx queue disable timeout errors. Hence, this patch adds a new PF state so that if a port's Tx is in suspended state the Tx queue disable flow would just put the request for the queue to be disabled and return without waiting for the queue to be actually disabled. Once the VSI(s) TC reconfiguration has been done and driver has called firmware AQC "Resume PF Traffic" the driver checks the Tx queues requested to be disabled are actually disabled before re-enabling them again. Change-ID: If3e03ce4813a4e342dbd5a1eb1d2861e952b7544 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 60 +++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index b7a807b380d7..464342a35214 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -146,6 +146,7 @@ enum i40e_state_t { __I40E_DOWN_REQUESTED, __I40E_FD_FLUSH_REQUESTED, __I40E_RESET_FAILED, + __I40E_PORT_TX_SUSPENDED, }; enum i40e_interrupt_policy { diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 71ab3277a295..3e55cef3176f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3492,6 +3492,9 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) } wr32(hw, I40E_QTX_ENA(pf_q), tx_reg); + /* No waiting for the Tx queue to disable */ + if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state)) + continue; /* wait for the change to finish */ ret = i40e_pf_txq_wait(pf, pf_q, enable); @@ -3911,6 +3914,56 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf) } } +#ifdef CONFIG_I40E_DCB +/** + * i40e_vsi_wait_txq_disabled - Wait for VSI's queues to be disabled + * @vsi: the VSI being configured + * + * This function waits for the given VSI's Tx queues to be disabled. + **/ +static int i40e_vsi_wait_txq_disabled(struct i40e_vsi *vsi) +{ + struct i40e_pf *pf = vsi->back; + int i, pf_q, ret; + + pf_q = vsi->base_queue; + for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { + /* Check and wait for the disable status of the queue */ + ret = i40e_pf_txq_wait(pf, pf_q, false); + if (ret) { + dev_info(&pf->pdev->dev, + "%s: VSI seid %d Tx ring %d disable timeout\n", + __func__, vsi->seid, pf_q); + return ret; + } + } + + return 0; +} + +/** + * i40e_pf_wait_txq_disabled - Wait for all queues of PF VSIs to be disabled + * @pf: the PF + * + * This function waits for the Tx queues to be in disabled state for all the + * VSIs that are managed by this PF. + **/ +static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf) +{ + int v, ret = 0; + + for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + if (pf->vsi[v]) { + ret = i40e_vsi_wait_txq_disabled(pf->vsi[v]); + if (ret) + break; + } + } + + return ret; +} + +#endif /** * i40e_dcb_get_num_tc - Get the number of TCs from DCBx config * @dcbcfg: the corresponding DCBx configuration structure @@ -5102,6 +5155,7 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, else pf->flags &= ~I40E_FLAG_DCB_ENABLED; + set_bit(__I40E_PORT_TX_SUSPENDED, &pf->state); /* Reconfiguration needed quiesce all VSIs */ i40e_pf_quiesce_all_vsi(pf); @@ -5110,7 +5164,13 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, ret = i40e_resume_port_tx(pf); + clear_bit(__I40E_PORT_TX_SUSPENDED, &pf->state); /* In case of error no point in resuming VSIs */ + if (ret) + goto exit; + + /* Wait for the PF's Tx queues to be disabled */ + ret = i40e_pf_wait_txq_disabled(pf); if (!ret) i40e_pf_unquiesce_all_vsi(pf); exit: -- GitLab From d341b7a52be79520f8e8b1ed0e3df657b2442e5b Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:51 +0000 Subject: [PATCH 5152/9457] i40e: Do not disable/enable FCoE VSI with DCB reconfig FCoE VSI Tx queue disable times out when reconfiguring as a result of DCB TC configuration change event. The hardware allows us to skip disabling and enabling of Tx queues for VSIs with single TC enabled. As FCoE VSI is configured to have only single TC we skip it from disable/enable flow. Change-ID: Ia73ff3df8785ba2aa3db91e6f2c9005e61ebaec2 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3e55cef3176f..c3107dca24da 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3862,6 +3862,15 @@ static void i40e_quiesce_vsi(struct i40e_vsi *vsi) if (test_bit(__I40E_DOWN, &vsi->state)) return; + /* No need to disable FCoE VSI when Tx suspended */ + if ((test_bit(__I40E_PORT_TX_SUSPENDED, &vsi->back->state)) && + vsi->type == I40E_VSI_FCOE) { + dev_dbg(&vsi->back->pdev->dev, + "%s: VSI seid %d skipping FCoE VSI disable\n", + __func__, vsi->seid); + return; + } + set_bit(__I40E_NEEDS_RESTART, &vsi->state); if (vsi->netdev && netif_running(vsi->netdev)) { vsi->netdev->netdev_ops->ndo_stop(vsi->netdev); @@ -3953,7 +3962,8 @@ static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf) int v, ret = 0; for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { - if (pf->vsi[v]) { + /* No need to wait for FCoE VSI queues */ + if (pf->vsi[v] && pf->vsi[v]->type != I40E_VSI_FCOE) { ret = i40e_vsi_wait_txq_disabled(pf->vsi[v]); if (ret) break; -- GitLab From 4b7698cb95638693e3d9a2fc01a2bdbd8710ff81 Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:18:57 +0000 Subject: [PATCH 5153/9457] i40e: Prevent link flow control settings when PFC is enabled When PFC is enabled we should not proceed with setting the link flow control parameters. Also, always report the link flow Tx/Rx settings as off when PFC is enabled. Change-ID: Ib09ec58afdf0b2e587ac9d8851a5c80ad58206c4 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index afad5aa5a12b..bb1698a7b3d1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -644,11 +644,19 @@ static void i40e_get_pauseparam(struct net_device *netdev, struct i40e_pf *pf = np->vsi->back; struct i40e_hw *hw = &pf->hw; struct i40e_link_status *hw_link_info = &hw->phy.link_info; + struct i40e_dcbx_config *dcbx_cfg = &hw->local_dcbx_config; pause->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ? AUTONEG_ENABLE : AUTONEG_DISABLE); + /* PFC enabled so report LFC as off */ + if (dcbx_cfg->pfc.pfcenable) { + pause->rx_pause = 0; + pause->tx_pause = 0; + return; + } + if (hw->fc.current_mode == I40E_FC_RX_PAUSE) { pause->rx_pause = 1; } else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) { @@ -672,6 +680,7 @@ static int i40e_set_pauseparam(struct net_device *netdev, struct i40e_vsi *vsi = np->vsi; struct i40e_hw *hw = &pf->hw; struct i40e_link_status *hw_link_info = &hw->phy.link_info; + struct i40e_dcbx_config *dcbx_cfg = &hw->local_dcbx_config; bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP; i40e_status status; u8 aq_failures; @@ -693,8 +702,9 @@ static int i40e_set_pauseparam(struct net_device *netdev, netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n"); } - if (hw->fc.current_mode == I40E_FC_PFC) { - netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n"); + if (dcbx_cfg->pfc.pfcenable) { + netdev_info(netdev, + "Priority flow control enabled. Cannot set link flow control.\n"); return -EOPNOTSUPP; } -- GitLab From 3ffa037d7f78ceb25115eda29176c2bd2844866f Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Wed, 12 Nov 2014 00:19:02 +0000 Subject: [PATCH 5154/9457] i40e: Set XPS bit mask to zero in DCB mode Due to DCBX configuration change if the VSI needs to use more than 1 TC; it needs to disable the XPS maps that were set when operating in 1 TC mode. Without disabling XPS the netdev layer will select queues based on those settings and not use the TC queue mapping to make the queue selection. This patch allows the driver to enable/disable the XPS based on the number of TCs being enabled for the given VSI. Change-ID: Idc4dec47a672d2a509f6d7fe11ed1ee65b4f0e08 Signed-off-by: Neerav Parikh Tested-By: Jack Morgan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 38 +++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c3107dca24da..c998d82da0fc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2381,6 +2381,35 @@ static void i40e_vsi_free_rx_resources(struct i40e_vsi *vsi) #endif } +/** + * i40e_config_xps_tx_ring - Configure XPS for a Tx ring + * @ring: The Tx ring to configure + * + * This enables/disables XPS for a given Tx descriptor ring + * based on the TCs enabled for the VSI that ring belongs to. + **/ +static void i40e_config_xps_tx_ring(struct i40e_ring *ring) +{ + struct i40e_vsi *vsi = ring->vsi; + cpumask_var_t mask; + + if (ring->q_vector && ring->netdev) { + /* Single TC mode enable XPS */ + if (vsi->tc_config.numtc <= 1 && + !test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) { + netif_set_xps_queue(ring->netdev, + &ring->q_vector->affinity_mask, + ring->queue_index); + } else if (alloc_cpumask_var(&mask, GFP_KERNEL)) { + /* Disable XPS to allow selection based on TC */ + bitmap_zero(cpumask_bits(mask), nr_cpumask_bits); + netif_set_xps_queue(ring->netdev, mask, + ring->queue_index); + free_cpumask_var(mask); + } + } +} + /** * i40e_configure_tx_ring - Configure a transmit ring context and rest * @ring: The Tx ring to configure @@ -2404,13 +2433,8 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring) ring->atr_sample_rate = 0; } - /* initialize XPS */ - if (ring->q_vector && ring->netdev && - vsi->tc_config.numtc <= 1 && - !test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) - netif_set_xps_queue(ring->netdev, - &ring->q_vector->affinity_mask, - ring->queue_index); + /* configure XPS */ + i40e_config_xps_tx_ring(ring); /* clear the context structure first */ memset(&tx_ctx, 0, sizeof(tx_ctx)); -- GitLab From 11cc9f56a18d371634d07b1be7e8772f6f7dcec5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 16 Nov 2014 23:23:19 +0100 Subject: [PATCH 5155/9457] jbd: Deletion of an unnecessary check before the function call "iput" The iput() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Jan Kara --- fs/jbd/journal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index aab8549591e7..c46a79adb6ad 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -1373,8 +1373,7 @@ int journal_destroy(journal_t *journal) } mutex_unlock(&journal->j_checkpoint_mutex); - if (journal->j_inode) - iput(journal->j_inode); + iput(journal->j_inode); if (journal->j_revoke) journal_destroy_revoke(journal); kfree(journal->j_wbuf); -- GitLab From 81ed33e4aaba65cda6367b27a21e2de9862e955f Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Tue, 18 Nov 2014 17:12:56 +0800 Subject: [PATCH 5156/9457] kvm: x86: vmx: cleanup handle_ept_violation Instead, just use PFERR_{FETCH, PRESENT, WRITE}_MASK inside handle_ept_violation() for slightly better code. Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 330a08aa0291..6a951d823c82 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5482,11 +5482,11 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) trace_kvm_page_fault(gpa, exit_qualification); /* It is a write fault? */ - error_code = exit_qualification & (1U << 1); + error_code = exit_qualification & PFERR_WRITE_MASK; /* It is a fetch fault? */ - error_code |= (exit_qualification & (1U << 2)) << 2; + error_code |= (exit_qualification << 2) & PFERR_FETCH_MASK; /* ept page table is present? */ - error_code |= (exit_qualification >> 3) & 0x1; + error_code |= (exit_qualification >> 3) & PFERR_PRESENT_MASK; vcpu->arch.exit_qualification = exit_qualification; -- GitLab From 842bb26a40af52b06a423d58e0d70609a936b162 Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Tue, 18 Nov 2014 17:14:38 +0800 Subject: [PATCH 5157/9457] kvm: x86: vmx: remove MMIO_MAX_GEN MMIO_MAX_GEN is the same as MMIO_GEN_MASK. Use only one. Signed-off-by: Tiejun Chen Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ac1c4de3a484..4ea0dcb0b21b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -214,13 +214,12 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask); #define MMIO_GEN_LOW_SHIFT 10 #define MMIO_GEN_LOW_MASK ((1 << MMIO_GEN_LOW_SHIFT) - 2) #define MMIO_GEN_MASK ((1 << MMIO_GEN_SHIFT) - 1) -#define MMIO_MAX_GEN ((1 << MMIO_GEN_SHIFT) - 1) static u64 generation_mmio_spte_mask(unsigned int gen) { u64 mask; - WARN_ON(gen > MMIO_MAX_GEN); + WARN_ON(gen & ~MMIO_GEN_MASK); mask = (gen & MMIO_GEN_LOW_MASK) << MMIO_SPTE_GEN_LOW_SHIFT; mask |= ((u64)gen >> MMIO_GEN_LOW_SHIFT) << MMIO_SPTE_GEN_HIGH_SHIFT; @@ -263,13 +262,13 @@ static bool is_mmio_spte(u64 spte) static gfn_t get_mmio_spte_gfn(u64 spte) { - u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask; + u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask; return (spte & ~mask) >> PAGE_SHIFT; } static unsigned get_mmio_spte_access(u64 spte) { - u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask; + u64 mask = generation_mmio_spte_mask(MMIO_GEN_MASK) | shadow_mmio_mask; return (spte & ~mask) & ~PAGE_MASK; } -- GitLab From eb45fa0b93e03b03848cd048dcc57648409c8125 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 18 Nov 2014 12:11:29 +0200 Subject: [PATCH 5158/9457] drm/i915/audio: fix monitor presence indication after disable Indicate the monitor has been disconnected on disable. The regression has been introduced in commit 5fad84a7530f8e7664cdc6f490cb90653fed1266 Author: Jani Nikula Date: Tue Nov 4 10:30:23 2014 +0200 drm/i915: rewrite hsw/bdw audio codec enable/disable sequences Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86424 Cc: Rodrigo Vivi Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_audio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 87750ef018e6..2c7ed5cb29c0 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -194,6 +194,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) /* Invalidate ELD */ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); tmp &= ~AUDIO_ELD_VALID(pipe); + tmp &= ~AUDIO_OUTPUT_ENABLE(pipe); I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); } -- GitLab From c2a0b538d2c778aef7bf2fbe7973229192c9a392 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:47:56 +0800 Subject: [PATCH 5159/9457] iommu/vt-d: Introduce helper function dmar_walk_resources() Introduce helper function dmar_walk_resources to walk resource entries in DMAR table and ACPI buffer object returned by ACPI _DSM method for IOMMU hot-plug. Signed-off-by: Jiang Liu Signed-off-by: Joerg Roedel --- drivers/iommu/dmar.c | 209 +++++++++++++++++++----------------- drivers/iommu/intel-iommu.c | 4 +- include/linux/dmar.h | 19 ++-- 3 files changed, 122 insertions(+), 110 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index c5c61cabd6e3..586dd2aa2ca2 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -44,6 +44,14 @@ #include "irq_remapping.h" +typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *); +struct dmar_res_callback { + dmar_res_handler_t cb[ACPI_DMAR_TYPE_RESERVED]; + void *arg[ACPI_DMAR_TYPE_RESERVED]; + bool ignore_unhandled; + bool print_entry; +}; + /* * Assumptions: * 1) The hotplug framework guarentees that DMAR unit will be hot-added @@ -350,7 +358,7 @@ static struct notifier_block dmar_pci_bus_nb = { * present in the platform */ static int __init -dmar_parse_one_drhd(struct acpi_dmar_header *header) +dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg) { struct acpi_dmar_hardware_unit *drhd; struct dmar_drhd_unit *dmaru; @@ -381,6 +389,10 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header) return ret; } dmar_register_drhd_unit(dmaru); + + if (arg) + (*(int *)arg)++; + return 0; } @@ -393,7 +405,8 @@ static void dmar_free_drhd(struct dmar_drhd_unit *dmaru) kfree(dmaru); } -static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) +static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, + void *arg) { struct acpi_dmar_andd *andd = (void *)header; @@ -415,7 +428,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) #ifdef CONFIG_ACPI_NUMA static int __init -dmar_parse_one_rhsa(struct acpi_dmar_header *header) +dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) { struct acpi_dmar_rhsa *rhsa; struct dmar_drhd_unit *drhd; @@ -442,6 +455,8 @@ dmar_parse_one_rhsa(struct acpi_dmar_header *header) return 0; } +#else +#define dmar_parse_one_rhsa dmar_res_noop #endif static void __init @@ -503,6 +518,52 @@ static int __init dmar_table_detect(void) return (ACPI_SUCCESS(status) ? 1 : 0); } +static int dmar_walk_remapping_entries(struct acpi_dmar_header *start, + size_t len, struct dmar_res_callback *cb) +{ + int ret = 0; + struct acpi_dmar_header *iter, *next; + struct acpi_dmar_header *end = ((void *)start) + len; + + for (iter = start; iter < end && ret == 0; iter = next) { + next = (void *)iter + iter->length; + if (iter->length == 0) { + /* Avoid looping forever on bad ACPI tables */ + pr_debug(FW_BUG "Invalid 0-length structure\n"); + break; + } else if (next > end) { + /* Avoid passing table end */ + pr_warn(FW_BUG "record passes table end\n"); + ret = -EINVAL; + break; + } + + if (cb->print_entry) + dmar_table_print_dmar_entry(iter); + + if (iter->type >= ACPI_DMAR_TYPE_RESERVED) { + /* continue for forward compatibility */ + pr_debug("Unknown DMAR structure type %d\n", + iter->type); + } else if (cb->cb[iter->type]) { + ret = cb->cb[iter->type](iter, cb->arg[iter->type]); + } else if (!cb->ignore_unhandled) { + pr_warn("No handler for DMAR structure type %d\n", + iter->type); + ret = -EINVAL; + } + } + + return ret; +} + +static inline int dmar_walk_dmar_table(struct acpi_table_dmar *dmar, + struct dmar_res_callback *cb) +{ + return dmar_walk_remapping_entries((void *)(dmar + 1), + dmar->header.length - sizeof(*dmar), cb); +} + /** * parse_dmar_table - parses the DMA reporting table */ @@ -510,9 +571,18 @@ static int __init parse_dmar_table(void) { struct acpi_table_dmar *dmar; - struct acpi_dmar_header *entry_header; int ret = 0; int drhd_count = 0; + struct dmar_res_callback cb = { + .print_entry = true, + .ignore_unhandled = true, + .arg[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &drhd_count, + .cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &dmar_parse_one_drhd, + .cb[ACPI_DMAR_TYPE_RESERVED_MEMORY] = &dmar_parse_one_rmrr, + .cb[ACPI_DMAR_TYPE_ROOT_ATS] = &dmar_parse_one_atsr, + .cb[ACPI_DMAR_TYPE_HARDWARE_AFFINITY] = &dmar_parse_one_rhsa, + .cb[ACPI_DMAR_TYPE_NAMESPACE] = &dmar_parse_one_andd, + }; /* * Do it again, earlier dmar_tbl mapping could be mapped with @@ -536,51 +606,10 @@ parse_dmar_table(void) } pr_info("Host address width %d\n", dmar->width + 1); - - entry_header = (struct acpi_dmar_header *)(dmar + 1); - while (((unsigned long)entry_header) < - (((unsigned long)dmar) + dmar_tbl->length)) { - /* Avoid looping forever on bad ACPI tables */ - if (entry_header->length == 0) { - pr_warn("Invalid 0-length structure\n"); - ret = -EINVAL; - break; - } - - dmar_table_print_dmar_entry(entry_header); - - switch (entry_header->type) { - case ACPI_DMAR_TYPE_HARDWARE_UNIT: - drhd_count++; - ret = dmar_parse_one_drhd(entry_header); - break; - case ACPI_DMAR_TYPE_RESERVED_MEMORY: - ret = dmar_parse_one_rmrr(entry_header); - break; - case ACPI_DMAR_TYPE_ROOT_ATS: - ret = dmar_parse_one_atsr(entry_header); - break; - case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: -#ifdef CONFIG_ACPI_NUMA - ret = dmar_parse_one_rhsa(entry_header); -#endif - break; - case ACPI_DMAR_TYPE_NAMESPACE: - ret = dmar_parse_one_andd(entry_header); - break; - default: - pr_warn("Unknown DMAR structure type %d\n", - entry_header->type); - ret = 0; /* for forward compatibility */ - break; - } - if (ret) - break; - - entry_header = ((void *)entry_header + entry_header->length); - } - if (drhd_count == 0) + ret = dmar_walk_dmar_table(dmar, &cb); + if (ret == 0 && drhd_count == 0) pr_warn(FW_BUG "No DRHD structure found in DMAR table\n"); + return ret; } @@ -778,76 +807,60 @@ static void warn_invalid_dmar(u64 addr, const char *message) dmi_get_system_info(DMI_PRODUCT_VERSION)); } -static int __init check_zero_address(void) +static int __ref +dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg) { - struct acpi_table_dmar *dmar; - struct acpi_dmar_header *entry_header; struct acpi_dmar_hardware_unit *drhd; + void __iomem *addr; + u64 cap, ecap; - dmar = (struct acpi_table_dmar *)dmar_tbl; - entry_header = (struct acpi_dmar_header *)(dmar + 1); - - while (((unsigned long)entry_header) < - (((unsigned long)dmar) + dmar_tbl->length)) { - /* Avoid looping forever on bad ACPI tables */ - if (entry_header->length == 0) { - pr_warn("Invalid 0-length structure\n"); - return 0; - } - - if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { - void __iomem *addr; - u64 cap, ecap; - - drhd = (void *)entry_header; - if (!drhd->address) { - warn_invalid_dmar(0, ""); - goto failed; - } + drhd = (void *)entry; + if (!drhd->address) { + warn_invalid_dmar(0, ""); + return -EINVAL; + } - addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); - if (!addr ) { - printk("IOMMU: can't validate: %llx\n", drhd->address); - goto failed; - } - cap = dmar_readq(addr + DMAR_CAP_REG); - ecap = dmar_readq(addr + DMAR_ECAP_REG); - early_iounmap(addr, VTD_PAGE_SIZE); - if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { - warn_invalid_dmar(drhd->address, - " returns all ones"); - goto failed; - } - } + addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); + if (!addr) { + pr_warn("IOMMU: can't validate: %llx\n", drhd->address); + return -EINVAL; + } + cap = dmar_readq(addr + DMAR_CAP_REG); + ecap = dmar_readq(addr + DMAR_ECAP_REG); + early_iounmap(addr, VTD_PAGE_SIZE); - entry_header = ((void *)entry_header + entry_header->length); + if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { + warn_invalid_dmar(drhd->address, " returns all ones"); + return -EINVAL; } - return 1; -failed: return 0; } int __init detect_intel_iommu(void) { int ret; + struct dmar_res_callback validate_drhd_cb = { + .cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &dmar_validate_one_drhd, + .ignore_unhandled = true, + }; down_write(&dmar_global_lock); ret = dmar_table_detect(); if (ret) - ret = check_zero_address(); - { - if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { - iommu_detected = 1; - /* Make sure ACS will be enabled */ - pci_request_acs(); - } + ret = !dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl, + &validate_drhd_cb); + if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { + iommu_detected = 1; + /* Make sure ACS will be enabled */ + pci_request_acs(); + } #ifdef CONFIG_X86 - if (ret) - x86_init.iommu.iommu_init = intel_iommu_init; + if (ret) + x86_init.iommu.iommu_init = intel_iommu_init; #endif - } + early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size); dmar_tbl = NULL; up_write(&dmar_global_lock); diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index ba0fa2a8d696..b9cc9c2b03fc 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3684,7 +3684,7 @@ static inline void init_iommu_pm_ops(void) {} #endif /* CONFIG_PM */ -int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header) +int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) { struct acpi_dmar_reserved_memory *rmrr; struct dmar_rmrr_unit *rmrru; @@ -3710,7 +3710,7 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header) return 0; } -int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr) +int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg) { struct acpi_dmar_atsr *atsr; struct dmar_atsr_unit *atsru; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 593fff99e6bf..495df5e48f80 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -121,22 +121,21 @@ extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, extern int detect_intel_iommu(void); extern int enable_drhd_fault_handling(void); +static inline int dmar_res_noop(struct acpi_dmar_header *hdr, void *arg) +{ + return 0; +} + #ifdef CONFIG_INTEL_IOMMU extern int iommu_detected, no_iommu; extern int intel_iommu_init(void); -extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); -extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); +extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg); +extern int dmar_parse_one_atsr(struct acpi_dmar_header *header, void *arg); extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); #else /* !CONFIG_INTEL_IOMMU: */ static inline int intel_iommu_init(void) { return -ENODEV; } -static inline int dmar_parse_one_rmrr(struct acpi_dmar_header *header) -{ - return 0; -} -static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header) -{ - return 0; -} +#define dmar_parse_one_rmrr dmar_res_noop +#define dmar_parse_one_atsr dmar_res_noop static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) { return 0; -- GitLab From 78d8e7046111425bb688cddc4303d79cb0f0d281 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:47:57 +0800 Subject: [PATCH 5160/9457] iommu/vt-d: Dynamically allocate and free seq_id for DMAR units Introduce functions to support dynamic IOMMU seq_id allocating and releasing, which will be used to support DMAR hotplug. Also rename IOMMU_UNITS_SUPPORTED as DMAR_UNITS_SUPPORTED. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Signed-off-by: Joerg Roedel --- drivers/iommu/dmar.c | 40 +++++++++++++++++++++++++++++++------ drivers/iommu/intel-iommu.c | 13 +++--------- include/linux/dmar.h | 6 ++++++ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 586dd2aa2ca2..78aa1b2af113 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -70,6 +70,7 @@ LIST_HEAD(dmar_drhd_units); struct acpi_table_header * __initdata dmar_tbl; static acpi_size dmar_tbl_size; static int dmar_dev_scope_status = 1; +static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)]; static int alloc_iommu(struct dmar_drhd_unit *drhd); static void free_iommu(struct intel_iommu *iommu); @@ -944,11 +945,32 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) return err; } +static int dmar_alloc_seq_id(struct intel_iommu *iommu) +{ + iommu->seq_id = find_first_zero_bit(dmar_seq_ids, + DMAR_UNITS_SUPPORTED); + if (iommu->seq_id >= DMAR_UNITS_SUPPORTED) { + iommu->seq_id = -1; + } else { + set_bit(iommu->seq_id, dmar_seq_ids); + sprintf(iommu->name, "dmar%d", iommu->seq_id); + } + + return iommu->seq_id; +} + +static void dmar_free_seq_id(struct intel_iommu *iommu) +{ + if (iommu->seq_id >= 0) { + clear_bit(iommu->seq_id, dmar_seq_ids); + iommu->seq_id = -1; + } +} + static int alloc_iommu(struct dmar_drhd_unit *drhd) { struct intel_iommu *iommu; u32 ver, sts; - static int iommu_allocated = 0; int agaw = 0; int msagaw = 0; int err; @@ -962,13 +984,16 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) if (!iommu) return -ENOMEM; - iommu->seq_id = iommu_allocated++; - sprintf (iommu->name, "dmar%d", iommu->seq_id); + if (dmar_alloc_seq_id(iommu) < 0) { + pr_err("IOMMU: failed to allocate seq_id\n"); + err = -ENOSPC; + goto error; + } err = map_iommu(iommu, drhd->reg_base_addr); if (err) { pr_err("IOMMU: failed to map %s\n", iommu->name); - goto error; + goto error_free_seq_id; } err = -EINVAL; @@ -1018,9 +1043,11 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) return 0; - err_unmap: +err_unmap: unmap_iommu(iommu); - error: +error_free_seq_id: + dmar_free_seq_id(iommu); +error: kfree(iommu); return err; } @@ -1044,6 +1071,7 @@ static void free_iommu(struct intel_iommu *iommu) if (iommu->reg) unmap_iommu(iommu); + dmar_free_seq_id(iommu); kfree(iommu); } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index b9cc9c2b03fc..2779354321f5 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -330,17 +330,10 @@ static int hw_pass_through = 1; /* si_domain contains mulitple devices */ #define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1) -/* define the limit of IOMMUs supported in each domain */ -#ifdef CONFIG_X86 -# define IOMMU_UNITS_SUPPORTED MAX_IO_APICS -#else -# define IOMMU_UNITS_SUPPORTED 64 -#endif - struct dmar_domain { int id; /* domain id */ int nid; /* node id */ - DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED); + DECLARE_BITMAP(iommu_bmp, DMAR_UNITS_SUPPORTED); /* bitmap of iommus this domain uses*/ struct list_head devices; /* all devices' list */ @@ -2730,12 +2723,12 @@ static int __init init_dmars(void) * threaded kernel __init code path all other access are read * only */ - if (g_num_of_iommus < IOMMU_UNITS_SUPPORTED) { + if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) { g_num_of_iommus++; continue; } printk_once(KERN_ERR "intel-iommu: exceeded %d IOMMUs\n", - IOMMU_UNITS_SUPPORTED); + DMAR_UNITS_SUPPORTED); } g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 495df5e48f80..725204fc433e 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -30,6 +30,12 @@ struct acpi_dmar_header; +#ifdef CONFIG_X86 +# define DMAR_UNITS_SUPPORTED MAX_IO_APICS +#else +# define DMAR_UNITS_SUPPORTED 64 +#endif + /* DMAR Flags */ #define DMAR_INTR_REMAP 0x1 #define DMAR_X2APIC_OPT_OUT 0x2 -- GitLab From 6b1972493a84f8fe13ff9d202745590f6c53d670 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:47:58 +0800 Subject: [PATCH 5161/9457] iommu/vt-d: Implement DMAR unit hotplug framework On Intel platforms, an IO Hub (PCI/PCIe host bridge) may contain DMAR units, so we need to support DMAR hotplug when supporting PCI host bridge hotplug on Intel platforms. According to Section 8.8 "Remapping Hardware Unit Hot Plug" in "Intel Virtualization Technology for Directed IO Architecture Specification Rev 2.2", ACPI BIOS should implement ACPI _DSM method under the ACPI object for the PCI host bridge to support DMAR hotplug. This patch introduces interfaces to parse ACPI _DSM method for DMAR unit hotplug. It also implements state machines for DMAR unit hot-addition and hot-removal. The PCI host bridge hotplug driver should call dmar_hotplug_hotplug() before scanning PCI devices connected for hot-addition and after destroying all PCI devices for hot-removal. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Signed-off-by: Joerg Roedel --- drivers/iommu/dmar.c | 268 ++++++++++++++++++++++++++-- drivers/iommu/intel-iommu.c | 78 +++++++- drivers/iommu/intel_irq_remapping.c | 5 + include/linux/dmar.h | 33 ++++ 4 files changed, 370 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 78aa1b2af113..0bd536d769a9 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -75,7 +75,7 @@ static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)]; static int alloc_iommu(struct dmar_drhd_unit *drhd); static void free_iommu(struct intel_iommu *iommu); -static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd) +static void dmar_register_drhd_unit(struct dmar_drhd_unit *drhd) { /* * add INCLUDE_ALL at the tail, so scan the list will find it at @@ -353,24 +353,45 @@ static struct notifier_block dmar_pci_bus_nb = { .priority = INT_MIN, }; +static struct dmar_drhd_unit * +dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd) +{ + struct dmar_drhd_unit *dmaru; + + list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list) + if (dmaru->segment == drhd->segment && + dmaru->reg_base_addr == drhd->address) + return dmaru; + + return NULL; +} + /** * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition * structure which uniquely represent one DMA remapping hardware unit * present in the platform */ -static int __init -dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg) +static int dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg) { struct acpi_dmar_hardware_unit *drhd; struct dmar_drhd_unit *dmaru; int ret = 0; drhd = (struct acpi_dmar_hardware_unit *)header; - dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL); + dmaru = dmar_find_dmaru(drhd); + if (dmaru) + goto out; + + dmaru = kzalloc(sizeof(*dmaru) + header->length, GFP_KERNEL); if (!dmaru) return -ENOMEM; - dmaru->hdr = header; + /* + * If header is allocated from slab by ACPI _DSM method, we need to + * copy the content because the memory buffer will be freed on return. + */ + dmaru->hdr = (void *)(dmaru + 1); + memcpy(dmaru->hdr, header, header->length); dmaru->reg_base_addr = drhd->address; dmaru->segment = drhd->segment; dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */ @@ -391,6 +412,7 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg) } dmar_register_drhd_unit(dmaru); +out: if (arg) (*(int *)arg)++; @@ -428,8 +450,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, } #ifdef CONFIG_ACPI_NUMA -static int __init -dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) +static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) { struct acpi_dmar_rhsa *rhsa; struct dmar_drhd_unit *drhd; @@ -821,14 +842,22 @@ dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg) return -EINVAL; } - addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); + if (arg) + addr = ioremap(drhd->address, VTD_PAGE_SIZE); + else + addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); if (!addr) { pr_warn("IOMMU: can't validate: %llx\n", drhd->address); return -EINVAL; } + cap = dmar_readq(addr + DMAR_CAP_REG); ecap = dmar_readq(addr + DMAR_ECAP_REG); - early_iounmap(addr, VTD_PAGE_SIZE); + + if (arg) + iounmap(addr); + else + early_iounmap(addr, VTD_PAGE_SIZE); if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { warn_invalid_dmar(drhd->address, " returns all ones"); @@ -1702,12 +1731,17 @@ int __init dmar_ir_support(void) return dmar->flags & 0x1; } +/* Check whether DMAR units are in use */ +static inline bool dmar_in_use(void) +{ + return irq_remapping_enabled || intel_iommu_enabled; +} + static int __init dmar_free_unused_resources(void) { struct dmar_drhd_unit *dmaru, *dmaru_n; - /* DMAR units are in use */ - if (irq_remapping_enabled || intel_iommu_enabled) + if (dmar_in_use()) return 0; if (dmar_dev_scope_status != 1 && !list_empty(&dmar_drhd_units)) @@ -1725,3 +1759,215 @@ static int __init dmar_free_unused_resources(void) late_initcall(dmar_free_unused_resources); IOMMU_INIT_POST(detect_intel_iommu); + +/* + * DMAR Hotplug Support + * For more details, please refer to Intel(R) Virtualization Technology + * for Directed-IO Architecture Specifiction, Rev 2.2, Section 8.8 + * "Remapping Hardware Unit Hot Plug". + */ +static u8 dmar_hp_uuid[] = { + /* 0000 */ 0xA6, 0xA3, 0xC1, 0xD8, 0x9B, 0xBE, 0x9B, 0x4C, + /* 0008 */ 0x91, 0xBF, 0xC3, 0xCB, 0x81, 0xFC, 0x5D, 0xAF +}; + +/* + * Currently there's only one revision and BIOS will not check the revision id, + * so use 0 for safety. + */ +#define DMAR_DSM_REV_ID 0 +#define DMAR_DSM_FUNC_DRHD 1 +#define DMAR_DSM_FUNC_ATSR 2 +#define DMAR_DSM_FUNC_RHSA 3 + +static inline bool dmar_detect_dsm(acpi_handle handle, int func) +{ + return acpi_check_dsm(handle, dmar_hp_uuid, DMAR_DSM_REV_ID, 1 << func); +} + +static int dmar_walk_dsm_resource(acpi_handle handle, int func, + dmar_res_handler_t handler, void *arg) +{ + int ret = -ENODEV; + union acpi_object *obj; + struct acpi_dmar_header *start; + struct dmar_res_callback callback; + static int res_type[] = { + [DMAR_DSM_FUNC_DRHD] = ACPI_DMAR_TYPE_HARDWARE_UNIT, + [DMAR_DSM_FUNC_ATSR] = ACPI_DMAR_TYPE_ROOT_ATS, + [DMAR_DSM_FUNC_RHSA] = ACPI_DMAR_TYPE_HARDWARE_AFFINITY, + }; + + if (!dmar_detect_dsm(handle, func)) + return 0; + + obj = acpi_evaluate_dsm_typed(handle, dmar_hp_uuid, DMAR_DSM_REV_ID, + func, NULL, ACPI_TYPE_BUFFER); + if (!obj) + return -ENODEV; + + memset(&callback, 0, sizeof(callback)); + callback.cb[res_type[func]] = handler; + callback.arg[res_type[func]] = arg; + start = (struct acpi_dmar_header *)obj->buffer.pointer; + ret = dmar_walk_remapping_entries(start, obj->buffer.length, &callback); + + ACPI_FREE(obj); + + return ret; +} + +static int dmar_hp_add_drhd(struct acpi_dmar_header *header, void *arg) +{ + int ret; + struct dmar_drhd_unit *dmaru; + + dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header); + if (!dmaru) + return -ENODEV; + + ret = dmar_ir_hotplug(dmaru, true); + if (ret == 0) + ret = dmar_iommu_hotplug(dmaru, true); + + return ret; +} + +static int dmar_hp_remove_drhd(struct acpi_dmar_header *header, void *arg) +{ + int i, ret; + struct device *dev; + struct dmar_drhd_unit *dmaru; + + dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header); + if (!dmaru) + return 0; + + /* + * All PCI devices managed by this unit should have been destroyed. + */ + if (!dmaru->include_all && dmaru->devices && dmaru->devices_cnt) + for_each_active_dev_scope(dmaru->devices, + dmaru->devices_cnt, i, dev) + return -EBUSY; + + ret = dmar_ir_hotplug(dmaru, false); + if (ret == 0) + ret = dmar_iommu_hotplug(dmaru, false); + + return ret; +} + +static int dmar_hp_release_drhd(struct acpi_dmar_header *header, void *arg) +{ + struct dmar_drhd_unit *dmaru; + + dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header); + if (dmaru) { + list_del_rcu(&dmaru->list); + synchronize_rcu(); + dmar_free_drhd(dmaru); + } + + return 0; +} + +static int dmar_hotplug_insert(acpi_handle handle) +{ + int ret; + int drhd_count = 0; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_validate_one_drhd, (void *)1); + if (ret) + goto out; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_parse_one_drhd, (void *)&drhd_count); + if (ret == 0 && drhd_count == 0) { + pr_warn(FW_BUG "No DRHD structures in buffer returned by _DSM method\n"); + goto out; + } else if (ret) { + goto release_drhd; + } + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_RHSA, + &dmar_parse_one_rhsa, NULL); + if (ret) + goto release_drhd; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR, + &dmar_parse_one_atsr, NULL); + if (ret) + goto release_atsr; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_add_drhd, NULL); + if (!ret) + return 0; + + dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_remove_drhd, NULL); +release_atsr: + dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR, + &dmar_release_one_atsr, NULL); +release_drhd: + dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_release_drhd, NULL); +out: + return ret; +} + +static int dmar_hotplug_remove(acpi_handle handle) +{ + int ret; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR, + &dmar_check_one_atsr, NULL); + if (ret) + return ret; + + ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_remove_drhd, NULL); + if (ret == 0) { + WARN_ON(dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR, + &dmar_release_one_atsr, NULL)); + WARN_ON(dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_release_drhd, NULL)); + } else { + dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD, + &dmar_hp_add_drhd, NULL); + } + + return ret; +} + +static int dmar_device_hotplug(acpi_handle handle, bool insert) +{ + int ret; + + if (!dmar_in_use()) + return 0; + + if (!dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) + return 0; + + down_write(&dmar_global_lock); + if (insert) + ret = dmar_hotplug_insert(handle); + else + ret = dmar_hotplug_remove(handle); + up_write(&dmar_global_lock); + + return ret; +} + +int dmar_device_add(acpi_handle handle) +{ + return dmar_device_hotplug(handle, true); +} + +int dmar_device_remove(acpi_handle handle) +{ + return dmar_device_hotplug(handle, false); +} diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2779354321f5..7c49ab51904f 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3703,17 +3703,48 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) return 0; } -int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg) +static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr) +{ + struct dmar_atsr_unit *atsru; + struct acpi_dmar_atsr *tmp; + + list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) { + tmp = (struct acpi_dmar_atsr *)atsru->hdr; + if (atsr->segment != tmp->segment) + continue; + if (atsr->header.length != tmp->header.length) + continue; + if (memcmp(atsr, tmp, atsr->header.length) == 0) + return atsru; + } + + return NULL; +} + +int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg) { struct acpi_dmar_atsr *atsr; struct dmar_atsr_unit *atsru; + if (system_state != SYSTEM_BOOTING && !intel_iommu_enabled) + return 0; + atsr = container_of(hdr, struct acpi_dmar_atsr, header); - atsru = kzalloc(sizeof(*atsru), GFP_KERNEL); + atsru = dmar_find_atsr(atsr); + if (atsru) + return 0; + + atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL); if (!atsru) return -ENOMEM; - atsru->hdr = hdr; + /* + * If memory is allocated from slab by ACPI _DSM method, we need to + * copy the memory content because the memory buffer will be freed + * on return. + */ + atsru->hdr = (void *)(atsru + 1); + memcpy(atsru->hdr, hdr, hdr->length); atsru->include_all = atsr->flags & 0x1; if (!atsru->include_all) { atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1), @@ -3736,6 +3767,47 @@ static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru) kfree(atsru); } +int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg) +{ + struct acpi_dmar_atsr *atsr; + struct dmar_atsr_unit *atsru; + + atsr = container_of(hdr, struct acpi_dmar_atsr, header); + atsru = dmar_find_atsr(atsr); + if (atsru) { + list_del_rcu(&atsru->list); + synchronize_rcu(); + intel_iommu_free_atsr(atsru); + } + + return 0; +} + +int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg) +{ + int i; + struct device *dev; + struct acpi_dmar_atsr *atsr; + struct dmar_atsr_unit *atsru; + + atsr = container_of(hdr, struct acpi_dmar_atsr, header); + atsru = dmar_find_atsr(atsr); + if (!atsru) + return 0; + + if (!atsru->include_all && atsru->devices && atsru->devices_cnt) + for_each_active_dev_scope(atsru->devices, atsru->devices_cnt, + i, dev) + return -EBUSY; + + return 0; +} + +int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert) +{ + return intel_iommu_enabled ? -ENOSYS : 0; +} + static void intel_iommu_free_dmars(void) { struct dmar_rmrr_unit *rmrru, *rmrr_n; diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 7c80661b35c1..1cbdb509bc7b 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -1171,3 +1171,8 @@ struct irq_remap_ops intel_irq_remap_ops = { .msi_setup_irq = intel_msi_setup_irq, .alloc_hpet_msi = intel_alloc_hpet_msi, }; + +int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert) +{ + return irq_remapping_enabled ? -ENOSYS : 0; +} diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 725204fc433e..30624954dec5 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -126,6 +126,8 @@ extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, /* Intel IOMMU detection */ extern int detect_intel_iommu(void); extern int enable_drhd_fault_handling(void); +extern int dmar_device_add(acpi_handle handle); +extern int dmar_device_remove(acpi_handle handle); static inline int dmar_res_noop(struct acpi_dmar_header *hdr, void *arg) { @@ -137,17 +139,48 @@ extern int iommu_detected, no_iommu; extern int intel_iommu_init(void); extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg); extern int dmar_parse_one_atsr(struct acpi_dmar_header *header, void *arg); +extern int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg); +extern int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg); +extern int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert); extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); #else /* !CONFIG_INTEL_IOMMU: */ static inline int intel_iommu_init(void) { return -ENODEV; } + #define dmar_parse_one_rmrr dmar_res_noop #define dmar_parse_one_atsr dmar_res_noop +#define dmar_check_one_atsr dmar_res_noop +#define dmar_release_one_atsr dmar_res_noop + static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info) { return 0; } + +static inline int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert) +{ + return 0; +} #endif /* CONFIG_INTEL_IOMMU */ +#ifdef CONFIG_IRQ_REMAP +extern int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert); +#else /* CONFIG_IRQ_REMAP */ +static inline int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert) +{ return 0; } +#endif /* CONFIG_IRQ_REMAP */ + +#else /* CONFIG_DMAR_TABLE */ + +static inline int dmar_device_add(void *handle) +{ + return 0; +} + +static inline int dmar_device_remove(void *handle) +{ + return 0; +} + #endif /* CONFIG_DMAR_TABLE */ struct irte { -- GitLab From d35165a955f095095cdb8512cb7cd8f63101649a Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:47:59 +0800 Subject: [PATCH 5162/9457] iommu/vt-d: Search for ACPI _DSM method for DMAR hotplug According to Intel VT-d specification, _DSM method to support DMAR hotplug should exist directly under corresponding ACPI object representing PCI host bridge. But some BIOSes doesn't conform to this, so search for _DSM method in the subtree starting from the ACPI object representing the PCI host bridge. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Signed-off-by: Joerg Roedel --- drivers/iommu/dmar.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 0bd536d769a9..9847613085e1 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -1942,21 +1942,48 @@ static int dmar_hotplug_remove(acpi_handle handle) return ret; } +static acpi_status dmar_get_dsm_handle(acpi_handle handle, u32 lvl, + void *context, void **retval) +{ + acpi_handle *phdl = retval; + + if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) { + *phdl = handle; + return AE_CTRL_TERMINATE; + } + + return AE_OK; +} + static int dmar_device_hotplug(acpi_handle handle, bool insert) { int ret; + acpi_handle tmp = NULL; + acpi_status status; if (!dmar_in_use()) return 0; - if (!dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) + if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) { + tmp = handle; + } else { + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, + dmar_get_dsm_handle, + NULL, NULL, &tmp); + if (ACPI_FAILURE(status)) { + pr_warn("Failed to locate _DSM method.\n"); + return -ENXIO; + } + } + if (tmp == NULL) return 0; down_write(&dmar_global_lock); if (insert) - ret = dmar_hotplug_insert(handle); + ret = dmar_hotplug_insert(tmp); else - ret = dmar_hotplug_remove(handle); + ret = dmar_hotplug_remove(tmp); up_write(&dmar_global_lock); return ret; -- GitLab From a7a3dad944344caf034699b0c0e8dc51b469cf20 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:48:00 +0800 Subject: [PATCH 5163/9457] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug Implement required callback functions for intel_irq_remapping driver to support DMAR unit hotplug. Signed-off-by: Jiang Liu Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 238 +++++++++++++++++++++------- 1 file changed, 178 insertions(+), 60 deletions(-) diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 1cbdb509bc7b..7af0b56dc2d1 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -36,7 +36,6 @@ struct hpet_scope { static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; static struct hpet_scope ir_hpet[MAX_HPET_TBS]; -static int ir_ioapic_num, ir_hpet_num; /* * Lock ordering: @@ -206,7 +205,7 @@ static struct intel_iommu *map_hpet_to_ir(u8 hpet_id) int i; for (i = 0; i < MAX_HPET_TBS; i++) - if (ir_hpet[i].id == hpet_id) + if (ir_hpet[i].id == hpet_id && ir_hpet[i].iommu) return ir_hpet[i].iommu; return NULL; } @@ -216,7 +215,7 @@ static struct intel_iommu *map_ioapic_to_ir(int apic) int i; for (i = 0; i < MAX_IO_APICS; i++) - if (ir_ioapic[i].id == apic) + if (ir_ioapic[i].id == apic && ir_ioapic[i].iommu) return ir_ioapic[i].iommu; return NULL; } @@ -325,7 +324,7 @@ static int set_ioapic_sid(struct irte *irte, int apic) down_read(&dmar_global_lock); for (i = 0; i < MAX_IO_APICS; i++) { - if (ir_ioapic[i].id == apic) { + if (ir_ioapic[i].iommu && ir_ioapic[i].id == apic) { sid = (ir_ioapic[i].bus << 8) | ir_ioapic[i].devfn; break; } @@ -352,7 +351,7 @@ static int set_hpet_sid(struct irte *irte, u8 id) down_read(&dmar_global_lock); for (i = 0; i < MAX_HPET_TBS; i++) { - if (ir_hpet[i].id == id) { + if (ir_hpet[i].iommu && ir_hpet[i].id == id) { sid = (ir_hpet[i].bus << 8) | ir_hpet[i].devfn; break; } @@ -473,17 +472,17 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) raw_spin_unlock_irqrestore(&iommu->register_lock, flags); } - -static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode) +static int intel_setup_irq_remapping(struct intel_iommu *iommu) { struct ir_table *ir_table; struct page *pages; unsigned long *bitmap; - ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table), - GFP_ATOMIC); + if (iommu->ir_table) + return 0; - if (!iommu->ir_table) + ir_table = kzalloc(sizeof(struct ir_table), GFP_ATOMIC); + if (!ir_table) return -ENOMEM; pages = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, @@ -492,24 +491,37 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode) if (!pages) { pr_err("IR%d: failed to allocate pages of order %d\n", iommu->seq_id, INTR_REMAP_PAGE_ORDER); - kfree(iommu->ir_table); - return -ENOMEM; + goto out_free_table; } bitmap = kcalloc(BITS_TO_LONGS(INTR_REMAP_TABLE_ENTRIES), sizeof(long), GFP_ATOMIC); if (bitmap == NULL) { pr_err("IR%d: failed to allocate bitmap\n", iommu->seq_id); - __free_pages(pages, INTR_REMAP_PAGE_ORDER); - kfree(ir_table); - return -ENOMEM; + goto out_free_pages; } ir_table->base = page_address(pages); ir_table->bitmap = bitmap; - - iommu_set_irq_remapping(iommu, mode); + iommu->ir_table = ir_table; return 0; + +out_free_pages: + __free_pages(pages, INTR_REMAP_PAGE_ORDER); +out_free_table: + kfree(ir_table); + return -ENOMEM; +} + +static void intel_teardown_irq_remapping(struct intel_iommu *iommu) +{ + if (iommu && iommu->ir_table) { + free_pages((unsigned long)iommu->ir_table->base, + INTR_REMAP_PAGE_ORDER); + kfree(iommu->ir_table->bitmap); + kfree(iommu->ir_table); + iommu->ir_table = NULL; + } } /* @@ -666,9 +678,10 @@ static int __init intel_enable_irq_remapping(void) if (!ecap_ir_support(iommu->ecap)) continue; - if (intel_setup_irq_remapping(iommu, eim)) + if (intel_setup_irq_remapping(iommu)) goto error; + iommu_set_irq_remapping(iommu, eim); setup = 1; } @@ -699,12 +712,13 @@ static int __init intel_enable_irq_remapping(void) return -1; } -static void ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope, - struct intel_iommu *iommu) +static int ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope, + struct intel_iommu *iommu, + struct acpi_dmar_hardware_unit *drhd) { struct acpi_dmar_pci_path *path; u8 bus; - int count; + int count, free = -1; bus = scope->bus; path = (struct acpi_dmar_pci_path *)(scope + 1); @@ -720,19 +734,36 @@ static void ir_parse_one_hpet_scope(struct acpi_dmar_device_scope *scope, PCI_SECONDARY_BUS); path++; } - ir_hpet[ir_hpet_num].bus = bus; - ir_hpet[ir_hpet_num].devfn = PCI_DEVFN(path->device, path->function); - ir_hpet[ir_hpet_num].iommu = iommu; - ir_hpet[ir_hpet_num].id = scope->enumeration_id; - ir_hpet_num++; + + for (count = 0; count < MAX_HPET_TBS; count++) { + if (ir_hpet[count].iommu == iommu && + ir_hpet[count].id == scope->enumeration_id) + return 0; + else if (ir_hpet[count].iommu == NULL && free == -1) + free = count; + } + if (free == -1) { + pr_warn("Exceeded Max HPET blocks\n"); + return -ENOSPC; + } + + ir_hpet[free].iommu = iommu; + ir_hpet[free].id = scope->enumeration_id; + ir_hpet[free].bus = bus; + ir_hpet[free].devfn = PCI_DEVFN(path->device, path->function); + pr_info("HPET id %d under DRHD base 0x%Lx\n", + scope->enumeration_id, drhd->address); + + return 0; } -static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, - struct intel_iommu *iommu) +static int ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, + struct intel_iommu *iommu, + struct acpi_dmar_hardware_unit *drhd) { struct acpi_dmar_pci_path *path; u8 bus; - int count; + int count, free = -1; bus = scope->bus; path = (struct acpi_dmar_pci_path *)(scope + 1); @@ -749,54 +780,63 @@ static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, path++; } - ir_ioapic[ir_ioapic_num].bus = bus; - ir_ioapic[ir_ioapic_num].devfn = PCI_DEVFN(path->device, path->function); - ir_ioapic[ir_ioapic_num].iommu = iommu; - ir_ioapic[ir_ioapic_num].id = scope->enumeration_id; - ir_ioapic_num++; + for (count = 0; count < MAX_IO_APICS; count++) { + if (ir_ioapic[count].iommu == iommu && + ir_ioapic[count].id == scope->enumeration_id) + return 0; + else if (ir_ioapic[count].iommu == NULL && free == -1) + free = count; + } + if (free == -1) { + pr_warn("Exceeded Max IO APICS\n"); + return -ENOSPC; + } + + ir_ioapic[free].bus = bus; + ir_ioapic[free].devfn = PCI_DEVFN(path->device, path->function); + ir_ioapic[free].iommu = iommu; + ir_ioapic[free].id = scope->enumeration_id; + pr_info("IOAPIC id %d under DRHD base 0x%Lx IOMMU %d\n", + scope->enumeration_id, drhd->address, iommu->seq_id); + + return 0; } static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header, struct intel_iommu *iommu) { + int ret = 0; struct acpi_dmar_hardware_unit *drhd; struct acpi_dmar_device_scope *scope; void *start, *end; drhd = (struct acpi_dmar_hardware_unit *)header; - start = (void *)(drhd + 1); end = ((void *)drhd) + header->length; - while (start < end) { + while (start < end && ret == 0) { scope = start; - if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_IOAPIC) { - if (ir_ioapic_num == MAX_IO_APICS) { - printk(KERN_WARNING "Exceeded Max IO APICS\n"); - return -1; - } - - printk(KERN_INFO "IOAPIC id %d under DRHD base " - " 0x%Lx IOMMU %d\n", scope->enumeration_id, - drhd->address, iommu->seq_id); + if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_IOAPIC) + ret = ir_parse_one_ioapic_scope(scope, iommu, drhd); + else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) + ret = ir_parse_one_hpet_scope(scope, iommu, drhd); + start += scope->length; + } - ir_parse_one_ioapic_scope(scope, iommu); - } else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) { - if (ir_hpet_num == MAX_HPET_TBS) { - printk(KERN_WARNING "Exceeded Max HPET blocks\n"); - return -1; - } + return ret; +} - printk(KERN_INFO "HPET id %d under DRHD base" - " 0x%Lx\n", scope->enumeration_id, - drhd->address); +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu) +{ + int i; - ir_parse_one_hpet_scope(scope, iommu); - } - start += scope->length; - } + for (i = 0; i < MAX_HPET_TBS; i++) + if (ir_hpet[i].iommu == iommu) + ir_hpet[i].iommu = NULL; - return 0; + for (i = 0; i < MAX_IO_APICS; i++) + if (ir_ioapic[i].iommu == iommu) + ir_ioapic[i].iommu = NULL; } /* @@ -1172,7 +1212,85 @@ struct irq_remap_ops intel_irq_remap_ops = { .alloc_hpet_msi = intel_alloc_hpet_msi, }; +/* + * Support of Interrupt Remapping Unit Hotplug + */ +static int dmar_ir_add(struct dmar_drhd_unit *dmaru, struct intel_iommu *iommu) +{ + int ret; + int eim = x2apic_enabled(); + + if (eim && !ecap_eim_support(iommu->ecap)) { + pr_info("DRHD %Lx: EIM not supported by DRHD, ecap %Lx\n", + iommu->reg_phys, iommu->ecap); + return -ENODEV; + } + + if (ir_parse_ioapic_hpet_scope(dmaru->hdr, iommu)) { + pr_warn("DRHD %Lx: failed to parse managed IOAPIC/HPET\n", + iommu->reg_phys); + return -ENODEV; + } + + /* TODO: check all IOAPICs are covered by IOMMU */ + + /* Setup Interrupt-remapping now. */ + ret = intel_setup_irq_remapping(iommu); + if (ret) { + pr_err("DRHD %Lx: failed to allocate resource\n", + iommu->reg_phys); + ir_remove_ioapic_hpet_scope(iommu); + return ret; + } + + if (!iommu->qi) { + /* Clear previous faults. */ + dmar_fault(-1, iommu); + iommu_disable_irq_remapping(iommu); + dmar_disable_qi(iommu); + } + + /* Enable queued invalidation */ + ret = dmar_enable_qi(iommu); + if (!ret) { + iommu_set_irq_remapping(iommu, eim); + } else { + pr_err("DRHD %Lx: failed to enable queued invalidation, ecap %Lx, ret %d\n", + iommu->reg_phys, iommu->ecap, ret); + intel_teardown_irq_remapping(iommu); + ir_remove_ioapic_hpet_scope(iommu); + } + + return ret; +} + int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert) { - return irq_remapping_enabled ? -ENOSYS : 0; + int ret = 0; + struct intel_iommu *iommu = dmaru->iommu; + + if (!irq_remapping_enabled) + return 0; + if (iommu == NULL) + return -EINVAL; + if (!ecap_ir_support(iommu->ecap)) + return 0; + + if (insert) { + if (!iommu->ir_table) + ret = dmar_ir_add(dmaru, iommu); + } else { + if (iommu->ir_table) { + if (!bitmap_empty(iommu->ir_table->bitmap, + INTR_REMAP_TABLE_ENTRIES)) { + ret = -EBUSY; + } else { + iommu_disable_irq_remapping(iommu); + intel_teardown_irq_remapping(iommu); + ir_remove_ioapic_hpet_scope(iommu); + } + } + } + + return ret; } -- GitLab From 51acce33c4df6ee23b5ad4c2e6c239e0d6f25771 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:48:01 +0800 Subject: [PATCH 5164/9457] iommu/vt-d: Enhance error recovery in function intel_enable_irq_remapping() Enhance error recovery in function intel_enable_irq_remapping() by tearing down all created data structures. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 7af0b56dc2d1..27541d440849 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -702,9 +702,11 @@ static int __init intel_enable_irq_remapping(void) return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; error: - /* - * handle error condition gracefully here! - */ + for_each_iommu(iommu, drhd) + if (ecap_ir_support(iommu->ecap)) { + iommu_disable_irq_remapping(iommu); + intel_teardown_irq_remapping(iommu); + } if (x2apic_present) pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n"); -- GitLab From ffebeb46dd34736c90ffbca1ccb0bef8f4827c44 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:48:02 +0800 Subject: [PATCH 5165/9457] iommu/vt-d: Enhance intel-iommu driver to support DMAR unit hotplug Implement required callback functions for intel-iommu driver to support DMAR unit hotplug. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 206 ++++++++++++++++++++++++++---------- 1 file changed, 151 insertions(+), 55 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 7c49ab51904f..99bf651234a6 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1127,8 +1127,11 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) unsigned long flags; root = (struct root_entry *)alloc_pgtable_page(iommu->node); - if (!root) + if (!root) { + pr_err("IOMMU: allocating root entry for %s failed\n", + iommu->name); return -ENOMEM; + } __iommu_flush_cache(iommu, root, ROOT_SIZE); @@ -1468,7 +1471,7 @@ static int iommu_init_domains(struct intel_iommu *iommu) return 0; } -static void free_dmar_iommu(struct intel_iommu *iommu) +static void disable_dmar_iommu(struct intel_iommu *iommu) { struct dmar_domain *domain; int i; @@ -1492,11 +1495,16 @@ static void free_dmar_iommu(struct intel_iommu *iommu) if (iommu->gcmd & DMA_GCMD_TE) iommu_disable_translation(iommu); +} - kfree(iommu->domains); - kfree(iommu->domain_ids); - iommu->domains = NULL; - iommu->domain_ids = NULL; +static void free_dmar_iommu(struct intel_iommu *iommu) +{ + if ((iommu->domains) && (iommu->domain_ids)) { + kfree(iommu->domains); + kfree(iommu->domain_ids); + iommu->domains = NULL; + iommu->domain_ids = NULL; + } g_iommus[iommu->seq_id] = NULL; @@ -2703,6 +2711,41 @@ static int __init iommu_prepare_static_identity_mapping(int hw) return 0; } +static void intel_iommu_init_qi(struct intel_iommu *iommu) +{ + /* + * Start from the sane iommu hardware state. + * If the queued invalidation is already initialized by us + * (for example, while enabling interrupt-remapping) then + * we got the things already rolling from a sane state. + */ + if (!iommu->qi) { + /* + * Clear any previous faults. + */ + dmar_fault(-1, iommu); + /* + * Disable queued invalidation if supported and already enabled + * before OS handover. + */ + dmar_disable_qi(iommu); + } + + if (dmar_enable_qi(iommu)) { + /* + * Queued Invalidate not enabled, use Register Based Invalidate + */ + iommu->flush.flush_context = __iommu_flush_context; + iommu->flush.flush_iotlb = __iommu_flush_iotlb; + pr_info("IOMMU: %s using Register based invalidation\n", + iommu->name); + } else { + iommu->flush.flush_context = qi_flush_context; + iommu->flush.flush_iotlb = qi_flush_iotlb; + pr_info("IOMMU: %s using Queued invalidation\n", iommu->name); + } +} + static int __init init_dmars(void) { struct dmar_drhd_unit *drhd; @@ -2731,6 +2774,10 @@ static int __init init_dmars(void) DMAR_UNITS_SUPPORTED); } + /* Preallocate enough resources for IOMMU hot-addition */ + if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) + g_num_of_iommus = DMAR_UNITS_SUPPORTED; + g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), GFP_KERNEL); if (!g_iommus) { @@ -2759,58 +2806,14 @@ static int __init init_dmars(void) * among all IOMMU's. Need to Split it later. */ ret = iommu_alloc_root_entry(iommu); - if (ret) { - printk(KERN_ERR "IOMMU: allocate root entry failed\n"); + if (ret) goto free_iommu; - } if (!ecap_pass_through(iommu->ecap)) hw_pass_through = 0; } - /* - * Start from the sane iommu hardware state. - */ - for_each_active_iommu(iommu, drhd) { - /* - * If the queued invalidation is already initialized by us - * (for example, while enabling interrupt-remapping) then - * we got the things already rolling from a sane state. - */ - if (iommu->qi) - continue; - - /* - * Clear any previous faults. - */ - dmar_fault(-1, iommu); - /* - * Disable queued invalidation if supported and already enabled - * before OS handover. - */ - dmar_disable_qi(iommu); - } - - for_each_active_iommu(iommu, drhd) { - if (dmar_enable_qi(iommu)) { - /* - * Queued Invalidate not enabled, use Register Based - * Invalidate - */ - iommu->flush.flush_context = __iommu_flush_context; - iommu->flush.flush_iotlb = __iommu_flush_iotlb; - printk(KERN_INFO "IOMMU %d 0x%Lx: using Register based " - "invalidation\n", - iommu->seq_id, - (unsigned long long)drhd->reg_base_addr); - } else { - iommu->flush.flush_context = qi_flush_context; - iommu->flush.flush_iotlb = qi_flush_iotlb; - printk(KERN_INFO "IOMMU %d 0x%Lx: using Queued " - "invalidation\n", - iommu->seq_id, - (unsigned long long)drhd->reg_base_addr); - } - } + for_each_active_iommu(iommu, drhd) + intel_iommu_init_qi(iommu); if (iommu_pass_through) iommu_identity_mapping |= IDENTMAP_ALL; @@ -2896,8 +2899,10 @@ static int __init init_dmars(void) return 0; free_iommu: - for_each_active_iommu(iommu, drhd) + for_each_active_iommu(iommu, drhd) { + disable_dmar_iommu(iommu); free_dmar_iommu(iommu); + } kfree(deferred_flush); free_g_iommus: kfree(g_iommus); @@ -3803,9 +3808,100 @@ int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg) return 0; } +static int intel_iommu_add(struct dmar_drhd_unit *dmaru) +{ + int sp, ret = 0; + struct intel_iommu *iommu = dmaru->iommu; + + if (g_iommus[iommu->seq_id]) + return 0; + + if (hw_pass_through && !ecap_pass_through(iommu->ecap)) { + pr_warn("IOMMU: %s doesn't support hardware pass through.\n", + iommu->name); + return -ENXIO; + } + if (!ecap_sc_support(iommu->ecap) && + domain_update_iommu_snooping(iommu)) { + pr_warn("IOMMU: %s doesn't support snooping.\n", + iommu->name); + return -ENXIO; + } + sp = domain_update_iommu_superpage(iommu) - 1; + if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) { + pr_warn("IOMMU: %s doesn't support large page.\n", + iommu->name); + return -ENXIO; + } + + /* + * Disable translation if already enabled prior to OS handover. + */ + if (iommu->gcmd & DMA_GCMD_TE) + iommu_disable_translation(iommu); + + g_iommus[iommu->seq_id] = iommu; + ret = iommu_init_domains(iommu); + if (ret == 0) + ret = iommu_alloc_root_entry(iommu); + if (ret) + goto out; + + if (dmaru->ignored) { + /* + * we always have to disable PMRs or DMA may fail on this device + */ + if (force_on) + iommu_disable_protect_mem_regions(iommu); + return 0; + } + + intel_iommu_init_qi(iommu); + iommu_flush_write_buffer(iommu); + ret = dmar_set_interrupt(iommu); + if (ret) + goto disable_iommu; + + iommu_set_root_entry(iommu); + iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL); + iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH); + iommu_enable_translation(iommu); + + if (si_domain) { + ret = iommu_attach_domain(si_domain, iommu); + if (ret < 0 || si_domain->id != ret) + goto disable_iommu; + domain_attach_iommu(si_domain, iommu); + } + + iommu_disable_protect_mem_regions(iommu); + return 0; + +disable_iommu: + disable_dmar_iommu(iommu); +out: + free_dmar_iommu(iommu); + return ret; +} + int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert) { - return intel_iommu_enabled ? -ENOSYS : 0; + int ret = 0; + struct intel_iommu *iommu = dmaru->iommu; + + if (!intel_iommu_enabled) + return 0; + if (iommu == NULL) + return -EINVAL; + + if (insert) { + ret = intel_iommu_add(dmaru); + } else { + disable_dmar_iommu(iommu); + free_dmar_iommu(iommu); + } + + return ret; } static void intel_iommu_free_dmars(void) -- GitLab From 30badc9543490f41497c42f004db02f1e8a29341 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 11:31:23 +0100 Subject: [PATCH 5166/9457] GFS2: Deletion of unnecessary checks before two function calls The functions iput() and put_pid() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Steven Whitehouse --- fs/gfs2/glock.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8f0c19d1d943..a23524aa3eac 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -836,8 +836,7 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder * gh->gh_flags = flags; gh->gh_iflags = 0; gh->gh_ip = _RET_IP_; - if (gh->gh_owner_pid) - put_pid(gh->gh_owner_pid); + put_pid(gh->gh_owner_pid); gh->gh_owner_pid = get_pid(task_pid(current)); } -- GitLab From 864b94adfcba752aa902ee34497bbe58b97aa8d3 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Sun, 9 Nov 2014 22:48:03 +0800 Subject: [PATCH 5167/9457] pci, ACPI, iommu: Enhance pci_root to support DMAR device hotplug Finally enhance pci_root driver to support DMAR device hotplug when hot-plugging PCI host bridges. Signed-off-by: Jiang Liu Reviewed-by: Yijing Wang Acked-by: Bjorn Helgaas Signed-off-by: Joerg Roedel --- drivers/acpi/pci_root.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index cd4de7e038ea..c6bcb8c719d8 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -525,6 +526,7 @@ static int acpi_pci_root_add(struct acpi_device *device, struct acpi_pci_root *root; acpi_handle handle = device->handle; int no_aspm = 0, clear_aspm = 0; + bool hotadd = system_state != SYSTEM_BOOTING; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -571,6 +573,11 @@ static int acpi_pci_root_add(struct acpi_device *device, strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); device->driver_data = root; + if (hotadd && dmar_device_add(handle)) { + result = -ENXIO; + goto end; + } + pr_info(PREFIX "%s [%s] (domain %04x %pR)\n", acpi_device_name(device), acpi_device_bid(device), root->segment, &root->secondary); @@ -597,7 +604,7 @@ static int acpi_pci_root_add(struct acpi_device *device, root->segment, (unsigned int)root->secondary.start); device->driver_data = NULL; result = -ENODEV; - goto end; + goto remove_dmar; } if (clear_aspm) { @@ -611,7 +618,7 @@ static int acpi_pci_root_add(struct acpi_device *device, if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); - if (system_state != SYSTEM_BOOTING) { + if (hotadd) { pcibios_resource_survey_bus(root->bus); pci_assign_unassigned_root_bus_resources(root->bus); } @@ -621,6 +628,9 @@ static int acpi_pci_root_add(struct acpi_device *device, pci_unlock_rescan_remove(); return 1; +remove_dmar: + if (hotadd) + dmar_device_remove(handle); end: kfree(root); return result; @@ -639,6 +649,8 @@ static void acpi_pci_root_remove(struct acpi_device *device) pci_remove_root_bus(root->bus); + dmar_device_remove(device->handle); + pci_unlock_rescan_remove(); kfree(root); -- GitLab From fcc50e5cd2deb8316d19e446d8efdfc9b35646ef Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 17 Nov 2014 23:17:03 +0800 Subject: [PATCH 5168/9457] spi: sirf: assign spi_master's max_speed_hz member if spi device has no frequency, spi core will setup the default frequency to max_speed_hz of spi_master according to int spi_setup(struct spi_device *spi) { ... if (!spi->max_speed_hz) spi->max_speed_hz = spi->master->max_speed_hz; ... } this patch moves CSR SiRFSoC SPI frequency set to follow SPI core behaviour. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 39e2c0a55a28..bf3c6bc77530 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -134,6 +134,7 @@ ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE)) #define SIRFSOC_MAX_CMD_BYTES 4 +#define SIRFSOC_SPI_DEFAULT_FRQ 1000000 struct sirfsoc_spi { struct spi_bitbang bitbang; @@ -629,9 +630,6 @@ static int spi_sirfsoc_setup(struct spi_device *spi) { struct sirfsoc_spi *sspi; - if (!spi->max_speed_hz) - return -EINVAL; - sspi = spi_master_get_devdata(spi->master); if (spi->cs_gpio == -ENOENT) @@ -683,6 +681,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32); + master->max_speed_hz = SIRFSOC_SPI_DEFAULT_FRQ; sspi->bitbang.master->dev.of_node = pdev->dev.of_node; /* request DMA channels */ -- GitLab From efed421a94e62a7ddbc76acba4312b70e4be958f Mon Sep 17 00:00:00 2001 From: Ashwini Pahuja Date: Thu, 13 Nov 2014 10:22:32 -0800 Subject: [PATCH 5169/9457] usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC This patch adds a UDC driver for Broadcom's USB3.0 Peripheral core named BDC. BDC supports control traffic on ep0 and bulk/Int/Isoch traffic on all other endpoints. [ balbi@ti.com : fix build error on randconfig due to lack of ] Signed-off-by: Ashwini Pahuja Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/Kconfig | 2 + drivers/usb/gadget/udc/Makefile | 1 + drivers/usb/gadget/udc/bdc/Kconfig | 21 + drivers/usb/gadget/udc/bdc/Makefile | 8 + drivers/usb/gadget/udc/bdc/bdc.h | 490 ++++++ drivers/usb/gadget/udc/bdc/bdc_cmd.c | 376 +++++ drivers/usb/gadget/udc/bdc/bdc_cmd.h | 29 + drivers/usb/gadget/udc/bdc/bdc_core.c | 533 +++++++ drivers/usb/gadget/udc/bdc/bdc_dbg.c | 123 ++ drivers/usb/gadget/udc/bdc/bdc_dbg.h | 37 + drivers/usb/gadget/udc/bdc/bdc_ep.c | 2023 +++++++++++++++++++++++++ drivers/usb/gadget/udc/bdc/bdc_ep.h | 22 + drivers/usb/gadget/udc/bdc/bdc_pci.c | 132 ++ drivers/usb/gadget/udc/bdc/bdc_udc.c | 587 +++++++ 14 files changed, 4384 insertions(+) create mode 100644 drivers/usb/gadget/udc/bdc/Kconfig create mode 100644 drivers/usb/gadget/udc/bdc/Makefile create mode 100644 drivers/usb/gadget/udc/bdc/bdc.h create mode 100644 drivers/usb/gadget/udc/bdc/bdc_cmd.c create mode 100644 drivers/usb/gadget/udc/bdc/bdc_cmd.h create mode 100644 drivers/usb/gadget/udc/bdc/bdc_core.c create mode 100644 drivers/usb/gadget/udc/bdc/bdc_dbg.c create mode 100644 drivers/usb/gadget/udc/bdc/bdc_dbg.h create mode 100644 drivers/usb/gadget/udc/bdc/bdc_ep.c create mode 100644 drivers/usb/gadget/udc/bdc/bdc_ep.h create mode 100644 drivers/usb/gadget/udc/bdc/bdc_pci.c create mode 100644 drivers/usb/gadget/udc/bdc/bdc_udc.c diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 217365d35a25..b8e213eb36cc 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -241,6 +241,8 @@ config USB_M66592 dynamically linked module called "m66592_udc" and force all gadget drivers to also be dynamically linked. +source "drivers/usb/gadget/udc/bdc/Kconfig" + # # Controllers available only in discrete form (and all PCI controllers) # diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index a7f4491593f1..fba2049bf985 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o obj-$(CONFIG_USB_GR_UDC) += gr_udc.o obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o +obj-$(CONFIG_USB_BDC_UDC) += bdc/ diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig new file mode 100644 index 000000000000..0d7b8c9f72fd --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -0,0 +1,21 @@ +config USB_BDC_UDC + tristate "Broadcom USB3.0 device controller IP driver(BDC)" + depends on USB_GADGET && HAS_DMA + + help + BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP + then select this driver. + + Say "y" here to link the driver statically, or "m" to build a dynamically + linked module called "bdc". + +if USB_BDC_UDC + +comment "Platform Support" +config USB_BDC_PCI + tristate "BDC support for PCIe based platforms" + depends on PCI + default USB_BDC_UDC + help + Enable support for platforms which have BDC connected through PCIe, such as Lego3 FPGA platform. +endif diff --git a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile new file mode 100644 index 000000000000..5cf6a3bcdf0f --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/Makefile @@ -0,0 +1,8 @@ +obj-$(CONFIG_USB_BDC_UDC) += bdc.o +bdc-y := bdc_core.o bdc_cmd.o bdc_ep.o bdc_udc.o + +ifneq ($(CONFIG_USB_GADGET_VERBOSE),) + bdc-y += bdc_dbg.o +endif + +obj-$(CONFIG_USB_BDC_PCI) += bdc_pci.o diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h new file mode 100644 index 000000000000..dc18a20bf040 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc.h @@ -0,0 +1,490 @@ +/* + * bdc.h - header for the BRCM BDC USB3.0 device controller + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __LINUX_BDC_H__ +#define __LINUX_BDC_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BRCM_BDC_NAME "bdc_usb3" +#define BRCM_BDC_DESC "BDC device controller driver" + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +/* BDC command operation timeout in usec*/ +#define BDC_CMD_TIMEOUT 1000 +/* BDC controller operation timeout in usec*/ +#define BDC_COP_TIMEOUT 500 + +/* + * Maximum size of ep0 response buffer for ch9 requests, + * the set_sel request uses 6 so far, the max. +*/ +#define EP0_RESPONSE_BUFF 6 +/* Start with SS as default */ +#define EP0_MAX_PKT_SIZE 512 + +/* 64 entries in a SRR */ +#define NUM_SR_ENTRIES 64 + +/* Num of bds per table */ +#define NUM_BDS_PER_TABLE 32 + +/* Num of tables in bd list for control,bulk and Int ep */ +#define NUM_TABLES 2 + +/* Num of tables in bd list for Isoch ep */ +#define NUM_TABLES_ISOCH 6 + +/* U1 Timeout default: 248usec */ +#define U1_TIMEOUT 0xf8 + +/* Interrupt coalescence in usec */ +#define INT_CLS 500 + +/* Register offsets */ +/* Configuration and Capability registers */ +#define BDC_BDCCFG0 0x00 +#define BDC_BDCCFG1 0x04 +#define BDC_BDCCAP0 0x08 +#define BDC_BDCCAP1 0x0c +#define BDC_CMDPAR0 0x10 +#define BDC_CMDPAR1 0x14 +#define BDC_CMDPAR2 0x18 +#define BDC_CMDSC 0x1c +#define BDC_USPC 0x20 +#define BDC_USPPMS 0x28 +#define BDC_USPPM2 0x2c +#define BDC_SPBBAL 0x38 +#define BDC_SPBBAH 0x3c +#define BDC_BDCSC 0x40 +#define BDC_XSFNTF 0x4c + +#define BDC_DVCSA 0x50 +#define BDC_DVCSB 0x54 +#define BDC_EPSTS0(n) (0x60 + (n * 0x10)) +#define BDC_EPSTS1(n) (0x64 + (n * 0x10)) +#define BDC_EPSTS2(n) (0x68 + (n * 0x10)) +#define BDC_EPSTS3(n) (0x6c + (n * 0x10)) +#define BDC_EPSTS4(n) (0x70 + (n * 0x10)) +#define BDC_EPSTS5(n) (0x74 + (n * 0x10)) +#define BDC_EPSTS6(n) (0x78 + (n * 0x10)) +#define BDC_EPSTS7(n) (0x7c + (n * 0x10)) +#define BDC_SRRBAL(n) (0x200 + (n * 0x10)) +#define BDC_SRRBAH(n) (0x204 + (n * 0x10)) +#define BDC_SRRINT(n) (0x208 + (n * 0x10)) +#define BDC_INTCTLS(n) (0x20c + (n * 0x10)) + +/* Extended capability regs */ +#define BDC_FSCNOC 0xcd4 +#define BDC_FSCNIC 0xce4 +#define NUM_NCS(p) (p >> 28) + +/* Register bit fields and Masks */ +/* BDC Configuration 0 */ +#define BDC_PGS(p) (((p) & (0x7 << 8)) >> 8) +#define BDC_SPB(p) (p & 0x7) + +/* BDC Capability1 */ +#define BDC_P64 (1 << 0) + +/* BDC Command register */ +#define BDC_CMD_FH 0xe +#define BDC_CMD_DNC 0x6 +#define BDC_CMD_EPO 0x4 +#define BDC_CMD_BLA 0x3 +#define BDC_CMD_EPC 0x2 +#define BDC_CMD_DVC 0x1 +#define BDC_CMD_CWS (0x1 << 5) +#define BDC_CMD_CST(p) (((p) & (0xf << 6))>>6) +#define BDC_CMD_EPN(p) ((p & 0x1f) << 10) +#define BDC_SUB_CMD_ADD (0x1 << 17) +#define BDC_SUB_CMD_FWK (0x4 << 17) +/* Reset sequence number */ +#define BDC_CMD_EPO_RST_SN (0x1 << 16) +#define BDC_CMD_EP0_XSD (0x1 << 16) +#define BDC_SUB_CMD_ADD_EP (0x1 << 17) +#define BDC_SUB_CMD_DRP_EP (0x2 << 17) +#define BDC_SUB_CMD_EP_STP (0x2 << 17) +#define BDC_SUB_CMD_EP_STL (0x4 << 17) +#define BDC_SUB_CMD_EP_RST (0x1 << 17) +#define BDC_CMD_SRD (1 << 27) + +/* CMD completion status */ +#define BDC_CMDS_SUCC 0x1 +#define BDC_CMDS_PARA 0x3 +#define BDC_CMDS_STAT 0x4 +#define BDC_CMDS_FAIL 0x5 +#define BDC_CMDS_INTL 0x6 +#define BDC_CMDS_BUSY 0xf + +/* CMDSC Param 2 shifts */ +#define EPT_SHIFT 22 +#define MP_SHIFT 10 +#define MB_SHIFT 6 +#define EPM_SHIFT 4 + +/* BDC USPSC */ +#define BDC_VBC (1 << 31) +#define BDC_PRC (1 << 30) +#define BDC_PCE (1 << 29) +#define BDC_CFC (1 << 28) +#define BDC_PCC (1 << 27) +#define BDC_PSC (1 << 26) +#define BDC_VBS (1 << 25) +#define BDC_PRS (1 << 24) +#define BDC_PCS (1 << 23) +#define BDC_PSP(p) (((p) & (0x7 << 20))>>20) +#define BDC_SCN (1 << 8) +#define BDC_SDC (1 << 7) +#define BDC_SWS (1 << 4) + +#define BDC_USPSC_RW (BDC_SCN|BDC_SDC|BDC_SWS|0xf) +#define BDC_PSP(p) (((p) & (0x7 << 20))>>20) + +#define BDC_SPEED_FS 0x1 +#define BDC_SPEED_LS 0x2 +#define BDC_SPEED_HS 0x3 +#define BDC_SPEED_SS 0x4 + +#define BDC_PST(p) (p & 0xf) +#define BDC_PST_MASK 0xf + +/* USPPMS */ +#define BDC_U2E (0x1 << 31) +#define BDC_U1E (0x1 << 30) +#define BDC_U2A (0x1 << 29) +#define BDC_PORT_W1S (0x1 << 17) +#define BDC_U1T(p) ((p) & 0xff) +#define BDC_U2T(p) (((p) & 0xff) << 8) +#define BDC_U1T_MASK 0xff + +/* USBPM2 */ +/* Hardware LPM Enable */ +#define BDC_HLE (1 << 16) + +/* BDC Status and Control */ +#define BDC_COP_RST (1 << 29) +#define BDC_COP_RUN (2 << 29) +#define BDC_COP_STP (4 << 29) + +#define BDC_COP_MASK (BDC_COP_RST|BDC_COP_RUN|BDC_COP_STP) + +#define BDC_COS (1 << 28) +#define BDC_CSTS(p) (((p) & (0x7 << 20)) >> 20) +#define BDC_MASK_MCW (1 << 7) +#define BDC_GIE (1 << 1) +#define BDC_GIP (1 << 0) + +#define BDC_HLT 1 +#define BDC_NOR 2 +#define BDC_OIP 7 + +/* Buffer descriptor and Status report bit fields and masks */ +#define BD_TYPE_BITMASK (0xf) +#define BD_CHAIN 0xf + +#define BD_TFS_SHIFT 4 +#define BD_SOT (1 << 26) +#define BD_EOT (1 << 27) +#define BD_ISP (1 << 29) +#define BD_IOC (1 << 30) +#define BD_SBF (1 << 31) + +#define BD_INTR_TARGET(p) (((p) & 0x1f) << 27) + +#define BDC_SRR_RWS (1 << 4) +#define BDC_SRR_RST (1 << 3) +#define BDC_SRR_ISR (1 << 2) +#define BDC_SRR_IE (1 << 1) +#define BDC_SRR_IP (1 << 0) +#define BDC_SRR_EPI(p) (((p) & (0xff << 24)) >> 24) +#define BDC_SRR_DPI(p) (((p) & (0xff << 16)) >> 16) +#define BDC_SRR_DPI_MASK 0x00ff0000 + +#define MARK_CHAIN_BD (BD_CHAIN|BD_EOT|BD_SOT) + +/* Control transfer BD specific fields */ +#define BD_DIR_IN (1 << 25) + +#define BDC_PTC_MASK 0xf0000000 + +/* status report defines */ +#define SR_XSF 0 +#define SR_USPC 4 +#define SR_BD_LEN(p) (p & 0xffffff) + +#define XSF_SUCC 0x1 +#define XSF_SHORT 0x3 +#define XSF_BABB 0x4 +#define XSF_SETUP_RECV 0x6 +#define XSF_DATA_START 0x7 +#define XSF_STATUS_START 0x8 + +#define XSF_STS(p) (((p) >> 28) & 0xf) + +/* Transfer BD fields */ +#define BD_LEN(p) ((p) & 0x1ffff) +#define BD_LTF (1 << 25) +#define BD_TYPE_DS 0x1 +#define BD_TYPE_SS 0x2 + +#define BDC_EP_ENABLED (1 << 0) +#define BDC_EP_STALL (1 << 1) +#define BDC_EP_STOP (1 << 2) + +/* One BD can transfer max 65536 bytes */ +#define BD_MAX_BUFF_SIZE (1 << 16) +/* Maximum bytes in one XFR, Refer to BDC spec */ +#define MAX_XFR_LEN 16777215 + +/* defines for Force Header command */ +#define DEV_NOTF_TYPE 6 +#define FWK_SUBTYPE 1 +#define TRA_PACKET 4 + +#define to_bdc_ep(e) container_of(e, struct bdc_ep, usb_ep) +#define to_bdc_req(r) container_of(r, struct bdc_req, usb_req) +#define gadget_to_bdc(g) container_of(g, struct bdc, gadget) + +/* FUNCTION WAKE DEV NOTIFICATION interval, USB3 spec table 8.13 */ +#define BDC_TNOTIFY 2500 /*in ms*/ +/* Devstatus bitfields */ +#define REMOTE_WAKEUP_ISSUED (1 << 16) +#define DEVICE_SUSPENDED (1 << 17) +#define FUNC_WAKE_ISSUED (1 << 18) +#define REMOTE_WAKE_ENABLE (1 << USB_DEVICE_REMOTE_WAKEUP) + +/* On disconnect, preserve these bits and clear rest */ +#define DEVSTATUS_CLEAR (1 << USB_DEVICE_SELF_POWERED) +/* Hardware and software Data structures */ + +/* Endpoint bd: buffer descriptor */ +struct bdc_bd { + __le32 offset[4]; +}; + +/* Status report in Status report ring(srr) */ +struct bdc_sr { + __le32 offset[4]; +}; + +/* bd_table: contigous bd's in a table */ +struct bd_table { + struct bdc_bd *start_bd; + /* dma address of start bd of table*/ + dma_addr_t dma; +}; + +/* + * Each endpoint has a bdl(buffer descriptor list), bdl consists of 1 or more bd + * table's chained to each other through a chain bd, every table has equal + * number of bds. the software uses bdi(bd index) to refer to particular bd in + * the list. + */ +struct bd_list { + /* Array of bd table pointers*/ + struct bd_table **bd_table_array; + /* How many tables chained to each other */ + int num_tabs; + /* Max_bdi = num_tabs * num_bds_table - 1 */ + int max_bdi; + /* current enq bdi from sw point of view */ + int eqp_bdi; + /* current deq bdi from sw point of view */ + int hwd_bdi; + /* numbers of bds per table */ + int num_bds_table; +}; + +struct bdc_req; + +/* Representation of a transfer, one transfer can have multiple bd's */ +struct bd_transfer { + struct bdc_req *req; + /* start bd index */ + int start_bdi; + /* this will be the next hw dqp when this transfer completes */ + int next_hwd_bdi; + /* number of bds in this transfer */ + int num_bds; +}; + +/* + * Representation of a gadget request, every gadget request is contained + * by 1 bd_transfer. + */ +struct bdc_req { + struct usb_request usb_req; + struct list_head queue; + struct bdc_ep *ep; + /* only one Transfer per request */ + struct bd_transfer bd_xfr; + int epnum; +}; + +/* scratchpad buffer needed by bdc hardware */ +struct bdc_scratchpad { + dma_addr_t sp_dma; + void *buff; + u32 size; +}; + +/* endpoint representation */ +struct bdc_ep { + struct usb_ep usb_ep; + struct list_head queue; + struct bdc *bdc; + u8 ep_type; + u8 dir; + u8 ep_num; + const struct usb_ss_ep_comp_descriptor *comp_desc; + const struct usb_endpoint_descriptor *desc; + unsigned int flags; + char name[20]; + /* endpoint bd list*/ + struct bd_list bd_list; + /* + * HW generates extra event for multi bd tranfers, this flag helps in + * ignoring the extra event + */ + bool ignore_next_sr; +}; + +/* bdc cmmand parameter structure */ +struct bdc_cmd_params { + u32 param2; + u32 param1; + u32 param0; +}; + +/* status report ring(srr), currently one srr is supported for entire system */ +struct srr { + struct bdc_sr *sr_bds; + u16 eqp_index; + u16 dqp_index; + dma_addr_t dma_addr; +}; + +/* EP0 states */ +enum bdc_ep0_state { + WAIT_FOR_SETUP = 0, + WAIT_FOR_DATA_START, + WAIT_FOR_DATA_XMIT, + WAIT_FOR_STATUS_START, + WAIT_FOR_STATUS_XMIT, + STATUS_PENDING +}; + +/* Link states */ +enum bdc_link_state { + BDC_LINK_STATE_U0 = 0x00, + BDC_LINK_STATE_U3 = 0x03, + BDC_LINK_STATE_RX_DET = 0x05, + BDC_LINK_STATE_RESUME = 0x0f +}; + +/* representation of bdc */ +struct bdc { + struct usb_gadget gadget; + struct usb_gadget_driver *gadget_driver; + struct device *dev; + /* device lock */ + spinlock_t lock; + + /* num of endpoints for a particular instantiation of IP */ + unsigned int num_eps; + /* + * Array of ep's, it uses the same index covention as bdc hw i.e. + * 1 for ep0, 2 for 1out,3 for 1in .... + */ + struct bdc_ep **bdc_ep_array; + void __iomem *regs; + struct bdc_scratchpad scratchpad; + u32 sp_buff_size; + /* current driver supports 1 status ring */ + struct srr srr; + /* Last received setup packet */ + struct usb_ctrlrequest setup_pkt; + struct bdc_req ep0_req; + struct bdc_req status_req; + enum bdc_ep0_state ep0_state; + bool delayed_status; + bool zlp_needed; + bool reinit; + bool pullup; + /* Bits 0-15 are standard and 16-31 for proprietary information */ + u32 devstatus; + int irq; + void *mem; + u32 dev_addr; + /* DMA pools */ + struct dma_pool *bd_table_pool; + u8 test_mode; + /* array of callbacks for various status report handlers */ + void (*sr_handler[2])(struct bdc *, struct bdc_sr *); + /* ep0 callback handlers */ + void (*sr_xsf_ep0[3])(struct bdc *, struct bdc_sr *); + /* ep0 response buffer for ch9 requests like GET_STATUS and SET_SEL */ + unsigned char ep0_response_buff[EP0_RESPONSE_BUFF]; + /* + * Timer to check if host resumed transfer after bdc sent Func wake + * notification packet after a remote wakeup. if not, then resend the + * Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4 + */ + struct delayed_work func_wake_notify; +}; + +static inline u32 bdc_readl(void __iomem *base, u32 offset) +{ + return readl(base + offset); +} + +static inline void bdc_writel(void __iomem *base, u32 offset, u32 value) +{ + writel(value, base + offset); +} + +/* Buffer descriptor list operations */ +void bdc_notify_xfr(struct bdc *, u32); +void bdc_softconn(struct bdc *); +void bdc_softdisconn(struct bdc *); +int bdc_run(struct bdc *); +int bdc_stop(struct bdc *); +int bdc_reset(struct bdc *); +int bdc_udc_init(struct bdc *); +void bdc_udc_exit(struct bdc *); +int bdc_reinit(struct bdc *); + +/* Status report handlers */ +/* Upstream port status change sr */ +void bdc_sr_uspc(struct bdc *, struct bdc_sr *); +/* transfer sr */ +void bdc_sr_xsf(struct bdc *, struct bdc_sr *); +/* EP0 XSF handlers */ +void bdc_xsf_ep0_setup_recv(struct bdc *, struct bdc_sr *); +void bdc_xsf_ep0_data_start(struct bdc *, struct bdc_sr *); +void bdc_xsf_ep0_status_start(struct bdc *, struct bdc_sr *); + +#endif /* __LINUX_BDC_H__ */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c new file mode 100644 index 000000000000..6a4155c4bd86 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c @@ -0,0 +1,376 @@ +/* + * bdc_cmd.c - BRCM BDC USB3.0 device controller + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include + +#include "bdc.h" +#include "bdc_cmd.h" +#include "bdc_dbg.h" + +/* Issues a cmd to cmd processor and waits for cmd completion */ +static int bdc_issue_cmd(struct bdc *bdc, u32 cmd_sc, u32 param0, + u32 param1, u32 param2) +{ + u32 timeout = BDC_CMD_TIMEOUT; + u32 cmd_status; + u32 temp; + + bdc_writel(bdc->regs, BDC_CMDPAR0, param0); + bdc_writel(bdc->regs, BDC_CMDPAR1, param1); + bdc_writel(bdc->regs, BDC_CMDPAR2, param2); + + /* Issue the cmd */ + /* Make sure the cmd params are written before asking HW to exec cmd */ + wmb(); + bdc_writel(bdc->regs, BDC_CMDSC, cmd_sc | BDC_CMD_CWS | BDC_CMD_SRD); + do { + temp = bdc_readl(bdc->regs, BDC_CMDSC); + dev_dbg_ratelimited(bdc->dev, "cmdsc=%x", temp); + cmd_status = BDC_CMD_CST(temp); + if (cmd_status != BDC_CMDS_BUSY) { + dev_dbg(bdc->dev, + "command completed cmd_sts:%x\n", cmd_status); + return cmd_status; + } + udelay(1); + } while (timeout--); + + dev_err(bdc->dev, + "command operation timedout cmd_status=%d\n", cmd_status); + + return cmd_status; +} + +/* Submits cmd and analyze the return value of bdc_issue_cmd */ +static int bdc_submit_cmd(struct bdc *bdc, u32 cmd_sc, + u32 param0, u32 param1, u32 param2) +{ + u32 temp, cmd_status; + int reset_bdc = 0; + int ret; + + temp = bdc_readl(bdc->regs, BDC_CMDSC); + dev_dbg(bdc->dev, + "%s:CMDSC:%08x cmdsc:%08x param0=%08x param1=%08x param2=%08x\n", + __func__, temp, cmd_sc, param0, param1, param2); + + cmd_status = BDC_CMD_CST(temp); + if (cmd_status == BDC_CMDS_BUSY) { + dev_err(bdc->dev, "command processor busy: %x\n", cmd_status); + return -EBUSY; + } + ret = bdc_issue_cmd(bdc, cmd_sc, param0, param1, param2); + switch (ret) { + case BDC_CMDS_SUCC: + dev_dbg(bdc->dev, "command completed successfully\n"); + ret = 0; + break; + + case BDC_CMDS_PARA: + dev_err(bdc->dev, "command parameter error\n"); + ret = -EINVAL; + break; + + case BDC_CMDS_STAT: + dev_err(bdc->dev, "Invalid device/ep state\n"); + ret = -EINVAL; + break; + + case BDC_CMDS_FAIL: + dev_err(bdc->dev, "Command failed?\n"); + ret = -EAGAIN; + break; + + case BDC_CMDS_INTL: + dev_err(bdc->dev, "BDC Internal error\n"); + reset_bdc = 1; + ret = -ECONNRESET; + break; + + case BDC_CMDS_BUSY: + dev_err(bdc->dev, + "command timedout waited for %dusec\n", + BDC_CMD_TIMEOUT); + reset_bdc = 1; + ret = -ECONNRESET; + break; + default: + dev_dbg(bdc->dev, "Unknown command completion code:%x\n", ret); + } + + return ret; +} + +/* Deconfigure the endpoint from HW */ +int bdc_dconfig_ep(struct bdc *bdc, struct bdc_ep *ep) +{ + u32 cmd_sc; + + cmd_sc = BDC_SUB_CMD_DRP_EP|BDC_CMD_EPN(ep->ep_num)|BDC_CMD_EPC; + dev_dbg(bdc->dev, "%s ep->ep_num =%d cmd_sc=%x\n", __func__, + ep->ep_num, cmd_sc); + + return bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); +} + +/* Reinitalize the bdlist after config ep command */ +static void ep_bd_list_reinit(struct bdc_ep *ep) +{ + struct bdc *bdc = ep->bdc; + struct bdc_bd *bd; + + ep->bd_list.eqp_bdi = 0; + ep->bd_list.hwd_bdi = 0; + bd = ep->bd_list.bd_table_array[0]->start_bd; + dev_dbg(bdc->dev, "%s ep:%p bd:%p\n", __func__, ep, bd); + memset(bd, 0, sizeof(struct bdc_bd)); + bd->offset[3] |= cpu_to_le32(BD_SBF); +} + +/* Configure an endpoint */ +int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep) +{ + const struct usb_ss_ep_comp_descriptor *comp_desc; + const struct usb_endpoint_descriptor *desc; + u32 param0, param1, param2, cmd_sc; + u32 mps, mbs, mul, si; + int ret; + + desc = ep->desc; + comp_desc = ep->comp_desc; + cmd_sc = mul = mbs = param2 = 0; + param0 = lower_32_bits(ep->bd_list.bd_table_array[0]->dma); + param1 = upper_32_bits(ep->bd_list.bd_table_array[0]->dma); + cpu_to_le32s(¶m0); + cpu_to_le32s(¶m1); + + dev_dbg(bdc->dev, "%s: param0=%08x param1=%08x", + __func__, param0, param1); + si = desc->bInterval; + si = clamp_val(si, 1, 16) - 1; + + mps = usb_endpoint_maxp(desc); + mps &= 0x7ff; + param2 |= mps << MP_SHIFT; + param2 |= usb_endpoint_type(desc) << EPT_SHIFT; + + switch (bdc->gadget.speed) { + case USB_SPEED_SUPER: + if (usb_endpoint_xfer_int(desc) || + usb_endpoint_xfer_isoc(desc)) { + param2 |= si; + if (usb_endpoint_xfer_isoc(desc) && comp_desc) + mul = comp_desc->bmAttributes; + + } + param2 |= mul << EPM_SHIFT; + if (comp_desc) + mbs = comp_desc->bMaxBurst; + param2 |= mbs << MB_SHIFT; + break; + + case USB_SPEED_HIGH: + if (usb_endpoint_xfer_isoc(desc) || + usb_endpoint_xfer_int(desc)) { + param2 |= si; + + mbs = (usb_endpoint_maxp(desc) & 0x1800) >> 11; + param2 |= mbs << MB_SHIFT; + } + break; + + case USB_SPEED_FULL: + case USB_SPEED_LOW: + /* the hardware accepts SI in 125usec range */ + if (usb_endpoint_xfer_isoc(desc)) + si += 3; + + /* + * FS Int endpoints can have si of 1-255ms but the controller + * accepts 2^bInterval*125usec, so convert ms to nearest power + * of 2 + */ + if (usb_endpoint_xfer_int(desc)) + si = fls(desc->bInterval * 8) - 1; + + param2 |= si; + break; + default: + dev_err(bdc->dev, "UNKNOWN speed ERR\n"); + return -EINVAL; + } + + cmd_sc |= BDC_CMD_EPC|BDC_CMD_EPN(ep->ep_num)|BDC_SUB_CMD_ADD_EP; + + dev_dbg(bdc->dev, "cmd_sc=%x param2=%08x\n", cmd_sc, param2); + ret = bdc_submit_cmd(bdc, cmd_sc, param0, param1, param2); + if (ret) { + dev_err(bdc->dev, "command failed :%x\n", ret); + return ret; + } + ep_bd_list_reinit(ep); + + return ret; +} + +/* + * Change the HW deq pointer, if this command is successful, HW will start + * fetching the next bd from address dma_addr. + */ +int bdc_ep_bla(struct bdc *bdc, struct bdc_ep *ep, dma_addr_t dma_addr) +{ + u32 param0, param1; + u32 cmd_sc = 0; + + dev_dbg(bdc->dev, "%s: add=%08llx\n", __func__, + (unsigned long long)(dma_addr)); + param0 = lower_32_bits(dma_addr); + param1 = upper_32_bits(dma_addr); + cpu_to_le32s(¶m0); + cpu_to_le32s(¶m1); + + cmd_sc |= BDC_CMD_EPN(ep->ep_num)|BDC_CMD_BLA; + dev_dbg(bdc->dev, "cmd_sc=%x\n", cmd_sc); + + return bdc_submit_cmd(bdc, cmd_sc, param0, param1, 0); +} + +/* Set the address sent bu Host in SET_ADD request */ +int bdc_address_device(struct bdc *bdc, u32 add) +{ + u32 cmd_sc = 0; + u32 param2; + + dev_dbg(bdc->dev, "%s: add=%d\n", __func__, add); + cmd_sc |= BDC_SUB_CMD_ADD|BDC_CMD_DVC; + param2 = add & 0x7f; + + return bdc_submit_cmd(bdc, cmd_sc, 0, 0, param2); +} + +/* Send a Function Wake notification packet using FH command */ +int bdc_function_wake_fh(struct bdc *bdc, u8 intf) +{ + u32 param0, param1; + u32 cmd_sc = 0; + + param0 = param1 = 0; + dev_dbg(bdc->dev, "%s intf=%d\n", __func__, intf); + cmd_sc |= BDC_CMD_FH; + param0 |= TRA_PACKET; + param0 |= (bdc->dev_addr << 25); + param1 |= DEV_NOTF_TYPE; + param1 |= (FWK_SUBTYPE<<4); + dev_dbg(bdc->dev, "param0=%08x param1=%08x\n", param0, param1); + + return bdc_submit_cmd(bdc, cmd_sc, param0, param1, 0); +} + +/* Send a Function Wake notification packet using DNC command */ +int bdc_function_wake(struct bdc *bdc, u8 intf) +{ + u32 cmd_sc = 0; + u32 param2 = 0; + + dev_dbg(bdc->dev, "%s intf=%d", __func__, intf); + param2 |= intf; + cmd_sc |= BDC_SUB_CMD_FWK|BDC_CMD_DNC; + + return bdc_submit_cmd(bdc, cmd_sc, 0, 0, param2); +} + +/* Stall the endpoint */ +int bdc_ep_set_stall(struct bdc *bdc, int epnum) +{ + u32 cmd_sc = 0; + + dev_dbg(bdc->dev, "%s epnum=%d\n", __func__, epnum); + /* issue a stall endpoint command */ + cmd_sc |= BDC_SUB_CMD_EP_STL | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; + + return bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); +} + +/* resets the endpoint, called when host sends CLEAR_FEATURE(HALT) */ +int bdc_ep_clear_stall(struct bdc *bdc, int epnum) +{ + struct bdc_ep *ep; + u32 cmd_sc = 0; + int ret; + + dev_dbg(bdc->dev, "%s: epnum=%d\n", __func__, epnum); + ep = bdc->bdc_ep_array[epnum]; + /* + * If we are not in stalled then stall Endpoint and issue clear stall, + * his will reset the seq number for non EP0. + */ + if (epnum != 1) { + /* if the endpoint it not stallled */ + if (!(ep->flags & BDC_EP_STALL)) { + ret = bdc_ep_set_stall(bdc, epnum); + if (ret) + return ret; + } + } + /* Preserve the seq number for ep0 only */ + if (epnum != 1) + cmd_sc |= BDC_CMD_EPO_RST_SN; + + /* issue a reset endpoint command */ + cmd_sc |= BDC_SUB_CMD_EP_RST | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; + + ret = bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); + if (ret) { + dev_err(bdc->dev, "command failed:%x\n", ret); + return ret; + } + bdc_notify_xfr(bdc, epnum); + + return ret; +} + +/* Stop the endpoint, called when software wants to dequeue some request */ +int bdc_stop_ep(struct bdc *bdc, int epnum) +{ + struct bdc_ep *ep; + u32 cmd_sc = 0; + int ret; + + ep = bdc->bdc_ep_array[epnum]; + dev_dbg(bdc->dev, "%s: ep:%s ep->flags:%08x\n", __func__, + ep->name, ep->flags); + /* Endpoint has to be in running state to execute stop ep command */ + if (!(ep->flags & BDC_EP_ENABLED)) { + dev_err(bdc->dev, "stop endpoint called for disabled ep\n"); + return -EINVAL; + } + if ((ep->flags & BDC_EP_STALL) || (ep->flags & BDC_EP_STOP)) + return 0; + + /* issue a stop endpoint command */ + cmd_sc |= BDC_CMD_EP0_XSD | BDC_SUB_CMD_EP_STP + | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; + + ret = bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); + if (ret) { + dev_err(bdc->dev, + "stop endpoint command didn't complete:%d ep:%s\n", + ret, ep->name); + return ret; + } + ep->flags |= BDC_EP_STOP; + bdc_dump_epsts(bdc); + + return ret; +} diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.h b/drivers/usb/gadget/udc/bdc/bdc_cmd.h new file mode 100644 index 000000000000..61d0e3bf9853 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.h @@ -0,0 +1,29 @@ +/* + * bdc_cmd.h - header for the BDC debug functions + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifndef __LINUX_BDC_CMD_H__ +#define __LINUX_BDC_CMD_H__ + +/* Command operations */ +int bdc_address_device(struct bdc *, u32); +int bdc_config_ep(struct bdc *, struct bdc_ep *); +int bdc_dconfig_ep(struct bdc *, struct bdc_ep *); +int bdc_stop_ep(struct bdc *, int); +int bdc_ep_set_stall(struct bdc *, int); +int bdc_ep_clear_stall(struct bdc *, int); +int bdc_ep_set_halt(struct bdc_ep *, u32 , int); +int bdc_ep_bla(struct bdc *, struct bdc_ep *, dma_addr_t); +int bdc_function_wake(struct bdc*, u8); +int bdc_function_wake_fh(struct bdc*, u8); + +#endif /* __LINUX_BDC_CMD_H__ */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c new file mode 100644 index 000000000000..c6dfef8c7bbc --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -0,0 +1,533 @@ +/* + * bdc_core.c - BRCM BDC USB3.0 device controller core operations + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bdc.h" +#include "bdc_dbg.h" + +/* Poll till controller status is not OIP */ +static int poll_oip(struct bdc *bdc, int usec) +{ + u32 status; + /* Poll till STS!= OIP */ + while (usec) { + status = bdc_readl(bdc->regs, BDC_BDCSC); + if (BDC_CSTS(status) != BDC_OIP) { + dev_dbg(bdc->dev, + "poll_oip complete status=%d", + BDC_CSTS(status)); + return 0; + } + udelay(10); + usec -= 10; + } + dev_err(bdc->dev, "Err: operation timedout BDCSC: 0x%08x\n", status); + + return -ETIMEDOUT; +} + +/* Stop the BDC controller */ +int bdc_stop(struct bdc *bdc) +{ + int ret; + u32 temp; + + dev_dbg(bdc->dev, "%s ()\n\n", __func__); + temp = bdc_readl(bdc->regs, BDC_BDCSC); + /* Check if BDC is already halted */ + if (BDC_CSTS(temp) == BDC_HLT) { + dev_vdbg(bdc->dev, "BDC already halted\n"); + return 0; + } + temp &= ~BDC_COP_MASK; + temp |= BDC_COS|BDC_COP_STP; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + + ret = poll_oip(bdc, BDC_COP_TIMEOUT); + if (ret) + dev_err(bdc->dev, "bdc stop operation failed"); + + return ret; +} + +/* Issue a reset to BDC controller */ +int bdc_reset(struct bdc *bdc) +{ + u32 temp; + int ret; + + dev_dbg(bdc->dev, "%s ()\n", __func__); + /* First halt the controller */ + ret = bdc_stop(bdc); + if (ret) + return ret; + + temp = bdc_readl(bdc->regs, BDC_BDCSC); + temp &= ~BDC_COP_MASK; + temp |= BDC_COS|BDC_COP_RST; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + ret = poll_oip(bdc, BDC_COP_TIMEOUT); + if (ret) + dev_err(bdc->dev, "bdc reset operation failed"); + + return ret; +} + +/* Run the BDC controller */ +int bdc_run(struct bdc *bdc) +{ + u32 temp; + int ret; + + dev_dbg(bdc->dev, "%s ()\n", __func__); + temp = bdc_readl(bdc->regs, BDC_BDCSC); + /* if BDC is already in running state then do not do anything */ + if (BDC_CSTS(temp) == BDC_NOR) { + dev_warn(bdc->dev, "bdc is already in running state\n"); + return 0; + } + temp &= ~BDC_COP_MASK; + temp |= BDC_COP_RUN; + temp |= BDC_COS; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + ret = poll_oip(bdc, BDC_COP_TIMEOUT); + if (ret) { + dev_err(bdc->dev, "bdc run operation failed:%d", ret); + return ret; + } + temp = bdc_readl(bdc->regs, BDC_BDCSC); + if (BDC_CSTS(temp) != BDC_NOR) { + dev_err(bdc->dev, "bdc not in normal mode after RUN op :%d\n", + BDC_CSTS(temp)); + return -ESHUTDOWN; + } + + return 0; +} + +/* + * Present the termination to the host, typically called from upstream port + * event with Vbus present =1 + */ +void bdc_softconn(struct bdc *bdc) +{ + u32 uspc; + + uspc = bdc_readl(bdc->regs, BDC_USPC); + uspc &= ~BDC_PST_MASK; + uspc |= BDC_LINK_STATE_RX_DET; + uspc |= BDC_SWS; + dev_dbg(bdc->dev, "%s () uspc=%08x\n", __func__, uspc); + bdc_writel(bdc->regs, BDC_USPC, uspc); +} + +/* Remove the termination */ +void bdc_softdisconn(struct bdc *bdc) +{ + u32 uspc; + + uspc = bdc_readl(bdc->regs, BDC_USPC); + uspc |= BDC_SDC; + uspc &= ~BDC_SCN; + dev_dbg(bdc->dev, "%s () uspc=%x\n", __func__, uspc); + bdc_writel(bdc->regs, BDC_USPC, uspc); +} + +/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */ +static int scratchpad_setup(struct bdc *bdc) +{ + int sp_buff_size; + u32 low32; + u32 upp32; + + sp_buff_size = BDC_SPB(bdc_readl(bdc->regs, BDC_BDCCFG0)); + dev_dbg(bdc->dev, "%s() sp_buff_size=%d\n", __func__, sp_buff_size); + if (!sp_buff_size) { + dev_dbg(bdc->dev, "Scratchpad buffer not needed\n"); + return 0; + } + /* Refer to BDC spec, Table 4 for description of SPB */ + sp_buff_size = 1 << (sp_buff_size + 5); + dev_dbg(bdc->dev, "Allocating %d bytes for scratchpad\n", sp_buff_size); + bdc->scratchpad.buff = dma_zalloc_coherent(bdc->dev, sp_buff_size, + &bdc->scratchpad.sp_dma, GFP_KERNEL); + + if (!bdc->scratchpad.buff) + goto fail; + + bdc->sp_buff_size = sp_buff_size; + bdc->scratchpad.size = sp_buff_size; + low32 = lower_32_bits(bdc->scratchpad.sp_dma); + upp32 = upper_32_bits(bdc->scratchpad.sp_dma); + cpu_to_le32s(&low32); + cpu_to_le32s(&upp32); + bdc_writel(bdc->regs, BDC_SPBBAL, low32); + bdc_writel(bdc->regs, BDC_SPBBAH, upp32); + return 0; + +fail: + bdc->scratchpad.buff = NULL; + + return -ENOMEM; +} + +/* Allocate the status report ring */ +static int setup_srr(struct bdc *bdc, int interrupter) +{ + dev_dbg(bdc->dev, "%s() NUM_SR_ENTRIES:%d\n", __func__, NUM_SR_ENTRIES); + /* Reset the SRR */ + bdc_writel(bdc->regs, BDC_SRRINT(0), BDC_SRR_RWS | BDC_SRR_RST); + bdc->srr.dqp_index = 0; + /* allocate the status report descriptors */ + bdc->srr.sr_bds = dma_zalloc_coherent( + bdc->dev, + NUM_SR_ENTRIES * sizeof(struct bdc_bd), + &bdc->srr.dma_addr, + GFP_KERNEL); + if (!bdc->srr.sr_bds) + return -ENOMEM; + + return 0; +} + +/* Initialize the HW regs and internal data structures */ +static void bdc_mem_init(struct bdc *bdc, bool reinit) +{ + u8 size = 0; + u32 usb2_pm; + u32 low32; + u32 upp32; + u32 temp; + + dev_dbg(bdc->dev, "%s ()\n", __func__); + bdc->ep0_state = WAIT_FOR_SETUP; + bdc->dev_addr = 0; + bdc->srr.eqp_index = 0; + bdc->srr.dqp_index = 0; + bdc->zlp_needed = false; + bdc->delayed_status = false; + + bdc_writel(bdc->regs, BDC_SPBBAL, bdc->scratchpad.sp_dma); + /* Init the SRR */ + temp = BDC_SRR_RWS | BDC_SRR_RST; + /* Reset the SRR */ + bdc_writel(bdc->regs, BDC_SRRINT(0), temp); + dev_dbg(bdc->dev, "bdc->srr.sr_bds =%p\n", bdc->srr.sr_bds); + temp = lower_32_bits(bdc->srr.dma_addr); + size = fls(NUM_SR_ENTRIES) - 2; + temp |= size; + dev_dbg(bdc->dev, "SRRBAL[0]=%08x NUM_SR_ENTRIES:%d size:%d\n", + temp, NUM_SR_ENTRIES, size); + + low32 = lower_32_bits(temp); + upp32 = upper_32_bits(bdc->srr.dma_addr); + cpu_to_le32s(&low32); + cpu_to_le32s(&upp32); + + /* Write the dma addresses into regs*/ + bdc_writel(bdc->regs, BDC_SRRBAL(0), low32); + bdc_writel(bdc->regs, BDC_SRRBAH(0), upp32); + + temp = bdc_readl(bdc->regs, BDC_SRRINT(0)); + temp |= BDC_SRR_IE; + temp &= ~(BDC_SRR_RST | BDC_SRR_RWS); + bdc_writel(bdc->regs, BDC_SRRINT(0), temp); + + /* Set the Interrupt Coalescence ~500 usec */ + temp = bdc_readl(bdc->regs, BDC_INTCTLS(0)); + temp &= ~0xffff; + temp |= INT_CLS; + bdc_writel(bdc->regs, BDC_INTCTLS(0), temp); + + usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); + dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm); + /* Enable hardware LPM Enable */ + usb2_pm |= BDC_HLE; + bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm); + + /* readback for debug */ + usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); + dev_dbg(bdc->dev, "usb2_pm=%08x\n", usb2_pm); + + /* Disable any unwanted SR's on SRR */ + temp = bdc_readl(bdc->regs, BDC_BDCSC); + /* We don't want Microframe counter wrap SR */ + temp |= BDC_MASK_MCW; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + + /* + * In some error cases, driver has to reset the entire BDC controller + * in that case reinit is passed as 1 + */ + if (reinit) { + /* Enable interrupts */ + temp = bdc_readl(bdc->regs, BDC_BDCSC); + temp |= BDC_GIE; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + /* Init scratchpad to 0 */ + memset(bdc->scratchpad.buff, 0, bdc->sp_buff_size); + /* Initialize SRR to 0 */ + memset(bdc->srr.sr_bds, 0, + NUM_SR_ENTRIES * sizeof(struct bdc_bd)); + } else { + /* One time initiaization only */ + /* Enable status report function pointers */ + bdc->sr_handler[0] = bdc_sr_xsf; + bdc->sr_handler[1] = bdc_sr_uspc; + + /* EP0 status report function pointers */ + bdc->sr_xsf_ep0[0] = bdc_xsf_ep0_setup_recv; + bdc->sr_xsf_ep0[1] = bdc_xsf_ep0_data_start; + bdc->sr_xsf_ep0[2] = bdc_xsf_ep0_status_start; + } +} + +/* Free the dynamic memory */ +static void bdc_mem_free(struct bdc *bdc) +{ + dev_dbg(bdc->dev, "%s\n", __func__); + /* Free SRR */ + if (bdc->srr.sr_bds) + dma_free_coherent(bdc->dev, + NUM_SR_ENTRIES * sizeof(struct bdc_bd), + bdc->srr.sr_bds, bdc->srr.dma_addr); + + /* Free scratchpad */ + if (bdc->scratchpad.buff) + dma_free_coherent(bdc->dev, bdc->sp_buff_size, + bdc->scratchpad.buff, bdc->scratchpad.sp_dma); + + /* Destroy the dma pools */ + if (bdc->bd_table_pool) + dma_pool_destroy(bdc->bd_table_pool); + + /* Free the bdc_ep array */ + kfree(bdc->bdc_ep_array); + + bdc->srr.sr_bds = NULL; + bdc->scratchpad.buff = NULL; + bdc->bd_table_pool = NULL; + bdc->bdc_ep_array = NULL; +} + +/* + * bdc reinit gives a controller reset and reinitialize the registers, + * called from disconnect/bus reset scenario's, to ensure proper HW cleanup + */ +int bdc_reinit(struct bdc *bdc) +{ + int ret; + + dev_dbg(bdc->dev, "%s\n", __func__); + ret = bdc_stop(bdc); + if (ret) + goto out; + + ret = bdc_reset(bdc); + if (ret) + goto out; + + /* the reinit flag is 1 */ + bdc_mem_init(bdc, true); + ret = bdc_run(bdc); +out: + bdc->reinit = false; + + return ret; +} + +/* Allocate all the dyanmic memory */ +static int bdc_mem_alloc(struct bdc *bdc) +{ + u32 page_size; + unsigned int num_ieps, num_oeps; + + dev_dbg(bdc->dev, + "%s() NUM_BDS_PER_TABLE:%d\n", __func__, + NUM_BDS_PER_TABLE); + page_size = BDC_PGS(bdc_readl(bdc->regs, BDC_BDCCFG0)); + /* page size is 2^pgs KB */ + page_size = 1 << page_size; + /* KB */ + page_size <<= 10; + dev_dbg(bdc->dev, "page_size=%d\n", page_size); + + /* Create a pool of bd tables */ + bdc->bd_table_pool = + dma_pool_create("BDC BD tables", bdc->dev, NUM_BDS_PER_TABLE * 16, + 16, page_size); + + if (!bdc->bd_table_pool) + goto fail; + + if (scratchpad_setup(bdc)) + goto fail; + + /* read from regs */ + num_ieps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNIC)); + num_oeps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNOC)); + /* +2: 1 for ep0 and the other is rsvd i.e. bdc_ep[0] is rsvd */ + bdc->num_eps = num_ieps + num_oeps + 2; + dev_dbg(bdc->dev, + "ieps:%d eops:%d num_eps:%d\n", + num_ieps, num_oeps, bdc->num_eps); + /* allocate array of ep pointers */ + bdc->bdc_ep_array = kcalloc(bdc->num_eps, sizeof(struct bdc_ep *), + GFP_KERNEL); + if (!bdc->bdc_ep_array) + goto fail; + + dev_dbg(bdc->dev, "Allocating sr report0\n"); + if (setup_srr(bdc, 0)) + goto fail; + + return 0; +fail: + dev_warn(bdc->dev, "Couldn't initialize memory\n"); + bdc_mem_free(bdc); + + return -ENOMEM; +} + +/* opposite to bdc_hw_init */ +static void bdc_hw_exit(struct bdc *bdc) +{ + dev_dbg(bdc->dev, "%s ()\n", __func__); + bdc_mem_free(bdc); +} + +/* Initialize the bdc HW and memory */ +static int bdc_hw_init(struct bdc *bdc) +{ + int ret; + + dev_dbg(bdc->dev, "%s ()\n", __func__); + ret = bdc_reset(bdc); + if (ret) { + dev_err(bdc->dev, "err resetting bdc abort bdc init%d\n", ret); + return ret; + } + ret = bdc_mem_alloc(bdc); + if (ret) { + dev_err(bdc->dev, "Mem alloc failed, aborting\n"); + return -ENOMEM; + } + bdc_mem_init(bdc, 0); + bdc_dbg_regs(bdc); + dev_dbg(bdc->dev, "HW Init done\n"); + + return 0; +} + +static int bdc_probe(struct platform_device *pdev) +{ + struct bdc *bdc; + struct resource *res; + int ret = -ENOMEM; + int irq; + u32 temp; + struct device *dev = &pdev->dev; + + dev_dbg(dev, "%s()\n", __func__); + bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); + if (!bdc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + bdc->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(bdc->regs)) { + dev_err(dev, "ioremap error\n"); + return -ENOMEM; + } + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "platform_get_irq failed:%d\n", irq); + return irq; + } + spin_lock_init(&bdc->lock); + platform_set_drvdata(pdev, bdc); + bdc->irq = irq; + bdc->dev = dev; + dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + + temp = bdc_readl(bdc->regs, BDC_BDCSC); + if ((temp & BDC_P64) && + !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { + dev_dbg(bdc->dev, "Using 64-bit address\n"); + } else { + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(bdc->dev, "No suitable DMA config available, abort\n"); + return -ENOTSUPP; + } + dev_dbg(bdc->dev, "Using 32-bit address\n"); + } + ret = bdc_hw_init(bdc); + if (ret) { + dev_err(bdc->dev, "BDC init failure:%d\n", ret); + return ret; + } + ret = bdc_udc_init(bdc); + if (ret) { + dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret); + goto cleanup; + } + return 0; + +cleanup: + bdc_hw_exit(bdc); + + return ret; +} + +static int bdc_remove(struct platform_device *pdev) +{ + struct bdc *bdc; + + bdc = platform_get_drvdata(pdev); + dev_dbg(bdc->dev, "%s ()\n", __func__); + bdc_udc_exit(bdc); + bdc_hw_exit(bdc); + + return 0; +} + +static struct platform_driver bdc_driver = { + .driver = { + .name = BRCM_BDC_NAME, + .owner = THIS_MODULE + }, + .probe = bdc_probe, + .remove = bdc_remove, +}; + +module_platform_driver(bdc_driver); +MODULE_AUTHOR("Ashwini Pahuja "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(BRCM_BDC_DESC); diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c new file mode 100644 index 000000000000..5945dbc47825 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c @@ -0,0 +1,123 @@ +/* + * bdc_dbg.c - BRCM BDC USB3.0 device controller debug functions + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include "bdc.h" +#include "bdc_dbg.h" + +void bdc_dbg_regs(struct bdc *bdc) +{ + u32 temp; + + dev_vdbg(bdc->dev, "bdc->regs:%p\n", bdc->regs); + temp = bdc_readl(bdc->regs, BDC_BDCCFG0); + dev_vdbg(bdc->dev, "bdccfg0:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_BDCCFG1); + dev_vdbg(bdc->dev, "bdccfg1:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_BDCCAP0); + dev_vdbg(bdc->dev, "bdccap0:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_BDCCAP1); + dev_vdbg(bdc->dev, "bdccap1:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_USPC); + dev_vdbg(bdc->dev, "uspc:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_DVCSA); + dev_vdbg(bdc->dev, "dvcsa:0x%08x\n", temp); + temp = bdc_readl(bdc->regs, BDC_DVCSB); + dev_vdbg(bdc->dev, "dvcsb:0x%x08\n", temp); +} + +void bdc_dump_epsts(struct bdc *bdc) +{ + u32 temp; + + temp = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS2(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS3(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS4(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS5(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS6(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp); + + temp = bdc_readl(bdc->regs, BDC_EPSTS7(0)); + dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp); +} + +void bdc_dbg_srr(struct bdc *bdc, u32 srr_num) +{ + struct bdc_sr *sr; + dma_addr_t addr; + int i; + + sr = bdc->srr.sr_bds; + addr = bdc->srr.dma_addr; + dev_vdbg(bdc->dev, "bdc_dbg_srr sr:%p dqp_index:%d\n", + sr, bdc->srr.dqp_index); + for (i = 0; i < NUM_SR_ENTRIES; i++) { + sr = &bdc->srr.sr_bds[i]; + dev_vdbg(bdc->dev, "%llx %08x %08x %08x %08x\n", + (unsigned long long)addr, + le32_to_cpu(sr->offset[0]), + le32_to_cpu(sr->offset[1]), + le32_to_cpu(sr->offset[2]), + le32_to_cpu(sr->offset[3])); + addr += sizeof(*sr); + } +} + +void bdc_dbg_bd_list(struct bdc *bdc, struct bdc_ep *ep) +{ + struct bd_list *bd_list = &ep->bd_list; + struct bd_table *bd_table; + struct bdc_bd *bd; + int tbi, bdi, gbdi; + dma_addr_t dma; + + gbdi = 0; + dev_vdbg(bdc->dev, + "Dump bd list for %s epnum:%d\n", + ep->name, ep->ep_num); + + dev_vdbg(bdc->dev, + "tabs:%d max_bdi:%d eqp_bdi:%d hwd_bdi:%d num_bds_table:%d\n", + bd_list->num_tabs, bd_list->max_bdi, bd_list->eqp_bdi, + bd_list->hwd_bdi, bd_list->num_bds_table); + + for (tbi = 0; tbi < bd_list->num_tabs; tbi++) { + bd_table = bd_list->bd_table_array[tbi]; + for (bdi = 0; bdi < bd_list->num_bds_table; bdi++) { + bd = bd_table->start_bd + bdi; + dma = bd_table->dma + (sizeof(struct bdc_bd) * bdi); + dev_vdbg(bdc->dev, + "tbi:%2d bdi:%2d gbdi:%2d virt:%p phys:%llx %08x %08x %08x %08x\n", + tbi, bdi, gbdi++, bd, (unsigned long long)dma, + le32_to_cpu(bd->offset[0]), + le32_to_cpu(bd->offset[1]), + le32_to_cpu(bd->offset[2]), + le32_to_cpu(bd->offset[3])); + } + dev_vdbg(bdc->dev, "\n\n"); + } +} diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.h b/drivers/usb/gadget/udc/bdc/bdc_dbg.h new file mode 100644 index 000000000000..338a6c701315 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.h @@ -0,0 +1,37 @@ +/* + * bdc_dbg.h - header for the BDC debug functions + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifndef __LINUX_BDC_DBG_H__ +#define __LINUX_BDC_DBG_H__ + +#include "bdc.h" + +#ifdef CONFIG_USB_GADGET_VERBOSE +void bdc_dbg_bd_list(struct bdc *, struct bdc_ep*); +void bdc_dbg_srr(struct bdc *, u32); +void bdc_dbg_regs(struct bdc *); +void bdc_dump_epsts(struct bdc *); +#else +static inline void bdc_dbg_regs(struct bdc *bdc) +{ } + +static inline void bdc_dbg_srr(struct bdc *bdc, u32 srr_num) +{ } + +static inline void bdc_dbg_bd_list(struct bdc *bdc, struct bdc_ep *ep) +{ } + +static inline void bdc_dump_epsts(struct bdc *bdc) +{ } +#endif /* CONFIG_USB_GADGET_VERBOSE */ +#endif /* __LINUX_BDC_DBG_H__ */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c new file mode 100644 index 000000000000..15da5b1e76c0 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -0,0 +1,2023 @@ +/* + * bdc_ep.c - BRCM BDC USB3.0 device controller endpoint related functions + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * Based on drivers under drivers/usb/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bdc.h" +#include "bdc_ep.h" +#include "bdc_cmd.h" +#include "bdc_dbg.h" + +static const char * const ep0_state_string[] = { + "WAIT_FOR_SETUP", + "WAIT_FOR_DATA_START", + "WAIT_FOR_DATA_XMIT", + "WAIT_FOR_STATUS_START", + "WAIT_FOR_STATUS_XMIT", + "STATUS_PENDING" +}; + +/* Free the bdl during ep disable */ +static void ep_bd_list_free(struct bdc_ep *ep, u32 num_tabs) +{ + struct bd_list *bd_list = &ep->bd_list; + struct bdc *bdc = ep->bdc; + struct bd_table *bd_table; + int index; + + dev_dbg(bdc->dev, "%s ep:%s num_tabs:%d\n", + __func__, ep->name, num_tabs); + + if (!bd_list->bd_table_array) { + dev_dbg(bdc->dev, "%s already freed\n", ep->name); + return; + } + for (index = 0; index < num_tabs; index++) { + /* + * check if the bd_table struct is allocated ? + * if yes, then check if bd memory has been allocated, then + * free the dma_pool and also the bd_table struct memory + */ + bd_table = bd_list->bd_table_array[index]; + dev_dbg(bdc->dev, "bd_table:%p index:%d\n", bd_table, index); + if (!bd_table) { + dev_dbg(bdc->dev, "bd_table not allocated\n"); + continue; + } + if (!bd_table->start_bd) { + dev_dbg(bdc->dev, "bd dma pool not allocted\n"); + continue; + } + + dev_dbg(bdc->dev, + "Free dma pool start_bd:%p dma:%llx\n", + bd_table->start_bd, + (unsigned long long)bd_table->dma); + + dma_pool_free(bdc->bd_table_pool, + bd_table->start_bd, + bd_table->dma); + /* Free the bd_table structure */ + kfree(bd_table); + } + /* Free the bd table array */ + kfree(ep->bd_list.bd_table_array); +} + +/* + * chain the tables, by insteting a chain bd at the end of prev_table, pointing + * to next_table + */ +static inline void chain_table(struct bd_table *prev_table, + struct bd_table *next_table, + u32 bd_p_tab) +{ + /* Chain the prev table to next table */ + prev_table->start_bd[bd_p_tab-1].offset[0] = + cpu_to_le32(lower_32_bits(next_table->dma)); + + prev_table->start_bd[bd_p_tab-1].offset[1] = + cpu_to_le32(upper_32_bits(next_table->dma)); + + prev_table->start_bd[bd_p_tab-1].offset[2] = + 0x0; + + prev_table->start_bd[bd_p_tab-1].offset[3] = + cpu_to_le32(MARK_CHAIN_BD); +} + +/* Allocate the bdl for ep, during config ep */ +static int ep_bd_list_alloc(struct bdc_ep *ep) +{ + struct bd_table *prev_table = NULL; + int index, num_tabs, bd_p_tab; + struct bdc *bdc = ep->bdc; + struct bd_table *bd_table; + dma_addr_t dma; + + if (usb_endpoint_xfer_isoc(ep->desc)) + num_tabs = NUM_TABLES_ISOCH; + else + num_tabs = NUM_TABLES; + + bd_p_tab = NUM_BDS_PER_TABLE; + /* if there is only 1 table in bd list then loop chain to self */ + dev_dbg(bdc->dev, + "%s ep:%p num_tabs:%d\n", + __func__, ep, num_tabs); + + /* Allocate memory for table array */ + ep->bd_list.bd_table_array = kzalloc( + num_tabs * sizeof(struct bd_table *), + GFP_ATOMIC); + if (!ep->bd_list.bd_table_array) + return -ENOMEM; + + /* Allocate memory for each table */ + for (index = 0; index < num_tabs; index++) { + /* Allocate memory for bd_table structure */ + bd_table = kzalloc(sizeof(struct bd_table), GFP_ATOMIC); + if (!bd_table) + goto fail; + + bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool, + GFP_ATOMIC, + &dma); + if (!bd_table->start_bd) + goto fail; + + bd_table->dma = dma; + + dev_dbg(bdc->dev, + "index:%d start_bd:%p dma=%08llx prev_table:%p\n", + index, bd_table->start_bd, + (unsigned long long)bd_table->dma, prev_table); + + ep->bd_list.bd_table_array[index] = bd_table; + memset(bd_table->start_bd, 0, bd_p_tab * sizeof(struct bdc_bd)); + if (prev_table) + chain_table(prev_table, bd_table, bd_p_tab); + + prev_table = bd_table; + } + chain_table(prev_table, ep->bd_list.bd_table_array[0], bd_p_tab); + /* Memory allocation is successful, now init the internal fields */ + ep->bd_list.num_tabs = num_tabs; + ep->bd_list.max_bdi = (num_tabs * bd_p_tab) - 1; + ep->bd_list.num_tabs = num_tabs; + ep->bd_list.num_bds_table = bd_p_tab; + ep->bd_list.eqp_bdi = 0; + ep->bd_list.hwd_bdi = 0; + + return 0; +fail: + /* Free the bd_table_array, bd_table struct, bd's */ + ep_bd_list_free(ep, num_tabs); + + return -ENOMEM; +} + +/* returns how many bd's are need for this transfer */ +static inline int bd_needed_req(struct bdc_req *req) +{ + int bd_needed = 0; + int remaining; + + /* 1 bd needed for 0 byte transfer */ + if (req->usb_req.length == 0) + return 1; + + /* remaining bytes after tranfering all max BD size BD's */ + remaining = req->usb_req.length % BD_MAX_BUFF_SIZE; + if (remaining) + bd_needed++; + + /* How many maximum BUFF size BD's ? */ + remaining = req->usb_req.length / BD_MAX_BUFF_SIZE; + bd_needed += remaining; + + return bd_needed; +} + +/* returns the bd index(bdi) corresponding to bd dma address */ +static int bd_add_to_bdi(struct bdc_ep *ep, dma_addr_t bd_dma_addr) +{ + struct bd_list *bd_list = &ep->bd_list; + dma_addr_t dma_first_bd, dma_last_bd; + struct bdc *bdc = ep->bdc; + struct bd_table *bd_table; + bool found = false; + int tbi, bdi; + + dma_first_bd = dma_last_bd = 0; + dev_dbg(bdc->dev, "%s %llx\n", + __func__, (unsigned long long)bd_dma_addr); + /* + * Find in which table this bd_dma_addr belongs?, go through the table + * array and compare addresses of first and last address of bd of each + * table + */ + for (tbi = 0; tbi < bd_list->num_tabs; tbi++) { + bd_table = bd_list->bd_table_array[tbi]; + dma_first_bd = bd_table->dma; + dma_last_bd = bd_table->dma + + (sizeof(struct bdc_bd) * + (bd_list->num_bds_table - 1)); + dev_dbg(bdc->dev, "dma_first_bd:%llx dma_last_bd:%llx\n", + (unsigned long long)dma_first_bd, + (unsigned long long)dma_last_bd); + if (bd_dma_addr >= dma_first_bd && bd_dma_addr <= dma_last_bd) { + found = true; + break; + } + } + if (unlikely(!found)) { + dev_err(bdc->dev, "%s FATAL err, bd not found\n", __func__); + return -EINVAL; + } + /* Now we know the table, find the bdi */ + bdi = (bd_dma_addr - dma_first_bd) / sizeof(struct bdc_bd); + + /* return the global bdi, to compare with ep eqp_bdi */ + return (bdi + (tbi * bd_list->num_bds_table)); +} + +/* returns the table index(tbi) of the given bdi */ +static int bdi_to_tbi(struct bdc_ep *ep, int bdi) +{ + int tbi; + + tbi = bdi / ep->bd_list.num_bds_table; + dev_vdbg(ep->bdc->dev, + "bdi:%d num_bds_table:%d tbi:%d\n", + bdi, ep->bd_list.num_bds_table, tbi); + + return tbi; +} + +/* Find the bdi last bd in the transfer */ +static inline int find_end_bdi(struct bdc_ep *ep, int next_hwd_bdi) +{ + int end_bdi; + + end_bdi = next_hwd_bdi - 1; + if (end_bdi < 0) + end_bdi = ep->bd_list.max_bdi - 1; + else if ((end_bdi % (ep->bd_list.num_bds_table-1)) == 0) + end_bdi--; + + return end_bdi; +} + +/* + * How many transfer bd's are available on this ep bdl, chain bds are not + * counted in available bds + */ +static int bd_available_ep(struct bdc_ep *ep) +{ + struct bd_list *bd_list = &ep->bd_list; + int available1, available2; + struct bdc *bdc = ep->bdc; + int chain_bd1, chain_bd2; + int available_bd = 0; + + available1 = available2 = chain_bd1 = chain_bd2 = 0; + /* if empty then we have all bd's available - number of chain bd's */ + if (bd_list->eqp_bdi == bd_list->hwd_bdi) + return bd_list->max_bdi - bd_list->num_tabs; + + /* + * Depending upon where eqp and dqp pointers are, caculate number + * of avaialble bd's + */ + if (bd_list->hwd_bdi < bd_list->eqp_bdi) { + /* available bd's are from eqp..max_bds + 0..dqp - chain_bds */ + available1 = bd_list->max_bdi - bd_list->eqp_bdi; + available2 = bd_list->hwd_bdi; + chain_bd1 = available1 / bd_list->num_bds_table; + chain_bd2 = available2 / bd_list->num_bds_table; + dev_vdbg(bdc->dev, "chain_bd1:%d chain_bd2:%d\n", + chain_bd1, chain_bd2); + available_bd = available1 + available2 - chain_bd1 - chain_bd2; + } else { + /* available bd's are from eqp..dqp - number of chain bd's */ + available1 = bd_list->hwd_bdi - bd_list->eqp_bdi; + /* if gap between eqp and dqp is less than NUM_BDS_PER_TABLE */ + if ((bd_list->hwd_bdi - bd_list->eqp_bdi) + <= bd_list->num_bds_table) { + /* If there any chain bd in between */ + if (!(bdi_to_tbi(ep, bd_list->hwd_bdi) + == bdi_to_tbi(ep, bd_list->eqp_bdi))) { + available_bd = available1 - 1; + } + } else { + chain_bd1 = available1 / bd_list->num_bds_table; + available_bd = available1 - chain_bd1; + } + } + /* + * we need to keep one extra bd to check if ring is full or empty so + * reduce by 1 + */ + available_bd--; + dev_vdbg(bdc->dev, "available_bd:%d\n", available_bd); + + return available_bd; +} + +/* Notify the hardware after queueing the bd to bdl */ +void bdc_notify_xfr(struct bdc *bdc, u32 epnum) +{ + struct bdc_ep *ep = bdc->bdc_ep_array[epnum]; + + dev_vdbg(bdc->dev, "%s epnum:%d\n", __func__, epnum); + /* + * We don't have anyway to check if ep state is running, + * except the software flags. + */ + if (unlikely(ep->flags & BDC_EP_STOP)) + ep->flags &= ~BDC_EP_STOP; + + bdc_writel(bdc->regs, BDC_XSFNTF, epnum); +} + +/* returns the bd corresponding to bdi */ +static struct bdc_bd *bdi_to_bd(struct bdc_ep *ep, int bdi) +{ + int tbi = bdi_to_tbi(ep, bdi); + int local_bdi = 0; + + local_bdi = bdi - (tbi * ep->bd_list.num_bds_table); + dev_vdbg(ep->bdc->dev, + "%s bdi:%d local_bdi:%d\n", + __func__, bdi, local_bdi); + + return (ep->bd_list.bd_table_array[tbi]->start_bd + local_bdi); +} + +/* Advance the enqueue pointer */ +static void ep_bdlist_eqp_adv(struct bdc_ep *ep) +{ + ep->bd_list.eqp_bdi++; + /* if it's chain bd, then move to next */ + if (((ep->bd_list.eqp_bdi + 1) % ep->bd_list.num_bds_table) == 0) + ep->bd_list.eqp_bdi++; + + /* if the eqp is pointing to last + 1 then move back to 0 */ + if (ep->bd_list.eqp_bdi == (ep->bd_list.max_bdi + 1)) + ep->bd_list.eqp_bdi = 0; +} + +/* Setup the first bd for ep0 transfer */ +static int setup_first_bd_ep0(struct bdc *bdc, struct bdc_req *req, u32 *dword3) +{ + u16 wValue; + u32 req_len; + + req->ep->dir = 0; + req_len = req->usb_req.length; + switch (bdc->ep0_state) { + case WAIT_FOR_DATA_START: + *dword3 |= BD_TYPE_DS; + if (bdc->setup_pkt.bRequestType & USB_DIR_IN) + *dword3 |= BD_DIR_IN; + + /* check if zlp will be needed */ + wValue = le16_to_cpu(bdc->setup_pkt.wValue); + if ((wValue > req_len) && + (req_len % bdc->gadget.ep0->maxpacket == 0)) { + dev_dbg(bdc->dev, "ZLP needed wVal:%d len:%d MaxP:%d\n", + wValue, req_len, + bdc->gadget.ep0->maxpacket); + bdc->zlp_needed = true; + } + break; + + case WAIT_FOR_STATUS_START: + *dword3 |= BD_TYPE_SS; + if (!le16_to_cpu(bdc->setup_pkt.wLength) || + !(bdc->setup_pkt.bRequestType & USB_DIR_IN)) + *dword3 |= BD_DIR_IN; + break; + default: + dev_err(bdc->dev, + "Unknown ep0 state for queueing bd ep0_state:%s\n", + ep0_state_string[bdc->ep0_state]); + return -EINVAL; + } + + return 0; +} + +/* Setup the bd dma descriptor for a given request */ +static int setup_bd_list_xfr(struct bdc *bdc, struct bdc_req *req, int num_bds) +{ + dma_addr_t buf_add = req->usb_req.dma; + u32 maxp, tfs, dword2, dword3; + struct bd_transfer *bd_xfr; + struct bd_list *bd_list; + struct bdc_ep *ep; + struct bdc_bd *bd; + int ret, bdnum; + u32 req_len; + + ep = req->ep; + bd_list = &ep->bd_list; + bd_xfr = &req->bd_xfr; + bd_xfr->req = req; + bd_xfr->start_bdi = bd_list->eqp_bdi; + bd = bdi_to_bd(ep, bd_list->eqp_bdi); + req_len = req->usb_req.length; + maxp = usb_endpoint_maxp(ep->desc) & 0x7ff; + tfs = roundup(req->usb_req.length, maxp); + tfs = tfs/maxp; + dev_vdbg(bdc->dev, "%s ep:%s num_bds:%d tfs:%d r_len:%d bd:%p\n", + __func__, ep->name, num_bds, tfs, req_len, bd); + + for (bdnum = 0; bdnum < num_bds; bdnum++) { + dword2 = dword3 = 0; + /* First bd */ + if (!bdnum) { + dword3 |= BD_SOT|BD_SBF|(tfs<ep_num == 1) + ret = setup_first_bd_ep0(bdc, req, &dword3); + if (ret) + return ret; + } + if (!req->ep->dir) + dword3 |= BD_ISP; + + if (req_len > BD_MAX_BUFF_SIZE) { + dword2 |= BD_MAX_BUFF_SIZE; + req_len -= BD_MAX_BUFF_SIZE; + } else { + /* this should be the last bd */ + dword2 |= req_len; + dword3 |= BD_IOC; + dword3 |= BD_EOT; + } + /* Currently only 1 INT target is supported */ + dword2 |= BD_INTR_TARGET(0); + bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi); + if (unlikely(!bd)) { + dev_err(bdc->dev, "Err bd pointing to wrong addr\n"); + return -EINVAL; + } + /* write bd */ + bd->offset[0] = cpu_to_le32(lower_32_bits(buf_add)); + bd->offset[1] = cpu_to_le32(upper_32_bits(buf_add)); + bd->offset[2] = cpu_to_le32(dword2); + bd->offset[3] = cpu_to_le32(dword3); + /* advance eqp pointer */ + ep_bdlist_eqp_adv(ep); + /* advance the buff pointer */ + buf_add += BD_MAX_BUFF_SIZE; + dev_vdbg(bdc->dev, "buf_add:%08llx req_len:%d bd:%p eqp:%d\n", + (unsigned long long)buf_add, req_len, bd, + ep->bd_list.eqp_bdi); + bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi); + bd->offset[3] = cpu_to_le32(BD_SBF); + } + /* clear the STOP BD fetch bit from the first bd of this xfr */ + bd = bdi_to_bd(ep, bd_xfr->start_bdi); + bd->offset[3] &= cpu_to_le32(~BD_SBF); + /* the new eqp will be next hw dqp */ + bd_xfr->num_bds = num_bds; + bd_xfr->next_hwd_bdi = ep->bd_list.eqp_bdi; + /* everything is written correctly before notifying the HW */ + wmb(); + + return 0; +} + +/* Queue the xfr */ +static int bdc_queue_xfr(struct bdc *bdc, struct bdc_req *req) +{ + int num_bds, bd_available; + struct bdc_ep *ep; + int ret; + + ep = req->ep; + dev_dbg(bdc->dev, "%s req:%p\n", __func__, req); + dev_dbg(bdc->dev, "eqp_bdi:%d hwd_bdi:%d\n", + ep->bd_list.eqp_bdi, ep->bd_list.hwd_bdi); + + num_bds = bd_needed_req(req); + bd_available = bd_available_ep(ep); + + /* how many bd's are avaialble on ep */ + if (num_bds > bd_available) + return -ENOMEM; + + ret = setup_bd_list_xfr(bdc, req, num_bds); + if (ret) + return ret; + list_add_tail(&req->queue, &ep->queue); + bdc_dbg_bd_list(bdc, ep); + bdc_notify_xfr(bdc, ep->ep_num); + + return 0; +} + +/* callback to gadget layer when xfr completes */ +static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req, + int status) +{ + struct bdc *bdc = ep->bdc; + + if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) + return; + + dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status); + list_del(&req->queue); + req->usb_req.status = status; + usb_gadget_unmap_request(&bdc->gadget, &req->usb_req, ep->dir); + if (req->usb_req.complete) { + spin_unlock(&bdc->lock); + usb_gadget_giveback_request(&ep->usb_ep, &req->usb_req); + spin_lock(&bdc->lock); + } +} + +/* Disable the endpoint */ +int bdc_ep_disable(struct bdc_ep *ep) +{ + struct bdc_req *req; + struct bdc *bdc; + int ret; + + ret = 0; + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s() ep->ep_num=%d\n", __func__, ep->ep_num); + /* Stop the endpoint */ + ret = bdc_stop_ep(bdc, ep->ep_num); + + /* + * Intentionally don't check the ret value of stop, it can fail in + * disconnect scenarios, continue with dconfig + */ + /* de-queue any pending requests */ + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, struct bdc_req, + queue); + bdc_req_complete(ep, req, -ESHUTDOWN); + } + /* deconfigure the endpoint */ + ret = bdc_dconfig_ep(bdc, ep); + if (ret) + dev_warn(bdc->dev, + "dconfig fail but continue with memory free"); + + ep->flags = 0; + /* ep0 memory is not freed, but reused on next connect sr */ + if (ep->ep_num == 1) + return 0; + + /* Free the bdl memory */ + ep_bd_list_free(ep, ep->bd_list.num_tabs); + ep->desc = NULL; + ep->comp_desc = NULL; + ep->usb_ep.desc = NULL; + ep->ep_type = 0; + + return ret; +} + +/* Enable the ep */ +int bdc_ep_enable(struct bdc_ep *ep) +{ + struct bdc *bdc; + int ret = 0; + + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s NUM_TABLES:%d %d\n", + __func__, NUM_TABLES, NUM_TABLES_ISOCH); + + ret = ep_bd_list_alloc(ep); + if (ret) { + dev_err(bdc->dev, "ep bd list allocation failed:%d\n", ret); + return -ENOMEM; + } + bdc_dbg_bd_list(bdc, ep); + /* only for ep0: config ep is called for ep0 from connect event */ + ep->flags |= BDC_EP_ENABLED; + if (ep->ep_num == 1) + return ret; + + /* Issue a configure endpoint command */ + ret = bdc_config_ep(bdc, ep); + if (ret) + return ret; + + ep->usb_ep.maxpacket = usb_endpoint_maxp(ep->desc); + ep->usb_ep.desc = ep->desc; + ep->usb_ep.comp_desc = ep->comp_desc; + ep->ep_type = usb_endpoint_type(ep->desc); + ep->flags |= BDC_EP_ENABLED; + + return 0; +} + +/* EP0 related code */ + +/* Queue a status stage BD */ +static int ep0_queue_status_stage(struct bdc *bdc) +{ + struct bdc_req *status_req; + struct bdc_ep *ep; + + status_req = &bdc->status_req; + ep = bdc->bdc_ep_array[1]; + status_req->ep = ep; + status_req->usb_req.length = 0; + status_req->usb_req.status = -EINPROGRESS; + status_req->usb_req.actual = 0; + status_req->usb_req.complete = NULL; + bdc_queue_xfr(bdc, status_req); + + return 0; +} + +/* Queue xfr on ep0 */ +static int ep0_queue(struct bdc_ep *ep, struct bdc_req *req) +{ + struct bdc *bdc; + int ret; + + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s()\n", __func__); + req->usb_req.actual = 0; + req->usb_req.status = -EINPROGRESS; + req->epnum = ep->ep_num; + + if (bdc->delayed_status) { + bdc->delayed_status = false; + /* if status stage was delayed? */ + if (bdc->ep0_state == WAIT_FOR_STATUS_START) { + /* Queue a status stage BD */ + ep0_queue_status_stage(bdc); + bdc->ep0_state = WAIT_FOR_STATUS_XMIT; + return 0; + } + } else { + /* + * if delayed status is false and 0 length transfer is requested + * i.e. for status stage of some setup request, then just + * return from here the status stage is queued independently + */ + if (req->usb_req.length == 0) + return 0; + + } + ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir); + if (ret) { + dev_err(bdc->dev, "dma mapping failed %s\n", ep->name); + return ret; + } + + return bdc_queue_xfr(bdc, req); +} + +/* Queue data stage */ +static int ep0_queue_data_stage(struct bdc *bdc) +{ + struct usb_request *ep0_usb_req; + struct bdc_ep *ep; + + dev_dbg(bdc->dev, "%s\n", __func__); + ep0_usb_req = &bdc->ep0_req.usb_req; + ep = bdc->bdc_ep_array[1]; + bdc->ep0_req.ep = ep; + bdc->ep0_req.usb_req.complete = NULL; + + return ep0_queue(ep, &bdc->ep0_req); +} + +/* Queue req on ep */ +static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) +{ + struct bdc *bdc; + int ret = 0; + + bdc = ep->bdc; + if (!req || !ep || !ep->usb_ep.desc) + return -EINVAL; + + req->usb_req.actual = 0; + req->usb_req.status = -EINPROGRESS; + req->epnum = ep->ep_num; + + ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir); + if (ret) { + dev_err(bdc->dev, "dma mapping failed\n"); + return ret; + } + + return bdc_queue_xfr(bdc, req); +} + +/* Dequeue a request from ep */ +static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) +{ + int start_bdi, end_bdi, tbi, eqp_bdi, curr_hw_dqpi; + bool start_pending, end_pending; + bool first_remove = false; + struct bdc_req *first_req; + struct bdc_bd *bd_start; + struct bd_table *table; + dma_addr_t next_bd_dma; + u64 deq_ptr_64 = 0; + struct bdc *bdc; + u32 tmp_32; + int ret; + + bdc = ep->bdc; + start_pending = end_pending = false; + eqp_bdi = ep->bd_list.eqp_bdi - 1; + + if (eqp_bdi < 0) + eqp_bdi = ep->bd_list.max_bdi; + + start_bdi = req->bd_xfr.start_bdi; + end_bdi = find_end_bdi(ep, req->bd_xfr.next_hwd_bdi); + + dev_dbg(bdc->dev, "%s ep:%s start:%d end:%d\n", + __func__, ep->name, start_bdi, end_bdi); + dev_dbg(bdc->dev, "ep_dequeue ep=%p ep->desc=%p\n", + ep, (void *)ep->usb_ep.desc); + /* Stop the ep to see where the HW is ? */ + ret = bdc_stop_ep(bdc, ep->ep_num); + /* if there is an issue with stopping ep, then no need to go further */ + if (ret) + return 0; + + /* + * After endpoint is stopped, there can be 3 cases, the request + * is processed, pending or in the middle of processing + */ + + /* The current hw dequeue pointer */ + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + deq_ptr_64 = tmp_32; + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(1)); + deq_ptr_64 |= ((u64)tmp_32 << 32); + + /* we have the dma addr of next bd that will be fetched by hardware */ + curr_hw_dqpi = bd_add_to_bdi(ep, deq_ptr_64); + if (curr_hw_dqpi < 0) + return curr_hw_dqpi; + + /* + * curr_hw_dqpi points to actual dqp of HW and HW owns bd's from + * curr_hw_dqbdi..eqp_bdi. + */ + + /* Check if start_bdi and end_bdi are in range of HW owned BD's */ + if (curr_hw_dqpi > eqp_bdi) { + /* there is a wrap from last to 0 */ + if (start_bdi >= curr_hw_dqpi || start_bdi <= eqp_bdi) { + start_pending = true; + end_pending = true; + } else if (end_bdi >= curr_hw_dqpi || end_bdi <= eqp_bdi) { + end_pending = true; + } + } else { + if (start_bdi >= curr_hw_dqpi) { + start_pending = true; + end_pending = true; + } else if (end_bdi >= curr_hw_dqpi) { + end_pending = true; + } + } + dev_dbg(bdc->dev, + "start_pending:%d end_pending:%d speed:%d\n", + start_pending, end_pending, bdc->gadget.speed); + + /* If both start till end are processes, we cannot deq req */ + if (!start_pending && !end_pending) + return -EINVAL; + + /* + * if ep_dequeue is called after disconnect then just return + * success from here + */ + if (bdc->gadget.speed == USB_SPEED_UNKNOWN) + return 0; + tbi = bdi_to_tbi(ep, req->bd_xfr.next_hwd_bdi); + table = ep->bd_list.bd_table_array[tbi]; + next_bd_dma = table->dma + + sizeof(struct bdc_bd)*(req->bd_xfr.next_hwd_bdi - + tbi * ep->bd_list.num_bds_table); + + first_req = list_first_entry(&ep->queue, struct bdc_req, + queue); + + if (req == first_req) + first_remove = true; + + /* + * Due to HW limitation we need to bypadd chain bd's and issue ep_bla, + * incase if start is pending this is the first request in the list + * then issue ep_bla instead of marking as chain bd + */ + if (start_pending && !first_remove) { + /* + * Mark the start bd as Chain bd, and point the chain + * bd to next_bd_dma + */ + bd_start = bdi_to_bd(ep, start_bdi); + bd_start->offset[0] = cpu_to_le32(lower_32_bits(next_bd_dma)); + bd_start->offset[1] = cpu_to_le32(upper_32_bits(next_bd_dma)); + bd_start->offset[2] = 0x0; + bd_start->offset[3] = cpu_to_le32(MARK_CHAIN_BD); + bdc_dbg_bd_list(bdc, ep); + } else if (end_pending) { + /* + * The transfer is stopped in the middle, move the + * HW deq pointer to next_bd_dma + */ + ret = bdc_ep_bla(bdc, ep, next_bd_dma); + if (ret) { + dev_err(bdc->dev, "error in ep_bla:%d\n", ret); + return ret; + } + } + + return 0; +} + +/* Halt/Clear the ep based on value */ +static int ep_set_halt(struct bdc_ep *ep, u32 value) +{ + struct bdc *bdc; + int ret; + + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value); + + if (value) { + dev_dbg(bdc->dev, "Halt\n"); + if (ep->ep_num == 1) + bdc->ep0_state = WAIT_FOR_SETUP; + + ret = bdc_ep_set_stall(bdc, ep->ep_num); + if (ret) + dev_err(bdc->dev, "failed to %s STALL on %s\n", + value ? "set" : "clear", ep->name); + else + ep->flags |= BDC_EP_STALL; + } else { + /* Clear */ + dev_dbg(bdc->dev, "Before Clear\n"); + ret = bdc_ep_clear_stall(bdc, ep->ep_num); + if (ret) + dev_err(bdc->dev, "failed to %s STALL on %s\n", + value ? "set" : "clear", ep->name); + else + ep->flags &= ~BDC_EP_STALL; + dev_dbg(bdc->dev, "After Clear\n"); + } + + return ret; +} + +/* Free all the ep */ +void bdc_free_ep(struct bdc *bdc) +{ + struct bdc_ep *ep; + u8 epnum; + + dev_dbg(bdc->dev, "%s\n", __func__); + for (epnum = 1; epnum < bdc->num_eps; epnum++) { + ep = bdc->bdc_ep_array[epnum]; + if (!ep) + continue; + + if (ep->flags & BDC_EP_ENABLED) + ep_bd_list_free(ep, ep->bd_list.num_tabs); + + /* ep0 is not in this gadget list */ + if (epnum != 1) + list_del(&ep->usb_ep.ep_list); + + kfree(ep); + } +} + +/* USB2 spec, section 7.1.20 */ +static int bdc_set_test_mode(struct bdc *bdc) +{ + u32 usb2_pm; + + usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); + usb2_pm &= ~BDC_PTC_MASK; + dev_dbg(bdc->dev, "%s\n", __func__); + switch (bdc->test_mode) { + case TEST_J: + case TEST_K: + case TEST_SE0_NAK: + case TEST_PACKET: + case TEST_FORCE_EN: + usb2_pm |= bdc->test_mode << 28; + break; + default: + return -EINVAL; + } + dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm); + bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm); + + return 0; +} + +/* + * Helper function to handle Transfer status report with status as either + * success or short + */ +static void handle_xsr_succ_status(struct bdc *bdc, struct bdc_ep *ep, + struct bdc_sr *sreport) +{ + int short_bdi, start_bdi, end_bdi, max_len_bds, chain_bds; + struct bd_list *bd_list = &ep->bd_list; + int actual_length, length_short; + struct bd_transfer *bd_xfr; + struct bdc_bd *short_bd; + struct bdc_req *req; + u64 deq_ptr_64 = 0; + int status = 0; + int sr_status; + u32 tmp_32; + + dev_dbg(bdc->dev, "%s ep:%p\n", __func__, ep); + bdc_dbg_srr(bdc, 0); + /* do not process thie sr if ignore flag is set */ + if (ep->ignore_next_sr) { + ep->ignore_next_sr = false; + return; + } + + if (unlikely(list_empty(&ep->queue))) { + dev_warn(bdc->dev, "xfr srr with no BD's queued\n"); + return; + } + req = list_entry(ep->queue.next, struct bdc_req, + queue); + + bd_xfr = &req->bd_xfr; + sr_status = XSF_STS(le32_to_cpu(sreport->offset[3])); + + /* + * sr_status is short and this transfer has more than 1 bd then it needs + * special handling, this is only applicable for bulk and ctrl + */ + if (sr_status == XSF_SHORT && bd_xfr->num_bds > 1) { + /* + * This is multi bd xfr, lets see which bd + * caused short transfer and how many bytes have been + * transferred so far. + */ + tmp_32 = le32_to_cpu(sreport->offset[0]); + deq_ptr_64 = tmp_32; + tmp_32 = le32_to_cpu(sreport->offset[1]); + deq_ptr_64 |= ((u64)tmp_32 << 32); + short_bdi = bd_add_to_bdi(ep, deq_ptr_64); + if (unlikely(short_bdi < 0)) + dev_warn(bdc->dev, "bd doesn't exist?\n"); + + start_bdi = bd_xfr->start_bdi; + /* + * We know the start_bdi and short_bdi, how many xfr + * bds in between + */ + if (start_bdi <= short_bdi) { + max_len_bds = short_bdi - start_bdi; + if (max_len_bds <= bd_list->num_bds_table) { + if (!(bdi_to_tbi(ep, start_bdi) == + bdi_to_tbi(ep, short_bdi))) + max_len_bds--; + } else { + chain_bds = max_len_bds/bd_list->num_bds_table; + max_len_bds -= chain_bds; + } + } else { + /* there is a wrap in the ring within a xfr */ + chain_bds = (bd_list->max_bdi - start_bdi)/ + bd_list->num_bds_table; + chain_bds += short_bdi/bd_list->num_bds_table; + max_len_bds = bd_list->max_bdi - start_bdi; + max_len_bds += short_bdi; + max_len_bds -= chain_bds; + } + /* max_len_bds is the number of full length bds */ + end_bdi = find_end_bdi(ep, bd_xfr->next_hwd_bdi); + if (!(end_bdi == short_bdi)) + ep->ignore_next_sr = true; + + actual_length = max_len_bds * BD_MAX_BUFF_SIZE; + short_bd = bdi_to_bd(ep, short_bdi); + /* length queued */ + length_short = le32_to_cpu(short_bd->offset[2]) & 0x1FFFFF; + /* actual length trensfered */ + length_short -= SR_BD_LEN(le32_to_cpu(sreport->offset[2])); + actual_length += length_short; + req->usb_req.actual = actual_length; + } else { + req->usb_req.actual = req->usb_req.length - + SR_BD_LEN(le32_to_cpu(sreport->offset[2])); + dev_dbg(bdc->dev, + "len=%d actual=%d bd_xfr->next_hwd_bdi:%d\n", + req->usb_req.length, req->usb_req.actual, + bd_xfr->next_hwd_bdi); + } + + /* Update the dequeue pointer */ + ep->bd_list.hwd_bdi = bd_xfr->next_hwd_bdi; + if (req->usb_req.actual < req->usb_req.length) { + dev_dbg(bdc->dev, "short xfr on %d\n", ep->ep_num); + if (req->usb_req.short_not_ok) + status = -EREMOTEIO; + } + bdc_req_complete(ep, bd_xfr->req, status); +} + +/* EP0 setup related packet handlers */ + +/* + * Setup packet received, just store the packet and process on next DS or SS + * started SR + */ +void bdc_xsf_ep0_setup_recv(struct bdc *bdc, struct bdc_sr *sreport) +{ + struct usb_ctrlrequest *setup_pkt; + u32 len; + + dev_dbg(bdc->dev, + "%s ep0_state:%s\n", + __func__, ep0_state_string[bdc->ep0_state]); + /* Store received setup packet */ + setup_pkt = &bdc->setup_pkt; + memcpy(setup_pkt, &sreport->offset[0], sizeof(*setup_pkt)); + len = le16_to_cpu(setup_pkt->wLength); + if (!len) + bdc->ep0_state = WAIT_FOR_STATUS_START; + else + bdc->ep0_state = WAIT_FOR_DATA_START; + + + dev_dbg(bdc->dev, + "%s exit ep0_state:%s\n", + __func__, ep0_state_string[bdc->ep0_state]); +} + +/* Stall ep0 */ +static void ep0_stall(struct bdc *bdc) +{ + struct bdc_ep *ep = bdc->bdc_ep_array[1]; + struct bdc_req *req; + + dev_dbg(bdc->dev, "%s\n", __func__); + bdc->delayed_status = false; + ep_set_halt(ep, 1); + + /* de-queue any pendig requests */ + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, struct bdc_req, + queue); + bdc_req_complete(ep, req, -ESHUTDOWN); + } +} + +/* SET_ADD handlers */ +static int ep0_set_address(struct bdc *bdc, struct usb_ctrlrequest *ctrl) +{ + enum usb_device_state state = bdc->gadget.state; + int ret = 0; + u32 addr; + + addr = le16_to_cpu(ctrl->wValue); + dev_dbg(bdc->dev, + "%s addr:%d dev state:%d\n", + __func__, addr, state); + + if (addr > 127) + return -EINVAL; + + switch (state) { + case USB_STATE_DEFAULT: + case USB_STATE_ADDRESS: + /* Issue Address device command */ + ret = bdc_address_device(bdc, addr); + if (ret) + return ret; + + if (addr) + usb_gadget_set_state(&bdc->gadget, USB_STATE_ADDRESS); + else + usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT); + + bdc->dev_addr = addr; + break; + default: + dev_warn(bdc->dev, + "SET Address in wrong device state %d\n", + state); + ret = -EINVAL; + } + + return ret; +} + +/* Handler for SET/CLEAR FEATURE requests for device */ +static int ep0_handle_feature_dev(struct bdc *bdc, u16 wValue, + u16 wIndex, bool set) +{ + enum usb_device_state state = bdc->gadget.state; + u32 usppms = 0; + + dev_dbg(bdc->dev, "%s set:%d dev state:%d\n", + __func__, set, state); + switch (wValue) { + case USB_DEVICE_REMOTE_WAKEUP: + dev_dbg(bdc->dev, "USB_DEVICE_REMOTE_WAKEUP\n"); + if (set) + bdc->devstatus |= REMOTE_WAKE_ENABLE; + else + bdc->devstatus &= ~REMOTE_WAKE_ENABLE; + break; + + case USB_DEVICE_TEST_MODE: + dev_dbg(bdc->dev, "USB_DEVICE_TEST_MODE\n"); + if ((wIndex & 0xFF) || + (bdc->gadget.speed != USB_SPEED_HIGH) || !set) + return -EINVAL; + + bdc->test_mode = wIndex >> 8; + break; + + case USB_DEVICE_U1_ENABLE: + dev_dbg(bdc->dev, "USB_DEVICE_U1_ENABLE\n"); + + if (bdc->gadget.speed != USB_SPEED_SUPER || + state != USB_STATE_CONFIGURED) + return -EINVAL; + + usppms = bdc_readl(bdc->regs, BDC_USPPMS); + if (set) { + /* clear previous u1t */ + usppms &= ~BDC_U1T(BDC_U1T_MASK); + usppms |= BDC_U1T(U1_TIMEOUT); + usppms |= BDC_U1E | BDC_PORT_W1S; + bdc->devstatus |= (1 << USB_DEV_STAT_U1_ENABLED); + } else { + usppms &= ~BDC_U1E; + usppms |= BDC_PORT_W1S; + bdc->devstatus &= ~(1 << USB_DEV_STAT_U1_ENABLED); + } + bdc_writel(bdc->regs, BDC_USPPMS, usppms); + break; + + case USB_DEVICE_U2_ENABLE: + dev_dbg(bdc->dev, "USB_DEVICE_U2_ENABLE\n"); + + if (bdc->gadget.speed != USB_SPEED_SUPER || + state != USB_STATE_CONFIGURED) + return -EINVAL; + + usppms = bdc_readl(bdc->regs, BDC_USPPMS); + if (set) { + usppms |= BDC_U2E; + usppms |= BDC_U2A; + bdc->devstatus |= (1 << USB_DEV_STAT_U2_ENABLED); + } else { + usppms &= ~BDC_U2E; + usppms &= ~BDC_U2A; + bdc->devstatus &= ~(1 << USB_DEV_STAT_U2_ENABLED); + } + bdc_writel(bdc->regs, BDC_USPPMS, usppms); + break; + + case USB_DEVICE_LTM_ENABLE: + dev_dbg(bdc->dev, "USB_DEVICE_LTM_ENABLE?\n"); + if (bdc->gadget.speed != USB_SPEED_SUPER || + state != USB_STATE_CONFIGURED) + return -EINVAL; + break; + default: + dev_err(bdc->dev, "Unknown wValue:%d\n", wValue); + return -EOPNOTSUPP; + } /* USB_RECIP_DEVICE end */ + + return 0; +} + +/* SET/CLEAR FEATURE handler */ +static int ep0_handle_feature(struct bdc *bdc, + struct usb_ctrlrequest *setup_pkt, bool set) +{ + enum usb_device_state state = bdc->gadget.state; + struct bdc_ep *ep; + u16 wValue; + u16 wIndex; + int epnum; + + wValue = le16_to_cpu(setup_pkt->wValue); + wIndex = le16_to_cpu(setup_pkt->wIndex); + + dev_dbg(bdc->dev, + "%s wValue=%d wIndex=%d devstate=%08x speed=%d set=%d", + __func__, wValue, wIndex, state, + bdc->gadget.speed, set); + + switch (setup_pkt->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + return ep0_handle_feature_dev(bdc, wValue, wIndex, set); + case USB_RECIP_INTERFACE: + dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n"); + /* USB3 spec, sec 9.4.9 */ + if (wValue != USB_INTRF_FUNC_SUSPEND) + return -EINVAL; + /* USB3 spec, Table 9-8 */ + if (set) { + if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) { + dev_dbg(bdc->dev, "SET REMOTE_WAKEUP\n"); + bdc->devstatus |= REMOTE_WAKE_ENABLE; + } else { + dev_dbg(bdc->dev, "CLEAR REMOTE_WAKEUP\n"); + bdc->devstatus &= ~REMOTE_WAKE_ENABLE; + } + } + break; + + case USB_RECIP_ENDPOINT: + dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n"); + if (wValue != USB_ENDPOINT_HALT) + return -EINVAL; + + epnum = wIndex & USB_ENDPOINT_NUMBER_MASK; + if (epnum) { + if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + epnum = epnum * 2 + 1; + else + epnum *= 2; + } else { + epnum = 1; /*EP0*/ + } + /* + * If CLEAR_FEATURE on ep0 then don't do anything as the stall + * condition on ep0 has already been cleared when SETUP packet + * was received. + */ + if (epnum == 1 && !set) { + dev_dbg(bdc->dev, "ep0 stall already cleared\n"); + return 0; + } + dev_dbg(bdc->dev, "epnum=%d\n", epnum); + ep = bdc->bdc_ep_array[epnum]; + if (!ep) + return -EINVAL; + + return ep_set_halt(ep, set); + default: + dev_err(bdc->dev, "Unknown recipient\n"); + return -EINVAL; + } + + return 0; +} + +/* GET_STATUS request handler */ +static int ep0_handle_status(struct bdc *bdc, + struct usb_ctrlrequest *setup_pkt) +{ + enum usb_device_state state = bdc->gadget.state; + struct bdc_ep *ep; + u16 usb_status = 0; + u32 epnum; + u16 wIndex; + + /* USB2.0 spec sec 9.4.5 */ + if (state == USB_STATE_DEFAULT) + return -EINVAL; + wIndex = le16_to_cpu(setup_pkt->wIndex); + dev_dbg(bdc->dev, "%s\n", __func__); + usb_status = bdc->devstatus; + switch (setup_pkt->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + dev_dbg(bdc->dev, + "USB_RECIP_DEVICE devstatus:%08x\n", + bdc->devstatus); + /* USB3 spec, sec 9.4.5 */ + if (bdc->gadget.speed == USB_SPEED_SUPER) + usb_status &= ~REMOTE_WAKE_ENABLE; + break; + + case USB_RECIP_INTERFACE: + dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n"); + if (bdc->gadget.speed == USB_SPEED_SUPER) { + /* + * This should come from func for Func remote wkup + * usb_status |=1; + */ + if (bdc->devstatus & REMOTE_WAKE_ENABLE) + usb_status |= REMOTE_WAKE_ENABLE; + } else { + usb_status = 0; + } + + break; + + case USB_RECIP_ENDPOINT: + dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n"); + epnum = wIndex & USB_ENDPOINT_NUMBER_MASK; + if (epnum) { + if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + epnum = epnum*2 + 1; + else + epnum *= 2; + } else { + epnum = 1; /* EP0 */ + } + + ep = bdc->bdc_ep_array[epnum]; + if (!ep) { + dev_err(bdc->dev, "ISSUE, GET_STATUS for invalid EP ?"); + return -EINVAL; + } + if (ep->flags & BDC_EP_STALL) + usb_status |= 1 << USB_ENDPOINT_HALT; + + break; + default: + dev_err(bdc->dev, "Unknown recipient for get_status\n"); + return -EINVAL; + } + /* prepare a data stage for GET_STATUS */ + dev_dbg(bdc->dev, "usb_status=%08x\n", usb_status); + *(__le16 *)bdc->ep0_response_buff = cpu_to_le16(usb_status); + bdc->ep0_req.usb_req.length = 2; + bdc->ep0_req.usb_req.buf = &bdc->ep0_response_buff; + ep0_queue_data_stage(bdc); + + return 0; +} + +static void ep0_set_sel_cmpl(struct usb_ep *_ep, struct usb_request *_req) +{ + /* ep0_set_sel_cmpl */ +} + +/* Queue data stage to handle 6 byte SET_SEL request */ +static int ep0_set_sel(struct bdc *bdc, + struct usb_ctrlrequest *setup_pkt) +{ + struct bdc_ep *ep; + u16 wLength; + u16 wValue; + + dev_dbg(bdc->dev, "%s\n", __func__); + wValue = le16_to_cpu(setup_pkt->wValue); + wLength = le16_to_cpu(setup_pkt->wLength); + if (unlikely(wLength != 6)) { + dev_err(bdc->dev, "%s Wrong wLength:%d\n", __func__, wLength); + return -EINVAL; + } + ep = bdc->bdc_ep_array[1]; + bdc->ep0_req.ep = ep; + bdc->ep0_req.usb_req.length = 6; + bdc->ep0_req.usb_req.buf = bdc->ep0_response_buff; + bdc->ep0_req.usb_req.complete = ep0_set_sel_cmpl; + ep0_queue_data_stage(bdc); + + return 0; +} + +/* + * Queue a 0 byte bd only if wLength is more than the length and and length is + * a multiple of MaxPacket then queue 0 byte BD + */ +static int ep0_queue_zlp(struct bdc *bdc) +{ + int ret; + + dev_dbg(bdc->dev, "%s\n", __func__); + bdc->ep0_req.ep = bdc->bdc_ep_array[1]; + bdc->ep0_req.usb_req.length = 0; + bdc->ep0_req.usb_req.complete = NULL; + bdc->ep0_state = WAIT_FOR_DATA_START; + ret = bdc_queue_xfr(bdc, &bdc->ep0_req); + if (ret) { + dev_err(bdc->dev, "err queueing zlp :%d\n", ret); + return ret; + } + bdc->ep0_state = WAIT_FOR_DATA_XMIT; + + return 0; +} + +/* Control request handler */ +static int handle_control_request(struct bdc *bdc) +{ + enum usb_device_state state = bdc->gadget.state; + struct usb_ctrlrequest *setup_pkt; + int delegate_setup = 0; + int ret = 0; + int config = 0; + + setup_pkt = &bdc->setup_pkt; + dev_dbg(bdc->dev, "%s\n", __func__); + if ((setup_pkt->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { + switch (setup_pkt->bRequest) { + case USB_REQ_SET_ADDRESS: + dev_dbg(bdc->dev, "USB_REQ_SET_ADDRESS\n"); + ret = ep0_set_address(bdc, setup_pkt); + bdc->devstatus &= DEVSTATUS_CLEAR; + break; + + case USB_REQ_SET_CONFIGURATION: + dev_dbg(bdc->dev, "USB_REQ_SET_CONFIGURATION\n"); + if (state == USB_STATE_ADDRESS) { + usb_gadget_set_state(&bdc->gadget, + USB_STATE_CONFIGURED); + } else if (state == USB_STATE_CONFIGURED) { + /* + * USB2 spec sec 9.4.7, if wValue is 0 then dev + * is moved to addressed state + */ + config = le16_to_cpu(setup_pkt->wValue); + if (!config) + usb_gadget_set_state( + &bdc->gadget, + USB_STATE_ADDRESS); + } + delegate_setup = 1; + break; + + case USB_REQ_SET_FEATURE: + dev_dbg(bdc->dev, "USB_REQ_SET_FEATURE\n"); + ret = ep0_handle_feature(bdc, setup_pkt, 1); + break; + + case USB_REQ_CLEAR_FEATURE: + dev_dbg(bdc->dev, "USB_REQ_CLEAR_FEATURE\n"); + ret = ep0_handle_feature(bdc, setup_pkt, 0); + break; + + case USB_REQ_GET_STATUS: + dev_dbg(bdc->dev, "USB_REQ_GET_STATUS\n"); + ret = ep0_handle_status(bdc, setup_pkt); + break; + + case USB_REQ_SET_SEL: + dev_dbg(bdc->dev, "USB_REQ_SET_SEL\n"); + ret = ep0_set_sel(bdc, setup_pkt); + break; + + case USB_REQ_SET_ISOCH_DELAY: + dev_warn(bdc->dev, + "USB_REQ_SET_ISOCH_DELAY not handled\n"); + ret = 0; + break; + default: + delegate_setup = 1; + } + } else { + delegate_setup = 1; + } + + if (delegate_setup) { + spin_unlock(&bdc->lock); + ret = bdc->gadget_driver->setup(&bdc->gadget, setup_pkt); + spin_lock(&bdc->lock); + } + + return ret; +} + +/* EP0: Data stage started */ +void bdc_xsf_ep0_data_start(struct bdc *bdc, struct bdc_sr *sreport) +{ + struct bdc_ep *ep; + int ret = 0; + + dev_dbg(bdc->dev, "%s\n", __func__); + ep = bdc->bdc_ep_array[1]; + /* If ep0 was stalled, the clear it first */ + if (ep->flags & BDC_EP_STALL) { + ret = ep_set_halt(ep, 0); + if (ret) + goto err; + } + if (bdc->ep0_state != WAIT_FOR_DATA_START) + dev_warn(bdc->dev, + "Data stage not expected ep0_state:%s\n", + ep0_state_string[bdc->ep0_state]); + + ret = handle_control_request(bdc); + if (ret == USB_GADGET_DELAYED_STATUS) { + /* + * The ep0 state will remain WAIT_FOR_DATA_START till + * we received ep_queue on ep0 + */ + bdc->delayed_status = true; + return; + } + if (!ret) { + bdc->ep0_state = WAIT_FOR_DATA_XMIT; + dev_dbg(bdc->dev, + "ep0_state:%s", ep0_state_string[bdc->ep0_state]); + return; + } +err: + ep0_stall(bdc); +} + +/* EP0: status stage started */ +void bdc_xsf_ep0_status_start(struct bdc *bdc, struct bdc_sr *sreport) +{ + struct usb_ctrlrequest *setup_pkt; + struct bdc_ep *ep; + int ret = 0; + + dev_dbg(bdc->dev, + "%s ep0_state:%s", + __func__, ep0_state_string[bdc->ep0_state]); + ep = bdc->bdc_ep_array[1]; + + /* check if ZLP was queued? */ + if (bdc->zlp_needed) + bdc->zlp_needed = false; + + if (ep->flags & BDC_EP_STALL) { + ret = ep_set_halt(ep, 0); + if (ret) + goto err; + } + + if ((bdc->ep0_state != WAIT_FOR_STATUS_START) && + (bdc->ep0_state != WAIT_FOR_DATA_XMIT)) + dev_err(bdc->dev, + "Status stage recv but ep0_state:%s\n", + ep0_state_string[bdc->ep0_state]); + + /* check if data stage is in progress ? */ + if (bdc->ep0_state == WAIT_FOR_DATA_XMIT) { + bdc->ep0_state = STATUS_PENDING; + /* Status stage will be queued upon Data stage transmit event */ + dev_dbg(bdc->dev, + "status started but data not transmitted yet\n"); + return; + } + setup_pkt = &bdc->setup_pkt; + + /* + * 2 stage setup then only process the setup, for 3 stage setup the date + * stage is already handled + */ + if (!le16_to_cpu(setup_pkt->wLength)) { + ret = handle_control_request(bdc); + if (ret == USB_GADGET_DELAYED_STATUS) { + bdc->delayed_status = true; + /* ep0_state will remain WAIT_FOR_STATUS_START */ + return; + } + } + if (!ret) { + /* Queue a status stage BD */ + ep0_queue_status_stage(bdc); + bdc->ep0_state = WAIT_FOR_STATUS_XMIT; + dev_dbg(bdc->dev, + "ep0_state:%s", ep0_state_string[bdc->ep0_state]); + return; + } +err: + ep0_stall(bdc); +} + +/* Helper function to update ep0 upon SR with xsf_succ or xsf_short */ +static void ep0_xsf_complete(struct bdc *bdc, struct bdc_sr *sreport) +{ + dev_dbg(bdc->dev, "%s\n", __func__); + switch (bdc->ep0_state) { + case WAIT_FOR_DATA_XMIT: + bdc->ep0_state = WAIT_FOR_STATUS_START; + break; + case WAIT_FOR_STATUS_XMIT: + bdc->ep0_state = WAIT_FOR_SETUP; + if (bdc->test_mode) { + int ret; + + dev_dbg(bdc->dev, "test_mode:%d\n", bdc->test_mode); + ret = bdc_set_test_mode(bdc); + if (ret < 0) { + dev_err(bdc->dev, "Err in setting Test mode\n"); + return; + } + bdc->test_mode = 0; + } + break; + case STATUS_PENDING: + bdc_xsf_ep0_status_start(bdc, sreport); + break; + + default: + dev_err(bdc->dev, + "Unknown ep0_state:%s\n", + ep0_state_string[bdc->ep0_state]); + + } +} + +/* xfr completion status report handler */ +void bdc_sr_xsf(struct bdc *bdc, struct bdc_sr *sreport) +{ + struct bdc_ep *ep; + u32 sr_status; + u8 ep_num; + + ep_num = (le32_to_cpu(sreport->offset[3])>>4) & 0x1f; + ep = bdc->bdc_ep_array[ep_num]; + if (!ep || !(ep->flags & BDC_EP_ENABLED)) { + dev_err(bdc->dev, "xsf for ep not enabled\n"); + return; + } + /* + * check if this transfer is after link went from U3->U0 due + * to remote wakeup + */ + if (bdc->devstatus & FUNC_WAKE_ISSUED) { + bdc->devstatus &= ~(FUNC_WAKE_ISSUED); + dev_dbg(bdc->dev, "%s clearing FUNC_WAKE_ISSUED flag\n", + __func__); + } + sr_status = XSF_STS(le32_to_cpu(sreport->offset[3])); + dev_dbg_ratelimited(bdc->dev, "%s sr_status=%d ep:%s\n", + __func__, sr_status, ep->name); + + switch (sr_status) { + case XSF_SUCC: + case XSF_SHORT: + handle_xsr_succ_status(bdc, ep, sreport); + if (ep_num == 1) + ep0_xsf_complete(bdc, sreport); + break; + + case XSF_SETUP_RECV: + case XSF_DATA_START: + case XSF_STATUS_START: + if (ep_num != 1) { + dev_err(bdc->dev, + "ep0 related packets on non ep0 endpoint"); + return; + } + bdc->sr_xsf_ep0[sr_status - XSF_SETUP_RECV](bdc, sreport); + break; + + case XSF_BABB: + if (ep_num == 1) { + dev_dbg(bdc->dev, "Babble on ep0 zlp_need:%d\n", + bdc->zlp_needed); + /* + * If the last completed transfer had wLength >Data Len, + * and Len is multiple of MaxPacket,then queue ZLP + */ + if (bdc->zlp_needed) { + /* queue 0 length bd */ + ep0_queue_zlp(bdc); + return; + } + } + dev_warn(bdc->dev, "Babble on ep not handled\n"); + break; + default: + dev_warn(bdc->dev, "sr status not handled:%x\n", sr_status); + break; + } +} + +static int bdc_gadget_ep_queue(struct usb_ep *_ep, + struct usb_request *_req, gfp_t gfp_flags) +{ + struct bdc_req *req; + unsigned long flags; + struct bdc_ep *ep; + struct bdc *bdc; + int ret; + + if (!_ep || !_ep->desc) + return -ESHUTDOWN; + + if (!_req || !_req->complete || !_req->buf) + return -EINVAL; + + ep = to_bdc_ep(_ep); + req = to_bdc_req(_req); + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s ep:%p req:%p\n", __func__, ep, req); + dev_dbg(bdc->dev, "queuing request %p to %s length %d zero:%d\n", + _req, ep->name, _req->length, _req->zero); + + if (!ep->usb_ep.desc) { + dev_warn(bdc->dev, + "trying to queue req %p to disabled %s\n", + _req, ep->name); + return -ESHUTDOWN; + } + + if (_req->length > MAX_XFR_LEN) { + dev_warn(bdc->dev, + "req length > supported MAX:%d requested:%d\n", + MAX_XFR_LEN, _req->length); + return -EOPNOTSUPP; + } + spin_lock_irqsave(&bdc->lock, flags); + if (ep == bdc->bdc_ep_array[1]) + ret = ep0_queue(ep, req); + else + ret = ep_queue(ep, req); + + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static int bdc_gadget_ep_dequeue(struct usb_ep *_ep, + struct usb_request *_req) +{ + struct bdc_req *req; + unsigned long flags; + struct bdc_ep *ep; + struct bdc *bdc; + int ret; + + if (!_ep || !_req) + return -EINVAL; + + ep = to_bdc_ep(_ep); + req = to_bdc_req(_req); + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req); + bdc_dbg_bd_list(bdc, ep); + spin_lock_irqsave(&bdc->lock, flags); + /* make sure it's still queued on this endpoint */ + list_for_each_entry(req, &ep->queue, queue) { + if (&req->usb_req == _req) + break; + } + if (&req->usb_req != _req) { + spin_unlock_irqrestore(&bdc->lock, flags); + dev_err(bdc->dev, "usb_req !=req n"); + return -EINVAL; + } + ret = ep_dequeue(ep, req); + if (ret) { + ret = -EOPNOTSUPP; + goto err; + } + bdc_req_complete(ep, req, -ECONNRESET); + +err: + bdc_dbg_bd_list(bdc, ep); + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static int bdc_gadget_ep_set_halt(struct usb_ep *_ep, int value) +{ + unsigned long flags; + struct bdc_ep *ep; + struct bdc *bdc; + int ret; + + ep = to_bdc_ep(_ep); + bdc = ep->bdc; + dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value); + spin_lock_irqsave(&bdc->lock, flags); + if (usb_endpoint_xfer_isoc(ep->usb_ep.desc)) + ret = -EINVAL; + else if (!list_empty(&ep->queue)) + ret = -EAGAIN; + else + ret = ep_set_halt(ep, value); + + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static struct usb_request *bdc_gadget_alloc_request(struct usb_ep *_ep, + gfp_t gfp_flags) +{ + struct bdc_req *req; + struct bdc_ep *ep; + + req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return NULL; + + ep = to_bdc_ep(_ep); + req->ep = ep; + req->epnum = ep->ep_num; + req->usb_req.dma = DMA_ADDR_INVALID; + dev_dbg(ep->bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req); + + return &req->usb_req; +} + +static void bdc_gadget_free_request(struct usb_ep *_ep, + struct usb_request *_req) +{ + struct bdc_req *req; + + req = to_bdc_req(_req); + kfree(req); +} + +/* endpoint operations */ + +/* configure endpoint and also allocate resources */ +static int bdc_gadget_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + unsigned long flags; + struct bdc_ep *ep; + struct bdc *bdc; + int ret; + + if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { + pr_debug("bdc_gadget_ep_enable invalid parameters\n"); + return -EINVAL; + } + + if (!desc->wMaxPacketSize) { + pr_debug("bdc_gadget_ep_enable missing wMaxPacketSize\n"); + return -EINVAL; + } + + ep = to_bdc_ep(_ep); + bdc = ep->bdc; + + /* Sanity check, upper layer will not send enable for ep0 */ + if (ep == bdc->bdc_ep_array[1]) + return -EINVAL; + + if (!bdc->gadget_driver + || bdc->gadget.speed == USB_SPEED_UNKNOWN) { + return -ESHUTDOWN; + } + + dev_dbg(bdc->dev, "%s Enabling %s\n", __func__, ep->name); + spin_lock_irqsave(&bdc->lock, flags); + ep->desc = desc; + ep->comp_desc = _ep->comp_desc; + ret = bdc_ep_enable(ep); + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static int bdc_gadget_ep_disable(struct usb_ep *_ep) +{ + unsigned long flags; + struct bdc_ep *ep; + struct bdc *bdc; + int ret; + + if (!_ep) { + pr_debug("bdc: invalid parameters\n"); + return -EINVAL; + } + ep = to_bdc_ep(_ep); + bdc = ep->bdc; + + /* Upper layer will not call this for ep0, but do a sanity check */ + if (ep == bdc->bdc_ep_array[1]) { + dev_warn(bdc->dev, "%s called for ep0\n", __func__); + return -EINVAL; + } + dev_dbg(bdc->dev, + "%s() ep:%s ep->flags:%08x\n", + __func__, ep->name, ep->flags); + + if (!(ep->flags & BDC_EP_ENABLED)) { + dev_warn(bdc->dev, "%s is already disabled\n", ep->name); + return 0; + } + spin_lock_irqsave(&bdc->lock, flags); + ret = bdc_ep_disable(ep); + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static const struct usb_ep_ops bdc_gadget_ep_ops = { + .enable = bdc_gadget_ep_enable, + .disable = bdc_gadget_ep_disable, + .alloc_request = bdc_gadget_alloc_request, + .free_request = bdc_gadget_free_request, + .queue = bdc_gadget_ep_queue, + .dequeue = bdc_gadget_ep_dequeue, + .set_halt = bdc_gadget_ep_set_halt +}; + +/* dir = 1 is IN */ +static int init_ep(struct bdc *bdc, u32 epnum, u32 dir) +{ + struct bdc_ep *ep; + + dev_dbg(bdc->dev, "%s epnum=%d dir=%d\n", __func__, epnum, dir); + ep = kzalloc(sizeof(*ep), GFP_KERNEL); + if (!ep) + return -ENOMEM; + + ep->bdc = bdc; + ep->dir = dir; + + /* ep->ep_num is the index inside bdc_ep */ + if (epnum == 1) { + ep->ep_num = 1; + bdc->bdc_ep_array[ep->ep_num] = ep; + snprintf(ep->name, sizeof(ep->name), "ep%d", epnum - 1); + usb_ep_set_maxpacket_limit(&ep->usb_ep, EP0_MAX_PKT_SIZE); + ep->comp_desc = NULL; + bdc->gadget.ep0 = &ep->usb_ep; + } else { + if (dir) + ep->ep_num = epnum * 2 - 1; + else + ep->ep_num = epnum * 2 - 2; + + bdc->bdc_ep_array[ep->ep_num] = ep; + snprintf(ep->name, sizeof(ep->name), "ep%d%s", epnum - 1, + dir & 1 ? "in" : "out"); + + usb_ep_set_maxpacket_limit(&ep->usb_ep, 1024); + ep->usb_ep.max_streams = 0; + list_add_tail(&ep->usb_ep.ep_list, &bdc->gadget.ep_list); + } + ep->usb_ep.ops = &bdc_gadget_ep_ops; + ep->usb_ep.name = ep->name; + ep->flags = 0; + ep->ignore_next_sr = false; + dev_dbg(bdc->dev, "ep=%p ep->usb_ep.name=%s epnum=%d ep->epnum=%d\n", + ep, ep->usb_ep.name, epnum, ep->ep_num); + + INIT_LIST_HEAD(&ep->queue); + + return 0; +} + +/* Init all ep */ +int bdc_init_ep(struct bdc *bdc) +{ + u8 epnum; + int ret; + + dev_dbg(bdc->dev, "%s()\n", __func__); + INIT_LIST_HEAD(&bdc->gadget.ep_list); + /* init ep0 */ + ret = init_ep(bdc, 1, 0); + if (ret) { + dev_err(bdc->dev, "init ep ep0 fail %d\n", ret); + return ret; + } + + for (epnum = 2; epnum <= bdc->num_eps / 2; epnum++) { + /* OUT */ + ret = init_ep(bdc, epnum, 0); + if (ret) { + dev_err(bdc->dev, + "init ep failed for:%d error: %d\n", + epnum, ret); + return ret; + } + + /* IN */ + ret = init_ep(bdc, epnum, 1); + if (ret) { + dev_err(bdc->dev, + "init ep failed for:%d error: %d\n", + epnum, ret); + return ret; + } + } + + return 0; +} diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.h b/drivers/usb/gadget/udc/bdc/bdc_ep.h new file mode 100644 index 000000000000..8a6b36cbf2ea --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.h @@ -0,0 +1,22 @@ +/* + * bdc_ep.h - header for the BDC debug functions + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifndef __LINUX_BDC_EP_H__ +#define __LINUX_BDC_EP_H__ + +int bdc_init_ep(struct bdc *); +int bdc_ep_disable(struct bdc_ep *); +int bdc_ep_enable(struct bdc_ep *); +void bdc_free_ep(struct bdc *); + +#endif /* __LINUX_BDC_EP_H__ */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c new file mode 100644 index 000000000000..02968842b359 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c @@ -0,0 +1,132 @@ +/* + * bdc_pci.c - BRCM BDC USB3.0 device controller PCI interface file. + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * Based on drivers under drivers/usb/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "bdc.h" + +#define BDC_PCI_PID 0x1570 + +struct bdc_pci { + struct device *dev; + struct platform_device *bdc; +}; + +static int bdc_setup_msi(struct pci_dev *pci) +{ + int ret; + + ret = pci_enable_msi(pci); + if (ret) { + pr_err("failed to allocate MSI entry\n"); + return ret; + } + + return ret; +} + +static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) +{ + struct resource res[2]; + struct platform_device *bdc; + struct bdc_pci *glue; + int ret = -ENOMEM; + + glue = devm_kzalloc(&pci->dev, sizeof(*glue), GFP_KERNEL); + if (!glue) + return -ENOMEM; + + glue->dev = &pci->dev; + ret = pci_enable_device(pci); + if (ret) { + dev_err(&pci->dev, "failed to enable pci device\n"); + return -ENODEV; + } + pci_set_master(pci); + + bdc = platform_device_alloc(BRCM_BDC_NAME, PLATFORM_DEVID_AUTO); + if (!bdc) + return -ENOMEM; + + memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); + bdc_setup_msi(pci); + + res[0].start = pci_resource_start(pci, 0); + res[0].end = pci_resource_end(pci, 0); + res[0].name = BRCM_BDC_NAME; + res[0].flags = IORESOURCE_MEM; + + res[1].start = pci->irq; + res[1].name = BRCM_BDC_NAME; + res[1].flags = IORESOURCE_IRQ; + + ret = platform_device_add_resources(bdc, res, ARRAY_SIZE(res)); + if (ret) { + dev_err(&pci->dev, + "couldn't add resources to bdc device\n"); + return ret; + } + + pci_set_drvdata(pci, glue); + + dma_set_coherent_mask(&bdc->dev, pci->dev.coherent_dma_mask); + + bdc->dev.dma_mask = pci->dev.dma_mask; + bdc->dev.dma_parms = pci->dev.dma_parms; + bdc->dev.parent = &pci->dev; + glue->bdc = bdc; + + ret = platform_device_add(bdc); + if (ret) { + dev_err(&pci->dev, "failed to register bdc device\n"); + platform_device_put(bdc); + return ret; + } + + return 0; +} + +static void bdc_pci_remove(struct pci_dev *pci) +{ + struct bdc_pci *glue = pci_get_drvdata(pci); + + platform_device_unregister(glue->bdc); + pci_disable_msi(pci); +} + +static struct pci_device_id bdc_pci_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BDC_PCI_PID), }, + {} /* Terminating Entry */ +}; + +MODULE_DEVICE_TABLE(pci, bdc_pci_id_table); + +static struct pci_driver bdc_pci_driver = { + .name = "bdc-pci", + .id_table = bdc_pci_id_table, + .probe = bdc_pci_probe, + .remove = bdc_pci_remove, +}; + +MODULE_AUTHOR("Ashwini Pahuja "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("BRCM BDC USB3 PCI Glue layer"); +module_pci_driver(bdc_pci_driver); diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c new file mode 100644 index 000000000000..3700ce70b0be --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c @@ -0,0 +1,587 @@ +/* + * bdc_udc.c - BRCM BDC USB3.0 device controller gagdet ops + * + * Copyright (C) 2014 Broadcom Corporation + * + * Author: Ashwini Pahuja + * + * Based on drivers under drivers/usb/gadget/udc/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bdc.h" +#include "bdc_ep.h" +#include "bdc_cmd.h" +#include "bdc_dbg.h" + +static const struct usb_gadget_ops bdc_gadget_ops; + +static const char * const conn_speed_str[] = { + "Not connected", + "Full Speed", + "Low Speed", + "High Speed", + "Super Speed", +}; + +/* EP0 initial descripror */ +static struct usb_endpoint_descriptor bdc_gadget_ep0_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, + .bEndpointAddress = 0, + .wMaxPacketSize = cpu_to_le16(EP0_MAX_PKT_SIZE), +}; + +/* Advance the srr dqp maintained by SW */ +static void srr_dqp_index_advc(struct bdc *bdc, u32 srr_num) +{ + struct srr *srr; + + srr = &bdc->srr; + dev_dbg_ratelimited(bdc->dev, "srr->dqp_index:%d\n", srr->dqp_index); + srr->dqp_index++; + /* rollback to 0 if we are past the last */ + if (srr->dqp_index == NUM_SR_ENTRIES) + srr->dqp_index = 0; +} + +/* connect sr */ +static void bdc_uspc_connected(struct bdc *bdc) +{ + u32 speed, temp; + u32 usppms; + int ret; + + temp = bdc_readl(bdc->regs, BDC_USPC); + speed = BDC_PSP(temp); + dev_dbg(bdc->dev, "%s speed=%x\n", __func__, speed); + switch (speed) { + case BDC_SPEED_SS: + bdc_gadget_ep0_desc.wMaxPacketSize = + cpu_to_le16(EP0_MAX_PKT_SIZE); + bdc->gadget.ep0->maxpacket = EP0_MAX_PKT_SIZE; + bdc->gadget.speed = USB_SPEED_SUPER; + /* Enable U1T in SS mode */ + usppms = bdc_readl(bdc->regs, BDC_USPPMS); + usppms &= ~BDC_U1T(0xff); + usppms |= BDC_U1T(U1_TIMEOUT); + usppms |= BDC_PORT_W1S; + bdc_writel(bdc->regs, BDC_USPPMS, usppms); + break; + + case BDC_SPEED_HS: + bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); + bdc->gadget.ep0->maxpacket = 64; + bdc->gadget.speed = USB_SPEED_HIGH; + break; + + case BDC_SPEED_FS: + bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); + bdc->gadget.ep0->maxpacket = 64; + bdc->gadget.speed = USB_SPEED_FULL; + break; + + case BDC_SPEED_LS: + bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8); + bdc->gadget.ep0->maxpacket = 8; + bdc->gadget.speed = USB_SPEED_LOW; + break; + default: + dev_err(bdc->dev, "UNDEFINED SPEED\n"); + return; + } + dev_dbg(bdc->dev, "connected at %s\n", conn_speed_str[speed]); + /* Now we know the speed, configure ep0 */ + bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc; + ret = bdc_config_ep(bdc, bdc->bdc_ep_array[1]); + if (ret) + dev_err(bdc->dev, "EP0 config failed\n"); + bdc->bdc_ep_array[1]->usb_ep.desc = &bdc_gadget_ep0_desc; + bdc->bdc_ep_array[1]->flags |= BDC_EP_ENABLED; + usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT); +} + +/* device got disconnected */ +static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit) +{ + struct bdc_ep *ep; + + dev_dbg(bdc->dev, "%s\n", __func__); + /* + * Only stop ep0 from here, rest of the endpoints will be disabled + * from gadget_disconnect + */ + ep = bdc->bdc_ep_array[1]; + if (ep && (ep->flags & BDC_EP_ENABLED)) + /* if enabled then stop and remove requests */ + bdc_ep_disable(ep); + + if (bdc->gadget_driver && bdc->gadget_driver->disconnect) { + spin_unlock(&bdc->lock); + bdc->gadget_driver->disconnect(&bdc->gadget); + spin_lock(&bdc->lock); + } + /* Set Unknown speed */ + bdc->gadget.speed = USB_SPEED_UNKNOWN; + bdc->devstatus &= DEVSTATUS_CLEAR; + bdc->delayed_status = false; + bdc->reinit = reinit; + bdc->test_mode = false; +} + +/* TNotify wkaeup timer */ +static void bdc_func_wake_timer(struct work_struct *work) +{ + struct bdc *bdc = container_of(work, struct bdc, func_wake_notify.work); + unsigned long flags; + + dev_dbg(bdc->dev, "%s\n", __func__); + spin_lock_irqsave(&bdc->lock, flags); + /* + * Check if host has started transferring on endpoints + * FUNC_WAKE_ISSUED is cleared when transfer has started after resume + */ + if (bdc->devstatus & FUNC_WAKE_ISSUED) { + dev_dbg(bdc->dev, "FUNC_WAKE_ISSUED FLAG IS STILL SET\n"); + /* flag is still set, so again send func wake */ + bdc_function_wake_fh(bdc, 0); + schedule_delayed_work(&bdc->func_wake_notify, + msecs_to_jiffies(BDC_TNOTIFY)); + } + spin_unlock_irqrestore(&bdc->lock, flags); +} + +/* handler for Link state change condition */ +static void handle_link_state_change(struct bdc *bdc, u32 uspc) +{ + u32 link_state; + + dev_dbg(bdc->dev, "Link state change"); + link_state = BDC_PST(uspc); + switch (link_state) { + case BDC_LINK_STATE_U3: + if ((bdc->gadget.speed != USB_SPEED_UNKNOWN) && + bdc->gadget_driver->suspend) { + dev_dbg(bdc->dev, "Entered Suspend mode\n"); + spin_unlock(&bdc->lock); + bdc->devstatus |= DEVICE_SUSPENDED; + bdc->gadget_driver->suspend(&bdc->gadget); + spin_lock(&bdc->lock); + } + break; + case BDC_LINK_STATE_U0: + if (bdc->devstatus & REMOTE_WAKEUP_ISSUED) { + bdc->devstatus &= ~REMOTE_WAKEUP_ISSUED; + if (bdc->gadget.speed == USB_SPEED_SUPER) { + bdc_function_wake_fh(bdc, 0); + bdc->devstatus |= FUNC_WAKE_ISSUED; + /* + * Start a Notification timer and check if the + * Host transferred anything on any of the EPs, + * if not then send function wake again every + * TNotification secs until host initiates + * transfer to BDC, USB3 spec Table 8.13 + */ + schedule_delayed_work( + &bdc->func_wake_notify, + msecs_to_jiffies(BDC_TNOTIFY)); + dev_dbg(bdc->dev, "sched func_wake_notify\n"); + } + } + break; + + case BDC_LINK_STATE_RESUME: + dev_dbg(bdc->dev, "Resumed from Suspend\n"); + if (bdc->devstatus & DEVICE_SUSPENDED) { + bdc->gadget_driver->resume(&bdc->gadget); + bdc->devstatus &= ~DEVICE_SUSPENDED; + } + break; + default: + dev_dbg(bdc->dev, "link state:%d\n", link_state); + } +} + +/* something changes on upstream port, handle it here */ +void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) +{ + u32 clear_flags = 0; + u32 uspc; + bool connected = false; + bool disconn = false; + + uspc = bdc_readl(bdc->regs, BDC_USPC); + dev_dbg(bdc->dev, "%s uspc=0x%08x\n", __func__, uspc); + + /* Port connect changed */ + if (uspc & BDC_PCC) { + /* Vbus not present, and not connected to Downstream port */ + if ((uspc & BDC_VBC) && !(uspc & BDC_VBS) && !(uspc & BDC_PCS)) + disconn = true; + else if ((uspc & BDC_PCS) && !BDC_PST(uspc)) + connected = true; + } + + /* Change in VBus and VBus is present */ + if ((uspc & BDC_VBC) && (uspc & BDC_VBS)) { + if (bdc->pullup) { + dev_dbg(bdc->dev, "Do a softconnect\n"); + /* Attached state, do a softconnect */ + bdc_softconn(bdc); + usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED); + } + clear_flags = BDC_VBC; + } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) { + /* Hot reset, warm reset, 2.0 bus reset or disconn */ + dev_dbg(bdc->dev, "Port reset or disconn\n"); + bdc_uspc_disconnected(bdc, disconn); + clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC; + } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) { + /* Change in Link state */ + handle_link_state_change(bdc, uspc); + clear_flags = BDC_PSC|BDC_PCS; + } + + /* + * In SS we might not have PRC bit set before connection, but in 2.0 + * the PRC bit is set before connection, so moving this condition out + * of bus reset to handle both SS/2.0 speeds. + */ + if (connected) { + /* This is the connect event for U0/L0 */ + dev_dbg(bdc->dev, "Connected\n"); + bdc_uspc_connected(bdc); + bdc->devstatus &= ~(DEVICE_SUSPENDED); + } + uspc = bdc_readl(bdc->regs, BDC_USPC); + uspc &= (~BDC_USPSC_RW); + dev_dbg(bdc->dev, "uspc=%x\n", uspc); + bdc_writel(bdc->regs, BDC_USPC, clear_flags); +} + +/* Main interrupt handler for bdc */ +static irqreturn_t bdc_udc_interrupt(int irq, void *_bdc) +{ + u32 eqp_index, dqp_index, sr_type, srr_int; + struct bdc_sr *sreport; + struct bdc *bdc = _bdc; + u32 status; + int ret; + + spin_lock(&bdc->lock); + status = bdc_readl(bdc->regs, BDC_BDCSC); + if (!(status & BDC_GIP)) { + spin_unlock(&bdc->lock); + return IRQ_NONE; + } + srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); + /* Check if the SRR IP bit it set? */ + if (!(srr_int & BDC_SRR_IP)) { + dev_warn(bdc->dev, "Global irq pending but SRR IP is 0\n"); + spin_unlock(&bdc->lock); + return IRQ_NONE; + } + eqp_index = BDC_SRR_EPI(srr_int); + dqp_index = BDC_SRR_DPI(srr_int); + dev_dbg(bdc->dev, + "%s eqp_index=%d dqp_index=%d srr.dqp_index=%d\n\n", + __func__, eqp_index, dqp_index, bdc->srr.dqp_index); + + /* check for ring empty condition */ + if (eqp_index == dqp_index) { + dev_dbg(bdc->dev, "SRR empty?\n"); + spin_unlock(&bdc->lock); + return IRQ_HANDLED; + } + + while (bdc->srr.dqp_index != eqp_index) { + sreport = &bdc->srr.sr_bds[bdc->srr.dqp_index]; + /* sreport is read before using it */ + rmb(); + sr_type = le32_to_cpu(sreport->offset[3]) & BD_TYPE_BITMASK; + dev_dbg_ratelimited(bdc->dev, "sr_type=%d\n", sr_type); + switch (sr_type) { + case SR_XSF: + bdc->sr_handler[0](bdc, sreport); + break; + + case SR_USPC: + bdc->sr_handler[1](bdc, sreport); + break; + default: + dev_warn(bdc->dev, "SR:%d not handled\n", sr_type); + } + /* Advance the srr dqp index */ + srr_dqp_index_advc(bdc, 0); + } + /* update the hw dequeue pointer */ + srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); + srr_int &= ~BDC_SRR_DPI_MASK; + srr_int &= ~(BDC_SRR_RWS|BDC_SRR_RST|BDC_SRR_ISR); + srr_int |= ((bdc->srr.dqp_index) << 16); + srr_int |= BDC_SRR_IP; + bdc_writel(bdc->regs, BDC_SRRINT(0), srr_int); + srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); + if (bdc->reinit) { + ret = bdc_reinit(bdc); + if (ret) + dev_err(bdc->dev, "err in bdc reinit\n"); + } + + spin_unlock(&bdc->lock); + + return IRQ_HANDLED; +} + +/* Gadget ops */ +static int bdc_udc_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) +{ + struct bdc *bdc = gadget_to_bdc(gadget); + unsigned long flags; + int ret = 0; + + dev_dbg(bdc->dev, "%s()\n", __func__); + spin_lock_irqsave(&bdc->lock, flags); + if (bdc->gadget_driver) { + dev_err(bdc->dev, "%s is already bound to %s\n", + bdc->gadget.name, + bdc->gadget_driver->driver.name); + ret = -EBUSY; + goto err; + } + /* + * Run the controller from here and when BDC is connected to + * Host then driver will receive a USPC SR with VBUS present + * and then driver will do a softconnect. + */ + ret = bdc_run(bdc); + if (ret) { + dev_err(bdc->dev, "%s bdc run fail\n", __func__); + goto err; + } + bdc->gadget_driver = driver; + bdc->gadget.dev.driver = &driver->driver; +err: + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static int bdc_udc_stop(struct usb_gadget *gadget) +{ + struct bdc *bdc = gadget_to_bdc(gadget); + unsigned long flags; + + dev_dbg(bdc->dev, "%s()\n", __func__); + spin_lock_irqsave(&bdc->lock, flags); + bdc_stop(bdc); + bdc->gadget_driver = NULL; + bdc->gadget.dev.driver = NULL; + spin_unlock_irqrestore(&bdc->lock, flags); + + return 0; +} + +static int bdc_udc_pullup(struct usb_gadget *gadget, int is_on) +{ + struct bdc *bdc = gadget_to_bdc(gadget); + unsigned long flags; + u32 uspc; + + dev_dbg(bdc->dev, "%s() is_on:%d\n", __func__, is_on); + if (!gadget) + return -EINVAL; + + spin_lock_irqsave(&bdc->lock, flags); + if (!is_on) { + bdc_softdisconn(bdc); + bdc->pullup = false; + } else { + /* + * For a self powered device, we need to wait till we receive + * a VBUS change and Vbus present event, then if pullup flag + * is set, then only we present the Termintation. + */ + bdc->pullup = true; + /* + * Check if BDC is already connected to Host i.e Vbus=1, + * if yes, then present TERM now, this is typical for bus + * powered devices. + */ + uspc = bdc_readl(bdc->regs, BDC_USPC); + if (uspc & BDC_VBS) + bdc_softconn(bdc); + } + spin_unlock_irqrestore(&bdc->lock, flags); + + return 0; +} + +static int bdc_udc_set_selfpowered(struct usb_gadget *gadget, + int is_self) +{ + struct bdc *bdc = gadget_to_bdc(gadget); + unsigned long flags; + + dev_dbg(bdc->dev, "%s()\n", __func__); + spin_lock_irqsave(&bdc->lock, flags); + if (!is_self) + bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; + else + bdc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); + + spin_unlock_irqrestore(&bdc->lock, flags); + + return 0; +} + +static int bdc_udc_wakeup(struct usb_gadget *gadget) +{ + struct bdc *bdc = gadget_to_bdc(gadget); + unsigned long flags; + u8 link_state; + u32 uspc; + int ret = 0; + + dev_dbg(bdc->dev, + "%s() bdc->devstatus=%08x\n", + __func__, bdc->devstatus); + + if (!(bdc->devstatus & REMOTE_WAKE_ENABLE)) + return -EOPNOTSUPP; + + spin_lock_irqsave(&bdc->lock, flags); + uspc = bdc_readl(bdc->regs, BDC_USPC); + link_state = BDC_PST(uspc); + dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc); + if (link_state != BDC_LINK_STATE_U3) { + dev_warn(bdc->dev, + "can't wakeup from link state %d\n", + link_state); + ret = -EINVAL; + goto out; + } + if (bdc->gadget.speed == USB_SPEED_SUPER) + bdc->devstatus |= REMOTE_WAKEUP_ISSUED; + + uspc &= ~BDC_PST_MASK; + uspc &= (~BDC_USPSC_RW); + uspc |= BDC_PST(BDC_LINK_STATE_U0); + uspc |= BDC_SWS; + bdc_writel(bdc->regs, BDC_USPC, uspc); + uspc = bdc_readl(bdc->regs, BDC_USPC); + link_state = BDC_PST(uspc); + dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc); +out: + spin_unlock_irqrestore(&bdc->lock, flags); + + return ret; +} + +static const struct usb_gadget_ops bdc_gadget_ops = { + .wakeup = bdc_udc_wakeup, + .set_selfpowered = bdc_udc_set_selfpowered, + .pullup = bdc_udc_pullup, + .udc_start = bdc_udc_start, + .udc_stop = bdc_udc_stop, +}; + +/* Init the gadget interface and register the udc */ +int bdc_udc_init(struct bdc *bdc) +{ + u32 temp; + int ret; + + dev_dbg(bdc->dev, "%s()\n", __func__); + bdc->gadget.ops = &bdc_gadget_ops; + bdc->gadget.max_speed = USB_SPEED_SUPER; + bdc->gadget.speed = USB_SPEED_UNKNOWN; + bdc->gadget.dev.parent = bdc->dev; + + bdc->gadget.sg_supported = false; + + + bdc->gadget.name = BRCM_BDC_NAME; + ret = devm_request_irq(bdc->dev, bdc->irq, bdc_udc_interrupt, + IRQF_SHARED , BRCM_BDC_NAME, bdc); + if (ret) { + dev_err(bdc->dev, + "failed to request irq #%d %d\n", + bdc->irq, ret); + return ret; + } + + ret = bdc_init_ep(bdc); + if (ret) { + dev_err(bdc->dev, "bdc init ep fail: %d\n", ret); + return ret; + } + + ret = usb_add_gadget_udc(bdc->dev, &bdc->gadget); + if (ret) { + dev_err(bdc->dev, "failed to register udc\n"); + goto err0; + } + usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED); + bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc; + /* + * Allocate bd list for ep0 only, ep0 will be enabled on connect + * status report when the speed is known + */ + ret = bdc_ep_enable(bdc->bdc_ep_array[1]); + if (ret) { + dev_err(bdc->dev, "fail to enable %s\n", + bdc->bdc_ep_array[1]->name); + goto err1; + } + INIT_DELAYED_WORK(&bdc->func_wake_notify, bdc_func_wake_timer); + /* Enable Interrupts */ + temp = bdc_readl(bdc->regs, BDC_BDCSC); + temp |= BDC_GIE; + bdc_writel(bdc->regs, BDC_BDCSC, temp); + return 0; +err1: + usb_del_gadget_udc(&bdc->gadget); +err0: + bdc_free_ep(bdc); + + return ret; +} + +void bdc_udc_exit(struct bdc *bdc) +{ + dev_dbg(bdc->dev, "%s()\n", __func__); + bdc_ep_disable(bdc->bdc_ep_array[1]); + usb_del_gadget_udc(&bdc->gadget); + bdc_free_ep(bdc); +} -- GitLab From 828f6148e89ec051c2540400773655c0174ccaa3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Nov 2014 09:19:47 +0300 Subject: [PATCH 5170/9457] usb: gadget: f_hid: use after free in hidg_alloc_inst() We free "opts" on the error path and then dereference it. Fixes: 21a9476a7ba8 ('usb: gadget: hid: add configfs support') Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 7d18f413ffea..f0545f801c9d 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -875,6 +875,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) kfree(opts); if (idr_is_empty(&hidg_ida.idr)) ghid_cleanup(); + goto unlock; } config_group_init_type_name(&opts->func_inst.group, "", &hid_func_type); -- GitLab From 0448d38c1e8cd64fb2fa88f44cbc7c3dcf75ed6c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Nov 2014 09:20:59 +0300 Subject: [PATCH 5171/9457] usb: gadget: f_hid: fix error handling in ghid_setup() There were a two issues here. 1) We returned PTR_ERR(NULL) which means success if class_create() failed. 2) If alloc_chrdev_region() failed then we should clean up before returning. Also kernel style is to have "error handling" as opposed to "success handling". In the original code checking for "if (!status) " is confusing and this bad style is what lead to bug #2. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index f0545f801c9d..488ac66aae9e 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -972,17 +972,22 @@ int ghid_setup(struct usb_gadget *g, int count) hidg_class = class_create(THIS_MODULE, "hidg"); if (IS_ERR(hidg_class)) { + status = PTR_ERR(hidg_class); hidg_class = NULL; - return PTR_ERR(hidg_class); + return status; } status = alloc_chrdev_region(&dev, 0, count, "hidg"); - if (!status) { - major = MAJOR(dev); - minors = count; + if (status) { + class_destroy(hidg_class); + hidg_class = NULL; + return status; } - return status; + major = MAJOR(dev); + minors = count; + + return 0; } void ghid_cleanup(void) -- GitLab From a1fc1920aaaaeadc7cf9d80fc16e6b8eca722b44 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 13 Nov 2014 18:33:08 +0100 Subject: [PATCH 5172/9457] usb: musb: core: make sure musb is in RPM_ACTIVE on resume On am335x-evm with musb in host mode and using it as a wakeup source the following happens once the CPU comes out of suspend to ram: |PM: Wakeup source MPU_WAKE |PM: noirq resume of devices complete after 15.453 msecs |PM: early resume of devices complete after 2.222 msecs |PM: resume of devices complete after 507.351 msecs |Restarting tasks ... |------------[ cut here ]------------ |WARNING: CPU: 0 PID: 322 at drivers/usb/core/urb.c:339 usb_submit_urb+0x494/0x4c8() |URB cc0db380 submitted while active |[] (usb_submit_urb) from [] (hub_activate+0x2b8/0x49c) |[] (hub_activate) from [] (hub_resume+0x14/0x1c) |[] (hub_resume) from [] (usb_resume_interface.isra.4+0xdc/0x110) |[] (usb_resume_interface.isra.4) from [] (usb_resume_both+0x6c/0x13c) |[] (usb_resume_both) from [] (usb_runtime_resume+0x10/0x14) |[] (usb_runtime_resume) from [] (__rpm_callback+0x2c/0x60) |[] (__rpm_callback) from [] (rpm_callback+0x20/0x74) |[] (rpm_callback) from [] (rpm_resume+0x380/0x548) |[] (rpm_resume) from [] (rpm_resume+0x238/0x548) |[] (rpm_resume) from [] (__pm_runtime_resume+0x64/0x94) |[] (__pm_runtime_resume) from [] (usb_autopm_get_interface+0x18/0x5c) |[] (usb_autopm_get_interface) from [] (hub_thread+0x10c/0x115c) |[] (hub_thread) from [] (kthread+0xbc/0xd8) |---[ end trace 036aa5fe78203142 ]--- |hub 1-0:1.0: activate --> -16 |hub 2-0:1.0: activate --> -16 The reason for this backtrace is the attempt of the USB code to resume the HUB twice and thus enqueue the status URB twice. Alan Stern was a great help by explaining how the USB code supposed to work and what is most likely the problem. The root problem is that after resume the musb runtime-suspend state remains RPM_SUSPENDED. According to git log it RPM was added for the omap2430 platform. If I understand it correct the omap2430 invokes a get on musb once a cable is connected and a put once the cable is gone. In between the device could go auto-idle/off. Not sure what happens when the device goes into suspend but then I guess it was gadget only. On DSPS I see only a get in probe and put in remove function. This would forbid RPM from working but then the devices enterns suspended state anyway :) To get rid of this warning, I set the device state to RPM_ACTIVE which the expected state. Cc: Alan Stern Cc: Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3345c945262f..f1dfe53515fb 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2321,6 +2321,14 @@ static int musb_resume(struct device *dev) schedule_delayed_work(&musb->finish_resume_work, msecs_to_jiffies(20)); } + + /* + * The USB HUB code expects the device to be in RPM_ACTIVE once it came + * out of suspend + */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); return 0; } -- GitLab From 2fbed5119d6a07a6777b2131262587df338df22b Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Tue, 18 Nov 2014 18:31:05 +0800 Subject: [PATCH 5173/9457] i2c: imx: Sort include headers alphabetically If the inlcude headers aren't sorted alphabetically, then the logical choice is to append new ones, however that creates a lot of potential for conflicts or duplicates because every change will then add new includes in the same location. Signed-off-by: Yuan Yao Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 3cbc09262326..d137289edfca 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -32,22 +32,22 @@ /** Includes ******************************************************************* *******************************************************************************/ -#include -#include -#include -#include -#include -#include +#include #include +#include +#include #include +#include +#include #include -#include -#include -#include -#include +#include +#include #include #include #include +#include +#include +#include /** Defines ******************************************************************** *******************************************************************************/ -- GitLab From ce1a78840ff7ab846065d5b65eaac959bafe1949 Mon Sep 17 00:00:00 2001 From: Yao Yuan Date: Tue, 18 Nov 2014 18:31:06 +0800 Subject: [PATCH 5174/9457] i2c: imx: add DMA support for freescale i2c driver Add dma support for i2c. This function depend on DMA driver. You can turn on it by write both the dmas and dma-name properties in dts node. DMA is optional, even DMA request unsuccessfully, i2c can also work well. Signed-off-by: Yuan Yao Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-imx.txt | 11 + drivers/i2c/busses/i2c-imx.c | 335 +++++++++++++++++- 2 files changed, 344 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt index 4a8513e44740..52d37fd8d3e5 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt @@ -11,6 +11,8 @@ Required properties: Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. The absence of the propoerty indicates the default frequency 100 kHz. +- dmas: A list of two dma specifiers, one for each entry in dma-names. +- dma-names: should contain "tx" and "rx". Examples: @@ -26,3 +28,12 @@ i2c@70038000 { /* HS-I2C on i.MX51 */ interrupts = <64>; clock-frequency = <400000>; }; + +i2c0: i2c@40066000 { /* i2c0 on vf610 */ + compatible = "fsl,vf610-i2c"; + reg = <0x40066000 0x1000>; + interrupts =<0 71 0x04>; + dmas = <&edma0 0 50>, + <&edma0 0 51>; + dma-names = "rx","tx"; +}; diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index d137289edfca..d0668d0d626d 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -33,7 +33,11 @@ *******************************************************************************/ #include +#include #include +#include +#include +#include #include #include #include @@ -44,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +63,15 @@ /* Default value */ #define IMX_I2C_BIT_RATE 100000 /* 100kHz */ +/* + * Enable DMA if transfer byte size is bigger than this threshold. + * As the hardware request, it must bigger than 4 bytes.\ + * I have set '16' here, maybe it's not the best but I think it's + * the appropriate. + */ +#define DMA_THRESHOLD 16 +#define DMA_TIMEOUT 1000 + /* IMX I2C registers: * the I2C register offset is different between SoCs, * to provid support for all these chips, split the @@ -83,6 +97,7 @@ #define I2SR_IBB 0x20 #define I2SR_IAAS 0x40 #define I2SR_ICF 0x80 +#define I2CR_DMAEN 0x02 #define I2CR_RSTA 0x04 #define I2CR_TXAK 0x08 #define I2CR_MTX 0x10 @@ -169,6 +184,17 @@ struct imx_i2c_hwdata { unsigned i2cr_ien_opcode; }; +struct imx_i2c_dma { + struct dma_chan *chan_tx; + struct dma_chan *chan_rx; + struct dma_chan *chan_using; + struct completion cmd_complete; + dma_addr_t dma_buf; + unsigned int dma_len; + enum dma_transfer_direction dma_transfer_dir; + enum dma_data_direction dma_data_dir; +}; + struct imx_i2c_struct { struct i2c_adapter adapter; struct clk *clk; @@ -181,6 +207,8 @@ struct imx_i2c_struct { unsigned int cur_clk; unsigned int bitrate; const struct imx_i2c_hwdata *hwdata; + + struct imx_i2c_dma *dma; }; static const struct imx_i2c_hwdata imx1_i2c_hwdata = { @@ -251,6 +279,138 @@ static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx, return readb(i2c_imx->base + (reg << i2c_imx->hwdata->regshift)); } +/* Functions for DMA support */ +static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, + dma_addr_t phy_addr) +{ + struct imx_i2c_dma *dma; + struct dma_slave_config dma_sconfig; + struct device *dev = &i2c_imx->adapter.dev; + int ret; + + dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); + if (!dma) + return; + + dma->chan_tx = dma_request_slave_channel(dev, "tx"); + if (!dma->chan_tx) { + dev_dbg(dev, "can't request DMA tx channel\n"); + ret = -ENODEV; + goto fail_al; + } + + dma_sconfig.dst_addr = phy_addr + + (IMX_I2C_I2DR << i2c_imx->hwdata->regshift); + dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma_sconfig.dst_maxburst = 1; + dma_sconfig.direction = DMA_MEM_TO_DEV; + ret = dmaengine_slave_config(dma->chan_tx, &dma_sconfig); + if (ret < 0) { + dev_dbg(dev, "can't configure tx channel\n"); + goto fail_tx; + } + + dma->chan_rx = dma_request_slave_channel(dev, "rx"); + if (!dma->chan_rx) { + dev_dbg(dev, "can't request DMA rx channel\n"); + ret = -ENODEV; + goto fail_tx; + } + + dma_sconfig.src_addr = phy_addr + + (IMX_I2C_I2DR << i2c_imx->hwdata->regshift); + dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma_sconfig.src_maxburst = 1; + dma_sconfig.direction = DMA_DEV_TO_MEM; + ret = dmaengine_slave_config(dma->chan_rx, &dma_sconfig); + if (ret < 0) { + dev_dbg(dev, "can't configure rx channel\n"); + goto fail_rx; + } + + i2c_imx->dma = dma; + init_completion(&dma->cmd_complete); + dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n", + dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx)); + + return; + +fail_rx: + dma_release_channel(dma->chan_rx); +fail_tx: + dma_release_channel(dma->chan_tx); +fail_al: + devm_kfree(dev, dma); + dev_info(dev, "can't use DMA\n"); +} + +static void i2c_imx_dma_callback(void *arg) +{ + struct imx_i2c_struct *i2c_imx = (struct imx_i2c_struct *)arg; + struct imx_i2c_dma *dma = i2c_imx->dma; + + dma_unmap_single(dma->chan_using->device->dev, dma->dma_buf, + dma->dma_len, dma->dma_data_dir); + complete(&dma->cmd_complete); +} + +static int i2c_imx_dma_xfer(struct imx_i2c_struct *i2c_imx, + struct i2c_msg *msgs) +{ + struct imx_i2c_dma *dma = i2c_imx->dma; + struct dma_async_tx_descriptor *txdesc; + struct device *dev = &i2c_imx->adapter.dev; + struct device *chan_dev = dma->chan_using->device->dev; + + dma->dma_buf = dma_map_single(chan_dev, msgs->buf, + dma->dma_len, dma->dma_data_dir); + if (dma_mapping_error(chan_dev, dma->dma_buf)) { + dev_err(dev, "DMA mapping failed\n"); + goto err_map; + } + + txdesc = dmaengine_prep_slave_single(dma->chan_using, dma->dma_buf, + dma->dma_len, dma->dma_transfer_dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!txdesc) { + dev_err(dev, "Not able to get desc for DMA xfer\n"); + goto err_desc; + } + + txdesc->callback = i2c_imx_dma_callback; + txdesc->callback_param = i2c_imx; + if (dma_submit_error(dmaengine_submit(txdesc))) { + dev_err(dev, "DMA submit failed\n"); + goto err_submit; + } + + dma_async_issue_pending(dma->chan_using); + return 0; + +err_submit: +err_desc: + dma_unmap_single(chan_dev, dma->dma_buf, + dma->dma_len, dma->dma_data_dir); +err_map: + return -EINVAL; +} + +static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx) +{ + struct imx_i2c_dma *dma = i2c_imx->dma; + + dma->dma_buf = 0; + dma->dma_len = 0; + + dma_release_channel(dma->chan_tx); + dma->chan_tx = NULL; + + dma_release_channel(dma->chan_rx); + dma->chan_rx = NULL; + + dma->chan_using = NULL; +} + /** Functions for IMX I2C adapter driver *************************************** *******************************************************************************/ @@ -382,6 +542,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) i2c_imx->stopped = 0; temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK; + temp &= ~I2CR_DMAEN; imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); return result; } @@ -395,6 +556,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); temp &= ~(I2CR_MSTA | I2CR_MTX); + if (i2c_imx->dma) + temp &= ~I2CR_DMAEN; imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); } if (is_imx1_i2c(i2c_imx)) { @@ -435,6 +598,159 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id) return IRQ_NONE; } +static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, + struct i2c_msg *msgs) +{ + int result; + unsigned int temp = 0; + unsigned long orig_jiffies = jiffies; + struct imx_i2c_dma *dma = i2c_imx->dma; + struct device *dev = &i2c_imx->adapter.dev; + + dma->chan_using = dma->chan_tx; + dma->dma_transfer_dir = DMA_MEM_TO_DEV; + dma->dma_data_dir = DMA_TO_DEVICE; + dma->dma_len = msgs->len - 1; + result = i2c_imx_dma_xfer(i2c_imx, msgs); + if (result) + return result; + + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp |= I2CR_DMAEN; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + /* + * Write slave address. + * The first byte must be transmitted by the CPU. + */ + imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR); + reinit_completion(&i2c_imx->dma->cmd_complete); + result = wait_for_completion_timeout( + &i2c_imx->dma->cmd_complete, + msecs_to_jiffies(DMA_TIMEOUT)); + if (result <= 0) { + dmaengine_terminate_all(dma->chan_using); + return result ?: -ETIMEDOUT; + } + + /* Waiting for transfer complete. */ + while (1) { + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); + if (temp & I2SR_ICF) + break; + if (time_after(jiffies, orig_jiffies + + msecs_to_jiffies(DMA_TIMEOUT))) { + dev_dbg(dev, "<%s> Timeout\n", __func__); + return -ETIMEDOUT; + } + schedule(); + } + + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp &= ~I2CR_DMAEN; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + /* The last data byte must be transferred by the CPU. */ + imx_i2c_write_reg(msgs->buf[msgs->len-1], + i2c_imx, IMX_I2C_I2DR); + result = i2c_imx_trx_complete(i2c_imx); + if (result) + return result; + + result = i2c_imx_acked(i2c_imx); + if (result) + return result; + + return 0; +} + +static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, + struct i2c_msg *msgs, bool is_lastmsg) +{ + int result; + unsigned int temp; + unsigned long orig_jiffies = jiffies; + struct imx_i2c_dma *dma = i2c_imx->dma; + struct device *dev = &i2c_imx->adapter.dev; + + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp |= I2CR_DMAEN; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + dma->chan_using = dma->chan_rx; + dma->dma_transfer_dir = DMA_DEV_TO_MEM; + dma->dma_data_dir = DMA_FROM_DEVICE; + /* The last two data bytes must be transferred by the CPU. */ + dma->dma_len = msgs->len - 2; + result = i2c_imx_dma_xfer(i2c_imx, msgs); + if (result) + return result; + + reinit_completion(&i2c_imx->dma->cmd_complete); + result = wait_for_completion_timeout( + &i2c_imx->dma->cmd_complete, + msecs_to_jiffies(DMA_TIMEOUT)); + if (result <= 0) { + dmaengine_terminate_all(dma->chan_using); + return result ?: -ETIMEDOUT; + } + + /* waiting for transfer complete. */ + while (1) { + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); + if (temp & I2SR_ICF) + break; + if (time_after(jiffies, orig_jiffies + + msecs_to_jiffies(DMA_TIMEOUT))) { + dev_dbg(dev, "<%s> Timeout\n", __func__); + return -ETIMEDOUT; + } + schedule(); + } + + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp &= ~I2CR_DMAEN; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + /* read n-1 byte data */ + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp |= I2CR_TXAK; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + msgs->buf[msgs->len-2] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); + /* read n byte data */ + result = i2c_imx_trx_complete(i2c_imx); + if (result) + return result; + + if (is_lastmsg) { + /* + * It must generate STOP before read I2DR to prevent + * controller from generating another clock cycle + */ + dev_dbg(dev, "<%s> clear MSTA\n", __func__); + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp &= ~(I2CR_MSTA | I2CR_MTX); + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + i2c_imx_bus_busy(i2c_imx, 0); + i2c_imx->stopped = 1; + } else { + /* + * For i2c master receiver repeat restart operation like: + * read -> repeat MSTA -> read/write + * The controller must set MTX before read the last byte in + * the first read operation, otherwise the first read cost + * one extra clock cycle. + */ + temp = readb(i2c_imx->base + IMX_I2C_I2CR); + temp |= I2CR_MTX; + writeb(temp, i2c_imx->base + IMX_I2C_I2CR); + } + msgs->buf[msgs->len-1] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); + + return 0; +} + static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) { int i, result; @@ -504,6 +820,9 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__); + if (i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data) + return i2c_imx_dma_read(i2c_imx, msgs, is_lastmsg); + /* read data */ for (i = 0; i < msgs->len; i++) { u8 len = 0; @@ -618,8 +937,12 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter, #endif if (msgs[i].flags & I2C_M_RD) result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg); - else - result = i2c_imx_write(i2c_imx, &msgs[i]); + else { + if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD) + result = i2c_imx_dma_write(i2c_imx, &msgs[i]); + else + result = i2c_imx_write(i2c_imx, &msgs[i]); + } if (result) goto fail0; } @@ -654,6 +977,7 @@ static int i2c_imx_probe(struct platform_device *pdev) struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev); void __iomem *base; int irq, ret; + dma_addr_t phy_addr; dev_dbg(&pdev->dev, "<%s>\n", __func__); @@ -668,6 +992,7 @@ static int i2c_imx_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); + phy_addr = (dma_addr_t)res->start; i2c_imx = devm_kzalloc(&pdev->dev, sizeof(*i2c_imx), GFP_KERNEL); if (!i2c_imx) return -ENOMEM; @@ -742,6 +1067,9 @@ static int i2c_imx_probe(struct platform_device *pdev) i2c_imx->adapter.name); dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); + /* Init DMA config if support*/ + i2c_imx_dma_request(i2c_imx, phy_addr); + return 0; /* Return OK */ clk_disable: @@ -757,6 +1085,9 @@ static int i2c_imx_remove(struct platform_device *pdev) dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n"); i2c_del_adapter(&i2c_imx->adapter); + if (i2c_imx->dma) + i2c_imx_dma_free(i2c_imx); + /* setup chip registers to defaults */ imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR); imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR); -- GitLab From bb29a93b38610d2adc6ead40b75e1a1991617550 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 12 Nov 2014 00:52:23 +0900 Subject: [PATCH 5175/9457] ASoC: jack: Fix warning while make htmldocs caused by soc-jack.c This patch fix following errors while "make htmldocs" on linux-next-20141110. Warning(.//sound/soc/soc-jack.c:126): No description found for parameter 'zones' Warning(.//sound/soc/soc-jack.c:126): Excess function parameter 'zone' description in 'snd_soc_jack_add_zones' Signed-off-by: Masanari Iida Signed-off-by: Mark Brown --- sound/soc/soc-jack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index ab47fea997a3..ef1d42d7c6f6 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_report); * * @jack: ASoC jack * @count: Number of zones - * @zone: Array of zones + * @zones: Array of zones * * After this function has been called the zones specified in the * array will be associated with the jack. -- GitLab From 4470c725ba7b86481c31466640ab487f927de6b7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 18 Nov 2014 15:12:43 +0100 Subject: [PATCH 5176/9457] i2c: acpi: remove unneeded variable initialization No need to initialize 'ret' if it gets assigned directly after that. Signed-off-by: Wolfram Sang Acked-by: Mika Westerberg --- drivers/i2c/i2c-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index cf830915713b..3105bd273f70 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -260,7 +260,7 @@ acpi_i2c_space_handler(u32 function, acpi_physical_address command, struct acpi_resource *ares; u32 accessor_type = function >> 16; u8 action = function & ACPI_IO_MASK; - acpi_status ret = AE_OK; + acpi_status ret; int status; ret = acpi_buffer_to_resource(info->connection, info->length, &ares); -- GitLab From 51cf3b0e2a72bb08cd280be6c0ead4e08ed50a2c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 13 Nov 2014 14:39:55 +0100 Subject: [PATCH 5177/9457] i2c: mux: create symlink to actual mux device The current implementation creates muxed i2c- busses as immediate children of their i2c- parent bus. In case of multiple muxes on one bus, it is impossible to determine which muxed bus comes from which mux. It could be argued that the parent device should be changed from the parent adapter to the mux device. This has pros and cons. To improve the topology, simply add a "mux_device" symlink pointing to the actual muxing device, so we can distinguish muxed busses. Doing it this way, we don't break the ABI. Signed-off-by: Wolfram Sang Tested-by: Guenter Roeck --- drivers/i2c/i2c-mux.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 2d0847b6be62..f246a9f7dd22 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -183,6 +183,9 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, return NULL; } + WARN(sysfs_create_link(&priv->adap.dev.kobj, &mux_dev->kobj, "mux_device"), + "can't create symlink to mux device\n"); + dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", i2c_adapter_id(&priv->adap)); @@ -194,6 +197,7 @@ void i2c_del_mux_adapter(struct i2c_adapter *adap) { struct i2c_mux_priv *priv = adap->algo_data; + sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); i2c_del_adapter(adap); kfree(priv); } -- GitLab From c9449affad2ae0824927df5a207705e07f346fb1 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Thu, 13 Nov 2014 14:39:56 +0100 Subject: [PATCH 5178/9457] i2c: mux: create "channel-n" symlinks for child segments in the mux device This makes the topology clearer. For instance, by adding a pca9547 device with address 0x70 to bus i2c-0, you get: /sys/class/i2c-dev/i2c-0/device/0-0070/channel-0 -> i2c-1 ... /sys/class/i2c-dev/i2c-0/device/0-0070/channel-7 -> i2c-8 Signed-off-by: Gerlando Falauto [wsa: simplified sysfs-usage and fixed format string usage] Signed-off-by: Wolfram Sang Acked-by: Martin Belanger Acked-by: Danielle Costantino --- drivers/i2c/i2c-mux.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index f246a9f7dd22..593f7ca9adc7 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -110,6 +110,7 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, void *, u32)) { struct i2c_mux_priv *priv; + char symlink_name[20]; int ret; priv = kzalloc(sizeof(struct i2c_mux_priv), GFP_KERNEL); @@ -186,6 +187,9 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, WARN(sysfs_create_link(&priv->adap.dev.kobj, &mux_dev->kobj, "mux_device"), "can't create symlink to mux device\n"); + snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id); + WARN(sysfs_create_link(&mux_dev->kobj, &priv->adap.dev.kobj, symlink_name), + "can't create symlink for channel %u\n", chan_id); dev_info(&parent->dev, "Added multiplexed i2c bus %d\n", i2c_adapter_id(&priv->adap)); @@ -196,6 +200,10 @@ EXPORT_SYMBOL_GPL(i2c_add_mux_adapter); void i2c_del_mux_adapter(struct i2c_adapter *adap) { struct i2c_mux_priv *priv = adap->algo_data; + char symlink_name[20]; + + snprintf(symlink_name, sizeof(symlink_name), "channel-%u", priv->chan_id); + sysfs_remove_link(&adap->dev.parent->kobj, symlink_name); sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); i2c_del_adapter(adap); -- GitLab From 30021e3707a75cc29dc1252c062d374151c5985f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 13 Nov 2014 20:32:01 +0100 Subject: [PATCH 5179/9457] i2c: add support for Amlogic Meson I2C controller This is a driver for the I2C controller found in Amlogic Meson SoCs. Signed-off-by: Beniamino Galvani Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-meson.txt | 24 + drivers/i2c/busses/Kconfig | 7 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-meson.c | 492 ++++++++++++++++++ 4 files changed, 524 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/i2c-meson.txt create mode 100644 drivers/i2c/busses/i2c-meson.c diff --git a/Documentation/devicetree/bindings/i2c/i2c-meson.txt b/Documentation/devicetree/bindings/i2c/i2c-meson.txt new file mode 100644 index 000000000000..682f9a6f766e --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-meson.txt @@ -0,0 +1,24 @@ +Amlogic Meson I2C controller + +Required properties: + - compatible: must be "amlogic,meson6-i2c" + - reg: physical address and length of the device registers + - interrupts: a single interrupt specifier + - clocks: clock for the device + - #address-cells: should be <1> + - #size-cells: should be <0> + +Optional properties: +- clock-frequency: the desired I2C bus clock frequency in Hz; in + absence of this property the default value is used (100 kHz). + +Examples: + + i2c@c8100500 { + compatible = "amlogic,meson6-i2c"; + reg = <0xc8100500 0x20>; + interrupts = <0 92 1>; + clocks = <&clk81>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 03c6119325ef..a940e336351d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -564,6 +564,13 @@ config I2C_KEMPLD This driver can also be built as a module. If so, the module will be called i2c-kempld. +config I2C_MESON + tristate "Amlogic Meson I2C controller" + depends on ARCH_MESON + help + If you say yes to this option, support will be included for the + I2C interface on the Amlogic Meson family of SoCs. + config I2C_MPC tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx" depends on PPC diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 84861ead6be9..e9b4a1f8431f 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o +obj-$(CONFIG_I2C_MESON) += i2c-meson.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_MXS) += i2c-mxs.o diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c new file mode 100644 index 000000000000..5e176adca8e8 --- /dev/null +++ b/drivers/i2c/busses/i2c-meson.c @@ -0,0 +1,492 @@ +/* + * I2C bus driver for Amlogic Meson SoCs + * + * Copyright (C) 2014 Beniamino Galvani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Meson I2C register map */ +#define REG_CTRL 0x00 +#define REG_SLAVE_ADDR 0x04 +#define REG_TOK_LIST0 0x08 +#define REG_TOK_LIST1 0x0c +#define REG_TOK_WDATA0 0x10 +#define REG_TOK_WDATA1 0x14 +#define REG_TOK_RDATA0 0x18 +#define REG_TOK_RDATA1 0x1c + +/* Control register fields */ +#define REG_CTRL_START BIT(0) +#define REG_CTRL_ACK_IGNORE BIT(1) +#define REG_CTRL_STATUS BIT(2) +#define REG_CTRL_ERROR BIT(3) +#define REG_CTRL_CLKDIV_SHIFT 12 +#define REG_CTRL_CLKDIV_MASK ((BIT(10) - 1) << REG_CTRL_CLKDIV_SHIFT) + +#define I2C_TIMEOUT_MS 500 +#define DEFAULT_FREQ 100000 + +enum { + TOKEN_END = 0, + TOKEN_START, + TOKEN_SLAVE_ADDR_WRITE, + TOKEN_SLAVE_ADDR_READ, + TOKEN_DATA, + TOKEN_DATA_LAST, + TOKEN_STOP, +}; + +enum { + STATE_IDLE, + STATE_READ, + STATE_WRITE, + STATE_STOP, +}; + +/** + * struct meson_i2c - Meson I2C device private data + * + * @adap: I2C adapter instance + * @dev: Pointer to device structure + * @regs: Base address of the device memory mapped registers + * @clk: Pointer to clock structure + * @irq: IRQ number + * @msg: Pointer to the current I2C message + * @state: Current state in the driver state machine + * @last: Flag set for the last message in the transfer + * @count: Number of bytes to be sent/received in current transfer + * @pos: Current position in the send/receive buffer + * @error: Flag set when an error is received + * @lock: To avoid race conditions between irq handler and xfer code + * @done: Completion used to wait for transfer termination + * @frequency: Operating frequency of I2C bus clock + * @tokens: Sequence of tokens to be written to the device + * @num_tokens: Number of tokens + */ +struct meson_i2c { + struct i2c_adapter adap; + struct device *dev; + void __iomem *regs; + struct clk *clk; + int irq; + + struct i2c_msg *msg; + int state; + bool last; + int count; + int pos; + int error; + + spinlock_t lock; + struct completion done; + unsigned int frequency; + u32 tokens[2]; + int num_tokens; +}; + +static void meson_i2c_set_mask(struct meson_i2c *i2c, int reg, u32 mask, + u32 val) +{ + u32 data; + + data = readl(i2c->regs + reg); + data &= ~mask; + data |= val & mask; + writel(data, i2c->regs + reg); +} + +static void meson_i2c_reset_tokens(struct meson_i2c *i2c) +{ + i2c->tokens[0] = 0; + i2c->tokens[1] = 0; + i2c->num_tokens = 0; +} + +static void meson_i2c_add_token(struct meson_i2c *i2c, int token) +{ + if (i2c->num_tokens < 8) + i2c->tokens[0] |= (token & 0xf) << (i2c->num_tokens * 4); + else + i2c->tokens[1] |= (token & 0xf) << ((i2c->num_tokens % 8) * 4); + + i2c->num_tokens++; +} + +static void meson_i2c_write_tokens(struct meson_i2c *i2c) +{ + writel(i2c->tokens[0], i2c->regs + REG_TOK_LIST0); + writel(i2c->tokens[1], i2c->regs + REG_TOK_LIST1); +} + +static void meson_i2c_set_clk_div(struct meson_i2c *i2c) +{ + unsigned long clk_rate = clk_get_rate(i2c->clk); + unsigned int div; + + div = DIV_ROUND_UP(clk_rate, i2c->frequency * 4); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK, + div << REG_CTRL_CLKDIV_SHIFT); + + dev_dbg(i2c->dev, "%s: clk %lu, freq %u, div %u\n", __func__, + clk_rate, i2c->frequency, div); +} + +static void meson_i2c_get_data(struct meson_i2c *i2c, char *buf, int len) +{ + u32 rdata0, rdata1; + int i; + + rdata0 = readl(i2c->regs + REG_TOK_RDATA0); + rdata1 = readl(i2c->regs + REG_TOK_RDATA1); + + dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, + rdata0, rdata1, len); + + for (i = 0; i < min_t(int, 4, len); i++) + *buf++ = (rdata0 >> i * 8) & 0xff; + + for (i = 4; i < min_t(int, 8, len); i++) + *buf++ = (rdata1 >> (i - 4) * 8) & 0xff; +} + +static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len) +{ + u32 wdata0 = 0, wdata1 = 0; + int i; + + for (i = 0; i < min_t(int, 4, len); i++) + wdata0 |= *buf++ << (i * 8); + + for (i = 4; i < min_t(int, 8, len); i++) + wdata1 |= *buf++ << ((i - 4) * 8); + + writel(wdata0, i2c->regs + REG_TOK_WDATA0); + writel(wdata0, i2c->regs + REG_TOK_WDATA1); + + dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, + wdata0, wdata1, len); +} + +static void meson_i2c_prepare_xfer(struct meson_i2c *i2c) +{ + bool write = !(i2c->msg->flags & I2C_M_RD); + int i; + + i2c->count = min_t(int, i2c->msg->len - i2c->pos, 8); + + for (i = 0; i < i2c->count - 1; i++) + meson_i2c_add_token(i2c, TOKEN_DATA); + + if (i2c->count) { + if (write || i2c->pos + i2c->count < i2c->msg->len) + meson_i2c_add_token(i2c, TOKEN_DATA); + else + meson_i2c_add_token(i2c, TOKEN_DATA_LAST); + } + + if (write) + meson_i2c_put_data(i2c, i2c->msg->buf + i2c->pos, i2c->count); +} + +static void meson_i2c_stop(struct meson_i2c *i2c) +{ + dev_dbg(i2c->dev, "%s: last %d\n", __func__, i2c->last); + + if (i2c->last) { + i2c->state = STATE_STOP; + meson_i2c_add_token(i2c, TOKEN_STOP); + } else { + i2c->state = STATE_IDLE; + complete_all(&i2c->done); + } +} + +static irqreturn_t meson_i2c_irq(int irqno, void *dev_id) +{ + struct meson_i2c *i2c = dev_id; + unsigned int ctrl; + + spin_lock(&i2c->lock); + + meson_i2c_reset_tokens(i2c); + ctrl = readl(i2c->regs + REG_CTRL); + + dev_dbg(i2c->dev, "irq: state %d, pos %d, count %d, ctrl %08x\n", + i2c->state, i2c->pos, i2c->count, ctrl); + + if (ctrl & REG_CTRL_ERROR && i2c->state != STATE_IDLE) { + /* + * The bit is set when the IGNORE_NAK bit is cleared + * and the device didn't respond. In this case, the + * I2C controller automatically generates a STOP + * condition. + */ + dev_dbg(i2c->dev, "error bit set\n"); + i2c->error = -ENXIO; + i2c->state = STATE_IDLE; + complete_all(&i2c->done); + goto out; + } + + switch (i2c->state) { + case STATE_READ: + if (i2c->count > 0) { + meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, + i2c->count); + i2c->pos += i2c->count; + } + + if (i2c->pos >= i2c->msg->len) { + meson_i2c_stop(i2c); + break; + } + + meson_i2c_prepare_xfer(i2c); + break; + case STATE_WRITE: + i2c->pos += i2c->count; + + if (i2c->pos >= i2c->msg->len) { + meson_i2c_stop(i2c); + break; + } + + meson_i2c_prepare_xfer(i2c); + break; + case STATE_STOP: + i2c->state = STATE_IDLE; + complete_all(&i2c->done); + break; + case STATE_IDLE: + break; + } + +out: + if (i2c->state != STATE_IDLE) { + /* Restart the processing */ + meson_i2c_write_tokens(i2c); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, + REG_CTRL_START); + } + + spin_unlock(&i2c->lock); + + return IRQ_HANDLED; +} + +static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg) +{ + int token; + + token = (msg->flags & I2C_M_RD) ? TOKEN_SLAVE_ADDR_READ : + TOKEN_SLAVE_ADDR_WRITE; + + writel(msg->addr << 1, i2c->regs + REG_SLAVE_ADDR); + meson_i2c_add_token(i2c, TOKEN_START); + meson_i2c_add_token(i2c, token); +} + +static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg, + int last) +{ + unsigned long time_left, flags; + int ret = 0; + + i2c->msg = msg; + i2c->last = last; + i2c->pos = 0; + i2c->count = 0; + i2c->error = 0; + + meson_i2c_reset_tokens(i2c); + + flags = (msg->flags & I2C_M_IGNORE_NAK) ? REG_CTRL_ACK_IGNORE : 0; + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_ACK_IGNORE, flags); + + if (!(msg->flags & I2C_M_NOSTART)) + meson_i2c_do_start(i2c, msg); + + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + meson_i2c_prepare_xfer(i2c); + meson_i2c_write_tokens(i2c); + reinit_completion(&i2c->done); + + /* Start the transfer */ + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, REG_CTRL_START); + + time_left = msecs_to_jiffies(I2C_TIMEOUT_MS); + time_left = wait_for_completion_timeout(&i2c->done, time_left); + + /* + * Protect access to i2c struct and registers from interrupt + * handlers triggered by a transfer terminated after the + * timeout period + */ + spin_lock_irqsave(&i2c->lock, flags); + + /* Abort any active operation */ + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); + + if (!time_left) { + i2c->state = STATE_IDLE; + ret = -ETIMEDOUT; + } + + if (i2c->error) + ret = i2c->error; + + spin_unlock_irqrestore(&i2c->lock, flags); + + return ret; +} + +static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num) +{ + struct meson_i2c *i2c = adap->algo_data; + int i, ret = 0, count = 0; + + clk_enable(i2c->clk); + meson_i2c_set_clk_div(i2c); + + for (i = 0; i < num; i++) { + ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1); + if (ret) + break; + count++; + } + + clk_disable(i2c->clk); + + return ret ? ret : count; +} + +static u32 meson_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm meson_i2c_algorithm = { + .master_xfer = meson_i2c_xfer, + .functionality = meson_i2c_func, +}; + +static int meson_i2c_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct meson_i2c *i2c; + struct resource *mem; + int ret = 0; + + i2c = devm_kzalloc(&pdev->dev, sizeof(struct meson_i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", + &i2c->frequency)) + i2c->frequency = DEFAULT_FREQ; + + i2c->dev = &pdev->dev; + platform_set_drvdata(pdev, i2c); + + spin_lock_init(&i2c->lock); + init_completion(&i2c->done); + + i2c->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(i2c->clk)) { + dev_err(&pdev->dev, "can't get device clock\n"); + return PTR_ERR(i2c->clk); + } + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + i2c->regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(i2c->regs)) + return PTR_ERR(i2c->regs); + + i2c->irq = platform_get_irq(pdev, 0); + if (i2c->irq < 0) { + dev_err(&pdev->dev, "can't find IRQ\n"); + return i2c->irq; + } + + ret = devm_request_irq(&pdev->dev, i2c->irq, meson_i2c_irq, + 0, dev_name(&pdev->dev), i2c); + if (ret < 0) { + dev_err(&pdev->dev, "can't request IRQ\n"); + return ret; + } + + ret = clk_prepare(i2c->clk); + if (ret < 0) { + dev_err(&pdev->dev, "can't prepare clock\n"); + return ret; + } + + strlcpy(i2c->adap.name, "Meson I2C adapter", + sizeof(i2c->adap.name)); + i2c->adap.owner = THIS_MODULE; + i2c->adap.algo = &meson_i2c_algorithm; + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.dev.of_node = np; + i2c->adap.algo_data = i2c; + + /* + * A transfer is triggered when START bit changes from 0 to 1. + * Ensure that the bit is set to 0 after probe + */ + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); + + ret = i2c_add_adapter(&i2c->adap); + if (ret < 0) { + dev_err(&pdev->dev, "can't register adapter\n"); + clk_unprepare(i2c->clk); + return ret; + } + + return 0; +} + +static int meson_i2c_remove(struct platform_device *pdev) +{ + struct meson_i2c *i2c = platform_get_drvdata(pdev); + + i2c_del_adapter(&i2c->adap); + clk_unprepare(i2c->clk); + + return 0; +} + +static const struct of_device_id meson_i2c_match[] = { + { .compatible = "amlogic,meson6-i2c" }, + { }, +}; + +static struct platform_driver meson_i2c_driver = { + .probe = meson_i2c_probe, + .remove = meson_i2c_remove, + .driver = { + .name = "meson-i2c", + .of_match_table = meson_i2c_match, + }, +}; + +module_platform_driver(meson_i2c_driver); + +MODULE_DESCRIPTION("Amlogic Meson I2C Bus driver"); +MODULE_AUTHOR("Beniamino Galvani "); +MODULE_LICENSE("GPL v2"); -- GitLab From 6dcc0cf6cb3120cedc0d4c12171894f3d6415981 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 18 Nov 2014 08:21:18 -0700 Subject: [PATCH 5180/9457] NVMe: nvme_submit_async_admin_req() must use atomic rq allocation We are called for async event notification issues, and the nvmeq lock is already held. If we fail the request allocation, we'll just retry next time. Reported-by: Julia Lawall Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index bbac17f29fe7..fb4b205317c6 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -825,7 +825,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) struct nvme_cmd_info *cmd_info; struct request *req; - req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_KERNEL, false); + req = blk_mq_alloc_request(dev->admin_q, WRITE, GFP_ATOMIC, false); if (IS_ERR(req)) return PTR_ERR(req); -- GitLab From 77c1aa84de0096792de673aa1c64c36b38553cf5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 18 Nov 2014 13:27:07 +0100 Subject: [PATCH 5181/9457] drm/i915: Don't print header in error state for non-existing CS This goes back to commit 362b8af7ad1d91266aa4931e62be45c1e5cf753b Author: Ben Widawsky Date: Thu Jan 30 00:19:38 2014 -0800 drm/i915: Move per ring error state to ring_error Spotted while reading error states. Cc: Ben Widawsky Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 89a2f3dbf956..82111b8ad374 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -242,11 +242,15 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a) static void i915_ring_error_state(struct drm_i915_error_state_buf *m, struct drm_device *dev, - struct drm_i915_error_ring *ring) + struct drm_i915_error_state *error, + int ring_idx) { + struct drm_i915_error_ring *ring = &error->ring[ring_idx]; + if (!ring->valid) return; + err_printf(m, "%s command stream:\n", ring_str(ring_idx)); err_printf(m, " HEAD: 0x%08x\n", ring->head); err_printf(m, " TAIL: 0x%08x\n", ring->tail); err_printf(m, " CTL: 0x%08x\n", ring->ctl); @@ -388,10 +392,8 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, if (INTEL_INFO(dev)->gen == 7) err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); - for (i = 0; i < ARRAY_SIZE(error->ring); i++) { - err_printf(m, "%s command stream:\n", ring_str(i)); - i915_ring_error_state(m, dev, &error->ring[i]); - } + for (i = 0; i < ARRAY_SIZE(error->ring); i++) + i915_ring_error_state(m, dev, error, i); for (i = 0; i < error->vm_count; i++) { err_printf(m, "vm[%d]\n", i); -- GitLab From 35480e3536cdab1ee1976675e798f16d707f5356 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:43 +0100 Subject: [PATCH 5182/9457] ASoC: mpc5200_psc_ac97: Remove unused on-stack snd_ac97 device The mpc5200_psc_ac97 driver puts a snd_ac97 device on the stack in the driver probe function, initializes the private data member of the device and the never uses the device again. It should be safe to remove it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/fsl/mpc5200_psc_ac97.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 24eafa2cfbf4..640801a60c12 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -282,7 +282,6 @@ static const struct snd_soc_component_driver psc_ac97_component = { static int psc_ac97_of_probe(struct platform_device *op) { int rc; - struct snd_ac97 ac97; struct mpc52xx_psc __iomem *regs; rc = mpc5200_audio_dma_create(op); @@ -304,7 +303,6 @@ static int psc_ac97_of_probe(struct platform_device *op) psc_dma = dev_get_drvdata(&op->dev); regs = psc_dma->psc_regs; - ac97.private_data = psc_dma; psc_dma->imr = 0; out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr); -- GitLab From 65c72efd1ea370f0311a5d89754996fff9fc0747 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:44 +0100 Subject: [PATCH 5183/9457] ASoC: mpc5200_dma: Don't overwrite ac97 device private_data The mpc5200_dma overwrites the private_data field of the CODEC's AC'97 device with the DMA drivers private data, but never actually reads it again. Given that the private_data field is supposed to be owned by the AC'97 driver, overwriting it may cause undefined behavior. This patch removes the code that overwrites the field from the driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/fsl/mpc5200_dma.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index f2b5d756b1f3..0b82e209b6e3 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -327,9 +327,6 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) goto capture_alloc_err; } - if (rtd->codec->ac97) - rtd->codec->ac97->private_data = psc_dma; - return 0; capture_alloc_err: -- GitLab From 70f3af3ca15affaef3d026a5aa6e44c4627ea6c7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:45 +0100 Subject: [PATCH 5184/9457] ASoC: Properly handle AC'97 device lifetime management The memory that a struct device is contained in must not be freed except from within the device's release callback. The ASoC code currently does not adhere to this rule for the AC'97 device. This patch fixes it by moving the freeing of the AC'97 to the release callback and splitting up the registration and unregistration of the device into separate steps for getting/putting the reference to the device and adding/removing it to the device hierarchy. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..7084c6f1285a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -504,13 +504,10 @@ EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) { if (codec->ac97->dev.bus) - device_unregister(&codec->ac97->dev); + device_del(&codec->ac97->dev); return 0; } -/* stop no dev release warning */ -static void soc_ac97_device_release(struct device *dev){} - /* register ac97 codec to bus */ static int soc_ac97_dev_register(struct snd_soc_codec *codec) { @@ -518,12 +515,11 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) codec->ac97->dev.bus = &ac97_bus_type; codec->ac97->dev.parent = codec->component.card->dev; - codec->ac97->dev.release = soc_ac97_device_release; dev_set_name(&codec->ac97->dev, "%d-%d:%s", codec->component.card->snd_card->number, 0, codec->component.name); - err = device_register(&codec->ac97->dev); + err = device_add(&codec->ac97->dev); if (err < 0) { dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); codec->ac97->dev.bus = NULL; @@ -1948,6 +1944,11 @@ static struct platform_driver soc_driver = { .remove = soc_remove, }; +static void soc_ac97_device_release(struct device *dev) +{ + kfree(to_ac97_t(dev)); +} + /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec @@ -1972,12 +1973,14 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, codec->ac97->bus->ops = ops; codec->ac97->num = num; + codec->ac97->dev.release = soc_ac97_device_release; /* * Mark the AC97 device to be created by us. This way we ensure that the * device will be registered with the device subsystem later on. */ codec->ac97_created = 1; + device_initialize(&codec->ac97->dev); return 0; } @@ -2152,7 +2155,8 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) soc_unregister_ac97_codec(codec); #endif kfree(codec->ac97->bus); - kfree(codec->ac97); + codec->ac97->bus = NULL; + put_device(&codec->ac97->dev); codec->ac97 = NULL; codec->ac97_created = 0; } -- GitLab From 336b8423e285174ebecf02a743d69913b83bbc48 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:46 +0100 Subject: [PATCH 5185/9457] ASoC: Move AC'97 support to its own file Currently the AC'97 support is splattered all throughout soc-core.c. Some parts are #ifdef'd some parts are not. This patch moves the AC'97 support to its own file, this should make the code a bit more clearer and also makes it possible to easily not compile it into the kernel when not needed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 28 +++- sound/soc/Makefile | 4 + sound/soc/soc-ac97.c | 382 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-core.c | 352 +-------------------------------------- 4 files changed, 416 insertions(+), 350 deletions(-) create mode 100644 sound/soc/soc-ac97.c diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..adef34fa5209 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -366,8 +366,6 @@ struct snd_soc_jack_gpio; typedef int (*hw_write_t)(void *,const char* ,int); -extern struct snd_ac97_bus_ops *soc_ac97_ops; - enum snd_soc_pcm_subclass { SND_SOC_PCM_CLASS_PCM = 0, SND_SOC_PCM_CLASS_BE = 1, @@ -500,6 +498,7 @@ int snd_soc_update_bits_locked(struct snd_soc_codec *codec, int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); +#ifdef CONFIG_SND_SOC_AC97_BUS int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, struct snd_ac97_bus_ops *ops, int num); void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); @@ -508,6 +507,31 @@ int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops); int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct platform_device *pdev); +extern struct snd_ac97_bus_ops *soc_ac97_ops; + +int snd_soc_ac97_register_dai_links(struct snd_soc_card *card); +void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd); +#else + +static inline int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) +{ + return 0; +} + +static inline void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd) {} + +static inline int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, + struct platform_device *pdev) +{ + return 0; +} + +static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops) +{ + return 0; +} +#endif + /* *Controls */ diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 534714a1ca44..0fded1bb613f 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -5,6 +5,10 @@ ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-objs += soc-generic-dmaengine-pcm.o endif +ifneq ($(CONFIG_SND_SOC_AC97_BUS),) +snd-soc-core-objs += soc-ac97.o +endif + obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c new file mode 100644 index 000000000000..da7b031a6eea --- /dev/null +++ b/sound/soc/soc-ac97.c @@ -0,0 +1,382 @@ +/* + * soc-ac97.c -- ALSA SoC Audio Layer AC97 support + * + * Copyright 2005 Wolfson Microelectronics PLC. + * Copyright 2005 Openedhand Ltd. + * Copyright (C) 2010 Slimlogic Ltd. + * Copyright (C) 2010 Texas Instruments Inc. + * + * Author: Liam Girdwood + * with code, comments and ideas from :- + * Richard Purdie + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct snd_ac97_reset_cfg { + struct pinctrl *pctl; + struct pinctrl_state *pstate_reset; + struct pinctrl_state *pstate_warm_reset; + struct pinctrl_state *pstate_run; + int gpio_sdata; + int gpio_sync; + int gpio_reset; +}; + +/* unregister ac97 codec */ +static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) +{ + if (codec->ac97->dev.bus) + device_del(&codec->ac97->dev); + return 0; +} + +/* register ac97 codec to bus */ +static int soc_ac97_dev_register(struct snd_soc_codec *codec) +{ + int err; + + codec->ac97->dev.bus = &ac97_bus_type; + codec->ac97->dev.parent = codec->component.card->dev; + + dev_set_name(&codec->ac97->dev, "%d-%d:%s", + codec->component.card->snd_card->number, 0, + codec->component.name); + err = device_add(&codec->ac97->dev); + if (err < 0) { + dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); + codec->ac97->dev.bus = NULL; + return err; + } + return 0; +} + +static int soc_register_ac97_codec(struct snd_soc_codec *codec, + struct snd_soc_dai *codec_dai) +{ + int ret; + + /* Only instantiate AC97 if not already done by the adaptor + * for the generic AC97 subsystem. + */ + if (codec_dai->driver->ac97_control && !codec->ac97_registered) { + /* + * It is possible that the AC97 device is already registered to + * the device subsystem. This happens when the device is created + * via snd_ac97_mixer(). Currently only SoC codec that does so + * is the generic AC97 glue but others migh emerge. + * + * In those cases we don't try to register the device again. + */ + if (!codec->ac97_created) + return 0; + + ret = soc_ac97_dev_register(codec); + if (ret < 0) { + dev_err(codec->dev, + "ASoC: AC97 device register failed: %d\n", ret); + return ret; + } + + codec->ac97_registered = 1; + } + return 0; +} + +static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) +{ + if (codec->ac97_registered) { + soc_ac97_dev_unregister(codec); + codec->ac97_registered = 0; + } +} + +static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + int i, ret; + + for (i = 0; i < rtd->num_codecs; i++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; + + ret = soc_register_ac97_codec(codec_dai->codec, codec_dai); + if (ret) { + while (--i >= 0) + soc_unregister_ac97_codec(codec_dai->codec); + return ret; + } + } + + return 0; +} + +static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + int i; + + for (i = 0; i < rtd->num_codecs; i++) + soc_unregister_ac97_codec(rtd->codec_dais[i]->codec); +} + +static void soc_ac97_device_release(struct device *dev) +{ + kfree(to_ac97_t(dev)); +} + +/** + * snd_soc_new_ac97_codec - initailise AC97 device + * @codec: audio codec + * @ops: AC97 bus operations + * @num: AC97 codec number + * + * Initialises AC97 codec resources for use by ad-hoc devices only. + */ +int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, + struct snd_ac97_bus_ops *ops, int num) +{ + codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); + if (codec->ac97 == NULL) + return -ENOMEM; + + codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL); + if (codec->ac97->bus == NULL) { + kfree(codec->ac97); + codec->ac97 = NULL; + return -ENOMEM; + } + + codec->ac97->bus->ops = ops; + codec->ac97->num = num; + codec->ac97->dev.release = soc_ac97_device_release; + + /* + * Mark the AC97 device to be created by us. This way we ensure that the + * device will be registered with the device subsystem later on. + */ + codec->ac97_created = 1; + device_initialize(&codec->ac97->dev); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); + +/** + * snd_soc_free_ac97_codec - free AC97 codec device + * @codec: audio codec + * + * Frees AC97 codec device resources. + */ +void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) +{ + soc_unregister_ac97_codec(codec); + kfree(codec->ac97->bus); + codec->ac97->bus = NULL; + put_device(&codec->ac97->dev); + codec->ac97 = NULL; + codec->ac97_created = 0; +} +EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); + +static struct snd_ac97_reset_cfg snd_ac97_rst_cfg; + +static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97) +{ + struct pinctrl *pctl = snd_ac97_rst_cfg.pctl; + + pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset); + + gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1); + + udelay(10); + + gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0); + + pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run); + msleep(2); +} + +static void snd_soc_ac97_reset(struct snd_ac97 *ac97) +{ + struct pinctrl *pctl = snd_ac97_rst_cfg.pctl; + + pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset); + + gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0); + gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0); + gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0); + + udelay(10); + + gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1); + + pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run); + msleep(2); +} + +static int snd_soc_ac97_parse_pinctl(struct device *dev, + struct snd_ac97_reset_cfg *cfg) +{ + struct pinctrl *p; + struct pinctrl_state *state; + int gpio; + int ret; + + p = devm_pinctrl_get(dev); + if (IS_ERR(p)) { + dev_err(dev, "Failed to get pinctrl\n"); + return PTR_ERR(p); + } + cfg->pctl = p; + + state = pinctrl_lookup_state(p, "ac97-reset"); + if (IS_ERR(state)) { + dev_err(dev, "Can't find pinctrl state ac97-reset\n"); + return PTR_ERR(state); + } + cfg->pstate_reset = state; + + state = pinctrl_lookup_state(p, "ac97-warm-reset"); + if (IS_ERR(state)) { + dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); + return PTR_ERR(state); + } + cfg->pstate_warm_reset = state; + + state = pinctrl_lookup_state(p, "ac97-running"); + if (IS_ERR(state)) { + dev_err(dev, "Can't find pinctrl state ac97-running\n"); + return PTR_ERR(state); + } + cfg->pstate_run = state; + + gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0); + if (gpio < 0) { + dev_err(dev, "Can't find ac97-sync gpio\n"); + return gpio; + } + ret = devm_gpio_request(dev, gpio, "AC97 link sync"); + if (ret) { + dev_err(dev, "Failed requesting ac97-sync gpio\n"); + return ret; + } + cfg->gpio_sync = gpio; + + gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1); + if (gpio < 0) { + dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio); + return gpio; + } + ret = devm_gpio_request(dev, gpio, "AC97 link sdata"); + if (ret) { + dev_err(dev, "Failed requesting ac97-sdata gpio\n"); + return ret; + } + cfg->gpio_sdata = gpio; + + gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2); + if (gpio < 0) { + dev_err(dev, "Can't find ac97-reset gpio\n"); + return gpio; + } + ret = devm_gpio_request(dev, gpio, "AC97 link reset"); + if (ret) { + dev_err(dev, "Failed requesting ac97-reset gpio\n"); + return ret; + } + cfg->gpio_reset = gpio; + + return 0; +} + +struct snd_ac97_bus_ops *soc_ac97_ops; +EXPORT_SYMBOL_GPL(soc_ac97_ops); + +int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops) +{ + if (ops == soc_ac97_ops) + return 0; + + if (soc_ac97_ops && ops) + return -EBUSY; + + soc_ac97_ops = ops; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops); + +/** + * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions + * + * This function sets the reset and warm_reset properties of ops and parses + * the device node of pdev to get pinctrl states and gpio numbers to use. + */ +int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct snd_ac97_reset_cfg cfg; + int ret; + + ret = snd_soc_ac97_parse_pinctl(dev, &cfg); + if (ret) + return ret; + + ret = snd_soc_set_ac97_ops(ops); + if (ret) + return ret; + + ops->warm_reset = snd_soc_ac97_warm_reset; + ops->reset = snd_soc_ac97_reset; + + snd_ac97_rst_cfg = cfg; + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset); + +int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) +{ + int i; + int ret; + + /* register any AC97 codecs */ + for (i = 0; i < card->num_rtd; i++) { + ret = soc_register_ac97_dai_link(&card->rtd[i]); + if (ret < 0) + goto err; + } + + return 0; +err: + dev_err(card->dev, + "ASoC: failed to register AC97: %d\n", ret); + while (--i >= 0) + soc_unregister_ac97_dai_link(&card->rtd[i]); + return ret; +} + +void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int i; + + /* add platform data for AC97 devices */ + for (i = 0; i < rtd->num_codecs; i++) { + if (rtd->codec_dais[i]->driver->ac97_control) + snd_ac97_dev_add_pdata(rtd->codec_dais[i]->codec->ac97, + rtd->cpu_dai->ac97_pdata); + } +} diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 7084c6f1285a..026722f5ebf4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -34,9 +34,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -69,16 +66,6 @@ static int pmdown_time = 5000; module_param(pmdown_time, int, 0); MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); -struct snd_ac97_reset_cfg { - struct pinctrl *pctl; - struct pinctrl_state *pstate_reset; - struct pinctrl_state *pstate_warm_reset; - struct pinctrl_state *pstate_run; - int gpio_sdata; - int gpio_sync; - int gpio_reset; -}; - /* returns the minimum number of bytes needed to represent * a particular given value */ static int min_bytes_needed(unsigned long val) @@ -499,36 +486,6 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime); -#ifdef CONFIG_SND_SOC_AC97_BUS -/* unregister ac97 codec */ -static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) -{ - if (codec->ac97->dev.bus) - device_del(&codec->ac97->dev); - return 0; -} - -/* register ac97 codec to bus */ -static int soc_ac97_dev_register(struct snd_soc_codec *codec) -{ - int err; - - codec->ac97->dev.bus = &ac97_bus_type; - codec->ac97->dev.parent = codec->component.card->dev; - - dev_set_name(&codec->ac97->dev, "%d-%d:%s", - codec->component.card->snd_card->number, 0, - codec->component.name); - err = device_add(&codec->ac97->dev); - if (err < 0) { - dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); - codec->ac97->dev.bus = NULL; - return err; - } - return 0; -} -#endif - static void codec2codec_close_delayed_work(struct work_struct *work) { /* Currently nothing to do for c2c links @@ -1418,84 +1375,11 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } } - /* add platform data for AC97 devices */ - for (i = 0; i < rtd->num_codecs; i++) { - if (rtd->codec_dais[i]->driver->ac97_control) - snd_ac97_dev_add_pdata(rtd->codec_dais[i]->codec->ac97, - rtd->cpu_dai->ac97_pdata); - } - - return 0; -} - -#ifdef CONFIG_SND_SOC_AC97_BUS -static int soc_register_ac97_codec(struct snd_soc_codec *codec, - struct snd_soc_dai *codec_dai) -{ - int ret; - - /* Only instantiate AC97 if not already done by the adaptor - * for the generic AC97 subsystem. - */ - if (codec_dai->driver->ac97_control && !codec->ac97_registered) { - /* - * It is possible that the AC97 device is already registered to - * the device subsystem. This happens when the device is created - * via snd_ac97_mixer(). Currently only SoC codec that does so - * is the generic AC97 glue but others migh emerge. - * - * In those cases we don't try to register the device again. - */ - if (!codec->ac97_created) - return 0; - - ret = soc_ac97_dev_register(codec); - if (ret < 0) { - dev_err(codec->dev, - "ASoC: AC97 device register failed: %d\n", ret); - return ret; - } - - codec->ac97_registered = 1; - } - return 0; -} - -static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) -{ - if (codec->ac97_registered) { - soc_ac97_dev_unregister(codec); - codec->ac97_registered = 0; - } -} - -static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) -{ - int i, ret; - - for (i = 0; i < rtd->num_codecs; i++) { - struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; - - ret = soc_register_ac97_codec(codec_dai->codec, codec_dai); - if (ret) { - while (--i >= 0) - soc_unregister_ac97_codec(codec_dai->codec); - return ret; - } - } + snd_soc_ac97_add_pdata(rtd); return 0; } -static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) -{ - int i; - - for (i = 0; i < rtd->num_codecs; i++) - soc_unregister_ac97_codec(rtd->codec_dais[i]->codec); -} -#endif - static int soc_bind_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; @@ -1789,19 +1673,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto probe_aux_dev_err; } -#ifdef CONFIG_SND_SOC_AC97_BUS - /* register any AC97 codecs */ - for (i = 0; i < card->num_rtd; i++) { - ret = soc_register_ac97_dai_link(&card->rtd[i]); - if (ret < 0) { - dev_err(card->dev, - "ASoC: failed to register AC97: %d\n", ret); - while (--i >= 0) - soc_unregister_ac97_dai_link(&card->rtd[i]); - goto probe_aux_dev_err; - } - } -#endif + ret = snd_soc_ac97_register_dai_links(card); + if (ret < 0) + goto probe_aux_dev_err; card->instantiated = 1; snd_soc_dapm_sync(&card->dapm); @@ -1944,224 +1818,6 @@ static struct platform_driver soc_driver = { .remove = soc_remove, }; -static void soc_ac97_device_release(struct device *dev) -{ - kfree(to_ac97_t(dev)); -} - -/** - * snd_soc_new_ac97_codec - initailise AC97 device - * @codec: audio codec - * @ops: AC97 bus operations - * @num: AC97 codec number - * - * Initialises AC97 codec resources for use by ad-hoc devices only. - */ -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, - struct snd_ac97_bus_ops *ops, int num) -{ - codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); - if (codec->ac97 == NULL) - return -ENOMEM; - - codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL); - if (codec->ac97->bus == NULL) { - kfree(codec->ac97); - codec->ac97 = NULL; - return -ENOMEM; - } - - codec->ac97->bus->ops = ops; - codec->ac97->num = num; - codec->ac97->dev.release = soc_ac97_device_release; - - /* - * Mark the AC97 device to be created by us. This way we ensure that the - * device will be registered with the device subsystem later on. - */ - codec->ac97_created = 1; - device_initialize(&codec->ac97->dev); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); - -static struct snd_ac97_reset_cfg snd_ac97_rst_cfg; - -static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97) -{ - struct pinctrl *pctl = snd_ac97_rst_cfg.pctl; - - pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset); - - gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1); - - udelay(10); - - gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0); - - pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run); - msleep(2); -} - -static void snd_soc_ac97_reset(struct snd_ac97 *ac97) -{ - struct pinctrl *pctl = snd_ac97_rst_cfg.pctl; - - pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset); - - gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0); - gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0); - gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0); - - udelay(10); - - gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1); - - pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run); - msleep(2); -} - -static int snd_soc_ac97_parse_pinctl(struct device *dev, - struct snd_ac97_reset_cfg *cfg) -{ - struct pinctrl *p; - struct pinctrl_state *state; - int gpio; - int ret; - - p = devm_pinctrl_get(dev); - if (IS_ERR(p)) { - dev_err(dev, "Failed to get pinctrl\n"); - return PTR_ERR(p); - } - cfg->pctl = p; - - state = pinctrl_lookup_state(p, "ac97-reset"); - if (IS_ERR(state)) { - dev_err(dev, "Can't find pinctrl state ac97-reset\n"); - return PTR_ERR(state); - } - cfg->pstate_reset = state; - - state = pinctrl_lookup_state(p, "ac97-warm-reset"); - if (IS_ERR(state)) { - dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); - return PTR_ERR(state); - } - cfg->pstate_warm_reset = state; - - state = pinctrl_lookup_state(p, "ac97-running"); - if (IS_ERR(state)) { - dev_err(dev, "Can't find pinctrl state ac97-running\n"); - return PTR_ERR(state); - } - cfg->pstate_run = state; - - gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0); - if (gpio < 0) { - dev_err(dev, "Can't find ac97-sync gpio\n"); - return gpio; - } - ret = devm_gpio_request(dev, gpio, "AC97 link sync"); - if (ret) { - dev_err(dev, "Failed requesting ac97-sync gpio\n"); - return ret; - } - cfg->gpio_sync = gpio; - - gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1); - if (gpio < 0) { - dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio); - return gpio; - } - ret = devm_gpio_request(dev, gpio, "AC97 link sdata"); - if (ret) { - dev_err(dev, "Failed requesting ac97-sdata gpio\n"); - return ret; - } - cfg->gpio_sdata = gpio; - - gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2); - if (gpio < 0) { - dev_err(dev, "Can't find ac97-reset gpio\n"); - return gpio; - } - ret = devm_gpio_request(dev, gpio, "AC97 link reset"); - if (ret) { - dev_err(dev, "Failed requesting ac97-reset gpio\n"); - return ret; - } - cfg->gpio_reset = gpio; - - return 0; -} - -struct snd_ac97_bus_ops *soc_ac97_ops; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops) -{ - if (ops == soc_ac97_ops) - return 0; - - if (soc_ac97_ops && ops) - return -EBUSY; - - soc_ac97_ops = ops; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops); - -/** - * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions - * - * This function sets the reset and warm_reset properties of ops and parses - * the device node of pdev to get pinctrl states and gpio numbers to use. - */ -int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, - struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct snd_ac97_reset_cfg cfg; - int ret; - - ret = snd_soc_ac97_parse_pinctl(dev, &cfg); - if (ret) - return ret; - - ret = snd_soc_set_ac97_ops(ops); - if (ret) - return ret; - - ops->warm_reset = snd_soc_ac97_warm_reset; - ops->reset = snd_soc_ac97_reset; - - snd_ac97_rst_cfg = cfg; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset); - -/** - * snd_soc_free_ac97_codec - free AC97 codec device - * @codec: audio codec - * - * Frees AC97 codec device resources. - */ -void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) -{ -#ifdef CONFIG_SND_SOC_AC97_BUS - soc_unregister_ac97_codec(codec); -#endif - kfree(codec->ac97->bus); - codec->ac97->bus = NULL; - put_device(&codec->ac97->dev); - codec->ac97 = NULL; - codec->ac97_created = 0; -} -EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); - /** * snd_soc_cnew - create new control * @_template: control template -- GitLab From c2365ce5d5a0531f24ee488bf846acda4ecbe2aa Mon Sep 17 00:00:00 2001 From: Roman Byshko Date: Mon, 10 Nov 2014 21:53:32 +0100 Subject: [PATCH 5186/9457] usb: musb: replace hard coded registers with defines musb registers can be dumped using the file regdump which is created in debugfs. Up to now hard coded register addresses are used for that. Different glue layers however have different register addresses. The patch addresses this issue by substituting bare register addresses with defines. Signed-off-by: Roman Byshko Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_debugfs.c | 57 +++++++++++++++++---------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 4c216790e86b..ad3701a97389 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -49,33 +49,36 @@ struct musb_register_map { }; static const struct musb_register_map musb_regmap[] = { - { "FAddr", 0x00, 8 }, - { "Power", 0x01, 8 }, - { "Frame", 0x0c, 16 }, - { "Index", 0x0e, 8 }, - { "Testmode", 0x0f, 8 }, - { "TxMaxPp", 0x10, 16 }, - { "TxCSRp", 0x12, 16 }, - { "RxMaxPp", 0x14, 16 }, - { "RxCSR", 0x16, 16 }, - { "RxCount", 0x18, 16 }, - { "ConfigData", 0x1f, 8 }, - { "DevCtl", 0x60, 8 }, - { "MISC", 0x61, 8 }, - { "TxFIFOsz", 0x62, 8 }, - { "RxFIFOsz", 0x63, 8 }, - { "TxFIFOadd", 0x64, 16 }, - { "RxFIFOadd", 0x66, 16 }, - { "VControl", 0x68, 32 }, - { "HWVers", 0x6C, 16 }, - { "EPInfo", 0x78, 8 }, - { "RAMInfo", 0x79, 8 }, - { "LinkInfo", 0x7A, 8 }, - { "VPLen", 0x7B, 8 }, - { "HS_EOF1", 0x7C, 8 }, - { "FS_EOF1", 0x7D, 8 }, - { "LS_EOF1", 0x7E, 8 }, - { "SOFT_RST", 0x7F, 8 }, + { "FAddr", MUSB_FADDR, 8 }, + { "Power", MUSB_POWER, 8 }, + { "Frame", MUSB_FRAME, 16 }, + { "Index", MUSB_INDEX, 8 }, + { "Testmode", MUSB_TESTMODE, 8 }, + { "TxMaxPp", MUSB_TXMAXP, 16 }, + { "TxCSRp", MUSB_TXCSR, 16 }, + { "RxMaxPp", MUSB_RXMAXP, 16 }, + { "RxCSR", MUSB_RXCSR, 16 }, + { "RxCount", MUSB_RXCOUNT, 16 }, + { "ConfigData", MUSB_CONFIGDATA,8 }, + { "IntrRxE", MUSB_INTRRXE, 16 }, + { "IntrTxE", MUSB_INTRTXE, 16 }, + { "IntrUsbE", MUSB_INTRUSBE, 8 }, + { "DevCtl", MUSB_DEVCTL, 8 }, + { "BabbleCtl", MUSB_BABBLE_CTL,8 }, + { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, + { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, + { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, + { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, + { "VControl", 0x68, 32 }, + { "HWVers", 0x69, 16 }, + { "EPInfo", MUSB_EPINFO, 8 }, + { "RAMInfo", MUSB_RAMINFO, 8 }, + { "LinkInfo", MUSB_LINKINFO, 8 }, + { "VPLen", MUSB_VPLEN, 8 }, + { "HS_EOF1", MUSB_HS_EOF1, 8 }, + { "FS_EOF1", MUSB_FS_EOF1, 8 }, + { "LS_EOF1", MUSB_LS_EOF1, 8 }, + { "SOFT_RST", 0x7F, 8 }, { "DMA_CNTLch0", 0x204, 16 }, { "DMA_ADDRch0", 0x208, 32 }, { "DMA_COUNTch0", 0x20C, 32 }, -- GitLab From 1eec34e9f25664cf71e05321329d128e0565beae Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 13 Nov 2014 18:28:47 +0100 Subject: [PATCH 5187/9457] usb: musb: musb_cppi41: recognize HS devices in hostmode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a poll loop for max 25us for HS devices. Now guess what, I tested it in gadget mode and forgot about the little detail. Nobody seem to have it noticed… This patch adds the missing logic for hostmode so it is recognized in host and device mode properly. Fixes: 50aea6fca771 ("usb: musb: cppi41: fire hrtimer according to programmed channel length") Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_cppi41.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 5a9b977fbc19..f64fd964dc6d 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -253,6 +253,7 @@ static void cppi41_dma_callback(void *private_data) cppi41_trans_done(cppi41_channel); } else { struct cppi41_dma_controller *controller; + int is_hs = 0; /* * On AM335x it has been observed that the TX interrupt fires * too early that means the TXFIFO is not yet empty but the DMA @@ -265,7 +266,14 @@ static void cppi41_dma_callback(void *private_data) */ controller = cppi41_channel->controller; - if (musb->g.speed == USB_SPEED_HIGH) { + if (is_host_active(musb)) { + if (musb->port1_status & USB_PORT_STAT_HIGH_SPEED) + is_hs = 1; + } else { + if (musb->g.speed == USB_SPEED_HIGH) + is_hs = 1; + } + if (is_hs) { unsigned wait = 25; do { -- GitLab From eda1a701fd9589b6ed15b109558bd4f6202e3829 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:47 +0100 Subject: [PATCH 5188/9457] ASoC: ac97: Use static ac97_bus We always pass soc_ac97_ops to snd_soc_new_ac97_codec(). So instead of allocating a snd_ac97_bus in snd_soc_new_ac97_codec() just use a static one that gets initialized when snd_soc_set_ac97_ops() is called. Also drop the device number parameter from snd_soc_new_ac97_codec(). We currently only support one device per bus and all drivers pass 0 for the device number. And if we should ever support multiple devices per bus it wouldn't be up to individual AC'97 device drivers to pick their number, but rather either the AC'97 adapter driver or the core code will assign them. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- include/sound/soc.h | 3 +-- sound/soc/codecs/ad1980.c | 2 +- sound/soc/codecs/stac9766.c | 2 +- sound/soc/codecs/wm9705.c | 2 +- sound/soc/codecs/wm9712.c | 2 +- sound/soc/codecs/wm9713.c | 2 +- sound/soc/soc-ac97.c | 22 ++++++++-------------- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index adef34fa5209..44b3ce531fd6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -499,8 +499,7 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); #ifdef CONFIG_SND_SOC_AC97_BUS -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, - struct snd_ac97_bus_ops *ops, int num); +int snd_soc_new_ac97_codec(struct snd_soc_codec *codec); void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops); diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9ed4e12c26d1..f71cc21e67d4 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -220,7 +220,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) u16 vendor_id2; u16 ext_status; - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); + ret = snd_soc_new_ac97_codec(codec); if (ret < 0) { dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 53b810d23fea..45ac4a71ecff 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -336,7 +336,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) { int ret = 0; - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); + ret = snd_soc_new_ac97_codec(codec); if (ret < 0) goto codec_err; diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 1650195f6c84..2cb8a31819fa 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -337,7 +337,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) { int ret = 0; - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); + ret = snd_soc_new_ac97_codec(codec); if (ret < 0) { dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 3fad37e0d33d..6b36223fd247 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) { int ret = 0; - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); + ret = snd_soc_new_ac97_codec(codec); if (ret < 0) { dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 998e4c7b6b12..2071df707e88 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1219,7 +1219,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) { int ret = 0, reg; - ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); + ret = snd_soc_new_ac97_codec(codec); if (ret < 0) return ret; diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index da7b031a6eea..dbfca7e7dddb 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -38,6 +38,10 @@ struct snd_ac97_reset_cfg { int gpio_reset; }; +static struct snd_ac97_bus soc_ac97_bus = { + .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */ +}; + /* unregister ac97 codec */ static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) { @@ -140,27 +144,17 @@ static void soc_ac97_device_release(struct device *dev) /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec - * @ops: AC97 bus operations - * @num: AC97 codec number * * Initialises AC97 codec resources for use by ad-hoc devices only. */ -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, - struct snd_ac97_bus_ops *ops, int num) +int snd_soc_new_ac97_codec(struct snd_soc_codec *codec) { codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); if (codec->ac97 == NULL) return -ENOMEM; - codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL); - if (codec->ac97->bus == NULL) { - kfree(codec->ac97); - codec->ac97 = NULL; - return -ENOMEM; - } - - codec->ac97->bus->ops = ops; - codec->ac97->num = num; + codec->ac97->bus = &soc_ac97_bus; + codec->ac97->num = 0; codec->ac97->dev.release = soc_ac97_device_release; /* @@ -183,7 +177,6 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) { soc_unregister_ac97_codec(codec); - kfree(codec->ac97->bus); codec->ac97->bus = NULL; put_device(&codec->ac97->dev); codec->ac97 = NULL; @@ -314,6 +307,7 @@ int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops) return -EBUSY; soc_ac97_ops = ops; + soc_ac97_bus.ops = ops; return 0; } -- GitLab From bdfd60e3c0affb914549f1d22e8aeef71e7828e6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:48 +0100 Subject: [PATCH 5189/9457] ASoC: ac97: Merge soc_ac97_dev_{un,}register()/soc_{un,}register_ac97_codec() soc_{un,}register_ac97_codec() is just a simple wrapper around soc_ac97_dev_{un,}register(). There is no need to split these up into two different sets of functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-ac97.c | 80 +++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 50 deletions(-) diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index dbfca7e7dddb..b5d23c976662 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -42,18 +42,28 @@ static struct snd_ac97_bus soc_ac97_bus = { .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */ }; -/* unregister ac97 codec */ -static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) -{ - if (codec->ac97->dev.bus) - device_del(&codec->ac97->dev); - return 0; -} - /* register ac97 codec to bus */ -static int soc_ac97_dev_register(struct snd_soc_codec *codec) +static int soc_register_ac97_codec(struct snd_soc_codec *codec, + struct snd_soc_dai *codec_dai) { - int err; + int ret; + + /* Only instantiate AC97 if not already done by the adaptor + * for the generic AC97 subsystem. + */ + if (!codec_dai->driver->ac97_control || codec->ac97_registered) + return 0; + + /* + * It is possible that the AC97 device is already registered to + * the device subsystem. This happens when the device is created + * via snd_ac97_mixer(). Currently only SoC codec that does so + * is the generic AC97 glue but others migh emerge. + * + * In those cases we don't try to register the device again. + */ + if (!codec->ac97_created) + return 0; codec->ac97->dev.bus = &ac97_bus_type; codec->ac97->dev.parent = codec->component.card->dev; @@ -61,53 +71,23 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) dev_set_name(&codec->ac97->dev, "%d-%d:%s", codec->component.card->snd_card->number, 0, codec->component.name); - err = device_add(&codec->ac97->dev); - if (err < 0) { - dev_err(codec->dev, "ASoC: Can't register ac97 bus\n"); - codec->ac97->dev.bus = NULL; - return err; + ret = device_add(&codec->ac97->dev); + if (ret < 0) { + dev_err(codec->dev, "ASoC: AC97 device register failed: %d\n", + ret); + return ret; } - return 0; -} - -static int soc_register_ac97_codec(struct snd_soc_codec *codec, - struct snd_soc_dai *codec_dai) -{ - int ret; + codec->ac97_registered = 1; - /* Only instantiate AC97 if not already done by the adaptor - * for the generic AC97 subsystem. - */ - if (codec_dai->driver->ac97_control && !codec->ac97_registered) { - /* - * It is possible that the AC97 device is already registered to - * the device subsystem. This happens when the device is created - * via snd_ac97_mixer(). Currently only SoC codec that does so - * is the generic AC97 glue but others migh emerge. - * - * In those cases we don't try to register the device again. - */ - if (!codec->ac97_created) - return 0; - - ret = soc_ac97_dev_register(codec); - if (ret < 0) { - dev_err(codec->dev, - "ASoC: AC97 device register failed: %d\n", ret); - return ret; - } - - codec->ac97_registered = 1; - } return 0; } static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) { - if (codec->ac97_registered) { - soc_ac97_dev_unregister(codec); - codec->ac97_registered = 0; - } + if (!codec->ac97_registered) + return; + device_del(&codec->ac97->dev); + codec->ac97_registered = 0; } static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) -- GitLab From ca005f324ee38308b319c693f40523d959027acf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:49 +0100 Subject: [PATCH 5190/9457] ASoC: ac97: Drop support for setting platform data via the CPU DAI This has no users since commit f0fba2ad1b6b ("ASoC: multi-component - ASoC Multi-Component Support") which was almost 5 years ago. Given that this runs after CODEC probe functions have been run it also doesn't seem to be that useful. So drop it altogether to make the code simpler. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 1 - include/sound/soc.h | 3 --- sound/soc/soc-ac97.c | 12 ------------ sound/soc/soc-core.c | 2 -- 4 files changed, 18 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index e8b3080d196a..c0e04688c6ed 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -241,7 +241,6 @@ struct snd_soc_dai { const char *name; int id; struct device *dev; - void *ac97_pdata; /* platform_data for the ac97 codec */ /* driver ops */ struct snd_soc_dai_driver *driver; diff --git a/include/sound/soc.h b/include/sound/soc.h index 44b3ce531fd6..5b4dec693ca5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -509,7 +509,6 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, extern struct snd_ac97_bus_ops *soc_ac97_ops; int snd_soc_ac97_register_dai_links(struct snd_soc_card *card); -void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd); #else static inline int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) @@ -517,8 +516,6 @@ static inline int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) return 0; } -static inline void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd) {} - static inline int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct platform_device *pdev) { diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index b5d23c976662..f2ed77b5169a 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -342,15 +342,3 @@ int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) soc_unregister_ac97_dai_link(&card->rtd[i]); return ret; } - -void snd_soc_ac97_add_pdata(struct snd_soc_pcm_runtime *rtd) -{ - unsigned int i; - - /* add platform data for AC97 devices */ - for (i = 0; i < rtd->num_codecs; i++) { - if (rtd->codec_dais[i]->driver->ac97_control) - snd_ac97_dev_add_pdata(rtd->codec_dais[i]->codec->ac97, - rtd->cpu_dai->ac97_pdata); - } -} diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 026722f5ebf4..d883b4ad03ac 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1375,8 +1375,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } } - snd_soc_ac97_add_pdata(rtd); - return 0; } -- GitLab From 6794f709b7124ff1e574c4f4c9494418ab56c4b4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:50 +0100 Subject: [PATCH 5191/9457] ASoC: ac97: Drop delayed device registration We have all the information and dependencies we need to initialize and register the device available in snd_soc_new_ac97_codec(). So there is no need to delay the device registration until after the card itself as been registered. This makes the code significantly simpler and also makes it possible to use the AC'97 device in the CODECs probe function. The later will be required to be able to convert the AC'97 CODEC drivers to regmap. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 10 ---- sound/soc/soc-ac97.c | 118 +++++-------------------------------------- sound/soc/soc-core.c | 4 -- 3 files changed, 14 insertions(+), 118 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 5b4dec693ca5..206cc8d6eefa 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -507,15 +507,7 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct platform_device *pdev); extern struct snd_ac97_bus_ops *soc_ac97_ops; - -int snd_soc_ac97_register_dai_links(struct snd_soc_card *card); #else - -static inline int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) -{ - return 0; -} - static inline int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct platform_device *pdev) { @@ -808,8 +800,6 @@ struct snd_soc_codec { struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ unsigned int cache_bypass:1; /* Suppress access to the cache */ unsigned int suspended:1; /* Codec is in suspend PM state */ - unsigned int ac97_registered:1; /* Codec has been AC97 registered */ - unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int cache_init:1; /* codec cache has been initialized */ u32 cache_sync; /* Cache needs to be synced to hardware */ diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index f2ed77b5169a..920d76c43827 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -42,80 +42,6 @@ static struct snd_ac97_bus soc_ac97_bus = { .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */ }; -/* register ac97 codec to bus */ -static int soc_register_ac97_codec(struct snd_soc_codec *codec, - struct snd_soc_dai *codec_dai) -{ - int ret; - - /* Only instantiate AC97 if not already done by the adaptor - * for the generic AC97 subsystem. - */ - if (!codec_dai->driver->ac97_control || codec->ac97_registered) - return 0; - - /* - * It is possible that the AC97 device is already registered to - * the device subsystem. This happens when the device is created - * via snd_ac97_mixer(). Currently only SoC codec that does so - * is the generic AC97 glue but others migh emerge. - * - * In those cases we don't try to register the device again. - */ - if (!codec->ac97_created) - return 0; - - codec->ac97->dev.bus = &ac97_bus_type; - codec->ac97->dev.parent = codec->component.card->dev; - - dev_set_name(&codec->ac97->dev, "%d-%d:%s", - codec->component.card->snd_card->number, 0, - codec->component.name); - ret = device_add(&codec->ac97->dev); - if (ret < 0) { - dev_err(codec->dev, "ASoC: AC97 device register failed: %d\n", - ret); - return ret; - } - codec->ac97_registered = 1; - - return 0; -} - -static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) -{ - if (!codec->ac97_registered) - return; - device_del(&codec->ac97->dev); - codec->ac97_registered = 0; -} - -static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) -{ - int i, ret; - - for (i = 0; i < rtd->num_codecs; i++) { - struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; - - ret = soc_register_ac97_codec(codec_dai->codec, codec_dai); - if (ret) { - while (--i >= 0) - soc_unregister_ac97_codec(codec_dai->codec); - return ret; - } - } - - return 0; -} - -static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) -{ - int i; - - for (i = 0; i < rtd->num_codecs; i++) - soc_unregister_ac97_codec(rtd->codec_dais[i]->codec); -} - static void soc_ac97_device_release(struct device *dev) { kfree(to_ac97_t(dev)); @@ -129,22 +55,28 @@ static void soc_ac97_device_release(struct device *dev) */ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec) { + int ret; + codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); if (codec->ac97 == NULL) return -ENOMEM; codec->ac97->bus = &soc_ac97_bus; codec->ac97->num = 0; + + codec->ac97->dev.bus = &ac97_bus_type; + codec->ac97->dev.parent = codec->component.card->dev; codec->ac97->dev.release = soc_ac97_device_release; - /* - * Mark the AC97 device to be created by us. This way we ensure that the - * device will be registered with the device subsystem later on. - */ - codec->ac97_created = 1; - device_initialize(&codec->ac97->dev); + dev_set_name(&codec->ac97->dev, "%d-%d:%s", + codec->component.card->snd_card->number, 0, + codec->component.name); + + ret = device_register(&codec->ac97->dev); + if (ret) + put_device(&codec->ac97->dev); - return 0; + return ret; } EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); @@ -156,11 +88,10 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); */ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) { - soc_unregister_ac97_codec(codec); + device_del(&codec->ac97->dev); codec->ac97->bus = NULL; put_device(&codec->ac97->dev); codec->ac97 = NULL; - codec->ac97_created = 0; } EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); @@ -321,24 +252,3 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, return 0; } EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset); - -int snd_soc_ac97_register_dai_links(struct snd_soc_card *card) -{ - int i; - int ret; - - /* register any AC97 codecs */ - for (i = 0; i < card->num_rtd; i++) { - ret = soc_register_ac97_dai_link(&card->rtd[i]); - if (ret < 0) - goto err; - } - - return 0; -err: - dev_err(card->dev, - "ASoC: failed to register AC97: %d\n", ret); - while (--i >= 0) - soc_unregister_ac97_dai_link(&card->rtd[i]); - return ret; -} diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d883b4ad03ac..fba6e28e18d3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1671,10 +1671,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) goto probe_aux_dev_err; } - ret = snd_soc_ac97_register_dai_links(card); - if (ret < 0) - goto probe_aux_dev_err; - card->instantiated = 1; snd_soc_dapm_sync(&card->dapm); mutex_unlock(&card->mutex); -- GitLab From 4bafcf074aca3bd191e4d93c6a140ca52654f192 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:51 +0100 Subject: [PATCH 5192/9457] ASoC: Drop ac97_control initialization from CODEC driver DAIs This is no longer necessary as there is no code anymore that uses this for CODEC DAIs. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/ac97.c | 1 - sound/soc/codecs/ad1980.c | 1 - sound/soc/codecs/stac9766.c | 2 -- sound/soc/codecs/wm9705.c | 1 - sound/soc/codecs/wm9712.c | 1 - sound/soc/codecs/wm9713.c | 1 - 6 files changed, 7 deletions(-) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index bd9b1839c8b0..5d90924e8b96 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -53,7 +53,6 @@ static const struct snd_soc_dai_ops ac97_dai_ops = { static struct snd_soc_dai_driver ac97_dai = { .name = "ac97-hifi", - .ac97_control = 1, .playback = { .stream_name = "AC97 Playback", .channels_min = 1, diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index f71cc21e67d4..c6cb101a5b8f 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -170,7 +170,6 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, static struct snd_soc_dai_driver ad1980_dai = { .name = "ad1980-hifi", - .ac97_control = 1, .playback = { .stream_name = "Playback", .channels_min = 2, diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 45ac4a71ecff..c0808061b08a 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -294,7 +294,6 @@ static const struct snd_soc_dai_ops stac9766_dai_ops_digital = { static struct snd_soc_dai_driver stac9766_dai[] = { { .name = "stac9766-hifi-analog", - .ac97_control = 1, /* stream cababilities */ .playback = { @@ -316,7 +315,6 @@ static struct snd_soc_dai_driver stac9766_dai[] = { }, { .name = "stac9766-hifi-IEC958", - .ac97_control = 1, /* stream cababilities */ .playback = { diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 2cb8a31819fa..5b5118ba1526 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -263,7 +263,6 @@ static const struct snd_soc_dai_ops wm9705_dai_ops = { static struct snd_soc_dai_driver wm9705_dai[] = { { .name = "wm9705-hifi", - .ac97_control = 1, .playback = { .stream_name = "HiFi Playback", .channels_min = 1, diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 6b36223fd247..9fa794baa5f8 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -565,7 +565,6 @@ static const struct snd_soc_dai_ops wm9712_dai_ops_aux = { static struct snd_soc_dai_driver wm9712_dai[] = { { .name = "wm9712-hifi", - .ac97_control = 1, .playback = { .stream_name = "HiFi Playback", .channels_min = 1, diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2071df707e88..cd1b266d3af3 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1076,7 +1076,6 @@ static const struct snd_soc_dai_ops wm9713_dai_ops_voice = { static struct snd_soc_dai_driver wm9713_dai[] = { { .name = "wm9713-hifi", - .ac97_control = 1, .playback = { .stream_name = "HiFi Playback", .channels_min = 1, -- GitLab From bc2632140435cc84f9817f1c362479b23dbdfebc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:52 +0100 Subject: [PATCH 5193/9457] ASoC: Rename snd_soc_dai_driver struct ac97_control field to bus_control Setting the ac97_control field on a CPU DAI tells the ASoC core that this DAI in addition to audio data also transports control data to the CODEC. This causes the core to suspend the DAI after the CODEC and resume it before the CODEC so communication to the CODEC is still possible. This is not necessarily something that is specific to AC'97 and can be used by other buses with the same requirement. This patch renames the flag from ac97_control to bus_control to make this explicit. While we are at it also change the type from int to bool. The following semantich patch was used for automatic conversion of the drivers: // @@ identifier drv; @@ struct snd_soc_dai_driver drv = { - .ac97_control + .bus_control = - 1 + true }; // Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 3 ++- sound/soc/au1x/ac97c.c | 2 +- sound/soc/au1x/psc-ac97.c | 2 +- sound/soc/blackfin/bf5xx-ac97.c | 2 +- sound/soc/cirrus/ep93xx-ac97.c | 2 +- sound/soc/fsl/fsl_ssi.c | 2 +- sound/soc/fsl/imx-ssi.c | 2 +- sound/soc/fsl/mpc5200_psc_ac97.c | 4 ++-- sound/soc/nuc900/nuc900-ac97.c | 2 +- sound/soc/pxa/pxa2xx-ac97.c | 6 +++--- sound/soc/samsung/ac97.c | 4 ++-- sound/soc/sh/hac.c | 2 +- sound/soc/soc-core.c | 26 ++++++++++++++------------ sound/soc/tegra/tegra20_ac97.c | 2 +- sound/soc/txx9/txx9aclc-ac97.c | 2 +- 15 files changed, 33 insertions(+), 30 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index c0e04688c6ed..a3738be45563 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -206,7 +206,6 @@ struct snd_soc_dai_driver { /* DAI description */ const char *name; unsigned int id; - int ac97_control; unsigned int base; /* DAI driver callbacks */ @@ -216,6 +215,8 @@ struct snd_soc_dai_driver { int (*resume)(struct snd_soc_dai *dai); /* compress dai */ bool compress_dai; + /* DAI is also used for the control bus */ + bool bus_control; /* ops */ const struct snd_soc_dai_ops *ops; diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index c8a2de103c5f..5159a50a45a6 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -205,7 +205,7 @@ static int au1xac97c_dai_probe(struct snd_soc_dai *dai) static struct snd_soc_dai_driver au1xac97c_dai_driver = { .name = "alchemy-ac97c", - .ac97_control = 1, + .bus_control = true, .probe = au1xac97c_dai_probe, .playback = { .rates = AC97_RATES, diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 84f31e1f9d24..c6daec98ff89 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -343,7 +343,7 @@ static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { }; static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { - .ac97_control = 1, + .bus_control = true, .probe = au1xpsc_ac97_probe, .playback = { .rates = AC97_RATES, diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index e82eb373a731..6bf21a6c02e4 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -260,7 +260,7 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai) #endif static struct snd_soc_dai_driver bfin_ac97_dai = { - .ac97_control = 1, + .bus_control = true, .suspend = bf5xx_ac97_suspend, .resume = bf5xx_ac97_resume, .playback = { diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index f30dadf85b99..6b8a366b0211 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -338,7 +338,7 @@ static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { static struct snd_soc_dai_driver ep93xx_ac97_dai = { .name = "ep93xx-ac97", .id = 0, - .ac97_control = 1, + .bus_control = true, .probe = ep93xx_ac97_dai_probe, .playback = { .stream_name = "AC97 Playback", diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e6955170dc42..7fd3cbcd74c0 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1099,7 +1099,7 @@ static const struct snd_soc_component_driver fsl_ssi_component = { }; static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 Playback", .channels_min = 2, diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index ab2fdd76b693..60b0a5b1f1f1 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -382,7 +382,7 @@ static struct snd_soc_dai_driver imx_ssi_dai = { static struct snd_soc_dai_driver imx_ac97_dai = { .probe = imx_ssi_dai_probe, - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 Playback", .channels_min = 2, diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 640801a60c12..c6ed6ba965a9 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -237,7 +237,7 @@ static const struct snd_soc_dai_ops psc_ac97_digital_ops = { static struct snd_soc_dai_driver psc_ac97_dai[] = { { .name = "mpc5200-psc-ac97.0", - .ac97_control = 1, + .bus_control = true, .probe = psc_ac97_probe, .playback = { .stream_name = "AC97 Playback", @@ -257,7 +257,7 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = { }, { .name = "mpc5200-psc-ac97.1", - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 SPDIF", .channels_min = 1, diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index f2f67942b229..dff443e4b657 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -298,7 +298,7 @@ static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = { static struct snd_soc_dai_driver nuc900_ac97_dai = { .probe = nuc900_ac97_probe, .remove = nuc900_ac97_remove, - .ac97_control = 1, + .bus_control = true, .playback = { .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index ae956e3f4b9d..73ca2820c08c 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -157,7 +157,7 @@ static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { { .name = "pxa2xx-ac97", - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 Playback", .channels_min = 2, @@ -174,7 +174,7 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { }, { .name = "pxa2xx-ac97-aux", - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 Aux Playback", .channels_min = 1, @@ -191,7 +191,7 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { }, { .name = "pxa2xx-ac97-mic", - .ac97_control = 1, + .bus_control = true, .capture = { .stream_name = "AC97 Mic Capture", .channels_min = 1, diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index e1615113fd84..7952a625669d 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -288,7 +288,7 @@ static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "samsung-ac97", - .ac97_control = 1, + .bus_control = true, .playback = { .stream_name = "AC97 Playback", .channels_min = 2, @@ -306,7 +306,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { }, [S3C_AC97_DAI_MIC] = { .name = "samsung-ac97-mic", - .ac97_control = 1, + .bus_control = true, .capture = { .stream_name = "AC97 Mic Capture", .channels_min = 1, diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 0af2e4dfd139..d5f567e085ff 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -272,7 +272,7 @@ static const struct snd_soc_dai_ops hac_dai_ops = { static struct snd_soc_dai_driver sh4_hac_dai[] = { { .name = "hac-dai.0", - .ac97_control = 1, + .bus_control = true, .playback = { .rates = AC97_RATES, .formats = AC97_FMTS, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index fba6e28e18d3..f5bebca84b71 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -550,7 +550,7 @@ int snd_soc_suspend(struct device *dev) if (card->rtd[i].dai_link->ignore_suspend) continue; - if (cpu_dai->driver->suspend && !cpu_dai->driver->ac97_control) + if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control) cpu_dai->driver->suspend(cpu_dai); if (platform->driver->suspend && !platform->suspended) { platform->driver->suspend(cpu_dai); @@ -629,7 +629,7 @@ int snd_soc_suspend(struct device *dev) if (card->rtd[i].dai_link->ignore_suspend) continue; - if (cpu_dai->driver->suspend && cpu_dai->driver->ac97_control) + if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control) cpu_dai->driver->suspend(cpu_dai); /* deactivate pins to sleep state */ @@ -665,14 +665,14 @@ static void soc_resume_deferred(struct work_struct *work) if (card->resume_pre) card->resume_pre(card); - /* resume AC97 DAIs */ + /* resume control bus DAIs */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; if (card->rtd[i].dai_link->ignore_suspend) continue; - if (cpu_dai->driver->resume && cpu_dai->driver->ac97_control) + if (cpu_dai->driver->resume && cpu_dai->driver->bus_control) cpu_dai->driver->resume(cpu_dai); } @@ -733,7 +733,7 @@ static void soc_resume_deferred(struct work_struct *work) if (card->rtd[i].dai_link->ignore_suspend) continue; - if (cpu_dai->driver->resume && !cpu_dai->driver->ac97_control) + if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control) cpu_dai->driver->resume(cpu_dai); if (platform->driver->resume && platform->suspended) { platform->driver->resume(cpu_dai); @@ -758,7 +758,8 @@ static void soc_resume_deferred(struct work_struct *work) int snd_soc_resume(struct device *dev) { struct snd_soc_card *card = dev_get_drvdata(dev); - int i, ac97_control = 0; + bool bus_control = false; + int i; /* If the card is not initialized yet there is nothing to do */ if (!card->instantiated) @@ -781,17 +782,18 @@ int snd_soc_resume(struct device *dev) } } - /* AC97 devices might have other drivers hanging off them so - * need to resume immediately. Other drivers don't have that - * problem and may take a substantial amount of time to resume + /* + * DAIs that also act as the control bus master might have other drivers + * hanging off them so need to resume immediately. Other drivers don't + * have that problem and may take a substantial amount of time to resume * due to I/O costs and anti-pop so handle them out of line. */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; - ac97_control |= cpu_dai->driver->ac97_control; + bus_control |= cpu_dai->driver->bus_control; } - if (ac97_control) { - dev_dbg(dev, "ASoC: Resuming AC97 immediately\n"); + if (bus_control) { + dev_dbg(dev, "ASoC: Resuming control bus master immediately\n"); soc_resume_deferred(&card->deferred_resume_work); } else { dev_dbg(dev, "ASoC: Scheduling resume work\n"); diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 3b0fa12dbff7..29a9957d335a 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -228,7 +228,7 @@ static int tegra20_ac97_probe(struct snd_soc_dai *dai) static struct snd_soc_dai_driver tegra20_ac97_dai = { .name = "tegra-ac97-pcm", - .ac97_control = 1, + .bus_control = true, .probe = tegra20_ac97_probe, .playback = { .stream_name = "PCM Playback", diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 9edd68db9f48..f7135cdaa2ca 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -152,7 +152,7 @@ static int txx9aclc_ac97_remove(struct snd_soc_dai *dai) } static struct snd_soc_dai_driver txx9aclc_ac97_dai = { - .ac97_control = 1, + .bus_control = true, .probe = txx9aclc_ac97_probe, .remove = txx9aclc_ac97_remove, .playback = { -- GitLab From 358a8bb5628420529e4f0b77068155ca8fa8973b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Nov 2014 22:41:53 +0100 Subject: [PATCH 5194/9457] ASoC: ac97: Push snd_ac97 pointer to the driver level Now that the ASoC core no longer needs a handle to the AC'97 device that is associated with a CODEC we can remove it from the snd_soc_codec struct and push it into the individual driver state structs like we do for other communication buses. Doing so creates a clean separation between the AC'97 bus support and the ASoC core. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- include/sound/soc.h | 5 ++--- sound/soc/codecs/ac97.c | 17 ++++++++++++---- sound/soc/codecs/ad1980.c | 27 ++++++++++++++++--------- sound/soc/codecs/stac9766.c | 38 ++++++++++++++++++++++------------- sound/soc/codecs/wm9705.c | 31 +++++++++++++++++++--------- sound/soc/codecs/wm9712.c | 32 +++++++++++++++++++---------- sound/soc/codecs/wm9713.c | 31 ++++++++++++++++++---------- sound/soc/soc-ac97.c | 40 +++++++++++++++++++------------------ 8 files changed, 141 insertions(+), 80 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 206cc8d6eefa..9e513ae11749 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -499,8 +499,8 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); #ifdef CONFIG_SND_SOC_AC97_BUS -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec); -void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); +struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec); +void snd_soc_free_ac97_codec(struct snd_ac97 *ac97); int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops); int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, @@ -797,7 +797,6 @@ struct snd_soc_codec { struct list_head card_list; /* runtime */ - struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ unsigned int cache_bypass:1; /* Suppress access to the cache */ unsigned int suspended:1; /* Codec is in suspend PM state */ unsigned int cache_init:1; /* codec cache has been initialized */ diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 5d90924e8b96..c6e5a313ebf4 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -37,10 +37,11 @@ static int ac97_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; - return snd_ac97_set_rate(codec->ac97, reg, substream->runtime->rate); + return snd_ac97_set_rate(ac97, reg, substream->runtime->rate); } #define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ @@ -70,6 +71,7 @@ static struct snd_soc_dai_driver ac97_dai = { static int ac97_soc_probe(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97; struct snd_ac97_bus *ac97_bus; struct snd_ac97_template ac97_template; int ret; @@ -81,24 +83,31 @@ static int ac97_soc_probe(struct snd_soc_codec *codec) return ret; memset(&ac97_template, 0, sizeof(struct snd_ac97_template)); - ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97); + ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); if (ret < 0) return ret; + snd_soc_codec_set_drvdata(codec, ac97); + return 0; } #ifdef CONFIG_PM static int ac97_soc_suspend(struct snd_soc_codec *codec) { - snd_ac97_suspend(codec->ac97); + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + snd_ac97_suspend(ac97); return 0; } static int ac97_soc_resume(struct snd_soc_codec *codec) { - snd_ac97_resume(codec->ac97); + + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + snd_ac97_resume(ac97); return 0; } diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index c6cb101a5b8f..93bd47db6d0c 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -135,6 +135,7 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = { static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; switch (reg) { @@ -144,7 +145,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, case AC97_EXTENDED_STATUS: case AC97_VENDOR_ID1: case AC97_VENDOR_ID2: - return soc_ac97_ops->read(codec->ac97, reg); + return soc_ac97_ops->read(ac97, reg); default: reg = reg >> 1; @@ -158,9 +159,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(ac97, reg, val); reg = reg >> 1; if (reg < ARRAY_SIZE(ad1980_reg)) cache[reg] = val; @@ -186,16 +188,17 @@ static struct snd_soc_dai_driver ad1980_dai = { static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); unsigned int retry_cnt = 0; do { if (try_warm && soc_ac97_ops->warm_reset) { - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(ac97); if (ac97_read(codec, AC97_RESET) == 0x0090) return 1; } - soc_ac97_ops->reset(codec->ac97); + soc_ac97_ops->reset(ac97); /* * Set bit 16slot in register 74h, then every slot will has only * 16 bits. This command is sent out in 20bit mode, in which @@ -215,16 +218,20 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) static int ad1980_soc_probe(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97; int ret; u16 vendor_id2; u16 ext_status; - ret = snd_soc_new_ac97_codec(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to register AC97 codec\n"); + ac97 = snd_soc_new_ac97_codec(codec); + if (IS_ERR(ac97)) { + ret = PTR_ERR(ac97); + dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); return ret; } + snd_soc_codec_set_drvdata(codec, ac97); + ret = ad1980_reset(codec, 0); if (ret < 0) goto reset_err; @@ -261,13 +268,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) return 0; reset_err: - snd_soc_free_ac97_codec(codec); + snd_soc_free_ac97_codec(ac97); return ret; } static int ad1980_soc_remove(struct snd_soc_codec *codec) { - snd_soc_free_ac97_codec(codec); + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + snd_soc_free_ac97_codec(ac97); return 0; } diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index c0808061b08a..f37a79ec45e6 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -139,18 +139,19 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; if (reg > AC97_STAC_PAGE0) { stac9766_ac97_write(codec, AC97_INT_PAGING, 0); - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(ac97, reg, val); stac9766_ac97_write(codec, AC97_INT_PAGING, 1); return 0; } if (reg / 2 >= ARRAY_SIZE(stac9766_reg)) return -EIO; - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(ac97, reg, val); cache[reg / 2] = val; return 0; } @@ -158,11 +159,12 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, unsigned int reg) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 val = 0, *cache = codec->reg_cache; if (reg > AC97_STAC_PAGE0) { stac9766_ac97_write(codec, AC97_INT_PAGING, 0); - val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0); + val = soc_ac97_ops->read(ac97, reg - AC97_STAC_PAGE0); stac9766_ac97_write(codec, AC97_INT_PAGING, 1); return val; } @@ -173,7 +175,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2) { - val = soc_ac97_ops->read(codec->ac97, reg); + val = soc_ac97_ops->read(ac97, reg); return val; } return cache[reg / 2]; @@ -240,15 +242,17 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec, static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + if (try_warm && soc_ac97_ops->warm_reset) { - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(ac97); if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) return 1; } - soc_ac97_ops->reset(codec->ac97); + soc_ac97_ops->reset(ac97); if (soc_ac97_ops->warm_reset) - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(ac97); if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) return -EIO; return 0; @@ -262,6 +266,7 @@ static int stac9766_codec_suspend(struct snd_soc_codec *codec) static int stac9766_codec_resume(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 id, reset; reset = 0; @@ -271,8 +276,8 @@ static int stac9766_codec_resume(struct snd_soc_codec *codec) printk(KERN_ERR "stac9766 failed to resume"); return -EIO; } - codec->ac97->bus->ops->warm_reset(codec->ac97); - id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2); + ac97->bus->ops->warm_reset(ac97); + id = soc_ac97_ops->read(ac97, AC97_VENDOR_ID2); if (id != 0x4c13) { stac9766_reset(codec, 0); reset++; @@ -332,11 +337,14 @@ static struct snd_soc_dai_driver stac9766_dai[] = { static int stac9766_codec_probe(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97; int ret = 0; - ret = snd_soc_new_ac97_codec(codec); - if (ret < 0) - goto codec_err; + ac97 = snd_soc_new_ac97_codec(codec); + if (IS_ERR(ac97)) + return PTR_ERR(ac97); + + snd_soc_codec_set_drvdata(codec, ac97); /* do a cold reset for the controller and then try * a warm reset followed by an optional cold reset for codec */ @@ -355,13 +363,15 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) return 0; codec_err: - snd_soc_free_ac97_codec(codec); + snd_soc_free_ac97_codec(ac97); return ret; } static int stac9766_codec_remove(struct snd_soc_codec *codec) { - snd_soc_free_ac97_codec(codec); + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + snd_soc_free_ac97_codec(ac97); return 0; } diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 5b5118ba1526..d3a800fa6f06 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -203,13 +203,14 @@ static const struct snd_soc_dapm_route wm9705_audio_map[] = { /* We use a register cache to enhance read performance. */ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; switch (reg) { case AC97_RESET: case AC97_VENDOR_ID1: case AC97_VENDOR_ID2: - return soc_ac97_ops->read(codec->ac97, reg); + return soc_ac97_ops->read(ac97, reg); default: reg = reg >> 1; @@ -223,9 +224,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9705_reg))) cache[reg] = val; @@ -293,8 +295,10 @@ static struct snd_soc_dai_driver wm9705_dai[] = { static int wm9705_reset(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + if (soc_ac97_ops->reset) { - soc_ac97_ops->reset(codec->ac97); + soc_ac97_ops->reset(ac97); if (ac97_read(codec, 0) == wm9705_reg[0]) return 0; /* Success */ } @@ -307,13 +311,16 @@ static int wm9705_reset(struct snd_soc_codec *codec) #ifdef CONFIG_PM static int wm9705_soc_suspend(struct snd_soc_codec *codec) { - soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff); + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + soc_ac97_ops->write(ac97, AC97_POWERDOWN, 0xffff); return 0; } static int wm9705_soc_resume(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); int i, ret; u16 *cache = codec->reg_cache; @@ -322,7 +329,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec) return ret; for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { - soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); + soc_ac97_ops->write(ac97, i, cache[i>>1]); } return 0; @@ -334,14 +341,18 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec) static int wm9705_soc_probe(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97; int ret = 0; - ret = snd_soc_new_ac97_codec(codec); - if (ret < 0) { + ac97 = snd_soc_new_ac97_codec(codec); + if (IS_ERR(ac97)) { + ret = PTR_ERR(ac97); dev_err(codec->dev, "Failed to register AC97 codec\n"); return ret; } + snd_soc_codec_set_drvdata(codec, ac97); + ret = wm9705_reset(codec); if (ret) goto reset_err; @@ -349,13 +360,15 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) return 0; reset_err: - snd_soc_free_ac97_codec(codec); + snd_soc_free_ac97_codec(ac97); return ret; } static int wm9705_soc_remove(struct snd_soc_codec *codec) { - snd_soc_free_ac97_codec(codec); + struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + + snd_soc_free_ac97_codec(ac97); return 0; } diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 9fa794baa5f8..52a211be5b47 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -24,6 +24,7 @@ #include "wm9712.h" struct wm9712_priv { + struct snd_ac97 *ac97; unsigned int hp_mixer[2]; struct mutex lock; }; @@ -484,12 +485,13 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || reg == AC97_REC_GAIN) - return soc_ac97_ops->read(codec->ac97, reg); + return soc_ac97_ops->read(wm9712->ac97, reg); else { reg = reg >> 1; @@ -503,9 +505,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(wm9712->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; @@ -613,15 +616,17 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec, static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) { + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + if (try_warm && soc_ac97_ops->warm_reset) { - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(wm9712->ac97); if (ac97_read(codec, 0) == wm9712_reg[0]) return 1; } - soc_ac97_ops->reset(codec->ac97); + soc_ac97_ops->reset(wm9712->ac97); if (soc_ac97_ops->warm_reset) - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(wm9712->ac97); if (ac97_read(codec, 0) != wm9712_reg[0]) goto err; return 0; @@ -639,6 +644,7 @@ static int wm9712_soc_suspend(struct snd_soc_codec *codec) static int wm9712_soc_resume(struct snd_soc_codec *codec) { + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); int i, ret; u16 *cache = codec->reg_cache; @@ -654,7 +660,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || (i > 0x58 && i != 0x5c)) continue; - soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); + soc_ac97_ops->write(wm9712->ac97, i, cache[i>>1]); } } @@ -663,11 +669,13 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec) static int wm9712_soc_probe(struct snd_soc_codec *codec) { + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); int ret = 0; - ret = snd_soc_new_ac97_codec(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to register AC97 codec\n"); + wm9712->ac97 = snd_soc_new_ac97_codec(codec); + if (IS_ERR(wm9712->ac97)) { + ret = PTR_ERR(wm9712->ac97); + dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); return ret; } @@ -683,13 +691,15 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) return 0; reset_err: - snd_soc_free_ac97_codec(codec); + snd_soc_free_ac97_codec(wm9712->ac97); return ret; } static int wm9712_soc_remove(struct snd_soc_codec *codec) { - snd_soc_free_ac97_codec(codec); + struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); + + snd_soc_free_ac97_codec(wm9712->ac97); return 0; } diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index cd1b266d3af3..6c95d98b0eb1 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -30,6 +30,7 @@ #include "wm9713.h" struct wm9713_priv { + struct snd_ac97 *ac97; u32 pll_in; /* PLL input frequency */ unsigned int hp_mixer[2]; struct mutex lock; @@ -674,12 +675,13 @@ static const struct snd_soc_dapm_route wm9713_audio_map[] = { static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); u16 *cache = codec->reg_cache; if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || reg == AC97_CD) - return soc_ac97_ops->read(codec->ac97, reg); + return soc_ac97_ops->read(wm9713->ac97, reg); else { reg = reg >> 1; @@ -693,8 +695,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); + u16 *cache = codec->reg_cache; - soc_ac97_ops->write(codec->ac97, reg, val); + soc_ac97_ops->write(wm9713->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9713_reg))) cache[reg] = val; @@ -1121,15 +1125,17 @@ static struct snd_soc_dai_driver wm9713_dai[] = { int wm9713_reset(struct snd_soc_codec *codec, int try_warm) { + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); + if (try_warm && soc_ac97_ops->warm_reset) { - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(wm9713->ac97); if (ac97_read(codec, 0) == wm9713_reg[0]) return 1; } - soc_ac97_ops->reset(codec->ac97); + soc_ac97_ops->reset(wm9713->ac97); if (soc_ac97_ops->warm_reset) - soc_ac97_ops->warm_reset(codec->ac97); + soc_ac97_ops->warm_reset(wm9713->ac97); if (ac97_read(codec, 0) != wm9713_reg[0]) { dev_err(codec->dev, "Failed to reset: AC97 link error\n"); return -EIO; @@ -1207,7 +1213,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec) if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || i == AC97_EXTENDED_MSTATUS || i > 0x66) continue; - soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); + soc_ac97_ops->write(wm9713->ac97, i, cache[i>>1]); } } @@ -1216,11 +1222,12 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec) static int wm9713_soc_probe(struct snd_soc_codec *codec) { + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); int ret = 0, reg; - ret = snd_soc_new_ac97_codec(codec); - if (ret < 0) - return ret; + wm9713->ac97 = snd_soc_new_ac97_codec(codec); + if (IS_ERR(wm9713->ac97)) + return PTR_ERR(wm9713->ac97); /* do a cold reset for the controller and then try * a warm reset followed by an optional cold reset for codec */ @@ -1238,13 +1245,15 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) return 0; reset_err: - snd_soc_free_ac97_codec(codec); + snd_soc_free_ac97_codec(wm9713->ac97); return ret; } static int wm9713_soc_remove(struct snd_soc_codec *codec) { - snd_soc_free_ac97_codec(codec); + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); + + snd_soc_free_ac97_codec(wm9713->ac97); return 0; } diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 920d76c43827..2e10e9a38376 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -53,30 +53,33 @@ static void soc_ac97_device_release(struct device *dev) * * Initialises AC97 codec resources for use by ad-hoc devices only. */ -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec) +struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) { + struct snd_ac97 *ac97; int ret; - codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); - if (codec->ac97 == NULL) - return -ENOMEM; + ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); + if (ac97 == NULL) + return ERR_PTR(-ENOMEM); - codec->ac97->bus = &soc_ac97_bus; - codec->ac97->num = 0; + ac97->bus = &soc_ac97_bus; + ac97->num = 0; - codec->ac97->dev.bus = &ac97_bus_type; - codec->ac97->dev.parent = codec->component.card->dev; - codec->ac97->dev.release = soc_ac97_device_release; + ac97->dev.bus = &ac97_bus_type; + ac97->dev.parent = codec->component.card->dev; + ac97->dev.release = soc_ac97_device_release; - dev_set_name(&codec->ac97->dev, "%d-%d:%s", + dev_set_name(&ac97->dev, "%d-%d:%s", codec->component.card->snd_card->number, 0, codec->component.name); - ret = device_register(&codec->ac97->dev); - if (ret) - put_device(&codec->ac97->dev); + ret = device_register(&ac97->dev); + if (ret) { + put_device(&ac97->dev); + return ERR_PTR(ret); + } - return ret; + return ac97; } EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); @@ -86,12 +89,11 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); * * Frees AC97 codec device resources. */ -void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) +void snd_soc_free_ac97_codec(struct snd_ac97 *ac97) { - device_del(&codec->ac97->dev); - codec->ac97->bus = NULL; - put_device(&codec->ac97->dev); - codec->ac97 = NULL; + device_del(&ac97->dev); + ac97->bus = NULL; + put_device(&ac97->dev); } EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); -- GitLab From a5a267cf9ca9937b0ef946b502657ae7638282f6 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 18 Nov 2014 17:42:54 +0530 Subject: [PATCH 5195/9457] ASoC: rt286: build warning of section mismatch while building we were getting the following build warning: Section mismatch in reference from the function rt286_i2c_probe() to the variable .init.data:force_combo_jack_table The function rt286_i2c_probe() references the variable __initdata force_combo_jack_table. This is often because rt286_i2c_probe lacks a __initdata annotation or the annotation of force_combo_jack_table is wrong. we were getting the warning as force_combo_jack_table was marked with __initdata Signed-off-by: Sudip Mukherjee Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 2e818aaca550..2cd4fe463102 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1206,7 +1206,7 @@ static const struct acpi_device_id rt286_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); -static struct dmi_system_id force_combo_jack_table[] __initdata = { +static struct dmi_system_id force_combo_jack_table[] = { { .ident = "Intel Wilson Beach", .matches = { -- GitLab From f0c71718c2968a744f834b26423b9fb5e7d41a34 Mon Sep 17 00:00:00 2001 From: Julien CHAUVEAU Date: Tue, 18 Nov 2014 12:10:43 +0100 Subject: [PATCH 5196/9457] clk: rockchip: fix parent clock for rk3188 hclk_lcdc1 The parent clock for hclk_lcdc1 was set to aclk_cpu instead of hclk_cpu. Signed-off-by: Julien CHAUVEAU Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index f88eb7dacd97..e6cd4838cde5 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -410,7 +410,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* hclk_ahb2apb is part of a clk branch */ GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), - GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), + GATE(HCLK_LCDC1, "hclk_lcdc1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS), GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), -- GitLab From 139768895309c6c1d6913e909e9c9422f81a1640 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 18 Nov 2014 08:45:31 -0700 Subject: [PATCH 5197/9457] NVMe: enable IO stats by default Before the blk-mq conversion they were on by default, we should not change behavior there. Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index fb4b205317c6..677d7b9ff454 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1889,7 +1889,6 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, ns->queue); queue_flag_set_unlocked(QUEUE_FLAG_SG_GAPS, ns->queue); - queue_flag_clear_unlocked(QUEUE_FLAG_IO_STAT, ns->queue); ns->dev = dev; ns->queue->queuedata = ns; -- GitLab From f905bc68833b37b2274dc269fd35edb19e67aed7 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 14 Nov 2014 13:54:46 +0530 Subject: [PATCH 5198/9457] usb: musb: core: Disable the Interrupts till BABBLE is fully handled Disable the MUSB interrupts till MUSB is recovered fully from BABBLE condition. There are chances that we could get multiple interrupts till the time the babble recover work gets scheduled. Sometimes this could even end up in an endless loop making MUSB itself unusable. Reported-by: Felipe Balbi Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index f1dfe53515fb..5257928425ce 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -423,6 +423,7 @@ void musb_hnp_stop(struct musb *musb) musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16); } +static void musb_generic_disable(struct musb *musb); /* * Interrupt Service Routine to record USB "global" interrupts. * Since these do not happen often and signify things of @@ -846,9 +847,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } /* handle babble condition */ - if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) + if (int_usb & MUSB_INTR_BABBLE && is_host_active(musb)) { + musb_generic_disable(musb); schedule_delayed_work(&musb->recover_work, msecs_to_jiffies(100)); + } #if 0 /* REVISIT ... this would be for multiplexing periodic endpoints, or -- GitLab From d6d521799fac14e14dead4e9428158340ff6b95f Mon Sep 17 00:00:00 2001 From: JS Park Date: Tue, 18 Nov 2014 16:07:22 +0000 Subject: [PATCH 5199/9457] ASoC: wm_adsp: Fix memory leak in wm_adsp_setup_algs Signed-off-by: JS Park Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 0a08ef5e27c8..6a2a03570977 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1053,8 +1053,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp1_alg[i].zm)); region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP1_DM; region->alg = be32_to_cpu(adsp1_alg[i].alg.id); region->base = be32_to_cpu(adsp1_alg[i].dm); @@ -1071,8 +1073,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP1_ZM; region->alg = be32_to_cpu(adsp1_alg[i].alg.id); region->base = be32_to_cpu(adsp1_alg[i].zm); @@ -1101,8 +1105,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) be32_to_cpu(adsp2_alg[i].zm)); region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_XM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].xm); @@ -1119,8 +1125,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_YM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].ym); @@ -1137,8 +1145,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) } region = kzalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; + if (!region) { + ret = -ENOMEM; + goto out; + } region->type = WMFW_ADSP2_ZM; region->alg = be32_to_cpu(adsp2_alg[i].alg.id); region->base = be32_to_cpu(adsp2_alg[i].zm); -- GitLab From a0212ae0be5ba10b6e01b7121f86e391ae1927ae Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 14 Nov 2014 17:58:23 +1100 Subject: [PATCH 5200/9457] of/address: Don't throw errors on absent ranges properties The core always tries to translate any "reg" property to construct the platform device names. This results in a pile of "OF: no ranges; cannot translate" errors in dmesg whenever we expose things like i2c devices that cannot directly translate to the MMIO space. Turn this into a pr_debug instead Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely --- drivers/of/address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index e02828fa3acd..78f02f65fc48 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -477,7 +477,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, ranges = of_get_property(parent, rprop, &rlen); #if !defined(CONFIG_PPC) if (ranges == NULL) { - pr_err("OF: no ranges; cannot translate\n"); + pr_debug("OF: no ranges; cannot translate\n"); return 1; } #endif /* !defined(CONFIG_PPC) */ -- GitLab From 5f217f905bc5e9d609d0aac830736bcfc087c7f5 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 18 Nov 2014 23:59:40 +0900 Subject: [PATCH 5201/9457] ALSA: firewire-lib: fix kerneldoc errors Complete missing parameters, correct wrong reference, and add an explaination about the differences between the latest specification and our implementation. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/amdtp.h | 24 ++++++++++++++++++++++-- sound/firewire/cmp.c | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 4823c08196ac..e6e8926275b0 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -23,7 +23,7 @@ * corresponds to the end of event in the packet. Out of IEC 61883. * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. * The value of data_block_quadlets is used instead of reported value. - * @SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is + * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is * skipped for detecting discontinuity. * @CIP_SKIP_INIT_DBC_CHECK: Only for in-stream. The value of dbc in first * packet is not continuous from an initial value. @@ -43,7 +43,27 @@ enum cip_flags { }; /** - * enum cip_sfc - a stream's sample rate + * enum cip_sfc - supported Sampling Frequency Codes (SFCs) + * @CIP_SFC_32000: 32,000 data blocks + * @CIP_SFC_44100: 44,100 data blocks + * @CIP_SFC_48000: 48,000 data blocks + * @CIP_SFC_88200: 88,200 data blocks + * @CIP_SFC_96000: 96,000 data blocks + * @CIP_SFC_176400: 176,400 data blocks + * @CIP_SFC_192000: 192,000 data blocks + * @CIP_SFC_COUNT: the number of supported SFCs + * + * These values are used to show nominal Sampling Frequency Code in + * Format Dependent Field (FDF) of AMDTP packet header. In IEC 61883-6:2002, + * this code means the number of events per second. Actually the code + * represents the number of data blocks transferred per second in an AMDTP + * stream. + * + * In IEC 61883-6:2005, some extensions were added to support more types of + * data such as 'One Bit LInear Audio', therefore the meaning of SFC became + * different depending on the types. + * + * Currently our implementation is compatible with IEC 61883-6:2002. */ enum cip_sfc { CIP_SFC_32000 = 0, diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index ba8df5a1be39..ae3bc1940efa 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c @@ -114,6 +114,7 @@ static int pcr_modify(struct cmp_connection *c, * cmp_connection_init - initializes a connection manager * @c: the connection manager to initialize * @unit: a unit of the target device + * @direction: input or output * @pcr_index: the index of the iPCR/oPCR on the target device */ int cmp_connection_init(struct cmp_connection *c, @@ -154,6 +155,7 @@ EXPORT_SYMBOL(cmp_connection_init); /** * cmp_connection_check_used - check connection is already esablished or not * @c: the connection manager to be checked + * @used: the pointer to store the result of checking the connection */ int cmp_connection_check_used(struct cmp_connection *c, bool *used) { -- GitLab From b19556231156ce3e58ffd677747bf3ef7890a937 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 31 Oct 2014 14:10:14 +0100 Subject: [PATCH 5202/9457] s390/docs: Fix the documentation of the address spaces The information about the address spaces was completely outdated, since the usage of the address spaces changed quite a bit since the early days. This patch now updates the information about the usage of the address spaces, mostly by using the description from Heiko's patch "rework uaccess code - fix locking issues" (457f2180951cdcbfb4657ddcc83b486e93497f56). Signed-off-by: Thomas Huth Signed-off-by: Martin Schwidefsky --- Documentation/s390/Debugging390.txt | 88 ++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt index 462321c1aeea..2120eec48a5c 100644 --- a/Documentation/s390/Debugging390.txt +++ b/Documentation/s390/Debugging390.txt @@ -114,28 +114,25 @@ s/390 z/Architecture 16-17 16-17 Address Space Control - 00 Primary Space Mode when DAT on - The linux kernel currently runs in this mode, CR1 is affiliated with - this mode & points to the primary segment table origin etc. - - 01 Access register mode this mode is used in functions to - copy data between kernel & user space. - - 10 Secondary space mode not used in linux however CR7 the - register affiliated with this mode is & this & normally - CR13=CR7 to allow us to copy data between kernel & user space. - We do this as follows: - We set ar2 to 0 to designate its - affiliated gpr ( gpr2 )to point to primary=kernel space. - We set ar4 to 1 to designate its - affiliated gpr ( gpr4 ) to point to secondary=home=user space - & then essentially do a memcopy(gpr2,gpr4,size) to - copy data between the address spaces, the reason we use home space for the - kernel & don't keep secondary space free is that code will not run in - secondary space. - - 11 Home Space Mode all user programs run in this mode. - it is affiliated with CR13. + 00 Primary Space Mode: + The register CR1 contains the primary address-space control ele- + ment (PASCE), which points to the primary space region/segment + table origin. + + 01 Access register mode + + 10 Secondary Space Mode: + The register CR7 contains the secondary address-space control + element (SASCE), which points to the secondary space region or + segment table origin. + + 11 Home Space Mode: + The register CR13 contains the home space address-space control + element (HASCE), which points to the home space region/segment + table origin. + + See "Address Spaces on Linux for s/390 & z/Architecture" below + for more information about address space usage in Linux. 18-19 18-19 Condition codes (CC) @@ -249,9 +246,9 @@ currently 4TB of physical memory currently on z/Architecture. Address Spaces on Linux for s/390 & z/Architecture ================================================== -Our addressing scheme is as follows - +Our addressing scheme is basically as follows: + Primary Space Home Space Himem 0x7fffffff 2GB on s/390 ***************** **************** currently 0x3ffffffffff (2^42)-1 * User Stack * * * on z/Architecture. ***************** * * @@ -264,9 +261,46 @@ on z/Architecture. ***************** * * * Sections * * * 0x00000000 ***************** **************** -This also means that we need to look at the PSW problem state bit -or the addressing mode to decide whether we are looking at -user or kernel space. +This also means that we need to look at the PSW problem state bit and the +addressing mode to decide whether we are looking at user or kernel space. + +User space runs in primary address mode (or access register mode within +the vdso code). + +The kernel usually also runs in home space mode, however when accessing +user space the kernel switches to primary or secondary address mode if +the mvcos instruction is not available or if a compare-and-swap (futex) +instruction on a user space address is performed. + +When also looking at the ASCE control registers, this means: + +User space: +- runs in primary or access register mode +- cr1 contains the user asce +- cr7 contains the user asce +- cr13 contains the kernel asce + +Kernel space: +- runs in home space mode +- cr1 contains the user or kernel asce + -> the kernel asce is loaded when a uaccess requires primary or + secondary address mode +- cr7 contains the user or kernel asce, (changed with set_fs()) +- cr13 contains the kernel asce + +In case of uaccess the kernel changes to: +- primary space mode in case of a uaccess (copy_to_user) and uses + e.g. the mvcp instruction to access user space. However the kernel + will stay in home space mode if the mvcos instruction is available +- secondary space mode in case of futex atomic operations, so that the + instructions come from primary address space and data from secondary + space + +In case of KVM, the kernel runs in home space mode, but cr1 gets switched +to contain the gmap asce before the SIE instruction gets executed. When +the SIE instruction is finished, cr1 will be switched back to contain the +user asce. + Virtual Addresses on s/390 & z/Architecture =========================================== -- GitLab From a6b42afa3fc452339e157ad5245320804cf1206f Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 28 Oct 2014 15:12:23 +0100 Subject: [PATCH 5203/9457] s390/docs: Remove sections that are not related to s390 Information how to use the GCC pre-processor, objdump, strace, top, etc. are generic and not specific to the S390 architecture, so we do not need this information in Debugging390.txt Signed-off-by: Thomas Huth Signed-off-by: Martin Schwidefsky --- Documentation/s390/Debugging390.txt | 374 ---------------------------- 1 file changed, 374 deletions(-) diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt index 2120eec48a5c..08911b5c6b0e 100644 --- a/Documentation/s390/Debugging390.txt +++ b/Documentation/s390/Debugging390.txt @@ -26,11 +26,6 @@ The Linux for s/390 & z/Architecture Kernel Task Structure Register Usage & Stackframes on Linux for s/390 & z/Architecture A sample program with comments Compiling programs for debugging on Linux for s/390 & z/Architecture -Figuring out gcc compile errors -Debugging Tools -objdump -strace -Performance Debugging Debugging under VM s/390 & z/Architecture IO Overview Debugging IO on s/390 & z/Architecture under VM @@ -740,376 +735,7 @@ Debugging with optimisation has since much improved after fixing some bugs, please make sure you are using gdb-5.0 or later developed after Nov'2000. -Figuring out gcc compile errors -=============================== -If you are getting a lot of syntax errors compiling a program & the problem -isn't blatantly obvious from the source. -It often helps to just preprocess the file, this is done with the -E -option in gcc. -What this does is that it runs through the very first phase of compilation -( compilation in gcc is done in several stages & gcc calls many programs to -achieve its end result ) with the -E option gcc just calls the gcc preprocessor (cpp). -The c preprocessor does the following, it joins all the files #included together -recursively ( #include files can #include other files ) & also the c file you wish to compile. -It puts a fully qualified path of the #included files in a comment & it -does macro expansion. -This is useful for debugging because -1) You can double check whether the files you expect to be included are the ones -that are being included ( e.g. double check that you aren't going to the i386 asm directory ). -2) Check that macro definitions aren't clashing with typedefs, -3) Check that definitions aren't being used before they are being included. -4) Helps put the line emitting the error under the microscope if it contains macros. - -For convenience the Linux kernel's makefile will do preprocessing automatically for you -by suffixing the file you want built with .i ( instead of .o ) - -e.g. -from the linux directory type -make arch/s390/kernel/signal.i -this will build - -s390-gcc -D__KERNEL__ -I/home1/barrow/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer --fno-strict-aliasing -D__SMP__ -pipe -fno-strength-reduce -E arch/s390/kernel/signal.c -> arch/s390/kernel/signal.i - -Now look at signal.i you should see something like. - - -# 1 "/home1/barrow/linux/include/asm/types.h" 1 -typedef unsigned short umode_t; -typedef __signed__ char __s8; -typedef unsigned char __u8; -typedef __signed__ short __s16; -typedef unsigned short __u16; - -If instead you are getting errors further down e.g. -unknown instruction:2515 "move.l" or better still unknown instruction:2515 -"Fixme not implemented yet, call Martin" you are probably are attempting to compile some code -meant for another architecture or code that is simply not implemented, with a fixme statement -stuck into the inline assembly code so that the author of the file now knows he has work to do. -To look at the assembly emitted by gcc just before it is about to call gas ( the gnu assembler ) -use the -S option. -Again for your convenience the Linux kernel's Makefile will hold your hand & -do all this donkey work for you also by building the file with the .s suffix. -e.g. -from the Linux directory type -make arch/s390/kernel/signal.s - -s390-gcc -D__KERNEL__ -I/home1/barrow/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer --fno-strict-aliasing -D__SMP__ -pipe -fno-strength-reduce -S arch/s390/kernel/signal.c --o arch/s390/kernel/signal.s - - -This will output something like, ( please note the constant pool & the useful comments -in the prologue to give you a hand at interpreting it ). - -.LC54: - .string "misaligned (__u16 *) in __xchg\n" -.LC57: - .string "misaligned (__u32 *) in __xchg\n" -.L$PG1: # Pool sys_sigsuspend -.LC192: - .long -262401 -.LC193: - .long -1 -.LC194: - .long schedule-.L$PG1 -.LC195: - .long do_signal-.L$PG1 - .align 4 -.globl sys_sigsuspend - .type sys_sigsuspend,@function -sys_sigsuspend: -# leaf function 0 -# automatics 16 -# outgoing args 0 -# need frame pointer 0 -# call alloca 0 -# has varargs 0 -# incoming args (stack) 0 -# function length 168 - STM 8,15,32(15) - LR 0,15 - AHI 15,-112 - BASR 13,0 -.L$CO1: AHI 13,.L$PG1-.L$CO1 - ST 0,0(15) - LR 8,2 - N 5,.LC192-.L$PG1(13) - -Adding -g to the above output makes the output even more useful -e.g. typing -make CC:="s390-gcc -g" kernel/sched.s - -which compiles. -s390-gcc -g -D__KERNEL__ -I/home/barrow/linux-2.3/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -S kernel/sched.c -o kernel/sched.s - -also outputs stabs ( debugger ) info, from this info you can find out the -offsets & sizes of various elements in structures. -e.g. the stab for the structure -struct rlimit { - unsigned long rlim_cur; - unsigned long rlim_max; -}; -is -.stabs "rlimit:T(151,2)=s8rlim_cur:(0,5),0,32;rlim_max:(0,5),32,32;;",128,0,0,0 -from this stab you can see that -rlimit_cur starts at bit offset 0 & is 32 bits in size -rlimit_max starts at bit offset 32 & is 32 bits in size. - - -Debugging Tools: -================ - -objdump -======= -This is a tool with many options the most useful being ( if compiled with -g). -objdump --source > - - -The whole kernel can be compiled like this ( Doing this will make a 17MB kernel -& a 200 MB listing ) however you have to strip it before building the image -using the strip command to make it a more reasonable size to boot it. - -A source/assembly mixed dump of the kernel can be done with the line -objdump --source vmlinux > vmlinux.lst -Also, if the file isn't compiled -g, this will output as much debugging information -as it can (e.g. function names). This is very slow as it spends lots -of time searching for debugging info. The following self explanatory line should be used -instead if the code isn't compiled -g, as it is much faster: -objdump --disassemble-all --syms vmlinux > vmlinux.lst - -As hard drive space is valuable most of us use the following approach. -1) Look at the emitted psw on the console to find the crash address in the kernel. -2) Look at the file System.map ( in the linux directory ) produced when building -the kernel to find the closest address less than the current PSW to find the -offending function. -3) use grep or similar to search the source tree looking for the source file - with this function if you don't know where it is. -4) rebuild this object file with -g on, as an example suppose the file was -( /arch/s390/kernel/signal.o ) -5) Assuming the file with the erroneous function is signal.c Move to the base of the -Linux source tree. -6) rm /arch/s390/kernel/signal.o -7) make /arch/s390/kernel/signal.o -8) watch the gcc command line emitted -9) type it in again or alternatively cut & paste it on the console adding the -g option. -10) objdump --source arch/s390/kernel/signal.o > signal.lst -This will output the source & the assembly intermixed, as the snippet below shows -This will unfortunately output addresses which aren't the same -as the kernel ones you should be able to get around the mental arithmetic -by playing with the --adjust-vma parameter to objdump. - - - - -static inline void spin_lock(spinlock_t *lp) -{ - a0: 18 34 lr %r3,%r4 - a2: a7 3a 03 bc ahi %r3,956 - __asm__ __volatile(" lhi 1,-1\n" - a6: a7 18 ff ff lhi %r1,-1 - aa: 1f 00 slr %r0,%r0 - ac: ba 01 30 00 cs %r0,%r1,0(%r3) - b0: a7 44 ff fd jm aa - saveset = current->blocked; - b4: d2 07 f0 68 mvc 104(8,%r15),972(%r4) - b8: 43 cc - return (set->sig[0] & mask) != 0; -} - -6) If debugging under VM go down to that section in the document for more info. - - -I now have a tool which takes the pain out of --adjust-vma -& you are able to do something like -make /arch/s390/kernel/traps.lst -& it automatically generates the correctly relocated entries for -the text segment in traps.lst. -This tool is now standard in linux distro's in scripts/makelst - -strace: -------- -Q. What is it ? -A. It is a tool for intercepting calls to the kernel & logging them -to a file & on the screen. - -Q. What use is it ? -A. You can use it to find out what files a particular program opens. - - - -Example 1 ---------- -If you wanted to know does ping work but didn't have the source -strace ping -c 1 127.0.0.1 -& then look at the man pages for each of the syscalls below, -( In fact this is sometimes easier than looking at some spaghetti -source which conditionally compiles for several architectures ). -Not everything that it throws out needs to make sense immediately. - -Just looking quickly you can see that it is making up a RAW socket -for the ICMP protocol. -Doing an alarm(10) for a 10 second timeout -& doing a gettimeofday call before & after each read to see -how long the replies took, & writing some text to stdout so the user -has an idea what is going on. - -socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3 -getuid() = 0 -setuid(0) = 0 -stat("/usr/share/locale/C/libc.cat", 0xbffff134) = -1 ENOENT (No such file or directory) -stat("/usr/share/locale/libc/C", 0xbffff134) = -1 ENOENT (No such file or directory) -stat("/usr/local/share/locale/C/libc.cat", 0xbffff134) = -1 ENOENT (No such file or directory) -getpid() = 353 -setsockopt(3, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0 -setsockopt(3, SOL_SOCKET, SO_RCVBUF, [49152], 4) = 0 -fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(3, 1), ...}) = 0 -mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40008000 -ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0 -write(1, "PING 127.0.0.1 (127.0.0.1): 56 d"..., 42PING 127.0.0.1 (127.0.0.1): 56 data bytes -) = 42 -sigaction(SIGINT, {0x8049ba0, [], SA_RESTART}, {SIG_DFL}) = 0 -sigaction(SIGALRM, {0x8049600, [], SA_RESTART}, {SIG_DFL}) = 0 -gettimeofday({948904719, 138951}, NULL) = 0 -sendto(3, "\10\0D\201a\1\0\0\17#\2178\307\36"..., 64, 0, {sin_family=AF_INET, -sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 64 -sigaction(SIGALRM, {0x8049600, [], SA_RESTART}, {0x8049600, [], SA_RESTART}) = 0 -sigaction(SIGALRM, {0x8049ba0, [], SA_RESTART}, {0x8049600, [], SA_RESTART}) = 0 -alarm(10) = 0 -recvfrom(3, "E\0\0T\0005\0\0@\1|r\177\0\0\1\177"..., 192, 0, -{sin_family=AF_INET, sin_port=htons(50882), sin_addr=inet_addr("127.0.0.1")}, [16]) = 84 -gettimeofday({948904719, 160224}, NULL) = 0 -recvfrom(3, "E\0\0T\0006\0\0\377\1\275p\177\0"..., 192, 0, -{sin_family=AF_INET, sin_port=htons(50882), sin_addr=inet_addr("127.0.0.1")}, [16]) = 84 -gettimeofday({948904719, 166952}, NULL) = 0 -write(1, "64 bytes from 127.0.0.1: icmp_se"..., -5764 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=28.0 ms - -Example 2 ---------- -strace passwd 2>&1 | grep open -produces the following output -open("/etc/ld.so.cache", O_RDONLY) = 3 -open("/opt/kde/lib/libc.so.5", O_RDONLY) = -1 ENOENT (No such file or directory) -open("/lib/libc.so.5", O_RDONLY) = 3 -open("/dev", O_RDONLY) = 3 -open("/var/run/utmp", O_RDONLY) = 3 -open("/etc/passwd", O_RDONLY) = 3 -open("/etc/shadow", O_RDONLY) = 3 -open("/etc/login.defs", O_RDONLY) = 4 -open("/dev/tty", O_RDONLY) = 4 - -The 2>&1 is done to redirect stderr to stdout & grep is then filtering this input -through the pipe for each line containing the string open. - - -Example 3 ---------- -Getting sophisticated -telnetd crashes & I don't know why - -Steps ------ -1) Replace the following line in /etc/inetd.conf -telnet stream tcp nowait root /usr/sbin/in.telnetd -h -with -telnet stream tcp nowait root /blah - -2) Create the file /blah with the following contents to start tracing telnetd -#!/bin/bash -/usr/bin/strace -o/t1 -f /usr/sbin/in.telnetd -h -3) chmod 700 /blah to make it executable only to root -4) -killall -HUP inetd -or ps aux | grep inetd -get inetd's process id -& kill -HUP inetd to restart it. - -Important options ------------------ --o is used to tell strace to output to a file in our case t1 in the root directory --f is to follow children i.e. -e.g in our case above telnetd will start the login process & subsequently a shell like bash. -You will be able to tell which is which from the process ID's listed on the left hand side -of the strace output. --p will tell strace to attach to a running process, yup this can be done provided - it isn't being traced or debugged already & you have enough privileges, -the reason 2 processes cannot trace or debug the same program is that strace -becomes the parent process of the one being debugged & processes ( unlike people ) -can have only one parent. - - -However the file /t1 will get big quite quickly -to test it telnet 127.0.0.1 - -now look at what files in.telnetd execve'd -413 execve("/usr/sbin/in.telnetd", ["/usr/sbin/in.telnetd", "-h"], [/* 17 vars */]) = 0 -414 execve("/bin/login", ["/bin/login", "-h", "localhost", "-p"], [/* 2 vars */]) = 0 -Whey it worked!. - - -Other hints: ------------- -If the program is not very interactive ( i.e. not much keyboard input ) -& is crashing in one architecture but not in another you can do -an strace of both programs under as identical a scenario as you can -on both architectures outputting to a file then. -do a diff of the two traces using the diff program -i.e. -diff output1 output2 -& maybe you'll be able to see where the call paths differed, this -is possibly near the cause of the crash. - -More info ---------- -Look at man pages for strace & the various syscalls -e.g. man strace, man alarm, man socket. - - -Performance Debugging -===================== -gcc is capable of compiling in profiling code just add the -p option -to the CFLAGS, this obviously affects program size & performance. -This can be used by the gprof gnu profiling tool or the -gcov the gnu code coverage tool ( code coverage is a means of testing -code quality by checking if all the code in an executable in exercised by -a tester ). - - -Using top to find out where processes are sleeping in the kernel ----------------------------------------------------------------- -To do this copy the System.map from the root directory where -the linux kernel was built to the /boot directory on your -linux machine. -Start top -Now type fU -You should see a new field called WCHAN which -tells you where each process is sleeping here is a typical output. - - 6:59pm up 41 min, 1 user, load average: 0.00, 0.00, 0.00 -28 processes: 27 sleeping, 1 running, 0 zombie, 0 stopped -CPU states: 0.0% user, 0.1% system, 0.0% nice, 99.8% idle -Mem: 254900K av, 45976K used, 208924K free, 0K shrd, 28636K buff -Swap: 0K av, 0K used, 0K free 8620K cached - - PID USER PRI NI SIZE RSS SHARE WCHAN STAT LIB %CPU %MEM TIME COMMAND - 750 root 12 0 848 848 700 do_select S 0 0.1 0.3 0:00 in.telnetd - 767 root 16 0 1140 1140 964 R 0 0.1 0.4 0:00 top - 1 root 8 0 212 212 180 do_select S 0 0.0 0.0 0:00 init - 2 root 9 0 0 0 0 down_inte SW 0 0.0 0.0 0:00 kmcheck - -The time command ----------------- -Another related command is the time command which gives you an indication -of where a process is spending the majority of its time. -e.g. -time ping -c 5 nc -outputs -real 0m4.054s -user 0m0.010s -sys 0m0.010s Debugging under VM ================== -- GitLab From 99e97b7106d492a3cac4f7963f4a89935d2fbca4 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 6 Nov 2014 13:17:06 +0100 Subject: [PATCH 5204/9457] s390/io: add ioport_map stubs add ioport_map stubs to make vfio build on s390. Signed-off-by: Frank Blaschka Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/io.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index cd6b9ee7b69c..ba516f8f918a 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -38,6 +38,15 @@ static inline void iounmap(volatile void __iomem *addr) { } +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return NULL; +} + +static inline void ioport_unmap(void __iomem *p) +{ +} + /* * s390 needs a private implementation of pci_iomap since ioremap with its * offset parameter isn't sufficient. That's because BAR spaces are not -- GitLab From afaa7d29bc04bf0fcf2e7bda2a802392a38d059b Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 14 Nov 2014 11:01:37 +0100 Subject: [PATCH 5205/9457] s390/irq: use irq 0 Irq 0 is currently unused on s390. Since there is no reason to do this start counting at the beginning and gain an additional irq. Also correctly report the smallest usable irq number for dynamic allocation. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/irq.h | 11 ++++------- arch/s390/kernel/irq.c | 5 +---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index b0d5f0a97a01..343ea7c987aa 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -1,11 +1,11 @@ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H -#define EXT_INTERRUPT 1 -#define IO_INTERRUPT 2 -#define THIN_INTERRUPT 3 +#define EXT_INTERRUPT 0 +#define IO_INTERRUPT 1 +#define THIN_INTERRUPT 2 -#define NR_IRQS_BASE 4 +#define NR_IRQS_BASE 3 #ifdef CONFIG_PCI_NR_MSI # define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI) @@ -13,9 +13,6 @@ # define NR_IRQS NR_IRQS_BASE #endif -/* This number is used when no interrupt has been assigned */ -#define NO_IRQ 0 - /* External interruption codes */ #define EXT_IRQ_INTERRUPT_KEY 0x0040 #define EXT_IRQ_CLK_COMP 0x1004 diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 1b8a38ab7861..f238720690f3 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -127,13 +127,10 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(cpu) seq_printf(p, "CPU%d ", cpu); seq_putc(p, '\n'); - goto out; } if (index < NR_IRQS) { if (index >= NR_IRQS_BASE) goto out; - /* Adjust index to process irqclass_main_desc array entries */ - index--; seq_printf(p, "%s: ", irqclass_main_desc[index].name); irq = irqclass_main_desc[index].irq; for_each_online_cpu(cpu) @@ -158,7 +155,7 @@ int show_interrupts(struct seq_file *p, void *v) unsigned int arch_dynirq_lower_bound(unsigned int from) { - return from < THIN_INTERRUPT ? THIN_INTERRUPT : from; + return from < NR_IRQS_BASE ? NR_IRQS_BASE : from; } /* -- GitLab From 00e4c3b6e285da90e736fbefff3d9e74a200ee54 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Nov 2014 16:25:27 +0000 Subject: [PATCH 5206/9457] ASoC: wm_adsp: Move core_ena to be co-located with start bit Many firmwares do not wait for the start bit before they begin processing audio, whilst this is a bug on the firmware side there are too many such firmwares in the wild to ignore the situation. This patch moves the core enable to happen at same time as the start, the firmware looses the ability to overlap its own startup with the audio path bring up but we ensure that all firmwares behave. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 67124783558a..cce9020933c6 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1595,13 +1595,6 @@ static void wm_adsp2_boot_work(struct work_struct *work) if (ret != 0) goto err; - ret = regmap_update_bits_async(dsp->regmap, - dsp->base + ADSP2_CONTROL, - ADSP2_CORE_ENA, - ADSP2_CORE_ENA); - if (ret != 0) - goto err; - dsp->running = true; return; @@ -1651,8 +1644,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_START, - ADSP2_START); + ADSP2_CORE_ENA | ADSP2_START, + ADSP2_CORE_ENA | ADSP2_START); if (ret != 0) goto err; break; -- GitLab From 25c7a1de6c4b9f9eb867af4dc9215bbf9e08ef2e Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 12 Nov 2014 12:54:00 -0800 Subject: [PATCH 5207/9457] of: Fix of_device_is_compatible() comment This function passes back a value from __of_device_is_compatible(), which returns a score in the range 0..11, not a bool. Signed-off-by: Kevin Cernekee Signed-off-by: Grant Likely --- drivers/of/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 6137f18d4244..4627e0acf4ad 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -500,7 +500,7 @@ EXPORT_SYMBOL(of_device_is_compatible); * of_machine_is_compatible - Test root of device tree for a given compatible value * @compat: compatible string to look for in root node's compatible property. * - * Returns true if the root node has the given value in its + * Returns a positive integer if the root node has the given value in its * compatible property. */ int of_machine_is_compatible(const char *compat) -- GitLab From 53a4ab96c61a34d62717b1481f6043e0b4338d74 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 12 Nov 2014 12:54:01 -0800 Subject: [PATCH 5208/9457] of: Change of_device_is_available() to return bool This function can only return true or false; using a bool makes it more obvious to the reader. Signed-off-by: Kevin Cernekee Signed-off-by: Grant Likely --- drivers/of/base.c | 22 +++++++++++----------- include/linux/of.h | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 4627e0acf4ad..2d5dfb8b2e65 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -522,27 +522,27 @@ EXPORT_SYMBOL(of_machine_is_compatible); * * @device: Node to check for availability, with locks already held * - * Returns 1 if the status property is absent or set to "okay" or "ok", - * 0 otherwise + * Returns true if the status property is absent or set to "okay" or "ok", + * false otherwise */ -static int __of_device_is_available(const struct device_node *device) +static bool __of_device_is_available(const struct device_node *device) { const char *status; int statlen; if (!device) - return 0; + return false; status = __of_get_property(device, "status", &statlen); if (status == NULL) - return 1; + return true; if (statlen > 0) { if (!strcmp(status, "okay") || !strcmp(status, "ok")) - return 1; + return true; } - return 0; + return false; } /** @@ -550,13 +550,13 @@ static int __of_device_is_available(const struct device_node *device) * * @device: Node to check for availability * - * Returns 1 if the status property is absent or set to "okay" or "ok", - * 0 otherwise + * Returns true if the status property is absent or set to "okay" or "ok", + * false otherwise */ -int of_device_is_available(const struct device_node *device) +bool of_device_is_available(const struct device_node *device) { unsigned long flags; - int res; + bool res; raw_spin_lock_irqsave(&devtree_lock, flags); res = __of_device_is_available(device); diff --git a/include/linux/of.h b/include/linux/of.h index 3c851a8f23eb..27635c89d8c2 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -276,7 +276,7 @@ extern int of_property_read_string_helper(struct device_node *np, const char **out_strs, size_t sz, int index); extern int of_device_is_compatible(const struct device_node *device, const char *); -extern int of_device_is_available(const struct device_node *device); +extern bool of_device_is_available(const struct device_node *device); extern const void *of_get_property(const struct device_node *node, const char *name, int *lenp); @@ -427,9 +427,9 @@ static inline int of_device_is_compatible(const struct device_node *device, return 0; } -static inline int of_device_is_available(const struct device_node *device) +static inline bool of_device_is_available(const struct device_node *device) { - return 0; + return false; } static inline struct property *of_find_property(const struct device_node *np, -- GitLab From cadaecd2188b99d93de676150007f0e097223232 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 17 Nov 2014 23:07:41 +0300 Subject: [PATCH 5209/9457] PPC: bpf_jit_comp: Unify BPF_MOD | BPF_X and BPF_DIV | BPF_X Reduce duplicated code by unifying BPF_ALU | BPF_MOD | BPF_X and BPF_ALU | BPF_DIV | BPF_X CC: Alexei Starovoitov CC: Daniel Borkmann CC: Philippe Bergheaud Signed-off-by: Denis Kirjanov Acked-by: Alexei Starovoitov Signed-off-by: David S. Miller --- arch/powerpc/net/bpf_jit_comp.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index d3fa80d04e6b..1ca125b9c226 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -181,6 +181,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, } break; case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */ + case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */ ctx->seen |= SEEN_XREG; PPC_CMPWI(r_X, 0); if (ctx->pc_ret0 != -1) { @@ -190,9 +191,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_LI(r_ret, 0); PPC_JMP(exit_addr); } - PPC_DIVWU(r_scratch1, r_A, r_X); - PPC_MUL(r_scratch1, r_X, r_scratch1); - PPC_SUB(r_A, r_A, r_scratch1); + if (code == (BPF_ALU | BPF_MOD | BPF_X)) { + PPC_DIVWU(r_scratch1, r_A, r_X); + PPC_MUL(r_scratch1, r_X, r_scratch1); + PPC_SUB(r_A, r_A, r_scratch1); + } else { + PPC_DIVWU(r_A, r_A, r_X); + } break; case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */ PPC_LI32(r_scratch2, K); @@ -200,22 +205,6 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_MUL(r_scratch1, r_scratch2, r_scratch1); PPC_SUB(r_A, r_A, r_scratch1); break; - case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */ - ctx->seen |= SEEN_XREG; - PPC_CMPWI(r_X, 0); - if (ctx->pc_ret0 != -1) { - PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); - } else { - /* - * Exit, returning 0; first pass hits here - * (longer worst-case code size). - */ - PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); - PPC_LI(r_ret, 0); - PPC_JMP(exit_addr); - } - PPC_DIVWU(r_A, r_A, r_X); - break; case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */ if (K == 1) break; -- GitLab From 3274f52073d88b62f3c5ace82ae9d48546232e72 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:44 -0800 Subject: [PATCH 5210/9457] bpf: add 'flags' attribute to BPF_MAP_UPDATE_ELEM command the current meaning of BPF_MAP_UPDATE_ELEM syscall command is: either update existing map element or create a new one. Initially the plan was to add a new command to handle the case of 'create new element if it didn't exist', but 'flags' style looks cleaner and overall diff is much smaller (more code reused), so add 'flags' attribute to BPF_MAP_UPDATE_ELEM command with the following meaning: #define BPF_ANY 0 /* create new element or update existing */ #define BPF_NOEXIST 1 /* create new element if it didn't exist */ #define BPF_EXIST 2 /* update existing element */ bpf_update_elem(fd, key, value, BPF_NOEXIST) call can fail with EEXIST if element already exists. bpf_update_elem(fd, key, value, BPF_EXIST) can fail with ENOENT if element doesn't exist. Userspace will call it as: int bpf_update_elem(int fd, void *key, void *value, __u64 flags) { union bpf_attr attr = { .map_fd = fd, .key = ptr_to_u64(key), .value = ptr_to_u64(value), .flags = flags; }; return bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); } First two bits of 'flags' are used to encode style of bpf_update_elem() command. Bits 2-63 are reserved for future use. Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- include/linux/bpf.h | 2 +- include/uapi/linux/bpf.h | 8 +++++++- kernel/bpf/syscall.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 3cf91754a957..51e9242e4803 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -22,7 +22,7 @@ struct bpf_map_ops { /* funcs callable from userspace and from eBPF programs */ void *(*map_lookup_elem)(struct bpf_map *map, void *key); - int (*map_update_elem)(struct bpf_map *map, void *key, void *value); + int (*map_update_elem)(struct bpf_map *map, void *key, void *value, u64 flags); int (*map_delete_elem)(struct bpf_map *map, void *key); }; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index d18316f9e9c4..3e9e1b77f29d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -82,7 +82,7 @@ enum bpf_cmd { /* create or update key/value pair in a given map * err = bpf(BPF_MAP_UPDATE_ELEM, union bpf_attr *attr, u32 size) - * Using attr->map_fd, attr->key, attr->value + * Using attr->map_fd, attr->key, attr->value, attr->flags * returns zero or negative error */ BPF_MAP_UPDATE_ELEM, @@ -117,6 +117,11 @@ enum bpf_prog_type { BPF_PROG_TYPE_UNSPEC, }; +/* flags for BPF_MAP_UPDATE_ELEM command */ +#define BPF_ANY 0 /* create new element or update existing */ +#define BPF_NOEXIST 1 /* create new element if it didn't exist */ +#define BPF_EXIST 2 /* update existing element */ + union bpf_attr { struct { /* anonymous struct used by BPF_MAP_CREATE command */ __u32 map_type; /* one of enum bpf_map_type */ @@ -132,6 +137,7 @@ union bpf_attr { __aligned_u64 value; __aligned_u64 next_key; }; + __u64 flags; }; struct { /* anonymous struct used by BPF_PROG_LOAD command */ diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index ba61c8c16032..c0d03bf317a2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -190,7 +190,7 @@ static int map_lookup_elem(union bpf_attr *attr) return err; } -#define BPF_MAP_UPDATE_ELEM_LAST_FIELD value +#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags static int map_update_elem(union bpf_attr *attr) { @@ -231,7 +231,7 @@ static int map_update_elem(union bpf_attr *attr) * therefore all map accessors rely on this fact, so do the same here */ rcu_read_lock(); - err = map->ops->map_update_elem(map, key, value); + err = map->ops->map_update_elem(map, key, value, attr->flags); rcu_read_unlock(); free_value: -- GitLab From 0f8e4bd8a1fc8c4185f1630061d0a1f2d197a475 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:45 -0800 Subject: [PATCH 5211/9457] bpf: add hashtable type of eBPF maps add new map type BPF_MAP_TYPE_HASH and its implementation - maps are created/destroyed by userspace. Both userspace and eBPF programs can lookup/update/delete elements from the map - eBPF programs can be called in_irq(), so use spin_lock_irqsave() mechanism for concurrent updates - key/value are opaque range of bytes (aligned to 8 bytes) - user space provides 3 configuration attributes via BPF syscall: key_size, value_size, max_entries - map takes care of allocating/freeing key/value pairs - map_update_elem() must fail to insert new element when max_entries limit is reached to make sure that eBPF programs cannot exhaust memory - map_update_elem() replaces elements in an atomic way - optimized for speed of lookup() which can be called multiple times from eBPF program which itself is triggered by high volume of events . in the future JIT compiler may recognize lookup() call and optimize it further, since key_size is constant for life of eBPF program Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- include/uapi/linux/bpf.h | 1 + kernel/bpf/Makefile | 2 +- kernel/bpf/hashtab.c | 362 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 kernel/bpf/hashtab.c diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 3e9e1b77f29d..03a01fd609aa 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -111,6 +111,7 @@ enum bpf_cmd { enum bpf_map_type { BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, }; enum bpf_prog_type { diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 0daf7f6ae7df..2c0ec7f9da78 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -1,5 +1,5 @@ obj-y := core.o -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o ifdef CONFIG_TEST_BPF obj-$(CONFIG_BPF_SYSCALL) += test_stub.o endif diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c new file mode 100644 index 000000000000..d234a012f046 --- /dev/null +++ b/kernel/bpf/hashtab.c @@ -0,0 +1,362 @@ +/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include + +struct bpf_htab { + struct bpf_map map; + struct hlist_head *buckets; + spinlock_t lock; + u32 count; /* number of elements in this hashtable */ + u32 n_buckets; /* number of hash buckets */ + u32 elem_size; /* size of each element in bytes */ +}; + +/* each htab element is struct htab_elem + key + value */ +struct htab_elem { + struct hlist_node hash_node; + struct rcu_head rcu; + u32 hash; + char key[0] __aligned(8); +}; + +/* Called from syscall */ +static struct bpf_map *htab_map_alloc(union bpf_attr *attr) +{ + struct bpf_htab *htab; + int err, i; + + htab = kzalloc(sizeof(*htab), GFP_USER); + if (!htab) + return ERR_PTR(-ENOMEM); + + /* mandatory map attributes */ + htab->map.key_size = attr->key_size; + htab->map.value_size = attr->value_size; + htab->map.max_entries = attr->max_entries; + + /* check sanity of attributes. + * value_size == 0 may be allowed in the future to use map as a set + */ + err = -EINVAL; + if (htab->map.max_entries == 0 || htab->map.key_size == 0 || + htab->map.value_size == 0) + goto free_htab; + + /* hash table size must be power of 2 */ + htab->n_buckets = roundup_pow_of_two(htab->map.max_entries); + + err = -E2BIG; + if (htab->map.key_size > MAX_BPF_STACK) + /* eBPF programs initialize keys on stack, so they cannot be + * larger than max stack size + */ + goto free_htab; + + err = -ENOMEM; + htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct hlist_head), + GFP_USER | __GFP_NOWARN); + + if (!htab->buckets) { + htab->buckets = vmalloc(htab->n_buckets * sizeof(struct hlist_head)); + if (!htab->buckets) + goto free_htab; + } + + for (i = 0; i < htab->n_buckets; i++) + INIT_HLIST_HEAD(&htab->buckets[i]); + + spin_lock_init(&htab->lock); + htab->count = 0; + + htab->elem_size = sizeof(struct htab_elem) + + round_up(htab->map.key_size, 8) + + htab->map.value_size; + return &htab->map; + +free_htab: + kfree(htab); + return ERR_PTR(err); +} + +static inline u32 htab_map_hash(const void *key, u32 key_len) +{ + return jhash(key, key_len, 0); +} + +static inline struct hlist_head *select_bucket(struct bpf_htab *htab, u32 hash) +{ + return &htab->buckets[hash & (htab->n_buckets - 1)]; +} + +static struct htab_elem *lookup_elem_raw(struct hlist_head *head, u32 hash, + void *key, u32 key_size) +{ + struct htab_elem *l; + + hlist_for_each_entry_rcu(l, head, hash_node) + if (l->hash == hash && !memcmp(&l->key, key, key_size)) + return l; + + return NULL; +} + +/* Called from syscall or from eBPF program */ +static void *htab_map_lookup_elem(struct bpf_map *map, void *key) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct hlist_head *head; + struct htab_elem *l; + u32 hash, key_size; + + /* Must be called with rcu_read_lock. */ + WARN_ON_ONCE(!rcu_read_lock_held()); + + key_size = map->key_size; + + hash = htab_map_hash(key, key_size); + + head = select_bucket(htab, hash); + + l = lookup_elem_raw(head, hash, key, key_size); + + if (l) + return l->key + round_up(map->key_size, 8); + + return NULL; +} + +/* Called from syscall */ +static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct hlist_head *head; + struct htab_elem *l, *next_l; + u32 hash, key_size; + int i; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + key_size = map->key_size; + + hash = htab_map_hash(key, key_size); + + head = select_bucket(htab, hash); + + /* lookup the key */ + l = lookup_elem_raw(head, hash, key, key_size); + + if (!l) { + i = 0; + goto find_first_elem; + } + + /* key was found, get next key in the same bucket */ + next_l = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)), + struct htab_elem, hash_node); + + if (next_l) { + /* if next elem in this hash list is non-zero, just return it */ + memcpy(next_key, next_l->key, key_size); + return 0; + } + + /* no more elements in this hash list, go to the next bucket */ + i = hash & (htab->n_buckets - 1); + i++; + +find_first_elem: + /* iterate over buckets */ + for (; i < htab->n_buckets; i++) { + head = select_bucket(htab, i); + + /* pick first element in the bucket */ + next_l = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)), + struct htab_elem, hash_node); + if (next_l) { + /* if it's not empty, just return it */ + memcpy(next_key, next_l->key, key_size); + return 0; + } + } + + /* itereated over all buckets and all elements */ + return -ENOENT; +} + +/* Called from syscall or from eBPF program */ +static int htab_map_update_elem(struct bpf_map *map, void *key, void *value, + u64 map_flags) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct htab_elem *l_new, *l_old; + struct hlist_head *head; + unsigned long flags; + u32 key_size; + int ret; + + if (map_flags > BPF_EXIST) + /* unknown flags */ + return -EINVAL; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + /* allocate new element outside of lock */ + l_new = kmalloc(htab->elem_size, GFP_ATOMIC); + if (!l_new) + return -ENOMEM; + + key_size = map->key_size; + + memcpy(l_new->key, key, key_size); + memcpy(l_new->key + round_up(key_size, 8), value, map->value_size); + + l_new->hash = htab_map_hash(l_new->key, key_size); + + /* bpf_map_update_elem() can be called in_irq() */ + spin_lock_irqsave(&htab->lock, flags); + + head = select_bucket(htab, l_new->hash); + + l_old = lookup_elem_raw(head, l_new->hash, key, key_size); + + if (!l_old && unlikely(htab->count >= map->max_entries)) { + /* if elem with this 'key' doesn't exist and we've reached + * max_entries limit, fail insertion of new elem + */ + ret = -E2BIG; + goto err; + } + + if (l_old && map_flags == BPF_NOEXIST) { + /* elem already exists */ + ret = -EEXIST; + goto err; + } + + if (!l_old && map_flags == BPF_EXIST) { + /* elem doesn't exist, cannot update it */ + ret = -ENOENT; + goto err; + } + + /* add new element to the head of the list, so that concurrent + * search will find it before old elem + */ + hlist_add_head_rcu(&l_new->hash_node, head); + if (l_old) { + hlist_del_rcu(&l_old->hash_node); + kfree_rcu(l_old, rcu); + } else { + htab->count++; + } + spin_unlock_irqrestore(&htab->lock, flags); + + return 0; +err: + spin_unlock_irqrestore(&htab->lock, flags); + kfree(l_new); + return ret; +} + +/* Called from syscall or from eBPF program */ +static int htab_map_delete_elem(struct bpf_map *map, void *key) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct hlist_head *head; + struct htab_elem *l; + unsigned long flags; + u32 hash, key_size; + int ret = -ENOENT; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + key_size = map->key_size; + + hash = htab_map_hash(key, key_size); + + spin_lock_irqsave(&htab->lock, flags); + + head = select_bucket(htab, hash); + + l = lookup_elem_raw(head, hash, key, key_size); + + if (l) { + hlist_del_rcu(&l->hash_node); + htab->count--; + kfree_rcu(l, rcu); + ret = 0; + } + + spin_unlock_irqrestore(&htab->lock, flags); + return ret; +} + +static void delete_all_elements(struct bpf_htab *htab) +{ + int i; + + for (i = 0; i < htab->n_buckets; i++) { + struct hlist_head *head = select_bucket(htab, i); + struct hlist_node *n; + struct htab_elem *l; + + hlist_for_each_entry_safe(l, n, head, hash_node) { + hlist_del_rcu(&l->hash_node); + htab->count--; + kfree(l); + } + } +} + +/* Called when map->refcnt goes to zero, either from workqueue or from syscall */ +static void htab_map_free(struct bpf_map *map) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + + /* at this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, + * so the programs (can be more than one that used this map) were + * disconnected from events. Wait for outstanding critical sections in + * these programs to complete + */ + synchronize_rcu(); + + /* some of kfree_rcu() callbacks for elements of this map may not have + * executed. It's ok. Proceed to free residual elements and map itself + */ + delete_all_elements(htab); + kvfree(htab->buckets); + kfree(htab); +} + +static struct bpf_map_ops htab_ops = { + .map_alloc = htab_map_alloc, + .map_free = htab_map_free, + .map_get_next_key = htab_map_get_next_key, + .map_lookup_elem = htab_map_lookup_elem, + .map_update_elem = htab_map_update_elem, + .map_delete_elem = htab_map_delete_elem, +}; + +static struct bpf_map_type_list tl = { + .ops = &htab_ops, + .type = BPF_MAP_TYPE_HASH, +}; + +static int __init register_htab_map(void) +{ + bpf_register_map_type(&tl); + return 0; +} +late_initcall(register_htab_map); -- GitLab From 28fbcfa08d8ed7c5a50d41a0433aad222835e8e3 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:46 -0800 Subject: [PATCH 5212/9457] bpf: add array type of eBPF maps add new map type BPF_MAP_TYPE_ARRAY and its implementation - optimized for fastest possible lookup() . in the future verifier/JIT may recognize lookup() with constant key and optimize it into constant pointer. Can optimize non-constant key into direct pointer arithmetic as well, since pointers and value_size are constant for the life of the eBPF program. In other words array_map_lookup_elem() may be 'inlined' by verifier/JIT while preserving concurrent access to this map from user space - two main use cases for array type: . 'global' eBPF variables: array of 1 element with key=0 and value is a collection of 'global' variables which programs can use to keep the state between events . aggregation of tracing events into fixed set of buckets - all array elements pre-allocated and zero initialized at init time - key as an index in array and can only be 4 byte - map_delete_elem() returns EINVAL, since elements cannot be deleted - map_update_elem() replaces elements in an non-atomic way (for atomic updates hashtable type should be used instead) Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- include/uapi/linux/bpf.h | 1 + kernel/bpf/Makefile | 2 +- kernel/bpf/arraymap.c | 151 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 kernel/bpf/arraymap.c diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 03a01fd609aa..0d662fe75df5 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -112,6 +112,7 @@ enum bpf_cmd { enum bpf_map_type { BPF_MAP_TYPE_UNSPEC, BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, }; enum bpf_prog_type { diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 2c0ec7f9da78..72ec98ba2d42 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -1,5 +1,5 @@ obj-y := core.o -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o arraymap.o ifdef CONFIG_TEST_BPF obj-$(CONFIG_BPF_SYSCALL) += test_stub.o endif diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c new file mode 100644 index 000000000000..58b80c137afd --- /dev/null +++ b/kernel/bpf/arraymap.c @@ -0,0 +1,151 @@ +/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include +#include +#include +#include + +struct bpf_array { + struct bpf_map map; + u32 elem_size; + char value[0] __aligned(8); +}; + +/* Called from syscall */ +static struct bpf_map *array_map_alloc(union bpf_attr *attr) +{ + struct bpf_array *array; + u32 elem_size; + + /* check sanity of attributes */ + if (attr->max_entries == 0 || attr->key_size != 4 || + attr->value_size == 0) + return ERR_PTR(-EINVAL); + + elem_size = round_up(attr->value_size, 8); + + /* allocate all map elements and zero-initialize them */ + array = kzalloc(sizeof(*array) + attr->max_entries * elem_size, + GFP_USER | __GFP_NOWARN); + if (!array) { + array = vzalloc(array->map.max_entries * array->elem_size); + if (!array) + return ERR_PTR(-ENOMEM); + } + + /* copy mandatory map attributes */ + array->map.key_size = attr->key_size; + array->map.value_size = attr->value_size; + array->map.max_entries = attr->max_entries; + + array->elem_size = elem_size; + + return &array->map; + +} + +/* Called from syscall or from eBPF program */ +static void *array_map_lookup_elem(struct bpf_map *map, void *key) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + u32 index = *(u32 *)key; + + if (index >= array->map.max_entries) + return NULL; + + return array->value + array->elem_size * index; +} + +/* Called from syscall */ +static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + u32 index = *(u32 *)key; + u32 *next = (u32 *)next_key; + + if (index >= array->map.max_entries) { + *next = 0; + return 0; + } + + if (index == array->map.max_entries - 1) + return -ENOENT; + + *next = index + 1; + return 0; +} + +/* Called from syscall or from eBPF program */ +static int array_map_update_elem(struct bpf_map *map, void *key, void *value, + u64 map_flags) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + u32 index = *(u32 *)key; + + if (map_flags > BPF_EXIST) + /* unknown flags */ + return -EINVAL; + + if (index >= array->map.max_entries) + /* all elements were pre-allocated, cannot insert a new one */ + return -E2BIG; + + if (map_flags == BPF_NOEXIST) + /* all elemenets already exist */ + return -EEXIST; + + memcpy(array->value + array->elem_size * index, value, array->elem_size); + return 0; +} + +/* Called from syscall or from eBPF program */ +static int array_map_delete_elem(struct bpf_map *map, void *key) +{ + return -EINVAL; +} + +/* Called when map->refcnt goes to zero, either from workqueue or from syscall */ +static void array_map_free(struct bpf_map *map) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + + /* at this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, + * so the programs (can be more than one that used this map) were + * disconnected from events. Wait for outstanding programs to complete + * and free the array + */ + synchronize_rcu(); + + kvfree(array); +} + +static struct bpf_map_ops array_ops = { + .map_alloc = array_map_alloc, + .map_free = array_map_free, + .map_get_next_key = array_map_get_next_key, + .map_lookup_elem = array_map_lookup_elem, + .map_update_elem = array_map_update_elem, + .map_delete_elem = array_map_delete_elem, +}; + +static struct bpf_map_type_list tl = { + .ops = &array_ops, + .type = BPF_MAP_TYPE_ARRAY, +}; + +static int __init register_array_map(void) +{ + bpf_register_map_type(&tl); + return 0; +} +late_initcall(register_array_map); -- GitLab From a1854d6ac0008518bfc45e791172ad250999c2a2 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:47 -0800 Subject: [PATCH 5213/9457] bpf: fix BPF_MAP_LOOKUP_ELEM command return code fix errno of BPF_MAP_LOOKUP_ELEM command as bpf manpage described it in commit b4fc1a460f30("Merge branch 'bpf-next'"): ----- BPF_MAP_LOOKUP_ELEM int bpf_lookup_elem(int fd, void *key, void *value) { union bpf_attr attr = { .map_fd = fd, .key = ptr_to_u64(key), .value = ptr_to_u64(value), }; return bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); } bpf() syscall looks up an element with given key in a map fd. If element is found it returns zero and stores element's value into value. If element is not found it returns -1 and sets errno to ENOENT. and further down in manpage: ENOENT For BPF_MAP_LOOKUP_ELEM or BPF_MAP_DELETE_ELEM, indicates that element with given key was not found. ----- In general all BPF commands return ENOENT when map element is not found (including BPF_MAP_GET_NEXT_KEY and BPF_MAP_UPDATE_ELEM with flags == BPF_MAP_UPDATE_ONLY) Subsequent patch adds a testsuite to check return values for all of these combinations. Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- kernel/bpf/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index c0d03bf317a2..088ac0b1b106 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -169,7 +169,7 @@ static int map_lookup_elem(union bpf_attr *attr) if (copy_from_user(key, ukey, map->key_size) != 0) goto free_key; - err = -ESRCH; + err = -ENOENT; rcu_read_lock(); value = map->ops->map_lookup_elem(map, key); if (!value) -- GitLab From ffb65f27a15583379567b6a59a9758163b7f5750 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:48 -0800 Subject: [PATCH 5214/9457] bpf: add a testsuite for eBPF maps . check error conditions and sanity of hash and array map APIs . check large maps (that kernel gracefully switches to vmalloc from kmalloc) . check multi-process parallel access and stress test Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- samples/bpf/Makefile | 3 +- samples/bpf/libbpf.c | 3 +- samples/bpf/libbpf.h | 2 +- samples/bpf/test_maps.c | 291 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 296 insertions(+), 3 deletions(-) create mode 100644 samples/bpf/test_maps.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 634391797856..0718d9ce4619 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -2,9 +2,10 @@ obj- := dummy.o # List of programs to build -hostprogs-y := test_verifier +hostprogs-y := test_verifier test_maps test_verifier-objs := test_verifier.o libbpf.o +test_maps-objs := test_maps.o libbpf.o # Tell kbuild to always build the programs always := $(hostprogs-y) diff --git a/samples/bpf/libbpf.c b/samples/bpf/libbpf.c index ff6504420738..17bb520eb57f 100644 --- a/samples/bpf/libbpf.c +++ b/samples/bpf/libbpf.c @@ -27,12 +27,13 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); } -int bpf_update_elem(int fd, void *key, void *value) +int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags) { union bpf_attr attr = { .map_fd = fd, .key = ptr_to_u64(key), .value = ptr_to_u64(value), + .flags = flags, }; return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); diff --git a/samples/bpf/libbpf.h b/samples/bpf/libbpf.h index 8a31babeca5d..f8678e5f48bf 100644 --- a/samples/bpf/libbpf.h +++ b/samples/bpf/libbpf.h @@ -6,7 +6,7 @@ struct bpf_insn; int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, int max_entries); -int bpf_update_elem(int fd, void *key, void *value); +int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags); int bpf_lookup_elem(int fd, void *key, void *value); int bpf_delete_elem(int fd, void *key); int bpf_get_next_key(int fd, void *key, void *next_key); diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c new file mode 100644 index 000000000000..e286b42307f3 --- /dev/null +++ b/samples/bpf/test_maps.c @@ -0,0 +1,291 @@ +/* + * Testsuite for eBPF maps + * + * Copyright (c) 2014 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "libbpf.h" + +/* sanity tests for map API */ +static void test_hashmap_sanity(int i, void *data) +{ + long long key, next_key, value; + int map_fd; + + map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), 2); + if (map_fd < 0) { + printf("failed to create hashmap '%s'\n", strerror(errno)); + exit(1); + } + + key = 1; + value = 1234; + /* insert key=1 element */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0); + + value = 0; + /* BPF_NOEXIST means: add new element if it doesn't exist */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 && + /* key=1 already exists */ + errno == EEXIST); + + assert(bpf_update_elem(map_fd, &key, &value, -1) == -1 && errno == EINVAL); + + /* check that key=1 can be found */ + assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234); + + key = 2; + /* check that key=2 is not found */ + assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT); + + /* BPF_EXIST means: update existing element */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 && + /* key=2 is not there */ + errno == ENOENT); + + /* insert key=2 element */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0); + + /* key=1 and key=2 were inserted, check that key=0 cannot be inserted + * due to max_entries limit + */ + key = 0; + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 && + errno == E2BIG); + + /* check that key = 0 doesn't exist */ + assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT); + + /* iterate over two elements */ + assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && + next_key == 2); + assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && + next_key == 1); + assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && + errno == ENOENT); + + /* delete both elements */ + key = 1; + assert(bpf_delete_elem(map_fd, &key) == 0); + key = 2; + assert(bpf_delete_elem(map_fd, &key) == 0); + assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT); + + key = 0; + /* check that map is empty */ + assert(bpf_get_next_key(map_fd, &key, &next_key) == -1 && + errno == ENOENT); + close(map_fd); +} + +static void test_arraymap_sanity(int i, void *data) +{ + int key, next_key, map_fd; + long long value; + + map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value), 2); + if (map_fd < 0) { + printf("failed to create arraymap '%s'\n", strerror(errno)); + exit(1); + } + + key = 1; + value = 1234; + /* insert key=1 element */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0); + + value = 0; + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 && + errno == EEXIST); + + /* check that key=1 can be found */ + assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234); + + key = 0; + /* check that key=0 is also found and zero initialized */ + assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0); + + + /* key=0 and key=1 were inserted, check that key=2 cannot be inserted + * due to max_entries limit + */ + key = 2; + assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 && + errno == E2BIG); + + /* check that key = 2 doesn't exist */ + assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT); + + /* iterate over two elements */ + assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && + next_key == 0); + assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && + next_key == 1); + assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && + errno == ENOENT); + + /* delete shouldn't succeed */ + key = 1; + assert(bpf_delete_elem(map_fd, &key) == -1 && errno == EINVAL); + + close(map_fd); +} + +#define MAP_SIZE (32 * 1024) +static void test_map_large(void) +{ + struct bigkey { + int a; + char b[116]; + long long c; + } key; + int map_fd, i, value; + + /* allocate 4Mbyte of memory */ + map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), + MAP_SIZE); + if (map_fd < 0) { + printf("failed to create large map '%s'\n", strerror(errno)); + exit(1); + } + + for (i = 0; i < MAP_SIZE; i++) { + key = (struct bigkey) {.c = i}; + value = i; + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0); + } + key.c = -1; + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 && + errno == E2BIG); + + /* iterate through all elements */ + for (i = 0; i < MAP_SIZE; i++) + assert(bpf_get_next_key(map_fd, &key, &key) == 0); + assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT); + + key.c = 0; + assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0); + key.a = 1; + assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT); + + close(map_fd); +} + +/* fork N children and wait for them to complete */ +static void run_parallel(int tasks, void (*fn)(int i, void *data), void *data) +{ + pid_t pid[tasks]; + int i; + + for (i = 0; i < tasks; i++) { + pid[i] = fork(); + if (pid[i] == 0) { + fn(i, data); + exit(0); + } else if (pid[i] == -1) { + printf("couldn't spawn #%d process\n", i); + exit(1); + } + } + for (i = 0; i < tasks; i++) { + int status; + + assert(waitpid(pid[i], &status, 0) == pid[i]); + assert(status == 0); + } +} + +static void test_map_stress(void) +{ + run_parallel(100, test_hashmap_sanity, NULL); + run_parallel(100, test_arraymap_sanity, NULL); +} + +#define TASKS 1024 +#define DO_UPDATE 1 +#define DO_DELETE 0 +static void do_work(int fn, void *data) +{ + int map_fd = ((int *)data)[0]; + int do_update = ((int *)data)[1]; + int i; + int key, value; + + for (i = fn; i < MAP_SIZE; i += TASKS) { + key = value = i; + if (do_update) + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0); + else + assert(bpf_delete_elem(map_fd, &key) == 0); + } +} + +static void test_map_parallel(void) +{ + int i, map_fd, key = 0, value = 0; + int data[2]; + + map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), + MAP_SIZE); + if (map_fd < 0) { + printf("failed to create map for parallel test '%s'\n", + strerror(errno)); + exit(1); + } + + data[0] = map_fd; + data[1] = DO_UPDATE; + /* use the same map_fd in children to add elements to this map + * child_0 adds key=0, key=1024, key=2048, ... + * child_1 adds key=1, key=1025, key=2049, ... + * child_1023 adds key=1023, ... + */ + run_parallel(TASKS, do_work, data); + + /* check that key=0 is already there */ + assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 && + errno == EEXIST); + + /* check that all elements were inserted */ + key = -1; + for (i = 0; i < MAP_SIZE; i++) + assert(bpf_get_next_key(map_fd, &key, &key) == 0); + assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT); + + /* another check for all elements */ + for (i = 0; i < MAP_SIZE; i++) { + key = MAP_SIZE - i - 1; + assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && + value == key); + } + + /* now let's delete all elemenets in parallel */ + data[1] = DO_DELETE; + run_parallel(TASKS, do_work, data); + + /* nothing should be left */ + key = -1; + assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT); +} + +int main(void) +{ + test_hashmap_sanity(0, NULL); + test_arraymap_sanity(0, NULL); + test_map_large(); + test_map_parallel(); + test_map_stress(); + printf("test_maps: OK\n"); + return 0; +} -- GitLab From d0003ec01c667b731c139e23de3306a8b328ccf5 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:49 -0800 Subject: [PATCH 5215/9457] bpf: allow eBPF programs to use maps expose bpf_map_lookup_elem(), bpf_map_update_elem(), bpf_map_delete_elem() map accessors to eBPF programs Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- include/linux/bpf.h | 5 +++ include/uapi/linux/bpf.h | 3 ++ kernel/bpf/Makefile | 2 +- kernel/bpf/helpers.c | 89 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 kernel/bpf/helpers.c diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 51e9242e4803..75e94eaa228b 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -133,4 +133,9 @@ struct bpf_prog *bpf_prog_get(u32 ufd); /* verify correctness of eBPF program */ int bpf_check(struct bpf_prog *fp, union bpf_attr *attr); +/* verifier prototypes for helper functions called from eBPF programs */ +extern struct bpf_func_proto bpf_map_lookup_elem_proto; +extern struct bpf_func_proto bpf_map_update_elem_proto; +extern struct bpf_func_proto bpf_map_delete_elem_proto; + #endif /* _LINUX_BPF_H */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0d662fe75df5..4a3d0f84f178 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -158,6 +158,9 @@ union bpf_attr { */ enum bpf_func_id { BPF_FUNC_unspec, + BPF_FUNC_map_lookup_elem, /* void *map_lookup_elem(&map, &key) */ + BPF_FUNC_map_update_elem, /* int map_update_elem(&map, &key, &value, flags) */ + BPF_FUNC_map_delete_elem, /* int map_delete_elem(&map, &key) */ __BPF_FUNC_MAX_ID, }; diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 72ec98ba2d42..a5ae60f0b0a2 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -1,5 +1,5 @@ obj-y := core.o -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o arraymap.o +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o arraymap.o helpers.o ifdef CONFIG_TEST_BPF obj-$(CONFIG_BPF_SYSCALL) += test_stub.o endif diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c new file mode 100644 index 000000000000..9e3414d85459 --- /dev/null +++ b/kernel/bpf/helpers.c @@ -0,0 +1,89 @@ +/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include +#include + +/* If kernel subsystem is allowing eBPF programs to call this function, + * inside its own verifier_ops->get_func_proto() callback it should return + * bpf_map_lookup_elem_proto, so that verifier can properly check the arguments + * + * Different map implementations will rely on rcu in map methods + * lookup/update/delete, therefore eBPF programs must run under rcu lock + * if program is allowed to access maps, so check rcu_read_lock_held in + * all three functions. + */ +static u64 bpf_map_lookup_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + /* verifier checked that R1 contains a valid pointer to bpf_map + * and R2 points to a program stack and map->key_size bytes were + * initialized + */ + struct bpf_map *map = (struct bpf_map *) (unsigned long) r1; + void *key = (void *) (unsigned long) r2; + void *value; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + value = map->ops->map_lookup_elem(map, key); + + /* lookup() returns either pointer to element value or NULL + * which is the meaning of PTR_TO_MAP_VALUE_OR_NULL type + */ + return (unsigned long) value; +} + +struct bpf_func_proto bpf_map_lookup_elem_proto = { + .func = bpf_map_lookup_elem, + .gpl_only = false, + .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_PTR_TO_MAP_KEY, +}; + +static u64 bpf_map_update_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + struct bpf_map *map = (struct bpf_map *) (unsigned long) r1; + void *key = (void *) (unsigned long) r2; + void *value = (void *) (unsigned long) r3; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + return map->ops->map_update_elem(map, key, value, r4); +} + +struct bpf_func_proto bpf_map_update_elem_proto = { + .func = bpf_map_update_elem, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_PTR_TO_MAP_KEY, + .arg3_type = ARG_PTR_TO_MAP_VALUE, + .arg4_type = ARG_ANYTHING, +}; + +static u64 bpf_map_delete_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + struct bpf_map *map = (struct bpf_map *) (unsigned long) r1; + void *key = (void *) (unsigned long) r2; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + return map->ops->map_delete_elem(map, key); +} + +struct bpf_func_proto bpf_map_delete_elem_proto = { + .func = bpf_map_delete_elem, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_PTR_TO_MAP_KEY, +}; -- GitLab From 7943c0f329d33f531607d66f5781f2210e1e278c Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 13 Nov 2014 17:36:50 -0800 Subject: [PATCH 5216/9457] bpf: remove test map scaffolding and user proper types proper types and function helpers are ready. Use them in verifier testsuite. Remove temporary stubs Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- kernel/bpf/test_stub.c | 56 ++++++------------------------------- samples/bpf/test_verifier.c | 14 +++++----- 2 files changed, 16 insertions(+), 54 deletions(-) diff --git a/kernel/bpf/test_stub.c b/kernel/bpf/test_stub.c index fcaddff4003e..0ceae1e6e8b5 100644 --- a/kernel/bpf/test_stub.c +++ b/kernel/bpf/test_stub.c @@ -18,26 +18,18 @@ struct bpf_context { u64 arg2; }; -static u64 test_func(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) -{ - return 0; -} - -static struct bpf_func_proto test_funcs[] = { - [BPF_FUNC_unspec] = { - .func = test_func, - .gpl_only = true, - .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL, - .arg1_type = ARG_CONST_MAP_PTR, - .arg2_type = ARG_PTR_TO_MAP_KEY, - }, -}; - static const struct bpf_func_proto *test_func_proto(enum bpf_func_id func_id) { - if (func_id < 0 || func_id >= ARRAY_SIZE(test_funcs)) + switch (func_id) { + case BPF_FUNC_map_lookup_elem: + return &bpf_map_lookup_elem_proto; + case BPF_FUNC_map_update_elem: + return &bpf_map_update_elem_proto; + case BPF_FUNC_map_delete_elem: + return &bpf_map_delete_elem_proto; + default: return NULL; - return &test_funcs[func_id]; + } } static const struct bpf_context_access { @@ -78,38 +70,8 @@ static struct bpf_prog_type_list tl_prog = { .type = BPF_PROG_TYPE_UNSPEC, }; -static struct bpf_map *test_map_alloc(union bpf_attr *attr) -{ - struct bpf_map *map; - - map = kzalloc(sizeof(*map), GFP_USER); - if (!map) - return ERR_PTR(-ENOMEM); - - map->key_size = attr->key_size; - map->value_size = attr->value_size; - map->max_entries = attr->max_entries; - return map; -} - -static void test_map_free(struct bpf_map *map) -{ - kfree(map); -} - -static struct bpf_map_ops test_map_ops = { - .map_alloc = test_map_alloc, - .map_free = test_map_free, -}; - -static struct bpf_map_type_list tl_map = { - .ops = &test_map_ops, - .type = BPF_MAP_TYPE_UNSPEC, -}; - static int __init register_test_ops(void) { - bpf_register_map_type(&tl_map); bpf_register_prog_type(&tl_prog); return 0; } diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c index 63402742345e..b96175e90363 100644 --- a/samples/bpf/test_verifier.c +++ b/samples/bpf/test_verifier.c @@ -261,7 +261,7 @@ static struct bpf_test tests[] = { BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_EXIT_INSN(), }, .fixup = {2}, @@ -417,7 +417,7 @@ static struct bpf_test tests[] = { BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem), BPF_EXIT_INSN(), }, .errstr = "fd 0 is not pointing to valid bpf_map", @@ -430,7 +430,7 @@ static struct bpf_test tests[] = { BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), BPF_EXIT_INSN(), }, @@ -445,7 +445,7 @@ static struct bpf_test tests[] = { BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0), BPF_EXIT_INSN(), @@ -461,7 +461,7 @@ static struct bpf_test tests[] = { BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0), BPF_EXIT_INSN(), @@ -548,7 +548,7 @@ static struct bpf_test tests[] = { BPF_ST_MEM(BPF_DW, BPF_REG_2, -56, 0), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -56), BPF_LD_MAP_FD(BPF_REG_1, 0), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_unspec), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_delete_elem), BPF_EXIT_INSN(), }, .fixup = {24}, @@ -659,7 +659,7 @@ static int create_map(void) long long key, value = 0; int map_fd; - map_fd = bpf_create_map(BPF_MAP_TYPE_UNSPEC, sizeof(key), sizeof(value), 1024); + map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), 1024); if (map_fd < 0) { printf("failed to create map '%s'\n", strerror(errno)); } -- GitLab From ea209de3dded8acd37677cf4e2f5fc06b791e052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:17 +0100 Subject: [PATCH 5217/9457] net: fec: indentation cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit consistently use TABs for indentation Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 108 +++++++++++++-------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 9af296a1ca99..3047db4f8c7b 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -213,60 +213,60 @@ struct bufdesc_ex { * The following definitions courtesy of commproc.h, which where * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ -#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ -#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ -#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ -#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */ -#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ -#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ -#define BD_SC_BR ((ushort)0x0020) /* Break received */ -#define BD_SC_FR ((ushort)0x0010) /* Framing error */ -#define BD_SC_PR ((ushort)0x0008) /* Parity error */ -#define BD_SC_OV ((ushort)0x0002) /* Overrun */ -#define BD_SC_CD ((ushort)0x0001) /* ?? */ +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ +#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ +#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */ +#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ +#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ +#define BD_SC_BR ((ushort)0x0020) /* Break received */ +#define BD_SC_FR ((ushort)0x0010) /* Framing error */ +#define BD_SC_PR ((ushort)0x0008) /* Parity error */ +#define BD_SC_OV ((ushort)0x0002) /* Overrun */ +#define BD_SC_CD ((ushort)0x0001) /* ?? */ /* Buffer descriptor control/status used by Ethernet receive. -*/ -#define BD_ENET_RX_EMPTY ((ushort)0x8000) -#define BD_ENET_RX_WRAP ((ushort)0x2000) -#define BD_ENET_RX_INTR ((ushort)0x1000) -#define BD_ENET_RX_LAST ((ushort)0x0800) -#define BD_ENET_RX_FIRST ((ushort)0x0400) -#define BD_ENET_RX_MISS ((ushort)0x0100) -#define BD_ENET_RX_LG ((ushort)0x0020) -#define BD_ENET_RX_NO ((ushort)0x0010) -#define BD_ENET_RX_SH ((ushort)0x0008) -#define BD_ENET_RX_CR ((ushort)0x0004) -#define BD_ENET_RX_OV ((ushort)0x0002) -#define BD_ENET_RX_CL ((ushort)0x0001) -#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ + */ +#define BD_ENET_RX_EMPTY ((ushort)0x8000) +#define BD_ENET_RX_WRAP ((ushort)0x2000) +#define BD_ENET_RX_INTR ((ushort)0x1000) +#define BD_ENET_RX_LAST ((ushort)0x0800) +#define BD_ENET_RX_FIRST ((ushort)0x0400) +#define BD_ENET_RX_MISS ((ushort)0x0100) +#define BD_ENET_RX_LG ((ushort)0x0020) +#define BD_ENET_RX_NO ((ushort)0x0010) +#define BD_ENET_RX_SH ((ushort)0x0008) +#define BD_ENET_RX_CR ((ushort)0x0004) +#define BD_ENET_RX_OV ((ushort)0x0002) +#define BD_ENET_RX_CL ((ushort)0x0001) +#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ /* Enhanced buffer descriptor control/status used by Ethernet receive */ -#define BD_ENET_RX_VLAN 0x00000004 +#define BD_ENET_RX_VLAN 0x00000004 /* Buffer descriptor control/status used by Ethernet transmit. -*/ -#define BD_ENET_TX_READY ((ushort)0x8000) -#define BD_ENET_TX_PAD ((ushort)0x4000) -#define BD_ENET_TX_WRAP ((ushort)0x2000) -#define BD_ENET_TX_INTR ((ushort)0x1000) -#define BD_ENET_TX_LAST ((ushort)0x0800) -#define BD_ENET_TX_TC ((ushort)0x0400) -#define BD_ENET_TX_DEF ((ushort)0x0200) -#define BD_ENET_TX_HB ((ushort)0x0100) -#define BD_ENET_TX_LC ((ushort)0x0080) -#define BD_ENET_TX_RL ((ushort)0x0040) -#define BD_ENET_TX_RCMASK ((ushort)0x003c) -#define BD_ENET_TX_UN ((ushort)0x0002) -#define BD_ENET_TX_CSL ((ushort)0x0001) -#define BD_ENET_TX_STATS ((ushort)0x0fff) /* All status bits */ - -/*enhanced buffer descriptor control/status used by Ethernet transmit*/ -#define BD_ENET_TX_INT 0x40000000 -#define BD_ENET_TX_TS 0x20000000 -#define BD_ENET_TX_PINS 0x10000000 -#define BD_ENET_TX_IINS 0x08000000 + */ +#define BD_ENET_TX_READY ((ushort)0x8000) +#define BD_ENET_TX_PAD ((ushort)0x4000) +#define BD_ENET_TX_WRAP ((ushort)0x2000) +#define BD_ENET_TX_INTR ((ushort)0x1000) +#define BD_ENET_TX_LAST ((ushort)0x0800) +#define BD_ENET_TX_TC ((ushort)0x0400) +#define BD_ENET_TX_DEF ((ushort)0x0200) +#define BD_ENET_TX_HB ((ushort)0x0100) +#define BD_ENET_TX_LC ((ushort)0x0080) +#define BD_ENET_TX_RL ((ushort)0x0040) +#define BD_ENET_TX_RCMASK ((ushort)0x003c) +#define BD_ENET_TX_UN ((ushort)0x0002) +#define BD_ENET_TX_CSL ((ushort)0x0001) +#define BD_ENET_TX_STATS ((ushort)0x0fff) /* All status bits */ + +/* enhanced buffer descriptor control/status used by Ethernet transmit */ +#define BD_ENET_TX_INT 0x40000000 +#define BD_ENET_TX_TS 0x20000000 +#define BD_ENET_TX_PINS 0x10000000 +#define BD_ENET_TX_IINS 0x08000000 /* This device has up to three irqs on some platforms */ @@ -301,7 +301,7 @@ struct bufdesc_ex { #define IDLE_SLOPE_2 0x200 /* BW fraction: 0.5 */ #define IDLE_SLOPE(X) ((X == 1) ? (IDLE_SLOPE_1 & IDLE_SLOPE_MASK) : \ (IDLE_SLOPE_2 & IDLE_SLOPE_MASK)) -#define RCMR_MATCHEN (0x1 << 16) +#define RCMR_MATCHEN (0x1 << 16) #define RCMR_CMP_CFG(v, n) ((v & 0x7) << (n << 2)) #define RCMR_CMP_1 (RCMR_CMP_CFG(0, 0) | RCMR_CMP_CFG(1, 1) | \ RCMR_CMP_CFG(2, 2) | RCMR_CMP_CFG(3, 3)) @@ -326,8 +326,8 @@ struct bufdesc_ex { #define TX_RING_SIZE 512 /* Must be power of two */ #define TX_RING_MOD_MASK 511 /* for this to work */ -#define BD_ENET_RX_INT 0x00800000 -#define BD_ENET_RX_PTP ((ushort)0x0400) +#define BD_ENET_RX_INT 0x00800000 +#define BD_ENET_RX_PTP ((ushort)0x0400) #define BD_ENET_RX_ICE 0x00000020 #define BD_ENET_RX_PCR 0x00000010 #define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR) @@ -364,8 +364,8 @@ struct bufdesc_ex { #define FEC_ITR_ICFT_DEFAULT 200 /* Set 200 frame count threshold */ #define FEC_ITR_ICTT_DEFAULT 1000 /* Set 1000us timer threshold */ -#define FEC_VLAN_TAG_LEN 0x04 -#define FEC_ETHTYPE_LEN 0x02 +#define FEC_VLAN_TAG_LEN 0x04 +#define FEC_ETHTYPE_LEN 0x02 /* Controller is ENET-MAC */ #define FEC_QUIRK_ENET_MAC (1 << 0) @@ -390,7 +390,7 @@ struct bufdesc_ex { * frames not being transmitted until there is a 0-to-1 transition on * ENET_TDAR[TDAR]. */ -#define FEC_QUIRK_ERR006358 (1 << 7) +#define FEC_QUIRK_ERR006358 (1 << 7) /* ENET IP hw AVB * * i.MX6SX ENET IP add Audio Video Bridging (AVB) feature support. -- GitLab From 745f42ba2a52d5b95594c24fb3755ff678f669f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:18 +0100 Subject: [PATCH 5218/9457] net: fec: consistently use lower case chars as hex digits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 88 ++++++++++++++-------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 3047db4f8c7b..e778b9e4f0a4 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -38,9 +38,9 @@ #define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */ #define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */ #define FEC_OPD 0x0ec /* Opcode + Pause duration */ -#define FEC_TXIC0 0xF0 /* Tx Interrupt Coalescing for ring 0 */ -#define FEC_TXIC1 0xF4 /* Tx Interrupt Coalescing for ring 1 */ -#define FEC_TXIC2 0xF8 /* Tx Interrupt Coalescing for ring 2 */ +#define FEC_TXIC0 0x0f0 /* Tx Interrupt Coalescing for ring 0 */ +#define FEC_TXIC1 0x0f4 /* Tx Interrupt Coalescing for ring 1 */ +#define FEC_TXIC2 0x0f8 /* Tx Interrupt Coalescing for ring 2 */ #define FEC_RXIC0 0x100 /* Rx Interrupt Coalescing for ring 0 */ #define FEC_RXIC1 0x104 /* Rx Interrupt Coalescing for ring 1 */ #define FEC_RXIC2 0x108 /* Rx Interrupt Coalescing for ring 2 */ @@ -62,7 +62,7 @@ #define FEC_R_FIFO_RSEM 0x194 /* Receive FIFO section empty threshold */ #define FEC_R_FIFO_RAEM 0x198 /* Receive FIFO almost empty threshold */ #define FEC_R_FIFO_RAFL 0x19c /* Receive FIFO almost full threshold */ -#define FEC_RACC 0x1C4 /* Receive Accelerator function */ +#define FEC_RACC 0x1c4 /* Receive Accelerator function */ #define FEC_RCMR_1 0x1c8 /* Receive classification match ring 1 */ #define FEC_RCMR_2 0x1cc /* Receive classification match ring 2 */ #define FEC_DMA_CFG_1 0x1d8 /* DMA class configuration for ring 1 */ @@ -82,57 +82,57 @@ #define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */ #define RMON_T_PACKETS 0x204 /* RMON TX packet count */ #define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */ -#define RMON_T_MC_PKT 0x20C /* RMON TX multicast pkts */ +#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */ #define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */ #define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */ #define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */ -#define RMON_T_FRAG 0x21C /* RMON TX pkts < 64 bytes, bad CRC */ +#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */ #define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */ #define RMON_T_COL 0x224 /* RMON TX collision count */ #define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */ -#define RMON_T_P65TO127 0x22C /* RMON TX 65 to 127 byte pkts */ +#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */ #define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */ #define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */ #define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */ -#define RMON_T_P1024TO2047 0x23C /* RMON TX 1024 to 2047 byte pkts */ +#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */ #define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */ #define RMON_T_OCTETS 0x244 /* RMON TX octets */ #define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */ -#define IEEE_T_FRAME_OK 0x24C /* Frames tx'd OK */ +#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */ #define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */ #define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ #define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ -#define IEEE_T_LCOL 0x25C /* Frames tx'd with late collision */ +#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */ #define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ #define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ #define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ -#define IEEE_T_SQE 0x26C /* Frames tx'd with SQE err */ +#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */ #define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */ #define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */ #define RMON_R_PACKETS 0x284 /* RMON RX packet count */ #define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */ -#define RMON_R_MC_PKT 0x28C /* RMON RX multicast pkts */ +#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */ #define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */ #define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */ #define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */ -#define RMON_R_FRAG 0x29C /* RMON RX pkts < 64 bytes, bad CRC */ -#define RMON_R_JAB 0x2A0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ -#define RMON_R_RESVD_O 0x2A4 /* Reserved */ -#define RMON_R_P64 0x2A8 /* RMON RX 64 byte pkts */ -#define RMON_R_P65TO127 0x2AC /* RMON RX 65 to 127 byte pkts */ -#define RMON_R_P128TO255 0x2B0 /* RMON RX 128 to 255 byte pkts */ -#define RMON_R_P256TO511 0x2B4 /* RMON RX 256 to 511 byte pkts */ -#define RMON_R_P512TO1023 0x2B8 /* RMON RX 512 to 1023 byte pkts */ -#define RMON_R_P1024TO2047 0x2BC /* RMON RX 1024 to 2047 byte pkts */ -#define RMON_R_P_GTE2048 0x2C0 /* RMON RX pkts > 2048 bytes */ -#define RMON_R_OCTETS 0x2C4 /* RMON RX octets */ -#define IEEE_R_DROP 0x2C8 /* Count frames not counted correctly */ -#define IEEE_R_FRAME_OK 0x2CC /* Frames rx'd OK */ -#define IEEE_R_CRC 0x2D0 /* Frames rx'd with CRC err */ -#define IEEE_R_ALIGN 0x2D4 /* Frames rx'd with alignment err */ -#define IEEE_R_MACERR 0x2D8 /* Receive FIFO overflow count */ -#define IEEE_R_FDXFC 0x2DC /* Flow control pause frames rx'd */ -#define IEEE_R_OCTETS_OK 0x2E0 /* Octet cnt for frames rx'd w/o err */ +#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */ +#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ +#define RMON_R_RESVD_O 0x2a4 /* Reserved */ +#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */ +#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */ +#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */ +#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */ +#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */ +#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */ +#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */ +#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */ +#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */ +#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */ +#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */ +#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */ +#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */ +#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */ +#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */ #else @@ -170,16 +170,16 @@ /* Not existed in real chip * Just for pass build. */ -#define FEC_RCMR_1 0xFFF -#define FEC_RCMR_2 0xFFF -#define FEC_DMA_CFG_1 0xFFF -#define FEC_DMA_CFG_2 0xFFF -#define FEC_TXIC0 0xFFF -#define FEC_TXIC1 0xFFF -#define FEC_TXIC2 0xFFF -#define FEC_RXIC0 0xFFF -#define FEC_RXIC1 0xFFF -#define FEC_RXIC2 0xFFF +#define FEC_RCMR_1 0xfff +#define FEC_RCMR_2 0xfff +#define FEC_DMA_CFG_1 0xfff +#define FEC_DMA_CFG_2 0xfff +#define FEC_TXIC0 0xfff +#define FEC_TXIC1 0xfff +#define FEC_TXIC2 0xfff +#define FEC_RXIC0 0xfff +#define FEC_RXIC1 0xfff +#define FEC_RXIC2 0xfff #endif /* CONFIG_M5272 */ @@ -296,7 +296,7 @@ struct bufdesc_ex { #define DMA_CLASS_EN (1 << 16) #define FEC_RCMR(X) ((X == 2) ? FEC_RCMR_2 : FEC_RCMR_1) -#define IDLE_SLOPE_MASK 0xFFFF +#define IDLE_SLOPE_MASK 0xffff #define IDLE_SLOPE_1 0x200 /* BW fraction: 0.5 */ #define IDLE_SLOPE_2 0x200 /* BW fraction: 0.5 */ #define IDLE_SLOPE(X) ((X == 1) ? (IDLE_SLOPE_1 & IDLE_SLOPE_MASK) : \ @@ -308,7 +308,7 @@ struct bufdesc_ex { #define RCMR_CMP_2 (RCMR_CMP_CFG(4, 0) | RCMR_CMP_CFG(5, 1) | \ RCMR_CMP_CFG(6, 2) | RCMR_CMP_CFG(7, 3)) #define RCMR_CMP(X) ((X == 1) ? RCMR_CMP_1 : RCMR_CMP_2) -#define FEC_TX_BD_FTYPE(X) ((X & 0xF) << 20) +#define FEC_TX_BD_FTYPE(X) ((X & 0xf) << 20) /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it it best @@ -359,8 +359,8 @@ struct bufdesc_ex { /* ENET interrupt coalescing macro define */ #define FEC_ITR_CLK_SEL (0x1 << 30) #define FEC_ITR_EN (0x1 << 31) -#define FEC_ITR_ICFT(X) ((X & 0xFF) << 20) -#define FEC_ITR_ICTT(X) ((X) & 0xFFFF) +#define FEC_ITR_ICFT(X) ((X & 0xff) << 20) +#define FEC_ITR_ICTT(X) ((X) & 0xffff) #define FEC_ITR_ICFT_DEFAULT 200 /* Set 200 frame count threshold */ #define FEC_ITR_ICTT_DEFAULT 1000 /* Set 1000us timer threshold */ -- GitLab From df406bc9c0d002ef52671dc7b6887ff1bb9142e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:19 +0100 Subject: [PATCH 5219/9457] net: fec: properly parenthesize macro args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 31 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index e778b9e4f0a4..27e75cfdc490 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -279,36 +279,37 @@ struct bufdesc_ex { #define FEC_ENET_MAX_TX_QS 3 #define FEC_ENET_MAX_RX_QS 3 -#define FEC_R_DES_START(X) ((X == 1) ? FEC_R_DES_START_1 : \ - ((X == 2) ? \ +#define FEC_R_DES_START(X) (((X) == 1) ? FEC_R_DES_START_1 : \ + (((X) == 2) ? \ FEC_R_DES_START_2 : FEC_R_DES_START_0)) -#define FEC_X_DES_START(X) ((X == 1) ? FEC_X_DES_START_1 : \ - ((X == 2) ? \ +#define FEC_X_DES_START(X) (((X) == 1) ? FEC_X_DES_START_1 : \ + (((X) == 2) ? \ FEC_X_DES_START_2 : FEC_X_DES_START_0)) -#define FEC_R_DES_ACTIVE(X) ((X == 1) ? FEC_R_DES_ACTIVE_1 : \ - ((X == 2) ? \ +#define FEC_R_DES_ACTIVE(X) (((X) == 1) ? FEC_R_DES_ACTIVE_1 : \ + (((X) == 2) ? \ FEC_R_DES_ACTIVE_2 : FEC_R_DES_ACTIVE_0)) -#define FEC_X_DES_ACTIVE(X) ((X == 1) ? FEC_X_DES_ACTIVE_1 : \ - ((X == 2) ? \ +#define FEC_X_DES_ACTIVE(X) (((X) == 1) ? FEC_X_DES_ACTIVE_1 : \ + (((X) == 2) ? \ FEC_X_DES_ACTIVE_2 : FEC_X_DES_ACTIVE_0)) -#define FEC_DMA_CFG(X) ((X == 2) ? FEC_DMA_CFG_2 : FEC_DMA_CFG_1) +#define FEC_DMA_CFG(X) (((X) == 2) ? FEC_DMA_CFG_2 : FEC_DMA_CFG_1) #define DMA_CLASS_EN (1 << 16) -#define FEC_RCMR(X) ((X == 2) ? FEC_RCMR_2 : FEC_RCMR_1) +#define FEC_RCMR(X) (((X) == 2) ? FEC_RCMR_2 : FEC_RCMR_1) #define IDLE_SLOPE_MASK 0xffff #define IDLE_SLOPE_1 0x200 /* BW fraction: 0.5 */ #define IDLE_SLOPE_2 0x200 /* BW fraction: 0.5 */ -#define IDLE_SLOPE(X) ((X == 1) ? (IDLE_SLOPE_1 & IDLE_SLOPE_MASK) : \ +#define IDLE_SLOPE(X) (((X) == 1) ? \ + (IDLE_SLOPE_1 & IDLE_SLOPE_MASK) : \ (IDLE_SLOPE_2 & IDLE_SLOPE_MASK)) #define RCMR_MATCHEN (0x1 << 16) -#define RCMR_CMP_CFG(v, n) ((v & 0x7) << (n << 2)) +#define RCMR_CMP_CFG(v, n) (((v) & 0x7) << (n << 2)) #define RCMR_CMP_1 (RCMR_CMP_CFG(0, 0) | RCMR_CMP_CFG(1, 1) | \ RCMR_CMP_CFG(2, 2) | RCMR_CMP_CFG(3, 3)) #define RCMR_CMP_2 (RCMR_CMP_CFG(4, 0) | RCMR_CMP_CFG(5, 1) | \ RCMR_CMP_CFG(6, 2) | RCMR_CMP_CFG(7, 3)) -#define RCMR_CMP(X) ((X == 1) ? RCMR_CMP_1 : RCMR_CMP_2) -#define FEC_TX_BD_FTYPE(X) ((X & 0xf) << 20) +#define RCMR_CMP(X) (((X) == 1) ? RCMR_CMP_1 : RCMR_CMP_2) +#define FEC_TX_BD_FTYPE(X) (((X) & 0xf) << 20) /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it it best @@ -359,7 +360,7 @@ struct bufdesc_ex { /* ENET interrupt coalescing macro define */ #define FEC_ITR_CLK_SEL (0x1 << 30) #define FEC_ITR_EN (0x1 << 31) -#define FEC_ITR_ICFT(X) ((X & 0xff) << 20) +#define FEC_ITR_ICFT(X) (((X) & 0xff) << 20) #define FEC_ITR_ICTT(X) ((X) & 0xffff) #define FEC_ITR_ICFT_DEFAULT 200 /* Set 200 frame count threshold */ #define FEC_ITR_ICTT_DEFAULT 1000 /* Set 1000us timer threshold */ -- GitLab From 217b5844e279c279414fdeb47a89959fad1fbc8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:20 +0100 Subject: [PATCH 5220/9457] net: fec: change type of 'bufdesc_ex' to bool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fep->bufdesc_ex is treated as a boolean value, thus declare it as such. Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 2 +- drivers/net/ethernet/freescale/fec_main.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 27e75cfdc490..14188133db95 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -502,7 +502,7 @@ struct fec_enet_private { int speed; struct completion mdio_done; int irq[FEC_IRQ_NUM]; - int bufdesc_ex; + bool bufdesc_ex; int pause_flag; struct napi_struct napi; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 3dca494797bd..f3a6379c12a2 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3184,8 +3184,6 @@ fec_probe(struct platform_device *pdev) fep->pdev = pdev; fep->dev_id = dev_id++; - fep->bufdesc_ex = 0; - platform_set_drvdata(pdev, ndev); phy_node = of_parse_phandle(np, "phy-handle", 0); @@ -3243,7 +3241,7 @@ fec_probe(struct platform_device *pdev) pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; if (IS_ERR(fep->clk_ptp)) { fep->clk_ptp = NULL; - fep->bufdesc_ex = 0; + fep->bufdesc_ex = false; } ret = fec_enet_clk_enable(ndev, true); -- GitLab From 6b7e4008389c8cb8140a9aef424b10048c44da39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:21 +0100 Subject: [PATCH 5221/9457] net: fec: improve access to quirk flags by copying them into fec_enet_private struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 1 + drivers/net/ethernet/freescale/fec_main.c | 106 ++++++++-------------- 2 files changed, 39 insertions(+), 68 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 14188133db95..7aa9388a3aa8 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -504,6 +504,7 @@ struct fec_enet_private { int irq[FEC_IRQ_NUM]; bool bufdesc_ex; int pause_flag; + u32 quirks; struct napi_struct napi; int csum_flags; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index f3a6379c12a2..3884dd9de3a4 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -361,8 +361,6 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq, struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct bufdesc *bdp = txq->cur_tx; struct bufdesc_ex *ebdp; int nr_frags = skb_shinfo(skb)->nr_frags; @@ -398,7 +396,7 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq, } if (fep->bufdesc_ex) { - if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) + if (fep->quirks & FEC_QUIRK_HAS_AVB) estatus |= FEC_TX_BD_FTYPE(queue); if (skb->ip_summed == CHECKSUM_PARTIAL) estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS; @@ -410,11 +408,11 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq, index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep); if (((unsigned long) bufaddr) & fep->tx_align || - id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) { + fep->quirks & FEC_QUIRK_SWAP_FRAME) { memcpy(txq->tx_bounce[index], bufaddr, frag_len); bufaddr = txq->tx_bounce[index]; - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) + if (fep->quirks & FEC_QUIRK_SWAP_FRAME) swap_buffer(bufaddr, frag_len); } @@ -450,8 +448,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb, struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); int nr_frags = skb_shinfo(skb)->nr_frags; struct bufdesc *bdp, *last_bdp; void *bufaddr; @@ -490,11 +486,11 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq, queue = skb_get_queue_mapping(skb); index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep); if (((unsigned long) bufaddr) & fep->tx_align || - id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) { + fep->quirks & FEC_QUIRK_SWAP_FRAME) { memcpy(txq->tx_bounce[index], skb->data, buflen); bufaddr = txq->tx_bounce[index]; - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) + if (fep->quirks & FEC_QUIRK_SWAP_FRAME) swap_buffer(bufaddr, buflen); } @@ -529,7 +525,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq, fep->hwts_tx_en)) skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) + if (fep->quirks & FEC_QUIRK_HAS_AVB) estatus |= FEC_TX_BD_FTYPE(queue); if (skb->ip_summed == CHECKSUM_PARTIAL) @@ -573,8 +569,6 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb, int size, bool last_tcp, bool is_last) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc); unsigned short queue = skb_get_queue_mapping(skb); unsigned short status; @@ -587,11 +581,11 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb, status |= (BD_ENET_TX_TC | BD_ENET_TX_READY); if (((unsigned long) data) & fep->tx_align || - id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) { + fep->quirks & FEC_QUIRK_SWAP_FRAME) { memcpy(txq->tx_bounce[index], data, size); data = txq->tx_bounce[index]; - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) + if (fep->quirks & FEC_QUIRK_SWAP_FRAME) swap_buffer(data, size); } @@ -607,7 +601,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb, bdp->cbd_bufaddr = addr; if (fep->bufdesc_ex) { - if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) + if (fep->quirks & FEC_QUIRK_HAS_AVB) estatus |= FEC_TX_BD_FTYPE(queue); if (skb->ip_summed == CHECKSUM_PARTIAL) estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS; @@ -635,8 +629,6 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq, struct bufdesc *bdp, int index) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc); unsigned short queue = skb_get_queue_mapping(skb); @@ -652,11 +644,11 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq, bufaddr = txq->tso_hdrs + index * TSO_HEADER_SIZE; dmabuf = txq->tso_hdrs_dma + index * TSO_HEADER_SIZE; if (((unsigned long)bufaddr) & fep->tx_align || - id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) { + fep->quirks & FEC_QUIRK_SWAP_FRAME) { memcpy(txq->tx_bounce[index], skb->data, hdr_len); bufaddr = txq->tx_bounce[index]; - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) + if (fep->quirks & FEC_QUIRK_SWAP_FRAME) swap_buffer(bufaddr, hdr_len); dmabuf = dma_map_single(&fep->pdev->dev, bufaddr, @@ -673,7 +665,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq, bdp->cbd_datlen = hdr_len; if (fep->bufdesc_ex) { - if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) + if (fep->quirks & FEC_QUIRK_HAS_AVB) estatus |= FEC_TX_BD_FTYPE(queue); if (skb->ip_summed == CHECKSUM_PARTIAL) estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS; @@ -698,8 +690,6 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, struct tso_t tso; unsigned int index = 0; int ret; - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep, txq)) { dev_kfree_skb_any(skb); @@ -761,7 +751,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, txq->cur_tx = bdp; /* Trigger transmission start */ - if (!(id_entry->driver_data & FEC_QUIRK_ERR007885) || + if (!(fep->quirks & FEC_QUIRK_ERR007885) || !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) || !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) || !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) || @@ -924,8 +914,6 @@ static void fec_restart(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); u32 val; u32 temp_mac[2]; u32 rcntl = OPT_FRAME_SIZE | 0x04; @@ -935,7 +923,7 @@ fec_restart(struct net_device *ndev) * For i.MX6SX SOC, enet use AXI bus, we use disable MAC * instead of reset MAC itself. */ - if (id_entry && id_entry->driver_data & FEC_QUIRK_HAS_AVB) { + if (fep->quirks & FEC_QUIRK_HAS_AVB) { writel(0, fep->hwp + FEC_ECNTRL); } else { writel(1, fep->hwp + FEC_ECNTRL); @@ -946,7 +934,7 @@ fec_restart(struct net_device *ndev) * enet-mac reset will reset mac address registers too, * so need to reconfigure it. */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + if (fep->quirks & FEC_QUIRK_ENET_MAC) { memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN); writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW); writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH); @@ -992,7 +980,7 @@ fec_restart(struct net_device *ndev) * The phy interface and speed need to get configured * differently on enet-mac. */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + if (fep->quirks & FEC_QUIRK_ENET_MAC) { /* Enable flow control and length check */ rcntl |= 0x40000000 | 0x00000020; @@ -1015,7 +1003,7 @@ fec_restart(struct net_device *ndev) } } else { #ifdef FEC_MIIGSK_ENR - if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) { + if (fep->quirks & FEC_QUIRK_USE_GASKET) { u32 cfgr; /* disable the gasket and wait */ writel(0, fep->hwp + FEC_MIIGSK_ENR); @@ -1068,7 +1056,7 @@ fec_restart(struct net_device *ndev) writel(0, fep->hwp + FEC_HASH_TABLE_LOW); #endif - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + if (fep->quirks & FEC_QUIRK_ENET_MAC) { /* enable ENET endian swap */ ecntl |= (1 << 8); /* enable ENET store and forward mode */ @@ -1102,8 +1090,6 @@ static void fec_stop(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8); /* We cannot expect a graceful transmit stop without link !!! */ @@ -1118,7 +1104,7 @@ fec_stop(struct net_device *ndev) * For i.MX6SX SOC, enet use AXI bus, we use disable MAC * instead of reset MAC itself. */ - if (id_entry && id_entry->driver_data & FEC_QUIRK_HAS_AVB) { + if (fep->quirks & FEC_QUIRK_HAS_AVB) { writel(0, fep->hwp + FEC_ECNTRL); } else { writel(1, fep->hwp + FEC_ECNTRL); @@ -1128,7 +1114,7 @@ fec_stop(struct net_device *ndev) writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); /* We have to keep ENET enabled to have MII interrupt stay working */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + if (fep->quirks & FEC_QUIRK_ENET_MAC) { writel(2, fep->hwp + FEC_ECNTRL); writel(rmii_mode, fep->hwp + FEC_R_CNTRL); } @@ -1350,8 +1336,6 @@ static int fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct fec_enet_priv_rx_q *rxq; struct bufdesc *bdp; unsigned short status; @@ -1365,7 +1349,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) u16 vlan_tag; int index = 0; bool is_copybreak; - bool need_swap = id_entry->driver_data & FEC_QUIRK_SWAP_FRAME; + bool need_swap = fep->quirks & FEC_QUIRK_SWAP_FRAME; #ifdef CONFIG_M532x flush_cache_all(); @@ -1880,8 +1864,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) static int fec_enet_mii_probe(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct phy_device *phy_dev = NULL; char mdio_bus_id[MII_BUS_ID_SIZE]; char phy_name[MII_BUS_ID_SIZE + 3]; @@ -1927,7 +1909,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) } /* mask with MAC supported features */ - if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) { + if (fep->quirks & FEC_QUIRK_HAS_GBIT) { phy_dev->supported &= PHY_GBIT_FEATURES; phy_dev->supported &= ~SUPPORTED_1000baseT_Half; #if !defined(CONFIG_M5272) @@ -1955,8 +1937,6 @@ static int fec_enet_mii_init(struct platform_device *pdev) static struct mii_bus *fec0_mii_bus; struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct device_node *node; int err = -ENXIO, i; @@ -1976,7 +1956,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) * mdio interface in board design, and need to be configured by * fec0 mii_bus. */ - if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { + if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { /* fec1 uses fec0 mii_bus */ if (mii_cnt && fec0_mii_bus) { fep->mii_bus = fec0_mii_bus; @@ -1997,7 +1977,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) * document. */ fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), 5000000); - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) + if (fep->quirks & FEC_QUIRK_ENET_MAC) fep->phy_speed--; fep->phy_speed <<= 1; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); @@ -2039,7 +2019,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) mii_cnt++; /* save fec0 mii_bus */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) + if (fep->quirks & FEC_QUIRK_ENET_MAC) fec0_mii_bus = fep->mii_bus; return 0; @@ -2308,11 +2288,9 @@ static int fec_enet_us_to_itr_clock(struct net_device *ndev, int us) static void fec_enet_itr_coal_set(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); int rx_itr, tx_itr; - if (!(id_entry->driver_data & FEC_QUIRK_HAS_AVB)) + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) return; /* Must be greater than zero to avoid unpredictable behavior */ @@ -2347,10 +2325,8 @@ static int fec_enet_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); - if (!(id_entry->driver_data & FEC_QUIRK_HAS_AVB)) + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) return -EOPNOTSUPP; ec->rx_coalesce_usecs = fep->rx_time_itr; @@ -2366,12 +2342,9 @@ static int fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); - unsigned int cycle; - if (!(id_entry->driver_data & FEC_QUIRK_HAS_AVB)) + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) return -EOPNOTSUPP; if (ec->rx_max_coalesced_frames > 255) { @@ -2951,8 +2924,6 @@ static const struct net_device_ops fec_netdev_ops = { static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct fec_enet_priv_tx_q *txq; struct fec_enet_priv_rx_q *rxq; struct bufdesc *cbd_base; @@ -3031,11 +3002,11 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT); - if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) + if (fep->quirks & FEC_QUIRK_HAS_VLAN) /* enable hw VLAN support */ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; - if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) { + if (fep->quirks & FEC_QUIRK_HAS_CSUM) { ndev->gso_max_segs = FEC_MAX_TSO_SEGS; /* enable hw accelerator */ @@ -3044,7 +3015,7 @@ static int fec_enet_init(struct net_device *ndev) fep->csum_flags |= FLAG_RX_CSUM_ENABLED; } - if (id_entry->driver_data & FEC_QUIRK_HAS_AVB) { + if (fep->quirks & FEC_QUIRK_HAS_AVB) { fep->tx_align = 0; fep->rx_align = 0x3f; } @@ -3144,10 +3115,6 @@ fec_probe(struct platform_device *pdev) int num_tx_qs; int num_rx_qs; - of_id = of_match_device(fec_dt_ids, &pdev->dev); - if (of_id) - pdev->id_entry = of_id->data; - fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); /* Init network device */ @@ -3161,13 +3128,17 @@ fec_probe(struct platform_device *pdev) /* setup board info structure */ fep = netdev_priv(ndev); + of_id = of_match_device(fec_dt_ids, &pdev->dev); + if (of_id) + pdev->id_entry = of_id->data; + fep->quirks = pdev->id_entry->driver_data; + fep->num_rx_queues = num_rx_qs; fep->num_tx_queues = num_tx_qs; #if !defined(CONFIG_M5272) /* default enable pause frame auto negotiation */ - if (pdev->id_entry && - (pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT)) + if (fep->quirks & FEC_QUIRK_HAS_GBIT) fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG; #endif @@ -3236,9 +3207,8 @@ fec_probe(struct platform_device *pdev) if (IS_ERR(fep->clk_ref)) fep->clk_ref = NULL; + fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX; fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp"); - fep->bufdesc_ex = - pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX; if (IS_ERR(fep->clk_ptp)) { fep->clk_ptp = NULL; fep->bufdesc_ex = false; -- GitLab From e453789a66ab152ecee80ded3279539d826c48ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:22 +0100 Subject: [PATCH 5222/9457] net: fec: use swab32s() instead of cpu_to_be32() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when swap_buffer() is being called, we know for sure, that we need to byte swap the data. Furthermore, this function is called for swapping data in both directions. Thus cpu_to_be32() is semantically not correct for all use cases. Use swab32s() to reflect this. Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 3884dd9de3a4..f73fee781e0b 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -293,7 +293,7 @@ static void *swap_buffer(void *bufaddr, int len) unsigned int *buf = bufaddr; for (i = 0; i < DIV_ROUND_UP(len, 4); i++, buf++) - *buf = cpu_to_be32(*buf); + swab32s(buf); return bufaddr; } -- GitLab From 7b487d070a0edea01816135d3b1a9c8f2c069657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:23 +0100 Subject: [PATCH 5223/9457] net: fec: simplify loop counter handling in swap_buffer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate the DIV_ROUND_UP() and change the loop counter increment to 4 instead. This results in saving 6 instructions in the functions assembly code. Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index f73fee781e0b..dbccdf37e2e4 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -292,7 +292,7 @@ static void *swap_buffer(void *bufaddr, int len) int i; unsigned int *buf = bufaddr; - for (i = 0; i < DIV_ROUND_UP(len, 4); i++, buf++) + for (i = 0; i < len; i += 4, buf++) swab32s(buf); return bufaddr; -- GitLab From c20e599bb57bf12177cd5404d124cae0b6fc7970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Mon, 17 Nov 2014 10:51:24 +0100 Subject: [PATCH 5224/9457] net: fec: remove unused return value from swap_buffer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return value of swap_buffer() is not used by any caller, thus remove it. Signed-off-by: Lothar Waßmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index dbccdf37e2e4..1b6d26b00826 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -287,15 +287,13 @@ static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep, return entries > 0 ? entries : entries + txq->tx_ring_size; } -static void *swap_buffer(void *bufaddr, int len) +static void swap_buffer(void *bufaddr, int len) { int i; unsigned int *buf = bufaddr; for (i = 0; i < len; i += 4, buf++) swab32s(buf); - - return bufaddr; } static void swap_buffer2(void *dst_buf, void *src_buf, int len) -- GitLab From 6d80c4732bbbd8a76057337cb758ed64cf34f804 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 21:51:21 +0100 Subject: [PATCH 5225/9457] dccp: kerneldoc warning fixes Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dccp/feat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 9733ddbc96cb..1704948e6a12 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -478,7 +478,7 @@ static struct dccp_feat_entry * * @fn_list: feature-negotiation list to update * @feat: one of %dccp_feature_numbers * @local: whether local (1) or remote (0) @feat_num is meant - * @needs_mandatory: whether to use Mandatory feature negotiation options + * @mandatory: whether to use Mandatory feature negotiation options * @fval: pointer to NN/SP value to be inserted (will be copied) */ static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local, @@ -1050,7 +1050,7 @@ static u8 dccp_feat_prefer(u8 preferred_value, u8 *array, u8 array_len) /** * dccp_feat_reconcile - Reconcile SP preference lists - * @fval: SP list to reconcile into + * @fv: SP list to reconcile into * @arr: received SP preference list * @len: length of @arr in bytes * @is_server: whether this side is the server (and @fv is the server's list) -- GitLab From 54da7996b85b3a3e7388c5010ec0f1d866fc4830 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 21:54:58 +0100 Subject: [PATCH 5226/9457] dccp: remove blank lines between function/EXPORT_SYMBOL See Documentation/CodingStyle chapter 6. Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dccp/ipv4.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 6ca645c4b48e..e45b968613a4 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -140,7 +140,6 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_dport = 0; goto out; } - EXPORT_SYMBOL_GPL(dccp_v4_connect); /* @@ -376,7 +375,6 @@ void dccp_v4_send_check(struct sock *sk, struct sk_buff *skb) inet->inet_saddr, inet->inet_daddr); } - EXPORT_SYMBOL_GPL(dccp_v4_send_check); static inline u64 dccp_v4_init_sequence(const struct sk_buff *skb) @@ -444,7 +442,6 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, dccp_done(newsk); goto exit; } - EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock); static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) @@ -670,7 +667,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); return -1; } - EXPORT_SYMBOL_GPL(dccp_v4_conn_request); int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) @@ -729,7 +725,6 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) kfree_skb(skb); return 0; } - EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); /** @@ -802,7 +797,6 @@ int dccp_invalid_packet(struct sk_buff *skb) return 0; } - EXPORT_SYMBOL_GPL(dccp_invalid_packet); /* this is called when real data arrives */ -- GitLab From 02c31d2e56dfc6e65ebf5891cf6953e3391ce590 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 21:58:37 +0100 Subject: [PATCH 5227/9457] dccp: replace min/casting by min_t Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dccp/ackvec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index ba07824af4c0..bd9e718c2a20 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -218,7 +218,7 @@ static void dccp_ackvec_add_new(struct dccp_ackvec *av, u32 num_packets, * different underlying data structure. */ for (num_packets = num_cells = 1; lost_packets; ++num_cells) { - u8 len = min(lost_packets, (u32)DCCPAV_MAX_RUNLEN); + u8 len = min_t(u32, lost_packets, DCCPAV_MAX_RUNLEN); av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, 1); av->av_buf[av->av_buf_head] = DCCPAV_NOT_RECEIVED | len; -- GitLab From a77b634367d4987718012b896c3d19c4cd7e8b4c Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 22:00:22 +0100 Subject: [PATCH 5228/9457] dccp: spelling s/reseting/resetting Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/dccp/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dccp/input.c b/net/dccp/input.c index 3c8ec7d4a34e..3bd14e885396 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -537,7 +537,7 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk, case DCCP_PKT_DATAACK: case DCCP_PKT_ACK: /* - * FIXME: we should be reseting the PARTOPEN (DELACK) timer + * FIXME: we should be resetting the PARTOPEN (DELACK) timer * here but only if we haven't used the DELACK timer for * something else, like sending a delayed ack for a TIMESTAMP * echo, etc, for now were not clearing it, sending an extra -- GitLab From 1d2398dc7c78f32c50ee23a21ad9141e5e08a2ed Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 22:04:03 +0100 Subject: [PATCH 5229/9457] net: fix spelling for synchronized Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/core/dev_addr_lists.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index b6b230600b97..c0548d268e1a 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -278,8 +278,8 @@ int __hw_addr_sync_dev(struct netdev_hw_addr_list *list, EXPORT_SYMBOL(__hw_addr_sync_dev); /** - * __hw_addr_unsync_dev - Remove synchonized addresses from device - * @list: address list to remove syncronized addresses from + * __hw_addr_unsync_dev - Remove synchronized addresses from device + * @list: address list to remove synchronized addresses from * @dev: device to sync * @unsync: function to call if address should be removed * -- GitLab From e56f735913c8d3c417c65c7e7fcdd65011f8d96f Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 22:08:22 +0100 Subject: [PATCH 5230/9457] net/core: include linux/types.h instead of asm/types.h Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/core/link_watch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/link_watch.c b/net/core/link_watch.c index bd0767e6b2b3..49a9e3e06c08 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include enum lw_bits { -- GitLab From 54aeba7f06323e04d59a6053ee3c6023079667b2 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 17 Nov 2014 22:23:17 +0100 Subject: [PATCH 5231/9457] dev_ioctl: use sizeof(x) instead of sizeof x Also remove spaces after cast. Signed-off-by: Fabian Frederick Signed-off-by: David S. Miller --- net/core/dev_ioctl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 72e899a3efda..b94b1d293506 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -142,10 +142,12 @@ static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm case SIOCGIFHWADDR: if (!dev->addr_len) - memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data); + memset(ifr->ifr_hwaddr.sa_data, 0, + sizeof(ifr->ifr_hwaddr.sa_data)); else memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr, - min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); + min(sizeof(ifr->ifr_hwaddr.sa_data), + (size_t)dev->addr_len)); ifr->ifr_hwaddr.sa_family = dev->type; return 0; @@ -265,7 +267,8 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) if (ifr->ifr_hwaddr.sa_family != dev->type) return -EINVAL; memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, - min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); + min(sizeof(ifr->ifr_hwaddr.sa_data), + (size_t)dev->addr_len)); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); return 0; -- GitLab From e3e3217029a35c579bf100998b43976d0b1cb8d7 Mon Sep 17 00:00:00 2001 From: Rick Jones Date: Mon, 17 Nov 2014 14:04:29 -0800 Subject: [PATCH 5232/9457] icmp: Remove some spurious dropped packet profile hits from the ICMP path If icmp_rcv() has successfully processed the incoming ICMP datagram, we should use consume_skb() rather than kfree_skb() because a hit on the likes of perf -e skb:kfree_skb is not called-for. Signed-off-by: Rick Jones Signed-off-by: David S. Miller --- include/net/ping.h | 2 +- net/ipv4/icmp.c | 43 ++++++++++++++++++++++++++++--------------- net/ipv4/ping.c | 6 +++--- net/ipv6/icmp.c | 12 ++++++++++-- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/include/net/ping.h b/include/net/ping.h index 026479b61a2d..f074060bc5de 100644 --- a/include/net/ping.h +++ b/include/net/ping.h @@ -82,7 +82,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len); int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); -void ping_rcv(struct sk_buff *skb); +bool ping_rcv(struct sk_buff *skb); #ifdef CONFIG_PROC_FS struct ping_seq_afinfo { diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 36b7bfa609d6..36f5584d93c5 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -190,7 +190,7 @@ EXPORT_SYMBOL(icmp_err_convert); */ struct icmp_control { - void (*handler)(struct sk_buff *skb); + bool (*handler)(struct sk_buff *skb); short error; /* This ICMP is classed as an error message */ }; @@ -746,7 +746,7 @@ static bool icmp_tag_validation(int proto) * ICMP_PARAMETERPROB. */ -static void icmp_unreach(struct sk_buff *skb) +static bool icmp_unreach(struct sk_buff *skb) { const struct iphdr *iph; struct icmphdr *icmph; @@ -839,10 +839,10 @@ static void icmp_unreach(struct sk_buff *skb) icmp_socket_deliver(skb, info); out: - return; + return true; out_err: ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); - goto out; + return false; } @@ -850,17 +850,20 @@ static void icmp_unreach(struct sk_buff *skb) * Handle ICMP_REDIRECT. */ -static void icmp_redirect(struct sk_buff *skb) +static bool icmp_redirect(struct sk_buff *skb) { if (skb->len < sizeof(struct iphdr)) { ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS); - return; + return false; } - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - return; + if (!pskb_may_pull(skb, sizeof(struct iphdr))) { + /* there aught to be a stat */ + return false; + } icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway); + return true; } /* @@ -875,7 +878,7 @@ static void icmp_redirect(struct sk_buff *skb) * See also WRT handling of options once they are done and working. */ -static void icmp_echo(struct sk_buff *skb) +static bool icmp_echo(struct sk_buff *skb) { struct net *net; @@ -891,6 +894,8 @@ static void icmp_echo(struct sk_buff *skb) icmp_param.head_len = sizeof(struct icmphdr); icmp_reply(&icmp_param, skb); } + /* should there be an ICMP stat for ignored echos? */ + return true; } /* @@ -900,7 +905,7 @@ static void icmp_echo(struct sk_buff *skb) * MUST be accurate to a few minutes. * MUST be updated at least at 15Hz. */ -static void icmp_timestamp(struct sk_buff *skb) +static bool icmp_timestamp(struct sk_buff *skb) { struct timespec tv; struct icmp_bxm icmp_param; @@ -927,15 +932,17 @@ static void icmp_timestamp(struct sk_buff *skb) icmp_param.data_len = 0; icmp_param.head_len = sizeof(struct icmphdr) + 12; icmp_reply(&icmp_param, skb); -out: - return; + return true; + out_err: ICMP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); - goto out; + return false; } -static void icmp_discard(struct sk_buff *skb) +static bool icmp_discard(struct sk_buff *skb) { + /* pretend it was a success */ + return true; } /* @@ -946,6 +953,7 @@ int icmp_rcv(struct sk_buff *skb) struct icmphdr *icmph; struct rtable *rt = skb_rtable(skb); struct net *net = dev_net(rt->dst.dev); + bool success; if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { struct sec_path *sp = skb_sec_path(skb); @@ -1012,7 +1020,12 @@ int icmp_rcv(struct sk_buff *skb) } } - icmp_pointers[icmph->type].handler(skb); + success = icmp_pointers[icmph->type].handler(skb); + + if (success) { + consume_skb(skb); + return 0; + } drop: kfree_skb(skb); diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 736236c3e554..ce2920f5bef3 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -955,7 +955,7 @@ EXPORT_SYMBOL_GPL(ping_queue_rcv_skb); * All we need to do is get the socket. */ -void ping_rcv(struct sk_buff *skb) +bool ping_rcv(struct sk_buff *skb) { struct sock *sk; struct net *net = dev_net(skb->dev); @@ -974,11 +974,11 @@ void ping_rcv(struct sk_buff *skb) pr_debug("rcv on socket %p\n", sk); ping_queue_rcv_skb(sk, skb_get(skb)); sock_put(sk); - return; + return true; } pr_debug("no socket, dropping\n"); - /* We're called from icmp_rcv(). kfree_skb() is done there. */ + return false; } EXPORT_SYMBOL_GPL(ping_rcv); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 092934032077..39b3ff97a504 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -679,6 +679,7 @@ static int icmpv6_rcv(struct sk_buff *skb) const struct in6_addr *saddr, *daddr; struct icmp6hdr *hdr; u8 type; + bool success = false; if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { struct sec_path *sp = skb_sec_path(skb); @@ -726,7 +727,7 @@ static int icmpv6_rcv(struct sk_buff *skb) break; case ICMPV6_ECHO_REPLY: - ping_rcv(skb); + success = ping_rcv(skb); break; case ICMPV6_PKT_TOOBIG: @@ -790,7 +791,14 @@ static int icmpv6_rcv(struct sk_buff *skb) icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu); } - kfree_skb(skb); + /* until the v6 path can be better sorted assume failure and + * preserve the status quo behaviour for the rest of the paths to here + */ + if (success) + consume_skb(skb); + else + kfree_skb(skb); + return 0; csum_error: -- GitLab From 08bb7beae7fe102939fe5931222fc09e10d27cda Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Maneyrol Date: Sun, 16 Nov 2014 22:45:43 +0800 Subject: [PATCH 5233/9457] HID: i2c-hid: print the correct data in dbg msg Report is received in "buffer"; fix the following i2c_hid_dbg() to dump data from the correct pointer. Signed-off-by: Jean-Baptiste Maneyrol [Antonio Borneo: cleanup and rebase to v3.17] Signed-off-by: Antonio Borneo Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 747d54421e73..933bf1052ec0 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -437,7 +437,7 @@ static void i2c_hid_init_report(struct hid_report *report, u8 *buffer, report->id, buffer, size)) return; - i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf); + i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, buffer); ret_size = buffer[0] | (buffer[1] << 8); -- GitLab From b2b49ccbdd547135c69371ed066cffa44912060a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 18 Nov 2014 01:43:42 +0100 Subject: [PATCH 5234/9457] PM: Kconfig: Set PM_RUNTIME if PM_SLEEP is selected The number of and dependencies between high-level power management Kconfig options make life much harder than necessary. Several conbinations of them have to be tested and supported, even though some of those combinations are very rarely used in practice (if they are used in practice at all). Moreover, the fact that we have separate independent Kconfig options for runtime PM and system suspend is a serious obstacle for integration between the two frameworks. To overcome these difficulties, always select PM_RUNTIME if PM_SLEEP is set. Among other things, this will allow system suspend callbacks provided by bus types and device drivers to rely on the runtime PM framework regardless of the kernel configuration. Enthusiastically-acked-by: Kevin Hilman Tested-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- kernel/power/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 3d39cc0228e9..95d712e3677d 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -94,6 +94,7 @@ config PM_STD_PARTITION config PM_SLEEP def_bool y depends on SUSPEND || HIBERNATE_CALLBACKS + select PM_RUNTIME config PM_SLEEP_SMP def_bool y -- GitLab From 6d20aff83c24e9a7f15fffe4be36ed33d24465da Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 17 Nov 2014 16:06:55 -0800 Subject: [PATCH 5235/9457] f2fs: fix to call put_page at the error handling routine The locked page should be released before returning the function. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 053d114f0528..f26fb87da163 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -141,8 +141,8 @@ int f2fs_convert_inline_inode(struct inode *inode) ipage = get_node_page(sbi, inode->i_ino); if (IS_ERR(ipage)) { - f2fs_unlock_op(sbi); - return PTR_ERR(ipage); + err = PTR_ERR(ipage); + goto out; } set_new_dnode(&dn, inode, ipage, ipage, 0); @@ -151,7 +151,7 @@ int f2fs_convert_inline_inode(struct inode *inode) err = f2fs_convert_inline_page(&dn, page); f2fs_put_dnode(&dn); - +out: f2fs_unlock_op(sbi); f2fs_put_page(page, 1); -- GitLab From 8cdcb71322ec21aaee90117b0c01d576851a8faa Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 17 Nov 2014 16:14:11 -0800 Subject: [PATCH 5236/9457] f2fs: put the inode page when error was occurred We should put the inode page when error was occurred. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8f164432408e..12dd58aa569a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -963,22 +963,22 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, } else if (page->index == 0) { err = f2fs_convert_inline_page(&dn, page); if (err) - goto unlock_fail; + goto put_fail; } else { struct page *p = grab_cache_page(inode->i_mapping, 0); if (!p) { err = -ENOMEM; - goto unlock_fail; + goto put_fail; } err = f2fs_convert_inline_page(&dn, p); f2fs_put_page(p, 1); if (err) - goto unlock_fail; + goto put_fail; } } err = f2fs_reserve_block(&dn, index); if (err) - goto unlock_fail; + goto put_fail; put_next: f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); @@ -1021,6 +1021,8 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, clear_cold_data(page); return 0; +put_fail: + f2fs_put_dnode(&dn); unlock_fail: f2fs_unlock_op(sbi); f2fs_put_page(page, 1); -- GitLab From a9ce7c36aa4256019180c590d60e2fad7431c749 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 17 Nov 2014 23:08:24 -0500 Subject: [PATCH 5237/9457] tracing: Fix race of function probes counting The function probe counting for traceon and traceoff suffered a race condition where if the probe was executing on two or more CPUs at the same time, it could decrement the counter by more than one when disabling (or enabling) the tracer only once. The way the traceon and traceoff probes are suppose to work is that they disable (or enable) tracing once per count. If a user were to echo 'schedule:traceoff:3' into set_ftrace_filter, then when the schedule function was called, it would disable tracing. But the count should only be decremented once (to 2). Then if the user enabled tracing again (via tracing_on file), the next call to schedule would disable tracing again and the count would be decremented to 1. But if multiple CPUS called schedule at the same time, it is possible that the count would be decremented more than once because of the simple "count--" used. By reading the count into a local variable and using memory barriers we can guarantee that the count would only be decremented once per disable (or enable). The stack trace probe had a similar race, but here the stack trace will decrement for each time it is called. But this had the read-modify- write race, where it could stack trace more than the number of times that was specified. This case we use a cmpxchg to stack trace only the number of times specified. The dump probes can still use the old "update_count()" function as they only run once, and that is controlled by the dump logic itself. Link: http://lkml.kernel.org/r/20141118134643.4b550ee4@gandalf.local.home Signed-off-by: Steven Rostedt --- kernel/trace/trace_functions.c | 117 +++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index a8e0c7666164..973db52eb070 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -261,37 +261,74 @@ static struct tracer function_trace __tracer_data = }; #ifdef CONFIG_DYNAMIC_FTRACE -static int update_count(void **data) +static void update_traceon_count(void **data, int on) { - unsigned long *count = (long *)data; + long *count = (long *)data; + long old_count = *count; - if (!*count) - return 0; + /* + * Tracing gets disabled (or enabled) once per count. + * This function can be called at the same time on mulitple CPUs. + * It is fine if both disable (or enable) tracing, as disabling + * (or enabling) the second time doesn't do anything as the + * state of the tracer is already disabled (or enabled). + * What needs to be synchronized in this case is that the count + * only gets decremented once, even if the tracer is disabled + * (or enabled) twice, as the second one is really a nop. + * + * The memory barriers guarantee that we only decrement the + * counter once. First the count is read to a local variable + * and a read barrier is used to make sure that it is loaded + * before checking if the tracer is in the state we want. + * If the tracer is not in the state we want, then the count + * is guaranteed to be the old count. + * + * Next the tracer is set to the state we want (disabled or enabled) + * then a write memory barrier is used to make sure that + * the new state is visible before changing the counter by + * one minus the old counter. This guarantees that another CPU + * executing this code will see the new state before seeing + * the new counter value, and would not do anthing if the new + * counter is seen. + * + * Note, there is no synchronization between this and a user + * setting the tracing_on file. But we currently don't care + * about that. + */ + if (!old_count) + return; - if (*count != -1) - (*count)--; + /* Make sure we see count before checking tracing state */ + smp_rmb(); - return 1; + if (on == !!tracing_is_on()) + return; + + if (on) + tracing_on(); + else + tracing_off(); + + /* unlimited? */ + if (old_count == -1) + return; + + /* Make sure tracing state is visible before updating count */ + smp_wmb(); + + *count = old_count - 1; } static void ftrace_traceon_count(unsigned long ip, unsigned long parent_ip, void **data) { - if (tracing_is_on()) - return; - - if (update_count(data)) - tracing_on(); + update_traceon_count(data, 1); } static void ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip, void **data) { - if (!tracing_is_on()) - return; - - if (update_count(data)) - tracing_off(); + update_traceon_count(data, 0); } static void @@ -330,11 +367,49 @@ ftrace_stacktrace(unsigned long ip, unsigned long parent_ip, void **data) static void ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip, void **data) { - if (!tracing_is_on()) - return; + long *count = (long *)data; + long old_count; + long new_count; - if (update_count(data)) - trace_dump_stack(STACK_SKIP); + /* + * Stack traces should only execute the number of times the + * user specified in the counter. + */ + do { + + if (!tracing_is_on()) + return; + + old_count = *count; + + if (!old_count) + return; + + /* unlimited? */ + if (old_count == -1) { + trace_dump_stack(STACK_SKIP); + return; + } + + new_count = old_count - 1; + new_count = cmpxchg(count, old_count, new_count); + if (new_count == old_count) + trace_dump_stack(STACK_SKIP); + + } while (new_count != old_count); +} + +static int update_count(void **data) +{ + unsigned long *count = (long *)data; + + if (!*count) + return 0; + + if (*count != -1) + (*count)--; + + return 1; } static void -- GitLab From a49ab6eeebe5624d51466969a7bac611231eede8 Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Mon, 17 Nov 2014 10:52:30 +0800 Subject: [PATCH 5238/9457] powerpc/pseries: Initialise nvram_pstore_info's buf_lock nvram_pstore_info's buf_lock is not initialized before registering, which is clearly incorrect. It causes some strange behavior when trying to obtain the lock during kdump process. On a UP configuration, the console stopped for a couple of seconds, then "lockup suspected" warning printed out, but then it continued to run. So try lock fails, and lockup reported, but then arch_spin_lock() passes. Signed-off-by: Li Zhong [mpe: Edited changelog] Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/nvram.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 11a3b617ef5d..054a0ed5c7ee 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -715,6 +715,8 @@ static int nvram_pstore_init(void) nvram_pstore_info.buf = oops_data; nvram_pstore_info.bufsize = oops_data_sz; + spin_lock_init(&nvram_pstore_info.buf_lock); + rc = pstore_register(&nvram_pstore_info); if (rc != 0) pr_err("nvram: pstore_register() failed, defaults to " -- GitLab From 86c558e8d3b774580faf8250092388d52cfde63e Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 14 Nov 2014 16:37:47 +0100 Subject: [PATCH 5239/9457] s390: fix ptrace of user area if the inferior uses vector registers The floating point registers of a process that uses vector instruction are not store into task->thread.fp_regs anymore but in the upper halves of the first 16 vector registers. The ptrace interface for the peeks and pokes to the user area fails to take this into account. Fix __peek_user[_compat] and __poke_user[_compat] to use the vector array for the floating pointer register if the process has one. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ptrace.c | 97 ++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 22 deletions(-) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 99a567b70d16..9eed6bb5c4a9 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -248,14 +248,27 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) */ tmp = 0; + } else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) { + /* + * floating point control reg. is in the thread structure + */ + tmp = child->thread.fp_regs.fpc; + tmp <<= BITS_PER_LONG - 32; + } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { - /* - * floating point regs. are stored in the thread structure + /* + * floating point regs. are either in child->thread.fp_regs + * or the child->thread.vxrs array */ - offset = addr - (addr_t) &dummy->regs.fp_regs; - tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); - if (addr == (addr_t) &dummy->regs.fp_regs.fpc) - tmp <<= BITS_PER_LONG - 32; + offset = addr - (addr_t) &dummy->regs.fp_regs.fprs; +#ifdef CONFIG_64BIT + if (child->thread.vxrs) + tmp = *(addr_t *) + ((addr_t) child->thread.vxrs + 2*offset); + else +#endif + tmp = *(addr_t *) + ((addr_t) &child->thread.fp_regs.fprs + offset); } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { /* @@ -383,16 +396,29 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) */ return 0; + } else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) { + /* + * floating point control reg. is in the thread structure + */ + if ((unsigned int) data != 0 || + test_fp_ctl(data >> (BITS_PER_LONG - 32))) + return -EINVAL; + child->thread.fp_regs.fpc = data >> (BITS_PER_LONG - 32); + } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* - * floating point regs. are stored in the thread structure + * floating point regs. are either in child->thread.fp_regs + * or the child->thread.vxrs array */ - if (addr == (addr_t) &dummy->regs.fp_regs.fpc) - if ((unsigned int) data != 0 || - test_fp_ctl(data >> (BITS_PER_LONG - 32))) - return -EINVAL; - offset = addr - (addr_t) &dummy->regs.fp_regs; - *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; + offset = addr - (addr_t) &dummy->regs.fp_regs.fprs; +#ifdef CONFIG_64BIT + if (child->thread.vxrs) + *(addr_t *)((addr_t) + child->thread.vxrs + 2*offset) = data; + else +#endif + *(addr_t *)((addr_t) + &child->thread.fp_regs.fprs + offset) = data; } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { /* @@ -611,12 +637,26 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr) */ tmp = 0; + } else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) { + /* + * floating point control reg. is in the thread structure + */ + tmp = child->thread.fp_regs.fpc; + } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* - * floating point regs. are stored in the thread structure + * floating point regs. are either in child->thread.fp_regs + * or the child->thread.vxrs array */ - offset = addr - (addr_t) &dummy32->regs.fp_regs; - tmp = *(__u32 *)((addr_t) &child->thread.fp_regs + offset); + offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs; +#ifdef CONFIG_64BIT + if (child->thread.vxrs) + tmp = *(__u32 *) + ((addr_t) child->thread.vxrs + 2*offset); + else +#endif + tmp = *(__u32 *) + ((addr_t) &child->thread.fp_regs.fprs + offset); } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { /* @@ -722,15 +762,28 @@ static int __poke_user_compat(struct task_struct *child, */ return 0; - } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { + } else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) { /* - * floating point regs. are stored in the thread structure + * floating point control reg. is in the thread structure */ - if (addr == (addr_t) &dummy32->regs.fp_regs.fpc && - test_fp_ctl(tmp)) + if (test_fp_ctl(tmp)) return -EINVAL; - offset = addr - (addr_t) &dummy32->regs.fp_regs; - *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp; + child->thread.fp_regs.fpc = data; + + } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { + /* + * floating point regs. are either in child->thread.fp_regs + * or the child->thread.vxrs array + */ + offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs; +#ifdef CONFIG_64BIT + if (child->thread.vxrs) + *(__u32 *)((addr_t) + child->thread.vxrs + 2*offset) = tmp; + else +#endif + *(__u32 *)((addr_t) + &child->thread.fp_regs.fprs + offset) = tmp; } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { /* -- GitLab From 4eafad7febd482092b331ea72c37274d745956be Mon Sep 17 00:00:00 2001 From: Alexey Ishchuk Date: Fri, 14 Nov 2014 14:27:58 +0100 Subject: [PATCH 5240/9457] s390/kernel: add system calls for PCI memory access Add the new __NR_s390_pci_mmio_write and __NR_s390_pci_mmio_read system calls to allow user space applications to access device PCI I/O memory pages on s390x platform. [ Martin Schwidefsky: some code beautification ] Signed-off-by: Alexey Ishchuk Signed-off-by: Martin Schwidefsky --- arch/s390/include/uapi/asm/unistd.h | 4 +- arch/s390/kernel/compat_wrapper.c | 2 + arch/s390/kernel/entry.h | 2 + arch/s390/kernel/syscalls.S | 2 + arch/s390/pci/Makefile | 2 +- arch/s390/pci/pci_mmio.c | 115 ++++++++++++++++++++++++++++ kernel/sys_ni.c | 2 + 7 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 arch/s390/pci/pci_mmio.c diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 4197c89c52d4..2b446cf0cc65 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -287,7 +287,9 @@ #define __NR_getrandom 349 #define __NR_memfd_create 350 #define __NR_bpf 351 -#define NR_syscalls 352 +#define __NR_s390_pci_mmio_write 352 +#define __NR_s390_pci_mmio_read 353 +#define NR_syscalls 354 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index c4f7a3d655b8..d7fa2f0f1425 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -218,3 +218,5 @@ COMPAT_SYSCALL_WRAP3(seccomp, unsigned int, op, unsigned int, flags, const char COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags) COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size); +COMPAT_SYSCALL_WRAP3(s390_pci_mmio_write, const unsigned long, mmio_addr, const void __user *, user_buffer, const size_t, length); +COMPAT_SYSCALL_WRAP3(s390_pci_mmio_read, const unsigned long, mmio_addr, void __user *, user_buffer, const size_t, length); diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 0554b9771c9f..8e61393c8275 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -74,4 +74,6 @@ struct old_sigaction; long sys_s390_personality(unsigned int personality); long sys_s390_runtime_instr(int command, int signum); +long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); +long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 9f7087fd58de..a2987243bc76 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -360,3 +360,5 @@ SYSCALL(sys_seccomp,sys_seccomp,compat_sys_seccomp) SYSCALL(sys_getrandom,sys_getrandom,compat_sys_getrandom) SYSCALL(sys_memfd_create,sys_memfd_create,compat_sys_memfd_create) /* 350 */ SYSCALL(sys_bpf,sys_bpf,compat_sys_bpf) +SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write) +SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read) diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile index a9e1dc4ae442..805d8b29193a 100644 --- a/arch/s390/pci/Makefile +++ b/arch/s390/pci/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_sysfs.o \ - pci_event.o pci_debug.o pci_insn.o + pci_event.o pci_debug.o pci_insn.o pci_mmio.o diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c new file mode 100644 index 000000000000..62c5ea6d8682 --- /dev/null +++ b/arch/s390/pci/pci_mmio.c @@ -0,0 +1,115 @@ +/* + * Access to PCI I/O memory from user space programs. + * + * Copyright IBM Corp. 2014 + * Author(s): Alexey Ishchuk + */ +#include +#include +#include +#include +#include +#include + +static long get_pfn(unsigned long user_addr, unsigned long access, + unsigned long *pfn) +{ + struct vm_area_struct *vma; + long ret; + + down_read(¤t->mm->mmap_sem); + ret = -EINVAL; + vma = find_vma(current->mm, user_addr); + if (!vma) + goto out; + ret = -EACCES; + if (!(vma->vm_flags & access)) + goto out; + ret = follow_pfn(vma, user_addr, pfn); +out: + up_read(¤t->mm->mmap_sem); + return ret; +} + +SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, + const void __user *, user_buffer, size_t, length) +{ + u8 local_buf[64]; + void __iomem *io_addr; + void *buf; + unsigned long pfn; + long ret; + + if (!zpci_is_enabled()) + return -ENODEV; + + if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) + return -EINVAL; + if (length > 64) { + buf = kmalloc(length, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } else + buf = local_buf; + + ret = get_pfn(mmio_addr, VM_WRITE, &pfn); + if (ret) + goto out; + io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); + + ret = -EFAULT; + if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) + goto out; + + if (copy_from_user(buf, user_buffer, length)) + goto out; + + memcpy_toio(io_addr, buf, length); + ret = 0; +out: + if (buf != local_buf) + kfree(buf); + return ret; +} + +SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, + void __user *, user_buffer, size_t, length) +{ + u8 local_buf[64]; + void __iomem *io_addr; + void *buf; + unsigned long pfn; + long ret; + + if (!zpci_is_enabled()) + return -ENODEV; + + if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) + return -EINVAL; + if (length > 64) { + buf = kmalloc(length, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } else + buf = local_buf; + + ret = get_pfn(mmio_addr, VM_READ, &pfn); + if (ret) + goto out; + io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); + + ret = -EFAULT; + if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) + goto out; + + memcpy_fromio(buf, io_addr, length); + + if (copy_to_user(user_buffer, buf, length)) + goto out; + + ret = 0; +out: + if (buf != local_buf) + kfree(buf); + return ret; +} diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 02aa4185b17e..61eea02b53f5 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -169,6 +169,8 @@ cond_syscall(ppc_rtas); cond_syscall(sys_spu_run); cond_syscall(sys_spu_create); cond_syscall(sys_subpage_prot); +cond_syscall(sys_s390_pci_mmio_read); +cond_syscall(sys_s390_pci_mmio_write); /* mmu depending weak syscall entries */ cond_syscall(sys_mprotect); -- GitLab From 0620520630bcc2c45cea71ce9069ddbc41b4b24d Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Tue, 18 Nov 2014 15:58:33 -0800 Subject: [PATCH 5241/9457] i2c: img-scb: Allow building for MIPS The SCB is present on IMG SoCs other than the META-based TZ1090, such as the MIPS-based Pistachio SoC. Relax the Kconfig dependency so that it can be built on any MIPS or META machine. Signed-off-by: Andrew Bresticker Acked-by: James Hogan Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a940e336351d..c074df7454d5 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -526,10 +526,10 @@ config I2C_IBM_IIC config I2C_IMG tristate "Imagination Technologies I2C SCB Controller" - depends on SOC_TZ1090 || COMPILE_TEST + depends on MIPS || METAG || COMPILE_TEST help Say Y here if you want to use the IMG I2C SCB controller, - available on the TZ1090 SoC. + available on the TZ1090 and other IMG SoCs. This driver can also be built as a module. If so, the module will be called i2c-img-scb. -- GitLab From 97735da074fdd3fe39d975cad8760807df0d4388 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 15 Oct 2014 16:50:52 +0100 Subject: [PATCH 5242/9457] drivers: cpuidle: Add status property to ARM idle states On some platforms the device tree bindings must provide the kernel with a status flag for idle states, that defines whether the idle state is operational or not in the current configuration. This patch adds a status property to the ARM idle states compliant with ePAPR v1.1 and updates the DT parsing code accordingly. Acked-by: Kevin Hilman Signed-off-by: Lorenzo Pieralisi Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/arm/idle-states.txt | 14 ++++++++++++++ drivers/cpuidle/dt_idle_states.c | 3 +++ 2 files changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt index 37375c7f3ccc..5e5151130c20 100644 --- a/Documentation/devicetree/bindings/arm/idle-states.txt +++ b/Documentation/devicetree/bindings/arm/idle-states.txt @@ -317,6 +317,20 @@ follows: In such systems entry-latency-us + exit-latency-us will exceed wakeup-latency-us by this duration. + - status: + Usage: Optional + Value type: + Definition: A standard device tree property [5] that indicates + the operational status of an idle-state. + If present, it shall be: + "okay": to indicate that the idle state is + operational. + "disabled": to indicate that the idle state has + been disabled in firmware so it is not + operational. + If the property is not present the idle-state must + be considered operational. + In addition to the properties listed above, a state node may require additional properties specifics to the entry-method defined in the idle-states node, please refer to the entry-method bindings diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c index 52f4d11bbf3f..22840f40283c 100644 --- a/drivers/cpuidle/dt_idle_states.c +++ b/drivers/cpuidle/dt_idle_states.c @@ -169,6 +169,9 @@ int dt_init_idle_driver(struct cpuidle_driver *drv, if (!state_node) break; + if (!of_device_is_available(state_node)) + continue; + if (!idle_state_valid(state_node, i, cpumask)) { pr_warn("%s idle state not valid, bailing out\n", state_node->full_name); -- GitLab From c00bc5df7c01a189843cb048cf29e2a445e0037a Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 15 Oct 2014 16:57:34 +0100 Subject: [PATCH 5243/9457] drivers: cpuidle: Add idle-state-name description to ARM idle states On ARM machines, where generally speaking the idle state numbering has no fixed and standard meaning it is useful to provide a description of the idle state inner workings for benchmarking and monitoring purposes. This patch adds a property to the idle states bindings that if present gives platform firmware a means of describing the idle state and export the string description to user space. The patch updates the DT parsing code accordingly to take the description, if present, into consideration. Acked-by: Kevin Hilman Signed-off-by: Lorenzo Pieralisi Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/arm/idle-states.txt | 6 ++++++ drivers/cpuidle/dt_idle_states.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt index 5e5151130c20..a8274eabae2e 100644 --- a/Documentation/devicetree/bindings/arm/idle-states.txt +++ b/Documentation/devicetree/bindings/arm/idle-states.txt @@ -331,6 +331,12 @@ follows: If the property is not present the idle-state must be considered operational. + - idle-state-name: + Usage: Optional + Value type: + Definition: A string used as a descriptive name for the idle + state. + In addition to the properties listed above, a state node may require additional properties specifics to the entry-method defined in the idle-states node, please refer to the entry-method bindings diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c index 22840f40283c..5301912cb84e 100644 --- a/drivers/cpuidle/dt_idle_states.c +++ b/drivers/cpuidle/dt_idle_states.c @@ -27,6 +27,7 @@ static int init_state_node(struct cpuidle_state *idle_state, { int err; const struct of_device_id *match_id; + const char *desc; match_id = of_match_node(matches, state_node); if (!match_id) @@ -73,6 +74,10 @@ static int init_state_node(struct cpuidle_state *idle_state, return -EINVAL; } + err = of_property_read_string(state_node, "idle-state-name", &desc); + if (err) + desc = state_node->name; + idle_state->flags = CPUIDLE_FLAG_TIME_VALID; if (of_property_read_bool(state_node, "local-timer-stop")) idle_state->flags |= CPUIDLE_FLAG_TIMER_STOP; @@ -82,7 +87,7 @@ static int init_state_node(struct cpuidle_state *idle_state, * and desc become string pointers */ strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1); - strncpy(idle_state->desc, state_node->name, CPUIDLE_DESC_LEN - 1); + strncpy(idle_state->desc, desc, CPUIDLE_DESC_LEN - 1); return 0; } -- GitLab From 18f95a3640dbf421ab9532e517070a0c1cd4d582 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Wed, 15 Oct 2014 18:29:54 +0100 Subject: [PATCH 5244/9457] drivers: cpuidle: Remove cpuidle-arm64 duplicate error messages Current CPUidle driver for arm64 machines spits errors upon idle state initialization and cpuidle driver registration failures. These error messages are already printed in core code so there is no need to print them again. This patch removes the duplicate print messages from the cpuidle-arm64 driver. Acked-by: Kevin Hilman Signed-off-by: Lorenzo Pieralisi Signed-off-by: Daniel Lezcano --- drivers/cpuidle/cpuidle-arm64.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm64.c index 50997ea942fc..1b10f92ecd5a 100644 --- a/drivers/cpuidle/cpuidle-arm64.c +++ b/drivers/cpuidle/cpuidle-arm64.c @@ -104,11 +104,8 @@ static int __init arm64_idle_init(void) * reason to initialize the idle driver if only wfi is supported. */ ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1); - if (ret <= 0) { - if (ret) - pr_err("failed to initialize idle states\n"); + if (ret <= 0) return ret ? : -ENODEV; - } /* * Call arch CPU operations in order to initialize @@ -122,12 +119,6 @@ static int __init arm64_idle_init(void) } } - ret = cpuidle_register(drv, NULL); - if (ret) { - pr_err("failed to register cpuidle driver\n"); - return ret; - } - - return 0; + return cpuidle_register(drv, NULL); } device_initcall(arm64_idle_init); -- GitLab From 9b2b5c9a790743ccb2516f1a86671d5df9c6c5cd Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 12 Nov 2014 14:10:09 -0500 Subject: [PATCH 5245/9457] HID: sony: Use kernel allocated buffers for HID reports Replace stack buffers with kernel allocated buffers for sending and receiving HID reports to prevent issues with DMA transfers on certain hardware. Output report buffers are allocated at initialization time to avoid excessive calls to kmalloc and kfree. Link: https://bugzilla.kernel.org/show_bug.cgi?id=87991 Signed-off-by: Frank Praznik Reviewed-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 147 +++++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 34 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index bc4269e559f1..b6e610289e9d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -798,6 +798,12 @@ union sixaxis_output_report_01 { __u8 buf[36]; }; +#define DS4_REPORT_0x02_SIZE 37 +#define DS4_REPORT_0x05_SIZE 32 +#define DS4_REPORT_0x11_SIZE 78 +#define DS4_REPORT_0x81_SIZE 7 +#define SIXAXIS_REPORT_0xF2_SIZE 18 + static spinlock_t sony_dev_list_lock; static LIST_HEAD(sony_device_list); static DEFINE_IDA(sony_device_id_allocator); @@ -811,6 +817,7 @@ struct sony_sc { struct work_struct state_worker; struct power_supply battery; int device_id; + __u8 *output_report_dmabuf; #ifdef CONFIG_SONY_FF __u8 left; @@ -1142,9 +1149,20 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) static int sixaxis_set_operational_bt(struct hid_device *hdev) { - unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; - return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), + static const __u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; + __u8 *buf; + int ret; + + buf = kmemdup(report, sizeof(report), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); + + kfree(buf); + + return ret; } /* @@ -1153,10 +1171,19 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev) */ static int dualshock4_set_operational_bt(struct hid_device *hdev) { - __u8 buf[37] = { 0 }; + __u8 *buf; + int ret; - return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), + buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_REPORT_0x02_SIZE, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + kfree(buf); + + return ret; } static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) @@ -1471,9 +1498,7 @@ static int sony_leds_init(struct sony_sc *sc) static void sixaxis_state_worker(struct work_struct *work) { - struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); - int n; - union sixaxis_output_report_01 report = { + static const union sixaxis_output_report_01 default_report = { .buf = { 0x01, 0x00, 0xff, 0x00, 0xff, 0x00, @@ -1485,20 +1510,27 @@ static void sixaxis_state_worker(struct work_struct *work) 0x00, 0x00, 0x00, 0x00, 0x00 } }; + struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); + struct sixaxis_output_report *report = + (struct sixaxis_output_report *)sc->output_report_dmabuf; + int n; + + /* Initialize the report with default values */ + memcpy(report, &default_report, sizeof(struct sixaxis_output_report)); #ifdef CONFIG_SONY_FF - report.data.rumble.right_motor_on = sc->right ? 1 : 0; - report.data.rumble.left_motor_force = sc->left; + report->rumble.right_motor_on = sc->right ? 1 : 0; + report->rumble.left_motor_force = sc->left; #endif - report.data.leds_bitmap |= sc->led_state[0] << 1; - report.data.leds_bitmap |= sc->led_state[1] << 2; - report.data.leds_bitmap |= sc->led_state[2] << 3; - report.data.leds_bitmap |= sc->led_state[3] << 4; + report->leds_bitmap |= sc->led_state[0] << 1; + report->leds_bitmap |= sc->led_state[1] << 2; + report->leds_bitmap |= sc->led_state[2] << 3; + report->leds_bitmap |= sc->led_state[3] << 4; /* Set flag for all leds off, required for 3rd party INTEC controller */ - if ((report.data.leds_bitmap & 0x1E) == 0) - report.data.leds_bitmap |= 0x20; + if ((report->leds_bitmap & 0x1E) == 0) + report->leds_bitmap |= 0x20; /* * The LEDs in the report are indexed in reverse order to their @@ -1511,28 +1543,30 @@ static void sixaxis_state_worker(struct work_struct *work) */ for (n = 0; n < 4; n++) { if (sc->led_delay_on[n] || sc->led_delay_off[n]) { - report.data.led[3 - n].duty_off = sc->led_delay_off[n]; - report.data.led[3 - n].duty_on = sc->led_delay_on[n]; + report->led[3 - n].duty_off = sc->led_delay_off[n]; + report->led[3 - n].duty_on = sc->led_delay_on[n]; } } - hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, - sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); + hid_hw_raw_request(sc->hdev, report->report_id, (__u8 *)report, + sizeof(struct sixaxis_output_report), + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); } static void dualshock4_state_worker(struct work_struct *work) { struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); struct hid_device *hdev = sc->hdev; + __u8 *buf = sc->output_report_dmabuf; int offset; - __u8 buf[78] = { 0 }; - if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { + memset(buf, 0, DS4_REPORT_0x05_SIZE); buf[0] = 0x05; buf[1] = 0xFF; offset = 4; } else { + memset(buf, 0, DS4_REPORT_0x11_SIZE); buf[0] = 0x11; buf[1] = 0xB0; buf[3] = 0x0F; @@ -1560,12 +1594,33 @@ static void dualshock4_state_worker(struct work_struct *work) buf[offset++] = sc->led_delay_off[3]; if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) - hid_hw_output_report(hdev, buf, 32); + hid_hw_output_report(hdev, buf, DS4_REPORT_0x05_SIZE); else - hid_hw_raw_request(hdev, 0x11, buf, 78, + hid_hw_raw_request(hdev, 0x11, buf, DS4_REPORT_0x11_SIZE, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); } +static int sony_allocate_output_report(struct sony_sc *sc) +{ + if (sc->quirks & SIXAXIS_CONTROLLER) + sc->output_report_dmabuf = + kmalloc(sizeof(union sixaxis_output_report_01), + GFP_KERNEL); + else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) + sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x11_SIZE, + GFP_KERNEL); + else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) + sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE, + GFP_KERNEL); + else + return 0; + + if (!sc->output_report_dmabuf) + return -ENOMEM; + + return 0; +} + #ifdef CONFIG_SONY_FF static int sony_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) @@ -1754,6 +1809,7 @@ static int sony_get_bt_devaddr(struct sony_sc *sc) static int sony_check_add(struct sony_sc *sc) { + __u8 *buf = NULL; int n, ret; if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || @@ -1769,36 +1825,44 @@ static int sony_check_add(struct sony_sc *sc) return 0; } } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { - __u8 buf[7]; + buf = kmalloc(DS4_REPORT_0x81_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; /* * The MAC address of a DS4 controller connected via USB can be * retrieved with feature report 0x81. The address begins at * offset 1. */ - ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf), - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + ret = hid_hw_raw_request(sc->hdev, 0x81, buf, + DS4_REPORT_0x81_SIZE, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); - if (ret != 7) { + if (ret != DS4_REPORT_0x81_SIZE) { hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); - return ret < 0 ? ret : -EINVAL; + ret = ret < 0 ? ret : -EINVAL; + goto out_free; } memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { - __u8 buf[18]; + buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; /* * The MAC address of a Sixaxis controller connected via USB can * be retrieved with feature report 0xf2. The address begins at * offset 4. */ - ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf), - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, + SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); - if (ret != 18) { + if (ret != SIXAXIS_REPORT_0xF2_SIZE) { hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); - return ret < 0 ? ret : -EINVAL; + ret = ret < 0 ? ret : -EINVAL; + goto out_free; } /* @@ -1811,7 +1875,13 @@ static int sony_check_add(struct sony_sc *sc) return 0; } - return sony_check_add_dev_list(sc); + ret = sony_check_add_dev_list(sc); + +out_free: + + kfree(buf); + + return ret; } static int sony_set_device_id(struct sony_sc *sc) @@ -1895,6 +1965,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } + ret = sony_allocate_output_report(sc); + if (ret < 0) { + hid_err(hdev, "failed to allocate the output report buffer\n"); + goto err_stop; + } + ret = sony_set_device_id(sc); if (ret < 0) { hid_err(hdev, "failed to allocate the device id\n"); @@ -1984,6 +2060,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) if (sc->quirks & SONY_BATTERY_SUPPORT) sony_battery_remove(sc); sony_cancel_work_sync(sc); + kfree(sc->output_report_dmabuf); sony_remove_dev_list(sc); sony_release_device_id(sc); hid_hw_stop(hdev); @@ -2004,6 +2081,8 @@ static void sony_remove(struct hid_device *hdev) sony_cancel_work_sync(sc); + kfree(sc->output_report_dmabuf); + sony_remove_dev_list(sc); sony_release_device_id(sc); -- GitLab From 2dfe2b08d280c15cc7266de40412c2a911643148 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 19 Nov 2014 13:52:18 +0800 Subject: [PATCH 5246/9457] ASoC: rt5677: Align the reg_default table with tab character Align the reg_default table with tab character Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 9ae2e8468006..b2d88bb14cfe 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -55,13 +55,13 @@ static const struct regmap_range_cfg rt5677_ranges[] = { }; static const struct reg_default init_list[] = { - {RT5677_ASRC_12, 0x0018}, - {RT5677_PR_BASE + 0x3d, 0x364d}, - {RT5677_PR_BASE + 0x17, 0x4fc0}, - {RT5677_PR_BASE + 0x13, 0x0312}, - {RT5677_PR_BASE + 0x1e, 0x0000}, - {RT5677_PR_BASE + 0x12, 0x0eaa}, - {RT5677_PR_BASE + 0x14, 0x018a}, + {RT5677_ASRC_12, 0x0018}, + {RT5677_PR_BASE + 0x3d, 0x364d}, + {RT5677_PR_BASE + 0x17, 0x4fc0}, + {RT5677_PR_BASE + 0x13, 0x0312}, + {RT5677_PR_BASE + 0x1e, 0x0000}, + {RT5677_PR_BASE + 0x12, 0x0eaa}, + {RT5677_PR_BASE + 0x14, 0x018a}, }; #define RT5677_INIT_REG_LEN ARRAY_SIZE(init_list) -- GitLab From 35d40d10e95f52569570dc4e26da19f072aa256d Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 19 Nov 2014 13:52:19 +0800 Subject: [PATCH 5247/9457] ASoC: rt5677: Follow the gpio naming rule to rename the irq function Follow the gpio naming rule to rename the irq function. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index b2d88bb14cfe..dd080cdbff10 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -4552,7 +4552,7 @@ static struct regmap_irq_chip rt5677_irq_chip = { .mask_invert = 1, }; -static int rt5677_irq_init(struct i2c_client *i2c) +static int rt5677_init_irq(struct i2c_client *i2c) { int ret; struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); @@ -4579,7 +4579,7 @@ static int rt5677_irq_init(struct i2c_client *i2c) return 0; } -static void rt5677_irq_exit(struct i2c_client *i2c) +static void rt5677_free_irq(struct i2c_client *i2c) { struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); @@ -4693,7 +4693,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, } rt5677_init_gpio(i2c); - rt5677_irq_init(i2c); + rt5677_init_irq(i2c); return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677, rt5677_dai, ARRAY_SIZE(rt5677_dai)); @@ -4701,9 +4701,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, static int rt5677_i2c_remove(struct i2c_client *i2c) { - rt5677_irq_exit(i2c); - snd_soc_unregister_codec(&i2c->dev); + rt5677_free_irq(i2c); rt5677_free_gpio(i2c); return 0; -- GitLab From 683996cb2255373c2055e7b69584ac153eb49f42 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 19 Nov 2014 13:52:20 +0800 Subject: [PATCH 5248/9457] ASoC: rt5677: Set the slow charge of the vref in the end of the power sequences Set the slow charge of the vref in the end of the power sequences Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 56 ++++++++++++++++++++++++++++++++------- sound/soc/codecs/rt5677.h | 1 + 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index dd080cdbff10..f2211f14ba41 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -2184,6 +2184,31 @@ static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w, return 0; } +static int rt5677_vref_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (codec->dapm.bias_level != SND_SOC_BIAS_ON && + !rt5677->is_vref_slow) { + mdelay(20); + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, + RT5677_PWR_FV1 | RT5677_PWR_FV2, + RT5677_PWR_FV1 | RT5677_PWR_FV2); + rt5677->is_vref_slow = true; + } + break; + + default: + return 0; + } + + return 0; +} + static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT, 0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU), @@ -2669,13 +2694,20 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_MUX("PDM2 R Mux", RT5677_PDM_OUT_CTRL, RT5677_M_PDM2_R_SFT, 1, &rt5677_pdm2_r_mux), - SND_SOC_DAPM_PGA_S("LOUT1 amp", 1, RT5677_PWR_ANLG1, RT5677_PWR_LO1_BIT, + SND_SOC_DAPM_PGA_S("LOUT1 amp", 0, RT5677_PWR_ANLG1, RT5677_PWR_LO1_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA_S("LOUT2 amp", 1, RT5677_PWR_ANLG1, RT5677_PWR_LO2_BIT, + SND_SOC_DAPM_PGA_S("LOUT2 amp", 0, RT5677_PWR_ANLG1, RT5677_PWR_LO2_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA_S("LOUT3 amp", 1, RT5677_PWR_ANLG1, RT5677_PWR_LO3_BIT, + SND_SOC_DAPM_PGA_S("LOUT3 amp", 0, RT5677_PWR_ANLG1, RT5677_PWR_LO3_BIT, 0, NULL, 0), + SND_SOC_DAPM_PGA_S("LOUT1 vref", 1, SND_SOC_NOPM, 0, 0, + rt5677_vref_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("LOUT2 vref", 1, SND_SOC_NOPM, 0, 0, + rt5677_vref_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("LOUT3 vref", 1, SND_SOC_NOPM, 0, 0, + rt5677_vref_event, SND_SOC_DAPM_POST_PMU), + /* Output Lines */ SND_SOC_DAPM_OUTPUT("LOUT1"), SND_SOC_DAPM_OUTPUT("LOUT2"), @@ -2684,6 +2716,8 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("PDM1R"), SND_SOC_DAPM_OUTPUT("PDM2L"), SND_SOC_DAPM_OUTPUT("PDM2R"), + + SND_SOC_DAPM_POST("vref", rt5677_vref_event), }; static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { @@ -3572,9 +3606,13 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "LOUT2 amp", NULL, "DAC 2" }, { "LOUT3 amp", NULL, "DAC 3" }, - { "LOUT1", NULL, "LOUT1 amp" }, - { "LOUT2", NULL, "LOUT2 amp" }, - { "LOUT3", NULL, "LOUT3 amp" }, + { "LOUT1 vref", NULL, "LOUT1 amp" }, + { "LOUT2 vref", NULL, "LOUT2 amp" }, + { "LOUT3 vref", NULL, "LOUT3 amp" }, + + { "LOUT1", NULL, "LOUT1 vref" }, + { "LOUT2", NULL, "LOUT2 vref" }, + { "LOUT3", NULL, "LOUT3 vref" }, { "PDM1L", NULL, "PDM1 L Mux" }, { "PDM1R", NULL, "PDM1 R Mux" }, @@ -3957,14 +3995,12 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec, RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0f00); regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, + RT5677_PWR_FV1 | RT5677_PWR_FV2 | RT5677_PWR_VREF1 | RT5677_PWR_MB | RT5677_PWR_BG | RT5677_PWR_VREF2, RT5677_PWR_VREF1 | RT5677_PWR_MB | RT5677_PWR_BG | RT5677_PWR_VREF2); - mdelay(20); - regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, - RT5677_PWR_FV1 | RT5677_PWR_FV2, - RT5677_PWR_FV1 | RT5677_PWR_FV2); + rt5677->is_vref_slow = false; regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, RT5677_PWR_CORE, RT5677_PWR_CORE); regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 2979d5a05789..a02f64c23596 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -1687,6 +1687,7 @@ struct rt5677_priv { bool dsp_vad_en; struct regmap_irq_chip_data *irq_data; bool is_dsp_mode; + bool is_vref_slow; }; #endif /* __RT5677_H__ */ -- GitLab From e39f223fc93580c86ccf6b3422033e349f57f0dd Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 18 Nov 2014 16:47:35 +1100 Subject: [PATCH 5249/9457] powerpc: Remove more traces of bootmem Although we are now selecting NO_BOOTMEM, we still have some traces of bootmem lying around. That is because even with NO_BOOTMEM there is still a shim that converts bootmem calls into memblock calls, but ultimately we want to remove all traces of bootmem. Most of the patch is conversions from alloc_bootmem() to memblock_virt_alloc(). In general a call such as: p = (struct foo *)alloc_bootmem(x); Becomes: p = memblock_virt_alloc(x, 0); We don't need the cast because memblock_virt_alloc() returns a void *. The alignment value of zero tells memblock to use the default alignment, which is SMP_CACHE_BYTES, the same value alloc_bootmem() uses. We remove a number of NULL checks on the result of memblock_virt_alloc(). That is because memblock_virt_alloc() will panic if it can't allocate, in exactly the same way as alloc_bootmem(), so the NULL checks are and always have been redundant. The memory returned by memblock_virt_alloc() is already zeroed, so we remove several memsets of the result of memblock_virt_alloc(). Finally we convert a few uses of __alloc_bootmem(x, y, MAX_DMA_ADDRESS) to just plain memblock_virt_alloc(). We don't use memblock_alloc_base() because MAX_DMA_ADDRESS is ~0ul on powerpc, so limiting the allocation to that is pointless, 16XB ought to be enough for anyone. Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/pci-common.c | 1 - arch/powerpc/kernel/pci_32.c | 4 +--- arch/powerpc/kernel/setup_64.c | 2 +- arch/powerpc/lib/alloc.c | 4 +--- arch/powerpc/mm/hugetlbpage.c | 2 +- arch/powerpc/mm/mmu_context_nohash.c | 8 ++++---- arch/powerpc/platforms/cell/celleb_pci.c | 6 +++--- arch/powerpc/platforms/powermac/nvram.c | 6 +----- arch/powerpc/platforms/powernv/pci-ioda.c | 12 +++--------- arch/powerpc/platforms/powernv/pci-p5ioc2.c | 16 ++++------------ arch/powerpc/platforms/ps3/setup.c | 7 +------ arch/powerpc/sysdev/fsl_pci.c | 1 - 12 files changed, 20 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index bc2dab52a991..37d512d35943 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 432459c817fa..1f7930037cb7 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -199,9 +199,7 @@ pci_create_OF_bus_map(void) struct property* of_prop; struct device_node *dn; - of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); - if (!of_prop) - return; + of_prop = memblock_virt_alloc(sizeof(struct property) + 256, 0); dn = of_find_node_by_path("/"); if (dn) { memset(of_prop, -1, sizeof(struct property) + 256); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6e5310ddf8c7..49f553bbb360 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -660,7 +660,7 @@ static void __init emergency_stack_init(void) } /* - * Called into from start_kernel this initializes bootmem, which is used + * Called into from start_kernel this initializes memblock, which is used * to manage page allocation until mem_init is called. */ void __init setup_arch(char **cmdline_p) diff --git a/arch/powerpc/lib/alloc.c b/arch/powerpc/lib/alloc.c index da22c84a8fed..4a6c2cf890d9 100644 --- a/arch/powerpc/lib/alloc.c +++ b/arch/powerpc/lib/alloc.c @@ -13,9 +13,7 @@ void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask) if (mem_init_done) p = kzalloc(size, mask); else { - p = alloc_bootmem(size); - if (p) - memset(p, 0, size); + p = memblock_virt_alloc(size, 0); } return p; } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index af56de82375d..8c9b8115867c 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -315,7 +315,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate) * If gpages can be in highmem we can't use the trick of storing the * data structure in the page; allocate space for this */ - m = alloc_bootmem(sizeof(struct huge_bootmem_page)); + m = memblock_virt_alloc(sizeof(struct huge_bootmem_page), 0); m->phys = gpage_freearray[idx].gpage_list[--nr_gpages]; #else m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]); diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 928ebe79668b..9cba6cba2e50 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -421,12 +421,12 @@ void __init mmu_context_init(void) /* * Allocate the maps used by context management */ - context_map = alloc_bootmem(CTX_MAP_SIZE); - context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1)); + context_map = memblock_virt_alloc(CTX_MAP_SIZE, 0); + context_mm = memblock_virt_alloc(sizeof(void *) * (last_context + 1), 0); #ifndef CONFIG_SMP - stale_map[0] = alloc_bootmem(CTX_MAP_SIZE); + stale_map[0] = memblock_virt_alloc(CTX_MAP_SIZE, 0); #else - stale_map[boot_cpuid] = alloc_bootmem(CTX_MAP_SIZE); + stale_map[boot_cpuid] = memblock_virt_alloc(CTX_MAP_SIZE, 0); register_cpu_notifier(&mmu_context_cpu_nb); #endif diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c index 2b98a36ef8fb..3ce70ded2d6a 100644 --- a/arch/powerpc/platforms/cell/celleb_pci.c +++ b/arch/powerpc/platforms/cell/celleb_pci.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -401,11 +401,11 @@ static int __init celleb_setup_fake_pci_device(struct device_node *node, } else { if (config && *config) { size = 256; - free_bootmem(__pa(*config), size); + memblock_free(__pa(*config), size); } if (res && *res) { size = sizeof(struct celleb_pci_resource); - free_bootmem(__pa(*res), size); + memblock_free(__pa(*res), size); } } diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index 014d06e6d46b..60b03a1703d1 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c @@ -513,11 +513,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) printk(KERN_ERR "nvram: no address\n"); return -EINVAL; } - nvram_image = alloc_bootmem(NVRAM_SIZE); - if (nvram_image == NULL) { - printk(KERN_ERR "nvram: can't allocate ram image\n"); - return -ENOMEM; - } + nvram_image = memblock_virt_alloc(NVRAM_SIZE, 0); nvram_data = ioremap(addr, NVRAM_SIZE*2); nvram_naddrs = 1; /* Make sure we get the correct case */ diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index d03503515692..cc861c14840d 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1940,19 +1940,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, phb_id = be64_to_cpup(prop64); pr_debug(" PHB-ID : 0x%016llx\n", phb_id); - phb = alloc_bootmem(sizeof(struct pnv_phb)); - if (!phb) { - pr_err(" Out of memory !\n"); - return; - } + phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); /* Allocate PCI controller */ - memset(phb, 0, sizeof(struct pnv_phb)); phb->hose = hose = pcibios_alloc_controller(np); if (!phb->hose) { pr_err(" Can't allocate PCI controller for %s\n", np->full_name); - free_bootmem((unsigned long)phb, sizeof(struct pnv_phb)); + memblock_free(__pa(phb), sizeof(struct pnv_phb)); return; } @@ -2019,8 +2014,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, } pemap_off = size; size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); - aux = alloc_bootmem(size); - memset(aux, 0, size); + aux = memblock_virt_alloc(size, 0); phb->ioda.pe_alloc = aux; phb->ioda.m32_segmap = aux + m32map_off; if (phb->type == PNV_PHB_IODA1) diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 3336fcbdd08a..6ef6d4d8e7e2 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c @@ -122,12 +122,9 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, return; } - phb = alloc_bootmem(sizeof(struct pnv_phb)); - if (phb) { - memset(phb, 0, sizeof(struct pnv_phb)); - phb->hose = pcibios_alloc_controller(np); - } - if (!phb || !phb->hose) { + phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); + phb->hose = pcibios_alloc_controller(np); + if (!phb->hose) { pr_err(" Failed to allocate PCI controller\n"); return; } @@ -216,12 +213,7 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) * * XXX TODO: Make it chip local if possible */ - tce_mem = __alloc_bootmem(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY, - __pa(MAX_DMA_ADDRESS)); - if (!tce_mem) { - pr_err(" Failed to allocate TCE Memory !\n"); - return; - } + tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY); pr_debug(" TCE : 0x%016lx..0x%016lx\n", __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 009a2004b876..799c8580ab09 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -125,12 +125,7 @@ static void __init prealloc(struct ps3_prealloc *p) if (!p->size) return; - p->address = __alloc_bootmem(p->size, p->align, __pa(MAX_DMA_ADDRESS)); - if (!p->address) { - printk(KERN_ERR "%s: Cannot allocate %s\n", __func__, - p->name); - return; - } + p->address = memblock_virt_alloc(p->size, p->align); printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, p->address); diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d8484d7cffaa..6455c1eada1a 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include -- GitLab From 672e7b7c1849c904b2c55185906b3940843c55c6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 19 Nov 2014 09:47:19 +0000 Subject: [PATCH 5250/9457] drm/i915: Don't continually defer the hangcheck With multiple rings, we may continue to render on the blitter whilst executing an infinite shader on the render ring. As we currently, rearm the timer with each execbuf, in this scenario the hangcheck will never fire and we will never detect the lockup on the render ring. Instead, only arm the timer once per hangcheck, so that hangcheck runs more frequently. v2: Rearrange code to avoid triggering a BUG_ON in add_timer from softirq context. Testcase: igt/gem_reset_stats/defer-hangcheck* Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86225 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5e5d3f709f0f..e298518c944e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -988,7 +988,6 @@ static void notify_ring(struct drm_device *dev, trace_i915_gem_request_complete(ring); wake_up_all(&ring->irq_queue); - i915_queue_hangcheck(dev); } static u32 vlv_c0_residency(struct drm_i915_private *dev_priv, @@ -3041,11 +3040,15 @@ static void i915_hangcheck_elapsed(unsigned long data) void i915_queue_hangcheck(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct timer_list *timer = &dev_priv->gpu_error.hangcheck_timer; + if (!i915.enable_hangcheck) return; - mod_timer(&dev_priv->gpu_error.hangcheck_timer, - round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); + /* Don't continually defer the hangcheck, but make sure it is active */ + if (!timer_pending(timer)) + timer->expires = round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES); + mod_timer(timer, timer->expires); } static void ibx_irq_reset(struct drm_device *dev) -- GitLab From 20feb881988cdf5f53304c355ae8ee3bf82e80ec Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Nov 2014 19:45:52 +0100 Subject: [PATCH 5251/9457] ASoC: Add helper functions for deferred regmap setup Some drivers (most notably the AC'97 drivers) do not have access to their regmap struct when the component/codec is registered. For those drivers the automatic regmap setup will not work and needs to be done manually, typically from the component/CODEC drivers probe callback. This patch adds a set of helper function to handle deferred regmap initialization as well as early regmap tear-down. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 35 ++++++++++++++++++++++++++ sound/soc/soc-core.c | 58 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..342b43b3799e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1277,6 +1277,41 @@ void snd_soc_component_async_complete(struct snd_soc_component *component); int snd_soc_component_test_bits(struct snd_soc_component *component, unsigned int reg, unsigned int mask, unsigned int value); +void snd_soc_component_init_regmap(struct snd_soc_component *component, + struct regmap *regmap); +void snd_soc_component_exit_regmap(struct snd_soc_component *component); + +/** + * snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC + * @codec: The CODEC for which to initialize the regmap instance + * @regmap: The regmap instance that should be used by the CODEC + * + * This function allows deferred assignment of the regmap instance that is + * associated with the CODEC. Only use this if the regmap instance is not yet + * ready when the CODEC is registered. The function must also be called before + * the first IO attempt of the CODEC. + */ +static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec, + struct regmap *regmap) +{ + snd_soc_component_init_regmap(&codec->component, regmap); +} + +/** + * snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC + * @codec: The CODEC for which to de-initialize the regmap instance + * + * Calls regmap_exit() on the regmap instance associated to the CODEC and + * removes the regmap instance from the CODEC. + * + * This function should only be used if snd_soc_codec_init_regmap() was used to + * initialize the regmap instance. + */ +static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec) +{ + snd_soc_component_exit_regmap(&codec->component); +} + /* device driver data */ static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..5fd5f08ce24e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3996,22 +3996,58 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, return 0; } -static void snd_soc_component_init_regmap(struct snd_soc_component *component) +static void snd_soc_component_setup_regmap(struct snd_soc_component *component) { - if (!component->regmap) - component->regmap = dev_get_regmap(component->dev, NULL); - if (component->regmap) { - int val_bytes = regmap_get_val_bytes(component->regmap); - /* Errors are legitimate for non-integer byte multiples */ - if (val_bytes > 0) - component->val_bytes = val_bytes; - } + int val_bytes = regmap_get_val_bytes(component->regmap); + + /* Errors are legitimate for non-integer byte multiples */ + if (val_bytes > 0) + component->val_bytes = val_bytes; +} + +/** + * snd_soc_component_init_regmap() - Initialize regmap instance for the component + * @component: The component for which to initialize the regmap instance + * @regmap: The regmap instance that should be used by the component + * + * This function allows deferred assignment of the regmap instance that is + * associated with the component. Only use this if the regmap instance is not + * yet ready when the component is registered. The function must also be called + * before the first IO attempt of the component. + */ +void snd_soc_component_init_regmap(struct snd_soc_component *component, + struct regmap *regmap) +{ + component->regmap = regmap; + snd_soc_component_setup_regmap(component); } +EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap); + +/** + * snd_soc_component_exit_regmap() - De-initialize regmap instance for the component + * @component: The component for which to de-initialize the regmap instance + * + * Calls regmap_exit() on the regmap instance associated to the component and + * removes the regmap instance from the component. + * + * This function should only be used if snd_soc_component_init_regmap() was used + * to initialize the regmap instance. + */ +void snd_soc_component_exit_regmap(struct snd_soc_component *component) +{ + regmap_exit(component->regmap); + component->regmap = NULL; +} +EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap); static void snd_soc_component_add_unlocked(struct snd_soc_component *component) { - if (!component->write && !component->read) - snd_soc_component_init_regmap(component); + if (!component->write && !component->read) { + if (!component->regmap) + component->regmap = dev_get_regmap(component->dev, NULL); + if (component->regmap) + snd_soc_component_setup_regmap(component); + } list_add(&component->list, &component_list); } -- GitLab From 90bd1f46caa9ad0d51ec48c91f3c3a616d6d6b8c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 11:18:47 +0100 Subject: [PATCH 5252/9457] drm/i915: Tune down sink crc timeout dmesg output For whatever reasons this can happen. For real testcases the test will notice the -EIO and fall over, but we also have some testcases that just read all debugfs files. And that shouldn't cause dmesg spam. So tune it down a bit so that we still have the information for debugging. And change the errno so that real testcases can easily differentiate. Cc: Rodrigo Vivi Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84890 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4e49caa5a1b3..565479002708 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3693,8 +3693,8 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); if (attempts == 0) { - DRM_ERROR("Panel is unable to calculate CRC after 6 vblanks\n"); - return -EIO; + DRM_DEBUG_KMS("Panel is unable to calculate CRC after 6 vblanks\n"); + return -ETIMEDOUT; } if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) -- GitLab From 82d14636418299b4f54511a02373796b38747b48 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Nov 2014 19:45:53 +0100 Subject: [PATCH 5253/9457] ASoC: ad1980: Convert to regmap This patch converts the ad1980 driver to use regmap for its IO. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + sound/soc/codecs/ad1980.c | 141 +++++++++++++++++++++++--------------- 2 files changed, 88 insertions(+), 54 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a68d1731a8fd..6a66216a9c0f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -223,6 +223,7 @@ config SND_SOC_AD193X_I2C select SND_SOC_AD193X config SND_SOC_AD1980 + select REGMAP_AC97 tristate config SND_SOC_AD73311 diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 93bd47db6d0c..5fd4a29a2fe0 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -24,32 +24,86 @@ #include #include #include +#include #include #include #include #include #include -/* - * AD1980 register cache - */ -static const u16 ad1980_reg[] = { - 0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6 */ - 0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e */ - 0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */ - 0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */ - 0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */ - 0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */ - 0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */ - 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */ - 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */ - 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */ - 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */ - 0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */ - 0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */ - 0x0000, 0x0000, 0x4144, 0x5370 /* 78 - 7e */ +static const struct reg_default ad1980_reg_defaults[] = { + { 0x02, 0x8000 }, + { 0x04, 0x8000 }, + { 0x06, 0x8000 }, + { 0x0c, 0x8008 }, + { 0x0e, 0x8008 }, + { 0x10, 0x8808 }, + { 0x12, 0x8808 }, + { 0x16, 0x8808 }, + { 0x18, 0x8808 }, + { 0x1a, 0x0000 }, + { 0x1c, 0x8000 }, + { 0x20, 0x0000 }, + { 0x28, 0x03c7 }, + { 0x2c, 0xbb80 }, + { 0x2e, 0xbb80 }, + { 0x30, 0xbb80 }, + { 0x32, 0xbb80 }, + { 0x36, 0x8080 }, + { 0x38, 0x8080 }, + { 0x3a, 0x2000 }, + { 0x60, 0x0000 }, + { 0x62, 0x0000 }, + { 0x72, 0x0000 }, + { 0x74, 0x1001 }, + { 0x76, 0x0000 }, +}; + +static bool ad1980_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AC97_RESET ... AC97_MASTER_MONO: + case AC97_PHONE ... AC97_CD: + case AC97_AUX ... AC97_GENERAL_PURPOSE: + case AC97_POWERDOWN ... AC97_PCM_LR_ADC_RATE: + case AC97_SPDIF: + case AC97_CODEC_CLASS_REV: + case AC97_PCI_SVID: + case AC97_AD_CODEC_CFG: + case AC97_AD_JACK_SPDIF: + case AC97_AD_SERIAL_CFG: + case AC97_VENDOR_ID1: + case AC97_VENDOR_ID2: + return true; + default: + return false; + } +} + +static bool ad1980_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AC97_VENDOR_ID1: + case AC97_VENDOR_ID2: + return false; + default: + return ad1980_readable_reg(dev, reg); + } +} + +static const struct regmap_config ad1980_regmap_config = { + .reg_bits = 16, + .reg_stride = 2, + .val_bits = 16, + .max_register = 0x7e, + .cache_type = REGCACHE_RBTREE, + + .volatile_reg = regmap_ac97_default_volatile, + .readable_reg = ad1980_readable_reg, + .writeable_reg = ad1980_writeable_reg, + + .reg_defaults = ad1980_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ad1980_reg_defaults), }; static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line", @@ -135,39 +189,13 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = { static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { - struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); - u16 *cache = codec->reg_cache; - - switch (reg) { - case AC97_RESET: - case AC97_INT_PAGING: - case AC97_POWERDOWN: - case AC97_EXTENDED_STATUS: - case AC97_VENDOR_ID1: - case AC97_VENDOR_ID2: - return soc_ac97_ops->read(ac97, reg); - default: - reg = reg >> 1; - - if (reg >= ARRAY_SIZE(ad1980_reg)) - return -EINVAL; - - return cache[reg]; - } + return snd_soc_read(codec, reg); } static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val) { - struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); - u16 *cache = codec->reg_cache; - - soc_ac97_ops->write(ac97, reg, val); - reg = reg >> 1; - if (reg < ARRAY_SIZE(ad1980_reg)) - cache[reg] = val; - - return 0; + return snd_soc_write(codec, reg, val); } static struct snd_soc_dai_driver ad1980_dai = { @@ -219,6 +247,7 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) static int ad1980_soc_probe(struct snd_soc_codec *codec) { struct snd_ac97 *ac97; + struct regmap *regmap; int ret; u16 vendor_id2; u16 ext_status; @@ -230,6 +259,13 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) return ret; } + regmap = regmap_init_ac97(ac97, &ad1980_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_free_ac97; + } + + snd_soc_codec_init_regmap(codec, regmap); snd_soc_codec_set_drvdata(codec, ac97); ret = ad1980_reset(codec, 0); @@ -268,6 +304,8 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) return 0; reset_err: + snd_soc_codec_exit_regmap(codec); +err_free_ac97: snd_soc_free_ac97_codec(ac97); return ret; } @@ -276,6 +314,7 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec) { struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); + snd_soc_codec_exit_regmap(codec); snd_soc_free_ac97_codec(ac97); return 0; } @@ -283,12 +322,6 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .probe = ad1980_soc_probe, .remove = ad1980_soc_remove, - .reg_cache_size = ARRAY_SIZE(ad1980_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = ad1980_reg, - .reg_cache_step = 2, - .write = ac97_write, - .read = ac97_read, .controls = ad1980_snd_ac97_controls, .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), -- GitLab From 17bb577328a00e7251c8e552471b6583173ca77d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Nov 2014 19:45:54 +0100 Subject: [PATCH 5254/9457] ASoC: ad1980: Remove ac97_read/ac97_write wrappers Since the regmap conversion ac97_read/ac97_write are just simple wrappers around snd_soc_read/snd_soc_write. Use those instead directly and remove the wrappers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ad1980.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 5fd4a29a2fe0..2860eef8610c 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -186,18 +186,6 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = { { "HP_OUT_R", NULL, "Playback" }, }; -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return snd_soc_read(codec, reg); -} - -static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - return snd_soc_write(codec, reg, val); -} - static struct snd_soc_dai_driver ad1980_dai = { .name = "ad1980-hifi", .playback = { @@ -222,7 +210,7 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) do { if (try_warm && soc_ac97_ops->warm_reset) { soc_ac97_ops->warm_reset(ac97); - if (ac97_read(codec, AC97_RESET) == 0x0090) + if (snd_soc_read(codec, AC97_RESET) == 0x0090) return 1; } @@ -233,9 +221,9 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) * case the first nibble of data is eaten by the addr. (Tag is * always 16 bit) */ - ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900); + snd_soc_write(codec, AC97_AD_SERIAL_CFG, 0x9900); - if (ac97_read(codec, AC97_RESET) == 0x0090) + if (snd_soc_read(codec, AC97_RESET) == 0x0090) return 0; } while (retry_cnt++ < 10); @@ -273,12 +261,12 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) goto reset_err; /* Read out vendor ID to make sure it is ad1980 */ - if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) { + if (snd_soc_read(codec, AC97_VENDOR_ID1) != 0x4144) { ret = -ENODEV; goto reset_err; } - vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); + vendor_id2 = snd_soc_read(codec, AC97_VENDOR_ID2); if (vendor_id2 != 0x5370) { if (vendor_id2 != 0x5374) { @@ -291,15 +279,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) } /* unmute captures and playbacks volume */ - ac97_write(codec, AC97_MASTER, 0x0000); - ac97_write(codec, AC97_PCM, 0x0000); - ac97_write(codec, AC97_REC_GAIN, 0x0000); - ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000); - ac97_write(codec, AC97_SURROUND_MASTER, 0x0000); + snd_soc_write(codec, AC97_MASTER, 0x0000); + snd_soc_write(codec, AC97_PCM, 0x0000); + snd_soc_write(codec, AC97_REC_GAIN, 0x0000); + snd_soc_write(codec, AC97_CENTER_LFE_MASTER, 0x0000); + snd_soc_write(codec, AC97_SURROUND_MASTER, 0x0000); /*power on LFE/CENTER/Surround DACs*/ - ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); + ext_status = snd_soc_read(codec, AC97_EXTENDED_STATUS); + snd_soc_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); return 0; -- GitLab From 92a6e2a227da5fcaa5b31c9124eabf8c64a6d9f9 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 19 Nov 2014 15:13:26 +0530 Subject: [PATCH 5255/9457] ASoC: Intel: cleanup runtime_pm initialization For ACPI we missed to pm_runtime_enable() call which is required to tell PM core that runtime on this device is enabled now. Since this is common to both PCI and APCI move it out. Also for ACPI we do not require pm_runtime_allow() call, so remove that Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index b2b5604943b5..9e68a7cefd1b 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -378,13 +378,13 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) * initially active. So change the state to active before * enabling the pm */ - if (acpi_disabled) { + pm_runtime_enable(ctx->dev); + + if (acpi_disabled) pm_runtime_set_active(ctx->dev); - pm_runtime_enable(ctx->dev); - } else { - pm_runtime_allow(ctx->dev); + else pm_runtime_put_noidle(ctx->dev); - } + sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); } EXPORT_SYMBOL_GPL(sst_configure_runtime_pm); -- GitLab From 51b04d59c27430a57c347b55478415c342009035 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 16 Nov 2014 21:08:49 +0100 Subject: [PATCH 5256/9457] firewire: ohci: replace vm_map_ram() with vmap() vm_map_ram() is intended for short-lived objects, so using it for the AR buffers could fragment address space, especially on a 32-bit machine. For an allocation that lives as long as the device, vmap() is the better choice. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index a66a3217f1d9..aff9018d0658 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -689,8 +689,7 @@ static void ar_context_release(struct ar_context *ctx) { unsigned int i; - if (ctx->buffer) - vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); + vunmap(ctx->buffer); for (i = 0; i < AR_BUFFERS; i++) if (ctx->pages[i]) { @@ -1018,8 +1017,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, pages[i] = ctx->pages[i]; for (i = 0; i < AR_WRAPAROUND_PAGES; i++) pages[AR_BUFFERS + i] = ctx->pages[i]; - ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES, - -1, PAGE_KERNEL); + ctx->buffer = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL); if (!ctx->buffer) goto out_of_memory; -- GitLab From 84f017a7b998563ee1f8d0249d0ec7ba295b6427 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 10:29:07 +0100 Subject: [PATCH 5257/9457] ARM: at91/dt: sama5d4: use macro instead of numeric value There is a macro for the irq type. Signed-off-by: Ludovic Desroches Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index e0157b0f075c..338dfd85658f 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -817,7 +817,7 @@ i2c2: i2c@f8024000 { compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8024000 0x4000>; - interrupts = <34 4 6>; + interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; #address-cells = <1>; -- GitLab From b3c7a497059cd9020ece1a3dfaddbadb4b7d38b6 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 13 Nov 2014 14:18:44 +0100 Subject: [PATCH 5258/9457] ARM: at91/dt: sama5d4: add DMA support Add DMA controllers and device configurations. Signed-off-by: Ludovic Desroches Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d4.dtsi | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 338dfd85658f..05e0526a82d2 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -45,6 +45,7 @@ #include "skeleton.dtsi" #include +#include #include #include #include @@ -302,6 +303,15 @@ #size-cells = <1>; ranges; + dma1: dma-controller@f0004000 { + compatible = "atmel,sama5d4-dma"; + reg = <0xf0004000 0x200>; + interrupts = <50 IRQ_TYPE_LEVEL_HIGH 0>; + #dma-cells = <1>; + clocks = <&dma1_clk>; + clock-names = "dma_clk"; + }; + ramc0: ramc@f0010000 { compatible = "atmel,sama5d3-ddramc"; reg = <0xf0010000 0x200>; @@ -309,6 +319,15 @@ clock-names = "ddrck", "mpddr"; }; + dma0: dma-controller@f0014000 { + compatible = "atmel,sama5d4-dma"; + reg = <0xf0014000 0x200>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH 0>; + #dma-cells = <1>; + clocks = <&dma0_clk>; + clock-names = "dma_clk"; + }; + pmc: pmc@f0018000 { compatible = "atmel,sama5d3-pmc"; reg = <0xf0018000 0x120>; @@ -761,6 +780,10 @@ compatible = "atmel,hsmci"; reg = <0xf8000000 0x600>; interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(0))>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3>; status = "disabled"; @@ -776,6 +799,13 @@ compatible = "atmel,at91rm9200-spi"; reg = <0xf8010000 0x100>; interrupts = <37 IRQ_TYPE_LEVEL_HIGH 3>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(10))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(11))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0>; clocks = <&spi0_clk>; @@ -787,6 +817,13 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8014000 0x4000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(2))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(3))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c0>; #address-cells = <1>; @@ -818,6 +855,13 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8024000 0x4000>; interrupts = <34 IRQ_TYPE_LEVEL_HIGH 6>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(6))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(7))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; #address-cells = <1>; @@ -830,6 +874,10 @@ compatible = "atmel,hsmci"; reg = <0xfc000000 0x600>; interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(1))>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>; status = "disabled"; @@ -843,6 +891,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfc008000 0x100>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(16))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(17))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rts &pinctrl_usart2_cts>; clocks = <&usart2_clk>; @@ -854,6 +909,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfc00c000 0x100>; interrupts = <30 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(18))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(19))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart3>; clocks = <&usart3_clk>; @@ -865,6 +927,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfc010000 0x100>; interrupts = <31 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(20))>, + <&dma1 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) + | AT91_XDMAC_DT_PERID(21))>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart4>; clocks = <&usart4_clk>; -- GitLab From f0213fe85d0eae3aee9deaa484298e08c3a54a18 Mon Sep 17 00:00:00 2001 From: Qiang Chen Date: Mon, 17 Nov 2014 17:25:01 +0800 Subject: [PATCH 5259/9457] video: ARM CLCD: Remove duplicated include in amba-clcd.c This patch fixes duplicated include dma-mapping.h in drivers/video/fbdev/amba-clcd.c Signed-off-by: Qiang Chen Acked-by: Pawel Moll Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/amba-clcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 6ad23bd3523a..32c0b6b28097 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include -- GitLab From 151a49d0792203ab735020b5777bb636420a2a11 Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Thu, 13 Nov 2014 18:50:10 -0800 Subject: [PATCH 5260/9457] drm/i915: Extend pcode mailbox interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In sandybridge_pcode_read and sandybridge_pcode_write, extend the mbox parameter from u8 to u32. On Haswell and Sandybridge, bits 7:0 encode the mailbox command and bits 28:8 are used for address control for specific commands. Based on suggestion from Ville Syrjälä. Signed-off-by: Tom O'Rourke Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c4f2cb6f4234..a8cfb1496229 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2975,8 +2975,8 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine); void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine); void assert_force_wake_inactive(struct drm_i915_private *dev_priv); -int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val); +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val); /* intel_sideband.c */ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 929648f2373f..4e39d74541e8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7158,7 +7158,7 @@ void intel_init_pm(struct drm_device *dev) } } -int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) { WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); @@ -7183,7 +7183,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) return 0; } -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val) { WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); -- GitLab From f061b9be74dbb83f383daa7c95bfa22ae011a81e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 18 Nov 2014 09:45:52 -0800 Subject: [PATCH 5261/9457] drm/i915/ddi: set has_infoframe flag on DDI too v2 Just like we do in the HDMI code, set the infoframe flag if we detect that infoframes are enabled. v2: check for actual infoframe status as in hdmi code (Daniel) Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 07c562598596..24110c96e539 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2075,6 +2075,14 @@ void intel_ddi_get_config(struct intel_encoder *encoder, break; } + if (encoder->type == INTEL_OUTPUT_HDMI) { + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&encoder->base); + + if (intel_hdmi->infoframe_enabled(&encoder->base)) + pipe_config->has_infoframe = true; + } + if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe)) -- GitLab From 9dc806fc1a9445c721aacf15a141c2758e518e90 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 17 Nov 2014 18:10:38 -0800 Subject: [PATCH 5262/9457] drm/i915: Don't store panning coordinates as 16.16 fixed point MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the universal plane interface, the source rectangle coordinates define the panning offset for the primary plane, which needs to be stored in crtc->{x,y}. The original universal plane code negelected to set these panning offset fields, which was partially remedied in: commit ccc759dc2a0214fd8b65ed4ebe78050874a67f94 Author: Gustavo Padovan Date: Wed Sep 24 14:20:22 2014 -0300 drm/i915: Merge of visible and !visible paths for primary planes However the plane source coordinates are provided in 16.16 fixed point format and the above commit forgot to convert back to integer coordinates before saving the values. When we replace intel_pipe_set_base() with plane->funcs->update_plane() in a future patch, this bug becomes visible via the set_config entrypoint as well as update_plane. Cc: Gustavo Padovan Testcase: igt/kms_plane Signed-off-by: Matt Roper Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f84738d5820e..32cec9d208d4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11765,8 +11765,8 @@ intel_commit_primary_plane(struct drm_plane *plane, struct drm_rect *src = &state->src; crtc->primary->fb = fb; - crtc->x = src->x1; - crtc->y = src->y1; + crtc->x = src->x1 >> 16; + crtc->y = src->y1 >> 16; intel_plane->crtc_x = state->orig_dst.x1; intel_plane->crtc_y = state->orig_dst.y1; -- GitLab From 4a74de821af510fcb3224d16ceed6a6609730d9c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 15:30:01 +0200 Subject: [PATCH 5263/9457] drm/i915: WARN if we receive any rps interrupts on gen>9 This extends commit 132f3f1767dbabfb01f3c9bd63098c65d91eeac9 Author: Imre Deak Date: Mon Nov 10 15:34:33 2014 +0200 drm/i915: WARN if we receive any gen9 rps interrupts to GEN>9 platforms as suggested by Paulo. Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e298518c944e..21c579e74451 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1689,9 +1689,9 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) * the work queue. */ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) { - /* TODO: RPS on GEN9 is not supported yet. */ - if (WARN_ONCE(INTEL_INFO(dev_priv)->gen == 9, - "GEN9: unexpected RPS IRQ\n")) + /* TODO: RPS on GEN9+ is not supported yet. */ + if (WARN_ONCE(INTEL_INFO(dev_priv)->gen >= 9, + "GEN9+: unexpected RPS IRQ\n")) return; if (pm_iir & dev_priv->pm_rps_events) { -- GitLab From e534770addd798e17b95372b4cd61682d1bf9296 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 15:30:02 +0200 Subject: [PATCH 5264/9457] drm/i915: move rps irq disable one level up We disable the RPS interrupts for all platforms at the same spot, so move it one level up in the callstack to simplify things. No functional change. v2: - rebase on the GEN9 patches where RPS isn't supported yet, so we don't need to disable RPS interrupts on it (Paulo) v3: - avoid disabling the interrupts on GEN>9 too (Paulo) Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4e39d74541e8..cdd00f156826 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4526,8 +4526,6 @@ static void gen6_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_CONTROL, 0); I915_WRITE(GEN6_RPNSWREQ, 1 << 31); - - gen6_disable_rps_interrupts(dev); } static void cherryview_disable_rps(struct drm_device *dev) @@ -4535,8 +4533,6 @@ static void cherryview_disable_rps(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; I915_WRITE(GEN6_RC_CONTROL, 0); - - gen6_disable_rps_interrupts(dev); } static void valleyview_disable_rps(struct drm_device *dev) @@ -4550,8 +4546,6 @@ static void valleyview_disable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_CONTROL, 0); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); - - gen6_disable_rps_interrupts(dev); } static void intel_print_rc6_info(struct drm_device *dev, u32 mode) @@ -6230,6 +6224,14 @@ void intel_disable_gt_powersave(struct drm_device *dev) valleyview_disable_rps(dev); else gen6_disable_rps(dev); + + /* + * TODO: disable RPS interrupts on GEN9+ too once RPS support + * is added for it. + */ + if (INTEL_INFO(dev)->gen < 9) + gen6_disable_rps_interrupts(dev); + dev_priv->rps.enabled = false; mutex_unlock(&dev_priv->rps.hw_lock); } -- GitLab From 3cc134e3ee09055d5a87193fc7eb0ecf4a59eaa1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 15:30:03 +0200 Subject: [PATCH 5265/9457] drm/i915: sanitize rps irq enabling Atm we first enable the RPS interrupts then we clear any pending ones. By this we could lose an interrupt arriving after we unmasked it. This may not be a problem as the caller should handle such a race, but logic still calls for the opposite order. Also we can delay enabling the interrupts until after all the RPS initialization is ready with the following order: 1. disable left-over RPS (earlier via intel_uncore_sanitize) 2. clear any pending RPS interrupts 3. initialize RPS 4. enable RPS interrupts This also allows us to do the 2. and 4. step the same way for all platforms, so let's follow this order to simplifying things. Also make sure any queued interrupts are also cleared. v2: - rebase on the GEN9 patches where we don't support RPS yet, so we musn't enable RPS interrupts on it (Paulo) v3: - avoid enabling RPS interrupts on GEN>9 too (Paulo) - clarify the RPS init sequence in the log message (Chris) - add POSTING_READ to gen6_reset_rps_interrupts() (Paulo) - WARN if any PM_IIR bits are set in gen6_enable_rps_interrupts() (Paulo) Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 14 +++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 19 +++++++++++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 21c579e74451..56b30534176a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -255,14 +255,26 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) snb_update_pm_irq(dev_priv, mask, 0); } +void gen6_reset_rps_interrupts(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t reg = gen6_pm_iir(dev_priv); + + spin_lock_irq(&dev_priv->irq_lock); + I915_WRITE(reg, dev_priv->pm_rps_events); + I915_WRITE(reg, dev_priv->pm_rps_events); + POSTING_READ(reg); + spin_unlock_irq(&dev_priv->irq_lock); +} + void gen6_enable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; spin_lock_irq(&dev_priv->irq_lock); WARN_ON(dev_priv->rps.pm_iir); + WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); - I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d1f9b639f0d1..f0a46ecf3f3a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -791,6 +791,7 @@ void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); +void gen6_reset_rps_interrupts(struct drm_device *dev); void gen6_enable_rps_interrupts(struct drm_device *dev); void gen6_disable_rps_interrupts(struct drm_device *dev); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cdd00f156826..c5b2636093b1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4747,8 +4747,6 @@ static void gen8_enable_rps(struct drm_device *dev) gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); - gen6_enable_rps_interrupts(dev); - gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } @@ -4845,8 +4843,6 @@ static void gen6_enable_rps(struct drm_device *dev) dev_priv->rps.power = HIGH_POWER; /* force a reset */ gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); - gen6_enable_rps_interrupts(dev); - rc6vids = 0; ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); if (IS_GEN6(dev) && ret) { @@ -5348,8 +5344,6 @@ static void cherryview_enable_rps(struct drm_device *dev) valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq); - gen6_enable_rps_interrupts(dev); - gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } @@ -5431,8 +5425,6 @@ static void valleyview_enable_rps(struct drm_device *dev) valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq); - gen6_enable_rps_interrupts(dev); - gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } @@ -6246,6 +6238,13 @@ static void intel_gen6_powersave_work(struct work_struct *work) mutex_lock(&dev_priv->rps.hw_lock); + /* + * TODO: reset/enable RPS interrupts on GEN9+ too, once RPS support is + * added for it. + */ + if (INTEL_INFO(dev)->gen < 9) + gen6_reset_rps_interrupts(dev); + if (IS_CHERRYVIEW(dev)) { cherryview_enable_rps(dev); } else if (IS_VALLEYVIEW(dev)) { @@ -6260,6 +6259,10 @@ static void intel_gen6_powersave_work(struct work_struct *work) __gen6_update_ring_freq(dev); } dev_priv->rps.enabled = true; + + if (INTEL_INFO(dev)->gen < 9) + gen6_enable_rps_interrupts(dev); + mutex_unlock(&dev_priv->rps.hw_lock); intel_runtime_pm_put(dev_priv); -- GitLab From d4d70aa5960a7fbf3d887663f144c324a10619ba Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 15:30:04 +0200 Subject: [PATCH 5266/9457] drm/i915: sanitize rps irq disabling When disabling the RPS interrupts there is a tricky dependency between the thread disabling the interrupts, the RPS interrupt handler and the corresponding RPS work. The RPS work can reenable the interrupts, so there is no straightforward order in the disabling thread to (1) make sure that any RPS work is flushed and to (2) disable all RPS interrupts. Currently this is solved by masking the interrupts using two separate mask registers (first level display IMR and PM IMR) and doing the disabling when all first level interrupts are disabled. This works, but the requirement to run with all first level interrupts disabled is unnecessary making the suspend / unload time ordering of RPS disabling wrt. other unitialization steps difficult and error prone. Removing this restriction allows us to disable RPS early during suspend / unload and forget about it for the rest of the sequence. By adding a more explicit method for avoiding the above race, it also becomes easier to prove its correctness. Finally currently we can hit the WARN in snb_update_pm_irq(), when a final RPS work runs with the first level interrupts already disabled. This won't lead to any problem (due to the separate interrupt masks), but with the change in this and the next patch we can get rid of the WARN, while leaving it in place for other scenarios. To address the above points, add a new RPS interrupts_enabled flag and use this during RPS disabling to avoid requeuing the RPS work and reenabling of the RPS interrupts. Since the interrupt disabling happens now in intel_suspend_gt_powersave(), we will disable RPS interrupts explicitly during suspend (and not just through the first level mask), but there is no problem doing so, it's also more consistent and allows us to unify more of the RPS disabling during suspend and unload time in the next patch. v2/v3: - rebase on patch "drm/i915: move rps irq disable one level up" in the patchset Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 +++++- drivers/gpu/drm/i915/i915_irq.c | 23 ++++++++++++++++------- drivers/gpu/drm/i915/intel_pm.c | 17 +++++++++-------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a8cfb1496229..4f08160d6192 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -998,8 +998,12 @@ struct intel_rps_ei { }; struct intel_gen6_power_mgmt { - /* work and pm_iir are protected by dev_priv->irq_lock */ + /* + * work, interrupts_enabled and pm_iir are protected by + * dev_priv->irq_lock + */ struct work_struct work; + bool interrupts_enabled; u32 pm_iir; /* Frequencies are stored in potentially platform dependent multiples. diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 56b30534176a..283756fe48d3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -274,6 +274,7 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) spin_lock_irq(&dev_priv->irq_lock); WARN_ON(dev_priv->rps.pm_iir); WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); + dev_priv->rps.interrupts_enabled = true; gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); } @@ -282,14 +283,16 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + spin_lock_irq(&dev_priv->irq_lock); + dev_priv->rps.interrupts_enabled = false; + spin_unlock_irq(&dev_priv->irq_lock); + + cancel_work_sync(&dev_priv->rps.work); + I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & ~dev_priv->pm_rps_events); - /* Complete PM interrupt masking here doesn't race with the rps work - * item again unmasking PM interrupts because that is using a different - * register (PMIMR) to mask PM interrupts. The only risk is in leaving - * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ spin_lock_irq(&dev_priv->irq_lock); dev_priv->rps.pm_iir = 0; @@ -1135,6 +1138,11 @@ static void gen6_pm_rps_work(struct work_struct *work) int new_delay, adj; spin_lock_irq(&dev_priv->irq_lock); + /* Speed up work cancelation during disabling rps interrupts. */ + if (!dev_priv->rps.interrupts_enabled) { + spin_unlock_irq(&dev_priv->irq_lock); + return; + } pm_iir = dev_priv->rps.pm_iir; dev_priv->rps.pm_iir = 0; /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ @@ -1708,11 +1716,12 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) if (pm_iir & dev_priv->pm_rps_events) { spin_lock(&dev_priv->irq_lock); - dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); + if (dev_priv->rps.interrupts_enabled) { + dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; + queue_work(dev_priv->wq, &dev_priv->rps.work); + } spin_unlock(&dev_priv->irq_lock); - - queue_work(dev_priv->wq, &dev_priv->rps.work); } if (INTEL_INFO(dev_priv)->gen >= 8) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c5b2636093b1..96a948a18833 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6186,9 +6186,17 @@ void intel_suspend_gt_powersave(struct drm_device *dev) /* Interrupts should be disabled already to avoid re-arming. */ WARN_ON(intel_irqs_enabled(dev_priv)); + if (INTEL_INFO(dev)->gen < 6) + return; + flush_delayed_work(&dev_priv->rps.delayed_resume_work); - cancel_work_sync(&dev_priv->rps.work); + /* + * TODO: disable RPS interrupts on GEN9+ too once RPS support + * is added for it. + */ + if (INTEL_INFO(dev)->gen < 9) + gen6_disable_rps_interrupts(dev); /* Force GPU to min freq during suspend */ gen6_rps_idle(dev_priv); @@ -6217,13 +6225,6 @@ void intel_disable_gt_powersave(struct drm_device *dev) else gen6_disable_rps(dev); - /* - * TODO: disable RPS interrupts on GEN9+ too once RPS support - * is added for it. - */ - if (INTEL_INFO(dev)->gen < 9) - gen6_disable_rps_interrupts(dev); - dev_priv->rps.enabled = false; mutex_unlock(&dev_priv->rps.hw_lock); } -- GitLab From 2eb5252e2fffc52745a672152c7df597f4041045 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 15:30:05 +0200 Subject: [PATCH 5267/9457] drm/i915: disable rps irqs earlier during suspend/unload After the previous patch RPS disabling doesn't depend any more on the first level interrupts being disabled, so we can move it everywhere earlier. Doing so let's us think about the uninitialization steps afterwards independently of any asynchronous RPS events that can happen atm. It also makes the system/runtime suspend time RPS disabling more uniform. Finally this gets rid of the WARN in intel_suspend_gt_powersave(), which we can hit if a final RPS work runs after we disabled the first level interrupts. Testcase: igt/pm_rpm Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939 Signed-off-by: Imre Deak Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 9 +++------ drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_pm.c | 3 --- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 122ea9549110..19558d61b032 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -584,6 +584,8 @@ static int i915_drm_suspend(struct drm_device *dev) return error; } + intel_suspend_gt_powersave(dev); + /* * Disable CRTCs directly since we want to preserve sw state * for _thaw. Also, power gate the CRTC power wells. @@ -595,15 +597,11 @@ static int i915_drm_suspend(struct drm_device *dev) intel_dp_mst_suspend(dev); - flush_delayed_work(&dev_priv->rps.delayed_resume_work); - intel_runtime_pm_disable_interrupts(dev_priv); intel_hpd_cancel_work(dev_priv); intel_suspend_encoders(dev_priv); - intel_suspend_gt_powersave(dev); - intel_suspend_hw(dev); } @@ -1393,9 +1391,8 @@ static int intel_runtime_suspend(struct device *device) i915_gem_release_all_mmaps(dev_priv); mutex_unlock(&dev->struct_mutex); - flush_delayed_work(&dev_priv->rps.delayed_resume_work); - intel_runtime_pm_disable_interrupts(dev_priv); intel_suspend_gt_powersave(dev); + intel_runtime_pm_disable_interrupts(dev_priv); ret = intel_suspend_complete(dev_priv); if (ret) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 32cec9d208d4..ca4b787f98a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13540,11 +13540,13 @@ void intel_modeset_cleanup(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; + intel_disable_gt_powersave(dev); + intel_backlight_unregister(dev); /* * Interrupts and polling as the first thing to avoid creating havoc. - * Too much stuff here (turning of rps, connectors, ...) would + * Too much stuff here (turning of connectors, ...) would * experience fancy races otherwise. */ intel_irq_uninstall(dev_priv); @@ -13561,8 +13563,6 @@ void intel_modeset_cleanup(struct drm_device *dev) intel_disable_fbc(dev); - intel_disable_gt_powersave(dev); - ironlake_teardown_rc6(dev); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 96a948a18833..41c51febb502 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6183,9 +6183,6 @@ void intel_suspend_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* Interrupts should be disabled already to avoid re-arming. */ - WARN_ON(intel_irqs_enabled(dev_priv)); - if (INTEL_INFO(dev)->gen < 6) return; -- GitLab From 1d2a05630b26874342790de2745877b70596fa9c Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 19 Nov 2014 14:52:05 +0100 Subject: [PATCH 5268/9457] ARM: at91: fix GPLv2 wording During the submission of these new sama5d4 files, the GPL notice mentioned the device tree as a library, which is not really accurate. Fix all these library mentions to reflect the fact that it's actually just a file. Reported-by: Maxime Ripard Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91-sama5d4ek.dts | 4 ++-- arch/arm/boot/dts/sama5d4.dtsi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index b5b84006469e..9198b719d0ef 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -9,12 +9,12 @@ * licensing only applies to this file, and not this project as a * whole. * - * a) This library is free software; you can redistribute it and/or + * a) This file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * This file 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. diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 05e0526a82d2..1b0f30c2c4a5 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -9,12 +9,12 @@ * licensing only applies to this file, and not this project as a * whole. * - * a) This library is free software; you can redistribute it and/or + * a) This file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * This file 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. -- GitLab From 30043f4ebbe6574418eeaf3fe9025f4019702880 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 1 Oct 2014 18:41:32 +0200 Subject: [PATCH 5269/9457] ARM: at91/dt: at91sam9rl: add rtc Add rtc support to the at91sam9rl dtsi file. Signed-off-by: Alexandre Belloni Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9rl.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index f0b4352650ed..505c1956cf8d 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -1059,6 +1059,13 @@ clocks = <&slow_rc_osc &slow_osc>; }; }; + + rtc@fffffeb0 { + compatible = "atmel,at91rm9200-rtc"; + reg = <0xfffffeb0 0x40>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + status = "disabled"; + }; }; }; -- GitLab From 9b5a0675072eb3b217cbbb3f8958addcbf27d740 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 14 Nov 2014 11:08:49 +0100 Subject: [PATCH 5270/9457] ARM: at91/dt: add RTT nodes to at91 dtsis at91sam926x, at91sam9g45 and at91sam9rl SoCs all have at least one RTT block. Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9260.dtsi | 8 ++++++++ arch/arm/boot/dts/at91sam9261.dtsi | 8 ++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 15 +++++++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 8 ++++++++ arch/arm/boot/dts/at91sam9rl.dtsi | 8 ++++++++ 5 files changed, 47 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index cb100b03a362..9ea824ee84d2 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -956,6 +956,14 @@ }; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; + watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index a81aab4281a7..06b11fc9057f 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi @@ -828,6 +828,14 @@ clocks = <&mck>; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; + status = "disabled"; + }; + watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 653e4395b7cb..7f37b7e97e9c 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -922,6 +922,21 @@ pinctrl-0 = <&pinctrl_can_rx_tx>; clocks = <&can_clk>; clock-names = "can_clk"; + }; + + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; + status = "disabled"; + }; + + rtc@fffffd50 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd50 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&slow_xtal>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index d3f65130a1f8..3771088bc36e 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -1192,6 +1192,14 @@ }; }; + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; + rtc@fffffdb0 { compatible = "atmel,at91rm9200-rtc"; reg = <0xfffffdb0 0x30>; diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 505c1956cf8d..254cbbad4576 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -1066,6 +1066,14 @@ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + rtc@fffffd20 { + compatible = "atmel,at91sam9260-rtt"; + reg = <0xfffffd20 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&clk32k>; + status = "disabled"; + }; }; }; -- GitLab From 1ff3beca55a4eb552068ebda34431a19c6534be6 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 14 Nov 2014 11:08:50 +0100 Subject: [PATCH 5271/9457] ARM: at91/dt: add GPBR nodes Add GPBR (General Purpose Block Backup Registers) nodes. Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9260.dtsi | 6 ++++++ arch/arm/boot/dts/at91sam9261.dtsi | 6 ++++++ arch/arm/boot/dts/at91sam9263.dtsi | 6 ++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 6 ++++++ arch/arm/boot/dts/at91sam9rl.dtsi | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 9ea824ee84d2..dd1313cbc314 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -974,6 +974,12 @@ atmel,idle-halt; status = "disabled"; }; + + gpbr: syscon@fffffd50 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd50 0x10>; + status = "disabled"; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index 06b11fc9057f..cdb9ed612109 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi @@ -842,6 +842,12 @@ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + gpbr: syscon@fffffd50 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd50 0x10>; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 7f37b7e97e9c..1467750e3377 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -939,6 +939,12 @@ clocks = <&slow_xtal>; status = "disabled"; }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x50>; + status = "disabled"; + }; }; fb0: fb@0x00700000 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 3771088bc36e..18453d98c2e7 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -1206,6 +1206,12 @@ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x10>; + status = "disabled"; + }; }; fb0: fb@0x00500000 { diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 254cbbad4576..72424371413e 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -1074,6 +1074,12 @@ clocks = <&clk32k>; status = "disabled"; }; + + gpbr: syscon@fffffd60 { + compatible = "atmel,at91sam9260-gpbr", "syscon"; + reg = <0xfffffd60 0x10>; + status = "disabled"; + }; }; }; -- GitLab From 846fdce623242c3a5ba0ebb0b14560fbb2b96e0d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 14 Nov 2014 11:08:51 +0100 Subject: [PATCH 5272/9457] ARM: at91/dt: enable the RTT block on the sam9g20ek board Enable the RTT and GPBR devices and specify the general purpose register used to store the current time. Enable wakeup on RTT event on the shutdown controller device. Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index d2919108e92d..dfaacb113f2e 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -112,9 +112,23 @@ }; }; + shdwc@fffffd10 { + atmel,wakeup-counter = <10>; + atmel,wakeup-rtt-timer; + }; + + rtc@fffffd20 { + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; + status = "okay"; + }; + watchdog@fffffd40 { status = "okay"; }; + + gpbr: syscon@fffffd50 { + status = "okay"; + }; }; nand0: nand@40000000 { -- GitLab From 199ec7ab1122c79ba8a2d0a15d272123cc3fcbcb Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 14 Nov 2014 11:08:52 +0100 Subject: [PATCH 5273/9457] ARM: at91/dt: enable the RTT block on the at91sam9m10g45ek board Enable the RTT and GPBR devices and specify the general purpose register used to store the current time. Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9m10g45ek.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index d8dd22651090..33ce7ca2c404 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -161,6 +161,15 @@ pinctrl-0 = <&pinctrl_pwm_leds>; }; + rtc@fffffd20 { + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; + status = "okay"; + }; + + gpbr: syscon@fffffd60 { + status = "okay"; + }; + rtc@fffffdb0 { status = "okay"; }; -- GitLab From f5084933673e57d38492198f04b0e81b6d00dfb2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 19 Nov 2014 10:11:39 +0100 Subject: [PATCH 5274/9457] i2c: imx: simplify i2c_imx_dma_write() a little Signed-off-by: Wolfram Sang Acked-by: Yao Yuan --- drivers/i2c/busses/i2c-imx.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index d0668d0d626d..aab1f4bb9e30 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -657,11 +657,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx, if (result) return result; - result = i2c_imx_acked(i2c_imx); - if (result) - return result; - - return 0; + return i2c_imx_acked(i2c_imx); } static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx, -- GitLab From 8cfcae9f0595bf0d145a67cfaa1051804a301d7c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 19 Nov 2014 13:43:22 +0100 Subject: [PATCH 5275/9457] i2c: sh_mobile: use proper device for mapping DMA memory It should be the DMA device, not the platform device. Signed-off-by: Wolfram Sang Acked-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-sh_mobile.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 92c7f7b56bdf..c7f36c1ce688 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -507,6 +507,17 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static void sh_mobile_i2c_dma_unmap(struct sh_mobile_i2c_data *pd) +{ + struct dma_chan *chan = pd->dma_direction == DMA_FROM_DEVICE + ? pd->dma_rx : pd->dma_tx; + + dma_unmap_single(chan->device->dev, sg_dma_address(&pd->sg), + pd->msg->len, pd->dma_direction); + + pd->dma_direction = DMA_NONE; +} + static void sh_mobile_i2c_cleanup_dma(struct sh_mobile_i2c_data *pd) { if (pd->dma_direction == DMA_NONE) @@ -516,20 +527,14 @@ static void sh_mobile_i2c_cleanup_dma(struct sh_mobile_i2c_data *pd) else if (pd->dma_direction == DMA_TO_DEVICE) dmaengine_terminate_all(pd->dma_tx); - dma_unmap_single(pd->dev, sg_dma_address(&pd->sg), - pd->msg->len, pd->dma_direction); - - pd->dma_direction = DMA_NONE; + sh_mobile_i2c_dma_unmap(pd); } static void sh_mobile_i2c_dma_callback(void *data) { struct sh_mobile_i2c_data *pd = data; - dma_unmap_single(pd->dev, sg_dma_address(&pd->sg), - pd->msg->len, pd->dma_direction); - - pd->dma_direction = DMA_NONE; + sh_mobile_i2c_dma_unmap(pd); pd->pos = pd->msg->len; iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); @@ -547,7 +552,7 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) if (!chan) return; - dma_addr = dma_map_single(pd->dev, pd->msg->buf, pd->msg->len, dir); + dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); if (dma_mapping_error(pd->dev, dma_addr)) { dev_dbg(pd->dev, "dma map failed, using PIO\n"); return; -- GitLab From fa040c24b19d8067c57fa488660361b122d2138e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 14 Nov 2014 17:03:30 +0100 Subject: [PATCH 5276/9457] DT: i2c: Add more devices handled by the rtc-rs5c372 driver This allows checkpatch to validate more DTSes. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/trivial-devices.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index fbde415078e6..7a2bbea61b70 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -74,7 +74,12 @@ ovti,ov5642 OV5642: Color CMOS QSXGA (5-megapixel) Image Sensor with OmniBSI an pericom,pt7c4338 Real-time Clock Module plx,pex8648 48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch ramtron,24c64 i2c serial eeprom (24cxx) +ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +ricoh,rs5c372b I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC samsung,24ad0xd1 S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power) sii,s35390a 2-wire CMOS real-time clock st-micro,24c256 i2c serial eeprom (24cxx) -- GitLab From 11321585f91bcb6de64376c3d767fb3200e20b53 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 14 Nov 2014 17:03:31 +0100 Subject: [PATCH 5277/9457] DT: i2c: Add more devices handled by the adxl34x-i2c driver This allows checkpatch to validate more DTSes. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/trivial-devices.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 7a2bbea61b70..e0beef4f8cff 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -17,6 +17,9 @@ adi,adt7473 +/-1C TDM Extended Temp Range I.C adi,adt7475 +/-1C TDM Extended Temp Range I.C adi,adt7476 +/-1C TDM Extended Temp Range I.C adi,adt7490 +/-1C TDM Extended Temp Range I.C +adi,adxl345 Three-Axis Digital Accelerometer +adi,adxl346 Three-Axis Digital Accelerometer +adi,adxl34x Three-Axis Digital Accelerometer at,24c08 i2c serial eeprom (24cxx) atmel,24c00 i2c serial eeprom (24cxx) atmel,24c01 i2c serial eeprom (24cxx) -- GitLab From accda2736fcab10fc3eb35da935e0e049188f6d5 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 30 Sep 2014 18:19:47 +0200 Subject: [PATCH 5278/9457] ARM: at91/dt: at91sam9g45: add ISI node Add ISI (Image Sensor Interface) DT node + pinctrl definition. Signed-off-by: Boris Brezillon Signed-off-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9g45.dtsi | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 18453d98c2e7..c13424228d06 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -492,6 +492,27 @@ }; }; + isi { + pinctrl_isi: isi-0 { + atmel,pins = ; + }; + }; + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @@ -1028,6 +1049,17 @@ }; }; + isi@fffb4000 { + compatible = "atmel,at91sam9g45-isi"; + reg = <0xfffb4000 0x4000>; + interrupts = <26 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&isi_clk>; + clock-names = "isi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isi>; + status = "disabled"; + }; + pwm0: pwm@fffb8000 { compatible = "atmel,at91sam9rl-pwm"; reg = <0xfffb8000 0x300>; -- GitLab From 08d53aa58cb162e65e25dbe31d28438657cb8e33 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 14 Nov 2014 18:05:35 +0100 Subject: [PATCH 5279/9457] of/fdt: export fdt blob as /sys/firmware/fdt Create a new /sys entry '/sys/firmware/fdt' to export the FDT blob that was passed to the kernel by the bootloader. This allows userland applications such as kexec to access the raw binary. The fact that this node does not reside under /sys/firmware/device-tree is deliberate: FDT is also used on arm64 UEFI/ACPI systems to communicate just the UEFI and ACPI entry points, but the FDT is never unflattened and used to configure the system. A CRC32 checksum is calculated over the entire FDT blob, and verified at late_initcall time. The sysfs entry is instantiated only if the checksum is valid, i.e., if the FDT blob has not been modified in the mean time. Otherwise, a warning is printed. Signed-off-by: Ard Biesheuvel Signed-off-by: Grant Likely --- drivers/of/Kconfig | 1 + drivers/of/fdt.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index be16ce2ffd69..fbe8f8d418f7 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -23,6 +23,7 @@ config OF_FLATTREE bool select DTC select LIBFDT + select CRC32 config OF_EARLY_FLATTREE bool diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 83a8e1154602..cb19adfb3933 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -9,6 +9,7 @@ * version 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include /* for COMMAND_LINE_SIZE */ #include @@ -423,6 +425,8 @@ void *initial_boot_params; #ifdef CONFIG_OF_EARLY_FLATTREE +static u32 of_fdt_crc32; + /** * res_mem_reserve_reg() - reserve all memory described in 'reg' property */ @@ -1003,6 +1007,8 @@ bool __init early_init_dt_verify(void *params) /* Setup flat device-tree pointer */ initial_boot_params = params; + of_fdt_crc32 = crc32_be(~0, initial_boot_params, + fdt_totalsize(initial_boot_params)); return true; } @@ -1080,27 +1086,32 @@ void __init unflatten_and_copy_device_tree(void) unflatten_device_tree(); } -#if defined(CONFIG_DEBUG_FS) && defined(DEBUG) -static struct debugfs_blob_wrapper flat_dt_blob; - -static int __init of_flat_dt_debugfs_export_fdt(void) +#ifdef CONFIG_SYSFS +static ssize_t of_fdt_raw_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) { - struct dentry *d = debugfs_create_dir("device-tree", NULL); - - if (!d) - return -ENOENT; + memcpy(buf, initial_boot_params + off, count); + return count; +} - flat_dt_blob.data = initial_boot_params; - flat_dt_blob.size = fdt_totalsize(initial_boot_params); +static int __init of_fdt_raw_init(void) +{ + static struct bin_attribute of_fdt_raw_attr = + __BIN_ATTR(fdt, S_IRUSR, of_fdt_raw_read, NULL, 0); - d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, - d, &flat_dt_blob); - if (!d) - return -ENOENT; + if (!initial_boot_params) + return 0; - return 0; + if (of_fdt_crc32 != crc32_be(~0, initial_boot_params, + fdt_totalsize(initial_boot_params))) { + pr_warn("fdt: not creating '/sys/firmware/fdt': CRC check failed\n"); + return 0; + } + of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params); + return sysfs_create_bin_file(firmware_kobj, &of_fdt_raw_attr); } -module_init(of_flat_dt_debugfs_export_fdt); +late_initcall(of_fdt_raw_init); #endif #endif /* CONFIG_OF_EARLY_FLATTREE */ -- GitLab From 22a3ceabf152c7c88afa9e34ea33fc3fa55e6cf8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Nov 2014 13:16:41 +0200 Subject: [PATCH 5280/9457] Bluetooth: Fix setting state back to TASK_RUNNING In __hci_cmd_sync_ev() and __hci_req_sync() if the hci_req_run() call fails and we return from the functions we should ensure that the state doesn't remain in TASK_INTERRUPTIBLE that we just set it to. This patch fixes missing calls to set_current_state(TASK_RUNNING) in both places. Reported-by: Kirill A. Shutemov Signed-off-by: Johan Hedberg Tested-by: Kirill A. Shutemov Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d786958a1dec..a67a4b8e4e1c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1128,6 +1128,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, err = hci_req_run(&req, hci_req_sync_complete); if (err < 0) { remove_wait_queue(&hdev->req_wait_q, &wait); + set_current_state(TASK_RUNNING); return ERR_PTR(err); } @@ -1196,6 +1197,7 @@ static int __hci_req_sync(struct hci_dev *hdev, hdev->req_status = 0; remove_wait_queue(&hdev->req_wait_q, &wait); + set_current_state(TASK_RUNNING); /* ENODATA means the HCI request command queue is empty. * This can happen when a request with conditionals doesn't -- GitLab From e7181d005e84b15fe3121a8d22840adc3395d496 Mon Sep 17 00:00:00 2001 From: Martin Hauke Date: Sun, 16 Nov 2014 21:17:30 +0100 Subject: [PATCH 5281/9457] USB: qcserial: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem Added new device layout "DEVICE_HWI" and also added the USB VID/PID for the HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) Signed-off-by: Martin Hauke Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/qcserial.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index b2aa003bf411..cb3e14780a7e 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -27,12 +27,15 @@ enum qcserial_layouts { QCSERIAL_G2K = 0, /* Gobi 2000 */ QCSERIAL_G1K = 1, /* Gobi 1000 */ QCSERIAL_SWI = 2, /* Sierra Wireless */ + QCSERIAL_HWI = 3, /* Huawei */ }; #define DEVICE_G1K(v, p) \ USB_DEVICE(v, p), .driver_info = QCSERIAL_G1K #define DEVICE_SWI(v, p) \ USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI +#define DEVICE_HWI(v, p) \ + USB_DEVICE(v, p), .driver_info = QCSERIAL_HWI static const struct usb_device_id id_table[] = { /* Gobi 1000 devices */ @@ -157,6 +160,9 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x413c, 0x81a8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */ {DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ + /* Huawei devices */ + {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); @@ -287,6 +293,33 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) break; } break; + case QCSERIAL_HWI: + /* + * Huawei layout: + * 0: AT-capable modem port + * 1: DM/DIAG + * 2: AT-capable modem port + * 3: CCID-compatible PCSC interface + * 4: QMI/net + * 5: NMEA + */ + switch (ifnum) { + case 0: + case 2: + dev_dbg(dev, "Modem port found\n"); + break; + case 1: + dev_dbg(dev, "DM/DIAG interface found\n"); + break; + case 5: + dev_dbg(dev, "NMEA GPS interface found\n"); + break; + default: + /* don't claim any unsupported interface */ + altsetting = -1; + break; + } + break; default: dev_err(dev, "unsupported device layout type: %lu\n", id->driver_info); -- GitLab From cb6f3f7ace0e61285db22508a9efd8a5aeca0af5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Nov 2014 14:53:04 +0200 Subject: [PATCH 5282/9457] Bluetooth: Fix setting conn->pending_sec_level value from link key When a connection is requested the conn->pending_sec_level value gets set to whatever level the user requested the connection to be. During the pairing process there are various sanity checks to try to ensure that the right length PIN or right IO Capability is used to satisfy the target security level. However, when we finally get hold of the link key that is to be used we should still set the actual final security level from the key type. This way when we eventually get an Encrypt Change event the correct value gets copied to conn->sec_level. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_event.c | 47 +++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 844f7d1ff1cd..54680fd39608 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3191,6 +3191,38 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } +static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) +{ + if (key_type == HCI_LK_CHANGED_COMBINATION) + return; + + conn->pin_length = pin_len; + conn->key_type = key_type; + + switch (key_type) { + case HCI_LK_LOCAL_UNIT: + case HCI_LK_REMOTE_UNIT: + case HCI_LK_DEBUG_COMBINATION: + return; + case HCI_LK_COMBINATION: + if (pin_len == 16) + conn->pending_sec_level = BT_SECURITY_HIGH; + else + conn->pending_sec_level = BT_SECURITY_MEDIUM; + break; + case HCI_LK_UNAUTH_COMBINATION_P192: + case HCI_LK_UNAUTH_COMBINATION_P256: + conn->pending_sec_level = BT_SECURITY_MEDIUM; + break; + case HCI_LK_AUTH_COMBINATION_P192: + conn->pending_sec_level = BT_SECURITY_HIGH; + break; + case HCI_LK_AUTH_COMBINATION_P256: + conn->pending_sec_level = BT_SECURITY_FIPS; + break; + } +} + static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_link_key_req *ev = (void *) skb->data; @@ -3232,8 +3264,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) goto not_found; } - conn->key_type = key->type; - conn->pin_length = key->pin_len; + conn_set_key(conn, key->type, key->pin_len); } bacpy(&cp.bdaddr, &ev->bdaddr); @@ -3266,12 +3297,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) if (conn) { hci_conn_hold(conn); conn->disc_timeout = HCI_DISCONN_TIMEOUT; - pin_len = conn->pin_length; - - if (ev->key_type != HCI_LK_CHANGED_COMBINATION) - conn->key_type = ev->key_type; - hci_conn_drop(conn); + conn_set_key(conn, ev->key_type, conn->pin_length); } if (!test_bit(HCI_MGMT, &hdev->dev_flags)) @@ -3282,6 +3309,12 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) if (!key) goto unlock; + /* Update connection information since adding the key will have + * fixed up the type in the case of changed combination keys. + */ + if (ev->key_type == HCI_LK_CHANGED_COMBINATION) + conn_set_key(conn, key->type, key->pin_len); + mgmt_new_link_key(hdev, key, persistent); /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag -- GitLab From 0378b59770130a994272b176a2a4346dc27361e9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Nov 2014 15:22:22 +0200 Subject: [PATCH 5283/9457] Bluetooth: Convert link keys list to use RCU This patch converts the hdev->link_keys list to be protected through RCU, thereby eliminating the need to hold the hdev lock while accessing the list. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 37 ++++++++++++++++---------------- net/bluetooth/hci_event.c | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a805b3d97c0b..396c09840fdf 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -130,6 +130,7 @@ struct smp_irk { struct link_key { struct list_head list; + struct rcu_head rcu; bdaddr_t bdaddr; u8 type; u8 val[HCI_LINK_KEY_SIZE]; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a67a4b8e4e1c..5c319a49a5a4 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -274,15 +274,13 @@ static const struct file_operations inquiry_cache_fops = { static int link_keys_show(struct seq_file *f, void *ptr) { struct hci_dev *hdev = f->private; - struct list_head *p, *n; + struct link_key *key; - hci_dev_lock(hdev); - list_for_each_safe(p, n, &hdev->link_keys) { - struct link_key *key = list_entry(p, struct link_key, list); + rcu_read_lock(); + list_for_each_entry_rcu(key, &hdev->link_keys, list) seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, HCI_LINK_KEY_SIZE, key->val, key->pin_len); - } - hci_dev_unlock(hdev); + rcu_read_unlock(); return 0; } @@ -3101,15 +3099,11 @@ void hci_uuids_clear(struct hci_dev *hdev) void hci_link_keys_clear(struct hci_dev *hdev) { - struct list_head *p, *n; - - list_for_each_safe(p, n, &hdev->link_keys) { - struct link_key *key; - - key = list_entry(p, struct link_key, list); + struct link_key *key; - list_del(p); - kfree(key); + list_for_each_entry_rcu(key, &hdev->link_keys, list) { + list_del_rcu(&key->list); + kfree_rcu(key, rcu); } } @@ -3137,9 +3131,14 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) { struct link_key *k; - list_for_each_entry(k, &hdev->link_keys, list) - if (bacmp(bdaddr, &k->bdaddr) == 0) + rcu_read_lock(); + list_for_each_entry_rcu(k, &hdev->link_keys, list) { + if (bacmp(bdaddr, &k->bdaddr) == 0) { + rcu_read_unlock(); return k; + } + } + rcu_read_unlock(); return NULL; } @@ -3290,7 +3289,7 @@ struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, key = kzalloc(sizeof(*key), GFP_KERNEL); if (!key) return NULL; - list_add(&key->list, &hdev->link_keys); + list_add_rcu(&key->list, &hdev->link_keys); } BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); @@ -3383,8 +3382,8 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) BT_DBG("%s removing %pMR", hdev->name, bdaddr); - list_del(&key->list); - kfree(key); + list_del_rcu(&key->list); + kfree_rcu(key, rcu); return 0; } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 54680fd39608..bd0a80120665 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3324,8 +3324,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) */ if (key->type == HCI_LK_DEBUG_COMBINATION && !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) { - list_del(&key->list); - kfree(key); + list_del_rcu(&key->list); + kfree_rcu(key, rcu); } else if (conn) { if (persistent) clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); -- GitLab From 098ea6bc4cb5890d09b1b79154fa11182e0f71e0 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 19 Nov 2014 01:28:32 -0800 Subject: [PATCH 5284/9457] Bluetooth: btmrvl: add DT bindings documentation Calibration data can be downloaded through device tree method. This patch adds the documentation. Also, instead of searching device tree node by name using of_find_node_by_name() API, let's use for_each_compatible_node(). Signed-off-by: Amitkumar Karwar Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/btmrvl.txt | 22 ++++++++++++++ drivers/bluetooth/btmrvl_main.c | 31 +++++++++----------- 2 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 Documentation/devicetree/bindings/btmrvl.txt diff --git a/Documentation/devicetree/bindings/btmrvl.txt b/Documentation/devicetree/bindings/btmrvl.txt new file mode 100644 index 000000000000..cdd57680a749 --- /dev/null +++ b/Documentation/devicetree/bindings/btmrvl.txt @@ -0,0 +1,22 @@ +btmrvl +------ + +Required properties: + + - compatible : must be "btmrvl,cfgdata" + +Optional properties: + + - btmrvl,cal-data : Calibration data downloaded to the device during + initialization. This is an array of 28 values(u8). + +Example: + +btmrvl { + compatible = "btmrvl,cfgdata"; + + btmrvl,cal-data = /bits/ 8 < + 0x37 0x01 0x1c 0x00 0xff 0xff 0xff 0xff 0x01 0x7f 0x04 0x02 + 0x00 0x00 0xba 0xce 0xc0 0xc6 0x2d 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0xf0 0x00>; +}; diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 1d7db2064889..2909bca6b8b6 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -496,25 +496,22 @@ static int btmrvl_cal_data_dt(struct btmrvl_private *priv) { struct device_node *dt_node; u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE]; - const char name[] = "btmrvl_caldata"; - const char property[] = "btmrvl,caldata"; int ret; - dt_node = of_find_node_by_name(NULL, name); - if (!dt_node) - return -ENODEV; - - ret = of_property_read_u8_array(dt_node, property, - cal_data + BT_CAL_HDR_LEN, - BT_CAL_DATA_SIZE); - if (ret) - return ret; - - BT_DBG("Use cal data from device tree"); - ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE); - if (ret) { - BT_ERR("Fail to download calibrate data"); - return ret; + for_each_compatible_node(dt_node, NULL, "btmrvl,cfgdata") { + ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data", + cal_data + BT_CAL_HDR_LEN, + BT_CAL_DATA_SIZE); + if (ret) + return ret; + + BT_DBG("Use cal data from device tree"); + ret = btmrvl_download_cal_data(priv, cal_data, + BT_CAL_DATA_SIZE); + if (ret) { + BT_ERR("Fail to download calibrate data"); + return ret; + } } return 0; -- GitLab From 025a60a752261fd479a4bb74cf7cb04fdc313ec7 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 19 Nov 2014 01:28:33 -0800 Subject: [PATCH 5285/9457] Bluetooth: btmrvl: add DT-bindings for gpio-gap This can be used to have GPIO host wakeup method suitable for the platform and configurable GAP for host sleep handshake. Signed-off-by: Amitkumar Karwar Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Marcel Holtmann --- Documentation/devicetree/bindings/btmrvl.txt | 7 +++++++ drivers/bluetooth/btmrvl_main.c | 12 +++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/btmrvl.txt b/Documentation/devicetree/bindings/btmrvl.txt index cdd57680a749..58f964bb0a52 100644 --- a/Documentation/devicetree/bindings/btmrvl.txt +++ b/Documentation/devicetree/bindings/btmrvl.txt @@ -10,8 +10,14 @@ Optional properties: - btmrvl,cal-data : Calibration data downloaded to the device during initialization. This is an array of 28 values(u8). + - btmrvl,gpio-gap : gpio and gap (in msecs) combination to be + configured. + Example: +GPIO pin 13 is configured as a wakeup source and GAP is set to 100 msecs +in below example. + btmrvl { compatible = "btmrvl,cfgdata"; @@ -19,4 +25,5 @@ btmrvl { 0x37 0x01 0x1c 0x00 0xff 0xff 0xff 0xff 0x01 0x7f 0x04 0x02 0x00 0x00 0xba 0xce 0xc0 0xc6 0x2d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xf0 0x00>; + btmrvl,gpio-gap = <0x0d64>; }; diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 2909bca6b8b6..e43c495e8181 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -492,13 +492,18 @@ static int btmrvl_download_cal_data(struct btmrvl_private *priv, return 0; } -static int btmrvl_cal_data_dt(struct btmrvl_private *priv) +static int btmrvl_check_device_tree(struct btmrvl_private *priv) { struct device_node *dt_node; u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE]; int ret; + u32 val; for_each_compatible_node(dt_node, NULL, "btmrvl,cfgdata") { + ret = of_property_read_u32(dt_node, "btmrvl,gpio-gap", &val); + if (!ret) + priv->btmrvl_dev.gpio_gap = val; + ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data", cal_data + BT_CAL_HDR_LEN, BT_CAL_DATA_SIZE); @@ -523,14 +528,15 @@ static int btmrvl_setup(struct hci_dev *hdev) btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); - btmrvl_cal_data_dt(priv); + priv->btmrvl_dev.gpio_gap = 0xffff; + + btmrvl_check_device_tree(priv); btmrvl_pscan_window_reporting(priv, 0x01); priv->btmrvl_dev.psmode = 1; btmrvl_enable_ps(priv); - priv->btmrvl_dev.gpio_gap = 0xffff; btmrvl_send_hscfg_cmd(priv); return 0; -- GitLab From 4c79e1dd3e121bd5aae0425c48f877a5de07e6d6 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 19 Nov 2014 01:28:34 -0800 Subject: [PATCH 5286/9457] Bluetooth: btmrvl: update hs_state in interrupt handler Host sleep status flag should be reset when there is an interrupt from device. Signed-off-by: Amitkumar Karwar Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index e43c495e8181..bb0d2c26a479 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -41,6 +41,11 @@ void btmrvl_interrupt(struct btmrvl_private *priv) priv->adapter->int_count++; + if (priv->adapter->hs_state == HS_ACTIVATED) { + BT_DBG("BT: HS DEACTIVATED in ISR!\n"); + priv->adapter->hs_state = HS_DEACTIVATED; + } + wake_up_interruptible(&priv->main_thread.wait_q); } EXPORT_SYMBOL_GPL(btmrvl_interrupt); @@ -323,6 +328,7 @@ int btmrvl_prepare_command(struct btmrvl_private *priv) } else { ret = priv->hw_wakeup_firmware(priv); priv->adapter->hs_state = HS_DEACTIVATED; + BT_DBG("BT: HS DEACTIVATED due to host activity!\n"); } } -- GitLab From a32c99e7ab8410bae7c276a7e94ca84d108de034 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 17 Nov 2014 17:11:42 +0100 Subject: [PATCH 5287/9457] HID: yet another buggy ELAN touchscreen The touchscreen needs the same quirk as the other models. Signed-off-by: Oliver Neukum Reported-by: Bryan Poling CC: stable@vger.kernel.org Acked-by: Greg Kroah-Hartman Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + drivers/usb/core/quirks.c | 3 +++ 3 files changed, 5 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7c863738e419..a7c1c1d9706d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -300,6 +300,7 @@ #define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089 #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103 0x0103 +#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c 0x010c #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f #define USB_VENDOR_ID_ELECOM 0x056e diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 552671ee7c5d..3e5f169d35f3 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -73,6 +73,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 39b4081b632d..8e8bc4f9d2f0 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -100,6 +100,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04f3, 0x009b), .driver_info = USB_QUIRK_DEVICE_QUALIFIER }, + { USB_DEVICE(0x04f3, 0x010c), .driver_info = + USB_QUIRK_DEVICE_QUALIFIER }, + { USB_DEVICE(0x04f3, 0x016f), .driver_info = USB_QUIRK_DEVICE_QUALIFIER }, -- GitLab From 98280374ff1750acfa582a4575b94f053a29f749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giedrius=20Statkevi=C4=8Dius?= Date: Sat, 18 Oct 2014 02:57:20 +0300 Subject: [PATCH 5288/9457] drivers: platform: change 0x20 to I8042_STR_AUXDATA in i8042 filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using a magic constant 0x20 in some drivers to get data only from the KBC port we should use the constant defined in i8042.h with the same value. Also, this makes these drivers uniform with what constant the only other filter function uses in drivers/input/misc/ideapad_slidebar.c. Signed-off-by: Giedrius Statkevičius Signed-off-by: Darren Hart --- drivers/platform/x86/dell-laptop.c | 2 +- drivers/platform/x86/msi-laptop.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 233d2ee598a6..60bfc8ebc541 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -564,7 +564,7 @@ static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, { static bool extended; - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; if (unlikely(data == 0xe0)) { diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 62f8030b9e77..206a7d964d40 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -821,7 +821,7 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, { static bool extended; - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/ diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index ab6151f05420..96076d99cf33 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1589,7 +1589,7 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, struct serio *port) { - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; if (unlikely(data == 0xe0)) -- GitLab From 248d490363906806e0a2ac8417a8bb3f3f8a012c Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:36 +0200 Subject: [PATCH 5289/9457] eeepc-laptop: flatten control flow In eeepc_rfkill_hotplug there's an if statement with a big tail that ends right before the out_unlock label. We might as well invert the condition and jump to out_unlock in that case, pretty much like the rest of the code does. This removes an indentation level for a large chunk of code and also stops suggesting there might be an else clause. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 89 +++++++++++++++-------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index db79902c4a8e..bb098e547121 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -580,59 +580,60 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) mutex_lock(&eeepc->hotplug_lock); pci_lock_rescan_remove(); - if (eeepc->hotplug_slot) { - port = acpi_get_pci_dev(handle); - if (!port) { - pr_warning("Unable to find port\n"); - goto out_unlock; - } + if (!eeepc->hotplug_slot) + goto out_unlock; - bus = port->subordinate; + port = acpi_get_pci_dev(handle); + if (!port) { + pr_warning("Unable to find port\n"); + goto out_unlock; + } - if (!bus) { - pr_warn("Unable to find PCI bus 1?\n"); - goto out_put_dev; - } + bus = port->subordinate; - if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { - pr_err("Unable to read PCI config space?\n"); - goto out_put_dev; - } + if (!bus) { + pr_warn("Unable to find PCI bus 1?\n"); + goto out_put_dev; + } + + if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { + pr_err("Unable to read PCI config space?\n"); + goto out_put_dev; + } - absent = (l == 0xffffffff); + absent = (l == 0xffffffff); - if (blocked != absent) { - pr_warn("BIOS says wireless lan is %s, " - "but the pci device is %s\n", - blocked ? "blocked" : "unblocked", - absent ? "absent" : "present"); - pr_warn("skipped wireless hotplug as probably " - "inappropriate for this model\n"); + if (blocked != absent) { + pr_warn("BIOS says wireless lan is %s, " + "but the pci device is %s\n", + blocked ? "blocked" : "unblocked", + absent ? "absent" : "present"); + pr_warn("skipped wireless hotplug as probably " + "inappropriate for this model\n"); + goto out_put_dev; + } + + if (!blocked) { + dev = pci_get_slot(bus, 0); + if (dev) { + /* Device already present */ + pci_dev_put(dev); goto out_put_dev; } - - if (!blocked) { - dev = pci_get_slot(bus, 0); - if (dev) { - /* Device already present */ - pci_dev_put(dev); - goto out_put_dev; - } - dev = pci_scan_single_device(bus, 0); - if (dev) { - pci_bus_assign_resources(bus); - pci_bus_add_device(dev); - } - } else { - dev = pci_get_slot(bus, 0); - if (dev) { - pci_stop_and_remove_bus_device(dev); - pci_dev_put(dev); - } + dev = pci_scan_single_device(bus, 0); + if (dev) { + pci_bus_assign_resources(bus); + pci_bus_add_device(dev); + } + } else { + dev = pci_get_slot(bus, 0); + if (dev) { + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } -out_put_dev: - pci_dev_put(port); } +out_put_dev: + pci_dev_put(port); out_unlock: pci_unlock_rescan_remove(); -- GitLab From 9f662b20d6cef8afbbf954de66dece78faf4bcc1 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:37 +0200 Subject: [PATCH 5290/9457] eeepc-laptop: don't break user visible strings As per Documentation/CodingStyle ch. 2, it is preferred that we don't break user visible strings, in order to allow users to grep for them. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index bb098e547121..6e3be01ca011 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -417,8 +417,7 @@ static ssize_t cpufv_disabled_store(struct device *dev, switch (value) { case 0: if (eeepc->cpufv_disabled) - pr_warn("cpufv enabled (not officially supported " - "on this model)\n"); + pr_warn("cpufv enabled (not officially supported on this model)\n"); eeepc->cpufv_disabled = false; return count; case 1: @@ -604,12 +603,10 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) absent = (l == 0xffffffff); if (blocked != absent) { - pr_warn("BIOS says wireless lan is %s, " - "but the pci device is %s\n", + pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n", blocked ? "blocked" : "unblocked", absent ? "absent" : "present"); - pr_warn("skipped wireless hotplug as probably " - "inappropriate for this model\n"); + pr_warn("skipped wireless hotplug as probably inappropriate for this model\n"); goto out_put_dev; } @@ -1295,8 +1292,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc) */ if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) { eeepc->cpufv_disabled = true; - pr_info("model %s does not officially support setting cpu " - "speed\n", model); + pr_info("model %s does not officially support setting cpu speed\n", + model); pr_info("cpufv disabled to avoid instability\n"); } @@ -1322,8 +1319,8 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name) Check if cm_getv[cm] works and, if yes, assume cm should be set. */ if (!(eeepc->cm_supported & (1 << cm)) && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) { - pr_info("%s (%x) not reported by BIOS," - " enabling anyway\n", name, 1 << cm); + pr_info("%s (%x) not reported by BIOS, enabling anyway\n", + name, 1 << cm); eeepc->cm_supported |= 1 << cm; } } -- GitLab From 792bd2a58f924fca7ed45d0cacfa5ae5cfb42e65 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:38 +0200 Subject: [PATCH 5291/9457] eeepc-laptop: define rfkill notifier nodes only once The rfkill notifier node names are used in three different places. As a matter of style, it is better to store them somewhere and have the compiler warn us about typos in the function arguments. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6e3be01ca011..e92ea4187cdf 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -819,11 +819,15 @@ static int eeepc_new_rfkill(struct eeepc_laptop *eeepc, return 0; } +static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5"; +static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6"; +static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7"; + static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) { - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3); if (eeepc->wlan_rfkill) { rfkill_unregister(eeepc->wlan_rfkill); rfkill_destroy(eeepc->wlan_rfkill); @@ -895,9 +899,9 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc) if (result == -EBUSY) result = 0; - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3); exit: if (result && result != -ENODEV) @@ -933,9 +937,9 @@ static int eeepc_hotk_restore(struct device *device) /* Refresh both wlan rfkill state and pci hotplug */ if (eeepc->wlan_rfkill) { - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5"); - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6"); - eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7"); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2); + eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3); } if (eeepc->bluetooth_rfkill) -- GitLab From a5de681c0cf7350fa13ccd67f1a118f1651cc2d5 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:41 +0200 Subject: [PATCH 5292/9457] eeepc-laptop: replace magic numbers with defines eeepc_[gs]et_fan_ctrl uses some magic numbers. These numbers mean something more than just the number. Describe them with macros instead of comments in one of the functions. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index e92ea4187cdf..c1758ec3c61b 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1005,15 +1005,19 @@ static int eeepc_get_fan_rpm(void) return high << 8 | low; } +#define EEEPC_EC_FAN_CTRL_BIT 0x02 +#define EEEPC_FAN_CTRL_MANUAL 1 +#define EEEPC_FAN_CTRL_AUTO 2 + static int eeepc_get_fan_ctrl(void) { u8 value = 0; ec_read(EEEPC_EC_FAN_CTRL, &value); - if (value & 0x02) - return 1; /* manual */ + if (value & EEEPC_EC_FAN_CTRL_BIT) + return EEEPC_FAN_CTRL_MANUAL; else - return 2; /* automatic */ + return EEEPC_FAN_CTRL_AUTO; } static void eeepc_set_fan_ctrl(int manual) @@ -1021,10 +1025,10 @@ static void eeepc_set_fan_ctrl(int manual) u8 value = 0; ec_read(EEEPC_EC_FAN_CTRL, &value); - if (manual == 1) - value |= 0x02; + if (manual == EEEPC_FAN_CTRL_MANUAL) + value |= EEEPC_EC_FAN_CTRL_BIT; else - value &= ~0x02; + value &= ~EEEPC_EC_FAN_CTRL_BIT; ec_write(EEEPC_EC_FAN_CTRL, value); } -- GitLab From 148a5dd5ccc25581b44a38079128f49e47353713 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:42 +0200 Subject: [PATCH 5293/9457] eeepc-laptop: document fan_pwm conversions eeepc_get_fan_pwm and eeepc_set_fan_pwm convert the PWM value read from the fan to a range lmsensors understands. Unfortunately this is only clear if you are familiar with how lmsensors handles duty cycles. Introduce two conversion functions that document the goal of these conversions. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index c1758ec3c61b..e87c1346e1d4 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -980,18 +980,28 @@ static struct platform_driver platform_driver = { #define EEEPC_EC_SFB0 0xD0 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */ +static inline int eeepc_pwm_to_lmsensors(int value) +{ + return value * 255 / 100; +} + +static inline int eeepc_lmsensors_to_pwm(int value) +{ + value = clamp_val(value, 0, 255); + return value * 100 / 255; +} + static int eeepc_get_fan_pwm(void) { u8 value = 0; ec_read(EEEPC_EC_FAN_PWM, &value); - return value * 255 / 100; + return eeepc_pwm_to_lmsensors(value); } static void eeepc_set_fan_pwm(int value) { - value = clamp_val(value, 0, 255); - value = value * 100 / 255; + value = eeepc_lmsensors_to_pwm(value); ec_write(EEEPC_EC_FAN_PWM, value); } -- GitLab From efef87296eb6bf7b9a21b16f81a6ddd5ee33b513 Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Wed, 22 Oct 2014 21:12:43 +0200 Subject: [PATCH 5294/9457] eeepc-laptop: don't assume get_acpi succeeds In eeepc_hotk_thaw, we assume that get_acpi() will effectively return a bool. However, it is possible that get_acpi() returns an error instead. We should not be writing error values to the ACPI device, even though it's quite possible that we couldn't contact the ACPI device in the first place. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index e87c1346e1d4..8f9dc9cf5994 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -917,7 +917,7 @@ static int eeepc_hotk_thaw(struct device *device) struct eeepc_laptop *eeepc = dev_get_drvdata(device); if (eeepc->wlan_rfkill) { - bool wlan; + int wlan; /* * Work around bios bug - acpi _PTS turns off the wireless led @@ -925,7 +925,8 @@ static int eeepc_hotk_thaw(struct device *device) * we should kick it ourselves in case hibernation is aborted. */ wlan = get_acpi(eeepc, CM_ASL_WLAN); - set_acpi(eeepc, CM_ASL_WLAN, wlan); + if (wlan >= 0) + set_acpi(eeepc, CM_ASL_WLAN, wlan); } return 0; -- GitLab From 049db626beae30769501abd946055aa9014d80af Mon Sep 17 00:00:00 2001 From: Chen Hanxiao Date: Wed, 29 Oct 2014 17:38:03 +0800 Subject: [PATCH 5295/9457] intel_ips: fix a comment typo s/tempurature/temperature/ Signed-off-by: Chen Hanxiao Signed-off-by: Darren Hart --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c0242ed13d9e..3c0323233a98 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -33,7 +33,7 @@ * performance by allocating more power or thermal budget to the CPU or GPU * based on available headroom and activity. * - * The basic algorithm is driven by a 5s moving average of tempurature. If + * The basic algorithm is driven by a 5s moving average of temperature. If * thermal headroom is available, the CPU and/or GPU power clamps may be * adjusted upwards. If we hit the thermal ceiling or a thermal trigger, * we scale back the clamp. Aside from trigger events (when we're critically -- GitLab From fb1d97a2c7a6b833043003e933dc1a67dd242d5a Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Sun, 2 Nov 2014 22:14:58 +0100 Subject: [PATCH 5296/9457] eeepc-laptop: clean up control flow in eeepc_acpi_notify eeepc_acpi_notify increases the indentation level to a whopping four. If we revise the conditions a bit, we can reduce that to a more soothing two and satisfy the indentation guidelines in Documentation/CodingStyle. Remove an unwanted space while we're in the neighbourhood. Signed-off-by: Frans Klaver Signed-off-by: Darren Hart --- drivers/platform/x86/eeepc-laptop.c | 53 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 8f9dc9cf5994..e4094b40a282 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1234,7 +1234,7 @@ static void eeepc_input_exit(struct eeepc_laptop *eeepc) static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) { if (!eeepc->inputdev) - return ; + return; if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true)) pr_info("Unknown key %x pressed\n", event); } @@ -1242,6 +1242,7 @@ static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) static void eeepc_acpi_notify(struct acpi_device *device, u32 event) { struct eeepc_laptop *eeepc = acpi_driver_data(device); + int old_brightness, new_brightness; u16 count; if (event > ACPI_MAX_SYS_NOTIFY) @@ -1252,34 +1253,32 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) count); /* Brightness events are special */ - if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { - - /* Ignore them completely if the acpi video driver is used */ - if (eeepc->backlight_device != NULL) { - int old_brightness, new_brightness; - - /* Update the backlight device. */ - old_brightness = eeepc_backlight_notify(eeepc); - - /* Convert event to keypress (obsolescent hack) */ - new_brightness = event - NOTIFY_BRN_MIN; - - if (new_brightness < old_brightness) { - event = NOTIFY_BRN_MIN; /* brightness down */ - } else if (new_brightness > old_brightness) { - event = NOTIFY_BRN_MAX; /* brightness up */ - } else { - /* - * no change in brightness - already at min/max, - * event will be desired value (or else ignored) - */ - } - eeepc_input_notify(eeepc, event); - } - } else { - /* Everything else is a bona-fide keypress event */ + if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) { eeepc_input_notify(eeepc, event); + return; + } + + /* Ignore them completely if the acpi video driver is used */ + if (!eeepc->backlight_device) + return; + + /* Update the backlight device. */ + old_brightness = eeepc_backlight_notify(eeepc); + + /* Convert event to keypress (obsolescent hack) */ + new_brightness = event - NOTIFY_BRN_MIN; + + if (new_brightness < old_brightness) { + event = NOTIFY_BRN_MIN; /* brightness down */ + } else if (new_brightness > old_brightness) { + event = NOTIFY_BRN_MAX; /* brightness up */ + } else { + /* + * no change in brightness - already at min/max, + * event will be desired value (or else ignored) + */ } + eeepc_input_notify(eeepc, event); } static void eeepc_dmi_check(struct eeepc_laptop *eeepc) -- GitLab From 7d882ffa81d52a19071952acf4460c06a38861e5 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:08 +0200 Subject: [PATCH 5297/9457] KVM: x86: Revert NoBigReal patch in the emulator Commit 10e38fc7cab6 ("KVM: x86: Emulator flag for instruction that only support 16-bit addresses in real mode") introduced NoBigReal for instructions such as MONITOR. Apparetnly, the Intel SDM description that led to this patch is misleading. Since no instruction is using NoBigReal, it is safe to remove it, we fully understand what the SDM means. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e020fed0b019..5d47714d895d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -690,13 +690,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, if (!fetch && (desc.type & 8) && !(desc.type & 2)) goto bad; lim = desc_limit_scaled(&desc); - if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch && - (ctxt->d & NoBigReal)) { - /* la is between zero and 0xffff */ - if (la > 0xffff) - goto bad; - *max_size = 0x10000 - la; - } else if ((desc.type & 8) || !(desc.type & 4)) { + if ((desc.type & 8) || !(desc.type & 4)) { /* expand-up segment */ if (addr.ea > lim) goto bad; -- GitLab From 1c1c35ae4b75d6fc08393a1f73a5a06dc68eebb8 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:09 +0200 Subject: [PATCH 5298/9457] KVM: x86: Stack size is overridden by __linearize When performing segmented-read/write in the emulator for stack operations, it ignores the stack size, and uses the ad_bytes as indication for the pointer size. As a result, a wrong address may be accessed. To fix this behavior, we can remove the masking of address in __linearize and perform it beforehand. It is already done for the operands (so currently it is inefficiently done twice). It is missing in two cases: 1. When using rip_relative 2. On fetch_bit_operand that changes the address. This patch masks the address on these two occassions, and removes the masking from __linearize. Note that it does not mask EIP during fetch. In protected/legacy mode code fetch when RIP >= 2^32 should result in #GP and not wrap-around. Since we make limit checks within __linearize, this is the expected behavior. Partial revert of commit 518547b32ab4 (KVM: x86: Emulator does not calculate address correctly, 2014-09-30). Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5d47714d895d..1317560d0823 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -665,8 +665,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, u16 sel; unsigned cpl; - la = seg_base(ctxt, addr.seg) + - (fetch || ctxt->ad_bytes == 8 ? addr.ea : (u32)addr.ea); + la = seg_base(ctxt, addr.seg) + addr.ea; *max_size = 0; switch (ctxt->mode) { case X86EMUL_MODE_PROT64: @@ -1289,7 +1288,8 @@ static void fetch_bit_operand(struct x86_emulate_ctxt *ctxt) else sv = (s64)ctxt->src.val & (s64)mask; - ctxt->dst.addr.mem.ea += (sv >> 3); + ctxt->dst.addr.mem.ea = address_mask(ctxt, + ctxt->dst.addr.mem.ea + (sv >> 3)); } /* only subword offset */ @@ -4638,7 +4638,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask); if (ctxt->rip_relative) - ctxt->memopp->addr.mem.ea += ctxt->_eip; + ctxt->memopp->addr.mem.ea = address_mask(ctxt, + ctxt->memopp->addr.mem.ea + ctxt->_eip); done: return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; -- GitLab From a7315d2f3c6c4ff37b27c652dba70939d94d436c Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:10 +0200 Subject: [PATCH 5299/9457] KVM: x86: Emulator performs privilege checks on __linearize When segment is accessed, real hardware does not perform any privilege level checks. In contrast, KVM emulator does. This causes some discrepencies from real hardware. For instance, reading from readable code segment may fail due to incorrect segment checks. In addition, it introduces unnecassary overhead. To reference Intel SDM 5.5 ("Privilege Levels"): "Privilege levels are checked when the segment selector of a segment descriptor is loaded into a segment register." The SDM never mentions privilege level checks during memory access, except for loading far pointers in section 5.10 ("Pointer Validation"). Those are actually segment selector loads and are emulated in the similarily (i.e., regardless to __linearize checks). This behavior was also checked using sysexit. A data-segment whose DPL=0 was loaded, and after sysexit (CPL=3) it is still accessible. Therefore, all the privilege level checks in __linearize are removed. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1317560d0823..d9461e47a65d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -663,7 +663,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, ulong la; u32 lim; u16 sel; - unsigned cpl; la = seg_base(ctxt, addr.seg) + addr.ea; *max_size = 0; @@ -705,20 +704,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, } if (size > *max_size) goto bad; - cpl = ctxt->ops->cpl(ctxt); - if (!fetch) { - /* data segment or readable code segment */ - if (cpl > desc.dpl) - goto bad; - } else if ((desc.type & 8) && !(desc.type & 4)) { - /* nonconforming code segment */ - if (cpl != desc.dpl) - goto bad; - } else if ((desc.type & 8) && (desc.type & 4)) { - /* conforming code segment */ - if (cpl < desc.dpl) - goto bad; - } break; } if (ctxt->mode != X86EMUL_MODE_PROT64) -- GitLab From d50eaa18039b8b848c2285478d0775335ad5e930 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:11 +0200 Subject: [PATCH 5300/9457] KVM: x86: Perform limit checks when assigning EIP If branch (e.g., jmp, ret) causes limit violations, since the target IP > limit, the #GP exception occurs before the branch. In other words, the RIP pushed on the stack should be that of the branch and not that of the target. To do so, we can call __linearize, with new EIP, which also saves us the code which performs the canonical address checks. On the case of assigning an EIP >= 2^32 (when switching cs.l), we also safe, as __linearize will check the new EIP does not exceed the limit and would trigger #GP(0) otherwise. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 95 ++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d9461e47a65d..4d083fb9dd8e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -575,40 +575,6 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt) return emulate_exception(ctxt, NM_VECTOR, 0, false); } -static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, - int cs_l) -{ - switch (ctxt->op_bytes) { - case 2: - ctxt->_eip = (u16)dst; - break; - case 4: - ctxt->_eip = (u32)dst; - break; -#ifdef CONFIG_X86_64 - case 8: - if ((cs_l && is_noncanonical_address(dst)) || - (!cs_l && (dst >> 32) != 0)) - return emulate_gp(ctxt, 0); - ctxt->_eip = dst; - break; -#endif - default: - WARN(1, "unsupported eip assignment size\n"); - } - return X86EMUL_CONTINUE; -} - -static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) -{ - return assign_eip_far(ctxt, dst, ctxt->mode == X86EMUL_MODE_PROT64); -} - -static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) -{ - return assign_eip_near(ctxt, ctxt->_eip + rel); -} - static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg) { u16 selector; @@ -656,7 +622,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, struct segmented_address addr, unsigned *max_size, unsigned size, bool write, bool fetch, - ulong *linear) + enum x86emul_mode mode, ulong *linear) { struct desc_struct desc; bool usable; @@ -666,7 +632,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, la = seg_base(ctxt, addr.seg) + addr.ea; *max_size = 0; - switch (ctxt->mode) { + switch (mode) { case X86EMUL_MODE_PROT64: if (is_noncanonical_address(la)) return emulate_gp(ctxt, 0); @@ -725,9 +691,55 @@ static int linearize(struct x86_emulate_ctxt *ctxt, ulong *linear) { unsigned max_size; - return __linearize(ctxt, addr, &max_size, size, write, false, linear); + return __linearize(ctxt, addr, &max_size, size, write, false, + ctxt->mode, linear); } +static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst, + enum x86emul_mode mode) +{ + ulong linear; + int rc; + unsigned max_size; + struct segmented_address addr = { .seg = VCPU_SREG_CS, + .ea = dst }; + + if (ctxt->op_bytes != sizeof(unsigned long)) + addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1); + rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear); + if (rc == X86EMUL_CONTINUE) + ctxt->_eip = addr.ea; + return rc; +} + +static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) +{ + return assign_eip(ctxt, dst, ctxt->mode); +} + +static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, + const struct desc_struct *cs_desc) +{ + enum x86emul_mode mode = ctxt->mode; + +#ifdef CONFIG_X86_64 + if (ctxt->mode >= X86EMUL_MODE_PROT32 && cs_desc->l) { + u64 efer = 0; + + ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); + if (efer & EFER_LMA) + mode = X86EMUL_MODE_PROT64; + } +#endif + if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32) + mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; + return assign_eip(ctxt, dst, mode); +} + +static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) +{ + return assign_eip_near(ctxt, ctxt->_eip + rel); +} static int segmented_read_std(struct x86_emulate_ctxt *ctxt, struct segmented_address addr, @@ -766,7 +778,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) * boundary check itself. Instead, we use max_size to check * against op_size. */ - rc = __linearize(ctxt, addr, &max_size, 0, false, true, &linear); + rc = __linearize(ctxt, addr, &max_size, 0, false, true, ctxt->mode, + &linear); if (unlikely(rc != X86EMUL_CONTINUE)) return rc; @@ -2032,7 +2045,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) if (rc != X86EMUL_CONTINUE) return rc; - rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); + rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); if (rc != X86EMUL_CONTINUE) { WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); /* assigning eip failed; restore the old cs */ @@ -2120,7 +2133,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) &new_desc); if (rc != X86EMUL_CONTINUE) return rc; - rc = assign_eip_far(ctxt, eip, new_desc.l); + rc = assign_eip_far(ctxt, eip, &new_desc); if (rc != X86EMUL_CONTINUE) { WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); @@ -3010,7 +3023,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt) if (rc != X86EMUL_CONTINUE) return X86EMUL_CONTINUE; - rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); + rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); if (rc != X86EMUL_CONTINUE) goto fail; -- GitLab From abc7d8a4c935dbe0be5db2eb338b2ec9b27ae157 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:12 +0200 Subject: [PATCH 5301/9457] KVM: x86: Non-canonical access using SS should cause #SS When SS is used using a non-canonical address, an #SS exception is generated on real hardware. KVM emulator causes a #GP instead. Fix it to behave as real x86 CPU. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4d083fb9dd8e..57dc0d79c10e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -635,7 +635,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, switch (mode) { case X86EMUL_MODE_PROT64: if (is_noncanonical_address(la)) - return emulate_gp(ctxt, 0); + goto bad; *max_size = min_t(u64, ~0u, (1ull << 48) - la); if (size > *max_size) -- GitLab From 31ff64881bed80456c5d37df905bdb66cdf29abe Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 19 Nov 2014 17:43:13 +0200 Subject: [PATCH 5302/9457] KVM: x86: Move __linearize masking of la into switch In __linearize there is check of the condition whether to check if masking of the linear address is needed. It occurs immediately after switch that evaluates the same condition. Merge them. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 57dc0d79c10e..19a59f3f702c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -670,10 +670,9 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, } if (size > *max_size) goto bad; + la &= (u32)-1; break; } - if (ctxt->mode != X86EMUL_MODE_PROT64) - la &= (u32)-1; if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0)) return emulate_gp(ctxt, 0); *linear = la; -- GitLab From 83fc44c32ad8b8bb359d6d0e93071b6b23e831d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 11 Nov 2014 20:21:22 +0100 Subject: [PATCH 5303/9457] dell-wmi: Update code for processing WMI events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WMI buffer can contain multiple events. First value in buffer is length of event followed by data of specified length. After that is next length and next data. When length is zero then there is no more events in bufffer. This patch adds support for processing all events in buffer (not only first) and parse more event types (not only hotkey events). Because of variable length of events sometimes BIOS fills more hotkeys (or other values) into single WMI event. In this case this patch also processes these multiple hotkeys (and not only first one). Some event types are just ignored because kernel is not interested in them (e.g. NIC Link status, battery unplug, ...). This patch is based on DSDT table from Dell Latitude E6440. Code should be backward compatible so will process other events of old types same as before this patch. This patch also fixes a problem with unknown WMI event messages being written to the log. Now all known events are parsed and those which are not interesting to the kernel are dropped without an unknown WMI event message. Signed-off-by: Pali Rohár Tested-by: Pali Rohár Signed-off-by: Darren Hart --- drivers/platform/x86/dell-wmi.c | 159 +++++++++++++++++++++++++------- 1 file changed, 128 insertions(+), 31 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 25721bf20092..e2b6a642b3c5 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -145,57 +145,154 @@ static const u16 bios_to_linux_keycode[256] __initconst = { static struct input_dev *dell_wmi_input_dev; +static void dell_wmi_process_key(int reported_key) +{ + const struct key_entry *key; + + key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, + reported_key); + if (!key) { + pr_info("Unknown key %x pressed\n", reported_key); + return; + } + + pr_debug("Key %x pressed\n", reported_key); + + /* Don't report brightness notifications that will also come via ACPI */ + if ((key->keycode == KEY_BRIGHTNESSUP || + key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) + return; + + sparse_keymap_report_entry(dell_wmi_input_dev, key, 1, true); +} + static void dell_wmi_notify(u32 value, void *context) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; acpi_status status; + acpi_size buffer_size; + u16 *buffer_entry, *buffer_end; + int len, i; status = wmi_get_event_data(value, &response); if (status != AE_OK) { - pr_info("bad event status 0x%x\n", status); + pr_warn("bad event status 0x%x\n", status); return; } obj = (union acpi_object *)response.pointer; + if (!obj) { + pr_warn("no response\n"); + return; + } - if (obj && obj->type == ACPI_TYPE_BUFFER) { - const struct key_entry *key; - int reported_key; - u16 *buffer_entry = (u16 *)obj->buffer.pointer; - int buffer_size = obj->buffer.length/2; - - if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) { - pr_info("Received unknown WMI event (0x%x)\n", - buffer_entry[1]); - kfree(obj); - return; - } + if (obj->type != ACPI_TYPE_BUFFER) { + pr_warn("bad response type %x\n", obj->type); + kfree(obj); + return; + } + + pr_debug("Received WMI event (%*ph)\n", + obj->buffer.length, obj->buffer.pointer); - if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0)) - reported_key = (int)buffer_entry[2]; + buffer_entry = (u16 *)obj->buffer.pointer; + buffer_size = obj->buffer.length/2; + + if (!dell_new_hk_type) { + if (buffer_size >= 3 && buffer_entry[1] == 0x0) + dell_wmi_process_key(buffer_entry[2]); else if (buffer_size >= 2) - reported_key = (int)buffer_entry[1] & 0xffff; - else { + dell_wmi_process_key(buffer_entry[1]); + else pr_info("Received unknown WMI event\n"); - kfree(obj); - return; + kfree(obj); + return; + } + + buffer_end = buffer_entry + buffer_size; + + while (buffer_entry < buffer_end) { + + len = buffer_entry[0]; + if (len == 0) + break; + + len++; + + if (buffer_entry + len > buffer_end) { + pr_warn("Invalid length of WMI event\n"); + break; } - key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, - reported_key); - if (!key) { - pr_info("Unknown key %x pressed\n", reported_key); - } else if ((key->keycode == KEY_BRIGHTNESSUP || - key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { - /* Don't report brightness notifications that will also - * come via ACPI */ - ; - } else { - sparse_keymap_report_entry(dell_wmi_input_dev, key, - 1, true); + pr_debug("Process buffer (%*ph)\n", len*2, buffer_entry); + + switch (buffer_entry[1]) { + case 0x00: + for (i = 2; i < len; ++i) { + switch (buffer_entry[i]) { + case 0xe043: + /* NIC Link is Up */ + pr_debug("NIC Link is Up\n"); + break; + case 0xe044: + /* NIC Link is Down */ + pr_debug("NIC Link is Down\n"); + break; + case 0xe045: + /* Unknown event but defined in DSDT */ + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x00: " + "0x%x\n", (int)buffer_entry[i]); + break; + } + } + break; + case 0x10: + /* Keys pressed */ + for (i = 2; i < len; ++i) + dell_wmi_process_key(buffer_entry[i]); + break; + case 0x11: + for (i = 2; i < len; ++i) { + switch (buffer_entry[i]) { + case 0xfff0: + /* Battery unplugged */ + pr_debug("Battery unplugged\n"); + break; + case 0xfff1: + /* Battery inserted */ + pr_debug("Battery inserted\n"); + break; + case 0x01e1: + case 0x02ea: + case 0x02eb: + case 0x02ec: + case 0x02f6: + /* Keyboard backlight level changed */ + pr_debug("Keyboard backlight level " + "changed\n"); + break; + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x11: " + "0x%x\n", (int)buffer_entry[i]); + break; + } + } + break; + default: + /* Unknown event */ + pr_info("Unknown WMI event type 0x%x\n", + (int)buffer_entry[1]); + break; } + + buffer_entry += len; + } + kfree(obj); } -- GitLab From 01485a2230540c0dacd146e9927ea3d87dcb0fd8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Nov 2014 18:25:08 +0100 Subject: [PATCH 5304/9457] KVM: emulator: remove code duplication in register_address{,_increment} register_address has been a duplicate of address_mask ever since the ancestor of __linearize was born in 90de84f50b42 (KVM: x86 emulator: preserve an operand's segment identity, 2010-11-17). However, we can put it to a better use by including the call to reg_read in register_address. Similarly, the call to reg_rmw can be moved to register_address_increment. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 19a59f3f702c..43a5b432d06f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -488,9 +488,9 @@ address_mask(struct x86_emulate_ctxt *ctxt, unsigned long reg) } static inline unsigned long -register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg) +register_address(struct x86_emulate_ctxt *ctxt, int reg) { - return address_mask(ctxt, reg); + return address_mask(ctxt, reg_read(ctxt, reg)); } static void masked_increment(ulong *reg, ulong mask, int inc) @@ -499,7 +499,7 @@ static void masked_increment(ulong *reg, ulong mask, int inc) } static inline void -register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc) +register_address_increment(struct x86_emulate_ctxt *ctxt, int reg, int inc) { ulong mask; @@ -507,7 +507,7 @@ register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, in mask = ~0UL; else mask = ad_mask(ctxt); - masked_increment(reg, mask, inc); + masked_increment(reg_rmw(ctxt, reg), mask, inc); } static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) @@ -2910,8 +2910,8 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg, { int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count; - register_address_increment(ctxt, reg_rmw(ctxt, reg), df * op->bytes); - op->addr.mem.ea = register_address(ctxt, reg_read(ctxt, reg)); + register_address_increment(ctxt, reg, df * op->bytes); + op->addr.mem.ea = register_address(ctxt, reg); } static int em_das(struct x86_emulate_ctxt *ctxt) @@ -3381,7 +3381,7 @@ static int em_loop(struct x86_emulate_ctxt *ctxt) { int rc = X86EMUL_CONTINUE; - register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1); + register_address_increment(ctxt, VCPU_REGS_RCX, -1); if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) && (ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags))) rc = jmp_rel(ctxt, ctxt->src.val); @@ -4280,7 +4280,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, op->type = OP_MEM; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.mem.ea = - register_address(ctxt, reg_read(ctxt, VCPU_REGS_RDI)); + register_address(ctxt, VCPU_REGS_RDI); op->addr.mem.seg = VCPU_SREG_ES; op->val = 0; op->count = 1; @@ -4332,7 +4332,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, op->type = OP_MEM; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.mem.ea = - register_address(ctxt, reg_read(ctxt, VCPU_REGS_RSI)); + register_address(ctxt, VCPU_REGS_RSI); op->addr.mem.seg = ctxt->seg_override; op->val = 0; op->count = 1; @@ -4341,7 +4341,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, op->type = OP_MEM; op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; op->addr.mem.ea = - register_address(ctxt, + address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RBX) + (reg_read(ctxt, VCPU_REGS_RAX) & 0xff)); op->addr.mem.seg = ctxt->seg_override; @@ -4979,8 +4979,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) count = ctxt->src.count; else count = ctxt->dst.count; - register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), - -count); + register_address_increment(ctxt, VCPU_REGS_RCX, -count); if (!string_insn_completed(ctxt)) { /* -- GitLab From 997b04128d4e07fd59d00fc18e21fd591138627f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Nov 2014 18:33:38 +0100 Subject: [PATCH 5305/9457] KVM: emulator: remove duplicated limit check The check on the higher limit of the segment, and the check on the maximum accessible size, is the same for both expand-up and expand-down segments. Only the computation of "lim" varies. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 43a5b432d06f..f62209e7ad84 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -654,20 +654,15 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt, if (!fetch && (desc.type & 8) && !(desc.type & 2)) goto bad; lim = desc_limit_scaled(&desc); - if ((desc.type & 8) || !(desc.type & 4)) { - /* expand-up segment */ - if (addr.ea > lim) - goto bad; - *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); - } else { + if (!(desc.type & 8) && (desc.type & 4)) { /* expand-down segment */ if (addr.ea <= lim) goto bad; lim = desc.d ? 0xffffffff : 0xffff; - if (addr.ea > lim) - goto bad; - *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); } + if (addr.ea > lim) + goto bad; + *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); if (size > *max_size) goto bad; la &= (u32)-1; -- GitLab From 24d342c514827d52d008736bf02c9f145651ca8e Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 9 Nov 2014 18:50:07 +0200 Subject: [PATCH 5306/9457] mac80211: add option for setting skb flags before xmit Allows setting of an skb's flags - if needed - when calling ieee80211_subif_start_xmit(). Signed-off-by: Liad Kaufman Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/tx.c | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a51c993ece73..208953d1d028 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1625,6 +1625,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); +void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags); void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, struct sk_buff_head *skbs); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3ffd91f295a6..66af35f56a33 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1787,21 +1787,22 @@ static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, } /** - * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type + * __ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type * subinterfaces (wlan#, WDS, and VLAN interfaces) * @skb: packet to be sent * @dev: incoming interface + * @info_flags: skb flags to set * - * Returns: NETDEV_TX_OK both on success and on failure. On failure skb will - * be freed. + * On failure skb will be freed. * * This function takes in an Ethernet header and encapsulates it with suitable * IEEE 802.11 header based on which interface the packet is coming in. The * encapsulated packet will then be passed to master interface, wlan#.11, for * transmission (through low-level driver). */ -netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, - struct net_device *dev) +void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; @@ -1819,7 +1820,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, bool wme_sta = false, authorized = false, tdls_auth = false; bool tdls_peer = false, tdls_setup_frame = false; bool multicast; - u32 info_flags = 0; u16 info_id = 0; struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_sub_if_data *ap_sdata; @@ -2224,15 +2224,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ieee80211_xmit(sdata, skb, band); rcu_read_unlock(); - return NETDEV_TX_OK; + return; fail_rcu: rcu_read_unlock(); fail: dev_kfree_skb(skb); - return NETDEV_TX_OK; } +netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + __ieee80211_subif_start_xmit(skb, dev, 0); + return NETDEV_TX_OK; +} /* * ieee80211_clear_tx_pending may not be called in a context where -- GitLab From 1277b4a9f531e84e26f9e0210c1801b0c0bf81ca Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 9 Nov 2014 18:50:08 +0200 Subject: [PATCH 5307/9457] mac80211: retransmit TDLS teardown packet through AP if not ACKed Since the TDLS peer station might not receive the teardown packet (e.g., when in PS), this makes sure the packet is retransmitted - this time through the AP - if the TDLS peer didn't ACK the packet. Signed-off-by: Liad Kaufman Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 25 ++++++++++++++++ net/mac80211/ieee80211_i.h | 4 +++ net/mac80211/mlme.c | 12 ++++++++ net/mac80211/status.c | 55 +++++++++++++++++++++++++++++++++-- net/mac80211/tdls.c | 59 +++++++++++++++++++++++++++++++------- 5 files changed, 142 insertions(+), 13 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index f65b5446d983..4e2bb9107878 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -19,6 +19,7 @@ #include #include #include +#include /* * DS bit usage @@ -2418,6 +2419,30 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim, return !!(tim->virtual_map[index] & mask); } +/** + * ieee80211_get_tdls_action - get tdls packet action (or -1, if not tdls packet) + * @skb: the skb containing the frame, length will not be checked + * @hdr_size: the size of the ieee80211_hdr that starts at skb->data + * + * This function assumes the frame is a data frame, and that the network header + * is in the correct place. + */ +static inline int ieee80211_get_tdls_action(struct sk_buff *skb, u32 hdr_size) +{ + if (!skb_is_nonlinear(skb) && + skb->len > (skb_network_offset(skb) + 2)) { + /* Point to where the indication of TDLS should start */ + const u8 *tdls_data = skb_network_header(skb) - 2; + + if (get_unaligned_be16(tdls_data) == ETH_P_TDLS && + tdls_data[2] == WLAN_TDLS_SNAP_RFTYPE && + tdls_data[3] == WLAN_CATEGORY_TDLS) + return tdls_data[4]; + } + + return -1; +} + /* convert time units */ #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 208953d1d028..bc6f12ff1f61 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -525,8 +525,12 @@ struct ieee80211_if_managed { struct ieee80211_vht_cap vht_capa; /* configured VHT overrides */ struct ieee80211_vht_cap vht_capa_mask; /* Valid parts of vht_capa */ + /* TDLS support */ u8 tdls_peer[ETH_ALEN] __aligned(2); struct delayed_work tdls_peer_del_work; + struct sk_buff *orig_teardown_skb; /* The original teardown skb */ + struct sk_buff *teardown_skb; /* A copy to send through the AP */ + spinlock_t teardown_lock; /* To lock changing teardown_skb */ /* WMM-AC TSPEC support */ struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 243539878991..11a937f3fdeb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4003,6 +4003,11 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; else ifmgd->req_smps = IEEE80211_SMPS_OFF; + + /* Setup TDLS data */ + spin_lock_init(&ifmgd->teardown_lock); + ifmgd->teardown_skb = NULL; + ifmgd->orig_teardown_skb = NULL; } /* scan finished notification */ @@ -4865,6 +4870,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) } if (ifmgd->auth_data) ieee80211_destroy_auth_data(sdata, false); + spin_lock_bh(&ifmgd->teardown_lock); + if (ifmgd->teardown_skb) { + kfree_skb(ifmgd->teardown_skb); + ifmgd->teardown_skb = NULL; + ifmgd->orig_teardown_skb = NULL; + } + spin_unlock_bh(&ifmgd->teardown_lock); del_timer_sync(&ifmgd->timer); sdata_unlock(sdata); } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 9612d89fad56..71de2d3866cc 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -390,6 +390,46 @@ ieee80211_add_tx_radiotap_header(struct ieee80211_local *local, } } +/* + * Handles the tx for TDLS teardown frames. + * If the frame wasn't ACKed by the peer - it will be re-sent through the AP + */ +static void ieee80211_tdls_td_tx_handle(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 flags) +{ + struct sk_buff *teardown_skb; + struct sk_buff *orig_teardown_skb; + bool is_teardown = false; + + /* Get the teardown data we need and free the lock */ + spin_lock(&sdata->u.mgd.teardown_lock); + teardown_skb = sdata->u.mgd.teardown_skb; + orig_teardown_skb = sdata->u.mgd.orig_teardown_skb; + if ((skb == orig_teardown_skb) && teardown_skb) { + sdata->u.mgd.teardown_skb = NULL; + sdata->u.mgd.orig_teardown_skb = NULL; + is_teardown = true; + } + spin_unlock(&sdata->u.mgd.teardown_lock); + + if (is_teardown) { + /* This mechanism relies on being able to get ACKs */ + WARN_ON(!(local->hw.flags & + IEEE80211_HW_REPORTS_TX_ACK_STATUS)); + + /* Check if peer has ACKed */ + if (flags & IEEE80211_TX_STAT_ACK) { + dev_kfree_skb_any(teardown_skb); + } else { + tdls_dbg(sdata, + "TDLS Resending teardown through AP\n"); + + ieee80211_subif_start_xmit(teardown_skb, skb->dev); + } + } +} + static void ieee80211_report_used_skb(struct ieee80211_local *local, struct sk_buff *skb, bool dropped) { @@ -426,8 +466,19 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, if (!sdata) { skb->dev = NULL; } else if (info->flags & IEEE80211_TX_INTFL_MLME_CONN_TX) { - ieee80211_mgd_conn_tx_status(sdata, hdr->frame_control, - acked); + unsigned int hdr_size = + ieee80211_hdrlen(hdr->frame_control); + + /* Check to see if packet is a TDLS teardown packet */ + if (ieee80211_is_data(hdr->frame_control) && + (ieee80211_get_tdls_action(skb, hdr_size) == + WLAN_TDLS_TEARDOWN)) + ieee80211_tdls_td_tx_handle(local, sdata, skb, + info->flags); + else + ieee80211_mgd_conn_tx_status(sdata, + hdr->frame_control, + acked); } else if (ieee80211_is_nullfunc(hdr->frame_control) || ieee80211_is_qos_nullfunc(hdr->frame_control)) { cfg80211_probe_status(sdata->dev, hdr->addr1, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index b4f368e2cb3b..d4fe091fd98a 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -512,20 +512,22 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; struct sk_buff *skb = NULL; + u32 flags = 0; bool send_direct; struct sta_info *sta; int ret; - skb = dev_alloc_skb(local->hw.extra_tx_headroom + - max(sizeof(struct ieee80211_mgmt), - sizeof(struct ieee80211_tdls_data)) + - 50 + /* supported rates */ - 7 + /* ext capab */ - 26 + /* max(WMM-info, WMM-param) */ - 2 + max(sizeof(struct ieee80211_ht_cap), - sizeof(struct ieee80211_ht_operation)) + - extra_ies_len + - sizeof(struct ieee80211_tdls_lnkie)); + skb = netdev_alloc_skb(dev, + local->hw.extra_tx_headroom + + max(sizeof(struct ieee80211_mgmt), + sizeof(struct ieee80211_tdls_data)) + + 50 + /* supported rates */ + 7 + /* ext capab */ + 26 + /* max(WMM-info, WMM-param) */ + 2 + max(sizeof(struct ieee80211_ht_cap), + sizeof(struct ieee80211_ht_operation)) + + extra_ies_len + + sizeof(struct ieee80211_tdls_lnkie)); if (!skb) return -ENOMEM; @@ -623,9 +625,44 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, break; } + /* + * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress. + * Later, if no ACK is returned from peer, we will re-send the teardown + * packet through the AP. + */ + if ((action_code == WLAN_TDLS_TEARDOWN) && + (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { + struct sta_info *sta = NULL; + bool try_resend; /* Should we keep skb for possible resend */ + + /* If not sending directly to peer - no point in keeping skb */ + rcu_read_lock(); + sta = sta_info_get(sdata, peer); + try_resend = sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); + rcu_read_unlock(); + + spin_lock_bh(&sdata->u.mgd.teardown_lock); + if (try_resend && !sdata->u.mgd.teardown_skb) { + /* Mark it as requiring TX status callback */ + flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_INTFL_MLME_CONN_TX; + + /* + * skb is copied since mac80211 will later set + * properties that might not be the same as the AP, + * such as encryption, QoS, addresses, etc. + * + * No problem if skb_copy() fails, so no need to check. + */ + sdata->u.mgd.teardown_skb = skb_copy(skb, GFP_ATOMIC); + sdata->u.mgd.orig_teardown_skb = skb; + } + spin_unlock_bh(&sdata->u.mgd.teardown_lock); + } + /* disable bottom halves when entering the Tx path */ local_bh_disable(); - ret = ieee80211_subif_start_xmit(skb, dev); + __ieee80211_subif_start_xmit(skb, dev, flags); local_bh_enable(); return ret; -- GitLab From 73c4e195e6396eea04e11f88dc0336e1bc3c8e66 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 9 Nov 2014 18:50:09 +0200 Subject: [PATCH 5308/9457] mac80211: move skb info band assignment out Instead of passing the band as a parameter to ieee80211_xmit() and ieee80211_tx(), move it outside of the two functions while making sure info->band is set up before calling them. This removes the parameter and simplifies the follow commit. Signed-off-by: Johannes Berg Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 ++- net/mac80211/ieee80211_i.h | 3 +-- net/mac80211/sta_info.c | 3 ++- net/mac80211/tx.c | 23 +++++++++++------------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a43a14863ecb..3ecbf68dadf1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3514,6 +3514,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | IEEE80211_TX_INTFL_NL80211_FRAME_TX; + info->band = band; skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; @@ -3521,7 +3522,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, nullfunc->qos_ctrl = cpu_to_le16(7); local_bh_disable(); - ieee80211_xmit(sdata, skb, band); + ieee80211_xmit(sdata, skb); local_bh_enable(); rcu_read_unlock(); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index bc6f12ff1f61..00cda1ea15f9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1761,8 +1761,7 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke gfp_t gfp); void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, bool bss_notify); -void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, - enum ieee80211_band band); +void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, int tid, diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index adc25371b171..97372514f287 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1249,7 +1249,8 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, return; } - ieee80211_xmit(sdata, skb, chanctx_conf->def.chan->band); + info->band = chanctx_conf->def.chan->band; + ieee80211_xmit(sdata, skb); rcu_read_unlock(); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 66af35f56a33..c4a5494c2ac6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1426,8 +1426,7 @@ EXPORT_SYMBOL(ieee80211_tx_prepare_skb); * Returns false if the frame couldn't be transmitted but was queued instead. */ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool txpending, - enum ieee80211_band band) + struct sk_buff *skb, bool txpending) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_data tx; @@ -1452,8 +1451,6 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, return true; } - info->band = band; - /* set up hw_queue value early */ if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || !(local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) @@ -1501,8 +1498,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, return 0; } -void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, - enum ieee80211_band band) +void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1537,7 +1533,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, } ieee80211_set_qos_hdr(sdata, skb); - ieee80211_tx(sdata, skb, false, band); + ieee80211_tx(sdata, skb, false); } static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) @@ -1757,7 +1753,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, sdata->vif.type)) goto fail_rcu; - ieee80211_xmit(sdata, skb, chandef->chan->band); + info->band = chandef->chan->band; + ieee80211_xmit(sdata, skb); rcu_read_unlock(); return NETDEV_TX_OK; @@ -2220,8 +2217,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, info->flags = info_flags; info->ack_frame_id = info_id; + info->band = band; - ieee80211_xmit(sdata, skb, band); + ieee80211_xmit(sdata, skb); rcu_read_unlock(); return; @@ -2277,8 +2275,8 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, dev_kfree_skb(skb); return true; } - result = ieee80211_tx(sdata, skb, true, - chanctx_conf->def.chan->band); + info->band = chanctx_conf->def.chan->band; + result = ieee80211_tx(sdata, skb, true); } else { struct sk_buff_head skbs; @@ -3059,6 +3057,7 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, * requirements are that we do not come into tx with bhs on. */ local_bh_disable(); - ieee80211_xmit(sdata, skb, band); + IEEE80211_SKB_CB(skb)->band = band; + ieee80211_xmit(sdata, skb); local_bh_enable(); } -- GitLab From 4c9451ed94087abf0e45835f133e0fa44b809f96 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 9 Nov 2014 18:50:10 +0200 Subject: [PATCH 5309/9457] mac80211: factor out 802.11 header building code Factor out the 802.11 header building code from the xmit function to be able to use it separately in a later commit. While at it, fix up some documentation. Signed-off-by: Johannes Berg Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 144 +++++++++++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 52 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c4a5494c2ac6..55d69fda4c6a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1784,24 +1784,26 @@ static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, } /** - * __ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type - * subinterfaces (wlan#, WDS, and VLAN interfaces) - * @skb: packet to be sent - * @dev: incoming interface + * ieee80211_build_hdr - build 802.11 header in the given frame + * @sdata: virtual interface to build the header for + * @skb: the skb to build the header in * @info_flags: skb flags to set * - * On failure skb will be freed. + * This function takes the skb with 802.3 header and reformats the header to + * the appropriate IEEE 802.11 header based on which interface the packet is + * being transmitted on. + * + * Note that this function also takes care of the TX status request and + * potential unsharing of the SKB - this needs to be interleaved with the + * header building. + * + * The function requires the read-side RCU lock held * - * This function takes in an Ethernet header and encapsulates it with suitable - * IEEE 802.11 header based on which interface the packet is coming in. The - * encapsulated packet will then be passed to master interface, wlan#.11, for - * transmission (through low-level driver). + * Returns: the (possibly reallocated) skb or an ERR_PTR() code */ -void __ieee80211_subif_start_xmit(struct sk_buff *skb, - struct net_device *dev, - u32 info_flags) +static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 info_flags) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info; int head_need; @@ -1821,20 +1823,13 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_sub_if_data *ap_sdata; enum ieee80211_band band; - - if (unlikely(skb->len < ETH_HLEN)) - goto fail; + int ret; /* convert Ethernet header to proper 802.11 header (based on * operation mode) */ ethertype = (skb->data[12] << 8) | skb->data[13]; fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); - rcu_read_lock(); - - /* Measure frame arrival for Tx latency statistics calculation */ - ieee80211_tx_latency_start_msrmnt(local, skb); - switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: sta = rcu_dereference(sdata->u.vlan.sta); @@ -1852,8 +1847,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } band = chanctx_conf->def.chan->band; if (sta) break; @@ -1861,8 +1858,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, case NL80211_IFTYPE_AP: if (sdata->vif.type == NL80211_IFTYPE_AP) chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); /* DA BSSID SA */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -1949,8 +1948,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, } chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } band = chanctx_conf->def.chan->band; break; #endif @@ -1980,8 +1981,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, * of a link teardown after a TDLS sta is removed due to being * unreachable. */ - if (tdls_peer && !tdls_auth && !tdls_setup_frame) - goto fail_rcu; + if (tdls_peer && !tdls_auth && !tdls_setup_frame) { + ret = -EINVAL; + goto free; + } /* send direct packets to authorized TDLS peers */ if (tdls_peer && tdls_auth) { @@ -2009,8 +2012,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, hdrlen = 24; } chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } band = chanctx_conf->def.chan->band; break; case NL80211_IFTYPE_OCB: @@ -2020,8 +2025,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, eth_broadcast_addr(hdr.addr3); hdrlen = 24; chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } band = chanctx_conf->def.chan->band; break; case NL80211_IFTYPE_ADHOC: @@ -2031,12 +2038,15 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); hdrlen = 24; chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; + if (!chanctx_conf) { + ret = -ENOTCONN; + goto free; + } band = chanctx_conf->def.chan->band; break; default: - goto fail_rcu; + ret = -EINVAL; + goto free; } /* @@ -2074,12 +2084,13 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", - dev->name, hdr.addr1); + sdata->name, hdr.addr1); #endif I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); - goto fail_rcu; + ret = -EPERM; + goto free; } if (unlikely(!multicast && skb->sk && @@ -2116,8 +2127,10 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, skb = skb_clone(skb, GFP_ATOMIC); kfree_skb(tmp_skb); - if (!skb) - goto fail_rcu; + if (!skb) { + ret = -ENOMEM; + goto free; + } } hdr.frame_control = fc; @@ -2166,7 +2179,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, if (ieee80211_skb_resize(sdata, skb, head_need, true)) { ieee80211_free_txskb(&local->hw, skb); skb = NULL; - goto fail_rcu; + return ERR_PTR(-ENOMEM); } } @@ -2200,9 +2213,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, nh_pos += hdrlen; h_pos += hdrlen; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - /* Update skb pointers to various headers since this modified frame * is going to go through Linux networking code that may potentially * need things like pointer to IP header. */ @@ -2213,23 +2223,53 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); - dev->trans_start = jiffies; - info->flags = info_flags; info->ack_frame_id = info_id; info->band = band; - ieee80211_xmit(sdata, skb); - rcu_read_unlock(); + return skb; + free: + kfree_skb(skb); + return ERR_PTR(ret); +} + +void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + + if (unlikely(skb->len < ETH_HLEN)) { + kfree_skb(skb); + return; + } + + rcu_read_lock(); + + /* Measure frame arrival for Tx latency statistics calculation */ + ieee80211_tx_latency_start_msrmnt(local, skb); + + skb = ieee80211_build_hdr(sdata, skb, info_flags); + if (IS_ERR(skb)) + goto out; - return; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev->trans_start = jiffies; - fail_rcu: + ieee80211_xmit(sdata, skb); + out: rcu_read_unlock(); - fail: - dev_kfree_skb(skb); } +/** + * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs + * @skb: packet to be sent + * @dev: incoming interface + * + * On failure skb will be freed. + */ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) { -- GitLab From 7528ec57760b942c9b74d2c6931a4a5b88f0eeff Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 9 Nov 2014 18:50:11 +0200 Subject: [PATCH 5310/9457] mac80211: add function to create data frame template including key For some TDLS channel switch implementations data frames need to be sent by the firmware based on a template. This template should be created by mac80211, and thus needs to properly be built from an 802.3 frame into an 802.11 frame. In addition, the device will need the key information so the select_key handler needs to be run. However, the driver/device will be responsible for all of the crypto encapsulation, as the sequence numbers etc. cannot be built by the host anyway in this case since it's a template to be used multiple times. Signed-off-by: Johannes Berg Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/tx.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 00cda1ea15f9..53eb41fad033 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1634,6 +1634,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, u32 info_flags); void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, struct sk_buff_head *skbs); +struct sk_buff * +ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 info_flags); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 55d69fda4c6a..2dd89670e1cd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2277,6 +2277,37 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +struct sk_buff * +ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 info_flags) +{ + struct ieee80211_hdr *hdr; + struct ieee80211_tx_data tx = { + .local = sdata->local, + .sdata = sdata, + }; + + rcu_read_lock(); + + skb = ieee80211_build_hdr(sdata, skb, info_flags); + if (IS_ERR(skb)) + goto out; + + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); + kfree_skb(skb); + return ERR_PTR(-EINVAL); + } + +out: + rcu_read_unlock(); + return skb; +} + /* * ieee80211_clear_tx_pending may not be called in a context where * it is possible that it packets could come in again. -- GitLab From f0d29cb979567f13c8db371940c5911a9025f081 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:12 +0200 Subject: [PATCH 5311/9457] mac80211: add supported channels IE during TDLS setup This information element is mandatory in case TDLS channel-switching is to be supported. The channels given are ones supported and allowed to be active in the current regulatory setting. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/tdls.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index d4fe091fd98a..8fb314b182e2 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -48,6 +48,75 @@ static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; } +static u8 +ieee80211_tdls_add_subband(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u16 start, u16 end, + u16 spacing) +{ + u8 subband_cnt = 0, ch_cnt = 0; + struct ieee80211_channel *ch; + struct cfg80211_chan_def chandef; + int i, subband_start; + + for (i = start; i <= end; i += spacing) { + if (!ch_cnt) + subband_start = i; + + ch = ieee80211_get_channel(sdata->local->hw.wiphy, i); + if (ch) { + /* we will be active on the channel */ + u32 flags = IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_NO_IR; + cfg80211_chandef_create(&chandef, ch, + NL80211_CHAN_HT20); + if (cfg80211_chandef_usable(sdata->local->hw.wiphy, + &chandef, flags)) { + ch_cnt++; + continue; + } + } + + if (ch_cnt) { + u8 *pos = skb_put(skb, 2); + *pos++ = ieee80211_frequency_to_channel(subband_start); + *pos++ = ch_cnt; + + subband_cnt++; + ch_cnt = 0; + } + } + + return subband_cnt; +} + +static void +ieee80211_tdls_add_supp_channels(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + /* + * Add possible channels for TDLS. These are channels that are allowed + * to be active. + */ + u8 subband_cnt; + u8 *pos = skb_put(skb, 2); + + *pos++ = WLAN_EID_SUPPORTED_CHANNELS; + + /* + * 5GHz and 2GHz channels numbers can overlap. Ignore this for now, as + * this doesn't happen in real world scenarios. + */ + + /* 2GHz, with 5MHz spacing */ + subband_cnt = ieee80211_tdls_add_subband(sdata, skb, 2412, 2472, 5); + + /* 5GHz, with 20MHz spacing */ + subband_cnt += ieee80211_tdls_add_subband(sdata, skb, 5000, 5825, 20); + + /* length */ + *pos = 2 * subband_cnt; +} + static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata, u16 status_code) { @@ -190,6 +259,7 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, ieee80211_add_srates_ie(sdata, skb, false, band); ieee80211_add_ext_srates_ie(sdata, skb, false, band); + ieee80211_tdls_add_supp_channels(sdata, skb); /* add any custom IEs that go before Extended Capabilities */ if (extra_ies_len) { @@ -526,6 +596,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, 26 + /* max(WMM-info, WMM-param) */ 2 + max(sizeof(struct ieee80211_ht_cap), sizeof(struct ieee80211_ht_operation)) + + 50 + /* supported channels */ extra_ies_len + sizeof(struct ieee80211_tdls_lnkie)); if (!skb) -- GitLab From 2cedd87960a809dd9bf683f72123b7dce6736f07 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:13 +0200 Subject: [PATCH 5312/9457] mac80211: add BSS coex IE to TDLS setup frames Add the BSS coex IE in case we support HT40 channels, as mandated by section 8.5.13 in IEEE802.11 2012. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 3 +++ net/mac80211/tdls.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 4e2bb9107878..adac1be67387 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2037,6 +2037,9 @@ enum ieee80211_tdls_actioncode { /* TDLS specific payload type in the LLC/SNAP header */ #define WLAN_TDLS_SNAP_RFTYPE 0x2 +/* BSS Coex IE information field bits */ +#define WLAN_BSS_COEX_INFORMATION_REQUEST BIT(0) + /** * enum - mesh synchronization method identifier * diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 8fb314b182e2..30a4c1004010 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -117,6 +117,16 @@ ieee80211_tdls_add_supp_channels(struct ieee80211_sub_if_data *sdata, *pos = 2 * subband_cnt; } +static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb) +{ + u8 *pos = (void *)skb_put(skb, 3); + + *pos++ = WLAN_EID_BSS_COEX_2040; + *pos++ = 1; /* len */ + + *pos++ = WLAN_BSS_COEX_INFORMATION_REQUEST; +} + static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata, u16 status_code) { @@ -341,6 +351,10 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); + if (ht_cap.ht_supported && + (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + ieee80211_tdls_add_bss_coex_ie(skb); + /* add any remaining IEs */ if (extra_ies_len) { noffset = extra_ies_len; @@ -597,6 +611,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, 2 + max(sizeof(struct ieee80211_ht_cap), sizeof(struct ieee80211_ht_operation)) + 50 + /* supported channels */ + 3 + /* 40/20 BSS coex */ extra_ies_len + sizeof(struct ieee80211_tdls_lnkie)); if (!skb) -- GitLab From 78632a17eaa7a5abdc22aac8ca5932d6cad59984 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:14 +0200 Subject: [PATCH 5313/9457] cfg/mac80211: define TDLS channel switch feature bit Define some related TDLS protocol constants and advertise channel switch support in the extended-capabilities IE when the feature bit is defined. Actually supporting TDLS channel-switching also requires support for some new nl80211 commands, to be introduced by future patches. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 6 ++++++ include/uapi/linux/nl80211.h | 3 +++ net/mac80211/tdls.c | 9 ++++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index adac1be67387..fbb02d240658 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2019,6 +2019,11 @@ enum ieee80211_tdls_actioncode { */ #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) +/* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */ +#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4) +#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5) +#define WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH BIT(6) + /* Interworking capabilities are set in 7th bit of 4th byte of the * @WLAN_EID_EXT_CAPABILITY information element */ @@ -2030,6 +2035,7 @@ enum ieee80211_tdls_actioncode { */ #define WLAN_EXT_CAPA5_TDLS_ENABLED BIT(5) #define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6) +#define WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED BIT(7) #define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(6) #define WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED BIT(7) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 442369f69b4f..ccdeef28d672 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -4095,6 +4095,8 @@ enum nl80211_ap_sme_features { * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring * the vif's MAC address upon creation. * See 'macaddr' field in the vif_params (cfg80211.h). + * @NL80211_FEATURE_TDLS_CHANNEL_SWITCH: Driver supports channel switching when + * operating as a TDLS peer. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4125,6 +4127,7 @@ enum nl80211_feature_flags { NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, + NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 1 << 28, }; /** diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 30a4c1004010..4554bdc72c91 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -35,16 +35,19 @@ void ieee80211_tdls_peer_del_work(struct work_struct *wk) mutex_unlock(&local->mtx); } -static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) +static void ieee80211_tdls_add_ext_capab(struct ieee80211_local *local, + struct sk_buff *skb) { u8 *pos = (void *)skb_put(skb, 7); + bool chan_switch = local->hw.wiphy->features & + NL80211_FEATURE_TDLS_CHANNEL_SWITCH; *pos++ = WLAN_EID_EXT_CAPABILITY; *pos++ = 5; /* len */ *pos++ = 0x0; *pos++ = 0x0; *pos++ = 0x0; - *pos++ = 0x0; + *pos++ = chan_switch ? WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH : 0; *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; } @@ -289,7 +292,7 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, offset = noffset; } - ieee80211_tdls_add_ext_capab(skb); + ieee80211_tdls_add_ext_capab(local, skb); /* add the QoS element if we support it */ if (local->hw.queues >= IEEE80211_NUM_ACS && -- GitLab From 9041c1fa5722250025be9a7450622c9108088c5a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:15 +0200 Subject: [PATCH 5314/9457] mac80211: track AP and peer STA TDLS chan-switch support The AP or peer can prohibit TDLS channel switch via a bit in the extended capabilities IE. Parse the IE and track this bit. Set an appropriate STA flag if both the AP and peer STA support TDLS channel-switching. Add the new STA flag and the missing TDLS_INITIATOR to debugfs. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 7 +++++++ net/mac80211/debugfs_sta.c | 5 +++-- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/mlme.c | 3 +++ net/mac80211/sta_info.h | 2 ++ net/mac80211/util.c | 5 +++++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3ecbf68dadf1..8195e65d8a91 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1042,6 +1042,13 @@ static int sta_apply_parameters(struct ieee80211_local *local, clear_sta_flag(sta, WLAN_STA_TDLS_PEER); } + /* mark TDLS channel switch support, if the AP allows it */ + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && + !sdata->u.mgd.tdls_chan_switch_prohibited && + params->ext_capab_len >= 4 && + params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) + set_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH); + if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { sta->sta.uapsd_queues = params->uapsd_queues; sta->sta.max_sp = params->max_sp; diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index bafe48916229..2ba7f53746da 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -74,7 +74,7 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" int res = scnprintf(buf, sizeof(buf), - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", TEST(AUTH), TEST(ASSOC), TEST(PS_STA), TEST(PS_DRIVER), TEST(AUTHORIZED), TEST(SHORT_PREAMBLE), @@ -82,7 +82,8 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, TEST(WDS), TEST(CLEAR_PS_FILT), TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), - TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), + TEST(TDLS_PEER_AUTH), TEST(TDLS_INITIATOR), + TEST(TDLS_CHAN_SWITCH), TEST(4ADDR_EVENT), TEST(INSERTED), TEST(RATE_CONTROL), TEST(TOFFSET_KNOWN), TEST(MPSP_OWNER), TEST(MPSP_RECIPIENT)); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 53eb41fad033..4b3a7e7ec2a0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -531,6 +531,7 @@ struct ieee80211_if_managed { struct sk_buff *orig_teardown_skb; /* The original teardown skb */ struct sk_buff *teardown_skb; /* A copy to send through the AP */ spinlock_t teardown_lock; /* To lock changing teardown_skb */ + bool tdls_chan_switch_prohibited; /* WMM-AC TSPEC support */ struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; @@ -1399,6 +1400,7 @@ struct ieee802_11_elems { size_t total_len; /* pointers to IEs */ + const u8 *ext_capab; const u8 *ssid; const u8 *supp_rates; const u8 *ds_params; @@ -1433,6 +1435,7 @@ struct ieee802_11_elems { const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; /* length of them, respectively */ + u8 ext_capab_len; u8 ssid_len; u8 supp_rates_len; u8 tim_len; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 11a937f3fdeb..45490a202d9c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2802,6 +2802,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, } ifmgd->aid = aid; + ifmgd->tdls_chan_switch_prohibited = + elems.ext_capab && elems.ext_capab_len >= 5 && + (elems.ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED); /* * Some APs are erroneously not including some information in their diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index bcda2ac7d844..b6702c810ad3 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -49,6 +49,7 @@ * packets. This means the link is enabled. * @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this * station. + * @WLAN_STA_TDLS_CHAN_SWITCH: This TDLS peer supports TDLS channel-switching * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was * keeping station in power-save mode, reply when the driver * unblocks the station. @@ -78,6 +79,7 @@ enum ieee80211_sta_info_flags { WLAN_STA_TDLS_PEER, WLAN_STA_TDLS_PEER_AUTH, WLAN_STA_TDLS_INITIATOR, + WLAN_STA_TDLS_CHAN_SWITCH, WLAN_STA_UAPSD, WLAN_STA_SP, WLAN_STA_4ADDR_EVENT, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f9319a5dca64..3ca0c2e725ff 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -831,6 +831,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, case WLAN_EID_SECONDARY_CHANNEL_OFFSET: case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: case WLAN_EID_CHAN_SWITCH_PARAM: + case WLAN_EID_EXT_CAPABILITY: /* * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible * that if the content gets bigger it might be needed more than once @@ -850,6 +851,10 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, elem_parse_failed = false; switch (id) { + case WLAN_EID_EXT_CAPABILITY: + elems->ext_capab = pos; + elems->ext_capab_len = elen; + break; case WLAN_EID_SSID: elems->ssid = pos; elems->ssid_len = elen; -- GitLab From c2733905692589cc73928ffd65d26107536e80fe Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:16 +0200 Subject: [PATCH 5315/9457] mac80211: prepare TDLS mgmt code for channel-switch templates Split the data-generating from the Tx-sending functionality, as we do not want to send templates to the lower driver. Also add an optional chandef argument to the data-generating portion. It will be used for channel-switch templates. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/tdls.c | 82 +++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 4554bdc72c91..fa141aecd986 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -453,7 +453,8 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, const u8 *peer, u8 action_code, u16 status_code, bool initiator, const u8 *extra_ies, - size_t extra_ies_len) + size_t extra_ies_len, u8 oper_class, + struct cfg80211_chan_def *chandef) { switch (action_code) { case WLAN_TDLS_SETUP_REQUEST: @@ -589,22 +590,19 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int -ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, - const u8 *peer, u8 action_code, - u8 dialog_token, u16 status_code, - u32 peer_capability, bool initiator, - const u8 *extra_ies, size_t extra_ies_len) +static struct sk_buff * +ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata, + const u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + bool initiator, const u8 *extra_ies, + size_t extra_ies_len, u8 oper_class, + struct cfg80211_chan_def *chandef) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; - struct sk_buff *skb = NULL; - u32 flags = 0; - bool send_direct; - struct sta_info *sta; + struct sk_buff *skb; int ret; - skb = netdev_alloc_skb(dev, + skb = netdev_alloc_skb(sdata->dev, local->hw.extra_tx_headroom + max(sizeof(struct ieee80211_mgmt), sizeof(struct ieee80211_tdls_data)) + @@ -618,7 +616,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, extra_ies_len + sizeof(struct ieee80211_tdls_lnkie)); if (!skb) - return -ENOMEM; + return NULL; skb_reserve(skb, local->hw.extra_tx_headroom); @@ -628,16 +626,16 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_DISCOVERY_REQUEST: - ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, + ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, + sdata->dev, peer, action_code, dialog_token, status_code, skb); - send_direct = false; break; case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: - ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, + ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev, + peer, action_code, dialog_token, status_code, skb); - send_direct = true; break; default: ret = -ENOTSUPP; @@ -647,6 +645,30 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, if (ret < 0) goto fail; + ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code, + initiator, extra_ies, extra_ies_len, oper_class, + chandef); + return skb; + +fail: + dev_kfree_skb(skb); + return NULL; +} + +static int +ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + bool initiator, const u8 *extra_ies, + size_t extra_ies_len, u8 oper_class, + struct cfg80211_chan_def *chandef) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct sk_buff *skb = NULL; + struct sta_info *sta; + u32 flags = 0; + int ret = 0; + rcu_read_lock(); sta = sta_info_get(sdata, peer); @@ -691,9 +713,17 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, if (ret < 0) goto fail; - ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code, - initiator, extra_ies, extra_ies_len); - if (send_direct) { + skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code, + dialog_token, status_code, + initiator, extra_ies, + extra_ies_len, oper_class, + chandef); + if (!skb) { + ret = -EINVAL; + goto fail; + } + + if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { ieee80211_tx_skb(sdata, skb); return 0; } @@ -720,7 +750,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, * packet through the AP. */ if ((action_code == WLAN_TDLS_TEARDOWN) && - (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { + (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { struct sta_info *sta = NULL; bool try_resend; /* Should we keep skb for possible resend */ @@ -802,7 +832,8 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, dialog_token, status_code, peer_capability, initiator, - extra_ies, extra_ies_len); + extra_ies, extra_ies_len, 0, + NULL); if (ret < 0) goto exit; @@ -841,7 +872,8 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev, ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, dialog_token, status_code, peer_capability, initiator, - extra_ies, extra_ies_len); + extra_ies, extra_ies_len, 0, + NULL); if (ret < 0) sdata_err(sdata, "Failed sending TDLS teardown packet %d\n", ret); @@ -911,7 +943,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, status_code, peer_capability, initiator, extra_ies, - extra_ies_len); + extra_ies_len, 0, NULL); break; default: ret = -EOPNOTSUPP; -- GitLab From 1057d35ede5dbf7ed7842357564fb42c9b54ba50 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 19 Nov 2014 12:54:26 +0200 Subject: [PATCH 5316/9457] cfg80211: introduce TDLS channel switch commands Introduce commands to initiate and cancel TDLS channel-switching. Once TDLS channel-switching is started, the lower level driver is responsible for continually initiating channel-switch operations and returning to the base (AP) channel to listen for beacons from time to time. Upon cancellation of the channel-switch all communication between the relevant TDLS peers will continue on the base channel. Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 14 +++++ include/uapi/linux/nl80211.h | 19 ++++++ net/wireless/core.c | 4 ++ net/wireless/nl80211.c | 108 +++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 24 ++++++++ net/wireless/trace.h | 42 ++++++++++++++ 6 files changed, 211 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 220d5f5f1aca..8d04dfef32bf 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2367,6 +2367,12 @@ struct cfg80211_qos_map { * (invoked with the wireless_dev mutex held) * @leave_ocb: leave the current OCB network * (invoked with the wireless_dev mutex held) + * + * @tdls_channel_switch: Start channel-switching with a TDLS peer. The driver + * is responsible for continually initiating channel-switching operations + * and returning to the base channel for communication with the AP. + * @tdls_cancel_channel_switch: Stop channel-switching with a TDLS peer. Both + * peers must be on the base channel when the call completes. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2622,6 +2628,14 @@ struct cfg80211_ops { u16 admitted_time); int (*del_tx_ts)(struct wiphy *wiphy, struct net_device *dev, u8 tsid, const u8 *peer); + + int (*tdls_channel_switch)(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef); + void (*tdls_cancel_channel_switch)(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr); }; /* diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index ccdeef28d672..365db67ca71d 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -762,6 +762,18 @@ * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the * network is determined by the network interface. * + * @NL80211_CMD_TDLS_CHANNEL_SWITCH: Start channel-switching with a TDLS peer, + * identified by the %NL80211_ATTR_MAC parameter. A target channel is + * provided via %NL80211_ATTR_WIPHY_FREQ and other attributes determining + * channel width/type. The target operating class is given via + * %NL80211_ATTR_OPER_CLASS. + * The driver is responsible for continually initiating channel-switching + * operations and returning to the base channel for communication with the + * AP. + * @NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH: Stop channel-switching with a TDLS + * peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel + * when this command completes. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -943,6 +955,9 @@ enum nl80211_commands { NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, + NL80211_CMD_TDLS_CHANNEL_SWITCH, + NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1669,6 +1684,8 @@ enum nl80211_commands { * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see * &enum nl80211_smps_mode. * + * @NL80211_ATTR_OPER_CLASS: operating class + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -2021,6 +2038,8 @@ enum nl80211_attrs { NL80211_ATTR_SMPS_MODE, + NL80211_ATTR_OPER_CLASS, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/core.c b/net/wireless/core.c index a4d27927aba2..4c2e501203d1 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -541,6 +541,10 @@ int wiphy_register(struct wiphy *wiphy) !wiphy->wowlan->tcp)) return -EINVAL; #endif + if (WARN_ON((wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) && + (!rdev->ops->tdls_channel_switch || + !rdev->ops->tdls_cancel_channel_switch))) + return -EINVAL; if (WARN_ON(wiphy->coalesce && (!wiphy->coalesce->n_rules || diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d0a8361b3395..27666f5e5050 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9658,6 +9658,98 @@ static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info) return err; } +static int nl80211_tdls_channel_switch(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_chan_def chandef = {}; + const u8 *addr; + u8 oper_class; + int err; + + if (!rdev->ops->tdls_channel_switch || + !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)) + return -EOPNOTSUPP; + + switch (dev->ieee80211_ptr->iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + break; + default: + return -EOPNOTSUPP; + } + + if (!info->attrs[NL80211_ATTR_MAC] || + !info->attrs[NL80211_ATTR_OPER_CLASS]) + return -EINVAL; + + err = nl80211_parse_chandef(rdev, info, &chandef); + if (err) + return err; + + /* + * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012 + * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the + * specification is not defined for them. + */ + if (chandef.chan->band == IEEE80211_BAND_2GHZ && + chandef.width != NL80211_CHAN_WIDTH_20_NOHT && + chandef.width != NL80211_CHAN_WIDTH_20) + return -EINVAL; + + /* we will be active on the TDLS link */ + if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, wdev->iftype)) + return -EINVAL; + + /* don't allow switching to DFS channels */ + if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype)) + return -EINVAL; + + addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]); + + wdev_lock(wdev); + err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef); + wdev_unlock(wdev); + + return err; +} + +static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + const u8 *addr; + + if (!rdev->ops->tdls_channel_switch || + !rdev->ops->tdls_cancel_channel_switch || + !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)) + return -EOPNOTSUPP; + + switch (dev->ieee80211_ptr->iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + break; + default: + return -EOPNOTSUPP; + } + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + + wdev_lock(wdev); + rdev_tdls_cancel_channel_switch(rdev, dev, addr); + wdev_unlock(wdev); + + return 0; +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -10456,6 +10548,22 @@ static const struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH, + .doit = nl80211_tdls_channel_switch, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, + .doit = nl80211_tdls_cancel_channel_switch, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, }; /* notification functions */ diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 1b3864cd50ca..35cfb7134bdb 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -993,4 +993,28 @@ rdev_del_tx_ts(struct cfg80211_registered_device *rdev, return ret; } +static inline int +rdev_tdls_channel_switch(struct cfg80211_registered_device *rdev, + struct net_device *dev, const u8 *addr, + u8 oper_class, struct cfg80211_chan_def *chandef) +{ + int ret; + + trace_rdev_tdls_channel_switch(&rdev->wiphy, dev, addr, oper_class, + chandef); + ret = rdev->ops->tdls_channel_switch(&rdev->wiphy, dev, addr, + oper_class, chandef); + trace_rdev_return_int(&rdev->wiphy, ret); + return ret; +} + +static inline void +rdev_tdls_cancel_channel_switch(struct cfg80211_registered_device *rdev, + struct net_device *dev, const u8 *addr) +{ + trace_rdev_tdls_cancel_channel_switch(&rdev->wiphy, dev, addr); + rdev->ops->tdls_cancel_channel_switch(&rdev->wiphy, dev, addr); + trace_rdev_return_void(&rdev->wiphy); +} + #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 6e25370d3ce7..ad38910f7036 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -2032,6 +2032,48 @@ TRACE_EVENT(rdev_del_tx_ts, WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tsid) ); +TRACE_EVENT(rdev_tdls_channel_switch, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef), + TP_ARGS(wiphy, netdev, addr, oper_class, chandef), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(addr) + __field(u8, oper_class) + CHAN_DEF_ENTRY + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(addr, addr); + CHAN_DEF_ASSIGN(chandef); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT + " oper class %d, " CHAN_DEF_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr), + __entry->oper_class, CHAN_DEF_PR_ARG) +); + +TRACE_EVENT(rdev_tdls_cancel_channel_switch, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + const u8 *addr), + TP_ARGS(wiphy, netdev, addr), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + MAC_ENTRY(addr) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + MAC_ASSIGN(addr, addr); + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT, + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr)) +); + /************************************************************* * cfg80211 exported functions traces * *************************************************************/ -- GitLab From 53837584438f8899e061ada4663ae1d09b49b96a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:18 +0200 Subject: [PATCH 5317/9457] mac80211: add parsing of TDLS specific IEs These are used in TDLS channel switching code. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/linux/ieee80211.h | 15 +++++++++++++++ net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/util.c | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index fbb02d240658..4f4eea8a6288 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1067,6 +1067,12 @@ struct ieee80211_pspoll { /* TDLS */ +/* Channel switch timing */ +struct ieee80211_ch_switch_timing { + __le16 switch_time; + __le16 switch_timeout; +} __packed; + /* Link-id information element */ struct ieee80211_tdls_lnkie { u8 ie_type; /* Link Identifier IE */ @@ -1108,6 +1114,15 @@ struct ieee80211_tdls_data { u8 dialog_token; u8 variable[0]; } __packed discover_req; + struct { + u8 target_channel; + u8 oper_class; + u8 variable[0]; + } __packed chan_switch_req; + struct { + __le16 status_code; + u8 variable[0]; + } __packed chan_switch_resp; } u; } __packed; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4b3a7e7ec2a0..e786ab6bc72c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1400,6 +1400,8 @@ struct ieee802_11_elems { size_t total_len; /* pointers to IEs */ + const struct ieee80211_tdls_lnkie *lnk_id; + const struct ieee80211_ch_switch_timing *ch_sw_timing; const u8 *ext_capab; const u8 *ssid; const u8 *supp_rates; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3ca0c2e725ff..9e5bfd614856 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -832,6 +832,8 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: case WLAN_EID_CHAN_SWITCH_PARAM: case WLAN_EID_EXT_CAPABILITY: + case WLAN_EID_CHAN_SWITCH_TIMING: + case WLAN_EID_LINK_ID: /* * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible * that if the content gets bigger it might be needed more than once @@ -851,6 +853,20 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, elem_parse_failed = false; switch (id) { + case WLAN_EID_LINK_ID: + if (elen + 2 != sizeof(struct ieee80211_tdls_lnkie)) { + elem_parse_failed = true; + break; + } + elems->lnk_id = (void *)(pos - 2); + break; + case WLAN_EID_CHAN_SWITCH_TIMING: + if (elen != sizeof(struct ieee80211_ch_switch_timing)) { + elem_parse_failed = true; + break; + } + elems->ch_sw_timing = (void *)pos; + break; case WLAN_EID_EXT_CAPABILITY: elems->ext_capab = pos; elems->ext_capab_len = elen; -- GitLab From a7a6bdd0670feb8bfc26d41cda32b6064dbca50e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:19 +0200 Subject: [PATCH 5318/9457] mac80211: introduce TDLS channel switch ops Implement the cfg80211 TDLS channel switch ops and introduce new mac80211 ones for low-level drivers. Verify low-level driver support for the new ops when using the relevant wiphy feature bit. Also verify the peer supports channel switching before passing the command down. Add a new STA flag to track the off-channel state with the TDLS peer and make sure to cancel the channel-switch if the peer STA is unexpectedly removed. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/net/mac80211.h | 19 +++ net/mac80211/cfg.c | 2 + net/mac80211/debugfs_sta.c | 10 +- net/mac80211/driver-ops.h | 41 +++++++ net/mac80211/ieee80211_i.h | 6 + net/mac80211/main.c | 5 + net/mac80211/sta_info.c | 9 ++ net/mac80211/sta_info.h | 3 + net/mac80211/tdls.c | 234 +++++++++++++++++++++++++++++++++++++ net/mac80211/trace.h | 57 +++++++++ 10 files changed, 381 insertions(+), 5 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 83232aa2f077..fdedceb7adcb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2915,6 +2915,16 @@ enum ieee80211_reconfig_type { * * @get_txpower: get current maximum tx power (in dBm) based on configuration * and hardware limits. + * + * @tdls_channel_switch: Start channel-switching with a TDLS peer. The driver + * is responsible for continually initiating channel-switching operations + * and returning to the base channel for communication with the AP. The + * driver receives a channel-switch request template and the location of + * the switch-timing IE within the template as part of the invocation. + * The template is valid only within the call, and the driver can + * optionally copy the skb for further re-use. + * @tdls_cancel_channel_switch: Stop channel-switching with a TDLS peer. Both + * peers must be on the base channel when the call completes. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -3126,6 +3136,15 @@ struct ieee80211_ops { u32 (*get_expected_throughput)(struct ieee80211_sta *sta); int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm); + + int (*tdls_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u8 oper_class, + struct cfg80211_chan_def *chandef, + struct sk_buff *skb, u32 ch_sw_tm_ie); + void (*tdls_cancel_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8195e65d8a91..e75d5c53e97b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3752,6 +3752,8 @@ const struct cfg80211_ops mac80211_config_ops = { .set_rekey_data = ieee80211_set_rekey_data, .tdls_oper = ieee80211_tdls_oper, .tdls_mgmt = ieee80211_tdls_mgmt, + .tdls_channel_switch = ieee80211_tdls_channel_switch, + .tdls_cancel_channel_switch = ieee80211_tdls_cancel_channel_switch, .probe_client = ieee80211_probe_client, .set_noack_map = ieee80211_set_noack_map, #ifdef CONFIG_PM diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 2ba7f53746da..94c70091bbd7 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -74,7 +74,7 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" int res = scnprintf(buf, sizeof(buf), - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", TEST(AUTH), TEST(ASSOC), TEST(PS_STA), TEST(PS_DRIVER), TEST(AUTHORIZED), TEST(SHORT_PREAMBLE), @@ -83,10 +83,10 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), TEST(TDLS_PEER_AUTH), TEST(TDLS_INITIATOR), - TEST(TDLS_CHAN_SWITCH), TEST(4ADDR_EVENT), - TEST(INSERTED), TEST(RATE_CONTROL), - TEST(TOFFSET_KNOWN), TEST(MPSP_OWNER), - TEST(MPSP_RECIPIENT)); + TEST(TDLS_CHAN_SWITCH), TEST(TDLS_OFF_CHANNEL), + TEST(4ADDR_EVENT), TEST(INSERTED), + TEST(RATE_CONTROL), TEST(TOFFSET_KNOWN), + TEST(MPSP_OWNER), TEST(MPSP_RECIPIENT)); #undef TEST return simple_read_from_buffer(userbuf, count, ppos, buf, res); } diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 9759dd1f0734..ec4ae42ac15f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1296,4 +1296,45 @@ static inline int drv_get_txpower(struct ieee80211_local *local, return ret; } +static inline int +drv_tdls_channel_switch(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, u8 oper_class, + struct cfg80211_chan_def *chandef, + struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) +{ + int ret; + + might_sleep(); + if (!check_sdata_in_driver(sdata)) + return -EIO; + + if (!local->ops->tdls_channel_switch) + return -EOPNOTSUPP; + + trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef); + ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta, + oper_class, chandef, tmpl_skb, + ch_sw_tm_ie); + trace_drv_return_int(local, ret); + return ret; +} + +static inline void +drv_tdls_cancel_channel_switch(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta) +{ + might_sleep(); + if (!check_sdata_in_driver(sdata)) + return; + + if (!local->ops->tdls_cancel_channel_switch) + return; + + trace_drv_tdls_cancel_channel_switch(local, sdata, sta); + local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta); + trace_drv_return_void(local); +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e786ab6bc72c..2c7abc077b6b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2007,6 +2007,12 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, enum nl80211_tdls_operation oper); void ieee80211_tdls_peer_del_work(struct work_struct *wk); +int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef); +void ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr); extern const struct ethtool_ops ieee80211_ethtool_ops; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 282a4f36eb92..774ccb2d9a76 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -764,6 +764,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.offchannel_tx_hw_queue >= local->hw.queues)) return -EINVAL; + if ((hw->wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) && + (!local->ops->tdls_channel_switch || + !local->ops->tdls_cancel_channel_switch)) + return -EOPNOTSUPP; + #ifdef CONFIG_PM if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume)) return -EINVAL; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 97372514f287..86ca62765699 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -847,6 +847,15 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta) if (WARN_ON(ret)) return ret; + /* + * for TDLS peers, make sure to return to the base channel before + * removal. + */ + if (test_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL)) { + drv_tdls_cancel_channel_switch(local, sdata, &sta->sta); + clear_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL); + } + list_del_rcu(&sta->list); drv_sta_pre_rcu_remove(local, sta->sdata, sta); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index b6702c810ad3..00f56eb72c60 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -50,6 +50,8 @@ * @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this * station. * @WLAN_STA_TDLS_CHAN_SWITCH: This TDLS peer supports TDLS channel-switching + * @WLAN_STA_TDLS_OFF_CHANNEL: The local STA is currently off-channel with this + * TDLS peer * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was * keeping station in power-save mode, reply when the driver * unblocks the station. @@ -80,6 +82,7 @@ enum ieee80211_sta_info_flags { WLAN_STA_TDLS_PEER_AUTH, WLAN_STA_TDLS_INITIATOR, WLAN_STA_TDLS_CHAN_SWITCH, + WLAN_STA_TDLS_OFF_CHANNEL, WLAN_STA_UAPSD, WLAN_STA_SP, WLAN_STA_4ADDR_EVENT, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index fa141aecd986..358f9a4512ad 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -449,6 +449,48 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); } +static void +ieee80211_tdls_add_chan_switch_req_ies(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, const u8 *peer, + bool initiator, const u8 *extra_ies, + size_t extra_ies_len, u8 oper_class, + struct cfg80211_chan_def *chandef) +{ + struct ieee80211_tdls_data *tf; + size_t offset = 0, noffset; + u8 *pos; + + if (WARN_ON_ONCE(!chandef)) + return; + + tf = (void *)skb->data; + tf->u.chan_switch_req.target_channel = + ieee80211_frequency_to_channel(chandef->chan->center_freq); + tf->u.chan_switch_req.oper_class = oper_class; + + if (extra_ies_len) { + static const u8 before_lnkie[] = { + WLAN_EID_SECONDARY_CHANNEL_OFFSET, + }; + noffset = ieee80211_ie_split(extra_ies, extra_ies_len, + before_lnkie, + ARRAY_SIZE(before_lnkie), + offset); + pos = skb_put(skb, noffset - offset); + memcpy(pos, extra_ies + offset, noffset - offset); + offset = noffset; + } + + ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); + + /* add any remaining IEs */ + if (extra_ies_len) { + noffset = extra_ies_len; + pos = skb_put(skb, noffset - offset); + memcpy(pos, extra_ies + offset, noffset - offset); + } +} + static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, const u8 *peer, u8 action_code, u16 status_code, @@ -481,6 +523,12 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN) ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); break; + case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: + ieee80211_tdls_add_chan_switch_req_ies(sdata, skb, peer, + initiator, extra_ies, + extra_ies_len, + oper_class, chandef); + break; } } @@ -547,6 +595,12 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, skb_put(skb, sizeof(tf->u.discover_req)); tf->u.discover_req.dialog_token = dialog_token; break; + case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: + tf->category = WLAN_CATEGORY_TDLS; + tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST; + + skb_put(skb, sizeof(tf->u.chan_switch_req)); + break; default: return -EINVAL; } @@ -626,6 +680,7 @@ ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata, case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_DISCOVERY_REQUEST: + case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, sdata->dev, peer, action_code, dialog_token, @@ -699,6 +754,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, initiator = false; break; case WLAN_TDLS_TEARDOWN: + case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: /* any value is ok */ break; default: @@ -1046,3 +1102,181 @@ void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer, cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp); } EXPORT_SYMBOL(ieee80211_tdls_oper_request); + +static void +iee80211_tdls_add_ch_switch_timing(u8 *buf, u16 switch_time, u16 switch_timeout) +{ + struct ieee80211_ch_switch_timing *ch_sw; + + *buf++ = WLAN_EID_CHAN_SWITCH_TIMING; + *buf++ = sizeof(struct ieee80211_ch_switch_timing); + + ch_sw = (void *)buf; + ch_sw->switch_time = cpu_to_le16(switch_time); + ch_sw->switch_timeout = cpu_to_le16(switch_timeout); +} + +/* find switch timing IE in SKB ready for Tx */ +static const u8 *ieee80211_tdls_find_sw_timing_ie(struct sk_buff *skb) +{ + struct ieee80211_tdls_data *tf; + const u8 *ie_start; + + /* + * Get the offset for the new location of the switch timing IE. + * The SKB network header will now point to the "payload_type" + * element of the TDLS data frame struct. + */ + tf = container_of(skb->data + skb_network_offset(skb), + struct ieee80211_tdls_data, payload_type); + ie_start = tf->u.chan_switch_req.variable; + return cfg80211_find_ie(WLAN_EID_CHAN_SWITCH_TIMING, ie_start, + skb->len - (ie_start - skb->data)); +} + +static struct sk_buff * +ieee80211_tdls_ch_sw_tmpl_get(struct sta_info *sta, u8 oper_class, + struct cfg80211_chan_def *chandef, + u32 *ch_sw_tm_ie_offset) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + u8 extra_ies[2 + sizeof(struct ieee80211_sec_chan_offs_ie) + + 2 + sizeof(struct ieee80211_ch_switch_timing)]; + int extra_ies_len = 2 + sizeof(struct ieee80211_ch_switch_timing); + u8 *pos = extra_ies; + struct sk_buff *skb; + + /* + * if chandef points to a wide channel add a Secondary-Channel + * Offset information element + */ + if (chandef->width == NL80211_CHAN_WIDTH_40) { + struct ieee80211_sec_chan_offs_ie *sec_chan_ie; + bool ht40plus; + + *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; + *pos++ = sizeof(*sec_chan_ie); + sec_chan_ie = (void *)pos; + + ht40plus = cfg80211_get_chandef_type(chandef) == + NL80211_CHAN_HT40PLUS; + sec_chan_ie->sec_chan_offs = ht40plus ? + IEEE80211_HT_PARAM_CHA_SEC_ABOVE : + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + pos += sizeof(*sec_chan_ie); + + extra_ies_len += 2 + sizeof(struct ieee80211_sec_chan_offs_ie); + } + + /* just set the values to 0, this is a template */ + iee80211_tdls_add_ch_switch_timing(pos, 0, 0); + + skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, + WLAN_TDLS_CHANNEL_SWITCH_REQUEST, + 0, 0, !sta->sta.tdls_initiator, + extra_ies, extra_ies_len, + oper_class, chandef); + if (!skb) + return NULL; + + skb = ieee80211_build_data_template(sdata, skb, 0); + if (IS_ERR(skb)) { + tdls_dbg(sdata, "Failed building TDLS channel switch frame\n"); + return NULL; + } + + if (ch_sw_tm_ie_offset) { + const u8 *tm_ie = ieee80211_tdls_find_sw_timing_ie(skb); + + if (!tm_ie) { + tdls_dbg(sdata, "No switch timing IE in TDLS switch\n"); + dev_kfree_skb_any(skb); + return NULL; + } + + *ch_sw_tm_ie_offset = tm_ie - skb->data; + } + + tdls_dbg(sdata, + "TDLS channel switch request template for %pM ch %d width %d\n", + sta->sta.addr, chandef->chan->center_freq, chandef->width); + return skb; +} + +int +ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + struct sk_buff *skb = NULL; + u32 ch_sw_tm_ie; + int ret; + + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, addr); + if (!sta) { + tdls_dbg(sdata, + "Invalid TDLS peer %pM for channel switch request\n", + addr); + ret = -ENOENT; + goto out; + } + + if (!test_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH)) { + tdls_dbg(sdata, "TDLS channel switch unsupported by %pM\n", + addr); + ret = -ENOTSUPP; + goto out; + } + + skb = ieee80211_tdls_ch_sw_tmpl_get(sta, oper_class, chandef, + &ch_sw_tm_ie); + if (!skb) { + ret = -ENOENT; + goto out; + } + + ret = drv_tdls_channel_switch(local, sdata, &sta->sta, oper_class, + chandef, skb, ch_sw_tm_ie); + if (!ret) + set_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL); + +out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(skb); + return ret; +} + +void +ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, addr); + if (!sta) { + tdls_dbg(sdata, + "Invalid TDLS peer %pM for channel switch cancel\n", + addr); + goto out; + } + + if (!test_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL)) { + tdls_dbg(sdata, "TDLS channel switch not initiated by %pM\n", + addr); + goto out; + } + + drv_tdls_cancel_channel_switch(local, sdata, &sta->sta); + clear_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL); + +out: + mutex_unlock(&local->sta_mtx); +} diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 96847e788488..c0c0fcace9d8 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2196,6 +2196,63 @@ TRACE_EVENT(drv_get_txpower, ) ); +TRACE_EVENT(drv_tdls_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, u8 oper_class, + struct cfg80211_chan_def *chandef), + + TP_ARGS(local, sdata, sta, oper_class, chandef), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + STA_ENTRY + __field(u8, oper_class) + CHANDEF_ENTRY + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + STA_ASSIGN; + __entry->oper_class = oper_class; + CHANDEF_ASSIGN(chandef) + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " tdls channel switch to" + CHANDEF_PR_FMT " oper_class:%d " STA_PR_FMT, + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->oper_class, + STA_PR_ARG + ) +); + +TRACE_EVENT(drv_tdls_cancel_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta), + + TP_ARGS(local, sdata, sta), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + STA_ENTRY + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + STA_ASSIGN; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT + " tdls cancel channel switch with " STA_PR_FMT, + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG + ) +); #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM -- GitLab From 8a4d32f30d11d6d8cc29594c7a36b9be6b0edbb5 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 9 Nov 2014 18:50:20 +0200 Subject: [PATCH 5319/9457] mac80211: add TDLS channel-switch Rx flow When receiving a TDLS channel switch request or response, parse the frame and call a new tdls_recv_channel_switch op in the low level driver with the parsed data. Signed-off-by: Arik Nemtsov Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/net/mac80211.h | 37 ++++- net/mac80211/driver-ops.h | 12 ++ net/mac80211/ieee80211_i.h | 3 + net/mac80211/iface.c | 2 + net/mac80211/main.c | 3 +- net/mac80211/rx.c | 21 +++ net/mac80211/tdls.c | 328 +++++++++++++++++++++++++++++++++++++ net/mac80211/trace.h | 45 +++++ 8 files changed, 449 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index fdedceb7adcb..56b7e2114728 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1826,6 +1826,31 @@ struct ieee80211_scan_request { struct cfg80211_scan_request req; }; +/** + * struct ieee80211_tdls_ch_sw_params - TDLS channel switch parameters + * + * @sta: peer this TDLS channel-switch request/response came from + * @chandef: channel referenced in a TDLS channel-switch request + * @action_code: see &enum ieee80211_tdls_actioncode + * @status: channel-switch response status + * @timestamp: time at which the frame was received + * @switch_time: switch-timing parameter received in the frame + * @switch_timeout: switch-timing parameter received in the frame + * @tmpl_skb: TDLS switch-channel response template + * @ch_sw_tm_ie: offset of the channel-switch timing IE inside @tmpl_skb + */ +struct ieee80211_tdls_ch_sw_params { + struct ieee80211_sta *sta; + struct cfg80211_chan_def *chandef; + u8 action_code; + u32 status; + u32 timestamp; + u16 switch_time; + u16 switch_timeout; + struct sk_buff *tmpl_skb; + u32 ch_sw_tm_ie; +}; + /** * wiphy_to_ieee80211_hw - return a mac80211 driver hw struct from a wiphy * @@ -2925,6 +2950,13 @@ enum ieee80211_reconfig_type { * optionally copy the skb for further re-use. * @tdls_cancel_channel_switch: Stop channel-switching with a TDLS peer. Both * peers must be on the base channel when the call completes. + * @tdls_recv_channel_switch: a TDLS channel-switch related frame (request or + * response) has been received from a remote peer. The driver gets + * parameters parsed from the incoming frame and may use them to continue + * an ongoing channel-switch operation. In addition, a channel-switch + * response template is provided, together with the location of the + * switch-timing IE within the template. The skb can only be used within + * the function call. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -3141,10 +3173,13 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_sta *sta, u8 oper_class, struct cfg80211_chan_def *chandef, - struct sk_buff *skb, u32 ch_sw_tm_ie); + struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie); void (*tdls_cancel_channel_switch)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); + void (*tdls_recv_channel_switch)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_tdls_ch_sw_params *params); }; /** diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ec4ae42ac15f..ba0d2cb5df12 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1337,4 +1337,16 @@ drv_tdls_cancel_channel_switch(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline void +drv_tdls_recv_channel_switch(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_tdls_ch_sw_params *params) +{ + trace_drv_tdls_recv_channel_switch(local, sdata, params); + if (local->ops->tdls_recv_channel_switch) + local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif, + params); + trace_drv_return_void(local); +} + #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2c7abc077b6b..5de2e5f3a57e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -993,6 +993,7 @@ enum sdata_queue_type { IEEE80211_SDATA_QUEUE_AGG_STOP = 2, IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, + IEEE80211_SDATA_QUEUE_TDLS_CHSW = 5, }; enum { @@ -2013,6 +2014,8 @@ int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, void ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy, struct net_device *dev, const u8 *addr); +void ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); extern const struct ethtool_ops ieee80211_ethtool_ops; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6b631c049eba..82473d909bb6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1202,6 +1202,8 @@ static void ieee80211_iface_work(struct work_struct *work) WLAN_BACK_RECIPIENT, 0, false); mutex_unlock(&local->sta_mtx); + } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_TDLS_CHSW) { + ieee80211_process_tdls_channel_switch(sdata, skb); } else if (ieee80211_is_action(mgmt->frame_control) && mgmt->u.action.category == WLAN_CATEGORY_BACK) { int len = skb->len; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 774ccb2d9a76..6ab99da38db9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -766,7 +766,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if ((hw->wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) && (!local->ops->tdls_channel_switch || - !local->ops->tdls_cancel_channel_switch)) + !local->ops->tdls_cancel_channel_switch || + !local->ops->tdls_recv_channel_switch)) return -EOPNOTSUPP; #ifdef CONFIG_PM diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0f4297e2aae2..d9bbb73d4436 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2333,6 +2333,27 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) if (!ieee80211_frame_allowed(rx, fc)) return RX_DROP_MONITOR; + /* directly handle TDLS channel switch requests/responses */ + if (unlikely(((struct ethhdr *)rx->skb->data)->h_proto == + cpu_to_be16(ETH_P_TDLS))) { + struct ieee80211_tdls_data *tf = (void *)rx->skb->data; + + if (pskb_may_pull(rx->skb, + offsetof(struct ieee80211_tdls_data, u)) && + tf->payload_type == WLAN_TDLS_SNAP_RFTYPE && + tf->category == WLAN_CATEGORY_TDLS && + (tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST || + tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE)) { + rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TDLS_CHSW; + skb_queue_tail(&sdata->skb_queue, rx->skb); + ieee80211_queue_work(&rx->local->hw, &sdata->work); + if (rx->sta) + rx->sta->rx_packets++; + + return RX_QUEUED; + } + } + if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && unlikely(port_control) && sdata->bss) { sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 358f9a4512ad..55ddd77b865d 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -491,6 +491,20 @@ ieee80211_tdls_add_chan_switch_req_ies(struct ieee80211_sub_if_data *sdata, } } +static void +ieee80211_tdls_add_chan_switch_resp_ies(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, const u8 *peer, + u16 status_code, bool initiator, + const u8 *extra_ies, + size_t extra_ies_len) +{ + if (status_code == 0) + ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); + + if (extra_ies_len) + memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); +} + static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, const u8 *peer, u8 action_code, u16 status_code, @@ -529,6 +543,12 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, extra_ies_len, oper_class, chandef); break; + case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE: + ieee80211_tdls_add_chan_switch_resp_ies(sdata, skb, peer, + status_code, + initiator, extra_ies, + extra_ies_len); + break; } } @@ -601,6 +621,13 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, skb_put(skb, sizeof(tf->u.chan_switch_req)); break; + case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE: + tf->category = WLAN_CATEGORY_TDLS; + tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE; + + skb_put(skb, sizeof(tf->u.chan_switch_resp)); + tf->u.chan_switch_resp.status_code = cpu_to_le16(status_code); + break; default: return -EINVAL; } @@ -681,6 +708,7 @@ ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata, case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_DISCOVERY_REQUEST: case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: + case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE: ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, sdata->dev, peer, action_code, dialog_token, @@ -755,6 +783,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, break; case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: + case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE: /* any value is ok */ break; default: @@ -1280,3 +1309,302 @@ ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy, out: mutex_unlock(&local->sta_mtx); } + +static struct sk_buff * +ieee80211_tdls_ch_sw_resp_tmpl_get(struct sta_info *sta, + u32 *ch_sw_tm_ie_offset) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct sk_buff *skb; + u8 extra_ies[2 + sizeof(struct ieee80211_ch_switch_timing)]; + + /* initial timing are always zero in the template */ + iee80211_tdls_add_ch_switch_timing(extra_ies, 0, 0); + + skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr, + WLAN_TDLS_CHANNEL_SWITCH_RESPONSE, + 0, 0, !sta->sta.tdls_initiator, + extra_ies, sizeof(extra_ies), 0, NULL); + if (!skb) + return NULL; + + skb = ieee80211_build_data_template(sdata, skb, 0); + if (IS_ERR(skb)) { + tdls_dbg(sdata, + "Failed building TDLS channel switch resp frame\n"); + return NULL; + } + + if (ch_sw_tm_ie_offset) { + const u8 *tm_ie = ieee80211_tdls_find_sw_timing_ie(skb); + + if (!tm_ie) { + tdls_dbg(sdata, + "No switch timing IE in TDLS switch resp\n"); + dev_kfree_skb_any(skb); + return NULL; + } + + *ch_sw_tm_ie_offset = tm_ie - skb->data; + } + + tdls_dbg(sdata, "TDLS get channel switch response template for %pM\n", + sta->sta.addr); + return skb; +} + +static int +ieee80211_process_tdls_channel_switch_resp(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_local *local = sdata->local; + struct ieee802_11_elems elems; + struct sta_info *sta; + struct ieee80211_tdls_data *tf = (void *)skb->data; + bool local_initiator; + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + int baselen = offsetof(typeof(*tf), u.chan_switch_resp.variable); + struct ieee80211_tdls_ch_sw_params params = {}; + int ret; + + params.action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE; + params.timestamp = rx_status->device_timestamp; + + if (skb->len < baselen) { + tdls_dbg(sdata, "TDLS channel switch resp too short: %d\n", + skb->len); + return -EINVAL; + } + + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, tf->sa); + if (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) { + tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", + tf->sa); + ret = -EINVAL; + goto out; + } + + params.sta = &sta->sta; + params.status = le16_to_cpu(tf->u.chan_switch_resp.status_code); + if (params.status != 0) { + ret = 0; + goto call_drv; + } + + ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, + skb->len - baselen, false, &elems); + if (elems.parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n"); + ret = -EINVAL; + goto out; + } + + if (!elems.ch_sw_timing || !elems.lnk_id) { + tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); + ret = -EINVAL; + goto out; + } + + /* validate the initiator is set correctly */ + local_initiator = + !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; + goto out; + } + + params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); + params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, ¶ms.ch_sw_tm_ie); + if (!params.tmpl_skb) { + ret = -ENOENT; + goto out; + } + +call_drv: + drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); + + tdls_dbg(sdata, + "TDLS channel switch response received from %pM status %d\n", + tf->sa, params.status); + +out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); + return ret; +} + +static int +ieee80211_process_tdls_channel_switch_req(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_local *local = sdata->local; + struct ieee802_11_elems elems; + struct cfg80211_chan_def chandef; + struct ieee80211_channel *chan; + enum nl80211_channel_type chan_type; + int freq; + u8 target_channel, oper_class; + bool local_initiator; + struct sta_info *sta; + enum ieee80211_band band; + struct ieee80211_tdls_data *tf = (void *)skb->data; + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + int baselen = offsetof(typeof(*tf), u.chan_switch_req.variable); + struct ieee80211_tdls_ch_sw_params params = {}; + int ret = 0; + + params.action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST; + params.timestamp = rx_status->device_timestamp; + + if (skb->len < baselen) { + tdls_dbg(sdata, "TDLS channel switch req too short: %d\n", + skb->len); + return -EINVAL; + } + + target_channel = tf->u.chan_switch_req.target_channel; + oper_class = tf->u.chan_switch_req.oper_class; + + /* + * We can't easily infer the channel band. The operating class is + * ambiguous - there are multiple tables (US/Europe/JP/Global). The + * solution here is to treat channels with number >14 as 5GHz ones, + * and specifically check for the (oper_class, channel) combinations + * where this doesn't hold. These are thankfully unique according to + * IEEE802.11-2012. + * We consider only the 2GHz and 5GHz bands and 20MHz+ channels as + * valid here. + */ + if ((oper_class == 112 || oper_class == 2 || oper_class == 3 || + oper_class == 4 || oper_class == 5 || oper_class == 6) && + target_channel < 14) + band = IEEE80211_BAND_5GHZ; + else + band = target_channel < 14 ? IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ; + + freq = ieee80211_channel_to_frequency(target_channel, band); + if (freq == 0) { + tdls_dbg(sdata, "Invalid channel in TDLS chan switch: %d\n", + target_channel); + return -EINVAL; + } + + chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); + if (!chan) { + tdls_dbg(sdata, + "Unsupported channel for TDLS chan switch: %d\n", + target_channel); + return -EINVAL; + } + + ieee802_11_parse_elems(tf->u.chan_switch_req.variable, + skb->len - baselen, false, &elems); + if (elems.parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n"); + return -EINVAL; + } + + if (!elems.ch_sw_timing || !elems.lnk_id) { + tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); + return -EINVAL; + } + + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, tf->sa); + if (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) { + tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n", + tf->sa); + ret = -EINVAL; + goto out; + } + + params.sta = &sta->sta; + + /* validate the initiator is set correctly */ + local_initiator = + !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; + goto out; + } + + if (!sta->sta.ht_cap.ht_supported) { + chan_type = NL80211_CHAN_NO_HT; + } else if (!elems.sec_chan_offs) { + chan_type = NL80211_CHAN_HT20; + } else { + switch (elems.sec_chan_offs->sec_chan_offs) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + chan_type = NL80211_CHAN_HT40PLUS; + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + chan_type = NL80211_CHAN_HT40MINUS; + break; + default: + chan_type = NL80211_CHAN_HT20; + break; + } + } + + cfg80211_chandef_create(&chandef, chan, chan_type); + params.chandef = &chandef; + + params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); + params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, + ¶ms.ch_sw_tm_ie); + if (!params.tmpl_skb) { + ret = -ENOENT; + goto out; + } + + drv_tdls_recv_channel_switch(sdata->local, sdata, ¶ms); + + tdls_dbg(sdata, + "TDLS ch switch request received from %pM ch %d width %d\n", + tf->sa, params.chandef->chan->center_freq, + params.chandef->width); +out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); + return ret; +} + +void ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_tdls_data *tf = (void *)skb->data; + struct wiphy *wiphy = sdata->local->hw.wiphy; + + /* make sure the driver supports it */ + if (!(wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH)) + return; + + /* we want to access the entire packet */ + if (skb_linearize(skb)) + return; + /* + * The packet/size was already validated by mac80211 Rx path, only look + * at the action type. + */ + switch (tf->action_code) { + case WLAN_TDLS_CHANNEL_SWITCH_REQUEST: + ieee80211_process_tdls_channel_switch_req(sdata, skb); + break; + case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE: + ieee80211_process_tdls_channel_switch_resp(sdata, skb); + break; + default: + WARN_ON_ONCE(1); + return; + } +} diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index c0c0fcace9d8..7f76e2f25744 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -16,6 +16,7 @@ #define STA_ENTRY __array(char, sta_addr, ETH_ALEN) #define STA_ASSIGN (sta ? memcpy(__entry->sta_addr, sta->addr, ETH_ALEN) : memset(__entry->sta_addr, 0, ETH_ALEN)) +#define STA_NAMED_ASSIGN(s) memcpy(__entry->sta_addr, (s)->addr, ETH_ALEN) #define STA_PR_FMT " sta:%pM" #define STA_PR_ARG __entry->sta_addr @@ -2254,6 +2255,50 @@ TRACE_EVENT(drv_tdls_cancel_channel_switch, ) ); +TRACE_EVENT(drv_tdls_recv_channel_switch, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_tdls_ch_sw_params *params), + + TP_ARGS(local, sdata, params), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __field(u8, action_code) + STA_ENTRY + CHANDEF_ENTRY + __field(u32, status) + __field(bool, peer_initiator) + __field(u32, timestamp) + __field(u16, switch_time) + __field(u16, switch_timeout) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + STA_NAMED_ASSIGN(params->sta); + CHANDEF_ASSIGN(params->chandef) + __entry->peer_initiator = params->sta->tdls_initiator; + __entry->action_code = params->action_code; + __entry->status = params->status; + __entry->timestamp = params->timestamp; + __entry->switch_time = params->switch_time; + __entry->switch_timeout = params->switch_timeout; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " received tdls channel switch packet" + " action:%d status:%d time:%d switch time:%d switch" + " timeout:%d initiator: %d chan:" CHANDEF_PR_FMT STA_PR_FMT, + LOCAL_PR_ARG, VIF_PR_ARG, __entry->action_code, __entry->status, + __entry->timestamp, __entry->switch_time, + __entry->switch_timeout, __entry->peer_initiator, + CHANDEF_PR_ARG, STA_PR_ARG + ) +); + #ifdef CONFIG_MAC80211_MESSAGE_TRACING #undef TRACE_SYSTEM #define TRACE_SYSTEM mac80211_msg -- GitLab From 4f9610d528a6aa5642fa350fa93fbd905a753ae8 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 9 Nov 2014 18:50:21 +0200 Subject: [PATCH 5320/9457] mac80211: add specific-queue flushing support If the HW supports IEEE80211_HW_QUEUE_CONTROL, allow flushing only specific queues rather than all of them. Signed-off-by: Liad Kaufman Signed-off-by: Arik Nemtsov Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 3 +++ net/mac80211/util.c | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 5de2e5f3a57e..a30d40839d49 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1881,6 +1881,9 @@ void ieee80211_add_pending_skbs(struct ieee80211_local *local, struct sk_buff_head *skbs); void ieee80211_flush_queues(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); +void __ieee80211_flush_queues(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + unsigned int queues); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, u16 status, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9e5bfd614856..745a8a9cbbb5 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -576,15 +576,19 @@ ieee80211_get_vif_queues(struct ieee80211_local *local, return queues; } -void ieee80211_flush_queues(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) +void __ieee80211_flush_queues(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + unsigned int queues) { - unsigned int queues; - if (!local->ops->flush) return; - queues = ieee80211_get_vif_queues(local, sdata); + /* + * If no queue was set, or if the HW doesn't support + * IEEE80211_HW_QUEUE_CONTROL - flush all queues + */ + if (!queues || !(local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) + queues = ieee80211_get_vif_queues(local, sdata); ieee80211_stop_queues_by_reason(&local->hw, queues, IEEE80211_QUEUE_STOP_REASON_FLUSH, @@ -597,6 +601,12 @@ void ieee80211_flush_queues(struct ieee80211_local *local, false); } +void ieee80211_flush_queues(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + __ieee80211_flush_queues(local, sdata, 0); +} + void ieee80211_stop_vif_queues(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, enum queue_stop_reason reason) -- GitLab From b6da911b3cf1d342f2f7123c9eb6463d299bca4e Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Wed, 19 Nov 2014 13:47:38 +0200 Subject: [PATCH 5321/9457] mac80211: synchronously reserve TID per station In TDLS (e.g., TDLS off-channel) there is a requirement for some drivers to supply an unused TID between the AP and the device to the FW, to allow sending PTI requests and to allow the FW to aggregate on a specific TID for better throughput. To ensure that the allocated TID is indeed unused, this patch introduces an API for blocking the driver from TXing on that TID. Signed-off-by: Liad Kaufman Signed-off-by: Johannes Berg --- include/net/mac80211.h | 37 ++++++++++++++++ net/mac80211/agg-tx.c | 7 +++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/sta_info.c | 3 ++ net/mac80211/sta_info.h | 6 +++ net/mac80211/tx.c | 91 ++++++++++++++++++++++++++++++++++++++ net/mac80211/wme.c | 39 ++++++++++++++++ 7 files changed, 184 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 56b7e2114728..59166a115aff 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -5070,6 +5070,43 @@ void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer, enum nl80211_tdls_operation oper, u16 reason_code, gfp_t gfp); +/** + * ieee80211_reserve_tid - request to reserve a specific TID + * + * There is sometimes a need (such as in TDLS) for blocking the driver from + * using a specific TID so that the FW can use it for certain operations such + * as sending PTI requests. To make sure that the driver doesn't use that TID, + * this function must be called as it flushes out packets on this TID and marks + * it as blocked, so that any transmit for the station on this TID will be + * redirected to the alternative TID in the same AC. + * + * Note that this function blocks and may call back into the driver, so it + * should be called without driver locks held. Also note this function should + * only be called from the driver's @sta_state callback. + * + * @sta: the station to reserve the TID for + * @tid: the TID to reserve + * + * Returns: 0 on success, else on failure + */ +int ieee80211_reserve_tid(struct ieee80211_sta *sta, u8 tid); + +/** + * ieee80211_unreserve_tid - request to unreserve a specific TID + * + * Once there is no longer any need for reserving a certain TID, this function + * should be called, and no longer will packets have their TID modified for + * preventing use of this TID in the driver. + * + * Note that this function blocks and acquires a lock, so it should be called + * without driver locks held. Also note this function should only be called + * from the driver's @sta_state callback. + * + * @sta: the station + * @tid: the TID to unreserve + */ +void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid); + /** * ieee80211_ie_split - split an IE buffer according to ordering * diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 9242c60048cf..a360c15cc978 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -509,6 +509,10 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, struct tid_ampdu_tx *tid_tx; int ret = 0; + if (WARN(sta->reserved_tid == tid, + "Requested to start BA session on reserved tid=%d", tid)) + return -EINVAL; + trace_api_start_tx_ba_session(pubsta, tid); if (WARN_ON_ONCE(!local->ops->ampdu_action)) @@ -765,6 +769,9 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) goto unlock; } + WARN(sta->reserved_tid == tid, + "Requested to stop BA session on reserved tid=%d", tid); + if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { /* already in progress stopping it */ ret = 0; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a30d40839d49..34168c21bf06 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1011,6 +1011,7 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, IEEE80211_QUEUE_STOP_REASON_FLUSH, IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN, + IEEE80211_QUEUE_STOP_REASON_RESERVE_TID, IEEE80211_QUEUE_STOP_REASONS, }; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 86ca62765699..a42f5b2b024d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -351,6 +351,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->sta_state = IEEE80211_STA_NONE; + /* Mark TID as unreserved */ + sta->reserved_tid = IEEE80211_TID_UNRESERVED; + ktime_get_ts(&uptime); sta->last_connected = uptime.tv_sec; ewma_init(&sta->avg_signal, 1024, 8); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 00f56eb72c60..4f052bb2a5ad 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -254,6 +254,9 @@ struct ieee80211_tx_latency_stat { u32 bin_count; }; +/* Value to indicate no TID reservation */ +#define IEEE80211_TID_UNRESERVED 0xff + /** * struct sta_info - STA information * @@ -342,6 +345,7 @@ struct ieee80211_tx_latency_stat { * AP only. * @cipher_scheme: optional cipher scheme for this station * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed + * @reserved_tid: reserved TID (if any, otherwise IEEE80211_TID_UNRESERVED) */ struct sta_info { /* General information, mostly static */ @@ -459,6 +463,8 @@ struct sta_info { /* TDLS timeout data */ unsigned long last_tdls_pkt_time; + u8 reserved_tid; + /* keep last! */ struct ieee80211_sta sta; }; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2dd89670e1cd..0cb41d1a1f20 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3107,6 +3107,97 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_get_buffered_bc); +int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid) +{ + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; + int ret; + u32 queues; + + lockdep_assert_held(&local->sta_mtx); + + /* only some cases are supported right now */ + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + break; + default: + WARN_ON(1); + return -EINVAL; + } + + if (WARN_ON(tid >= IEEE80211_NUM_UPS)) + return -EINVAL; + + if (sta->reserved_tid == tid) { + ret = 0; + goto out; + } + + if (sta->reserved_tid != IEEE80211_TID_UNRESERVED) { + sdata_err(sdata, "TID reservation already active\n"); + ret = -EALREADY; + goto out; + } + + ieee80211_stop_vif_queues(sdata->local, sdata, + IEEE80211_QUEUE_STOP_REASON_RESERVE_TID); + + synchronize_net(); + + /* Tear down BA sessions so we stop aggregating on this TID */ + if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) { + set_sta_flag(sta, WLAN_STA_BLOCK_BA); + __ieee80211_stop_tx_ba_session(sta, tid, + AGG_STOP_LOCAL_REQUEST); + } + + queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]); + __ieee80211_flush_queues(local, sdata, queues); + + sta->reserved_tid = tid; + + ieee80211_wake_vif_queues(local, sdata, + IEEE80211_QUEUE_STOP_REASON_RESERVE_TID); + + if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) + clear_sta_flag(sta, WLAN_STA_BLOCK_BA); + + ret = 0; + out: + return ret; +} +EXPORT_SYMBOL(ieee80211_reserve_tid); + +void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid) +{ + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); + struct ieee80211_sub_if_data *sdata = sta->sdata; + + lockdep_assert_held(&sdata->local->sta_mtx); + + /* only some cases are supported right now */ + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + break; + default: + WARN_ON(1); + return; + } + + if (tid != sta->reserved_tid) { + sdata_err(sdata, "TID to unreserve (%d) isn't reserved\n", tid); + return; + } + + sta->reserved_tid = IEEE80211_TID_UNRESERVED; +} +EXPORT_SYMBOL(ieee80211_unreserve_tid); + void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, int tid, enum ieee80211_band band) diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index fdf52db95b33..9eb0aee9105b 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -53,6 +53,36 @@ static int wme_downgrade_ac(struct sk_buff *skb) } } +/** + * ieee80211_fix_reserved_tid - return the TID to use if this one is reserved + * @tid: the assumed-reserved TID + * + * Returns: the alternative TID to use, or 0 on error + */ +static inline u8 ieee80211_fix_reserved_tid(u8 tid) +{ + switch (tid) { + case 0: + return 3; + case 1: + return 2; + case 2: + return 1; + case 3: + return 0; + case 4: + return 5; + case 5: + return 4; + case 6: + return 7; + case 7: + return 6; + } + + return 0; +} + static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct sk_buff *skb) { @@ -77,6 +107,10 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, } } + /* Check to see if this is a reserved TID */ + if (sta && sta->reserved_tid == skb->priority) + skb->priority = ieee80211_fix_reserved_tid(skb->priority); + /* look up which queue to use for frames with this 1d tag */ return ieee802_1d_to_ac[skb->priority]; } @@ -143,6 +177,11 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, break; #endif case NL80211_IFTYPE_STATION: + /* might be a TDLS station */ + sta = sta_info_get(sdata, skb->data); + if (sta) + qos = sta->sta.wme; + ra = sdata->u.mgd.bssid; break; case NL80211_IFTYPE_ADHOC: -- GitLab From 256da02d1806c740be97576a5e8548d658858319 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 16:13:46 +0200 Subject: [PATCH 5322/9457] cfg80211: refactor nl80211_start_sched_scan so it can be reused For net detect, we will need to reuse most of the scheduled scan parsing function, but not all, so split out the attributes parsing part out of the main start sched_scan function. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 130 +++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 27666f5e5050..03a302b884fd 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5681,14 +5681,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) return err; } -static int nl80211_start_sched_scan(struct sk_buff *skb, - struct genl_info *info) +static struct cfg80211_sched_scan_request * +nl80211_parse_sched_scan(struct wiphy *wiphy, + struct nlattr **attrs) { struct cfg80211_sched_scan_request *request; - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; struct nlattr *attr; - struct wiphy *wiphy; int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; u32 interval; enum ieee80211_band band; @@ -5696,38 +5694,32 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF; - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || - !rdev->ops->sched_scan_start) - return -EOPNOTSUPP; - - if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) - return -EINVAL; + if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE])) + return ERR_PTR(-EINVAL); - if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) - return -EINVAL; + if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) + return ERR_PTR(-EINVAL); - interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); + interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); if (interval == 0) - return -EINVAL; - - wiphy = &rdev->wiphy; + return ERR_PTR(-EINVAL); - if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { n_channels = validate_scan_freqs( - info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); + attrs[NL80211_ATTR_SCAN_FREQUENCIES]); if (!n_channels) - return -EINVAL; + return ERR_PTR(-EINVAL); } else { n_channels = ieee80211_get_num_supported_channels(wiphy); } - if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) - nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], + if (attrs[NL80211_ATTR_SCAN_SSIDS]) + nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS], tmp) n_ssids++; if (n_ssids > wiphy->max_sched_scan_ssids) - return -EINVAL; + return ERR_PTR(-EINVAL); /* * First, count the number of 'real' matchsets. Due to an issue with @@ -5738,9 +5730,9 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, * older userspace that treated a matchset with only the RSSI as the * global RSSI for all other matchsets - if there are other matchsets. */ - if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { + if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { nla_for_each_nested(attr, - info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + attrs[NL80211_ATTR_SCHED_SCAN_MATCH], tmp) { struct nlattr *rssi; @@ -5748,7 +5740,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, nla_data(attr), nla_len(attr), nl80211_match_policy); if (err) - return err; + return ERR_PTR(err); /* add other standalone attributes here */ if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) { n_match_sets++; @@ -5765,30 +5757,23 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, n_match_sets = 1; if (n_match_sets > wiphy->max_match_sets) - return -EINVAL; + return ERR_PTR(-EINVAL); - if (info->attrs[NL80211_ATTR_IE]) - ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); + if (attrs[NL80211_ATTR_IE]) + ie_len = nla_len(attrs[NL80211_ATTR_IE]); else ie_len = 0; if (ie_len > wiphy->max_sched_scan_ie_len) - return -EINVAL; - - if (rdev->sched_scan_req) { - err = -EINPROGRESS; - goto out; - } + return ERR_PTR(-EINVAL); request = kzalloc(sizeof(*request) + sizeof(*request->ssids) * n_ssids + sizeof(*request->match_sets) * n_match_sets + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); - if (!request) { - err = -ENOMEM; - goto out; - } + if (!request) + return ERR_PTR(-ENOMEM); if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; @@ -5813,10 +5798,10 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->n_match_sets = n_match_sets; i = 0; - if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { /* user specified, bail out if channel not found */ nla_for_each_nested(attr, - info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], + attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { struct ieee80211_channel *chan; @@ -5862,8 +5847,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->n_channels = i; i = 0; - if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { - nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], + if (attrs[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { err = -EINVAL; @@ -5877,9 +5862,9 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, } i = 0; - if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { + if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { nla_for_each_nested(attr, - info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + attrs[NL80211_ATTR_SCHED_SCAN_MATCH], tmp) { struct nlattr *ssid, *rssi; @@ -5934,13 +5919,13 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (ie_len) { request->ie_len = ie_len; memcpy((void *)request->ie, - nla_data(info->attrs[NL80211_ATTR_IE]), + nla_data(attrs[NL80211_ATTR_IE]), request->ie_len); } - if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { + if (attrs[NL80211_ATTR_SCAN_FLAGS]) { request->flags = nla_get_u32( - info->attrs[NL80211_ATTR_SCAN_FLAGS]); + attrs[NL80211_ATTR_SCAN_FLAGS]); if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { err = -EOPNOTSUPP; @@ -5948,22 +5933,51 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, } } - request->dev = dev; - request->wiphy = &rdev->wiphy; request->interval = interval; request->scan_start = jiffies; - err = rdev_sched_scan_start(rdev, dev, request); - if (!err) { - rdev->sched_scan_req = request; - nl80211_send_sched_scan(rdev, dev, - NL80211_CMD_START_SCHED_SCAN); - goto out; - } + return request; out_free: kfree(request); -out: + return ERR_PTR(err); +} + +static int nl80211_start_sched_scan(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + int err; + + if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || + !rdev->ops->sched_scan_start) + return -EOPNOTSUPP; + + if (rdev->sched_scan_req) + return -EINPROGRESS; + + rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, + info->attrs); + err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); + if (err) + goto out_err; + + err = rdev_sched_scan_start(rdev, dev, rdev->sched_scan_req); + if (err) + goto out_free; + + rdev->sched_scan_req->dev = dev; + rdev->sched_scan_req->wiphy = &rdev->wiphy; + + nl80211_send_sched_scan(rdev, dev, + NL80211_CMD_START_SCHED_SCAN); + return 0; + +out_free: + kfree(rdev->sched_scan_req); +out_err: + rdev->sched_scan_req = NULL; return err; } -- GitLab From 8cd4d4563ef0a518002c4a8f47dd950afe386ea8 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 17 Sep 2014 11:55:28 +0300 Subject: [PATCH 5323/9457] cfg80211: add wowlan net-detect support Add a new WoWLAN API to enable net-detect as a wake up trigger. Net-detect allows the device to scan in the background while the host is asleep to wake up the host system when a matching network is found. Reuse the scheduled scan attributes to specify how the scan is performed while suspended and the matches that will trigger a wake event. Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 41 +++++++++++++ include/uapi/linux/nl80211.h | 23 ++++++++ net/wireless/core.h | 1 + net/wireless/nl80211.c | 111 ++++++++++++++++++++++++++++++++++- 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8d04dfef32bf..05aae22e92a5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1940,6 +1940,7 @@ struct cfg80211_wowlan_tcp { * @rfkill_release: wake up when rfkill is released * @tcp: TCP connection establishment/wakeup parameters, see nl80211.h. * NULL if not configured. + * @nd_config: configuration for the scan to be used for net detect wake. */ struct cfg80211_wowlan { bool any, disconnect, magic_pkt, gtk_rekey_failure, @@ -1948,6 +1949,7 @@ struct cfg80211_wowlan { struct cfg80211_pkt_pattern *patterns; struct cfg80211_wowlan_tcp *tcp; int n_patterns; + struct cfg80211_sched_scan_request *nd_config; }; /** @@ -1979,6 +1981,35 @@ struct cfg80211_coalesce { int n_rules; }; +/** + * struct cfg80211_wowlan_nd_match - information about the match + * + * @ssid: SSID of the match that triggered the wake up + * @n_channels: Number of channels where the match occurred. This + * value may be zero if the driver can't report the channels. + * @channels: center frequencies of the channels where a match + * occurred (in MHz) + */ +struct cfg80211_wowlan_nd_match { + struct cfg80211_ssid ssid; + int n_channels; + u32 channels[]; +}; + +/** + * struct cfg80211_wowlan_nd_info - net detect wake up information + * + * @n_matches: Number of match information instances provided in + * @matches. This value may be zero if the driver can't provide + * match information. + * @matches: Array of pointers to matches containing information about + * the matches that triggered the wake up. + */ +struct cfg80211_wowlan_nd_info { + int n_matches; + struct cfg80211_wowlan_nd_match *matches[]; +}; + /** * struct cfg80211_wowlan_wakeup - wakeup report * @disconnect: woke up by getting disconnected @@ -1998,6 +2029,7 @@ struct cfg80211_coalesce { * @tcp_match: TCP wakeup packet received * @tcp_connlost: TCP connection lost or failed to establish * @tcp_nomoretokens: TCP data ran out of tokens + * @net_detect: if not %NULL, woke up because of net detect */ struct cfg80211_wowlan_wakeup { bool disconnect, magic_pkt, gtk_rekey_failure, @@ -2007,6 +2039,7 @@ struct cfg80211_wowlan_wakeup { s32 pattern_idx; u32 packet_present_len, packet_len; const void *packet; + struct cfg80211_wowlan_nd_info *net_detect; }; /** @@ -2810,6 +2843,7 @@ struct ieee80211_txrx_stypes { * @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request * @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure * @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release + * @WIPHY_WOWLAN_NET_DETECT: supports wakeup on network detection */ enum wiphy_wowlan_support_flags { WIPHY_WOWLAN_ANY = BIT(0), @@ -2820,6 +2854,7 @@ enum wiphy_wowlan_support_flags { WIPHY_WOWLAN_EAP_IDENTITY_REQ = BIT(5), WIPHY_WOWLAN_4WAY_HANDSHAKE = BIT(6), WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), + WIPHY_WOWLAN_NET_DETECT = BIT(8), }; struct wiphy_wowlan_tcp_support { @@ -2838,6 +2873,11 @@ struct wiphy_wowlan_tcp_support { * @pattern_max_len: maximum length of each pattern * @pattern_min_len: minimum length of each pattern * @max_pkt_offset: maximum Rx packet offset + * @max_nd_match_sets: maximum number of matchsets for net-detect, + * similar, but not necessarily identical, to max_match_sets for + * scheduled scans. + * See &struct cfg80211_sched_scan_request.@match_sets for more + * details. * @tcp: TCP wakeup support information */ struct wiphy_wowlan_support { @@ -2846,6 +2886,7 @@ struct wiphy_wowlan_support { int pattern_max_len; int pattern_min_len; int max_pkt_offset; + int max_nd_match_sets; const struct wiphy_wowlan_tcp_support *tcp; }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 365db67ca71d..d23208194e3c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1686,6 +1686,7 @@ enum nl80211_commands { * * @NL80211_ATTR_OPER_CLASS: operating class * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -2043,6 +2044,7 @@ enum nl80211_attrs { /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, + NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST, NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 }; @@ -3610,6 +3612,25 @@ struct nl80211_pattern_support { * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only, * the TCP connection ran out of tokens to use for data to send to the * service + * @NL80211_WOWLAN_TRIG_NET_DETECT: wake up when a configured network + * is detected. This is a nested attribute that contains the + * same attributes used with @NL80211_CMD_START_SCHED_SCAN. It + * specifies how the scan is performed (e.g. the interval and the + * channels to scan) as well as the scan results that will + * trigger a wake (i.e. the matchsets). + * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute + * containing an array with information about what triggered the + * wake up. If no elements are present in the array, it means + * that the information is not available. If more than one + * element is present, it means that more than one match + * occurred. + * Each element in the array is a nested attribute that contains + * one optional %NL80211_ATTR_SSID attribute and one optional + * %NL80211_ATTR_SCAN_FREQUENCIES attribute. At least one of + * these attributes must be present. If + * %NL80211_ATTR_SCAN_FREQUENCIES contains more than one + * frequency, it means that the match occurred in more than one + * channel. * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number * @@ -3635,6 +3656,8 @@ enum nl80211_wowlan_triggers { NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST, NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS, + NL80211_WOWLAN_TRIG_NET_DETECT, + NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, /* keep last */ NUM_NL80211_WOWLAN_TRIG, diff --git a/net/wireless/core.h b/net/wireless/core.h index 61ee664cf2bd..faa5b1609aae 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -111,6 +111,7 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) rdev->wiphy.wowlan_config->tcp->sock) sock_release(rdev->wiphy.wowlan_config->tcp->sock); kfree(rdev->wiphy.wowlan_config->tcp); + kfree(rdev->wiphy.wowlan_config->nd_config); kfree(rdev->wiphy.wowlan_config); #endif } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 03a302b884fd..3ec7dc557960 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -209,7 +209,7 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) } /* policy for the attributes */ -static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { +static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, .len = 20-1 }, @@ -428,6 +428,7 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED }, + [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED }, }; static const struct nla_policy @@ -1088,6 +1089,8 @@ static int nl80211_send_wowlan(struct sk_buff *msg, if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) return -ENOBUFS; + /* TODO: send wowlan net detect */ + nla_nest_end(msg, nl_wowlan); return 0; @@ -8695,6 +8698,39 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev, return 0; } +static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev, + const struct wiphy_wowlan_support *wowlan, + struct nlattr *attr, + struct cfg80211_wowlan *trig) +{ + struct nlattr **tb; + int err; + + tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL); + if (!tb) + return -ENOMEM; + + if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) { + err = -EOPNOTSUPP; + goto out; + } + + err = nla_parse(tb, NL80211_ATTR_MAX, + nla_data(attr), nla_len(attr), + nl80211_policy); + if (err) + goto out; + + trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, tb); + err = PTR_ERR_OR_ZERO(trig->nd_config); + if (err) + trig->nd_config = NULL; + +out: + kfree(tb); + return err; +} + static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -8840,6 +8876,14 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) goto error; } + if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) { + err = nl80211_parse_wowlan_nd( + rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT], + &new_triggers); + if (err) + goto error; + } + ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); if (!ntrig) { err = -ENOMEM; @@ -12082,6 +12126,67 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, EXPORT_SYMBOL(cfg80211_report_obss_beacon); #ifdef CONFIG_PM +static int cfg80211_net_detect_results(struct sk_buff *msg, + struct cfg80211_wowlan_wakeup *wakeup) +{ + struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect; + struct nlattr *nl_results, *nl_match, *nl_freqs; + int i, j; + + nl_results = nla_nest_start( + msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS); + if (!nl_results) + return -EMSGSIZE; + + for (i = 0; i < nd->n_matches; i++) { + struct cfg80211_wowlan_nd_match *match = nd->matches[i]; + + nl_match = nla_nest_start(msg, i); + if (!nl_match) + break; + + /* The SSID attribute is optional in nl80211, but for + * simplicity reasons it's always present in the + * cfg80211 structure. If a driver can't pass the + * SSID, that needs to be changed. A zero length SSID + * is still a valid SSID (wildcard), so it cannot be + * used for this purpose. + */ + if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len, + match->ssid.ssid)) { + nla_nest_cancel(msg, nl_match); + goto out; + } + + if (match->n_channels) { + nl_freqs = nla_nest_start( + msg, NL80211_ATTR_SCAN_FREQUENCIES); + if (!nl_freqs) { + nla_nest_cancel(msg, nl_match); + goto out; + } + + for (j = 0; j < match->n_channels; j++) { + if (nla_put_u32(msg, + NL80211_ATTR_WIPHY_FREQ, + match->channels[j])) { + nla_nest_cancel(msg, nl_freqs); + nla_nest_cancel(msg, nl_match); + goto out; + } + } + + nla_nest_end(msg, nl_freqs); + } + + nla_nest_end(msg, nl_match); + } + +out: + nla_nest_end(msg, nl_results); + return 0; +} + void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, struct cfg80211_wowlan_wakeup *wakeup, gfp_t gfp) @@ -12176,6 +12281,10 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, goto free_msg; } + if (wakeup->net_detect && + cfg80211_net_detect_results(msg, wakeup)) + goto free_msg; + nla_nest_end(msg, reasons); } -- GitLab From ff5db4392c75e005882dd93641b2caa436437dd6 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 12 Nov 2014 10:08:29 +0200 Subject: [PATCH 5324/9457] mac80211: remove redundant check local->scan_req was tested in the previous line, so it can't be NULL. Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg --- net/mac80211/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index af0d094b2f2f..d23c8d90c3b4 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -799,7 +799,7 @@ void ieee80211_scan_work(struct work_struct *work) if (!sdata || !local->scan_req) goto out; - if (local->scan_req && !local->scanning) { + if (!local->scanning) { struct cfg80211_scan_request *req = local->scan_req; int rc; -- GitLab From ad2b26abc157460ca6fac1a53a2bfeade283adfa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Jun 2014 21:39:05 +0200 Subject: [PATCH 5325/9457] cfg80211: allow drivers to support random MAC addresses for scan Add the necessary feature flags and a scan flag to support using random MAC addresses for scan while unassociated. The configuration for this supports an arbitrary MAC address value and mask, so that any kind of configuration (e.g. fixed OUI or full 46-bit random) can be requested. Full 46-bit random is the default when no other configuration is passed. Also add a small helper function to use the addr/mask correctly. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 25 +++++++++++ include/uapi/linux/nl80211.h | 29 ++++++++++++ net/wireless/nl80211.c | 86 ++++++++++++++++++++++++++++++++++-- 3 files changed, 137 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 05aae22e92a5..bb748c4da5af 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1437,6 +1437,10 @@ struct cfg80211_ssid { * @aborted: (internal) scan request was notified as aborted * @notified: (internal) scan request was notified as done or aborted * @no_cck: used to send probe requests at non CCK rate in 2GHz band + * @mac_addr: MAC address used with randomisation + * @mac_addr_mask: MAC address mask used with randomisation, bits that + * are 0 in the mask should be randomised, bits that are 1 should + * be taken from the @mac_addr */ struct cfg80211_scan_request { struct cfg80211_ssid *ssids; @@ -1451,6 +1455,9 @@ struct cfg80211_scan_request { struct wireless_dev *wdev; + u8 mac_addr[ETH_ALEN] __aligned(2); + u8 mac_addr_mask[ETH_ALEN] __aligned(2); + /* internal */ struct wiphy *wiphy; unsigned long scan_start; @@ -1461,6 +1468,17 @@ struct cfg80211_scan_request { struct ieee80211_channel *channels[0]; }; +static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask) +{ + int i; + + get_random_bytes(buf, ETH_ALEN); + for (i = 0; i < ETH_ALEN; i++) { + buf[i] &= ~mask[i]; + buf[i] |= addr[i] & mask[i]; + } +} + /** * struct cfg80211_match_set - sets of attributes to match * @@ -1494,6 +1512,10 @@ struct cfg80211_match_set { * @channels: channels to scan * @min_rssi_thold: for drivers only supporting a single threshold, this * contains the minimum over all matchsets + * @mac_addr: MAC address used with randomisation + * @mac_addr_mask: MAC address mask used with randomisation, bits that + * are 0 in the mask should be randomised, bits that are 1 should + * be taken from the @mac_addr */ struct cfg80211_sched_scan_request { struct cfg80211_ssid *ssids; @@ -1508,6 +1530,9 @@ struct cfg80211_sched_scan_request { int n_match_sets; s32 min_rssi_thold; + u8 mac_addr[ETH_ALEN] __aligned(2); + u8 mac_addr_mask[ETH_ALEN] __aligned(2); + /* internal */ struct wiphy *wiphy; struct net_device *dev; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d23208194e3c..a99081efc2d4 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1686,6 +1686,8 @@ enum nl80211_commands { * * @NL80211_ATTR_OPER_CLASS: operating class * + * @NL80211_ATTR_MAC_MASK: MAC address mask + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2041,6 +2043,8 @@ enum nl80211_attrs { NL80211_ATTR_OPER_CLASS, + NL80211_ATTR_MAC_MASK, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -4139,6 +4143,18 @@ enum nl80211_ap_sme_features { * See 'macaddr' field in the vif_params (cfg80211.h). * @NL80211_FEATURE_TDLS_CHANNEL_SWITCH: Driver supports channel switching when * operating as a TDLS peer. + * @NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address during scan (if the device is unassociated); the + * %NL80211_SCAN_FLAG_RANDOM_ADDR flag may be set for scans and the MAC + * address mask/value will be used. + * @NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR: This device/driver supports + * using a random MAC address for every scan iteration during scheduled + * scan (while not associated), the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. + * @NL80211_FEATURE_ND_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address for every scan iteration during "net detect", i.e. + * scan in unassociated WoWLAN, the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -4170,6 +4186,9 @@ enum nl80211_feature_flags { NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 1 << 28, + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR = 1 << 29, + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR = 1 << 30, + NL80211_FEATURE_ND_RANDOM_MAC_ADDR = 1 << 31, }; /** @@ -4218,11 +4237,21 @@ enum nl80211_connect_failed_reason { * dangerous because will destroy stations performance as a lot of frames * will be lost while scanning off-channel, therefore it must be used only * when really needed + * @NL80211_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (or + * for scheduled scan: a different one for every scan iteration). When the + * flag is set, depending on device capabilities the @NL80211_ATTR_MAC and + * @NL80211_ATTR_MAC_MASK attributes may also be given in which case only + * the masked bits will be preserved from the MAC address and the remainder + * randomised. If the attributes are not given full randomisation (46 bits, + * locally administered 1, multicast 0) is assumed. + * This flag must not be requested when the feature isn't supported, check + * the nl80211 feature flags for the device. */ enum nl80211_scan_flags { NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, NL80211_SCAN_FLAG_FLUSH = 1<<1, NL80211_SCAN_FLAG_AP = 1<<2, + NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3, }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 3ec7dc557960..dd5a827f9cb0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -395,6 +395,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, + [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, }; /* policy for the key attributes */ @@ -5481,6 +5482,43 @@ static int validate_scan_freqs(struct nlattr *freqs) return n_channels; } +static int nl80211_parse_random_mac(struct nlattr **attrs, + u8 *mac_addr, u8 *mac_addr_mask) +{ + int i; + + if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) { + memset(mac_addr, 0, ETH_ALEN); + memset(mac_addr_mask, 0, ETH_ALEN); + mac_addr[0] = 0x2; + mac_addr_mask[0] = 0x3; + + return 0; + } + + /* need both or none */ + if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK]) + return -EINVAL; + + memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN); + memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN); + + /* don't allow or configure an mcast address */ + if (!is_multicast_ether_addr(mac_addr_mask) || + is_multicast_ether_addr(mac_addr)) + return -EINVAL; + + /* + * allow users to pass a MAC address that has bits set outside + * of the mask, but don't bother drivers with having to deal + * with such bits + */ + for (i = 0; i < ETH_ALEN; i++) + mac_addr[i] &= mac_addr_mask[i]; + + return 0; +} + static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -5658,6 +5696,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) err = -EOPNOTSUPP; goto out_free; } + + if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + if (!(wiphy->features & + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) { + err = -EOPNOTSUPP; + goto out_free; + } + + if (wdev->current_bss) { + err = -EOPNOTSUPP; + goto out_free; + } + + err = nl80211_parse_random_mac(info->attrs, + request->mac_addr, + request->mac_addr_mask); + if (err) + goto out_free; + } } request->no_cck = @@ -5685,7 +5742,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) } static struct cfg80211_sched_scan_request * -nl80211_parse_sched_scan(struct wiphy *wiphy, +nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev, struct nlattr **attrs) { struct cfg80211_sched_scan_request *request; @@ -5934,6 +5991,28 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, err = -EOPNOTSUPP; goto out_free; } + + if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; + + if (!wdev) /* must be net-detect */ + flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR; + + if (!(wiphy->features & flg)) { + err = -EOPNOTSUPP; + goto out_free; + } + + if (wdev && wdev->current_bss) { + err = -EOPNOTSUPP; + goto out_free; + } + + err = nl80211_parse_random_mac(attrs, request->mac_addr, + request->mac_addr_mask); + if (err) + goto out_free; + } } request->interval = interval; @@ -5951,6 +6030,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; int err; if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || @@ -5960,7 +6040,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (rdev->sched_scan_req) return -EINPROGRESS; - rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, + rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, info->attrs); err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); if (err) @@ -8721,7 +8801,7 @@ static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev, if (err) goto out; - trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, tb); + trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb); err = PTR_ERR_OR_ZERO(trig->nd_config); if (err) trig->nd_config = NULL; -- GitLab From 6ea0a69ca21bbddab5b3979c2190013b0263e749 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Nov 2014 11:55:49 +0100 Subject: [PATCH 5326/9457] mac80211: rcu-ify scan and scheduled scan request pointers In order to use the scan and scheduled scan request pointers during RX to check for randomisation, make them accessible using RCU. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 4 +- net/mac80211/scan.c | 79 +++++++++++++++++++++++--------------- net/mac80211/util.c | 7 +++- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 34168c21bf06..dd27180060b9 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1238,7 +1238,7 @@ struct ieee80211_local { unsigned long scanning; struct cfg80211_ssid scan_ssid; struct cfg80211_scan_request *int_scan_req; - struct cfg80211_scan_request *scan_req; + struct cfg80211_scan_request __rcu *scan_req; struct ieee80211_scan_request *hw_scan_req; struct cfg80211_chan_def scan_chandef; enum ieee80211_band hw_scan_band; @@ -1248,7 +1248,7 @@ struct ieee80211_local { struct work_struct sched_scan_stopped_work; struct ieee80211_sub_if_data __rcu *sched_scan_sdata; - struct cfg80211_sched_scan_request *sched_scan_req; + struct cfg80211_sched_scan_request __rcu *sched_scan_req; unsigned long leave_oper_channel_time; enum mac80211_scan_state next_scan_state; diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d23c8d90c3b4..e75e64b8042c 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -234,11 +234,14 @@ ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef, /* return false if no more work */ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) { - struct cfg80211_scan_request *req = local->scan_req; + struct cfg80211_scan_request *req; struct cfg80211_chan_def chandef; u8 bands_used = 0; int i, ielen, n_chans; + req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); + if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) return false; @@ -290,6 +293,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) struct ieee80211_local *local = hw_to_local(hw); bool hw_scan = local->ops->hw_scan; bool was_scanning = local->scanning; + struct cfg80211_scan_request *scan_req; lockdep_assert_held(&local->mtx); @@ -322,9 +326,12 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) kfree(local->hw_scan_req); local->hw_scan_req = NULL; - if (local->scan_req != local->int_scan_req) - cfg80211_scan_done(local->scan_req, aborted); - local->scan_req = NULL; + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); + + if (scan_req != local->int_scan_req) + cfg80211_scan_done(scan_req, aborted); + RCU_INIT_POINTER(local->scan_req, NULL); RCU_INIT_POINTER(local->scan_sdata, NULL); local->scanning = 0; @@ -440,23 +447,26 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, { int i; struct ieee80211_sub_if_data *sdata; + struct cfg80211_scan_request *scan_req; enum ieee80211_band band = local->hw.conf.chandef.chan->band; u32 tx_flags; + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); + tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; - if (local->scan_req->no_cck) + if (scan_req->no_cck) tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE; sdata = rcu_dereference_protected(local->scan_sdata, lockdep_is_held(&local->mtx)); - for (i = 0; i < local->scan_req->n_ssids; i++) + for (i = 0; i < scan_req->n_ssids; i++) ieee80211_send_probe_req( sdata, NULL, - local->scan_req->ssids[i].ssid, - local->scan_req->ssids[i].ssid_len, - local->scan_req->ie, local->scan_req->ie_len, - local->scan_req->rates[band], false, + scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, + scan_req->ie, scan_req->ie_len, + scan_req->rates[band], false, tx_flags, local->hw.conf.chandef.chan, true); /* @@ -480,7 +490,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if (!ieee80211_can_scan(local, sdata)) { /* wait for the work to finish/time out */ - local->scan_req = req; + rcu_assign_pointer(local->scan_req, req); rcu_assign_pointer(local->scan_sdata, sdata); return 0; } @@ -530,7 +540,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, */ } - local->scan_req = req; + rcu_assign_pointer(local->scan_req, req); rcu_assign_pointer(local->scan_sdata, sdata); if (local->ops->hw_scan) { @@ -558,7 +568,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if ((req->channels[0]->flags & IEEE80211_CHAN_NO_IR) || - !local->scan_req->n_ssids) { + !req->n_ssids) { next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; } else { ieee80211_scan_state_send_probe(local, &next_delay); @@ -617,6 +627,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *next_chan; enum mac80211_scan_state next_scan_state; + struct cfg80211_scan_request *scan_req; /* * check if at least one STA interface is associated, @@ -641,7 +652,10 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, } mutex_unlock(&local->iflist_mtx); - next_chan = local->scan_req->channels[local->scan_channel_idx]; + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); + + next_chan = scan_req->channels[local->scan_channel_idx]; /* * we're currently scanning a different channel, let's @@ -656,7 +670,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, local->leave_oper_channel_time + HZ / 8); if (associated && !tx_empty) { - if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) + if (scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) next_scan_state = SCAN_ABORT; else next_scan_state = SCAN_SUSPEND; @@ -677,14 +691,18 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, int skip; struct ieee80211_channel *chan; enum nl80211_bss_scan_width oper_scan_width; + struct cfg80211_scan_request *scan_req; + + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); skip = 0; - chan = local->scan_req->channels[local->scan_channel_idx]; + chan = scan_req->channels[local->scan_channel_idx]; local->scan_chandef.chan = chan; local->scan_chandef.center_freq1 = chan->center_freq; local->scan_chandef.center_freq2 = 0; - switch (local->scan_req->scan_width) { + switch (scan_req->scan_width) { case NL80211_BSS_CHAN_WIDTH_5: local->scan_chandef.width = NL80211_CHAN_WIDTH_5; break; @@ -698,7 +716,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, oper_scan_width = cfg80211_chandef_to_scan_width( &local->_oper_chandef); if (chan == local->_oper_chandef.chan && - oper_scan_width == local->scan_req->scan_width) + oper_scan_width == scan_req->scan_width) local->scan_chandef = local->_oper_chandef; else local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT; @@ -727,8 +745,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, * * In any case, it is not necessary for a passive scan. */ - if (chan->flags & IEEE80211_CHAN_NO_IR || - !local->scan_req->n_ssids) { + if (chan->flags & IEEE80211_CHAN_NO_IR || !scan_req->n_ssids) { *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; local->next_scan_state = SCAN_DECISION; return; @@ -777,6 +794,7 @@ void ieee80211_scan_work(struct work_struct *work) struct ieee80211_local *local = container_of(work, struct ieee80211_local, scan_work.work); struct ieee80211_sub_if_data *sdata; + struct cfg80211_scan_request *scan_req; unsigned long next_delay = 0; bool aborted; @@ -784,6 +802,8 @@ void ieee80211_scan_work(struct work_struct *work) sdata = rcu_dereference_protected(local->scan_sdata, lockdep_is_held(&local->mtx)); + scan_req = rcu_dereference_protected(local->scan_req, + lockdep_is_held(&local->mtx)); /* When scanning on-channel, the first-callback means completed. */ if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { @@ -796,20 +816,19 @@ void ieee80211_scan_work(struct work_struct *work) goto out_complete; } - if (!sdata || !local->scan_req) + if (!sdata || !scan_req) goto out; if (!local->scanning) { - struct cfg80211_scan_request *req = local->scan_req; int rc; - local->scan_req = NULL; + RCU_INIT_POINTER(local->scan_req, NULL); RCU_INIT_POINTER(local->scan_sdata, NULL); - rc = __ieee80211_start_scan(sdata, req); + rc = __ieee80211_start_scan(sdata, scan_req); if (rc) { /* need to complete scan in cfg80211 */ - local->scan_req = req; + rcu_assign_pointer(local->scan_req, scan_req); aborted = true; goto out_complete; } else @@ -829,7 +848,7 @@ void ieee80211_scan_work(struct work_struct *work) switch (local->next_scan_state) { case SCAN_DECISION: /* if no more bands/channels left, complete scan */ - if (local->scan_channel_idx >= local->scan_req->n_channels) { + if (local->scan_channel_idx >= scan_req->n_channels) { aborted = false; goto out_complete; } @@ -1043,7 +1062,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); if (ret == 0) { rcu_assign_pointer(local->sched_scan_sdata, sdata); - local->sched_scan_req = req; + rcu_assign_pointer(local->sched_scan_req, req); } kfree(ie); @@ -1052,7 +1071,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, if (ret) { /* Clean in case of failure after HW restart or upon resume. */ RCU_INIT_POINTER(local->sched_scan_sdata, NULL); - local->sched_scan_req = NULL; + RCU_INIT_POINTER(local->sched_scan_req, NULL); } return ret; @@ -1090,7 +1109,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) } /* We don't want to restart sched scan anymore. */ - local->sched_scan_req = NULL; + RCU_INIT_POINTER(local->sched_scan_req, NULL); if (rcu_access_pointer(local->sched_scan_sdata)) { ret = drv_sched_scan_stop(local, sdata); @@ -1125,7 +1144,7 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local) RCU_INIT_POINTER(local->sched_scan_sdata, NULL); /* If sched scan was aborted by the driver. */ - local->sched_scan_req = NULL; + RCU_INIT_POINTER(local->sched_scan_req, NULL); mutex_unlock(&local->mtx); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 745a8a9cbbb5..0ad534abc008 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1721,6 +1721,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) int res, i; bool reconfig_due_to_wowlan = false; struct ieee80211_sub_if_data *sched_scan_sdata; + struct cfg80211_sched_scan_request *sched_scan_req; bool sched_scan_stopped = false; #ifdef CONFIG_PM @@ -2011,13 +2012,15 @@ int ieee80211_reconfig(struct ieee80211_local *local) mutex_lock(&local->mtx); sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, lockdep_is_held(&local->mtx)); - if (sched_scan_sdata && local->sched_scan_req) + sched_scan_req = rcu_dereference_protected(local->sched_scan_req, + lockdep_is_held(&local->mtx)); + if (sched_scan_sdata && sched_scan_req) /* * Sched scan stopped, but we don't want to report it. Instead, * we're trying to reschedule. */ if (__ieee80211_request_sched_scan_start(sched_scan_sdata, - local->sched_scan_req)) + sched_scan_req)) sched_scan_stopped = true; mutex_unlock(&local->mtx); -- GitLab From a344d6778a98e4c19ac871f369e399e6356edcb3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Jun 2014 22:24:31 +0200 Subject: [PATCH 5327/9457] mac80211: allow drivers to support NL80211_SCAN_FLAG_RANDOM_ADDR Allow drivers to support NL80211_SCAN_FLAG_RANDOM_ADDR with software based scanning and generate a random MAC address for them for every scan request with the flag. Signed-off-by: Johannes Berg --- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 6 ++- drivers/net/wireless/ath/ath9k/channel.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 ++- drivers/net/wireless/ath/ath9k/main.c | 7 ++- drivers/net/wireless/ath/wcn36xx/main.c | 7 ++- drivers/net/wireless/b43/main.c | 7 ++- .../wireless/brcm80211/brcmsmac/mac80211_if.c | 7 ++- drivers/net/wireless/cw1200/scan.c | 2 +- drivers/net/wireless/mac80211_hwsim.c | 9 ++-- drivers/net/wireless/mwl8k.c | 7 ++- drivers/net/wireless/rt2x00/rt2x00.h | 7 ++- drivers/net/wireless/rt2x00/rt2x00mac.c | 7 ++- drivers/net/wireless/rtlwifi/core.c | 7 ++- drivers/net/wireless/ti/wl1251/main.c | 2 +- drivers/net/wireless/ti/wlcore/cmd.c | 2 +- drivers/staging/vt6656/main_usb.c | 7 ++- include/net/mac80211.h | 15 ++++-- net/mac80211/driver-ops.h | 15 +++--- net/mac80211/ieee80211_i.h | 7 ++- net/mac80211/mlme.c | 8 ++-- net/mac80211/scan.c | 48 +++++++++++++++---- net/mac80211/trace.h | 31 +++++++++--- net/mac80211/tx.c | 9 ++-- net/mac80211/util.c | 12 +++-- 24 files changed, 166 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index ab2709a43768..19eab2a69ad5 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -547,7 +547,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static void -ath5k_sw_scan_start(struct ieee80211_hw *hw) +ath5k_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct ath5k_hw *ah = hw->priv; if (!ah->assoc) @@ -556,7 +558,7 @@ ath5k_sw_scan_start(struct ieee80211_hw *hw) static void -ath5k_sw_scan_complete(struct ieee80211_hw *hw) +ath5k_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath5k_hw *ah = hw->priv; ath5k_hw_set_ledstate(ah, ah->assoc ? diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 794d52016437..206665059d66 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -963,7 +963,7 @@ static void ath_scan_send_probe(struct ath_softc *sc, struct ieee80211_tx_info *info; int band = sc->offchannel.chan.chandef.chan->band; - skb = ieee80211_probereq_get(sc->hw, vif, + skb = ieee80211_probereq_get(sc->hw, vif->addr, ssid->ssid, ssid->ssid_len, req->ie_len); if (!skb) return; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index c7d12efaa86a..92d5a6c5a225 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1691,7 +1691,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, return ret; } -static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) +static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); @@ -1705,7 +1707,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) mutex_unlock(&priv->mutex); } -static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) +static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5f16630f26ce..027ad715ffb2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2180,14 +2180,17 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) return 0; } -static void ath9k_sw_scan_start(struct ieee80211_hw *hw) +static void ath9k_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); set_bit(ATH_OP_SCANNING, &common->op_flags); } -static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) +static void ath9k_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index b71d2b33532d..267c35d1f699 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -494,7 +494,9 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw) +static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct wcn36xx *wcn = hw->priv; @@ -502,7 +504,8 @@ static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw) wcn36xx_smd_start_scan(wcn); } -static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw) +static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct wcn36xx *wcn = hw->priv; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5d4173ee55bc..47731cb0d815 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -5110,7 +5110,9 @@ static void b43_op_sta_notify(struct ieee80211_hw *hw, B43_WARN_ON(!vif || wl->vif != vif); } -static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw) +static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev; @@ -5124,7 +5126,8 @@ static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw) mutex_unlock(&wl->mutex); } -static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw) +static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 43c71bfaa474..f95b52442281 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -764,7 +764,9 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, return; } -static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct brcms_info *wl = hw->priv; spin_lock_bh(&wl->lock); @@ -773,7 +775,8 @@ static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw) return; } -static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct brcms_info *wl = hw->priv; spin_lock_bh(&wl->lock); diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c index b2fb6c632092..f2e276faca70 100644 --- a/drivers/net/wireless/cw1200/scan.c +++ b/drivers/net/wireless/cw1200/scan.c @@ -78,7 +78,7 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS) return -EINVAL; - frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0, + frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0, req->ie_len); if (!frame.skb) return -ENOMEM; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 58f11bb0896f..6daaad595ea4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1802,7 +1802,7 @@ static void hw_scan_work(struct work_struct *work) struct sk_buff *probe; probe = ieee80211_probereq_get(hwsim->hw, - hwsim->hw_scan_vif, + hwsim->hw_scan_vif->addr, req->ssids[i].ssid, req->ssids[i].ssid_len, req->ie_len); @@ -1866,7 +1866,9 @@ static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw, mutex_unlock(&hwsim->mutex); } -static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) +static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct mac80211_hwsim_data *hwsim = hw->priv; @@ -1884,7 +1886,8 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) mutex_unlock(&hwsim->mutex); } -static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) +static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct mac80211_hwsim_data *hwsim = hw->priv; diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index ef1104476bd8..b8d1e04aa9b9 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -5548,7 +5548,9 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return rc; } -static void mwl8k_sw_scan_start(struct ieee80211_hw *hw) +static void mwl8k_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct mwl8k_priv *priv = hw->priv; u8 tmp; @@ -5565,7 +5567,8 @@ static void mwl8k_sw_scan_start(struct ieee80211_hw *hw) priv->sw_scan_start = true; } -static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw) +static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct mwl8k_priv *priv = hw->priv; u8 tmp; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index d13f25cd70d5..1ff81afb672c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1437,8 +1437,11 @@ int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw); -void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw); +void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr); +void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); int rt2x00mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ad6e5a8d1e10..cb40245a0695 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -568,7 +568,9 @@ int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove); -void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) +void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct rt2x00_dev *rt2x00dev = hw->priv; set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); @@ -576,7 +578,8 @@ void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); -void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw) +void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct rt2x00_dev *rt2x00dev = hw->priv; clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index f6179bc06086..884d90526f9e 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1361,7 +1361,9 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, return 0; } -static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) +static void rtl_op_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -1396,7 +1398,8 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP_BAND0); } -static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) +static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 38234851457e..0b30a7b4d663 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -1029,7 +1029,7 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw, goto out_sleep; } - skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, + skb = ieee80211_probereq_get(wl->hw, wl->vif->addr, ssid, ssid_len, req->ie_len); if (!skb) { ret = -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index dd2e448c3e2b..b82661962d33 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -1145,7 +1145,7 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_SCAN, "build probe request band %d", band); - skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, + skb = ieee80211_probereq_get(wl->hw, vif->addr, ssid, ssid_len, ie0_len + ie1_len); if (!skb) { ret = -ENOMEM; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 2fbff907ce8a..dbc311c3dc37 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -856,7 +856,9 @@ static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return 0; } -static void vnt_sw_scan_start(struct ieee80211_hw *hw) +static void vnt_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *addr) { struct vnt_private *priv = hw->priv; @@ -865,7 +867,8 @@ static void vnt_sw_scan_start(struct ieee80211_hw *hw) vnt_update_pre_ed_threshold(priv, true); } -static void vnt_sw_scan_complete(struct ieee80211_hw *hw) +static void vnt_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct vnt_private *priv = hw->priv; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 59166a115aff..7b889e3a2647 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2622,7 +2622,9 @@ enum ieee80211_reconfig_type { * * @sw_scan_start: Notifier function that is called just before a software scan * is started. Can be NULL, if the driver doesn't need this notification. - * The callback can sleep. + * The mac_addr parameter allows supporting NL80211_SCAN_FLAG_RANDOM_ADDR, + * the driver may set the NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR flag if it + * can use this parameter. The callback can sleep. * * @sw_scan_complete: Notifier function that is called just after a * software scan finished. Can be NULL, if the driver doesn't need @@ -3016,8 +3018,11 @@ struct ieee80211_ops { struct ieee80211_scan_ies *ies); int (*sched_scan_stop)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); - void (*sw_scan_start)(struct ieee80211_hw *hw); - void (*sw_scan_complete)(struct ieee80211_hw *hw); + void (*sw_scan_start)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr); + void (*sw_scan_complete)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); int (*get_stats)(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx, @@ -3820,7 +3825,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, /** * ieee80211_probereq_get - retrieve a Probe Request template * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @src_addr: source MAC address * @ssid: SSID buffer * @ssid_len: length of SSID * @tailroom: tailroom to reserve at end of SKB for IEs @@ -3831,7 +3836,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, * Return: The Probe Request template. %NULL on error. */ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, + const u8 *src_addr, const u8 *ssid, size_t ssid_len, size_t tailroom); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ba0d2cb5df12..5f5fc3f3ee7c 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -380,23 +380,26 @@ static inline int drv_sched_scan_stop(struct ieee80211_local *local, return ret; } -static inline void drv_sw_scan_start(struct ieee80211_local *local) +static inline void drv_sw_scan_start(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + const u8 *mac_addr) { might_sleep(); - trace_drv_sw_scan_start(local); + trace_drv_sw_scan_start(local, sdata, mac_addr); if (local->ops->sw_scan_start) - local->ops->sw_scan_start(&local->hw); + local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); trace_drv_return_void(local); } -static inline void drv_sw_scan_complete(struct ieee80211_local *local) +static inline void drv_sw_scan_complete(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) { might_sleep(); - trace_drv_sw_scan_complete(local); + trace_drv_sw_scan_complete(local, sdata); if (local->ops->sw_scan_complete) - local->ops->sw_scan_complete(&local->hw); + local->ops->sw_scan_complete(&local->hw, &sdata->vif); trace_drv_return_void(local); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index dd27180060b9..cf95d033bcbf 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1249,6 +1249,7 @@ struct ieee80211_local { struct work_struct sched_scan_stopped_work; struct ieee80211_sub_if_data __rcu *sched_scan_sdata; struct cfg80211_sched_scan_request __rcu *sched_scan_req; + u8 scan_addr[ETH_ALEN]; unsigned long leave_oper_channel_time; enum mac80211_scan_state next_scan_state; @@ -1901,12 +1902,14 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, u8 bands_used, u32 *rate_masks, struct cfg80211_chan_def *chandef); struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, - u8 *dst, u32 ratemask, + const u8 *src, const u8 *dst, + u32 ratemask, struct ieee80211_channel *chan, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, bool directed); -void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, +void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, + const u8 *src, const u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u32 ratemask, bool directed, u32 tx_flags, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 45490a202d9c..d29589a09065 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2225,7 +2225,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) else ssid_len = ssid[1]; - ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, + ieee80211_send_probe_req(sdata, sdata->vif.addr, NULL, + ssid + 2, ssid_len, NULL, 0, (u32) -1, true, 0, ifmgd->associated->channel, false); rcu_read_unlock(); @@ -2328,7 +2329,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, else ssid_len = ssid[1]; - skb = ieee80211_build_probe_req(sdata, cbss->bssid, + skb = ieee80211_build_probe_req(sdata, sdata->vif.addr, cbss->bssid, (u32) -1, cbss->channel, ssid + 2, ssid_len, NULL, 0, true); @@ -3649,7 +3650,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) * Direct probe is sent to broadcast address as some APs * will not answer to direct packet in unassociated state. */ - ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], + ieee80211_send_probe_req(sdata, sdata->vif.addr, NULL, + ssidie + 2, ssidie[1], NULL, 0, (u32) -1, true, 0, auth_data->bss->channel, false); rcu_read_unlock(); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index e75e64b8042c..ae842678b629 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -184,9 +184,21 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) return; if (ieee80211_is_probe_resp(mgmt->frame_control)) { - /* ignore ProbeResp to foreign address */ - if ((!sdata1 || !ether_addr_equal(mgmt->da, sdata1->vif.addr)) && - (!sdata2 || !ether_addr_equal(mgmt->da, sdata2->vif.addr))) + struct cfg80211_scan_request *scan_req; + struct cfg80211_sched_scan_request *sched_scan_req; + + scan_req = rcu_dereference(local->scan_req); + sched_scan_req = rcu_dereference(local->sched_scan_req); + + /* ignore ProbeResp to foreign address unless scanning + * with randomised address + */ + if (!(sdata1 && + (ether_addr_equal(mgmt->da, sdata1->vif.addr) || + scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) && + !(sdata2 && + (ether_addr_equal(mgmt->da, sdata2->vif.addr) || + sched_scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))) return; elements = mgmt->u.probe_resp.variable; @@ -284,6 +296,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) bands_used, req->rates, &chandef); local->hw_scan_req->req.ie_len = ielen; local->hw_scan_req->req.no_cck = req->no_cck; + ether_addr_copy(local->hw_scan_req->req.mac_addr, req->mac_addr); + ether_addr_copy(local->hw_scan_req->req.mac_addr_mask, + req->mac_addr_mask); return true; } @@ -294,6 +309,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) bool hw_scan = local->ops->hw_scan; bool was_scanning = local->scanning; struct cfg80211_scan_request *scan_req; + struct ieee80211_sub_if_data *scan_sdata; lockdep_assert_held(&local->mtx); @@ -332,6 +348,9 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (scan_req != local->int_scan_req) cfg80211_scan_done(scan_req, aborted); RCU_INIT_POINTER(local->scan_req, NULL); + + scan_sdata = rcu_dereference_protected(local->scan_sdata, + lockdep_is_held(&local->mtx)); RCU_INIT_POINTER(local->scan_sdata, NULL); local->scanning = 0; @@ -342,7 +361,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (!hw_scan) { ieee80211_configure_filter(local); - drv_sw_scan_complete(local); + drv_sw_scan_complete(local, scan_sdata); ieee80211_offchannel_return(local); } @@ -368,7 +387,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) } EXPORT_SYMBOL(ieee80211_scan_completed); -static int ieee80211_start_sw_scan(struct ieee80211_local *local) +static int ieee80211_start_sw_scan(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) { /* Software scan is not supported in multi-channel cases */ if (local->use_chanctx) @@ -387,7 +407,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) * nullfunc frames and probe requests will be dropped in * ieee80211_tx_h_check_assoc(). */ - drv_sw_scan_start(local); + drv_sw_scan_start(local, sdata, local->scan_addr); local->leave_oper_channel_time = jiffies; local->next_scan_state = SCAN_DECISION; @@ -463,7 +483,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, for (i = 0; i < scan_req->n_ssids; i++) ieee80211_send_probe_req( - sdata, NULL, + sdata, local->scan_addr, NULL, scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, scan_req->ie, scan_req->ie_len, scan_req->rates[band], false, @@ -543,6 +563,13 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, rcu_assign_pointer(local->scan_req, req); rcu_assign_pointer(local->scan_sdata, sdata); + if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) + get_random_mask_addr(local->scan_addr, + req->mac_addr, + req->mac_addr_mask); + else + memcpy(local->scan_addr, sdata->vif.addr, ETH_ALEN); + if (local->ops->hw_scan) { __set_bit(SCAN_HW_SCANNING, &local->scanning); } else if ((req->n_channels == 1) && @@ -559,7 +586,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, /* Notify driver scan is starting, keep order of operations * same as normal software scan, in case that matters. */ - drv_sw_scan_start(local); + drv_sw_scan_start(local, sdata, local->scan_addr); ieee80211_configure_filter(local); /* accept probe-responses */ @@ -589,8 +616,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if (local->ops->hw_scan) { WARN_ON(!ieee80211_prep_hw_scan(local)); rc = drv_hw_scan(local, sdata, local->hw_scan_req); - } else - rc = ieee80211_start_sw_scan(local); + } else { + rc = ieee80211_start_sw_scan(local, sdata); + } if (rc) { kfree(local->hw_scan_req); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 7f76e2f25744..eb91505eb43e 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -596,14 +596,33 @@ DEFINE_EVENT(local_sdata_evt, drv_sched_scan_stop, TP_ARGS(local, sdata) ); -DEFINE_EVENT(local_only_evt, drv_sw_scan_start, - TP_PROTO(struct ieee80211_local *local), - TP_ARGS(local) +TRACE_EVENT(drv_sw_scan_start, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + const u8 *mac_addr), + + TP_ARGS(local, sdata, mac_addr), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __array(char, mac_addr, ETH_ALEN) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + memcpy(__entry->mac_addr, mac_addr, ETH_ALEN); + ), + + TP_printk(LOCAL_PR_FMT ", " VIF_PR_FMT ", addr:%pM", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->mac_addr) ); -DEFINE_EVENT(local_only_evt, drv_sw_scan_complete, - TP_PROTO(struct ieee80211_local *local), - TP_ARGS(local) +DEFINE_EVENT(local_sdata_evt, drv_sw_scan_complete, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata), + TP_ARGS(local, sdata) ); TRACE_EVENT(drv_get_stats, diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0cb41d1a1f20..66ddbbeccd20 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2961,19 +2961,16 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, EXPORT_SYMBOL(ieee80211_nullfunc_get); struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, + const u8 *src_addr, const u8 *ssid, size_t ssid_len, size_t tailroom) { - struct ieee80211_sub_if_data *sdata; - struct ieee80211_local *local; + struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_hdr_3addr *hdr; struct sk_buff *skb; size_t ie_ssid_len; u8 *pos; - sdata = vif_to_sdata(vif); - local = sdata->local; ie_ssid_len = 2 + ssid_len; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) + @@ -2988,7 +2985,7 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); eth_broadcast_addr(hdr->addr1); - memcpy(hdr->addr2, vif->addr, ETH_ALEN); + memcpy(hdr->addr2, src_addr, ETH_ALEN); eth_broadcast_addr(hdr->addr3); pos = skb_put(skb, ie_ssid_len); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0ad534abc008..bb9664cb8831 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1523,7 +1523,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, }; struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, - u8 *dst, u32 ratemask, + const u8 *src, const u8 *dst, + u32 ratemask, struct ieee80211_channel *chan, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, @@ -1548,8 +1549,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, else chandef.chan = chan; - skb = ieee80211_probereq_get(&local->hw, &sdata->vif, - ssid, ssid_len, 100 + ie_len); + skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len, + 100 + ie_len); if (!skb) return NULL; @@ -1571,7 +1572,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, return skb; } -void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, +void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, + const u8 *src, const u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u32 ratemask, bool directed, u32 tx_flags, @@ -1579,7 +1581,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, { struct sk_buff *skb; - skb = ieee80211_build_probe_req(sdata, dst, ratemask, channel, + skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel, ssid, ssid_len, ie, ie_len, directed); if (skb) { -- GitLab From 339467b906f599b6f3a479dffe7f5bb0241b78ac Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Jun 2014 22:41:00 +0200 Subject: [PATCH 5328/9457] mac80211_hwsim: support scanning with random MAC address This adds support for scanning with random MAC address for both software and hardware scan. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6daaad595ea4..c2303dbcb63c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -422,6 +422,7 @@ struct mac80211_hwsim_data { struct cfg80211_scan_request *hw_scan_request; struct ieee80211_vif *hw_scan_vif; int scan_chan_idx; + u8 scan_addr[ETH_ALEN]; struct ieee80211_channel *channel; u64 beacon_int /* beacon interval in us */; @@ -830,6 +831,9 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, .ret = false, }; + if (data->scanning && memcmp(addr, data->scan_addr, ETH_ALEN) == 0) + return true; + memcpy(md.addr, addr, ETH_ALEN); ieee80211_iterate_active_interfaces_atomic(data->hw, @@ -1802,7 +1806,7 @@ static void hw_scan_work(struct work_struct *work) struct sk_buff *probe; probe = ieee80211_probereq_get(hwsim->hw, - hwsim->hw_scan_vif->addr, + hwsim->scan_addr, req->ssids[i].ssid, req->ssids[i].ssid_len, req->ie_len); @@ -1840,6 +1844,12 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, hwsim->hw_scan_request = req; hwsim->hw_scan_vif = vif; hwsim->scan_chan_idx = 0; + if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) + get_random_mask_addr(hwsim->scan_addr, + hw_req->req.mac_addr, + hw_req->req.mac_addr_mask); + else + memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN); mutex_unlock(&hwsim->mutex); wiphy_debug(hw->wiphy, "hwsim hw_scan request\n"); @@ -1880,6 +1890,8 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw, } printk(KERN_DEBUG "hwsim sw_scan request, prepping stuff\n"); + + memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN); hwsim->scanning = true; out: @@ -1895,6 +1907,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw, printk(KERN_DEBUG "hwsim sw_scan_complete\n"); hwsim->scanning = false; + memset(hwsim->scan_addr, 0, ETH_ALEN); mutex_unlock(&hwsim->mutex); } @@ -2320,7 +2333,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | NL80211_FEATURE_STATIC_SMPS | - NL80211_FEATURE_DYNAMIC_SMPS; + NL80211_FEATURE_DYNAMIC_SMPS | + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; /* ask mac80211 to reserve space for magic */ hw->vif_data_size = sizeof(struct hwsim_vif_priv); -- GitLab From 8b1956f0416f10c2362532a9f87c9f1afc70347c Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 11 Nov 2014 18:11:22 +0200 Subject: [PATCH 5329/9457] mac80211: don't allow 40MHz tx rates in case of 20MHz chandef When 20MHz chandef is used, 40MHz rates shouldn't be used (by the rate-control algorithm), even if the sta ht capabilities indicate support for it. Signed-off-by: Eliad Peller Singed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/vht.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 671ce0d27a80..bc9e8fc48785 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c @@ -287,6 +287,8 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) /* fall through */ case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: + bw = IEEE80211_STA_RX_BW_20; + break; case NL80211_CHAN_WIDTH_40: bw = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; -- GitLab From 628c010f1f395459e6871e15b8dbd6f8c8045285 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 15 Nov 2014 03:48:54 +0100 Subject: [PATCH 5330/9457] mac80211: skip legacy rate mask handling for VHT rates The rate mask code currently assumes that a rate is legacy if IEEE80211_TX_RC_MCS is not set. This might be the cause of bogus VHT rates being reported with minstrel_ht. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 6081329784dd..f6fea67fcc5b 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -385,7 +385,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, *rate = alt_rate; return; } - } else { + } else if (!(rate->flags & IEEE80211_TX_RC_VHT_MCS)) { /* handle legacy rates */ if (rate_idx_match_legacy_mask(rate, sband->n_bitrates, mask)) return; -- GitLab From 2e18b38fc8fb0323804e4a7812cb1a8ea78b9dd7 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 16 Nov 2014 16:37:46 +0200 Subject: [PATCH 5331/9457] cfg80211: update missing fields in custom regulatory path Some channels fields were not being updated in the custom regulatory path. Update them according to the code in handle_channel(). Signed-off-by: Jonathan Doron Signed-off-by: Arik Nemtsov Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7449a8c0f9fd..a60f391b30a6 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1597,10 +1597,20 @@ static void handle_channel_custom(struct wiphy *wiphy, if (max_bandwidth_khz < MHZ_TO_KHZ(160)) bw_flags |= IEEE80211_CHAN_NO_160MHZ; + chan->dfs_state_entered = jiffies; chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); chan->max_reg_power = chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); + + if (chan->flags & IEEE80211_CHAN_RADAR) { + if (reg_rule->dfs_cac_ms) + chan->dfs_cac_ms = reg_rule->dfs_cac_ms; + else + chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; + } + + chan->max_power = chan->max_reg_power; } static void handle_band_custom(struct wiphy *wiphy, -- GitLab From c7ab508190aee6b4a62cfab7ee08457602468672 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 16 Nov 2014 16:37:47 +0200 Subject: [PATCH 5332/9457] cfg80211: explicitly initialize some fields in custom reg path Explicitly initialize the DFS state and beacon found state when handling channels in the custom regulatory path. Signed-off-by: Arik Nemtsov Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a60f391b30a6..32d8310b0f85 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1598,6 +1598,9 @@ static void handle_channel_custom(struct wiphy *wiphy, bw_flags |= IEEE80211_CHAN_NO_160MHZ; chan->dfs_state_entered = jiffies; + chan->dfs_state = NL80211_DFS_USABLE; + + chan->beacon_found = false; chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); chan->max_reg_power = chan->max_power = -- GitLab From 996cc8494d663cb03c5ec23ced0e09e4bcd845de Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Wed, 19 Nov 2014 15:13:27 +0530 Subject: [PATCH 5333/9457] ASoC: Intel: add BYTCR machine driver with RT5640 Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 12 ++ sound/soc/intel/Makefile | 2 + sound/soc/intel/bytcr_dpcm_rt5640.c | 230 ++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 sound/soc/intel/bytcr_dpcm_rt5640.c diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index a992e8572d89..a26e8e8bb9aa 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -86,3 +86,15 @@ config SND_SOC_INTEL_BROADWELL_MACH Ultrabook platforms. Say Y if you have such a device If unsure select "N". + +config SND_SOC_INTEL_BYTCR_RT5640_MACH + tristate "ASoC Audio DSP Support for MID BYT Platform" + depends on X86 + select SND_SOC_RT5640 + select SND_SST_MFLD_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) MID Baytrail platform + used as alsa device in audio substem in Intel(R) MID devices + Say Y if you have such a device + If unsure select "N". diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index 9ab43be75311..fbde4b07d455 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -26,11 +26,13 @@ snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o snd-soc-sst-broadwell-objs := broadwell.o +snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o +obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o # DSP driver obj-$(CONFIG_SND_SST_IPC) += sst/ diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/bytcr_dpcm_rt5640.c new file mode 100644 index 000000000000..f5d0fc1ab10c --- /dev/null +++ b/sound/soc/intel/bytcr_dpcm_rt5640.c @@ -0,0 +1,230 @@ +/* + * byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform + * + * Copyright (C) 2014 Intel Corp + * Author: Subhransu S. Prusty + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../codecs/rt5640.h" +#include "sst-atom-controls.h" + +static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static const struct snd_soc_dapm_route byt_audio_map[] = { + {"IN2P", NULL, "Headset Mic"}, + {"IN2N", NULL, "Headset Mic"}, + {"Headset Mic", NULL, "MICBIAS1"}, + {"IN1P", NULL, "MICBIAS1"}, + {"LDO2", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Ext Spk", NULL, "SPOLP"}, + {"Ext Spk", NULL, "SPOLN"}, + {"Ext Spk", NULL, "SPORP"}, + {"Ext Spk", NULL, "SPORN"}, + + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_kcontrol_new byt_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static int byt_aif1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + snd_soc_dai_set_bclk_ratio(codec_dai, 50); + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec clock %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, + params_rate(params) * 50, + params_rate(params) * 512); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct snd_soc_pcm_stream byt_dai_params = { + .formats = SNDRV_PCM_FMTBIT_S24_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, +}; + +static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - + SNDRV_PCM_HW_PARAM_FIRST_MASK], + SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + +static unsigned int rates_48000[] = { + 48000, +}; + +static struct snd_pcm_hw_constraint_list constraints_48000 = { + .count = ARRAY_SIZE(rates_48000), + .list = rates_48000, +}; + +static int byt_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_48000); +} + +static struct snd_soc_ops byt_aif1_ops = { + .startup = byt_aif1_startup, +}; + +static struct snd_soc_ops byt_be_ssp2_ops = { + .hw_params = byt_aif1_hw_params, +}; + +static struct snd_soc_dai_link byt_dailink[] = { + [MERR_DPCM_AUDIO] = { + .name = "Baytrail Audio Port", + .stream_name = "Baytrail Audio", + .cpu_dai_name = "media-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .ignore_suspend = 1, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_aif1_ops, + }, + [MERR_DPCM_COMPR] = { + .name = "Baytrail Compressed Port", + .stream_name = "Baytrail Compress", + .cpu_dai_name = "compress-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + }, + /* back ends */ + { + .name = "SSP2-Codec", + .be_id = 1, + .cpu_dai_name = "ssp2-port", + .platform_name = "sst-mfld-platform", + .no_pcm = 1, + .codec_dai_name = "rt5640-aif1", + .codec_name = "i2c-10EC5640:00", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_codec_fixup, + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_be_ssp2_ops, + }, +}; + +/* SoC card */ +static struct snd_soc_card snd_soc_card_byt = { + .name = "baytrailcraudio", + .dai_link = byt_dailink, + .num_links = ARRAY_SIZE(byt_dailink), + .dapm_widgets = byt_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(byt_dapm_widgets), + .dapm_routes = byt_audio_map, + .num_dapm_routes = ARRAY_SIZE(byt_audio_map), + .controls = byt_mc_controls, + .num_controls = ARRAY_SIZE(byt_mc_controls), +}; + +static int snd_byt_mc_probe(struct platform_device *pdev) +{ + int ret_val = 0; + + /* register the soc card */ + snd_soc_card_byt.dev = &pdev->dev; + + ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_byt); + if (ret_val) { + dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &snd_soc_card_byt); + return ret_val; +} + +static struct platform_driver snd_byt_mc_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "bytt100_rt5640", + .pm = &snd_soc_pm_ops, + }, + .probe = snd_byt_mc_probe, +}; + +module_platform_driver(snd_byt_mc_driver); + +MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); +MODULE_AUTHOR("Subhransu S. Prusty "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:bytrt5640-audio"); -- GitLab From d687cbb703f50980e155c5642cf229ec2bb45e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 14 Nov 2014 18:43:28 +0100 Subject: [PATCH 5334/9457] cfg80211: protect fools returning NULL in add_virtual_intf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Callback add_virtual_intf is supposed to return ERR_PTR and trying to return NULL results in some "Unable to handle kernel paging request", etc. As it may be complicated to debug & trace, let's catch it (WARN). Signed-off-by: Rafał Miłecki Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index dd5a827f9cb0..5cfd75dfff67 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2645,7 +2645,10 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) wdev = rdev_add_virtual_intf(rdev, nla_data(info->attrs[NL80211_ATTR_IFNAME]), type, err ? NULL : &flags, ¶ms); - if (IS_ERR(wdev)) { + if (WARN_ON(!wdev)) { + nlmsg_free(msg); + return -EPROTO; + } else if (IS_ERR(wdev)) { nlmsg_free(msg); return PTR_ERR(wdev); } -- GitLab From b9995f83c33e3ff7486da0630a979a05edf2e982 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 14 Nov 2014 13:16:34 +0200 Subject: [PATCH 5335/9457] mac80211-hwsim: hwname is always known so use the value from wiphy We can always know the hwname of the radio so use the value from wiphy. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c2303dbcb63c..bbbcc4d8bb91 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2491,12 +2491,10 @@ static void hwsim_mcast_del_radio(int id, const char *hwname, if (ret < 0) goto error; - if (hwname) { - ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(hwname), - hwname); - if (ret < 0) - goto error; - } + ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(hwname), + hwname); + if (ret < 0) + goto error; genlmsg_end(skb, data); @@ -2530,7 +2528,8 @@ static void mac80211_hwsim_free(void) list))) { list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); - mac80211_hwsim_del_radio(data, NULL, NULL); + mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), + NULL); spin_lock_bh(&hwsim_radio_lock); } spin_unlock_bh(&hwsim_radio_lock); @@ -2816,7 +2815,8 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) list_del(&data->list); spin_unlock_bh(&hwsim_radio_lock); - mac80211_hwsim_del_radio(data, hwname, info); + mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), + info); return 0; } spin_unlock_bh(&hwsim_radio_lock); @@ -2861,7 +2861,7 @@ static void destroy_radio(struct work_struct *work) struct mac80211_hwsim_data *data = container_of(work, struct mac80211_hwsim_data, destroy_work); - mac80211_hwsim_del_radio(data, NULL, NULL); + mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL); } static void remove_user_radios(u32 portid) -- GitLab From 6b67e01fc0c4f7759a3e6e75fdcf17195daa482e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Nov 2014 18:51:55 +0100 Subject: [PATCH 5336/9457] mac80211-hwsim: remove unnecessary hwname check The hwname will always be set if idx is negative (as it's a u32 read into an s64 it can't overflow either) so we can remove the unnecessary check for hwname being non-NULL. This was reported by smatch. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index bbbcc4d8bb91..c88a21acda64 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2808,8 +2808,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) if (data->idx != idx) continue; } else { - if (hwname && - strcmp(hwname, wiphy_name(data->hw->wiphy))) + if (strcmp(hwname, wiphy_name(data->hw->wiphy))) continue; } -- GitLab From 18e5ca65e55da4cacd9deb4e934eb5429bb4b79d Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 13 Nov 2014 17:25:14 +0200 Subject: [PATCH 5337/9457] nl80211: Replace interface socket owner attribute with more generic one Replace NL80211_ATTR_IFACE_SOCKET_OWNER attribute with more generic NL80211_ATTR_SOCKET_OWNER that can be used with other commands that interface creation. Signed-off-by: Jukka Rissanen Signed-off-by: Johannes Berg --- include/uapi/linux/nl80211.h | 7 ++++--- net/wireless/nl80211.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index a99081efc2d4..d77524510435 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1652,9 +1652,9 @@ enum nl80211_commands { * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. * As specified in the &enum nl80211_tdls_peer_capability. * - * @NL80211_ATTR_IFACE_SOCKET_OWNER: flag attribute, if set during interface + * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface * creation then the new interface will be owned by the netlink socket - * that created it and will be destroyed when the socket is closed + * that created it and will be destroyed when the socket is closed. * * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is * the TDLS link initiator. @@ -2024,7 +2024,7 @@ enum nl80211_attrs { NL80211_ATTR_TDLS_PEER_CAPABILITY, - NL80211_ATTR_IFACE_SOCKET_OWNER, + NL80211_ATTR_SOCKET_OWNER, NL80211_ATTR_CSA_C_OFFSETS_TX, NL80211_ATTR_MAX_CSA_COUNTERS, @@ -2055,6 +2055,7 @@ enum nl80211_attrs { /* source-level API compatibility */ #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG +#define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER /* * Allow user space programs to use #ifdef on new attributes by defining them diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5cfd75dfff67..c81491b1f737 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -388,7 +388,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, - [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, + [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG }, [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG }, [NL80211_ATTR_TSID] = { .type = NLA_U8 }, @@ -2653,7 +2653,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return PTR_ERR(wdev); } - if (info->attrs[NL80211_ATTR_IFACE_SOCKET_OWNER]) + if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) wdev->owner_nlportid = info->snd_portid; switch (type) { -- GitLab From 86619e7ba3991309b88969f9a2e5c7f2d014c680 Mon Sep 17 00:00:00 2001 From: Nicholas Krause Date: Wed, 19 Nov 2014 07:48:18 -0500 Subject: [PATCH 5338/9457] KVM: x86: Remove FIXMEs in emulate.c Remove FIXME comments about needing fault addresses to be returned. These are propaagated from walk_addr_generic to gva_to_gpa and from there to ops->read_std and ops->write_std. Signed-off-by: Nicholas Krause Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f62209e7ad84..6a57157675ad 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2595,7 +2595,6 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, &ctxt->exception); if (ret != X86EMUL_CONTINUE) - /* FIXME: need to provide precise fault address */ return ret; save_state_to_tss16(ctxt, &tss_seg); @@ -2603,13 +2602,11 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, &ctxt->exception); if (ret != X86EMUL_CONTINUE) - /* FIXME: need to provide precise fault address */ return ret; ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, &ctxt->exception); if (ret != X86EMUL_CONTINUE) - /* FIXME: need to provide precise fault address */ return ret; if (old_tss_sel != 0xffff) { @@ -2620,7 +2617,6 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, sizeof tss_seg.prev_task_link, &ctxt->exception); if (ret != X86EMUL_CONTINUE) - /* FIXME: need to provide precise fault address */ return ret; } -- GitLab From 986cdb862e4aafc92a1537e04388898fc42b8bc0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Sep 2014 17:38:59 -0400 Subject: [PATCH 5339/9457] gfs2: bugger off early if O_CREAT open finds a directory Signed-off-by: Al Viro --- fs/gfs2/inode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c4ed823d150e..310e2487239d 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -624,6 +624,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = gfs2_dir_search(dir, &dentry->d_name, !S_ISREG(mode) || excl); error = PTR_ERR(inode); if (!IS_ERR(inode)) { + if (S_ISDIR(inode->i_mode)) { + iput(inode); + inode = ERR_PTR(-EISDIR); + goto fail_gunlock; + } d = d_splice_alias(inode, dentry); error = PTR_ERR(d); if (IS_ERR(d)) { -- GitLab From 81295ce635a83f052497656348e9edc794b4cae6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Sep 2014 17:42:35 -0400 Subject: [PATCH 5340/9457] gfs2_create_inode(): don't bother with d_splice_alias() dentry is always hashed and negative, inode - non-error, non-NULL and non-directory. In such conditions d_splice_alias() is equivalent to "d_instantiate(dentry, inode) and return NULL", which simplifies the downstream code and is consistent with the "have to create a new object" case. Signed-off-by: Al Viro --- fs/gfs2/inode.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 310e2487239d..ce0cf9ad5f97 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -596,7 +596,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, struct gfs2_inode *dip = GFS2_I(dir), *ip; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_glock *io_gl; - struct dentry *d; int error, free_vfs_inode = 0; u32 aflags = 0; unsigned blocks = 1; @@ -629,22 +628,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = ERR_PTR(-EISDIR); goto fail_gunlock; } - d = d_splice_alias(inode, dentry); - error = PTR_ERR(d); - if (IS_ERR(d)) { - inode = ERR_CAST(d); - goto fail_gunlock; - } + d_instantiate(dentry, inode); error = 0; if (file) { - if (S_ISREG(inode->i_mode)) { - WARN_ON(d != NULL); + if (S_ISREG(inode->i_mode)) error = finish_open(file, dentry, gfs2_open_common, opened); - } else { - error = finish_no_open(file, d); - } - } else { - dput(d); + else + error = finish_no_open(file, NULL); } gfs2_glock_dq_uninit(ghs); return error; -- GitLab From 845409b49bcc8fe2ad9f1a948cc4f54c301b742d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 18 Nov 2014 21:10:23 -0500 Subject: [PATCH 5341/9457] gfs2_atomic_open(): simplify the use of finish_no_open() In ->atomic_open(inode, dentry, file, opened) calling finish_no_open(file, NULL) is equivalent to dget(dentry); return finish_no_open(file, dentry); No need to open-code that... Signed-off-by: Al Viro --- fs/gfs2/inode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index ce0cf9ad5f97..6e2917433170 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1249,11 +1249,8 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, if (d != NULL) dentry = d; if (dentry->d_inode) { - if (!(*opened & FILE_OPENED)) { - if (d == NULL) - dget(dentry); - return finish_no_open(file, dentry); - } + if (!(*opened & FILE_OPENED)) + return finish_no_open(file, d); dput(d); return 0; } -- GitLab From c449981c4761f16d57db70834bee0380c7c97f18 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Wed, 12 Nov 2014 16:42:39 +0200 Subject: [PATCH 5342/9457] mac80211-hwsim: Factor out netlink attribute appending Factor out netlink message attribute appending in order to reuse it with later code. As a result move netlink skb allocation to the calling function. Signed-off-by: Patrik Flykt Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c88a21acda64..3cb825b3ef17 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2123,36 +2123,26 @@ static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb, HWSIM_MCGRP_CONFIG, GFP_KERNEL); } -static struct sk_buff *build_radio_msg(int cmd, int id, - struct hwsim_new_radio_params *param) +static int append_radio_msg(struct sk_buff *skb, int id, + struct hwsim_new_radio_params *param) { - struct sk_buff *skb; - void *data; int ret; - skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!skb) - return NULL; - - data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, cmd); - if (!data) - goto error; - ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id); if (ret < 0) - goto error; + return ret; if (param->channels) { ret = nla_put_u32(skb, HWSIM_ATTR_CHANNELS, param->channels); if (ret < 0) - goto error; + return ret; } if (param->reg_alpha2) { ret = nla_put(skb, HWSIM_ATTR_REG_HINT_ALPHA2, 2, param->reg_alpha2); if (ret < 0) - goto error; + return ret; } if (param->regd) { @@ -2165,54 +2155,64 @@ static struct sk_buff *build_radio_msg(int cmd, int id, if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) { ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); if (ret < 0) - goto error; + return ret; } } if (param->reg_strict) { ret = nla_put_flag(skb, HWSIM_ATTR_REG_STRICT_REG); if (ret < 0) - goto error; + return ret; } if (param->p2p_device) { ret = nla_put_flag(skb, HWSIM_ATTR_SUPPORT_P2P_DEVICE); if (ret < 0) - goto error; + return ret; } if (param->use_chanctx) { ret = nla_put_flag(skb, HWSIM_ATTR_USE_CHANCTX); if (ret < 0) - goto error; + return ret; } if (param->hwname) { ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(param->hwname), param->hwname); if (ret < 0) - goto error; + return ret; } - genlmsg_end(skb, data); - - return skb; - -error: - nlmsg_free(skb); - return NULL; + return 0; } -static void hswim_mcast_new_radio(int id, struct genl_info *info, +static void hwsim_mcast_new_radio(int id, struct genl_info *info, struct hwsim_new_radio_params *param) { struct sk_buff *mcast_skb; + void *data; - mcast_skb = build_radio_msg(HWSIM_CMD_NEW_RADIO, id, param); + mcast_skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!mcast_skb) return; + data = genlmsg_put(mcast_skb, 0, 0, &hwsim_genl_family, 0, + HWSIM_CMD_NEW_RADIO); + if (!data) + goto out_err; + + if (append_radio_msg(mcast_skb, id, param) < 0) + goto out_err; + + genlmsg_end(mcast_skb, data); + hwsim_mcast_config_msg(mcast_skb, info); + return; + +out_err: + genlmsg_cancel(mcast_skb, data); + nlmsg_free(mcast_skb); } static int mac80211_hwsim_new_radio(struct genl_info *info, @@ -2459,7 +2459,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, spin_unlock_bh(&hwsim_radio_lock); if (idx > 0) - hswim_mcast_new_radio(idx, info, param); + hwsim_mcast_new_radio(idx, info, param); return idx; -- GitLab From 93d638d49cac96a93abf09bb3526f2112d9f8387 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Wed, 12 Nov 2014 16:42:40 +0200 Subject: [PATCH 5343/9457] mac80211-hwsim: Add HWSIM_CMD_GET_RADIO command HWSIM_CMD_GET_RADIO returns information about a specific radio id or all of them in response to a dump. Create the netlink skb or use the one provided by the dump functionality. Use the existing attribute appending function to fill in the same attributes when creating a new hwsim radio. Save alpha2 and struct ieee80211_regdomain in the hwsim data or else they will be lost in the depths of regulatory infrastructure. Signed-off-by: Patrik Flykt Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 123 +++++++++++++++++++++++++- drivers/net/wireless/mac80211_hwsim.h | 3 + 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 3cb825b3ef17..e23a8d14578a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -415,6 +415,8 @@ struct mac80211_hwsim_data { bool destroy_on_close; struct work_struct destroy_work; u32 portid; + char alpha2[2]; + const struct ieee80211_regdomain *regd; struct ieee80211_channel *tmp_chan; struct delayed_work roc_done; @@ -2420,6 +2422,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, if (param->reg_strict) hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; if (param->regd) { + data->regd = param->regd; hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy_apply_custom_regulatory(hw->wiphy, param->regd); /* give the regulatory workqueue a chance to run */ @@ -2438,8 +2441,11 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); - if (param->reg_alpha2) + if (param->reg_alpha2) { + data->alpha2[0] = param->reg_alpha2[0]; + data->alpha2[1] = param->reg_alpha2[1]; regulatory_hint(hw->wiphy, param->reg_alpha2); + } data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); @@ -2518,6 +2524,44 @@ static void mac80211_hwsim_del_radio(struct mac80211_hwsim_data *data, ieee80211_free_hw(data->hw); } +static int mac80211_hwsim_get_radio(struct sk_buff *skb, + struct mac80211_hwsim_data *data, + u32 portid, u32 seq, + struct netlink_callback *cb, int flags) +{ + void *hdr; + struct hwsim_new_radio_params param = { }; + int res = -EMSGSIZE; + + hdr = genlmsg_put(skb, portid, seq, &hwsim_genl_family, flags, + HWSIM_CMD_GET_RADIO); + if (!hdr) + return -EMSGSIZE; + + if (cb) + genl_dump_check_consistent(cb, hdr, &hwsim_genl_family); + + param.reg_alpha2 = data->alpha2; + param.reg_strict = !!(data->hw->wiphy->regulatory_flags & + REGULATORY_STRICT_REG); + param.p2p_device = !!(data->hw->wiphy->interface_modes & + BIT(NL80211_IFTYPE_P2P_DEVICE)); + param.use_chanctx = data->use_chanctx; + param.regd = data->regd; + param.channels = data->channels; + param.hwname = wiphy_name(data->hw->wiphy); + + res = append_radio_msg(skb, data->idx, ¶m); + if (res < 0) + goto out_err; + + return genlmsg_end(skb, hdr); + +out_err: + genlmsg_cancel(skb, hdr); + return res; +} + static void mac80211_hwsim_free(void) { struct mac80211_hwsim_data *data; @@ -2823,6 +2867,77 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) return -ENODEV; } +static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) +{ + struct mac80211_hwsim_data *data; + struct sk_buff *skb; + int idx, res = -ENODEV; + + if (!info->attrs[HWSIM_ATTR_RADIO_ID]) + return -EINVAL; + idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); + + spin_lock_bh(&hwsim_radio_lock); + list_for_each_entry(data, &hwsim_radios, list) { + if (data->idx != idx) + continue; + + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) { + res = -ENOMEM; + goto out_err; + } + + res = mac80211_hwsim_get_radio(skb, data, info->snd_portid, + info->snd_seq, NULL, 0); + if (res < 0) { + nlmsg_free(skb); + goto out_err; + } + + genlmsg_reply(skb, info); + break; + } + +out_err: + spin_unlock_bh(&hwsim_radio_lock); + + return res; +} + +static int hwsim_dump_radio_nl(struct sk_buff *skb, + struct netlink_callback *cb) +{ + int idx = cb->args[0]; + struct mac80211_hwsim_data *data = NULL; + int res; + + spin_lock_bh(&hwsim_radio_lock); + + if (idx == hwsim_radio_idx) + goto done; + + list_for_each_entry(data, &hwsim_radios, list) { + if (data->idx < idx) + continue; + + res = mac80211_hwsim_get_radio(skb, data, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, cb, + NLM_F_MULTI); + if (res < 0) + break; + + idx = data->idx + 1; + } + + cb->args[0] = idx; + +done: + spin_unlock_bh(&hwsim_radio_lock); + return skb->len; +} + /* Generic Netlink operations array */ static const struct genl_ops hwsim_ops[] = { { @@ -2853,6 +2968,12 @@ static const struct genl_ops hwsim_ops[] = { .doit = hwsim_del_radio_nl, .flags = GENL_ADMIN_PERM, }, + { + .cmd = HWSIM_CMD_GET_RADIO, + .policy = hwsim_genl_policy, + .doit = hwsim_get_radio_nl, + .dumpit = hwsim_dump_radio_nl, + }, }; static void destroy_radio(struct work_struct *work) diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h index f08debdd639b..66e1c73bd507 100644 --- a/drivers/net/wireless/mac80211_hwsim.h +++ b/drivers/net/wireless/mac80211_hwsim.h @@ -69,6 +69,8 @@ enum hwsim_tx_control_flags { * returns the radio ID (>= 0) or negative on errors, if successful * then multicast the result * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted + * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses: + * %HWSIM_ATTR_RADIO_ID * @__HWSIM_CMD_MAX: enum limit */ enum { @@ -78,6 +80,7 @@ enum { HWSIM_CMD_TX_INFO_FRAME, HWSIM_CMD_NEW_RADIO, HWSIM_CMD_DEL_RADIO, + HWSIM_CMD_GET_RADIO, __HWSIM_CMD_MAX, }; #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) -- GitLab From 427c77d4619657c483c49b28ca1813bb33e857b0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Oct 2014 18:46:26 -0400 Subject: [PATCH 5344/9457] d_add_ci() should just accept a hashed exact match if it finds one Signed-off-by: Al Viro --- fs/dcache.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index e90aa825cc03..e605e90d0f0a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1888,51 +1888,19 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, * if not go ahead and create it now. */ found = d_hash_and_lookup(dentry->d_parent, name); - if (unlikely(IS_ERR(found))) - goto err_out; if (!found) { new = d_alloc(dentry->d_parent, name); if (!new) { found = ERR_PTR(-ENOMEM); - goto err_out; - } - - found = d_splice_alias(inode, new); - if (found) { - dput(new); - return found; - } - return new; - } - - /* - * If a matching dentry exists, and it's not negative use it. - * - * Decrement the reference count to balance the iget() done - * earlier on. - */ - if (found->d_inode) { - if (unlikely(found->d_inode != inode)) { - /* This can't happen because bad inodes are unhashed. */ - BUG_ON(!is_bad_inode(inode)); - BUG_ON(!is_bad_inode(found->d_inode)); + } else { + found = d_splice_alias(inode, new); + if (found) { + dput(new); + return found; + } + return new; } - iput(inode); - return found; } - - /* - * Negative dentry: instantiate it unless the inode is a directory and - * already has a dentry. - */ - new = d_splice_alias(inode, found); - if (new) { - dput(found); - found = new; - } - return found; - -err_out: iput(inode); return found; } -- GitLab From b5ae6b15bd73e35b129408755a0804287a87e041 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Oct 2014 22:16:02 -0400 Subject: [PATCH 5345/9457] merge d_materialise_unique() into d_splice_alias() Signed-off-by: Al Viro --- fs/dcache.c | 143 ++++++++++------------------------------- include/linux/dcache.h | 2 +- 2 files changed, 36 insertions(+), 109 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index e605e90d0f0a..435991eada1e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2575,11 +2575,11 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) * Note: If ever the locking in lock_rename() changes, then please * remember to update this too... */ -static struct dentry *__d_unalias(struct inode *inode, +static int __d_unalias(struct inode *inode, struct dentry *dentry, struct dentry *alias) { struct mutex *m1 = NULL, *m2 = NULL; - struct dentry *ret = ERR_PTR(-EBUSY); + int ret = -EBUSY; /* If alias and dentry share a parent, then no extra locks required */ if (alias->d_parent == dentry->d_parent) @@ -2594,7 +2594,7 @@ static struct dentry *__d_unalias(struct inode *inode, m2 = &alias->d_parent->d_inode->i_mutex; out_unalias: __d_move(alias, dentry, false); - ret = alias; + ret = 0; out_err: spin_unlock(&inode->i_lock); if (m2) @@ -2629,130 +2629,57 @@ static struct dentry *__d_unalias(struct inode *inode, */ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) { - struct dentry *new = NULL; - if (IS_ERR(inode)) return ERR_CAST(inode); - if (inode && S_ISDIR(inode->i_mode)) { - spin_lock(&inode->i_lock); - new = __d_find_any_alias(inode); - if (new) { - if (!IS_ROOT(new)) { - spin_unlock(&inode->i_lock); - dput(new); - iput(inode); - return ERR_PTR(-EIO); - } - if (d_ancestor(new, dentry)) { - spin_unlock(&inode->i_lock); - dput(new); - iput(inode); - return ERR_PTR(-EIO); - } - write_seqlock(&rename_lock); - __d_move(new, dentry, false); - write_sequnlock(&rename_lock); - spin_unlock(&inode->i_lock); - security_d_instantiate(new, inode); - iput(inode); - } else { - /* already taking inode->i_lock, so d_add() by hand */ - __d_instantiate(dentry, inode); - spin_unlock(&inode->i_lock); - security_d_instantiate(dentry, inode); - d_rehash(dentry); - } - } else { - d_instantiate(dentry, inode); - if (d_unhashed(dentry)) - d_rehash(dentry); - } - return new; -} -EXPORT_SYMBOL(d_splice_alias); - -/** - * d_materialise_unique - introduce an inode into the tree - * @dentry: candidate dentry - * @inode: inode to bind to the dentry, to which aliases may be attached - * - * Introduces an dentry into the tree, substituting an extant disconnected - * root directory alias in its place if there is one. Caller must hold the - * i_mutex of the parent directory. - */ -struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) -{ - struct dentry *actual; - BUG_ON(!d_unhashed(dentry)); if (!inode) { - actual = dentry; __d_instantiate(dentry, NULL); - d_rehash(actual); - goto out_nolock; + goto out; } - spin_lock(&inode->i_lock); - if (S_ISDIR(inode->i_mode)) { - struct dentry *alias; - - /* Does an aliased dentry already exist? */ - alias = __d_find_alias(inode); - if (alias) { - actual = alias; + struct dentry *new = __d_find_any_alias(inode); + if (unlikely(new)) { write_seqlock(&rename_lock); - - if (d_ancestor(alias, dentry)) { - /* Check for loops */ - actual = ERR_PTR(-ELOOP); + if (unlikely(d_ancestor(new, dentry))) { + write_sequnlock(&rename_lock); spin_unlock(&inode->i_lock); - } else if (IS_ROOT(alias)) { - /* Is this an anonymous mountpoint that we - * could splice into our tree? */ - __d_move(alias, dentry, false); + dput(new); + new = ERR_PTR(-ELOOP); + pr_warn_ratelimited( + "VFS: Lookup of '%s' in %s %s" + " would have caused loop\n", + dentry->d_name.name, + inode->i_sb->s_type->name, + inode->i_sb->s_id); + } else if (!IS_ROOT(new)) { + int err = __d_unalias(inode, dentry, new); write_sequnlock(&rename_lock); - goto found; + if (err) { + dput(new); + new = ERR_PTR(err); + } } else { - /* Nope, but we must(!) avoid directory - * aliasing. This drops inode->i_lock */ - actual = __d_unalias(inode, dentry, alias); - } - write_sequnlock(&rename_lock); - if (IS_ERR(actual)) { - if (PTR_ERR(actual) == -ELOOP) - pr_warn_ratelimited( - "VFS: Lookup of '%s' in %s %s" - " would have caused loop\n", - dentry->d_name.name, - inode->i_sb->s_type->name, - inode->i_sb->s_id); - dput(alias); + __d_move(new, dentry, false); + write_sequnlock(&rename_lock); + spin_unlock(&inode->i_lock); + security_d_instantiate(new, inode); } - goto out_nolock; + iput(inode); + return new; } } - - /* Add a unique reference */ - actual = __d_instantiate_unique(dentry, inode); - if (!actual) - actual = dentry; - - d_rehash(actual); -found: + /* already taking inode->i_lock, so d_add() by hand */ + __d_instantiate(dentry, inode); spin_unlock(&inode->i_lock); -out_nolock: - if (actual == dentry) { - security_d_instantiate(dentry, inode); - return NULL; - } - - iput(inode); - return actual; +out: + security_d_instantiate(dentry, inode); + d_rehash(dentry); + return NULL; } -EXPORT_SYMBOL_GPL(d_materialise_unique); +EXPORT_SYMBOL(d_splice_alias); static int prepend(char **buffer, int *buflen, const char *str, int namelen) { diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 1c2f1b84468b..ee569da27b72 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -230,7 +230,7 @@ extern seqlock_t rename_lock; */ extern void d_instantiate(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); -extern struct dentry * d_materialise_unique(struct dentry *, struct inode *); +#define d_materialise_unique(d, i) d_splice_alias(i, d) extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); -- GitLab From 41d28bca2da4bd75a8915c1ccf2cacf7f4a2e531 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Oct 2014 22:24:21 -0400 Subject: [PATCH 5346/9457] switch d_materialise_unique() users to d_splice_alias() Signed-off-by: Al Viro --- Documentation/filesystems/nfs/Exporting | 23 +++++------------------ Documentation/filesystems/porting | 4 ++++ fs/9p/vfs_inode.c | 2 +- fs/btrfs/inode.c | 2 +- fs/ceph/inode.c | 2 +- fs/cifs/readdir.c | 2 +- fs/fuse/dir.c | 4 ++-- fs/kernfs/dir.c | 2 +- fs/nfs/dir.c | 4 ++-- fs/nfs/getroot.c | 2 +- include/linux/dcache.h | 1 - 11 files changed, 19 insertions(+), 29 deletions(-) diff --git a/Documentation/filesystems/nfs/Exporting b/Documentation/filesystems/nfs/Exporting index c8f036a9b13f..520a4becb75c 100644 --- a/Documentation/filesystems/nfs/Exporting +++ b/Documentation/filesystems/nfs/Exporting @@ -72,24 +72,11 @@ c/ Helper routines to allocate anonymous dentries, and to help attach DCACHE_DISCONNECTED) dentry is allocated and attached. In the case of a directory, care is taken that only one dentry can ever be attached. - d_splice_alias(inode, dentry) or d_materialise_unique(dentry, inode) - will introduce a new dentry into the tree; either the passed-in - dentry or a preexisting alias for the given inode (such as an - anonymous one created by d_obtain_alias), if appropriate. The two - functions differ in their handling of directories with preexisting - aliases: - d_splice_alias will use any existing IS_ROOT dentry, but it will - return -EIO rather than try to move a dentry with a different - parent. This is appropriate for local filesystems, which - should never see such an alias unless the filesystem is - corrupted somehow (for example, if two on-disk directory - entries refer to the same directory.) - d_materialise_unique will attempt to move any dentry. This is - appropriate for distributed filesystems, where finding a - directory other than where we last cached it may be a normal - consequence of concurrent operations on other hosts. - Both functions return NULL when the passed-in dentry is used, - following the calling convention of ->lookup. + d_splice_alias(inode, dentry) will introduce a new dentry into the tree; + either the passed-in dentry or a preexisting alias for the given inode + (such as an anonymous one created by d_obtain_alias), if appropriate. + It returns NULL when the passed-in dentry is used, following the calling + convention of ->lookup. Filesystem Issues diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 0f3a1390bf00..b6b55a9cffee 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -463,3 +463,7 @@ in your dentry operations instead. of the in-tree instances did). inode_hash_lock is still held, of course, so they are still serialized wrt removal from inode hash, as well as wrt set() callback of iget5_locked(). +-- +[mandatory] + d_materialise_unique() is gone; d_splice_alias() does everything you + need now. Remember that they have opposite orders of arguments ;-/ diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 296482fc77a9..9ee5343d4884 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -832,7 +832,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, * moved b under k and client parallely did a lookup for * k/b. */ - res = d_materialise_unique(dentry, inode); + res = d_splice_alias(inode, dentry); if (!res) v9fs_fid_add(dentry, fid); else if (!IS_ERR(res)) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d23362f4464e..ff0dcc016b71 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5303,7 +5303,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, return ERR_CAST(inode); } - return d_materialise_unique(dentry, inode); + return d_splice_alias(inode, dentry); } unsigned char btrfs_filetype_table[] = { diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 7a1df90c7771..90ec8e32c138 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -967,7 +967,7 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, /* dn must be unhashed */ if (!d_unhashed(dn)) d_drop(dn); - realdn = d_materialise_unique(dn, in); + realdn = d_splice_alias(in, dn); if (IS_ERR(realdn)) { pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", PTR_ERR(realdn), dn, in, ceph_vinop(in)); diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 8fd2a95860ba..586e3d3b204e 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -123,7 +123,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, if (!inode) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); if (alias && !IS_ERR(alias)) dput(alias); out: diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index dbab798f5caf..df562cc87763 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -372,7 +372,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, if (inode && get_node_id(inode) == FUSE_ROOT_ID) goto out_iput; - newent = d_materialise_unique(entry, inode); + newent = d_splice_alias(inode, entry); err = PTR_ERR(newent); if (IS_ERR(newent)) goto out_err; @@ -1320,7 +1320,7 @@ static int fuse_direntplus_link(struct file *file, if (!inode) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); err = PTR_ERR(alias); if (IS_ERR(alias)) goto out; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1c771931bb60..37989f02a226 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -807,7 +807,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, } /* instantiate and hash dentry */ - ret = d_materialise_unique(dentry, inode); + ret = d_splice_alias(inode, dentry); out_unlock: mutex_unlock(&kernfs_mutex); return ret; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 06e8cfcbb670..44d7d0c7e376 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -499,7 +499,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) if (IS_ERR(inode)) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); if (IS_ERR(alias)) goto out; else if (alias) { @@ -1393,7 +1393,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in nfs_advise_use_readdirplus(dir); no_entry: - res = d_materialise_unique(dentry, inode); + res = d_splice_alias(inode, dentry); if (res != NULL) { if (IS_ERR(res)) goto out_unblock_sillyrename; diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index ebc6a0add5ae..9ac3846cb59e 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -51,7 +51,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i /* * Ensure that this dentry is invisible to d_find_alias(). * Otherwise, it may be spliced into the tree by - * d_materialise_unique if a parent directory from the same + * d_splice_alias if a parent directory from the same * filesystem gets mounted at a later time. * This again causes shrink_dcache_for_umount_subtree() to * Oops, since the test for IS_ROOT() will fail. diff --git a/include/linux/dcache.h b/include/linux/dcache.h index ee569da27b72..5a813988e6d4 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -230,7 +230,6 @@ extern seqlock_t rename_lock; */ extern void d_instantiate(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); -#define d_materialise_unique(d, i) d_splice_alias(i, d) extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); -- GitLab From a455589f181e60439c736c6c6a068bb7e6dc23f0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Oct 2014 20:11:25 -0400 Subject: [PATCH 5347/9457] assorted conversions to %p[dD] Signed-off-by: Al Viro --- arch/powerpc/oprofile/cell/spu_task_sync.c | 10 ++- arch/s390/hypfs/hypfs_dbfs.c | 3 +- arch/x86/ia32/ia32_aout.c | 8 +-- drivers/gpu/drm/armada/armada_gem.c | 2 +- drivers/media/pci/zoran/zoran_procfs.c | 4 +- drivers/misc/genwqe/card_dev.c | 2 +- drivers/s390/char/hmcdrv_dev.c | 16 +++-- drivers/scsi/lpfc/lpfc_debugfs.c | 4 +- fs/9p/vfs_inode_dotl.c | 4 +- fs/affs/inode.c | 4 +- fs/affs/namei.c | 40 ++++++------ fs/afs/dir.c | 71 +++++++++++----------- fs/afs/inode.c | 4 +- fs/afs/mntpt.c | 22 ++----- fs/afs/write.c | 4 +- fs/autofs4/expire.c | 30 +++------ fs/autofs4/root.c | 23 +++---- fs/befs/linuxvfs.c | 16 +++-- fs/binfmt_aout.c | 8 +-- fs/cachefiles/namei.c | 21 +++---- fs/cachefiles/xattr.c | 15 ++--- fs/ceph/debugfs.c | 14 ++--- fs/ceph/dir.c | 42 ++++++------- fs/ceph/file.c | 4 +- fs/ceph/inode.c | 14 ++--- fs/configfs/dir.c | 2 +- fs/fuse/file.c | 2 +- fs/jfs/namei.c | 18 +++--- fs/nfs/dir.c | 2 +- fs/nfsd/nfs4xdr.c | 2 +- fs/ntfs/namei.c | 4 +- fs/ocfs2/dcache.c | 18 +++--- fs/ocfs2/dlmfs/dlmfs.c | 4 +- fs/ocfs2/dlmglue.c | 3 +- fs/reiserfs/xattr.c | 6 +- security/smack/smack_lsm.c | 8 +-- 36 files changed, 194 insertions(+), 260 deletions(-) diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index 28f1af2db1f5..1c27831df1ac 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -331,8 +331,7 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, if (mm->exe_file) { app_cookie = fast_get_dcookie(&mm->exe_file->f_path); - pr_debug("got dcookie for %s\n", - mm->exe_file->f_dentry->d_name.name); + pr_debug("got dcookie for %pD\n", mm->exe_file); } for (vma = mm->mmap; vma; vma = vma->vm_next) { @@ -342,15 +341,14 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, if (!vma->vm_file) goto fail_no_image_cookie; - pr_debug("Found spu ELF at %X(object-id:%lx) for file %s\n", - my_offset, spu_ref, - vma->vm_file->f_dentry->d_name.name); + pr_debug("Found spu ELF at %X(object-id:%lx) for file %pD\n", + my_offset, spu_ref, vma->vm_file); *offsetp = my_offset; break; } *spu_bin_dcookie = fast_get_dcookie(&vma->vm_file->f_path); - pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); + pr_debug("got dcookie for %pD\n", vma->vm_file); up_read(&mm->mmap_sem); diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 2badf2bf9cd7..47fe1055c714 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -83,10 +83,9 @@ static ssize_t dbfs_read(struct file *file, char __user *buf, static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct hypfs_dbfs_file *df; + struct hypfs_dbfs_file *df = file_inode(file)->i_private; long rc; - df = file->f_path.dentry->d_inode->i_private; mutex_lock(&df->lock); if (df->unlocked_ioctl) rc = df->unlocked_ioctl(file, cmd, arg); diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index df91466f973d..ae6aad1d24f7 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -342,8 +342,8 @@ static int load_aout_binary(struct linux_binprm *bprm) time_after(jiffies, error_time + 5*HZ)) { printk(KERN_WARNING "fd_offset is not page aligned. Please convert " - "program: %s\n", - bprm->file->f_path.dentry->d_name.name); + "program: %pD\n", + bprm->file); error_time = jiffies; } #endif @@ -429,8 +429,8 @@ static int load_aout_library(struct file *file) if (time_after(jiffies, error_time + 5*HZ)) { printk(KERN_WARNING "N_TXTOFF is not page aligned. Please convert " - "library: %s\n", - file->f_path.dentry->d_name.name); + "library: %pD\n", + file); error_time = jiffies; } #endif diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 7496f55611a5..ef5feeecec84 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -226,7 +226,7 @@ struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, obj->dev_addr = DMA_ERROR_CODE; - mapping = obj->obj.filp->f_path.dentry->d_inode->i_mapping; + mapping = file_inode(obj->obj.filp)->i_mapping; mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); DRM_DEBUG_DRIVER("alloc obj %p size %zu\n", obj, size); diff --git a/drivers/media/pci/zoran/zoran_procfs.c b/drivers/media/pci/zoran/zoran_procfs.c index f7ceee0cdefd..437652761093 100644 --- a/drivers/media/pci/zoran/zoran_procfs.c +++ b/drivers/media/pci/zoran/zoran_procfs.c @@ -157,8 +157,8 @@ static ssize_t zoran_write(struct file *file, const char __user *buffer, return -EFAULT; } string[count] = 0; - dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n", - ZR_DEVNAME(zr), file->f_path.dentry->d_name.name, count, zr); + dprintk(4, KERN_INFO "%s: write_proc: name=%pD count=%zu zr=%p\n", + ZR_DEVNAME(zr), file, count, zr); ldelim = " \t\n"; tdelim = "="; line = strpbrk(sp, ldelim); diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 5918586f2f76..c49d244265ec 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -395,7 +395,7 @@ static void genwqe_vma_open(struct vm_area_struct *vma) static void genwqe_vma_close(struct vm_area_struct *vma) { unsigned long vsize = vma->vm_end - vma->vm_start; - struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct inode *inode = file_inode(vma->vm_file); struct dma_mapping *dma_map; struct genwqe_dev *cd = container_of(inode->i_cdev, struct genwqe_dev, cdev_genwqe); diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c index 0c5176179c17..43cee7fcd01c 100644 --- a/drivers/s390/char/hmcdrv_dev.c +++ b/drivers/s390/char/hmcdrv_dev.c @@ -136,8 +136,7 @@ static int hmcdrv_dev_open(struct inode *inode, struct file *fp) if (rc) module_put(THIS_MODULE); - pr_debug("open file '/dev/%s' with return code %d\n", - fp->f_dentry->d_name.name, rc); + pr_debug("open file '/dev/%pD' with return code %d\n", fp, rc); return rc; } @@ -146,7 +145,7 @@ static int hmcdrv_dev_open(struct inode *inode, struct file *fp) */ static int hmcdrv_dev_release(struct inode *inode, struct file *fp) { - pr_debug("closing file '/dev/%s'\n", fp->f_dentry->d_name.name); + pr_debug("closing file '/dev/%pD'\n", fp); kfree(fp->private_data); fp->private_data = NULL; hmcdrv_ftp_shutdown(); @@ -231,8 +230,8 @@ static ssize_t hmcdrv_dev_read(struct file *fp, char __user *ubuf, retlen = hmcdrv_dev_transfer((char *) fp->private_data, *pos, ubuf, len); - pr_debug("read from file '/dev/%s' at %lld returns %zd/%zu\n", - fp->f_dentry->d_name.name, (long long) *pos, retlen, len); + pr_debug("read from file '/dev/%pD' at %lld returns %zd/%zu\n", + fp, (long long) *pos, retlen, len); if (retlen > 0) *pos += retlen; @@ -248,8 +247,8 @@ static ssize_t hmcdrv_dev_write(struct file *fp, const char __user *ubuf, { ssize_t retlen; - pr_debug("writing file '/dev/%s' at pos. %lld with length %zd\n", - fp->f_dentry->d_name.name, (long long) *pos, len); + pr_debug("writing file '/dev/%pD' at pos. %lld with length %zd\n", + fp, (long long) *pos, len); if (!fp->private_data) { /* first expect a cmd write */ fp->private_data = kmalloc(len + 1, GFP_KERNEL); @@ -272,8 +271,7 @@ static ssize_t hmcdrv_dev_write(struct file *fp, const char __user *ubuf, if (retlen > 0) *pos += retlen; - pr_debug("write to file '/dev/%s' returned %zd\n", - fp->f_dentry->d_name.name, retlen); + pr_debug("write to file '/dev/%pD' returned %zd\n", fp, retlen); return retlen; } diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 786a2aff7b59..1311ab15243e 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -968,8 +968,8 @@ lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file) goto out; /* Round to page boundary */ - printk(KERN_ERR "9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%s\n", - __func__, _dump_buf_dif, file->f_dentry->d_name.name); + printk(KERN_ERR "9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n", + __func__, _dump_buf_dif, file); debug->buffer = _dump_buf_dif; if (!debug->buffer) { kfree(debug); diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 02b64f4e576a..6054c16b8fae 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -826,8 +826,8 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, struct dentry *dir_dentry; struct posix_acl *dacl = NULL, *pacl = NULL; - p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n", - dir->i_ino, dentry->d_name.name, omode, + p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n", + dir->i_ino, dentry, omode, MAJOR(rdev), MINOR(rdev)); if (!new_valid_dev(rdev)) diff --git a/fs/affs/inode.c b/fs/affs/inode.c index e217c511459b..d0609a282e1d 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -348,9 +348,9 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3 u32 block = 0; int retval; - pr_debug("%s(dir=%u, inode=%u, \"%*s\", type=%d)\n", + pr_debug("%s(dir=%u, inode=%u, \"%pd\", type=%d)\n", __func__, (u32)dir->i_ino, - (u32)inode->i_ino, (int)dentry->d_name.len, dentry->d_name.name, type); + (u32)inode->i_ino, dentry, type); retval = -EIO; bh = affs_bread(sb, inode->i_ino); diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 035bd31556fc..bbc38530e924 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -190,8 +190,7 @@ affs_find_entry(struct inode *dir, struct dentry *dentry) toupper_t toupper = affs_get_toupper(sb); u32 key; - pr_debug("%s(\"%.*s\")\n", - __func__, (int)dentry->d_name.len, dentry->d_name.name); + pr_debug("%s(\"%pd\")\n", __func__, dentry); bh = affs_bread(sb, dir->i_ino); if (!bh) @@ -219,8 +218,7 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) struct buffer_head *bh; struct inode *inode = NULL; - pr_debug("%s(\"%.*s\")\n", - __func__, (int)dentry->d_name.len, dentry->d_name.name); + pr_debug("%s(\"%pd\")\n", __func__, dentry); affs_lock_dir(dir); bh = affs_find_entry(dir, dentry); @@ -250,9 +248,9 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) int affs_unlink(struct inode *dir, struct dentry *dentry) { - pr_debug("%s(dir=%d, %lu \"%.*s\")\n", + pr_debug("%s(dir=%d, %lu \"%pd\")\n", __func__, (u32)dir->i_ino, dentry->d_inode->i_ino, - (int)dentry->d_name.len, dentry->d_name.name); + dentry); return affs_remove_header(dentry); } @@ -264,9 +262,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) struct inode *inode; int error; - pr_debug("%s(%lu,\"%.*s\",0%ho)\n", - __func__, dir->i_ino, (int)dentry->d_name.len, - dentry->d_name.name,mode); + pr_debug("%s(%lu,\"%pd\",0%ho)\n", + __func__, dir->i_ino, dentry, mode); inode = affs_new_inode(dir); if (!inode) @@ -294,9 +291,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) struct inode *inode; int error; - pr_debug("%s(%lu,\"%.*s\",0%ho)\n", - __func__, dir->i_ino, (int)dentry->d_name.len, - dentry->d_name.name, mode); + pr_debug("%s(%lu,\"%pd\",0%ho)\n", + __func__, dir->i_ino, dentry, mode); inode = affs_new_inode(dir); if (!inode) @@ -321,9 +317,9 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) int affs_rmdir(struct inode *dir, struct dentry *dentry) { - pr_debug("%s(dir=%u, %lu \"%.*s\")\n", + pr_debug("%s(dir=%u, %lu \"%pd\")\n", __func__, (u32)dir->i_ino, dentry->d_inode->i_ino, - (int)dentry->d_name.len, dentry->d_name.name); + dentry); return affs_remove_header(dentry); } @@ -338,9 +334,8 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) int i, maxlen, error; char c, lc; - pr_debug("%s(%lu,\"%.*s\" -> \"%s\")\n", - __func__, dir->i_ino, (int)dentry->d_name.len, - dentry->d_name.name, symname); + pr_debug("%s(%lu,\"%pd\" -> \"%s\")\n", + __func__, dir->i_ino, dentry, symname); maxlen = AFFS_SB(sb)->s_hashsize * sizeof(u32) - 1; inode = affs_new_inode(dir); @@ -409,9 +404,9 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { struct inode *inode = old_dentry->d_inode; - pr_debug("%s(%u, %u, \"%.*s\")\n", + pr_debug("%s(%u, %u, \"%pd\")\n", __func__, (u32)inode->i_ino, (u32)dir->i_ino, - (int)dentry->d_name.len,dentry->d_name.name); + dentry); return affs_add_entry(dir, inode, dentry, ST_LINKFILE); } @@ -424,10 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, struct buffer_head *bh = NULL; int retval; - pr_debug("%s(old=%u,\"%*s\" to new=%u,\"%*s\")\n", - __func__, (u32)old_dir->i_ino, (int)old_dentry->d_name.len, - old_dentry->d_name.name, (u32)new_dir->i_ino, - (int)new_dentry->d_name.len, new_dentry->d_name.name); + pr_debug("%s(old=%u,\"%pd\" to new=%u,\"%pd\")\n", + __func__, (u32)old_dir->i_ino, old_dentry, + (u32)new_dir->i_ino, new_dentry); retval = affs_check_name(new_dentry->d_name.name, new_dentry->d_name.len, diff --git a/fs/afs/dir.c b/fs/afs/dir.c index d452f3de5434..4ec35e9130e1 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -434,7 +434,7 @@ static int afs_do_lookup(struct inode *dir, struct dentry *dentry, }; int ret; - _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name); + _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); /* search the directory */ ret = afs_dir_iterate(dir, &cookie.ctx, key); @@ -466,8 +466,8 @@ static struct inode *afs_try_auto_mntpt( struct afs_vnode *vnode = AFS_FS_I(dir); struct inode *inode; - _enter("%d, %p{%s}, {%x:%u}, %p", - ret, dentry, devname, vnode->fid.vid, vnode->fid.vnode, key); + _enter("%d, %p{%pd}, {%x:%u}, %p", + ret, dentry, dentry, vnode->fid.vid, vnode->fid.vnode, key); if (ret != -ENOENT || !test_bit(AFS_VNODE_AUTOCELL, &vnode->flags)) @@ -502,8 +502,8 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, vnode = AFS_FS_I(dir); - _enter("{%x:%u},%p{%s},", - vnode->fid.vid, vnode->fid.vnode, dentry, dentry->d_name.name); + _enter("{%x:%u},%p{%pd},", + vnode->fid.vid, vnode->fid.vnode, dentry, dentry); ASSERTCMP(dentry->d_inode, ==, NULL); @@ -589,11 +589,11 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) vnode = AFS_FS_I(dentry->d_inode); if (dentry->d_inode) - _enter("{v={%x:%u} n=%s fl=%lx},", - vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, + _enter("{v={%x:%u} n=%pd fl=%lx},", + vnode->fid.vid, vnode->fid.vnode, dentry, vnode->flags); else - _enter("{neg n=%s}", dentry->d_name.name); + _enter("{neg n=%pd}", dentry); key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell); if (IS_ERR(key)) @@ -608,7 +608,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) afs_validate(dir, key); if (test_bit(AFS_VNODE_DELETED, &dir->flags)) { - _debug("%s: parent dir deleted", dentry->d_name.name); + _debug("%pd: parent dir deleted", dentry); goto out_bad; } @@ -626,16 +626,16 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) if (!dentry->d_inode) goto out_bad; if (is_bad_inode(dentry->d_inode)) { - printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n", - parent->d_name.name, dentry->d_name.name); + printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n", + dentry); goto out_bad; } /* if the vnode ID has changed, then the dirent points to a * different file */ if (fid.vnode != vnode->fid.vnode) { - _debug("%s: dirent changed [%u != %u]", - dentry->d_name.name, fid.vnode, + _debug("%pd: dirent changed [%u != %u]", + dentry, fid.vnode, vnode->fid.vnode); goto not_found; } @@ -644,8 +644,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) * been deleted and replaced, and the original vnode ID has * been reused */ if (fid.unique != vnode->fid.unique) { - _debug("%s: file deleted (uq %u -> %u I:%u)", - dentry->d_name.name, fid.unique, + _debug("%pd: file deleted (uq %u -> %u I:%u)", + dentry, fid.unique, vnode->fid.unique, dentry->d_inode->i_generation); spin_lock(&vnode->lock); @@ -657,14 +657,14 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) case -ENOENT: /* the filename is unknown */ - _debug("%s: dirent not found", dentry->d_name.name); + _debug("%pd: dirent not found", dentry); if (dentry->d_inode) goto not_found; goto out_valid; default: - _debug("failed to iterate dir %s: %d", - parent->d_name.name, ret); + _debug("failed to iterate dir %pd: %d", + parent, ret); goto out_bad; } @@ -682,8 +682,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) spin_unlock(&dentry->d_lock); out_bad: - _debug("dropping dentry %s/%s", - parent->d_name.name, dentry->d_name.name); + _debug("dropping dentry %pd2", dentry); dput(parent); key_put(key); @@ -699,7 +698,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) */ static int afs_d_delete(const struct dentry *dentry) { - _enter("%s", dentry->d_name.name); + _enter("%pd", dentry); if (dentry->d_flags & DCACHE_NFSFS_RENAMED) goto zap; @@ -722,7 +721,7 @@ static int afs_d_delete(const struct dentry *dentry) */ static void afs_d_release(struct dentry *dentry) { - _enter("%s", dentry->d_name.name); + _enter("%pd", dentry); } /* @@ -741,8 +740,8 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%s},%ho", - dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode); + _enter("{%x:%u},{%pd},%ho", + dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); key = afs_request_key(dvnode->volume->cell); if (IS_ERR(key)) { @@ -802,8 +801,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%s}", - dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); + _enter("{%x:%u},{%pd}", + dvnode->fid.vid, dvnode->fid.vnode, dentry); key = afs_request_key(dvnode->volume->cell); if (IS_ERR(key)) { @@ -844,8 +843,8 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%s}", - dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); + _enter("{%x:%u},{%pd}", + dvnode->fid.vid, dvnode->fid.vnode, dentry); ret = -ENAMETOOLONG; if (dentry->d_name.len >= AFSNAMEMAX) @@ -918,8 +917,8 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%s},%ho,", - dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode); + _enter("{%x:%u},{%pd},%ho,", + dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); key = afs_request_key(dvnode->volume->cell); if (IS_ERR(key)) { @@ -981,10 +980,10 @@ static int afs_link(struct dentry *from, struct inode *dir, vnode = AFS_FS_I(from->d_inode); dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%x:%u},{%s}", + _enter("{%x:%u},{%x:%u},{%pd}", vnode->fid.vid, vnode->fid.vnode, dvnode->fid.vid, dvnode->fid.vnode, - dentry->d_name.name); + dentry); key = afs_request_key(dvnode->volume->cell); if (IS_ERR(key)) { @@ -1026,8 +1025,8 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, dvnode = AFS_FS_I(dir); - _enter("{%x:%u},{%s},%s", - dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, + _enter("{%x:%u},{%pd},%s", + dvnode->fid.vid, dvnode->fid.vnode, dentry, content); ret = -EINVAL; @@ -1094,11 +1093,11 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, orig_dvnode = AFS_FS_I(old_dir); new_dvnode = AFS_FS_I(new_dir); - _enter("{%x:%u},{%x:%u},{%x:%u},{%s}", + _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}", orig_dvnode->fid.vid, orig_dvnode->fid.vnode, vnode->fid.vid, vnode->fid.vnode, new_dvnode->fid.vid, new_dvnode->fid.vnode, - new_dentry->d_name.name); + new_dentry); key = afs_request_key(orig_dvnode->volume->cell); if (IS_ERR(key)) { diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 294671288449..8a1d38ef0fc2 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -462,8 +462,8 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr) struct key *key; int ret; - _enter("{%x:%u},{n=%s},%x", - vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, + _enter("{%x:%u},{n=%pd},%x", + vnode->fid.vid, vnode->fid.vnode, dentry, attr->ia_valid); if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID | diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 9682c33d5daf..938c5ab06d5a 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c @@ -106,14 +106,7 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - _enter("%p,%p{%p{%s},%s}", - dir, - dentry, - dentry->d_parent, - dentry->d_parent ? - dentry->d_parent->d_name.name : (const unsigned char *) "", - dentry->d_name.name); - + _enter("%p,%p{%pd2}", dir, dentry, dentry); return ERR_PTR(-EREMOTE); } @@ -122,14 +115,7 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir, */ static int afs_mntpt_open(struct inode *inode, struct file *file) { - _enter("%p,%p{%p{%s},%s}", - inode, file, - file->f_path.dentry->d_parent, - file->f_path.dentry->d_parent ? - file->f_path.dentry->d_parent->d_name.name : - (const unsigned char *) "", - file->f_path.dentry->d_name.name); - + _enter("%p,%p{%pD2}", inode, file, file); return -EREMOTE; } @@ -146,7 +132,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) bool rwpath = false; int ret; - _enter("{%s}", mntpt->d_name.name); + _enter("{%pd}", mntpt); BUG_ON(!mntpt->d_inode); @@ -242,7 +228,7 @@ struct vfsmount *afs_d_automount(struct path *path) { struct vfsmount *newmnt; - _enter("{%s}", path->dentry->d_name.name); + _enter("{%pd}", path->dentry); newmnt = afs_mntpt_do_automount(path->dentry); if (IS_ERR(newmnt)) diff --git a/fs/afs/write.c b/fs/afs/write.c index ab6adfd52516..d148138325c3 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -688,8 +688,8 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); int ret; - _enter("{%x:%u},{n=%s},%d", - vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name, + _enter("{%x:%u},{n=%pd},%d", + vnode->fid.vid, vnode->fid.vnode, dentry, datasync); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index dcdec6fd33c6..bfdbaba9c2ba 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -41,8 +41,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) struct path path = {.mnt = mnt, .dentry = dentry}; int status = 1; - DPRINTK("dentry %p %.*s", - dentry, (int)dentry->d_name.len, dentry->d_name.name); + DPRINTK("dentry %p %pd", dentry, dentry); path_get(&path); @@ -192,8 +191,7 @@ static int autofs4_direct_busy(struct vfsmount *mnt, unsigned long timeout, int do_now) { - DPRINTK("top %p %.*s", - top, (int) top->d_name.len, top->d_name.name); + DPRINTK("top %p %pd", top, top); /* If it's busy update the expiry counters */ if (!may_umount_tree(mnt)) { @@ -221,8 +219,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt, struct autofs_info *top_ino = autofs4_dentry_ino(top); struct dentry *p; - DPRINTK("top %p %.*s", - top, (int)top->d_name.len, top->d_name.name); + DPRINTK("top %p %pd", top, top); /* Negative dentry - give up */ if (!simple_positive(top)) @@ -230,8 +227,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt, p = NULL; while ((p = get_next_positive_dentry(p, top))) { - DPRINTK("dentry %p %.*s", - p, (int) p->d_name.len, p->d_name.name); + DPRINTK("dentry %p %pd", p, p); /* * Is someone visiting anywhere in the subtree ? @@ -277,13 +273,11 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt, { struct dentry *p; - DPRINTK("parent %p %.*s", - parent, (int)parent->d_name.len, parent->d_name.name); + DPRINTK("parent %p %pd", parent, parent); p = NULL; while ((p = get_next_positive_dentry(p, parent))) { - DPRINTK("dentry %p %.*s", - p, (int) p->d_name.len, p->d_name.name); + DPRINTK("dentry %p %pd", p, p); if (d_mountpoint(p)) { /* Can we umount this guy */ @@ -368,8 +362,7 @@ static struct dentry *should_expire(struct dentry *dentry, * offset (autofs-5.0+). */ if (d_mountpoint(dentry)) { - DPRINTK("checking mountpoint %p %.*s", - dentry, (int)dentry->d_name.len, dentry->d_name.name); + DPRINTK("checking mountpoint %p %pd", dentry, dentry); /* Can we umount this guy */ if (autofs4_mount_busy(mnt, dentry)) @@ -382,8 +375,7 @@ static struct dentry *should_expire(struct dentry *dentry, } if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) { - DPRINTK("checking symlink %p %.*s", - dentry, (int)dentry->d_name.len, dentry->d_name.name); + DPRINTK("checking symlink %p %pd", dentry, dentry); /* * A symlink can't be "busy" in the usual sense so * just check last used for expire timeout. @@ -479,8 +471,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, return NULL; found: - DPRINTK("returning %p %.*s", - expired, (int)expired->d_name.len, expired->d_name.name); + DPRINTK("returning %p %pd", expired, expired); ino->flags |= AUTOFS_INF_EXPIRING; smp_mb(); ino->flags &= ~AUTOFS_INF_NO_RCU; @@ -512,8 +503,7 @@ int autofs4_expire_wait(struct dentry *dentry, int rcu_walk) if (ino->flags & AUTOFS_INF_EXPIRING) { spin_unlock(&sbi->fs_lock); - DPRINTK("waiting for expire %p name=%.*s", - dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("waiting for expire %p name=%pd", dentry, dentry); status = autofs4_wait(sbi, dentry, NFY_NONE); wait_for_completion(&ino->expire_complete); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 0822c9eacc56..dbb5b7212ce1 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -108,8 +108,7 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) struct dentry *dentry = file->f_path.dentry; struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); - DPRINTK("file=%p dentry=%p %.*s", - file, dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("file=%p dentry=%p %pD", file, dentry, dentry); if (autofs4_oz_mode(sbi)) goto out; @@ -279,8 +278,7 @@ static int autofs4_mount_wait(struct dentry *dentry, bool rcu_walk) if (ino->flags & AUTOFS_INF_PENDING) { if (rcu_walk) return -ECHILD; - DPRINTK("waiting for mount name=%.*s", - dentry->d_name.len, dentry->d_name.name); + DPRINTK("waiting for mount name=%pd", dentry); status = autofs4_wait(sbi, dentry, NFY_MOUNT); DPRINTK("mount wait done status=%d", status); } @@ -340,8 +338,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path) struct autofs_info *ino = autofs4_dentry_ino(dentry); int status; - DPRINTK("dentry=%p %.*s", - dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("dentry=%p %pd", dentry, dentry); /* The daemon never triggers a mount. */ if (autofs4_oz_mode(sbi)) @@ -428,8 +425,7 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) struct autofs_info *ino = autofs4_dentry_ino(dentry); int status; - DPRINTK("dentry=%p %.*s", - dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("dentry=%p %pd", dentry, dentry); /* The daemon never waits. */ if (autofs4_oz_mode(sbi)) { @@ -504,7 +500,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, u struct autofs_info *ino; struct dentry *active; - DPRINTK("name = %.*s", dentry->d_name.len, dentry->d_name.name); + DPRINTK("name = %pd", dentry); /* File name too long to exist */ if (dentry->d_name.len > NAME_MAX) @@ -558,8 +554,7 @@ static int autofs4_dir_symlink(struct inode *dir, size_t size = strlen(symname); char *cp; - DPRINTK("%s <- %.*s", symname, - dentry->d_name.len, dentry->d_name.name); + DPRINTK("%s <- %pd", symname, dentry); if (!autofs4_oz_mode(sbi)) return -EACCES; @@ -701,8 +696,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) struct autofs_info *ino = autofs4_dentry_ino(dentry); struct autofs_info *p_ino; - DPRINTK("dentry %p, removing %.*s", - dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("dentry %p, removing %pd", dentry, dentry); if (!autofs4_oz_mode(sbi)) return -EACCES; @@ -744,8 +738,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t m if (!autofs4_oz_mode(sbi)) return -EACCES; - DPRINTK("dentry %p, creating %.*s", - dentry, dentry->d_name.len, dentry->d_name.name); + DPRINTK("dentry %p, creating %pd", dentry, dentry); BUG_ON(!ino); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 4cf61ec6b7a8..b94d1cc9cd30 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -172,8 +172,8 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) char *utfname; const char *name = dentry->d_name.name; - befs_debug(sb, "---> %s name %s inode %ld", __func__, - dentry->d_name.name, dir->i_ino); + befs_debug(sb, "---> %s name %pd inode %ld", __func__, + dentry, dir->i_ino); /* Convert to UTF-8 */ if (BEFS_SB(sb)->nls) { @@ -191,8 +191,7 @@ befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) } if (ret == BEFS_BT_NOT_FOUND) { - befs_debug(sb, "<--- %s %s not found", __func__, - dentry->d_name.name); + befs_debug(sb, "<--- %s %pd not found", __func__, dentry); return ERR_PTR(-ENOENT); } else if (ret != BEFS_OK || offset == 0) { @@ -222,10 +221,9 @@ befs_readdir(struct file *file, struct dir_context *ctx) size_t keysize; unsigned char d_type; char keybuf[BEFS_NAME_LEN + 1]; - const char *dirname = file->f_path.dentry->d_name.name; - befs_debug(sb, "---> %s name %s, inode %ld, ctx->pos %lld", - __func__, dirname, inode->i_ino, ctx->pos); + befs_debug(sb, "---> %s name %pD, inode %ld, ctx->pos %lld", + __func__, file, inode->i_ino, ctx->pos); more: result = befs_btree_read(sb, ds, ctx->pos, BEFS_NAME_LEN + 1, @@ -233,8 +231,8 @@ befs_readdir(struct file *file, struct dir_context *ctx) if (result == BEFS_ERR) { befs_debug(sb, "<--- %s ERROR", __func__); - befs_error(sb, "IO error reading %s (inode %lu)", - dirname, inode->i_ino); + befs_error(sb, "IO error reading %pD (inode %lu)", + file, inode->i_ino); return -EIO; } else if (result == BEFS_BT_END) { diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 929dec08c348..4c556680fa74 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -292,8 +292,8 @@ static int load_aout_binary(struct linux_binprm * bprm) if ((fd_offset & ~PAGE_MASK) != 0 && printk_ratelimit()) { printk(KERN_WARNING - "fd_offset is not page aligned. Please convert program: %s\n", - bprm->file->f_path.dentry->d_name.name); + "fd_offset is not page aligned. Please convert program: %pD\n", + bprm->file); } if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { @@ -375,8 +375,8 @@ static int load_aout_library(struct file *file) if (printk_ratelimit()) { printk(KERN_WARNING - "N_TXTOFF is not page aligned. Please convert library: %s\n", - file->f_path.dentry->d_name.name); + "N_TXTOFF is not page aligned. Please convert library: %pD\n", + file); } vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index e12f189d539b..7f8e83f9d74e 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -102,8 +102,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, struct cachefiles_object *object; struct rb_node *p; - _enter(",'%*.*s'", - dentry->d_name.len, dentry->d_name.len, dentry->d_name.name); + _enter(",'%pd'", dentry); write_lock(&cache->active_lock); @@ -273,9 +272,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, char nbuffer[8 + 8 + 1]; int ret; - _enter(",'%*.*s','%*.*s'", - dir->d_name.len, dir->d_name.len, dir->d_name.name, - rep->d_name.len, rep->d_name.len, rep->d_name.name); + _enter(",'%pd','%pd'", dir, rep); _debug("remove %p from %p", rep, dir); @@ -597,8 +594,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, /* if we've found that the terminal object exists, then we need to * check its attributes and delete it if it's out of date */ if (!object->new) { - _debug("validate '%*.*s'", - next->d_name.len, next->d_name.len, next->d_name.name); + _debug("validate '%pd'", next); ret = cachefiles_check_object_xattr(object, auxdata); if (ret == -ESTALE) { @@ -827,8 +823,8 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache, unsigned long start; int ret; - //_enter(",%*.*s/,%s", - // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename); + //_enter(",%pd/,%s", + // dir, filename); /* look up the victim */ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); @@ -910,8 +906,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, struct dentry *victim; int ret; - _enter(",%*.*s/,%s", - dir->d_name.len, dir->d_name.len, dir->d_name.name, filename); + _enter(",%pd/,%s", dir, filename); victim = cachefiles_check_active(cache, dir, filename); if (IS_ERR(victim)) @@ -969,8 +964,8 @@ int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, { struct dentry *victim; - //_enter(",%*.*s/,%s", - // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename); + //_enter(",%pd/,%s", + // dir, filename); victim = cachefiles_check_active(cache, dir, filename); if (IS_ERR(victim)) diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index acbc1f094fb1..a8a68745e11d 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -51,9 +51,8 @@ int cachefiles_check_object_type(struct cachefiles_object *object) } if (ret != -EEXIST) { - pr_err("Can't set xattr on %*.*s [%lu] (err %d)\n", - dentry->d_name.len, dentry->d_name.len, - dentry->d_name.name, dentry->d_inode->i_ino, + pr_err("Can't set xattr on %pd [%lu] (err %d)\n", + dentry, dentry->d_inode->i_ino, -ret); goto error; } @@ -64,9 +63,8 @@ int cachefiles_check_object_type(struct cachefiles_object *object) if (ret == -ERANGE) goto bad_type_length; - pr_err("Can't read xattr on %*.*s [%lu] (err %d)\n", - dentry->d_name.len, dentry->d_name.len, - dentry->d_name.name, dentry->d_inode->i_ino, + pr_err("Can't read xattr on %pd [%lu] (err %d)\n", + dentry, dentry->d_inode->i_ino, -ret); goto error; } @@ -92,9 +90,8 @@ int cachefiles_check_object_type(struct cachefiles_object *object) bad_type: xtype[2] = 0; - pr_err("Cache object %*.*s [%lu] type %s not %s\n", - dentry->d_name.len, dentry->d_name.len, - dentry->d_name.name, dentry->d_inode->i_ino, + pr_err("Cache object %pd [%lu] type %s not %s\n", + dentry, dentry->d_inode->i_ino, xtype, type); ret = -EIO; goto error; diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 5d5a4c8c8496..1b2355109b9f 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -83,10 +83,9 @@ static int mdsc_show(struct seq_file *s, void *p) if (IS_ERR(path)) path = NULL; spin_lock(&req->r_dentry->d_lock); - seq_printf(s, " #%llx/%.*s (%s)", + seq_printf(s, " #%llx/%pd (%s)", ceph_ino(req->r_dentry->d_parent->d_inode), - req->r_dentry->d_name.len, - req->r_dentry->d_name.name, + req->r_dentry, path ? path : ""); spin_unlock(&req->r_dentry->d_lock); kfree(path); @@ -103,11 +102,10 @@ static int mdsc_show(struct seq_file *s, void *p) if (IS_ERR(path)) path = NULL; spin_lock(&req->r_old_dentry->d_lock); - seq_printf(s, " #%llx/%.*s (%s)", + seq_printf(s, " #%llx/%pd (%s)", req->r_old_dentry_dir ? ceph_ino(req->r_old_dentry_dir) : 0, - req->r_old_dentry->d_name.len, - req->r_old_dentry->d_name.name, + req->r_old_dentry, path ? path : ""); spin_unlock(&req->r_old_dentry->d_lock); kfree(path); @@ -150,8 +148,8 @@ static int dentry_lru_show(struct seq_file *s, void *ptr) spin_lock(&mdsc->dentry_lru_lock); list_for_each_entry(di, &mdsc->dentry_lru, lru) { struct dentry *dentry = di->dentry; - seq_printf(s, "%p %p\t%.*s\n", - di, dentry, dentry->d_name.len, dentry->d_name.name); + seq_printf(s, "%p %p\t%pd\n", + di, dentry, dentry); } spin_unlock(&mdsc->dentry_lru_lock); diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 695e7888fef8..766ec35f988e 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -168,8 +168,8 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && fpos_cmp(ctx->pos, di->offset) <= 0) break; - dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, - dentry->d_name.len, dentry->d_name.name, di->offset, + dout(" skipping %p %pd at %llu (%llu)%s%s\n", dentry, + dentry, di->offset, ctx->pos, d_unhashed(dentry) ? " unhashed" : "", !dentry->d_inode ? " null" : ""); spin_unlock(&dentry->d_lock); @@ -190,8 +190,8 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, goto out; } - dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, - dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + dout(" %llu (%llu) dentry %p %pd %p\n", di->offset, ctx->pos, + dentry, dentry, dentry->d_inode); if (!dir_emit(ctx, dentry->d_name.name, dentry->d_name.len, ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), @@ -538,8 +538,8 @@ int ceph_handle_snapdir(struct ceph_mds_request *req, strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) { struct inode *inode = ceph_get_snapdir(parent); - dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", - dentry, dentry->d_name.len, dentry->d_name.name, inode); + dout("ENOENT on snapdir %p '%pd', linking to snapdir %p\n", + dentry, dentry, inode); BUG_ON(!d_unhashed(dentry)); d_add(dentry, inode); err = 0; @@ -603,8 +603,8 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, int op; int err; - dout("lookup %p dentry %p '%.*s'\n", - dir, dentry, dentry->d_name.len, dentry->d_name.name); + dout("lookup %p dentry %p '%pd'\n", + dir, dentry, dentry); if (dentry->d_name.len > NAME_MAX) return ERR_PTR(-ENAMETOOLONG); @@ -774,8 +774,8 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (ceph_snap(dir) == CEPH_SNAPDIR) { /* mkdir .snap/foo is a MKSNAP */ op = CEPH_MDS_OP_MKSNAP; - dout("mksnap dir %p snap '%.*s' dn %p\n", dir, - dentry->d_name.len, dentry->d_name.name, dentry); + dout("mksnap dir %p snap '%pd' dn %p\n", dir, + dentry, dentry); } else if (ceph_snap(dir) == CEPH_NOSNAP) { dout("mkdir dir %p dn %p mode 0%ho\n", dir, dentry, mode); op = CEPH_MDS_OP_MKDIR; @@ -888,8 +888,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry) if (ceph_snap(dir) == CEPH_SNAPDIR) { /* rmdir .snap/foo is RMSNAP */ - dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len, - dentry->d_name.name, dentry); + dout("rmsnap dir %p '%pd' dn %p\n", dir, dentry, dentry); op = CEPH_MDS_OP_RMSNAP; } else if (ceph_snap(dir) == CEPH_NOSNAP) { dout("unlink/rmdir dir %p dn %p inode %p\n", @@ -1063,16 +1062,15 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) if (flags & LOOKUP_RCU) return -ECHILD; - dout("d_revalidate %p '%.*s' inode %p offset %lld\n", dentry, - dentry->d_name.len, dentry->d_name.name, dentry->d_inode, - ceph_dentry(dentry)->offset); + dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry, + dentry, dentry->d_inode, ceph_dentry(dentry)->offset); dir = ceph_get_dentry_parent_inode(dentry); /* always trust cached snapped dentries, snapdir dentry */ if (ceph_snap(dir) != CEPH_NOSNAP) { - dout("d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry, - dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + dout("d_revalidate %p '%pd' inode %p is SNAPPED\n", dentry, + dentry, dentry->d_inode); valid = 1; } else if (dentry->d_inode && ceph_snap(dentry->d_inode) == CEPH_SNAPDIR) { @@ -1265,8 +1263,7 @@ void ceph_dentry_lru_add(struct dentry *dn) struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_add %p %p '%.*s'\n", di, dn, - dn->d_name.len, dn->d_name.name); + dout("dentry_lru_add %p %p '%pd'\n", di, dn, dn); mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); list_add_tail(&di->lru, &mdsc->dentry_lru); @@ -1279,8 +1276,8 @@ void ceph_dentry_lru_touch(struct dentry *dn) struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_touch %p %p '%.*s' (offset %lld)\n", di, dn, - dn->d_name.len, dn->d_name.name, di->offset); + dout("dentry_lru_touch %p %p '%pd' (offset %lld)\n", di, dn, dn, + di->offset); mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); list_move_tail(&di->lru, &mdsc->dentry_lru); @@ -1292,8 +1289,7 @@ void ceph_dentry_lru_del(struct dentry *dn) struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_del %p %p '%.*s'\n", di, dn, - dn->d_name.len, dn->d_name.name); + dout("dentry_lru_del %p %p '%pd'\n", di, dn, dn); mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); list_del_init(&di->lru); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index d7e0da8366e6..db2c967950f7 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -238,8 +238,8 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, struct ceph_acls_info acls = {}; int err; - dout("atomic_open %p dentry %p '%.*s' %s flags %d mode 0%o\n", - dir, dentry, dentry->d_name.len, dentry->d_name.name, + dout("atomic_open %p dentry %p '%pd' %s flags %d mode 0%o\n", + dir, dentry, dentry, d_unhashed(dentry) ? "unhashed" : "hashed", flags, mode); if (dentry->d_name.len > NAME_MAX) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 90ec8e32c138..a5593d51d035 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1186,20 +1186,18 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, struct inode *olddir = req->r_old_dentry_dir; BUG_ON(!olddir); - dout(" src %p '%.*s' dst %p '%.*s'\n", + dout(" src %p '%pd' dst %p '%pd'\n", req->r_old_dentry, - req->r_old_dentry->d_name.len, - req->r_old_dentry->d_name.name, - dn, dn->d_name.len, dn->d_name.name); + req->r_old_dentry, + dn, dn); dout("fill_trace doing d_move %p -> %p\n", req->r_old_dentry, dn); d_move(req->r_old_dentry, dn); - dout(" src %p '%.*s' dst %p '%.*s'\n", + dout(" src %p '%pd' dst %p '%pd'\n", + req->r_old_dentry, req->r_old_dentry, - req->r_old_dentry->d_name.len, - req->r_old_dentry->d_name.name, - dn, dn->d_name.len, dn->d_name.name); + dn, dn); /* ensure target dentry is invalidated, despite rehashing bug in vfs_rename_dir */ diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 668dcabc5695..c9c298bd3058 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -386,7 +386,7 @@ static void remove_dir(struct dentry * d) if (d->d_inode) simple_rmdir(parent->d_inode,d); - pr_debug(" o %s removing done (%d)\n",d->d_name.name, d_count(d)); + pr_debug(" o %pd removing done (%d)\n", d, d_count(d)); dput(parent); } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index caa8d95b24e8..bf50259012ab 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1988,7 +1988,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) { pgoff_t index = pos >> PAGE_CACHE_SHIFT; - struct fuse_conn *fc = get_fuse_conn(file->f_dentry->d_inode); + struct fuse_conn *fc = get_fuse_conn(file_inode(file)); struct page *page; loff_t fsize; int err = -ENOMEM; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index d59c7defb1ef..38fdc533f4ec 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -84,7 +84,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, struct inode *iplist[2]; struct tblock *tblk; - jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); + jfs_info("jfs_create: dip:0x%p name:%pd", dip, dentry); dquot_initialize(dip); @@ -216,7 +216,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) struct inode *iplist[2]; struct tblock *tblk; - jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name); + jfs_info("jfs_mkdir: dip:0x%p name:%pd", dip, dentry); dquot_initialize(dip); @@ -352,7 +352,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) struct inode *iplist[2]; struct tblock *tblk; - jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); + jfs_info("jfs_rmdir: dip:0x%p name:%pd", dip, dentry); /* Init inode for quota operations. */ dquot_initialize(dip); @@ -480,7 +480,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) s64 new_size = 0; int commit_flag; - jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); + jfs_info("jfs_unlink: dip:0x%p name:%pd", dip, dentry); /* Init inode for quota operations. */ dquot_initialize(dip); @@ -797,8 +797,7 @@ static int jfs_link(struct dentry *old_dentry, struct btstack btstack; struct inode *iplist[2]; - jfs_info("jfs_link: %s %s", old_dentry->d_name.name, - dentry->d_name.name); + jfs_info("jfs_link: %pd %pd", old_dentry, dentry); dquot_initialize(dir); @@ -1082,8 +1081,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, int commit_flag; - jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, - new_dentry->d_name.name); + jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry); dquot_initialize(old_dir); dquot_initialize(new_dir); @@ -1355,7 +1353,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, if (!new_valid_dev(rdev)) return -EINVAL; - jfs_info("jfs_mknod: %s", dentry->d_name.name); + jfs_info("jfs_mknod: %pd", dentry); dquot_initialize(dir); @@ -1444,7 +1442,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsig struct component_name key; int rc; - jfs_info("jfs_lookup: name = %s", dentry->d_name.name); + jfs_info("jfs_lookup: name = %pd", dentry); if ((rc = get_UCSname(&key, dentry))) return ERR_PTR(rc); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 44d7d0c7e376..105ccc30572d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -133,7 +133,7 @@ nfs_opendir(struct inode *inode, struct file *filp) static int nfs_closedir(struct inode *inode, struct file *filp) { - put_nfs_open_dir_context(filp->f_path.dentry->d_inode, filp->private_data); + put_nfs_open_dir_context(file_inode(filp), filp->private_data); return 0; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index eeea7a90eb87..b1eed4dd2eab 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1886,7 +1886,7 @@ static __be32 nfsd4_encode_path(struct xdr_stream *xdr, goto out_free; } p = xdr_encode_opaque(p, dentry->d_name.name, len); - dprintk("/%s", dentry->d_name.name); + dprintk("/%pd", dentry); spin_unlock(&dentry->d_lock); dput(dentry); ncomponents--; diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index 436f36037e09..b3973c2fd190 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c @@ -111,8 +111,8 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, unsigned long dent_ino; int uname_len; - ntfs_debug("Looking up %s in directory inode 0x%lx.", - dent->d_name.name, dir_ino->i_ino); + ntfs_debug("Looking up %pd in directory inode 0x%lx.", + dent, dir_ino->i_ino); /* Convert the name of the dentry to Unicode. */ uname_len = ntfs_nlstoucs(vol, dent->d_name.name, dent->d_name.len, &uname); diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index 92edcfc23c1c..4fda7a5f3088 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c @@ -251,8 +251,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, if (dl) { mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno, - " \"%.*s\": old parent: %llu, new: %llu\n", - dentry->d_name.len, dentry->d_name.name, + " \"%pd\": old parent: %llu, new: %llu\n", + dentry, (unsigned long long)parent_blkno, (unsigned long long)dl->dl_parent_blkno); return 0; @@ -277,8 +277,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, (unsigned long long)OCFS2_I(inode)->ip_blkno); mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno, - " \"%.*s\": old parent: %llu, new: %llu\n", - dentry->d_name.len, dentry->d_name.name, + " \"%pd\": old parent: %llu, new: %llu\n", + dentry, (unsigned long long)parent_blkno, (unsigned long long)dl->dl_parent_blkno); @@ -406,17 +406,15 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode) if (inode) ino = (unsigned long long)OCFS2_I(inode)->ip_blkno; mlog(ML_ERROR, "Dentry is missing cluster lock. " - "inode: %llu, d_flags: 0x%x, d_name: %.*s\n", - ino, dentry->d_flags, dentry->d_name.len, - dentry->d_name.name); + "inode: %llu, d_flags: 0x%x, d_name: %pd\n", + ino, dentry->d_flags, dentry); } goto out; } - mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n", - dentry->d_name.len, dentry->d_name.name, - dl->dl_count); + mlog_bug_on_msg(dl->dl_count == 0, "dentry: %pd, count: %u\n", + dentry, dl->dl_count); ocfs2_dentry_lock_put(OCFS2_SB(dentry->d_sb), dl); diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 09b7d9dac71d..57c40e34f56f 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -565,8 +565,8 @@ static int dlmfs_unlink(struct inode *dir, * to acquire a lock, this basically destroys our lockres. */ status = user_dlm_destroy_lock(&DLMFS_I(inode)->ip_lockres); if (status < 0) { - mlog(ML_ERROR, "unlink %.*s, error %d from destroy\n", - dentry->d_name.len, dentry->d_name.name, status); + mlog(ML_ERROR, "unlink %pd, error %d from destroy\n", + dentry, status); goto bail; } status = simple_unlink(dir, dentry); diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 21262f2b1654..37297c14f9a3 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3725,8 +3725,7 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, break; spin_unlock(&dentry_attach_lock); - mlog(0, "d_delete(%.*s);\n", dentry->d_name.len, - dentry->d_name.name); + mlog(0, "d_delete(%pd);\n", dentry); /* * The following dcache calls may do an diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 628248ce2f8b..04b06146bae2 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -210,9 +210,9 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen, } else if (!dentry->d_inode) { /* A directory entry exists, but no file? */ reiserfs_error(dentry->d_sb, "xattr-20003", - "Corrupted directory: xattr %s listed but " - "not found for file %s.\n", - dentry->d_name.name, dbuf->xadir->d_name.name); + "Corrupted directory: xattr %pd listed but " + "not found for file %pd.\n", + dentry, dbuf->xadir); dput(dentry); return -EIO; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d515ec25ae9f..433ae61e7f42 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -166,9 +166,9 @@ static int smk_bu_file(struct file *file, int mode, int rc) return rc; smk_bu_mode(mode, acc); - pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", + pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", sskp->smk_known, (char *)file->f_security, acc, - inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, + inode->i_sb->s_id, inode->i_ino, file, current->comm); return 0; } @@ -189,9 +189,9 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, return rc; smk_bu_mode(mode, acc); - pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", + pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", sskp->smk_known, smk_of_inode(inode)->smk_known, acc, - inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, + inode->i_sb->s_id, inode->i_ino, file, current->comm); return 0; } -- GitLab From 244c7d444b8bf5b1b76efd53f65c13bde809dbaa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Oct 2014 20:19:11 -0400 Subject: [PATCH 5348/9457] nfsd/nfsctl.c: new helper ... to get from opened file on nfsctl to relevant struct net * Signed-off-by: Al Viro --- fs/nfsd/nfsctl.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index ca73ca79a0ee..9506ea565610 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -231,6 +231,10 @@ static struct file_operations reply_cache_stats_operations = { * payload - write methods */ +static inline struct net *netns(struct file *file) +{ + return file_inode(file)->i_sb->s_fs_info; +} /** * write_unlock_ip - Release all locks used by a client @@ -252,7 +256,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size) struct sockaddr *sap = (struct sockaddr *)&address; size_t salen = sizeof(address); char *fo_path; - struct net *net = file->f_dentry->d_sb->s_fs_info; + struct net *net = netns(file); /* sanity check */ if (size == 0) @@ -350,7 +354,6 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) int len; struct auth_domain *dom; struct knfsd_fh fh; - struct net *net = file->f_dentry->d_sb->s_fs_info; if (size == 0) return -EINVAL; @@ -385,7 +388,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) if (!dom) return -ENOMEM; - len = exp_rootfh(net, dom, path, &fh, maxsize); + len = exp_rootfh(netns(file), dom, path, &fh, maxsize); auth_domain_put(dom); if (len) return len; @@ -429,7 +432,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) { char *mesg = buf; int rv; - struct net *net = file->f_dentry->d_sb->s_fs_info; + struct net *net = netns(file); if (size > 0) { int newthreads; @@ -480,7 +483,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) int len; int npools; int *nthreads; - struct net *net = file->f_dentry->d_sb->s_fs_info; + struct net *net = netns(file); mutex_lock(&nfsd_mutex); npools = nfsd_nrpools(net); @@ -543,8 +546,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) unsigned minor; ssize_t tlen = 0; char *sep; - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); if (size>0) { if (nn->nfsd_serv) @@ -830,10 +832,9 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size, static ssize_t write_ports(struct file *file, char *buf, size_t size) { ssize_t rv; - struct net *net = file->f_dentry->d_sb->s_fs_info; mutex_lock(&nfsd_mutex); - rv = __write_ports(file, buf, size, net); + rv = __write_ports(file, buf, size, netns(file)); mutex_unlock(&nfsd_mutex); return rv; } @@ -865,8 +866,7 @@ int nfsd_max_blksize; static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) { char *mesg = buf; - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); if (size > 0) { int bsize; @@ -915,8 +915,7 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) static ssize_t write_maxconn(struct file *file, char *buf, size_t size) { char *mesg = buf; - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); unsigned int maxconn = nn->max_connections; if (size > 0) { @@ -997,8 +996,7 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, */ static ssize_t write_leasetime(struct file *file, char *buf, size_t size) { - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); } @@ -1014,8 +1012,7 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size) */ static ssize_t write_gracetime(struct file *file, char *buf, size_t size) { - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); } @@ -1071,8 +1068,7 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size, static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) { ssize_t rv; - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); mutex_lock(&nfsd_mutex); rv = __write_recoverydir(file, buf, size, nn); @@ -1102,8 +1098,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) */ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size) { - struct net *net = file->f_dentry->d_sb->s_fs_info; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); if (size > 0) { switch(buf[0]) { -- GitLab From ddb52f4fd2184c3405be4b09f7ac9b2bf47d4e61 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Oct 2014 20:21:18 -0400 Subject: [PATCH 5349/9457] btrfs: get rid of f_dentry use Signed-off-by: Al Viro --- fs/btrfs/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4399f0c3a4ce..080fe66c0349 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -5296,7 +5296,7 @@ long btrfs_ioctl(struct file *file, unsigned int ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1); if (ret) return ret; - ret = btrfs_sync_fs(file->f_dentry->d_sb, 1); + ret = btrfs_sync_fs(file_inode(file)->i_sb, 1); /* * The transaction thread may want to do more work, * namely it pokes the cleaner ktread that will start -- GitLab From 7119e220a7aed7b6e6df02ddfaa2c5f8df2e4e3d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 22 Oct 2014 00:25:12 -0400 Subject: [PATCH 5350/9457] cifs: get rid of ->f_path.dentry->d_sb uses, add a new helper Signed-off-by: Al Viro --- fs/cifs/cifsfs.c | 3 +-- fs/cifs/cifsglob.h | 6 ++++++ fs/cifs/file.c | 12 ++++++------ fs/cifs/readdir.c | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9d7996e8e793..d72fe37f5420 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -209,8 +209,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) { - struct super_block *sb = file->f_path.dentry->d_sb; - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct TCP_Server_Info *server = tcon->ses->server; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 02a33e529904..6e139111fdb2 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1168,6 +1168,12 @@ CIFS_SB(struct super_block *sb) return sb->s_fs_info; } +static inline struct cifs_sb_info * +CIFS_FILE_SB(struct file *file) +{ + return CIFS_SB(file_inode(file)->i_sb); +} + static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 3e4d00a06c44..d535e168a9d3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1586,7 +1586,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag, tcon->ses->server); - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + cifs_sb = CIFS_FILE_SB(file); netfid = cfile->fid.netfid; cinode = CIFS_I(file_inode(file)); @@ -2305,7 +2305,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct cifs_tcon *tcon; struct TCP_Server_Info *server; struct cifsFileInfo *smbfile = file->private_data; - struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct inode *inode = file->f_mapping->host; rc = filemap_write_and_wait_range(inode->i_mapping, start, end); @@ -2585,7 +2585,7 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset) iov_iter_truncate(from, len); INIT_LIST_HEAD(&wdata_list); - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + cifs_sb = CIFS_FILE_SB(file); open_file = file->private_data; tcon = tlink_tcon(open_file->tlink); @@ -3010,7 +3010,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) return 0; INIT_LIST_HEAD(&rdata_list); - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + cifs_sb = CIFS_FILE_SB(file); open_file = file->private_data; tcon = tlink_tcon(open_file->tlink); @@ -3155,7 +3155,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) __u32 pid; xid = get_xid(); - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + cifs_sb = CIFS_FILE_SB(file); /* FIXME: set up handlers for larger reads and/or convert to async */ rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize); @@ -3462,7 +3462,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, int rc; struct list_head tmplist; struct cifsFileInfo *open_file = file->private_data; - struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct TCP_Server_Info *server; pid_t pid; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 586e3d3b204e..d19f1996a6ea 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -261,7 +261,7 @@ initiate_cifs_search(const unsigned int xid, struct file *file) int rc = 0; char *full_path = NULL; struct cifsFileInfo *cifsFile; - struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct tcon_link *tlink = NULL; struct cifs_tcon *tcon; struct TCP_Server_Info *server; @@ -561,7 +561,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, loff_t first_entry_in_buffer; loff_t index_to_find = pos; struct cifsFileInfo *cfile = file->private_data; - struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); struct TCP_Server_Info *server = tcon->ses->server; /* check if index in the buffer */ @@ -679,7 +679,7 @@ static int cifs_filldir(char *find_entry, struct file *file, char *scratch_buf, unsigned int max_len) { struct cifsFileInfo *file_info = file->private_data; - struct super_block *sb = file->f_path.dentry->d_sb; + struct super_block *sb = file_inode(file)->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_dirent de = { NULL, }; struct cifs_fattr fattr; -- GitLab From 3c981bfc57040c0016cfbfa6e9b312571eda2533 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 3 Sep 2013 13:37:45 -0400 Subject: [PATCH 5351/9457] afs_fsync: don't bother with ->f_path.dentry Signed-off-by: Al Viro --- fs/afs/write.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/afs/write.c b/fs/afs/write.c index d148138325c3..c13cb08964ed 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -682,14 +682,13 @@ int afs_writeback_all(struct afs_vnode *vnode) */ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = file->f_mapping->host; + struct inode *inode = file_inode(file); struct afs_writeback *wb, *xwb; - struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); + struct afs_vnode *vnode = AFS_FS_I(inode); int ret; - _enter("{%x:%u},{n=%pd},%d", - vnode->fid.vid, vnode->fid.vnode, dentry, + _enter("{%x:%u},{n=%pD},%d", + vnode->fid.vid, vnode->fid.vnode, file, datasync); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); -- GitLab From 32a59234ae96161b2c91f39801f81c471933d78b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 00:36:30 -0400 Subject: [PATCH 5352/9457] rpc_pipefs.c: get rid of f_dentry Signed-off-by: Al Viro --- fs/nfs/blocklayout/rpc_pipefs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/blocklayout/rpc_pipefs.c b/fs/nfs/blocklayout/rpc_pipefs.c index e966c023b1b7..2a15fa437880 100644 --- a/fs/nfs/blocklayout/rpc_pipefs.c +++ b/fs/nfs/blocklayout/rpc_pipefs.c @@ -109,7 +109,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b, static ssize_t bl_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) { - struct nfs_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info, + struct nfs_net *nn = net_generic(file_inode(filp)->i_sb->s_fs_info, nfs_net_id); if (mlen != sizeof (struct bl_dev_msg)) -- GitLab From ef8a1a10e95beaad0ce77544ae083990ef9fb2d7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 00:41:12 -0400 Subject: [PATCH 5353/9457] nfsd: get rid of ->f_dentry Signed-off-by: Al Viro --- fs/nfsd/nfs4recover.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 0e71a0dd58ca..cc6a76072009 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -705,7 +705,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) struct cld_upcall *tmp, *cup; struct cld_msg __user *cmsg = (struct cld_msg __user *)src; uint32_t xid; - struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info, + struct nfsd_net *nn = net_generic(file_inode(filp)->i_sb->s_fs_info, nfsd_net_id); struct cld_net *cn = nn->cld_net; -- GitLab From 3aa3377fbc3bd31851c4f98b09e20fc5d48814af Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 00:42:35 -0400 Subject: [PATCH 5354/9457] procfs: get rid of ->f_dentry Signed-off-by: Al Viro --- fs/proc/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 772efa45a452..64891f3e41bd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2789,7 +2789,7 @@ static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter ite int proc_pid_readdir(struct file *file, struct dir_context *ctx) { struct tgid_iter iter; - struct pid_namespace *ns = file->f_dentry->d_sb->s_fs_info; + struct pid_namespace *ns = file_inode(file)->i_sb->s_fs_info; loff_t pos = ctx->pos; if (pos >= PID_MAX_LIMIT + TGID_OFFSET) @@ -3095,7 +3095,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx) /* f_version caches the tgid value that the last readdir call couldn't * return. lseek aka telldir automagically resets f_version to 0. */ - ns = file->f_dentry->d_sb->s_fs_info; + ns = inode->i_sb->s_fs_info; tid = (int)file->f_version; file->f_version = 0; for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns); -- GitLab From 30e46aba8f1010b03178f04c0c56be299c063df2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 00:43:30 -0400 Subject: [PATCH 5355/9457] lockd: get rid of ->f_path.dentry->d_sb Signed-off-by: Al Viro --- fs/lockd/svcsubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index b6f3b84b6e99..d12ff4e2dbe7 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -408,7 +408,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file) { struct super_block *sb = datap; - return sb == file->f_file->f_path.dentry->d_sb; + return sb == file_inode(file->f_file)->i_sb; } /** -- GitLab From b583043e99bc6d91e98fae32bd9eff6a5958240a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 01:22:04 -0400 Subject: [PATCH 5356/9457] kill f_dentry uses Signed-off-by: Al Viro --- drivers/block/drbd/drbd_debugfs.c | 6 +++--- drivers/scsi/lpfc/lpfc_debugfs.c | 4 ++-- drivers/staging/lustre/lustre/llite/file.c | 12 +++--------- fs/ceph/dir.c | 6 +++--- fs/ceph/file.c | 2 +- fs/cifs/readdir.c | 2 +- fs/ecryptfs/crypto.c | 2 +- fs/ecryptfs/mmap.c | 2 +- fs/efivarfs/file.c | 4 ++-- fs/sync.c | 2 +- include/linux/cgroup.h | 4 ++-- kernel/auditsc.c | 2 +- kernel/events/core.c | 2 +- kernel/taskstats.c | 2 +- mm/memcontrol.c | 4 ++-- security/commoncap.c | 2 +- security/integrity/ima/ima_api.c | 4 ++-- security/integrity/ima/ima_appraise.c | 4 ++-- security/integrity/ima/ima_template_lib.c | 2 +- 19 files changed, 31 insertions(+), 37 deletions(-) diff --git a/drivers/block/drbd/drbd_debugfs.c b/drivers/block/drbd/drbd_debugfs.c index 900d4d3272d1..9a950022ff88 100644 --- a/drivers/block/drbd/drbd_debugfs.c +++ b/drivers/block/drbd/drbd_debugfs.c @@ -419,7 +419,7 @@ static int in_flight_summary_show(struct seq_file *m, void *pos) return 0; } -/* simple_positive(file->f_dentry) respectively debugfs_positive(), +/* simple_positive(file->f_path.dentry) respectively debugfs_positive(), * but neither is "reachable" from here. * So we have our own inline version of it above. :-( */ static inline int debugfs_positive(struct dentry *dentry) @@ -437,14 +437,14 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo /* Are we still linked, * or has debugfs_remove() already been called? */ - parent = file->f_dentry->d_parent; + parent = file->f_path.dentry->d_parent; /* not sure if this can happen: */ if (!parent || !parent->d_inode) goto out; /* serialize with d_delete() */ mutex_lock(&parent->d_inode->i_mutex); /* Make sure the object is still alive */ - if (debugfs_positive(file->f_dentry) + if (debugfs_positive(file->f_path.dentry) && kref_get_unless_zero(kref)) ret = 0; mutex_unlock(&parent->d_inode->i_mutex); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 1311ab15243e..5633e7dadc08 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1011,7 +1011,7 @@ static ssize_t lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct dentry *dent = file->f_dentry; + struct dentry *dent = file->f_path.dentry; struct lpfc_hba *phba = file->private_data; char cbuf[32]; uint64_t tmp = 0; @@ -1052,7 +1052,7 @@ static ssize_t lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos) { - struct dentry *dent = file->f_dentry; + struct dentry *dent = file->f_path.dentry; struct lpfc_hba *phba = file->private_data; char dstbuf[32]; uint64_t tmp = 0; diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index c99b74117152..08e77492da8f 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -2092,7 +2092,7 @@ static int ll_swap_layouts(struct file *file1, struct file *file2, rc = 0; if (llss->ia2.ia_valid != 0) { mutex_lock(&llss->inode1->i_mutex); - rc = ll_setattr(file1->f_dentry, &llss->ia2); + rc = ll_setattr(file1->f_path.dentry, &llss->ia2); mutex_unlock(&llss->inode1->i_mutex); } @@ -2100,7 +2100,7 @@ static int ll_swap_layouts(struct file *file1, struct file *file2, int rc1; mutex_lock(&llss->inode2->i_mutex); - rc1 = ll_setattr(file2->f_dentry, &llss->ia1); + rc1 = ll_setattr(file2->f_path.dentry, &llss->ia1); mutex_unlock(&llss->inode2->i_mutex); if (rc == 0) rc = rc1; @@ -2185,7 +2185,7 @@ static int ll_hsm_import(struct inode *inode, struct file *file, mutex_lock(&inode->i_mutex); - rc = ll_setattr_raw(file->f_dentry, attr, true); + rc = ll_setattr_raw(file->f_path.dentry, attr, true); if (rc == -ENODATA) rc = 0; @@ -2622,12 +2622,6 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end, return result; } -/* - * When dentry is provided (the 'else' case), *file->f_dentry may be - * null and dentry must be used directly rather than pulled from - * *file->f_dentry as is done otherwise. - */ - int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct dentry *dentry = file->f_dentry; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 766ec35f988e..681a8537b64f 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -123,7 +123,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, u32 shared_gen) { struct ceph_file_info *fi = file->private_data; - struct dentry *parent = file->f_dentry; + struct dentry *parent = file->f_path.dentry; struct inode *dir = parent->d_inode; struct list_head *p; struct dentry *dentry, *last; @@ -274,7 +274,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) off = 1; } if (ctx->pos == 1) { - ino_t ino = parent_ino(file->f_dentry); + ino_t ino = parent_ino(file->f_path.dentry); dout("readdir off 1 -> '..'\n"); if (!dir_emit(ctx, "..", 2, ceph_translate_ino(inode->i_sb, ino), @@ -337,7 +337,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) } req->r_inode = inode; ihold(inode); - req->r_dentry = dget(file->f_dentry); + req->r_dentry = dget(file->f_path.dentry); /* hints to request -> mds selection code */ req->r_direct_mode = USE_AUTH_MDS; req->r_direct_hash = ceph_frag_value(frag); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index db2c967950f7..9f8e3572040e 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -211,7 +211,7 @@ int ceph_open(struct inode *inode, struct file *file) req->r_num_caps = 1; if (flags & O_CREAT) - parent_inode = ceph_get_dentry_parent_inode(file->f_dentry); + parent_inode = ceph_get_dentry_parent_inode(file->f_path.dentry); err = ceph_mdsc_do_request(mdsc, parent_inode, req); iput(parent_inode); if (!err) diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index d19f1996a6ea..d116ca8ce4c0 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -753,7 +753,7 @@ static int cifs_filldir(char *find_entry, struct file *file, */ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; - cifs_prime_dcache(file->f_dentry, &name, &fattr); + cifs_prime_dcache(file->f_path.dentry, &name, &fattr); ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); return !dir_emit(ctx, name.name, name.len, ino, fattr.cf_dtype); diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 2f6735dbf1a9..c2d6604667b0 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1373,7 +1373,7 @@ static int ecryptfs_read_headers_virt(char *page_virt, int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode) { struct dentry *lower_dentry = - ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; + ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_path.dentry; ssize_t size; int rc = 0; diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 564a1fa34b99..4626976794e7 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -419,7 +419,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) ssize_t size; void *xattr_virt; struct dentry *lower_dentry = - ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; + ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_path.dentry; struct inode *lower_inode = lower_dentry->d_inode; int rc; diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index cdb2971192a5..90001da9abfd 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -47,8 +47,8 @@ static ssize_t efivarfs_file_write(struct file *file, if (bytes == -ENOENT) { drop_nlink(inode); - d_delete(file->f_dentry); - dput(file->f_dentry); + d_delete(file->f_path.dentry); + dput(file->f_path.dentry); } else { mutex_lock(&inode->i_mutex); i_size_write(inode, datasize + sizeof(attributes)); diff --git a/fs/sync.c b/fs/sync.c index bdc729d80e5e..01d9f18a70b5 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -154,7 +154,7 @@ SYSCALL_DEFINE1(syncfs, int, fd) if (!f.file) return -EBADF; - sb = f.file->f_dentry->d_sb; + sb = f.file->f_path.dentry->d_sb; down_read(&sb->s_umount); ret = sync_filesystem(sb); diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 1d5196889048..27b0c9105da5 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -367,8 +367,8 @@ struct css_set { * struct cftype: handler definitions for cgroup control files * * When reading/writing to a file: - * - the cgroup to use is file->f_dentry->d_parent->d_fsdata - * - the 'cftype' of the file is file->f_dentry->d_fsdata + * - the cgroup to use is file->f_path.dentry->d_parent->d_fsdata + * - the 'cftype' of the file is file->f_path.dentry->d_fsdata */ /* cftype->flags */ diff --git a/kernel/auditsc.c b/kernel/auditsc.c index e420a0c41b5f..06820657c8ca 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2373,7 +2373,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm, ax->d.next = context->aux; context->aux = (void *)ax; - dentry = dget(bprm->file->f_dentry); + dentry = dget(bprm->file->f_path.dentry); get_vfs_caps_from_disk(dentry, &vcaps); dput(dentry); diff --git a/kernel/events/core.c b/kernel/events/core.c index 1425d07018de..446fbeefad1c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -614,7 +614,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, if (!f.file) return -EBADF; - css = css_tryget_online_from_dir(f.file->f_dentry, + css = css_tryget_online_from_dir(f.file->f_path.dentry, &perf_event_cgrp_subsys); if (IS_ERR(css)) { ret = PTR_ERR(css); diff --git a/kernel/taskstats.c b/kernel/taskstats.c index b312fcc73024..670fff88a961 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c @@ -459,7 +459,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) stats = nla_data(na); memset(stats, 0, sizeof(*stats)); - rc = cgroupstats_build(stats, f.file->f_dentry); + rc = cgroupstats_build(stats, f.file->f_path.dentry); if (rc < 0) { nlmsg_free(rep_skb); goto err; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 23976fd885fd..8c3385181b16 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5055,7 +5055,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, * * DO NOT ADD NEW FILES. */ - name = cfile.file->f_dentry->d_name.name; + name = cfile.file->f_path.dentry->d_name.name; if (!strcmp(name, "memory.usage_in_bytes")) { event->register_event = mem_cgroup_usage_register_event; @@ -5079,7 +5079,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, * automatically removed on cgroup destruction but the removal is * asynchronous, so take an extra ref on @css. */ - cfile_css = css_tryget_online_from_dir(cfile.file->f_dentry->d_parent, + cfile_css = css_tryget_online_from_dir(cfile.file->f_path.dentry->d_parent, &memory_cgrp_subsys); ret = -EINVAL; if (IS_ERR(cfile_css)) diff --git a/security/commoncap.c b/security/commoncap.c index bab0611afc1e..2915d8503054 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -446,7 +446,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) return 0; - dentry = dget(bprm->file->f_dentry); + dentry = dget(bprm->file->f_path.dentry); rc = get_vfs_caps_from_disk(dentry, &vcaps); if (rc < 0) { diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 86885979918c..f92be1b14089 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -196,7 +196,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, { const char *audit_cause = "failed"; struct inode *inode = file_inode(file); - const char *filename = file->f_dentry->d_name.name; + const char *filename = file->f_path.dentry->d_name.name; int result = 0; struct { struct ima_digest_data hdr; @@ -204,7 +204,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, } hash; if (xattr_value) - *xattr_len = ima_read_xattr(file->f_dentry, xattr_value); + *xattr_len = ima_read_xattr(file->f_path.dentry, xattr_value); if (!(iint->flags & IMA_COLLECTED)) { u64 i_version = file_inode(file)->i_version; diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 922685483bd3..c2f203accbd1 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -189,7 +189,7 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, { static const char op[] = "appraise_data"; char *cause = "unknown"; - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; enum integrity_status status = INTEGRITY_UNKNOWN; int rc = xattr_len, hash_start = 0; @@ -289,7 +289,7 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, */ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) { - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; int rc = 0; /* do not collect and update hash for digital signatures */ diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 1506f0248572..bcfc36cbde6a 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -284,7 +284,7 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint, } if (file) { - cur_filename = file->f_dentry->d_name.name; + cur_filename = file->f_path.dentry->d_name.name; cur_filename_len = strlen(cur_filename); } else /* -- GitLab From a67f797db61ee8f2d732e411bf35a92fd78b44a2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 02:41:28 -0400 Subject: [PATCH 5357/9457] ncpfs: use file_inode() Signed-off-by: Al Viro --- fs/ncpfs/dir.c | 6 ++---- fs/ncpfs/file.c | 14 ++++++-------- fs/ncpfs/mmap.c | 4 +--- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 865d578704c8..008960101520 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -685,8 +685,7 @@ static void ncp_read_volume_list(struct file *file, struct dir_context *ctx, struct ncp_cache_control *ctl) { - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file_inode(file); struct ncp_server *server = NCP_SERVER(inode); struct ncp_volume_info info; struct ncp_entry_info entry; @@ -721,8 +720,7 @@ static void ncp_do_readdir(struct file *file, struct dir_context *ctx, struct ncp_cache_control *ctl) { - struct dentry *dentry = file->f_path.dentry; - struct inode *dir = dentry->d_inode; + struct inode *dir = file_inode(file); struct ncp_server *server = NCP_SERVER(dir); struct nw_search_sequence seq; struct ncp_entry_info entry; diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 77640a8bfb87..1dd7007f974d 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -100,8 +100,7 @@ int ncp_make_open(struct inode *inode, int right) static ssize_t ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file_inode(file); size_t already_read = 0; off_t pos; size_t bufsize; @@ -109,7 +108,7 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) void* freepage; size_t freelen; - ncp_dbg(1, "enter %pd2\n", dentry); + ncp_dbg(1, "enter %pD2\n", file); pos = *ppos; @@ -167,7 +166,7 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) file_accessed(file); - ncp_dbg(1, "exit %pd2\n", dentry); + ncp_dbg(1, "exit %pD2\n", file); outrel: ncp_inode_close(inode); return already_read ? already_read : error; @@ -176,15 +175,14 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) static ssize_t ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file_inode(file); size_t already_written = 0; off_t pos; size_t bufsize; int errno; void* bouncebuffer; - ncp_dbg(1, "enter %pd2\n", dentry); + ncp_dbg(1, "enter %pD2\n", file); if ((ssize_t) count < 0) return -EINVAL; pos = *ppos; @@ -263,7 +261,7 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t * i_size_write(inode, pos); mutex_unlock(&inode->i_mutex); } - ncp_dbg(1, "exit %pd2\n", dentry); + ncp_dbg(1, "exit %pD2\n", file); outrel: ncp_inode_close(inode); return already_written ? already_written : errno; diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index b359d12eb359..33b873b259a8 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -30,9 +30,7 @@ static int ncp_file_mmap_fault(struct vm_area_struct *area, struct vm_fault *vmf) { - struct file *file = area->vm_file; - struct dentry *dentry = file->f_path.dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file_inode(area->vm_file); char *pg_addr; unsigned int already_read; unsigned int count; -- GitLab From 6f4e0d5aaa9efaa701f4c3c0bb9b22d7943157c9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 02:42:53 -0400 Subject: [PATCH 5358/9457] nfsd_vfs_write(): use file_inode() Signed-off-by: Al Viro --- fs/nfsd/vfs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 161d2d51b6f2..0a82e3c033ee 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -930,7 +930,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, unsigned long *cnt, int *stablep) { struct svc_export *exp; - struct dentry *dentry; struct inode *inode; mm_segment_t oldfs; __be32 err = 0; @@ -949,8 +948,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, */ current->flags |= PF_LESS_THROTTLE; - dentry = file->f_path.dentry; - inode = dentry->d_inode; + inode = file_inode(file); exp = fhp->fh_export; use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp); -- GitLab From 9f45f5bf302daad6835ce64701fb3c286a2cc6af Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 17:44:57 -0400 Subject: [PATCH 5359/9457] new helper: audit_file() ... for situations when we don't have any candidate in pathnames - basically, in descriptor-based syscalls. [Folded the build fix for !CONFIG_AUDITSYSCALL configs from Chen Gang] Signed-off-by: Al Viro --- fs/open.c | 4 ++-- fs/xattr.c | 16 ++++++---------- include/linux/audit.h | 9 +++++++++ ipc/mqueue.c | 4 ++-- kernel/auditsc.c | 5 +++++ 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/fs/open.c b/fs/open.c index de92c13b58be..b1bf3d542d5d 100644 --- a/fs/open.c +++ b/fs/open.c @@ -516,7 +516,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) int err = -EBADF; if (f.file) { - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); err = chmod_common(&f.file->f_path, mode); fdput(f); } @@ -642,7 +642,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) error = mnt_want_write_file(f.file); if (error) goto out_fput; - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); error = chown_common(&f.file->f_path, user, group); mnt_drop_write_file(f.file); out_fput: diff --git a/fs/xattr.c b/fs/xattr.c index 64e83efb742d..4ef698549e31 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -405,16 +405,14 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, const void __user *,value, size_t, size, int, flags) { struct fd f = fdget(fd); - struct dentry *dentry; int error = -EBADF; if (!f.file) return error; - dentry = f.file->f_path.dentry; - audit_inode(NULL, dentry, 0); + audit_file(f.file); error = mnt_want_write_file(f.file); if (!error) { - error = setxattr(dentry, name, value, size, flags); + error = setxattr(f.file->f_path.dentry, name, value, size, flags); mnt_drop_write_file(f.file); } fdput(f); @@ -509,7 +507,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, if (!f.file) return error; - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); error = getxattr(f.file->f_path.dentry, name, value, size); fdput(f); return error; @@ -590,7 +588,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) if (!f.file) return error; - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); error = listxattr(f.file->f_path.dentry, list, size); fdput(f); return error; @@ -651,16 +649,14 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { struct fd f = fdget(fd); - struct dentry *dentry; int error = -EBADF; if (!f.file) return error; - dentry = f.file->f_path.dentry; - audit_inode(NULL, dentry, 0); + audit_file(f.file); error = mnt_want_write_file(f.file); if (!error) { - error = removexattr(dentry, name); + error = removexattr(f.file->f_path.dentry, name); mnt_drop_write_file(f.file); } fdput(f); diff --git a/include/linux/audit.h b/include/linux/audit.h index e58fe7df8b9c..0c04917c2f12 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -130,6 +130,7 @@ extern void audit_putname(struct filename *name); #define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */ extern void __audit_inode(struct filename *name, const struct dentry *dentry, unsigned int flags); +extern void __audit_file(const struct file *); extern void __audit_inode_child(const struct inode *parent, const struct dentry *dentry, const unsigned char type); @@ -183,6 +184,11 @@ static inline void audit_inode(struct filename *name, __audit_inode(name, dentry, flags); } } +static inline void audit_file(struct file *file) +{ + if (unlikely(!audit_dummy_context())) + __audit_file(file); +} static inline void audit_inode_parent_hidden(struct filename *name, const struct dentry *dentry) { @@ -357,6 +363,9 @@ static inline void audit_inode(struct filename *name, const struct dentry *dentry, unsigned int parent) { } +static inline void audit_file(struct file *file) +{ +} static inline void audit_inode_parent_hidden(struct filename *name, const struct dentry *dentry) { } diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 4fcf39af1776..7635a1cf99f3 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -990,7 +990,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, goto out_fput; } info = MQUEUE_I(inode); - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); if (unlikely(!(f.file->f_mode & FMODE_WRITE))) { ret = -EBADF; @@ -1106,7 +1106,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, goto out_fput; } info = MQUEUE_I(inode); - audit_inode(NULL, f.file->f_path.dentry, 0); + audit_file(f.file); if (unlikely(!(f.file->f_mode & FMODE_READ))) { ret = -EBADF; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 06820657c8ca..c75522a83678 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1897,6 +1897,11 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, audit_copy_inode(n, dentry, inode); } +void __audit_file(const struct file *file) +{ + __audit_inode(NULL, file->f_path.dentry, 0); +} + /** * __audit_inode_child - collect inode info for created/removed objects * @parent: inode of dentry parent -- GitLab From 08d4f7722268755ee34ed1c9e8afee7dfff022bb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 5 Sep 2014 12:16:01 -0400 Subject: [PATCH 5360/9457] dcache: fix kmemcheck warning in switch_names This patch fixes kmemcheck warning in switch_names. The function switch_names swaps inline names of two dentries. It swaps full arrays d_iname, no matter how many bytes are really used by the strings. Reading data beyond string ends results in kmemcheck warning. We fix the bug by marking both arrays as fully initialized. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org # v3.15 Signed-off-by: Al Viro --- fs/dcache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 435991eada1e..a6c5d7e9d622 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2360,6 +2360,8 @@ static void swap_names(struct dentry *dentry, struct dentry *target) */ unsigned int i; BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); + kmemcheck_mark_initialized(dentry->d_iname, DNAME_INLINE_LEN); + kmemcheck_mark_initialized(target->d_iname, DNAME_INLINE_LEN); for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { swap(((long *) &dentry->d_iname)[i], ((long *) &target->d_iname)[i]); -- GitLab From 78d28e651f97866d608d9b41f8ad291e65d47dd5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 01:22:04 -0400 Subject: [PATCH 5361/9457] kill f_dentry macro Signed-off-by: Al Viro --- Documentation/filesystems/porting | 4 ++++ include/linux/fs.h | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index b6b55a9cffee..fa2db081505e 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -467,3 +467,7 @@ in your dentry operations instead. [mandatory] d_materialise_unique() is gone; d_splice_alias() does everything you need now. Remember that they have opposite orders of arguments ;-/ +-- +[mandatory] + f_dentry is gone; use f_path.dentry, or, better yet, see if you can avoid + it entirely. diff --git a/include/linux/fs.h b/include/linux/fs.h index 1c12c681803f..1a8bb3c023a1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -789,7 +789,6 @@ struct file { struct rcu_head fu_rcuhead; } f_u; struct path f_path; -#define f_dentry f_path.dentry struct inode *f_inode; /* cached value */ const struct file_operations *f_op; -- GitLab From 8f894be2df9ad43d17763bc0201f7f303a91f091 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Wed, 12 Nov 2014 16:26:45 +0200 Subject: [PATCH 5362/9457] nl80211: Broadcast CMD_NEW_INTERFACE and CMD_DEL_INTERFACE Let the other listeners being notified when a new or del interface command has been issued, thus reducing later necessary request to be in sync with current context. Signed-off-by: Tomasz Bursztyka Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c81491b1f737..6e4177701d86 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2345,12 +2345,16 @@ static int nl80211_send_chandef(struct sk_buff *msg, static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) + struct wireless_dev *wdev, bool removal) { struct net_device *dev = wdev->netdev; + u8 cmd = NL80211_CMD_NEW_INTERFACE; void *hdr; - hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE); + if (removal) + cmd = NL80211_CMD_DEL_INTERFACE; + + hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); if (!hdr) return -1; @@ -2417,7 +2421,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * } if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - rdev, wdev) < 0) { + rdev, wdev, false) < 0) { goto out; } if_idx++; @@ -2445,7 +2449,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) return -ENOMEM; if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, - rdev, wdev) < 0) { + rdev, wdev, false) < 0) { nlmsg_free(msg); return -ENOBUFS; } @@ -2591,7 +2595,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; struct wireless_dev *wdev; - struct sk_buff *msg; + struct sk_buff *msg, *event; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; u32 flags; @@ -2689,11 +2693,25 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) } if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, - rdev, wdev) < 0) { + rdev, wdev, false) < 0) { nlmsg_free(msg); return -ENOBUFS; } + event = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (event) { + if (nl80211_send_iface(event, 0, 0, 0, + rdev, wdev, false) < 0) { + nlmsg_free(event); + goto out; + } + + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), + event, 0, NL80211_MCGRP_CONFIG, + GFP_KERNEL); + } + +out: return genlmsg_reply(msg, info); } @@ -2701,10 +2719,18 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct wireless_dev *wdev = info->user_ptr[1]; + struct sk_buff *msg; + int status; if (!rdev->ops->del_virtual_intf) return -EOPNOTSUPP; + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (msg && nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, true) < 0) { + nlmsg_free(msg); + msg = NULL; + } + /* * If we remove a wireless device without a netdev then clear * user_ptr[1] so that nl80211_post_doit won't dereference it @@ -2715,7 +2741,15 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) if (!wdev->netdev) info->user_ptr[1] = NULL; - return rdev_del_virtual_intf(rdev, wdev); + status = rdev_del_virtual_intf(rdev, wdev); + if (status >= 0 && msg) + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), + msg, 0, NL80211_MCGRP_CONFIG, + GFP_KERNEL); + else + nlmsg_free(msg); + + return status; } static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) -- GitLab From f815e2b3c0126c26911cac72b837f03a31c0c2ed Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Nov 2014 00:10:42 +0100 Subject: [PATCH 5363/9457] mac80211: notify drivers on sta rate table changes This allows drivers with a firmware or chip-based rate lookup table to use the most recent default rate selection without having to get it from per-packet data or explicit ieee80211_get_tx_rate calls Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- include/net/mac80211.h | 6 ++++++ net/mac80211/driver-ops.h | 15 +++++++++++++++ net/mac80211/rate.c | 3 +++ net/mac80211/trace.h | 7 +++++++ 4 files changed, 31 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7b889e3a2647..cff3a26a9dae 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2695,6 +2695,9 @@ enum ieee80211_reconfig_type { * uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since * otherwise the rate control algorithm is notified directly. * Must be atomic. + * @sta_rate_tbl_update: Notifies the driver that the rate table changed. This + * is only used if the configured rate control algorithm actually uses + * the new rate table API, and is therefore optional. Must be atomic. * * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), * bursting) for a hardware TX queue. @@ -3056,6 +3059,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_sta *sta, u32 changed); + void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); int (*conf_tx)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 ac, const struct ieee80211_tx_queue_params *params); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5f5fc3f3ee7c..2ebc9ead9695 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -624,6 +624,21 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta) +{ + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return; + + trace_drv_sta_rate_tbl_update(local, sdata, sta); + if (local->ops->sta_rate_tbl_update) + local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta); + + trace_drv_return_void(local); +} + static inline int drv_conf_tx(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, u16 ac, const struct ieee80211_tx_queue_params *params) diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index f6fea67fcc5b..08ab7d6d1517 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, struct ieee80211_sta_rates *rates) { + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct ieee80211_sta_rates *old; /* @@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw, if (old) kfree_rcu(old, rcu_head); + drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta); + return 0; } EXPORT_SYMBOL(rate_control_set_rates); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index eb91505eb43e..85ccfbe863db 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -846,6 +846,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_remove, TP_ARGS(local, sdata, sta) ); +DEFINE_EVENT(sta_event, drv_sta_rate_tbl_update, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta), + TP_ARGS(local, sdata, sta) +); + TRACE_EVENT(drv_conf_tx, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, -- GitLab From c86ee3a9f8cddcf2e637da19d6e7c05bdea11a96 Mon Sep 17 00:00:00 2001 From: Thomas Daniel Date: Thu, 13 Nov 2014 10:27:05 +0000 Subject: [PATCH 5364/9457] drm/i915/bdw: Clean up execlist queue items in retire_work No longer create a work item to clean each execlist queue item. Instead, move retired execlist requests to a queue and clean up the items during retire_requests. v2: Fix legacy ring path broken during overzealous cleanup v3: Update idle detection to take execlists queue into account v4: Grab execlist lock when checking queue state v5: Fix leaking requests by freeing in execlists_retire_requests. Issue: VIZ-4274 Signed-off-by: Thomas Daniel Reviewed-by: Deepak S Reviewed-by: Akash Goel Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 9 +++++ drivers/gpu/drm/i915/intel_lrc.c | 53 +++++++++++++++---------- drivers/gpu/drm/i915/intel_lrc.h | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 86cf428b6c4e..2e85ef1650bf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2800,6 +2800,15 @@ i915_gem_retire_requests(struct drm_device *dev) for_each_ring(ring, dev_priv, i) { i915_gem_retire_requests_ring(ring); idle &= list_empty(&ring->request_list); + if (i915.enable_execlists) { + unsigned long flags; + + spin_lock_irqsave(&ring->execlist_lock, flags); + idle &= list_empty(&ring->execlist_queue); + spin_unlock_irqrestore(&ring->execlist_lock, flags); + + intel_execlists_retire_requests(ring); + } } if (idle) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3cf15c4da0e8..c855051ba18d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -399,7 +399,6 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) { struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL; struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL; - struct drm_i915_private *dev_priv = ring->dev->dev_private; assert_spin_locked(&ring->execlist_lock); @@ -416,7 +415,8 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) * will update tail past first request's workload */ cursor->elsp_submitted = req0->elsp_submitted; list_del(&req0->execlist_link); - queue_work(dev_priv->wq, &req0->work); + list_add_tail(&req0->execlist_link, + &ring->execlist_retired_req_list); req0 = cursor; } else { req1 = cursor; @@ -438,7 +438,6 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) static bool execlists_check_remove_request(struct intel_engine_cs *ring, u32 request_id) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; struct intel_ctx_submit_request *head_req; assert_spin_locked(&ring->execlist_lock); @@ -456,7 +455,8 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, if (--head_req->elsp_submitted <= 0) { list_del(&head_req->execlist_link); - queue_work(dev_priv->wq, &head_req->work); + list_add_tail(&head_req->execlist_link, + &ring->execlist_retired_req_list); return true; } } @@ -525,22 +525,6 @@ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) ((u32)ring->next_context_status_buffer & 0x07) << 8); } -static void execlists_free_request_task(struct work_struct *work) -{ - struct intel_ctx_submit_request *req = - container_of(work, struct intel_ctx_submit_request, work); - struct drm_device *dev = req->ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - intel_runtime_pm_put(dev_priv); - - mutex_lock(&dev->struct_mutex); - i915_gem_context_unreference(req->ctx); - mutex_unlock(&dev->struct_mutex); - - kfree(req); -} - static int execlists_context_queue(struct intel_engine_cs *ring, struct intel_context *to, u32 tail) @@ -557,7 +541,6 @@ static int execlists_context_queue(struct intel_engine_cs *ring, i915_gem_context_reference(req->ctx); req->ring = ring; req->tail = tail; - INIT_WORK(&req->work, execlists_free_request_task); intel_runtime_pm_get(dev_priv); @@ -578,7 +561,8 @@ static int execlists_context_queue(struct intel_engine_cs *ring, WARN(tail_req->elsp_submitted != 0, "More than 2 already-submitted reqs queued\n"); list_del(&tail_req->execlist_link); - queue_work(dev_priv->wq, &tail_req->work); + list_add_tail(&tail_req->execlist_link, + &ring->execlist_retired_req_list); } } @@ -746,6 +730,30 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, return 0; } +void intel_execlists_retire_requests(struct intel_engine_cs *ring) +{ + struct intel_ctx_submit_request *req, *tmp; + struct drm_i915_private *dev_priv = ring->dev->dev_private; + unsigned long flags; + struct list_head retired_list; + + WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + if (list_empty(&ring->execlist_retired_req_list)) + return; + + INIT_LIST_HEAD(&retired_list); + spin_lock_irqsave(&ring->execlist_lock, flags); + list_replace_init(&ring->execlist_retired_req_list, &retired_list); + spin_unlock_irqrestore(&ring->execlist_lock, flags); + + list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { + intel_runtime_pm_put(dev_priv); + i915_gem_context_unreference(req->ctx); + list_del(&req->execlist_link); + kfree(req); + } +} + void intel_logical_ring_stop(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = ring->dev->dev_private; @@ -1301,6 +1309,7 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin init_waitqueue_head(&ring->irq_queue); INIT_LIST_HEAD(&ring->execlist_queue); + INIT_LIST_HEAD(&ring->execlist_retired_req_list); spin_lock_init(&ring->execlist_lock); ring->next_context_status_buffer = 0; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 33c3b4bf28c5..84bbf1916324 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -104,11 +104,11 @@ struct intel_ctx_submit_request { u32 tail; struct list_head execlist_link; - struct work_struct work; int elsp_submitted; }; void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring); +void intel_execlists_retire_requests(struct intel_engine_cs *ring); #endif /* _INTEL_LRC_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index aab2e2f90a74..85156567044b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -236,6 +236,7 @@ struct intel_engine_cs { /* Execlists */ spinlock_t execlist_lock; struct list_head execlist_queue; + struct list_head execlist_retired_req_list; u8 next_context_status_buffer; u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct intel_ringbuffer *ringbuf); -- GitLab From 75769c80e381653994293b5aa5a8cfec50088f9f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 16 Nov 2014 00:27:55 +0100 Subject: [PATCH 5365/9457] mac80211: minstrel_ht: add a small optimization to minstrel_aggr_check Check the queue mapping earlier, skb->queue_mapping is more likely than skb->data to still be in d-cache. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/rc80211_minstrel_ht.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index c50fd94d2aef..62ff7cfb2723 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -690,6 +690,9 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) struct sta_info *sta = container_of(pubsta, struct sta_info, sta); u16 tid; + if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) + return; + if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) return; @@ -700,9 +703,6 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) if (likely(sta->ampdu_mlme.tid_tx[tid])) return; - if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) - return; - ieee80211_start_tx_ba_session(pubsta, tid, 5000); } -- GitLab From dcb4c12a687710ab745c2cdee8298c3e97f6f707 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 13 Nov 2014 10:28:10 +0000 Subject: [PATCH 5366/9457] drm/i915/bdw: Pin the context backing objects to GGTT on-demand Up until now, we have pinned every logical ring context backing object during creation, and left it pinned until destruction. This made my life easier, but it's a harmful thing to do, because we cause fragmentation of the GGTT (and, eventually, we would run out of space). This patch makes the pinning on-demand: the backing objects of the two contexts that are written to the ELSP are pinned right before submission and unpinned once the hardware is done with them. The only context that is still pinned regardless is the global default one, so that the HWS can still be accessed in the same way (ring->status_page). v2: In the early version of this patch, we were pinning the context as we put it into the ELSP: on the one hand, this is very efficient because only a maximum two contexts are pinned at any given time, but on the other hand, we cannot really pin in interrupt time :( v3: Use a mutex rather than atomic_t to protect pin count to avoid races. Do not unpin default context in free_request. v4: Break out pin and unpin into functions. Fix style problems reported by checkpatch v5: Remove unpin_lock as all pinning and unpinning is done with the struct mutex already locked. Add WARN_ONs to make sure this is the case in future. Issue: VIZ-4277 Signed-off-by: Oscar Mateo Signed-off-by: Thomas Daniel Reviewed-by: Akash Goel Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 39 ++++++++++------ drivers/gpu/drm/i915/intel_lrc.c | 69 ++++++++++++++++++++++++----- drivers/gpu/drm/i915/intel_lrc.h | 4 ++ 5 files changed, 98 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 319da61354b0..bb1458381dc4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1799,10 +1799,16 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) continue; if (ctx_obj) { - struct page *page = i915_gem_object_get_page(ctx_obj, 1); - uint32_t *reg_state = kmap_atomic(page); + struct page *page; + uint32_t *reg_state; int j; + i915_gem_obj_ggtt_pin(ctx_obj, + GEN8_LR_CONTEXT_ALIGN, 0); + + page = i915_gem_object_get_page(ctx_obj, 1); + reg_state = kmap_atomic(page); + seq_printf(m, "CONTEXT: %s %u\n", ring->name, intel_execlists_ctx_id(ctx_obj)); @@ -1814,6 +1820,8 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) } kunmap_atomic(reg_state); + i915_gem_object_ggtt_unpin(ctx_obj); + seq_putc(m, '\n'); } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4f08160d6192..1097d20a4f35 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -685,6 +685,7 @@ struct intel_context { struct { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; + int unpin_count; } engine[I915_NUM_RINGS]; struct list_head link; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2e85ef1650bf..7f95d8ff28af 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2576,12 +2576,18 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv, static void i915_gem_free_request(struct drm_i915_gem_request *request) { + struct intel_context *ctx = request->ctx; + list_del(&request->list); i915_gem_request_remove_from_client(request); - if (request->ctx) - i915_gem_context_unreference(request->ctx); + if (i915.enable_execlists && ctx) { + struct intel_engine_cs *ring = request->ring; + if (ctx != ring->default_context) + intel_lr_context_unpin(ring, ctx); + i915_gem_context_unreference(ctx); + } kfree(request); } @@ -2635,6 +2641,23 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, i915_gem_object_move_to_inactive(obj); } + /* + * Clear the execlists queue up before freeing the requests, as those + * are the ones that keep the context and ringbuffer backing objects + * pinned in place. + */ + while (!list_empty(&ring->execlist_queue)) { + struct intel_ctx_submit_request *submit_req; + + submit_req = list_first_entry(&ring->execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + list_del(&submit_req->execlist_link); + intel_runtime_pm_put(dev_priv); + i915_gem_context_unreference(submit_req->ctx); + kfree(submit_req); + } + /* * We must free the requests after all the corresponding objects have * been moved off active lists. Which is the same order as the normal @@ -2652,18 +2675,6 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, i915_gem_free_request(request); } - while (!list_empty(&ring->execlist_queue)) { - struct intel_ctx_submit_request *submit_req; - - submit_req = list_first_entry(&ring->execlist_queue, - struct intel_ctx_submit_request, - execlist_link); - list_del(&submit_req->execlist_link); - intel_runtime_pm_put(dev_priv); - i915_gem_context_unreference(submit_req->ctx); - kfree(submit_req); - } - /* These may not have been flush before the reset, do so now */ kfree(ring->preallocated_lazy_request); ring->preallocated_lazy_request = NULL; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c855051ba18d..9560e634c9b8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -140,8 +140,6 @@ #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) #define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE) -#define GEN8_LR_CONTEXT_ALIGN 4096 - #define RING_EXECLIST_QFULL (1 << 0x2) #define RING_EXECLIST1_VALID (1 << 0x3) #define RING_EXECLIST0_VALID (1 << 0x4) @@ -814,9 +812,40 @@ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) execlists_context_queue(ring, ctx, ringbuf->tail); } +static int intel_lr_context_pin(struct intel_engine_cs *ring, + struct intel_context *ctx) +{ + struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + int ret = 0; + + WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + if (ctx->engine[ring->id].unpin_count++ == 0) { + ret = i915_gem_obj_ggtt_pin(ctx_obj, + GEN8_LR_CONTEXT_ALIGN, 0); + if (ret) + ctx->engine[ring->id].unpin_count = 0; + } + + return ret; +} + +void intel_lr_context_unpin(struct intel_engine_cs *ring, + struct intel_context *ctx) +{ + struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + + if (ctx_obj) { + WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + if (--ctx->engine[ring->id].unpin_count == 0) + i915_gem_object_ggtt_unpin(ctx_obj); + } +} + static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, struct intel_context *ctx) { + int ret; + if (ring->outstanding_lazy_seqno) return 0; @@ -827,6 +856,14 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, if (request == NULL) return -ENOMEM; + if (ctx != ring->default_context) { + ret = intel_lr_context_pin(ring, ctx); + if (ret) { + kfree(request); + return ret; + } + } + /* Hold a reference to the context this request belongs to * (we will need it when the time comes to emit/retire the * request). @@ -1680,12 +1717,16 @@ void intel_lr_context_free(struct intel_context *ctx) for (i = 0; i < I915_NUM_RINGS; i++) { struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; - struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; if (ctx_obj) { + struct intel_ringbuffer *ringbuf = + ctx->engine[i].ringbuf; + struct intel_engine_cs *ring = ringbuf->ring; + intel_destroy_ringbuffer_obj(ringbuf); kfree(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); + if (ctx == ring->default_context) + i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); } } @@ -1748,6 +1789,7 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, int intel_lr_context_deferred_create(struct intel_context *ctx, struct intel_engine_cs *ring) { + const bool is_global_default_ctx = (ctx == ring->default_context); struct drm_device *dev = ring->dev; struct drm_i915_gem_object *ctx_obj; uint32_t context_size; @@ -1767,18 +1809,22 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return ret; } - ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, 0); - if (ret) { - DRM_DEBUG_DRIVER("Pin LRC backing obj failed: %d\n", ret); - drm_gem_object_unreference(&ctx_obj->base); - return ret; + if (is_global_default_ctx) { + ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, 0); + if (ret) { + DRM_DEBUG_DRIVER("Pin LRC backing obj failed: %d\n", + ret); + drm_gem_object_unreference(&ctx_obj->base); + return ret; + } } ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL); if (!ringbuf) { DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n", ring->name); - i915_gem_object_ggtt_unpin(ctx_obj); + if (is_global_default_ctx) + i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); ret = -ENOMEM; return ret; @@ -1841,7 +1887,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, error: kfree(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); + if (is_global_default_ctx) + i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); return ret; } diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 84bbf1916324..14b216b9be7f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,6 +24,8 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +#define GEN8_LR_CONTEXT_ALIGN 4096 + /* Execlists regs */ #define RING_ELSP(ring) ((ring)->mmio_base+0x230) #define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) @@ -67,6 +69,8 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring, void intel_lr_context_free(struct intel_context *ctx); int intel_lr_context_deferred_create(struct intel_context *ctx, struct intel_engine_cs *ring); +void intel_lr_context_unpin(struct intel_engine_cs *ring, + struct intel_context *ctx); /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); -- GitLab From 7a8685accb95801bb29ab85d5b370999d3fb8e32 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Wed, 19 Nov 2014 04:48:35 -0800 Subject: [PATCH 5367/9457] leds: lp8860: Introduce TI lp8860 4 channel LED driver Introduce the Texas Instruments lp8860 4 channel LED driver. This driver configures the device in display cluster mode as this seems to be the most used configuration at the time of the driver configuration. For more product information please see the link below: http://www.ti.com/product/lp8860-q1 Signed-off-by: Dan Murphy Signed-off-by: Bryan Wu --- .../devicetree/bindings/leds/leds-lp8860.txt | 29 ++ drivers/leds/Kconfig | 10 + drivers/leds/Makefile | 1 + drivers/leds/leds-lp8860.c | 491 ++++++++++++++++++ 4 files changed, 531 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/leds-lp8860.txt create mode 100644 drivers/leds/leds-lp8860.c diff --git a/Documentation/devicetree/bindings/leds/leds-lp8860.txt b/Documentation/devicetree/bindings/leds/leds-lp8860.txt new file mode 100644 index 000000000000..aad38dd94d4b --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-lp8860.txt @@ -0,0 +1,29 @@ +* Texas Instruments - lp8860 4-Channel LED Driver + +The LP8860-Q1 is an high-efficiency LED +driver with boost controller. It has 4 high-precision +current sinks that can be controlled by a PWM input +signal, a SPI/I2C master, or both. + +Required properties: + - compatible: + "ti,lp8860" + - reg - I2C slave address + - label - Used for naming LEDs + +Optional properties: + - enable-gpio - gpio pin to enable/disable the device. + - supply - "vled" - LED supply + +Example: + +leds: leds@6 { + compatible = "ti,lp8860"; + reg = <0x2d>; + label = "display_cluster"; + enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + vled-supply = <&vbatt>; +} + +For more product information please see the link below: +http://www.ti.com/product/lp8860-q1 diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a210338cfeb1..b0dce59f23e8 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -250,6 +250,16 @@ config LEDS_LP8788 help This option enables support for the Keyboard LEDs on the LP8788 PMIC. +config LEDS_LP8860 + tristate "LED support for the TI LP8860 4 channel LED driver" + depends on LEDS_CLASS && REGMAP_I2C + help + If you say yes here you get support for the TI LP8860 4 channel + LED driver. + This option enables support for the display cluster LEDs + on the LP8860 4 channel LED driver using the I2C communication + bus. + config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index a2b164741465..1c65a191d907 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o obj-$(CONFIG_LEDS_LP5562) += leds-lp5562.o obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o +obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_IPAQ_MICRO) += leds-ipaq-micro.o diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c new file mode 100644 index 000000000000..840e93f3ab3e --- /dev/null +++ b/drivers/leds/leds-lp8860.c @@ -0,0 +1,491 @@ +/* + * TI LP8860 4-Channel LED Driver + * + * Copyright (C) 2014 Texas Instruments + * + * Author: Dan Murphy + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LP8860_DISP_CL1_BRT_MSB 0x00 +#define LP8860_DISP_CL1_BRT_LSB 0x01 +#define LP8860_DISP_CL1_CURR_MSB 0x02 +#define LP8860_DISP_CL1_CURR_LSB 0x03 +#define LP8860_CL2_BRT_MSB 0x04 +#define LP8860_CL2_BRT_LSB 0x05 +#define LP8860_CL2_CURRENT 0x06 +#define LP8860_CL3_BRT_MSB 0x07 +#define LP8860_CL3_BRT_LSB 0x08 +#define LP8860_CL3_CURRENT 0x09 +#define LP8860_CL4_BRT_MSB 0x0a +#define LP8860_CL4_BRT_LSB 0x0b +#define LP8860_CL4_CURRENT 0x0c +#define LP8860_CONFIG 0x0d +#define LP8860_STATUS 0x0e +#define LP8860_FAULT 0x0f +#define LP8860_LED_FAULT 0x10 +#define LP8860_FAULT_CLEAR 0x11 +#define LP8860_ID 0x12 +#define LP8860_TEMP_MSB 0x13 +#define LP8860_TEMP_LSB 0x14 +#define LP8860_DISP_LED_CURR_MSB 0x15 +#define LP8860_DISP_LED_CURR_LSB 0x16 +#define LP8860_DISP_LED_PWM_MSB 0x17 +#define LP8860_DISP_LED_PWM_LSB 0x18 +#define LP8860_EEPROM_CNTRL 0x19 +#define LP8860_EEPROM_UNLOCK 0x1a + +#define LP8860_EEPROM_REG_0 0x60 +#define LP8860_EEPROM_REG_1 0x61 +#define LP8860_EEPROM_REG_2 0x62 +#define LP8860_EEPROM_REG_3 0x63 +#define LP8860_EEPROM_REG_4 0x64 +#define LP8860_EEPROM_REG_5 0x65 +#define LP8860_EEPROM_REG_6 0x66 +#define LP8860_EEPROM_REG_7 0x67 +#define LP8860_EEPROM_REG_8 0x68 +#define LP8860_EEPROM_REG_9 0x69 +#define LP8860_EEPROM_REG_10 0x6a +#define LP8860_EEPROM_REG_11 0x6b +#define LP8860_EEPROM_REG_12 0x6c +#define LP8860_EEPROM_REG_13 0x6d +#define LP8860_EEPROM_REG_14 0x6e +#define LP8860_EEPROM_REG_15 0x6f +#define LP8860_EEPROM_REG_16 0x70 +#define LP8860_EEPROM_REG_17 0x71 +#define LP8860_EEPROM_REG_18 0x72 +#define LP8860_EEPROM_REG_19 0x73 +#define LP8860_EEPROM_REG_20 0x74 +#define LP8860_EEPROM_REG_21 0x75 +#define LP8860_EEPROM_REG_22 0x76 +#define LP8860_EEPROM_REG_23 0x77 +#define LP8860_EEPROM_REG_24 0x78 + +#define LP8860_LOCK_EEPROM 0x00 +#define LP8860_UNLOCK_EEPROM 0x01 +#define LP8860_PROGRAM_EEPROM 0x02 +#define LP8860_EEPROM_CODE_1 0x08 +#define LP8860_EEPROM_CODE_2 0xba +#define LP8860_EEPROM_CODE_3 0xef + +#define LP8860_CLEAR_FAULTS 0x01 + +#define LP8860_DISP_LED_NAME "display_cluster" + +/** + * struct lp8860_led - + * @lock - Lock for reading/writing the device + * @work - Work item used to off load the brightness register writes + * @client - Pointer to the I2C client + * @led_dev - led class device pointer + * @regmap - Devices register map + * @eeprom_regmap - EEPROM register map + * @enable_gpio - VDDIO/EN gpio to enable communication interface + * @regulator - LED supply regulator pointer + * @brightness - Current brightness value requested + * @label - LED label +**/ +struct lp8860_led { + struct mutex lock; + struct work_struct work; + struct i2c_client *client; + struct led_classdev led_dev; + struct regmap *regmap; + struct regmap *eeprom_regmap; + struct gpio_desc *enable_gpio; + struct regulator *regulator; + enum led_brightness brightness; + const char *label; +}; + +struct lp8860_eeprom_reg { + uint8_t reg; + uint8_t value; +}; + +static struct lp8860_eeprom_reg lp8860_eeprom_disp_regs[] = { + { LP8860_EEPROM_REG_0, 0xed }, + { LP8860_EEPROM_REG_1, 0xdf }, + { LP8860_EEPROM_REG_2, 0xdc }, + { LP8860_EEPROM_REG_3, 0xf0 }, + { LP8860_EEPROM_REG_4, 0xdf }, + { LP8860_EEPROM_REG_5, 0xe5 }, + { LP8860_EEPROM_REG_6, 0xf2 }, + { LP8860_EEPROM_REG_7, 0x77 }, + { LP8860_EEPROM_REG_8, 0x77 }, + { LP8860_EEPROM_REG_9, 0x71 }, + { LP8860_EEPROM_REG_10, 0x3f }, + { LP8860_EEPROM_REG_11, 0xb7 }, + { LP8860_EEPROM_REG_12, 0x17 }, + { LP8860_EEPROM_REG_13, 0xef }, + { LP8860_EEPROM_REG_14, 0xb0 }, + { LP8860_EEPROM_REG_15, 0x87 }, + { LP8860_EEPROM_REG_16, 0xce }, + { LP8860_EEPROM_REG_17, 0x72 }, + { LP8860_EEPROM_REG_18, 0xe5 }, + { LP8860_EEPROM_REG_19, 0xdf }, + { LP8860_EEPROM_REG_20, 0x35 }, + { LP8860_EEPROM_REG_21, 0x06 }, + { LP8860_EEPROM_REG_22, 0xdc }, + { LP8860_EEPROM_REG_23, 0x88 }, + { LP8860_EEPROM_REG_24, 0x3E }, +}; + +static int lp8860_unlock_eeprom(struct lp8860_led *led, int lock) +{ + int ret; + + mutex_lock(&led->lock); + + if (lock == LP8860_UNLOCK_EEPROM) { + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_1); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_2); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_EEPROM_CODE_3); + if (ret) { + dev_err(&led->client->dev, "EEPROM Unlock failed\n"); + goto out; + } + } else { + ret = regmap_write(led->regmap, + LP8860_EEPROM_UNLOCK, + LP8860_LOCK_EEPROM); + } + +out: + mutex_unlock(&led->lock); + return ret; +} + +static int lp8860_fault_check(struct lp8860_led *led) +{ + int ret, fault; + unsigned int read_buf; + + ret = regmap_read(led->regmap, LP8860_LED_FAULT, &read_buf); + if (ret) + goto out; + + fault = read_buf; + + ret = regmap_read(led->regmap, LP8860_FAULT, &read_buf); + if (ret) + goto out; + + fault |= read_buf; + + /* Attempt to clear any faults */ + if (fault) + ret = regmap_write(led->regmap, LP8860_FAULT_CLEAR, + LP8860_CLEAR_FAULTS); +out: + return ret; +} + +static void lp8860_led_brightness_work(struct work_struct *work) +{ + struct lp8860_led *led = container_of(work, struct lp8860_led, work); + int ret; + int disp_brightness = led->brightness * 255; + + mutex_lock(&led->lock); + + ret = lp8860_fault_check(led); + if (ret) { + dev_err(&led->client->dev, "Cannot read/clear faults\n"); + goto out; + } + + ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_MSB, + (disp_brightness & 0xff00) >> 8); + if (ret) { + dev_err(&led->client->dev, "Cannot write CL1 MSB\n"); + goto out; + } + + ret = regmap_write(led->regmap, LP8860_DISP_CL1_BRT_LSB, + disp_brightness & 0xff); + if (ret) { + dev_err(&led->client->dev, "Cannot write CL1 LSB\n"); + goto out; + } +out: + mutex_unlock(&led->lock); +} + +static void lp8860_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brt_val) +{ + struct lp8860_led *led = + container_of(led_cdev, struct lp8860_led, led_dev); + + led->brightness = brt_val; + schedule_work(&led->work); +} + +static int lp8860_init(struct lp8860_led *led) +{ + unsigned int read_buf; + int ret, i, reg_count; + + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 1); + + ret = lp8860_fault_check(led); + if (ret) + goto out; + + ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf); + if (ret) + goto out; + + ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM); + if (ret) { + dev_err(&led->client->dev, "Failed unlocking EEPROM\n"); + goto out; + } + + reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); + for (i = 0; i < reg_count; i++) { + ret = regmap_write(led->eeprom_regmap, + lp8860_eeprom_disp_regs[i].reg, + lp8860_eeprom_disp_regs[i].value); + if (ret) { + dev_err(&led->client->dev, "Failed writing EEPROM\n"); + goto out; + } + } + + ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM); + if (ret) + goto out; + + ret = regmap_write(led->regmap, + LP8860_EEPROM_CNTRL, + LP8860_PROGRAM_EEPROM); + if (ret) + dev_err(&led->client->dev, "Failed programming EEPROM\n"); +out: + if (ret) + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 0); + return ret; +} + +static struct reg_default lp8860_reg_defs[] = { + { LP8860_DISP_CL1_BRT_MSB, 0x00}, + { LP8860_DISP_CL1_BRT_LSB, 0x00}, + { LP8860_DISP_CL1_CURR_MSB, 0x00}, + { LP8860_DISP_CL1_CURR_LSB, 0x00}, + { LP8860_CL2_BRT_MSB, 0x00}, + { LP8860_CL2_BRT_LSB, 0x00}, + { LP8860_CL2_CURRENT, 0x00}, + { LP8860_CL3_BRT_MSB, 0x00}, + { LP8860_CL3_BRT_LSB, 0x00}, + { LP8860_CL3_CURRENT, 0x00}, + { LP8860_CL4_BRT_MSB, 0x00}, + { LP8860_CL4_BRT_LSB, 0x00}, + { LP8860_CL4_CURRENT, 0x00}, + { LP8860_CONFIG, 0x00}, + { LP8860_FAULT_CLEAR, 0x00}, + { LP8860_EEPROM_CNTRL, 0x80}, + { LP8860_EEPROM_UNLOCK, 0x00}, +}; + +static const struct regmap_config lp8860_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = LP8860_EEPROM_UNLOCK, + .reg_defaults = lp8860_reg_defs, + .num_reg_defaults = ARRAY_SIZE(lp8860_reg_defs), + .cache_type = REGCACHE_NONE, +}; + +static struct reg_default lp8860_eeprom_defs[] = { + { LP8860_EEPROM_REG_0, 0x00 }, + { LP8860_EEPROM_REG_1, 0x00 }, + { LP8860_EEPROM_REG_2, 0x00 }, + { LP8860_EEPROM_REG_3, 0x00 }, + { LP8860_EEPROM_REG_4, 0x00 }, + { LP8860_EEPROM_REG_5, 0x00 }, + { LP8860_EEPROM_REG_6, 0x00 }, + { LP8860_EEPROM_REG_7, 0x00 }, + { LP8860_EEPROM_REG_8, 0x00 }, + { LP8860_EEPROM_REG_9, 0x00 }, + { LP8860_EEPROM_REG_10, 0x00 }, + { LP8860_EEPROM_REG_11, 0x00 }, + { LP8860_EEPROM_REG_12, 0x00 }, + { LP8860_EEPROM_REG_13, 0x00 }, + { LP8860_EEPROM_REG_14, 0x00 }, + { LP8860_EEPROM_REG_15, 0x00 }, + { LP8860_EEPROM_REG_16, 0x00 }, + { LP8860_EEPROM_REG_17, 0x00 }, + { LP8860_EEPROM_REG_18, 0x00 }, + { LP8860_EEPROM_REG_19, 0x00 }, + { LP8860_EEPROM_REG_20, 0x00 }, + { LP8860_EEPROM_REG_21, 0x00 }, + { LP8860_EEPROM_REG_22, 0x00 }, + { LP8860_EEPROM_REG_23, 0x00 }, + { LP8860_EEPROM_REG_24, 0x00 }, +}; + +static const struct regmap_config lp8860_eeprom_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = LP8860_EEPROM_REG_24, + .reg_defaults = lp8860_eeprom_defs, + .num_reg_defaults = ARRAY_SIZE(lp8860_eeprom_defs), + .cache_type = REGCACHE_NONE, +}; + +static int lp8860_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct lp8860_led *led; + struct device_node *np = client->dev.of_node; + + led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + led->label = LP8860_DISP_LED_NAME; + + if (client->dev.of_node) { + ret = of_property_read_string(np, "label", &led->label); + if (ret) { + dev_err(&client->dev, "Missing label in dt\n"); + return -EINVAL; + } + } + + led->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + if (IS_ERR(led->enable_gpio)) + led->enable_gpio = NULL; + else + gpiod_direction_output(led->enable_gpio, 0); + + led->regulator = devm_regulator_get(&client->dev, "vled"); + if (IS_ERR(led->regulator)) + led->regulator = NULL; + + led->client = client; + led->led_dev.name = led->label; + led->led_dev.max_brightness = LED_FULL; + led->led_dev.brightness_set = lp8860_brightness_set; + + mutex_init(&led->lock); + INIT_WORK(&led->work, lp8860_led_brightness_work); + + i2c_set_clientdata(client, led); + + led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config); + if (IS_ERR(led->regmap)) { + ret = PTR_ERR(led->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + led->eeprom_regmap = devm_regmap_init_i2c(client, &lp8860_eeprom_regmap_config); + if (IS_ERR(led->eeprom_regmap)) { + ret = PTR_ERR(led->eeprom_regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + ret = lp8860_init(led); + if (ret) + return ret; + + ret = led_classdev_register(&client->dev, &led->led_dev); + if (ret) { + dev_err(&client->dev, "led register err: %d\n", ret); + return ret; + } + + return 0; +} + +static int lp8860_remove(struct i2c_client *client) +{ + struct lp8860_led *led = i2c_get_clientdata(client); + int ret; + + led_classdev_unregister(&led->led_dev); + cancel_work_sync(&led->work); + + if (led->enable_gpio) + gpiod_direction_output(led->enable_gpio, 0); + + if (led->regulator) { + ret = regulator_disable(led->regulator); + if (ret) + dev_err(&led->client->dev, + "Failed to disable regulator\n"); + } + + return 0; +} + +static const struct i2c_device_id lp8860_id[] = { + { "lp8860", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lp8860_id); + +#ifdef CONFIG_OF +static const struct of_device_id of_lp8860_leds_match[] = { + { .compatible = "ti,lp8860", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_lp8860_leds_match); +#endif + +static struct i2c_driver lp8860_driver = { + .driver = { + .name = "lp8860", + .of_match_table = of_match_ptr(of_lp8860_leds_match), + }, + .probe = lp8860_probe, + .remove = lp8860_remove, + .id_table = lp8860_id, +}; +module_i2c_driver(lp8860_driver); + +MODULE_DESCRIPTION("Texas Instruments LP8860 LED drvier"); +MODULE_AUTHOR("Dan Murphy "); +MODULE_LICENSE("GPL"); -- GitLab From 7ba717cf365d79f2b284e508205ec3d4a05fc41b Mon Sep 17 00:00:00 2001 From: Thomas Daniel Date: Thu, 13 Nov 2014 10:28:56 +0000 Subject: [PATCH 5368/9457] drm/i915/bdw: Pin the ringbuffer backing object to GGTT on-demand Same as with the context, pinning to GGTT regardless is harmful (it badly fragments the GGTT and can even exhaust it). Unfortunately, this case is also more complex than the previous one because we need to map and access the ringbuffer in several places along the execbuffer path (and we cannot make do by leaving the default ringbuffer pinned, as before). Also, the context object itself contains a pointer to the ringbuffer address that we have to keep updated if we are going to allow the ringbuffer to move around. v2: Same as with the context pinning, we cannot really do it during an interrupt. Also, pin the default ringbuffers objects regardless (makes error capture a lot easier). v3: Rebased. Take a pin reference of the ringbuffer for each item in the execlist request queue because the hardware may still be using the ringbuffer after the MI_USER_INTERRUPT to notify the seqno update is executed. The ringbuffer must remain pinned until the context save is complete. No longer pin and unpin ringbuffer in populate_lr_context() - this transient address is meaningless and the pinning can cause a sleep while atomic. v4: Moved ringbuffer pin and unpin into the lr_context_pin functions. Downgraded pinning check BUG_ONs to WARN_ONs. v5: Reinstated WARN_ONs for unexpected execlist states. Removed unused variable. Issue: VIZ-4277 Signed-off-by: Oscar Mateo Signed-off-by: Thomas Daniel Reviewed-by: Akash Goel Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 102 +++++++++++++++++------- drivers/gpu/drm/i915/intel_ringbuffer.c | 85 ++++++++++++-------- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 + 3 files changed, 128 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9560e634c9b8..e588376227ea 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -203,6 +203,9 @@ enum { }; #define GEN8_CTX_ID_SHIFT 32 +static int intel_lr_context_pin(struct intel_engine_cs *ring, + struct intel_context *ctx); + /** * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists * @dev: DRM device. @@ -354,7 +357,9 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); } -static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tail) +static int execlists_update_context(struct drm_i915_gem_object *ctx_obj, + struct drm_i915_gem_object *ring_obj, + u32 tail) { struct page *page; uint32_t *reg_state; @@ -363,6 +368,7 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai reg_state = kmap_atomic(page); reg_state[CTX_RING_TAIL+1] = tail; + reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(ring_obj); kunmap_atomic(reg_state); @@ -373,21 +379,25 @@ static void execlists_submit_contexts(struct intel_engine_cs *ring, struct intel_context *to0, u32 tail0, struct intel_context *to1, u32 tail1) { - struct drm_i915_gem_object *ctx_obj0; + struct drm_i915_gem_object *ctx_obj0 = to0->engine[ring->id].state; + struct intel_ringbuffer *ringbuf0 = to0->engine[ring->id].ringbuf; struct drm_i915_gem_object *ctx_obj1 = NULL; + struct intel_ringbuffer *ringbuf1 = NULL; - ctx_obj0 = to0->engine[ring->id].state; BUG_ON(!ctx_obj0); WARN_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + WARN_ON(!i915_gem_obj_is_pinned(ringbuf0->obj)); - execlists_ctx_write_tail(ctx_obj0, tail0); + execlists_update_context(ctx_obj0, ringbuf0->obj, tail0); if (to1) { + ringbuf1 = to1->engine[ring->id].ringbuf; ctx_obj1 = to1->engine[ring->id].state; BUG_ON(!ctx_obj1); WARN_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + WARN_ON(!i915_gem_obj_is_pinned(ringbuf1->obj)); - execlists_ctx_write_tail(ctx_obj1, tail1); + execlists_update_context(ctx_obj1, ringbuf1->obj, tail1); } execlists_elsp_write(ring, ctx_obj0, ctx_obj1); @@ -537,6 +547,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring, return -ENOMEM; req->ctx = to; i915_gem_context_reference(req->ctx); + + if (to != ring->default_context) + intel_lr_context_pin(ring, to); + req->ring = ring; req->tail = tail; @@ -557,7 +571,7 @@ static int execlists_context_queue(struct intel_engine_cs *ring, if (to == tail_req->ctx) { WARN(tail_req->elsp_submitted != 0, - "More than 2 already-submitted reqs queued\n"); + "More than 2 already-submitted reqs queued\n"); list_del(&tail_req->execlist_link); list_add_tail(&tail_req->execlist_link, &ring->execlist_retired_req_list); @@ -745,6 +759,12 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring) spin_unlock_irqrestore(&ring->execlist_lock, flags); list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { + struct intel_context *ctx = req->ctx; + struct drm_i915_gem_object *ctx_obj = + ctx->engine[ring->id].state; + + if (ctx_obj && (ctx != ring->default_context)) + intel_lr_context_unpin(ring, ctx); intel_runtime_pm_put(dev_priv); i915_gem_context_unreference(req->ctx); list_del(&req->execlist_link); @@ -816,6 +836,7 @@ static int intel_lr_context_pin(struct intel_engine_cs *ring, struct intel_context *ctx) { struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; int ret = 0; WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); @@ -823,9 +844,20 @@ static int intel_lr_context_pin(struct intel_engine_cs *ring, ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, 0); if (ret) - ctx->engine[ring->id].unpin_count = 0; + goto reset_unpin_count; + + ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf); + if (ret) + goto unpin_ctx_obj; } + return ret; + +unpin_ctx_obj: + i915_gem_object_ggtt_unpin(ctx_obj); +reset_unpin_count: + ctx->engine[ring->id].unpin_count = 0; + return ret; } @@ -833,11 +865,14 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring, struct intel_context *ctx) { struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; if (ctx_obj) { WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); - if (--ctx->engine[ring->id].unpin_count == 0) + if (--ctx->engine[ring->id].unpin_count == 0) { + intel_unpin_ringbuffer_obj(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); + } } } @@ -1595,7 +1630,6 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *ring_obj = ringbuf->obj; struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; struct page *page; uint32_t *reg_state; @@ -1641,7 +1675,9 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o reg_state[CTX_RING_TAIL] = RING_TAIL(ring->mmio_base); reg_state[CTX_RING_TAIL+1] = 0; reg_state[CTX_RING_BUFFER_START] = RING_START(ring->mmio_base); - reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(ring_obj); + /* Ring buffer start address is not known until the buffer is pinned. + * It is written to the context image in execlists_update_context() + */ reg_state[CTX_RING_BUFFER_CONTROL] = RING_CTL(ring->mmio_base); reg_state[CTX_RING_BUFFER_CONTROL+1] = ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID; @@ -1723,10 +1759,12 @@ void intel_lr_context_free(struct intel_context *ctx) ctx->engine[i].ringbuf; struct intel_engine_cs *ring = ringbuf->ring; + if (ctx == ring->default_context) { + intel_unpin_ringbuffer_obj(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); + } intel_destroy_ringbuffer_obj(ringbuf); kfree(ringbuf); - if (ctx == ring->default_context) - i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); } } @@ -1823,11 +1861,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, if (!ringbuf) { DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n", ring->name); - if (is_global_default_ctx) - i915_gem_object_ggtt_unpin(ctx_obj); - drm_gem_object_unreference(&ctx_obj->base); ret = -ENOMEM; - return ret; + goto error_unpin_ctx; } ringbuf->ring = ring; @@ -1840,22 +1875,30 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ringbuf->space = ringbuf->size; ringbuf->last_retired_head = -1; - /* TODO: For now we put this in the mappable region so that we can reuse - * the existing ringbuffer code which ioremaps it. When we start - * creating many contexts, this will no longer work and we must switch - * to a kmapish interface. - */ - ret = intel_alloc_ringbuffer_obj(dev, ringbuf); - if (ret) { - DRM_DEBUG_DRIVER("Failed to allocate ringbuffer obj %s: %d\n", + if (ringbuf->obj == NULL) { + ret = intel_alloc_ringbuffer_obj(dev, ringbuf); + if (ret) { + DRM_DEBUG_DRIVER( + "Failed to allocate ringbuffer obj %s: %d\n", ring->name, ret); - goto error; + goto error_free_rbuf; + } + + if (is_global_default_ctx) { + ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); + if (ret) { + DRM_ERROR( + "Failed to pin and map ringbuffer %s: %d\n", + ring->name, ret); + goto error_destroy_rbuf; + } + } + } ret = populate_lr_context(ctx, ctx_obj, ring, ringbuf); if (ret) { DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret); - intel_destroy_ringbuffer_obj(ringbuf); goto error; } @@ -1877,7 +1920,6 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, DRM_ERROR("Init render state failed: %d\n", ret); ctx->engine[ring->id].ringbuf = NULL; ctx->engine[ring->id].state = NULL; - intel_destroy_ringbuffer_obj(ringbuf); goto error; } ctx->rcs_initialized = true; @@ -1886,7 +1928,13 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return 0; error: + if (is_global_default_ctx) + intel_unpin_ringbuffer_obj(ringbuf); +error_destroy_rbuf: + intel_destroy_ringbuffer_obj(ringbuf); +error_free_rbuf: kfree(ringbuf); +error_unpin_ctx: if (is_global_default_ctx) i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ae092589ea0c..0a4f35e735c3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1722,13 +1722,42 @@ static int init_phys_status_page(struct intel_engine_cs *ring) return 0; } -void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) +void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf) { - if (!ringbuf->obj) - return; - iounmap(ringbuf->virtual_start); + ringbuf->virtual_start = NULL; i915_gem_object_ggtt_unpin(ringbuf->obj); +} + +int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, + struct intel_ringbuffer *ringbuf) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_gem_object *obj = ringbuf->obj; + int ret; + + ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); + if (ret) + return ret; + + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) { + i915_gem_object_ggtt_unpin(obj); + return ret; + } + + ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base + + i915_gem_obj_ggtt_offset(obj), ringbuf->size); + if (ringbuf->virtual_start == NULL) { + i915_gem_object_ggtt_unpin(obj); + return -EINVAL; + } + + return 0; +} + +void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) +{ drm_gem_object_unreference(&ringbuf->obj->base); ringbuf->obj = NULL; } @@ -1736,12 +1765,7 @@ void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) int intel_alloc_ringbuffer_obj(struct drm_device *dev, struct intel_ringbuffer *ringbuf) { - struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; - int ret; - - if (ringbuf->obj) - return 0; obj = NULL; if (!HAS_LLC(dev)) @@ -1754,30 +1778,9 @@ int intel_alloc_ringbuffer_obj(struct drm_device *dev, /* mark ring buffers as read-only from GPU side by default */ obj->gt_ro = 1; - ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); - if (ret) - goto err_unref; - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - goto err_unpin; - - ringbuf->virtual_start = - ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), - ringbuf->size); - if (ringbuf->virtual_start == NULL) { - ret = -EINVAL; - goto err_unpin; - } - ringbuf->obj = obj; - return 0; -err_unpin: - i915_gem_object_ggtt_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); - return ret; + return 0; } static int intel_init_ring_buffer(struct drm_device *dev, @@ -1814,10 +1817,21 @@ static int intel_init_ring_buffer(struct drm_device *dev, goto error; } - ret = intel_alloc_ringbuffer_obj(dev, ringbuf); - if (ret) { - DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", ring->name, ret); - goto error; + if (ringbuf->obj == NULL) { + ret = intel_alloc_ringbuffer_obj(dev, ringbuf); + if (ret) { + DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", + ring->name, ret); + goto error; + } + + ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); + if (ret) { + DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n", + ring->name, ret); + intel_destroy_ringbuffer_obj(ringbuf); + goto error; + } } /* Workaround an erratum on the i830 which causes a hang if @@ -1858,6 +1872,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) intel_stop_ring_buffer(ring); WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); + intel_unpin_ringbuffer_obj(ringbuf); intel_destroy_ringbuffer_obj(ringbuf); ring->preallocated_lazy_request = NULL; ring->outstanding_lazy_seqno = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 85156567044b..9eb3188595a6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -383,6 +383,9 @@ intel_write_status_page(struct intel_engine_cs *ring, #define I915_GEM_HWS_SCRATCH_INDEX 0x30 #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) +void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf); +int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, + struct intel_ringbuffer *ringbuf); void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf); int intel_alloc_ringbuffer_obj(struct drm_device *dev, struct intel_ringbuffer *ringbuf); -- GitLab From 40ba3f0ff261a14107f3f52c67602fff8b88d980 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Fri, 14 Nov 2014 10:10:40 +0800 Subject: [PATCH 5369/9457] clk: delete a local variable's repeated assignment It's the same to the next statement, "ret = clk->parent". I think compiler will optimize it, it's just not looking well. Signed-off-by: Zhen Lei Signed-off-by: Michael Turquette --- drivers/clk/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4896ae9e23da..5307225684eb 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1614,7 +1614,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (clk->num_parents == 1) { if (IS_ERR_OR_NULL(clk->parent)) - ret = clk->parent = __clk_lookup(clk->parent_names[0]); + clk->parent = __clk_lookup(clk->parent_names[0]); ret = clk->parent; goto out; } -- GitLab From 29a77b8a04e794c6c34d45ea10a300b117a68e08 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Nov 2014 19:49:34 +0100 Subject: [PATCH 5370/9457] clk: shmobile: Deprecate renesas,clock-indices Commit 8e33f91a0b84ae19 ("clk: shmobile: clk-mstp: change to using clock-indices") forgot to replace all occurrences of "renesas,clock-indices" in the driver-specific binding documentation. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Acked-by: Kuninori Morimoto Acked-by: Laurent Pinchart Signed-off-by: Michael Turquette --- .../devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt index a5f52238c80d..2e18676bd4b5 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt @@ -26,11 +26,11 @@ Required Properties: must appear in the same order as the output clocks. - #clock-cells: Must be 1 - clock-output-names: The name of the clocks as free-form strings - - renesas,clock-indices: Indices of the gate clocks into the group (0 to 31) + - clock-indices: Indices of the gate clocks into the group (0 to 31) -The clocks, clock-output-names and renesas,clock-indices properties contain one -entry per gate clock. The MSTP groups are sparsely populated. Unimplemented -gate clocks must not be declared. +The clocks, clock-output-names and clock-indices properties contain one entry +per gate clock. The MSTP groups are sparsely populated. Unimplemented gate +clocks must not be declared. Example -- GitLab From baeababb5b85d5c4e6c917efe2a1504179438d3b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 18 Nov 2014 13:20:41 +0800 Subject: [PATCH 5371/9457] tun: return NET_XMIT_DROP for dropped packets After commit 5d097109257c03a71845729f8db6b5770c4bbedc ("tun: only queue packets on device"), NETDEV_TX_OK was returned for dropped packets. This will confuse pktgen since dropped packets were counted as sent ones. Fixing this by returning NET_XMIT_DROP to let pktgen count it as error packet. Cc: Michael S. Tsirkin Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e3fa65a4d96c..ac53a7316ecd 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -819,7 +819,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) skb_tx_error(skb); kfree_skb(skb); rcu_read_unlock(); - return NETDEV_TX_OK; + return NET_XMIT_DROP; } static void tun_net_mclist(struct net_device *dev) -- GitLab From e32efbfc35c1b06f1bfe3e6d737acdd14d27baed Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 14 Nov 2014 09:49:26 -0700 Subject: [PATCH 5372/9457] NVMe: make setup work for devices that don't do INTx The setup/probe part currently relies on INTx being there and working, that's not always the case. For devices that don't advertise INTx, enable a single MSIx vector early on and disable it again before we ask for our full range of queue vecs. Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 677d7b9ff454..9310fe51382e 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -1998,6 +1998,13 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) /* Deregister the admin queue's interrupt */ free_irq(dev->entry[0].vector, adminq); + /* + * If we enable msix early due to not intx, disable it again before + * setting up the full range we need. + */ + if (!pdev->irq) + pci_disable_msix(pdev); + for (i = 0; i < nr_io_queues; i++) dev->entry[i].entry = i; vecs = pci_enable_msix_range(pdev, dev->entry, 1, nr_io_queues); @@ -2150,10 +2157,22 @@ static int nvme_dev_map(struct nvme_dev *dev) dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); if (!dev->bar) goto disable; + if (readl(&dev->bar->csts) == -1) { result = -ENODEV; goto unmap; } + + /* + * Some devices don't advertse INTx interrupts, pre-enable a single + * MSIX vec for setup. We'll adjust this later. + */ + if (!pdev->irq) { + result = pci_enable_msix(pdev, dev->entry, 1); + if (result < 0) + goto unmap; + } + cap = readq(&dev->bar->cap); dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH); dev->db_stride = 1 << NVME_CAP_STRIDE(cap); -- GitLab From 355a901e6cf1b2b763ec85caa2a9f04fbcc4ab4a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 17 Nov 2014 23:06:20 -0800 Subject: [PATCH 5373/9457] tcp: make connect() mem charging friendly While working on sk_forward_alloc problems reported by Denys Fedoryshchenko, we found that tcp connect() (and fastopen) do not call sk_wmem_schedule() for SYN packet (and/or SYN/DATA packet), so sk_forward_alloc is negative while connect is in progress. We can fix this by calling regular sk_stream_alloc_skb() both for the SYN packet (in tcp_connect()) and the syn_data packet in tcp_send_syn_data() Then, tcp_send_syn_data() can avoid copying syn_data as we simply can manipulate syn_data->cb[] to remove SYN flag (and increment seq) Instead of open coding memcpy_fromiovecend(), simply use this helper. This leaves in socket write queue clean fast clone skbs. This was tested against our fastopen packetdrill tests. Reported-by: Denys Fedoryshchenko Signed-off-by: Eric Dumazet Acked-by: Yuchung Cheng Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 68 ++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index eb73a1dccf56..f5bd4bd3f7e6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3011,9 +3011,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) { struct tcp_sock *tp = tcp_sk(sk); struct tcp_fastopen_request *fo = tp->fastopen_req; - int syn_loss = 0, space, i, err = 0, iovlen = fo->data->msg_iovlen; - struct sk_buff *syn_data = NULL, *data; + int syn_loss = 0, space, err = 0; unsigned long last_syn_loss = 0; + struct sk_buff *syn_data; tp->rx_opt.mss_clamp = tp->advmss; /* If MSS is not cached */ tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie, @@ -3044,48 +3044,40 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) /* limit to order-0 allocations */ space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER)); - syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space, - sk->sk_allocation); - if (syn_data == NULL) + syn_data = sk_stream_alloc_skb(sk, space, sk->sk_allocation); + if (!syn_data) goto fallback; + syn_data->ip_summed = CHECKSUM_PARTIAL; + memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); + if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space), + fo->data->msg_iov, 0, space))) { + kfree_skb(syn_data); + goto fallback; + } - for (i = 0; i < iovlen && syn_data->len < space; ++i) { - struct iovec *iov = &fo->data->msg_iov[i]; - unsigned char __user *from = iov->iov_base; - int len = iov->iov_len; + /* No more data pending in inet_wait_for_connect() */ + if (space == fo->size) + fo->data = NULL; + fo->copied = space; - if (syn_data->len + len > space) - len = space - syn_data->len; - else if (i + 1 == iovlen) - /* No more data pending in inet_wait_for_connect() */ - fo->data = NULL; + tcp_connect_queue_skb(sk, syn_data); - if (skb_add_data(syn_data, from, len)) - goto fallback; - } + err = tcp_transmit_skb(sk, syn_data, 1, sk->sk_allocation); - /* Queue a data-only packet after the regular SYN for retransmission */ - data = pskb_copy(syn_data, sk->sk_allocation); - if (data == NULL) - goto fallback; - TCP_SKB_CB(data)->seq++; - TCP_SKB_CB(data)->tcp_flags &= ~TCPHDR_SYN; - TCP_SKB_CB(data)->tcp_flags = (TCPHDR_ACK|TCPHDR_PSH); - tcp_connect_queue_skb(sk, data); - fo->copied = data->len; - - /* syn_data is about to be sent, we need to take current time stamps - * for the packets that are in write queue : SYN packet and DATA - */ - skb_mstamp_get(&syn->skb_mstamp); - data->skb_mstamp = syn->skb_mstamp; + syn->skb_mstamp = syn_data->skb_mstamp; - if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { + /* Now full SYN+DATA was cloned and sent (or not), + * remove the SYN from the original skb (syn_data) + * we keep in write queue in case of a retransmit, as we + * also have the SYN packet (with no data) in the same queue. + */ + TCP_SKB_CB(syn_data)->seq++; + TCP_SKB_CB(syn_data)->tcp_flags = TCPHDR_ACK | TCPHDR_PSH; + if (!err) { tp->syn_data = (fo->copied > 0); NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPORIGDATASENT); goto done; } - syn_data = NULL; fallback: /* Send a regular SYN with Fast Open cookie request option */ @@ -3094,7 +3086,6 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) err = tcp_transmit_skb(sk, syn, 1, sk->sk_allocation); if (err) tp->syn_fastopen = 0; - kfree_skb(syn_data); done: fo->cookie.len = -1; /* Exclude Fast Open option for SYN retries */ return err; @@ -3114,13 +3105,10 @@ int tcp_connect(struct sock *sk) return 0; } - buff = alloc_skb_fclone(MAX_TCP_HEADER + 15, sk->sk_allocation); - if (unlikely(buff == NULL)) + buff = sk_stream_alloc_skb(sk, 0, sk->sk_allocation); + if (unlikely(!buff)) return -ENOBUFS; - /* Reserve space for headers. */ - skb_reserve(buff, MAX_TCP_HEADER); - tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN); tp->retrans_stamp = tcp_time_stamp; tcp_connect_queue_skb(sk, buff); -- GitLab From 233b36cf1f83ef4a7b3670ffa5eeac1ed9d41889 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Tue, 18 Nov 2014 09:46:59 +0100 Subject: [PATCH 5374/9457] stmmac: update driver documentation Recently many changes have been done inside the driver so this patch updates the driver's doc for example reviewing information for the rx and tx processes that are managed by napi method, adding new information for missing glue-logic files etc. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- Documentation/networking/stmmac.txt | 132 ++++++++++++++-------------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index 2090895b08d4..e655e2453c98 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -1,12 +1,12 @@ STMicroelectronics 10/100/1000 Synopsys Ethernet driver -Copyright (C) 2007-2013 STMicroelectronics Ltd +Copyright (C) 2007-2014 STMicroelectronics Ltd Author: Giuseppe Cavallaro This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers (Synopsys IP blocks). -Currently this network device driver is for all STM embedded MAC/GMAC +Currently this network device driver is for all STi embedded MAC/GMAC (i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000 FF1152AMT0221 D1215994A VIRTEX FPGA board. @@ -22,6 +22,9 @@ The kernel configuration option is STMMAC_ETH: Device Drivers ---> Network device support ---> Ethernet (1000 Mbit) ---> STMicroelectronics 10/100/1000 Ethernet driver (STMMAC_ETH) +CONFIG_STMMAC_PLATFORM: is to enable the platform driver. +CONFIG_STMMAC_PCI: is to enable the pci driver. + 2) Driver parameters list: debug: message level (0: no output, 16: all); phyaddr: to manually provide the physical address to the PHY device; @@ -45,10 +48,11 @@ Driver parameters can be also passed in command line by using: The xmit method is invoked when the kernel needs to transmit a packet; it sets the descriptors in the ring and informs the DMA engine that there is a packet ready to be transmitted. -Once the controller has finished transmitting the packet, an interrupt is -triggered; So the driver will be able to release the socket buffers. By default, the driver sets the NETIF_F_SG bit in the features field of the -net_device structure enabling the scatter/gather feature. +net_device structure enabling the scatter-gather feature. This is true on +chips and configurations where the checksum can be done in hardware. +Once the controller has finished transmitting the packet, napi will be +scheduled to release the transmit resources. 4.2) Receive process When one or more packets are received, an interrupt happens. The interrupts @@ -58,20 +62,12 @@ This is based on NAPI so the interrupt handler signals only if there is work to be done, and it exits. Then the poll method will be scheduled at some future point. The incoming packets are stored, by the DMA, in a list of pre-allocated socket -buffers in order to avoid the memcpy (Zero-copy). +buffers in order to avoid the memcpy (zero-copy). 4.3) Interrupt Mitigation The driver is able to mitigate the number of its DMA interrupts using NAPI for the reception on chips older than the 3.50. New chips have an HW RX-Watchdog used for this mitigation. - -On Tx-side, the mitigation schema is based on a SW timer that calls the -tx function (stmmac_tx) to reclaim the resource after transmitting the -frames. -Also there is another parameter (like a threshold) used to program -the descriptors avoiding to set the interrupt on completion bit in -when the frame is sent (xmit). - Mitigation parameters can be tuned by ethtool. 4.4) WOL @@ -79,7 +75,7 @@ Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC core. 4.5) DMA descriptors -Driver handles both normal and enhanced descriptors. The latter has been only +Driver handles both normal and alternate descriptors. The latter has been only tested on DWC Ether MAC 10/100/1000 Universal version 3.41a and later. STMMAC supports DMA descriptor to operate both in dual buffer (RING) @@ -91,9 +87,20 @@ In CHAINED mode each descriptor will have pointer to next descriptor in the list, hence creating the explicit chaining in the descriptor itself, whereas such explicit chaining is not possible in RING mode. +4.5.1) Extended descriptors + The extended descriptors give us information about the Ethernet payload + when it is carrying PTP packets or TCP/UDP/ICMP over IP. + These are not available on GMAC Synopsys chips older than the 3.50. + At probe time the driver will decide if these can be actually used. + This support also is mandatory for PTPv2 because the extra descriptors + are used for saving the hardware timestamps and Extended Status. + 4.6) Ethtool support -Ethtool is supported. Driver statistics and internal errors can be taken using: -ethtool -S ethX command. It is possible to dump registers etc. +Ethtool is supported. + +For example, driver statistics (including RMON), internal errors can be taken +using: + # ethtool -S ethX command 4.7) Jumbo and Segmentation Offloading Jumbo frames are supported and tested for the GMAC. @@ -101,12 +108,11 @@ The GSO has been also added but it's performed in software. LRO is not supported. 4.8) Physical -The driver is compatible with PAL to work with PHY and GPHY devices. +The driver is compatible with Physical Abstraction Layer to be connected with +PHY and GPHY devices. 4.9) Platform information -Several driver's information can be passed through the platform -These are included in the include/linux/stmmac.h header file -and detailed below as well: +Several information can be passed through the platform and device-tree. struct plat_stmmacenet_data { char *phy_bus_name; @@ -125,15 +131,18 @@ struct plat_stmmacenet_data { int force_sf_dma_mode; int force_thresh_dma_mode; int riwt_off; + int max_speed; + int maxmtu; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); void *(*setup)(struct platform_device *pdev); + void (*free)(struct platform_device *pdev, void *priv); int (*init)(struct platform_device *pdev, void *priv); void (*exit)(struct platform_device *pdev, void *priv); void *custom_cfg; void *custom_data; void *bsp_priv; - }; +}; Where: o phy_bus_name: phy bus name to attach to the stmmac. @@ -258,32 +267,43 @@ and the second one, with a real PHY device attached to the bus, by using the stmmac_mdio_bus_data structure (to provide the id, the reset procedure etc). -4.10) List of source files: - o Kconfig - o Makefile - o stmmac_main.c: main network device driver; - o stmmac_mdio.c: mdio functions; - o stmmac_pci: PCI driver; - o stmmac_platform.c: platform driver - o stmmac_ethtool.c: ethtool support; - o stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts - (only tested on ST40 platforms based); +Note that, starting from new chips, where it is available the HW capability +register, many configurations are discovered at run-time for example to +understand if EEE, HW csum, PTP, enhanced descriptor etc are actually +available. As strategy adopted in this driver, the information from the HW +capability register can replace what has been passed from the platform. + +4.10) Device-tree support. + +Please see the following document: + Documentation/devicetree/bindings/net/stmmac.txt + +and the stmmac_of_data structure inside the include/linux/stmmac.h header file. + +4.11) This is a summary of the content of some relevant files: + o stmmac_main.c: to implement the main network device driver; + o stmmac_mdio.c: to provide mdio functions; + o stmmac_pci: this the PCI driver; + o stmmac_platform.c: this the platform driver (OF supported) + o stmmac_ethtool.c: to implement the ethtool support; o stmmac.h: private driver structure; o common.h: common definitions and VFTs; o descs.h: descriptor structure definitions; - o dwmac1000_core.c: GMAC core functions; - o dwmac1000_dma.c: dma functions for the GMAC chip; - o dwmac1000.h: specific header file for the GMAC; - o dwmac100_core: MAC 100 core and dma code; - o dwmac100_dma.c: dma functions for the MAC chip; + o dwmac1000_core.c: dwmac GiGa core functions; + o dwmac1000_dma.c: dma functions for the GMAC chip; + o dwmac1000.h: specific header file for the dwmac GiGa; + o dwmac100_core: dwmac 100 core code; + o dwmac100_dma.c: dma functions for the dwmac 100 chip; o dwmac1000.h: specific header file for the MAC; - o dwmac_lib.c: generic DMA functions shared among chips; + o dwmac_lib.c: generic DMA functions; o enh_desc.c: functions for handling enhanced descriptors; o norm_desc.c: functions for handling normal descriptors; o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes; o mmc_core.c/mmc.h: Management MAC Counters; - o stmmac_hwtstamp.c: HW timestamp support for PTP - o stmmac_ptp.c: PTP 1588 clock + o stmmac_hwtstamp.c: HW timestamp support for PTP; + o stmmac_ptp.c: PTP 1588 clock; + o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c + for STMicroelectronics SoCs. 5) Debug Information @@ -298,23 +318,14 @@ to get statistics: e.g. using: ethtool -S ethX (that shows the Management counters (MMC) if supported) or sees the MAC/DMA registers: e.g. using: ethtool -d ethX -Compiling the Kernel with CONFIG_DEBUG_FS and enabling the -STMMAC_DEBUG_FS option the driver will export the following +Compiling the Kernel with CONFIG_DEBUG_FS the driver will export the following debugfs entries: /sys/kernel/debug/stmmaceth/descriptors_status To show the DMA TX/RX descriptor rings -Developer can also use the "debug" module parameter to get -further debug information. - -In the end, there are other macros (that cannot be enabled -via menuconfig) to turn-on the RX/TX DMA debugging, -specific MAC core debug printk etc. Others to enable the -debug in the TX and RX processes. -All these are only useful during the developing stage -and should never enabled inside the code for general usage. -In fact, these can generate an huge amount of debug messages. +Developer can also use the "debug" module parameter to get further debug +information (please see: NETIF Msg Level). 6) Energy Efficient Ethernet @@ -337,15 +348,7 @@ To enter in Tx LPI mode the driver needs to have a software timer that enable and disable the LPI mode when there is nothing to be transmitted. -7) Extended descriptors -The extended descriptors give us information about the receive Ethernet payload -when it is carrying PTP packets or TCP/UDP/ICMP over IP. -These are not available on GMAC Synopsys chips older than the 3.50. -At probe time the driver will decide if these can be actually used. -This support also is mandatory for PTPv2 because the extra descriptors 6 and 7 -are used for saving the hardware timestamps. - -8) Precision Time Protocol (PTP) +7) Precision Time Protocol (PTP) The driver supports the IEEE 1588-2002, Precision Time Protocol (PTP), which enables precise synchronization of clocks in measurement and control systems implemented with technologies such as network @@ -355,7 +358,7 @@ In addition to the basic timestamp features mentioned in IEEE 1588-2002 Timestamps, new GMAC cores support the advanced timestamp features. IEEE 1588-2008 that can be enabled when configure the Kernel. -9) SGMII/RGMII supports +8) SGMII/RGMII supports New GMAC devices provide own way to manage RGMII/SGMII. This information is available at run-time by looking at the HW capability register. This means that the stmmac can manage @@ -364,8 +367,3 @@ In fact, the HW provides a subset of extended registers to restart the ANE, verify Full/Half duplex mode and Speed. Also thanks to these registers it is possible to look at the Auto-negotiated Link Parter Ability. - -10) TODO: - o XGMAC is not supported. - o Complete the TBI & RTBI support. - o extend VLAN support for 3.70a SYNP GMAC. -- GitLab From 915c199fc8cde9f9a5af19c1ea8c7c3c075d60e1 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Tue, 18 Nov 2014 09:47:00 +0100 Subject: [PATCH 5375/9457] stmmac: document common header file This patch adds some useful comments inside the common header file to provide information about the APIs exposed by the driver. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/common.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 12a174e01d56..cd77289c3cfe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -44,6 +44,7 @@ #undef FRAME_FILTER_DEBUG /* #define FRAME_FILTER_DEBUG */ +/* Extra statistic and debug information exposed by ethtool */ struct stmmac_extra_stats { /* Transmit errors */ unsigned long tx_underflow ____cacheline_aligned; @@ -220,6 +221,7 @@ enum dma_irq_status { handle_tx = 0x8, }; +/* EEE and LPI defines */ #define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 0) #define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 1) #define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 2) @@ -229,6 +231,7 @@ enum dma_irq_status { #define CORE_PCS_LINK_STATUS (1 << 6) #define CORE_RGMII_IRQ (1 << 7) +/* Physical Coding Sublayer */ struct rgmii_adv { unsigned int pause; unsigned int duplex; @@ -294,6 +297,7 @@ struct dma_features { #define JUMBO_LEN 9000 +/* Descriptors helpers */ struct stmmac_desc_ops { /* DMA RX descriptor ring initialization */ void (*init_rx_desc) (struct dma_desc *p, int disable_rx_ic, int mode, @@ -344,6 +348,7 @@ struct stmmac_desc_ops { extern const struct stmmac_desc_ops enh_desc_ops; extern const struct stmmac_desc_ops ndesc_ops; +/* Specific DMA helpers */ struct stmmac_dma_ops { /* DMA core initialization */ int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb, @@ -373,6 +378,7 @@ struct stmmac_dma_ops { struct mac_device_info; +/* Helpers to program the MAC core */ struct stmmac_ops { /* MAC core initialization */ void (*core_init)(struct mac_device_info *hw, int mtu); @@ -403,6 +409,7 @@ struct stmmac_ops { void (*get_adv)(struct mac_device_info *hw, struct rgmii_adv *adv); }; +/* PTP and HW Timer helpers */ struct stmmac_hwtimestamp { void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data); void (*config_sub_second_increment) (void __iomem *ioaddr); @@ -426,6 +433,7 @@ struct mii_regs { unsigned int data; /* MII Data */ }; +/* Helpers to manage the descriptors for chain and ring modes */ struct stmmac_mode_ops { void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, unsigned int extend_desc); -- GitLab From 732fdf0e5253e9d3687d332630e8468a701bebb2 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Tue, 18 Nov 2014 09:47:01 +0100 Subject: [PATCH 5376/9457] stmmac: review driver when run kernel-doc When run ./scripts/kernel-doc several warnings are reported so this patch fix them. Also it reviews many comments and adds new ones. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-sti.c | 15 +- .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 151 ++++++++++++------ .../ethernet/stmicro/stmmac/stmmac_platform.c | 43 ++++- 4 files changed, 142 insertions(+), 69 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c index ea4069276444..0e137751e76e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c @@ -1,4 +1,4 @@ -/** +/* * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer * * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited @@ -37,9 +37,8 @@ #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \ iface == PHY_INTERFACE_MODE_GMII) -/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) */ - -/** +/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) + * * Below table summarizes the clock requirement and clock sources for * supported phy interface modes with link speeds. * ________________________________________________ @@ -78,9 +77,7 @@ #define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) #define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125 BIT(6) -/* STiD127 register definitions */ - -/** +/* STiD127 register definitions *----------------------- * src |BIT(6)| BIT(7)| *----------------------- @@ -106,13 +103,13 @@ #define EN_MASK GENMASK(1, 1) #define EN BIT(1) -/** +/* * 3 bits [4:2] * 000-GMII/MII * 001-RGMII * 010-SGMII * 100-RMII -*/ + */ #define MII_PHY_SEL_MASK GENMASK(4, 2) #define ETH_PHY_SEL_RMII BIT(4) #define ETH_PHY_SEL_SGMII BIT(3) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c index a26bda274c66..c5ea9ab75b03 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c @@ -1,4 +1,4 @@ -/** +/* * dwmac-sunxi.c - Allwinner sunxi DWMAC specific glue layer * * Copyright (C) 2013 Chen-Yu Tsai diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 0f1c146fcce1..118a427d1942 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -125,8 +125,8 @@ static void stmmac_exit_fs(void); /** * stmmac_verify_args - verify the driver parameters. - * Description: it verifies if some wrong parameter is passed to the driver. - * Note that wrong parameters are replaced with the default values. + * Description: it checks the driver parameters and set a default in case of + * errors. */ static void stmmac_verify_args(void) { @@ -204,7 +204,7 @@ static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) } /** - * stmmac_hw_fix_mac_speed: callback for speed selection + * stmmac_hw_fix_mac_speed - callback for speed selection * @priv: driver private structure * Description: on some platforms (e.g. ST), some HW system configuraton * registers have to be set according to the link speed negotiated. @@ -218,9 +218,10 @@ static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) } /** - * stmmac_enable_eee_mode: Check and enter in LPI mode + * stmmac_enable_eee_mode - check and enter in LPI mode * @priv: driver private structure - * Description: this function is to verify and enter in LPI mode for EEE. + * Description: this function is to verify and enter in LPI mode in case of + * EEE. */ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) { @@ -231,7 +232,7 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) } /** - * stmmac_disable_eee_mode: disable/exit from EEE + * stmmac_disable_eee_mode - disable and exit from LPI mode * @priv: driver private structure * Description: this function is to exit and disable EEE in case of * LPI state is true. This is called by the xmit. @@ -244,7 +245,7 @@ void stmmac_disable_eee_mode(struct stmmac_priv *priv) } /** - * stmmac_eee_ctrl_timer: EEE TX SW timer. + * stmmac_eee_ctrl_timer - EEE TX SW timer. * @arg : data hook * Description: * if there is no data transfer and if we are not in LPI state, @@ -259,13 +260,12 @@ static void stmmac_eee_ctrl_timer(unsigned long arg) } /** - * stmmac_eee_init: init EEE + * stmmac_eee_init - init EEE * @priv: driver private structure * Description: - * If the EEE support has been enabled while configuring the driver, - * if the GMAC actually supports the EEE (from the HW cap reg) and the - * phy can also manage EEE, so enable the LPI state and start the timer - * to verify if the tx path can enter in LPI state. + * if the GMAC supports the EEE (from the HW cap reg) and the phy device + * can also manage EEE, this function enable the LPI state and start related + * timer. */ bool stmmac_eee_init(struct stmmac_priv *priv) { @@ -332,7 +332,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv) return ret; } -/* stmmac_get_tx_hwtstamp: get HW TX timestamps +/* stmmac_get_tx_hwtstamp - get HW TX timestamps * @priv: driver private structure * @entry : descriptor index to be used. * @skb : the socket buffer @@ -374,7 +374,7 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, return; } -/* stmmac_get_rx_hwtstamp: get HW RX timestamps +/* stmmac_get_rx_hwtstamp - get HW RX timestamps * @priv: driver private structure * @entry : descriptor index to be used. * @skb : the socket buffer @@ -630,11 +630,11 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) } /** - * stmmac_init_ptp: init PTP + * stmmac_init_ptp - init PTP * @priv: driver private structure - * Description: this is to verify if the HW supports the PTPv1 or v2. + * Description: this is to verify if the HW supports the PTPv1 or PTPv2. * This is done by looking at the HW cap. register. - * Also it registers the ptp driver. + * This function also registers the ptp driver. */ static int stmmac_init_ptp(struct stmmac_priv *priv) { @@ -676,9 +676,13 @@ static void stmmac_release_ptp(struct stmmac_priv *priv) } /** - * stmmac_adjust_link + * stmmac_adjust_link - adjusts the link parameters * @dev: net device structure - * Description: it adjusts the link parameters. + * Description: this is the helper called by the physical abstraction layer + * drivers to communicate the phy link status. According the speed and duplex + * this driver can invoke registered glue-logic as well. + * It also invoke the eee initialization because it could happen when switch + * on different networks (that are eee capable). */ static void stmmac_adjust_link(struct net_device *dev) { @@ -768,7 +772,7 @@ static void stmmac_adjust_link(struct net_device *dev) } /** - * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported + * stmmac_check_pcs_mode - verify if RGMII/SGMII is supported * @priv: driver private structure * Description: this is to verify if the HW supports the PCS. * Physical Coding Sublayer (PCS) interface that can be used when the MAC is @@ -857,7 +861,7 @@ static int stmmac_init_phy(struct net_device *dev) } /** - * stmmac_display_ring: display ring + * stmmac_display_ring - display ring * @head: pointer to the head of the ring passed. * @size: size of the ring. * @extend_desc: to verify if extended descriptors are used. @@ -925,7 +929,7 @@ static int stmmac_set_bfsize(int mtu, int bufsize) } /** - * stmmac_clear_descriptors: clear descriptors + * stmmac_clear_descriptors - clear descriptors * @priv: driver private structure * Description: this function is called to clear the tx and rx descriptors * in case of both basic and extended descriptors are used. @@ -957,6 +961,15 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv) (i == txsize - 1)); } +/** + * stmmac_init_rx_buffers - init the RX descriptor buffer. + * @priv: driver private structure + * @p: descriptor pointer + * @i: descriptor index + * @flags: gfp flag. + * Description: this function is called to allocate a receive buffer, perform + * the DMA mapping and init the descriptor. + */ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, int i, gfp_t flags) { @@ -1001,7 +1014,8 @@ static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) /** * init_dma_desc_rings - init the RX/TX descriptor rings * @dev: net device structure - * Description: this function initializes the DMA RX/TX descriptors + * @flags: gfp flag. + * Description: this function initializes the DMA RX/TX descriptors * and allocates the socket buffers. It suppors the chained and ring * modes. */ @@ -1138,6 +1152,14 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv) } } +/** + * alloc_dma_desc_resources - alloc TX/RX resources. + * @priv: private structure + * Description: according to which descriptor can be used (extend or basic) + * this function allocates the resources for TX and RX paths. In case of + * reception, for example, it pre-allocated the RX socket buffer in order to + * allow zero-copy mechanism. + */ static int alloc_dma_desc_resources(struct stmmac_priv *priv) { unsigned int txsize = priv->dma_tx_size; @@ -1249,8 +1271,8 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) /** * stmmac_dma_operation_mode - HW DMA operation mode * @priv: driver private structure - * Description: it sets the DMA operation mode: tx/rx DMA thresholds - * or Store-And-Forward capability. + * Description: it is used for configuring the DMA operation mode register in + * order to program the tx/rx DMA thresholds or Store-And-Forward mode. */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { @@ -1271,9 +1293,9 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) } /** - * stmmac_tx_clean: + * stmmac_tx_clean - to manage the transmission completion * @priv: driver private structure - * Description: it reclaims resources after transmission completes. + * Description: it reclaims the transmit resources after transmission completes. */ static void stmmac_tx_clean(struct stmmac_priv *priv) { @@ -1372,10 +1394,10 @@ static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) } /** - * stmmac_tx_err: irq tx error mng function + * stmmac_tx_err - to manage the tx error * @priv: driver private structure * Description: it cleans the descriptors and restarts the transmission - * in case of errors. + * in case of transmission errors. */ static void stmmac_tx_err(struct stmmac_priv *priv) { @@ -1403,12 +1425,11 @@ static void stmmac_tx_err(struct stmmac_priv *priv) } /** - * stmmac_dma_interrupt: DMA ISR + * stmmac_dma_interrupt - DMA ISR * @priv: driver private structure * Description: this is the DMA ISR. It is called by the main ISR. - * It calls the dwmac dma routine to understand which type of interrupt - * happened. In case of there is a Normal interrupt and either TX or RX - * interrupt happened so the NAPI is scheduled. + * It calls the dwmac dma routine and schedule poll method in case of some + * work can be done. */ static void stmmac_dma_interrupt(struct stmmac_priv *priv) { @@ -1451,6 +1472,12 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) pr_info(" No MAC Management Counters available\n"); } +/** + * stmmac_get_synopsys_id - return the SYINID. + * @priv: driver private structure + * Description: this simple function is to decode and return the SYINID + * starting from the HW core register. + */ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) { u32 hwid = priv->hw->synopsys_uid; @@ -1469,11 +1496,11 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) } /** - * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors + * stmmac_selec_desc_mode - to select among: normal/alternate/extend descriptors * @priv: driver private structure * Description: select the Enhanced/Alternate or Normal descriptors. - * In case of Enhanced/Alternate, it looks at the extended descriptors are - * supported by the HW cap. register. + * In case of Enhanced/Alternate, it checks if the extended descriptors are + * supported by the HW capability register. */ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) { @@ -1495,7 +1522,7 @@ static void stmmac_selec_desc_mode(struct stmmac_priv *priv) } /** - * stmmac_get_hw_features: get MAC capabilities from the HW cap. register. + * stmmac_get_hw_features - get MAC capabilities from the HW cap. register. * @priv: driver private structure * Description: * new GMAC chip generations have a new register to indicate the @@ -1553,7 +1580,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) } /** - * stmmac_check_ether_addr: check if the MAC addr is valid + * stmmac_check_ether_addr - check if the MAC addr is valid * @priv: driver private structure * Description: * it is to verify if the MAC address is valid, in case of failures it @@ -1572,7 +1599,7 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv) } /** - * stmmac_init_dma_engine: DMA init. + * stmmac_init_dma_engine - DMA init. * @priv: driver private structure * Description: * It inits the DMA invoking the specific MAC/GMAC callback. @@ -1601,7 +1628,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) } /** - * stmmac_tx_timer: mitigation sw timer for tx. + * stmmac_tx_timer - mitigation sw timer for tx. * @data: data pointer * Description: * This is the timer handler to directly invoke the stmmac_tx_clean. @@ -1614,7 +1641,7 @@ static void stmmac_tx_timer(unsigned long data) } /** - * stmmac_init_tx_coalesce: init tx mitigation options. + * stmmac_init_tx_coalesce - init tx mitigation options. * @priv: driver private structure * Description: * This inits the transmit coalesce parameters: i.e. timer rate, @@ -1633,10 +1660,13 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) } /** - * stmmac_hw_setup: setup mac in a usable state. + * stmmac_hw_setup - setup mac in a usable state. * @dev : pointer to the device structure. * Description: - * This function sets up the ip in a usable state. + * this is the main function to setup the HW in a usable state because the + * dma engine is reset, the core registers are configured (e.g. AXI, + * Checksum features, timers). The DMA is ready to start receiving and + * transmitting. * Return value: * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. @@ -1874,7 +1904,7 @@ static int stmmac_release(struct net_device *dev) } /** - * stmmac_xmit: Tx entry point of the driver + * stmmac_xmit - Tx entry point of the driver * @skb : the socket buffer * @dev : device pointer * Description : this is the tx entry point of the driver. @@ -2049,7 +2079,7 @@ static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) /** - * stmmac_rx_refill: refill used skb preallocated buffers + * stmmac_rx_refill - refill used skb preallocated buffers * @priv: driver private structure * Description : this is to reallocate the skb for the reception process * that is based on zero-copy. @@ -2100,7 +2130,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) } /** - * stmmac_rx_refill: refill used skb preallocated buffers + * stmmac_rx - manage the receive process * @priv: driver private structure * @limit: napi bugget. * Description : this the function called by the napi poll method. @@ -2369,8 +2399,11 @@ static int stmmac_set_features(struct net_device *netdev, * @irq: interrupt number. * @dev_id: to pass the net device pointer. * Description: this is the main driver interrupt service routine. - * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI - * interrupts. + * It can call: + * o DMA service routine (to manage incoming frame reception and transmission + * status) + * o Core interrupts to manage: remote wake-up, management counter, LPI + * interrupts. */ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) { @@ -2657,11 +2690,10 @@ static const struct net_device_ops stmmac_netdev_ops = { /** * stmmac_hw_init - Init the MAC device * @priv: driver private structure - * Description: this function detects which MAC device - * (GMAC/MAC10-100) has to attached, checks the HW capability - * (if supported) and sets the driver's features (for example - * to use the ring or chaine mode or support the normal/enh - * descriptor structure). + * Description: this function is to configure the MAC device according to + * some platform parameters or the HW capability register. It prepares the + * driver to use either ring or chain modes and to setup either enhanced or + * normal descriptors. */ static int stmmac_hw_init(struct stmmac_priv *priv) { @@ -2917,6 +2949,13 @@ int stmmac_dvr_remove(struct net_device *ndev) } EXPORT_SYMBOL_GPL(stmmac_dvr_remove); +/** + * stmmac_suspend - suspend callback + * @ndev: net device pointer + * Description: this is the function to suspend the device and it is called + * by the platform driver to stop the network queue, release the resources, + * program the PMT register (for WoL), clean and release driver resources. + */ int stmmac_suspend(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); @@ -2960,6 +2999,12 @@ int stmmac_suspend(struct net_device *ndev) } EXPORT_SYMBOL_GPL(stmmac_suspend); +/** + * stmmac_resume - resume callback + * @ndev: net device pointer + * Description: when resume this function is invoked to setup the DMA and CORE + * in a usable state. + */ int stmmac_resume(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index e22a960f8bd7..15814b79ff10 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -51,7 +51,11 @@ MODULE_DEVICE_TABLE(of, stmmac_dt_ids); #ifdef CONFIG_OF -/* This function validates the number of Multicast filtering bins specified +/** + * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins + * @mcast_bins: Multicast filtering bins + * Description: + * this function validates the number of Multicast filtering bins specified * by the configuration through the device tree. The Synopsys GMAC supports * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds @@ -77,7 +81,11 @@ static int dwmac1000_validate_mcast_bins(int mcast_bins) return x; } -/* This function validates the number of Unicast address entries supported +/** + * dwmac1000_validate_ucast_entries - validate the Unicast address entries + * @ucast_entries: number of Unicast address entries + * Description: + * This function validates the number of Unicast address entries supported * by a particular Synopsys 10/100/1000 controller. The Synopsys controller * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter * logic. This function validates a valid, supported configuration is @@ -103,6 +111,15 @@ static int dwmac1000_validate_ucast_entries(int ucast_entries) return x; } +/** + * stmmac_probe_config_dt - parse device-tree driver parameters + * @pdev: platform_device structure + * @plat: driver data platform structure + * @mac: MAC address to use + * Description: + * this function is to read the driver parameters from device-tree and + * set some private fields that will be used by the main at runtime. + */ static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) @@ -242,11 +259,11 @@ static int stmmac_probe_config_dt(struct platform_device *pdev, #endif /* CONFIG_OF */ /** - * stmmac_pltfr_probe + * stmmac_pltfr_probe - platform driver probe. * @pdev: platform device pointer - * Description: platform_device probe function. It allocates - * the necessary resources and invokes the main to init - * the net device, register the mdio bus etc. + * Description: platform_device probe function. It is to allocate + * the necessary platform resources, invoke custom helper (if required) and + * invoke the main probe function. */ static int stmmac_pltfr_probe(struct platform_device *pdev) { @@ -363,6 +380,13 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP +/** + * stmmac_pltfr_suspend + * @dev: device pointer + * Description: this function is invoked when suspend the driver and it direcly + * call the main suspend function and then, if required, on some platform, it + * can call an exit helper. + */ static int stmmac_pltfr_suspend(struct device *dev) { int ret; @@ -377,6 +401,13 @@ static int stmmac_pltfr_suspend(struct device *dev) return ret; } +/** + * stmmac_pltfr_resume + * @dev: device pointer + * Description: this function is invoked when resume the driver before calling + * the main resume function, on some platforms, it can call own init helper + * if required. + */ static int stmmac_pltfr_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); -- GitLab From 5fabcb4c33fe11c7e3afdf805fde26c1a54d0953 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 19 Nov 2014 13:06:22 -0700 Subject: [PATCH 5377/9457] genhd: check for int overflow in disk_expand_part_tbl() We can get here from blkdev_ioctl() -> blkpg_ioctl() -> add_partition() with a user passed in partno value. If we pass in 0x7fffffff, the new target in disk_expand_part_tbl() overflows the 'int' and we access beyond the end of ptbl->part[] and even write to it when we do the rcu_assign_pointer() to assign the new partition. Reported-by: David Ramos Cc: stable@kernel.org Signed-off-by: Jens Axboe --- block/genhd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index bd3060684ab2..0a536dc05f3b 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1070,9 +1070,16 @@ int disk_expand_part_tbl(struct gendisk *disk, int partno) struct disk_part_tbl *old_ptbl = disk->part_tbl; struct disk_part_tbl *new_ptbl; int len = old_ptbl ? old_ptbl->len : 0; - int target = partno + 1; + int i, target; size_t size; - int i; + + /* + * check for int overflow, since we can get here from blkpg_ioctl() + * with a user passed 'partno'. + */ + target = partno + 1; + if (target < 0) + return -EINVAL; /* disk_max_parts() is zero during initialization, ignore if so */ if (disk_max_parts(disk) && target > disk_max_parts(disk)) -- GitLab From 1abe7cd91a994a214650d7dec0bd03e6ebc95913 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 18 Nov 2014 21:55:21 +0530 Subject: [PATCH 5378/9457] usbnet: rtl8150: remove unused variable remove unused variable Signed-off-by: Sudip Mukherjee Signed-off-by: David S. Miller --- drivers/net/usb/rtl8150.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 6e87e5710048..d37b7dce2d40 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -753,14 +753,13 @@ static int rtl8150_open(struct net_device *netdev) static int rtl8150_close(struct net_device *netdev) { rtl8150_t *dev = netdev_priv(netdev); - int res = 0; netif_stop_queue(netdev); if (!test_bit(RTL8150_UNPLUG, &dev->flags)) disable_net_traffic(dev); unlink_all_urbs(dev); - return res; + return 0; } static void rtl8150_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) -- GitLab From 5c6c600354adac5f95fd41b178b084ac0182e14c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 6 Sep 2014 10:28:27 +0100 Subject: [PATCH 5379/9457] drm/i915: Remove DRI1 ring accessors and API With the deprecation of UMS, and by association DRI1, we have a tough choice when updating the ring access routines. We either rewrite the DRI1 routines blindly without testing (so likely to be broken) or take the liberty of declaring them no longer supported and remove them entirely. This takes the latter approach. v2: Also remove the DRI1 sarea updates Signed-off-by: Chris Wilson [danvet: Fix rebase conflicts.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 931 +-------------------- drivers/gpu/drm/i915/i915_drv.c | 2 - drivers/gpu/drm/i915/i915_drv.h | 27 - drivers/gpu/drm/i915/i915_gem.c | 4 - drivers/gpu/drm/i915/i915_gem_execbuffer.c | 43 +- drivers/gpu/drm/i915/i915_irq.c | 6 - drivers/gpu/drm/i915/intel_display.c | 35 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 104 +-- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 - 9 files changed, 62 insertions(+), 1093 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 56f62112411a..d1562281e607 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -50,883 +50,58 @@ #include #include -#define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS]) - -#define BEGIN_LP_RING(n) \ - intel_ring_begin(LP_RING(dev_priv), (n)) - -#define OUT_RING(x) \ - intel_ring_emit(LP_RING(dev_priv), x) - -#define ADVANCE_LP_RING() \ - __intel_ring_advance(LP_RING(dev_priv)) - -/** - * Lock test for when it's just for synchronization of ring access. - * - * In that case, we don't need to do it when GEM is initialized as nobody else - * has access to the ring. - */ -#define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ - if (LP_RING(dev->dev_private)->buffer->obj == NULL) \ - LOCK_TEST_WITH_RETURN(dev, file); \ -} while (0) - -static inline u32 -intel_read_legacy_status_page(struct drm_i915_private *dev_priv, int reg) -{ - if (I915_NEED_GFX_HWS(dev_priv->dev)) - return ioread32(dev_priv->dri1.gfx_hws_cpu_addr + reg); - else - return intel_read_status_page(LP_RING(dev_priv), reg); -} - -#define READ_HWSP(dev_priv, reg) intel_read_legacy_status_page(dev_priv, reg) -#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) -#define I915_BREADCRUMB_INDEX 0x21 - -void i915_update_dri1_breadcrumb(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - - /* - * The dri breadcrumb update races against the drm master disappearing. - * Instead of trying to fix this (this is by far not the only ums issue) - * just don't do the update in kms mode. - */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } -} - -static void i915_write_hws_pga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 addr; - - addr = dev_priv->status_page_dmah->busaddr; - if (INTEL_INFO(dev)->gen >= 4) - addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; - I915_WRITE(HWS_PGA, addr); -} - -/** - * Frees the hardware status page, whether it's a physical address or a virtual - * address set up by the X Server. - */ -static void i915_free_hws(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = LP_RING(dev_priv); - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - } - - if (ring->status_page.gfx_addr) { - ring->status_page.gfx_addr = 0; - iounmap(dev_priv->dri1.gfx_hws_cpu_addr); - } - - /* Need to rewrite hardware status page */ - I915_WRITE(HWS_PGA, 0x1ffff000); -} - -void i915_kernel_lost_context(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - struct intel_engine_cs *ring = LP_RING(dev_priv); - struct intel_ringbuffer *ringbuf = ring->buffer; - - /* - * We should never lose context on the ring with modesetting - * as we don't expose it to userspace - */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - ringbuf->head = I915_READ_HEAD(ring) & HEAD_ADDR; - ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ringbuf->space = ringbuf->head - (ringbuf->tail + I915_RING_FREE_SPACE); - if (ringbuf->space < 0) - ringbuf->space += ringbuf->size; - - if (!dev->primary->master) - return; - - master_priv = dev->primary->master->driver_priv; - if (ringbuf->head == ringbuf->tail && master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; -} - -static int i915_dma_cleanup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - for (i = 0; i < I915_NUM_RINGS; i++) - intel_cleanup_ring_buffer(&dev_priv->ring[i]); - mutex_unlock(&dev->struct_mutex); - - /* Clear the HWS virtual address at teardown */ - if (I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); - - return 0; -} - -static int i915_initialize(struct drm_device *dev, drm_i915_init_t *init) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - int ret; - - master_priv->sarea = drm_legacy_getsarea(dev); - if (master_priv->sarea) { - master_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); - } else { - DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n"); - } - - if (init->ring_size != 0) { - if (LP_RING(dev_priv)->buffer->obj != NULL) { - i915_dma_cleanup(dev); - DRM_ERROR("Client tried to initialize ringbuffer in " - "GEM mode\n"); - return -EINVAL; - } - - ret = intel_render_ring_init_dri(dev, - init->ring_start, - init->ring_size); - if (ret) { - i915_dma_cleanup(dev); - return ret; - } - } - - dev_priv->dri1.cpp = init->cpp; - dev_priv->dri1.back_offset = init->back_offset; - dev_priv->dri1.front_offset = init->front_offset; - dev_priv->dri1.current_page = 0; - if (master_priv->sarea_priv) - master_priv->sarea_priv->pf_current_page = 0; - - /* Allow hardware batchbuffers unless told otherwise. - */ - dev_priv->dri1.allow_batchbuffer = 1; - - return 0; -} - -static int i915_dma_resume(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = LP_RING(dev_priv); - - DRM_DEBUG_DRIVER("%s\n", __func__); - - if (ring->buffer->virtual_start == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - /* Program Hardware Status Page */ - if (!ring->status_page.page_addr) { - DRM_ERROR("Can not find hardware status page\n"); - return -EINVAL; - } - DRM_DEBUG_DRIVER("hw status page @ %p\n", - ring->status_page.page_addr); - if (ring->status_page.gfx_addr != 0) - intel_ring_setup_status_page(ring); - else - i915_write_hws_pga(dev); - - DRM_DEBUG_DRIVER("Enabled hardware status page\n"); - - return 0; -} - static int i915_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_i915_init_t *init = data; - int retcode = 0; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - switch (init->func) { - case I915_INIT_DMA: - retcode = i915_initialize(dev, init); - break; - case I915_CLEANUP_DMA: - retcode = i915_dma_cleanup(dev); - break; - case I915_RESUME_DMA: - retcode = i915_dma_resume(dev); - break; - default: - retcode = -EINVAL; - break; - } - - return retcode; -} - -/* Implement basically the same security restrictions as hardware does - * for MI_BATCH_NON_SECURE. These can be made stricter at any time. - * - * Most of the calculations below involve calculating the size of a - * particular instruction. It's important to get the size right as - * that tells us where the next instruction to check is. Any illegal - * instruction detected will be given a size of zero, which is a - * signal to abort the rest of the buffer. - */ -static int validate_cmd(int cmd) -{ - switch (((cmd >> 29) & 0x7)) { - case 0x0: - switch ((cmd >> 23) & 0x3f) { - case 0x0: - return 1; /* MI_NOOP */ - case 0x4: - return 1; /* MI_FLUSH */ - default: - return 0; /* disallow everything else */ - } - break; - case 0x1: - return 0; /* reserved */ - case 0x2: - return (cmd & 0xff) + 2; /* 2d commands */ - case 0x3: - if (((cmd >> 24) & 0x1f) <= 0x18) - return 1; - - switch ((cmd >> 24) & 0x1f) { - case 0x1c: - return 1; - case 0x1d: - switch ((cmd >> 16) & 0xff) { - case 0x3: - return (cmd & 0x1f) + 2; - case 0x4: - return (cmd & 0xf) + 2; - default: - return (cmd & 0xffff) + 2; - } - case 0x1e: - if (cmd & (1 << 23)) - return (cmd & 0xffff) + 1; - else - return 1; - case 0x1f: - if ((cmd & (1 << 23)) == 0) /* inline vertices */ - return (cmd & 0x1ffff) + 2; - else if (cmd & (1 << 17)) /* indirect random */ - if ((cmd & 0xffff) == 0) - return 0; /* unknown length, too hard */ - else - return (((cmd & 0xffff) + 1) / 2) + 1; - else - return 2; /* indirect sequential */ - default: - return 0; - } - default: - return 0; - } - - return 0; -} - -static int i915_emit_cmds(struct drm_device *dev, int *buffer, int dwords) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i, ret; - - if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->buffer->size - 8) - return -EINVAL; - - for (i = 0; i < dwords;) { - int sz = validate_cmd(buffer[i]); - - if (sz == 0 || i + sz > dwords) - return -EINVAL; - i += sz; - } - - ret = BEGIN_LP_RING((dwords+1)&~1); - if (ret) - return ret; - - for (i = 0; i < dwords; i++) - OUT_RING(buffer[i]); - if (dwords & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); - - return 0; -} - -int -i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *box, - int DR1, int DR4) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (box->y2 <= box->y1 || box->x2 <= box->x1 || - box->y2 <= 0 || box->x2 <= 0) { - DRM_ERROR("Bad box %d,%d..%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - return -EINVAL; - } - - if (INTEL_INFO(dev)->gen >= 4) { - ret = BEGIN_LP_RING(4); - if (ret) - return ret; - - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); - OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); - OUT_RING(DR4); - } else { - ret = BEGIN_LP_RING(6); - if (ret) - return ret; - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(DR1); - OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); - OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); - OUT_RING(DR4); - OUT_RING(0); - } - ADVANCE_LP_RING(); - - return 0; -} - -/* XXX: Emitting the counter should really be moved to part of the IRQ - * emit. For now, do it in both places: - */ - -static void i915_emit_breadcrumb(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - - dev_priv->dri1.counter++; - if (dev_priv->dri1.counter > 0x7FFFFFFFUL) - dev_priv->dri1.counter = 0; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_enqueue = dev_priv->dri1.counter; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->dri1.counter); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static int i915_dispatch_cmdbuffer(struct drm_device *dev, - drm_i915_cmdbuffer_t *cmd, - struct drm_clip_rect *cliprects, - void *cmdbuf) -{ - int nbox = cmd->num_cliprects; - int i = 0, count, ret; - - if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, &cliprects[i], - cmd->DR1, cmd->DR4); - if (ret) - return ret; - } - - ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4); - if (ret) - return ret; - } - - i915_emit_breadcrumb(dev); - return 0; -} - -static int i915_dispatch_batchbuffer(struct drm_device *dev, - drm_i915_batchbuffer_t *batch, - struct drm_clip_rect *cliprects) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int nbox = batch->num_cliprects; - int i, count, ret; - - if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, &cliprects[i], - batch->DR1, batch->DR4); - if (ret) - return ret; - } - - if (!IS_I830(dev) && !IS_845G(dev)) { - ret = BEGIN_LP_RING(2); - if (ret) - return ret; - - if (INTEL_INFO(dev)->gen >= 4) { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); - OUT_RING(batch->start); - } else { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - } - } else { - ret = BEGIN_LP_RING(4); - if (ret) - return ret; - - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - OUT_RING(batch->start + batch->used - 4); - OUT_RING(0); - } - ADVANCE_LP_RING(); - } - - - if (IS_G4X(dev) || IS_GEN5(dev)) { - if (BEGIN_LP_RING(2) == 0) { - OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - } - } - - i915_emit_breadcrumb(dev); - return 0; -} - -static int i915_dispatch_flip(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = - dev->primary->master->driver_priv; - int ret; - - if (!master_priv->sarea_priv) - return -EINVAL; - - DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n", - __func__, - dev_priv->dri1.current_page, - master_priv->sarea_priv->pf_current_page); - - i915_kernel_lost_context(dev); - - ret = BEGIN_LP_RING(10); - if (ret) - return ret; - - OUT_RING(MI_FLUSH | MI_READ_FLUSH); - OUT_RING(0); - - OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); - OUT_RING(0); - if (dev_priv->dri1.current_page == 0) { - OUT_RING(dev_priv->dri1.back_offset); - dev_priv->dri1.current_page = 1; - } else { - OUT_RING(dev_priv->dri1.front_offset); - dev_priv->dri1.current_page = 0; - } - OUT_RING(0); - - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - - ADVANCE_LP_RING(); - - master_priv->sarea_priv->last_enqueue = dev_priv->dri1.counter++; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->dri1.counter); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - master_priv->sarea_priv->pf_current_page = dev_priv->dri1.current_page; - return 0; -} - -static int i915_quiescent(struct drm_device *dev) -{ - i915_kernel_lost_context(dev); - return intel_ring_idle(LP_RING(dev->dev_private)); + return -ENODEV; } static int i915_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_quiescent(dev); - mutex_unlock(&dev->struct_mutex); - - return ret; + return -ENODEV; } static int i915_batchbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - drm_i915_sarea_t *sarea_priv; - drm_i915_batchbuffer_t *batch = data; - int ret; - struct drm_clip_rect *cliprects = NULL; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - master_priv = dev->primary->master->driver_priv; - sarea_priv = (drm_i915_sarea_t *) master_priv->sarea_priv; - - if (!dev_priv->dri1.allow_batchbuffer) { - DRM_ERROR("Batchbuffer ioctl disabled\n"); - return -EINVAL; - } - - DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n", - batch->start, batch->used, batch->num_cliprects); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (batch->num_cliprects < 0) - return -EINVAL; - - if (batch->num_cliprects) { - cliprects = kcalloc(batch->num_cliprects, - sizeof(*cliprects), - GFP_KERNEL); - if (cliprects == NULL) - return -ENOMEM; - - ret = copy_from_user(cliprects, batch->cliprects, - batch->num_cliprects * - sizeof(struct drm_clip_rect)); - if (ret != 0) { - ret = -EFAULT; - goto fail_free; - } - } - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_batchbuffer(dev, batch, cliprects); - mutex_unlock(&dev->struct_mutex); - - if (sarea_priv) - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - -fail_free: - kfree(cliprects); - - return ret; + return -ENODEV; } static int i915_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - drm_i915_sarea_t *sarea_priv; - drm_i915_cmdbuffer_t *cmdbuf = data; - struct drm_clip_rect *cliprects = NULL; - void *batch_data; - int ret; - - DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - master_priv = dev->primary->master->driver_priv; - sarea_priv = (drm_i915_sarea_t *) master_priv->sarea_priv; - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (cmdbuf->num_cliprects < 0) - return -EINVAL; - - batch_data = kmalloc(cmdbuf->sz, GFP_KERNEL); - if (batch_data == NULL) - return -ENOMEM; - - ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); - if (ret != 0) { - ret = -EFAULT; - goto fail_batch_free; - } - - if (cmdbuf->num_cliprects) { - cliprects = kcalloc(cmdbuf->num_cliprects, - sizeof(*cliprects), GFP_KERNEL); - if (cliprects == NULL) { - ret = -ENOMEM; - goto fail_batch_free; - } - - ret = copy_from_user(cliprects, cmdbuf->cliprects, - cmdbuf->num_cliprects * - sizeof(struct drm_clip_rect)); - if (ret != 0) { - ret = -EFAULT; - goto fail_clip_free; - } - } - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data); - mutex_unlock(&dev->struct_mutex); - if (ret) { - DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); - goto fail_clip_free; - } - - if (sarea_priv) - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - -fail_clip_free: - kfree(cliprects); -fail_batch_free: - kfree(batch_data); - - return ret; -} - -static int i915_emit_irq(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - - i915_kernel_lost_context(dev); - - DRM_DEBUG_DRIVER("\n"); - - dev_priv->dri1.counter++; - if (dev_priv->dri1.counter > 0x7FFFFFFFUL) - dev_priv->dri1.counter = 1; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_enqueue = dev_priv->dri1.counter; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->dri1.counter); - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); - } - - return dev_priv->dri1.counter; -} - -static int i915_wait_irq(struct drm_device *dev, int irq_nr) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - int ret = 0; - struct intel_engine_cs *ring = LP_RING(dev_priv); - - DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, - READ_BREADCRUMB(dev_priv)); - - if (READ_BREADCRUMB(dev_priv) >= irq_nr) { - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - return 0; - } - - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - - if (ring->irq_get(ring)) { - DRM_WAIT_ON(ret, ring->irq_queue, 3 * HZ, - READ_BREADCRUMB(dev_priv) >= irq_nr); - ring->irq_put(ring); - } else if (wait_for(READ_BREADCRUMB(dev_priv) >= irq_nr, 3000)) - ret = -EBUSY; - - if (ret == -EBUSY) { - DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", - READ_BREADCRUMB(dev_priv), (int)dev_priv->dri1.counter); - } - - return ret; + return -ENODEV; } -/* Needs the lock as it touches the ring. - */ static int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - drm_i915_irq_emit_t *emit = data; - int result; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (!dev_priv || !LP_RING(dev_priv)->buffer->virtual_start) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - result = i915_emit_irq(dev); - mutex_unlock(&dev->struct_mutex); - - if (copy_to_user(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; + return -ENODEV; } -/* Doesn't need the hardware lock. - */ static int i915_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - drm_i915_irq_wait_t *irqwait = data; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - return i915_wait_irq(dev, irqwait->irq_seq); + return -ENODEV; } static int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t *pipe = data; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - - return 0; + return -ENODEV; } -/** - * Schedule buffer swap at given vertical blank. - */ static int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - /* The delayed swap mechanism was fundamentally racy, and has been - * removed. The model was that the client requested a delayed flip/swap - * from the kernel, then waited for vblank before continuing to perform - * rendering. The problem was that the kernel might wake the client - * up before it dispatched the vblank swap (since the lock has to be - * held while touching the ringbuffer), in which case the client would - * clear and start the next frame before the swap occurred, and - * flicker would occur in addition to likely missing the vblank. - * - * In the absence of this ioctl, userland falls back to a correct path - * of waiting for a vblank, then dispatching the swap on its own. - * Context switching to userland and back is plenty fast enough for - * meeting the requirements of vblank swapping. - */ - return -EINVAL; + return -ENODEV; } static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - DRM_DEBUG_DRIVER("%s\n", __func__); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_flip(dev); - mutex_unlock(&dev->struct_mutex); - - return ret; + return -ENODEV; } static int i915_getparam(struct drm_device *dev, void *data, @@ -943,14 +118,11 @@ static int i915_getparam(struct drm_device *dev, void *data, switch (param->param) { case I915_PARAM_IRQ_ACTIVE: - value = dev->pdev->irq ? 1 : 0; - break; + return -ENODEV; case I915_PARAM_ALLOW_BATCHBUFFER: - value = dev_priv->dri1.allow_batchbuffer ? 1 : 0; - break; + return -ENODEV; case I915_PARAM_LAST_DISPATCH: - value = READ_BREADCRUMB(dev_priv); - break; + return -ENODEV; case I915_PARAM_CHIPSET_ID: value = dev->pdev->device; break; @@ -1056,12 +228,10 @@ static int i915_setparam(struct drm_device *dev, void *data, switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - break; case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv->dri1.allow_batchbuffer = param->value ? 1 : 0; - break; + return -ENODEV; + case I915_SETPARAM_NUM_USED_FENCES: if (param->value > dev_priv->num_fence_regs || param->value < 0) @@ -1081,49 +251,7 @@ static int i915_setparam(struct drm_device *dev, void *data, static int i915_set_status_page(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - drm_i915_hws_addr_t *hws = data; - struct intel_engine_cs *ring; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (!I915_NEED_GFX_HWS(dev)) - return -EINVAL; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - WARN(1, "tried to set status page when mode setting active\n"); - return 0; - } - - DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); - - ring = LP_RING(dev_priv); - ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); - - dev_priv->dri1.gfx_hws_cpu_addr = - ioremap_wc(dev_priv->gtt.mappable_base + hws->addr, 4096); - if (dev_priv->dri1.gfx_hws_cpu_addr == NULL) { - i915_dma_cleanup(dev); - ring->status_page.gfx_addr = 0; - DRM_ERROR("can not ioremap virtual address for" - " G33 hw status page\n"); - return -ENOMEM; - } - - memset_io(dev_priv->dri1.gfx_hws_cpu_addr, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); - - DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", - ring->status_page.gfx_addr); - DRM_DEBUG_DRIVER("load hws at %p\n", - ring->status_page.page_addr); - return 0; + return -ENODEV; } static int i915_get_bridge_dev(struct drm_device *dev) @@ -1401,30 +529,6 @@ static int i915_load_modeset_init(struct drm_device *dev) return ret; } -int i915_master_create(struct drm_device *dev, struct drm_master *master) -{ - struct drm_i915_master_private *master_priv; - - master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); - if (!master_priv) - return -ENOMEM; - - master->driver_priv = master_priv; - return 0; -} - -void i915_master_destroy(struct drm_device *dev, struct drm_master *master) -{ - struct drm_i915_master_private *master_priv = master->driver_priv; - - if (!master_priv) - return; - - kfree(master_priv); - - master->driver_priv = NULL; -} - #if IS_ENABLED(CONFIG_FB) static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) { @@ -1899,9 +1003,6 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); i915_gem_cleanup_stolen(dev); - - if (!I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); } intel_teardown_gmbus(dev); @@ -1966,8 +1067,6 @@ void i915_driver_lastclose(struct drm_device *dev) } i915_gem_lastclose(dev); - - i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 19558d61b032..c9f248acbd69 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1573,8 +1573,6 @@ static struct drm_driver driver = { .resume = i915_resume_legacy, .device_is_agp = i915_driver_device_is_agp, - .master_create = i915_master_create, - .master_destroy = i915_master_destroy, #if defined(CONFIG_DEBUG_FS) .debugfs_init = i915_debugfs_init, .debugfs_cleanup = i915_debugfs_cleanup, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1097d20a4f35..100296475fb4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -327,12 +327,6 @@ struct intel_opregion { struct intel_overlay; struct intel_overlay_error_state; -struct drm_local_map; - -struct drm_i915_master_private { - struct drm_local_map *sarea; - struct _drm_i915_sarea *sarea_priv; -}; #define I915_FENCE_REG_NONE -1 #define I915_MAX_NUM_FENCES 32 /* 32 fences + sign bit for FENCE_REG_NONE */ @@ -1127,19 +1121,6 @@ struct i915_power_domains { struct i915_power_well *power_wells; }; -struct i915_dri1_state { - unsigned allow_batchbuffer : 1; - u32 __iomem *gfx_hws_cpu_addr; - - unsigned int cpp; - int back_offset; - int front_offset; - int current_page; - int page_flipping; - - uint32_t counter; -}; - struct i915_ums_state { /** * Flag if the X Server, and thus DRM, is not currently in @@ -1787,9 +1768,6 @@ struct drm_i915_private { uint32_t bios_vgacntr; - /* Old dri1 support infrastructure, beware the dragons ya fools entering - * here! */ - struct i915_dri1_state dri1; /* Old ums support infrastructure, same warning applies. */ struct i915_ums_state ums; @@ -2351,8 +2329,6 @@ struct i915_params { extern struct i915_params i915 __read_mostly; /* i915_dma.c */ -void i915_update_dri1_breadcrumb(struct drm_device *dev); -extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); extern int i915_driver_open(struct drm_device *dev, struct drm_file *file); @@ -2366,9 +2342,6 @@ extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #endif -extern int i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *box, - int DR1, int DR4); extern int intel_gpu_reset(struct drm_device *dev); extern int i915_reset(struct drm_device *dev); extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7f95d8ff28af..7985f7b28325 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4664,7 +4664,6 @@ i915_gem_suspend(struct drm_device *dev) if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_gem_evict_everything(dev); - i915_kernel_lost_context(dev); i915_gem_stop_ringbuffers(dev); /* Hack! Don't let anybody do execbuf while we don't control the chip. @@ -4963,9 +4962,6 @@ int i915_gem_init(struct drm_device *dev) } mutex_unlock(&dev->struct_mutex); - /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - dev_priv->dri1.allow_batchbuffer = 1; return ret; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e1ed85a6dc6d..b16eee061990 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1020,6 +1020,47 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, return 0; } +static int +i915_emit_box(struct intel_engine_cs *ring, + struct drm_clip_rect *box, + int DR1, int DR4) +{ + int ret; + + if (box->y2 <= box->y1 || box->x2 <= box->x1 || + box->y2 <= 0 || box->x2 <= 0) { + DRM_ERROR("Bad box %d,%d..%d,%d\n", + box->x1, box->y1, box->x2, box->y2); + return -EINVAL; + } + + if (INTEL_INFO(ring->dev)->gen >= 4) { + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_DRAWRECT_INFO_I965); + intel_ring_emit(ring, (box->x1 & 0xffff) | box->y1 << 16); + intel_ring_emit(ring, ((box->x2 - 1) & 0xffff) | (box->y2 - 1) << 16); + intel_ring_emit(ring, DR4); + } else { + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_DRAWRECT_INFO); + intel_ring_emit(ring, DR1); + intel_ring_emit(ring, (box->x1 & 0xffff) | box->y1 << 16); + intel_ring_emit(ring, ((box->x2 - 1) & 0xffff) | (box->y2 - 1) << 16); + intel_ring_emit(ring, DR4); + intel_ring_emit(ring, 0); + } + intel_ring_advance(ring); + + return 0; +} + + int i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, @@ -1148,7 +1189,7 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, exec_len = args->batch_len; if (cliprects) { for (i = 0; i < args->num_cliprects; i++) { - ret = i915_emit_box(dev, &cliprects[i], + ret = i915_emit_box(ring, &cliprects[i], args->DR1, args->DR4); if (ret) goto error; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 283756fe48d3..8d169e152d1e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3764,8 +3764,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) I915_WRITE16(IIR, iir & ~flip_mask); new_iir = I915_READ16(IIR); /* Flush posted writes */ - i915_update_dri1_breadcrumb(dev); - if (iir & I915_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[RCS]); @@ -4002,8 +4000,6 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) iir = new_iir; } while (iir & ~flip_mask); - i915_update_dri1_breadcrumb(dev); - return ret; } @@ -4231,8 +4227,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) iir = new_iir; } - i915_update_dri1_breadcrumb(dev); - return ret; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6060b71d9301..9c983e4c33bd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5185,36 +5185,6 @@ static void i9xx_crtc_off(struct drm_crtc *crtc) { } -static void intel_crtc_update_sarea(struct drm_crtc *crtc, - bool enabled) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_master_private *master_priv; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - - if (!dev->primary->master) - return; - - master_priv = dev->primary->master->driver_priv; - if (!master_priv->sarea_priv) - return; - - switch (pipe) { - case 0: - master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; - master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0; - break; - case 1: - master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0; - master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0; - break; - default: - DRM_ERROR("Can't update pipe %c in SAREA\n", pipe_name(pipe)); - break; - } -} - /* Master function to enable/disable CRTC and corresponding power wells */ void intel_crtc_control(struct drm_crtc *crtc, bool enable) { @@ -5258,8 +5228,6 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc) enable |= intel_encoder->connectors_active; intel_crtc_control(crtc, enable); - - intel_crtc_update_sarea(crtc, enable); } static void intel_crtc_disable(struct drm_crtc *crtc) @@ -5274,7 +5242,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc) WARN_ON(!crtc->enabled); dev_priv->display.crtc_disable(crtc); - intel_crtc_update_sarea(crtc, false); dev_priv->display.off(crtc); if (crtc->primary->fb) { @@ -8369,7 +8336,7 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; unsigned old_width; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0a4f35e735c3..1d01b51ff058 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -589,14 +589,10 @@ static int init_ring_common(struct intel_engine_cs *ring) goto out; } - if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) - i915_kernel_lost_context(ring->dev); - else { - ringbuf->head = I915_READ_HEAD(ring); - ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ringbuf->space = intel_ring_space(ringbuf); - ringbuf->last_retired_head = -1; - } + ringbuf->head = I915_READ_HEAD(ring); + ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR; + ringbuf->space = intel_ring_space(ringbuf); + ringbuf->last_retired_head = -1; memset(&ring->hangcheck, 0, sizeof(ring->hangcheck)); @@ -1958,13 +1954,6 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n) break; } - if (!drm_core_check_feature(dev, DRIVER_MODESET) && - dev->primary->master) { - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - } - msleep(1); if (dev_priv->mm.interruptible && signal_pending(current)) { @@ -2455,91 +2444,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) return intel_init_ring_buffer(dev, ring); } -int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring = &dev_priv->ring[RCS]; - struct intel_ringbuffer *ringbuf = ring->buffer; - int ret; - - if (ringbuf == NULL) { - ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL); - if (!ringbuf) - return -ENOMEM; - ring->buffer = ringbuf; - } - - ring->name = "render ring"; - ring->id = RCS; - ring->mmio_base = RENDER_RING_BASE; - - if (INTEL_INFO(dev)->gen >= 6) { - /* non-kms not supported on gen6+ */ - ret = -ENODEV; - goto err_ringbuf; - } - - /* Note: gem is not supported on gen5/ilk without kms (the corresponding - * gem_init ioctl returns with -ENODEV). Hence we do not need to set up - * the special gen5 functions. */ - ring->add_request = i9xx_add_request; - if (INTEL_INFO(dev)->gen < 4) - ring->flush = gen2_render_ring_flush; - else - ring->flush = gen4_render_ring_flush; - ring->get_seqno = ring_get_seqno; - ring->set_seqno = ring_set_seqno; - if (IS_GEN2(dev)) { - ring->irq_get = i8xx_ring_get_irq; - ring->irq_put = i8xx_ring_put_irq; - } else { - ring->irq_get = i9xx_ring_get_irq; - ring->irq_put = i9xx_ring_put_irq; - } - ring->irq_enable_mask = I915_USER_INTERRUPT; - ring->write_tail = ring_write_tail; - if (INTEL_INFO(dev)->gen >= 4) - ring->dispatch_execbuffer = i965_dispatch_execbuffer; - else if (IS_I830(dev) || IS_845G(dev)) - ring->dispatch_execbuffer = i830_dispatch_execbuffer; - else - ring->dispatch_execbuffer = i915_dispatch_execbuffer; - ring->init = init_render_ring; - ring->cleanup = render_ring_cleanup; - - ring->dev = dev; - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - - ringbuf->size = size; - ringbuf->effective_size = ringbuf->size; - if (IS_I830(ring->dev) || IS_845G(ring->dev)) - ringbuf->effective_size -= 2 * CACHELINE_BYTES; - - ringbuf->virtual_start = ioremap_wc(start, size); - if (ringbuf->virtual_start == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - ret = -ENOMEM; - goto err_ringbuf; - } - - if (!I915_NEED_GFX_HWS(dev)) { - ret = init_phys_status_page(ring); - if (ret) - goto err_vstart; - } - - return 0; - -err_vstart: - iounmap(ringbuf->virtual_start); -err_ringbuf: - kfree(ringbuf); - ring->buffer = NULL; - return ret; -} - int intel_init_bsd_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 9eb3188595a6..fe426cff598b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -448,7 +448,4 @@ static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno) ring->trace_irq_seqno = seqno; } -/* DRI warts */ -int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size); - #endif /* _INTEL_RINGBUFFER_H_ */ -- GitLab From ef87c5d6a11af45c31910728e46642e77aa8db61 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 20:10:34 +0100 Subject: [PATCH 5380/9457] net: pktgen: Deletion of an unnecessary check before the function call "proc_remove" The proc_remove() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- net/core/pktgen.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 443256bdcddc..da934fc3faa8 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3728,8 +3728,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, /* Remove proc before if_list entry, because add_device uses * list to determine if interface already exist, avoid race * with proc_create_data() */ - if (pkt_dev->entry) - proc_remove(pkt_dev->entry); + proc_remove(pkt_dev->entry); /* And update the thread if_list */ _rem_dev_from_if_list(t, pkt_dev); -- GitLab From 9960efeb80f73bd073483dab0855ee0ddc27085c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 18 Nov 2014 19:13:25 -0500 Subject: [PATCH 5381/9457] ftrace/x86: Add frames pointers to trampoline as necessary When CONFIG_FRAME_POINTERS are enabled, it is required that the ftrace_caller and ftrace_regs_caller trampolines set up frame pointers otherwise a stack trace from a function call wont print the functions that called the trampoline. This is due to a check in __save_stack_address(): #ifdef CONFIG_FRAME_POINTER if (!reliable) return; #endif The "reliable" variable is only set if the function address is equal to contents of the address before the address the frame pointer register points to. If the frame pointer is not set up for the ftrace caller then this will fail the reliable test. It will miss the function that called the trampoline. Worse yet, if fentry is used (gcc 4.6 and beyond), it will also miss the parent, as the fentry is called before the stack frame is set up. That means the bp frame pointer points to the stack of just before the parent function was called. Link: http://lkml.kernel.org/r/20141119034829.355440340@goodmis.org Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: stable@vger.kernel.org # 3.7+ Acked-by: Thomas Gleixner Signed-off-by: Steven Rostedt --- arch/x86/kernel/mcount_64.S | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S index 42f0cdd20baf..35a793fa4bba 100644 --- a/arch/x86/kernel/mcount_64.S +++ b/arch/x86/kernel/mcount_64.S @@ -47,14 +47,51 @@ GLOBAL(\trace_label) #endif .endm +#ifdef CONFIG_FRAME_POINTER +/* + * Stack traces will stop at the ftrace trampoline if the frame pointer + * is not set up properly. If fentry is used, we need to save a frame + * pointer for the parent as well as the function traced, because the + * fentry is called before the stack frame is set up, where as mcount + * is called afterward. + */ +.macro create_frame parent rip +#ifdef CC_USING_FENTRY + pushq \parent + pushq %rbp + movq %rsp, %rbp +#endif + pushq \rip + pushq %rbp + movq %rsp, %rbp +.endm + +.macro restore_frame +#ifdef CC_USING_FENTRY + addq $16, %rsp +#endif + popq %rbp + addq $8, %rsp +.endm +#else +.macro create_frame parent rip +.endm +.macro restore_frame +.endm +#endif /* CONFIG_FRAME_POINTER */ + ENTRY(ftrace_caller) ftrace_caller_setup ftrace_caller_op_ptr /* regs go into 4th parameter (but make it NULL) */ movq $0, %rcx + create_frame %rsi, %rdi + GLOBAL(ftrace_call) call ftrace_stub + restore_frame + MCOUNT_RESTORE_FRAME /* @@ -105,9 +142,13 @@ ENTRY(ftrace_regs_caller) /* regs go into 4th parameter */ leaq (%rsp), %rcx + create_frame %rsi, %rdi + GLOBAL(ftrace_regs_call) call ftrace_stub + restore_frame + /* Copy flags back to SS, to restore them */ movq EFLAGS(%rsp), %rax movq %rax, SS(%rsp) -- GitLab From aec0be2d6e9f02dbef41ee54854c2e003e55c23e Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 18 Nov 2014 21:14:11 -0500 Subject: [PATCH 5382/9457] ftrace/x86/extable: Add is_ftrace_trampoline() function Stack traces that happen from function tracing check if the address on the stack is a __kernel_text_address(). That is, is the address kernel code. This calls core_kernel_text() which returns true if the address is part of the builtin kernel code. It also calls is_module_text_address() which returns true if the address belongs to module code. But what is missing is ftrace dynamically allocated trampolines. These trampolines are allocated for individual ftrace_ops that call the ftrace_ops callback functions directly. But if they do a stack trace, the code checking the stack wont detect them as they are neither core kernel code nor module address space. Adding another field to ftrace_ops that also stores the size of the trampoline assigned to it we can create a new function called is_ftrace_trampoline() that returns true if the address is a dynamically allocate ftrace trampoline. Note, it ignores trampolines that are not dynamically allocated as they will return true with the core_kernel_text() function. Link: http://lkml.kernel.org/r/20141119034829.497125839@goodmis.org Cc: Ingo Molnar Cc: "H. Peter Anvin" Acked-by: Thomas Gleixner Signed-off-by: Steven Rostedt --- arch/x86/kernel/ftrace.c | 9 +++++++-- include/linux/ftrace.h | 8 ++++++++ kernel/extable.c | 7 ++++++- kernel/trace/ftrace.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 1aea94d336c7..60881d919432 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -712,7 +712,8 @@ union ftrace_op_code_union { } __attribute__((packed)); }; -static unsigned long create_trampoline(struct ftrace_ops *ops) +static unsigned long +create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) { unsigned const char *jmp; unsigned long start_offset; @@ -749,6 +750,8 @@ static unsigned long create_trampoline(struct ftrace_ops *ops) if (!trampoline) return 0; + *tramp_size = size + MCOUNT_INSN_SIZE + sizeof(void *); + /* Copy ftrace_caller onto the trampoline memory */ ret = probe_kernel_read(trampoline, (void *)start_offset, size); if (WARN_ON(ret < 0)) { @@ -819,6 +822,7 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops) unsigned char *new; unsigned long offset; unsigned long ip; + unsigned int size; int ret; if (ops->trampoline) { @@ -829,9 +833,10 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops) if (!(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP)) return; } else { - ops->trampoline = create_trampoline(ops); + ops->trampoline = create_trampoline(ops, &size); if (!ops->trampoline) return; + ops->trampoline_size = size; } offset = calc_trampoline_call_offset(ops->flags & FTRACE_OPS_FL_SAVE_REGS); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 619e37cc17fd..7b2616fa2472 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -150,6 +150,7 @@ struct ftrace_ops { struct ftrace_ops_hash *func_hash; struct ftrace_ops_hash old_hash; unsigned long trampoline; + unsigned long trampoline_size; #endif }; @@ -297,6 +298,8 @@ extern int ftrace_text_reserved(const void *start, const void *end); extern int ftrace_nr_registered_ops(void); +bool is_ftrace_trampoline(unsigned long addr); + /* * The dyn_ftrace record's flags field is split into two parts. * the first part which is '0-FTRACE_REF_MAX' is a counter of @@ -596,6 +599,11 @@ static inline ssize_t ftrace_notrace_write(struct file *file, const char __user size_t cnt, loff_t *ppos) { return -ENODEV; } static inline int ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } + +static inline bool is_ftrace_trampoline(unsigned long addr) +{ + return false; +} #endif /* CONFIG_DYNAMIC_FTRACE */ /* totally disable ftrace - can not re-enable after this */ diff --git a/kernel/extable.c b/kernel/extable.c index d8a6446adbcb..c98f926277a8 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,8 @@ int __kernel_text_address(unsigned long addr) return 1; if (is_module_text_address(addr)) return 1; + if (is_ftrace_trampoline(addr)) + return 1; /* * There might be init symbols in saved stacktraces. * Give those symbols a chance to be printed in @@ -119,7 +122,9 @@ int kernel_text_address(unsigned long addr) { if (core_kernel_text(addr)) return 1; - return is_module_text_address(addr); + if (is_module_text_address(addr)) + return 1; + return is_ftrace_trampoline(addr); } /* diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 6233f9102179..fa0f36bb32e9 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1117,6 +1117,43 @@ static struct ftrace_ops global_ops = { FTRACE_OPS_FL_INITIALIZED, }; +/* + * This is used by __kernel_text_address() to return true if the + * the address is on a dynamically allocated trampoline that would + * not return true for either core_kernel_text() or + * is_module_text_address(). + */ +bool is_ftrace_trampoline(unsigned long addr) +{ + struct ftrace_ops *op; + bool ret = false; + + /* + * Some of the ops may be dynamically allocated, + * they are freed after a synchronize_sched(). + */ + preempt_disable_notrace(); + + do_for_each_ftrace_op(op, ftrace_ops_list) { + /* + * This is to check for dynamically allocated trampolines. + * Trampolines that are in kernel text will have + * core_kernel_text() return true. + */ + if (op->trampoline && op->trampoline_size) + if (addr >= op->trampoline && + addr < op->trampoline + op->trampoline_size) { + ret = true; + goto out; + } + } while_for_each_ftrace_op(op); + + out: + preempt_enable_notrace(); + + return ret; +} + struct ftrace_page { struct ftrace_page *next; struct dyn_ftrace *records; @@ -5373,6 +5410,7 @@ static struct ftrace_ops graph_ops = { FTRACE_OPS_FL_STUB, #ifdef FTRACE_GRAPH_TRAMP_ADDR .trampoline = FTRACE_GRAPH_TRAMP_ADDR, + /* trampoline_size is only needed for dynamically allocated tramps */ #endif ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash) }; -- GitLab From 467aa1f276a0cf7445a1f4b9600f03d949b76251 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 24 Sep 2014 18:52:39 -0400 Subject: [PATCH 5383/9457] x86/kvm/tracing: Use helper function trace_seq_buffer_ptr() To allow for the restructiong of the trace_seq code, we need users of it to use the helper functions instead of accessing the internals of the trace_seq structure itself. Link: http://lkml.kernel.org/r/20141104160221.585025609@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Acked-by: Paolo Bonzini Acked-by: Mark Rustad Reviewed-by: Petr Mladek Cc: Jeff Kirsher Signed-off-by: Steven Rostedt --- arch/x86/kvm/mmutrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 5aaf35641768..ce463a9cc8fb 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h @@ -22,7 +22,7 @@ __entry->unsync = sp->unsync; #define KVM_MMU_PAGE_PRINTK() ({ \ - const u32 saved_len = p->len; \ + const char *saved_ptr = trace_seq_buffer_ptr(p); \ static const char *access_str[] = { \ "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \ }; \ @@ -41,7 +41,7 @@ role.nxe ? "" : "!", \ __entry->root_count, \ __entry->unsync ? "unsync" : "sync", 0); \ - p->buffer + saved_len; \ + saved_ptr; \ }) #define kvm_mmu_trace_pferr_flags \ -- GitLab From dbcf3e06cae0424d85c8dd1a1b93e25e84b06a8d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 31 Oct 2014 19:43:08 -0400 Subject: [PATCH 5384/9457] RAS/tracing: Use trace_seq_buffer_ptr() helper instead of open coded Use the helper function trace_seq_buffer_ptr() to get the current location of the next buffer write of a trace_seq object, instead of open coding it. This facilitates the conversion of trace_seq to use seq_buf. Tested-by: Jiri Kosina Acked-by: Jiri Kosina Acked-by: Borislav Petkov Reviewed-by: Petr Mladek Cc: Chen Gong Cc: Tony Luck Signed-off-by: Steven Rostedt --- drivers/firmware/efi/cper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 5b53d6183b6b..4fd9961d552e 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -294,7 +294,7 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem, const char *cper_mem_err_unpack(struct trace_seq *p, struct cper_mem_err_compact *cmem) { - const char *ret = p->buffer + p->len; + const char *ret = trace_seq_buffer_ptr(p); if (cper_mem_err_location(cmem, rcd_decode_str)) trace_seq_printf(p, "%s", rcd_decode_str); -- GitLab From e400a40cffa77e45c60c5431ec8757579247cae2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 21:11:59 -0500 Subject: [PATCH 5385/9457] tracing: Fix trace_seq_bitmask() to start at current position In trace_seq_bitmask() it calls bitmap_scnprintf() not from the current position of the trace_seq buffer (s->buffer + s->len), but instead from the beginning of the buffer (s->buffer). Luckily, the only user of this "ipi_raise tracepoint" uses it as the first parameter, and as such, the start of the temp buffer in include/trace/ftrace.h (see __get_bitmask()). Reported-by: Petr Mladek Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace_seq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 1f24ed99dca2..b100994a17fe 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -122,7 +122,7 @@ int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, if (s->full || !len) return 0; - ret = bitmap_scnprintf(s->buffer, len, maskp, nmaskbits); + ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits); s->len += ret; return 1; -- GitLab From 19a7fe206232cc875a3083211e0a21c08edd756e Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 10:29:54 -0500 Subject: [PATCH 5386/9457] tracing: Add trace_seq_has_overflowed() and trace_handle_return() Adding a trace_seq_has_overflowed() which returns true if the trace_seq had too much written into it allows us to simplify the code. Instead of checking the return value of every call to trace_seq_printf() and friends, they can all be called normally, and at the end we can return !trace_seq_has_overflowed() instead. Several functions also return TRACE_TYPE_PARTIAL_LINE when the trace_seq overflowed and TRACE_TYPE_HANDLED otherwise. Another helper function was created called trace_handle_return() which takes a trace_seq and returns these enums. Using this helper function also simplifies the code. This change also makes it possible to remove the return values of trace_seq_printf() and friends. They should instead just be void functions. Link: http://lkml.kernel.org/r/20141114011410.365183157@goodmis.org Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 11 + include/linux/trace_seq.h | 12 + include/trace/ftrace.h | 6 +- kernel/trace/trace.c | 69 +++--- kernel/trace/trace.h | 1 + kernel/trace/trace_output.c | 416 ++++++++++++++--------------------- kernel/trace/trace_output.h | 16 +- 7 files changed, 231 insertions(+), 300 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 28672e87e910..0bebb5c348b8 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -138,6 +138,17 @@ enum print_line_t { TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ }; +/* + * Several functions return TRACE_TYPE_PARTIAL_LINE if the trace_seq + * overflowed, and TRACE_TYPE_HANDLED otherwise. This helper function + * simplifies those functions and keeps them in sync. + */ +static inline enum print_line_t trace_handle_return(struct trace_seq *s) +{ + return trace_seq_has_overflowed(s) ? + TRACE_TYPE_PARTIAL_LINE : TRACE_TYPE_HANDLED; +} + void tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, int pc); diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index ea6c9dea79e3..07eda413dfcf 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -40,6 +40,18 @@ trace_seq_buffer_ptr(struct trace_seq *s) return s->buffer + s->len; } +/** + * trace_seq_has_overflowed - return true if the trace_seq took too much + * @s: trace sequence descriptor + * + * Returns true if too much data was added to the trace_seq and it is + * now full and will not take anymore. + */ +static inline bool trace_seq_has_overflowed(struct trace_seq *s) +{ + return s->full || s->len > PAGE_SIZE - 1; +} + /* * Currently only defined when tracing is enabled. */ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 26b4f2e13275..f13471b5d27a 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -280,11 +280,9 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ if (ret) \ return ret; \ \ - ret = trace_seq_printf(s, print); \ - if (!ret) \ - return TRACE_TYPE_PARTIAL_LINE; \ + trace_seq_printf(s, print); \ \ - return TRACE_TYPE_HANDLED; \ + return trace_handle_return(s); \ } \ static struct trace_event_functions ftrace_event_type_funcs_##call = { \ .trace = ftrace_raw_output_##call, \ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 44d561426700..3ce3c4ccfc94 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2649,24 +2649,21 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) event = ftrace_find_event(entry->type); if (trace_flags & TRACE_ITER_CONTEXT_INFO) { - if (iter->iter_flags & TRACE_FILE_LAT_FMT) { - if (!trace_print_lat_context(iter)) - goto partial; - } else { - if (!trace_print_context(iter)) - goto partial; - } + if (iter->iter_flags & TRACE_FILE_LAT_FMT) + trace_print_lat_context(iter); + else + trace_print_context(iter); } + if (trace_seq_has_overflowed(s)) + return TRACE_TYPE_PARTIAL_LINE; + if (event) return event->funcs->trace(iter, sym_flags, event); - if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) - goto partial; + trace_seq_printf(s, "Unknown type %d\n", entry->type); - return TRACE_TYPE_HANDLED; -partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static enum print_line_t print_raw_fmt(struct trace_iterator *iter) @@ -2677,22 +2674,20 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter) entry = iter->ent; - if (trace_flags & TRACE_ITER_CONTEXT_INFO) { - if (!trace_seq_printf(s, "%d %d %llu ", - entry->pid, iter->cpu, iter->ts)) - goto partial; - } + if (trace_flags & TRACE_ITER_CONTEXT_INFO) + trace_seq_printf(s, "%d %d %llu ", + entry->pid, iter->cpu, iter->ts); + + if (trace_seq_has_overflowed(s)) + return TRACE_TYPE_PARTIAL_LINE; event = ftrace_find_event(entry->type); if (event) return event->funcs->raw(iter, 0, event); - if (!trace_seq_printf(s, "%d ?\n", entry->type)) - goto partial; + trace_seq_printf(s, "%d ?\n", entry->type); - return TRACE_TYPE_HANDLED; -partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static enum print_line_t print_hex_fmt(struct trace_iterator *iter) @@ -2705,9 +2700,11 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) entry = iter->ent; if (trace_flags & TRACE_ITER_CONTEXT_INFO) { - SEQ_PUT_HEX_FIELD_RET(s, entry->pid); - SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); - SEQ_PUT_HEX_FIELD_RET(s, iter->ts); + SEQ_PUT_HEX_FIELD(s, entry->pid); + SEQ_PUT_HEX_FIELD(s, iter->cpu); + SEQ_PUT_HEX_FIELD(s, iter->ts); + if (trace_seq_has_overflowed(s)) + return TRACE_TYPE_PARTIAL_LINE; } event = ftrace_find_event(entry->type); @@ -2717,9 +2714,9 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) return ret; } - SEQ_PUT_FIELD_RET(s, newline); + SEQ_PUT_FIELD(s, newline); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t print_bin_fmt(struct trace_iterator *iter) @@ -2731,9 +2728,11 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) entry = iter->ent; if (trace_flags & TRACE_ITER_CONTEXT_INFO) { - SEQ_PUT_FIELD_RET(s, entry->pid); - SEQ_PUT_FIELD_RET(s, iter->cpu); - SEQ_PUT_FIELD_RET(s, iter->ts); + SEQ_PUT_FIELD(s, entry->pid); + SEQ_PUT_FIELD(s, iter->cpu); + SEQ_PUT_FIELD(s, iter->ts); + if (trace_seq_has_overflowed(s)) + return TRACE_TYPE_PARTIAL_LINE; } event = ftrace_find_event(entry->type); @@ -2779,10 +2778,12 @@ enum print_line_t print_trace_line(struct trace_iterator *iter) { enum print_line_t ret; - if (iter->lost_events && - !trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", - iter->cpu, iter->lost_events)) - return TRACE_TYPE_PARTIAL_LINE; + if (iter->lost_events) { + trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", + iter->cpu, iter->lost_events); + if (trace_seq_has_overflowed(&iter->seq)) + return TRACE_TYPE_PARTIAL_LINE; + } if (iter->trace && iter->trace->print_line) { ret = iter->trace->print_line(iter); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 3376de623ea0..19418221b302 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_FTRACE_SYSCALLS #include /* For NR_SYSCALLS */ diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cfa91de22e27..163c11b6b8ff 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -25,15 +25,12 @@ enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent; struct bputs_entry *field; - int ret; trace_assign_type(field, entry); - ret = trace_seq_puts(s, field->str); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, field->str); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) @@ -41,15 +38,12 @@ enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent; struct bprint_entry *field; - int ret; trace_assign_type(field, entry); - ret = trace_seq_bprintf(s, field->fmt, field->buf); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_bprintf(s, field->fmt, field->buf); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter) @@ -57,15 +51,12 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter) struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent; struct print_entry *field; - int ret; trace_assign_type(field, entry); - ret = trace_seq_puts(s, field->buf); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, field->buf); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } const char * @@ -193,7 +184,6 @@ int ftrace_raw_output_prep(struct trace_iterator *iter, struct trace_seq *s = &iter->seq; struct trace_seq *p = &iter->tmp_seq; struct trace_entry *entry; - int ret; event = container_of(trace_event, struct ftrace_event_call, event); entry = iter->ent; @@ -204,8 +194,9 @@ int ftrace_raw_output_prep(struct trace_iterator *iter, } trace_seq_init(p); - ret = trace_seq_printf(s, "%s: ", ftrace_event_name(event)); - if (!ret) + trace_seq_printf(s, "%s: ", ftrace_event_name(event)); + + if (trace_seq_has_overflowed(s)) return TRACE_TYPE_PARTIAL_LINE; return 0; @@ -216,18 +207,11 @@ static int ftrace_output_raw(struct trace_iterator *iter, char *name, char *fmt, va_list ap) { struct trace_seq *s = &iter->seq; - int ret; - ret = trace_seq_printf(s, "%s: ", name); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - ret = trace_seq_vprintf(s, fmt, ap); + trace_seq_printf(s, "%s: ", name); + trace_seq_vprintf(s, fmt, ap); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } int ftrace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...) @@ -260,7 +244,7 @@ static inline const char *kretprobed(const char *name) } #endif /* CONFIG_KRETPROBES */ -static int +static void seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) { #ifdef CONFIG_KALLSYMS @@ -271,12 +255,11 @@ seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) name = kretprobed(str); - return trace_seq_printf(s, fmt, name); + trace_seq_printf(s, fmt, name); #endif - return 1; } -static int +static void seq_print_sym_offset(struct trace_seq *s, const char *fmt, unsigned long address) { @@ -287,9 +270,8 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt, sprint_symbol(str, address); name = kretprobed(str); - return trace_seq_printf(s, fmt, name); + trace_seq_printf(s, fmt, name); #endif - return 1; } #ifndef CONFIG_64BIT @@ -320,14 +302,14 @@ int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, if (file) { ret = trace_seq_path(s, &file->f_path); if (ret) - ret = trace_seq_printf(s, "[+0x%lx]", - ip - vmstart); + trace_seq_printf(s, "[+0x%lx]", + ip - vmstart); } up_read(&mm->mmap_sem); } if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file)) - ret = trace_seq_printf(s, " <" IP_FMT ">", ip); - return ret; + trace_seq_printf(s, " <" IP_FMT ">", ip); + return !trace_seq_has_overflowed(s); } int @@ -335,7 +317,6 @@ seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s, unsigned long sym_flags) { struct mm_struct *mm = NULL; - int ret = 1; unsigned int i; if (trace_flags & TRACE_ITER_SYM_USEROBJ) { @@ -354,48 +335,45 @@ seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s, for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { unsigned long ip = entry->caller[i]; - if (ip == ULONG_MAX || !ret) + if (ip == ULONG_MAX || trace_seq_has_overflowed(s)) break; - if (ret) - ret = trace_seq_puts(s, " => "); + + trace_seq_puts(s, " => "); + if (!ip) { - if (ret) - ret = trace_seq_puts(s, "??"); - if (ret) - ret = trace_seq_putc(s, '\n'); + trace_seq_puts(s, "??"); + trace_seq_putc(s, '\n'); continue; } - if (!ret) - break; - if (ret) - ret = seq_print_user_ip(s, mm, ip, sym_flags); - ret = trace_seq_putc(s, '\n'); + + seq_print_user_ip(s, mm, ip, sym_flags); + trace_seq_putc(s, '\n'); } if (mm) mmput(mm); - return ret; + + return !trace_seq_has_overflowed(s); } int seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) { - int ret; - - if (!ip) - return trace_seq_putc(s, '0'); + if (!ip) { + trace_seq_putc(s, '0'); + goto out; + } if (sym_flags & TRACE_ITER_SYM_OFFSET) - ret = seq_print_sym_offset(s, "%s", ip); + seq_print_sym_offset(s, "%s", ip); else - ret = seq_print_sym_short(s, "%s", ip); - - if (!ret) - return 0; + seq_print_sym_short(s, "%s", ip); if (sym_flags & TRACE_ITER_SYM_ADDR) - ret = trace_seq_printf(s, " <" IP_FMT ">", ip); - return ret; + trace_seq_printf(s, " <" IP_FMT ">", ip); + + out: + return !trace_seq_has_overflowed(s); } /** @@ -413,7 +391,6 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) char irqs_off; int hardirq; int softirq; - int ret; hardirq = entry->flags & TRACE_FLAG_HARDIRQ; softirq = entry->flags & TRACE_FLAG_SOFTIRQ; @@ -445,16 +422,15 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) softirq ? 's' : '.'; - if (!trace_seq_printf(s, "%c%c%c", - irqs_off, need_resched, hardsoft_irq)) - return 0; + trace_seq_printf(s, "%c%c%c", + irqs_off, need_resched, hardsoft_irq); if (entry->preempt_count) - ret = trace_seq_printf(s, "%x", entry->preempt_count); + trace_seq_printf(s, "%x", entry->preempt_count); else - ret = trace_seq_putc(s, '.'); + trace_seq_putc(s, '.'); - return ret; + return !trace_seq_has_overflowed(s); } static int @@ -464,9 +440,8 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) trace_find_cmdline(entry->pid, comm); - if (!trace_seq_printf(s, "%8.8s-%-5d %3d", - comm, entry->pid, cpu)) - return 0; + trace_seq_printf(s, "%8.8s-%-5d %3d", + comm, entry->pid, cpu); return trace_print_lat_fmt(s, entry); } @@ -493,24 +468,29 @@ lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC); unsigned long rel_msec = (unsigned long)rel_ts; - return trace_seq_printf( - s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", - ns2usecs(iter->ts), - abs_msec, abs_usec, - rel_msec, rel_usec); + trace_seq_printf( + s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", + ns2usecs(iter->ts), + abs_msec, abs_usec, + rel_msec, rel_usec); + } else if (verbose && !in_ns) { - return trace_seq_printf( - s, "[%016llx] %lld (+%lld): ", - iter->ts, abs_ts, rel_ts); + trace_seq_printf( + s, "[%016llx] %lld (+%lld): ", + iter->ts, abs_ts, rel_ts); + } else if (!verbose && in_ns) { - return trace_seq_printf( - s, " %4lldus%c: ", - abs_ts, - rel_ts > preempt_mark_thresh_us ? '!' : - rel_ts > 1 ? '+' : ' '); + trace_seq_printf( + s, " %4lldus%c: ", + abs_ts, + rel_ts > preempt_mark_thresh_us ? '!' : + rel_ts > 1 ? '+' : ' '); + } else { /* !verbose && !in_ns */ - return trace_seq_printf(s, " %4lld: ", abs_ts); + trace_seq_printf(s, " %4lld: ", abs_ts); } + + return !trace_seq_has_overflowed(s); } int trace_print_context(struct trace_iterator *iter) @@ -520,34 +500,29 @@ int trace_print_context(struct trace_iterator *iter) unsigned long long t; unsigned long secs, usec_rem; char comm[TASK_COMM_LEN]; - int ret; trace_find_cmdline(entry->pid, comm); - ret = trace_seq_printf(s, "%16s-%-5d [%03d] ", + trace_seq_printf(s, "%16s-%-5d [%03d] ", comm, entry->pid, iter->cpu); - if (!ret) - return 0; - if (trace_flags & TRACE_ITER_IRQ_INFO) { - ret = trace_print_lat_fmt(s, entry); - if (!ret) - return 0; - } + if (trace_flags & TRACE_ITER_IRQ_INFO) + trace_print_lat_fmt(s, entry); if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { t = ns2usecs(iter->ts); usec_rem = do_div(t, USEC_PER_SEC); secs = (unsigned long)t; - return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); + trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); } else - return trace_seq_printf(s, " %12llu: ", iter->ts); + trace_seq_printf(s, " %12llu: ", iter->ts); + + return !trace_seq_has_overflowed(s); } int trace_print_lat_context(struct trace_iterator *iter) { u64 next_ts; - int ret; /* trace_find_next_entry will reset ent_size */ int ent_size = iter->ent_size; struct trace_seq *s = &iter->seq; @@ -567,18 +542,17 @@ int trace_print_lat_context(struct trace_iterator *iter) trace_find_cmdline(entry->pid, comm); - ret = trace_seq_printf( - s, "%16s %5d %3d %d %08x %08lx ", - comm, entry->pid, iter->cpu, entry->flags, - entry->preempt_count, iter->idx); + trace_seq_printf( + s, "%16s %5d %3d %d %08x %08lx ", + comm, entry->pid, iter->cpu, entry->flags, + entry->preempt_count, iter->idx); } else { - ret = lat_print_generic(s, entry, iter->cpu); + lat_print_generic(s, entry, iter->cpu); } - if (ret) - ret = lat_print_timestamp(iter, next_ts); + lat_print_timestamp(iter, next_ts); - return ret; + return !trace_seq_has_overflowed(s); } static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; @@ -764,10 +738,9 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_event); enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags, struct trace_event *event) { - if (!trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type)) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type); - return TRACE_TYPE_HANDLED; + return trace_handle_return(&iter->seq); } /* TRACE_FN */ @@ -779,24 +752,16 @@ static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - if (!seq_print_ip_sym(s, field->ip, flags)) - goto partial; + seq_print_ip_sym(s, field->ip, flags); if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) { - if (!trace_seq_puts(s, " <-")) - goto partial; - if (!seq_print_ip_sym(s, - field->parent_ip, - flags)) - goto partial; + trace_seq_puts(s, " <-"); + seq_print_ip_sym(s, field->parent_ip, flags); } - if (!trace_seq_putc(s, '\n')) - goto partial; - return TRACE_TYPE_HANDLED; + trace_seq_putc(s, '\n'); - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, @@ -806,12 +771,11 @@ static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - if (!trace_seq_printf(&iter->seq, "%lx %lx\n", - field->ip, - field->parent_ip)) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(&iter->seq, "%lx %lx\n", + field->ip, + field->parent_ip); - return TRACE_TYPE_HANDLED; + return trace_handle_return(&iter->seq); } static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, @@ -822,10 +786,10 @@ static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - SEQ_PUT_HEX_FIELD_RET(s, field->ip); - SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip); + SEQ_PUT_HEX_FIELD(s, field->ip); + SEQ_PUT_HEX_FIELD(s, field->parent_ip); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, @@ -836,10 +800,10 @@ static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - SEQ_PUT_FIELD_RET(s, field->ip); - SEQ_PUT_FIELD_RET(s, field->parent_ip); + SEQ_PUT_FIELD(s, field->ip); + SEQ_PUT_FIELD(s, field->parent_ip); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static struct trace_event_functions trace_fn_funcs = { @@ -868,18 +832,17 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, T = task_state_char(field->next_state); S = task_state_char(field->prev_state); trace_find_cmdline(field->next_pid, comm); - if (!trace_seq_printf(&iter->seq, - " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", - field->prev_pid, - field->prev_prio, - S, delim, - field->next_cpu, - field->next_pid, - field->next_prio, - T, comm)) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_seq_printf(&iter->seq, + " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", + field->prev_pid, + field->prev_prio, + S, delim, + field->next_cpu, + field->next_pid, + field->next_prio, + T, comm); + + return trace_handle_return(&iter->seq); } static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags, @@ -904,17 +867,16 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S) if (!S) S = task_state_char(field->prev_state); T = task_state_char(field->next_state); - if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", - field->prev_pid, - field->prev_prio, - S, - field->next_cpu, - field->next_pid, - field->next_prio, - T)) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", + field->prev_pid, + field->prev_prio, + S, + field->next_cpu, + field->next_pid, + field->next_prio, + T); + + return trace_handle_return(&iter->seq); } static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags, @@ -942,15 +904,15 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S) S = task_state_char(field->prev_state); T = task_state_char(field->next_state); - SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); - SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio); - SEQ_PUT_HEX_FIELD_RET(s, S); - SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu); - SEQ_PUT_HEX_FIELD_RET(s, field->next_pid); - SEQ_PUT_HEX_FIELD_RET(s, field->next_prio); - SEQ_PUT_HEX_FIELD_RET(s, T); + SEQ_PUT_HEX_FIELD(s, field->prev_pid); + SEQ_PUT_HEX_FIELD(s, field->prev_prio); + SEQ_PUT_HEX_FIELD(s, S); + SEQ_PUT_HEX_FIELD(s, field->next_cpu); + SEQ_PUT_HEX_FIELD(s, field->next_pid); + SEQ_PUT_HEX_FIELD(s, field->next_prio); + SEQ_PUT_HEX_FIELD(s, T); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags, @@ -973,15 +935,15 @@ static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, trace_assign_type(field, iter->ent); - SEQ_PUT_FIELD_RET(s, field->prev_pid); - SEQ_PUT_FIELD_RET(s, field->prev_prio); - SEQ_PUT_FIELD_RET(s, field->prev_state); - SEQ_PUT_FIELD_RET(s, field->next_cpu); - SEQ_PUT_FIELD_RET(s, field->next_pid); - SEQ_PUT_FIELD_RET(s, field->next_prio); - SEQ_PUT_FIELD_RET(s, field->next_state); + SEQ_PUT_FIELD(s, field->prev_pid); + SEQ_PUT_FIELD(s, field->prev_prio); + SEQ_PUT_FIELD(s, field->prev_state); + SEQ_PUT_FIELD(s, field->next_cpu); + SEQ_PUT_FIELD(s, field->next_pid); + SEQ_PUT_FIELD(s, field->next_prio); + SEQ_PUT_FIELD(s, field->next_state); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static struct trace_event_functions trace_ctx_funcs = { @@ -1021,23 +983,19 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter, trace_assign_type(field, iter->ent); end = (unsigned long *)((long)iter->ent + iter->ent_size); - if (!trace_seq_puts(s, "\n")) - goto partial; + trace_seq_puts(s, "\n"); for (p = field->caller; p && *p != ULONG_MAX && p < end; p++) { - if (!trace_seq_puts(s, " => ")) - goto partial; - if (!seq_print_ip_sym(s, *p, flags)) - goto partial; - if (!trace_seq_putc(s, '\n')) - goto partial; - } + if (trace_seq_has_overflowed(s)) + break; - return TRACE_TYPE_HANDLED; + trace_seq_puts(s, " => "); + seq_print_ip_sym(s, *p, flags); + trace_seq_putc(s, '\n'); + } - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static struct trace_event_functions trace_stack_funcs = { @@ -1058,16 +1016,10 @@ static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, trace_assign_type(field, iter->ent); - if (!trace_seq_puts(s, "\n")) - goto partial; - - if (!seq_print_userip_objs(field, s, flags)) - goto partial; - - return TRACE_TYPE_HANDLED; + trace_seq_puts(s, "\n"); + seq_print_userip_objs(field, s, flags); - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static struct trace_event_functions trace_user_stack_funcs = { @@ -1090,19 +1042,11 @@ trace_bputs_print(struct trace_iterator *iter, int flags, trace_assign_type(field, entry); - if (!seq_print_ip_sym(s, field->ip, flags)) - goto partial; + seq_print_ip_sym(s, field->ip, flags); + trace_seq_puts(s, ": "); + trace_seq_puts(s, field->str); - if (!trace_seq_puts(s, ": ")) - goto partial; - - if (!trace_seq_puts(s, field->str)) - goto partial; - - return TRACE_TYPE_HANDLED; - - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } @@ -1115,16 +1059,10 @@ trace_bputs_raw(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - if (!trace_seq_printf(s, ": %lx : ", field->ip)) - goto partial; - - if (!trace_seq_puts(s, field->str)) - goto partial; + trace_seq_printf(s, ": %lx : ", field->ip); + trace_seq_puts(s, field->str); - return TRACE_TYPE_HANDLED; - - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static struct trace_event_functions trace_bputs_funcs = { @@ -1148,19 +1086,11 @@ trace_bprint_print(struct trace_iterator *iter, int flags, trace_assign_type(field, entry); - if (!seq_print_ip_sym(s, field->ip, flags)) - goto partial; - - if (!trace_seq_puts(s, ": ")) - goto partial; - - if (!trace_seq_bprintf(s, field->fmt, field->buf)) - goto partial; + seq_print_ip_sym(s, field->ip, flags); + trace_seq_puts(s, ": "); + trace_seq_bprintf(s, field->fmt, field->buf); - return TRACE_TYPE_HANDLED; - - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } @@ -1173,16 +1103,10 @@ trace_bprint_raw(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - if (!trace_seq_printf(s, ": %lx : ", field->ip)) - goto partial; - - if (!trace_seq_bprintf(s, field->fmt, field->buf)) - goto partial; + trace_seq_printf(s, ": %lx : ", field->ip); + trace_seq_bprintf(s, field->fmt, field->buf); - return TRACE_TYPE_HANDLED; - - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static struct trace_event_functions trace_bprint_funcs = { @@ -1204,16 +1128,10 @@ static enum print_line_t trace_print_print(struct trace_iterator *iter, trace_assign_type(field, iter->ent); - if (!seq_print_ip_sym(s, field->ip, flags)) - goto partial; - - if (!trace_seq_printf(s, ": %s", field->buf)) - goto partial; + seq_print_ip_sym(s, field->ip, flags); + trace_seq_printf(s, ": %s", field->buf); - return TRACE_TYPE_HANDLED; - - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(s); } static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, @@ -1223,13 +1141,9 @@ static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, trace_assign_type(field, iter->ent); - if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf)) - goto partial; - - return TRACE_TYPE_HANDLED; + trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf); - partial: - return TRACE_TYPE_PARTIAL_LINE; + return trace_handle_return(&iter->seq); } static struct trace_event_functions trace_print_funcs = { diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h index 80b25b585a70..8ef2c40efb3c 100644 --- a/kernel/trace/trace_output.h +++ b/kernel/trace/trace_output.h @@ -35,17 +35,11 @@ trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry); extern int __unregister_ftrace_event(struct trace_event *event); extern struct rw_semaphore trace_event_sem; -#define SEQ_PUT_FIELD_RET(s, x) \ -do { \ - if (!trace_seq_putmem(s, &(x), sizeof(x))) \ - return TRACE_TYPE_PARTIAL_LINE; \ -} while (0) - -#define SEQ_PUT_HEX_FIELD_RET(s, x) \ -do { \ - if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \ - return TRACE_TYPE_PARTIAL_LINE; \ -} while (0) +#define SEQ_PUT_FIELD(s, x) \ + trace_seq_putmem(s, &(x), sizeof(x)) + +#define SEQ_PUT_HEX_FIELD(s, x) \ + trace_seq_putmem_hex(s, &(x), sizeof(x)) #endif -- GitLab From f4a1d08ce65d7156504f2f0eac26f47dfc9120e6 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 11:35:48 -0500 Subject: [PATCH 5387/9457] blktrace/tracing: Use trace_seq_has_overflowed() helper function Checking the return code of every trace_seq_printf() operation and having to return early if it overflowed makes the code messy. Using the new trace_seq_has_overflowed() and trace_handle_return() functions allows us to clean up the code. In the future, trace_seq_printf() and friends will be turning into void functions and not returning a value. The trace_seq_has_overflowed() is to be used instead. This cleanup allows that change to take place. Cc: Jens Axboe Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/blktrace.c | 148 ++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 82 deletions(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index c1bd4ada2a04..11b9cb36092b 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -1142,9 +1142,9 @@ static void get_pdu_remap(const struct trace_entry *ent, r->sector_from = be64_to_cpu(sector_from); } -typedef int (blk_log_action_t) (struct trace_iterator *iter, const char *act); +typedef void (blk_log_action_t) (struct trace_iterator *iter, const char *act); -static int blk_log_action_classic(struct trace_iterator *iter, const char *act) +static void blk_log_action_classic(struct trace_iterator *iter, const char *act) { char rwbs[RWBS_LEN]; unsigned long long ts = iter->ts; @@ -1154,33 +1154,33 @@ static int blk_log_action_classic(struct trace_iterator *iter, const char *act) fill_rwbs(rwbs, t); - return trace_seq_printf(&iter->seq, - "%3d,%-3d %2d %5d.%09lu %5u %2s %3s ", - MAJOR(t->device), MINOR(t->device), iter->cpu, - secs, nsec_rem, iter->ent->pid, act, rwbs); + trace_seq_printf(&iter->seq, + "%3d,%-3d %2d %5d.%09lu %5u %2s %3s ", + MAJOR(t->device), MINOR(t->device), iter->cpu, + secs, nsec_rem, iter->ent->pid, act, rwbs); } -static int blk_log_action(struct trace_iterator *iter, const char *act) +static void blk_log_action(struct trace_iterator *iter, const char *act) { char rwbs[RWBS_LEN]; const struct blk_io_trace *t = te_blk_io_trace(iter->ent); fill_rwbs(rwbs, t); - return trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ", - MAJOR(t->device), MINOR(t->device), act, rwbs); + trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ", + MAJOR(t->device), MINOR(t->device), act, rwbs); } -static int blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent) { const unsigned char *pdu_buf; int pdu_len; - int i, end, ret; + int i, end; pdu_buf = pdu_start(ent); pdu_len = te_blk_io_trace(ent)->pdu_len; if (!pdu_len) - return 1; + return; /* find the last zero that needs to be printed */ for (end = pdu_len - 1; end >= 0; end--) @@ -1188,119 +1188,107 @@ static int blk_log_dump_pdu(struct trace_seq *s, const struct trace_entry *ent) break; end++; - if (!trace_seq_putc(s, '(')) - return 0; + trace_seq_putc(s, '('); for (i = 0; i < pdu_len; i++) { - ret = trace_seq_printf(s, "%s%02x", - i == 0 ? "" : " ", pdu_buf[i]); - if (!ret) - return ret; + trace_seq_printf(s, "%s%02x", + i == 0 ? "" : " ", pdu_buf[i]); /* * stop when the rest is just zeroes and indicate so * with a ".." appended */ - if (i == end && end != pdu_len - 1) - return trace_seq_puts(s, " ..) "); + if (i == end && end != pdu_len - 1) { + trace_seq_puts(s, " ..) "); + return; + } } - return trace_seq_puts(s, ") "); + trace_seq_puts(s, ") "); } -static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) { - int ret; - - ret = trace_seq_printf(s, "%u ", t_bytes(ent)); - if (!ret) - return 0; - ret = blk_log_dump_pdu(s, ent); - if (!ret) - return 0; - return trace_seq_printf(s, "[%s]\n", cmd); + trace_seq_printf(s, "%u ", t_bytes(ent)); + blk_log_dump_pdu(s, ent); + trace_seq_printf(s, "[%s]\n", cmd); } else { if (t_sec(ent)) - return trace_seq_printf(s, "%llu + %u [%s]\n", + trace_seq_printf(s, "%llu + %u [%s]\n", t_sector(ent), t_sec(ent), cmd); - return trace_seq_printf(s, "[%s]\n", cmd); + else + trace_seq_printf(s, "[%s]\n", cmd); } } -static int blk_log_with_error(struct trace_seq *s, +static void blk_log_with_error(struct trace_seq *s, const struct trace_entry *ent) { if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) { - int ret; - - ret = blk_log_dump_pdu(s, ent); - if (ret) - return trace_seq_printf(s, "[%d]\n", t_error(ent)); - return 0; + blk_log_dump_pdu(s, ent); + trace_seq_printf(s, "[%d]\n", t_error(ent)); } else { if (t_sec(ent)) - return trace_seq_printf(s, "%llu + %u [%d]\n", - t_sector(ent), - t_sec(ent), t_error(ent)); - return trace_seq_printf(s, "%llu [%d]\n", - t_sector(ent), t_error(ent)); + trace_seq_printf(s, "%llu + %u [%d]\n", + t_sector(ent), + t_sec(ent), t_error(ent)); + else + trace_seq_printf(s, "%llu [%d]\n", + t_sector(ent), t_error(ent)); } } -static int blk_log_remap(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_remap(struct trace_seq *s, const struct trace_entry *ent) { struct blk_io_trace_remap r = { .device_from = 0, }; get_pdu_remap(ent, &r); - return trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n", - t_sector(ent), t_sec(ent), - MAJOR(r.device_from), MINOR(r.device_from), - (unsigned long long)r.sector_from); + trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n", + t_sector(ent), t_sec(ent), + MAJOR(r.device_from), MINOR(r.device_from), + (unsigned long long)r.sector_from); } -static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_plug(struct trace_seq *s, const struct trace_entry *ent) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); - return trace_seq_printf(s, "[%s]\n", cmd); + trace_seq_printf(s, "[%s]\n", cmd); } -static int blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); - return trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent)); + trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent)); } -static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_split(struct trace_seq *s, const struct trace_entry *ent) { char cmd[TASK_COMM_LEN]; trace_find_cmdline(ent->pid, cmd); - return trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent), - get_pdu_int(ent), cmd); + trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent), + get_pdu_int(ent), cmd); } -static int blk_log_msg(struct trace_seq *s, const struct trace_entry *ent) +static void blk_log_msg(struct trace_seq *s, const struct trace_entry *ent) { - int ret; const struct blk_io_trace *t = te_blk_io_trace(ent); - ret = trace_seq_putmem(s, t + 1, t->pdu_len); - if (ret) - return trace_seq_putc(s, '\n'); - return ret; + trace_seq_putmem(s, t + 1, t->pdu_len); + trace_seq_putc(s, '\n'); } /* @@ -1339,7 +1327,7 @@ static void blk_tracer_reset(struct trace_array *tr) static const struct { const char *act[2]; - int (*print)(struct trace_seq *s, const struct trace_entry *ent); + void (*print)(struct trace_seq *s, const struct trace_entry *ent); } what2act[] = { [__BLK_TA_QUEUE] = {{ "Q", "queue" }, blk_log_generic }, [__BLK_TA_BACKMERGE] = {{ "M", "backmerge" }, blk_log_generic }, @@ -1364,7 +1352,6 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, struct trace_seq *s = &iter->seq; const struct blk_io_trace *t; u16 what; - int ret; bool long_act; blk_log_action_t *log_action; @@ -1374,21 +1361,18 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, log_action = classic ? &blk_log_action_classic : &blk_log_action; if (t->action == BLK_TN_MESSAGE) { - ret = log_action(iter, long_act ? "message" : "m"); - if (ret) - ret = blk_log_msg(s, iter->ent); - goto out; + log_action(iter, long_act ? "message" : "m"); + blk_log_msg(s, iter->ent); } if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) - ret = trace_seq_printf(s, "Unknown action %x\n", what); + trace_seq_printf(s, "Unknown action %x\n", what); else { - ret = log_action(iter, what2act[what].act[long_act]); - if (ret) - ret = what2act[what].print(s, iter->ent); + log_action(iter, what2act[what].act[long_act]); + what2act[what].print(s, iter->ent); } -out: - return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; + + return trace_handle_return(s); } static enum print_line_t blk_trace_event_print(struct trace_iterator *iter, @@ -1397,7 +1381,7 @@ static enum print_line_t blk_trace_event_print(struct trace_iterator *iter, return print_one_line(iter, false); } -static int blk_trace_synthesize_old_trace(struct trace_iterator *iter) +static void blk_trace_synthesize_old_trace(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; struct blk_io_trace *t = (struct blk_io_trace *)iter->ent; @@ -1407,18 +1391,18 @@ static int blk_trace_synthesize_old_trace(struct trace_iterator *iter) .time = iter->ts, }; - if (!trace_seq_putmem(s, &old, offset)) - return 0; - return trace_seq_putmem(s, &t->sector, - sizeof(old) - offset + t->pdu_len); + trace_seq_putmem(s, &old, offset); + trace_seq_putmem(s, &t->sector, + sizeof(old) - offset + t->pdu_len); } static enum print_line_t blk_trace_event_print_binary(struct trace_iterator *iter, int flags, struct trace_event *event) { - return blk_trace_synthesize_old_trace(iter) ? - TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; + blk_trace_synthesize_old_trace(iter); + + return trace_handle_return(&iter->seq); } static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter) -- GitLab From c0cd93aa1640a48038bacbee093695f892ea0130 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 11:49:00 -0500 Subject: [PATCH 5388/9457] ring-buffer: Remove check of trace_seq_{puts,printf}() return values Remove checking the return value of all trace_seq_puts(). It was wrong anyway as only the last return value mattered. But as the trace_seq_puts() is going to be a void function in the future, we should not be checking the return value of it anyway. Just return !trace_seq_has_overflowed() instead. Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/ring_buffer.c | 75 ++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 2d75c94ae87d..a28bdd17c853 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -34,21 +34,19 @@ static void update_pages_handler(struct work_struct *work); */ int ring_buffer_print_entry_header(struct trace_seq *s) { - int ret; - - ret = trace_seq_puts(s, "# compressed entry header\n"); - ret = trace_seq_puts(s, "\ttype_len : 5 bits\n"); - ret = trace_seq_puts(s, "\ttime_delta : 27 bits\n"); - ret = trace_seq_puts(s, "\tarray : 32 bits\n"); - ret = trace_seq_putc(s, '\n'); - ret = trace_seq_printf(s, "\tpadding : type == %d\n", - RINGBUF_TYPE_PADDING); - ret = trace_seq_printf(s, "\ttime_extend : type == %d\n", - RINGBUF_TYPE_TIME_EXTEND); - ret = trace_seq_printf(s, "\tdata max type_len == %d\n", - RINGBUF_TYPE_DATA_TYPE_LEN_MAX); + trace_seq_puts(s, "# compressed entry header\n"); + trace_seq_puts(s, "\ttype_len : 5 bits\n"); + trace_seq_puts(s, "\ttime_delta : 27 bits\n"); + trace_seq_puts(s, "\tarray : 32 bits\n"); + trace_seq_putc(s, '\n'); + trace_seq_printf(s, "\tpadding : type == %d\n", + RINGBUF_TYPE_PADDING); + trace_seq_printf(s, "\ttime_extend : type == %d\n", + RINGBUF_TYPE_TIME_EXTEND); + trace_seq_printf(s, "\tdata max type_len == %d\n", + RINGBUF_TYPE_DATA_TYPE_LEN_MAX); - return ret; + return !trace_seq_has_overflowed(s); } /* @@ -419,32 +417,31 @@ static inline int test_time_stamp(u64 delta) int ring_buffer_print_page_header(struct trace_seq *s) { struct buffer_data_page field; - int ret; - - ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t" - "offset:0;\tsize:%u;\tsigned:%u;\n", - (unsigned int)sizeof(field.time_stamp), - (unsigned int)is_signed_type(u64)); - - ret = trace_seq_printf(s, "\tfield: local_t commit;\t" - "offset:%u;\tsize:%u;\tsigned:%u;\n", - (unsigned int)offsetof(typeof(field), commit), - (unsigned int)sizeof(field.commit), - (unsigned int)is_signed_type(long)); - - ret = trace_seq_printf(s, "\tfield: int overwrite;\t" - "offset:%u;\tsize:%u;\tsigned:%u;\n", - (unsigned int)offsetof(typeof(field), commit), - 1, - (unsigned int)is_signed_type(long)); - - ret = trace_seq_printf(s, "\tfield: char data;\t" - "offset:%u;\tsize:%u;\tsigned:%u;\n", - (unsigned int)offsetof(typeof(field), data), - (unsigned int)BUF_PAGE_SIZE, - (unsigned int)is_signed_type(char)); - return ret; + trace_seq_printf(s, "\tfield: u64 timestamp;\t" + "offset:0;\tsize:%u;\tsigned:%u;\n", + (unsigned int)sizeof(field.time_stamp), + (unsigned int)is_signed_type(u64)); + + trace_seq_printf(s, "\tfield: local_t commit;\t" + "offset:%u;\tsize:%u;\tsigned:%u;\n", + (unsigned int)offsetof(typeof(field), commit), + (unsigned int)sizeof(field.commit), + (unsigned int)is_signed_type(long)); + + trace_seq_printf(s, "\tfield: int overwrite;\t" + "offset:%u;\tsize:%u;\tsigned:%u;\n", + (unsigned int)offsetof(typeof(field), commit), + 1, + (unsigned int)is_signed_type(long)); + + trace_seq_printf(s, "\tfield: char data;\t" + "offset:%u;\tsize:%u;\tsigned:%u;\n", + (unsigned int)offsetof(typeof(field), data), + (unsigned int)BUF_PAGE_SIZE, + (unsigned int)is_signed_type(char)); + + return !trace_seq_has_overflowed(s); } struct rb_irq_work { -- GitLab From 7d40f67165d9a4c9add5c0f7e599637a292bbfb2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 13:19:06 -0500 Subject: [PATCH 5389/9457] tracing: Have branch tracer use trace_handle_return() helper function The branch tracer should not be checking the trace_seq_printf() return value as that will soon be void. There's a new trace_handle_return() helper function that will return TRACE_TYPE_PARTIAL_LINE if the trace_seq overflowed and TRACE_TYPE_HANDLED otherwise. Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace_branch.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index a3916f68a1c7..7d6e2afde669 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -151,14 +151,13 @@ static enum print_line_t trace_branch_print(struct trace_iterator *iter, trace_assign_type(field, iter->ent); - if (trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n", - field->correct ? " ok " : " MISS ", - field->func, - field->file, - field->line)) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n", + field->correct ? " ok " : " MISS ", + field->func, + field->file, + field->line); + + return trace_handle_return(&iter->seq); } static void branch_print_header(struct seq_file *s) -- GitLab From 9d9add34ec7b2cdd438b0b26481f8d1861bde45c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 14:57:38 -0500 Subject: [PATCH 5390/9457] tracing: Have function_graph use trace_seq_has_overflowed() Instead of doing individual checks all over the place that makes the code very messy. Just check trace_seq_has_overflowed() at the end or in strategic places. This makes the code much cleaner and also helps with getting closer to removing the return values of trace_seq_printf() and friends. Link: http://lkml.kernel.org/r/20141114011410.987913836@goodmis.org Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace.h | 2 +- kernel/trace/trace_functions_graph.c | 382 ++++++++------------------- 2 files changed, 118 insertions(+), 266 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 19418221b302..c3a37e55ec8b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -726,7 +726,7 @@ extern unsigned long trace_flags; extern enum print_line_t print_graph_function_flags(struct trace_iterator *iter, u32 flags); extern void print_graph_headers_flags(struct seq_file *s, u32 flags); -extern enum print_line_t +extern void trace_print_graph_duration(unsigned long long duration, struct trace_seq *s); extern void graph_trace_open(struct trace_iterator *iter); extern void graph_trace_close(struct trace_iterator *iter); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 55bdf9d7f714..100288d10e1f 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -107,7 +107,7 @@ enum { FLAGS_FILL_END = 3 << TRACE_GRAPH_PRINT_FILL_SHIFT, }; -static enum print_line_t +static void print_graph_duration(unsigned long long duration, struct trace_seq *s, u32 flags); @@ -483,33 +483,24 @@ static int graph_trace_update_thresh(struct trace_array *tr) static int max_bytes_for_cpu; -static enum print_line_t -print_graph_cpu(struct trace_seq *s, int cpu) +static void print_graph_cpu(struct trace_seq *s, int cpu) { - int ret; - /* * Start with a space character - to make it stand out * to the right a bit when trace output is pasted into * email: */ - ret = trace_seq_printf(s, " %*d) ", max_bytes_for_cpu, cpu); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_seq_printf(s, " %*d) ", max_bytes_for_cpu, cpu); } #define TRACE_GRAPH_PROCINFO_LENGTH 14 -static enum print_line_t -print_graph_proc(struct trace_seq *s, pid_t pid) +static void print_graph_proc(struct trace_seq *s, pid_t pid) { char comm[TASK_COMM_LEN]; /* sign + log10(MAX_INT) + '\0' */ char pid_str[11]; int spaces = 0; - int ret; int len; int i; @@ -524,56 +515,43 @@ print_graph_proc(struct trace_seq *s, pid_t pid) spaces = TRACE_GRAPH_PROCINFO_LENGTH - len; /* First spaces to align center */ - for (i = 0; i < spaces / 2; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + for (i = 0; i < spaces / 2; i++) + trace_seq_putc(s, ' '); - ret = trace_seq_printf(s, "%s-%s", comm, pid_str); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "%s-%s", comm, pid_str); /* Last spaces to align center */ - for (i = 0; i < spaces - (spaces / 2); i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } - return TRACE_TYPE_HANDLED; + for (i = 0; i < spaces - (spaces / 2); i++) + trace_seq_putc(s, ' '); } -static enum print_line_t -print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry) +static void print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry) { - if (!trace_seq_putc(s, ' ')) - return 0; - - return trace_print_lat_fmt(s, entry); + trace_seq_putc(s, ' '); + trace_print_lat_fmt(s, entry); } /* If the pid changed since the last trace, output this event */ -static enum print_line_t +static void verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data) { pid_t prev_pid; pid_t *last_pid; - int ret; if (!data) - return TRACE_TYPE_HANDLED; + return; last_pid = &(per_cpu_ptr(data->cpu_data, cpu)->last_pid); if (*last_pid == pid) - return TRACE_TYPE_HANDLED; + return; prev_pid = *last_pid; *last_pid = pid; if (prev_pid == -1) - return TRACE_TYPE_HANDLED; + return; /* * Context-switch trace line: @@ -582,33 +560,12 @@ verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data) ------------------------------------------ */ - ret = trace_seq_puts(s, - " ------------------------------------------\n"); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - ret = print_graph_cpu(s, cpu); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - - ret = print_graph_proc(s, prev_pid); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - - ret = trace_seq_puts(s, " => "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - ret = print_graph_proc(s, pid); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - - ret = trace_seq_puts(s, - "\n ------------------------------------------\n\n"); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_seq_puts(s, " ------------------------------------------\n"); + print_graph_cpu(s, cpu); + print_graph_proc(s, prev_pid); + trace_seq_puts(s, " => "); + print_graph_proc(s, pid); + trace_seq_puts(s, "\n ------------------------------------------\n\n"); } static struct ftrace_graph_ret_entry * @@ -682,103 +639,74 @@ get_return_for_leaf(struct trace_iterator *iter, return next; } -static int print_graph_abs_time(u64 t, struct trace_seq *s) +static void print_graph_abs_time(u64 t, struct trace_seq *s) { unsigned long usecs_rem; usecs_rem = do_div(t, NSEC_PER_SEC); usecs_rem /= 1000; - return trace_seq_printf(s, "%5lu.%06lu | ", - (unsigned long)t, usecs_rem); + trace_seq_printf(s, "%5lu.%06lu | ", + (unsigned long)t, usecs_rem); } -static enum print_line_t +static void print_graph_irq(struct trace_iterator *iter, unsigned long addr, enum trace_type type, int cpu, pid_t pid, u32 flags) { - int ret; struct trace_seq *s = &iter->seq; struct trace_entry *ent = iter->ent; if (addr < (unsigned long)__irqentry_text_start || addr >= (unsigned long)__irqentry_text_end) - return TRACE_TYPE_UNHANDLED; + return; if (trace_flags & TRACE_ITER_CONTEXT_INFO) { /* Absolute time */ - if (flags & TRACE_GRAPH_PRINT_ABS_TIME) { - ret = print_graph_abs_time(iter->ts, s); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + if (flags & TRACE_GRAPH_PRINT_ABS_TIME) + print_graph_abs_time(iter->ts, s); /* Cpu */ - if (flags & TRACE_GRAPH_PRINT_CPU) { - ret = print_graph_cpu(s, cpu); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - } + if (flags & TRACE_GRAPH_PRINT_CPU) + print_graph_cpu(s, cpu); /* Proc */ if (flags & TRACE_GRAPH_PRINT_PROC) { - ret = print_graph_proc(s, pid); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - ret = trace_seq_puts(s, " | "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_proc(s, pid); + trace_seq_puts(s, " | "); } /* Latency format */ - if (trace_flags & TRACE_ITER_LATENCY_FMT) { - ret = print_graph_lat_fmt(s, ent); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - } - + if (trace_flags & TRACE_ITER_LATENCY_FMT) + print_graph_lat_fmt(s, ent); } /* No overhead */ - ret = print_graph_duration(0, s, flags | FLAGS_FILL_START); - if (ret != TRACE_TYPE_HANDLED) - return ret; + print_graph_duration(0, s, flags | FLAGS_FILL_START); if (type == TRACE_GRAPH_ENT) - ret = trace_seq_puts(s, "==========>"); + trace_seq_puts(s, "==========>"); else - ret = trace_seq_puts(s, "<=========="); - - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - ret = print_graph_duration(0, s, flags | FLAGS_FILL_END); - if (ret != TRACE_TYPE_HANDLED) - return ret; + trace_seq_puts(s, "<=========="); - ret = trace_seq_putc(s, '\n'); - - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - return TRACE_TYPE_HANDLED; + print_graph_duration(0, s, flags | FLAGS_FILL_END); + trace_seq_putc(s, '\n'); } -enum print_line_t +void trace_print_graph_duration(unsigned long long duration, struct trace_seq *s) { unsigned long nsecs_rem = do_div(duration, 1000); /* log10(ULONG_MAX) + '\0' */ char usecs_str[21]; char nsecs_str[5]; - int ret, len; + int len; int i; sprintf(usecs_str, "%lu", (unsigned long) duration); /* Print msecs */ - ret = trace_seq_printf(s, "%s", usecs_str); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "%s", usecs_str); len = strlen(usecs_str); @@ -787,79 +715,63 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s) size_t slen = min_t(size_t, sizeof(nsecs_str), 8UL - len); snprintf(nsecs_str, slen, "%03lu", nsecs_rem); - ret = trace_seq_printf(s, ".%s", nsecs_str); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, ".%s", nsecs_str); len += strlen(nsecs_str); } - ret = trace_seq_puts(s, " us "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, " us "); /* Print remaining spaces to fit the row's width */ - for (i = len; i < 7; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } - return TRACE_TYPE_HANDLED; + for (i = len; i < 7; i++) + trace_seq_putc(s, ' '); } -static enum print_line_t +static void print_graph_duration(unsigned long long duration, struct trace_seq *s, u32 flags) { - int ret = -1; + bool duration_printed = false; if (!(flags & TRACE_GRAPH_PRINT_DURATION) || !(trace_flags & TRACE_ITER_CONTEXT_INFO)) - return TRACE_TYPE_HANDLED; + return; /* No real adata, just filling the column with spaces */ switch (flags & TRACE_GRAPH_PRINT_FILL_MASK) { case FLAGS_FILL_FULL: - ret = trace_seq_puts(s, " | "); - return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, " | "); + return; case FLAGS_FILL_START: - ret = trace_seq_puts(s, " "); - return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, " "); + return; case FLAGS_FILL_END: - ret = trace_seq_puts(s, " |"); - return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, " |"); + return; } /* Signal a overhead of time execution to the output */ if (flags & TRACE_GRAPH_PRINT_OVERHEAD) { /* Duration exceeded 100 usecs */ - if (duration > 100000ULL) - ret = trace_seq_puts(s, "! "); + if (duration > 100000ULL) { + trace_seq_puts(s, "! "); + duration_printed = true; + /* Duration exceeded 10 usecs */ - else if (duration > 10000ULL) - ret = trace_seq_puts(s, "+ "); + } else if (duration > 10000ULL) { + trace_seq_puts(s, "+ "); + duration_printed = true; + } } /* - * The -1 means we either did not exceed the duration tresholds - * or we dont want to print out the overhead. Either way we need - * to fill out the space. + * If we did not exceed the duration tresholds or we dont want + * to print out the overhead. Either way we need to fill out the space. */ - if (ret == -1) - ret = trace_seq_puts(s, " "); - - /* Catching here any failure happenned above */ - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - ret = trace_print_graph_duration(duration, s); - if (ret != TRACE_TYPE_HANDLED) - return ret; + if (!duration_printed) + trace_seq_puts(s, " "); - ret = trace_seq_puts(s, "| "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - - return TRACE_TYPE_HANDLED; + trace_print_graph_duration(duration, s); + trace_seq_puts(s, "| "); } /* Case of a leaf function on its call entry */ @@ -873,7 +785,6 @@ print_graph_entry_leaf(struct trace_iterator *iter, struct ftrace_graph_ret *graph_ret; struct ftrace_graph_ent *call; unsigned long long duration; - int ret; int i; graph_ret = &ret_entry->ret; @@ -899,22 +810,15 @@ print_graph_entry_leaf(struct trace_iterator *iter, } /* Overhead and duration */ - ret = print_graph_duration(duration, s, flags); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_duration(duration, s, flags); /* Function */ - for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) + trace_seq_putc(s, ' '); - ret = trace_seq_printf(s, "%ps();\n", (void *)call->func); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "%ps();\n", (void *)call->func); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t @@ -924,7 +828,6 @@ print_graph_entry_nested(struct trace_iterator *iter, { struct ftrace_graph_ent *call = &entry->graph_ent; struct fgraph_data *data = iter->private; - int ret; int i; if (data) { @@ -940,19 +843,15 @@ print_graph_entry_nested(struct trace_iterator *iter, } /* No time */ - ret = print_graph_duration(0, s, flags | FLAGS_FILL_FULL); - if (ret != TRACE_TYPE_HANDLED) - return ret; + print_graph_duration(0, s, flags | FLAGS_FILL_FULL); /* Function */ - for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) + trace_seq_putc(s, ' '); + + trace_seq_printf(s, "%ps() {\n", (void *)call->func); - ret = trace_seq_printf(s, "%ps() {\n", (void *)call->func); - if (!ret) + if (trace_seq_has_overflowed(s)) return TRACE_TYPE_PARTIAL_LINE; /* @@ -962,62 +861,43 @@ print_graph_entry_nested(struct trace_iterator *iter, return TRACE_TYPE_NO_CONSUME; } -static enum print_line_t +static void print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, int type, unsigned long addr, u32 flags) { struct fgraph_data *data = iter->private; struct trace_entry *ent = iter->ent; int cpu = iter->cpu; - int ret; /* Pid */ - if (verif_pid(s, ent->pid, cpu, data) == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; + verif_pid(s, ent->pid, cpu, data); - if (type) { + if (type) /* Interrupt */ - ret = print_graph_irq(iter, addr, type, cpu, ent->pid, flags); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - } + print_graph_irq(iter, addr, type, cpu, ent->pid, flags); if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) - return 0; + return; /* Absolute time */ - if (flags & TRACE_GRAPH_PRINT_ABS_TIME) { - ret = print_graph_abs_time(iter->ts, s); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + if (flags & TRACE_GRAPH_PRINT_ABS_TIME) + print_graph_abs_time(iter->ts, s); /* Cpu */ - if (flags & TRACE_GRAPH_PRINT_CPU) { - ret = print_graph_cpu(s, cpu); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - } + if (flags & TRACE_GRAPH_PRINT_CPU) + print_graph_cpu(s, cpu); /* Proc */ if (flags & TRACE_GRAPH_PRINT_PROC) { - ret = print_graph_proc(s, ent->pid); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - - ret = trace_seq_puts(s, " | "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_proc(s, ent->pid); + trace_seq_puts(s, " | "); } /* Latency format */ - if (trace_flags & TRACE_ITER_LATENCY_FMT) { - ret = print_graph_lat_fmt(s, ent); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; - } + if (trace_flags & TRACE_ITER_LATENCY_FMT) + print_graph_lat_fmt(s, ent); - return 0; + return; } /* @@ -1135,8 +1015,7 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, if (check_irq_entry(iter, flags, call->func, call->depth)) return TRACE_TYPE_HANDLED; - if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags)) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags); leaf_ret = get_return_for_leaf(iter, field); if (leaf_ret) @@ -1169,7 +1048,6 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, pid_t pid = ent->pid; int cpu = iter->cpu; int func_match = 1; - int ret; int i; if (check_irq_return(iter, flags, trace->depth)) @@ -1195,20 +1073,14 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, } } - if (print_graph_prologue(iter, s, 0, 0, flags)) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_prologue(iter, s, 0, 0, flags); /* Overhead and duration */ - ret = print_graph_duration(duration, s, flags); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_duration(duration, s, flags); /* Closing brace */ - for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) + trace_seq_putc(s, ' '); /* * If the return function does not have a matching entry, @@ -1217,30 +1089,20 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, * belongs to, write out the function name. Always do * that if the funcgraph-tail option is enabled. */ - if (func_match && !(flags & TRACE_GRAPH_PRINT_TAIL)) { - ret = trace_seq_puts(s, "}\n"); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } else { - ret = trace_seq_printf(s, "} /* %ps */\n", (void *)trace->func); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + if (func_match && !(flags & TRACE_GRAPH_PRINT_TAIL)) + trace_seq_puts(s, "}\n"); + else + trace_seq_printf(s, "} /* %ps */\n", (void *)trace->func); /* Overrun */ - if (flags & TRACE_GRAPH_PRINT_OVERRUN) { - ret = trace_seq_printf(s, " (Overruns: %lu)\n", - trace->overrun); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + if (flags & TRACE_GRAPH_PRINT_OVERRUN) + trace_seq_printf(s, " (Overruns: %lu)\n", + trace->overrun); - ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, - cpu, pid, flags); - if (ret == TRACE_TYPE_PARTIAL_LINE) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, + cpu, pid, flags); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t @@ -1257,26 +1119,18 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, if (data) depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth; - if (print_graph_prologue(iter, s, 0, 0, flags)) - return TRACE_TYPE_PARTIAL_LINE; + print_graph_prologue(iter, s, 0, 0, flags); /* No time */ - ret = print_graph_duration(0, s, flags | FLAGS_FILL_FULL); - if (ret != TRACE_TYPE_HANDLED) - return ret; + print_graph_duration(0, s, flags | FLAGS_FILL_FULL); /* Indentation */ if (depth > 0) - for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) { - ret = trace_seq_putc(s, ' '); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) + trace_seq_putc(s, ' '); /* The comment */ - ret = trace_seq_puts(s, "/* "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, "/* "); switch (iter->ent->type) { case TRACE_BPRINT: @@ -1305,11 +1159,9 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, s->len--; } - ret = trace_seq_puts(s, " */\n"); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_puts(s, " */\n"); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } -- GitLab From 85224da0b81a52a58b91feccdcd341856d8eb83d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 15:18:16 -0500 Subject: [PATCH 5391/9457] kprobes/tracing: Use trace_seq_has_overflowed() for overflow checks Instead of checking the return value of trace_seq_printf() and friends for overflowing of the buffer, use the trace_seq_has_overflowed() helper function. This cleans up the code quite a bit and also takes us a step closer to changing the return values of trace_seq_printf() and friends to void. Link: http://lkml.kernel.org/r/20141114011411.181812785@goodmis.org Reviewed-by: Srikar Dronamraju Reviewed-by: Petr Mladek Acked-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- kernel/trace/trace_kprobe.c | 42 ++++++++++++++----------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ef7e7f16ed1a..5edb518be345 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1024,27 +1024,22 @@ print_kprobe_event(struct trace_iterator *iter, int flags, field = (struct kprobe_trace_entry_head *)iter->ent; tp = container_of(event, struct trace_probe, call.event); - if (!trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call))) - goto partial; + trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call)); if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) - goto partial; + goto out; - if (!trace_seq_putc(s, ')')) - goto partial; + trace_seq_putc(s, ')'); data = (u8 *)&field[1]; for (i = 0; i < tp->nr_args; i++) if (!tp->args[i].type->print(s, tp->args[i].name, data + tp->args[i].offset, field)) - goto partial; - - if (!trace_seq_putc(s, '\n')) - goto partial; + goto out; - return TRACE_TYPE_HANDLED; -partial: - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_putc(s, '\n'); + out: + return trace_handle_return(s); } static enum print_line_t @@ -1060,33 +1055,28 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, field = (struct kretprobe_trace_entry_head *)iter->ent; tp = container_of(event, struct trace_probe, call.event); - if (!trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call))) - goto partial; + trace_seq_printf(s, "%s: (", ftrace_event_name(&tp->call)); if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) - goto partial; + goto out; - if (!trace_seq_puts(s, " <- ")) - goto partial; + trace_seq_puts(s, " <- "); if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET)) - goto partial; + goto out; - if (!trace_seq_putc(s, ')')) - goto partial; + trace_seq_putc(s, ')'); data = (u8 *)&field[1]; for (i = 0; i < tp->nr_args; i++) if (!tp->args[i].type->print(s, tp->args[i].name, data + tp->args[i].offset, field)) - goto partial; + goto out; - if (!trace_seq_putc(s, '\n')) - goto partial; + trace_seq_putc(s, '\n'); - return TRACE_TYPE_HANDLED; -partial: - return TRACE_TYPE_PARTIAL_LINE; + out: + return trace_handle_return(s); } -- GitLab From a72e10afab565385d51e5117d7cffe4a667c1b62 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 16:26:06 -0500 Subject: [PATCH 5392/9457] tracing: Do not check return values of trace_seq_p*() for mmio tracer The return values for trace_seq_printf() and friends are going to be removed and they will become void functions. The mmio tracer checked their return and even did so incorrectly. Some of the funtions which returned the values were never checked themselves. Removing all the checks simplifies the code. Use trace_seq_has_overflowed() and trace_handle_return() where necessary instead. Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace_mmiotrace.c | 52 ++++++++++++++-------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 0abd9b863474..7a9ba62e9fef 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -59,17 +59,15 @@ static void mmio_trace_start(struct trace_array *tr) mmio_reset_data(tr); } -static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) +static void mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) { - int ret = 0; int i; resource_size_t start, end; const struct pci_driver *drv = pci_dev_driver(dev); - /* XXX: incomplete checks for trace_seq_printf() return value */ - ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", - dev->bus->number, dev->devfn, - dev->vendor, dev->device, dev->irq); + trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", + dev->bus->number, dev->devfn, + dev->vendor, dev->device, dev->irq); /* * XXX: is pci_resource_to_user() appropriate, since we are * supposed to interpret the __ioremap() phys_addr argument based on @@ -77,21 +75,20 @@ static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) */ for (i = 0; i < 7; i++) { pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); - ret += trace_seq_printf(s, " %llx", + trace_seq_printf(s, " %llx", (unsigned long long)(start | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); } for (i = 0; i < 7; i++) { pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); - ret += trace_seq_printf(s, " %llx", + trace_seq_printf(s, " %llx", dev->resource[i].start < dev->resource[i].end ? (unsigned long long)(end - start) + 1 : 0); } if (drv) - ret += trace_seq_printf(s, " %s\n", drv->name); + trace_seq_printf(s, " %s\n", drv->name); else - ret += trace_seq_puts(s, " \n"); - return ret; + trace_seq_puts(s, " \n"); } static void destroy_header_iter(struct header_iter *hiter) @@ -179,28 +176,27 @@ static enum print_line_t mmio_print_rw(struct trace_iterator *iter) unsigned long long t = ns2usecs(iter->ts); unsigned long usec_rem = do_div(t, USEC_PER_SEC); unsigned secs = (unsigned long)t; - int ret = 1; trace_assign_type(field, entry); rw = &field->rw; switch (rw->opcode) { case MMIO_READ: - ret = trace_seq_printf(s, + trace_seq_printf(s, "R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", rw->width, secs, usec_rem, rw->map_id, (unsigned long long)rw->phys, rw->value, rw->pc, 0); break; case MMIO_WRITE: - ret = trace_seq_printf(s, + trace_seq_printf(s, "W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", rw->width, secs, usec_rem, rw->map_id, (unsigned long long)rw->phys, rw->value, rw->pc, 0); break; case MMIO_UNKNOWN_OP: - ret = trace_seq_printf(s, + trace_seq_printf(s, "UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx," "%02lx 0x%lx %d\n", secs, usec_rem, rw->map_id, @@ -209,12 +205,11 @@ static enum print_line_t mmio_print_rw(struct trace_iterator *iter) (rw->value >> 0) & 0xff, rw->pc, 0); break; default: - ret = trace_seq_puts(s, "rw what?\n"); + trace_seq_puts(s, "rw what?\n"); break; } - if (ret) - return TRACE_TYPE_HANDLED; - return TRACE_TYPE_PARTIAL_LINE; + + return trace_handle_return(s); } static enum print_line_t mmio_print_map(struct trace_iterator *iter) @@ -226,31 +221,29 @@ static enum print_line_t mmio_print_map(struct trace_iterator *iter) unsigned long long t = ns2usecs(iter->ts); unsigned long usec_rem = do_div(t, USEC_PER_SEC); unsigned secs = (unsigned long)t; - int ret; trace_assign_type(field, entry); m = &field->map; switch (m->opcode) { case MMIO_PROBE: - ret = trace_seq_printf(s, + trace_seq_printf(s, "MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", secs, usec_rem, m->map_id, (unsigned long long)m->phys, m->virt, m->len, 0UL, 0); break; case MMIO_UNPROBE: - ret = trace_seq_printf(s, + trace_seq_printf(s, "UNMAP %u.%06lu %d 0x%lx %d\n", secs, usec_rem, m->map_id, 0UL, 0); break; default: - ret = trace_seq_puts(s, "map what?\n"); + trace_seq_puts(s, "map what?\n"); break; } - if (ret) - return TRACE_TYPE_HANDLED; - return TRACE_TYPE_PARTIAL_LINE; + + return trace_handle_return(s); } static enum print_line_t mmio_print_mark(struct trace_iterator *iter) @@ -262,14 +255,11 @@ static enum print_line_t mmio_print_mark(struct trace_iterator *iter) unsigned long long t = ns2usecs(iter->ts); unsigned long usec_rem = do_div(t, USEC_PER_SEC); unsigned secs = (unsigned long)t; - int ret; /* The trailing newline must be in the message. */ - ret = trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t mmio_print_line(struct trace_iterator *iter) -- GitLab From d2b0191a38cb1811fa69f645ff4b37e3a23a956d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 17:19:51 -0500 Subject: [PATCH 5393/9457] tracing/probes: Do not use return value of trace_seq_printf() The functions trace_seq_printf() and friends will soon not have a return value and will only be a void function. Use trace_seq_has_overflowed() instead to know if the trace_seq operations succeeded or not. Link: http://lkml.kernel.org/r/20141114011411.530216306@goodmis.org Reviewed-by: Petr Mladek Acked-by: Masami Hiramatsu Acked-by: Namhyung Kim Signed-off-by: Steven Rostedt --- kernel/trace/trace_probe.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d4b9fc22cd27..b983b2fd2ca1 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -40,7 +40,8 @@ const char *reserved_field_names[] = { int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name, \ void *data, void *ent) \ { \ - return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ + trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ + return !trace_seq_has_overflowed(s); \ } \ const char PRINT_TYPE_FMT_NAME(type)[] = fmt; \ NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(type)); @@ -61,10 +62,11 @@ int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name, int len = *(u32 *)data >> 16; if (!len) - return trace_seq_printf(s, " %s=(fault)", name); + trace_seq_printf(s, " %s=(fault)", name); else - return trace_seq_printf(s, " %s=\"%s\"", name, - (const char *)get_loc_data(data, ent)); + trace_seq_printf(s, " %s=\"%s\"", name, + (const char *)get_loc_data(data, ent)); + return !trace_seq_has_overflowed(s); } NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string)); -- GitLab From 8579a107a6490511bbe35d6f0be5be5b8b697775 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 17:26:57 -0500 Subject: [PATCH 5394/9457] tracing/uprobes: Do not use return values of trace_seq_printf() The functions trace_seq_printf() and friends will soon no longer have return values. Using trace_seq_has_overflowed() and trace_handle_return() should be used instead. Link: http://lkml.kernel.org/r/20141114011411.693008134@goodmis.org Link: http://lkml.kernel.org/r/20141115050602.333705855@goodmis.org Reviewed-by: Masami Hiramatsu Acked-by: Srikar Dronamraju Acked-by: Namhyung Kim Signed-off-by: Steven Rostedt --- kernel/trace/trace_uprobe.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index e35327c787f7..fd76f8e108ef 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -852,16 +852,14 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e tu = container_of(event, struct trace_uprobe, tp.call.event); if (is_ret_probe(tu)) { - if (!trace_seq_printf(s, "%s: (0x%lx <- 0x%lx)", - ftrace_event_name(&tu->tp.call), - entry->vaddr[1], entry->vaddr[0])) - goto partial; + trace_seq_printf(s, "%s: (0x%lx <- 0x%lx)", + ftrace_event_name(&tu->tp.call), + entry->vaddr[1], entry->vaddr[0]); data = DATAOF_TRACE_ENTRY(entry, true); } else { - if (!trace_seq_printf(s, "%s: (0x%lx)", - ftrace_event_name(&tu->tp.call), - entry->vaddr[0])) - goto partial; + trace_seq_printf(s, "%s: (0x%lx)", + ftrace_event_name(&tu->tp.call), + entry->vaddr[0]); data = DATAOF_TRACE_ENTRY(entry, false); } @@ -869,14 +867,13 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e struct probe_arg *parg = &tu->tp.args[i]; if (!parg->type->print(s, parg->name, data + parg->offset, entry)) - goto partial; + goto out; } - if (trace_seq_putc(s, '\n')) - return TRACE_TYPE_HANDLED; + trace_seq_putc(s, '\n'); -partial: - return TRACE_TYPE_PARTIAL_LINE; + out: + return trace_handle_return(s); } typedef bool (*filter_func_t)(struct uprobe_consumer *self, -- GitLab From 183742f08c5532c0cd3c3d3fa184a26c092e2157 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 17:41:33 -0500 Subject: [PATCH 5395/9457] tracing: Do not use return values of trace_seq_printf() in syscall tracing The functions trace_seq_printf() and friends will not be returning values soon and will be void functions. To know if they succeeded or not, the functions trace_seq_has_overflowed() and trace_handle_return() should be used instead. Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace_syscalls.c | 47 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 4dc8b79c5f75..a72f3d8d813e 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -114,7 +114,7 @@ print_syscall_enter(struct trace_iterator *iter, int flags, struct trace_entry *ent = iter->ent; struct syscall_trace_enter *trace; struct syscall_metadata *entry; - int i, ret, syscall; + int i, syscall; trace = (typeof(trace))ent; syscall = trace->nr; @@ -128,35 +128,28 @@ print_syscall_enter(struct trace_iterator *iter, int flags, goto end; } - ret = trace_seq_printf(s, "%s(", entry->name); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "%s(", entry->name); for (i = 0; i < entry->nb_args; i++) { + + if (trace_seq_has_overflowed(s)) + goto end; + /* parameter types */ - if (trace_flags & TRACE_ITER_VERBOSE) { - ret = trace_seq_printf(s, "%s ", entry->types[i]); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - } + if (trace_flags & TRACE_ITER_VERBOSE) + trace_seq_printf(s, "%s ", entry->types[i]); + /* parameter values */ - ret = trace_seq_printf(s, "%s: %lx%s", entry->args[i], - trace->args[i], - i == entry->nb_args - 1 ? "" : ", "); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_printf(s, "%s: %lx%s", entry->args[i], + trace->args[i], + i == entry->nb_args - 1 ? "" : ", "); } - ret = trace_seq_putc(s, ')'); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - + trace_seq_putc(s, ')'); end: - ret = trace_seq_putc(s, '\n'); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; + trace_seq_putc(s, '\n'); - return TRACE_TYPE_HANDLED; + return trace_handle_return(s); } static enum print_line_t @@ -168,7 +161,6 @@ print_syscall_exit(struct trace_iterator *iter, int flags, struct syscall_trace_exit *trace; int syscall; struct syscall_metadata *entry; - int ret; trace = (typeof(trace))ent; syscall = trace->nr; @@ -176,7 +168,7 @@ print_syscall_exit(struct trace_iterator *iter, int flags, if (!entry) { trace_seq_putc(s, '\n'); - return TRACE_TYPE_HANDLED; + goto out; } if (entry->exit_event->event.type != ent->type) { @@ -184,12 +176,11 @@ print_syscall_exit(struct trace_iterator *iter, int flags, return TRACE_TYPE_UNHANDLED; } - ret = trace_seq_printf(s, "%s -> 0x%lx\n", entry->name, + trace_seq_printf(s, "%s -> 0x%lx\n", entry->name, trace->ret); - if (!ret) - return TRACE_TYPE_PARTIAL_LINE; - return TRACE_TYPE_HANDLED; + out: + return trace_handle_return(s); } extern char *__bad_type_size(void); -- GitLab From dba39448abb7340f86ae9b062f99d7acacb5d2d2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 12 Nov 2014 18:07:22 -0500 Subject: [PATCH 5396/9457] tracing: Remove return values of most trace_seq_*() functions The trace_seq_printf() and friends are used to store strings into a buffer that can be passed around from function to function. If the trace_seq buffer fills up, it will not print any more. The return values were somewhat inconsistant and using trace_seq_has_overflowed() was a better way to know if the write to the trace_seq buffer succeeded or not. Now that all users have removed reading the return value of the printf() type functions, they can safely return void and keep future users of them from reading the inconsistent values as well. Link: http://lkml.kernel.org/r/20141114011411.992510720@goodmis.org Signed-off-by: Steven Rostedt --- include/linux/trace_seq.h | 37 +++++++---------- kernel/trace/trace_seq.c | 84 +++++++++++---------------------------- 2 files changed, 38 insertions(+), 83 deletions(-) diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 07eda413dfcf..db8a73224f1a 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -57,40 +57,37 @@ static inline bool trace_seq_has_overflowed(struct trace_seq *s) */ #ifdef CONFIG_TRACING extern __printf(2, 3) -int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); +void trace_seq_printf(struct trace_seq *s, const char *fmt, ...); extern __printf(2, 0) -int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args); -extern int +void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args); +extern void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt); -extern int trace_seq_puts(struct trace_seq *s, const char *str); -extern int trace_seq_putc(struct trace_seq *s, unsigned char c); -extern int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len); -extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, +extern void trace_seq_puts(struct trace_seq *s, const char *str); +extern void trace_seq_putc(struct trace_seq *s, unsigned char c); +extern void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len); +extern void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len); extern int trace_seq_path(struct trace_seq *s, const struct path *path); -extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, +extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, int nmaskbits); #else /* CONFIG_TRACING */ -static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) +static inline void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { - return 0; } -static inline int +static inline void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) { - return 0; } -static inline int +static inline void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, int nmaskbits) { - return 0; } static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) @@ -102,23 +99,19 @@ static inline int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, { return 0; } -static inline int trace_seq_puts(struct trace_seq *s, const char *str) +static inline void trace_seq_puts(struct trace_seq *s, const char *str) { - return 0; } -static inline int trace_seq_putc(struct trace_seq *s, unsigned char c) +static inline void trace_seq_putc(struct trace_seq *s, unsigned char c) { - return 0; } -static inline int +static inline void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) { - return 0; } -static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, +static inline void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len) { - return 0; } static inline int trace_seq_path(struct trace_seq *s, const struct path *path) { diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index b100994a17fe..fabfa0f190a3 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -69,20 +69,15 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s) * trace_seq_printf() is used to store strings into a special * buffer (@s). Then the output may be either used by * the sequencer or pulled into another buffer. - * - * Returns 1 if we successfully written all the contents to - * the buffer. - * Returns 0 if we the length to write is bigger than the - * reserved buffer space. In this case, nothing gets written. */ -int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) +void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { unsigned int len = TRACE_SEQ_BUF_LEFT(s); va_list ap; int ret; if (s->full || !len) - return 0; + return; va_start(ap, fmt); ret = vsnprintf(s->buffer + s->len, len, fmt, ap); @@ -91,12 +86,10 @@ int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) /* If we can't write it all, don't bother writing anything */ if (ret >= len) { s->full = 1; - return 0; + return; } s->len += ret; - - return 1; } EXPORT_SYMBOL_GPL(trace_seq_printf); @@ -107,25 +100,18 @@ EXPORT_SYMBOL_GPL(trace_seq_printf); * @nmaskbits: The number of bits that are valid in @maskp * * Writes a ASCII representation of a bitmask string into @s. - * - * Returns 1 if we successfully written all the contents to - * the buffer. - * Returns 0 if we the length to write is bigger than the - * reserved buffer space. In this case, nothing gets written. */ -int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, +void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, int nmaskbits) { unsigned int len = TRACE_SEQ_BUF_LEFT(s); int ret; if (s->full || !len) - return 0; + return; ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits); s->len += ret; - - return 1; } EXPORT_SYMBOL_GPL(trace_seq_bitmask); @@ -139,28 +125,24 @@ EXPORT_SYMBOL_GPL(trace_seq_bitmask); * trace_seq_printf is used to store strings into a special * buffer (@s). Then the output may be either used by * the sequencer or pulled into another buffer. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) +void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) { unsigned int len = TRACE_SEQ_BUF_LEFT(s); int ret; if (s->full || !len) - return 0; + return; ret = vsnprintf(s->buffer + s->len, len, fmt, args); /* If we can't write it all, don't bother writing anything */ if (ret >= len) { s->full = 1; - return 0; + return; } s->len += ret; - - return len; } EXPORT_SYMBOL_GPL(trace_seq_vprintf); @@ -178,28 +160,24 @@ EXPORT_SYMBOL_GPL(trace_seq_vprintf); * * This function will take the format and the binary array and finish * the conversion into the ASCII string within the buffer. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) +void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) { unsigned int len = TRACE_SEQ_BUF_LEFT(s); int ret; if (s->full || !len) - return 0; + return; ret = bstr_printf(s->buffer + s->len, len, fmt, binary); /* If we can't write it all, don't bother writing anything */ if (ret >= len) { s->full = 1; - return 0; + return; } s->len += ret; - - return len; } EXPORT_SYMBOL_GPL(trace_seq_bprintf); @@ -212,25 +190,21 @@ EXPORT_SYMBOL_GPL(trace_seq_bprintf); * copy to user routines. This function records a simple string * into a special buffer (@s) for later retrieval by a sequencer * or other mechanism. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_puts(struct trace_seq *s, const char *str) +void trace_seq_puts(struct trace_seq *s, const char *str) { unsigned int len = strlen(str); if (s->full) - return 0; + return; if (len > TRACE_SEQ_BUF_LEFT(s)) { s->full = 1; - return 0; + return; } memcpy(s->buffer + s->len, str, len); s->len += len; - - return len; } EXPORT_SYMBOL_GPL(trace_seq_puts); @@ -243,22 +217,18 @@ EXPORT_SYMBOL_GPL(trace_seq_puts); * copy to user routines. This function records a simple charater * into a special buffer (@s) for later retrieval by a sequencer * or other mechanism. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_putc(struct trace_seq *s, unsigned char c) +void trace_seq_putc(struct trace_seq *s, unsigned char c) { if (s->full) - return 0; + return; if (TRACE_SEQ_BUF_LEFT(s) < 1) { s->full = 1; - return 0; + return; } s->buffer[s->len++] = c; - - return 1; } EXPORT_SYMBOL_GPL(trace_seq_putc); @@ -271,23 +241,19 @@ EXPORT_SYMBOL_GPL(trace_seq_putc); * There may be cases where raw memory needs to be written into the * buffer and a strcpy() would not work. Using this function allows * for such cases. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) +void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) { if (s->full) - return 0; + return; if (len > TRACE_SEQ_BUF_LEFT(s)) { s->full = 1; - return 0; + return; } memcpy(s->buffer + s->len, mem, len); s->len += len; - - return len; } EXPORT_SYMBOL_GPL(trace_seq_putmem); @@ -303,20 +269,17 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem); * This is similar to trace_seq_putmem() except instead of just copying the * raw memory into the buffer it writes its ASCII representation of it * in hex characters. - * - * Returns how much it wrote to the buffer. */ -int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, +void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len) { unsigned char hex[HEX_CHARS]; const unsigned char *data = mem; unsigned int start_len; int i, j; - int cnt = 0; if (s->full) - return 0; + return; while (len) { start_len = min(len, HEX_CHARS - 1); @@ -335,9 +298,8 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, len -= j / 2; hex[j++] = ' '; - cnt += trace_seq_putmem(s, hex, j); + trace_seq_putmem(s, hex, j); } - return cnt; } EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); -- GitLab From 8e2e095cbecad21078332cd83ae7e61ecfe12c59 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 14 Nov 2014 11:42:06 -0500 Subject: [PATCH 5397/9457] tracing: Fix return value of ftrace_raw_output_prep() If the trace_seq of ftrace_raw_output_prep() is full this function returns TRACE_TYPE_PARTIAL_LINE, otherwise it returns zero. The problem is that TRACE_TYPE_PARTIAL_LINE happens to be zero! The thing is, the caller of ftrace_raw_output_prep() expects a success to be zero. Change that to expect it to be TRACE_TYPE_HANDLED. Link: http://lkml.kernel.org/r/20141114112522.GA2988@dhcp128.suse.cz Reminded-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/trace/ftrace.h | 2 +- kernel/trace/trace_output.c | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index f13471b5d27a..139b5067345b 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -277,7 +277,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ field = (typeof(field))iter->ent; \ \ ret = ftrace_raw_output_prep(iter, trace_event); \ - if (ret) \ + if (ret != TRACE_TYPE_HANDLED) \ return ret; \ \ trace_seq_printf(s, print); \ diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 163c11b6b8ff..723818bc83b4 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -196,10 +196,7 @@ int ftrace_raw_output_prep(struct trace_iterator *iter, trace_seq_init(p); trace_seq_printf(s, "%s: ", ftrace_event_name(event)); - if (trace_seq_has_overflowed(s)) - return TRACE_TYPE_PARTIAL_LINE; - - return 0; + return trace_handle_return(s); } EXPORT_SYMBOL(ftrace_raw_output_prep); -- GitLab From fcd4d35ecc1636c8ac50e3a6266a620eb8ff0626 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 21:03:13 +0100 Subject: [PATCH 5398/9457] netlink: Deletion of an unnecessary check before the function call "__module_get" The __module_get() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d479b32d5826..e1aad6eeac14 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -142,8 +142,7 @@ int netlink_add_tap(struct netlink_tap *nt) list_add_rcu(&nt->list, &netlink_tap_all); spin_unlock(&netlink_tap_lock); - if (nt->module) - __module_get(nt->module); + __module_get(nt->module); return 0; } -- GitLab From 77f31815e1d0a9ae2cb073fc5f9ef33e5f3df059 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 21:23:55 +0100 Subject: [PATCH 5399/9457] drm/i915: Replace dri1 functions with drm_noop Whether we'll reject them or no-op doesn't really matter ... Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 79 +++++---------------------------- 1 file changed, 10 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d1562281e607..887df56cb655 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -50,59 +50,6 @@ #include #include -static int i915_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_batchbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_cmdbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - -static int i915_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} static int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -248,12 +195,6 @@ static int i915_setparam(struct drm_device *dev, void *data, return 0; } -static int i915_set_status_page(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return -ENODEV; -} - static int i915_get_bridge_dev(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1090,23 +1031,23 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) } const struct drm_ioctl_desc i915_ioctls[] = { - DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), -- GitLab From ac883c84e45f44a671e6ebe2a4be41b3167c0261 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 21:24:54 +0100 Subject: [PATCH 5400/9457] drm/i915: Drop checks for initialization KMS always intializes, this was only a valid check when userspace was still in control of the kernel driver. v2: Comment that we outright reject all dri1/ums params. Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 887df56cb655..69d6c76f4c2d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -58,17 +58,11 @@ static int i915_getparam(struct drm_device *dev, void *data, drm_i915_getparam_t *param = data; int value; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - switch (param->param) { case I915_PARAM_IRQ_ACTIVE: - return -ENODEV; case I915_PARAM_ALLOW_BATCHBUFFER: - return -ENODEV; case I915_PARAM_LAST_DISPATCH: + /* Reject all old ums/dri params. */ return -ENODEV; case I915_PARAM_CHIPSET_ID: value = dev->pdev->device; @@ -168,15 +162,11 @@ static int i915_setparam(struct drm_device *dev, void *data, struct drm_i915_private *dev_priv = dev->dev_private; drm_i915_setparam_t *param = data; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: case I915_SETPARAM_ALLOW_BATCHBUFFER: + /* Reject all old ums/dri params. */ return -ENODEV; case I915_SETPARAM_NUM_USED_FENCES: -- GitLab From 71b14ab6184cc618d4c3557205113d3df51e2197 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 20:36:47 +0100 Subject: [PATCH 5401/9457] drm/i915: No-Op enter/leave vt gem ioctl We've killed ums support by now, it's time to reap the benefits. This one here is getting in the way of doing some ring init cleanup. Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 +-- drivers/gpu/drm/i915/i915_drv.h | 4 --- drivers/gpu/drm/i915/i915_gem.c | 55 --------------------------------- 3 files changed, 2 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 69d6c76f4c2d..6c9625305abc 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1047,8 +1047,8 @@ const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 100296475fb4..a52fba103ce9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2441,10 +2441,6 @@ int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); int i915_gem_set_tiling(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_get_tiling(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7985f7b28325..bd171092e86f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4976,61 +4976,6 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) dev_priv->gt.cleanup_ring(ring); } -int -i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - - if (i915_reset_in_progress(&dev_priv->gpu_error)) { - DRM_ERROR("Reenabling wedged hardware, good luck\n"); - atomic_set(&dev_priv->gpu_error.reset_counter, 0); - } - - mutex_lock(&dev->struct_mutex); - dev_priv->ums.mm_suspended = 0; - - ret = i915_gem_init_hw(dev); - if (ret != 0) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - - BUG_ON(!list_empty(&dev_priv->gtt.base.active_list)); - - ret = drm_irq_install(dev, dev->pdev->irq); - if (ret) - goto cleanup_ringbuffer; - mutex_unlock(&dev->struct_mutex); - - return 0; - -cleanup_ringbuffer: - i915_gem_cleanup_ringbuffer(dev); - dev_priv->ums.mm_suspended = 1; - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -int -i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - - mutex_lock(&dev->struct_mutex); - drm_irq_uninstall(dev); - mutex_unlock(&dev->struct_mutex); - - return i915_gem_suspend(dev); -} - void i915_gem_lastclose(struct drm_device *dev) { -- GitLab From daaf427c6ab392bedcd018e326b2ffa1e1110cd6 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 18 Nov 2014 17:32:16 -0800 Subject: [PATCH 5402/9457] bpf: fix arraymap NULL deref and missing overflow and zero size checks - fix NULL pointer dereference: kernel/bpf/arraymap.c:41 array_map_alloc() error: potential null dereference 'array'. (kzalloc returns null) kernel/bpf/arraymap.c:41 array_map_alloc() error: we previously assumed 'array' could be null (see line 40) - integer overflow check was missing in arraymap (hashmap checks for overflow via kmalloc_array()) - arraymap can round_up(value_size, 8) to zero. check was missing. - hashmap was missing zero size check as well, since roundup_pow_of_two() can truncate into zero - found a typo in the arraymap comment and unnecessary empty line Fix all of these issues and make both overflow checks explicit U32 in size. Reported-by: kbuild test robot Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- kernel/bpf/arraymap.c | 17 +++++++++++------ kernel/bpf/hashtab.c | 5 +++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 58b80c137afd..9eb4d8a7cd87 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -25,7 +25,7 @@ struct bpf_array { static struct bpf_map *array_map_alloc(union bpf_attr *attr) { struct bpf_array *array; - u32 elem_size; + u32 elem_size, array_size; /* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || @@ -34,11 +34,17 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) elem_size = round_up(attr->value_size, 8); + /* check round_up into zero and u32 overflow */ + if (elem_size == 0 || + attr->max_entries > (U32_MAX - sizeof(*array)) / elem_size) + return ERR_PTR(-ENOMEM); + + array_size = sizeof(*array) + attr->max_entries * elem_size; + /* allocate all map elements and zero-initialize them */ - array = kzalloc(sizeof(*array) + attr->max_entries * elem_size, - GFP_USER | __GFP_NOWARN); + array = kzalloc(array_size, GFP_USER | __GFP_NOWARN); if (!array) { - array = vzalloc(array->map.max_entries * array->elem_size); + array = vzalloc(array_size); if (!array) return ERR_PTR(-ENOMEM); } @@ -51,7 +57,6 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) array->elem_size = elem_size; return &array->map; - } /* Called from syscall or from eBPF program */ @@ -101,7 +106,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, return -E2BIG; if (map_flags == BPF_NOEXIST) - /* all elemenets already exist */ + /* all elements already exist */ return -EEXIST; memcpy(array->value + array->elem_size * index, value, array->elem_size); diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index d234a012f046..b3ba43674310 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -65,6 +65,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) goto free_htab; err = -ENOMEM; + /* prevent zero size kmalloc and check for u32 overflow */ + if (htab->n_buckets == 0 || + htab->n_buckets > U32_MAX / sizeof(struct hlist_head)) + goto free_htab; + htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct hlist_head), GFP_USER | __GFP_NOWARN); -- GitLab From 2ab4bd8ea3a6954bc79a9bbeb291cd6c2d6213a7 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 17 Oct 2014 11:05:50 -0500 Subject: [PATCH 5403/9457] dlm: adopt orphan locks A process may exit, leaving an orphan lock in the lockspace. This adds the capability for another process to acquire the orphan lock. Acquiring the orphan just moves the lock from the orphan list onto the acquiring process's list of locks. An adopting process must specify the resource name and mode of the lock it wants to adopt. If a matching lock is found, the lock is moved to the caller's 's list of locks, and the lkid of the lock is returned like the lkid of a new lock. If an orphan with a different mode is found, then -EAGAIN is returned. If no orphan lock is found on the resource, then -ENOENT is returned. No async completion is used because the result is immediately available. Also, when orphans are purged, allow a zero nodeid to refer to the local nodeid so the caller does not need to look up the local nodeid. Signed-off-by: David Teigland --- fs/dlm/lock.c | 76 ++++++++++++++++++++++++++++++- fs/dlm/lock.h | 3 ++ fs/dlm/user.c | 13 +++++- include/uapi/linux/dlmconstants.h | 2 +- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 83f3d5520307..35502d4046f5 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -5886,6 +5886,78 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, return error; } +/* + * The caller asks for an orphan lock on a given resource with a given mode. + * If a matching lock exists, it's moved to the owner's list of locks and + * the lkid is returned. + */ + +int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, + int mode, uint32_t flags, void *name, unsigned int namelen, + unsigned long timeout_cs, uint32_t *lkid) +{ + struct dlm_lkb *lkb; + struct dlm_user_args *ua; + int found_other_mode = 0; + int found = 0; + int rv = 0; + + mutex_lock(&ls->ls_orphans_mutex); + list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) { + if (lkb->lkb_resource->res_length != namelen) + continue; + if (memcmp(lkb->lkb_resource->res_name, name, namelen)) + continue; + if (lkb->lkb_grmode != mode) { + found_other_mode = 1; + continue; + } + + found = 1; + list_del_init(&lkb->lkb_ownqueue); + lkb->lkb_flags &= ~DLM_IFL_ORPHAN; + *lkid = lkb->lkb_id; + break; + } + mutex_unlock(&ls->ls_orphans_mutex); + + if (!found && found_other_mode) { + rv = -EAGAIN; + goto out; + } + + if (!found) { + rv = -ENOENT; + goto out; + } + + lkb->lkb_exflags = flags; + lkb->lkb_ownpid = (int) current->pid; + + ua = lkb->lkb_ua; + + ua->proc = ua_tmp->proc; + ua->xid = ua_tmp->xid; + ua->castparam = ua_tmp->castparam; + ua->castaddr = ua_tmp->castaddr; + ua->bastparam = ua_tmp->bastparam; + ua->bastaddr = ua_tmp->bastaddr; + ua->user_lksb = ua_tmp->user_lksb; + + /* + * The lkb reference from the ls_orphans list was not + * removed above, and is now considered the reference + * for the proc locks list. + */ + + spin_lock(&ua->proc->locks_spin); + list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); + spin_unlock(&ua->proc->locks_spin); + out: + kfree(ua_tmp); + return rv; +} + int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid, char *lvb_in) { @@ -6029,7 +6101,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb) struct dlm_args args; int error; - hold_lkb(lkb); + hold_lkb(lkb); /* reference for the ls_orphans list */ mutex_lock(&ls->ls_orphans_mutex); list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans); mutex_unlock(&ls->ls_orphans_mutex); @@ -6217,7 +6289,7 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc, { int error = 0; - if (nodeid != dlm_our_nodeid()) { + if (nodeid && (nodeid != dlm_our_nodeid())) { error = send_purge(ls, nodeid, pid); } else { dlm_lock_recovery(ls); diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 5e0c72e36a9b..ed8ebd3a8593 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -49,6 +49,9 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, int mode, uint32_t flags, uint32_t lkid, char *lvb_in, unsigned long timeout_cs); +int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, + int mode, uint32_t flags, void *name, unsigned int namelen, + unsigned long timeout_cs, uint32_t *lkid); int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, uint32_t flags, uint32_t lkid, char *lvb_in); int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 142e21655eed..fb85f32e9eca 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -238,6 +238,7 @@ static int device_user_lock(struct dlm_user_proc *proc, { struct dlm_ls *ls; struct dlm_user_args *ua; + uint32_t lkid; int error = -ENOMEM; ls = dlm_find_lockspace_local(proc->lockspace); @@ -260,12 +261,20 @@ static int device_user_lock(struct dlm_user_proc *proc, ua->bastaddr = params->bastaddr; ua->xid = params->xid; - if (params->flags & DLM_LKF_CONVERT) + if (params->flags & DLM_LKF_CONVERT) { error = dlm_user_convert(ls, ua, params->mode, params->flags, params->lkid, params->lvb, (unsigned long) params->timeout); - else { + } else if (params->flags & DLM_LKF_ORPHAN) { + error = dlm_user_adopt_orphan(ls, ua, + params->mode, params->flags, + params->name, params->namelen, + (unsigned long) params->timeout, + &lkid); + if (!error) + error = lkid; + } else { error = dlm_user_request(ls, ua, params->mode, params->flags, params->name, params->namelen, diff --git a/include/uapi/linux/dlmconstants.h b/include/uapi/linux/dlmconstants.h index 47bf08dc7566..2857bdc5b27b 100644 --- a/include/uapi/linux/dlmconstants.h +++ b/include/uapi/linux/dlmconstants.h @@ -114,7 +114,7 @@ * * DLM_LKF_ORPHAN * - * not yet implemented + * Acquire an orphan lock. * * DLM_LKF_ALTPR * -- GitLab From b4c1b70823721e9edb19a839188e4dae50ce878d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 19 Nov 2014 12:30:28 +0100 Subject: [PATCH 5404/9457] ath9k_common: make sure DEBUG_FS and RELAY enabled currently ath9k_common depends on this components. Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ca101d7cb99f..fee0cadb0f5e 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -3,6 +3,8 @@ config ATH9K_HW config ATH9K_COMMON tristate select ATH_COMMON + select DEBUG_FS + select RELAY config ATH9K_DFS_DEBUGFS def_bool y depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED -- GitLab From 0d454e4a443178863f858cdafac870ceb1989407 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 17:17:46 +0100 Subject: [PATCH 5405/9457] udf: Deletion of unnecessary checks before the function call "iput" The iput() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Jan Kara --- fs/udf/super.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index e229315bbf7a..f93c65d6c7d9 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2237,8 +2237,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) return 0; error_out: - if (sbi->s_vat_inode) - iput(sbi->s_vat_inode); + iput(sbi->s_vat_inode); #ifdef CONFIG_UDF_NLS if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) unload_nls(sbi->s_nls_map); @@ -2291,8 +2290,7 @@ static void udf_put_super(struct super_block *sb) sbi = UDF_SB(sb); - if (sbi->s_vat_inode) - iput(sbi->s_vat_inode); + iput(sbi->s_vat_inode); #ifdef CONFIG_UDF_NLS if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) unload_nls(sbi->s_nls_map); -- GitLab From fdf2657bc81b10dee856ec9f8fe5b201c0561e9d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 18:29:10 +0100 Subject: [PATCH 5406/9457] udf: One function call less in udf_fill_super() after error detection The iput() function was called in up to three cases by the udf_fill_super() function during error handling even if the passed data structure element contained still a null pointer. This implementation detail could be improved by the introduction of another jump label. Signed-off-by: Markus Elfring Signed-off-by: Jan Kara --- fs/udf/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index f93c65d6c7d9..3ccb2f11fc76 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2082,12 +2082,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) mutex_init(&sbi->s_alloc_mutex); if (!udf_parse_options((char *)options, &uopt, false)) - goto error_out; + goto parse_options_failure; if (uopt.flags & (1 << UDF_FLAG_UTF8) && uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { udf_err(sb, "utf8 cannot be combined with iocharset\n"); - goto error_out; + goto parse_options_failure; } #ifdef CONFIG_UDF_NLS if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { @@ -2238,6 +2238,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) error_out: iput(sbi->s_vat_inode); +parse_options_failure: #ifdef CONFIG_UDF_NLS if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) unload_nls(sbi->s_nls_map); -- GitLab From 666547ff591cebdedc4679bf6b1b3f3383a8dea3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 6 Apr 2014 14:03:05 -0400 Subject: [PATCH 5407/9457] separate kernel- and userland-side msghdr Kernel-side struct msghdr is (currently) using the same layout as userland one, but it's not a one-to-one copy - even without considering 32bit compat issues, we have msg_iov, msg_name and msg_control copied to kernel[1]. It's fairly localized, so we get away with a few functions where that knowledge is needed (and we could shrink that set even more). Pretty much everything deals with the kernel-side variant and the few places that want userland one just use a bunch of force-casts to paper over the differences. The thing is, kernel-side definition of struct msghdr is *not* exposed in include/uapi - libc doesn't see it, etc. So we can add struct user_msghdr, with proper annotations and let the few places that ever deal with those beasts use it for userland pointers. Saner typechecking aside, that will allow to change the layout of kernel-side msghdr - e.g. replace msg_iov/msg_iovlen there with struct iov_iter, getting rid of the need to modify the iovec as we copy data to/from it, etc. We could introduce kernel_msghdr instead, but that would create much more noise - the absolute majority of the instances would need to have the type switched to kernel_msghdr and definition of struct msghdr in include/linux/socket.h is not going to be seen by userland anyway. This commit just introduces user_msghdr and switches the few places that are dealing with userland-side msghdr to it. [1] actually, it's even trickier than that - we copy msg_control for sendmsg, but keep the userland address on recvmsg. Signed-off-by: Al Viro --- arch/arm/kernel/sys_oabi-compat.c | 4 ++-- include/linux/socket.h | 16 +++++++++++++--- include/linux/syscalls.h | 6 +++--- net/compat.c | 4 ++-- net/socket.c | 29 ++++++++++++++++------------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index e90a3148f385..b83f3b7737fb 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -400,7 +400,7 @@ asmlinkage long sys_oabi_sendto(int fd, void __user *buff, return sys_sendto(fd, buff, len, flags, addr, addrlen); } -asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) +asmlinkage long sys_oabi_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags) { struct sockaddr __user *addr; int msg_namelen; @@ -446,7 +446,7 @@ asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args) break; case SYS_SENDMSG: if (copy_from_user(a, args, 3 * sizeof(long)) == 0) - r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]); + r = sys_oabi_sendmsg(a[0], (struct user_msghdr __user *)a[1], a[2]); break; default: r = sys_socketcall(call, args); diff --git a/include/linux/socket.h b/include/linux/socket.h index bb9b83640070..51bd6668b80e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -53,10 +53,20 @@ struct msghdr { __kernel_size_t msg_controllen; /* ancillary data buffer length */ unsigned int msg_flags; /* flags on received message */ }; + +struct user_msghdr { + void __user *msg_name; /* ptr to socket address structure */ + int msg_namelen; /* size of socket address structure */ + struct iovec __user *msg_iov; /* scatter/gather array */ + __kernel_size_t msg_iovlen; /* # elements in msg_iov */ + void __user *msg_control; /* ancillary data */ + __kernel_size_t msg_controllen; /* ancillary data buffer length */ + unsigned int msg_flags; /* flags on received message */ +}; /* For recvmmsg/sendmmsg */ struct mmsghdr { - struct msghdr msg_hdr; + struct user_msghdr msg_hdr; unsigned int msg_len; }; @@ -319,8 +329,8 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); struct timespec; /* The __sys_...msg variants allow MSG_CMSG_COMPAT */ -extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); -extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); +extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags); +extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags); extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index bda9b81357cc..c9afdc7a7f84 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -25,7 +25,7 @@ struct linux_dirent64; struct list_head; struct mmap_arg_struct; struct msgbuf; -struct msghdr; +struct user_msghdr; struct mmsghdr; struct msqid_ds; struct new_utsname; @@ -601,13 +601,13 @@ asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); asmlinkage long sys_send(int, void __user *, size_t, unsigned); asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, struct sockaddr __user *, int); -asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); +asmlinkage long sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags); asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg, unsigned int vlen, unsigned flags); asmlinkage long sys_recv(int, void __user *, size_t, unsigned); asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *); -asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); +asmlinkage long sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags); asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, unsigned int vlen, unsigned flags, struct timespec __user *timeout); diff --git a/net/compat.c b/net/compat.c index bc8aeefddf3f..562e920b07f0 100644 --- a/net/compat.c +++ b/net/compat.c @@ -740,7 +740,7 @@ COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, uns { if (flags & MSG_CMSG_COMPAT) return -EINVAL; - return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); } COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, @@ -756,7 +756,7 @@ COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, uns { if (flags & MSG_CMSG_COMPAT) return -EINVAL; - return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); } COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags) diff --git a/net/socket.c b/net/socket.c index fe20c319a0bb..0ae8147e3acc 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1989,8 +1989,11 @@ struct used_address { }; static int copy_msghdr_from_user(struct msghdr *kmsg, - struct msghdr __user *umsg) + struct user_msghdr __user *umsg) { + /* We are relying on the (currently) identical layouts. Once + * the kernel-side changes, this place will need to be updated + */ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) return -EFAULT; @@ -2005,7 +2008,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, return 0; } -static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, struct msghdr *msg_sys, unsigned int flags, struct used_address *used_address) { @@ -2123,7 +2126,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, * BSD sendmsg interface */ -long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) +long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags) { int fput_needed, err; struct msghdr msg_sys; @@ -2140,7 +2143,7 @@ long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) return err; } -SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) +SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) { if (flags & MSG_CMSG_COMPAT) return -EINVAL; @@ -2177,7 +2180,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, while (datagrams < vlen) { if (MSG_CMSG_COMPAT & flags) { - err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, + err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry, &msg_sys, flags, &used_address); if (err < 0) break; @@ -2185,7 +2188,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, ++compat_entry; } else { err = ___sys_sendmsg(sock, - (struct msghdr __user *)entry, + (struct user_msghdr __user *)entry, &msg_sys, flags, &used_address); if (err < 0) break; @@ -2215,7 +2218,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, return __sys_sendmmsg(fd, mmsg, vlen, flags); } -static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, struct msghdr *msg_sys, unsigned int flags, int nosec) { struct compat_msghdr __user *msg_compat = @@ -2311,7 +2314,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, * BSD recvmsg interface */ -long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) +long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags) { int fput_needed, err; struct msghdr msg_sys; @@ -2328,7 +2331,7 @@ long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) return err; } -SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, +SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) { if (flags & MSG_CMSG_COMPAT) @@ -2373,7 +2376,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, * No need to ask LSM for more than the first datagram. */ if (MSG_CMSG_COMPAT & flags) { - err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, + err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry, &msg_sys, flags & ~MSG_WAITFORONE, datagrams); if (err < 0) @@ -2382,7 +2385,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, ++compat_entry; } else { err = ___sys_recvmsg(sock, - (struct msghdr __user *)entry, + (struct user_msghdr __user *)entry, &msg_sys, flags & ~MSG_WAITFORONE, datagrams); if (err < 0) @@ -2571,13 +2574,13 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (int __user *)a[4]); break; case SYS_SENDMSG: - err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); + err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]); break; case SYS_SENDMMSG: err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); break; case SYS_RECVMSG: - err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); + err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]); break; case SYS_RECVMMSG: err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], -- GitLab From 0844932009e1656726c6e9c369e694017b129378 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 9 Nov 2014 22:33:45 -0500 Subject: [PATCH 5408/9457] {compat_,}verify_iovec(): switch to generic copying of iovecs use {compat_,}rw_copy_check_uvector(). As the result, we are guaranteed that all iovecs seen in ->msg_iov by ->sendmsg() and ->recvmsg() will pass access_ok(). Signed-off-by: Al Viro --- net/compat.c | 51 ++++++++++++++---------------------------------- net/core/iovec.c | 37 +++++++++++++---------------------- net/socket.c | 38 ++++++++---------------------------- 3 files changed, 37 insertions(+), 89 deletions(-) diff --git a/net/compat.c b/net/compat.c index 562e920b07f0..7b4b6ad13235 100644 --- a/net/compat.c +++ b/net/compat.c @@ -31,33 +31,6 @@ #include #include -static inline int iov_from_user_compat_to_kern(struct iovec *kiov, - struct compat_iovec __user *uiov32, - int niov) -{ - int tot_len = 0; - - while (niov > 0) { - compat_uptr_t buf; - compat_size_t len; - - if (get_user(len, &uiov32->iov_len) || - get_user(buf, &uiov32->iov_base)) - return -EFAULT; - - if (len > INT_MAX - tot_len) - len = INT_MAX - tot_len; - - tot_len += len; - kiov->iov_base = compat_ptr(buf); - kiov->iov_len = (__kernel_size_t) len; - uiov32++; - kiov++; - niov--; - } - return tot_len; -} - int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) { compat_uptr_t tmp1, tmp2, tmp3; @@ -80,13 +53,15 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) } /* I've named the args so it is easy to tell whose space the pointers are in. */ -int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, +int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *iov, struct sockaddr_storage *kern_address, int mode) { - int tot_len; + struct compat_iovec __user *p; + struct iovec *res; + int err; if (kern_msg->msg_name && kern_msg->msg_namelen) { - if (mode == VERIFY_READ) { + if (mode == WRITE) { int err = move_addr_to_kernel(kern_msg->msg_name, kern_msg->msg_namelen, kern_address); @@ -99,13 +74,17 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, kern_msg->msg_namelen = 0; } - tot_len = iov_from_user_compat_to_kern(kern_iov, - (struct compat_iovec __user *)kern_msg->msg_iov, - kern_msg->msg_iovlen); - if (tot_len >= 0) - kern_msg->msg_iov = kern_iov; + if (kern_msg->msg_iovlen > UIO_MAXIOV) + return -EMSGSIZE; - return tot_len; + p = (struct compat_iovec __user *)kern_msg->msg_iov; + err = compat_rw_copy_check_uvector(mode, p, kern_msg->msg_iovlen, + UIO_FASTIOV, iov, &res); + if (err >= 0) + kern_msg->msg_iov = res; + else if (res != iov) + kfree(res); + return err; } /* Bleech... */ diff --git a/net/core/iovec.c b/net/core/iovec.c index e1ec45ab1e63..86beeea61d72 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -37,13 +37,13 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode) { - int size, ct, err; + struct iovec *res; + int err; if (m->msg_name && m->msg_namelen) { - if (mode == VERIFY_READ) { - void __user *namep; - namep = (void __user __force *) m->msg_name; - err = move_addr_to_kernel(namep, m->msg_namelen, + if (mode == WRITE) { + void __user *namep = (void __user __force *)m->msg_name; + int err = move_addr_to_kernel(namep, m->msg_namelen, address); if (err < 0) return err; @@ -53,24 +53,15 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a m->msg_name = NULL; m->msg_namelen = 0; } - - size = m->msg_iovlen * sizeof(struct iovec); - if (copy_from_user(iov, (void __user __force *) m->msg_iov, size)) - return -EFAULT; - - m->msg_iov = iov; - err = 0; - - for (ct = 0; ct < m->msg_iovlen; ct++) { - size_t len = iov[ct].iov_len; - - if (len > INT_MAX - err) { - len = INT_MAX - err; - iov[ct].iov_len = len; - } - err += len; - } - + if (m->msg_iovlen > UIO_MAXIOV) + return -EMSGSIZE; + + err = rw_copy_check_uvector(mode, (void __user __force *)m->msg_iov, + m->msg_iovlen, UIO_FASTIOV, iov, &res); + if (err >= 0) + m->msg_iov = res; + else if (res != iov) + kfree(res); return err; } diff --git a/net/socket.c b/net/socket.c index 0ae8147e3acc..59020f0b583b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2032,24 +2032,14 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, return err; } - if (msg_sys->msg_iovlen > UIO_FASTIOV) { - err = -EMSGSIZE; - if (msg_sys->msg_iovlen > UIO_MAXIOV) - goto out; - err = -ENOMEM; - iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec), - GFP_KERNEL); - if (!iov) - goto out; - } - /* This will also move the address data into kernel space */ - if (MSG_CMSG_COMPAT & flags) { - err = verify_compat_iovec(msg_sys, iov, &address, VERIFY_READ); - } else - err = verify_iovec(msg_sys, iov, &address, VERIFY_READ); + if (MSG_CMSG_COMPAT & flags) + err = verify_compat_iovec(msg_sys, iovstack, &address, WRITE); + else + err = verify_iovec(msg_sys, iovstack, &address, WRITE); if (err < 0) goto out_freeiov; + iov = msg_sys->msg_iov; total_len = err; err = -ENOBUFS; @@ -2118,7 +2108,6 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, out_freeiov: if (iov != iovstack) kfree(iov); -out: return err; } @@ -2244,28 +2233,18 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, return err; } - if (msg_sys->msg_iovlen > UIO_FASTIOV) { - err = -EMSGSIZE; - if (msg_sys->msg_iovlen > UIO_MAXIOV) - goto out; - err = -ENOMEM; - iov = kmalloc(msg_sys->msg_iovlen * sizeof(struct iovec), - GFP_KERNEL); - if (!iov) - goto out; - } - /* Save the user-mode address (verify_iovec will change the * kernel msghdr to use the kernel address space) */ uaddr = (__force void __user *)msg_sys->msg_name; uaddr_len = COMPAT_NAMELEN(msg); if (MSG_CMSG_COMPAT & flags) - err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); + err = verify_compat_iovec(msg_sys, iovstack, &addr, READ); else - err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); + err = verify_iovec(msg_sys, iovstack, &addr, READ); if (err < 0) goto out_freeiov; + iov = msg_sys->msg_iov; total_len = err; cmsg_ptr = (unsigned long)msg_sys->msg_control; @@ -2306,7 +2285,6 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, out_freeiov: if (iov != iovstack) kfree(iov); -out: return err; } -- GitLab From 08adb7dabd4874cc5666b4490653b26534702ce0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 10 Nov 2014 20:23:13 -0500 Subject: [PATCH 5409/9457] fold verify_iovec() into copy_msghdr_from_user() ... and do the same on the compat side of things. Signed-off-by: Al Viro --- include/linux/socket.h | 1 - include/net/compat.h | 5 +-- net/compat.c | 52 ++++++++++------------- net/core/iovec.c | 38 ----------------- net/socket.c | 93 ++++++++++++++++++++++++------------------ 5 files changed, 77 insertions(+), 112 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 51bd6668b80e..de5222832be4 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -322,7 +322,6 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, extern unsigned long iov_pages(const struct iovec *iov, int offset, unsigned long nr_segs); -extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); diff --git a/include/net/compat.h b/include/net/compat.h index 3b603b199c01..42a9c8431177 100644 --- a/include/net/compat.h +++ b/include/net/compat.h @@ -40,9 +40,8 @@ int compat_sock_get_timestampns(struct sock *, struct timespec __user *); #define compat_mmsghdr mmsghdr #endif /* defined(CONFIG_COMPAT) */ -int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *); -int verify_compat_iovec(struct msghdr *, struct iovec *, - struct sockaddr_storage *, int); +ssize_t get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *, + struct sockaddr __user **, struct iovec **); asmlinkage long compat_sys_sendmsg(int, struct compat_msghdr __user *, unsigned int); asmlinkage long compat_sys_sendmmsg(int, struct compat_mmsghdr __user *, diff --git a/net/compat.c b/net/compat.c index 7b4b6ad13235..062f157d2a6b 100644 --- a/net/compat.c +++ b/net/compat.c @@ -31,14 +31,18 @@ #include #include -int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) +ssize_t get_compat_msghdr(struct msghdr *kmsg, + struct compat_msghdr __user *umsg, + struct sockaddr __user **save_addr, + struct iovec **iov) { - compat_uptr_t tmp1, tmp2, tmp3; + compat_uptr_t uaddr, uiov, tmp3; + ssize_t err; if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || - __get_user(tmp1, &umsg->msg_name) || + __get_user(uaddr, &umsg->msg_name) || __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || - __get_user(tmp2, &umsg->msg_iov) || + __get_user(uiov, &umsg->msg_iov) || __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) || __get_user(tmp3, &umsg->msg_control) || __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || @@ -46,44 +50,32 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) return -EFAULT; if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) kmsg->msg_namelen = sizeof(struct sockaddr_storage); - kmsg->msg_name = compat_ptr(tmp1); - kmsg->msg_iov = compat_ptr(tmp2); kmsg->msg_control = compat_ptr(tmp3); - return 0; -} -/* I've named the args so it is easy to tell whose space the pointers are in. */ -int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *iov, - struct sockaddr_storage *kern_address, int mode) -{ - struct compat_iovec __user *p; - struct iovec *res; - int err; + if (save_addr) + *save_addr = compat_ptr(uaddr); - if (kern_msg->msg_name && kern_msg->msg_namelen) { - if (mode == WRITE) { - int err = move_addr_to_kernel(kern_msg->msg_name, - kern_msg->msg_namelen, - kern_address); + if (uaddr && kmsg->msg_namelen) { + if (!save_addr) { + err = move_addr_to_kernel(compat_ptr(uaddr), + kmsg->msg_namelen, + kmsg->msg_name); if (err < 0) return err; } - kern_msg->msg_name = kern_address; } else { - kern_msg->msg_name = NULL; - kern_msg->msg_namelen = 0; + kmsg->msg_name = NULL; + kmsg->msg_namelen = 0; } - if (kern_msg->msg_iovlen > UIO_MAXIOV) + if (kmsg->msg_iovlen > UIO_MAXIOV) return -EMSGSIZE; - p = (struct compat_iovec __user *)kern_msg->msg_iov; - err = compat_rw_copy_check_uvector(mode, p, kern_msg->msg_iovlen, - UIO_FASTIOV, iov, &res); + err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE, + compat_ptr(uiov), kmsg->msg_iovlen, + UIO_FASTIOV, *iov, iov); if (err >= 0) - kern_msg->msg_iov = res; - else if (res != iov) - kfree(res); + kmsg->msg_iov = *iov; return err; } diff --git a/net/core/iovec.c b/net/core/iovec.c index 86beeea61d72..dcbe98b3726a 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -27,44 +27,6 @@ #include #include -/* - * Verify iovec. The caller must ensure that the iovec is big enough - * to hold the message iovec. - * - * Save time not doing access_ok. copy_*_user will make this work - * in any case. - */ - -int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode) -{ - struct iovec *res; - int err; - - if (m->msg_name && m->msg_namelen) { - if (mode == WRITE) { - void __user *namep = (void __user __force *)m->msg_name; - int err = move_addr_to_kernel(namep, m->msg_namelen, - address); - if (err < 0) - return err; - } - m->msg_name = address; - } else { - m->msg_name = NULL; - m->msg_namelen = 0; - } - if (m->msg_iovlen > UIO_MAXIOV) - return -EMSGSIZE; - - err = rw_copy_check_uvector(mode, (void __user __force *)m->msg_iov, - m->msg_iovlen, UIO_FASTIOV, iov, &res); - if (err >= 0) - m->msg_iov = res; - else if (res != iov) - kfree(res); - return err; -} - /* * And now for the all-in-one: copy and checksum from a user iovec * directly to a datagram diff --git a/net/socket.c b/net/socket.c index 59020f0b583b..ee3ee39eefa5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1988,16 +1988,26 @@ struct used_address { unsigned int name_len; }; -static int copy_msghdr_from_user(struct msghdr *kmsg, - struct user_msghdr __user *umsg) +static ssize_t copy_msghdr_from_user(struct msghdr *kmsg, + struct user_msghdr __user *umsg, + struct sockaddr __user **save_addr, + struct iovec **iov) { - /* We are relying on the (currently) identical layouts. Once - * the kernel-side changes, this place will need to be updated - */ - if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) + struct sockaddr __user *uaddr; + struct iovec __user *uiov; + ssize_t err; + + if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || + __get_user(uaddr, &umsg->msg_name) || + __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || + __get_user(uiov, &umsg->msg_iov) || + __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) || + __get_user(kmsg->msg_control, &umsg->msg_control) || + __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || + __get_user(kmsg->msg_flags, &umsg->msg_flags)) return -EFAULT; - if (kmsg->msg_name == NULL) + if (!uaddr) kmsg->msg_namelen = 0; if (kmsg->msg_namelen < 0) @@ -2005,7 +2015,31 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) kmsg->msg_namelen = sizeof(struct sockaddr_storage); - return 0; + + if (save_addr) + *save_addr = uaddr; + + if (uaddr && kmsg->msg_namelen) { + if (!save_addr) { + err = move_addr_to_kernel(uaddr, kmsg->msg_namelen, + kmsg->msg_name); + if (err < 0) + return err; + } + } else { + kmsg->msg_name = NULL; + kmsg->msg_namelen = 0; + } + + if (kmsg->msg_iovlen > UIO_MAXIOV) + return -EMSGSIZE; + + err = rw_copy_check_uvector(save_addr ? READ : WRITE, + uiov, kmsg->msg_iovlen, + UIO_FASTIOV, *iov, iov); + if (err >= 0) + kmsg->msg_iov = *iov; + return err; } static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, @@ -2020,26 +2054,17 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, __attribute__ ((aligned(sizeof(__kernel_size_t)))); /* 20 is size of ipv6_pktinfo */ unsigned char *ctl_buf = ctl; - int err, ctl_len, total_len; + int ctl_len, total_len; + ssize_t err; - err = -EFAULT; - if (MSG_CMSG_COMPAT & flags) { - if (get_compat_msghdr(msg_sys, msg_compat)) - return -EFAULT; - } else { - err = copy_msghdr_from_user(msg_sys, msg); - if (err) - return err; - } + msg_sys->msg_name = &address; - /* This will also move the address data into kernel space */ if (MSG_CMSG_COMPAT & flags) - err = verify_compat_iovec(msg_sys, iovstack, &address, WRITE); + err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov); else - err = verify_iovec(msg_sys, iovstack, &address, WRITE); + err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov); if (err < 0) goto out_freeiov; - iov = msg_sys->msg_iov; total_len = err; err = -ENOBUFS; @@ -2215,36 +2240,24 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; unsigned long cmsg_ptr; - int err, total_len, len; + int total_len, len; + ssize_t err; /* kernel mode address */ struct sockaddr_storage addr; /* user mode address pointers */ struct sockaddr __user *uaddr; - int __user *uaddr_len; + int __user *uaddr_len = COMPAT_NAMELEN(msg); - if (MSG_CMSG_COMPAT & flags) { - if (get_compat_msghdr(msg_sys, msg_compat)) - return -EFAULT; - } else { - err = copy_msghdr_from_user(msg_sys, msg); - if (err) - return err; - } + msg_sys->msg_name = &addr; - /* Save the user-mode address (verify_iovec will change the - * kernel msghdr to use the kernel address space) - */ - uaddr = (__force void __user *)msg_sys->msg_name; - uaddr_len = COMPAT_NAMELEN(msg); if (MSG_CMSG_COMPAT & flags) - err = verify_compat_iovec(msg_sys, iovstack, &addr, READ); + err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov); else - err = verify_iovec(msg_sys, iovstack, &addr, READ); + err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov); if (err < 0) goto out_freeiov; - iov = msg_sys->msg_iov; total_len = err; cmsg_ptr = (unsigned long)msg_sys->msg_control; -- GitLab From 232365f660b0016dcf618723707f91f4a95013db Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 10 Nov 2014 17:30:00 -0500 Subject: [PATCH 5410/9457] bury skb_copy_to_page() no callers since 3.0 Signed-off-by: Al Viro --- include/net/sock.h | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 83a669f83bae..df9b89bce8ff 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1884,29 +1884,6 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from, return 0; } -static inline int skb_copy_to_page(struct sock *sk, char __user *from, - struct sk_buff *skb, struct page *page, - int off, int copy) -{ - if (skb->ip_summed == CHECKSUM_NONE) { - int err = 0; - __wsum csum = csum_and_copy_from_user(from, - page_address(page) + off, - copy, 0, &err); - if (err) - return err; - skb->csum = csum_block_add(skb->csum, csum, skb->len); - } else if (copy_from_user(page_address(page) + off, from, copy)) - return -EFAULT; - - skb->len += copy; - skb->data_len += copy; - skb->truesize += copy; - sk->sk_wmem_queued += copy; - sk_mem_charge(sk, copy); - return 0; -} - /** * sk_wmem_alloc_get - returns write allocations * @sk: socket -- GitLab From 16a8ef2751801346f1f76a18685b2beb63cd170f Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 16 Nov 2014 14:46:28 +0100 Subject: [PATCH 5411/9457] tracing: Deletion of an unnecessary check before iput() The iput() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Link: http://lkml.kernel.org/r/5468F875.7080907@users.sourceforge.net Signed-off-by: Markus Elfring Signed-off-by: Steven Rostedt --- kernel/trace/trace_uprobe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index fd76f8e108ef..8520acc34b18 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -552,8 +552,7 @@ static int create_trace_uprobe(int argc, char **argv) return ret; fail_address_parse: - if (inode) - iput(inode); + iput(inode); pr_info("Failed to parse address or file.\n"); -- GitLab From 6793b3cd5da817c4be218bd8632f07cf4d2b0d26 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 19 Nov 2014 14:48:59 +0100 Subject: [PATCH 5412/9457] clk_mux: Fix set_parent doing the wrong thing when INDEX_BIT && index >= 3 If CLK_MUX_INDEX_BIT is set, then each bit turns on / off a single parent, so theoretically multiple parents could be enabled at the same time, but in practice only one bit should ever be 1. So to select parent 0, set the register (*) to 0x01, to select parent 1 set it 0x02, parent 2, 0x04, parent 3, 0x08, etc. But the current code does: if (mux->flags & CLK_MUX_INDEX_BIT) index = (1 << ffs(index)); Which means that: For an input index of 0, ffs returns 0, so we set the register to 0x01, ok. For an input index of 1, ffs returns 1, so we set the register to 0x02, ok. For an input index of 2, ffs returns 2, so we set the register to 0x04, ok. For an input index of 3, ffs returns 1, so we set the register to 0x02, not good! The code should simply be: if (mux->flags & CLK_MUX_INDEX_BIT) index = 1 << index; Which always does the right thing, this commit fixes this. Signed-off-by: Hans de Goede Signed-off-by: Michael Turquette --- drivers/clk/clk-mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 4f96ff3ba728..6e1ecf94bf58 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) else { if (mux->flags & CLK_MUX_INDEX_BIT) - index = (1 << ffs(index)); + index = 1 << index; if (mux->flags & CLK_MUX_INDEX_ONE) index++; -- GitLab From 7e79c5f8cad2ac1dc26c03e1aa16216391a04dad Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Thu, 30 Oct 2014 11:54:50 -0600 Subject: [PATCH 5413/9457] PCI: Add informational printk for invalid BARs As a consequence of restoring the detection of invalid BARs, add a new informational printk like the following when such occurrences are encountered. pci ssss:bb:dd.f: [Firmware Bug]: reg 0xXX: invalid BAR (can't size) Reported-by: William Unruh Reported-by: Martin Lucina Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas CC: Matthew Wilcox --- drivers/pci/probe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 529fcd782e43..6029ad786146 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -247,8 +247,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, goto fail; sz64 = pci_size(l64, sz64, mask64); - if (!sz64) + if (!sz64) { + dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n", + pos); goto fail; + } if (res->flags & IORESOURCE_MEM_64) { if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && -- GitLab From 26ff46c6f23bb1497aaa1364a5c73a109493b653 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Tue, 11 Nov 2014 08:04:50 -0700 Subject: [PATCH 5414/9457] PCI: Remove fixed parameter in pci_iov_resource_bar() pci_iov_resource_bar() always sets its 'pci_bar_type' parameter to 'pci_bar_unknown'. Drop the parameter and just use 'pci_bar_unknown' directly in the callers. No functional change intended. Signed-off-by: Myron Stowe Signed-off-by: Bjorn Helgaas CC: Chris Wright CC: Yu Zhao --- drivers/pci/iov.c | 11 +++-------- drivers/pci/pci.c | 3 ++- drivers/pci/pci.h | 6 ++---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4d109c07294a..4b3a4eaad996 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -479,20 +479,16 @@ void pci_iov_release(struct pci_dev *dev) * pci_iov_resource_bar - get position of the SR-IOV BAR * @dev: the PCI device * @resno: the resource number - * @type: the BAR type to be filled in * * Returns position of the BAR encapsulated in the SR-IOV capability. */ -int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type) +int pci_iov_resource_bar(struct pci_dev *dev, int resno) { if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) return 0; BUG_ON(!dev->is_physfn); - *type = pci_bar_unknown; - return dev->sriov->pos + PCI_SRIOV_BAR + 4 * (resno - PCI_IOV_RESOURCES); } @@ -510,13 +506,12 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) { struct resource tmp; - enum pci_bar_type type; - int reg = pci_iov_resource_bar(dev, resno, &type); + int reg = pci_iov_resource_bar(dev, resno); if (!reg) return 0; - __pci_read_base(dev, type, &tmp, reg); + __pci_read_base(dev, pci_bar_unknown, &tmp, reg); return resource_alignment(&tmp); } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 625a4ace10b4..7bf246595c63 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4180,7 +4180,8 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) return dev->rom_base_reg; } else if (resno < PCI_BRIDGE_RESOURCES) { /* device specific resource */ - reg = pci_iov_resource_bar(dev, resno, type); + *type = pci_bar_unknown; + reg = pci_iov_resource_bar(dev, resno); if (reg) return reg; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0601890db22d..a0905a0985ce 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -251,8 +251,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) #ifdef CONFIG_PCI_IOV int pci_iov_init(struct pci_dev *dev); void pci_iov_release(struct pci_dev *dev); -int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); +int pci_iov_resource_bar(struct pci_dev *dev, int resno); resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); void pci_restore_iov_state(struct pci_dev *dev); int pci_iov_bus_range(struct pci_bus *bus); @@ -266,8 +265,7 @@ static inline void pci_iov_release(struct pci_dev *dev) { } -static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type) +static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno) { return 0; } -- GitLab From cb8dda90c28e2a13a007ef675a25db6a79991630 Mon Sep 17 00:00:00 2001 From: Jianhua Xie Date: Wed, 19 Nov 2014 16:48:58 +0800 Subject: [PATCH 5415/9457] bonding: change AD_LINK_SPEED_BITMASK to enum to suport more speed Port Key was determined as 16 bits according to the link speed, duplex and user key (which is yet not supported). In the old speed field, 5 bits are for speed [1|10|100|1000|10000]Mbps as below: -------------------------------------------------------------- Port key :| User key | Speed | Duplex| -------------------------------------------------------------- 16 6 1 0 This patch keeps the old layout, but changes AD_LINK_SPEED_BITMASK from bit type to an enum type. In this way, the speed field can expand speed type from 5 to 32. CC: Jay Vosburgh CC: Veaceslav Falico CC: Andy Gospodarek CC: David S. Miller Signed-off-by: Jianhua Xie Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 66 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0a32143af12b..6bc27d9a8670 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -79,15 +79,17 @@ * -------------------------------------------------------------- * 16 6 1 0 */ -#define AD_DUPLEX_KEY_BITS 0x1 -#define AD_SPEED_KEY_BITS 0x3E -#define AD_USER_KEY_BITS 0xFFC0 - -#define AD_LINK_SPEED_BITMASK_1MBPS 0x1 -#define AD_LINK_SPEED_BITMASK_10MBPS 0x2 -#define AD_LINK_SPEED_BITMASK_100MBPS 0x4 -#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 -#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10 +#define AD_DUPLEX_KEY_MASKS 0x1 +#define AD_SPEED_KEY_MASKS 0x3E +#define AD_USER_KEY_MASKS 0xFFC0 + +enum ad_link_speed_type { + AD_LINK_SPEED_1MBPS = 1, + AD_LINK_SPEED_10MBPS, + AD_LINK_SPEED_100MBPS, + AD_LINK_SPEED_1000MBPS, + AD_LINK_SPEED_10000MBPS +}; /* compare MAC addresses */ #define MAC_ADDRESS_EQUAL(A, B) \ @@ -240,12 +242,12 @@ static inline int __check_agg_selection_timer(struct port *port) * __get_link_speed - get a port's speed * @port: the port we're looking at * - * Return @port's speed in 802.3ad bitmask format. i.e. one of: + * Return @port's speed in 802.3ad enum format. i.e. one of: * 0, - * %AD_LINK_SPEED_BITMASK_10MBPS, - * %AD_LINK_SPEED_BITMASK_100MBPS, - * %AD_LINK_SPEED_BITMASK_1000MBPS, - * %AD_LINK_SPEED_BITMASK_10000MBPS + * %AD_LINK_SPEED_10MBPS, + * %AD_LINK_SPEED_100MBPS, + * %AD_LINK_SPEED_1000MBPS, + * %AD_LINK_SPEED_10000MBPS */ static u16 __get_link_speed(struct port *port) { @@ -262,19 +264,19 @@ static u16 __get_link_speed(struct port *port) else { switch (slave->speed) { case SPEED_10: - speed = AD_LINK_SPEED_BITMASK_10MBPS; + speed = AD_LINK_SPEED_10MBPS; break; case SPEED_100: - speed = AD_LINK_SPEED_BITMASK_100MBPS; + speed = AD_LINK_SPEED_100MBPS; break; case SPEED_1000: - speed = AD_LINK_SPEED_BITMASK_1000MBPS; + speed = AD_LINK_SPEED_1000MBPS; break; case SPEED_10000: - speed = AD_LINK_SPEED_BITMASK_10000MBPS; + speed = AD_LINK_SPEED_10000MBPS; break; default: @@ -625,19 +627,19 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) if (aggregator->num_of_ports) { switch (__get_link_speed(aggregator->lag_ports)) { - case AD_LINK_SPEED_BITMASK_1MBPS: + case AD_LINK_SPEED_1MBPS: bandwidth = aggregator->num_of_ports; break; - case AD_LINK_SPEED_BITMASK_10MBPS: + case AD_LINK_SPEED_10MBPS: bandwidth = aggregator->num_of_ports * 10; break; - case AD_LINK_SPEED_BITMASK_100MBPS: + case AD_LINK_SPEED_100MBPS: bandwidth = aggregator->num_of_ports * 100; break; - case AD_LINK_SPEED_BITMASK_1000MBPS: + case AD_LINK_SPEED_1000MBPS: bandwidth = aggregator->num_of_ports * 1000; break; - case AD_LINK_SPEED_BITMASK_10000MBPS: + case AD_LINK_SPEED_10000MBPS: bandwidth = aggregator->num_of_ports * 10000; break; default: @@ -1011,7 +1013,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) port->sm_rx_state); switch (port->sm_rx_state) { case AD_RX_INITIALIZE: - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; else port->sm_vars |= AD_PORT_LACP_ENABLED; @@ -1318,7 +1320,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr) /* update the new aggregator's parameters * if port was responsed from the end-user */ - if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) + if (port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS) /* if port is full duplex */ port->aggregator->is_individual = false; else @@ -1846,7 +1848,7 @@ void bond_3ad_bind_slave(struct slave *slave) /* if the port is not full duplex, then the port should be not * lacp Enabled */ - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; /* actor system is the bond's system */ port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; @@ -2214,7 +2216,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) spin_lock_bh(&slave->bond->mode_lock); - port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; + port->actor_admin_port_key &= ~AD_SPEED_KEY_MASKS; port->actor_oper_port_key = port->actor_admin_port_key |= (__get_link_speed(port) << 1); netdev_dbg(slave->bond->dev, "Port %d changed speed\n", port->actor_port_number); @@ -2247,7 +2249,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) spin_lock_bh(&slave->bond->mode_lock); - port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_MASKS; port->actor_oper_port_key = port->actor_admin_port_key |= __get_duplex(port); netdev_dbg(slave->bond->dev, "Port %d changed duplex\n", port->actor_port_number); @@ -2289,18 +2291,18 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) */ if (link == BOND_LINK_UP) { port->is_enabled = true; - port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_MASKS; port->actor_oper_port_key = port->actor_admin_port_key |= __get_duplex(port); - port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; + port->actor_admin_port_key &= ~AD_SPEED_KEY_MASKS; port->actor_oper_port_key = port->actor_admin_port_key |= (__get_link_speed(port) << 1); } else { /* link has failed */ port->is_enabled = false; - port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; + port->actor_admin_port_key &= ~AD_DUPLEX_KEY_MASKS; port->actor_oper_port_key = (port->actor_admin_port_key &= - ~AD_SPEED_KEY_BITS); + ~AD_SPEED_KEY_MASKS); } netdev_dbg(slave->bond->dev, "Port %d changed link status to %s\n", port->actor_port_number, -- GitLab From 424c3232b04ac97176d105ffaaed80edcaa19b92 Mon Sep 17 00:00:00 2001 From: Jianhua Xie Date: Wed, 19 Nov 2014 16:48:59 +0800 Subject: [PATCH 5416/9457] bonding: Introduce 4 AD link speed to fix agg_bandwidth This patch adds [2.5|20|40|56] Gbps enum definition, and fixes aggregated bandwidth calculation based on above slave links. CC: Jay Vosburgh CC: Veaceslav Falico CC: Andy Gospodarek CC: David S. Miller Signed-off-by: Jianhua Xie Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6bc27d9a8670..8baa87df1738 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -88,7 +88,11 @@ enum ad_link_speed_type { AD_LINK_SPEED_10MBPS, AD_LINK_SPEED_100MBPS, AD_LINK_SPEED_1000MBPS, - AD_LINK_SPEED_10000MBPS + AD_LINK_SPEED_2500MBPS, + AD_LINK_SPEED_10000MBPS, + AD_LINK_SPEED_20000MBPS, + AD_LINK_SPEED_40000MBPS, + AD_LINK_SPEED_56000MBPS }; /* compare MAC addresses */ @@ -247,7 +251,11 @@ static inline int __check_agg_selection_timer(struct port *port) * %AD_LINK_SPEED_10MBPS, * %AD_LINK_SPEED_100MBPS, * %AD_LINK_SPEED_1000MBPS, + * %AD_LINK_SPEED_2500MBPS, * %AD_LINK_SPEED_10000MBPS + * %AD_LINK_SPEED_20000MBPS + * %AD_LINK_SPEED_40000MBPS + * %AD_LINK_SPEED_56000MBPS */ static u16 __get_link_speed(struct port *port) { @@ -275,10 +283,26 @@ static u16 __get_link_speed(struct port *port) speed = AD_LINK_SPEED_1000MBPS; break; + case SPEED_2500: + speed = AD_LINK_SPEED_2500MBPS; + break; + case SPEED_10000: speed = AD_LINK_SPEED_10000MBPS; break; + case SPEED_20000: + speed = AD_LINK_SPEED_20000MBPS; + break; + + case SPEED_40000: + speed = AD_LINK_SPEED_40000MBPS; + break; + + case SPEED_56000: + speed = AD_LINK_SPEED_56000MBPS; + break; + default: /* unknown speed value from ethtool. shouldn't happen */ speed = 0; @@ -639,9 +663,21 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) case AD_LINK_SPEED_1000MBPS: bandwidth = aggregator->num_of_ports * 1000; break; + case AD_LINK_SPEED_2500MBPS: + bandwidth = aggregator->num_of_ports * 2500; + break; case AD_LINK_SPEED_10000MBPS: bandwidth = aggregator->num_of_ports * 10000; break; + case AD_LINK_SPEED_20000MBPS: + bandwidth = aggregator->num_of_ports * 20000; + break; + case AD_LINK_SPEED_40000MBPS: + bandwidth = aggregator->num_of_ports * 40000; + break; + case AD_LINK_SPEED_56000MBPS: + bandwidth = aggregator->num_of_ports * 56000; + break; default: bandwidth = 0; /* to silence the compiler */ } -- GitLab From 7f615dd43ced8dc5424ad3fa95edd6b7fbbbc27c Mon Sep 17 00:00:00 2001 From: Bintian Wang Date: Mon, 10 Nov 2014 20:58:31 +0800 Subject: [PATCH 5417/9457] clk: hi3620: Move const initdata into correct code section Use __initconst instead of __initdata for constant init data. Signed-off-by: Bintian Wang Acked-by: Haojian Zhuang Signed-off-by: Michael Turquette --- drivers/clk/hisilicon/clk-hi3620.c | 70 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 339945d2503b..640ea3327c3e 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -38,44 +38,44 @@ #include "clk.h" /* clock parent list */ -static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; -static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; -static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; -static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; -static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; -static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; -static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; -static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; -static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; -static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; -static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; -static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; -static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; -static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; +static const char *timer0_mux_p[] __initconst = { "osc32k", "timerclk01", }; +static const char *timer1_mux_p[] __initconst = { "osc32k", "timerclk01", }; +static const char *timer2_mux_p[] __initconst = { "osc32k", "timerclk23", }; +static const char *timer3_mux_p[] __initconst = { "osc32k", "timerclk23", }; +static const char *timer4_mux_p[] __initconst = { "osc32k", "timerclk45", }; +static const char *timer5_mux_p[] __initconst = { "osc32k", "timerclk45", }; +static const char *timer6_mux_p[] __initconst = { "osc32k", "timerclk67", }; +static const char *timer7_mux_p[] __initconst = { "osc32k", "timerclk67", }; +static const char *timer8_mux_p[] __initconst = { "osc32k", "timerclk89", }; +static const char *timer9_mux_p[] __initconst = { "osc32k", "timerclk89", }; +static const char *uart0_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart1_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart2_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart3_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *uart4_mux_p[] __initconst = { "osc26m", "pclk", }; +static const char *spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; +static const char *spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; +static const char *spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; /* share axi parent */ -static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; -static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; -static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; -static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; -static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", +static const char *saxi_mux_p[] __initconst = { "armpll3", "armpll2", }; +static const char *pwm0_mux_p[] __initconst = { "osc32k", "osc26m", }; +static const char *pwm1_mux_p[] __initconst = { "osc32k", "osc26m", }; +static const char *sd_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc1_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", }; +static const char *g2d_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *venc_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *vdec_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *vpp_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *edc0_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *ldi0_mux_p[] __initconst = { "armpll2", "armpll4", "armpll3", "armpll5", }; -static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", +static const char *edc1_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *ldi1_mux_p[] __initconst = { "armpll2", "armpll4", "armpll3", "armpll5", }; -static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; -static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; -static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; +static const char *rclk_hsic_p[] __initconst = { "armpll3", "armpll2", }; +static const char *mmc2_mux_p[] __initconst = { "armpll2", "armpll3", }; +static const char *mmc3_mux_p[] __initconst = { "armpll2", "armpll3", }; /* fixed rate clocks */ -- GitLab From fbd2f9fe97726944f98d9a5813d08372446b6a37 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Nov 2014 12:28:09 +0100 Subject: [PATCH 5418/9457] bochs: little cleanup Drop some leftover, commented code. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs_hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index dbe619e6aab4..e8b1dacc4911 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -54,8 +54,7 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) unsigned long addr, size, mem, ioaddr, iosize; u16 id; - if (/* (ent->driver_data == BOCHS_QEMU_STDVGA) && */ - (pdev->resource[2].flags & IORESOURCE_MEM)) { + if (pdev->resource[2].flags & IORESOURCE_MEM) { /* mmio bar with vga and bochs registers present */ if (pci_request_region(pdev, 2, "bochs-drm") != 0) { DRM_ERROR("Cannot request mmio region\n"); -- GitLab From 9ecdb039b7517dc10b8c3e6dbeb40859178ac28e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Nov 2014 12:28:10 +0100 Subject: [PATCH 5419/9457] bochs: add endian switching support Recently (qemu 2.2+) the qemu stdvga got a register to switch the vga framebuffer endianness. This patch adds code to explicitly set the endianness of the framebuffer. In most cases this has no effect as the default is guest architecture endianness. It is needed though in case a architecture supports both big and little endian, i.e. for ppc64le. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs_hw.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index e8b1dacc4911..460389702d31 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -51,7 +51,7 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) { struct bochs_device *bochs = dev->dev_private; struct pci_dev *pdev = dev->pdev; - unsigned long addr, size, mem, ioaddr, iosize; + unsigned long addr, size, mem, ioaddr, iosize, qext_size; u16 id; if (pdev->resource[2].flags & IORESOURCE_MEM) { @@ -115,6 +115,24 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) size / 1024, addr, bochs->ioports ? "ioports" : "mmio", ioaddr); + + if (bochs->mmio && pdev->revision >= 2) { + qext_size = readl(bochs->mmio + 0x600); + if (qext_size < 4 || qext_size > iosize) + goto noext; + DRM_DEBUG("Found qemu ext regs, size %ld\n", qext_size); + if (qext_size >= 8) { +#ifdef __BIG_ENDIAN + writel(0xbebebebe, bochs->mmio + 0x604); +#else + writel(0x1e1e1e1e, bochs->mmio + 0x604); +#endif + DRM_DEBUG(" qext endian: 0x%x\n", + readl(bochs->mmio + 0x604)); + } + } + +noext: return 0; } -- GitLab From 49b70a31c166a6da12f60ec85da608c064555406 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Nov 2014 12:28:11 +0100 Subject: [PATCH 5420/9457] bochs: fix bochsdrmfb mmap Remove the mapping offset from the bo backing the fbdev framebuffer. Wire up fbdev mmap function to map the backing bo using ttm_fbdev_mmap. With that patch in place mmap(/dev/fb0) works as expected. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs_fbdev.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index fe95d31cd110..61dbf09dff5d 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -9,6 +9,17 @@ /* ---------------------------------------------------------------------- */ +static int bochsfb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + struct bochs_device *bochs = + container_of(fb_helper, struct bochs_device, fb.helper); + struct bochs_bo *bo = gem_to_bochs_bo(bochs->fb.gfb.obj); + + return ttm_fbdev_mmap(vma, &bo->bo); +} + static struct fb_ops bochsfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, @@ -19,6 +30,7 @@ static struct fb_ops bochsfb_ops = { .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, + .fb_mmap = bochsfb_mmap, }; static int bochsfb_create_object(struct bochs_device *bochs, @@ -123,11 +135,9 @@ static int bochsfb_create(struct drm_fb_helper *helper, info->screen_base = bo->kmap.virtual; info->screen_size = size; -#if 0 - /* FIXME: get this right for mmap(/dev/fb0) */ - info->fix.smem_start = bochs_bo_mmap_offset(bo); + drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node); + info->fix.smem_start = 0; info->fix.smem_len = size; -#endif ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) { -- GitLab From 3ce733b909764a3ee17b35d7a2c940fd0bc45d5b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Nov 2014 12:28:12 +0100 Subject: [PATCH 5421/9457] bochs: add page_flip Implement crtc page_flip callback for bochsdrm. The qemu stdvga has no vblank signaling, so we have to fake it. We do so by instantly calling drm_send_vblank_event. Tested with kmscon. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs_kms.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 5ffd4895d040..85f0f8cf1fb8 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -109,11 +109,32 @@ static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, { } +static int bochs_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) +{ + struct bochs_device *bochs = + container_of(crtc, struct bochs_device, crtc); + struct drm_framebuffer *old_fb = crtc->primary->fb; + unsigned long irqflags; + + crtc->primary->fb = fb; + bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); + if (event) { + spin_lock_irqsave(&bochs->dev->event_lock, irqflags); + drm_send_vblank_event(bochs->dev, -1, event); + spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags); + } + return 0; +} + /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs bochs_crtc_funcs = { .gamma_set = bochs_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = drm_crtc_cleanup, + .page_flip = bochs_crtc_page_flip, }; static const struct drm_crtc_helper_funcs bochs_helper_funcs = { -- GitLab From aeb24cc0a31646eb9233a05834440fdf16a713bd Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 17 Nov 2014 11:21:08 +0100 Subject: [PATCH 5422/9457] drm: omapdrm: remove unused variable Commit f9b9faf6d94dd29eab8c128905c7d091f955481d "drm: flip-work: change drm_flip_work_init prototype" changed the drm_flip_work_init prototype to a void function, which makes 'ret' an unused variable. Signed-off-by: Boris Brezillon Signed-off-by: Dave Airlie --- drivers/gpu/drm/omapdrm/omap_plane.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 0ad740132ac3..ee8e2b3a117e 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -388,7 +388,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, struct drm_plane *plane = NULL; struct omap_plane *omap_plane; struct omap_overlay_info *info; - int ret; DBG("%s: priv=%d", plane_names[id], private_plane); -- GitLab From 2b0a3c400033c23ef83d2e9191d36c250289a79e Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Sun, 16 Nov 2014 11:21:25 +0100 Subject: [PATCH 5423/9457] drm: remove unnecessary sizeof(u8) sizeof(u8) is always 1. Signed-off-by: Fabian Frederick Signed-off-by: Dave Airlie --- drivers/gpu/drm/r128/r128_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 575e986f82a7..8fd2d9f58f77 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c @@ -905,7 +905,7 @@ static int r128_cce_dispatch_write_span(struct drm_device *dev, if (IS_ERR(buffer)) return PTR_ERR(buffer); - mask_size = depth->n * sizeof(u8); + mask_size = depth->n; if (depth->mask) { mask = memdup_user(depth->mask, mask_size); if (IS_ERR(mask)) { @@ -1010,7 +1010,7 @@ static int r128_cce_dispatch_write_pixels(struct drm_device *dev, } if (depth->mask) { - mask_size = depth->n * sizeof(u8); + mask_size = depth->n; mask = memdup_user(depth->mask, mask_size); if (IS_ERR(mask)) { kfree(x); -- GitLab From 881fdaa5e4cb0d68e52acab0ad4e1820e2bfffa4 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 13 Nov 2014 22:43:23 +0900 Subject: [PATCH 5424/9457] drm/ttm: Avoid memory allocation from shrinker functions. Andrew Morton wrote: > On Wed, 12 Nov 2014 13:08:55 +0900 Tetsuo Handa wrote: > > > Andrew Morton wrote: > > > Poor ttm guys - this is a bit of a trap we set for them. > > > > Commit a91576d7916f6cce ("drm/ttm: Pass GFP flags in order to avoid deadlock.") > > changed to use sc->gfp_mask rather than GFP_KERNEL. > > > > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), > > - GFP_KERNEL); > > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp); > > > > But this bug is caused by sc->gfp_mask containing some flags which are not > > in GFP_KERNEL, right? Then, I think > > > > - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp); > > + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp & GFP_KERNEL); > > > > would hide this bug. > > > > But I think we should use GFP_ATOMIC (or drop __GFP_WAIT flag) > > Well no - ttm_page_pool_free() should stop calling kmalloc altogether. > Just do > > struct page *pages_to_free[16]; > > and rework the code to free 16 pages at a time. Easy. Well, ttm code wants to process 512 pages at a time for performance. Memory footprint increased by 512 * sizeof(struct page *) buffer is only 4096 bytes. What about using static buffer like below? ---------- >From d3cb5393c9c8099d6b37e769f78c31af1541fe8c Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 13 Nov 2014 22:21:54 +0900 Subject: [PATCH] drm/ttm: Avoid memory allocation from shrinker functions. Commit a91576d7916f6cce ("drm/ttm: Pass GFP flags in order to avoid deadlock.") caused BUG_ON() due to sc->gfp_mask containing flags which are not in GFP_KERNEL. https://bugzilla.kernel.org/show_bug.cgi?id=87891 Changing from sc->gfp_mask to (sc->gfp_mask & GFP_KERNEL) would avoid the BUG_ON(), but avoiding memory allocation from shrinker function is better and reliable fix. Shrinker function is already serialized by global lock, and clean up function is called after shrinker function is unregistered. Thus, we can use static buffer when called from shrinker function and clean up function. Signed-off-by: Tetsuo Handa Cc: stable [2.6.35+] Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 26 ++++++++++++++---------- drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 25 ++++++++++++++--------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 09874d695188..025c429050c0 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -297,11 +297,12 @@ static void ttm_pool_update_free_locked(struct ttm_page_pool *pool, * * @pool: to free the pages from * @free_all: If set to true will free all pages in pool - * @gfp: GFP flags. + * @use_static: Safe to use static buffer **/ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, - gfp_t gfp) + bool use_static) { + static struct page *static_buf[NUM_PAGES_TO_ALLOC]; unsigned long irq_flags; struct page *p; struct page **pages_to_free; @@ -311,7 +312,11 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, if (NUM_PAGES_TO_ALLOC < nr_free) npages_to_free = NUM_PAGES_TO_ALLOC; - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp); + if (use_static) + pages_to_free = static_buf; + else + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), + GFP_KERNEL); if (!pages_to_free) { pr_err("Failed to allocate memory for pool free operation\n"); return 0; @@ -374,7 +379,8 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, if (freed_pages) ttm_pages_put(pages_to_free, freed_pages); out: - kfree(pages_to_free); + if (pages_to_free != static_buf) + kfree(pages_to_free); return nr_free; } @@ -383,8 +389,6 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free, * * XXX: (dchinner) Deadlock warning! * - * We need to pass sc->gfp_mask to ttm_page_pool_free(). - * * This code is crying out for a shrinker per pool.... */ static unsigned long @@ -407,8 +411,8 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) if (shrink_pages == 0) break; pool = &_manager->pools[(i + pool_offset)%NUM_POOLS]; - shrink_pages = ttm_page_pool_free(pool, nr_free, - sc->gfp_mask); + /* OK to use static buffer since global mutex is held. */ + shrink_pages = ttm_page_pool_free(pool, nr_free, true); freed += nr_free - shrink_pages; } mutex_unlock(&lock); @@ -710,7 +714,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, } spin_unlock_irqrestore(&pool->lock, irq_flags); if (npages) - ttm_page_pool_free(pool, npages, GFP_KERNEL); + ttm_page_pool_free(pool, npages, false); } /* @@ -849,9 +853,9 @@ void ttm_page_alloc_fini(void) pr_info("Finalizing pool allocator\n"); ttm_pool_mm_shrink_fini(_manager); + /* OK to use static buffer since global mutex is no longer used. */ for (i = 0; i < NUM_POOLS; ++i) - ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES, - GFP_KERNEL); + ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES, true); kobject_put(&_manager->kobj); _manager = NULL; diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index c96db433f8af..01e1d27eb078 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -411,11 +411,12 @@ static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page) * * @pool: to free the pages from * @nr_free: If set to true will free all pages in pool - * @gfp: GFP flags. + * @use_static: Safe to use static buffer **/ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free, - gfp_t gfp) + bool use_static) { + static struct page *static_buf[NUM_PAGES_TO_ALLOC]; unsigned long irq_flags; struct dma_page *dma_p, *tmp; struct page **pages_to_free; @@ -432,7 +433,11 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free, npages_to_free, nr_free); } #endif - pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp); + if (use_static) + pages_to_free = static_buf; + else + pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), + GFP_KERNEL); if (!pages_to_free) { pr_err("%s: Failed to allocate memory for pool free operation\n", @@ -502,7 +507,8 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free, if (freed_pages) ttm_dma_pages_put(pool, &d_pages, pages_to_free, freed_pages); out: - kfree(pages_to_free); + if (pages_to_free != static_buf) + kfree(pages_to_free); return nr_free; } @@ -531,7 +537,8 @@ static void ttm_dma_free_pool(struct device *dev, enum pool_type type) if (pool->type != type) continue; /* Takes a spinlock.. */ - ttm_dma_page_pool_free(pool, FREE_ALL_PAGES, GFP_KERNEL); + /* OK to use static buffer since global mutex is held. */ + ttm_dma_page_pool_free(pool, FREE_ALL_PAGES, true); WARN_ON(((pool->npages_in_use + pool->npages_free) != 0)); /* This code path is called after _all_ references to the * struct device has been dropped - so nobody should be @@ -986,7 +993,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) /* shrink pool if necessary (only on !is_cached pools)*/ if (npages) - ttm_dma_page_pool_free(pool, npages, GFP_KERNEL); + ttm_dma_page_pool_free(pool, npages, false); ttm->state = tt_unpopulated; } EXPORT_SYMBOL_GPL(ttm_dma_unpopulate); @@ -996,8 +1003,6 @@ EXPORT_SYMBOL_GPL(ttm_dma_unpopulate); * * XXX: (dchinner) Deadlock warning! * - * We need to pass sc->gfp_mask to ttm_dma_page_pool_free(). - * * I'm getting sadder as I hear more pathetical whimpers about needing per-pool * shrinkers */ @@ -1030,8 +1035,8 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) if (++idx < pool_offset) continue; nr_free = shrink_pages; - shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free, - sc->gfp_mask); + /* OK to use static buffer since global mutex is held. */ + shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free, true); freed += nr_free - shrink_pages; pr_debug("%s: (%s:%d) Asked to shrink %d, have %d more to go\n", -- GitLab From 7f907bf284ba7bb8d271f094b226699d3fef2142 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 8 Nov 2014 10:16:19 -0500 Subject: [PATCH 5425/9457] drm/irq: BUG_ON() -> WARN_ON() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's make things a bit easier to debug when things go bad (potentially under console_lock). Signed-off-by: Rob Clark Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3e6b582f60dd..0e47df4ef24e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1029,7 +1029,8 @@ void drm_vblank_put(struct drm_device *dev, int crtc) { struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; - BUG_ON(atomic_read(&vblank->refcount) == 0); + if (WARN_ON(atomic_read(&vblank->refcount) == 0)) + return; if (WARN_ON(crtc >= dev->num_crtcs)) return; -- GitLab From c7eb76f4931b505e57c6510133df19f4ec1ce3e5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:06 +0100 Subject: [PATCH 5426/9457] drm/atomic: Ensure that drm_connector_index is stable I've totally forgotten that with DP MST connectors can now be hotplugged. And failed to adapt Rob's drm_atomic_state code (which predates connector hotplugging) to the new realities. The first step is to make sure that the connector indices used to access the arrays of pointers are stable. The connection mutex gives us enough guarantees for that, which means we won't unecessarily block on concurrent modesets or background probing. So add a locking WARN_ON and shuffle the code slightly to make sure we always hold the right lock. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic.c | 8 ++++---- drivers/gpu/drm/drm_crtc.c | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index ed22a719440f..90b2d1644bd7 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -295,15 +295,15 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, struct drm_mode_config *config = &connector->dev->mode_config; struct drm_connector_state *connector_state; + ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx); + if (ret) + return ERR_PTR(ret); + index = drm_connector_index(connector); if (state->connector_states[index]) return state->connector_states[index]; - ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx); - if (ret) - return ERR_PTR(ret); - connector_state = connector->funcs->atomic_duplicate_state(connector); if (!connector_state) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 56737e74b59d..5c878f172365 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -867,6 +867,8 @@ int drm_connector_init(struct drm_device *dev, drm_connector_get_cmdline_mode(connector); + /* We should add connectors at the end to avoid upsetting the connector + * index too much. */ list_add_tail(&connector->head, &dev->mode_config.connector_list); dev->mode_config.num_connector++; @@ -930,6 +932,9 @@ unsigned int drm_connector_index(struct drm_connector *connector) { unsigned int index = 0; struct drm_connector *tmp; + struct drm_mode_config *config = &connector->dev->mode_config; + + WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) { if (tmp == connector) -- GitLab From 6f75cea66c8dd043ced282016b21a639af176642 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:07 +0100 Subject: [PATCH 5427/9457] drm/atomic: Only destroy connector states with connection mutex held Otherwise the connector might have been unplugged and destroyed while we didn't look. Yet another fallout from DP MST hotplugging that I didn't consider. To make sure we get this right add an appropriate WARN_ON to drm_atomic_state_clear (obviously only when we actually have a state to clear up). And reorder all the state_clear and backoff calls to make it work out properly. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic.c | 9 ++++++--- drivers/gpu/drm/drm_atomic_helper.c | 14 +++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 90b2d1644bd7..67c1dc894bd9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -112,21 +112,24 @@ EXPORT_SYMBOL(drm_atomic_state_alloc); void drm_atomic_state_clear(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; + struct drm_mode_config *config = &dev->mode_config; int i; DRM_DEBUG_KMS("Clearing atomic state %p\n", state); - for (i = 0; i < dev->mode_config.num_connector; i++) { + for (i = 0; i < config->num_connector; i++) { struct drm_connector *connector = state->connectors[i]; if (!connector) continue; + WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); + connector->funcs->atomic_destroy_state(connector, state->connector_states[i]); } - for (i = 0; i < dev->mode_config.num_crtc; i++) { + for (i = 0; i < config->num_crtc; i++) { struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) @@ -136,7 +139,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) state->crtc_states[i]); } - for (i = 0; i < dev->mode_config.num_total_plane; i++) { + for (i = 0; i < config->num_total_plane; i++) { struct drm_plane *plane = state->planes[i]; if (!plane) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index fad2b932cf72..0cd054615920 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1217,8 +1217,8 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane, return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); /* * Someone might have exchanged the framebuffer while we dropped locks @@ -1285,8 +1285,8 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane) return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); /* * Someone might have exchanged the framebuffer while we dropped locks @@ -1462,8 +1462,8 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set) return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); /* * Someone might have exchanged the framebuffer while we dropped locks @@ -1528,8 +1528,8 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); goto retry; } @@ -1587,8 +1587,8 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane, return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); goto retry; } @@ -1646,8 +1646,8 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector, return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); goto retry; } @@ -1725,8 +1725,8 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, return ret; backoff: - drm_atomic_legacy_backoff(state); drm_atomic_state_clear(state); + drm_atomic_legacy_backoff(state); /* * Someone might have exchanged the framebuffer while we dropped locks -- GitLab From f52b69f1ecfdd7ef6867a257620258c09e569552 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:08 +0100 Subject: [PATCH 5428/9457] drm/atomic: Don't overrun the connector array when hotplugging Yet another fallout from not considering DP MST hotplug. With the previous patches we have stable indices, but it might still happen that a connector gets added between when we allocate the array and when we actually add a connector. Especially when we back off due to ww mutex contention or similar issues. So store the sizes of the arrays in struct drm_atomic_state and double check them. We don't really care about races except that we want to use a consistent value, so ACCESS_ONCE is all we need. And if we indeed notice that we'd overrun the array then just give up and restart the entire ioctl. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic.c | 26 +++++++++++++++++++++----- drivers/gpu/drm/drm_atomic_helper.c | 23 ++++++++--------------- include/drm/drm_crtc.h | 2 ++ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 67c1dc894bd9..3624632084e2 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -56,6 +56,8 @@ drm_atomic_state_alloc(struct drm_device *dev) if (!state) return NULL; + state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector); + state->crtcs = kcalloc(dev->mode_config.num_crtc, sizeof(*state->crtcs), GFP_KERNEL); if (!state->crtcs) @@ -72,12 +74,12 @@ drm_atomic_state_alloc(struct drm_device *dev) sizeof(*state->plane_states), GFP_KERNEL); if (!state->plane_states) goto fail; - state->connectors = kcalloc(dev->mode_config.num_connector, + state->connectors = kcalloc(state->num_connector, sizeof(*state->connectors), GFP_KERNEL); if (!state->connectors) goto fail; - state->connector_states = kcalloc(dev->mode_config.num_connector, + state->connector_states = kcalloc(state->num_connector, sizeof(*state->connector_states), GFP_KERNEL); if (!state->connector_states) @@ -117,7 +119,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) DRM_DEBUG_KMS("Clearing atomic state %p\n", state); - for (i = 0; i < config->num_connector; i++) { + for (i = 0; i < state->num_connector; i++) { struct drm_connector *connector = state->connectors[i]; if (!connector) @@ -304,6 +306,21 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, index = drm_connector_index(connector); + /* + * Construction of atomic state updates can race with a connector + * hot-add which might overflow. In this case flip the table and just + * restart the entire ioctl - no one is fast enough to livelock a cpu + * with physical hotplug events anyway. + * + * Note that we only grab the indexes once we have the right lock to + * prevent hotplug/unplugging of connectors. So removal is no problem, + * at most the array is a bit too large. + */ + if (index >= state->num_connector) { + DRM_DEBUG_KMS("Hot-added connector would overflow state array, restarting\n"); + return -EAGAIN; + } + if (state->connector_states[index]) return state->connector_states[index]; @@ -499,10 +516,9 @@ int drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, struct drm_crtc *crtc) { - int nconnectors = state->dev->mode_config.num_connector; int i, num_connected_connectors = 0; - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < state->num_connector; i++) { struct drm_connector_state *conn_state; conn_state = state->connector_states[i]; diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 0cd054615920..99095ef147ef 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -249,7 +249,6 @@ static int mode_fixup(struct drm_atomic_state *state) { int ncrtcs = state->dev->mode_config.num_crtc; - int nconnectors = state->dev->mode_config.num_connector; struct drm_crtc_state *crtc_state; struct drm_connector_state *conn_state; int i; @@ -264,7 +263,7 @@ mode_fixup(struct drm_atomic_state *state) drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode); } - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < state->num_connector; i++) { struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; @@ -336,7 +335,6 @@ drm_atomic_helper_check_prepare(struct drm_device *dev, struct drm_atomic_state *state) { int ncrtcs = dev->mode_config.num_crtc; - int nconnectors = dev->mode_config.num_connector; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; int i, ret; @@ -361,7 +359,7 @@ drm_atomic_helper_check_prepare(struct drm_device *dev, } } - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < state->num_connector; i++) { /* * This only sets crtc->mode_changed for routing changes, * drivers must set crtc->mode_changed themselves when connector @@ -485,10 +483,9 @@ static void disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) { int ncrtcs = old_state->dev->mode_config.num_crtc; - int nconnectors = old_state->dev->mode_config.num_connector; int i; - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < old_state->num_connector; i++) { struct drm_connector_state *old_conn_state; struct drm_connector *connector; struct drm_encoder_helper_funcs *funcs; @@ -553,12 +550,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) static void set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state) { - int nconnectors = dev->mode_config.num_connector; int ncrtcs = old_state->dev->mode_config.num_crtc; int i; /* clear out existing links */ - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < old_state->num_connector; i++) { struct drm_connector *connector; connector = old_state->connectors[i]; @@ -573,7 +569,7 @@ set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state) } /* set new links */ - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < old_state->num_connector; i++) { struct drm_connector *connector; connector = old_state->connectors[i]; @@ -608,7 +604,6 @@ static void crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) { int ncrtcs = old_state->dev->mode_config.num_crtc; - int nconnectors = old_state->dev->mode_config.num_connector; int i; for (i = 0; i < ncrtcs; i++) { @@ -626,7 +621,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) funcs->mode_set_nofb(crtc); } - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < old_state->num_connector; i++) { struct drm_connector *connector; struct drm_crtc_state *new_crtc_state; struct drm_encoder_helper_funcs *funcs; @@ -687,7 +682,6 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev, struct drm_atomic_state *old_state) { int ncrtcs = old_state->dev->mode_config.num_crtc; - int nconnectors = old_state->dev->mode_config.num_connector; int i; for (i = 0; i < ncrtcs; i++) { @@ -706,7 +700,7 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev, funcs->commit(crtc); } - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < old_state->num_connector; i++) { struct drm_connector *connector; struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; @@ -1304,7 +1298,6 @@ static int update_output_state(struct drm_atomic_state *state, { struct drm_device *dev = set->crtc->dev; struct drm_connector_state *conn_state; - int nconnectors = state->dev->mode_config.num_connector; int ncrtcs = state->dev->mode_config.num_crtc; int ret, i, j; @@ -1333,7 +1326,7 @@ static int update_output_state(struct drm_atomic_state *state, } /* Then recompute connector->crtc links and crtc enabling state. */ - for (i = 0; i < nconnectors; i++) { + for (i = 0; i < state->num_connector; i++) { struct drm_connector *connector; connector = state->connectors[i]; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 7b28ab032a88..f3142c64e3d5 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -825,6 +825,7 @@ struct drm_bridge { * @plane_states: pointer to array of plane states pointers * @crtcs: pointer to array of CRTC pointers * @crtc_states: pointer to array of CRTC states pointers + * @num_connector: size of the @connectors and @connector_states arrays * @connectors: pointer to array of connector pointers * @connector_states: pointer to array of connector states pointers * @acquire_ctx: acquire context for this atomic modeset state update @@ -836,6 +837,7 @@ struct drm_atomic_state { struct drm_plane_state **plane_states; struct drm_crtc **crtcs; struct drm_crtc_state **crtc_states; + int num_connector; struct drm_connector **connectors; struct drm_connector_state **connector_states; -- GitLab From 1a49863349929f5a85fd7c7ffb06213d4fdc8c15 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:09 +0100 Subject: [PATCH 5429/9457] drm/crtc: Polish kerneldoc - Make it clear that it's a negative errno (more in line with everything else). - Clean up the confusion around get_properties vs. getproperty ioctls: One reads per-obj property values, the other reads property metadata. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 79 ++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5c878f172365..8c550302a9ef 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1490,7 +1490,7 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); * connectors. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_create_aspect_ratio_property(struct drm_device *dev) { @@ -1674,7 +1674,7 @@ static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, * the caller. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ static int drm_crtc_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in) @@ -1717,7 +1717,7 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -1905,7 +1905,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getcrtc(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -1966,7 +1966,7 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getconnector(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2110,7 +2110,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getencoder(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2151,7 +2151,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getplane_res(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2212,7 +2212,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getplane(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2386,7 +2386,7 @@ static int setplane_internal(struct drm_plane *plane, * valid crtc). * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2461,7 +2461,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, * interface. The only thing it adds is correct refcounting dance. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_set_config_internal(struct drm_mode_set *set) { @@ -2554,7 +2554,7 @@ EXPORT_SYMBOL(drm_crtc_check_viewport); * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_setcrtc(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2717,7 +2717,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, * userspace wants to make use of these capabilities. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ static int drm_mode_cursor_universal(struct drm_crtc *crtc, struct drm_mode_cursor2 *req, @@ -2865,7 +2865,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_cursor_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2892,7 +2892,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_cursor2_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -2956,7 +2956,7 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format); * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_addfb(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3161,7 +3161,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_addfb2(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3189,7 +3189,7 @@ int drm_mode_addfb2(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_rmfb(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3243,7 +3243,7 @@ int drm_mode_rmfb(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getfb(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3304,7 +3304,7 @@ int drm_mode_getfb(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3384,7 +3384,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ void drm_fb_release(struct drm_file *priv) { @@ -3818,17 +3818,20 @@ int drm_object_property_get_value(struct drm_mode_object *obj, EXPORT_SYMBOL(drm_object_property_get_value); /** - * drm_mode_getproperty_ioctl - get the current value of a connector's property + * drm_mode_getproperty_ioctl - get the property metadata * @dev: DRM device * @data: ioctl data * @file_priv: DRM file info * - * This function retrieves the current value for an connectors's property. + * This function retrieves the metadata for a given property, like the different + * possible values for an enum property or the limits for a range property. + * + * Blob properties are special * * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getproperty_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3981,7 +3984,7 @@ static void drm_property_destroy_blob(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_getblob_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4026,7 +4029,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev, * them more meaningful names. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_connector_set_path_property(struct drm_connector *connector, const char *path) @@ -4056,7 +4059,7 @@ EXPORT_SYMBOL(drm_mode_connector_set_path_property); * connector's edid property. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_connector_update_edid_property(struct drm_connector *connector, const struct edid *edid) @@ -4153,7 +4156,7 @@ static bool drm_property_change_is_valid(struct drm_property *property, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4236,7 +4239,7 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); /** - * drm_mode_getproperty_ioctl - get the current value of a object's property + * drm_mode_obj_get_properties_ioctl - get the current value of a object's property * @dev: DRM device * @data: ioctl data * @file_priv: DRM file info @@ -4248,7 +4251,7 @@ EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4320,7 +4323,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4392,7 +4395,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, * possible_clones and possible_crtcs bitmasks. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder) @@ -4419,7 +4422,7 @@ EXPORT_SYMBOL(drm_mode_connector_attach_encoder); * fixed gamma table size. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size) @@ -4448,7 +4451,7 @@ EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_gamma_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4520,7 +4523,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_gamma_get_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4586,7 +4589,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4752,7 +4755,7 @@ EXPORT_SYMBOL(drm_mode_config_reset); * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_create_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4804,7 +4807,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -4831,7 +4834,7 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, * Called by the user via ioctl. * * Returns: - * Zero on success, errno on failure. + * Zero on success, negative errno on failure. */ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) -- GitLab From 3758b34193638f664177565f1692faa1bec7d9ed Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:10 +0100 Subject: [PATCH 5430/9457] drm: s/enum_blob_list/enum_list/ in drm_property I guess for hysterical raisins this was meant to be the way to read blob properties. But that's done with the two-stage approach which uses separate blob kms object and the special-purpose get_blob ioctl. Shipping userspace seems to have never relied on this, and the kernel also never put any blob thing onto that property. And nowadays it would blow up, e.g. in drm_property_destroy. Also it makes no sense to return values in an ioctl that only returns metadata about everything. So let's ditch all the internal code for the blob list, rename the list to be unambiguous and sprinkle comments all over the place to explain this peculiar piece of api. v2: Squash in fixup from Rob to remove now unused variables. Cc: Rob Clark Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 53 ++++++++++++------------------------- include/drm/drm_crtc.h | 2 +- include/uapi/drm/drm_mode.h | 2 ++ 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8c550302a9ef..589a921d4313 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3457,7 +3457,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, property->flags = flags; property->num_values = num_values; - INIT_LIST_HEAD(&property->enum_blob_list); + INIT_LIST_HEAD(&property->enum_list); if (name) { strncpy(property->name, name, DRM_PROP_NAME_LEN); @@ -3679,8 +3679,8 @@ int drm_property_add_enum(struct drm_property *property, int index, (value > 63)) return -EINVAL; - if (!list_empty(&property->enum_blob_list)) { - list_for_each_entry(prop_enum, &property->enum_blob_list, head) { + if (!list_empty(&property->enum_list)) { + list_for_each_entry(prop_enum, &property->enum_list, head) { if (prop_enum->value == value) { strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; @@ -3698,7 +3698,7 @@ int drm_property_add_enum(struct drm_property *property, int index, prop_enum->value = value; property->values[index] = value; - list_add_tail(&prop_enum->head, &property->enum_blob_list); + list_add_tail(&prop_enum->head, &property->enum_list); return 0; } EXPORT_SYMBOL(drm_property_add_enum); @@ -3715,7 +3715,7 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property) { struct drm_property_enum *prop_enum, *pt; - list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { + list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) { list_del(&prop_enum->head); kfree(prop_enum); } @@ -3839,16 +3839,12 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, struct drm_mode_get_property *out_resp = data; struct drm_property *property; int enum_count = 0; - int blob_count = 0; int value_count = 0; int ret = 0, i; int copied; struct drm_property_enum *prop_enum; struct drm_mode_property_enum __user *enum_ptr; - struct drm_property_blob *prop_blob; - uint32_t __user *blob_id_ptr; uint64_t __user *values_ptr; - uint32_t __user *blob_length_ptr; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; @@ -3862,11 +3858,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) || drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { - list_for_each_entry(prop_enum, &property->enum_blob_list, head) + list_for_each_entry(prop_enum, &property->enum_list, head) enum_count++; - } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { - list_for_each_entry(prop_blob, &property->enum_blob_list, head) - blob_count++; } value_count = property->num_values; @@ -3891,7 +3884,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { copied = 0; enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; - list_for_each_entry(prop_enum, &property->enum_blob_list, head) { + list_for_each_entry(prop_enum, &property->enum_list, head) { if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { ret = -EFAULT; @@ -3909,28 +3902,16 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, out_resp->count_enum_blobs = enum_count; } - if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { - if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { - copied = 0; - blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr; - blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr; - - list_for_each_entry(prop_blob, &property->enum_blob_list, head) { - if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { - ret = -EFAULT; - goto done; - } - - if (put_user(prop_blob->length, blob_length_ptr + copied)) { - ret = -EFAULT; - goto done; - } - - copied++; - } - } - out_resp->count_enum_blobs = blob_count; - } + /* + * NOTE: The idea seems to have been to use this to read all the blob + * property values. But nothing ever added them to the corresponding + * list, userspace always used the special-purpose get_blob ioctl to + * read the value for a blob property. It also doesn't make a lot of + * sense to return values here when everything else is just metadata for + * the property itself. + */ + if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) + out_resp->count_enum_blobs = 0; done: drm_modeset_unlock_all(dev); return ret; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f3142c64e3d5..b459e8fbbc25 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -216,7 +216,7 @@ struct drm_property { uint64_t *values; struct drm_device *dev; - struct list_head enum_blob_list; + struct list_head enum_list; }; struct drm_crtc; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a0db2d4aa5f0..86574b0005ff 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -286,6 +286,8 @@ struct drm_mode_get_property { char name[DRM_PROP_NAME_LEN]; __u32 count_values; + /* This is only used to count enum values, not blobs. The _blobs is + * simply because of a historical reason, i.e. backwards compat. */ __u32 count_enum_blobs; }; -- GitLab From b0fcfc899513a4d4729914b6872ab0564c0f523a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:11 +0100 Subject: [PATCH 5431/9457] drm/atomic_helper: Make it clear that commit_planes gets the old state Oversight from my kerneldoc cleanup when doing the original atomic helper series - I've only applied this clarification to the modeset related helpers, and not the plane update code. Remedy this asap. Signed-off-by: Daniel Vetter Reviewed-by: Rob Clark Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic_helper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 99095ef147ef..690360038dc1 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -976,18 +976,18 @@ EXPORT_SYMBOL(drm_atomic_helper_prepare_planes); /** * drm_atomic_helper_commit_planes - commit plane state * @dev: DRM device - * @state: atomic state + * @old_state: atomic state object with old state structures * * This function commits the new plane state using the plane and atomic helper * functions for planes and crtcs. It assumes that the atomic state has already * been pushed into the relevant object state pointers, since this step can no * longer fail. * - * It still requires the global state object @state to know which planes and + * It still requires the global state object @old_state to know which planes and * crtcs need to be updated though. */ void drm_atomic_helper_commit_planes(struct drm_device *dev, - struct drm_atomic_state *state) + struct drm_atomic_state *old_state) { int nplanes = dev->mode_config.num_total_plane; int ncrtcs = dev->mode_config.num_crtc; @@ -995,7 +995,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, for (i = 0; i < ncrtcs; i++) { struct drm_crtc_helper_funcs *funcs; - struct drm_crtc *crtc = state->crtcs[i]; + struct drm_crtc *crtc = old_state->crtcs[i]; if (!crtc) continue; @@ -1010,7 +1010,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; - struct drm_plane *plane = state->planes[i]; + struct drm_plane *plane = old_state->planes[i]; if (!plane) continue; @@ -1025,7 +1025,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, for (i = 0; i < ncrtcs; i++) { struct drm_crtc_helper_funcs *funcs; - struct drm_crtc *crtc = state->crtcs[i]; + struct drm_crtc *crtc = old_state->crtcs[i]; if (!crtc) continue; -- GitLab From a7ca52e108e549669940b11779bb491a931f8c65 Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Mon, 17 Nov 2014 17:19:41 -0800 Subject: [PATCH 5432/9457] drm/cirrus: fix leaky driver load error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this patch, cirrus_device_init could have failed while cirrus_mm_init succeeded and the driver would have reported overall success on load. This patch causes cirrus_device_init to return on the first error encountered. Reviewed-by: Stéphane Marchesin Signed-off-by: Dave Airlie --- drivers/gpu/drm/cirrus/cirrus_main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index 99c1983f99d2..ab7cb547c570 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -179,17 +179,22 @@ int cirrus_driver_load(struct drm_device *dev, unsigned long flags) } r = cirrus_mm_init(cdev); - if (r) + if (r) { dev_err(&dev->pdev->dev, "fatal err on mm init\n"); + goto out; + } r = cirrus_modeset_init(cdev); - if (r) + if (r) { dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); + goto out; + } dev->mode_config.funcs = (void *)&cirrus_mode_funcs; + + return 0; out: - if (r) - cirrus_driver_unload(dev); + cirrus_driver_unload(dev); return r; } -- GitLab From 09a58da052111263e31f0050ad775b62166fafba Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 12 Nov 2014 18:33:52 -0800 Subject: [PATCH 5433/9457] drm/udl: add cache flags definitions for udl_gem_object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default set udl_gem_object as cacheable, but set WC flag when attaching dmabuf. In udl_gem_mmap() update cache attributes based on the flags, similar to exynos_drm_gem_mmap(). Signed-off-by: Haixia Shi Reviewed-by: Sonny Rao Reviewed-by: Olof Johansson Reviewed-by: Stéphane Marchesin Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_drv.h | 4 ++++ drivers/gpu/drm/udl/udl_gem.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index c7490a2489a7..308278086c72 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -25,6 +25,9 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 1 +#define UDL_BO_CACHEABLE (1 << 0) +#define UDL_BO_WC (1 << 1) + struct udl_device; struct urb_node { @@ -69,6 +72,7 @@ struct udl_gem_object { struct page **pages; void *vmapping; struct sg_table *sg; + unsigned int flags; }; #define to_udl_bo(x) container_of(x, struct udl_gem_object, base) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 8044f5fb7c49..e00459d38dcb 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -25,6 +25,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, return NULL; } + obj->flags = UDL_BO_CACHEABLE; return obj; } @@ -56,6 +57,23 @@ udl_gem_create(struct drm_file *file, return 0; } +static void update_vm_cache_attr(struct udl_gem_object *obj, + struct vm_area_struct *vma) +{ + DRM_DEBUG_KMS("flags = 0x%x\n", obj->flags); + + /* non-cacheable as default. */ + if (obj->flags & UDL_BO_CACHEABLE) { + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + } else if (obj->flags & UDL_BO_WC) { + vma->vm_page_prot = + pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); + } else { + vma->vm_page_prot = + pgprot_noncached(vm_get_page_prot(vma->vm_flags)); + } +} + int udl_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) @@ -77,6 +95,8 @@ int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags &= ~VM_PFNMAP; vma->vm_flags |= VM_MIXEDMAP; + update_vm_cache_attr(to_udl_bo(vma->vm_private_data), vma); + return ret; } @@ -279,6 +299,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, } uobj->base.import_attach = attach; + uobj->flags = UDL_BO_WC; return &uobj->base; -- GitLab From ebfdd6d5e837bd1c170b9bdd749fee2a4183a7f5 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 12 Nov 2014 18:33:53 -0800 Subject: [PATCH 5434/9457] drm/udl: add support to export a handle to a FD on UDL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only importing an FD to a handle is currently supported on UDL, but the exporting functionality is equally useful. Signed-off-by: Haixia Shi Reviewed-by: Stéphane Marchesin Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/Makefile | 2 +- drivers/gpu/drm/udl/udl_dmabuf.c | 273 +++++++++++++++++++++++++++++++ drivers/gpu/drm/udl/udl_drv.c | 2 + drivers/gpu/drm/udl/udl_drv.h | 2 + drivers/gpu/drm/udl/udl_gem.c | 71 -------- 5 files changed, 278 insertions(+), 72 deletions(-) create mode 100644 drivers/gpu/drm/udl/udl_dmabuf.c diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index 05c7481bfd40..195bcac0b6c8 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -1,6 +1,6 @@ ccflags-y := -Iinclude/drm -udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o +udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o udl_dmabuf.o obj-$(CONFIG_DRM_UDL) := udl.o diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c new file mode 100644 index 000000000000..1d85c3a9151d --- /dev/null +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -0,0 +1,273 @@ +/* + * udl_dmabuf.c + * + * Copyright (c) 2014 The Chromium OS Authors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "udl_drv.h" +#include +#include + +struct udl_drm_dmabuf_attachment { + struct sg_table sgt; + enum dma_data_direction dir; + bool is_mapped; +}; + +static int udl_attach_dma_buf(struct dma_buf *dmabuf, + struct device *dev, + struct dma_buf_attachment *attach) +{ + struct udl_drm_dmabuf_attachment *udl_attach; + + DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), + attach->dmabuf->size); + + udl_attach = kzalloc(sizeof(*udl_attach), GFP_KERNEL); + if (!udl_attach) + return -ENOMEM; + + udl_attach->dir = DMA_NONE; + attach->priv = udl_attach; + + return 0; +} + +static void udl_detach_dma_buf(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) +{ + struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; + struct sg_table *sgt; + + if (!udl_attach) + return; + + DRM_DEBUG_PRIME("[DEV:%s] size:%zd\n", dev_name(attach->dev), + attach->dmabuf->size); + + sgt = &udl_attach->sgt; + + if (udl_attach->dir != DMA_NONE) + dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, + udl_attach->dir); + + sg_free_table(sgt); + kfree(udl_attach); + attach->priv = NULL; +} + +static struct sg_table *udl_map_dma_buf(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct udl_drm_dmabuf_attachment *udl_attach = attach->priv; + struct udl_gem_object *obj = to_udl_bo(attach->dmabuf->priv); + struct drm_device *dev = obj->base.dev; + struct scatterlist *rd, *wr; + struct sg_table *sgt = NULL; + unsigned int i; + int page_count; + int nents, ret; + + DRM_DEBUG_PRIME("[DEV:%s] size:%zd dir=%d\n", dev_name(attach->dev), + attach->dmabuf->size, dir); + + /* just return current sgt if already requested. */ + if (udl_attach->dir == dir && udl_attach->is_mapped) + return &udl_attach->sgt; + + if (!obj->pages) { + DRM_ERROR("pages is null.\n"); + return ERR_PTR(-ENOMEM); + } + + page_count = obj->base.size / PAGE_SIZE; + obj->sg = drm_prime_pages_to_sg(obj->pages, page_count); + if (!obj->sg) { + DRM_ERROR("sg is null.\n"); + return ERR_PTR(-ENOMEM); + } + + sgt = &udl_attach->sgt; + + ret = sg_alloc_table(sgt, obj->sg->orig_nents, GFP_KERNEL); + if (ret) { + DRM_ERROR("failed to alloc sgt.\n"); + return ERR_PTR(-ENOMEM); + } + + mutex_lock(&dev->struct_mutex); + + rd = obj->sg->sgl; + wr = sgt->sgl; + for (i = 0; i < sgt->orig_nents; ++i) { + sg_set_page(wr, sg_page(rd), rd->length, rd->offset); + rd = sg_next(rd); + wr = sg_next(wr); + } + + if (dir != DMA_NONE) { + nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); + if (!nents) { + DRM_ERROR("failed to map sgl with iommu.\n"); + sg_free_table(sgt); + sgt = ERR_PTR(-EIO); + goto err_unlock; + } + } + + udl_attach->is_mapped = true; + udl_attach->dir = dir; + attach->priv = udl_attach; + +err_unlock: + mutex_unlock(&dev->struct_mutex); + return sgt; +} + +static void udl_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ + /* Nothing to do. */ + DRM_DEBUG_PRIME("[DEV:%s] size:%zd dir:%d\n", dev_name(attach->dev), + attach->dmabuf->size, dir); +} + +static void *udl_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num) +{ + /* TODO */ + + return NULL; +} + +static void *udl_dmabuf_kmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num) +{ + /* TODO */ + + return NULL; +} + +static void udl_dmabuf_kunmap(struct dma_buf *dma_buf, + unsigned long page_num, void *addr) +{ + /* TODO */ +} + +static void udl_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num, + void *addr) +{ + /* TODO */ +} + +static int udl_dmabuf_mmap(struct dma_buf *dma_buf, + struct vm_area_struct *vma) +{ + /* TODO */ + + return -EINVAL; +} + +static struct dma_buf_ops udl_dmabuf_ops = { + .attach = udl_attach_dma_buf, + .detach = udl_detach_dma_buf, + .map_dma_buf = udl_map_dma_buf, + .unmap_dma_buf = udl_unmap_dma_buf, + .kmap = udl_dmabuf_kmap, + .kmap_atomic = udl_dmabuf_kmap_atomic, + .kunmap = udl_dmabuf_kunmap, + .kunmap_atomic = udl_dmabuf_kunmap_atomic, + .mmap = udl_dmabuf_mmap, + .release = drm_gem_dmabuf_release, +}; + +struct dma_buf *udl_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags) +{ + return dma_buf_export(obj, &udl_dmabuf_ops, obj->size, flags, NULL); +} + +static int udl_prime_create(struct drm_device *dev, + size_t size, + struct sg_table *sg, + struct udl_gem_object **obj_p) +{ + struct udl_gem_object *obj; + int npages; + + npages = size / PAGE_SIZE; + + *obj_p = NULL; + obj = udl_gem_alloc_object(dev, npages * PAGE_SIZE); + if (!obj) + return -ENOMEM; + + obj->sg = sg; + obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + if (obj->pages == NULL) { + DRM_ERROR("obj pages is NULL %d\n", npages); + return -ENOMEM; + } + + drm_prime_sg_to_page_addr_arrays(sg, obj->pages, NULL, npages); + + *obj_p = obj; + return 0; +} + +struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf) +{ + struct dma_buf_attachment *attach; + struct sg_table *sg; + struct udl_gem_object *uobj; + int ret; + + /* need to attach */ + get_device(dev->dev); + attach = dma_buf_attach(dma_buf, dev->dev); + if (IS_ERR(attach)) { + put_device(dev->dev); + return ERR_CAST(attach); + } + + get_dma_buf(dma_buf); + + sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sg)) { + ret = PTR_ERR(sg); + goto fail_detach; + } + + ret = udl_prime_create(dev, dma_buf->size, sg, &uobj); + if (ret) + goto fail_unmap; + + uobj->base.import_attach = attach; + uobj->flags = UDL_BO_WC; + + return &uobj->base; + +fail_unmap: + dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); +fail_detach: + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + put_device(dev->dev); + return ERR_PTR(ret); +} diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 8607e9e513db..d5728ec85254 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -51,7 +51,9 @@ static struct drm_driver driver = { .dumb_destroy = drm_gem_dumb_destroy, .fops = &udl_driver_fops, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = udl_gem_prime_export, .gem_prime_import = udl_gem_prime_import, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 308278086c72..1b132d779621 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -124,6 +124,8 @@ int udl_gem_mmap(struct drm_file *file_priv, struct drm_device *dev, void udl_gem_free_object(struct drm_gem_object *gem_obj); struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, size_t size); +struct dma_buf *udl_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags); struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index e00459d38dcb..692d6f21f1bc 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -240,74 +240,3 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, mutex_unlock(&dev->struct_mutex); return ret; } - -static int udl_prime_create(struct drm_device *dev, - size_t size, - struct sg_table *sg, - struct udl_gem_object **obj_p) -{ - struct udl_gem_object *obj; - int npages; - - npages = size / PAGE_SIZE; - - *obj_p = NULL; - obj = udl_gem_alloc_object(dev, npages * PAGE_SIZE); - if (!obj) - return -ENOMEM; - - obj->sg = sg; - obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); - if (obj->pages == NULL) { - DRM_ERROR("obj pages is NULL %d\n", npages); - return -ENOMEM; - } - - drm_prime_sg_to_page_addr_arrays(sg, obj->pages, NULL, npages); - - *obj_p = obj; - return 0; -} - -struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf) -{ - struct dma_buf_attachment *attach; - struct sg_table *sg; - struct udl_gem_object *uobj; - int ret; - - /* need to attach */ - get_device(dev->dev); - attach = dma_buf_attach(dma_buf, dev->dev); - if (IS_ERR(attach)) { - put_device(dev->dev); - return ERR_CAST(attach); - } - - get_dma_buf(dma_buf); - - sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sg)) { - ret = PTR_ERR(sg); - goto fail_detach; - } - - ret = udl_prime_create(dev, dma_buf->size, sg, &uobj); - if (ret) { - goto fail_unmap; - } - - uobj->base.import_attach = attach; - uobj->flags = UDL_BO_WC; - - return &uobj->base; - -fail_unmap: - dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); -fail_detach: - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - put_device(dev->dev); - return ERR_PTR(ret); -} -- GitLab From 8975626ea35adcca561f8a81dedccfbc5dd8ec72 Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Wed, 29 Oct 2014 11:04:24 -0700 Subject: [PATCH 5435/9457] drm/cirrus: allow 32bpp framebuffers for cirrus drm This patch allows framebuffers for cirrus to be created with 32bpp pixel formats provided that they do not violate certain restrictions of the cirrus hardware. v2: Use pci resource length for vram size. Signed-off-by: Zach Reizner Signed-off-by: Dave Airlie --- drivers/gpu/drm/cirrus/cirrus_drv.h | 3 +++ drivers/gpu/drm/cirrus/cirrus_fbdev.c | 5 ++++- drivers/gpu/drm/cirrus/cirrus_main.c | 27 +++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h index d44e69daa239..693a4565c4ff 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.h +++ b/drivers/gpu/drm/cirrus/cirrus_drv.h @@ -210,6 +210,9 @@ int cirrus_framebuffer_init(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj); +bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height, + int bpp, int pitch); + /* cirrus_display.c */ int cirrus_modeset_init(struct cirrus_device *cdev); void cirrus_modeset_fini(struct cirrus_device *cdev); diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index d231b1c317af..502a89eb54b5 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c @@ -139,6 +139,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev, struct drm_gem_object **gobj_p) { struct drm_device *dev = afbdev->helper.dev; + struct cirrus_device *cdev = dev->dev_private; u32 bpp, depth; u32 size; struct drm_gem_object *gobj; @@ -146,8 +147,10 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev, int ret = 0; drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); - if (bpp > 24) + if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height, + bpp, mode_cmd->pitches[0])) return -EINVAL; + size = mode_cmd->pitches[0] * mode_cmd->height; ret = cirrus_gem_create(dev, size, true, &gobj); if (ret) diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index ab7cb547c570..4c2d68e9102d 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -49,14 +49,16 @@ cirrus_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, struct drm_mode_fb_cmd2 *mode_cmd) { + struct cirrus_device *cdev = dev->dev_private; struct drm_gem_object *obj; struct cirrus_framebuffer *cirrus_fb; int ret; u32 bpp, depth; drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); - /* cirrus can't handle > 24bpp framebuffers at all */ - if (bpp > 24) + + if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height, + bpp, mode_cmd->pitches[0])) return ERR_PTR(-EINVAL); obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); @@ -96,8 +98,7 @@ static int cirrus_vram_init(struct cirrus_device *cdev) { /* BAR 0 is VRAM */ cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0); - /* We have 4MB of VRAM */ - cdev->mc.vram_size = 4 * 1024 * 1024; + cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0); if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size, "cirrusdrmfb_vram")) { @@ -312,3 +313,21 @@ cirrus_dumb_mmap_offset(struct drm_file *file, return ret; } + +bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height, + int bpp, int pitch) +{ + const int max_pitch = 0x1FF << 3; /* (4096 - 1) & ~111b bytes */ + const int max_size = cdev->mc.vram_size; + + if (bpp > 32) + return false; + + if (pitch > max_pitch) + return false; + + if (pitch * height > max_size) + return false; + + return true; +} -- GitLab From 3a161d99c43ce74c76aecff309be4c3ba455e823 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 25 Jun 2014 15:54:42 -0400 Subject: [PATCH 5436/9457] tracing: Create seq_buf layer in trace_seq Create a seq_buf layer that trace_seq sits on. The seq_buf will not be limited to page size. This will allow other usages of seq_buf instead of a hard set PAGE_SIZE one that trace_seq has. Link: http://lkml.kernel.org/r/20141104160221.864997179@goodmis.org Link: http://lkml.kernel.org/r/20141114011412.170377300@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 81 +++++++ include/linux/trace_seq.h | 12 +- kernel/trace/Makefile | 1 + kernel/trace/seq_buf.c | 341 +++++++++++++++++++++++++++ kernel/trace/trace.c | 39 +-- kernel/trace/trace_events.c | 6 +- kernel/trace/trace_functions_graph.c | 6 +- kernel/trace/trace_seq.c | 178 +++++++------- 8 files changed, 538 insertions(+), 126 deletions(-) create mode 100644 include/linux/seq_buf.h create mode 100644 kernel/trace/seq_buf.c diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h new file mode 100644 index 000000000000..4f7a96a9d71a --- /dev/null +++ b/include/linux/seq_buf.h @@ -0,0 +1,81 @@ +#ifndef _LINUX_SEQ_BUF_H +#define _LINUX_SEQ_BUF_H + +#include + +/* + * Trace sequences are used to allow a function to call several other functions + * to create a string of data to use. + */ + +/** + * seq_buf - seq buffer structure + * @buffer: pointer to the buffer + * @size: size of the buffer + * @len: the amount of data inside the buffer + * @readpos: The next position to read in the buffer. + */ +struct seq_buf { + unsigned char *buffer; + unsigned int size; + unsigned int len; + unsigned int readpos; +}; + +static inline void +seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size) +{ + s->buffer = buf; + s->size = size; + s->len = 0; + s->readpos = 0; +} + +/* + * seq_buf have a buffer that might overflow. When this happens + * the len and size are set to be equal. + */ +static inline bool +seq_buf_has_overflowed(struct seq_buf *s) +{ + return s->len == s->size; +} + +static inline void +seq_buf_set_overflow(struct seq_buf *s) +{ + s->len = s->size; +} + +/* + * How much buffer is left on the seq_buf? + */ +static inline unsigned int +seq_buf_buffer_left(struct seq_buf *s) +{ + if (seq_buf_has_overflowed(s)) + return 0; + + return (s->size - 1) - s->len; +} + +extern __printf(2, 3) +int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); +extern __printf(2, 0) +int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); +extern int +seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary); +extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s); +extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, + int cnt); +extern int seq_buf_puts(struct seq_buf *s, const char *str); +extern int seq_buf_putc(struct seq_buf *s, unsigned char c); +extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len); +extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, + unsigned int len); +extern int seq_buf_path(struct seq_buf *s, const struct path *path); + +extern int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, + int nmaskbits); + +#endif /* _LINUX_SEQ_BUF_H */ diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index db8a73224f1a..85d37106be3d 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -1,7 +1,7 @@ #ifndef _LINUX_TRACE_SEQ_H #define _LINUX_TRACE_SEQ_H -#include +#include #include @@ -12,16 +12,14 @@ struct trace_seq { unsigned char buffer[PAGE_SIZE]; - unsigned int len; - unsigned int readpos; + struct seq_buf seq; int full; }; static inline void trace_seq_init(struct trace_seq *s) { - s->len = 0; - s->readpos = 0; + seq_buf_init(&s->seq, s->buffer, PAGE_SIZE); s->full = 0; } @@ -37,7 +35,7 @@ trace_seq_init(struct trace_seq *s) static inline unsigned char * trace_seq_buffer_ptr(struct trace_seq *s) { - return s->buffer + s->len; + return s->buffer + s->seq.len; } /** @@ -49,7 +47,7 @@ trace_seq_buffer_ptr(struct trace_seq *s) */ static inline bool trace_seq_has_overflowed(struct trace_seq *s) { - return s->full || s->len > PAGE_SIZE - 1; + return s->full || seq_buf_has_overflowed(&s->seq); } /* diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 67d6369ddf83..edc98c72a634 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o +obj-$(CONFIG_TRACING) += seq_buf.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c new file mode 100644 index 000000000000..e9a7861595d2 --- /dev/null +++ b/kernel/trace/seq_buf.c @@ -0,0 +1,341 @@ +/* + * seq_buf.c + * + * Copyright (C) 2014 Red Hat Inc, Steven Rostedt + * + * The seq_buf is a handy tool that allows you to pass a descriptor around + * to a buffer that other functions can write to. It is similar to the + * seq_file functionality but has some differences. + * + * To use it, the seq_buf must be initialized with seq_buf_init(). + * This will set up the counters within the descriptor. You can call + * seq_buf_init() more than once to reset the seq_buf to start + * from scratch. + */ +#include +#include +#include + +/* How much buffer is written? */ +#define SEQ_BUF_USED(s) min((s)->len, (s)->size - 1) + +/** + * seq_buf_print_seq - move the contents of seq_buf into a seq_file + * @m: the seq_file descriptor that is the destination + * @s: the seq_buf descriptor that is the source. + * + * Returns zero on success, non zero otherwise + */ +int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) +{ + unsigned int len = SEQ_BUF_USED(s); + + return seq_write(m, s->buffer, len); +} + +/** + * seq_buf_vprintf - sequence printing of information. + * @s: seq_buf descriptor + * @fmt: printf format string + * @args: va_list of arguments from a printf() type function + * + * Writes a vnprintf() format into the sequencce buffer. + * + * Returns zero on success, -1 on overflow. + */ +int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) +{ + int len; + + WARN_ON(s->size == 0); + + if (s->len < s->size) { + len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); + if (s->len + len < s->size) { + s->len += len; + return 0; + } + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_printf - sequence printing of information + * @s: seq_buf descriptor + * @fmt: printf format string + * + * Writes a printf() format into the sequence buffer. + * + * Returns zero on success, -1 on overflow. + */ +int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = seq_buf_vprintf(s, fmt, ap); + va_end(ap); + + return ret; +} + +/** + * seq_buf_bitmask - write a bitmask array in its ASCII representation + * @s: seq_buf descriptor + * @maskp: points to an array of unsigned longs that represent a bitmask + * @nmaskbits: The number of bits that are valid in @maskp + * + * Writes a ASCII representation of a bitmask string into @s. + * + * Returns zero on success, -1 on overflow. + */ +int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, + int nmaskbits) +{ + unsigned int len = seq_buf_buffer_left(s); + int ret; + + WARN_ON(s->size == 0); + + /* + * The last byte of the buffer is used to determine if we + * overflowed or not. + */ + if (len > 1) { + ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits); + if (ret < len) { + s->len += ret; + return 0; + } + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_bprintf - Write the printf string from binary arguments + * @s: seq_buf descriptor + * @fmt: The format string for the @binary arguments + * @binary: The binary arguments for @fmt. + * + * When recording in a fast path, a printf may be recorded with just + * saving the format and the arguments as they were passed to the + * function, instead of wasting cycles converting the arguments into + * ASCII characters. Instead, the arguments are saved in a 32 bit + * word array that is defined by the format string constraints. + * + * This function will take the format and the binary array and finish + * the conversion into the ASCII string within the buffer. + * + * Returns zero on success, -1 on overflow. + */ +int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) +{ + unsigned int len = seq_buf_buffer_left(s); + int ret; + + WARN_ON(s->size == 0); + + if (s->len < s->size) { + ret = bstr_printf(s->buffer + s->len, len, fmt, binary); + if (s->len + ret < s->size) { + s->len += ret; + return 0; + } + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_puts - sequence printing of simple string + * @s: seq_buf descriptor + * @str: simple string to record + * + * Copy a simple string into the sequence buffer. + * + * Returns zero on success, -1 on overflow + */ +int seq_buf_puts(struct seq_buf *s, const char *str) +{ + unsigned int len = strlen(str); + + WARN_ON(s->size == 0); + + if (s->len + len < s->size) { + memcpy(s->buffer + s->len, str, len); + s->len += len; + return 0; + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_putc - sequence printing of simple character + * @s: seq_buf descriptor + * @c: simple character to record + * + * Copy a single character into the sequence buffer. + * + * Returns zero on success, -1 on overflow + */ +int seq_buf_putc(struct seq_buf *s, unsigned char c) +{ + WARN_ON(s->size == 0); + + if (s->len + 1 < s->size) { + s->buffer[s->len++] = c; + return 0; + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_putmem - write raw data into the sequenc buffer + * @s: seq_buf descriptor + * @mem: The raw memory to copy into the buffer + * @len: The length of the raw memory to copy (in bytes) + * + * There may be cases where raw memory needs to be written into the + * buffer and a strcpy() would not work. Using this function allows + * for such cases. + * + * Returns zero on success, -1 on overflow + */ +int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len) +{ + WARN_ON(s->size == 0); + + if (s->len + len < s->size) { + memcpy(s->buffer + s->len, mem, len); + s->len += len; + return 0; + } + seq_buf_set_overflow(s); + return -1; +} + +#define MAX_MEMHEX_BYTES 8U +#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) + +/** + * seq_buf_putmem_hex - write raw memory into the buffer in ASCII hex + * @s: seq_buf descriptor + * @mem: The raw memory to write its hex ASCII representation of + * @len: The length of the raw memory to copy (in bytes) + * + * This is similar to seq_buf_putmem() except instead of just copying the + * raw memory into the buffer it writes its ASCII representation of it + * in hex characters. + * + * Returns zero on success, -1 on overflow + */ +int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, + unsigned int len) +{ + unsigned char hex[HEX_CHARS]; + const unsigned char *data = mem; + unsigned int start_len; + int i, j; + + WARN_ON(s->size == 0); + + while (len) { + start_len = min(len, HEX_CHARS - 1); +#ifdef __BIG_ENDIAN + for (i = 0, j = 0; i < start_len; i++) { +#else + for (i = start_len-1, j = 0; i >= 0; i--) { +#endif + hex[j++] = hex_asc_hi(data[i]); + hex[j++] = hex_asc_lo(data[i]); + } + if (WARN_ON_ONCE(j == 0 || j/2 > len)) + break; + + /* j increments twice per loop */ + len -= j / 2; + hex[j++] = ' '; + + seq_buf_putmem(s, hex, j); + if (seq_buf_has_overflowed(s)) + return -1; + } + return 0; +} + +/** + * seq_buf_path - copy a path into the sequence buffer + * @s: seq_buf descriptor + * @path: path to write into the sequence buffer. + * + * Write a path name into the sequence buffer. + * + * Returns zero on success, -1 on overflow + */ +int seq_buf_path(struct seq_buf *s, const struct path *path) +{ + unsigned int len = seq_buf_buffer_left(s); + unsigned char *p; + + WARN_ON(s->size == 0); + + p = d_path(path, s->buffer + s->len, len); + if (!IS_ERR(p)) { + p = mangle_path(s->buffer + s->len, p, "\n"); + if (p) { + s->len = p - s->buffer; + return 0; + } + } + seq_buf_set_overflow(s); + return -1; +} + +/** + * seq_buf_to_user - copy the squence buffer to user space + * @s: seq_buf descriptor + * @ubuf: The userspace memory location to copy to + * @cnt: The amount to copy + * + * Copies the sequence buffer into the userspace memory pointed to + * by @ubuf. It starts from the last read position (@s->readpos) + * and writes up to @cnt characters or till it reaches the end of + * the content in the buffer (@s->len), which ever comes first. + * + * On success, it returns a positive number of the number of bytes + * it copied. + * + * On failure it returns -EBUSY if all of the content in the + * sequence has been already read, which includes nothing in the + * sequence (@s->len == @s->readpos). + * + * Returns -EFAULT if the copy to userspace fails. + */ +int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt) +{ + int len; + int ret; + + if (!cnt) + return 0; + + if (s->len <= s->readpos) + return -EBUSY; + + len = s->len - s->readpos; + if (cnt > len) + cnt = len; + ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); + if (ret == cnt) + return -EFAULT; + + cnt -= ret; + + s->readpos += cnt; + return cnt; +} diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3ce3c4ccfc94..7d7a07e9b9e9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -939,19 +939,20 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, return ret; } +/* TODO add a seq_buf_to_buffer() */ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) { int len; - if (s->len <= s->readpos) + if (s->seq.len <= s->seq.readpos) return -EBUSY; - len = s->len - s->readpos; + len = s->seq.len - s->seq.readpos; if (cnt > len) cnt = len; - memcpy(buf, s->buffer + s->readpos, cnt); + memcpy(buf, s->buffer + s->seq.readpos, cnt); - s->readpos += cnt; + s->seq.readpos += cnt; return cnt; } @@ -4315,6 +4316,8 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) goto out; } + trace_seq_init(&iter->seq); + /* * We make a copy of the current tracer to avoid concurrent * changes on it while we are reading. @@ -4511,18 +4514,18 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, trace_access_lock(iter->cpu_file); while (trace_find_next_entry_inc(iter) != NULL) { enum print_line_t ret; - int len = iter->seq.len; + int len = iter->seq.seq.len; ret = print_trace_line(iter); if (ret == TRACE_TYPE_PARTIAL_LINE) { /* don't print partial lines */ - iter->seq.len = len; + iter->seq.seq.len = len; break; } if (ret != TRACE_TYPE_NO_CONSUME) trace_consume(iter); - if (iter->seq.len >= cnt) + if (iter->seq.seq.len >= cnt) break; /* @@ -4538,7 +4541,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, /* Now copy what we have to the user */ sret = trace_seq_to_user(&iter->seq, ubuf, cnt); - if (iter->seq.readpos >= iter->seq.len) + if (iter->seq.seq.readpos >= iter->seq.seq.len) trace_seq_init(&iter->seq); /* @@ -4576,16 +4579,16 @@ tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) /* Seq buffer is page-sized, exactly what we need. */ for (;;) { - count = iter->seq.len; + count = iter->seq.seq.len; ret = print_trace_line(iter); - count = iter->seq.len - count; + count = iter->seq.seq.len - count; if (rem < count) { rem = 0; - iter->seq.len -= count; + iter->seq.seq.len -= count; break; } if (ret == TRACE_TYPE_PARTIAL_LINE) { - iter->seq.len -= count; + iter->seq.seq.len -= count; break; } @@ -4666,13 +4669,13 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, /* Copy the data into the page, so we can start over. */ ret = trace_seq_to_buffer(&iter->seq, page_address(spd.pages[i]), - iter->seq.len); + iter->seq.seq.len); if (ret < 0) { __free_page(spd.pages[i]); break; } spd.partial[i].offset = 0; - spd.partial[i].len = iter->seq.len; + spd.partial[i].len = iter->seq.seq.len; trace_seq_init(&iter->seq); } @@ -5673,7 +5676,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf, cnt = ring_buffer_read_events_cpu(trace_buf->buffer, cpu); trace_seq_printf(s, "read events: %ld\n", cnt); - count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); + count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->seq.len); kfree(s); @@ -6636,11 +6639,11 @@ void trace_printk_seq(struct trace_seq *s) { /* Probably should print a warning here. */ - if (s->len >= TRACE_MAX_PRINT) - s->len = TRACE_MAX_PRINT; + if (s->seq.len >= TRACE_MAX_PRINT) + s->seq.len = TRACE_MAX_PRINT; /* should be zero ended, but we are paranoid. */ - s->buffer[s->len] = 0; + s->buffer[s->seq.len] = 0; printk(KERN_TRACE "%s", s->buffer); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index f9d0cbe014b7..4d0067dd7f88 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -1044,7 +1044,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, mutex_unlock(&event_mutex); if (file) - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); + r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); kfree(s); @@ -1210,7 +1210,7 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, trace_seq_init(s); print_subsystem_event_filter(system, s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); + r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); kfree(s); @@ -1265,7 +1265,7 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) trace_seq_init(s); func(s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); + r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); kfree(s); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 100288d10e1f..6d1342ae7a44 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1154,9 +1154,9 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, } /* Strip ending newline */ - if (s->buffer[s->len - 1] == '\n') { - s->buffer[s->len - 1] = '\0'; - s->len--; + if (s->buffer[s->seq.len - 1] == '\n') { + s->buffer[s->seq.len - 1] = '\0'; + s->seq.len--; } trace_seq_puts(s, " */\n"); diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index fabfa0f190a3..8c0c54fe674b 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -27,10 +27,19 @@ #include /* How much buffer is left on the trace_seq? */ -#define TRACE_SEQ_BUF_LEFT(s) ((PAGE_SIZE - 1) - (s)->len) +#define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq) /* How much buffer is written? */ -#define TRACE_SEQ_BUF_USED(s) min((s)->len, (unsigned int)(PAGE_SIZE - 1)) +#define TRACE_SEQ_BUF_USED(s) min((s)->seq.len, (unsigned int)(PAGE_SIZE - 1)) + +/* + * trace_seq should work with being initialized with 0s. + */ +static inline void __trace_seq_init(struct trace_seq *s) +{ + if (unlikely(!s->seq.size)) + trace_seq_init(s); +} /** * trace_print_seq - move the contents of trace_seq into a seq_file @@ -43,10 +52,11 @@ */ int trace_print_seq(struct seq_file *m, struct trace_seq *s) { - unsigned int len = TRACE_SEQ_BUF_USED(s); int ret; - ret = seq_write(m, s->buffer, len); + __trace_seq_init(s); + + ret = seq_buf_print_seq(m, &s->seq); /* * Only reset this buffer if we successfully wrote to the @@ -72,24 +82,23 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s) */ void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { - unsigned int len = TRACE_SEQ_BUF_LEFT(s); + unsigned int save_len = s->seq.len; va_list ap; - int ret; - if (s->full || !len) + if (s->full) return; + __trace_seq_init(s); + va_start(ap, fmt); - ret = vsnprintf(s->buffer + s->len, len, fmt, ap); + seq_buf_vprintf(&s->seq, fmt, ap); va_end(ap); /* If we can't write it all, don't bother writing anything */ - if (ret >= len) { + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; s->full = 1; - return; } - - s->len += ret; } EXPORT_SYMBOL_GPL(trace_seq_printf); @@ -104,14 +113,19 @@ EXPORT_SYMBOL_GPL(trace_seq_printf); void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, int nmaskbits) { - unsigned int len = TRACE_SEQ_BUF_LEFT(s); - int ret; + unsigned int save_len = s->seq.len; - if (s->full || !len) + if (s->full) return; - ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits); - s->len += ret; + __trace_seq_init(s); + + seq_buf_bitmask(&s->seq, maskp, nmaskbits); + + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; + s->full = 1; + } } EXPORT_SYMBOL_GPL(trace_seq_bitmask); @@ -128,21 +142,20 @@ EXPORT_SYMBOL_GPL(trace_seq_bitmask); */ void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) { - unsigned int len = TRACE_SEQ_BUF_LEFT(s); - int ret; + unsigned int save_len = s->seq.len; - if (s->full || !len) + if (s->full) return; - ret = vsnprintf(s->buffer + s->len, len, fmt, args); + __trace_seq_init(s); + + seq_buf_vprintf(&s->seq, fmt, args); /* If we can't write it all, don't bother writing anything */ - if (ret >= len) { + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; s->full = 1; - return; } - - s->len += ret; } EXPORT_SYMBOL_GPL(trace_seq_vprintf); @@ -163,21 +176,21 @@ EXPORT_SYMBOL_GPL(trace_seq_vprintf); */ void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) { - unsigned int len = TRACE_SEQ_BUF_LEFT(s); - int ret; + unsigned int save_len = s->seq.len; - if (s->full || !len) + if (s->full) return; - ret = bstr_printf(s->buffer + s->len, len, fmt, binary); + __trace_seq_init(s); + + seq_buf_bprintf(&s->seq, fmt, binary); /* If we can't write it all, don't bother writing anything */ - if (ret >= len) { + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; s->full = 1; return; } - - s->len += ret; } EXPORT_SYMBOL_GPL(trace_seq_bprintf); @@ -198,13 +211,14 @@ void trace_seq_puts(struct trace_seq *s, const char *str) if (s->full) return; + __trace_seq_init(s); + if (len > TRACE_SEQ_BUF_LEFT(s)) { s->full = 1; return; } - memcpy(s->buffer + s->len, str, len); - s->len += len; + seq_buf_putmem(&s->seq, str, len); } EXPORT_SYMBOL_GPL(trace_seq_puts); @@ -223,12 +237,14 @@ void trace_seq_putc(struct trace_seq *s, unsigned char c) if (s->full) return; + __trace_seq_init(s); + if (TRACE_SEQ_BUF_LEFT(s) < 1) { s->full = 1; return; } - s->buffer[s->len++] = c; + seq_buf_putc(&s->seq, c); } EXPORT_SYMBOL_GPL(trace_seq_putc); @@ -247,19 +263,17 @@ void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len) if (s->full) return; + __trace_seq_init(s); + if (len > TRACE_SEQ_BUF_LEFT(s)) { s->full = 1; return; } - memcpy(s->buffer + s->len, mem, len); - s->len += len; + seq_buf_putmem(&s->seq, mem, len); } EXPORT_SYMBOL_GPL(trace_seq_putmem); -#define MAX_MEMHEX_BYTES 8U -#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) - /** * trace_seq_putmem_hex - write raw memory into the buffer in ASCII hex * @s: trace sequence descriptor @@ -273,32 +287,26 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem); void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len) { - unsigned char hex[HEX_CHARS]; - const unsigned char *data = mem; - unsigned int start_len; - int i, j; + unsigned int save_len = s->seq.len; if (s->full) return; - while (len) { - start_len = min(len, HEX_CHARS - 1); -#ifdef __BIG_ENDIAN - for (i = 0, j = 0; i < start_len; i++) { -#else - for (i = start_len-1, j = 0; i >= 0; i--) { -#endif - hex[j++] = hex_asc_hi(data[i]); - hex[j++] = hex_asc_lo(data[i]); - } - if (WARN_ON_ONCE(j == 0 || j/2 > len)) - break; - - /* j increments twice per loop */ - len -= j / 2; - hex[j++] = ' '; - - trace_seq_putmem(s, hex, j); + __trace_seq_init(s); + + /* Each byte is represented by two chars */ + if (len * 2 > TRACE_SEQ_BUF_LEFT(s)) { + s->full = 1; + return; + } + + /* The added spaces can still cause an overflow */ + seq_buf_putmem_hex(&s->seq, mem, len); + + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; + s->full = 1; + return; } } EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); @@ -317,30 +325,28 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); */ int trace_seq_path(struct trace_seq *s, const struct path *path) { - unsigned char *p; + unsigned int save_len = s->seq.len; + int ret; if (s->full) return 0; + __trace_seq_init(s); + if (TRACE_SEQ_BUF_LEFT(s) < 1) { s->full = 1; return 0; } - p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); - if (!IS_ERR(p)) { - p = mangle_path(s->buffer + s->len, p, "\n"); - if (p) { - s->len = p - s->buffer; - return 1; - } - } else { - s->buffer[s->len++] = '?'; - return 1; + ret = seq_buf_path(&s->seq, path); + + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; + s->full = 1; + return 0; } - s->full = 1; - return 0; + return ret; } EXPORT_SYMBOL_GPL(trace_seq_path); @@ -366,25 +372,7 @@ EXPORT_SYMBOL_GPL(trace_seq_path); */ int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) { - int len; - int ret; - - if (!cnt) - return 0; - - if (s->len <= s->readpos) - return -EBUSY; - - len = s->len - s->readpos; - if (cnt > len) - cnt = len; - ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); - if (ret == cnt) - return -EFAULT; - - cnt -= ret; - - s->readpos += cnt; - return cnt; + __trace_seq_init(s); + return seq_buf_to_user(&s->seq, ubuf, cnt); } EXPORT_SYMBOL_GPL(trace_seq_to_user); -- GitLab From dd23180aacf4b27d48f40b27249f1e58c8df03be Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 29 Oct 2014 13:48:37 -0400 Subject: [PATCH 5437/9457] tracing: Convert seq_buf_path() to be like seq_path() Rewrite seq_buf_path() like it is done in seq_path() and allow it to accept any escape character instead of just "\n". Making seq_buf_path() like seq_path() will help prevent problems when converting seq_file to use the seq_buf logic. Link: http://lkml.kernel.org/r/20141104160222.048795666@goodmis.org Link: http://lkml.kernel.org/r/20141114011412.338523371@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 2 +- kernel/trace/seq_buf.c | 28 ++++++++++++++++------------ kernel/trace/trace_seq.c | 5 ++--- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 4f7a96a9d71a..38770688a627 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -73,7 +73,7 @@ extern int seq_buf_putc(struct seq_buf *s, unsigned char c); extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len); extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, unsigned int len); -extern int seq_buf_path(struct seq_buf *s, const struct path *path); +extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc); extern int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, int nmaskbits); diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index e9a7861595d2..7dac34d1235b 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -272,28 +272,32 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, * seq_buf_path - copy a path into the sequence buffer * @s: seq_buf descriptor * @path: path to write into the sequence buffer. + * @esc: set of characters to escape in the output * * Write a path name into the sequence buffer. * - * Returns zero on success, -1 on overflow + * Returns the number of written bytes on success, -1 on overflow */ -int seq_buf_path(struct seq_buf *s, const struct path *path) +int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc) { - unsigned int len = seq_buf_buffer_left(s); - unsigned char *p; + char *buf = s->buffer + s->len; + size_t size = seq_buf_buffer_left(s); + int res = -1; WARN_ON(s->size == 0); - p = d_path(path, s->buffer + s->len, len); - if (!IS_ERR(p)) { - p = mangle_path(s->buffer + s->len, p, "\n"); - if (p) { - s->len = p - s->buffer; - return 0; + if (size) { + char *p = d_path(path, buf, size); + if (!IS_ERR(p)) { + char *end = mangle_path(buf, p, esc); + if (end) + res = end - buf; } } - seq_buf_set_overflow(s); - return -1; + if (res > 0) + s->len += res; + + return res; } /** diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 8c0c54fe674b..74cacc930c24 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -326,7 +326,6 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); int trace_seq_path(struct trace_seq *s, const struct path *path) { unsigned int save_len = s->seq.len; - int ret; if (s->full) return 0; @@ -338,7 +337,7 @@ int trace_seq_path(struct trace_seq *s, const struct path *path) return 0; } - ret = seq_buf_path(&s->seq, path); + seq_buf_path(&s->seq, path, "\n"); if (unlikely(seq_buf_has_overflowed(&s->seq))) { s->seq.len = save_len; @@ -346,7 +345,7 @@ int trace_seq_path(struct trace_seq *s, const struct path *path) return 0; } - return ret; + return 1; } EXPORT_SYMBOL_GPL(trace_seq_path); -- GitLab From 9a7777935c34b9192e28ef3d232a4b6b5414a657 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 29 Oct 2014 13:59:58 -0400 Subject: [PATCH 5438/9457] tracing: Convert seq_buf fields to be like seq_file fields In facilitating the conversion of seq_file to use seq_buf, have the seq_buf fields match the types used by seq_file. Link: http://lkml.kernel.org/r/20141104160222.195301024@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 38770688a627..d14dc9023dde 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -16,10 +16,10 @@ * @readpos: The next position to read in the buffer. */ struct seq_buf { - unsigned char *buffer; - unsigned int size; - unsigned int len; - unsigned int readpos; + char *buffer; + size_t size; + size_t len; + loff_t readpos; }; static inline void -- GitLab From 0736c033a81547b1cdc5120fc8dd60e26a00fd28 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 29 Oct 2014 14:17:52 -0400 Subject: [PATCH 5439/9457] tracing: Add a seq_buf_clear() helper and clear len and readpos in init Add a helper function seq_buf_clear() that resets the len and readpos fields of a seq_buf. Currently it is only used in the seq_buf_init() but will be used later when updating the seq_file code. Link: http://lkml.kernel.org/r/20141104160222.352309995@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index d14dc9023dde..5d91262433e2 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -22,13 +22,18 @@ struct seq_buf { loff_t readpos; }; +static inline void seq_buf_clear(struct seq_buf *s) +{ + s->len = 0; + s->readpos = 0; +} + static inline void seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size) { s->buffer = buf; s->size = size; - s->len = 0; - s->readpos = 0; + seq_buf_clear(s); } /* -- GitLab From eeab98154dc0b49afd398afdd71c464a8af5911f Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 6 Nov 2014 16:38:28 -0500 Subject: [PATCH 5440/9457] seq_buf: Create seq_buf_used() to find out how much was written Add a helper function seq_buf_used() that replaces the SEQ_BUF_USED() private macro to let callers have a method to know how much of the seq_buf was written to. Link: http://lkml.kernel.org/r/20141114011412.170377300@goodmis.org Link: http://lkml.kernel.org/r/20141114011413.321654244@goodmis.org Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 6 ++++++ kernel/trace/seq_buf.c | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 5d91262433e2..93718e570d4c 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -64,6 +64,12 @@ seq_buf_buffer_left(struct seq_buf *s) return (s->size - 1) - s->len; } +/* How much buffer was written? */ +static inline unsigned int seq_buf_used(struct seq_buf *s) +{ + return min(s->len, s->size); +} + extern __printf(2, 3) int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); extern __printf(2, 0) diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index 7dac34d1235b..9ec5305d9da7 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -16,9 +16,6 @@ #include #include -/* How much buffer is written? */ -#define SEQ_BUF_USED(s) min((s)->len, (s)->size - 1) - /** * seq_buf_print_seq - move the contents of seq_buf into a seq_file * @m: the seq_file descriptor that is the destination @@ -28,7 +25,7 @@ */ int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) { - unsigned int len = SEQ_BUF_USED(s); + unsigned int len = seq_buf_used(s); return seq_write(m, s->buffer, len); } -- GitLab From 74f06bb72347302a19aac087314388ebd0e4fee9 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 17 Nov 2014 13:12:22 -0500 Subject: [PATCH 5441/9457] tracing: Clean up tracing_fill_pipe_page() The function tracing_fill_pipe_page() logic is a little confusing with the use of count saving the seq.len and reusing it. Instead of subtracting a number that is calculated from the saved value of the seq.len from seq.len, just save the seq.len at the start and if we need to reset it, just assign it again. When the seq_buf overflow is len == size + 1, the current logic will break. Changing it to use a saved length for resetting back to the original value is more robust and will work when we change the way seq_buf sets the overflow. Link: http://lkml.kernel.org/r/20141118161546.GJ23958@pathway.suse.cz Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 7d7a07e9b9e9..0aa75be843a0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4575,20 +4575,33 @@ static size_t tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) { size_t count; + int save_len; int ret; /* Seq buffer is page-sized, exactly what we need. */ for (;;) { - count = iter->seq.seq.len; + save_len = iter->seq.seq.len; ret = print_trace_line(iter); - count = iter->seq.seq.len - count; - if (rem < count) { - rem = 0; - iter->seq.seq.len -= count; + + if (trace_seq_has_overflowed(&iter->seq)) { + iter->seq.seq.len = save_len; break; } + + /* + * This should not be hit, because it should only + * be set if the iter->seq overflowed. But check it + * anyway to be safe. + */ if (ret == TRACE_TYPE_PARTIAL_LINE) { - iter->seq.seq.len -= count; + iter->seq.seq.len = save_len; + break; + } + + count = iter->seq.seq.len - save_len; + if (rem < count) { + rem = 0; + iter->seq.seq.len = save_len; break; } -- GitLab From 5ac48378414dccca735897c4d7f4e19987c8977c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 14 Nov 2014 15:49:41 -0500 Subject: [PATCH 5442/9457] tracing: Use trace_seq_used() and seq_buf_used() instead of len As the seq_buf->len will soon be +1 size when there's an overflow, we must use trace_seq_used() or seq_buf_used() methods to get the real length. This will prevent buffer overflow issues if just the len of the seq_buf descriptor is used to copy memory. Link: http://lkml.kernel.org/r/20141114121911.09ba3d38@gandalf.local.home Reported-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/trace_seq.h | 20 +++++++++++++++++++- kernel/trace/seq_buf.c | 2 +- kernel/trace/trace.c | 21 +++++++++++---------- kernel/trace/trace_events.c | 9 ++++++--- kernel/trace/trace_functions_graph.c | 5 ++++- kernel/trace/trace_seq.c | 2 +- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 85d37106be3d..cfaf5a1d4bad 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -23,6 +23,24 @@ trace_seq_init(struct trace_seq *s) s->full = 0; } +/** + * trace_seq_used - amount of actual data written to buffer + * @s: trace sequence descriptor + * + * Returns the amount of data written to the buffer. + * + * IMPORTANT! + * + * Use this instead of @s->seq.len if you need to pass the amount + * of data from the buffer to another buffer (userspace, or what not). + * The @s->seq.len on overflow is bigger than the buffer size and + * using it can cause access to undefined memory. + */ +static inline int trace_seq_used(struct trace_seq *s) +{ + return seq_buf_used(&s->seq); +} + /** * trace_seq_buffer_ptr - return pointer to next location in buffer * @s: trace sequence descriptor @@ -35,7 +53,7 @@ trace_seq_init(struct trace_seq *s) static inline unsigned char * trace_seq_buffer_ptr(struct trace_seq *s) { - return s->buffer + s->seq.len; + return s->buffer + seq_buf_used(&s->seq); } /** diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index 9ec5305d9da7..ce17f65268ed 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -328,7 +328,7 @@ int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt) if (s->len <= s->readpos) return -EBUSY; - len = s->len - s->readpos; + len = seq_buf_used(s) - s->readpos; if (cnt > len) cnt = len; ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0aa75be843a0..9023446b2c2b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -944,10 +944,10 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) { int len; - if (s->seq.len <= s->seq.readpos) + if (trace_seq_used(s) <= s->seq.readpos) return -EBUSY; - len = s->seq.len - s->seq.readpos; + len = trace_seq_used(s) - s->seq.readpos; if (cnt > len) cnt = len; memcpy(buf, s->buffer + s->seq.readpos, cnt); @@ -4514,18 +4514,18 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, trace_access_lock(iter->cpu_file); while (trace_find_next_entry_inc(iter) != NULL) { enum print_line_t ret; - int len = iter->seq.seq.len; + int save_len = iter->seq.seq.len; ret = print_trace_line(iter); if (ret == TRACE_TYPE_PARTIAL_LINE) { /* don't print partial lines */ - iter->seq.seq.len = len; + iter->seq.seq.len = save_len; break; } if (ret != TRACE_TYPE_NO_CONSUME) trace_consume(iter); - if (iter->seq.seq.len >= cnt) + if (trace_seq_used(&iter->seq) >= cnt) break; /* @@ -4541,7 +4541,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, /* Now copy what we have to the user */ sret = trace_seq_to_user(&iter->seq, ubuf, cnt); - if (iter->seq.seq.readpos >= iter->seq.seq.len) + if (iter->seq.seq.readpos >= trace_seq_used(&iter->seq)) trace_seq_init(&iter->seq); /* @@ -4598,7 +4598,7 @@ tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) break; } - count = iter->seq.seq.len - save_len; + count = trace_seq_used(&iter->seq) - save_len; if (rem < count) { rem = 0; iter->seq.seq.len = save_len; @@ -4682,13 +4682,13 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, /* Copy the data into the page, so we can start over. */ ret = trace_seq_to_buffer(&iter->seq, page_address(spd.pages[i]), - iter->seq.seq.len); + trace_seq_used(&iter->seq)); if (ret < 0) { __free_page(spd.pages[i]); break; } spd.partial[i].offset = 0; - spd.partial[i].len = iter->seq.seq.len; + spd.partial[i].len = trace_seq_used(&iter->seq); trace_seq_init(&iter->seq); } @@ -5689,7 +5689,8 @@ tracing_stats_read(struct file *filp, char __user *ubuf, cnt = ring_buffer_read_events_cpu(trace_buf->buffer, cpu); trace_seq_printf(s, "read events: %ld\n", cnt); - count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->seq.len); + count = simple_read_from_buffer(ubuf, count, ppos, + s->buffer, trace_seq_used(s)); kfree(s); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 4d0067dd7f88..935cbea78532 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -1044,7 +1044,8 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, mutex_unlock(&event_mutex); if (file) - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); + r = simple_read_from_buffer(ubuf, cnt, ppos, + s->buffer, trace_seq_used(s)); kfree(s); @@ -1210,7 +1211,8 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, trace_seq_init(s); print_subsystem_event_filter(system, s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); + r = simple_read_from_buffer(ubuf, cnt, ppos, + s->buffer, trace_seq_used(s)); kfree(s); @@ -1265,7 +1267,8 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) trace_seq_init(s); func(s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->seq.len); + r = simple_read_from_buffer(ubuf, cnt, ppos, + s->buffer, trace_seq_used(s)); kfree(s); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 6d1342ae7a44..ec35468349a7 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1153,6 +1153,9 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, return ret; } + if (trace_seq_has_overflowed(s)) + goto out; + /* Strip ending newline */ if (s->buffer[s->seq.len - 1] == '\n') { s->buffer[s->seq.len - 1] = '\0'; @@ -1160,7 +1163,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, } trace_seq_puts(s, " */\n"); - + out: return trace_handle_return(s); } diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 74cacc930c24..f8b45d8792f9 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -30,7 +30,7 @@ #define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq) /* How much buffer is written? */ -#define TRACE_SEQ_BUF_USED(s) min((s)->seq.len, (unsigned int)(PAGE_SIZE - 1)) +#define TRACE_SEQ_BUF_USED(s) seq_buf_used(&(s)->seq) /* * trace_seq should work with being initialized with 0s. -- GitLab From 820b75f63d0152dbb9ff4accf274408592d613f2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 19 Nov 2014 10:56:41 -0500 Subject: [PATCH 5443/9457] tracing: Add paranoid size check in trace_printk_seq() To be really paranoid about writing out of bound data in trace_printk_seq(), add another check of len compared to size. Link: http://lkml.kernel.org/r/20141119144004.GB2332@dhcp128.suse.cz Suggested-by: Petr Mladek Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9023446b2c2b..26facec4625e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6656,6 +6656,14 @@ trace_printk_seq(struct trace_seq *s) if (s->seq.len >= TRACE_MAX_PRINT) s->seq.len = TRACE_MAX_PRINT; + /* + * More paranoid code. Although the buffer size is set to + * PAGE_SIZE, and TRACE_MAX_PRINT is 1000, this is just + * an extra layer of protection. + */ + if (WARN_ON_ONCE(s->seq.len >= s->seq.size)) + s->seq.len = s->seq.size - 1; + /* should be zero ended, but we are paranoid. */ s->buffer[s->seq.len] = 0; -- GitLab From 9b77215382b42ef9c5b34293ad3a95332e5b71ef Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 14 Nov 2014 16:18:14 -0500 Subject: [PATCH 5444/9457] seq_buf: Add seq_buf_can_fit() helper function Add a seq_buf_can_fit() helper function that removes the possible mistakes of comparing the seq_buf length plus added data compared to the size of the buffer. Link: http://lkml.kernel.org/r/20141118164025.GL23958@pathway.suse.cz Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/seq_buf.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index ce17f65268ed..6fc9d021cbef 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -16,6 +16,19 @@ #include #include +/** + * seq_buf_can_fit - can the new data fit in the current buffer? + * @s: the seq_buf descriptor + * @len: The length to see if it can fit in the current buffer + * + * Returns true if there's enough unused space in the seq_buf buffer + * to fit the amount of new data according to @len. + */ +static bool seq_buf_can_fit(struct seq_buf *s, size_t len) +{ + return s->len + len < s->size; +} + /** * seq_buf_print_seq - move the contents of seq_buf into a seq_file * @m: the seq_file descriptor that is the destination @@ -48,7 +61,7 @@ int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) if (s->len < s->size) { len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); - if (s->len + len < s->size) { + if (seq_buf_can_fit(s, len)) { s->len += len; return 0; } @@ -137,7 +150,7 @@ int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) if (s->len < s->size) { ret = bstr_printf(s->buffer + s->len, len, fmt, binary); - if (s->len + ret < s->size) { + if (seq_buf_can_fit(s, ret)) { s->len += ret; return 0; } @@ -161,7 +174,7 @@ int seq_buf_puts(struct seq_buf *s, const char *str) WARN_ON(s->size == 0); - if (s->len + len < s->size) { + if (seq_buf_can_fit(s, len)) { memcpy(s->buffer + s->len, str, len); s->len += len; return 0; @@ -183,7 +196,7 @@ int seq_buf_putc(struct seq_buf *s, unsigned char c) { WARN_ON(s->size == 0); - if (s->len + 1 < s->size) { + if (seq_buf_can_fit(s, 1)) { s->buffer[s->len++] = c; return 0; } @@ -207,7 +220,7 @@ int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len) { WARN_ON(s->size == 0); - if (s->len + len < s->size) { + if (seq_buf_can_fit(s, len)) { memcpy(s->buffer + s->len, mem, len); s->len += len; return 0; -- GitLab From 8cd709ae7658a7fd7f6630699e3229188c2591e4 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 29 Oct 2014 15:26:09 -0400 Subject: [PATCH 5445/9457] tracing: Have seq_buf use full buffer Currently seq_buf is full when all but one byte of the buffer is filled. Change it so that the seq_buf is full when all of the buffer is filled. Some of the functions would fill the buffer completely and report everything was fine. This was inconsistent with the max of size - 1. Changing this to be max of size makes all functions consistent. Link: http://lkml.kernel.org/r/20141104160222.502133196@goodmis.org Link: http://lkml.kernel.org/r/20141114011412.811957882@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 6 +++--- kernel/trace/seq_buf.c | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 93718e570d4c..0800a24b4348 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -43,13 +43,13 @@ seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size) static inline bool seq_buf_has_overflowed(struct seq_buf *s) { - return s->len == s->size; + return s->len > s->size; } static inline void seq_buf_set_overflow(struct seq_buf *s) { - s->len = s->size; + s->len = s->size + 1; } /* @@ -61,7 +61,7 @@ seq_buf_buffer_left(struct seq_buf *s) if (seq_buf_has_overflowed(s)) return 0; - return (s->size - 1) - s->len; + return s->size - s->len; } /* How much buffer was written? */ diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index 6fc9d021cbef..c53f1d5088e8 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -26,7 +26,7 @@ */ static bool seq_buf_can_fit(struct seq_buf *s, size_t len) { - return s->len + len < s->size; + return s->len + len <= s->size; } /** @@ -110,8 +110,11 @@ int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, WARN_ON(s->size == 0); /* - * The last byte of the buffer is used to determine if we - * overflowed or not. + * Note, because bitmap_scnprintf() only returns the number of bytes + * written and not the number that would be written, we use the last + * byte of the buffer to let us know if we overflowed. There's a small + * chance that the bitmap could have fit exactly inside the buffer, but + * it's not that critical if that does happen. */ if (len > 1) { ret = bitmap_scnprintf(s->buffer + s->len, len, maskp, nmaskbits); -- GitLab From 01cb06a4c229908d239149017049fdd1fca1dd51 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 29 Oct 2014 17:30:50 -0400 Subject: [PATCH 5446/9457] tracing: Add seq_buf_get_buf() and seq_buf_commit() helper functions Add two helper functions; seq_buf_get_buf() and seq_buf_commit() that are used by seq_buf_path(). This makes the code similar to the seq_file: seq_path() function, and will help to be able to consolidate the functions between seq_file and trace_seq. Link: http://lkml.kernel.org/r/20141104160222.644881406@goodmis.org Link: http://lkml.kernel.org/r/20141114011412.977571447@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 41 +++++++++++++++++++++++++++++++++++++++++ kernel/trace/seq_buf.c | 7 +++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 0800a24b4348..12c64282aa98 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -70,6 +70,47 @@ static inline unsigned int seq_buf_used(struct seq_buf *s) return min(s->len, s->size); } +/** + * seq_buf_get_buf - get buffer to write arbitrary data to + * @s: the seq_buf handle + * @bufp: the beginning of the buffer is stored here + * + * Return the number of bytes available in the buffer, or zero if + * there's no space. + */ +static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp) +{ + WARN_ON(s->len > s->size + 1); + + if (s->len < s->size) { + *bufp = s->buffer + s->len; + return s->size - s->len; + } + + *bufp = NULL; + return 0; +} + +/** + * seq_buf_commit - commit data to the buffer + * @s: the seq_buf handle + * @num: the number of bytes to commit + * + * Commit @num bytes of data written to a buffer previously acquired + * by seq_buf_get. To signal an error condition, or that the data + * didn't fit in the available space, pass a negative @num value. + */ +static inline void seq_buf_commit(struct seq_buf *s, int num) +{ + if (num < 0) { + seq_buf_set_overflow(s); + } else { + /* num must be negative on overflow */ + BUG_ON(s->len + num > s->size); + s->len += num; + } +} + extern __printf(2, 3) int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); extern __printf(2, 0) diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index c53f1d5088e8..086f594ac890 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -293,8 +293,8 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, */ int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc) { - char *buf = s->buffer + s->len; - size_t size = seq_buf_buffer_left(s); + char *buf; + size_t size = seq_buf_get_buf(s, &buf); int res = -1; WARN_ON(s->size == 0); @@ -307,8 +307,7 @@ int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc) res = end - buf; } } - if (res > 0) - s->len += res; + seq_buf_commit(s, res); return res; } -- GitLab From 2448913ed2aa7a7424d9b9ca79861d13c746a3f1 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 3 Nov 2014 18:53:50 -0500 Subject: [PATCH 5447/9457] seq-buf: Make seq_buf_bprintf() conditional on CONFIG_BINARY_PRINTF The function bstr_printf() from lib/vsprnintf.c is only available if CONFIG_BINARY_PRINTF is defined. This is due to the only user currently being the tracing infrastructure, which needs to select this config when tracing is configured. Until there is another user of the binary printf formats, this will continue to be the case. Since seq_buf.c is now lives in lib/ and is compiled even without tracing, it must encompass its use of bstr_printf() which is used by seq_buf_printf(). This too is only used by the tracing infrastructure and is still encapsulated by the CONFIG_BINARY_PRINTF. Link: http://lkml.kernel.org/r/20141104160222.969013383@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/seq_buf.h | 7 +++++-- kernel/trace/seq_buf.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h index 12c64282aa98..9aafe0e24c68 100644 --- a/include/linux/seq_buf.h +++ b/include/linux/seq_buf.h @@ -115,8 +115,6 @@ extern __printf(2, 3) int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); extern __printf(2, 0) int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); -extern int -seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary); extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s); extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt); @@ -130,4 +128,9 @@ extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char * extern int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, int nmaskbits); +#ifdef CONFIG_BINARY_PRINTF +extern int +seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary); +#endif + #endif /* _LINUX_SEQ_BUF_H */ diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c index 086f594ac890..4eedfedb9e31 100644 --- a/kernel/trace/seq_buf.c +++ b/kernel/trace/seq_buf.c @@ -127,6 +127,7 @@ int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, return -1; } +#ifdef CONFIG_BINARY_PRINTF /** * seq_buf_bprintf - Write the printf string from binary arguments * @s: seq_buf descriptor @@ -161,6 +162,7 @@ int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) seq_buf_set_overflow(s); return -1; } +#endif /* CONFIG_BINARY_PRINTF */ /** * seq_buf_puts - sequence printing of simple string -- GitLab From 8d58e99af5980d444948720977b0976455885391 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 19 Jun 2014 17:33:30 -0400 Subject: [PATCH 5448/9457] seq_buf: Move the seq_buf code to lib/ The seq_buf functions are rather useful outside of tracing. Instead of having it be dependent on CONFIG_TRACING, move the code into lib/ and allow other users to have access to it even when tracing is not configured. The seq_buf utility is similar to the seq_file utility, but instead of writing sending data back up to userland, it writes it into a buffer defined at seq_buf_init(). This allows us to send a descriptor around that writes printf() formatted strings into it that can be retrieved later. It is currently used by the tracing facility for such things like trace events to convert its binary saved data in the ring buffer into an ASCII human readable context to be displayed in /sys/kernel/debug/trace. It can also be used for doing NMI prints safely from NMI context into the seq_buf and retrieved later and dumped to printk() safely. Doing printk() from an NMI context is dangerous because an NMI can preempt a current printk() and deadlock on it. Link: http://lkml.kernel.org/p/20140619213952.058255809@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/Makefile | 1 - lib/Makefile | 2 +- {kernel/trace => lib}/seq_buf.c | 0 3 files changed, 1 insertion(+), 2 deletions(-) rename {kernel/trace => lib}/seq_buf.c (100%) diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index edc98c72a634..67d6369ddf83 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o -obj-$(CONFIG_TRACING) += seq_buf.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o diff --git a/lib/Makefile b/lib/Makefile index 7512dc978f18..a1aa1e81ed36 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -13,7 +13,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o flex_proportions.o ratelimit.o show_mem.o \ is_single_threaded.o plist.o decompress.o kobject_uevent.o \ - earlycpio.o + earlycpio.o seq_buf.o obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o lib-$(CONFIG_MMU) += ioremap.o diff --git a/kernel/trace/seq_buf.c b/lib/seq_buf.c similarity index 100% rename from kernel/trace/seq_buf.c rename to lib/seq_buf.c -- GitLab From afdc34a3d3b823a12a93b822ee1efb566f884032 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 19 Jun 2014 17:33:31 -0400 Subject: [PATCH 5449/9457] printk: Add per_cpu printk func to allow printk to be diverted Being able to divert printk to call another function besides the normal logging is useful for such things like NMI handling. If some functions are to be called from NMI that does printk() it is possible to lock up the box if the nmi handler triggers when another printk is happening. One example of this use is to perform a stack trace on all CPUs via NMI. But if the NMI is to do the printk() it can cause the system to lock up. By allowing the printk to be diverted to another function that can safely record the printk output and then print it when it in a safe context then NMIs will be safe to call these functions like show_regs(). Link: http://lkml.kernel.org/p/20140619213952.209176403@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Acked-by: Paul E. McKenney Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- include/linux/percpu.h | 3 +++ include/linux/printk.h | 2 ++ kernel/printk/printk.c | 38 +++++++++++++++++++++++++++++--------- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index a3aa63e47637..ba2e85a0ff5b 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -134,4 +134,7 @@ extern phys_addr_t per_cpu_ptr_to_phys(void *addr); (typeof(type) __percpu *)__alloc_percpu(sizeof(type), \ __alignof__(type)) +/* To avoid include hell, as printk can not declare this, we declare it here */ +DECLARE_PER_CPU(printk_func_t, printk_func); + #endif /* __LINUX_PERCPU_H */ diff --git a/include/linux/printk.h b/include/linux/printk.h index d78125f73ac4..3bbd979d32fb 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -162,6 +162,8 @@ extern int kptr_restrict; extern void wake_up_klogd(void); +typedef int(*printk_func_t)(const char *fmt, va_list args); + void log_buf_kexec_setup(void); void __init setup_log_buf(int early); void dump_stack_set_arch_desc(const char *fmt, ...); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ced2b84b1cb7..f7b723f98cb9 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1807,6 +1807,30 @@ asmlinkage int printk_emit(int facility, int level, } EXPORT_SYMBOL(printk_emit); +int vprintk_default(const char *fmt, va_list args) +{ + int r; + +#ifdef CONFIG_KGDB_KDB + if (unlikely(kdb_trap_printk)) { + r = vkdb_printf(fmt, args); + return r; + } +#endif + r = vprintk_emit(0, -1, NULL, 0, fmt, args); + + return r; +} +EXPORT_SYMBOL_GPL(vprintk_default); + +/* + * This allows printk to be diverted to another function per cpu. + * This is useful for calling printk functions from within NMI + * without worrying about race conditions that can lock up the + * box. + */ +DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default; + /** * printk - print a kernel message * @fmt: format string @@ -1830,19 +1854,15 @@ EXPORT_SYMBOL(printk_emit); */ asmlinkage __visible int printk(const char *fmt, ...) { + printk_func_t vprintk_func; va_list args; int r; -#ifdef CONFIG_KGDB_KDB - if (unlikely(kdb_trap_printk)) { - va_start(args, fmt); - r = vkdb_printf(fmt, args); - va_end(args); - return r; - } -#endif va_start(args, fmt); - r = vprintk_emit(0, -1, NULL, 0, fmt, args); + preempt_disable(); + vprintk_func = this_cpu_read(printk_func); + r = vprintk_func(fmt, args); + preempt_enable(); va_end(args); return r; -- GitLab From a9edc88093287183ac934be44f295f183b2c62dd Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 19 Jun 2014 17:33:32 -0400 Subject: [PATCH 5450/9457] x86/nmi: Perform a safe NMI stack trace on all CPUs When trigger_all_cpu_backtrace() is called on x86, it will trigger an NMI on each CPU and call show_regs(). But this can lead to a hard lock up if the NMI comes in on another printk(). In order to avoid this, when the NMI triggers, it switches the printk routine for that CPU to call a NMI safe printk function that records the printk in a per_cpu seq_buf descriptor. After all NMIs have finished recording its data, the seq_bufs are printed in a safe context. Link: http://lkml.kernel.org/p/20140619213952.360076309@goodmis.org Link: http://lkml.kernel.org/r/20141115050605.055232587@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Acked-by: Paul E. McKenney Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- arch/x86/kernel/apic/hw_nmi.c | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index 6a1e71bde323..c95c3e9ce196 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_HARDLOCKUP_DETECTOR u64 hw_nmi_get_sample_period(int watchdog_thresh) @@ -29,14 +30,35 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh) #ifdef arch_trigger_all_cpu_backtrace /* For reliability, we're prepared to waste bits here. */ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; +static cpumask_var_t printtrace_mask; + +#define NMI_BUF_SIZE 4096 + +struct nmi_seq_buf { + unsigned char buffer[NMI_BUF_SIZE]; + struct seq_buf seq; +}; + +/* Safe printing in NMI context */ +static DEFINE_PER_CPU(struct nmi_seq_buf, nmi_print_seq); /* "in progress" flag of arch_trigger_all_cpu_backtrace */ static unsigned long backtrace_flag; +static void print_seq_line(struct nmi_seq_buf *s, int start, int end) +{ + const char *buf = s->buffer + start; + + printk("%.*s", (end - start) + 1, buf); +} + void arch_trigger_all_cpu_backtrace(bool include_self) { + struct nmi_seq_buf *s; + int len; + int cpu; int i; - int cpu = get_cpu(); + int this_cpu = get_cpu(); if (test_and_set_bit(0, &backtrace_flag)) { /* @@ -49,7 +71,17 @@ void arch_trigger_all_cpu_backtrace(bool include_self) cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); if (!include_self) - cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); + cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); + + cpumask_copy(printtrace_mask, to_cpumask(backtrace_mask)); + /* + * Set up per_cpu seq_buf buffers that the NMIs running on the other + * CPUs will write to. + */ + for_each_cpu(cpu, to_cpumask(backtrace_mask)) { + s = &per_cpu(nmi_print_seq, cpu); + seq_buf_init(&s->seq, s->buffer, NMI_BUF_SIZE); + } if (!cpumask_empty(to_cpumask(backtrace_mask))) { pr_info("sending NMI to %s CPUs:\n", @@ -65,11 +97,58 @@ void arch_trigger_all_cpu_backtrace(bool include_self) touch_softlockup_watchdog(); } + /* + * Now that all the NMIs have triggered, we can dump out their + * back traces safely to the console. + */ + for_each_cpu(cpu, printtrace_mask) { + int last_i = 0; + + s = &per_cpu(nmi_print_seq, cpu); + len = seq_buf_used(&s->seq); + if (!len) + continue; + + /* Print line by line. */ + for (i = 0; i < len; i++) { + if (s->buffer[i] == '\n') { + print_seq_line(s, last_i, i); + last_i = i + 1; + } + } + /* Check if there was a partial line. */ + if (last_i < len) { + print_seq_line(s, last_i, len - 1); + pr_cont("\n"); + } + } + clear_bit(0, &backtrace_flag); smp_mb__after_atomic(); put_cpu(); } +/* + * It is not safe to call printk() directly from NMI handlers. + * It may be fine if the NMI detected a lock up and we have no choice + * but to do so, but doing a NMI on all other CPUs to get a back trace + * can be done with a sysrq-l. We don't want that to lock up, which + * can happen if the NMI interrupts a printk in progress. + * + * Instead, we redirect the vprintk() to this nmi_vprintk() that writes + * the content into a per cpu seq_buf buffer. Then when the NMIs are + * all done, we can safely dump the contents of the seq_buf to a printk() + * from a non NMI context. + */ +static int nmi_vprintk(const char *fmt, va_list args) +{ + struct nmi_seq_buf *s = this_cpu_ptr(&nmi_print_seq); + unsigned int len = seq_buf_used(&s->seq); + + seq_buf_vprintf(&s->seq, fmt, args); + return seq_buf_used(&s->seq) - len; +} + static int arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) { @@ -78,12 +157,14 @@ arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs) cpu = smp_processor_id(); if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { - static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; + printk_func_t printk_func_save = this_cpu_read(printk_func); - arch_spin_lock(&lock); + /* Replace printk to write into the NMI seq */ + this_cpu_write(printk_func, nmi_vprintk); printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); show_regs(regs); - arch_spin_unlock(&lock); + this_cpu_write(printk_func, printk_func_save); + cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); return NMI_HANDLED; } -- GitLab From 6c0299320318c8154a20a3d9e73cbd1fc58d96e1 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 18 Nov 2014 11:16:01 +0800 Subject: [PATCH 5451/9457] f2fs: avoid unable to restart gc thread in remount In f2fs_remount, we will stop gc thread and set need_restart_gc as true when new option is set without BG_GC, then if any error occurred in the following procedure, we can restore to start the gc thread. But after that, We will fail to restore gc thread in start_gc_thread as BG_GC is not set in new option, so we'd better move this condition judgment out of start_gc_thread to fix this issue. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 2 -- fs/f2fs/super.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index b197a2f2993a..657683c9ee48 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -96,8 +96,6 @@ int start_gc_thread(struct f2fs_sb_info *sbi) dev_t dev = sbi->sb->s_bdev->bd_dev; int err = 0; - if (!test_opt(sbi, BG_GC)) - goto out; gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL); if (!gc_th) { err = -ENOMEM; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 512ffd8e1624..536d41401748 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1138,7 +1138,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) * If filesystem is not mounted as read-only then * do start the gc_thread. */ - if (!f2fs_readonly(sb)) { + if (test_opt(sbi, BG_GC) && !f2fs_readonly(sb)) { /* After POR, we can run background GC thread.*/ err = start_gc_thread(sbi); if (err) -- GitLab From aba291b3d8d83941c7ea39487e279ae793b711b3 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 18 Nov 2014 11:17:20 +0800 Subject: [PATCH 5452/9457] f2fs: remove unneeded check code with option in f2fs_remount Because we have checked the contrary condition in case of "if" judgment, we do not need to check the condition again in case of "else" judgment. Let's remove it. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 536d41401748..f71421d70475 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -669,7 +669,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) f2fs_sync_fs(sb, 1); need_restart_gc = true; } - } else if (test_opt(sbi, BG_GC) && !sbi->gc_thread) { + } else if (!sbi->gc_thread) { err = start_gc_thread(sbi); if (err) goto restore_opts; @@ -682,7 +682,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) */ if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { destroy_flush_cmd_control(sbi); - } else if (test_opt(sbi, FLUSH_MERGE) && !SM_I(sbi)->cmd_control_info) { + } else if (!SM_I(sbi)->cmd_control_info) { err = create_flush_cmd_control(sbi); if (err) goto restore_gc; -- GitLab From 67298804f34452a53a9ec9e609d95aa35084132b Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 18 Nov 2014 11:18:36 +0800 Subject: [PATCH 5453/9457] f2fs: introduce struct inode_management to wrap inner fields Now in f2fs, we have three inode cache: ORPHAN_INO, APPEND_INO, UPDATE_INO, and we manage fields related to inode cache separately in struct f2fs_sb_info for each inode cache type. This makes codes a bit messy, so that this patch intorduce a new struct inode_management to wrap inner fields as following which make codes more neat. /* for inner inode cache management */ struct inode_management { struct radix_tree_root ino_root; /* ino entry array */ spinlock_t ino_lock; /* for ino entry lock */ struct list_head ino_list; /* inode list head */ unsigned long ino_num; /* number of entries */ }; struct f2fs_sb_info { ... struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ ... } Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 95 +++++++++++++++++++++++++------------------- fs/f2fs/debug.c | 2 +- fs/f2fs/f2fs.h | 14 ++++--- fs/f2fs/node.c | 4 +- 4 files changed, 66 insertions(+), 49 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index bcd686e0dded..838e8ed3d13a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -298,47 +298,49 @@ const struct address_space_operations f2fs_meta_aops = { static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { + struct inode_management *im = &sbi->im[type]; struct ino_entry *e; retry: - spin_lock(&sbi->ino_lock[type]); + spin_lock(&im->ino_lock); - e = radix_tree_lookup(&sbi->ino_root[type], ino); + e = radix_tree_lookup(&im->ino_root, ino); if (!e) { e = kmem_cache_alloc(ino_entry_slab, GFP_ATOMIC); if (!e) { - spin_unlock(&sbi->ino_lock[type]); + spin_unlock(&im->ino_lock); goto retry; } - if (radix_tree_insert(&sbi->ino_root[type], ino, e)) { - spin_unlock(&sbi->ino_lock[type]); + if (radix_tree_insert(&im->ino_root, ino, e)) { + spin_unlock(&im->ino_lock); kmem_cache_free(ino_entry_slab, e); goto retry; } memset(e, 0, sizeof(struct ino_entry)); e->ino = ino; - list_add_tail(&e->list, &sbi->ino_list[type]); + list_add_tail(&e->list, &im->ino_list); if (type != ORPHAN_INO) - sbi->ino_num[type]++; + im->ino_num++; } - spin_unlock(&sbi->ino_lock[type]); + spin_unlock(&im->ino_lock); } static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) { + struct inode_management *im = &sbi->im[type]; struct ino_entry *e; - spin_lock(&sbi->ino_lock[type]); - e = radix_tree_lookup(&sbi->ino_root[type], ino); + spin_lock(&im->ino_lock); + e = radix_tree_lookup(&im->ino_root, ino); if (e) { list_del(&e->list); - radix_tree_delete(&sbi->ino_root[type], ino); - sbi->ino_num[type]--; - spin_unlock(&sbi->ino_lock[type]); + radix_tree_delete(&im->ino_root, ino); + im->ino_num--; + spin_unlock(&im->ino_lock); kmem_cache_free(ino_entry_slab, e); return; } - spin_unlock(&sbi->ino_lock[type]); + spin_unlock(&im->ino_lock); } void add_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) @@ -356,10 +358,12 @@ void remove_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type) /* mode should be APPEND_INO or UPDATE_INO */ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) { + struct inode_management *im = &sbi->im[mode]; struct ino_entry *e; - spin_lock(&sbi->ino_lock[mode]); - e = radix_tree_lookup(&sbi->ino_root[mode], ino); - spin_unlock(&sbi->ino_lock[mode]); + + spin_lock(&im->ino_lock); + e = radix_tree_lookup(&im->ino_root, ino); + spin_unlock(&im->ino_lock); return e ? true : false; } @@ -369,37 +373,42 @@ void release_dirty_inode(struct f2fs_sb_info *sbi) int i; for (i = APPEND_INO; i <= UPDATE_INO; i++) { - spin_lock(&sbi->ino_lock[i]); - list_for_each_entry_safe(e, tmp, &sbi->ino_list[i], list) { + struct inode_management *im = &sbi->im[i]; + + spin_lock(&im->ino_lock); + list_for_each_entry_safe(e, tmp, &im->ino_list, list) { list_del(&e->list); - radix_tree_delete(&sbi->ino_root[i], e->ino); + radix_tree_delete(&im->ino_root, e->ino); kmem_cache_free(ino_entry_slab, e); - sbi->ino_num[i]--; + im->ino_num--; } - spin_unlock(&sbi->ino_lock[i]); + spin_unlock(&im->ino_lock); } } int acquire_orphan_inode(struct f2fs_sb_info *sbi) { + struct inode_management *im = &sbi->im[ORPHAN_INO]; int err = 0; - spin_lock(&sbi->ino_lock[ORPHAN_INO]); - if (unlikely(sbi->ino_num[ORPHAN_INO] >= sbi->max_orphans)) + spin_lock(&im->ino_lock); + if (unlikely(im->ino_num >= sbi->max_orphans)) err = -ENOSPC; else - sbi->ino_num[ORPHAN_INO]++; - spin_unlock(&sbi->ino_lock[ORPHAN_INO]); + im->ino_num++; + spin_unlock(&im->ino_lock); return err; } void release_orphan_inode(struct f2fs_sb_info *sbi) { - spin_lock(&sbi->ino_lock[ORPHAN_INO]); - f2fs_bug_on(sbi, sbi->ino_num[ORPHAN_INO] == 0); - sbi->ino_num[ORPHAN_INO]--; - spin_unlock(&sbi->ino_lock[ORPHAN_INO]); + struct inode_management *im = &sbi->im[ORPHAN_INO]; + + spin_lock(&im->ino_lock); + f2fs_bug_on(sbi, im->ino_num == 0); + im->ino_num--; + spin_unlock(&im->ino_lock); } void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) @@ -465,15 +474,16 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) unsigned short orphan_blocks; struct page *page = NULL; struct ino_entry *orphan = NULL; + struct inode_management *im = &sbi->im[ORPHAN_INO]; - orphan_blocks = GET_ORPHAN_BLOCKS(sbi->ino_num[ORPHAN_INO]); + orphan_blocks = GET_ORPHAN_BLOCKS(im->ino_num); for (index = 0; index < orphan_blocks; index++) grab_meta_page(sbi, start_blk + index); index = 1; - spin_lock(&sbi->ino_lock[ORPHAN_INO]); - head = &sbi->ino_list[ORPHAN_INO]; + spin_lock(&im->ino_lock); + head = &im->ino_list; /* loop for each orphan inode entry and write them in Jornal block */ list_for_each_entry(orphan, head, list) { @@ -513,7 +523,7 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) f2fs_put_page(page, 1); } - spin_unlock(&sbi->ino_lock[ORPHAN_INO]); + spin_unlock(&im->ino_lock); } static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, @@ -836,6 +846,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); struct f2fs_nm_info *nm_i = NM_I(sbi); + unsigned long orphan_num = sbi->im[ORPHAN_INO].ino_num; nid_t last_nid = nm_i->next_scan_nid; block_t start_blk; struct page *cp_page; @@ -895,7 +906,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) else clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); - orphan_blocks = GET_ORPHAN_BLOCKS(sbi->ino_num[ORPHAN_INO]); + orphan_blocks = GET_ORPHAN_BLOCKS(orphan_num); ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + orphan_blocks); @@ -911,7 +922,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) orphan_blocks); } - if (sbi->ino_num[ORPHAN_INO]) + if (orphan_num) set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); else clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); @@ -946,7 +957,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_put_page(cp_page, 1); } - if (sbi->ino_num[ORPHAN_INO]) { + if (orphan_num) { write_orphan_inodes(sbi, start_blk); start_blk += orphan_blocks; } @@ -1045,10 +1056,12 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi) int i; for (i = 0; i < MAX_INO_ENTRY; i++) { - INIT_RADIX_TREE(&sbi->ino_root[i], GFP_ATOMIC); - spin_lock_init(&sbi->ino_lock[i]); - INIT_LIST_HEAD(&sbi->ino_list[i]); - sbi->ino_num[i] = 0; + struct inode_management *im = &sbi->im[i]; + + INIT_RADIX_TREE(&im->ino_root, GFP_ATOMIC); + spin_lock_init(&im->ino_lock); + INIT_LIST_HEAD(&im->ino_list); + im->ino_num = 0; } /* diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 74a0d78dbd3e..40b679ce35d9 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -171,7 +171,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->cache_mem += npages << PAGE_CACHE_SHIFT; si->cache_mem += sbi->n_dirty_dirs * sizeof(struct dir_inode_entry); for (i = 0; i <= UPDATE_INO; i++) - si->cache_mem += sbi->ino_num[i] * sizeof(struct ino_entry); + si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry); } static int stat_show(struct seq_file *s, void *v) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 994b87eb7a7d..418c8524a164 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -499,6 +499,14 @@ struct f2fs_bio_info { struct rw_semaphore io_rwsem; /* blocking op for bio */ }; +/* for inner inode cache management */ +struct inode_management { + struct radix_tree_root ino_root; /* ino entry array */ + spinlock_t ino_lock; /* for ino entry lock */ + struct list_head ino_list; /* inode list head */ + unsigned long ino_num; /* number of entries */ +}; + struct f2fs_sb_info { struct super_block *sb; /* pointer to VFS super block */ struct proc_dir_entry *s_proc; /* proc entry */ @@ -528,11 +536,7 @@ struct f2fs_sb_info { bool por_doing; /* recovery is doing or not */ wait_queue_head_t cp_wait; - /* for inode management */ - struct radix_tree_root ino_root[MAX_INO_ENTRY]; /* ino entry array */ - spinlock_t ino_lock[MAX_INO_ENTRY]; /* for ino entry lock */ - struct list_head ino_list[MAX_INO_ENTRY]; /* inode list head */ - unsigned long ino_num[MAX_INO_ENTRY]; /* number of entries */ + struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ /* for orphan inode, use 0'th array */ unsigned int max_orphans; /* max orphan inodes */ diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 6f514fb5fd96..478ce1eacd54 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -60,8 +60,8 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) if (sbi->sb->s_bdi->dirty_exceeded) return false; for (i = 0; i <= UPDATE_INO; i++) - mem_size += (sbi->ino_num[i] * sizeof(struct ino_entry)) - >> PAGE_CACHE_SHIFT; + mem_size += (sbi->im[i].ino_num * + sizeof(struct ino_entry)) >> PAGE_CACHE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); } return res; -- GitLab From 27c6bd60ac9bf8114f6bb41eda6addc16a6b76a9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 19 Nov 2014 10:54:48 -0800 Subject: [PATCH 5454/9457] f2fs: submit bio for node blocks in the reclaim path If a node page is request to be written during the reclaiming path, we should submit the bio to avoid pending to recliam it. Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 478ce1eacd54..dbf49cc80297 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1326,6 +1326,10 @@ static int f2fs_write_node_page(struct page *page, dec_page_count(sbi, F2FS_DIRTY_NODES); up_read(&sbi->node_write); unlock_page(page); + + if (wbc->for_reclaim) + f2fs_submit_merged_bio(sbi, NODE, WRITE); + return 0; redirty_out: -- GitLab From 857dc4e0598e2a95b1cbb8d17c8538b34cc9a2f3 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 19 Nov 2014 11:03:34 -0800 Subject: [PATCH 5455/9457] f2fs: write SSA pages under memory pressure Under memory pressure, we don't need to skip SSA page writes. Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 838e8ed3d13a..20a917b05b99 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -178,7 +178,7 @@ static int f2fs_write_meta_page(struct page *page, if (unlikely(sbi->por_doing)) goto redirty_out; - if (wbc->for_reclaim) + if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0)) goto redirty_out; if (unlikely(f2fs_cp_error(sbi))) goto redirty_out; @@ -187,6 +187,9 @@ static int f2fs_write_meta_page(struct page *page, write_meta_page(sbi, page); dec_page_count(sbi, F2FS_DIRTY_META); unlock_page(page); + + if (wbc->for_reclaim) + f2fs_submit_merged_bio(sbi, META, WRITE); return 0; redirty_out: -- GitLab From 5a66088bffd9a5251e96ca5d0d46456ab9196287 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 21 Oct 2014 16:53:27 +0300 Subject: [PATCH 5456/9457] mtd: mtd_oobtest: Show the verification error location and data Add a function memcmpshow() that compares the 2 data buffers and shows the address:offset and data bytes on comparison failure. This function does not break at a comparison failure but runs the check for the whole data buffer. Use memcmpshow() instead of memcmp() for all the verification paths. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Signed-off-by: Brian Norris --- drivers/mtd/tests/oobtest.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index dc4f9602b97e..edd859d96d85 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -115,6 +115,26 @@ static int write_whole_device(void) return 0; } +/* Display the address, offset and data bytes at comparison failure */ +static int memcmpshow(loff_t addr, const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + int res; + int ret = 0; + size_t i = 0; + + for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) { + res = *su1 ^ *su2; + if (res) { + pr_info("error @addr[0x%lx:0x%x] 0x%x -> 0x%x diff 0x%x\n", + (unsigned long)addr, i, *su1, *su2, res); + ret = 1; + } + } + + return ret; +} + static int verify_eraseblock(int ebnum) { int i; @@ -139,8 +159,9 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf, writebuf + (use_len_max * i) + use_offset, - use_len)) { + if (memcmpshow(addr, readbuf, + writebuf + (use_len_max * i) + use_offset, + use_len)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -167,9 +188,9 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf + use_offset, - writebuf + (use_len_max * i) + use_offset, - use_len)) { + if (memcmpshow(addr, readbuf + use_offset, + writebuf + (use_len_max * i) + use_offset, + use_len)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -233,7 +254,7 @@ static int verify_eraseblock_in_one_go(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmp(readbuf, writebuf, len)) { + if (memcmpshow(addr, readbuf, writebuf, len)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -610,7 +631,8 @@ static int __init mtd_oobtest_init(void) err = mtd_read_oob(mtd, addr, &ops); if (err) goto out; - if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { + if (memcmpshow(addr, readbuf, writebuf, + mtd->ecclayout->oobavail * 2)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; -- GitLab From afc0ea1b8e1e27b2cb77e7023d917f3aa5971d17 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 21 Oct 2014 16:53:28 +0300 Subject: [PATCH 5457/9457] mtd: mtd_oobtest: add bitflip_limit parameter It is common for NAND devices to have bitflip errors. Add a bitflip_limit parameter to specify how many bitflips per page we can tolerate without flagging an error. By default zero bitflips are tolerated. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Signed-off-by: Brian Norris --- drivers/mtd/tests/oobtest.c | 65 +++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index edd859d96d85..1fd2cdad85f0 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -34,8 +34,11 @@ #include "mtd_test.h" static int dev = -EINVAL; +static int bitflip_limit; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); +module_param(bitflip_limit, int, S_IRUGO); +MODULE_PARM_DESC(bitflip_limit, "Max. allowed bitflips per page"); static struct mtd_info *mtd; static unsigned char *readbuf; @@ -115,24 +118,27 @@ static int write_whole_device(void) return 0; } -/* Display the address, offset and data bytes at comparison failure */ -static int memcmpshow(loff_t addr, const void *cs, const void *ct, size_t count) +/* + * Display the address, offset and data bytes at comparison failure. + * Return number of bitflips encountered. + */ +static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t count) { const unsigned char *su1, *su2; int res; - int ret = 0; size_t i = 0; + size_t bitflips = 0; for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) { res = *su1 ^ *su2; if (res) { pr_info("error @addr[0x%lx:0x%x] 0x%x -> 0x%x diff 0x%x\n", (unsigned long)addr, i, *su1, *su2, res); - ret = 1; + bitflips += hweight8(res); } } - return ret; + return bitflips; } static int verify_eraseblock(int ebnum) @@ -141,6 +147,7 @@ static int verify_eraseblock(int ebnum) struct mtd_oob_ops ops; int err = 0; loff_t addr = (loff_t)ebnum * mtd->erasesize; + size_t bitflips; prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { @@ -159,9 +166,11 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmpshow(addr, readbuf, - writebuf + (use_len_max * i) + use_offset, - use_len)) { + + bitflips = memcmpshow(addr, readbuf, + writebuf + (use_len_max * i) + use_offset, + use_len); + if (bitflips > bitflip_limit) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -169,7 +178,10 @@ static int verify_eraseblock(int ebnum) pr_err("error: too many errors\n"); return -1; } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } + if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) { int k; @@ -188,9 +200,10 @@ static int verify_eraseblock(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmpshow(addr, readbuf + use_offset, - writebuf + (use_len_max * i) + use_offset, - use_len)) { + bitflips = memcmpshow(addr, readbuf + use_offset, + writebuf + (use_len_max * i) + use_offset, + use_len); + if (bitflips > bitflip_limit) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; @@ -198,7 +211,10 @@ static int verify_eraseblock(int ebnum) pr_err("error: too many errors\n"); return -1; } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } + for (k = 0; k < use_offset; ++k) if (readbuf[k] != 0xff) { pr_err("error: verify 0xff " @@ -237,6 +253,9 @@ static int verify_eraseblock_in_one_go(int ebnum) int err = 0; loff_t addr = (loff_t)ebnum * mtd->erasesize; size_t len = mtd->ecclayout->oobavail * pgcnt; + size_t oobavail = mtd->ecclayout->oobavail; + size_t bitflips; + int i; prandom_bytes_state(&rnd_state, writebuf, len); ops.mode = MTD_OPS_AUTO_OOB; @@ -247,6 +266,8 @@ static int verify_eraseblock_in_one_go(int ebnum) ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; + + /* read entire block's OOB at one go */ err = mtd_read_oob(mtd, addr, &ops); if (err || ops.oobretlen != len) { pr_err("error: readoob failed at %#llx\n", @@ -254,13 +275,21 @@ static int verify_eraseblock_in_one_go(int ebnum) errcnt += 1; return err ? err : -1; } - if (memcmpshow(addr, readbuf, writebuf, len)) { - pr_err("error: verify failed at %#llx\n", - (long long)addr); - errcnt += 1; - if (errcnt > 1000) { - pr_err("error: too many errors\n"); - return -1; + + /* verify one page OOB at a time for bitflip per page limit check */ + for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { + bitflips = memcmpshow(addr, readbuf + (i * oobavail), + writebuf + (i * oobavail), oobavail); + if (bitflips > bitflip_limit) { + pr_err("error: verify failed at %#llx\n", + (long long)addr); + errcnt += 1; + if (errcnt > 1000) { + pr_err("error: too many errors\n"); + return -1; + } + } else if (bitflips) { + pr_info("ignoring error as within bitflip_limit\n"); } } -- GitLab From 62d956dc3e11138c5ffd4b2c62e4f909c5180a12 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 20 Oct 2014 10:46:14 +0200 Subject: [PATCH 5458/9457] mtd: nand: provide detailed description for raw read/write page methods read_page_raw and write_page_raw method description is not clear enough. It clearly specifies that ECC correction should not be involved but does not talk about specific layout (by layout I mean where in-band and out-of-band data are stored on the NAND media) used by NAND/ECC controllers. Those specific layouts might impact MTD users and thus should be hidden (as already done in the standard NAND_ECC_HW_SYNDROME implementation). Clearly state this constraint in the nand_ecc_ctrl struct documentation. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index e4d451e4600b..b14d190b593a 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -455,8 +455,21 @@ struct nand_hw_control { * be provided if an hardware ECC is available * @calculate: function for ECC calculation or readback from ECC hardware * @correct: function for ECC correction, matching to ECC generator (sw/hw) - * @read_page_raw: function to read a raw page without ECC - * @write_page_raw: function to write a raw page without ECC + * @read_page_raw: function to read a raw page without ECC. This function + * should hide the specific layout used by the ECC + * controller and always return contiguous in-band and + * out-of-band data even if they're not stored + * contiguously on the NAND chip (e.g. + * NAND_ECC_HW_SYNDROME interleaves in-band and + * out-of-band data). + * @write_page_raw: function to write a raw page without ECC. This function + * should hide the specific layout used by the ECC + * controller and consider the passed data as contiguous + * in-band and out-of-band data. ECC controller is + * responsible for doing the appropriate transformations + * to adapt to its specific layout (e.g. + * NAND_ECC_HW_SYNDROME interleaves in-band and + * out-of-band data). * @read_page: function to read a page according to the ECC generator * requirements; returns maximum number of bitflips corrected in * any single ECC step, 0 if bitflips uncorrectable, -EIO hw error -- GitLab From fbe68ee87522f6eaa10f9076c0a7117e1613f2f7 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Thu, 20 Nov 2014 10:01:49 +0100 Subject: [PATCH 5459/9457] vti6: Add a lookup method for tunnels with wildcard endpoints. Currently we can't lookup tunnels with wildcard endpoints. This patch adds a method to lookup these tunnels in the receive path. Signed-off-by: Steffen Klassert --- net/ipv6/ip6_vti.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index d440bb585524..61019199c84b 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -95,6 +95,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, unsigned int hash = HASH(remote, local); struct ip6_tnl *t; struct vti6_net *ip6n = net_generic(net, vti6_net_id); + struct in6_addr any; for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { if (ipv6_addr_equal(local, &t->parms.laddr) && @@ -102,6 +103,22 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote, (t->dev->flags & IFF_UP)) return t; } + + memset(&any, 0, sizeof(any)); + hash = HASH(&any, local); + for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { + if (ipv6_addr_equal(local, &t->parms.laddr) && + (t->dev->flags & IFF_UP)) + return t; + } + + hash = HASH(remote, &any); + for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) { + if (ipv6_addr_equal(remote, &t->parms.raddr) && + (t->dev->flags & IFF_UP)) + return t; + } + t = rcu_dereference(ip6n->tnls_wc[0]); if (t && (t->dev->flags & IFF_UP)) return t; -- GitLab From 806b6ef5676a1c6ea78592174aae15f59bb0a923 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 20 Nov 2014 01:26:51 -0800 Subject: [PATCH 5460/9457] mtd: oobtest: correct printf() format specifier for 'size_t' Fixes warning: drivers/mtd/tests/oobtest.c: In function 'memcmpshow': drivers/mtd/tests/oobtest.c:129: warning: format '%x' expects type 'unsigned int', but argument 3 has type 'size_t' Signed-off-by: Brian Norris Cc: Roger Quadros Cc: Sekhar Nori --- drivers/mtd/tests/oobtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index 1fd2cdad85f0..5e061186eab1 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -132,7 +132,7 @@ static size_t memcmpshow(loff_t addr, const void *cs, const void *ct, size_t cou for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) { res = *su1 ^ *su2; if (res) { - pr_info("error @addr[0x%lx:0x%x] 0x%x -> 0x%x diff 0x%x\n", + pr_info("error @addr[0x%lx:0x%zx] 0x%x -> 0x%x diff 0x%x\n", (unsigned long)addr, i, *su1, *su2, res); bitflips += hweight8(res); } -- GitLab From 50c0f21b42dd4cd02b51f82274f66912d9a7fa32 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Nov 2014 18:29:02 +0100 Subject: [PATCH 5461/9457] ASoC: sigmadsp: Refuse to load firmware files with a non-supported version Make sure to check the version field of the firmware header to make sure to not accidentally try to parse a firmware file with a different layout. Trying to do so can result in loading invalid firmware code to the device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/sigmadsp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index f2de7e049bc6..81a38dd9af1f 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -159,6 +159,13 @@ int _process_sigma_firmware(struct device *dev, goto done; } + if (ssfw_head->version != 1) { + dev_err(dev, + "Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n", + ssfw_head->version); + goto done; + } + crc = crc32(0, fw->data + sizeof(*ssfw_head), fw->size - sizeof(*ssfw_head)); pr_debug("%s: crc=%x\n", __func__, crc); -- GitLab From 6b25730f68073ee95079d241ea6aa7be00805254 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Nov 2014 18:29:04 +0100 Subject: [PATCH 5462/9457] ASoC: sigmadsp: Drop support support SIGMA_ACTION_DELAY The official firmware generation tool never emitted any SIGMA_ACTION_DELAY instructions. Keeping support for it with the new restructured loader that also supports v2 will be difficult, so drop support for it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sigmadsp.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 81a38dd9af1f..4fd31434276b 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -28,9 +27,6 @@ enum { SIGMA_ACTION_WRITEXBYTES = 0, SIGMA_ACTION_WRITESINGLE, SIGMA_ACTION_WRITESAFELOAD, - SIGMA_ACTION_DELAY, - SIGMA_ACTION_PLLWAIT, - SIGMA_ACTION_NOOP, SIGMA_ACTION_END, }; @@ -79,10 +75,6 @@ process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa) if (ret < 0) return -EINVAL; break; - case SIGMA_ACTION_DELAY: - udelay(len); - len = 0; - break; case SIGMA_ACTION_END: return 0; default: -- GitLab From d48b088e3ec45eeccf0fce0b75378e41428f47e9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Nov 2014 18:29:05 +0100 Subject: [PATCH 5463/9457] ASoC: sigmadsp: Restructure in preparation for fw v2 support The v2 file format of the SigmaDSP takes a more declarative style compared to the imperative style of the v1 format. In addition some features that are supported with v2 require the driver to keep state around for the firmware. This requires a bit of restructuring of both the firmware loader itself and the drivers making use of the firmware loader. Instead of loading and executing the firmware in place when the DSP is configured the firmware is now loaded at driver probe time. This is required since the new firmware format will in addition to the firmware data itself contain meta information describing the firmware and its requirements and capabilities. Those will for example be used to restrict the supported samplerates advertised by the driver to userspace to the list of samplerates supported for the firmware. This only does the restructuring required by the v2 format, but does not yet add support for the new format itself. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1701.c | 33 +++- sound/soc/codecs/adau1761.c | 21 ++- sound/soc/codecs/adau1781.c | 30 ++-- sound/soc/codecs/adau17x1.c | 54 +++++- sound/soc/codecs/adau17x1.h | 9 +- sound/soc/codecs/sigmadsp-i2c.c | 52 ++++-- sound/soc/codecs/sigmadsp-regmap.c | 38 +++-- sound/soc/codecs/sigmadsp.c | 255 ++++++++++++++++++++++++----- sound/soc/codecs/sigmadsp.h | 53 ++++-- 9 files changed, 424 insertions(+), 121 deletions(-) diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 370b742117ef..05d5eb5984b6 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -103,6 +103,8 @@ struct adau1701 { unsigned int sysclk; struct regmap *regmap; u8 pin_config[12]; + + struct sigmadsp *sigmadsp; }; static const struct snd_kcontrol_new adau1701_controls[] = { @@ -238,12 +240,14 @@ static int adau1701_reg_read(void *context, unsigned int reg, return 0; } -static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) +static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv, + unsigned int rate) { struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *client = to_i2c_client(codec->dev); int ret; + sigmadsp_reset(adau1701->sigmadsp); + if (clkdiv != ADAU1707_CLKDIV_UNSET && gpio_is_valid(adau1701->gpio_pll_mode[0]) && gpio_is_valid(adau1701->gpio_pll_mode[1])) { @@ -284,7 +288,7 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) * know the correct PLL setup */ if (clkdiv != ADAU1707_CLKDIV_UNSET) { - ret = process_sigma_firmware(client, ADAU1701_FIRMWARE); + ret = sigmadsp_setup(adau1701->sigmadsp, rate); if (ret) { dev_warn(codec->dev, "Failed to load firmware\n"); return ret; @@ -385,7 +389,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, * firmware upload. */ if (clkdiv != adau1701->pll_clkdiv) { - ret = adau1701_reset(codec, clkdiv); + ret = adau1701_reset(codec, clkdiv, params_rate(params)); if (ret < 0) return ret; } @@ -554,6 +558,14 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, return 0; } +static int adau1701_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(dai->codec); + + return sigmadsp_restrict_params(adau1701->sigmadsp, substream); +} + #define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \ SNDRV_PCM_RATE_192000) @@ -564,6 +576,7 @@ static const struct snd_soc_dai_ops adau1701_dai_ops = { .set_fmt = adau1701_set_dai_fmt, .hw_params = adau1701_hw_params, .digital_mute = adau1701_digital_mute, + .startup = adau1701_startup, }; static struct snd_soc_dai_driver adau1701_dai = { @@ -600,6 +613,10 @@ static int adau1701_probe(struct snd_soc_codec *codec) unsigned int val; struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + ret = sigmadsp_attach(adau1701->sigmadsp, &codec->component); + if (ret) + return ret; + /* * Let the pll_clkdiv variable default to something that won't happen * at runtime. That way, we can postpone the firmware download from @@ -609,7 +626,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET; /* initalize with pre-configured pll mode settings */ - ret = adau1701_reset(codec, adau1701->pll_clkdiv); + ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0); if (ret < 0) return ret; @@ -722,6 +739,12 @@ static int adau1701_i2c_probe(struct i2c_client *client, adau1701->gpio_pll_mode[1] = gpio_pll_mode[1]; i2c_set_clientdata(client, adau1701); + + adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, NULL, + ADAU1701_FIRMWARE); + if (IS_ERR(adau1701->sigmadsp)) + return PTR_ERR(adau1701->sigmadsp); + ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, &adau1701_dai, 1); return ret; diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 5518ebd6947c..0ae1501f3c11 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -698,11 +698,6 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec) ARRAY_SIZE(adau1761_dapm_routes)); if (ret) return ret; - - ret = adau17x1_load_firmware(adau, codec->dev, - ADAU1761_FIRMWARE); - if (ret) - dev_warn(codec->dev, "Failed to firmware\n"); } ret = adau17x1_add_routes(codec); @@ -771,16 +766,20 @@ int adau1761_probe(struct device *dev, struct regmap *regmap, enum adau17x1_type type, void (*switch_mode)(struct device *dev)) { struct snd_soc_dai_driver *dai_drv; + const char *firmware_name; int ret; - ret = adau17x1_probe(dev, regmap, type, switch_mode); - if (ret) - return ret; - - if (type == ADAU1361) + if (type == ADAU1361) { dai_drv = &adau1361_dai_driver; - else + firmware_name = NULL; + } else { dai_drv = &adau1761_dai_driver; + firmware_name = ADAU1761_FIRMWARE; + } + + ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name); + if (ret) + return ret; return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1); } diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index e9fc00fb13dd..4c8ddc3c69e1 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -385,7 +385,6 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec) { struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev); struct adau *adau = snd_soc_codec_get_drvdata(codec); - const char *firmware; int ret; ret = adau17x1_add_widgets(codec); @@ -422,25 +421,10 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec) return ret; } - switch (adau->type) { - case ADAU1381: - firmware = ADAU1381_FIRMWARE; - break; - case ADAU1781: - firmware = ADAU1781_FIRMWARE; - break; - default: - return -EINVAL; - } - ret = adau17x1_add_routes(codec); if (ret < 0) return ret; - ret = adau17x1_load_firmware(adau, codec->dev, firmware); - if (ret) - dev_warn(codec->dev, "Failed to load firmware\n"); - return 0; } @@ -495,9 +479,21 @@ EXPORT_SYMBOL_GPL(adau1781_regmap_config); int adau1781_probe(struct device *dev, struct regmap *regmap, enum adau17x1_type type, void (*switch_mode)(struct device *dev)) { + const char *firmware_name; int ret; - ret = adau17x1_probe(dev, regmap, type, switch_mode); + switch (type) { + case ADAU1381: + firmware_name = ADAU1381_FIRMWARE; + break; + case ADAU1781: + firmware_name = ADAU1781_FIRMWARE; + break; + default: + return -EINVAL; + } + + ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name); if (ret) return ret; diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 3e16c1c64115..1cab34c57413 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -307,6 +307,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, struct adau *adau = snd_soc_codec_get_drvdata(codec); unsigned int val, div, dsp_div; unsigned int freq; + int ret; if (adau->clk_src == ADAU17X1_CLK_SRC_PLL) freq = adau->pll_freq; @@ -356,6 +357,12 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div); } + if (adau->sigmadsp) { + ret = adau17x1_setup_firmware(adau, params_rate(params)); + if (ret < 0) + return ret; + } + if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J) return 0; @@ -661,12 +668,24 @@ static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai, return 0; } +static int adau17x1_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); + + if (adau->sigmadsp) + return sigmadsp_restrict_params(adau->sigmadsp, substream); + + return 0; +} + const struct snd_soc_dai_ops adau17x1_dai_ops = { .hw_params = adau17x1_hw_params, .set_sysclk = adau17x1_set_dai_sysclk, .set_fmt = adau17x1_set_dai_fmt, .set_pll = adau17x1_set_dai_pll, .set_tdm_slot = adau17x1_set_dai_tdm_slot, + .startup = adau17x1_startup, }; EXPORT_SYMBOL_GPL(adau17x1_dai_ops); @@ -745,8 +764,7 @@ bool adau17x1_volatile_register(struct device *dev, unsigned int reg) } EXPORT_SYMBOL_GPL(adau17x1_volatile_register); -int adau17x1_load_firmware(struct adau *adau, struct device *dev, - const char *firmware) +int adau17x1_setup_firmware(struct adau *adau, unsigned int rate) { int ret; int dspsr; @@ -758,7 +776,7 @@ int adau17x1_load_firmware(struct adau *adau, struct device *dev, regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); - ret = process_sigma_firmware_regmap(dev, adau->regmap, firmware); + ret = sigmadsp_setup(adau->sigmadsp, rate); if (ret) { regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); return ret; @@ -767,7 +785,7 @@ int adau17x1_load_firmware(struct adau *adau, struct device *dev, return 0; } -EXPORT_SYMBOL_GPL(adau17x1_load_firmware); +EXPORT_SYMBOL_GPL(adau17x1_setup_firmware); int adau17x1_add_widgets(struct snd_soc_codec *codec) { @@ -787,8 +805,21 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec) ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dsp_dapm_widgets, ARRAY_SIZE(adau17x1_dsp_dapm_widgets)); + if (ret) + return ret; + + if (!adau->sigmadsp) + return 0; + + ret = sigmadsp_attach(adau->sigmadsp, &codec->component); + if (ret) { + dev_err(codec->dev, "Failed to attach firmware: %d\n", + ret); + return ret; + } } - return ret; + + return 0; } EXPORT_SYMBOL_GPL(adau17x1_add_widgets); @@ -829,7 +860,8 @@ int adau17x1_resume(struct snd_soc_codec *codec) EXPORT_SYMBOL_GPL(adau17x1_resume); int adau17x1_probe(struct device *dev, struct regmap *regmap, - enum adau17x1_type type, void (*switch_mode)(struct device *dev)) + enum adau17x1_type type, void (*switch_mode)(struct device *dev), + const char *firmware_name) { struct adau *adau; @@ -846,6 +878,16 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap, dev_set_drvdata(dev, adau); + if (firmware_name) { + adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap, NULL, + firmware_name); + if (IS_ERR(adau->sigmadsp)) { + dev_warn(dev, "Could not find firmware file: %ld\n", + PTR_ERR(adau->sigmadsp)); + adau->sigmadsp = NULL; + } + } + if (switch_mode) switch_mode(dev); diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index e4a557fd7155..6861aa3aec02 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -4,6 +4,8 @@ #include #include +#include "sigmadsp.h" + enum adau17x1_type { ADAU1361, ADAU1761, @@ -42,12 +44,14 @@ struct adau { bool dsp_bypass[2]; struct regmap *regmap; + struct sigmadsp *sigmadsp; }; int adau17x1_add_widgets(struct snd_soc_codec *codec); int adau17x1_add_routes(struct snd_soc_codec *codec); int adau17x1_probe(struct device *dev, struct regmap *regmap, - enum adau17x1_type type, void (*switch_mode)(struct device *dev)); + enum adau17x1_type type, void (*switch_mode)(struct device *dev), + const char *firmware_name); int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, enum adau17x1_micbias_voltage micbias); bool adau17x1_readable_register(struct device *dev, unsigned int reg); @@ -56,8 +60,7 @@ int adau17x1_resume(struct snd_soc_codec *codec); extern const struct snd_soc_dai_ops adau17x1_dai_ops; -int adau17x1_load_firmware(struct adau *adau, struct device *dev, - const char *firmware); +int adau17x1_setup_firmware(struct adau *adau, unsigned int rate); bool adau17x1_has_dsp(struct adau *adau); #define ADAU17X1_CLOCK_CONTROL 0x4000 diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c index 246081aae8ca..bf6a2be72692 100644 --- a/sound/soc/codecs/sigmadsp-i2c.c +++ b/sound/soc/codecs/sigmadsp-i2c.c @@ -6,29 +6,59 @@ * Licensed under the GPL-2 or later. */ -#include #include +#include #include +#include +#include #include "sigmadsp.h" -static int sigma_action_write_i2c(void *control_data, - const struct sigma_action *sa, size_t len) +static int sigmadsp_write_i2c(void *control_data, + unsigned int addr, const uint8_t data[], size_t len) { - return i2c_master_send(control_data, (const unsigned char *)&sa->addr, - len); + uint8_t *buf; + int ret; + + buf = kzalloc(2 + len, GFP_KERNEL | GFP_DMA); + if (!buf) + return -ENOMEM; + + put_unaligned_be16(addr, buf); + memcpy(buf + 2, data, len); + + ret = i2c_master_send(control_data, buf, len + 2); + + kfree(buf); + + return ret; } -int process_sigma_firmware(struct i2c_client *client, const char *name) +/** + * devm_sigmadsp_init_i2c() - Initialize SigmaDSP instance + * @client: The parent I2C device + * @ops: The sigmadsp_ops to use for this instance + * @firmware_name: Name of the firmware file to load + * + * Allocates a SigmaDSP instance and loads the specified firmware file. + * + * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error. + */ +struct sigmadsp *devm_sigmadsp_init_i2c(struct i2c_client *client, + const struct sigmadsp_ops *ops, const char *firmware_name) { - struct sigma_firmware ssfw; + struct sigmadsp *sigmadsp; + + sigmadsp = devm_sigmadsp_init(&client->dev, ops, firmware_name); + if (IS_ERR(sigmadsp)) + return sigmadsp; - ssfw.control_data = client; - ssfw.write = sigma_action_write_i2c; + sigmadsp->control_data = client; + sigmadsp->write = sigmadsp_write_i2c; - return _process_sigma_firmware(&client->dev, &ssfw, name); + return sigmadsp; } -EXPORT_SYMBOL(process_sigma_firmware); +EXPORT_SYMBOL_GPL(devm_sigmadsp_init_i2c); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("SigmaDSP I2C firmware loader"); diff --git a/sound/soc/codecs/sigmadsp-regmap.c b/sound/soc/codecs/sigmadsp-regmap.c index f78ed8d2cfb2..cdc5dda47b88 100644 --- a/sound/soc/codecs/sigmadsp-regmap.c +++ b/sound/soc/codecs/sigmadsp-regmap.c @@ -12,24 +12,40 @@ #include "sigmadsp.h" -static int sigma_action_write_regmap(void *control_data, - const struct sigma_action *sa, size_t len) +static int sigmadsp_write_regmap(void *control_data, + unsigned int addr, const uint8_t data[], size_t len) { - return regmap_raw_write(control_data, be16_to_cpu(sa->addr), - sa->payload, len - 2); + return regmap_raw_write(control_data, addr, + data, len); } -int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, - const char *name) +/** + * devm_sigmadsp_init_i2c() - Initialize SigmaDSP instance + * @dev: The parent device + * @regmap: Regmap instance to use + * @ops: The sigmadsp_ops to use for this instance + * @firmware_name: Name of the firmware file to load + * + * Allocates a SigmaDSP instance and loads the specified firmware file. + * + * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error. + */ +struct sigmadsp *devm_sigmadsp_init_regmap(struct device *dev, + struct regmap *regmap, const struct sigmadsp_ops *ops, + const char *firmware_name) { - struct sigma_firmware ssfw; + struct sigmadsp *sigmadsp; + + sigmadsp = devm_sigmadsp_init(dev, ops, firmware_name); + if (IS_ERR(sigmadsp)) + return sigmadsp; - ssfw.control_data = regmap; - ssfw.write = sigma_action_write_regmap; + sigmadsp->control_data = regmap; + sigmadsp->write = sigmadsp_write_regmap; - return _process_sigma_firmware(dev, &ssfw, name); + return sigmadsp; } -EXPORT_SYMBOL(process_sigma_firmware_regmap); +EXPORT_SYMBOL_GPL(devm_sigmadsp_init_regmap); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("SigmaDSP regmap firmware loader"); diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 4fd31434276b..34e63b554c31 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -1,7 +1,7 @@ /* * Load Analog Devices SigmaStudio firmware files * - * Copyright 2009-2011 Analog Devices Inc. + * Copyright 2009-2014 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -12,11 +12,21 @@ #include #include #include +#include + +#include #include "sigmadsp.h" #define SIGMA_MAGIC "ADISIGM" +struct sigmadsp_data { + struct list_head head; + unsigned int addr; + unsigned int length; + uint8_t data[]; +}; + struct sigma_firmware_header { unsigned char magic[7]; u8 version; @@ -30,6 +40,20 @@ enum { SIGMA_ACTION_END, }; +struct sigma_action { + u8 instr; + u8 len_hi; + __le16 len; + __be16 addr; + unsigned char payload[]; +} __packed; + +static int sigmadsp_write(struct sigmadsp *sigmadsp, unsigned int addr, + const uint8_t data[], size_t len) +{ + return sigmadsp->write(sigmadsp->control_data, addr, data, len); +} + static inline u32 sigma_action_len(struct sigma_action *sa) { return (sa->len_hi << 16) | le16_to_cpu(sa->len); @@ -58,11 +82,11 @@ static size_t sigma_action_size(struct sigma_action *sa) * Returns a negative error value in case of an error, 0 if processing of * the firmware should be stopped after this action, 1 otherwise. */ -static int -process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa) +static int process_sigma_action(struct sigmadsp *sigmadsp, + struct sigma_action *sa) { size_t len = sigma_action_len(sa); - int ret; + struct sigmadsp_data *data; pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, sa->instr, sa->addr, len); @@ -71,9 +95,17 @@ process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa) case SIGMA_ACTION_WRITEXBYTES: case SIGMA_ACTION_WRITESINGLE: case SIGMA_ACTION_WRITESAFELOAD: - ret = ssfw->write(ssfw->control_data, sa, len); - if (ret < 0) + if (len < 3) return -EINVAL; + + data = kzalloc(sizeof(*data) + len - 2, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->addr = be16_to_cpu(sa->addr); + data->length = len - 2; + memcpy(data->data, sa->payload, data->length); + list_add_tail(&data->head, &sigmadsp->data_list); break; case SIGMA_ACTION_END: return 0; @@ -84,22 +116,24 @@ process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa) return 1; } -static int -process_sigma_actions(struct sigma_firmware *ssfw) +static int sigmadsp_fw_load_v1(struct sigmadsp *sigmadsp, + const struct firmware *fw) { struct sigma_action *sa; - size_t size; + size_t size, pos; int ret; - while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { - sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); + pos = sizeof(struct sigma_firmware_header); + + while (pos + sizeof(*sa) <= fw->size) { + sa = (struct sigma_action *)(fw->data + pos); size = sigma_action_size(sa); - ssfw->pos += size; - if (ssfw->pos > ssfw->fw->size || size == 0) + pos += size; + if (pos > fw->size || size == 0) break; - ret = process_sigma_action(ssfw, sa); + ret = process_sigma_action(sigmadsp, sa); pr_debug("%s: action returned %i\n", __func__, ret); @@ -107,29 +141,40 @@ process_sigma_actions(struct sigma_firmware *ssfw) return ret; } - if (ssfw->pos != ssfw->fw->size) + if (pos != fw->size) return -EINVAL; return 0; } -int _process_sigma_firmware(struct device *dev, - struct sigma_firmware *ssfw, const char *name) +static void sigmadsp_firmware_release(struct sigmadsp *sigmadsp) { - int ret; - struct sigma_firmware_header *ssfw_head; + struct sigmadsp_data *data, *_data; + + list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head) + kfree(data); + + INIT_LIST_HEAD(&sigmadsp->data_list); +} + +static void devm_sigmadsp_release(struct device *dev, void *res) +{ + sigmadsp_firmware_release((struct sigmadsp *)res); +} + +static int sigmadsp_firmware_load(struct sigmadsp *sigmadsp, const char *name) +{ + const struct sigma_firmware_header *ssfw_head; const struct firmware *fw; + int ret; u32 crc; - pr_debug("%s: loading firmware %s\n", __func__, name); - /* first load the blob */ - ret = request_firmware(&fw, name, dev); + ret = request_firmware(&fw, name, sigmadsp->dev); if (ret) { pr_debug("%s: request_firmware() failed with %i\n", __func__, ret); - return ret; + goto done; } - ssfw->fw = fw; /* then verify the header */ ret = -EINVAL; @@ -141,20 +186,13 @@ int _process_sigma_firmware(struct device *dev, * overflows later in the loading process. */ if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) { - dev_err(dev, "Failed to load firmware: Invalid size\n"); + dev_err(sigmadsp->dev, "Failed to load firmware: Invalid size\n"); goto done; } ssfw_head = (void *)fw->data; if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) { - dev_err(dev, "Failed to load firmware: Invalid magic\n"); - goto done; - } - - if (ssfw_head->version != 1) { - dev_err(dev, - "Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n", - ssfw_head->version); + dev_err(sigmadsp->dev, "Failed to load firmware: Invalid magic\n"); goto done; } @@ -162,23 +200,160 @@ int _process_sigma_firmware(struct device *dev, fw->size - sizeof(*ssfw_head)); pr_debug("%s: crc=%x\n", __func__, crc); if (crc != le32_to_cpu(ssfw_head->crc)) { - dev_err(dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", + dev_err(sigmadsp->dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", le32_to_cpu(ssfw_head->crc), crc); goto done; } - ssfw->pos = sizeof(*ssfw_head); + switch (ssfw_head->version) { + case 1: + ret = sigmadsp_fw_load_v1(sigmadsp, fw); + break; + default: + dev_err(sigmadsp->dev, + "Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n", + ssfw_head->version); + ret = -EINVAL; + break; + } - /* finally process all of the actions */ - ret = process_sigma_actions(ssfw); + if (ret) + sigmadsp_firmware_release(sigmadsp); - done: +done: release_firmware(fw); - pr_debug("%s: loaded %s\n", __func__, name); + return ret; +} + +static int sigmadsp_init(struct sigmadsp *sigmadsp, struct device *dev, + const struct sigmadsp_ops *ops, const char *firmware_name) +{ + sigmadsp->ops = ops; + sigmadsp->dev = dev; + + INIT_LIST_HEAD(&sigmadsp->data_list); + + return sigmadsp_firmware_load(sigmadsp, firmware_name); +} + +/** + * devm_sigmadsp_init() - Initialize SigmaDSP instance + * @dev: The parent device + * @ops: The sigmadsp_ops to use for this instance + * @firmware_name: Name of the firmware file to load + * + * Allocates a SigmaDSP instance and loads the specified firmware file. + * + * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error. + */ +struct sigmadsp *devm_sigmadsp_init(struct device *dev, + const struct sigmadsp_ops *ops, const char *firmware_name) +{ + struct sigmadsp *sigmadsp; + int ret; + + sigmadsp = devres_alloc(devm_sigmadsp_release, sizeof(*sigmadsp), + GFP_KERNEL); + if (!sigmadsp) + return ERR_PTR(-ENOMEM); + + ret = sigmadsp_init(sigmadsp, dev, ops, firmware_name); + if (ret) { + devres_free(sigmadsp); + return ERR_PTR(ret); + } + + devres_add(dev, sigmadsp); + + return sigmadsp; +} +EXPORT_SYMBOL_GPL(devm_sigmadsp_init); + +/** + * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component + * @sigmadsp: The sigmadsp instance to attach + * @component: The component to attach to + * + * Typically called in the components probe callback. + * + * Note, once this function has been called the firmware must not be released + * until after the ALSA snd_card that the component belongs to has been + * disconnected, even if sigmadsp_attach() returns an error. + */ +int sigmadsp_attach(struct sigmadsp *sigmadsp, + struct snd_soc_component *component) +{ + sigmadsp->component = component; + + return 0; +} +EXPORT_SYMBOL_GPL(sigmadsp_attach); + +/** + * sigmadsp_setup() - Setup the DSP for the specified samplerate + * @sigmadsp: The sigmadsp instance to configure + * @samplerate: The samplerate the DSP should be configured for + * + * Loads the appropriate firmware program and parameter memory (if not already + * loaded) and enables the controls for the specified samplerate. Any control + * parameter changes that have been made previously will be restored. + * + * Returns 0 on success, a negative error code otherwise. + */ +int sigmadsp_setup(struct sigmadsp *sigmadsp, unsigned int samplerate) +{ + struct sigmadsp_data *data; + int ret; + + if (sigmadsp->current_samplerate == samplerate) + return 0; + + list_for_each_entry(data, &sigmadsp->data_list, head) { + ret = sigmadsp_write(sigmadsp, data->addr, data->data, + data->length); + if (ret) + goto err; + } + + sigmadsp->current_samplerate = samplerate; + + return 0; +err: + sigmadsp_reset(sigmadsp); return ret; } -EXPORT_SYMBOL_GPL(_process_sigma_firmware); +EXPORT_SYMBOL_GPL(sigmadsp_setup); + +/** + * sigmadsp_reset() - Notify the sigmadsp instance that the DSP has been reset + * @sigmadsp: The sigmadsp instance to reset + * + * Should be called whenever the DSP has been reset and parameter and program + * memory need to be re-loaded. + */ +void sigmadsp_reset(struct sigmadsp *sigmadsp) +{ + sigmadsp->current_samplerate = 0; +} +EXPORT_SYMBOL_GPL(sigmadsp_reset); + +/** + * sigmadsp_restrict_params() - Applies DSP firmware specific constraints + * @sigmadsp: The sigmadsp instance + * @substream: The substream to restrict + * + * Applies samplerate constraints that may be required by the firmware Should + * typically be called from the CODEC/component drivers startup callback. + * + * Returns 0 on success, a negative error code otherwise. + */ +int sigmadsp_restrict_params(struct sigmadsp *sigmadsp, + struct snd_pcm_substream *substream) +{ + return 0; +} +EXPORT_SYMBOL_GPL(sigmadsp_restrict_params); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h index c47cd23e9827..a6be91a4c2dc 100644 --- a/sound/soc/codecs/sigmadsp.h +++ b/sound/soc/codecs/sigmadsp.h @@ -11,31 +11,50 @@ #include #include +#include -struct sigma_action { - u8 instr; - u8 len_hi; - __le16 len; - __be16 addr; - unsigned char payload[]; -} __packed; +#include -struct sigma_firmware { - const struct firmware *fw; - size_t pos; +struct sigmadsp; +struct snd_soc_component; +struct snd_pcm_substream; + +struct sigmadsp_ops { + int (*safeload)(struct sigmadsp *sigmadsp, unsigned int addr, + const uint8_t *data, size_t len); +}; + +struct sigmadsp { + const struct sigmadsp_ops *ops; + + struct list_head data_list; + + unsigned int current_samplerate; + struct snd_soc_component *component; + struct device *dev; void *control_data; - int (*write)(void *control_data, const struct sigma_action *sa, - size_t len); + int (*write)(void *, unsigned int, const uint8_t *, size_t); }; -int _process_sigma_firmware(struct device *dev, - struct sigma_firmware *ssfw, const char *name); +struct sigmadsp *devm_sigmadsp_init(struct device *dev, + const struct sigmadsp_ops *ops, const char *firmware_name); +void sigmadsp_reset(struct sigmadsp *sigmadsp); + +int sigmadsp_restrict_params(struct sigmadsp *sigmadsp, + struct snd_pcm_substream *substream); struct i2c_client; -extern int process_sigma_firmware(struct i2c_client *client, const char *name); -extern int process_sigma_firmware_regmap(struct device *dev, - struct regmap *regmap, const char *name); +struct sigmadsp *devm_sigmadsp_init_regmap(struct device *dev, + struct regmap *regmap, const struct sigmadsp_ops *ops, + const char *firmware_name); +struct sigmadsp *devm_sigmadsp_init_i2c(struct i2c_client *client, + const struct sigmadsp_ops *ops, const char *firmware_name); + +int sigmadsp_attach(struct sigmadsp *sigmadsp, + struct snd_soc_component *component); +int sigmadsp_setup(struct sigmadsp *sigmadsp, unsigned int rate); +void sigmadsp_reset(struct sigmadsp *sigmadsp); #endif -- GitLab From a35daac77a0397d4f23b642d3dc0684682e56cc5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Nov 2014 18:29:06 +0100 Subject: [PATCH 5464/9457] ASoC: sigmadsp: Add support for fw v2 This patch adds support for the v2 version of the SigmaDSP firmware file format. The new format has support for having different program and parameter settings for different samplerates. In addition it stores metadata describing the firmware. This metadata includes the set of supported samplerates which will be used to restrict the samplerates that can be selected by userspace. Also included is information about the modifiable parameters. Those will be exposed as ALSA controls so they can be changed at runtime. The new format is based on a binary type-length-value structure that makes it both forward and backwards compatible. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sigmadsp-i2c.c | 29 ++ sound/soc/codecs/sigmadsp-regmap.c | 8 + sound/soc/codecs/sigmadsp.c | 463 ++++++++++++++++++++++++++++- sound/soc/codecs/sigmadsp.h | 6 + 4 files changed, 504 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c index bf6a2be72692..21ca3a5e9f66 100644 --- a/sound/soc/codecs/sigmadsp-i2c.c +++ b/sound/soc/codecs/sigmadsp-i2c.c @@ -34,6 +34,34 @@ static int sigmadsp_write_i2c(void *control_data, return ret; } +static int sigmadsp_read_i2c(void *control_data, + unsigned int addr, uint8_t data[], size_t len) +{ + struct i2c_client *client = control_data; + struct i2c_msg msgs[2]; + uint8_t buf[2]; + int ret; + + put_unaligned_be16(addr, buf); + + msgs[0].addr = client->addr; + msgs[0].len = sizeof(buf); + msgs[0].buf = buf; + msgs[0].flags = 0; + + msgs[1].addr = client->addr; + msgs[1].len = len; + msgs[1].buf = data; + msgs[1].flags = I2C_M_RD; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + else if (ret != ARRAY_SIZE(msgs)) + return -EIO; + return 0; +} + /** * devm_sigmadsp_init_i2c() - Initialize SigmaDSP instance * @client: The parent I2C device @@ -55,6 +83,7 @@ struct sigmadsp *devm_sigmadsp_init_i2c(struct i2c_client *client, sigmadsp->control_data = client; sigmadsp->write = sigmadsp_write_i2c; + sigmadsp->read = sigmadsp_read_i2c; return sigmadsp; } diff --git a/sound/soc/codecs/sigmadsp-regmap.c b/sound/soc/codecs/sigmadsp-regmap.c index cdc5dda47b88..912861be5b87 100644 --- a/sound/soc/codecs/sigmadsp-regmap.c +++ b/sound/soc/codecs/sigmadsp-regmap.c @@ -19,6 +19,13 @@ static int sigmadsp_write_regmap(void *control_data, data, len); } +static int sigmadsp_read_regmap(void *control_data, + unsigned int addr, uint8_t data[], size_t len) +{ + return regmap_raw_read(control_data, addr, + data, len); +} + /** * devm_sigmadsp_init_i2c() - Initialize SigmaDSP instance * @dev: The parent device @@ -42,6 +49,7 @@ struct sigmadsp *devm_sigmadsp_init_regmap(struct device *dev, sigmadsp->control_data = regmap; sigmadsp->write = sigmadsp_write_regmap; + sigmadsp->read = sigmadsp_read_regmap; return sigmadsp; } diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 34e63b554c31..55af596935d4 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -14,19 +14,61 @@ #include #include +#include #include #include "sigmadsp.h" #define SIGMA_MAGIC "ADISIGM" +#define SIGMA_FW_CHUNK_TYPE_DATA 0 +#define SIGMA_FW_CHUNK_TYPE_CONTROL 1 +#define SIGMA_FW_CHUNK_TYPE_SAMPLERATES 2 + +struct sigmadsp_control { + struct list_head head; + uint32_t samplerates; + unsigned int addr; + unsigned int num_bytes; + const char *name; + struct snd_kcontrol *kcontrol; + bool cached; + uint8_t cache[]; +}; + struct sigmadsp_data { struct list_head head; + uint32_t samplerates; unsigned int addr; unsigned int length; uint8_t data[]; }; +struct sigma_fw_chunk { + __le32 length; + __le32 tag; + __le32 samplerates; +} __packed; + +struct sigma_fw_chunk_data { + struct sigma_fw_chunk chunk; + __le16 addr; + uint8_t data[]; +} __packed; + +struct sigma_fw_chunk_control { + struct sigma_fw_chunk chunk; + __le16 type; + __le16 addr; + __le16 num_bytes; + const char name[]; +} __packed; + +struct sigma_fw_chunk_samplerate { + struct sigma_fw_chunk chunk; + __le32 samplerates[]; +} __packed; + struct sigma_firmware_header { unsigned char magic[7]; u8 version; @@ -54,6 +96,269 @@ static int sigmadsp_write(struct sigmadsp *sigmadsp, unsigned int addr, return sigmadsp->write(sigmadsp->control_data, addr, data, len); } +static int sigmadsp_read(struct sigmadsp *sigmadsp, unsigned int addr, + uint8_t data[], size_t len) +{ + return sigmadsp->read(sigmadsp->control_data, addr, data, len); +} + +static int sigmadsp_ctrl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *info) +{ + struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; + + info->type = SNDRV_CTL_ELEM_TYPE_BYTES; + info->count = ctrl->num_bytes; + + return 0; +} + +static int sigmadsp_ctrl_write(struct sigmadsp *sigmadsp, + struct sigmadsp_control *ctrl, void *data) +{ + /* safeload loads up to 20 bytes in a atomic operation */ + if (ctrl->num_bytes > 4 && ctrl->num_bytes <= 20 && sigmadsp->ops && + sigmadsp->ops->safeload) + return sigmadsp->ops->safeload(sigmadsp, ctrl->addr, data, + ctrl->num_bytes); + else + return sigmadsp_write(sigmadsp, ctrl->addr, data, + ctrl->num_bytes); +} + +static int sigmadsp_ctrl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; + struct sigmadsp *sigmadsp = snd_kcontrol_chip(kcontrol); + uint8_t *data; + int ret = 0; + + mutex_lock(&sigmadsp->lock); + + data = ucontrol->value.bytes.data; + + if (!(kcontrol->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) + ret = sigmadsp_ctrl_write(sigmadsp, ctrl, data); + + if (ret == 0) { + memcpy(ctrl->cache, data, ctrl->num_bytes); + ctrl->cached = true; + } + + mutex_unlock(&sigmadsp->lock); + + return ret; +} + +static int sigmadsp_ctrl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; + struct sigmadsp *sigmadsp = snd_kcontrol_chip(kcontrol); + int ret = 0; + + mutex_lock(&sigmadsp->lock); + + if (!ctrl->cached) { + ret = sigmadsp_read(sigmadsp, ctrl->addr, ctrl->cache, + ctrl->num_bytes); + } + + if (ret == 0) { + ctrl->cached = true; + memcpy(ucontrol->value.bytes.data, ctrl->cache, + ctrl->num_bytes); + } + + mutex_unlock(&sigmadsp->lock); + + return ret; +} + +static void sigmadsp_control_free(struct snd_kcontrol *kcontrol) +{ + struct sigmadsp_control *ctrl = (void *)kcontrol->private_value; + + ctrl->kcontrol = NULL; +} + +static bool sigma_fw_validate_control_name(const char *name, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) { + /* Normal ASCII characters are valid */ + if (name[i] < ' ' || name[i] > '~') + return false; + } + + return true; +} + +static int sigma_fw_load_control(struct sigmadsp *sigmadsp, + const struct sigma_fw_chunk *chunk, unsigned int length) +{ + const struct sigma_fw_chunk_control *ctrl_chunk; + struct sigmadsp_control *ctrl; + unsigned int num_bytes; + size_t name_len; + char *name; + int ret; + + if (length <= sizeof(*ctrl_chunk)) + return -EINVAL; + + ctrl_chunk = (const struct sigma_fw_chunk_control *)chunk; + + name_len = length - sizeof(*ctrl_chunk); + if (name_len >= SNDRV_CTL_ELEM_ID_NAME_MAXLEN) + name_len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1; + + /* Make sure there are no non-displayable characaters in the string */ + if (!sigma_fw_validate_control_name(ctrl_chunk->name, name_len)) + return -EINVAL; + + num_bytes = le16_to_cpu(ctrl_chunk->num_bytes); + ctrl = kzalloc(sizeof(*ctrl) + num_bytes, GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + name = kzalloc(name_len + 1, GFP_KERNEL); + if (!name) { + ret = -ENOMEM; + goto err_free_ctrl; + } + memcpy(name, ctrl_chunk->name, name_len); + name[name_len] = '\0'; + ctrl->name = name; + + ctrl->addr = le16_to_cpu(ctrl_chunk->addr); + ctrl->num_bytes = num_bytes; + ctrl->samplerates = chunk->samplerates; + + list_add_tail(&ctrl->head, &sigmadsp->ctrl_list); + + return 0; + +err_free_ctrl: + kfree(ctrl); + + return ret; +} + +static int sigma_fw_load_data(struct sigmadsp *sigmadsp, + const struct sigma_fw_chunk *chunk, unsigned int length) +{ + const struct sigma_fw_chunk_data *data_chunk; + struct sigmadsp_data *data; + + if (length <= sizeof(*data_chunk)) + return -EINVAL; + + data_chunk = (struct sigma_fw_chunk_data *)chunk; + + length -= sizeof(*data_chunk); + + data = kzalloc(sizeof(*data) + length, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->addr = le16_to_cpu(data_chunk->addr); + data->length = length; + data->samplerates = chunk->samplerates; + memcpy(data->data, data_chunk->data, length); + list_add_tail(&data->head, &sigmadsp->data_list); + + return 0; +} + +static int sigma_fw_load_samplerates(struct sigmadsp *sigmadsp, + const struct sigma_fw_chunk *chunk, unsigned int length) +{ + const struct sigma_fw_chunk_samplerate *rate_chunk; + unsigned int num_rates; + unsigned int *rates; + unsigned int i; + + rate_chunk = (const struct sigma_fw_chunk_samplerate *)chunk; + + num_rates = (length - sizeof(*rate_chunk)) / sizeof(__le32); + + if (num_rates > 32 || num_rates == 0) + return -EINVAL; + + /* We only allow one samplerates block per file */ + if (sigmadsp->rate_constraints.count) + return -EINVAL; + + rates = kcalloc(num_rates, sizeof(*rates), GFP_KERNEL); + if (!rates) + return -ENOMEM; + + for (i = 0; i < num_rates; i++) + rates[i] = le32_to_cpu(rate_chunk->samplerates[i]); + + sigmadsp->rate_constraints.count = num_rates; + sigmadsp->rate_constraints.list = rates; + + return 0; +} + +static int sigmadsp_fw_load_v2(struct sigmadsp *sigmadsp, + const struct firmware *fw) +{ + struct sigma_fw_chunk *chunk; + unsigned int length, pos; + int ret; + + /* + * Make sure that there is at least one chunk to avoid integer + * underflows later on. Empty firmware is still valid though. + */ + if (fw->size < sizeof(*chunk) + sizeof(struct sigma_firmware_header)) + return 0; + + pos = sizeof(struct sigma_firmware_header); + + while (pos < fw->size - sizeof(*chunk)) { + chunk = (struct sigma_fw_chunk *)(fw->data + pos); + + length = le32_to_cpu(chunk->length); + + if (length > fw->size - pos || length < sizeof(*chunk)) + return -EINVAL; + + switch (chunk->tag) { + case SIGMA_FW_CHUNK_TYPE_DATA: + ret = sigma_fw_load_data(sigmadsp, chunk, length); + break; + case SIGMA_FW_CHUNK_TYPE_CONTROL: + ret = sigma_fw_load_control(sigmadsp, chunk, length); + break; + case SIGMA_FW_CHUNK_TYPE_SAMPLERATES: + ret = sigma_fw_load_samplerates(sigmadsp, chunk, length); + break; + default: + dev_warn(sigmadsp->dev, "Unknown chunk type: %d\n", + chunk->tag); + ret = 0; + break; + } + + if (ret) + return ret; + + /* + * This can not overflow since if length is larger than the + * maximum firmware size (0x4000000) we'll error out earilier. + */ + pos += ALIGN(length, sizeof(__le32)); + } + + return 0; +} + static inline u32 sigma_action_len(struct sigma_action *sa) { return (sa->len_hi << 16) | le16_to_cpu(sa->len); @@ -149,11 +454,18 @@ static int sigmadsp_fw_load_v1(struct sigmadsp *sigmadsp, static void sigmadsp_firmware_release(struct sigmadsp *sigmadsp) { + struct sigmadsp_control *ctrl, *_ctrl; struct sigmadsp_data *data, *_data; + list_for_each_entry_safe(ctrl, _ctrl, &sigmadsp->ctrl_list, head) { + kfree(ctrl->name); + kfree(ctrl); + } + list_for_each_entry_safe(data, _data, &sigmadsp->data_list, head) kfree(data); + INIT_LIST_HEAD(&sigmadsp->ctrl_list); INIT_LIST_HEAD(&sigmadsp->data_list); } @@ -209,9 +521,12 @@ static int sigmadsp_firmware_load(struct sigmadsp *sigmadsp, const char *name) case 1: ret = sigmadsp_fw_load_v1(sigmadsp, fw); break; + case 2: + ret = sigmadsp_fw_load_v2(sigmadsp, fw); + break; default: dev_err(sigmadsp->dev, - "Failed to load firmware: Invalid version %d. Supported firmware versions: 1\n", + "Failed to load firmware: Invalid version %d. Supported firmware versions: 1, 2\n", ssfw_head->version); ret = -EINVAL; break; @@ -232,7 +547,9 @@ static int sigmadsp_init(struct sigmadsp *sigmadsp, struct device *dev, sigmadsp->ops = ops; sigmadsp->dev = dev; + INIT_LIST_HEAD(&sigmadsp->ctrl_list); INIT_LIST_HEAD(&sigmadsp->data_list); + mutex_init(&sigmadsp->lock); return sigmadsp_firmware_load(sigmadsp, firmware_name); } @@ -270,6 +587,114 @@ struct sigmadsp *devm_sigmadsp_init(struct device *dev, } EXPORT_SYMBOL_GPL(devm_sigmadsp_init); +static int sigmadsp_rate_to_index(struct sigmadsp *sigmadsp, unsigned int rate) +{ + unsigned int i; + + for (i = 0; i < sigmadsp->rate_constraints.count; i++) { + if (sigmadsp->rate_constraints.list[i] == rate) + return i; + } + + return -EINVAL; +} + +static unsigned int sigmadsp_get_samplerate_mask(struct sigmadsp *sigmadsp, + unsigned int samplerate) +{ + int samplerate_index; + + if (samplerate == 0) + return 0; + + if (sigmadsp->rate_constraints.count) { + samplerate_index = sigmadsp_rate_to_index(sigmadsp, samplerate); + if (samplerate_index < 0) + return 0; + + return BIT(samplerate_index); + } else { + return ~0; + } +} + +static bool sigmadsp_samplerate_valid(unsigned int supported, + unsigned int requested) +{ + /* All samplerates are supported */ + if (!supported) + return true; + + return supported & requested; +} + +static int sigmadsp_alloc_control(struct sigmadsp *sigmadsp, + struct sigmadsp_control *ctrl, unsigned int samplerate_mask) +{ + struct snd_kcontrol_new template; + struct snd_kcontrol *kcontrol; + int ret; + + memset(&template, 0, sizeof(template)); + template.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + template.name = ctrl->name; + template.info = sigmadsp_ctrl_info; + template.get = sigmadsp_ctrl_get; + template.put = sigmadsp_ctrl_put; + template.private_value = (unsigned long)ctrl; + template.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; + if (!sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask)) + template.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + + kcontrol = snd_ctl_new1(&template, sigmadsp); + if (!kcontrol) + return -ENOMEM; + + kcontrol->private_free = sigmadsp_control_free; + ctrl->kcontrol = kcontrol; + + ret = snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol); + if (ret) + return ret; + + return 0; +} + +static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp, + struct sigmadsp_control *ctrl, unsigned int samplerate_mask) +{ + struct snd_card *card = sigmadsp->component->card->snd_card; + struct snd_kcontrol_volatile *vd; + struct snd_ctl_elem_id id; + bool active, changed; + + active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask); + + down_write(&card->controls_rwsem); + if (!ctrl->kcontrol) { + up_write(&card->controls_rwsem); + return; + } + + id = ctrl->kcontrol->id; + vd = &ctrl->kcontrol->vd[0]; + if (active == (bool)(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) { + vd->access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + changed = true; + } + up_write(&card->controls_rwsem); + + if (active && changed) { + mutex_lock(&sigmadsp->lock); + if (ctrl->cached) + sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache); + mutex_unlock(&sigmadsp->lock); + } + + if (changed) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &id); +} + /** * sigmadsp_attach() - Attach a sigmadsp instance to a ASoC component * @sigmadsp: The sigmadsp instance to attach @@ -284,8 +709,21 @@ EXPORT_SYMBOL_GPL(devm_sigmadsp_init); int sigmadsp_attach(struct sigmadsp *sigmadsp, struct snd_soc_component *component) { + struct sigmadsp_control *ctrl; + unsigned int samplerate_mask; + int ret; + sigmadsp->component = component; + samplerate_mask = sigmadsp_get_samplerate_mask(sigmadsp, + sigmadsp->current_samplerate); + + list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) { + ret = sigmadsp_alloc_control(sigmadsp, ctrl, samplerate_mask); + if (ret) + return ret; + } + return 0; } EXPORT_SYMBOL_GPL(sigmadsp_attach); @@ -303,19 +741,31 @@ EXPORT_SYMBOL_GPL(sigmadsp_attach); */ int sigmadsp_setup(struct sigmadsp *sigmadsp, unsigned int samplerate) { + struct sigmadsp_control *ctrl; + unsigned int samplerate_mask; struct sigmadsp_data *data; int ret; if (sigmadsp->current_samplerate == samplerate) return 0; + samplerate_mask = sigmadsp_get_samplerate_mask(sigmadsp, samplerate); + if (samplerate_mask == 0) + return -EINVAL; + list_for_each_entry(data, &sigmadsp->data_list, head) { + if (!sigmadsp_samplerate_valid(data->samplerates, + samplerate_mask)) + continue; ret = sigmadsp_write(sigmadsp, data->addr, data->data, data->length); if (ret) goto err; } + list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) + sigmadsp_activate_ctrl(sigmadsp, ctrl, samplerate_mask); + sigmadsp->current_samplerate = samplerate; return 0; @@ -335,6 +785,11 @@ EXPORT_SYMBOL_GPL(sigmadsp_setup); */ void sigmadsp_reset(struct sigmadsp *sigmadsp) { + struct sigmadsp_control *ctrl; + + list_for_each_entry(ctrl, &sigmadsp->ctrl_list, head) + sigmadsp_activate_ctrl(sigmadsp, ctrl, false); + sigmadsp->current_samplerate = 0; } EXPORT_SYMBOL_GPL(sigmadsp_reset); @@ -352,7 +807,11 @@ EXPORT_SYMBOL_GPL(sigmadsp_reset); int sigmadsp_restrict_params(struct sigmadsp *sigmadsp, struct snd_pcm_substream *substream) { - return 0; + if (sigmadsp->rate_constraints.count == 0) + return 0; + + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &sigmadsp->rate_constraints); } EXPORT_SYMBOL_GPL(sigmadsp_restrict_params); diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h index a6be91a4c2dc..614475cbb823 100644 --- a/sound/soc/codecs/sigmadsp.h +++ b/sound/soc/codecs/sigmadsp.h @@ -27,14 +27,20 @@ struct sigmadsp_ops { struct sigmadsp { const struct sigmadsp_ops *ops; + struct list_head ctrl_list; struct list_head data_list; + struct snd_pcm_hw_constraint_list rate_constraints; + unsigned int current_samplerate; struct snd_soc_component *component; struct device *dev; + struct mutex lock; + void *control_data; int (*write)(void *, unsigned int, const uint8_t *, size_t); + int (*read)(void *, unsigned int, uint8_t *, size_t); }; struct sigmadsp *devm_sigmadsp_init(struct device *dev, -- GitLab From a3a1ec66d6c9320e676fc99dbaf18db4f8dcda93 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Nov 2014 18:29:07 +0100 Subject: [PATCH 5465/9457] ASoC: adau1701: Implement sigmadsp safeload The safeload feature allows to load up to 5 parameter memory registers atomically. This is helpful for switching between e.g. filter settings without causing any glitches. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1701.c | 57 +++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 05d5eb5984b6..d4e219b6b98f 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -22,9 +22,14 @@ #include #include +#include + #include "sigmadsp.h" #include "adau1701.h" +#define ADAU1701_SAFELOAD_DATA(i) (0x0810 + (i)) +#define ADAU1701_SAFELOAD_ADDR(i) (0x0815 + (i)) + #define ADAU1701_DSPCTRL 0x081c #define ADAU1701_SEROCTL 0x081e #define ADAU1701_SERICTL 0x081f @@ -42,6 +47,7 @@ #define ADAU1701_DSPCTRL_CR (1 << 2) #define ADAU1701_DSPCTRL_DAM (1 << 3) #define ADAU1701_DSPCTRL_ADM (1 << 4) +#define ADAU1701_DSPCTRL_IST (1 << 5) #define ADAU1701_DSPCTRL_SR_48 0x00 #define ADAU1701_DSPCTRL_SR_96 0x01 #define ADAU1701_DSPCTRL_SR_192 0x02 @@ -102,6 +108,7 @@ struct adau1701 { unsigned int pll_clkdiv; unsigned int sysclk; struct regmap *regmap; + struct i2c_client *client; u8 pin_config[12]; struct sigmadsp *sigmadsp; @@ -161,6 +168,7 @@ static bool adau1701_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case ADAU1701_DACSET: + case ADAU1701_DSPCTRL: return true; default: return false; @@ -240,6 +248,50 @@ static int adau1701_reg_read(void *context, unsigned int reg, return 0; } +static int adau1701_safeload(struct sigmadsp *sigmadsp, unsigned int addr, + const uint8_t bytes[], size_t len) +{ + struct i2c_client *client = to_i2c_client(sigmadsp->dev); + struct adau1701 *adau1701 = i2c_get_clientdata(client); + unsigned int val; + unsigned int i; + uint8_t buf[10]; + int ret; + + ret = regmap_read(adau1701->regmap, ADAU1701_DSPCTRL, &val); + if (ret) + return ret; + + if (val & ADAU1701_DSPCTRL_IST) + msleep(50); + + for (i = 0; i < len / 4; i++) { + put_unaligned_le16(ADAU1701_SAFELOAD_DATA(i), buf); + buf[2] = 0x00; + memcpy(buf + 3, bytes + i * 4, 4); + ret = i2c_master_send(client, buf, 7); + if (ret < 0) + return ret; + else if (ret != 7) + return -EIO; + + put_unaligned_le16(ADAU1701_SAFELOAD_ADDR(i), buf); + put_unaligned_le16(addr + i, buf + 2); + ret = i2c_master_send(client, buf, 4); + if (ret < 0) + return ret; + else if (ret != 4) + return -EIO; + } + + return regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, + ADAU1701_DSPCTRL_IST, ADAU1701_DSPCTRL_IST); +} + +static const struct sigmadsp_ops adau1701_sigmadsp_ops = { + .safeload = adau1701_safeload, +}; + static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv, unsigned int rate) { @@ -684,6 +736,7 @@ static int adau1701_i2c_probe(struct i2c_client *client, if (!adau1701) return -ENOMEM; + adau1701->client = client; adau1701->regmap = devm_regmap_init(dev, NULL, client, &adau1701_regmap); if (IS_ERR(adau1701->regmap)) @@ -740,8 +793,8 @@ static int adau1701_i2c_probe(struct i2c_client *client, i2c_set_clientdata(client, adau1701); - adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, NULL, - ADAU1701_FIRMWARE); + adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, + &adau1701_sigmadsp_ops, ADAU1701_FIRMWARE); if (IS_ERR(adau1701->sigmadsp)) return PTR_ERR(adau1701->sigmadsp); -- GitLab From 0f32fd1900e6b972f289416dbd75e92772b630cb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Nov 2014 12:16:14 +0100 Subject: [PATCH 5466/9457] ALSA: hda/realtek - Clean up mute/mic GPIO LED handling There are a few duplicated codes handling the mute and mic-mute LEDs via GPIO pins. Let's consolidate to single helpers. Here we introduced two new fields to alc_spec, gpio_mute_led_mask and gpio_mic_led_mask, to contain the bit mask to set/clear. Also, mute_led_polarity is evaluated as well. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 81 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1af917f58a70..3c29a558e7db 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -96,6 +96,8 @@ struct alc_spec { hda_nid_t cap_mute_led_nid; unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ + unsigned int gpio_mute_led_mask; + unsigned int gpio_mic_led_mask; hda_nid_t headset_mic_pin; hda_nid_t headphone_mic_pin; @@ -3235,41 +3237,45 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, } } -/* turn on/off mute LED per vmaster hook */ -static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) +/* update LED status via GPIO */ +static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, + bool enabled) { - struct hda_codec *codec = private_data; struct alc_spec *spec = codec->spec; unsigned int oldval = spec->gpio_led; + if (spec->mute_led_polarity) + enabled = !enabled; + if (enabled) - spec->gpio_led &= ~0x08; + spec->gpio_led &= ~mask; else - spec->gpio_led |= 0x08; + spec->gpio_led |= mask; if (spec->gpio_led != oldval) snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_led); } -/* turn on/off mic-mute LED per capture hook */ -static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +/* turn on/off mute LED via GPIO per vmaster hook */ +static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) { + struct hda_codec *codec = private_data; struct alc_spec *spec = codec->spec; - unsigned int oldval = spec->gpio_led; - if (!ucontrol) - return; + alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); +} - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - spec->gpio_led &= ~0x10; - else - spec->gpio_led |= 0x10; - if (spec->gpio_led != oldval) - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_led); +/* turn on/off mic-mute LED via GPIO per capture hook */ +static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct alc_spec *spec = codec->spec; + + if (ucontrol) + alc_update_gpio_led(codec, spec->gpio_mic_led_mask, + ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]); } static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, @@ -3283,9 +3289,12 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, }; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; + spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; + spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; + spec->mute_led_polarity = 0; + spec->gpio_mute_led_mask = 0x08; + spec->gpio_mic_led_mask = 0x10; snd_hda_add_verbs(codec, gpio_init); } } @@ -3327,9 +3336,11 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, }; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; + spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; spec->gpio_led = 0; + spec->mute_led_polarity = 0; + spec->gpio_mute_led_mask = 0x08; spec->cap_mute_led_nid = 0x18; snd_hda_add_verbs(codec, gpio_init); codec->power_filter = led_power_filter; @@ -3348,9 +3359,11 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, }; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; + spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; spec->gpio_led = 0; + spec->mute_led_polarity = 0; + spec->gpio_mute_led_mask = 0x08; spec->cap_mute_led_nid = 0x18; snd_hda_add_verbs(codec, gpio_init); codec->power_filter = led_power_filter; @@ -5624,22 +5637,6 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec, } } -/* turn on/off mute LED per vmaster hook */ -static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) -{ - struct hda_codec *codec = private_data; - struct alc_spec *spec = codec->spec; - unsigned int oldval = spec->gpio_led; - - if (enabled) - spec->gpio_led |= 0x01; - else - spec->gpio_led &= ~0x01; - if (spec->gpio_led != oldval) - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_led); -} - /* avoid D3 for keeping GPIO up */ static unsigned int gpio_led_power_filter(struct hda_codec *codec, hda_nid_t nid, @@ -5662,8 +5659,10 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec, }; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; + spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; spec->gpio_led = 0; + spec->mute_led_polarity = 1; + spec->gpio_mute_led_mask = 0x01; snd_hda_add_verbs(codec, gpio_init); codec->power_filter = gpio_led_power_filter; } -- GitLab From 003f7de6258900e17f6206e8e417d76c75ca549f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Nov 2014 16:22:52 +0100 Subject: [PATCH 5467/9457] KVM: ia64: remove KVM for ia64 has been marked as broken not just once, but twice even, and the last patch from the maintainer is now roughly 5 years old. Time for it to rest in peace. Acked-by: Gleb Natapov Signed-off-by: Paolo Bonzini --- MAINTAINERS | 9 - arch/ia64/Kconfig | 3 - arch/ia64/Makefile | 1 - arch/ia64/include/asm/kvm_host.h | 609 -------- arch/ia64/include/asm/pvclock-abi.h | 48 - arch/ia64/include/uapi/asm/kvm.h | 268 ---- arch/ia64/kvm/Kconfig | 66 - arch/ia64/kvm/Makefile | 67 - arch/ia64/kvm/asm-offsets.c | 241 --- arch/ia64/kvm/irq.h | 33 - arch/ia64/kvm/kvm-ia64.c | 1942 ----------------------- arch/ia64/kvm/kvm_fw.c | 674 -------- arch/ia64/kvm/kvm_lib.c | 21 - arch/ia64/kvm/kvm_minstate.h | 266 ---- arch/ia64/kvm/lapic.h | 30 - arch/ia64/kvm/memcpy.S | 1 - arch/ia64/kvm/memset.S | 1 - arch/ia64/kvm/misc.h | 94 -- arch/ia64/kvm/mmio.c | 336 ---- arch/ia64/kvm/optvfault.S | 1090 ------------- arch/ia64/kvm/process.c | 1024 ------------- arch/ia64/kvm/trampoline.S | 1038 ------------- arch/ia64/kvm/vcpu.c | 2209 --------------------------- arch/ia64/kvm/vcpu.h | 752 --------- arch/ia64/kvm/vmm.c | 99 -- arch/ia64/kvm/vmm_ivt.S | 1392 ----------------- arch/ia64/kvm/vti.h | 290 ---- arch/ia64/kvm/vtlb.c | 640 -------- virt/kvm/ioapic.c | 5 - virt/kvm/ioapic.h | 1 - virt/kvm/irq_comm.c | 22 - 31 files changed, 13272 deletions(-) delete mode 100644 arch/ia64/include/asm/kvm_host.h delete mode 100644 arch/ia64/include/asm/pvclock-abi.h delete mode 100644 arch/ia64/include/uapi/asm/kvm.h delete mode 100644 arch/ia64/kvm/Kconfig delete mode 100644 arch/ia64/kvm/Makefile delete mode 100644 arch/ia64/kvm/asm-offsets.c delete mode 100644 arch/ia64/kvm/irq.h delete mode 100644 arch/ia64/kvm/kvm-ia64.c delete mode 100644 arch/ia64/kvm/kvm_fw.c delete mode 100644 arch/ia64/kvm/kvm_lib.c delete mode 100644 arch/ia64/kvm/kvm_minstate.h delete mode 100644 arch/ia64/kvm/lapic.h delete mode 100644 arch/ia64/kvm/memcpy.S delete mode 100644 arch/ia64/kvm/memset.S delete mode 100644 arch/ia64/kvm/misc.h delete mode 100644 arch/ia64/kvm/mmio.c delete mode 100644 arch/ia64/kvm/optvfault.S delete mode 100644 arch/ia64/kvm/process.c delete mode 100644 arch/ia64/kvm/trampoline.S delete mode 100644 arch/ia64/kvm/vcpu.c delete mode 100644 arch/ia64/kvm/vcpu.h delete mode 100644 arch/ia64/kvm/vmm.c delete mode 100644 arch/ia64/kvm/vmm_ivt.S delete mode 100644 arch/ia64/kvm/vti.h delete mode 100644 arch/ia64/kvm/vtlb.c diff --git a/MAINTAINERS b/MAINTAINERS index 3c6427190be2..0b8321afa35a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5352,15 +5352,6 @@ S: Supported F: arch/powerpc/include/asm/kvm* F: arch/powerpc/kvm/ -KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64) -M: Xiantao Zhang -L: kvm-ia64@vger.kernel.org -W: http://kvm.qumranet.com -S: Supported -F: Documentation/ia64/kvm.txt -F: arch/ia64/include/asm/kvm* -F: arch/ia64/kvm/ - KERNEL VIRTUAL MACHINE for s390 (KVM/s390) M: Christian Borntraeger M: Cornelia Huck diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index c84c88bbbbd7..11afe7ab1981 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -21,7 +21,6 @@ config IA64 select HAVE_DYNAMIC_FTRACE if (!ITANIUM) select HAVE_FUNCTION_TRACER select HAVE_DMA_ATTRS - select HAVE_KVM select TTY select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG @@ -640,8 +639,6 @@ source "security/Kconfig" source "crypto/Kconfig" -source "arch/ia64/kvm/Kconfig" - source "lib/Kconfig" config IOMMU_HELPER diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 5441b14994fc..970d0bd99621 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -53,7 +53,6 @@ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ -core-$(CONFIG_KVM) += arch/ia64/kvm/ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h deleted file mode 100644 index 4729752b7256..000000000000 --- a/arch/ia64/include/asm/kvm_host.h +++ /dev/null @@ -1,609 +0,0 @@ -/* - * kvm_host.h: used for kvm module, and hold ia64-specific sections. - * - * Copyright (C) 2007, Intel Corporation. - * - * Xiantao Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#ifndef __ASM_KVM_HOST_H -#define __ASM_KVM_HOST_H - -#define KVM_USER_MEM_SLOTS 32 - -#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -#define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS - -/* define exit reasons from vmm to kvm*/ -#define EXIT_REASON_VM_PANIC 0 -#define EXIT_REASON_MMIO_INSTRUCTION 1 -#define EXIT_REASON_PAL_CALL 2 -#define EXIT_REASON_SAL_CALL 3 -#define EXIT_REASON_SWITCH_RR6 4 -#define EXIT_REASON_VM_DESTROY 5 -#define EXIT_REASON_EXTERNAL_INTERRUPT 6 -#define EXIT_REASON_IPI 7 -#define EXIT_REASON_PTC_G 8 -#define EXIT_REASON_DEBUG 20 - -/*Define vmm address space and vm data space.*/ -#define KVM_VMM_SIZE (__IA64_UL_CONST(16)<<20) -#define KVM_VMM_SHIFT 24 -#define KVM_VMM_BASE 0xD000000000000000 -#define VMM_SIZE (__IA64_UL_CONST(8)<<20) - -/* - * Define vm_buffer, used by PAL Services, base address. - * Note: vm_buffer is in the VMM-BLOCK, the size must be < 8M - */ -#define KVM_VM_BUFFER_BASE (KVM_VMM_BASE + VMM_SIZE) -#define KVM_VM_BUFFER_SIZE (__IA64_UL_CONST(8)<<20) - -/* - * kvm guest's data area looks as follow: - * - * +----------------------+ ------- KVM_VM_DATA_SIZE - * | vcpu[n]'s data | | ___________________KVM_STK_OFFSET - * | | | / | - * | .......... | | /vcpu's struct&stack | - * | .......... | | /---------------------|---- 0 - * | vcpu[5]'s data | | / vpd | - * | vcpu[4]'s data | |/-----------------------| - * | vcpu[3]'s data | / vtlb | - * | vcpu[2]'s data | /|------------------------| - * | vcpu[1]'s data |/ | vhpt | - * | vcpu[0]'s data |____________________________| - * +----------------------+ | - * | memory dirty log | | - * +----------------------+ | - * | vm's data struct | | - * +----------------------+ | - * | | | - * | | | - * | | | - * | | | - * | | | - * | | | - * | | | - * | vm's p2m table | | - * | | | - * | | | - * | | | | - * vm's data->| | | | - * +----------------------+ ------- 0 - * To support large memory, needs to increase the size of p2m. - * To support more vcpus, needs to ensure it has enough space to - * hold vcpus' data. - */ - -#define KVM_VM_DATA_SHIFT 26 -#define KVM_VM_DATA_SIZE (__IA64_UL_CONST(1) << KVM_VM_DATA_SHIFT) -#define KVM_VM_DATA_BASE (KVM_VMM_BASE + KVM_VM_DATA_SIZE) - -#define KVM_P2M_BASE KVM_VM_DATA_BASE -#define KVM_P2M_SIZE (__IA64_UL_CONST(24) << 20) - -#define VHPT_SHIFT 16 -#define VHPT_SIZE (__IA64_UL_CONST(1) << VHPT_SHIFT) -#define VHPT_NUM_ENTRIES (__IA64_UL_CONST(1) << (VHPT_SHIFT-5)) - -#define VTLB_SHIFT 16 -#define VTLB_SIZE (__IA64_UL_CONST(1) << VTLB_SHIFT) -#define VTLB_NUM_ENTRIES (1UL << (VHPT_SHIFT-5)) - -#define VPD_SHIFT 16 -#define VPD_SIZE (__IA64_UL_CONST(1) << VPD_SHIFT) - -#define VCPU_STRUCT_SHIFT 16 -#define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT) - -/* - * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h - */ -#define KVM_STK_SHIFT 16 -#define KVM_STK_OFFSET (__IA64_UL_CONST(1)<< KVM_STK_SHIFT) - -#define KVM_VM_STRUCT_SHIFT 19 -#define KVM_VM_STRUCT_SIZE (__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT) - -#define KVM_MEM_DIRY_LOG_SHIFT 19 -#define KVM_MEM_DIRTY_LOG_SIZE (__IA64_UL_CONST(1) << KVM_MEM_DIRY_LOG_SHIFT) - -#ifndef __ASSEMBLY__ - -/*Define the max vcpus and memory for Guests.*/ -#define KVM_MAX_VCPUS (KVM_VM_DATA_SIZE - KVM_P2M_SIZE - KVM_VM_STRUCT_SIZE -\ - KVM_MEM_DIRTY_LOG_SIZE) / sizeof(struct kvm_vcpu_data) -#define KVM_MAX_MEM_SIZE (KVM_P2M_SIZE >> 3 << PAGE_SHIFT) - -#define VMM_LOG_LEN 256 - -#include -#include -#include -#include -#include - -#include -#include -#include - -struct kvm_vcpu_data { - char vcpu_vhpt[VHPT_SIZE]; - char vcpu_vtlb[VTLB_SIZE]; - char vcpu_vpd[VPD_SIZE]; - char vcpu_struct[VCPU_STRUCT_SIZE]; -}; - -struct kvm_vm_data { - char kvm_p2m[KVM_P2M_SIZE]; - char kvm_vm_struct[KVM_VM_STRUCT_SIZE]; - char kvm_mem_dirty_log[KVM_MEM_DIRTY_LOG_SIZE]; - struct kvm_vcpu_data vcpu_data[KVM_MAX_VCPUS]; -}; - -#define VCPU_BASE(n) (KVM_VM_DATA_BASE + \ - offsetof(struct kvm_vm_data, vcpu_data[n])) -#define KVM_VM_BASE (KVM_VM_DATA_BASE + \ - offsetof(struct kvm_vm_data, kvm_vm_struct)) -#define KVM_MEM_DIRTY_LOG_BASE KVM_VM_DATA_BASE + \ - offsetof(struct kvm_vm_data, kvm_mem_dirty_log) - -#define VHPT_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vhpt)) -#define VTLB_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vtlb)) -#define VPD_BASE(n) (VCPU_BASE(n) + offsetof(struct kvm_vcpu_data, vcpu_vpd)) -#define VCPU_STRUCT_BASE(n) (VCPU_BASE(n) + \ - offsetof(struct kvm_vcpu_data, vcpu_struct)) - -/*IO section definitions*/ -#define IOREQ_READ 1 -#define IOREQ_WRITE 0 - -#define STATE_IOREQ_NONE 0 -#define STATE_IOREQ_READY 1 -#define STATE_IOREQ_INPROCESS 2 -#define STATE_IORESP_READY 3 - -/*Guest Physical address layout.*/ -#define GPFN_MEM (0UL << 60) /* Guest pfn is normal mem */ -#define GPFN_FRAME_BUFFER (1UL << 60) /* VGA framebuffer */ -#define GPFN_LOW_MMIO (2UL << 60) /* Low MMIO range */ -#define GPFN_PIB (3UL << 60) /* PIB base */ -#define GPFN_IOSAPIC (4UL << 60) /* IOSAPIC base */ -#define GPFN_LEGACY_IO (5UL << 60) /* Legacy I/O base */ -#define GPFN_GFW (6UL << 60) /* Guest Firmware */ -#define GPFN_PHYS_MMIO (7UL << 60) /* Directed MMIO Range */ - -#define GPFN_IO_MASK (7UL << 60) /* Guest pfn is I/O type */ -#define GPFN_INV_MASK (1UL << 63) /* Guest pfn is invalid */ -#define INVALID_MFN (~0UL) -#define MEM_G (1UL << 30) -#define MEM_M (1UL << 20) -#define MMIO_START (3 * MEM_G) -#define MMIO_SIZE (512 * MEM_M) -#define VGA_IO_START 0xA0000UL -#define VGA_IO_SIZE 0x20000 -#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) -#define LEGACY_IO_SIZE (64 * MEM_M) -#define IO_SAPIC_START 0xfec00000UL -#define IO_SAPIC_SIZE 0x100000 -#define PIB_START 0xfee00000UL -#define PIB_SIZE 0x200000 -#define GFW_START (4 * MEM_G - 16 * MEM_M) -#define GFW_SIZE (16 * MEM_M) - -/*Deliver mode, defined for ioapic.c*/ -#define dest_Fixed IOSAPIC_FIXED -#define dest_LowestPrio IOSAPIC_LOWEST_PRIORITY - -#define NMI_VECTOR 2 -#define ExtINT_VECTOR 0 -#define NULL_VECTOR (-1) -#define IA64_SPURIOUS_INT_VECTOR 0x0f - -#define VCPU_LID(v) (((u64)(v)->vcpu_id) << 24) - -/* - *Delivery mode - */ -#define SAPIC_DELIV_SHIFT 8 -#define SAPIC_FIXED 0x0 -#define SAPIC_LOWEST_PRIORITY 0x1 -#define SAPIC_PMI 0x2 -#define SAPIC_NMI 0x4 -#define SAPIC_INIT 0x5 -#define SAPIC_EXTINT 0x7 - -/* - * vcpu->requests bit members for arch - */ -#define KVM_REQ_PTC_G 32 -#define KVM_REQ_RESUME 33 - -struct kvm_mmio_req { - uint64_t addr; /* physical address */ - uint64_t size; /* size in bytes */ - uint64_t data; /* data (or paddr of data) */ - uint8_t state:4; - uint8_t dir:1; /* 1=read, 0=write */ -}; - -/*Pal data struct */ -struct kvm_pal_call{ - /*In area*/ - uint64_t gr28; - uint64_t gr29; - uint64_t gr30; - uint64_t gr31; - /*Out area*/ - struct ia64_pal_retval ret; -}; - -/* Sal data structure */ -struct kvm_sal_call{ - /*In area*/ - uint64_t in0; - uint64_t in1; - uint64_t in2; - uint64_t in3; - uint64_t in4; - uint64_t in5; - uint64_t in6; - uint64_t in7; - struct sal_ret_values ret; -}; - -/*Guest change rr6*/ -struct kvm_switch_rr6 { - uint64_t old_rr; - uint64_t new_rr; -}; - -union ia64_ipi_a{ - unsigned long val; - struct { - unsigned long rv : 3; - unsigned long ir : 1; - unsigned long eid : 8; - unsigned long id : 8; - unsigned long ib_base : 44; - }; -}; - -union ia64_ipi_d { - unsigned long val; - struct { - unsigned long vector : 8; - unsigned long dm : 3; - unsigned long ig : 53; - }; -}; - -/*ipi check exit data*/ -struct kvm_ipi_data{ - union ia64_ipi_a addr; - union ia64_ipi_d data; -}; - -/*global purge data*/ -struct kvm_ptc_g { - unsigned long vaddr; - unsigned long rr; - unsigned long ps; - struct kvm_vcpu *vcpu; -}; - -/*Exit control data */ -struct exit_ctl_data{ - uint32_t exit_reason; - uint32_t vm_status; - union { - struct kvm_mmio_req ioreq; - struct kvm_pal_call pal_data; - struct kvm_sal_call sal_data; - struct kvm_switch_rr6 rr_data; - struct kvm_ipi_data ipi_data; - struct kvm_ptc_g ptc_g_data; - } u; -}; - -union pte_flags { - unsigned long val; - struct { - unsigned long p : 1; /*0 */ - unsigned long : 1; /* 1 */ - unsigned long ma : 3; /* 2-4 */ - unsigned long a : 1; /* 5 */ - unsigned long d : 1; /* 6 */ - unsigned long pl : 2; /* 7-8 */ - unsigned long ar : 3; /* 9-11 */ - unsigned long ppn : 38; /* 12-49 */ - unsigned long : 2; /* 50-51 */ - unsigned long ed : 1; /* 52 */ - }; -}; - -union ia64_pta { - unsigned long val; - struct { - unsigned long ve : 1; - unsigned long reserved0 : 1; - unsigned long size : 6; - unsigned long vf : 1; - unsigned long reserved1 : 6; - unsigned long base : 49; - }; -}; - -struct thash_cb { - /* THASH base information */ - struct thash_data *hash; /* hash table pointer */ - union ia64_pta pta; - int num; -}; - -struct kvm_vcpu_stat { - u32 halt_wakeup; -}; - -struct kvm_vcpu_arch { - int launched; - int last_exit; - int last_run_cpu; - int vmm_tr_slot; - int vm_tr_slot; - int sn_rtc_tr_slot; - -#define KVM_MP_STATE_RUNNABLE 0 -#define KVM_MP_STATE_UNINITIALIZED 1 -#define KVM_MP_STATE_INIT_RECEIVED 2 -#define KVM_MP_STATE_HALTED 3 - int mp_state; - -#define MAX_PTC_G_NUM 3 - int ptc_g_count; - struct kvm_ptc_g ptc_g_data[MAX_PTC_G_NUM]; - - /*halt timer to wake up sleepy vcpus*/ - struct hrtimer hlt_timer; - long ht_active; - - struct kvm_lapic *apic; /* kernel irqchip context */ - struct vpd *vpd; - - /* Exit data for vmm_transition*/ - struct exit_ctl_data exit_data; - - cpumask_t cache_coherent_map; - - unsigned long vmm_rr; - unsigned long host_rr6; - unsigned long psbits[8]; - unsigned long cr_iipa; - unsigned long cr_isr; - unsigned long vsa_base; - unsigned long dirty_log_lock_pa; - unsigned long __gp; - /* TR and TC. */ - struct thash_data itrs[NITRS]; - struct thash_data dtrs[NDTRS]; - /* Bit is set if there is a tr/tc for the region. */ - unsigned char itr_regions; - unsigned char dtr_regions; - unsigned char tc_regions; - /* purge all */ - unsigned long ptce_base; - unsigned long ptce_count[2]; - unsigned long ptce_stride[2]; - /* itc/itm */ - unsigned long last_itc; - long itc_offset; - unsigned long itc_check; - unsigned long timer_check; - unsigned int timer_pending; - unsigned int timer_fired; - - unsigned long vrr[8]; - unsigned long ibr[8]; - unsigned long dbr[8]; - unsigned long insvc[4]; /* Interrupt in service. */ - unsigned long xtp; - - unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ - unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ - unsigned long metaphysical_saved_rr0; /* from kvm_arch */ - unsigned long metaphysical_saved_rr4; /* from kvm_arch */ - unsigned long fp_psr; /*used for lazy float register */ - unsigned long saved_gp; - /*for phycial emulation */ - int mode_flags; - struct thash_cb vtlb; - struct thash_cb vhpt; - char irq_check; - char irq_new_pending; - - unsigned long opcode; - unsigned long cause; - char log_buf[VMM_LOG_LEN]; - union context host; - union context guest; - - char mmio_data[8]; -}; - -struct kvm_vm_stat { - u64 remote_tlb_flush; -}; - -struct kvm_sal_data { - unsigned long boot_ip; - unsigned long boot_gp; -}; - -struct kvm_arch_memory_slot { -}; - -struct kvm_arch { - spinlock_t dirty_log_lock; - - unsigned long vm_base; - unsigned long metaphysical_rr0; - unsigned long metaphysical_rr4; - unsigned long vmm_init_rr; - - int is_sn2; - - struct kvm_ioapic *vioapic; - struct kvm_vm_stat stat; - struct kvm_sal_data rdv_sal_data; - - struct list_head assigned_dev_head; - struct iommu_domain *iommu_domain; - bool iommu_noncoherent; - - unsigned long irq_sources_bitmap; - unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; -}; - -union cpuid3_t { - u64 value; - struct { - u64 number : 8; - u64 revision : 8; - u64 model : 8; - u64 family : 8; - u64 archrev : 8; - u64 rv : 24; - }; -}; - -struct kvm_pt_regs { - /* The following registers are saved by SAVE_MIN: */ - unsigned long b6; /* scratch */ - unsigned long b7; /* scratch */ - - unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */ - unsigned long ar_ssd; /* reserved for future use (scratch) */ - - unsigned long r8; /* scratch (return value register 0) */ - unsigned long r9; /* scratch (return value register 1) */ - unsigned long r10; /* scratch (return value register 2) */ - unsigned long r11; /* scratch (return value register 3) */ - - unsigned long cr_ipsr; /* interrupted task's psr */ - unsigned long cr_iip; /* interrupted task's instruction pointer */ - unsigned long cr_ifs; /* interrupted task's function state */ - - unsigned long ar_unat; /* interrupted task's NaT register (preserved) */ - unsigned long ar_pfs; /* prev function state */ - unsigned long ar_rsc; /* RSE configuration */ - /* The following two are valid only if cr_ipsr.cpl > 0: */ - unsigned long ar_rnat; /* RSE NaT */ - unsigned long ar_bspstore; /* RSE bspstore */ - - unsigned long pr; /* 64 predicate registers (1 bit each) */ - unsigned long b0; /* return pointer (bp) */ - unsigned long loadrs; /* size of dirty partition << 16 */ - - unsigned long r1; /* the gp pointer */ - unsigned long r12; /* interrupted task's memory stack pointer */ - unsigned long r13; /* thread pointer */ - - unsigned long ar_fpsr; /* floating point status (preserved) */ - unsigned long r15; /* scratch */ - - /* The remaining registers are NOT saved for system calls. */ - unsigned long r14; /* scratch */ - unsigned long r2; /* scratch */ - unsigned long r3; /* scratch */ - unsigned long r16; /* scratch */ - unsigned long r17; /* scratch */ - unsigned long r18; /* scratch */ - unsigned long r19; /* scratch */ - unsigned long r20; /* scratch */ - unsigned long r21; /* scratch */ - unsigned long r22; /* scratch */ - unsigned long r23; /* scratch */ - unsigned long r24; /* scratch */ - unsigned long r25; /* scratch */ - unsigned long r26; /* scratch */ - unsigned long r27; /* scratch */ - unsigned long r28; /* scratch */ - unsigned long r29; /* scratch */ - unsigned long r30; /* scratch */ - unsigned long r31; /* scratch */ - unsigned long ar_ccv; /* compare/exchange value (scratch) */ - - /* - * Floating point registers that the kernel considers scratch: - */ - struct ia64_fpreg f6; /* scratch */ - struct ia64_fpreg f7; /* scratch */ - struct ia64_fpreg f8; /* scratch */ - struct ia64_fpreg f9; /* scratch */ - struct ia64_fpreg f10; /* scratch */ - struct ia64_fpreg f11; /* scratch */ - - unsigned long r4; /* preserved */ - unsigned long r5; /* preserved */ - unsigned long r6; /* preserved */ - unsigned long r7; /* preserved */ - unsigned long eml_unat; /* used for emulating instruction */ - unsigned long pad0; /* alignment pad */ -}; - -static inline struct kvm_pt_regs *vcpu_regs(struct kvm_vcpu *v) -{ - return (struct kvm_pt_regs *) ((unsigned long) v + KVM_STK_OFFSET) - 1; -} - -typedef int kvm_vmm_entry(void); -typedef void kvm_tramp_entry(union context *host, union context *guest); - -struct kvm_vmm_info{ - struct module *module; - kvm_vmm_entry *vmm_entry; - kvm_tramp_entry *tramp_entry; - unsigned long vmm_ivt; - unsigned long patch_mov_ar; - unsigned long patch_mov_ar_sn2; -}; - -int kvm_highest_pending_irq(struct kvm_vcpu *vcpu); -int kvm_emulate_halt(struct kvm_vcpu *vcpu); -int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); -void kvm_sal_emul(struct kvm_vcpu *vcpu); - -#define __KVM_HAVE_ARCH_VM_ALLOC 1 -struct kvm *kvm_arch_alloc_vm(void); -void kvm_arch_free_vm(struct kvm *kvm); - -static inline void kvm_arch_sync_events(struct kvm *kvm) {} -static inline void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) {} -static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu) {} -static inline void kvm_arch_free_memslot(struct kvm *kvm, - struct kvm_memory_slot *free, struct kvm_memory_slot *dont) {} -static inline void kvm_arch_memslots_updated(struct kvm *kvm) {} -static inline void kvm_arch_commit_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - const struct kvm_memory_slot *old, - enum kvm_mr_change change) {} -static inline void kvm_arch_hardware_unsetup(void) {} - -#endif /* __ASSEMBLY__*/ - -#endif diff --git a/arch/ia64/include/asm/pvclock-abi.h b/arch/ia64/include/asm/pvclock-abi.h deleted file mode 100644 index 42b233bedeb5..000000000000 --- a/arch/ia64/include/asm/pvclock-abi.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * same structure to x86's - * Hopefully asm-x86/pvclock-abi.h would be moved to somewhere more generic. - * For now, define same duplicated definitions. - */ - -#ifndef _ASM_IA64__PVCLOCK_ABI_H -#define _ASM_IA64__PVCLOCK_ABI_H -#ifndef __ASSEMBLY__ - -/* - * These structs MUST NOT be changed. - * They are the ABI between hypervisor and guest OS. - * KVM is using this. - * - * pvclock_vcpu_time_info holds the system time and the tsc timestamp - * of the last update. So the guest can use the tsc delta to get a - * more precise system time. There is one per virtual cpu. - * - * pvclock_wall_clock references the point in time when the system - * time was zero (usually boot time), thus the guest calculates the - * current wall clock by adding the system time. - * - * Protocol for the "version" fields is: hypervisor raises it (making - * it uneven) before it starts updating the fields and raises it again - * (making it even) when it is done. Thus the guest can make sure the - * time values it got are consistent by checking the version before - * and after reading them. - */ - -struct pvclock_vcpu_time_info { - u32 version; - u32 pad0; - u64 tsc_timestamp; - u64 system_time; - u32 tsc_to_system_mul; - s8 tsc_shift; - u8 pad[3]; -} __attribute__((__packed__)); /* 32 bytes */ - -struct pvclock_wall_clock { - u32 version; - u32 sec; - u32 nsec; -} __attribute__((__packed__)); - -#endif /* __ASSEMBLY__ */ -#endif /* _ASM_IA64__PVCLOCK_ABI_H */ diff --git a/arch/ia64/include/uapi/asm/kvm.h b/arch/ia64/include/uapi/asm/kvm.h deleted file mode 100644 index 99503c284400..000000000000 --- a/arch/ia64/include/uapi/asm/kvm.h +++ /dev/null @@ -1,268 +0,0 @@ -#ifndef __ASM_IA64_KVM_H -#define __ASM_IA64_KVM_H - -/* - * kvm structure definitions for ia64 - * - * Copyright (C) 2007 Xiantao Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include -#include - -/* Select x86 specific features in */ -#define __KVM_HAVE_IOAPIC -#define __KVM_HAVE_IRQ_LINE - -/* Architectural interrupt line count. */ -#define KVM_NR_INTERRUPTS 256 - -#define KVM_IOAPIC_NUM_PINS 48 - -struct kvm_ioapic_state { - __u64 base_address; - __u32 ioregsel; - __u32 id; - __u32 irr; - __u32 pad; - union { - __u64 bits; - struct { - __u8 vector; - __u8 delivery_mode:3; - __u8 dest_mode:1; - __u8 delivery_status:1; - __u8 polarity:1; - __u8 remote_irr:1; - __u8 trig_mode:1; - __u8 mask:1; - __u8 reserve:7; - __u8 reserved[4]; - __u8 dest_id; - } fields; - } redirtbl[KVM_IOAPIC_NUM_PINS]; -}; - -#define KVM_IRQCHIP_PIC_MASTER 0 -#define KVM_IRQCHIP_PIC_SLAVE 1 -#define KVM_IRQCHIP_IOAPIC 2 -#define KVM_NR_IRQCHIPS 3 - -#define KVM_CONTEXT_SIZE 8*1024 - -struct kvm_fpreg { - union { - unsigned long bits[2]; - long double __dummy; /* force 16-byte alignment */ - } u; -}; - -union context { - /* 8K size */ - char dummy[KVM_CONTEXT_SIZE]; - struct { - unsigned long psr; - unsigned long pr; - unsigned long caller_unat; - unsigned long pad; - unsigned long gr[32]; - unsigned long ar[128]; - unsigned long br[8]; - unsigned long cr[128]; - unsigned long rr[8]; - unsigned long ibr[8]; - unsigned long dbr[8]; - unsigned long pkr[8]; - struct kvm_fpreg fr[128]; - }; -}; - -struct thash_data { - union { - struct { - unsigned long p : 1; /* 0 */ - unsigned long rv1 : 1; /* 1 */ - unsigned long ma : 3; /* 2-4 */ - unsigned long a : 1; /* 5 */ - unsigned long d : 1; /* 6 */ - unsigned long pl : 2; /* 7-8 */ - unsigned long ar : 3; /* 9-11 */ - unsigned long ppn : 38; /* 12-49 */ - unsigned long rv2 : 2; /* 50-51 */ - unsigned long ed : 1; /* 52 */ - unsigned long ig1 : 11; /* 53-63 */ - }; - struct { - unsigned long __rv1 : 53; /* 0-52 */ - unsigned long contiguous : 1; /*53 */ - unsigned long tc : 1; /* 54 TR or TC */ - unsigned long cl : 1; - /* 55 I side or D side cache line */ - unsigned long len : 4; /* 56-59 */ - unsigned long io : 1; /* 60 entry is for io or not */ - unsigned long nomap : 1; - /* 61 entry cann't be inserted into machine TLB.*/ - unsigned long checked : 1; - /* 62 for VTLB/VHPT sanity check */ - unsigned long invalid : 1; - /* 63 invalid entry */ - }; - unsigned long page_flags; - }; /* same for VHPT and TLB */ - - union { - struct { - unsigned long rv3 : 2; - unsigned long ps : 6; - unsigned long key : 24; - unsigned long rv4 : 32; - }; - unsigned long itir; - }; - union { - struct { - unsigned long ig2 : 12; - unsigned long vpn : 49; - unsigned long vrn : 3; - }; - unsigned long ifa; - unsigned long vadr; - struct { - unsigned long tag : 63; - unsigned long ti : 1; - }; - unsigned long etag; - }; - union { - struct thash_data *next; - unsigned long rid; - unsigned long gpaddr; - }; -}; - -#define NITRS 8 -#define NDTRS 8 - -struct saved_vpd { - unsigned long vhpi; - unsigned long vgr[16]; - unsigned long vbgr[16]; - unsigned long vnat; - unsigned long vbnat; - unsigned long vcpuid[5]; - unsigned long vpsr; - unsigned long vpr; - union { - unsigned long vcr[128]; - struct { - unsigned long dcr; - unsigned long itm; - unsigned long iva; - unsigned long rsv1[5]; - unsigned long pta; - unsigned long rsv2[7]; - unsigned long ipsr; - unsigned long isr; - unsigned long rsv3; - unsigned long iip; - unsigned long ifa; - unsigned long itir; - unsigned long iipa; - unsigned long ifs; - unsigned long iim; - unsigned long iha; - unsigned long rsv4[38]; - unsigned long lid; - unsigned long ivr; - unsigned long tpr; - unsigned long eoi; - unsigned long irr[4]; - unsigned long itv; - unsigned long pmv; - unsigned long cmcv; - unsigned long rsv5[5]; - unsigned long lrr0; - unsigned long lrr1; - unsigned long rsv6[46]; - }; - }; -}; - -struct kvm_regs { - struct saved_vpd vpd; - /*Arch-regs*/ - int mp_state; - unsigned long vmm_rr; - /* TR and TC. */ - struct thash_data itrs[NITRS]; - struct thash_data dtrs[NDTRS]; - /* Bit is set if there is a tr/tc for the region. */ - unsigned char itr_regions; - unsigned char dtr_regions; - unsigned char tc_regions; - - char irq_check; - unsigned long saved_itc; - unsigned long itc_check; - unsigned long timer_check; - unsigned long timer_pending; - unsigned long last_itc; - - unsigned long vrr[8]; - unsigned long ibr[8]; - unsigned long dbr[8]; - unsigned long insvc[4]; /* Interrupt in service. */ - unsigned long xtp; - - unsigned long metaphysical_rr0; /* from kvm_arch (so is pinned) */ - unsigned long metaphysical_rr4; /* from kvm_arch (so is pinned) */ - unsigned long metaphysical_saved_rr0; /* from kvm_arch */ - unsigned long metaphysical_saved_rr4; /* from kvm_arch */ - unsigned long fp_psr; /*used for lazy float register */ - unsigned long saved_gp; - /*for phycial emulation */ - - union context saved_guest; - - unsigned long reserved[64]; /* for future use */ -}; - -struct kvm_sregs { -}; - -struct kvm_fpu { -}; - -#define KVM_IA64_VCPU_STACK_SHIFT 16 -#define KVM_IA64_VCPU_STACK_SIZE (1UL << KVM_IA64_VCPU_STACK_SHIFT) - -struct kvm_ia64_vcpu_stack { - unsigned char stack[KVM_IA64_VCPU_STACK_SIZE]; -}; - -struct kvm_debug_exit_arch { -}; - -/* for KVM_SET_GUEST_DEBUG */ -struct kvm_guest_debug_arch { -}; - -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - -#endif diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig deleted file mode 100644 index 3d50ea955c4c..000000000000 --- a/arch/ia64/kvm/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -# -# KVM configuration -# - -source "virt/kvm/Kconfig" - -menuconfig VIRTUALIZATION - bool "Virtualization" - depends on HAVE_KVM || IA64 - default y - ---help--- - Say Y here to get to see options for using your Linux host to run other - operating systems inside virtual machines (guests). - This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if VIRTUALIZATION - -config KVM - tristate "Kernel-based Virtual Machine (KVM) support" - depends on BROKEN - depends on HAVE_KVM && MODULES - depends on BROKEN - select PREEMPT_NOTIFIERS - select ANON_INODES - select HAVE_KVM_IRQCHIP - select HAVE_KVM_IRQFD - select HAVE_KVM_IRQ_ROUTING - select KVM_APIC_ARCHITECTURE - select KVM_MMIO - ---help--- - Support hosting fully virtualized guest machines using hardware - virtualization extensions. You will need a fairly recent - processor equipped with virtualization extensions. You will also - need to select one or more of the processor modules below. - - This module provides access to the hardware capabilities through - a character device node named /dev/kvm. - - To compile this as a module, choose M here: the module - will be called kvm. - - If unsure, say N. - -config KVM_INTEL - tristate "KVM for Intel Itanium 2 processors support" - depends on KVM && m - ---help--- - Provides support for KVM on Itanium 2 processors equipped with the VT - extensions. - -config KVM_DEVICE_ASSIGNMENT - bool "KVM legacy PCI device assignment support" - depends on KVM && PCI && IOMMU_API - default y - ---help--- - Provide support for legacy PCI device assignment through KVM. The - kernel now also supports a full featured userspace device driver - framework through VFIO, which supersedes much of this support. - - If unsure, say Y. - -source drivers/vhost/Kconfig - -endif # VIRTUALIZATION diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile deleted file mode 100644 index 18e45ec49bbf..000000000000 --- a/arch/ia64/kvm/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -#This Make file is to generate asm-offsets.h and build source. -# - -#Generate asm-offsets.h for vmm module build -offsets-file := asm-offsets.h - -always := $(offsets-file) -targets := $(offsets-file) -targets += arch/ia64/kvm/asm-offsets.s - -# Default sed regexp - multiline due to syntax constraints -define sed-y - "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}" -endef - -quiet_cmd_offsets = GEN $@ -define cmd_offsets - (set -e; \ - echo "#ifndef __ASM_KVM_OFFSETS_H__"; \ - echo "#define __ASM_KVM_OFFSETS_H__"; \ - echo "/*"; \ - echo " * DO NOT MODIFY."; \ - echo " *"; \ - echo " * This file was generated by Makefile"; \ - echo " *"; \ - echo " */"; \ - echo ""; \ - sed -ne $(sed-y) $<; \ - echo ""; \ - echo "#endif" ) > $@ -endef - -# We use internal rules to avoid the "is up to date" message from make -arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c \ - $(wildcard $(srctree)/arch/ia64/include/asm/*.h)\ - $(wildcard $(srctree)/include/linux/*.h) - $(call if_changed_dep,cc_s_c) - -$(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s - $(call cmd,offsets) - -FORCE : $(obj)/$(offsets-file) - -# -# Makefile for Kernel-based Virtual Machine module -# - -ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ -asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/ -KVM := ../../../virt/kvm - -common-objs = $(KVM)/kvm_main.o $(KVM)/ioapic.o \ - $(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o - -ifeq ($(CONFIG_KVM_DEVICE_ASSIGNMENT),y) -common-objs += $(KVM)/assigned-dev.o $(KVM)/iommu.o -endif - -kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o -obj-$(CONFIG_KVM) += kvm.o - -CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 -kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ - vtlb.o process.o kvm_lib.o -#Add link memcpy and memset to avoid possible structure assignment error -kvm-intel-objs += memcpy.o memset.o -obj-$(CONFIG_KVM_INTEL) += kvm-intel.o diff --git a/arch/ia64/kvm/asm-offsets.c b/arch/ia64/kvm/asm-offsets.c deleted file mode 100644 index 9324c875caf5..000000000000 --- a/arch/ia64/kvm/asm-offsets.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * asm-offsets.c Generate definitions needed by assembly language modules. - * This code generates raw asm output which is post-processed - * to extract and format the required data. - * - * Anthony Xu - * Xiantao Zhang - * Copyright (c) 2007 Intel Corporation KVM support. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include -#include - -#include "vcpu.h" - -void foo(void) -{ - DEFINE(VMM_TASK_SIZE, sizeof(struct kvm_vcpu)); - DEFINE(VMM_PT_REGS_SIZE, sizeof(struct kvm_pt_regs)); - - BLANK(); - - DEFINE(VMM_VCPU_META_RR0_OFFSET, - offsetof(struct kvm_vcpu, arch.metaphysical_rr0)); - DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET, - offsetof(struct kvm_vcpu, - arch.metaphysical_saved_rr0)); - DEFINE(VMM_VCPU_VRR0_OFFSET, - offsetof(struct kvm_vcpu, arch.vrr[0])); - DEFINE(VMM_VPD_IRR0_OFFSET, - offsetof(struct vpd, irr[0])); - DEFINE(VMM_VCPU_ITC_CHECK_OFFSET, - offsetof(struct kvm_vcpu, arch.itc_check)); - DEFINE(VMM_VCPU_IRQ_CHECK_OFFSET, - offsetof(struct kvm_vcpu, arch.irq_check)); - DEFINE(VMM_VPD_VHPI_OFFSET, - offsetof(struct vpd, vhpi)); - DEFINE(VMM_VCPU_VSA_BASE_OFFSET, - offsetof(struct kvm_vcpu, arch.vsa_base)); - DEFINE(VMM_VCPU_VPD_OFFSET, - offsetof(struct kvm_vcpu, arch.vpd)); - DEFINE(VMM_VCPU_IRQ_CHECK, - offsetof(struct kvm_vcpu, arch.irq_check)); - DEFINE(VMM_VCPU_TIMER_PENDING, - offsetof(struct kvm_vcpu, arch.timer_pending)); - DEFINE(VMM_VCPU_META_SAVED_RR0_OFFSET, - offsetof(struct kvm_vcpu, arch.metaphysical_saved_rr0)); - DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET, - offsetof(struct kvm_vcpu, arch.mode_flags)); - DEFINE(VMM_VCPU_ITC_OFS_OFFSET, - offsetof(struct kvm_vcpu, arch.itc_offset)); - DEFINE(VMM_VCPU_LAST_ITC_OFFSET, - offsetof(struct kvm_vcpu, arch.last_itc)); - DEFINE(VMM_VCPU_SAVED_GP_OFFSET, - offsetof(struct kvm_vcpu, arch.saved_gp)); - - BLANK(); - - DEFINE(VMM_PT_REGS_B6_OFFSET, - offsetof(struct kvm_pt_regs, b6)); - DEFINE(VMM_PT_REGS_B7_OFFSET, - offsetof(struct kvm_pt_regs, b7)); - DEFINE(VMM_PT_REGS_AR_CSD_OFFSET, - offsetof(struct kvm_pt_regs, ar_csd)); - DEFINE(VMM_PT_REGS_AR_SSD_OFFSET, - offsetof(struct kvm_pt_regs, ar_ssd)); - DEFINE(VMM_PT_REGS_R8_OFFSET, - offsetof(struct kvm_pt_regs, r8)); - DEFINE(VMM_PT_REGS_R9_OFFSET, - offsetof(struct kvm_pt_regs, r9)); - DEFINE(VMM_PT_REGS_R10_OFFSET, - offsetof(struct kvm_pt_regs, r10)); - DEFINE(VMM_PT_REGS_R11_OFFSET, - offsetof(struct kvm_pt_regs, r11)); - DEFINE(VMM_PT_REGS_CR_IPSR_OFFSET, - offsetof(struct kvm_pt_regs, cr_ipsr)); - DEFINE(VMM_PT_REGS_CR_IIP_OFFSET, - offsetof(struct kvm_pt_regs, cr_iip)); - DEFINE(VMM_PT_REGS_CR_IFS_OFFSET, - offsetof(struct kvm_pt_regs, cr_ifs)); - DEFINE(VMM_PT_REGS_AR_UNAT_OFFSET, - offsetof(struct kvm_pt_regs, ar_unat)); - DEFINE(VMM_PT_REGS_AR_PFS_OFFSET, - offsetof(struct kvm_pt_regs, ar_pfs)); - DEFINE(VMM_PT_REGS_AR_RSC_OFFSET, - offsetof(struct kvm_pt_regs, ar_rsc)); - DEFINE(VMM_PT_REGS_AR_RNAT_OFFSET, - offsetof(struct kvm_pt_regs, ar_rnat)); - - DEFINE(VMM_PT_REGS_AR_BSPSTORE_OFFSET, - offsetof(struct kvm_pt_regs, ar_bspstore)); - DEFINE(VMM_PT_REGS_PR_OFFSET, - offsetof(struct kvm_pt_regs, pr)); - DEFINE(VMM_PT_REGS_B0_OFFSET, - offsetof(struct kvm_pt_regs, b0)); - DEFINE(VMM_PT_REGS_LOADRS_OFFSET, - offsetof(struct kvm_pt_regs, loadrs)); - DEFINE(VMM_PT_REGS_R1_OFFSET, - offsetof(struct kvm_pt_regs, r1)); - DEFINE(VMM_PT_REGS_R12_OFFSET, - offsetof(struct kvm_pt_regs, r12)); - DEFINE(VMM_PT_REGS_R13_OFFSET, - offsetof(struct kvm_pt_regs, r13)); - DEFINE(VMM_PT_REGS_AR_FPSR_OFFSET, - offsetof(struct kvm_pt_regs, ar_fpsr)); - DEFINE(VMM_PT_REGS_R15_OFFSET, - offsetof(struct kvm_pt_regs, r15)); - DEFINE(VMM_PT_REGS_R14_OFFSET, - offsetof(struct kvm_pt_regs, r14)); - DEFINE(VMM_PT_REGS_R2_OFFSET, - offsetof(struct kvm_pt_regs, r2)); - DEFINE(VMM_PT_REGS_R3_OFFSET, - offsetof(struct kvm_pt_regs, r3)); - DEFINE(VMM_PT_REGS_R16_OFFSET, - offsetof(struct kvm_pt_regs, r16)); - DEFINE(VMM_PT_REGS_R17_OFFSET, - offsetof(struct kvm_pt_regs, r17)); - DEFINE(VMM_PT_REGS_R18_OFFSET, - offsetof(struct kvm_pt_regs, r18)); - DEFINE(VMM_PT_REGS_R19_OFFSET, - offsetof(struct kvm_pt_regs, r19)); - DEFINE(VMM_PT_REGS_R20_OFFSET, - offsetof(struct kvm_pt_regs, r20)); - DEFINE(VMM_PT_REGS_R21_OFFSET, - offsetof(struct kvm_pt_regs, r21)); - DEFINE(VMM_PT_REGS_R22_OFFSET, - offsetof(struct kvm_pt_regs, r22)); - DEFINE(VMM_PT_REGS_R23_OFFSET, - offsetof(struct kvm_pt_regs, r23)); - DEFINE(VMM_PT_REGS_R24_OFFSET, - offsetof(struct kvm_pt_regs, r24)); - DEFINE(VMM_PT_REGS_R25_OFFSET, - offsetof(struct kvm_pt_regs, r25)); - DEFINE(VMM_PT_REGS_R26_OFFSET, - offsetof(struct kvm_pt_regs, r26)); - DEFINE(VMM_PT_REGS_R27_OFFSET, - offsetof(struct kvm_pt_regs, r27)); - DEFINE(VMM_PT_REGS_R28_OFFSET, - offsetof(struct kvm_pt_regs, r28)); - DEFINE(VMM_PT_REGS_R29_OFFSET, - offsetof(struct kvm_pt_regs, r29)); - DEFINE(VMM_PT_REGS_R30_OFFSET, - offsetof(struct kvm_pt_regs, r30)); - DEFINE(VMM_PT_REGS_R31_OFFSET, - offsetof(struct kvm_pt_regs, r31)); - DEFINE(VMM_PT_REGS_AR_CCV_OFFSET, - offsetof(struct kvm_pt_regs, ar_ccv)); - DEFINE(VMM_PT_REGS_F6_OFFSET, - offsetof(struct kvm_pt_regs, f6)); - DEFINE(VMM_PT_REGS_F7_OFFSET, - offsetof(struct kvm_pt_regs, f7)); - DEFINE(VMM_PT_REGS_F8_OFFSET, - offsetof(struct kvm_pt_regs, f8)); - DEFINE(VMM_PT_REGS_F9_OFFSET, - offsetof(struct kvm_pt_regs, f9)); - DEFINE(VMM_PT_REGS_F10_OFFSET, - offsetof(struct kvm_pt_regs, f10)); - DEFINE(VMM_PT_REGS_F11_OFFSET, - offsetof(struct kvm_pt_regs, f11)); - DEFINE(VMM_PT_REGS_R4_OFFSET, - offsetof(struct kvm_pt_regs, r4)); - DEFINE(VMM_PT_REGS_R5_OFFSET, - offsetof(struct kvm_pt_regs, r5)); - DEFINE(VMM_PT_REGS_R6_OFFSET, - offsetof(struct kvm_pt_regs, r6)); - DEFINE(VMM_PT_REGS_R7_OFFSET, - offsetof(struct kvm_pt_regs, r7)); - DEFINE(VMM_PT_REGS_EML_UNAT_OFFSET, - offsetof(struct kvm_pt_regs, eml_unat)); - DEFINE(VMM_VCPU_IIPA_OFFSET, - offsetof(struct kvm_vcpu, arch.cr_iipa)); - DEFINE(VMM_VCPU_OPCODE_OFFSET, - offsetof(struct kvm_vcpu, arch.opcode)); - DEFINE(VMM_VCPU_CAUSE_OFFSET, offsetof(struct kvm_vcpu, arch.cause)); - DEFINE(VMM_VCPU_ISR_OFFSET, - offsetof(struct kvm_vcpu, arch.cr_isr)); - DEFINE(VMM_PT_REGS_R16_SLOT, - (((offsetof(struct kvm_pt_regs, r16) - - sizeof(struct kvm_pt_regs)) >> 3) & 0x3f)); - DEFINE(VMM_VCPU_MODE_FLAGS_OFFSET, - offsetof(struct kvm_vcpu, arch.mode_flags)); - DEFINE(VMM_VCPU_GP_OFFSET, offsetof(struct kvm_vcpu, arch.__gp)); - BLANK(); - - DEFINE(VMM_VPD_BASE_OFFSET, offsetof(struct kvm_vcpu, arch.vpd)); - DEFINE(VMM_VPD_VIFS_OFFSET, offsetof(struct vpd, ifs)); - DEFINE(VMM_VLSAPIC_INSVC_BASE_OFFSET, - offsetof(struct kvm_vcpu, arch.insvc[0])); - DEFINE(VMM_VPD_VPTA_OFFSET, offsetof(struct vpd, pta)); - DEFINE(VMM_VPD_VPSR_OFFSET, offsetof(struct vpd, vpsr)); - - DEFINE(VMM_CTX_R4_OFFSET, offsetof(union context, gr[4])); - DEFINE(VMM_CTX_R5_OFFSET, offsetof(union context, gr[5])); - DEFINE(VMM_CTX_R12_OFFSET, offsetof(union context, gr[12])); - DEFINE(VMM_CTX_R13_OFFSET, offsetof(union context, gr[13])); - DEFINE(VMM_CTX_KR0_OFFSET, offsetof(union context, ar[0])); - DEFINE(VMM_CTX_KR1_OFFSET, offsetof(union context, ar[1])); - DEFINE(VMM_CTX_B0_OFFSET, offsetof(union context, br[0])); - DEFINE(VMM_CTX_B1_OFFSET, offsetof(union context, br[1])); - DEFINE(VMM_CTX_B2_OFFSET, offsetof(union context, br[2])); - DEFINE(VMM_CTX_RR0_OFFSET, offsetof(union context, rr[0])); - DEFINE(VMM_CTX_RSC_OFFSET, offsetof(union context, ar[16])); - DEFINE(VMM_CTX_BSPSTORE_OFFSET, offsetof(union context, ar[18])); - DEFINE(VMM_CTX_RNAT_OFFSET, offsetof(union context, ar[19])); - DEFINE(VMM_CTX_FCR_OFFSET, offsetof(union context, ar[21])); - DEFINE(VMM_CTX_EFLAG_OFFSET, offsetof(union context, ar[24])); - DEFINE(VMM_CTX_CFLG_OFFSET, offsetof(union context, ar[27])); - DEFINE(VMM_CTX_FSR_OFFSET, offsetof(union context, ar[28])); - DEFINE(VMM_CTX_FIR_OFFSET, offsetof(union context, ar[29])); - DEFINE(VMM_CTX_FDR_OFFSET, offsetof(union context, ar[30])); - DEFINE(VMM_CTX_UNAT_OFFSET, offsetof(union context, ar[36])); - DEFINE(VMM_CTX_FPSR_OFFSET, offsetof(union context, ar[40])); - DEFINE(VMM_CTX_PFS_OFFSET, offsetof(union context, ar[64])); - DEFINE(VMM_CTX_LC_OFFSET, offsetof(union context, ar[65])); - DEFINE(VMM_CTX_DCR_OFFSET, offsetof(union context, cr[0])); - DEFINE(VMM_CTX_IVA_OFFSET, offsetof(union context, cr[2])); - DEFINE(VMM_CTX_PTA_OFFSET, offsetof(union context, cr[8])); - DEFINE(VMM_CTX_IBR0_OFFSET, offsetof(union context, ibr[0])); - DEFINE(VMM_CTX_DBR0_OFFSET, offsetof(union context, dbr[0])); - DEFINE(VMM_CTX_F2_OFFSET, offsetof(union context, fr[2])); - DEFINE(VMM_CTX_F3_OFFSET, offsetof(union context, fr[3])); - DEFINE(VMM_CTX_F32_OFFSET, offsetof(union context, fr[32])); - DEFINE(VMM_CTX_F33_OFFSET, offsetof(union context, fr[33])); - DEFINE(VMM_CTX_PKR0_OFFSET, offsetof(union context, pkr[0])); - DEFINE(VMM_CTX_PSR_OFFSET, offsetof(union context, psr)); - BLANK(); -} diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h deleted file mode 100644 index c0785a728271..000000000000 --- a/arch/ia64/kvm/irq.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * irq.h: In-kernel interrupt controller related definitions - * Copyright (c) 2008, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * 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. - * - * Authors: - * Xiantao Zhang - * - */ - -#ifndef __IRQ_H -#define __IRQ_H - -#include "lapic.h" - -static inline int irqchip_in_kernel(struct kvm *kvm) -{ - return 1; -} - -#endif diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c deleted file mode 100644 index ec6b9acb6bea..000000000000 --- a/arch/ia64/kvm/kvm-ia64.c +++ /dev/null @@ -1,1942 +0,0 @@ -/* - * kvm_ia64.c: Basic KVM support On Itanium series processors - * - * - * Copyright (C) 2007, Intel Corporation. - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "misc.h" -#include "vti.h" -#include "iodev.h" -#include "ioapic.h" -#include "lapic.h" -#include "irq.h" - -static unsigned long kvm_vmm_base; -static unsigned long kvm_vsa_base; -static unsigned long kvm_vm_buffer; -static unsigned long kvm_vm_buffer_size; -unsigned long kvm_vmm_gp; - -static long vp_env_info; - -static struct kvm_vmm_info *kvm_vmm_info; - -static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu); - -struct kvm_stats_debugfs_item debugfs_entries[] = { - { NULL } -}; - -static unsigned long kvm_get_itc(struct kvm_vcpu *vcpu) -{ -#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) - if (vcpu->kvm->arch.is_sn2) - return rtc_time(); - else -#endif - return ia64_getreg(_IA64_REG_AR_ITC); -} - -static void kvm_flush_icache(unsigned long start, unsigned long len) -{ - int l; - - for (l = 0; l < (len + 32); l += 32) - ia64_fc((void *)(start + l)); - - ia64_sync_i(); - ia64_srlz_i(); -} - -static void kvm_flush_tlb_all(void) -{ - unsigned long i, j, count0, count1, stride0, stride1, addr; - long flags; - - addr = local_cpu_data->ptce_base; - count0 = local_cpu_data->ptce_count[0]; - count1 = local_cpu_data->ptce_count[1]; - stride0 = local_cpu_data->ptce_stride[0]; - stride1 = local_cpu_data->ptce_stride[1]; - - local_irq_save(flags); - for (i = 0; i < count0; ++i) { - for (j = 0; j < count1; ++j) { - ia64_ptce(addr); - addr += stride1; - } - addr += stride0; - } - local_irq_restore(flags); - ia64_srlz_i(); /* srlz.i implies srlz.d */ -} - -long ia64_pal_vp_create(u64 *vpd, u64 *host_iva, u64 *opt_handler) -{ - struct ia64_pal_retval iprv; - - PAL_CALL_STK(iprv, PAL_VP_CREATE, (u64)vpd, (u64)host_iva, - (u64)opt_handler); - - return iprv.status; -} - -static DEFINE_SPINLOCK(vp_lock); - -int kvm_arch_hardware_enable(void) -{ - long status; - long tmp_base; - unsigned long pte; - unsigned long saved_psr; - int slot; - - pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); - local_irq_save(saved_psr); - slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); - local_irq_restore(saved_psr); - if (slot < 0) - return -EINVAL; - - spin_lock(&vp_lock); - status = ia64_pal_vp_init_env(kvm_vsa_base ? - VP_INIT_ENV : VP_INIT_ENV_INITALIZE, - __pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base); - if (status != 0) { - spin_unlock(&vp_lock); - printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n"); - return -EINVAL; - } - - if (!kvm_vsa_base) { - kvm_vsa_base = tmp_base; - printk(KERN_INFO"kvm: kvm_vsa_base:0x%lx\n", kvm_vsa_base); - } - spin_unlock(&vp_lock); - ia64_ptr_entry(0x3, slot); - - return 0; -} - -void kvm_arch_hardware_disable(void) -{ - - long status; - int slot; - unsigned long pte; - unsigned long saved_psr; - unsigned long host_iva = ia64_getreg(_IA64_REG_CR_IVA); - - pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), - PAGE_KERNEL)); - - local_irq_save(saved_psr); - slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); - local_irq_restore(saved_psr); - if (slot < 0) - return; - - status = ia64_pal_vp_exit_env(host_iva); - if (status) - printk(KERN_DEBUG"kvm: Failed to disable VT support! :%ld\n", - status); - ia64_ptr_entry(0x3, slot); -} - -void kvm_arch_check_processor_compat(void *rtn) -{ - *(int *)rtn = 0; -} - -int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) -{ - - int r; - - switch (ext) { - case KVM_CAP_IRQCHIP: - case KVM_CAP_MP_STATE: - case KVM_CAP_IRQ_INJECT_STATUS: - case KVM_CAP_IOAPIC_POLARITY_IGNORED: - r = 1; - break; - case KVM_CAP_COALESCED_MMIO: - r = KVM_COALESCED_MMIO_PAGE_OFFSET; - break; -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT - case KVM_CAP_IOMMU: - r = iommu_present(&pci_bus_type); - break; -#endif - default: - r = 0; - } - return r; - -} - -static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = 1; - return 0; -} - -static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - struct kvm_mmio_req *p; - struct kvm_io_device *mmio_dev; - int r; - - p = kvm_get_vcpu_ioreq(vcpu); - - if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS) - goto mmio; - vcpu->mmio_needed = 1; - vcpu->mmio_fragments[0].gpa = kvm_run->mmio.phys_addr = p->addr; - vcpu->mmio_fragments[0].len = kvm_run->mmio.len = p->size; - vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir; - - if (vcpu->mmio_is_write) - memcpy(vcpu->arch.mmio_data, &p->data, p->size); - memcpy(kvm_run->mmio.data, &p->data, p->size); - kvm_run->exit_reason = KVM_EXIT_MMIO; - return 0; -mmio: - if (p->dir) - r = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, p->addr, - p->size, &p->data); - else - r = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, p->addr, - p->size, &p->data); - if (r) - printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr); - p->state = STATE_IORESP_READY; - - return 1; -} - -static int handle_pal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - - if (p->exit_reason == EXIT_REASON_PAL_CALL) - return kvm_pal_emul(vcpu, kvm_run); - else { - kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = 2; - return 0; - } -} - -static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - - if (p->exit_reason == EXIT_REASON_SAL_CALL) { - kvm_sal_emul(vcpu); - return 1; - } else { - kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = 3; - return 0; - } - -} - -static int __apic_accept_irq(struct kvm_vcpu *vcpu, uint64_t vector) -{ - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - - if (!test_and_set_bit(vector, &vpd->irr[0])) { - vcpu->arch.irq_new_pending = 1; - kvm_vcpu_kick(vcpu); - return 1; - } - return 0; -} - -/* - * offset: address offset to IPI space. - * value: deliver value. - */ -static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm, - uint64_t vector) -{ - switch (dm) { - case SAPIC_FIXED: - break; - case SAPIC_NMI: - vector = 2; - break; - case SAPIC_EXTINT: - vector = 0; - break; - case SAPIC_INIT: - case SAPIC_PMI: - default: - printk(KERN_ERR"kvm: Unimplemented Deliver reserved IPI!\n"); - return; - } - __apic_accept_irq(vcpu, vector); -} - -static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id, - unsigned long eid) -{ - union ia64_lid lid; - int i; - struct kvm_vcpu *vcpu; - - kvm_for_each_vcpu(i, vcpu, kvm) { - lid.val = VCPU_LID(vcpu); - if (lid.id == id && lid.eid == eid) - return vcpu; - } - - return NULL; -} - -static int handle_ipi(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - struct exit_ctl_data *p = kvm_get_exit_data(vcpu); - struct kvm_vcpu *target_vcpu; - struct kvm_pt_regs *regs; - union ia64_ipi_a addr = p->u.ipi_data.addr; - union ia64_ipi_d data = p->u.ipi_data.data; - - target_vcpu = lid_to_vcpu(vcpu->kvm, addr.id, addr.eid); - if (!target_vcpu) - return handle_vm_error(vcpu, kvm_run); - - if (!target_vcpu->arch.launched) { - regs = vcpu_regs(target_vcpu); - - regs->cr_iip = vcpu->kvm->arch.rdv_sal_data.boot_ip; - regs->r1 = vcpu->kvm->arch.rdv_sal_data.boot_gp; - - target_vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; - if (waitqueue_active(&target_vcpu->wq)) - wake_up_interruptible(&target_vcpu->wq); - } else { - vcpu_deliver_ipi(target_vcpu, data.dm, data.vector); - if (target_vcpu != vcpu) - kvm_vcpu_kick(target_vcpu); - } - - return 1; -} - -struct call_data { - struct kvm_ptc_g ptc_g_data; - struct kvm_vcpu *vcpu; -}; - -static void vcpu_global_purge(void *info) -{ - struct call_data *p = (struct call_data *)info; - struct kvm_vcpu *vcpu = p->vcpu; - - if (test_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) - return; - - set_bit(KVM_REQ_PTC_G, &vcpu->requests); - if (vcpu->arch.ptc_g_count < MAX_PTC_G_NUM) { - vcpu->arch.ptc_g_data[vcpu->arch.ptc_g_count++] = - p->ptc_g_data; - } else { - clear_bit(KVM_REQ_PTC_G, &vcpu->requests); - vcpu->arch.ptc_g_count = 0; - set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests); - } -} - -static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - struct exit_ctl_data *p = kvm_get_exit_data(vcpu); - struct kvm *kvm = vcpu->kvm; - struct call_data call_data; - int i; - struct kvm_vcpu *vcpui; - - call_data.ptc_g_data = p->u.ptc_g_data; - - kvm_for_each_vcpu(i, vcpui, kvm) { - if (vcpui->arch.mp_state == KVM_MP_STATE_UNINITIALIZED || - vcpu == vcpui) - continue; - - if (waitqueue_active(&vcpui->wq)) - wake_up_interruptible(&vcpui->wq); - - if (vcpui->cpu != -1) { - call_data.vcpu = vcpui; - smp_call_function_single(vcpui->cpu, - vcpu_global_purge, &call_data, 1); - } else - printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); - - } - return 1; -} - -static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - return 1; -} - -static int kvm_sn2_setup_mappings(struct kvm_vcpu *vcpu) -{ - unsigned long pte, rtc_phys_addr, map_addr; - int slot; - - map_addr = KVM_VMM_BASE + (1UL << KVM_VMM_SHIFT); - rtc_phys_addr = LOCAL_MMR_OFFSET | SH_RTC; - pte = pte_val(mk_pte_phys(rtc_phys_addr, PAGE_KERNEL_UC)); - slot = ia64_itr_entry(0x3, map_addr, pte, PAGE_SHIFT); - vcpu->arch.sn_rtc_tr_slot = slot; - if (slot < 0) { - printk(KERN_ERR "Mayday mayday! RTC mapping failed!\n"); - slot = 0; - } - return slot; -} - -int kvm_emulate_halt(struct kvm_vcpu *vcpu) -{ - - ktime_t kt; - long itc_diff; - unsigned long vcpu_now_itc; - unsigned long expires; - struct hrtimer *p_ht = &vcpu->arch.hlt_timer; - unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec; - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - - if (irqchip_in_kernel(vcpu->kvm)) { - - vcpu_now_itc = kvm_get_itc(vcpu) + vcpu->arch.itc_offset; - - if (time_after(vcpu_now_itc, vpd->itm)) { - vcpu->arch.timer_check = 1; - return 1; - } - itc_diff = vpd->itm - vcpu_now_itc; - if (itc_diff < 0) - itc_diff = -itc_diff; - - expires = div64_u64(itc_diff, cyc_per_usec); - kt = ktime_set(0, 1000 * expires); - - vcpu->arch.ht_active = 1; - hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); - - vcpu->arch.mp_state = KVM_MP_STATE_HALTED; - kvm_vcpu_block(vcpu); - hrtimer_cancel(p_ht); - vcpu->arch.ht_active = 0; - - if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests) || - kvm_cpu_has_pending_timer(vcpu)) - if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; - - if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) - return -EINTR; - return 1; - } else { - printk(KERN_ERR"kvm: Unsupported userspace halt!"); - return 0; - } -} - -static int handle_vm_shutdown(struct kvm_vcpu *vcpu, - struct kvm_run *kvm_run) -{ - kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; - return 0; -} - -static int handle_external_interrupt(struct kvm_vcpu *vcpu, - struct kvm_run *kvm_run) -{ - return 1; -} - -static int handle_vcpu_debug(struct kvm_vcpu *vcpu, - struct kvm_run *kvm_run) -{ - printk("VMM: %s", vcpu->arch.log_buf); - return 1; -} - -static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu, - struct kvm_run *kvm_run) = { - [EXIT_REASON_VM_PANIC] = handle_vm_error, - [EXIT_REASON_MMIO_INSTRUCTION] = handle_mmio, - [EXIT_REASON_PAL_CALL] = handle_pal_call, - [EXIT_REASON_SAL_CALL] = handle_sal_call, - [EXIT_REASON_SWITCH_RR6] = handle_switch_rr6, - [EXIT_REASON_VM_DESTROY] = handle_vm_shutdown, - [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, - [EXIT_REASON_IPI] = handle_ipi, - [EXIT_REASON_PTC_G] = handle_global_purge, - [EXIT_REASON_DEBUG] = handle_vcpu_debug, - -}; - -static const int kvm_vti_max_exit_handlers = - sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); - -static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p_exit_data; - - p_exit_data = kvm_get_exit_data(vcpu); - return p_exit_data->exit_reason; -} - -/* - * The guest has exited. See if we can fix it or if we need userspace - * assistance. - */ -static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) -{ - u32 exit_reason = kvm_get_exit_reason(vcpu); - vcpu->arch.last_exit = exit_reason; - - if (exit_reason < kvm_vti_max_exit_handlers - && kvm_vti_exit_handlers[exit_reason]) - return kvm_vti_exit_handlers[exit_reason](vcpu, kvm_run); - else { - kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = exit_reason; - } - return 0; -} - -static inline void vti_set_rr6(unsigned long rr6) -{ - ia64_set_rr(RR6, rr6); - ia64_srlz_i(); -} - -static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu) -{ - unsigned long pte; - struct kvm *kvm = vcpu->kvm; - int r; - - /*Insert a pair of tr to map vmm*/ - pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL)); - r = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT); - if (r < 0) - goto out; - vcpu->arch.vmm_tr_slot = r; - /*Insert a pairt of tr to map data of vm*/ - pte = pte_val(mk_pte_phys(__pa(kvm->arch.vm_base), PAGE_KERNEL)); - r = ia64_itr_entry(0x3, KVM_VM_DATA_BASE, - pte, KVM_VM_DATA_SHIFT); - if (r < 0) - goto out; - vcpu->arch.vm_tr_slot = r; - -#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) - if (kvm->arch.is_sn2) { - r = kvm_sn2_setup_mappings(vcpu); - if (r < 0) - goto out; - } -#endif - - r = 0; -out: - return r; -} - -static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = vcpu->kvm; - ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot); - ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot); -#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC) - if (kvm->arch.is_sn2) - ia64_ptr_entry(0x3, vcpu->arch.sn_rtc_tr_slot); -#endif -} - -static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu) -{ - unsigned long psr; - int r; - int cpu = smp_processor_id(); - - if (vcpu->arch.last_run_cpu != cpu || - per_cpu(last_vcpu, cpu) != vcpu) { - per_cpu(last_vcpu, cpu) = vcpu; - vcpu->arch.last_run_cpu = cpu; - kvm_flush_tlb_all(); - } - - vcpu->arch.host_rr6 = ia64_get_rr(RR6); - vti_set_rr6(vcpu->arch.vmm_rr); - local_irq_save(psr); - r = kvm_insert_vmm_mapping(vcpu); - local_irq_restore(psr); - return r; -} - -static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu) -{ - kvm_purge_vmm_mapping(vcpu); - vti_set_rr6(vcpu->arch.host_rr6); -} - -static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - union context *host_ctx, *guest_ctx; - int r, idx; - - idx = srcu_read_lock(&vcpu->kvm->srcu); - -again: - if (signal_pending(current)) { - r = -EINTR; - kvm_run->exit_reason = KVM_EXIT_INTR; - goto out; - } - - preempt_disable(); - local_irq_disable(); - - /*Get host and guest context with guest address space.*/ - host_ctx = kvm_get_host_context(vcpu); - guest_ctx = kvm_get_guest_context(vcpu); - - clear_bit(KVM_REQ_KICK, &vcpu->requests); - - r = kvm_vcpu_pre_transition(vcpu); - if (r < 0) - goto vcpu_run_fail; - - srcu_read_unlock(&vcpu->kvm->srcu, idx); - vcpu->mode = IN_GUEST_MODE; - kvm_guest_enter(); - - /* - * Transition to the guest - */ - kvm_vmm_info->tramp_entry(host_ctx, guest_ctx); - - kvm_vcpu_post_transition(vcpu); - - vcpu->arch.launched = 1; - set_bit(KVM_REQ_KICK, &vcpu->requests); - local_irq_enable(); - - /* - * We must have an instruction between local_irq_enable() and - * kvm_guest_exit(), so the timer interrupt isn't delayed by - * the interrupt shadow. The stat.exits increment will do nicely. - * But we need to prevent reordering, hence this barrier(): - */ - barrier(); - kvm_guest_exit(); - vcpu->mode = OUTSIDE_GUEST_MODE; - preempt_enable(); - - idx = srcu_read_lock(&vcpu->kvm->srcu); - - r = kvm_handle_exit(kvm_run, vcpu); - - if (r > 0) { - if (!need_resched()) - goto again; - } - -out: - srcu_read_unlock(&vcpu->kvm->srcu, idx); - if (r > 0) { - cond_resched(); - idx = srcu_read_lock(&vcpu->kvm->srcu); - goto again; - } - - return r; - -vcpu_run_fail: - local_irq_enable(); - preempt_enable(); - kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; - goto out; -} - -static void kvm_set_mmio_data(struct kvm_vcpu *vcpu) -{ - struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu); - - if (!vcpu->mmio_is_write) - memcpy(&p->data, vcpu->arch.mmio_data, 8); - p->state = STATE_IORESP_READY; -} - -int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - int r; - sigset_t sigsaved; - - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); - - if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { - kvm_vcpu_block(vcpu); - clear_bit(KVM_REQ_UNHALT, &vcpu->requests); - r = -EAGAIN; - goto out; - } - - if (vcpu->mmio_needed) { - memcpy(vcpu->arch.mmio_data, kvm_run->mmio.data, 8); - kvm_set_mmio_data(vcpu); - vcpu->mmio_read_completed = 1; - vcpu->mmio_needed = 0; - } - r = __vcpu_run(vcpu, kvm_run); -out: - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &sigsaved, NULL); - - return r; -} - -struct kvm *kvm_arch_alloc_vm(void) -{ - - struct kvm *kvm; - uint64_t vm_base; - - BUG_ON(sizeof(struct kvm) > KVM_VM_STRUCT_SIZE); - - vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); - - if (!vm_base) - return NULL; - - memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); - kvm = (struct kvm *)(vm_base + - offsetof(struct kvm_vm_data, kvm_vm_struct)); - kvm->arch.vm_base = vm_base; - printk(KERN_DEBUG"kvm: vm's data area:0x%lx\n", vm_base); - - return kvm; -} - -struct kvm_ia64_io_range { - unsigned long start; - unsigned long size; - unsigned long type; -}; - -static const struct kvm_ia64_io_range io_ranges[] = { - {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, - {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, - {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, - {IO_SAPIC_START, IO_SAPIC_SIZE, GPFN_IOSAPIC}, - {PIB_START, PIB_SIZE, GPFN_PIB}, -}; - -static void kvm_build_io_pmt(struct kvm *kvm) -{ - unsigned long i, j; - - /* Mark I/O ranges */ - for (i = 0; i < (sizeof(io_ranges) / sizeof(struct kvm_io_range)); - i++) { - for (j = io_ranges[i].start; - j < io_ranges[i].start + io_ranges[i].size; - j += PAGE_SIZE) - kvm_set_pmt_entry(kvm, j >> PAGE_SHIFT, - io_ranges[i].type, 0); - } - -} - -/*Use unused rids to virtualize guest rid.*/ -#define GUEST_PHYSICAL_RR0 0x1739 -#define GUEST_PHYSICAL_RR4 0x2739 -#define VMM_INIT_RR 0x1660 - -int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) -{ - BUG_ON(!kvm); - - if (type) - return -EINVAL; - - kvm->arch.is_sn2 = ia64_platform_is("sn2"); - - kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0; - kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4; - kvm->arch.vmm_init_rr = VMM_INIT_RR; - - /* - *Fill P2M entries for MMIO/IO ranges - */ - kvm_build_io_pmt(kvm); - - INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); - - /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ - set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); - - return 0; -} - -static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, - struct kvm_irqchip *chip) -{ - int r; - - r = 0; - switch (chip->chip_id) { - case KVM_IRQCHIP_IOAPIC: - r = kvm_get_ioapic(kvm, &chip->chip.ioapic); - break; - default: - r = -EINVAL; - break; - } - return r; -} - -static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) -{ - int r; - - r = 0; - switch (chip->chip_id) { - case KVM_IRQCHIP_IOAPIC: - r = kvm_set_ioapic(kvm, &chip->chip.ioapic); - break; - default: - r = -EINVAL; - break; - } - return r; -} - -#define RESTORE_REGS(_x) vcpu->arch._x = regs->_x - -int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) -{ - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - int i; - - for (i = 0; i < 16; i++) { - vpd->vgr[i] = regs->vpd.vgr[i]; - vpd->vbgr[i] = regs->vpd.vbgr[i]; - } - for (i = 0; i < 128; i++) - vpd->vcr[i] = regs->vpd.vcr[i]; - vpd->vhpi = regs->vpd.vhpi; - vpd->vnat = regs->vpd.vnat; - vpd->vbnat = regs->vpd.vbnat; - vpd->vpsr = regs->vpd.vpsr; - - vpd->vpr = regs->vpd.vpr; - - memcpy(&vcpu->arch.guest, ®s->saved_guest, sizeof(union context)); - - RESTORE_REGS(mp_state); - RESTORE_REGS(vmm_rr); - memcpy(vcpu->arch.itrs, regs->itrs, sizeof(struct thash_data) * NITRS); - memcpy(vcpu->arch.dtrs, regs->dtrs, sizeof(struct thash_data) * NDTRS); - RESTORE_REGS(itr_regions); - RESTORE_REGS(dtr_regions); - RESTORE_REGS(tc_regions); - RESTORE_REGS(irq_check); - RESTORE_REGS(itc_check); - RESTORE_REGS(timer_check); - RESTORE_REGS(timer_pending); - RESTORE_REGS(last_itc); - for (i = 0; i < 8; i++) { - vcpu->arch.vrr[i] = regs->vrr[i]; - vcpu->arch.ibr[i] = regs->ibr[i]; - vcpu->arch.dbr[i] = regs->dbr[i]; - } - for (i = 0; i < 4; i++) - vcpu->arch.insvc[i] = regs->insvc[i]; - RESTORE_REGS(xtp); - RESTORE_REGS(metaphysical_rr0); - RESTORE_REGS(metaphysical_rr4); - RESTORE_REGS(metaphysical_saved_rr0); - RESTORE_REGS(metaphysical_saved_rr4); - RESTORE_REGS(fp_psr); - RESTORE_REGS(saved_gp); - - vcpu->arch.irq_new_pending = 1; - vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu); - set_bit(KVM_REQ_RESUME, &vcpu->requests); - - return 0; -} - -int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, - bool line_status) -{ - if (!irqchip_in_kernel(kvm)) - return -ENXIO; - - irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, - irq_event->irq, irq_event->level, - line_status); - return 0; -} - -long kvm_arch_vm_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) -{ - struct kvm *kvm = filp->private_data; - void __user *argp = (void __user *)arg; - int r = -ENOTTY; - - switch (ioctl) { - case KVM_CREATE_IRQCHIP: - r = -EFAULT; - r = kvm_ioapic_init(kvm); - if (r) - goto out; - r = kvm_setup_default_irq_routing(kvm); - if (r) { - mutex_lock(&kvm->slots_lock); - kvm_ioapic_destroy(kvm); - mutex_unlock(&kvm->slots_lock); - goto out; - } - break; - case KVM_GET_IRQCHIP: { - /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ - struct kvm_irqchip chip; - - r = -EFAULT; - if (copy_from_user(&chip, argp, sizeof chip)) - goto out; - r = -ENXIO; - if (!irqchip_in_kernel(kvm)) - goto out; - r = kvm_vm_ioctl_get_irqchip(kvm, &chip); - if (r) - goto out; - r = -EFAULT; - if (copy_to_user(argp, &chip, sizeof chip)) - goto out; - r = 0; - break; - } - case KVM_SET_IRQCHIP: { - /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ - struct kvm_irqchip chip; - - r = -EFAULT; - if (copy_from_user(&chip, argp, sizeof chip)) - goto out; - r = -ENXIO; - if (!irqchip_in_kernel(kvm)) - goto out; - r = kvm_vm_ioctl_set_irqchip(kvm, &chip); - if (r) - goto out; - r = 0; - break; - } - default: - ; - } -out: - return r; -} - -int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) -{ - return -EINVAL; -} - -int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, - struct kvm_sregs *sregs) -{ - return -EINVAL; - -} -int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, - struct kvm_translation *tr) -{ - - return -EINVAL; -} - -static int kvm_alloc_vmm_area(void) -{ - if (!kvm_vmm_base && (kvm_vm_buffer_size < KVM_VM_BUFFER_SIZE)) { - kvm_vmm_base = __get_free_pages(GFP_KERNEL, - get_order(KVM_VMM_SIZE)); - if (!kvm_vmm_base) - return -ENOMEM; - - memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); - kvm_vm_buffer = kvm_vmm_base + VMM_SIZE; - - printk(KERN_DEBUG"kvm:VMM's Base Addr:0x%lx, vm_buffer:0x%lx\n", - kvm_vmm_base, kvm_vm_buffer); - } - - return 0; -} - -static void kvm_free_vmm_area(void) -{ - if (kvm_vmm_base) { - /*Zero this area before free to avoid bits leak!!*/ - memset((void *)kvm_vmm_base, 0, KVM_VMM_SIZE); - free_pages(kvm_vmm_base, get_order(KVM_VMM_SIZE)); - kvm_vmm_base = 0; - kvm_vm_buffer = 0; - kvm_vsa_base = 0; - } -} - -static int vti_init_vpd(struct kvm_vcpu *vcpu) -{ - int i; - union cpuid3_t cpuid3; - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - - if (IS_ERR(vpd)) - return PTR_ERR(vpd); - - /* CPUID init */ - for (i = 0; i < 5; i++) - vpd->vcpuid[i] = ia64_get_cpuid(i); - - /* Limit the CPUID number to 5 */ - cpuid3.value = vpd->vcpuid[3]; - cpuid3.number = 4; /* 5 - 1 */ - vpd->vcpuid[3] = cpuid3.value; - - /*Set vac and vdc fields*/ - vpd->vac.a_from_int_cr = 1; - vpd->vac.a_to_int_cr = 1; - vpd->vac.a_from_psr = 1; - vpd->vac.a_from_cpuid = 1; - vpd->vac.a_cover = 1; - vpd->vac.a_bsw = 1; - vpd->vac.a_int = 1; - vpd->vdc.d_vmsw = 1; - - /*Set virtual buffer*/ - vpd->virt_env_vaddr = KVM_VM_BUFFER_BASE; - - return 0; -} - -static int vti_create_vp(struct kvm_vcpu *vcpu) -{ - long ret; - struct vpd *vpd = vcpu->arch.vpd; - unsigned long vmm_ivt; - - vmm_ivt = kvm_vmm_info->vmm_ivt; - - printk(KERN_DEBUG "kvm: vcpu:%p,ivt: 0x%lx\n", vcpu, vmm_ivt); - - ret = ia64_pal_vp_create((u64 *)vpd, (u64 *)vmm_ivt, 0); - - if (ret) { - printk(KERN_ERR"kvm: ia64_pal_vp_create failed!\n"); - return -EINVAL; - } - return 0; -} - -static void init_ptce_info(struct kvm_vcpu *vcpu) -{ - ia64_ptce_info_t ptce = {0}; - - ia64_get_ptce(&ptce); - vcpu->arch.ptce_base = ptce.base; - vcpu->arch.ptce_count[0] = ptce.count[0]; - vcpu->arch.ptce_count[1] = ptce.count[1]; - vcpu->arch.ptce_stride[0] = ptce.stride[0]; - vcpu->arch.ptce_stride[1] = ptce.stride[1]; -} - -static void kvm_migrate_hlt_timer(struct kvm_vcpu *vcpu) -{ - struct hrtimer *p_ht = &vcpu->arch.hlt_timer; - - if (hrtimer_cancel(p_ht)) - hrtimer_start_expires(p_ht, HRTIMER_MODE_ABS); -} - -static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) -{ - struct kvm_vcpu *vcpu; - wait_queue_head_t *q; - - vcpu = container_of(data, struct kvm_vcpu, arch.hlt_timer); - q = &vcpu->wq; - - if (vcpu->arch.mp_state != KVM_MP_STATE_HALTED) - goto out; - - if (waitqueue_active(q)) - wake_up_interruptible(q); - -out: - vcpu->arch.timer_fired = 1; - vcpu->arch.timer_check = 1; - return HRTIMER_NORESTART; -} - -#define PALE_RESET_ENTRY 0x80000000ffffffb0UL - -bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) -{ - return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); -} - -int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) -{ - struct kvm_vcpu *v; - int r; - int i; - long itc_offset; - struct kvm *kvm = vcpu->kvm; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - union context *p_ctx = &vcpu->arch.guest; - struct kvm_vcpu *vmm_vcpu = to_guest(vcpu->kvm, vcpu); - - /*Init vcpu context for first run.*/ - if (IS_ERR(vmm_vcpu)) - return PTR_ERR(vmm_vcpu); - - if (kvm_vcpu_is_bsp(vcpu)) { - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; - - /*Set entry address for first run.*/ - regs->cr_iip = PALE_RESET_ENTRY; - - /*Initialize itc offset for vcpus*/ - itc_offset = 0UL - kvm_get_itc(vcpu); - for (i = 0; i < KVM_MAX_VCPUS; i++) { - v = (struct kvm_vcpu *)((char *)vcpu + - sizeof(struct kvm_vcpu_data) * i); - v->arch.itc_offset = itc_offset; - v->arch.last_itc = 0; - } - } else - vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; - - r = -ENOMEM; - vcpu->arch.apic = kzalloc(sizeof(struct kvm_lapic), GFP_KERNEL); - if (!vcpu->arch.apic) - goto out; - vcpu->arch.apic->vcpu = vcpu; - - p_ctx->gr[1] = 0; - p_ctx->gr[12] = (unsigned long)((char *)vmm_vcpu + KVM_STK_OFFSET); - p_ctx->gr[13] = (unsigned long)vmm_vcpu; - p_ctx->psr = 0x1008522000UL; - p_ctx->ar[40] = FPSR_DEFAULT; /*fpsr*/ - p_ctx->caller_unat = 0; - p_ctx->pr = 0x0; - p_ctx->ar[36] = 0x0; /*unat*/ - p_ctx->ar[19] = 0x0; /*rnat*/ - p_ctx->ar[18] = (unsigned long)vmm_vcpu + - ((sizeof(struct kvm_vcpu)+15) & ~15); - p_ctx->ar[64] = 0x0; /*pfs*/ - p_ctx->cr[0] = 0x7e04UL; - p_ctx->cr[2] = (unsigned long)kvm_vmm_info->vmm_ivt; - p_ctx->cr[8] = 0x3c; - - /*Initialize region register*/ - p_ctx->rr[0] = 0x30; - p_ctx->rr[1] = 0x30; - p_ctx->rr[2] = 0x30; - p_ctx->rr[3] = 0x30; - p_ctx->rr[4] = 0x30; - p_ctx->rr[5] = 0x30; - p_ctx->rr[7] = 0x30; - - /*Initialize branch register 0*/ - p_ctx->br[0] = *(unsigned long *)kvm_vmm_info->vmm_entry; - - vcpu->arch.vmm_rr = kvm->arch.vmm_init_rr; - vcpu->arch.metaphysical_rr0 = kvm->arch.metaphysical_rr0; - vcpu->arch.metaphysical_rr4 = kvm->arch.metaphysical_rr4; - - hrtimer_init(&vcpu->arch.hlt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - vcpu->arch.hlt_timer.function = hlt_timer_fn; - - vcpu->arch.last_run_cpu = -1; - vcpu->arch.vpd = (struct vpd *)VPD_BASE(vcpu->vcpu_id); - vcpu->arch.vsa_base = kvm_vsa_base; - vcpu->arch.__gp = kvm_vmm_gp; - vcpu->arch.dirty_log_lock_pa = __pa(&kvm->arch.dirty_log_lock); - vcpu->arch.vhpt.hash = (struct thash_data *)VHPT_BASE(vcpu->vcpu_id); - vcpu->arch.vtlb.hash = (struct thash_data *)VTLB_BASE(vcpu->vcpu_id); - init_ptce_info(vcpu); - - r = 0; -out: - return r; -} - -static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id) -{ - unsigned long psr; - int r; - - local_irq_save(psr); - r = kvm_insert_vmm_mapping(vcpu); - local_irq_restore(psr); - if (r) - goto fail; - r = kvm_vcpu_init(vcpu, vcpu->kvm, id); - if (r) - goto fail; - - r = vti_init_vpd(vcpu); - if (r) { - printk(KERN_DEBUG"kvm: vpd init error!!\n"); - goto uninit; - } - - r = vti_create_vp(vcpu); - if (r) - goto uninit; - - kvm_purge_vmm_mapping(vcpu); - - return 0; -uninit: - kvm_vcpu_uninit(vcpu); -fail: - return r; -} - -struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, - unsigned int id) -{ - struct kvm_vcpu *vcpu; - unsigned long vm_base = kvm->arch.vm_base; - int r; - int cpu; - - BUG_ON(sizeof(struct kvm_vcpu) > VCPU_STRUCT_SIZE/2); - - r = -EINVAL; - if (id >= KVM_MAX_VCPUS) { - printk(KERN_ERR"kvm: Can't configure vcpus > %ld", - KVM_MAX_VCPUS); - goto fail; - } - - r = -ENOMEM; - if (!vm_base) { - printk(KERN_ERR"kvm: Create vcpu[%d] error!\n", id); - goto fail; - } - vcpu = (struct kvm_vcpu *)(vm_base + offsetof(struct kvm_vm_data, - vcpu_data[id].vcpu_struct)); - vcpu->kvm = kvm; - - cpu = get_cpu(); - r = vti_vcpu_setup(vcpu, id); - put_cpu(); - - if (r) { - printk(KERN_DEBUG"kvm: vcpu_setup error!!\n"); - goto fail; - } - - return vcpu; -fail: - return ERR_PTR(r); -} - -int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) -{ - return 0; -} - -int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) -{ - return 0; -} - -int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) -{ - return -EINVAL; -} - -int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) -{ - return -EINVAL; -} - -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, - struct kvm_guest_debug *dbg) -{ - return -EINVAL; -} - -void kvm_arch_free_vm(struct kvm *kvm) -{ - unsigned long vm_base = kvm->arch.vm_base; - - if (vm_base) { - memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); - free_pages(vm_base, get_order(KVM_VM_DATA_SIZE)); - } - -} - -static void kvm_release_vm_pages(struct kvm *kvm) -{ - struct kvm_memslots *slots; - struct kvm_memory_slot *memslot; - int j; - - slots = kvm_memslots(kvm); - kvm_for_each_memslot(memslot, slots) { - for (j = 0; j < memslot->npages; j++) { - if (memslot->rmap[j]) - put_page((struct page *)memslot->rmap[j]); - } - } -} - -void kvm_arch_destroy_vm(struct kvm *kvm) -{ - kvm_iommu_unmap_guest(kvm); - kvm_free_all_assigned_devices(kvm); - kfree(kvm->arch.vioapic); - kvm_release_vm_pages(kvm); -} - -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) -{ - if (cpu != vcpu->cpu) { - vcpu->cpu = cpu; - if (vcpu->arch.ht_active) - kvm_migrate_hlt_timer(vcpu); - } -} - -#define SAVE_REGS(_x) regs->_x = vcpu->arch._x - -int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) -{ - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - int i; - - vcpu_load(vcpu); - - for (i = 0; i < 16; i++) { - regs->vpd.vgr[i] = vpd->vgr[i]; - regs->vpd.vbgr[i] = vpd->vbgr[i]; - } - for (i = 0; i < 128; i++) - regs->vpd.vcr[i] = vpd->vcr[i]; - regs->vpd.vhpi = vpd->vhpi; - regs->vpd.vnat = vpd->vnat; - regs->vpd.vbnat = vpd->vbnat; - regs->vpd.vpsr = vpd->vpsr; - regs->vpd.vpr = vpd->vpr; - - memcpy(®s->saved_guest, &vcpu->arch.guest, sizeof(union context)); - - SAVE_REGS(mp_state); - SAVE_REGS(vmm_rr); - memcpy(regs->itrs, vcpu->arch.itrs, sizeof(struct thash_data) * NITRS); - memcpy(regs->dtrs, vcpu->arch.dtrs, sizeof(struct thash_data) * NDTRS); - SAVE_REGS(itr_regions); - SAVE_REGS(dtr_regions); - SAVE_REGS(tc_regions); - SAVE_REGS(irq_check); - SAVE_REGS(itc_check); - SAVE_REGS(timer_check); - SAVE_REGS(timer_pending); - SAVE_REGS(last_itc); - for (i = 0; i < 8; i++) { - regs->vrr[i] = vcpu->arch.vrr[i]; - regs->ibr[i] = vcpu->arch.ibr[i]; - regs->dbr[i] = vcpu->arch.dbr[i]; - } - for (i = 0; i < 4; i++) - regs->insvc[i] = vcpu->arch.insvc[i]; - regs->saved_itc = vcpu->arch.itc_offset + kvm_get_itc(vcpu); - SAVE_REGS(xtp); - SAVE_REGS(metaphysical_rr0); - SAVE_REGS(metaphysical_rr4); - SAVE_REGS(metaphysical_saved_rr0); - SAVE_REGS(metaphysical_saved_rr4); - SAVE_REGS(fp_psr); - SAVE_REGS(saved_gp); - - vcpu_put(vcpu); - return 0; -} - -int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu, - struct kvm_ia64_vcpu_stack *stack) -{ - memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack)); - return 0; -} - -int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu, - struct kvm_ia64_vcpu_stack *stack) -{ - memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu), - sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu)); - - vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data; - return 0; -} - -void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) -{ - - hrtimer_cancel(&vcpu->arch.hlt_timer); - kfree(vcpu->arch.apic); -} - -long kvm_arch_vcpu_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) -{ - struct kvm_vcpu *vcpu = filp->private_data; - void __user *argp = (void __user *)arg; - struct kvm_ia64_vcpu_stack *stack = NULL; - long r; - - switch (ioctl) { - case KVM_IA64_VCPU_GET_STACK: { - struct kvm_ia64_vcpu_stack __user *user_stack; - void __user *first_p = argp; - - r = -EFAULT; - if (copy_from_user(&user_stack, first_p, sizeof(void *))) - goto out; - - if (!access_ok(VERIFY_WRITE, user_stack, - sizeof(struct kvm_ia64_vcpu_stack))) { - printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: " - "Illegal user destination address for stack\n"); - goto out; - } - stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); - if (!stack) { - r = -ENOMEM; - goto out; - } - - r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack); - if (r) - goto out; - - if (copy_to_user(user_stack, stack, - sizeof(struct kvm_ia64_vcpu_stack))) { - r = -EFAULT; - goto out; - } - - break; - } - case KVM_IA64_VCPU_SET_STACK: { - struct kvm_ia64_vcpu_stack __user *user_stack; - void __user *first_p = argp; - - r = -EFAULT; - if (copy_from_user(&user_stack, first_p, sizeof(void *))) - goto out; - - if (!access_ok(VERIFY_READ, user_stack, - sizeof(struct kvm_ia64_vcpu_stack))) { - printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: " - "Illegal user address for stack\n"); - goto out; - } - stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL); - if (!stack) { - r = -ENOMEM; - goto out; - } - if (copy_from_user(stack, user_stack, - sizeof(struct kvm_ia64_vcpu_stack))) - goto out; - - r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack); - break; - } - - default: - r = -EINVAL; - } - -out: - kfree(stack); - return r; -} - -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) -{ - return VM_FAULT_SIGBUS; -} - -int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, - unsigned long npages) -{ - return 0; -} - -int kvm_arch_prepare_memory_region(struct kvm *kvm, - struct kvm_memory_slot *memslot, - struct kvm_userspace_memory_region *mem, - enum kvm_mr_change change) -{ - unsigned long i; - unsigned long pfn; - int npages = memslot->npages; - unsigned long base_gfn = memslot->base_gfn; - - if (base_gfn + npages > (KVM_MAX_MEM_SIZE >> PAGE_SHIFT)) - return -ENOMEM; - - for (i = 0; i < npages; i++) { - pfn = gfn_to_pfn(kvm, base_gfn + i); - if (!kvm_is_mmio_pfn(pfn)) { - kvm_set_pmt_entry(kvm, base_gfn + i, - pfn << PAGE_SHIFT, - _PAGE_AR_RWX | _PAGE_MA_WB); - memslot->rmap[i] = (unsigned long)pfn_to_page(pfn); - } else { - kvm_set_pmt_entry(kvm, base_gfn + i, - GPFN_PHYS_MMIO | (pfn << PAGE_SHIFT), - _PAGE_MA_UC); - memslot->rmap[i] = 0; - } - } - - return 0; -} - -void kvm_arch_flush_shadow_all(struct kvm *kvm) -{ - kvm_flush_remote_tlbs(kvm); -} - -void kvm_arch_flush_shadow_memslot(struct kvm *kvm, - struct kvm_memory_slot *slot) -{ - kvm_arch_flush_shadow_all(); -} - -long kvm_arch_dev_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) -{ - return -EINVAL; -} - -void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) -{ - kvm_vcpu_uninit(vcpu); -} - -static int vti_cpu_has_kvm_support(void) -{ - long avail = 1, status = 1, control = 1; - long ret; - - ret = ia64_pal_proc_get_features(&avail, &status, &control, 0); - if (ret) - goto out; - - if (!(avail & PAL_PROC_VM_BIT)) - goto out; - - printk(KERN_DEBUG"kvm: Hardware Supports VT\n"); - - ret = ia64_pal_vp_env_info(&kvm_vm_buffer_size, &vp_env_info); - if (ret) - goto out; - printk(KERN_DEBUG"kvm: VM Buffer Size:0x%lx\n", kvm_vm_buffer_size); - - if (!(vp_env_info & VP_OPCODE)) { - printk(KERN_WARNING"kvm: No opcode ability on hardware, " - "vm_env_info:0x%lx\n", vp_env_info); - } - - return 1; -out: - return 0; -} - - -/* - * On SN2, the ITC isn't stable, so copy in fast path code to use the - * SN2 RTC, replacing the ITC based default verion. - */ -static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info, - struct module *module) -{ - unsigned long new_ar, new_ar_sn2; - unsigned long module_base; - - if (!ia64_platform_is("sn2")) - return; - - module_base = (unsigned long)module->module_core; - - new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base; - new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base; - - printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC " - "as source\n"); - - /* - * Copy the SN2 version of mov_ar into place. They are both - * the same size, so 6 bundles is sufficient (6 * 0x10). - */ - memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60); -} - -static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info, - struct module *module) -{ - unsigned long module_base; - unsigned long vmm_size; - - unsigned long vmm_offset, func_offset, fdesc_offset; - struct fdesc *p_fdesc; - - BUG_ON(!module); - - if (!kvm_vmm_base) { - printk("kvm: kvm area hasn't been initialized yet!!\n"); - return -EFAULT; - } - - /*Calculate new position of relocated vmm module.*/ - module_base = (unsigned long)module->module_core; - vmm_size = module->core_size; - if (unlikely(vmm_size > KVM_VMM_SIZE)) - return -EFAULT; - - memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size); - kvm_patch_vmm(vmm_info, module); - kvm_flush_icache(kvm_vmm_base, vmm_size); - - /*Recalculate kvm_vmm_info based on new VMM*/ - vmm_offset = vmm_info->vmm_ivt - module_base; - kvm_vmm_info->vmm_ivt = KVM_VMM_BASE + vmm_offset; - printk(KERN_DEBUG"kvm: Relocated VMM's IVT Base Addr:%lx\n", - kvm_vmm_info->vmm_ivt); - - fdesc_offset = (unsigned long)vmm_info->vmm_entry - module_base; - kvm_vmm_info->vmm_entry = (kvm_vmm_entry *)(KVM_VMM_BASE + - fdesc_offset); - func_offset = *(unsigned long *)vmm_info->vmm_entry - module_base; - p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset); - p_fdesc->ip = KVM_VMM_BASE + func_offset; - p_fdesc->gp = KVM_VMM_BASE+(p_fdesc->gp - module_base); - - printk(KERN_DEBUG"kvm: Relocated VMM's Init Entry Addr:%lx\n", - KVM_VMM_BASE+func_offset); - - fdesc_offset = (unsigned long)vmm_info->tramp_entry - module_base; - kvm_vmm_info->tramp_entry = (kvm_tramp_entry *)(KVM_VMM_BASE + - fdesc_offset); - func_offset = *(unsigned long *)vmm_info->tramp_entry - module_base; - p_fdesc = (struct fdesc *)(kvm_vmm_base + fdesc_offset); - p_fdesc->ip = KVM_VMM_BASE + func_offset; - p_fdesc->gp = KVM_VMM_BASE + (p_fdesc->gp - module_base); - - kvm_vmm_gp = p_fdesc->gp; - - printk(KERN_DEBUG"kvm: Relocated VMM's Entry IP:%p\n", - kvm_vmm_info->vmm_entry); - printk(KERN_DEBUG"kvm: Relocated VMM's Trampoline Entry IP:0x%lx\n", - KVM_VMM_BASE + func_offset); - - return 0; -} - -int kvm_arch_init(void *opaque) -{ - int r; - struct kvm_vmm_info *vmm_info = (struct kvm_vmm_info *)opaque; - - if (!vti_cpu_has_kvm_support()) { - printk(KERN_ERR "kvm: No Hardware Virtualization Support!\n"); - r = -EOPNOTSUPP; - goto out; - } - - if (kvm_vmm_info) { - printk(KERN_ERR "kvm: Already loaded VMM module!\n"); - r = -EEXIST; - goto out; - } - - r = -ENOMEM; - kvm_vmm_info = kzalloc(sizeof(struct kvm_vmm_info), GFP_KERNEL); - if (!kvm_vmm_info) - goto out; - - if (kvm_alloc_vmm_area()) - goto out_free0; - - r = kvm_relocate_vmm(vmm_info, vmm_info->module); - if (r) - goto out_free1; - - return 0; - -out_free1: - kvm_free_vmm_area(); -out_free0: - kfree(kvm_vmm_info); -out: - return r; -} - -void kvm_arch_exit(void) -{ - kvm_free_vmm_area(); - kfree(kvm_vmm_info); - kvm_vmm_info = NULL; -} - -static void kvm_ia64_sync_dirty_log(struct kvm *kvm, - struct kvm_memory_slot *memslot) -{ - int i; - long base; - unsigned long n; - unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base + - offsetof(struct kvm_vm_data, kvm_mem_dirty_log)); - - n = kvm_dirty_bitmap_bytes(memslot); - base = memslot->base_gfn / BITS_PER_LONG; - - spin_lock(&kvm->arch.dirty_log_lock); - for (i = 0; i < n/sizeof(long); ++i) { - memslot->dirty_bitmap[i] = dirty_bitmap[base + i]; - dirty_bitmap[base + i] = 0; - } - spin_unlock(&kvm->arch.dirty_log_lock); -} - -int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) -{ - int r; - unsigned long n; - struct kvm_memory_slot *memslot; - int is_dirty = 0; - - mutex_lock(&kvm->slots_lock); - - r = -EINVAL; - if (log->slot >= KVM_USER_MEM_SLOTS) - goto out; - - memslot = id_to_memslot(kvm->memslots, log->slot); - r = -ENOENT; - if (!memslot->dirty_bitmap) - goto out; - - kvm_ia64_sync_dirty_log(kvm, memslot); - r = kvm_get_dirty_log(kvm, log, &is_dirty); - if (r) - goto out; - - /* If nothing is dirty, don't bother messing with page tables. */ - if (is_dirty) { - kvm_flush_remote_tlbs(kvm); - n = kvm_dirty_bitmap_bytes(memslot); - memset(memslot->dirty_bitmap, 0, n); - } - r = 0; -out: - mutex_unlock(&kvm->slots_lock); - return r; -} - -int kvm_arch_hardware_setup(void) -{ - return 0; -} - -int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) -{ - return __apic_accept_irq(vcpu, irq->vector); -} - -int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) -{ - return apic->vcpu->vcpu_id == dest; -} - -int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) -{ - return 0; -} - -int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) -{ - return vcpu1->arch.xtp - vcpu2->arch.xtp; -} - -int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, - int short_hand, int dest, int dest_mode) -{ - struct kvm_lapic *target = vcpu->arch.apic; - return (dest_mode == 0) ? - kvm_apic_match_physical_addr(target, dest) : - kvm_apic_match_logical_addr(target, dest); -} - -static int find_highest_bits(int *dat) -{ - u32 bits, bitnum; - int i; - - /* loop for all 256 bits */ - for (i = 7; i >= 0 ; i--) { - bits = dat[i]; - if (bits) { - bitnum = fls(bits); - return i * 32 + bitnum - 1; - } - } - - return -1; -} - -int kvm_highest_pending_irq(struct kvm_vcpu *vcpu) -{ - struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - - if (vpd->irr[0] & (1UL << NMI_VECTOR)) - return NMI_VECTOR; - if (vpd->irr[0] & (1UL << ExtINT_VECTOR)) - return ExtINT_VECTOR; - - return find_highest_bits((int *)&vpd->irr[0]); -} - -int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) -{ - return vcpu->arch.timer_fired; -} - -int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) -{ - return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) || - (kvm_highest_pending_irq(vcpu) != -1); -} - -int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) -{ - return (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests)); -} - -int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, - struct kvm_mp_state *mp_state) -{ - mp_state->mp_state = vcpu->arch.mp_state; - return 0; -} - -static int vcpu_reset(struct kvm_vcpu *vcpu) -{ - int r; - long psr; - local_irq_save(psr); - r = kvm_insert_vmm_mapping(vcpu); - local_irq_restore(psr); - if (r) - goto fail; - - vcpu->arch.launched = 0; - kvm_arch_vcpu_uninit(vcpu); - r = kvm_arch_vcpu_init(vcpu); - if (r) - goto fail; - - kvm_purge_vmm_mapping(vcpu); - r = 0; -fail: - return r; -} - -int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, - struct kvm_mp_state *mp_state) -{ - int r = 0; - - vcpu->arch.mp_state = mp_state->mp_state; - if (vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED) - r = vcpu_reset(vcpu); - return r; -} diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c deleted file mode 100644 index cb548ee9fcae..000000000000 --- a/arch/ia64/kvm/kvm_fw.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * PAL/SAL call delegation - * - * Copyright (c) 2004 Li Susie - * Copyright (c) 2005 Yu Ke - * Copyright (c) 2007 Xiantao Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - */ - -#include -#include -#include -#include -#include - -#include "vti.h" -#include "misc.h" - -#include -#include -#include - -/* - * Handy macros to make sure that the PAL return values start out - * as something meaningful. - */ -#define INIT_PAL_STATUS_UNIMPLEMENTED(x) \ - { \ - x.status = PAL_STATUS_UNIMPLEMENTED; \ - x.v0 = 0; \ - x.v1 = 0; \ - x.v2 = 0; \ - } - -#define INIT_PAL_STATUS_SUCCESS(x) \ - { \ - x.status = PAL_STATUS_SUCCESS; \ - x.v0 = 0; \ - x.v1 = 0; \ - x.v2 = 0; \ - } - -static void kvm_get_pal_call_data(struct kvm_vcpu *vcpu, - u64 *gr28, u64 *gr29, u64 *gr30, u64 *gr31) { - struct exit_ctl_data *p; - - if (vcpu) { - p = &vcpu->arch.exit_data; - if (p->exit_reason == EXIT_REASON_PAL_CALL) { - *gr28 = p->u.pal_data.gr28; - *gr29 = p->u.pal_data.gr29; - *gr30 = p->u.pal_data.gr30; - *gr31 = p->u.pal_data.gr31; - return ; - } - } - printk(KERN_DEBUG"Failed to get vcpu pal data!!!\n"); -} - -static void set_pal_result(struct kvm_vcpu *vcpu, - struct ia64_pal_retval result) { - - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - if (p->exit_reason == EXIT_REASON_PAL_CALL) { - p->u.pal_data.ret = result; - return ; - } - INIT_PAL_STATUS_UNIMPLEMENTED(p->u.pal_data.ret); -} - -static void set_sal_result(struct kvm_vcpu *vcpu, - struct sal_ret_values result) { - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - if (p->exit_reason == EXIT_REASON_SAL_CALL) { - p->u.sal_data.ret = result; - return ; - } - printk(KERN_WARNING"Failed to set sal result!!\n"); -} - -struct cache_flush_args { - u64 cache_type; - u64 operation; - u64 progress; - long status; -}; - -cpumask_t cpu_cache_coherent_map; - -static void remote_pal_cache_flush(void *data) -{ - struct cache_flush_args *args = data; - long status; - u64 progress = args->progress; - - status = ia64_pal_cache_flush(args->cache_type, args->operation, - &progress, NULL); - if (status != 0) - args->status = status; -} - -static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu) -{ - u64 gr28, gr29, gr30, gr31; - struct ia64_pal_retval result = {0, 0, 0, 0}; - struct cache_flush_args args = {0, 0, 0, 0}; - long psr; - - gr28 = gr29 = gr30 = gr31 = 0; - kvm_get_pal_call_data(vcpu, &gr28, &gr29, &gr30, &gr31); - - if (gr31 != 0) - printk(KERN_ERR"vcpu:%p called cache_flush error!\n", vcpu); - - /* Always call Host Pal in int=1 */ - gr30 &= ~PAL_CACHE_FLUSH_CHK_INTRS; - args.cache_type = gr29; - args.operation = gr30; - smp_call_function(remote_pal_cache_flush, - (void *)&args, 1); - if (args.status != 0) - printk(KERN_ERR"pal_cache_flush error!," - "status:0x%lx\n", args.status); - /* - * Call Host PAL cache flush - * Clear psr.ic when call PAL_CACHE_FLUSH - */ - local_irq_save(psr); - result.status = ia64_pal_cache_flush(gr29, gr30, &result.v1, - &result.v0); - local_irq_restore(psr); - if (result.status != 0) - printk(KERN_ERR"vcpu:%p crashed due to cache_flush err:%ld" - "in1:%lx,in2:%lx\n", - vcpu, result.status, gr29, gr30); - -#if 0 - if (gr29 == PAL_CACHE_TYPE_COHERENT) { - cpus_setall(vcpu->arch.cache_coherent_map); - cpu_clear(vcpu->cpu, vcpu->arch.cache_coherent_map); - cpus_setall(cpu_cache_coherent_map); - cpu_clear(vcpu->cpu, cpu_cache_coherent_map); - } -#endif - return result; -} - -struct ia64_pal_retval pal_cache_summary(struct kvm_vcpu *vcpu) -{ - - struct ia64_pal_retval result; - - PAL_CALL(result, PAL_CACHE_SUMMARY, 0, 0, 0); - return result; -} - -static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu) -{ - - struct ia64_pal_retval result; - - PAL_CALL(result, PAL_FREQ_BASE, 0, 0, 0); - - /* - * PAL_FREQ_BASE may not be implemented in some platforms, - * call SAL instead. - */ - if (result.v0 == 0) { - result.status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, - &result.v0, - &result.v1); - result.v2 = 0; - } - - return result; -} - -/* - * On the SGI SN2, the ITC isn't stable. Emulation backed by the SN2 - * RTC is used instead. This function patches the ratios from SAL - * to match the RTC before providing them to the guest. - */ -static void sn2_patch_itc_freq_ratios(struct ia64_pal_retval *result) -{ - struct pal_freq_ratio *ratio; - unsigned long sal_freq, sal_drift, factor; - - result->status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, - &sal_freq, &sal_drift); - ratio = (struct pal_freq_ratio *)&result->v2; - factor = ((sal_freq * 3) + (sn_rtc_cycles_per_second / 2)) / - sn_rtc_cycles_per_second; - - ratio->num = 3; - ratio->den = factor; -} - -static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu) -{ - struct ia64_pal_retval result; - - PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0); - - if (vcpu->kvm->arch.is_sn2) - sn2_patch_itc_freq_ratios(&result); - - return result; -} - -static struct ia64_pal_retval pal_logical_to_physica(struct kvm_vcpu *vcpu) -{ - struct ia64_pal_retval result; - - INIT_PAL_STATUS_UNIMPLEMENTED(result); - return result; -} - -static struct ia64_pal_retval pal_platform_addr(struct kvm_vcpu *vcpu) -{ - - struct ia64_pal_retval result; - - INIT_PAL_STATUS_SUCCESS(result); - return result; -} - -static struct ia64_pal_retval pal_proc_get_features(struct kvm_vcpu *vcpu) -{ - - struct ia64_pal_retval result = {0, 0, 0, 0}; - long in0, in1, in2, in3; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - result.status = ia64_pal_proc_get_features(&result.v0, &result.v1, - &result.v2, in2); - - return result; -} - -static struct ia64_pal_retval pal_register_info(struct kvm_vcpu *vcpu) -{ - - struct ia64_pal_retval result = {0, 0, 0, 0}; - long in0, in1, in2, in3; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - result.status = ia64_pal_register_info(in1, &result.v1, &result.v2); - - return result; -} - -static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu) -{ - - pal_cache_config_info_t ci; - long status; - unsigned long in0, in1, in2, in3, r9, r10; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - status = ia64_pal_cache_config_info(in1, in2, &ci); - r9 = ci.pcci_info_1.pcci1_data; - r10 = ci.pcci_info_2.pcci2_data; - return ((struct ia64_pal_retval){status, r9, r10, 0}); -} - -#define GUEST_IMPL_VA_MSB 59 -#define GUEST_RID_BITS 18 - -static struct ia64_pal_retval pal_vm_summary(struct kvm_vcpu *vcpu) -{ - - pal_vm_info_1_u_t vminfo1; - pal_vm_info_2_u_t vminfo2; - struct ia64_pal_retval result; - - PAL_CALL(result, PAL_VM_SUMMARY, 0, 0, 0); - if (!result.status) { - vminfo1.pvi1_val = result.v0; - vminfo1.pal_vm_info_1_s.max_itr_entry = 8; - vminfo1.pal_vm_info_1_s.max_dtr_entry = 8; - result.v0 = vminfo1.pvi1_val; - vminfo2.pal_vm_info_2_s.impl_va_msb = GUEST_IMPL_VA_MSB; - vminfo2.pal_vm_info_2_s.rid_size = GUEST_RID_BITS; - result.v1 = vminfo2.pvi2_val; - } - - return result; -} - -static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu) -{ - struct ia64_pal_retval result; - unsigned long in0, in1, in2, in3; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - - result.status = ia64_pal_vm_info(in1, in2, - (pal_tc_info_u_t *)&result.v1, &result.v2); - - return result; -} - -static u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu) -{ - u64 index = 0; - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - if (p->exit_reason == EXIT_REASON_PAL_CALL) - index = p->u.pal_data.gr28; - - return index; -} - -static void prepare_for_halt(struct kvm_vcpu *vcpu) -{ - vcpu->arch.timer_pending = 1; - vcpu->arch.timer_fired = 0; -} - -static struct ia64_pal_retval pal_perf_mon_info(struct kvm_vcpu *vcpu) -{ - long status; - unsigned long in0, in1, in2, in3, r9; - unsigned long pm_buffer[16]; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - status = ia64_pal_perf_mon_info(pm_buffer, - (pal_perf_mon_info_u_t *) &r9); - if (status != 0) { - printk(KERN_DEBUG"PAL_PERF_MON_INFO fails ret=%ld\n", status); - } else { - if (in1) - memcpy((void *)in1, pm_buffer, sizeof(pm_buffer)); - else { - status = PAL_STATUS_EINVAL; - printk(KERN_WARNING"Invalid parameters " - "for PAL call:0x%lx!\n", in0); - } - } - return (struct ia64_pal_retval){status, r9, 0, 0}; -} - -static struct ia64_pal_retval pal_halt_info(struct kvm_vcpu *vcpu) -{ - unsigned long in0, in1, in2, in3; - long status; - unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32) - | (1UL << 61) | (1UL << 60); - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - if (in1) { - memcpy((void *)in1, &res, sizeof(res)); - status = 0; - } else{ - status = PAL_STATUS_EINVAL; - printk(KERN_WARNING"Invalid parameters " - "for PAL call:0x%lx!\n", in0); - } - - return (struct ia64_pal_retval){status, 0, 0, 0}; -} - -static struct ia64_pal_retval pal_mem_attrib(struct kvm_vcpu *vcpu) -{ - unsigned long r9; - long status; - - status = ia64_pal_mem_attrib(&r9); - - return (struct ia64_pal_retval){status, r9, 0, 0}; -} - -static void remote_pal_prefetch_visibility(void *v) -{ - s64 trans_type = (s64)v; - ia64_pal_prefetch_visibility(trans_type); -} - -static struct ia64_pal_retval pal_prefetch_visibility(struct kvm_vcpu *vcpu) -{ - struct ia64_pal_retval result = {0, 0, 0, 0}; - unsigned long in0, in1, in2, in3; - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - result.status = ia64_pal_prefetch_visibility(in1); - if (result.status == 0) { - /* Must be performed on all remote processors - in the coherence domain. */ - smp_call_function(remote_pal_prefetch_visibility, - (void *)in1, 1); - /* Unnecessary on remote processor for other vcpus!*/ - result.status = 1; - } - return result; -} - -static void remote_pal_mc_drain(void *v) -{ - ia64_pal_mc_drain(); -} - -static struct ia64_pal_retval pal_get_brand_info(struct kvm_vcpu *vcpu) -{ - struct ia64_pal_retval result = {0, 0, 0, 0}; - unsigned long in0, in1, in2, in3; - - kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3); - - if (in1 == 0 && in2) { - char brand_info[128]; - result.status = ia64_pal_get_brand_info(brand_info); - if (result.status == PAL_STATUS_SUCCESS) - memcpy((void *)in2, brand_info, 128); - } else { - result.status = PAL_STATUS_REQUIRES_MEMORY; - printk(KERN_WARNING"Invalid parameters for " - "PAL call:0x%lx!\n", in0); - } - - return result; -} - -int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - - u64 gr28; - struct ia64_pal_retval result; - int ret = 1; - - gr28 = kvm_get_pal_call_index(vcpu); - switch (gr28) { - case PAL_CACHE_FLUSH: - result = pal_cache_flush(vcpu); - break; - case PAL_MEM_ATTRIB: - result = pal_mem_attrib(vcpu); - break; - case PAL_CACHE_SUMMARY: - result = pal_cache_summary(vcpu); - break; - case PAL_PERF_MON_INFO: - result = pal_perf_mon_info(vcpu); - break; - case PAL_HALT_INFO: - result = pal_halt_info(vcpu); - break; - case PAL_HALT_LIGHT: - { - INIT_PAL_STATUS_SUCCESS(result); - prepare_for_halt(vcpu); - if (kvm_highest_pending_irq(vcpu) == -1) - ret = kvm_emulate_halt(vcpu); - } - break; - - case PAL_PREFETCH_VISIBILITY: - result = pal_prefetch_visibility(vcpu); - break; - case PAL_MC_DRAIN: - result.status = ia64_pal_mc_drain(); - /* FIXME: All vcpus likely call PAL_MC_DRAIN. - That causes the congestion. */ - smp_call_function(remote_pal_mc_drain, NULL, 1); - break; - - case PAL_FREQ_RATIOS: - result = pal_freq_ratios(vcpu); - break; - - case PAL_FREQ_BASE: - result = pal_freq_base(vcpu); - break; - - case PAL_LOGICAL_TO_PHYSICAL : - result = pal_logical_to_physica(vcpu); - break; - - case PAL_VM_SUMMARY : - result = pal_vm_summary(vcpu); - break; - - case PAL_VM_INFO : - result = pal_vm_info(vcpu); - break; - case PAL_PLATFORM_ADDR : - result = pal_platform_addr(vcpu); - break; - case PAL_CACHE_INFO: - result = pal_cache_info(vcpu); - break; - case PAL_PTCE_INFO: - INIT_PAL_STATUS_SUCCESS(result); - result.v1 = (1L << 32) | 1L; - break; - case PAL_REGISTER_INFO: - result = pal_register_info(vcpu); - break; - case PAL_VM_PAGE_SIZE: - result.status = ia64_pal_vm_page_size(&result.v0, - &result.v1); - break; - case PAL_RSE_INFO: - result.status = ia64_pal_rse_info(&result.v0, - (pal_hints_u_t *)&result.v1); - break; - case PAL_PROC_GET_FEATURES: - result = pal_proc_get_features(vcpu); - break; - case PAL_DEBUG_INFO: - result.status = ia64_pal_debug_info(&result.v0, - &result.v1); - break; - case PAL_VERSION: - result.status = ia64_pal_version( - (pal_version_u_t *)&result.v0, - (pal_version_u_t *)&result.v1); - break; - case PAL_FIXED_ADDR: - result.status = PAL_STATUS_SUCCESS; - result.v0 = vcpu->vcpu_id; - break; - case PAL_BRAND_INFO: - result = pal_get_brand_info(vcpu); - break; - case PAL_GET_PSTATE: - case PAL_CACHE_SHARED_INFO: - INIT_PAL_STATUS_UNIMPLEMENTED(result); - break; - default: - INIT_PAL_STATUS_UNIMPLEMENTED(result); - printk(KERN_WARNING"kvm: Unsupported pal call," - " index:0x%lx\n", gr28); - } - set_pal_result(vcpu, result); - return ret; -} - -static struct sal_ret_values sal_emulator(struct kvm *kvm, - long index, unsigned long in1, - unsigned long in2, unsigned long in3, - unsigned long in4, unsigned long in5, - unsigned long in6, unsigned long in7) -{ - unsigned long r9 = 0; - unsigned long r10 = 0; - long r11 = 0; - long status; - - status = 0; - switch (index) { - case SAL_FREQ_BASE: - status = ia64_sal_freq_base(in1, &r9, &r10); - break; - case SAL_PCI_CONFIG_READ: - printk(KERN_WARNING"kvm: Not allowed to call here!" - " SAL_PCI_CONFIG_READ\n"); - break; - case SAL_PCI_CONFIG_WRITE: - printk(KERN_WARNING"kvm: Not allowed to call here!" - " SAL_PCI_CONFIG_WRITE\n"); - break; - case SAL_SET_VECTORS: - if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) { - if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) { - status = -2; - } else { - kvm->arch.rdv_sal_data.boot_ip = in2; - kvm->arch.rdv_sal_data.boot_gp = in3; - } - printk("Rendvous called! iip:%lx\n\n", in2); - } else - printk(KERN_WARNING"kvm: CALLED SAL_SET_VECTORS %lu." - "ignored...\n", in1); - break; - case SAL_GET_STATE_INFO: - /* No more info. */ - status = -5; - r9 = 0; - break; - case SAL_GET_STATE_INFO_SIZE: - /* Return a dummy size. */ - status = 0; - r9 = 128; - break; - case SAL_CLEAR_STATE_INFO: - /* Noop. */ - break; - case SAL_MC_RENDEZ: - printk(KERN_WARNING - "kvm: called SAL_MC_RENDEZ. ignored...\n"); - break; - case SAL_MC_SET_PARAMS: - printk(KERN_WARNING - "kvm: called SAL_MC_SET_PARAMS.ignored!\n"); - break; - case SAL_CACHE_FLUSH: - if (1) { - /*Flush using SAL. - This method is faster but has a side - effect on other vcpu running on - this cpu. */ - status = ia64_sal_cache_flush(in1); - } else { - /*Maybe need to implement the method - without side effect!*/ - status = 0; - } - break; - case SAL_CACHE_INIT: - printk(KERN_WARNING - "kvm: called SAL_CACHE_INIT. ignored...\n"); - break; - case SAL_UPDATE_PAL: - printk(KERN_WARNING - "kvm: CALLED SAL_UPDATE_PAL. ignored...\n"); - break; - default: - printk(KERN_WARNING"kvm: called SAL_CALL with unknown index." - " index:%ld\n", index); - status = -1; - break; - } - return ((struct sal_ret_values) {status, r9, r10, r11}); -} - -static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1, - u64 *in2, u64 *in3, u64 *in4, u64 *in5, u64 *in6, u64 *in7){ - - struct exit_ctl_data *p; - - p = kvm_get_exit_data(vcpu); - - if (p->exit_reason == EXIT_REASON_SAL_CALL) { - *in0 = p->u.sal_data.in0; - *in1 = p->u.sal_data.in1; - *in2 = p->u.sal_data.in2; - *in3 = p->u.sal_data.in3; - *in4 = p->u.sal_data.in4; - *in5 = p->u.sal_data.in5; - *in6 = p->u.sal_data.in6; - *in7 = p->u.sal_data.in7; - return ; - } - *in0 = 0; -} - -void kvm_sal_emul(struct kvm_vcpu *vcpu) -{ - - struct sal_ret_values result; - u64 index, in1, in2, in3, in4, in5, in6, in7; - - kvm_get_sal_call_data(vcpu, &index, &in1, &in2, - &in3, &in4, &in5, &in6, &in7); - result = sal_emulator(vcpu->kvm, index, in1, in2, in3, - in4, in5, in6, in7); - set_sal_result(vcpu, result); -} diff --git a/arch/ia64/kvm/kvm_lib.c b/arch/ia64/kvm/kvm_lib.c deleted file mode 100644 index f1268b8e6f9e..000000000000 --- a/arch/ia64/kvm/kvm_lib.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * kvm_lib.c: Compile some libraries for kvm-intel module. - * - * Just include kernel's library, and disable symbols export. - * Copyright (C) 2008, Intel Corporation. - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#undef CONFIG_MODULES -#include -#undef CONFIG_KALLSYMS -#undef EXPORT_SYMBOL -#undef EXPORT_SYMBOL_GPL -#define EXPORT_SYMBOL(sym) -#define EXPORT_SYMBOL_GPL(sym) -#include "../../../lib/vsprintf.c" -#include "../../../lib/ctype.c" diff --git a/arch/ia64/kvm/kvm_minstate.h b/arch/ia64/kvm/kvm_minstate.h deleted file mode 100644 index b2bcaa2787aa..000000000000 --- a/arch/ia64/kvm/kvm_minstate.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * kvm_minstate.h: min save macros - * Copyright (c) 2007, Intel Corporation. - * - * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - - -#include -#include -#include -#include - -#include "asm-offsets.h" - -#define KVM_MINSTATE_START_SAVE_MIN \ - mov ar.rsc = 0;/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */\ - ;; \ - mov.m r28 = ar.rnat; \ - addl r22 = VMM_RBS_OFFSET,r1; /* compute base of RBS */ \ - ;; \ - lfetch.fault.excl.nt1 [r22]; \ - addl r1 = KVM_STK_OFFSET-VMM_PT_REGS_SIZE, r1; \ - mov r23 = ar.bspstore; /* save ar.bspstore */ \ - ;; \ - mov ar.bspstore = r22; /* switch to kernel RBS */\ - ;; \ - mov r18 = ar.bsp; \ - mov ar.rsc = 0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ - - - -#define KVM_MINSTATE_END_SAVE_MIN \ - bsw.1; /* switch back to bank 1 (must be last in insn group) */\ - ;; - - -#define PAL_VSA_SYNC_READ \ - /* begin to call pal vps sync_read */ \ -{.mii; \ - add r25 = VMM_VPD_BASE_OFFSET, r21; \ - nop 0x0; \ - mov r24=ip; \ - ;; \ -} \ -{.mmb \ - add r24=0x20, r24; \ - ld8 r25 = [r25]; /* read vpd base */ \ - br.cond.sptk kvm_vps_sync_read; /*call the service*/ \ - ;; \ -}; \ - - -#define KVM_MINSTATE_GET_CURRENT(reg) mov reg=r21 - -/* - * KVM_DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves - * the minimum state necessary that allows us to turn psr.ic back - * on. - * - * Assumed state upon entry: - * psr.ic: off - * r31: contains saved predicates (pr) - * - * Upon exit, the state is as follows: - * psr.ic: off - * r2 = points to &pt_regs.r16 - * r8 = contents of ar.ccv - * r9 = contents of ar.csd - * r10 = contents of ar.ssd - * r11 = FPSR_DEFAULT - * r12 = kernel sp (kernel virtual address) - * r13 = points to current task_struct (kernel virtual address) - * p15 = TRUE if psr.i is set in cr.ipsr - * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15: - * preserved - * - * Note that psr.ic is NOT turned on by this macro. This is so that - * we can pass interruption state as arguments to a handler. - */ - - -#define PT(f) (VMM_PT_REGS_##f##_OFFSET) - -#define KVM_DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ - KVM_MINSTATE_GET_CURRENT(r16); /* M (or M;;I) */ \ - mov r27 = ar.rsc; /* M */ \ - mov r20 = r1; /* A */ \ - mov r25 = ar.unat; /* M */ \ - mov r29 = cr.ipsr; /* M */ \ - mov r26 = ar.pfs; /* I */ \ - mov r18 = cr.isr; \ - COVER; /* B;; (or nothing) */ \ - ;; \ - tbit.z p0,p15 = r29,IA64_PSR_I_BIT; \ - mov r1 = r16; \ -/* mov r21=r16; */ \ - /* switch from user to kernel RBS: */ \ - ;; \ - invala; /* M */ \ - SAVE_IFS; \ - ;; \ - KVM_MINSTATE_START_SAVE_MIN \ - adds r17 = 2*L1_CACHE_BYTES,r1;/* cache-line size */ \ - adds r16 = PT(CR_IPSR),r1; \ - ;; \ - lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ - st8 [r16] = r29; /* save cr.ipsr */ \ - ;; \ - lfetch.fault.excl.nt1 [r17]; \ - tbit.nz p15,p0 = r29,IA64_PSR_I_BIT; \ - mov r29 = b0 \ - ;; \ - adds r16 = PT(R8),r1; /* initialize first base pointer */\ - adds r17 = PT(R9),r1; /* initialize second base pointer */\ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r8,16; \ -.mem.offset 8,0; st8.spill [r17] = r9,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r10,24; \ -.mem.offset 8,0; st8.spill [r17] = r11,24; \ - ;; \ - mov r9 = cr.iip; /* M */ \ - mov r10 = ar.fpsr; /* M */ \ - ;; \ - st8 [r16] = r9,16; /* save cr.iip */ \ - st8 [r17] = r30,16; /* save cr.ifs */ \ - sub r18 = r18,r22; /* r18=RSE.ndirty*8 */ \ - ;; \ - st8 [r16] = r25,16; /* save ar.unat */ \ - st8 [r17] = r26,16; /* save ar.pfs */ \ - shl r18 = r18,16; /* calu ar.rsc used for "loadrs" */\ - ;; \ - st8 [r16] = r27,16; /* save ar.rsc */ \ - st8 [r17] = r28,16; /* save ar.rnat */ \ - ;; /* avoid RAW on r16 & r17 */ \ - st8 [r16] = r23,16; /* save ar.bspstore */ \ - st8 [r17] = r31,16; /* save predicates */ \ - ;; \ - st8 [r16] = r29,16; /* save b0 */ \ - st8 [r17] = r18,16; /* save ar.rsc value for "loadrs" */\ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r20,16;/* save original r1 */ \ -.mem.offset 8,0; st8.spill [r17] = r12,16; \ - adds r12 = -16,r1; /* switch to kernel memory stack */ \ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r13,16; \ -.mem.offset 8,0; st8.spill [r17] = r10,16; /* save ar.fpsr */\ - mov r13 = r21; /* establish `current' */ \ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r15,16; \ -.mem.offset 8,0; st8.spill [r17] = r14,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r16] = r2,16; \ -.mem.offset 8,0; st8.spill [r17] = r3,16; \ - adds r2 = VMM_PT_REGS_R16_OFFSET,r1; \ - ;; \ - adds r16 = VMM_VCPU_IIPA_OFFSET,r13; \ - adds r17 = VMM_VCPU_ISR_OFFSET,r13; \ - mov r26 = cr.iipa; \ - mov r27 = cr.isr; \ - ;; \ - st8 [r16] = r26; \ - st8 [r17] = r27; \ - ;; \ - EXTRA; \ - mov r8 = ar.ccv; \ - mov r9 = ar.csd; \ - mov r10 = ar.ssd; \ - movl r11 = FPSR_DEFAULT; /* L-unit */ \ - adds r17 = VMM_VCPU_GP_OFFSET,r13; \ - ;; \ - ld8 r1 = [r17];/* establish kernel global pointer */ \ - ;; \ - PAL_VSA_SYNC_READ \ - KVM_MINSTATE_END_SAVE_MIN - -/* - * SAVE_REST saves the remainder of pt_regs (with psr.ic on). - * - * Assumed state upon entry: - * psr.ic: on - * r2: points to &pt_regs.f6 - * r3: points to &pt_regs.f7 - * r8: contents of ar.ccv - * r9: contents of ar.csd - * r10: contents of ar.ssd - * r11: FPSR_DEFAULT - * - * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST. - */ -#define KVM_SAVE_REST \ -.mem.offset 0,0; st8.spill [r2] = r16,16; \ -.mem.offset 8,0; st8.spill [r3] = r17,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r18,16; \ -.mem.offset 8,0; st8.spill [r3] = r19,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r20,16; \ -.mem.offset 8,0; st8.spill [r3] = r21,16; \ - mov r18=b6; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r22,16; \ -.mem.offset 8,0; st8.spill [r3] = r23,16; \ - mov r19 = b7; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r24,16; \ -.mem.offset 8,0; st8.spill [r3] = r25,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r26,16; \ -.mem.offset 8,0; st8.spill [r3] = r27,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r28,16; \ -.mem.offset 8,0; st8.spill [r3] = r29,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r30,16; \ -.mem.offset 8,0; st8.spill [r3] = r31,32; \ - ;; \ - mov ar.fpsr = r11; \ - st8 [r2] = r8,8; \ - adds r24 = PT(B6)-PT(F7),r3; \ - adds r25 = PT(B7)-PT(F7),r3; \ - ;; \ - st8 [r24] = r18,16; /* b6 */ \ - st8 [r25] = r19,16; /* b7 */ \ - adds r2 = PT(R4)-PT(F6),r2; \ - adds r3 = PT(R5)-PT(F7),r3; \ - ;; \ - st8 [r24] = r9; /* ar.csd */ \ - st8 [r25] = r10; /* ar.ssd */ \ - ;; \ - mov r18 = ar.unat; \ - adds r19 = PT(EML_UNAT)-PT(R4),r2; \ - ;; \ - st8 [r19] = r18; /* eml_unat */ \ - - -#define KVM_SAVE_EXTRA \ -.mem.offset 0,0; st8.spill [r2] = r4,16; \ -.mem.offset 8,0; st8.spill [r3] = r5,16; \ - ;; \ -.mem.offset 0,0; st8.spill [r2] = r6,16; \ -.mem.offset 8,0; st8.spill [r3] = r7; \ - ;; \ - mov r26 = ar.unat; \ - ;; \ - st8 [r2] = r26;/* eml_unat */ \ - -#define KVM_SAVE_MIN_WITH_COVER KVM_DO_SAVE_MIN(cover, mov r30 = cr.ifs,) -#define KVM_SAVE_MIN_WITH_COVER_R19 KVM_DO_SAVE_MIN(cover, mov r30 = cr.ifs, mov r15 = r19) -#define KVM_SAVE_MIN KVM_DO_SAVE_MIN( , mov r30 = r0, ) diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h deleted file mode 100644 index c5f92a926a9a..000000000000 --- a/arch/ia64/kvm/lapic.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __KVM_IA64_LAPIC_H -#define __KVM_IA64_LAPIC_H - -#include - -/* - * vlsapic - */ -struct kvm_lapic{ - struct kvm_vcpu *vcpu; - uint64_t insvc[4]; - uint64_t vhpi; - uint8_t xtp; - uint8_t pal_init_pending; - uint8_t pad[2]; -}; - -int kvm_create_lapic(struct kvm_vcpu *vcpu); -void kvm_free_lapic(struct kvm_vcpu *vcpu); - -int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); -int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); -int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, - int short_hand, int dest, int dest_mode); -int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); -int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq); -#define kvm_apic_present(x) (true) -#define kvm_lapic_enabled(x) (true) - -#endif diff --git a/arch/ia64/kvm/memcpy.S b/arch/ia64/kvm/memcpy.S deleted file mode 100644 index c04cdbe9f80f..000000000000 --- a/arch/ia64/kvm/memcpy.S +++ /dev/null @@ -1 +0,0 @@ -#include "../lib/memcpy.S" diff --git a/arch/ia64/kvm/memset.S b/arch/ia64/kvm/memset.S deleted file mode 100644 index 83c3066d844a..000000000000 --- a/arch/ia64/kvm/memset.S +++ /dev/null @@ -1 +0,0 @@ -#include "../lib/memset.S" diff --git a/arch/ia64/kvm/misc.h b/arch/ia64/kvm/misc.h deleted file mode 100644 index dd979e00b574..000000000000 --- a/arch/ia64/kvm/misc.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef __KVM_IA64_MISC_H -#define __KVM_IA64_MISC_H - -#include -/* - * misc.h - * Copyright (C) 2007, Intel Corporation. - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * 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. - * - */ - -/* - *Return p2m base address at host side! - */ -static inline uint64_t *kvm_host_get_pmt(struct kvm *kvm) -{ - return (uint64_t *)(kvm->arch.vm_base + - offsetof(struct kvm_vm_data, kvm_p2m)); -} - -static inline void kvm_set_pmt_entry(struct kvm *kvm, gfn_t gfn, - u64 paddr, u64 mem_flags) -{ - uint64_t *pmt_base = kvm_host_get_pmt(kvm); - unsigned long pte; - - pte = PAGE_ALIGN(paddr) | mem_flags; - pmt_base[gfn] = pte; -} - -/*Function for translating host address to guest address*/ - -static inline void *to_guest(struct kvm *kvm, void *addr) -{ - return (void *)((unsigned long)(addr) - kvm->arch.vm_base + - KVM_VM_DATA_BASE); -} - -/*Function for translating guest address to host address*/ - -static inline void *to_host(struct kvm *kvm, void *addr) -{ - return (void *)((unsigned long)addr - KVM_VM_DATA_BASE - + kvm->arch.vm_base); -} - -/* Get host context of the vcpu */ -static inline union context *kvm_get_host_context(struct kvm_vcpu *vcpu) -{ - union context *ctx = &vcpu->arch.host; - return to_guest(vcpu->kvm, ctx); -} - -/* Get guest context of the vcpu */ -static inline union context *kvm_get_guest_context(struct kvm_vcpu *vcpu) -{ - union context *ctx = &vcpu->arch.guest; - return to_guest(vcpu->kvm, ctx); -} - -/* kvm get exit data from gvmm! */ -static inline struct exit_ctl_data *kvm_get_exit_data(struct kvm_vcpu *vcpu) -{ - return &vcpu->arch.exit_data; -} - -/*kvm get vcpu ioreq for kvm module!*/ -static inline struct kvm_mmio_req *kvm_get_vcpu_ioreq(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p_ctl_data; - - if (vcpu) { - p_ctl_data = kvm_get_exit_data(vcpu); - if (p_ctl_data->exit_reason == EXIT_REASON_MMIO_INSTRUCTION) - return &p_ctl_data->u.ioreq; - } - - return NULL; -} - -#endif diff --git a/arch/ia64/kvm/mmio.c b/arch/ia64/kvm/mmio.c deleted file mode 100644 index f1e17d3d6cd9..000000000000 --- a/arch/ia64/kvm/mmio.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * mmio.c: MMIO emulation components. - * Copyright (c) 2004, Intel Corporation. - * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) - * Kun Tian (Kevin Tian) (Kevin.tian@intel.com) - * - * Copyright (c) 2007 Intel Corporation KVM support. - * Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include - -#include "vcpu.h" - -static void vlsapic_write_xtp(struct kvm_vcpu *v, uint8_t val) -{ - VLSAPIC_XTP(v) = val; -} - -/* - * LSAPIC OFFSET - */ -#define PIB_LOW_HALF(ofst) !(ofst & (1 << 20)) -#define PIB_OFST_INTA 0x1E0000 -#define PIB_OFST_XTP 0x1E0008 - -/* - * execute write IPI op. - */ -static void vlsapic_write_ipi(struct kvm_vcpu *vcpu, - uint64_t addr, uint64_t data) -{ - struct exit_ctl_data *p = ¤t_vcpu->arch.exit_data; - unsigned long psr; - - local_irq_save(psr); - - p->exit_reason = EXIT_REASON_IPI; - p->u.ipi_data.addr.val = addr; - p->u.ipi_data.data.val = data; - vmm_transition(current_vcpu); - - local_irq_restore(psr); - -} - -void lsapic_write(struct kvm_vcpu *v, unsigned long addr, - unsigned long length, unsigned long val) -{ - addr &= (PIB_SIZE - 1); - - switch (addr) { - case PIB_OFST_INTA: - panic_vm(v, "Undefined write on PIB INTA\n"); - break; - case PIB_OFST_XTP: - if (length == 1) { - vlsapic_write_xtp(v, val); - } else { - panic_vm(v, "Undefined write on PIB XTP\n"); - } - break; - default: - if (PIB_LOW_HALF(addr)) { - /*Lower half */ - if (length != 8) - panic_vm(v, "Can't LHF write with size %ld!\n", - length); - else - vlsapic_write_ipi(v, addr, val); - } else { /*Upper half */ - panic_vm(v, "IPI-UHF write %lx\n", addr); - } - break; - } -} - -unsigned long lsapic_read(struct kvm_vcpu *v, unsigned long addr, - unsigned long length) -{ - uint64_t result = 0; - - addr &= (PIB_SIZE - 1); - - switch (addr) { - case PIB_OFST_INTA: - if (length == 1) /* 1 byte load */ - ; /* There is no i8259, there is no INTA access*/ - else - panic_vm(v, "Undefined read on PIB INTA\n"); - - break; - case PIB_OFST_XTP: - if (length == 1) { - result = VLSAPIC_XTP(v); - } else { - panic_vm(v, "Undefined read on PIB XTP\n"); - } - break; - default: - panic_vm(v, "Undefined addr access for lsapic!\n"); - break; - } - return result; -} - -static void mmio_access(struct kvm_vcpu *vcpu, u64 src_pa, u64 *dest, - u16 s, int ma, int dir) -{ - unsigned long iot; - struct exit_ctl_data *p = &vcpu->arch.exit_data; - unsigned long psr; - - iot = __gpfn_is_io(src_pa >> PAGE_SHIFT); - - local_irq_save(psr); - - /*Intercept the access for PIB range*/ - if (iot == GPFN_PIB) { - if (!dir) - lsapic_write(vcpu, src_pa, s, *dest); - else - *dest = lsapic_read(vcpu, src_pa, s); - goto out; - } - p->exit_reason = EXIT_REASON_MMIO_INSTRUCTION; - p->u.ioreq.addr = src_pa; - p->u.ioreq.size = s; - p->u.ioreq.dir = dir; - if (dir == IOREQ_WRITE) - p->u.ioreq.data = *dest; - p->u.ioreq.state = STATE_IOREQ_READY; - vmm_transition(vcpu); - - if (p->u.ioreq.state == STATE_IORESP_READY) { - if (dir == IOREQ_READ) - /* it's necessary to ensure zero extending */ - *dest = p->u.ioreq.data & (~0UL >> (64-(s*8))); - } else - panic_vm(vcpu, "Unhandled mmio access returned!\n"); -out: - local_irq_restore(psr); - return ; -} - -/* - dir 1: read 0:write - inst_type 0:integer 1:floating point - */ -#define SL_INTEGER 0 /* store/load interger*/ -#define SL_FLOATING 1 /* store/load floating*/ - -void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma) -{ - struct kvm_pt_regs *regs; - IA64_BUNDLE bundle; - int slot, dir = 0; - int inst_type = -1; - u16 size = 0; - u64 data, slot1a, slot1b, temp, update_reg; - s32 imm; - INST64 inst; - - regs = vcpu_regs(vcpu); - - if (fetch_code(vcpu, regs->cr_iip, &bundle)) { - /* if fetch code fail, return and try again */ - return; - } - slot = ((struct ia64_psr *)&(regs->cr_ipsr))->ri; - if (!slot) - inst.inst = bundle.slot0; - else if (slot == 1) { - slot1a = bundle.slot1a; - slot1b = bundle.slot1b; - inst.inst = slot1a + (slot1b << 18); - } else if (slot == 2) - inst.inst = bundle.slot2; - - /* Integer Load/Store */ - if (inst.M1.major == 4 && inst.M1.m == 0 && inst.M1.x == 0) { - inst_type = SL_INTEGER; - size = (inst.M1.x6 & 0x3); - if ((inst.M1.x6 >> 2) > 0xb) { - /*write*/ - dir = IOREQ_WRITE; - data = vcpu_get_gr(vcpu, inst.M4.r2); - } else if ((inst.M1.x6 >> 2) < 0xb) { - /*read*/ - dir = IOREQ_READ; - } - } else if (inst.M2.major == 4 && inst.M2.m == 1 && inst.M2.x == 0) { - /* Integer Load + Reg update */ - inst_type = SL_INTEGER; - dir = IOREQ_READ; - size = (inst.M2.x6 & 0x3); - temp = vcpu_get_gr(vcpu, inst.M2.r3); - update_reg = vcpu_get_gr(vcpu, inst.M2.r2); - temp += update_reg; - vcpu_set_gr(vcpu, inst.M2.r3, temp, 0); - } else if (inst.M3.major == 5) { - /*Integer Load/Store + Imm update*/ - inst_type = SL_INTEGER; - size = (inst.M3.x6&0x3); - if ((inst.M5.x6 >> 2) > 0xb) { - /*write*/ - dir = IOREQ_WRITE; - data = vcpu_get_gr(vcpu, inst.M5.r2); - temp = vcpu_get_gr(vcpu, inst.M5.r3); - imm = (inst.M5.s << 31) | (inst.M5.i << 30) | - (inst.M5.imm7 << 23); - temp += imm >> 23; - vcpu_set_gr(vcpu, inst.M5.r3, temp, 0); - - } else if ((inst.M3.x6 >> 2) < 0xb) { - /*read*/ - dir = IOREQ_READ; - temp = vcpu_get_gr(vcpu, inst.M3.r3); - imm = (inst.M3.s << 31) | (inst.M3.i << 30) | - (inst.M3.imm7 << 23); - temp += imm >> 23; - vcpu_set_gr(vcpu, inst.M3.r3, temp, 0); - - } - } else if (inst.M9.major == 6 && inst.M9.x6 == 0x3B - && inst.M9.m == 0 && inst.M9.x == 0) { - /* Floating-point spill*/ - struct ia64_fpreg v; - - inst_type = SL_FLOATING; - dir = IOREQ_WRITE; - vcpu_get_fpreg(vcpu, inst.M9.f2, &v); - /* Write high word. FIXME: this is a kludge! */ - v.u.bits[1] &= 0x3ffff; - mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], 8, - ma, IOREQ_WRITE); - data = v.u.bits[0]; - size = 3; - } else if (inst.M10.major == 7 && inst.M10.x6 == 0x3B) { - /* Floating-point spill + Imm update */ - struct ia64_fpreg v; - - inst_type = SL_FLOATING; - dir = IOREQ_WRITE; - vcpu_get_fpreg(vcpu, inst.M10.f2, &v); - temp = vcpu_get_gr(vcpu, inst.M10.r3); - imm = (inst.M10.s << 31) | (inst.M10.i << 30) | - (inst.M10.imm7 << 23); - temp += imm >> 23; - vcpu_set_gr(vcpu, inst.M10.r3, temp, 0); - - /* Write high word.FIXME: this is a kludge! */ - v.u.bits[1] &= 0x3ffff; - mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], - 8, ma, IOREQ_WRITE); - data = v.u.bits[0]; - size = 3; - } else if (inst.M10.major == 7 && inst.M10.x6 == 0x31) { - /* Floating-point stf8 + Imm update */ - struct ia64_fpreg v; - inst_type = SL_FLOATING; - dir = IOREQ_WRITE; - size = 3; - vcpu_get_fpreg(vcpu, inst.M10.f2, &v); - data = v.u.bits[0]; /* Significand. */ - temp = vcpu_get_gr(vcpu, inst.M10.r3); - imm = (inst.M10.s << 31) | (inst.M10.i << 30) | - (inst.M10.imm7 << 23); - temp += imm >> 23; - vcpu_set_gr(vcpu, inst.M10.r3, temp, 0); - } else if (inst.M15.major == 7 && inst.M15.x6 >= 0x2c - && inst.M15.x6 <= 0x2f) { - temp = vcpu_get_gr(vcpu, inst.M15.r3); - imm = (inst.M15.s << 31) | (inst.M15.i << 30) | - (inst.M15.imm7 << 23); - temp += imm >> 23; - vcpu_set_gr(vcpu, inst.M15.r3, temp, 0); - - vcpu_increment_iip(vcpu); - return; - } else if (inst.M12.major == 6 && inst.M12.m == 1 - && inst.M12.x == 1 && inst.M12.x6 == 1) { - /* Floating-point Load Pair + Imm ldfp8 M12*/ - struct ia64_fpreg v; - - inst_type = SL_FLOATING; - dir = IOREQ_READ; - size = 8; /*ldfd*/ - mmio_access(vcpu, padr, &data, size, ma, dir); - v.u.bits[0] = data; - v.u.bits[1] = 0x1003E; - vcpu_set_fpreg(vcpu, inst.M12.f1, &v); - padr += 8; - mmio_access(vcpu, padr, &data, size, ma, dir); - v.u.bits[0] = data; - v.u.bits[1] = 0x1003E; - vcpu_set_fpreg(vcpu, inst.M12.f2, &v); - padr += 8; - vcpu_set_gr(vcpu, inst.M12.r3, padr, 0); - vcpu_increment_iip(vcpu); - return; - } else { - inst_type = -1; - panic_vm(vcpu, "Unsupported MMIO access instruction! " - "Bunld[0]=0x%lx, Bundle[1]=0x%lx\n", - bundle.i64[0], bundle.i64[1]); - } - - size = 1 << size; - if (dir == IOREQ_WRITE) { - mmio_access(vcpu, padr, &data, size, ma, dir); - } else { - mmio_access(vcpu, padr, &data, size, ma, dir); - if (inst_type == SL_INTEGER) - vcpu_set_gr(vcpu, inst.M1.r1, data, 0); - else - panic_vm(vcpu, "Unsupported instruction type!\n"); - - } - vcpu_increment_iip(vcpu); -} diff --git a/arch/ia64/kvm/optvfault.S b/arch/ia64/kvm/optvfault.S deleted file mode 100644 index f793be3effff..000000000000 --- a/arch/ia64/kvm/optvfault.S +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * arch/ia64/kvm/optvfault.S - * optimize virtualization fault handler - * - * Copyright (C) 2006 Intel Co - * Xuefei Xu (Anthony Xu) - * Copyright (C) 2008 Intel Co - * Add the support for Tukwila processors. - * Xiantao Zhang - */ - -#include -#include -#include - -#include "vti.h" -#include "asm-offsets.h" - -#define ACCE_MOV_FROM_AR -#define ACCE_MOV_FROM_RR -#define ACCE_MOV_TO_RR -#define ACCE_RSM -#define ACCE_SSM -#define ACCE_MOV_TO_PSR -#define ACCE_THASH - -#define VMX_VPS_SYNC_READ \ - add r16=VMM_VPD_BASE_OFFSET,r21; \ - mov r17 = b0; \ - mov r18 = r24; \ - mov r19 = r25; \ - mov r20 = r31; \ - ;; \ -{.mii; \ - ld8 r16 = [r16]; \ - nop 0x0; \ - mov r24 = ip; \ - ;; \ -}; \ -{.mmb; \ - add r24=0x20, r24; \ - mov r25 =r16; \ - br.sptk.many kvm_vps_sync_read; \ -}; \ - mov b0 = r17; \ - mov r24 = r18; \ - mov r25 = r19; \ - mov r31 = r20 - -ENTRY(kvm_vps_entry) - adds r29 = VMM_VCPU_VSA_BASE_OFFSET,r21 - ;; - ld8 r29 = [r29] - ;; - add r29 = r29, r30 - ;; - mov b0 = r29 - br.sptk.many b0 -END(kvm_vps_entry) - -/* - * Inputs: - * r24 : return address - * r25 : vpd - * r29 : scratch - * - */ -GLOBAL_ENTRY(kvm_vps_sync_read) - movl r30 = PAL_VPS_SYNC_READ - ;; - br.sptk.many kvm_vps_entry -END(kvm_vps_sync_read) - -/* - * Inputs: - * r24 : return address - * r25 : vpd - * r29 : scratch - * - */ -GLOBAL_ENTRY(kvm_vps_sync_write) - movl r30 = PAL_VPS_SYNC_WRITE - ;; - br.sptk.many kvm_vps_entry -END(kvm_vps_sync_write) - -/* - * Inputs: - * r23 : pr - * r24 : guest b0 - * r25 : vpd - * - */ -GLOBAL_ENTRY(kvm_vps_resume_normal) - movl r30 = PAL_VPS_RESUME_NORMAL - ;; - mov pr=r23,-2 - br.sptk.many kvm_vps_entry -END(kvm_vps_resume_normal) - -/* - * Inputs: - * r23 : pr - * r24 : guest b0 - * r25 : vpd - * r17 : isr - */ -GLOBAL_ENTRY(kvm_vps_resume_handler) - movl r30 = PAL_VPS_RESUME_HANDLER - ;; - ld8 r26=[r25] - shr r17=r17,IA64_ISR_IR_BIT - ;; - dep r26=r17,r26,63,1 // bit 63 of r26 indicate whether enable CFLE - mov pr=r23,-2 - br.sptk.many kvm_vps_entry -END(kvm_vps_resume_handler) - -//mov r1=ar3 -GLOBAL_ENTRY(kvm_asm_mov_from_ar) -#ifndef ACCE_MOV_FROM_AR - br.many kvm_virtualization_fault_back -#endif - add r18=VMM_VCPU_ITC_OFS_OFFSET, r21 - add r16=VMM_VCPU_LAST_ITC_OFFSET,r21 - extr.u r17=r25,6,7 - ;; - ld8 r18=[r18] - mov r19=ar.itc - mov r24=b0 - ;; - add r19=r19,r18 - addl r20=@gprel(asm_mov_to_reg),gp - ;; - st8 [r16] = r19 - adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20 - shladd r17=r17,4,r20 - ;; - mov b0=r17 - br.sptk.few b0 - ;; -END(kvm_asm_mov_from_ar) - -/* - * Special SGI SN2 optimized version of mov_from_ar using the SN2 RTC - * clock as it's source for emulating the ITC. This version will be - * copied on top of the original version if the host is determined to - * be an SN2. - */ -GLOBAL_ENTRY(kvm_asm_mov_from_ar_sn2) - add r18=VMM_VCPU_ITC_OFS_OFFSET, r21 - movl r19 = (KVM_VMM_BASE+(1<arch.vrr[0]'s addr - adds r16=VMM_VPD_VPTA_OFFSET,r16 // get vpta - ;; - shladd r27=r23,3,r28 // get vcpu->arch.vrr[r23]'s addr - ld8 r17=[r16] // get PTA - mov r26=1 - ;; - extr.u r29=r17,2,6 // get pta.size - ld8 r28=[r27] // get vcpu->arch.vrr[r23]'s value - ;; - mov b0=r24 - //Fallback to C if pta.vf is set - tbit.nz p6,p0=r17, 8 - ;; - (p6) mov r24=EVENT_THASH - (p6) br.cond.dpnt.many kvm_virtualization_fault_back - extr.u r28=r28,2,6 // get rr.ps - shl r22=r26,r29 // 1UL << pta.size - ;; - shr.u r23=r19,r28 // vaddr >> rr.ps - adds r26=3,r29 // pta.size + 3 - shl r27=r17,3 // pta << 3 - ;; - shl r23=r23,3 // (vaddr >> rr.ps) << 3 - shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3) - movl r16=7<<61 - ;; - adds r22=-1,r22 // (1UL << pta.size) - 1 - shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<>(pta.size + 3))< - * Xiaoyan Feng (Fleming Feng) - * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) - * Xiantao Zhang (xiantao.zhang@intel.com) - */ -#include "vcpu.h" - -#include -#include -#include -#include -#include - -fpswa_interface_t *vmm_fpswa_interface; - -#define IA64_VHPT_TRANS_VECTOR 0x0000 -#define IA64_INST_TLB_VECTOR 0x0400 -#define IA64_DATA_TLB_VECTOR 0x0800 -#define IA64_ALT_INST_TLB_VECTOR 0x0c00 -#define IA64_ALT_DATA_TLB_VECTOR 0x1000 -#define IA64_DATA_NESTED_TLB_VECTOR 0x1400 -#define IA64_INST_KEY_MISS_VECTOR 0x1800 -#define IA64_DATA_KEY_MISS_VECTOR 0x1c00 -#define IA64_DIRTY_BIT_VECTOR 0x2000 -#define IA64_INST_ACCESS_BIT_VECTOR 0x2400 -#define IA64_DATA_ACCESS_BIT_VECTOR 0x2800 -#define IA64_BREAK_VECTOR 0x2c00 -#define IA64_EXTINT_VECTOR 0x3000 -#define IA64_PAGE_NOT_PRESENT_VECTOR 0x5000 -#define IA64_KEY_PERMISSION_VECTOR 0x5100 -#define IA64_INST_ACCESS_RIGHTS_VECTOR 0x5200 -#define IA64_DATA_ACCESS_RIGHTS_VECTOR 0x5300 -#define IA64_GENEX_VECTOR 0x5400 -#define IA64_DISABLED_FPREG_VECTOR 0x5500 -#define IA64_NAT_CONSUMPTION_VECTOR 0x5600 -#define IA64_SPECULATION_VECTOR 0x5700 /* UNUSED */ -#define IA64_DEBUG_VECTOR 0x5900 -#define IA64_UNALIGNED_REF_VECTOR 0x5a00 -#define IA64_UNSUPPORTED_DATA_REF_VECTOR 0x5b00 -#define IA64_FP_FAULT_VECTOR 0x5c00 -#define IA64_FP_TRAP_VECTOR 0x5d00 -#define IA64_LOWERPRIV_TRANSFER_TRAP_VECTOR 0x5e00 -#define IA64_TAKEN_BRANCH_TRAP_VECTOR 0x5f00 -#define IA64_SINGLE_STEP_TRAP_VECTOR 0x6000 - -/* SDM vol2 5.5 - IVA based interruption handling */ -#define INITIAL_PSR_VALUE_AT_INTERRUPTION (IA64_PSR_UP | IA64_PSR_MFL |\ - IA64_PSR_MFH | IA64_PSR_PK | IA64_PSR_DT | \ - IA64_PSR_RT | IA64_PSR_MC|IA64_PSR_IT) - -#define DOMN_PAL_REQUEST 0x110000 -#define DOMN_SAL_REQUEST 0x110001 - -static u64 vec2off[68] = {0x0, 0x400, 0x800, 0xc00, 0x1000, 0x1400, 0x1800, - 0x1c00, 0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, - 0x4000, 0x4400, 0x4800, 0x4c00, 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, - 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, - 0x5e00, 0x5f00, 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, - 0x6700, 0x6800, 0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00, - 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, 0x7800, - 0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00 -}; - -static void collect_interruption(struct kvm_vcpu *vcpu) -{ - u64 ipsr; - u64 vdcr; - u64 vifs; - unsigned long vpsr; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - vpsr = vcpu_get_psr(vcpu); - vcpu_bsw0(vcpu); - if (vpsr & IA64_PSR_IC) { - - /* Sync mpsr id/da/dd/ss/ed bits to vipsr - * since after guest do rfi, we still want these bits on in - * mpsr - */ - - ipsr = regs->cr_ipsr; - vpsr = vpsr | (ipsr & (IA64_PSR_ID | IA64_PSR_DA - | IA64_PSR_DD | IA64_PSR_SS - | IA64_PSR_ED)); - vcpu_set_ipsr(vcpu, vpsr); - - /* Currently, for trap, we do not advance IIP to next - * instruction. That's because we assume caller already - * set up IIP correctly - */ - - vcpu_set_iip(vcpu , regs->cr_iip); - - /* set vifs.v to zero */ - vifs = VCPU(vcpu, ifs); - vifs &= ~IA64_IFS_V; - vcpu_set_ifs(vcpu, vifs); - - vcpu_set_iipa(vcpu, VMX(vcpu, cr_iipa)); - } - - vdcr = VCPU(vcpu, dcr); - - /* Set guest psr - * up/mfl/mfh/pk/dt/rt/mc/it keeps unchanged - * be: set to the value of dcr.be - * pp: set to the value of dcr.pp - */ - vpsr &= INITIAL_PSR_VALUE_AT_INTERRUPTION; - vpsr |= (vdcr & IA64_DCR_BE); - - /* VDCR pp bit position is different from VPSR pp bit */ - if (vdcr & IA64_DCR_PP) { - vpsr |= IA64_PSR_PP; - } else { - vpsr &= ~IA64_PSR_PP; - } - - vcpu_set_psr(vcpu, vpsr); - -} - -void inject_guest_interruption(struct kvm_vcpu *vcpu, u64 vec) -{ - u64 viva; - struct kvm_pt_regs *regs; - union ia64_isr pt_isr; - - regs = vcpu_regs(vcpu); - - /* clear cr.isr.ir (incomplete register frame)*/ - pt_isr.val = VMX(vcpu, cr_isr); - pt_isr.ir = 0; - VMX(vcpu, cr_isr) = pt_isr.val; - - collect_interruption(vcpu); - - viva = vcpu_get_iva(vcpu); - regs->cr_iip = viva + vec; -} - -static u64 vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, u64 ifa) -{ - union ia64_rr rr, rr1; - - rr.val = vcpu_get_rr(vcpu, ifa); - rr1.val = 0; - rr1.ps = rr.ps; - rr1.rid = rr.rid; - return (rr1.val); -} - -/* - * Set vIFA & vITIR & vIHA, when vPSR.ic =1 - * Parameter: - * set_ifa: if true, set vIFA - * set_itir: if true, set vITIR - * set_iha: if true, set vIHA - */ -void set_ifa_itir_iha(struct kvm_vcpu *vcpu, u64 vadr, - int set_ifa, int set_itir, int set_iha) -{ - long vpsr; - u64 value; - - vpsr = VCPU(vcpu, vpsr); - /* Vol2, Table 8-1 */ - if (vpsr & IA64_PSR_IC) { - if (set_ifa) - vcpu_set_ifa(vcpu, vadr); - if (set_itir) { - value = vcpu_get_itir_on_fault(vcpu, vadr); - vcpu_set_itir(vcpu, value); - } - - if (set_iha) { - value = vcpu_thash(vcpu, vadr); - vcpu_set_iha(vcpu, value); - } - } -} - -/* - * Data TLB Fault - * @ Data TLB vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void dtlb_fault(struct kvm_vcpu *vcpu, u64 vadr) -{ - /* If vPSR.ic, IFA, ITIR, IHA */ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); - inject_guest_interruption(vcpu, IA64_DATA_TLB_VECTOR); -} - -/* - * Instruction TLB Fault - * @ Instruction TLB vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void itlb_fault(struct kvm_vcpu *vcpu, u64 vadr) -{ - /* If vPSR.ic, IFA, ITIR, IHA */ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); - inject_guest_interruption(vcpu, IA64_INST_TLB_VECTOR); -} - -/* - * Data Nested TLB Fault - * @ Data Nested TLB Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void nested_dtlb(struct kvm_vcpu *vcpu) -{ - inject_guest_interruption(vcpu, IA64_DATA_NESTED_TLB_VECTOR); -} - -/* - * Alternate Data TLB Fault - * @ Alternate Data TLB vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void alt_dtlb(struct kvm_vcpu *vcpu, u64 vadr) -{ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); - inject_guest_interruption(vcpu, IA64_ALT_DATA_TLB_VECTOR); -} - -/* - * Data TLB Fault - * @ Data TLB vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void alt_itlb(struct kvm_vcpu *vcpu, u64 vadr) -{ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); - inject_guest_interruption(vcpu, IA64_ALT_INST_TLB_VECTOR); -} - -/* Deal with: - * VHPT Translation Vector - */ -static void _vhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) -{ - /* If vPSR.ic, IFA, ITIR, IHA*/ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 1); - inject_guest_interruption(vcpu, IA64_VHPT_TRANS_VECTOR); -} - -/* - * VHPT Instruction Fault - * @ VHPT Translation vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void ivhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) -{ - _vhpt_fault(vcpu, vadr); -} - -/* - * VHPT Data Fault - * @ VHPT Translation vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void dvhpt_fault(struct kvm_vcpu *vcpu, u64 vadr) -{ - _vhpt_fault(vcpu, vadr); -} - -/* - * Deal with: - * General Exception vector - */ -void _general_exception(struct kvm_vcpu *vcpu) -{ - inject_guest_interruption(vcpu, IA64_GENEX_VECTOR); -} - -/* - * Illegal Operation Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void illegal_op(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} - -/* - * Illegal Dependency Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void illegal_dep(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} - -/* - * Reserved Register/Field Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void rsv_reg_field(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} -/* - * Privileged Operation Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ - -void privilege_op(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} - -/* - * Unimplement Data Address Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void unimpl_daddr(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} - -/* - * Privileged Register Fault - * @ General Exception Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void privilege_reg(struct kvm_vcpu *vcpu) -{ - _general_exception(vcpu); -} - -/* Deal with - * Nat consumption vector - * Parameter: - * vaddr: Optional, if t == REGISTER - */ -static void _nat_consumption_fault(struct kvm_vcpu *vcpu, u64 vadr, - enum tlb_miss_type t) -{ - /* If vPSR.ic && t == DATA/INST, IFA */ - if (t == DATA || t == INSTRUCTION) { - /* IFA */ - set_ifa_itir_iha(vcpu, vadr, 1, 0, 0); - } - - inject_guest_interruption(vcpu, IA64_NAT_CONSUMPTION_VECTOR); -} - -/* - * Instruction Nat Page Consumption Fault - * @ Nat Consumption Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void inat_page_consumption(struct kvm_vcpu *vcpu, u64 vadr) -{ - _nat_consumption_fault(vcpu, vadr, INSTRUCTION); -} - -/* - * Register Nat Consumption Fault - * @ Nat Consumption Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void rnat_consumption(struct kvm_vcpu *vcpu) -{ - _nat_consumption_fault(vcpu, 0, REGISTER); -} - -/* - * Data Nat Page Consumption Fault - * @ Nat Consumption Vector - * Refer to SDM Vol2 Table 5-6 & 8-1 - */ -void dnat_page_consumption(struct kvm_vcpu *vcpu, u64 vadr) -{ - _nat_consumption_fault(vcpu, vadr, DATA); -} - -/* Deal with - * Page not present vector - */ -static void __page_not_present(struct kvm_vcpu *vcpu, u64 vadr) -{ - /* If vPSR.ic, IFA, ITIR */ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); - inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR); -} - -void data_page_not_present(struct kvm_vcpu *vcpu, u64 vadr) -{ - __page_not_present(vcpu, vadr); -} - -void inst_page_not_present(struct kvm_vcpu *vcpu, u64 vadr) -{ - __page_not_present(vcpu, vadr); -} - -/* Deal with - * Data access rights vector - */ -void data_access_rights(struct kvm_vcpu *vcpu, u64 vadr) -{ - /* If vPSR.ic, IFA, ITIR */ - set_ifa_itir_iha(vcpu, vadr, 1, 1, 0); - inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR); -} - -fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr, - unsigned long *fpsr, unsigned long *isr, unsigned long *pr, - unsigned long *ifs, struct kvm_pt_regs *regs) -{ - fp_state_t fp_state; - fpswa_ret_t ret; - struct kvm_vcpu *vcpu = current_vcpu; - - uint64_t old_rr7 = ia64_get_rr(7UL<<61); - - if (!vmm_fpswa_interface) - return (fpswa_ret_t) {-1, 0, 0, 0}; - - memset(&fp_state, 0, sizeof(fp_state_t)); - - /* - * compute fp_state. only FP registers f6 - f11 are used by the - * vmm, so set those bits in the mask and set the low volatile - * pointer to point to these registers. - */ - fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ - - fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; - - /* - * unsigned long (*EFI_FPSWA) ( - * unsigned long trap_type, - * void *Bundle, - * unsigned long *pipsr, - * unsigned long *pfsr, - * unsigned long *pisr, - * unsigned long *ppreds, - * unsigned long *pifs, - * void *fp_state); - */ - /*Call host fpswa interface directly to virtualize - *guest fpswa request! - */ - ia64_set_rr(7UL << 61, vcpu->arch.host.rr[7]); - ia64_srlz_d(); - - ret = (*vmm_fpswa_interface->fpswa) (fp_fault, bundle, - ipsr, fpsr, isr, pr, ifs, &fp_state); - ia64_set_rr(7UL << 61, old_rr7); - ia64_srlz_d(); - return ret; -} - -/* - * Handle floating-point assist faults and traps for domain. - */ -unsigned long vmm_handle_fpu_swa(int fp_fault, struct kvm_pt_regs *regs, - unsigned long isr) -{ - struct kvm_vcpu *v = current_vcpu; - IA64_BUNDLE bundle; - unsigned long fault_ip; - fpswa_ret_t ret; - - fault_ip = regs->cr_iip; - /* - * When the FP trap occurs, the trapping instruction is completed. - * If ipsr.ri == 0, there is the trapping instruction in previous - * bundle. - */ - if (!fp_fault && (ia64_psr(regs)->ri == 0)) - fault_ip -= 16; - - if (fetch_code(v, fault_ip, &bundle)) - return -EAGAIN; - - if (!bundle.i64[0] && !bundle.i64[1]) - return -EACCES; - - ret = vmm_fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr, - &isr, ®s->pr, ®s->cr_ifs, regs); - return ret.status; -} - -void reflect_interruption(u64 ifa, u64 isr, u64 iim, - u64 vec, struct kvm_pt_regs *regs) -{ - u64 vector; - int status ; - struct kvm_vcpu *vcpu = current_vcpu; - u64 vpsr = VCPU(vcpu, vpsr); - - vector = vec2off[vec]; - - if (!(vpsr & IA64_PSR_IC) && (vector != IA64_DATA_NESTED_TLB_VECTOR)) { - panic_vm(vcpu, "Interruption with vector :0x%lx occurs " - "with psr.ic = 0\n", vector); - return; - } - - switch (vec) { - case 32: /*IA64_FP_FAULT_VECTOR*/ - status = vmm_handle_fpu_swa(1, regs, isr); - if (!status) { - vcpu_increment_iip(vcpu); - return; - } else if (-EAGAIN == status) - return; - break; - case 33: /*IA64_FP_TRAP_VECTOR*/ - status = vmm_handle_fpu_swa(0, regs, isr); - if (!status) - return ; - break; - } - - VCPU(vcpu, isr) = isr; - VCPU(vcpu, iipa) = regs->cr_iip; - if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) - VCPU(vcpu, iim) = iim; - else - set_ifa_itir_iha(vcpu, ifa, 1, 1, 1); - - inject_guest_interruption(vcpu, vector); -} - -static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu, - unsigned long arg) -{ - struct thash_data *data; - unsigned long gpa, poff; - - if (!is_physical_mode(vcpu)) { - /* Depends on caller to provide the DTR or DTC mapping.*/ - data = vtlb_lookup(vcpu, arg, D_TLB); - if (data) - gpa = data->page_flags & _PAGE_PPN_MASK; - else { - data = vhpt_lookup(arg); - if (!data) - return 0; - gpa = data->gpaddr & _PAGE_PPN_MASK; - } - - poff = arg & (PSIZE(data->ps) - 1); - arg = PAGEALIGN(gpa, data->ps) | poff; - } - arg = kvm_gpa_to_mpa(arg << 1 >> 1); - - return (unsigned long)__va(arg); -} - -static void set_pal_call_data(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - unsigned long gr28 = vcpu_get_gr(vcpu, 28); - unsigned long gr29 = vcpu_get_gr(vcpu, 29); - unsigned long gr30 = vcpu_get_gr(vcpu, 30); - - /*FIXME:For static and stacked convention, firmware - * has put the parameters in gr28-gr31 before - * break to vmm !!*/ - - switch (gr28) { - case PAL_PERF_MON_INFO: - case PAL_HALT_INFO: - p->u.pal_data.gr29 = kvm_trans_pal_call_args(vcpu, gr29); - p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); - break; - case PAL_BRAND_INFO: - p->u.pal_data.gr29 = gr29; - p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30); - break; - default: - p->u.pal_data.gr29 = gr29; - p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); - } - p->u.pal_data.gr28 = gr28; - p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31); - - p->exit_reason = EXIT_REASON_PAL_CALL; -} - -static void get_pal_call_result(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - - if (p->exit_reason == EXIT_REASON_PAL_CALL) { - vcpu_set_gr(vcpu, 8, p->u.pal_data.ret.status, 0); - vcpu_set_gr(vcpu, 9, p->u.pal_data.ret.v0, 0); - vcpu_set_gr(vcpu, 10, p->u.pal_data.ret.v1, 0); - vcpu_set_gr(vcpu, 11, p->u.pal_data.ret.v2, 0); - } else - panic_vm(vcpu, "Mis-set for exit reason!\n"); -} - -static void set_sal_call_data(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - - p->u.sal_data.in0 = vcpu_get_gr(vcpu, 32); - p->u.sal_data.in1 = vcpu_get_gr(vcpu, 33); - p->u.sal_data.in2 = vcpu_get_gr(vcpu, 34); - p->u.sal_data.in3 = vcpu_get_gr(vcpu, 35); - p->u.sal_data.in4 = vcpu_get_gr(vcpu, 36); - p->u.sal_data.in5 = vcpu_get_gr(vcpu, 37); - p->u.sal_data.in6 = vcpu_get_gr(vcpu, 38); - p->u.sal_data.in7 = vcpu_get_gr(vcpu, 39); - p->exit_reason = EXIT_REASON_SAL_CALL; -} - -static void get_sal_call_result(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - - if (p->exit_reason == EXIT_REASON_SAL_CALL) { - vcpu_set_gr(vcpu, 8, p->u.sal_data.ret.r8, 0); - vcpu_set_gr(vcpu, 9, p->u.sal_data.ret.r9, 0); - vcpu_set_gr(vcpu, 10, p->u.sal_data.ret.r10, 0); - vcpu_set_gr(vcpu, 11, p->u.sal_data.ret.r11, 0); - } else - panic_vm(vcpu, "Mis-set for exit reason!\n"); -} - -void kvm_ia64_handle_break(unsigned long ifa, struct kvm_pt_regs *regs, - unsigned long isr, unsigned long iim) -{ - struct kvm_vcpu *v = current_vcpu; - long psr; - - if (ia64_psr(regs)->cpl == 0) { - /* Allow hypercalls only when cpl = 0. */ - if (iim == DOMN_PAL_REQUEST) { - local_irq_save(psr); - set_pal_call_data(v); - vmm_transition(v); - get_pal_call_result(v); - vcpu_increment_iip(v); - local_irq_restore(psr); - return; - } else if (iim == DOMN_SAL_REQUEST) { - local_irq_save(psr); - set_sal_call_data(v); - vmm_transition(v); - get_sal_call_result(v); - vcpu_increment_iip(v); - local_irq_restore(psr); - return; - } - } - reflect_interruption(ifa, isr, iim, 11, regs); -} - -void check_pending_irq(struct kvm_vcpu *vcpu) -{ - int mask, h_pending, h_inservice; - u64 isr; - unsigned long vpsr; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - h_pending = highest_pending_irq(vcpu); - if (h_pending == NULL_VECTOR) { - update_vhpi(vcpu, NULL_VECTOR); - return; - } - h_inservice = highest_inservice_irq(vcpu); - - vpsr = VCPU(vcpu, vpsr); - mask = irq_masked(vcpu, h_pending, h_inservice); - if ((vpsr & IA64_PSR_I) && IRQ_NO_MASKED == mask) { - isr = vpsr & IA64_PSR_RI; - update_vhpi(vcpu, h_pending); - reflect_interruption(0, isr, 0, 12, regs); /* EXT IRQ */ - } else if (mask == IRQ_MASKED_BY_INSVC) { - if (VCPU(vcpu, vhpi)) - update_vhpi(vcpu, NULL_VECTOR); - } else { - /* masked by vpsr.i or vtpr.*/ - update_vhpi(vcpu, h_pending); - } -} - -static void generate_exirq(struct kvm_vcpu *vcpu) -{ - unsigned vpsr; - uint64_t isr; - - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - vpsr = VCPU(vcpu, vpsr); - isr = vpsr & IA64_PSR_RI; - if (!(vpsr & IA64_PSR_IC)) - panic_vm(vcpu, "Trying to inject one IRQ with psr.ic=0\n"); - reflect_interruption(0, isr, 0, 12, regs); /* EXT IRQ */ -} - -void vhpi_detection(struct kvm_vcpu *vcpu) -{ - uint64_t threshold, vhpi; - union ia64_tpr vtpr; - struct ia64_psr vpsr; - - vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - vtpr.val = VCPU(vcpu, tpr); - - threshold = ((!vpsr.i) << 5) | (vtpr.mmi << 4) | vtpr.mic; - vhpi = VCPU(vcpu, vhpi); - if (vhpi > threshold) { - /* interrupt actived*/ - generate_exirq(vcpu); - } -} - -void leave_hypervisor_tail(void) -{ - struct kvm_vcpu *v = current_vcpu; - - if (VMX(v, timer_check)) { - VMX(v, timer_check) = 0; - if (VMX(v, itc_check)) { - if (vcpu_get_itc(v) > VCPU(v, itm)) { - if (!(VCPU(v, itv) & (1 << 16))) { - vcpu_pend_interrupt(v, VCPU(v, itv) - & 0xff); - VMX(v, itc_check) = 0; - } else { - v->arch.timer_pending = 1; - } - VMX(v, last_itc) = VCPU(v, itm) + 1; - } - } - } - - rmb(); - if (v->arch.irq_new_pending) { - v->arch.irq_new_pending = 0; - VMX(v, irq_check) = 0; - check_pending_irq(v); - return; - } - if (VMX(v, irq_check)) { - VMX(v, irq_check) = 0; - vhpi_detection(v); - } -} - -static inline void handle_lds(struct kvm_pt_regs *regs) -{ - regs->cr_ipsr |= IA64_PSR_ED; -} - -void physical_tlb_miss(struct kvm_vcpu *vcpu, unsigned long vadr, int type) -{ - unsigned long pte; - union ia64_rr rr; - - rr.val = ia64_get_rr(vadr); - pte = vadr & _PAGE_PPN_MASK; - pte = pte | PHY_PAGE_WB; - thash_vhpt_insert(vcpu, pte, (u64)(rr.ps << 2), vadr, type); - return; -} - -void kvm_page_fault(u64 vadr , u64 vec, struct kvm_pt_regs *regs) -{ - unsigned long vpsr; - int type; - - u64 vhpt_adr, gppa, pteval, rr, itir; - union ia64_isr misr; - union ia64_pta vpta; - struct thash_data *data; - struct kvm_vcpu *v = current_vcpu; - - vpsr = VCPU(v, vpsr); - misr.val = VMX(v, cr_isr); - - type = vec; - - if (is_physical_mode(v) && (!(vadr << 1 >> 62))) { - if (vec == 2) { - if (__gpfn_is_io((vadr << 1) >> (PAGE_SHIFT + 1))) { - emulate_io_inst(v, ((vadr << 1) >> 1), 4); - return; - } - } - physical_tlb_miss(v, vadr, type); - return; - } - data = vtlb_lookup(v, vadr, type); - if (data != 0) { - if (type == D_TLB) { - gppa = (vadr & ((1UL << data->ps) - 1)) - + (data->ppn >> (data->ps - 12) << data->ps); - if (__gpfn_is_io(gppa >> PAGE_SHIFT)) { - if (data->pl >= ((regs->cr_ipsr >> - IA64_PSR_CPL0_BIT) & 3)) - emulate_io_inst(v, gppa, data->ma); - else { - vcpu_set_isr(v, misr.val); - data_access_rights(v, vadr); - } - return ; - } - } - thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type); - - } else if (type == D_TLB) { - if (misr.sp) { - handle_lds(regs); - return; - } - - rr = vcpu_get_rr(v, vadr); - itir = rr & (RR_RID_MASK | RR_PS_MASK); - - if (!vhpt_enabled(v, vadr, misr.rs ? RSE_REF : DATA_REF)) { - if (vpsr & IA64_PSR_IC) { - vcpu_set_isr(v, misr.val); - alt_dtlb(v, vadr); - } else { - nested_dtlb(v); - } - return ; - } - - vpta.val = vcpu_get_pta(v); - /* avoid recursively walking (short format) VHPT */ - - vhpt_adr = vcpu_thash(v, vadr); - if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { - /* VHPT successfully read. */ - if (!(pteval & _PAGE_P)) { - if (vpsr & IA64_PSR_IC) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - } else { - nested_dtlb(v); - } - } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) { - thash_purge_and_insert(v, pteval, itir, - vadr, D_TLB); - } else if (vpsr & IA64_PSR_IC) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - } else { - nested_dtlb(v); - } - } else { - /* Can't read VHPT. */ - if (vpsr & IA64_PSR_IC) { - vcpu_set_isr(v, misr.val); - dvhpt_fault(v, vadr); - } else { - nested_dtlb(v); - } - } - } else if (type == I_TLB) { - if (!(vpsr & IA64_PSR_IC)) - misr.ni = 1; - if (!vhpt_enabled(v, vadr, INST_REF)) { - vcpu_set_isr(v, misr.val); - alt_itlb(v, vadr); - return; - } - - vpta.val = vcpu_get_pta(v); - - vhpt_adr = vcpu_thash(v, vadr); - if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { - /* VHPT successfully read. */ - if (pteval & _PAGE_P) { - if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) { - vcpu_set_isr(v, misr.val); - itlb_fault(v, vadr); - return ; - } - rr = vcpu_get_rr(v, vadr); - itir = rr & (RR_RID_MASK | RR_PS_MASK); - thash_purge_and_insert(v, pteval, itir, - vadr, I_TLB); - } else { - vcpu_set_isr(v, misr.val); - inst_page_not_present(v, vadr); - } - } else { - vcpu_set_isr(v, misr.val); - ivhpt_fault(v, vadr); - } - } -} - -void kvm_vexirq(struct kvm_vcpu *vcpu) -{ - u64 vpsr, isr; - struct kvm_pt_regs *regs; - - regs = vcpu_regs(vcpu); - vpsr = VCPU(vcpu, vpsr); - isr = vpsr & IA64_PSR_RI; - reflect_interruption(0, isr, 0, 12, regs); /*EXT IRQ*/ -} - -void kvm_ia64_handle_irq(struct kvm_vcpu *v) -{ - struct exit_ctl_data *p = &v->arch.exit_data; - long psr; - - local_irq_save(psr); - p->exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT; - vmm_transition(v); - local_irq_restore(psr); - - VMX(v, timer_check) = 1; - -} - -static void ptc_ga_remote_func(struct kvm_vcpu *v, int pos) -{ - u64 oldrid, moldrid, oldpsbits, vaddr; - struct kvm_ptc_g *p = &v->arch.ptc_g_data[pos]; - vaddr = p->vaddr; - - oldrid = VMX(v, vrr[0]); - VMX(v, vrr[0]) = p->rr; - oldpsbits = VMX(v, psbits[0]); - VMX(v, psbits[0]) = VMX(v, psbits[REGION_NUMBER(vaddr)]); - moldrid = ia64_get_rr(0x0); - ia64_set_rr(0x0, vrrtomrr(p->rr)); - ia64_srlz_d(); - - vaddr = PAGEALIGN(vaddr, p->ps); - thash_purge_entries_remote(v, vaddr, p->ps); - - VMX(v, vrr[0]) = oldrid; - VMX(v, psbits[0]) = oldpsbits; - ia64_set_rr(0x0, moldrid); - ia64_dv_serialize_data(); -} - -static void vcpu_do_resume(struct kvm_vcpu *vcpu) -{ - /*Re-init VHPT and VTLB once from resume*/ - vcpu->arch.vhpt.num = VHPT_NUM_ENTRIES; - thash_init(&vcpu->arch.vhpt, VHPT_SHIFT); - vcpu->arch.vtlb.num = VTLB_NUM_ENTRIES; - thash_init(&vcpu->arch.vtlb, VTLB_SHIFT); - - ia64_set_pta(vcpu->arch.vhpt.pta.val); -} - -static void vmm_sanity_check(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - - if (!vmm_sanity && p->exit_reason != EXIT_REASON_DEBUG) { - panic_vm(vcpu, "Failed to do vmm sanity check," - "it maybe caused by crashed vmm!!\n\n"); - } -} - -static void kvm_do_resume_op(struct kvm_vcpu *vcpu) -{ - vmm_sanity_check(vcpu); /*Guarantee vcpu running on healthy vmm!*/ - - if (test_and_clear_bit(KVM_REQ_RESUME, &vcpu->requests)) { - vcpu_do_resume(vcpu); - return; - } - - if (unlikely(test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))) { - thash_purge_all(vcpu); - return; - } - - if (test_and_clear_bit(KVM_REQ_PTC_G, &vcpu->requests)) { - while (vcpu->arch.ptc_g_count > 0) - ptc_ga_remote_func(vcpu, --vcpu->arch.ptc_g_count); - } -} - -void vmm_transition(struct kvm_vcpu *vcpu) -{ - ia64_call_vsa(PAL_VPS_SAVE, (unsigned long)vcpu->arch.vpd, - 1, 0, 0, 0, 0, 0); - vmm_trampoline(&vcpu->arch.guest, &vcpu->arch.host); - ia64_call_vsa(PAL_VPS_RESTORE, (unsigned long)vcpu->arch.vpd, - 1, 0, 0, 0, 0, 0); - kvm_do_resume_op(vcpu); -} - -void vmm_panic_handler(u64 vec) -{ - struct kvm_vcpu *vcpu = current_vcpu; - vmm_sanity = 0; - panic_vm(vcpu, "Unexpected interruption occurs in VMM, vector:0x%lx\n", - vec2off[vec]); -} diff --git a/arch/ia64/kvm/trampoline.S b/arch/ia64/kvm/trampoline.S deleted file mode 100644 index 30897d44d61e..000000000000 --- a/arch/ia64/kvm/trampoline.S +++ /dev/null @@ -1,1038 +0,0 @@ -/* Save all processor states - * - * Copyright (c) 2007 Fleming Feng - * Copyright (c) 2007 Anthony Xu - */ - -#include -#include "asm-offsets.h" - - -#define CTX(name) VMM_CTX_##name##_OFFSET - - /* - * r32: context_t base address - */ -#define SAVE_BRANCH_REGS \ - add r2 = CTX(B0),r32; \ - add r3 = CTX(B1),r32; \ - mov r16 = b0; \ - mov r17 = b1; \ - ;; \ - st8 [r2]=r16,16; \ - st8 [r3]=r17,16; \ - ;; \ - mov r16 = b2; \ - mov r17 = b3; \ - ;; \ - st8 [r2]=r16,16; \ - st8 [r3]=r17,16; \ - ;; \ - mov r16 = b4; \ - mov r17 = b5; \ - ;; \ - st8 [r2]=r16; \ - st8 [r3]=r17; \ - ;; - - /* - * r33: context_t base address - */ -#define RESTORE_BRANCH_REGS \ - add r2 = CTX(B0),r33; \ - add r3 = CTX(B1),r33; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov b0 = r16; \ - mov b1 = r17; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov b2 = r16; \ - mov b3 = r17; \ - ;; \ - ld8 r16=[r2]; \ - ld8 r17=[r3]; \ - ;; \ - mov b4=r16; \ - mov b5=r17; \ - ;; - - - /* - * r32: context_t base address - * bsw == 1 - * Save all bank1 general registers, r4 ~ r7 - */ -#define SAVE_GENERAL_REGS \ - add r2=CTX(R4),r32; \ - add r3=CTX(R5),r32; \ - ;; \ -.mem.offset 0,0; \ - st8.spill [r2]=r4,16; \ -.mem.offset 8,0; \ - st8.spill [r3]=r5,16; \ - ;; \ -.mem.offset 0,0; \ - st8.spill [r2]=r6,48; \ -.mem.offset 8,0; \ - st8.spill [r3]=r7,48; \ - ;; \ -.mem.offset 0,0; \ - st8.spill [r2]=r12; \ -.mem.offset 8,0; \ - st8.spill [r3]=r13; \ - ;; - - /* - * r33: context_t base address - * bsw == 1 - */ -#define RESTORE_GENERAL_REGS \ - add r2=CTX(R4),r33; \ - add r3=CTX(R5),r33; \ - ;; \ - ld8.fill r4=[r2],16; \ - ld8.fill r5=[r3],16; \ - ;; \ - ld8.fill r6=[r2],48; \ - ld8.fill r7=[r3],48; \ - ;; \ - ld8.fill r12=[r2]; \ - ld8.fill r13 =[r3]; \ - ;; - - - - - /* - * r32: context_t base address - */ -#define SAVE_KERNEL_REGS \ - add r2 = CTX(KR0),r32; \ - add r3 = CTX(KR1),r32; \ - mov r16 = ar.k0; \ - mov r17 = ar.k1; \ - ;; \ - st8 [r2] = r16,16; \ - st8 [r3] = r17,16; \ - ;; \ - mov r16 = ar.k2; \ - mov r17 = ar.k3; \ - ;; \ - st8 [r2] = r16,16; \ - st8 [r3] = r17,16; \ - ;; \ - mov r16 = ar.k4; \ - mov r17 = ar.k5; \ - ;; \ - st8 [r2] = r16,16; \ - st8 [r3] = r17,16; \ - ;; \ - mov r16 = ar.k6; \ - mov r17 = ar.k7; \ - ;; \ - st8 [r2] = r16; \ - st8 [r3] = r17; \ - ;; - - - - /* - * r33: context_t base address - */ -#define RESTORE_KERNEL_REGS \ - add r2 = CTX(KR0),r33; \ - add r3 = CTX(KR1),r33; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov ar.k0=r16; \ - mov ar.k1=r17; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov ar.k2=r16; \ - mov ar.k3=r17; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov ar.k4=r16; \ - mov ar.k5=r17; \ - ;; \ - ld8 r16=[r2],16; \ - ld8 r17=[r3],16; \ - ;; \ - mov ar.k6=r16; \ - mov ar.k7=r17; \ - ;; - - - - /* - * r32: context_t base address - */ -#define SAVE_APP_REGS \ - add r2 = CTX(BSPSTORE),r32; \ - mov r16 = ar.bspstore; \ - ;; \ - st8 [r2] = r16,CTX(RNAT)-CTX(BSPSTORE);\ - mov r16 = ar.rnat; \ - ;; \ - st8 [r2] = r16,CTX(FCR)-CTX(RNAT); \ - mov r16 = ar.fcr; \ - ;; \ - st8 [r2] = r16,CTX(EFLAG)-CTX(FCR); \ - mov r16 = ar.eflag; \ - ;; \ - st8 [r2] = r16,CTX(CFLG)-CTX(EFLAG); \ - mov r16 = ar.cflg; \ - ;; \ - st8 [r2] = r16,CTX(FSR)-CTX(CFLG); \ - mov r16 = ar.fsr; \ - ;; \ - st8 [r2] = r16,CTX(FIR)-CTX(FSR); \ - mov r16 = ar.fir; \ - ;; \ - st8 [r2] = r16,CTX(FDR)-CTX(FIR); \ - mov r16 = ar.fdr; \ - ;; \ - st8 [r2] = r16,CTX(UNAT)-CTX(FDR); \ - mov r16 = ar.unat; \ - ;; \ - st8 [r2] = r16,CTX(FPSR)-CTX(UNAT); \ - mov r16 = ar.fpsr; \ - ;; \ - st8 [r2] = r16,CTX(PFS)-CTX(FPSR); \ - mov r16 = ar.pfs; \ - ;; \ - st8 [r2] = r16,CTX(LC)-CTX(PFS); \ - mov r16 = ar.lc; \ - ;; \ - st8 [r2] = r16; \ - ;; - - /* - * r33: context_t base address - */ -#define RESTORE_APP_REGS \ - add r2=CTX(BSPSTORE),r33; \ - ;; \ - ld8 r16=[r2],CTX(RNAT)-CTX(BSPSTORE); \ - ;; \ - mov ar.bspstore=r16; \ - ld8 r16=[r2],CTX(FCR)-CTX(RNAT); \ - ;; \ - mov ar.rnat=r16; \ - ld8 r16=[r2],CTX(EFLAG)-CTX(FCR); \ - ;; \ - mov ar.fcr=r16; \ - ld8 r16=[r2],CTX(CFLG)-CTX(EFLAG); \ - ;; \ - mov ar.eflag=r16; \ - ld8 r16=[r2],CTX(FSR)-CTX(CFLG); \ - ;; \ - mov ar.cflg=r16; \ - ld8 r16=[r2],CTX(FIR)-CTX(FSR); \ - ;; \ - mov ar.fsr=r16; \ - ld8 r16=[r2],CTX(FDR)-CTX(FIR); \ - ;; \ - mov ar.fir=r16; \ - ld8 r16=[r2],CTX(UNAT)-CTX(FDR); \ - ;; \ - mov ar.fdr=r16; \ - ld8 r16=[r2],CTX(FPSR)-CTX(UNAT); \ - ;; \ - mov ar.unat=r16; \ - ld8 r16=[r2],CTX(PFS)-CTX(FPSR); \ - ;; \ - mov ar.fpsr=r16; \ - ld8 r16=[r2],CTX(LC)-CTX(PFS); \ - ;; \ - mov ar.pfs=r16; \ - ld8 r16=[r2]; \ - ;; \ - mov ar.lc=r16; \ - ;; - - /* - * r32: context_t base address - */ -#define SAVE_CTL_REGS \ - add r2 = CTX(DCR),r32; \ - mov r16 = cr.dcr; \ - ;; \ - st8 [r2] = r16,CTX(IVA)-CTX(DCR); \ - ;; \ - mov r16 = cr.iva; \ - ;; \ - st8 [r2] = r16,CTX(PTA)-CTX(IVA); \ - ;; \ - mov r16 = cr.pta; \ - ;; \ - st8 [r2] = r16 ; \ - ;; - - /* - * r33: context_t base address - */ -#define RESTORE_CTL_REGS \ - add r2 = CTX(DCR),r33; \ - ;; \ - ld8 r16 = [r2],CTX(IVA)-CTX(DCR); \ - ;; \ - mov cr.dcr = r16; \ - dv_serialize_data; \ - ;; \ - ld8 r16 = [r2],CTX(PTA)-CTX(IVA); \ - ;; \ - mov cr.iva = r16; \ - dv_serialize_data; \ - ;; \ - ld8 r16 = [r2]; \ - ;; \ - mov cr.pta = r16; \ - dv_serialize_data; \ - ;; - - - /* - * r32: context_t base address - */ -#define SAVE_REGION_REGS \ - add r2=CTX(RR0),r32; \ - mov r16=rr[r0]; \ - dep.z r18=1,61,3; \ - ;; \ - st8 [r2]=r16,8; \ - mov r17=rr[r18]; \ - dep.z r18=2,61,3; \ - ;; \ - st8 [r2]=r17,8; \ - mov r16=rr[r18]; \ - dep.z r18=3,61,3; \ - ;; \ - st8 [r2]=r16,8; \ - mov r17=rr[r18]; \ - dep.z r18=4,61,3; \ - ;; \ - st8 [r2]=r17,8; \ - mov r16=rr[r18]; \ - dep.z r18=5,61,3; \ - ;; \ - st8 [r2]=r16,8; \ - mov r17=rr[r18]; \ - dep.z r18=7,61,3; \ - ;; \ - st8 [r2]=r17,16; \ - mov r16=rr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - ;; - - /* - * r33:context_t base address - */ -#define RESTORE_REGION_REGS \ - add r2=CTX(RR0),r33;\ - mov r18=r0; \ - ;; \ - ld8 r20=[r2],8; \ - ;; /* rr0 */ \ - ld8 r21=[r2],8; \ - ;; /* rr1 */ \ - ld8 r22=[r2],8; \ - ;; /* rr2 */ \ - ld8 r23=[r2],8; \ - ;; /* rr3 */ \ - ld8 r24=[r2],8; \ - ;; /* rr4 */ \ - ld8 r25=[r2],16; \ - ;; /* rr5 */ \ - ld8 r27=[r2]; \ - ;; /* rr7 */ \ - mov rr[r18]=r20; \ - dep.z r18=1,61,3; \ - ;; /* rr1 */ \ - mov rr[r18]=r21; \ - dep.z r18=2,61,3; \ - ;; /* rr2 */ \ - mov rr[r18]=r22; \ - dep.z r18=3,61,3; \ - ;; /* rr3 */ \ - mov rr[r18]=r23; \ - dep.z r18=4,61,3; \ - ;; /* rr4 */ \ - mov rr[r18]=r24; \ - dep.z r18=5,61,3; \ - ;; /* rr5 */ \ - mov rr[r18]=r25; \ - dep.z r18=7,61,3; \ - ;; /* rr7 */ \ - mov rr[r18]=r27; \ - ;; \ - srlz.i; \ - ;; - - - - /* - * r32: context_t base address - * r36~r39:scratch registers - */ -#define SAVE_DEBUG_REGS \ - add r2=CTX(IBR0),r32; \ - add r3=CTX(DBR0),r32; \ - mov r16=ibr[r0]; \ - mov r17=dbr[r0]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=1,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=2,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=2,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=3,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=4,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=5,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=6,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - add r18=7,r0; \ - ;; \ - mov r16=ibr[r18]; \ - mov r17=dbr[r18]; \ - ;; \ - st8 [r2]=r16,8; \ - st8 [r3]=r17,8; \ - ;; - - -/* - * r33: point to context_t structure - * ar.lc are corrupted. - */ -#define RESTORE_DEBUG_REGS \ - add r2=CTX(IBR0),r33; \ - add r3=CTX(DBR0),r33; \ - mov r16=7; \ - mov r17=r0; \ - ;; \ - mov ar.lc = r16; \ - ;; \ -1: \ - ld8 r18=[r2],8; \ - ld8 r19=[r3],8; \ - ;; \ - mov ibr[r17]=r18; \ - mov dbr[r17]=r19; \ - ;; \ - srlz.i; \ - ;; \ - add r17=1,r17; \ - br.cloop.sptk 1b; \ - ;; - - - /* - * r32: context_t base address - */ -#define SAVE_FPU_LOW \ - add r2=CTX(F2),r32; \ - add r3=CTX(F3),r32; \ - ;; \ - stf.spill.nta [r2]=f2,32; \ - stf.spill.nta [r3]=f3,32; \ - ;; \ - stf.spill.nta [r2]=f4,32; \ - stf.spill.nta [r3]=f5,32; \ - ;; \ - stf.spill.nta [r2]=f6,32; \ - stf.spill.nta [r3]=f7,32; \ - ;; \ - stf.spill.nta [r2]=f8,32; \ - stf.spill.nta [r3]=f9,32; \ - ;; \ - stf.spill.nta [r2]=f10,32; \ - stf.spill.nta [r3]=f11,32; \ - ;; \ - stf.spill.nta [r2]=f12,32; \ - stf.spill.nta [r3]=f13,32; \ - ;; \ - stf.spill.nta [r2]=f14,32; \ - stf.spill.nta [r3]=f15,32; \ - ;; \ - stf.spill.nta [r2]=f16,32; \ - stf.spill.nta [r3]=f17,32; \ - ;; \ - stf.spill.nta [r2]=f18,32; \ - stf.spill.nta [r3]=f19,32; \ - ;; \ - stf.spill.nta [r2]=f20,32; \ - stf.spill.nta [r3]=f21,32; \ - ;; \ - stf.spill.nta [r2]=f22,32; \ - stf.spill.nta [r3]=f23,32; \ - ;; \ - stf.spill.nta [r2]=f24,32; \ - stf.spill.nta [r3]=f25,32; \ - ;; \ - stf.spill.nta [r2]=f26,32; \ - stf.spill.nta [r3]=f27,32; \ - ;; \ - stf.spill.nta [r2]=f28,32; \ - stf.spill.nta [r3]=f29,32; \ - ;; \ - stf.spill.nta [r2]=f30; \ - stf.spill.nta [r3]=f31; \ - ;; - - /* - * r32: context_t base address - */ -#define SAVE_FPU_HIGH \ - add r2=CTX(F32),r32; \ - add r3=CTX(F33),r32; \ - ;; \ - stf.spill.nta [r2]=f32,32; \ - stf.spill.nta [r3]=f33,32; \ - ;; \ - stf.spill.nta [r2]=f34,32; \ - stf.spill.nta [r3]=f35,32; \ - ;; \ - stf.spill.nta [r2]=f36,32; \ - stf.spill.nta [r3]=f37,32; \ - ;; \ - stf.spill.nta [r2]=f38,32; \ - stf.spill.nta [r3]=f39,32; \ - ;; \ - stf.spill.nta [r2]=f40,32; \ - stf.spill.nta [r3]=f41,32; \ - ;; \ - stf.spill.nta [r2]=f42,32; \ - stf.spill.nta [r3]=f43,32; \ - ;; \ - stf.spill.nta [r2]=f44,32; \ - stf.spill.nta [r3]=f45,32; \ - ;; \ - stf.spill.nta [r2]=f46,32; \ - stf.spill.nta [r3]=f47,32; \ - ;; \ - stf.spill.nta [r2]=f48,32; \ - stf.spill.nta [r3]=f49,32; \ - ;; \ - stf.spill.nta [r2]=f50,32; \ - stf.spill.nta [r3]=f51,32; \ - ;; \ - stf.spill.nta [r2]=f52,32; \ - stf.spill.nta [r3]=f53,32; \ - ;; \ - stf.spill.nta [r2]=f54,32; \ - stf.spill.nta [r3]=f55,32; \ - ;; \ - stf.spill.nta [r2]=f56,32; \ - stf.spill.nta [r3]=f57,32; \ - ;; \ - stf.spill.nta [r2]=f58,32; \ - stf.spill.nta [r3]=f59,32; \ - ;; \ - stf.spill.nta [r2]=f60,32; \ - stf.spill.nta [r3]=f61,32; \ - ;; \ - stf.spill.nta [r2]=f62,32; \ - stf.spill.nta [r3]=f63,32; \ - ;; \ - stf.spill.nta [r2]=f64,32; \ - stf.spill.nta [r3]=f65,32; \ - ;; \ - stf.spill.nta [r2]=f66,32; \ - stf.spill.nta [r3]=f67,32; \ - ;; \ - stf.spill.nta [r2]=f68,32; \ - stf.spill.nta [r3]=f69,32; \ - ;; \ - stf.spill.nta [r2]=f70,32; \ - stf.spill.nta [r3]=f71,32; \ - ;; \ - stf.spill.nta [r2]=f72,32; \ - stf.spill.nta [r3]=f73,32; \ - ;; \ - stf.spill.nta [r2]=f74,32; \ - stf.spill.nta [r3]=f75,32; \ - ;; \ - stf.spill.nta [r2]=f76,32; \ - stf.spill.nta [r3]=f77,32; \ - ;; \ - stf.spill.nta [r2]=f78,32; \ - stf.spill.nta [r3]=f79,32; \ - ;; \ - stf.spill.nta [r2]=f80,32; \ - stf.spill.nta [r3]=f81,32; \ - ;; \ - stf.spill.nta [r2]=f82,32; \ - stf.spill.nta [r3]=f83,32; \ - ;; \ - stf.spill.nta [r2]=f84,32; \ - stf.spill.nta [r3]=f85,32; \ - ;; \ - stf.spill.nta [r2]=f86,32; \ - stf.spill.nta [r3]=f87,32; \ - ;; \ - stf.spill.nta [r2]=f88,32; \ - stf.spill.nta [r3]=f89,32; \ - ;; \ - stf.spill.nta [r2]=f90,32; \ - stf.spill.nta [r3]=f91,32; \ - ;; \ - stf.spill.nta [r2]=f92,32; \ - stf.spill.nta [r3]=f93,32; \ - ;; \ - stf.spill.nta [r2]=f94,32; \ - stf.spill.nta [r3]=f95,32; \ - ;; \ - stf.spill.nta [r2]=f96,32; \ - stf.spill.nta [r3]=f97,32; \ - ;; \ - stf.spill.nta [r2]=f98,32; \ - stf.spill.nta [r3]=f99,32; \ - ;; \ - stf.spill.nta [r2]=f100,32; \ - stf.spill.nta [r3]=f101,32; \ - ;; \ - stf.spill.nta [r2]=f102,32; \ - stf.spill.nta [r3]=f103,32; \ - ;; \ - stf.spill.nta [r2]=f104,32; \ - stf.spill.nta [r3]=f105,32; \ - ;; \ - stf.spill.nta [r2]=f106,32; \ - stf.spill.nta [r3]=f107,32; \ - ;; \ - stf.spill.nta [r2]=f108,32; \ - stf.spill.nta [r3]=f109,32; \ - ;; \ - stf.spill.nta [r2]=f110,32; \ - stf.spill.nta [r3]=f111,32; \ - ;; \ - stf.spill.nta [r2]=f112,32; \ - stf.spill.nta [r3]=f113,32; \ - ;; \ - stf.spill.nta [r2]=f114,32; \ - stf.spill.nta [r3]=f115,32; \ - ;; \ - stf.spill.nta [r2]=f116,32; \ - stf.spill.nta [r3]=f117,32; \ - ;; \ - stf.spill.nta [r2]=f118,32; \ - stf.spill.nta [r3]=f119,32; \ - ;; \ - stf.spill.nta [r2]=f120,32; \ - stf.spill.nta [r3]=f121,32; \ - ;; \ - stf.spill.nta [r2]=f122,32; \ - stf.spill.nta [r3]=f123,32; \ - ;; \ - stf.spill.nta [r2]=f124,32; \ - stf.spill.nta [r3]=f125,32; \ - ;; \ - stf.spill.nta [r2]=f126; \ - stf.spill.nta [r3]=f127; \ - ;; - - /* - * r33: point to context_t structure - */ -#define RESTORE_FPU_LOW \ - add r2 = CTX(F2), r33; \ - add r3 = CTX(F3), r33; \ - ;; \ - ldf.fill.nta f2 = [r2], 32; \ - ldf.fill.nta f3 = [r3], 32; \ - ;; \ - ldf.fill.nta f4 = [r2], 32; \ - ldf.fill.nta f5 = [r3], 32; \ - ;; \ - ldf.fill.nta f6 = [r2], 32; \ - ldf.fill.nta f7 = [r3], 32; \ - ;; \ - ldf.fill.nta f8 = [r2], 32; \ - ldf.fill.nta f9 = [r3], 32; \ - ;; \ - ldf.fill.nta f10 = [r2], 32; \ - ldf.fill.nta f11 = [r3], 32; \ - ;; \ - ldf.fill.nta f12 = [r2], 32; \ - ldf.fill.nta f13 = [r3], 32; \ - ;; \ - ldf.fill.nta f14 = [r2], 32; \ - ldf.fill.nta f15 = [r3], 32; \ - ;; \ - ldf.fill.nta f16 = [r2], 32; \ - ldf.fill.nta f17 = [r3], 32; \ - ;; \ - ldf.fill.nta f18 = [r2], 32; \ - ldf.fill.nta f19 = [r3], 32; \ - ;; \ - ldf.fill.nta f20 = [r2], 32; \ - ldf.fill.nta f21 = [r3], 32; \ - ;; \ - ldf.fill.nta f22 = [r2], 32; \ - ldf.fill.nta f23 = [r3], 32; \ - ;; \ - ldf.fill.nta f24 = [r2], 32; \ - ldf.fill.nta f25 = [r3], 32; \ - ;; \ - ldf.fill.nta f26 = [r2], 32; \ - ldf.fill.nta f27 = [r3], 32; \ - ;; \ - ldf.fill.nta f28 = [r2], 32; \ - ldf.fill.nta f29 = [r3], 32; \ - ;; \ - ldf.fill.nta f30 = [r2], 32; \ - ldf.fill.nta f31 = [r3], 32; \ - ;; - - - - /* - * r33: point to context_t structure - */ -#define RESTORE_FPU_HIGH \ - add r2 = CTX(F32), r33; \ - add r3 = CTX(F33), r33; \ - ;; \ - ldf.fill.nta f32 = [r2], 32; \ - ldf.fill.nta f33 = [r3], 32; \ - ;; \ - ldf.fill.nta f34 = [r2], 32; \ - ldf.fill.nta f35 = [r3], 32; \ - ;; \ - ldf.fill.nta f36 = [r2], 32; \ - ldf.fill.nta f37 = [r3], 32; \ - ;; \ - ldf.fill.nta f38 = [r2], 32; \ - ldf.fill.nta f39 = [r3], 32; \ - ;; \ - ldf.fill.nta f40 = [r2], 32; \ - ldf.fill.nta f41 = [r3], 32; \ - ;; \ - ldf.fill.nta f42 = [r2], 32; \ - ldf.fill.nta f43 = [r3], 32; \ - ;; \ - ldf.fill.nta f44 = [r2], 32; \ - ldf.fill.nta f45 = [r3], 32; \ - ;; \ - ldf.fill.nta f46 = [r2], 32; \ - ldf.fill.nta f47 = [r3], 32; \ - ;; \ - ldf.fill.nta f48 = [r2], 32; \ - ldf.fill.nta f49 = [r3], 32; \ - ;; \ - ldf.fill.nta f50 = [r2], 32; \ - ldf.fill.nta f51 = [r3], 32; \ - ;; \ - ldf.fill.nta f52 = [r2], 32; \ - ldf.fill.nta f53 = [r3], 32; \ - ;; \ - ldf.fill.nta f54 = [r2], 32; \ - ldf.fill.nta f55 = [r3], 32; \ - ;; \ - ldf.fill.nta f56 = [r2], 32; \ - ldf.fill.nta f57 = [r3], 32; \ - ;; \ - ldf.fill.nta f58 = [r2], 32; \ - ldf.fill.nta f59 = [r3], 32; \ - ;; \ - ldf.fill.nta f60 = [r2], 32; \ - ldf.fill.nta f61 = [r3], 32; \ - ;; \ - ldf.fill.nta f62 = [r2], 32; \ - ldf.fill.nta f63 = [r3], 32; \ - ;; \ - ldf.fill.nta f64 = [r2], 32; \ - ldf.fill.nta f65 = [r3], 32; \ - ;; \ - ldf.fill.nta f66 = [r2], 32; \ - ldf.fill.nta f67 = [r3], 32; \ - ;; \ - ldf.fill.nta f68 = [r2], 32; \ - ldf.fill.nta f69 = [r3], 32; \ - ;; \ - ldf.fill.nta f70 = [r2], 32; \ - ldf.fill.nta f71 = [r3], 32; \ - ;; \ - ldf.fill.nta f72 = [r2], 32; \ - ldf.fill.nta f73 = [r3], 32; \ - ;; \ - ldf.fill.nta f74 = [r2], 32; \ - ldf.fill.nta f75 = [r3], 32; \ - ;; \ - ldf.fill.nta f76 = [r2], 32; \ - ldf.fill.nta f77 = [r3], 32; \ - ;; \ - ldf.fill.nta f78 = [r2], 32; \ - ldf.fill.nta f79 = [r3], 32; \ - ;; \ - ldf.fill.nta f80 = [r2], 32; \ - ldf.fill.nta f81 = [r3], 32; \ - ;; \ - ldf.fill.nta f82 = [r2], 32; \ - ldf.fill.nta f83 = [r3], 32; \ - ;; \ - ldf.fill.nta f84 = [r2], 32; \ - ldf.fill.nta f85 = [r3], 32; \ - ;; \ - ldf.fill.nta f86 = [r2], 32; \ - ldf.fill.nta f87 = [r3], 32; \ - ;; \ - ldf.fill.nta f88 = [r2], 32; \ - ldf.fill.nta f89 = [r3], 32; \ - ;; \ - ldf.fill.nta f90 = [r2], 32; \ - ldf.fill.nta f91 = [r3], 32; \ - ;; \ - ldf.fill.nta f92 = [r2], 32; \ - ldf.fill.nta f93 = [r3], 32; \ - ;; \ - ldf.fill.nta f94 = [r2], 32; \ - ldf.fill.nta f95 = [r3], 32; \ - ;; \ - ldf.fill.nta f96 = [r2], 32; \ - ldf.fill.nta f97 = [r3], 32; \ - ;; \ - ldf.fill.nta f98 = [r2], 32; \ - ldf.fill.nta f99 = [r3], 32; \ - ;; \ - ldf.fill.nta f100 = [r2], 32; \ - ldf.fill.nta f101 = [r3], 32; \ - ;; \ - ldf.fill.nta f102 = [r2], 32; \ - ldf.fill.nta f103 = [r3], 32; \ - ;; \ - ldf.fill.nta f104 = [r2], 32; \ - ldf.fill.nta f105 = [r3], 32; \ - ;; \ - ldf.fill.nta f106 = [r2], 32; \ - ldf.fill.nta f107 = [r3], 32; \ - ;; \ - ldf.fill.nta f108 = [r2], 32; \ - ldf.fill.nta f109 = [r3], 32; \ - ;; \ - ldf.fill.nta f110 = [r2], 32; \ - ldf.fill.nta f111 = [r3], 32; \ - ;; \ - ldf.fill.nta f112 = [r2], 32; \ - ldf.fill.nta f113 = [r3], 32; \ - ;; \ - ldf.fill.nta f114 = [r2], 32; \ - ldf.fill.nta f115 = [r3], 32; \ - ;; \ - ldf.fill.nta f116 = [r2], 32; \ - ldf.fill.nta f117 = [r3], 32; \ - ;; \ - ldf.fill.nta f118 = [r2], 32; \ - ldf.fill.nta f119 = [r3], 32; \ - ;; \ - ldf.fill.nta f120 = [r2], 32; \ - ldf.fill.nta f121 = [r3], 32; \ - ;; \ - ldf.fill.nta f122 = [r2], 32; \ - ldf.fill.nta f123 = [r3], 32; \ - ;; \ - ldf.fill.nta f124 = [r2], 32; \ - ldf.fill.nta f125 = [r3], 32; \ - ;; \ - ldf.fill.nta f126 = [r2], 32; \ - ldf.fill.nta f127 = [r3], 32; \ - ;; - - /* - * r32: context_t base address - */ -#define SAVE_PTK_REGS \ - add r2=CTX(PKR0), r32; \ - mov r16=7; \ - ;; \ - mov ar.lc=r16; \ - mov r17=r0; \ - ;; \ -1: \ - mov r18=pkr[r17]; \ - ;; \ - srlz.i; \ - ;; \ - st8 [r2]=r18, 8; \ - ;; \ - add r17 =1,r17; \ - ;; \ - br.cloop.sptk 1b; \ - ;; - -/* - * r33: point to context_t structure - * ar.lc are corrupted. - */ -#define RESTORE_PTK_REGS \ - add r2=CTX(PKR0), r33; \ - mov r16=7; \ - ;; \ - mov ar.lc=r16; \ - mov r17=r0; \ - ;; \ -1: \ - ld8 r18=[r2], 8; \ - ;; \ - mov pkr[r17]=r18; \ - ;; \ - srlz.i; \ - ;; \ - add r17 =1,r17; \ - ;; \ - br.cloop.sptk 1b; \ - ;; - - -/* - * void vmm_trampoline( context_t * from, - * context_t * to) - * - * from: r32 - * to: r33 - * note: interrupt disabled before call this function. - */ -GLOBAL_ENTRY(vmm_trampoline) - mov r16 = psr - adds r2 = CTX(PSR), r32 - ;; - st8 [r2] = r16, 8 // psr - mov r17 = pr - ;; - st8 [r2] = r17, 8 // pr - mov r18 = ar.unat - ;; - st8 [r2] = r18 - mov r17 = ar.rsc - ;; - adds r2 = CTX(RSC),r32 - ;; - st8 [r2]= r17 - mov ar.rsc =0 - flushrs - ;; - SAVE_GENERAL_REGS - ;; - SAVE_KERNEL_REGS - ;; - SAVE_APP_REGS - ;; - SAVE_BRANCH_REGS - ;; - SAVE_CTL_REGS - ;; - SAVE_REGION_REGS - ;; - //SAVE_DEBUG_REGS - ;; - rsm psr.dfl - ;; - srlz.d - ;; - SAVE_FPU_LOW - ;; - rsm psr.dfh - ;; - srlz.d - ;; - SAVE_FPU_HIGH - ;; - SAVE_PTK_REGS - ;; - RESTORE_PTK_REGS - ;; - RESTORE_FPU_HIGH - ;; - RESTORE_FPU_LOW - ;; - //RESTORE_DEBUG_REGS - ;; - RESTORE_REGION_REGS - ;; - RESTORE_CTL_REGS - ;; - RESTORE_BRANCH_REGS - ;; - RESTORE_APP_REGS - ;; - RESTORE_KERNEL_REGS - ;; - RESTORE_GENERAL_REGS - ;; - adds r2=CTX(PSR), r33 - ;; - ld8 r16=[r2], 8 // psr - ;; - mov psr.l=r16 - ;; - srlz.d - ;; - ld8 r16=[r2], 8 // pr - ;; - mov pr =r16,-1 - ld8 r16=[r2] // unat - ;; - mov ar.unat=r16 - ;; - adds r2=CTX(RSC),r33 - ;; - ld8 r16 =[r2] - ;; - mov ar.rsc = r16 - ;; - br.ret.sptk.few b0 -END(vmm_trampoline) diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c deleted file mode 100644 index 958815c9787d..000000000000 --- a/arch/ia64/kvm/vcpu.c +++ /dev/null @@ -1,2209 +0,0 @@ -/* - * kvm_vcpu.c: handling all virtual cpu related thing. - * Copyright (c) 2005, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * 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. - * - * Shaofan Li (Susue Li) - * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) - * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) - * Xiantao Zhang - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "asm-offsets.h" -#include "vcpu.h" - -/* - * Special notes: - * - Index by it/dt/rt sequence - * - Only existing mode transitions are allowed in this table - * - RSE is placed at lazy mode when emulating guest partial mode - * - If gva happens to be rr0 and rr4, only allowed case is identity - * mapping (gva=gpa), or panic! (How?) - */ -int mm_switch_table[8][8] = { - /* 2004/09/12(Kevin): Allow switch to self */ - /* - * (it,dt,rt): (0,0,0) -> (1,1,1) - * This kind of transition usually occurs in the very early - * stage of Linux boot up procedure. Another case is in efi - * and pal calls. (see "arch/ia64/kernel/head.S") - * - * (it,dt,rt): (0,0,0) -> (0,1,1) - * This kind of transition is found when OSYa exits efi boot - * service. Due to gva = gpa in this case (Same region), - * data access can be satisfied though itlb entry for physical - * emulation is hit. - */ - {SW_SELF, 0, 0, SW_NOP, 0, 0, 0, SW_P2V}, - {0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0}, - /* - * (it,dt,rt): (0,1,1) -> (1,1,1) - * This kind of transition is found in OSYa. - * - * (it,dt,rt): (0,1,1) -> (0,0,0) - * This kind of transition is found in OSYa - */ - {SW_NOP, 0, 0, SW_SELF, 0, 0, 0, SW_P2V}, - /* (1,0,0)->(1,1,1) */ - {0, 0, 0, 0, 0, 0, 0, SW_P2V}, - /* - * (it,dt,rt): (1,0,1) -> (1,1,1) - * This kind of transition usually occurs when Linux returns - * from the low level TLB miss handlers. - * (see "arch/ia64/kernel/ivt.S") - */ - {0, 0, 0, 0, 0, SW_SELF, 0, SW_P2V}, - {0, 0, 0, 0, 0, 0, 0, 0}, - /* - * (it,dt,rt): (1,1,1) -> (1,0,1) - * This kind of transition usually occurs in Linux low level - * TLB miss handler. (see "arch/ia64/kernel/ivt.S") - * - * (it,dt,rt): (1,1,1) -> (0,0,0) - * This kind of transition usually occurs in pal and efi calls, - * which requires running in physical mode. - * (see "arch/ia64/kernel/head.S") - * (1,1,1)->(1,0,0) - */ - - {SW_V2P, 0, 0, 0, SW_V2P, SW_V2P, 0, SW_SELF}, -}; - -void physical_mode_init(struct kvm_vcpu *vcpu) -{ - vcpu->arch.mode_flags = GUEST_IN_PHY; -} - -void switch_to_physical_rid(struct kvm_vcpu *vcpu) -{ - unsigned long psr; - - /* Save original virtual mode rr[0] and rr[4] */ - psr = ia64_clear_ic(); - ia64_set_rr(VRN0<arch.metaphysical_rr0); - ia64_srlz_d(); - ia64_set_rr(VRN4<arch.metaphysical_rr4); - ia64_srlz_d(); - - ia64_set_psr(psr); - return; -} - -void switch_to_virtual_rid(struct kvm_vcpu *vcpu) -{ - unsigned long psr; - - psr = ia64_clear_ic(); - ia64_set_rr(VRN0 << VRN_SHIFT, vcpu->arch.metaphysical_saved_rr0); - ia64_srlz_d(); - ia64_set_rr(VRN4 << VRN_SHIFT, vcpu->arch.metaphysical_saved_rr4); - ia64_srlz_d(); - ia64_set_psr(psr); - return; -} - -static int mm_switch_action(struct ia64_psr opsr, struct ia64_psr npsr) -{ - return mm_switch_table[MODE_IND(opsr)][MODE_IND(npsr)]; -} - -void switch_mm_mode(struct kvm_vcpu *vcpu, struct ia64_psr old_psr, - struct ia64_psr new_psr) -{ - int act; - act = mm_switch_action(old_psr, new_psr); - switch (act) { - case SW_V2P: - /*printk("V -> P mode transition: (0x%lx -> 0x%lx)\n", - old_psr.val, new_psr.val);*/ - switch_to_physical_rid(vcpu); - /* - * Set rse to enforced lazy, to prevent active rse - *save/restor when guest physical mode. - */ - vcpu->arch.mode_flags |= GUEST_IN_PHY; - break; - case SW_P2V: - switch_to_virtual_rid(vcpu); - /* - * recover old mode which is saved when entering - * guest physical mode - */ - vcpu->arch.mode_flags &= ~GUEST_IN_PHY; - break; - case SW_SELF: - break; - case SW_NOP: - break; - default: - /* Sanity check */ - break; - } - return; -} - -/* - * In physical mode, insert tc/tr for region 0 and 4 uses - * RID[0] and RID[4] which is for physical mode emulation. - * However what those inserted tc/tr wants is rid for - * virtual mode. So original virtual rid needs to be restored - * before insert. - * - * Operations which required such switch include: - * - insertions (itc.*, itr.*) - * - purges (ptc.* and ptr.*) - * - tpa - * - tak - * - thash?, ttag? - * All above needs actual virtual rid for destination entry. - */ - -void check_mm_mode_switch(struct kvm_vcpu *vcpu, struct ia64_psr old_psr, - struct ia64_psr new_psr) -{ - - if ((old_psr.dt != new_psr.dt) - || (old_psr.it != new_psr.it) - || (old_psr.rt != new_psr.rt)) - switch_mm_mode(vcpu, old_psr, new_psr); - - return; -} - - -/* - * In physical mode, insert tc/tr for region 0 and 4 uses - * RID[0] and RID[4] which is for physical mode emulation. - * However what those inserted tc/tr wants is rid for - * virtual mode. So original virtual rid needs to be restored - * before insert. - * - * Operations which required such switch include: - * - insertions (itc.*, itr.*) - * - purges (ptc.* and ptr.*) - * - tpa - * - tak - * - thash?, ttag? - * All above needs actual virtual rid for destination entry. - */ - -void prepare_if_physical_mode(struct kvm_vcpu *vcpu) -{ - if (is_physical_mode(vcpu)) { - vcpu->arch.mode_flags |= GUEST_PHY_EMUL; - switch_to_virtual_rid(vcpu); - } - return; -} - -/* Recover always follows prepare */ -void recover_if_physical_mode(struct kvm_vcpu *vcpu) -{ - if (is_physical_mode(vcpu)) - switch_to_physical_rid(vcpu); - vcpu->arch.mode_flags &= ~GUEST_PHY_EMUL; - return; -} - -#define RPT(x) ((u16) &((struct kvm_pt_regs *)0)->x) - -static u16 gr_info[32] = { - 0, /* r0 is read-only : WE SHOULD NEVER GET THIS */ - RPT(r1), RPT(r2), RPT(r3), - RPT(r4), RPT(r5), RPT(r6), RPT(r7), - RPT(r8), RPT(r9), RPT(r10), RPT(r11), - RPT(r12), RPT(r13), RPT(r14), RPT(r15), - RPT(r16), RPT(r17), RPT(r18), RPT(r19), - RPT(r20), RPT(r21), RPT(r22), RPT(r23), - RPT(r24), RPT(r25), RPT(r26), RPT(r27), - RPT(r28), RPT(r29), RPT(r30), RPT(r31) -}; - -#define IA64_FIRST_STACKED_GR 32 -#define IA64_FIRST_ROTATING_FR 32 - -static inline unsigned long -rotate_reg(unsigned long sor, unsigned long rrb, unsigned long reg) -{ - reg += rrb; - if (reg >= sor) - reg -= sor; - return reg; -} - -/* - * Return the (rotated) index for floating point register - * be in the REGNUM (REGNUM must range from 32-127, - * result is in the range from 0-95. - */ -static inline unsigned long fph_index(struct kvm_pt_regs *regs, - long regnum) -{ - unsigned long rrb_fr = (regs->cr_ifs >> 25) & 0x7f; - return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR)); -} - -/* - * The inverse of the above: given bspstore and the number of - * registers, calculate ar.bsp. - */ -static inline unsigned long *kvm_rse_skip_regs(unsigned long *addr, - long num_regs) -{ - long delta = ia64_rse_slot_num(addr) + num_regs; - int i = 0; - - if (num_regs < 0) - delta -= 0x3e; - if (delta < 0) { - while (delta <= -0x3f) { - i--; - delta += 0x3f; - } - } else { - while (delta >= 0x3f) { - i++; - delta -= 0x3f; - } - } - - return addr + num_regs + i; -} - -static void get_rse_reg(struct kvm_pt_regs *regs, unsigned long r1, - unsigned long *val, int *nat) -{ - unsigned long *bsp, *addr, *rnat_addr, *bspstore; - unsigned long *kbs = (void *) current_vcpu + VMM_RBS_OFFSET; - unsigned long nat_mask; - unsigned long old_rsc, new_rsc; - long sof = (regs->cr_ifs) & 0x7f; - long sor = (((regs->cr_ifs >> 14) & 0xf) << 3); - long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; - long ridx = r1 - 32; - - if (ridx < sor) - ridx = rotate_reg(sor, rrb_gr, ridx); - - old_rsc = ia64_getreg(_IA64_REG_AR_RSC); - new_rsc = old_rsc&(~(0x3)); - ia64_setreg(_IA64_REG_AR_RSC, new_rsc); - - bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); - bsp = kbs + (regs->loadrs >> 19); - - addr = kvm_rse_skip_regs(bsp, -sof + ridx); - nat_mask = 1UL << ia64_rse_slot_num(addr); - rnat_addr = ia64_rse_rnat_addr(addr); - - if (addr >= bspstore) { - ia64_flushrs(); - ia64_mf(); - bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); - } - *val = *addr; - if (nat) { - if (bspstore < rnat_addr) - *nat = (int)!!(ia64_getreg(_IA64_REG_AR_RNAT) - & nat_mask); - else - *nat = (int)!!((*rnat_addr) & nat_mask); - ia64_setreg(_IA64_REG_AR_RSC, old_rsc); - } -} - -void set_rse_reg(struct kvm_pt_regs *regs, unsigned long r1, - unsigned long val, unsigned long nat) -{ - unsigned long *bsp, *bspstore, *addr, *rnat_addr; - unsigned long *kbs = (void *) current_vcpu + VMM_RBS_OFFSET; - unsigned long nat_mask; - unsigned long old_rsc, new_rsc, psr; - unsigned long rnat; - long sof = (regs->cr_ifs) & 0x7f; - long sor = (((regs->cr_ifs >> 14) & 0xf) << 3); - long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; - long ridx = r1 - 32; - - if (ridx < sor) - ridx = rotate_reg(sor, rrb_gr, ridx); - - old_rsc = ia64_getreg(_IA64_REG_AR_RSC); - /* put RSC to lazy mode, and set loadrs 0 */ - new_rsc = old_rsc & (~0x3fff0003); - ia64_setreg(_IA64_REG_AR_RSC, new_rsc); - bsp = kbs + (regs->loadrs >> 19); /* 16 + 3 */ - - addr = kvm_rse_skip_regs(bsp, -sof + ridx); - nat_mask = 1UL << ia64_rse_slot_num(addr); - rnat_addr = ia64_rse_rnat_addr(addr); - - local_irq_save(psr); - bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); - if (addr >= bspstore) { - - ia64_flushrs(); - ia64_mf(); - *addr = val; - bspstore = (unsigned long *)ia64_getreg(_IA64_REG_AR_BSPSTORE); - rnat = ia64_getreg(_IA64_REG_AR_RNAT); - if (bspstore < rnat_addr) - rnat = rnat & (~nat_mask); - else - *rnat_addr = (*rnat_addr)&(~nat_mask); - - ia64_mf(); - ia64_loadrs(); - ia64_setreg(_IA64_REG_AR_RNAT, rnat); - } else { - rnat = ia64_getreg(_IA64_REG_AR_RNAT); - *addr = val; - if (bspstore < rnat_addr) - rnat = rnat&(~nat_mask); - else - *rnat_addr = (*rnat_addr) & (~nat_mask); - - ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore); - ia64_setreg(_IA64_REG_AR_RNAT, rnat); - } - local_irq_restore(psr); - ia64_setreg(_IA64_REG_AR_RSC, old_rsc); -} - -void getreg(unsigned long regnum, unsigned long *val, - int *nat, struct kvm_pt_regs *regs) -{ - unsigned long addr, *unat; - if (regnum >= IA64_FIRST_STACKED_GR) { - get_rse_reg(regs, regnum, val, nat); - return; - } - - /* - * Now look at registers in [0-31] range and init correct UNAT - */ - addr = (unsigned long)regs; - unat = ®s->eml_unat; - - addr += gr_info[regnum]; - - *val = *(unsigned long *)addr; - /* - * do it only when requested - */ - if (nat) - *nat = (*unat >> ((addr >> 3) & 0x3f)) & 0x1UL; -} - -void setreg(unsigned long regnum, unsigned long val, - int nat, struct kvm_pt_regs *regs) -{ - unsigned long addr; - unsigned long bitmask; - unsigned long *unat; - - /* - * First takes care of stacked registers - */ - if (regnum >= IA64_FIRST_STACKED_GR) { - set_rse_reg(regs, regnum, val, nat); - return; - } - - /* - * Now look at registers in [0-31] range and init correct UNAT - */ - addr = (unsigned long)regs; - unat = ®s->eml_unat; - /* - * add offset from base of struct - * and do it ! - */ - addr += gr_info[regnum]; - - *(unsigned long *)addr = val; - - /* - * We need to clear the corresponding UNAT bit to fully emulate the load - * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4 - */ - bitmask = 1UL << ((addr >> 3) & 0x3f); - if (nat) - *unat |= bitmask; - else - *unat &= ~bitmask; - -} - -u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - unsigned long val; - - if (!reg) - return 0; - getreg(reg, &val, 0, regs); - return val; -} - -void vcpu_set_gr(struct kvm_vcpu *vcpu, unsigned long reg, u64 value, int nat) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - long sof = (regs->cr_ifs) & 0x7f; - - if (!reg) - return; - if (reg >= sof + 32) - return; - setreg(reg, value, nat, regs); /* FIXME: handle NATs later*/ -} - -void getfpreg(unsigned long regnum, struct ia64_fpreg *fpval, - struct kvm_pt_regs *regs) -{ - /* Take floating register rotation into consideration*/ - if (regnum >= IA64_FIRST_ROTATING_FR) - regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); -#define CASE_FIXED_FP(reg) \ - case (reg) : \ - ia64_stf_spill(fpval, reg); \ - break - - switch (regnum) { - CASE_FIXED_FP(0); - CASE_FIXED_FP(1); - CASE_FIXED_FP(2); - CASE_FIXED_FP(3); - CASE_FIXED_FP(4); - CASE_FIXED_FP(5); - - CASE_FIXED_FP(6); - CASE_FIXED_FP(7); - CASE_FIXED_FP(8); - CASE_FIXED_FP(9); - CASE_FIXED_FP(10); - CASE_FIXED_FP(11); - - CASE_FIXED_FP(12); - CASE_FIXED_FP(13); - CASE_FIXED_FP(14); - CASE_FIXED_FP(15); - CASE_FIXED_FP(16); - CASE_FIXED_FP(17); - CASE_FIXED_FP(18); - CASE_FIXED_FP(19); - CASE_FIXED_FP(20); - CASE_FIXED_FP(21); - CASE_FIXED_FP(22); - CASE_FIXED_FP(23); - CASE_FIXED_FP(24); - CASE_FIXED_FP(25); - CASE_FIXED_FP(26); - CASE_FIXED_FP(27); - CASE_FIXED_FP(28); - CASE_FIXED_FP(29); - CASE_FIXED_FP(30); - CASE_FIXED_FP(31); - CASE_FIXED_FP(32); - CASE_FIXED_FP(33); - CASE_FIXED_FP(34); - CASE_FIXED_FP(35); - CASE_FIXED_FP(36); - CASE_FIXED_FP(37); - CASE_FIXED_FP(38); - CASE_FIXED_FP(39); - CASE_FIXED_FP(40); - CASE_FIXED_FP(41); - CASE_FIXED_FP(42); - CASE_FIXED_FP(43); - CASE_FIXED_FP(44); - CASE_FIXED_FP(45); - CASE_FIXED_FP(46); - CASE_FIXED_FP(47); - CASE_FIXED_FP(48); - CASE_FIXED_FP(49); - CASE_FIXED_FP(50); - CASE_FIXED_FP(51); - CASE_FIXED_FP(52); - CASE_FIXED_FP(53); - CASE_FIXED_FP(54); - CASE_FIXED_FP(55); - CASE_FIXED_FP(56); - CASE_FIXED_FP(57); - CASE_FIXED_FP(58); - CASE_FIXED_FP(59); - CASE_FIXED_FP(60); - CASE_FIXED_FP(61); - CASE_FIXED_FP(62); - CASE_FIXED_FP(63); - CASE_FIXED_FP(64); - CASE_FIXED_FP(65); - CASE_FIXED_FP(66); - CASE_FIXED_FP(67); - CASE_FIXED_FP(68); - CASE_FIXED_FP(69); - CASE_FIXED_FP(70); - CASE_FIXED_FP(71); - CASE_FIXED_FP(72); - CASE_FIXED_FP(73); - CASE_FIXED_FP(74); - CASE_FIXED_FP(75); - CASE_FIXED_FP(76); - CASE_FIXED_FP(77); - CASE_FIXED_FP(78); - CASE_FIXED_FP(79); - CASE_FIXED_FP(80); - CASE_FIXED_FP(81); - CASE_FIXED_FP(82); - CASE_FIXED_FP(83); - CASE_FIXED_FP(84); - CASE_FIXED_FP(85); - CASE_FIXED_FP(86); - CASE_FIXED_FP(87); - CASE_FIXED_FP(88); - CASE_FIXED_FP(89); - CASE_FIXED_FP(90); - CASE_FIXED_FP(91); - CASE_FIXED_FP(92); - CASE_FIXED_FP(93); - CASE_FIXED_FP(94); - CASE_FIXED_FP(95); - CASE_FIXED_FP(96); - CASE_FIXED_FP(97); - CASE_FIXED_FP(98); - CASE_FIXED_FP(99); - CASE_FIXED_FP(100); - CASE_FIXED_FP(101); - CASE_FIXED_FP(102); - CASE_FIXED_FP(103); - CASE_FIXED_FP(104); - CASE_FIXED_FP(105); - CASE_FIXED_FP(106); - CASE_FIXED_FP(107); - CASE_FIXED_FP(108); - CASE_FIXED_FP(109); - CASE_FIXED_FP(110); - CASE_FIXED_FP(111); - CASE_FIXED_FP(112); - CASE_FIXED_FP(113); - CASE_FIXED_FP(114); - CASE_FIXED_FP(115); - CASE_FIXED_FP(116); - CASE_FIXED_FP(117); - CASE_FIXED_FP(118); - CASE_FIXED_FP(119); - CASE_FIXED_FP(120); - CASE_FIXED_FP(121); - CASE_FIXED_FP(122); - CASE_FIXED_FP(123); - CASE_FIXED_FP(124); - CASE_FIXED_FP(125); - CASE_FIXED_FP(126); - CASE_FIXED_FP(127); - } -#undef CASE_FIXED_FP -} - -void setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, - struct kvm_pt_regs *regs) -{ - /* Take floating register rotation into consideration*/ - if (regnum >= IA64_FIRST_ROTATING_FR) - regnum = IA64_FIRST_ROTATING_FR + fph_index(regs, regnum); - -#define CASE_FIXED_FP(reg) \ - case (reg) : \ - ia64_ldf_fill(reg, fpval); \ - break - - switch (regnum) { - CASE_FIXED_FP(2); - CASE_FIXED_FP(3); - CASE_FIXED_FP(4); - CASE_FIXED_FP(5); - - CASE_FIXED_FP(6); - CASE_FIXED_FP(7); - CASE_FIXED_FP(8); - CASE_FIXED_FP(9); - CASE_FIXED_FP(10); - CASE_FIXED_FP(11); - - CASE_FIXED_FP(12); - CASE_FIXED_FP(13); - CASE_FIXED_FP(14); - CASE_FIXED_FP(15); - CASE_FIXED_FP(16); - CASE_FIXED_FP(17); - CASE_FIXED_FP(18); - CASE_FIXED_FP(19); - CASE_FIXED_FP(20); - CASE_FIXED_FP(21); - CASE_FIXED_FP(22); - CASE_FIXED_FP(23); - CASE_FIXED_FP(24); - CASE_FIXED_FP(25); - CASE_FIXED_FP(26); - CASE_FIXED_FP(27); - CASE_FIXED_FP(28); - CASE_FIXED_FP(29); - CASE_FIXED_FP(30); - CASE_FIXED_FP(31); - CASE_FIXED_FP(32); - CASE_FIXED_FP(33); - CASE_FIXED_FP(34); - CASE_FIXED_FP(35); - CASE_FIXED_FP(36); - CASE_FIXED_FP(37); - CASE_FIXED_FP(38); - CASE_FIXED_FP(39); - CASE_FIXED_FP(40); - CASE_FIXED_FP(41); - CASE_FIXED_FP(42); - CASE_FIXED_FP(43); - CASE_FIXED_FP(44); - CASE_FIXED_FP(45); - CASE_FIXED_FP(46); - CASE_FIXED_FP(47); - CASE_FIXED_FP(48); - CASE_FIXED_FP(49); - CASE_FIXED_FP(50); - CASE_FIXED_FP(51); - CASE_FIXED_FP(52); - CASE_FIXED_FP(53); - CASE_FIXED_FP(54); - CASE_FIXED_FP(55); - CASE_FIXED_FP(56); - CASE_FIXED_FP(57); - CASE_FIXED_FP(58); - CASE_FIXED_FP(59); - CASE_FIXED_FP(60); - CASE_FIXED_FP(61); - CASE_FIXED_FP(62); - CASE_FIXED_FP(63); - CASE_FIXED_FP(64); - CASE_FIXED_FP(65); - CASE_FIXED_FP(66); - CASE_FIXED_FP(67); - CASE_FIXED_FP(68); - CASE_FIXED_FP(69); - CASE_FIXED_FP(70); - CASE_FIXED_FP(71); - CASE_FIXED_FP(72); - CASE_FIXED_FP(73); - CASE_FIXED_FP(74); - CASE_FIXED_FP(75); - CASE_FIXED_FP(76); - CASE_FIXED_FP(77); - CASE_FIXED_FP(78); - CASE_FIXED_FP(79); - CASE_FIXED_FP(80); - CASE_FIXED_FP(81); - CASE_FIXED_FP(82); - CASE_FIXED_FP(83); - CASE_FIXED_FP(84); - CASE_FIXED_FP(85); - CASE_FIXED_FP(86); - CASE_FIXED_FP(87); - CASE_FIXED_FP(88); - CASE_FIXED_FP(89); - CASE_FIXED_FP(90); - CASE_FIXED_FP(91); - CASE_FIXED_FP(92); - CASE_FIXED_FP(93); - CASE_FIXED_FP(94); - CASE_FIXED_FP(95); - CASE_FIXED_FP(96); - CASE_FIXED_FP(97); - CASE_FIXED_FP(98); - CASE_FIXED_FP(99); - CASE_FIXED_FP(100); - CASE_FIXED_FP(101); - CASE_FIXED_FP(102); - CASE_FIXED_FP(103); - CASE_FIXED_FP(104); - CASE_FIXED_FP(105); - CASE_FIXED_FP(106); - CASE_FIXED_FP(107); - CASE_FIXED_FP(108); - CASE_FIXED_FP(109); - CASE_FIXED_FP(110); - CASE_FIXED_FP(111); - CASE_FIXED_FP(112); - CASE_FIXED_FP(113); - CASE_FIXED_FP(114); - CASE_FIXED_FP(115); - CASE_FIXED_FP(116); - CASE_FIXED_FP(117); - CASE_FIXED_FP(118); - CASE_FIXED_FP(119); - CASE_FIXED_FP(120); - CASE_FIXED_FP(121); - CASE_FIXED_FP(122); - CASE_FIXED_FP(123); - CASE_FIXED_FP(124); - CASE_FIXED_FP(125); - CASE_FIXED_FP(126); - CASE_FIXED_FP(127); - } -} - -void vcpu_get_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, - struct ia64_fpreg *val) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - getfpreg(reg, val, regs); /* FIXME: handle NATs later*/ -} - -void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, - struct ia64_fpreg *val) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - if (reg > 1) - setfpreg(reg, val, regs); /* FIXME: handle NATs later*/ -} - -/* - * The Altix RTC is mapped specially here for the vmm module - */ -#define SN_RTC_BASE (u64 *)(KVM_VMM_BASE+(1UL<arch.is_sn2) - return (*SN_RTC_BASE); - else -#endif - return ia64_getreg(_IA64_REG_AR_ITC); -} - -/************************************************************************ - * lsapic timer - ***********************************************************************/ -u64 vcpu_get_itc(struct kvm_vcpu *vcpu) -{ - unsigned long guest_itc; - guest_itc = VMX(vcpu, itc_offset) + kvm_get_itc(vcpu); - - if (guest_itc >= VMX(vcpu, last_itc)) { - VMX(vcpu, last_itc) = guest_itc; - return guest_itc; - } else - return VMX(vcpu, last_itc); -} - -static inline void vcpu_set_itm(struct kvm_vcpu *vcpu, u64 val); -static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val) -{ - struct kvm_vcpu *v; - struct kvm *kvm; - int i; - long itc_offset = val - kvm_get_itc(vcpu); - unsigned long vitv = VCPU(vcpu, itv); - - kvm = (struct kvm *)KVM_VM_BASE; - - if (kvm_vcpu_is_bsp(vcpu)) { - for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) { - v = (struct kvm_vcpu *)((char *)vcpu + - sizeof(struct kvm_vcpu_data) * i); - VMX(v, itc_offset) = itc_offset; - VMX(v, last_itc) = 0; - } - } - VMX(vcpu, last_itc) = 0; - if (VCPU(vcpu, itm) <= val) { - VMX(vcpu, itc_check) = 0; - vcpu_unpend_interrupt(vcpu, vitv); - } else { - VMX(vcpu, itc_check) = 1; - vcpu_set_itm(vcpu, VCPU(vcpu, itm)); - } - -} - -static inline u64 vcpu_get_itm(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, itm)); -} - -static inline void vcpu_set_itm(struct kvm_vcpu *vcpu, u64 val) -{ - unsigned long vitv = VCPU(vcpu, itv); - VCPU(vcpu, itm) = val; - - if (val > vcpu_get_itc(vcpu)) { - VMX(vcpu, itc_check) = 1; - vcpu_unpend_interrupt(vcpu, vitv); - VMX(vcpu, timer_pending) = 0; - } else - VMX(vcpu, itc_check) = 0; -} - -#define ITV_VECTOR(itv) (itv&0xff) -#define ITV_IRQ_MASK(itv) (itv&(1<<16)) - -static inline void vcpu_set_itv(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, itv) = val; - if (!ITV_IRQ_MASK(val) && vcpu->arch.timer_pending) { - vcpu_pend_interrupt(vcpu, ITV_VECTOR(val)); - vcpu->arch.timer_pending = 0; - } -} - -static inline void vcpu_set_eoi(struct kvm_vcpu *vcpu, u64 val) -{ - int vec; - - vec = highest_inservice_irq(vcpu); - if (vec == NULL_VECTOR) - return; - VMX(vcpu, insvc[vec >> 6]) &= ~(1UL << (vec & 63)); - VCPU(vcpu, eoi) = 0; - vcpu->arch.irq_new_pending = 1; - -} - -/* See Table 5-8 in SDM vol2 for the definition */ -int irq_masked(struct kvm_vcpu *vcpu, int h_pending, int h_inservice) -{ - union ia64_tpr vtpr; - - vtpr.val = VCPU(vcpu, tpr); - - if (h_inservice == NMI_VECTOR) - return IRQ_MASKED_BY_INSVC; - - if (h_pending == NMI_VECTOR) { - /* Non Maskable Interrupt */ - return IRQ_NO_MASKED; - } - - if (h_inservice == ExtINT_VECTOR) - return IRQ_MASKED_BY_INSVC; - - if (h_pending == ExtINT_VECTOR) { - if (vtpr.mmi) { - /* mask all external IRQ */ - return IRQ_MASKED_BY_VTPR; - } else - return IRQ_NO_MASKED; - } - - if (is_higher_irq(h_pending, h_inservice)) { - if (is_higher_class(h_pending, vtpr.mic + (vtpr.mmi << 4))) - return IRQ_NO_MASKED; - else - return IRQ_MASKED_BY_VTPR; - } else { - return IRQ_MASKED_BY_INSVC; - } -} - -void vcpu_pend_interrupt(struct kvm_vcpu *vcpu, u8 vec) -{ - long spsr; - int ret; - - local_irq_save(spsr); - ret = test_and_set_bit(vec, &VCPU(vcpu, irr[0])); - local_irq_restore(spsr); - - vcpu->arch.irq_new_pending = 1; -} - -void vcpu_unpend_interrupt(struct kvm_vcpu *vcpu, u8 vec) -{ - long spsr; - int ret; - - local_irq_save(spsr); - ret = test_and_clear_bit(vec, &VCPU(vcpu, irr[0])); - local_irq_restore(spsr); - if (ret) { - vcpu->arch.irq_new_pending = 1; - wmb(); - } -} - -void update_vhpi(struct kvm_vcpu *vcpu, int vec) -{ - u64 vhpi; - - if (vec == NULL_VECTOR) - vhpi = 0; - else if (vec == NMI_VECTOR) - vhpi = 32; - else if (vec == ExtINT_VECTOR) - vhpi = 16; - else - vhpi = vec >> 4; - - VCPU(vcpu, vhpi) = vhpi; - if (VCPU(vcpu, vac).a_int) - ia64_call_vsa(PAL_VPS_SET_PENDING_INTERRUPT, - (u64)vcpu->arch.vpd, 0, 0, 0, 0, 0, 0); -} - -u64 vcpu_get_ivr(struct kvm_vcpu *vcpu) -{ - int vec, h_inservice, mask; - - vec = highest_pending_irq(vcpu); - h_inservice = highest_inservice_irq(vcpu); - mask = irq_masked(vcpu, vec, h_inservice); - if (vec == NULL_VECTOR || mask == IRQ_MASKED_BY_INSVC) { - if (VCPU(vcpu, vhpi)) - update_vhpi(vcpu, NULL_VECTOR); - return IA64_SPURIOUS_INT_VECTOR; - } - if (mask == IRQ_MASKED_BY_VTPR) { - update_vhpi(vcpu, vec); - return IA64_SPURIOUS_INT_VECTOR; - } - VMX(vcpu, insvc[vec >> 6]) |= (1UL << (vec & 63)); - vcpu_unpend_interrupt(vcpu, vec); - return (u64)vec; -} - -/************************************************************************** - Privileged operation emulation routines - **************************************************************************/ -u64 vcpu_thash(struct kvm_vcpu *vcpu, u64 vadr) -{ - union ia64_pta vpta; - union ia64_rr vrr; - u64 pval; - u64 vhpt_offset; - - vpta.val = vcpu_get_pta(vcpu); - vrr.val = vcpu_get_rr(vcpu, vadr); - vhpt_offset = ((vadr >> vrr.ps) << 3) & ((1UL << (vpta.size)) - 1); - if (vpta.vf) { - pval = ia64_call_vsa(PAL_VPS_THASH, vadr, vrr.val, - vpta.val, 0, 0, 0, 0); - } else { - pval = (vadr & VRN_MASK) | vhpt_offset | - (vpta.val << 3 >> (vpta.size + 3) << (vpta.size)); - } - return pval; -} - -u64 vcpu_ttag(struct kvm_vcpu *vcpu, u64 vadr) -{ - union ia64_rr vrr; - union ia64_pta vpta; - u64 pval; - - vpta.val = vcpu_get_pta(vcpu); - vrr.val = vcpu_get_rr(vcpu, vadr); - if (vpta.vf) { - pval = ia64_call_vsa(PAL_VPS_TTAG, vadr, vrr.val, - 0, 0, 0, 0, 0); - } else - pval = 1; - - return pval; -} - -u64 vcpu_tak(struct kvm_vcpu *vcpu, u64 vadr) -{ - struct thash_data *data; - union ia64_pta vpta; - u64 key; - - vpta.val = vcpu_get_pta(vcpu); - if (vpta.vf == 0) { - key = 1; - return key; - } - data = vtlb_lookup(vcpu, vadr, D_TLB); - if (!data || !data->p) - key = 1; - else - key = data->key; - - return key; -} - -void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long thash, vadr; - - vadr = vcpu_get_gr(vcpu, inst.M46.r3); - thash = vcpu_thash(vcpu, vadr); - vcpu_set_gr(vcpu, inst.M46.r1, thash, 0); -} - -void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long tag, vadr; - - vadr = vcpu_get_gr(vcpu, inst.M46.r3); - tag = vcpu_ttag(vcpu, vadr); - vcpu_set_gr(vcpu, inst.M46.r1, tag, 0); -} - -int vcpu_tpa(struct kvm_vcpu *vcpu, u64 vadr, unsigned long *padr) -{ - struct thash_data *data; - union ia64_isr visr, pt_isr; - struct kvm_pt_regs *regs; - struct ia64_psr vpsr; - - regs = vcpu_regs(vcpu); - pt_isr.val = VMX(vcpu, cr_isr); - visr.val = 0; - visr.ei = pt_isr.ei; - visr.ir = pt_isr.ir; - vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - visr.na = 1; - - data = vhpt_lookup(vadr); - if (data) { - if (data->p == 0) { - vcpu_set_isr(vcpu, visr.val); - data_page_not_present(vcpu, vadr); - return IA64_FAULT; - } else if (data->ma == VA_MATTR_NATPAGE) { - vcpu_set_isr(vcpu, visr.val); - dnat_page_consumption(vcpu, vadr); - return IA64_FAULT; - } else { - *padr = (data->gpaddr >> data->ps << data->ps) | - (vadr & (PSIZE(data->ps) - 1)); - return IA64_NO_FAULT; - } - } - - data = vtlb_lookup(vcpu, vadr, D_TLB); - if (data) { - if (data->p == 0) { - vcpu_set_isr(vcpu, visr.val); - data_page_not_present(vcpu, vadr); - return IA64_FAULT; - } else if (data->ma == VA_MATTR_NATPAGE) { - vcpu_set_isr(vcpu, visr.val); - dnat_page_consumption(vcpu, vadr); - return IA64_FAULT; - } else{ - *padr = ((data->ppn >> (data->ps - 12)) << data->ps) - | (vadr & (PSIZE(data->ps) - 1)); - return IA64_NO_FAULT; - } - } - if (!vhpt_enabled(vcpu, vadr, NA_REF)) { - if (vpsr.ic) { - vcpu_set_isr(vcpu, visr.val); - alt_dtlb(vcpu, vadr); - return IA64_FAULT; - } else { - nested_dtlb(vcpu); - return IA64_FAULT; - } - } else { - if (vpsr.ic) { - vcpu_set_isr(vcpu, visr.val); - dvhpt_fault(vcpu, vadr); - return IA64_FAULT; - } else{ - nested_dtlb(vcpu); - return IA64_FAULT; - } - } - - return IA64_NO_FAULT; -} - -int kvm_tpa(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r1, r3; - - r3 = vcpu_get_gr(vcpu, inst.M46.r3); - - if (vcpu_tpa(vcpu, r3, &r1)) - return IA64_FAULT; - - vcpu_set_gr(vcpu, inst.M46.r1, r1, 0); - return(IA64_NO_FAULT); -} - -void kvm_tak(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r1, r3; - - r3 = vcpu_get_gr(vcpu, inst.M46.r3); - r1 = vcpu_tak(vcpu, r3); - vcpu_set_gr(vcpu, inst.M46.r1, r1, 0); -} - -/************************************ - * Insert/Purge translation register/cache - ************************************/ -void vcpu_itc_i(struct kvm_vcpu *vcpu, u64 pte, u64 itir, u64 ifa) -{ - thash_purge_and_insert(vcpu, pte, itir, ifa, I_TLB); -} - -void vcpu_itc_d(struct kvm_vcpu *vcpu, u64 pte, u64 itir, u64 ifa) -{ - thash_purge_and_insert(vcpu, pte, itir, ifa, D_TLB); -} - -void vcpu_itr_i(struct kvm_vcpu *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa) -{ - u64 ps, va, rid; - struct thash_data *p_itr; - - ps = itir_ps(itir); - va = PAGEALIGN(ifa, ps); - pte &= ~PAGE_FLAGS_RV_MASK; - rid = vcpu_get_rr(vcpu, ifa); - rid = rid & RR_RID_MASK; - p_itr = (struct thash_data *)&vcpu->arch.itrs[slot]; - vcpu_set_tr(p_itr, pte, itir, va, rid); - vcpu_quick_region_set(VMX(vcpu, itr_regions), va); -} - - -void vcpu_itr_d(struct kvm_vcpu *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa) -{ - u64 gpfn; - u64 ps, va, rid; - struct thash_data *p_dtr; - - ps = itir_ps(itir); - va = PAGEALIGN(ifa, ps); - pte &= ~PAGE_FLAGS_RV_MASK; - - if (ps != _PAGE_SIZE_16M) - thash_purge_entries(vcpu, va, ps); - gpfn = (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT; - if (__gpfn_is_io(gpfn)) - pte |= VTLB_PTE_IO; - rid = vcpu_get_rr(vcpu, va); - rid = rid & RR_RID_MASK; - p_dtr = (struct thash_data *)&vcpu->arch.dtrs[slot]; - vcpu_set_tr((struct thash_data *)&vcpu->arch.dtrs[slot], - pte, itir, va, rid); - vcpu_quick_region_set(VMX(vcpu, dtr_regions), va); -} - -void vcpu_ptr_d(struct kvm_vcpu *vcpu, u64 ifa, u64 ps) -{ - int index; - u64 va; - - va = PAGEALIGN(ifa, ps); - while ((index = vtr_find_overlap(vcpu, va, ps, D_TLB)) >= 0) - vcpu->arch.dtrs[index].page_flags = 0; - - thash_purge_entries(vcpu, va, ps); -} - -void vcpu_ptr_i(struct kvm_vcpu *vcpu, u64 ifa, u64 ps) -{ - int index; - u64 va; - - va = PAGEALIGN(ifa, ps); - while ((index = vtr_find_overlap(vcpu, va, ps, I_TLB)) >= 0) - vcpu->arch.itrs[index].page_flags = 0; - - thash_purge_entries(vcpu, va, ps); -} - -void vcpu_ptc_l(struct kvm_vcpu *vcpu, u64 va, u64 ps) -{ - va = PAGEALIGN(va, ps); - thash_purge_entries(vcpu, va, ps); -} - -void vcpu_ptc_e(struct kvm_vcpu *vcpu, u64 va) -{ - thash_purge_all(vcpu); -} - -void vcpu_ptc_ga(struct kvm_vcpu *vcpu, u64 va, u64 ps) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - long psr; - local_irq_save(psr); - p->exit_reason = EXIT_REASON_PTC_G; - - p->u.ptc_g_data.rr = vcpu_get_rr(vcpu, va); - p->u.ptc_g_data.vaddr = va; - p->u.ptc_g_data.ps = ps; - vmm_transition(vcpu); - /* Do Local Purge Here*/ - vcpu_ptc_l(vcpu, va, ps); - local_irq_restore(psr); -} - - -void vcpu_ptc_g(struct kvm_vcpu *vcpu, u64 va, u64 ps) -{ - vcpu_ptc_ga(vcpu, va, ps); -} - -void kvm_ptc_e(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - vcpu_ptc_e(vcpu, ifa); -} - -void kvm_ptc_g(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa, itir; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - itir = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_ptc_g(vcpu, ifa, itir_ps(itir)); -} - -void kvm_ptc_ga(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa, itir; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - itir = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_ptc_ga(vcpu, ifa, itir_ps(itir)); -} - -void kvm_ptc_l(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa, itir; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - itir = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_ptc_l(vcpu, ifa, itir_ps(itir)); -} - -void kvm_ptr_d(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa, itir; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - itir = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_ptr_d(vcpu, ifa, itir_ps(itir)); -} - -void kvm_ptr_i(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long ifa, itir; - - ifa = vcpu_get_gr(vcpu, inst.M45.r3); - itir = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_ptr_i(vcpu, ifa, itir_ps(itir)); -} - -void kvm_itr_d(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long itir, ifa, pte, slot; - - slot = vcpu_get_gr(vcpu, inst.M45.r3); - pte = vcpu_get_gr(vcpu, inst.M45.r2); - itir = vcpu_get_itir(vcpu); - ifa = vcpu_get_ifa(vcpu); - vcpu_itr_d(vcpu, slot, pte, itir, ifa); -} - - - -void kvm_itr_i(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long itir, ifa, pte, slot; - - slot = vcpu_get_gr(vcpu, inst.M45.r3); - pte = vcpu_get_gr(vcpu, inst.M45.r2); - itir = vcpu_get_itir(vcpu); - ifa = vcpu_get_ifa(vcpu); - vcpu_itr_i(vcpu, slot, pte, itir, ifa); -} - -void kvm_itc_d(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long itir, ifa, pte; - - itir = vcpu_get_itir(vcpu); - ifa = vcpu_get_ifa(vcpu); - pte = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_itc_d(vcpu, pte, itir, ifa); -} - -void kvm_itc_i(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long itir, ifa, pte; - - itir = vcpu_get_itir(vcpu); - ifa = vcpu_get_ifa(vcpu); - pte = vcpu_get_gr(vcpu, inst.M45.r2); - vcpu_itc_i(vcpu, pte, itir, ifa); -} - -/************************************* - * Moves to semi-privileged registers - *************************************/ - -void kvm_mov_to_ar_imm(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long imm; - - if (inst.M30.s) - imm = -inst.M30.imm; - else - imm = inst.M30.imm; - - vcpu_set_itc(vcpu, imm); -} - -void kvm_mov_to_ar_reg(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r2; - - r2 = vcpu_get_gr(vcpu, inst.M29.r2); - vcpu_set_itc(vcpu, r2); -} - -void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r1; - - r1 = vcpu_get_itc(vcpu); - vcpu_set_gr(vcpu, inst.M31.r1, r1, 0); -} - -/************************************************************************** - struct kvm_vcpu protection key register access routines - **************************************************************************/ - -unsigned long vcpu_get_pkr(struct kvm_vcpu *vcpu, unsigned long reg) -{ - return ((unsigned long)ia64_get_pkr(reg)); -} - -void vcpu_set_pkr(struct kvm_vcpu *vcpu, unsigned long reg, unsigned long val) -{ - ia64_set_pkr(reg, val); -} - -/******************************** - * Moves to privileged registers - ********************************/ -unsigned long vcpu_set_rr(struct kvm_vcpu *vcpu, unsigned long reg, - unsigned long val) -{ - union ia64_rr oldrr, newrr; - unsigned long rrval; - struct exit_ctl_data *p = &vcpu->arch.exit_data; - unsigned long psr; - - oldrr.val = vcpu_get_rr(vcpu, reg); - newrr.val = val; - vcpu->arch.vrr[reg >> VRN_SHIFT] = val; - - switch ((unsigned long)(reg >> VRN_SHIFT)) { - case VRN6: - vcpu->arch.vmm_rr = vrrtomrr(val); - local_irq_save(psr); - p->exit_reason = EXIT_REASON_SWITCH_RR6; - vmm_transition(vcpu); - local_irq_restore(psr); - break; - case VRN4: - rrval = vrrtomrr(val); - vcpu->arch.metaphysical_saved_rr4 = rrval; - if (!is_physical_mode(vcpu)) - ia64_set_rr(reg, rrval); - break; - case VRN0: - rrval = vrrtomrr(val); - vcpu->arch.metaphysical_saved_rr0 = rrval; - if (!is_physical_mode(vcpu)) - ia64_set_rr(reg, rrval); - break; - default: - ia64_set_rr(reg, vrrtomrr(val)); - break; - } - - return (IA64_NO_FAULT); -} - -void kvm_mov_to_rr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r2; - - r3 = vcpu_get_gr(vcpu, inst.M42.r3); - r2 = vcpu_get_gr(vcpu, inst.M42.r2); - vcpu_set_rr(vcpu, r3, r2); -} - -void kvm_mov_to_dbr(struct kvm_vcpu *vcpu, INST64 inst) -{ -} - -void kvm_mov_to_ibr(struct kvm_vcpu *vcpu, INST64 inst) -{ -} - -void kvm_mov_to_pmc(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r2; - - r3 = vcpu_get_gr(vcpu, inst.M42.r3); - r2 = vcpu_get_gr(vcpu, inst.M42.r2); - vcpu_set_pmc(vcpu, r3, r2); -} - -void kvm_mov_to_pmd(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r2; - - r3 = vcpu_get_gr(vcpu, inst.M42.r3); - r2 = vcpu_get_gr(vcpu, inst.M42.r2); - vcpu_set_pmd(vcpu, r3, r2); -} - -void kvm_mov_to_pkr(struct kvm_vcpu *vcpu, INST64 inst) -{ - u64 r3, r2; - - r3 = vcpu_get_gr(vcpu, inst.M42.r3); - r2 = vcpu_get_gr(vcpu, inst.M42.r2); - vcpu_set_pkr(vcpu, r3, r2); -} - -void kvm_mov_from_rr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_rr(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -void kvm_mov_from_pkr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_pkr(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -void kvm_mov_from_dbr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_dbr(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -void kvm_mov_from_ibr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_ibr(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -void kvm_mov_from_pmc(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_pmc(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -unsigned long vcpu_get_cpuid(struct kvm_vcpu *vcpu, unsigned long reg) -{ - /* FIXME: This could get called as a result of a rsvd-reg fault */ - if (reg > (ia64_get_cpuid(3) & 0xff)) - return 0; - else - return ia64_get_cpuid(reg); -} - -void kvm_mov_from_cpuid(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r3, r1; - - r3 = vcpu_get_gr(vcpu, inst.M43.r3); - r1 = vcpu_get_cpuid(vcpu, r3); - vcpu_set_gr(vcpu, inst.M43.r1, r1, 0); -} - -void vcpu_set_tpr(struct kvm_vcpu *vcpu, unsigned long val) -{ - VCPU(vcpu, tpr) = val; - vcpu->arch.irq_check = 1; -} - -unsigned long kvm_mov_to_cr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long r2; - - r2 = vcpu_get_gr(vcpu, inst.M32.r2); - VCPU(vcpu, vcr[inst.M32.cr3]) = r2; - - switch (inst.M32.cr3) { - case 0: - vcpu_set_dcr(vcpu, r2); - break; - case 1: - vcpu_set_itm(vcpu, r2); - break; - case 66: - vcpu_set_tpr(vcpu, r2); - break; - case 67: - vcpu_set_eoi(vcpu, r2); - break; - default: - break; - } - - return 0; -} - -unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long tgt = inst.M33.r1; - unsigned long val; - - switch (inst.M33.cr3) { - case 65: - val = vcpu_get_ivr(vcpu); - vcpu_set_gr(vcpu, tgt, val, 0); - break; - - case 67: - vcpu_set_gr(vcpu, tgt, 0L, 0); - break; - default: - val = VCPU(vcpu, vcr[inst.M33.cr3]); - vcpu_set_gr(vcpu, tgt, val, 0); - break; - } - - return 0; -} - -void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val) -{ - - unsigned long mask; - struct kvm_pt_regs *regs; - struct ia64_psr old_psr, new_psr; - - old_psr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - - regs = vcpu_regs(vcpu); - /* We only support guest as: - * vpsr.pk = 0 - * vpsr.is = 0 - * Otherwise panic - */ - if (val & (IA64_PSR_PK | IA64_PSR_IS | IA64_PSR_VM)) - panic_vm(vcpu, "Only support guests with vpsr.pk =0 " - "& vpsr.is=0\n"); - - /* - * For those IA64_PSR bits: id/da/dd/ss/ed/ia - * Since these bits will become 0, after success execution of each - * instruction, we will change set them to mIA64_PSR - */ - VCPU(vcpu, vpsr) = val - & (~(IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | - IA64_PSR_SS | IA64_PSR_ED | IA64_PSR_IA)); - - if (!old_psr.i && (val & IA64_PSR_I)) { - /* vpsr.i 0->1 */ - vcpu->arch.irq_check = 1; - } - new_psr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - - /* - * All vIA64_PSR bits shall go to mPSR (v->tf->tf_special.psr) - * , except for the following bits: - * ic/i/dt/si/rt/mc/it/bn/vm - */ - mask = IA64_PSR_IC + IA64_PSR_I + IA64_PSR_DT + IA64_PSR_SI + - IA64_PSR_RT + IA64_PSR_MC + IA64_PSR_IT + IA64_PSR_BN + - IA64_PSR_VM; - - regs->cr_ipsr = (regs->cr_ipsr & mask) | (val & (~mask)); - - check_mm_mode_switch(vcpu, old_psr, new_psr); - - return ; -} - -unsigned long vcpu_cover(struct kvm_vcpu *vcpu) -{ - struct ia64_psr vpsr; - - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - - if (!vpsr.ic) - VCPU(vcpu, ifs) = regs->cr_ifs; - regs->cr_ifs = IA64_IFS_V; - return (IA64_NO_FAULT); -} - - - -/************************************************************************** - VCPU banked general register access routines - **************************************************************************/ -#define vcpu_bsw0_unat(i, b0unat, b1unat, runat, VMM_PT_REGS_R16_SLOT) \ - do { \ - __asm__ __volatile__ ( \ - ";;extr.u %0 = %3,%6,16;;\n" \ - "dep %1 = %0, %1, 0, 16;;\n" \ - "st8 [%4] = %1\n" \ - "extr.u %0 = %2, 16, 16;;\n" \ - "dep %3 = %0, %3, %6, 16;;\n" \ - "st8 [%5] = %3\n" \ - ::"r"(i), "r"(*b1unat), "r"(*b0unat), \ - "r"(*runat), "r"(b1unat), "r"(runat), \ - "i"(VMM_PT_REGS_R16_SLOT) : "memory"); \ - } while (0) - -void vcpu_bsw0(struct kvm_vcpu *vcpu) -{ - unsigned long i; - - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - unsigned long *r = ®s->r16; - unsigned long *b0 = &VCPU(vcpu, vbgr[0]); - unsigned long *b1 = &VCPU(vcpu, vgr[0]); - unsigned long *runat = ®s->eml_unat; - unsigned long *b0unat = &VCPU(vcpu, vbnat); - unsigned long *b1unat = &VCPU(vcpu, vnat); - - - if (VCPU(vcpu, vpsr) & IA64_PSR_BN) { - for (i = 0; i < 16; i++) { - *b1++ = *r; - *r++ = *b0++; - } - vcpu_bsw0_unat(i, b0unat, b1unat, runat, - VMM_PT_REGS_R16_SLOT); - VCPU(vcpu, vpsr) &= ~IA64_PSR_BN; - } -} - -#define vcpu_bsw1_unat(i, b0unat, b1unat, runat, VMM_PT_REGS_R16_SLOT) \ - do { \ - __asm__ __volatile__ (";;extr.u %0 = %3, %6, 16;;\n" \ - "dep %1 = %0, %1, 16, 16;;\n" \ - "st8 [%4] = %1\n" \ - "extr.u %0 = %2, 0, 16;;\n" \ - "dep %3 = %0, %3, %6, 16;;\n" \ - "st8 [%5] = %3\n" \ - ::"r"(i), "r"(*b0unat), "r"(*b1unat), \ - "r"(*runat), "r"(b0unat), "r"(runat), \ - "i"(VMM_PT_REGS_R16_SLOT) : "memory"); \ - } while (0) - -void vcpu_bsw1(struct kvm_vcpu *vcpu) -{ - unsigned long i; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - unsigned long *r = ®s->r16; - unsigned long *b0 = &VCPU(vcpu, vbgr[0]); - unsigned long *b1 = &VCPU(vcpu, vgr[0]); - unsigned long *runat = ®s->eml_unat; - unsigned long *b0unat = &VCPU(vcpu, vbnat); - unsigned long *b1unat = &VCPU(vcpu, vnat); - - if (!(VCPU(vcpu, vpsr) & IA64_PSR_BN)) { - for (i = 0; i < 16; i++) { - *b0++ = *r; - *r++ = *b1++; - } - vcpu_bsw1_unat(i, b0unat, b1unat, runat, - VMM_PT_REGS_R16_SLOT); - VCPU(vcpu, vpsr) |= IA64_PSR_BN; - } -} - -void vcpu_rfi(struct kvm_vcpu *vcpu) -{ - unsigned long ifs, psr; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - psr = VCPU(vcpu, ipsr); - if (psr & IA64_PSR_BN) - vcpu_bsw1(vcpu); - else - vcpu_bsw0(vcpu); - vcpu_set_psr(vcpu, psr); - ifs = VCPU(vcpu, ifs); - if (ifs >> 63) - regs->cr_ifs = ifs; - regs->cr_iip = VCPU(vcpu, iip); -} - -/* - VPSR can't keep track of below bits of guest PSR - This function gets guest PSR - */ - -unsigned long vcpu_get_psr(struct kvm_vcpu *vcpu) -{ - unsigned long mask; - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - - mask = IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | - IA64_PSR_MFH | IA64_PSR_CPL | IA64_PSR_RI; - return (VCPU(vcpu, vpsr) & ~mask) | (regs->cr_ipsr & mask); -} - -void kvm_rsm(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long vpsr; - unsigned long imm24 = (inst.M44.i<<23) | (inst.M44.i2<<21) - | inst.M44.imm; - - vpsr = vcpu_get_psr(vcpu); - vpsr &= (~imm24); - vcpu_set_psr(vcpu, vpsr); -} - -void kvm_ssm(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long vpsr; - unsigned long imm24 = (inst.M44.i << 23) | (inst.M44.i2 << 21) - | inst.M44.imm; - - vpsr = vcpu_get_psr(vcpu); - vpsr |= imm24; - vcpu_set_psr(vcpu, vpsr); -} - -/* Generate Mask - * Parameter: - * bit -- starting bit - * len -- how many bits - */ -#define MASK(bit,len) \ -({ \ - __u64 ret; \ - \ - __asm __volatile("dep %0=-1, r0, %1, %2"\ - : "=r" (ret): \ - "M" (bit), \ - "M" (len)); \ - ret; \ -}) - -void vcpu_set_psr_l(struct kvm_vcpu *vcpu, unsigned long val) -{ - val = (val & MASK(0, 32)) | (vcpu_get_psr(vcpu) & MASK(32, 32)); - vcpu_set_psr(vcpu, val); -} - -void kvm_mov_to_psr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long val; - - val = vcpu_get_gr(vcpu, inst.M35.r2); - vcpu_set_psr_l(vcpu, val); -} - -void kvm_mov_from_psr(struct kvm_vcpu *vcpu, INST64 inst) -{ - unsigned long val; - - val = vcpu_get_psr(vcpu); - val = (val & MASK(0, 32)) | (val & MASK(35, 2)); - vcpu_set_gr(vcpu, inst.M33.r1, val, 0); -} - -void vcpu_increment_iip(struct kvm_vcpu *vcpu) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - struct ia64_psr *ipsr = (struct ia64_psr *)®s->cr_ipsr; - if (ipsr->ri == 2) { - ipsr->ri = 0; - regs->cr_iip += 16; - } else - ipsr->ri++; -} - -void vcpu_decrement_iip(struct kvm_vcpu *vcpu) -{ - struct kvm_pt_regs *regs = vcpu_regs(vcpu); - struct ia64_psr *ipsr = (struct ia64_psr *)®s->cr_ipsr; - - if (ipsr->ri == 0) { - ipsr->ri = 2; - regs->cr_iip -= 16; - } else - ipsr->ri--; -} - -/** Emulate a privileged operation. - * - * - * @param vcpu virtual cpu - * @cause the reason cause virtualization fault - * @opcode the instruction code which cause virtualization fault - */ - -void kvm_emulate(struct kvm_vcpu *vcpu, struct kvm_pt_regs *regs) -{ - unsigned long status, cause, opcode ; - INST64 inst; - - status = IA64_NO_FAULT; - cause = VMX(vcpu, cause); - opcode = VMX(vcpu, opcode); - inst.inst = opcode; - /* - * Switch to actual virtual rid in rr0 and rr4, - * which is required by some tlb related instructions. - */ - prepare_if_physical_mode(vcpu); - - switch (cause) { - case EVENT_RSM: - kvm_rsm(vcpu, inst); - break; - case EVENT_SSM: - kvm_ssm(vcpu, inst); - break; - case EVENT_MOV_TO_PSR: - kvm_mov_to_psr(vcpu, inst); - break; - case EVENT_MOV_FROM_PSR: - kvm_mov_from_psr(vcpu, inst); - break; - case EVENT_MOV_FROM_CR: - kvm_mov_from_cr(vcpu, inst); - break; - case EVENT_MOV_TO_CR: - kvm_mov_to_cr(vcpu, inst); - break; - case EVENT_BSW_0: - vcpu_bsw0(vcpu); - break; - case EVENT_BSW_1: - vcpu_bsw1(vcpu); - break; - case EVENT_COVER: - vcpu_cover(vcpu); - break; - case EVENT_RFI: - vcpu_rfi(vcpu); - break; - case EVENT_ITR_D: - kvm_itr_d(vcpu, inst); - break; - case EVENT_ITR_I: - kvm_itr_i(vcpu, inst); - break; - case EVENT_PTR_D: - kvm_ptr_d(vcpu, inst); - break; - case EVENT_PTR_I: - kvm_ptr_i(vcpu, inst); - break; - case EVENT_ITC_D: - kvm_itc_d(vcpu, inst); - break; - case EVENT_ITC_I: - kvm_itc_i(vcpu, inst); - break; - case EVENT_PTC_L: - kvm_ptc_l(vcpu, inst); - break; - case EVENT_PTC_G: - kvm_ptc_g(vcpu, inst); - break; - case EVENT_PTC_GA: - kvm_ptc_ga(vcpu, inst); - break; - case EVENT_PTC_E: - kvm_ptc_e(vcpu, inst); - break; - case EVENT_MOV_TO_RR: - kvm_mov_to_rr(vcpu, inst); - break; - case EVENT_MOV_FROM_RR: - kvm_mov_from_rr(vcpu, inst); - break; - case EVENT_THASH: - kvm_thash(vcpu, inst); - break; - case EVENT_TTAG: - kvm_ttag(vcpu, inst); - break; - case EVENT_TPA: - status = kvm_tpa(vcpu, inst); - break; - case EVENT_TAK: - kvm_tak(vcpu, inst); - break; - case EVENT_MOV_TO_AR_IMM: - kvm_mov_to_ar_imm(vcpu, inst); - break; - case EVENT_MOV_TO_AR: - kvm_mov_to_ar_reg(vcpu, inst); - break; - case EVENT_MOV_FROM_AR: - kvm_mov_from_ar_reg(vcpu, inst); - break; - case EVENT_MOV_TO_DBR: - kvm_mov_to_dbr(vcpu, inst); - break; - case EVENT_MOV_TO_IBR: - kvm_mov_to_ibr(vcpu, inst); - break; - case EVENT_MOV_TO_PMC: - kvm_mov_to_pmc(vcpu, inst); - break; - case EVENT_MOV_TO_PMD: - kvm_mov_to_pmd(vcpu, inst); - break; - case EVENT_MOV_TO_PKR: - kvm_mov_to_pkr(vcpu, inst); - break; - case EVENT_MOV_FROM_DBR: - kvm_mov_from_dbr(vcpu, inst); - break; - case EVENT_MOV_FROM_IBR: - kvm_mov_from_ibr(vcpu, inst); - break; - case EVENT_MOV_FROM_PMC: - kvm_mov_from_pmc(vcpu, inst); - break; - case EVENT_MOV_FROM_PKR: - kvm_mov_from_pkr(vcpu, inst); - break; - case EVENT_MOV_FROM_CPUID: - kvm_mov_from_cpuid(vcpu, inst); - break; - case EVENT_VMSW: - status = IA64_FAULT; - break; - default: - break; - }; - /*Assume all status is NO_FAULT ?*/ - if (status == IA64_NO_FAULT && cause != EVENT_RFI) - vcpu_increment_iip(vcpu); - - recover_if_physical_mode(vcpu); -} - -void init_vcpu(struct kvm_vcpu *vcpu) -{ - int i; - - vcpu->arch.mode_flags = GUEST_IN_PHY; - VMX(vcpu, vrr[0]) = 0x38; - VMX(vcpu, vrr[1]) = 0x38; - VMX(vcpu, vrr[2]) = 0x38; - VMX(vcpu, vrr[3]) = 0x38; - VMX(vcpu, vrr[4]) = 0x38; - VMX(vcpu, vrr[5]) = 0x38; - VMX(vcpu, vrr[6]) = 0x38; - VMX(vcpu, vrr[7]) = 0x38; - VCPU(vcpu, vpsr) = IA64_PSR_BN; - VCPU(vcpu, dcr) = 0; - /* pta.size must not be 0. The minimum is 15 (32k) */ - VCPU(vcpu, pta) = 15 << 2; - VCPU(vcpu, itv) = 0x10000; - VCPU(vcpu, itm) = 0; - VMX(vcpu, last_itc) = 0; - - VCPU(vcpu, lid) = VCPU_LID(vcpu); - VCPU(vcpu, ivr) = 0; - VCPU(vcpu, tpr) = 0x10000; - VCPU(vcpu, eoi) = 0; - VCPU(vcpu, irr[0]) = 0; - VCPU(vcpu, irr[1]) = 0; - VCPU(vcpu, irr[2]) = 0; - VCPU(vcpu, irr[3]) = 0; - VCPU(vcpu, pmv) = 0x10000; - VCPU(vcpu, cmcv) = 0x10000; - VCPU(vcpu, lrr0) = 0x10000; /* default reset value? */ - VCPU(vcpu, lrr1) = 0x10000; /* default reset value? */ - update_vhpi(vcpu, NULL_VECTOR); - VLSAPIC_XTP(vcpu) = 0x80; /* disabled */ - - for (i = 0; i < 4; i++) - VLSAPIC_INSVC(vcpu, i) = 0; -} - -void kvm_init_all_rr(struct kvm_vcpu *vcpu) -{ - unsigned long psr; - - local_irq_save(psr); - - /* WARNING: not allow co-exist of both virtual mode and physical - * mode in same region - */ - - vcpu->arch.metaphysical_saved_rr0 = vrrtomrr(VMX(vcpu, vrr[VRN0])); - vcpu->arch.metaphysical_saved_rr4 = vrrtomrr(VMX(vcpu, vrr[VRN4])); - - if (is_physical_mode(vcpu)) { - if (vcpu->arch.mode_flags & GUEST_PHY_EMUL) - panic_vm(vcpu, "Machine Status conflicts!\n"); - - ia64_set_rr((VRN0 << VRN_SHIFT), vcpu->arch.metaphysical_rr0); - ia64_dv_serialize_data(); - ia64_set_rr((VRN4 << VRN_SHIFT), vcpu->arch.metaphysical_rr4); - ia64_dv_serialize_data(); - } else { - ia64_set_rr((VRN0 << VRN_SHIFT), - vcpu->arch.metaphysical_saved_rr0); - ia64_dv_serialize_data(); - ia64_set_rr((VRN4 << VRN_SHIFT), - vcpu->arch.metaphysical_saved_rr4); - ia64_dv_serialize_data(); - } - ia64_set_rr((VRN1 << VRN_SHIFT), - vrrtomrr(VMX(vcpu, vrr[VRN1]))); - ia64_dv_serialize_data(); - ia64_set_rr((VRN2 << VRN_SHIFT), - vrrtomrr(VMX(vcpu, vrr[VRN2]))); - ia64_dv_serialize_data(); - ia64_set_rr((VRN3 << VRN_SHIFT), - vrrtomrr(VMX(vcpu, vrr[VRN3]))); - ia64_dv_serialize_data(); - ia64_set_rr((VRN5 << VRN_SHIFT), - vrrtomrr(VMX(vcpu, vrr[VRN5]))); - ia64_dv_serialize_data(); - ia64_set_rr((VRN7 << VRN_SHIFT), - vrrtomrr(VMX(vcpu, vrr[VRN7]))); - ia64_dv_serialize_data(); - ia64_srlz_d(); - ia64_set_psr(psr); -} - -int vmm_entry(void) -{ - struct kvm_vcpu *v; - v = current_vcpu; - - ia64_call_vsa(PAL_VPS_RESTORE, (unsigned long)v->arch.vpd, - 0, 0, 0, 0, 0, 0); - kvm_init_vtlb(v); - kvm_init_vhpt(v); - init_vcpu(v); - kvm_init_all_rr(v); - vmm_reset_entry(); - - return 0; -} - -static void kvm_show_registers(struct kvm_pt_regs *regs) -{ - unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; - - struct kvm_vcpu *vcpu = current_vcpu; - if (vcpu != NULL) - printk("vcpu 0x%p vcpu %d\n", - vcpu, vcpu->vcpu_id); - - printk("psr : %016lx ifs : %016lx ip : [<%016lx>]\n", - regs->cr_ipsr, regs->cr_ifs, ip); - - printk("unat: %016lx pfs : %016lx rsc : %016lx\n", - regs->ar_unat, regs->ar_pfs, regs->ar_rsc); - printk("rnat: %016lx bspstore: %016lx pr : %016lx\n", - regs->ar_rnat, regs->ar_bspstore, regs->pr); - printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", - regs->loadrs, regs->ar_ccv, regs->ar_fpsr); - printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd); - printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, - regs->b6, regs->b7); - printk("f6 : %05lx%016lx f7 : %05lx%016lx\n", - regs->f6.u.bits[1], regs->f6.u.bits[0], - regs->f7.u.bits[1], regs->f7.u.bits[0]); - printk("f8 : %05lx%016lx f9 : %05lx%016lx\n", - regs->f8.u.bits[1], regs->f8.u.bits[0], - regs->f9.u.bits[1], regs->f9.u.bits[0]); - printk("f10 : %05lx%016lx f11 : %05lx%016lx\n", - regs->f10.u.bits[1], regs->f10.u.bits[0], - regs->f11.u.bits[1], regs->f11.u.bits[0]); - - printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, - regs->r2, regs->r3); - printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, - regs->r9, regs->r10); - printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, - regs->r12, regs->r13); - printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, - regs->r15, regs->r16); - printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, - regs->r18, regs->r19); - printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, - regs->r21, regs->r22); - printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, - regs->r24, regs->r25); - printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, - regs->r27, regs->r28); - printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, - regs->r30, regs->r31); - -} - -void panic_vm(struct kvm_vcpu *v, const char *fmt, ...) -{ - va_list args; - char buf[256]; - - struct kvm_pt_regs *regs = vcpu_regs(v); - struct exit_ctl_data *p = &v->arch.exit_data; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - printk(buf); - kvm_show_registers(regs); - p->exit_reason = EXIT_REASON_VM_PANIC; - vmm_transition(v); - /*Never to return*/ - while (1); -} diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h deleted file mode 100644 index 988911b4cc7a..000000000000 --- a/arch/ia64/kvm/vcpu.h +++ /dev/null @@ -1,752 +0,0 @@ -/* - * vcpu.h: vcpu routines - * Copyright (c) 2005, Intel Corporation. - * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) - * Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com) - * - * Copyright (c) 2007, Intel Corporation. - * Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com) - * Xiantao Zhang (xiantao.zhang@intel.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - - -#ifndef __KVM_VCPU_H__ -#define __KVM_VCPU_H__ - -#include -#include -#include - -#ifndef __ASSEMBLY__ -#include "vti.h" - -#include -#include - -typedef unsigned long IA64_INST; - -typedef union U_IA64_BUNDLE { - unsigned long i64[2]; - struct { unsigned long template:5, slot0:41, slot1a:18, - slot1b:23, slot2:41; }; - /* NOTE: following doesn't work because bitfields can't cross natural - size boundaries - struct { unsigned long template:5, slot0:41, slot1:41, slot2:41; }; */ -} IA64_BUNDLE; - -typedef union U_INST64_A5 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, imm7b:7, r3:2, imm5c:5, - imm9d:9, s:1, major:4; }; -} INST64_A5; - -typedef union U_INST64_B4 { - IA64_INST inst; - struct { unsigned long qp:6, btype:3, un3:3, p:1, b2:3, un11:11, x6:6, - wh:2, d:1, un1:1, major:4; }; -} INST64_B4; - -typedef union U_INST64_B8 { - IA64_INST inst; - struct { unsigned long qp:6, un21:21, x6:6, un4:4, major:4; }; -} INST64_B8; - -typedef union U_INST64_B9 { - IA64_INST inst; - struct { unsigned long qp:6, imm20:20, :1, x6:6, :3, i:1, major:4; }; -} INST64_B9; - -typedef union U_INST64_I19 { - IA64_INST inst; - struct { unsigned long qp:6, imm20:20, :1, x6:6, x3:3, i:1, major:4; }; -} INST64_I19; - -typedef union U_INST64_I26 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4; }; -} INST64_I26; - -typedef union U_INST64_I27 { - IA64_INST inst; - struct { unsigned long qp:6, :7, imm:7, ar3:7, x6:6, x3:3, s:1, major:4; }; -} INST64_I27; - -typedef union U_INST64_I28 { /* not privileged (mov from AR) */ - IA64_INST inst; - struct { unsigned long qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4; }; -} INST64_I28; - -typedef union U_INST64_M28 { - IA64_INST inst; - struct { unsigned long qp:6, :14, r3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M28; - -typedef union U_INST64_M29 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, ar3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M29; - -typedef union U_INST64_M30 { - IA64_INST inst; - struct { unsigned long qp:6, :7, imm:7, ar3:7, x4:4, x2:2, - x3:3, s:1, major:4; }; -} INST64_M30; - -typedef union U_INST64_M31 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, :7, ar3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M31; - -typedef union U_INST64_M32 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, cr3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M32; - -typedef union U_INST64_M33 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, :7, cr3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M33; - -typedef union U_INST64_M35 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; }; - -} INST64_M35; - -typedef union U_INST64_M36 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, :14, x6:6, x3:3, :1, major:4; }; -} INST64_M36; - -typedef union U_INST64_M37 { - IA64_INST inst; - struct { unsigned long qp:6, imm20a:20, :1, x4:4, x2:2, x3:3, - i:1, major:4; }; -} INST64_M37; - -typedef union U_INST64_M41 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, :7, x6:6, x3:3, :1, major:4; }; -} INST64_M41; - -typedef union U_INST64_M42 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M42; - -typedef union U_INST64_M43 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, :7, r3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M43; - -typedef union U_INST64_M44 { - IA64_INST inst; - struct { unsigned long qp:6, imm:21, x4:4, i2:2, x3:3, i:1, major:4; }; -} INST64_M44; - -typedef union U_INST64_M45 { - IA64_INST inst; - struct { unsigned long qp:6, :7, r2:7, r3:7, x6:6, x3:3, :1, major:4; }; -} INST64_M45; - -typedef union U_INST64_M46 { - IA64_INST inst; - struct { unsigned long qp:6, r1:7, un7:7, r3:7, x6:6, - x3:3, un1:1, major:4; }; -} INST64_M46; - -typedef union U_INST64_M47 { - IA64_INST inst; - struct { unsigned long qp:6, un14:14, r3:7, x6:6, x3:3, un1:1, major:4; }; -} INST64_M47; - -typedef union U_INST64_M1{ - IA64_INST inst; - struct { unsigned long qp:6, r1:7, un7:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M1; - -typedef union U_INST64_M2{ - IA64_INST inst; - struct { unsigned long qp:6, r1:7, r2:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M2; - -typedef union U_INST64_M3{ - IA64_INST inst; - struct { unsigned long qp:6, r1:7, imm7:7, r3:7, i:1, hint:2, - x6:6, s:1, major:4; }; -} INST64_M3; - -typedef union U_INST64_M4 { - IA64_INST inst; - struct { unsigned long qp:6, un7:7, r2:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M4; - -typedef union U_INST64_M5 { - IA64_INST inst; - struct { unsigned long qp:6, imm7:7, r2:7, r3:7, i:1, hint:2, - x6:6, s:1, major:4; }; -} INST64_M5; - -typedef union U_INST64_M6 { - IA64_INST inst; - struct { unsigned long qp:6, f1:7, un7:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M6; - -typedef union U_INST64_M9 { - IA64_INST inst; - struct { unsigned long qp:6, :7, f2:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M9; - -typedef union U_INST64_M10 { - IA64_INST inst; - struct { unsigned long qp:6, imm7:7, f2:7, r3:7, i:1, hint:2, - x6:6, s:1, major:4; }; -} INST64_M10; - -typedef union U_INST64_M12 { - IA64_INST inst; - struct { unsigned long qp:6, f1:7, f2:7, r3:7, x:1, hint:2, - x6:6, m:1, major:4; }; -} INST64_M12; - -typedef union U_INST64_M15 { - IA64_INST inst; - struct { unsigned long qp:6, :7, imm7:7, r3:7, i:1, hint:2, - x6:6, s:1, major:4; }; -} INST64_M15; - -typedef union U_INST64 { - IA64_INST inst; - struct { unsigned long :37, major:4; } generic; - INST64_A5 A5; /* used in build_hypercall_bundle only */ - INST64_B4 B4; /* used in build_hypercall_bundle only */ - INST64_B8 B8; /* rfi, bsw.[01] */ - INST64_B9 B9; /* break.b */ - INST64_I19 I19; /* used in build_hypercall_bundle only */ - INST64_I26 I26; /* mov register to ar (I unit) */ - INST64_I27 I27; /* mov immediate to ar (I unit) */ - INST64_I28 I28; /* mov from ar (I unit) */ - INST64_M1 M1; /* ld integer */ - INST64_M2 M2; - INST64_M3 M3; - INST64_M4 M4; /* st integer */ - INST64_M5 M5; - INST64_M6 M6; /* ldfd floating pointer */ - INST64_M9 M9; /* stfd floating pointer */ - INST64_M10 M10; /* stfd floating pointer */ - INST64_M12 M12; /* ldfd pair floating pointer */ - INST64_M15 M15; /* lfetch + imm update */ - INST64_M28 M28; /* purge translation cache entry */ - INST64_M29 M29; /* mov register to ar (M unit) */ - INST64_M30 M30; /* mov immediate to ar (M unit) */ - INST64_M31 M31; /* mov from ar (M unit) */ - INST64_M32 M32; /* mov reg to cr */ - INST64_M33 M33; /* mov from cr */ - INST64_M35 M35; /* mov to psr */ - INST64_M36 M36; /* mov from psr */ - INST64_M37 M37; /* break.m */ - INST64_M41 M41; /* translation cache insert */ - INST64_M42 M42; /* mov to indirect reg/translation reg insert*/ - INST64_M43 M43; /* mov from indirect reg */ - INST64_M44 M44; /* set/reset system mask */ - INST64_M45 M45; /* translation purge */ - INST64_M46 M46; /* translation access (tpa,tak) */ - INST64_M47 M47; /* purge translation entry */ -} INST64; - -#define MASK_41 ((unsigned long)0x1ffffffffff) - -/* Virtual address memory attributes encoding */ -#define VA_MATTR_WB 0x0 -#define VA_MATTR_UC 0x4 -#define VA_MATTR_UCE 0x5 -#define VA_MATTR_WC 0x6 -#define VA_MATTR_NATPAGE 0x7 - -#define PMASK(size) (~((size) - 1)) -#define PSIZE(size) (1UL<<(size)) -#define CLEARLSB(ppn, nbits) (((ppn) >> (nbits)) << (nbits)) -#define PAGEALIGN(va, ps) CLEARLSB(va, ps) -#define PAGE_FLAGS_RV_MASK (0x2|(0x3UL<<50)|(((1UL<<11)-1)<<53)) -#define _PAGE_MA_ST (0x1 << 2) /* is reserved for software use */ - -#define ARCH_PAGE_SHIFT 12 - -#define INVALID_TI_TAG (1UL << 63) - -#define VTLB_PTE_P_BIT 0 -#define VTLB_PTE_IO_BIT 60 -#define VTLB_PTE_IO (1UL<> 61))) - -#define vcpu_quick_region_set(_tr_regions,_ifa) \ - do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0) - -static inline void vcpu_set_tr(struct thash_data *trp, u64 pte, u64 itir, - u64 va, u64 rid) -{ - trp->page_flags = pte; - trp->itir = itir; - trp->vadr = va; - trp->rid = rid; -} - -extern u64 kvm_get_mpt_entry(u64 gpfn); - -/* Return I/ */ -static inline u64 __gpfn_is_io(u64 gpfn) -{ - u64 pte; - pte = kvm_get_mpt_entry(gpfn); - if (!(pte & GPFN_INV_MASK)) { - pte = pte & GPFN_IO_MASK; - if (pte != GPFN_PHYS_MMIO) - return pte; - } - return 0; -} -#endif -#define IA64_NO_FAULT 0 -#define IA64_FAULT 1 - -#define VMM_RBS_OFFSET ((VMM_TASK_SIZE + 15) & ~15) - -#define SW_BAD 0 /* Bad mode transitition */ -#define SW_V2P 1 /* Physical emulatino is activated */ -#define SW_P2V 2 /* Exit physical mode emulation */ -#define SW_SELF 3 /* No mode transition */ -#define SW_NOP 4 /* Mode transition, but without action required */ - -#define GUEST_IN_PHY 0x1 -#define GUEST_PHY_EMUL 0x2 - -#define current_vcpu ((struct kvm_vcpu *) ia64_getreg(_IA64_REG_TP)) - -#define VRN_SHIFT 61 -#define VRN_MASK 0xe000000000000000 -#define VRN0 0x0UL -#define VRN1 0x1UL -#define VRN2 0x2UL -#define VRN3 0x3UL -#define VRN4 0x4UL -#define VRN5 0x5UL -#define VRN6 0x6UL -#define VRN7 0x7UL - -#define IRQ_NO_MASKED 0 -#define IRQ_MASKED_BY_VTPR 1 -#define IRQ_MASKED_BY_INSVC 2 /* masked by inservice IRQ */ - -#define PTA_BASE_SHIFT 15 - -#define IA64_PSR_VM_BIT 46 -#define IA64_PSR_VM (__IA64_UL(1) << IA64_PSR_VM_BIT) - -/* Interruption Function State */ -#define IA64_IFS_V_BIT 63 -#define IA64_IFS_V (__IA64_UL(1) << IA64_IFS_V_BIT) - -#define PHY_PAGE_UC (_PAGE_A|_PAGE_D|_PAGE_P|_PAGE_MA_UC|_PAGE_AR_RWX) -#define PHY_PAGE_WB (_PAGE_A|_PAGE_D|_PAGE_P|_PAGE_MA_WB|_PAGE_AR_RWX) - -#ifndef __ASSEMBLY__ - -#include - -#define is_physical_mode(v) \ - ((v->arch.mode_flags) & GUEST_IN_PHY) - -#define is_virtual_mode(v) \ - (!is_physical_mode(v)) - -#define MODE_IND(psr) \ - (((psr).it << 2) + ((psr).dt << 1) + (psr).rt) - -#ifndef CONFIG_SMP -#define _vmm_raw_spin_lock(x) do {}while(0) -#define _vmm_raw_spin_unlock(x) do {}while(0) -#else -typedef struct { - volatile unsigned int lock; -} vmm_spinlock_t; -#define _vmm_raw_spin_lock(x) \ - do { \ - __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ - __u64 ia64_spinlock_val; \ - ia64_spinlock_val = ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0);\ - if (unlikely(ia64_spinlock_val)) { \ - do { \ - while (*ia64_spinlock_ptr) \ - ia64_barrier(); \ - ia64_spinlock_val = \ - ia64_cmpxchg4_acq(ia64_spinlock_ptr, 1, 0);\ - } while (ia64_spinlock_val); \ - } \ - } while (0) - -#define _vmm_raw_spin_unlock(x) \ - do { barrier(); \ - ((vmm_spinlock_t *)x)->lock = 0; } \ -while (0) -#endif - -void vmm_spin_lock(vmm_spinlock_t *lock); -void vmm_spin_unlock(vmm_spinlock_t *lock); -enum { - I_TLB = 1, - D_TLB = 2 -}; - -union kvm_va { - struct { - unsigned long off : 60; /* intra-region offset */ - unsigned long reg : 4; /* region number */ - } f; - unsigned long l; - void *p; -}; - -#define __kvm_pa(x) ({union kvm_va _v; _v.l = (long) (x); \ - _v.f.reg = 0; _v.l; }) -#define __kvm_va(x) ({union kvm_va _v; _v.l = (long) (x); \ - _v.f.reg = -1; _v.p; }) - -#define _REGION_ID(x) ({union ia64_rr _v; _v.val = (long)(x); \ - _v.rid; }) -#define _REGION_PAGE_SIZE(x) ({union ia64_rr _v; _v.val = (long)(x); \ - _v.ps; }) -#define _REGION_HW_WALKER(x) ({union ia64_rr _v; _v.val = (long)(x); \ - _v.ve; }) - -enum vhpt_ref{ DATA_REF, NA_REF, INST_REF, RSE_REF }; -enum tlb_miss_type { INSTRUCTION, DATA, REGISTER }; - -#define VCPU(_v, _x) ((_v)->arch.vpd->_x) -#define VMX(_v, _x) ((_v)->arch._x) - -#define VLSAPIC_INSVC(vcpu, i) ((vcpu)->arch.insvc[i]) -#define VLSAPIC_XTP(_v) VMX(_v, xtp) - -static inline unsigned long itir_ps(unsigned long itir) -{ - return ((itir >> 2) & 0x3f); -} - - -/************************************************************************** - VCPU control register access routines - **************************************************************************/ - -static inline u64 vcpu_get_itir(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, itir)); -} - -static inline void vcpu_set_itir(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, itir) = val; -} - -static inline u64 vcpu_get_ifa(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, ifa)); -} - -static inline void vcpu_set_ifa(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, ifa) = val; -} - -static inline u64 vcpu_get_iva(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, iva)); -} - -static inline u64 vcpu_get_pta(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, pta)); -} - -static inline u64 vcpu_get_lid(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, lid)); -} - -static inline u64 vcpu_get_tpr(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, tpr)); -} - -static inline u64 vcpu_get_eoi(struct kvm_vcpu *vcpu) -{ - return (0UL); /*reads of eoi always return 0 */ -} - -static inline u64 vcpu_get_irr0(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, irr[0])); -} - -static inline u64 vcpu_get_irr1(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, irr[1])); -} - -static inline u64 vcpu_get_irr2(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, irr[2])); -} - -static inline u64 vcpu_get_irr3(struct kvm_vcpu *vcpu) -{ - return ((u64)VCPU(vcpu, irr[3])); -} - -static inline void vcpu_set_dcr(struct kvm_vcpu *vcpu, u64 val) -{ - ia64_setreg(_IA64_REG_CR_DCR, val); -} - -static inline void vcpu_set_isr(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, isr) = val; -} - -static inline void vcpu_set_lid(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, lid) = val; -} - -static inline void vcpu_set_ipsr(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, ipsr) = val; -} - -static inline void vcpu_set_iip(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, iip) = val; -} - -static inline void vcpu_set_ifs(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, ifs) = val; -} - -static inline void vcpu_set_iipa(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, iipa) = val; -} - -static inline void vcpu_set_iha(struct kvm_vcpu *vcpu, u64 val) -{ - VCPU(vcpu, iha) = val; -} - - -static inline u64 vcpu_get_rr(struct kvm_vcpu *vcpu, u64 reg) -{ - return vcpu->arch.vrr[reg>>61]; -} - -/************************************************************************** - VCPU debug breakpoint register access routines - **************************************************************************/ - -static inline void vcpu_set_dbr(struct kvm_vcpu *vcpu, u64 reg, u64 val) -{ - __ia64_set_dbr(reg, val); -} - -static inline void vcpu_set_ibr(struct kvm_vcpu *vcpu, u64 reg, u64 val) -{ - ia64_set_ibr(reg, val); -} - -static inline u64 vcpu_get_dbr(struct kvm_vcpu *vcpu, u64 reg) -{ - return ((u64)__ia64_get_dbr(reg)); -} - -static inline u64 vcpu_get_ibr(struct kvm_vcpu *vcpu, u64 reg) -{ - return ((u64)ia64_get_ibr(reg)); -} - -/************************************************************************** - VCPU performance monitor register access routines - **************************************************************************/ -static inline void vcpu_set_pmc(struct kvm_vcpu *vcpu, u64 reg, u64 val) -{ - /* NOTE: Writes to unimplemented PMC registers are discarded */ - ia64_set_pmc(reg, val); -} - -static inline void vcpu_set_pmd(struct kvm_vcpu *vcpu, u64 reg, u64 val) -{ - /* NOTE: Writes to unimplemented PMD registers are discarded */ - ia64_set_pmd(reg, val); -} - -static inline u64 vcpu_get_pmc(struct kvm_vcpu *vcpu, u64 reg) -{ - /* NOTE: Reads from unimplemented PMC registers return zero */ - return ((u64)ia64_get_pmc(reg)); -} - -static inline u64 vcpu_get_pmd(struct kvm_vcpu *vcpu, u64 reg) -{ - /* NOTE: Reads from unimplemented PMD registers return zero */ - return ((u64)ia64_get_pmd(reg)); -} - -static inline unsigned long vrrtomrr(unsigned long val) -{ - union ia64_rr rr; - rr.val = val; - rr.rid = (rr.rid << 4) | 0xe; - if (rr.ps > PAGE_SHIFT) - rr.ps = PAGE_SHIFT; - rr.ve = 1; - return rr.val; -} - - -static inline int highest_bits(int *dat) -{ - u32 bits, bitnum; - int i; - - /* loop for all 256 bits */ - for (i = 7; i >= 0 ; i--) { - bits = dat[i]; - if (bits) { - bitnum = fls(bits); - return i * 32 + bitnum - 1; - } - } - return NULL_VECTOR; -} - -/* - * The pending irq is higher than the inservice one. - * - */ -static inline int is_higher_irq(int pending, int inservice) -{ - return ((pending > inservice) - || ((pending != NULL_VECTOR) - && (inservice == NULL_VECTOR))); -} - -static inline int is_higher_class(int pending, int mic) -{ - return ((pending >> 4) > mic); -} - -/* - * Return 0-255 for pending irq. - * NULL_VECTOR: when no pending. - */ -static inline int highest_pending_irq(struct kvm_vcpu *vcpu) -{ - if (VCPU(vcpu, irr[0]) & (1UL< -#include -#include - -#include "vcpu.h" - -MODULE_AUTHOR("Intel"); -MODULE_LICENSE("GPL"); - -extern char kvm_ia64_ivt; -extern char kvm_asm_mov_from_ar; -extern char kvm_asm_mov_from_ar_sn2; -extern fpswa_interface_t *vmm_fpswa_interface; - -long vmm_sanity = 1; - -struct kvm_vmm_info vmm_info = { - .module = THIS_MODULE, - .vmm_entry = vmm_entry, - .tramp_entry = vmm_trampoline, - .vmm_ivt = (unsigned long)&kvm_ia64_ivt, - .patch_mov_ar = (unsigned long)&kvm_asm_mov_from_ar, - .patch_mov_ar_sn2 = (unsigned long)&kvm_asm_mov_from_ar_sn2, -}; - -static int __init kvm_vmm_init(void) -{ - - vmm_fpswa_interface = fpswa_interface; - - /*Register vmm data to kvm side*/ - return kvm_init(&vmm_info, 1024, 0, THIS_MODULE); -} - -static void __exit kvm_vmm_exit(void) -{ - kvm_exit(); - return ; -} - -void vmm_spin_lock(vmm_spinlock_t *lock) -{ - _vmm_raw_spin_lock(lock); -} - -void vmm_spin_unlock(vmm_spinlock_t *lock) -{ - _vmm_raw_spin_unlock(lock); -} - -static void vcpu_debug_exit(struct kvm_vcpu *vcpu) -{ - struct exit_ctl_data *p = &vcpu->arch.exit_data; - long psr; - - local_irq_save(psr); - p->exit_reason = EXIT_REASON_DEBUG; - vmm_transition(vcpu); - local_irq_restore(psr); -} - -asmlinkage int printk(const char *fmt, ...) -{ - struct kvm_vcpu *vcpu = current_vcpu; - va_list args; - int r; - - memset(vcpu->arch.log_buf, 0, VMM_LOG_LEN); - va_start(args, fmt); - r = vsnprintf(vcpu->arch.log_buf, VMM_LOG_LEN, fmt, args); - va_end(args); - vcpu_debug_exit(vcpu); - return r; -} - -module_init(kvm_vmm_init) -module_exit(kvm_vmm_exit) diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S deleted file mode 100644 index 397e34a63e18..000000000000 --- a/arch/ia64/kvm/vmm_ivt.S +++ /dev/null @@ -1,1392 +0,0 @@ -/* - * arch/ia64/kvm/vmm_ivt.S - * - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co - * Stephane Eranian - * David Mosberger - * Copyright (C) 2000, 2002-2003 Intel Co - * Asit Mallick - * Suresh Siddha - * Kenneth Chen - * Fenghua Yu - * - * - * 00/08/23 Asit Mallick TLB handling - * for SMP - * 00/12/20 David Mosberger-Tang DTLB/ITLB - * handler now uses virtual PT. - * - * 07/6/20 Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) - * Supporting Intel virtualization architecture - * - */ - -/* - * This file defines the interruption vector table used by the CPU. - * It does not include one entry per possible cause of interruption. - * - * The first 20 entries of the table contain 64 bundles each while the - * remaining 48 entries contain only 16 bundles each. - * - * The 64 bundles are used to allow inlining the whole handler for - * critical - * interruptions like TLB misses. - * - * For each entry, the comment is as follows: - * - * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss - * (12,51) - * entry offset ----/ / / / - * / - * entry number ---------/ / / - * / - * size of the entry -------------/ / - * / - * vector name -------------------------------------/ - * / - * interruptions triggering this vector - * ----------------------/ - * - * The table is 32KB in size and must be aligned on 32KB - * boundary. - * (The CPU ignores the 15 lower bits of the address) - * - * Table is based upon EAS2.6 (Oct 1999) - */ - - -#include -#include -#include - -#include "asm-offsets.h" -#include "vcpu.h" -#include "kvm_minstate.h" -#include "vti.h" - -#if 0 -# define PSR_DEFAULT_BITS psr.ac -#else -# define PSR_DEFAULT_BITS 0 -#endif - -#define KVM_FAULT(n) \ - kvm_fault_##n:; \ - mov r19=n;; \ - br.sptk.many kvm_vmm_panic; \ - ;; \ - -#define KVM_REFLECT(n) \ - mov r31=pr; \ - mov r19=n; /* prepare to save predicates */ \ - mov r29=cr.ipsr; \ - ;; \ - tbit.z p6,p7=r29,IA64_PSR_VM_BIT; \ -(p7) br.sptk.many kvm_dispatch_reflection; \ - br.sptk.many kvm_vmm_panic; \ - -GLOBAL_ENTRY(kvm_vmm_panic) - KVM_SAVE_MIN_WITH_COVER_R19 - alloc r14=ar.pfs,0,0,1,0 - mov out0=r15 - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr. - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - KVM_SAVE_REST - mov rp=r14 - ;; - br.call.sptk.many b6=vmm_panic_handler; -END(kvm_vmm_panic) - - .section .text..ivt,"ax" - - .align 32768 // align on 32KB boundary - .global kvm_ia64_ivt -kvm_ia64_ivt: -/////////////////////////////////////////////////////////////// -// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47) -ENTRY(kvm_vhpt_miss) - KVM_FAULT(0) -END(kvm_vhpt_miss) - - .org kvm_ia64_ivt+0x400 -//////////////////////////////////////////////////////////////// -// 0x0400 Entry 1 (size 64 bundles) ITLB (21) -ENTRY(kvm_itlb_miss) - mov r31 = pr - mov r29=cr.ipsr; - ;; - tbit.z p6,p7=r29,IA64_PSR_VM_BIT; -(p6) br.sptk kvm_alt_itlb_miss - mov r19 = 1 - br.sptk kvm_itlb_miss_dispatch - KVM_FAULT(1); -END(kvm_itlb_miss) - - .org kvm_ia64_ivt+0x0800 -////////////////////////////////////////////////////////////////// -// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) -ENTRY(kvm_dtlb_miss) - mov r31 = pr - mov r29=cr.ipsr; - ;; - tbit.z p6,p7=r29,IA64_PSR_VM_BIT; -(p6) br.sptk kvm_alt_dtlb_miss - br.sptk kvm_dtlb_miss_dispatch -END(kvm_dtlb_miss) - - .org kvm_ia64_ivt+0x0c00 -//////////////////////////////////////////////////////////////////// -// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) -ENTRY(kvm_alt_itlb_miss) - mov r16=cr.ifa // get address that caused the TLB miss - ;; - movl r17=PAGE_KERNEL - mov r24=cr.ipsr - movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) - ;; - and r19=r19,r16 // clear ed, reserved bits, and PTE control bits - ;; - or r19=r17,r19 // insert PTE control bits into r19 - ;; - movl r20=IA64_GRANULE_SHIFT<<2 - ;; - mov cr.itir=r20 - ;; - itc.i r19 // insert the TLB entry - mov pr=r31,-1 - rfi -END(kvm_alt_itlb_miss) - - .org kvm_ia64_ivt+0x1000 -///////////////////////////////////////////////////////////////////// -// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) -ENTRY(kvm_alt_dtlb_miss) - mov r16=cr.ifa // get address that caused the TLB miss - ;; - movl r17=PAGE_KERNEL - movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) - mov r24=cr.ipsr - ;; - and r19=r19,r16 // clear ed, reserved bits, and PTE control bits - ;; - or r19=r19,r17 // insert PTE control bits into r19 - ;; - movl r20=IA64_GRANULE_SHIFT<<2 - ;; - mov cr.itir=r20 - ;; - itc.d r19 // insert the TLB entry - mov pr=r31,-1 - rfi -END(kvm_alt_dtlb_miss) - - .org kvm_ia64_ivt+0x1400 -////////////////////////////////////////////////////////////////////// -// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) -ENTRY(kvm_nested_dtlb_miss) - KVM_FAULT(5) -END(kvm_nested_dtlb_miss) - - .org kvm_ia64_ivt+0x1800 -///////////////////////////////////////////////////////////////////// -// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) -ENTRY(kvm_ikey_miss) - KVM_REFLECT(6) -END(kvm_ikey_miss) - - .org kvm_ia64_ivt+0x1c00 -///////////////////////////////////////////////////////////////////// -// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) -ENTRY(kvm_dkey_miss) - KVM_REFLECT(7) -END(kvm_dkey_miss) - - .org kvm_ia64_ivt+0x2000 -//////////////////////////////////////////////////////////////////// -// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) -ENTRY(kvm_dirty_bit) - KVM_REFLECT(8) -END(kvm_dirty_bit) - - .org kvm_ia64_ivt+0x2400 -//////////////////////////////////////////////////////////////////// -// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) -ENTRY(kvm_iaccess_bit) - KVM_REFLECT(9) -END(kvm_iaccess_bit) - - .org kvm_ia64_ivt+0x2800 -/////////////////////////////////////////////////////////////////// -// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) -ENTRY(kvm_daccess_bit) - KVM_REFLECT(10) -END(kvm_daccess_bit) - - .org kvm_ia64_ivt+0x2c00 -///////////////////////////////////////////////////////////////// -// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) -ENTRY(kvm_break_fault) - mov r31=pr - mov r19=11 - mov r29=cr.ipsr - ;; - KVM_SAVE_MIN_WITH_COVER_R19 - ;; - alloc r14=ar.pfs,0,0,4,0 //(must be first in insn group!) - mov out0=cr.ifa - mov out2=cr.isr // FIXME: pity to make this slow access twice - mov out3=cr.iim // FIXME: pity to make this slow access twice - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15)ssm psr.i // restore psr.i - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - KVM_SAVE_REST - mov rp=r14 - ;; - adds out1=16,sp - br.call.sptk.many b6=kvm_ia64_handle_break - ;; -END(kvm_break_fault) - - .org kvm_ia64_ivt+0x3000 -///////////////////////////////////////////////////////////////// -// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) -ENTRY(kvm_interrupt) - mov r31=pr // prepare to save predicates - mov r19=12 - mov r29=cr.ipsr - ;; - tbit.z p6,p7=r29,IA64_PSR_VM_BIT - tbit.z p0,p15=r29,IA64_PSR_I_BIT - ;; -(p7) br.sptk kvm_dispatch_interrupt - ;; - mov r27=ar.rsc /* M */ - mov r20=r1 /* A */ - mov r25=ar.unat /* M */ - mov r26=ar.pfs /* I */ - mov r28=cr.iip /* M */ - cover /* B (or nothing) */ - ;; - mov r1=sp - ;; - invala /* M */ - mov r30=cr.ifs - ;; - addl r1=-VMM_PT_REGS_SIZE,r1 - ;; - adds r17=2*L1_CACHE_BYTES,r1 /* really: biggest cache-line size */ - adds r16=PT(CR_IPSR),r1 - ;; - lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES - st8 [r16]=r29 /* save cr.ipsr */ - ;; - lfetch.fault.excl.nt1 [r17] - mov r29=b0 - ;; - adds r16=PT(R8),r1 /* initialize first base pointer */ - adds r17=PT(R9),r1 /* initialize second base pointer */ - mov r18=r0 /* make sure r18 isn't NaT */ - ;; -.mem.offset 0,0; st8.spill [r16]=r8,16 -.mem.offset 8,0; st8.spill [r17]=r9,16 - ;; -.mem.offset 0,0; st8.spill [r16]=r10,24 -.mem.offset 8,0; st8.spill [r17]=r11,24 - ;; - st8 [r16]=r28,16 /* save cr.iip */ - st8 [r17]=r30,16 /* save cr.ifs */ - mov r8=ar.fpsr /* M */ - mov r9=ar.csd - mov r10=ar.ssd - movl r11=FPSR_DEFAULT /* L-unit */ - ;; - st8 [r16]=r25,16 /* save ar.unat */ - st8 [r17]=r26,16 /* save ar.pfs */ - shl r18=r18,16 /* compute ar.rsc to be used for "loadrs" */ - ;; - st8 [r16]=r27,16 /* save ar.rsc */ - adds r17=16,r17 /* skip over ar_rnat field */ - ;; - st8 [r17]=r31,16 /* save predicates */ - adds r16=16,r16 /* skip over ar_bspstore field */ - ;; - st8 [r16]=r29,16 /* save b0 */ - st8 [r17]=r18,16 /* save ar.rsc value for "loadrs" */ - ;; -.mem.offset 0,0; st8.spill [r16]=r20,16 /* save original r1 */ -.mem.offset 8,0; st8.spill [r17]=r12,16 - adds r12=-16,r1 - /* switch to kernel memory stack (with 16 bytes of scratch) */ - ;; -.mem.offset 0,0; st8.spill [r16]=r13,16 -.mem.offset 8,0; st8.spill [r17]=r8,16 /* save ar.fpsr */ - ;; -.mem.offset 0,0; st8.spill [r16]=r15,16 -.mem.offset 8,0; st8.spill [r17]=r14,16 - dep r14=-1,r0,60,4 - ;; -.mem.offset 0,0; st8.spill [r16]=r2,16 -.mem.offset 8,0; st8.spill [r17]=r3,16 - adds r2=VMM_PT_REGS_R16_OFFSET,r1 - adds r14 = VMM_VCPU_GP_OFFSET,r13 - ;; - mov r8=ar.ccv - ld8 r14 = [r14] - ;; - mov r1=r14 /* establish kernel global pointer */ - ;; \ - bsw.1 - ;; - alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group - mov out0=r13 - ;; - ssm psr.ic - ;; - srlz.i - ;; - //(p15) ssm psr.i - adds r3=8,r2 // set up second base pointer for SAVE_REST - srlz.i // ensure everybody knows psr.ic is back on - ;; -.mem.offset 0,0; st8.spill [r2]=r16,16 -.mem.offset 8,0; st8.spill [r3]=r17,16 - ;; -.mem.offset 0,0; st8.spill [r2]=r18,16 -.mem.offset 8,0; st8.spill [r3]=r19,16 - ;; -.mem.offset 0,0; st8.spill [r2]=r20,16 -.mem.offset 8,0; st8.spill [r3]=r21,16 - mov r18=b6 - ;; -.mem.offset 0,0; st8.spill [r2]=r22,16 -.mem.offset 8,0; st8.spill [r3]=r23,16 - mov r19=b7 - ;; -.mem.offset 0,0; st8.spill [r2]=r24,16 -.mem.offset 8,0; st8.spill [r3]=r25,16 - ;; -.mem.offset 0,0; st8.spill [r2]=r26,16 -.mem.offset 8,0; st8.spill [r3]=r27,16 - ;; -.mem.offset 0,0; st8.spill [r2]=r28,16 -.mem.offset 8,0; st8.spill [r3]=r29,16 - ;; -.mem.offset 0,0; st8.spill [r2]=r30,16 -.mem.offset 8,0; st8.spill [r3]=r31,32 - ;; - mov ar.fpsr=r11 /* M-unit */ - st8 [r2]=r8,8 /* ar.ccv */ - adds r24=PT(B6)-PT(F7),r3 - ;; - stf.spill [r2]=f6,32 - stf.spill [r3]=f7,32 - ;; - stf.spill [r2]=f8,32 - stf.spill [r3]=f9,32 - ;; - stf.spill [r2]=f10 - stf.spill [r3]=f11 - adds r25=PT(B7)-PT(F11),r3 - ;; - st8 [r24]=r18,16 /* b6 */ - st8 [r25]=r19,16 /* b7 */ - ;; - st8 [r24]=r9 /* ar.csd */ - st8 [r25]=r10 /* ar.ssd */ - ;; - srlz.d // make sure we see the effect of cr.ivr - addl r14=@gprel(ia64_leave_nested),gp - ;; - mov rp=r14 - br.call.sptk.many b6=kvm_ia64_handle_irq - ;; -END(kvm_interrupt) - - .global kvm_dispatch_vexirq - .org kvm_ia64_ivt+0x3400 -////////////////////////////////////////////////////////////////////// -// 0x3400 Entry 13 (size 64 bundles) Reserved -ENTRY(kvm_virtual_exirq) - mov r31=pr - mov r19=13 - mov r30 =r0 - ;; -kvm_dispatch_vexirq: - cmp.eq p6,p0 = 1,r30 - ;; -(p6) add r29 = VMM_VCPU_SAVED_GP_OFFSET,r21 - ;; -(p6) ld8 r1 = [r29] - ;; - KVM_SAVE_MIN_WITH_COVER_R19 - alloc r14=ar.pfs,0,0,1,0 - mov out0=r13 - - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr.i - adds r3=8,r2 // set up second base pointer - ;; - KVM_SAVE_REST - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - mov rp=r14 - br.call.sptk.many b6=kvm_vexirq -END(kvm_virtual_exirq) - - .org kvm_ia64_ivt+0x3800 -///////////////////////////////////////////////////////////////////// -// 0x3800 Entry 14 (size 64 bundles) Reserved - KVM_FAULT(14) - // this code segment is from 2.6.16.13 - - .org kvm_ia64_ivt+0x3c00 -/////////////////////////////////////////////////////////////////////// -// 0x3c00 Entry 15 (size 64 bundles) Reserved - KVM_FAULT(15) - - .org kvm_ia64_ivt+0x4000 -/////////////////////////////////////////////////////////////////////// -// 0x4000 Entry 16 (size 64 bundles) Reserved - KVM_FAULT(16) - - .org kvm_ia64_ivt+0x4400 -////////////////////////////////////////////////////////////////////// -// 0x4400 Entry 17 (size 64 bundles) Reserved - KVM_FAULT(17) - - .org kvm_ia64_ivt+0x4800 -////////////////////////////////////////////////////////////////////// -// 0x4800 Entry 18 (size 64 bundles) Reserved - KVM_FAULT(18) - - .org kvm_ia64_ivt+0x4c00 -////////////////////////////////////////////////////////////////////// -// 0x4c00 Entry 19 (size 64 bundles) Reserved - KVM_FAULT(19) - - .org kvm_ia64_ivt+0x5000 -////////////////////////////////////////////////////////////////////// -// 0x5000 Entry 20 (size 16 bundles) Page Not Present -ENTRY(kvm_page_not_present) - KVM_REFLECT(20) -END(kvm_page_not_present) - - .org kvm_ia64_ivt+0x5100 -/////////////////////////////////////////////////////////////////////// -// 0x5100 Entry 21 (size 16 bundles) Key Permission vector -ENTRY(kvm_key_permission) - KVM_REFLECT(21) -END(kvm_key_permission) - - .org kvm_ia64_ivt+0x5200 -////////////////////////////////////////////////////////////////////// -// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) -ENTRY(kvm_iaccess_rights) - KVM_REFLECT(22) -END(kvm_iaccess_rights) - - .org kvm_ia64_ivt+0x5300 -////////////////////////////////////////////////////////////////////// -// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) -ENTRY(kvm_daccess_rights) - KVM_REFLECT(23) -END(kvm_daccess_rights) - - .org kvm_ia64_ivt+0x5400 -///////////////////////////////////////////////////////////////////// -// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) -ENTRY(kvm_general_exception) - KVM_REFLECT(24) - KVM_FAULT(24) -END(kvm_general_exception) - - .org kvm_ia64_ivt+0x5500 -////////////////////////////////////////////////////////////////////// -// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) -ENTRY(kvm_disabled_fp_reg) - KVM_REFLECT(25) -END(kvm_disabled_fp_reg) - - .org kvm_ia64_ivt+0x5600 -//////////////////////////////////////////////////////////////////// -// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) -ENTRY(kvm_nat_consumption) - KVM_REFLECT(26) -END(kvm_nat_consumption) - - .org kvm_ia64_ivt+0x5700 -///////////////////////////////////////////////////////////////////// -// 0x5700 Entry 27 (size 16 bundles) Speculation (40) -ENTRY(kvm_speculation_vector) - KVM_REFLECT(27) -END(kvm_speculation_vector) - - .org kvm_ia64_ivt+0x5800 -///////////////////////////////////////////////////////////////////// -// 0x5800 Entry 28 (size 16 bundles) Reserved - KVM_FAULT(28) - - .org kvm_ia64_ivt+0x5900 -/////////////////////////////////////////////////////////////////// -// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) -ENTRY(kvm_debug_vector) - KVM_FAULT(29) -END(kvm_debug_vector) - - .org kvm_ia64_ivt+0x5a00 -/////////////////////////////////////////////////////////////// -// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) -ENTRY(kvm_unaligned_access) - KVM_REFLECT(30) -END(kvm_unaligned_access) - - .org kvm_ia64_ivt+0x5b00 -////////////////////////////////////////////////////////////////////// -// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) -ENTRY(kvm_unsupported_data_reference) - KVM_REFLECT(31) -END(kvm_unsupported_data_reference) - - .org kvm_ia64_ivt+0x5c00 -//////////////////////////////////////////////////////////////////// -// 0x5c00 Entry 32 (size 16 bundles) Floating Point FAULT (65) -ENTRY(kvm_floating_point_fault) - KVM_REFLECT(32) -END(kvm_floating_point_fault) - - .org kvm_ia64_ivt+0x5d00 -///////////////////////////////////////////////////////////////////// -// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) -ENTRY(kvm_floating_point_trap) - KVM_REFLECT(33) -END(kvm_floating_point_trap) - - .org kvm_ia64_ivt+0x5e00 -////////////////////////////////////////////////////////////////////// -// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) -ENTRY(kvm_lower_privilege_trap) - KVM_REFLECT(34) -END(kvm_lower_privilege_trap) - - .org kvm_ia64_ivt+0x5f00 -////////////////////////////////////////////////////////////////////// -// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) -ENTRY(kvm_taken_branch_trap) - KVM_REFLECT(35) -END(kvm_taken_branch_trap) - - .org kvm_ia64_ivt+0x6000 -//////////////////////////////////////////////////////////////////// -// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) -ENTRY(kvm_single_step_trap) - KVM_REFLECT(36) -END(kvm_single_step_trap) - .global kvm_virtualization_fault_back - .org kvm_ia64_ivt+0x6100 -///////////////////////////////////////////////////////////////////// -// 0x6100 Entry 37 (size 16 bundles) Virtualization Fault -ENTRY(kvm_virtualization_fault) - mov r31=pr - adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21 - ;; - st8 [r16] = r1 - adds r17 = VMM_VCPU_GP_OFFSET, r21 - ;; - ld8 r1 = [r17] - cmp.eq p6,p0=EVENT_MOV_FROM_AR,r24 - cmp.eq p7,p0=EVENT_MOV_FROM_RR,r24 - cmp.eq p8,p0=EVENT_MOV_TO_RR,r24 - cmp.eq p9,p0=EVENT_RSM,r24 - cmp.eq p10,p0=EVENT_SSM,r24 - cmp.eq p11,p0=EVENT_MOV_TO_PSR,r24 - cmp.eq p12,p0=EVENT_THASH,r24 -(p6) br.dptk.many kvm_asm_mov_from_ar -(p7) br.dptk.many kvm_asm_mov_from_rr -(p8) br.dptk.many kvm_asm_mov_to_rr -(p9) br.dptk.many kvm_asm_rsm -(p10) br.dptk.many kvm_asm_ssm -(p11) br.dptk.many kvm_asm_mov_to_psr -(p12) br.dptk.many kvm_asm_thash - ;; -kvm_virtualization_fault_back: - adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21 - ;; - ld8 r1 = [r16] - ;; - mov r19=37 - adds r16 = VMM_VCPU_CAUSE_OFFSET,r21 - adds r17 = VMM_VCPU_OPCODE_OFFSET,r21 - ;; - st8 [r16] = r24 - st8 [r17] = r25 - ;; - cmp.ne p6,p0=EVENT_RFI, r24 -(p6) br.sptk kvm_dispatch_virtualization_fault - ;; - adds r18=VMM_VPD_BASE_OFFSET,r21 - ;; - ld8 r18=[r18] - ;; - adds r18=VMM_VPD_VIFS_OFFSET,r18 - ;; - ld8 r18=[r18] - ;; - tbit.z p6,p0=r18,63 -(p6) br.sptk kvm_dispatch_virtualization_fault - ;; -//if vifs.v=1 desert current register frame - alloc r18=ar.pfs,0,0,0,0 - br.sptk kvm_dispatch_virtualization_fault -END(kvm_virtualization_fault) - - .org kvm_ia64_ivt+0x6200 -////////////////////////////////////////////////////////////// -// 0x6200 Entry 38 (size 16 bundles) Reserved - KVM_FAULT(38) - - .org kvm_ia64_ivt+0x6300 -///////////////////////////////////////////////////////////////// -// 0x6300 Entry 39 (size 16 bundles) Reserved - KVM_FAULT(39) - - .org kvm_ia64_ivt+0x6400 -///////////////////////////////////////////////////////////////// -// 0x6400 Entry 40 (size 16 bundles) Reserved - KVM_FAULT(40) - - .org kvm_ia64_ivt+0x6500 -////////////////////////////////////////////////////////////////// -// 0x6500 Entry 41 (size 16 bundles) Reserved - KVM_FAULT(41) - - .org kvm_ia64_ivt+0x6600 -////////////////////////////////////////////////////////////////// -// 0x6600 Entry 42 (size 16 bundles) Reserved - KVM_FAULT(42) - - .org kvm_ia64_ivt+0x6700 -////////////////////////////////////////////////////////////////// -// 0x6700 Entry 43 (size 16 bundles) Reserved - KVM_FAULT(43) - - .org kvm_ia64_ivt+0x6800 -////////////////////////////////////////////////////////////////// -// 0x6800 Entry 44 (size 16 bundles) Reserved - KVM_FAULT(44) - - .org kvm_ia64_ivt+0x6900 -/////////////////////////////////////////////////////////////////// -// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception -//(17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) -ENTRY(kvm_ia32_exception) - KVM_FAULT(45) -END(kvm_ia32_exception) - - .org kvm_ia64_ivt+0x6a00 -//////////////////////////////////////////////////////////////////// -// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) -ENTRY(kvm_ia32_intercept) - KVM_FAULT(47) -END(kvm_ia32_intercept) - - .org kvm_ia64_ivt+0x6c00 -///////////////////////////////////////////////////////////////////// -// 0x6c00 Entry 48 (size 16 bundles) Reserved - KVM_FAULT(48) - - .org kvm_ia64_ivt+0x6d00 -////////////////////////////////////////////////////////////////////// -// 0x6d00 Entry 49 (size 16 bundles) Reserved - KVM_FAULT(49) - - .org kvm_ia64_ivt+0x6e00 -////////////////////////////////////////////////////////////////////// -// 0x6e00 Entry 50 (size 16 bundles) Reserved - KVM_FAULT(50) - - .org kvm_ia64_ivt+0x6f00 -///////////////////////////////////////////////////////////////////// -// 0x6f00 Entry 51 (size 16 bundles) Reserved - KVM_FAULT(52) - - .org kvm_ia64_ivt+0x7100 -//////////////////////////////////////////////////////////////////// -// 0x7100 Entry 53 (size 16 bundles) Reserved - KVM_FAULT(53) - - .org kvm_ia64_ivt+0x7200 -///////////////////////////////////////////////////////////////////// -// 0x7200 Entry 54 (size 16 bundles) Reserved - KVM_FAULT(54) - - .org kvm_ia64_ivt+0x7300 -//////////////////////////////////////////////////////////////////// -// 0x7300 Entry 55 (size 16 bundles) Reserved - KVM_FAULT(55) - - .org kvm_ia64_ivt+0x7400 -//////////////////////////////////////////////////////////////////// -// 0x7400 Entry 56 (size 16 bundles) Reserved - KVM_FAULT(56) - - .org kvm_ia64_ivt+0x7500 -///////////////////////////////////////////////////////////////////// -// 0x7500 Entry 57 (size 16 bundles) Reserved - KVM_FAULT(57) - - .org kvm_ia64_ivt+0x7600 -///////////////////////////////////////////////////////////////////// -// 0x7600 Entry 58 (size 16 bundles) Reserved - KVM_FAULT(58) - - .org kvm_ia64_ivt+0x7700 -//////////////////////////////////////////////////////////////////// -// 0x7700 Entry 59 (size 16 bundles) Reserved - KVM_FAULT(59) - - .org kvm_ia64_ivt+0x7800 -//////////////////////////////////////////////////////////////////// -// 0x7800 Entry 60 (size 16 bundles) Reserved - KVM_FAULT(60) - - .org kvm_ia64_ivt+0x7900 -///////////////////////////////////////////////////////////////////// -// 0x7900 Entry 61 (size 16 bundles) Reserved - KVM_FAULT(61) - - .org kvm_ia64_ivt+0x7a00 -///////////////////////////////////////////////////////////////////// -// 0x7a00 Entry 62 (size 16 bundles) Reserved - KVM_FAULT(62) - - .org kvm_ia64_ivt+0x7b00 -///////////////////////////////////////////////////////////////////// -// 0x7b00 Entry 63 (size 16 bundles) Reserved - KVM_FAULT(63) - - .org kvm_ia64_ivt+0x7c00 -//////////////////////////////////////////////////////////////////// -// 0x7c00 Entry 64 (size 16 bundles) Reserved - KVM_FAULT(64) - - .org kvm_ia64_ivt+0x7d00 -///////////////////////////////////////////////////////////////////// -// 0x7d00 Entry 65 (size 16 bundles) Reserved - KVM_FAULT(65) - - .org kvm_ia64_ivt+0x7e00 -///////////////////////////////////////////////////////////////////// -// 0x7e00 Entry 66 (size 16 bundles) Reserved - KVM_FAULT(66) - - .org kvm_ia64_ivt+0x7f00 -//////////////////////////////////////////////////////////////////// -// 0x7f00 Entry 67 (size 16 bundles) Reserved - KVM_FAULT(67) - - .org kvm_ia64_ivt+0x8000 -// There is no particular reason for this code to be here, other than that -// there happens to be space here that would go unused otherwise. If this -// fault ever gets "unreserved", simply moved the following code to a more -// suitable spot... - - -ENTRY(kvm_dtlb_miss_dispatch) - mov r19 = 2 - KVM_SAVE_MIN_WITH_COVER_R19 - alloc r14=ar.pfs,0,0,3,0 - mov out0=cr.ifa - mov out1=r15 - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr.i - addl r14=@gprel(ia64_leave_hypervisor_prepare),gp - ;; - KVM_SAVE_REST - KVM_SAVE_EXTRA - mov rp=r14 - ;; - adds out2=16,r12 - br.call.sptk.many b6=kvm_page_fault -END(kvm_dtlb_miss_dispatch) - -ENTRY(kvm_itlb_miss_dispatch) - - KVM_SAVE_MIN_WITH_COVER_R19 - alloc r14=ar.pfs,0,0,3,0 - mov out0=cr.ifa - mov out1=r15 - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr.i - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - KVM_SAVE_REST - mov rp=r14 - ;; - adds out2=16,r12 - br.call.sptk.many b6=kvm_page_fault -END(kvm_itlb_miss_dispatch) - -ENTRY(kvm_dispatch_reflection) -/* - * Input: - * psr.ic: off - * r19: intr type (offset into ivt, see ia64_int.h) - * r31: contains saved predicates (pr) - */ - KVM_SAVE_MIN_WITH_COVER_R19 - alloc r14=ar.pfs,0,0,5,0 - mov out0=cr.ifa - mov out1=cr.isr - mov out2=cr.iim - mov out3=r15 - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr.i - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - KVM_SAVE_REST - mov rp=r14 - ;; - adds out4=16,r12 - br.call.sptk.many b6=reflect_interruption -END(kvm_dispatch_reflection) - -ENTRY(kvm_dispatch_virtualization_fault) - adds r16 = VMM_VCPU_CAUSE_OFFSET,r21 - adds r17 = VMM_VCPU_OPCODE_OFFSET,r21 - ;; - st8 [r16] = r24 - st8 [r17] = r25 - ;; - KVM_SAVE_MIN_WITH_COVER_R19 - ;; - alloc r14=ar.pfs,0,0,2,0 // (must be first in insn group!) - mov out0=r13 //vcpu - adds r3=8,r2 // set up second base pointer - ;; - ssm psr.ic - ;; - srlz.i // guarantee that interruption collection is on - ;; - (p15) ssm psr.i // restore psr.i - addl r14=@gprel(ia64_leave_hypervisor_prepare),gp - ;; - KVM_SAVE_REST - KVM_SAVE_EXTRA - mov rp=r14 - ;; - adds out1=16,sp //regs - br.call.sptk.many b6=kvm_emulate -END(kvm_dispatch_virtualization_fault) - - -ENTRY(kvm_dispatch_interrupt) - KVM_SAVE_MIN_WITH_COVER_R19 // uses r31; defines r2 and r3 - ;; - alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group - adds r3=8,r2 // set up second base pointer for SAVE_REST - ;; - ssm psr.ic - ;; - srlz.i - ;; - (p15) ssm psr.i - addl r14=@gprel(ia64_leave_hypervisor),gp - ;; - KVM_SAVE_REST - mov rp=r14 - ;; - mov out0=r13 // pass pointer to pt_regs as second arg - br.call.sptk.many b6=kvm_ia64_handle_irq -END(kvm_dispatch_interrupt) - -GLOBAL_ENTRY(ia64_leave_nested) - rsm psr.i - ;; - adds r21=PT(PR)+16,r12 - ;; - lfetch [r21],PT(CR_IPSR)-PT(PR) - adds r2=PT(B6)+16,r12 - adds r3=PT(R16)+16,r12 - ;; - lfetch [r21] - ld8 r28=[r2],8 // load b6 - adds r29=PT(R24)+16,r12 - - ld8.fill r16=[r3] - adds r3=PT(AR_CSD)-PT(R16),r3 - adds r30=PT(AR_CCV)+16,r12 - ;; - ld8.fill r24=[r29] - ld8 r15=[r30] // load ar.ccv - ;; - ld8 r29=[r2],16 // load b7 - ld8 r30=[r3],16 // load ar.csd - ;; - ld8 r31=[r2],16 // load ar.ssd - ld8.fill r8=[r3],16 - ;; - ld8.fill r9=[r2],16 - ld8.fill r10=[r3],PT(R17)-PT(R10) - ;; - ld8.fill r11=[r2],PT(R18)-PT(R11) - ld8.fill r17=[r3],16 - ;; - ld8.fill r18=[r2],16 - ld8.fill r19=[r3],16 - ;; - ld8.fill r20=[r2],16 - ld8.fill r21=[r3],16 - mov ar.csd=r30 - mov ar.ssd=r31 - ;; - rsm psr.i | psr.ic - // initiate turning off of interrupt and interruption collection - invala // invalidate ALAT - ;; - srlz.i - ;; - ld8.fill r22=[r2],24 - ld8.fill r23=[r3],24 - mov b6=r28 - ;; - ld8.fill r25=[r2],16 - ld8.fill r26=[r3],16 - mov b7=r29 - ;; - ld8.fill r27=[r2],16 - ld8.fill r28=[r3],16 - ;; - ld8.fill r29=[r2],16 - ld8.fill r30=[r3],24 - ;; - ld8.fill r31=[r2],PT(F9)-PT(R31) - adds r3=PT(F10)-PT(F6),r3 - ;; - ldf.fill f9=[r2],PT(F6)-PT(F9) - ldf.fill f10=[r3],PT(F8)-PT(F10) - ;; - ldf.fill f6=[r2],PT(F7)-PT(F6) - ;; - ldf.fill f7=[r2],PT(F11)-PT(F7) - ldf.fill f8=[r3],32 - ;; - srlz.i // ensure interruption collection is off - mov ar.ccv=r15 - ;; - bsw.0 // switch back to bank 0 (no stop bit required beforehand...) - ;; - ldf.fill f11=[r2] -// mov r18=r13 -// mov r21=r13 - adds r16=PT(CR_IPSR)+16,r12 - adds r17=PT(CR_IIP)+16,r12 - ;; - ld8 r29=[r16],16 // load cr.ipsr - ld8 r28=[r17],16 // load cr.iip - ;; - ld8 r30=[r16],16 // load cr.ifs - ld8 r25=[r17],16 // load ar.unat - ;; - ld8 r26=[r16],16 // load ar.pfs - ld8 r27=[r17],16 // load ar.rsc - cmp.eq p9,p0=r0,r0 - // set p9 to indicate that we should restore cr.ifs - ;; - ld8 r24=[r16],16 // load ar.rnat (may be garbage) - ld8 r23=[r17],16// load ar.bspstore (may be garbage) - ;; - ld8 r31=[r16],16 // load predicates - ld8 r22=[r17],16 // load b0 - ;; - ld8 r19=[r16],16 // load ar.rsc value for "loadrs" - ld8.fill r1=[r17],16 // load r1 - ;; - ld8.fill r12=[r16],16 - ld8.fill r13=[r17],16 - ;; - ld8 r20=[r16],16 // ar.fpsr - ld8.fill r15=[r17],16 - ;; - ld8.fill r14=[r16],16 - ld8.fill r2=[r17] - ;; - ld8.fill r3=[r16] - ;; - mov r16=ar.bsp // get existing backing store pointer - ;; - mov b0=r22 - mov ar.pfs=r26 - mov cr.ifs=r30 - mov cr.ipsr=r29 - mov ar.fpsr=r20 - mov cr.iip=r28 - ;; - mov ar.rsc=r27 - mov ar.unat=r25 - mov pr=r31,-1 - rfi -END(ia64_leave_nested) - -GLOBAL_ENTRY(ia64_leave_hypervisor_prepare) -/* - * work.need_resched etc. mustn't get changed - *by this CPU before it returns to - * user- or fsys-mode, hence we disable interrupts early on: - */ - adds r2 = PT(R4)+16,r12 - adds r3 = PT(R5)+16,r12 - adds r8 = PT(EML_UNAT)+16,r12 - ;; - ld8 r8 = [r8] - ;; - mov ar.unat=r8 - ;; - ld8.fill r4=[r2],16 //load r4 - ld8.fill r5=[r3],16 //load r5 - ;; - ld8.fill r6=[r2] //load r6 - ld8.fill r7=[r3] //load r7 - ;; -END(ia64_leave_hypervisor_prepare) -//fall through -GLOBAL_ENTRY(ia64_leave_hypervisor) - rsm psr.i - ;; - br.call.sptk.many b0=leave_hypervisor_tail - ;; - adds r20=PT(PR)+16,r12 - adds r8=PT(EML_UNAT)+16,r12 - ;; - ld8 r8=[r8] - ;; - mov ar.unat=r8 - ;; - lfetch [r20],PT(CR_IPSR)-PT(PR) - adds r2 = PT(B6)+16,r12 - adds r3 = PT(B7)+16,r12 - ;; - lfetch [r20] - ;; - ld8 r24=[r2],16 /* B6 */ - ld8 r25=[r3],16 /* B7 */ - ;; - ld8 r26=[r2],16 /* ar_csd */ - ld8 r27=[r3],16 /* ar_ssd */ - mov b6 = r24 - ;; - ld8.fill r8=[r2],16 - ld8.fill r9=[r3],16 - mov b7 = r25 - ;; - mov ar.csd = r26 - mov ar.ssd = r27 - ;; - ld8.fill r10=[r2],PT(R15)-PT(R10) - ld8.fill r11=[r3],PT(R14)-PT(R11) - ;; - ld8.fill r15=[r2],PT(R16)-PT(R15) - ld8.fill r14=[r3],PT(R17)-PT(R14) - ;; - ld8.fill r16=[r2],16 - ld8.fill r17=[r3],16 - ;; - ld8.fill r18=[r2],16 - ld8.fill r19=[r3],16 - ;; - ld8.fill r20=[r2],16 - ld8.fill r21=[r3],16 - ;; - ld8.fill r22=[r2],16 - ld8.fill r23=[r3],16 - ;; - ld8.fill r24=[r2],16 - ld8.fill r25=[r3],16 - ;; - ld8.fill r26=[r2],16 - ld8.fill r27=[r3],16 - ;; - ld8.fill r28=[r2],16 - ld8.fill r29=[r3],16 - ;; - ld8.fill r30=[r2],PT(F6)-PT(R30) - ld8.fill r31=[r3],PT(F7)-PT(R31) - ;; - rsm psr.i | psr.ic - // initiate turning off of interrupt and interruption collection - invala // invalidate ALAT - ;; - srlz.i // ensure interruption collection is off - ;; - bsw.0 - ;; - adds r16 = PT(CR_IPSR)+16,r12 - adds r17 = PT(CR_IIP)+16,r12 - mov r21=r13 // get current - ;; - ld8 r31=[r16],16 // load cr.ipsr - ld8 r30=[r17],16 // load cr.iip - ;; - ld8 r29=[r16],16 // load cr.ifs - ld8 r28=[r17],16 // load ar.unat - ;; - ld8 r27=[r16],16 // load ar.pfs - ld8 r26=[r17],16 // load ar.rsc - ;; - ld8 r25=[r16],16 // load ar.rnat - ld8 r24=[r17],16 // load ar.bspstore - ;; - ld8 r23=[r16],16 // load predicates - ld8 r22=[r17],16 // load b0 - ;; - ld8 r20=[r16],16 // load ar.rsc value for "loadrs" - ld8.fill r1=[r17],16 //load r1 - ;; - ld8.fill r12=[r16],16 //load r12 - ld8.fill r13=[r17],PT(R2)-PT(R13) //load r13 - ;; - ld8 r19=[r16],PT(R3)-PT(AR_FPSR) //load ar_fpsr - ld8.fill r2=[r17],PT(AR_CCV)-PT(R2) //load r2 - ;; - ld8.fill r3=[r16] //load r3 - ld8 r18=[r17] //load ar_ccv - ;; - mov ar.fpsr=r19 - mov ar.ccv=r18 - shr.u r18=r20,16 - ;; -kvm_rbs_switch: - mov r19=96 - -kvm_dont_preserve_current_frame: -/* - * To prevent leaking bits between the hypervisor and guest domain, - * we must clear the stacked registers in the "invalid" partition here. - * 5 registers/cycle on McKinley). - */ -# define pRecurse p6 -# define pReturn p7 -# define Nregs 14 - - alloc loc0=ar.pfs,2,Nregs-2,2,0 - shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) - sub r19=r19,r18 // r19 = (physStackedSize + 8) - dirtySize - ;; - mov ar.rsc=r20 // load ar.rsc to be used for "loadrs" - shladd in0=loc1,3,r19 - mov in1=0 - ;; - TEXT_ALIGN(32) -kvm_rse_clear_invalid: - alloc loc0=ar.pfs,2,Nregs-2,2,0 - cmp.lt pRecurse,p0=Nregs*8,in0 - // if more than Nregs regs left to clear, (re)curse - add out0=-Nregs*8,in0 - add out1=1,in1 // increment recursion count - mov loc1=0 - mov loc2=0 - ;; - mov loc3=0 - mov loc4=0 - mov loc5=0 - mov loc6=0 - mov loc7=0 -(pRecurse) br.call.dptk.few b0=kvm_rse_clear_invalid - ;; - mov loc8=0 - mov loc9=0 - cmp.ne pReturn,p0=r0,in1 - // if recursion count != 0, we need to do a br.ret - mov loc10=0 - mov loc11=0 -(pReturn) br.ret.dptk.many b0 - -# undef pRecurse -# undef pReturn - -// loadrs has already been shifted - alloc r16=ar.pfs,0,0,0,0 // drop current register frame - ;; - loadrs - ;; - mov ar.bspstore=r24 - ;; - mov ar.unat=r28 - mov ar.rnat=r25 - mov ar.rsc=r26 - ;; - mov cr.ipsr=r31 - mov cr.iip=r30 - mov cr.ifs=r29 - mov ar.pfs=r27 - adds r18=VMM_VPD_BASE_OFFSET,r21 - ;; - ld8 r18=[r18] //vpd - adds r17=VMM_VCPU_ISR_OFFSET,r21 - ;; - ld8 r17=[r17] - adds r19=VMM_VPD_VPSR_OFFSET,r18 - ;; - ld8 r19=[r19] //vpsr - mov r25=r18 - adds r16= VMM_VCPU_GP_OFFSET,r21 - ;; - ld8 r16= [r16] // Put gp in r24 - movl r24=@gprel(ia64_vmm_entry) // calculate return address - ;; - add r24=r24,r16 - ;; - br.sptk.many kvm_vps_sync_write // call the service - ;; -END(ia64_leave_hypervisor) -// fall through -GLOBAL_ENTRY(ia64_vmm_entry) -/* - * must be at bank 0 - * parameter: - * r17:cr.isr - * r18:vpd - * r19:vpsr - * r22:b0 - * r23:predicate - */ - mov r24=r22 - mov r25=r18 - tbit.nz p1,p2 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic -(p1) br.cond.sptk.few kvm_vps_resume_normal -(p2) br.cond.sptk.many kvm_vps_resume_handler - ;; -END(ia64_vmm_entry) - -/* - * extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, - * u64 arg3, u64 arg4, u64 arg5, - * u64 arg6, u64 arg7); - * - * XXX: The currently defined services use only 4 args at the max. The - * rest are not consumed. - */ -GLOBAL_ENTRY(ia64_call_vsa) - .regstk 4,4,0,0 - -rpsave = loc0 -pfssave = loc1 -psrsave = loc2 -entry = loc3 -hostret = r24 - - alloc pfssave=ar.pfs,4,4,0,0 - mov rpsave=rp - adds entry=VMM_VCPU_VSA_BASE_OFFSET, r13 - ;; - ld8 entry=[entry] -1: mov hostret=ip - mov r25=in1 // copy arguments - mov r26=in2 - mov r27=in3 - mov psrsave=psr - ;; - tbit.nz p6,p0=psrsave,14 // IA64_PSR_I - tbit.nz p7,p0=psrsave,13 // IA64_PSR_IC - ;; - add hostret=2f-1b,hostret // calculate return address - add entry=entry,in0 - ;; - rsm psr.i | psr.ic - ;; - srlz.i - mov b6=entry - br.cond.sptk b6 // call the service -2: -// Architectural sequence for enabling interrupts if necessary -(p7) ssm psr.ic - ;; -(p7) srlz.i - ;; -(p6) ssm psr.i - ;; - mov rp=rpsave - mov ar.pfs=pfssave - mov r8=r31 - ;; - srlz.d - br.ret.sptk rp - -END(ia64_call_vsa) - -#define INIT_BSPSTORE ((4<<30)-(12<<20)-0x100) - -GLOBAL_ENTRY(vmm_reset_entry) - //set up ipsr, iip, vpd.vpsr, dcr - // For IPSR: it/dt/rt=1, i/ic=1, si=1, vm/bn=1 - // For DCR: all bits 0 - bsw.0 - ;; - mov r21 =r13 - adds r14=-VMM_PT_REGS_SIZE, r12 - ;; - movl r6=0x501008826000 // IPSR dt/rt/it:1;i/ic:1, si:1, vm/bn:1 - movl r10=0x8000000000000000 - adds r16=PT(CR_IIP), r14 - adds r20=PT(R1), r14 - ;; - rsm psr.ic | psr.i - ;; - srlz.i - ;; - mov ar.rsc = 0 - ;; - flushrs - ;; - mov ar.bspstore = 0 - // clear BSPSTORE - ;; - mov cr.ipsr=r6 - mov cr.ifs=r10 - ld8 r4 = [r16] // Set init iip for first run. - ld8 r1 = [r20] - ;; - mov cr.iip=r4 - adds r16=VMM_VPD_BASE_OFFSET,r13 - ;; - ld8 r18=[r16] - ;; - adds r19=VMM_VPD_VPSR_OFFSET,r18 - ;; - ld8 r19=[r19] - mov r17=r0 - mov r22=r0 - mov r23=r0 - br.cond.sptk ia64_vmm_entry - br.ret.sptk b0 -END(vmm_reset_entry) diff --git a/arch/ia64/kvm/vti.h b/arch/ia64/kvm/vti.h deleted file mode 100644 index b214b5b0432d..000000000000 --- a/arch/ia64/kvm/vti.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * vti.h: prototype for generial vt related interface - * Copyright (c) 2004, Intel Corporation. - * - * Xuefei Xu (Anthony Xu) (anthony.xu@intel.com) - * Fred Yang (fred.yang@intel.com) - * Kun Tian (Kevin Tian) (kevin.tian@intel.com) - * - * Copyright (c) 2007, Intel Corporation. - * Zhang xiantao - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - */ -#ifndef _KVM_VT_I_H -#define _KVM_VT_I_H - -#ifndef __ASSEMBLY__ -#include - -#include - -/* define itr.i and itr.d in ia64_itr function */ -#define ITR 0x01 -#define DTR 0x02 -#define IaDTR 0x03 - -#define IA64_TR_VMM 6 /*itr6, dtr6 : maps vmm code, vmbuffer*/ -#define IA64_TR_VM_DATA 7 /*dtr7 : maps current vm data*/ - -#define RR6 (6UL<<61) -#define RR7 (7UL<<61) - - -/* config_options in pal_vp_init_env */ -#define VP_INITIALIZE 1UL -#define VP_FR_PMC 1UL<<1 -#define VP_OPCODE 1UL<<8 -#define VP_CAUSE 1UL<<9 -#define VP_FW_ACC 1UL<<63 - -/* init vp env with initializing vm_buffer */ -#define VP_INIT_ENV_INITALIZE (VP_INITIALIZE | VP_FR_PMC |\ - VP_OPCODE | VP_CAUSE | VP_FW_ACC) -/* init vp env without initializing vm_buffer */ -#define VP_INIT_ENV VP_FR_PMC | VP_OPCODE | VP_CAUSE | VP_FW_ACC - -#define PAL_VP_CREATE 265 -/* Stacked Virt. Initializes a new VPD for the operation of - * a new virtual processor in the virtual environment. - */ -#define PAL_VP_ENV_INFO 266 -/*Stacked Virt. Returns the parameters needed to enter a virtual environment.*/ -#define PAL_VP_EXIT_ENV 267 -/*Stacked Virt. Allows a logical processor to exit a virtual environment.*/ -#define PAL_VP_INIT_ENV 268 -/*Stacked Virt. Allows a logical processor to enter a virtual environment.*/ -#define PAL_VP_REGISTER 269 -/*Stacked Virt. Register a different host IVT for the virtual processor.*/ -#define PAL_VP_RESUME 270 -/* Renamed from PAL_VP_RESUME */ -#define PAL_VP_RESTORE 270 -/*Stacked Virt. Resumes virtual processor operation on the logical processor.*/ -#define PAL_VP_SUSPEND 271 -/* Renamed from PAL_VP_SUSPEND */ -#define PAL_VP_SAVE 271 -/* Stacked Virt. Suspends operation for the specified virtual processor on - * the logical processor. - */ -#define PAL_VP_TERMINATE 272 -/* Stacked Virt. Terminates operation for the specified virtual processor.*/ - -union vac { - unsigned long value; - struct { - unsigned int a_int:1; - unsigned int a_from_int_cr:1; - unsigned int a_to_int_cr:1; - unsigned int a_from_psr:1; - unsigned int a_from_cpuid:1; - unsigned int a_cover:1; - unsigned int a_bsw:1; - long reserved:57; - }; -}; - -union vdc { - unsigned long value; - struct { - unsigned int d_vmsw:1; - unsigned int d_extint:1; - unsigned int d_ibr_dbr:1; - unsigned int d_pmc:1; - unsigned int d_to_pmd:1; - unsigned int d_itm:1; - long reserved:58; - }; -}; - -struct vpd { - union vac vac; - union vdc vdc; - unsigned long virt_env_vaddr; - unsigned long reserved1[29]; - unsigned long vhpi; - unsigned long reserved2[95]; - unsigned long vgr[16]; - unsigned long vbgr[16]; - unsigned long vnat; - unsigned long vbnat; - unsigned long vcpuid[5]; - unsigned long reserved3[11]; - unsigned long vpsr; - unsigned long vpr; - unsigned long reserved4[76]; - union { - unsigned long vcr[128]; - struct { - unsigned long dcr; - unsigned long itm; - unsigned long iva; - unsigned long rsv1[5]; - unsigned long pta; - unsigned long rsv2[7]; - unsigned long ipsr; - unsigned long isr; - unsigned long rsv3; - unsigned long iip; - unsigned long ifa; - unsigned long itir; - unsigned long iipa; - unsigned long ifs; - unsigned long iim; - unsigned long iha; - unsigned long rsv4[38]; - unsigned long lid; - unsigned long ivr; - unsigned long tpr; - unsigned long eoi; - unsigned long irr[4]; - unsigned long itv; - unsigned long pmv; - unsigned long cmcv; - unsigned long rsv5[5]; - unsigned long lrr0; - unsigned long lrr1; - unsigned long rsv6[46]; - }; - }; - unsigned long reserved5[128]; - unsigned long reserved6[3456]; - unsigned long vmm_avail[128]; - unsigned long reserved7[4096]; -}; - -#define PAL_PROC_VM_BIT (1UL << 40) -#define PAL_PROC_VMSW_BIT (1UL << 54) - -static inline s64 ia64_pal_vp_env_info(u64 *buffer_size, - u64 *vp_env_info) -{ - struct ia64_pal_retval iprv; - PAL_CALL_STK(iprv, PAL_VP_ENV_INFO, 0, 0, 0); - *buffer_size = iprv.v0; - *vp_env_info = iprv.v1; - return iprv.status; -} - -static inline s64 ia64_pal_vp_exit_env(u64 iva) -{ - struct ia64_pal_retval iprv; - - PAL_CALL_STK(iprv, PAL_VP_EXIT_ENV, (u64)iva, 0, 0); - return iprv.status; -} - -static inline s64 ia64_pal_vp_init_env(u64 config_options, u64 pbase_addr, - u64 vbase_addr, u64 *vsa_base) -{ - struct ia64_pal_retval iprv; - - PAL_CALL_STK(iprv, PAL_VP_INIT_ENV, config_options, pbase_addr, - vbase_addr); - *vsa_base = iprv.v0; - - return iprv.status; -} - -static inline s64 ia64_pal_vp_restore(u64 *vpd, u64 pal_proc_vector) -{ - struct ia64_pal_retval iprv; - - PAL_CALL_STK(iprv, PAL_VP_RESTORE, (u64)vpd, pal_proc_vector, 0); - - return iprv.status; -} - -static inline s64 ia64_pal_vp_save(u64 *vpd, u64 pal_proc_vector) -{ - struct ia64_pal_retval iprv; - - PAL_CALL_STK(iprv, PAL_VP_SAVE, (u64)vpd, pal_proc_vector, 0); - - return iprv.status; -} - -#endif - -/*VPD field offset*/ -#define VPD_VAC_START_OFFSET 0 -#define VPD_VDC_START_OFFSET 8 -#define VPD_VHPI_START_OFFSET 256 -#define VPD_VGR_START_OFFSET 1024 -#define VPD_VBGR_START_OFFSET 1152 -#define VPD_VNAT_START_OFFSET 1280 -#define VPD_VBNAT_START_OFFSET 1288 -#define VPD_VCPUID_START_OFFSET 1296 -#define VPD_VPSR_START_OFFSET 1424 -#define VPD_VPR_START_OFFSET 1432 -#define VPD_VRSE_CFLE_START_OFFSET 1440 -#define VPD_VCR_START_OFFSET 2048 -#define VPD_VTPR_START_OFFSET 2576 -#define VPD_VRR_START_OFFSET 3072 -#define VPD_VMM_VAIL_START_OFFSET 31744 - -/*Virtualization faults*/ - -#define EVENT_MOV_TO_AR 1 -#define EVENT_MOV_TO_AR_IMM 2 -#define EVENT_MOV_FROM_AR 3 -#define EVENT_MOV_TO_CR 4 -#define EVENT_MOV_FROM_CR 5 -#define EVENT_MOV_TO_PSR 6 -#define EVENT_MOV_FROM_PSR 7 -#define EVENT_ITC_D 8 -#define EVENT_ITC_I 9 -#define EVENT_MOV_TO_RR 10 -#define EVENT_MOV_TO_DBR 11 -#define EVENT_MOV_TO_IBR 12 -#define EVENT_MOV_TO_PKR 13 -#define EVENT_MOV_TO_PMC 14 -#define EVENT_MOV_TO_PMD 15 -#define EVENT_ITR_D 16 -#define EVENT_ITR_I 17 -#define EVENT_MOV_FROM_RR 18 -#define EVENT_MOV_FROM_DBR 19 -#define EVENT_MOV_FROM_IBR 20 -#define EVENT_MOV_FROM_PKR 21 -#define EVENT_MOV_FROM_PMC 22 -#define EVENT_MOV_FROM_CPUID 23 -#define EVENT_SSM 24 -#define EVENT_RSM 25 -#define EVENT_PTC_L 26 -#define EVENT_PTC_G 27 -#define EVENT_PTC_GA 28 -#define EVENT_PTR_D 29 -#define EVENT_PTR_I 30 -#define EVENT_THASH 31 -#define EVENT_TTAG 32 -#define EVENT_TPA 33 -#define EVENT_TAK 34 -#define EVENT_PTC_E 35 -#define EVENT_COVER 36 -#define EVENT_RFI 37 -#define EVENT_BSW_0 38 -#define EVENT_BSW_1 39 -#define EVENT_VMSW 40 - -/**PAL virtual services offsets */ -#define PAL_VPS_RESUME_NORMAL 0x0000 -#define PAL_VPS_RESUME_HANDLER 0x0400 -#define PAL_VPS_SYNC_READ 0x0800 -#define PAL_VPS_SYNC_WRITE 0x0c00 -#define PAL_VPS_SET_PENDING_INTERRUPT 0x1000 -#define PAL_VPS_THASH 0x1400 -#define PAL_VPS_TTAG 0x1800 -#define PAL_VPS_RESTORE 0x1c00 -#define PAL_VPS_SAVE 0x2000 - -#endif/* _VT_I_H*/ diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c deleted file mode 100644 index a7869f8f49a6..000000000000 --- a/arch/ia64/kvm/vtlb.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * vtlb.c: guest virtual tlb handling module. - * Copyright (c) 2004, Intel Corporation. - * Yaozu Dong (Eddie Dong) - * Xuefei Xu (Anthony Xu) - * - * Copyright (c) 2007, Intel Corporation. - * Xuefei Xu (Anthony Xu) - * Xiantao Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include "vcpu.h" - -#include - -#include - -/* - * Check to see if the address rid:va is translated by the TLB - */ - -static int __is_tr_translated(struct thash_data *trp, u64 rid, u64 va) -{ - return ((trp->p) && (trp->rid == rid) - && ((va-trp->vadr) < PSIZE(trp->ps))); -} - -/* - * Only for GUEST TR format. - */ -static int __is_tr_overlap(struct thash_data *trp, u64 rid, u64 sva, u64 eva) -{ - u64 sa1, ea1; - - if (!trp->p || trp->rid != rid) - return 0; - - sa1 = trp->vadr; - ea1 = sa1 + PSIZE(trp->ps) - 1; - eva -= 1; - if ((sva > ea1) || (sa1 > eva)) - return 0; - else - return 1; - -} - -void machine_tlb_purge(u64 va, u64 ps) -{ - ia64_ptcl(va, ps << 2); -} - -void local_flush_tlb_all(void) -{ - int i, j; - unsigned long flags, count0, count1; - unsigned long stride0, stride1, addr; - - addr = current_vcpu->arch.ptce_base; - count0 = current_vcpu->arch.ptce_count[0]; - count1 = current_vcpu->arch.ptce_count[1]; - stride0 = current_vcpu->arch.ptce_stride[0]; - stride1 = current_vcpu->arch.ptce_stride[1]; - - local_irq_save(flags); - for (i = 0; i < count0; ++i) { - for (j = 0; j < count1; ++j) { - ia64_ptce(addr); - addr += stride1; - } - addr += stride0; - } - local_irq_restore(flags); - ia64_srlz_i(); /* srlz.i implies srlz.d */ -} - -int vhpt_enabled(struct kvm_vcpu *vcpu, u64 vadr, enum vhpt_ref ref) -{ - union ia64_rr vrr; - union ia64_pta vpta; - struct ia64_psr vpsr; - - vpsr = *(struct ia64_psr *)&VCPU(vcpu, vpsr); - vrr.val = vcpu_get_rr(vcpu, vadr); - vpta.val = vcpu_get_pta(vcpu); - - if (vrr.ve & vpta.ve) { - switch (ref) { - case DATA_REF: - case NA_REF: - return vpsr.dt; - case INST_REF: - return vpsr.dt && vpsr.it && vpsr.ic; - case RSE_REF: - return vpsr.dt && vpsr.rt; - - } - } - return 0; -} - -struct thash_data *vsa_thash(union ia64_pta vpta, u64 va, u64 vrr, u64 *tag) -{ - u64 index, pfn, rid, pfn_bits; - - pfn_bits = vpta.size - 5 - 8; - pfn = REGION_OFFSET(va) >> _REGION_PAGE_SIZE(vrr); - rid = _REGION_ID(vrr); - index = ((rid & 0xff) << pfn_bits)|(pfn & ((1UL << pfn_bits) - 1)); - *tag = ((rid >> 8) & 0xffff) | ((pfn >> pfn_bits) << 16); - - return (struct thash_data *)((vpta.base << PTA_BASE_SHIFT) + - (index << 5)); -} - -struct thash_data *__vtr_lookup(struct kvm_vcpu *vcpu, u64 va, int type) -{ - - struct thash_data *trp; - int i; - u64 rid; - - rid = vcpu_get_rr(vcpu, va); - rid = rid & RR_RID_MASK; - if (type == D_TLB) { - if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { - for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; - i < NDTRS; i++, trp++) { - if (__is_tr_translated(trp, rid, va)) - return trp; - } - } - } else { - if (vcpu_quick_region_check(vcpu->arch.itr_regions, va)) { - for (trp = (struct thash_data *)&vcpu->arch.itrs, i = 0; - i < NITRS; i++, trp++) { - if (__is_tr_translated(trp, rid, va)) - return trp; - } - } - } - - return NULL; -} - -static void vhpt_insert(u64 pte, u64 itir, u64 ifa, u64 gpte) -{ - union ia64_rr rr; - struct thash_data *head; - unsigned long ps, gpaddr; - - ps = itir_ps(itir); - rr.val = ia64_get_rr(ifa); - - gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) | - (ifa & ((1UL << ps) - 1)); - - head = (struct thash_data *)ia64_thash(ifa); - head->etag = INVALID_TI_TAG; - ia64_mf(); - head->page_flags = pte & ~PAGE_FLAGS_RV_MASK; - head->itir = rr.ps << 2; - head->etag = ia64_ttag(ifa); - head->gpaddr = gpaddr; -} - -void mark_pages_dirty(struct kvm_vcpu *v, u64 pte, u64 ps) -{ - u64 i, dirty_pages = 1; - u64 base_gfn = (pte&_PAGE_PPN_MASK) >> PAGE_SHIFT; - vmm_spinlock_t *lock = __kvm_va(v->arch.dirty_log_lock_pa); - void *dirty_bitmap = (void *)KVM_MEM_DIRTY_LOG_BASE; - - dirty_pages <<= ps <= PAGE_SHIFT ? 0 : ps - PAGE_SHIFT; - - vmm_spin_lock(lock); - for (i = 0; i < dirty_pages; i++) { - /* avoid RMW */ - if (!test_bit(base_gfn + i, dirty_bitmap)) - set_bit(base_gfn + i , dirty_bitmap); - } - vmm_spin_unlock(lock); -} - -void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va, int type) -{ - u64 phy_pte, psr; - union ia64_rr mrr; - - mrr.val = ia64_get_rr(va); - phy_pte = translate_phy_pte(&pte, itir, va); - - if (itir_ps(itir) >= mrr.ps) { - vhpt_insert(phy_pte, itir, va, pte); - } else { - phy_pte &= ~PAGE_FLAGS_RV_MASK; - psr = ia64_clear_ic(); - ia64_itc(type, va, phy_pte, itir_ps(itir)); - paravirt_dv_serialize_data(); - ia64_set_psr(psr); - } - - if (!(pte&VTLB_PTE_IO)) - mark_pages_dirty(v, pte, itir_ps(itir)); -} - -/* - * vhpt lookup - */ -struct thash_data *vhpt_lookup(u64 va) -{ - struct thash_data *head; - u64 tag; - - head = (struct thash_data *)ia64_thash(va); - tag = ia64_ttag(va); - if (head->etag == tag) - return head; - return NULL; -} - -u64 guest_vhpt_lookup(u64 iha, u64 *pte) -{ - u64 ret; - struct thash_data *data; - - data = __vtr_lookup(current_vcpu, iha, D_TLB); - if (data != NULL) - thash_vhpt_insert(current_vcpu, data->page_flags, - data->itir, iha, D_TLB); - - asm volatile ("rsm psr.ic|psr.i;;" - "srlz.d;;" - "ld8.s r9=[%1];;" - "tnat.nz p6,p7=r9;;" - "(p6) mov %0=1;" - "(p6) mov r9=r0;" - "(p7) extr.u r9=r9,0,53;;" - "(p7) mov %0=r0;" - "(p7) st8 [%2]=r9;;" - "ssm psr.ic;;" - "srlz.d;;" - "ssm psr.i;;" - "srlz.d;;" - : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); - - return ret; -} - -/* - * purge software guest tlb - */ - -static void vtlb_purge(struct kvm_vcpu *v, u64 va, u64 ps) -{ - struct thash_data *cur; - u64 start, curadr, size, psbits, tag, rr_ps, num; - union ia64_rr vrr; - struct thash_cb *hcb = &v->arch.vtlb; - - vrr.val = vcpu_get_rr(v, va); - psbits = VMX(v, psbits[(va >> 61)]); - start = va & ~((1UL << ps) - 1); - while (psbits) { - curadr = start; - rr_ps = __ffs(psbits); - psbits &= ~(1UL << rr_ps); - num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps)); - size = PSIZE(rr_ps); - vrr.ps = rr_ps; - while (num) { - cur = vsa_thash(hcb->pta, curadr, vrr.val, &tag); - if (cur->etag == tag && cur->ps == rr_ps) - cur->etag = INVALID_TI_TAG; - curadr += size; - num--; - } - } -} - - -/* - * purge VHPT and machine TLB - */ -static void vhpt_purge(struct kvm_vcpu *v, u64 va, u64 ps) -{ - struct thash_data *cur; - u64 start, size, tag, num; - union ia64_rr rr; - - start = va & ~((1UL << ps) - 1); - rr.val = ia64_get_rr(va); - size = PSIZE(rr.ps); - num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps)); - while (num) { - cur = (struct thash_data *)ia64_thash(start); - tag = ia64_ttag(start); - if (cur->etag == tag) - cur->etag = INVALID_TI_TAG; - start += size; - num--; - } - machine_tlb_purge(va, ps); -} - -/* - * Insert an entry into hash TLB or VHPT. - * NOTES: - * 1: When inserting VHPT to thash, "va" is a must covered - * address by the inserted machine VHPT entry. - * 2: The format of entry is always in TLB. - * 3: The caller need to make sure the new entry will not overlap - * with any existed entry. - */ -void vtlb_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va) -{ - struct thash_data *head; - union ia64_rr vrr; - u64 tag; - struct thash_cb *hcb = &v->arch.vtlb; - - vrr.val = vcpu_get_rr(v, va); - vrr.ps = itir_ps(itir); - VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps); - head = vsa_thash(hcb->pta, va, vrr.val, &tag); - head->page_flags = pte; - head->itir = itir; - head->etag = tag; -} - -int vtr_find_overlap(struct kvm_vcpu *vcpu, u64 va, u64 ps, int type) -{ - struct thash_data *trp; - int i; - u64 end, rid; - - rid = vcpu_get_rr(vcpu, va); - rid = rid & RR_RID_MASK; - end = va + PSIZE(ps); - if (type == D_TLB) { - if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { - for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; - i < NDTRS; i++, trp++) { - if (__is_tr_overlap(trp, rid, va, end)) - return i; - } - } - } else { - if (vcpu_quick_region_check(vcpu->arch.itr_regions, va)) { - for (trp = (struct thash_data *)&vcpu->arch.itrs, i = 0; - i < NITRS; i++, trp++) { - if (__is_tr_overlap(trp, rid, va, end)) - return i; - } - } - } - return -1; -} - -/* - * Purge entries in VTLB and VHPT - */ -void thash_purge_entries(struct kvm_vcpu *v, u64 va, u64 ps) -{ - if (vcpu_quick_region_check(v->arch.tc_regions, va)) - vtlb_purge(v, va, ps); - vhpt_purge(v, va, ps); -} - -void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps) -{ - u64 old_va = va; - va = REGION_OFFSET(va); - if (vcpu_quick_region_check(v->arch.tc_regions, old_va)) - vtlb_purge(v, va, ps); - vhpt_purge(v, va, ps); -} - -u64 translate_phy_pte(u64 *pte, u64 itir, u64 va) -{ - u64 ps, ps_mask, paddr, maddr, io_mask; - union pte_flags phy_pte; - - ps = itir_ps(itir); - ps_mask = ~((1UL << ps) - 1); - phy_pte.val = *pte; - paddr = *pte; - paddr = ((paddr & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask); - maddr = kvm_get_mpt_entry(paddr >> PAGE_SHIFT); - io_mask = maddr & GPFN_IO_MASK; - if (io_mask && (io_mask != GPFN_PHYS_MMIO)) { - *pte |= VTLB_PTE_IO; - return -1; - } - maddr = ((maddr & _PAGE_PPN_MASK) & PAGE_MASK) | - (paddr & ~PAGE_MASK); - phy_pte.ppn = maddr >> ARCH_PAGE_SHIFT; - return phy_pte.val; -} - -/* - * Purge overlap TCs and then insert the new entry to emulate itc ops. - * Notes: Only TC entry can purge and insert. - */ -void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir, - u64 ifa, int type) -{ - u64 ps; - u64 phy_pte, io_mask, index; - union ia64_rr vrr, mrr; - - ps = itir_ps(itir); - vrr.val = vcpu_get_rr(v, ifa); - mrr.val = ia64_get_rr(ifa); - - index = (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT; - io_mask = kvm_get_mpt_entry(index) & GPFN_IO_MASK; - phy_pte = translate_phy_pte(&pte, itir, ifa); - - /* Ensure WB attribute if pte is related to a normal mem page, - * which is required by vga acceleration since qemu maps shared - * vram buffer with WB. - */ - if (!(pte & VTLB_PTE_IO) && ((pte & _PAGE_MA_MASK) != _PAGE_MA_NAT) && - io_mask != GPFN_PHYS_MMIO) { - pte &= ~_PAGE_MA_MASK; - phy_pte &= ~_PAGE_MA_MASK; - } - - vtlb_purge(v, ifa, ps); - vhpt_purge(v, ifa, ps); - - if ((ps != mrr.ps) || (pte & VTLB_PTE_IO)) { - vtlb_insert(v, pte, itir, ifa); - vcpu_quick_region_set(VMX(v, tc_regions), ifa); - } - if (pte & VTLB_PTE_IO) - return; - - if (ps >= mrr.ps) - vhpt_insert(phy_pte, itir, ifa, pte); - else { - u64 psr; - phy_pte &= ~PAGE_FLAGS_RV_MASK; - psr = ia64_clear_ic(); - ia64_itc(type, ifa, phy_pte, ps); - paravirt_dv_serialize_data(); - ia64_set_psr(psr); - } - if (!(pte&VTLB_PTE_IO)) - mark_pages_dirty(v, pte, ps); - -} - -/* - * Purge all TCs or VHPT entries including those in Hash table. - * - */ - -void thash_purge_all(struct kvm_vcpu *v) -{ - int i; - struct thash_data *head; - struct thash_cb *vtlb, *vhpt; - vtlb = &v->arch.vtlb; - vhpt = &v->arch.vhpt; - - for (i = 0; i < 8; i++) - VMX(v, psbits[i]) = 0; - - head = vtlb->hash; - for (i = 0; i < vtlb->num; i++) { - head->page_flags = 0; - head->etag = INVALID_TI_TAG; - head->itir = 0; - head->next = 0; - head++; - }; - - head = vhpt->hash; - for (i = 0; i < vhpt->num; i++) { - head->page_flags = 0; - head->etag = INVALID_TI_TAG; - head->itir = 0; - head->next = 0; - head++; - }; - - local_flush_tlb_all(); -} - -/* - * Lookup the hash table and its collision chain to find an entry - * covering this address rid:va or the entry. - * - * INPUT: - * in: TLB format for both VHPT & TLB. - */ -struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data) -{ - struct thash_data *cch; - u64 psbits, ps, tag; - union ia64_rr vrr; - - struct thash_cb *hcb = &v->arch.vtlb; - - cch = __vtr_lookup(v, va, is_data); - if (cch) - return cch; - - if (vcpu_quick_region_check(v->arch.tc_regions, va) == 0) - return NULL; - - psbits = VMX(v, psbits[(va >> 61)]); - vrr.val = vcpu_get_rr(v, va); - while (psbits) { - ps = __ffs(psbits); - psbits &= ~(1UL << ps); - vrr.ps = ps; - cch = vsa_thash(hcb->pta, va, vrr.val, &tag); - if (cch->etag == tag && cch->ps == ps) - return cch; - } - - return NULL; -} - -/* - * Initialize internal control data before service. - */ -void thash_init(struct thash_cb *hcb, u64 sz) -{ - int i; - struct thash_data *head; - - hcb->pta.val = (unsigned long)hcb->hash; - hcb->pta.vf = 1; - hcb->pta.ve = 1; - hcb->pta.size = sz; - head = hcb->hash; - for (i = 0; i < hcb->num; i++) { - head->page_flags = 0; - head->itir = 0; - head->etag = INVALID_TI_TAG; - head->next = 0; - head++; - } -} - -u64 kvm_get_mpt_entry(u64 gpfn) -{ - u64 *base = (u64 *) KVM_P2M_BASE; - - if (gpfn >= (KVM_P2M_SIZE >> 3)) - panic_vm(current_vcpu, "Invalid gpfn =%lx\n", gpfn); - - return *(base + gpfn); -} - -u64 kvm_lookup_mpa(u64 gpfn) -{ - u64 maddr; - maddr = kvm_get_mpt_entry(gpfn); - return maddr&_PAGE_PPN_MASK; -} - -u64 kvm_gpa_to_mpa(u64 gpa) -{ - u64 pte = kvm_lookup_mpa(gpa >> PAGE_SHIFT); - return (pte >> PAGE_SHIFT << PAGE_SHIFT) | (gpa & ~PAGE_MASK); -} - -/* - * Fetch guest bundle code. - * INPUT: - * gip: guest ip - * pbundle: used to return fetched bundle. - */ -int fetch_code(struct kvm_vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle) -{ - u64 gpip = 0; /* guest physical IP*/ - u64 *vpa; - struct thash_data *tlb; - u64 maddr; - - if (!(VCPU(vcpu, vpsr) & IA64_PSR_IT)) { - /* I-side physical mode */ - gpip = gip; - } else { - tlb = vtlb_lookup(vcpu, gip, I_TLB); - if (tlb) - gpip = (tlb->ppn >> (tlb->ps - 12) << tlb->ps) | - (gip & (PSIZE(tlb->ps) - 1)); - } - if (gpip) { - maddr = kvm_gpa_to_mpa(gpip); - } else { - tlb = vhpt_lookup(gip); - if (tlb == NULL) { - ia64_ptcl(gip, ARCH_PAGE_SHIFT << 2); - return IA64_FAULT; - } - maddr = (tlb->ppn >> (tlb->ps - 12) << tlb->ps) - | (gip & (PSIZE(tlb->ps) - 1)); - } - vpa = (u64 *)__kvm_va(maddr); - - pbundle->i64[0] = *vpa++; - pbundle->i64[1] = *vpa; - - return IA64_NO_FAULT; -} - -void kvm_init_vhpt(struct kvm_vcpu *v) -{ - v->arch.vhpt.num = VHPT_NUM_ENTRIES; - thash_init(&v->arch.vhpt, VHPT_SHIFT); - ia64_set_pta(v->arch.vhpt.pta.val); - /*Enable VHPT here?*/ -} - -void kvm_init_vtlb(struct kvm_vcpu *v) -{ - v->arch.vtlb.num = VTLB_NUM_ENTRIES; - thash_init(&v->arch.vtlb, VTLB_SHIFT); -} diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 0ba4057d271b..f0f7ef82b7a6 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -586,11 +586,6 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, case IOAPIC_REG_WINDOW: ioapic_write_indirect(ioapic, data); break; -#ifdef CONFIG_IA64 - case IOAPIC_REG_EOI: - __kvm_ioapic_update_eoi(NULL, ioapic, data, IOAPIC_LEVEL_TRIG); - break; -#endif default: break; diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 31725a3a93b8..dc3baa3a538f 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h @@ -19,7 +19,6 @@ struct kvm_vcpu; /* Direct registers. */ #define IOAPIC_REG_SELECT 0x00 #define IOAPIC_REG_WINDOW 0x10 -#define IOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */ /* Indirect registers. */ #define IOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 963b8995a9e8..1345bde064f5 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -26,9 +26,6 @@ #include #include -#ifdef CONFIG_IA64 -#include -#endif #include "irq.h" @@ -57,12 +54,7 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) { -#ifdef CONFIG_IA64 - return irq->delivery_mode == - (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); -#else return irq->delivery_mode == APIC_DM_LOWEST; -#endif } int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, @@ -346,20 +338,6 @@ static const struct kvm_irq_routing_entry default_routing[] = { ROUTING_ENTRY1(18), ROUTING_ENTRY1(19), ROUTING_ENTRY1(20), ROUTING_ENTRY1(21), ROUTING_ENTRY1(22), ROUTING_ENTRY1(23), -#ifdef CONFIG_IA64 - ROUTING_ENTRY1(24), ROUTING_ENTRY1(25), - ROUTING_ENTRY1(26), ROUTING_ENTRY1(27), - ROUTING_ENTRY1(28), ROUTING_ENTRY1(29), - ROUTING_ENTRY1(30), ROUTING_ENTRY1(31), - ROUTING_ENTRY1(32), ROUTING_ENTRY1(33), - ROUTING_ENTRY1(34), ROUTING_ENTRY1(35), - ROUTING_ENTRY1(36), ROUTING_ENTRY1(37), - ROUTING_ENTRY1(38), ROUTING_ENTRY1(39), - ROUTING_ENTRY1(40), ROUTING_ENTRY1(41), - ROUTING_ENTRY1(42), ROUTING_ENTRY1(43), - ROUTING_ENTRY1(44), ROUTING_ENTRY1(45), - ROUTING_ENTRY1(46), ROUTING_ENTRY1(47), -#endif }; int kvm_setup_default_irq_routing(struct kvm *kvm) -- GitLab From c32a42721ce67594e4481a961aa149055de9c1d9 Mon Sep 17 00:00:00 2001 From: Tiejun Chen Date: Thu, 20 Nov 2014 11:07:18 +0100 Subject: [PATCH 5468/9457] kvm: Documentation: remove ia64 kvm/ia64 is gone, clean up Documentation too. Signed-off-by: Paolo Bonzini --- Documentation/ia64/kvm.txt | 83 ------------------------------- Documentation/virtual/kvm/api.txt | 45 ++++++++--------- 2 files changed, 22 insertions(+), 106 deletions(-) delete mode 100644 Documentation/ia64/kvm.txt diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt deleted file mode 100644 index ffb5c80bec3e..000000000000 --- a/Documentation/ia64/kvm.txt +++ /dev/null @@ -1,83 +0,0 @@ -Currently, kvm module is in EXPERIMENTAL stage on IA64. This means that -interfaces are not stable enough to use. So, please don't run critical -applications in virtual machine. -We will try our best to improve it in future versions! - - Guide: How to boot up guests on kvm/ia64 - -This guide is to describe how to enable kvm support for IA-64 systems. - -1. Get the kvm source from git.kernel.org. - Userspace source: - git clone git://git.kernel.org/pub/scm/virt/kvm/kvm-userspace.git - Kernel Source: - git clone git://git.kernel.org/pub/scm/linux/kernel/git/xiantao/kvm-ia64.git - -2. Compile the source code. - 2.1 Compile userspace code: - (1)cd ./kvm-userspace - (2)./configure - (3)cd kernel - (4)make sync LINUX= $kernel_dir (kernel_dir is the directory of kernel source.) - (5)cd .. - (6)make qemu - (7)cd qemu; make install - - 2.2 Compile kernel source code: - (1) cd ./$kernel_dir - (2) Make menuconfig - (3) Enter into virtualization option, and choose kvm. - (4) make - (5) Once (4) done, make modules_install - (6) Make initrd, and use new kernel to reboot up host machine. - (7) Once (6) done, cd $kernel_dir/arch/ia64/kvm - (8) insmod kvm.ko; insmod kvm-intel.ko - -Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qemu, otherwise, may fail. - -3. Get Guest Firmware named as Flash.fd, and put it under right place: - (1) If you have the guest firmware (binary) released by Intel Corp for Xen, use it directly. - - (2) If you have no firmware at hand, Please download its source from - hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg - you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries. - - (3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu - -4. Boot up Linux or Windows guests: - 4.1 Create or install a image for guest boot. If you have xen experience, it should be easy. - - 4.2 Boot up guests use the following command. - /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image - (xx is the number of virtual processors for the guest, now the maximum value is 4) - -5. Known possible issue on some platforms with old Firmware. - -In the event of strange host crash issues, try to solve it through either of the following ways: - -(1): Upgrade your Firmware to the latest one. - -(2): Applying the below patch to kernel source. -diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S -index 0b53344..f02b0f7 100644 ---- a/arch/ia64/kernel/pal.S -+++ b/arch/ia64/kernel/pal.S -@@ -84,7 +84,8 @@ GLOBAL_ENTRY(ia64_pal_call_static) - mov ar.pfs = loc1 - mov rp = loc0 - ;; -- srlz.d // serialize restoration of psr.l -+ srlz.i // serialize restoration of psr.l -+ ;; - br.ret.sptk.many b0 - END(ia64_pal_call_static) - -6. Bug report: - If you found any issues when use kvm/ia64, Please post the bug info to kvm-ia64-devel mailing list. - https://lists.sourceforge.net/lists/listinfo/kvm-ia64-devel/ - -Thanks for your interest! Let's work together, and make kvm/ia64 stronger and stronger! - - - Xiantao Zhang - 2008.3.10 diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 7a943c23db1c..80bfe59fc992 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -607,7 +607,7 @@ struct kvm_fpu { 4.24 KVM_CREATE_IRQCHIP Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390) -Architectures: x86, ia64, ARM, arm64, s390 +Architectures: x86, ARM, arm64, s390 Type: vm ioctl Parameters: none Returns: 0 on success, -1 on error @@ -615,7 +615,7 @@ Returns: 0 on success, -1 on error Creates an interrupt controller model in the kernel. On x86, creates a virtual ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 -only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is +only go to the IOAPIC. On ARM/arm64, a GIC is created. On s390, a dummy irq routing table is created. Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled @@ -625,7 +625,7 @@ before KVM_CREATE_IRQCHIP can be used. 4.25 KVM_IRQ_LINE Capability: KVM_CAP_IRQCHIP -Architectures: x86, ia64, arm, arm64 +Architectures: x86, arm, arm64 Type: vm ioctl Parameters: struct kvm_irq_level Returns: 0 on success, -1 on error @@ -679,7 +679,7 @@ struct kvm_irq_level { 4.26 KVM_GET_IRQCHIP Capability: KVM_CAP_IRQCHIP -Architectures: x86, ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_irqchip (in/out) Returns: 0 on success, -1 on error @@ -701,7 +701,7 @@ struct kvm_irqchip { 4.27 KVM_SET_IRQCHIP Capability: KVM_CAP_IRQCHIP -Architectures: x86, ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_irqchip (in) Returns: 0 on success, -1 on error @@ -994,7 +994,7 @@ for vm-wide capabilities. 4.38 KVM_GET_MP_STATE Capability: KVM_CAP_MP_STATE -Architectures: x86, ia64, s390 +Architectures: x86, s390 Type: vcpu ioctl Parameters: struct kvm_mp_state (out) Returns: 0 on success; -1 on error @@ -1008,16 +1008,15 @@ uniprocessor guests). Possible values are: - - KVM_MP_STATE_RUNNABLE: the vcpu is currently running [x86, ia64] + - KVM_MP_STATE_RUNNABLE: the vcpu is currently running [x86] - KVM_MP_STATE_UNINITIALIZED: the vcpu is an application processor (AP) - which has not yet received an INIT signal [x86, - ia64] + which has not yet received an INIT signal [x86] - KVM_MP_STATE_INIT_RECEIVED: the vcpu has received an INIT signal, and is - now ready for a SIPI [x86, ia64] + now ready for a SIPI [x86] - KVM_MP_STATE_HALTED: the vcpu has executed a HLT instruction and - is waiting for an interrupt [x86, ia64] + is waiting for an interrupt [x86] - KVM_MP_STATE_SIPI_RECEIVED: the vcpu has just received a SIPI (vector - accessible via KVM_GET_VCPU_EVENTS) [x86, ia64] + accessible via KVM_GET_VCPU_EVENTS) [x86] - KVM_MP_STATE_STOPPED: the vcpu is stopped [s390] - KVM_MP_STATE_CHECK_STOP: the vcpu is in a special error state [s390] - KVM_MP_STATE_OPERATING: the vcpu is operating (running or halted) @@ -1025,7 +1024,7 @@ Possible values are: - KVM_MP_STATE_LOAD: the vcpu is in a special load/startup state [s390] -On x86 and ia64, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an +On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an in-kernel irqchip, the multiprocessing state must be maintained by userspace on these architectures. @@ -1033,7 +1032,7 @@ these architectures. 4.39 KVM_SET_MP_STATE Capability: KVM_CAP_MP_STATE -Architectures: x86, ia64, s390 +Architectures: x86, s390 Type: vcpu ioctl Parameters: struct kvm_mp_state (in) Returns: 0 on success; -1 on error @@ -1041,7 +1040,7 @@ Returns: 0 on success; -1 on error Sets the vcpu's current "multiprocessing state"; see KVM_GET_MP_STATE for arguments. -On x86 and ia64, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an +On x86, this ioctl is only useful after KVM_CREATE_IRQCHIP. Without an in-kernel irqchip, the multiprocessing state must be maintained by userspace on these architectures. @@ -1068,7 +1067,7 @@ documentation when it pops into existence). 4.41 KVM_SET_BOOT_CPU_ID Capability: KVM_CAP_SET_BOOT_CPU_ID -Architectures: x86, ia64 +Architectures: x86 Type: vm ioctl Parameters: unsigned long vcpu_id Returns: 0 on success, -1 on error @@ -1261,7 +1260,7 @@ The flags bitmap is defined as: 4.48 KVM_ASSIGN_PCI_DEVICE Capability: none -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_pci_dev (in) Returns: 0 on success, -1 on error @@ -1311,7 +1310,7 @@ Errors: 4.49 KVM_DEASSIGN_PCI_DEVICE Capability: none -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_pci_dev (in) Returns: 0 on success, -1 on error @@ -1330,7 +1329,7 @@ Errors: 4.50 KVM_ASSIGN_DEV_IRQ Capability: KVM_CAP_ASSIGN_DEV_IRQ -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_irq (in) Returns: 0 on success, -1 on error @@ -1370,7 +1369,7 @@ Errors: 4.51 KVM_DEASSIGN_DEV_IRQ Capability: KVM_CAP_ASSIGN_DEV_IRQ -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_irq (in) Returns: 0 on success, -1 on error @@ -1385,7 +1384,7 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed. 4.52 KVM_SET_GSI_ROUTING Capability: KVM_CAP_IRQ_ROUTING -Architectures: x86 ia64 s390 +Architectures: x86 s390 Type: vm ioctl Parameters: struct kvm_irq_routing (in) Returns: 0 on success, -1 on error @@ -1444,7 +1443,7 @@ struct kvm_irq_routing_s390_adapter { 4.53 KVM_ASSIGN_SET_MSIX_NR Capability: none -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_msix_nr (in) Returns: 0 on success, -1 on error @@ -1466,7 +1465,7 @@ struct kvm_assigned_msix_nr { 4.54 KVM_ASSIGN_SET_MSIX_ENTRY Capability: none -Architectures: x86 ia64 +Architectures: x86 Type: vm ioctl Parameters: struct kvm_assigned_msix_entry (in) Returns: 0 on success, -1 on error -- GitLab From 571a4b57975aaaf50479a59882f1d44ae2737084 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 19 Nov 2014 19:34:49 +0000 Subject: [PATCH 5469/9457] GFS2: bugger off early if O_CREAT open finds a directory Signed-off-by: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 04065e5af4b6..f41b2fd12416 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -624,6 +624,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = gfs2_dir_search(dir, &dentry->d_name, !S_ISREG(mode) || excl); error = PTR_ERR(inode); if (!IS_ERR(inode)) { + if (S_ISDIR(inode->i_mode)) { + iput(inode); + inode = ERR_PTR(-EISDIR); + goto fail_gunlock; + } d = d_splice_alias(inode, dentry); error = PTR_ERR(d); if (IS_ERR(d)) { -- GitLab From 44bb31bac555b0faf2e7068f3a953d5b23883dc9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 19 Nov 2014 19:35:24 +0000 Subject: [PATCH 5470/9457] GFS2: gfs2_create_inode(): don't bother with d_splice_alias() dentry is always hashed and negative, inode - non-error, non-NULL and non-directory. In such conditions d_splice_alias() is equivalent to "d_instantiate(dentry, inode) and return NULL", which simplifies the downstream code and is consistent with the "have to create a new object" case. Signed-off-by: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index f41b2fd12416..9e8545bbc55c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -596,7 +596,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, struct gfs2_inode *dip = GFS2_I(dir), *ip; struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_glock *io_gl; - struct dentry *d; int error, free_vfs_inode = 0; u32 aflags = 0; unsigned blocks = 1; @@ -629,22 +628,13 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, inode = ERR_PTR(-EISDIR); goto fail_gunlock; } - d = d_splice_alias(inode, dentry); - error = PTR_ERR(d); - if (IS_ERR(d)) { - inode = ERR_CAST(d); - goto fail_gunlock; - } + d_instantiate(dentry, inode); error = 0; if (file) { - if (S_ISREG(inode->i_mode)) { - WARN_ON(d != NULL); + if (S_ISREG(inode->i_mode)) error = finish_open(file, dentry, gfs2_open_common, opened); - } else { - error = finish_no_open(file, d); - } - } else { - dput(d); + else + error = finish_no_open(file, NULL); } gfs2_glock_dq_uninit(ghs); return error; -- GitLab From 3cdcf63ed2d169c82d70a506f3569e484cd9e7a0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 05:18:38 +0000 Subject: [PATCH 5471/9457] GFS2: use kvfree() instead of open-coding it Signed-off-by: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/dir.c | 40 ++++++++-------------------------------- fs/gfs2/quota.c | 9 ++------- 2 files changed, 10 insertions(+), 39 deletions(-) diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 5d4261ff5d23..c247fed4a9a6 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -365,22 +365,15 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip) ret = gfs2_dir_read_data(ip, hc, hsize); if (ret < 0) { - if (is_vmalloc_addr(hc)) - vfree(hc); - else - kfree(hc); + kvfree(hc); return ERR_PTR(ret); } spin_lock(&inode->i_lock); - if (ip->i_hash_cache) { - if (is_vmalloc_addr(hc)) - vfree(hc); - else - kfree(hc); - } else { + if (ip->i_hash_cache) + kvfree(hc); + else ip->i_hash_cache = hc; - } spin_unlock(&inode->i_lock); return ip->i_hash_cache; @@ -396,10 +389,7 @@ void gfs2_dir_hash_inval(struct gfs2_inode *ip) { __be64 *hc = ip->i_hash_cache; ip->i_hash_cache = NULL; - if (is_vmalloc_addr(hc)) - vfree(hc); - else - kfree(hc); + kvfree(hc); } static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) @@ -1168,10 +1158,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) gfs2_dinode_out(dip, dibh->b_data); brelse(dibh); out_kfree: - if (is_vmalloc_addr(hc2)) - vfree(hc2); - else - kfree(hc2); + kvfree(hc2); return error; } @@ -1302,14 +1289,6 @@ static void *gfs2_alloc_sort_buffer(unsigned size) return ptr; } -static void gfs2_free_sort_buffer(void *ptr) -{ - if (is_vmalloc_addr(ptr)) - vfree(ptr); - else - kfree(ptr); -} - static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, int *copied, unsigned *depth, u64 leaf_no) @@ -1393,7 +1372,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, out_free: for(i = 0; i < leaf; i++) brelse(larr[i]); - gfs2_free_sort_buffer(larr); + kvfree(larr); out: return error; } @@ -2004,10 +1983,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, gfs2_rlist_free(&rlist); gfs2_quota_unhold(dip); out: - if (is_vmalloc_addr(ht)) - vfree(ht); - else - kfree(ht); + kvfree(ht); return error; } diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 64b29f7f6b4c..c8b148bbdc8b 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1360,13 +1360,8 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_quota_count)); - if (sdp->sd_quota_bitmap) { - if (is_vmalloc_addr(sdp->sd_quota_bitmap)) - vfree(sdp->sd_quota_bitmap); - else - kfree(sdp->sd_quota_bitmap); - sdp->sd_quota_bitmap = NULL; - } + kvfree(sdp->sd_quota_bitmap); + sdp->sd_quota_bitmap = NULL; } static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) -- GitLab From 9265f1d0c7593e3e7e1e94a4a83a6dea34230a35 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 05:19:47 +0000 Subject: [PATCH 5472/9457] GFS2: gfs2_dir_get_hash_table(): avoiding deferred vfree() is easy here... vfree() is allowed under spinlock these days, but it's cheaper when it doesn't step into deferred case and here it's very easy to avoid. Signed-off-by: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/dir.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index c247fed4a9a6..c5a34f09e228 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -370,11 +370,12 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip) } spin_lock(&inode->i_lock); - if (ip->i_hash_cache) - kvfree(hc); - else + if (likely(!ip->i_hash_cache)) { ip->i_hash_cache = hc; + hc = NULL; + } spin_unlock(&inode->i_lock); + kvfree(hc); return ip->i_hash_cache; } -- GitLab From 2d0747c4b68be8eb8ccfa2c538f2f5dd2ea89094 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 19 Nov 2014 22:35:39 +0000 Subject: [PATCH 5473/9457] of: Properly set the OF_POPULATED_BUS flag on root node of_platform_populate() takes a subset of the device tree and turns it into a set of platform_devices. At the same time it sets the OF_POPULATED_BUS flag in each bus nodes so that of_platform_depopulate() can undo the operation at a later time. However, it doesn't set the flag on the root of the population tree which means that dynamic modifications of the device tree at runtime will not create/destroy devices correctly. Fix of_platform_populate() to set the OF_POPULATED_BUS flag on the node it is called with. Signed-off-by: Grant Likely Cc: Rob Herring Cc: Pantelis Antoniou Cc: Pawel Moll --- drivers/of/platform.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 7c6771986c06..656cccf0e680 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -500,6 +500,7 @@ int of_platform_populate(struct device_node *root, if (rc) break; } + of_node_set_flag(root, OF_POPULATED_BUS); of_node_put(root); return rc; @@ -542,7 +543,10 @@ static int of_platform_device_destroy(struct device *dev, void *data) */ void of_platform_depopulate(struct device *parent) { - device_for_each_child(parent, NULL, of_platform_device_destroy); + if (parent->of_node && of_node_check_flag(parent->of_node, OF_POPULATED_BUS)) { + device_for_each_child(parent, NULL, of_platform_device_destroy); + of_node_clear_flag(parent->of_node, OF_POPULATED_BUS); + } } EXPORT_SYMBOL_GPL(of_platform_depopulate); -- GitLab From ec7d879c457611e540cb465c25f3040facbd1185 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 19 Nov 2014 19:35:58 +0000 Subject: [PATCH 5474/9457] GFS2: gfs2_atomic_open(): simplify the use of finish_no_open() In ->atomic_open(inode, dentry, file, opened) calling finish_no_open(file, NULL) is equivalent to dget(dentry); return finish_no_open(file, dentry); No need to open-code that... Signed-off-by: Al Viro Signed-off-by: Steven Whitehouse --- fs/gfs2/inode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 9e8545bbc55c..9054002ebe70 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1245,11 +1245,8 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, if (d != NULL) dentry = d; if (dentry->d_inode) { - if (!(*opened & FILE_OPENED)) { - if (d == NULL) - dget(dentry); - return finish_no_open(file, dentry); - } + if (!(*opened & FILE_OPENED)) + return finish_no_open(file, d); dput(d); return 0; } -- GitLab From 87255483070c1e5a37b39cdda4d1e98fa3a13516 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 20:36:48 +0100 Subject: [PATCH 5475/9457] drm/i915: Ditch dev_priv->ums.mm_suspend Again just complicates gem init functions and makes a general mess out of everything. Good riddance! v2: In my enthusiasm to start removing dri1/ums crud I went overboard a bit and killed parts of hangcheck. Resurrect it. Acked-by: Chris Wilson Cc: Chris Wilson Cc: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 --- drivers/gpu/drm/i915/i915_drv.c | 5 +---- drivers/gpu/drm/i915/i915_drv.h | 15 -------------- drivers/gpu/drm/i915/i915_gem.c | 24 ++++++---------------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 ------ 5 files changed, 7 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6c9625305abc..c20fa303365f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -815,9 +815,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_ERROR("failed to init modeset\n"); goto out_power_well; } - } else { - /* Start out suspended in ums mode. */ - dev_priv->ums.mm_suspended = 1; } i915_setup_sysfs(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c9f248acbd69..1df407941700 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -852,10 +852,7 @@ int i915_reset(struct drm_device *dev) * was running at the time of the reset (i.e. we weren't VT * switched away). */ - if (drm_core_check_feature(dev, DRIVER_MODESET) || - !dev_priv->ums.mm_suspended) { - dev_priv->ums.mm_suspended = 0; - + if (drm_core_check_feature(dev, DRIVER_MODESET)) { /* Used to prevent gem_check_wedged returning -EAGAIN during gpu reset */ dev_priv->gpu_error.reload_in_reset = true; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a52fba103ce9..3d572a6023e6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1121,18 +1121,6 @@ struct i915_power_domains { struct i915_power_well *power_wells; }; -struct i915_ums_state { - /** - * Flag if the X Server, and thus DRM, is not currently in - * control of the device. - * - * This is set between LeaveVT and EnterVT. It needs to be - * replaced with a semaphore. It also needs to be - * transitioned away from for kernel modesetting. - */ - int mm_suspended; -}; - #define MAX_L3_SLICES 2 struct intel_l3_parity { u32 *remap_info[MAX_L3_SLICES]; @@ -1768,9 +1756,6 @@ struct drm_i915_private { uint32_t bios_vgacntr; - /* Old ums support infrastructure, same warning applies. */ - struct i915_ums_state ums; - /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ struct { int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bd171092e86f..af30283db628 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2501,15 +2501,13 @@ int __i915_add_request(struct intel_engine_cs *ring, ring->outstanding_lazy_seqno = 0; ring->preallocated_lazy_request = NULL; - if (!dev_priv->ums.mm_suspended) { - i915_queue_hangcheck(ring->dev); + i915_queue_hangcheck(ring->dev); - cancel_delayed_work_sync(&dev_priv->mm.idle_work); - queue_delayed_work(dev_priv->wq, - &dev_priv->mm.retire_work, - round_jiffies_up_relative(HZ)); - intel_mark_busy(dev_priv->dev); - } + cancel_delayed_work_sync(&dev_priv->mm.idle_work); + queue_delayed_work(dev_priv->wq, + &dev_priv->mm.retire_work, + round_jiffies_up_relative(HZ)); + intel_mark_busy(dev_priv->dev); if (out_seqno) *out_seqno = request->seqno; @@ -4651,9 +4649,6 @@ i915_gem_suspend(struct drm_device *dev) int ret = 0; mutex_lock(&dev->struct_mutex); - if (dev_priv->ums.mm_suspended) - goto err; - ret = i915_gpu_idle(dev); if (ret) goto err; @@ -4665,13 +4660,6 @@ i915_gem_suspend(struct drm_device *dev) i915_gem_evict_everything(dev); i915_gem_stop_ringbuffers(dev); - - /* Hack! Don't let anybody do execbuf while we don't control the chip. - * We need to replace this with a semaphore, or something. - * And not confound ums.mm_suspended! - */ - dev_priv->ums.mm_suspended = !drm_core_check_feature(dev, - DRIVER_MODESET); mutex_unlock(&dev->struct_mutex); del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b16eee061990..11738316394a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1338,12 +1338,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto pre_mutex_err; - if (dev_priv->ums.mm_suspended) { - mutex_unlock(&dev->struct_mutex); - ret = -EBUSY; - goto pre_mutex_err; - } - ctx = i915_gem_validate_context(dev, file, ring, ctx_id); if (IS_ERR(ctx)) { mutex_unlock(&dev->struct_mutex); -- GitLab From 377e91b2049352aed54e6dc3edc186f26da372ed Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 20:36:49 +0100 Subject: [PATCH 5476/9457] drm/i915: Sanitize ->lastclose With this all the ums nonsense around gem setup/teardown has disappeared, yay! Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 17 ++--------------- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 13 ------------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c20fa303365f..f5ded5c7daeb 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -980,21 +980,8 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) */ void i915_driver_lastclose(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - - /* On gen6+ we refuse to init without kms enabled, but then the drm core - * goes right around and calls lastclose. Check for this and don't clean - * up anything. */ - if (!dev_priv) - return; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - intel_fbdev_restore_mode(dev); - vga_switcheroo_process_delayed_switch(); - return; - } - - i915_gem_lastclose(dev); + intel_fbdev_restore_mode(dev); + vga_switcheroo_process_delayed_switch(); } void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3d572a6023e6..230a17211d76 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2468,7 +2468,6 @@ int __must_check i915_vma_unbind(struct i915_vma *vma); int i915_gem_object_put_pages(struct drm_i915_gem_object *obj); void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv); void i915_gem_release_mmap(struct drm_i915_gem_object *obj); -void i915_gem_lastclose(struct drm_device *dev); int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, int *needs_clflush); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index af30283db628..f2d7ce5e4bfb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4964,19 +4964,6 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) dev_priv->gt.cleanup_ring(ring); } -void -i915_gem_lastclose(struct drm_device *dev) -{ - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - ret = i915_gem_suspend(dev); - if (ret) - DRM_ERROR("failed to idle hardware: %d\n", ret); -} - static void init_ring_lists(struct intel_engine_cs *ring) { -- GitLab From f548c0e9d4200a660e607bb4d8824c21c6d0bd74 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 21:40:13 +0100 Subject: [PATCH 5477/9457] drm/i915: Can i915_gem_init_ioctl Found one more! With this we can clear up the ggtt init code a bit, yay! Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem.c | 27 --------------------------- drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++++---- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 -- 5 files changed, 5 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f5ded5c7daeb..ecee3bcc8772 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1022,7 +1022,7 @@ const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 230a17211d76..02b3cb32c8a6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2378,8 +2378,6 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, ibx_display_interrupt_update((dev_priv), (bits), 0) /* i915_gem.c */ -int i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); int i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_pread_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f2d7ce5e4bfb..480d00e672fa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -159,33 +159,6 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) return i915_gem_obj_bound_any(obj) && !obj->active; } -int -i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_init *args = data; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - - if (args->gtt_start >= args->gtt_end || - (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) - return -EINVAL; - - /* GEM with user mode setting was never supported on ilk and later. */ - if (INTEL_INFO(dev)->gen >= 5) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - i915_gem_setup_global_gtt(dev, args->gtt_start, args->gtt_end, - args->gtt_end); - dev_priv->gtt.mappable_end = args->gtt_end; - mutex_unlock(&dev->struct_mutex); - - return 0; -} - int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index bee5b0a00927..171f6eafdeee 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1664,10 +1664,10 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node, } } -int i915_gem_setup_global_gtt(struct drm_device *dev, - unsigned long start, - unsigned long mappable_end, - unsigned long end) +static int i915_gem_setup_global_gtt(struct drm_device *dev, + unsigned long start, + unsigned long mappable_end, + unsigned long end) { /* Let GEM Manage all of the aperture. * diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index d0562d0ef6ec..beaf4bcfdac8 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -274,8 +274,6 @@ struct i915_hw_ppgtt { int i915_gem_gtt_init(struct drm_device *dev); void i915_gem_init_global_gtt(struct drm_device *dev); -int i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, - unsigned long mappable_end, unsigned long end); void i915_global_gtt_cleanup(struct drm_device *dev); -- GitLab From 93ee29203f506582cca2bcec5f05041526d9ab0a Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Wed, 19 Nov 2014 14:21:52 -0800 Subject: [PATCH 5478/9457] drm/i915: Use efficient frequency for HSW/BDW Added gen6_init_rps_frequencies() to initialize the rps frequency values. This function replaces parse_rp_state_cap(). In addition to reading RPn, RP0, and RP1 from RP_STATE_CAP register, the new function reads efficient frequency (aka RPe) from pcode for Haswell and Broadwell and sets the turbo softlimits. The turbo minimum frequency softlimit is set to RPe for Haswell and Broadwell and to RPn otherwise. For RPe, the efficiency is based on the frequency/power ratio (MHz/W); this is considering GT power and not package power. The efficent frequency is the highest frequency for which the frequency/power ratio is within some threshold of the highest frequency/power ratio. A fixed decrease in frequency results in smaller decrease in power at frequencies less than RPe than at frequencies above RPe. v2: Following suggestions from Chris Wilson and Daniel Vetter to extend and rename parse_rp_state_cap and to open-code a poorly named function. Signed-off-by: Tom O'Rourke Reviewed-by: Chris Wilson [danvet: Remove unused variables.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 46 +++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7a77cd5676c8..3a51c05ca552 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6038,6 +6038,7 @@ enum punit_power_well { #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) #define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) #define DISPLAY_IPS_CONTROL 0x19 +#define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A #define GEN6_PCODE_DATA 0x138128 #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 417ba880c427..eb2a0a85e057 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4609,25 +4609,45 @@ int intel_enable_rc6(const struct drm_device *dev) return i915.enable_rc6; } -static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_cap) +static void gen6_init_rps_frequencies(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t rp_state_cap; + u32 ddcc_status = 0; + int ret; + + rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); /* All of these values are in units of 50MHz */ dev_priv->rps.cur_freq = 0; - /* static values from HW: RP0 < RPe < RP1 < RPn (min_freq) */ - dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; + /* static values from HW: RP0 > RP1 > RPn (min_freq) */ dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; + dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; - /* XXX: only BYT has a special efficient freq */ - dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; /* hw_max = RP0 until we check for overclocking */ dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; + dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = sandybridge_pcode_read(dev_priv, + HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, + &ddcc_status); + if (0 == ret) + dev_priv->rps.efficient_freq = + (ddcc_status >> 8) & 0xff; + } + /* Preserve min/max settings in case of re-init */ if (dev_priv->rps.max_freq_softlimit == 0) dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; - if (dev_priv->rps.min_freq_softlimit == 0) - dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; + if (dev_priv->rps.min_freq_softlimit == 0) { + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + dev_priv->rps.min_freq_softlimit = + dev_priv->rps.efficient_freq; + else + dev_priv->rps.min_freq_softlimit = + dev_priv->rps.min_freq; + } } static void gen9_enable_rps(struct drm_device *dev) @@ -4673,7 +4693,7 @@ static void gen8_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; - uint32_t rc6_mask = 0, rp_state_cap; + uint32_t rc6_mask = 0; int unused; /* 1a: Software RC state - RC0 */ @@ -4686,8 +4706,8 @@ static void gen8_enable_rps(struct drm_device *dev) /* 2a: Disable RC states. */ I915_WRITE(GEN6_RC_CONTROL, 0); - rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - parse_rp_state_cap(dev_priv, rp_state_cap); + /* Initialize rps frequencies */ + gen6_init_rps_frequencies(dev); /* 2b: Program RC6 thresholds.*/ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); @@ -4754,7 +4774,6 @@ static void gen6_enable_rps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; - u32 rp_state_cap; u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; u32 gtfifodbg; int rc6_mode; @@ -4778,9 +4797,8 @@ static void gen6_enable_rps(struct drm_device *dev) gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); - rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - - parse_rp_state_cap(dev_priv, rp_state_cap); + /* Initialize rps frequencies */ + gen6_init_rps_frequencies(dev); /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); -- GitLab From f4ab408c4b55fcbc447cf0288456613bad824626 Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Wed, 19 Nov 2014 14:21:53 -0800 Subject: [PATCH 5479/9457] drm/i915: Keep min freq above floor on HSW/BDW Set the min_freq_softlimit to max(RPe, 450MHz). Setting a floor can ensure a minimum experience level. The 450MHz value came from a power and performance study of various types of workloads (3D, Media, GPGPU, idle, etc). v2: rebased Signed-off-by: Tom O'Rourke Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index eb2a0a85e057..6d0795d3b2e4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4643,7 +4643,8 @@ static void gen6_init_rps_frequencies(struct drm_device *dev) if (dev_priv->rps.min_freq_softlimit == 0) { if (IS_HASWELL(dev) || IS_BROADWELL(dev)) dev_priv->rps.min_freq_softlimit = - dev_priv->rps.efficient_freq; + /* max(RPe, 450 MHz) */ + max(dev_priv->rps.efficient_freq, (u8) 9); else dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; -- GitLab From c7f3153a61b543830d397cda8918ef2d6330c6c7 Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Wed, 19 Nov 2014 14:21:54 -0800 Subject: [PATCH 5480/9457] drm/i915: change initial rps frequency for gen8 In gen8_enable_rps, change the initial rps setting to the min_freq_softlimit (same as gen6_enable_rps). Signed-off-by: Tom O'Rourke Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6d0795d3b2e4..70e75477f8fc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4766,7 +4766,8 @@ static void gen8_enable_rps(struct drm_device *dev) /* 6: Ring frequency + overclocking (our driver does this later */ - gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); + dev_priv->rps.power = HIGH_POWER; /* force a reset */ + gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } -- GitLab From 6985b352183fc00df22a769892a24bc438db5357 Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Wed, 19 Nov 2014 14:21:55 -0800 Subject: [PATCH 5481/9457] drm/i915: Update ring freq for full gpu freq range In __gen6_update_ring_freq, use the full range of possible gpu frequencies from max_freq to min_freq. The actual gpu frequency could be outside the range from max_freq_softlimit to min_freq_softlimit due to power/thermal constraints. Signed-off-by: Tom O'Rourke Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 70e75477f8fc..f103ffffc599 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4915,9 +4915,9 @@ static void __gen6_update_ring_freq(struct drm_device *dev) * to use for memory access. We do this by specifying the IA frequency * the PCU should use as a reference to determine the ring frequency. */ - for (gpu_freq = dev_priv->rps.max_freq_softlimit; gpu_freq >= dev_priv->rps.min_freq_softlimit; + for (gpu_freq = dev_priv->rps.max_freq; gpu_freq >= dev_priv->rps.min_freq; gpu_freq--) { - int diff = dev_priv->rps.max_freq_softlimit - gpu_freq; + int diff = dev_priv->rps.max_freq - gpu_freq; unsigned int ia_freq = 0, ring_freq = 0; if (INTEL_INFO(dev)->gen >= 8) { -- GitLab From 656bfa3afc14e45e2d9e1624bf60d79b3beb12f2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 20 Nov 2014 09:26:30 +0100 Subject: [PATCH 5482/9457] drm/i915: Pin tiled objects for L-shaped configs Let's just throw in the towel on this one and take the cheap way out. Based on a patch from Chris Wilson, but checking for a different bit. Chris' patch checked for even bank layout, this one here for a magic bit. Given the evidence we've gathered (not much) both work I think, but checking for the magic bit might be more accurate. Anyway, works on my gm45 here. For paranoi restrict to gen4 (and mobile), since we've only ever seen this on gm45 and i965gm. Also add some debugfs output so that we can skip the tiled swapping tests properly in these cases. v2: Clean up the quirk'ed pin count in free_object to avoid upsetting the WARN_ON. Spotted by Chris. Cc: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=28813 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45092 Signed-off-by: Daniel Vetter Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_tiling.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 2 ++ 5 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index bb1458381dc4..a27b1e47e89c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1983,6 +1983,8 @@ static int i915_swizzle_info(struct seq_file *m, void *data) if (IS_GEN3(dev) || IS_GEN4(dev)) { seq_printf(m, "DDC = 0x%08x\n", I915_READ(DCC)); + seq_printf(m, "DDC2 = 0x%08x\n", + I915_READ(DCC2)); seq_printf(m, "C0DRB3 = 0x%04x\n", I915_READ16(C0DRB3)); seq_printf(m, "C1DRB3 = 0x%04x\n", @@ -2005,6 +2007,10 @@ static int i915_swizzle_info(struct seq_file *m, void *data) seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", I915_READ(DISP_ARB_CTL)); } + + if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) + seq_puts(m, "L-shaped memory detected\n"); + intel_runtime_pm_put(dev_priv); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 02b3cb32c8a6..5448ce9d1490 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -764,6 +764,7 @@ enum intel_sbi_destination { #define QUIRK_INVERT_BRIGHTNESS (1<<2) #define QUIRK_BACKLIGHT_PRESENT (1<<3) #define QUIRK_PIPEB_FORCE (1<<4) +#define QUIRK_PIN_SWIZZLED_PAGES (1<<5) struct intel_fbdev; struct intel_fbc_work; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 480d00e672fa..3c64eb6abf2d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2176,6 +2176,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj); + if (obj->tiling_mode != I915_TILING_NONE && + dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) + i915_gem_object_pin_pages(obj); + return 0; err_pages: @@ -4374,6 +4378,7 @@ int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_madvise *args = data; struct drm_i915_gem_object *obj; int ret; @@ -4401,6 +4406,15 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, goto out; } + if (obj->pages && + obj->tiling_mode != I915_TILING_NONE && + dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { + if (obj->madv == I915_MADV_WILLNEED) + i915_gem_object_unpin_pages(obj); + if (args->madv == I915_MADV_WILLNEED) + i915_gem_object_pin_pages(obj); + } + if (obj->madv != __I915_MADV_PURGED) obj->madv = args->madv; @@ -4550,6 +4564,11 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) WARN_ON(obj->frontbuffer_bits); + if (obj->pages && obj->madv == I915_MADV_WILLNEED && + dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES && + obj->tiling_mode != I915_TILING_NONE) + i915_gem_object_unpin_pages(obj); + if (WARN_ON(obj->pages_pin_count)) obj->pages_pin_count = 0; if (discard_backing_storage(obj)) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index cd7f4734c9f8..4727a4e2c87c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -178,6 +178,15 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) } break; } + + /* check for L-shaped memory aka modified enhanced addressing */ + if (IS_GEN4(dev)) { + uint32_t ddc2 = I915_READ(DCC2); + + if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE)) + dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES; + } + if (dcc == 0xffffffff) { DRM_ERROR("Couldn't read from MCHBAR. " "Disabling tiling.\n"); @@ -380,6 +389,15 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, ret = i915_gem_object_ggtt_unbind(obj); if (ret == 0) { + if (obj->pages && + obj->madv == I915_MADV_WILLNEED && + dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { + if (args->tiling_mode == I915_TILING_NONE) + i915_gem_object_unpin_pages(obj); + if (obj->tiling_mode == I915_TILING_NONE) + i915_gem_object_pin_pages(obj); + } + obj->fence_dirty = obj->last_fenced_seqno || obj->fence_reg != I915_FENCE_REG_NONE; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3a51c05ca552..3102907a96a7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2043,6 +2043,8 @@ enum punit_power_well { #define DCC_ADDRESSING_MODE_MASK (3 << 0) #define DCC_CHANNEL_XOR_DISABLE (1 << 10) #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) +#define DCC2 0x10204 +#define DCC2_MODIFIED_ENHANCED_DISABLE (1 << 20) /* Pineview MCH register contains DDR3 setting */ #define CSHRDDR3CTL 0x101a8 -- GitLab From 6b312cd3668b066467228b51142d05b94c2ad7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 19 Nov 2014 20:07:42 +0200 Subject: [PATCH 5483/9457] drm/i915: Read power well status before other registers for drpc info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to read the status of the power wells right after taking forcewake for the other register reads makes little sense. Most of the time the power wells will still be up due to the recent forcewake. Instead do the power well status read first, and only then read the register needing forcewake. This way the reported power well status can actually reflect what's going on in the system. Cc: Deepak S Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a27b1e47e89c..f91e7f7c92af 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1240,11 +1240,12 @@ static int vlv_drpc_info(struct seq_file *m) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 rpmodectl1, rcctl1; + u32 rpmodectl1, rcctl1, pw_status; unsigned fw_rendercount = 0, fw_mediacount = 0; intel_runtime_pm_get(dev_priv); + pw_status = I915_READ(VLV_GTLC_PW_STATUS); rpmodectl1 = I915_READ(GEN6_RP_CONTROL); rcctl1 = I915_READ(GEN6_RC_CONTROL); @@ -1263,11 +1264,9 @@ static int vlv_drpc_info(struct seq_file *m) yesno(rcctl1 & (GEN7_RC_CTL_TO_MODE | GEN6_RC_CTL_EI_MODE(1)))); seq_printf(m, "Render Power Well: %s\n", - (I915_READ(VLV_GTLC_PW_STATUS) & - VLV_GTLC_PW_RENDER_STATUS_MASK) ? "Up" : "Down"); + (pw_status & VLV_GTLC_PW_RENDER_STATUS_MASK) ? "Up" : "Down"); seq_printf(m, "Media Power Well: %s\n", - (I915_READ(VLV_GTLC_PW_STATUS) & - VLV_GTLC_PW_MEDIA_STATUS_MASK) ? "Up" : "Down"); + (pw_status & VLV_GTLC_PW_MEDIA_STATUS_MASK) ? "Up" : "Down"); seq_printf(m, "Render RC6 residency since boot: %u\n", I915_READ(VLV_GT_RENDER_RC6)); -- GitLab From 982f405136a44754e884184d24b70d2d4cefcb7a Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 20:37:05 +0100 Subject: [PATCH 5484/9457] netfilter: Deletion of unnecessary checks before two function calls The functions free_percpu() and module_put() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Julian Anastasov Acked-by: Simon Horman Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipvs/ip_vs_ctl.c | 3 +-- net/netfilter/ipvs/ip_vs_pe.c | 3 +-- net/netfilter/ipvs/ip_vs_sched.c | 3 +-- net/netfilter/ipvs/ip_vs_sync.c | 3 +-- net/netfilter/nf_tables_api.c | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index ac7ba689efe7..b8295a430a56 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -465,8 +465,7 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc) static void ip_vs_service_free(struct ip_vs_service *svc) { - if (svc->stats.cpustats) - free_percpu(svc->stats.cpustats); + free_percpu(svc->stats.cpustats); kfree(svc); } diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c index 1a82b29ce8ea..0df17caa8af6 100644 --- a/net/netfilter/ipvs/ip_vs_pe.c +++ b/net/netfilter/ipvs/ip_vs_pe.c @@ -37,8 +37,7 @@ struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name) rcu_read_unlock(); return pe; } - if (pe->module) - module_put(pe->module); + module_put(pe->module); } rcu_read_unlock(); diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index 4dbcda6258bc..199760c71f39 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -104,8 +104,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name) mutex_unlock(&ip_vs_sched_mutex); return sched; } - if (sched->module) - module_put(sched->module); + module_put(sched->module); } mutex_unlock(&ip_vs_sched_mutex); diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 7162c86fd50d..c47ffd7a0a70 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -820,8 +820,7 @@ ip_vs_conn_fill_param_sync(struct net *net, int af, union ip_vs_sync_conn *sc, p->pe_data = kmemdup(pe_data, pe_data_len, GFP_ATOMIC); if (!p->pe_data) { - if (p->pe->module) - module_put(p->pe->module); + module_put(p->pe->module); return -ENOMEM; } p->pe_data_len = pe_data_len; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 1ffb253c6a77..18a9daef22dd 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3674,8 +3674,7 @@ static int nf_tables_abort(struct sk_buff *skb) break; case NFT_MSG_NEWCHAIN: if (nft_trans_chain_update(trans)) { - if (nft_trans_chain_stats(trans)) - free_percpu(nft_trans_chain_stats(trans)); + free_percpu(nft_trans_chain_stats(trans)); nft_trans_destroy(trans); } else { -- GitLab From beacd3e8ef237e077c8707395440813feef16d3f Mon Sep 17 00:00:00 2001 From: Marcelo Leitner Date: Thu, 6 Nov 2014 12:32:30 +0100 Subject: [PATCH 5485/9457] netfilter: nfnetlink_log: Make use of pr_fmt where applicable Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_log.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 51996ece3d2a..405cf5879320 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -12,6 +12,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1063,19 +1066,19 @@ static int __init nfnetlink_log_init(void) netlink_register_notifier(&nfulnl_rtnl_notifier); status = nfnetlink_subsys_register(&nfulnl_subsys); if (status < 0) { - pr_err("log: failed to create netlink socket\n"); + pr_err("failed to create netlink socket\n"); goto cleanup_netlink_notifier; } status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger); if (status < 0) { - pr_err("log: failed to register logger\n"); + pr_err("failed to register logger\n"); goto cleanup_subsys; } status = register_pernet_subsys(&nfnl_log_net_ops); if (status < 0) { - pr_err("log: failed to register pernet ops\n"); + pr_err("failed to register pernet ops\n"); goto cleanup_logger; } return status; -- GitLab From 565ccde9603f80c2278032df787d2069ddb2dcf7 Mon Sep 17 00:00:00 2001 From: Alex Pilon Date: Thu, 6 Nov 2014 19:50:40 -0500 Subject: [PATCH 5486/9457] scsi: mpt2sas: fix ioctl in comment Fix 'ioctl' spelling. Signed-off-by: Alex Pilon Acked-by: Sreekanth Reddy Signed-off-by: Jiri Kosina --- drivers/scsi/mpt2sas/mpt2sas_ctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h index 8b2ac1869dcc..60d76f435a68 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h @@ -224,7 +224,7 @@ struct mpt2_ioctl_eventreport { }; /** - * struct mpt2_ioctl_command - generic mpt firmware passthru ioclt + * struct mpt2_ioctl_command - generic mpt firmware passthru ioctl * @hdr - generic header * @timeout - command timeout in seconds. (if zero then use driver default * value). -- GitLab From eff264efeeb0898408e8c9df72d8a32621035bed Mon Sep 17 00:00:00 2001 From: Frans Klaver Date: Fri, 7 Nov 2014 15:53:44 +0100 Subject: [PATCH 5487/9457] kernel: trace: fix printk message s,produciton,production Signed-off-by: Frans Klaver Acked-by: Steven Rostedt Signed-off-by: Jiri Kosina --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8a528392b1f4..f3ef80c8914c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2028,7 +2028,7 @@ void trace_printk_init_buffers(void) pr_warning("** trace_printk() being used. Allocating extra memory. **\n"); pr_warning("** **\n"); pr_warning("** This means that this is a DEBUG kernel and it is **\n"); - pr_warning("** unsafe for produciton use. **\n"); + pr_warning("** unsafe for production use. **\n"); pr_warning("** **\n"); pr_warning("** If you see this message and you are not debugging **\n"); pr_warning("** the kernel, report this immediately to your vendor! **\n"); -- GitLab From 9aa505d20b3a3577bd4eeec79f70895153a1a474 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:47 +0200 Subject: [PATCH 5488/9457] ath10k: start using sk_buff_head Instead of using manual sk_buff linking via ->next use sk_buff_head. It's more robust, cleaner and there's plenty of helper functions in kernel already to manage sk_buff_head. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 213 ++++++++++------------- 1 file changed, 91 insertions(+), 122 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 52c630672718..f988a8db7bfd 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -301,27 +301,15 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) return msdu; } -static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb) -{ - struct sk_buff *next; - - while (skb) { - next = skb->next; - dev_kfree_skb_any(skb); - skb = next; - } -} - /* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, u8 **fw_desc, int *fw_desc_len, - struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, + struct sk_buff_head *amsdu, u32 *attention) { struct ath10k *ar = htt->ar; int msdu_len, msdu_chaining = 0; - struct sk_buff *msdu, *next; + struct sk_buff *msdu; struct htt_rx_desc *rx_desc; lockdep_assert_held(&htt->rx_ring.lock); @@ -331,10 +319,19 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, return -1; } - msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt); - while (msdu) { + for (;;) { int last_msdu, msdu_len_invalid, msdu_chained; + msdu = ath10k_htt_rx_netbuf_pop(htt); + if (!msdu) { + ath10k_err(ar, "failed to pop msdu\n"); + __skb_queue_purge(amsdu); + htt->rx_confused = true; + break; + } + + __skb_queue_tail(amsdu, msdu); + rx_desc = (struct htt_rx_desc *)msdu->data; /* FIXME: we must report msdu payload since this is what caller @@ -352,10 +349,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, */ if (!(__le32_to_cpu(rx_desc->attention.flags) & RX_ATTENTION_FLAGS_MSDU_DONE)) { - ath10k_htt_rx_free_msdu_chain(*head_msdu); - *head_msdu = NULL; - msdu = NULL; - ath10k_err(ar, "htt rx stopped. cannot recover\n"); + ath10k_err(ar, "popped an incomplete msdu\n"); + __skb_queue_purge(amsdu); htt->rx_confused = true; break; } @@ -421,25 +416,20 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, skb_put(msdu, min(msdu_len, HTT_RX_MSDU_SIZE)); msdu_len -= msdu->len; - /* FIXME: Do chained buffers include htt_rx_desc or not? */ + /* Note: Chained buffers do not contain rx descriptor */ while (msdu_chained--) { - struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); - - if (!next) { + msdu = ath10k_htt_rx_netbuf_pop(htt); + if (!msdu) { ath10k_warn(ar, "failed to pop chained msdu\n"); - ath10k_htt_rx_free_msdu_chain(*head_msdu); - *head_msdu = NULL; - msdu = NULL; + __skb_queue_purge(amsdu); htt->rx_confused = true; break; } - skb_trim(next, 0); - skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE)); - msdu_len -= next->len; - - msdu->next = next; - msdu = next; + __skb_queue_tail(amsdu, msdu); + skb_trim(msdu, 0); + skb_put(msdu, min(msdu_len, HTT_RX_BUF_SIZE)); + msdu_len -= msdu->len; msdu_chaining = 1; } @@ -448,18 +438,12 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, trace_ath10k_htt_rx_desc(ar, &rx_desc->attention, sizeof(*rx_desc) - sizeof(u32)); - if (last_msdu) { - msdu->next = NULL; - break; - } - next = ath10k_htt_rx_netbuf_pop(htt); - msdu->next = next; - msdu = next; + if (last_msdu) + break; } - *tail_msdu = msdu; - if (*head_msdu == NULL) + if (skb_queue_empty(amsdu)) msdu_chaining = -1; /* @@ -915,11 +899,11 @@ static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr) static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, struct ieee80211_rx_status *rx_status, - struct sk_buff *skb_in) + struct sk_buff_head *amsdu) { struct ath10k *ar = htt->ar; struct htt_rx_desc *rxd; - struct sk_buff *skb = skb_in; + struct sk_buff *skb; struct sk_buff *first; enum rx_msdu_decap_format fmt; enum htt_rx_mpdu_encrypt_type enctype; @@ -927,7 +911,9 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos; unsigned int hdr_len; - rxd = (void *)skb->data - sizeof(*rxd); + first = skb_peek(amsdu); + + rxd = (void *)first->data - sizeof(*rxd); enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), RX_MPDU_START_INFO0_ENCRYPT_TYPE); @@ -936,8 +922,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, memcpy(hdr_buf, hdr, hdr_len); hdr = (struct ieee80211_hdr *)hdr_buf; - first = skb; - while (skb) { + while ((skb = __skb_dequeue(amsdu))) { void *decap_hdr; int len; @@ -1005,18 +990,15 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, break; } - skb_in = skb; - ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype, fmt, + ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype, fmt, false); - skb = skb->next; - skb_in->next = NULL; - if (skb) - rx_status->flag |= RX_FLAG_AMSDU_MORE; - else + if (skb_queue_empty(amsdu)) rx_status->flag &= ~RX_FLAG_AMSDU_MORE; + else + rx_status->flag |= RX_FLAG_AMSDU_MORE; - ath10k_process_rx(htt->ar, rx_status, skb_in); + ath10k_process_rx(htt->ar, rx_status, skb); } /* FIXME: It might be nice to re-assemble the A-MSDU when there's a @@ -1035,13 +1017,6 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, int hdr_len; void *rfc1042; - /* This shouldn't happen. If it does than it may be a FW bug. */ - if (skb->next) { - ath10k_warn(ar, "htt rx received chained non A-MSDU frame\n"); - ath10k_htt_rx_free_msdu_chain(skb->next); - skb->next = NULL; - } - rxd = (void *)skb->data - sizeof(*rxd); fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), RX_MSDU_START_INFO1_DECAP_FORMAT); @@ -1127,10 +1102,9 @@ static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) return CHECKSUM_UNNECESSARY; } -static int ath10k_unchain_msdu(struct sk_buff *msdu_head) +static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) { - struct sk_buff *next = msdu_head->next; - struct sk_buff *to_free = next; + struct sk_buff *skb, *first; int space; int total_len = 0; @@ -1141,40 +1115,33 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head) * skb? */ - msdu_head->next = NULL; + first = __skb_dequeue(amsdu); /* Allocate total length all at once. */ - while (next) { - total_len += next->len; - next = next->next; - } + skb_queue_walk(amsdu, skb) + total_len += skb->len; - space = total_len - skb_tailroom(msdu_head); + space = total_len - skb_tailroom(first); if ((space > 0) && - (pskb_expand_head(msdu_head, 0, space, GFP_ATOMIC) < 0)) { + (pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0)) { /* TODO: bump some rx-oom error stat */ /* put it back together so we can free the * whole list at once. */ - msdu_head->next = to_free; + __skb_queue_head(amsdu, first); return -1; } /* Walk list again, copying contents into * msdu_head */ - next = to_free; - while (next) { - skb_copy_from_linear_data(next, skb_put(msdu_head, next->len), - next->len); - next = next->next; + while ((skb = __skb_dequeue(amsdu))) { + skb_copy_from_linear_data(skb, skb_put(first, skb->len), + skb->len); + dev_kfree_skb_any(skb); } - /* If here, we have consolidated skb. Free the - * fragments and pass the main skb on up the - * stack. - */ - ath10k_htt_rx_free_msdu_chain(to_free); + __skb_queue_head(amsdu, first); return 0; } @@ -1223,6 +1190,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct ath10k *ar = htt->ar; struct ieee80211_rx_status *rx_status = &htt->rx_status; struct htt_rx_indication_mpdu_range *mpdu_ranges; + struct sk_buff_head amsdu; struct ieee80211_hdr *hdr; int num_mpdu_ranges; u32 attention; @@ -1271,35 +1239,28 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, for (i = 0; i < num_mpdu_ranges; i++) { for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { - struct sk_buff *msdu_head, *msdu_tail; - attention = 0; - msdu_head = NULL; - msdu_tail = NULL; - ret = ath10k_htt_rx_amsdu_pop(htt, - &fw_desc, - &fw_desc_len, - &msdu_head, - &msdu_tail, + __skb_queue_head_init(&amsdu); + ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, + &fw_desc_len, &amsdu, &attention); if (ret < 0) { ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n", ret); - ath10k_htt_rx_free_msdu_chain(msdu_head); + __skb_queue_purge(&amsdu); continue; } - if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, + if (!ath10k_htt_rx_amsdu_allowed(htt, skb_peek(&amsdu), channel_set, attention)) { - ath10k_htt_rx_free_msdu_chain(msdu_head); + __skb_queue_purge(&amsdu); continue; } - if (ret > 0 && - ath10k_unchain_msdu(msdu_head) < 0) { - ath10k_htt_rx_free_msdu_chain(msdu_head); + if (ret > 0 && ath10k_unchain_msdu(&amsdu) < 0) { + __skb_queue_purge(&amsdu); continue; } @@ -1313,12 +1274,13 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, else rx_status->flag &= ~RX_FLAG_MMIC_ERROR; - hdr = ath10k_htt_rx_skb_get_hdr(msdu_head); + hdr = ath10k_htt_rx_skb_get_hdr(skb_peek(&amsdu)); if (ath10k_htt_rx_hdr_is_amsdu(hdr)) - ath10k_htt_rx_amsdu(htt, rx_status, msdu_head); + ath10k_htt_rx_amsdu(htt, rx_status, &amsdu); else - ath10k_htt_rx_msdu(htt, rx_status, msdu_head); + ath10k_htt_rx_msdu(htt, rx_status, + __skb_dequeue(&amsdu)); } } @@ -1329,12 +1291,13 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, struct htt_rx_fragment_indication *frag) { struct ath10k *ar = htt->ar; - struct sk_buff *msdu_head, *msdu_tail; + struct sk_buff *msdu; enum htt_rx_mpdu_encrypt_type enctype; struct htt_rx_desc *rxd; enum rx_msdu_decap_format fmt; struct ieee80211_rx_status *rx_status = &htt->rx_status; struct ieee80211_hdr *hdr; + struct sk_buff_head amsdu; int ret; bool tkip_mic_err; bool decrypt_err; @@ -1346,13 +1309,11 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes); fw_desc = (u8 *)frag->fw_msdu_rx_desc; - msdu_head = NULL; - msdu_tail = NULL; + __skb_queue_head_init(&amsdu); spin_lock_bh(&htt->rx_ring.lock); ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, - &msdu_head, &msdu_tail, - &attention); + &amsdu, &attention); spin_unlock_bh(&htt->rx_ring.lock); tasklet_schedule(&htt->rx_replenish_task); @@ -1362,15 +1323,23 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, if (ret) { ath10k_warn(ar, "failed to pop amsdu from httr rx ring for fragmented rx %d\n", ret); - ath10k_htt_rx_free_msdu_chain(msdu_head); + __skb_queue_purge(&amsdu); return; } + if (skb_queue_len(&amsdu) != 1) { + ath10k_warn(ar, "failed to pop frag amsdu: too many msdus\n"); + __skb_queue_purge(&amsdu); + return; + } + + msdu = __skb_dequeue(&amsdu); + /* FIXME: implement signal strength */ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; - hdr = (struct ieee80211_hdr *)msdu_head->data; - rxd = (void *)msdu_head->data - sizeof(*rxd); + hdr = (struct ieee80211_hdr *)msdu->data; + rxd = (void *)msdu->data - sizeof(*rxd); tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), @@ -1378,22 +1347,22 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, if (fmt != RX_MSDU_DECAP_RAW) { ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n"); - dev_kfree_skb_any(msdu_head); + dev_kfree_skb_any(msdu); goto end; } enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), RX_MPDU_START_INFO0_ENCRYPT_TYPE); - ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype, fmt, + ath10k_htt_rx_h_protected(htt, rx_status, msdu, enctype, fmt, true); - msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); + msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); if (tkip_mic_err) ath10k_warn(ar, "tkip mic error\n"); if (decrypt_err) { ath10k_warn(ar, "decryption err in fragmented rx\n"); - dev_kfree_skb_any(msdu_head); + dev_kfree_skb_any(msdu); goto end; } @@ -1402,11 +1371,11 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, paramlen = ath10k_htt_rx_crypto_param_len(ar, enctype); /* It is more efficient to move the header than the payload */ - memmove((void *)msdu_head->data + paramlen, - (void *)msdu_head->data, + memmove((void *)msdu->data + paramlen, + (void *)msdu->data, hdrlen); - skb_pull(msdu_head, paramlen); - hdr = (struct ieee80211_hdr *)msdu_head->data; + skb_pull(msdu, paramlen); + hdr = (struct ieee80211_hdr *)msdu->data; } /* remove trailing FCS */ @@ -1420,17 +1389,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) trim += MICHAEL_MIC_LEN; - if (trim > msdu_head->len) { + if (trim > msdu->len) { ath10k_warn(ar, "htt rx fragment: trailer longer than the frame itself? drop\n"); - dev_kfree_skb_any(msdu_head); + dev_kfree_skb_any(msdu); goto end; } - skb_trim(msdu_head, msdu_head->len - trim); + skb_trim(msdu, msdu->len - trim); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ", - msdu_head->data, msdu_head->len); - ath10k_process_rx(htt->ar, rx_status, msdu_head); + msdu->data, msdu->len); + ath10k_process_rx(htt->ar, rx_status, msdu); end: if (fw_desc_len > 0) { -- GitLab From d540690d3ab7f7a19610649c66fa5e670091c7fb Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:47 +0200 Subject: [PATCH 5489/9457] ath10k: simplify Rx loop Since htt_rx_mpdu_status isn't used anymore (instead attention flags are used) simplify the loop. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 80 ++++++++++++------------ 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index f988a8db7bfd..5edeac00b624 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1197,8 +1197,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, int fw_desc_len; u8 *fw_desc; bool channel_set; - int i, j; - int ret; + int i, ret, mpdu_count = 0; lockdep_assert_held(&htt->rx_ring.lock); @@ -1237,51 +1236,50 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, (sizeof(struct htt_rx_indication_mpdu_range) * num_mpdu_ranges)); - for (i = 0; i < num_mpdu_ranges; i++) { - for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { - attention = 0; - __skb_queue_head_init(&amsdu); - ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, - &fw_desc_len, &amsdu, - &attention); - - if (ret < 0) { - ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n", - ret); - __skb_queue_purge(&amsdu); - continue; - } + for (i = 0; i < num_mpdu_ranges; i++) + mpdu_count += mpdu_ranges[i].mpdu_count; + + while (mpdu_count--) { + attention = 0; + __skb_queue_head_init(&amsdu); + ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, + &fw_desc_len, &amsdu, + &attention); + if (ret < 0) { + ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n", + ret); + __skb_queue_purge(&amsdu); + continue; + } - if (!ath10k_htt_rx_amsdu_allowed(htt, skb_peek(&amsdu), - channel_set, - attention)) { - __skb_queue_purge(&amsdu); - continue; - } + if (!ath10k_htt_rx_amsdu_allowed(htt, skb_peek(&amsdu), + channel_set, attention)) { + __skb_queue_purge(&amsdu); + continue; + } - if (ret > 0 && ath10k_unchain_msdu(&amsdu) < 0) { - __skb_queue_purge(&amsdu); - continue; - } + if (ret > 0 && ath10k_unchain_msdu(&amsdu) < 0) { + __skb_queue_purge(&amsdu); + continue; + } - if (attention & RX_ATTENTION_FLAGS_FCS_ERR) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - else - rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC; + if (attention & RX_ATTENTION_FLAGS_FCS_ERR) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + else + rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC; - if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) - rx_status->flag |= RX_FLAG_MMIC_ERROR; - else - rx_status->flag &= ~RX_FLAG_MMIC_ERROR; + if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) + rx_status->flag |= RX_FLAG_MMIC_ERROR; + else + rx_status->flag &= ~RX_FLAG_MMIC_ERROR; - hdr = ath10k_htt_rx_skb_get_hdr(skb_peek(&amsdu)); + hdr = ath10k_htt_rx_skb_get_hdr(skb_peek(&amsdu)); - if (ath10k_htt_rx_hdr_is_amsdu(hdr)) - ath10k_htt_rx_amsdu(htt, rx_status, &amsdu); - else - ath10k_htt_rx_msdu(htt, rx_status, - __skb_dequeue(&amsdu)); - } + if (ath10k_htt_rx_hdr_is_amsdu(hdr)) + ath10k_htt_rx_amsdu(htt, rx_status, &amsdu); + else + ath10k_htt_rx_msdu(htt, rx_status, + __skb_dequeue(&amsdu)); } tasklet_schedule(&htt->rx_replenish_task); -- GitLab From e0bd7513bbc85a7714bb456641bd065ddfafe008 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:48 +0200 Subject: [PATCH 5490/9457] ath10k: refactor htt->rx_confused Make the rx_confused be handled by the rx indication handlers instead of the buffer popping function. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 29 ++++++++++-------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 5edeac00b624..8255bd93ead2 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -314,20 +314,13 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, lockdep_assert_held(&htt->rx_ring.lock); - if (htt->rx_confused) { - ath10k_warn(ar, "htt is confused. refusing rx\n"); - return -1; - } - for (;;) { int last_msdu, msdu_len_invalid, msdu_chained; msdu = ath10k_htt_rx_netbuf_pop(htt); if (!msdu) { - ath10k_err(ar, "failed to pop msdu\n"); __skb_queue_purge(amsdu); - htt->rx_confused = true; - break; + return -ENOENT; } __skb_queue_tail(amsdu, msdu); @@ -349,10 +342,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, */ if (!(__le32_to_cpu(rx_desc->attention.flags) & RX_ATTENTION_FLAGS_MSDU_DONE)) { - ath10k_err(ar, "popped an incomplete msdu\n"); __skb_queue_purge(amsdu); - htt->rx_confused = true; - break; + return -EIO; } *attention |= __le32_to_cpu(rx_desc->attention.flags) & @@ -420,10 +411,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, while (msdu_chained--) { msdu = ath10k_htt_rx_netbuf_pop(htt); if (!msdu) { - ath10k_warn(ar, "failed to pop chained msdu\n"); __skb_queue_purge(amsdu); - htt->rx_confused = true; - break; + return -ENOENT; } __skb_queue_tail(amsdu, msdu); @@ -1201,6 +1190,9 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, lockdep_assert_held(&htt->rx_ring.lock); + if (htt->rx_confused) + return; + fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes); fw_desc = (u8 *)&rx->fw_desc; @@ -1246,10 +1238,13 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, &fw_desc_len, &amsdu, &attention); if (ret < 0) { - ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n", - ret); + ath10k_warn(ar, "rx ring became corrupted: %d\n", ret); __skb_queue_purge(&amsdu); - continue; + /* FIXME: It's probably a good idea to reboot the + * device instead of leaving it inoperable. + */ + htt->rx_confused = true; + break; } if (!ath10k_htt_rx_amsdu_allowed(htt, skb_peek(&amsdu), -- GitLab From 581c25f82ff4a7a8199e33961276cae3e801f05d Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:48 +0200 Subject: [PATCH 5491/9457] ath10k: unify rx undecapping This creates a single, common path for MSDU, A-MSDU and fragmented Rx. Hopefully this will make it easier to understand Rx path and make it easier to work with. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 738 +++++++++++++---------- 1 file changed, 412 insertions(+), 326 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 8255bd93ead2..6abb3b6a348f 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -601,35 +601,6 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar, return 0; } -/* Applies for first msdu in chain, before altering it. */ -static struct ieee80211_hdr *ath10k_htt_rx_skb_get_hdr(struct sk_buff *skb) -{ - struct htt_rx_desc *rxd; - enum rx_msdu_decap_format fmt; - - rxd = (void *)skb->data - sizeof(*rxd); - fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), - RX_MSDU_START_INFO1_DECAP_FORMAT); - - if (fmt == RX_MSDU_DECAP_RAW) - return (void *)skb->data; - - return (void *)skb->data - RX_HTT_HDR_STATUS_LEN; -} - -/* This function only applies for first msdu in an msdu chain */ -static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr) -{ - u8 *qc; - - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); - if (qc[0] & 0x80) - return true; - } - return false; -} - struct rfc1042_hdr { u8 llc_dsap; u8 llc_ssap; @@ -755,41 +726,6 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, } } -static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt, - struct ieee80211_rx_status *rx_status, - struct sk_buff *skb, - enum htt_rx_mpdu_encrypt_type enctype, - enum rx_msdu_decap_format fmt, - bool dot11frag) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - rx_status->flag &= ~(RX_FLAG_DECRYPTED | - RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED); - - if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) - return; - - /* - * There's no explicit rx descriptor flag to indicate whether a given - * frame has been decrypted or not. We're forced to use the decap - * format as an implicit indication. However fragmentation rx is always - * raw and it probably never reports undecrypted raws. - * - * This makes sure sniffed frames are reported as-is without stripping - * the protected flag. - */ - if (fmt == RX_MSDU_DECAP_RAW && !dot11frag) - return; - - rx_status->flag |= RX_FLAG_DECRYPTED | - RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED; - hdr->frame_control = __cpu_to_le16(__le16_to_cpu(hdr->frame_control) & - ~IEEE80211_FCTL_PROTECTED); -} - static bool ath10k_htt_rx_h_channel(struct ath10k *ar, struct ieee80211_rx_status *status) { @@ -886,178 +822,263 @@ static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr) return round_up(ieee80211_hdrlen(hdr->frame_control), 4); } -static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, - struct ieee80211_rx_status *rx_status, - struct sk_buff_head *amsdu) +static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + enum htt_rx_mpdu_encrypt_type enctype, + bool is_decrypted) { - struct ath10k *ar = htt->ar; + struct ieee80211_hdr *hdr; struct htt_rx_desc *rxd; - struct sk_buff *skb; - struct sk_buff *first; - enum rx_msdu_decap_format fmt; - enum htt_rx_mpdu_encrypt_type enctype; + size_t hdr_len; + size_t crypto_len; + bool is_first; + bool is_last; + + rxd = (void *)msdu->data - sizeof(*rxd); + is_first = !!(rxd->msdu_end.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); + is_last = !!(rxd->msdu_end.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); + + /* Delivered decapped frame: + * [802.11 header] + * [crypto param] <-- can be trimmed if !fcs_err && + * !decrypt_err && !peer_idx_invalid + * [amsdu header] <-- only if A-MSDU + * [rfc1042/llc] + * [payload] + * [FCS] <-- at end, needs to be trimmed + */ + + /* This probably shouldn't happen but warn just in case */ + if (unlikely(WARN_ON_ONCE(!is_first))) + return; + + /* This probably shouldn't happen but warn just in case */ + if (unlikely(WARN_ON_ONCE(!(is_first && is_last)))) + return; + + skb_trim(msdu, msdu->len - FCS_LEN); + + /* In most cases this will be true for sniffed frames. It makes sense + * to deliver them as-is without stripping the crypto param. This would + * also make sense for software based decryption (which is not + * implemented in ath10k). + * + * If there's no error then the frame is decrypted. At least that is + * the case for frames that come in via fragmented rx indication. + */ + if (!is_decrypted) + return; + + /* The payload is decrypted so strip crypto params. Start from tail + * since hdr is used to compute some stuff. + */ + + hdr = (void *)msdu->data; + + /* Tail */ + skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype)); + + /* MMIC */ + if (!ieee80211_has_morefrags(hdr->frame_control) && + enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) + skb_trim(msdu, msdu->len - 8); + + /* Head */ + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); + + memmove((void *)msdu->data + crypto_len, + (void *)msdu->data, hdr_len); + skb_pull(msdu, crypto_len); +} + +static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + const u8 first_hdr[64]) +{ struct ieee80211_hdr *hdr; - u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos; - unsigned int hdr_len; + size_t hdr_len; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; - first = skb_peek(amsdu); + /* Delivered decapped frame: + * [nwifi 802.11 header] <-- replaced with 802.11 hdr + * [rfc1042/llc] + * + * Note: The nwifi header doesn't have QoS Control and is + * (always?) a 3addr frame. + * + * Note2: There's no A-MSDU subframe header. Even if it's part + * of an A-MSDU. + */ - rxd = (void *)first->data - sizeof(*rxd); - enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), - RX_MPDU_START_INFO0_ENCRYPT_TYPE); + /* pull decapped header and copy SA & DA */ + hdr = (struct ieee80211_hdr *)msdu->data; + hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); + ether_addr_copy(da, ieee80211_get_DA(hdr)); + ether_addr_copy(sa, ieee80211_get_SA(hdr)); + skb_pull(msdu, hdr_len); - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; + /* push original 802.11 header */ + hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(hdr_buf, hdr, hdr_len); - hdr = (struct ieee80211_hdr *)hdr_buf; + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); - while ((skb = __skb_dequeue(amsdu))) { - void *decap_hdr; - int len; - - rxd = (void *)skb->data - sizeof(*rxd); - fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), - RX_MSDU_START_INFO1_DECAP_FORMAT); - decap_hdr = (void *)rxd->rx_hdr_status; - - skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); - - /* First frame in an A-MSDU chain has more decapped data. */ - if (skb == first) { - len = round_up(ieee80211_hdrlen(hdr->frame_control), 4); - len += round_up(ath10k_htt_rx_crypto_param_len(ar, - enctype), 4); - decap_hdr += len; - } + /* original 802.11 header has a different DA and in + * case of 4addr it may also have different SA + */ + hdr = (struct ieee80211_hdr *)msdu->data; + ether_addr_copy(ieee80211_get_DA(hdr), da); + ether_addr_copy(ieee80211_get_SA(hdr), sa); +} - switch (fmt) { - case RX_MSDU_DECAP_RAW: - /* remove trailing FCS */ - skb_trim(skb, skb->len - FCS_LEN); - break; - case RX_MSDU_DECAP_NATIVE_WIFI: - /* pull decapped header and copy SA & DA */ - hdr = (struct ieee80211_hdr *)skb->data; - hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); - ether_addr_copy(da, ieee80211_get_DA(hdr)); - ether_addr_copy(sa, ieee80211_get_SA(hdr)); - skb_pull(skb, hdr_len); - - /* push original 802.11 header */ - hdr = (struct ieee80211_hdr *)hdr_buf; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); - - /* original A-MSDU header has the bit set but we're - * not including A-MSDU subframe header */ - hdr = (struct ieee80211_hdr *)skb->data; - qos = ieee80211_get_qos_ctl(hdr); - qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - - /* original 802.11 header has a different DA and in - * case of 4addr it may also have different SA - */ - ether_addr_copy(ieee80211_get_DA(hdr), da); - ether_addr_copy(ieee80211_get_SA(hdr), sa); - break; - case RX_MSDU_DECAP_ETHERNET2_DIX: - /* strip ethernet header and insert decapped 802.11 - * header, amsdu subframe header and rfc1042 header */ +static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar, + struct sk_buff *msdu, + enum htt_rx_mpdu_encrypt_type enctype) +{ + struct ieee80211_hdr *hdr; + struct htt_rx_desc *rxd; + size_t hdr_len, crypto_len; + void *rfc1042; + bool is_first, is_last, is_amsdu; - len = 0; - len += sizeof(struct rfc1042_hdr); - len += sizeof(struct amsdu_subframe_hdr); + rxd = (void *)msdu->data - sizeof(*rxd); + hdr = (void *)rxd->rx_hdr_status; - skb_pull(skb, sizeof(struct ethhdr)); - memcpy(skb_push(skb, len), decap_hdr, len); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); - break; - case RX_MSDU_DECAP_8023_SNAP_LLC: - /* insert decapped 802.11 header making a singly - * A-MSDU */ - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); - break; - } + is_first = !!(rxd->msdu_end.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); + is_last = !!(rxd->msdu_end.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); + is_amsdu = !(is_first && is_last); - ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype, fmt, - false); + rfc1042 = hdr; - if (skb_queue_empty(amsdu)) - rx_status->flag &= ~RX_FLAG_AMSDU_MORE; - else - rx_status->flag |= RX_FLAG_AMSDU_MORE; + if (is_first) { + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); - ath10k_process_rx(htt->ar, rx_status, skb); + rfc1042 += round_up(hdr_len, 4) + + round_up(crypto_len, 4); } - /* FIXME: It might be nice to re-assemble the A-MSDU when there's a - * monitor interface active for sniffing purposes. */ + if (is_amsdu) + rfc1042 += sizeof(struct amsdu_subframe_hdr); + + return rfc1042; } -static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, - struct ieee80211_rx_status *rx_status, - struct sk_buff *skb) +static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + const u8 first_hdr[64], + enum htt_rx_mpdu_encrypt_type enctype) { - struct ath10k *ar = htt->ar; - struct htt_rx_desc *rxd; struct ieee80211_hdr *hdr; - enum rx_msdu_decap_format fmt; - enum htt_rx_mpdu_encrypt_type enctype; - int hdr_len; + struct ethhdr *eth; + size_t hdr_len; void *rfc1042; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; - rxd = (void *)skb->data - sizeof(*rxd); - fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), - RX_MSDU_START_INFO1_DECAP_FORMAT); - enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), - RX_MPDU_START_INFO0_ENCRYPT_TYPE); - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; + /* Delivered decapped frame: + * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc + * [payload] + */ + + rfc1042 = ath10k_htt_rx_h_find_rfc1042(ar, msdu, enctype); + if (WARN_ON_ONCE(!rfc1042)) + return; + + /* pull decapped header and copy SA & DA */ + eth = (struct ethhdr *)msdu->data; + ether_addr_copy(da, eth->h_dest); + ether_addr_copy(sa, eth->h_source); + skb_pull(msdu, sizeof(struct ethhdr)); + + /* push rfc1042/llc/snap */ + memcpy(skb_push(msdu, sizeof(struct rfc1042_hdr)), rfc1042, + sizeof(struct rfc1042_hdr)); + + /* push original 802.11 header */ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + + /* original 802.11 header has a different DA and in + * case of 4addr it may also have different SA + */ + hdr = (struct ieee80211_hdr *)msdu->data; + ether_addr_copy(ieee80211_get_DA(hdr), da); + ether_addr_copy(ieee80211_get_SA(hdr), sa); +} + +static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + const u8 first_hdr[64]) +{ + struct ieee80211_hdr *hdr; + size_t hdr_len; + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr + * [rfc1042/llc] + * [payload] + */ + + skb_pull(msdu, sizeof(struct amsdu_subframe_hdr)); + + hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); +} - skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); +static void ath10k_htt_rx_h_undecap(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 first_hdr[64], + enum htt_rx_mpdu_encrypt_type enctype, + bool is_decrypted) +{ + struct htt_rx_desc *rxd; + enum rx_msdu_decap_format decap; + struct ieee80211_hdr *hdr; - switch (fmt) { + /* First msdu's decapped header: + * [802.11 header] <-- padded to 4 bytes long + * [crypto param] <-- padded to 4 bytes long + * [amsdu header] <-- only if A-MSDU + * [rfc1042/llc] + * + * Other (2nd, 3rd, ..) msdu's decapped header: + * [amsdu header] <-- only if A-MSDU + * [rfc1042/llc] + */ + + rxd = (void *)msdu->data - sizeof(*rxd); + hdr = (void *)rxd->rx_hdr_status; + decap = MS(__le32_to_cpu(rxd->msdu_start.info1), + RX_MSDU_START_INFO1_DECAP_FORMAT); + + switch (decap) { case RX_MSDU_DECAP_RAW: - /* remove trailing FCS */ - skb_trim(skb, skb->len - FCS_LEN); + ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype, + is_decrypted); break; case RX_MSDU_DECAP_NATIVE_WIFI: - /* Pull decapped header */ - hdr = (struct ieee80211_hdr *)skb->data; - hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); - skb_pull(skb, hdr_len); - - /* Push original header */ - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr); break; case RX_MSDU_DECAP_ETHERNET2_DIX: - /* strip ethernet header and insert decapped 802.11 header and - * rfc1042 header */ - - rfc1042 = hdr; - rfc1042 += roundup(hdr_len, 4); - rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(ar, - enctype), 4); - - skb_pull(skb, sizeof(struct ethhdr)); - memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)), - rfc1042, sizeof(struct rfc1042_hdr)); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype); break; case RX_MSDU_DECAP_8023_SNAP_LLC: - /* remove A-MSDU subframe header and insert - * decapped 802.11 header. rfc1042 header is already there */ - - skb_pull(skb, sizeof(struct amsdu_subframe_hdr)); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr); break; } - - ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype, fmt, false); - - ath10k_process_rx(htt->ar, rx_status, skb); } static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) @@ -1091,6 +1112,125 @@ static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) return CHECKSUM_UNNECESSARY; } +static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) +{ + msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); +} + +static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *status) +{ + struct sk_buff *first; + struct sk_buff *last; + struct sk_buff *msdu; + struct htt_rx_desc *rxd; + struct ieee80211_hdr *hdr; + enum htt_rx_mpdu_encrypt_type enctype; + u8 first_hdr[64]; + u8 *qos; + size_t hdr_len; + bool has_fcs_err; + bool has_crypto_err; + bool has_tkip_err; + bool has_peer_idx_invalid; + bool is_decrypted; + u32 attention; + + if (skb_queue_empty(amsdu)) + return; + + first = skb_peek(amsdu); + rxd = (void *)first->data - sizeof(*rxd); + + enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), + RX_MPDU_START_INFO0_ENCRYPT_TYPE); + + /* First MSDU's Rx descriptor in an A-MSDU contains full 802.11 + * decapped header. It'll be used for undecapping of each MSDU. + */ + hdr = (void *)rxd->rx_hdr_status; + hdr_len = ieee80211_hdrlen(hdr->frame_control); + memcpy(first_hdr, hdr, hdr_len); + + /* Each A-MSDU subframe will use the original header as the base and be + * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. + */ + hdr = (void *)first_hdr; + qos = ieee80211_get_qos_ctl(hdr); + qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + + /* Some attention flags are valid only in the last MSDU. */ + last = skb_peek_tail(amsdu); + rxd = (void *)last->data - sizeof(*rxd); + attention = __le32_to_cpu(rxd->attention.flags); + + has_fcs_err = !!(attention & RX_ATTENTION_FLAGS_FCS_ERR); + has_crypto_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); + has_tkip_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); + has_peer_idx_invalid = !!(attention & RX_ATTENTION_FLAGS_PEER_IDX_INVALID); + + /* Note: If hardware captures an encrypted frame that it can't decrypt, + * e.g. due to fcs error, missing peer or invalid key data it will + * report the frame as raw. + */ + is_decrypted = (enctype != HTT_RX_MPDU_ENCRYPT_NONE && + !has_fcs_err && + !has_crypto_err && + !has_peer_idx_invalid); + + /* Clear per-MPDU flags while leaving per-PPDU flags intact. */ + status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | + RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED | + RX_FLAG_IV_STRIPPED | + RX_FLAG_MMIC_STRIPPED); + + if (has_fcs_err) + status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (has_tkip_err) + status->flag |= RX_FLAG_MMIC_ERROR; + + if (is_decrypted) + status->flag |= RX_FLAG_DECRYPTED | + RX_FLAG_IV_STRIPPED | + RX_FLAG_MMIC_STRIPPED; + + skb_queue_walk(amsdu, msdu) { + ath10k_htt_rx_h_csum_offload(msdu); + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, + is_decrypted); + + /* Undecapping involves copying the original 802.11 header back + * to sk_buff. If frame is protected and hardware has decrypted + * it then remove the protected bit. + */ + if (!is_decrypted) + continue; + + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } +} + +static void ath10k_htt_rx_h_deliver(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *status) +{ + struct sk_buff *msdu; + + while ((msdu = __skb_dequeue(amsdu))) { + /* Setup per-MSDU flags */ + if (skb_queue_empty(amsdu)) + status->flag &= ~RX_FLAG_AMSDU_MORE; + else + status->flag |= RX_FLAG_AMSDU_MORE; + + ath10k_process_rx(ar, status, msdu); + } +} + static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) { struct sk_buff *skb, *first; @@ -1134,45 +1274,86 @@ static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) return 0; } -static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, - struct sk_buff *head, - bool channel_set, - u32 attention) +static void ath10k_htt_rx_h_unchain(struct ath10k *ar, + struct sk_buff_head *amsdu, + bool chained) { - struct ath10k *ar = htt->ar; + struct sk_buff *first; + struct htt_rx_desc *rxd; + enum rx_msdu_decap_format decap; - if (head->len == 0) { - ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt rx dropping due to zero-len\n"); - return false; - } + first = skb_peek(amsdu); + rxd = (void *)first->data - sizeof(*rxd); + decap = MS(__le32_to_cpu(rxd->msdu_start.info1), + RX_MSDU_START_INFO1_DECAP_FORMAT); - if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) { - ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt rx dropping due to decrypt-err\n"); - return false; + if (!chained) + return; + + /* FIXME: Current unchaining logic can only handle simple case of raw + * msdu chaining. If decapping is other than raw the chaining may be + * more complex and this isn't handled by the current code. Don't even + * try re-constructing such frames - it'll be pretty much garbage. + */ + if (decap != RX_MSDU_DECAP_RAW || + skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) { + __skb_queue_purge(amsdu); + return; } - if (!channel_set) { - ath10k_warn(ar, "no channel configured; ignoring frame!\n"); + ath10k_unchain_msdu(amsdu); +} + +static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *rx_status) +{ + struct sk_buff *msdu; + struct htt_rx_desc *rxd; + + msdu = skb_peek(amsdu); + rxd = (void *)msdu->data - sizeof(*rxd); + + /* FIXME: It might be a good idea to do some fuzzy-testing to drop + * invalid/dangerous frames. + */ + + if (!rx_status->freq) { + ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); return false; } - /* Skip mgmt frames while we handle this in WMI */ - if (attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { + /* Management frames are handled via WMI events. The pros of such + * approach is that channel is explicitly provided in WMI events + * whereas HTT doesn't provide channel information for Rxed frames. + */ + if (rxd->attention.flags & + __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE)) { ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); return false; } - if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { - ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt rx CAC running\n"); + if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx cac running\n"); return false; } return true; } +static void ath10k_htt_rx_h_filter(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *rx_status) +{ + if (skb_queue_empty(amsdu)) + return; + + if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status)) + return; + + __skb_queue_purge(amsdu); +} + static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct htt_rx_indication *rx) { @@ -1180,7 +1361,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct ieee80211_rx_status *rx_status = &htt->rx_status; struct htt_rx_indication_mpdu_range *mpdu_ranges; struct sk_buff_head amsdu; - struct ieee80211_hdr *hdr; int num_mpdu_ranges; u32 attention; int fw_desc_len; @@ -1247,34 +1427,10 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, break; } - if (!ath10k_htt_rx_amsdu_allowed(htt, skb_peek(&amsdu), - channel_set, attention)) { - __skb_queue_purge(&amsdu); - continue; - } - - if (ret > 0 && ath10k_unchain_msdu(&amsdu) < 0) { - __skb_queue_purge(&amsdu); - continue; - } - - if (attention & RX_ATTENTION_FLAGS_FCS_ERR) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - else - rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC; - - if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) - rx_status->flag |= RX_FLAG_MMIC_ERROR; - else - rx_status->flag &= ~RX_FLAG_MMIC_ERROR; - - hdr = ath10k_htt_rx_skb_get_hdr(skb_peek(&amsdu)); - - if (ath10k_htt_rx_hdr_is_amsdu(hdr)) - ath10k_htt_rx_amsdu(htt, rx_status, &amsdu); - else - ath10k_htt_rx_msdu(htt, rx_status, - __skb_dequeue(&amsdu)); + ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); + ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); + ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); } tasklet_schedule(&htt->rx_replenish_task); @@ -1284,19 +1440,11 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, struct htt_rx_fragment_indication *frag) { struct ath10k *ar = htt->ar; - struct sk_buff *msdu; - enum htt_rx_mpdu_encrypt_type enctype; - struct htt_rx_desc *rxd; - enum rx_msdu_decap_format fmt; struct ieee80211_rx_status *rx_status = &htt->rx_status; - struct ieee80211_hdr *hdr; struct sk_buff_head amsdu; int ret; - bool tkip_mic_err; - bool decrypt_err; u8 *fw_desc; - int fw_desc_len, hdrlen, paramlen; - int trim; + int fw_desc_len; u32 attention = 0; fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes); @@ -1326,75 +1474,13 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, return; } - msdu = __skb_dequeue(&amsdu); - /* FIXME: implement signal strength */ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; - hdr = (struct ieee80211_hdr *)msdu->data; - rxd = (void *)msdu->data - sizeof(*rxd); - tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); - decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); - fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), - RX_MSDU_START_INFO1_DECAP_FORMAT); - - if (fmt != RX_MSDU_DECAP_RAW) { - ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n"); - dev_kfree_skb_any(msdu); - goto end; - } - - enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), - RX_MPDU_START_INFO0_ENCRYPT_TYPE); - ath10k_htt_rx_h_protected(htt, rx_status, msdu, enctype, fmt, - true); - msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); - - if (tkip_mic_err) - ath10k_warn(ar, "tkip mic error\n"); - - if (decrypt_err) { - ath10k_warn(ar, "decryption err in fragmented rx\n"); - dev_kfree_skb_any(msdu); - goto end; - } - - if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) { - hdrlen = ieee80211_hdrlen(hdr->frame_control); - paramlen = ath10k_htt_rx_crypto_param_len(ar, enctype); - - /* It is more efficient to move the header than the payload */ - memmove((void *)msdu->data + paramlen, - (void *)msdu->data, - hdrlen); - skb_pull(msdu, paramlen); - hdr = (struct ieee80211_hdr *)msdu->data; - } - - /* remove trailing FCS */ - trim = 4; - - /* remove crypto trailer */ - trim += ath10k_htt_rx_crypto_tail_len(ar, enctype); - - /* last fragment of TKIP frags has MIC */ - if (!ieee80211_has_morefrags(hdr->frame_control) && - enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) - trim += MICHAEL_MIC_LEN; - - if (trim > msdu->len) { - ath10k_warn(ar, "htt rx fragment: trailer longer than the frame itself? drop\n"); - dev_kfree_skb_any(msdu); - goto end; - } - - skb_trim(msdu, msdu->len - trim); - - ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ", - msdu->data, msdu->len); - ath10k_process_rx(htt->ar, rx_status, msdu); + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); + ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); + ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); -end: if (fw_desc_len > 0) { ath10k_dbg(ar, ATH10K_DBG_HTT, "expecting more fragmented rx in one indication %d\n", -- GitLab From f0e2770ff75efb6353a73321271d80e4529ff3ab Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:49 +0200 Subject: [PATCH 5492/9457] ath10k: remove unused function argument The original fix has been moved into a different place in the code. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 6abb3b6a348f..332abc751c18 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -304,8 +304,7 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) /* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, u8 **fw_desc, int *fw_desc_len, - struct sk_buff_head *amsdu, - u32 *attention) + struct sk_buff_head *amsdu) { struct ath10k *ar = htt->ar; int msdu_len, msdu_chaining = 0; @@ -346,11 +345,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, return -EIO; } - *attention |= __le32_to_cpu(rx_desc->attention.flags) & - (RX_ATTENTION_FLAGS_TKIP_MIC_ERR | - RX_ATTENTION_FLAGS_DECRYPT_ERR | - RX_ATTENTION_FLAGS_FCS_ERR | - RX_ATTENTION_FLAGS_MGMT_TYPE); /* * Copy the FW rx descriptor for this MSDU from the rx * indication message into the MSDU's netbuf. HL uses the @@ -1362,7 +1356,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct htt_rx_indication_mpdu_range *mpdu_ranges; struct sk_buff_head amsdu; int num_mpdu_ranges; - u32 attention; int fw_desc_len; u8 *fw_desc; bool channel_set; @@ -1412,11 +1405,9 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, mpdu_count += mpdu_ranges[i].mpdu_count; while (mpdu_count--) { - attention = 0; __skb_queue_head_init(&amsdu); ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, - &fw_desc_len, &amsdu, - &attention); + &fw_desc_len, &amsdu); if (ret < 0) { ath10k_warn(ar, "rx ring became corrupted: %d\n", ret); __skb_queue_purge(&amsdu); @@ -1445,7 +1436,6 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, int ret; u8 *fw_desc; int fw_desc_len; - u32 attention = 0; fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes); fw_desc = (u8 *)frag->fw_msdu_rx_desc; @@ -1454,7 +1444,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, spin_lock_bh(&htt->rx_ring.lock); ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, - &amsdu, &attention); + &amsdu); spin_unlock_bh(&htt->rx_ring.lock); tasklet_schedule(&htt->rx_replenish_task); -- GitLab From b9fd8a8420fe9c20fc639f7abd6561661f2ecd3e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:49 +0200 Subject: [PATCH 5493/9457] ath10k: use rx descriptor for ppdu status extraction This makes it more in line with the new Rx path. It also makes the code more reusable because Rx descriptor is more accessible. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 136 ++++++++++++++++------- 1 file changed, 95 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 332abc751c18..3d503b0057f0 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -629,23 +629,34 @@ static const u8 rx_legacy_rate_idx[] = { }; static void ath10k_htt_rx_h_rates(struct ath10k *ar, - enum ieee80211_band band, - u8 info0, u32 info1, u32 info2, - struct ieee80211_rx_status *status) + struct ieee80211_rx_status *status, + struct htt_rx_desc *rxd) { + enum ieee80211_band band; u8 cck, rate, rate_idx, bw, sgi, mcs, nss; u8 preamble = 0; + u32 info1, info2, info3; - /* Check if valid fields */ - if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID)) + /* Band value can't be set as undefined but freq can be 0 - use that to + * determine whether band is provided. + * + * FIXME: Perhaps this can go away if CCK rate reporting is a little + * reworked? + */ + if (!status->freq) return; - preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE); + band = status->band; + info1 = __le32_to_cpu(rxd->ppdu_start.info1); + info2 = __le32_to_cpu(rxd->ppdu_start.info2); + info3 = __le32_to_cpu(rxd->ppdu_start.info3); + + preamble = MS(info1, RX_PPDU_START_INFO1_PREAMBLE_TYPE); switch (preamble) { case HTT_RX_LEGACY: - cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK; - rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE); + cck = info1 & RX_PPDU_START_INFO1_L_SIG_RATE_SELECT; + rate = MS(info1, RX_PPDU_START_INFO1_L_SIG_RATE); rate_idx = 0; if (rate < 0x08 || rate > 0x0F) @@ -672,11 +683,11 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, break; case HTT_RX_HT: case HTT_RX_HT_WITH_TXBF: - /* HT-SIG - Table 20-11 in info1 and info2 */ - mcs = info1 & 0x1F; + /* HT-SIG - Table 20-11 in info2 and info3 */ + mcs = info2 & 0x1F; nss = mcs >> 3; - bw = (info1 >> 7) & 1; - sgi = (info2 >> 7) & 1; + bw = (info2 >> 7) & 1; + sgi = (info3 >> 7) & 1; status->rate_idx = mcs; status->flag |= RX_FLAG_HT; @@ -687,12 +698,12 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, break; case HTT_RX_VHT: case HTT_RX_VHT_WITH_TXBF: - /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2 + /* VHT-SIG-A1 in info2, VHT-SIG-A2 in info3 TODO check this */ - mcs = (info2 >> 4) & 0x0F; - nss = ((info1 >> 10) & 0x07) + 1; - bw = info1 & 3; - sgi = info2 & 1; + mcs = (info3 >> 4) & 0x0F; + nss = ((info2 >> 10) & 0x07) + 1; + bw = info2 & 3; + sgi = info3 & 1; status->rate_idx = mcs; status->vht_nss = nss; @@ -740,6 +751,72 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, return true; } +static void ath10k_htt_rx_h_signal(struct ath10k *ar, + struct ieee80211_rx_status *status, + struct htt_rx_desc *rxd) +{ + /* FIXME: Get real NF */ + status->signal = ATH10K_DEFAULT_NOISE_FLOOR + + rxd->ppdu_start.rssi_comb; + status->flag &= ~RX_FLAG_NO_SIGNAL_VAL; +} + +static void ath10k_htt_rx_h_mactime(struct ath10k *ar, + struct ieee80211_rx_status *status, + struct htt_rx_desc *rxd) +{ + /* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This + * means all prior MSDUs in a PPDU are reported to mac80211 without the + * TSF. Is it worth holding frames until end of PPDU is known? + * + * FIXME: Can we get/compute 64bit TSF? + */ + status->mactime = __le32_to_cpu(rxd->ppdu_end.tsf_timestamp); + status->flag |= RX_FLAG_MACTIME_END; +} + +static void ath10k_htt_rx_h_ppdu(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *status) +{ + struct sk_buff *first; + struct htt_rx_desc *rxd; + bool is_first_ppdu; + bool is_last_ppdu; + + if (skb_queue_empty(amsdu)) + return; + + first = skb_peek(amsdu); + rxd = (void *)first->data - sizeof(*rxd); + + is_first_ppdu = !!(rxd->attention.flags & + __cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU)); + is_last_ppdu = !!(rxd->attention.flags & + __cpu_to_le32(RX_ATTENTION_FLAGS_LAST_MPDU)); + + if (is_first_ppdu) { + /* New PPDU starts so clear out the old per-PPDU status. */ + status->freq = 0; + status->rate_idx = 0; + status->vht_nss = 0; + status->vht_flag &= ~RX_VHT_FLAG_80MHZ; + status->flag &= ~(RX_FLAG_HT | + RX_FLAG_VHT | + RX_FLAG_SHORT_GI | + RX_FLAG_40MHZ | + RX_FLAG_MACTIME_END); + status->flag |= RX_FLAG_NO_SIGNAL_VAL; + + ath10k_htt_rx_h_signal(ar, status, rxd); + ath10k_htt_rx_h_channel(ar, status); + ath10k_htt_rx_h_rates(ar, status, rxd); + } + + if (is_last_ppdu) + ath10k_htt_rx_h_mactime(ar, status, rxd); +} + static const char * const tid_to_ac[] = { "BE", "BK", @@ -1358,7 +1435,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, int num_mpdu_ranges; int fw_desc_len; u8 *fw_desc; - bool channel_set; int i, ret, mpdu_count = 0; lockdep_assert_held(&htt->rx_ring.lock); @@ -1373,29 +1449,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); - /* Fill this once, while this is per-ppdu */ - if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) { - memset(rx_status, 0, sizeof(*rx_status)); - rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR + - rx->ppdu.combined_rssi; - } - - if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) { - /* TSF available only in 32-bit */ - rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff; - rx_status->flag |= RX_FLAG_MACTIME_END; - } - - channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status); - - if (channel_set) { - ath10k_htt_rx_h_rates(htt->ar, rx_status->band, - rx->ppdu.info0, - __le32_to_cpu(rx->ppdu.info1), - __le32_to_cpu(rx->ppdu.info2), - rx_status); - } - ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", rx, sizeof(*rx) + (sizeof(struct htt_rx_indication_mpdu_range) * @@ -1418,6 +1471,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, break; } + ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status); ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); -- GitLab From 89a5a317531738950b1b7f16fc4ee3be520ecc69 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 18 Nov 2014 09:24:49 +0200 Subject: [PATCH 5494/9457] ath10k: report rx rate and signal for fragmented Rx Fragmented Rx wasn't reporting everything. With the reworked Rx code it's very easy to fix it. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 3d503b0057f0..75b229345beb 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1518,9 +1518,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, return; } - /* FIXME: implement signal strength */ - rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; - + ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status); ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); -- GitLab From 3943f42c11896ce82ad3da132c8a5630313bdd0e Mon Sep 17 00:00:00 2001 From: Andrey Utkin Date: Fri, 14 Nov 2014 05:09:55 +0400 Subject: [PATCH 5495/9457] Replace mentions of "list_struct" to "list_head" There's no such thing as "list_struct". Signed-off-by: Andrey Utkin Acked-by: Steven Rostedt Acked-by: Mauro Carvalho Chehab Acked-by: Paul E. McKenney Acked-by: Alex Deucher Signed-off-by: Jiri Kosina --- drivers/gpu/drm/radeon/mkregtable.c | 24 ++++++++++---------- drivers/media/pci/cx18/cx18-driver.h | 2 +- include/linux/list.h | 34 ++++++++++++++-------------- include/linux/plist.h | 10 ++++---- include/linux/rculist.h | 8 +++---- scripts/kconfig/list.h | 6 ++--- tools/usb/usbip/libsrc/list.h | 2 +- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index 4a85bb644e24..b928c17bdeed 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c @@ -347,7 +347,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) @@ -356,7 +356,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_first_entry - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ @@ -406,7 +406,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ @@ -417,7 +417,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_reverse - iterate backwards over list of given type. * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member); \ @@ -428,7 +428,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() * @pos: the type * to use as a start point * @head: the head of the list - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). */ @@ -439,7 +439,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_continue - continue iteration over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Continue to iterate over list of given type, continuing after * the current position. @@ -453,7 +453,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_continue_reverse - iterate backwards from the given point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Start to iterate over list of given type backwards, continuing after * the current position. @@ -467,7 +467,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_from - iterate over list of given type from the current point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type, continuing from current position. */ @@ -480,7 +480,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ @@ -493,7 +493,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type, continuing after current point, * safe against removal of list entry. @@ -509,7 +509,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry. @@ -524,7 +524,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry. diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h index 57f4688ea55b..da59ec31d109 100644 --- a/drivers/media/pci/cx18/cx18-driver.h +++ b/drivers/media/pci/cx18/cx18-driver.h @@ -290,7 +290,7 @@ struct cx18_options { * list_entry_is_past_end - check if a previous loop cursor is off list end * @pos: the type * previously used as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Check if the entry's list_head is the head of the list, thus it's not a * real entry but was the loop cursor that walked past the end diff --git a/include/linux/list.h b/include/linux/list.h index f33f831eb3c8..feb773c76ee0 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -346,7 +346,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) @@ -355,7 +355,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_first_entry - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ @@ -366,7 +366,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_last_entry - get the last element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ @@ -377,7 +377,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_first_entry_or_null - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Note that if the list is empty, it returns NULL. */ @@ -387,7 +387,7 @@ static inline void list_splice_tail_init(struct list_head *list, /** * list_next_entry - get the next element in list * @pos: the type * to cursor - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) @@ -395,7 +395,7 @@ static inline void list_splice_tail_init(struct list_head *list, /** * list_prev_entry - get the prev element in list * @pos: the type * to cursor - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_prev_entry(pos, member) \ list_entry((pos)->member.prev, typeof(*(pos)), member) @@ -441,7 +441,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ @@ -452,7 +452,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_reverse - iterate backwards over list of given type. * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_last_entry(head, typeof(*pos), member); \ @@ -463,7 +463,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() * @pos: the type * to use as a start point * @head: the head of the list - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). */ @@ -474,7 +474,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_continue - continue iteration over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Continue to iterate over list of given type, continuing after * the current position. @@ -488,7 +488,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_continue_reverse - iterate backwards from the given point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Start to iterate over list of given type backwards, continuing after * the current position. @@ -502,7 +502,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_from - iterate over list of given type from the current point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type, continuing from current position. */ @@ -515,7 +515,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member), \ @@ -528,7 +528,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type, continuing after current point, * safe against removal of list entry. @@ -544,7 +544,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry. @@ -559,7 +559,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry. @@ -574,7 +574,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_safe_reset_next - reset a stale list_for_each_entry_safe loop * @pos: the loop cursor used in the list_for_each_entry_safe loop * @n: temporary storage used in list_for_each_entry_safe - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * list_safe_reset_next is not safe to use in general if the list may be * modified concurrently (eg. the lock is dropped in the loop body). An diff --git a/include/linux/plist.h b/include/linux/plist.h index 8b6c970cff6c..97883604a3c5 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h @@ -176,7 +176,7 @@ extern void plist_requeue(struct plist_node *node, struct plist_head *head); * plist_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop counter * @head: the head for your list - * @mem: the name of the list_struct within the struct + * @mem: the name of the list_head within the struct */ #define plist_for_each_entry(pos, head, mem) \ list_for_each_entry(pos, &(head)->node_list, mem.node_list) @@ -185,7 +185,7 @@ extern void plist_requeue(struct plist_node *node, struct plist_head *head); * plist_for_each_entry_continue - continue iteration over list of given type * @pos: the type * to use as a loop cursor * @head: the head for your list - * @m: the name of the list_struct within the struct + * @m: the name of the list_head within the struct * * Continue to iterate over list of given type, continuing after * the current position. @@ -198,7 +198,7 @@ extern void plist_requeue(struct plist_node *node, struct plist_head *head); * @pos: the type * to use as a loop counter * @n: another type * to use as temporary storage * @head: the head for your list - * @m: the name of the list_struct within the struct + * @m: the name of the list_head within the struct * * Iterate over list of given type, safe against removal of list entry. */ @@ -229,7 +229,7 @@ static inline int plist_node_empty(const struct plist_node *node) * plist_first_entry - get the struct for the first entry * @head: the &struct plist_head pointer * @type: the type of the struct this is embedded in - * @member: the name of the list_struct within the struct + * @member: the name of the list_head within the struct */ #ifdef CONFIG_DEBUG_PI_LIST # define plist_first_entry(head, type, member) \ @@ -246,7 +246,7 @@ static inline int plist_node_empty(const struct plist_node *node) * plist_last_entry - get the struct for the last entry * @head: the &struct plist_head pointer * @type: the type of the struct this is embedded in - * @member: the name of the list_struct within the struct + * @member: the name of the list_head within the struct */ #ifdef CONFIG_DEBUG_PI_LIST # define plist_last_entry(head, type, member) \ diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 372ad5e0dcb8..664060bd2f43 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -241,7 +241,7 @@ static inline void list_splice_init_rcu(struct list_head *list, * list_entry_rcu - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * This primitive may safely run concurrently with the _rcu list-mutation * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). @@ -278,7 +278,7 @@ static inline void list_splice_init_rcu(struct list_head *list, * list_first_or_null_rcu - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Note that if the list is empty, it returns NULL. * @@ -296,7 +296,7 @@ static inline void list_splice_init_rcu(struct list_head *list, * list_for_each_entry_rcu - iterate over rcu list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as list_add_rcu() @@ -311,7 +311,7 @@ static inline void list_splice_init_rcu(struct list_head *list, * list_for_each_entry_continue_rcu - continue iteration over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Continue to iterate over list of given type, continuing after * the current position. diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h index 685d80e1bb0e..2cf23f002d3f 100644 --- a/scripts/kconfig/list.h +++ b/scripts/kconfig/list.h @@ -34,7 +34,7 @@ struct list_head { * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) @@ -43,7 +43,7 @@ struct list_head { * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ @@ -55,7 +55,7 @@ struct list_head { * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ diff --git a/tools/usb/usbip/libsrc/list.h b/tools/usb/usbip/libsrc/list.h index 8d0c936e184f..5eaaa78e2c6a 100644 --- a/tools/usb/usbip/libsrc/list.h +++ b/tools/usb/usbip/libsrc/list.h @@ -98,7 +98,7 @@ static inline void list_del(struct list_head *entry) * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -- GitLab From cbd2551628c50816b479e7689641f553f1aa688e Mon Sep 17 00:00:00 2001 From: Radek Dostal Date: Mon, 17 Nov 2014 15:41:18 +0100 Subject: [PATCH 5496/9457] ARM: dts: bcm63138: change "interupts" to "interrupts" all other nodes in bcm63138.dtsi use "interrupts", this had to be just a typo which never got noticed, even it may have quite some consequences. Signed-off-by: Radek Dostal Acked-by: Florian Fainelli Signed-off-by: Jiri Kosina --- arch/arm/boot/dts/bcm63138.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi index f3bb2dd6269e..d2d8e94e0aa2 100644 --- a/arch/arm/boot/dts/bcm63138.dtsi +++ b/arch/arm/boot/dts/bcm63138.dtsi @@ -102,7 +102,7 @@ twd_watchdog: watchdog@1e620 { compatible = "arm,cortex-a9-twd-wdt"; reg = <0x1e620 0x20>; - interupts = ; + interrupts = ; }; }; -- GitLab From 6774def6422f6eac53f1828c317bf3b08a8f5a60 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 5 Nov 2014 22:26:48 +0900 Subject: [PATCH 5497/9457] treewide: fix typo in printk and Kconfig This patch fix spelling typo in printk and Kconfig within various part of kernel sources. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Jiri Kosina --- arch/mips/cavium-octeon/setup.c | 4 ++-- arch/mips/pci/pci-octeon.c | 2 +- arch/powerpc/kvm/e500_mmu_host.c | 6 +++--- drivers/isdn/mISDN/l1oip_core.c | 2 +- drivers/media/pci/ttpci/budget-patch.c | 2 +- drivers/s390/char/tape_3590.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- drivers/target/target_core_xcopy.c | 2 +- drivers/tty/serial/Kconfig | 2 +- drivers/usb/gadget/function/f_hid.c | 2 +- drivers/usb/host/ehci-sysfs.c | 2 +- drivers/usb/host/fotg210-hcd.c | 2 +- drivers/usb/host/fusbh200-hcd.c | 2 +- fs/reiserfs/journal.c | 2 +- .../ffs-aio-example/multibuff/device_app/aio_multibuff.c | 2 +- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 5ebdb32d9a2b..94f888d3384e 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -1092,7 +1092,7 @@ static int __init edac_devinit(void) name = edac_device_names[i]; dev = platform_device_register_simple(name, -1, NULL, 0); if (IS_ERR(dev)) { - pr_err("Registation of %s failed!\n", name); + pr_err("Registration of %s failed!\n", name); err = PTR_ERR(dev); } } @@ -1103,7 +1103,7 @@ static int __init edac_devinit(void) dev = platform_device_register_simple("octeon_lmc_edac", i, NULL, 0); if (IS_ERR(dev)) { - pr_err("Registation of octeon_lmc_edac %d failed!\n", i); + pr_err("Registration of octeon_lmc_edac %d failed!\n", i); err = PTR_ERR(dev); } } diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 59cccd95688b..d07e04121cc6 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -708,7 +708,7 @@ static int __init octeon_pci_setup(void) if (IS_ERR(platform_device_register_simple("octeon_pci_edac", -1, NULL, 0))) - pr_err("Registation of co_pci_edac failed!\n"); + pr_err("Registration of co_pci_edac failed!\n"); octeon_pci_dma_init(); diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 769778f855b0..cc536d4a75ef 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -661,7 +661,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, if (unlikely((pr && !(mas3 & MAS3_UX)) || (!pr && !(mas3 & MAS3_SX)))) { pr_err_ratelimited( - "%s: Instuction emulation from guest addres %08lx without execute permission\n", + "%s: Instruction emulation from guest address %08lx without execute permission\n", __func__, geaddr); return EMULATE_AGAIN; } @@ -673,7 +673,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, if (has_feature(vcpu, VCPU_FTR_MMU_V2) && unlikely((mas2 & MAS2_I) || (mas2 & MAS2_W) || !(mas2 & MAS2_M))) { pr_err_ratelimited( - "%s: Instuction emulation from guest addres %08lx mismatches storage attributes\n", + "%s: Instruction emulation from guest address %08lx mismatches storage attributes\n", __func__, geaddr); return EMULATE_AGAIN; } @@ -686,7 +686,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type, /* Guard against emulation from devices area */ if (unlikely(!page_is_ram(pfn))) { - pr_err_ratelimited("%s: Instruction emulation from non-RAM host addres %08llx is not supported\n", + pr_err_ratelimited("%s: Instruction emulation from non-RAM host address %08llx is not supported\n", __func__, addr); return EMULATE_AGAIN; } diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 9f454d76cc06..67c21876c35f 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -1334,7 +1334,7 @@ init_card(struct l1oip *hc, int pri, int bundle) if (id[l1oip_cnt] == 0) { printk(KERN_WARNING "Warning: No 'id' value given or " "0, this is highly unsecure. Please use 32 " - "bit randmom number 0x...\n"); + "bit random number 0x...\n"); } hc->id = id[l1oip_cnt]; if (debug & DEBUG_L1OIP_INIT) diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c index 2cb35c23d2ac..a4d8867e1d7b 100644 --- a/drivers/media/pci/ttpci/budget-patch.c +++ b/drivers/media/pci/ttpci/budget-patch.c @@ -490,7 +490,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte if(detected == 0) printk("budget-patch not detected or saa7146 in non-default state.\n" - "try enabling ressetting of 7146 with MASK_31 in MC1 register\n"); + "try enabling resetting of 7146 with MASK_31 in MC1 register\n"); else printk("BUDGET-PATCH DETECTED.\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 327cb19ad0b0..d3d1936057b4 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -1090,7 +1090,7 @@ tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb) "channel path 0x%x on CU", sense->fmt.f71.md[1]); else - snprintf(service, BUFSIZE, "Repair will disable cannel" + snprintf(service, BUFSIZE, "Repair will disable channel" " paths (0x%x-0x%x) on CU", sense->fmt.f71.md[1], sense->fmt.f71.md[2]); break; @@ -1481,7 +1481,7 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, } if (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) { - DBF_EVENT(2, "cannel end\n"); + DBF_EVENT(2, "channel end\n"); return TAPE_IO_PENDING; } diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5640ad1c8214..6edef43969d1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6740,7 +6740,7 @@ static int __init megasas_init(void) rval = pci_register_driver(&megasas_pci_driver); if (rval) { - printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n"); + printk(KERN_DEBUG "megasas: PCI hotplug registration failed \n"); goto err_pcidrv; } diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index e9186cdf35e9..33ac39bf75e5 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -335,7 +335,7 @@ static int target_xcopy_parse_segment_descriptors(struct se_cmd *se_cmd, desc += XCOPY_SEGMENT_DESC_LEN; break; default: - pr_err("XCOPY unspported segment descriptor" + pr_err("XCOPY unsupported segment descriptor" "type: 0x%02x\n", desc[0]); goto out; } diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 649b784081c7..f967d65c7d28 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -701,7 +701,7 @@ config PDC_CONSOLE Saying Y here will enable the software based PDC console to be used as the system console. This is useful for machines in which the hardware based console has not been written yet. The - following steps must be competed to use the PDC console: + following steps must be completed to use the PDC console: 1. create the device entry (mknod /dev/ttyB0 c 11 0) 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0 diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 59ab62c92b66..ea2b9c374305 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -396,7 +396,7 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_REPORT): - VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength); + VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength); goto stall; break; diff --git a/drivers/usb/host/ehci-sysfs.c b/drivers/usb/host/ehci-sysfs.c index f6459dfb6f54..5e44407aa099 100644 --- a/drivers/usb/host/ehci-sysfs.c +++ b/drivers/usb/host/ehci-sysfs.c @@ -132,7 +132,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev, if (allocated_max > uframe_periodic_max) { ehci_info(ehci, - "cannot decrease uframe_periodic_max becase " + "cannot decrease uframe_periodic_max because " "periodic bandwidth is already allocated " "(%u > %u)\n", allocated_max, uframe_periodic_max); diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 3de1278677d0..ecf02b2623e8 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -4958,7 +4958,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev, if (allocated_max > uframe_periodic_max) { fotg210_info(fotg210, - "cannot decrease uframe_periodic_max becase " + "cannot decrease uframe_periodic_max because " "periodic bandwidth is already allocated " "(%u > %u)\n", allocated_max, uframe_periodic_max); diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c index abe42f31559f..664d2aa1239c 100644 --- a/drivers/usb/host/fusbh200-hcd.c +++ b/drivers/usb/host/fusbh200-hcd.c @@ -4893,7 +4893,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev, if (allocated_max > uframe_periodic_max) { fusbh200_info(fusbh200, - "cannot decrease uframe_periodic_max becase " + "cannot decrease uframe_periodic_max because " "periodic bandwidth is already allocated " "(%u > %u)\n", allocated_max, uframe_periodic_max); diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index d571e173a990..9d6486d416a3 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2772,7 +2772,7 @@ int journal_init(struct super_block *sb, const char *j_dev_name, if (journal_init_dev(sb, journal, j_dev_name) != 0) { reiserfs_warning(sb, "sh-462", - "unable to initialize jornal device"); + "unable to initialize journal device"); goto free_and_return; } diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c index af4b0508be77..aaca1f44e788 100644 --- a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c +++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c @@ -342,7 +342,7 @@ int main(int argc, char *argv[]) iobuf[i].requested = ret; printf("submit: %d requests buf: %d\n", ret, i); } else - perror("unable to submit reqests"); + perror("unable to submit requests"); } /* if event is ready to read */ -- GitLab From af222097aaf7f547b7543d5a0d6198d1480db414 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 5 Nov 2014 21:11:10 +1100 Subject: [PATCH 5498/9457] ps3rom: fix error return code Set the return variable to an error code as done elsewhere in the function. Signed-off-by: Julia Lawall Signed-off-by: Michael Ellerman Acked-By: Geoff Levand Signed-off-by: Jiri Kosina --- drivers/scsi/ps3rom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index ef23fabe3924..619caf1acc9c 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -387,6 +387,7 @@ static int ps3rom_probe(struct ps3_system_bus_device *_dev) if (!host) { dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed\n", __func__, __LINE__); + error = -ENOMEM; goto fail_teardown; } -- GitLab From edd52b1c39ea3ddb1c814d1d5cd9cc4843a04c01 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Oct 2014 11:52:54 +0200 Subject: [PATCH 5499/9457] cpufreq: cpufreq-dt: Move newline to end of error message Currently the error message is needlessly splitted across two lines. Signed-off-by: Geert Uytterhoeven Acked-by: Viresh Kumar Signed-off-by: Jiri Kosina --- drivers/cpufreq/cpufreq-dt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f657c571b18e..a023abfab4bd 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -193,7 +193,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk); if (ret) { - pr_err("%s: Failed to allocate resources\n: %d", __func__, ret); + pr_err("%s: Failed to allocate resources: %d\n", __func__, ret); return ret; } -- GitLab From 078014dd36989c66378dfe80066c3f8a1f6952e8 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 29 Oct 2014 15:35:54 +0900 Subject: [PATCH 5500/9457] intel_ips: fix a type in error message Signed-off-by: Masatake YAMATO Signed-off-by: Jiri Kosina --- drivers/platform/x86/intel_ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c0242ed13d9e..ecd36e332c3c 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -593,7 +593,7 @@ static void ips_disable_gpu_turbo(struct ips_driver *ips) return; if (!ips->gpu_turbo_disable()) - dev_err(&ips->dev->dev, "failed to disable graphis turbo\n"); + dev_err(&ips->dev->dev, "failed to disable graphics turbo\n"); else ips->__gpu_turbo_on = false; } -- GitLab From 68a49e51a4a9c500d950f893f1758c5ac13b7c8b Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 12 Nov 2014 14:52:28 -0500 Subject: [PATCH 5501/9457] HID: sony: Add support for the third-party SMK PS3 Bluetooth Remote Add vid/pid for the SMK branded third-party PS3 Bluetooth remote and enable support in the hid-sony driver. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-sony.c | 3 +++ 3 files changed, 7 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3402033fa52a..0ab6d6af54c8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1914,6 +1914,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7c863738e419..27e0f5188d08 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -813,6 +813,9 @@ #define USB_VENDOR_ID_SKYCABLE 0x1223 #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 +#define USB_VENDOR_ID_SMK 0x0609 +#define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306 + #define USB_VENDOR_ID_SONY 0x054c #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b #define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b6e610289e9d..31e9d2561106 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2113,6 +2113,9 @@ static const struct hid_device_id sony_devices[] = { /* Logitech Harmony Adapter for PS3 */ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), .driver_data = PS3REMOTE }, + /* SMK-Link PS3 BD Remote Control */ + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE), + .driver_data = PS3REMOTE }, /* Sony Dualshock 4 controllers for PS4 */ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), .driver_data = DUALSHOCK4_CONTROLLER_USB }, -- GitLab From 4597a88a1eba0f513583517cbdb5d90bada68f0f Mon Sep 17 00:00:00 2001 From: Zhe Wang Date: Thu, 20 Nov 2014 13:42:55 +0000 Subject: [PATCH 5502/9457] drm/i915/skl: Gen9 multi-engine forcewake Enable multi-engine forcewake for Gen9. v2: (Damien) - Rebase on top of nightly - Move the register range definitions to intel_uncore.c - Whitespace fixes v3: (Addressing Mika's comment, done by Damien) - Use REG_RANGE() (introduced after the patch was written) - Add a SKL_NEEDS_FORCE_WAKE() macro that gets rid of a useless comparison to FORCEWAKE (reg 0xa18c is not used on SKL) v4: (Damien) - Use newly introduced ASSIGN_READ/WRITE_MMIO_VFUNCS() macros Reviewed-by: Mika Kuoppala Signed-off-by: Zhe Wang Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 115 ++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c98421dbfafd..4c10faa5783f 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -670,6 +670,34 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv) REG_RANGE((reg), 0x14000, 0x14400) || \ REG_RANGE((reg), 0x22000, 0x24000)) +#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \ + REG_RANGE((reg), 0xC00, 0x2000) + +#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \ + (REG_RANGE((reg), 0x2000, 0x4000) || \ + REG_RANGE((reg), 0x5200, 0x8000) || \ + REG_RANGE((reg), 0x8300, 0x8500) || \ + REG_RANGE((reg), 0x8C00, 0x8D00) || \ + REG_RANGE((reg), 0xB000, 0xB480) || \ + REG_RANGE((reg), 0xE000, 0xE800)) + +#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \ + (REG_RANGE((reg), 0x8800, 0x8A00) || \ + REG_RANGE((reg), 0xD000, 0xD800) || \ + REG_RANGE((reg), 0x12000, 0x14000) || \ + REG_RANGE((reg), 0x1A000, 0x1EA00) || \ + REG_RANGE((reg), 0x30000, 0x40000)) + +#define FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg) \ + REG_RANGE((reg), 0x9400, 0x9800) + +#define FORCEWAKE_GEN9_BLITTER_RANGE_OFFSET(reg) \ + ((reg) < 0x40000 &&\ + !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) && \ + !FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) && \ + !FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \ + !FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) + static void ilk_dummy_write(struct drm_i915_private *dev_priv) { @@ -800,6 +828,45 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ REG_READ_FOOTER; \ } +#define SKL_NEEDS_FORCE_WAKE(dev_priv, reg) \ + ((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg)) + +#define __gen9_read(x) \ +static u##x \ +gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ + REG_READ_HEADER(x); \ + if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + val = __raw_i915_read##x(dev_priv, reg); \ + } else { \ + unsigned fwengine = 0; \ + if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_rendercount == 0) \ + fwengine = FORCEWAKE_RENDER; \ + } else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_mediacount == 0) \ + fwengine = FORCEWAKE_MEDIA; \ + } else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_rendercount == 0) \ + fwengine |= FORCEWAKE_RENDER; \ + if (dev_priv->uncore.fw_mediacount == 0) \ + fwengine |= FORCEWAKE_MEDIA; \ + } else { \ + if (dev_priv->uncore.fw_blittercount == 0) \ + fwengine = FORCEWAKE_BLITTER; \ + } \ + if (fwengine) \ + dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \ + val = __raw_i915_read##x(dev_priv, reg); \ + if (fwengine) \ + dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \ + } \ + REG_READ_FOOTER; \ +} + +__gen9_read(8) +__gen9_read(16) +__gen9_read(32) +__gen9_read(64) __chv_read(8) __chv_read(16) __chv_read(32) @@ -821,6 +888,7 @@ __gen4_read(16) __gen4_read(32) __gen4_read(64) +#undef __gen9_read #undef __chv_read #undef __vlv_read #undef __gen6_read @@ -958,6 +1026,45 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __gen9_write(x) \ +static void \ +gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \ + bool trace) { \ + REG_WRITE_HEADER; \ + if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + __raw_i915_write##x(dev_priv, reg, val); \ + } else { \ + unsigned fwengine = 0; \ + if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_rendercount == 0) \ + fwengine = FORCEWAKE_RENDER; \ + } else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_mediacount == 0) \ + fwengine = FORCEWAKE_MEDIA; \ + } else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \ + if (dev_priv->uncore.fw_rendercount == 0) \ + fwengine |= FORCEWAKE_RENDER; \ + if (dev_priv->uncore.fw_mediacount == 0) \ + fwengine |= FORCEWAKE_MEDIA; \ + } else { \ + if (dev_priv->uncore.fw_blittercount == 0) \ + fwengine = FORCEWAKE_BLITTER; \ + } \ + if (fwengine) \ + dev_priv->uncore.funcs.force_wake_get(dev_priv, \ + fwengine); \ + __raw_i915_write##x(dev_priv, reg, val); \ + if (fwengine) \ + dev_priv->uncore.funcs.force_wake_put(dev_priv, \ + fwengine); \ + } \ + REG_WRITE_FOOTER; \ +} + +__gen9_write(8) +__gen9_write(16) +__gen9_write(32) +__gen9_write(64) __chv_write(8) __chv_write(16) __chv_write(32) @@ -983,6 +1090,7 @@ __gen4_write(16) __gen4_write(32) __gen4_write(64) +#undef __gen9_write #undef __chv_write #undef __gen8_write #undef __hsw_write @@ -1066,6 +1174,13 @@ void intel_uncore_init(struct drm_device *dev) switch (INTEL_INFO(dev)->gen) { default: + WARN_ON(1); + return; + case 9: + ASSIGN_WRITE_MMIO_VFUNCS(gen9); + ASSIGN_READ_MMIO_VFUNCS(gen9); + break; + case 8: if (IS_CHERRYVIEW(dev)) { ASSIGN_WRITE_MMIO_VFUNCS(chv); ASSIGN_READ_MMIO_VFUNCS(chv); -- GitLab From 7c859007fdae545b71db7a2d58a9214da5806800 Mon Sep 17 00:00:00 2001 From: Zhe Wang Date: Thu, 20 Nov 2014 13:42:56 +0000 Subject: [PATCH 5503/9457] drm/i915: Gen9 shadowed registers For MMIO registers which are shadowed, force wake is not needed to write to these registers. v2: Rebase on top of nightly (Damien) v3: Rebase on top of "Gen9 multiple-engine forcewake" changes v4: (Mika, Bob, done by Damien) - Reorder the shadowed registers by popularity Reviewed-by: Mika Kuoppala Signed-off-by: Zhe Wang Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_uncore.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 4c10faa5783f..1a3e485a4f97 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1026,12 +1026,36 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +static const u32 gen9_shadowed_regs[] = { + RING_TAIL(RENDER_RING_BASE), + RING_TAIL(GEN6_BSD_RING_BASE), + RING_TAIL(VEBOX_RING_BASE), + RING_TAIL(BLT_RING_BASE), + FORCEWAKE_BLITTER_GEN9, + FORCEWAKE_RENDER_GEN9, + FORCEWAKE_MEDIA_GEN9, + GEN6_RPNSWREQ, + GEN6_RC_VIDEO_FREQ, + /* TODO: Other registers are not yet used */ +}; + +static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg) +{ + int i; + for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++) + if (reg == gen9_shadowed_regs[i]) + return true; + + return false; +} + #define __gen9_write(x) \ static void \ gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \ bool trace) { \ REG_WRITE_HEADER; \ - if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \ + is_gen9_shadowed(dev_priv, reg)) { \ __raw_i915_write##x(dev_priv, reg, val); \ } else { \ unsigned fwengine = 0; \ -- GitLab From f6f203faa3ebd8fa229e34424850a0919ded6c10 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Wed, 19 Nov 2014 11:19:37 -0600 Subject: [PATCH 5504/9457] crypto: crc32 - Add ARM64 CRC32 hw accelerated module This module registers a crc32 algorithm and a crc32c algorithm that use the optional CRC32 and CRC32C instructions in ARMv8. Tested on AMD Seattle. Improvement compared to crc32c-generic algorithm: TCRYPT CRC32C speed test shows ~450% speedup. Simple dd write tests to btrfs filesystem show ~30% speedup. Signed-off-by: Yazen Ghannam Acked-by: Steve Capper Acked-by: Ard Biesheuvel Signed-off-by: Herbert Xu --- arch/arm64/crypto/Kconfig | 4 + arch/arm64/crypto/Makefile | 4 + arch/arm64/crypto/crc32-arm64.c | 274 ++++++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 arch/arm64/crypto/crc32-arm64.c diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index 5562652c5316..c1a0468f7156 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -50,4 +50,8 @@ config CRYPTO_AES_ARM64_NEON_BLK select CRYPTO_AES select CRYPTO_ABLK_HELPER +config CRYPTO_CRC32_ARM64 + tristate "CRC32 and CRC32C using optional ARMv8 instructions" + depends on ARM64 + select CRYPTO_HASH endif diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile index a3f935fde975..5720608c50b1 100644 --- a/arch/arm64/crypto/Makefile +++ b/arch/arm64/crypto/Makefile @@ -34,5 +34,9 @@ AFLAGS_aes-neon.o := -DINTERLEAVE=4 CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS +obj-$(CONFIG_CRYPTO_CRC32_ARM64) += crc32-arm64.o + +CFLAGS_crc32-arm64.o := -mcpu=generic+crc + $(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE $(call if_changed_rule,cc_o_c) diff --git a/arch/arm64/crypto/crc32-arm64.c b/arch/arm64/crypto/crc32-arm64.c new file mode 100644 index 000000000000..9499199924ae --- /dev/null +++ b/arch/arm64/crypto/crc32-arm64.c @@ -0,0 +1,274 @@ +/* + * crc32-arm64.c - CRC32 and CRC32C using optional ARMv8 instructions + * + * Module based on crypto/crc32c_generic.c + * + * CRC32 loop taken from Ed Nevill's Hadoop CRC patch + * http://mail-archives.apache.org/mod_mbox/hadoop-common-dev/201406.mbox/%3C1403687030.3355.19.camel%40localhost.localdomain%3E + * + * Using inline assembly instead of intrinsics in order to be backwards + * compatible with older compilers. + * + * Copyright (C) 2014 Linaro Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("Yazen Ghannam "); +MODULE_DESCRIPTION("CRC32 and CRC32C using optional ARMv8 instructions"); +MODULE_LICENSE("GPL v2"); + +#define CRC32X(crc, value) __asm__("crc32x %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32W(crc, value) __asm__("crc32w %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32H(crc, value) __asm__("crc32h %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32B(crc, value) __asm__("crc32b %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32CX(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32CW(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32CH(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) +#define CRC32CB(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)) + +static u32 crc32_arm64_le_hw(u32 crc, const u8 *p, unsigned int len) +{ + s64 length = len; + + while ((length -= sizeof(u64)) >= 0) { + CRC32X(crc, get_unaligned_le64(p)); + p += sizeof(u64); + } + + /* The following is more efficient than the straight loop */ + if (length & sizeof(u32)) { + CRC32W(crc, get_unaligned_le32(p)); + p += sizeof(u32); + } + if (length & sizeof(u16)) { + CRC32H(crc, get_unaligned_le16(p)); + p += sizeof(u16); + } + if (length & sizeof(u8)) + CRC32B(crc, *p); + + return crc; +} + +static u32 crc32c_arm64_le_hw(u32 crc, const u8 *p, unsigned int len) +{ + s64 length = len; + + while ((length -= sizeof(u64)) >= 0) { + CRC32CX(crc, get_unaligned_le64(p)); + p += sizeof(u64); + } + + /* The following is more efficient than the straight loop */ + if (length & sizeof(u32)) { + CRC32CW(crc, get_unaligned_le32(p)); + p += sizeof(u32); + } + if (length & sizeof(u16)) { + CRC32CH(crc, get_unaligned_le16(p)); + p += sizeof(u16); + } + if (length & sizeof(u8)) + CRC32CB(crc, *p); + + return crc; +} + +#define CHKSUM_BLOCK_SIZE 1 +#define CHKSUM_DIGEST_SIZE 4 + +struct chksum_ctx { + u32 key; +}; + +struct chksum_desc_ctx { + u32 crc; +}; + +static int chksum_init(struct shash_desc *desc) +{ + struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm); + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + ctx->crc = mctx->key; + + return 0; +} + +/* + * Setting the seed allows arbitrary accumulators and flexible XOR policy + * If your algorithm starts with ~0, then XOR with ~0 before you set + * the seed. + */ +static int chksum_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen) +{ + struct chksum_ctx *mctx = crypto_shash_ctx(tfm); + + if (keylen != sizeof(mctx->key)) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + mctx->key = get_unaligned_le32(key); + return 0; +} + +static int chksum_update(struct shash_desc *desc, const u8 *data, + unsigned int length) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + ctx->crc = crc32_arm64_le_hw(ctx->crc, data, length); + return 0; +} + +static int chksumc_update(struct shash_desc *desc, const u8 *data, + unsigned int length) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + ctx->crc = crc32c_arm64_le_hw(ctx->crc, data, length); + return 0; +} + +static int chksum_final(struct shash_desc *desc, u8 *out) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + put_unaligned_le32(~ctx->crc, out); + return 0; +} + +static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out) +{ + put_unaligned_le32(~crc32_arm64_le_hw(crc, data, len), out); + return 0; +} + +static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out) +{ + put_unaligned_le32(~crc32c_arm64_le_hw(crc, data, len), out); + return 0; +} + +static int chksum_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + return __chksum_finup(ctx->crc, data, len, out); +} + +static int chksumc_finup(struct shash_desc *desc, const u8 *data, + unsigned int len, u8 *out) +{ + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); + + return __chksumc_finup(ctx->crc, data, len, out); +} + +static int chksum_digest(struct shash_desc *desc, const u8 *data, + unsigned int length, u8 *out) +{ + struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm); + + return __chksum_finup(mctx->key, data, length, out); +} + +static int chksumc_digest(struct shash_desc *desc, const u8 *data, + unsigned int length, u8 *out) +{ + struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm); + + return __chksumc_finup(mctx->key, data, length, out); +} + +static int crc32_cra_init(struct crypto_tfm *tfm) +{ + struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); + + mctx->key = ~0; + return 0; +} + +static struct shash_alg crc32_alg = { + .digestsize = CHKSUM_DIGEST_SIZE, + .setkey = chksum_setkey, + .init = chksum_init, + .update = chksum_update, + .final = chksum_final, + .finup = chksum_finup, + .digest = chksum_digest, + .descsize = sizeof(struct chksum_desc_ctx), + .base = { + .cra_name = "crc32", + .cra_driver_name = "crc32-arm64-hw", + .cra_priority = 300, + .cra_blocksize = CHKSUM_BLOCK_SIZE, + .cra_alignmask = 0, + .cra_ctxsize = sizeof(struct chksum_ctx), + .cra_module = THIS_MODULE, + .cra_init = crc32_cra_init, + } +}; + +static struct shash_alg crc32c_alg = { + .digestsize = CHKSUM_DIGEST_SIZE, + .setkey = chksum_setkey, + .init = chksum_init, + .update = chksumc_update, + .final = chksum_final, + .finup = chksumc_finup, + .digest = chksumc_digest, + .descsize = sizeof(struct chksum_desc_ctx), + .base = { + .cra_name = "crc32c", + .cra_driver_name = "crc32c-arm64-hw", + .cra_priority = 300, + .cra_blocksize = CHKSUM_BLOCK_SIZE, + .cra_alignmask = 0, + .cra_ctxsize = sizeof(struct chksum_ctx), + .cra_module = THIS_MODULE, + .cra_init = crc32_cra_init, + } +}; + +static int __init crc32_mod_init(void) +{ + int err; + + err = crypto_register_shash(&crc32_alg); + + if (err) + return err; + + err = crypto_register_shash(&crc32c_alg); + + if (err) { + crypto_unregister_shash(&crc32_alg); + return err; + } + + return 0; +} + +static void __exit crc32_mod_exit(void) +{ + crypto_unregister_shash(&crc32_alg); + crypto_unregister_shash(&crc32c_alg); +} + +module_cpu_feature_match(CRC32, crc32_mod_init); +module_exit(crc32_mod_exit); -- GitLab From 1e0bdad02583764e90671a2900920cffa3e9d605 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Nov 2014 21:16:04 +0100 Subject: [PATCH 5505/9457] crypto: bfin_crc - don't include linux/unaligned/access_ok.h This is a specific implementation, is the multiplexer that has the arch-specific knowledge of which of the implementations needs to be used, so include that. Signed-off-by: Johannes Berg Signed-off-by: Herbert Xu --- drivers/crypto/bfin_crc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/bfin_crc.c b/drivers/crypto/bfin_crc.c index b099e33cb073..e96eddc0e0b3 100644 --- a/drivers/crypto/bfin_crc.c +++ b/drivers/crypto/bfin_crc.c @@ -21,13 +21,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include -- GitLab From 21961efa1381053633aed190fdaac21481fb6c12 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 20 Nov 2014 10:43:22 +0100 Subject: [PATCH 5506/9457] hwrng: atmel - use clk_prepapre_enable/_disable_unprepare Use clk_prepare_enable/_disable_unprepare instead of clk_enable/disable to work properly with the CCF. Signed-off-by: Boris Brezillon Acked-by: Peter Korsgaard Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- drivers/char/hw_random/atmel-rng.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 851bc7e20ad2..644ec4882206 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -67,7 +67,7 @@ static int atmel_trng_probe(struct platform_device *pdev) if (IS_ERR(trng->clk)) return PTR_ERR(trng->clk); - ret = clk_enable(trng->clk); + ret = clk_prepare_enable(trng->clk); if (ret) return ret; @@ -95,7 +95,7 @@ static int atmel_trng_remove(struct platform_device *pdev) hwrng_unregister(&trng->rng); writel(TRNG_KEY, trng->base + TRNG_CR); - clk_disable(trng->clk); + clk_disable_unprepare(trng->clk); return 0; } @@ -105,7 +105,7 @@ static int atmel_trng_suspend(struct device *dev) { struct atmel_trng *trng = dev_get_drvdata(dev); - clk_disable(trng->clk); + clk_disable_unprepare(trng->clk); return 0; } @@ -114,7 +114,7 @@ static int atmel_trng_resume(struct device *dev) { struct atmel_trng *trng = dev_get_drvdata(dev); - return clk_enable(trng->clk); + return clk_prepare_enable(trng->clk); } static const struct dev_pm_ops atmel_trng_pm_ops = { -- GitLab From 4951db7edc9460e5102b9c00b67ceddb09dfbe4c Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 20 Nov 2014 10:43:23 +0100 Subject: [PATCH 5507/9457] hwrng: atmel - add DT support Add DT support. Make the driver depend on CONFIG_OF as at91sam9g45 was the only SoC making use of the TRNG block and this SoC is now fully migrated to DT. Signed-off-by: Boris Brezillon Acked-by: Peter Korsgaard Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- drivers/char/hw_random/Kconfig | 2 +- drivers/char/hw_random/atmel-rng.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 91a04ae8003c..de57b38809c7 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -64,7 +64,7 @@ config HW_RANDOM_AMD config HW_RANDOM_ATMEL tristate "Atmel Random Number Generator support" - depends on ARCH_AT91 && HAVE_CLK + depends on ARCH_AT91 && HAVE_CLK && OF default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 644ec4882206..0bb0b2120a63 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -123,6 +123,12 @@ static const struct dev_pm_ops atmel_trng_pm_ops = { }; #endif /* CONFIG_PM */ +static const struct of_device_id atmel_trng_dt_ids[] = { + { .compatible = "atmel,at91sam9g45-trng" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, atmel_trng_dt_ids); + static struct platform_driver atmel_trng_driver = { .probe = atmel_trng_probe, .remove = atmel_trng_remove, @@ -132,6 +138,7 @@ static struct platform_driver atmel_trng_driver = { #ifdef CONFIG_PM .pm = &atmel_trng_pm_ops, #endif /* CONFIG_PM */ + .of_match_table = atmel_trng_dt_ids, }, }; -- GitLab From 1281c87ff067933cdeed79c4bda18ef3052b1165 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 20 Nov 2014 10:43:24 +0100 Subject: [PATCH 5508/9457] hwrng: atmel - Add TRNG DT binding doc Document DT bindings of Atmel's TRNG (True Random Number Generator) IP. Signed-off-by: Boris Brezillon Acked-by: Peter Korsgaard Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- .../devicetree/bindings/hwrng/atmel-trng.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/devicetree/bindings/hwrng/atmel-trng.txt diff --git a/Documentation/devicetree/bindings/hwrng/atmel-trng.txt b/Documentation/devicetree/bindings/hwrng/atmel-trng.txt new file mode 100644 index 000000000000..4ac5aaa2d024 --- /dev/null +++ b/Documentation/devicetree/bindings/hwrng/atmel-trng.txt @@ -0,0 +1,16 @@ +Atmel TRNG (True Random Number Generator) block + +Required properties: +- compatible : Should be "atmel,at91sam9g45-trng" +- reg : Offset and length of the register set of this block +- interrupts : the interrupt number for the TRNG block +- clocks: should contain the TRNG clk source + +Example: + +trng@fffcc000 { + compatible = "atmel,at91sam9g45-trng"; + reg = <0xfffcc000 0x4000>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&trng_clk>; +}; -- GitLab From 3e16d322f21c6bba7ac7dc08ff2664e68b021915 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 20 Nov 2014 10:43:25 +0100 Subject: [PATCH 5509/9457] ARM: at91/dt: add trng node to at91sam9g45 Add a DT node for the TRNG (True Random Number Generator) block. Keep this block enabled as it does not depend on any external connection, and thus should be available on all boards. Signed-off-by: Boris Brezillon Acked-by: Nicolas Ferre Signed-off-by: Herbert Xu --- arch/arm/boot/dts/at91sam9g45.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index d3f65130a1f8..6c0637a4bda5 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -940,6 +940,13 @@ status = "disabled"; }; + trng@fffcc000 { + compatible = "atmel,at91sam9g45-trng"; + reg = <0xfffcc000 0x4000>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&trng_clk>; + }; + i2c0: i2c@fff84000 { compatible = "atmel,at91sam9g10-i2c"; reg = <0xfff84000 0x100>; -- GitLab From f9df89d897ee0928aa4e03b30250e87f5d1e788a Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Mon, 6 Jan 2014 09:04:18 -0400 Subject: [PATCH 5510/9457] thermal: introduce clock cooling device This patch introduces a new thermal cooling device based on common clock framework. The original motivation to write this cooling device is to be able to cool down thermal zones using clocks that feed co-processors, such as GPUs, DSPs, Image Processing Co-processors, etc. But it is written in a way that it can be used on top of any clock. The implementation is pretty straight forward. The code creates a thermal cooling device based on a pair of a struct device and a clock name. The struct device is assumed to be usable by the OPP layer. The OPP layer is used as source of the list of possible frequencies. The (cpufreq) frequency table is then used as a map from frequencies to cooling states. Cooling states are indexes to the frequency table. The logic sits on top of common clock framework, specifically on clock pre notifications. Any PRE_RATE_CHANGE is hijacked, and the transition is only allowed when the new rate is within the thermal limit (cooling state -> freq). When a thermal cooling device state transition is requested, the clock is also checked to verify if the current clock rate is within the new thermal limit. Cc: Zhang Rui Cc: Mike Turquette Cc: Nishanth Menon Cc: Pavel Machek Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Greg Kroah-Hartman Cc: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Eduardo Valentin Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 12 + drivers/thermal/Makefile | 3 + drivers/thermal/clock_cooling.c | 485 ++++++++++++++++++++++++++++++++ include/linux/clock_cooling.h | 65 +++++ 4 files changed, 565 insertions(+) create mode 100644 drivers/thermal/clock_cooling.c create mode 100644 include/linux/clock_cooling.h diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index f554d25b4399..efbdb8c0bb1d 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -112,6 +112,18 @@ config CPU_THERMAL If you want this support, you should say Y here. +config CLOCK_THERMAL + bool "Generic clock cooling support" + depends on COMMON_CLK + depends on PM_OPP + help + This entry implements the generic clock cooling mechanism through + frequency clipping. Typically used to cool off co-processors. The + device that is configured to use this cooling mechanism will be + controlled to reduce clock frequency whenever temperature is high. + + If you want this support, you should say Y here. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 39c4fe87da2f..9d33532cae9f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -18,6 +18,9 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o # cpufreq cooling thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o +# clock cooling +thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o + # platform thermal drivers obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o diff --git a/drivers/thermal/clock_cooling.c b/drivers/thermal/clock_cooling.c new file mode 100644 index 000000000000..1b4ff0f4c716 --- /dev/null +++ b/drivers/thermal/clock_cooling.c @@ -0,0 +1,485 @@ +/* + * drivers/thermal/clock_cooling.c + * + * Copyright (C) 2014 Eduardo Valentin + * + * Copyright (C) 2013 Texas Instruments Inc. + * Contact: Eduardo Valentin + * + * Highly based on cpu_cooling.c. + * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) + * Copyright (C) 2012 Amit Daniel + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct clock_cooling_device - data for cooling device with clock + * @id: unique integer value corresponding to each clock_cooling_device + * registered. + * @dev: struct device pointer to the device being used to cool off using + * clock frequencies. + * @cdev: thermal_cooling_device pointer to keep track of the + * registered cooling device. + * @clk_rate_change_nb: reference to notifier block used to receive clock + * rate changes. + * @freq_table: frequency table used to keep track of available frequencies. + * @clock_state: integer value representing the current state of clock + * cooling devices. + * @clock_val: integer value representing the absolute value of the clipped + * frequency. + * @clk: struct clk reference used to enforce clock limits. + * @lock: mutex lock to protect this struct. + * + * This structure is required for keeping information of each + * clock_cooling_device registered. In order to prevent corruption of this a + * mutex @lock is used. + */ +struct clock_cooling_device { + int id; + struct device *dev; + struct thermal_cooling_device *cdev; + struct notifier_block clk_rate_change_nb; + struct cpufreq_frequency_table *freq_table; + unsigned long clock_state; + unsigned long clock_val; + struct clk *clk; + struct mutex lock; /* lock to protect the content of this struct */ +}; +#define to_clock_cooling_device(x) \ + container_of(x, struct clock_cooling_device, clk_rate_change_nb) +static DEFINE_IDR(clock_idr); +static DEFINE_MUTEX(cooling_clock_lock); + +/** + * clock_cooling_get_idr - function to get an unique id. + * @id: int * value generated by this function. + * + * This function will populate @id with an unique + * id, using the idr API. + * + * Return: 0 on success, an error code on failure. + */ +static int clock_cooling_get_idr(int *id) +{ + int ret; + + mutex_lock(&cooling_clock_lock); + ret = idr_alloc(&clock_idr, NULL, 0, 0, GFP_KERNEL); + mutex_unlock(&cooling_clock_lock); + if (unlikely(ret < 0)) + return ret; + *id = ret; + + return 0; +} + +/** + * release_idr - function to free the unique id. + * @id: int value representing the unique id. + */ +static void release_idr(int id) +{ + mutex_lock(&cooling_clock_lock); + idr_remove(&clock_idr, id); + mutex_unlock(&cooling_clock_lock); +} + +/* Below code defines functions to be used for clock as cooling device */ + +enum clock_cooling_property { + GET_LEVEL, + GET_FREQ, + GET_MAXL, +}; + +/** + * clock_cooling_get_property - fetch a property of interest for a give cpu. + * @ccdev: clock cooling device reference + * @input: query parameter + * @output: query return + * @property: type of query (frequency, level, max level) + * + * This is the common function to + * 1. get maximum clock cooling states + * 2. translate frequency to cooling state + * 3. translate cooling state to frequency + * Note that the code may be not in good shape + * but it is written in this way in order to: + * a) reduce duplicate code as most of the code can be shared. + * b) make sure the logic is consistent when translating between + * cooling states and frequencies. + * + * Return: 0 on success, -EINVAL when invalid parameters are passed. + */ +static int clock_cooling_get_property(struct clock_cooling_device *ccdev, + unsigned long input, + unsigned long *output, + enum clock_cooling_property property) +{ + int i; + unsigned long max_level = 0, level = 0; + unsigned int freq = CPUFREQ_ENTRY_INVALID; + int descend = -1; + struct cpufreq_frequency_table *pos, *table = ccdev->freq_table; + + if (!output) + return -EINVAL; + + if (!table) + return -EINVAL; + + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* get the frequency order */ + if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) + descend = freq > pos->frequency; + + freq = pos->frequency; + max_level++; + } + + /* No valid cpu frequency entry */ + if (max_level == 0) + return -EINVAL; + + /* max_level is an index, not a counter */ + max_level--; + + /* get max level */ + if (property == GET_MAXL) { + *output = max_level; + return 0; + } + + if (property == GET_FREQ) + level = descend ? input : (max_level - input); + + i = 0; + cpufreq_for_each_valid_entry(pos, table) { + /* ignore duplicate entry */ + if (freq == pos->frequency) + continue; + + /* now we have a valid frequency entry */ + freq = pos->frequency; + + if (property == GET_LEVEL && (unsigned int)input == freq) { + /* get level by frequency */ + *output = descend ? i : (max_level - i); + return 0; + } + if (property == GET_FREQ && level == i) { + /* get frequency by level */ + *output = freq; + return 0; + } + i++; + } + + return -EINVAL; +} + +/** + * clock_cooling_get_level - return the cooling level of given clock cooling. + * @cdev: reference of a thermal cooling device of used as clock cooling device + * @freq: the frequency of interest + * + * This function will match the cooling level corresponding to the + * requested @freq and return it. + * + * Return: The matched cooling level on success or THERMAL_CSTATE_INVALID + * otherwise. + */ +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long val; + + if (clock_cooling_get_property(ccdev, (unsigned long)freq, &val, + GET_LEVEL)) + return THERMAL_CSTATE_INVALID; + + return val; +} +EXPORT_SYMBOL_GPL(clock_cooling_get_level); + +/** + * clock_cooling_get_frequency - get the absolute value of frequency from level. + * @ccdev: clock cooling device reference + * @level: cooling level + * + * This function matches cooling level with frequency. Based on a cooling level + * of frequency, equals cooling state of cpu cooling device, it will return + * the corresponding frequency. + * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc + * + * Return: 0 on error, the corresponding frequency otherwise. + */ +static unsigned long +clock_cooling_get_frequency(struct clock_cooling_device *ccdev, + unsigned long level) +{ + int ret = 0; + unsigned long freq; + + ret = clock_cooling_get_property(ccdev, level, &freq, GET_FREQ); + if (ret) + return 0; + + return freq; +} + +/** + * clock_cooling_apply - function to apply frequency clipping. + * @ccdev: clock_cooling_device pointer containing frequency clipping data. + * @cooling_state: value of the cooling state. + * + * Function used to make sure the clock layer is aware of current thermal + * limits. The limits are applied by updating the clock rate in case it is + * higher than the corresponding frequency based on the requested cooling_state. + * + * Return: 0 on success, an error code otherwise (-EINVAL in case wrong + * cooling state). + */ +static int clock_cooling_apply(struct clock_cooling_device *ccdev, + unsigned long cooling_state) +{ + unsigned long clip_freq, cur_freq; + int ret = 0; + + /* Here we write the clipping */ + /* Check if the old cooling action is same as new cooling action */ + if (ccdev->clock_state == cooling_state) + return 0; + + clip_freq = clock_cooling_get_frequency(ccdev, cooling_state); + if (!clip_freq) + return -EINVAL; + + cur_freq = clk_get_rate(ccdev->clk); + + mutex_lock(&ccdev->lock); + ccdev->clock_state = cooling_state; + ccdev->clock_val = clip_freq; + /* enforce clock level */ + if (cur_freq > clip_freq) + ret = clk_set_rate(ccdev->clk, clip_freq); + mutex_unlock(&ccdev->lock); + + return ret; +} + +/** + * clock_cooling_clock_notifier - notifier callback on clock rate changes. + * @nb: struct notifier_block * with callback info. + * @event: value showing clock event for which this function invoked. + * @data: callback-specific data + * + * Callback to hijack the notification on clock transition. + * Every time there is a clock change, we intercept all pre change events + * and block the transition in case the new rate infringes thermal limits. + * + * Return: NOTIFY_DONE (success) or NOTIFY_BAD (new_rate > thermal limit). + */ +static int clock_cooling_clock_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct clock_cooling_device *ccdev = to_clock_cooling_device(nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * checks on current state + * TODO: current method is not best we can find as it + * allows possibly voltage transitions, in case DVFS + * layer is also hijacking clock pre notifications. + */ + if (ndata->new_rate > ccdev->clock_val) + return NOTIFY_BAD; + /* fall through */ + case POST_RATE_CHANGE: + case ABORT_RATE_CHANGE: + default: + return NOTIFY_DONE; + } +} + +/* clock cooling device thermal callback functions are defined below */ + +/** + * clock_cooling_get_max_state - callback function to get the max cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the max cooling state. + * + * Callback for the thermal cooling device to return the clock + * max cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + unsigned long count = 0; + int ret; + + ret = clock_cooling_get_property(ccdev, 0, &count, GET_MAXL); + if (!ret) + *state = count; + + return ret; +} + +/** + * clock_cooling_get_cur_state - function to get the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the current cooling state. + * + * Callback for the thermal cooling device to return the clock + * current cooling state. + * + * Return: 0 (success) + */ +static int clock_cooling_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct clock_cooling_device *ccdev = cdev->devdata; + + *state = ccdev->clock_state; + + return 0; +} + +/** + * clock_cooling_set_cur_state - function to set the current cooling state. + * @cdev: thermal cooling device pointer. + * @state: set this variable to the current cooling state. + * + * Callback for the thermal cooling device to change the clock cooling + * current cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int clock_cooling_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct clock_cooling_device *clock_device = cdev->devdata; + + return clock_cooling_apply(clock_device, state); +} + +/* Bind clock callbacks to thermal cooling device ops */ +static struct thermal_cooling_device_ops const clock_cooling_ops = { + .get_max_state = clock_cooling_get_max_state, + .get_cur_state = clock_cooling_get_cur_state, + .set_cur_state = clock_cooling_set_cur_state, +}; + +/** + * clock_cooling_register - function to create clock cooling device. + * @dev: struct device pointer to the device used as clock cooling device. + * @clock_name: string containing the clock used as cooling mechanism. + * + * This interface function registers the clock cooling device with the name + * "thermal-clock-%x". The cooling device is based on clock frequencies. + * The struct device is assumed to be capable of DVFS transitions. + * The OPP layer is used to fetch and fill the available frequencies for + * the referred device. The ordered frequency table is used to control + * the clock cooling device cooling states and to limit clock transitions + * based on the cooling state requested by the thermal framework. + * + * Return: a valid struct thermal_cooling_device pointer on success, + * on failure, it returns a corresponding ERR_PTR(). + */ +struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name) +{ + struct thermal_cooling_device *cdev; + struct clock_cooling_device *ccdev = NULL; + char dev_name[THERMAL_NAME_LENGTH]; + int ret = 0; + + ccdev = devm_kzalloc(dev, sizeof(*ccdev), GFP_KERNEL); + if (!ccdev) + return ERR_PTR(-ENOMEM); + + ccdev->dev = dev; + ccdev->clk = devm_clk_get(dev, clock_name); + if (IS_ERR(ccdev->clk)) + return ERR_CAST(ccdev->clk); + + ret = clock_cooling_get_idr(&ccdev->id); + if (ret) + return ERR_PTR(-EINVAL); + + snprintf(dev_name, sizeof(dev_name), "thermal-clock-%d", ccdev->id); + + cdev = thermal_cooling_device_register(dev_name, ccdev, + &clock_cooling_ops); + if (IS_ERR(cdev)) { + release_idr(ccdev->id); + return ERR_PTR(-EINVAL); + } + ccdev->cdev = cdev; + ccdev->clk_rate_change_nb.notifier_call = clock_cooling_clock_notifier; + + /* Assuming someone has already filled the opp table for this device */ + ret = dev_pm_opp_init_cpufreq_table(dev, &ccdev->freq_table); + if (ret) { + release_idr(ccdev->id); + return ERR_PTR(ret); + } + ccdev->clock_state = 0; + ccdev->clock_val = clock_cooling_get_frequency(ccdev, 0); + + clk_notifier_register(ccdev->clk, &ccdev->clk_rate_change_nb); + + return cdev; +} +EXPORT_SYMBOL_GPL(clock_cooling_register); + +/** + * clock_cooling_unregister - function to remove clock cooling device. + * @cdev: thermal cooling device pointer. + * + * This interface function unregisters the "thermal-clock-%x" cooling device. + */ +void clock_cooling_unregister(struct thermal_cooling_device *cdev) +{ + struct clock_cooling_device *ccdev; + + if (!cdev) + return; + + ccdev = cdev->devdata; + + clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb); + dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table); + + thermal_cooling_device_unregister(ccdev->cdev); + release_idr(ccdev->id); +} +EXPORT_SYMBOL_GPL(clock_cooling_unregister); diff --git a/include/linux/clock_cooling.h b/include/linux/clock_cooling.h new file mode 100644 index 000000000000..4d1019d56f7f --- /dev/null +++ b/include/linux/clock_cooling.h @@ -0,0 +1,65 @@ +/* + * linux/include/linux/clock_cooling.h + * + * Copyright (C) 2014 Eduardo Valentin + * + * Copyright (C) 2013 Texas Instruments Inc. + * Contact: Eduardo Valentin + * + * Highly based on cpu_cooling.c. + * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) + * Copyright (C) 2012 Amit Daniel + * + * 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. + */ + +#ifndef __CPU_COOLING_H__ +#define __CPU_COOLING_H__ + +#include +#include +#include + +#ifdef CONFIG_CLOCK_THERMAL +/** + * clock_cooling_register - function to create clock cooling device. + * @dev: struct device pointer to the device used as clock cooling device. + * @clock_name: string containing the clock used as cooling mechanism. + */ +struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name); + +/** + * clock_cooling_unregister - function to remove clock cooling device. + * @cdev: thermal cooling device pointer. + */ +void clock_cooling_unregister(struct thermal_cooling_device *cdev); + +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq); +#else /* !CONFIG_CLOCK_THERMAL */ +static inline struct thermal_cooling_device * +clock_cooling_register(struct device *dev, const char *clock_name) +{ + return NULL; +} +static inline +void clock_cooling_unregister(struct thermal_cooling_device *cdev) +{ +} +static inline +unsigned long clock_cooling_get_level(struct thermal_cooling_device *cdev, + unsigned long freq) +{ + return THERMAL_CSTATE_INVALID; +} +#endif /* CONFIG_CLOCK_THERMAL */ + +#endif /* __CPU_COOLING_H__ */ -- GitLab From 0199e9938f2c0e7f5476f5983f1763d28f049837 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Fri, 26 Sep 2014 12:43:10 +0300 Subject: [PATCH 5511/9457] of: Add bindings for nvidia,tegra124-soctherm This adds binding documentation and headers for the Tegra124 SOCTHERM device tree node. Signed-off-by: Mikko Perttunen Acked-by: Stephen Warren Acked-by: Eduardo Valentin Signed-off-by: Eduardo Valentin --- .../bindings/thermal/tegra-soctherm.txt | 53 +++++++++++++++++++ .../dt-bindings/thermal/tegra124-soctherm.h | 13 +++++ 2 files changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/tegra-soctherm.txt create mode 100644 include/dt-bindings/thermal/tegra124-soctherm.h diff --git a/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt b/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt new file mode 100644 index 000000000000..ecf3ed76cd46 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/tegra-soctherm.txt @@ -0,0 +1,53 @@ +Tegra124 SOCTHERM thermal management system + +The SOCTHERM IP block contains thermal sensors, support for polled +or interrupt-based thermal monitoring, CPU and GPU throttling based +on temperature trip points, and handling external overcurrent +notifications. It is also used to manage emergency shutdown in an +overheating situation. + +Required properties : +- compatible : "nvidia,tegra124-soctherm". +- reg : Should contain 1 entry: + - SOCTHERM register set +- interrupts : Defines the interrupt used by SOCTHERM +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + - tsensor + - soctherm +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - soctherm +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description + of this property. See for a + list of valid values when referring to thermal sensors. + + +Example : + + soctherm@0,700e2000 { + compatible = "nvidia,tegra124-soctherm"; + reg = <0x0 0x700e2000 0x0 0x1000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, + <&tegra_car TEGRA124_CLK_SOC_THERM>; + clock-names = "tsensor", "soctherm"; + resets = <&tegra_car 78>; + reset-names = "soctherm"; + + #thermal-sensor-cells = <1>; + }; + +Example: referring to thermal sensors : + + thermal-zones { + cpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>; + }; + }; diff --git a/include/dt-bindings/thermal/tegra124-soctherm.h b/include/dt-bindings/thermal/tegra124-soctherm.h new file mode 100644 index 000000000000..85aaf66690f9 --- /dev/null +++ b/include/dt-bindings/thermal/tegra124-soctherm.h @@ -0,0 +1,13 @@ +/* + * This header provides constants for binding nvidia,tegra124-soctherm. + */ + +#ifndef _DT_BINDINGS_THERMAL_TEGRA124_SOCTHERM_H +#define _DT_BINDINGS_THERMAL_TEGRA124_SOCTHERM_H + +#define TEGRA124_SOCTHERM_SENSOR_CPU 0 +#define TEGRA124_SOCTHERM_SENSOR_MEM 1 +#define TEGRA124_SOCTHERM_SENSOR_GPU 2 +#define TEGRA124_SOCTHERM_SENSOR_PLLX 3 + +#endif -- GitLab From 26b76f80b32c824ea746cd17c70814f28935afc9 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Fri, 26 Sep 2014 12:43:11 +0300 Subject: [PATCH 5512/9457] ARM: tegra: Add soctherm and thermal zones to Tegra124 device tree This adds the soctherm thermal sensing and management unit to the Tegra124 device tree along with the four thermal zones corresponding to the four thermal sensors provided by soctherm. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin --- arch/arm/boot/dts/tegra124.dtsi | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 478c555ebd96..41f8b274529a 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -3,6 +3,7 @@ #include #include #include +#include #include "skeleton.dtsi" @@ -640,6 +641,18 @@ status = "disabled"; }; + soctherm: thermal-sensor@0,700e2000 { + compatible = "nvidia,tegra124-soctherm"; + reg = <0x0 0x700e2000 0x0 0x1000>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, + <&tegra_car TEGRA124_CLK_SOC_THERM>; + clock-names = "tsensor", "soctherm"; + resets = <&tegra_car 78>; + reset-names = "soctherm"; + #thermal-sensor-cells = <1>; + }; + ahub@0,70300000 { compatible = "nvidia,tegra124-ahub"; reg = <0x0 0x70300000 0x0 0x200>, @@ -881,6 +894,40 @@ }; }; + thermal-zones { + cpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>; + }; + + mem { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>; + }; + + gpu { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>; + }; + + pllx { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = + <&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = Date: Fri, 26 Sep 2014 12:43:12 +0300 Subject: [PATCH 5513/9457] ARM: tegra: Add thermal trip points for Jetson TK1 This adds critical trip points to the Jetson TK1 device tree. The device will do a controlled shutdown when either the CPU, GPU or MEM thermal zone reaches 101 degrees Celsius. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin --- arch/arm/boot/dts/tegra124-jetson-tk1.dts | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 029c9a021541..f46a7892d269 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -1941,4 +1941,48 @@ <&tegra_car TEGRA124_CLK_EXTERN1>; clock-names = "pll_a", "pll_a_out0", "mclk"; }; + + thermal-zones { + cpu { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + + mem { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + + gpu { + trips { + trip@0 { + temperature = <101000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + /* There are currently no cooling maps because there are no cooling devices */ + }; + }; + }; }; -- GitLab From 66fb84805134c39f00d7c2054c881faa50910390 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Mon, 29 Sep 2014 17:17:31 +0300 Subject: [PATCH 5514/9457] thermal: Add Tegra SOCTHERM thermal management driver This adds support for the Tegra SOCTHERM thermal sensing and management system found in the Tegra124 system-on-chip. This initial driver supports temperature polling for four thermal zones. Signed-off-by: Mikko Perttunen Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 10 + drivers/thermal/Makefile | 1 + drivers/thermal/tegra_soctherm.c | 473 +++++++++++++++++++++++++++++++ 3 files changed, 484 insertions(+) create mode 100644 drivers/thermal/tegra_soctherm.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index efbdb8c0bb1d..911c38aba6ef 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -197,6 +197,16 @@ config ARMADA_THERMAL Enable this option if you want to have support for thermal management controller present in Armada 370 and Armada XP SoC. +config TEGRA_SOCTHERM + tristate "Tegra SOCTHERM thermal management" + depends on ARCH_TEGRA + help + Enable this option for integrated thermal management support on NVIDIA + Tegra124 systems-on-chip. The driver supports four thermal zones + (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal + zones to manage temperatures. This option is also required for the + emergency thermal reset (thermtrip) feature to function. + config DB8500_CPUFREQ_COOLING tristate "DB8500 cpufreq cooling" depends on ARCH_U8500 diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 9d33532cae9f..2b18e3ac581f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_ST_THERMAL) += st/ +obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c new file mode 100644 index 000000000000..70f7e9ef4355 --- /dev/null +++ b/drivers/thermal/tegra_soctherm.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * Author: + * Mikko Perttunen + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SENSOR_CONFIG0 0 +#define SENSOR_CONFIG0_STOP BIT(0) +#define SENSOR_CONFIG0_TALL_SHIFT 8 +#define SENSOR_CONFIG0_TCALC_OVER BIT(4) +#define SENSOR_CONFIG0_OVER BIT(3) +#define SENSOR_CONFIG0_CPTR_OVER BIT(2) + +#define SENSOR_CONFIG1 4 +#define SENSOR_CONFIG1_TSAMPLE_SHIFT 0 +#define SENSOR_CONFIG1_TIDDQ_EN_SHIFT 15 +#define SENSOR_CONFIG1_TEN_COUNT_SHIFT 24 +#define SENSOR_CONFIG1_TEMP_ENABLE BIT(31) + +#define SENSOR_CONFIG2 8 +#define SENSOR_CONFIG2_THERMA_SHIFT 16 +#define SENSOR_CONFIG2_THERMB_SHIFT 0 + +#define SENSOR_PDIV 0x1c0 +#define SENSOR_PDIV_T124 0x8888 +#define SENSOR_HOTSPOT_OFF 0x1c4 +#define SENSOR_HOTSPOT_OFF_T124 0x00060600 +#define SENSOR_TEMP1 0x1c8 +#define SENSOR_TEMP2 0x1cc + +#define SENSOR_TEMP_MASK 0xffff +#define READBACK_VALUE_MASK 0xff00 +#define READBACK_VALUE_SHIFT 8 +#define READBACK_ADD_HALF BIT(7) +#define READBACK_NEGATE BIT(1) + +#define FUSE_TSENSOR8_CALIB 0x180 +#define FUSE_SPARE_REALIGNMENT_REG_0 0x1fc + +#define FUSE_TSENSOR_CALIB_CP_TS_BASE_MASK 0x1fff +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK (0x1fff << 13) +#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT 13 + +#define FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK 0x3ff +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK (0x7ff << 10) +#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT 10 + +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_MASK 0x3f +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK (0x1f << 21) +#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21 + +#define NOMINAL_CALIB_FT_T124 105 +#define NOMINAL_CALIB_CP_T124 25 + +struct tegra_tsensor_configuration { + u32 tall, tsample, tiddq_en, ten_count, pdiv, tsample_ate, pdiv_ate; +}; + +struct tegra_tsensor { + const struct tegra_tsensor_configuration *config; + u32 base, calib_fuse_offset; + /* Correction values used to modify values read from calibration fuses */ + s32 fuse_corr_alpha, fuse_corr_beta; +}; + +struct tegra_thermctl_zone { + void __iomem *reg; + unsigned int shift; +}; + +static const struct tegra_tsensor_configuration t124_tsensor_config = { + .tall = 16300, + .tsample = 120, + .tiddq_en = 1, + .ten_count = 1, + .pdiv = 8, + .tsample_ate = 480, + .pdiv_ate = 8 +}; + +static const struct tegra_tsensor t124_tsensors[] = { + { + .config = &t124_tsensor_config, + .base = 0xc0, + .calib_fuse_offset = 0x098, + .fuse_corr_alpha = 1135400, + .fuse_corr_beta = -6266900, + }, + { + .config = &t124_tsensor_config, + .base = 0xe0, + .calib_fuse_offset = 0x084, + .fuse_corr_alpha = 1122220, + .fuse_corr_beta = -5700700, + }, + { + .config = &t124_tsensor_config, + .base = 0x100, + .calib_fuse_offset = 0x088, + .fuse_corr_alpha = 1127000, + .fuse_corr_beta = -6768200, + }, + { + .config = &t124_tsensor_config, + .base = 0x120, + .calib_fuse_offset = 0x12c, + .fuse_corr_alpha = 1110900, + .fuse_corr_beta = -6232000, + }, + { + .config = &t124_tsensor_config, + .base = 0x140, + .calib_fuse_offset = 0x158, + .fuse_corr_alpha = 1122300, + .fuse_corr_beta = -5936400, + }, + { + .config = &t124_tsensor_config, + .base = 0x160, + .calib_fuse_offset = 0x15c, + .fuse_corr_alpha = 1145700, + .fuse_corr_beta = -7124600, + }, + { + .config = &t124_tsensor_config, + .base = 0x180, + .calib_fuse_offset = 0x154, + .fuse_corr_alpha = 1120100, + .fuse_corr_beta = -6000500, + }, + { + .config = &t124_tsensor_config, + .base = 0x1a0, + .calib_fuse_offset = 0x160, + .fuse_corr_alpha = 1106500, + .fuse_corr_beta = -6729300, + }, +}; + +struct tegra_soctherm { + struct reset_control *reset; + struct clk *clock_tsensor; + struct clk *clock_soctherm; + void __iomem *regs; + + struct thermal_zone_device *thermctl_tzs[4]; +}; + +struct tsensor_shared_calibration { + u32 base_cp, base_ft; + u32 actual_temp_cp, actual_temp_ft; +}; + +static int calculate_shared_calibration(struct tsensor_shared_calibration *r) +{ + u32 val, shifted_cp, shifted_ft; + int err; + + err = tegra_fuse_readl(FUSE_TSENSOR8_CALIB, &val); + if (err) + return err; + r->base_cp = val & FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK; + r->base_ft = (val & FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT; + val = ((val & FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK) + >> FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT); + shifted_ft = sign_extend32(val, 4); + + err = tegra_fuse_readl(FUSE_SPARE_REALIGNMENT_REG_0, &val); + if (err) + return err; + shifted_cp = sign_extend32(val, 5); + + r->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + shifted_cp; + r->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + shifted_ft; + + return 0; +} + +static s64 div64_s64_precise(s64 a, s64 b) +{ + s64 r, al; + + /* Scale up for increased precision division */ + al = a << 16; + + r = div64_s64(al * 2 + 1, 2 * b); + return r >> 16; +} + +static int +calculate_tsensor_calibration(const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared, + u32 *calib) +{ + u32 val; + s32 actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp, + mult, div; + s16 therma, thermb; + s64 tmp; + int err; + + err = tegra_fuse_readl(sensor->calib_fuse_offset, &val); + if (err) + return err; + + actual_tsensor_cp = (shared->base_cp * 64) + sign_extend32(val, 12); + val = (val & FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK) + >> FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT; + actual_tsensor_ft = (shared->base_ft * 32) + sign_extend32(val, 12); + + delta_sens = actual_tsensor_ft - actual_tsensor_cp; + delta_temp = shared->actual_temp_ft - shared->actual_temp_cp; + + mult = sensor->config->pdiv * sensor->config->tsample_ate; + div = sensor->config->tsample * sensor->config->pdiv_ate; + + therma = div64_s64_precise((s64) delta_temp * (1LL << 13) * mult, + (s64) delta_sens * div); + + tmp = (s64)actual_tsensor_ft * shared->actual_temp_cp - + (s64)actual_tsensor_cp * shared->actual_temp_ft; + thermb = div64_s64_precise(tmp, (s64)delta_sens); + + therma = div64_s64_precise((s64)therma * sensor->fuse_corr_alpha, + (s64)1000000LL); + thermb = div64_s64_precise((s64)thermb * sensor->fuse_corr_alpha + + sensor->fuse_corr_beta, (s64)1000000LL); + + *calib = ((u16)therma << SENSOR_CONFIG2_THERMA_SHIFT) | + ((u16)thermb << SENSOR_CONFIG2_THERMB_SHIFT); + + return 0; +} + +static int enable_tsensor(struct tegra_soctherm *tegra, + const struct tegra_tsensor *sensor, + const struct tsensor_shared_calibration *shared) +{ + void __iomem *base = tegra->regs + sensor->base; + unsigned int val; + u32 calib; + int err; + + err = calculate_tsensor_calibration(sensor, shared, &calib); + if (err) + return err; + + val = sensor->config->tall << SENSOR_CONFIG0_TALL_SHIFT; + writel(val, base + SENSOR_CONFIG0); + + val = (sensor->config->tsample - 1) << SENSOR_CONFIG1_TSAMPLE_SHIFT; + val |= sensor->config->tiddq_en << SENSOR_CONFIG1_TIDDQ_EN_SHIFT; + val |= sensor->config->ten_count << SENSOR_CONFIG1_TEN_COUNT_SHIFT; + val |= SENSOR_CONFIG1_TEMP_ENABLE; + writel(val, base + SENSOR_CONFIG1); + + writel(calib, base + SENSOR_CONFIG2); + + return 0; +} + +/* + * Translate from soctherm readback format to millicelsius. + * The soctherm readback format in bits is as follows: + * TTTTTTTT H______N + * where T's contain the temperature in Celsius, + * H denotes an addition of 0.5 Celsius and N denotes negation + * of the final value. + */ +static long translate_temp(u16 val) +{ + long t; + + t = ((val & READBACK_VALUE_MASK) >> READBACK_VALUE_SHIFT) * 1000; + if (val & READBACK_ADD_HALF) + t += 500; + if (val & READBACK_NEGATE) + t *= -1; + + return t; +} + +static int tegra_thermctl_get_temp(void *data, long *out_temp) +{ + struct tegra_thermctl_zone *zone = data; + u32 val; + + val = (readl(zone->reg) >> zone->shift) & SENSOR_TEMP_MASK; + *out_temp = translate_temp(val); + + return 0; +} + +static const struct of_device_id tegra_soctherm_of_match[] = { + { .compatible = "nvidia,tegra124-soctherm" }, + { }, +}; +MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match); + +struct thermctl_zone_desc { + unsigned int offset; + unsigned int shift; +}; + +static const struct thermctl_zone_desc t124_thermctl_temp_zones[] = { + { SENSOR_TEMP1, 16 }, + { SENSOR_TEMP2, 16 }, + { SENSOR_TEMP1, 0 }, + { SENSOR_TEMP2, 0 } +}; + +static int tegra_soctherm_probe(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra; + struct thermal_zone_device *tz; + struct tsensor_shared_calibration shared_calib; + struct resource *res; + unsigned int i; + int err; + + const struct tegra_tsensor *tsensors = t124_tsensors; + + tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); + if (!tegra) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + tegra->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(tegra->regs)) + return PTR_ERR(tegra->regs); + + tegra->reset = devm_reset_control_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->reset)) { + dev_err(&pdev->dev, "can't get soctherm reset\n"); + return PTR_ERR(tegra->reset); + } + + tegra->clock_tsensor = devm_clk_get(&pdev->dev, "tsensor"); + if (IS_ERR(tegra->clock_tsensor)) { + dev_err(&pdev->dev, "can't get tsensor clock\n"); + return PTR_ERR(tegra->clock_tsensor); + } + + tegra->clock_soctherm = devm_clk_get(&pdev->dev, "soctherm"); + if (IS_ERR(tegra->clock_soctherm)) { + dev_err(&pdev->dev, "can't get soctherm clock\n"); + return PTR_ERR(tegra->clock_soctherm); + } + + reset_control_assert(tegra->reset); + + err = clk_prepare_enable(tegra->clock_soctherm); + if (err) + return err; + + err = clk_prepare_enable(tegra->clock_tsensor); + if (err) { + clk_disable_unprepare(tegra->clock_soctherm); + return err; + } + + reset_control_deassert(tegra->reset); + + /* Initialize raw sensors */ + + err = calculate_shared_calibration(&shared_calib); + if (err) + goto disable_clocks; + + for (i = 0; i < ARRAY_SIZE(t124_tsensors); ++i) { + err = enable_tsensor(tegra, tsensors + i, &shared_calib); + if (err) + goto disable_clocks; + } + + writel(SENSOR_PDIV_T124, tegra->regs + SENSOR_PDIV); + writel(SENSOR_HOTSPOT_OFF_T124, tegra->regs + SENSOR_HOTSPOT_OFF); + + /* Initialize thermctl sensors */ + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + struct tegra_thermctl_zone *zone = + devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + err = -ENOMEM; + goto unregister_tzs; + } + + zone->reg = tegra->regs + t124_thermctl_temp_zones[i].offset; + zone->shift = t124_thermctl_temp_zones[i].shift; + + tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, + tegra_thermctl_get_temp, + NULL); + if (IS_ERR(tz)) { + err = PTR_ERR(tz); + dev_err(&pdev->dev, "failed to register sensor: %d\n", + err); + goto unregister_tzs; + } + + tegra->thermctl_tzs[i] = tz; + } + + return 0; + +unregister_tzs: + while (i--) + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + +disable_clocks: + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return err; +} + +static int tegra_soctherm_remove(struct platform_device *pdev) +{ + struct tegra_soctherm *tegra = platform_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) { + thermal_zone_of_sensor_unregister(&pdev->dev, + tegra->thermctl_tzs[i]); + } + + clk_disable_unprepare(tegra->clock_tsensor); + clk_disable_unprepare(tegra->clock_soctherm); + + return 0; +} + +static struct platform_driver tegra_soctherm_driver = { + .probe = tegra_soctherm_probe, + .remove = tegra_soctherm_remove, + .driver = { + .name = "tegra-soctherm", + .of_match_table = tegra_soctherm_of_match, + }, +}; +module_platform_driver(tegra_soctherm_driver); + +MODULE_AUTHOR("Mikko Perttunen "); +MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 2251aef64a38db60f4ae7a4a83f9203c6791f196 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Fri, 7 Nov 2014 21:24:39 -0400 Subject: [PATCH 5515/9457] thermal: of: improve of-thermal sensor registration API Different drivers request API extensions in of-thermal. For this reason, additional callbacks are required to fit the new drivers needs. The current API implementation expects the registering sensor driver to provide a get_temp and get_trend callbacks as function parameters. As the amount of callbacks is growing, this patch changes the existing implementation to use a .ops field to hold all the of thermal callbacks to sensor drivers. This patch also changes the existing of-thermal users to fit the new API design. No functional change is introduced in this patch. Cc: Alexandre Courbot Cc: devicetree@vger.kernel.org Cc: Grant Likely Cc: Guenter Roeck Cc: Jean Delvare Cc: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: linux-tegra@vger.kernel.org Cc: lm-sensors@lm-sensors.org Cc: Rob Herring Cc: Stephen Warren Cc: Thierry Reding Cc: Zhang Rui Acked-by: Guenter Roeck Tested-by: Mikko Perttunen Reviewed-by: Mikko Perttunen Reviewed-by: Alexandre Courbot Reviewed-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/hwmon/lm75.c | 9 +++-- drivers/hwmon/ntc_thermistor.c | 6 ++- drivers/hwmon/tmp102.c | 6 ++- drivers/thermal/of-thermal.c | 39 ++++++++----------- drivers/thermal/tegra_soctherm.c | 7 +++- .../ti-soc-thermal/ti-thermal-common.c | 8 +++- include/linux/thermal.h | 24 +++++++++--- 7 files changed, 62 insertions(+), 37 deletions(-) diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d16dbb33a531..e7c8bf9093ea 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -176,6 +176,10 @@ static struct attribute *lm75_attrs[] = { }; ATTRIBUTE_GROUPS(lm75); +static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { + .get_temp = lm75_read_temp, +}; + /*-----------------------------------------------------------------------*/ /* device probe and removal */ @@ -291,10 +295,9 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) if (IS_ERR(data->hwmon_dev)) return PTR_ERR(data->hwmon_dev); - data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, - 0, + data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0, data->hwmon_dev, - lm75_read_temp, NULL); + &lm75_of_thermal_ops); if (IS_ERR(data->tz)) data->tz = NULL; diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 4ff89b2482e4..bca8521c8a9b 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c @@ -486,6 +486,10 @@ static const struct attribute_group ntc_attr_group = { .attrs = ntc_attributes, }; +static const struct thermal_zone_of_device_ops ntc_of_thermal_ops = { + .get_temp = ntc_read_temp, +}; + static int ntc_thermistor_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -579,7 +583,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev) pdev_id->name); data->tz = thermal_zone_of_sensor_register(data->dev, 0, data->dev, - ntc_read_temp, NULL); + &ntc_of_thermal_ops); if (IS_ERR(data->tz)) { dev_dbg(&pdev->dev, "Failed to register to thermal fw.\n"); data->tz = NULL; diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 51719956cc03..ba9f478f64ee 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -158,6 +158,10 @@ ATTRIBUTE_GROUPS(tmp102); #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) +static const struct thermal_zone_of_device_ops tmp102_of_thermal_ops = { + .get_temp = tmp102_read_temp, +}; + static int tmp102_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -215,7 +219,7 @@ static int tmp102_probe(struct i2c_client *client, } tmp102->hwmon_dev = hwmon_dev; tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, - tmp102_read_temp, NULL); + &tmp102_of_thermal_ops); if (IS_ERR(tmp102->tz)) tmp102->tz = NULL; diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 62143ba31001..b7982f0a6eaf 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "thermal_core.h" @@ -77,8 +78,7 @@ struct __thermal_bind_params { * @num_tbps: number of thermal bind params * @tbps: an array of thermal bind params (0..num_tbps - 1) * @sensor_data: sensor private data used while reading temperature and trend - * @get_temp: sensor callback to read temperature - * @get_trend: sensor callback to read temperature trend + * @ops: set of callbacks to handle the thermal zone based on DT */ struct __thermal_zone { @@ -96,8 +96,7 @@ struct __thermal_zone { /* sensor interface */ void *sensor_data; - int (*get_temp)(void *, long *); - int (*get_trend)(void *, long *); + const struct thermal_zone_of_device_ops *ops; }; /*** DT thermal zone device callbacks ***/ @@ -107,10 +106,10 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, { struct __thermal_zone *data = tz->devdata; - if (!data->get_temp) + if (!data->ops->get_temp) return -EINVAL; - return data->get_temp(data->sensor_data, temp); + return data->ops->get_temp(data->sensor_data, temp); } static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, @@ -120,10 +119,10 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, long dev_trend; int r; - if (!data->get_trend) + if (!data->ops->get_trend) return -EINVAL; - r = data->get_trend(data->sensor_data, &dev_trend); + r = data->ops->get_trend(data->sensor_data, &dev_trend); if (r) return r; @@ -324,8 +323,7 @@ static struct thermal_zone_device_ops of_thermal_ops = { static struct thermal_zone_device * thermal_zone_of_add_sensor(struct device_node *zone, struct device_node *sensor, void *data, - int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) + const struct thermal_zone_of_device_ops *ops) { struct thermal_zone_device *tzd; struct __thermal_zone *tz; @@ -336,9 +334,11 @@ thermal_zone_of_add_sensor(struct device_node *zone, tz = tzd->devdata; + if (!ops) + return ERR_PTR(-EINVAL); + mutex_lock(&tzd->lock); - tz->get_temp = get_temp; - tz->get_trend = get_trend; + tz->ops = ops; tz->sensor_data = data; tzd->ops->get_temp = of_thermal_get_temp; @@ -356,8 +356,7 @@ thermal_zone_of_add_sensor(struct device_node *zone, * than one sensors * @data: a private pointer (owned by the caller) that will be passed * back, when a temperature reading is needed. - * @get_temp: a pointer to a function that reads the sensor temperature. - * @get_trend: a pointer to a function that reads the sensor temperature trend. + * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. * * This function will search the list of thermal zones described in device * tree and look for the zone that refer to the sensor device pointed by @@ -382,9 +381,8 @@ thermal_zone_of_add_sensor(struct device_node *zone, * check the return value with help of IS_ERR() helper. */ struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int sensor_id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) +thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, + const struct thermal_zone_of_device_ops *ops) { struct device_node *np, *child, *sensor_np; struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); @@ -426,9 +424,7 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, if (sensor_specs.np == sensor_np && id == sensor_id) { tzd = thermal_zone_of_add_sensor(child, sensor_np, - data, - get_temp, - get_trend); + data, ops); of_node_put(sensor_specs.np); of_node_put(child); goto exit; @@ -476,8 +472,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, tzd->ops->get_temp = NULL; tzd->ops->get_trend = NULL; - tz->get_temp = NULL; - tz->get_trend = NULL; + tz->ops = NULL; tz->sensor_data = NULL; mutex_unlock(&tzd->lock); } diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c index 70f7e9ef4355..9197fc05c5cc 100644 --- a/drivers/thermal/tegra_soctherm.c +++ b/drivers/thermal/tegra_soctherm.c @@ -317,6 +317,10 @@ static int tegra_thermctl_get_temp(void *data, long *out_temp) return 0; } +static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = { + .get_temp = tegra_thermctl_get_temp, +}; + static const struct of_device_id tegra_soctherm_of_match[] = { { .compatible = "nvidia,tegra124-soctherm" }, { }, @@ -416,8 +420,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev) zone->shift = t124_thermctl_temp_zones[i].shift; tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone, - tegra_thermctl_get_temp, - NULL); + &tegra_of_thermal_ops); if (IS_ERR(tz)) { err = PTR_ERR(tz); dev_err(&pdev->dev, "failed to register sensor: %d\n", diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 9eec26dc0448..5fd03865e396 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -286,6 +286,11 @@ static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); } +static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { + .get_temp = __ti_thermal_get_temp, + .get_trend = __ti_thermal_get_trend, +}; + static struct thermal_zone_device_ops ti_thermal_ops = { .get_temp = ti_thermal_get_temp, .get_trend = ti_thermal_get_trend, @@ -333,8 +338,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, /* in case this is specified by DT */ data->ti_thermal = thermal_zone_of_sensor_register(bgp->dev, id, - data, __ti_thermal_get_temp, - __ti_thermal_get_trend); + data, &ti_of_thermal_ops); if (IS_ERR(data->ti_thermal)) { /* Create thermal zone */ data->ti_thermal = thermal_zone_device_register(domain, diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ef90838b36a0..5bc28a70014e 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -289,19 +289,31 @@ struct thermal_genl_event { enum events event; }; +/** + * struct thermal_zone_of_device_ops - scallbacks for handling DT based zones + * + * Mandatory: + * @get_temp: a pointer to a function that reads the sensor temperature. + * + * Optional: + * @get_trend: a pointer to a function that reads the sensor temperature trend. + */ +struct thermal_zone_of_device_ops { + int (*get_temp)(void *, long *); + int (*get_trend)(void *, long *); +}; + /* Function declarations */ #ifdef CONFIG_THERMAL_OF struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)); +thermal_zone_of_sensor_register(struct device *dev, int id, void *data, + const struct thermal_zone_of_device_ops *ops); void thermal_zone_of_sensor_unregister(struct device *dev, struct thermal_zone_device *tz); #else static inline struct thermal_zone_device * -thermal_zone_of_sensor_register(struct device *dev, int id, - void *data, int (*get_temp)(void *, long *), - int (*get_trend)(void *, long *)) +thermal_zone_of_sensor_register(struct device *dev, int id, void *data, + const struct thermal_zone_of_device_ops *ops) { return NULL; } -- GitLab From 77109411d5d24471ffa391dce56ba3559fb87d94 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:56 +0100 Subject: [PATCH 5516/9457] thermal: exynos: remove needless triminfo_data abstraction reg->triminfo_data is used only in exynos_tmu_initialize() and the code has already different paths for Exynos5440 and other SoC types (on which TRIMINFO_DATA register offset is identical) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 10 +++++----- drivers/thermal/samsung/exynos_tmu.h | 3 --- drivers/thermal/samsung/exynos_tmu_data.c | 6 ------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 49c09243fd38..bb05355620c2 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -182,22 +182,22 @@ static int exynos_tmu_initialize(struct platform_device *pdev) switch (data->id) { case 0: trim_info = readl(data->base + - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); + EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); break; case 1: - trim_info = readl(data->base + reg->triminfo_data); + trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); break; case 2: trim_info = readl(data->base - - EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data); + EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); } } else { /* On exynos5420 the triminfo register is in the shared space */ if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) trim_info = readl(data->base_second + - reg->triminfo_data); + EXYNOS_TMU_REG_TRIMINFO); else - trim_info = readl(data->base + reg->triminfo_data); + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); } data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index c58c7663a3fe..91e2317f4be2 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -76,7 +76,6 @@ enum soc_type { * struct exynos_tmu_register - register descriptors to access registers and * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. - * @triminfo_data: register containing 2 pont trimming data * @triminfo_ctrl: trim info controller register. * @triminfo_ctrl_count: the number of trim info controller register. * @tmu_ctrl: TMU main controller register. @@ -107,8 +106,6 @@ enum soc_type { * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { - u32 triminfo_data; - u32 triminfo_ctrl[MAX_TRIMINFO_CTRL_REG]; u32 triminfo_ctrl_count; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 1724f6cdaef8..a6088fffb169 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,7 +26,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, @@ -85,7 +84,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON1, .triminfo_ctrl[1] = EXYNOS_TMU_TRIMINFO_CON2, .triminfo_ctrl_count = 2, @@ -168,7 +166,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON2, .triminfo_ctrl_count = 1, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, @@ -262,7 +259,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, @@ -341,7 +337,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .triminfo_data = EXYNOS_TMU_REG_TRIMINFO, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, @@ -428,7 +423,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM, .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, -- GitLab From 5d022061cabe5b4967d9f5b65d2ce9c121aa458a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:57 +0100 Subject: [PATCH 5517/9457] thermal: exynos: remove needless tmu_status abstraction reg->tmu_status is used only in exynos_tmu_initialize() and it is accessed only if TMU_SUPPORT_READY_STATUS flag is set. This flag is not set for Exynos5440 and TMU_STATUS register offset is identical for all other SoC types so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 3 --- drivers/thermal/samsung/exynos_tmu_data.c | 6 ------ drivers/thermal/samsung/exynos_tmu_data.h | 1 - 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index bb05355620c2..ac436379d9ce 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -154,7 +154,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) clk_enable(data->clk_sec); if (TMU_SUPPORTS(pdata, READY_STATUS)) { - status = readb(data->base + reg->tmu_status); + status = readb(data->base + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 91e2317f4be2..7849d8f2128c 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -83,7 +83,6 @@ enum soc_type { * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. - * @tmu_status: register drescribing the TMU status. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_temp: register containing the base threshold level. * @threshold_th0: Register containing first set of rising levels. @@ -115,8 +114,6 @@ struct exynos_tmu_registers { u32 therm_trip_mode_mask; u32 therm_trip_en_shift; - u32 tmu_status; - u32 tmu_cur_temp; u32 threshold_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index a6088fffb169..49c814299bd9 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -27,7 +27,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP, .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, @@ -92,7 +91,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -173,7 +171,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -263,7 +260,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -341,7 +337,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS_TMU_REG_STATUS, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -427,7 +422,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, - .tmu_status = EXYNOS5440_TMU_S0_7_STATUS, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index 63de598c9c2c..e02ef992f71e 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -88,7 +88,6 @@ #define EXYNOS5440_TMU_S0_7_TRIM 0x000 #define EXYNOS5440_TMU_S0_7_CTRL 0x020 #define EXYNOS5440_TMU_S0_7_DEBUG 0x040 -#define EXYNOS5440_TMU_S0_7_STATUS 0x060 #define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 #define EXYNOS5440_TMU_S0_7_TH0 0x110 #define EXYNOS5440_TMU_S0_7_TH1 0x130 -- GitLab From 6b1fbbdebae2016fa8a7505021ff2924e75d9e82 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:58 +0100 Subject: [PATCH 5518/9457] thermal: exynos: remove needless threshold_temp abstraction reg->threshold_temp is used only in exynos_tmu_initialize() and is accessed only on Exynos4210 (other SoC types don't even have threshold_temp entry assigned in their struct exynos_tmu_registers instances) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 3 --- drivers/thermal/samsung/exynos_tmu_data.c | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index ac436379d9ce..12e6f16d75c7 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -219,7 +219,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); writeb(threshold_code, - data->base + reg->threshold_temp); + data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); for (i = 0; i < pdata->non_hw_trigger_levels; i++) writeb(pdata->trigger_levels[i], data->base + reg->threshold_th0 + i * sizeof(reg->threshold_th0)); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 7849d8f2128c..d69321579140 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -84,7 +84,6 @@ enum soc_type { * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @threshold_temp: register containing the base threshold level. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. * @threshold_th2: Register containing third set of rising levels. @@ -116,8 +115,6 @@ struct exynos_tmu_registers { u32 tmu_cur_temp; - u32 threshold_temp; - u32 threshold_th0; u32 threshold_th1; u32 threshold_th2; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 49c814299bd9..8153c41b9725 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -28,7 +28,6 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP, .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, -- GitLab From 32f9520569ed6bf75673063b8b1c4f2e46a75c48 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:00:59 +0100 Subject: [PATCH 5519/9457] thermal: exynos: remove needless triminfo_ctrl abstraction reg->triminfo_ctrl[] is used in only exynos_tmu_initialize() and accessed only if TMU_SUPPORT_TRIM_RELOAD flag is set. This flag is set only on Exynos3250, Exynos4412 and Exynos5250 (other SoC types don't even have triminfo_ctrl[] entries assigned in their struct exynos_tmu_registers instances) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_thermal_common.h | 1 - drivers/thermal/samsung/exynos_tmu.c | 15 +++++++-------- drivers/thermal/samsung/exynos_tmu.h | 7 ------- drivers/thermal/samsung/exynos_tmu_data.c | 8 -------- 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h index 158f5aa8dc5d..cd4471925cdd 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.h +++ b/drivers/thermal/samsung/exynos_thermal_common.h @@ -27,7 +27,6 @@ #define SENSOR_NAME_LEN 16 #define MAX_TRIP_COUNT 8 #define MAX_COOLING_DEVICE 4 -#define MAX_TRIMINFO_CTRL_REG 2 #define ACTIVE_INTERVAL 500 #define IDLE_INTERVAL 10000 diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 12e6f16d75c7..160e7fa5e1bc 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -162,15 +162,14 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) { - for (i = 0; i < reg->triminfo_ctrl_count; i++) { - if (pdata->triminfo_reload[i]) { - ctrl = readl(data->base + - reg->triminfo_ctrl[i]); - ctrl |= pdata->triminfo_reload[i]; - writel(ctrl, data->base + - reg->triminfo_ctrl[i]); - } + if (data->soc == SOC_ARCH_EXYNOS3250) { + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); } + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); } /* Save trimming info in order to perform calibration */ diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d69321579140..cee81a1de8e3 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -76,8 +76,6 @@ enum soc_type { * struct exynos_tmu_register - register descriptors to access registers and * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. - * @triminfo_ctrl: trim info controller register. - * @triminfo_ctrl_count: the number of trim info controller register. * @tmu_ctrl: TMU main controller register. * @test_mux_addr_shift: shift bits of test mux address. * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. @@ -104,9 +102,6 @@ enum soc_type { * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { - u32 triminfo_ctrl[MAX_TRIMINFO_CTRL_REG]; - u32 triminfo_ctrl_count; - u32 tmu_ctrl; u32 test_mux_addr_shift; u32 therm_trip_mode_shift; @@ -184,7 +179,6 @@ struct exynos_tmu_registers { * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming * @test_mux; information if SoC supports test MUX - * @triminfo_reload: reload value to read TRIMINFO register * @cal_type: calibration type for temperature * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may @@ -215,7 +209,6 @@ struct exynos_tmu_platform_data { u8 second_point_trim; u8 default_temp_offset; u8 test_mux; - u8 triminfo_reload[MAX_TRIMINFO_CTRL_REG]; enum calibration_type cal_type; enum soc_type type; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 8153c41b9725..d4b9a68e803d 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -82,9 +82,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON1, - .triminfo_ctrl[1] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 2, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, @@ -140,8 +137,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ - .triminfo_reload[1] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ @@ -163,8 +158,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .triminfo_ctrl[0] = EXYNOS_TMU_TRIMINFO_CON2, - .triminfo_ctrl_count = 1, .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, @@ -221,7 +214,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .triminfo_reload[0] = EXYNOS_TRIMINFO_RELOAD_ENABLE, \ .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ -- GitLab From bfb2b88c79df839779586e0247456bd79882b145 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:00 +0100 Subject: [PATCH 5520/9457] thermal: exynos: remove needless test_mux_addr_shift abstraction reg->test_mux_addr_shift is used only if pdata->test_mux is non-zero. pdata->test_mux is defined only on Exynos3250 and Exynos4412 (other SoC types don't even have pdata->test_mux entry assigned in their struct exynos_tmu_registers instances) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 160e7fa5e1bc..c8d6cdde272c 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -295,7 +295,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con = readl(data->base + reg->tmu_ctrl); if (pdata->test_mux) - con |= (pdata->test_mux << reg->test_mux_addr_shift); + con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index cee81a1de8e3..0fb10d158471 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,7 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @test_mux_addr_shift: shift bits of test mux address. * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. @@ -103,7 +102,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 test_mux_addr_shift; u32 therm_trip_mode_shift; u32 therm_trip_mode_mask; u32 therm_trip_en_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d4b9a68e803d..4ca1283f1afb 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,7 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, @@ -159,7 +158,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT, .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, -- GitLab From b9504a6a3d668e4995420e311869291b21b81b37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:01 +0100 Subject: [PATCH 5521/9457] thermal: exynos: remove needless therm_trip_[mode,mask]_shift abstractions reg->therm_trip_mode_shift and reg->therm_trip_mode_mask are used only in exynos_tmu_control() and accessed only if pdata->noise_cancel_mode is non-zero. pdata->noise_cancel field is not defined on Exynos4210 (also therm_trip_mode_shift and therm_trip_mode_mask entries are not even assigned in exynos4210_tmu_registers but they are assigned to identical values for all other SoC types) so the abstractions are not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 5 ++--- drivers/thermal/samsung/exynos_tmu.h | 4 ---- drivers/thermal/samsung/exynos_tmu_data.c | 10 ---------- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index c8d6cdde272c..fb3841113b72 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -304,9 +304,8 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con |= (pdata->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT); if (pdata->noise_cancel_mode) { - con &= ~(reg->therm_trip_mode_mask << - reg->therm_trip_mode_shift); - con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift); + con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT); + con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); } if (on) { diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 0fb10d158471..88c16d7302cb 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,8 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register. - * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register. * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. @@ -102,8 +100,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 therm_trip_mode_shift; - u32 therm_trip_mode_mask; u32 therm_trip_en_shift; u32 tmu_cur_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4ca1283f1afb..4a44eb7b11fe 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,8 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -158,8 +156,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -246,8 +242,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -323,8 +317,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, @@ -408,8 +400,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, - .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT, - .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK, .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, -- GitLab From 77a37a92ca18e4385bfcca9f2762d39fe83110b9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:02 +0100 Subject: [PATCH 5522/9457] thermal: exynos: remove needless therm_trip_en_shift abstraction reg->therm_trip_en_shift is used only in exynos_tmu_initialize() and not accessed on Exynos4210 (also reg->therm_trip_en_shift is not even assigned in exynos4210_tmu_registers but it is assigned to identical value for all other SoC types) so the register abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 5 ----- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index fb3841113b72..3f3b8cf0455a 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -266,7 +266,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) data->base + reg->threshold_th2); } con = readl(data->base + reg->tmu_ctrl); - con |= (1 << reg->therm_trip_en_shift); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); writel(con, data->base + reg->tmu_ctrl); } } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 88c16d7302cb..4798313ca5e1 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -77,7 +77,6 @@ enum soc_type { * bitfields. The register validity, offsets and bitfield values may vary * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. - * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register. * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. @@ -100,7 +99,6 @@ enum soc_type { */ struct exynos_tmu_registers { u32 tmu_ctrl; - u32 therm_trip_en_shift; u32 tmu_cur_temp; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4a44eb7b11fe..a120a8cd80ad 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -83,7 +83,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -156,7 +155,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -242,7 +240,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -317,7 +314,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .threshold_th0 = EXYNOS_THD_TEMP_RISE, .threshold_th1 = EXYNOS_THD_TEMP_FALL, @@ -400,7 +396,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, - .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, -- GitLab From 9e288d6430373a679d1ee88ff90813cd6be20dd2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:03 +0100 Subject: [PATCH 5523/9457] thermal: exynos: remove needless emul_temp_shift abstraction reg->emul_temp_shift is used only in exynos_tmu_set_emulation() and accessed only if TMU_SUPPORT_EMULATION flag is set. This flag is not set for Exynos4210 (reg->emul_temp_shift field is not even assigned in exynos4210_tmu_registers and is assigned to identical value for all other SoC types) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 4 ++-- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 5 ----- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 3f3b8cf0455a..c108a1f3de71 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -383,8 +383,8 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); } - val &= ~(EXYNOS_EMUL_DATA_MASK << reg->emul_temp_shift); - val |= (temp_to_code(data, temp) << reg->emul_temp_shift) | + val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); + val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE; } else { val &= ~EXYNOS_EMUL_ENABLE; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 4798313ca5e1..ed3d816ae24c 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @emul_temp_shift: shift bits of emulation temperature. * @emul_time_shift: shift bits of emulation time. * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. @@ -119,7 +118,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - u32 emul_temp_shift; u32 emul_time_shift; u32 tmu_irqstatus; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index a120a8cd80ad..c35a6eadafd1 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -94,7 +94,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -167,7 +166,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -252,7 +250,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -327,7 +324,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; @@ -411,7 +407,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, - .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT, .tmu_pmin = EXYNOS5440_TMU_PMIN, }; -- GitLab From 6070c2ca37c3b04a007541761b244afebc3e9876 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:04 +0100 Subject: [PATCH 5524/9457] thermal: exynos: remove needless emul_time_shift abstraction reg->emul_time_shift is used only in exynos_tmu_set_emulation() and accessed only if TMU_SUPPORT_EMUL_TIME flag is set. This flag is not set for Exynos4210 and Exynos5440 (reg->emul_time_shift field is not even assigned in exynos[4210,5440]_tmu_registers and is assigned to identical value for all other SoC types) so the abstraction is not needed and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 4 ++-- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index c108a1f3de71..e35c2895b4ed 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -380,8 +380,8 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) temp /= MCELSIUS; if (TMU_SUPPORTS(pdata, EMUL_TIME)) { - val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift); - val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift); + val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); + val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); } val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ed3d816ae24c..2694298eef59 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @emul_time_shift: shift bits of emulation time. * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. */ @@ -118,7 +117,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - u32 emul_time_shift; u32 tmu_irqstatus; u32 tmu_pmin; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index c35a6eadafd1..cef0b9744aef 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -94,7 +94,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define EXYNOS3250_TMU_DATA \ @@ -166,7 +165,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define EXYNOS4412_TMU_DATA \ @@ -250,7 +248,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define __EXYNOS5260_TMU_DATA \ @@ -324,7 +321,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, - .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT, }; #define __EXYNOS5420_TMU_DATA \ -- GitLab From 421d5d127d422bb98ce96ffa70af713698035f93 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:05 +0100 Subject: [PATCH 5525/9457] thermal: exynos: replace tmu_irqstatus check by Exynos5440 one reg->tmu_irqstatus is set to non-zero value only for Exynos5440 so replace check for non-zero value of reg->tmu_irqstatus by explicitly checking for Exynos5440 SoC type. Then remove no longer needed reg->tmu_irqstatus register abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 6 ++---- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index e35c2895b4ed..839b07bbcebf 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -407,15 +407,13 @@ static void exynos_tmu_work(struct work_struct *work) { struct exynos_tmu_data *data = container_of(work, struct exynos_tmu_data, irq_work); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; unsigned int val_type; if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); /* Find which sensor generated this interrupt */ - if (reg->tmu_irqstatus) { - val_type = readl(data->base_second + reg->tmu_irqstatus); + if (data->soc == SOC_ARCH_EXYNOS5440) { + val_type = readl(data->base_second + EXYNOS5440_TMU_IRQ_STATUS); if (!((val_type >> data->id) & 0x1)) goto out; } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 2694298eef59..5c2cef1770dd 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @tmu_irqstatus: register to find which TMU generated interrupts. * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { @@ -118,7 +117,6 @@ struct exynos_tmu_registers { u32 emul_con; - u32 tmu_irqstatus; u32 tmu_pmin; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index cef0b9744aef..557b4a598b37 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -401,7 +401,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, .tmu_pmin = EXYNOS5440_TMU_PMIN, }; -- GitLab From 0c78b4d88f1c5e09800ad99d705699cda7411d51 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:06 +0100 Subject: [PATCH 5526/9457] thermal: exynos: replace tmu_pmin check by Exynos5440 one reg->tmu_pmin is set to non-zero value only for Exynos5440 so replace check for non-zero value of reg->tmu_pmin by explicitly checking for Exynos5440 SoC type. Then remove no longer needed reg->tmu_pmin register abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 4 ++-- drivers/thermal/samsung/exynos_tmu.h | 3 --- drivers/thermal/samsung/exynos_tmu_data.c | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 839b07bbcebf..411c4650353e 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -271,8 +271,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } } /*Clear the PMIN in the common TMU register*/ - if (reg->tmu_pmin && !data->id) - writel(0, data->base_second + reg->tmu_pmin); + if (data->soc == SOC_ARCH_EXYNOS5440 && !data->id) + writel(0, data->base_second + EXYNOS5440_TMU_PMIN); out: clk_disable(data->clk); mutex_unlock(&data->lock); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 5c2cef1770dd..e8510aaceb05 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -92,7 +92,6 @@ enum soc_type { * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. - * @tmu_pmin: register to get/set the Pmin value. */ struct exynos_tmu_registers { u32 tmu_ctrl; @@ -116,8 +115,6 @@ struct exynos_tmu_registers { u32 tmu_intclear; u32 emul_con; - - u32 tmu_pmin; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 557b4a598b37..fe063d486ea4 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -402,7 +402,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, - .tmu_pmin = EXYNOS5440_TMU_PMIN, }; #define EXYNOS5440_TMU_DATA \ -- GitLab From 2516593e4ef0230b184e8ce4dd3de6caed5e6131 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:07 +0100 Subject: [PATCH 5527/9457] thermal: exynos: simplify HW_TRIP level setting Simplify HW_TRIP level setting in exynos_tmu_initialize() (don't pretend that the current code is hardware and configuration independent and just do SoC type check explicitly). Then remove no longer needed reg->threshold_[th2,th3_l0_shift] abstractions (only assigned for Exynos5440 in exynos5440_tmu_registers) and EXYNOS_MAX_TRIGGER_PER_REG define. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 10 +++++----- drivers/thermal/samsung/exynos_tmu.h | 4 ---- drivers/thermal/samsung/exynos_tmu_data.c | 2 -- drivers/thermal/samsung/exynos_tmu_data.h | 2 -- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 411c4650353e..1c15b37821cb 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -252,18 +252,18 @@ static int exynos_tmu_initialize(struct platform_device *pdev) (pdata->trigger_type[i] == HW_TRIP)) { threshold_code = temp_to_code(data, pdata->trigger_levels[i]); - if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) { + if (data->soc != SOC_ARCH_EXYNOS5440) { /* 1-4 level to be assigned in th0 reg */ rising_threshold &= ~(0xff << 8 * i); rising_threshold |= threshold_code << 8 * i; writel(rising_threshold, - data->base + reg->threshold_th0); - } else if (i == EXYNOS_MAX_TRIGGER_PER_REG) { + data->base + EXYNOS_THD_TEMP_RISE); + } else { /* 5th level to be assigned in th2 reg */ rising_threshold = - threshold_code << reg->threshold_th3_l0_shift; + threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; writel(rising_threshold, - data->base + reg->threshold_th2); + data->base + EXYNOS5440_TMU_S0_7_TH2); } con = readl(data->base + reg->tmu_ctrl); con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index e8510aaceb05..ebe39b433da4 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -80,8 +80,6 @@ enum soc_type { * @tmu_cur_temp: register containing the current temperature of the TMU. * @threshold_th0: Register containing first set of rising levels. * @threshold_th1: Register containing second set of rising levels. - * @threshold_th2: Register containing third set of rising levels. - * @threshold_th3_l0_shift: shift bits of level0 threshold temperature. * @tmu_inten: register containing the different threshold interrupt enable bits. * @inten_rise0_shift: shift bits of rising 0 interrupt bits. @@ -100,8 +98,6 @@ struct exynos_tmu_registers { u32 threshold_th0; u32 threshold_th1; - u32 threshold_th2; - u32 threshold_th3_l0_shift; u32 tmu_inten; u32 inten_rise0_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index fe063d486ea4..f81c940fe884 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -391,8 +391,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, - .threshold_th2 = EXYNOS5440_TMU_S0_7_TH2, - .threshold_th3_l0_shift = EXYNOS5440_TMU_TH_RISE4_SHIFT, .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index e02ef992f71e..2af312d8f7b5 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -72,8 +72,6 @@ #define EXYNOS_EMUL_DATA_MASK 0xFF #define EXYNOS_EMUL_ENABLE 0x1 -#define EXYNOS_MAX_TRIGGER_PER_REG 4 - /* Exynos5260 specific */ #define EXYNOS5260_TMU_REG_INTEN 0xC0 #define EXYNOS5260_TMU_REG_INTSTAT 0xC4 -- GitLab From 23f146296c6a166b9ba3d810a6a53cb5df6a5b4f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:08 +0100 Subject: [PATCH 5528/9457] thermal: exynos: replace threshold_falling check by Exynos SoC type one Replace pdata->threshold_falling check for non-zero value in exynos_tmu_initialize() by an explicit check for a SoC type (all SoC types except Exynos5440 have pdata->threshold_falling assigned to non-zero value in their struct exynos_tmu_registers instances). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1c15b37821cb..4f7cad94771b 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -231,7 +231,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) pdata->trigger_levels[i]); rising_threshold &= ~(0xff << 8 * i); rising_threshold |= threshold_code << 8 * i; - if (pdata->threshold_falling) { + if (data->soc != SOC_ARCH_EXYNOS5440) { threshold_code = temp_to_code(data, pdata->trigger_levels[i] - pdata->threshold_falling); -- GitLab From 6f02fa18fbff39919f26c228e2e7f1f5b9b211e9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:09 +0100 Subject: [PATCH 5529/9457] thermal: exynos: remove TMU_SUPPORT_READY_STATUS flag Replace TMU_SUPPORT_READY_STATUS flag check in exynos_tmu_initialize() by an explicit check for a SoC type (all SoC types except Exynos5440 have TMU_SUPPORT_READY_STATUS flag set in their struct exynos_tmu_init_data instances). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 7 ++----- drivers/thermal/samsung/exynos_tmu_data.c | 14 +++++--------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 4f7cad94771b..33ee527fd211 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -153,7 +153,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); - if (TMU_SUPPORTS(pdata, READY_STATUS)) { + if (data->soc != SOC_ARCH_EXYNOS5440) { status = readb(data->base + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ebe39b433da4..d3d92058139e 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -54,8 +54,6 @@ enum soc_type { * be reloaded. * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can * be registered for falling trips also. - * TMU_SUPPORT_READY_STATUS - This feature tells that the TMU current - * state(active/idle) can be checked. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU @@ -66,9 +64,8 @@ enum soc_type { #define TMU_SUPPORT_MULTI_INST BIT(1) #define TMU_SUPPORT_TRIM_RELOAD BIT(2) #define TMU_SUPPORT_FALLING_TRIP BIT(3) -#define TMU_SUPPORT_READY_STATUS BIT(4) -#define TMU_SUPPORT_EMUL_TIME BIT(5) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(6) +#define TMU_SUPPORT_EMUL_TIME BIT(4) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(5) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index f81c940fe884..c327120046ef 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -73,7 +73,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, .registers = &exynos4210_tmu_registers, - .features = TMU_SUPPORT_READY_STATUS, }, }, .tmu_count = 1, @@ -133,8 +132,7 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .freq_tab_count = 2, \ .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -204,8 +202,7 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .freq_tab_count = 2, \ .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \ - TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -291,7 +288,7 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_EMUL_TIME) struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -364,14 +361,13 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5250, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME) + TMU_SUPPORT_EMUL_TIME) #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_READY_STATUS | TMU_SUPPORT_EMUL_TIME | \ - TMU_SUPPORT_ADDRESS_MULTIPLE) + TMU_SUPPORT_EMUL_TIME | TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { -- GitLab From 1e04ee8053b5f0af6bfab52b86a57de1c13c57ef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:10 +0100 Subject: [PATCH 5530/9457] thermal: exynos: remove TMU_SUPPORT_TRIM_RELOAD flag Replace TMU_SUPPORT_TRIM_RELOAD flag check in exynos_tmu_initialize() by an explicit check for a SoC type (only Exynos3250, Exynos4412 and Exynos5250 have TMU_SUPPORT_READY_STATUS flag set in their struct exynos_tmu_init_data instances). Please note that this requires adding separate SoC type for Exynos5420 so it doesn't get mistaken with Exynos5250. This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 5 ++++- drivers/thermal/samsung/exynos_tmu.h | 10 ++++------ drivers/thermal/samsung/exynos_tmu_data.c | 10 +++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 33ee527fd211..e4d75a1a17ae 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -161,7 +161,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } } - if (TMU_SUPPORTS(pdata, TRIM_RELOAD)) { + if (data->soc == SOC_ARCH_EXYNOS3250 || + data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS5250) { if (data->soc == SOC_ARCH_EXYNOS3250) { ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; @@ -626,6 +628,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) pdata->type == SOC_ARCH_EXYNOS4412 || pdata->type == SOC_ARCH_EXYNOS5250 || pdata->type == SOC_ARCH_EXYNOS5260 || + pdata->type == SOC_ARCH_EXYNOS5420 || pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO || pdata->type == SOC_ARCH_EXYNOS5440) data->soc = pdata->type; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d3d92058139e..adecc7ff5b8a 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -40,6 +40,7 @@ enum soc_type { SOC_ARCH_EXYNOS4412, SOC_ARCH_EXYNOS5250, SOC_ARCH_EXYNOS5260, + SOC_ARCH_EXYNOS5420, SOC_ARCH_EXYNOS5420_TRIMINFO, SOC_ARCH_EXYNOS5440, }; @@ -50,8 +51,6 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_TRIM_RELOAD - This features shows that trimming can - * be reloaded. * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can * be registered for falling trips also. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation @@ -62,10 +61,9 @@ enum soc_type { */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_TRIM_RELOAD BIT(2) -#define TMU_SUPPORT_FALLING_TRIP BIT(3) -#define TMU_SUPPORT_EMUL_TIME BIT(4) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(5) +#define TMU_SUPPORT_FALLING_TRIP BIT(2) +#define TMU_SUPPORT_EMUL_TIME BIT(3) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(4) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index c327120046ef..1ed8bdc117a0 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -131,8 +131,8 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { }, \ .freq_tab_count = 2, \ .registers = &exynos3250_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ + TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -201,8 +201,8 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { }, \ .freq_tab_count = 2, \ .registers = &exynos4412_tmu_registers, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \ - TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ + TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -359,7 +359,7 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5250, \ + .type = SOC_ARCH_EXYNOS5420, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) -- GitLab From 8328a4b1d67fa6a4e0c51c27ddb7cb61b562f33e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:11 +0100 Subject: [PATCH 5531/9457] thermal: exynos: add sanitize_temp_error() helper Factor out code for initializing data->temp_error[1,2] values from exynos_tmu_initialize() into sanitize_temp_error(). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index e4d75a1a17ae..b0c07151e2eb 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -139,6 +139,25 @@ static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) writel(val_irq, data->base + reg->tmu_intclear); } +static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + + data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; + data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & + EXYNOS_TMU_TEMP_MASK); + + if (!data->temp_error1 || + (pdata->min_efuse_value > data->temp_error1) || + (data->temp_error1 > pdata->max_efuse_value)) + data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; + + if (!data->temp_error2) + data->temp_error2 = + (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & + EXYNOS_TMU_TEMP_MASK; +} + static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); @@ -200,19 +219,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev) else trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); } - data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK; - data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) & - EXYNOS_TMU_TEMP_MASK); - - if (!data->temp_error1 || - (pdata->min_efuse_value > data->temp_error1) || - (data->temp_error1 > pdata->max_efuse_value)) - data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK; - - if (!data->temp_error2) - data->temp_error2 = - (pdata->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) & - EXYNOS_TMU_TEMP_MASK; + sanitize_temp_error(data, trim_info); rising_threshold = readl(data->base + reg->threshold_th0); -- GitLab From fe87789cd437378e7cf72c43b753703b2a835fc3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:12 +0100 Subject: [PATCH 5532/9457] thermal: exynos: add get_th_reg() helper Factor out code for preparing threshold register value from exynos_tmu_initialize() into get_th_reg(). This is a preparation for introducing per-SoC type tmu_initialize method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 37 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index b0c07151e2eb..6e82fdd860b0 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -158,6 +158,25 @@ static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) EXYNOS_TMU_TEMP_MASK; } +static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + int i; + + for (i = 0; i < pdata->non_hw_trigger_levels; i++) { + u8 temp = pdata->trigger_levels[i]; + + if (falling) + temp -= pdata->threshold_falling; + else + threshold &= ~(0xff << 8 * i); + + threshold |= temp_to_code(data, temp) << 8 * i; + } + + return threshold; +} + static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); @@ -221,8 +240,6 @@ static int exynos_tmu_initialize(struct platform_device *pdev) } sanitize_temp_error(data, trim_info); - rising_threshold = readl(data->base + reg->threshold_th0); - if (data->soc == SOC_ARCH_EXYNOS4210) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); @@ -235,18 +252,10 @@ static int exynos_tmu_initialize(struct platform_device *pdev) exynos_tmu_clear_irqs(data); } else { /* Write temperature code for rising and falling threshold */ - for (i = 0; i < pdata->non_hw_trigger_levels; i++) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - if (data->soc != SOC_ARCH_EXYNOS5440) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i] - - pdata->threshold_falling); - falling_threshold |= threshold_code << 8 * i; - } - } + rising_threshold = readl(data->base + reg->threshold_th0); + rising_threshold = get_th_reg(data, rising_threshold, false); + if (data->soc != SOC_ARCH_EXYNOS5440) + falling_threshold = get_th_reg(data, 0, true); writel(rising_threshold, data->base + reg->threshold_th0); -- GitLab From 72d1100b736d2ff597c5aa73bbef12050c686ee4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:13 +0100 Subject: [PATCH 5533/9457] thermal: exynos: add ->tmu_initialize method Add ->tmu_initialize method to struct exynos_tmu_data and use it in exynos_tmu_initialize(). Then add ->tmu_initialize implementations for Exynos4210, Exynos4412+ and Exynos5440. Finally remove no longer needed reg->threshold_th[0,1], reg->intclr_[fall,rise]_shift and reg->intclr_[rise,fall]_mask abstractions. There are more improvements available in the future on top of this patch like merging HW_TRIP level setting with setting of other levels for Exynos4412+ or adding separate method for clearing IRQs using INTCLEAR register (for Exynos5420, Exynos5260 and Exynos4412+). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 276 +++++++++++++--------- drivers/thermal/samsung/exynos_tmu.h | 5 - drivers/thermal/samsung/exynos_tmu_data.c | 11 - 3 files changed, 159 insertions(+), 133 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6e82fdd860b0..736ef7885878 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -52,6 +52,7 @@ * @temp_error2: fused value of the second point trim. * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. + * @tmu_initialize: SoC specific TMU initialization method */ struct exynos_tmu_data { int id; @@ -66,6 +67,7 @@ struct exynos_tmu_data { u8 temp_error1, temp_error2; struct regulator *regulator; struct thermal_sensor_conf *reg_conf; + int (*tmu_initialize)(struct platform_device *pdev); }; /* @@ -180,118 +182,13 @@ static u32 get_th_reg(struct exynos_tmu_data *data, u32 threshold, bool falling) static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int status, trim_info = 0, con, ctrl; - unsigned int rising_threshold = 0, falling_threshold = 0; - int ret = 0, threshold_code, i; + int ret; mutex_lock(&data->lock); clk_enable(data->clk); if (!IS_ERR(data->clk_sec)) clk_enable(data->clk_sec); - - if (data->soc != SOC_ARCH_EXYNOS5440) { - status = readb(data->base + EXYNOS_TMU_REG_STATUS); - if (!status) { - ret = -EBUSY; - goto out; - } - } - - if (data->soc == SOC_ARCH_EXYNOS3250 || - data->soc == SOC_ARCH_EXYNOS4412 || - data->soc == SOC_ARCH_EXYNOS5250) { - if (data->soc == SOC_ARCH_EXYNOS3250) { - ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); - ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; - writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); - } - ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); - ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; - writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); - } - - /* Save trimming info in order to perform calibration */ - if (data->soc == SOC_ARCH_EXYNOS5440) { - /* - * For exynos5440 soc triminfo value is swapped between TMU0 and - * TMU2, so the below logic is needed. - */ - switch (data->id) { - case 0: - trim_info = readl(data->base + - EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); - break; - case 1: - trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); - break; - case 2: - trim_info = readl(data->base - - EXYNOS5440_EFUSE_SWAP_OFFSET + EXYNOS5440_TMU_S0_7_TRIM); - } - } else { - /* On exynos5420 the triminfo register is in the shared space */ - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) - trim_info = readl(data->base_second + - EXYNOS_TMU_REG_TRIMINFO); - else - trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); - } - sanitize_temp_error(data, trim_info); - - if (data->soc == SOC_ARCH_EXYNOS4210) { - /* Write temperature code for threshold */ - threshold_code = temp_to_code(data, pdata->threshold); - writeb(threshold_code, - data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); - for (i = 0; i < pdata->non_hw_trigger_levels; i++) - writeb(pdata->trigger_levels[i], data->base + - reg->threshold_th0 + i * sizeof(reg->threshold_th0)); - - exynos_tmu_clear_irqs(data); - } else { - /* Write temperature code for rising and falling threshold */ - rising_threshold = readl(data->base + reg->threshold_th0); - rising_threshold = get_th_reg(data, rising_threshold, false); - if (data->soc != SOC_ARCH_EXYNOS5440) - falling_threshold = get_th_reg(data, 0, true); - - writel(rising_threshold, - data->base + reg->threshold_th0); - writel(falling_threshold, - data->base + reg->threshold_th1); - - exynos_tmu_clear_irqs(data); - - /* if last threshold limit is also present */ - i = pdata->max_trigger_level - 1; - if (pdata->trigger_levels[i] && - (pdata->trigger_type[i] == HW_TRIP)) { - threshold_code = temp_to_code(data, - pdata->trigger_levels[i]); - if (data->soc != SOC_ARCH_EXYNOS5440) { - /* 1-4 level to be assigned in th0 reg */ - rising_threshold &= ~(0xff << 8 * i); - rising_threshold |= threshold_code << 8 * i; - writel(rising_threshold, - data->base + EXYNOS_THD_TEMP_RISE); - } else { - /* 5th level to be assigned in th2 reg */ - rising_threshold = - threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; - writel(rising_threshold, - data->base + EXYNOS5440_TMU_S0_7_TH2); - } - con = readl(data->base + reg->tmu_ctrl); - con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); - writel(con, data->base + reg->tmu_ctrl); - } - } - /*Clear the PMIN in the common TMU register*/ - if (data->soc == SOC_ARCH_EXYNOS5440 && !data->id) - writel(0, data->base_second + EXYNOS5440_TMU_PMIN); -out: + ret = data->tmu_initialize(pdev); clk_disable(data->clk); mutex_unlock(&data->lock); if (!IS_ERR(data->clk_sec)) @@ -347,6 +244,143 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) mutex_unlock(&data->lock); } +static int exynos4210_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int status; + int ret = 0, threshold_code, i; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + sanitize_temp_error(data, readl(data->base + EXYNOS_TMU_REG_TRIMINFO)); + + /* Write temperature code for threshold */ + threshold_code = temp_to_code(data, pdata->threshold); + writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); + + for (i = 0; i < pdata->non_hw_trigger_levels; i++) + writeb(pdata->trigger_levels[i], data->base + + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); + + exynos_tmu_clear_irqs(data); +out: + return ret; +} + +static int exynos4412_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int status, trim_info, con, ctrl, rising_threshold; + int ret = 0, threshold_code, i; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + if (data->soc == SOC_ARCH_EXYNOS3250 || + data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS5250) { + if (data->soc == SOC_ARCH_EXYNOS3250) { + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1); + } + ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2); + ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE; + writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2); + } + + /* On exynos5420 the triminfo register is in the shared space */ + if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) + trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO); + else + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); + + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS_THD_TEMP_RISE); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); + + exynos_tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 1-4 level to be assigned in th0 reg */ + rising_threshold &= ~(0xff << 8 * i); + rising_threshold |= threshold_code << 8 * i; + writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); + con = readl(data->base + EXYNOS_TMU_REG_CONTROL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); + } +out: + return ret; +} + +static int exynos5440_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int trim_info = 0, con, rising_threshold; + int ret = 0, threshold_code, i; + + /* + * For exynos5440 soc triminfo value is swapped between TMU0 and + * TMU2, so the below logic is needed. + */ + switch (data->id) { + case 0: + trim_info = readl(data->base + EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 1: + trim_info = readl(data->base + EXYNOS5440_TMU_S0_7_TRIM); + break; + case 2: + trim_info = readl(data->base - EXYNOS5440_EFUSE_SWAP_OFFSET + + EXYNOS5440_TMU_S0_7_TRIM); + } + sanitize_temp_error(data, trim_info); + + /* Write temperature code for rising and falling threshold */ + rising_threshold = readl(data->base + EXYNOS5440_TMU_S0_7_TH0); + rising_threshold = get_th_reg(data, rising_threshold, false); + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); + writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); + + exynos_tmu_clear_irqs(data); + + /* if last threshold limit is also present */ + i = pdata->max_trigger_level - 1; + if (pdata->trigger_levels[i] && pdata->trigger_type[i] == HW_TRIP) { + threshold_code = temp_to_code(data, pdata->trigger_levels[i]); + /* 5th level to be assigned in th2 reg */ + rising_threshold = + threshold_code << EXYNOS5440_TMU_TH_RISE4_SHIFT; + writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH2); + con = readl(data->base + EXYNOS5440_TMU_S0_7_CTRL); + con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); + } + /* Clear the PMIN in the common TMU register */ + if (!data->id) + writel(0, data->base_second + EXYNOS5440_TMU_PMIN); + return ret; +} + static int exynos_tmu_read(struct exynos_tmu_data *data) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -639,16 +673,24 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - if (pdata->type == SOC_ARCH_EXYNOS3250 || - pdata->type == SOC_ARCH_EXYNOS4210 || - pdata->type == SOC_ARCH_EXYNOS4412 || - pdata->type == SOC_ARCH_EXYNOS5250 || - pdata->type == SOC_ARCH_EXYNOS5260 || - pdata->type == SOC_ARCH_EXYNOS5420 || - pdata->type == SOC_ARCH_EXYNOS5420_TRIMINFO || - pdata->type == SOC_ARCH_EXYNOS5440) - data->soc = pdata->type; - else { + data->soc = pdata->type; + + switch (data->soc) { + case SOC_ARCH_EXYNOS4210: + data->tmu_initialize = exynos4210_tmu_initialize; + break; + case SOC_ARCH_EXYNOS3250: + case SOC_ARCH_EXYNOS4412: + case SOC_ARCH_EXYNOS5250: + case SOC_ARCH_EXYNOS5260: + case SOC_ARCH_EXYNOS5420: + case SOC_ARCH_EXYNOS5420_TRIMINFO: + data->tmu_initialize = exynos4412_tmu_initialize; + break; + case SOC_ARCH_EXYNOS5440: + data->tmu_initialize = exynos5440_tmu_initialize; + break; + default: ret = -EINVAL; dev_err(&pdev->dev, "Platform not supported\n"); goto err_clk; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index adecc7ff5b8a..f186f4ff44c4 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -73,8 +73,6 @@ enum soc_type { * slightly across different exynos SOC's. * @tmu_ctrl: TMU main controller register. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @threshold_th0: Register containing first set of rising levels. - * @threshold_th1: Register containing second set of rising levels. * @tmu_inten: register containing the different threshold interrupt enable bits. * @inten_rise0_shift: shift bits of rising 0 interrupt bits. @@ -91,9 +89,6 @@ struct exynos_tmu_registers { u32 tmu_cur_temp; - u32 threshold_th0; - u32 threshold_th1; - u32 tmu_inten; u32 inten_rise0_shift; u32 inten_rise1_shift; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 1ed8bdc117a0..db3b3bc53f76 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -28,7 +28,6 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -83,8 +82,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -152,8 +149,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -234,8 +229,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS5260_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -306,8 +299,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .threshold_th0 = EXYNOS_THD_TEMP_RISE, - .threshold_th1 = EXYNOS_THD_TEMP_FALL, .tmu_inten = EXYNOS_TMU_REG_INTEN, .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, @@ -385,8 +376,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, - .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0, - .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1, .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, -- GitLab From d00671c3ae3f4bfdfbdd1413150ad1a3a135ad1e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:14 +0100 Subject: [PATCH 5534/9457] thermal: exynos: add get_con_reg() helper Factor out code for preparing TMU_CONTROL register value from exynos_tmu_control() into get_con_reg(). This is a preparation for introducing per-SoC type tmu_control method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 736ef7885878..f65e6d807afe 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -197,17 +197,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev) return ret; } -static void exynos_tmu_control(struct platform_device *pdev, bool on) +static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) { - struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int con, interrupt_en; - - mutex_lock(&data->lock); - clk_enable(data->clk); - - con = readl(data->base + reg->tmu_ctrl); if (pdata->test_mux) con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); @@ -223,6 +215,21 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT); } + return con; +} + +static void exynos_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + const struct exynos_tmu_registers *reg = pdata->registers; + unsigned int con, interrupt_en; + + mutex_lock(&data->lock); + clk_enable(data->clk); + + con = get_con_reg(data, readl(data->base + reg->tmu_ctrl)); + if (on) { con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); interrupt_en = -- GitLab From 37f9034f99c3c1ba9087357fbbc2b79fc1a30e72 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:15 +0100 Subject: [PATCH 5535/9457] thermal: exynos: add ->tmu_control method Add ->tmu_control method to struct exynos_tmu_data and use it in exynos_tmu_control(). Then add ->tmu_control implementations for Exynos4210+ and Exynos5440. Finally remove no longer needed reg->tmu_[ctrl,inten], reg->inten_rise[0,1,2,3]_shift and reg->inten_fall0_shift abstractions. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 81 ++++++++++++++++------- drivers/thermal/samsung/exynos_tmu.h | 25 +------ drivers/thermal/samsung/exynos_tmu_data.c | 41 ------------ 3 files changed, 60 insertions(+), 87 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index f65e6d807afe..938e8e63cff9 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -53,6 +53,7 @@ * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. * @tmu_initialize: SoC specific TMU initialization method + * @tmu_control: SoC specific TMU control method */ struct exynos_tmu_data { int id; @@ -68,6 +69,7 @@ struct exynos_tmu_data { struct regulator *regulator; struct thermal_sensor_conf *reg_conf; int (*tmu_initialize)(struct platform_device *pdev); + void (*tmu_control)(struct platform_device *pdev, bool on); }; /* @@ -221,32 +223,10 @@ static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) static void exynos_tmu_control(struct platform_device *pdev, bool on) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int con, interrupt_en; mutex_lock(&data->lock); clk_enable(data->clk); - - con = get_con_reg(data, readl(data->base + reg->tmu_ctrl)); - - if (on) { - con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = - pdata->trigger_enable[3] << reg->inten_rise3_shift | - pdata->trigger_enable[2] << reg->inten_rise2_shift | - pdata->trigger_enable[1] << reg->inten_rise1_shift | - pdata->trigger_enable[0] << reg->inten_rise0_shift; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) - interrupt_en |= - interrupt_en << reg->inten_fall0_shift; - } else { - con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); - interrupt_en = 0; /* Disable all interrupts */ - } - writel(interrupt_en, data->base + reg->tmu_inten); - writel(con, data->base + reg->tmu_ctrl); - + data->tmu_control(pdev, on); clk_disable(data->clk); mutex_unlock(&data->lock); } @@ -388,6 +368,58 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) return ret; } +static void exynos4210_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int con, interrupt_en; + + con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL)); + + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; + if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + interrupt_en |= + interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN); + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); +} + +static void exynos5440_tmu_control(struct platform_device *pdev, bool on) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + unsigned int con, interrupt_en; + + con = get_con_reg(data, readl(data->base + EXYNOS5440_TMU_S0_7_CTRL)); + + if (on) { + con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = + pdata->trigger_enable[3] << EXYNOS5440_TMU_INTEN_RISE3_SHIFT | + pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT | + pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT | + pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT; + if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + interrupt_en |= + interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; + } else { + con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + interrupt_en = 0; /* Disable all interrupts */ + } + writel(interrupt_en, data->base + EXYNOS5440_TMU_S0_7_IRQEN); + writel(con, data->base + EXYNOS5440_TMU_S0_7_CTRL); +} + static int exynos_tmu_read(struct exynos_tmu_data *data) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -685,6 +717,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) switch (data->soc) { case SOC_ARCH_EXYNOS4210: data->tmu_initialize = exynos4210_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -693,9 +726,11 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS5420: case SOC_ARCH_EXYNOS5420_TRIMINFO: data->tmu_initialize = exynos4412_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; + data->tmu_control = exynos5440_tmu_control; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index f186f4ff44c4..7496b54f2a86 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -68,38 +68,17 @@ enum soc_type { #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) /** - * struct exynos_tmu_register - register descriptors to access registers and - * bitfields. The register validity, offsets and bitfield values may vary - * slightly across different exynos SOC's. - * @tmu_ctrl: TMU main controller register. + * struct exynos_tmu_register - register descriptors to access registers. + * The register validity may vary slightly across different exynos SOC's. * @tmu_cur_temp: register containing the current temperature of the TMU. - * @tmu_inten: register containing the different threshold interrupt - enable bits. - * @inten_rise0_shift: shift bits of rising 0 interrupt bits. - * @inten_rise1_shift: shift bits of rising 1 interrupt bits. - * @inten_rise2_shift: shift bits of rising 2 interrupt bits. - * @inten_rise3_shift: shift bits of rising 3 interrupt bits. - * @inten_fall0_shift: shift bits of falling 0 interrupt bits. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { - u32 tmu_ctrl; - u32 tmu_cur_temp; - - u32 tmu_inten; - u32 inten_rise0_shift; - u32 inten_rise1_shift; - u32 inten_rise2_shift; - u32 inten_rise3_shift; - u32 inten_fall0_shift; - u32 tmu_intstat; - u32 tmu_intclear; - u32 emul_con; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index db3b3bc53f76..2bfd4690e0d7 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,13 +26,7 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, }; @@ -80,13 +74,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -147,14 +135,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -227,14 +208,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS5260_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, @@ -297,15 +271,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_ctrl = EXYNOS_TMU_REG_CONTROL, .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, - .tmu_inten = EXYNOS_TMU_REG_INTEN, - .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT, - /* INTEN_RISE3 Not availble in exynos5420 */ - .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -374,14 +340,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL, .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, - .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN, - .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT, - .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT, - .inten_rise2_shift = EXYNOS5440_TMU_INTEN_RISE2_SHIFT, - .inten_rise3_shift = EXYNOS5440_TMU_INTEN_RISE3_SHIFT, - .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, -- GitLab From b79985ca74b25926cb2d88b60805092c5456bf43 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:16 +0100 Subject: [PATCH 5536/9457] thermal: exynos: add ->tmu_read method Add ->tmu_read method to struct exynos_tmu_data and use it in exynos_tmu_control(). Then add ->tmu_read implementations for Exynos4210, Exynos4412+ and Exynos5440. Finally remove no longer needed reg->tmu_cur_temp abstractions. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 45 ++++++++++++++--------- drivers/thermal/samsung/exynos_tmu.h | 2 - drivers/thermal/samsung/exynos_tmu_data.c | 6 --- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 938e8e63cff9..b209593d78dc 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -54,6 +54,7 @@ * @reg_conf: pointer to structure to register with core thermal. * @tmu_initialize: SoC specific TMU initialization method * @tmu_control: SoC specific TMU control method + * @tmu_read: SoC specific TMU temperature read method */ struct exynos_tmu_data { int id; @@ -70,6 +71,7 @@ struct exynos_tmu_data { struct thermal_sensor_conf *reg_conf; int (*tmu_initialize)(struct platform_device *pdev); void (*tmu_control)(struct platform_device *pdev, bool on); + int (*tmu_read)(struct exynos_tmu_data *data); }; /* @@ -422,29 +424,17 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on) static int exynos_tmu_read(struct exynos_tmu_data *data) { - struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - u8 temp_code; - int temp; + int ret; mutex_lock(&data->lock); clk_enable(data->clk); - - temp_code = readb(data->base + reg->tmu_cur_temp); - - if (data->soc == SOC_ARCH_EXYNOS4210) - /* temp_code should range between 75 and 175 */ - if (temp_code < 75 || temp_code > 175) { - temp = -ENODATA; - goto out; - } - - temp = code_to_temp(data, temp_code); -out: + ret = data->tmu_read(data); + if (ret >= 0) + ret = code_to_temp(data, ret); clk_disable(data->clk); mutex_unlock(&data->lock); - return temp; + return ret; } #ifdef CONFIG_THERMAL_EMULATION @@ -494,6 +484,24 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { return -EINVAL; } #endif/*CONFIG_THERMAL_EMULATION*/ +static int exynos4210_tmu_read(struct exynos_tmu_data *data) +{ + int ret = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); + + /* "temp_code" should range between 75 and 175 */ + return (ret < 75 || ret > 175) ? -ENODATA : ret; +} + +static int exynos4412_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP); +} + +static int exynos5440_tmu_read(struct exynos_tmu_data *data) +{ + return readb(data->base + EXYNOS5440_TMU_S0_7_TEMP); +} + static void exynos_tmu_work(struct work_struct *work) { struct exynos_tmu_data *data = container_of(work, @@ -718,6 +726,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS4210: data->tmu_initialize = exynos4210_tmu_initialize; data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4210_tmu_read; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -727,10 +736,12 @@ static int exynos_tmu_probe(struct platform_device *pdev) case SOC_ARCH_EXYNOS5420_TRIMINFO: data->tmu_initialize = exynos4412_tmu_initialize; data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4412_tmu_read; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; + data->tmu_read = exynos5440_tmu_read; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 7496b54f2a86..9460e6e55fe8 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -70,13 +70,11 @@ enum soc_type { /** * struct exynos_tmu_register - register descriptors to access registers. * The register validity may vary slightly across different exynos SOC's. - * @tmu_cur_temp: register containing the current temperature of the TMU. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { - u32 tmu_cur_temp; u32 tmu_intstat; u32 tmu_intclear; u32 emul_con; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 2bfd4690e0d7..769b89d7d641 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -26,7 +26,6 @@ #if defined(CONFIG_CPU_EXYNOS4210) static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, }; @@ -74,7 +73,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS3250) static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -135,7 +133,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -208,7 +205,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5260) static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, .emul_con = EXYNOS5260_EMUL_CON, @@ -271,7 +267,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5420) static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP, .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, .emul_con = EXYNOS_EMUL_CON, @@ -340,7 +335,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #if defined(CONFIG_SOC_EXYNOS5440) static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP, .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, -- GitLab From 154013ea5fc9de969f6808b4bbb7e986e396f1f1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:17 +0100 Subject: [PATCH 5537/9457] thermal: exynos: add get_emul_con_reg() helper Factor out code for preparing EMUL_CON register value from exynos_tmu_set_emulation() into get_emul_con_reg(). This is a preparation for introducing per-SoC type tmu_set_emulation method. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 38 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index b209593d78dc..1b622ce0ee79 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -438,6 +438,28 @@ static int exynos_tmu_read(struct exynos_tmu_data *data) } #ifdef CONFIG_THERMAL_EMULATION +static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, + unsigned long temp) +{ + struct exynos_tmu_platform_data *pdata = data->pdata; + + if (temp) { + temp /= MCELSIUS; + + if (TMU_SUPPORTS(pdata, EMUL_TIME)) { + val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); + val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); + } + val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); + val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | + EXYNOS_EMUL_ENABLE; + } else { + val &= ~EXYNOS_EMUL_ENABLE; + } + + return val; +} + static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; @@ -456,21 +478,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) clk_enable(data->clk); val = readl(data->base + reg->emul_con); - - if (temp) { - temp /= MCELSIUS; - - if (TMU_SUPPORTS(pdata, EMUL_TIME)) { - val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); - val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); - } - val &= ~(EXYNOS_EMUL_DATA_MASK << EXYNOS_EMUL_DATA_SHIFT); - val |= (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) | - EXYNOS_EMUL_ENABLE; - } else { - val &= ~EXYNOS_EMUL_ENABLE; - } - + val = get_emul_con_reg(data, val, temp); writel(val, data->base + reg->emul_con); clk_disable(data->clk); -- GitLab From 285d994a51e45ca59a9cde34a3a0ea316e263617 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:18 +0100 Subject: [PATCH 5538/9457] thermal: exynos: add ->tmu_set_emulation method Add ->tmu_set_emulation method to struct exynos_tmu_data and use it in exynos_tmu_set_emulation(). Then add ->tmu_set_emulation implementations for Exynos4412+ and Exynos5440. Finally remove no longer needed reg->emul_con abstraction. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 41 +++++++++++++++++++---- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 5 --- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1b622ce0ee79..01aa5481c13e 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -55,6 +55,7 @@ * @tmu_initialize: SoC specific TMU initialization method * @tmu_control: SoC specific TMU control method * @tmu_read: SoC specific TMU temperature read method + * @tmu_set_emulation: SoC specific TMU emulation setting method */ struct exynos_tmu_data { int id; @@ -72,6 +73,8 @@ struct exynos_tmu_data { int (*tmu_initialize)(struct platform_device *pdev); void (*tmu_control)(struct platform_device *pdev, bool on); int (*tmu_read)(struct exynos_tmu_data *data); + void (*tmu_set_emulation)(struct exynos_tmu_data *data, + unsigned long temp); }; /* @@ -460,12 +463,36 @@ static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, return val; } +static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + u32 emul_con; + + if (data->soc == SOC_ARCH_EXYNOS5260) + emul_con = EXYNOS5260_EMUL_CON; + else + emul_con = EXYNOS_EMUL_CON; + + val = readl(data->base + emul_con); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + emul_con); +} + +static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, + unsigned long temp) +{ + unsigned int val; + + val = readl(data->base + EXYNOS5440_TMU_S0_7_DEBUG); + val = get_emul_con_reg(data, val, temp); + writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG); +} + static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; struct exynos_tmu_platform_data *pdata = data->pdata; - const struct exynos_tmu_registers *reg = pdata->registers; - unsigned int val; int ret = -EINVAL; if (!TMU_SUPPORTS(pdata, EMULATION)) @@ -476,11 +503,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) mutex_lock(&data->lock); clk_enable(data->clk); - - val = readl(data->base + reg->emul_con); - val = get_emul_con_reg(data, val, temp); - writel(val, data->base + reg->emul_con); - + data->tmu_set_emulation(data, temp); clk_disable(data->clk); mutex_unlock(&data->lock); return 0; @@ -488,6 +511,8 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) return ret; } #else +#define exynos4412_tmu_set_emulation NULL +#define exynos5440_tmu_set_emulation NULL static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { return -EINVAL; } #endif/*CONFIG_THERMAL_EMULATION*/ @@ -745,11 +770,13 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_initialize = exynos4412_tmu_initialize; data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; data->tmu_read = exynos5440_tmu_read; + data->tmu_set_emulation = exynos5440_tmu_set_emulation; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 9460e6e55fe8..785eccf22c19 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -72,12 +72,10 @@ enum soc_type { * The register validity may vary slightly across different exynos SOC's. * @tmu_intstat: Register containing the interrupt status values. * @tmu_intclear: Register for clearing the raised interrupt status. - * @emul_con: TMU emulation controller register. */ struct exynos_tmu_registers { u32 tmu_intstat; u32 tmu_intclear; - u32 emul_con; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 769b89d7d641..d0bb4b35d0b9 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -75,7 +75,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { static const struct exynos_tmu_registers exynos3250_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define EXYNOS3250_TMU_DATA \ @@ -135,7 +134,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { static const struct exynos_tmu_registers exynos4412_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define EXYNOS4412_TMU_DATA \ @@ -207,7 +205,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { static const struct exynos_tmu_registers exynos5260_tmu_registers = { .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, - .emul_con = EXYNOS5260_EMUL_CON, }; #define __EXYNOS5260_TMU_DATA \ @@ -269,7 +266,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { static const struct exynos_tmu_registers exynos5420_tmu_registers = { .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, - .emul_con = EXYNOS_EMUL_CON, }; #define __EXYNOS5420_TMU_DATA \ @@ -337,7 +333,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { static const struct exynos_tmu_registers exynos5440_tmu_registers = { .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, - .emul_con = EXYNOS5440_TMU_S0_7_DEBUG, }; #define EXYNOS5440_TMU_DATA \ -- GitLab From a7331f72d3eb2bf6a15405459f7c514607402ca6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:19 +0100 Subject: [PATCH 5539/9457] thermal: exynos: add ->tmu_clear_irqs method Add ->tmu_clear_irqs method to struct exynos_tmu_data and use it instead exynos_tmu_clear_irqs(). Then add ->tmu_clear_irqs implementations for Exynos4210+ and Exynos5440. Finally remove no longer needed reg->tmu_int[stat,clear] abstractions and struct exynos_tmu_registers instances. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 64 +++++++++++++++-------- drivers/thermal/samsung/exynos_tmu.h | 14 ----- drivers/thermal/samsung/exynos_tmu_data.c | 36 ------------- 3 files changed, 43 insertions(+), 71 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 01aa5481c13e..1b3c2f4a846b 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -56,6 +56,7 @@ * @tmu_control: SoC specific TMU control method * @tmu_read: SoC specific TMU temperature read method * @tmu_set_emulation: SoC specific TMU emulation setting method + * @tmu_clear_irqs: SoC specific TMU interrupts clearing method */ struct exynos_tmu_data { int id; @@ -75,6 +76,7 @@ struct exynos_tmu_data { int (*tmu_read)(struct exynos_tmu_data *data); void (*tmu_set_emulation)(struct exynos_tmu_data *data, unsigned long temp); + void (*tmu_clear_irqs)(struct exynos_tmu_data *data); }; /* @@ -131,23 +133,6 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code) return temp; } -static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data) -{ - const struct exynos_tmu_registers *reg = data->pdata->registers; - unsigned int val_irq; - - val_irq = readl(data->base + reg->tmu_intstat); - /* - * Clear the interrupts. Please note that the documentation for - * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly - * states that INTCLEAR register has a different placing of bits - * responsible for FALL IRQs than INTSTAT register. Exynos5420 - * and Exynos5440 documentation is correct (Exynos4210 doesn't - * support FALL IRQs at all). - */ - writel(val_irq, data->base + reg->tmu_intclear); -} - static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info) { struct exynos_tmu_platform_data *pdata = data->pdata; @@ -259,7 +244,7 @@ static int exynos4210_tmu_initialize(struct platform_device *pdev) writeb(pdata->trigger_levels[i], data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); out: return ret; } @@ -304,7 +289,7 @@ static int exynos4412_tmu_initialize(struct platform_device *pdev) writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); writel(get_th_reg(data, 0, true), data->base + EXYNOS_THD_TEMP_FALL); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); /* if last threshold limit is also present */ i = pdata->max_trigger_level - 1; @@ -353,7 +338,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) writel(rising_threshold, data->base + EXYNOS5440_TMU_S0_7_TH0); writel(0, data->base + EXYNOS5440_TMU_S0_7_TH1); - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); /* if last threshold limit is also present */ i = pdata->max_trigger_level - 1; @@ -557,7 +542,7 @@ static void exynos_tmu_work(struct work_struct *work) clk_enable(data->clk); /* TODO: take action based on particular interrupt */ - exynos_tmu_clear_irqs(data); + data->tmu_clear_irqs(data); clk_disable(data->clk); mutex_unlock(&data->lock); @@ -565,6 +550,40 @@ static void exynos_tmu_work(struct work_struct *work) enable_irq(data->irq); } +static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + u32 tmu_intstat, tmu_intclear; + + if (data->soc == SOC_ARCH_EXYNOS5260) { + tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR; + } else { + tmu_intstat = EXYNOS_TMU_REG_INTSTAT; + tmu_intclear = EXYNOS_TMU_REG_INTCLEAR; + } + + val_irq = readl(data->base + tmu_intstat); + /* + * Clear the interrupts. Please note that the documentation for + * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly + * states that INTCLEAR register has a different placing of bits + * responsible for FALL IRQs than INTSTAT register. Exynos5420 + * and Exynos5440 documentation is correct (Exynos4210 doesn't + * support FALL IRQs at all). + */ + writel(val_irq, data->base + tmu_intclear); +} + +static void exynos5440_tmu_clear_irqs(struct exynos_tmu_data *data) +{ + unsigned int val_irq; + + val_irq = readl(data->base + EXYNOS5440_TMU_S0_7_IRQ); + /* clear the interrupts */ + writel(val_irq, data->base + EXYNOS5440_TMU_S0_7_IRQ); +} + static irqreturn_t exynos_tmu_irq(int irq, void *id) { struct exynos_tmu_data *data = id; @@ -760,6 +779,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_initialize = exynos4210_tmu_initialize; data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4210_tmu_read; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; break; case SOC_ARCH_EXYNOS3250: case SOC_ARCH_EXYNOS4412: @@ -771,12 +791,14 @@ static int exynos_tmu_probe(struct platform_device *pdev) data->tmu_control = exynos4210_tmu_control; data->tmu_read = exynos4412_tmu_read; data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; data->tmu_read = exynos5440_tmu_read; data->tmu_set_emulation = exynos5440_tmu_set_emulation; + data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; break; default: ret = -EINVAL; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 785eccf22c19..c4c0aa58f3a1 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -67,17 +67,6 @@ enum soc_type { #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) -/** - * struct exynos_tmu_register - register descriptors to access registers. - * The register validity may vary slightly across different exynos SOC's. - * @tmu_intstat: Register containing the interrupt status values. - * @tmu_intclear: Register for clearing the raised interrupt status. - */ -struct exynos_tmu_registers { - u32 tmu_intstat; - u32 tmu_intclear; -}; - /** * struct exynos_tmu_platform_data * @threshold: basic temperature for generating interrupt @@ -127,8 +116,6 @@ struct exynos_tmu_registers { * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may * applicable to only some of the trigger levels. - * @registers: Pointer to structure containing all the TMU controller registers - * and bitfields shifts and masks. * @features: a bitfield value indicating the features supported in SOC like * emulation, multi instance etc * @@ -158,7 +145,6 @@ struct exynos_tmu_platform_data { enum soc_type type; struct freq_clip_table freq_tab[4]; unsigned int freq_tab_count; - const struct exynos_tmu_registers *registers; unsigned int features; }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d0bb4b35d0b9..d35ec1545a2d 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -25,11 +25,6 @@ #include "exynos_tmu_data.h" #if defined(CONFIG_CPU_EXYNOS4210) -static const struct exynos_tmu_registers exynos4210_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { { @@ -64,7 +59,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { }, .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, - .registers = &exynos4210_tmu_registers, }, }, .tmu_count = 1, @@ -72,11 +66,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS3250) -static const struct exynos_tmu_registers exynos3250_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define EXYNOS3250_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -112,7 +101,6 @@ static const struct exynos_tmu_registers exynos3250_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos3250_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) #endif @@ -131,11 +119,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) -static const struct exynos_tmu_registers exynos4412_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define EXYNOS4412_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -171,7 +154,6 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos4412_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_EMUL_TIME) #endif @@ -202,11 +184,6 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5260) -static const struct exynos_tmu_registers exynos5260_tmu_registers = { - .tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR, -}; - #define __EXYNOS5260_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -242,7 +219,6 @@ static const struct exynos_tmu_registers exynos5260_tmu_registers = { .temp_level = 103, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos5260_tmu_registers, \ #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ @@ -263,11 +239,6 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5420) -static const struct exynos_tmu_registers exynos5420_tmu_registers = { - .tmu_intstat = EXYNOS_TMU_REG_INTSTAT, - .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR, -}; - #define __EXYNOS5420_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -303,7 +274,6 @@ static const struct exynos_tmu_registers exynos5420_tmu_registers = { .temp_level = 103, \ }, \ .freq_tab_count = 2, \ - .registers = &exynos5420_tmu_registers, \ #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ @@ -330,11 +300,6 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { #endif #if defined(CONFIG_SOC_EXYNOS5440) -static const struct exynos_tmu_registers exynos5440_tmu_registers = { - .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ, - .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ, -}; - #define EXYNOS5440_TMU_DATA \ .trigger_levels[0] = 100, \ .trigger_levels[4] = 105, \ @@ -354,7 +319,6 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .registers = &exynos5440_tmu_registers, \ .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), -- GitLab From e0761533a1d41e7486bddac75ee878e9814ec0e3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:20 +0100 Subject: [PATCH 5540/9457] thermal: exynos: remove TMU_SUPPORT_FALLING_TRIP flag Replace TMU_SUPPORT_FALLING_TRIP flag check in exynos[4210,5440]_tmu_control() by an explicit check for a SoC type (all SoC types except Exynos4210 have TMU_SUPPORT_FALLING_TRIP flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 6 ++---- drivers/thermal/samsung/exynos_tmu.h | 7 ++----- drivers/thermal/samsung/exynos_tmu_data.c | 20 ++++++++------------ 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1b3c2f4a846b..6795ddc07b4c 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -373,7 +373,7 @@ static void exynos4210_tmu_control(struct platform_device *pdev, bool on) pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT | pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT | pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) + if (data->soc != SOC_ARCH_EXYNOS4210) interrupt_en |= interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; } else { @@ -399,9 +399,7 @@ static void exynos5440_tmu_control(struct platform_device *pdev, bool on) pdata->trigger_enable[2] << EXYNOS5440_TMU_INTEN_RISE2_SHIFT | pdata->trigger_enable[1] << EXYNOS5440_TMU_INTEN_RISE1_SHIFT | pdata->trigger_enable[0] << EXYNOS5440_TMU_INTEN_RISE0_SHIFT; - if (TMU_SUPPORTS(pdata, FALLING_TRIP)) - interrupt_en |= - interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; + interrupt_en |= interrupt_en << EXYNOS5440_TMU_INTEN_FALL0_SHIFT; } else { con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); interrupt_en = 0; /* Disable all interrupts */ diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index c4c0aa58f3a1..ed83d3d10ad8 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -51,8 +51,6 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can - * be registered for falling trips also. * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU @@ -61,9 +59,8 @@ enum soc_type { */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_FALLING_TRIP BIT(2) -#define TMU_SUPPORT_EMUL_TIME BIT(3) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(4) +#define TMU_SUPPORT_EMUL_TIME BIT(2) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(3) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d35ec1545a2d..39b96514b540 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -101,8 +101,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -154,8 +153,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -223,8 +221,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -278,14 +275,13 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_EMUL_TIME | TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME | \ + TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -319,8 +315,8 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \ - TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_MULTI_INST | \ + TMU_SUPPORT_ADDRESS_MULTIPLE), struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- GitLab From d564b55a81e720430f50e301ff330b1c9ec3944c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:21 +0100 Subject: [PATCH 5541/9457] thermal: exynos: remove TMU_SUPPORT_EMUL_TIME flag Replace TMU_SUPPORT_EMUL_TIME flag check in get_emul_con_reg() by an explicit check for a SoC type (all SoC types except Exynos4210 and Exynos5440 have TMU_SUPPORT_EMUL_TIME flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 4 +--- drivers/thermal/samsung/exynos_tmu.h | 5 +---- drivers/thermal/samsung/exynos_tmu_data.c | 11 +++++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6795ddc07b4c..209221f1fab2 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -427,12 +427,10 @@ static int exynos_tmu_read(struct exynos_tmu_data *data) static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, unsigned long temp) { - struct exynos_tmu_platform_data *pdata = data->pdata; - if (temp) { temp /= MCELSIUS; - if (TMU_SUPPORTS(pdata, EMUL_TIME)) { + if (data->soc != SOC_ARCH_EXYNOS5440) { val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT); val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT); } diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index ed83d3d10ad8..d90852a0b403 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -51,16 +51,13 @@ enum soc_type { * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation - * sample time. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ #define TMU_SUPPORT_EMULATION BIT(0) #define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_EMUL_TIME BIT(2) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(3) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(2) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 39b96514b540..82f1cba2dc7f 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -101,7 +101,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -153,7 +153,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -221,7 +221,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5260, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -275,13 +275,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME) + .features = TMU_SUPPORT_EMULATION #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_EMUL_TIME | \ - TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_ADDRESS_MULTIPLE) struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { -- GitLab From ef3f80fc7f79c32a1b015afcbffce2a2630011a4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:22 +0100 Subject: [PATCH 5542/9457] thermal: exynos: remove TMU_SUPPORT_EMULATION flag Replace TMU_SUPPORT_EMULATION flag check in exynos_tmu_set_emulation() by an explicit check for a SoC type (all SoC types except Exynos4210 have TMU_SUPPORT_EMULATION flag set in their struct exynos_tmu_init_data instances). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- drivers/thermal/samsung/exynos_tmu.h | 7 ++----- drivers/thermal/samsung/exynos_tmu_data.c | 17 ++++++----------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 209221f1fab2..51d8cc70b6d6 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -476,7 +476,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) struct exynos_tmu_platform_data *pdata = data->pdata; int ret = -EINVAL; - if (!TMU_SUPPORTS(pdata, EMULATION)) + if (data->soc == SOC_ARCH_EXYNOS4210) goto out; if (temp && temp < MCELSIUS) diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index d90852a0b403..5ad3f3fbc6f0 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -47,17 +47,14 @@ enum soc_type { /** * EXYNOS TMU supported features. - * TMU_SUPPORT_EMULATION - This features is used to set user defined - * temperature to the TMU controller. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ -#define TMU_SUPPORT_EMULATION BIT(0) -#define TMU_SUPPORT_MULTI_INST BIT(1) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(2) +#define TMU_SUPPORT_MULTI_INST BIT(0) +#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(1) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 82f1cba2dc7f..4dd8d1c1b822 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -100,8 +100,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .features = TMU_SUPPORT_EMULATION + .freq_tab_count = 2 #endif #if defined(CONFIG_SOC_EXYNOS3250) @@ -152,8 +151,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .freq_clip_max = 400 * 1000, \ .temp_level = 95, \ }, \ - .freq_tab_count = 2, \ - .features = TMU_SUPPORT_EMULATION + .freq_tab_count = 2 #endif #if defined(CONFIG_SOC_EXYNOS4412) @@ -220,8 +218,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5260, \ - .features = TMU_SUPPORT_EMULATION + .type = SOC_ARCH_EXYNOS5260 struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_data = { @@ -274,13 +271,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5420, \ - .features = TMU_SUPPORT_EMULATION + .type = SOC_ARCH_EXYNOS5420 #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_ADDRESS_MULTIPLE) + .features = TMU_SUPPORT_ADDRESS_MULTIPLE struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -314,8 +310,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_MULTI_INST | \ - TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = (TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- GitLab From 56adb9efeb8115d2a3a807d84a0d037398588911 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:23 +0100 Subject: [PATCH 5543/9457] thermal: exynos: remove TMU_SUPPORT_ADDRESS_MULTIPLE flag Replace TMU_SUPPORT_ADDRESS_MULTIPLE flag check in exynos_map_dt_data() by an explicit check for a SoC type (only Exynos5420 with TRIMINFO quirk and Exynos5440 have TMU_SUPPORT_ADDRESS_MULTIPLE flag set in their struct exynos_tmu_init_data instances). Please note that this requires moving SoC type assignment and verification from exynos_tmu_probe() to exynos_map_dt_data() so it happens earlier (which is a good thing in itself). There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 72 +++++++++++------------ drivers/thermal/samsung/exynos_tmu.h | 3 - drivers/thermal/samsung/exynos_tmu_data.c | 5 +- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 51d8cc70b6d6..65eeeccff78b 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -473,7 +473,6 @@ static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) { struct exynos_tmu_data *data = drv_data; - struct exynos_tmu_platform_data *pdata = data->pdata; int ret = -EINVAL; if (data->soc == SOC_ARCH_EXYNOS4210) @@ -696,12 +695,47 @@ static int exynos_map_dt_data(struct platform_device *pdev) dev_err(&pdev->dev, "No platform init data supplied.\n"); return -ENODEV; } + data->pdata = pdata; + data->soc = pdata->type; + + switch (data->soc) { + case SOC_ARCH_EXYNOS4210: + data->tmu_initialize = exynos4210_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4210_tmu_read; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS3250: + case SOC_ARCH_EXYNOS4412: + case SOC_ARCH_EXYNOS5250: + case SOC_ARCH_EXYNOS5260: + case SOC_ARCH_EXYNOS5420: + case SOC_ARCH_EXYNOS5420_TRIMINFO: + data->tmu_initialize = exynos4412_tmu_initialize; + data->tmu_control = exynos4210_tmu_control; + data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; + case SOC_ARCH_EXYNOS5440: + data->tmu_initialize = exynos5440_tmu_initialize; + data->tmu_control = exynos5440_tmu_control; + data->tmu_read = exynos5440_tmu_read; + data->tmu_set_emulation = exynos5440_tmu_set_emulation; + data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; + break; + default: + dev_err(&pdev->dev, "Platform not supported\n"); + return -EINVAL; + } + /* * Check if the TMU shares some registers and then try to map the * memory of common registers. */ - if (!TMU_SUPPORTS(pdata, ADDRESS_MULTIPLE)) + if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && + data->soc != SOC_ARCH_EXYNOS5440) return 0; if (of_address_to_resource(pdev->dev.of_node, 1, &res)) { @@ -768,40 +802,6 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - data->soc = pdata->type; - - switch (data->soc) { - case SOC_ARCH_EXYNOS4210: - data->tmu_initialize = exynos4210_tmu_initialize; - data->tmu_control = exynos4210_tmu_control; - data->tmu_read = exynos4210_tmu_read; - data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; - break; - case SOC_ARCH_EXYNOS3250: - case SOC_ARCH_EXYNOS4412: - case SOC_ARCH_EXYNOS5250: - case SOC_ARCH_EXYNOS5260: - case SOC_ARCH_EXYNOS5420: - case SOC_ARCH_EXYNOS5420_TRIMINFO: - data->tmu_initialize = exynos4412_tmu_initialize; - data->tmu_control = exynos4210_tmu_control; - data->tmu_read = exynos4412_tmu_read; - data->tmu_set_emulation = exynos4412_tmu_set_emulation; - data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; - break; - case SOC_ARCH_EXYNOS5440: - data->tmu_initialize = exynos5440_tmu_initialize; - data->tmu_control = exynos5440_tmu_control; - data->tmu_read = exynos5440_tmu_read; - data->tmu_set_emulation = exynos5440_tmu_set_emulation; - data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; - break; - default: - ret = -EINVAL; - dev_err(&pdev->dev, "Platform not supported\n"); - goto err_clk; - } - ret = exynos_tmu_initialize(pdev); if (ret) { dev_err(&pdev->dev, "Failed to initialize TMU\n"); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 5ad3f3fbc6f0..54f018d6c382 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -49,12 +49,9 @@ enum soc_type { * EXYNOS TMU supported features. * TMU_SUPPORT_MULTI_INST - This features denotes that the soc * has many instances of TMU. - * TMU_SUPPORT_ADDRESS_MULTIPLE - This feature tells that the different TMU - * sensors shares some common registers. * TMU_SUPPORT - macro to compare the above features with the supplied. */ #define TMU_SUPPORT_MULTI_INST BIT(0) -#define TMU_SUPPORT_ADDRESS_MULTIPLE BIT(1) #define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 4dd8d1c1b822..13ac00b88e6b 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -275,8 +275,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { #define EXYNOS5420_TMU_DATA_SHARED \ __EXYNOS5420_TMU_DATA \ - .type = SOC_ARCH_EXYNOS5420_TRIMINFO, \ - .features = TMU_SUPPORT_ADDRESS_MULTIPLE + .type = SOC_ARCH_EXYNOS5420_TRIMINFO struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .tmu_data = { @@ -310,7 +309,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .second_point_trim = 70, \ .default_temp_offset = 25, \ .type = SOC_ARCH_EXYNOS5440, \ - .features = (TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_ADDRESS_MULTIPLE), + .features = TMU_SUPPORT_MULTI_INST, struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- GitLab From 17be30cb7f4b4ba5f50946e2d638c1b9162ecfc7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:24 +0100 Subject: [PATCH 5544/9457] thermal: exynos: remove TMU_SUPPORT_MULTI_INST flag Remove unused TMU_SUPPORT_MULTI_INST flag, no longer needed TMU_SUPPORTS() macro and features field from struct exynos_tmu_platform_data. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.h | 13 ------------- drivers/thermal/samsung/exynos_tmu_data.c | 3 +-- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 54f018d6c382..2eb4cb96f28f 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -45,16 +45,6 @@ enum soc_type { SOC_ARCH_EXYNOS5440, }; -/** - * EXYNOS TMU supported features. - * TMU_SUPPORT_MULTI_INST - This features denotes that the soc - * has many instances of TMU. - * TMU_SUPPORT - macro to compare the above features with the supplied. - */ -#define TMU_SUPPORT_MULTI_INST BIT(0) - -#define TMU_SUPPORTS(a, b) (a->features & TMU_SUPPORT_ ## b) - /** * struct exynos_tmu_platform_data * @threshold: basic temperature for generating interrupt @@ -104,8 +94,6 @@ enum soc_type { * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may * applicable to only some of the trigger levels. - * @features: a bitfield value indicating the features supported in SOC like - * emulation, multi instance etc * * This structure is required for configuration of exynos_tmu driver. */ @@ -133,7 +121,6 @@ struct exynos_tmu_platform_data { enum soc_type type; struct freq_clip_table freq_tab[4]; unsigned int freq_tab_count; - unsigned int features; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 13ac00b88e6b..d90b050a7ceb 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -308,8 +308,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { .first_point_trim = 25, \ .second_point_trim = 70, \ .default_temp_offset = 25, \ - .type = SOC_ARCH_EXYNOS5440, \ - .features = TMU_SUPPORT_MULTI_INST, + .type = SOC_ARCH_EXYNOS5440 struct exynos_tmu_init_data const exynos5440_default_tmu_data = { .tmu_data = { -- GitLab From 7575983c577c724425d11361acb1fc45834633f3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:25 +0100 Subject: [PATCH 5545/9457] thermal: exynos: remove test_mux pdata field Replace pdata->test_mux check in get_con_reg() by explicitly checking for SoC type. Also since the used pdata->test_mux value is always identical use it directly and remove pdata->test_mux completely. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 5 +++-- drivers/thermal/samsung/exynos_tmu.h | 2 -- drivers/thermal/samsung/exynos_tmu_data.c | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 65eeeccff78b..2fcb4cdf8532 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -193,8 +193,9 @@ static u32 get_con_reg(struct exynos_tmu_data *data, u32 con) { struct exynos_tmu_platform_data *pdata = data->pdata; - if (pdata->test_mux) - con |= (pdata->test_mux << EXYNOS4412_MUX_ADDR_SHIFT); + if (data->soc == SOC_ARCH_EXYNOS4412 || + data->soc == SOC_ARCH_EXYNOS3250) + con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT); con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT); con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT; diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 2eb4cb96f28f..8de0f8254947 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -89,7 +89,6 @@ enum soc_type { * @first_point_trim: temp value of the first point trimming * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming - * @test_mux; information if SoC supports test MUX * @cal_type: calibration type for temperature * @freq_clip_table: Table representing frequency reduction percentage. * @freq_tab_count: Count of the above table as frequency reduction may @@ -115,7 +114,6 @@ struct exynos_tmu_platform_data { u8 first_point_trim; u8 second_point_trim; u8 default_temp_offset; - u8 test_mux; enum calibration_type cal_type; enum soc_type type; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index d90b050a7ceb..708c3e146e89 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -109,7 +109,6 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { { EXYNOS3250_TMU_DATA, .type = SOC_ARCH_EXYNOS3250, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, @@ -160,7 +159,6 @@ struct exynos_tmu_init_data const exynos4412_default_tmu_data = { { EXYNOS4412_TMU_DATA, .type = SOC_ARCH_EXYNOS4412, - .test_mux = EXYNOS4412_MUX_ADDR_VALUE, }, }, .tmu_count = 1, -- GitLab From 4c4680a16716ef77826eb11fe8d7c1e70e4eb78d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:26 +0100 Subject: [PATCH 5546/9457] thermal: exynos: remove SoC type ifdefs Maximum theoretical size saving (i.e. with only Exynos5410 SoC support enabled in kernel config so all SoC dependend Exynos thermal driver code was dropped) is 4096 bytes so there is no much sense in keeping these ifdefs (especially given that they are useless once the driver gets updated to use device tree). While at it remove needless 'void *' casts. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 16 ++++----- drivers/thermal/samsung/exynos_tmu_data.c | 18 ---------- drivers/thermal/samsung/exynos_tmu_data.h | 41 ----------------------- 3 files changed, 8 insertions(+), 67 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 2fcb4cdf8532..6cc6b6e7f4c4 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -593,35 +593,35 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id) static const struct of_device_id exynos_tmu_match[] = { { .compatible = "samsung,exynos3250-tmu", - .data = (void *)EXYNOS3250_TMU_DRV_DATA, + .data = &exynos3250_default_tmu_data, }, { .compatible = "samsung,exynos4210-tmu", - .data = (void *)EXYNOS4210_TMU_DRV_DATA, + .data = &exynos4210_default_tmu_data, }, { .compatible = "samsung,exynos4412-tmu", - .data = (void *)EXYNOS4412_TMU_DRV_DATA, + .data = &exynos4412_default_tmu_data, }, { .compatible = "samsung,exynos5250-tmu", - .data = (void *)EXYNOS5250_TMU_DRV_DATA, + .data = &exynos5250_default_tmu_data, }, { .compatible = "samsung,exynos5260-tmu", - .data = (void *)EXYNOS5260_TMU_DRV_DATA, + .data = &exynos5260_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5420-tmu-ext-triminfo", - .data = (void *)EXYNOS5420_TMU_DRV_DATA, + .data = &exynos5420_default_tmu_data, }, { .compatible = "samsung,exynos5440-tmu", - .data = (void *)EXYNOS5440_TMU_DRV_DATA, + .data = &exynos5440_default_tmu_data, }, {}, }; diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 708c3e146e89..02a1c342db4c 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -24,7 +24,6 @@ #include "exynos_tmu.h" #include "exynos_tmu_data.h" -#if defined(CONFIG_CPU_EXYNOS4210) struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { { @@ -63,9 +62,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS3250) #define EXYNOS3250_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -101,9 +98,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2 -#endif -#if defined(CONFIG_SOC_EXYNOS3250) struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .tmu_data = { { @@ -113,9 +108,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) #define EXYNOS4412_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 70, \ @@ -151,9 +144,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .temp_level = 95, \ }, \ .freq_tab_count = 2 -#endif -#if defined(CONFIG_SOC_EXYNOS4412) struct exynos_tmu_init_data const exynos4412_default_tmu_data = { .tmu_data = { { @@ -163,9 +154,7 @@ struct exynos_tmu_init_data const exynos4412_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5250) struct exynos_tmu_init_data const exynos5250_default_tmu_data = { .tmu_data = { { @@ -175,9 +164,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { }, .tmu_count = 1, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5260) #define __EXYNOS5260_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -228,9 +215,7 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { }, .tmu_count = 5, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5420) #define __EXYNOS5420_TMU_DATA \ .threshold_falling = 10, \ .trigger_levels[0] = 85, \ @@ -285,9 +270,7 @@ struct exynos_tmu_init_data const exynos5420_default_tmu_data = { }, .tmu_count = 5, }; -#endif -#if defined(CONFIG_SOC_EXYNOS5440) #define EXYNOS5440_TMU_DATA \ .trigger_levels[0] = 100, \ .trigger_levels[4] = 105, \ @@ -316,4 +299,3 @@ struct exynos_tmu_init_data const exynos5440_default_tmu_data = { }, .tmu_count = 3, }; -#endif diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h index 2af312d8f7b5..0bfbbf234d57 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ b/drivers/thermal/samsung/exynos_tmu_data.h @@ -104,53 +104,12 @@ #define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 #define EXYNOS5440_EFUSE_SWAP_OFFSET 8 -#if defined(CONFIG_SOC_EXYNOS3250) extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; -#define EXYNOS3250_TMU_DRV_DATA (&exynos3250_default_tmu_data) -#else -#define EXYNOS3250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_CPU_EXYNOS4210) extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; -#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data) -#else -#define EXYNOS4210_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS4412) extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; -#define EXYNOS4412_TMU_DRV_DATA (&exynos4412_default_tmu_data) -#else -#define EXYNOS4412_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5250) extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; -#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data) -#else -#define EXYNOS5250_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5260) extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; -#define EXYNOS5260_TMU_DRV_DATA (&exynos5260_default_tmu_data) -#else -#define EXYNOS5260_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5420) extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; -#define EXYNOS5420_TMU_DRV_DATA (&exynos5420_default_tmu_data) -#else -#define EXYNOS5420_TMU_DRV_DATA (NULL) -#endif - -#if defined(CONFIG_SOC_EXYNOS5440) extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; -#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data) -#else -#define EXYNOS5440_TMU_DRV_DATA (NULL) -#endif #endif /*_EXYNOS_TMU_DATA_H*/ -- GitLab From 78f3320d7756c5f5ee34ea01916a91b714548962 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:27 +0100 Subject: [PATCH 5547/9457] thermal: exynos: remove __EXYNOS5420_TMU_DATA macro __EXYNOS5420_TMU_DATA macro is now identical to __EXYNOS5260_TMU_DATA one and can be removed. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu_data.c | 40 ++--------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 02a1c342db4c..592c470c1c4f 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -216,48 +216,12 @@ struct exynos_tmu_init_data const exynos5260_default_tmu_data = { .tmu_count = 5, }; -#define __EXYNOS5420_TMU_DATA \ - .threshold_falling = 10, \ - .trigger_levels[0] = 85, \ - .trigger_levels[1] = 103, \ - .trigger_levels[2] = 110, \ - .trigger_levels[3] = 120, \ - .trigger_enable[0] = true, \ - .trigger_enable[1] = true, \ - .trigger_enable[2] = true, \ - .trigger_enable[3] = false, \ - .trigger_type[0] = THROTTLE_ACTIVE, \ - .trigger_type[1] = THROTTLE_ACTIVE, \ - .trigger_type[2] = SW_TRIP, \ - .trigger_type[3] = HW_TRIP, \ - .max_trigger_level = 4, \ - .non_hw_trigger_levels = 3, \ - .gain = 8, \ - .reference_voltage = 16, \ - .noise_cancel_mode = 4, \ - .cal_type = TYPE_ONE_POINT_TRIMMING, \ - .efuse_value = 55, \ - .min_efuse_value = 40, \ - .max_efuse_value = 100, \ - .first_point_trim = 25, \ - .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 800 * 1000, \ - .temp_level = 85, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 200 * 1000, \ - .temp_level = 103, \ - }, \ - .freq_tab_count = 2, \ - #define EXYNOS5420_TMU_DATA \ - __EXYNOS5420_TMU_DATA \ + __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420 #define EXYNOS5420_TMU_DATA_SHARED \ - __EXYNOS5420_TMU_DATA \ + __EXYNOS5260_TMU_DATA \ .type = SOC_ARCH_EXYNOS5420_TRIMINFO struct exynos_tmu_init_data const exynos5420_default_tmu_data = { -- GitLab From 2845f6ec81d74344a93693d9b7807ae9c3dae9ed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Nov 2014 16:01:28 +0100 Subject: [PATCH 5548/9457] thermal: exynos: remove exynos_tmu_data.h include There is no longer need to share defines between exynos_tmu.c and exynos_tmu_data.c (as they are now only used by the former file) so move them accordingly. Then move externs for struct exynos_tmu_init_data instances to exynos_tmu.h and remove no longer needed exynos_tmu_data.h include. There should be no functional changes caused by this patch. Cc: Amit Daniel Kachhap Cc: Lukasz Majewski Cc: Eduardo Valentin Cc: Zhang Rui Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Tested-by: Lukasz Majewski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 82 ++++++++++++++- drivers/thermal/samsung/exynos_tmu.h | 8 ++ drivers/thermal/samsung/exynos_tmu_data.c | 1 - drivers/thermal/samsung/exynos_tmu_data.h | 115 ---------------------- 4 files changed, 89 insertions(+), 117 deletions(-) delete mode 100644 drivers/thermal/samsung/exynos_tmu_data.h diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 6cc6b6e7f4c4..2a1c4c7a7c1b 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -33,7 +33,87 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" + +/* Exynos generic registers */ +#define EXYNOS_TMU_REG_TRIMINFO 0x0 +#define EXYNOS_TMU_REG_CONTROL 0x20 +#define EXYNOS_TMU_REG_STATUS 0x28 +#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 +#define EXYNOS_TMU_REG_INTEN 0x70 +#define EXYNOS_TMU_REG_INTSTAT 0x74 +#define EXYNOS_TMU_REG_INTCLEAR 0x78 + +#define EXYNOS_TMU_TEMP_MASK 0xff +#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 +#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f +#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf +#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 +#define EXYNOS_TMU_CORE_EN_SHIFT 0 + +/* Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON1 0x10 + +/* Exynos4210 specific registers */ +#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 +#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 + +/* Exynos5250, Exynos4412, Exynos3250 specific registers */ +#define EXYNOS_TMU_TRIMINFO_CON2 0x14 +#define EXYNOS_THD_TEMP_RISE 0x50 +#define EXYNOS_THD_TEMP_FALL 0x54 +#define EXYNOS_EMUL_CON 0x80 + +#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 +#define EXYNOS_TRIMINFO_25_SHIFT 0 +#define EXYNOS_TRIMINFO_85_SHIFT 8 +#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 +#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 +#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 + +#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 +#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 +#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 +#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 + +#define EXYNOS_EMUL_TIME 0x57F0 +#define EXYNOS_EMUL_TIME_MASK 0xffff +#define EXYNOS_EMUL_TIME_SHIFT 16 +#define EXYNOS_EMUL_DATA_SHIFT 8 +#define EXYNOS_EMUL_DATA_MASK 0xFF +#define EXYNOS_EMUL_ENABLE 0x1 + +/* Exynos5260 specific */ +#define EXYNOS5260_TMU_REG_INTEN 0xC0 +#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 +#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 +#define EXYNOS5260_EMUL_CON 0x100 + +/* Exynos4412 specific */ +#define EXYNOS4412_MUX_ADDR_VALUE 6 +#define EXYNOS4412_MUX_ADDR_SHIFT 20 + +/*exynos5440 specific registers*/ +#define EXYNOS5440_TMU_S0_7_TRIM 0x000 +#define EXYNOS5440_TMU_S0_7_CTRL 0x020 +#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 +#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 +#define EXYNOS5440_TMU_S0_7_TH0 0x110 +#define EXYNOS5440_TMU_S0_7_TH1 0x130 +#define EXYNOS5440_TMU_S0_7_TH2 0x150 +#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 +#define EXYNOS5440_TMU_S0_7_IRQ 0x230 +/* exynos5440 common registers */ +#define EXYNOS5440_TMU_IRQ_STATUS 0x000 +#define EXYNOS5440_TMU_PMIN 0x004 + +#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 +#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 +#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 +#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 +#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 +#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 +#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 /** * struct exynos_tmu_data : A structure to hold the private data of the TMU diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 8de0f8254947..da3009bff6c4 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -133,4 +133,12 @@ struct exynos_tmu_init_data { struct exynos_tmu_platform_data tmu_data[]; }; +extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; +extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; +extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; + #endif /* _EXYNOS_TMU_H */ diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index 592c470c1c4f..b23910069f68 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -22,7 +22,6 @@ #include "exynos_thermal_common.h" #include "exynos_tmu.h" -#include "exynos_tmu_data.h" struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .tmu_data = { diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h deleted file mode 100644 index 0bfbbf234d57..000000000000 --- a/drivers/thermal/samsung/exynos_tmu_data.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * exynos_tmu_data.h - Samsung EXYNOS tmu data header file - * - * Copyright (C) 2013 Samsung Electronics - * Amit Daniel Kachhap - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _EXYNOS_TMU_DATA_H -#define _EXYNOS_TMU_DATA_H - -/* Exynos generic registers */ -#define EXYNOS_TMU_REG_TRIMINFO 0x0 -#define EXYNOS_TMU_REG_CONTROL 0x20 -#define EXYNOS_TMU_REG_STATUS 0x28 -#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40 -#define EXYNOS_TMU_REG_INTEN 0x70 -#define EXYNOS_TMU_REG_INTSTAT 0x74 -#define EXYNOS_TMU_REG_INTCLEAR 0x78 - -#define EXYNOS_TMU_TEMP_MASK 0xff -#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24 -#define EXYNOS_TMU_REF_VOLTAGE_MASK 0x1f -#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf -#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT 8 -#define EXYNOS_TMU_CORE_EN_SHIFT 0 - -/* Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON1 0x10 - -/* Exynos4210 specific registers */ -#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44 -#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50 - -/* Exynos5250, Exynos4412, Exynos3250 specific registers */ -#define EXYNOS_TMU_TRIMINFO_CON2 0x14 -#define EXYNOS_THD_TEMP_RISE 0x50 -#define EXYNOS_THD_TEMP_FALL 0x54 -#define EXYNOS_EMUL_CON 0x80 - -#define EXYNOS_TRIMINFO_RELOAD_ENABLE 1 -#define EXYNOS_TRIMINFO_25_SHIFT 0 -#define EXYNOS_TRIMINFO_85_SHIFT 8 -#define EXYNOS_TMU_TRIP_MODE_SHIFT 13 -#define EXYNOS_TMU_TRIP_MODE_MASK 0x7 -#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT 12 - -#define EXYNOS_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS_TMU_INTEN_RISE1_SHIFT 4 -#define EXYNOS_TMU_INTEN_RISE2_SHIFT 8 -#define EXYNOS_TMU_INTEN_RISE3_SHIFT 12 -#define EXYNOS_TMU_INTEN_FALL0_SHIFT 16 - -#define EXYNOS_EMUL_TIME 0x57F0 -#define EXYNOS_EMUL_TIME_MASK 0xffff -#define EXYNOS_EMUL_TIME_SHIFT 16 -#define EXYNOS_EMUL_DATA_SHIFT 8 -#define EXYNOS_EMUL_DATA_MASK 0xFF -#define EXYNOS_EMUL_ENABLE 0x1 - -/* Exynos5260 specific */ -#define EXYNOS5260_TMU_REG_INTEN 0xC0 -#define EXYNOS5260_TMU_REG_INTSTAT 0xC4 -#define EXYNOS5260_TMU_REG_INTCLEAR 0xC8 -#define EXYNOS5260_EMUL_CON 0x100 - -/* Exynos4412 specific */ -#define EXYNOS4412_MUX_ADDR_VALUE 6 -#define EXYNOS4412_MUX_ADDR_SHIFT 20 - -/*exynos5440 specific registers*/ -#define EXYNOS5440_TMU_S0_7_TRIM 0x000 -#define EXYNOS5440_TMU_S0_7_CTRL 0x020 -#define EXYNOS5440_TMU_S0_7_DEBUG 0x040 -#define EXYNOS5440_TMU_S0_7_TEMP 0x0f0 -#define EXYNOS5440_TMU_S0_7_TH0 0x110 -#define EXYNOS5440_TMU_S0_7_TH1 0x130 -#define EXYNOS5440_TMU_S0_7_TH2 0x150 -#define EXYNOS5440_TMU_S0_7_IRQEN 0x210 -#define EXYNOS5440_TMU_S0_7_IRQ 0x230 -/* exynos5440 common registers */ -#define EXYNOS5440_TMU_IRQ_STATUS 0x000 -#define EXYNOS5440_TMU_PMIN 0x004 - -#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT 0 -#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT 1 -#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT 2 -#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT 3 -#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT 4 -#define EXYNOS5440_TMU_TH_RISE4_SHIFT 24 -#define EXYNOS5440_EFUSE_SWAP_OFFSET 8 - -extern struct exynos_tmu_init_data const exynos3250_default_tmu_data; -extern struct exynos_tmu_init_data const exynos4210_default_tmu_data; -extern struct exynos_tmu_init_data const exynos4412_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5250_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5260_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5420_default_tmu_data; -extern struct exynos_tmu_init_data const exynos5440_default_tmu_data; - -#endif /*_EXYNOS_TMU_DATA_H*/ -- GitLab From 0af26492d5f5c00a08d52e9f3f3831faead90246 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 20 Nov 2014 10:05:36 -0500 Subject: [PATCH 5549/9457] tracing/trivial: Fix typos and make an int into a bool Fix up a few typos in comments and convert an int into a bool in update_traceon_count(). Link: http://lkml.kernel.org/r/546DD445.5080108@hitachi.com Suggested-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 2 +- kernel/trace/trace_functions.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fa0f36bb32e9..588af40d33db 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1119,7 +1119,7 @@ static struct ftrace_ops global_ops = { /* * This is used by __kernel_text_address() to return true if the - * the address is on a dynamically allocated trampoline that would + * address is on a dynamically allocated trampoline that would * not return true for either core_kernel_text() or * is_module_text_address(). */ diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 973db52eb070..fcd41a166405 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -261,14 +261,14 @@ static struct tracer function_trace __tracer_data = }; #ifdef CONFIG_DYNAMIC_FTRACE -static void update_traceon_count(void **data, int on) +static void update_traceon_count(void **data, bool on) { long *count = (long *)data; long old_count = *count; /* * Tracing gets disabled (or enabled) once per count. - * This function can be called at the same time on mulitple CPUs. + * This function can be called at the same time on multiple CPUs. * It is fine if both disable (or enable) tracing, as disabling * (or enabling) the second time doesn't do anything as the * state of the tracer is already disabled (or enabled). @@ -288,7 +288,7 @@ static void update_traceon_count(void **data, int on) * the new state is visible before changing the counter by * one minus the old counter. This guarantees that another CPU * executing this code will see the new state before seeing - * the new counter value, and would not do anthing if the new + * the new counter value, and would not do anything if the new * counter is seen. * * Note, there is no synchronization between this and a user -- GitLab From 55072d194ca1bee7dcbf2e24d30728c0141085f6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 20 Nov 2014 16:10:28 +0100 Subject: [PATCH 5550/9457] drm/i915: Dump hdmi pipe_config state Makes it easier to debug infoframe mismatches. Cc: Paulo Zanoni Cc: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9c983e4c33bd..83af88cef296 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10001,6 +10001,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config->dp_m2_n2.link_n, pipe_config->dp_m2_n2.tu); + DRM_DEBUG_KMS("audio: %i, infoframes: %i\n", + pipe_config->has_audio, + pipe_config->has_infoframe); + DRM_DEBUG_KMS("requested mode:\n"); drm_mode_debug_printmodeline(&pipe_config->requested_mode); DRM_DEBUG_KMS("adjusted mode:\n"); -- GitLab From 738c05c07d74769a1c5704636969b9b21cc96835 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 16:25:37 +0200 Subject: [PATCH 5551/9457] drm/i915: vlv: fix cdclk setting during modeset while suspended MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently after doing DPMS-OFF on all outputs CDCLK won't be set to its minimum value as it should. A subsequent modeset to turn off all outputs will thus run with all power domains disabled, and notice that it needs to change CDCLK to its minimum value. Since the power domains are disabled this will emit a register-access-while-suspended WARN and fail to set the minimum freq. The proper solution for this is to set the minimum frequency during DPMS-OFF. That needs a bigger rework that would take into account the user DPMS setting too during the calculation of the new modesetting configuration. Until that's done this stop-gap solution gets the PIPE-A power domain during setting the CDCLK; this domain covers the HW blocks needed for this. Idea to use PIPE-A domain from Ville. Testcase: igt/pm_rpm Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939 Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 83af88cef296..d4aa2dd5f14d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4939,10 +4939,23 @@ static void valleyview_modeset_global_resources(struct drm_device *dev) int req_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk); if (req_cdclk != dev_priv->vlv_cdclk_freq) { + /* + * FIXME: We can end up here with all power domains off, yet + * with a CDCLK frequency other than the minimum. To account + * for this take the PIPE-A power domain, which covers the HW + * blocks needed for the following programming. This can be + * removed once it's guaranteed that we get here either with + * the minimum CDCLK set, or the required power domains + * enabled. + */ + intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); + if (IS_CHERRYVIEW(dev)) cherryview_set_cdclk(dev, req_cdclk); else valleyview_set_cdclk(dev, req_cdclk); + + intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A); } } -- GitLab From 2837ac40698d0931727b957a40c8c8ea27c3bcb2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 19 Nov 2014 16:25:38 +0200 Subject: [PATCH 5552/9457] drm/i915: vlv: increase timeout when setting idle GPU freq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I saw punit timeouts in vlv_set_rps_idle() while running various subtests of pm_rpm. Increasing the timeout to 100ms got rid of the issue. Testcase: igt/pm_rpm Reference: https://bugs.freedesktop.org/show_bug.cgi?id=82939 Signed-off-by: Imre Deak Tested-by: Guo Jinxian Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f103ffffc599..14f34f0358c0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4451,7 +4451,7 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) dev_priv->rps.min_freq_softlimit); if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) - & GENFREQSTATUS) == 0, 5)) + & GENFREQSTATUS) == 0, 100)) DRM_ERROR("timed out waiting for Punit\n"); vlv_force_gfx_clock(dev_priv, false); -- GitLab From cc1df8a3fe39357fa5b727780129f50a68bff8f9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Nov 2014 18:38:39 +0100 Subject: [PATCH 5553/9457] drm/i915: Use ggtt error obj capture helper for gen8 semaphores Spotted while reading and trying to understand how our error capture code deals with full ppgtt. Cc: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gpu_error.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 82111b8ad374..cdaee6ce05f8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -809,9 +809,8 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, if (!error->semaphore_obj) error->semaphore_obj = - i915_error_object_create(dev_priv, - dev_priv->semaphore_obj, - &dev_priv->gtt.base); + i915_error_ggtt_object_create(dev_priv, + dev_priv->semaphore_obj); for_each_ring(to, dev_priv, i) { int idx; -- GitLab From 99990f1b0b95b3c6056d7d80669ab9a8644fed34 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 20 Nov 2014 17:59:22 +0200 Subject: [PATCH 5554/9457] drm/i915: remove the IRQs enabled WARN from intel_disable_gt_powersave This function can be called now with i915 interrupts enabled, so the corresponding WARN is incorrect, remove it. I think this was spotted by Paulo during his review, but since I already removed the same WARN from intel_suspend_gt_powersave() I missed then his point. Spotted-by: Paulo Zanoni Signed-off-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 14f34f0358c0..9af0af49382e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6223,9 +6223,6 @@ void intel_disable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* Interrupts should be disabled already to avoid re-arming. */ - WARN_ON(intel_irqs_enabled(dev_priv)); - if (IS_IRONLAKE_M(dev)) { ironlake_disable_drps(dev); ironlake_disable_rc6(dev); -- GitLab From 78b1a6010b46a69bcd47b723a80f92693f26d17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 18 Nov 2014 18:00:08 +0900 Subject: [PATCH 5555/9457] drm/radeon: Use cursor_set2 hook for enabling / disabling the HW cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cursor_set2 hook provides the cursor hotspot position within the cursor image. When the hotspot position changes, we can adjust the cursor position such that the hotspot doesn't move on the screen. This prevents the cursor from appearing to intermittently jump around on the screen when the position of the hotspot within the cursor image changes. Reviewed-by: Alex Deucher Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_cursor.c | 51 +++++++++++++++++++------ drivers/gpu/drm/radeon/radeon_display.c | 2 +- drivers/gpu/drm/radeon/radeon_mode.h | 16 +++++--- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 9630e8d95fb4..fd4bddfd67d6 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -117,8 +117,10 @@ static void radeon_show_cursor(struct drm_crtc *crtc) } } +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y); + static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, - uint64_t gpu_addr) + uint64_t gpu_addr, int hot_x, int hot_y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -142,13 +144,28 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, /* offset is from DISP(2)_BASE_ADDRESS */ WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); } + + if (hot_x != radeon_crtc->cursor_hot_x || + hot_y != radeon_crtc->cursor_hot_y) { + int x, y; + + x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; + y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; + + radeon_cursor_move_locked(crtc, x, y); + + radeon_crtc->cursor_hot_x = hot_x; + radeon_crtc->cursor_hot_y = hot_y; + } } -int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height) +int radeon_crtc_cursor_set2(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, + uint32_t height, + int32_t hot_x, + int32_t hot_y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -192,7 +209,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, radeon_crtc->cursor_height = height; radeon_lock_cursor(crtc, true); - radeon_set_cursor(crtc, obj, gpu_addr); + radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); radeon_show_cursor(crtc); radeon_lock_cursor(crtc, false); @@ -215,8 +232,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, return ret; } -int radeon_crtc_cursor_move(struct drm_crtc *crtc, - int x, int y) +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; @@ -281,7 +297,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, } } - radeon_lock_cursor(crtc, true); if (ASIC_IS_DCE4(rdev)) { WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); @@ -308,7 +323,21 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + (yorigin * 256))); } - radeon_lock_cursor(crtc, false); + + radeon_crtc->cursor_x = x; + radeon_crtc->cursor_y = y; return 0; } + +int radeon_crtc_cursor_move(struct drm_crtc *crtc, + int x, int y) +{ + int ret; + + radeon_lock_cursor(crtc, true); + ret = radeon_cursor_move_locked(crtc, x, y); + radeon_lock_cursor(crtc, false); + + return ret; +} diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index f1b0fa1285bb..102116902a07 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -635,7 +635,7 @@ radeon_crtc_set_config(struct drm_mode_set *set) return ret; } static const struct drm_crtc_funcs radeon_crtc_funcs = { - .cursor_set = radeon_crtc_cursor_set, + .cursor_set2 = radeon_crtc_cursor_set2, .cursor_move = radeon_crtc_cursor_move, .gamma_set = radeon_crtc_gamma_set, .set_config = radeon_crtc_set_config, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 64eba7ebb354..f3d87cdd5c9d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -321,6 +321,10 @@ struct radeon_crtc { uint32_t crtc_offset; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; + int cursor_x; + int cursor_y; + int cursor_hot_x; + int cursor_hot_y; int cursor_width; int cursor_height; int max_cursor_width; @@ -805,11 +809,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic); -extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height); +extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, + uint32_t height, + int32_t hot_x, + int32_t hot_y); extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); -- GitLab From 3feba08d79c32777a845c3c8a4ab93092bdf6f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 18 Nov 2014 18:00:09 +0900 Subject: [PATCH 5556/9457] drm/radeon: Move radeon_cursor_move(_locked) to replace forward declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change. Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_cursor.c | 220 ++++++++++++------------- 1 file changed, 109 insertions(+), 111 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index fd4bddfd67d6..85f38ee11888 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -117,7 +117,115 @@ static void radeon_show_cursor(struct drm_crtc *crtc) } } -static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y); +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct radeon_device *rdev = crtc->dev->dev_private; + int xorigin = 0, yorigin = 0; + int w = radeon_crtc->cursor_width; + + if (ASIC_IS_AVIVO(rdev)) { + /* avivo cursor are offset into the total surface */ + x += crtc->x; + y += crtc->y; + } + DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); + + if (x < 0) { + xorigin = min(-x, radeon_crtc->max_cursor_width - 1); + x = 0; + } + if (y < 0) { + yorigin = min(-y, radeon_crtc->max_cursor_height - 1); + y = 0; + } + + /* fixed on DCE6 and newer */ + if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) { + int i = 0; + struct drm_crtc *crtc_p; + + /* + * avivo cursor image can't end on 128 pixel boundary or + * go past the end of the frame if both crtcs are enabled + * + * NOTE: It is safe to access crtc->enabled of other crtcs + * without holding either the mode_config lock or the other + * crtc's lock as long as write access to this flag _always_ + * grabs all locks. + */ + list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { + if (crtc_p->enabled) + i++; + } + if (i > 1) { + int cursor_end, frame_end; + + cursor_end = x - xorigin + w; + frame_end = crtc->x + crtc->mode.crtc_hdisplay; + if (cursor_end >= frame_end) { + w = w - (cursor_end - frame_end); + if (!(frame_end & 0x7f)) + w--; + } else { + if (!(cursor_end & 0x7f)) + w--; + } + if (w <= 0) { + w = 1; + cursor_end = x - xorigin + w; + if (!(cursor_end & 0x7f)) { + x--; + WARN_ON_ONCE(x < 0); + } + } + } + } + + if (ASIC_IS_DCE4(rdev)) { + WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); + WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); + WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, + ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); + } else if (ASIC_IS_AVIVO(rdev)) { + WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); + WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); + WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, + ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); + } else { + if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) + y *= 2; + + WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset, + (RADEON_CUR_LOCK + | (xorigin << 16) + | yorigin)); + WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, + (RADEON_CUR_LOCK + | (x << 16) + | y)); + /* offset is from DISP(2)_BASE_ADDRESS */ + WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + + (yorigin * 256))); + } + + radeon_crtc->cursor_x = x; + radeon_crtc->cursor_y = y; + + return 0; +} + +int radeon_crtc_cursor_move(struct drm_crtc *crtc, + int x, int y) +{ + int ret; + + radeon_lock_cursor(crtc, true); + ret = radeon_cursor_move_locked(crtc, x, y); + radeon_lock_cursor(crtc, false); + + return ret; +} static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, uint64_t gpu_addr, int hot_x, int hot_y) @@ -231,113 +339,3 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, return ret; } - -static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - int xorigin = 0, yorigin = 0; - int w = radeon_crtc->cursor_width; - - if (ASIC_IS_AVIVO(rdev)) { - /* avivo cursor are offset into the total surface */ - x += crtc->x; - y += crtc->y; - } - DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); - - if (x < 0) { - xorigin = min(-x, radeon_crtc->max_cursor_width - 1); - x = 0; - } - if (y < 0) { - yorigin = min(-y, radeon_crtc->max_cursor_height - 1); - y = 0; - } - - /* fixed on DCE6 and newer */ - if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) { - int i = 0; - struct drm_crtc *crtc_p; - - /* - * avivo cursor image can't end on 128 pixel boundary or - * go past the end of the frame if both crtcs are enabled - * - * NOTE: It is safe to access crtc->enabled of other crtcs - * without holding either the mode_config lock or the other - * crtc's lock as long as write access to this flag _always_ - * grabs all locks. - */ - list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { - if (crtc_p->enabled) - i++; - } - if (i > 1) { - int cursor_end, frame_end; - - cursor_end = x - xorigin + w; - frame_end = crtc->x + crtc->mode.crtc_hdisplay; - if (cursor_end >= frame_end) { - w = w - (cursor_end - frame_end); - if (!(frame_end & 0x7f)) - w--; - } else { - if (!(cursor_end & 0x7f)) - w--; - } - if (w <= 0) { - w = 1; - cursor_end = x - xorigin + w; - if (!(cursor_end & 0x7f)) { - x--; - WARN_ON_ONCE(x < 0); - } - } - } - } - - if (ASIC_IS_DCE4(rdev)) { - WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); - WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); - WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, - ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); - } else if (ASIC_IS_AVIVO(rdev)) { - WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); - WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); - WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, - ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); - } else { - if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) - y *= 2; - - WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset, - (RADEON_CUR_LOCK - | (xorigin << 16) - | yorigin)); - WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, - (RADEON_CUR_LOCK - | (x << 16) - | y)); - /* offset is from DISP(2)_BASE_ADDRESS */ - WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + - (yorigin * 256))); - } - - radeon_crtc->cursor_x = x; - radeon_crtc->cursor_y = y; - - return 0; -} - -int radeon_crtc_cursor_move(struct drm_crtc *crtc, - int x, int y) -{ - int ret; - - radeon_lock_cursor(crtc, true); - ret = radeon_cursor_move_locked(crtc, x, y); - radeon_lock_cursor(crtc, false); - - return ret; -} -- GitLab From 4bb62c95a7e781a238b2ab374f34b1bf91e01ddc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 17 Nov 2014 15:08:17 -0500 Subject: [PATCH 5557/9457] drm/radeon: work around a hw bug in MGCG on CIK Always need to set bit 0 of RLC_CGTT_MGCG_OVERRIDE to avoid unreliable doorbell updates in some cases. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cik.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index bce73b6203ac..cef4cb7e5438 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -6344,6 +6344,7 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) } orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); + data |= 0x00000001; data &= 0xfffffffd; if (orig != data) WREG32(RLC_CGTT_MGCG_OVERRIDE, data); @@ -6377,7 +6378,7 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) } } else { orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); - data |= 0x00000002; + data |= 0x00000003; if (orig != data) WREG32(RLC_CGTT_MGCG_OVERRIDE, data); -- GitLab From a4722fd3f2d3590af5200890b61dbbdf87480abb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 20 Nov 2014 10:12:32 -0600 Subject: [PATCH 5558/9457] usb: dwc3: trace: don't save pointers There was another instance where we were holding pointers which could be long gone. Fix that by caching only values pointed to by such pointer. Because no crash has been observed, this patch will be sent on v3.19 merge window, instead of -rc. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/trace.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 7a9d7804193c..9fc20b33dd8e 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -175,17 +175,21 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, TP_STRUCT__entry( __dynamic_array(char, name, DWC3_MSG_MAX) __field(unsigned int, cmd) - __field(struct dwc3_gadget_ep_cmd_params *, params) + __field(u32, param0) + __field(u32, param1) + __field(u32, param2) ), TP_fast_assign( snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); __entry->cmd = cmd; - __entry->params = params; + __entry->param0 = params->param0; + __entry->param1 = params->param1; + __entry->param2 = params->param2; ), TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x", __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), - __entry->cmd, __entry->params->param0, - __entry->params->param1, __entry->params->param2 + __entry->cmd, __entry->param0, + __entry->param1, __entry->param2 ) ); -- GitLab From b3c8e93f99a7f9453be54549ae362b603c42188c Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 18 Nov 2014 13:27:48 -0800 Subject: [PATCH 5559/9457] HID: wacom - return ENODEV for failed wacom_setup_pad_input_capabilities ENODEV indicates no device is added. Hence, the associated pad input device is simply freed. Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 104829524bcd..63821c0e8207 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2405,7 +2405,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOSPS: /* touch interface does not have the pad device */ if (features->device_type != BTN_TOOL_PEN) - return 1; + return -ENODEV; for (i = 0; i < 7; i++) __set_bit(BTN_0 + i, input_dev->keybit); @@ -2450,7 +2450,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case BAMBOO_PT: /* pad device is on the touch interface */ if (features->device_type != BTN_TOOL_FINGER) - return 1; + return -ENODEV; __clear_bit(ABS_MISC, input_dev->absbit); @@ -2463,7 +2463,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, default: /* no pad supported */ - return 1; + return -ENODEV; } return 0; } -- GitLab From 97edcad81324ede21e421b79eaeab26f0b1ad2fc Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 18 Nov 2014 13:28:37 -0800 Subject: [PATCH 5560/9457] HID: wacom - Cleanup input_capabilities for Graphire 4 and Bamboo Fun Graphire 4 only has two tablet buttons; Bamboo Fun touch ring is only for PAD. Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 63821c0e8207..51c7353e01a5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2050,9 +2050,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, switch (features->type) { case WACOM_MO: - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - /* fall through */ - case WACOM_G4: /* fall through */ @@ -2306,9 +2303,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case WACOM_G4: __set_bit(BTN_BACK, input_dev->keybit); - __set_bit(BTN_LEFT, input_dev->keybit); __set_bit(BTN_FORWARD, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); input_set_capability(input_dev, EV_REL, REL_WHEEL); break; -- GitLab From 30ebc1aea8ce02da5b3789eba775dd2d79837813 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 18 Nov 2014 13:29:16 -0800 Subject: [PATCH 5561/9457] HID: wacom - Bamboo pen-only tablet does not support PAD Bamboo models do not support HID_DG_CONTACTMAX. Plus, Bamboo pen-only has touch descriptor. This leads to some complications in the code. This patch also fixes duplicated PAD interfeaces for Intuos Pen models. Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom.h | 2 +- drivers/hid/wacom_sys.c | 25 +++++++++++++++---------- drivers/hid/wacom_wac.c | 9 +++++++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 0cc53440543a..7db432809e9e 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -140,7 +140,7 @@ extern const struct hid_device_id wacom_ids[]; void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); void wacom_setup_device_quirks(struct wacom_features *features); -int wacom_setup_input_capabilities(struct input_dev *input_dev, +int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac); diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 8593047bb726..68b6cd66f9c3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -192,9 +192,15 @@ static void wacom_usage_mapping(struct hid_device *hdev, if (!pen && !finger) return; - if (finger && !features->touch_max) - /* touch device at least supports one touch point */ - features->touch_max = 1; + /* + * Bamboo models do not support HID_DG_CONTACTMAX. + * And, Bamboo Pen only descriptor contains touch. + */ + if (features->type != BAMBOO_PT) { + /* ISDv4 touch devices at least supports one touch point */ + if (finger && !features->touch_max) + features->touch_max = 1; + } switch (usage->hid) { case HID_GD_X: @@ -1151,13 +1157,12 @@ static int wacom_register_inputs(struct wacom *wacom) if (!input_dev || !pad_input_dev) return -EINVAL; - error = wacom_setup_input_capabilities(input_dev, wacom_wac); - if (error) - return error; - - error = input_register_device(input_dev); - if (error) - return error; + error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac); + if (!error) { + error = input_register_device(input_dev); + if (error) + return error; + } error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); if (error) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 51c7353e01a5..caf035f662b9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2032,7 +2032,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, } } -int wacom_setup_input_capabilities(struct input_dev *input_dev, +int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { struct wacom_features *features = &wacom_wac->features; @@ -2246,6 +2246,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __clear_bit(ABS_X, input_dev->absbit); __clear_bit(ABS_Y, input_dev->absbit); __clear_bit(BTN_TOUCH, input_dev->keybit); + + /* PAD is setup by wacom_setup_pad_input_capabilities later */ + return 1; } } else if (features->device_type == BTN_TOOL_PEN) { __set_bit(INPUT_PROP_POINTER, input_dev->propbit); @@ -2444,7 +2447,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOSHT: case BAMBOO_PT: /* pad device is on the touch interface */ - if (features->device_type != BTN_TOOL_FINGER) + if ((features->device_type != BTN_TOOL_FINGER) || + /* Bamboo Pen only tablet does not have pad */ + ((features->type == BAMBOO_PT) && !features->touch_max)) return -ENODEV; __clear_bit(ABS_MISC, input_dev->absbit); -- GitLab From a017784f1b236cbc42ce83b4345a667c21113481 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 9 Oct 2014 13:01:06 +0000 Subject: [PATCH 5562/9457] kprobes/ftrace: Recover original IP if pre_handler doesn't change it Recover original IP register if the pre_handler doesn't change it. Since current kprobes doesn't expect that another ftrace handler may change regs->ip, it sets kprobe.addr + MCOUNT_INSN_SIZE to regs->ip and returns to ftrace. This seems wrong behavior since kprobes can recover regs->ip and safely pass it to another handler. This adds code which recovers original regs->ip passed from ftrace right before returning to ftrace, so that another ftrace user can change regs->ip. Link: http://lkml.kernel.org/r/20141009130106.4698.26362.stgit@kbuild-f20.novalocal Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- arch/x86/kernel/kprobes/ftrace.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c index 717b02a22e67..5f8f0b3cc674 100644 --- a/arch/x86/kernel/kprobes/ftrace.c +++ b/arch/x86/kernel/kprobes/ftrace.c @@ -27,7 +27,7 @@ static nokprobe_inline int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, - struct kprobe_ctlblk *kcb) + struct kprobe_ctlblk *kcb, unsigned long orig_ip) { /* * Emulate singlestep (and also recover regs->ip) @@ -39,6 +39,8 @@ int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, p->post_handler(p, regs, 0); } __this_cpu_write(current_kprobe, NULL); + if (orig_ip) + regs->ip = orig_ip; return 1; } @@ -46,7 +48,7 @@ int skip_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { if (kprobe_ftrace(p)) - return __skip_singlestep(p, regs, kcb); + return __skip_singlestep(p, regs, kcb, 0); else return 0; } @@ -71,13 +73,14 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, if (kprobe_running()) { kprobes_inc_nmissed_count(p); } else { + unsigned long orig_ip = regs->ip; /* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */ regs->ip = ip + sizeof(kprobe_opcode_t); __this_cpu_write(current_kprobe, p); kcb->kprobe_status = KPROBE_HIT_ACTIVE; if (!p->pre_handler || !p->pre_handler(p, regs)) - __skip_singlestep(p, regs, kcb); + __skip_singlestep(p, regs, kcb, orig_ip); /* * If pre_handler returns !0, it sets regs->ip and * resets current kprobe. -- GitLab From b93b41d4c7338dda9304eaac9d3b40da43198806 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 12:19:11 -0500 Subject: [PATCH 5563/9457] ext4: kill ext4_kvfree() Signed-off-by: Al Viro Signed-off-by: Theodore Ts'o --- fs/ext4/ext4.h | 1 - fs/ext4/mballoc.c | 6 +++--- fs/ext4/resize.c | 6 +++--- fs/ext4/super.c | 19 +++++-------------- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c55a1faaed58..21a3b38395ff 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2192,7 +2192,6 @@ extern int ext4_calculate_overhead(struct super_block *sb); extern void ext4_superblock_csum_set(struct super_block *sb); extern void *ext4_kvmalloc(size_t size, gfp_t flags); extern void *ext4_kvzalloc(size_t size, gfp_t flags); -extern void ext4_kvfree(void *ptr); extern int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup); extern const char *ext4_decode_error(struct super_block *sb, int errno, diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dbfe15c2533c..004d0ff8325f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2358,7 +2358,7 @@ int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups) if (sbi->s_group_info) { memcpy(new_groupinfo, sbi->s_group_info, sbi->s_group_info_size * sizeof(*sbi->s_group_info)); - ext4_kvfree(sbi->s_group_info); + kvfree(sbi->s_group_info); } sbi->s_group_info = new_groupinfo; sbi->s_group_info_size = size / sizeof(*sbi->s_group_info); @@ -2495,7 +2495,7 @@ static int ext4_mb_init_backend(struct super_block *sb) kfree(sbi->s_group_info[i]); iput(sbi->s_buddy_cache); err_freesgi: - ext4_kvfree(sbi->s_group_info); + kvfree(sbi->s_group_info); return -ENOMEM; } @@ -2708,7 +2708,7 @@ int ext4_mb_release(struct super_block *sb) EXT4_DESC_PER_BLOCK_BITS(sb); for (i = 0; i < num_meta_group_infos; i++) kfree(sbi->s_group_info[i]); - ext4_kvfree(sbi->s_group_info); + kvfree(sbi->s_group_info); } kfree(sbi->s_mb_offsets); kfree(sbi->s_mb_maxs); diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index ca4588388fc3..bf76f405a5f9 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -856,7 +856,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, n_group_desc[gdb_num] = gdb_bh; EXT4_SB(sb)->s_group_desc = n_group_desc; EXT4_SB(sb)->s_gdb_count++; - ext4_kvfree(o_group_desc); + kvfree(o_group_desc); le16_add_cpu(&es->s_reserved_gdt_blocks, -1); err = ext4_handle_dirty_super(handle, sb); @@ -866,7 +866,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, return err; exit_inode: - ext4_kvfree(n_group_desc); + kvfree(n_group_desc); brelse(iloc.bh); exit_dind: brelse(dind); @@ -909,7 +909,7 @@ static int add_new_gdb_meta_bg(struct super_block *sb, n_group_desc[gdb_num] = gdb_bh; EXT4_SB(sb)->s_group_desc = n_group_desc; EXT4_SB(sb)->s_gdb_count++; - ext4_kvfree(o_group_desc); + kvfree(o_group_desc); BUFFER_TRACE(gdb_bh, "get_write_access"); err = ext4_journal_get_write_access(handle, gdb_bh); if (unlikely(err)) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2c9e6864abd9..4b79f39ebf66 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -176,15 +176,6 @@ void *ext4_kvzalloc(size_t size, gfp_t flags) return ret; } -void ext4_kvfree(void *ptr) -{ - if (is_vmalloc_addr(ptr)) - vfree(ptr); - else - kfree(ptr); - -} - ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg) { @@ -811,8 +802,8 @@ static void ext4_put_super(struct super_block *sb) for (i = 0; i < sbi->s_gdb_count; i++) brelse(sbi->s_group_desc[i]); - ext4_kvfree(sbi->s_group_desc); - ext4_kvfree(sbi->s_flex_groups); + kvfree(sbi->s_group_desc); + kvfree(sbi->s_flex_groups); percpu_counter_destroy(&sbi->s_freeclusters_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); @@ -1939,7 +1930,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup) memcpy(new_groups, sbi->s_flex_groups, (sbi->s_flex_groups_allocated * sizeof(struct flex_groups))); - ext4_kvfree(sbi->s_flex_groups); + kvfree(sbi->s_flex_groups); } sbi->s_flex_groups = new_groups; sbi->s_flex_groups_allocated = size / sizeof(struct flex_groups); @@ -4224,7 +4215,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) failed_mount6: ext4_mb_release(sb); if (sbi->s_flex_groups) - ext4_kvfree(sbi->s_flex_groups); + kvfree(sbi->s_flex_groups); percpu_counter_destroy(&sbi->s_freeclusters_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); @@ -4253,7 +4244,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); - ext4_kvfree(sbi->s_group_desc); + kvfree(sbi->s_group_desc); failed_mount: if (sbi->s_chksum_driver) crypto_free_shash(sbi->s_chksum_driver); -- GitLab From 39471ad39de827657e6ab69da96496eb0943295e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 14 Sep 2014 21:14:14 -0400 Subject: [PATCH 5564/9457] drm/radeon/dpm: add smc fan control for SI (v2) Enable smc fan control for SI boards. Should reduce the fan noise on systems with a higher default fan profile. v2: disable by default, add rpm controls bug: https://bugs.freedesktop.org/show_bug.cgi?id=73338 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ppsmc.h | 5 + drivers/gpu/drm/radeon/r600_dpm.h | 3 + drivers/gpu/drm/radeon/si_dpm.c | 330 +++++++++++++++++++++++++- drivers/gpu/drm/radeon/si_dpm.h | 5 + drivers/gpu/drm/radeon/sid.h | 40 +++- drivers/gpu/drm/radeon/sislands_smc.h | 25 ++ 6 files changed, 401 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h index 11c0e4d5c0bf..0c4eaa60b6ca 100644 --- a/drivers/gpu/drm/radeon/ppsmc.h +++ b/drivers/gpu/drm/radeon/ppsmc.h @@ -56,6 +56,9 @@ #define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20 #define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS 0x40 +#define FDO_MODE_HARDWARE 0 +#define FDO_MODE_PIECE_WISE_LINEAR 1 + #define PPSMC_Result_OK ((uint8_t)0x01) #define PPSMC_Result_Failed ((uint8_t)0xFF) @@ -79,6 +82,8 @@ typedef uint8_t PPSMC_Result; #define PPSMC_MSG_DisableCac ((uint8_t)0x54) #define PPSMC_TDPClampingActive ((uint8_t)0x59) #define PPSMC_TDPClampingInactive ((uint8_t)0x5A) +#define PPSMC_StartFanControl ((uint8_t)0x5B) +#define PPSMC_StopFanControl ((uint8_t)0x5C) #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) #define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60) diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h index 46b9d2a03018..bd499d749bc9 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.h +++ b/drivers/gpu/drm/radeon/r600_dpm.h @@ -96,6 +96,9 @@ #define R600_TEMP_RANGE_MIN (90 * 1000) #define R600_TEMP_RANGE_MAX (120 * 1000) +#define FDO_PWM_MODE_STATIC 1 +#define FDO_PWM_MODE_STATIC_RPM 5 + enum r600_power_level { R600_POWER_LEVEL_LOW = 0, R600_POWER_LEVEL_MEDIUM = 1, diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index b59e1d6b27ab..cf4c420b5572 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -3396,6 +3396,15 @@ static int si_process_firmware_header(struct radeon_device *rdev) si_pi->mc_reg_table_start = tmp; + ret = si_read_smc_sram_dword(rdev, + SISLANDS_SMC_FIRMWARE_HEADER_LOCATION + + SISLANDS_SMC_FIRMWARE_HEADER_fanTable, + &tmp, si_pi->sram_end); + if (ret) + return ret; + + si_pi->fan_table_start = tmp; + ret = si_read_smc_sram_dword(rdev, SISLANDS_SMC_FIRMWARE_HEADER_LOCATION + SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable, @@ -5825,20 +5834,20 @@ static int si_thermal_enable_alert(struct radeon_device *rdev, if (enable) { PPSMC_Result result; - thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; - rdev->irq.dpm_thermal = true; + thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); + WREG32(CG_THERMAL_INT, thermal_int); + rdev->irq.dpm_thermal = false; result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); if (result != PPSMC_Result_OK) { DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); return -EINVAL; } } else { - thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); - rdev->irq.dpm_thermal = false; + thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; + WREG32(CG_THERMAL_INT, thermal_int); + rdev->irq.dpm_thermal = true; } - WREG32(CG_THERMAL_INT, thermal_int); - return 0; } @@ -5867,6 +5876,309 @@ static int si_thermal_set_temperature_range(struct radeon_device *rdev, return 0; } +static void si_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) +{ + struct si_power_info *si_pi = si_get_pi(rdev); + u32 tmp; + + if (si_pi->fan_ctrl_is_in_default_mode) { + tmp = (RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT; + si_pi->fan_ctrl_default_mode = tmp; + tmp = (RREG32(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT; + si_pi->t_min = tmp; + si_pi->fan_ctrl_is_in_default_mode = false; + } + + tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK; + tmp |= TMIN(0); + WREG32(CG_FDO_CTRL2, tmp); + + tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; + tmp |= FDO_PWM_MODE(mode); + WREG32(CG_FDO_CTRL2, tmp); +} + +static int si_thermal_setup_fan_table(struct radeon_device *rdev) +{ + struct si_power_info *si_pi = si_get_pi(rdev); + PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE }; + u32 duty100; + u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2; + u16 fdo_min, slope1, slope2; + u32 reference_clock, tmp; + int ret; + u64 tmp64; + + if (!si_pi->fan_table_start) { + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; + } + + duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + + if (duty100 == 0) { + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; + } + + tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100; + do_div(tmp64, 10000); + fdo_min = (u16)tmp64; + + t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min; + t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med; + + pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min; + pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med; + + slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.slope1 = cpu_to_be16(slope1); + fan_table.slope2 = cpu_to_be16(slope2); + + fan_table.fdo_min = cpu_to_be16(fdo_min); + + fan_table.hys_down = cpu_to_be16(rdev->pm.dpm.fan.t_hyst); + + fan_table.hys_up = cpu_to_be16(1); + + fan_table.hys_slope = cpu_to_be16(1); + + fan_table.temp_resp_lim = cpu_to_be16(5); + + reference_clock = radeon_get_xclk(rdev); + + fan_table.refresh_period = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay * + reference_clock) / 1600); + + fan_table.fdo_max = cpu_to_be16((u16)duty100); + + tmp = (RREG32(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT; + fan_table.temp_src = (uint8_t)tmp; + + ret = si_copy_bytes_to_smc(rdev, + si_pi->fan_table_start, + (u8 *)(&fan_table), + sizeof(fan_table), + si_pi->sram_end); + + if (ret) { + DRM_ERROR("Failed to load fan table to the SMC."); + rdev->pm.dpm.fan.ucode_fan_control = false; + } + + return 0; +} + +static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) +{ + PPSMC_Result ret; + + ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); + if (ret == PPSMC_Result_OK) + return 0; + else + return -EINVAL; +} + +static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) +{ + PPSMC_Result ret; + + ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); + if (ret == PPSMC_Result_OK) + return 0; + else + return -EINVAL; +} + +#if 0 +static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed) +{ + u32 duty, duty100; + u64 tmp64; + + if (rdev->pm.no_fan) + return -ENOENT; + + duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; + + if (duty100 == 0) + return -EINVAL; + + tmp64 = (u64)duty * 100; + do_div(tmp64, duty100); + *speed = (u32)tmp64; + + if (*speed > 100) + *speed = 100; + + return 0; +} + +static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed) +{ + u32 tmp; + u32 duty, duty100; + u64 tmp64; + + if (rdev->pm.no_fan) + return -ENOENT; + + if (speed > 100) + return -EINVAL; + + if (rdev->pm.dpm.fan.ucode_fan_control) + si_fan_ctrl_stop_smc_fan_control(rdev); + + duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + + if (duty100 == 0) + return -EINVAL; + + tmp64 = (u64)speed * duty100; + do_div(tmp64, 100); + duty = (u32)tmp64; + + tmp = RREG32(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK; + tmp |= FDO_STATIC_DUTY(duty); + WREG32(CG_FDO_CTRL0, tmp); + + si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + + return 0; +} + +static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, + u32 *speed) +{ + u32 tach_period; + u32 xclk = radeon_get_xclk(rdev); + + if (rdev->pm.no_fan) + return -ENOENT; + + if (rdev->pm.fan_pulses_per_revolution == 0) + return -ENOENT; + + tach_period = (RREG32(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT; + if (tach_period == 0) + return -ENOENT; + + *speed = 60 * xclk * 10000 / tach_period; + + return 0; +} + +static int si_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, + u32 speed) +{ + u32 tach_period, tmp; + u32 xclk = radeon_get_xclk(rdev); + + if (rdev->pm.no_fan) + return -ENOENT; + + if (rdev->pm.fan_pulses_per_revolution == 0) + return -ENOENT; + + if ((speed < rdev->pm.fan_min_rpm) || + (speed > rdev->pm.fan_max_rpm)) + return -EINVAL; + + if (rdev->pm.dpm.fan.ucode_fan_control) + si_fan_ctrl_stop_smc_fan_control(rdev); + + tach_period = 60 * xclk * 10000 / (8 * speed); + tmp = RREG32(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK; + tmp |= TARGET_PERIOD(tach_period); + WREG32(CG_TACH_CTRL, tmp); + + si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + + return 0; +} +#endif + +static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev) +{ + struct si_power_info *si_pi = si_get_pi(rdev); + u32 tmp; + + if (!si_pi->fan_ctrl_is_in_default_mode) { + tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; + tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode); + WREG32(CG_FDO_CTRL2, tmp); + + tmp = RREG32(CG_FDO_CTRL2) & TMIN_MASK; + tmp |= TMIN(si_pi->t_min); + WREG32(CG_FDO_CTRL2, tmp); + si_pi->fan_ctrl_is_in_default_mode = true; + } +} + +static void si_thermal_start_smc_fan_control(struct radeon_device *rdev) +{ + if (rdev->pm.dpm.fan.ucode_fan_control) { + si_fan_ctrl_start_smc_fan_control(rdev); + si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + } +} + +static void si_thermal_initialize(struct radeon_device *rdev) +{ + u32 tmp; + + if (rdev->pm.fan_pulses_per_revolution) { + tmp = RREG32(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK; + tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1); + WREG32(CG_TACH_CTRL, tmp); + } + + tmp = RREG32(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK; + tmp |= TACH_PWM_RESP_RATE(0x28); + WREG32(CG_FDO_CTRL2, tmp); +} + +static int si_thermal_start_thermal_controller(struct radeon_device *rdev) +{ + int ret; + + si_thermal_initialize(rdev); + ret = si_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + ret = si_thermal_enable_alert(rdev, true); + if (ret) + return ret; + if (rdev->pm.dpm.fan.ucode_fan_control) { + ret = si_halt_smc(rdev); + if (ret) + return ret; + ret = si_thermal_setup_fan_table(rdev); + if (ret) + return ret; + ret = si_resume_smc(rdev); + if (ret) + return ret; + si_thermal_start_smc_fan_control(rdev); + } + + return 0; +} + +static void si_thermal_stop_thermal_controller(struct radeon_device *rdev) +{ + if (!rdev->pm.no_fan) { + si_fan_ctrl_set_default_mode(rdev); + si_fan_ctrl_stop_smc_fan_control(rdev); + } +} + int si_dpm_enable(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev); @@ -5979,6 +6291,8 @@ int si_dpm_enable(struct radeon_device *rdev) si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); + si_thermal_start_thermal_controller(rdev); + ni_update_current_ps(rdev, boot_ps); return 0; @@ -6019,6 +6333,7 @@ void si_dpm_disable(struct radeon_device *rdev) if (!si_is_smc_running(rdev)) return; + si_thermal_stop_thermal_controller(rdev); si_disable_ulv(rdev); si_clear_vc(rdev); if (pi->thermal_protection) @@ -6557,6 +6872,9 @@ int si_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; + si_pi->fan_ctrl_is_in_default_mode = true; + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; } diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h index 8b5c06a0832d..d16bb1b5f10f 100644 --- a/drivers/gpu/drm/radeon/si_dpm.h +++ b/drivers/gpu/drm/radeon/si_dpm.h @@ -182,6 +182,7 @@ struct si_power_info { u32 dte_table_start; u32 spll_table_start; u32 papm_cfg_table_start; + u32 fan_table_start; /* CAC stuff */ const struct si_cac_config_reg *cac_weights; const struct si_cac_config_reg *lcac_config; @@ -197,6 +198,10 @@ struct si_power_info { /* SVI2 */ u8 svd_gpio_id; u8 svc_gpio_id; + /* fan control */ + bool fan_ctrl_is_in_default_mode; + u32 t_min; + u32 fan_ctrl_default_mode; }; #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 6635da9ec986..c549c16a4fe4 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -180,7 +180,10 @@ #define DIG_THERM_DPM(x) ((x) << 14) #define DIG_THERM_DPM_MASK 0x003FC000 #define DIG_THERM_DPM_SHIFT 14 - +#define CG_THERMAL_STATUS 0x704 +#define FDO_PWM_DUTY(x) ((x) << 9) +#define FDO_PWM_DUTY_MASK (0xff << 9) +#define FDO_PWM_DUTY_SHIFT 9 #define CG_THERMAL_INT 0x708 #define DIG_THERM_INTH(x) ((x) << 8) #define DIG_THERM_INTH_MASK 0x0000FF00 @@ -191,6 +194,10 @@ #define THERM_INT_MASK_HIGH (1 << 24) #define THERM_INT_MASK_LOW (1 << 25) +#define CG_MULT_THERMAL_CTRL 0x710 +#define TEMP_SEL(x) ((x) << 20) +#define TEMP_SEL_MASK (0xff << 20) +#define TEMP_SEL_SHIFT 20 #define CG_MULT_THERMAL_STATUS 0x714 #define ASIC_MAX_TEMP(x) ((x) << 0) #define ASIC_MAX_TEMP_MASK 0x000001ff @@ -199,6 +206,37 @@ #define CTF_TEMP_MASK 0x0003fe00 #define CTF_TEMP_SHIFT 9 +#define CG_FDO_CTRL0 0x754 +#define FDO_STATIC_DUTY(x) ((x) << 0) +#define FDO_STATIC_DUTY_MASK 0x0000000F +#define FDO_STATIC_DUTY_SHIFT 0 +#define CG_FDO_CTRL1 0x758 +#define FMAX_DUTY100(x) ((x) << 0) +#define FMAX_DUTY100_MASK 0x0000000F +#define FMAX_DUTY100_SHIFT 0 +#define CG_FDO_CTRL2 0x75C +#define TMIN(x) ((x) << 0) +#define TMIN_MASK 0x0000000F +#define TMIN_SHIFT 0 +#define FDO_PWM_MODE(x) ((x) << 11) +#define FDO_PWM_MODE_MASK (3 << 11) +#define FDO_PWM_MODE_SHIFT 11 +#define TACH_PWM_RESP_RATE(x) ((x) << 25) +#define TACH_PWM_RESP_RATE_MASK (0x7f << 25) +#define TACH_PWM_RESP_RATE_SHIFT 25 + +#define CG_TACH_CTRL 0x770 +# define EDGE_PER_REV(x) ((x) << 0) +# define EDGE_PER_REV_MASK (0x7 << 0) +# define EDGE_PER_REV_SHIFT 0 +# define TARGET_PERIOD(x) ((x) << 3) +# define TARGET_PERIOD_MASK 0xfffffff8 +# define TARGET_PERIOD_SHIFT 3 +#define CG_TACH_STATUS 0x774 +# define TACH_PERIOD(x) ((x) << 0) +# define TACH_PERIOD_MASK 0xffffffff +# define TACH_PERIOD_SHIFT 0 + #define GENERAL_PWRMGT 0x780 # define GLOBAL_PWRMGT_EN (1 << 0) # define STATIC_PM_EN (1 << 1) diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h index 623a0b1e2d9d..3c779838d9ab 100644 --- a/drivers/gpu/drm/radeon/sislands_smc.h +++ b/drivers/gpu/drm/radeon/sislands_smc.h @@ -245,6 +245,31 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE; #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 +struct PP_SIslands_FanTable +{ + uint8_t fdo_mode; + uint8_t padding; + int16_t temp_min; + int16_t temp_med; + int16_t temp_max; + int16_t slope1; + int16_t slope2; + int16_t fdo_min; + int16_t hys_up; + int16_t hys_down; + int16_t hys_slope; + int16_t temp_resp_lim; + int16_t temp_curr; + int16_t slope_curr; + int16_t pwm_curr; + uint32_t refresh_period; + int16_t fdo_max; + uint8_t temp_src; + int8_t padding2; +}; + +typedef struct PP_SIslands_FanTable PP_SIslands_FanTable; + #define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16 #define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32 -- GitLab From e03cea367f992e683435c41344197cd7b223b62c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 15 Sep 2014 00:15:22 -0400 Subject: [PATCH 5565/9457] drm/radeon/dpm: add smc fan control for CI (v2) Enable smc fan control for CI boards. Should reduce the fan noise on systems with a higher default fan profile. v2: disable by default, add additional fan setup, rpm control bug: https://bugs.freedesktop.org/show_bug.cgi?id=73338 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 345 ++++++++++++++++++++++++- drivers/gpu/drm/radeon/ci_dpm.h | 5 + drivers/gpu/drm/radeon/cikd.h | 40 ++- drivers/gpu/drm/radeon/ppsmc.h | 6 + drivers/gpu/drm/radeon/pptable.h | 8 + drivers/gpu/drm/radeon/r600_dpm.c | 9 + drivers/gpu/drm/radeon/radeon.h | 4 + drivers/gpu/drm/radeon/smu7_discrete.h | 30 ++- 8 files changed, 443 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 9dbc52f3c4d1..4581d6cf90e8 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -184,6 +184,9 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev, u32 target_tdp); static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); +static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, + PPSMC_Msg msg, u32 parameter); + static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) { struct ci_power_info *pi = rdev->pm.dpm.priv; @@ -355,6 +358,21 @@ static int ci_populate_dw8(struct radeon_device *rdev) return 0; } +static int ci_populate_fuzzy_fan(struct radeon_device *rdev) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + + if ((rdev->pm.dpm.fan.fan_output_sensitivity & (1 << 15)) || + (rdev->pm.dpm.fan.fan_output_sensitivity == 0)) + rdev->pm.dpm.fan.fan_output_sensitivity = + rdev->pm.dpm.fan.default_fan_output_sensitivity; + + pi->smc_powertune_table.FuzzyFan_PwmSetDelta = + cpu_to_be16(rdev->pm.dpm.fan.fan_output_sensitivity); + + return 0; +} + static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev) { struct ci_power_info *pi = ci_get_pi(rdev); @@ -478,6 +496,9 @@ static int ci_populate_pm_base(struct radeon_device *rdev) if (ret) return ret; ret = ci_populate_dw8(rdev); + if (ret) + return ret; + ret = ci_populate_fuzzy_fan(rdev); if (ret) return ret; ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev); @@ -859,6 +880,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, if (enable) { thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); + WREG32_SMC(CG_THERMAL_INT, thermal_int); rdev->irq.dpm_thermal = false; result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable); if (result != PPSMC_Result_OK) { @@ -867,6 +889,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, } } else { thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; + WREG32_SMC(CG_THERMAL_INT, thermal_int); rdev->irq.dpm_thermal = true; result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable); if (result != PPSMC_Result_OK) { @@ -875,11 +898,324 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, } } - WREG32_SMC(CG_THERMAL_INT, thermal_int); + return 0; +} + +static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + u32 tmp; + + if (pi->fan_ctrl_is_in_default_mode) { + tmp = (RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT; + pi->fan_ctrl_default_mode = tmp; + tmp = (RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT; + pi->t_min = tmp; + pi->fan_ctrl_is_in_default_mode = false; + } + + tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK; + tmp |= TMIN(0); + WREG32_SMC(CG_FDO_CTRL2, tmp); + + tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; + tmp |= FDO_PWM_MODE(mode); + WREG32_SMC(CG_FDO_CTRL2, tmp); +} + +static int ci_thermal_setup_fan_table(struct radeon_device *rdev) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; + u32 duty100; + u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2; + u16 fdo_min, slope1, slope2; + u32 reference_clock, tmp; + int ret; + u64 tmp64; + + if (!pi->fan_table_start) { + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; + } + + duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + + if (duty100 == 0) { + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; + } + + tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100; + do_div(tmp64, 10000); + fdo_min = (u16)tmp64; + + t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min; + t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med; + + pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min; + pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med; + + slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); + slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + + fan_table.TempMin = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100); + fan_table.TempMed = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100); + fan_table.TempMax = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100); + + fan_table.Slope1 = cpu_to_be16(slope1); + fan_table.Slope2 = cpu_to_be16(slope2); + + fan_table.FdoMin = cpu_to_be16(fdo_min); + + fan_table.HystDown = cpu_to_be16(rdev->pm.dpm.fan.t_hyst); + + fan_table.HystUp = cpu_to_be16(1); + + fan_table.HystSlope = cpu_to_be16(1); + + fan_table.TempRespLim = cpu_to_be16(5); + + reference_clock = radeon_get_xclk(rdev); + + fan_table.RefreshPeriod = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay * + reference_clock) / 1600); + + fan_table.FdoMax = cpu_to_be16((u16)duty100); + + tmp = (RREG32_SMC(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT; + fan_table.TempSrc = (uint8_t)tmp; + + ret = ci_copy_bytes_to_smc(rdev, + pi->fan_table_start, + (u8 *)(&fan_table), + sizeof(fan_table), + pi->sram_end); + + if (ret) { + DRM_ERROR("Failed to load fan table to the SMC."); + rdev->pm.dpm.fan.ucode_fan_control = false; + } + + return 0; +} + +static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + PPSMC_Result ret; + + if (pi->caps_od_fuzzy_fan_control_support) { + ret = ci_send_msg_to_smc_with_parameter(rdev, + PPSMC_StartFanControl, + FAN_CONTROL_FUZZY); + if (ret != PPSMC_Result_OK) + return -EINVAL; + ret = ci_send_msg_to_smc_with_parameter(rdev, + PPSMC_MSG_SetFanPwmMax, + rdev->pm.dpm.fan.default_max_fan_pwm); + if (ret != PPSMC_Result_OK) + return -EINVAL; + } else { + ret = ci_send_msg_to_smc_with_parameter(rdev, + PPSMC_StartFanControl, + FAN_CONTROL_TABLE); + if (ret != PPSMC_Result_OK) + return -EINVAL; + } return 0; } +#if 0 +static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) +{ + PPSMC_Result ret; + + ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl); + if (ret == PPSMC_Result_OK) + return 0; + else + return -EINVAL; +} + +static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed) +{ + u32 duty, duty100; + u64 tmp64; + + if (rdev->pm.no_fan) + return -ENOENT; + + duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + duty = (RREG32_SMC(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; + + if (duty100 == 0) + return -EINVAL; + + tmp64 = (u64)duty * 100; + do_div(tmp64, duty100); + *speed = (u32)tmp64; + + if (*speed > 100) + *speed = 100; + + return 0; +} + +static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed) +{ + u32 tmp; + u32 duty, duty100; + u64 tmp64; + + if (rdev->pm.no_fan) + return -ENOENT; + + if (speed > 100) + return -EINVAL; + + if (rdev->pm.dpm.fan.ucode_fan_control) + ci_fan_ctrl_stop_smc_fan_control(rdev); + + duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; + + if (duty100 == 0) + return -EINVAL; + + tmp64 = (u64)speed * duty100; + do_div(tmp64, 100); + duty = (u32)tmp64; + + tmp = RREG32_SMC(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK; + tmp |= FDO_STATIC_DUTY(duty); + WREG32_SMC(CG_FDO_CTRL0, tmp); + + ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + + return 0; +} + +static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, + u32 *speed) +{ + u32 tach_period; + u32 xclk = radeon_get_xclk(rdev); + + if (rdev->pm.no_fan) + return -ENOENT; + + if (rdev->pm.fan_pulses_per_revolution == 0) + return -ENOENT; + + tach_period = (RREG32_SMC(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT; + if (tach_period == 0) + return -ENOENT; + + *speed = 60 * xclk * 10000 / tach_period; + + return 0; +} + +static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, + u32 speed) +{ + u32 tach_period, tmp; + u32 xclk = radeon_get_xclk(rdev); + + if (rdev->pm.no_fan) + return -ENOENT; + + if (rdev->pm.fan_pulses_per_revolution == 0) + return -ENOENT; + + if ((speed < rdev->pm.fan_min_rpm) || + (speed > rdev->pm.fan_max_rpm)) + return -EINVAL; + + if (rdev->pm.dpm.fan.ucode_fan_control) + ci_fan_ctrl_stop_smc_fan_control(rdev); + + tach_period = 60 * xclk * 10000 / (8 * speed); + tmp = RREG32_SMC(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK; + tmp |= TARGET_PERIOD(tach_period); + WREG32_SMC(CG_TACH_CTRL, tmp); + + ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + + return 0; +} +#endif + +static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + u32 tmp; + + if (!pi->fan_ctrl_is_in_default_mode) { + tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; + tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode); + WREG32_SMC(CG_FDO_CTRL2, tmp); + + tmp = RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK; + tmp |= TMIN(pi->t_min); + WREG32_SMC(CG_FDO_CTRL2, tmp); + pi->fan_ctrl_is_in_default_mode = true; + } +} + +static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev) +{ + if (rdev->pm.dpm.fan.ucode_fan_control) { + ci_fan_ctrl_start_smc_fan_control(rdev); + ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); + } +} + +static void ci_thermal_initialize(struct radeon_device *rdev) +{ + u32 tmp; + + if (rdev->pm.fan_pulses_per_revolution) { + tmp = RREG32_SMC(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK; + tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1); + WREG32_SMC(CG_TACH_CTRL, tmp); + } + + tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK; + tmp |= TACH_PWM_RESP_RATE(0x28); + WREG32_SMC(CG_FDO_CTRL2, tmp); +} + +static int ci_thermal_start_thermal_controller(struct radeon_device *rdev) +{ + int ret; + + ci_thermal_initialize(rdev); + ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + ret = ci_thermal_enable_alert(rdev, true); + if (ret) + return ret; + if (rdev->pm.dpm.fan.ucode_fan_control) { + ret = ci_thermal_setup_fan_table(rdev); + if (ret) + return ret; + ci_thermal_start_smc_fan_control(rdev); + } + + return 0; +} + +static void ci_thermal_stop_thermal_controller(struct radeon_device *rdev) +{ + if (!rdev->pm.no_fan) + ci_fan_ctrl_set_default_mode(rdev); +} + #if 0 static int ci_read_smc_soft_register(struct radeon_device *rdev, u16 reg_offset, u32 *value) @@ -4841,6 +5177,8 @@ int ci_dpm_enable(struct radeon_device *rdev) ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); + ci_thermal_start_thermal_controller(rdev); + ci_update_current_ps(rdev, boot_ps); return 0; @@ -4886,6 +5224,8 @@ void ci_dpm_disable(struct radeon_device *rdev) if (!ci_is_smc_running(rdev)) return; + ci_thermal_stop_thermal_controller(rdev); + if (pi->thermal_protection) ci_enable_thermal_protection(rdev, false); ci_enable_power_containment(rdev, false); @@ -5473,6 +5813,9 @@ int ci_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; + pi->fan_ctrl_is_in_default_mode = true; + rdev->pm.dpm.fan.ucode_fan_control = false; + return 0; } diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index 615cb2cacf2c..bb19fbf3ab8a 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h @@ -266,6 +266,7 @@ struct ci_power_info { bool caps_automatic_dc_transition; bool caps_sclk_throttle_low_notification; bool caps_dynamic_ac_timing; + bool caps_od_fuzzy_fan_control_support; /* flags */ bool thermal_protection; bool pcie_performance_request; @@ -287,6 +288,10 @@ struct ci_power_info { struct ci_ps current_ps; struct radeon_ps requested_rps; struct ci_ps requested_ps; + /* fan control */ + bool fan_ctrl_is_in_default_mode; + u32 t_min; + u32 fan_ctrl_default_mode; }; #define CISLANDS_VOLTAGE_CONTROL_NONE 0x0 diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 068cbb019326..e4e88ca8b82e 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -186,7 +186,10 @@ #define DIG_THERM_DPM(x) ((x) << 14) #define DIG_THERM_DPM_MASK 0x003FC000 #define DIG_THERM_DPM_SHIFT 14 - +#define CG_THERMAL_STATUS 0xC0300008 +#define FDO_PWM_DUTY(x) ((x) << 9) +#define FDO_PWM_DUTY_MASK (0xff << 9) +#define FDO_PWM_DUTY_SHIFT 9 #define CG_THERMAL_INT 0xC030000C #define CI_DIG_THERM_INTH(x) ((x) << 8) #define CI_DIG_THERM_INTH_MASK 0x0000FF00 @@ -196,7 +199,10 @@ #define CI_DIG_THERM_INTL_SHIFT 16 #define THERM_INT_MASK_HIGH (1 << 24) #define THERM_INT_MASK_LOW (1 << 25) - +#define CG_MULT_THERMAL_CTRL 0xC0300010 +#define TEMP_SEL(x) ((x) << 20) +#define TEMP_SEL_MASK (0xff << 20) +#define TEMP_SEL_SHIFT 20 #define CG_MULT_THERMAL_STATUS 0xC0300014 #define ASIC_MAX_TEMP(x) ((x) << 0) #define ASIC_MAX_TEMP_MASK 0x000001ff @@ -205,6 +211,36 @@ #define CTF_TEMP_MASK 0x0003fe00 #define CTF_TEMP_SHIFT 9 +#define CG_FDO_CTRL0 0xC0300064 +#define FDO_STATIC_DUTY(x) ((x) << 0) +#define FDO_STATIC_DUTY_MASK 0x0000000F +#define FDO_STATIC_DUTY_SHIFT 0 +#define CG_FDO_CTRL1 0xC0300068 +#define FMAX_DUTY100(x) ((x) << 0) +#define FMAX_DUTY100_MASK 0x0000000F +#define FMAX_DUTY100_SHIFT 0 +#define CG_FDO_CTRL2 0xC030006C +#define TMIN(x) ((x) << 0) +#define TMIN_MASK 0x0000000F +#define TMIN_SHIFT 0 +#define FDO_PWM_MODE(x) ((x) << 11) +#define FDO_PWM_MODE_MASK (3 << 11) +#define FDO_PWM_MODE_SHIFT 11 +#define TACH_PWM_RESP_RATE(x) ((x) << 25) +#define TACH_PWM_RESP_RATE_MASK (0x7f << 25) +#define TACH_PWM_RESP_RATE_SHIFT 25 +#define CG_TACH_CTRL 0xC0300070 +# define EDGE_PER_REV(x) ((x) << 0) +# define EDGE_PER_REV_MASK (0x7 << 0) +# define EDGE_PER_REV_SHIFT 0 +# define TARGET_PERIOD(x) ((x) << 3) +# define TARGET_PERIOD_MASK 0xfffffff8 +# define TARGET_PERIOD_SHIFT 3 +#define CG_TACH_STATUS 0xC0300074 +# define TACH_PERIOD(x) ((x) << 0) +# define TACH_PERIOD_MASK 0xffffffff +# define TACH_PERIOD_SHIFT 0 + #define CG_ECLK_CNTL 0xC05000AC # define ECLK_DIVIDER_MASK 0x7f # define ECLK_DIR_CNTL_EN (1 << 8) diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h index 0c4eaa60b6ca..ff698b05bdf5 100644 --- a/drivers/gpu/drm/radeon/ppsmc.h +++ b/drivers/gpu/drm/radeon/ppsmc.h @@ -59,6 +59,11 @@ #define FDO_MODE_HARDWARE 0 #define FDO_MODE_PIECE_WISE_LINEAR 1 +enum FAN_CONTROL { + FAN_CONTROL_FUZZY, + FAN_CONTROL_TABLE +}; + #define PPSMC_Result_OK ((uint8_t)0x01) #define PPSMC_Result_Failed ((uint8_t)0xFF) @@ -155,6 +160,7 @@ typedef uint8_t PPSMC_Result; #define PPSMC_MSG_MASTER_DeepSleep_ON ((uint16_t) 0x18F) #define PPSMC_MSG_MASTER_DeepSleep_OFF ((uint16_t) 0x190) #define PPSMC_MSG_Remove_DC_Clamp ((uint16_t) 0x191) +#define PPSMC_MSG_SetFanPwmMax ((uint16_t) 0x19A) #define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200) #define PPSMC_MSG_API_GetMclkFrequency ((uint16_t) 0x201) diff --git a/drivers/gpu/drm/radeon/pptable.h b/drivers/gpu/drm/radeon/pptable.h index 2d532996c697..4c2eec49dadc 100644 --- a/drivers/gpu/drm/radeon/pptable.h +++ b/drivers/gpu/drm/radeon/pptable.h @@ -96,6 +96,14 @@ typedef struct _ATOM_PPLIB_FANTABLE2 USHORT usTMax; // The max temperature } ATOM_PPLIB_FANTABLE2; +typedef struct _ATOM_PPLIB_FANTABLE3 +{ + ATOM_PPLIB_FANTABLE2 basicTable2; + UCHAR ucFanControlMode; + USHORT usFanPWMMax; + USHORT usFanOutputSensitivity; +} ATOM_PPLIB_FANTABLE3; + typedef struct _ATOM_PPLIB_EXTENDEDHEADER { USHORT usSize; diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index f6309bd23e01..76c6a17eeb2d 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -811,6 +811,7 @@ union power_info { union fan_info { struct _ATOM_PPLIB_FANTABLE fan; struct _ATOM_PPLIB_FANTABLE2 fan2; + struct _ATOM_PPLIB_FANTABLE3 fan3; }; static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table, @@ -900,6 +901,14 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) else rdev->pm.dpm.fan.t_max = 10900; rdev->pm.dpm.fan.cycle_delay = 100000; + if (fan_info->fan.ucFanTableFormat >= 3) { + rdev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode; + rdev->pm.dpm.fan.default_max_fan_pwm = + le16_to_cpu(fan_info->fan3.usFanPWMMax); + rdev->pm.dpm.fan.default_fan_output_sensitivity = 4836; + rdev->pm.dpm.fan.fan_output_sensitivity = + le16_to_cpu(fan_info->fan3.usFanOutputSensitivity); + } rdev->pm.dpm.fan.ucode_fan_control = true; } } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1f61ff089c9e..5aabbe0a43f5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1494,6 +1494,10 @@ struct radeon_dpm_fan { u8 t_hyst; u32 cycle_delay; u16 t_max; + u8 control_mode; + u16 default_max_fan_pwm; + u16 default_fan_output_sensitivity; + u16 fan_output_sensitivity; bool ucode_fan_control; }; diff --git a/drivers/gpu/drm/radeon/smu7_discrete.h b/drivers/gpu/drm/radeon/smu7_discrete.h index 82f70c90a9ee..0b0b404ff091 100644 --- a/drivers/gpu/drm/radeon/smu7_discrete.h +++ b/drivers/gpu/drm/radeon/smu7_discrete.h @@ -431,6 +431,31 @@ struct SMU7_Discrete_MCRegisters typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters; +struct SMU7_Discrete_FanTable +{ + uint16_t FdoMode; + int16_t TempMin; + int16_t TempMed; + int16_t TempMax; + int16_t Slope1; + int16_t Slope2; + int16_t FdoMin; + int16_t HystUp; + int16_t HystDown; + int16_t HystSlope; + int16_t TempRespLim; + int16_t TempCurr; + int16_t SlopeCurr; + int16_t PwmCurr; + uint32_t RefreshPeriod; + int16_t FdoMax; + uint8_t TempSrc; + int8_t Padding; +}; + +typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable; + + struct SMU7_Discrete_PmFuses { // dw0-dw1 uint8_t BapmVddCVidHiSidd[8]; @@ -462,7 +487,10 @@ struct SMU7_Discrete_PmFuses { uint8_t BapmVddCVidHiSidd2[8]; // dw11-dw12 - uint32_t Reserved6[2]; + int16_t FuzzyFan_ErrorSetDelta; + int16_t FuzzyFan_ErrorRateSetDelta; + int16_t FuzzyFan_PwmSetDelta; + uint16_t CalcMeasPowerBlend; // dw13-dw16 uint8_t GnbLPML[16]; -- GitLab From 0e4ed1c1908e48ee66d9e955ce824bc1f34d103e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 15 Sep 2014 02:15:04 -0400 Subject: [PATCH 5566/9457] drm/radeon/dpm: add thermal dpm support for CI Not currently used. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/radeon/ci_dpm.h | 1 + drivers/gpu/drm/radeon/ppsmc.h | 3 +++ 3 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 4581d6cf90e8..83121403ce3b 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -714,6 +714,25 @@ static int ci_enable_smc_cac(struct radeon_device *rdev, bool enable) return ret; } +static int ci_enable_thermal_based_sclk_dpm(struct radeon_device *rdev, + bool enable) +{ + struct ci_power_info *pi = ci_get_pi(rdev); + PPSMC_Result smc_result = PPSMC_Result_OK; + + if (pi->thermal_sclk_dpm_enabled) { + if (enable) + smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_ENABLE_THERMAL_DPM); + else + smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_DISABLE_THERMAL_DPM); + } + + if (smc_result == PPSMC_Result_OK) + return 0; + else + return -EINVAL; +} + static int ci_power_control_set_level(struct radeon_device *rdev) { struct ci_power_info *pi = ci_get_pi(rdev); @@ -5177,6 +5196,12 @@ int ci_dpm_enable(struct radeon_device *rdev) ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); + ret = ci_enable_thermal_based_sclk_dpm(rdev, true); + if (ret) { + DRM_ERROR("ci_enable_thermal_based_sclk_dpm failed\n"); + return ret; + } + ci_thermal_start_thermal_controller(rdev); ci_update_current_ps(rdev, boot_ps); @@ -5240,6 +5265,7 @@ void ci_dpm_disable(struct radeon_device *rdev) ci_reset_to_default(rdev); ci_dpm_stop_smc(rdev); ci_force_switch_to_arb_f0(rdev); + ci_enable_thermal_based_sclk_dpm(rdev, false); ci_update_current_ps(rdev, boot_ps); } @@ -5639,6 +5665,7 @@ int ci_dpm_init(struct radeon_device *rdev) pi->sclk_dpm_key_disabled = 0; pi->mclk_dpm_key_disabled = 0; pi->pcie_dpm_key_disabled = 0; + pi->thermal_sclk_dpm_enabled = 0; /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */ if ((rdev->pdev->device == 0x6658) && diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index bb19fbf3ab8a..84e3d3bcf9f3 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h @@ -239,6 +239,7 @@ struct ci_power_info { u32 sclk_dpm_key_disabled; u32 mclk_dpm_key_disabled; u32 pcie_dpm_key_disabled; + u32 thermal_sclk_dpm_enabled; struct ci_pcie_perf_range pcie_gen_performance; struct ci_pcie_perf_range pcie_lane_performance; struct ci_pcie_perf_range pcie_gen_powersaving; diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h index ff698b05bdf5..7e5724a12f8b 100644 --- a/drivers/gpu/drm/radeon/ppsmc.h +++ b/drivers/gpu/drm/radeon/ppsmc.h @@ -162,6 +162,9 @@ typedef uint8_t PPSMC_Result; #define PPSMC_MSG_Remove_DC_Clamp ((uint16_t) 0x191) #define PPSMC_MSG_SetFanPwmMax ((uint16_t) 0x19A) +#define PPSMC_MSG_ENABLE_THERMAL_DPM ((uint16_t) 0x19C) +#define PPSMC_MSG_DISABLE_THERMAL_DPM ((uint16_t) 0x19D) + #define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200) #define PPSMC_MSG_API_GetMclkFrequency ((uint16_t) 0x201) -- GitLab From 66648b81ce6a1ea713e299d2074d81d36cff4c94 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 17 Nov 2014 11:52:48 -0500 Subject: [PATCH 5567/9457] drm/radeon: fix PCC debugging message for CI DPM Add missing newline and print the bad gpio shift. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 83121403ce3b..c9963b589336 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5773,7 +5773,7 @@ int ci_dpm_init(struct radeon_device *rdev) tmp |= DPM_ENABLED; break; default: - DRM_ERROR("Invalid PCC GPIO!"); + DRM_ERROR("Invalid PCC GPIO: %u!\n", gpio.shift); break; } WREG32_SMC(CNB_PWRMGT_CNTL, tmp); -- GitLab From f281d0a37c423cb4cc8ef91ba7136848744c955f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Nov 2014 14:32:14 -0500 Subject: [PATCH 5568/9457] drm/radeon/ci: apply disp voltage changes before clk changes Apply voltage changes for displays before changing clocks. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index c9963b589336..e7816281f0d7 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -3752,6 +3752,8 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) struct ci_power_info *pi = ci_get_pi(rdev); PPSMC_Result result; + ci_apply_disp_minimum_voltage_request(rdev); + if (!pi->sclk_dpm_key_disabled) { if (pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { result = ci_send_msg_to_smc_with_parameter(rdev, @@ -3782,8 +3784,6 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) } } - ci_apply_disp_minimum_voltage_request(rdev); - return 0; } -- GitLab From e745c3c9aa5e30ae94a1be04a1d2f326fb213a56 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Nov 2014 14:36:59 -0500 Subject: [PATCH 5569/9457] drm/radeon/ci: use different smc command for pcie dpm Use unforce levels rather than enable mask instruction. This is the preferred method. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index e7816281f0d7..73f8c4b5bc9c 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -3773,7 +3773,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) return -EINVAL; } } - +#if 0 if (!pi->pcie_dpm_key_disabled) { if (pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { result = ci_send_msg_to_smc_with_parameter(rdev, @@ -3783,7 +3783,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) return -EINVAL; } } - +#endif return 0; } @@ -4247,6 +4247,14 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, } } } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { + if (!pi->pcie_dpm_key_disabled) { + PPSMC_Result smc_result; + + smc_result = ci_send_msg_to_smc(rdev, + PPSMC_MSG_PCIeDPM_UnForceLevel); + if (smc_result != PPSMC_Result_OK) + return -EINVAL; + } ret = ci_upload_dpm_level_enable_mask(rdev); if (ret) return ret; -- GitLab From 7f6233ca8769a92cf4f23a0bc18bf241e9c50606 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Nov 2014 14:40:26 -0500 Subject: [PATCH 5570/9457] drm/radeon/ci: force pcie level before sclk and mclk Preferred ordering. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 73f8c4b5bc9c..630434cba22d 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -4143,57 +4143,57 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, int ret; if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { - if ((!pi->sclk_dpm_key_disabled) && - pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { + if ((!pi->pcie_dpm_key_disabled) && + pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { levels = 0; - tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask; + tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask; while (tmp >>= 1) levels++; if (levels) { - ret = ci_dpm_force_state_sclk(rdev, levels); + ret = ci_dpm_force_state_pcie(rdev, level); if (ret) return ret; for (i = 0; i < rdev->usec_timeout; i++) { - tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & - CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT; + tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) & + CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT; if (tmp == levels) break; udelay(1); } } } - if ((!pi->mclk_dpm_key_disabled) && - pi->dpm_level_enable_mask.mclk_dpm_enable_mask) { + if ((!pi->sclk_dpm_key_disabled) && + pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { levels = 0; - tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask; + tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask; while (tmp >>= 1) levels++; if (levels) { - ret = ci_dpm_force_state_mclk(rdev, levels); + ret = ci_dpm_force_state_sclk(rdev, levels); if (ret) return ret; for (i = 0; i < rdev->usec_timeout; i++) { tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & - CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT; + CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT; if (tmp == levels) break; udelay(1); } } } - if ((!pi->pcie_dpm_key_disabled) && - pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { + if ((!pi->mclk_dpm_key_disabled) && + pi->dpm_level_enable_mask.mclk_dpm_enable_mask) { levels = 0; - tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask; + tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask; while (tmp >>= 1) levels++; if (levels) { - ret = ci_dpm_force_state_pcie(rdev, level); + ret = ci_dpm_force_state_mclk(rdev, levels); if (ret) return ret; for (i = 0; i < rdev->usec_timeout; i++) { - tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) & - CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT; + tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & + CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT; if (tmp == levels) break; udelay(1); -- GitLab From d967be9b80a5aa3ba228a9c2d3fea91ae99e4a07 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Nov 2014 15:07:33 -0500 Subject: [PATCH 5571/9457] drm/radeon/ci: disable needless sclk changes The current code always reprogrammed the sclk levels, but we don't currently handle disp sclk requirements so just skip it. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 630434cba22d..3f898d020ae6 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -3809,7 +3809,7 @@ static void ci_find_dpm_states_clocks_in_dpm_table(struct radeon_device *rdev, pi->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; } else { /* XXX check display min clock requirements */ - if (0 != CISLAND_MINIMUM_ENGINE_CLOCK) + if (CISLAND_MINIMUM_ENGINE_CLOCK != CISLAND_MINIMUM_ENGINE_CLOCK) pi->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK; } -- GitLab From faffaf620f32c6e907d06570f8f75845ecb1349f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:19 +0100 Subject: [PATCH 5572/9457] drm/radeon: rework vm_flush parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use ring structure instead of index and provide vm_id and pd_addr separately. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 23 ++++++++++------------- drivers/gpu/drm/radeon/cik_sdma.c | 22 +++++++++------------- drivers/gpu/drm/radeon/ni.c | 14 +++++--------- drivers/gpu/drm/radeon/ni_dma.c | 14 +++++--------- drivers/gpu/drm/radeon/radeon.h | 5 +++-- drivers/gpu/drm/radeon/radeon_asic.h | 18 ++++++++++++------ drivers/gpu/drm/radeon/radeon_vm.c | 3 ++- drivers/gpu/drm/radeon/si.c | 18 +++++++----------- drivers/gpu/drm/radeon/si_dma.c | 19 ++++++++----------- 9 files changed, 61 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index cef4cb7e5438..3dc2be07dcde 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5982,26 +5982,23 @@ static void cik_vm_decode_fault(struct radeon_device *rdev, * Update the page table base and flush the VM TLB * using the CP (CIK). */ -void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) +void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) { - struct radeon_ring *ring = &rdev->ring[ridx]; - int usepfp = (ridx == RADEON_RING_TYPE_GFX_INDEX); - - if (vm == NULL) - return; + int usepfp = (ring->idx == RADEON_RING_TYPE_GFX_INDEX); radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | WRITE_DATA_DST_SEL(0))); - if (vm->id < 8) { + if (vm_id < 8) { radeon_ring_write(ring, - (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); + (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); } else { radeon_ring_write(ring, - (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); + (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); } radeon_ring_write(ring, 0); - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, pd_addr >> 12); /* update SH_MEM_* regs */ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); @@ -6009,7 +6006,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); radeon_ring_write(ring, 0); - radeon_ring_write(ring, VMID(vm->id)); + radeon_ring_write(ring, VMID(vm_id)); radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | @@ -6030,7 +6027,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) radeon_ring_write(ring, VMID(0)); /* HDP flush */ - cik_hdp_flush_cp_ring_emit(rdev, ridx); + cik_hdp_flush_cp_ring_emit(rdev, ring->idx); /* bits 0-15 are the VM contexts0-15 */ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); @@ -6038,7 +6035,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 0); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); /* compute doesn't have PFP */ if (usepfp) { diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 4e8432d07f15..7470a2ee83bd 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -901,25 +901,21 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) * Update the page table base and flush the VM TLB * using sDMA (CIK). */ -void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) +void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) { - struct radeon_ring *ring = &rdev->ring[ridx]; - - if (vm == NULL) - return; - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); - if (vm->id < 8) { - radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); + if (vm_id < 8) { + radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); } else { - radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); + radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); } - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, pd_addr >> 12); /* update SH_MEM_* regs */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); - radeon_ring_write(ring, VMID(vm->id)); + radeon_ring_write(ring, VMID(vm_id)); radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); radeon_ring_write(ring, SH_MEM_BASES >> 2); @@ -942,11 +938,11 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm radeon_ring_write(ring, VMID(0)); /* flush HDP */ - cik_sdma_hdp_flush_ring_emit(rdev, ridx); + cik_sdma_hdp_flush_ring_emit(rdev, ring->idx); /* flush TLB */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3faee58946dd..bee432d3dd30 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2502,15 +2502,11 @@ void cayman_vm_decode_fault(struct radeon_device *rdev, * Update the page table base and flush the VM TLB * using the CP (cayman-si). */ -void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) +void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) { - struct radeon_ring *ring = &rdev->ring[ridx]; - - if (vm == NULL) - return; - - radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0)); + radeon_ring_write(ring, pd_addr >> 12); /* flush hdp cache */ radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); @@ -2518,7 +2514,7 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) /* bits 0-7 are the VM contexts0-7 */ radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index f26f0a9fb522..5a72404c9d5e 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c @@ -446,16 +446,12 @@ void cayman_dma_vm_pad_ib(struct radeon_ib *ib) ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); } -void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) +void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) { - struct radeon_ring *ring = &rdev->ring[ridx]; - - if (vm == NULL) - return; - radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); - radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2)); + radeon_ring_write(ring, pd_addr >> 12); /* flush hdp cache */ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); @@ -465,6 +461,6 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm /* bits 0-7 are the VM contexts0-7 */ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5aabbe0a43f5..39f7716343a4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1798,7 +1798,8 @@ struct radeon_asic_ring { void (*hdp_flush)(struct radeon_device *rdev, struct radeon_ring *ring); bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, struct radeon_semaphore *semaphore, bool emit_wait); - void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + void (*vm_flush)(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); /* testing functions */ int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); @@ -2850,7 +2851,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_execute((rdev), (ib)) #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_parse((rdev), (ib)) #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)]->is_lockup((rdev), (cp)) -#define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)]->vm_flush((rdev), (r), (vm)) +#define radeon_ring_vm_flush(rdev, r, vm_id, pd_addr) (rdev)->asic->ring[(r)->idx]->vm_flush((rdev), (r), (vm_id), (pd_addr)) #define radeon_ring_get_rptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_rptr((rdev), (r)) #define radeon_ring_get_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_wptr((rdev), (r)) #define radeon_ring_set_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->set_wptr((rdev), (r)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d8ace5b28a5b..2a45d548d5ec 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -599,7 +599,8 @@ int cayman_asic_reset(struct radeon_device *rdev); void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cayman_vm_init(struct radeon_device *rdev); void cayman_vm_fini(struct radeon_device *rdev); -void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); @@ -624,7 +625,8 @@ void cayman_dma_vm_set_pages(struct radeon_device *rdev, uint32_t incr, uint32_t flags); void cayman_dma_vm_pad_ib(struct radeon_ib *ib); -void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); u32 cayman_gfx_get_rptr(struct radeon_device *rdev, struct radeon_ring *ring); @@ -699,7 +701,8 @@ int si_irq_set(struct radeon_device *rdev); int si_irq_process(struct radeon_device *rdev); int si_vm_init(struct radeon_device *rdev); void si_vm_fini(struct radeon_device *rdev); -void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); struct radeon_fence *si_copy_dma(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, @@ -721,7 +724,8 @@ void si_dma_vm_set_pages(struct radeon_device *rdev, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags); -void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); u32 si_get_xclk(struct radeon_device *rdev); uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); @@ -793,7 +797,8 @@ int cik_irq_set(struct radeon_device *rdev); int cik_irq_process(struct radeon_device *rdev); int cik_vm_init(struct radeon_device *rdev); void cik_vm_fini(struct radeon_device *rdev); -void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); void cik_sdma_vm_copy_pages(struct radeon_device *rdev, struct radeon_ib *ib, @@ -811,7 +816,8 @@ void cik_sdma_vm_set_pages(struct radeon_device *rdev, uint32_t incr, uint32_t flags); void cik_sdma_vm_pad_ib(struct radeon_ib *ib); -void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr); int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); u32 cik_gfx_get_rptr(struct radeon_device *rdev, struct radeon_ring *ring); diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index dfde266529e2..9d0f87be6fa0 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -243,7 +243,8 @@ void radeon_vm_flush(struct radeon_device *rdev, if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) { trace_radeon_vm_flush(pd_addr, ring, vm->id); vm->pd_gpu_addr = pd_addr; - radeon_ring_vm_flush(rdev, ring, vm); + radeon_ring_vm_flush(rdev, &rdev->ring[ring], + vm->id, vm->pd_gpu_addr); } } diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index eeea5b6a1775..e91968b04154 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5020,27 +5020,23 @@ static void si_vm_decode_fault(struct radeon_device *rdev, block, mc_id); } -void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) +void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) { - struct radeon_ring *ring = &rdev->ring[ridx]; - - if (vm == NULL) - return; - /* write new base address */ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | WRITE_DATA_DST_SEL(0))); - if (vm->id < 8) { + if (vm_id < 8) { radeon_ring_write(ring, - (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); + (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); } else { radeon_ring_write(ring, - (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); + (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); } radeon_ring_write(ring, 0); - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, pd_addr >> 12); /* flush hdp cache */ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); @@ -5056,7 +5052,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) WRITE_DATA_DST_SEL(0))); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 0); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index b58f12b762d7..e8bc0a516b57 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c @@ -185,20 +185,17 @@ void si_dma_vm_set_pages(struct radeon_device *rdev, } } -void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) -{ - struct radeon_ring *ring = &rdev->ring[ridx]; - - if (vm == NULL) - return; +void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned vm_id, uint64_t pd_addr) +{ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); - if (vm->id < 8) { - radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); + if (vm_id < 8) { + radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2)); } else { - radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2)); + radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2)); } - radeon_ring_write(ring, vm->pd_gpu_addr >> 12); + radeon_ring_write(ring, pd_addr >> 12); /* flush hdp cache */ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); @@ -208,7 +205,7 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) /* bits 0-7 are the VM contexts0-7 */ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); - radeon_ring_write(ring, 1 << vm->id); + radeon_ring_write(ring, 1 << vm_id); } /** -- GitLab From 85761f605a21ef7f3feda9d272565f97ecf1aa56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:20 +0100 Subject: [PATCH 5573/9457] drm/radeon: stop re-reserving the BO in radeon_vm_bo_set_addr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That's useless when all callers drop the reservation immediately after calling the function. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_kms.c | 2 -- drivers/gpu/drm/radeon/radeon_vm.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c194497aa586..f752c7f56015 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -601,6 +601,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, if (bo_va->it.start) { args->operation = RADEON_VA_RESULT_VA_EXIST; args->offset = bo_va->it.start * RADEON_GPU_PAGE_SIZE; + radeon_bo_unreserve(rbo); goto out; } r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags); @@ -616,7 +617,6 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, args->operation = RADEON_VA_RESULT_ERROR; } out: - radeon_bo_unreserve(rbo); drm_gem_object_unreference_unlocked(gobj); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 6eb561d33eba..f4dd26ae33e5 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -628,8 +628,6 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) RADEON_VA_IB_OFFSET, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); - - radeon_bo_unreserve(rdev->ring_tmp_bo.bo); if (r) { radeon_vm_fini(rdev, vm); kfree(fpriv); diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 9d0f87be6fa0..db0ed3af8e82 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -450,7 +450,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, * Validate and set the offset requested within the vm address space. * Returns 0 for success, error for failure. * - * Object has to be reserved! + * Object has to be reserved and gets unreserved by this function! */ int radeon_vm_bo_set_addr(struct radeon_device *rdev, struct radeon_bo_va *bo_va, @@ -576,7 +576,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, } mutex_unlock(&vm->mutex); - return radeon_bo_reserve(bo_va->bo, false); + return 0; } /** -- GitLab From e0602c35fe3bcbe5fe9179be78882b3101780781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:21 +0100 Subject: [PATCH 5574/9457] drm/radeon: remove unnecessary VM syncs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PD/PTs reservation object now contains everything needed. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_vm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index db0ed3af8e82..d8c49ad34dee 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -701,7 +701,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, radeon_asic_vm_pad_ib(rdev, &ib); radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); - radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); WARN_ON(ib.length_dw > ndw); r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { @@ -969,7 +968,6 @@ int radeon_vm_bo_update(struct radeon_device *rdev, radeon_asic_vm_pad_ib(rdev, &ib); WARN_ON(ib.length_dw > ndw); - radeon_semaphore_sync_fence(ib.semaphore, vm->fence); r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { radeon_ib_free(rdev, &ib); -- GitLab From 975700d2cc84408efa9b2360e38b1ab95368556f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:22 +0100 Subject: [PATCH 5575/9457] drm/radeon: split semaphore and sync object handling v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we just allocated space for four hardware semaphores in each software semaphore object. Make software semaphore objects represent only one hardware semaphore address again by splitting the sync code into it's own object. v2: fix typo in comment Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/Makefile | 3 +- drivers/gpu/drm/radeon/cik.c | 18 +- drivers/gpu/drm/radeon/cik_sdma.c | 18 +- drivers/gpu/drm/radeon/evergreen_dma.c | 18 +- drivers/gpu/drm/radeon/r600.c | 18 +- drivers/gpu/drm/radeon/r600_dma.c | 18 +- drivers/gpu/drm/radeon/radeon.h | 42 +++-- drivers/gpu/drm/radeon/radeon_cs.c | 8 +- drivers/gpu/drm/radeon/radeon_ib.c | 13 +- drivers/gpu/drm/radeon/radeon_semaphore.c | 154 +--------------- drivers/gpu/drm/radeon/radeon_sync.c | 213 ++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_vm.c | 4 +- drivers/gpu/drm/radeon/rv770_dma.c | 18 +- drivers/gpu/drm/radeon/si_dma.c | 18 +- 14 files changed, 303 insertions(+), 260 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_sync.c diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index bad6caa0a727..12bc21219a0e 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -80,7 +80,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ - ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ + radeon_sync.o # add async DMA block radeon-y += \ diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 3dc2be07dcde..755923bc6786 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3994,31 +3994,27 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.blit_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_bytes, cur_size_in_bytes, control; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_bytes = size_in_bytes; @@ -4042,12 +4038,12 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 7470a2ee83bd..604e2e770951 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -541,31 +541,27 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.dma_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_bytes, cur_size_in_bytes; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_bytes = size_in_bytes; @@ -586,12 +582,12 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index 66bcfadeedd1..96535aa8659c 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c @@ -110,31 +110,27 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.dma_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_dw, cur_size_in_dw; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_dw = size_in_dw; @@ -153,12 +149,12 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 56b02927cd3d..ef5d6066fa5b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2889,31 +2889,27 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.blit_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_bytes, cur_size_in_bytes, tmp; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); @@ -2942,12 +2938,12 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index aabc343b9a8f..3a58b8073f49 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c @@ -441,31 +441,27 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.dma_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_dw, cur_size_in_dw; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_dw = size_in_dw; @@ -484,12 +480,12 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 39f7716343a4..7cda6d77aeb0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -150,9 +150,6 @@ extern int radeon_backlight; /* number of hw syncs before falling back on blocking */ #define RADEON_NUM_SYNCS 4 -/* number of hw syncs before falling back on blocking */ -#define RADEON_NUM_SYNCS 4 - /* hardcode those limit for now */ #define RADEON_VA_IB_OFFSET (1 << 20) #define RADEON_VA_RESERVED_SIZE (8 << 20) @@ -576,10 +573,9 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, * Semaphores. */ struct radeon_semaphore { - struct radeon_sa_bo *sa_bo; - signed waiters; - uint64_t gpu_addr; - struct radeon_fence *sync_to[RADEON_NUM_RINGS]; + struct radeon_sa_bo *sa_bo; + signed waiters; + uint64_t gpu_addr; }; int radeon_semaphore_create(struct radeon_device *rdev, @@ -588,19 +584,31 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore); bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore); -void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, - struct radeon_fence *fence); -int radeon_semaphore_sync_resv(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - struct reservation_object *resv, - bool shared); -int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - int waiting_ring); void radeon_semaphore_free(struct radeon_device *rdev, struct radeon_semaphore **semaphore, struct radeon_fence *fence); +/* + * Synchronization + */ +struct radeon_sync { + struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; + struct radeon_fence *sync_to[RADEON_NUM_RINGS]; +}; + +void radeon_sync_create(struct radeon_sync *sync); +void radeon_sync_fence(struct radeon_sync *sync, + struct radeon_fence *fence); +int radeon_sync_resv(struct radeon_device *rdev, + struct radeon_sync *sync, + struct reservation_object *resv, + bool shared); +int radeon_sync_rings(struct radeon_device *rdev, + struct radeon_sync *sync, + int waiting_ring); +void radeon_sync_free(struct radeon_device *rdev, struct radeon_sync *sync, + struct radeon_fence *fence); + /* * GART structures, functions & helpers */ @@ -818,7 +826,7 @@ struct radeon_ib { struct radeon_fence *fence; struct radeon_vm *vm; bool is_const_ib; - struct radeon_semaphore *semaphore; + struct radeon_sync sync; }; struct radeon_ring { diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index a3e7aed7e680..30437aa00014 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -260,8 +260,8 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p) continue; resv = p->relocs[i].robj->tbo.resv; - r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, - p->relocs[i].tv.shared); + r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, + p->relocs[i].tv.shared); if (r) break; @@ -285,9 +285,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) INIT_LIST_HEAD(&p->validated); p->idx = 0; p->ib.sa_bo = NULL; - p->ib.semaphore = NULL; p->const_ib.sa_bo = NULL; - p->const_ib.semaphore = NULL; p->chunk_ib_idx = -1; p->chunk_relocs_idx = -1; p->chunk_flags_idx = -1; @@ -582,7 +580,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, DRM_ERROR("Failed to sync rings: %i\n", r); goto out; } - radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); + radeon_sync_fence(&parser->ib.sync, vm->fence); if ((rdev->family >= CHIP_TAHITI) && (parser->chunk_const_ib_idx != -1)) { diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 3f39fcca4d07..56a17046a61f 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c @@ -64,10 +64,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, return r; } - r = radeon_semaphore_create(rdev, &ib->semaphore); - if (r) { - return r; - } + radeon_sync_create(&ib->sync); ib->ring = ring; ib->fence = NULL; @@ -96,7 +93,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, */ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) { - radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); + radeon_sync_free(rdev, &ib->sync, ib->fence); radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); radeon_fence_unref(&ib->fence); } @@ -145,11 +142,11 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, if (ib->vm) { struct radeon_fence *vm_id_fence; vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); - radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence); + radeon_sync_fence(&ib->sync, vm_id_fence); } /* sync with other rings */ - r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); + r = radeon_sync_rings(rdev, &ib->sync, ib->ring); if (r) { dev_err(rdev->dev, "failed to sync rings (%d)\n", r); radeon_ring_unlock_undo(rdev, ring); @@ -161,7 +158,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, if (const_ib) { radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); - radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); + radeon_sync_free(rdev, &const_ib->sync, NULL); } radeon_ring_ib_execute(rdev, ib->ring, ib); r = radeon_fence_emit(rdev, &ib->fence, ib->ring); diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 6deb08f045b7..e6ad54cdfa62 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -34,15 +34,14 @@ int radeon_semaphore_create(struct radeon_device *rdev, struct radeon_semaphore **semaphore) { - uint64_t *cpu_addr; - int i, r; + int r; *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); if (*semaphore == NULL) { return -ENOMEM; } - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, - 8 * RADEON_NUM_SYNCS, 8); + r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, + &(*semaphore)->sa_bo, 8, 8); if (r) { kfree(*semaphore); *semaphore = NULL; @@ -51,12 +50,7 @@ int radeon_semaphore_create(struct radeon_device *rdev, (*semaphore)->waiters = 0; (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); - cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); - for (i = 0; i < RADEON_NUM_SYNCS; ++i) - cpu_addr[i] = 0; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) - (*semaphore)->sync_to[i] = NULL; + *((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; return 0; } @@ -95,146 +89,6 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, return false; } -/** - * radeon_semaphore_sync_fence - use the semaphore to sync to a fence - * - * @semaphore: semaphore object to add fence to - * @fence: fence to sync to - * - * Sync to the fence using this semaphore object - */ -void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, - struct radeon_fence *fence) -{ - struct radeon_fence *other; - - if (!fence) - return; - - other = semaphore->sync_to[fence->ring]; - semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); -} - -/** - * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object - * - * @sema: semaphore object to add fence from reservation object to - * @resv: reservation object with embedded fence - * @shared: true if we should onyl sync to the exclusive fence - * - * Sync to the fence using this semaphore object - */ -int radeon_semaphore_sync_resv(struct radeon_device *rdev, - struct radeon_semaphore *sema, - struct reservation_object *resv, - bool shared) -{ - struct reservation_object_list *flist; - struct fence *f; - struct radeon_fence *fence; - unsigned i; - int r = 0; - - /* always sync to the exclusive fence */ - f = reservation_object_get_excl(resv); - fence = f ? to_radeon_fence(f) : NULL; - if (fence && fence->rdev == rdev) - radeon_semaphore_sync_fence(sema, fence); - else if (f) - r = fence_wait(f, true); - - flist = reservation_object_get_list(resv); - if (shared || !flist || r) - return r; - - for (i = 0; i < flist->shared_count; ++i) { - f = rcu_dereference_protected(flist->shared[i], - reservation_object_held(resv)); - fence = to_radeon_fence(f); - if (fence && fence->rdev == rdev) - radeon_semaphore_sync_fence(sema, fence); - else - r = fence_wait(f, true); - - if (r) - break; - } - return r; -} - -/** - * radeon_semaphore_sync_rings - sync ring to all registered fences - * - * @rdev: radeon_device pointer - * @semaphore: semaphore object to use for sync - * @ring: ring that needs sync - * - * Ensure that all registered fences are signaled before letting - * the ring continue. The caller must hold the ring lock. - */ -int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - int ring) -{ - unsigned count = 0; - int i, r; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - struct radeon_fence *fence = semaphore->sync_to[i]; - - /* check if we really need to sync */ - if (!radeon_fence_need_sync(fence, ring)) - continue; - - /* prevent GPU deadlocks */ - if (!rdev->ring[i].ready) { - dev_err(rdev->dev, "Syncing to a disabled ring!"); - return -EINVAL; - } - - if (++count > RADEON_NUM_SYNCS) { - /* not enough room, wait manually */ - r = radeon_fence_wait(fence, false); - if (r) - return r; - continue; - } - - /* allocate enough space for sync command */ - r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); - if (r) { - return r; - } - - /* emit the signal semaphore */ - if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { - /* signaling wasn't successful wait manually */ - radeon_ring_undo(&rdev->ring[i]); - r = radeon_fence_wait(fence, false); - if (r) - return r; - continue; - } - - /* we assume caller has already allocated space on waiters ring */ - if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { - /* waiting wasn't successful wait manually */ - radeon_ring_undo(&rdev->ring[i]); - r = radeon_fence_wait(fence, false); - if (r) - return r; - continue; - } - - radeon_ring_commit(rdev, &rdev->ring[i], false); - radeon_fence_note_sync(fence, ring); - - semaphore->gpu_addr += 8; - } - - return 0; -} - void radeon_semaphore_free(struct radeon_device *rdev, struct radeon_semaphore **semaphore, struct radeon_fence *fence) diff --git a/drivers/gpu/drm/radeon/radeon_sync.c b/drivers/gpu/drm/radeon/radeon_sync.c new file mode 100644 index 000000000000..ddd88fb28d99 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_sync.c @@ -0,0 +1,213 @@ +/* + * Copyright 2014 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + */ +/* + * Authors: + * Christian König + */ + +#include +#include "radeon.h" +#include "radeon_trace.h" + +/** + * radeon_sync_create - zero init sync object + * + * @sync: sync object to initialize + * + * Just clear the sync object for now. + */ +void radeon_sync_create(struct radeon_sync *sync) +{ + unsigned i; + + for (i = 0; i < RADEON_NUM_SYNCS; ++i) + sync->semaphores[i] = NULL; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) + sync->sync_to[i] = NULL; +} + +/** + * radeon_sync_fence - use the semaphore to sync to a fence + * + * @sync: sync object to add fence to + * @fence: fence to sync to + * + * Sync to the fence using the semaphore objects + */ +void radeon_sync_fence(struct radeon_sync *sync, + struct radeon_fence *fence) +{ + struct radeon_fence *other; + + if (!fence) + return; + + other = sync->sync_to[fence->ring]; + sync->sync_to[fence->ring] = radeon_fence_later(fence, other); +} + +/** + * radeon_sync_resv - use the semaphores to sync to a reservation object + * + * @sync: sync object to add fences from reservation object to + * @resv: reservation object with embedded fence + * @shared: true if we should only sync to the exclusive fence + * + * Sync to the fence using the semaphore objects + */ +int radeon_sync_resv(struct radeon_device *rdev, + struct radeon_sync *sync, + struct reservation_object *resv, + bool shared) +{ + struct reservation_object_list *flist; + struct fence *f; + struct radeon_fence *fence; + unsigned i; + int r = 0; + + /* always sync to the exclusive fence */ + f = reservation_object_get_excl(resv); + fence = f ? to_radeon_fence(f) : NULL; + if (fence && fence->rdev == rdev) + radeon_sync_fence(sync, fence); + else if (f) + r = fence_wait(f, true); + + flist = reservation_object_get_list(resv); + if (shared || !flist || r) + return r; + + for (i = 0; i < flist->shared_count; ++i) { + f = rcu_dereference_protected(flist->shared[i], + reservation_object_held(resv)); + fence = to_radeon_fence(f); + if (fence && fence->rdev == rdev) + radeon_sync_fence(sync, fence); + else + r = fence_wait(f, true); + + if (r) + break; + } + return r; +} + +/** + * radeon_sync_rings - sync ring to all registered fences + * + * @rdev: radeon_device pointer + * @sync: sync object to use + * @ring: ring that needs sync + * + * Ensure that all registered fences are signaled before letting + * the ring continue. The caller must hold the ring lock. + */ +int radeon_sync_rings(struct radeon_device *rdev, + struct radeon_sync *sync, + int ring) +{ + unsigned count = 0; + int i, r; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + struct radeon_fence *fence = sync->sync_to[i]; + struct radeon_semaphore *semaphore; + + /* check if we really need to sync */ + if (!radeon_fence_need_sync(fence, ring)) + continue; + + /* prevent GPU deadlocks */ + if (!rdev->ring[i].ready) { + dev_err(rdev->dev, "Syncing to a disabled ring!"); + return -EINVAL; + } + + if (count >= RADEON_NUM_SYNCS) { + /* not enough room, wait manually */ + r = radeon_fence_wait(fence, false); + if (r) + return r; + continue; + } + r = radeon_semaphore_create(rdev, &semaphore); + if (r) + return r; + + sync->semaphores[count++] = semaphore; + + /* allocate enough space for sync command */ + r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); + if (r) + return r; + + /* emit the signal semaphore */ + if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { + /* signaling wasn't successful wait manually */ + radeon_ring_undo(&rdev->ring[i]); + r = radeon_fence_wait(fence, false); + if (r) + return r; + continue; + } + + /* we assume caller has already allocated space on waiters ring */ + if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { + /* waiting wasn't successful wait manually */ + radeon_ring_undo(&rdev->ring[i]); + r = radeon_fence_wait(fence, false); + if (r) + return r; + continue; + } + + radeon_ring_commit(rdev, &rdev->ring[i], false); + radeon_fence_note_sync(fence, ring); + } + + return 0; +} + +/** + * radeon_sync_free - free the sync object + * + * @rdev: radeon_device pointer + * @sync: sync object to use + * @fence: fence to use for the free + * + * Free the sync object by freeing all semaphores in it. + */ +void radeon_sync_free(struct radeon_device *rdev, + struct radeon_sync *sync, + struct radeon_fence *fence) +{ + unsigned i; + + for (i = 0; i < RADEON_NUM_SYNCS; ++i) + radeon_semaphore_free(rdev, &sync->semaphores[i], fence); +} diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index d8c49ad34dee..20ef8263d970 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -700,7 +700,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, if (ib.length_dw != 0) { radeon_asic_vm_pad_ib(rdev, &ib); - radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); + radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, false); WARN_ON(ib.length_dw > ndw); r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { @@ -826,7 +826,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, unsigned nptes; uint64_t pte; - radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false); + radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, false); if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index 7f34bad2e724..acff6e09cc40 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c @@ -44,31 +44,27 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.dma_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_dw, cur_size_in_dw; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_dw = size_in_dw; @@ -87,12 +83,12 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index e8bc0a516b57..f5cc777e1c5f 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c @@ -226,31 +226,27 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct reservation_object *resv) { - struct radeon_semaphore *sem = NULL; struct radeon_fence *fence; + struct radeon_sync sync; int ring_index = rdev->asic->copy.dma_ring_index; struct radeon_ring *ring = &rdev->ring[ring_index]; u32 size_in_bytes, cur_size_in_bytes; int i, num_loops; int r = 0; - r = radeon_semaphore_create(rdev, &sem); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return ERR_PTR(r); - } + radeon_sync_create(&sync); size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } - radeon_semaphore_sync_resv(rdev, sem, resv, false); - radeon_semaphore_sync_rings(rdev, sem, ring->idx); + radeon_sync_resv(rdev, &sync, resv, false); + radeon_sync_rings(rdev, &sync, ring->idx); for (i = 0; i < num_loops; i++) { cur_size_in_bytes = size_in_bytes; @@ -269,12 +265,12 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, r = radeon_fence_emit(rdev, &fence, ring->idx); if (r) { radeon_ring_unlock_undo(rdev, ring); - radeon_semaphore_free(rdev, &sem, NULL); + radeon_sync_free(rdev, &sync, NULL); return ERR_PTR(r); } radeon_ring_unlock_commit(rdev, ring, false); - radeon_semaphore_free(rdev, &sem, fence); + radeon_sync_free(rdev, &sync, fence); return fence; } -- GitLab From 587cdda8f739f4c57c91d3f73a1d5b2851a86cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:23 +0100 Subject: [PATCH 5576/9457] drm/radeon: fence PT updates manually v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to add the real execution fence as shared. v2: fix typo Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_object.c | 19 ++++++++ drivers/gpu/drm/radeon/radeon_object.h | 2 + drivers/gpu/drm/radeon/radeon_vm.c | 65 ++++++++++++++++---------- 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 33e6c7a89c32..686e450199c5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -818,3 +818,22 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) ttm_bo_unreserve(&bo->tbo); return r; } + +/** + * radeon_bo_fence - add fence to buffer object + * + * @bo: buffer object in question + * @fence: fence to add + * @shared: true if fence should be added shared + * + */ +void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, + bool shared) +{ + struct reservation_object *resv = bo->tbo.resv; + + if (shared) + reservation_object_add_shared_fence(resv, &fence->base); + else + reservation_object_add_excl_fence(resv, &fence->base); +} diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 1b8ec7917154..3b0b377f76cb 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -155,6 +155,8 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem); extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); +extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, + bool shared); /* * sub allocation diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 20ef8263d970..4ca2779ed828 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -143,7 +143,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; list[0].tv.bo = &vm->page_directory->tbo; - list[0].tv.shared = false; + list[0].tv.shared = true; list[0].tiling_flags = 0; list[0].handle = 0; list_add(&list[0].tv.head, head); @@ -157,7 +157,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; list[idx].tv.bo = &list[idx].robj->tbo; - list[idx].tv.shared = false; + list[idx].tv.shared = true; list[idx].tiling_flags = 0; list[idx].handle = 0; list_add(&list[idx++].tv.head, head); @@ -388,35 +388,25 @@ static void radeon_vm_set_pages(struct radeon_device *rdev, static int radeon_vm_clear_bo(struct radeon_device *rdev, struct radeon_bo *bo) { - struct ttm_validate_buffer tv; - struct ww_acquire_ctx ticket; - struct list_head head; struct radeon_ib ib; unsigned entries; uint64_t addr; int r; - memset(&tv, 0, sizeof(tv)); - tv.bo = &bo->tbo; - tv.shared = false; - - INIT_LIST_HEAD(&head); - list_add(&tv.head, &head); - - r = ttm_eu_reserve_buffers(&ticket, &head, true); - if (r) + r = radeon_bo_reserve(bo, false); + if (r) return r; - r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); - if (r) - goto error; + r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); + if (r) + goto error_unreserve; addr = radeon_bo_gpu_offset(bo); entries = radeon_bo_size(bo) / 8; r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256); if (r) - goto error; + goto error_unreserve; ib.length_dw = 0; @@ -426,15 +416,15 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) - goto error; + goto error_free; - ttm_eu_fence_buffer_objects(&ticket, &head, &ib.fence->base); - radeon_ib_free(rdev, &ib); + radeon_bo_fence(bo, ib.fence, false); - return 0; +error_free: + radeon_ib_free(rdev, &ib); -error: - ttm_eu_backoff_reservation(&ticket, &head); +error_unreserve: + radeon_bo_unreserve(bo); return r; } @@ -707,6 +697,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + radeon_bo_fence(pd, ib.fence, false); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); radeon_fence_unref(&vm->last_flush); @@ -862,6 +853,31 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, } } +/** + * radeon_vm_fence_pts - fence page tables after an update + * + * @vm: requested vm + * @start: start of GPU address range + * @end: end of GPU address range + * @fence: fence to use + * + * Fence the page tables in the range @start - @end (cayman+). + * + * Global and local mutex must be locked! + */ +static void radeon_vm_fence_pts(struct radeon_vm *vm, + uint64_t start, uint64_t end, + struct radeon_fence *fence) +{ + unsigned i; + + start >>= radeon_vm_block_size; + end >>= radeon_vm_block_size; + + for (i = start; i <= end; ++i) + radeon_bo_fence(vm->page_tables[i].bo, fence, false); +} + /** * radeon_vm_bo_update - map a bo into the vm page table * @@ -973,6 +989,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); radeon_ib_free(rdev, &ib); -- GitLab From ad1a58a45ae9a35aaf68b27d21600889360680f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:24 +0100 Subject: [PATCH 5577/9457] drm/radeon: track VM update fences separately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note for each fence if it's a VM page table update or not. This allows us to determine the last VM update in a sync object and so to figure out if we need to flush the TLB or not. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 18 ++++++++++-------- drivers/gpu/drm/radeon/radeon_fence.c | 1 + drivers/gpu/drm/radeon/radeon_ib.c | 3 ++- drivers/gpu/drm/radeon/radeon_sync.c | 7 +++++++ drivers/gpu/drm/radeon/radeon_vm.c | 25 +++++++++++++------------ 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 7cda6d77aeb0..61b2eeabf7a4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -360,14 +360,15 @@ struct radeon_fence_driver { }; struct radeon_fence { - struct fence base; + struct fence base; - struct radeon_device *rdev; - uint64_t seq; + struct radeon_device *rdev; + uint64_t seq; /* RB, DMA, etc. */ - unsigned ring; + unsigned ring; + bool is_vm_update; - wait_queue_t fence_wake; + wait_queue_t fence_wake; }; int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); @@ -594,6 +595,7 @@ void radeon_semaphore_free(struct radeon_device *rdev, struct radeon_sync { struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; struct radeon_fence *sync_to[RADEON_NUM_RINGS]; + struct radeon_fence *last_vm_update; }; void radeon_sync_create(struct radeon_sync *sync); @@ -926,8 +928,8 @@ struct radeon_vm { struct mutex mutex; /* last fence for cs using this vm */ struct radeon_fence *fence; - /* last flush or NULL if we still need to flush */ - struct radeon_fence *last_flush; + /* last flushed PD/PT update */ + struct radeon_fence *flushed_updates; /* last use of vmid */ struct radeon_fence *last_id_use; }; @@ -2975,7 +2977,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring); void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, - int ring); + int ring, struct radeon_fence *fence); void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm, struct radeon_fence *fence); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 995167025282..d13d1b5a859f 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -140,6 +140,7 @@ int radeon_fence_emit(struct radeon_device *rdev, (*fence)->rdev = rdev; (*fence)->seq = seq; (*fence)->ring = ring; + (*fence)->is_vm_update = false; fence_init(&(*fence)->base, &radeon_fence_ops, &rdev->fence_queue.lock, rdev->fence_context + ring, seq); radeon_fence_ring_emit(rdev, ring, *fence); diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 56a17046a61f..c39ce1f05703 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c @@ -154,7 +154,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, } if (ib->vm) - radeon_vm_flush(rdev, ib->vm, ib->ring); + radeon_vm_flush(rdev, ib->vm, ib->ring, + ib->sync.last_vm_update); if (const_ib) { radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); diff --git a/drivers/gpu/drm/radeon/radeon_sync.c b/drivers/gpu/drm/radeon/radeon_sync.c index ddd88fb28d99..02ac8a1de4ff 100644 --- a/drivers/gpu/drm/radeon/radeon_sync.c +++ b/drivers/gpu/drm/radeon/radeon_sync.c @@ -48,6 +48,8 @@ void radeon_sync_create(struct radeon_sync *sync) for (i = 0; i < RADEON_NUM_RINGS; ++i) sync->sync_to[i] = NULL; + + sync->last_vm_update = NULL; } /** @@ -68,6 +70,11 @@ void radeon_sync_fence(struct radeon_sync *sync, other = sync->sync_to[fence->ring]; sync->sync_to[fence->ring] = radeon_fence_later(fence, other); + + if (fence->is_vm_update) { + other = sync->last_vm_update; + sync->last_vm_update = radeon_fence_later(fence, other); + } } /** diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 4ca2779ed828..6ff5741ea403 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -190,7 +190,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, return NULL; /* we definately need to flush */ - radeon_fence_unref(&vm->last_flush); + vm->pd_gpu_addr = ~0ll; /* skip over VMID 0, since it is the system VM */ for (i = 1; i < rdev->vm_manager.nvm; ++i) { @@ -228,6 +228,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, * @rdev: radeon_device pointer * @vm: vm we want to flush * @ring: ring to use for flush + * @updates: last vm update that is waited for * * Flush the vm (cayman+). * @@ -235,13 +236,16 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, */ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, - int ring) + int ring, struct radeon_fence *updates) { uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); - /* if we can't remember our last VM flush then flush now! */ - if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) { + if (pd_addr != vm->pd_gpu_addr || !vm->flushed_updates || + radeon_fence_is_earlier(vm->flushed_updates, updates)) { + trace_radeon_vm_flush(pd_addr, ring, vm->id); + radeon_fence_unref(&vm->flushed_updates); + vm->flushed_updates = radeon_fence_ref(updates); vm->pd_gpu_addr = pd_addr; radeon_ring_vm_flush(rdev, &rdev->ring[ring], vm->id, vm->pd_gpu_addr); @@ -272,10 +276,6 @@ void radeon_vm_fence(struct radeon_device *rdev, radeon_fence_unref(&vm->last_id_use); vm->last_id_use = radeon_fence_ref(fence); - - /* we just flushed the VM, remember that */ - if (!vm->last_flush) - vm->last_flush = radeon_fence_ref(fence); } /** @@ -418,6 +418,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, if (r) goto error_free; + ib.fence->is_vm_update = true; radeon_bo_fence(bo, ib.fence, false); error_free: @@ -697,10 +698,10 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + ib.fence->is_vm_update = true; radeon_bo_fence(pd, ib.fence, false); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); - radeon_fence_unref(&vm->last_flush); } radeon_ib_free(rdev, &ib); @@ -989,11 +990,11 @@ int radeon_vm_bo_update(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + ib.fence->is_vm_update = true; radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); radeon_ib_free(rdev, &ib); - radeon_fence_unref(&vm->last_flush); return 0; } @@ -1124,7 +1125,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) vm->id = 0; vm->ib_bo_va = NULL; vm->fence = NULL; - vm->last_flush = NULL; + vm->flushed_updates = NULL; vm->last_id_use = NULL; mutex_init(&vm->mutex); vm->va = RB_ROOT; @@ -1196,7 +1197,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_bo_unref(&vm->page_directory); radeon_fence_unref(&vm->fence); - radeon_fence_unref(&vm->last_flush); + radeon_fence_unref(&vm->flushed_updates); radeon_fence_unref(&vm->last_id_use); mutex_destroy(&vm->mutex); -- GitLab From 7c42bc1aa23fc061a6ff9c2bd9208817bd54ea04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:25 +0100 Subject: [PATCH 5578/9457] drm/radeon: use one VMID for each ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use multiple VMIDs for each VM, one for each ring. That allows us to execute flushes separately on each ring, still not ideal cause in a lot of cases rings can share IDs. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 4 +- drivers/gpu/drm/radeon/cik_sdma.c | 2 +- drivers/gpu/drm/radeon/ni.c | 6 +-- drivers/gpu/drm/radeon/ni_dma.c | 3 +- drivers/gpu/drm/radeon/radeon.h | 36 ++++++++++-------- drivers/gpu/drm/radeon/radeon_vm.c | 59 ++++++++++++++++++------------ drivers/gpu/drm/radeon/si.c | 6 +-- 7 files changed, 68 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 755923bc6786..3deeed33322f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -4066,6 +4066,7 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; + unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; u32 header, control = INDIRECT_BUFFER_VALID; if (ib->is_const_ib) { @@ -4094,8 +4095,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); } - control |= ib->length_dw | - (ib->vm ? (ib->vm->id << 24) : 0); + control |= ib->length_dw | (vm_id << 24); radeon_ring_write(ring, header); radeon_ring_write(ring, diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 604e2e770951..54b98379188d 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -134,7 +134,7 @@ void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; - u32 extra_bits = (ib->vm ? ib->vm->id : 0) & 0xf; + u32 extra_bits = (ib->vm ? ib->vm->ids[ib->ring].id : 0) & 0xf; if (rdev->wb.enabled) { u32 next_rptr = ring->wptr + 5; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index bee432d3dd30..360de9f1f491 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1373,6 +1373,7 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; + unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA; @@ -1395,15 +1396,14 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) #endif (ib->gpu_addr & 0xFFFFFFFC)); radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(ring, ib->length_dw | - (ib->vm ? (ib->vm->id << 24) : 0)); + radeon_ring_write(ring, ib->length_dw | (vm_id << 24)); /* flush read cache over gart for this vmid */ radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); - radeon_ring_write(ring, ((ib->vm ? ib->vm->id : 0) << 24) | 10); /* poll interval */ + radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */ } static void cayman_cp_enable(struct radeon_device *rdev, bool enable) diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 5a72404c9d5e..50f88611ff60 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c @@ -123,6 +123,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; + unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; if (rdev->wb.enabled) { u32 next_rptr = ring->wptr + 4; @@ -140,7 +141,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev, */ while ((ring->wptr & 7) != 5) radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); - radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0)); + radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, vm_id, 0)); radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 61b2eeabf7a4..79f5f5bf4c0c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -905,33 +905,39 @@ struct radeon_vm_pt { uint64_t addr; }; +struct radeon_vm_id { + unsigned id; + uint64_t pd_gpu_addr; + /* last flushed PD/PT update */ + struct radeon_fence *flushed_updates; + /* last use of vmid */ + struct radeon_fence *last_id_use; +}; + struct radeon_vm { - struct rb_root va; - unsigned id; + struct rb_root va; /* BOs moved, but not yet updated in the PT */ - struct list_head invalidated; + struct list_head invalidated; /* BOs freed, but not yet updated in the PT */ - struct list_head freed; + struct list_head freed; /* contains the page directory */ - struct radeon_bo *page_directory; - uint64_t pd_gpu_addr; - unsigned max_pde_used; + struct radeon_bo *page_directory; + unsigned max_pde_used; /* array of page tables, one for each page directory entry */ - struct radeon_vm_pt *page_tables; + struct radeon_vm_pt *page_tables; - struct radeon_bo_va *ib_bo_va; + struct radeon_bo_va *ib_bo_va; - struct mutex mutex; + struct mutex mutex; /* last fence for cs using this vm */ - struct radeon_fence *fence; - /* last flushed PD/PT update */ - struct radeon_fence *flushed_updates; - /* last use of vmid */ - struct radeon_fence *last_id_use; + struct radeon_fence *fence; + + /* for id and flush management per ring */ + struct radeon_vm_id ids[RADEON_NUM_RINGS]; }; struct radeon_vm_manager { diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 6ff5741ea403..e38efe4962f3 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -182,15 +182,18 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring) { struct radeon_fence *best[RADEON_NUM_RINGS] = {}; + struct radeon_vm_id *vm_id = &vm->ids[ring]; + unsigned choices[2] = {}; unsigned i; /* check if the id is still valid */ - if (vm->last_id_use && vm->last_id_use == rdev->vm_manager.active[vm->id]) + if (vm_id->id && vm_id->last_id_use && + vm_id->last_id_use == rdev->vm_manager.active[vm_id->id]) return NULL; /* we definately need to flush */ - vm->pd_gpu_addr = ~0ll; + vm_id->pd_gpu_addr = ~0ll; /* skip over VMID 0, since it is the system VM */ for (i = 1; i < rdev->vm_manager.nvm; ++i) { @@ -198,8 +201,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, if (fence == NULL) { /* found a free one */ - vm->id = i; - trace_radeon_vm_grab_id(vm->id, ring); + vm_id->id = i; + trace_radeon_vm_grab_id(i, ring); return NULL; } @@ -211,8 +214,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, for (i = 0; i < 2; ++i) { if (choices[i]) { - vm->id = choices[i]; - trace_radeon_vm_grab_id(vm->id, ring); + vm_id->id = choices[i]; + trace_radeon_vm_grab_id(choices[i], ring); return rdev->vm_manager.active[choices[i]]; } } @@ -239,16 +242,18 @@ void radeon_vm_flush(struct radeon_device *rdev, int ring, struct radeon_fence *updates) { uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); + struct radeon_vm_id *vm_id = &vm->ids[ring]; - if (pd_addr != vm->pd_gpu_addr || !vm->flushed_updates || - radeon_fence_is_earlier(vm->flushed_updates, updates)) { + if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates || + radeon_fence_is_earlier(vm_id->flushed_updates, updates)) { - trace_radeon_vm_flush(pd_addr, ring, vm->id); - radeon_fence_unref(&vm->flushed_updates); - vm->flushed_updates = radeon_fence_ref(updates); - vm->pd_gpu_addr = pd_addr; + trace_radeon_vm_flush(pd_addr, ring, vm->ids[ring].id); + radeon_fence_unref(&vm_id->flushed_updates); + vm_id->flushed_updates = radeon_fence_ref(updates); + vm_id->pd_gpu_addr = pd_addr; radeon_ring_vm_flush(rdev, &rdev->ring[ring], - vm->id, vm->pd_gpu_addr); + vm_id->id, vm_id->pd_gpu_addr); + } } @@ -268,14 +273,16 @@ void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm, struct radeon_fence *fence) { + unsigned vm_id = vm->ids[fence->ring].id; + radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(fence); - radeon_fence_unref(&rdev->vm_manager.active[vm->id]); - rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence); + radeon_fence_unref(&rdev->vm_manager.active[vm_id]); + rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence); - radeon_fence_unref(&vm->last_id_use); - vm->last_id_use = radeon_fence_ref(fence); + radeon_fence_unref(&vm->ids[fence->ring].last_id_use); + vm->ids[fence->ring].last_id_use = radeon_fence_ref(fence); } /** @@ -1120,13 +1127,16 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE, RADEON_VM_PTE_COUNT * 8); unsigned pd_size, pd_entries, pts_size; - int r; + int i, r; - vm->id = 0; vm->ib_bo_va = NULL; vm->fence = NULL; - vm->flushed_updates = NULL; - vm->last_id_use = NULL; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + vm->ids[i].id = 0; + vm->ids[i].flushed_updates = NULL; + vm->ids[i].last_id_use = NULL; + } mutex_init(&vm->mutex); vm->va = RB_ROOT; INIT_LIST_HEAD(&vm->invalidated); @@ -1197,8 +1207,11 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_bo_unref(&vm->page_directory); radeon_fence_unref(&vm->fence); - radeon_fence_unref(&vm->flushed_updates); - radeon_fence_unref(&vm->last_id_use); + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + radeon_fence_unref(&vm->ids[i].flushed_updates); + radeon_fence_unref(&vm->ids[i].last_id_use); + } mutex_destroy(&vm->mutex); } diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index e91968b04154..14896ce76324 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3362,6 +3362,7 @@ void si_fence_ring_emit(struct radeon_device *rdev, void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { struct radeon_ring *ring = &rdev->ring[ib->ring]; + unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; u32 header; if (ib->is_const_ib) { @@ -3397,14 +3398,13 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) #endif (ib->gpu_addr & 0xFFFFFFFC)); radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); - radeon_ring_write(ring, ib->length_dw | - (ib->vm ? (ib->vm->id << 24) : 0)); + radeon_ring_write(ring, ib->length_dw | (vm_id << 24)); if (!ib->is_const_ib) { /* flush read cache over gart for this vmid */ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); + radeon_ring_write(ring, vm_id); radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | PACKET3_TC_ACTION_ENA | -- GitLab From 94214635f09c9211023730acdff9342fdf100aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:26 +0100 Subject: [PATCH 5579/9457] drm/radeon: fence BO_VAs manually MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to finally remove the VM fence and so allow concurrent use of it from different engines. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 7 +++---- drivers/gpu/drm/radeon/radeon_cs.c | 6 +++++- drivers/gpu/drm/radeon/radeon_vm.c | 17 ++++++----------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 79f5f5bf4c0c..3207bb60715e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -456,6 +456,7 @@ struct radeon_bo_va { struct list_head bo_list; uint32_t flags; uint64_t addr; + struct radeon_fence *last_pt_update; unsigned ref_count; /* protected by vm mutex */ @@ -915,6 +916,8 @@ struct radeon_vm_id { }; struct radeon_vm { + struct mutex mutex; + struct rb_root va; /* BOs moved, but not yet updated in the PT */ @@ -932,10 +935,6 @@ struct radeon_vm { struct radeon_bo_va *ib_bo_va; - struct mutex mutex; - /* last fence for cs using this vm */ - struct radeon_fence *fence; - /* for id and flush management per ring */ struct radeon_vm_id ids[RADEON_NUM_RINGS]; }; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 30437aa00014..75f22e5e999f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -505,6 +505,9 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, if (r) return r; + radeon_sync_resv(p->rdev, &p->ib.sync, vm->page_directory->tbo.resv, + true); + r = radeon_vm_clear_freed(rdev, vm); if (r) return r; @@ -536,6 +539,8 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); if (r) return r; + + radeon_sync_fence(&p->ib.sync, bo_va->last_pt_update); } return radeon_vm_clear_invalids(rdev, vm); @@ -580,7 +585,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, DRM_ERROR("Failed to sync rings: %i\n", r); goto out; } - radeon_sync_fence(&parser->ib.sync, vm->fence); if ((rdev->family >= CHIP_TAHITI) && (parser->chunk_const_ib_idx != -1)) { diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index e38efe4962f3..f45761469e95 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -275,9 +275,6 @@ void radeon_vm_fence(struct radeon_device *rdev, { unsigned vm_id = vm->ids[fence->ring].id; - radeon_fence_unref(&vm->fence); - vm->fence = radeon_fence_ref(fence); - radeon_fence_unref(&rdev->vm_manager.active[vm_id]); rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence); @@ -707,8 +704,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, } ib.fence->is_vm_update = true; radeon_bo_fence(pd, ib.fence, false); - radeon_fence_unref(&vm->fence); - vm->fence = radeon_fence_ref(ib.fence); } radeon_ib_free(rdev, &ib); @@ -999,8 +994,8 @@ int radeon_vm_bo_update(struct radeon_device *rdev, } ib.fence->is_vm_update = true; radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); - radeon_fence_unref(&vm->fence); - vm->fence = radeon_fence_ref(ib.fence); + radeon_fence_unref(&bo_va->last_pt_update); + bo_va->last_pt_update = radeon_fence_ref(ib.fence); radeon_ib_free(rdev, &ib); return 0; @@ -1026,6 +1021,7 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { r = radeon_vm_bo_update(rdev, bo_va, NULL); radeon_bo_unref(&bo_va->bo); + radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); if (r) return r; @@ -1084,6 +1080,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, bo_va->bo = radeon_bo_ref(bo_va->bo); list_add(&bo_va->vm_status, &vm->freed); } else { + radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); } @@ -1130,8 +1127,6 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) int i, r; vm->ib_bo_va = NULL; - vm->fence = NULL; - for (i = 0; i < RADEON_NUM_RINGS; ++i) { vm->ids[i].id = 0; vm->ids[i].flushed_updates = NULL; @@ -1192,11 +1187,13 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) if (!r) { list_del_init(&bo_va->bo_list); radeon_bo_unreserve(bo_va->bo); + radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); } } list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { radeon_bo_unref(&bo_va->bo); + radeon_fence_unref(&bo_va->last_pt_update); kfree(bo_va); } @@ -1206,8 +1203,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_bo_unref(&vm->page_directory); - radeon_fence_unref(&vm->fence); - for (i = 0; i < RADEON_NUM_RINGS; ++i) { radeon_fence_unref(&vm->ids[i].flushed_updates); radeon_fence_unref(&vm->ids[i].last_id_use); -- GitLab From 43ac885764a589626018cc66973507213cef96ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:27 +0100 Subject: [PATCH 5580/9457] drm/radeon: sync PD updates as shared MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We never invalidate PD entries and making them valid can run with other users in parallel. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index f45761469e95..470451c1de62 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -695,7 +695,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, if (ib.length_dw != 0) { radeon_asic_vm_pad_ib(rdev, &ib); - radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, false); + radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, true); WARN_ON(ib.length_dw > ndw); r = radeon_ib_schedule(rdev, &ib, NULL, false); if (r) { -- GitLab From d1968e1db892e53b5783570a5738477b2a51080b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 19 Nov 2014 14:01:28 +0100 Subject: [PATCH 5581/9457] drm/radeon: sync PT updates as shared v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only invalidating PTEs needs to be executed synchronized to using the PT. v2: fix sync to uses Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_vm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 470451c1de62..0b10f3a03ce2 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -820,7 +820,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, unsigned nptes; uint64_t pte; - radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, false); + radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true); if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; @@ -980,6 +980,13 @@ int radeon_vm_bo_update(struct radeon_device *rdev, return r; ib.length_dw = 0; + if (!(bo_va->flags & RADEON_VM_PAGE_VALID)) { + unsigned i; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) + radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use); + } + radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, bo_va->it.last + 1, addr, radeon_vm_page_flags(bo_va->flags)); -- GitLab From 2f2624c23511b4bf0dd3d4c5ae167715513f351d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 12 Sep 2014 12:25:45 +0200 Subject: [PATCH 5582/9457] drm/radeon: update the VM after setting BO address v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way the necessary VM update is kicked off immediately if all BOs involved are in GPU accessible memory. v2: fix vm lock v3: immediately update unmaps as well v4: use drm_free_large instead of kfree Tested-by: Kai Wasserbäch Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f752c7f56015..a748a64b38b9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -518,6 +518,68 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, return r; } +/** + * radeon_gem_va_update_vm -update the bo_va in its VM + * + * @rdev: radeon_device pointer + * @bo_va: bo_va to update + * + * Update the bo_va directly after setting it's address. Errors are not + * vital here, so they are not reported back to userspace. + */ +static void radeon_gem_va_update_vm(struct radeon_device *rdev, + struct radeon_bo_va *bo_va) +{ + struct ttm_validate_buffer tv, *entry; + struct radeon_cs_reloc *vm_bos; + struct ww_acquire_ctx ticket; + struct list_head list; + unsigned domain; + int r; + + INIT_LIST_HEAD(&list); + + tv.bo = &bo_va->bo->tbo; + tv.shared = true; + list_add(&tv.head, &list); + + vm_bos = radeon_vm_get_bos(rdev, bo_va->vm, &list); + if (!vm_bos) + return; + + r = ttm_eu_reserve_buffers(&ticket, &list, true); + if (r) + goto error_free; + + list_for_each_entry(entry, &list, head) { + domain = radeon_mem_type_to_domain(entry->bo->mem.mem_type); + /* if anything is swapped out don't swap it in here, + just abort and wait for the next CS */ + if (domain == RADEON_GEM_DOMAIN_CPU) + goto error_unreserve; + } + + mutex_lock(&bo_va->vm->mutex); + r = radeon_vm_clear_freed(rdev, bo_va->vm); + if (r) + goto error_unlock; + + if (bo_va->it.start) + r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem); + +error_unlock: + mutex_unlock(&bo_va->vm->mutex); + +error_unreserve: + ttm_eu_backoff_reservation(&ticket, &list); + +error_free: + drm_free_large(vm_bos); + + if (r) + DRM_ERROR("Couldn't update BO_VA (%d)\n", r); +} + int radeon_gem_va_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -612,6 +674,8 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, default: break; } + if (!r) + radeon_gem_va_update_vm(rdev, bo_va); args->operation = RADEON_VA_RESULT_OK; if (r) { args->operation = RADEON_VA_RESULT_ERROR; -- GitLab From 2c30540b38d683d4c7f06d13a451f67d4362d7b1 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 14 Nov 2014 09:47:32 -0700 Subject: [PATCH 5583/9457] NVMe: add ->exit_hctx() hook If we do teardown and setup of the queue and block related parts of the driver, then we should clear nvmeq->hctx once we kill the hardware queue. Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 9310fe51382e..ba278ae00705 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -171,6 +171,13 @@ static int nvme_admin_init_request(void *data, struct request *req, return 0; } +static void nvme_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) +{ + struct nvme_queue *nvmeq = hctx->driver_data; + + nvmeq->hctx = NULL; +} + static int nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, unsigned int hctx_idx) { @@ -1335,6 +1342,7 @@ static struct blk_mq_ops nvme_mq_admin_ops = { .queue_rq = nvme_admin_queue_rq, .map_queue = blk_mq_map_queue, .init_hctx = nvme_admin_init_hctx, + .exit_hctx = nvme_exit_hctx, .init_request = nvme_admin_init_request, .timeout = nvme_timeout, }; @@ -1343,6 +1351,7 @@ static struct blk_mq_ops nvme_mq_ops = { .queue_rq = nvme_queue_rq, .map_queue = blk_mq_map_queue, .init_hctx = nvme_init_hctx, + .exit_hctx = nvme_exit_hctx, .init_request = nvme_init_request, .timeout = nvme_timeout, }; -- GitLab From be7837e89d610046ae8dd28dc504df09261d9f91 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 14 Nov 2014 09:50:19 -0700 Subject: [PATCH 5584/9457] NVMe: fail pci initialization if the device doesn't have any BARs The PCI init of NVMe doesn't check for valid bars before proceeding to map and use BAR 0. If the device is hosed (or firmware is), then we should catch this case and give up early. This fixes a: [ 1662.035778] WARNING: CPU: 0 PID: 4 at arch/x86/mm/ioremap.c:63 __ioremap_check_ram+0xa7/0xc0() and later badness on such a device. Acked-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index ba278ae00705..c1541652b7e0 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2156,6 +2156,9 @@ static int nvme_dev_map(struct nvme_dev *dev) dev->entry[0].vector = pdev->irq; pci_set_master(pdev); bars = pci_select_bars(pdev, IORESOURCE_MEM); + if (!bars) + goto disable_pci; + if (pci_request_selected_regions(pdev, bars, "nvme")) goto disable_pci; -- GitLab From 62c606978aa028260f88d0dcb9834bbb7a42b048 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 20 Nov 2014 18:33:58 +0100 Subject: [PATCH 5585/9457] usb: dwc3: keystone: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-keystone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index dd8d2df6db31..fe3b9335a74e 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -123,6 +123,7 @@ static int kdwc3_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "missing irq\n"); + error = irq; goto err_irq; } -- GitLab From 1290a958d48e30d60262a33acb5f068e87834ce4 Mon Sep 17 00:00:00 2001 From: Arjun Sreedharan Date: Thu, 20 Nov 2014 21:23:36 +0530 Subject: [PATCH 5586/9457] usb: phy: propagate __of_usb_find_phy()'s error on failure When __of_usb_find_phy() fails, it returns -ENODEV - its error code has to be returned by devm_usb_get_phy_by_phandle(). Only when the former function succeeds and try_module_get() fails should -EPROBE_DEFER be returned. [ balbi@ti.com : remove trailing whitespace ] Signed-off-by: Arjun Sreedharan Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 045cd309367a..e6bf801a339a 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -191,7 +191,9 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, phy = __of_usb_find_phy(node); if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - phy = ERR_PTR(-EPROBE_DEFER); + if (!IS_ERR(phy)) + phy = ERR_PTR(-EPROBE_DEFER); + devres_free(ptr); goto err1; } -- GitLab From 74df41b40ab0222903dcc9681e9076c2604741d8 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Tue, 18 Nov 2014 15:11:54 -0500 Subject: [PATCH 5587/9457] usb: gadget: add USB3 support to the printer driver Add SS descriptors to support the capabilities provided by USB3 controller drivers; unit tests run using a PLX 3380 [max transfer speed measured of 1Gbps] This driver shall fallback to lower operating modes when the higher ones are not available. Signed-off-by: Jorge Ramirez-Ortiz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 65 ++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 6474081dcbaf..e0cf1b0d471d 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -208,6 +208,43 @@ static struct usb_descriptor_header *hs_printer_function[] = { NULL }; +/* + * Added endpoint descriptors for 3.0 devices + */ + +static struct usb_endpoint_descriptor ss_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { + .bLength = sizeof(ss_ep_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_endpoint_descriptor ss_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { + .bLength = sizeof(ss_ep_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_descriptor_header *ss_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &ss_ep_in_desc, + (struct usb_descriptor_header *) &ss_ep_in_comp_desc, + (struct usb_descriptor_header *) &ss_ep_out_desc, + (struct usb_descriptor_header *) &ss_ep_out_comp_desc, + NULL +}; + static struct usb_otg_descriptor otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, @@ -220,7 +257,20 @@ static const struct usb_descriptor_header *otg_desc[] = { }; /* maxpacket and other transfer characteristics vary by speed. */ -#define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) +static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, + struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs, + struct usb_endpoint_descriptor *ss) +{ + switch (gadget->speed) { + case USB_SPEED_SUPER: + return ss; + case USB_SPEED_HIGH: + return hs; + default: + return fs; + } +} /*-------------------------------------------------------------------------*/ @@ -793,11 +843,12 @@ set_printer_interface(struct printer_dev *dev) { int result = 0; - dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); + dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, + &ss_ep_in_desc); dev->in_ep->driver_data = dev; - dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc, - &fs_ep_out_desc); + dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, + &hs_ep_out_desc, &ss_ep_out_desc); dev->out_ep->driver_data = dev; result = usb_ep_enable(dev->in_ep); @@ -1016,9 +1067,11 @@ static int __init printer_func_bind(struct usb_configuration *c, /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_printer_function, - hs_printer_function, NULL); + hs_printer_function, ss_printer_function); if (ret) return ret; @@ -1253,7 +1306,7 @@ static __refdata struct usb_composite_driver printer_driver = { .name = shortname, .dev = &device_desc, .strings = dev_strings, - .max_speed = USB_SPEED_HIGH, + .max_speed = USB_SPEED_SUPER, .bind = printer_bind, .unbind = printer_unbind, }; -- GitLab From ba7cc772e77d30943833b7d38a861203dcb8c881 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 19 Nov 2014 17:19:05 +0800 Subject: [PATCH 5588/9457] usb: gadget: at91_udc: remove unused release function As the driver call usb_add_gadget_udc --> usb_add_gadget_udc_release with NULL as release parameter, so it will use usb_udc_no_release. So, the release in driver won't used, remove it. And at the same time, in the usb_add_gadget_udc_release will set the gadget name, so remove it also in driver. Signed-off-by: Bo Shen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 753e93b5440c..fe0534c0e3d4 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1537,20 +1537,11 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) /*-------------------------------------------------------------------------*/ -static void nop_release(struct device *dev) -{ - /* nothing to free */ -} - static struct at91_udc controller = { .gadget = { .ops = &at91_udc_ops, .ep0 = &controller.ep[0].ep, .name = driver_name, - .dev = { - .init_name = "gadget", - .release = nop_release, - } }, .ep[0] = { .ep = { -- GitLab From cf0b1d1309790fbae27e7276ae4cb30c38ac9fc8 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 19 Nov 2014 17:19:06 +0800 Subject: [PATCH 5589/9457] usb: gadget: atmel_usba_udc: remove release function As the driver call usb_add_gadget_udc --> usb_add_gadget_udc_release with NULL as release parameter, so it will use usb_udc_no_release. So, the release in driver won't used, remove it. And at the same time, in the usb_add_gadget_udc_release will set the gadget name, so remove it also in driver. Signed-off-by: Bo Shen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/atmel_usba_udc.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 990b26f33738..b31747979c4a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1007,19 +1007,10 @@ static struct usb_endpoint_descriptor usba_ep0_desc = { .bInterval = 1, }; -static void nop_release(struct device *dev) -{ - -} - static struct usb_gadget usba_gadget_template = { .ops = &usba_udc_ops, .max_speed = USB_SPEED_HIGH, .name = "atmel_usba_udc", - .dev = { - .init_name = "gadget", - .release = nop_release, - }, }; /* -- GitLab From b2ba27a5c56ff7204d8a8684893d64d4afe2cee5 Mon Sep 17 00:00:00 2001 From: Ronald Wahl Date: Wed, 19 Nov 2014 16:37:27 +0100 Subject: [PATCH 5590/9457] usb: gadget: at91_udc: move prepare clk into process context Commit 7628083227b6bc4a7e33d7c381d7a4e558424b6b (usb: gadget: at91_udc: prepare clk before calling enable) added clock preparation in interrupt context. This is not allowed as it might sleep. Also setting the clock rate is unsafe to call from there for the same reason. Move clock preparation and setting clock rate into process context (at91udc_probe). Signed-off-by: Ronald Wahl Acked-by: Alexandre Belloni Acked-by: Boris Brezillon Acked-by: Nicolas Ferre Cc: Felipe Balbi Cc: # v3.17+ Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.c | 44 ++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index fe0534c0e3d4..eb2999c5d03c 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -895,12 +895,10 @@ static void clk_on(struct at91_udc *udc) return; udc->clocked = 1; - if (IS_ENABLED(CONFIG_COMMON_CLK)) { - clk_set_rate(udc->uclk, 48000000); - clk_prepare_enable(udc->uclk); - } - clk_prepare_enable(udc->iclk); - clk_prepare_enable(udc->fclk); + if (IS_ENABLED(CONFIG_COMMON_CLK)) + clk_enable(udc->uclk); + clk_enable(udc->iclk); + clk_enable(udc->fclk); } static void clk_off(struct at91_udc *udc) @@ -909,10 +907,10 @@ static void clk_off(struct at91_udc *udc) return; udc->clocked = 0; udc->gadget.speed = USB_SPEED_UNKNOWN; - clk_disable_unprepare(udc->fclk); - clk_disable_unprepare(udc->iclk); + clk_disable(udc->fclk); + clk_disable(udc->iclk); if (IS_ENABLED(CONFIG_COMMON_CLK)) - clk_disable_unprepare(udc->uclk); + clk_disable(udc->uclk); } /* @@ -1793,14 +1791,24 @@ static int at91udc_probe(struct platform_device *pdev) } /* don't do anything until we have both gadget driver and VBUS */ + if (IS_ENABLED(CONFIG_COMMON_CLK)) { + clk_set_rate(udc->uclk, 48000000); + retval = clk_prepare(udc->uclk); + if (retval) + goto fail1; + } + retval = clk_prepare(udc->fclk); + if (retval) + goto fail1a; + retval = clk_prepare_enable(udc->iclk); if (retval) - goto fail1; + goto fail1b; at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); /* Clear all pending interrupts - UDP may be used by bootloader. */ at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); - clk_disable_unprepare(udc->iclk); + clk_disable(udc->iclk); /* request UDC and maybe VBUS irqs */ udc->udp_irq = platform_get_irq(pdev, 0); @@ -1808,7 +1816,7 @@ static int at91udc_probe(struct platform_device *pdev) 0, driver_name, udc); if (retval < 0) { DBG("request irq %d failed\n", udc->udp_irq); - goto fail1; + goto fail1c; } if (gpio_is_valid(udc->board.vbus_pin)) { retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); @@ -1861,6 +1869,13 @@ static int at91udc_probe(struct platform_device *pdev) gpio_free(udc->board.vbus_pin); fail2: free_irq(udc->udp_irq, udc); +fail1c: + clk_unprepare(udc->iclk); +fail1b: + clk_unprepare(udc->fclk); +fail1a: + if (IS_ENABLED(CONFIG_COMMON_CLK)) + clk_unprepare(udc->uclk); fail1: if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk)) clk_put(udc->uclk); @@ -1909,6 +1924,11 @@ static int __exit at91udc_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); + if (IS_ENABLED(CONFIG_COMMON_CLK)) + clk_unprepare(udc->uclk); + clk_unprepare(udc->fclk); + clk_unprepare(udc->iclk); + clk_put(udc->iclk); clk_put(udc->fclk); if (IS_ENABLED(CONFIG_COMMON_CLK)) -- GitLab From 18a4e65f229aec8ac23a036ff734864eefe4b89d Mon Sep 17 00:00:00 2001 From: Mario Schuknecht Date: Sun, 16 Nov 2014 21:21:45 +0100 Subject: [PATCH 5591/9457] usb: gadget: net2280: Fix superspeed dma_done() Parameter three in function call dma_done() is incorrect. Move use of variable 'tmp' after if-condition. Signed-off-by: Mario Schuknecht Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index c49179493796..d6411e0a8e03 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1118,10 +1118,10 @@ static void scan_dma_completions(struct net2280_ep *ep) break; } else if (!ep->is_in && (req->req.length % ep->ep.maxpacket) != 0) { - tmp = readl(&ep->regs->ep_stat); if (ep->dev->quirks & PLX_SUPERSPEED) return dma_done(ep, req, tmp, 0); + tmp = readl(&ep->regs->ep_stat); /* AVOID TROUBLE HERE by not issuing short reads from * your gadget driver. That helps avoids errata 0121, * 0122, and 0124; not all cases trigger the warning. -- GitLab From 2ed127697eb1376645cbcfa08a13dda157233c9d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 17 Nov 2014 16:19:10 +0100 Subject: [PATCH 5592/9457] PM / Domains: Power on the PM domain right after attach completes Vast amount of platform drivers which enables runtime PM, don't invoke a pm_runtime_get_sync() while probing their devices. Instead, once they have turned on their PM resourses during ->probe() and are ready to handle I/O, these invokes pm_runtime_set_active() to synchronize its state towards the runtime PM core. From the runtime PM point of view this behavior is perfectly acceptable, but we encounter probe failures if their corresponding devices resides in the generic PM domain. The issues are observed for those devices, which requires its PM domain to stay powered during ->probe() since that's not being controlled. While using the generic OF-based PM domain look-up, a device's PM domain will be attached during the probe sequence. For this path, let's fix the probe failures, by simply power on the PM domain right after when it's been attached to the device. The generic PM domain stays powered until all of its devices becomes runtime PM enabled and runtime PM suspended. The old SOCs which makes use of the generic PM domain but don't use the generic OF-based PM domain look-up, will not be affected from this change. Signed-off-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 3989eb63d538..1bfb54ce60e8 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2235,6 +2235,7 @@ int genpd_dev_pm_attach(struct device *dev) } dev->pm_domain->detach = genpd_dev_pm_detach; + pm_genpd_poweron(pd); return 0; } -- GitLab From 5aeee3424fa5926a53885b9defb593971e446d77 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 11:02:14 +0100 Subject: [PATCH 5593/9457] ALSA: usb-audio: Refactor ignore_ctl_error checks Introduce an internal helper macro for avoiding many open codes. The only slight behavior change is in a couple of get ballcks where the value is reset at error no matter whether ignore_ctl_error is set or not. Actually this is even safer than before. Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index c6209ce5a430..a4fbfff63191 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -136,6 +136,10 @@ check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen) return strlcpy(buf, p->name, buflen); } +/* ignore the error value if ignore_ctl_error flag is set */ +#define filter_error(cval, err) \ + ((cval)->mixer->ignore_ctl_error ? 0 : (err)) + /* check whether the control should be ignored */ static inline int check_ignored_ctl(const struct usbmix_name_map *p) @@ -1088,7 +1092,7 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, continue; err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &val); if (err < 0) - return cval->mixer->ignore_ctl_error ? 0 : err; + return filter_error(cval, err); val = get_relative_value(cval, val); ucontrol->value.integer.value[cnt] = val; cnt++; @@ -1098,7 +1102,7 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, /* master channel */ err = snd_usb_get_cur_mix_value(cval, 0, 0, &val); if (err < 0) - return cval->mixer->ignore_ctl_error ? 0 : err; + return filter_error(cval, err); val = get_relative_value(cval, val); ucontrol->value.integer.value[0] = val; } @@ -1120,7 +1124,7 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, continue; err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &oval); if (err < 0) - return cval->mixer->ignore_ctl_error ? 0 : err; + return filter_error(cval, err); val = ucontrol->value.integer.value[cnt]; val = get_abs_value(cval, val); if (oval != val) { @@ -1133,7 +1137,7 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, /* master channel */ err = snd_usb_get_cur_mix_value(cval, 0, 0, &oval); if (err < 0) - return cval->mixer->ignore_ctl_error ? 0 : err; + return filter_error(cval, err); val = ucontrol->value.integer.value[0]; val = get_abs_value(cval, val); if (val != oval) { @@ -1628,12 +1632,10 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, int err, val; err = get_cur_ctl_value(cval, cval->control << 8, &val); - if (err < 0 && cval->mixer->ignore_ctl_error) { + if (err < 0) { ucontrol->value.integer.value[0] = cval->min; - return 0; + return filter_error(cval, err); } - if (err < 0) - return err; val = get_relative_value(cval, val); ucontrol->value.integer.value[0] = val; return 0; @@ -1647,11 +1649,8 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, int val, oval, err; err = get_cur_ctl_value(cval, cval->control << 8, &oval); - if (err < 0) { - if (cval->mixer->ignore_ctl_error) - return 0; - return err; - } + if (err < 0) + return filter_error(cval, err); val = ucontrol->value.integer.value[0]; val = get_abs_value(cval, val); if (val != oval) { @@ -1923,11 +1922,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, err = get_cur_ctl_value(cval, cval->control << 8, &val); if (err < 0) { - if (cval->mixer->ignore_ctl_error) { - ucontrol->value.enumerated.item[0] = 0; - return 0; - } - return err; + ucontrol->value.enumerated.item[0] = 0; + return filter_error(cval, err); } val = get_relative_value(cval, val); ucontrol->value.enumerated.item[0] = val; @@ -1942,11 +1938,8 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, int val, oval, err; err = get_cur_ctl_value(cval, cval->control << 8, &oval); - if (err < 0) { - if (cval->mixer->ignore_ctl_error) - return 0; - return err; - } + if (err < 0) + return filter_error(cval, err); val = ucontrol->value.enumerated.item[0]; val = get_abs_value(cval, val); if (val != oval) { -- GitLab From ac96ce83ff21c9338afa0e81baabd902d9350015 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 16:42:51 +0100 Subject: [PATCH 5594/9457] net: brcm80211: Deletion of unnecessary checks before two function calls The functions brcmu_pkt_buf_free_skb() and release_firmware() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 3 +-- drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 3 +-- drivers/net/wireless/brcm80211/brcmsmac/main.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index 0f157f151282..1ff787d1a36b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -262,8 +262,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) fail: brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); - if (fwctx->code) - release_firmware(fwctx->code); + release_firmware(fwctx->code); device_release_driver(fwctx->dev); kfree(fwctx); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c index 02d39ce8dbca..9f783db34ae5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c @@ -518,8 +518,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? len : msgbuf->ioctl_resp_ret_len); } - if (skb) - brcmu_pkt_buf_free_skb(skb); + brcmu_pkt_buf_free_skb(skb); return msgbuf->ioctl_resp_status; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index bc9be78faafa..738cfaca1e0f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1009,8 +1009,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) if (txh) trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); - if (p) - brcmu_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } if (dma && queue < NFIFO) { -- GitLab From 9e6f3f472c8f95021ad048acc7cd3e40a827f8ce Mon Sep 17 00:00:00 2001 From: Kristian Evensen Date: Thu, 20 Nov 2014 16:52:58 +0100 Subject: [PATCH 5595/9457] mwifiex: Add USB8766 support Adds new VID/PID for the Marvell 88W8766. The kernel currently only supports the device as PCI, but it is also available using USB. An example of a device delivered with the 88W8766 as USB is the Globalscale Mirabox. TX buffer size is set to driver default (2K), as we do not know the firmware requirement. Signed-off-by: Kristian Evensen Reviewed-by: Andrew Lunn Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/Kconfig | 2 +- drivers/net/wireless/mwifiex/usb.c | 13 +++++++++++++ drivers/net/wireless/mwifiex/usb.h | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig index e70d0df9b0da..aa01c9bc77f9 100644 --- a/drivers/net/wireless/mwifiex/Kconfig +++ b/drivers/net/wireless/mwifiex/Kconfig @@ -31,7 +31,7 @@ config MWIFIEX_PCIE mwifiex_pcie. config MWIFIEX_USB - tristate "Marvell WiFi-Ex Driver for USB8797/8897" + tristate "Marvell WiFi-Ex Driver for USB8766/8797/8897" depends on MWIFIEX && USB select FW_LOADER ---help--- diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 6cc8519c0f40..1b56495ec872 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -27,6 +27,11 @@ static struct mwifiex_if_ops usb_ops; static struct semaphore add_remove_card_sem; static struct usb_device_id mwifiex_usb_table[] = { + /* 8766 */ + {USB_DEVICE(USB8XXX_VID, USB8766_PID_1)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8766_PID_2, + USB_CLASS_VENDOR_SPEC, + USB_SUBCLASS_VENDOR_SPEC, 0xff)}, /* 8797 */ {USB_DEVICE(USB8XXX_VID, USB8797_PID_1)}, {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2, @@ -354,10 +359,12 @@ static int mwifiex_usb_probe(struct usb_interface *intf, /* PID_1 is used for firmware downloading only */ switch (id_product) { + case USB8766_PID_1: case USB8797_PID_1: case USB8897_PID_1: card->usb_boot_state = USB8XXX_FW_DNLD; break; + case USB8766_PID_2: case USB8797_PID_2: case USB8897_PID_2: card->usb_boot_state = USB8XXX_FW_READY; @@ -786,6 +793,11 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K; strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME); break; + case USB8766_PID_1: + case USB8766_PID_2: + adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; + strcpy(adapter->fw_name, USB8766_DEFAULT_FW_NAME); + break; case USB8797_PID_1: case USB8797_PID_2: default: @@ -1060,5 +1072,6 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION); MODULE_VERSION(USB_VERSION); MODULE_LICENSE("GPL v2"); +MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME); MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME); MODULE_FIRMWARE(USB8897_DEFAULT_FW_NAME); diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h index 4c41c2a193c5..a7cbba1355af 100644 --- a/drivers/net/wireless/mwifiex/usb.h +++ b/drivers/net/wireless/mwifiex/usb.h @@ -24,6 +24,8 @@ #define USB8XXX_VID 0x1286 +#define USB8766_PID_1 0x2041 +#define USB8766_PID_2 0x2042 #define USB8797_PID_1 0x2043 #define USB8797_PID_2 0x2044 #define USB8897_PID_1 0x2045 @@ -37,6 +39,7 @@ #define MWIFIEX_RX_DATA_URB 6 #define MWIFIEX_USB_TIMEOUT 100 +#define USB8766_DEFAULT_FW_NAME "mrvl/usb8766_uapsta.bin" #define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin" #define USB8897_DEFAULT_FW_NAME "mrvl/usb8897_uapsta.bin" -- GitLab From bbd440fb81338d8e8d58193867f1404c4e6cef7a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 20 Nov 2014 22:33:59 +0100 Subject: [PATCH 5596/9457] drm/i915: Don't rely upon encoder->type for infoframe hw state readout encoder->type can change underneath us and doesn't need to reflect actual hw state (since we don't construct it from hw state like e.g. encoder->crtc crtc->config). And this can indeed happen: 1) Boot with plugged-in hdmi screen. Since we only set ->type in the probe functions this means we won't detect any infoframes since type is still unkown. 2) First probe sets type to HDMI. 3) If the first modeset now does _not_ happen on the HDMI pipe with infoframes encoder->get_config suddenly sees infoframes and the state checker gets angry. Fix this by only relying on actual hw state when figuring out whether the ddi port is in hdmi mode and sends infoframes. Cc: Jesse Barnes Cc: Paulo Zanoni Reported-by: Paulo Zanoni Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 24110c96e539..e6b45cd150d3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2027,6 +2027,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + struct intel_hdmi *intel_hdmi; u32 temp, flags = 0; struct drm_device *dev = dev_priv->dev; @@ -2062,6 +2063,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder, switch (temp & TRANS_DDI_MODE_SELECT_MASK) { case TRANS_DDI_MODE_SELECT_HDMI: pipe_config->has_hdmi_sink = true; + intel_hdmi = enc_to_intel_hdmi(&encoder->base); + + if (intel_hdmi->infoframe_enabled(&encoder->base)) + pipe_config->has_infoframe = true; break; case TRANS_DDI_MODE_SELECT_DVI: case TRANS_DDI_MODE_SELECT_FDI: @@ -2075,14 +2080,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, break; } - if (encoder->type == INTEL_OUTPUT_HDMI) { - struct intel_hdmi *intel_hdmi = - enc_to_intel_hdmi(&encoder->base); - - if (intel_hdmi->infoframe_enabled(&encoder->base)) - pipe_config->has_infoframe = true; - } - if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe)) -- GitLab From d9e600b2e4a5e9f1dfe80cfcb453c8f5067a2a8a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 20 Nov 2014 20:10:33 +0000 Subject: [PATCH 5597/9457] drm/i915: Only call mod_timer() if not already pending The final arrangement of updating timer->expires and calling mod_timer() used in commit 672e7b7c1849c904b2c55185906b3940843c55c6 Author: Chris Wilson Date: Wed Nov 19 09:47:19 2014 +0000 drm/i915: Don't continually defer the hangcheck turns out to be very unsafe. Try again. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8d169e152d1e..5908580d7c15 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3067,9 +3067,10 @@ void i915_queue_hangcheck(struct drm_device *dev) return; /* Don't continually defer the hangcheck, but make sure it is active */ - if (!timer_pending(timer)) - timer->expires = round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES); - mod_timer(timer, timer->expires); + if (timer_pending(timer)) + return; + mod_timer(timer, + round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); } static void ibx_irq_reset(struct drm_device *dev) -- GitLab From 89a35ecdc6aa5a88165313ca5cfd52b8e8e7fbbd Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 20 Nov 2014 13:24:13 -0800 Subject: [PATCH 5598/9457] drm/i915/g4x: fix g4x infoframe readout Need to check the port too. Reported-by: Daniel Vetter Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_hdmi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f58e8834ebfb..ec873338e84d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -170,9 +170,13 @@ static bool g4x_infoframe_enabled(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); u32 val = I915_READ(VIDEO_DIP_CTL); - return val & VIDEO_DIP_ENABLE; + if (VIDEO_DIP_PORT(intel_dig_port->port) == (val & VIDEO_DIP_PORT_MASK)) + return val & VIDEO_DIP_ENABLE; + + return false; } static void ibx_write_infoframe(struct drm_encoder *encoder, -- GitLab From bafa578fdfb2e9861dcaf7d9863e1265aff226c9 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:15 +0000 Subject: [PATCH 5599/9457] ixgbevf: Update ixgbevf_alloc_rx_buffers to handle clearing of status bits Instead of clearing the status bits in the cleanup it makes more sense to just clear the status bits on allocation. This way we can leave the Rx descriptor rings as a read only memory block until we actually have buffers to give back to the hardware. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 132 +++++++++++------- 1 file changed, 80 insertions(+), 52 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 030a219c85e3..deda74d24075 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -143,21 +143,6 @@ u32 ixgbevf_read_reg(struct ixgbe_hw *hw, u32 reg) return value; } -static inline void ixgbevf_release_rx_desc(struct ixgbevf_ring *rx_ring, - u32 val) -{ - rx_ring->next_to_use = val; - - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - ixgbevf_write_tail(rx_ring, val); -} - /** * ixgbevf_set_ivar - set IVAR registers - maps interrupt causes to vectors * @adapter: pointer to adapter struct @@ -424,52 +409,99 @@ static inline void ixgbevf_rx_checksum(struct ixgbevf_ring *ring, skb->ip_summed = CHECKSUM_UNNECESSARY; } +static bool ixgbevf_alloc_mapped_skb(struct ixgbevf_ring *rx_ring, + struct ixgbevf_rx_buffer *bi) +{ + struct sk_buff *skb = bi->skb; + dma_addr_t dma = bi->dma; + + if (unlikely(skb)) + return true; + + skb = netdev_alloc_skb_ip_align(rx_ring->netdev, + rx_ring->rx_buf_len); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + dma = dma_map_single(rx_ring->dev, skb->data, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); + + /* if mapping failed free memory back to system since + * there isn't much point in holding memory we can't use + */ + if (dma_mapping_error(rx_ring->dev, dma)) { + dev_kfree_skb_any(skb); + + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + bi->skb = skb; + bi->dma = dma; + + return true; +} + /** * ixgbevf_alloc_rx_buffers - Replace used receive buffers; packet split * @rx_ring: rx descriptor ring (for a specific queue) to setup buffers on + * @cleaned_count: number of buffers to replace **/ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring, - int cleaned_count) + u16 cleaned_count) { union ixgbe_adv_rx_desc *rx_desc; struct ixgbevf_rx_buffer *bi; unsigned int i = rx_ring->next_to_use; - while (cleaned_count--) { - rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - bi = &rx_ring->rx_buffer_info[i]; - - if (!bi->skb) { - struct sk_buff *skb; + /* nothing to do or no valid netdev defined */ + if (!cleaned_count || !rx_ring->netdev) + return; - skb = netdev_alloc_skb_ip_align(rx_ring->netdev, - rx_ring->rx_buf_len); - if (!skb) - goto no_buffers; + rx_desc = IXGBEVF_RX_DESC(rx_ring, i); + bi = &rx_ring->rx_buffer_info[i]; + i -= rx_ring->count; - bi->skb = skb; + do { + if (!ixgbevf_alloc_mapped_skb(rx_ring, bi)) + break; - bi->dma = dma_map_single(rx_ring->dev, skb->data, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(rx_ring->dev, bi->dma)) { - dev_kfree_skb(skb); - bi->skb = NULL; - dev_err(rx_ring->dev, "Rx DMA map failed\n"); - break; - } - } + /* Refresh the desc even if pkt_addr didn't change + * because each write-back erases this info. + */ rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + rx_desc++; + bi++; i++; - if (i == rx_ring->count) - i = 0; - } + if (unlikely(!i)) { + rx_desc = IXGBEVF_RX_DESC(rx_ring, 0); + bi = rx_ring->rx_buffer_info; + i -= rx_ring->count; + } + + /* clear the hdr_addr for the next_to_use descriptor */ + rx_desc->read.hdr_addr = 0; + + cleaned_count--; + } while (cleaned_count); -no_buffers: - rx_ring->rx_stats.alloc_rx_buff_failed++; - if (rx_ring->next_to_use != i) - ixgbevf_release_rx_desc(rx_ring, i); + i += rx_ring->count; + + if (rx_ring->next_to_use != i) { + /* record the next descriptor to use */ + rx_ring->next_to_use = i; + + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). + */ + wmb(); + ixgbevf_write_tail(rx_ring, i); + } } static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter, @@ -489,8 +521,8 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct sk_buff *skb; unsigned int i; u32 len, staterr; - int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; + u16 cleaned_count = ixgbevf_desc_unused(rx_ring); i = rx_ring->next_to_clean; rx_desc = IXGBEVF_RX_DESC(rx_ring, i); @@ -571,8 +603,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, ixgbevf_rx_skb(q_vector, skb, staterr, rx_desc); next_desc: - rx_desc->wb.upper.status_error = 0; - /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); @@ -587,11 +617,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, } rx_ring->next_to_clean = i; - cleaned_count = ixgbevf_desc_unused(rx_ring); - - if (cleaned_count) - ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); - u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; @@ -599,6 +624,9 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, q_vector->rx.total_packets += total_rx_packets; q_vector->rx.total_bytes += total_rx_bytes; + if (cleaned_count) + ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); + return total_rx_packets; } -- GitLab From ec62fe264110a021336de20e400bc778a4111f60 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:20 +0000 Subject: [PATCH 5600/9457] ixgbevf: Test Rx status bits directly out of the descriptor Instead of keeping a local copy of the status bits from the descriptor we can just read them directly - this is accomplished with the addition of ixgbevf_test_staterr(). In addition instead of doing a byteswap on the status bits value, we can byteswap the constant values we are testing since that can be done at compile time which should help to improve performance on big-endian systems. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 7 +++ .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 59 ++++++++----------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index ba96cb5b886d..5f7d2f3c738d 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -307,6 +307,13 @@ static inline bool ixgbevf_qv_disable(struct ixgbevf_q_vector *q_vector) ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8) #define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG +/* ixgbevf_test_staterr - tests bits in Rx descriptor status and error fields */ +static inline __le32 ixgbevf_test_staterr(union ixgbe_adv_rx_desc *rx_desc, + const u32 stat_err_bits) +{ + return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits); +} + static inline u16 ixgbevf_desc_unused(struct ixgbevf_ring *ring) { u16 ntc = ring->next_to_clean; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index deda74d24075..19062dcf1e80 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -331,15 +331,14 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, * ixgbevf_receive_skb - Send a completed packet up the stack * @q_vector: structure containing interrupt and ring information * @skb: packet to send up - * @status: hardware indication of status of receive * @rx_desc: rx descriptor **/ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, - struct sk_buff *skb, u8 status, + struct sk_buff *skb, union ixgbe_adv_rx_desc *rx_desc) { struct ixgbevf_adapter *adapter = q_vector->adapter; - bool is_vlan = (status & IXGBE_RXD_STAT_VP); + bool is_vlan = !!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); if (is_vlan && test_bit(tag & VLAN_VID_MASK, adapter->active_vlans)) @@ -355,11 +354,10 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, * ixgbevf_rx_skb - Helper function to determine proper Rx method * @q_vector: structure containing interrupt and ring information * @skb: packet to send up - * @status: hardware indication of status of receive * @rx_desc: rx descriptor **/ static void ixgbevf_rx_skb(struct ixgbevf_q_vector *q_vector, - struct sk_buff *skb, u8 status, + struct sk_buff *skb, union ixgbe_adv_rx_desc *rx_desc) { #ifdef CONFIG_NET_RX_BUSY_POLL @@ -372,17 +370,17 @@ static void ixgbevf_rx_skb(struct ixgbevf_q_vector *q_vector, } #endif /* CONFIG_NET_RX_BUSY_POLL */ - ixgbevf_receive_skb(q_vector, skb, status, rx_desc); + ixgbevf_receive_skb(q_vector, skb, rx_desc); } -/** - * ixgbevf_rx_checksum - indicate in skb if hw indicated a good cksum - * @ring: pointer to Rx descriptor ring structure - * @status_err: hardware indication of status of receive +/* ixgbevf_rx_checksum - indicate in skb if hw indicated a good cksum + * @ring: structure containig ring specific data + * @rx_desc: current Rx descriptor being processed * @skb: skb currently being received and modified - **/ + */ static inline void ixgbevf_rx_checksum(struct ixgbevf_ring *ring, - u32 status_err, struct sk_buff *skb) + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) { skb_checksum_none_assert(skb); @@ -391,16 +389,16 @@ static inline void ixgbevf_rx_checksum(struct ixgbevf_ring *ring, return; /* if IP and error */ - if ((status_err & IXGBE_RXD_STAT_IPCS) && - (status_err & IXGBE_RXDADV_ERR_IPE)) { + if (ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) && + ixgbevf_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) { ring->rx_stats.csum_err++; return; } - if (!(status_err & IXGBE_RXD_STAT_L4CS)) + if (!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_L4CS)) return; - if (status_err & IXGBE_RXDADV_ERR_TCPE) { + if (ixgbevf_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { ring->rx_stats.csum_err++; return; } @@ -520,33 +518,29 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_rx_buffer *rx_buffer_info, *next_buffer; struct sk_buff *skb; unsigned int i; - u32 len, staterr; unsigned int total_rx_bytes = 0, total_rx_packets = 0; u16 cleaned_count = ixgbevf_desc_unused(rx_ring); i = rx_ring->next_to_clean; rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - staterr = le32_to_cpu(rx_desc->wb.upper.status_error); rx_buffer_info = &rx_ring->rx_buffer_info[i]; - while (staterr & IXGBE_RXD_STAT_DD) { + while (ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { if (!budget) break; budget--; rmb(); /* read descriptor and rx_buffer_info after status DD */ - len = le16_to_cpu(rx_desc->wb.upper.length); + skb = rx_buffer_info->skb; prefetch(skb->data - NET_IP_ALIGN); rx_buffer_info->skb = NULL; - if (rx_buffer_info->dma) { - dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - rx_buffer_info->dma = 0; - skb_put(skb, len); - } + dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + rx_buffer_info->dma = 0; + skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length)); i++; if (i == rx_ring->count) @@ -558,7 +552,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, next_buffer = &rx_ring->rx_buffer_info[i]; - if (!(staterr & IXGBE_RXD_STAT_EOP)) { + if (!(ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) { skb->next = next_buffer->skb; IXGBE_CB(skb->next)->prev = skb; rx_ring->rx_stats.non_eop_descs++; @@ -576,12 +570,13 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, } /* ERR_MASK will only have valid bits if EOP set */ - if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { + if (unlikely(ixgbevf_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { dev_kfree_skb_irq(skb); goto next_desc; } - ixgbevf_rx_checksum(rx_ring, staterr, skb); + ixgbevf_rx_checksum(rx_ring, rx_desc, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; @@ -600,7 +595,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, goto next_desc; } - ixgbevf_rx_skb(q_vector, skb, staterr, rx_desc); + ixgbevf_rx_skb(q_vector, skb, rx_desc); next_desc: /* return some buffers to hardware, one at a time is too slow */ @@ -612,8 +607,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, /* use prefetched values */ rx_desc = next_rxd; rx_buffer_info = &rx_ring->rx_buffer_info[i]; - - staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } rx_ring->next_to_clean = i; -- GitLab From dff80520335ac79eed1cd62fcbb7156a6557d94e Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:25 +0000 Subject: [PATCH 5601/9457] ixgbevf: Combine the logic for post Rx processing into single function This patch cleans up ixgbevf_clean_rx_irq() by merging several similar operations into a new function - ixgbevf_process_skb_fields(). CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 4 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 68 ++++++++++--------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 5f7d2f3c738d..90d5751b7f92 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -346,8 +346,10 @@ static inline void ixgbevf_write_tail(struct ixgbevf_ring *ring, u32 value) /* board specific private data structure */ struct ixgbevf_adapter { - struct timer_list watchdog_timer; + /* this field must be first, see ixgbevf_process_skb_fields */ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; + + struct timer_list watchdog_timer; struct work_struct reset_task; struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 19062dcf1e80..36b005e58930 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -327,38 +327,13 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, return !!budget; } -/** - * ixgbevf_receive_skb - Send a completed packet up the stack - * @q_vector: structure containing interrupt and ring information - * @skb: packet to send up - * @rx_desc: rx descriptor - **/ -static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, - struct sk_buff *skb, - union ixgbe_adv_rx_desc *rx_desc) -{ - struct ixgbevf_adapter *adapter = q_vector->adapter; - bool is_vlan = !!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_VP); - u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - - if (is_vlan && test_bit(tag & VLAN_VID_MASK, adapter->active_vlans)) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tag); - - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) - napi_gro_receive(&q_vector->napi, skb); - else - netif_rx(skb); -} - /** * ixgbevf_rx_skb - Helper function to determine proper Rx method * @q_vector: structure containing interrupt and ring information * @skb: packet to send up - * @rx_desc: rx descriptor **/ static void ixgbevf_rx_skb(struct ixgbevf_q_vector *q_vector, - struct sk_buff *skb, - union ixgbe_adv_rx_desc *rx_desc) + struct sk_buff *skb) { #ifdef CONFIG_NET_RX_BUSY_POLL skb_mark_napi_id(skb, &q_vector->napi); @@ -369,8 +344,10 @@ static void ixgbevf_rx_skb(struct ixgbevf_q_vector *q_vector, return; } #endif /* CONFIG_NET_RX_BUSY_POLL */ - - ixgbevf_receive_skb(q_vector, skb, rx_desc); + if (!(q_vector->adapter->flags & IXGBE_FLAG_IN_NETPOLL)) + napi_gro_receive(&q_vector->napi, skb); + else + netif_rx(skb); } /* ixgbevf_rx_checksum - indicate in skb if hw indicated a good cksum @@ -407,6 +384,32 @@ static inline void ixgbevf_rx_checksum(struct ixgbevf_ring *ring, skb->ip_summed = CHECKSUM_UNNECESSARY; } +/* ixgbevf_process_skb_fields - Populate skb header fields from Rx descriptor + * @rx_ring: rx descriptor ring packet is being transacted on + * @rx_desc: pointer to the EOP Rx descriptor + * @skb: pointer to current skb being populated + * + * This function checks the ring, descriptor, and packet information in + * order to populate the checksum, VLAN, protocol, and other fields within + * the skb. + */ +static void ixgbevf_process_skb_fields(struct ixgbevf_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + ixgbevf_rx_checksum(rx_ring, rx_desc, skb); + + if (ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { + u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); + unsigned long *active_vlans = netdev_priv(rx_ring->netdev); + + if (test_bit(vid & VLAN_VID_MASK, active_vlans)) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid); + } + + skb->protocol = eth_type_trans(skb, rx_ring->netdev); +} + static bool ixgbevf_alloc_mapped_skb(struct ixgbevf_ring *rx_ring, struct ixgbevf_rx_buffer *bi) { @@ -576,14 +579,10 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, goto next_desc; } - ixgbevf_rx_checksum(rx_ring, rx_desc, skb); - /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; total_rx_packets++; - skb->protocol = eth_type_trans(skb, rx_ring->netdev); - /* Workaround hardware that can't do proper VEPA multicast * source pruning. */ @@ -595,7 +594,10 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, goto next_desc; } - ixgbevf_rx_skb(q_vector, skb, rx_desc); + /* populate checksum, VLAN, and protocol */ + ixgbevf_process_skb_fields(rx_ring, rx_desc, skb); + + ixgbevf_rx_skb(q_vector, skb); next_desc: /* return some buffers to hardware, one at a time is too slow */ -- GitLab From b97fe3b1aff8195e689b6b07fa5c00e372d2426f Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:30 +0000 Subject: [PATCH 5602/9457] ixgbevf: Cleanup variable usage, improve stack performance This change is meant to help cleanup the usage of temporary variables within the Rx hot-path by removing unnecessary variables and reducing the scope of variables that do not need to exist outside the main loop. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 36b005e58930..f864da991c47 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -517,26 +517,28 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_ring *rx_ring, int budget) { - union ixgbe_adv_rx_desc *rx_desc, *next_rxd; - struct ixgbevf_rx_buffer *rx_buffer_info, *next_buffer; - struct sk_buff *skb; + union ixgbe_adv_rx_desc *rx_desc; unsigned int i; unsigned int total_rx_bytes = 0, total_rx_packets = 0; u16 cleaned_count = ixgbevf_desc_unused(rx_ring); i = rx_ring->next_to_clean; rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - rx_buffer_info = &rx_ring->rx_buffer_info[i]; while (ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { + union ixgbe_adv_rx_desc *next_rxd; + struct ixgbevf_rx_buffer *rx_buffer_info; + struct sk_buff *skb; + if (!budget) break; budget--; rmb(); /* read descriptor and rx_buffer_info after status DD */ + rx_buffer_info = &rx_ring->rx_buffer_info[i]; skb = rx_buffer_info->skb; - prefetch(skb->data - NET_IP_ALIGN); + prefetch(skb->data); rx_buffer_info->skb = NULL; dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, @@ -545,18 +547,17 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, rx_buffer_info->dma = 0; skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length)); + cleaned_count++; + i++; if (i == rx_ring->count) i = 0; next_rxd = IXGBEVF_RX_DESC(rx_ring, i); prefetch(next_rxd); - cleaned_count++; - - next_buffer = &rx_ring->rx_buffer_info[i]; if (!(ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) { - skb->next = next_buffer->skb; + skb->next = rx_ring->rx_buffer_info[i].skb; IXGBE_CB(skb->next)->prev = skb; rx_ring->rx_stats.non_eop_descs++; goto next_desc; @@ -609,6 +610,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, /* use prefetched values */ rx_desc = next_rxd; rx_buffer_info = &rx_ring->rx_buffer_info[i]; + rx_desc = IXGBEVF_RX_DESC(rx_ring, i); } rx_ring->next_to_clean = i; -- GitLab From 0579eefca75304886cfadeec593d159125badfb4 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:35 +0000 Subject: [PATCH 5603/9457] ixgbevf: reorder main loop in ixgbe_clean_rx_irq to allow for do/while/continue This change allows us to go from a loop based on the descriptor to one primarily based on the budget. The advantage to this is that we can avoid carrying too many values from one iteration to the next. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index f864da991c47..220699285021 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -517,35 +517,48 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_ring *rx_ring, int budget) { - union ixgbe_adv_rx_desc *rx_desc; unsigned int i; unsigned int total_rx_bytes = 0, total_rx_packets = 0; u16 cleaned_count = ixgbevf_desc_unused(rx_ring); i = rx_ring->next_to_clean; - rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - while (ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { - union ixgbe_adv_rx_desc *next_rxd; - struct ixgbevf_rx_buffer *rx_buffer_info; + do { + union ixgbe_adv_rx_desc *rx_desc, *next_rxd; + struct ixgbevf_rx_buffer *rx_buffer; struct sk_buff *skb; - if (!budget) + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { + ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); + cleaned_count = 0; + } + + rx_desc = IXGBEVF_RX_DESC(rx_ring, i); + rx_buffer = &rx_ring->rx_buffer_info[i]; + + if (!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) break; - budget--; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + /* This memory barrier is needed to keep us from reading + * any other fields out of the rx_desc until we know the + * RXD_STAT_DD bit is set + */ + rmb(); - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - skb = rx_buffer_info->skb; + skb = rx_buffer->skb; prefetch(skb->data); - rx_buffer_info->skb = NULL; - dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, + /* pull the header of the skb in */ + __skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length)); + + dma_unmap_single(rx_ring->dev, rx_buffer->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); - rx_buffer_info->dma = 0; - skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length)); + + /* clear skb reference in buffer info structure */ + rx_buffer->skb = NULL; + rx_buffer->dma = 0; cleaned_count++; @@ -560,7 +573,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, skb->next = rx_ring->rx_buffer_info[i].skb; IXGBE_CB(skb->next)->prev = skb; rx_ring->rx_stats.non_eop_descs++; - goto next_desc; + continue; } /* we should not be chaining buffers, if we did drop the skb */ @@ -570,14 +583,14 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, skb = IXGBE_CB(skb)->prev; dev_kfree_skb(this); } while (skb); - goto next_desc; + continue; } /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(ixgbevf_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { dev_kfree_skb_irq(skb); - goto next_desc; + continue; } /* probably a little skewed due to removing CRC */ @@ -592,7 +605,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, ether_addr_equal(rx_ring->netdev->dev_addr, eth_hdr(skb)->h_source)) { dev_kfree_skb_irq(skb); - goto next_desc; + continue; } /* populate checksum, VLAN, and protocol */ @@ -600,18 +613,9 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, ixgbevf_rx_skb(q_vector, skb); -next_desc: - /* return some buffers to hardware, one at a time is too slow */ - if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { - ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); - cleaned_count = 0; - } - - /* use prefetched values */ - rx_desc = next_rxd; - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - } + /* update budget accounting */ + budget--; + } while (likely(budget)); rx_ring->next_to_clean = i; u64_stats_update_begin(&rx_ring->syncp); -- GitLab From 4b95fe3de7f25402b22cd4d8b20b99cce1979309 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:41 +0000 Subject: [PATCH 5604/9457] ixgbevf: Update Rx next to clean in real time Since the next_to_clean value is only accessed by the Rx interrupt handler we can save on stack space by just storing our updated values back in next_to_clean instead of using the stack variable i. This should help to reduce stack space and we can further collapse the size of the function. Also removed non_eop_descs counter as it was never shown in the stats. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 2 - .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 55 ++++++++++++------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 90d5751b7f92..72a354b2128e 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -79,7 +79,6 @@ struct ixgbevf_tx_queue_stats { }; struct ixgbevf_rx_queue_stats { - u64 non_eop_descs; u64 alloc_rx_page_failed; u64 alloc_rx_buff_failed; u64 csum_err; @@ -372,7 +371,6 @@ struct ixgbevf_adapter { struct ixgbevf_ring *rx_ring[MAX_TX_QUEUES]; /* One per active queue */ u64 hw_csum_rx_error; u64 hw_rx_no_dma_resources; - u64 non_eop_descs; int num_msix_vectors; u32 alloc_rx_page_failed; u32 alloc_rx_buff_failed; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 220699285021..20bebd212ac2 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -410,6 +410,35 @@ static void ixgbevf_process_skb_fields(struct ixgbevf_ring *rx_ring, skb->protocol = eth_type_trans(skb, rx_ring->netdev); } +/** + * ixgbevf_is_non_eop - process handling of non-EOP buffers + * @rx_ring: Rx ring being processed + * @rx_desc: Rx descriptor for current buffer + * @skb: current socket buffer containing buffer in progress + * + * This function updates next to clean. If the buffer is an EOP buffer + * this function exits returning false, otherwise it will place the + * sk_buff in the next buffer to be chained and return true indicating + * that this is in fact a non-EOP buffer. + **/ +static bool ixgbevf_is_non_eop(struct ixgbevf_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + u32 ntc = rx_ring->next_to_clean + 1; + + /* fetch, update, and store next to clean */ + ntc = (ntc < rx_ring->count) ? ntc : 0; + rx_ring->next_to_clean = ntc; + + prefetch(IXGBEVF_RX_DESC(rx_ring, ntc)); + + if (likely(ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) + return false; + + return true; +} + static bool ixgbevf_alloc_mapped_skb(struct ixgbevf_ring *rx_ring, struct ixgbevf_rx_buffer *bi) { @@ -517,16 +546,14 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_ring *rx_ring, int budget) { - unsigned int i; unsigned int total_rx_bytes = 0, total_rx_packets = 0; u16 cleaned_count = ixgbevf_desc_unused(rx_ring); - i = rx_ring->next_to_clean; - do { - union ixgbe_adv_rx_desc *rx_desc, *next_rxd; + union ixgbe_adv_rx_desc *rx_desc; struct ixgbevf_rx_buffer *rx_buffer; struct sk_buff *skb; + u16 ntc; /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { @@ -534,8 +561,9 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, cleaned_count = 0; } - rx_desc = IXGBEVF_RX_DESC(rx_ring, i); - rx_buffer = &rx_ring->rx_buffer_info[i]; + ntc = rx_ring->next_to_clean; + rx_desc = IXGBEVF_RX_DESC(rx_ring, ntc); + rx_buffer = &rx_ring->rx_buffer_info[ntc]; if (!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) break; @@ -562,19 +590,9 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, cleaned_count++; - i++; - if (i == rx_ring->count) - i = 0; - - next_rxd = IXGBEVF_RX_DESC(rx_ring, i); - prefetch(next_rxd); - - if (!(ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) { - skb->next = rx_ring->rx_buffer_info[i].skb; - IXGBE_CB(skb->next)->prev = skb; - rx_ring->rx_stats.non_eop_descs++; + /* place incomplete frames back on ring for completion */ + if (ixgbevf_is_non_eop(rx_ring, rx_desc, skb)) continue; - } /* we should not be chaining buffers, if we did drop the skb */ if (IXGBE_CB(skb)->prev) { @@ -617,7 +635,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, budget--; } while (likely(budget)); - rx_ring->next_to_clean = i; u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; -- GitLab From bad17234ba702a50aeec50ab04724ee58af89607 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 21 Nov 2014 02:57:15 +0000 Subject: [PATCH 5605/9457] ixgbevf: Change receive model to use double buffered page based receives This patch changes the basic receive path for ixgbevf so that instead of receiving the data into an skb it is received into a double buffered page. The main change is that the receives will be done in pages only and then pull the header out of the page and copy it into the sk_buff data. This has the advantages of reduced cache misses and improved performance on IOMMU enabled systems. v2: - added pfmemalloc check to a new function for reusable page - moved atomic_inc outside of #if/else in ixgbevf_add_rx_frag() - reverted the removal of the api check in ixgbevf_change_mtu() CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 24 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 444 +++++++++++++----- 2 files changed, 334 insertions(+), 134 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 72a354b2128e..666049849d3f 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -58,8 +58,9 @@ struct ixgbevf_tx_buffer { }; struct ixgbevf_rx_buffer { - struct sk_buff *skb; dma_addr_t dma; + struct page *page; + unsigned int page_offset; }; struct ixgbevf_stats { @@ -91,9 +92,10 @@ struct ixgbevf_ring { void *desc; /* descriptor ring memory */ dma_addr_t dma; /* phys. address of descriptor ring */ unsigned int size; /* length in bytes */ - unsigned int count; /* amount of descriptors */ - unsigned int next_to_use; - unsigned int next_to_clean; + u16 count; /* amount of descriptors */ + u16 next_to_use; + u16 next_to_clean; + u16 next_to_alloc; union { struct ixgbevf_tx_buffer *tx_buffer_info; @@ -109,12 +111,11 @@ struct ixgbevf_ring { u64 hw_csum_rx_error; u8 __iomem *tail; + struct sk_buff *skb; u16 reg_idx; /* holds the special value that gets the hardware register * offset associated with this ring, which is different * for DCB and RSS modes */ - - u16 rx_buf_len; int queue_index; /* needed for multiqueue queue management */ }; @@ -133,12 +134,10 @@ struct ixgbevf_ring { /* Supported Rx Buffer Sizes */ #define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */ -#define IXGBEVF_RXBUFFER_2K 2048 -#define IXGBEVF_RXBUFFER_4K 4096 -#define IXGBEVF_RXBUFFER_8K 8192 -#define IXGBEVF_RXBUFFER_10K 10240 +#define IXGBEVF_RXBUFFER_2048 2048 #define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256 +#define IXGBEVF_RX_BUFSZ IXGBEVF_RXBUFFER_2048 #define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) @@ -430,11 +429,6 @@ enum ixbgevf_state_t { __IXGBEVF_WORK_INIT, }; -struct ixgbevf_cb { - struct sk_buff *prev; -}; -#define IXGBE_CB(skb) ((struct ixgbevf_cb *)(skb)->cb) - enum ixgbevf_boards { board_82599_vf, board_X540_vf, diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 20bebd212ac2..07222b84026e 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -422,8 +422,7 @@ static void ixgbevf_process_skb_fields(struct ixgbevf_ring *rx_ring, * that this is in fact a non-EOP buffer. **/ static bool ixgbevf_is_non_eop(struct ixgbevf_ring *rx_ring, - union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb) + union ixgbe_adv_rx_desc *rx_desc) { u32 ntc = rx_ring->next_to_clean + 1; @@ -439,37 +438,40 @@ static bool ixgbevf_is_non_eop(struct ixgbevf_ring *rx_ring, return true; } -static bool ixgbevf_alloc_mapped_skb(struct ixgbevf_ring *rx_ring, - struct ixgbevf_rx_buffer *bi) +static bool ixgbevf_alloc_mapped_page(struct ixgbevf_ring *rx_ring, + struct ixgbevf_rx_buffer *bi) { - struct sk_buff *skb = bi->skb; + struct page *page = bi->page; dma_addr_t dma = bi->dma; - if (unlikely(skb)) + /* since we are recycling buffers we should seldom need to alloc */ + if (likely(page)) return true; - skb = netdev_alloc_skb_ip_align(rx_ring->netdev, - rx_ring->rx_buf_len); - if (unlikely(!skb)) { - rx_ring->rx_stats.alloc_rx_buff_failed++; + /* alloc new page for storage */ + page = dev_alloc_page(); + if (unlikely(!page)) { + rx_ring->rx_stats.alloc_rx_page_failed++; return false; } - dma = dma_map_single(rx_ring->dev, skb->data, - rx_ring->rx_buf_len, DMA_FROM_DEVICE); + /* map page for use */ + dma = dma_map_page(rx_ring->dev, page, 0, + PAGE_SIZE, DMA_FROM_DEVICE); /* if mapping failed free memory back to system since * there isn't much point in holding memory we can't use */ if (dma_mapping_error(rx_ring->dev, dma)) { - dev_kfree_skb_any(skb); + __free_page(page); rx_ring->rx_stats.alloc_rx_buff_failed++; return false; } - bi->skb = skb; bi->dma = dma; + bi->page = page; + bi->page_offset = 0; return true; } @@ -495,13 +497,13 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring, i -= rx_ring->count; do { - if (!ixgbevf_alloc_mapped_skb(rx_ring, bi)) + if (!ixgbevf_alloc_mapped_page(rx_ring, bi)) break; /* Refresh the desc even if pkt_addr didn't change * because each write-back erases this info. */ - rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); rx_desc++; bi++; @@ -524,6 +526,9 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring, /* record the next descriptor to use */ rx_ring->next_to_use = i; + /* update next to alloc since we have filled the ring */ + rx_ring->next_to_alloc = i; + /* Force memory writes to complete before letting h/w * know there are new descriptors to fetch. (Only * applicable for weak-ordered memory model archs, @@ -534,6 +539,260 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring, } } +/* ixgbevf_pull_tail - ixgbevf specific version of skb_pull_tail + * @rx_ring: rx descriptor ring packet is being transacted on + * @skb: pointer to current skb being adjusted + * + * This function is an ixgbevf specific version of __pskb_pull_tail. The + * main difference between this version and the original function is that + * this function can make several assumptions about the state of things + * that allow for significant optimizations versus the standard function. + * As a result we can do things like drop a frag and maintain an accurate + * truesize for the skb. + */ +static void ixgbevf_pull_tail(struct ixgbevf_ring *rx_ring, + struct sk_buff *skb) +{ + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; + unsigned char *va; + unsigned int pull_len; + + /* it is valid to use page_address instead of kmap since we are + * working with pages allocated out of the lomem pool per + * alloc_page(GFP_ATOMIC) + */ + va = skb_frag_address(frag); + + /* we need the header to contain the greater of either ETH_HLEN or + * 60 bytes if the skb->len is less than 60 for skb_pad. + */ + pull_len = eth_get_headlen(va, IXGBEVF_RX_HDR_SIZE); + + /* align pull length to size of long to optimize memcpy performance */ + skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); + + /* update all of the pointers */ + skb_frag_size_sub(frag, pull_len); + frag->page_offset += pull_len; + skb->data_len -= pull_len; + skb->tail += pull_len; +} + +/* ixgbevf_cleanup_headers - Correct corrupted or empty headers + * @rx_ring: rx descriptor ring packet is being transacted on + * @rx_desc: pointer to the EOP Rx descriptor + * @skb: pointer to current skb being fixed + * + * Check for corrupted packet headers caused by senders on the local L2 + * embedded NIC switch not setting up their Tx Descriptors right. These + * should be very rare. + * + * Also address the case where we are pulling data in on pages only + * and as such no data is present in the skb header. + * + * In addition if skb is not at least 60 bytes we need to pad it so that + * it is large enough to qualify as a valid Ethernet frame. + * + * Returns true if an error was encountered and skb was freed. + */ +static bool ixgbevf_cleanup_headers(struct ixgbevf_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + /* verify that the packet does not have any known errors */ + if (unlikely(ixgbevf_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { + struct net_device *netdev = rx_ring->netdev; + + if (!(netdev->features & NETIF_F_RXALL)) { + dev_kfree_skb_any(skb); + return true; + } + } + + /* place header in linear portion of buffer */ + if (skb_is_nonlinear(skb)) + ixgbevf_pull_tail(rx_ring, skb); + + /* if skb_pad returns an error the skb was freed */ + if (unlikely(skb->len < 60)) { + int pad_len = 60 - skb->len; + + if (skb_pad(skb, pad_len)) + return true; + __skb_put(skb, pad_len); + } + + return false; +} + +/* ixgbevf_reuse_rx_page - page flip buffer and store it back on the ring + * @rx_ring: rx descriptor ring to store buffers on + * @old_buff: donor buffer to have page reused + * + * Synchronizes page for reuse by the adapter + */ +static void ixgbevf_reuse_rx_page(struct ixgbevf_ring *rx_ring, + struct ixgbevf_rx_buffer *old_buff) +{ + struct ixgbevf_rx_buffer *new_buff; + u16 nta = rx_ring->next_to_alloc; + + new_buff = &rx_ring->rx_buffer_info[nta]; + + /* update, and store next to alloc */ + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + /* transfer page from old buffer to new buffer */ + new_buff->page = old_buff->page; + new_buff->dma = old_buff->dma; + new_buff->page_offset = old_buff->page_offset; + + /* sync the buffer for use by the device */ + dma_sync_single_range_for_device(rx_ring->dev, new_buff->dma, + new_buff->page_offset, + IXGBEVF_RX_BUFSZ, + DMA_FROM_DEVICE); +} + +static inline bool ixgbevf_page_is_reserved(struct page *page) +{ + return (page_to_nid(page) != numa_mem_id()) || page->pfmemalloc; +} + +/* ixgbevf_add_rx_frag - Add contents of Rx buffer to sk_buff + * @rx_ring: rx descriptor ring to transact packets on + * @rx_buffer: buffer containing page to add + * @rx_desc: descriptor containing length of buffer written by hardware + * @skb: sk_buff to place the data into + * + * This function will add the data contained in rx_buffer->page to the skb. + * This is done either through a direct copy if the data in the buffer is + * less than the skb header size, otherwise it will just attach the page as + * a frag to the skb. + * + * The function will then update the page offset if necessary and return + * true if the buffer can be reused by the adapter. + */ +static bool ixgbevf_add_rx_frag(struct ixgbevf_ring *rx_ring, + struct ixgbevf_rx_buffer *rx_buffer, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct page *page = rx_buffer->page; + unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); +#if (PAGE_SIZE < 8192) + unsigned int truesize = IXGBEVF_RX_BUFSZ; +#else + unsigned int truesize = ALIGN(size, L1_CACHE_BYTES); +#endif + + if ((size <= IXGBEVF_RX_HDR_SIZE) && !skb_is_nonlinear(skb)) { + unsigned char *va = page_address(page) + rx_buffer->page_offset; + + memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); + + /* page is not reserved, we can reuse buffer as is */ + if (likely(!ixgbevf_page_is_reserved(page))) + return true; + + /* this page cannot be reused so discard it */ + put_page(page); + return false; + } + + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + rx_buffer->page_offset, size, truesize); + + /* avoid re-using remote pages */ + if (unlikely(ixgbevf_page_is_reserved(page))) + return false; + +#if (PAGE_SIZE < 8192) + /* if we are only owner of page we can reuse it */ + if (unlikely(page_count(page) != 1)) + return false; + + /* flip page offset to other buffer */ + rx_buffer->page_offset ^= IXGBEVF_RX_BUFSZ; + +#else + /* move offset up to the next cache line */ + rx_buffer->page_offset += truesize; + + if (rx_buffer->page_offset > (PAGE_SIZE - IXGBEVF_RX_BUFSZ)) + return false; + +#endif + /* Even if we own the page, we are not allowed to use atomic_set() + * This would break get_page_unless_zero() users. + */ + atomic_inc(&page->_count); + + return true; +} + +static struct sk_buff *ixgbevf_fetch_rx_buffer(struct ixgbevf_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct ixgbevf_rx_buffer *rx_buffer; + struct page *page; + + rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + page = rx_buffer->page; + prefetchw(page); + + if (likely(!skb)) { + void *page_addr = page_address(page) + + rx_buffer->page_offset; + + /* prefetch first cache line of first page */ + prefetch(page_addr); +#if L1_CACHE_BYTES < 128 + prefetch(page_addr + L1_CACHE_BYTES); +#endif + + /* allocate a skb to store the frags */ + skb = netdev_alloc_skb_ip_align(rx_ring->netdev, + IXGBEVF_RX_HDR_SIZE); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + return NULL; + } + + /* we will be copying header into skb->data in + * pskb_may_pull so it is in our interest to prefetch + * it now to avoid a possible cache miss + */ + prefetchw(skb->data); + } + + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + IXGBEVF_RX_BUFSZ, + DMA_FROM_DEVICE); + + /* pull page into skb */ + if (ixgbevf_add_rx_frag(rx_ring, rx_buffer, rx_desc, skb)) { + /* hand second half of page back to the ring */ + ixgbevf_reuse_rx_page(rx_ring, rx_buffer); + } else { + /* we are not reusing the buffer so unmap it */ + dma_unmap_page(rx_ring->dev, rx_buffer->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + } + + /* clear contents of buffer_info */ + rx_buffer->dma = 0; + rx_buffer->page = NULL; + + return skb; +} + static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter, u32 qmask) { @@ -548,12 +807,10 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, { unsigned int total_rx_bytes = 0, total_rx_packets = 0; u16 cleaned_count = ixgbevf_desc_unused(rx_ring); + struct sk_buff *skb = rx_ring->skb; do { union ixgbe_adv_rx_desc *rx_desc; - struct ixgbevf_rx_buffer *rx_buffer; - struct sk_buff *skb; - u16 ntc; /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBEVF_RX_BUFFER_WRITE) { @@ -561,9 +818,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, cleaned_count = 0; } - ntc = rx_ring->next_to_clean; - rx_desc = IXGBEVF_RX_DESC(rx_ring, ntc); - rx_buffer = &rx_ring->rx_buffer_info[ntc]; + rx_desc = IXGBEVF_RX_DESC(rx_ring, rx_ring->next_to_clean); if (!ixgbevf_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) break; @@ -574,40 +829,22 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, */ rmb(); - skb = rx_buffer->skb; - prefetch(skb->data); - - /* pull the header of the skb in */ - __skb_put(skb, le16_to_cpu(rx_desc->wb.upper.length)); + /* retrieve a buffer from the ring */ + skb = ixgbevf_fetch_rx_buffer(rx_ring, rx_desc, skb); - dma_unmap_single(rx_ring->dev, rx_buffer->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - - /* clear skb reference in buffer info structure */ - rx_buffer->skb = NULL; - rx_buffer->dma = 0; + /* exit if we failed to retrieve a buffer */ + if (!skb) + break; cleaned_count++; - /* place incomplete frames back on ring for completion */ - if (ixgbevf_is_non_eop(rx_ring, rx_desc, skb)) - continue; - - /* we should not be chaining buffers, if we did drop the skb */ - if (IXGBE_CB(skb)->prev) { - do { - struct sk_buff *this = skb; - skb = IXGBE_CB(skb)->prev; - dev_kfree_skb(this); - } while (skb); + /* fetch next buffer in frame if non-eop */ + if (ixgbevf_is_non_eop(rx_ring, rx_desc)) continue; - } - /* ERR_MASK will only have valid bits if EOP set */ - if (unlikely(ixgbevf_test_staterr(rx_desc, - IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { - dev_kfree_skb_irq(skb); + /* verify the packet layout is correct */ + if (ixgbevf_cleanup_headers(rx_ring, rx_desc, skb)) { + skb = NULL; continue; } @@ -631,10 +868,16 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, ixgbevf_rx_skb(q_vector, skb); + /* reset skb pointer */ + skb = NULL; + /* update budget accounting */ budget--; } while (likely(budget)); + /* place incomplete frames back on ring for completion */ + rx_ring->skb = skb; + u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; @@ -642,9 +885,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, q_vector->rx.total_packets += total_rx_packets; q_vector->rx.total_bytes += total_rx_bytes; - if (cleaned_count) - ixgbevf_alloc_rx_buffers(rx_ring, cleaned_count); - return total_rx_packets; } @@ -1275,19 +1515,15 @@ static void ixgbevf_configure_tx(struct ixgbevf_adapter *adapter) static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index) { - struct ixgbevf_ring *rx_ring; struct ixgbe_hw *hw = &adapter->hw; u32 srrctl; - rx_ring = adapter->rx_ring[index]; - srrctl = IXGBE_SRRCTL_DROP_EN; + srrctl |= IXGBEVF_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT; + srrctl |= IXGBEVF_RX_BUFSZ >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >> - IXGBE_SRRCTL_BSIZEPKT_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl); } @@ -1306,40 +1542,6 @@ static void ixgbevf_setup_psrtype(struct ixgbevf_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); } -static void ixgbevf_set_rx_buffer_len(struct ixgbevf_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int i; - u16 rx_buf_len; - - /* notify the PF of our intent to use this size of frame */ - ixgbevf_rlpml_set_vf(hw, max_frame); - - /* PF will allow an extra 4 bytes past for vlan tagged frames */ - max_frame += VLAN_HLEN; - - /* - * Allocate buffer sizes that fit well into 32K and - * take into account max frame size of 9.5K - */ - if ((hw->mac.type == ixgbe_mac_X540_vf) && - (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE)) - rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; - else if (max_frame <= IXGBEVF_RXBUFFER_2K) - rx_buf_len = IXGBEVF_RXBUFFER_2K; - else if (max_frame <= IXGBEVF_RXBUFFER_4K) - rx_buf_len = IXGBEVF_RXBUFFER_4K; - else if (max_frame <= IXGBEVF_RXBUFFER_8K) - rx_buf_len = IXGBEVF_RXBUFFER_8K; - else - rx_buf_len = IXGBEVF_RXBUFFER_10K; - - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i]->rx_buf_len = rx_buf_len; -} - #define IXGBEVF_MAX_RX_DESC_POLL 10 static void ixgbevf_disable_rx_queue(struct ixgbevf_adapter *adapter, struct ixgbevf_ring *ring) @@ -1417,12 +1619,13 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter, /* reset ntu and ntc to place SW in sync with hardwdare */ ring->next_to_clean = 0; ring->next_to_use = 0; + ring->next_to_alloc = 0; ixgbevf_configure_srrctl(adapter, reg_idx); - /* prevent DMA from exceeding buffer space available */ - rxdctl &= ~IXGBE_RXDCTL_RLPMLMASK; - rxdctl |= ring->rx_buf_len | IXGBE_RXDCTL_RLPML_EN; + /* allow any size packet since we can handle overflow */ + rxdctl &= ~IXGBE_RXDCTL_RLPML_EN; + rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl); @@ -1439,11 +1642,13 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter, static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) { int i; + struct ixgbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; ixgbevf_setup_psrtype(adapter); - /* set_rx_buffer_len must be called before ring initialization */ - ixgbevf_set_rx_buffer_len(adapter); + /* notify the PF of our intent to use this size of frame */ + ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN); /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ @@ -1748,32 +1953,32 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter) **/ static void ixgbevf_clean_rx_ring(struct ixgbevf_ring *rx_ring) { + struct device *dev = rx_ring->dev; unsigned long size; unsigned int i; + /* Free Rx ring sk_buff */ + if (rx_ring->skb) { + dev_kfree_skb(rx_ring->skb); + rx_ring->skb = NULL; + } + + /* ring already cleared, nothing to do */ if (!rx_ring->rx_buffer_info) return; - /* Free all the Rx ring sk_buffs */ + /* Free all the Rx ring pages */ for (i = 0; i < rx_ring->count; i++) { - struct ixgbevf_rx_buffer *rx_buffer_info; + struct ixgbevf_rx_buffer *rx_buffer; - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - if (rx_buffer_info->dma) { - dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - rx_buffer_info->dma = 0; - } - if (rx_buffer_info->skb) { - struct sk_buff *skb = rx_buffer_info->skb; - rx_buffer_info->skb = NULL; - do { - struct sk_buff *this = skb; - skb = IXGBE_CB(skb)->prev; - dev_kfree_skb(this); - } while (skb); - } + rx_buffer = &rx_ring->rx_buffer_info[i]; + if (rx_buffer->dma) + dma_unmap_page(dev, rx_buffer->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + rx_buffer->dma = 0; + if (rx_buffer->page) + __free_page(rx_buffer->page); + rx_buffer->page = NULL; } size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; @@ -3320,6 +3525,7 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; @@ -3337,13 +3543,13 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) if ((new_mtu < 68) || (max_frame > max_possible_frame)) return -EINVAL; - hw_dbg(&adapter->hw, "changing MTU from %d to %d\n", + hw_dbg(hw, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; - if (netif_running(netdev)) - ixgbevf_reinit_locked(adapter); + /* notify the PF of our intent to use this size of frame */ + ixgbevf_rlpml_set_vf(hw, max_frame); return 0; } -- GitLab From 6622402a72580afee68e961e37020894dedbecb6 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:51 +0000 Subject: [PATCH 5606/9457] ixgbevf: compare total_rx_packets and budget in ixgbevf_clean_rx_irq total_rx_packets is the number of packets we had cleaned, and budget is the total number of packets that we could clean per poll. Instead of altering both of these values we can save ourselves one write to memory by just comparing total_rx_packets to the budget and as long as we are less than budget we continue cleaning. Also change the do{}while logic to while{} in order to avoid processing packets when budget is 0. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 07222b84026e..70a2b8fe40ba 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -809,7 +809,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, u16 cleaned_count = ixgbevf_desc_unused(rx_ring); struct sk_buff *skb = rx_ring->skb; - do { + while (likely(total_rx_packets < budget)) { union ixgbe_adv_rx_desc *rx_desc; /* return some buffers to hardware, one at a time is too slow */ @@ -850,7 +850,6 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; - total_rx_packets++; /* Workaround hardware that can't do proper VEPA multicast * source pruning. @@ -872,8 +871,8 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, skb = NULL; /* update budget accounting */ - budget--; - } while (likely(budget)); + total_rx_packets++; + } /* place incomplete frames back on ring for completion */ rx_ring->skb = skb; -- GitLab From 688ff32db2f7e7074df4eb6871afa65dee41c98f Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 8 Nov 2014 01:39:56 +0000 Subject: [PATCH 5607/9457] ixgbevf: add netpoll support This patch adds ixgbevf_netpoll() a callback for .ndo_poll_controller to allow for the VF interface to be used with netconsole. CC: Alexander Duyck Signed-off-by: Emil Tantilov Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 2 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 29 +++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 666049849d3f..bb6726cbeb86 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -379,7 +379,7 @@ struct ixgbevf_adapter { */ u32 flags; #define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1) -#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 1) + #define IXGBEVF_FLAG_QUEUE_RESET_REQUESTED (u32)(1 << 2) struct msix_entry *msix_entries; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 70a2b8fe40ba..755f71f07ae1 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -344,10 +344,8 @@ static void ixgbevf_rx_skb(struct ixgbevf_q_vector *q_vector, return; } #endif /* CONFIG_NET_RX_BUSY_POLL */ - if (!(q_vector->adapter->flags & IXGBE_FLAG_IN_NETPOLL)) - napi_gro_receive(&q_vector->napi, skb); - else - netif_rx(skb); + + napi_gro_receive(&q_vector->napi, skb); } /* ixgbevf_rx_checksum - indicate in skb if hw indicated a good cksum @@ -919,12 +917,10 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) else per_ring_budget = budget; - adapter->flags |= IXGBE_FLAG_IN_NETPOLL; ixgbevf_for_each_ring(ring, q_vector->rx) clean_complete &= (ixgbevf_clean_rx_irq(q_vector, ring, per_ring_budget) < per_ring_budget); - adapter->flags &= ~IXGBE_FLAG_IN_NETPOLL; #ifdef CONFIG_NET_RX_BUSY_POLL ixgbevf_qv_unlock_napi(q_vector); @@ -3553,6 +3549,24 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +/* Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void ixgbevf_netpoll(struct net_device *netdev) +{ + struct ixgbevf_adapter *adapter = netdev_priv(netdev); + int i; + + /* if interface is down do nothing */ + if (test_bit(__IXGBEVF_DOWN, &adapter->state)) + return; + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbevf_msix_clean_rings(0, adapter->q_vector[i]); +} +#endif /* CONFIG_NET_POLL_CONTROLLER */ + static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -3689,6 +3703,9 @@ static const struct net_device_ops ixgbevf_netdev_ops = { #ifdef CONFIG_NET_RX_BUSY_POLL .ndo_busy_poll = ixgbevf_busy_poll_recv, #endif +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ixgbevf_netpoll, +#endif }; static void ixgbevf_assign_netdev_ops(struct net_device *dev) -- GitLab From 1001dc3739a9b29946ff595eb4b02a1082ad4e7b Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 20:02:19 +0000 Subject: [PATCH 5608/9457] i40e: don't overload fields Overloading the msg_size field in the arq_event_info struct is just a bad idea. It leads to repeated bugs when the structure is used in a loop, since the input value (buffer size) is overwritten by the output value (actual message length). Fix this by splitting the field into two and renaming to indicate the actual function of each field. Since the arq_event struct has now changed, we need to change the drivers to support this. Note that we no longer need to initialize the buffer size each time we go through a loop as this value is no longer destroyed by arq processing. In the process, we also fix a bug in i40evf_verify_api_ver where the buffer size was not correctly reinitialized each time through the loop. Change-ID: Ic7f9633cdd6f871f93e698dfb095e29c696f5581 Signed-off-by: Mitch Williams Acked-by: Shannon Nelson Acked-by: Ashish Shah Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq.c | 6 +++--- drivers/net/ethernet/intel/i40e/i40e_adminq.h | 3 ++- drivers/net/ethernet/intel/i40e/i40e_main.c | 7 +++---- drivers/net/ethernet/intel/i40evf/i40e_adminq.c | 6 +++--- drivers/net/ethernet/intel/i40evf/i40e_adminq.h | 3 ++- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 7 +++---- drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 11 +++++------ 7 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index f7f6206368df..5bb4914bda56 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -980,10 +980,10 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw, e->desc = *desc; datalen = le16_to_cpu(desc->datalen); - e->msg_size = min(datalen, e->msg_size); - if (e->msg_buf != NULL && (e->msg_size != 0)) + e->msg_len = min(datalen, e->buf_len); + if (e->msg_buf != NULL && (e->msg_len != 0)) memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va, - e->msg_size); + e->msg_len); i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf, diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h index df0bd09ed5d8..003a227b8515 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h @@ -76,7 +76,8 @@ struct i40e_asq_cmd_details { /* ARQ event information */ struct i40e_arq_event_info { struct i40e_aq_desc desc; - u16 msg_size; + u16 msg_len; + u16 buf_len; u8 *msg_buf; }; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c998d82da0fc..3ebab039fbb3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5750,13 +5750,12 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf) if (oldval != val) wr32(&pf->hw, pf->hw.aq.asq.len, val); - event.msg_size = I40E_MAX_AQ_BUF_SIZE; - event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL); + event.buf_len = I40E_MAX_AQ_BUF_SIZE; + event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) return; do { - event.msg_size = I40E_MAX_AQ_BUF_SIZE; /* reinit each time */ ret = i40e_clean_arq_element(hw, &event, &pending); if (ret == I40E_ERR_ADMIN_QUEUE_NO_WORK) break; @@ -5777,7 +5776,7 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf) le32_to_cpu(event.desc.cookie_high), le32_to_cpu(event.desc.cookie_low), event.msg_buf, - event.msg_size); + event.msg_len); break; case i40e_aqc_opc_lldp_update_mib: dev_dbg(&pf->pdev->dev, "ARQ: Update LLDP MIB event received\n"); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c index 500ca2162708..d7e446f3e7a4 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c @@ -929,10 +929,10 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw, e->desc = *desc; datalen = le16_to_cpu(desc->datalen); - e->msg_size = min(datalen, e->msg_size); - if (e->msg_buf != NULL && (e->msg_size != 0)) + e->msg_len = min(datalen, e->buf_len); + if (e->msg_buf != NULL && (e->msg_len != 0)) memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va, - e->msg_size); + e->msg_len); if (i40e_is_nvm_update_op(&e->desc)) hw->aq.nvm_busy = false; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h index f40cfac4b022..0d58378be740 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h @@ -76,7 +76,8 @@ struct i40e_asq_cmd_details { /* ARQ event information */ struct i40e_arq_event_info { struct i40e_aq_desc desc; - u16 msg_size; + u16 msg_len; + u16 buf_len; u8 *msg_buf; }; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 489227891ffb..d378e130d421 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1632,8 +1632,8 @@ static void i40evf_adminq_task(struct work_struct *work) if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) return; - event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; - event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL); + event.buf_len = I40EVF_MAX_AQ_BUF_SIZE; + event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) return; @@ -1645,10 +1645,9 @@ static void i40evf_adminq_task(struct work_struct *work) i40evf_virtchnl_completion(adapter, v_msg->v_opcode, v_msg->v_retval, event.msg_buf, - event.msg_size); + event.msg_len); if (pending != 0) { memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); - event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; } } while (pending); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 49bfdb5421c8..422dd2d6551b 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -92,8 +92,8 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter) enum i40e_virtchnl_ops op; i40e_status err; - event.msg_size = I40EVF_MAX_AQ_BUF_SIZE; - event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL); + event.buf_len = I40EVF_MAX_AQ_BUF_SIZE; + event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) { err = -ENOMEM; goto out; @@ -169,15 +169,14 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) len = sizeof(struct i40e_virtchnl_vf_resource) + I40E_MAX_VF_VSI * sizeof(struct i40e_virtchnl_vsi_resource); - event.msg_size = len; - event.msg_buf = kzalloc(event.msg_size, GFP_KERNEL); + event.buf_len = len; + event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) { err = -ENOMEM; goto out; } while (1) { - event.msg_size = len; /* When the AQ is empty, i40evf_clean_arq_element will return * nonzero and this loop will terminate. */ @@ -191,7 +190,7 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) } err = (i40e_status)le32_to_cpu(event.desc.cookie_low); - memcpy(adapter->vf_res, event.msg_buf, min(event.msg_size, len)); + memcpy(adapter->vf_res, event.msg_buf, min(event.msg_len, len)); i40e_vf_parse_hw_config(hw, adapter->vf_res); out_alloc: -- GitLab From 2cda3f3be5c2f630952b6c46661b44574f5dbd24 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 20:02:31 +0000 Subject: [PATCH 5609/9457] i40evf: update header comments No code changes. Update comments to match actual function declarations. Change-ID: Ib830d2f154ee917a104955c0914267fc98f3d2c8 Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c index 876411c39ee0..b2cd9ea12c7e 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c @@ -621,7 +621,7 @@ static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev) * i40evf_get_rxfh - get the rx flow hash indirection table * @netdev: network interface device structure * @indir: indirection table - * @key: hash key (will be %NULL until get_rxfh_key_size is implemented) + * @key: hash key * * Reads the indirection table directly from the hardware. Always returns 0. **/ @@ -646,7 +646,7 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key) * i40evf_set_rxfh - set the rx flow hash indirection table * @netdev: network interface device structure * @indir: indirection table - * @key: hash key (will be %NULL until get_rxfh_key_size is implemented) + * @key: hash key * * Returns -EINVAL if the table specifies an inavlid queue id, otherwise * returns 0 after programming the table. -- GitLab From 75a644358a2323c6c0769fd3faa4f54e0c58a30c Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 20:02:42 +0000 Subject: [PATCH 5610/9457] i40evf: make checkpatch happy This patch is the result of running checkpatch on the i40evf driver with the --strict option. The vast majority of changes are adding/removing blank lines, aligning function parameters, and correcting over-long lines. The only possible functional change is changing the flags member of the adapter structure to be non-volatile. However, according to the kernel documentation, this is not necessary and the volatile should be removed. Change-ID: Ie8c6414800924f529bef831e8845292b970fe2ed Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf.h | 2 +- .../ethernet/intel/i40evf/i40evf_ethtool.c | 10 ++-- .../net/ethernet/intel/i40evf/i40evf_main.c | 48 ++++++++++--------- .../ethernet/intel/i40evf/i40evf_virtchnl.c | 12 ++--- 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index 1113f8a2d3b6..981224743c73 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -244,7 +244,7 @@ struct i40evf_adapter { struct i40e_hw hw; /* defined in i40e_type.h */ enum i40evf_state_t state; - volatile unsigned long crit_section; + unsigned long crit_section; struct work_struct watchdog_task; bool netdev_registered; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c index b2cd9ea12c7e..69a269b23be6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c @@ -58,7 +58,7 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = { #define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats) #define I40EVF_QUEUE_STATS_LEN(_dev) \ - (((struct i40evf_adapter *) \ + (((struct i40evf_adapter *)\ netdev_priv(_dev))->num_active_queues \ * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64))) #define I40EVF_STATS_LEN(_dev) \ @@ -175,6 +175,7 @@ static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data) static u32 i40evf_get_msglevel(struct net_device *netdev) { struct i40evf_adapter *adapter = netdev_priv(netdev); + return adapter->msg_enable; } @@ -189,6 +190,7 @@ static u32 i40evf_get_msglevel(struct net_device *netdev) static void i40evf_set_msglevel(struct net_device *netdev, u32 data) { struct i40evf_adapter *adapter = netdev_priv(netdev); + adapter->msg_enable = data; } @@ -219,7 +221,7 @@ static void i40evf_get_drvinfo(struct net_device *netdev, * but the number of rings is not reported. **/ static void i40evf_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) + struct ethtool_ringparam *ring) { struct i40evf_adapter *adapter = netdev_priv(netdev); @@ -280,7 +282,7 @@ static int i40evf_set_ringparam(struct net_device *netdev, * this functionality. **/ static int i40evf_get_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) + struct ethtool_coalesce *ec) { struct i40evf_adapter *adapter = netdev_priv(netdev); struct i40e_vsi *vsi = &adapter->vsi; @@ -308,7 +310,7 @@ static int i40evf_get_coalesce(struct net_device *netdev, * Change current coalescing settings. **/ static int i40evf_set_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) + struct ethtool_coalesce *ec) { struct i40evf_adapter *adapter = netdev_priv(netdev); struct i40e_hw *hw = &adapter->hw; diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index d378e130d421..777d3a5161c3 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -185,6 +185,7 @@ static void i40evf_tx_timeout(struct net_device *netdev) static void i40evf_misc_irq_disable(struct i40evf_adapter *adapter) { struct i40e_hw *hw = &adapter->hw; + wr32(hw, I40E_VFINT_DYN_CTL01, 0); /* read flush */ @@ -200,6 +201,7 @@ static void i40evf_misc_irq_disable(struct i40evf_adapter *adapter) static void i40evf_misc_irq_enable(struct i40evf_adapter *adapter) { struct i40e_hw *hw = &adapter->hw; + wr32(hw, I40E_VFINT_DYN_CTL01, I40E_VFINT_DYN_CTL01_INTENA_MASK | I40E_VFINT_DYN_CTL01_ITR_INDX_MASK); wr32(hw, I40E_VFINT_ICR0_ENA1, I40E_VFINT_ICR0_ENA_ADMINQ_MASK); @@ -226,7 +228,6 @@ static void i40evf_irq_disable(struct i40evf_adapter *adapter) } /* read flush */ rd32(hw, I40E_VFGEN_RSTAT); - } /** @@ -253,8 +254,7 @@ void i40evf_irq_enable_queues(struct i40evf_adapter *adapter, u32 mask) * @adapter: board private structure * @mask: bitmap of vectors to trigger **/ -static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, - u32 mask) +static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, u32 mask) { struct i40e_hw *hw = &adapter->hw; int i; @@ -551,6 +551,7 @@ static void i40evf_free_traffic_irqs(struct i40evf_adapter *adapter) { int i; int q_vectors; + q_vectors = adapter->num_msix_vectors - NONQ_VECS; for (i = 0; i < q_vectors; i++) { @@ -584,6 +585,7 @@ static void i40evf_configure_tx(struct i40evf_adapter *adapter) { struct i40e_hw *hw = &adapter->hw; int i; + for (i = 0; i < adapter->num_active_queues; i++) adapter->tx_rings[i]->tail = hw->hw_addr + I40E_QTX_TAIL1(i); } @@ -705,7 +707,7 @@ static void i40evf_del_vlan(struct i40evf_adapter *adapter, u16 vlan) * @vid: VLAN tag **/ static int i40evf_vlan_rx_add_vid(struct net_device *netdev, - __always_unused __be16 proto, u16 vid) + __always_unused __be16 proto, u16 vid) { struct i40evf_adapter *adapter = netdev_priv(netdev); @@ -720,7 +722,7 @@ static int i40evf_vlan_rx_add_vid(struct net_device *netdev, * @vid: VLAN tag **/ static int i40evf_vlan_rx_kill_vid(struct net_device *netdev, - __always_unused __be16 proto, u16 vid) + __always_unused __be16 proto, u16 vid) { struct i40evf_adapter *adapter = netdev_priv(netdev); @@ -881,6 +883,7 @@ static void i40evf_napi_enable_all(struct i40evf_adapter *adapter) for (q_idx = 0; q_idx < q_vectors; q_idx++) { struct napi_struct *napi; + q_vector = adapter->q_vector[q_idx]; napi = &q_vector->napi; napi_enable(napi); @@ -920,6 +923,7 @@ static void i40evf_configure(struct i40evf_adapter *adapter) for (i = 0; i < adapter->num_active_queues; i++) { struct i40e_ring *ring = adapter->rx_rings[i]; + i40evf_alloc_rx_buffers(ring, ring->count); ring->next_to_use = ring->count - 1; writel(ring->next_to_use, ring->tail); @@ -1088,7 +1092,7 @@ static int i40evf_alloc_queues(struct i40evf_adapter *adapter) struct i40e_ring *tx_ring; struct i40e_ring *rx_ring; - tx_ring = kzalloc(sizeof(struct i40e_ring) * 2, GFP_KERNEL); + tx_ring = kzalloc(sizeof(*tx_ring) * 2, GFP_KERNEL); if (!tx_ring) goto err_out; @@ -1172,14 +1176,14 @@ static int i40evf_alloc_q_vectors(struct i40evf_adapter *adapter) num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { - q_vector = kzalloc(sizeof(struct i40e_q_vector), GFP_KERNEL); + q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); if (!q_vector) goto err_out; q_vector->adapter = adapter; q_vector->vsi = &adapter->vsi; q_vector->v_idx = q_idx; netif_napi_add(adapter->netdev, &q_vector->napi, - i40evf_napi_poll, NAPI_POLL_WEIGHT); + i40evf_napi_poll, NAPI_POLL_WEIGHT); adapter->q_vector[q_idx] = q_vector; } @@ -1265,8 +1269,8 @@ int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter) } dev_info(&adapter->pdev->dev, "Multiqueue %s: Queue pair count = %u", - (adapter->num_active_queues > 1) ? "Enabled" : - "Disabled", adapter->num_active_queues); + (adapter->num_active_queues > 1) ? "Enabled" : "Disabled", + adapter->num_active_queues); return 0; err_alloc_queues: @@ -1284,6 +1288,7 @@ int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter) static void i40evf_watchdog_timer(unsigned long data) { struct i40evf_adapter *adapter = (struct i40evf_adapter *)data; + schedule_work(&adapter->watchdog_task); /* timer will be rescheduled in watchdog task */ } @@ -1295,8 +1300,8 @@ static void i40evf_watchdog_timer(unsigned long data) static void i40evf_watchdog_task(struct work_struct *work) { struct i40evf_adapter *adapter = container_of(work, - struct i40evf_adapter, - watchdog_task); + struct i40evf_adapter, + watchdog_task); struct i40e_hw *hw = &adapter->hw; uint32_t rstat_val; @@ -1334,7 +1339,7 @@ static void i40evf_watchdog_task(struct work_struct *work) /* check for reset */ rstat_val = rd32(hw, I40E_VFGEN_RSTAT) & - I40E_VFGEN_RSTAT_VFR_STATE_MASK; + I40E_VFGEN_RSTAT_VFR_STATE_MASK; if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING) && (rstat_val != I40E_VFR_VFACTIVE) && (rstat_val != I40E_VFR_COMPLETED)) { @@ -1575,12 +1580,12 @@ static void i40evf_reset_task(struct work_struct *work) /* kill and reinit the admin queue */ if (i40evf_shutdown_adminq(hw)) dev_warn(&adapter->pdev->dev, - "%s: Failed to destroy the Admin Queue resources\n", - __func__); + "%s: Failed to destroy the Admin Queue resources\n", + __func__); err = i40evf_init_adminq(hw); if (err) dev_info(&adapter->pdev->dev, "%s: init_adminq failed: %d\n", - __func__, err); + __func__, err); adapter->aq_pending = 0; adapter->aq_required = 0; @@ -1646,9 +1651,8 @@ static void i40evf_adminq_task(struct work_struct *work) i40evf_virtchnl_completion(adapter, v_msg->v_opcode, v_msg->v_retval, event.msg_buf, event.msg_len); - if (pending != 0) { + if (pending != 0) memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE); - } } while (pending); /* check for error indications */ @@ -1705,7 +1709,6 @@ static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter) for (i = 0; i < adapter->num_active_queues; i++) if (adapter->tx_rings[i]->desc) i40evf_free_tx_resources(adapter->tx_rings[i]); - } /** @@ -2019,7 +2022,7 @@ static void i40evf_init_task(struct work_struct *work) err = i40evf_check_reset_complete(hw); if (err) { dev_info(&pdev->dev, "Device is still in reset (%d), retrying\n", - err); + err); goto err; } hw->aq.num_arq_entries = I40EVF_AQ_LEN; @@ -2051,7 +2054,7 @@ static void i40evf_init_task(struct work_struct *work) err = i40evf_verify_api_ver(adapter); if (err) { dev_info(&pdev->dev, "Unable to verify API version (%d), retrying\n", - err); + err); if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) { dev_info(&pdev->dev, "Resending request\n"); err = i40evf_send_api_ver(adapter); @@ -2500,8 +2503,9 @@ static struct pci_driver i40evf_driver = { static int __init i40evf_init_module(void) { int ret; + pr_info("i40evf: %s - version %s\n", i40evf_driver_string, - i40evf_driver_version); + i40evf_driver_version); pr_info("%s\n", i40evf_copyright); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 422dd2d6551b..07c13b039181 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -395,7 +395,7 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter) (count * sizeof(struct i40e_virtchnl_ether_addr)); if (len > I40EVF_MAX_AQ_BUF_SIZE) { dev_warn(&adapter->pdev->dev, "%s: Too many MAC address changes in one request\n", - __func__); + __func__); count = (I40EVF_MAX_AQ_BUF_SIZE - sizeof(struct i40e_virtchnl_ether_addr_list)) / sizeof(struct i40e_virtchnl_ether_addr); @@ -456,7 +456,7 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter) (count * sizeof(struct i40e_virtchnl_ether_addr)); if (len > I40EVF_MAX_AQ_BUF_SIZE) { dev_warn(&adapter->pdev->dev, "%s: Too many MAC address changes in one request\n", - __func__); + __func__); count = (I40EVF_MAX_AQ_BUF_SIZE - sizeof(struct i40e_virtchnl_ether_addr_list)) / sizeof(struct i40e_virtchnl_ether_addr); @@ -518,7 +518,7 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter) (count * sizeof(u16)); if (len > I40EVF_MAX_AQ_BUF_SIZE) { dev_warn(&adapter->pdev->dev, "%s: Too many VLAN changes in one request\n", - __func__); + __func__); count = (I40EVF_MAX_AQ_BUF_SIZE - sizeof(struct i40e_virtchnl_vlan_filter_list)) / sizeof(u16); @@ -578,7 +578,7 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter) (count * sizeof(u16)); if (len > I40EVF_MAX_AQ_BUF_SIZE) { dev_warn(&adapter->pdev->dev, "%s: Too many VLAN changes in one request\n", - __func__); + __func__); count = (I40EVF_MAX_AQ_BUF_SIZE - sizeof(struct i40e_virtchnl_vlan_filter_list)) / sizeof(u16); @@ -637,6 +637,7 @@ void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags) void i40evf_request_stats(struct i40evf_adapter *adapter) { struct i40e_virtchnl_queue_select vqs; + if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) { /* no error message, this isn't crucial */ return; @@ -711,7 +712,6 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, "%s: Unknown event %d from pf\n", __func__, vpe->event); break; - } return; } @@ -776,7 +776,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, break; default: dev_warn(&adapter->pdev->dev, "%s: Received unexpected message %d from PF\n", - __func__, v_opcode); + __func__, v_opcode); break; } /* switch v_opcode */ adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN; -- GitLab From 348d499440635f8847bedf124cda54eacf4c29a0 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 20:02:52 +0000 Subject: [PATCH 5611/9457] i40evf: make comparisons consistent Most of the null-checking in this driver is of the style if (!foo), except these few. Make these checks consistent with the rest of the code. Change-ID: I991924f34072fa607a1b626a8b3f1fa5195d43e9 Reported-by: Joe Perches Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 777d3a5161c3..233710c91c84 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -669,9 +669,9 @@ i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter *adapter, u16 vlan) struct i40evf_vlan_filter *f; f = i40evf_find_vlan(adapter, vlan); - if (NULL == f) { + if (!f) { f = kzalloc(sizeof(*f), GFP_ATOMIC); - if (NULL == f) + if (!f) return NULL; f->vlan = vlan; @@ -774,9 +774,9 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter, udelay(1); f = i40evf_find_filter(adapter, macaddr); - if (NULL == f) { + if (!f) { f = kzalloc(sizeof(*f), GFP_ATOMIC); - if (NULL == f) { + if (!f) { clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); return NULL; @@ -2138,7 +2138,7 @@ static void i40evf_init_task(struct work_struct *work) ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr); f = kzalloc(sizeof(*f), GFP_ATOMIC); - if (NULL == f) + if (!f) goto err_sw_init; ether_addr_copy(f->macaddr, adapter->hw.mac.addr); -- GitLab From c88e38cc50d582c56f64c8bf091f4fd670ad97e3 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 11 Nov 2014 20:03:13 +0000 Subject: [PATCH 5612/9457] i40evf: remove unnecessary else Since the if part of this statement contains a break, there's no reason for the else. Clean up the code and make it more obvious that the delay happens each time through the loop. Change-ID: I9292eaf7dd687688bdc401b8bd8d1d14f6944460 Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 233710c91c84..8e01009695da 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1513,8 +1513,7 @@ static void i40evf_reset_task(struct work_struct *work) if ((rstat_val != I40E_VFR_VFACTIVE) && (rstat_val != I40E_VFR_COMPLETED)) break; - else - msleep(I40EVF_RESET_WAIT_MS); + msleep(I40EVF_RESET_WAIT_MS); } if (i == I40EVF_RESET_WAIT_COUNT) { adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; @@ -1528,8 +1527,7 @@ static void i40evf_reset_task(struct work_struct *work) if ((rstat_val == I40E_VFR_VFACTIVE) || (rstat_val == I40E_VFR_COMPLETED)) break; - else - msleep(I40EVF_RESET_WAIT_MS); + msleep(I40EVF_RESET_WAIT_MS); } if (i == I40EVF_RESET_WAIT_COUNT) { struct i40evf_mac_filter *f, *ftmp; -- GitLab From 5d1ff1061c26f6e115784bad62767ca47d67f47f Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 11 Nov 2014 20:04:35 +0000 Subject: [PATCH 5613/9457] i40e: trigger SW INT with no ITR wait Since we want the SW INT to go off as soon as possible, write the extra bits that will turn off the ITR wait for the interrupt. Change-ID: I6d5382ba60840fa32abb7dea17c839eb4b5f68f7 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 5 ++++- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index bb1698a7b3d1..b2402851a9bd 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1400,7 +1400,10 @@ static int i40e_intr_test(struct net_device *netdev, u64 *data) netif_info(pf, hw, netdev, "interrupt test\n"); wr32(&pf->hw, I40E_PFINT_DYN_CTL0, (I40E_PFINT_DYN_CTL0_INTENA_MASK | - I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK)); + I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTL0_ITR_INDX_MASK | + I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK | + I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK)); usleep_range(1000, 2000); *data = (swc_old == pf->sw_int_count); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3ebab039fbb3..3913329998bf 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5565,11 +5565,17 @@ static void i40e_check_hang_subtask(struct i40e_pf *pf) if (!(pf->flags & I40E_FLAG_MSIX_ENABLED)) { wr32(&vsi->back->hw, I40E_PFINT_DYN_CTL0, (I40E_PFINT_DYN_CTL0_INTENA_MASK | - I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK)); + I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTL0_ITR_INDX_MASK | + I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK | + I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK)); } else { u16 vec = vsi->base_vector - 1; u32 val = (I40E_PFINT_DYN_CTLN_INTENA_MASK | - I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK); + I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | + I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | + I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK | + I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK); for (i = 0; i < vsi->num_q_vectors; i++, vec++) wr32(&vsi->back->hw, I40E_PFINT_DYN_CTLN(vec), val); -- GitLab From 704de49d2be665be44933300f60023c889832fca Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 6 Oct 2014 22:14:22 +0100 Subject: [PATCH 5614/9457] Btrfs: set page and mapping error on compressed write failure If we fail in submit_compressed_extents() before calling btrfs_submit_compressed_write(), we start and end the writeback for the pages (clear their dirty flag, unlock them, etc) but we don't tag the pages, nor the inode's mapping, with an error. This makes it impossible for a caller of filemap_fdatawait_range() (fsync, or transaction commit for e.g.) know that there was an error. Note that the return value of submit_compressed_extents() is useless, as that function is executed by a workqueue task and not directly by the fill_delalloc callback. This means the writepage/s callbacks of the inode's address space operations don't get that return value. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 5 +++++ fs/btrfs/extent_io.h | 1 + fs/btrfs/inode.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index bf3f424e0013..420fe26d32d5 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1746,6 +1746,9 @@ int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, if (page_ops == 0) return 0; + if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0) + mapping_set_error(inode->i_mapping, -EIO); + while (nr_pages > 0) { ret = find_get_pages_contig(inode->i_mapping, index, min_t(unsigned long, @@ -1763,6 +1766,8 @@ int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, clear_page_dirty_for_io(pages[i]); if (page_ops & PAGE_SET_WRITEBACK) set_page_writeback(pages[i]); + if (page_ops & PAGE_SET_ERROR) + SetPageError(pages[i]); if (page_ops & PAGE_END_WRITEBACK) end_page_writeback(pages[i]); if (page_ops & PAGE_UNLOCK) diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 6d4b938be986..ece9ce87edff 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -49,6 +49,7 @@ #define PAGE_SET_WRITEBACK (1 << 2) #define PAGE_END_WRITEBACK (1 << 3) #define PAGE_SET_PRIVATE2 (1 << 4) +#define PAGE_SET_ERROR (1 << 5) /* * page->private values. Every page that is controlled by the extent diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d23362f4464e..fcb9a38fc9d3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -832,7 +832,8 @@ static noinline int submit_compressed_extents(struct inode *inode, NULL, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | - PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK); + PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK | + PAGE_SET_ERROR); kfree(async_extent); goto again; } -- GitLab From fce2a4e6b2da1bcc03837aff53b5bcb02bee4cee Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 6 Oct 2014 22:14:23 +0100 Subject: [PATCH 5615/9457] Btrfs: fix hang on compressed write error In inode.c:submit_compressed_extents(), before calling btrfs_submit_compressed_write() we start writeback for all pages, clear their dirty flag, unlock them, etc, but if btrfs_submit_compressed_write() fails (at the moment it can only fail with -ENOMEM), we never end the writeback on the pages, so any filemap_fdatawait_range() call will hang forever. We were also not calling the writepage end io hook, which means the corresponding ordered extent will never complete and all its waiters will block forever, such as a full fsync (via btrfs_wait_ordered_range()). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fcb9a38fc9d3..ec68eaef05d7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -814,6 +814,20 @@ static noinline int submit_compressed_extents(struct inode *inode, ins.objectid, ins.offset, async_extent->pages, async_extent->nr_pages); + if (ret) { + struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; + struct page *p = async_extent->pages[0]; + const u64 start = async_extent->start; + const u64 end = start + async_extent->ram_size - 1; + + p->mapping = inode->i_mapping; + tree->ops->writepage_end_io_hook(p, start, end, + NULL, 0); + p->mapping = NULL; + extent_clear_unlock_delalloc(inode, start, end, NULL, 0, + PAGE_END_WRITEBACK | + PAGE_SET_ERROR); + } alloc_hint = ins.objectid + ins.offset; kfree(async_extent); if (ret) -- GitLab From 40ae837b43565c47ee171e704d05947fd5c2bae9 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 6 Oct 2014 22:14:24 +0100 Subject: [PATCH 5616/9457] Btrfs: don't leak pages and memory on compressed write error In inode.c:submit_compressed_extents(), if we fail before calling btrfs_submit_compressed_write(), or when that function fails, we were freeing the async_extent structure without releasing its pages and freeing the pages array. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ec68eaef05d7..b759585fbc6a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -633,6 +633,22 @@ static noinline int compress_file_range(struct inode *inode, goto out; } +static void free_async_extent_pages(struct async_extent *async_extent) +{ + int i; + + if (!async_extent->pages) + return; + + for (i = 0; i < async_extent->nr_pages; i++) { + WARN_ON(async_extent->pages[i]->mapping); + page_cache_release(async_extent->pages[i]); + } + kfree(async_extent->pages); + async_extent->nr_pages = 0; + async_extent->pages = NULL; +} + /* * phase two of compressed writeback. This is the ordered portion * of the code, which only gets called in the order the work was @@ -709,15 +725,7 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->compressed_size, 0, alloc_hint, &ins, 1, 1); if (ret) { - int i; - - for (i = 0; i < async_extent->nr_pages; i++) { - WARN_ON(async_extent->pages[i]->mapping); - page_cache_release(async_extent->pages[i]); - } - kfree(async_extent->pages); - async_extent->nr_pages = 0; - async_extent->pages = NULL; + free_async_extent_pages(async_extent); if (ret == -ENOSPC) { unlock_extent(io_tree, async_extent->start, @@ -827,6 +835,7 @@ static noinline int submit_compressed_extents(struct inode *inode, extent_clear_unlock_delalloc(inode, start, end, NULL, 0, PAGE_END_WRITEBACK | PAGE_SET_ERROR); + free_async_extent_pages(async_extent); } alloc_hint = ins.objectid + ins.offset; kfree(async_extent); @@ -848,6 +857,7 @@ static noinline int submit_compressed_extents(struct inode *inode, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK | PAGE_SET_ERROR); + free_async_extent_pages(async_extent); kfree(async_extent); goto again; } -- GitLab From 3d7a820f713a1a3339139ea8c86a98437ae0a2c1 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 6 Oct 2014 22:14:25 +0100 Subject: [PATCH 5617/9457] Btrfs: process all async extents on compressed write failure If we had an error when processing one of the async extents from our list, we were not processing the remaining async extents, meaning we would leak those async_extent structs, never release the pages with the compressed data and never unlock and clear the dirty flag from the inode's pages (those that correspond to the uncompressed content). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b759585fbc6a..d1a52850d17d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -839,13 +839,9 @@ static noinline int submit_compressed_extents(struct inode *inode, } alloc_hint = ins.objectid + ins.offset; kfree(async_extent); - if (ret) - goto out; cond_resched(); } - ret = 0; -out: - return ret; + return 0; out_free_reserve: btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); out_free: -- GitLab From dec8f1756342c92fc31ba8bc7060b55dd62836a0 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 6 Oct 2014 22:14:26 +0100 Subject: [PATCH 5618/9457] Btrfs: make inode.c:submit_compressed_extents() return void Its return value is completely ignored by its single caller and it's useless anyway, since errors are indicated through SetPageError and the bit AS_EIO set in the flags of the inode's mapping. The caller can't do anything with the value, as it's invoked from a workqueue task and not by the task calling filemap_fdatawrite_range (which calls the writepages address space callback, which in turn calls the inode's fill_delalloc callback). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d1a52850d17d..6fed30c3f9ce 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -655,7 +655,7 @@ static void free_async_extent_pages(struct async_extent *async_extent) * queued. We walk all the async extents created by compress_file_range * and send them down to the disk. */ -static noinline int submit_compressed_extents(struct inode *inode, +static noinline void submit_compressed_extents(struct inode *inode, struct async_cow *async_cow) { struct async_extent *async_extent; @@ -667,9 +667,6 @@ static noinline int submit_compressed_extents(struct inode *inode, struct extent_io_tree *io_tree; int ret = 0; - if (list_empty(&async_cow->extents)) - return 0; - again: while (!list_empty(&async_cow->extents)) { async_extent = list_entry(async_cow->extents.next, @@ -841,7 +838,7 @@ static noinline int submit_compressed_extents(struct inode *inode, kfree(async_extent); cond_resched(); } - return 0; + return; out_free_reserve: btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); out_free: -- GitLab From 7bdcefc103849386ef7f3029dd94ecfd4a822a67 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 7 Oct 2014 01:48:26 +0100 Subject: [PATCH 5619/9457] Btrfs: don't ignore compressed bio write errors Our compressed bio write end callback was essentially ignoring the error parameter. When a write error happens, it must pass a value of 0 to the inode's write_page_end_io_hook callback, SetPageError on the respective pages and set AS_EIO in the inode's mapping flags, so that a call to filemap_fdatawait_range() / filemap_fdatawait() can find out that errors happened (we surely don't want silent failures on fsync for example). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/compression.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index d3220d31d3cb..1bf411bc28fd 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -224,16 +224,19 @@ static void end_compressed_bio_read(struct bio *bio, int err) * Clear the writeback bits on all of the file * pages for a compressed write */ -static noinline void end_compressed_writeback(struct inode *inode, u64 start, - unsigned long ram_size) +static noinline void end_compressed_writeback(struct inode *inode, + const struct compressed_bio *cb) { - unsigned long index = start >> PAGE_CACHE_SHIFT; - unsigned long end_index = (start + ram_size - 1) >> PAGE_CACHE_SHIFT; + unsigned long index = cb->start >> PAGE_CACHE_SHIFT; + unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_CACHE_SHIFT; struct page *pages[16]; unsigned long nr_pages = end_index - index + 1; int i; int ret; + if (cb->errors) + mapping_set_error(inode->i_mapping, -EIO); + while (nr_pages > 0) { ret = find_get_pages_contig(inode->i_mapping, index, min_t(unsigned long, @@ -244,6 +247,8 @@ static noinline void end_compressed_writeback(struct inode *inode, u64 start, continue; } for (i = 0; i < ret; i++) { + if (cb->errors) + SetPageError(pages[i]); end_page_writeback(pages[i]); page_cache_release(pages[i]); } @@ -287,10 +292,11 @@ static void end_compressed_bio_write(struct bio *bio, int err) tree->ops->writepage_end_io_hook(cb->compressed_pages[0], cb->start, cb->start + cb->len - 1, - NULL, 1); + NULL, + err ? 0 : 1); cb->compressed_pages[0]->mapping = NULL; - end_compressed_writeback(inode, cb->start, cb->len); + end_compressed_writeback(inode, cb); /* note, our inode could be gone now */ /* -- GitLab From 4bcbb33255131adbe481c0467df26d654ce3bc78 Mon Sep 17 00:00:00 2001 From: Shilong Wang Date: Tue, 7 Oct 2014 18:44:35 -0400 Subject: [PATCH 5620/9457] Btrfs: fix incorrect compression ratio detection Steps to reproduce: # mkfs.btrfs -f /dev/sdb # mount -t btrfs /dev/sdb /mnt -o compress=lzo # dd if=/dev/zero of=/mnt/data bs=$((33*4096)) count=1 after previous steps, inode will be detected as bad compression ratio, and NOCOMPRESS flag will be set for that inode. Reason is that compress have a max limit pages every time(128K), if a 132k write in, it will be splitted into two write(128k+4k), this bug is a leftover for commit 68bb462d42a(Btrfs: don't compress for a small write) Fix this problem by checking every time before compression, if it is a small write(<=blocksize), we bail out and fall into nocompression directly. Signed-off-by: Wang Shilong Reviewed-by: Miao Xie Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6fed30c3f9ce..793e033cbd17 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -411,14 +411,6 @@ static noinline int compress_file_range(struct inode *inode, (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) btrfs_add_inode_defrag(NULL, inode); - /* - * skip compression for a small file range(<=blocksize) that - * isn't an inline extent, since it dosen't save disk space at all. - */ - if ((end - start + 1) <= blocksize && - (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) - goto cleanup_and_bail_uncompressed; - actual_end = min_t(u64, isize, end + 1); again: will_compress = 0; @@ -440,6 +432,14 @@ static noinline int compress_file_range(struct inode *inode, total_compressed = actual_end - start; + /* + * skip compression for a small file range(<=blocksize) that + * isn't an inline extent, since it dosen't save disk space at all. + */ + if (total_compressed <= blocksize && + (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) + goto cleanup_and_bail_uncompressed; + /* we want to make sure that amount of ram required to uncompress * an extent is reasonable, so we limit the total size in ram * of a compressed extent to 128k. This is a crucial number -- GitLab From c44f649e281e93689827a206653696be9599a320 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 9 Oct 2014 21:15:44 +0100 Subject: [PATCH 5621/9457] Btrfs: make inode.c:compress_file_range() return void Its return value is useless, its single caller ignores it and can't do anything with it anyway, since it's a workqueue task and not the task calling filemap_fdatawrite_range (writepages) nor filemap_fdatawait_range(). Failure is communicated to such functions via start and end of writeback with the respective pages tagged with an error and AS_EIO flag set in the inode's imapping. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 793e033cbd17..5a8a749b7e6b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -382,7 +382,7 @@ static inline int inode_need_compress(struct inode *inode) * are written in the same order that the flusher thread sent them * down. */ -static noinline int compress_file_range(struct inode *inode, +static noinline void compress_file_range(struct inode *inode, struct page *locked_page, u64 start, u64 end, struct async_cow *async_cow, @@ -620,8 +620,7 @@ static noinline int compress_file_range(struct inode *inode, *num_added += 1; } -out: - return ret; + return; free_pages_out: for (i = 0; i < nr_pages_ret; i++) { @@ -629,8 +628,6 @@ static noinline int compress_file_range(struct inode *inode, page_cache_release(pages[i]); } kfree(pages); - - goto out; } static void free_async_extent_pages(struct async_extent *async_extent) -- GitLab From 075bdbdbe9f21d68950ba5b187f80a4a23105365 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 9 Oct 2014 21:18:55 +0100 Subject: [PATCH 5622/9457] Btrfs: correctly flush compressed data before/after direct IO For compressed writes, after doing the first filemap_fdatawrite_range() we don't get the pages tagged for writeback immediately. Instead we create a workqueue task, which is run by other kthread, and keep the pages locked. That other kthread compresses data, creates the respective ordered extent/s, tags the pages for writeback and unlocks them. Therefore we need a second call to filemap_fdatawrite_range() if we have compressed writes, as this second call will wait for the pages to become unlocked, then see they became tagged for writeback and finally wait for the writeback to finish. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/file.c | 12 +++++++++++- fs/btrfs/inode.c | 16 +++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a18ceabd99a8..f5a868ab60f3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1692,8 +1692,18 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, err = written_buffered; goto out; } + /* + * Ensure all data is persisted. We want the next direct IO read to be + * able to read what was just written. + */ endbyte = pos + written_buffered - 1; - err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte); + err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte); + if (!err && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, + &BTRFS_I(file_inode(file))->runtime_flags)) + err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte); + if (err) + goto out; + err = filemap_fdatawait_range(file->f_mapping, pos, endbyte); if (err) goto out; written += written_buffered; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5a8a749b7e6b..01d223e22bb1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7015,9 +7015,19 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend, btrfs_put_ordered_extent(ordered); } else { /* Screw you mmap */ - ret = filemap_write_and_wait_range(inode->i_mapping, - lockstart, - lockend); + ret = filemap_fdatawrite_range(inode->i_mapping, + lockstart, + lockend); + if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, + &BTRFS_I(inode)->runtime_flags)) + ret = filemap_fdatawrite_range(inode->i_mapping, + lockstart, + lockend); + if (ret) + break; + ret = filemap_fdatawait_range(inode->i_mapping, + lockstart, + lockend); if (ret) break; -- GitLab From 728404dacfddb5364d7256d821a2ea482159cbe7 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 10 Oct 2014 09:43:11 +0100 Subject: [PATCH 5623/9457] Btrfs: add helper btrfs_fdatawrite_range To avoid duplicating this double filemap_fdatawrite_range() call for inodes with async extents (compressed writes) so often. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 1 + fs/btrfs/file.c | 39 ++++++++++++++++++++++++++++++--------- fs/btrfs/inode.c | 9 +-------- fs/btrfs/ordered-data.c | 24 ++---------------------- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index fe69edda11fb..b72b35867a7f 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3901,6 +3901,7 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, struct page **pages, size_t num_pages, loff_t pos, size_t write_bytes, struct extent_state **cached); +int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end); /* tree-defrag.c */ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f5a868ab60f3..0fbf0e7bc606 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1676,6 +1676,7 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, loff_t pos) { struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); ssize_t written; ssize_t written_buffered; loff_t endbyte; @@ -1697,13 +1698,10 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, * able to read what was just written. */ endbyte = pos + written_buffered - 1; - err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte); - if (!err && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, - &BTRFS_I(file_inode(file))->runtime_flags)) - err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte); + err = btrfs_fdatawrite_range(inode, pos, endbyte); if (err) goto out; - err = filemap_fdatawait_range(file->f_mapping, pos, endbyte); + err = filemap_fdatawait_range(inode->i_mapping, pos, endbyte); if (err) goto out; written += written_buffered; @@ -1864,10 +1862,7 @@ static int start_ordered_ops(struct inode *inode, loff_t start, loff_t end) int ret; atomic_inc(&BTRFS_I(inode)->sync_writers); - ret = filemap_fdatawrite_range(inode->i_mapping, start, end); - if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, - &BTRFS_I(inode)->runtime_flags)) - ret = filemap_fdatawrite_range(inode->i_mapping, start, end); + ret = btrfs_fdatawrite_range(inode, start, end); atomic_dec(&BTRFS_I(inode)->sync_writers); return ret; @@ -2820,3 +2815,29 @@ int btrfs_auto_defrag_init(void) return 0; } + +int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end) +{ + int ret; + + /* + * So with compression we will find and lock a dirty page and clear the + * first one as dirty, setup an async extent, and immediately return + * with the entire range locked but with nobody actually marked with + * writeback. So we can't just filemap_write_and_wait_range() and + * expect it to work since it will just kick off a thread to do the + * actual work. So we need to call filemap_fdatawrite_range _again_ + * since it will wait on the page lock, which won't be unlocked until + * after the pages have been marked as writeback and so we're good to go + * from there. We have to do this otherwise we'll miss the ordered + * extents and that results in badness. Please Josef, do not think you + * know better and pull this out at some point in the future, it is + * right and you are wrong. + */ + ret = filemap_fdatawrite_range(inode->i_mapping, start, end); + if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, + &BTRFS_I(inode)->runtime_flags)) + ret = filemap_fdatawrite_range(inode->i_mapping, start, end); + + return ret; +} diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 01d223e22bb1..95f06936bc6e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7015,14 +7015,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend, btrfs_put_ordered_extent(ordered); } else { /* Screw you mmap */ - ret = filemap_fdatawrite_range(inode->i_mapping, - lockstart, - lockend); - if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, - &BTRFS_I(inode)->runtime_flags)) - ret = filemap_fdatawrite_range(inode->i_mapping, - lockstart, - lockend); + ret = btrfs_fdatawrite_range(inode, lockstart, lockend); if (ret) break; ret = filemap_fdatawait_range(inode->i_mapping, diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index ac734ec4cc20..1401b1af4f06 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -725,30 +725,10 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) /* start IO across the range first to instantiate any delalloc * extents */ - ret = filemap_fdatawrite_range(inode->i_mapping, start, orig_end); + ret = btrfs_fdatawrite_range(inode, start, orig_end); if (ret) return ret; - /* - * So with compression we will find and lock a dirty page and clear the - * first one as dirty, setup an async extent, and immediately return - * with the entire range locked but with nobody actually marked with - * writeback. So we can't just filemap_write_and_wait_range() and - * expect it to work since it will just kick off a thread to do the - * actual work. So we need to call filemap_fdatawrite_range _again_ - * since it will wait on the page lock, which won't be unlocked until - * after the pages have been marked as writeback and so we're good to go - * from there. We have to do this otherwise we'll miss the ordered - * extents and that results in badness. Please Josef, do not think you - * know better and pull this out at some point in the future, it is - * right and you are wrong. - */ - if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, - &BTRFS_I(inode)->runtime_flags)) { - ret = filemap_fdatawrite_range(inode->i_mapping, start, - orig_end); - if (ret) - return ret; - } + ret = filemap_fdatawait_range(inode->i_mapping, start, orig_end); if (ret) return ret; -- GitLab From e6eb43142a72ba356f9fcd0f0fe2169c3642b460 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 10 Oct 2014 10:45:12 +0100 Subject: [PATCH 5624/9457] Btrfs: report error after failure inlining extent in compressed write path If cow_file_range_inline() failed, when called from compress_file_range(), we were tagging the locked page for writeback, end its writeback and unlock it, but not marking it with an error nor setting AS_EIO in inode's mapping flags. This made it impossible for a caller of filemap_fdatawrite_range (writepages) or filemap_fdatawait_range() to know that an error happened. And the return value of compress_file_range() is useless because it's returned to a workqueue task and not to the task calling filemap_fdatawrite_range (writepages). This change applies on top of the previous patchset starting at the patch titled: "[1/5] Btrfs: set page and mapping error on compressed write failure" Which changed extent_clear_unlock_delalloc() to use SetPageError and mapping_set_error(). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 95f06936bc6e..cb5978a4a277 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -527,7 +527,10 @@ static noinline void compress_file_range(struct inode *inode, if (ret <= 0) { unsigned long clear_flags = EXTENT_DELALLOC | EXTENT_DEFRAG; + unsigned long page_error_op; + clear_flags |= (ret < 0) ? EXTENT_DO_ACCOUNTING : 0; + page_error_op = ret < 0 ? PAGE_SET_ERROR : 0; /* * inline extent creation worked or returned error, @@ -538,6 +541,7 @@ static noinline void compress_file_range(struct inode *inode, clear_flags, PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | + page_error_op | PAGE_END_WRITEBACK); goto free_pages_out; } -- GitLab From 6b3a4d60dbf7a60b91d810498e8c212f26718efd Mon Sep 17 00:00:00 2001 From: Shilong Wang Date: Fri, 10 Oct 2014 17:35:59 -0400 Subject: [PATCH 5625/9457] Btrfs: fix allocationg memory failure for btrfsic_state structure size of @btrfsic_state needs more than 2M, it is very likely to fail allocating memory using kzalloc(). see following mesage: [91428.902148] Call Trace: [] dump_stack+0x4d/0x66 [] warn_alloc_failed+0xff/0x170 [] __alloc_pages_nodemask+0x951/0xc30 [] alloc_pages_current+0x11a/0x1f0 [] ? alloc_kmem_pages+0x3b/0xf0 [] alloc_kmem_pages+0x3b/0xf0 [] kmalloc_order+0x18/0x50 [] kmalloc_order_trace+0x24/0x140 [] btrfsic_mount+0x8b/0xae0 [btrfs] [] ? check_preempt_curr+0x85/0xa0 [] ? try_to_wake_up+0x103/0x430 [] open_ctree+0x1bd0/0x2130 [btrfs] [] btrfs_mount+0x62e/0x8b0 [btrfs] [] ? alloc_pages_current+0x11a/0x1f0 [] ? __get_free_pages+0xe/0x50 [] mount_fs+0x39/0x1b0 [] vfs_kern_mount+0x6b/0x150 [] do_mount+0x27b/0xc30 [] ? __get_free_pages+0xe/0x50 [] SyS_mount+0x96/0xf0 [] system_call_fastpath+0x16/0x1b Since we are allocating memory for hash table array, so it will be good if we could allocate continuous pages here. Fix this problem by firstly trying kzalloc(), if we fail, use vzalloc() instead. Signed-off-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/check-integrity.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index cb7f3fe9c9f6..66e820f7b440 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -3130,10 +3130,13 @@ int btrfsic_mount(struct btrfs_root *root, root->sectorsize, PAGE_CACHE_SIZE); return -1; } - state = kzalloc(sizeof(*state), GFP_NOFS); - if (NULL == state) { - printk(KERN_INFO "btrfs check-integrity: kmalloc() failed!\n"); - return -1; + state = kzalloc(sizeof(*state), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); + if (!state) { + state = vzalloc(sizeof(*state)); + if (!state) { + printk(KERN_INFO "btrfs check-integrity: vzalloc() failed!\n"); + return -1; + } } if (!btrfsic_is_initialized) { @@ -3277,5 +3280,8 @@ void btrfsic_unmount(struct btrfs_root *root, mutex_unlock(&btrfsic_mutex); - kfree(state); + if (is_vmalloc_addr(state)) + vfree(state); + else + kfree(state); } -- GitLab From 2fc9f6baa24ac230166df41ed636224969523341 Mon Sep 17 00:00:00 2001 From: Eryu Guan Date: Mon, 13 Oct 2014 12:42:12 +0800 Subject: [PATCH 5626/9457] Btrfs: return failure if btrfs_dev_replace_finishing() failed device replace could fail due to another running scrub process or any other errors btrfs_scrub_dev() may hit, but this failure doesn't get returned to userspace. The following steps could reproduce this issue mkfs -t btrfs -f /dev/sdb1 /dev/sdb2 mount /dev/sdb1 /mnt/btrfs while true; do btrfs scrub start -B /mnt/btrfs >/dev/null 2>&1; done & btrfs replace start -Bf /dev/sdb2 /dev/sdb3 /mnt/btrfs # if this replace succeeded, do the following and repeat until # you see this log in dmesg # BTRFS: btrfs_scrub_dev(/dev/sdb2, 2, /dev/sdb3) failed -115 #btrfs replace start -Bf /dev/sdb3 /dev/sdb2 /mnt/btrfs # once you see the error log in dmesg, check return value of # replace echo $? Introduce a new dev replace result BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS to catch -EINPROGRESS explicitly and return other errors directly to userspace. Signed-off-by: Eryu Guan Signed-off-by: Chris Mason --- fs/btrfs/dev-replace.c | 12 +++++++++--- include/uapi/linux/btrfs.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 6f662b34ba0e..971c061eb1ce 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -422,9 +422,15 @@ int btrfs_dev_replace_start(struct btrfs_root *root, &dev_replace->scrub_progress, 0, 1); ret = btrfs_dev_replace_finishing(root->fs_info, ret); - WARN_ON(ret); + /* don't warn if EINPROGRESS, someone else might be running scrub */ + if (ret == -EINPROGRESS) { + args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS; + ret = 0; + } else { + WARN_ON(ret); + } - return 0; + return ret; leave: dev_replace->srcdev = NULL; @@ -542,7 +548,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device); mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); - return 0; + return scrub_ret; } printk_in_rcu(KERN_INFO diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 2f47824e7a36..611e1c5893b4 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -157,6 +157,7 @@ struct btrfs_ioctl_dev_replace_status_params { #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR 0 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED 1 #define BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED 2 +#define BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS 3 struct btrfs_ioctl_dev_replace_args { __u64 cmd; /* in */ __u64 result; /* out */ -- GitLab From 663dfbb07774e0fe1049e8db3054a08500122f18 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 13 Oct 2014 12:28:37 +0100 Subject: [PATCH 5627/9457] Btrfs: deal with convert_extent_bit errors to avoid fs corruption When committing a transaction or a log, we look for btree extents that need to be durably persisted by searching for ranges in a io tree that have some bits set (EXTENT_DIRTY or EXTENT_NEW). We then attempt to clear those bits and set the EXTENT_NEED_WAIT bit, with calls to the function convert_extent_bit, and then start writeback for the extents. That function however can return an error (at the moment only -ENOMEM is possible, specially when it does GFP_ATOMIC allocation requests through alloc_extent_state_atomic) - that means the ranges didn't got the EXTENT_NEED_WAIT bit set (or at least not for the whole range), which in turn means a call to btrfs_wait_marked_extents() won't find those ranges for which we started writeback, causing a transaction commit or a log commit to persist a new superblock without waiting for the writeback of extents in that range to finish first. Therefore if a crash happens after persisting the new superblock and before writeback finishes, we have a superblock pointing to roots that weren't fully persisted or roots that point to nodes or leafs that weren't fully persisted, causing all sorts of unexpected/bad behaviour as we endup reading garbage from disk or the content of some node/leaf from a past generation that got cowed or deleted and is no longer valid (for this later case we end up getting error messages like "parent transid verify failed on X wanted Y found Z" when reading btree nodes/leafs from disk). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/transaction.c | 92 ++++++++++++++++++++++++++++++++++-------- fs/btrfs/transaction.h | 2 - 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index dcaae3616728..04dbc800c209 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -76,6 +76,32 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction) } } +static void clear_btree_io_tree(struct extent_io_tree *tree) +{ + spin_lock(&tree->lock); + while (!RB_EMPTY_ROOT(&tree->state)) { + struct rb_node *node; + struct extent_state *state; + + node = rb_first(&tree->state); + state = rb_entry(node, struct extent_state, rb_node); + rb_erase(&state->rb_node, &tree->state); + RB_CLEAR_NODE(&state->rb_node); + /* + * btree io trees aren't supposed to have tasks waiting for + * changes in the flags of extent states ever. + */ + ASSERT(!waitqueue_active(&state->wq)); + free_extent_state(state); + if (need_resched()) { + spin_unlock(&tree->lock); + cond_resched(); + spin_lock(&tree->lock); + } + } + spin_unlock(&tree->lock); +} + static noinline void switch_commit_roots(struct btrfs_transaction *trans, struct btrfs_fs_info *fs_info) { @@ -89,6 +115,7 @@ static noinline void switch_commit_roots(struct btrfs_transaction *trans, root->commit_root = btrfs_root_node(root); if (is_fstree(root->objectid)) btrfs_unpin_free_ino(root); + clear_btree_io_tree(&root->dirty_log_pages); } up_write(&fs_info->commit_root_sem); } @@ -828,17 +855,38 @@ int btrfs_write_marked_extents(struct btrfs_root *root, while (!find_first_extent_bit(dirty_pages, start, &start, &end, mark, &cached_state)) { - convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, - mark, &cached_state, GFP_NOFS); - cached_state = NULL; - err = filemap_fdatawrite_range(mapping, start, end); + bool wait_writeback = false; + + err = convert_extent_bit(dirty_pages, start, end, + EXTENT_NEED_WAIT, + mark, &cached_state, GFP_NOFS); + /* + * convert_extent_bit can return -ENOMEM, which is most of the + * time a temporary error. So when it happens, ignore the error + * and wait for writeback of this range to finish - because we + * failed to set the bit EXTENT_NEED_WAIT for the range, a call + * to btrfs_wait_marked_extents() would not know that writeback + * for this range started and therefore wouldn't wait for it to + * finish - we don't want to commit a superblock that points to + * btree nodes/leafs for which writeback hasn't finished yet + * (and without errors). + * We cleanup any entries left in the io tree when committing + * the transaction (through clear_btree_io_tree()). + */ + if (err == -ENOMEM) { + err = 0; + wait_writeback = true; + } + if (!err) + err = filemap_fdatawrite_range(mapping, start, end); if (err) werr = err; + else if (wait_writeback) + werr = filemap_fdatawait_range(mapping, start, end); + cached_state = NULL; cond_resched(); start = end + 1; } - if (err) - werr = err; return werr; } @@ -862,9 +910,21 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, while (!find_first_extent_bit(dirty_pages, start, &start, &end, EXTENT_NEED_WAIT, &cached_state)) { - clear_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, - 0, 0, &cached_state, GFP_NOFS); - err = filemap_fdatawait_range(mapping, start, end); + /* + * Ignore -ENOMEM errors returned by clear_extent_bit(). + * When committing the transaction, we'll remove any entries + * left in the io tree. For a log commit, we don't remove them + * after committing the log because the tree can be accessed + * concurrently - we do it only at transaction commit time when + * it's safe to do it (through clear_btree_io_tree()). + */ + err = clear_extent_bit(dirty_pages, start, end, + EXTENT_NEED_WAIT, + 0, 0, &cached_state, GFP_NOFS); + if (err == -ENOMEM) + err = 0; + if (!err) + err = filemap_fdatawait_range(mapping, start, end); if (err) werr = err; cond_resched(); @@ -919,17 +979,17 @@ static int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, return 0; } -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, +static int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - if (!trans || !trans->transaction) { - struct inode *btree_inode; - btree_inode = root->fs_info->btree_inode; - return filemap_write_and_wait(btree_inode->i_mapping); - } - return btrfs_write_and_wait_marked_extents(root, + int ret; + + ret = btrfs_write_and_wait_marked_extents(root, &trans->transaction->dirty_pages, EXTENT_DIRTY); + clear_btree_io_tree(&trans->transaction->dirty_pages); + + return ret; } /* diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index d8f40e1a5d2d..b3f5b40aab22 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h @@ -145,8 +145,6 @@ struct btrfs_trans_handle *btrfs_attach_transaction_barrier( struct btrfs_root *root); struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root); int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid); -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, - struct btrfs_root *root); void btrfs_add_dead_root(struct btrfs_root *root); int btrfs_defrag_root(struct btrfs_root *root); -- GitLab From e38e2ed701ff5f3d889c8dda5fe863e165e60d61 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 13 Oct 2014 12:28:38 +0100 Subject: [PATCH 5628/9457] Btrfs: make find_first_extent_bit be able to cache any state Right now the only caller of find_first_extent_bit() that is interested in caching extent states (transaction or log commit), never gets an extent state cached. This is because find_first_extent_bit() only caches states that have at least one of the flags EXTENT_IOBITS or EXTENT_BOUNDARY, and the transaction/log commit caller always passes a tree that doesn't have ever extent states with any of those flags (they can only have one of the following flags: EXTENT_DIRTY, EXTENT_NEW or EXTENT_NEED_WAIT). This change together with the following one in the patch series (titled "Btrfs: avoid returning -ENOMEM in convert_extent_bit() too early") will help reduce significantly the chances of calls to convert_extent_bit() fail with -ENOMEM when called from the transaction/log commit code. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 16 ++++++++++++---- fs/btrfs/transaction.c | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 420fe26d32d5..0d931b143c00 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -796,17 +796,25 @@ static void set_state_bits(struct extent_io_tree *tree, state->state |= bits_to_set; } -static void cache_state(struct extent_state *state, - struct extent_state **cached_ptr) +static void cache_state_if_flags(struct extent_state *state, + struct extent_state **cached_ptr, + const u64 flags) { if (cached_ptr && !(*cached_ptr)) { - if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) { + if (!flags || (state->state & flags)) { *cached_ptr = state; atomic_inc(&state->refs); } } } +static void cache_state(struct extent_state *state, + struct extent_state **cached_ptr) +{ + return cache_state_if_flags(state, cached_ptr, + EXTENT_IOBITS | EXTENT_BOUNDARY); +} + /* * set some bits on a range in the tree. This may require allocations or * sleeping, so the gfp mask is used to indicate what is allowed. @@ -1482,7 +1490,7 @@ int find_first_extent_bit(struct extent_io_tree *tree, u64 start, state = find_first_extent_bit_state(tree, start, bits); got_it: if (state) { - cache_state(state, cached_state); + cache_state_if_flags(state, cached_state, 0); *start_ret = state->start; *end_ret = state->end; ret = 0; diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 04dbc800c209..16c704b68704 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -883,6 +883,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, werr = err; else if (wait_writeback) werr = filemap_fdatawait_range(mapping, start, end); + free_extent_state(cached_state); cached_state = NULL; cond_resched(); start = end + 1; @@ -927,6 +928,8 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, err = filemap_fdatawait_range(mapping, start, end); if (err) werr = err; + free_extent_state(cached_state); + cached_state = NULL; cond_resched(); start = end + 1; } -- GitLab From c8fd3de79f44f5d41bc3a801214faf667b95df9d Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 13 Oct 2014 12:28:39 +0100 Subject: [PATCH 5629/9457] Btrfs: avoid returning -ENOMEM in convert_extent_bit() too early We try to allocate an extent state before acquiring the tree's spinlock just in case we end up needing to split an existing extent state into two. If that allocation failed, we would return -ENOMEM. However, our only single caller (transaction/log commit code), passes in an extent state that was cached from a call to find_first_extent_bit() and that has a very high chance to match exactly the input range (always true for a transaction commit and very often, but not always, true for a log commit) - in this case we end up not needing at all that initial extent state used for an eventual split. Therefore just don't return -ENOMEM if we can't allocate the temporary extent state, since we might not need it at all, and if we end up needing one, we'll do it later anyway. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 0d931b143c00..654ed3de0054 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1066,13 +1066,21 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int err = 0; u64 last_start; u64 last_end; + bool first_iteration = true; btrfs_debug_check_extent_io_range(tree, start, end); again: if (!prealloc && (mask & __GFP_WAIT)) { + /* + * Best effort, don't worry if extent state allocation fails + * here for the first iteration. We might have a cached state + * that matches exactly the target range, in which case no + * extent state allocations are needed. We'll only know this + * after locking the tree. + */ prealloc = alloc_extent_state(mask); - if (!prealloc) + if (!prealloc && !first_iteration) return -ENOMEM; } @@ -1242,6 +1250,7 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, spin_unlock(&tree->lock); if (mask & __GFP_WAIT) cond_resched(); + first_iteration = false; goto again; } -- GitLab From f382e4653f06f4e285b7800f80e6548e026f90a8 Mon Sep 17 00:00:00 2001 From: Stefan Behrens Date: Thu, 16 Oct 2014 17:48:48 +0200 Subject: [PATCH 5630/9457] Btrfs: check_int: use the known block location The xfstest btrfs/014 which tests the balance operation caused issues with the check_int module. The attempt was made to use btrfs_map_block() to find the physical location for a written block. However, this was not at all needed since the location of the written block was known since a hook to submit_bio() was the reason for entering the check_int module. Additionally, after a block relocation it happened that btrfs_map_block() failed causing misleading error messages afterwards. This patch changes the check_int module to use the known information of the physical location from the bio. Reported-by: Wang Shilong Signed-off-by: Stefan Behrens Tested-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/check-integrity.c | 66 +++++++------------------------------- 1 file changed, 11 insertions(+), 55 deletions(-) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 66e820f7b440..b5aa8124bf47 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -326,9 +326,6 @@ static int btrfsic_handle_extent_data(struct btrfsic_state *state, static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, struct btrfsic_block_data_ctx *block_ctx_out, int mirror_num); -static int btrfsic_map_superblock(struct btrfsic_state *state, u64 bytenr, - u32 len, struct block_device *bdev, - struct btrfsic_block_data_ctx *block_ctx_out); static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx); static int btrfsic_read_block(struct btrfsic_state *state, struct btrfsic_block_data_ctx *block_ctx); @@ -1607,25 +1604,6 @@ static int btrfsic_map_block(struct btrfsic_state *state, u64 bytenr, u32 len, return ret; } -static int btrfsic_map_superblock(struct btrfsic_state *state, u64 bytenr, - u32 len, struct block_device *bdev, - struct btrfsic_block_data_ctx *block_ctx_out) -{ - block_ctx_out->dev = btrfsic_dev_state_lookup(bdev); - block_ctx_out->dev_bytenr = bytenr; - block_ctx_out->start = bytenr; - block_ctx_out->len = len; - block_ctx_out->datav = NULL; - block_ctx_out->pagev = NULL; - block_ctx_out->mem_to_free = NULL; - if (NULL != block_ctx_out->dev) { - return 0; - } else { - printk(KERN_INFO "btrfsic: error, cannot lookup dev (#2)!\n"); - return -ENXIO; - } -} - static void btrfsic_release_block_ctx(struct btrfsic_block_data_ctx *block_ctx) { if (block_ctx->mem_to_free) { @@ -2002,24 +1980,13 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, } } - if (block->is_superblock) - ret = btrfsic_map_superblock(state, bytenr, - processed_len, - bdev, &block_ctx); - else - ret = btrfsic_map_block(state, bytenr, processed_len, - &block_ctx, 0); - if (ret) { - printk(KERN_INFO - "btrfsic: btrfsic_map_block(root @%llu)" - " failed!\n", bytenr); - goto continue_loop; - } - block_ctx.datav = mapped_datav; - /* the following is required in case of writes to mirrors, - * use the same that was used for the lookup */ block_ctx.dev = dev_state; block_ctx.dev_bytenr = dev_bytenr; + block_ctx.start = bytenr; + block_ctx.len = processed_len; + block_ctx.pagev = NULL; + block_ctx.mem_to_free = NULL; + block_ctx.datav = mapped_datav; if (is_metadata || state->include_extent_data) { block->never_written = 0; @@ -2133,10 +2100,6 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, /* this is getting ugly for the * include_extent_data case... */ bytenr = 0; /* unknown */ - block_ctx.start = bytenr; - block_ctx.len = processed_len; - block_ctx.mem_to_free = NULL; - block_ctx.pagev = NULL; } else { processed_len = state->metablock_size; bytenr = btrfs_stack_header_bytenr( @@ -2149,22 +2112,15 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, "Written block @%llu (%s/%llu/?)" " !found in hash table, M.\n", bytenr, dev_state->name, dev_bytenr); - - ret = btrfsic_map_block(state, bytenr, processed_len, - &block_ctx, 0); - if (ret) { - printk(KERN_INFO - "btrfsic: btrfsic_map_block(root @%llu)" - " failed!\n", - dev_bytenr); - goto continue_loop; - } } - block_ctx.datav = mapped_datav; - /* the following is required in case of writes to mirrors, - * use the same that was used for the lookup */ + block_ctx.dev = dev_state; block_ctx.dev_bytenr = dev_bytenr; + block_ctx.start = bytenr; + block_ctx.len = processed_len; + block_ctx.pagev = NULL; + block_ctx.mem_to_free = NULL; + block_ctx.datav = mapped_datav; block = btrfsic_block_alloc(); if (NULL == block) { -- GitLab From cf90c59e680ee83c263a60ee2cd464a7d96cc6d5 Mon Sep 17 00:00:00 2001 From: Stefan Behrens Date: Fri, 17 Oct 2014 14:10:10 +0200 Subject: [PATCH 5631/9457] Btrfs: check-int: don't complain about balanced blocks The xfstest btrfs/014 which tests the balance operation caused that the check_int module complained that known blocks changed their physical location. Since this is not an error in this case, only print such message if the verbose mode was enabled. Reported-by: Wang Shilong Signed-off-by: Stefan Behrens Tested-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/check-integrity.c | 80 ++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index b5aa8124bf47..47cb267b8ac7 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -1323,24 +1323,25 @@ static int btrfsic_create_link_to_next_block( l = NULL; next_block->generation = BTRFSIC_GENERATION_UNKNOWN; } else { - if (next_block->logical_bytenr != next_bytenr && - !(!next_block->is_metadata && - 0 == next_block->logical_bytenr)) { - printk(KERN_INFO - "Referenced block @%llu (%s/%llu/%d)" - " found in hash table, %c," - " bytenr mismatch (!= stored %llu).\n", - next_bytenr, next_block_ctx->dev->name, - next_block_ctx->dev_bytenr, *mirror_nump, - btrfsic_get_block_type(state, next_block), - next_block->logical_bytenr); - } else if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) - printk(KERN_INFO - "Referenced block @%llu (%s/%llu/%d)" - " found in hash table, %c.\n", - next_bytenr, next_block_ctx->dev->name, - next_block_ctx->dev_bytenr, *mirror_nump, - btrfsic_get_block_type(state, next_block)); + if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) { + if (next_block->logical_bytenr != next_bytenr && + !(!next_block->is_metadata && + 0 == next_block->logical_bytenr)) + printk(KERN_INFO + "Referenced block @%llu (%s/%llu/%d) found in hash table, %c, bytenr mismatch (!= stored %llu).\n", + next_bytenr, next_block_ctx->dev->name, + next_block_ctx->dev_bytenr, *mirror_nump, + btrfsic_get_block_type(state, + next_block), + next_block->logical_bytenr); + else + printk(KERN_INFO + "Referenced block @%llu (%s/%llu/%d) found in hash table, %c.\n", + next_bytenr, next_block_ctx->dev->name, + next_block_ctx->dev_bytenr, *mirror_nump, + btrfsic_get_block_type(state, + next_block)); + } next_block->logical_bytenr = next_bytenr; next_block->mirror_num = *mirror_nump; @@ -1526,7 +1527,9 @@ static int btrfsic_handle_extent_data( return -1; } if (!block_was_created) { - if (next_block->logical_bytenr != next_bytenr && + if ((state->print_mask & + BTRFSIC_PRINT_MASK_VERBOSE) && + next_block->logical_bytenr != next_bytenr && !(!next_block->is_metadata && 0 == next_block->logical_bytenr)) { printk(KERN_INFO @@ -1879,25 +1882,26 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, dev_state, dev_bytenr); } - if (block->logical_bytenr != bytenr && - !(!block->is_metadata && - block->logical_bytenr == 0)) - printk(KERN_INFO - "Written block @%llu (%s/%llu/%d)" - " found in hash table, %c," - " bytenr mismatch" - " (!= stored %llu).\n", - bytenr, dev_state->name, dev_bytenr, - block->mirror_num, - btrfsic_get_block_type(state, block), - block->logical_bytenr); - else if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) - printk(KERN_INFO - "Written block @%llu (%s/%llu/%d)" - " found in hash table, %c.\n", - bytenr, dev_state->name, dev_bytenr, - block->mirror_num, - btrfsic_get_block_type(state, block)); + if (state->print_mask & BTRFSIC_PRINT_MASK_VERBOSE) { + if (block->logical_bytenr != bytenr && + !(!block->is_metadata && + block->logical_bytenr == 0)) + printk(KERN_INFO + "Written block @%llu (%s/%llu/%d) found in hash table, %c, bytenr mismatch (!= stored %llu).\n", + bytenr, dev_state->name, + dev_bytenr, + block->mirror_num, + btrfsic_get_block_type(state, + block), + block->logical_bytenr); + else + printk(KERN_INFO + "Written block @%llu (%s/%llu/%d) found in hash table, %c.\n", + bytenr, dev_state->name, + dev_bytenr, block->mirror_num, + btrfsic_get_block_type(state, + block)); + } block->logical_bytenr = bytenr; } else { if (num_pages * PAGE_CACHE_SIZE < -- GitLab From cd743fac42bbc2e6125ee14aaa8741601f92fe9a Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 31 Oct 2014 19:40:14 +0100 Subject: [PATCH 5632/9457] btrfs: fix typos in btrfs_check_super_valid Copy&paste errors in some messages and add few more missing macro accessors. Signed-off-by: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 1bf9f897065d..7af9a1978a2f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3839,12 +3839,12 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, */ if (!IS_ALIGNED(btrfs_super_root(sb), 4096)) printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n", - sb->root); + btrfs_super_root(sb)); if (!IS_ALIGNED(btrfs_super_chunk_root(sb), 4096)) - printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n", - sb->chunk_root); + printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n", + btrfs_super_chunk_root(sb)); if (!IS_ALIGNED(btrfs_super_log_root(sb), 4096)) - printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n", + printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n", btrfs_super_log_root(sb)); if (memcmp(fs_info->fsid, sb->dev_item.fsid, BTRFS_UUID_SIZE) != 0) { -- GitLab From 633c0aad4c0243a506a3e8590551085ad78af82d Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 31 Oct 2014 09:49:34 -0400 Subject: [PATCH 5633/9457] Btrfs: move read only block groups onto their own list V2 Our gluster boxes were spending lots of time in statfs because our fs'es are huge. The problem is statfs loops through all of the block groups looking for read only block groups, and when you have several terabytes worth of data that ends up being a lot of block groups. Move the read only block groups onto a read only list and only proces that list in btrfs_account_ro_block_groups_free_space to reduce the amount of churn. Thanks, Signed-off-by: Josef Bacik Reviewed-by: Liu Bo Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 4 ++++ fs/btrfs/extent-tree.c | 36 +++++++++++++----------------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b72b35867a7f..fa14081e3383 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1170,6 +1170,7 @@ struct btrfs_space_info { struct percpu_counter total_bytes_pinned; struct list_head list; + struct list_head ro_bgs; struct rw_semaphore groups_sem; /* for block groups in our same type */ @@ -1305,6 +1306,9 @@ struct btrfs_block_group_cache { /* For delayed block group creation or deletion of empty block groups */ struct list_head bg_list; + + /* For read-only block groups */ + struct list_head ro_list; }; /* delayed seq elem */ diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 47c1ba141082..cf3460e9b122 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3504,6 +3504,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, found->chunk_alloc = 0; found->flush = 0; init_waitqueue_head(&found->wait); + INIT_LIST_HEAD(&found->ro_bgs); ret = kobject_init_and_add(&found->kobj, &space_info_ktype, info->space_info_kobj, "%s", @@ -8511,6 +8512,7 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache, int force) min_allocable_bytes <= sinfo->total_bytes) { sinfo->bytes_readonly += num_bytes; cache->ro = 1; + list_add_tail(&cache->ro_list, &sinfo->ro_bgs); ret = 0; } out: @@ -8565,15 +8567,20 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, /* * helper to account the unused space of all the readonly block group in the - * list. takes mirrors into account. + * space_info. takes mirrors into account. */ -static u64 __btrfs_get_ro_block_group_free_space(struct list_head *groups_list) +u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) { struct btrfs_block_group_cache *block_group; u64 free_bytes = 0; int factor; - list_for_each_entry(block_group, groups_list, list) { + /* It's df, we don't care if it's racey */ + if (list_empty(&sinfo->ro_bgs)) + return 0; + + spin_lock(&sinfo->lock); + list_for_each_entry(block_group, &sinfo->ro_bgs, ro_list) { spin_lock(&block_group->lock); if (!block_group->ro) { @@ -8594,26 +8601,6 @@ static u64 __btrfs_get_ro_block_group_free_space(struct list_head *groups_list) spin_unlock(&block_group->lock); } - - return free_bytes; -} - -/* - * helper to account the unused space of all the readonly block group in the - * space_info. takes mirrors into account. - */ -u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) -{ - int i; - u64 free_bytes = 0; - - spin_lock(&sinfo->lock); - - for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) - if (!list_empty(&sinfo->block_groups[i])) - free_bytes += __btrfs_get_ro_block_group_free_space( - &sinfo->block_groups[i]); - spin_unlock(&sinfo->lock); return free_bytes; @@ -8633,6 +8620,7 @@ void btrfs_set_block_group_rw(struct btrfs_root *root, cache->bytes_super - btrfs_block_group_used(&cache->item); sinfo->bytes_readonly -= num_bytes; cache->ro = 0; + list_del_init(&cache->ro_list); spin_unlock(&cache->lock); spin_unlock(&sinfo->lock); } @@ -9002,6 +8990,7 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) INIT_LIST_HEAD(&cache->list); INIT_LIST_HEAD(&cache->cluster_list); INIT_LIST_HEAD(&cache->bg_list); + INIT_LIST_HEAD(&cache->ro_list); btrfs_init_free_space_ctl(cache); return cache; @@ -9411,6 +9400,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, * are still on the list after taking the semaphore */ list_del_init(&block_group->list); + list_del_init(&block_group->ro_list); if (list_empty(&block_group->space_info->block_groups[index])) { kobj = block_group->space_info->block_group_kobjs[index]; block_group->space_info->block_group_kobjs[index] = NULL; -- GitLab From 7e33fd993a74b3fda39c756803ba8b24bef72df5 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 3 Nov 2014 08:56:50 -0500 Subject: [PATCH 5634/9457] Btrfs: don't take the chunk_mutex/dev_list mutex in statfs V2 Our gluster boxes get several thousand statfs() calls per second, which begins to suck hardcore with all of the lock contention on the chunk mutex and dev list mutex. We don't really need to hold these things, if we have transient weirdness with statfs() because of the chunk allocator we don't care, so remove this locking. We still need the dev_list lock if you mount with -o alloc_start however, which is a good argument for nuking that thing from orbit, but that's a patch for another day. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/super.c | 72 +++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 54bd91ece35b..dc337d14ef5c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1644,8 +1644,20 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) int i = 0, nr_devices; int ret; + /* + * We aren't under the device list lock, so this is racey-ish, but good + * enough for our purposes. + */ nr_devices = fs_info->fs_devices->open_devices; - BUG_ON(!nr_devices); + if (!nr_devices) { + smp_mb(); + nr_devices = fs_info->fs_devices->open_devices; + ASSERT(nr_devices); + if (!nr_devices) { + *free_bytes = 0; + return 0; + } + } devices_info = kmalloc_array(nr_devices, sizeof(*devices_info), GFP_NOFS); @@ -1670,11 +1682,17 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) else min_stripe_size = BTRFS_STRIPE_LEN; - list_for_each_entry(device, &fs_devices->devices, dev_list) { + if (fs_info->alloc_start) + mutex_lock(&fs_devices->device_list_mutex); + rcu_read_lock(); + list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { if (!device->in_fs_metadata || !device->bdev || device->is_tgtdev_for_dev_replace) continue; + if (i >= nr_devices) + break; + avail_space = device->total_bytes - device->bytes_used; /* align with stripe_len */ @@ -1689,24 +1707,32 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) skip_space = 1024 * 1024; /* user can set the offset in fs_info->alloc_start. */ - if (fs_info->alloc_start + BTRFS_STRIPE_LEN <= - device->total_bytes) + if (fs_info->alloc_start && + fs_info->alloc_start + BTRFS_STRIPE_LEN <= + device->total_bytes) { + rcu_read_unlock(); skip_space = max(fs_info->alloc_start, skip_space); - /* - * btrfs can not use the free space in [0, skip_space - 1], - * we must subtract it from the total. In order to implement - * it, we account the used space in this range first. - */ - ret = btrfs_account_dev_extents_size(device, 0, skip_space - 1, - &used_space); - if (ret) { - kfree(devices_info); - return ret; - } + /* + * btrfs can not use the free space in + * [0, skip_space - 1], we must subtract it from the + * total. In order to implement it, we account the used + * space in this range first. + */ + ret = btrfs_account_dev_extents_size(device, 0, + skip_space - 1, + &used_space); + if (ret) { + kfree(devices_info); + mutex_unlock(&fs_devices->device_list_mutex); + return ret; + } - /* calc the free space in [0, skip_space - 1] */ - skip_space -= used_space; + rcu_read_lock(); + + /* calc the free space in [0, skip_space - 1] */ + skip_space -= used_space; + } /* * we can use the free space in [0, skip_space - 1], subtract @@ -1725,6 +1751,9 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) i++; } + rcu_read_unlock(); + if (fs_info->alloc_start) + mutex_unlock(&fs_devices->device_list_mutex); nr_devices = i; @@ -1787,8 +1816,6 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) * holding chunk_muext to avoid allocating new chunks, holding * device_list_mutex to avoid the device being removed */ - mutex_lock(&fs_info->fs_devices->device_list_mutex); - mutex_lock(&fs_info->chunk_mutex); rcu_read_lock(); list_for_each_entry_rcu(found, head, list) { if (found->flags & BTRFS_BLOCK_GROUP_DATA) { @@ -1826,15 +1853,10 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bavail = total_free_data; ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); - if (ret) { - mutex_unlock(&fs_info->chunk_mutex); - mutex_unlock(&fs_info->fs_devices->device_list_mutex); + if (ret) return ret; - } buf->f_bavail += div_u64(total_free_data, factor); buf->f_bavail = buf->f_bavail >> bits; - mutex_unlock(&fs_info->chunk_mutex); - mutex_unlock(&fs_info->fs_devices->device_list_mutex); buf->f_type = BTRFS_SUPER_MAGIC; buf->f_bsize = dentry->d_sb->s_blocksize; -- GitLab From c7bc6319c59cc791743cf1b6e98f86be69444495 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 3 Nov 2014 14:12:57 +0000 Subject: [PATCH 5635/9457] Btrfs: avoid premature -ENOMEM in clear_extent_bit() We try to allocate an extent state structure before acquiring the extent state tree's spinlock as we might need a new one later and therefore avoid doing later an atomic allocation while holding the tree's spinlock. However we returned -ENOMEM if that initial non-atomic allocation failed, which is a bit excessive since we might end up not needing the pre-allocated extent state at all - for the case where the tree doesn't have any extent states that cover the input range and cover too any other range. Therefore don't return -ENOMEM if that pre-allocation fails. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 654ed3de0054..4ebabd237153 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -595,9 +595,14 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, clear = 1; again: if (!prealloc && (mask & __GFP_WAIT)) { + /* + * Don't care for allocation failure here because we might end + * up not needing the pre-allocated extent state at all, which + * is the case if we only have in the tree extent states that + * cover our input range and don't cover too any other range. + * If we end up needing a new extent state we allocate it later. + */ prealloc = alloc_extent_state(mask); - if (!prealloc) - return -ENOMEM; } spin_lock(&tree->lock); -- GitLab From 5f5bc6b1e2d5a6f827bc860ef2dc5b6f365d1339 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 9 Nov 2014 08:38:39 +0000 Subject: [PATCH 5636/9457] Btrfs: make xattr replace operations atomic Replacing a xattr consists of doing a lookup for its existing value, delete the current value from the respective leaf, release the search path and then finally insert the new value. This leaves a time window where readers (getxattr, listxattrs) won't see any value for the xattr. Xattrs are used to store ACLs, so this has security implications. This change also fixes 2 other existing issues which were: *) Deleting the old xattr value without verifying first if the new xattr will fit in the existing leaf item (in case multiple xattrs are packed in the same item due to name hash collision); *) Returning -EEXIST when the flag XATTR_CREATE is given and the xattr doesn't exist but we have have an existing item that packs muliple xattrs with the same name hash as the input xattr. In this case we should return ENOSPC. A test case for xfstests follows soon. Thanks to Alexandre Oliva for reporting the non-atomicity of the xattr replace implementation. Reported-by: Alexandre Oliva Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ctree.c | 2 +- fs/btrfs/ctree.h | 5 ++ fs/btrfs/dir-item.c | 10 +-- fs/btrfs/xattr.c | 150 +++++++++++++++++++++++++++----------------- 4 files changed, 102 insertions(+), 65 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 19bc6162fb8e..817234168a7f 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2939,7 +2939,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root */ if (!p->leave_spinning) btrfs_set_path_blocking(p); - if (ret < 0) + if (ret < 0 && !p->skip_release_on_error) btrfs_release_path(p); return ret; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index fa14081e3383..a9466e346358 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -607,6 +607,7 @@ struct btrfs_path { unsigned int leave_spinning:1; unsigned int search_commit_root:1; unsigned int need_commit_sem:1; + unsigned int skip_release_on_error:1; }; /* @@ -3690,6 +3691,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, int verify_dir_item(struct btrfs_root *root, struct extent_buffer *leaf, struct btrfs_dir_item *dir_item); +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, + int name_len); /* orphan.c */ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index fc8df866e919..1752625fb4dd 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -21,10 +21,6 @@ #include "hash.h" #include "transaction.h" -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len); - /* * insert a name into a directory, doing overflow properly if there is a hash * collision. data_size indicates how big the item inserted should be. On @@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, * this walks through all the entries in a dir item and finds one * for a specific name. */ -static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, - struct btrfs_path *path, - const char *name, int name_len) +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, int name_len) { struct btrfs_dir_item *dir_item; unsigned long name_ptr; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index dcf20131fbe4..47b19465f0dc 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -29,6 +29,7 @@ #include "xattr.h" #include "disk-io.h" #include "props.h" +#include "locking.h" ssize_t __btrfs_getxattr(struct inode *inode, const char *name, @@ -91,7 +92,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, const char *name, const void *value, size_t size, int flags) { - struct btrfs_dir_item *di; + struct btrfs_dir_item *di = NULL; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path; size_t name_len = strlen(name); @@ -103,84 +104,119 @@ static int do_setxattr(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; + path->skip_release_on_error = 1; + + if (!value) { + di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), + name, name_len, -1); + if (!di && (flags & XATTR_REPLACE)) + ret = -ENODATA; + else if (di) + ret = btrfs_delete_one_dir_name(trans, root, path, di); + goto out; + } + /* + * For a replace we can't just do the insert blindly. + * Do a lookup first (read-only btrfs_search_slot), and return if xattr + * doesn't exist. If it exists, fall down below to the insert/replace + * path - we can't race with a concurrent xattr delete, because the VFS + * locks the inode's i_mutex before calling setxattr or removexattr. + */ if (flags & XATTR_REPLACE) { - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, - name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { + ASSERT(mutex_is_locked(&inode->i_mutex)); + di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), + name, name_len, 0); + if (!di) { ret = -ENODATA; goto out; } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; btrfs_release_path(path); + di = NULL; + } + ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), + name, name_len, value, size); + if (ret == -EOVERFLOW) { /* - * remove the attribute + * We have an existing item in a leaf, split_leaf couldn't + * expand it. That item might have or not a dir_item that + * matches our target xattr, so lets check. */ - if (!value) - goto out; - } else { - di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), - name, name_len, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); + ret = 0; + btrfs_assert_tree_locked(path->nodes[0]); + di = btrfs_match_dir_item_name(root, path, name, name_len); + if (!di && !(flags & XATTR_REPLACE)) { + ret = -ENOSPC; goto out; } - if (!di && !value) - goto out; - btrfs_release_path(path); + } else if (ret == -EEXIST) { + ret = 0; + di = btrfs_match_dir_item_name(root, path, name, name_len); + ASSERT(di); /* logic error */ + } else if (ret) { + goto out; } -again: - ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), - name, name_len, value, size); - /* - * If we're setting an xattr to a new value but the new value is say - * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting - * back from split_leaf. This is because it thinks we'll be extending - * the existing item size, but we're asking for enough space to add the - * item itself. So if we get EOVERFLOW just set ret to EEXIST and let - * the rest of the function figure it out. - */ - if (ret == -EOVERFLOW) + if (di && (flags & XATTR_CREATE)) { ret = -EEXIST; + goto out; + } - if (ret == -EEXIST) { - if (flags & XATTR_CREATE) - goto out; + if (di) { /* - * We can't use the path we already have since we won't have the - * proper locking for a delete, so release the path and - * re-lookup to delete the thing. + * We're doing a replace, and it must be atomic, that is, at + * any point in time we have either the old or the new xattr + * value in the tree. We don't want readers (getxattr and + * listxattrs) to miss a value, this is specially important + * for ACLs. */ - btrfs_release_path(path); - di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), - name, name_len, -1); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; - } else if (!di) { - /* Shouldn't happen but just in case... */ - btrfs_release_path(path); - goto again; + const int slot = path->slots[0]; + struct extent_buffer *leaf = path->nodes[0]; + const u16 old_data_len = btrfs_dir_data_len(leaf, di); + const u32 item_size = btrfs_item_size_nr(leaf, slot); + const u32 data_size = sizeof(*di) + name_len + size; + struct btrfs_item *item; + unsigned long data_ptr; + char *ptr; + + if (size > old_data_len) { + if (btrfs_leaf_free_space(root, leaf) < + (size - old_data_len)) { + ret = -ENOSPC; + goto out; + } } - ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) - goto out; + if (old_data_len + name_len + sizeof(*di) == item_size) { + /* No other xattrs packed in the same leaf item. */ + if (size > old_data_len) + btrfs_extend_item(root, path, + size - old_data_len); + else if (size < old_data_len) + btrfs_truncate_item(root, path, data_size, 1); + } else { + /* There are other xattrs packed in the same item. */ + ret = btrfs_delete_one_dir_name(trans, root, path, di); + if (ret) + goto out; + btrfs_extend_item(root, path, data_size); + } + item = btrfs_item_nr(slot); + ptr = btrfs_item_ptr(leaf, slot, char); + ptr += btrfs_item_size(leaf, item) - data_size; + di = (struct btrfs_dir_item *)ptr; + btrfs_set_dir_data_len(leaf, di, size); + data_ptr = ((unsigned long)(di + 1)) + name_len; + write_extent_buffer(leaf, value, data_ptr, size); + btrfs_mark_buffer_dirty(leaf); + } else { /* - * We have a value to set, so go back and try to insert it now. + * Insert, and we had space for the xattr, so path->slots[0] is + * where our xattr dir_item is and btrfs_insert_xattr_item() + * filled it. */ - if (value) { - btrfs_release_path(path); - goto again; - } } out: btrfs_free_path(path); -- GitLab From 321592427c0146126aadfab8a9b663de1875c9f4 Mon Sep 17 00:00:00 2001 From: Gui Hecheng Date: Mon, 10 Nov 2014 15:36:08 +0800 Subject: [PATCH 5637/9457] btrfs: fix dead lock while running replace and defrag concurrently This can be reproduced by fstests: btrfs/070 The scenario is like the following: replace worker thread defrag thread --------------------- ------------- copy_nocow_pages_worker btrfs_defrag_file copy_nocow_pages_for_inode ... btrfs_writepages |A| lock_extent_bits extent_write_cache_pages |B| lock_page __extent_writepage ... writepage_delalloc find_lock_delalloc_range |B| lock_extent_bits find_or_create_page pagecache_get_page |A| lock_page This leads to an ABBA pattern deadlock. To fix it, o we just change it to an AABB pattern which means to @unlock_extent_bits() before we @lock_page(), and in this way the @extent_read_full_page_nolock() is no longer in an locked context, so change it back to @extent_read_full_page() to regain protection. o Since we @unlock_extent_bits() earlier, then before @write_page_nocow(), the extent may not really point at the physical block we want, so we have to check it before write. Signed-off-by: Gui Hecheng Tested-by: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/scrub.c | 90 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index efa083113827..4325bb0111d9 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -3310,6 +3310,50 @@ static void copy_nocow_pages_worker(struct btrfs_work *work) scrub_pending_trans_workers_dec(sctx); } +static int check_extent_to_block(struct inode *inode, u64 start, u64 len, + u64 logical) +{ + struct extent_state *cached_state = NULL; + struct btrfs_ordered_extent *ordered; + struct extent_io_tree *io_tree; + struct extent_map *em; + u64 lockstart = start, lockend = start + len - 1; + int ret = 0; + + io_tree = &BTRFS_I(inode)->io_tree; + + lock_extent_bits(io_tree, lockstart, lockend, 0, &cached_state); + ordered = btrfs_lookup_ordered_range(inode, lockstart, len); + if (ordered) { + btrfs_put_ordered_extent(ordered); + ret = 1; + goto out_unlock; + } + + em = btrfs_get_extent(inode, NULL, 0, start, len, 0); + if (IS_ERR(em)) { + ret = PTR_ERR(em); + goto out_unlock; + } + + /* + * This extent does not actually cover the logical extent anymore, + * move on to the next inode. + */ + if (em->block_start > logical || + em->block_start + em->block_len < logical + len) { + free_extent_map(em); + ret = 1; + goto out_unlock; + } + free_extent_map(em); + +out_unlock: + unlock_extent_cached(io_tree, lockstart, lockend, &cached_state, + GFP_NOFS); + return ret; +} + static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, struct scrub_copy_nocow_ctx *nocow_ctx) { @@ -3318,13 +3362,10 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, struct inode *inode; struct page *page; struct btrfs_root *local_root; - struct btrfs_ordered_extent *ordered; - struct extent_map *em; - struct extent_state *cached_state = NULL; struct extent_io_tree *io_tree; u64 physical_for_dev_replace; + u64 nocow_ctx_logical; u64 len = nocow_ctx->len; - u64 lockstart = offset, lockend = offset + len - 1; unsigned long index; int srcu_index; int ret = 0; @@ -3356,30 +3397,13 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, physical_for_dev_replace = nocow_ctx->physical_for_dev_replace; io_tree = &BTRFS_I(inode)->io_tree; + nocow_ctx_logical = nocow_ctx->logical; - lock_extent_bits(io_tree, lockstart, lockend, 0, &cached_state); - ordered = btrfs_lookup_ordered_range(inode, lockstart, len); - if (ordered) { - btrfs_put_ordered_extent(ordered); - goto out_unlock; - } - - em = btrfs_get_extent(inode, NULL, 0, lockstart, len, 0); - if (IS_ERR(em)) { - ret = PTR_ERR(em); - goto out_unlock; - } - - /* - * This extent does not actually cover the logical extent anymore, - * move on to the next inode. - */ - if (em->block_start > nocow_ctx->logical || - em->block_start + em->block_len < nocow_ctx->logical + len) { - free_extent_map(em); - goto out_unlock; + ret = check_extent_to_block(inode, offset, len, nocow_ctx_logical); + if (ret) { + ret = ret > 0 ? 0 : ret; + goto out; } - free_extent_map(em); while (len >= PAGE_CACHE_SIZE) { index = offset >> PAGE_CACHE_SHIFT; @@ -3396,7 +3420,7 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, goto next_page; } else { ClearPageError(page); - err = extent_read_full_page_nolock(io_tree, page, + err = extent_read_full_page(io_tree, page, btrfs_get_extent, nocow_ctx->mirror_num); if (err) { @@ -3421,6 +3445,14 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, goto next_page; } } + + ret = check_extent_to_block(inode, offset, len, + nocow_ctx_logical); + if (ret) { + ret = ret > 0 ? 0 : ret; + goto next_page; + } + err = write_page_nocow(nocow_ctx->sctx, physical_for_dev_replace, page); if (err) @@ -3434,12 +3466,10 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, offset += PAGE_CACHE_SIZE; physical_for_dev_replace += PAGE_CACHE_SIZE; + nocow_ctx_logical += PAGE_CACHE_SIZE; len -= PAGE_CACHE_SIZE; } ret = COPY_COMPLETE; -out_unlock: - unlock_extent_cached(io_tree, lockstart, lockend, &cached_state, - GFP_NOFS); out: mutex_unlock(&inode->i_mutex); iput(inode); -- GitLab From 0d95c1bec906dd1ad951c9c001e798ca52baeb0f Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 14 Nov 2014 15:05:06 +0100 Subject: [PATCH 5638/9457] btrfs: fix wrong accounting of raid1 data profile in statfs The sizes that are obtained from space infos are in raw units and have to be adjusted according to the raid factor. This was missing for f_bavail and df reported doubled size for raid1. Reported-by: Martin Steigerwald Fixes: ba7b6e62f420 ("btrfs: adjust statfs calculations according to raid profiles") CC: stable@vger.kernel.org Signed-off-by: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index dc337d14ef5c..21c60ee2f664 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1851,7 +1851,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bfree -= block_rsv->size >> bits; spin_unlock(&block_rsv->lock); - buf->f_bavail = total_free_data; + buf->f_bavail = div_u64(total_free_data, factor); ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); if (ret) return ret; -- GitLab From 9dba8cf128ef98257ca719722280c9634e7e9dc7 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Thu, 6 Nov 2014 10:19:54 -0500 Subject: [PATCH 5639/9457] Btrfs: make sure we wait on logged extents when fsycning two subvols If we have two fsync()'s race on different subvols one will do all of its work to get into the log_tree, wait on it's outstanding IO, and then allow the log_tree to finish it's commit. The problem is we were just free'ing that subvols logged extents instead of waiting on them, so whoever lost the race wouldn't really have their data on disk. Fix this by waiting properly instead of freeing the logged extents. Thanks, cc: stable@vger.kernel.org Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/tree-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 286213cec861..fc715ff31d26 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2600,9 +2600,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, if (atomic_read(&log_root_tree->log_commit[index2])) { blk_finish_plug(&plug); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + btrfs_wait_logged_extents(log, log_transid); wait_log_commit(trans, log_root_tree, root_log_ctx.log_transid); - btrfs_free_logged_extents(log, log_transid); mutex_unlock(&log_root_tree->log_mutex); ret = root_log_ctx.log_ret; goto out; -- GitLab From 355a70183848f21198e9f6296bd646df3478a26d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 20 Nov 2014 09:56:25 +0100 Subject: [PATCH 5640/9457] drm/gem: Warn on illegal use of the dumb buffer interface v2 It happens on occasion that developers of generic user-space applications abuse the dumb buffer API to get hold of drm buffers that they can both mmap() and use for GPU acceleration, using the assumptions that dumb buffers and buffers available for GPU are a) The same type and can be aribtrarily type-casted. b) fully coherent. This patch makes the most widely used drivers warn nicely when that happens, the next step will be to fail. v2: Move drmP.h changes to drm_gem.h. Fix Radeon dumb mmap breakage. Signed-off-by: Thomas Hellstrom Acked-by: Daniel Vetter Acked-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 ++-- drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_display.c | 9 +++++++ drivers/gpu/drm/nouveau/nouveau_gem.c | 3 +++ drivers/gpu/drm/radeon/radeon_gem.c | 26 ++++++++++++++++---- drivers/gpu/drm/radeon/radeon_object.c | 3 +++ include/drm/drm_gem.h | 7 ++++++ 9 files changed, 74 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2404b2baa01e..c743908b0a7e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1593,7 +1593,7 @@ static struct drm_driver driver = { .gem_prime_import = i915_gem_prime_import, .dumb_create = i915_gem_dumb_create, - .dumb_map_offset = i915_gem_mmap_gtt, + .dumb_map_offset = i915_gem_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, .ioctls = i915_ioctls, .fops = &i915_driver_fops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f830596faa9e..4ba1aca071da 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2523,8 +2523,9 @@ void i915_vma_move_to_active(struct i915_vma *vma, int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle, uint64_t *offset); +int i915_gem_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *dev, uint32_t handle, + uint64_t *offset); /** * Returns true if seq1 is later than seq2. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3e0cabe9b544..50b842231c26 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -346,6 +346,7 @@ static int i915_gem_create(struct drm_file *file, struct drm_device *dev, uint64_t size, + bool dumb, uint32_t *handle_p) { struct drm_i915_gem_object *obj; @@ -361,6 +362,7 @@ i915_gem_create(struct drm_file *file, if (obj == NULL) return -ENOMEM; + obj->base.dumb = dumb; ret = drm_gem_handle_create(file, &obj->base, &handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(&obj->base); @@ -380,7 +382,7 @@ i915_gem_dumb_create(struct drm_file *file, args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); args->size = args->pitch * args->height; return i915_gem_create(file, dev, - args->size, &args->handle); + args->size, true, &args->handle); } /** @@ -393,7 +395,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_create *args = data; return i915_gem_create(file, dev, - args->size, &args->handle); + args->size, false, &args->handle); } static inline int @@ -1773,10 +1775,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) drm_gem_free_mmap_offset(&obj->base); } -int +static int i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, + uint32_t handle, bool dumb, uint64_t *offset) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1793,6 +1795,13 @@ i915_gem_mmap_gtt(struct drm_file *file, goto unlock; } + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach), + "Illegal dumb map of accelerated buffer.\n"); + if (obj->base.size > dev_priv->gtt.mappable_end) { ret = -E2BIG; goto out; @@ -1817,6 +1826,15 @@ i915_gem_mmap_gtt(struct drm_file *file, return ret; } +int +i915_gem_dumb_map_offset(struct drm_file *file, + struct drm_device *dev, + uint32_t handle, + uint64_t *offset) +{ + return i915_gem_mmap_gtt(file, dev, handle, true, offset); +} + /** * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing * @dev: DRM device @@ -1838,7 +1856,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_mmap_gtt *args = data; - return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); + return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset); } static inline int diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e1ed85a6dc6d..2b02fcfae534 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -121,6 +121,9 @@ eb_lookup_vmas(struct eb_vmas *eb, goto err; } + WARN_ONCE(obj->base.dumb, + "GPU use of dumb buffer is illegal.\n"); + drm_gem_object_reference(&obj->base); list_add_tail(&obj->obj_exec_link, &objects); } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index a88e6927f571..2640fcfa5c37 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -871,6 +871,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, if (ret) return ret; + bo->gem.dumb = true; ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); drm_gem_object_unreference_unlocked(&bo->gem); return ret; @@ -886,6 +887,14 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, gem = drm_gem_object_lookup(dev, file_priv, handle); if (gem) { struct nouveau_bo *bo = nouveau_gem_object(gem); + + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(!(gem->dumb || gem->import_attach), + "Illegal dumb map of accelerated buffer.\n"); + *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); drm_gem_object_unreference_unlocked(gem); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 36951ee4b157..ebba9deb0d04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -444,6 +444,9 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; + WARN_ONCE(nvbo->gem.dumb, + "GPU use of dumb buffer is illegal.\n"); + ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, b->write_domains, b->valid_domains); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c194497aa586..429213b6ed0f 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -394,9 +394,10 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, return r; } -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) +static int radeon_mode_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, bool dumb, + uint64_t *offset_p) { struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -405,6 +406,14 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, if (gobj == NULL) { return -ENOENT; } + + /* + * We don't allow dumb mmaps on objects created using another + * interface. + */ + WARN_ONCE(dumb && !(gobj->dumb || gobj->import_attach), + "Illegal dumb map of GPU buffer.\n"); + robj = gem_to_radeon_bo(gobj); if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { drm_gem_object_unreference_unlocked(gobj); @@ -415,12 +424,20 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, return 0; } +int radeon_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p) +{ + return radeon_mode_mmap(filp, dev, handle, true, offset_p); +} + int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct drm_radeon_gem_mmap *args = data; - return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); + return radeon_mode_mmap(filp, dev, args->handle, false, + &args->addr_ptr); } int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, @@ -682,6 +699,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, return -ENOMEM; r = drm_gem_handle_create(file_priv, gobj, &handle); + gobj->dumb = true; /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 33e6c7a89c32..76eedd6a34f0 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -521,6 +521,9 @@ int radeon_bo_list_validate(struct radeon_device *rdev, u32 current_domain = radeon_mem_type_to_domain(bo->tbo.mem.mem_type); + WARN_ONCE(bo->gem_base.dumb, + "GPU use of dumb buffer is illegal.\n"); + /* Check if this buffer will be moved and don't move it * if we have moved too many buffers for this IB already. * diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 1e6ae1458f7a..780511a459c0 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -119,6 +119,13 @@ struct drm_gem_object { * simply leave it as NULL. */ struct dma_buf_attachment *import_attach; + + /** + * dumb - created as dumb buffer + * Whether the gem object was created using the dumb buffer interface + * as such it may not be used for GPU rendering. + */ + bool dumb; }; void drm_gem_object_release(struct drm_gem_object *obj); -- GitLab From fc2d2bc1f1f8d8351f884bb65b5cc4ad2411b2a7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 20 Nov 2014 09:53:35 +0100 Subject: [PATCH 5641/9457] drm/atomic: Add missing ERR_PTR casting This is an oversight from commit f52b69f1ecfdd7ef6867a257620258c09e569552 Author: Daniel Vetter Date: Wed Nov 19 18:38:08 2014 +0100 drm/atomic: Don't overrun the connector array when hotplugging Cc: Dave Airlie Cc: Rob Clark Signed-off-by: Daniel Vetter Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_atomic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3624632084e2..d3b46746b611 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -318,7 +318,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, */ if (index >= state->num_connector) { DRM_DEBUG_KMS("Hot-added connector would overflow state array, restarting\n"); - return -EAGAIN; + return ERR_PTR(-EAGAIN); } if (state->connector_states[index]) -- GitLab From 9084acf19bb98afb0ed90337fd39541103fe3494 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 16:33:17 +0100 Subject: [PATCH 5642/9457] drm/edid: Deletion of an unnecessary check before the function call "release_firmware" The release_firmware() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid_load.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 0a235fe61c9b..732cb6f8e653 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c @@ -254,8 +254,7 @@ static void *edid_load(struct drm_connector *connector, const char *name, name, connector_name); out: - if (fw) - release_firmware(fw); + release_firmware(fw); return edid; } -- GitLab From c08448173545428ed9761308fbaf90f8be7498c5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 17:05:20 +0100 Subject: [PATCH 5643/9457] drm/tilcdc: Deletion of an unnecessary check before the function call "drm_fbdev_cma_hotplug_event" The drm_fbdev_cma_hotplug_event() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 79a34cbd29f5..d56d3f8b8d6b 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -58,8 +58,7 @@ static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev, static void tilcdc_fb_output_poll_changed(struct drm_device *dev) { struct tilcdc_drm_private *priv = dev->dev_private; - if (priv->fbdev) - drm_fbdev_cma_hotplug_event(priv->fbdev); + drm_fbdev_cma_hotplug_event(priv->fbdev); } static const struct drm_mode_config_funcs mode_config_funcs = { -- GitLab From e9196d238597da0189b035f37c473c411275b0dd Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 17:33:32 +0100 Subject: [PATCH 5644/9457] drm/udl: Deletion of an unnecessary check before the function call "vunmap" The vunmap() function performes also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_gem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 692d6f21f1bc..cd3482de5cab 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -184,8 +184,7 @@ void udl_gem_vunmap(struct udl_gem_object *obj) return; } - if (obj->vmapping) - vunmap(obj->vmapping); + vunmap(obj->vmapping); udl_gem_put_pages(obj); } -- GitLab From a3a1a6674f7fd6c0f7e673c4fc1b1aea3d8fce53 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 17:50:19 +0100 Subject: [PATCH 5645/9457] drm/vmwgfx: Deletion of an unnecessary check before the function call "vfree" The vfree() function performes also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 25f3c250fd98..db7621828bc7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -889,8 +889,7 @@ static int vmw_driver_unload(struct drm_device *dev) if (dev_priv->ctx.res_ht_initialized) drm_ht_remove(&dev_priv->ctx.res_ht); - if (dev_priv->ctx.cmd_bounce) - vfree(dev_priv->ctx.cmd_bounce); + vfree(dev_priv->ctx.cmd_bounce); if (dev_priv->enable_fb) { vmw_fb_close(dev_priv); vmw_kms_restore_vga(dev_priv); -- GitLab From 413d404768256eda4e13fdfce753fe2bbff2fcaf Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 19 Nov 2014 13:31:08 +0100 Subject: [PATCH 5646/9457] s390/traps: print interrupt code and instruction length code It always confuses me to see the mixed instruction length code and interruption code on user space faults, while the message clearly says it is the interruption code. So split the value and print both values separately. Also add the ILC output to the die() message, so thar user and kernel space faults contain the same information. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/dumpstack.c | 3 ++- arch/s390/kernel/traps.c | 3 ++- arch/s390/mm/fault.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index acb412442e5e..a99852e96a77 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -191,7 +191,8 @@ void die(struct pt_regs *regs, const char *str) console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); + printk("%s: %04x ilc:%d [#%d] ", str, regs->int_code & 0xffff, + regs->int_code >> 17, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); #endif diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 1e1b866b2966..b7a3ccffa345 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -49,7 +49,8 @@ static inline void report_user_fault(struct pt_regs *regs, int signr) return; if (!printk_ratelimit()) return; - printk("User process fault: interruption code 0x%X ", regs->int_code); + printk("User process fault: interruption code %04x ilc:%d ", + regs->int_code & 0xffff, regs->int_code >> 17); print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); printk("\n"); show_regs(regs); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index ca70fad2fc92..811937bb90be 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -261,8 +261,8 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) return; if (!printk_ratelimit()) return; - printk(KERN_ALERT "User process fault: interruption code 0x%X ", - regs->int_code); + printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d", + regs->int_code & 0xffff, regs->int_code >> 17); print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); printk(KERN_CONT "\n"); printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", -- GitLab From e56da345eb529370f21f36a52bbb114ba38ad921 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 19 Nov 2014 14:05:52 +0100 Subject: [PATCH 5647/9457] s390/traps: die on translation exceptions Translation exceptions should never happen, since that implies that either we screwed up the page tables or missed to properly flush the TLB. In both cases we should not just simply kill user space or walk the kernel exception tables. Instead an oops or a panic (panic_on_oops) is the better answer. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/traps.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index b7a3ccffa345..f081cf1157c3 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -153,8 +153,6 @@ DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC, "privileged operation") DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN, "special operation exception") -DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, - "translation exception") #ifdef CONFIG_64BIT DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN, @@ -181,6 +179,12 @@ static inline void do_fp_trap(struct pt_regs *regs, int fpc) do_trap(regs, SIGFPE, si_code, "floating point exception"); } +void translation_exception(struct pt_regs *regs) +{ + /* May never happen. */ + die(regs, "Translation exception"); +} + void illegal_op(struct pt_regs *regs) { siginfo_t info; -- GitLab From e7f1d0b735fd4bbec225a83de2aa8f52a0a2e95c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 21 Nov 2014 10:37:14 +0100 Subject: [PATCH 5648/9457] drm/i915: Update DRIVER_DATE to 20141121 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5448ce9d1490..b6d8d2dce203 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -55,7 +55,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20141107" +#define DRIVER_DATE "20141121" #undef WARN_ON #define WARN_ON(x) WARN(x, "WARN_ON(" #x ")") -- GitLab From eaa8e5ef18fa9e09286482a4ded3a3cad36e44b2 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 21 Nov 2014 15:49:11 +0800 Subject: [PATCH 5649/9457] ALSA: hda/realtek - Supported HP mute Led for ALC286 New HP machine supported output mute led and input mute led. ALC286: GPIO1 to control output mute led. GPIO5 to control input mute led. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3c29a558e7db..3fcb7d951572 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3299,6 +3299,27 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, } } +static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static const struct hda_verb gpio_init[] = { + { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 }, + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 }, + {} + }; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; + spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; + spec->gpio_led = 0; + spec->mute_led_polarity = 0; + spec->gpio_mute_led_mask = 0x02; + spec->gpio_mic_led_mask = 0x20; + snd_hda_add_verbs(codec, gpio_init); + } +} + /* turn on/off mic-mute LED per capture hook */ static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec, struct snd_kcontrol *kcontrol, @@ -4238,6 +4259,7 @@ enum { ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, ALC282_FIXUP_ASPIRE_V5_PINS, ALC280_FIXUP_HP_GPIO4, + ALC286_FIXUP_HP_GPIO_LED, }; static const struct hda_fixup alc269_fixups[] = { @@ -4705,6 +4727,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc280_fixup_hp_gpio4, }, + [ALC286_FIXUP_HP_GPIO_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc286_fixup_hp_gpio_led, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -4745,6 +4771,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), -- GitLab From 3360b84b8ed1f08bfb39743465b858a04492fcc3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 11:47:04 +0100 Subject: [PATCH 5650/9457] ALSA: usb-audio: Allow quirks to handle own resume and proc dump So far, we blindly assumed that the all usb-audio mixer elements follow the standard and apply the standard resume method for the registered elements in the id_elems[] list. However, some quirks really need the own resume and it's incomplete for now. This patch enhances the resume handling in two folds: - split some fields in struct usb_mixer_elem_info into a smaller header struct (usb_mixer_elem_list) for keeping the minimal information in the linked-list; the usb_mixer_elem_info embeds this header struct instead - add resume and dump callbacks to usb_mixer_elem_list struct to allow quirks providing the own methods For the standard mixer elements, these new callbacks are set to the standard ones as default, thus there is no functional change by this patch yet. The dump and resume callbacks are typedef'ed for ease of later patches using arrays of such function pointers. Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 156 ++++++++++++++++++++----------------- sound/usb/mixer.h | 26 +++++-- sound/usb/mixer_quirks.c | 12 +-- sound/usb/mixer_scarlett.c | 8 +- 4 files changed, 114 insertions(+), 88 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index a4fbfff63191..41650d5b93b7 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -138,7 +138,7 @@ check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen) /* ignore the error value if ignore_ctl_error flag is set */ #define filter_error(cval, err) \ - ((cval)->mixer->ignore_ctl_error ? 0 : (err)) + ((cval)->head.mixer->ignore_ctl_error ? 0 : (err)) /* check whether the control should be ignored */ static inline int @@ -290,13 +290,13 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val) static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) { - struct snd_usb_audio *chip = cval->mixer->chip; + struct snd_usb_audio *chip = cval->head.mixer->chip; unsigned char buf[2]; int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; int timeout = 10; int idx = 0, err; - err = snd_usb_autoresume(cval->mixer->chip); + err = snd_usb_autoresume(chip); if (err < 0) return -EIO; @@ -304,7 +304,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, while (timeout-- > 0) { if (chip->shutdown) break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, idx, buf, val_len) >= val_len) { @@ -320,14 +320,14 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, out: up_read(&chip->shutdown_rwsem); - snd_usb_autosuspend(cval->mixer->chip); + snd_usb_autosuspend(chip); return err; } static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) { - struct snd_usb_audio *chip = cval->mixer->chip; + struct snd_usb_audio *chip = cval->head.mixer->chip; unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */ unsigned char *val; int idx = 0, ret, size; @@ -351,7 +351,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, if (chip->shutdown) { ret = -ENODEV; } else { - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, idx, buf, size); @@ -396,7 +396,7 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, { validx += cval->idx_off; - return (cval->mixer->protocol == UAC_VERSION_1) ? + return (cval->head.mixer->protocol == UAC_VERSION_1) ? get_ctl_value_v1(cval, request, validx, value_ret) : get_ctl_value_v2(cval, request, validx, value_ret); } @@ -427,8 +427,8 @@ int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, } err = get_cur_mix_raw(cval, channel, value); if (err < 0) { - if (!cval->mixer->ignore_ctl_error) - usb_audio_dbg(cval->mixer->chip, + if (!cval->head.mixer->ignore_ctl_error) + usb_audio_dbg(cval->head.mixer->chip, "cannot get current value for control %d ch %d: err = %d\n", cval->control, channel, err); return err; @@ -445,13 +445,13 @@ int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set) { - struct snd_usb_audio *chip = cval->mixer->chip; + struct snd_usb_audio *chip = cval->head.mixer->chip; unsigned char buf[2]; int idx = 0, val_len, err, timeout = 10; validx += cval->idx_off; - if (cval->mixer->protocol == UAC_VERSION_1) { + if (cval->head.mixer->protocol == UAC_VERSION_1) { val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; } else { /* UAC_VERSION_2 */ /* audio class v2 controls are always 2 bytes in size */ @@ -476,7 +476,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, while (timeout-- > 0) { if (chip->shutdown) break; - idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); if (snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, @@ -510,7 +510,7 @@ int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, cval->ch_readonly & (1 << (channel - 1)); if (read_only) { - usb_audio_dbg(cval->mixer->chip, + usb_audio_dbg(cval->head.mixer->chip, "%s(): channel %d of control %d is read_only\n", __func__, channel, cval->control); return 0; @@ -569,10 +569,10 @@ static int check_matrix_bitmap(unsigned char *bmap, * if failed, give up and free the control instance. */ -int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, +int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, struct snd_kcontrol *kctl) { - struct usb_mixer_elem_info *cval = kctl->private_data; + struct usb_mixer_interface *mixer = list->mixer; int err; while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) @@ -582,9 +582,9 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, err); return err; } - cval->elem_id = &kctl->id; - cval->next_id_elem = mixer->id_elems[cval->id]; - mixer->id_elems[cval->id] = cval; + list->kctl = kctl; + list->next_id_elem = mixer->id_elems[list->id]; + mixer->id_elems[list->id] = list; return 0; } @@ -833,7 +833,7 @@ void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl) static void volume_control_quirks(struct usb_mixer_elem_info *cval, struct snd_kcontrol *kctl) { - struct snd_usb_audio *chip = cval->mixer->chip; + struct snd_usb_audio *chip = cval->head.mixer->chip; switch (chip->usb_id) { case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ @@ -958,10 +958,10 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, } if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { - usb_audio_err(cval->mixer->chip, + usb_audio_err(cval->head.mixer->chip, "%d:%d: cannot get min/max values for control %d (id %d)\n", - cval->id, snd_usb_ctrl_intf(cval->mixer->chip), - cval->control, cval->id); + cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip), + cval->control, cval->head.id); return -EINVAL; } if (get_ctl_value(cval, UAC_GET_RES, @@ -1065,7 +1065,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, kcontrol->vd[0].access &= ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); - snd_ctl_notify(cval->mixer->chip->card, + snd_ctl_notify(cval->head.mixer->chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kcontrol->id); } @@ -1235,8 +1235,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return; - cval->mixer = state->mixer; - cval->id = unitid; + snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); cval->control = control; cval->cmask = ctl_mask; cval->val_type = audio_feature_info[control-1].type; @@ -1347,14 +1346,14 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, range); usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d", - cval->id, kctl->id.name, cval->channels, + cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); } usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", - cval->id, kctl->id.name, cval->channels, + cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); - snd_usb_mixer_add_control(state->mixer, kctl); + snd_usb_mixer_add_control(&cval->head, kctl); } /* @@ -1528,8 +1527,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, if (!cval) return; - cval->mixer = state->mixer; - cval->id = unitid; + snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); cval->control = in_ch + 1; /* based on 1 */ cval->val_type = USB_MIXER_S16; for (i = 0; i < num_outs; i++) { @@ -1561,8 +1559,8 @@ static void build_mixer_unit_ctl(struct mixer_build *state, append_ctl_name(kctl, " Volume"); usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n", - cval->id, kctl->id.name, cval->channels, cval->min, cval->max); - snd_usb_mixer_add_control(state->mixer, kctl); + cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max); + snd_usb_mixer_add_control(&cval->head, kctl); } /* @@ -1812,8 +1810,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return -ENOMEM; - cval->mixer = state->mixer; - cval->id = unitid; + snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); cval->control = valinfo->control; cval->val_type = valinfo->val_type; cval->channels = 1; @@ -1866,10 +1863,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, usb_audio_dbg(state->chip, "[%d] PU [%s] ch = %d, val = %d/%d\n", - cval->id, kctl->id.name, cval->channels, + cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max); - err = snd_usb_mixer_add_control(state->mixer, kctl); + err = snd_usb_mixer_add_control(&cval->head, kctl); if (err < 0) return err; } @@ -2016,8 +2013,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return -ENOMEM; - cval->mixer = state->mixer; - cval->id = unitid; + snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); cval->val_type = USB_MIXER_U8; cval->channels = 1; cval->min = 1; @@ -2088,11 +2084,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, } usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n", - cval->id, kctl->id.name, desc->bNrInPins); - if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) - return err; - - return 0; + cval->head.id, kctl->id.name, desc->bNrInPins); + return snd_usb_mixer_add_control(&cval->head, kctl); } /* @@ -2237,25 +2230,21 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) { - struct usb_mixer_elem_info *info; + struct usb_mixer_elem_list *list; - for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) + for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - info->elem_id); + &list->kctl->id); } static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, - int unitid, - struct usb_mixer_elem_info *cval) + struct usb_mixer_elem_list *list) { + struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", "S8", "U8", "S16", "U16"}; - snd_iprintf(buffer, " Unit: %i\n", unitid); - if (cval->elem_id) - snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n", - cval->elem_id->name, cval->elem_id->index); snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " - "channels=%i, type=\"%s\"\n", cval->id, + "channels=%i, type=\"%s\"\n", cval->head.id, cval->control, cval->cmask, cval->channels, val_types[cval->val_type]); snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n", @@ -2267,7 +2256,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, { struct snd_usb_audio *chip = entry->private_data; struct usb_mixer_interface *mixer; - struct usb_mixer_elem_info *cval; + struct usb_mixer_elem_list *list; int unitid; list_for_each_entry(mixer, &chip->mixer_list, list) { @@ -2277,9 +2266,17 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, mixer->ignore_ctl_error); snd_iprintf(buffer, "Card: %s\n", chip->card->longname); for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { - for (cval = mixer->id_elems[unitid]; cval; - cval = cval->next_id_elem) - snd_usb_mixer_dump_cval(buffer, unitid, cval); + for (list = mixer->id_elems[unitid]; list; + list = list->next_id_elem) { + snd_iprintf(buffer, " Unit: %i\n", list->id); + if (list->kctl) + snd_iprintf(buffer, + " Control: name=\"%s\", index=%i\n", + list->kctl->id.name, + list->kctl->id.index); + if (list->dump) + list->dump(buffer, list); + } } } } @@ -2287,7 +2284,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, int attribute, int value, int index) { - struct usb_mixer_elem_info *info; + struct usb_mixer_elem_list *list; __u8 unitid = (index >> 8) & 0xff; __u8 control = (value >> 8) & 0xff; __u8 channel = value & 0xff; @@ -2299,7 +2296,13 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, return; } - for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) { + for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { + struct usb_mixer_elem_info *info; + + if (!list->kctl) + continue; + + info = (struct usb_mixer_elem_info *)list; if (info->control != control) continue; @@ -2312,7 +2315,7 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, info->cached = 0; snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - info->elem_id); + &info->head.kctl->id); break; case UAC2_CS_RANGE: @@ -2510,8 +2513,9 @@ int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer) return 0; } -static int restore_mixer_value(struct usb_mixer_elem_info *cval) +static int restore_mixer_value(struct usb_mixer_elem_list *list) { + struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; int c, err, idx; if (cval->cmask) { @@ -2541,19 +2545,19 @@ static int restore_mixer_value(struct usb_mixer_elem_info *cval) int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) { - struct usb_mixer_elem_info *cval; + struct usb_mixer_elem_list *list; int id, err; - /* FIXME: any mixer quirks? */ - if (reset_resume) { /* restore cached mixer values */ for (id = 0; id < MAX_ID_ELEMS; id++) { - for (cval = mixer->id_elems[id]; cval; - cval = cval->next_id_elem) { - err = restore_mixer_value(cval); - if (err < 0) - return err; + for (list = mixer->id_elems[id]; list; + list = list->next_id_elem) { + if (list->resume) { + err = list->resume(list); + if (err < 0) + return err; + } } } } @@ -2561,3 +2565,15 @@ int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) return snd_usb_mixer_activate(mixer); } #endif + +void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, + struct usb_mixer_interface *mixer, + int unitid) +{ + list->mixer = mixer; + list->id = unitid; + list->dump = snd_usb_mixer_dump_cval; +#ifdef CONFIG_PM + list->resume = restore_mixer_value; +#endif +} diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 2478a844a322..0fe87b7c7f00 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -1,6 +1,8 @@ #ifndef __USBMIXER_H #define __USBMIXER_H +#include + struct usb_mixer_interface { struct snd_usb_audio *chip; struct usb_host_interface *hostif; @@ -8,7 +10,7 @@ struct usb_mixer_interface { unsigned int ignore_ctl_error; struct urb *urb; /* array[MAX_ID_ELEMS], indexed by unit id */ - struct usb_mixer_elem_info **id_elems; + struct usb_mixer_elem_list **id_elems; /* the usb audio specification version this interface complies to */ int protocol; @@ -36,11 +38,21 @@ enum { USB_MIXER_U16, }; -struct usb_mixer_elem_info { +typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, + struct usb_mixer_elem_list *list); +typedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); + +struct usb_mixer_elem_list { struct usb_mixer_interface *mixer; - struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */ - struct snd_ctl_elem_id *elem_id; + struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ + struct snd_kcontrol *kctl; unsigned int id; + usb_mixer_elem_dump_func_t dump; + usb_mixer_elem_resume_func_t resume; +}; + +struct usb_mixer_elem_info { + struct usb_mixer_elem_list head; unsigned int control; /* CS or ICN (high byte) */ unsigned int cmask; /* channel mask bitmap: 0 = master */ unsigned int idx_off; /* Control index offset */ @@ -65,9 +77,13 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set); -int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, +int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, struct snd_kcontrol *kctl); +void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, + struct usb_mixer_interface *mixer, + int unitid); + int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *_tlv); diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 8b55c0667f60..88a408cdddbd 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -69,7 +69,6 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, const char *name, snd_kcontrol_tlv_rw_t *tlv_callback) { - int err; struct usb_mixer_elem_info *cval; struct snd_kcontrol *kctl; @@ -77,8 +76,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, if (!cval) return -ENOMEM; - cval->id = unitid; - cval->mixer = mixer; + snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); cval->val_type = val_type; cval->channels = 1; cval->control = control; @@ -112,11 +110,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; } /* Add control to mixer */ - err = snd_usb_mixer_add_control(mixer, kctl); - if (err < 0) - return err; - - return 0; + return snd_usb_mixer_add_control(&cval->head, kctl); } static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, @@ -1206,7 +1200,7 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, int unitid = 12; /* SamleRate ExtensionUnit ID */ list_for_each_entry(mixer, &chip->mixer_list, list) { - cval = mixer->id_elems[unitid]; + cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid]; if (cval) { snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, cval->control << 8, diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c index a0a874507de5..92dba35660b3 100644 --- a/sound/usb/mixer_scarlett.c +++ b/sound/usb/mixer_scarlett.c @@ -436,10 +436,10 @@ static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { struct usb_mixer_elem_info *elem = kctl->private_data; - struct snd_usb_audio *chip = elem->mixer->chip; + struct snd_usb_audio *chip = elem->head.mixer->chip; unsigned char buf[2 * MAX_CHANNELS] = {0, }; int wValue = (elem->control << 8) | elem->idx_off; - int idx = snd_usb_ctrl_intf(chip) | (elem->id << 8); + int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8); int err; err = snd_usb_ctl_msg(chip->dev, @@ -528,10 +528,10 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, if (!elem) return -ENOMEM; - elem->mixer = mixer; + elem->head.mixer = mixer; elem->control = offset; elem->idx_off = num; - elem->id = index; + elem->head.id = index; elem->val_type = val_type; elem->channels = channels; -- GitLab From 9cf3689bfe0784b6f6afb301bece95d3fc3eeb64 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 12:58:51 +0100 Subject: [PATCH 5651/9457] ALSA: usb-audio: Add audigy2nx resume support Rewrite the code to handle LEDs on audigy2nx and co for supporting the proper resume. A new internal helper function add_single_ctl_with_resume() is introduced to manage the usb_mixer_elem_list more easily. Also while we're at it, move audigy2nx_leds[] in usb_mixer_interface struct into the private_value of each kctl, too. Signed-off-by: Takashi Iwai --- sound/usb/mixer.h | 1 - sound/usb/mixer_quirks.c | 148 ++++++++++++++++++++++++--------------- 2 files changed, 92 insertions(+), 57 deletions(-) diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 0fe87b7c7f00..0b3740ea6614 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -23,7 +23,6 @@ struct usb_mixer_interface { struct usb_ctrlrequest *rc_setup_packet; u8 rc_buffer[6]; - u8 audigy2nx_leds[3]; u8 xonar_u1_status; }; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 88a408cdddbd..41cacf889c98 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -144,6 +144,32 @@ static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, return 0; } +static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer, + int id, + usb_mixer_elem_resume_func_t resume, + const struct snd_kcontrol_new *knew, + struct usb_mixer_elem_list **listp) +{ + struct usb_mixer_elem_list *list; + struct snd_kcontrol *kctl; + + list = kzalloc(sizeof(*list), GFP_KERNEL); + if (!list) + return -ENOMEM; + if (listp) + *listp = list; + list->mixer = mixer; + list->id = id; + list->resume = resume; + kctl = snd_ctl_new1(knew, list); + if (!kctl) { + kfree(list); + return -ENOMEM; + } + kctl->private_free = snd_usb_mixer_elem_free; + return snd_usb_mixer_add_control(list, kctl); +} + /* * Sound Blaster remote control configuration * @@ -271,84 +297,90 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - int index = kcontrol->private_value; - - ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index]; + ucontrol->value.integer.value[0] = kcontrol->private_value >> 8; return 0; } -static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer, + int value, int index) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - int index = kcontrol->private_value; - int value = ucontrol->value.integer.value[0]; - int err, changed; + struct snd_usb_audio *chip = mixer->chip; + int err; - if (value > 1) - return -EINVAL; - changed = value != mixer->audigy2nx_leds[index]; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) { + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) { err = -ENODEV; goto out; } - if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + if (chip->usb_id == USB_ID(0x041e, 0x3042)) + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, !value, 0, NULL, 0); /* USB X-Fi S51 Pro */ - if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + if (chip->usb_id == USB_ID(0x041e, 0x30df)) + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, !value, 0, NULL, 0); else - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, value, index + 2, NULL, 0); out: - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; - mixer->audigy2nx_leds[index] = value; - return changed; + up_read(&chip->shutdown_rwsem); + return err; } -static struct snd_kcontrol_new snd_audigy2nx_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CMSS LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 0, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Power LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Dolby Digital LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 2, - }, +static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + struct usb_mixer_interface *mixer = list->mixer; + int index = kcontrol->private_value & 0xff; + int value = ucontrol->value.integer.value[0]; + int old_value = kcontrol->private_value >> 8; + int err; + + if (value > 1) + return -EINVAL; + if (value == old_value) + return 0; + kcontrol->private_value = (value << 8) | index; + err = snd_audigy2nx_led_update(mixer, value, index); + return err < 0 ? err : 1; +} + +static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list) +{ + int priv_value = list->kctl->private_value; + + return snd_audigy2nx_led_update(list->mixer, priv_value >> 8, + priv_value & 0xff); +} + +/* name and private_value are set dynamically */ +static struct snd_kcontrol_new snd_audigy2nx_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_audigy2nx_led_info, + .get = snd_audigy2nx_led_get, + .put = snd_audigy2nx_led_put, +}; + +static const char * const snd_audigy2nx_led_names[] = { + "CMSS LED Switch", + "Power LED Switch", + "Dolby Digital LED Switch", }; static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) { int i, err; - for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { + for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_led_names); ++i) { + struct snd_kcontrol_new knew; + /* USB X-Fi S51 doesn't have a CMSS LED */ if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) continue; @@ -361,12 +393,16 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) mixer->chip->usb_id == USB_ID(0x041e, 0x30df) || mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) break; - err = snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); + + knew = snd_audigy2nx_control; + knew.name = snd_audigy2nx_led_names[i]; + knew.private_value = (1 << 8) | i; /* LED on as default */ + err = add_single_ctl_with_resume(mixer, 0, + snd_audigy2nx_led_resume, + &knew, NULL); if (err < 0) return err; } - mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */ return 0; } -- GitLab From 5f503ee9e270f8251ba9024bafa8d698050066cb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 16:11:37 +0100 Subject: [PATCH 5652/9457] ALSA: usb-audio: Add Emu0204 channel switch resume support Similar as the previous fix, this adds the proper resume support to Emu0202 "Front Jack Channels" enum mixer element. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 84 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 41cacf889c98..f2b1c0d8ccd1 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -473,63 +473,71 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, return 0; } -static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer, + int value) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - unsigned int value = ucontrol->value.enumerated.item[0]; - int err, changed; + struct snd_usb_audio *chip = mixer->chip; + int err; unsigned char buf[2]; - if (value > 1) - return -EINVAL; - - buf[0] = 0x01; - buf[1] = value ? 0x02 : 0x01; - - changed = value != kcontrol->private_value; - down_read(&mixer->chip->shutdown_rwsem); + down_read(&chip->shutdown_rwsem); if (mixer->chip->shutdown) { err = -ENODEV; goto out; } - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, + + buf[0] = 0x01; + buf[1] = value ? 0x02 : 0x01; + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 0x0400, 0x0e00, buf, 2); out: - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; + up_read(&chip->shutdown_rwsem); + return err; +} + +static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + struct usb_mixer_interface *mixer = list->mixer; + unsigned int value = ucontrol->value.enumerated.item[0]; + int err; + + if (value > 1) + return -EINVAL; + + if (value == kcontrol->private_value) + return 0; + kcontrol->private_value = value; - return changed; + err = snd_emu0204_ch_switch_update(mixer, value); + return err < 0 ? err : 1; } +static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list) +{ + return snd_emu0204_ch_switch_update(list->mixer, + list->kctl->private_value); +} -static struct snd_kcontrol_new snd_emu0204_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Jack Channels", - .info = snd_emu0204_ch_switch_info, - .get = snd_emu0204_ch_switch_get, - .put = snd_emu0204_ch_switch_put, - .private_value = 0, - }, +static struct snd_kcontrol_new snd_emu0204_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Front Jack Channels", + .info = snd_emu0204_ch_switch_info, + .get = snd_emu0204_ch_switch_get, + .put = snd_emu0204_ch_switch_put, + .private_value = 0, }; static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) { - int i, err; - - for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { - err = snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_emu0204_controls[i], mixer)); - if (err < 0) - return err; - } - - return 0; + return add_single_ctl_with_resume(mixer, 0, + snd_emu0204_ch_switch_resume, + &snd_emu0204_control, NULL); } + /* ASUS Xonar U1 / U3 controls */ static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, -- GitLab From 2bfb14c3b8fbc787ff4478f9d77ecee78cb922fe Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 16:18:15 +0100 Subject: [PATCH 5653/9457] ALSA: usb-audio: Add Xonar U1 resume support This time it's about Xonar U1: add the proper resume support for "Digital Playback Switch" element. Also, the status is moved into kcontrol private_value from usb_mixer_interface struct field. One more cut. Signed-off-by: Takashi Iwai --- sound/usb/mixer.h | 2 -- sound/usb/mixer_quirks.c | 66 +++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 0b3740ea6614..d3268f0ee2b3 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -22,8 +22,6 @@ struct usb_mixer_interface { struct urb *rc_urb; struct usb_ctrlrequest *rc_setup_packet; u8 rc_buffer[6]; - - u8 xonar_u1_status; }; #define MAX_CHANNELS 16 /* max logical channels */ diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f2b1c0d8ccd1..4afcf096ebb2 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -543,38 +543,52 @@ static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02); + ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02); return 0; } +static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer, + unsigned char status) +{ + struct snd_usb_audio *chip = mixer->chip; + int err; + + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) + err = -ENODEV; + else + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + 50, 0, &status, 1); + up_read(&chip->shutdown_rwsem); + return err; +} + static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); u8 old_status, new_status; - int err, changed; + int err; - old_status = mixer->xonar_u1_status; + old_status = kcontrol->private_value; if (ucontrol->value.integer.value[0]) new_status = old_status | 0x02; else new_status = old_status & ~0x02; - changed = new_status != old_status; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, - 50, 0, &new_status, 1); - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; - mixer->xonar_u1_status = new_status; - return changed; + if (new_status == old_status) + return 0; + + kcontrol->private_value = new_status; + err = snd_xonar_u1_switch_update(list->mixer, new_status); + return err < 0 ? err : 1; +} + +static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list) +{ + return snd_xonar_u1_switch_update(list->mixer, + list->kctl->private_value); } static struct snd_kcontrol_new snd_xonar_u1_output_switch = { @@ -583,18 +597,14 @@ static struct snd_kcontrol_new snd_xonar_u1_output_switch = { .info = snd_ctl_boolean_mono_info, .get = snd_xonar_u1_switch_get, .put = snd_xonar_u1_switch_put, + .private_value = 0x05, }; static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) { - int err; - - err = snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_xonar_u1_output_switch, mixer)); - if (err < 0) - return err; - mixer->xonar_u1_status = 0x05; - return 0; + return add_single_ctl_with_resume(mixer, 0, + snd_xonar_u1_switch_resume, + &snd_xonar_u1_output_switch, NULL); } /* Digidesign Mbox 1 clock source switch (internal/spdif) */ -- GitLab From 25a9a4f91b909822fa07cbc9939c99a8c67d8960 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 16:31:35 +0100 Subject: [PATCH 5654/9457] ALSA: usb-audio: Add Digidesign Mbox 1 resume support Again another quirk fix, just convert to usb_mixer_elem_list with the resume callback for Mbox 1 stuff. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 52 ++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 4afcf096ebb2..f7ad2078c0cf 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -616,29 +616,12 @@ static int snd_mbox1_switch_get(struct snd_kcontrol *kctl, return 0; } -static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, - struct snd_ctl_elem_value *ucontrol) +static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val) { - struct snd_usb_audio *chip; - struct usb_mixer_interface *mixer; + struct snd_usb_audio *chip = mixer->chip; int err; - bool cur_val, new_val; unsigned char buff[3]; - cur_val = kctl->private_value; - new_val = ucontrol->value.enumerated.item[0]; - - mixer = snd_kcontrol_chip(kctl); - if (snd_BUG_ON(!mixer)) - return -EINVAL; - - chip = mixer->chip; - if (snd_BUG_ON(!chip)) - return -EINVAL; - - if (cur_val == new_val) - return 0; - down_read(&chip->shutdown_rwsem); if (chip->shutdown) { err = -ENODEV; @@ -668,7 +651,7 @@ static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, * while S/PDIF sync is enabled and confusing * this configuration. */ - if (new_val == 0) { + if (val == 0) { buff[0] = 0x80; buff[1] = 0xbb; buff[2] = 0x00; @@ -697,10 +680,27 @@ static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3); if (err < 0) goto err; - kctl->private_value = new_val; err: up_read(&chip->shutdown_rwsem); + return err; +} + +static int snd_mbox1_switch_put(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); + struct usb_mixer_interface *mixer = list->mixer; + int err; + bool cur_val, new_val; + + cur_val = kctl->private_value; + new_val = ucontrol->value.enumerated.item[0]; + if (cur_val == new_val) + return 0; + + kctl->private_value = new_val; + err = snd_mbox1_switch_update(mixer, new_val); return err < 0 ? err : 1; } @@ -715,6 +715,11 @@ static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol, return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } +static int snd_mbox1_switch_resume(struct usb_mixer_elem_list *list) +{ + return snd_mbox1_switch_update(list->mixer, list->kctl->private_value); +} + static struct snd_kcontrol_new snd_mbox1_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Clock Source", @@ -728,8 +733,9 @@ static struct snd_kcontrol_new snd_mbox1_switch = { static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer) { - return snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_mbox1_switch, mixer)); + return add_single_ctl_with_resume(mixer, 0, + snd_mbox1_switch_resume, + &snd_mbox1_switch, NULL); } /* Native Instruments device quirks */ -- GitLab From da6d276957ea56b9514aa5c8d885edf22f0b3e65 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 16:59:47 +0100 Subject: [PATCH 5655/9457] ALSA: usb-audio: Add resume support for Native Instruments controls The changes at this time are a bit more wider than previous ones. Firstly, the NI controls didn't cache the values, so I had to implement the caching. It's stored in bit 24 of private_value. In addition to that, the initial values have to be read from registers. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 99 +++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index f7ad2078c0cf..e11b4f3e1215 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -742,64 +742,68 @@ static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer) #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex)) -static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_ni_control_init_val(struct usb_mixer_interface *mixer, + struct snd_kcontrol *kctl) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); struct usb_device *dev = mixer->chip->dev; - u8 bRequest = (kcontrol->private_value >> 16) & 0xff; - u16 wIndex = kcontrol->private_value & 0xffff; - u8 tmp; - int ret; - - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; - else - ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, wIndex, - &tmp, sizeof(tmp)); - up_read(&mixer->chip->shutdown_rwsem); + unsigned int pval = kctl->private_value; + u8 value; + int err; - if (ret < 0) { + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), + (pval >> 16) & 0xff, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0, pval & 0xffff, &value, 1); + if (err < 0) { dev_err(&dev->dev, - "unable to issue vendor read request (ret = %d)", ret); - return ret; + "unable to issue vendor read request (ret = %d)", err); + return err; } - ucontrol->value.integer.value[0] = tmp; - + kctl->private_value |= (value << 24); return 0; } -static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, +static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - struct usb_device *dev = mixer->chip->dev; - u8 bRequest = (kcontrol->private_value >> 16) & 0xff; - u16 wIndex = kcontrol->private_value & 0xffff; - u16 wValue = ucontrol->value.integer.value[0]; - int ret; + ucontrol->value.integer.value[0] = kcontrol->private_value >> 24; + return 0; +} - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - ret = -ENODEV; +static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list) +{ + struct snd_usb_audio *chip = list->mixer->chip; + unsigned int pval = list->kctl->private_value; + int err; + + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) + err = -ENODEV; else - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - wValue, wIndex, - NULL, 0, 1000); - up_read(&mixer->chip->shutdown_rwsem); + err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), + (pval >> 16) & 0xff, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + pval >> 24, pval & 0xffff, NULL, 0, 1000); + up_read(&chip->shutdown_rwsem); + return err; +} - if (ret < 0) { - dev_err(&dev->dev, - "unable to issue vendor write request (ret = %d)", ret); - return ret; - } +static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + u8 oldval = (kcontrol->private_value >> 24) & 0xff; + u8 newval = ucontrol->value.integer.value[0]; + int err; - return 0; + if (oldval == newval) + return 0; + + kcontrol->private_value &= ~(0xff << 24); + kcontrol->private_value |= newval; + err = snd_ni_update_cur_val(list); + return err < 0 ? err : 1; } static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = { @@ -870,16 +874,17 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, }; for (i = 0; i < count; i++) { - struct snd_kcontrol *c; + struct usb_mixer_elem_list *list; template.name = kc[i].name; template.private_value = kc[i].private_value; - c = snd_ctl_new1(&template, mixer); - err = snd_ctl_add(mixer->chip->card, c); - + err = add_single_ctl_with_resume(mixer, 0, + snd_ni_update_cur_val, + &template, &list); if (err < 0) break; + snd_ni_control_init_val(mixer, list->kctl); } return err; -- GitLab From 0b4e9cfcef055a1be9bee5a47262e9cbcf17e8cd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 17:37:40 +0100 Subject: [PATCH 5656/9457] ALSA: usb-audio: Add resume support for FTU controls A few FTU mixer controls have the own value handling, so they have to be rewritten to follow the support for resume callbacks. This ended up in a fair amount of refactoring. Its own struct is now removed, instead the values are embedded in kctl private_value totally. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 194 +++++++++++---------------------------- 1 file changed, 54 insertions(+), 140 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e11b4f3e1215..fcb7ae5131a9 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -892,14 +892,6 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, /* M-Audio FastTrack Ultra quirks */ /* FTU Effect switch (also used by C400/C600) */ -struct snd_ftu_eff_switch_priv_val { - struct usb_mixer_interface *mixer; - int cached_value; - int is_cached; - int bUnitID; - int validx; -}; - static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -911,138 +903,77 @@ static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); } -static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, - struct snd_ctl_elem_value *ucontrol) +static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer, + struct snd_kcontrol *kctl) { - struct snd_usb_audio *chip; - struct usb_mixer_interface *mixer; - struct snd_ftu_eff_switch_priv_val *pval; + struct usb_device *dev = mixer->chip->dev; + unsigned int pval = kctl->private_value; int err; unsigned char value[2]; - int id, validx; - - const int val_len = 2; value[0] = 0x00; value[1] = 0x00; - pval = (struct snd_ftu_eff_switch_priv_val *) - kctl->private_value; + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + pval & 0xff00, + snd_usb_ctrl_intf(mixer->chip) | ((pval & 0xff) << 8), + value, 2); + if (err < 0) + return err; - if (pval->is_cached) { - ucontrol->value.enumerated.item[0] = pval->cached_value; - return 0; - } + kctl->private_value |= value[0] << 24; + return 0; +} - mixer = (struct usb_mixer_interface *) pval->mixer; - if (snd_BUG_ON(!mixer)) - return -EINVAL; +static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = kctl->private_value >> 24; + return 0; +} - chip = (struct snd_usb_audio *) mixer->chip; - if (snd_BUG_ON(!chip)) - return -EINVAL; +static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list) +{ + struct snd_usb_audio *chip = list->mixer->chip; + unsigned int pval = list->kctl->private_value; + unsigned char value[2]; + int err; - id = pval->bUnitID; - validx = pval->validx; + value[0] = pval >> 24; + value[1] = 0; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) err = -ENODEV; else err = snd_usb_ctl_msg(chip->dev, - usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), - value, val_len); - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; - - ucontrol->value.enumerated.item[0] = value[0]; - pval->cached_value = value[0]; - pval->is_cached = 1; - - return 0; + usb_sndctrlpipe(chip->dev, 0), + UAC_SET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + pval & 0xff00, + snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8), + value, 2); + up_read(&chip->shutdown_rwsem); + return err; } static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { - struct snd_usb_audio *chip; - struct snd_ftu_eff_switch_priv_val *pval; - - struct usb_mixer_interface *mixer; - int changed, cur_val, err, new_val; - unsigned char value[2]; - int id, validx; - - const int val_len = 2; - - changed = 0; + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); + unsigned int pval = list->kctl->private_value; + int cur_val, err, new_val; - pval = (struct snd_ftu_eff_switch_priv_val *) - kctl->private_value; - cur_val = pval->cached_value; + cur_val = pval >> 24; new_val = ucontrol->value.enumerated.item[0]; + if (cur_val == new_val) + return 0; - mixer = (struct usb_mixer_interface *) pval->mixer; - if (snd_BUG_ON(!mixer)) - return -EINVAL; - - chip = (struct snd_usb_audio *) mixer->chip; - if (snd_BUG_ON(!chip)) - return -EINVAL; - - id = pval->bUnitID; - validx = pval->validx; - - if (!pval->is_cached) { - /* Read current value */ - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, - usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), - value, val_len); - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; - - cur_val = value[0]; - pval->cached_value = cur_val; - pval->is_cached = 1; - } - /* update value if needed */ - if (cur_val != new_val) { - value[0] = new_val; - value[1] = 0; - down_read(&mixer->chip->shutdown_rwsem); - if (mixer->chip->shutdown) - err = -ENODEV; - else - err = snd_usb_ctl_msg(chip->dev, - usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), - value, val_len); - up_read(&mixer->chip->shutdown_rwsem); - if (err < 0) - return err; - - pval->cached_value = new_val; - pval->is_cached = 1; - changed = 1; - } - - return changed; -} - -static void kctl_private_value_free(struct snd_kcontrol *kctl) -{ - kfree((void *)kctl->private_value); + kctl->private_value &= ~(0xff << 24); + kctl->private_value |= new_val << 24; + err = snd_ftu_eff_switch_update(list); + return err < 0 ? err : 1; } static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, @@ -1057,33 +988,16 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, .get = snd_ftu_eff_switch_get, .put = snd_ftu_eff_switch_put }; - + struct usb_mixer_elem_list *list; int err; - struct snd_kcontrol *kctl; - struct snd_ftu_eff_switch_priv_val *pval; - - pval = kzalloc(sizeof(*pval), GFP_KERNEL); - if (!pval) - return -ENOMEM; - - pval->cached_value = 0; - pval->is_cached = 0; - pval->mixer = mixer; - pval->bUnitID = bUnitID; - pval->validx = validx; - template.private_value = (unsigned long) pval; - kctl = snd_ctl_new1(&template, mixer->chip); - if (!kctl) { - kfree(pval); - return -ENOMEM; - } - - kctl->private_free = kctl_private_value_free; - err = snd_ctl_add(mixer->chip->card, kctl); + err = add_single_ctl_with_resume(mixer, bUnitID, + snd_ftu_eff_switch_update, + &template, &list); if (err < 0) return err; - + list->kctl->private_value = (validx << 8) | bUnitID; + snd_ftu_eff_switch_init(mixer, list->kctl); return 0; } -- GitLab From 288673beae6cbd8198be94284adbaeb5cba7dbda Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2014 18:06:17 +0100 Subject: [PATCH 5657/9457] ALSA: usb-audio: Add resume support for MicroII SPDIF ctls Like the previous fixes, the mixer accessors are converted to use usb_mixer_elem_list objects. In addition, the proper shutdown check are put in get and put callbacks. Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 135 +++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 42 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index fcb7ae5131a9..dc9df007d3e3 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1509,7 +1509,8 @@ static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol, static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + struct snd_usb_audio *chip = list->mixer->chip; int err; struct usb_interface *iface; struct usb_host_interface *alts; @@ -1517,17 +1518,23 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, unsigned char data[3]; int rate; + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) { + err = -ENODEV; + goto end; + } + ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff; ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff; ucontrol->value.iec958.status[2] = 0x00; /* use known values for that card: interface#1 altsetting#1 */ - iface = usb_ifnum_to_if(mixer->chip->dev, 1); + iface = usb_ifnum_to_if(chip->dev, 1); alts = &iface->altsetting[1]; ep = get_endpoint(alts, 0)->bEndpointAddress; - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_rcvctrlpipe(mixer->chip->dev, 0), + err = snd_usb_ctl_msg(chip->dev, + usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, UAC_EP_CS_ATTR_SAMPLE_RATE << 8, @@ -1542,22 +1549,27 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol, IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100; err = 0; -end: + end: + up_read(&chip->shutdown_rwsem); return err; } -static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - int err; + struct snd_usb_audio *chip = list->mixer->chip; + unsigned int pval = list->kctl->private_value; u8 reg; - unsigned long priv_backup = kcontrol->private_value; + int err; + + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) { + err = -ENODEV; + goto end; + } - reg = ((ucontrol->value.iec958.status[1] & 0x0f) << 4) | - (ucontrol->value.iec958.status[0] & 0x0f); - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), + reg = ((pval >> 4) & 0xf0) | (pval & 0x0f); + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, reg, @@ -1567,15 +1579,10 @@ static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, if (err < 0) goto end; - kcontrol->private_value &= 0xfffff0f0; - kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0x0f) << 8; - kcontrol->private_value |= (ucontrol->value.iec958.status[0] & 0x0f); - - reg = (ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO) ? - 0xa0 : 0x20; - reg |= (ucontrol->value.iec958.status[1] >> 4) & 0x0f; - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), + reg = (pval & IEC958_AES0_NONAUDIO) ? 0xa0 : 0x20; + reg |= (pval >> 12) & 0x0f; + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, reg, @@ -1585,16 +1592,36 @@ static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, if (err < 0) goto end; - kcontrol->private_value &= 0xffff0fff; - kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0xf0) << 8; + end: + up_read(&chip->shutdown_rwsem); + return err; +} + +static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + unsigned int pval, pval_old; + int err; + + pval = pval_old = kcontrol->private_value; + pval &= 0xfffff0f0; + pval |= (ucontrol->value.iec958.status[1] & 0x0f) << 8; + pval |= (ucontrol->value.iec958.status[0] & 0x0f); + + pval &= 0xffff0fff; + pval |= (ucontrol->value.iec958.status[1] & 0xf0) << 8; /* The frequency bits in AES3 cannot be set via register access. */ /* Silently ignore any bits from the request that cannot be set. */ - err = (priv_backup != kcontrol->private_value); -end: - return err; + if (pval == pval_old) + return 0; + + kcontrol->private_value = pval; + err = snd_microii_spdif_default_update(list); + return err < 0 ? err : 1; } static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol, @@ -1616,15 +1643,20 @@ static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol, return 0; } -static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list) { - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); + struct snd_usb_audio *chip = list->mixer->chip; + u8 reg = list->kctl->private_value; int err; - u8 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a; - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), + down_read(&chip->shutdown_rwsem); + if (chip->shutdown) { + err = -ENODEV; + goto end; + } + + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, reg, @@ -1632,15 +1664,27 @@ static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, NULL, 0); - if (!err) { - err = (reg != (kcontrol->private_value & 0x0ff)); - if (err) - kcontrol->private_value = reg; - } - + end: + up_read(&chip->shutdown_rwsem); return err; } +static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); + u8 reg; + int err; + + reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a; + if (reg != list->kctl->private_value) + return 0; + + kcontrol->private_value = reg; + err = snd_microii_spdif_switch_update(list); + return err < 0 ? err : 1; +} + static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { { .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1670,10 +1714,17 @@ static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { static int snd_microii_controls_create(struct usb_mixer_interface *mixer) { int err, i; + static usb_mixer_elem_resume_func_t resume_funcs[] = { + snd_microii_spdif_default_update, + NULL, + snd_microii_spdif_switch_update + }; for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) { - err = snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_microii_mixer_spdif[i], mixer)); + err = add_single_ctl_with_resume(mixer, 0, + resume_funcs[i], + &snd_microii_mixer_spdif[i], + NULL); if (err < 0) return err; } -- GitLab From b61f90eac1ff9d1b30497e611aba4651d4066706 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 20 Nov 2014 17:20:46 +0100 Subject: [PATCH 5658/9457] ALSA: usb-audio: Add resume support for Scarlett mixers Scarlett driver uses almost compatible usb_mixer_elem_info struct, so we just need to add a couple of simple resume callbacks to handle them accordingly. Signed-off-by: Takashi Iwai --- sound/usb/mixer_scarlett.c | 65 ++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c index 92dba35660b3..9109652b88b9 100644 --- a/sound/usb/mixer_scarlett.c +++ b/sound/usb/mixer_scarlett.c @@ -285,6 +285,19 @@ static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl, return changed; } +static int scarlett_ctl_resume(struct usb_mixer_elem_list *list) +{ + struct usb_mixer_elem_info *elem = + container_of(list, struct usb_mixer_elem_info, head); + int i; + + for (i = 0; i < elem->channels; i++) + if (elem->cached & (1 << i)) + snd_usb_set_cur_mix_value(elem, i, i, + elem->cache_val[i]); + return 0; +} + static int scarlett_ctl_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { @@ -432,6 +445,16 @@ static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl, return 0; } +static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list) +{ + struct usb_mixer_elem_info *elem = + container_of(list, struct usb_mixer_elem_info, head); + + if (elem->cached) + snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val); + return 0; +} + static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { @@ -514,6 +537,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_sync = { static int add_new_ctl(struct usb_mixer_interface *mixer, const struct snd_kcontrol_new *ncontrol, + usb_mixer_elem_resume_func_t resume, int index, int offset, int num, int val_type, int channels, const char *name, const struct scarlett_mixer_elem_enum_info *opt, @@ -529,6 +553,7 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, return -ENOMEM; elem->head.mixer = mixer; + elem->head.resume = resume; elem->control = offset; elem->idx_off = num; elem->head.id = index; @@ -548,7 +573,7 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); - err = snd_ctl_add(mixer->chip->card, kctl); + err = snd_usb_mixer_add_control(&elem->head, kctl); if (err < 0) return err; @@ -569,7 +594,8 @@ static int add_output_ctls(struct usb_mixer_interface *mixer, /* Add mute switch */ snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch", index + 1, name); - err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, 0x0a, 0x01, + err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, + scarlett_ctl_resume, 0x0a, 0x01, 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem); if (err < 0) return err; @@ -577,7 +603,8 @@ static int add_output_ctls(struct usb_mixer_interface *mixer, /* Add volume control and initialize to 0 */ snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume", index + 1, name); - err = add_new_ctl(mixer, &usb_scarlett_ctl_master, 0x0a, 0x02, + err = add_new_ctl(mixer, &usb_scarlett_ctl_master, + scarlett_ctl_resume, 0x0a, 0x02, 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem); if (err < 0) return err; @@ -585,7 +612,8 @@ static int add_output_ctls(struct usb_mixer_interface *mixer, /* Add L channel source playback enumeration */ snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum", index + 1, name); - err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, 0x33, 0x00, + err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, + scarlett_ctl_enum_resume, 0x33, 0x00, 2*index, USB_MIXER_S16, 1, mx, &info->opt_master, &elem); if (err < 0) @@ -594,7 +622,8 @@ static int add_output_ctls(struct usb_mixer_interface *mixer, /* Add R channel source playback enumeration */ snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum", index + 1, name); - err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, 0x33, 0x00, + err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, + scarlett_ctl_enum_resume, 0x33, 0x00, 2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master, &elem); if (err < 0) @@ -824,13 +853,15 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *elem; /* create master switch and playback volume */ - err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, 0x0a, 0x01, 0, + err = add_new_ctl(mixer, &usb_scarlett_ctl_switch, + scarlett_ctl_resume, 0x0a, 0x01, 0, USB_MIXER_S16, 1, "Master Playback Switch", NULL, &elem); if (err < 0) return err; - err = add_new_ctl(mixer, &usb_scarlett_ctl_master, 0x0a, 0x02, 0, + err = add_new_ctl(mixer, &usb_scarlett_ctl_master, + scarlett_ctl_resume, 0x0a, 0x02, 0, USB_MIXER_S16, 1, "Master Playback Volume", NULL, &elem); if (err < 0) @@ -848,7 +879,8 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer, break; case SCARLETT_SWITCH_IMPEDANCE: sprintf(mx, "Input %d Impedance Switch", ctl->num); - err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 0x01, + err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, + scarlett_ctl_enum_resume, 0x01, 0x09, ctl->num, USB_MIXER_S16, 1, mx, &opt_impedance, &elem); if (err < 0) @@ -856,7 +888,8 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer, break; case SCARLETT_SWITCH_PAD: sprintf(mx, "Input %d Pad Switch", ctl->num); - err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 0x01, + err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, + scarlett_ctl_enum_resume, 0x01, 0x0b, ctl->num, USB_MIXER_S16, 1, mx, &opt_pad, &elem); if (err < 0) @@ -912,7 +945,8 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) for (i = 0; i < info->matrix_in; i++) { snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route", i+1); - err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, 0x32, + err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, + scarlett_ctl_enum_resume, 0x32, 0x06, i, USB_MIXER_S16, 1, mx, &info->opt_matrix, &elem); if (err < 0) @@ -921,7 +955,8 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) for (o = 0; o < info->matrix_out; o++) { sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1, o+'A'); - err = add_new_ctl(mixer, &usb_scarlett_ctl, 0x3c, 0x00, + err = add_new_ctl(mixer, &usb_scarlett_ctl, + scarlett_ctl_resume, 0x3c, 0x00, (i << 3) + (o & 0x07), USB_MIXER_S16, 1, mx, NULL, &elem); if (err < 0) @@ -933,7 +968,8 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) for (i = 0; i < info->input_len; i++) { snprintf(mx, sizeof(mx), "Input Source %02d Capture Route", i+1); - err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, 0x34, + err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum, + scarlett_ctl_enum_resume, 0x34, 0x00, i, USB_MIXER_S16, 1, mx, &info->opt_master, &elem); if (err < 0) @@ -941,14 +977,15 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer) } /* val_len == 1 needed here */ - err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 0x28, 0x01, 0, + err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, + scarlett_ctl_enum_resume, 0x28, 0x01, 0, USB_MIXER_U8, 1, "Sample Clock Source", &opt_clock, &elem); if (err < 0) return err; /* val_len == 1 and UAC2_CS_MEM */ - err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, 0x3c, 0x00, 2, + err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2, USB_MIXER_U8, 1, "Sample Clock Sync Status", &opt_sync, &elem); if (err < 0) -- GitLab From b0ad5e8b4905d2398702e1dde033bce9c2c0fcad Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Fri, 21 Nov 2014 15:08:02 +0200 Subject: [PATCH 5659/9457] mac80211_hwsim: Send alpha2 only if non-zero A properly set alpha2 value consists of two chars that both contain letters or digits. If no value is set, both chars keep their initial value zero. Therefore do not send the alpha2 parameter to user space if either of the characters has been left at its initial zero value. Signed-off-by: Patrik Flykt Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e23a8d14578a..d399a7367ce9 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2541,7 +2541,9 @@ static int mac80211_hwsim_get_radio(struct sk_buff *skb, if (cb) genl_dump_check_consistent(cb, hdr, &hwsim_genl_family); - param.reg_alpha2 = data->alpha2; + if (data->alpha2[0] && data->alpha2[1]) + param.reg_alpha2 = data->alpha2; + param.reg_strict = !!(data->hw->wiphy->regulatory_flags & REGULATORY_STRICT_REG); param.p2p_device = !!(data->hw->wiphy->interface_modes & -- GitLab From f6a8eaca0ea10fc5c5ae0d6b0067759164e633a0 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 17 Nov 2014 15:28:07 -0500 Subject: [PATCH 5660/9457] drm/msm/mdp5: use irqdomains For mdp5, the irqs of hdmi/eDP/dsi0/dsi1 blocks get routed through the mdp block. In order to decouple hdmi/eDP/etc, register an irq domain in mdp5. When hdmi/dsi/etc are used with mdp4, they can directly setup their irqs in their DT nodes as normal. When used with mdp5, instead set the mdp device as the interrupt-parent, as in: mdp: qcom,mdss_mdp@fd900000 { compatible = "qcom,mdss_mdp"; interrupt-controller; #interrupt-cells = <1>; ... }; hdmi: qcom,hdmi_tx@fd922100 { compatible = "qcom,hdmi-tx-8074"; interrupt-parent = <&mdp>; interrupts = <8 0>; /* MDP5_HW_INTR_STATUS.INTR_HDMI */ ... }; There is a slight awkwardness, in that we cannot disable child irqs at the mdp level, they can only be cleared in the child block. So you must not use threaded irq handlers in the child. I'm not sure if there is a better way to deal with that. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi.c | 33 ++++----- drivers/gpu/drm/msm/hdmi/hdmi.h | 3 - drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 94 +++++++++++++++++++++++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 10 +++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 7 ++ drivers/gpu/drm/msm/msm_drv.h | 1 - 6 files changed, 122 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 90077619029d..db8c3b45bc24 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -15,6 +15,7 @@ * this program. If not, see . */ +#include #include "hdmi.h" void hdmi_set_mode(struct hdmi *hdmi, bool power_on) @@ -39,7 +40,7 @@ void hdmi_set_mode(struct hdmi *hdmi, bool power_on) power_on ? "Enable" : "Disable", ctrl); } -irqreturn_t hdmi_irq(int irq, void *dev_id) +static irqreturn_t hdmi_irq(int irq, void *dev_id) { struct hdmi *hdmi = dev_id; @@ -200,7 +201,6 @@ int hdmi_modeset_init(struct hdmi *hdmi, { struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = hdmi->pdev; - struct hdmi_platform_config *config = pdev->dev.platform_data; int ret; hdmi->dev = dev; @@ -224,22 +224,20 @@ int hdmi_modeset_init(struct hdmi *hdmi, goto fail; } - if (!config->shared_irq) { - hdmi->irq = platform_get_irq(pdev, 0); - if (hdmi->irq < 0) { - ret = hdmi->irq; - dev_err(dev->dev, "failed to get irq: %d\n", ret); - goto fail; - } + hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + if (hdmi->irq < 0) { + ret = hdmi->irq; + dev_err(dev->dev, "failed to get irq: %d\n", ret); + goto fail; + } - ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, - NULL, hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "hdmi_isr", hdmi); - if (ret < 0) { - dev_err(dev->dev, "failed to request IRQ%u: %d\n", - hdmi->irq, ret); - goto fail; - } + ret = devm_request_irq(&pdev->dev, hdmi->irq, + hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "hdmi_isr", hdmi); + if (ret < 0) { + dev_err(dev->dev, "failed to request IRQ%u: %d\n", + hdmi->irq, ret); + goto fail; } encoder->bridge = hdmi->bridge; @@ -318,7 +316,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); config.pwr_clk_names = pwr_clk_names; config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); - config.shared_irq = true; } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) { static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index b981995410b5..0a6f538f012c 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -97,9 +97,6 @@ struct hdmi_platform_config { /* gpio's: */ int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, mux_en_gpio, mux_sel_gpio; int mux_lpm_gpio; - - /* older devices had their own irq, mdp5+ it is shared w/ mdp: */ - bool shared_irq; }; void hdmi_set_mode(struct hdmi *hdmi, bool power_on); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 812c59bbaf7f..70ac81edd40f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -15,6 +15,8 @@ * this program. If not, see . */ +#include +#include #include "msm_drv.h" #include "mdp5_kms.h" @@ -82,18 +84,23 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) { struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); - struct msm_drm_private *priv = mdp5_kms->dev->dev_private; uint32_t intr; intr = mdp5_read(mdp5_kms, REG_MDP5_HW_INTR_STATUS); VERB("intr=%08x", intr); - if (intr & MDP5_HW_INTR_STATUS_INTR_MDP) + if (intr & MDP5_HW_INTR_STATUS_INTR_MDP) { mdp5_irq_mdp(mdp_kms); + intr &= ~MDP5_HW_INTR_STATUS_INTR_MDP; + } - if (intr & MDP5_HW_INTR_STATUS_INTR_HDMI) - hdmi_irq(0, priv->hdmi); + while (intr) { + irq_hw_number_t hwirq = fls(intr) - 1; + generic_handle_irq(irq_find_mapping( + mdp5_kms->irqcontroller.domain, hwirq)); + intr &= ~(1 << hwirq); + } return IRQ_HANDLED; } @@ -110,3 +117,82 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), false); } + +/* + * interrupt-controller implementation, so sub-blocks (hdmi/eDP/dsi/etc) + * can register to get their irq's delivered + */ + +#define VALID_IRQS (MDP5_HW_INTR_STATUS_INTR_DSI0 | \ + MDP5_HW_INTR_STATUS_INTR_DSI1 | \ + MDP5_HW_INTR_STATUS_INTR_HDMI | \ + MDP5_HW_INTR_STATUS_INTR_EDP) + +static void mdp5_hw_mask_irq(struct irq_data *irqd) +{ + struct mdp5_kms *mdp5_kms = irq_data_get_irq_chip_data(irqd); + smp_mb__before_atomic(); + clear_bit(irqd->hwirq, &mdp5_kms->irqcontroller.enabled_mask); + smp_mb__after_atomic(); +} + +static void mdp5_hw_unmask_irq(struct irq_data *irqd) +{ + struct mdp5_kms *mdp5_kms = irq_data_get_irq_chip_data(irqd); + smp_mb__before_atomic(); + set_bit(irqd->hwirq, &mdp5_kms->irqcontroller.enabled_mask); + smp_mb__after_atomic(); +} + +static struct irq_chip mdp5_hw_irq_chip = { + .name = "mdp5", + .irq_mask = mdp5_hw_mask_irq, + .irq_unmask = mdp5_hw_unmask_irq, +}; + +static int mdp5_hw_irqdomain_map(struct irq_domain *d, + unsigned int irq, irq_hw_number_t hwirq) +{ + struct mdp5_kms *mdp5_kms = d->host_data; + + if (!(VALID_IRQS & (1 << hwirq))) + return -EPERM; + + irq_set_chip_and_handler(irq, &mdp5_hw_irq_chip, handle_level_irq); + irq_set_chip_data(irq, mdp5_kms); + set_irq_flags(irq, IRQF_VALID); + + return 0; +} + +static struct irq_domain_ops mdp5_hw_irqdomain_ops = { + .map = mdp5_hw_irqdomain_map, + .xlate = irq_domain_xlate_onecell, +}; + + +int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms) +{ + struct device *dev = mdp5_kms->dev->dev; + struct irq_domain *d; + + d = irq_domain_add_linear(dev->of_node, 32, + &mdp5_hw_irqdomain_ops, mdp5_kms); + if (!d) { + dev_err(dev, "mdp5 irq domain add failed\n"); + return -ENXIO; + } + + mdp5_kms->irqcontroller.enabled_mask = 0; + mdp5_kms->irqcontroller.domain = d; + + return 0; +} + +void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms) +{ + if (mdp5_kms->irqcontroller.domain) { + irq_domain_remove(mdp5_kms->irqcontroller.domain); + mdp5_kms->irqcontroller.domain = NULL; + } +} diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index ce0308124a72..6c414db6ff02 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -221,10 +221,13 @@ static void mdp5_destroy(struct msm_kms *kms) struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct msm_mmu *mmu = mdp5_kms->mmu; + mdp5_irq_domain_fini(mdp5_kms); + if (mmu) { mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); mmu->funcs->destroy(mmu); } + kfree(mdp5_kms); } @@ -279,6 +282,13 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) struct drm_encoder *encoder; int i, ret; + /* register our interrupt-controller for hdmi/eDP/dsi/etc + * to use for irqs routed through mdp: + */ + ret = mdp5_irq_domain_init(mdp5_kms); + if (ret) + goto fail; + /* construct CRTCs: */ for (i = 0; i < mdp5_kms->hw_cfg->pipe_rgb.count; i++) { struct drm_plane *plane; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index c91101d5ac0f..0e9e3f7f4e9d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -72,6 +72,11 @@ struct mdp5_kms { struct clk *vsync_clk; struct mdp_irq error_handler; + + struct { + volatile unsigned long enabled_mask; + struct irq_domain *domain; + } irqcontroller; }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) @@ -195,6 +200,8 @@ void mdp5_irq_uninstall(struct msm_kms *kms); irqreturn_t mdp5_irq(struct msm_kms *kms); int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); +int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms); +void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms); static inline uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 4b52d752bb6e..136303818436 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -215,7 +215,6 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); struct hdmi; int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, struct drm_encoder *encoder); -irqreturn_t hdmi_irq(int irq, void *dev_id); void __init hdmi_register(void); void __exit hdmi_unregister(void); -- GitLab From 3f307963fc07953b56b51b18ed47416bf340320f Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Mon, 17 Nov 2014 13:39:34 -0500 Subject: [PATCH 5661/9457] drm/msm/mdp5: get the core clock rate from MDP5 config The core clock rate depends on the hw configuration. Once we have read the hardware revision, we can set the core clock to its maximum value. Before then, the clock is set at a rate supported by all MDP5 revisions. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 9 +++++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 6c414db6ff02..1cb91bef2bc1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -62,6 +62,7 @@ static const struct mdp5_config msm8x74_config = { .count = 4, .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, }, + .max_clk = 200000000, }; static const struct mdp5_config apq8084_config = { @@ -99,6 +100,7 @@ static const struct mdp5_config apq8084_config = { .count = 5, .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, }, + .max_clk = 320000000, }; struct mdp5_config_entry { @@ -427,12 +429,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) if (ret) goto fail; - ret = clk_set_rate(mdp5_kms->src_clk, config->max_clk); - ret = mdp5_select_hw_cfg(kms); if (ret) goto fail; + /* TODO: compute core clock rate at runtime */ + clk_set_rate(mdp5_kms->src_clk, mdp5_kms->hw_cfg->max_clk); + /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if * we don't disable): @@ -493,8 +496,6 @@ static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev) /* TODO */ #endif config.iommu = iommu_domain_alloc(&platform_bus_type); - /* TODO hard-coded in downstream mdss, but should it be? */ - config.max_clk = 200000000; /* TODO get from DT: */ config.smp_blk_cnt = 22; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 0e9e3f7f4e9d..70aa8d4dbba0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -37,6 +37,8 @@ struct mdp5_config { struct mdp5_sub_block dspp; struct mdp5_sub_block ad; struct mdp5_sub_block intf; + + uint32_t max_clk; }; extern const struct mdp5_config *mdp5_cfg; #include "mdp5.xml.h" @@ -83,7 +85,6 @@ struct mdp5_kms { /* platform config data (ie. from DT, or pdata) */ struct mdp5_platform_config { struct iommu_domain *iommu; - uint32_t max_clk; int smp_blk_cnt; }; -- GitLab From d1a717bd2719d6416fdc5e9b65786f17c6c3facb Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 18 Nov 2014 08:40:44 -0500 Subject: [PATCH 5662/9457] drm/msm/hdmi: remove useless kref A left-over from prior to component framework. The original intent was to deal with hdmi getting unloaded before the master component, but that isn't really going to work anyways. These days with the component framework taking care to unload the master component first, we don't have to worry about this. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi.c | 24 +++++++++++------------ drivers/gpu/drm/msm/hdmi/hdmi.h | 14 ------------- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 3 +-- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 4 +--- 4 files changed, 13 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index db8c3b45bc24..062c68725376 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -55,9 +55,8 @@ static irqreturn_t hdmi_irq(int irq, void *dev_id) return IRQ_HANDLED; } -void hdmi_destroy(struct kref *kref) +static void hdmi_destroy(struct hdmi *hdmi) { - struct hdmi *hdmi = container_of(kref, struct hdmi, refcount); struct hdmi_phy *phy = hdmi->phy; if (phy) @@ -85,8 +84,6 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) goto fail; } - kref_init(&hdmi->refcount); - hdmi->pdev = pdev; hdmi->config = config; @@ -183,7 +180,7 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) fail: if (hdmi) - hdmi_destroy(&hdmi->refcount); + hdmi_destroy(hdmi); return ERR_PTR(ret); } @@ -269,12 +266,6 @@ int hdmi_modeset_init(struct hdmi *hdmi, #include -static void set_hdmi(struct drm_device *dev, struct hdmi *hdmi) -{ - struct msm_drm_private *priv = dev->dev_private; - priv->hdmi = hdmi; -} - #ifdef CONFIG_OF static int get_gpio(struct device *dev, struct device_node *of_node, const char *name) { @@ -295,6 +286,8 @@ static int get_gpio(struct device *dev, struct device_node *of_node, const char static int hdmi_bind(struct device *dev, struct device *master, void *data) { + struct drm_device *drm = dev_get_drvdata(master); + struct msm_drm_private *priv = drm->dev_private; static struct hdmi_platform_config config = {}; struct hdmi *hdmi; #ifdef CONFIG_OF @@ -389,14 +382,19 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) hdmi = hdmi_init(to_platform_device(dev)); if (IS_ERR(hdmi)) return PTR_ERR(hdmi); - set_hdmi(dev_get_drvdata(master), hdmi); + priv->hdmi = hdmi; return 0; } static void hdmi_unbind(struct device *dev, struct device *master, void *data) { - set_hdmi(dev_get_drvdata(master), NULL); + struct drm_device *drm = dev_get_drvdata(master); + struct msm_drm_private *priv = drm->dev_private; + if (priv->hdmi) { + hdmi_destroy(priv->hdmi); + priv->hdmi = NULL; + } } static const struct component_ops hdmi_ops = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 0a6f538f012c..43e654f751b7 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -38,8 +38,6 @@ struct hdmi_audio { }; struct hdmi { - struct kref refcount; - struct drm_device *dev; struct platform_device *pdev; @@ -100,7 +98,6 @@ struct hdmi_platform_config { }; void hdmi_set_mode(struct hdmi *hdmi, bool power_on); -void hdmi_destroy(struct kref *kref); static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data) { @@ -112,17 +109,6 @@ static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) return msm_readl(hdmi->mmio + reg); } -static inline struct hdmi * hdmi_reference(struct hdmi *hdmi) -{ - kref_get(&hdmi->refcount); - return hdmi; -} - -static inline void hdmi_unreference(struct hdmi *hdmi) -{ - kref_put(&hdmi->refcount, hdmi_destroy); -} - /* * The phy appears to be different, for example between 8960 and 8x60, * so split the phy related functions out and load the correct one at diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index f6cf745c249e..6902ad6da710 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -26,7 +26,6 @@ struct hdmi_bridge { static void hdmi_bridge_destroy(struct drm_bridge *bridge) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); - hdmi_unreference(hdmi_bridge->hdmi); drm_bridge_cleanup(bridge); kfree(hdmi_bridge); } @@ -218,7 +217,7 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) goto fail; } - hdmi_bridge->hdmi = hdmi_reference(hdmi); + hdmi_bridge->hdmi = hdmi; bridge = &hdmi_bridge->base; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index 0aecb2580072..fbebb0405d76 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -330,8 +330,6 @@ static void hdmi_connector_destroy(struct drm_connector *connector) drm_connector_unregister(connector); drm_connector_cleanup(connector); - hdmi_unreference(hdmi_connector->hdmi); - kfree(hdmi_connector); } @@ -425,7 +423,7 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) goto fail; } - hdmi_connector->hdmi = hdmi_reference(hdmi); + hdmi_connector->hdmi = hdmi; INIT_WORK(&hdmi_connector->hpd_work, hotplug_work); connector = &hdmi_connector->base; -- GitLab From bfcdfb0e62639732339c85371a8c07e915bf0941 Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Tue, 18 Nov 2014 12:49:47 -0500 Subject: [PATCH 5663/9457] drm/msm/mdp5: make SMP module dynamically configurable The Shared Memory Pool (SMP) has its own limitation, features and state. Some examples are: - the number of Memory Macro Block (MMB) and their size - the number of lines that can be fetched - the state of MMB currently allocated - the computation of number of blocks required per plane - client IDs ... In order to avoid private data to be overwritten by other modules, let's make these private to the SMP module. Some of these depend on the hardware configuration, let's add them to the mdp5_config struct. In some hw configurations, some MMBs are statically tied to RGB pipes and cannot be re-allocated dynamically. This change introduces the concept of MMB static usage and makes sure that dynamic MMB requests are dimensioned accordingly. A note on passing a pipe pointer, instead of client IDs: Client IDs are SMP-related information. Passing PIPE information to SMP lets SMP module to find out which SMP client(s) are used. This allows the SMP module to access the PIPE pointer, which can be used for FIFO watermark configuration. By the way, even though REG_MDP5_PIPE_REQPRIO_FIFO_WM_* registers are part of the PIPE registers, their functionality is to reflect the behavior of the SMP block. These registers access is now restricted to the SMP module. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 28 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 34 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 92 ++------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | 242 ++++++++++++++++++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h | 22 +- 5 files changed, 265 insertions(+), 153 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 1cb91bef2bc1..f852fa456d93 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -30,6 +30,10 @@ const struct mdp5_config *mdp5_cfg; static const struct mdp5_config msm8x74_config = { .name = "msm8x74", + .smp = { + .mmb_count = 22, + .mmb_size = 4096, + }, .ctl = { .count = 5, .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, @@ -67,6 +71,15 @@ static const struct mdp5_config msm8x74_config = { static const struct mdp5_config apq8084_config = { .name = "apq8084", + .smp = { + .mmb_count = 44, + .mmb_size = 8192, + .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */ + .reserved[CID_RGB0] = 2, + .reserved[CID_RGB1] = 2, + .reserved[CID_RGB2] = 2, + .reserved[CID_RGB3] = 2, + }, .ctl = { .count = 5, .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, @@ -222,6 +235,7 @@ static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct msm_mmu *mmu = mdp5_kms->mmu; + void *smp = mdp5_kms->smp_priv; mdp5_irq_domain_fini(mdp5_kms); @@ -230,6 +244,9 @@ static void mdp5_destroy(struct msm_kms *kms) mmu->funcs->destroy(mmu); } + if (smp) + mdp5_smp_destroy(smp); + kfree(mdp5_kms); } @@ -370,6 +387,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) struct mdp5_kms *mdp5_kms; struct msm_kms *kms = NULL; struct msm_mmu *mmu; + void *priv; int i, ret; mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL); @@ -384,7 +402,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) kms = &mdp5_kms->base.base; mdp5_kms->dev = dev; - mdp5_kms->smp_blk_cnt = config->smp_blk_cnt; mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5"); if (IS_ERR(mdp5_kms->mmio)) { @@ -436,6 +453,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) /* TODO: compute core clock rate at runtime */ clk_set_rate(mdp5_kms->src_clk, mdp5_kms->hw_cfg->max_clk); + priv = mdp5_smp_init(mdp5_kms->dev, &mdp5_kms->hw_cfg->smp); + if (IS_ERR(priv)) { + ret = PTR_ERR(priv); + goto fail; + } + mdp5_kms->smp_priv = priv; + /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if * we don't disable): @@ -496,8 +520,6 @@ static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev) /* TODO */ #endif config.iommu = iommu_domain_alloc(&platform_bus_type); - /* TODO get from DT: */ - config.smp_blk_cnt = 22; return &config; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 70aa8d4dbba0..3f7aa49dd944 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -23,12 +23,22 @@ #include "mdp/mdp_kms.h" /* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */ #define MDP5_MAX_BASES 8 +#define MAX_SMP_BLOCKS 44 +#define MAX_CLIENTS 32 +typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS); struct mdp5_sub_block { int count; uint32_t base[MDP5_MAX_BASES]; }; +struct mdp5_smp_block { + int mmb_count; /* number of SMP MMBs */ + int mmb_size; /* MMB: size in bytes */ + mdp5_smp_state_t reserved_state;/* SMP MMBs statically allocated */ + int reserved[MAX_CLIENTS]; /* # of MMBs reserved per client */ +}; struct mdp5_config { char *name; + struct mdp5_smp_block smp; struct mdp5_sub_block ctl; struct mdp5_sub_block pipe_vig; struct mdp5_sub_block pipe_rgb; @@ -56,10 +66,7 @@ struct mdp5_kms { int id; struct msm_mmu *mmu; - /* for tracking smp allocation amongst pipes: */ - mdp5_smp_state_t smp_state; - struct mdp5_client_smp_state smp_client_state[CID_MAX]; - int smp_blk_cnt; + void *smp_priv; /* io/register spaces: */ void __iomem *mmio, *vbif; @@ -85,7 +92,6 @@ struct mdp5_kms { /* platform config data (ie. from DT, or pdata) */ struct mdp5_platform_config { struct iommu_domain *iommu; - int smp_blk_cnt; }; static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) @@ -141,24 +147,6 @@ static inline int pipe2nclients(enum mdp5_pipe pipe) } } -static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane) -{ - WARN_ON(plane >= pipe2nclients(pipe)); - switch (pipe) { - case SSPP_VIG0: return CID_VIG0_Y + plane; - case SSPP_VIG1: return CID_VIG1_Y + plane; - case SSPP_VIG2: return CID_VIG2_Y + plane; - case SSPP_RGB0: return CID_RGB0; - case SSPP_RGB1: return CID_RGB1; - case SSPP_RGB2: return CID_RGB2; - case SSPP_DMA0: return CID_DMA0_Y + plane; - case SSPP_DMA1: return CID_DMA1_Y + plane; - case SSPP_VIG3: return CID_VIG3_Y + plane; - case SSPP_RGB3: return CID_RGB3; - default: return CID_UNUSED; - } -} - static inline uint32_t mixer2flush(int lm) { switch (lm) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index f3daec4412ad..633ca08bb014 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -63,13 +63,13 @@ static int mdp5_plane_disable(struct drm_plane *plane) struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); enum mdp5_pipe pipe = mdp5_plane->pipe; - int i; DBG("%s: disable", mdp5_plane->name); - /* update our SMP request to zero (release all our blks): */ - for (i = 0; i < pipe2nclients(pipe); i++) - mdp5_smp_request(mdp5_kms, pipe2client(pipe, i), 0); + if (mdp5_kms) { + /* Release the memory we requested earlier from the SMP: */ + mdp5_smp_release(mdp5_kms->smp_priv, pipe); + } /* TODO detaching now will cause us not to get the last * vblank and mdp5_smp_commit().. so other planes will @@ -149,68 +149,6 @@ void mdp5_plane_set_scanout(struct drm_plane *plane, plane->fb = fb; } -/* NOTE: looks like if horizontal decimation is used (if we supported that) - * then the width used to calculate SMP block requirements is the post- - * decimated width. Ie. SMP buffering sits downstream of decimation (which - * presumably happens during the dma from scanout buffer). - */ -static int request_smp_blocks(struct drm_plane *plane, uint32_t format, - uint32_t nplanes, uint32_t width) -{ - struct drm_device *dev = plane->dev; - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - struct mdp5_kms *mdp5_kms = get_kms(plane); - enum mdp5_pipe pipe = mdp5_plane->pipe; - int i, hsub, nlines, nblks, ret; - - hsub = drm_format_horz_chroma_subsampling(format); - - /* different if BWC (compressed framebuffer?) enabled: */ - nlines = 2; - - for (i = 0, nblks = 0; i < nplanes; i++) { - int n, fetch_stride, cpp; - - cpp = drm_format_plane_cpp(format, i); - fetch_stride = width * cpp / (i ? hsub : 1); - - n = DIV_ROUND_UP(fetch_stride * nlines, SMP_BLK_SIZE); - - /* for hw rev v1.00 */ - if (mdp5_kms->rev == 0) - n = roundup_pow_of_two(n); - - DBG("%s[%d]: request %d SMP blocks", mdp5_plane->name, i, n); - ret = mdp5_smp_request(mdp5_kms, pipe2client(pipe, i), n); - if (ret) { - dev_err(dev->dev, "Could not allocate %d SMP blocks: %d\n", - n, ret); - return ret; - } - - nblks += n; - } - - /* in success case, return total # of blocks allocated: */ - return nblks; -} - -static void set_fifo_thresholds(struct drm_plane *plane, int nblks) -{ - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - struct mdp5_kms *mdp5_kms = get_kms(plane); - enum mdp5_pipe pipe = mdp5_plane->pipe; - uint32_t val; - - /* 1/4 of SMP pool that is being fetched */ - val = (nblks * SMP_ENTRIES_PER_BLK) / 4; - - mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe), val * 1); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe), val * 2); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe), val * 3); - -} - int mdp5_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, @@ -225,7 +163,7 @@ int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t nplanes, config = 0; uint32_t phasex_step = 0, phasey_step = 0; uint32_t hdecm = 0, vdecm = 0; - int i, nblks; + int ret; nplanes = drm_format_num_planes(fb->pixel_format); @@ -243,12 +181,11 @@ int mdp5_plane_mode_set(struct drm_plane *plane, fb->base.id, src_x, src_y, src_w, src_h, crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); - /* - * Calculate and request required # of smp blocks: - */ - nblks = request_smp_blocks(plane, fb->pixel_format, nplanes, src_w); - if (nblks < 0) - return nblks; + /* Request some memory from the SMP: */ + ret = mdp5_smp_request(mdp5_kms->smp_priv, + mdp5_plane->pipe, fb->pixel_format, src_w); + if (ret) + return ret; /* * Currently we update the hw for allocations/requests immediately, @@ -256,8 +193,7 @@ int mdp5_plane_mode_set(struct drm_plane *plane, * would move into atomic->check_plane_state(), while updating the * hw would remain here: */ - for (i = 0; i < pipe2nclients(pipe); i++) - mdp5_smp_configure(mdp5_kms, pipe2client(pipe, i)); + mdp5_smp_configure(mdp5_kms->smp_priv, pipe); if (src_w != crtc_w) { config |= MDP5_PIPE_SCALE_CONFIG_SCALEX_EN; @@ -330,8 +266,6 @@ int mdp5_plane_mode_set(struct drm_plane *plane, MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) | MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST)); - set_fifo_thresholds(plane, nblks); - /* TODO detach from old crtc (if we had more than one) */ mdp5_crtc_attach(crtc, plane); @@ -342,10 +276,8 @@ void mdp5_plane_complete_flip(struct drm_plane *plane) { struct mdp5_kms *mdp5_kms = get_kms(plane); enum mdp5_pipe pipe = to_mdp5_plane(plane)->pipe; - int i; - for (i = 0; i < pipe2nclients(pipe); i++) - mdp5_smp_commit(mdp5_kms, pipe2client(pipe, i)); + mdp5_smp_commit(mdp5_kms->smp_priv, pipe); } enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c index 2d0236b963a6..e61e1cfed853 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -29,8 +30,11 @@ * Based on the size of the attached scanout buffer, a certain # of * blocks must be allocated to that client out of the shared pool. * - * For each block, it can be either free, or pending/in-use by a - * client. The updates happen in three steps: + * In some hw, some blocks are statically allocated for certain pipes + * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0). + * + * For each block that can be dynamically allocated, it can be either + * free, or pending/in-use by a client. The updates happen in three steps: * * 1) mdp5_smp_request(): * When plane scanout is setup, calculate required number of @@ -61,21 +65,64 @@ * inuse and pending state of all clients.. */ -static DEFINE_SPINLOCK(smp_lock); +struct mdp5_smp { + struct drm_device *dev; + + int blk_cnt; + int blk_size; + + spinlock_t state_lock; + mdp5_smp_state_t state; /* to track smp allocation amongst pipes: */ + + struct mdp5_client_smp_state client_state[CID_MAX]; +}; +static inline +struct mdp5_kms *get_kms(struct mdp5_smp *smp) +{ + struct msm_drm_private *priv = smp->dev->dev_private; + + return to_mdp5_kms(to_mdp_kms(priv->kms)); +} + +static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane) +{ + WARN_ON(plane >= pipe2nclients(pipe)); + switch (pipe) { + case SSPP_VIG0: return CID_VIG0_Y + plane; + case SSPP_VIG1: return CID_VIG1_Y + plane; + case SSPP_VIG2: return CID_VIG2_Y + plane; + case SSPP_RGB0: return CID_RGB0; + case SSPP_RGB1: return CID_RGB1; + case SSPP_RGB2: return CID_RGB2; + case SSPP_DMA0: return CID_DMA0_Y + plane; + case SSPP_DMA1: return CID_DMA1_Y + plane; + case SSPP_VIG3: return CID_VIG3_Y + plane; + case SSPP_RGB3: return CID_RGB3; + default: return CID_UNUSED; + } +} /* step #1: update # of blocks pending for the client: */ -int mdp5_smp_request(struct mdp5_kms *mdp5_kms, +static int smp_request_block(struct mdp5_smp *smp, enum mdp5_client_id cid, int nblks) { - struct mdp5_client_smp_state *ps = &mdp5_kms->smp_client_state[cid]; - int i, ret, avail, cur_nblks, cnt = mdp5_kms->smp_blk_cnt; + struct mdp5_kms *mdp5_kms = get_kms(smp); + struct mdp5_client_smp_state *ps = &smp->client_state[cid]; + int i, ret, avail, cur_nblks, cnt = smp->blk_cnt; + int reserved = mdp5_kms->hw_cfg->smp.reserved[cid]; unsigned long flags; - spin_lock_irqsave(&smp_lock, flags); + spin_lock_irqsave(&smp->state_lock, flags); + + nblks -= reserved; + if (reserved) + DBG("%d MMBs allocated (%d reserved)", nblks, reserved); - avail = cnt - bitmap_weight(mdp5_kms->smp_state, cnt); + avail = cnt - bitmap_weight(smp->state, cnt); if (nblks > avail) { + dev_err(mdp5_kms->dev->dev, "out of blks (req=%d > avail=%d)\n", + nblks, avail); ret = -ENOSPC; goto fail; } @@ -84,9 +131,9 @@ int mdp5_smp_request(struct mdp5_kms *mdp5_kms, if (nblks > cur_nblks) { /* grow the existing pending reservation: */ for (i = cur_nblks; i < nblks; i++) { - int blk = find_first_zero_bit(mdp5_kms->smp_state, cnt); + int blk = find_first_zero_bit(smp->state, cnt); set_bit(blk, ps->pending); - set_bit(blk, mdp5_kms->smp_state); + set_bit(blk, smp->state); } } else { /* shrink the existing pending reservation: */ @@ -98,15 +145,89 @@ int mdp5_smp_request(struct mdp5_kms *mdp5_kms, } fail: - spin_unlock_irqrestore(&smp_lock, flags); + spin_unlock_irqrestore(&smp->state_lock, flags); + return 0; +} + +static void set_fifo_thresholds(struct mdp5_smp *smp, + enum mdp5_pipe pipe, int nblks) +{ + struct mdp5_kms *mdp5_kms = get_kms(smp); + u32 smp_entries_per_blk = smp->blk_size / (128 / BITS_PER_BYTE); + u32 val; + + /* 1/4 of SMP pool that is being fetched */ + val = (nblks * smp_entries_per_blk) / 4; + + mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe), val * 1); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe), val * 2); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe), val * 3); +} + +/* + * NOTE: looks like if horizontal decimation is used (if we supported that) + * then the width used to calculate SMP block requirements is the post- + * decimated width. Ie. SMP buffering sits downstream of decimation (which + * presumably happens during the dma from scanout buffer). + */ +int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width) +{ + struct mdp5_smp *smp = handler; + struct mdp5_kms *mdp5_kms = get_kms(smp); + struct drm_device *dev = mdp5_kms->dev; + int i, hsub, nplanes, nlines, nblks, ret; + + nplanes = drm_format_num_planes(fmt); + hsub = drm_format_horz_chroma_subsampling(fmt); + + /* different if BWC (compressed framebuffer?) enabled: */ + nlines = 2; + + for (i = 0, nblks = 0; i < nplanes; i++) { + int n, fetch_stride, cpp; + + cpp = drm_format_plane_cpp(fmt, i); + fetch_stride = width * cpp / (i ? hsub : 1); + + n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size); + + /* for hw rev v1.00 */ + if (mdp5_kms->rev == 0) + n = roundup_pow_of_two(n); + + DBG("%s[%d]: request %d SMP blocks", pipe2name(pipe), i, n); + ret = smp_request_block(smp, pipe2client(pipe, i), n); + if (ret) { + dev_err(dev->dev, "Cannot allocate %d SMP blocks: %d\n", + n, ret); + return ret; + } + + nblks += n; + } + + set_fifo_thresholds(smp, pipe, nblks); + return 0; } -static void update_smp_state(struct mdp5_kms *mdp5_kms, +/* Release SMP blocks for all clients of the pipe */ +void mdp5_smp_release(void *handler, enum mdp5_pipe pipe) +{ + struct mdp5_smp *smp = handler; + int i, nblks; + + for (i = 0, nblks = 0; i < pipe2nclients(pipe); i++) + smp_request_block(smp, pipe2client(pipe, i), 0); + set_fifo_thresholds(smp, pipe, 0); +} + +static void update_smp_state(struct mdp5_smp *smp, enum mdp5_client_id cid, mdp5_smp_state_t *assigned) { - int cnt = mdp5_kms->smp_blk_cnt; - uint32_t blk, val; + struct mdp5_kms *mdp5_kms = get_kms(smp); + int cnt = smp->blk_cnt; + u32 blk, val; for_each_set_bit(blk, *assigned, cnt) { int idx = blk / 3; @@ -135,39 +256,84 @@ static void update_smp_state(struct mdp5_kms *mdp5_kms, } /* step #2: configure hw for union(pending, inuse): */ -void mdp5_smp_configure(struct mdp5_kms *mdp5_kms, enum mdp5_client_id cid) +void mdp5_smp_configure(void *handler, enum mdp5_pipe pipe) { - struct mdp5_client_smp_state *ps = &mdp5_kms->smp_client_state[cid]; - int cnt = mdp5_kms->smp_blk_cnt; + struct mdp5_smp *smp = handler; + int cnt = smp->blk_cnt; mdp5_smp_state_t assigned; + int i; + + for (i = 0; i < pipe2nclients(pipe); i++) { + enum mdp5_client_id cid = pipe2client(pipe, i); + struct mdp5_client_smp_state *ps = &smp->client_state[cid]; - bitmap_or(assigned, ps->inuse, ps->pending, cnt); - update_smp_state(mdp5_kms, cid, &assigned); + bitmap_or(assigned, ps->inuse, ps->pending, cnt); + update_smp_state(smp, cid, &assigned); + } } /* step #3: after vblank, copy pending -> inuse: */ -void mdp5_smp_commit(struct mdp5_kms *mdp5_kms, enum mdp5_client_id cid) +void mdp5_smp_commit(void *handler, enum mdp5_pipe pipe) { - struct mdp5_client_smp_state *ps = &mdp5_kms->smp_client_state[cid]; - int cnt = mdp5_kms->smp_blk_cnt; + struct mdp5_smp *smp = handler; + int cnt = smp->blk_cnt; mdp5_smp_state_t released; + int i; + + for (i = 0; i < pipe2nclients(pipe); i++) { + enum mdp5_client_id cid = pipe2client(pipe, i); + struct mdp5_client_smp_state *ps = &smp->client_state[cid]; + + /* + * Figure out if there are any blocks we where previously + * using, which can be released and made available to other + * clients: + */ + if (bitmap_andnot(released, ps->inuse, ps->pending, cnt)) { + unsigned long flags; + + spin_lock_irqsave(&smp->state_lock, flags); + /* clear released blocks: */ + bitmap_andnot(smp->state, smp->state, released, cnt); + spin_unlock_irqrestore(&smp->state_lock, flags); + + update_smp_state(smp, CID_UNUSED, &released); + } - /* - * Figure out if there are any blocks we where previously - * using, which can be released and made available to other - * clients: - */ - if (bitmap_andnot(released, ps->inuse, ps->pending, cnt)) { - unsigned long flags; - - spin_lock_irqsave(&smp_lock, flags); - /* clear released blocks: */ - bitmap_andnot(mdp5_kms->smp_state, mdp5_kms->smp_state, - released, cnt); - spin_unlock_irqrestore(&smp_lock, flags); - - update_smp_state(mdp5_kms, CID_UNUSED, &released); + bitmap_copy(ps->inuse, ps->pending, cnt); } +} + +void mdp5_smp_destroy(void *handler) +{ + struct mdp5_smp *smp = handler; + + kfree(smp); +} + +void *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg) +{ + struct mdp5_smp *smp = NULL; + int ret; + + smp = kzalloc(sizeof(*smp), GFP_KERNEL); + if (unlikely(!smp)) { + ret = -ENOMEM; + goto fail; + } + + smp->dev = dev; + smp->blk_cnt = cfg->mmb_count; + smp->blk_size = cfg->mmb_size; + + /* statically tied MMBs cannot be re-allocated: */ + bitmap_copy(smp->state, cfg->reserved_state, smp->blk_cnt); + spin_lock_init(&smp->state_lock); + + return smp; +fail: + if (smp) + mdp5_smp_destroy(smp); - bitmap_copy(ps->inuse, ps->pending, cnt); + return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h index 0ab739e1a1dd..3e3c7534ec0f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -20,12 +21,6 @@ #include "msm_drv.h" -#define MAX_SMP_BLOCKS 22 -#define SMP_BLK_SIZE 4096 -#define SMP_ENTRIES_PER_BLK (SMP_BLK_SIZE / 16) - -typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS); - struct mdp5_client_smp_state { mdp5_smp_state_t inuse; mdp5_smp_state_t pending; @@ -33,9 +28,18 @@ struct mdp5_client_smp_state { struct mdp5_kms; -int mdp5_smp_request(struct mdp5_kms *mdp5_kms, enum mdp5_client_id cid, int nblks); -void mdp5_smp_configure(struct mdp5_kms *mdp5_kms, enum mdp5_client_id cid); -void mdp5_smp_commit(struct mdp5_kms *mdp5_kms, enum mdp5_client_id cid); +/* + * SMP module prototypes: + * mdp5_smp_init() returns a SMP @handler, + * which is then used to call the other mdp5_smp_*(handler, ...) functions. + */ + +void *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg); +void mdp5_smp_destroy(void *handler); +int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width); +void mdp5_smp_configure(void *handler, enum mdp5_pipe pipe); +void mdp5_smp_commit(void *handler, enum mdp5_pipe pipe); +void mdp5_smp_release(void *handler, enum mdp5_pipe pipe); #endif /* __MDP5_SMP_H__ */ -- GitLab From 2e362e1772b8978428f087007fc4d6c4990efd41 Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Tue, 18 Nov 2014 12:49:48 -0500 Subject: [PATCH 5664/9457] drm/msm/mdp5: introduce mdp5_cfg module The hardware configuration modification from a version to another is quite consequent. Introducing a configuration module (mdp5_cfg) may make things more clear and easier to access when a new hardware version comes up. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 215 ++++++++++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 88 ++++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 211 +++++------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 39 +---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | 9 +- 6 files changed, 354 insertions(+), 209 deletions(-) create mode 100644 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c create mode 100644 drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 0d96132df059..dda38529dd56 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -25,6 +25,7 @@ msm-y := \ mdp/mdp4/mdp4_irq.o \ mdp/mdp4/mdp4_kms.o \ mdp/mdp4/mdp4_plane.o \ + mdp/mdp5/mdp5_cfg.o \ mdp/mdp5/mdp5_crtc.o \ mdp/mdp5/mdp5_encoder.o \ mdp/mdp5/mdp5_irq.o \ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c new file mode 100644 index 000000000000..62e77d1d3c59 --- /dev/null +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mdp5_kms.h" +#include "mdp5_cfg.h" + +struct mdp5_cfg_handler { + int revision; + struct mdp5_cfg config; +}; + +/* mdp5_cfg must be exposed (used in mdp5.xml.h) */ +const struct mdp5_cfg_hw *mdp5_cfg = NULL; + +const struct mdp5_cfg_hw msm8x74_config = { + .name = "msm8x74", + .smp = { + .mmb_count = 22, + .mmb_size = 4096, + }, + .ctl = { + .count = 5, + .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, + }, + .pipe_vig = { + .count = 3, + .base = { 0x01200, 0x01600, 0x01a00 }, + }, + .pipe_rgb = { + .count = 3, + .base = { 0x01e00, 0x02200, 0x02600 }, + }, + .pipe_dma = { + .count = 2, + .base = { 0x02a00, 0x02e00 }, + }, + .lm = { + .count = 5, + .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 }, + .nb_stages = 5, + }, + .dspp = { + .count = 3, + .base = { 0x04600, 0x04a00, 0x04e00 }, + }, + .ad = { + .count = 2, + .base = { 0x13100, 0x13300 }, /* NOTE: no ad in v1.0 */ + }, + .intf = { + .count = 4, + .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, + }, + .max_clk = 200000000, +}; + +const struct mdp5_cfg_hw apq8084_config = { + .name = "apq8084", + .smp = { + .mmb_count = 44, + .mmb_size = 8192, + .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */ + .reserved[CID_RGB0] = 2, + .reserved[CID_RGB1] = 2, + .reserved[CID_RGB2] = 2, + .reserved[CID_RGB3] = 2, + }, + .ctl = { + .count = 5, + .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, + }, + .pipe_vig = { + .count = 4, + .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 }, + }, + .pipe_rgb = { + .count = 4, + .base = { 0x02200, 0x02600, 0x02a00, 0x02e00 }, + }, + .pipe_dma = { + .count = 2, + .base = { 0x03200, 0x03600 }, + }, + .lm = { + .count = 6, + .base = { 0x03a00, 0x03e00, 0x04200, 0x04600, 0x04a00, 0x04e00 }, + .nb_stages = 5, + }, + .dspp = { + .count = 4, + .base = { 0x05200, 0x05600, 0x05a00, 0x05e00 }, + + }, + .ad = { + .count = 3, + .base = { 0x13500, 0x13700, 0x13900 }, + }, + .intf = { + .count = 5, + .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, + }, + .max_clk = 320000000, +}; + +static const struct mdp5_cfg_handler cfg_handlers[] = { + { .revision = 0, .config = { .hw = &msm8x74_config } }, + { .revision = 2, .config = { .hw = &msm8x74_config } }, + { .revision = 3, .config = { .hw = &apq8084_config } }, +}; + + +static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev); + +const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(void *cfg_hnd) +{ + struct mdp5_cfg_handler *cfg_handler = cfg_hnd; + + return cfg_handler->config.hw; +} + +struct mdp5_cfg *mdp5_cfg_get_config(void *cfg_hnd) +{ + struct mdp5_cfg_handler *cfg_handler = cfg_hnd; + + return &cfg_handler->config; +} + +int mdp5_cfg_get_hw_rev(void *cfg_hnd) +{ + struct mdp5_cfg_handler *cfg_handler = cfg_hnd; + + return cfg_handler->revision; +} + +void mdp5_cfg_destroy(void *cfg_hnd) +{ + struct mdp5_cfg_handler *cfg_handler = cfg_hnd; + + kfree(cfg_handler); +} + +void *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, + uint32_t major, uint32_t minor) +{ + struct drm_device *dev = mdp5_kms->dev; + struct platform_device *pdev = dev->platformdev; + struct mdp5_cfg_handler *cfg_handler; + struct mdp5_cfg_platform *pconfig; + int i, ret = 0; + + cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL); + if (unlikely(!cfg_handler)) { + ret = -ENOMEM; + goto fail; + } + + if (major != 1) { + dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n", + major, minor); + ret = -ENXIO; + goto fail; + } + + /* only after mdp5_cfg global pointer's init can we access the hw */ + for (i = 0; i < ARRAY_SIZE(cfg_handlers); i++) { + if (cfg_handlers[i].revision != minor) + continue; + mdp5_cfg = cfg_handlers[i].config.hw; + + break; + } + if (unlikely(!mdp5_cfg)) { + dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n", + major, minor); + ret = -ENXIO; + goto fail; + } + + cfg_handler->revision = minor; + cfg_handler->config.hw = mdp5_cfg; + + pconfig = mdp5_get_config(pdev); + memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig)); + + DBG("MDP5: %s hw config selected", mdp5_cfg->name); + + return cfg_handler; + +fail: + if (cfg_handler) + mdp5_cfg_destroy(cfg_handler); + + return NULL; +} + +static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev) +{ + static struct mdp5_cfg_platform config = {}; +#ifdef CONFIG_OF + /* TODO */ +#endif + config.iommu = iommu_domain_alloc(&platform_bus_type); + + return &config; +} diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h new file mode 100644 index 000000000000..00c8271ad928 --- /dev/null +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MDP5_CFG_H__ +#define __MDP5_CFG_H__ + +#include "msm_drv.h" + +/* + * mdp5_cfg + * + * This module configures the dynamic offsets used by mdp5.xml.h + * (initialized in mdp5_cfg.c) + */ +extern const struct mdp5_cfg_hw *mdp5_cfg; + +#define MAX_BASES 8 +#define MAX_SMP_BLOCKS 44 +#define MAX_CLIENTS 32 + +typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS); + +#define MDP5_SUB_BLOCK_DEFINITION \ + int count; \ + uint32_t base[MAX_BASES] + +struct mdp5_sub_block { + MDP5_SUB_BLOCK_DEFINITION; +}; + +struct mdp5_lm_block { + MDP5_SUB_BLOCK_DEFINITION; + uint32_t nb_stages; /* number of stages per blender */ +}; + +struct mdp5_smp_block { + int mmb_count; /* number of SMP MMBs */ + int mmb_size; /* MMB: size in bytes */ + mdp5_smp_state_t reserved_state;/* SMP MMBs statically allocated */ + int reserved[MAX_CLIENTS]; /* # of MMBs allocated per client */ +}; + +struct mdp5_cfg_hw { + char *name; + + struct mdp5_smp_block smp; + struct mdp5_sub_block ctl; + struct mdp5_sub_block pipe_vig; + struct mdp5_sub_block pipe_rgb; + struct mdp5_sub_block pipe_dma; + struct mdp5_lm_block lm; + struct mdp5_sub_block dspp; + struct mdp5_sub_block ad; + struct mdp5_sub_block intf; + + uint32_t max_clk; +}; + +/* platform config data (ie. from DT, or pdata) */ +struct mdp5_cfg_platform { + struct iommu_domain *iommu; +}; + +struct mdp5_cfg { + const struct mdp5_cfg_hw *hw; + struct mdp5_cfg_platform platform; +}; + +struct mdp5_kms; + +const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(void *cfg_hnd); +struct mdp5_cfg *mdp5_cfg_get_config(void *cfg_hnd); +int mdp5_cfg_get_hw_rev(void *cfg_hnd); + +void *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, uint32_t major, uint32_t minor); +void mdp5_cfg_destroy(void *cfg_hnd); + +#endif /* __MDP5_CFG_H__ */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index f852fa456d93..64de0f9310c3 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -24,158 +25,10 @@ static const char *iommu_ports[] = { "mdp_0", }; -static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); - -const struct mdp5_config *mdp5_cfg; - -static const struct mdp5_config msm8x74_config = { - .name = "msm8x74", - .smp = { - .mmb_count = 22, - .mmb_size = 4096, - }, - .ctl = { - .count = 5, - .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, - }, - .pipe_vig = { - .count = 3, - .base = { 0x01200, 0x01600, 0x01a00 }, - }, - .pipe_rgb = { - .count = 3, - .base = { 0x01e00, 0x02200, 0x02600 }, - }, - .pipe_dma = { - .count = 2, - .base = { 0x02a00, 0x02e00 }, - }, - .lm = { - .count = 5, - .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 }, - }, - .dspp = { - .count = 3, - .base = { 0x04600, 0x04a00, 0x04e00 }, - }, - .ad = { - .count = 2, - .base = { 0x13100, 0x13300 }, /* NOTE: no ad in v1.0 */ - }, - .intf = { - .count = 4, - .base = { 0x12500, 0x12700, 0x12900, 0x12b00 }, - }, - .max_clk = 200000000, -}; - -static const struct mdp5_config apq8084_config = { - .name = "apq8084", - .smp = { - .mmb_count = 44, - .mmb_size = 8192, - .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */ - .reserved[CID_RGB0] = 2, - .reserved[CID_RGB1] = 2, - .reserved[CID_RGB2] = 2, - .reserved[CID_RGB3] = 2, - }, - .ctl = { - .count = 5, - .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 }, - }, - .pipe_vig = { - .count = 4, - .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 }, - }, - .pipe_rgb = { - .count = 4, - .base = { 0x02200, 0x02600, 0x02a00, 0x02e00 }, - }, - .pipe_dma = { - .count = 2, - .base = { 0x03200, 0x03600 }, - }, - .lm = { - .count = 6, - .base = { 0x03a00, 0x03e00, 0x04200, 0x04600, 0x04a00, 0x04e00 }, - }, - .dspp = { - .count = 4, - .base = { 0x05200, 0x05600, 0x05a00, 0x05e00 }, - - }, - .ad = { - .count = 3, - .base = { 0x13500, 0x13700, 0x13900 }, - }, - .intf = { - .count = 5, - .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 }, - }, - .max_clk = 320000000, -}; - -struct mdp5_config_entry { - int revision; - const struct mdp5_config *config; -}; - -static const struct mdp5_config_entry mdp5_configs[] = { - { .revision = 0, .config = &msm8x74_config }, - { .revision = 2, .config = &msm8x74_config }, - { .revision = 3, .config = &apq8084_config }, -}; - -static int mdp5_select_hw_cfg(struct msm_kms *kms) -{ - struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - struct drm_device *dev = mdp5_kms->dev; - uint32_t version, major, minor; - int i, ret = 0; - - mdp5_enable(mdp5_kms); - version = mdp5_read(mdp5_kms, REG_MDP5_MDP_VERSION); - mdp5_disable(mdp5_kms); - - major = FIELD(version, MDP5_MDP_VERSION_MAJOR); - minor = FIELD(version, MDP5_MDP_VERSION_MINOR); - - DBG("found MDP5 version v%d.%d", major, minor); - - if (major != 1) { - dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n", - major, minor); - ret = -ENXIO; - goto out; - } - - mdp5_kms->rev = minor; - - /* only after mdp5_cfg global pointer's init can we access the hw */ - for (i = 0; i < ARRAY_SIZE(mdp5_configs); i++) { - if (mdp5_configs[i].revision != minor) - continue; - mdp5_kms->hw_cfg = mdp5_cfg = mdp5_configs[i].config; - break; - } - if (unlikely(!mdp5_kms->hw_cfg)) { - dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n", - major, minor); - ret = -ENXIO; - goto out; - } - - DBG("MDP5: %s config selected", mdp5_kms->hw_cfg->name); - - return 0; -out: - return ret; -} - static int mdp5_hw_init(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + const struct mdp5_cfg_hw *hw_cfg; struct drm_device *dev = mdp5_kms->dev; int i; @@ -207,7 +60,9 @@ static int mdp5_hw_init(struct msm_kms *kms) mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0); - for (i = 0; i < mdp5_kms->hw_cfg->ctl.count; i++) + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + + for (i = 0; i < hw_cfg->ctl.count; i++) mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(i), 0); pm_runtime_put_sync(dev->dev); @@ -236,6 +91,7 @@ static void mdp5_destroy(struct msm_kms *kms) struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct msm_mmu *mmu = mdp5_kms->mmu; void *smp = mdp5_kms->smp_priv; + void *cfg = mdp5_kms->cfg_priv; mdp5_irq_domain_fini(mdp5_kms); @@ -246,6 +102,8 @@ static void mdp5_destroy(struct msm_kms *kms) if (smp) mdp5_smp_destroy(smp); + if (cfg) + mdp5_cfg_destroy(cfg); kfree(mdp5_kms); } @@ -299,8 +157,11 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) struct drm_device *dev = mdp5_kms->dev; struct msm_drm_private *priv = dev->dev_private; struct drm_encoder *encoder; + const struct mdp5_cfg_hw *hw_cfg; int i, ret; + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + /* register our interrupt-controller for hdmi/eDP/dsi/etc * to use for irqs routed through mdp: */ @@ -309,7 +170,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) goto fail; /* construct CRTCs: */ - for (i = 0; i < mdp5_kms->hw_cfg->pipe_rgb.count; i++) { + for (i = 0; i < hw_cfg->pipe_rgb.count; i++) { struct drm_plane *plane; struct drm_crtc *crtc; @@ -367,6 +228,21 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) return ret; } +static void read_hw_revision(struct mdp5_kms *mdp5_kms, + uint32_t *major, uint32_t *minor) +{ + uint32_t version; + + mdp5_enable(mdp5_kms); + version = mdp5_read(mdp5_kms, REG_MDP5_MDP_VERSION); + mdp5_disable(mdp5_kms); + + *major = FIELD(version, MDP5_MDP_VERSION_MAJOR); + *minor = FIELD(version, MDP5_MDP_VERSION_MINOR); + + DBG("MDP5 version v%d.%d", *major, *minor); +} + static int get_clk(struct platform_device *pdev, struct clk **clkp, const char *name) { @@ -383,10 +259,11 @@ static int get_clk(struct platform_device *pdev, struct clk **clkp, struct msm_kms *mdp5_kms_init(struct drm_device *dev) { struct platform_device *pdev = dev->platformdev; - struct mdp5_platform_config *config = mdp5_get_config(pdev); + struct mdp5_cfg *config; struct mdp5_kms *mdp5_kms; struct msm_kms *kms = NULL; struct msm_mmu *mmu; + uint32_t major, minor; void *priv; int i, ret; @@ -446,14 +323,19 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) if (ret) goto fail; - ret = mdp5_select_hw_cfg(kms); - if (ret) + read_hw_revision(mdp5_kms, &major, &minor); + priv = mdp5_cfg_init(mdp5_kms, major, minor); + if (IS_ERR(priv)) { + ret = PTR_ERR(priv); goto fail; + } + mdp5_kms->cfg_priv = priv; + config = mdp5_cfg_get_config(mdp5_kms->cfg_priv); /* TODO: compute core clock rate at runtime */ - clk_set_rate(mdp5_kms->src_clk, mdp5_kms->hw_cfg->max_clk); + clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk); - priv = mdp5_smp_init(mdp5_kms->dev, &mdp5_kms->hw_cfg->smp); + priv = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp); if (IS_ERR(priv)) { ret = PTR_ERR(priv); goto fail; @@ -465,13 +347,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) * we don't disable): */ mdp5_enable(mdp5_kms); - for (i = 0; i < mdp5_kms->hw_cfg->intf.count; i++) + for (i = 0; i < config->hw->intf.count; i++) mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0); mdp5_disable(mdp5_kms); mdelay(16); - if (config->iommu) { - mmu = msm_iommu_new(&pdev->dev, config->iommu); + if (config->platform.iommu) { + mmu = msm_iommu_new(&pdev->dev, config->platform.iommu); if (IS_ERR(mmu)) { ret = PTR_ERR(mmu); dev_err(dev->dev, "failed to init iommu: %d\n", ret); @@ -512,14 +394,3 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mdp5_destroy(kms); return ERR_PTR(ret); } - -static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev) -{ - static struct mdp5_platform_config config = {}; -#ifdef CONFIG_OF - /* TODO */ -#endif - config.iommu = iommu_domain_alloc(&platform_bus_type); - - return &config; -} diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 3f7aa49dd944..daca8da64666 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -21,36 +21,7 @@ #include "msm_drv.h" #include "msm_kms.h" #include "mdp/mdp_kms.h" -/* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */ -#define MDP5_MAX_BASES 8 -#define MAX_SMP_BLOCKS 44 -#define MAX_CLIENTS 32 -typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS); -struct mdp5_sub_block { - int count; - uint32_t base[MDP5_MAX_BASES]; -}; -struct mdp5_smp_block { - int mmb_count; /* number of SMP MMBs */ - int mmb_size; /* MMB: size in bytes */ - mdp5_smp_state_t reserved_state;/* SMP MMBs statically allocated */ - int reserved[MAX_CLIENTS]; /* # of MMBs reserved per client */ -}; -struct mdp5_config { - char *name; - struct mdp5_smp_block smp; - struct mdp5_sub_block ctl; - struct mdp5_sub_block pipe_vig; - struct mdp5_sub_block pipe_rgb; - struct mdp5_sub_block pipe_dma; - struct mdp5_sub_block lm; - struct mdp5_sub_block dspp; - struct mdp5_sub_block ad; - struct mdp5_sub_block intf; - - uint32_t max_clk; -}; -extern const struct mdp5_config *mdp5_cfg; +#include "mdp5_cfg.h" /* must be included before mdp5.xml.h */ #include "mdp5.xml.h" #include "mdp5_smp.h" @@ -59,8 +30,7 @@ struct mdp5_kms { struct drm_device *dev; - int rev; - const struct mdp5_config *hw_cfg; + void *cfg_priv; /* mapper-id used to request GEM buffer mapped for scanout: */ int id; @@ -89,11 +59,6 @@ struct mdp5_kms { }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) -/* platform config data (ie. from DT, or pdata) */ -struct mdp5_platform_config { - struct iommu_domain *iommu; -}; - static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) { msm_writel(data, mdp5_kms->mmio + reg); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c index e61e1cfed853..04996cae4585 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c @@ -108,11 +108,15 @@ static int smp_request_block(struct mdp5_smp *smp, enum mdp5_client_id cid, int nblks) { struct mdp5_kms *mdp5_kms = get_kms(smp); + const struct mdp5_cfg_hw *hw_cfg; struct mdp5_client_smp_state *ps = &smp->client_state[cid]; int i, ret, avail, cur_nblks, cnt = smp->blk_cnt; - int reserved = mdp5_kms->hw_cfg->smp.reserved[cid]; + int reserved; unsigned long flags; + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + reserved = hw_cfg->smp.reserved[cid]; + spin_lock_irqsave(&smp->state_lock, flags); nblks -= reserved; @@ -175,6 +179,7 @@ int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width) struct mdp5_smp *smp = handler; struct mdp5_kms *mdp5_kms = get_kms(smp); struct drm_device *dev = mdp5_kms->dev; + int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg_priv); int i, hsub, nplanes, nlines, nblks, ret; nplanes = drm_format_num_planes(fmt); @@ -192,7 +197,7 @@ int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width) n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size); /* for hw rev v1.00 */ - if (mdp5_kms->rev == 0) + if (rev == 0) n = roundup_pow_of_two(n); DBG("%s[%d]: request %d SMP blocks", pipe2name(pipe), i, n); -- GitLab From ac7a570406417e9d837f81c3a6b83fc8d629e583 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 20 Nov 2014 17:08:06 -0500 Subject: [PATCH 5665/9457] drm/msm/mdp5: set rate before enabling clk Set a "safe" rate at first, in order to read out the hw revision. And then after set the optimal value. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 64de0f9310c3..adb45419b08d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -323,6 +323,12 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) if (ret) goto fail; + /* we need to set a default rate before enabling. Set a safe + * rate first, then figure out hw revision, and then set a + * more optimal rate: + */ + clk_set_rate(mdp5_kms->src_clk, 200000000); + read_hw_revision(mdp5_kms, &major, &minor); priv = mdp5_cfg_init(mdp5_kms, major, minor); if (IS_ERR(priv)) { -- GitLab From 0deed25b65aaf495e36818481cfc9f58dfa5cd3f Mon Sep 17 00:00:00 2001 From: Stephane Viau Date: Tue, 18 Nov 2014 12:49:49 -0500 Subject: [PATCH 5666/9457] drm/msm: add multiple CRTC and overlay support MDP5 currently support one single CRTC with its private pipe. This change allows the configuration of multiple CRTCs with the possibility to attach several public planes to these CRTCs. Signed-off-by: Stephane Viau Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 1 + drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 271 ++++++++++++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 325 ++++++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h | 121 ++++++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 13 + drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 45 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 48 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 107 +++++-- 9 files changed, 811 insertions(+), 121 deletions(-) create mode 100644 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c create mode 100644 drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index dda38529dd56..143d988f8add 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -26,6 +26,7 @@ msm-y := \ mdp/mdp4/mdp4_kms.o \ mdp/mdp4/mdp4_plane.o \ mdp/mdp5/mdp5_cfg.o \ + mdp/mdp5/mdp5_ctl.o \ mdp/mdp5/mdp5_crtc.o \ mdp/mdp5/mdp5_encoder.o \ mdp/mdp5/mdp5_irq.o \ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h index 00c8271ad928..d0c98f9a93e1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h @@ -24,6 +24,7 @@ */ extern const struct mdp5_cfg_hw *mdp5_cfg; +#define MAX_CTL 8 #define MAX_BASES 8 #define MAX_SMP_BLOCKS 44 #define MAX_CLIENTS 32 diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index b7b32c47fd71..85f2fb460a88 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -22,14 +23,21 @@ #include "drm_crtc_helper.h" #include "drm_flip_work.h" +#define SSPP_MAX (SSPP_RGB3 + 1) /* TODO: Add SSPP_MAX in mdp5.xml.h */ + struct mdp5_crtc { struct drm_crtc base; char name[8]; int id; bool enabled; - /* which mixer/encoder we route output to: */ - int mixer; + /* layer mixer used for this CRTC (+ its lock): */ +#define GET_LM_ID(crtc_id) ((crtc_id == 3) ? 5 : crtc_id) + int lm; + spinlock_t lm_lock; /* protect REG_MDP5_LM_* registers */ + + /* CTL used for this CRTC: */ + void *ctl; /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; @@ -71,25 +79,38 @@ static void request_pending(struct drm_crtc *crtc, uint32_t pending) mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank); } -static void crtc_flush(struct drm_crtc *crtc) +#define mdp5_lm_get_flush(lm) mdp_ctl_flush_mask_lm(lm) + +static void crtc_flush(struct drm_crtc *crtc, u32 flush_mask) +{ + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + + DBG("%s: flush=%08x", mdp5_crtc->name, flush_mask); + mdp5_ctl_commit(mdp5_crtc->ctl, flush_mask); +} + +/* + * flush updates, to make sure hw is updated to new scanout fb, + * so that we can safely queue unref to current fb (ie. next + * vblank we know hw is done w/ previous scanout_fb). + */ +static void crtc_flush_all(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - struct mdp5_kms *mdp5_kms = get_kms(crtc); - int id = mdp5_crtc->id; struct drm_plane *plane; - uint32_t flush = 0; + uint32_t flush_mask = 0; + + /* we could have already released CTL in the disable path: */ + if (!mdp5_crtc->ctl) + return; for_each_plane_on_crtc(crtc, plane) { - enum mdp5_pipe pipe = mdp5_plane_pipe(plane); - flush |= pipe2flush(pipe); + flush_mask |= mdp5_plane_get_flush(plane); } + flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl); + flush_mask |= mdp5_lm_get_flush(mdp5_crtc->lm); - flush |= mixer2flush(mdp5_crtc->id); - flush |= MDP5_CTL_FLUSH_CTL; - - DBG("%s: flush=%08x", mdp5_crtc->name, flush); - - mdp5_write(mdp5_kms, REG_MDP5_CTL_FLUSH(id), flush); + crtc_flush(crtc, flush_mask); } static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) @@ -117,12 +138,6 @@ static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - /* flush updates, to make sure hw is updated to new scanout fb, - * so that we can safely queue unref to current fb (ie. next - * vblank we know hw is done w/ previous scanout_fb). - */ - crtc_flush(crtc); - if (mdp5_crtc->scanout_fb) drm_flip_work_queue(&mdp5_crtc->unref_fb_work, mdp5_crtc->scanout_fb); @@ -173,6 +188,7 @@ static void pageflip_cb(struct msm_fence_cb *cb) drm_framebuffer_reference(fb); mdp5_plane_set_scanout(crtc->primary, fb); update_scanout(crtc, fb); + crtc_flush_all(crtc); } static void unref_fb_worker(struct drm_flip_work *work, void *val) @@ -223,41 +239,68 @@ static bool mdp5_crtc_mode_fixup(struct drm_crtc *crtc, return true; } +/* + * blend_setup() - blend all the planes of a CRTC + * + * When border is enabled, the border color will ALWAYS be the base layer. + * Therefore, the first plane (private RGB pipe) will start at STAGE0. + * If disabled, the first plane starts at STAGE_BASE. + * + * Note: + * Border is not enabled here because the private plane is exactly + * the CRTC resolution. + */ static void blend_setup(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_kms *mdp5_kms = get_kms(crtc); - int id = mdp5_crtc->id; + struct drm_plane *plane; + const struct mdp5_cfg_hw *hw_cfg; + uint32_t lm = mdp5_crtc->lm, blend_cfg = 0; + enum mdp_mixer_stage_id stage; + unsigned long flags; +#define blender(stage) ((stage) - STAGE_BASE) - /* - * Hard-coded setup for now until I figure out how the - * layer-mixer works - */ + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); - /* LM[id]: */ - mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(id), - MDP5_LM_BLEND_COLOR_OUT_STAGE0_FG_ALPHA); - mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_OP_MODE(id, 0), - MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) | - MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL) | - MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA); - mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_FG_ALPHA(id, 0), 0xff); - mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(id, 0), 0x00); - - /* NOTE: seems that LM[n] and CTL[m], we do not need n==m.. but - * we want to be setting CTL[m].LAYER[n]. Not sure what the - * point of having CTL[m].LAYER[o] (for o!=n).. maybe that is - * used when chaining up mixers for high resolution displays? - */ + spin_lock_irqsave(&mdp5_crtc->lm_lock, flags); + + /* ctl could be released already when we are shutting down: */ + if (!mdp5_crtc->ctl) + goto out; + + for_each_plane_on_crtc(crtc, plane) { + struct mdp5_overlay_info *overlay; + + overlay = mdp5_plane_get_overlay_info(plane); + stage = overlay->zorder; - /* CTL[id]: */ - mdp5_write(mdp5_kms, REG_MDP5_CTL_LAYER_REG(id, 0), - MDP5_CTL_LAYER_REG_RGB0(STAGE0) | - MDP5_CTL_LAYER_REG_BORDER_COLOR); - mdp5_write(mdp5_kms, REG_MDP5_CTL_LAYER_REG(id, 1), 0); - mdp5_write(mdp5_kms, REG_MDP5_CTL_LAYER_REG(id, 2), 0); - mdp5_write(mdp5_kms, REG_MDP5_CTL_LAYER_REG(id, 3), 0); - mdp5_write(mdp5_kms, REG_MDP5_CTL_LAYER_REG(id, 4), 0); + /* + * Note: This cannot happen with current implementation but + * we need to check this condition once z property is added + */ + BUG_ON(stage > hw_cfg->lm.nb_stages); + + /* LM */ + mdp5_write(mdp5_kms, + REG_MDP5_LM_BLEND_OP_MODE(lm, blender(stage)), + MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) | + MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST)); + mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_FG_ALPHA(lm, + blender(stage)), 0xff); + mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(lm, + blender(stage)), 0x00); + /* CTL */ + blend_cfg |= mdp_ctl_blend_mask(mdp5_plane_pipe(plane), stage); + DBG("%s: blending pipe %s on stage=%d", mdp5_crtc->name, + pipe2name(mdp5_plane_pipe(plane)), stage); + } + + DBG("%s: lm%d: blend config = 0x%08x", mdp5_crtc->name, lm, blend_cfg); + mdp5_ctl_blend(mdp5_crtc->ctl, lm, blend_cfg); + +out: + spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); } static int mdp5_crtc_mode_set(struct drm_crtc *crtc, @@ -268,6 +311,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_kms *mdp5_kms = get_kms(crtc); + unsigned long flags; int ret; mode = adjusted_mode; @@ -281,6 +325,13 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, mode->vsync_end, mode->vtotal, mode->type, mode->flags); + /* request a free CTL, if none is already allocated for this CRTC */ + if (!mdp5_crtc->ctl) { + mdp5_crtc->ctl = mdp5_ctl_request(mdp5_kms->ctl_priv, crtc); + if (!mdp5_crtc->ctl) + return -EBUSY; + } + /* grab extra ref for update_scanout() */ drm_framebuffer_reference(crtc->primary->fb); @@ -295,12 +346,15 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, return ret; } - mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(mdp5_crtc->id), + spin_lock_irqsave(&mdp5_crtc->lm_lock, flags); + mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(mdp5_crtc->lm), MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) | MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay)); + spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); update_fb(crtc, crtc->primary->fb); update_scanout(crtc, crtc->primary->fb); + /* crtc_flush_all(crtc) will be called in _commit callback */ return 0; } @@ -317,7 +371,7 @@ static void mdp5_crtc_prepare(struct drm_crtc *crtc) static void mdp5_crtc_commit(struct drm_crtc *crtc) { mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_ON); - crtc_flush(crtc); + crtc_flush_all(crtc); /* drop the ref to mdp clk's that we got in prepare: */ mdp5_disable(get_kms(crtc)); } @@ -343,6 +397,7 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, update_fb(crtc, crtc->primary->fb); update_scanout(crtc, crtc->primary->fb); + crtc_flush_all(crtc); return 0; } @@ -351,6 +406,19 @@ static void mdp5_crtc_load_lut(struct drm_crtc *crtc) { } +static void mdp5_crtc_disable(struct drm_crtc *crtc) +{ + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + + DBG("%s", mdp5_crtc->name); + + if (mdp5_crtc->ctl) { + mdp5_ctl_release(mdp5_crtc->ctl); + mdp5_crtc->ctl = NULL; + } +} + + static int mdp5_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *new_fb, struct drm_pending_vblank_event *event, @@ -399,6 +467,7 @@ static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { .commit = mdp5_crtc_commit, .mode_set_base = mdp5_crtc_mode_set_base, .load_lut = mdp5_crtc_load_lut, + .disable = mdp5_crtc_disable, }; static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) @@ -421,9 +490,8 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus) { struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, err); - struct drm_crtc *crtc = &mdp5_crtc->base; + DBG("%s: error: %08x", mdp5_crtc->name, irqstatus); - crtc_flush(crtc); } uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc) @@ -444,10 +512,9 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_kms *mdp5_kms = get_kms(crtc); - static const enum mdp5_intfnum intfnum[] = { - INTF0, INTF1, INTF2, INTF3, - }; + uint32_t flush_mask = 0; uint32_t intf_sel; + unsigned long flags; /* now that we know what irq's we want: */ mdp5_crtc->err.irqmask = intf2err(intf); @@ -457,6 +524,7 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, if (!mdp5_kms) return; + spin_lock_irqsave(&mdp5_kms->resource_lock, flags); intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL); switch (intf) { @@ -481,16 +549,24 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, break; } - blend_setup(crtc); + mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel); + spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags); DBG("%s: intf_sel=%08x", mdp5_crtc->name, intf_sel); + mdp5_ctl_set_intf(mdp5_crtc->ctl, intf); + flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl); + flush_mask |= mdp5_lm_get_flush(mdp5_crtc->lm); - mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel); - mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(mdp5_crtc->id), - MDP5_CTL_OP_MODE(MODE_NONE) | - MDP5_CTL_OP_INTF_NUM(intfnum[intf])); + crtc_flush(crtc, flush_mask); +} - crtc_flush(crtc); +static int count_planes(struct drm_crtc *crtc) +{ + struct drm_plane *plane; + int cnt = 0; + for_each_plane_on_crtc(crtc, plane) + cnt++; + return cnt; } static void set_attach(struct drm_crtc *crtc, enum mdp5_pipe pipe_id, @@ -498,14 +574,68 @@ static void set_attach(struct drm_crtc *crtc, enum mdp5_pipe pipe_id, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + if (plane) + plane->crtc = crtc; + + DBG("%s: %d planes attached", mdp5_crtc->name, count_planes(crtc)); + blend_setup(crtc); - if (mdp5_crtc->enabled && (plane != crtc->primary)) - crtc_flush(crtc); + if (mdp5_crtc->enabled) + crtc_flush_all(crtc); } -void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) +int mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) { + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct device *dev = crtc->dev->dev; + const struct mdp5_cfg_hw *hw_cfg; + bool private_plane = (plane == crtc->primary); + struct mdp5_overlay_info overlay_info; + enum mdp_mixer_stage_id stage = STAGE_BASE; + int max_nb_planes; + + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + max_nb_planes = hw_cfg->lm.nb_stages; + + if (count_planes(crtc) >= max_nb_planes) { + dev_err(dev, "%s: max # of planes (%d) reached\n", + mdp5_crtc->name, max_nb_planes); + return -EBUSY; + } + + /* + * Set default z-ordering depending on the type of plane + * private -> lower stage + * public -> topmost stage + * + * TODO: add a property to give userspace an API to change this... + * (will come in a subsequent patch) + */ + if (private_plane) { + stage = STAGE_BASE; + } else { + struct drm_plane *attached_plane; + for_each_plane_on_crtc(crtc, attached_plane) { + struct mdp5_overlay_info *overlay; + + if (!attached_plane) + continue; + overlay = mdp5_plane_get_overlay_info(attached_plane); + stage = max(stage, overlay->zorder); + } + stage++; + } + overlay_info.zorder = stage; + mdp5_plane_set_overlay_info(plane, &overlay_info); + + DBG("%s: %s plane %s set to stage %d by default", mdp5_crtc->name, + private_plane ? "private" : "public", + pipe2name(mdp5_plane_pipe(plane)), overlay_info.zorder); + set_attach(crtc, mdp5_plane_pipe(plane), plane); + + return 0; } void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) @@ -516,6 +646,16 @@ void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) set_attach(crtc, mdp5_plane_pipe(plane), NULL); } +int mdp5_crtc_get_lm(struct drm_crtc *crtc) +{ + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + + if (WARN_ON(!crtc)) + return -EINVAL; + + return mdp5_crtc->lm; +} + /* initialize crtc */ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, struct drm_plane *plane, int id) @@ -530,6 +670,9 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, crtc = &mdp5_crtc->base; mdp5_crtc->id = id; + mdp5_crtc->lm = GET_LM_ID(id); + + spin_lock_init(&mdp5_crtc->lm_lock); mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq; mdp5_crtc->err.irq = mdp5_crtc_err_irq; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c new file mode 100644 index 000000000000..a6155b77cb13 --- /dev/null +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "mdp5_kms.h" +#include "mdp5_ctl.h" + +/* + * CTL - MDP Control Pool Manager + * + * Controls are shared between all CRTCs. + * + * They are intended to be used for data path configuration. + * The top level register programming describes the complete data path for + * a specific data path ID - REG_MDP5_CTL_*(, ...) + * + * Hardware capabilities determine the number of concurrent data paths + * + * In certain use cases (high-resolution dual pipe), one single CTL can be + * shared across multiple CRTCs. + * + * Because the number of CTLs can be less than the number of CRTCs, + * CTLs are dynamically allocated from a pool of CTLs, only once a CRTC is + * requested by the client (in mdp5_crtc_mode_set()). + */ + +struct mdp5_ctl { + u32 id; + + /* whether this CTL has been allocated or not: */ + bool busy; + + /* memory output connection (@see mdp5_ctl_mode): */ + u32 mode; + + /* REG_MDP5_CTL_*() registers access info + lock: */ + spinlock_t hw_lock; + u32 reg_offset; + + /* flush mask used to commit CTL registers */ + u32 flush_mask; + + bool cursor_on; + void *crtc; +}; + +struct mdp5_ctl_manager { + struct drm_device *dev; + + /* number of CTL / Layer Mixers in this hw config: */ + u32 nlm; + u32 nctl; + + /* pool of CTLs + lock to protect resource allocation (ctls[i].busy) */ + spinlock_t pool_lock; + struct mdp5_ctl ctls[MAX_CTL]; +}; + +static struct mdp5_ctl_manager mdp5_ctl_mgr; + +static inline +struct mdp5_kms *get_kms(struct mdp5_ctl_manager *ctl_mgr) +{ + struct msm_drm_private *priv = ctl_mgr->dev->dev_private; + + return to_mdp5_kms(to_mdp_kms(priv->kms)); +} + +static inline +void ctl_write(struct mdp5_ctl *ctl, u32 reg, u32 data) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); + + (void)ctl->reg_offset; /* TODO use this instead of mdp5_write */ + mdp5_write(mdp5_kms, reg, data); +} + +static inline +u32 ctl_read(struct mdp5_ctl *ctl, u32 reg) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); + + (void)ctl->reg_offset; /* TODO use this instead of mdp5_write */ + return mdp5_read(mdp5_kms, reg); +} + + +int mdp5_ctl_set_intf(void *c, enum mdp5_intf intf) +{ + struct mdp5_ctl *ctl = c; + unsigned long flags; + static const enum mdp5_intfnum intfnum[] = { + INTF0, INTF1, INTF2, INTF3, + }; + + spin_lock_irqsave(&ctl->hw_lock, flags); + ctl_write(ctl, REG_MDP5_CTL_OP(ctl->id), + MDP5_CTL_OP_MODE(ctl->mode) | + MDP5_CTL_OP_INTF_NUM(intfnum[intf])); + spin_unlock_irqrestore(&ctl->hw_lock, flags); + + return 0; +} + +int mdp5_ctl_set_cursor(void *c, bool enable) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl *ctl = c; + unsigned long flags; + u32 blend_cfg; + int lm; + + lm = mdp5_crtc_get_lm(ctl->crtc); + if (unlikely(WARN_ON(lm < 0))) { + dev_err(ctl_mgr->dev->dev, "CTL %d cannot find LM: %d", + ctl->id, lm); + return -EINVAL; + } + + spin_lock_irqsave(&ctl->hw_lock, flags); + + blend_cfg = ctl_read(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, lm)); + + if (enable) + blend_cfg |= MDP5_CTL_LAYER_REG_CURSOR_OUT; + else + blend_cfg &= ~MDP5_CTL_LAYER_REG_CURSOR_OUT; + + ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, lm), blend_cfg); + + spin_unlock_irqrestore(&ctl->hw_lock, flags); + + ctl->cursor_on = enable; + + return 0; +} + + +int mdp5_ctl_blend(void *c, u32 lm, u32 blend_cfg) +{ + struct mdp5_ctl *ctl = c; + unsigned long flags; + + if (ctl->cursor_on) + blend_cfg |= MDP5_CTL_LAYER_REG_CURSOR_OUT; + else + blend_cfg &= ~MDP5_CTL_LAYER_REG_CURSOR_OUT; + + spin_lock_irqsave(&ctl->hw_lock, flags); + ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, lm), blend_cfg); + spin_unlock_irqrestore(&ctl->hw_lock, flags); + + return 0; +} + +int mdp5_ctl_commit(void *c, u32 flush_mask) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl *ctl = c; + unsigned long flags; + + if (flush_mask & MDP5_CTL_FLUSH_CURSOR_DUMMY) { + int lm = mdp5_crtc_get_lm(ctl->crtc); + + if (unlikely(WARN_ON(lm < 0))) { + dev_err(ctl_mgr->dev->dev, "CTL %d cannot find LM: %d", + ctl->id, lm); + return -EINVAL; + } + + /* for current targets, cursor bit is the same as LM bit */ + flush_mask |= mdp_ctl_flush_mask_lm(lm); + } + + spin_lock_irqsave(&ctl->hw_lock, flags); + ctl_write(ctl, REG_MDP5_CTL_FLUSH(ctl->id), flush_mask); + spin_unlock_irqrestore(&ctl->hw_lock, flags); + + return 0; +} + +u32 mdp5_ctl_get_flush(void *c) +{ + struct mdp5_ctl *ctl = c; + + return ctl->flush_mask; +} + +void mdp5_ctl_release(void *c) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl *ctl = c; + unsigned long flags; + + if (unlikely(WARN_ON(ctl->id >= MAX_CTL) || !ctl->busy)) { + dev_err(ctl_mgr->dev->dev, "CTL %d in bad state (%d)", + ctl->id, ctl->busy); + return; + } + + spin_lock_irqsave(&ctl_mgr->pool_lock, flags); + ctl->busy = false; + spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); + + DBG("CTL %d released", ctl->id); +} + +/* + * mdp5_ctl_request() - CTL dynamic allocation + * + * Note: Current implementation considers that we can only have one CRTC per CTL + * + * @return first free CTL + */ +void *mdp5_ctl_request(void *ctlm, void *crtc) +{ + struct mdp5_ctl_manager *ctl_mgr = ctlm; + struct mdp5_ctl *ctl = NULL; + unsigned long flags; + int c; + + spin_lock_irqsave(&ctl_mgr->pool_lock, flags); + + for (c = 0; c < ctl_mgr->nctl; c++) + if (!ctl_mgr->ctls[c].busy) + break; + + if (unlikely(c >= ctl_mgr->nctl)) { + dev_err(ctl_mgr->dev->dev, "No more CTL available!"); + goto unlock; + } + + ctl = &ctl_mgr->ctls[c]; + + ctl->crtc = crtc; + ctl->busy = true; + DBG("CTL %d allocated", ctl->id); + +unlock: + spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); + return ctl; +} + +void mdp5_ctlm_hw_reset(void *ctlm) +{ + struct mdp5_ctl_manager *ctl_mgr = ctlm; + unsigned long flags; + int c; + + for (c = 0; c < ctl_mgr->nctl; c++) { + struct mdp5_ctl *ctl = &ctl_mgr->ctls[c]; + + spin_lock_irqsave(&ctl->hw_lock, flags); + ctl_write(ctl, REG_MDP5_CTL_OP(ctl->id), 0); + spin_unlock_irqrestore(&ctl->hw_lock, flags); + } +} + +void mdp5_ctlm_destroy(void *ctlm) +{ + struct mdp5_ctl_manager *ctl_mgr = ctlm; + + kfree(ctl_mgr); +} + +void *mdp5_ctlm_init(struct drm_device *dev, void __iomem *mmio_base, + const struct mdp5_cfg_hw *hw_cfg) +{ + struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + const struct mdp5_sub_block *ctl_cfg = &hw_cfg->ctl; + unsigned long flags; + int c, ret; + + if (unlikely(WARN_ON(ctl_cfg->count > MAX_CTL))) { + dev_err(dev->dev, "Increase static pool size to at least %d\n", + ctl_cfg->count); + ret = -ENOSPC; + goto fail; + } + + /* initialize the CTL manager: */ + ctl_mgr->dev = dev; + ctl_mgr->nlm = hw_cfg->lm.count; + ctl_mgr->nctl = ctl_cfg->count; + spin_lock_init(&ctl_mgr->pool_lock); + + /* initialize each CTL of the pool: */ + spin_lock_irqsave(&ctl_mgr->pool_lock, flags); + for (c = 0; c < ctl_mgr->nctl; c++) { + struct mdp5_ctl *ctl = &ctl_mgr->ctls[c]; + + if (WARN_ON(!ctl_cfg->base[c])) { + dev_err(dev->dev, "CTL_%d: base is null!\n", c); + ret = -EINVAL; + goto fail; + } + ctl->id = c; + ctl->mode = MODE_NONE; + ctl->reg_offset = ctl_cfg->base[c]; + ctl->flush_mask = MDP5_CTL_FLUSH_CTL; + ctl->busy = false; + spin_lock_init(&ctl->hw_lock); + } + spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); + DBG("Pool of %d CTLs created.", ctl_mgr->nctl); + + return ctl_mgr; + +fail: + if (ctl_mgr) + mdp5_ctlm_destroy(ctl_mgr); + + return ERR_PTR(ret); +} diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h new file mode 100644 index 000000000000..dbe1cae71937 --- /dev/null +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MDP5_CTL_H__ +#define __MDP5_CTL_H__ + +#include "msm_drv.h" + +/* + * CTL Manager prototypes: + * mdp5_ctlm_init() returns a ctlm (CTL Manager) handler, + * which is then used to call the other mdp5_ctlm_*(ctlm, ...) functions. + */ +void *mdp5_ctlm_init(struct drm_device *dev, void __iomem *mmio_base, + const struct mdp5_cfg_hw *hw_cfg); +void mdp5_ctlm_hw_reset(void *ctlm); +void mdp5_ctlm_destroy(void *ctlm); + +/* + * CTL prototypes: + * mdp5_ctl_request(ctlm, ...) returns a ctl (CTL resource) handler, + * which is then used to call the other mdp5_ctl_*(ctl, ...) functions. + */ +void *mdp5_ctl_request(void *ctlm, void *crtc); + +int mdp5_ctl_set_intf(void *ctl, enum mdp5_intf intf); + +int mdp5_ctl_set_cursor(void *ctl, bool enable); + +/* @blend_cfg: see LM blender config definition below */ +int mdp5_ctl_blend(void *ctl, u32 lm, u32 blend_cfg); + +/* @flush_mask: see CTL flush masks definitions below */ +int mdp5_ctl_commit(void *ctl, u32 flush_mask); +u32 mdp5_ctl_get_flush(void *ctl); + +void mdp5_ctl_release(void *ctl); + +/* + * blend_cfg (LM blender config): + * + * The function below allows the caller of mdp5_ctl_blend() to specify how pipes + * are being blended according to their stage (z-order), through @blend_cfg arg. + */ +static inline u32 mdp_ctl_blend_mask(enum mdp5_pipe pipe, + enum mdp_mixer_stage_id stage) +{ + switch (pipe) { + case SSPP_VIG0: return MDP5_CTL_LAYER_REG_VIG0(stage); + case SSPP_VIG1: return MDP5_CTL_LAYER_REG_VIG1(stage); + case SSPP_VIG2: return MDP5_CTL_LAYER_REG_VIG2(stage); + case SSPP_RGB0: return MDP5_CTL_LAYER_REG_RGB0(stage); + case SSPP_RGB1: return MDP5_CTL_LAYER_REG_RGB1(stage); + case SSPP_RGB2: return MDP5_CTL_LAYER_REG_RGB2(stage); + case SSPP_DMA0: return MDP5_CTL_LAYER_REG_DMA0(stage); + case SSPP_DMA1: return MDP5_CTL_LAYER_REG_DMA1(stage); + case SSPP_VIG3: return MDP5_CTL_LAYER_REG_VIG3(stage); + case SSPP_RGB3: return MDP5_CTL_LAYER_REG_RGB3(stage); + default: return 0; + } +} + +/* + * flush_mask (CTL flush masks): + * + * The following functions allow each DRM entity to get and store + * their own flush mask. + * Once stored, these masks will then be accessed through each DRM's + * interface and used by the caller of mdp5_ctl_commit() to specify + * which block(s) need to be flushed through @flush_mask parameter. + */ + +#define MDP5_CTL_FLUSH_CURSOR_DUMMY 0x80000000 + +static inline u32 mdp_ctl_flush_mask_cursor(int cursor_id) +{ + /* TODO: use id once multiple cursor support is present */ + (void)cursor_id; + + return MDP5_CTL_FLUSH_CURSOR_DUMMY; +} + +static inline u32 mdp_ctl_flush_mask_lm(int lm) +{ + switch (lm) { + case 0: return MDP5_CTL_FLUSH_LM0; + case 1: return MDP5_CTL_FLUSH_LM1; + case 2: return MDP5_CTL_FLUSH_LM2; + case 5: return MDP5_CTL_FLUSH_LM5; + default: return 0; + } +} + +static inline u32 mdp_ctl_flush_mask_pipe(enum mdp5_pipe pipe) +{ + switch (pipe) { + case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0; + case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1; + case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2; + case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0; + case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1; + case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2; + case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0; + case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1; + case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3; + case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3; + default: return 0; + } +} + +#endif /* __MDP5_CTL_H__ */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index edec7bfaa952..25c2fcb39ac3 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -24,6 +24,7 @@ struct mdp5_encoder { struct drm_encoder base; int intf; enum mdp5_intf intf_id; + spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */ bool enabled; uint32_t bsc; }; @@ -115,6 +116,7 @@ static void mdp5_encoder_dpms(struct drm_encoder *encoder, int mode) struct mdp5_kms *mdp5_kms = get_kms(encoder); int intf = mdp5_encoder->intf; bool enabled = (mode == DRM_MODE_DPMS_ON); + unsigned long flags; DBG("mode=%d", mode); @@ -123,9 +125,13 @@ static void mdp5_encoder_dpms(struct drm_encoder *encoder, int mode) if (enabled) { bs_set(mdp5_encoder, 1); + spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1); + spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); } else { + spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0); + spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); bs_set(mdp5_encoder, 0); } @@ -150,6 +156,7 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, uint32_t display_v_start, display_v_end; uint32_t hsync_start_x, hsync_end_x; uint32_t format; + unsigned long flags; mode = adjusted_mode; @@ -180,6 +187,8 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew; display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1; + spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); + mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf), MDP5_INTF_HSYNC_CTL_PULSEW(mode->hsync_end - mode->hsync_start) | MDP5_INTF_HSYNC_CTL_PERIOD(mode->htotal)); @@ -201,6 +210,8 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VEND_F0(intf), 0); mdp5_write(mdp5_kms, REG_MDP5_INTF_PANEL_FORMAT(intf), format); mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3); /* frame+line? */ + + spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); } static void mdp5_encoder_prepare(struct drm_encoder *encoder) @@ -242,6 +253,8 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf, mdp5_encoder->intf_id = intf_id; encoder = &mdp5_encoder->base; + spin_lock_init(&mdp5_encoder->intf_lock); + drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, DRM_MODE_ENCODER_TMDS); drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index adb45419b08d..da248c2b4fe8 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -28,9 +28,8 @@ static const char *iommu_ports[] = { static int mdp5_hw_init(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - const struct mdp5_cfg_hw *hw_cfg; struct drm_device *dev = mdp5_kms->dev; - int i; + unsigned long flags; pm_runtime_get_sync(dev->dev); @@ -58,12 +57,11 @@ static int mdp5_hw_init(struct msm_kms *kms) * care. */ + spin_lock_irqsave(&mdp5_kms->resource_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0); + spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags); - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); - - for (i = 0; i < hw_cfg->ctl.count; i++) - mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(i), 0); + mdp5_ctlm_hw_reset(mdp5_kms->ctl_priv); pm_runtime_put_sync(dev->dev); @@ -92,6 +90,7 @@ static void mdp5_destroy(struct msm_kms *kms) struct msm_mmu *mmu = mdp5_kms->mmu; void *smp = mdp5_kms->smp_priv; void *cfg = mdp5_kms->cfg_priv; + void *ctl = mdp5_kms->ctl_priv; mdp5_irq_domain_fini(mdp5_kms); @@ -99,7 +98,8 @@ static void mdp5_destroy(struct msm_kms *kms) mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); mmu->funcs->destroy(mmu); } - + if (ctl) + mdp5_ctlm_destroy(ctl); if (smp) mdp5_smp_destroy(smp); if (cfg) @@ -154,6 +154,9 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) static const enum mdp5_pipe crtcs[] = { SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3, }; + static const enum mdp5_pipe pub_planes[] = { + SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3, + }; struct drm_device *dev = mdp5_kms->dev; struct msm_drm_private *priv = dev->dev_private; struct drm_encoder *encoder; @@ -169,12 +172,13 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) if (ret) goto fail; - /* construct CRTCs: */ + /* construct CRTCs and their private planes: */ for (i = 0; i < hw_cfg->pipe_rgb.count; i++) { struct drm_plane *plane; struct drm_crtc *crtc; - plane = mdp5_plane_init(dev, crtcs[i], true); + plane = mdp5_plane_init(dev, crtcs[i], true, + hw_cfg->pipe_rgb.base[i]); if (IS_ERR(plane)) { ret = PTR_ERR(plane); dev_err(dev->dev, "failed to construct plane for %s (%d)\n", @@ -192,6 +196,20 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) priv->crtcs[priv->num_crtcs++] = crtc; } + /* Construct public planes: */ + for (i = 0; i < hw_cfg->pipe_vig.count; i++) { + struct drm_plane *plane; + + plane = mdp5_plane_init(dev, pub_planes[i], false, + hw_cfg->pipe_vig.base[i]); + if (IS_ERR(plane)) { + ret = PTR_ERR(plane); + dev_err(dev->dev, "failed to construct %s plane: %d\n", + pipe2name(pub_planes[i]), ret); + goto fail; + } + } + /* Construct encoder for HDMI: */ encoder = mdp5_encoder_init(dev, 3, INTF_HDMI); if (IS_ERR(encoder)) { @@ -274,6 +292,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) goto fail; } + spin_lock_init(&mdp5_kms->resource_lock); + mdp_kms_init(&mdp5_kms->base, &kms_funcs); kms = &mdp5_kms->base.base; @@ -348,6 +368,13 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) } mdp5_kms->smp_priv = priv; + priv = mdp5_ctlm_init(dev, mdp5_kms->mmio, config->hw); + if (IS_ERR(priv)) { + ret = PTR_ERR(priv); + goto fail; + } + mdp5_kms->ctl_priv = priv; + /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if * we don't disable): diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index daca8da64666..77fd43ea912e 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -23,6 +23,7 @@ #include "mdp/mdp_kms.h" #include "mdp5_cfg.h" /* must be included before mdp5.xml.h */ #include "mdp5.xml.h" +#include "mdp5_ctl.h" #include "mdp5_smp.h" struct mdp5_kms { @@ -37,6 +38,7 @@ struct mdp5_kms { struct msm_mmu *mmu; void *smp_priv; + void *ctl_priv; /* io/register spaces: */ void __iomem *mmio, *vbif; @@ -50,6 +52,12 @@ struct mdp5_kms { struct clk *lut_clk; struct clk *vsync_clk; + /* + * lock to protect access to global resources: ie., following register: + * - REG_MDP5_DISP_INTF_SEL + */ + spinlock_t resource_lock; + struct mdp_irq error_handler; struct { @@ -59,6 +67,10 @@ struct mdp5_kms { }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) +struct mdp5_overlay_info { + enum mdp_mixer_stage_id zorder; +}; + static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) { msm_writel(data, mdp5_kms->mmio + reg); @@ -82,23 +94,6 @@ static inline const char *pipe2name(enum mdp5_pipe pipe) return names[pipe]; } -static inline uint32_t pipe2flush(enum mdp5_pipe pipe) -{ - switch (pipe) { - case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0; - case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1; - case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2; - case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0; - case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1; - case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2; - case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0; - case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1; - case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3; - case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3; - default: return 0; - } -} - static inline int pipe2nclients(enum mdp5_pipe pipe) { switch (pipe) { @@ -112,16 +107,6 @@ static inline int pipe2nclients(enum mdp5_pipe pipe) } } -static inline uint32_t mixer2flush(int lm) -{ - switch (lm) { - case 0: return MDP5_CTL_FLUSH_LM0; - case 1: return MDP5_CTL_FLUSH_LM1; - case 2: return MDP5_CTL_FLUSH_LM2; - default: return 0; - } -} - static inline uint32_t intf2err(int intf) { switch (intf) { @@ -169,6 +154,10 @@ uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); +void mdp5_plane_set_overlay_info(struct drm_plane *plane, + const struct mdp5_overlay_info *overlay_info); +struct mdp5_overlay_info *mdp5_plane_get_overlay_info(struct drm_plane *plane); +uint32_t mdp5_plane_get_flush(struct drm_plane *plane); void mdp5_plane_set_scanout(struct drm_plane *plane, struct drm_framebuffer *fb); int mdp5_plane_mode_set(struct drm_plane *plane, @@ -180,14 +169,15 @@ int mdp5_plane_mode_set(struct drm_plane *plane, void mdp5_plane_complete_flip(struct drm_plane *plane); enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); struct drm_plane *mdp5_plane_init(struct drm_device *dev, - enum mdp5_pipe pipe, bool private_plane); + enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset); uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); +int mdp5_crtc_get_lm(struct drm_crtc *crtc); void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, enum mdp5_intf intf_id); -void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); +int mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, struct drm_plane *plane, int id); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 633ca08bb014..59703faa9d13 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -17,6 +18,7 @@ #include "mdp5_kms.h" +#define MAX_PLANE 4 struct mdp5_plane { struct drm_plane base; @@ -24,6 +26,13 @@ struct mdp5_plane { enum mdp5_pipe pipe; + spinlock_t pipe_lock; /* protect REG_MDP5_PIPE_* registers */ + uint32_t reg_offset; + + uint32_t flush_mask; /* used to commit pipe registers */ + + struct mdp5_overlay_info overlay_info; + uint32_t nformats; uint32_t formats[32]; @@ -95,6 +104,22 @@ static void mdp5_plane_destroy(struct drm_plane *plane) kfree(mdp5_plane); } +void mdp5_plane_set_overlay_info(struct drm_plane *plane, + const struct mdp5_overlay_info *overlay_info) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + + memcpy(&mdp5_plane->overlay_info, overlay_info, sizeof(*overlay_info)); +} + +struct mdp5_overlay_info *mdp5_plane_get_overlay_info( + struct drm_plane *plane) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + + return &mdp5_plane->overlay_info; +} + /* helper to install properties which are common to planes and crtcs */ void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) @@ -116,35 +141,58 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { .set_property = mdp5_plane_set_property, }; -void mdp5_plane_set_scanout(struct drm_plane *plane, - struct drm_framebuffer *fb) +static int get_fb_addr(struct drm_plane *plane, struct drm_framebuffer *fb, + uint32_t iova[MAX_PLANE]) { - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); - enum mdp5_pipe pipe = mdp5_plane->pipe; uint32_t nplanes = drm_format_num_planes(fb->pixel_format); - uint32_t iova[4]; int i; for (i = 0; i < nplanes; i++) { struct drm_gem_object *bo = msm_framebuffer_bo(fb, i); msm_gem_get_iova(bo, mdp5_kms->id, &iova[i]); } - for (; i < 4; i++) + for (; i < MAX_PLANE; i++) iova[i] = 0; + return 0; +} + +static void set_scanout_locked(struct drm_plane *plane, + uint32_t pitches[MAX_PLANE], uint32_t src_addr[MAX_PLANE]) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + struct mdp5_kms *mdp5_kms = get_kms(plane); + enum mdp5_pipe pipe = mdp5_plane->pipe; + + WARN_ON(!spin_is_locked(&mdp5_plane->pipe_lock)); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe), - MDP5_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | - MDP5_PIPE_SRC_STRIDE_A_P1(fb->pitches[1])); + MDP5_PIPE_SRC_STRIDE_A_P0(pitches[0]) | + MDP5_PIPE_SRC_STRIDE_A_P1(pitches[1])); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_B(pipe), - MDP5_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | - MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); + MDP5_PIPE_SRC_STRIDE_B_P2(pitches[2]) | + MDP5_PIPE_SRC_STRIDE_B_P3(pitches[3])); + + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), src_addr[0]); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), src_addr[1]); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), src_addr[2]); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), src_addr[3]); +} + +void mdp5_plane_set_scanout(struct drm_plane *plane, + struct drm_framebuffer *fb) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + uint32_t src_addr[MAX_PLANE]; + unsigned long flags; - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), iova[0]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), iova[1]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), iova[2]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), iova[3]); + get_fb_addr(plane, fb, src_addr); + + spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); + set_scanout_locked(plane, fb->pitches, src_addr); + spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); plane->fb = fb; } @@ -163,6 +211,8 @@ int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t nplanes, config = 0; uint32_t phasex_step = 0, phasey_step = 0; uint32_t hdecm = 0, vdecm = 0; + uint32_t src_addr[MAX_PLANE]; + unsigned long flags; int ret; nplanes = drm_format_num_planes(fb->pixel_format); @@ -205,6 +255,12 @@ int mdp5_plane_mode_set(struct drm_plane *plane, /* TODO calc phasey_step, vdecm */ } + ret = get_fb_addr(plane, fb, src_addr); + if (ret) + return ret; + + spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_IMG_SIZE(pipe), MDP5_PIPE_SRC_IMG_SIZE_WIDTH(src_w) | MDP5_PIPE_SRC_IMG_SIZE_HEIGHT(src_h)); @@ -225,8 +281,6 @@ int mdp5_plane_mode_set(struct drm_plane *plane, MDP5_PIPE_OUT_XY_X(crtc_x) | MDP5_PIPE_OUT_XY_Y(crtc_y)); - mdp5_plane_set_scanout(plane, fb); - format = to_mdp_format(msm_framebuffer_format(fb)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe), @@ -266,10 +320,14 @@ int mdp5_plane_mode_set(struct drm_plane *plane, MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) | MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST)); + set_scanout_locked(plane, fb->pitches, src_addr); + + spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); + /* TODO detach from old crtc (if we had more than one) */ - mdp5_crtc_attach(crtc, plane); + ret = mdp5_crtc_attach(crtc, plane); - return 0; + return ret; } void mdp5_plane_complete_flip(struct drm_plane *plane) @@ -286,9 +344,16 @@ enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) return mdp5_plane->pipe; } +uint32_t mdp5_plane_get_flush(struct drm_plane *plane) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + + return mdp5_plane->flush_mask; +} + /* initialize plane */ struct drm_plane *mdp5_plane_init(struct drm_device *dev, - enum mdp5_pipe pipe, bool private_plane) + enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset) { struct drm_plane *plane = NULL; struct mdp5_plane *mdp5_plane; @@ -309,6 +374,10 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, mdp5_plane->nformats = mdp5_get_formats(pipe, mdp5_plane->formats, ARRAY_SIZE(mdp5_plane->formats)); + mdp5_plane->flush_mask = mdp_ctl_flush_mask_pipe(pipe); + mdp5_plane->reg_offset = reg_offset; + spin_lock_init(&mdp5_plane->pipe_lock); + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, mdp5_plane->formats, mdp5_plane->nformats, -- GitLab From 42238da8b10320420be19f056cc8e0d95cc606a3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 18 Nov 2014 14:28:43 -0500 Subject: [PATCH 5667/9457] drm/msm/mdp5: don't use void * for opaque types For example, use 'struct mdp5_smp *' everywhere instead of 'void *', but only declare it as 'struct mdp5_smp;' in common headers, so the struct body is still private. The accomplishes the desired modularity while still letting the compiler provide some type checking for us. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c | 18 +++------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h | 12 +++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 8 ++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 37 +++++++---------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h | 23 ++++++----- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 49 +++++++++++------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 6 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 8 ++-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | 22 ++++------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h | 13 +++--- 10 files changed, 88 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c index 62e77d1d3c59..b0a44310cf2a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c @@ -121,35 +121,27 @@ static const struct mdp5_cfg_handler cfg_handlers[] = { static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev); -const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(void *cfg_hnd) +const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler) { - struct mdp5_cfg_handler *cfg_handler = cfg_hnd; - return cfg_handler->config.hw; } -struct mdp5_cfg *mdp5_cfg_get_config(void *cfg_hnd) +struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler) { - struct mdp5_cfg_handler *cfg_handler = cfg_hnd; - return &cfg_handler->config; } -int mdp5_cfg_get_hw_rev(void *cfg_hnd) +int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler) { - struct mdp5_cfg_handler *cfg_handler = cfg_hnd; - return cfg_handler->revision; } -void mdp5_cfg_destroy(void *cfg_hnd) +void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler) { - struct mdp5_cfg_handler *cfg_handler = cfg_hnd; - kfree(cfg_handler); } -void *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, +struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, uint32_t major, uint32_t minor) { struct drm_device *dev = mdp5_kms->dev; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h index d0c98f9a93e1..dba4d52cceeb 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h @@ -78,12 +78,14 @@ struct mdp5_cfg { }; struct mdp5_kms; +struct mdp5_cfg_handler; -const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(void *cfg_hnd); -struct mdp5_cfg *mdp5_cfg_get_config(void *cfg_hnd); -int mdp5_cfg_get_hw_rev(void *cfg_hnd); +const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_hnd); +struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_hnd); +int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd); -void *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, uint32_t major, uint32_t minor); -void mdp5_cfg_destroy(void *cfg_hnd); +struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, + uint32_t major, uint32_t minor); +void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd); #endif /* __MDP5_CFG_H__ */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 85f2fb460a88..11c38fa86d89 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -37,7 +37,7 @@ struct mdp5_crtc { spinlock_t lm_lock; /* protect REG_MDP5_LM_* registers */ /* CTL used for this CRTC: */ - void *ctl; + struct mdp5_ctl *ctl; /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; @@ -261,7 +261,7 @@ static void blend_setup(struct drm_crtc *crtc) unsigned long flags; #define blender(stage) ((stage) - STAGE_BASE) - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); spin_lock_irqsave(&mdp5_crtc->lm_lock, flags); @@ -327,7 +327,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, /* request a free CTL, if none is already allocated for this CRTC */ if (!mdp5_crtc->ctl) { - mdp5_crtc->ctl = mdp5_ctl_request(mdp5_kms->ctl_priv, crtc); + mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); if (!mdp5_crtc->ctl) return -EBUSY; } @@ -595,7 +595,7 @@ int mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) enum mdp_mixer_stage_id stage = STAGE_BASE; int max_nb_planes; - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); max_nb_planes = hw_cfg->lm.nb_stages; if (count_planes(crtc) >= max_nb_planes) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c index a6155b77cb13..c5347a797ab6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c @@ -50,7 +50,8 @@ struct mdp5_ctl { u32 flush_mask; bool cursor_on; - void *crtc; + + struct drm_crtc *crtc; }; struct mdp5_ctl_manager { @@ -96,9 +97,8 @@ u32 ctl_read(struct mdp5_ctl *ctl, u32 reg) } -int mdp5_ctl_set_intf(void *c, enum mdp5_intf intf) +int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf) { - struct mdp5_ctl *ctl = c; unsigned long flags; static const enum mdp5_intfnum intfnum[] = { INTF0, INTF1, INTF2, INTF3, @@ -113,10 +113,9 @@ int mdp5_ctl_set_intf(void *c, enum mdp5_intf intf) return 0; } -int mdp5_ctl_set_cursor(void *c, bool enable) +int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable) { struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; - struct mdp5_ctl *ctl = c; unsigned long flags; u32 blend_cfg; int lm; @@ -147,9 +146,8 @@ int mdp5_ctl_set_cursor(void *c, bool enable) } -int mdp5_ctl_blend(void *c, u32 lm, u32 blend_cfg) +int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u32 blend_cfg) { - struct mdp5_ctl *ctl = c; unsigned long flags; if (ctl->cursor_on) @@ -164,10 +162,9 @@ int mdp5_ctl_blend(void *c, u32 lm, u32 blend_cfg) return 0; } -int mdp5_ctl_commit(void *c, u32 flush_mask) +int mdp5_ctl_commit(struct mdp5_ctl *ctl, u32 flush_mask) { struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; - struct mdp5_ctl *ctl = c; unsigned long flags; if (flush_mask & MDP5_CTL_FLUSH_CURSOR_DUMMY) { @@ -190,17 +187,14 @@ int mdp5_ctl_commit(void *c, u32 flush_mask) return 0; } -u32 mdp5_ctl_get_flush(void *c) +u32 mdp5_ctl_get_flush(struct mdp5_ctl *ctl) { - struct mdp5_ctl *ctl = c; - return ctl->flush_mask; } -void mdp5_ctl_release(void *c) +void mdp5_ctl_release(struct mdp5_ctl *ctl) { struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; - struct mdp5_ctl *ctl = c; unsigned long flags; if (unlikely(WARN_ON(ctl->id >= MAX_CTL) || !ctl->busy)) { @@ -223,9 +217,9 @@ void mdp5_ctl_release(void *c) * * @return first free CTL */ -void *mdp5_ctl_request(void *ctlm, void *crtc) +struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, + struct drm_crtc *crtc) { - struct mdp5_ctl_manager *ctl_mgr = ctlm; struct mdp5_ctl *ctl = NULL; unsigned long flags; int c; @@ -252,9 +246,8 @@ void *mdp5_ctl_request(void *ctlm, void *crtc) return ctl; } -void mdp5_ctlm_hw_reset(void *ctlm) +void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctl_mgr) { - struct mdp5_ctl_manager *ctl_mgr = ctlm; unsigned long flags; int c; @@ -267,15 +260,13 @@ void mdp5_ctlm_hw_reset(void *ctlm) } } -void mdp5_ctlm_destroy(void *ctlm) +void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctl_mgr) { - struct mdp5_ctl_manager *ctl_mgr = ctlm; - kfree(ctl_mgr); } -void *mdp5_ctlm_init(struct drm_device *dev, void __iomem *mmio_base, - const struct mdp5_cfg_hw *hw_cfg) +struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, + void __iomem *mmio_base, const struct mdp5_cfg_hw *hw_cfg) { struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; const struct mdp5_sub_block *ctl_cfg = &hw_cfg->ctl; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h index dbe1cae71937..1018519b6af2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h @@ -21,30 +21,31 @@ * mdp5_ctlm_init() returns a ctlm (CTL Manager) handler, * which is then used to call the other mdp5_ctlm_*(ctlm, ...) functions. */ -void *mdp5_ctlm_init(struct drm_device *dev, void __iomem *mmio_base, - const struct mdp5_cfg_hw *hw_cfg); -void mdp5_ctlm_hw_reset(void *ctlm); -void mdp5_ctlm_destroy(void *ctlm); +struct mdp5_ctl_manager; +struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, + void __iomem *mmio_base, const struct mdp5_cfg_hw *hw_cfg); +void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctlm); +void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm); /* * CTL prototypes: * mdp5_ctl_request(ctlm, ...) returns a ctl (CTL resource) handler, * which is then used to call the other mdp5_ctl_*(ctl, ...) functions. */ -void *mdp5_ctl_request(void *ctlm, void *crtc); +struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc); -int mdp5_ctl_set_intf(void *ctl, enum mdp5_intf intf); +int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf); -int mdp5_ctl_set_cursor(void *ctl, bool enable); +int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable); /* @blend_cfg: see LM blender config definition below */ -int mdp5_ctl_blend(void *ctl, u32 lm, u32 blend_cfg); +int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u32 blend_cfg); /* @flush_mask: see CTL flush masks definitions below */ -int mdp5_ctl_commit(void *ctl, u32 flush_mask); -u32 mdp5_ctl_get_flush(void *ctl); +int mdp5_ctl_commit(struct mdp5_ctl *ctl, u32 flush_mask); +u32 mdp5_ctl_get_flush(struct mdp5_ctl *ctl); -void mdp5_ctl_release(void *ctl); +void mdp5_ctl_release(struct mdp5_ctl *ctl); /* * blend_cfg (LM blender config): diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index da248c2b4fe8..a11f1b80c488 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -61,7 +61,7 @@ static int mdp5_hw_init(struct msm_kms *kms) mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0); spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags); - mdp5_ctlm_hw_reset(mdp5_kms->ctl_priv); + mdp5_ctlm_hw_reset(mdp5_kms->ctlm); pm_runtime_put_sync(dev->dev); @@ -88,9 +88,6 @@ static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct msm_mmu *mmu = mdp5_kms->mmu; - void *smp = mdp5_kms->smp_priv; - void *cfg = mdp5_kms->cfg_priv; - void *ctl = mdp5_kms->ctl_priv; mdp5_irq_domain_fini(mdp5_kms); @@ -98,12 +95,13 @@ static void mdp5_destroy(struct msm_kms *kms) mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); mmu->funcs->destroy(mmu); } - if (ctl) - mdp5_ctlm_destroy(ctl); - if (smp) - mdp5_smp_destroy(smp); - if (cfg) - mdp5_cfg_destroy(cfg); + + if (mdp5_kms->ctlm) + mdp5_ctlm_destroy(mdp5_kms->ctlm); + if (mdp5_kms->smp) + mdp5_smp_destroy(mdp5_kms->smp); + if (mdp5_kms->cfg) + mdp5_cfg_destroy(mdp5_kms->cfg); kfree(mdp5_kms); } @@ -163,7 +161,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) const struct mdp5_cfg_hw *hw_cfg; int i, ret; - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); /* register our interrupt-controller for hdmi/eDP/dsi/etc * to use for irqs routed through mdp: @@ -282,7 +280,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) struct msm_kms *kms = NULL; struct msm_mmu *mmu; uint32_t major, minor; - void *priv; int i, ret; mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL); @@ -350,30 +347,32 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) clk_set_rate(mdp5_kms->src_clk, 200000000); read_hw_revision(mdp5_kms, &major, &minor); - priv = mdp5_cfg_init(mdp5_kms, major, minor); - if (IS_ERR(priv)) { - ret = PTR_ERR(priv); + + mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor); + if (IS_ERR(mdp5_kms->cfg)) { + ret = PTR_ERR(mdp5_kms->cfg); + mdp5_kms->cfg = NULL; goto fail; } - mdp5_kms->cfg_priv = priv; - config = mdp5_cfg_get_config(mdp5_kms->cfg_priv); + + config = mdp5_cfg_get_config(mdp5_kms->cfg); /* TODO: compute core clock rate at runtime */ clk_set_rate(mdp5_kms->src_clk, config->hw->max_clk); - priv = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp); - if (IS_ERR(priv)) { - ret = PTR_ERR(priv); + mdp5_kms->smp = mdp5_smp_init(mdp5_kms->dev, &config->hw->smp); + if (IS_ERR(mdp5_kms->smp)) { + ret = PTR_ERR(mdp5_kms->smp); + mdp5_kms->smp = NULL; goto fail; } - mdp5_kms->smp_priv = priv; - priv = mdp5_ctlm_init(dev, mdp5_kms->mmio, config->hw); - if (IS_ERR(priv)) { - ret = PTR_ERR(priv); + mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, config->hw); + if (IS_ERR(mdp5_kms->ctlm)) { + ret = PTR_ERR(mdp5_kms->ctlm); + mdp5_kms->ctlm = NULL; goto fail; } - mdp5_kms->ctl_priv = priv; /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 77fd43ea912e..414447c14598 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -31,14 +31,14 @@ struct mdp5_kms { struct drm_device *dev; - void *cfg_priv; + struct mdp5_cfg_handler *cfg; /* mapper-id used to request GEM buffer mapped for scanout: */ int id; struct msm_mmu *mmu; - void *smp_priv; - void *ctl_priv; + struct mdp5_smp *smp; + struct mdp5_ctl_manager *ctlm; /* io/register spaces: */ void __iomem *mmio, *vbif; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 59703faa9d13..49c10a9cd6c6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -77,7 +77,7 @@ static int mdp5_plane_disable(struct drm_plane *plane) if (mdp5_kms) { /* Release the memory we requested earlier from the SMP: */ - mdp5_smp_release(mdp5_kms->smp_priv, pipe); + mdp5_smp_release(mdp5_kms->smp, pipe); } /* TODO detaching now will cause us not to get the last @@ -232,7 +232,7 @@ int mdp5_plane_mode_set(struct drm_plane *plane, crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); /* Request some memory from the SMP: */ - ret = mdp5_smp_request(mdp5_kms->smp_priv, + ret = mdp5_smp_request(mdp5_kms->smp, mdp5_plane->pipe, fb->pixel_format, src_w); if (ret) return ret; @@ -243,7 +243,7 @@ int mdp5_plane_mode_set(struct drm_plane *plane, * would move into atomic->check_plane_state(), while updating the * hw would remain here: */ - mdp5_smp_configure(mdp5_kms->smp_priv, pipe); + mdp5_smp_configure(mdp5_kms->smp, pipe); if (src_w != crtc_w) { config |= MDP5_PIPE_SCALE_CONFIG_SCALEX_EN; @@ -335,7 +335,7 @@ void mdp5_plane_complete_flip(struct drm_plane *plane) struct mdp5_kms *mdp5_kms = get_kms(plane); enum mdp5_pipe pipe = to_mdp5_plane(plane)->pipe; - mdp5_smp_commit(mdp5_kms->smp_priv, pipe); + mdp5_smp_commit(mdp5_kms->smp, pipe); } enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c index 04996cae4585..bf551885e019 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c @@ -114,7 +114,7 @@ static int smp_request_block(struct mdp5_smp *smp, int reserved; unsigned long flags; - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg_priv); + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); reserved = hw_cfg->smp.reserved[cid]; spin_lock_irqsave(&smp->state_lock, flags); @@ -174,12 +174,11 @@ static void set_fifo_thresholds(struct mdp5_smp *smp, * decimated width. Ie. SMP buffering sits downstream of decimation (which * presumably happens during the dma from scanout buffer). */ -int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width) +int mdp5_smp_request(struct mdp5_smp *smp, enum mdp5_pipe pipe, u32 fmt, u32 width) { - struct mdp5_smp *smp = handler; struct mdp5_kms *mdp5_kms = get_kms(smp); struct drm_device *dev = mdp5_kms->dev; - int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg_priv); + int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg); int i, hsub, nplanes, nlines, nblks, ret; nplanes = drm_format_num_planes(fmt); @@ -217,9 +216,8 @@ int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width) } /* Release SMP blocks for all clients of the pipe */ -void mdp5_smp_release(void *handler, enum mdp5_pipe pipe) +void mdp5_smp_release(struct mdp5_smp *smp, enum mdp5_pipe pipe) { - struct mdp5_smp *smp = handler; int i, nblks; for (i = 0, nblks = 0; i < pipe2nclients(pipe); i++) @@ -261,9 +259,8 @@ static void update_smp_state(struct mdp5_smp *smp, } /* step #2: configure hw for union(pending, inuse): */ -void mdp5_smp_configure(void *handler, enum mdp5_pipe pipe) +void mdp5_smp_configure(struct mdp5_smp *smp, enum mdp5_pipe pipe) { - struct mdp5_smp *smp = handler; int cnt = smp->blk_cnt; mdp5_smp_state_t assigned; int i; @@ -278,9 +275,8 @@ void mdp5_smp_configure(void *handler, enum mdp5_pipe pipe) } /* step #3: after vblank, copy pending -> inuse: */ -void mdp5_smp_commit(void *handler, enum mdp5_pipe pipe) +void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe) { - struct mdp5_smp *smp = handler; int cnt = smp->blk_cnt; mdp5_smp_state_t released; int i; @@ -309,14 +305,12 @@ void mdp5_smp_commit(void *handler, enum mdp5_pipe pipe) } } -void mdp5_smp_destroy(void *handler) +void mdp5_smp_destroy(struct mdp5_smp *smp) { - struct mdp5_smp *smp = handler; - kfree(smp); } -void *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg) +struct mdp5_smp *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg) { struct mdp5_smp *smp = NULL; int ret; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h index 3e3c7534ec0f..e47179f63585 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h @@ -27,6 +27,7 @@ struct mdp5_client_smp_state { }; struct mdp5_kms; +struct mdp5_smp; /* * SMP module prototypes: @@ -34,12 +35,12 @@ struct mdp5_kms; * which is then used to call the other mdp5_smp_*(handler, ...) functions. */ -void *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg); -void mdp5_smp_destroy(void *handler); +struct mdp5_smp *mdp5_smp_init(struct drm_device *dev, const struct mdp5_smp_block *cfg); +void mdp5_smp_destroy(struct mdp5_smp *smp); -int mdp5_smp_request(void *handler, enum mdp5_pipe pipe, u32 fmt, u32 width); -void mdp5_smp_configure(void *handler, enum mdp5_pipe pipe); -void mdp5_smp_commit(void *handler, enum mdp5_pipe pipe); -void mdp5_smp_release(void *handler, enum mdp5_pipe pipe); +int mdp5_smp_request(struct mdp5_smp *smp, enum mdp5_pipe pipe, u32 fmt, u32 width); +void mdp5_smp_configure(struct mdp5_smp *smp, enum mdp5_pipe pipe); +void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe); +void mdp5_smp_release(struct mdp5_smp *smp, enum mdp5_pipe pipe); #endif /* __MDP5_SMP_H__ */ -- GitLab From 32c0e3e24c885ffeecb6d3a67ecb607b8fe63129 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 18 Nov 2014 17:22:51 -0500 Subject: [PATCH 5668/9457] drm/msm/mdp5: remove global mdp5_ctl_mgr A bit cleaner.. and won't resulting in an attempt to kfree() a static global in unload path. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | 26 +++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c index c5347a797ab6..dea4505ac963 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c @@ -34,6 +34,8 @@ */ struct mdp5_ctl { + struct mdp5_ctl_manager *ctlm; + u32 id; /* whether this CTL has been allocated or not: */ @@ -66,8 +68,6 @@ struct mdp5_ctl_manager { struct mdp5_ctl ctls[MAX_CTL]; }; -static struct mdp5_ctl_manager mdp5_ctl_mgr; - static inline struct mdp5_kms *get_kms(struct mdp5_ctl_manager *ctl_mgr) { @@ -79,8 +79,7 @@ struct mdp5_kms *get_kms(struct mdp5_ctl_manager *ctl_mgr) static inline void ctl_write(struct mdp5_ctl *ctl, u32 reg, u32 data) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; - struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); + struct mdp5_kms *mdp5_kms = get_kms(ctl->ctlm); (void)ctl->reg_offset; /* TODO use this instead of mdp5_write */ mdp5_write(mdp5_kms, reg, data); @@ -89,8 +88,7 @@ void ctl_write(struct mdp5_ctl *ctl, u32 reg, u32 data) static inline u32 ctl_read(struct mdp5_ctl *ctl, u32 reg) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; - struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr); + struct mdp5_kms *mdp5_kms = get_kms(ctl->ctlm); (void)ctl->reg_offset; /* TODO use this instead of mdp5_write */ return mdp5_read(mdp5_kms, reg); @@ -115,7 +113,7 @@ int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf) int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; unsigned long flags; u32 blend_cfg; int lm; @@ -164,7 +162,7 @@ int mdp5_ctl_blend(struct mdp5_ctl *ctl, u32 lm, u32 blend_cfg) int mdp5_ctl_commit(struct mdp5_ctl *ctl, u32 flush_mask) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; unsigned long flags; if (flush_mask & MDP5_CTL_FLUSH_CURSOR_DUMMY) { @@ -194,7 +192,7 @@ u32 mdp5_ctl_get_flush(struct mdp5_ctl *ctl) void mdp5_ctl_release(struct mdp5_ctl *ctl) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm; unsigned long flags; if (unlikely(WARN_ON(ctl->id >= MAX_CTL) || !ctl->busy)) { @@ -268,11 +266,18 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctl_mgr) struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, void __iomem *mmio_base, const struct mdp5_cfg_hw *hw_cfg) { - struct mdp5_ctl_manager *ctl_mgr = &mdp5_ctl_mgr; + struct mdp5_ctl_manager *ctl_mgr; const struct mdp5_sub_block *ctl_cfg = &hw_cfg->ctl; unsigned long flags; int c, ret; + ctl_mgr = kzalloc(sizeof(*ctl_mgr), GFP_KERNEL); + if (!ctl_mgr) { + dev_err(dev->dev, "failed to allocate CTL manager\n"); + ret = -ENOMEM; + goto fail; + } + if (unlikely(WARN_ON(ctl_cfg->count > MAX_CTL))) { dev_err(dev->dev, "Increase static pool size to at least %d\n", ctl_cfg->count); @@ -296,6 +301,7 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, ret = -EINVAL; goto fail; } + ctl->ctlm = ctl_mgr; ctl->id = c; ctl->mode = MODE_NONE; ctl->reg_offset = ctl_cfg->base[c]; -- GitLab From 3e2f29e4137c78a3bd7e1b85cf287ff375f6367e Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 19 Nov 2014 12:29:33 -0500 Subject: [PATCH 5669/9457] drm/msm: atomic fixes Fixes for a couple little issues found in testing. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_atomic.c | 2 +- drivers/gpu/drm/msm/msm_fb.c | 2 ++ drivers/gpu/drm/msm/msm_kms.h | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 8cf3361daba3..f0de412e13dc 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -117,7 +117,7 @@ int msm_atomic_commit(struct drm_device *dev, if (!plane) continue; - if (plane->state->fb != new_state->fb) + if ((plane->state->fb != new_state->fb) && new_state->fb) add_fb(c, new_state->fb); } diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index f4e42d506ff7..84dec161d836 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -120,6 +120,8 @@ void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id) uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); + if (!msm_fb->planes[plane]) + return 0; return msm_gem_iova(msm_fb->planes[plane], id); } diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 15a0fec99c70..1e9d8c2e6a5d 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -68,6 +68,11 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev); /* TODO move these helper iterator macro somewhere common: */ #define for_each_plane_on_crtc(_crtc, _plane) \ list_for_each_entry((_plane), &(_crtc)->dev->mode_config.plane_list, head) \ - if ((_plane)->crtc == (_crtc)) + if ((_plane)->state->crtc == (_crtc)) + +#define for_each_pending_plane_on_crtc(_state, _crtc, _plane) \ + list_for_each_entry((_plane), &(_crtc)->dev->mode_config.plane_list, head) \ + if (({struct drm_plane_state *_ps = (_state)->plane_states[drm_plane_index(_plane)]; \ + _ps && _ps->crtc == (_crtc);})) #endif /* __MSM_KMS_H__ */ -- GitLab From ed8519636ef6c4b6ffbc4a449ebf39502e80ee74 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 19 Nov 2014 12:31:03 -0500 Subject: [PATCH 5670/9457] drm/msm/mdp5: atomic Convert mdp5 over to atomic helpers. Extend/wrap drm_plane_state to track plane zpos and to keep track of the needed when applying the atomic update. In mdp5's plane->atomic_check() we also need to check for updates which require SMP reallocation, in order to trigger full modeset. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 359 +++++++--------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 40 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 270 ++++++++++------ drivers/gpu/drm/msm/msm_kms.h | 17 +- 4 files changed, 318 insertions(+), 368 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 11c38fa86d89..a6728a80f7e0 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -18,6 +18,7 @@ #include "mdp5_kms.h" +#include #include #include "drm_crtc.h" #include "drm_crtc_helper.h" @@ -41,25 +42,11 @@ struct mdp5_crtc { /* if there is a pending flip, these will be non-null: */ struct drm_pending_vblank_event *event; - struct msm_fence_cb pageflip_cb; #define PENDING_CURSOR 0x1 #define PENDING_FLIP 0x2 atomic_t pending; - /* the fb that we logically (from PoV of KMS API) hold a ref - * to. Which we may not yet be scanning out (we may still - * be scanning out previous in case of page_flip while waiting - * for gpu rendering to complete: - */ - struct drm_framebuffer *fb; - - /* the fb that we currently hold a scanout ref to: */ - struct drm_framebuffer *scanout_fb; - - /* for unref'ing framebuffers after scanout completes: */ - struct drm_flip_work unref_fb_work; - struct mdp_irq vblank; struct mdp_irq err; }; @@ -113,41 +100,6 @@ static void crtc_flush_all(struct drm_crtc *crtc) crtc_flush(crtc, flush_mask); } -static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) -{ - struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - struct drm_framebuffer *old_fb = mdp5_crtc->fb; - - /* grab reference to incoming scanout fb: */ - drm_framebuffer_reference(new_fb); - mdp5_crtc->base.primary->fb = new_fb; - mdp5_crtc->fb = new_fb; - - if (old_fb) - drm_flip_work_queue(&mdp5_crtc->unref_fb_work, old_fb); -} - -/* unlike update_fb(), take a ref to the new scanout fb *before* updating - * plane, then call this. Needed to ensure we don't unref the buffer that - * is actually still being scanned out. - * - * Note that this whole thing goes away with atomic.. since we can defer - * calling into driver until rendering is done. - */ -static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) -{ - struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - - if (mdp5_crtc->scanout_fb) - drm_flip_work_queue(&mdp5_crtc->unref_fb_work, - mdp5_crtc->scanout_fb); - - mdp5_crtc->scanout_fb = fb; - - /* enable vblank to complete flip: */ - request_pending(crtc, PENDING_FLIP); -} - /* if file!=NULL, this is preclose potential cancel-flip path */ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) { @@ -166,6 +118,7 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) */ if (!file || (event->base.file_priv == file)) { mdp5_crtc->event = NULL; + DBG("%s: send event: %p", mdp5_crtc->name, event); drm_send_vblank_event(dev, mdp5_crtc->id, event); } } @@ -175,39 +128,11 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) mdp5_plane_complete_flip(plane); } -static void pageflip_cb(struct msm_fence_cb *cb) -{ - struct mdp5_crtc *mdp5_crtc = - container_of(cb, struct mdp5_crtc, pageflip_cb); - struct drm_crtc *crtc = &mdp5_crtc->base; - struct drm_framebuffer *fb = mdp5_crtc->fb; - - if (!fb) - return; - - drm_framebuffer_reference(fb); - mdp5_plane_set_scanout(crtc->primary, fb); - update_scanout(crtc, fb); - crtc_flush_all(crtc); -} - -static void unref_fb_worker(struct drm_flip_work *work, void *val) -{ - struct mdp5_crtc *mdp5_crtc = - container_of(work, struct mdp5_crtc, unref_fb_work); - struct drm_device *dev = mdp5_crtc->base.dev; - - mutex_lock(&dev->mode_config.mutex); - drm_framebuffer_unreference(val); - mutex_unlock(&dev->mode_config.mutex); -} - static void mdp5_crtc_destroy(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); drm_crtc_cleanup(crtc); - drm_flip_work_cleanup(&mdp5_crtc->unref_fb_work); kfree(mdp5_crtc); } @@ -257,7 +182,6 @@ static void blend_setup(struct drm_crtc *crtc) struct drm_plane *plane; const struct mdp5_cfg_hw *hw_cfg; uint32_t lm = mdp5_crtc->lm, blend_cfg = 0; - enum mdp_mixer_stage_id stage; unsigned long flags; #define blender(stage) ((stage) - STAGE_BASE) @@ -270,10 +194,8 @@ static void blend_setup(struct drm_crtc *crtc) goto out; for_each_plane_on_crtc(crtc, plane) { - struct mdp5_overlay_info *overlay; - - overlay = mdp5_plane_get_overlay_info(plane); - stage = overlay->zorder; + enum mdp_mixer_stage_id stage = + to_mdp5_plane_state(plane->state)->stage; /* * Note: This cannot happen with current implementation but @@ -303,18 +225,17 @@ static void blend_setup(struct drm_crtc *crtc) spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); } -static int mdp5_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) +static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_kms *mdp5_kms = get_kms(crtc); unsigned long flags; - int ret; + struct drm_display_mode *mode; + + if (WARN_ON(!crtc->state)) + return; - mode = adjusted_mode; + mode = &crtc->state->adjusted_mode; DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", mdp5_crtc->name, mode->base.id, mode->name, @@ -325,38 +246,11 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, mode->vsync_end, mode->vtotal, mode->type, mode->flags); - /* request a free CTL, if none is already allocated for this CRTC */ - if (!mdp5_crtc->ctl) { - mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); - if (!mdp5_crtc->ctl) - return -EBUSY; - } - - /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->primary->fb); - - ret = mdp5_plane_mode_set(crtc->primary, crtc, crtc->primary->fb, - 0, 0, mode->hdisplay, mode->vdisplay, - x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16); - if (ret) { - drm_framebuffer_unreference(crtc->primary->fb); - dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", - mdp5_crtc->name, ret); - return ret; - } - spin_lock_irqsave(&mdp5_crtc->lm_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(mdp5_crtc->lm), MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) | MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay)); spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); - - update_fb(crtc, crtc->primary->fb); - update_scanout(crtc, crtc->primary->fb); - /* crtc_flush_all(crtc) will be called in _commit callback */ - - return 0; } static void mdp5_crtc_prepare(struct drm_crtc *crtc) @@ -370,79 +264,119 @@ static void mdp5_crtc_prepare(struct drm_crtc *crtc) static void mdp5_crtc_commit(struct drm_crtc *crtc) { + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + DBG("%s", mdp5_crtc->name); mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_ON); crtc_flush_all(crtc); /* drop the ref to mdp clk's that we got in prepare: */ mdp5_disable(get_kms(crtc)); } -static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) +static void mdp5_crtc_load_lut(struct drm_crtc *crtc) { - struct drm_plane *plane = crtc->primary; - struct drm_display_mode *mode = &crtc->mode; - int ret; - - /* grab extra ref for update_scanout() */ - drm_framebuffer_reference(crtc->primary->fb); - - ret = mdp5_plane_mode_set(plane, crtc, crtc->primary->fb, - 0, 0, mode->hdisplay, mode->vdisplay, - x << 16, y << 16, - mode->hdisplay << 16, mode->vdisplay << 16); - if (ret) { - drm_framebuffer_unreference(crtc->primary->fb); - return ret; - } - - update_fb(crtc, crtc->primary->fb); - update_scanout(crtc, crtc->primary->fb); - crtc_flush_all(crtc); - - return 0; } -static void mdp5_crtc_load_lut(struct drm_crtc *crtc) +struct plane_state { + struct drm_plane *plane; + struct mdp5_plane_state *state; +}; + +static int pstate_cmp(const void *a, const void *b) { + struct plane_state *pa = (struct plane_state *)a; + struct plane_state *pb = (struct plane_state *)b; + return pa->state->zpos - pb->state->zpos; } -static void mdp5_crtc_disable(struct drm_crtc *crtc) +static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct drm_plane *plane; + struct drm_device *dev = crtc->dev; + struct plane_state pstates[STAGE3 + 1]; + int cnt = 0, i; - DBG("%s", mdp5_crtc->name); + DBG("%s: check", mdp5_crtc->name); - if (mdp5_crtc->ctl) { - mdp5_ctl_release(mdp5_crtc->ctl); - mdp5_crtc->ctl = NULL; + if (mdp5_crtc->event) { + dev_err(dev->dev, "already pending flip!\n"); + return -EBUSY; + } + + /* request a free CTL, if none is already allocated for this CRTC */ + if (state->enable && !mdp5_crtc->ctl) { + mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); + if (WARN_ON(!mdp5_crtc->ctl)) + return -EINVAL; } + + /* verify that there are not too many planes attached to crtc + * and that we don't have conflicting mixer stages: + */ + for_each_pending_plane_on_crtc(state->state, crtc, plane) { + struct drm_plane_state *pstate; + + if (cnt >= ARRAY_SIZE(pstates)) { + dev_err(dev->dev, "too many planes!\n"); + return -EINVAL; + } + + pstate = state->state->plane_states[drm_plane_index(plane)]; + + /* plane might not have changed, in which case take + * current state: + */ + if (!pstate) + pstate = plane->state; + + pstates[cnt].plane = plane; + pstates[cnt].state = to_mdp5_plane_state(pstate); + + cnt++; + } + + sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); + + for (i = 0; i < cnt; i++) { + pstates[i].state->stage = STAGE_BASE + i; + DBG("%s: assign pipe %s on stage=%d", mdp5_crtc->name, + pipe2name(mdp5_plane_pipe(pstates[i].plane)), + pstates[i].state->stage); + } + + return 0; } +static void mdp5_crtc_atomic_begin(struct drm_crtc *crtc) +{ + struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); + DBG("%s: begin", mdp5_crtc->name); +} -static int mdp5_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *new_fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags) +static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_gem_object *obj; unsigned long flags; - if (mdp5_crtc->event) { - dev_err(dev->dev, "already pending flip!\n"); - return -EBUSY; - } + DBG("%s: flush", mdp5_crtc->name); - obj = msm_framebuffer_bo(new_fb, 0); + WARN_ON(mdp5_crtc->event); spin_lock_irqsave(&dev->event_lock, flags); - mdp5_crtc->event = event; + mdp5_crtc->event = crtc->state->event; spin_unlock_irqrestore(&dev->event_lock, flags); - update_fb(crtc, new_fb); + blend_setup(crtc); + crtc_flush_all(crtc); + request_pending(crtc, PENDING_FLIP); - return msm_gem_queue_inactive_cb(obj, &mdp5_crtc->pageflip_cb); + if (mdp5_crtc->ctl && !crtc->state->enable) { + mdp5_ctl_release(mdp5_crtc->ctl); + mdp5_crtc->ctl = NULL; + } } static int mdp5_crtc_set_property(struct drm_crtc *crtc, @@ -453,28 +387,33 @@ static int mdp5_crtc_set_property(struct drm_crtc *crtc, } static const struct drm_crtc_funcs mdp5_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = mdp5_crtc_destroy, - .page_flip = mdp5_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, .set_property = mdp5_crtc_set_property, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { .dpms = mdp5_crtc_dpms, .mode_fixup = mdp5_crtc_mode_fixup, - .mode_set = mdp5_crtc_mode_set, + .mode_set_nofb = mdp5_crtc_mode_set_nofb, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_base = drm_helper_crtc_mode_set_base, .prepare = mdp5_crtc_prepare, .commit = mdp5_crtc_commit, - .mode_set_base = mdp5_crtc_mode_set_base, .load_lut = mdp5_crtc_load_lut, - .disable = mdp5_crtc_disable, + .atomic_check = mdp5_crtc_atomic_check, + .atomic_begin = mdp5_crtc_atomic_begin, + .atomic_flush = mdp5_crtc_atomic_flush, }; static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) { struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank); struct drm_crtc *crtc = &mdp5_crtc->base; - struct msm_drm_private *priv = crtc->dev->dev_private; unsigned pending; mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank); @@ -483,7 +422,6 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) if (pending & PENDING_FLIP) { complete_flip(crtc, NULL); - drm_flip_work_commit(&mdp5_crtc->unref_fb_work, priv->wq); } } @@ -560,92 +498,6 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, crtc_flush(crtc, flush_mask); } -static int count_planes(struct drm_crtc *crtc) -{ - struct drm_plane *plane; - int cnt = 0; - for_each_plane_on_crtc(crtc, plane) - cnt++; - return cnt; -} - -static void set_attach(struct drm_crtc *crtc, enum mdp5_pipe pipe_id, - struct drm_plane *plane) -{ - struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - - if (plane) - plane->crtc = crtc; - - DBG("%s: %d planes attached", mdp5_crtc->name, count_planes(crtc)); - - blend_setup(crtc); - if (mdp5_crtc->enabled) - crtc_flush_all(crtc); -} - -int mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane) -{ - struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); - struct mdp5_kms *mdp5_kms = get_kms(crtc); - struct device *dev = crtc->dev->dev; - const struct mdp5_cfg_hw *hw_cfg; - bool private_plane = (plane == crtc->primary); - struct mdp5_overlay_info overlay_info; - enum mdp_mixer_stage_id stage = STAGE_BASE; - int max_nb_planes; - - hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); - max_nb_planes = hw_cfg->lm.nb_stages; - - if (count_planes(crtc) >= max_nb_planes) { - dev_err(dev, "%s: max # of planes (%d) reached\n", - mdp5_crtc->name, max_nb_planes); - return -EBUSY; - } - - /* - * Set default z-ordering depending on the type of plane - * private -> lower stage - * public -> topmost stage - * - * TODO: add a property to give userspace an API to change this... - * (will come in a subsequent patch) - */ - if (private_plane) { - stage = STAGE_BASE; - } else { - struct drm_plane *attached_plane; - for_each_plane_on_crtc(crtc, attached_plane) { - struct mdp5_overlay_info *overlay; - - if (!attached_plane) - continue; - overlay = mdp5_plane_get_overlay_info(attached_plane); - stage = max(stage, overlay->zorder); - } - stage++; - } - overlay_info.zorder = stage; - mdp5_plane_set_overlay_info(plane, &overlay_info); - - DBG("%s: %s plane %s set to stage %d by default", mdp5_crtc->name, - private_plane ? "private" : "public", - pipe2name(mdp5_plane_pipe(plane)), overlay_info.zorder); - - set_attach(crtc, mdp5_plane_pipe(plane), plane); - - return 0; -} - -void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane) -{ - /* don't actually detatch our primary plane: */ - if (crtc->primary == plane) - return; - set_attach(crtc, mdp5_plane_pipe(plane), NULL); -} - int mdp5_crtc_get_lm(struct drm_crtc *crtc) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); @@ -680,11 +532,6 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, snprintf(mdp5_crtc->name, sizeof(mdp5_crtc->name), "%s:%d", pipe2name(mdp5_plane_pipe(plane)), id); - drm_flip_work_init(&mdp5_crtc->unref_fb_work, - "unref fb", unref_fb_worker); - - INIT_FENCE_CB(&mdp5_crtc->pageflip_cb, pageflip_cb); - drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); plane->crtc = crtc; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 414447c14598..dd69c77c0d64 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -67,9 +67,32 @@ struct mdp5_kms { }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) -struct mdp5_overlay_info { - enum mdp_mixer_stage_id zorder; +struct mdp5_plane_state { + struct drm_plane_state base; + + /* "virtual" zpos.. we calculate actual mixer-stage at runtime + * by sorting the attached planes by zpos and then assigning + * mixer stage lowest to highest. Private planes get default + * zpos of zero, and public planes a unique value that is + * greater than zero. This way, things work out if a naive + * userspace assigns planes to a crtc without setting zpos. + */ + int zpos; + + /* the actual mixer stage, calculated in crtc->atomic_check() + * NOTE: this should move to mdp5_crtc_state, when that exists + */ + enum mdp_mixer_stage_id stage; + + /* some additional transactional status to help us know in the + * apply path whether we need to update SMP allocation, and + * whether current update is still pending: + */ + bool mode_changed : 1; + bool pending : 1; }; +#define to_mdp5_plane_state(x) \ + container_of(x, struct mdp5_plane_state, base) static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) { @@ -154,18 +177,7 @@ uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj); -void mdp5_plane_set_overlay_info(struct drm_plane *plane, - const struct mdp5_overlay_info *overlay_info); -struct mdp5_overlay_info *mdp5_plane_get_overlay_info(struct drm_plane *plane); uint32_t mdp5_plane_get_flush(struct drm_plane *plane); -void mdp5_plane_set_scanout(struct drm_plane *plane, - struct drm_framebuffer *fb); -int mdp5_plane_mode_set(struct drm_plane *plane, - struct drm_crtc *crtc, struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h); void mdp5_plane_complete_flip(struct drm_plane *plane); enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); struct drm_plane *mdp5_plane_init(struct drm_device *dev, @@ -177,8 +189,6 @@ int mdp5_crtc_get_lm(struct drm_crtc *crtc); void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, enum mdp5_intf intf_id); -int mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); -void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, struct drm_plane *plane, int id); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 49c10a9cd6c6..533df7caa310 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -31,8 +31,6 @@ struct mdp5_plane { uint32_t flush_mask; /* used to commit pipe registers */ - struct mdp5_overlay_info overlay_info; - uint32_t nformats; uint32_t formats[32]; @@ -40,31 +38,24 @@ struct mdp5_plane { }; #define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base) +static int mdp5_plane_mode_set(struct drm_plane *plane, + struct drm_crtc *crtc, struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); +static void set_scanout_locked(struct drm_plane *plane, + struct drm_framebuffer *fb); + static struct mdp5_kms *get_kms(struct drm_plane *plane) { struct msm_drm_private *priv = plane->dev->dev_private; return to_mdp5_kms(to_mdp_kms(priv->kms)); } -static int mdp5_plane_update(struct drm_plane *plane, - struct drm_crtc *crtc, struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +static bool plane_enabled(struct drm_plane_state *state) { - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - - mdp5_plane->enabled = true; - - if (plane->fb) - drm_framebuffer_unreference(plane->fb); - - drm_framebuffer_reference(fb); - - return mdp5_plane_mode_set(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h); + return state->fb && state->crtc; } static int mdp5_plane_disable(struct drm_plane *plane) @@ -80,46 +71,19 @@ static int mdp5_plane_disable(struct drm_plane *plane) mdp5_smp_release(mdp5_kms->smp, pipe); } - /* TODO detaching now will cause us not to get the last - * vblank and mdp5_smp_commit().. so other planes will - * still see smp blocks previously allocated to us as - * in-use.. - */ - if (plane->crtc) - mdp5_crtc_detach(plane->crtc, plane); - return 0; } static void mdp5_plane_destroy(struct drm_plane *plane) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - struct msm_drm_private *priv = plane->dev->dev_private; - - if (priv->kms) - mdp5_plane_disable(plane); + drm_plane_helper_disable(plane); drm_plane_cleanup(plane); kfree(mdp5_plane); } -void mdp5_plane_set_overlay_info(struct drm_plane *plane, - const struct mdp5_overlay_info *overlay_info) -{ - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - - memcpy(&mdp5_plane->overlay_info, overlay_info, sizeof(*overlay_info)); -} - -struct mdp5_overlay_info *mdp5_plane_get_overlay_info( - struct drm_plane *plane) -{ - struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - - return &mdp5_plane->overlay_info; -} - /* helper to install properties which are common to planes and crtcs */ void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) @@ -134,70 +98,185 @@ int mdp5_plane_set_property(struct drm_plane *plane, return -EINVAL; } +static void mdp5_plane_reset(struct drm_plane *plane) +{ + struct mdp5_plane_state *mdp5_state; + + if (plane->state && plane->state->fb) + drm_framebuffer_unreference(plane->state->fb); + + kfree(to_mdp5_plane_state(plane->state)); + mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + + if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + mdp5_state->zpos = 0; + } else { + mdp5_state->zpos = 1 + drm_plane_index(plane); + } + + plane->state = &mdp5_state->base; +} + +static struct drm_plane_state * +mdp5_plane_duplicate_state(struct drm_plane *plane) +{ + struct mdp5_plane_state *mdp5_state; + + if (WARN_ON(!plane->state)) + return NULL; + + mdp5_state = kmemdup(to_mdp5_plane_state(plane->state), + sizeof(*mdp5_state), GFP_KERNEL); + + if (mdp5_state && mdp5_state->base.fb) + drm_framebuffer_reference(mdp5_state->base.fb); + + mdp5_state->mode_changed = false; + mdp5_state->pending = false; + + return &mdp5_state->base; +} + +static void mdp5_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + if (state->fb) + drm_framebuffer_unreference(state->fb); + + kfree(to_mdp5_plane_state(state)); +} + static const struct drm_plane_funcs mdp5_plane_funcs = { - .update_plane = mdp5_plane_update, - .disable_plane = mdp5_plane_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy = mdp5_plane_destroy, .set_property = mdp5_plane_set_property, + .reset = mdp5_plane_reset, + .atomic_duplicate_state = mdp5_plane_duplicate_state, + .atomic_destroy_state = mdp5_plane_destroy_state, }; -static int get_fb_addr(struct drm_plane *plane, struct drm_framebuffer *fb, - uint32_t iova[MAX_PLANE]) +static int mdp5_plane_prepare_fb(struct drm_plane *plane, + struct drm_framebuffer *fb) { + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); - uint32_t nplanes = drm_format_num_planes(fb->pixel_format); - int i; - for (i = 0; i < nplanes; i++) { - struct drm_gem_object *bo = msm_framebuffer_bo(fb, i); - msm_gem_get_iova(bo, mdp5_kms->id, &iova[i]); - } - for (; i < MAX_PLANE; i++) - iova[i] = 0; - - return 0; + DBG("%s: prepare: FB[%u]", mdp5_plane->name, fb->base.id); + return msm_framebuffer_prepare(fb, mdp5_kms->id); } -static void set_scanout_locked(struct drm_plane *plane, - uint32_t pitches[MAX_PLANE], uint32_t src_addr[MAX_PLANE]) +static void mdp5_plane_cleanup_fb(struct drm_plane *plane, + struct drm_framebuffer *fb) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct mdp5_kms *mdp5_kms = get_kms(plane); - enum mdp5_pipe pipe = mdp5_plane->pipe; - WARN_ON(!spin_is_locked(&mdp5_plane->pipe_lock)); + DBG("%s: cleanup: FB[%u]", mdp5_plane->name, fb->base.id); + msm_framebuffer_cleanup(fb, mdp5_kms->id); +} - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe), - MDP5_PIPE_SRC_STRIDE_A_P0(pitches[0]) | - MDP5_PIPE_SRC_STRIDE_A_P1(pitches[1])); +static int mdp5_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + struct drm_plane_state *old_state = plane->state; + + DBG("%s: check (%d -> %d)", mdp5_plane->name, + plane_enabled(old_state), plane_enabled(state)); + + if (plane_enabled(state) && plane_enabled(old_state)) { + /* we cannot change SMP block configuration during scanout: */ + bool full_modeset = false; + if (state->fb->pixel_format != old_state->fb->pixel_format) { + DBG("%s: pixel_format change!", mdp5_plane->name); + full_modeset = true; + } + if (state->src_w != old_state->src_w) { + DBG("%s: src_w change!", mdp5_plane->name); + full_modeset = true; + } + if (to_mdp5_plane_state(old_state)->pending) { + DBG("%s: still pending!", mdp5_plane->name); + full_modeset = true; + } + if (full_modeset) { + struct drm_crtc_state *crtc_state = + drm_atomic_get_crtc_state(state->state, state->crtc); + crtc_state->mode_changed = true; + to_mdp5_plane_state(state)->mode_changed = true; + } + } else { + to_mdp5_plane_state(state)->mode_changed = true; + } - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_B(pipe), - MDP5_PIPE_SRC_STRIDE_B_P2(pitches[2]) | - MDP5_PIPE_SRC_STRIDE_B_P3(pitches[3])); + return 0; +} + +static void mdp5_plane_atomic_update(struct drm_plane *plane) +{ + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + struct drm_plane_state *state = plane->state; + + DBG("%s: update", mdp5_plane->name); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), src_addr[0]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), src_addr[1]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), src_addr[2]); - mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), src_addr[3]); + if (!plane_enabled(state)) { + to_mdp5_plane_state(state)->pending = true; + mdp5_plane_disable(plane); + } else if (to_mdp5_plane_state(state)->mode_changed) { + int ret; + to_mdp5_plane_state(state)->pending = true; + ret = mdp5_plane_mode_set(plane, + state->crtc, state->fb, + state->crtc_x, state->crtc_y, + state->crtc_w, state->crtc_h, + state->src_x, state->src_y, + state->src_w, state->src_h); + /* atomic_check should have ensured that this doesn't fail */ + WARN_ON(ret < 0); + } else { + unsigned long flags; + spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); + set_scanout_locked(plane, state->fb); + spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); + } } -void mdp5_plane_set_scanout(struct drm_plane *plane, +static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { + .prepare_fb = mdp5_plane_prepare_fb, + .cleanup_fb = mdp5_plane_cleanup_fb, + .atomic_check = mdp5_plane_atomic_check, + .atomic_update = mdp5_plane_atomic_update, +}; + +static void set_scanout_locked(struct drm_plane *plane, struct drm_framebuffer *fb) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); - uint32_t src_addr[MAX_PLANE]; - unsigned long flags; + struct mdp5_kms *mdp5_kms = get_kms(plane); + enum mdp5_pipe pipe = mdp5_plane->pipe; - get_fb_addr(plane, fb, src_addr); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe), + MDP5_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | + MDP5_PIPE_SRC_STRIDE_A_P1(fb->pitches[1])); - spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); - set_scanout_locked(plane, fb->pitches, src_addr); - spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_B(pipe), + MDP5_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | + MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); + + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), + msm_framebuffer_iova(fb, mdp5_kms->id, 0)); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), + msm_framebuffer_iova(fb, mdp5_kms->id, 1)); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), + msm_framebuffer_iova(fb, mdp5_kms->id, 2)); + mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), + msm_framebuffer_iova(fb, mdp5_kms->id, 4)); plane->fb = fb; } -int mdp5_plane_mode_set(struct drm_plane *plane, +static int mdp5_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -211,7 +290,6 @@ int mdp5_plane_mode_set(struct drm_plane *plane, uint32_t nplanes, config = 0; uint32_t phasex_step = 0, phasey_step = 0; uint32_t hdecm = 0, vdecm = 0; - uint32_t src_addr[MAX_PLANE]; unsigned long flags; int ret; @@ -255,10 +333,6 @@ int mdp5_plane_mode_set(struct drm_plane *plane, /* TODO calc phasey_step, vdecm */ } - ret = get_fb_addr(plane, fb, src_addr); - if (ret) - return ret; - spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_IMG_SIZE(pipe), @@ -320,22 +394,24 @@ int mdp5_plane_mode_set(struct drm_plane *plane, MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) | MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST)); - set_scanout_locked(plane, fb->pitches, src_addr); + set_scanout_locked(plane, fb); spin_unlock_irqrestore(&mdp5_plane->pipe_lock, flags); - /* TODO detach from old crtc (if we had more than one) */ - ret = mdp5_crtc_attach(crtc, plane); - return ret; } void mdp5_plane_complete_flip(struct drm_plane *plane) { struct mdp5_kms *mdp5_kms = get_kms(plane); - enum mdp5_pipe pipe = to_mdp5_plane(plane)->pipe; + struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); + enum mdp5_pipe pipe = mdp5_plane->pipe; + + DBG("%s: complete flip", mdp5_plane->name); mdp5_smp_commit(mdp5_kms->smp, pipe); + + to_mdp5_plane_state(plane->state)->pending = false; } enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) @@ -379,9 +455,13 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, spin_lock_init(&mdp5_plane->pipe_lock); type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, + ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, mdp5_plane->formats, mdp5_plane->nformats, type); + if (ret) + goto fail; + + drm_plane_helper_add(plane, &mdp5_plane_helper_funcs); mdp5_plane_install_properties(plane, &plane->base); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 1e9d8c2e6a5d..7fb4876388e7 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -70,9 +70,22 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev); list_for_each_entry((_plane), &(_crtc)->dev->mode_config.plane_list, head) \ if ((_plane)->state->crtc == (_crtc)) +static inline bool +__plane_will_be_attached_to_crtc(struct drm_atomic_state *state, + struct drm_plane *plane, struct drm_crtc *crtc) +{ + int idx = drm_plane_index(plane); + + /* if plane is modified in incoming state, use the new state: */ + if (state->plane_states[idx]) + return state->plane_states[idx]->crtc == crtc; + + /* otherwise, current state: */ + return plane->state->crtc == crtc; +} + #define for_each_pending_plane_on_crtc(_state, _crtc, _plane) \ list_for_each_entry((_plane), &(_crtc)->dev->mode_config.plane_list, head) \ - if (({struct drm_plane_state *_ps = (_state)->plane_states[drm_plane_index(_plane)]; \ - _ps && _ps->crtc == (_crtc);})) + if (__plane_will_be_attached_to_crtc((_state), (_plane), (_crtc))) #endif /* __MSM_KMS_H__ */ -- GitLab From d6ac4a84e7a3713929ec473cb8c10acc1dec41a2 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 20 Nov 2014 17:05:04 -0500 Subject: [PATCH 5671/9457] drm/msm/mdp5: dpms(OFF) cleanups When disabling the interface (INTF), the change doesn't latch until next vblank, so we need to wait for vblank. Also, to be pedantic, in the crtc, set all the mixer stages to unused. It shouldn't really matter, since at this point we have already disabled the INTF and waited for necessary vblank. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 2 ++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index a6728a80f7e0..0598bdea4ff4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -150,6 +150,8 @@ static void mdp5_crtc_dpms(struct drm_crtc *crtc, int mode) mdp5_enable(mdp5_kms); mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); } else { + /* set STAGE_UNUSED for all layers */ + mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, 0x00000000); mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err); mdp5_disable(mdp5_kms); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index 25c2fcb39ac3..0254bfdeb92f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -132,6 +132,17 @@ static void mdp5_encoder_dpms(struct drm_encoder *encoder, int mode) spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0); spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); + + /* + * Wait for a vsync so we know the ENABLE=0 latched before + * the (connector) source of the vsync's gets disabled, + * otherwise we end up in a funny state if we re-enable + * before the disable latches, which results that some of + * the settings changes for the new modeset (like new + * scanout buffer) don't latch properly.. + */ + mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf)); + bs_set(mdp5_encoder, 0); } -- GitLab From 13ebb68cb5a227abe2437094f99a699736e39e0a Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 20 Nov 2014 22:53:25 +0100 Subject: [PATCH 5672/9457] phy: add the Berlin USB PHY driver Add the driver driving the Marvell Berlin USB PHY. This allows to initialize the PHY and to use it from the USB driver later. Signed-off-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/Kconfig | 7 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-berlin-usb.c | 224 +++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 drivers/phy/phy-berlin-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index cfaced92e0c8..4144d250524f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -15,6 +15,13 @@ config GENERIC_PHY phy users can obtain reference to the PHY. All the users of this framework should select this config. +config PHY_BERLIN_USB + tristate "Marvell Berlin USB PHY Driver" + depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF + select GENERIC_PHY + help + Enable this to support the USB PHY on Marvell Berlin SoCs. + config PHY_BERLIN_SATA tristate "Marvell Berlin SATA PHY driver" depends on ARCH_BERLIN && HAS_IOMEM && OF diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 30d90a8d72e8..68022f698f51 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_GENERIC_PHY) += phy-core.o +obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c new file mode 100644 index 000000000000..f9f13067f50f --- /dev/null +++ b/drivers/phy/phy-berlin-usb.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * Jisheng Zhang + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB_PHY_PLL 0x04 +#define USB_PHY_PLL_CONTROL 0x08 +#define USB_PHY_TX_CTRL0 0x10 +#define USB_PHY_TX_CTRL1 0x14 +#define USB_PHY_TX_CTRL2 0x18 +#define USB_PHY_RX_CTRL 0x20 +#define USB_PHY_ANALOG 0x34 + +/* USB_PHY_PLL */ +#define CLK_REF_DIV(x) ((x) << 4) +#define FEEDBACK_CLK_DIV(x) ((x) << 8) + +/* USB_PHY_PLL_CONTROL */ +#define CLK_STABLE BIT(0) +#define PLL_CTRL_PIN BIT(1) +#define PLL_CTRL_REG BIT(2) +#define PLL_ON BIT(3) +#define PHASE_OFF_TOL_125 (0x0 << 5) +#define PHASE_OFF_TOL_250 BIT(5) +#define KVC0_CALIB (0x0 << 9) +#define KVC0_REG_CTRL BIT(9) +#define KVC0_HIGH (0x0 << 10) +#define KVC0_LOW (0x3 << 10) +#define CLK_BLK_EN BIT(13) + +/* USB_PHY_TX_CTRL0 */ +#define EXT_HS_RCAL_EN BIT(3) +#define EXT_FS_RCAL_EN BIT(4) +#define IMPCAL_VTH_DIV(x) ((x) << 5) +#define EXT_RS_RCAL_DIV(x) ((x) << 8) +#define EXT_FS_RCAL_DIV(x) ((x) << 12) + +/* USB_PHY_TX_CTRL1 */ +#define TX_VDD15_14 (0x0 << 4) +#define TX_VDD15_15 BIT(4) +#define TX_VDD15_16 (0x2 << 4) +#define TX_VDD15_17 (0x3 << 4) +#define TX_VDD12_VDD (0x0 << 6) +#define TX_VDD12_11 BIT(6) +#define TX_VDD12_12 (0x2 << 6) +#define TX_VDD12_13 (0x3 << 6) +#define LOW_VDD_EN BIT(8) +#define TX_OUT_AMP(x) ((x) << 9) + +/* USB_PHY_TX_CTRL2 */ +#define TX_CHAN_CTRL_REG(x) ((x) << 0) +#define DRV_SLEWRATE(x) ((x) << 4) +#define IMP_CAL_FS_HS_DLY_0 (0x0 << 6) +#define IMP_CAL_FS_HS_DLY_1 BIT(6) +#define IMP_CAL_FS_HS_DLY_2 (0x2 << 6) +#define IMP_CAL_FS_HS_DLY_3 (0x3 << 6) +#define FS_DRV_EN_MASK(x) ((x) << 8) +#define HS_DRV_EN_MASK(x) ((x) << 12) + +/* USB_PHY_RX_CTRL */ +#define PHASE_FREEZE_DLY_2_CL (0x0 << 0) +#define PHASE_FREEZE_DLY_4_CL BIT(0) +#define ACK_LENGTH_8_CL (0x0 << 2) +#define ACK_LENGTH_12_CL BIT(2) +#define ACK_LENGTH_16_CL (0x2 << 2) +#define ACK_LENGTH_20_CL (0x3 << 2) +#define SQ_LENGTH_3 (0x0 << 4) +#define SQ_LENGTH_6 BIT(4) +#define SQ_LENGTH_9 (0x2 << 4) +#define SQ_LENGTH_12 (0x3 << 4) +#define DISCON_THRESHOLD_260 (0x0 << 6) +#define DISCON_THRESHOLD_270 BIT(6) +#define DISCON_THRESHOLD_280 (0x2 << 6) +#define DISCON_THRESHOLD_290 (0x3 << 6) +#define SQ_THRESHOLD(x) ((x) << 8) +#define LPF_COEF(x) ((x) << 12) +#define INTPL_CUR_10 (0x0 << 14) +#define INTPL_CUR_20 BIT(14) +#define INTPL_CUR_30 (0x2 << 14) +#define INTPL_CUR_40 (0x3 << 14) + +/* USB_PHY_ANALOG */ +#define ANA_PWR_UP BIT(1) +#define ANA_PWR_DOWN BIT(2) +#define V2I_VCO_RATIO(x) ((x) << 7) +#define R_ROTATE_90 (0x0 << 10) +#define R_ROTATE_0 BIT(10) +#define MODE_TEST_EN BIT(11) +#define ANA_TEST_DC_CTRL(x) ((x) << 12) + +#define to_phy_berlin_usb_priv(p) \ + container_of((p), struct phy_berlin_usb_priv, phy) + +static const u32 phy_berlin_pll_dividers[] = { + /* Berlin 2 */ + CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54), + /* Berlin 2CD */ + CLK_REF_DIV(0x6) | FEEDBACK_CLK_DIV(0x55), +}; + +struct phy_berlin_usb_priv { + void __iomem *base; + struct phy *phy; + struct reset_control *rst_ctrl; + u32 pll_divider; +}; + +static int phy_berlin_usb_power_on(struct phy *phy) +{ + struct phy_berlin_usb_priv *priv = dev_get_drvdata(phy->dev.parent); + + reset_control_reset(priv->rst_ctrl); + + writel(priv->pll_divider, + priv->base + USB_PHY_PLL); + writel(CLK_STABLE | PLL_CTRL_REG | PHASE_OFF_TOL_250 | KVC0_REG_CTRL | + CLK_BLK_EN, priv->base + USB_PHY_PLL_CONTROL); + writel(V2I_VCO_RATIO(0x5) | R_ROTATE_0 | ANA_TEST_DC_CTRL(0x5), + priv->base + USB_PHY_ANALOG); + writel(PHASE_FREEZE_DLY_4_CL | ACK_LENGTH_16_CL | SQ_LENGTH_12 | + DISCON_THRESHOLD_260 | SQ_THRESHOLD(0xa) | LPF_COEF(0x2) | + INTPL_CUR_30, priv->base + USB_PHY_RX_CTRL); + + writel(TX_VDD12_13 | TX_OUT_AMP(0x3), priv->base + USB_PHY_TX_CTRL1); + writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4), + priv->base + USB_PHY_TX_CTRL0); + + writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4) | + EXT_FS_RCAL_DIV(0x2), priv->base + USB_PHY_TX_CTRL0); + + writel(EXT_HS_RCAL_EN | IMPCAL_VTH_DIV(0x3) | EXT_RS_RCAL_DIV(0x4), + priv->base + USB_PHY_TX_CTRL0); + writel(TX_CHAN_CTRL_REG(0xf) | DRV_SLEWRATE(0x3) | IMP_CAL_FS_HS_DLY_3 | + FS_DRV_EN_MASK(0xd), priv->base + USB_PHY_TX_CTRL2); + + return 0; +} + +static struct phy_ops phy_berlin_usb_ops = { + .power_on = phy_berlin_usb_power_on, + .owner = THIS_MODULE, +}; + +static const struct of_device_id phy_berlin_sata_of_match[] = { + { + .compatible = "marvell,berlin2-usb-phy", + .data = &phy_berlin_pll_dividers[0], + }, + { + .compatible = "marvell,berlin2cd-usb-phy", + .data = &phy_berlin_pll_dividers[1], + }, + { }, +}; +MODULE_DEVICE_TABLE(of, phy_berlin_sata_of_match); + +static int phy_berlin_usb_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(phy_berlin_sata_of_match, &pdev->dev); + struct phy_berlin_usb_priv *priv; + struct resource *res; + struct phy_provider *phy_provider; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->rst_ctrl = devm_reset_control_get(&pdev->dev, NULL); + if (IS_ERR(priv->rst_ctrl)) + return PTR_ERR(priv->rst_ctrl); + + priv->pll_divider = *((u32 *)match->data); + + priv->phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops, + NULL); + if (IS_ERR(priv->phy)) { + dev_err(&pdev->dev, "failed to create PHY\n"); + return PTR_ERR(priv->phy); + } + + platform_set_drvdata(pdev, priv); + + phy_provider = + devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return PTR_ERR(phy_provider); + + return 0; +} + +static struct platform_driver phy_berlin_usb_driver = { + .probe = phy_berlin_usb_probe, + .driver = { + .name = "phy-berlin-usb", + .owner = THIS_MODULE, + .of_match_table = phy_berlin_sata_of_match, + }, +}; +module_platform_driver(phy_berlin_usb_driver); + +MODULE_AUTHOR("Antoine Tenart "); +MODULE_DESCRIPTION("Marvell Berlin PHY driver for USB"); +MODULE_LICENSE("GPL"); -- GitLab From 2f3fa3a0e5672f87f5b972910737a2ef60941b62 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 20 Nov 2014 22:53:26 +0100 Subject: [PATCH 5673/9457] Documentation: bindings: add doc for the Berlin USB PHY Document the bindings of the Marvell Berlin USB PHY driver. Signed-off-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/berlin-usb-phy.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/berlin-usb-phy.txt diff --git a/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt b/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt new file mode 100644 index 000000000000..be33780f668e --- /dev/null +++ b/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt @@ -0,0 +1,16 @@ +* Marvell Berlin USB PHY + +Required properties: +- compatible: "marvell,berlin2-usb-phy" or "marvell,berlin2cd-usb-phy" +- reg: base address and length of the registers +- #phys-cells: should be 0 +- resets: reference to the reset controller + +Example: + + usb-phy@f774000 { + compatible = "marvell,berlin2-usb-phy"; + reg = <0xf774000 0x128>; + #phy-cells = <0>; + resets = <&chip 0x104 14>; + }; -- GitLab From d451057464a7ea2fe400e56c8a7e004c875f2a84 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:17 +0200 Subject: [PATCH 5674/9457] phy: safer to_phy() macro This makes to_phy() macro work with other variable names besides "dev". Signed-off-by: Heikki Krogerus Tested-by: Vivek Gautam Acked-by: Felipe Balbi Signed-off-by: Kishon Vijay Abraham I --- include/linux/phy/phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 8cb6f815475b..9fda68324298 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -110,7 +110,7 @@ struct phy_init_data { .port = _port, \ } -#define to_phy(dev) (container_of((dev), struct phy, dev)) +#define to_phy(a) (container_of((a), struct phy, dev)) #define of_phy_provider_register(dev, xlate) \ __of_phy_provider_register((dev), THIS_MODULE, (xlate)) -- GitLab From b7bc15b98e843926d01eb03b9c0e196d8ddbadeb Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:18 +0200 Subject: [PATCH 5675/9457] phy: improved lookup method Separates registration of the phy and the lookup. The method is copied from clkdev.c, Signed-off-by: Heikki Krogerus Signed-off-by: Kishon Vijay Abraham I --- Documentation/phy.txt | 60 ++++++++--------------------- drivers/phy/phy-core.c | 84 ++++++++++++++++++++++++++++++++++++++++- include/linux/phy/phy.h | 16 ++++++++ 3 files changed, 115 insertions(+), 45 deletions(-) diff --git a/Documentation/phy.txt b/Documentation/phy.txt index c6594af94d25..371361c69a4b 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt @@ -54,18 +54,14 @@ The PHY driver should create the PHY in order for other peripheral controllers to make use of it. The PHY framework provides 2 APIs to create the PHY. struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); + const struct phy_ops *ops); struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); + const struct phy_ops *ops); The PHY drivers can use one of the above 2 APIs to create the PHY by passing -the device pointer, phy ops and init_data. +the device pointer and phy ops. phy_ops is a set of function pointers for performing PHY operations such as -init, exit, power_on and power_off. *init_data* is mandatory to get a reference -to the PHY in the case of non-dt boot. See section *Board File Initialization* -on how init_data should be used. +init, exit, power_on and power_off. Inorder to dereference the private data (in phy_ops), the phy provider driver can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in @@ -137,42 +133,18 @@ There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync, phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and phy_pm_runtime_forbid for performing PM operations. -8. Board File Initialization - -Certain board file initialization is necessary in order to get a reference -to the PHY in the case of non-dt boot. -Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe, -then in the board file the following initialization should be done. - -struct phy_consumer consumers[] = { - PHY_CONSUMER("dwc3.0", "usb"), - PHY_CONSUMER("pcie.0", "pcie"), - PHY_CONSUMER("sata.0", "sata"), -}; -PHY_CONSUMER takes 2 parameters, first is the device name of the controller -(PHY consumer) and second is the port name. - -struct phy_init_data init_data = { - .consumers = consumers, - .num_consumers = ARRAY_SIZE(consumers), -}; - -static const struct platform_device pipe3_phy_dev = { - .name = "pipe3-phy", - .id = -1, - .dev = { - .platform_data = { - .init_data = &init_data, - }, - }, -}; - -then, while doing phy_create, the PHY driver should pass this init_data - phy_create(dev, ops, pdata->init_data); - -and the controller driver (phy consumer) should pass the port name along with -the device to get a reference to the PHY - phy_get(dev, "pcie"); +8. PHY Mappings + +In order to get reference to a PHY without help from DeviceTree, the framework +offers lookups which can be compared to clkdev that allow clk structures to be +bound to devices. A lookup can be made be made during runtime when a handle to +the struct phy already exists. + +The framework offers the following API for registering and unregistering the +lookups. + +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); 9. DeviceTree Binding diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 1606ce9805d0..bc830773fe05 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -26,6 +26,7 @@ static struct class *phy_class; static DEFINE_MUTEX(phy_provider_mutex); static LIST_HEAD(phy_provider_list); +static LIST_HEAD(phys); static DEFINE_IDA(phy_ida); static void devm_phy_release(struct device *dev, void *res) @@ -84,6 +85,87 @@ static struct phy *phy_lookup(struct device *device, const char *port) return ERR_PTR(-ENODEV); } +/** + * phy_create_lookup() - allocate and register PHY/device association + * @phy: the phy of the association + * @con_id: connection ID string on device + * @dev_id: the device of the association + * + * Creates and registers phy_lookup entry. + */ +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + struct phy_lookup *pl; + + if (!phy || !dev_id || !con_id) + return -EINVAL; + + pl = kzalloc(sizeof(*pl), GFP_KERNEL); + if (!pl) + return -ENOMEM; + + pl->dev_id = dev_id; + pl->con_id = con_id; + pl->phy = phy; + + mutex_lock(&phy_provider_mutex); + list_add_tail(&pl->node, &phys); + mutex_unlock(&phy_provider_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(phy_create_lookup); + +/** + * phy_remove_lookup() - find and remove PHY/device association + * @phy: the phy of the association + * @con_id: connection ID string on device + * @dev_id: the device of the association + * + * Finds and unregisters phy_lookup entry that was created with + * phy_create_lookup(). + */ +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + struct phy_lookup *pl; + + if (!phy || !dev_id || !con_id) + return; + + mutex_lock(&phy_provider_mutex); + list_for_each_entry(pl, &phys, node) + if (pl->phy == phy && !strcmp(pl->dev_id, dev_id) && + !strcmp(pl->con_id, con_id)) { + list_del(&pl->node); + kfree(pl); + break; + } + mutex_unlock(&phy_provider_mutex); +} +EXPORT_SYMBOL_GPL(phy_remove_lookup); + +static struct phy *phy_find(struct device *dev, const char *con_id) +{ + const char *dev_id = dev_name(dev); + struct phy_lookup *p, *pl = NULL; + struct phy *phy; + + mutex_lock(&phy_provider_mutex); + list_for_each_entry(p, &phys, node) + if (!strcmp(p->dev_id, dev_id) && !strcmp(p->con_id, con_id)) { + pl = p; + break; + } + mutex_unlock(&phy_provider_mutex); + + phy = pl ? pl->phy : ERR_PTR(-ENODEV); + + /* fall-back to the old lookup method for now */ + if (IS_ERR(phy)) + phy = phy_lookup(dev, con_id); + return phy; +} + static struct phy_provider *of_phy_provider_lookup(struct device_node *node) { struct phy_provider *phy_provider; @@ -455,7 +537,7 @@ struct phy *phy_get(struct device *dev, const char *string) string); phy = _of_phy_get(dev->of_node, index); } else { - phy = phy_lookup(dev, string); + phy = phy_find(dev, string); } if (IS_ERR(phy)) return phy; diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 9fda68324298..849284e5873f 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -110,6 +110,13 @@ struct phy_init_data { .port = _port, \ } +struct phy_lookup { + struct list_head node; + const char *dev_id; + const char *con_id; + struct phy *phy; +}; + #define to_phy(a) (container_of((a), struct phy, dev)) #define of_phy_provider_register(dev, xlate) \ @@ -174,6 +181,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev, void of_phy_provider_unregister(struct phy_provider *phy_provider); void devm_of_phy_provider_unregister(struct device *dev, struct phy_provider *phy_provider); +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); #else static inline int phy_pm_runtime_get(struct phy *phy) { @@ -345,6 +354,13 @@ static inline void devm_of_phy_provider_unregister(struct device *dev, struct phy_provider *phy_provider) { } +static inline int +phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + return 0; +} +static inline void phy_remove_lookup(struct phy *phy, const char *con_id, + const char *dev_id) { } #endif #endif /* __DRIVERS_PHY_H */ -- GitLab From df9f7b311db1edae7ec5e2c78aa92fce7b9dd34d Mon Sep 17 00:00:00 2001 From: Kiran Raparthy Date: Fri, 21 Nov 2014 11:31:20 +0530 Subject: [PATCH 5676/9457] usb: phy: introduce usb_phy_set_event interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHY drivers require a generic interface to handle per-PHY events. usb_phy_set_event interface sets event to phy event. PHY drivers call this interface for each phy event. Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: Android Kernel Team Cc: John Stultz Cc: Sumit Semwal Cc: Arve Hj�nnev�g Cc: Benoit Goby [Original patch in Android from Todd] Cc: Todd Poynor Signed-off-by: Kiran Raparthy Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy.c | 12 ++++++++++++ include/linux/usb/phy.h | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index e6bf801a339a..b4066a001ba0 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -446,3 +446,15 @@ int usb_bind_phy(const char *dev_name, u8 index, return 0; } EXPORT_SYMBOL_GPL(usb_bind_phy); + +/** + * usb_phy_set_event - set event to phy event + * @x: the phy returned by usb_get_phy(); + * + * This sets event to phy event + */ +void usb_phy_set_event(struct usb_phy *x, unsigned long event) +{ + x->last_event = event; +} +EXPORT_SYMBOL_GPL(usb_phy_set_event); diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index ac7d7913694f..f499c23e6342 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -209,6 +209,7 @@ extern void usb_put_phy(struct usb_phy *); extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); extern int usb_bind_phy(const char *dev_name, u8 index, const char *phy_dev_name); +extern void usb_phy_set_event(struct usb_phy *x, unsigned long event); #else static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) { @@ -250,6 +251,10 @@ static inline int usb_bind_phy(const char *dev_name, u8 index, { return -EOPNOTSUPP; } + +static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event) +{ +} #endif static inline int -- GitLab From c1a3acaadde7eb260f4fd4ec87cb87d3ffeed979 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:45 +0530 Subject: [PATCH 5677/9457] usb: dwc3: exynos: Remove local variable for clock from probe There's no need to keep one local variable for clock, and then assign the same to 'clk' member of dwc3_exynos. Just cleaning it up. Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 4369c6658ec8..14f85a08a4cf 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -105,7 +105,6 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused) static int dwc3_exynos_probe(struct platform_device *pdev) { struct dwc3_exynos *exynos; - struct clk *clk; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; @@ -132,15 +131,13 @@ static int dwc3_exynos_probe(struct platform_device *pdev) return ret; } - clk = devm_clk_get(dev, "usbdrd30"); - if (IS_ERR(clk)) { + exynos->dev = dev; + + exynos->clk = devm_clk_get(dev, "usbdrd30"); + if (IS_ERR(exynos->clk)) { dev_err(dev, "couldn't get clock\n"); return -EINVAL; } - - exynos->dev = dev; - exynos->clk = clk; - clk_prepare_enable(exynos->clk); exynos->vdd33 = devm_regulator_get(dev, "vdd33"); @@ -184,7 +181,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) err3: regulator_disable(exynos->vdd33); err2: - clk_disable_unprepare(clk); + clk_disable_unprepare(exynos->clk); return ret; } -- GitLab From 72d996fc7a01c2e4d581a15db7d001e2799ffb29 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:46 +0530 Subject: [PATCH 5678/9457] usb: dwc3: exynos: Add provision for suspend clock DWC3 controller on Exynos SoC series have separate control for suspend clock which replaces pipe3_rx_pclk as clock source to a small part of DWC3 core that operates when SS PHY is in its lowest power state (P3) in states SS.disabled and U3. Suggested-by: Anton Tikhomirov Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 14f85a08a4cf..a1782d86a226 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -34,6 +34,8 @@ struct dwc3_exynos { struct device *dev; struct clk *clk; + struct clk *susp_clk; + struct regulator *vdd33; struct regulator *vdd10; }; @@ -140,6 +142,13 @@ static int dwc3_exynos_probe(struct platform_device *pdev) } clk_prepare_enable(exynos->clk); + exynos->susp_clk = devm_clk_get(dev, "usbdrd30_susp_clk"); + if (IS_ERR(exynos->susp_clk)) { + dev_dbg(dev, "no suspend clk specified\n"); + exynos->susp_clk = NULL; + } + clk_prepare_enable(exynos->susp_clk); + exynos->vdd33 = devm_regulator_get(dev, "vdd33"); if (IS_ERR(exynos->vdd33)) { ret = PTR_ERR(exynos->vdd33); @@ -181,6 +190,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) err3: regulator_disable(exynos->vdd33); err2: + clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); return ret; } @@ -193,6 +203,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); + clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); regulator_disable(exynos->vdd33); -- GitLab From ed692a99f31c92ec649ee2f7a0ecb4aa0f69d853 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:47 +0530 Subject: [PATCH 5679/9457] usb: dwc3: exynos: Add provision for AXI UpScaler clock on exynos7 DWC3 controller on Exynos7 SoC has separate control for AXI UpScaler which connects DWC3 DRD controller to AXI bus. Get the gate clock for the same to control it across power cycles. Suggested-by: Anton Tikhomirov Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- .../devicetree/bindings/usb/exynos-usb.txt | 6 ++++-- drivers/usb/dwc3/dwc3-exynos.c | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index a3b5990d0f2c..9b4dbe3b2acc 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -82,8 +82,10 @@ Example: DWC3 Required properties: - - compatible: should be "samsung,exynos5250-dwusb3" for USB 3.0 DWC3 - controller. + - compatible: should be one of the following - + "samsung,exynos5250-dwusb3": for USB 3.0 DWC3 controller on + Exynos5250/5420. + "samsung,exynos7-dwusb3": for USB 3.0 DWC3 controller on Exynos7. - #address-cells, #size-cells : should be '1' if the device has sub-nodes with 'reg' property. - ranges: allows valid 1:1 translation between child's address space and diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index a1782d86a226..7bd0a95b2815 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -35,6 +35,7 @@ struct dwc3_exynos { struct clk *clk; struct clk *susp_clk; + struct clk *axius_clk; struct regulator *vdd33; struct regulator *vdd10; @@ -149,6 +150,17 @@ static int dwc3_exynos_probe(struct platform_device *pdev) } clk_prepare_enable(exynos->susp_clk); + if (of_device_is_compatible(node, "samsung,exynos7-dwusb3")) { + exynos->axius_clk = devm_clk_get(dev, "usbdrd30_axius_clk"); + if (IS_ERR(exynos->axius_clk)) { + dev_err(dev, "no AXI UpScaler clk specified\n"); + return -ENODEV; + } + clk_prepare_enable(exynos->axius_clk); + } else { + exynos->axius_clk = NULL; + } + exynos->vdd33 = devm_regulator_get(dev, "vdd33"); if (IS_ERR(exynos->vdd33)) { ret = PTR_ERR(exynos->vdd33); @@ -190,6 +202,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) err3: regulator_disable(exynos->vdd33); err2: + clk_disable_unprepare(exynos->axius_clk); clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); return ret; @@ -203,6 +216,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); + clk_disable_unprepare(exynos->axius_clk); clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); @@ -214,6 +228,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) static const struct of_device_id exynos_dwc3_match[] = { { .compatible = "samsung,exynos5250-dwusb3" }, + { .compatible = "samsung,exynos7-dwusb3" }, {}, }; MODULE_DEVICE_TABLE(of, exynos_dwc3_match); @@ -223,6 +238,7 @@ static int dwc3_exynos_suspend(struct device *dev) { struct dwc3_exynos *exynos = dev_get_drvdata(dev); + clk_disable(exynos->axius_clk); clk_disable(exynos->clk); regulator_disable(exynos->vdd33); @@ -248,6 +264,7 @@ static int dwc3_exynos_resume(struct device *dev) } clk_enable(exynos->clk); + clk_enable(exynos->axius_clk); /* runtime set active to reflect active state. */ pm_runtime_disable(dev); -- GitLab From 4ace06e8b3c32d6a601474af31580bbc1027fa9f Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 21 Nov 2014 15:14:47 +0100 Subject: [PATCH 5680/9457] usb: dwc2: gadget: rework disconnect event handling This patch adds a call to s3c_hsotg_disconnect() from 'end session' interrupt (GOTGINT_SES_END_DET) to correctly notify gadget subsystem about unplugged usb cable. DISCONNINT interrupt cannot be used for this purpose, because it is asserted only in host mode. To avoid reporting disconnect event more than once, a disconnect call has been moved from USB_REQ_SET_ADDRESS handling function to SESSREQINT interrupt. This way driver ensures that disconnect event is reported either when usb cable is unplugged or every time the host starts a new session. To handle devices which has been synthesized without SRP support, connected state is set in ENUMDONE interrupt. Signed-off-by: Marek Szyprowski Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 3 +++ drivers/usb/dwc2/core_intr.c | 9 +++++++++ drivers/usb/dwc2/gadget.c | 10 +++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 4710935fbad3..2cb0ac31ae86 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -687,6 +687,7 @@ struct dwc2_hsotg { u8 ctrl_buff[8]; struct usb_gadget gadget; + unsigned int connected:1; unsigned int setup; unsigned long last_rst; struct s3c_hsotg_ep *eps; @@ -968,6 +969,7 @@ extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2); extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); +extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -979,6 +981,7 @@ static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {} static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} +static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b176c2fc34e5..ad43c5bc1ef1 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -128,6 +128,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dwc2_op_state_str(hsotg)); gotgctl = readl(hsotg->regs + GOTGCTL); + if (dwc2_is_device_mode(hsotg)) + s3c_hsotg_disconnect(hsotg); + if (hsotg->op_state == OTG_STATE_B_HOST) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; } else { @@ -314,6 +317,12 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) /* Clear interrupt */ writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); + + /* + * Report disconnect if there is any previous session established + */ + if (dwc2_is_device_mode(hsotg)) + s3c_hsotg_disconnect(hsotg); } /* diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 367689b3d645..3cd789139f3f 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1030,7 +1030,6 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, } static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); -static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg); /** * s3c_hsotg_stall_ep0 - stall ep0 @@ -1108,7 +1107,6 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { switch (ctrl->bRequest) { case USB_REQ_SET_ADDRESS: - s3c_hsotg_disconnect(hsotg); dcfg = readl(hsotg->regs + DCFG); dcfg &= ~DCFG_DEVADDR_MASK; dcfg |= (le16_to_cpu(ctrl->wValue) << @@ -2028,15 +2026,20 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, * transactions and signal the gadget driver that this * has happened. */ -static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) +void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) { unsigned ep; + if (!hsotg->connected) + return; + + hsotg->connected = 0; for (ep = 0; ep < hsotg->num_of_eps; ep++) kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); call_gadget(hsotg, disconnect); } +EXPORT_SYMBOL_GPL(s3c_hsotg_disconnect); /** * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler @@ -2289,6 +2292,7 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); + hsotg->connected = 1; } if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { -- GitLab From 7ad8096edfe0529eabb3ad466184c8fbd6134e1a Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 21 Nov 2014 15:14:48 +0100 Subject: [PATCH 5681/9457] usb: dwc2: gadget: add mutex to serialize init/deinit calls This patch adds mutex, which protects initialization and deinitialization procedures against suspend/resume methods. This mutex will be needed by the updated suspend/resume calls, which tracks gadget state. Signed-off-by: Marek Szyprowski Acked-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/gadget.c | 19 +++++++++++++++++++ drivers/usb/dwc2/platform.c | 2 ++ 3 files changed, 22 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 2cb0ac31ae86..6b197550c133 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -576,6 +576,7 @@ struct dwc2_hsotg { struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; spinlock_t lock; + struct mutex init_mutex; void *priv; int irq; struct clk *clk; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 3cd789139f3f..651733413c0e 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -2866,6 +2867,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, return -EINVAL; } + mutex_lock(&hsotg->init_mutex); WARN_ON(hsotg->driver); driver->driver.bus = NULL; @@ -2891,9 +2893,12 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); + mutex_unlock(&hsotg->init_mutex); + return 0; err: + mutex_unlock(&hsotg->init_mutex); hsotg->driver = NULL; return ret; } @@ -2914,6 +2919,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) if (!hsotg) return -ENODEV; + mutex_lock(&hsotg->init_mutex); + /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); @@ -2931,6 +2938,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) clk_disable(hsotg->clk); + mutex_unlock(&hsotg->init_mutex); + return 0; } @@ -2959,6 +2968,7 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on); + mutex_lock(&hsotg->init_mutex); spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { clk_enable(hsotg->clk); @@ -2970,6 +2980,7 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); + mutex_unlock(&hsotg->init_mutex); return 0; } @@ -3572,6 +3583,8 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) unsigned long flags; int ret = 0; + mutex_lock(&hsotg->init_mutex); + if (hsotg->driver) dev_info(hsotg->dev, "suspending usb gadget %s\n", hsotg->driver->driver.name); @@ -3594,6 +3607,8 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) clk_disable(hsotg->clk); } + mutex_unlock(&hsotg->init_mutex); + return ret; } EXPORT_SYMBOL_GPL(s3c_hsotg_suspend); @@ -3603,6 +3618,8 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) unsigned long flags; int ret = 0; + mutex_lock(&hsotg->init_mutex); + if (hsotg->driver) { dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name); @@ -3619,6 +3636,8 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) s3c_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); + mutex_unlock(&hsotg->init_mutex); + return ret; } EXPORT_SYMBOL_GPL(s3c_hsotg_resume); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 57eb8a3e022b..ec5658ac52ba 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -212,6 +213,7 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); spin_lock_init(&hsotg->lock); + mutex_init(&hsotg->init_mutex); retval = dwc2_gadget_init(hsotg, irq); if (retval) return retval; -- GitLab From dc6e69e603e58200df806afcfb9b71ef94e58847 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 21 Nov 2014 15:14:49 +0100 Subject: [PATCH 5682/9457] usb: dwc2: gadget: rework suspend/resume code to correctly restore gadget state Suspend/resume code assumed that the gadget was always started and enabled to connect to usb bus. This means that the actual state of the gadget (started/stopped or connected/disconnected) was not correctly preserved on suspend/resume cycle. This patch fixes this issue. Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 3 ++- drivers/usb/dwc2/gadget.c | 39 ++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 6b197550c133..7a70a1349334 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -688,8 +688,9 @@ struct dwc2_hsotg { u8 ctrl_buff[8]; struct usb_gadget gadget; + unsigned int enabled:1; unsigned int connected:1; - unsigned int setup; + unsigned int setup:1; unsigned long last_rst; struct s3c_hsotg_ep *eps; #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 651733413c0e..05b05221d677 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2889,6 +2889,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_init(hsotg); s3c_hsotg_core_init_disconnected(hsotg); + hsotg->enabled = 0; spin_unlock_irqrestore(&hsotg->lock, flags); dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); @@ -2929,6 +2930,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) hsotg->driver = NULL; hsotg->gadget.speed = USB_SPEED_UNKNOWN; + hsotg->enabled = 0; spin_unlock_irqrestore(&hsotg->lock, flags); @@ -2972,9 +2974,11 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { clk_enable(hsotg->clk); + hsotg->enabled = 1; s3c_hsotg_core_connect(hsotg); } else { s3c_hsotg_core_disconnect(hsotg); + hsotg->enabled = 0; clk_disable(hsotg->clk); } @@ -3585,20 +3589,21 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) mutex_lock(&hsotg->init_mutex); - if (hsotg->driver) + if (hsotg->driver) { + int ep; + dev_info(hsotg->dev, "suspending usb gadget %s\n", hsotg->driver->driver.name); - spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_core_disconnect(hsotg); - s3c_hsotg_disconnect(hsotg); - hsotg->gadget.speed = USB_SPEED_UNKNOWN; - spin_unlock_irqrestore(&hsotg->lock, flags); + spin_lock_irqsave(&hsotg->lock, flags); + if (hsotg->enabled) + s3c_hsotg_core_disconnect(hsotg); + s3c_hsotg_disconnect(hsotg); + hsotg->gadget.speed = USB_SPEED_UNKNOWN; + spin_unlock_irqrestore(&hsotg->lock, flags); - s3c_hsotg_phy_disable(hsotg); + s3c_hsotg_phy_disable(hsotg); - if (hsotg->driver) { - int ep; for (ep = 0; ep < hsotg->num_of_eps; ep++) s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); @@ -3626,16 +3631,16 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) clk_enable(hsotg->clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - } - - s3c_hsotg_phy_enable(hsotg); + hsotg->supplies); - spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_core_init_disconnected(hsotg); - s3c_hsotg_core_connect(hsotg); - spin_unlock_irqrestore(&hsotg->lock, flags); + s3c_hsotg_phy_enable(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); + s3c_hsotg_core_init_disconnected(hsotg); + if (hsotg->enabled) + s3c_hsotg_core_connect(hsotg); + spin_unlock_irqrestore(&hsotg->lock, flags); + } mutex_unlock(&hsotg->init_mutex); return ret; -- GitLab From 7b0f000b2fdc18662e9070765a0f63c93ea0ef31 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 14:51:43 +0100 Subject: [PATCH 5683/9457] usb: gadget: function: delete an unnecessary check before rndis_add_hdr() The rndis_add_hdr() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_rndis.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index f13fc6a58565..829edf878dac 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -375,8 +375,7 @@ static struct sk_buff *rndis_add_header(struct gether *port, struct sk_buff *skb2; skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); - if (skb2) - rndis_add_hdr(skb2); + rndis_add_hdr(skb2); dev_kfree_skb(skb); return skb2; -- GitLab From 6f0f2a9f0f8f420f604e1ae06f1d24cc9b61a9d0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 10 Nov 2014 21:56:40 +0100 Subject: [PATCH 5684/9457] ARM: 8196/1: vfp: Workaround bad MVFR1 register on some Kraits Certain versions of the Krait processor don't report that they support the fused multiply accumulate instruction via the MVFR1 register despite the fact that they actually do. Unfortunately we use this register to identify support for VFPv4. Override the hwcap on all Krait processors to indicate support for VFPv4 to workaround this. Tested-by: Rob Clark Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/mm/proc-v7.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index b3a947863ac7..6c33eaf879ae 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -593,9 +593,10 @@ __krait_proc_info: /* * Some Krait processors don't indicate support for SDIV and UDIV * instructions in the ARM instruction set, even though they actually - * do support them. + * do support them. They also don't indicate support for fused multiply + * instructions even though they actually do support them. */ - __v7_proc __v7_setup, hwcaps = HWCAP_IDIV + __v7_proc __v7_setup, hwcaps = HWCAP_IDIV | HWCAP_VFPv4 .size __krait_proc_info, . - __krait_proc_info /* -- GitLab From 6c96a4a6e249a0580b32893583771149e0611375 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 10 Nov 2014 21:56:41 +0100 Subject: [PATCH 5685/9457] ARM: 8197/1: vfp: Fix VFPv3 hwcap detection on CPUID based cpus The subarchitecture field in the fpsid register is 7 bits wide on ARM CPUs using the CPUID identification scheme, spanning bits 22 to 16. The topmost bit is used to designate that the subarchitecture designer is not ARM when it is set to 1. On non-CPUID scheme CPUs the subarchitecture field is only 4 bits wide and the higher bits are used to indicate no double precision support (bit 20) and the FTSMX/FLDMX format (bits 21-22). The VFP support code only looks at bits 19-16 to determine the VFP version. On Qualcomm's processors (Krait and Scorpion) we should see that we have HWCAP_VFPv3 but we don't because bit 22 is set to 1 to indicate that the subarchitecture is not implemented by ARM and the rest of the bits are left as 0 because this is the first subarchitecture that Qualcomm has designed. Unfortunately we can't just widen the FPSID subarchitecture bitmask to consider all the bits on a CPUID scheme because there may be CPUs without the CPUID scheme that have VFP without double precision support and then the version would be a very wrong and large number. Instead, update the version detection logic to consider if the CPU is using the CPUID scheme. If the CPU is using CPUID scheme, use the MVFR registers to determine what version of VFP is supported. We already do this for VFPv4, so do something similar for VFPv3 and look for single or double precision support in MVFR0. Otherwise fall back to using FPSID to detect VFP support on non-CPUID scheme CPUs. We know that VFPv3 is only present in CPUs that have support for the CPUID scheme so this should be equivalent. Tested-by: Rob Clark Reviewed-by: Will Deacon Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/include/asm/vfp.h | 5 ++ arch/arm/vfp/vfpmodule.c | 93 +++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h index f4ab34fd4f72..ee5f3084243c 100644 --- a/arch/arm/include/asm/vfp.h +++ b/arch/arm/include/asm/vfp.h @@ -22,6 +22,7 @@ #define FPSID_NODOUBLE (1<<20) #define FPSID_ARCH_BIT (16) #define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) +#define FPSID_CPUID_ARCH_MASK (0x7F << FPSID_ARCH_BIT) #define FPSID_PART_BIT (8) #define FPSID_PART_MASK (0xFF << FPSID_PART_BIT) #define FPSID_VARIANT_BIT (4) @@ -75,6 +76,10 @@ /* MVFR0 bits */ #define MVFR0_A_SIMD_BIT (0) #define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT) +#define MVFR0_SP_BIT (4) +#define MVFR0_SP_MASK (0xf << MVFR0_SP_BIT) +#define MVFR0_DP_BIT (8) +#define MVFR0_DP_MASK (0xf << MVFR0_DP_BIT) /* Bit patterns for decoding the packaged operation descriptors */ #define VFPOPDESC_LENGTH_BIT (9) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 2f37e1d6cb45..5002d002f6e3 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -722,6 +722,7 @@ static int __init vfp_init(void) { unsigned int vfpsid; unsigned int cpu_arch = cpu_architecture(); + u32 mvfr0; if (cpu_arch >= CPU_ARCH_ARMv6) on_each_cpu(vfp_enable, NULL, 1); @@ -738,63 +739,73 @@ static int __init vfp_init(void) vfp_vector = vfp_null_entry; pr_info("VFP support v0.3: "); - if (VFP_arch) + if (VFP_arch) { pr_cont("not present\n"); - else if (vfpsid & FPSID_NODOUBLE) { - pr_cont("no double precision support\n"); - } else { - hotcpu_notifier(vfp_hotplug, 0); - - VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ - pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n", - (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, - (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, - (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, - (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, - (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); - - vfp_vector = vfp_support_entry; - - thread_register_notifier(&vfp_notifier_block); - vfp_pm_init(); - + return 0; + /* Extract the architecture on CPUID scheme */ + } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { + VFP_arch = vfpsid & FPSID_CPUID_ARCH_MASK; + VFP_arch >>= FPSID_ARCH_BIT; /* - * We detected VFP, and the support code is - * in place; report VFP support to userspace. + * Check for the presence of the Advanced SIMD + * load/store instructions, integer and single + * precision floating point operations. Only check + * for NEON if the hardware has the MVFR registers. */ - elf_hwcap |= HWCAP_VFP; +#ifdef CONFIG_NEON + if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + elf_hwcap |= HWCAP_NEON; +#endif #ifdef CONFIG_VFPv3 - if (VFP_arch >= 2) { + mvfr0 = fmrx(MVFR0); + if (((mvfr0 & MVFR0_DP_MASK) >> MVFR0_DP_BIT) == 0x2 || + ((mvfr0 & MVFR0_SP_MASK) >> MVFR0_SP_BIT) == 0x2) { elf_hwcap |= HWCAP_VFPv3; - /* * Check for VFPv3 D16 and VFPv4 D16. CPUs in * this configuration only have 16 x 64bit * registers. */ - if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ + if ((mvfr0 & MVFR0_A_SIMD_MASK) == 1) + /* also v4-D16 */ + elf_hwcap |= HWCAP_VFPv3D16; else elf_hwcap |= HWCAP_VFPD32; } + + if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) + elf_hwcap |= HWCAP_VFPv4; #endif - /* - * Check for the presence of the Advanced SIMD - * load/store instructions, integer and single - * precision floating point operations. Only check - * for NEON if the hardware has the MVFR registers. - */ - if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { -#ifdef CONFIG_NEON - if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) - elf_hwcap |= HWCAP_NEON; -#endif -#ifdef CONFIG_VFPv3 - if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) - elf_hwcap |= HWCAP_VFPv4; -#endif + /* Extract the architecture version on pre-cpuid scheme */ + } else { + if (vfpsid & FPSID_NODOUBLE) { + pr_cont("no double precision support\n"); + return 0; } + + VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; } + + hotcpu_notifier(vfp_hotplug, 0); + + vfp_vector = vfp_support_entry; + + thread_register_notifier(&vfp_notifier_block); + vfp_pm_init(); + + /* + * We detected VFP, and the support code is + * in place; report VFP support to userspace. + */ + elf_hwcap |= HWCAP_VFP; + + pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n", + (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, + VFP_arch, + (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, + (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, + (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); + return 0; } -- GitLab From 2b94fe2ac97fdd2ae7521004e857e33016720eb7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 20 Nov 2014 20:29:09 +0100 Subject: [PATCH 5686/9457] ARM: 8215/1: vfp: Silence mvfr0 variable unused warning Stephen Rothwell reports that commit 3f4c9f8f0a20 ("ARM: 8197/1: vfp: Fix VFPv3 hwcap detection on CPUID based cpus") introduced a variable unused warning. arch/arm/vfp/vfpmodule.c: In function 'vfp_init': arch/arm/vfp/vfpmodule.c:725:6: warning: unused variable 'mvfr0' [-Wunused-variable] u32 mvfr0; Silence this warning by using IS_ENABLED instead of ifdefs. Reported-by: Stephen Rothwell Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/vfp/vfpmodule.c | 45 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 5002d002f6e3..f6e4d56eda00 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -722,7 +722,6 @@ static int __init vfp_init(void) { unsigned int vfpsid; unsigned int cpu_arch = cpu_architecture(); - u32 mvfr0; if (cpu_arch >= CPU_ARCH_ARMv6) on_each_cpu(vfp_enable, NULL, 1); @@ -752,30 +751,30 @@ static int __init vfp_init(void) * precision floating point operations. Only check * for NEON if the hardware has the MVFR registers. */ -#ifdef CONFIG_NEON - if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + if (IS_ENABLED(CONFIG_NEON) && + (fmrx(MVFR1) & 0x000fff00) == 0x00011100) elf_hwcap |= HWCAP_NEON; -#endif -#ifdef CONFIG_VFPv3 - mvfr0 = fmrx(MVFR0); - if (((mvfr0 & MVFR0_DP_MASK) >> MVFR0_DP_BIT) == 0x2 || - ((mvfr0 & MVFR0_SP_MASK) >> MVFR0_SP_BIT) == 0x2) { - elf_hwcap |= HWCAP_VFPv3; - /* - * Check for VFPv3 D16 and VFPv4 D16. CPUs in - * this configuration only have 16 x 64bit - * registers. - */ - if ((mvfr0 & MVFR0_A_SIMD_MASK) == 1) - /* also v4-D16 */ - elf_hwcap |= HWCAP_VFPv3D16; - else - elf_hwcap |= HWCAP_VFPD32; - } - if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) - elf_hwcap |= HWCAP_VFPv4; -#endif + if (IS_ENABLED(CONFIG_VFPv3)) { + u32 mvfr0 = fmrx(MVFR0); + if (((mvfr0 & MVFR0_DP_MASK) >> MVFR0_DP_BIT) == 0x2 || + ((mvfr0 & MVFR0_SP_MASK) >> MVFR0_SP_BIT) == 0x2) { + elf_hwcap |= HWCAP_VFPv3; + /* + * Check for VFPv3 D16 and VFPv4 D16. CPUs in + * this configuration only have 16 x 64bit + * registers. + */ + if ((mvfr0 & MVFR0_A_SIMD_MASK) == 1) + /* also v4-D16 */ + elf_hwcap |= HWCAP_VFPv3D16; + else + elf_hwcap |= HWCAP_VFPD32; + } + + if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) + elf_hwcap |= HWCAP_VFPv4; + } /* Extract the architecture version on pre-cpuid scheme */ } else { if (vfpsid & FPSID_NODOUBLE) { -- GitLab From a391263cd84e6ae2da26a54383f3abf80c18d9df Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 14 Nov 2014 11:37:34 +0100 Subject: [PATCH 5687/9457] ARM: 8203/1: mm: try to re-use old ASID assignments following a rollover Rather than unconditionally allocating a fresh ASID to an mm from an older generation, attempt to re-use the old assignment where possible. This can bring performance benefits on systems where the ASID is used to tag things other than the TLB (e.g. branch prediction resources). Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mm/context.c | 58 +++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 6eb97b3a7481..91892569710f 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -184,36 +184,46 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) u64 asid = atomic64_read(&mm->context.id); u64 generation = atomic64_read(&asid_generation); - if (asid != 0 && is_reserved_asid(asid)) { + if (asid != 0) { /* - * Our current ASID was active during a rollover, we can - * continue to use it and this was just a false alarm. + * If our current ASID was active during a rollover, we + * can continue to use it and this was just a false alarm. */ - asid = generation | (asid & ~ASID_MASK); - } else { + if (is_reserved_asid(asid)) + return generation | (asid & ~ASID_MASK); + /* - * Allocate a free ASID. If we can't find one, take a - * note of the currently active ASIDs and mark the TLBs - * as requiring flushes. We always count from ASID #1, - * as we reserve ASID #0 to switch via TTBR0 and to - * avoid speculative page table walks from hitting in - * any partial walk caches, which could be populated - * from overlapping level-1 descriptors used to map both - * the module area and the userspace stack. + * We had a valid ASID in a previous life, so try to re-use + * it if possible., */ - asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx); - if (asid == NUM_USER_ASIDS) { - generation = atomic64_add_return(ASID_FIRST_VERSION, - &asid_generation); - flush_context(cpu); - asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); - } - __set_bit(asid, asid_map); - cur_idx = asid; - asid |= generation; - cpumask_clear(mm_cpumask(mm)); + asid &= ~ASID_MASK; + if (!__test_and_set_bit(asid, asid_map)) + goto bump_gen; } + /* + * Allocate a free ASID. If we can't find one, take a note of the + * currently active ASIDs and mark the TLBs as requiring flushes. + * We always count from ASID #1, as we reserve ASID #0 to switch + * via TTBR0 and to avoid speculative page table walks from hitting + * in any partial walk caches, which could be populated from + * overlapping level-1 descriptors used to map both the module + * area and the userspace stack. + */ + asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx); + if (asid == NUM_USER_ASIDS) { + generation = atomic64_add_return(ASID_FIRST_VERSION, + &asid_generation); + flush_context(cpu); + asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); + } + + __set_bit(asid, asid_map); + cur_idx = asid; + +bump_gen: + asid |= generation; + cpumask_clear(mm_cpumask(mm)); return asid; } -- GitLab From c2459d35f5b8de077fde859b8c96a23f309b9ab2 Mon Sep 17 00:00:00 2001 From: Lin Yongting Date: Sun, 16 Nov 2014 03:14:58 +0100 Subject: [PATCH 5688/9457] ARM: 8204/1: Add unwinding support for memset function The memset function never had unwinding annotations added. Currently, when accessing NULL pointer by memset occurs the backtrace shown will stop at memset or some completely unrelated function. Add unwinding annotations in hopes of getting a more useful backtrace when accessing NULL pointer by memset, kprobe or interrupt. Signed-off-by: Lin Yongting Signed-off-by: Russell King --- arch/arm/lib/memset.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index 671455c854fa..a4ee97b5a2bf 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -11,11 +11,13 @@ */ #include #include +#include .text .align 5 ENTRY(memset) +UNWIND( .fnstart ) ands r3, r0, #3 @ 1 unaligned? mov ip, r0 @ preserve r0 as return value bne 6f @ 1 @@ -34,6 +36,9 @@ ENTRY(memset) * We need 2 extra registers for this loop - use r8 and the LR */ stmfd sp!, {r8, lr} +UNWIND( .fnend ) +UNWIND( .fnstart ) +UNWIND( .save {r8, lr} ) mov r8, r1 mov lr, r1 @@ -53,6 +58,7 @@ ENTRY(memset) tst r2, #16 stmneia ip!, {r1, r3, r8, lr} ldmfd sp!, {r8, lr} +UNWIND( .fnend ) #else @@ -62,6 +68,9 @@ ENTRY(memset) */ stmfd sp!, {r4-r8, lr} +UNWIND( .fnend ) +UNWIND( .fnstart ) +UNWIND( .save {r4-r8, lr} ) mov r4, r1 mov r5, r1 mov r6, r1 @@ -94,9 +103,11 @@ ENTRY(memset) tst r2, #16 stmneia ip!, {r4-r7} ldmfd sp!, {r4-r8, lr} +UNWIND( .fnend ) #endif +UNWIND( .fnstart ) 4: tst r2, #8 stmneia ip!, {r1, r3} tst r2, #4 @@ -120,4 +131,5 @@ ENTRY(memset) strb r1, [ip], #1 @ 1 add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) b 1b +UNWIND( .fnend ) ENDPROC(memset) -- GitLab From 4ed89f2228061422ce5f62545fd0b6f6648bd2cc Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 11:26:42 +0000 Subject: [PATCH 5689/9457] ARM: convert printk(KERN_* to pr_* Convert many (but not all) printk(KERN_* to pr_* to simplify the code. We take the opportunity to join some printk lines together so we don't split the message across several lines, and we also add a few levels to some messages which were previously missing them. Tested-by: Andrew Lunn Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 13 +++++----- arch/arm/kernel/atags_compat.c | 6 ++--- arch/arm/kernel/atags_parse.c | 5 ++-- arch/arm/kernel/atags_proc.c | 4 ++-- arch/arm/kernel/bios32.c | 2 +- arch/arm/kernel/dma-isa.c | 4 ++-- arch/arm/kernel/dma.c | 26 +++++++++----------- arch/arm/kernel/etm.c | 12 +++++----- arch/arm/kernel/fiq.c | 2 +- arch/arm/kernel/irq.c | 2 +- arch/arm/kernel/machine_kexec.c | 6 ++--- arch/arm/kernel/module.c | 2 +- arch/arm/kernel/smp.c | 16 ++++++------- arch/arm/kernel/smp_twd.c | 4 ++-- arch/arm/kernel/swp_emulate.c | 2 +- arch/arm/kernel/thumbee.c | 2 +- arch/arm/kernel/topology.c | 4 ++-- arch/arm/kernel/traps.c | 42 ++++++++++++++++----------------- arch/arm/kernel/xscale-cp0.c | 7 +++--- arch/arm/mm/alignment.c | 10 ++++---- arch/arm/mm/cache-feroceon-l2.c | 6 ++--- arch/arm/mm/cache-tauros2.c | 12 +++++----- arch/arm/mm/fault-armv.c | 6 ++--- arch/arm/mm/fault.c | 31 ++++++++++++------------ arch/arm/mm/init.c | 4 ++-- arch/arm/mm/mmu.c | 38 ++++++++++++----------------- arch/arm/nwfpe/fpmodule.c | 4 ++-- arch/arm/vfp/vfpsingle.c | 2 +- 28 files changed, 128 insertions(+), 146 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index e57d7e5bf96a..7b69c5f9cd74 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -282,8 +282,8 @@ static int sa1111_retrigger_lowirq(struct irq_data *d) } if (i == 8) - printk(KERN_ERR "Danger Will Robinson: failed to " - "re-trigger IRQ%d\n", d->irq); + pr_err("Danger Will Robinson: failed to re-trigger IRQ%d\n", + d->irq); return i == 8 ? -1 : 0; } @@ -384,8 +384,8 @@ static int sa1111_retrigger_highirq(struct irq_data *d) } if (i == 8) - printk(KERN_ERR "Danger Will Robinson: failed to " - "re-trigger IRQ%d\n", d->irq); + pr_err("Danger Will Robinson: failed to re-trigger IRQ%d\n", + d->irq); return i == 8 ? -1 : 0; } @@ -740,9 +740,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) goto err_unmap; } - printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " - "silicon revision %lx, metal revision %lx\n", - (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK)); + pr_info("SA1111 Microprocessor Companion Chip: silicon revision %lx, metal revision %lx\n", + (id & SKID_SIREV_MASK) >> 4, id & SKID_MTREV_MASK); /* * We found it. Wake the chip up, and initialise. diff --git a/arch/arm/kernel/atags_compat.c b/arch/arm/kernel/atags_compat.c index 5236ad38f417..05c28b12353c 100644 --- a/arch/arm/kernel/atags_compat.c +++ b/arch/arm/kernel/atags_compat.c @@ -97,8 +97,7 @@ static void __init build_tag_list(struct param_struct *params, void *taglist) struct tag *tag = taglist; if (params->u1.s.page_size != PAGE_SIZE) { - printk(KERN_WARNING "Warning: bad configuration page, " - "trying to continue\n"); + pr_warn("Warning: bad configuration page, trying to continue\n"); return; } @@ -109,8 +108,7 @@ static void __init build_tag_list(struct param_struct *params, void *taglist) params->u1.s.nr_pages != 0x04000 && params->u1.s.nr_pages != 0x08000 && params->u1.s.nr_pages != 0x10000) { - printk(KERN_WARNING "Warning: bad NeTTrom parameters " - "detected, using defaults\n"); + pr_warn("Warning: bad NeTTrom parameters detected, using defaults\n"); params->u1.s.nr_pages = 0x1000; /* 16MB */ params->u1.s.ramdisk_size = 0; diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 528f8af2addb..68c6ae0b9e4c 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c @@ -167,8 +167,7 @@ static void __init parse_tags(const struct tag *t) { for (; t->hdr.size; t = tag_next(t)) if (!parse_tag(t)) - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", + pr_warn("Ignoring unrecognised tag 0x%08x\n", t->hdr.tag); } @@ -193,7 +192,7 @@ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) */ for_each_machine_desc(p) if (machine_nr == p->nr) { - printk("Machine: %s\n", p->name); + pr_info("Machine: %s\n", p->name); mdesc = p; break; } diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c index c7ff8073416f..5a3379055f55 100644 --- a/arch/arm/kernel/atags_proc.c +++ b/arch/arm/kernel/atags_proc.c @@ -41,7 +41,7 @@ static int __init init_atags_procfs(void) size_t size; if (tag->hdr.tag != ATAG_CORE) { - printk(KERN_INFO "No ATAGs?"); + pr_info("No ATAGs?"); return -EINVAL; } @@ -68,7 +68,7 @@ static int __init init_atags_procfs(void) nomem: kfree(b); - printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); + pr_err("Exporting ATAGs: not enough memory\n"); return -ENOMEM; } diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 17a26c17f7f5..391ffdfce571 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -355,7 +355,7 @@ void pcibios_fixup_bus(struct pci_bus *bus) /* * Report what we did for this bus */ - printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", + pr_info("PCI: bus%d: Fast back to back transfers %sabled\n", bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); } EXPORT_SYMBOL(pcibios_fixup_bus); diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 360bb6d701f5..84363fe7bad2 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -213,8 +213,8 @@ void __init isa_init_dma(void) for (chan = 0; chan < 8; chan++) { int ret = isa_dma_add(chan, &isa_dma[chan]); if (ret) - printk(KERN_ERR "ISADMA%u: unable to register: %d\n", - chan, ret); + pr_err("ISADMA%u: unable to register: %d\n", + chan, ret); } request_dma(DMA_ISA_CASCADE, "cascade"); diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 7b829d9663b1..e651c4d0a0d9 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -79,7 +79,7 @@ int request_dma(unsigned int chan, const char *device_id) return ret; bad_dma: - printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan); + pr_err("dma: trying to allocate DMA%d\n", chan); return -EINVAL; busy: @@ -100,7 +100,7 @@ void free_dma(unsigned int chan) goto bad_dma; if (dma->active) { - printk(KERN_ERR "dma%d: freeing active DMA\n", chan); + pr_err("dma%d: freeing active DMA\n", chan); dma->d_ops->disable(chan, dma); dma->active = 0; } @@ -111,11 +111,11 @@ void free_dma(unsigned int chan) return; } - printk(KERN_ERR "dma%d: trying to free free DMA\n", chan); + pr_err("dma%d: trying to free free DMA\n", chan); return; bad_dma: - printk(KERN_ERR "dma: trying to free DMA%d\n", chan); + pr_err("dma: trying to free DMA%d\n", chan); } EXPORT_SYMBOL(free_dma); @@ -126,8 +126,7 @@ void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg) dma_t *dma = dma_channel(chan); if (dma->active) - printk(KERN_ERR "dma%d: altering DMA SG while " - "DMA active\n", chan); + pr_err("dma%d: altering DMA SG while DMA active\n", chan); dma->sg = sg; dma->sgcount = nr_sg; @@ -144,8 +143,7 @@ void __set_dma_addr (unsigned int chan, void *addr) dma_t *dma = dma_channel(chan); if (dma->active) - printk(KERN_ERR "dma%d: altering DMA address while " - "DMA active\n", chan); + pr_err("dma%d: altering DMA address while DMA active\n", chan); dma->sg = NULL; dma->addr = addr; @@ -162,8 +160,7 @@ void set_dma_count (unsigned int chan, unsigned long count) dma_t *dma = dma_channel(chan); if (dma->active) - printk(KERN_ERR "dma%d: altering DMA count while " - "DMA active\n", chan); + pr_err("dma%d: altering DMA count while DMA active\n", chan); dma->sg = NULL; dma->count = count; @@ -178,8 +175,7 @@ void set_dma_mode (unsigned int chan, unsigned int mode) dma_t *dma = dma_channel(chan); if (dma->active) - printk(KERN_ERR "dma%d: altering DMA mode while " - "DMA active\n", chan); + pr_err("dma%d: altering DMA mode while DMA active\n", chan); dma->dma_mode = mode; dma->invalid = 1; @@ -202,7 +198,7 @@ void enable_dma (unsigned int chan) return; free_dma: - printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan); + pr_err("dma%d: trying to enable free DMA\n", chan); BUG(); } EXPORT_SYMBOL(enable_dma); @@ -223,7 +219,7 @@ void disable_dma (unsigned int chan) return; free_dma: - printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan); + pr_err("dma%d: trying to disable free DMA\n", chan); BUG(); } EXPORT_SYMBOL(disable_dma); @@ -240,7 +236,7 @@ EXPORT_SYMBOL(dma_channel_active); void set_dma_page(unsigned int chan, char pagenr) { - printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan); + pr_err("dma%d: trying to set_dma_page\n", chan); } EXPORT_SYMBOL(set_dma_page); diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 131a6ab5f355..8b96972dcb1d 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -213,7 +213,7 @@ static void etm_dump(void) int length; if (!t->etb_regs) { - printk(KERN_INFO "No tracing hardware found\n"); + pr_info("No tracing hardware found\n"); return; } @@ -229,11 +229,11 @@ static void etm_dump(void) etb_writel(t, first, ETBR_READADDR); - printk(KERN_INFO "Trace buffer contents length: %d\n", length); - printk(KERN_INFO "--- ETB buffer begin ---\n"); + pr_info("Trace buffer contents length: %d\n", length); + pr_info("--- ETB buffer begin ---\n"); for (; length; length--) printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); - printk(KERN_INFO "\n--- ETB buffer end ---\n"); + pr_info("\n--- ETB buffer end ---\n"); /* deassert the overflow bit */ etb_writel(t, 1, ETBR_CTRL); @@ -633,14 +633,14 @@ static int __init etm_init(void) retval = amba_driver_register(&etb_driver); if (retval) { - printk(KERN_ERR "Failed to register etb\n"); + pr_err("Failed to register etb\n"); return retval; } retval = amba_driver_register(&etm_driver); if (retval) { amba_driver_unregister(&etb_driver); - printk(KERN_ERR "Failed to probe etm\n"); + pr_err("Failed to probe etm\n"); return retval; } diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index b37752a96652..059c3da0fee3 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -124,7 +124,7 @@ int claim_fiq(struct fiq_handler *f) void release_fiq(struct fiq_handler *f) { if (current_fiq != f) { - printk(KERN_ERR "%s FIQ trying to release %s FIQ\n", + pr_err("%s FIQ trying to release %s FIQ\n", f->name, current_fiq->name); dump_stack(); return; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 7c81ec428b9b..f2fea6831cd5 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -82,7 +82,7 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; if (irq >= nr_irqs) { - printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); + pr_err("Trying to set irq flags for IRQ%d\n", irq); return; } diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8cf0996aa1a8..4f75192f2ef9 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -126,12 +126,12 @@ void machine_crash_shutdown(struct pt_regs *regs) msecs--; } if (atomic_read(&waiting_for_crash_ipi) > 0) - printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); + pr_warn("Non-crashing CPUs did not react to IPI\n"); crash_save_cpu(regs, smp_processor_id()); machine_kexec_mask_interrupts(); - printk(KERN_INFO "Loading crashdump kernel...\n"); + pr_info("Loading crashdump kernel...\n"); } /* @@ -177,7 +177,7 @@ void machine_kexec(struct kimage *image) reboot_entry_phys = (unsigned long)reboot_entry + (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); - printk(KERN_INFO "Bye!\n"); + pr_info("Bye!\n"); if (kexec_reinit) kexec_reinit(); diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 6a4dffefd357..bea7db9e5b80 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -251,7 +251,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, #endif default: - printk(KERN_ERR "%s: unknown relocation: %u\n", + pr_err("%s: unknown relocation: %u\n", module->name, ELF32_R_TYPE(rel->r_info)); return -ENOEXEC; } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 13396d3d600e..3138d8ea9e55 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -225,7 +225,7 @@ void __cpu_die(unsigned int cpu) pr_err("CPU%u: cpu didn't die\n", cpu); return; } - printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); + pr_notice("CPU%u: shutdown\n", cpu); /* * platform_cpu_kill() is generally expected to do the powering off @@ -235,7 +235,7 @@ void __cpu_die(unsigned int cpu) * the requesting CPU and the dying CPU actually losing power. */ if (!platform_cpu_kill(cpu)) - printk("CPU%u: unable to kill\n", cpu); + pr_err("CPU%u: unable to kill\n", cpu); } /* @@ -351,7 +351,7 @@ asmlinkage void secondary_start_kernel(void) cpu_init(); - printk("CPU%u: Booted secondary processor\n", cpu); + pr_info("CPU%u: Booted secondary processor\n", cpu); preempt_disable(); trace_hardirqs_off(); @@ -387,8 +387,8 @@ asmlinkage void secondary_start_kernel(void) void __init smp_cpus_done(unsigned int max_cpus) { - printk(KERN_INFO "SMP: Total of %d processors activated.\n", - num_online_cpus()); + pr_info("SMP: Total of %d processors activated.\n", + num_online_cpus()); hyp_mode_check(); } @@ -521,7 +521,7 @@ static void ipi_cpu_stop(unsigned int cpu) if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { raw_spin_lock(&stop_lock); - printk(KERN_CRIT "CPU%u: stopping\n", cpu); + pr_crit("CPU%u: stopping\n", cpu); dump_stack(); raw_spin_unlock(&stop_lock); } @@ -615,8 +615,8 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; default: - printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", - cpu, ipinr); + pr_crit("CPU%u: Unknown IPI message 0x%x\n", + cpu, ipinr); break; } diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 93090213c71c..172c6a05d27f 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -199,7 +199,7 @@ static void twd_calibrate_rate(void) * the timer ticks */ if (twd_timer_rate == 0) { - printk(KERN_INFO "Calibrating local timer... "); + pr_info("Calibrating local timer... "); /* Wait for a tick to start */ waitjiffies = get_jiffies_64() + 1; @@ -223,7 +223,7 @@ static void twd_calibrate_rate(void) twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); - printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, + pr_cont("%lu.%02luMHz.\n", twd_timer_rate / 1000000, (twd_timer_rate / 10000) % 100); } } diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 587fdfe1a72c..afdd51e30bec 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -260,7 +260,7 @@ static int __init swp_emulation_init(void) return -ENOMEM; #endif /* CONFIG_PROC_FS */ - printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n"); + pr_notice("Registering SWP/SWPB emulation handler\n"); register_undef_hook(&swp_hook); return 0; diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c index 80f0d69205e7..8ff8dbfbe9fb 100644 --- a/arch/arm/kernel/thumbee.c +++ b/arch/arm/kernel/thumbee.c @@ -72,7 +72,7 @@ static int __init thumbee_init(void) if ((pfr0 & 0x0000f000) != 0x00001000) return 0; - printk(KERN_INFO "ThumbEE CPU extension supported.\n"); + pr_info("ThumbEE CPU extension supported.\n"); elf_hwcap |= HWCAP_THUMBEE; thread_register_notifier(&thumbee_notifier_block); diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 89cfdd6e50cb..08b7847bf912 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -165,7 +165,7 @@ static void update_cpu_capacity(unsigned int cpu) set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity); - printk(KERN_INFO "CPU%u: update cpu_capacity %lu\n", + pr_info("CPU%u: update cpu_capacity %lu\n", cpu, arch_scale_cpu_capacity(NULL, cpu)); } @@ -269,7 +269,7 @@ void store_cpu_topology(unsigned int cpuid) update_cpu_capacity(cpuid); - printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", + pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", cpuid, cpu_topology[cpuid].thread_id, cpu_topology[cpuid].core_id, cpu_topology[cpuid].socket_id, mpidr); diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 0c8b10801d36..bb121b52ef36 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -198,14 +198,14 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) } if (!fp) { - printk("no frame pointer"); + pr_cont("no frame pointer"); ok = 0; } else if (verify_stack(fp)) { - printk("invalid frame pointer 0x%08x", fp); + pr_cont("invalid frame pointer 0x%08x", fp); ok = 0; } else if (fp < (unsigned long)end_of_stack(tsk)) - printk("frame pointer underflow"); - printk("\n"); + pr_cont("frame pointer underflow"); + pr_cont("\n"); if (ok) c_backtrace(fp, mode); @@ -240,8 +240,8 @@ static int __die(const char *str, int err, struct pt_regs *regs) static int die_counter; int ret; - printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP - S_ISA "\n", str, err, ++die_counter); + pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n", + str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); @@ -250,8 +250,8 @@ static int __die(const char *str, int err, struct pt_regs *regs) print_modules(); __show_regs(regs); - printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n", - TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); + pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", + TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); if (!user_mode(regs) || in_interrupt()) { dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, @@ -446,7 +446,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) die_sig: #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { - printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", + pr_info("%s (%d): undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); __show_regs(regs); dump_instr(KERN_INFO, regs); @@ -496,7 +496,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason) { console_verbose(); - printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]); + pr_crit("Bad mode in %s handler detected\n", handler[reason]); die("Oops - bad mode", regs, 0); local_irq_disable(); @@ -516,7 +516,7 @@ static int bad_syscall(int n, struct pt_regs *regs) #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_SYSCALL) { - printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", + pr_err("[%d] %s: obsolete system call %08x.\n", task_pid_nr(current), current->comm, n); dump_instr(KERN_ERR, regs); } @@ -721,7 +721,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) * something catastrophic has happened */ if (user_debug & UDBG_SYSCALL) { - printk("[%d] %s: arm syscall %d\n", + pr_err("[%d] %s: arm syscall %d\n", task_pid_nr(current), current->comm, no); dump_instr("", regs); if (user_mode(regs)) { @@ -780,8 +780,8 @@ late_initcall(arm_mrc_hook_init); void __bad_xchg(volatile void *ptr, int size) { - printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", - __builtin_return_address(0), ptr, size); + pr_err("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", + __builtin_return_address(0), ptr, size); BUG(); } EXPORT_SYMBOL(__bad_xchg); @@ -798,8 +798,8 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_BADABORT) { - printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", - task_pid_nr(current), current->comm, code, instr); + pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n", + task_pid_nr(current), current->comm, code, instr); dump_instr(KERN_ERR, regs); show_pte(current->mm, addr); } @@ -815,29 +815,29 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) void __readwrite_bug(const char *fn) { - printk("%s called, but not implemented\n", fn); + pr_err("%s called, but not implemented\n", fn); BUG(); } EXPORT_SYMBOL(__readwrite_bug); void __pte_error(const char *file, int line, pte_t pte) { - printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); + pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); } void __pmd_error(const char *file, int line, pmd_t pmd) { - printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd)); + pr_err("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd)); } void __pgd_error(const char *file, int line, pgd_t pgd) { - printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd)); + pr_err("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd)); } asmlinkage void __div0(void) { - printk("Division by zero in kernel.\n"); + pr_err("Division by zero in kernel.\n"); dump_stack(); } EXPORT_SYMBOL(__div0); diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c index e42adc6bcdb1..bdbb8853a19b 100644 --- a/arch/arm/kernel/xscale-cp0.c +++ b/arch/arm/kernel/xscale-cp0.c @@ -157,15 +157,14 @@ static int __init xscale_cp0_init(void) if (cpu_has_iwmmxt()) { #ifndef CONFIG_IWMMXT - printk(KERN_WARNING "CAUTION: XScale iWMMXt coprocessor " - "detected, but kernel support is missing.\n"); + pr_warn("CAUTION: XScale iWMMXt coprocessor detected, but kernel support is missing.\n"); #else - printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n"); + pr_info("XScale iWMMXt coprocessor detected.\n"); elf_hwcap |= HWCAP_IWMMXT; thread_register_notifier(&iwmmxt_notifier_block); #endif } else { - printk(KERN_INFO "XScale DSP coprocessor detected.\n"); + pr_info("XScale DSP coprocessor detected.\n"); thread_register_notifier(&dsp_notifier_block); cp_access |= 1; } diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 83792f4324ea..2c0c541c60ca 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -113,7 +113,7 @@ static int safe_usermode(int new_usermode, bool warn) new_usermode |= UM_FIXUP; if (warn) - printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); + pr_warn("alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); } return new_usermode; @@ -523,7 +523,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg * processor for us. */ if (addr != eaddr) { - printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, " + pr_err("LDMSTM: PC = %08lx, instr = %08lx, " "addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr); show_regs(regs); @@ -567,7 +567,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg return TYPE_FAULT; bad: - printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n"); + pr_err("Alignment trap: not handling ldm with s-bit set\n"); return TYPE_ERROR; } @@ -899,13 +899,13 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) return 0; swp: - printk(KERN_ERR "Alignment trap: not handling swp instruction\n"); + pr_err("Alignment trap: not handling swp instruction\n"); bad: /* * Oops, we didn't handle the instruction. */ - printk(KERN_ERR "Alignment trap: not handling instruction " + pr_err("Alignment trap: not handling instruction " "%0*lx at [<%08lx>]\n", isize << 1, isize == 2 ? tinstr : instr, instrptr); diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index e028a7f2ebcc..097181e08c25 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -313,7 +313,7 @@ static void __init disable_l2_prefetch(void) */ u = read_extra_features(); if (!(u & 0x01000000)) { - printk(KERN_INFO "Feroceon L2: Disabling L2 prefetch.\n"); + pr_info("Feroceon L2: Disabling L2 prefetch.\n"); write_extra_features(u | 0x01000000); } } @@ -326,7 +326,7 @@ static void __init enable_l2(void) if (!(u & 0x00400000)) { int i, d; - printk(KERN_INFO "Feroceon L2: Enabling L2\n"); + pr_info("Feroceon L2: Enabling L2\n"); d = flush_and_disable_dcache(); i = invalidate_and_disable_icache(); @@ -353,7 +353,7 @@ void __init feroceon_l2_init(int __l2_wt_override) enable_l2(); - printk(KERN_INFO "Feroceon L2: Cache support initialised%s.\n", + pr_info("Feroceon L2: Cache support initialised%s.\n", l2_wt_override ? ", in WT override mode" : ""); } #ifdef CONFIG_OF diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index b273739e6359..1e373d268c04 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -185,7 +185,7 @@ static void enable_extra_feature(unsigned int features) u &= ~0x01000000; else u |= 0x01000000; - printk(KERN_INFO "Tauros2: %s L2 prefetch.\n", + pr_info("Tauros2: %s L2 prefetch.\n", (features & CACHE_TAUROS2_PREFETCH_ON) ? "Enabling" : "Disabling"); @@ -193,7 +193,7 @@ static void enable_extra_feature(unsigned int features) u |= 0x00100000; else u &= ~0x00100000; - printk(KERN_INFO "Tauros2: %s line fill burt8.\n", + pr_info("Tauros2: %s line fill burt8.\n", (features & CACHE_TAUROS2_LINEFILL_BURST8) ? "Enabling" : "Disabling"); @@ -216,7 +216,7 @@ static void __init tauros2_internal_init(unsigned int features) */ feat = read_extra_features(); if (!(feat & 0x00400000)) { - printk(KERN_INFO "Tauros2: Enabling L2 cache.\n"); + pr_info("Tauros2: Enabling L2 cache.\n"); write_extra_features(feat | 0x00400000); } @@ -253,7 +253,7 @@ static void __init tauros2_internal_init(unsigned int features) */ actlr = read_actlr(); if (!(actlr & 0x00000002)) { - printk(KERN_INFO "Tauros2: Enabling L2 cache.\n"); + pr_info("Tauros2: Enabling L2 cache.\n"); write_actlr(actlr | 0x00000002); } @@ -262,11 +262,11 @@ static void __init tauros2_internal_init(unsigned int features) #endif if (mode == NULL) { - printk(KERN_CRIT "Tauros2: Unable to detect CPU mode.\n"); + pr_crit("Tauros2: Unable to detect CPU mode.\n"); return; } - printk(KERN_INFO "Tauros2: L2 cache support initialised " + pr_info("Tauros2: L2 cache support initialised " "in %s mode.\n", mode); } diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index ff379ac115df..d9e0d00a6699 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -235,7 +235,7 @@ void __init check_writebuffer_bugs(void) const char *reason; unsigned long v = 1; - printk(KERN_INFO "CPU: Testing write buffer coherency: "); + pr_info("CPU: Testing write buffer coherency: "); page = alloc_page(GFP_KERNEL); if (page) { @@ -261,9 +261,9 @@ void __init check_writebuffer_bugs(void) } if (v) { - printk("failed, %s\n", reason); + pr_cont("failed, %s\n", reason); shared_pte_mask = L_PTE_MT_UNCACHED; } else { - printk("ok\n"); + pr_cont("ok\n"); } } diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index eb8830a4c5ed..a982dc3190df 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -63,9 +63,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr) if (!mm) mm = &init_mm; - printk(KERN_ALERT "pgd = %p\n", mm->pgd); + pr_alert("pgd = %p\n", mm->pgd); pgd = pgd_offset(mm, addr); - printk(KERN_ALERT "[%08lx] *pgd=%08llx", + pr_alert("[%08lx] *pgd=%08llx", addr, (long long)pgd_val(*pgd)); do { @@ -77,31 +77,31 @@ void show_pte(struct mm_struct *mm, unsigned long addr) break; if (pgd_bad(*pgd)) { - printk("(bad)"); + pr_cont("(bad)"); break; } pud = pud_offset(pgd, addr); if (PTRS_PER_PUD != 1) - printk(", *pud=%08llx", (long long)pud_val(*pud)); + pr_cont(", *pud=%08llx", (long long)pud_val(*pud)); if (pud_none(*pud)) break; if (pud_bad(*pud)) { - printk("(bad)"); + pr_cont("(bad)"); break; } pmd = pmd_offset(pud, addr); if (PTRS_PER_PMD != 1) - printk(", *pmd=%08llx", (long long)pmd_val(*pmd)); + pr_cont(", *pmd=%08llx", (long long)pmd_val(*pmd)); if (pmd_none(*pmd)) break; if (pmd_bad(*pmd)) { - printk("(bad)"); + pr_cont("(bad)"); break; } @@ -110,15 +110,15 @@ void show_pte(struct mm_struct *mm, unsigned long addr) break; pte = pte_offset_map(pmd, addr); - printk(", *pte=%08llx", (long long)pte_val(*pte)); + pr_cont(", *pte=%08llx", (long long)pte_val(*pte)); #ifndef CONFIG_ARM_LPAE - printk(", *ppte=%08llx", + pr_cont(", *ppte=%08llx", (long long)pte_val(pte[PTE_HWTABLE_PTRS])); #endif pte_unmap(pte); } while(0); - printk("\n"); + pr_cont("\n"); } #else /* CONFIG_MMU */ void show_pte(struct mm_struct *mm, unsigned long addr) @@ -142,10 +142,9 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, * No handler, we'll have to terminate things with extreme prejudice. */ bust_spinlocks(1); - printk(KERN_ALERT - "Unable to handle kernel %s at virtual address %08lx\n", - (addr < PAGE_SIZE) ? "NULL pointer dereference" : - "paging request", addr); + pr_alert("Unable to handle kernel %s at virtual address %08lx\n", + (addr < PAGE_SIZE) ? "NULL pointer dereference" : + "paging request", addr); show_pte(mm, addr); die("Oops", regs, fsr); @@ -551,7 +550,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) return; - printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", + pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); info.si_signo = inf->sig; @@ -583,7 +582,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) return; - printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", + pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", inf->name, ifsr, addr); info.si_signo = inf->sig; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 92bba32d9230..6ca53c338519 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -67,7 +67,7 @@ early_param("initrd", early_initrd); static int __init parse_tag_initrd(const struct tag *tag) { - printk(KERN_WARNING "ATAG_INITRD is deprecated; " + pr_warn("ATAG_INITRD is deprecated; " "please update your bootloader.\n"); phys_initrd_start = __virt_to_phys(tag->u.initrd.start); phys_initrd_size = tag->u.initrd.size; @@ -544,7 +544,7 @@ void __init mem_init(void) #define MLM(b, t) b, t, ((t) - (b)) >> 20 #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) - printk(KERN_NOTICE "Virtual kernel memory layout:\n" + pr_notice("Virtual kernel memory layout:\n" " vector : 0x%08lx - 0x%08lx (%4ld kB)\n" #ifdef CONFIG_HAVE_TCM " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n" diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9f98cec7fe1e..d028dc74a9d5 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -192,7 +192,7 @@ early_param("cachepolicy", early_cachepolicy); static int __init early_nocache(char *__unused) { char *p = "buffered"; - printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); + pr_warn("nocache is deprecated; use cachepolicy=%s\n", p); early_cachepolicy(p); return 0; } @@ -201,7 +201,7 @@ early_param("nocache", early_nocache); static int __init early_nowrite(char *__unused) { char *p = "uncached"; - printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); + pr_warn("nowb is deprecated; use cachepolicy=%s\n", p); early_cachepolicy(p); return 0; } @@ -786,8 +786,7 @@ static void __init create_36bit_mapping(struct map_desc *md, length = PAGE_ALIGN(md->length); if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { - printk(KERN_ERR "MM: CPU does not support supersection " - "mapping for 0x%08llx at 0x%08lx\n", + pr_err("MM: CPU does not support supersection mapping for 0x%08llx at 0x%08lx\n", (long long)__pfn_to_phys((u64)md->pfn), addr); return; } @@ -799,15 +798,13 @@ static void __init create_36bit_mapping(struct map_desc *md, * of the actual domain assignments in use. */ if (type->domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", + pr_err("MM: invalid domain in supersection mapping for 0x%08llx at 0x%08lx\n", (long long)__pfn_to_phys((u64)md->pfn), addr); return; } if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for 0x%08llx" - " at 0x%08lx invalid alignment\n", + pr_err("MM: cannot create mapping for 0x%08llx at 0x%08lx invalid alignment\n", (long long)__pfn_to_phys((u64)md->pfn), addr); return; } @@ -850,18 +847,16 @@ static void __init create_mapping(struct map_desc *md) pgd_t *pgd; if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { - printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx" - " at 0x%08lx in user region\n", - (long long)__pfn_to_phys((u64)md->pfn), md->virtual); + pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n", + (long long)__pfn_to_phys((u64)md->pfn), md->virtual); return; } if ((md->type == MT_DEVICE || md->type == MT_ROM) && md->virtual >= PAGE_OFFSET && (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { - printk(KERN_WARNING "BUG: mapping for 0x%08llx" - " at 0x%08lx out of vmalloc space\n", - (long long)__pfn_to_phys((u64)md->pfn), md->virtual); + pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n", + (long long)__pfn_to_phys((u64)md->pfn), md->virtual); } type = &mem_types[md->type]; @@ -881,9 +876,8 @@ static void __init create_mapping(struct map_desc *md) length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { - printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not " - "be mapped using pages, ignoring.\n", - (long long)__pfn_to_phys(md->pfn), addr); + pr_warn("BUG: map for 0x%08llx at 0x%08lx can not be mapped using pages, ignoring.\n", + (long long)__pfn_to_phys(md->pfn), addr); return; } @@ -1053,15 +1047,13 @@ static int __init early_vmalloc(char *arg) if (vmalloc_reserve < SZ_16M) { vmalloc_reserve = SZ_16M; - printk(KERN_WARNING - "vmalloc area too small, limiting to %luMB\n", + pr_warn("vmalloc area too small, limiting to %luMB\n", vmalloc_reserve >> 20); } if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) { vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M); - printk(KERN_WARNING - "vmalloc area is too big, limiting to %luMB\n", + pr_warn("vmalloc area is too big, limiting to %luMB\n", vmalloc_reserve >> 20); } @@ -1094,7 +1086,7 @@ void __init sanity_check_meminfo(void) if (highmem) { pr_notice("Ignoring RAM at %pa-%pa (!CONFIG_HIGHMEM)\n", - &block_start, &block_end); + &block_start, &block_end); memblock_remove(reg->base, reg->size); continue; } @@ -1103,7 +1095,7 @@ void __init sanity_check_meminfo(void) phys_addr_t overlap_size = reg->size - size_limit; pr_notice("Truncating RAM at %pa-%pa to -%pa", - &block_start, &block_end, &vmalloc_limit); + &block_start, &block_end, &vmalloc_limit); memblock_remove(vmalloc_limit, overlap_size); block_end = vmalloc_limit; } diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c index 4e729f055a81..b2a9182acf14 100644 --- a/arch/arm/nwfpe/fpmodule.c +++ b/arch/arm/nwfpe/fpmodule.c @@ -86,12 +86,12 @@ extern void nwfpe_enter(void); static int __init fpe_init(void) { if (sizeof(FPA11) > sizeof(union fp_state)) { - printk(KERN_ERR "nwfpe: bad structure size\n"); + pr_err("nwfpe: bad structure size\n"); return -EINVAL; } if (sizeof(FPREG) != 12) { - printk(KERN_ERR "nwfpe: bad register size\n"); + pr_err("nwfpe: bad register size\n"); return -EINVAL; } if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 4f96c1617aae..f0465ba0f221 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -290,7 +290,7 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) u32 z, a; if ((significand & 0xc0000000) != 0x40000000) { - printk(KERN_WARNING "VFP: estimate_sqrt: invalid significand\n"); + pr_warn("VFP: estimate_sqrt: invalid significand\n"); } a = significand << 1; -- GitLab From 108900b54dce19aab3fa48adde7138ed868bb109 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 13:32:35 +0000 Subject: [PATCH 5690/9457] ARM: use pr_warn_ratelimited() when migrating IRQs Rather than open coding the printk_ratelimit() check with pr_warn(), use pr_warn_ratelimited() instead. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index f2fea6831cd5..ad857bada96c 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -135,7 +136,6 @@ int __init arch_probe_nr_irqs(void) #endif #ifdef CONFIG_HOTPLUG_CPU - static bool migrate_one_irq(struct irq_desc *desc) { struct irq_data *d = irq_desc_get_irq_data(desc); @@ -187,8 +187,8 @@ void migrate_irqs(void) affinity_broken = migrate_one_irq(desc); raw_spin_unlock(&desc->lock); - if (affinity_broken && printk_ratelimit()) - pr_warn("IRQ%u no longer affine to CPU%u\n", + if (affinity_broken) + pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n", i, smp_processor_id()); } -- GitLab From 8a2ab42b7586a78d6225771cf65bfb9df50b029f Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 12:06:55 +0000 Subject: [PATCH 5691/9457] ARM: drop nwfpe initialisation message from warning to info level nwfpe's initialisation message is not a warning, it is purely informational. Print it at the appropriate message level. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/nwfpe/fpmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c index b2a9182acf14..ec717c190e2c 100644 --- a/arch/arm/nwfpe/fpmodule.c +++ b/arch/arm/nwfpe/fpmodule.c @@ -98,8 +98,8 @@ static int __init fpe_init(void) return 0; /* Display title, version and copyright information. */ - printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" - NWFPE_BITS " precision)\n"); + pr_info("NetWinder Floating Point Emulator V0.97 (" + NWFPE_BITS " precision)\n"); thread_register_notifier(&nwfpe_notifier_block); -- GitLab From c68b0274fb3cf8b98c3696354833c03e49963bf4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 12:08:34 +0000 Subject: [PATCH 5692/9457] ARM: reduce "Booted secondary processor" message to debug level Drop the "CPUn: Booted secondary processor" message from info to debug level. We later print how many CPUs came online, so listing each one is redundant, and when using hotplug, can be quite noisy. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 3138d8ea9e55..7b18a1be179c 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -351,7 +351,7 @@ asmlinkage void secondary_start_kernel(void) cpu_init(); - pr_info("CPU%u: Booted secondary processor\n", cpu); + pr_debug("CPU%u: Booted secondary processor\n", cpu); preempt_disable(); trace_hardirqs_off(); -- GitLab From 1381c5a65fc6abc8b22f179da6a6577b0deb0687 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 12:13:59 +0000 Subject: [PATCH 5693/9457] ARM: remove "SMP: Total of %d processors activated." message The "SMP: Total of %d processors activated." message which we print in smp_cpus_done() provides no further information than the message in genreic code in smp_announce(). Kill it. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7b18a1be179c..5e6052e18850 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -387,9 +387,6 @@ asmlinkage void secondary_start_kernel(void) void __init smp_cpus_done(unsigned int max_cpus) { - pr_info("SMP: Total of %d processors activated.\n", - num_online_cpus()); - hyp_mode_check(); } -- GitLab From 719c9d1489bad6ff26fa1f6a7e3f760935663398 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 12:40:26 +0000 Subject: [PATCH 5694/9457] ARM: add machine name to stack dump output The generic dump_stack() code provides the facility to include the machine name in the stack dump, which can be useful information. Add a call to dump_stack_set_arch_desc() for the generic code to print this information. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c03106378b49..8361652b6dab 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -900,6 +900,7 @@ void __init setup_arch(char **cmdline_p) mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); machine_desc = mdesc; machine_name = mdesc->name; + dump_stack_set_arch_desc("%s", mdesc->name); if (mdesc->reboot_mode != REBOOT_HARD) reboot_mode = mdesc->reboot_mode; -- GitLab From 82112379b73c937576f40c99b4d93162343af6f9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 13:26:48 +0000 Subject: [PATCH 5695/9457] ARM: move ftrace assembly code to separate file The ftrace assembly code doesn't need to live in entry-common.S and be surrounded with #ifdef CONFIG_FUNCTION_TRACER. Instead, move it to its own file and conditionally assemble it. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/Makefile | 1 + arch/arm/kernel/entry-common.S | 235 ------------------------------- arch/arm/kernel/entry-ftrace.S | 243 +++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 235 deletions(-) create mode 100644 arch/arm/kernel/entry-ftrace.S diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 38ddd9f83d0e..738ebe5a91e6 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -47,6 +47,7 @@ endif obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o +obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 6bb09d4abdea..f8ccc21fa032 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -109,241 +109,6 @@ ENDPROC(ret_from_fork) #undef CALL #define CALL(x) .long x -#ifdef CONFIG_FUNCTION_TRACER -/* - * When compiling with -pg, gcc inserts a call to the mcount routine at the - * start of every function. In mcount, apart from the function's address (in - * lr), we need to get hold of the function's caller's address. - * - * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this: - * - * bl mcount - * - * These versions have the limitation that in order for the mcount routine to - * be able to determine the function's caller's address, an APCS-style frame - * pointer (which is set up with something like the code below) is required. - * - * mov ip, sp - * push {fp, ip, lr, pc} - * sub fp, ip, #4 - * - * With EABI, these frame pointers are not available unless -mapcs-frame is - * specified, and if building as Thumb-2, not even then. - * - * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount, - * with call sites like: - * - * push {lr} - * bl __gnu_mcount_nc - * - * With these compilers, frame pointers are not necessary. - * - * mcount can be thought of as a function called in the middle of a subroutine - * call. As such, it needs to be transparent for both the caller and the - * callee: the original lr needs to be restored when leaving mcount, and no - * registers should be clobbered. (In the __gnu_mcount_nc implementation, we - * clobber the ip register. This is OK because the ARM calling convention - * allows it to be clobbered in subroutines and doesn't use it to hold - * parameters.) - * - * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0" - * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see - * arch/arm/kernel/ftrace.c). - */ - -#ifndef CONFIG_OLD_MCOUNT -#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) -#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0. -#endif -#endif - -.macro mcount_adjust_addr rd, rn - bic \rd, \rn, #1 @ clear the Thumb bit if present - sub \rd, \rd, #MCOUNT_INSN_SIZE -.endm - -.macro __mcount suffix - mcount_enter - ldr r0, =ftrace_trace_function - ldr r2, [r0] - adr r0, .Lftrace_stub - cmp r0, r2 - bne 1f - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - ldr r1, =ftrace_graph_return - ldr r2, [r1] - cmp r0, r2 - bne ftrace_graph_caller\suffix - - ldr r1, =ftrace_graph_entry - ldr r2, [r1] - ldr r0, =ftrace_graph_entry_stub - cmp r0, r2 - bne ftrace_graph_caller\suffix -#endif - - mcount_exit - -1: mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function - adr lr, BSYM(2f) - mov pc, r2 -2: mcount_exit -.endm - -.macro __ftrace_caller suffix - mcount_enter - - mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function - - .globl ftrace_call\suffix -ftrace_call\suffix: - bl ftrace_stub - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - .globl ftrace_graph_call\suffix -ftrace_graph_call\suffix: - mov r0, r0 -#endif - - mcount_exit -.endm - -.macro __ftrace_graph_caller - sub r0, fp, #4 @ &lr of instrumented routine (&parent) -#ifdef CONFIG_DYNAMIC_FTRACE - @ called from __ftrace_caller, saved in mcount_enter - ldr r1, [sp, #16] @ instrumented routine (func) - mcount_adjust_addr r1, r1 -#else - @ called from __mcount, untouched in lr - mcount_adjust_addr r1, lr @ instrumented routine (func) -#endif - mov r2, fp @ frame pointer - bl prepare_ftrace_return - mcount_exit -.endm - -#ifdef CONFIG_OLD_MCOUNT -/* - * mcount - */ - -.macro mcount_enter - stmdb sp!, {r0-r3, lr} -.endm - -.macro mcount_get_lr reg - ldr \reg, [fp, #-4] -.endm - -.macro mcount_exit - ldr lr, [fp, #-4] - ldmia sp!, {r0-r3, pc} -.endm - -ENTRY(mcount) -#ifdef CONFIG_DYNAMIC_FTRACE - stmdb sp!, {lr} - ldr lr, [fp, #-4] - ldmia sp!, {pc} -#else - __mcount _old -#endif -ENDPROC(mcount) - -#ifdef CONFIG_DYNAMIC_FTRACE -ENTRY(ftrace_caller_old) - __ftrace_caller _old -ENDPROC(ftrace_caller_old) -#endif - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -ENTRY(ftrace_graph_caller_old) - __ftrace_graph_caller -ENDPROC(ftrace_graph_caller_old) -#endif - -.purgem mcount_enter -.purgem mcount_get_lr -.purgem mcount_exit -#endif - -/* - * __gnu_mcount_nc - */ - -.macro mcount_enter -/* - * This pad compensates for the push {lr} at the call site. Note that we are - * unable to unwind through a function which does not otherwise save its lr. - */ - UNWIND(.pad #4) - stmdb sp!, {r0-r3, lr} - UNWIND(.save {r0-r3, lr}) -.endm - -.macro mcount_get_lr reg - ldr \reg, [sp, #20] -.endm - -.macro mcount_exit - ldmia sp!, {r0-r3, ip, lr} - ret ip -.endm - -ENTRY(__gnu_mcount_nc) -UNWIND(.fnstart) -#ifdef CONFIG_DYNAMIC_FTRACE - mov ip, lr - ldmia sp!, {lr} - ret ip -#else - __mcount -#endif -UNWIND(.fnend) -ENDPROC(__gnu_mcount_nc) - -#ifdef CONFIG_DYNAMIC_FTRACE -ENTRY(ftrace_caller) -UNWIND(.fnstart) - __ftrace_caller -UNWIND(.fnend) -ENDPROC(ftrace_caller) -#endif - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -ENTRY(ftrace_graph_caller) -UNWIND(.fnstart) - __ftrace_graph_caller -UNWIND(.fnend) -ENDPROC(ftrace_graph_caller) -#endif - -.purgem mcount_enter -.purgem mcount_get_lr -.purgem mcount_exit - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - .globl return_to_handler -return_to_handler: - stmdb sp!, {r0-r3} - mov r0, fp @ frame pointer - bl ftrace_return_to_handler - mov lr, r0 @ r0 has real ret addr - ldmia sp!, {r0-r3} - ret lr -#endif - -ENTRY(ftrace_stub) -.Lftrace_stub: - ret lr -ENDPROC(ftrace_stub) - -#endif /* CONFIG_FUNCTION_TRACER */ - /*============================================================================= * SWI handler *----------------------------------------------------------------------------- diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S new file mode 100644 index 000000000000..fe57c73e70a4 --- /dev/null +++ b/arch/arm/kernel/entry-ftrace.S @@ -0,0 +1,243 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "entry-header.S" + +/* + * When compiling with -pg, gcc inserts a call to the mcount routine at the + * start of every function. In mcount, apart from the function's address (in + * lr), we need to get hold of the function's caller's address. + * + * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this: + * + * bl mcount + * + * These versions have the limitation that in order for the mcount routine to + * be able to determine the function's caller's address, an APCS-style frame + * pointer (which is set up with something like the code below) is required. + * + * mov ip, sp + * push {fp, ip, lr, pc} + * sub fp, ip, #4 + * + * With EABI, these frame pointers are not available unless -mapcs-frame is + * specified, and if building as Thumb-2, not even then. + * + * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount, + * with call sites like: + * + * push {lr} + * bl __gnu_mcount_nc + * + * With these compilers, frame pointers are not necessary. + * + * mcount can be thought of as a function called in the middle of a subroutine + * call. As such, it needs to be transparent for both the caller and the + * callee: the original lr needs to be restored when leaving mcount, and no + * registers should be clobbered. (In the __gnu_mcount_nc implementation, we + * clobber the ip register. This is OK because the ARM calling convention + * allows it to be clobbered in subroutines and doesn't use it to hold + * parameters.) + * + * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0" + * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see + * arch/arm/kernel/ftrace.c). + */ + +#ifndef CONFIG_OLD_MCOUNT +#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) +#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0. +#endif +#endif + +.macro mcount_adjust_addr rd, rn + bic \rd, \rn, #1 @ clear the Thumb bit if present + sub \rd, \rd, #MCOUNT_INSN_SIZE +.endm + +.macro __mcount suffix + mcount_enter + ldr r0, =ftrace_trace_function + ldr r2, [r0] + adr r0, .Lftrace_stub + cmp r0, r2 + bne 1f + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + ldr r1, =ftrace_graph_return + ldr r2, [r1] + cmp r0, r2 + bne ftrace_graph_caller\suffix + + ldr r1, =ftrace_graph_entry + ldr r2, [r1] + ldr r0, =ftrace_graph_entry_stub + cmp r0, r2 + bne ftrace_graph_caller\suffix +#endif + + mcount_exit + +1: mcount_get_lr r1 @ lr of instrumented func + mcount_adjust_addr r0, lr @ instrumented function + adr lr, BSYM(2f) + mov pc, r2 +2: mcount_exit +.endm + +.macro __ftrace_caller suffix + mcount_enter + + mcount_get_lr r1 @ lr of instrumented func + mcount_adjust_addr r0, lr @ instrumented function + + .globl ftrace_call\suffix +ftrace_call\suffix: + bl ftrace_stub + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .globl ftrace_graph_call\suffix +ftrace_graph_call\suffix: + mov r0, r0 +#endif + + mcount_exit +.endm + +.macro __ftrace_graph_caller + sub r0, fp, #4 @ &lr of instrumented routine (&parent) +#ifdef CONFIG_DYNAMIC_FTRACE + @ called from __ftrace_caller, saved in mcount_enter + ldr r1, [sp, #16] @ instrumented routine (func) + mcount_adjust_addr r1, r1 +#else + @ called from __mcount, untouched in lr + mcount_adjust_addr r1, lr @ instrumented routine (func) +#endif + mov r2, fp @ frame pointer + bl prepare_ftrace_return + mcount_exit +.endm + +#ifdef CONFIG_OLD_MCOUNT +/* + * mcount + */ + +.macro mcount_enter + stmdb sp!, {r0-r3, lr} +.endm + +.macro mcount_get_lr reg + ldr \reg, [fp, #-4] +.endm + +.macro mcount_exit + ldr lr, [fp, #-4] + ldmia sp!, {r0-r3, pc} +.endm + +ENTRY(mcount) +#ifdef CONFIG_DYNAMIC_FTRACE + stmdb sp!, {lr} + ldr lr, [fp, #-4] + ldmia sp!, {pc} +#else + __mcount _old +#endif +ENDPROC(mcount) + +#ifdef CONFIG_DYNAMIC_FTRACE +ENTRY(ftrace_caller_old) + __ftrace_caller _old +ENDPROC(ftrace_caller_old) +#endif + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(ftrace_graph_caller_old) + __ftrace_graph_caller +ENDPROC(ftrace_graph_caller_old) +#endif + +.purgem mcount_enter +.purgem mcount_get_lr +.purgem mcount_exit +#endif + +/* + * __gnu_mcount_nc + */ + +.macro mcount_enter +/* + * This pad compensates for the push {lr} at the call site. Note that we are + * unable to unwind through a function which does not otherwise save its lr. + */ + UNWIND(.pad #4) + stmdb sp!, {r0-r3, lr} + UNWIND(.save {r0-r3, lr}) +.endm + +.macro mcount_get_lr reg + ldr \reg, [sp, #20] +.endm + +.macro mcount_exit + ldmia sp!, {r0-r3, ip, lr} + ret ip +.endm + +ENTRY(__gnu_mcount_nc) +UNWIND(.fnstart) +#ifdef CONFIG_DYNAMIC_FTRACE + mov ip, lr + ldmia sp!, {lr} + ret ip +#else + __mcount +#endif +UNWIND(.fnend) +ENDPROC(__gnu_mcount_nc) + +#ifdef CONFIG_DYNAMIC_FTRACE +ENTRY(ftrace_caller) +UNWIND(.fnstart) + __ftrace_caller +UNWIND(.fnend) +ENDPROC(ftrace_caller) +#endif + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(ftrace_graph_caller) +UNWIND(.fnstart) + __ftrace_graph_caller +UNWIND(.fnend) +ENDPROC(ftrace_graph_caller) +#endif + +.purgem mcount_enter +.purgem mcount_get_lr +.purgem mcount_exit + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .globl return_to_handler +return_to_handler: + stmdb sp!, {r0-r3} + mov r0, fp @ frame pointer + bl ftrace_return_to_handler + mov lr, r0 @ r0 has real ret addr + ldmia sp!, {r0-r3} + ret lr +#endif + +ENTRY(ftrace_stub) +.Lftrace_stub: + ret lr +ENDPROC(ftrace_stub) -- GitLab From 296630c9c8c6ff5f116b417fafa6067d4c7a786e Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2014 13:31:04 +0000 Subject: [PATCH 5696/9457] ARM: io.c: clean up EXPORT_SYMBOL()s Place EXPORT_SYMBOL()s after the function definition. Tested-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/kernel/io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c index 9203cf883330..eedefe050022 100644 --- a/arch/arm/kernel/io.c +++ b/arch/arm/kernel/io.c @@ -51,6 +51,7 @@ void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count) from++; } } +EXPORT_SYMBOL(_memcpy_fromio); /* * Copy data from "real" memory space to IO memory space. @@ -66,6 +67,7 @@ void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count) to++; } } +EXPORT_SYMBOL(_memcpy_toio); /* * "memset" on IO memory space. @@ -79,7 +81,4 @@ void _memset_io(volatile void __iomem *dst, int c, size_t count) dst++; } } - -EXPORT_SYMBOL(_memcpy_fromio); -EXPORT_SYMBOL(_memcpy_toio); EXPORT_SYMBOL(_memset_io); -- GitLab From 1a28fc190c60e9bb04649384826f3224c8463efc Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Fri, 21 Nov 2014 19:06:15 +0800 Subject: [PATCH 5697/9457] ASoC: Intel: byt_rvp_platform_data can be static sound/soc/intel/sst/sst_acpi.c:124:26: sparse: symbol 'byt_rvp_platform_data' was not declared. Should it be static? Signed-off-by: Fengguang Wu Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index b261821163fa..f94f007a0e49 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c @@ -121,7 +121,7 @@ static const struct sst_res_info byt_rvp_res_info = { .acpi_ipc_irq_index = 5, }; -struct sst_platform_info byt_rvp_platform_data = { +static struct sst_platform_info byt_rvp_platform_data = { .probe_data = &byt_fwparse_info, .ipc_info = &byt_ipc_info, .lib_info = &byt_lib_dnld_info, -- GitLab From 04b74b27c2941e5d62120f6fee3a0a9388a30613 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 21 Nov 2014 09:16:58 -0500 Subject: [PATCH 5698/9457] printk/percpu: Define printk_func when printk is not defined To avoid include hell, the per_cpu variable printk_func was declared in percpu.h. But it is only defined if printk is defined. As users of printk may also use the printk_func variable, it needs to be defined even if CONFIG_PRINTK is not. Also add a printk.h include in percpu.h just to be safe. Link: http://lkml.kernel.org/r/20141121183215.01ba539c@canb.auug.org.au Reported-by: Stephen Rothwell Signed-off-by: Steven Rostedt --- include/linux/percpu.h | 1 + include/linux/printk.h | 4 ++-- kernel/printk/printk.c | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index ba2e85a0ff5b..caebf2a758dc 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/include/linux/printk.h b/include/linux/printk.h index 3bbd979d32fb..c69be9ee8f48 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -124,6 +124,8 @@ static inline __printf(1, 2) __cold void early_printk(const char *s, ...) { } #endif +typedef int(*printk_func_t)(const char *fmt, va_list args); + #ifdef CONFIG_PRINTK asmlinkage __printf(5, 0) int vprintk_emit(int facility, int level, @@ -162,8 +164,6 @@ extern int kptr_restrict; extern void wake_up_klogd(void); -typedef int(*printk_func_t)(const char *fmt, va_list args); - void log_buf_kexec_setup(void); void __init setup_log_buf(int early); void dump_stack_set_arch_desc(const char *fmt, ...); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f7b723f98cb9..5af2b8bc88f0 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1896,6 +1896,9 @@ static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, bool syslog, char *buf, size_t size) { return 0; } static size_t cont_print_text(char *text, size_t size) { return 0; } +/* Still needs to be defined for users */ +DEFINE_PER_CPU(printk_func_t, printk_func); + #endif /* CONFIG_PRINTK */ #ifdef CONFIG_EARLY_PRINTK -- GitLab From 6ef768fac9dfe3404d3fdc09909ea203a88f2f38 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 20 Nov 2014 13:45:31 +0100 Subject: [PATCH 5699/9457] kvm: x86: move ioapic.c and irq_comm.c back to arch/x86/ ia64 does not need them anymore. Ack notifiers become x86-specific too. Suggested-by: Gleb Natapov Reviewed-by: Radim Krcmar Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 16 ++++++++++++++++ arch/x86/kvm/Makefile | 5 ++--- {virt => arch/x86}/kvm/ioapic.c | 0 {virt => arch/x86}/kvm/ioapic.h | 1 - {virt => arch/x86}/kvm/irq_comm.c | 4 ++-- arch/x86/kvm/x86.c | 1 + include/linux/kvm_host.h | 22 ++++++++-------------- virt/kvm/eventfd.c | 7 ------- virt/kvm/kvm_main.c | 3 --- 9 files changed, 29 insertions(+), 30 deletions(-) rename {virt => arch/x86}/kvm/ioapic.c (100%) rename {virt => arch/x86}/kvm/ioapic.h (98%) rename {virt => arch/x86}/kvm/irq_comm.c (98%) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 769db36a3001..76ff3e2d8fd2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -603,6 +603,9 @@ struct kvm_arch { struct kvm_xen_hvm_config xen_hvm_config; + /* reads protected by irq_srcu, writes by irq_lock */ + struct hlist_head mask_notifier_list; + /* fields used by HYPER-V emulation */ u64 hv_guest_os_id; u64 hv_hypercall; @@ -819,6 +822,19 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, const void *val, int bytes); u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn); +struct kvm_irq_mask_notifier { + void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked); + int irq; + struct hlist_node link; +}; + +void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, + struct kvm_irq_mask_notifier *kimn); +void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, + struct kvm_irq_mask_notifier *kimn); +void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, + bool mask); + extern bool tdp_enabled; u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 25d22b2d6509..ee1cd92b03be 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -7,14 +7,13 @@ CFLAGS_vmx.o := -I. KVM := ../../../virt/kvm -kvm-y += $(KVM)/kvm_main.o $(KVM)/ioapic.o \ - $(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o \ +kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(KVM)/assigned-dev.o $(KVM)/iommu.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ - i8254.o cpuid.o pmu.o + i8254.o ioapic.o irq_comm.o cpuid.o pmu.o kvm-intel-y += vmx.o kvm-amd-y += svm.o diff --git a/virt/kvm/ioapic.c b/arch/x86/kvm/ioapic.c similarity index 100% rename from virt/kvm/ioapic.c rename to arch/x86/kvm/ioapic.c diff --git a/virt/kvm/ioapic.h b/arch/x86/kvm/ioapic.h similarity index 98% rename from virt/kvm/ioapic.h rename to arch/x86/kvm/ioapic.h index dc3baa3a538f..deac8d509f2a 100644 --- a/virt/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h @@ -96,7 +96,6 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, struct kvm_lapic_irq *irq, unsigned long *dest_map); int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); -void kvm_vcpu_request_scan_ioapic(struct kvm *kvm); void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, u32 *tmr); diff --git a/virt/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c similarity index 98% rename from virt/kvm/irq_comm.c rename to arch/x86/kvm/irq_comm.c index 1345bde064f5..e9c135b639aa 100644 --- a/virt/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c @@ -234,7 +234,7 @@ void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, { mutex_lock(&kvm->irq_lock); kimn->irq = irq; - hlist_add_head_rcu(&kimn->link, &kvm->mask_notifier_list); + hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list); mutex_unlock(&kvm->irq_lock); } @@ -256,7 +256,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, idx = srcu_read_lock(&kvm->irq_srcu); gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); if (gsi != -1) - hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link) + hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link) if (kimn->irq == gsi) kimn->func(kimn, mask); srcu_read_unlock(&kvm->irq_srcu, idx); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a8f53a6960fd..5337039427c8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7264,6 +7264,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (type) return -EINVAL; + INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list); INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ea53b04993f2..ded64cb3a081 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -395,7 +395,6 @@ struct kvm { * Update side is protected by irq_lock. */ struct kvm_irq_routing_table __rcu *irq_routing; - struct hlist_head mask_notifier_list; #endif #ifdef CONFIG_HAVE_KVM_IRQFD struct hlist_head irq_ack_notifier_list; @@ -447,6 +446,14 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); int __must_check vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); +#ifdef __KVM_HAVE_IOAPIC +void kvm_vcpu_request_scan_ioapic(struct kvm *kvm); +#else +static inline void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) +{ +} +#endif + #ifdef CONFIG_HAVE_KVM_IRQFD int kvm_irqfd_init(void); void kvm_irqfd_exit(void); @@ -736,19 +743,6 @@ struct kvm_assigned_dev_kernel { struct pci_saved_state *pci_saved_state; }; -struct kvm_irq_mask_notifier { - void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked); - int irq; - struct hlist_node link; -}; - -void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq, - struct kvm_irq_mask_notifier *kimn); -void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, - struct kvm_irq_mask_notifier *kimn); -void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, - bool mask); - int kvm_irq_map_gsi(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *entries, int gsi); int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin); diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index b0fb390943c6..148b2392c762 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -36,9 +36,6 @@ #include #include -#ifdef __KVM_HAVE_IOAPIC -#include "ioapic.h" -#endif #include "iodev.h" #ifdef CONFIG_HAVE_KVM_IRQFD @@ -492,9 +489,7 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm, mutex_lock(&kvm->irq_lock); hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); mutex_unlock(&kvm->irq_lock); -#ifdef __KVM_HAVE_IOAPIC kvm_vcpu_request_scan_ioapic(kvm); -#endif } void kvm_unregister_irq_ack_notifier(struct kvm *kvm, @@ -504,9 +499,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, hlist_del_init_rcu(&kian->link); mutex_unlock(&kvm->irq_lock); synchronize_srcu(&kvm->irq_srcu); -#ifdef __KVM_HAVE_IOAPIC kvm_vcpu_request_scan_ioapic(kvm); -#endif } #endif diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 751ece6a595c..3be43424818b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -468,9 +468,6 @@ static struct kvm *kvm_create_vm(unsigned long type) if (r) goto out_err_no_disable; -#ifdef CONFIG_HAVE_KVM_IRQCHIP - INIT_HLIST_HEAD(&kvm->mask_notifier_list); -#endif #ifdef CONFIG_HAVE_KVM_IRQFD INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); #endif -- GitLab From 3bf58e9ae8802bbb6af722a2e7dc4c4d21110c5a Mon Sep 17 00:00:00 2001 From: Radim Krcmar Date: Fri, 21 Nov 2014 18:06:19 +0100 Subject: [PATCH 5700/9457] kvm: remove CONFIG_X86 #ifdefs from files formerly shared with ia64 Signed-off-by: Radim Krcmar Signed-off-by: Paolo Bonzini --- arch/x86/kvm/ioapic.c | 7 ------- arch/x86/kvm/irq_comm.c | 19 ++----------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index f0f7ef82b7a6..b1947e0f3e10 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -270,7 +270,6 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, spin_unlock(&ioapic->lock); } -#ifdef CONFIG_X86 void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) { struct kvm_ioapic *ioapic = kvm->arch.vioapic; @@ -279,12 +278,6 @@ void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) return; kvm_make_scan_ioapic_request(kvm); } -#else -void kvm_vcpu_request_scan_ioapic(struct kvm *kvm) -{ - return; -} -#endif static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) { diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c index e9c135b639aa..72298b3ac025 100644 --- a/arch/x86/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c @@ -35,12 +35,8 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, int irq_source_id, int level, bool line_status) { -#ifdef CONFIG_X86 struct kvm_pic *pic = pic_irqchip(kvm); return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); -#else - return -1; -#endif } static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, @@ -194,9 +190,7 @@ int kvm_request_irq_source_id(struct kvm *kvm) } ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); -#ifdef CONFIG_X86 ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); -#endif set_bit(irq_source_id, bitmap); unlock: mutex_unlock(&kvm->irq_lock); @@ -207,9 +201,7 @@ int kvm_request_irq_source_id(struct kvm *kvm) void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) { ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); -#ifdef CONFIG_X86 ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID); -#endif mutex_lock(&kvm->irq_lock); if (irq_source_id < 0 || @@ -222,9 +214,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) goto unlock; kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); -#ifdef CONFIG_X86 kvm_pic_clear_all(pic_irqchip(kvm), irq_source_id); -#endif unlock: mutex_unlock(&kvm->irq_lock); } @@ -314,16 +304,11 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, .u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } } #define ROUTING_ENTRY1(irq) IOAPIC_ROUTING_ENTRY(irq) -#ifdef CONFIG_X86 -# define PIC_ROUTING_ENTRY(irq) \ +#define PIC_ROUTING_ENTRY(irq) \ { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ .u.irqchip = { .irqchip = SELECT_PIC(irq), .pin = (irq) % 8 } } -# define ROUTING_ENTRY2(irq) \ +#define ROUTING_ENTRY2(irq) \ IOAPIC_ROUTING_ENTRY(irq), PIC_ROUTING_ENTRY(irq) -#else -# define ROUTING_ENTRY2(irq) \ - IOAPIC_ROUTING_ENTRY(irq) -#endif static const struct kvm_irq_routing_entry default_routing[] = { ROUTING_ENTRY2(0), ROUTING_ENTRY2(1), -- GitLab From 6b397158d07f885154b871a15f879d25b3de7579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 20 Nov 2014 14:43:18 +0100 Subject: [PATCH 5701/9457] kvm: remove IA64 ioctls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KVM ia64 is no longer present so new applications shouldn't use them. The main problem is that they most likely didn't work even before, because of a conflict in the #defines: #define KVM_SET_GUEST_DEBUG _IOW(KVMIO, 0x9b, struct kvm_guest_debug) #define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *) The argument to KVM_SET_GUEST_DEBUG is: struct kvm_guest_debug { __u32 control; __u32 pad; struct kvm_guest_debug_arch arch; }; struct kvm_guest_debug_arch { }; meaning that sizeof(struct kvm_guest_debug) == sizeof(void *) == 8 and KVM_SET_GUEST_DEBUG == KVM_IA64_VCPU_SET_STACK. KVM_SET_GUEST_DEBUG is handled in virt/kvm/kvm_main.c before even calling kvm_arch_vcpu_ioctl (which would have handled KVM_IA64_VCPU_SET_STACK), so KVM_IA64_VCPU_SET_STACK would just return -EINVAL. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- include/uapi/linux/kvm.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 6d59e5b39c9c..a37fd1224f36 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1099,9 +1099,6 @@ struct kvm_s390_ucas_mapping { #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) #define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) -/* IA64 stack access */ -#define KVM_IA64_VCPU_GET_STACK _IOR(KVMIO, 0x9a, void *) -#define KVM_IA64_VCPU_SET_STACK _IOW(KVMIO, 0x9b, void *) /* Available with KVM_CAP_VCPU_EVENTS */ #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) -- GitLab From 3819ffdff70da4c0d3bab0f8becabfc6936a230c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 20:48:26 +0100 Subject: [PATCH 5702/9457] mISDN: Deletion of unnecessary checks before the function call "vfree" The vfree() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/isdn/mISDN/l1oip_codec.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c index a601c8472220..9b033be11a5f 100644 --- a/drivers/isdn/mISDN/l1oip_codec.c +++ b/drivers/isdn/mISDN/l1oip_codec.c @@ -312,10 +312,8 @@ l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result) void l1oip_4bit_free(void) { - if (table_dec) - vfree(table_dec); - if (table_com) - vfree(table_com); + vfree(table_dec); + vfree(table_com); table_com = NULL; table_dec = NULL; } -- GitLab From f8e34d246c7d89e13399b410f92234acd2f7411a Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan <_govind@gmx.com> Date: Wed, 19 Nov 2014 12:59:32 +0530 Subject: [PATCH 5703/9457] enic: support skb->xmit_more Check and update posted_index only when skb->xmit_more is 0 or tx queue is full. v2: use txq_map instead of skb_get_queue_mapping(skb) Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic_main.c | 8 ++++++-- drivers/net/ethernet/cisco/enic/vnic_wq.h | 20 +++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 5afe360c7e89..b9cda2fc5ae8 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -533,6 +533,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, struct vnic_wq *wq; unsigned long flags; unsigned int txq_map; + struct netdev_queue *txq; if (skb->len <= 0) { dev_kfree_skb_any(skb); @@ -541,6 +542,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, txq_map = skb_get_queue_mapping(skb) % enic->wq_count; wq = &enic->wq[txq_map]; + txq = netdev_get_tx_queue(netdev, txq_map); /* Non-TSO sends must fit within ENIC_NON_TSO_MAX_DESC descs, * which is very likely. In the off chance it's going to take @@ -558,7 +560,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, if (vnic_wq_desc_avail(wq) < skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { - netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map)); + netif_tx_stop_queue(txq); /* This is a hard error, log it */ netdev_err(netdev, "BUG! Tx ring full when queue awake!\n"); spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); @@ -568,7 +570,9 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, enic_queue_wq_skb(enic, wq, skb); if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS) - netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map)); + netif_tx_stop_queue(txq); + if (!skb->xmit_more || netif_xmit_stopped(txq)) + vnic_wq_doorbell(wq); spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h index 2c6c70804a39..816f1ad6072f 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_wq.h +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h @@ -104,6 +104,17 @@ static inline void *vnic_wq_next_desc(struct vnic_wq *wq) return wq->to_use->desc; } +static inline void vnic_wq_doorbell(struct vnic_wq *wq) +{ + /* Adding write memory barrier prevents compiler and/or CPU + * reordering, thus avoiding descriptor posting before + * descriptor is initialized. Otherwise, hardware can read + * stale descriptor fields. + */ + wmb(); + iowrite32(wq->to_use->index, &wq->ctrl->posted_index); +} + static inline void vnic_wq_post(struct vnic_wq *wq, void *os_buf, dma_addr_t dma_addr, unsigned int len, int sop, int eop, @@ -122,15 +133,6 @@ static inline void vnic_wq_post(struct vnic_wq *wq, buf->wr_id = wrid; buf = buf->next; - if (eop) { - /* Adding write memory barrier prevents compiler and/or CPU - * reordering, thus avoiding descriptor posting before - * descriptor is initialized. Otherwise, hardware can read - * stale descriptor fields. - */ - wmb(); - iowrite32(buf->index, &wq->ctrl->posted_index); - } wq->to_use = buf; wq->ring.desc_avail -= desc_skip_cnt; -- GitLab From 2e95b2a8244bfd8993f55c993f1b7d33a89124e0 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Wed, 19 Nov 2014 09:06:51 +0000 Subject: [PATCH 5704/9457] sky2: use new netdev_rss_key_fill() helper Switch to a random RSS key rather than a fixed one. Using netdev_rss_key_fill helper also ensures that all ports share a common key. See also commit 960fb622f85180f36d3aff82af53e2be3db2f888. Signed-off-by: Ian Morris Cc: Mirko Lindner Cc: Stephen Hemminger Cc: Eric Dumazet Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/sky2.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index bd3366267039..53a1cc52d496 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1290,14 +1290,6 @@ static void rx_set_checksum(struct sky2_port *sky2) ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } -/* - * Fixed initial key as seed to RSS. - */ -static const uint32_t rss_init_key[10] = { - 0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43, - 0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30 -}; - /* Enable/disable receive hash calculation (RSS) */ static void rx_set_rss(struct net_device *dev, netdev_features_t features) { @@ -1313,9 +1305,12 @@ static void rx_set_rss(struct net_device *dev, netdev_features_t features) /* Program RSS initial values */ if (features & NETIF_F_RXHASH) { + u32 rss_key[10]; + + netdev_rss_key_fill(rss_key, sizeof(rss_key)); for (i = 0; i < nkeys; i++) sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), - rss_init_key[i]); + rss_key[i]); /* Need to turn on (undocumented) flag to make hashing work */ sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), -- GitLab From 1b65729a186b313420123f95c50dbb919569d0c9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 14 Nov 2014 06:10:26 -0300 Subject: [PATCH 5705/9457] [media] mach-omap2: remove deprecated VIDEO_OMAP2 support The omap2 camera driver has been deprecated for a year and is now going to be removed. It is unmaintained and it uses an internal API that has long since been superseded by a much better API. Worse, that internal API has been abused by out-of-kernel trees (i.MX6). In addition, Sakari stated that these drivers have never been in a usable state in the mainline kernel due to missing platform data. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Acked-by: Tony Lindgren Cc: David Cohen Signed-off-by: Mauro Carvalho Chehab --- arch/arm/mach-omap2/devices.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 324f02bf8a51..1b623a06cdcd 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -101,28 +101,6 @@ static int __init omap4_l3_init(void) } omap_postcore_initcall(omap4_l3_init); -#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) - -static struct resource omap2cam_resources[] = { - { - .start = OMAP24XX_CAMERA_BASE, - .end = OMAP24XX_CAMERA_BASE + 0xfff, - .flags = IORESOURCE_MEM, - }, - { - .start = 24 + OMAP_INTC_START, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device omap2cam_device = { - .name = "omap24xxcam", - .id = -1, - .num_resources = ARRAY_SIZE(omap2cam_resources), - .resource = omap2cam_resources, -}; -#endif - #if defined(CONFIG_IOMMU_API) #include @@ -245,14 +223,6 @@ int omap3_init_camera(struct isp_platform_data *pdata) #endif -static inline void omap_init_camera(void) -{ -#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) - if (cpu_is_omap24xx()) - platform_device_register(&omap2cam_device); -#endif -} - #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) static inline void __init omap_init_mbox(void) { @@ -431,7 +401,6 @@ static int __init omap2_init_devices(void) * in alphabetical order so they're easier to sort through. */ omap_init_audio(); - omap_init_camera(); /* If dtb is there, the devices will be created dynamically */ if (!of_have_populated_dt()) { omap_init_mbox(); -- GitLab From db85a0403be4a59cf536a25622fe110feefba8d3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 14 Nov 2014 10:19:47 +0100 Subject: [PATCH 5706/9457] [media] omap24xx/tcm825x: remove deprecated omap2 camera drivers. The omap2 camera driver and the tcm825x sensor driver have been deprecated for a year and are now being removed. They are unmaintained and they use an internal API that has long since been superseded by a much better API. Worse, that internal API has been abused by out-of-kernel trees (i.MX6). In addition, Sakari stated that these drivers have never been in a usable state in the mainline kernel due to missing platform data. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Cc: David Cohen Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/Kconfig | 2 - drivers/staging/media/Makefile | 1 - drivers/staging/media/omap24xx/Kconfig | 35 - drivers/staging/media/omap24xx/Makefile | 5 - .../staging/media/omap24xx/omap24xxcam-dma.c | 598 ------ drivers/staging/media/omap24xx/omap24xxcam.c | 1882 ----------------- drivers/staging/media/omap24xx/omap24xxcam.h | 596 ------ drivers/staging/media/omap24xx/tcm825x.c | 938 -------- drivers/staging/media/omap24xx/tcm825x.h | 200 -- .../staging/media/omap24xx/v4l2-int-device.c | 164 -- .../staging/media/omap24xx/v4l2-int-device.h | 305 --- 11 files changed, 4726 deletions(-) delete mode 100644 drivers/staging/media/omap24xx/Kconfig delete mode 100644 drivers/staging/media/omap24xx/Makefile delete mode 100644 drivers/staging/media/omap24xx/omap24xxcam-dma.c delete mode 100644 drivers/staging/media/omap24xx/omap24xxcam.c delete mode 100644 drivers/staging/media/omap24xx/omap24xxcam.h delete mode 100644 drivers/staging/media/omap24xx/tcm825x.c delete mode 100644 drivers/staging/media/omap24xx/tcm825x.h delete mode 100644 drivers/staging/media/omap24xx/v4l2-int-device.c delete mode 100644 drivers/staging/media/omap24xx/v4l2-int-device.h diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 273c44c41a33..96498b7fc20e 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -31,8 +31,6 @@ source "drivers/staging/media/mn88472/Kconfig" source "drivers/staging/media/mn88473/Kconfig" -source "drivers/staging/media/omap24xx/Kconfig" - source "drivers/staging/media/omap4iss/Kconfig" # Keep LIRC at the end, as it has sub-menus diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index bb2180083b22..97bfef97f838 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ -obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/ obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/ obj-$(CONFIG_DVB_MN88472) += mn88472/ obj-$(CONFIG_DVB_MN88473) += mn88473/ diff --git a/drivers/staging/media/omap24xx/Kconfig b/drivers/staging/media/omap24xx/Kconfig deleted file mode 100644 index 82e569a21c46..000000000000 --- a/drivers/staging/media/omap24xx/Kconfig +++ /dev/null @@ -1,35 +0,0 @@ -config VIDEO_V4L2_INT_DEVICE - tristate - -config VIDEO_OMAP2 - tristate "OMAP2 Camera Capture Interface driver (DEPRECATED)" - depends on VIDEO_DEV && ARCH_OMAP2 - select VIDEOBUF_DMA_SG - select VIDEO_V4L2_INT_DEVICE - ---help--- - This is a v4l2 driver for the TI OMAP2 camera capture interface - - It uses the deprecated int-device API. Since this driver is no - longer actively maintained and nobody is interested in converting - it to the subdev API, this driver will be removed soon. - - If you do want to keep this driver in the kernel, and are willing - to convert it to the subdev API, then please contact the linux-media - mailinglist. - -config VIDEO_TCM825X - tristate "TCM825x camera sensor support (DEPRECATED)" - depends on I2C && VIDEO_V4L2 - depends on MEDIA_CAMERA_SUPPORT - select VIDEO_V4L2_INT_DEVICE - ---help--- - This is a driver for the Toshiba TCM825x VGA camera sensor. - It is used for example in Nokia N800. - - It uses the deprecated int-device API. Since this driver is no - longer actively maintained and nobody is interested in converting - it to the subdev API, this driver will be removed soon. - - If you do want to keep this driver in the kernel, and are willing - to convert it to the subdev API, then please contact the linux-media - mailinglist. diff --git a/drivers/staging/media/omap24xx/Makefile b/drivers/staging/media/omap24xx/Makefile deleted file mode 100644 index c2e7175599c2..000000000000 --- a/drivers/staging/media/omap24xx/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o - -obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o -obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o -obj-$(CONFIG_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o diff --git a/drivers/staging/media/omap24xx/omap24xxcam-dma.c b/drivers/staging/media/omap24xx/omap24xxcam-dma.c deleted file mode 100644 index c427eb94ea66..000000000000 --- a/drivers/staging/media/omap24xx/omap24xxcam-dma.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * drivers/media/platform/omap24xxcam-dma.c - * - * Copyright (C) 2004 MontaVista Software, Inc. - * Copyright (C) 2004 Texas Instruments. - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * Based on code from Andy Lowe and - * David Cohen . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include - -#include "omap24xxcam.h" - -/* - * - * DMA hardware. - * - */ - -/* Ack all interrupt on CSR and IRQSTATUS_L0 */ -static void omap24xxcam_dmahw_ack_all(void __iomem *base) -{ - u32 csr; - int i; - - for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) { - csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i)); - /* ack interrupt in CSR */ - omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr); - } - omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf); -} - -/* Ack dmach on CSR and IRQSTATUS_L0 */ -static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach) -{ - u32 csr; - - csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach)); - /* ack interrupt in CSR */ - omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr); - /* ack interrupt in IRQSTATUS */ - omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach)); - - return csr; -} - -static int omap24xxcam_dmahw_running(void __iomem *base, int dmach) -{ - return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE; -} - -static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach, - dma_addr_t start, u32 len) -{ - omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), - CAMDMA_CCR_SEL_SRC_DST_SYNC - | CAMDMA_CCR_BS - | CAMDMA_CCR_DST_AMODE_POST_INC - | CAMDMA_CCR_SRC_AMODE_POST_INC - | CAMDMA_CCR_FS - | CAMDMA_CCR_WR_ACTIVE - | CAMDMA_CCR_RD_ACTIVE - | CAMDMA_CCR_SYNCHRO_CAMERA); - omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0); - omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len); - omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1); - omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach), - CAMDMA_CSDP_WRITE_MODE_POSTED - | CAMDMA_CSDP_DST_BURST_EN_32 - | CAMDMA_CSDP_DST_PACKED - | CAMDMA_CSDP_SRC_BURST_EN_32 - | CAMDMA_CSDP_SRC_PACKED - | CAMDMA_CSDP_DATA_TYPE_8BITS); - omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0); - omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start); - omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0); - omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD); - omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0); - omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0); - omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), - CAMDMA_CSR_MISALIGNED_ERR - | CAMDMA_CSR_SECURE_ERR - | CAMDMA_CSR_TRANS_ERR - | CAMDMA_CSR_BLOCK - | CAMDMA_CSR_DROP); - omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), - CAMDMA_CICR_MISALIGNED_ERR_IE - | CAMDMA_CICR_SECURE_ERR_IE - | CAMDMA_CICR_TRANS_ERR_IE - | CAMDMA_CICR_BLOCK_IE - | CAMDMA_CICR_DROP_IE); -} - -static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach) -{ - omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), - CAMDMA_CCR_SEL_SRC_DST_SYNC - | CAMDMA_CCR_BS - | CAMDMA_CCR_DST_AMODE_POST_INC - | CAMDMA_CCR_SRC_AMODE_POST_INC - | CAMDMA_CCR_ENABLE - | CAMDMA_CCR_FS - | CAMDMA_CCR_SYNCHRO_CAMERA); -} - -static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach, - int free_dmach) -{ - int prev_dmach, ch; - - if (dmach == 0) - prev_dmach = NUM_CAMDMA_CHANNELS - 1; - else - prev_dmach = dmach - 1; - omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach), - CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach); - /* Did we chain the DMA transfer before the previous one - * finished? - */ - ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS; - while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch)) - & CAMDMA_CCR_ENABLE)) { - if (ch == dmach) { - /* The previous transfer has ended and this one - * hasn't started, so we must not have chained - * to the previous one in time. We'll have to - * start it now. - */ - omap24xxcam_dmahw_transfer_start(base, dmach); - break; - } - ch = (ch + 1) % NUM_CAMDMA_CHANNELS; - } -} - -/* Abort all chained DMA transfers. After all transfers have been - * aborted and the DMA controller is idle, the completion routines for - * any aborted transfers will be called in sequence. The DMA - * controller may not be idle after this routine completes, because - * the completion routines might start new transfers. - */ -static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach) -{ - /* mask all interrupts from this channel */ - omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0); - /* unlink this channel */ - omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0, - CAMDMA_CLNK_CTRL_ENABLE_LNK); - /* disable this channel */ - omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE); -} - -static void omap24xxcam_dmahw_init(void __iomem *base) -{ - omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG, - CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY - | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE - | CAMDMA_OCP_SYSCONFIG_AUTOIDLE); - - omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10, - CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH); - - omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf); -} - -/* - * - * Individual DMA channel handling. - * - */ - -/* Start a DMA transfer from the camera to memory. - * Returns zero if the transfer was successfully started, or non-zero if all - * DMA channels are already in use or starting is currently inhibited. - */ -static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start, - u32 len, dma_callback_t callback, void *arg) -{ - unsigned long flags; - int dmach; - - spin_lock_irqsave(&dma->lock, flags); - - if (!dma->free_dmach || atomic_read(&dma->dma_stop)) { - spin_unlock_irqrestore(&dma->lock, flags); - return -EBUSY; - } - - dmach = dma->next_dmach; - - dma->ch_state[dmach].callback = callback; - dma->ch_state[dmach].arg = arg; - - omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len); - - /* We're ready to start the DMA transfer. */ - - if (dma->free_dmach < NUM_CAMDMA_CHANNELS) { - /* A transfer is already in progress, so try to chain to it. */ - omap24xxcam_dmahw_transfer_chain(dma->base, dmach, - dma->free_dmach); - } else { - /* No transfer is in progress, so we'll just start this one - * now. - */ - omap24xxcam_dmahw_transfer_start(dma->base, dmach); - } - - dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS; - dma->free_dmach--; - - spin_unlock_irqrestore(&dma->lock, flags); - - return 0; -} - -/* Abort all chained DMA transfers. After all transfers have been - * aborted and the DMA controller is idle, the completion routines for - * any aborted transfers will be called in sequence. The DMA - * controller may not be idle after this routine completes, because - * the completion routines might start new transfers. - */ -static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr) -{ - unsigned long flags; - int dmach, i, free_dmach; - dma_callback_t callback; - void *arg; - - spin_lock_irqsave(&dma->lock, flags); - - /* stop any DMA transfers in progress */ - dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS; - for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) { - omap24xxcam_dmahw_abort_ch(dma->base, dmach); - dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS; - } - - /* We have to be careful here because the callback routine - * might start a new DMA transfer, and we only want to abort - * transfers that were started before this routine was called. - */ - free_dmach = dma->free_dmach; - while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) && - (free_dmach < NUM_CAMDMA_CHANNELS)) { - dmach = (dma->next_dmach + dma->free_dmach) - % NUM_CAMDMA_CHANNELS; - callback = dma->ch_state[dmach].callback; - arg = dma->ch_state[dmach].arg; - dma->free_dmach++; - free_dmach++; - if (callback) { - /* leave interrupts disabled during callback */ - spin_unlock(&dma->lock); - (*callback) (dma, csr, arg); - spin_lock(&dma->lock); - } - } - - spin_unlock_irqrestore(&dma->lock, flags); -} - -/* Abort all chained DMA transfers. After all transfers have been - * aborted and the DMA controller is idle, the completion routines for - * any aborted transfers will be called in sequence. If the completion - * routines attempt to start a new DMA transfer it will fail, so the - * DMA controller will be idle after this routine completes. - */ -static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr) -{ - atomic_inc(&dma->dma_stop); - omap24xxcam_dma_abort(dma, csr); - atomic_dec(&dma->dma_stop); -} - -/* Camera DMA interrupt service routine. */ -void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma) -{ - int dmach; - dma_callback_t callback; - void *arg; - u32 csr; - const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR - | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR - | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; - - spin_lock(&dma->lock); - - if (dma->free_dmach == NUM_CAMDMA_CHANNELS) { - /* A camera DMA interrupt occurred while all channels - * are idle, so we'll acknowledge the interrupt in the - * IRQSTATUS register and exit. - */ - omap24xxcam_dmahw_ack_all(dma->base); - spin_unlock(&dma->lock); - return; - } - - while (dma->free_dmach < NUM_CAMDMA_CHANNELS) { - dmach = (dma->next_dmach + dma->free_dmach) - % NUM_CAMDMA_CHANNELS; - if (omap24xxcam_dmahw_running(dma->base, dmach)) { - /* This buffer hasn't finished yet, so we're done. */ - break; - } - csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach); - if (csr & csr_error) { - /* A DMA error occurred, so stop all DMA - * transfers in progress. - */ - spin_unlock(&dma->lock); - omap24xxcam_dma_stop(dma, csr); - return; - } - callback = dma->ch_state[dmach].callback; - arg = dma->ch_state[dmach].arg; - dma->free_dmach++; - if (callback) { - spin_unlock(&dma->lock); - (*callback) (dma, csr, arg); - spin_lock(&dma->lock); - } - } - - spin_unlock(&dma->lock); - - omap24xxcam_sgdma_process( - container_of(dma, struct omap24xxcam_sgdma, dma)); -} - -void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma) -{ - unsigned long flags; - - spin_lock_irqsave(&dma->lock, flags); - - omap24xxcam_dmahw_init(dma->base); - - spin_unlock_irqrestore(&dma->lock, flags); -} - -static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma, - void __iomem *base) -{ - int ch; - - /* group all channels on DMA IRQ0 and unmask irq */ - spin_lock_init(&dma->lock); - dma->base = base; - dma->free_dmach = NUM_CAMDMA_CHANNELS; - dma->next_dmach = 0; - for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) { - dma->ch_state[ch].callback = NULL; - dma->ch_state[ch].arg = NULL; - } -} - -/* - * - * Scatter-gather DMA. - * - * High-level DMA construct for transferring whole picture frames to - * memory that is discontinuous. - * - */ - -/* DMA completion routine for the scatter-gather DMA fragments. */ -static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr, - void *arg) -{ - struct omap24xxcam_sgdma *sgdma = - container_of(dma, struct omap24xxcam_sgdma, dma); - int sgslot = (int)arg; - struct sgdma_state *sg_state; - const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR - | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR - | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; - - spin_lock(&sgdma->lock); - - /* We got an interrupt, we can remove the timer */ - del_timer(&sgdma->reset_timer); - - sg_state = sgdma->sg_state + sgslot; - if (!sg_state->queued_sglist) { - spin_unlock(&sgdma->lock); - printk(KERN_ERR "%s: sgdma completed when none queued!\n", - __func__); - return; - } - - sg_state->csr |= csr; - if (!--sg_state->queued_sglist) { - /* Queue for this sglist is empty, so check to see if we're - * done. - */ - if ((sg_state->next_sglist == sg_state->sglen) - || (sg_state->csr & csr_error)) { - sgdma_callback_t callback = sg_state->callback; - void *arg = sg_state->arg; - u32 sg_csr = sg_state->csr; - /* All done with this sglist */ - sgdma->free_sgdma++; - if (callback) { - spin_unlock(&sgdma->lock); - (*callback) (sgdma, sg_csr, arg); - return; - } - } - } - - spin_unlock(&sgdma->lock); -} - -/* Start queued scatter-gather DMA transfers. */ -void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma) -{ - unsigned long flags; - int queued_sgdma, sgslot; - struct sgdma_state *sg_state; - const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR - | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR - | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; - - spin_lock_irqsave(&sgdma->lock, flags); - - queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma; - sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA; - while (queued_sgdma > 0) { - sg_state = sgdma->sg_state + sgslot; - while ((sg_state->next_sglist < sg_state->sglen) && - !(sg_state->csr & csr_error)) { - const struct scatterlist *sglist; - unsigned int len; - - sglist = sg_state->sglist + sg_state->next_sglist; - /* try to start the next DMA transfer */ - if (sg_state->next_sglist + 1 == sg_state->sglen) { - /* - * On the last sg, we handle the case where - * cam->img.pix.sizeimage % PAGE_ALIGN != 0 - */ - len = sg_state->len - sg_state->bytes_read; - } else { - len = sg_dma_len(sglist); - } - - if (omap24xxcam_dma_start(&sgdma->dma, - sg_dma_address(sglist), - len, - omap24xxcam_sgdma_callback, - (void *)sgslot)) { - /* DMA start failed */ - spin_unlock_irqrestore(&sgdma->lock, flags); - return; - } - /* DMA start was successful */ - sg_state->next_sglist++; - sg_state->bytes_read += len; - sg_state->queued_sglist++; - - /* We start the reset timer */ - mod_timer(&sgdma->reset_timer, jiffies + HZ); - } - queued_sgdma--; - sgslot = (sgslot + 1) % NUM_SG_DMA; - } - - spin_unlock_irqrestore(&sgdma->lock, flags); -} - -/* - * Queue a scatter-gather DMA transfer from the camera to memory. - * Returns zero if the transfer was successfully queued, or non-zero - * if all of the scatter-gather slots are already in use. - */ -int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, - const struct scatterlist *sglist, int sglen, - int len, sgdma_callback_t callback, void *arg) -{ - unsigned long flags; - struct sgdma_state *sg_state; - - if ((sglen < 0) || ((sglen > 0) && !sglist)) - return -EINVAL; - - spin_lock_irqsave(&sgdma->lock, flags); - - if (!sgdma->free_sgdma) { - spin_unlock_irqrestore(&sgdma->lock, flags); - return -EBUSY; - } - - sg_state = sgdma->sg_state + sgdma->next_sgdma; - - sg_state->sglist = sglist; - sg_state->sglen = sglen; - sg_state->next_sglist = 0; - sg_state->bytes_read = 0; - sg_state->len = len; - sg_state->queued_sglist = 0; - sg_state->csr = 0; - sg_state->callback = callback; - sg_state->arg = arg; - - sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA; - sgdma->free_sgdma--; - - spin_unlock_irqrestore(&sgdma->lock, flags); - - omap24xxcam_sgdma_process(sgdma); - - return 0; -} - -/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress. - * Any queued scatter-gather DMA transactions that have not yet been started - * will remain queued. The DMA controller will be idle after this routine - * completes. When the scatter-gather queue is restarted, the next - * scatter-gather DMA transfer will begin at the start of a new transaction. - */ -void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma) -{ - unsigned long flags; - int sgslot; - struct sgdma_state *sg_state; - u32 csr = CAMDMA_CSR_TRANS_ERR; - - /* stop any DMA transfers in progress */ - omap24xxcam_dma_stop(&sgdma->dma, csr); - - spin_lock_irqsave(&sgdma->lock, flags); - - if (sgdma->free_sgdma < NUM_SG_DMA) { - sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA; - sg_state = sgdma->sg_state + sgslot; - if (sg_state->next_sglist != 0) { - /* This DMA transfer was in progress, so abort it. */ - sgdma_callback_t callback = sg_state->callback; - void *arg = sg_state->arg; - - sgdma->free_sgdma++; - if (callback) { - /* leave interrupts masked */ - spin_unlock(&sgdma->lock); - (*callback) (sgdma, csr, arg); - spin_lock(&sgdma->lock); - } - } - } - - spin_unlock_irqrestore(&sgdma->lock, flags); -} - -void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, - void __iomem *base, - void (*reset_callback)(unsigned long data), - unsigned long reset_callback_data) -{ - int sg; - - spin_lock_init(&sgdma->lock); - sgdma->free_sgdma = NUM_SG_DMA; - sgdma->next_sgdma = 0; - for (sg = 0; sg < NUM_SG_DMA; sg++) { - sgdma->sg_state[sg].sglen = 0; - sgdma->sg_state[sg].next_sglist = 0; - sgdma->sg_state[sg].bytes_read = 0; - sgdma->sg_state[sg].queued_sglist = 0; - sgdma->sg_state[sg].csr = 0; - sgdma->sg_state[sg].callback = NULL; - sgdma->sg_state[sg].arg = NULL; - } - - omap24xxcam_dma_init(&sgdma->dma, base); - setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data); -} diff --git a/drivers/staging/media/omap24xx/omap24xxcam.c b/drivers/staging/media/omap24xx/omap24xxcam.c deleted file mode 100644 index d590b3e8b70c..000000000000 --- a/drivers/staging/media/omap24xx/omap24xxcam.c +++ /dev/null @@ -1,1882 +0,0 @@ -/* - * drivers/media/platform/omap24xxcam.c - * - * OMAP 2 camera block driver. - * - * Copyright (C) 2004 MontaVista Software, Inc. - * Copyright (C) 2004 Texas Instruments. - * Copyright (C) 2007-2008 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * Based on code from Andy Lowe - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include /* needed for videobufs */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "omap24xxcam.h" - -#define OMAP24XXCAM_VERSION "0.0.1" - -#define RESET_TIMEOUT_NS 10000 - -static void omap24xxcam_reset(struct omap24xxcam_device *cam); -static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam); -static void omap24xxcam_device_unregister(struct v4l2_int_device *s); -static int omap24xxcam_remove(struct platform_device *pdev); - -/* module parameters */ -static int video_nr = -1; /* video device minor (-1 ==> auto assign) */ -/* - * Maximum amount of memory to use for capture buffers. - * Default is 4800KB, enough to double-buffer SXGA. - */ -static int capture_mem = 1280 * 960 * 2 * 2; - -static struct v4l2_int_device omap24xxcam; - -/* - * - * Clocks. - * - */ - -static void omap24xxcam_clock_put(struct omap24xxcam_device *cam) -{ - if (cam->ick != NULL && !IS_ERR(cam->ick)) - clk_put(cam->ick); - if (cam->fck != NULL && !IS_ERR(cam->fck)) - clk_put(cam->fck); - - cam->ick = cam->fck = NULL; -} - -static int omap24xxcam_clock_get(struct omap24xxcam_device *cam) -{ - int rval = 0; - - cam->fck = clk_get(cam->dev, "fck"); - if (IS_ERR(cam->fck)) { - dev_err(cam->dev, "can't get camera fck"); - rval = PTR_ERR(cam->fck); - omap24xxcam_clock_put(cam); - return rval; - } - - cam->ick = clk_get(cam->dev, "ick"); - if (IS_ERR(cam->ick)) { - dev_err(cam->dev, "can't get camera ick"); - rval = PTR_ERR(cam->ick); - omap24xxcam_clock_put(cam); - } - - return rval; -} - -static void omap24xxcam_clock_on(struct omap24xxcam_device *cam) -{ - clk_enable(cam->fck); - clk_enable(cam->ick); -} - -static void omap24xxcam_clock_off(struct omap24xxcam_device *cam) -{ - clk_disable(cam->fck); - clk_disable(cam->ick); -} - -/* - * - * Camera core - * - */ - -/* - * Set xclk. - * - * To disable xclk, use value zero. - */ -static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam, - u32 xclk) -{ - if (xclk) { - u32 divisor = CAM_MCLK / xclk; - - if (divisor == 1) - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, - CC_CTRL_XCLK, - CC_CTRL_XCLK_DIV_BYPASS); - else - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, - CC_CTRL_XCLK, divisor); - } else - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, - CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW); -} - -static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam) -{ - /* - * Setting the camera core AUTOIDLE bit causes problems with frame - * synchronization, so we will clear the AUTOIDLE bit instead. - */ - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG, - CC_SYSCONFIG_AUTOIDLE); - - /* program the camera interface DMA packet size */ - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA, - CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1)); - - /* enable camera core error interrupts */ - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE, - CC_IRQENABLE_FW_ERR_IRQ - | CC_IRQENABLE_FSC_ERR_IRQ - | CC_IRQENABLE_SSC_ERR_IRQ - | CC_IRQENABLE_FIFO_OF_IRQ); -} - -/* - * Enable the camera core. - * - * Data transfer to the camera DMA starts from next starting frame. - */ -static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam) -{ - - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL, - cam->cc_ctrl); -} - -/* - * Disable camera core. - * - * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The - * core internal state machines will be reset. Use - * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current - * frame completely. - */ -static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam) -{ - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL, - CC_CTRL_CC_RST); -} - -/* Interrupt service routine for camera core interrupts. */ -static void omap24xxcam_core_isr(struct omap24xxcam_device *cam) -{ - u32 cc_irqstatus; - const u32 cc_irqstatus_err = - CC_IRQSTATUS_FW_ERR_IRQ - | CC_IRQSTATUS_FSC_ERR_IRQ - | CC_IRQSTATUS_SSC_ERR_IRQ - | CC_IRQSTATUS_FIFO_UF_IRQ - | CC_IRQSTATUS_FIFO_OF_IRQ; - - cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET, - CC_IRQSTATUS); - omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS, - cc_irqstatus); - - if (cc_irqstatus & cc_irqstatus_err - && !atomic_read(&cam->in_reset)) { - dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n", - cc_irqstatus); - omap24xxcam_reset(cam); - } -} - -/* - * - * videobuf_buffer handling. - * - * Memory for mmapped videobuf_buffers is not allocated - * conventionally, but by several kmalloc allocations and then - * creating the scatterlist on our own. User-space buffers are handled - * normally. - * - */ - -/* - * Free the memory-mapped buffer memory allocated for a - * videobuf_buffer and the associated scatterlist. - */ -static void omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - size_t alloc_size; - struct page *page; - int i; - - if (dma->sglist == NULL) - return; - - i = dma->sglen; - while (i) { - i--; - alloc_size = sg_dma_len(&dma->sglist[i]); - page = sg_page(&dma->sglist[i]); - do { - ClearPageReserved(page++); - } while (alloc_size -= PAGE_SIZE); - __free_pages(sg_page(&dma->sglist[i]), - get_order(sg_dma_len(&dma->sglist[i]))); - } - - kfree(dma->sglist); - dma->sglist = NULL; -} - -/* Release all memory related to the videobuf_queue. */ -static void omap24xxcam_vbq_free_mmap_buffers(struct videobuf_queue *vbq) -{ - int i; - - mutex_lock(&vbq->vb_lock); - - for (i = 0; i < VIDEO_MAX_FRAME; i++) { - if (NULL == vbq->bufs[i]) - continue; - if (V4L2_MEMORY_MMAP != vbq->bufs[i]->memory) - continue; - vbq->ops->buf_release(vbq, vbq->bufs[i]); - omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]); - kfree(vbq->bufs[i]); - vbq->bufs[i] = NULL; - } - - mutex_unlock(&vbq->vb_lock); - - videobuf_mmap_free(vbq); -} - -/* - * Allocate physically as contiguous as possible buffer for video - * frame and allocate and build DMA scatter-gather list for it. - */ -static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb) -{ - unsigned int order; - size_t alloc_size, size = vb->bsize; /* vb->bsize is page aligned */ - struct page *page; - int max_pages, err = 0, i = 0; - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - - /* - * allocate maximum size scatter-gather list. Note this is - * overhead. We may not use as many entries as we allocate - */ - max_pages = vb->bsize >> PAGE_SHIFT; - dma->sglist = kcalloc(max_pages, sizeof(*dma->sglist), GFP_KERNEL); - if (dma->sglist == NULL) { - err = -ENOMEM; - goto out; - } - - while (size) { - order = get_order(size); - /* - * do not over-allocate even if we would get larger - * contiguous chunk that way - */ - if ((PAGE_SIZE << order) > size) - order--; - - /* try to allocate as many contiguous pages as possible */ - page = alloc_pages(GFP_KERNEL, order); - /* if allocation fails, try to allocate smaller amount */ - while (page == NULL) { - order--; - page = alloc_pages(GFP_KERNEL, order); - if (page == NULL && !order) { - err = -ENOMEM; - goto out; - } - } - size -= (PAGE_SIZE << order); - - /* append allocated chunk of pages into scatter-gather list */ - sg_set_page(&dma->sglist[i], page, PAGE_SIZE << order, 0); - dma->sglen++; - i++; - - alloc_size = (PAGE_SIZE << order); - - /* clear pages before giving them to user space */ - memset(page_address(page), 0, alloc_size); - - /* mark allocated pages reserved */ - do { - SetPageReserved(page++); - } while (alloc_size -= PAGE_SIZE); - } - /* - * REVISIT: not fully correct to assign nr_pages == sglen but - * video-buf is passing nr_pages for e.g. unmap_sg calls - */ - dma->nr_pages = dma->sglen; - dma->direction = PCI_DMA_FROMDEVICE; - - return 0; - -out: - omap24xxcam_vbq_free_mmap_buffer(vb); - return err; -} - -static int omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq, - unsigned int count) -{ - int i, err = 0; - struct omap24xxcam_fh *fh = - container_of(vbq, struct omap24xxcam_fh, vbq); - - mutex_lock(&vbq->vb_lock); - - for (i = 0; i < count; i++) { - err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]); - if (err) - goto out; - dev_dbg(fh->cam->dev, "sglen is %d for buffer %d\n", - videobuf_to_dma(vbq->bufs[i])->sglen, i); - } - - mutex_unlock(&vbq->vb_lock); - - return 0; -out: - while (i) { - i--; - omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]); - } - - mutex_unlock(&vbq->vb_lock); - - return err; -} - -/* - * This routine is called from interrupt context when a scatter-gather DMA - * transfer of a videobuf_buffer completes. - */ -static void omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma, - u32 csr, void *arg) -{ - struct omap24xxcam_device *cam = - container_of(sgdma, struct omap24xxcam_device, sgdma); - struct omap24xxcam_fh *fh = cam->streaming->private_data; - struct videobuf_buffer *vb = (struct videobuf_buffer *)arg; - const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR - | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR - | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP; - unsigned long flags; - - spin_lock_irqsave(&cam->core_enable_disable_lock, flags); - if (--cam->sgdma_in_queue == 0) - omap24xxcam_core_disable(cam); - spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); - - v4l2_get_timestamp(&vb->ts); - vb->field_count = atomic_add_return(2, &fh->field_count); - if (csr & csr_error) { - vb->state = VIDEOBUF_ERROR; - if (!atomic_read(&fh->cam->in_reset)) { - dev_dbg(cam->dev, "resetting camera, csr 0x%x\n", csr); - omap24xxcam_reset(cam); - } - } else - vb->state = VIDEOBUF_DONE; - wake_up(&vb->done); -} - -static void omap24xxcam_vbq_release(struct videobuf_queue *vbq, - struct videobuf_buffer *vb) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - - /* wait for buffer, especially to get out of the sgdma queue */ - videobuf_waiton(vbq, vb, 0, 0); - if (vb->memory == V4L2_MEMORY_MMAP) { - dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, - dma->direction); - dma->direction = DMA_NONE; - } else { - videobuf_dma_unmap(vbq->dev, videobuf_to_dma(vb)); - videobuf_dma_free(videobuf_to_dma(vb)); - } - - vb->state = VIDEOBUF_NEEDS_INIT; -} - -/* - * Limit the number of available kernel image capture buffers based on the - * number requested, the currently selected image size, and the maximum - * amount of memory permitted for kernel capture buffers. - */ -static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt, - unsigned int *size) -{ - struct omap24xxcam_fh *fh = vbq->priv_data; - - if (*cnt <= 0) - *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */ - - if (*cnt > VIDEO_MAX_FRAME) - *cnt = VIDEO_MAX_FRAME; - - *size = fh->pix.sizeimage; - - /* accessing fh->cam->capture_mem is ok, it's constant */ - if (*size * *cnt > fh->cam->capture_mem) - *cnt = fh->cam->capture_mem / *size; - - return 0; -} - -static int omap24xxcam_dma_iolock(struct videobuf_queue *vbq, - struct videobuf_dmabuf *dma) -{ - int err = 0; - - dma->direction = PCI_DMA_FROMDEVICE; - if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen, dma->direction)) { - kfree(dma->sglist); - dma->sglist = NULL; - dma->sglen = 0; - err = -EIO; - } - - return err; -} - -static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq, - struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct omap24xxcam_fh *fh = vbq->priv_data; - int err = 0; - - /* - * Accessing pix here is okay since it's constant while - * streaming is on (and we only get called then). - */ - if (vb->baddr) { - /* This is a userspace buffer. */ - if (fh->pix.sizeimage > vb->bsize) { - /* The buffer isn't big enough. */ - err = -EINVAL; - } else - vb->size = fh->pix.sizeimage; - } else { - if (vb->state != VIDEOBUF_NEEDS_INIT) { - /* - * We have a kernel bounce buffer that has - * already been allocated. - */ - if (fh->pix.sizeimage > vb->size) { - /* - * The image size has been changed to - * a larger size since this buffer was - * allocated, so we need to free and - * reallocate it. - */ - omap24xxcam_vbq_release(vbq, vb); - vb->size = fh->pix.sizeimage; - } - } else { - /* We need to allocate a new kernel bounce buffer. */ - vb->size = fh->pix.sizeimage; - } - } - - if (err) - return err; - - vb->width = fh->pix.width; - vb->height = fh->pix.height; - vb->field = field; - - if (vb->state == VIDEOBUF_NEEDS_INIT) { - if (vb->memory == V4L2_MEMORY_MMAP) - /* - * we have built the scatter-gather list by ourself so - * do the scatter-gather mapping as well - */ - err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb)); - else - err = videobuf_iolock(vbq, vb, NULL); - } - - if (!err) - vb->state = VIDEOBUF_PREPARED; - else - omap24xxcam_vbq_release(vbq, vb); - - return err; -} - -static void omap24xxcam_vbq_queue(struct videobuf_queue *vbq, - struct videobuf_buffer *vb) -{ - struct omap24xxcam_fh *fh = vbq->priv_data; - struct omap24xxcam_device *cam = fh->cam; - enum videobuf_state state = vb->state; - unsigned long flags; - int err; - - /* - * FIXME: We're marking the buffer active since we have no - * pretty way of marking it active exactly when the - * scatter-gather transfer starts. - */ - vb->state = VIDEOBUF_ACTIVE; - - err = omap24xxcam_sgdma_queue(&fh->cam->sgdma, - videobuf_to_dma(vb)->sglist, - videobuf_to_dma(vb)->sglen, vb->size, - omap24xxcam_vbq_complete, vb); - - if (!err) { - spin_lock_irqsave(&cam->core_enable_disable_lock, flags); - if (++cam->sgdma_in_queue == 1 - && !atomic_read(&cam->in_reset)) - omap24xxcam_core_enable(cam); - spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); - } else { - /* - * Oops. We're not supposed to get any errors here. - * The only way we could get an error is if we ran out - * of scatter-gather DMA slots, but we are supposed to - * have at least as many scatter-gather DMA slots as - * video buffers so that can't happen. - */ - dev_err(cam->dev, "failed to queue a video buffer for dma!\n"); - dev_err(cam->dev, "likely a bug in the driver!\n"); - vb->state = state; - } -} - -static struct videobuf_queue_ops omap24xxcam_vbq_ops = { - .buf_setup = omap24xxcam_vbq_setup, - .buf_prepare = omap24xxcam_vbq_prepare, - .buf_queue = omap24xxcam_vbq_queue, - .buf_release = omap24xxcam_vbq_release, -}; - -/* - * - * OMAP main camera system - * - */ - -/* - * Reset camera block to power-on state. - */ -static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam) -{ - int max_loop = RESET_TIMEOUT_NS; - - /* Reset whole camera subsystem */ - omap24xxcam_reg_out(cam->mmio_base, - CAM_SYSCONFIG, - CAM_SYSCONFIG_SOFTRESET); - - /* Wait till it's finished */ - while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS) - & CAM_SYSSTATUS_RESETDONE) - && --max_loop) { - ndelay(1); - } - - if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS) - & CAM_SYSSTATUS_RESETDONE)) - dev_err(cam->dev, "camera soft reset timeout\n"); -} - -/* - * (Re)initialise the camera block. - */ -static void omap24xxcam_hwinit(struct omap24xxcam_device *cam) -{ - omap24xxcam_poweron_reset(cam); - - /* set the camera subsystem autoidle bit */ - omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG, - CAM_SYSCONFIG_AUTOIDLE); - - /* set the camera MMU autoidle bit */ - omap24xxcam_reg_out(cam->mmio_base, - CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG, - CAMMMU_SYSCONFIG_AUTOIDLE); - - omap24xxcam_core_hwinit(cam); - - omap24xxcam_dma_hwinit(&cam->sgdma.dma); -} - -/* - * Callback for dma transfer stalling. - */ -static void omap24xxcam_stalled_dma_reset(unsigned long data) -{ - struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data; - - if (!atomic_read(&cam->in_reset)) { - dev_dbg(cam->dev, "dma stalled, resetting camera\n"); - omap24xxcam_reset(cam); - } -} - -/* - * Stop capture. Mark we're doing a reset, stop DMA transfers and - * core. (No new scatter-gather transfers will be queued whilst - * in_reset is non-zero.) - * - * If omap24xxcam_capture_stop is called from several places at - * once, only the first call will have an effect. Similarly, the last - * call omap24xxcam_streaming_cont will have effect. - * - * Serialisation is ensured by using cam->core_enable_disable_lock. - */ -static void omap24xxcam_capture_stop(struct omap24xxcam_device *cam) -{ - unsigned long flags; - - spin_lock_irqsave(&cam->core_enable_disable_lock, flags); - - if (atomic_inc_return(&cam->in_reset) != 1) { - spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); - return; - } - - omap24xxcam_core_disable(cam); - - spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); - - omap24xxcam_sgdma_sync(&cam->sgdma); -} - -/* - * Reset and continue streaming. - * - * Note: Resetting the camera FIFO via the CC_RST bit in the CC_CTRL - * register is supposed to be sufficient to recover from a camera - * interface error, but it doesn't seem to be enough. If we only do - * that then subsequent image captures are out of sync by either one - * or two times DMA_THRESHOLD bytes. Resetting and re-initializing the - * entire camera subsystem prevents the problem with frame - * synchronization. - */ -static void omap24xxcam_capture_cont(struct omap24xxcam_device *cam) -{ - unsigned long flags; - - spin_lock_irqsave(&cam->core_enable_disable_lock, flags); - - if (atomic_read(&cam->in_reset) != 1) - goto out; - - omap24xxcam_hwinit(cam); - - omap24xxcam_sensor_if_enable(cam); - - omap24xxcam_sgdma_process(&cam->sgdma); - - if (cam->sgdma_in_queue) - omap24xxcam_core_enable(cam); - -out: - atomic_dec(&cam->in_reset); - spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags); -} - -static ssize_t -omap24xxcam_streaming_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct omap24xxcam_device *cam = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", cam->streaming ? "active" : "inactive"); -} -static DEVICE_ATTR(streaming, S_IRUGO, omap24xxcam_streaming_show, NULL); - -/* - * Stop capture and restart it. I.e. reset the camera during use. - */ -static void omap24xxcam_reset(struct omap24xxcam_device *cam) -{ - omap24xxcam_capture_stop(cam); - omap24xxcam_capture_cont(cam); -} - -/* - * The main interrupt handler. - */ -static irqreturn_t omap24xxcam_isr(int irq, void *arg) -{ - struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg; - u32 irqstatus; - unsigned int irqhandled = 0; - - irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS); - - if (irqstatus & - (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1 - | CAM_IRQSTATUS_DMA_IRQ0)) { - omap24xxcam_dma_isr(&cam->sgdma.dma); - irqhandled = 1; - } - if (irqstatus & CAM_IRQSTATUS_CC_IRQ) { - omap24xxcam_core_isr(cam); - irqhandled = 1; - } - if (irqstatus & CAM_IRQSTATUS_MMU_IRQ) - dev_err(cam->dev, "unhandled camera MMU interrupt!\n"); - - return IRQ_RETVAL(irqhandled); -} - -/* - * - * Sensor handling. - * - */ - -/* - * Enable the external sensor interface. Try to negotiate interface - * parameters with the sensor and start using the new ones. The calls - * to sensor_if_enable and sensor_if_disable need not to be balanced. - */ -static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam) -{ - int rval; - struct v4l2_ifparm p; - - rval = vidioc_int_g_ifparm(cam->sdev, &p); - if (rval) { - dev_err(cam->dev, "vidioc_int_g_ifparm failed with %d\n", rval); - return rval; - } - - cam->if_type = p.if_type; - - cam->cc_ctrl = CC_CTRL_CC_EN; - - switch (p.if_type) { - case V4L2_IF_TYPE_BT656: - if (p.u.bt656.frame_start_on_rising_vs) - cam->cc_ctrl |= CC_CTRL_NOBT_SYNCHRO; - if (p.u.bt656.bt_sync_correct) - cam->cc_ctrl |= CC_CTRL_BT_CORRECT; - if (p.u.bt656.swap) - cam->cc_ctrl |= CC_CTRL_PAR_ORDERCAM; - if (p.u.bt656.latch_clk_inv) - cam->cc_ctrl |= CC_CTRL_PAR_CLK_POL; - if (p.u.bt656.nobt_hs_inv) - cam->cc_ctrl |= CC_CTRL_NOBT_HS_POL; - if (p.u.bt656.nobt_vs_inv) - cam->cc_ctrl |= CC_CTRL_NOBT_VS_POL; - - switch (p.u.bt656.mode) { - case V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT: - cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT8; - break; - case V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT: - cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT10; - break; - case V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT: - cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT12; - break; - case V4L2_IF_TYPE_BT656_MODE_BT_8BIT: - cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT8; - break; - case V4L2_IF_TYPE_BT656_MODE_BT_10BIT: - cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT10; - break; - default: - dev_err(cam->dev, - "bt656 interface mode %d not supported\n", - p.u.bt656.mode); - return -EINVAL; - } - /* - * The clock rate that the sensor wants has changed. - * We have to adjust the xclk from OMAP 2 side to - * match the sensor's wish as closely as possible. - */ - if (p.u.bt656.clock_curr != cam->if_u.bt656.xclk) { - u32 xclk = p.u.bt656.clock_curr; - u32 divisor; - - if (xclk == 0) - return -EINVAL; - - if (xclk > CAM_MCLK) - xclk = CAM_MCLK; - - divisor = CAM_MCLK / xclk; - if (divisor * xclk < CAM_MCLK) - divisor++; - if (CAM_MCLK / divisor < p.u.bt656.clock_min - && divisor > 1) - divisor--; - if (divisor > 30) - divisor = 30; - - xclk = CAM_MCLK / divisor; - - if (xclk < p.u.bt656.clock_min - || xclk > p.u.bt656.clock_max) - return -EINVAL; - - cam->if_u.bt656.xclk = xclk; - } - omap24xxcam_core_xclk_set(cam, cam->if_u.bt656.xclk); - break; - default: - /* FIXME: how about other interfaces? */ - dev_err(cam->dev, "interface type %d not supported\n", - p.if_type); - return -EINVAL; - } - - return 0; -} - -static void omap24xxcam_sensor_if_disable(const struct omap24xxcam_device *cam) -{ - switch (cam->if_type) { - case V4L2_IF_TYPE_BT656: - omap24xxcam_core_xclk_set(cam, 0); - break; - } -} - -/* - * Initialise the sensor hardware. - */ -static int omap24xxcam_sensor_init(struct omap24xxcam_device *cam) -{ - int err = 0; - struct v4l2_int_device *sdev = cam->sdev; - - omap24xxcam_clock_on(cam); - err = omap24xxcam_sensor_if_enable(cam); - if (err) { - dev_err(cam->dev, "sensor interface could not be enabled at " - "initialisation, %d\n", err); - cam->sdev = NULL; - goto out; - } - - /* power up sensor during sensor initialization */ - vidioc_int_s_power(sdev, 1); - - err = vidioc_int_dev_init(sdev); - if (err) { - dev_err(cam->dev, "cannot initialize sensor, error %d\n", err); - /* Sensor init failed --- it's nonexistent to us! */ - cam->sdev = NULL; - goto out; - } - - dev_info(cam->dev, "sensor is %s\n", sdev->name); - -out: - omap24xxcam_sensor_if_disable(cam); - omap24xxcam_clock_off(cam); - - vidioc_int_s_power(sdev, 0); - - return err; -} - -static void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam) -{ - if (cam->sdev) - vidioc_int_dev_exit(cam->sdev); -} - -static void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam) -{ - omap24xxcam_sensor_if_disable(cam); - omap24xxcam_clock_off(cam); - vidioc_int_s_power(cam->sdev, 0); -} - -/* - * Power-up and configure camera sensor. It's ready for capturing now. - */ -static int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam) -{ - int rval; - - omap24xxcam_clock_on(cam); - - omap24xxcam_sensor_if_enable(cam); - - rval = vidioc_int_s_power(cam->sdev, 1); - if (rval) - goto out; - - rval = vidioc_int_init(cam->sdev); - if (rval) - goto out; - - return 0; - -out: - omap24xxcam_sensor_disable(cam); - - return rval; -} - -static void omap24xxcam_sensor_reset_work(struct work_struct *work) -{ - struct omap24xxcam_device *cam = - container_of(work, struct omap24xxcam_device, - sensor_reset_work); - - if (atomic_read(&cam->reset_disable)) - return; - - omap24xxcam_capture_stop(cam); - - if (vidioc_int_reset(cam->sdev) == 0) { - vidioc_int_init(cam->sdev); - } else { - /* Can't reset it by vidioc_int_reset. */ - omap24xxcam_sensor_disable(cam); - omap24xxcam_sensor_enable(cam); - } - - omap24xxcam_capture_cont(cam); -} - -/* - * - * IOCTL interface. - * - */ - -static int vidioc_querycap(struct file *file, void *fh, - struct v4l2_capability *cap) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - - strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver)); - strlcpy(cap->card, cam->vfd->name, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_fmtdesc *f) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - - return vidioc_int_enum_fmt_cap(cam->sdev, f); -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - rval = vidioc_int_g_fmt_cap(cam->sdev, f); - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - if (cam->streaming) { - rval = -EBUSY; - goto out; - } - - rval = vidioc_int_s_fmt_cap(cam->sdev, f); - -out: - mutex_unlock(&cam->mutex); - - if (!rval) { - mutex_lock(&ofh->vbq.vb_lock); - ofh->pix = f->fmt.pix; - mutex_unlock(&ofh->vbq.vb_lock); - } - - memset(f, 0, sizeof(*f)); - vidioc_g_fmt_vid_cap(file, fh, f); - - return rval; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - rval = vidioc_int_try_fmt_cap(cam->sdev, f); - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_reqbufs(struct file *file, void *fh, - struct v4l2_requestbuffers *b) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - if (cam->streaming) { - mutex_unlock(&cam->mutex); - return -EBUSY; - } - - omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq); - mutex_unlock(&cam->mutex); - - rval = videobuf_reqbufs(&ofh->vbq, b); - - /* - * Either videobuf_reqbufs failed or the buffers are not - * memory-mapped (which would need special attention). - */ - if (rval < 0 || b->memory != V4L2_MEMORY_MMAP) - goto out; - - rval = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq, rval); - if (rval) - omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq); - -out: - return rval; -} - -static int vidioc_querybuf(struct file *file, void *fh, - struct v4l2_buffer *b) -{ - struct omap24xxcam_fh *ofh = fh; - - return videobuf_querybuf(&ofh->vbq, b); -} - -static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) -{ - struct omap24xxcam_fh *ofh = fh; - - return videobuf_qbuf(&ofh->vbq, b); -} - -static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - struct videobuf_buffer *vb; - int rval; - -videobuf_dqbuf_again: - rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK); - if (rval) - goto out; - - vb = ofh->vbq.bufs[b->index]; - - mutex_lock(&cam->mutex); - /* _needs_reset returns -EIO if reset is required. */ - rval = vidioc_int_g_needs_reset(cam->sdev, (void *)vb->baddr); - mutex_unlock(&cam->mutex); - if (rval == -EIO) - schedule_work(&cam->sensor_reset_work); - else - rval = 0; - -out: - /* - * This is a hack. We don't want to show -EIO to the user - * space. Requeue the buffer and try again if we're not doing - * this in non-blocking mode. - */ - if (rval == -EIO) { - videobuf_qbuf(&ofh->vbq, b); - if (!(file->f_flags & O_NONBLOCK)) - goto videobuf_dqbuf_again; - /* - * We don't have a videobuf_buffer now --- maybe next - * time... - */ - rval = -EAGAIN; - } - - return rval; -} - -static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - if (cam->streaming) { - rval = -EBUSY; - goto out; - } - - rval = omap24xxcam_sensor_if_enable(cam); - if (rval) { - dev_dbg(cam->dev, "vidioc_int_g_ifparm failed\n"); - goto out; - } - - rval = videobuf_streamon(&ofh->vbq); - if (!rval) { - cam->streaming = file; - sysfs_notify(&cam->dev->kobj, NULL, "streaming"); - } - -out: - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - struct videobuf_queue *q = &ofh->vbq; - int rval; - - atomic_inc(&cam->reset_disable); - - flush_work(&cam->sensor_reset_work); - - rval = videobuf_streamoff(q); - if (!rval) { - mutex_lock(&cam->mutex); - cam->streaming = NULL; - mutex_unlock(&cam->mutex); - sysfs_notify(&cam->dev->kobj, NULL, "streaming"); - } - - atomic_dec(&cam->reset_disable); - - return rval; -} - -static int vidioc_enum_input(struct file *file, void *fh, - struct v4l2_input *inp) -{ - if (inp->index > 0) - return -EINVAL; - - strlcpy(inp->name, "camera", sizeof(inp->name)); - inp->type = V4L2_INPUT_TYPE_CAMERA; - - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) -{ - *i = 0; - - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int i) -{ - if (i > 0) - return -EINVAL; - - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *fh, - struct v4l2_queryctrl *a) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - - return vidioc_int_queryctrl(cam->sdev, a); -} - -static int vidioc_g_ctrl(struct file *file, void *fh, - struct v4l2_control *a) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - rval = vidioc_int_g_ctrl(cam->sdev, a); - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_s_ctrl(struct file *file, void *fh, - struct v4l2_control *a) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - rval = vidioc_int_s_ctrl(cam->sdev, a); - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_g_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) { - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - int rval; - - mutex_lock(&cam->mutex); - rval = vidioc_int_g_parm(cam->sdev, a); - mutex_unlock(&cam->mutex); - - return rval; -} - -static int vidioc_s_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) -{ - struct omap24xxcam_fh *ofh = fh; - struct omap24xxcam_device *cam = ofh->cam; - struct v4l2_streamparm old_streamparm; - int rval; - - mutex_lock(&cam->mutex); - if (cam->streaming) { - rval = -EBUSY; - goto out; - } - - old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - rval = vidioc_int_g_parm(cam->sdev, &old_streamparm); - if (rval) - goto out; - - rval = vidioc_int_s_parm(cam->sdev, a); - if (rval) - goto out; - - rval = omap24xxcam_sensor_if_enable(cam); - /* - * Revert to old streaming parameters if enabling sensor - * interface with the new ones failed. - */ - if (rval) - vidioc_int_s_parm(cam->sdev, &old_streamparm); - -out: - mutex_unlock(&cam->mutex); - - return rval; -} - -/* - * - * File operations. - * - */ - -static unsigned int omap24xxcam_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct omap24xxcam_fh *fh = file->private_data; - struct omap24xxcam_device *cam = fh->cam; - struct videobuf_buffer *vb; - - mutex_lock(&cam->mutex); - if (cam->streaming != file) { - mutex_unlock(&cam->mutex); - return POLLERR; - } - mutex_unlock(&cam->mutex); - - mutex_lock(&fh->vbq.vb_lock); - if (list_empty(&fh->vbq.stream)) { - mutex_unlock(&fh->vbq.vb_lock); - return POLLERR; - } - vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream); - mutex_unlock(&fh->vbq.vb_lock); - - poll_wait(file, &vb->done, wait); - - if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR) - return POLLIN | POLLRDNORM; - - return 0; -} - -static int omap24xxcam_mmap_buffers(struct file *file, - struct vm_area_struct *vma) -{ - struct omap24xxcam_fh *fh = file->private_data; - struct omap24xxcam_device *cam = fh->cam; - struct videobuf_queue *vbq = &fh->vbq; - unsigned int first, last, size, i, j; - int err = 0; - - mutex_lock(&cam->mutex); - if (cam->streaming) { - mutex_unlock(&cam->mutex); - return -EBUSY; - } - mutex_unlock(&cam->mutex); - mutex_lock(&vbq->vb_lock); - - /* look for first buffer to map */ - for (first = 0; first < VIDEO_MAX_FRAME; first++) { - if (NULL == vbq->bufs[first]) - continue; - if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory) - continue; - if (vbq->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT)) - break; - } - - /* look for last buffer to map */ - for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) { - if (NULL == vbq->bufs[last]) - continue; - if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory) - continue; - size += vbq->bufs[last]->bsize; - if (size == (vma->vm_end - vma->vm_start)) - break; - } - - size = 0; - for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) { - struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]); - - for (j = 0; j < dma->sglen; j++) { - err = remap_pfn_range( - vma, vma->vm_start + size, - page_to_pfn(sg_page(&dma->sglist[j])), - sg_dma_len(&dma->sglist[j]), vma->vm_page_prot); - if (err) - goto out; - size += sg_dma_len(&dma->sglist[j]); - } - } - -out: - mutex_unlock(&vbq->vb_lock); - - return err; -} - -static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct omap24xxcam_fh *fh = file->private_data; - int rval; - - /* let the video-buf mapper check arguments and set-up structures */ - rval = videobuf_mmap_mapper(&fh->vbq, vma); - if (rval) - return rval; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - /* do mapping to our allocated buffers */ - rval = omap24xxcam_mmap_buffers(file, vma); - /* - * In case of error, free vma->vm_private_data allocated by - * videobuf_mmap_mapper. - */ - if (rval) - kfree(vma->vm_private_data); - - return rval; -} - -static int omap24xxcam_open(struct file *file) -{ - struct omap24xxcam_device *cam = omap24xxcam.priv; - struct omap24xxcam_fh *fh; - struct v4l2_format format; - - if (!cam || !cam->vfd) - return -ENODEV; - - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (fh == NULL) - return -ENOMEM; - - mutex_lock(&cam->mutex); - if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) { - mutex_unlock(&cam->mutex); - goto out_try_module_get; - } - - if (atomic_inc_return(&cam->users) == 1) { - omap24xxcam_hwinit(cam); - if (omap24xxcam_sensor_enable(cam)) { - mutex_unlock(&cam->mutex); - goto out_omap24xxcam_sensor_enable; - } - } - mutex_unlock(&cam->mutex); - - fh->cam = cam; - mutex_lock(&cam->mutex); - vidioc_int_g_fmt_cap(cam->sdev, &format); - mutex_unlock(&cam->mutex); - /* FIXME: how about fh->pix when there are more users? */ - fh->pix = format.fmt.pix; - - file->private_data = fh; - - spin_lock_init(&fh->vbq_lock); - - videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL, - &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_NONE, - sizeof(struct videobuf_buffer), fh, NULL); - - return 0; - -out_omap24xxcam_sensor_enable: - omap24xxcam_poweron_reset(cam); - module_put(cam->sdev->module); - -out_try_module_get: - kfree(fh); - - return -ENODEV; -} - -static int omap24xxcam_release(struct file *file) -{ - struct omap24xxcam_fh *fh = file->private_data; - struct omap24xxcam_device *cam = fh->cam; - - atomic_inc(&cam->reset_disable); - - flush_work(&cam->sensor_reset_work); - - /* stop streaming capture */ - videobuf_streamoff(&fh->vbq); - - mutex_lock(&cam->mutex); - if (cam->streaming == file) { - cam->streaming = NULL; - mutex_unlock(&cam->mutex); - sysfs_notify(&cam->dev->kobj, NULL, "streaming"); - } else { - mutex_unlock(&cam->mutex); - } - - atomic_dec(&cam->reset_disable); - - omap24xxcam_vbq_free_mmap_buffers(&fh->vbq); - - /* - * Make sure the reset work we might have scheduled is not - * pending! It may be run *only* if we have users. (And it may - * not be scheduled anymore since streaming is already - * disabled.) - */ - flush_work(&cam->sensor_reset_work); - - mutex_lock(&cam->mutex); - if (atomic_dec_return(&cam->users) == 0) { - omap24xxcam_sensor_disable(cam); - omap24xxcam_poweron_reset(cam); - } - mutex_unlock(&cam->mutex); - - file->private_data = NULL; - - module_put(cam->sdev->module); - kfree(fh); - - return 0; -} - -static struct v4l2_file_operations omap24xxcam_fops = { - .ioctl = video_ioctl2, - .poll = omap24xxcam_poll, - .mmap = omap24xxcam_mmap, - .open = omap24xxcam_open, - .release = omap24xxcam_release, -}; - -/* - * - * Power management. - * - */ - -#ifdef CONFIG_PM -static int omap24xxcam_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct omap24xxcam_device *cam = platform_get_drvdata(pdev); - - if (atomic_read(&cam->users) == 0) - return 0; - - if (!atomic_read(&cam->reset_disable)) - omap24xxcam_capture_stop(cam); - - omap24xxcam_sensor_disable(cam); - omap24xxcam_poweron_reset(cam); - - return 0; -} - -static int omap24xxcam_resume(struct platform_device *pdev) -{ - struct omap24xxcam_device *cam = platform_get_drvdata(pdev); - - if (atomic_read(&cam->users) == 0) - return 0; - - omap24xxcam_hwinit(cam); - omap24xxcam_sensor_enable(cam); - - if (!atomic_read(&cam->reset_disable)) - omap24xxcam_capture_cont(cam); - - return 0; -} -#endif /* CONFIG_PM */ - -static const struct v4l2_ioctl_ops omap24xxcam_ioctl_fops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_parm = vidioc_g_parm, - .vidioc_s_parm = vidioc_s_parm, -}; - -/* - * - * Camera device (i.e. /dev/video). - * - */ - -static int omap24xxcam_device_register(struct v4l2_int_device *s) -{ - struct omap24xxcam_device *cam = s->u.slave->master->priv; - struct video_device *vfd; - int rval; - - /* We already have a slave. */ - if (cam->sdev) - return -EBUSY; - - cam->sdev = s; - - if (device_create_file(cam->dev, &dev_attr_streaming) != 0) { - dev_err(cam->dev, "could not register sysfs entry\n"); - rval = -EBUSY; - goto err; - } - - /* initialize the video_device struct */ - vfd = cam->vfd = video_device_alloc(); - if (!vfd) { - dev_err(cam->dev, "could not allocate video device struct\n"); - rval = -ENOMEM; - goto err; - } - vfd->release = video_device_release; - - vfd->v4l2_dev = &cam->v4l2_dev; - - strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); - vfd->fops = &omap24xxcam_fops; - vfd->ioctl_ops = &omap24xxcam_ioctl_fops; - - omap24xxcam_hwinit(cam); - - rval = omap24xxcam_sensor_init(cam); - if (rval) - goto err; - - if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { - dev_err(cam->dev, "could not register V4L device\n"); - rval = -EBUSY; - goto err; - } - - omap24xxcam_poweron_reset(cam); - - dev_info(cam->dev, "registered device %s\n", - video_device_node_name(vfd)); - - return 0; - -err: - omap24xxcam_device_unregister(s); - - return rval; -} - -static void omap24xxcam_device_unregister(struct v4l2_int_device *s) -{ - struct omap24xxcam_device *cam = s->u.slave->master->priv; - - omap24xxcam_sensor_exit(cam); - - if (cam->vfd) { - if (!video_is_registered(cam->vfd)) { - /* - * The device was never registered, so release the - * video_device struct directly. - */ - video_device_release(cam->vfd); - } else { - /* - * The unregister function will release the - * video_device struct as well as - * unregistering it. - */ - video_unregister_device(cam->vfd); - } - cam->vfd = NULL; - } - - device_remove_file(cam->dev, &dev_attr_streaming); - - cam->sdev = NULL; -} - -static struct v4l2_int_master omap24xxcam_master = { - .attach = omap24xxcam_device_register, - .detach = omap24xxcam_device_unregister, -}; - -static struct v4l2_int_device omap24xxcam = { - .module = THIS_MODULE, - .name = CAM_NAME, - .type = v4l2_int_type_master, - .u = { - .master = &omap24xxcam_master - }, -}; - -/* - * - * Driver initialisation and deinitialisation. - * - */ - -static int omap24xxcam_probe(struct platform_device *pdev) -{ - struct omap24xxcam_device *cam; - struct resource *mem; - int irq; - - cam = kzalloc(sizeof(*cam), GFP_KERNEL); - if (!cam) { - dev_err(&pdev->dev, "could not allocate memory\n"); - goto err; - } - - platform_set_drvdata(pdev, cam); - - cam->dev = &pdev->dev; - - if (v4l2_device_register(&pdev->dev, &cam->v4l2_dev)) { - dev_err(&pdev->dev, "v4l2_device_register failed\n"); - goto err; - } - - /* - * Impose a lower limit on the amount of memory allocated for - * capture. We require at least enough memory to double-buffer - * QVGA (300KB). - */ - if (capture_mem < 320 * 240 * 2 * 2) - capture_mem = 320 * 240 * 2 * 2; - cam->capture_mem = capture_mem; - - /* request the mem region for the camera registers */ - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(cam->dev, "no mem resource?\n"); - goto err; - } - if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) { - dev_err(cam->dev, - "cannot reserve camera register I/O region\n"); - goto err; - } - cam->mmio_base_phys = mem->start; - cam->mmio_size = resource_size(mem); - - /* map the region */ - cam->mmio_base = ioremap_nocache(cam->mmio_base_phys, cam->mmio_size); - if (!cam->mmio_base) { - dev_err(cam->dev, "cannot map camera register I/O region\n"); - goto err; - } - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - dev_err(cam->dev, "no irq for camera?\n"); - goto err; - } - - /* install the interrupt service routine */ - if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) { - dev_err(cam->dev, - "could not install interrupt service routine\n"); - goto err; - } - cam->irq = irq; - - if (omap24xxcam_clock_get(cam)) - goto err; - - INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work); - - mutex_init(&cam->mutex); - spin_lock_init(&cam->core_enable_disable_lock); - - omap24xxcam_sgdma_init(&cam->sgdma, - cam->mmio_base + CAMDMA_REG_OFFSET, - omap24xxcam_stalled_dma_reset, - (unsigned long)cam); - - omap24xxcam.priv = cam; - - if (v4l2_int_device_register(&omap24xxcam)) - goto err; - - return 0; - -err: - omap24xxcam_remove(pdev); - return -ENODEV; -} - -static int omap24xxcam_remove(struct platform_device *pdev) -{ - struct omap24xxcam_device *cam = platform_get_drvdata(pdev); - - if (!cam) - return 0; - - if (omap24xxcam.priv != NULL) - v4l2_int_device_unregister(&omap24xxcam); - omap24xxcam.priv = NULL; - - omap24xxcam_clock_put(cam); - - if (cam->irq) { - free_irq(cam->irq, cam); - cam->irq = 0; - } - - if (cam->mmio_base) { - iounmap((void *)cam->mmio_base); - cam->mmio_base = 0; - } - - if (cam->mmio_base_phys) { - release_mem_region(cam->mmio_base_phys, cam->mmio_size); - cam->mmio_base_phys = 0; - } - - v4l2_device_unregister(&cam->v4l2_dev); - - kfree(cam); - - return 0; -} - -static struct platform_driver omap24xxcam_driver = { - .probe = omap24xxcam_probe, - .remove = omap24xxcam_remove, -#ifdef CONFIG_PM - .suspend = omap24xxcam_suspend, - .resume = omap24xxcam_resume, -#endif - .driver = { - .name = CAM_NAME, - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(omap24xxcam_driver); - -MODULE_AUTHOR("Sakari Ailus "); -MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(OMAP24XXCAM_VERSION); -module_param(video_nr, int, 0); -MODULE_PARM_DESC(video_nr, - "Minor number for video device (-1 ==> auto assign)"); -module_param(capture_mem, int, 0); -MODULE_PARM_DESC(capture_mem, "Maximum amount of memory for capture " - "buffers (default 4800kiB)"); diff --git a/drivers/staging/media/omap24xx/omap24xxcam.h b/drivers/staging/media/omap24xx/omap24xxcam.h deleted file mode 100644 index 233bb40cfec3..000000000000 --- a/drivers/staging/media/omap24xx/omap24xxcam.h +++ /dev/null @@ -1,596 +0,0 @@ -/* - * drivers/media/platform/omap24xxcam.h - * - * Copyright (C) 2004 MontaVista Software, Inc. - * Copyright (C) 2004 Texas Instruments. - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * Based on code from Andy Lowe . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef OMAP24XXCAM_H -#define OMAP24XXCAM_H - -#include -#include -#include "v4l2-int-device.h" - -/* - * - * General driver related definitions. - * - */ - -#define CAM_NAME "omap24xxcam" - -#define CAM_MCLK 96000000 - -/* number of bytes transferred per DMA request */ -#define DMA_THRESHOLD 32 - -/* - * NUM_CAMDMA_CHANNELS is the number of logical channels provided by - * the camera DMA controller. - */ -#define NUM_CAMDMA_CHANNELS 4 - -/* - * NUM_SG_DMA is the number of scatter-gather DMA transfers that can - * be queued. (We don't have any overlay sglists now.) - */ -#define NUM_SG_DMA (VIDEO_MAX_FRAME) - -/* - * - * Register definitions. - * - */ - -/* subsystem register block offsets */ -#define CC_REG_OFFSET 0x00000400 -#define CAMDMA_REG_OFFSET 0x00000800 -#define CAMMMU_REG_OFFSET 0x00000C00 - -/* define camera subsystem register offsets */ -#define CAM_REVISION 0x000 -#define CAM_SYSCONFIG 0x010 -#define CAM_SYSSTATUS 0x014 -#define CAM_IRQSTATUS 0x018 -#define CAM_GPO 0x040 -#define CAM_GPI 0x050 - -/* define camera core register offsets */ -#define CC_REVISION 0x000 -#define CC_SYSCONFIG 0x010 -#define CC_SYSSTATUS 0x014 -#define CC_IRQSTATUS 0x018 -#define CC_IRQENABLE 0x01C -#define CC_CTRL 0x040 -#define CC_CTRL_DMA 0x044 -#define CC_CTRL_XCLK 0x048 -#define CC_FIFODATA 0x04C -#define CC_TEST 0x050 -#define CC_GENPAR 0x054 -#define CC_CCPFSCR 0x058 -#define CC_CCPFECR 0x05C -#define CC_CCPLSCR 0x060 -#define CC_CCPLECR 0x064 -#define CC_CCPDFR 0x068 - -/* define camera dma register offsets */ -#define CAMDMA_REVISION 0x000 -#define CAMDMA_IRQSTATUS_L0 0x008 -#define CAMDMA_IRQSTATUS_L1 0x00C -#define CAMDMA_IRQSTATUS_L2 0x010 -#define CAMDMA_IRQSTATUS_L3 0x014 -#define CAMDMA_IRQENABLE_L0 0x018 -#define CAMDMA_IRQENABLE_L1 0x01C -#define CAMDMA_IRQENABLE_L2 0x020 -#define CAMDMA_IRQENABLE_L3 0x024 -#define CAMDMA_SYSSTATUS 0x028 -#define CAMDMA_OCP_SYSCONFIG 0x02C -#define CAMDMA_CAPS_0 0x064 -#define CAMDMA_CAPS_2 0x06C -#define CAMDMA_CAPS_3 0x070 -#define CAMDMA_CAPS_4 0x074 -#define CAMDMA_GCR 0x078 -#define CAMDMA_CCR(n) (0x080 + (n)*0x60) -#define CAMDMA_CLNK_CTRL(n) (0x084 + (n)*0x60) -#define CAMDMA_CICR(n) (0x088 + (n)*0x60) -#define CAMDMA_CSR(n) (0x08C + (n)*0x60) -#define CAMDMA_CSDP(n) (0x090 + (n)*0x60) -#define CAMDMA_CEN(n) (0x094 + (n)*0x60) -#define CAMDMA_CFN(n) (0x098 + (n)*0x60) -#define CAMDMA_CSSA(n) (0x09C + (n)*0x60) -#define CAMDMA_CDSA(n) (0x0A0 + (n)*0x60) -#define CAMDMA_CSEI(n) (0x0A4 + (n)*0x60) -#define CAMDMA_CSFI(n) (0x0A8 + (n)*0x60) -#define CAMDMA_CDEI(n) (0x0AC + (n)*0x60) -#define CAMDMA_CDFI(n) (0x0B0 + (n)*0x60) -#define CAMDMA_CSAC(n) (0x0B4 + (n)*0x60) -#define CAMDMA_CDAC(n) (0x0B8 + (n)*0x60) -#define CAMDMA_CCEN(n) (0x0BC + (n)*0x60) -#define CAMDMA_CCFN(n) (0x0C0 + (n)*0x60) -#define CAMDMA_COLOR(n) (0x0C4 + (n)*0x60) - -/* define camera mmu register offsets */ -#define CAMMMU_REVISION 0x000 -#define CAMMMU_SYSCONFIG 0x010 -#define CAMMMU_SYSSTATUS 0x014 -#define CAMMMU_IRQSTATUS 0x018 -#define CAMMMU_IRQENABLE 0x01C -#define CAMMMU_WALKING_ST 0x040 -#define CAMMMU_CNTL 0x044 -#define CAMMMU_FAULT_AD 0x048 -#define CAMMMU_TTB 0x04C -#define CAMMMU_LOCK 0x050 -#define CAMMMU_LD_TLB 0x054 -#define CAMMMU_CAM 0x058 -#define CAMMMU_RAM 0x05C -#define CAMMMU_GFLUSH 0x060 -#define CAMMMU_FLUSH_ENTRY 0x064 -#define CAMMMU_READ_CAM 0x068 -#define CAMMMU_READ_RAM 0x06C -#define CAMMMU_EMU_FAULT_AD 0x070 - -/* Define bit fields within selected registers */ -#define CAM_REVISION_MAJOR (15 << 4) -#define CAM_REVISION_MAJOR_SHIFT 4 -#define CAM_REVISION_MINOR (15 << 0) -#define CAM_REVISION_MINOR_SHIFT 0 - -#define CAM_SYSCONFIG_SOFTRESET (1 << 1) -#define CAM_SYSCONFIG_AUTOIDLE (1 << 0) - -#define CAM_SYSSTATUS_RESETDONE (1 << 0) - -#define CAM_IRQSTATUS_CC_IRQ (1 << 4) -#define CAM_IRQSTATUS_MMU_IRQ (1 << 3) -#define CAM_IRQSTATUS_DMA_IRQ2 (1 << 2) -#define CAM_IRQSTATUS_DMA_IRQ1 (1 << 1) -#define CAM_IRQSTATUS_DMA_IRQ0 (1 << 0) - -#define CAM_GPO_CAM_S_P_EN (1 << 1) -#define CAM_GPO_CAM_CCP_MODE (1 << 0) - -#define CAM_GPI_CC_DMA_REQ1 (1 << 24) -#define CAP_GPI_CC_DMA_REQ0 (1 << 23) -#define CAP_GPI_CAM_MSTANDBY (1 << 21) -#define CAP_GPI_CAM_WAIT (1 << 20) -#define CAP_GPI_CAM_S_DATA (1 << 17) -#define CAP_GPI_CAM_S_CLK (1 << 16) -#define CAP_GPI_CAM_P_DATA (0xFFF << 3) -#define CAP_GPI_CAM_P_DATA_SHIFT 3 -#define CAP_GPI_CAM_P_VS (1 << 2) -#define CAP_GPI_CAM_P_HS (1 << 1) -#define CAP_GPI_CAM_P_CLK (1 << 0) - -#define CC_REVISION_MAJOR (15 << 4) -#define CC_REVISION_MAJOR_SHIFT 4 -#define CC_REVISION_MINOR (15 << 0) -#define CC_REVISION_MINOR_SHIFT 0 - -#define CC_SYSCONFIG_SIDLEMODE (3 << 3) -#define CC_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3) -#define CC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3) -#define CC_SYSCONFIG_SOFTRESET (1 << 1) -#define CC_SYSCONFIG_AUTOIDLE (1 << 0) - -#define CC_SYSSTATUS_RESETDONE (1 << 0) - -#define CC_IRQSTATUS_FS_IRQ (1 << 19) -#define CC_IRQSTATUS_LE_IRQ (1 << 18) -#define CC_IRQSTATUS_LS_IRQ (1 << 17) -#define CC_IRQSTATUS_FE_IRQ (1 << 16) -#define CC_IRQSTATUS_FW_ERR_IRQ (1 << 10) -#define CC_IRQSTATUS_FSC_ERR_IRQ (1 << 9) -#define CC_IRQSTATUS_SSC_ERR_IRQ (1 << 8) -#define CC_IRQSTATUS_FIFO_NOEMPTY_IRQ (1 << 4) -#define CC_IRQSTATUS_FIFO_FULL_IRQ (1 << 3) -#define CC_IRQSTATUS_FIFO_THR_IRQ (1 << 2) -#define CC_IRQSTATUS_FIFO_OF_IRQ (1 << 1) -#define CC_IRQSTATUS_FIFO_UF_IRQ (1 << 0) - -#define CC_IRQENABLE_FS_IRQ (1 << 19) -#define CC_IRQENABLE_LE_IRQ (1 << 18) -#define CC_IRQENABLE_LS_IRQ (1 << 17) -#define CC_IRQENABLE_FE_IRQ (1 << 16) -#define CC_IRQENABLE_FW_ERR_IRQ (1 << 10) -#define CC_IRQENABLE_FSC_ERR_IRQ (1 << 9) -#define CC_IRQENABLE_SSC_ERR_IRQ (1 << 8) -#define CC_IRQENABLE_FIFO_NOEMPTY_IRQ (1 << 4) -#define CC_IRQENABLE_FIFO_FULL_IRQ (1 << 3) -#define CC_IRQENABLE_FIFO_THR_IRQ (1 << 2) -#define CC_IRQENABLE_FIFO_OF_IRQ (1 << 1) -#define CC_IRQENABLE_FIFO_UF_IRQ (1 << 0) - -#define CC_CTRL_CC_ONE_SHOT (1 << 20) -#define CC_CTRL_CC_IF_SYNCHRO (1 << 19) -#define CC_CTRL_CC_RST (1 << 18) -#define CC_CTRL_CC_FRAME_TRIG (1 << 17) -#define CC_CTRL_CC_EN (1 << 16) -#define CC_CTRL_NOBT_SYNCHRO (1 << 13) -#define CC_CTRL_BT_CORRECT (1 << 12) -#define CC_CTRL_PAR_ORDERCAM (1 << 11) -#define CC_CTRL_PAR_CLK_POL (1 << 10) -#define CC_CTRL_NOBT_HS_POL (1 << 9) -#define CC_CTRL_NOBT_VS_POL (1 << 8) -#define CC_CTRL_PAR_MODE (7 << 1) -#define CC_CTRL_PAR_MODE_SHIFT 1 -#define CC_CTRL_PAR_MODE_NOBT8 (0 << 1) -#define CC_CTRL_PAR_MODE_NOBT10 (1 << 1) -#define CC_CTRL_PAR_MODE_NOBT12 (2 << 1) -#define CC_CTRL_PAR_MODE_BT8 (4 << 1) -#define CC_CTRL_PAR_MODE_BT10 (5 << 1) -#define CC_CTRL_PAR_MODE_FIFOTEST (7 << 1) -#define CC_CTRL_CCP_MODE (1 << 0) - -#define CC_CTRL_DMA_EN (1 << 8) -#define CC_CTRL_DMA_FIFO_THRESHOLD (0x7F << 0) -#define CC_CTRL_DMA_FIFO_THRESHOLD_SHIFT 0 - -#define CC_CTRL_XCLK_DIV (0x1F << 0) -#define CC_CTRL_XCLK_DIV_SHIFT 0 -#define CC_CTRL_XCLK_DIV_STABLE_LOW (0 << 0) -#define CC_CTRL_XCLK_DIV_STABLE_HIGH (1 << 0) -#define CC_CTRL_XCLK_DIV_BYPASS (31 << 0) - -#define CC_TEST_FIFO_RD_POINTER (0xFF << 24) -#define CC_TEST_FIFO_RD_POINTER_SHIFT 24 -#define CC_TEST_FIFO_WR_POINTER (0xFF << 16) -#define CC_TEST_FIFO_WR_POINTER_SHIFT 16 -#define CC_TEST_FIFO_LEVEL (0xFF << 8) -#define CC_TEST_FIFO_LEVEL_SHIFT 8 -#define CC_TEST_FIFO_LEVEL_PEAK (0xFF << 0) -#define CC_TEST_FIFO_LEVEL_PEAK_SHIFT 0 - -#define CC_GENPAR_FIFO_DEPTH (7 << 0) -#define CC_GENPAR_FIFO_DEPTH_SHIFT 0 - -#define CC_CCPDFR_ALPHA (0xFF << 8) -#define CC_CCPDFR_ALPHA_SHIFT 8 -#define CC_CCPDFR_DATAFORMAT (15 << 0) -#define CC_CCPDFR_DATAFORMAT_SHIFT 0 -#define CC_CCPDFR_DATAFORMAT_YUV422BE (0 << 0) -#define CC_CCPDFR_DATAFORMAT_YUV422 (1 << 0) -#define CC_CCPDFR_DATAFORMAT_YUV420 (2 << 0) -#define CC_CCPDFR_DATAFORMAT_RGB444 (4 << 0) -#define CC_CCPDFR_DATAFORMAT_RGB565 (5 << 0) -#define CC_CCPDFR_DATAFORMAT_RGB888NDE (6 << 0) -#define CC_CCPDFR_DATAFORMAT_RGB888 (7 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW8NDE (8 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW8 (9 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW10NDE (10 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW10 (11 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW12NDE (12 << 0) -#define CC_CCPDFR_DATAFORMAT_RAW12 (13 << 0) -#define CC_CCPDFR_DATAFORMAT_JPEG8 (15 << 0) - -#define CAMDMA_REVISION_MAJOR (15 << 4) -#define CAMDMA_REVISION_MAJOR_SHIFT 4 -#define CAMDMA_REVISION_MINOR (15 << 0) -#define CAMDMA_REVISION_MINOR_SHIFT 0 - -#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE (3 << 12) -#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 << 12) -#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12) -#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 << 12) -#define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 << 9) -#define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 << 8) -#define CAMDMA_OCP_SYSCONFIG_EMUFREE (1 << 5) -#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE (3 << 3) -#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3) -#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3) -#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_SIDLE (2 << 3) -#define CAMDMA_OCP_SYSCONFIG_SOFTRESET (1 << 1) -#define CAMDMA_OCP_SYSCONFIG_AUTOIDLE (1 << 0) - -#define CAMDMA_SYSSTATUS_RESETDONE (1 << 0) - -#define CAMDMA_GCR_ARBITRATION_RATE (0xFF << 16) -#define CAMDMA_GCR_ARBITRATION_RATE_SHIFT 16 -#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH (0xFF << 0) -#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH_SHIFT 0 - -#define CAMDMA_CCR_SEL_SRC_DST_SYNC (1 << 24) -#define CAMDMA_CCR_PREFETCH (1 << 23) -#define CAMDMA_CCR_SUPERVISOR (1 << 22) -#define CAMDMA_CCR_SECURE (1 << 21) -#define CAMDMA_CCR_BS (1 << 18) -#define CAMDMA_CCR_TRANSPARENT_COPY_ENABLE (1 << 17) -#define CAMDMA_CCR_CONSTANT_FILL_ENABLE (1 << 16) -#define CAMDMA_CCR_DST_AMODE (3 << 14) -#define CAMDMA_CCR_DST_AMODE_CONST_ADDR (0 << 14) -#define CAMDMA_CCR_DST_AMODE_POST_INC (1 << 14) -#define CAMDMA_CCR_DST_AMODE_SGL_IDX (2 << 14) -#define CAMDMA_CCR_DST_AMODE_DBL_IDX (3 << 14) -#define CAMDMA_CCR_SRC_AMODE (3 << 12) -#define CAMDMA_CCR_SRC_AMODE_CONST_ADDR (0 << 12) -#define CAMDMA_CCR_SRC_AMODE_POST_INC (1 << 12) -#define CAMDMA_CCR_SRC_AMODE_SGL_IDX (2 << 12) -#define CAMDMA_CCR_SRC_AMODE_DBL_IDX (3 << 12) -#define CAMDMA_CCR_WR_ACTIVE (1 << 10) -#define CAMDMA_CCR_RD_ACTIVE (1 << 9) -#define CAMDMA_CCR_SUSPEND_SENSITIVE (1 << 8) -#define CAMDMA_CCR_ENABLE (1 << 7) -#define CAMDMA_CCR_PRIO (1 << 6) -#define CAMDMA_CCR_FS (1 << 5) -#define CAMDMA_CCR_SYNCHRO ((3 << 19) | (31 << 0)) -#define CAMDMA_CCR_SYNCHRO_CAMERA 0x01 - -#define CAMDMA_CLNK_CTRL_ENABLE_LNK (1 << 15) -#define CAMDMA_CLNK_CTRL_NEXTLCH_ID (0x1F << 0) -#define CAMDMA_CLNK_CTRL_NEXTLCH_ID_SHIFT 0 - -#define CAMDMA_CICR_MISALIGNED_ERR_IE (1 << 11) -#define CAMDMA_CICR_SUPERVISOR_ERR_IE (1 << 10) -#define CAMDMA_CICR_SECURE_ERR_IE (1 << 9) -#define CAMDMA_CICR_TRANS_ERR_IE (1 << 8) -#define CAMDMA_CICR_PACKET_IE (1 << 7) -#define CAMDMA_CICR_BLOCK_IE (1 << 5) -#define CAMDMA_CICR_LAST_IE (1 << 4) -#define CAMDMA_CICR_FRAME_IE (1 << 3) -#define CAMDMA_CICR_HALF_IE (1 << 2) -#define CAMDMA_CICR_DROP_IE (1 << 1) - -#define CAMDMA_CSR_MISALIGNED_ERR (1 << 11) -#define CAMDMA_CSR_SUPERVISOR_ERR (1 << 10) -#define CAMDMA_CSR_SECURE_ERR (1 << 9) -#define CAMDMA_CSR_TRANS_ERR (1 << 8) -#define CAMDMA_CSR_PACKET (1 << 7) -#define CAMDMA_CSR_SYNC (1 << 6) -#define CAMDMA_CSR_BLOCK (1 << 5) -#define CAMDMA_CSR_LAST (1 << 4) -#define CAMDMA_CSR_FRAME (1 << 3) -#define CAMDMA_CSR_HALF (1 << 2) -#define CAMDMA_CSR_DROP (1 << 1) - -#define CAMDMA_CSDP_SRC_ENDIANNESS (1 << 21) -#define CAMDMA_CSDP_SRC_ENDIANNESS_LOCK (1 << 20) -#define CAMDMA_CSDP_DST_ENDIANNESS (1 << 19) -#define CAMDMA_CSDP_DST_ENDIANNESS_LOCK (1 << 18) -#define CAMDMA_CSDP_WRITE_MODE (3 << 16) -#define CAMDMA_CSDP_WRITE_MODE_WRNP (0 << 16) -#define CAMDMA_CSDP_WRITE_MODE_POSTED (1 << 16) -#define CAMDMA_CSDP_WRITE_MODE_POSTED_LAST_WRNP (2 << 16) -#define CAMDMA_CSDP_DST_BURST_EN (3 << 14) -#define CAMDMA_CSDP_DST_BURST_EN_1 (0 << 14) -#define CAMDMA_CSDP_DST_BURST_EN_16 (1 << 14) -#define CAMDMA_CSDP_DST_BURST_EN_32 (2 << 14) -#define CAMDMA_CSDP_DST_BURST_EN_64 (3 << 14) -#define CAMDMA_CSDP_DST_PACKED (1 << 13) -#define CAMDMA_CSDP_WR_ADD_TRSLT (15 << 9) -#define CAMDMA_CSDP_WR_ADD_TRSLT_ENABLE_MREQADD (3 << 9) -#define CAMDMA_CSDP_SRC_BURST_EN (3 << 7) -#define CAMDMA_CSDP_SRC_BURST_EN_1 (0 << 7) -#define CAMDMA_CSDP_SRC_BURST_EN_16 (1 << 7) -#define CAMDMA_CSDP_SRC_BURST_EN_32 (2 << 7) -#define CAMDMA_CSDP_SRC_BURST_EN_64 (3 << 7) -#define CAMDMA_CSDP_SRC_PACKED (1 << 6) -#define CAMDMA_CSDP_RD_ADD_TRSLT (15 << 2) -#define CAMDMA_CSDP_RD_ADD_TRSLT_ENABLE_MREQADD (3 << 2) -#define CAMDMA_CSDP_DATA_TYPE (3 << 0) -#define CAMDMA_CSDP_DATA_TYPE_8BITS (0 << 0) -#define CAMDMA_CSDP_DATA_TYPE_16BITS (1 << 0) -#define CAMDMA_CSDP_DATA_TYPE_32BITS (2 << 0) - -#define CAMMMU_SYSCONFIG_AUTOIDLE (1 << 0) - -/* - * - * Declarations. - * - */ - -/* forward declarations */ -struct omap24xxcam_sgdma; -struct omap24xxcam_dma; - -typedef void (*sgdma_callback_t)(struct omap24xxcam_sgdma *cam, - u32 status, void *arg); -typedef void (*dma_callback_t)(struct omap24xxcam_dma *cam, - u32 status, void *arg); - -struct channel_state { - dma_callback_t callback; - void *arg; -}; - -/* sgdma state for each of the possible videobuf_buffers + 2 overlays */ -struct sgdma_state { - const struct scatterlist *sglist; - int sglen; /* number of sglist entries */ - int next_sglist; /* index of next sglist entry to process */ - unsigned int bytes_read; /* number of bytes read */ - unsigned int len; /* total length of sglist (excluding - * bytes due to page alignment) */ - int queued_sglist; /* number of sglist entries queued for DMA */ - u32 csr; /* DMA return code */ - sgdma_callback_t callback; - void *arg; -}; - -/* physical DMA channel management */ -struct omap24xxcam_dma { - spinlock_t lock; /* Lock for the whole structure. */ - - void __iomem *base; /* base address for dma controller */ - - /* While dma_stop!=0, an attempt to start a new DMA transfer will - * fail. - */ - atomic_t dma_stop; - int free_dmach; /* number of dma channels free */ - int next_dmach; /* index of next dma channel to use */ - struct channel_state ch_state[NUM_CAMDMA_CHANNELS]; -}; - -/* scatter-gather DMA (scatterlist stuff) management */ -struct omap24xxcam_sgdma { - struct omap24xxcam_dma dma; - - spinlock_t lock; /* Lock for the fields below. */ - int free_sgdma; /* number of free sg dma slots */ - int next_sgdma; /* index of next sg dma slot to use */ - struct sgdma_state sg_state[NUM_SG_DMA]; - - /* Reset timer data */ - struct timer_list reset_timer; -}; - -/* per-device data structure */ -struct omap24xxcam_device { - /*** mutex ***/ - /* - * mutex serialises access to this structure. Also camera - * opening and releasing is synchronised by this. - */ - struct mutex mutex; - - struct v4l2_device v4l2_dev; - - /*** general driver state information ***/ - atomic_t users; - /* - * Lock to serialise core enabling and disabling and access to - * sgdma_in_queue. - */ - spinlock_t core_enable_disable_lock; - /* - * Number or sgdma requests in scatter-gather queue, protected - * by the lock above. - */ - int sgdma_in_queue; - /* - * Sensor interface parameters: interface type, CC_CTRL - * register value and interface specific data. - */ - int if_type; - union { - struct parallel { - u32 xclk; - } bt656; - } if_u; - u32 cc_ctrl; - - /*** subsystem structures ***/ - struct omap24xxcam_sgdma sgdma; - - /*** hardware resources ***/ - unsigned int irq; - void __iomem *mmio_base; - unsigned long mmio_base_phys; - unsigned long mmio_size; - - /*** interfaces and device ***/ - struct v4l2_int_device *sdev; - struct device *dev; - struct video_device *vfd; - - /*** camera and sensor reset related stuff ***/ - struct work_struct sensor_reset_work; - /* - * We're in the middle of a reset. Don't enable core if this - * is non-zero! This exists to help decisionmaking in a case - * where videobuf_qbuf is called while we are in the middle of - * a reset. - */ - atomic_t in_reset; - /* - * Non-zero if we don't want any resets for now. Used to - * prevent reset work to run when we're about to stop - * streaming. - */ - atomic_t reset_disable; - - /*** video device parameters ***/ - int capture_mem; - - /*** camera module clocks ***/ - struct clk *fck; - struct clk *ick; - - /*** capture data ***/ - /* file handle, if streaming is on */ - struct file *streaming; -}; - -/* Per-file handle data. */ -struct omap24xxcam_fh { - spinlock_t vbq_lock; /* spinlock for the videobuf queue */ - struct videobuf_queue vbq; - struct v4l2_pix_format pix; /* serialise pix by vbq->lock */ - atomic_t field_count; /* field counter for videobuf_buffer */ - /* accessing cam here doesn't need serialisation: it's constant */ - struct omap24xxcam_device *cam; -}; - -/* - * - * Register I/O functions. - * - */ - -static inline u32 omap24xxcam_reg_in(u32 __iomem *base, u32 offset) -{ - return readl(base + offset); -} - -static inline u32 omap24xxcam_reg_out(u32 __iomem *base, u32 offset, - u32 val) -{ - writel(val, base + offset); - return val; -} - -static inline u32 omap24xxcam_reg_merge(u32 __iomem *base, u32 offset, - u32 val, u32 mask) -{ - u32 __iomem *addr = base + offset; - u32 new_val = (readl(addr) & ~mask) | (val & mask); - - writel(new_val, addr); - return new_val; -} - -/* - * - * Function prototypes. - * - */ - -/* dma prototypes */ - -void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma); -void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma); - -/* sgdma prototypes */ - -void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma); -int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, - const struct scatterlist *sglist, int sglen, - int len, sgdma_callback_t callback, void *arg); -void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma); -void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, - void __iomem *base, - void (*reset_callback)(unsigned long data), - unsigned long reset_callback_data); -void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma); - -#endif diff --git a/drivers/staging/media/omap24xx/tcm825x.c b/drivers/staging/media/omap24xx/tcm825x.c deleted file mode 100644 index 9d9ecf1fc4ae..000000000000 --- a/drivers/staging/media/omap24xx/tcm825x.c +++ /dev/null @@ -1,938 +0,0 @@ -/* - * drivers/media/i2c/tcm825x.c - * - * TCM825X camera sensor driver. - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * Based on code from David Cohen - * - * This driver was based on ov9640 sensor driver from MontaVista - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include "v4l2-int-device.h" - -#include "tcm825x.h" - -/* - * The sensor has two fps modes: the lower one just gives half the fps - * at the same xclk than the high one. - */ -#define MAX_FPS 30 -#define MIN_FPS 8 -#define MAX_HALF_FPS (MAX_FPS / 2) -#define HIGH_FPS_MODE_LOWER_LIMIT 14 -#define DEFAULT_FPS MAX_HALF_FPS - -struct tcm825x_sensor { - const struct tcm825x_platform_data *platform_data; - struct v4l2_int_device *v4l2_int_device; - struct i2c_client *i2c_client; - struct v4l2_pix_format pix; - struct v4l2_fract timeperframe; -}; - -/* list of image formats supported by TCM825X sensor */ -static const struct v4l2_fmtdesc tcm825x_formats[] = { - { - .description = "YUYV (YUV 4:2:2), packed", - .pixelformat = V4L2_PIX_FMT_UYVY, - }, { - /* Note: V4L2 defines RGB565 as: - * - * Byte 0 Byte 1 - * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3 - * - * We interpret RGB565 as: - * - * Byte 0 Byte 1 - * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3 - */ - .description = "RGB565, le", - .pixelformat = V4L2_PIX_FMT_RGB565, - }, -}; - -#define TCM825X_NUM_CAPTURE_FORMATS ARRAY_SIZE(tcm825x_formats) - -/* - * TCM825X register configuration for all combinations of pixel format and - * image size - */ -static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; -static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; -static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; -static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; -static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; -static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; - -static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; -static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; - -/* Our own specific controls */ -#define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE -#define V4L2_CID_H_EDGE_EN (V4L2_CID_PRIVATE_BASE + 1) -#define V4L2_CID_V_EDGE_EN (V4L2_CID_PRIVATE_BASE + 2) -#define V4L2_CID_LENS (V4L2_CID_PRIVATE_BASE + 3) -#define V4L2_CID_MAX_EXPOSURE_TIME (V4L2_CID_PRIVATE_BASE + 4) -#define V4L2_CID_LAST_PRIV V4L2_CID_MAX_EXPOSURE_TIME - -/* Video controls */ -static struct vcontrol { - struct v4l2_queryctrl qc; - u16 reg; - u16 start_bit; -} video_control[] = { - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 63, - .step = 1, - }, - .reg = TCM825X_AG, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Balance", - .minimum = 0, - .maximum = 255, - .step = 1, - }, - .reg = TCM825X_MRG, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Balance", - .minimum = 0, - .maximum = 255, - .step = 1, - }, - .reg = TCM825X_MBG, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto White Balance", - .minimum = 0, - .maximum = 1, - .step = 0, - }, - .reg = TCM825X_AWBSW, - .start_bit = 7, - }, - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Time", - .minimum = 0, - .maximum = 0x1fff, - .step = 1, - }, - .reg = TCM825X_ESRSPD_U, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Image", - .minimum = 0, - .maximum = 1, - .step = 0, - }, - .reg = TCM825X_H_INV, - .start_bit = 6, - }, - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Vertical Flip", - .minimum = 0, - .maximum = 1, - .step = 0, - }, - .reg = TCM825X_V_INV, - .start_bit = 7, - }, - /* Private controls */ - { - { - .id = V4L2_CID_ALC, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Luminance Control", - .minimum = 0, - .maximum = 1, - .step = 0, - }, - .reg = TCM825X_ALCSW, - .start_bit = 7, - }, - { - { - .id = V4L2_CID_H_EDGE_EN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Horizontal Edge Enhancement", - .minimum = 0, - .maximum = 0xff, - .step = 1, - }, - .reg = TCM825X_HDTG, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_V_EDGE_EN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Vertical Edge Enhancement", - .minimum = 0, - .maximum = 0xff, - .step = 1, - }, - .reg = TCM825X_VDTG, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_LENS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Lens Shading Compensation", - .minimum = 0, - .maximum = 0x3f, - .step = 1, - }, - .reg = TCM825X_LENS, - .start_bit = 0, - }, - { - { - .id = V4L2_CID_MAX_EXPOSURE_TIME, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Maximum Exposure Time", - .minimum = 0, - .maximum = 0x3, - .step = 1, - }, - .reg = TCM825X_ESRLIM, - .start_bit = 5, - }, -}; - - -static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = { - &subqcif, &qqvga, &qcif, &qvga, &cif, &vga }; - -static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = { - &yuv422, &rgb565 }; - -/* - * Read a value from a register in an TCM825X sensor device. The value is - * returned in 'val'. - * Returns zero if successful, or non-zero otherwise. - */ -static int tcm825x_read_reg(struct i2c_client *client, int reg) -{ - int err; - struct i2c_msg msg[2]; - u8 reg_buf, data_buf = 0; - - if (!client->adapter) - return -ENODEV; - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = ®_buf; - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &data_buf; - - reg_buf = reg; - - err = i2c_transfer(client->adapter, msg, 2); - if (err < 0) - return err; - return data_buf; -} - -/* - * Write a value to a register in an TCM825X sensor device. - * Returns zero if successful, or non-zero otherwise. - */ -static int tcm825x_write_reg(struct i2c_client *client, u8 reg, u8 val) -{ - int err; - struct i2c_msg msg[1]; - unsigned char data[2]; - - if (!client->adapter) - return -ENODEV; - - msg->addr = client->addr; - msg->flags = 0; - msg->len = 2; - msg->buf = data; - data[0] = reg; - data[1] = val; - err = i2c_transfer(client->adapter, msg, 1); - if (err >= 0) - return 0; - return err; -} - -static int __tcm825x_write_reg_mask(struct i2c_client *client, - u8 reg, u8 val, u8 mask) -{ - int rc; - - /* need to do read - modify - write */ - rc = tcm825x_read_reg(client, reg); - if (rc < 0) - return rc; - - rc &= (~mask); /* Clear the masked bits */ - val &= mask; /* Enforce mask on value */ - val |= rc; - - /* write the new value to the register */ - rc = tcm825x_write_reg(client, reg, val); - if (rc) - return rc; - - return 0; -} - -#define tcm825x_write_reg_mask(client, regmask, val) \ - __tcm825x_write_reg_mask(client, TCM825X_ADDR((regmask)), val, \ - TCM825X_MASK((regmask))) - - -/* - * Initialize a list of TCM825X registers. - * The list of registers is terminated by the pair of values - * { TCM825X_REG_TERM, TCM825X_VAL_TERM }. - * Returns zero if successful, or non-zero otherwise. - */ -static int tcm825x_write_default_regs(struct i2c_client *client, - const struct tcm825x_reg *reglist) -{ - int err; - const struct tcm825x_reg *next = reglist; - - while (!((next->reg == TCM825X_REG_TERM) - && (next->val == TCM825X_VAL_TERM))) { - err = tcm825x_write_reg(client, next->reg, next->val); - if (err) { - dev_err(&client->dev, "register writing failed\n"); - return err; - } - next++; - } - - return 0; -} - -static struct vcontrol *find_vctrl(int id) -{ - int i; - - if (id < V4L2_CID_BASE) - return NULL; - - for (i = 0; i < ARRAY_SIZE(video_control); i++) - if (video_control[i].qc.id == id) - return &video_control[i]; - - return NULL; -} - -/* - * Find the best match for a requested image capture size. The best match - * is chosen as the nearest match that has the same number or fewer pixels - * as the requested size, or the smallest image size if the requested size - * has fewer pixels than the smallest image. - */ -static enum image_size tcm825x_find_size(struct v4l2_int_device *s, - unsigned int width, - unsigned int height) -{ - enum image_size isize; - unsigned long pixels = width * height; - struct tcm825x_sensor *sensor = s->priv; - - for (isize = subQCIF; isize < VGA; isize++) { - if (tcm825x_sizes[isize + 1].height - * tcm825x_sizes[isize + 1].width > pixels) { - dev_dbg(&sensor->i2c_client->dev, "size %d\n", isize); - - return isize; - } - } - - dev_dbg(&sensor->i2c_client->dev, "format default VGA\n"); - - return VGA; -} - -/* - * Configure the TCM825X for current image size, pixel format, and - * frame period. fper is the frame period (in seconds) expressed as a - * fraction. Returns zero if successful, or non-zero otherwise. The - * actual frame period is returned in fper. - */ -static int tcm825x_configure(struct v4l2_int_device *s) -{ - struct tcm825x_sensor *sensor = s->priv; - struct v4l2_pix_format *pix = &sensor->pix; - enum image_size isize = tcm825x_find_size(s, pix->width, pix->height); - struct v4l2_fract *fper = &sensor->timeperframe; - enum pixel_format pfmt; - int err; - u32 tgt_fps; - u8 val; - - /* common register initialization */ - err = tcm825x_write_default_regs( - sensor->i2c_client, sensor->platform_data->default_regs()); - if (err) - return err; - - /* configure image size */ - val = tcm825x_siz_reg[isize]->val; - dev_dbg(&sensor->i2c_client->dev, - "configuring image size %d\n", isize); - err = tcm825x_write_reg_mask(sensor->i2c_client, - tcm825x_siz_reg[isize]->reg, val); - if (err) - return err; - - /* configure pixel format */ - switch (pix->pixelformat) { - default: - case V4L2_PIX_FMT_RGB565: - pfmt = RGB565; - break; - case V4L2_PIX_FMT_UYVY: - pfmt = YUV422; - break; - } - - dev_dbg(&sensor->i2c_client->dev, - "configuring pixel format %d\n", pfmt); - val = tcm825x_fmt_reg[pfmt]->val; - - err = tcm825x_write_reg_mask(sensor->i2c_client, - tcm825x_fmt_reg[pfmt]->reg, val); - if (err) - return err; - - /* - * For frame rate < 15, the FPS reg (addr 0x02, bit 7) must be - * set. Frame rate will be halved from the normal. - */ - tgt_fps = fper->denominator / fper->numerator; - if (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) { - val = tcm825x_read_reg(sensor->i2c_client, 0x02); - val |= 0x80; - tcm825x_write_reg(sensor->i2c_client, 0x02, val); - } - - return 0; -} - -static int ioctl_queryctrl(struct v4l2_int_device *s, - struct v4l2_queryctrl *qc) -{ - struct vcontrol *control; - - control = find_vctrl(qc->id); - - if (control == NULL) - return -EINVAL; - - *qc = control->qc; - - return 0; -} - -static int ioctl_g_ctrl(struct v4l2_int_device *s, - struct v4l2_control *vc) -{ - struct tcm825x_sensor *sensor = s->priv; - struct i2c_client *client = sensor->i2c_client; - int val, r; - struct vcontrol *lvc; - - /* exposure time is special, spread across 2 registers */ - if (vc->id == V4L2_CID_EXPOSURE) { - int val_lower, val_upper; - - val_upper = tcm825x_read_reg(client, - TCM825X_ADDR(TCM825X_ESRSPD_U)); - if (val_upper < 0) - return val_upper; - val_lower = tcm825x_read_reg(client, - TCM825X_ADDR(TCM825X_ESRSPD_L)); - if (val_lower < 0) - return val_lower; - - vc->value = ((val_upper & 0x1f) << 8) | (val_lower); - return 0; - } - - lvc = find_vctrl(vc->id); - if (lvc == NULL) - return -EINVAL; - - r = tcm825x_read_reg(client, TCM825X_ADDR(lvc->reg)); - if (r < 0) - return r; - val = r & TCM825X_MASK(lvc->reg); - val >>= lvc->start_bit; - - if (val < 0) - return val; - - if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP) - val ^= sensor->platform_data->is_upside_down(); - - vc->value = val; - return 0; -} - -static int ioctl_s_ctrl(struct v4l2_int_device *s, - struct v4l2_control *vc) -{ - struct tcm825x_sensor *sensor = s->priv; - struct i2c_client *client = sensor->i2c_client; - struct vcontrol *lvc; - int val = vc->value; - - /* exposure time is special, spread across 2 registers */ - if (vc->id == V4L2_CID_EXPOSURE) { - int val_lower, val_upper; - - val_lower = val & TCM825X_MASK(TCM825X_ESRSPD_L); - val_upper = (val >> 8) & TCM825X_MASK(TCM825X_ESRSPD_U); - - if (tcm825x_write_reg_mask(client, - TCM825X_ESRSPD_U, val_upper)) - return -EIO; - - if (tcm825x_write_reg_mask(client, - TCM825X_ESRSPD_L, val_lower)) - return -EIO; - - return 0; - } - - lvc = find_vctrl(vc->id); - if (lvc == NULL) - return -EINVAL; - - if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP) - val ^= sensor->platform_data->is_upside_down(); - - val = val << lvc->start_bit; - if (tcm825x_write_reg_mask(client, lvc->reg, val)) - return -EIO; - - return 0; -} - -static int ioctl_enum_fmt_cap(struct v4l2_int_device *s, - struct v4l2_fmtdesc *fmt) -{ - int index = fmt->index; - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (index >= TCM825X_NUM_CAPTURE_FORMATS) - return -EINVAL; - break; - - default: - return -EINVAL; - } - - fmt->flags = tcm825x_formats[index].flags; - strlcpy(fmt->description, tcm825x_formats[index].description, - sizeof(fmt->description)); - fmt->pixelformat = tcm825x_formats[index].pixelformat; - - return 0; -} - -static int ioctl_try_fmt_cap(struct v4l2_int_device *s, - struct v4l2_format *f) -{ - struct tcm825x_sensor *sensor = s->priv; - enum image_size isize; - int ifmt; - struct v4l2_pix_format *pix = &f->fmt.pix; - - isize = tcm825x_find_size(s, pix->width, pix->height); - dev_dbg(&sensor->i2c_client->dev, "isize = %d num_capture = %lu\n", - isize, (unsigned long)TCM825X_NUM_CAPTURE_FORMATS); - - pix->width = tcm825x_sizes[isize].width; - pix->height = tcm825x_sizes[isize].height; - - for (ifmt = 0; ifmt < TCM825X_NUM_CAPTURE_FORMATS; ifmt++) - if (pix->pixelformat == tcm825x_formats[ifmt].pixelformat) - break; - - if (ifmt == TCM825X_NUM_CAPTURE_FORMATS) - ifmt = 0; /* Default = YUV 4:2:2 */ - - pix->pixelformat = tcm825x_formats[ifmt].pixelformat; - pix->field = V4L2_FIELD_NONE; - pix->bytesperline = pix->width * TCM825X_BYTES_PER_PIXEL; - pix->sizeimage = pix->bytesperline * pix->height; - pix->priv = 0; - dev_dbg(&sensor->i2c_client->dev, "format = 0x%08x\n", - pix->pixelformat); - - switch (pix->pixelformat) { - case V4L2_PIX_FMT_UYVY: - default: - pix->colorspace = V4L2_COLORSPACE_JPEG; - break; - case V4L2_PIX_FMT_RGB565: - pix->colorspace = V4L2_COLORSPACE_SRGB; - break; - } - - return 0; -} - -static int ioctl_s_fmt_cap(struct v4l2_int_device *s, - struct v4l2_format *f) -{ - struct tcm825x_sensor *sensor = s->priv; - struct v4l2_pix_format *pix = &f->fmt.pix; - int rval; - - rval = ioctl_try_fmt_cap(s, f); - if (rval) - return rval; - - rval = tcm825x_configure(s); - - sensor->pix = *pix; - - return rval; -} - -static int ioctl_g_fmt_cap(struct v4l2_int_device *s, - struct v4l2_format *f) -{ - struct tcm825x_sensor *sensor = s->priv; - - f->fmt.pix = sensor->pix; - - return 0; -} - -static int ioctl_g_parm(struct v4l2_int_device *s, - struct v4l2_streamparm *a) -{ - struct tcm825x_sensor *sensor = s->priv; - struct v4l2_captureparm *cparm = &a->parm.capture; - - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - memset(a, 0, sizeof(*a)); - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - cparm->capability = V4L2_CAP_TIMEPERFRAME; - cparm->timeperframe = sensor->timeperframe; - - return 0; -} - -static int ioctl_s_parm(struct v4l2_int_device *s, - struct v4l2_streamparm *a) -{ - struct tcm825x_sensor *sensor = s->priv; - struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe; - u32 tgt_fps; /* target frames per secound */ - int rval; - - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if ((timeperframe->numerator == 0) - || (timeperframe->denominator == 0)) { - timeperframe->denominator = DEFAULT_FPS; - timeperframe->numerator = 1; - } - - tgt_fps = timeperframe->denominator / timeperframe->numerator; - - if (tgt_fps > MAX_FPS) { - timeperframe->denominator = MAX_FPS; - timeperframe->numerator = 1; - } else if (tgt_fps < MIN_FPS) { - timeperframe->denominator = MIN_FPS; - timeperframe->numerator = 1; - } - - sensor->timeperframe = *timeperframe; - - rval = tcm825x_configure(s); - - return rval; -} - -static int ioctl_s_power(struct v4l2_int_device *s, int on) -{ - struct tcm825x_sensor *sensor = s->priv; - - return sensor->platform_data->power_set(on); -} - -/* - * Given the image capture format in pix, the nominal frame period in - * timeperframe, calculate the required xclk frequency. - * - * TCM825X input frequency characteristics are: - * Minimum 11.9 MHz, Typical 24.57 MHz and maximum 25/27 MHz - */ - -static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) -{ - struct tcm825x_sensor *sensor = s->priv; - struct v4l2_fract *timeperframe = &sensor->timeperframe; - u32 tgt_xclk; /* target xclk */ - u32 tgt_fps; /* target frames per secound */ - int rval; - - rval = sensor->platform_data->ifparm(p); - if (rval) - return rval; - - tgt_fps = timeperframe->denominator / timeperframe->numerator; - - tgt_xclk = (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) ? - (2457 * tgt_fps) / MAX_HALF_FPS : - (2457 * tgt_fps) / MAX_FPS; - tgt_xclk *= 10000; - - tgt_xclk = min(tgt_xclk, (u32)TCM825X_XCLK_MAX); - tgt_xclk = max(tgt_xclk, (u32)TCM825X_XCLK_MIN); - - p->u.bt656.clock_curr = tgt_xclk; - - return 0; -} - -static int ioctl_g_needs_reset(struct v4l2_int_device *s, void *buf) -{ - struct tcm825x_sensor *sensor = s->priv; - - return sensor->platform_data->needs_reset(s, buf, &sensor->pix); -} - -static int ioctl_reset(struct v4l2_int_device *s) -{ - return -EBUSY; -} - -static int ioctl_init(struct v4l2_int_device *s) -{ - return tcm825x_configure(s); -} - -static int ioctl_dev_exit(struct v4l2_int_device *s) -{ - return 0; -} - -static int ioctl_dev_init(struct v4l2_int_device *s) -{ - struct tcm825x_sensor *sensor = s->priv; - int r; - - r = tcm825x_read_reg(sensor->i2c_client, 0x01); - if (r < 0) - return r; - if (r == 0) { - dev_err(&sensor->i2c_client->dev, "device not detected\n"); - return -EIO; - } - return 0; -} - -static struct v4l2_int_ioctl_desc tcm825x_ioctl_desc[] = { - { vidioc_int_dev_init_num, - (v4l2_int_ioctl_func *)ioctl_dev_init }, - { vidioc_int_dev_exit_num, - (v4l2_int_ioctl_func *)ioctl_dev_exit }, - { vidioc_int_s_power_num, - (v4l2_int_ioctl_func *)ioctl_s_power }, - { vidioc_int_g_ifparm_num, - (v4l2_int_ioctl_func *)ioctl_g_ifparm }, - { vidioc_int_g_needs_reset_num, - (v4l2_int_ioctl_func *)ioctl_g_needs_reset }, - { vidioc_int_reset_num, - (v4l2_int_ioctl_func *)ioctl_reset }, - { vidioc_int_init_num, - (v4l2_int_ioctl_func *)ioctl_init }, - { vidioc_int_enum_fmt_cap_num, - (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap }, - { vidioc_int_try_fmt_cap_num, - (v4l2_int_ioctl_func *)ioctl_try_fmt_cap }, - { vidioc_int_g_fmt_cap_num, - (v4l2_int_ioctl_func *)ioctl_g_fmt_cap }, - { vidioc_int_s_fmt_cap_num, - (v4l2_int_ioctl_func *)ioctl_s_fmt_cap }, - { vidioc_int_g_parm_num, - (v4l2_int_ioctl_func *)ioctl_g_parm }, - { vidioc_int_s_parm_num, - (v4l2_int_ioctl_func *)ioctl_s_parm }, - { vidioc_int_queryctrl_num, - (v4l2_int_ioctl_func *)ioctl_queryctrl }, - { vidioc_int_g_ctrl_num, - (v4l2_int_ioctl_func *)ioctl_g_ctrl }, - { vidioc_int_s_ctrl_num, - (v4l2_int_ioctl_func *)ioctl_s_ctrl }, -}; - -static struct v4l2_int_slave tcm825x_slave = { - .ioctls = tcm825x_ioctl_desc, - .num_ioctls = ARRAY_SIZE(tcm825x_ioctl_desc), -}; - -static struct tcm825x_sensor tcm825x; - -static struct v4l2_int_device tcm825x_int_device = { - .module = THIS_MODULE, - .name = TCM825X_NAME, - .priv = &tcm825x, - .type = v4l2_int_type_slave, - .u = { - .slave = &tcm825x_slave, - }, -}; - -static int tcm825x_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct tcm825x_sensor *sensor = &tcm825x; - - if (i2c_get_clientdata(client)) - return -EBUSY; - - sensor->platform_data = client->dev.platform_data; - - if (sensor->platform_data == NULL - || !sensor->platform_data->is_okay()) - return -ENODEV; - - sensor->v4l2_int_device = &tcm825x_int_device; - - sensor->i2c_client = client; - i2c_set_clientdata(client, sensor); - - /* Make the default capture format QVGA RGB565 */ - sensor->pix.width = tcm825x_sizes[QVGA].width; - sensor->pix.height = tcm825x_sizes[QVGA].height; - sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565; - - return v4l2_int_device_register(sensor->v4l2_int_device); -} - -static int tcm825x_remove(struct i2c_client *client) -{ - struct tcm825x_sensor *sensor = i2c_get_clientdata(client); - - if (!client->adapter) - return -ENODEV; /* our client isn't attached */ - - v4l2_int_device_unregister(sensor->v4l2_int_device); - - return 0; -} - -static const struct i2c_device_id tcm825x_id[] = { - { "tcm825x", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tcm825x_id); - -static struct i2c_driver tcm825x_i2c_driver = { - .driver = { - .name = TCM825X_NAME, - }, - .probe = tcm825x_probe, - .remove = tcm825x_remove, - .id_table = tcm825x_id, -}; - -static struct tcm825x_sensor tcm825x = { - .timeperframe = { - .numerator = 1, - .denominator = DEFAULT_FPS, - }, -}; - -static int __init tcm825x_init(void) -{ - int rval; - - rval = i2c_add_driver(&tcm825x_i2c_driver); - if (rval) - pr_info("%s: failed registering " TCM825X_NAME "\n", - __func__); - - return rval; -} - -static void __exit tcm825x_exit(void) -{ - i2c_del_driver(&tcm825x_i2c_driver); -} - -/* - * FIXME: Menelaus isn't ready (?) at module_init stage, so use - * late_initcall for now. - */ -late_initcall(tcm825x_init); -module_exit(tcm825x_exit); - -MODULE_AUTHOR("Sakari Ailus "); -MODULE_DESCRIPTION("TCM825x camera sensor driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/omap24xx/tcm825x.h b/drivers/staging/media/omap24xx/tcm825x.h deleted file mode 100644 index 8a29636d1ad4..000000000000 --- a/drivers/staging/media/omap24xx/tcm825x.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * drivers/media/i2c/tcm825x.h - * - * Register definitions for the TCM825X CameraChip. - * - * Author: David Cohen (david.cohen@indt.org.br) - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - * This file was based on ov9640.h from MontaVista - */ - -#ifndef TCM825X_H -#define TCM825X_H - -#include - -#include "v4l2-int-device.h" - -#define TCM825X_NAME "tcm825x" - -#define TCM825X_MASK(x) (x & 0x00ff) -#define TCM825X_ADDR(x) ((x & 0xff00) >> 8) - -/* The TCM825X I2C sensor chip has a fixed slave address of 0x3d. */ -#define TCM825X_I2C_ADDR 0x3d - -/* - * define register offsets for the TCM825X sensor chip - * OFFSET(8 bits) + MASK(8 bits) - * MASK bit 4 and 3 are used when the register uses more than one address - */ -#define TCM825X_FPS 0x0280 -#define TCM825X_ACF 0x0240 -#define TCM825X_DOUTBUF 0x020C -#define TCM825X_DCLKP 0x0202 -#define TCM825X_ACFDET 0x0201 -#define TCM825X_DOUTSW 0x0380 -#define TCM825X_DATAHZ 0x0340 -#define TCM825X_PICSIZ 0x033c -#define TCM825X_PICFMT 0x0302 -#define TCM825X_V_INV 0x0480 -#define TCM825X_H_INV 0x0440 -#define TCM825X_ESRLSW 0x0430 -#define TCM825X_V_LENGTH 0x040F -#define TCM825X_ALCSW 0x0580 -#define TCM825X_ESRLIM 0x0560 -#define TCM825X_ESRSPD_U 0x051F -#define TCM825X_ESRSPD_L 0x06FF -#define TCM825X_AG 0x07FF -#define TCM825X_ESRSPD2 0x06FF -#define TCM825X_ALCMODE 0x0830 -#define TCM825X_ALCH 0x080F -#define TCM825X_ALCL 0x09FF -#define TCM825X_AWBSW 0x0A80 -#define TCM825X_MRG 0x0BFF -#define TCM825X_MBG 0x0CFF -#define TCM825X_GAMSW 0x0D80 -#define TCM825X_HDTG 0x0EFF -#define TCM825X_VDTG 0x0FFF -#define TCM825X_HDTCORE 0x10F0 -#define TCM825X_VDTCORE 0x100F -#define TCM825X_CONT 0x11FF -#define TCM825X_BRIGHT 0x12FF -#define TCM825X_VHUE 0x137F -#define TCM825X_UHUE 0x147F -#define TCM825X_VGAIN 0x153F -#define TCM825X_UGAIN 0x163F -#define TCM825X_UVCORE 0x170F -#define TCM825X_SATU 0x187F -#define TCM825X_MHMODE 0x1980 -#define TCM825X_MHLPFSEL 0x1940 -#define TCM825X_YMODE 0x1930 -#define TCM825X_MIXHG 0x1907 -#define TCM825X_LENS 0x1A3F -#define TCM825X_AGLIM 0x1BE0 -#define TCM825X_LENSRPOL 0x1B10 -#define TCM825X_LENSRGAIN 0x1B0F -#define TCM825X_ES100S 0x1CFF -#define TCM825X_ES120S 0x1DFF -#define TCM825X_DMASK 0x1EC0 -#define TCM825X_CODESW 0x1E20 -#define TCM825X_CODESEL 0x1E10 -#define TCM825X_TESPIC 0x1E04 -#define TCM825X_PICSEL 0x1E03 -#define TCM825X_HNUM 0x20FF -#define TCM825X_VOUTPH 0x287F -#define TCM825X_ESROUT 0x327F -#define TCM825X_ESROUT2 0x33FF -#define TCM825X_AGOUT 0x34FF -#define TCM825X_DGOUT 0x353F -#define TCM825X_AGSLOW1 0x39C0 -#define TCM825X_FLLSMODE 0x3930 -#define TCM825X_FLLSLIM 0x390F -#define TCM825X_DETSEL 0x3AF0 -#define TCM825X_ACDETNC 0x3A0F -#define TCM825X_AGSLOW2 0x3BC0 -#define TCM825X_DG 0x3B3F -#define TCM825X_REJHLEV 0x3CFF -#define TCM825X_ALCLOCK 0x3D80 -#define TCM825X_FPSLNKSW 0x3D40 -#define TCM825X_ALCSPD 0x3D30 -#define TCM825X_REJH 0x3D03 -#define TCM825X_SHESRSW 0x3E80 -#define TCM825X_ESLIMSEL 0x3E40 -#define TCM825X_SHESRSPD 0x3E30 -#define TCM825X_ELSTEP 0x3E0C -#define TCM825X_ELSTART 0x3E03 -#define TCM825X_AGMIN 0x3FFF -#define TCM825X_PREGRG 0x423F -#define TCM825X_PREGBG 0x433F -#define TCM825X_PRERG 0x443F -#define TCM825X_PREBG 0x453F -#define TCM825X_MSKBR 0x477F -#define TCM825X_MSKGR 0x487F -#define TCM825X_MSKRB 0x497F -#define TCM825X_MSKGB 0x4A7F -#define TCM825X_MSKRG 0x4B7F -#define TCM825X_MSKBG 0x4C7F -#define TCM825X_HDTCSW 0x4D80 -#define TCM825X_VDTCSW 0x4D40 -#define TCM825X_DTCYL 0x4D3F -#define TCM825X_HDTPSW 0x4E80 -#define TCM825X_VDTPSW 0x4E40 -#define TCM825X_DTCGAIN 0x4E3F -#define TCM825X_DTLLIMSW 0x4F10 -#define TCM825X_DTLYLIM 0x4F0F -#define TCM825X_YLCUTLMSK 0x5080 -#define TCM825X_YLCUTL 0x503F -#define TCM825X_YLCUTHMSK 0x5180 -#define TCM825X_YLCUTH 0x513F -#define TCM825X_UVSKNC 0x527F -#define TCM825X_UVLJ 0x537F -#define TCM825X_WBGMIN 0x54FF -#define TCM825X_WBGMAX 0x55FF -#define TCM825X_WBSPDUP 0x5603 -#define TCM825X_ALLAREA 0x5820 -#define TCM825X_WBLOCK 0x5810 -#define TCM825X_WB2SP 0x580F -#define TCM825X_KIZUSW 0x5920 -#define TCM825X_PBRSW 0x5910 -#define TCM825X_ABCSW 0x5903 -#define TCM825X_PBDLV 0x5AFF -#define TCM825X_PBC1LV 0x5BFF - -#define TCM825X_NUM_REGS (TCM825X_ADDR(TCM825X_PBC1LV) + 1) - -#define TCM825X_BYTES_PER_PIXEL 2 - -#define TCM825X_REG_TERM 0xff /* terminating list entry for reg */ -#define TCM825X_VAL_TERM 0xff /* terminating list entry for val */ - -/* define a structure for tcm825x register initialization values */ -struct tcm825x_reg { - u8 val; - u16 reg; -}; - -enum image_size { subQCIF = 0, QQVGA, QCIF, QVGA, CIF, VGA }; -enum pixel_format { YUV422 = 0, RGB565 }; -#define NUM_IMAGE_SIZES 6 -#define NUM_PIXEL_FORMATS 2 - -#define TCM825X_XCLK_MIN 11900000 -#define TCM825X_XCLK_MAX 25000000 - -struct capture_size { - unsigned long width; - unsigned long height; -}; - -struct tcm825x_platform_data { - /* Is the sensor usable? Doesn't yet mean it's there, but you - * can try! */ - int (*is_okay)(void); - /* Set power state, zero is off, non-zero is on. */ - int (*power_set)(int power); - /* Default registers written after power-on or reset. */ - const struct tcm825x_reg * (*default_regs)(void); - int (*needs_reset)(struct v4l2_int_device *s, void *buf, - struct v4l2_pix_format *fmt); - int (*ifparm)(struct v4l2_ifparm *p); - int (*is_upside_down)(void); -}; - -/* Array of image sizes supported by TCM825X. These must be ordered from - * smallest image size to largest. - */ -static const struct capture_size tcm825x_sizes[] = { - { 128, 96 }, /* subQCIF */ - { 160, 120 }, /* QQVGA */ - { 176, 144 }, /* QCIF */ - { 320, 240 }, /* QVGA */ - { 352, 288 }, /* CIF */ - { 640, 480 }, /* VGA */ -}; - -#endif /* ifndef TCM825X_H */ diff --git a/drivers/staging/media/omap24xx/v4l2-int-device.c b/drivers/staging/media/omap24xx/v4l2-int-device.c deleted file mode 100644 index 427a89033a1d..000000000000 --- a/drivers/staging/media/omap24xx/v4l2-int-device.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * drivers/media/video/v4l2-int-device.c - * - * V4L2 internal ioctl interface. - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include "v4l2-int-device.h" - -static DEFINE_MUTEX(mutex); -static LIST_HEAD(int_list); - -void v4l2_int_device_try_attach_all(void) -{ - struct v4l2_int_device *m, *s; - - list_for_each_entry(m, &int_list, head) { - if (m->type != v4l2_int_type_master) - continue; - - list_for_each_entry(s, &int_list, head) { - if (s->type != v4l2_int_type_slave) - continue; - - /* Slave is connected? */ - if (s->u.slave->master) - continue; - - /* Slave wants to attach to master? */ - if (s->u.slave->attach_to[0] != 0 - && strncmp(m->name, s->u.slave->attach_to, - V4L2NAMESIZE)) - continue; - - if (!try_module_get(m->module)) - continue; - - s->u.slave->master = m; - if (m->u.master->attach(s)) { - s->u.slave->master = NULL; - module_put(m->module); - continue; - } - } - } -} -EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all); - -static int ioctl_sort_cmp(const void *a, const void *b) -{ - const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b; - - if (d1->num > d2->num) - return 1; - - if (d1->num < d2->num) - return -1; - - return 0; -} - -int v4l2_int_device_register(struct v4l2_int_device *d) -{ - if (d->type == v4l2_int_type_slave) - sort(d->u.slave->ioctls, d->u.slave->num_ioctls, - sizeof(struct v4l2_int_ioctl_desc), - &ioctl_sort_cmp, NULL); - mutex_lock(&mutex); - list_add(&d->head, &int_list); - v4l2_int_device_try_attach_all(); - mutex_unlock(&mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(v4l2_int_device_register); - -void v4l2_int_device_unregister(struct v4l2_int_device *d) -{ - mutex_lock(&mutex); - list_del(&d->head); - if (d->type == v4l2_int_type_slave - && d->u.slave->master != NULL) { - d->u.slave->master->u.master->detach(d); - module_put(d->u.slave->master->module); - d->u.slave->master = NULL; - } - mutex_unlock(&mutex); -} -EXPORT_SYMBOL_GPL(v4l2_int_device_unregister); - -/* Adapted from search_extable in extable.c. */ -static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd, - v4l2_int_ioctl_func *no_such_ioctl) -{ - const struct v4l2_int_ioctl_desc *first = slave->ioctls; - const struct v4l2_int_ioctl_desc *last = - first + slave->num_ioctls - 1; - - while (first <= last) { - const struct v4l2_int_ioctl_desc *mid; - - mid = (last - first) / 2 + first; - - if (mid->num < cmd) - first = mid + 1; - else if (mid->num > cmd) - last = mid - 1; - else - return mid->func; - } - - return no_such_ioctl; -} - -static int no_such_ioctl_0(struct v4l2_int_device *d) -{ - return -ENOIOCTLCMD; -} - -int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd) -{ - return ((v4l2_int_ioctl_func_0 *) - find_ioctl(d->u.slave, cmd, - (v4l2_int_ioctl_func *)no_such_ioctl_0))(d); -} -EXPORT_SYMBOL_GPL(v4l2_int_ioctl_0); - -static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg) -{ - return -ENOIOCTLCMD; -} - -int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg) -{ - return ((v4l2_int_ioctl_func_1 *) - find_ioctl(d->u.slave, cmd, - (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg); -} -EXPORT_SYMBOL_GPL(v4l2_int_ioctl_1); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/omap24xx/v4l2-int-device.h b/drivers/staging/media/omap24xx/v4l2-int-device.h deleted file mode 100644 index 0286c95814ff..000000000000 --- a/drivers/staging/media/omap24xx/v4l2-int-device.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * include/media/v4l2-int-device.h - * - * V4L2 internal ioctl interface. - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Sakari Ailus - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef V4L2_INT_DEVICE_H -#define V4L2_INT_DEVICE_H - -#include - -#define V4L2NAMESIZE 32 - -/* - * - * The internal V4L2 device interface core. - * - */ - -enum v4l2_int_type { - v4l2_int_type_master = 1, - v4l2_int_type_slave -}; - -struct module; - -struct v4l2_int_device; - -struct v4l2_int_master { - int (*attach)(struct v4l2_int_device *slave); - void (*detach)(struct v4l2_int_device *slave); -}; - -typedef int (v4l2_int_ioctl_func)(struct v4l2_int_device *); -typedef int (v4l2_int_ioctl_func_0)(struct v4l2_int_device *); -typedef int (v4l2_int_ioctl_func_1)(struct v4l2_int_device *, void *); - -struct v4l2_int_ioctl_desc { - int num; - v4l2_int_ioctl_func *func; -}; - -struct v4l2_int_slave { - /* Don't touch master. */ - struct v4l2_int_device *master; - - char attach_to[V4L2NAMESIZE]; - - int num_ioctls; - struct v4l2_int_ioctl_desc *ioctls; -}; - -struct v4l2_int_device { - /* Don't touch head. */ - struct list_head head; - - struct module *module; - - char name[V4L2NAMESIZE]; - - enum v4l2_int_type type; - union { - struct v4l2_int_master *master; - struct v4l2_int_slave *slave; - } u; - - void *priv; -}; - -void v4l2_int_device_try_attach_all(void); - -int v4l2_int_device_register(struct v4l2_int_device *d); -void v4l2_int_device_unregister(struct v4l2_int_device *d); - -int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd); -int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg); - -/* - * - * Types and definitions for IOCTL commands. - * - */ - -enum v4l2_power { - V4L2_POWER_OFF = 0, - V4L2_POWER_ON, - V4L2_POWER_STANDBY, -}; - -/* Slave interface type. */ -enum v4l2_if_type { - /* - * Parallel 8-, 10- or 12-bit interface, used by for example - * on certain image sensors. - */ - V4L2_IF_TYPE_BT656, -}; - -enum v4l2_if_type_bt656_mode { - /* - * Modes without Bt synchronisation codes. Separate - * synchronisation signal lines are used. - */ - V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT, - V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT, - V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT, - /* - * Use Bt synchronisation codes. The vertical and horizontal - * synchronisation is done based on synchronisation codes. - */ - V4L2_IF_TYPE_BT656_MODE_BT_8BIT, - V4L2_IF_TYPE_BT656_MODE_BT_10BIT, -}; - -struct v4l2_if_type_bt656 { - /* - * 0: Frame begins when vsync is high. - * 1: Frame begins when vsync changes from low to high. - */ - unsigned frame_start_on_rising_vs:1; - /* Use Bt synchronisation codes for sync correction. */ - unsigned bt_sync_correct:1; - /* Swap every two adjacent image data elements. */ - unsigned swap:1; - /* Inverted latch clock polarity from slave. */ - unsigned latch_clk_inv:1; - /* Hs polarity. 0 is active high, 1 active low. */ - unsigned nobt_hs_inv:1; - /* Vs polarity. 0 is active high, 1 active low. */ - unsigned nobt_vs_inv:1; - enum v4l2_if_type_bt656_mode mode; - /* Minimum accepted bus clock for slave (in Hz). */ - u32 clock_min; - /* Maximum accepted bus clock for slave. */ - u32 clock_max; - /* - * Current wish of the slave. May only change in response to - * ioctls that affect image capture. - */ - u32 clock_curr; -}; - -struct v4l2_ifparm { - enum v4l2_if_type if_type; - union { - struct v4l2_if_type_bt656 bt656; - } u; -}; - -/* IOCTL command numbers. */ -enum v4l2_int_ioctl_num { - /* - * - * "Proper" V4L ioctls, as in struct video_device. - * - */ - vidioc_int_enum_fmt_cap_num = 1, - vidioc_int_g_fmt_cap_num, - vidioc_int_s_fmt_cap_num, - vidioc_int_try_fmt_cap_num, - vidioc_int_queryctrl_num, - vidioc_int_g_ctrl_num, - vidioc_int_s_ctrl_num, - vidioc_int_cropcap_num, - vidioc_int_g_crop_num, - vidioc_int_s_crop_num, - vidioc_int_g_parm_num, - vidioc_int_s_parm_num, - vidioc_int_querystd_num, - vidioc_int_s_std_num, - vidioc_int_s_video_routing_num, - - /* - * - * Strictly internal ioctls. - * - */ - /* Initialise the device when slave attaches to the master. */ - vidioc_int_dev_init_num = 1000, - /* Delinitialise the device at slave detach. */ - vidioc_int_dev_exit_num, - /* Set device power state. */ - vidioc_int_s_power_num, - /* - * Get slave private data, e.g. platform-specific slave - * configuration used by the master. - */ - vidioc_int_g_priv_num, - /* Get slave interface parameters. */ - vidioc_int_g_ifparm_num, - /* Does the slave need to be reset after VIDIOC_DQBUF? */ - vidioc_int_g_needs_reset_num, - vidioc_int_enum_framesizes_num, - vidioc_int_enum_frameintervals_num, - - /* - * - * VIDIOC_INT_* ioctls. - * - */ - /* VIDIOC_INT_RESET */ - vidioc_int_reset_num, - /* VIDIOC_INT_INIT */ - vidioc_int_init_num, - - /* - * - * Start of private ioctls. - * - */ - vidioc_int_priv_start_num = 2000, -}; - -/* - * - * IOCTL wrapper functions for better type checking. - * - */ - -#define V4L2_INT_WRAPPER_0(name) \ - static inline int vidioc_int_##name(struct v4l2_int_device *d) \ - { \ - return v4l2_int_ioctl_0(d, vidioc_int_##name##_num); \ - } \ - \ - static inline struct v4l2_int_ioctl_desc \ - vidioc_int_##name##_cb(int (*func) \ - (struct v4l2_int_device *)) \ - { \ - struct v4l2_int_ioctl_desc desc; \ - \ - desc.num = vidioc_int_##name##_num; \ - desc.func = (v4l2_int_ioctl_func *)func; \ - \ - return desc; \ - } - -#define V4L2_INT_WRAPPER_1(name, arg_type, asterisk) \ - static inline int vidioc_int_##name(struct v4l2_int_device *d, \ - arg_type asterisk arg) \ - { \ - return v4l2_int_ioctl_1(d, vidioc_int_##name##_num, \ - (void *)(unsigned long)arg); \ - } \ - \ - static inline struct v4l2_int_ioctl_desc \ - vidioc_int_##name##_cb(int (*func) \ - (struct v4l2_int_device *, \ - arg_type asterisk)) \ - { \ - struct v4l2_int_ioctl_desc desc; \ - \ - desc.num = vidioc_int_##name##_num; \ - desc.func = (v4l2_int_ioctl_func *)func; \ - \ - return desc; \ - } - -V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *); -V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *); -V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *); -V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *); -V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *); -V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *); -V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *); -V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *); -V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *); -V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *); -V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); -V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *); -V4L2_INT_WRAPPER_1(querystd, v4l2_std_id, *); -V4L2_INT_WRAPPER_1(s_std, v4l2_std_id, *); -V4L2_INT_WRAPPER_1(s_video_routing, struct v4l2_routing, *); - -V4L2_INT_WRAPPER_0(dev_init); -V4L2_INT_WRAPPER_0(dev_exit); -V4L2_INT_WRAPPER_1(s_power, enum v4l2_power, ); -V4L2_INT_WRAPPER_1(g_priv, void, *); -V4L2_INT_WRAPPER_1(g_ifparm, struct v4l2_ifparm, *); -V4L2_INT_WRAPPER_1(g_needs_reset, void, *); -V4L2_INT_WRAPPER_1(enum_framesizes, struct v4l2_frmsizeenum, *); -V4L2_INT_WRAPPER_1(enum_frameintervals, struct v4l2_frmivalenum, *); - -V4L2_INT_WRAPPER_0(reset); -V4L2_INT_WRAPPER_0(init); - -#endif -- GitLab From dc6df6e90de9b1e0fb2e2329312b4431de60ad0f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 21 Nov 2014 14:44:31 +0100 Subject: [PATCH 5707/9457] i2c: at91: remove legacy DMA support Since at91sam9g45 is now DT-only, all DMA capable users of this driver are using the DT case, and the legacy support can be removed. Signed-off-by: Arnd Bergmann Signed-off-by: Ludovic Desroches Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 37 +++-------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 77fb6472fd5d..8790f2332458 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -75,7 +75,6 @@ struct at91_twi_pdata { unsigned clk_max_div; unsigned clk_offset; bool has_unre_flag; - bool has_dma_support; struct at_dma_slave dma_slave; }; @@ -556,35 +555,30 @@ static struct at91_twi_pdata at91rm9200_config = { .clk_max_div = 5, .clk_offset = 3, .has_unre_flag = true, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9261_config = { .clk_max_div = 5, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9260_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9g20_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static struct at91_twi_pdata at91sam9g10_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = false, }; static const struct platform_device_id at91_twi_devtypes[] = { @@ -613,7 +607,6 @@ static struct at91_twi_pdata at91sam9x5_config = { .clk_max_div = 7, .clk_offset = 4, .has_unre_flag = false, - .has_dma_support = true, }; static const struct of_device_id atmel_twi_dt_ids[] = { @@ -642,30 +635,11 @@ static const struct of_device_id atmel_twi_dt_ids[] = { MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids); #endif -static bool filter(struct dma_chan *chan, void *pdata) -{ - struct at91_twi_pdata *sl_pdata = pdata; - struct at_dma_slave *sl; - - if (!sl_pdata) - return false; - - sl = &sl_pdata->dma_slave; - if (sl && (sl->dma_dev == chan->device->dev)) { - chan->private = sl; - return true; - } else { - return false; - } -} - static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) { int ret = 0; - struct at91_twi_pdata *pdata = dev->pdata; struct dma_slave_config slave_config; struct at91_twi_dma *dma = &dev->dma; - dma_cap_mask_t mask; memset(&slave_config, 0, sizeof(slave_config)); slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR; @@ -676,19 +650,14 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) slave_config.dst_maxburst = 1; slave_config.device_fc = false; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - dma->chan_tx = dma_request_slave_channel_compat(mask, filter, pdata, - dev->dev, "tx"); + dma->chan_tx = dma_request_slave_channel(dev->dev, "tx"); if (!dma->chan_tx) { dev_err(dev->dev, "can't get a DMA channel for tx\n"); ret = -EBUSY; goto error; } - dma->chan_rx = dma_request_slave_channel_compat(mask, filter, pdata, - dev->dev, "rx"); + dma->chan_rx = dma_request_slave_channel(dev->dev, "rx"); if (!dma->chan_rx) { dev_err(dev->dev, "can't get a DMA channel for rx\n"); ret = -EBUSY; @@ -787,7 +756,7 @@ static int at91_twi_probe(struct platform_device *pdev) } clk_prepare_enable(dev->clk); - if (dev->pdata->has_dma_support) { + if (dev->dev->of_node) { if (at91_twi_configure_dma(dev, phy_addr) == 0) dev->use_dma = true; } -- GitLab From fe37b38bbb7145e080b094b790ba8427945c6ecc Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Thu, 28 Nov 2013 19:15:19 -0300 Subject: [PATCH 5708/9457] [media] rtl2832: implement option to bypass slave demod TS Implement partial PIP mode to carry TS from slave demodulator, through that master demodulator. RTL2832 demod has TS input interface to connected another demodulator TS output. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832.c | 60 +++++++++++++++++++++++++-- drivers/media/dvb-frontends/rtl2832.h | 11 +++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index eb737cf29a36..9026e1aee163 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -258,13 +258,11 @@ static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val, return rtl2832_rd(priv, reg, val, len); } -#if 0 /* currently not used */ /* write single register */ static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val) { return rtl2832_wr_regs(priv, reg, page, &val, 1); } -#endif /* read single register */ static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val) @@ -599,6 +597,11 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) if (fe->ops.tuner_ops.set_params) fe->ops.tuner_ops.set_params(fe); + /* PIP mode related */ + ret = rtl2832_wr_regs(priv, 0x92, 1, "\x00\x0f\xff", 3); + if (ret) + goto err; + /* If the frontend has get_if_frequency(), use it */ if (fe->ops.tuner_ops.get_if_frequency) { u32 if_freq; @@ -661,7 +664,6 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - /* soft reset */ ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1); if (ret) @@ -1020,6 +1022,58 @@ static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv, return 0; } +int rtl2832_enable_external_ts_if(struct dvb_frontend *fe) +{ + struct rtl2832_priv *priv = fe->demodulator_priv; + int ret; + + dev_dbg(&priv->i2c->dev, "%s: setting PIP mode\n", __func__); + + ret = rtl2832_wr_regs(priv, 0x0c, 1, "\x5f\xff", 2); + if (ret) + goto err; + + ret = rtl2832_wr_demod_reg(priv, DVBT_PIP_ON, 0x1); + if (ret) + goto err; + + ret = rtl2832_wr_reg(priv, 0xbc, 0, 0x18); + if (ret) + goto err; + + ret = rtl2832_wr_reg(priv, 0x22, 0, 0x01); + if (ret) + goto err; + + ret = rtl2832_wr_reg(priv, 0x26, 0, 0x1f); + if (ret) + goto err; + + ret = rtl2832_wr_reg(priv, 0x27, 0, 0xff); + if (ret) + goto err; + + ret = rtl2832_wr_regs(priv, 0x92, 1, "\x7f\xf7\xff", 3); + if (ret) + goto err; + + /* soft reset */ + ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1); + if (ret) + goto err; + + ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0); + if (ret) + goto err; + + return 0; +err: + dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + return ret; + +} +EXPORT_SYMBOL(rtl2832_enable_external_ts_if); + struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe) { struct rtl2832_priv *priv = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h index cb3b6b0775b8..5254c1dfc8de 100644 --- a/drivers/media/dvb-frontends/rtl2832.h +++ b/drivers/media/dvb-frontends/rtl2832.h @@ -64,6 +64,10 @@ extern struct i2c_adapter *rtl2832_get_private_i2c_adapter( struct dvb_frontend *fe ); +extern int rtl2832_enable_external_ts_if( + struct dvb_frontend *fe +); + #else static inline struct dvb_frontend *rtl2832_attach( @@ -89,6 +93,13 @@ static inline struct i2c_adapter *rtl2832_get_private_i2c_adapter( return NULL; } +static inline int rtl2832_enable_external_ts_if( + struct dvb_frontend *fe +) +{ + return -ENODEV; +} + #endif -- GitLab From 80f189a1d081f9e8701b974ea6bb59ce89a8d0f9 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 1 Dec 2013 13:44:23 -0300 Subject: [PATCH 5709/9457] [media] rtl28xxu: add support for Panasonic MN88472 slave demod There is RTL2832P devices having extra MN88472 demodulator. This patch add support for such configuration. Logically MN88472 slave demodulator is connected to RTL2832 master demodulator, both I2C bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P chips. Chip version RTL2832P has extra TS interface for connecting slave demodulator. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 135 ++++++++++++++++++------ drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 4 + 2 files changed, 108 insertions(+), 31 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 5ea52c7616f1..d9ee1a9c5cbe 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -24,6 +24,7 @@ #include "rtl2830.h" #include "rtl2832.h" +#include "mn88472.h" #include "qt1010.h" #include "mt2060.h" @@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf}; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0xa1) { priv->tuner = TUNER_RTL2832_FC0012; priv->tuner_name = "FC0012"; - goto found; + goto tuner_found; } /* check FC0013 ID register; reg=00 val=a3 */ @@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0xa3) { priv->tuner = TUNER_RTL2832_FC0013; priv->tuner_name = "FC0013"; - goto found; + goto tuner_found; } /* check MT2266 ID register; reg=00 val=85 */ @@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x85) { priv->tuner = TUNER_RTL2832_MT2266; priv->tuner_name = "MT2266"; - goto found; + goto tuner_found; } /* check FC2580 ID register; reg=01 val=56 */ @@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x56) { priv->tuner = TUNER_RTL2832_FC2580; priv->tuner_name = "FC2580"; - goto found; + goto tuner_found; } /* check MT2063 ID register; reg=00 val=9e || 9c */ @@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { priv->tuner = TUNER_RTL2832_MT2063; priv->tuner_name = "MT2063"; - goto found; + goto tuner_found; } /* check MAX3543 ID register; reg=00 val=38 */ @@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x38) { priv->tuner = TUNER_RTL2832_MAX3543; priv->tuner_name = "MAX3543"; - goto found; + goto tuner_found; } /* check TUA9001 ID register; reg=7e val=2328 */ @@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { priv->tuner = TUNER_RTL2832_TUA9001; priv->tuner_name = "TUA9001"; - goto found; + goto tuner_found; } /* check MXL5007R ID register; reg=d9 val=14 */ @@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x14) { priv->tuner = TUNER_RTL2832_MXL5007T; priv->tuner_name = "MXL5007T"; - goto found; + goto tuner_found; } /* check E4000 ID register; reg=02 val=40 */ @@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x40) { priv->tuner = TUNER_RTL2832_E4000; priv->tuner_name = "E4000"; - goto found; + goto tuner_found; } /* check TDA18272 ID register; reg=00 val=c760 */ @@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { priv->tuner = TUNER_RTL2832_TDA18272; priv->tuner_name = "TDA18272"; - goto found; + goto tuner_found; } /* check R820T ID register; reg=00 val=69 */ @@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x69) { priv->tuner = TUNER_RTL2832_R820T; priv->tuner_name = "R820T"; - goto found; + goto tuner_found; } /* check R828D ID register; reg=00 val=69 */ @@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x69) { priv->tuner = TUNER_RTL2832_R828D; priv->tuner_name = "R828D"; - goto found; + goto tuner_found; } - -found: +tuner_found: dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); + /* probe slave demod */ + if (priv->tuner == TUNER_RTL2832_R828D) { + /* power on MN88472 demod on GPIO0 */ + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01); + if (ret) + goto err; + + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01); + if (ret) + goto err; + + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01); + if (ret) + goto err; + + /* check MN88472 answers */ + ret = rtl28xxu_ctrl_msg(d, &req_mn88472); + if (ret == 0 && buf[0] == 0x02) { + dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__); + priv->slave_demod = SLAVE_DEMOD_MN88472; + goto demod_found; + } + } + +demod_found: /* close demod I2C gate */ ret = rtl28xxu_ctrl_msg(d, &req_gate_close); if (ret < 0) @@ -818,7 +844,44 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) /* set fe callback */ adap->fe[0]->callback = rtl2832u_frontend_callback; + if (priv->slave_demod) { + struct i2c_board_info info = {}; + struct i2c_client *client; + + /* + * We continue on reduced mode, without DVB-T2/C, using master + * demod, when slave demod fails. + */ + ret = 0; + + /* attach slave demodulator */ + if (priv->slave_demod == SLAVE_DEMOD_MN88472) { + struct mn88472_config mn88472_config = {}; + + mn88472_config.fe = &adap->fe[1]; + mn88472_config.i2c_wr_max = 22, + strlcpy(info.type, "mn88472", I2C_NAME_SIZE); + info.addr = 0x18; + info.platform_data = &mn88472_config; + request_module(info.type); + client = i2c_new_device(priv->demod_i2c_adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + priv->i2c_client_slave_demod = client; + } + } + return 0; +err_slave_demod_failed: err: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; @@ -1024,25 +1087,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) &rtl28xxu_rtl2832_r820t_config, NULL); break; case TUNER_RTL2832_R828D: - /* power off mn88472 demod on GPIO0 */ - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01); - if (ret) - goto err; - - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01); - if (ret) - goto err; - - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01); - if (ret) - goto err; - - fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap, + fe = dvb_attach(r820t_attach, adap->fe[0], + priv->demod_i2c_adapter, &rtl2832u_r828d_config); - - /* Use tuner to get the signal strength */ adap->fe[0]->ops.read_signal_strength = adap->fe[0]->ops.tuner_ops.get_rf_strength; + + if (adap->fe[1]) { + fe = dvb_attach(r820t_attach, adap->fe[1], + priv->demod_i2c_adapter, + &rtl2832u_r828d_config); + adap->fe[1]->ops.read_signal_strength = + adap->fe[1]->ops.tuner_ops.get_rf_strength; + } break; default: dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, @@ -1097,11 +1154,19 @@ static int rtl28xxu_init(struct dvb_usb_device *d) static void rtl28xxu_exit(struct dvb_usb_device *d) { struct rtl28xxu_priv *priv = d->priv; - struct i2c_client *client = priv->client; + struct i2c_client *client; dev_dbg(&d->udev->dev, "%s:\n", __func__); /* remove I2C tuner */ + client = priv->client; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + + /* remove I2C slave demod */ + client = priv->i2c_client_slave_demod; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); @@ -1235,6 +1300,7 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff) { struct dvb_usb_device *d = fe_to_d(fe); + struct dvb_usb_adapter *adap = fe_to_adap(fe); int ret; u8 val; @@ -1250,6 +1316,13 @@ static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff) if (ret) goto err; + /* bypass slave demod TS through master demod */ + if (fe->id == 1 && onoff) { + ret = rtl2832_enable_external_ts_if(adap->fe[0]); + if (ret) + goto err; + } + return 0; err: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index a26cab10f382..c1b00b9831c9 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -58,6 +58,10 @@ struct rtl28xxu_priv { struct i2c_adapter *demod_i2c_adapter; bool rc_active; struct i2c_client *client; + struct i2c_client *i2c_client_slave_demod; + #define SLAVE_DEMOD_NONE 0 + #define SLAVE_DEMOD_MN88472 1 + unsigned int slave_demod:1; }; enum rtl28xxu_chip_id { -- GitLab From b2de1d20a05d8691cb1889c859de2ab56938b82a Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Thu, 20 Nov 2014 15:33:17 +0530 Subject: [PATCH 5710/9457] ASoC: samsung: ASoC: samsung: Fix IISMOD setting in i2s_set_sysclk() In the i2s_set_sysclk() callback we are currently clearing all bits of the IISMOD register in i2s_set_sysclk. It's due to an incorrect mask used for the AND operation which is introduced in commit a5a56871f804edac93a53b5e871c0e9818fb9033 (ASoC: samsung: add support for exynos7 I2S controller) and also adds the missing break statement. Signed-off-by: Sylwester Nawrocki Signed-off-by: Padmavathi Venna Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 947352d00ddf..0d76bc15b785 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -494,7 +494,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, if (dir == SND_SOC_CLOCK_IN) mod |= 1 << i2s_regs->cdclkcon_off; else - mod &= 0 << i2s_regs->cdclkcon_off; + mod &= ~(1 << i2s_regs->cdclkcon_off); i2s->rfs = rfs; break; @@ -551,10 +551,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, } if (clk_id == 0) - mod &= 0 << i2s_regs->rclksrc_off; + mod &= ~(1 << i2s_regs->rclksrc_off); else mod |= 1 << i2s_regs->rclksrc_off; + break; default: dev_err(&i2s->pdev->dev, "We don't serve that!\n"); return -EINVAL; -- GitLab From fc694e444c28100e3f33bb5ddb8a0582e42793a8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 30 Sep 2014 01:03:04 -0300 Subject: [PATCH 5711/9457] [media] rtl28xxu: add support for Panasonic MN88473 slave demod There is RTL2832P devices having extra MN88473 demodulator. This patch add support for such configuration. Logically MN88473 slave demodulator is connected to RTL2832 master demodulator, both I2C bus and TS input. RTL2832 is integrated to RTL2832U and RTL2832P chips. Chip version RTL2832P has extra TS interface for connecting slave demodulator. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 31 +++++++++++++++++++++++++ drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index d9ee1a9c5cbe..cb54d2a4c60b 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -25,6 +25,7 @@ #include "rtl2830.h" #include "rtl2832.h" #include "mn88472.h" +#include "mn88473.h" #include "qt1010.h" #include "mt2060.h" @@ -422,6 +423,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf}; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -567,6 +569,13 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) priv->slave_demod = SLAVE_DEMOD_MN88472; goto demod_found; } + + ret = rtl28xxu_ctrl_msg(d, &req_mn88473); + if (ret == 0 && buf[0] == 0x03) { + dev_dbg(&d->udev->dev, "%s: MN88473 found\n", __func__); + priv->slave_demod = SLAVE_DEMOD_MN88473; + goto demod_found; + } } demod_found: @@ -876,6 +885,28 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) goto err_slave_demod_failed; } + priv->i2c_client_slave_demod = client; + } else { + struct mn88473_config mn88473_config = {}; + + mn88473_config.fe = &adap->fe[1]; + mn88473_config.i2c_wr_max = 22, + strlcpy(info.type, "mn88473", I2C_NAME_SIZE); + info.addr = 0x18; + info.platform_data = &mn88473_config; + request_module(info.type); + client = i2c_new_device(priv->demod_i2c_adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + priv->i2c_client_slave_demod = client; } } diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index c1b00b9831c9..7f959ff7451f 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -61,7 +61,8 @@ struct rtl28xxu_priv { struct i2c_client *i2c_client_slave_demod; #define SLAVE_DEMOD_NONE 0 #define SLAVE_DEMOD_MN88472 1 - unsigned int slave_demod:1; + #define SLAVE_DEMOD_MN88473 2 + unsigned int slave_demod:2; }; enum rtl28xxu_chip_id { -- GitLab From 473eadf32ab16987e9cead0855fc396e6e06a9f8 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 11 Nov 2014 21:39:43 -0300 Subject: [PATCH 5712/9457] [media] rtl28xxu: rename tuner I2C client pointer Better to rename tuner I2C to something which clearly says it is for tuner as there is now multiple different I2C clients used. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 6 +++--- drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index cb54d2a4c60b..a527330d1ee1 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1078,7 +1078,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) break; } - priv->client = client; + priv->i2c_client_tuner = client; sd = i2c_get_clientdata(client); i2c_set_adapdata(i2c_adap_internal, d); @@ -1137,7 +1137,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) priv->tuner); } - if (fe == NULL && priv->client == NULL) { + if (fe == NULL && priv->i2c_client_tuner == NULL) { ret = -ENODEV; goto err; } @@ -1190,7 +1190,7 @@ static void rtl28xxu_exit(struct dvb_usb_device *d) dev_dbg(&d->udev->dev, "%s:\n", __func__); /* remove I2C tuner */ - client = priv->client; + client = priv->i2c_client_tuner; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index 7f959ff7451f..3e3ea9d64a38 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -57,7 +57,7 @@ struct rtl28xxu_priv { u8 page; /* integrated demod active register page */ struct i2c_adapter *demod_i2c_adapter; bool rc_active; - struct i2c_client *client; + struct i2c_client *i2c_client_tuner; struct i2c_client *i2c_client_slave_demod; #define SLAVE_DEMOD_NONE 0 #define SLAVE_DEMOD_MN88472 1 -- GitLab From 4507f75013b88ba0175863f4fbb8d7fb11f81d58 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 11 Nov 2014 23:25:27 -0300 Subject: [PATCH 5713/9457] [media] rtl28xxu: remove unused SDR attach logic That logic was duplicated from rtl2832_sdr.h in order to avoid hard dependency for staging directory. rtl2832_sdr is moved to media, so we could remove that code now. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index a527330d1ee1..a30ed17852c0 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -24,6 +24,7 @@ #include "rtl2830.h" #include "rtl2832.h" +#include "rtl2832_sdr.h" #include "mn88472.h" #include "mn88473.h" @@ -37,25 +38,6 @@ #include "tua9001.h" #include "r820t.h" -/* - * RTL2832_SDR module is in staging. That logic is added in order to avoid any - * hard dependency to drivers/staging/ directory as we want compile mainline - * driver even whole staging directory is missing. - */ -#include - -#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR) -struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct rtl2832_config *cfg, - struct v4l2_subdev *sd); -#else -static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct rtl2832_config *cfg, - struct v4l2_subdev *sd) -{ - return NULL; -} -#endif #ifdef CONFIG_MEDIA_ATTACH #define dvb_attach_sdr(FUNCTION, ARGS...) ({ \ -- GitLab From f2500ff3b8a3a832a49ff6fb6f3d7b3fdaae5e5c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 11 Nov 2014 23:31:16 -0300 Subject: [PATCH 5714/9457] [media] rtl28xxu: add SDR module for devices having R828D tuner Load SDR sub-driver in order to support SDR for devices having this tuner too. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index a30ed17852c0..896a225ee011 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1113,6 +1113,10 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) adap->fe[1]->ops.read_signal_strength = adap->fe[1]->ops.tuner_ops.get_rf_strength; } + + /* attach SDR */ + dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, + &rtl28xxu_rtl2832_r820t_config, NULL); break; default: dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, -- GitLab From 8509c55fcb5192b7f70ec596a8752c2ec39942e3 Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Thu, 20 Nov 2014 22:33:07 +0800 Subject: [PATCH 5715/9457] spi: sirf: reset SPI controller in init stage in SPI boot mode, romcode uses SPI controller to fetch data from NOR flash. Here we need to reset the hardware IP to restore its state. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index bf3c6bc77530..0a96a65f580f 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -23,6 +23,7 @@ #include #include #include +#include #define DRIVER_NAME "sirfsoc_spi" @@ -647,6 +648,12 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) int irq; int i, ret; + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "SPI reset failed!\n"); + return ret; + } + master = spi_alloc_master(&pdev->dev, sizeof(*sspi)); if (!master) { dev_err(&pdev->dev, "Unable to allocate SPI master\n"); -- GitLab From 194ed900cac2070175c6e6bf6d23e6bb7400a0f2 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 20 Nov 2014 17:24:17 +0100 Subject: [PATCH 5716/9457] spi: fsl-spi: Don't use cpm_command on CPM1 On CPM1, when the SPI parameter RAM is relocated to somewhere else than the default location, in accordance with freescale documentation (refer micropatch SPI application note EB662), init RX/TX params command shall not be used because it doesn't take into account the new location, and overwrites data that is in original location of SPI param ram at addresses SCC2 param base + (u32*)0x88 (u16*)0x90 (u32*)0x98 (u16*)0xA0, hence breaking activity on SCC2 if SCC2 is used in a mode like QMC for instance. Therefore, the action shall be done manually as described by freescale and as was already partly done by the driver. Reported-by: Patrick Vasseur Signed-off-by: Christophe Leroy Tested-by: Patrick Vasseur Signed-off-by: Mark Brown --- drivers/spi/spi-fsl-cpm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index c5dd20beee22..e85ab1cb17a2 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -56,12 +56,15 @@ void fsl_spi_cpm_reinit_txrx(struct mpc8xxx_spi *mspi) qe_issue_cmd(QE_INIT_TX_RX, mspi->subblock, QE_CR_PROTOCOL_UNSPECIFIED, 0); } else { - cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX); if (mspi->flags & SPI_CPM1) { + out_be32(&mspi->pram->rstate, 0); out_be16(&mspi->pram->rbptr, in_be16(&mspi->pram->rbase)); + out_be32(&mspi->pram->tstate, 0); out_be16(&mspi->pram->tbptr, in_be16(&mspi->pram->tbase)); + } else { + cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX); } } } -- GitLab From 335ca471eebf130d88cb94c1192568b6c75aa9b0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:28:15 +0100 Subject: [PATCH 5717/9457] ASoC: sirf-audio-codec: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. While we are at it also replace dev_get_drvdata() with snd_soc_codec_get_drvdata(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sirf-audio-codec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 06ba4923fd5a..07eea20e6645 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -120,7 +120,8 @@ static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, { #define ATLAS6_CODEC_ENABLE_BITS (1 << 29) #define ATLAS6_CODEC_RESET_BITS (1 << 28) - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_PRE_PMU: enable_and_reset_codec(sirf_audio_codec->regmap, @@ -142,7 +143,8 @@ static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, { #define PRIMA2_CODEC_ENABLE_BITS (1 << 27) #define PRIMA2_CODEC_RESET_BITS (1 << 26) - struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMU: enable_and_reset_codec(sirf_audio_codec->regmap, -- GitLab From 0b5155bbca8b5a8a1456ae462a47eeaedf8ce091 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:21:53 +0100 Subject: [PATCH 5718/9457] ASoC: max98088: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 2cd3e5427441..abf3832e6f8b 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -875,7 +875,7 @@ static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = { static int max98088_mic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); switch (event) { @@ -905,7 +905,7 @@ static int max98088_mic_event(struct snd_soc_dapm_widget *w, static int max98088_line_pga(struct snd_soc_dapm_widget *w, int event, int line, u8 channel) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); u8 *state; -- GitLab From 24445f8c5eae926e402335bbe0292f09b1deb7a7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:21:54 +0100 Subject: [PATCH 5719/9457] ASoC: max98090: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index a65861cf0a44..2ad381c4ec57 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -806,7 +806,7 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = { static int max98090_micinput_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); unsigned int val = snd_soc_read(codec, w->reg); -- GitLab From 0db5dc943e7649bbfbc2d2de8f5cb778b05ea5bd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:21:55 +0100 Subject: [PATCH 5720/9457] ASoC: max98095: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98095.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 42103cafeb24..d911d4cb9add 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -864,7 +864,7 @@ static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = { static int max98095_mic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); switch (event) { @@ -894,7 +894,7 @@ static int max98095_mic_event(struct snd_soc_dapm_widget *w, static int max98095_line_pga(struct snd_soc_dapm_widget *w, int event, u8 channel) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); u8 *state; @@ -942,7 +942,7 @@ static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w, static int max98095_lineout_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: -- GitLab From dee9cec42fc9cc4635ea2f45939e443210a638f8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 21 Nov 2014 18:53:51 +0100 Subject: [PATCH 5721/9457] ASoC: adau17x1: Mark DSP parameter memory as readable and precious To be able to read back data from the DSP parameter memory the register range needs to be marked as readable. At the same time we do not want them to e.g. appear in debugfs output so mark them as precious as well. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1761.c | 1 + sound/soc/codecs/adau1781.c | 1 + sound/soc/codecs/adau17x1.c | 14 ++++++++++++++ sound/soc/codecs/adau17x1.h | 1 + 4 files changed, 17 insertions(+) diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 0ae1501f3c11..4c018c575b01 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -793,6 +793,7 @@ const struct regmap_config adau1761_regmap_config = { .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults), .readable_reg = adau1761_readable_register, .volatile_reg = adau17x1_volatile_register, + .precious_reg = adau17x1_precious_register, .cache_type = REGCACHE_RBTREE, }; EXPORT_SYMBOL_GPL(adau1761_regmap_config); diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index 4c8ddc3c69e1..926fc99c1dda 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -472,6 +472,7 @@ const struct regmap_config adau1781_regmap_config = { .num_reg_defaults = ARRAY_SIZE(adau1781_reg_defaults), .readable_reg = adau1781_readable_register, .volatile_reg = adau17x1_volatile_register, + .precious_reg = adau17x1_precious_register, .cache_type = REGCACHE_RBTREE, }; EXPORT_SYMBOL_GPL(adau1781_regmap_config); diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 1cab34c57413..50000477dc2a 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -706,8 +706,22 @@ int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(adau17x1_set_micbias_voltage); +bool adau17x1_precious_register(struct device *dev, unsigned int reg) +{ + /* SigmaDSP parameter memory */ + if (reg < 0x400) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(adau17x1_precious_register); + bool adau17x1_readable_register(struct device *dev, unsigned int reg) { + /* SigmaDSP parameter memory */ + if (reg < 0x400) + return true; + switch (reg) { case ADAU17X1_CLOCK_CONTROL: case ADAU17X1_PLL_CONTROL: diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index 6861aa3aec02..e13583e6ff56 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -56,6 +56,7 @@ int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, enum adau17x1_micbias_voltage micbias); bool adau17x1_readable_register(struct device *dev, unsigned int reg); bool adau17x1_volatile_register(struct device *dev, unsigned int reg); +bool adau17x1_precious_register(struct device *dev, unsigned int reg); int adau17x1_resume(struct snd_soc_codec *codec); extern const struct snd_soc_dai_ops adau17x1_dai_ops; -- GitLab From 1fc10044d76e86b71f724988c7cbd8205bb903a8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 21 Nov 2014 18:53:52 +0100 Subject: [PATCH 5722/9457] ASoC: sigmadsp: Fix endianness conversion Make sure to always convert the firmware data to local endianness before using it. Reported-by: kbuild test robot Fixes: a35daac77a03 ("ASoC: sigmadsp: Add support for fw v2") Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/sigmadsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 55af596935d4..6abefd27b86c 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -235,7 +235,7 @@ static int sigma_fw_load_control(struct sigmadsp *sigmadsp, ctrl->addr = le16_to_cpu(ctrl_chunk->addr); ctrl->num_bytes = num_bytes; - ctrl->samplerates = chunk->samplerates; + ctrl->samplerates = le32_to_cpu(chunk->samplerates); list_add_tail(&ctrl->head, &sigmadsp->ctrl_list); @@ -266,7 +266,7 @@ static int sigma_fw_load_data(struct sigmadsp *sigmadsp, data->addr = le16_to_cpu(data_chunk->addr); data->length = length; - data->samplerates = chunk->samplerates; + data->samplerates = le32_to_cpu(chunk->samplerates); memcpy(data->data, data_chunk->data, length); list_add_tail(&data->head, &sigmadsp->data_list); @@ -329,7 +329,7 @@ static int sigmadsp_fw_load_v2(struct sigmadsp *sigmadsp, if (length > fw->size - pos || length < sizeof(*chunk)) return -EINVAL; - switch (chunk->tag) { + switch (le32_to_cpu(chunk->tag)) { case SIGMA_FW_CHUNK_TYPE_DATA: ret = sigma_fw_load_data(sigmadsp, chunk, length); break; -- GitLab From e2280c9040d8bc5039617af35ccf7b8ac4abb428 Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Thu, 20 Nov 2014 19:07:48 +0800 Subject: [PATCH 5723/9457] ASoC: wm8960: Add device tree support Document the device tree binding for the WM8960 codec, and modify the driver to extract the platform data from device tree, if present. Signed-off-by: Zidan Wang Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/wm8960.txt | 31 ++++++++++++++ sound/soc/codecs/wm8960.c | 41 ++++++++++++++----- 2 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/wm8960.txt diff --git a/Documentation/devicetree/bindings/sound/wm8960.txt b/Documentation/devicetree/bindings/sound/wm8960.txt new file mode 100644 index 000000000000..2deb8a3da9c5 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8960.txt @@ -0,0 +1,31 @@ +WM8960 audio CODEC + +This device supports I2C only. + +Required properties: + + - compatible : "wlf,wm8960" + + - reg : the I2C address of the device. + +Optional properties: + - wlf,shared-lrclk: This is a boolean property. If present, the LRCM bit of + R24 (Additional control 2) gets set, indicating that ADCLRC and DACLRC pins + will be disabled only when ADC (Left and Right) and DAC (Left and Right) + are disabled. + When wm8960 works on synchronize mode and DACLRC pin is used to supply + frame clock, it will no frame clock for captrue unless enable DAC to enable + DACLRC pin. If shared-lrclk is present, no need to enable DAC for captrue. + + - wlf,capless: This is a boolean property. If present, OUT3 pin will be + enabled and disabled together with HP_L and HP_R pins in response to jack + detect events. + +Example: + +codec: wm8960@1a { + compatible = "wlf,wm8960"; + reg = <0x1a>; + + wlf,shared-lrclk; +}; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 4dc4e85116cd..99d6457c87ba 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -125,6 +125,7 @@ struct wm8960_priv { struct snd_soc_dapm_widget *out3; bool deemph; int playback_fs; + struct wm8960_data pdata; }; #define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) @@ -440,8 +441,8 @@ static const struct snd_soc_dapm_route audio_paths_capless[] = { static int wm8960_add_widgets(struct snd_soc_codec *codec) { - struct wm8960_data *pdata = codec->dev->platform_data; struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); + struct wm8960_data *pdata = &wm8960->pdata; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_widget *w; @@ -961,17 +962,13 @@ static int wm8960_resume(struct snd_soc_codec *codec) static int wm8960_probe(struct snd_soc_codec *codec) { struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - struct wm8960_data *pdata = dev_get_platdata(codec->dev); + struct wm8960_data *pdata = &wm8960->pdata; int ret; - wm8960->set_bias_level = wm8960_set_bias_level_out3; - - if (!pdata) { - dev_warn(codec->dev, "No platform data supplied\n"); - } else { - if (pdata->capless) - wm8960->set_bias_level = wm8960_set_bias_level_capless; - } + if (pdata->capless) + wm8960->set_bias_level = wm8960_set_bias_level_capless; + else + wm8960->set_bias_level = wm8960_set_bias_level_out3; ret = wm8960_reset(codec); if (ret < 0) { @@ -1029,6 +1026,18 @@ static const struct regmap_config wm8960_regmap = { .volatile_reg = wm8960_volatile, }; +static void wm8960_set_pdata_from_of(struct i2c_client *i2c, + struct wm8960_data *pdata) +{ + const struct device_node *np = i2c->dev.of_node; + + if (of_property_read_bool(np, "wlf,capless")) + pdata->capless = true; + + if (of_property_read_bool(np, "wlf,shared-lrclk")) + pdata->shared_lrclk = true; +} + static int wm8960_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1045,6 +1054,11 @@ static int wm8960_i2c_probe(struct i2c_client *i2c, if (IS_ERR(wm8960->regmap)) return PTR_ERR(wm8960->regmap); + if (pdata) + memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data)); + else if (i2c->dev.of_node) + wm8960_set_pdata_from_of(i2c, &wm8960->pdata); + if (pdata && pdata->shared_lrclk) { ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2, 0x4, 0x4); @@ -1075,10 +1089,17 @@ static const struct i2c_device_id wm8960_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); +static const struct of_device_id wm8960_of_match[] = { + { .compatible = "wlf,wm8960", }, + { } +}; +MODULE_DEVICE_TABLE(of, wm8960_of_match); + static struct i2c_driver wm8960_i2c_driver = { .driver = { .name = "wm8960", .owner = THIS_MODULE, + .of_match_table = wm8960_of_match, }, .probe = wm8960_i2c_probe, .remove = wm8960_i2c_remove, -- GitLab From ceb3c0683cfc5dcc2b627985143105f6dfb0b324 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:05:38 +0100 Subject: [PATCH 5724/9457] ASoC: cs42l51: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 09488d97de60..3142bafc9262 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -153,15 +153,17 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + switch (event) { case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, + snd_soc_update_bits(codec, CS42L51_POWER_CTL1, CS42L51_POWER_CTL1_PDN, CS42L51_POWER_CTL1_PDN); break; default: case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, + snd_soc_update_bits(codec, CS42L51_POWER_CTL1, CS42L51_POWER_CTL1_PDN, 0); break; } -- GitLab From 6e2793b98e23372cc80d9b5d981ab2467e90acea Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Nov 2014 21:05:39 +0100 Subject: [PATCH 5725/9457] ASoC: cs42l73: Replace w->codec snd_soc_dapm_to_codec(w->dapm) The codec field of the snd_soc_widget struct is eventually going to be removed, use snd_soc_dapm_to_codec(w->dapm) instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l73.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 2f8b94683e83..7c55537c69cf 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -584,7 +584,7 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMD: @@ -600,7 +600,7 @@ static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w, static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMD: @@ -618,7 +618,7 @@ static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w, static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = w->codec; + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMD: -- GitLab From 3f56d2b31d6a0711082e635c5137fa90951c9995 Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Fri, 21 Nov 2014 15:23:28 -0300 Subject: [PATCH 5726/9457] [media] media: pci: smipcie: Fix dependency for DVB_SMIPCIE In smipcie.c, the function i2c_bit_add_bus() is called. This function is defined by the I2C bit-banging interfaces enabled with CONFIG_I2C_ALGOBIT. As there was no dependency in Kconfig, CONFIG_I2C_ALGOBIT could be set to "m" while CONFIG_DVB_SMIPCIE was set to "y", resulting in a build error due to an undefined reference. This patch adds the dependency on CONFIG_I2C_ALGOBIT in Kconfig by selecting it when CONFIG_DVB_SMIPCIE is selected. Signed-off-by: Andreas Ruprecht Reported-by: Jim Davis Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/smipcie/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig index 75a299295999..57dd124079fc 100644 --- a/drivers/media/pci/smipcie/Kconfig +++ b/drivers/media/pci/smipcie/Kconfig @@ -1,6 +1,7 @@ config DVB_SMIPCIE tristate "SMI PCIe DVBSky cards" depends on DVB_CORE && PCI && I2C + select I2C_ALGOBIT select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT -- GitLab From dfe8e5a1bd37aa0ef6e1b17868721de9efc33587 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Thu, 20 Nov 2014 17:33:47 -0300 Subject: [PATCH 5727/9457] [media] cxusb: initialize si2168_config struct When new parameters are added for si2168 driver, the parameters have to be explicitly defined for each device if the si2168_config struct is not initialized to all zeros. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cxusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index b46f84d49a24..abece57aa2ea 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1435,6 +1435,7 @@ static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) msleep(100); /* attach frontend */ + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &adap->fe_adap[0].fe; si2168_config.ts_mode = SI2168_TS_PARALLEL; -- GitLab From 251a5c4e3c2149e8b2fd64720e20bfa93fc2851d Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Thu, 20 Nov 2014 17:33:48 -0300 Subject: [PATCH 5728/9457] [media] af9035: initialize si2168_config struct When new parameters are added for si2168 driver, the parameters have to be explicitly defined for each device if the si2168_config struct is not initialized to all zeros. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9035.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 1896ab218b11..80a29f5377ea 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1171,6 +1171,7 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap) dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id); + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &adap->fe[0]; si2168_config.ts_mode = SI2168_TS_SERIAL; -- GitLab From bf9025f3e099b8ebc5f68a8ab271d5b30041e52e Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Thu, 20 Nov 2014 17:33:49 -0300 Subject: [PATCH 5729/9457] [media] em28xx: initialize si2168_config struct When new parameters are added for si2168 driver, the parameters have to be explicitly defined for each device if the si2168_config struct is not initialized to all zeros. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-dvb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 65a456d2f454..5a94f174cc74 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1553,6 +1553,7 @@ static int em28xx_dvb_init(struct em28xx *dev) struct si2157_config si2157_config; /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &dvb->fe[0]; si2168_config.ts_mode = SI2168_TS_PARALLEL; -- GitLab From 5937a784c3e5fe8fd1e201f42a2b1ece6c36a6c0 Mon Sep 17 00:00:00 2001 From: Christian Resell Date: Sat, 15 Nov 2014 16:43:37 -0300 Subject: [PATCH 5730/9457] [media] staging: media: bcm2048: fix coding style error Simple style fix (checkpatch.pl: "space prohibited before that ','"). For the eudyptula challenge (http://eudyptula-challenge.org/). Signed-off-by: Christian F. Resell Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 2bba370a47ca..bdc6854d8b53 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2707,7 +2707,7 @@ static int __exit bcm2048_i2c_driver_remove(struct i2c_client *client) * bcm2048_i2c_driver - i2c driver interface */ static const struct i2c_device_id bcm2048_id[] = { - { "bcm2048" , 0 }, + { "bcm2048", 0 }, { }, }; MODULE_DEVICE_TABLE(i2c, bcm2048_id); -- GitLab From d712eaf29d3fe5928d891a4a90ac58644ad595ed Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 18:34:48 +0100 Subject: [PATCH 5731/9457] ALSA: core: Deletion of unnecessary checks before two function calls The functions snd_seq_oss_timer_delete() and vunmap() perform also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/core/seq/oss/seq_oss_init.c | 9 +++------ sound/core/sgbuf.c | 3 +-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index b9184d20c39f..b0e32e161dd1 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -403,14 +403,11 @@ free_devinfo(void *private) { struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private; - if (dp->timer) - snd_seq_oss_timer_delete(dp->timer); + snd_seq_oss_timer_delete(dp->timer); - if (dp->writeq) - snd_seq_oss_writeq_delete(dp->writeq); + snd_seq_oss_writeq_delete(dp->writeq); - if (dp->readq) - snd_seq_oss_readq_delete(dp->readq); + snd_seq_oss_readq_delete(dp->readq); kfree(dp); } diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index 0a418503ec41..84fffabdd129 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c @@ -39,8 +39,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) if (! sgbuf) return -EINVAL; - if (dmab->area) - vunmap(dmab->area); + vunmap(dmab->area); dmab->area = NULL; tmpb.dev.type = SNDRV_DMA_TYPE_DEV; -- GitLab From 42d772101274492ca15258ea346e6ebbc2bc9bd0 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 19:05:50 +0100 Subject: [PATCH 5732/9457] ALSA: es1688_lib: Deletion of an unnecessary check before the function call "release_and_free_resource" The release_and_free_resource() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/isa/es1688/es1688_lib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index de810e484bdf..b5450143407b 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -614,8 +614,7 @@ static int snd_es1688_free(struct snd_es1688 *chip) { if (chip->hardware != ES1688_HW_UNDEF) snd_es1688_init(chip, 0); - if (chip->res_port) - release_and_free_resource(chip->res_port); + release_and_free_resource(chip->res_port); if (chip->irq >= 0) free_irq(chip->irq, (void *) chip); if (chip->dma8 >= 0) { -- GitLab From 966b7bc9354ab8f59f0ef2d96306615157e0f76e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 19:32:02 +0100 Subject: [PATCH 5733/9457] ALSA: sb: Deletion of unnecessary checks before two function calls The functions release_and_free_resource() and snd_util_memhdr_free() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Takashi Iwai --- sound/isa/sb/emu8000_synth.c | 3 +-- sound/isa/sb/sb_common.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c index 4e3fcfb15ad4..95b39beb61c1 100644 --- a/sound/isa/sb/emu8000_synth.c +++ b/sound/isa/sb/emu8000_synth.c @@ -105,8 +105,7 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev) snd_device_free(dev->card, hw->pcm); if (hw->emu) snd_emux_free(hw->emu); - if (hw->memhdr) - snd_util_memhdr_free(hw->memhdr); + snd_util_memhdr_free(hw->memhdr); hw->emu = NULL; hw->memhdr = NULL; return 0; diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 3ef990602cdd..f22b4480828e 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -184,8 +184,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip) static int snd_sbdsp_free(struct snd_sb *chip) { - if (chip->res_port) - release_and_free_resource(chip->res_port); + release_and_free_resource(chip->res_port); if (chip->irq >= 0) free_irq(chip->irq, (void *) chip); #ifdef CONFIG_ISA -- GitLab From 860f6e9eb780443381a76e3766a9698afbc5e2e5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:14 +0100 Subject: [PATCH 5734/9457] net: phy: add static data field to struct phy_driver Add static driver-data field to struct phy_driver, which can be used to store structured device-type information. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- include/linux/phy.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/phy.h b/include/linux/phy.h index 07794e720139..22af8f8f5802 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -433,6 +433,7 @@ struct phy_device { * by this PHY * flags: A bitfield defining certain other features this PHY * supports (like interrupts) + * driver_data: static driver data * * The drivers must implement config_aneg and read_status. All * other functions are optional. Note that none of these @@ -448,6 +449,7 @@ struct phy_driver { unsigned int phy_id_mask; u32 features; u32 flags; + const void *driver_data; /* * Called to issue a PHY software reset -- GitLab From e6a423a81da0eb3da755428f4d2df5a9ba13030f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:15 +0100 Subject: [PATCH 5735/9457] net: phy: micrel: add device-type abstraction Add structured device-type information and support for generic led-mode setup to the generic config_init callback. This is a first step in ultimately getting rid of device-type specific callbacks. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 83 +++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 30e894d6ffbd..1b528137afd9 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -73,6 +73,30 @@ #define PS_TO_REG 200 +struct kszphy_type { + u32 led_mode_reg; +}; + +struct kszphy_priv { + const struct kszphy_type *type; +}; + +static const struct kszphy_type ksz8021_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + +static const struct kszphy_type ksz8041_type = { + .led_mode_reg = MII_KSZPHY_CTRL_1, +}; + +static const struct kszphy_type ksz8051_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + +static const struct kszphy_type ksz8081_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + static int ksz_config_flags(struct phy_device *phydev) { int regval; @@ -229,19 +253,25 @@ static int kszphy_broadcast_disable(struct phy_device *phydev) static int kszphy_config_init(struct phy_device *phydev) { - return 0; -} + struct kszphy_priv *priv = phydev->priv; + const struct kszphy_type *type; -static int kszphy_config_init_led8041(struct phy_device *phydev) -{ - return kszphy_setup_led(phydev, MII_KSZPHY_CTRL_1); + if (!priv) + return 0; + + type = priv->type; + + if (type->led_mode_reg) + kszphy_setup_led(phydev, type->led_mode_reg); + + return 0; } static int ksz8021_config_init(struct phy_device *phydev) { int rc; - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); + kszphy_config_init(phydev); rc = ksz_config_flags(phydev); if (rc < 0) @@ -256,7 +286,7 @@ static int ks8051_config_init(struct phy_device *phydev) { int rc; - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); + kszphy_config_init(phydev); rc = ksz_config_flags(phydev); return rc < 0 ? rc : 0; @@ -265,9 +295,8 @@ static int ks8051_config_init(struct phy_device *phydev) static int ksz8081_config_init(struct phy_device *phydev) { kszphy_broadcast_disable(phydev); - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); - return 0; + return kszphy_config_init(phydev); } static int ksz9021_load_values_from_of(struct phy_device *phydev, @@ -499,6 +528,22 @@ ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, { } +static int kszphy_probe(struct phy_device *phydev) +{ + const struct kszphy_type *type = phydev->drv->driver_data; + struct kszphy_priv *priv; + + priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + priv->type = type; + + return 0; +} + static int ksz8021_probe(struct phy_device *phydev) { struct clk *clk; @@ -517,7 +562,7 @@ static int ksz8021_probe(struct phy_device *phydev) } } - return 0; + return kszphy_probe(phydev); } static struct phy_driver ksphy_driver[] = { @@ -542,6 +587,7 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8021_type, .probe = ksz8021_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, @@ -558,6 +604,7 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8021_type, .probe = ksz8021_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, @@ -574,7 +621,9 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -589,7 +638,9 @@ static struct phy_driver ksphy_driver[] = { .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -604,6 +655,8 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8051_type, + .probe = kszphy_probe, .config_init = ks8051_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, @@ -618,7 +671,9 @@ static struct phy_driver ksphy_driver[] = { .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -632,6 +687,8 @@ static struct phy_driver ksphy_driver[] = { .phy_id_mask = 0x00fffff0, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8081_type, + .probe = kszphy_probe, .config_init = ksz8081_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, -- GitLab From e7a792e945f9bc5eb3032db8db11c762e8ea9ab0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:16 +0100 Subject: [PATCH 5736/9457] net: phy: micrel: parse of nodes at probe Parse the "micrel,led-mode" property at probe, rather than at config_init time in the led-setup helper itself. Note that the bogus parent->of_node bit is removed. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 1b528137afd9..6a81aaca5b1c 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -79,6 +79,7 @@ struct kszphy_type { struct kszphy_priv { const struct kszphy_type *type; + int led_mode; }; static const struct kszphy_type ksz8021_type = { @@ -186,24 +187,9 @@ static int ks8737_config_intr(struct phy_device *phydev) return rc < 0 ? rc : 0; } -static int kszphy_setup_led(struct phy_device *phydev, u32 reg) +static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val) { - - struct device *dev = &phydev->dev; - struct device_node *of_node = dev->of_node; int rc, temp, shift; - u32 val; - - if (!of_node && dev->parent->of_node) - of_node = dev->parent->of_node; - - if (of_property_read_u32(of_node, "micrel,led-mode", &val)) - return 0; - - if (val > 3) { - dev_err(&phydev->dev, "invalid led mode: 0x%02x\n", val); - return -EINVAL; - } switch (reg) { case MII_KSZPHY_CTRL_1: @@ -261,8 +247,8 @@ static int kszphy_config_init(struct phy_device *phydev) type = priv->type; - if (type->led_mode_reg) - kszphy_setup_led(phydev, type->led_mode_reg); + if (priv->led_mode >= 0) + kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode); return 0; } @@ -531,7 +517,9 @@ ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, static int kszphy_probe(struct phy_device *phydev) { const struct kszphy_type *type = phydev->drv->driver_data; + struct device_node *np = phydev->dev.of_node; struct kszphy_priv *priv; + int ret; priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -541,6 +529,21 @@ static int kszphy_probe(struct phy_device *phydev) priv->type = type; + if (type->led_mode_reg) { + ret = of_property_read_u32(np, "micrel,led-mode", + &priv->led_mode); + if (ret) + priv->led_mode = -1; + + if (priv->led_mode > 3) { + dev_err(&phydev->dev, "invalid led mode: 0x%02x\n", + priv->led_mode); + priv->led_mode = -1; + } + } else { + priv->led_mode = -1; + } + return 0; } -- GitLab From 0f95903ef60868a1aba0f9fb2e61419fc3a697f2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:17 +0100 Subject: [PATCH 5737/9457] net: phy: micrel: add has-broadcast-disable flag to type data Add has_broadcast_disable flag to type-data and generic config_init. This allows us to remove the ksz8081 config_init callback. Note that ksz8021_config_init is kept for now due to a95a18afe4c8 ("phy/micrel: KSZ8031RNL RMII clock reconfiguration bug"). Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 6a81aaca5b1c..a0e944099020 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -75,6 +75,7 @@ struct kszphy_type { u32 led_mode_reg; + bool has_broadcast_disable; }; struct kszphy_priv { @@ -96,6 +97,7 @@ static const struct kszphy_type ksz8051_type = { static const struct kszphy_type ksz8081_type = { .led_mode_reg = MII_KSZPHY_CTRL_2, + .has_broadcast_disable = true, }; static int ksz_config_flags(struct phy_device *phydev) @@ -247,6 +249,9 @@ static int kszphy_config_init(struct phy_device *phydev) type = priv->type; + if (type->has_broadcast_disable) + kszphy_broadcast_disable(phydev); + if (priv->led_mode >= 0) kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode); @@ -278,13 +283,6 @@ static int ks8051_config_init(struct phy_device *phydev) return rc < 0 ? rc : 0; } -static int ksz8081_config_init(struct phy_device *phydev) -{ - kszphy_broadcast_disable(phydev); - - return kszphy_config_init(phydev); -} - static int ksz9021_load_values_from_of(struct phy_device *phydev, struct device_node *of_node, u16 reg, char *field1, char *field2, @@ -692,7 +690,7 @@ static struct phy_driver ksphy_driver[] = { .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8081_type, .probe = kszphy_probe, - .config_init = ksz8081_config_init, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, -- GitLab From 63f44b2bfccdd98193bbd602747f780c0fae0f02 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:18 +0100 Subject: [PATCH 5738/9457] net: phy: micrel: add generic clock-mode-select support Add generic RMII-Reference-Clock-Select support. Several Micrel PHY have an RMII-Reference-Clock-Select bit to select 25 MHz or 50 MHz clock mode. Recently, support for configuring this through device tree for KSZ8021 and KSZ8031 was added. Generalise this support so that it can be configured for other PHY types as well. Note that some PHY revisions (of the same type) has this bit inverted. This should be either configurable through a new device-tree property, or preferably, determined based on PHY ID if possible. Also note that this removes support for setting 25 MHz mode from board files which was also added by the above mentioned commit 45f56cb82e45 ("net/phy: micrel: Add clock support for KSZ8021/KSZ8031"). Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 93 ++++++++++++++++++++------------------ include/linux/micrel_phy.h | 1 - 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index a0e944099020..d2e790cd3651 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -57,7 +57,7 @@ #define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) #define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14) #define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14) -#define KSZ8051_RMII_50MHZ_CLK BIT(7) +#define KSZPHY_RMII_REF_CLK_SEL BIT(7) /* Write/read to/from extended registers */ #define MII_KSZPHY_EXTREG 0x0b @@ -76,15 +76,19 @@ struct kszphy_type { u32 led_mode_reg; bool has_broadcast_disable; + bool has_rmii_ref_clk_sel; }; struct kszphy_priv { const struct kszphy_type *type; int led_mode; + bool rmii_ref_clk_sel; + bool rmii_ref_clk_sel_val; }; static const struct kszphy_type ksz8021_type = { .led_mode_reg = MII_KSZPHY_CTRL_2, + .has_rmii_ref_clk_sel = true, }; static const struct kszphy_type ksz8041_type = { @@ -100,21 +104,6 @@ static const struct kszphy_type ksz8081_type = { .has_broadcast_disable = true, }; -static int ksz_config_flags(struct phy_device *phydev) -{ - int regval; - - if (phydev->dev_flags & (MICREL_PHY_50MHZ_CLK | MICREL_PHY_25MHZ_CLK)) { - regval = phy_read(phydev, MII_KSZPHY_CTRL); - if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) - regval |= KSZ8051_RMII_50MHZ_CLK; - else - regval &= ~KSZ8051_RMII_50MHZ_CLK; - return phy_write(phydev, MII_KSZPHY_CTRL, regval); - } - return 0; -} - static int kszphy_extended_write(struct phy_device *phydev, u32 regnum, u16 val) { @@ -189,6 +178,22 @@ static int ks8737_config_intr(struct phy_device *phydev) return rc < 0 ? rc : 0; } +static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val) +{ + int ctrl; + + ctrl = phy_read(phydev, MII_KSZPHY_CTRL); + if (ctrl < 0) + return ctrl; + + if (val) + ctrl |= KSZPHY_RMII_REF_CLK_SEL; + else + ctrl &= ~KSZPHY_RMII_REF_CLK_SEL; + + return phy_write(phydev, MII_KSZPHY_CTRL, ctrl); +} + static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val) { int rc, temp, shift; @@ -243,6 +248,7 @@ static int kszphy_config_init(struct phy_device *phydev) { struct kszphy_priv *priv = phydev->priv; const struct kszphy_type *type; + int ret; if (!priv) return 0; @@ -252,6 +258,14 @@ static int kszphy_config_init(struct phy_device *phydev) if (type->has_broadcast_disable) kszphy_broadcast_disable(phydev); + if (priv->rmii_ref_clk_sel) { + ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val); + if (ret) { + dev_err(&phydev->dev, "failed to set rmii reference clock\n"); + return ret; + } + } + if (priv->led_mode >= 0) kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode); @@ -262,10 +276,8 @@ static int ksz8021_config_init(struct phy_device *phydev) { int rc; - kszphy_config_init(phydev); - - rc = ksz_config_flags(phydev); - if (rc < 0) + rc = kszphy_config_init(phydev); + if (rc) return rc; rc = kszphy_broadcast_disable(phydev); @@ -273,16 +285,6 @@ static int ksz8021_config_init(struct phy_device *phydev) return rc < 0 ? rc : 0; } -static int ks8051_config_init(struct phy_device *phydev) -{ - int rc; - - kszphy_config_init(phydev); - - rc = ksz_config_flags(phydev); - return rc < 0 ? rc : 0; -} - static int ksz9021_load_values_from_of(struct phy_device *phydev, struct device_node *of_node, u16 reg, char *field1, char *field2, @@ -517,6 +519,7 @@ static int kszphy_probe(struct phy_device *phydev) const struct kszphy_type *type = phydev->drv->driver_data; struct device_node *np = phydev->dev.of_node; struct kszphy_priv *priv; + struct clk *clk; int ret; priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL); @@ -542,28 +545,32 @@ static int kszphy_probe(struct phy_device *phydev) priv->led_mode = -1; } - return 0; -} - -static int ksz8021_probe(struct phy_device *phydev) -{ - struct clk *clk; - clk = devm_clk_get(&phydev->dev, "rmii-ref"); if (!IS_ERR(clk)) { unsigned long rate = clk_get_rate(clk); + priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; + + /* FIXME: add support for PHY revisions that have this bit + * inverted (e.g. through new property or based on PHY ID). + */ if (rate > 24500000 && rate < 25500000) { - phydev->dev_flags |= MICREL_PHY_25MHZ_CLK; + priv->rmii_ref_clk_sel_val = false; } else if (rate > 49500000 && rate < 50500000) { - phydev->dev_flags |= MICREL_PHY_50MHZ_CLK; + priv->rmii_ref_clk_sel_val = true; } else { dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate); return -EINVAL; } } - return kszphy_probe(phydev); + /* Support legacy board-file configuration */ + if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { + priv->rmii_ref_clk_sel = true; + priv->rmii_ref_clk_sel_val = true; + } + + return 0; } static struct phy_driver ksphy_driver[] = { @@ -589,7 +596,7 @@ static struct phy_driver ksphy_driver[] = { SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8021_type, - .probe = ksz8021_probe, + .probe = kszphy_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, @@ -606,7 +613,7 @@ static struct phy_driver ksphy_driver[] = { SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8021_type, - .probe = ksz8021_probe, + .probe = kszphy_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, @@ -658,7 +665,7 @@ static struct phy_driver ksphy_driver[] = { .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .driver_data = &ksz8051_type, .probe = kszphy_probe, - .config_init = ks8051_config_init, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index 53d33dee70e1..2e5b194b9b19 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h @@ -37,7 +37,6 @@ /* struct phy_device dev_flags definitions */ #define MICREL_PHY_50MHZ_CLK 0x00000001 -#define MICREL_PHY_25MHZ_CLK 0x00000002 #define MICREL_KSZ9021_EXTREG_CTRL 0xB #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC -- GitLab From 86dc1342bcbb1905b2ac9653a559b303f62bd728 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:19 +0100 Subject: [PATCH 5739/9457] net: phy: micrel: add support for clock-mode select to KSZ8081/KSZ8091 Micrel KSZ8081 and KSZ8091 PHYs have the RMII Reference Clock Select bit, which is used to select 25 or 50 MHz clock mode. Note that on some revisions of the PHY (e.g. KSZ8081RND) the function of this bit is inverted so that setting it enables 25 rather than 50 MHz mode. Add a new device-tree property "micrel,rmii-reference-clock-select-25-mhz" to describe this. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/micrel.txt | 4 ++-- drivers/net/phy/micrel.c | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt index 30062fae5623..a1bab5eaae02 100644 --- a/Documentation/devicetree/bindings/net/micrel.txt +++ b/Documentation/devicetree/bindings/net/micrel.txt @@ -22,5 +22,5 @@ Optional properties: - clocks, clock-names: contains clocks according to the common clock bindings. supported clocks: - - KSZ8021, KSZ8031: "rmii-ref": The RMII refence input clock. Used - to determine the XI input clock. + - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII + refence input clock. Used to determine the XI input clock. diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index d2e790cd3651..04fbee846b66 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -102,6 +102,7 @@ static const struct kszphy_type ksz8051_type = { static const struct kszphy_type ksz8081_type = { .led_mode_reg = MII_KSZPHY_CTRL_2, .has_broadcast_disable = true, + .has_rmii_ref_clk_sel = true, }; static int kszphy_extended_write(struct phy_device *phydev, @@ -548,16 +549,16 @@ static int kszphy_probe(struct phy_device *phydev) clk = devm_clk_get(&phydev->dev, "rmii-ref"); if (!IS_ERR(clk)) { unsigned long rate = clk_get_rate(clk); + bool rmii_ref_clk_sel_25_mhz; priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; + rmii_ref_clk_sel_25_mhz = of_property_read_bool(np, + "micrel,rmii-reference-clock-select-25-mhz"); - /* FIXME: add support for PHY revisions that have this bit - * inverted (e.g. through new property or based on PHY ID). - */ if (rate > 24500000 && rate < 25500000) { - priv->rmii_ref_clk_sel_val = false; + priv->rmii_ref_clk_sel_val = rmii_ref_clk_sel_25_mhz; } else if (rate > 49500000 && rate < 50500000) { - priv->rmii_ref_clk_sel_val = true; + priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz; } else { dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate); return -EINVAL; -- GitLab From 6d01329444725a5c17cf75ba6c5c0c5e42843613 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:20 +0100 Subject: [PATCH 5740/9457] dt/bindings: reformat micrel eth-phy documentation Reduce indentation of Micrel PHY binding documentations somewhat. Also fix "reference input clock" typo while at it. Cc: devicetree@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- .../devicetree/bindings/net/micrel.txt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt index a1bab5eaae02..20a6cac7abc6 100644 --- a/Documentation/devicetree/bindings/net/micrel.txt +++ b/Documentation/devicetree/bindings/net/micrel.txt @@ -6,21 +6,21 @@ Optional properties: - micrel,led-mode : LED mode value to set for PHYs with configurable LEDs. - Configure the LED mode with single value. The list of PHYs and - the bits that are currently supported: + Configure the LED mode with single value. The list of PHYs and the + bits that are currently supported: - KSZ8001: register 0x1e, bits 15..14 - KSZ8041: register 0x1e, bits 15..14 - KSZ8021: register 0x1f, bits 5..4 - KSZ8031: register 0x1f, bits 5..4 - KSZ8051: register 0x1f, bits 5..4 - KSZ8081: register 0x1f, bits 5..4 - KSZ8091: register 0x1f, bits 5..4 + KSZ8001: register 0x1e, bits 15..14 + KSZ8041: register 0x1e, bits 15..14 + KSZ8021: register 0x1f, bits 5..4 + KSZ8031: register 0x1f, bits 5..4 + KSZ8051: register 0x1f, bits 5..4 + KSZ8081: register 0x1f, bits 5..4 + KSZ8091: register 0x1f, bits 5..4 - See the respective PHY datasheet for the mode values. + See the respective PHY datasheet for the mode values. - clocks, clock-names: contains clocks according to the common clock bindings. - supported clocks: - - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII - refence input clock. Used to determine the XI input clock. + supported clocks: + - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII reference + input clock. Used to determine the XI input clock. -- GitLab From c3a8e1eddd6c140fbaaf957f7da8f2175f79623d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:21 +0100 Subject: [PATCH 5741/9457] dt/bindings: add clock-select function property to micrel phy binding Add "micrel,rmii-reference-clock-select-25-mhz" to Micrel ethernet PHY binding documentation. This property is needed to properly describe some revisions of Micrel PHYs which has the function of this configuration bit inverted so that setting it enables 25 MHz rather than 50 MHz clock mode. Note that a clock reference ("rmii-ref") is still needed to actually select either mode. Cc: devicetree@vger.kernel.org Signed-off-by: Johan Hovold Acked-by: Sascha Hauer Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/micrel.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/net/micrel.txt b/Documentation/devicetree/bindings/net/micrel.txt index 20a6cac7abc6..87496a8c64ab 100644 --- a/Documentation/devicetree/bindings/net/micrel.txt +++ b/Documentation/devicetree/bindings/net/micrel.txt @@ -19,6 +19,17 @@ Optional properties: See the respective PHY datasheet for the mode values. + - micrel,rmii-reference-clock-select-25-mhz: RMII Reference Clock Select + bit selects 25 MHz mode + + Setting the RMII Reference Clock Select bit enables 25 MHz rather + than 50 MHz clock mode. + + Note that this option in only needed for certain PHY revisions with a + non-standard, inverted function of this configuration bit. + Specifically, a clock reference ("rmii-ref" below) is always needed to + actually select a mode. + - clocks, clock-names: contains clocks according to the common clock bindings. supported clocks: -- GitLab From c6f9575cc86250422c84972219e2a1bd7ec7e2ae Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:22 +0100 Subject: [PATCH 5742/9457] net: phy: micrel: refactor interrupt config Add generic interrupt-config callback and store interrupt-level bitmask in type data for PHY types not using bit 9. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 71 ++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 04fbee846b66..d7eb7b0e6d4e 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -55,8 +55,6 @@ #define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2 /* bitmap of PHY register to set interrupt mode */ #define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) -#define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14) -#define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14) #define KSZPHY_RMII_REF_CLK_SEL BIT(7) /* Write/read to/from extended registers */ @@ -75,6 +73,7 @@ struct kszphy_type { u32 led_mode_reg; + u16 interrupt_level_mask; bool has_broadcast_disable; bool has_rmii_ref_clk_sel; }; @@ -105,6 +104,14 @@ static const struct kszphy_type ksz8081_type = { .has_rmii_ref_clk_sel = true, }; +static const struct kszphy_type ks8737_type = { + .interrupt_level_mask = BIT(14), +}; + +static const struct kszphy_type ksz9021_type = { + .interrupt_level_mask = BIT(14), +}; + static int kszphy_extended_write(struct phy_device *phydev, u32 regnum, u16 val) { @@ -129,54 +136,31 @@ static int kszphy_ack_interrupt(struct phy_device *phydev) return (rc < 0) ? rc : 0; } -static int kszphy_set_interrupt(struct phy_device *phydev) -{ - int temp; - temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? - KSZPHY_INTCS_ALL : 0; - return phy_write(phydev, MII_KSZPHY_INTCS, temp); -} - static int kszphy_config_intr(struct phy_device *phydev) { - int temp, rc; - - /* set the interrupt pin active low */ - temp = phy_read(phydev, MII_KSZPHY_CTRL); - if (temp < 0) - return temp; - temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; - phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; -} + const struct kszphy_type *type = phydev->drv->driver_data; + int temp; + u16 mask; -static int ksz9021_config_intr(struct phy_device *phydev) -{ - int temp, rc; + if (type && type->interrupt_level_mask) + mask = type->interrupt_level_mask; + else + mask = KSZPHY_CTRL_INT_ACTIVE_HIGH; /* set the interrupt pin active low */ temp = phy_read(phydev, MII_KSZPHY_CTRL); if (temp < 0) return temp; - temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; + temp &= ~mask; phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; -} -static int ks8737_config_intr(struct phy_device *phydev) -{ - int temp, rc; + /* enable / disable interrupts */ + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + temp = KSZPHY_INTCS_ALL; + else + temp = 0; - /* set the interrupt pin active low */ - temp = phy_read(phydev, MII_KSZPHY_CTRL); - if (temp < 0) - return temp; - temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; - phy_write(phydev, MII_KSZPHY_CTRL, temp); - rc = kszphy_set_interrupt(phydev); - return rc < 0 ? rc : 0; + return phy_write(phydev, MII_KSZPHY_INTCS, temp); } static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val) @@ -581,11 +565,12 @@ static struct phy_driver ksphy_driver[] = { .name = "Micrel KS8737", .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ks8737_type, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, - .config_intr = ks8737_config_intr, + .config_intr = kszphy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, @@ -726,11 +711,12 @@ static struct phy_driver ksphy_driver[] = { .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz9021_type, .config_init = ksz9021_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, - .config_intr = ksz9021_config_intr, + .config_intr = kszphy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, .read_mmd_indirect = ksz9021_rd_mmd_phyreg, @@ -742,11 +728,12 @@ static struct phy_driver ksphy_driver[] = { .name = "Micrel KSZ9031 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz9021_type, .config_init = ksz9031_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, - .config_intr = ksz9021_config_intr, + .config_intr = kszphy_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, .driver = { .owner = THIS_MODULE, }, -- GitLab From ee0dc2fbfc915b349a42ee808242321ffda6abef Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 Nov 2014 12:59:23 +0100 Subject: [PATCH 5743/9457] net: phy: micrel: add copyright entry Add myself to the list of copyright holders. Signed-off-by: Johan Hovold Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index d7eb7b0e6d4e..c530de1e63f5 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -6,6 +6,7 @@ * Author: David J. Choi * * Copyright (c) 2010-2013 Micrel, Inc. + * Copyright (c) 2014 Johan Hovold * * 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 -- GitLab From fe1591224a1c454f4344d59e11ccd44577c00508 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Wed, 19 Nov 2014 13:24:39 +0100 Subject: [PATCH 5744/9457] l2tp_eth: allow to set a specific mac address Signed-off-by: Alexander Couzens Signed-off-by: David S. Miller --- net/l2tp/l2tp_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index edb78e69efe4..781b3a226ba7 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -126,6 +126,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { .ndo_uninit = l2tp_eth_dev_uninit, .ndo_start_xmit = l2tp_eth_dev_xmit, .ndo_get_stats64 = l2tp_eth_get_stats64, + .ndo_set_mac_address = eth_mac_addr, }; static void l2tp_eth_dev_setup(struct net_device *dev) -- GitLab From 1abcd82c20e7cbfd2b89d834b24ff68feae158ec Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:04:55 +0100 Subject: [PATCH 5745/9457] openvswitch: actions: use skb_postpull_rcsum when possible Replace duplicated code by calling skb_postpull_rcsum Suggested-by: Eric Dumazet Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Acked-by: Simon Horman Signed-off-by: David S. Miller --- net/openvswitch/actions.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 394efa67934e..749a30163071 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -175,10 +175,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, if (unlikely(err)) return err; - if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->csum = csum_sub(skb->csum, - csum_partial(skb_mpls_header(skb), - MPLS_HLEN, 0)); + skb_postpull_rcsum(skb, skb_mpls_header(skb), MPLS_HLEN); memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb), skb->mac_len); @@ -230,9 +227,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) if (unlikely(err)) return err; - if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->csum = csum_sub(skb->csum, csum_partial(skb->data - + (2 * ETH_ALEN), VLAN_HLEN, 0)); + skb_postpull_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); *current_tci = vhdr->h_vlan_TCI; -- GitLab From b960a0ac6939ef4962c5abbf33e80d1382b45fc1 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:04:56 +0100 Subject: [PATCH 5746/9457] vlan: make __vlan_hwaccel_put_tag return void Always returns the same skb it gets, so change to void. Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- drivers/scsi/fcoe/fcoe.c | 6 ++---- include/linux/if_vlan.h | 9 ++++----- net/8021q/vlan_dev.c | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 4a8ac7d8c76b..73a8cc485f87 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1669,10 +1669,8 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) { /* must set skb->dev before calling vlan_put_tag */ skb->dev = fcoe->realdev; - skb = __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), - vlan_dev_vlan_id(fcoe->netdev)); - if (!skb) - return -ENOMEM; + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + vlan_dev_vlan_id(fcoe->netdev)); } else skb->dev = fcoe->netdev; diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index d69f0577a319..1b5dbc2711f9 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -347,13 +347,11 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, * * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest */ -static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, - __be16 vlan_proto, - u16 vlan_tci) +static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { skb->vlan_proto = vlan_proto; skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; - return skb; } /** @@ -368,7 +366,8 @@ static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) { if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) { - return __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); + __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); + return skb; } else { return __vlan_put_tag(skb, vlan_proto, vlan_tci); } diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 0d441ec8763e..d6524b2b206a 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -150,7 +150,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, u16 vlan_tci; vlan_tci = vlan->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); - skb = __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci); + __vlan_hwaccel_put_tag(skb, vlan->vlan_proto, vlan_tci); } skb->dev = vlan->real_dev; -- GitLab From b4bef1b57544b18899eb15569e3bafd8d2eeeff6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:04:57 +0100 Subject: [PATCH 5747/9457] vlan: kill vlan_put_tag helper Since both tx and rx paths work with skb->vlan_tci, there's no need for this function anymore. Switch users directly to __vlan_hwaccel_put_tag. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 17 ++++------------- drivers/net/bonding/bond_main.c | 8 ++------ drivers/net/usb/cdc_mbim.c | 2 +- include/linux/if_vlan.h | 19 ------------------- 4 files changed, 7 insertions(+), 39 deletions(-) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index e1f1a006af85..bb9e9fc45e1b 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -475,12 +475,8 @@ static void rlb_update_client(struct rlb_client_info *client_info) skb->dev = client_info->slave->dev; if (client_info->vlan_id) { - skb = vlan_put_tag(skb, htons(ETH_P_8021Q), client_info->vlan_id); - if (!skb) { - netdev_err(client_info->slave->bond->dev, - "failed to insert VLAN tag\n"); - continue; - } + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + client_info->vlan_id); } arp_xmit(skb); @@ -951,13 +947,8 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], skb->priority = TC_PRIO_CONTROL; skb->dev = slave->dev; - if (vid) { - skb = vlan_put_tag(skb, vlan_proto, vid); - if (!skb) { - netdev_err(slave->bond->dev, "failed to insert VLAN tag\n"); - return; - } - } + if (vid) + __vlan_hwaccel_put_tag(skb, vlan_proto, vid); dev_queue_xmit(skb); } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8575fee8b359..e26c68232032 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2159,12 +2159,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, if (outer_tag->vlan_id) { netdev_dbg(slave_dev, "outer tag: proto %X vid %X\n", ntohs(outer_tag->vlan_proto), outer_tag->vlan_id); - skb = vlan_put_tag(skb, outer_tag->vlan_proto, - outer_tag->vlan_id); - if (!skb) { - net_err_ratelimited("failed to insert outer VLAN tag\n"); - return; - } + __vlan_hwaccel_put_tag(skb, outer_tag->vlan_proto, + outer_tag->vlan_id); } xmit: diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 5ee7a1dbc023..96fc8a5bde84 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -402,7 +402,7 @@ static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_ /* map MBIM session to VLAN */ if (tci) - vlan_put_tag(skb, htons(ETH_P_8021Q), tci); + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tci); err: return skb; } diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 1b5dbc2711f9..75b70a5e4a6d 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -354,25 +354,6 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; } -/** - * vlan_put_tag - inserts VLAN tag according to device features - * @skb: skbuff to tag - * @vlan_tci: VLAN TCI to insert - * - * Assumes skb->dev is the target that will xmit this frame. - * Returns a VLAN tagged skb. - */ -static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, - __be16 vlan_proto, u16 vlan_tci) -{ - if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) { - __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); - return skb; - } else { - return __vlan_put_tag(skb, vlan_proto, vlan_tci); - } -} - /** * __vlan_get_tag - get the VLAN ID that is part of the payload * @skb: skbuff to query -- GitLab From 62749e2cb3c4a7da3eaa5c01a7e787aebeff8536 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:04:58 +0100 Subject: [PATCH 5748/9457] vlan: rename __vlan_put_tag to vlan_insert_tag_set_proto Name fits better. Plus there's going to be introduced __vlan_insert_tag later on. Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/ethernet/emulex/benet/be_main.c | 6 ++++-- drivers/net/vxlan.c | 12 ++++++------ include/linux/if_vlan.h | 8 +++++--- net/bridge/br_vlan.c | 4 ++-- net/core/dev.c | 4 ++-- net/core/netpoll.c | 4 ++-- net/ipv4/geneve.c | 11 +++++------ net/openvswitch/actions.c | 4 +++- net/openvswitch/datapath.c | 3 ++- net/openvswitch/vport-gre.c | 6 +++--- 11 files changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e26c68232032..c1d7da427a3e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2146,8 +2146,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n", ntohs(outer_tag->vlan_proto), tags->vlan_id); - skb = __vlan_put_tag(skb, tags->vlan_proto, - tags->vlan_id); + skb = vlan_insert_tag_set_proto(skb, tags->vlan_proto, + tags->vlan_id); if (!skb) { net_err_ratelimited("failed to insert inner VLAN tag\n"); return; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 54160cc62656..d02fbc7694ea 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -887,7 +887,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, } if (vlan_tag) { - skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); + skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q), + vlan_tag); if (unlikely(!skb)) return skb; skb->vlan_tci = 0; @@ -896,7 +897,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, /* Insert the outer VLAN, if any */ if (adapter->qnq_vid) { vlan_tag = adapter->qnq_vid; - skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); + skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q), + vlan_tag); if (unlikely(!skb)) return skb; if (skip_hw_vlan) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 23b1e8c0d547..bb8fbab438e8 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1600,9 +1600,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, return err; if (vlan_tx_tag_present(skb)) { - if (WARN_ON(!__vlan_put_tag(skb, - skb->vlan_proto, - vlan_tx_tag_get(skb)))) + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (WARN_ON(!skb)) return -ENOMEM; skb->vlan_tci = 0; @@ -1644,9 +1644,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, return err; if (vlan_tx_tag_present(skb)) { - if (WARN_ON(!__vlan_put_tag(skb, - skb->vlan_proto, - vlan_tx_tag_get(skb)))) + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (WARN_ON(!skb)) return -ENOMEM; skb->vlan_tci = 0; diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 75b70a5e4a6d..46e4a15b9b55 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -320,8 +320,9 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, } /** - * __vlan_put_tag - regular VLAN tag inserting + * vlan_insert_tag_set_proto - regular VLAN tag inserting * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol * @vlan_tci: VLAN TCI to insert * * Inserts the VLAN tag into @skb as part of the payload @@ -330,8 +331,9 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, * Following the skb_unshare() example, in case of error, the calling function * doesn't have to worry about freeing the original skb. */ -static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, - __be16 vlan_proto, u16 vlan_tci) +static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb, + __be16 vlan_proto, + u16 vlan_tci) { skb = vlan_insert_tag(skb, vlan_proto, vlan_tci); if (skb) diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 150048fb99b0..97b8ddf57363 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -199,8 +199,8 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, if (skb->vlan_proto != proto) { /* Protocol-mismatch, empty out vlan_tci for new tag */ skb_push(skb, ETH_HLEN); - skb = __vlan_put_tag(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); if (unlikely(!skb)) return false; diff --git a/net/core/dev.c b/net/core/dev.c index 1ab168e0fdf7..3611e60df407 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2645,8 +2645,8 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, { if (vlan_tx_tag_present(skb) && !vlan_hw_offload_capable(features, skb->vlan_proto)) { - skb = __vlan_put_tag(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); if (skb) skb->vlan_tci = 0; } diff --git a/net/core/netpoll.c b/net/core/netpoll.c index e6645b4f330a..65d372384a3f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -79,8 +79,8 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev, if (vlan_tx_tag_present(skb) && !vlan_hw_offload_capable(features, skb->vlan_proto)) { - skb = __vlan_put_tag(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); if (unlikely(!skb)) { /* This is actually a packet drop, but we * don't want the code that calls this diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 31802afce34f..fd430a6a1c37 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c @@ -132,12 +132,11 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, return err; if (vlan_tx_tag_present(skb)) { - if (unlikely(!__vlan_put_tag(skb, - skb->vlan_proto, - vlan_tx_tag_get(skb)))) { - err = -ENOMEM; - return err; - } + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (unlikely(!skb) + return -ENOMEM; + skb->vlan_tci = 0; } diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 749a30163071..426b9131ede0 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -287,7 +287,9 @@ static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key, /* push down current VLAN tag */ current_tag = vlan_tx_tag_get(skb); - if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag)) + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + current_tag); + if (!skb) return -ENOMEM; /* Update mac_len for subsequent MPLS actions */ skb->mac_len += VLAN_HLEN; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index ab141d49bb9d..c63e60e4d947 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -425,7 +425,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, if (!nskb) return -ENOMEM; - nskb = __vlan_put_tag(nskb, nskb->vlan_proto, vlan_tx_tag_get(nskb)); + nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto, + vlan_tx_tag_get(nskb)); if (!nskb) return -ENOMEM; diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 8e61a5c6ae7c..777cd8c71d53 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c @@ -176,9 +176,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) } if (vlan_tx_tag_present(skb)) { - if (unlikely(!__vlan_put_tag(skb, - skb->vlan_proto, - vlan_tx_tag_get(skb)))) { + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (unlikely(!skb) { err = -ENOMEM; goto err_free_rt; } -- GitLab From 5968250c868ceee680aa77395b24e6ddcae17d36 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:04:59 +0100 Subject: [PATCH 5749/9457] vlan: introduce *vlan_hwaccel_push_inside helpers Use them to push skb->vlan_tci into the payload and avoid code duplication. Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 22 ++++++---------------- include/linux/if_vlan.h | 34 ++++++++++++++++++++++++++++++++++ net/core/dev.c | 8 ++------ net/core/netpoll.c | 4 +--- net/ipv4/geneve.c | 11 +++-------- net/openvswitch/datapath.c | 4 +--- net/openvswitch/vport-gre.c | 12 ++++-------- 7 files changed, 51 insertions(+), 44 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index bb8fbab438e8..64d45fa3d997 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1599,14 +1599,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, if (unlikely(err)) return err; - if (vlan_tx_tag_present(skb)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); - if (WARN_ON(!skb)) - return -ENOMEM; - - skb->vlan_tci = 0; - } + skb = vlan_hwaccel_push_inside(skb); + if (WARN_ON(!skb)) + return -ENOMEM; vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); vxh->vx_flags = htonl(VXLAN_FLAGS); @@ -1643,14 +1638,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, if (unlikely(err)) return err; - if (vlan_tx_tag_present(skb)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); - if (WARN_ON(!skb)) - return -ENOMEM; - - skb->vlan_tci = 0; - } + skb = vlan_hwaccel_push_inside(skb); + if (WARN_ON(!skb)) + return -ENOMEM; vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); vxh->vx_flags = htonl(VXLAN_FLAGS); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 46e4a15b9b55..291e6706876e 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -341,6 +341,40 @@ static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb, return skb; } +/* + * __vlan_hwaccel_push_inside - pushes vlan tag to the payload + * @skb: skbuff to tag + * + * Pushes the VLAN tag from @skb->vlan_tci inside to the payload. + * + * Following the skb_unshare() example, in case of error, the calling function + * doesn't have to worry about freeing the original skb. + */ +static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb) +{ + skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (likely(skb)) + skb->vlan_tci = 0; + return skb; +} +/* + * vlan_hwaccel_push_inside - pushes vlan tag to the payload + * @skb: skbuff to tag + * + * Checks is tag is present in @skb->vlan_tci and if it is, it pushes the + * VLAN tag from @skb->vlan_tci inside to the payload. + * + * Following the skb_unshare() example, in case of error, the calling function + * doesn't have to worry about freeing the original skb. + */ +static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb) +{ + if (vlan_tx_tag_present(skb)) + skb = __vlan_hwaccel_push_inside(skb); + return skb; +} + /** * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting * @skb: skbuff to tag diff --git a/net/core/dev.c b/net/core/dev.c index 3611e60df407..ac4836241a96 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2644,12 +2644,8 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, netdev_features_t features) { if (vlan_tx_tag_present(skb) && - !vlan_hw_offload_capable(features, skb->vlan_proto)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); - if (skb) - skb->vlan_tci = 0; - } + !vlan_hw_offload_capable(features, skb->vlan_proto)) + skb = __vlan_hwaccel_push_inside(skb); return skb; } diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 65d372384a3f..e0ad5d16c9c5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -79,8 +79,7 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev, if (vlan_tx_tag_present(skb) && !vlan_hw_offload_capable(features, skb->vlan_proto)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); + skb = __vlan_hwaccel_push_inside(skb); if (unlikely(!skb)) { /* This is actually a packet drop, but we * don't want the code that calls this @@ -88,7 +87,6 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev, */ goto out; } - skb->vlan_tci = 0; } status = netdev_start_xmit(skb, dev, txq, false); diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index fd430a6a1c37..a457232f0131 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c @@ -131,14 +131,9 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, if (unlikely(err)) return err; - if (vlan_tx_tag_present(skb)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); - if (unlikely(!skb) - return -ENOMEM; - - skb->vlan_tci = 0; - } + skb = vlan_hwaccel_push_inside(skb); + if (unlikely(!skb)) + return -ENOMEM; gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len); geneve_build_header(gnvh, tun_flags, vni, opt_len, opt); diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index c63e60e4d947..f37ca3e5824c 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -425,12 +425,10 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, if (!nskb) return -ENOMEM; - nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto, - vlan_tx_tag_get(nskb)); + nskb = __vlan_hwaccel_push_inside(nskb); if (!nskb) return -ENOMEM; - nskb->vlan_tci = 0; skb = nskb; } diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 777cd8c71d53..6b69df545b1d 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c @@ -175,14 +175,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) goto err_free_rt; } - if (vlan_tx_tag_present(skb)) { - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - vlan_tx_tag_get(skb)); - if (unlikely(!skb) { - err = -ENOMEM; - goto err_free_rt; - } - skb->vlan_tci = 0; + skb = vlan_hwaccel_push_inside(skb); + if (unlikely(!skb)) { + err = -ENOMEM; + goto err_free_rt; } /* Push Tunnel header. */ -- GitLab From 15255a43e6c917813800702e100267046e240cc0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:05:00 +0100 Subject: [PATCH 5750/9457] vlan: introduce __vlan_insert_tag helper which does not free skb There's a need for helper which inserts vlan tag but does not free the skb in case of an error. Suggested-by: Pravin Shelar Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 45 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 291e6706876e..515a35e2a48a 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -282,28 +282,24 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features, } /** - * vlan_insert_tag - regular VLAN tag inserting + * __vlan_insert_tag - regular VLAN tag inserting * @skb: skbuff to tag * @vlan_proto: VLAN encapsulation protocol * @vlan_tci: VLAN TCI to insert * * Inserts the VLAN tag into @skb as part of the payload - * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. - * - * Following the skb_unshare() example, in case of error, the calling function - * doesn't have to worry about freeing the original skb. + * Returns error if skb_cow_head failes. * * Does not change skb->protocol so this function can be used during receive. */ -static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, - __be16 vlan_proto, u16 vlan_tci) +static inline int __vlan_insert_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { struct vlan_ethhdr *veth; - if (skb_cow_head(skb, VLAN_HLEN) < 0) { - dev_kfree_skb_any(skb); - return NULL; - } + if (skb_cow_head(skb, VLAN_HLEN) < 0) + return -ENOMEM; + veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN); /* Move the mac addresses to the beginning of the new header. */ @@ -316,6 +312,33 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, /* now, the TCI */ veth->h_vlan_TCI = htons(vlan_tci); + return 0; +} + +/** + * vlan_insert_tag - regular VLAN tag inserting + * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol + * @vlan_tci: VLAN TCI to insert + * + * Inserts the VLAN tag into @skb as part of the payload + * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. + * + * Following the skb_unshare() example, in case of error, the calling function + * doesn't have to worry about freeing the original skb. + * + * Does not change skb->protocol so this function can be used during receive. + */ +static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) +{ + int err; + + err = __vlan_insert_tag(skb, vlan_proto, vlan_tci); + if (err) { + dev_kfree_skb_any(skb); + return NULL; + } return skb; } -- GitLab From e21951212f03b8d805795d8f71206853b2ab344d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:05:01 +0100 Subject: [PATCH 5751/9457] net: move make_writable helper into common code note that skb_make_writable already exists in net/netfilter/core.c but does something slightly different. Suggested-by: Eric Dumazet Signed-off-by: Jiri Pirko Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- include/linux/skbuff.h | 1 + net/core/skbuff.c | 12 ++++++++++++ net/openvswitch/actions.c | 39 ++++++++++++++------------------------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 73c370e615de..e045516891a9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2678,6 +2678,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet); unsigned int skb_gso_transport_seglen(const struct sk_buff *skb); struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); struct sk_buff *skb_vlan_untag(struct sk_buff *skb); +int skb_ensure_writable(struct sk_buff *skb, int write_len); struct skb_checksum_ops { __wsum (*update)(const void *mem, int len, __wsum wsum); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 700189604f3d..d11bbe0da355 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4151,6 +4151,18 @@ struct sk_buff *skb_vlan_untag(struct sk_buff *skb) } EXPORT_SYMBOL(skb_vlan_untag); +int skb_ensure_writable(struct sk_buff *skb, int write_len) +{ + if (!pskb_may_pull(skb, write_len)) + return -ENOMEM; + + if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) + return 0; + + return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); +} +EXPORT_SYMBOL(skb_ensure_writable); + /** * alloc_skb_with_frags - allocate skb with page frags * diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 426b9131ede0..7ffa37716265 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -119,17 +119,6 @@ static bool is_flow_key_valid(const struct sw_flow_key *key) return !!key->eth.type; } -static int make_writable(struct sk_buff *skb, int write_len) -{ - if (!pskb_may_pull(skb, write_len)) - return -ENOMEM; - - if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) - return 0; - - return pskb_expand_head(skb, 0, 0, GFP_ATOMIC); -} - static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_action_push_mpls *mpls) { @@ -171,7 +160,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, struct ethhdr *hdr; int err; - err = make_writable(skb, skb->mac_len + MPLS_HLEN); + err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); if (unlikely(err)) return err; @@ -201,7 +190,7 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key, __be32 *stack; int err; - err = make_writable(skb, skb->mac_len + MPLS_HLEN); + err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); if (unlikely(err)) return err; @@ -223,7 +212,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) struct vlan_hdr *vhdr; int err; - err = make_writable(skb, VLAN_ETH_HLEN); + err = skb_ensure_writable(skb, VLAN_ETH_HLEN); if (unlikely(err)) return err; @@ -310,7 +299,7 @@ static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_key_ethernet *eth_key) { int err; - err = make_writable(skb, ETH_HLEN); + err = skb_ensure_writable(skb, ETH_HLEN); if (unlikely(err)) return err; @@ -412,8 +401,8 @@ static int set_ipv4(struct sk_buff *skb, struct sw_flow_key *key, struct iphdr *nh; int err; - err = make_writable(skb, skb_network_offset(skb) + - sizeof(struct iphdr)); + err = skb_ensure_writable(skb, skb_network_offset(skb) + + sizeof(struct iphdr)); if (unlikely(err)) return err; @@ -450,8 +439,8 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key, __be32 *saddr; __be32 *daddr; - err = make_writable(skb, skb_network_offset(skb) + - sizeof(struct ipv6hdr)); + err = skb_ensure_writable(skb, skb_network_offset(skb) + + sizeof(struct ipv6hdr)); if (unlikely(err)) return err; @@ -493,7 +482,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *key, return 0; } -/* Must follow make_writable() since that can move the skb data. */ +/* Must follow skb_ensure_writable() since that can move the skb data. */ static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) { @@ -523,8 +512,8 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *key, struct udphdr *uh; int err; - err = make_writable(skb, skb_transport_offset(skb) + - sizeof(struct udphdr)); + err = skb_ensure_writable(skb, skb_transport_offset(skb) + + sizeof(struct udphdr)); if (unlikely(err)) return err; @@ -548,8 +537,8 @@ static int set_tcp(struct sk_buff *skb, struct sw_flow_key *key, struct tcphdr *th; int err; - err = make_writable(skb, skb_transport_offset(skb) + - sizeof(struct tcphdr)); + err = skb_ensure_writable(skb, skb_transport_offset(skb) + + sizeof(struct tcphdr)); if (unlikely(err)) return err; @@ -574,7 +563,7 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *key, int err; unsigned int sctphoff = skb_transport_offset(skb); - err = make_writable(skb, sctphoff + sizeof(struct sctphdr)); + err = skb_ensure_writable(skb, sctphoff + sizeof(struct sctphdr)); if (unlikely(err)) return err; -- GitLab From 93515d53b133d66f01aec7b231fa3e40e3d2fd9a Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:05:02 +0100 Subject: [PATCH 5752/9457] net: move vlan pop/push functions into common code So it can be used from out of openvswitch code. Did couple of cosmetic changes on the way, namely variable naming and adding support for 8021AD proto. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 + net/core/skbuff.c | 95 +++++++++++++++++++++++++++++++++++++++ net/openvswitch/actions.c | 86 ++++------------------------------- 3 files changed, 106 insertions(+), 77 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e045516891a9..78c299f40bac 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2679,6 +2679,8 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb); struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); struct sk_buff *skb_vlan_untag(struct sk_buff *skb); int skb_ensure_writable(struct sk_buff *skb, int write_len); +int skb_vlan_pop(struct sk_buff *skb); +int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); struct skb_checksum_ops { __wsum (*update)(const void *mem, int len, __wsum wsum); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d11bbe0da355..c906c5f4bf69 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4163,6 +4163,101 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len) } EXPORT_SYMBOL(skb_ensure_writable); +/* remove VLAN header from packet and update csum accordingly. */ +static int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci) +{ + struct vlan_hdr *vhdr; + unsigned int offset = skb->data - skb_mac_header(skb); + int err; + + __skb_push(skb, offset); + err = skb_ensure_writable(skb, VLAN_ETH_HLEN); + if (unlikely(err)) + goto pull; + + skb_postpull_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); + + vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); + *vlan_tci = ntohs(vhdr->h_vlan_TCI); + + memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN); + __skb_pull(skb, VLAN_HLEN); + + vlan_set_encap_proto(skb, vhdr); + skb->mac_header += VLAN_HLEN; + + if (skb_network_offset(skb) < ETH_HLEN) + skb_set_network_header(skb, ETH_HLEN); + + skb_reset_mac_len(skb); +pull: + __skb_pull(skb, offset); + + return err; +} + +int skb_vlan_pop(struct sk_buff *skb) +{ + u16 vlan_tci; + __be16 vlan_proto; + int err; + + if (likely(vlan_tx_tag_present(skb))) { + skb->vlan_tci = 0; + } else { + if (unlikely((skb->protocol != htons(ETH_P_8021Q) && + skb->protocol != htons(ETH_P_8021AD)) || + skb->len < VLAN_ETH_HLEN)) + return 0; + + err = __skb_vlan_pop(skb, &vlan_tci); + if (err) + return err; + } + /* move next vlan tag to hw accel tag */ + if (likely((skb->protocol != htons(ETH_P_8021Q) && + skb->protocol != htons(ETH_P_8021AD)) || + skb->len < VLAN_ETH_HLEN)) + return 0; + + vlan_proto = skb->protocol; + err = __skb_vlan_pop(skb, &vlan_tci); + if (unlikely(err)) + return err; + + __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); + return 0; +} +EXPORT_SYMBOL(skb_vlan_pop); + +int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) +{ + if (vlan_tx_tag_present(skb)) { + unsigned int offset = skb->data - skb_mac_header(skb); + int err; + + /* __vlan_insert_tag expect skb->data pointing to mac header. + * So change skb->data before calling it and change back to + * original position later + */ + __skb_push(skb, offset); + err = __vlan_insert_tag(skb, skb->vlan_proto, + vlan_tx_tag_get(skb)); + if (err) + return err; + skb->protocol = skb->vlan_proto; + skb->mac_len += VLAN_HLEN; + __skb_pull(skb, offset); + + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_add(skb->csum, csum_partial(skb->data + + (2 * ETH_ALEN), VLAN_HLEN, 0)); + } + __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); + return 0; +} +EXPORT_SYMBOL(skb_vlan_push); + /** * alloc_skb_with_frags - allocate skb with page frags * diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 7ffa37716265..4e05ea1c2d11 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -206,93 +206,27 @@ static int set_mpls(struct sk_buff *skb, struct sw_flow_key *key, return 0; } -/* remove VLAN header from packet and update csum accordingly. */ -static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) -{ - struct vlan_hdr *vhdr; - int err; - - err = skb_ensure_writable(skb, VLAN_ETH_HLEN); - if (unlikely(err)) - return err; - - skb_postpull_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); - - vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); - *current_tci = vhdr->h_vlan_TCI; - - memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN); - __skb_pull(skb, VLAN_HLEN); - - vlan_set_encap_proto(skb, vhdr); - skb->mac_header += VLAN_HLEN; - - if (skb_network_offset(skb) < ETH_HLEN) - skb_set_network_header(skb, ETH_HLEN); - - /* Update mac_len for subsequent MPLS actions */ - skb_reset_mac_len(skb); - return 0; -} - static int pop_vlan(struct sk_buff *skb, struct sw_flow_key *key) { - __be16 tci; int err; - if (likely(vlan_tx_tag_present(skb))) { - skb->vlan_tci = 0; - } else { - if (unlikely(skb->protocol != htons(ETH_P_8021Q) || - skb->len < VLAN_ETH_HLEN)) - return 0; - - err = __pop_vlan_tci(skb, &tci); - if (err) - return err; - } - /* move next vlan tag to hw accel tag */ - if (likely(skb->protocol != htons(ETH_P_8021Q) || - skb->len < VLAN_ETH_HLEN)) { + err = skb_vlan_pop(skb); + if (vlan_tx_tag_present(skb)) + invalidate_flow_key(key); + else key->eth.tci = 0; - return 0; - } - - invalidate_flow_key(key); - err = __pop_vlan_tci(skb, &tci); - if (unlikely(err)) - return err; - - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(tci)); - return 0; + return err; } static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key, const struct ovs_action_push_vlan *vlan) { - if (unlikely(vlan_tx_tag_present(skb))) { - u16 current_tag; - - /* push down current VLAN tag */ - current_tag = vlan_tx_tag_get(skb); - - skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, - current_tag); - if (!skb) - return -ENOMEM; - /* Update mac_len for subsequent MPLS actions */ - skb->mac_len += VLAN_HLEN; - - if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->csum = csum_add(skb->csum, csum_partial(skb->data - + (2 * ETH_ALEN), VLAN_HLEN, 0)); - + if (vlan_tx_tag_present(skb)) invalidate_flow_key(key); - } else { + else key->eth.tci = vlan->vlan_tci; - } - __vlan_hwaccel_put_tag(skb, vlan->vlan_tpid, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); - return 0; + return skb_vlan_push(skb, vlan->vlan_tpid, + ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); } static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *key, @@ -858,8 +792,6 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, case OVS_ACTION_ATTR_PUSH_VLAN: err = push_vlan(skb, key, nla_data(a)); - if (unlikely(err)) /* skb already freed. */ - return err; break; case OVS_ACTION_ATTR_POP_VLAN: -- GitLab From c7e2b9689ef81362a8091592da6cb6a7723f377a Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 19 Nov 2014 14:05:03 +0100 Subject: [PATCH 5753/9457] sched: introduce vlan action This tc action allows to work with vlan tagged skbs. Two supported sub-actions are header pop and header push. Signed-off-by: Jiri Pirko Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/net/tc_act/tc_vlan.h | 27 ++++ include/uapi/linux/tc_act/tc_vlan.h | 35 +++++ net/sched/Kconfig | 11 ++ net/sched/Makefile | 1 + net/sched/act_vlan.c | 207 ++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) create mode 100644 include/net/tc_act/tc_vlan.h create mode 100644 include/uapi/linux/tc_act/tc_vlan.h create mode 100644 net/sched/act_vlan.c diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h new file mode 100644 index 000000000000..c809c1d2cea5 --- /dev/null +++ b/include/net/tc_act/tc_vlan.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014 Jiri Pirko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __NET_TC_VLAN_H +#define __NET_TC_VLAN_H + +#include + +#define VLAN_F_POP 0x1 +#define VLAN_F_PUSH 0x2 + +struct tcf_vlan { + struct tcf_common common; + int tcfv_action; + __be16 tcfv_push_vid; + __be16 tcfv_push_proto; +}; +#define to_vlan(a) \ + container_of(a->priv, struct tcf_vlan, common) + +#endif /* __NET_TC_VLAN_H */ diff --git a/include/uapi/linux/tc_act/tc_vlan.h b/include/uapi/linux/tc_act/tc_vlan.h new file mode 100644 index 000000000000..f7b8d448b960 --- /dev/null +++ b/include/uapi/linux/tc_act/tc_vlan.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 Jiri Pirko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_TC_VLAN_H +#define __LINUX_TC_VLAN_H + +#include + +#define TCA_ACT_VLAN 12 + +#define TCA_VLAN_ACT_POP 1 +#define TCA_VLAN_ACT_PUSH 2 + +struct tc_vlan { + tc_gen; + int v_action; +}; + +enum { + TCA_VLAN_UNSPEC, + TCA_VLAN_TM, + TCA_VLAN_PARMS, + TCA_VLAN_PUSH_VLAN_ID, + TCA_VLAN_PUSH_VLAN_PROTOCOL, + __TCA_VLAN_MAX, +}; +#define TCA_VLAN_MAX (__TCA_VLAN_MAX - 1) + +#endif diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a1a8e29e5fc9..88618f8b794c 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -686,6 +686,17 @@ config NET_ACT_CSUM To compile this code as a module, choose M here: the module will be called act_csum. +config NET_ACT_VLAN + tristate "Vlan manipulation" + depends on NET_CLS_ACT + ---help--- + Say Y here to push or pop vlan headers. + + If unsure, say N. + + To compile this code as a module, choose M here: the + module will be called act_vlan. + config NET_CLS_IND bool "Incoming device classification" depends on NET_CLS_U32 || NET_CLS_FW diff --git a/net/sched/Makefile b/net/sched/Makefile index 0a869a11f3e6..679f24ae7f93 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o +obj-$(CONFIG_NET_ACT_VLAN) += act_vlan.o obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c new file mode 100644 index 000000000000..d735ecf0b1a7 --- /dev/null +++ b/net/sched/act_vlan.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014 Jiri Pirko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define VLAN_TAB_MASK 15 + +static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a, + struct tcf_result *res) +{ + struct tcf_vlan *v = a->priv; + int action; + int err; + + spin_lock(&v->tcf_lock); + v->tcf_tm.lastuse = jiffies; + bstats_update(&v->tcf_bstats, skb); + action = v->tcf_action; + + switch (v->tcfv_action) { + case TCA_VLAN_ACT_POP: + err = skb_vlan_pop(skb); + if (err) + goto drop; + break; + case TCA_VLAN_ACT_PUSH: + err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid); + if (err) + goto drop; + break; + default: + BUG(); + } + + goto unlock; + +drop: + action = TC_ACT_SHOT; + v->tcf_qstats.drops++; +unlock: + spin_unlock(&v->tcf_lock); + return action; +} + +static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = { + [TCA_VLAN_PARMS] = { .len = sizeof(struct tc_vlan) }, + [TCA_VLAN_PUSH_VLAN_ID] = { .type = NLA_U16 }, + [TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type = NLA_U16 }, +}; + +static int tcf_vlan_init(struct net *net, struct nlattr *nla, + struct nlattr *est, struct tc_action *a, + int ovr, int bind) +{ + struct nlattr *tb[TCA_VLAN_MAX + 1]; + struct tc_vlan *parm; + struct tcf_vlan *v; + int action; + __be16 push_vid = 0; + __be16 push_proto = 0; + int ret = 0; + int err; + + if (!nla) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_VLAN_MAX, nla, vlan_policy); + if (err < 0) + return err; + + if (!tb[TCA_VLAN_PARMS]) + return -EINVAL; + parm = nla_data(tb[TCA_VLAN_PARMS]); + switch (parm->v_action) { + case TCA_VLAN_ACT_POP: + break; + case TCA_VLAN_ACT_PUSH: + if (!tb[TCA_VLAN_PUSH_VLAN_ID]) + return -EINVAL; + push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); + if (push_vid >= VLAN_VID_MASK) + return -ERANGE; + + if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) { + push_proto = nla_get_be16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]); + switch (push_proto) { + case htons(ETH_P_8021Q): + case htons(ETH_P_8021AD): + break; + default: + return -EPROTONOSUPPORT; + } + } else { + push_proto = htons(ETH_P_8021Q); + } + break; + default: + return -EINVAL; + } + action = parm->v_action; + + if (!tcf_hash_check(parm->index, a, bind)) { + ret = tcf_hash_create(parm->index, est, a, sizeof(*v), bind); + if (ret) + return ret; + + ret = ACT_P_CREATED; + } else { + if (bind) + return 0; + tcf_hash_release(a, bind); + if (!ovr) + return -EEXIST; + } + + v = to_vlan(a); + + spin_lock_bh(&v->tcf_lock); + + v->tcfv_action = action; + v->tcfv_push_vid = push_vid; + v->tcfv_push_proto = push_proto; + + v->tcf_action = parm->action; + + spin_unlock_bh(&v->tcf_lock); + + if (ret == ACT_P_CREATED) + tcf_hash_insert(a); + return ret; +} + +static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, + int bind, int ref) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tcf_vlan *v = a->priv; + struct tc_vlan opt = { + .index = v->tcf_index, + .refcnt = v->tcf_refcnt - ref, + .bindcnt = v->tcf_bindcnt - bind, + .action = v->tcf_action, + .v_action = v->tcfv_action, + }; + struct tcf_t t; + + if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt)) + goto nla_put_failure; + + if (v->tcfv_action == TCA_VLAN_ACT_PUSH && + (nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) || + nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL, v->tcfv_push_proto))) + goto nla_put_failure; + + t.install = jiffies_to_clock_t(jiffies - v->tcf_tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - v->tcf_tm.lastuse); + t.expires = jiffies_to_clock_t(v->tcf_tm.expires); + if (nla_put(skb, TCA_VLAN_TM, sizeof(t), &t)) + goto nla_put_failure; + return skb->len; + +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static struct tc_action_ops act_vlan_ops = { + .kind = "vlan", + .type = TCA_ACT_VLAN, + .owner = THIS_MODULE, + .act = tcf_vlan, + .dump = tcf_vlan_dump, + .init = tcf_vlan_init, +}; + +static int __init vlan_init_module(void) +{ + return tcf_register_action(&act_vlan_ops, VLAN_TAB_MASK); +} + +static void __exit vlan_cleanup_module(void) +{ + tcf_unregister_action(&act_vlan_ops); +} + +module_init(vlan_init_module); +module_exit(vlan_cleanup_module); + +MODULE_AUTHOR("Jiri Pirko "); +MODULE_DESCRIPTION("vlan manipulation actions"); +MODULE_LICENSE("GPL v2"); -- GitLab From 026da220c512f6ab706cc9f738439f900b564967 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Fri, 21 Nov 2014 16:08:59 +0800 Subject: [PATCH 5754/9457] ASoC: Intel: Add Cherrytrail & Braswell machine driver cht_bsw_rt5672 Add machine driver for two Intel Cherryview-based platforms, Cherrytrail and Braswell, with RT5672 codec. Signed-off-by: Mengdong Lin Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 12 ++ sound/soc/intel/Makefile | 2 + sound/soc/intel/cht_bsw_rt5672.c | 285 +++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 sound/soc/intel/cht_bsw_rt5672.c diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index a26e8e8bb9aa..e989ecf046c9 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -98,3 +98,15 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH used as alsa device in audio substem in Intel(R) MID devices Say Y if you have such a device If unsure select "N". + +config SND_SOC_INTEL_CHT_BSW_RT5672_MACH + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" + depends on X86_INTEL_LPSS + select SND_SOC_RT5670 + select SND_SST_MFLD_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell + platforms with RT5672 audio codec. + Say Y if you have such a device + If unsure select "N". diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index fbde4b07d455..e928ec385300 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -27,12 +27,14 @@ snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o snd-soc-sst-broadwell-objs := broadwell.o snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o +snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o +obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o # DSP driver obj-$(CONFIG_SND_SST_IPC) += sst/ diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c new file mode 100644 index 000000000000..9b8b561171b7 --- /dev/null +++ b/sound/soc/intel/cht_bsw_rt5672.c @@ -0,0 +1,285 @@ +/* + * cht_bsw_rt5672.c - ASoc Machine driver for Intel Cherryview-based platforms + * Cherrytrail and Braswell, with RT5672 codec. + * + * Copyright (C) 2014 Intel Corp + * Author: Subhransu S. Prusty + * Mengdong Lin + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "../codecs/rt5670.h" +#include "sst-atom-controls.h" + +/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ +#define CHT_PLAT_CLK_3_HZ 19200000 +#define CHT_CODEC_DAI "rt5670-aif1" + +static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) +{ + int i; + + for (i = 0; i < card->num_rtd; i++) { + struct snd_soc_pcm_runtime *rtd; + + rtd = card->rtd + i; + if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, + strlen(CHT_CODEC_DAI))) + return rtd->codec_dai; + } + return NULL; +} + +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + + codec_dai = cht_get_codec_dai(card); + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); + return -EIO; + } + + if (!SND_SOC_DAPM_EVENT_OFF(event)) + return 0; + + /* Set codec sysclk source to its internal clock because codec PLL will + * be off when idle and MCLK will also be off by ACPI when codec is + * runtime suspended. Codec needs clock for jack detection and button + * press. + */ + snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK, + 0, SND_SOC_CLOCK_IN); + + return 0; +} + +static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, + platform_clock_control, SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route cht_audio_map[] = { + {"IN1P", NULL, "Headset Mic"}, + {"IN1N", NULL, "Headset Mic"}, + {"DMIC L1", NULL, "Int Mic"}, + {"DMIC R1", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Ext Spk", NULL, "SPOLP"}, + {"Ext Spk", NULL, "SPOLN"}, + {"Ext Spk", NULL, "SPORP"}, + {"Ext Spk", NULL, "SPORN"}, + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, + {"Headphone", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Int Mic", NULL, "Platform Clock"}, + {"Ext Spk", NULL, "Platform Clock"}, +}; + +static const struct snd_kcontrol_new cht_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static int cht_aif1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK, + CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + /* set codec sysclk source to PLL */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + return 0; +} + +static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret; + struct snd_soc_dai *codec_dai = runtime->codec_dai; + + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); + if (ret < 0) { + dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret); + return ret; + } + + return 0; +} + +static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - + SNDRV_PCM_HW_PARAM_FIRST_MASK], + SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + +static unsigned int rates_48000[] = { + 48000, +}; + +static struct snd_pcm_hw_constraint_list constraints_48000 = { + .count = ARRAY_SIZE(rates_48000), + .list = rates_48000, +}; + +static int cht_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_48000); +} + +static struct snd_soc_ops cht_aif1_ops = { + .startup = cht_aif1_startup, +}; + +static struct snd_soc_ops cht_be_ssp2_ops = { + .hw_params = cht_aif1_hw_params, +}; + +static struct snd_soc_dai_link cht_dailink[] = { + /* Front End DAI links */ + [MERR_DPCM_AUDIO] = { + .name = "Audio Port", + .stream_name = "Audio", + .cpu_dai_name = "media-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .ignore_suspend = 1, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &cht_aif1_ops, + }, + [MERR_DPCM_COMPR] = { + .name = "Compressed Port", + .stream_name = "Compress", + .cpu_dai_name = "compress-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + }, + + /* Back End DAI links */ + { + /* SSP2 - Codec */ + .name = "SSP2-Codec", + .be_id = 1, + .cpu_dai_name = "ssp2-port", + .platform_name = "sst-mfld-platform", + .no_pcm = 1, + .codec_dai_name = "rt5670-aif1", + .codec_name = "i2c-10EC5670:00", + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .init = cht_codec_init, + .be_hw_params_fixup = cht_codec_fixup, + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &cht_be_ssp2_ops, + }, +}; + +/* SoC card */ +static struct snd_soc_card snd_soc_card_cht = { + .name = "cherrytrailcraudio", + .dai_link = cht_dailink, + .num_links = ARRAY_SIZE(cht_dailink), + .dapm_widgets = cht_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), + .dapm_routes = cht_audio_map, + .num_dapm_routes = ARRAY_SIZE(cht_audio_map), + .controls = cht_mc_controls, + .num_controls = ARRAY_SIZE(cht_mc_controls), +}; + +static int snd_cht_mc_probe(struct platform_device *pdev) +{ + int ret_val = 0; + + /* register the soc card */ + snd_soc_card_cht.dev = &pdev->dev; + ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); + if (ret_val) { + dev_err(&pdev->dev, + "snd_soc_register_card failed %d\n", ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &snd_soc_card_cht); + return ret_val; +} + +static struct platform_driver snd_cht_mc_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "cht-bsw-rt5672", + .pm = &snd_soc_pm_ops, + }, + .probe = snd_cht_mc_probe, +}; + +module_platform_driver(snd_cht_mc_driver); + +MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); +MODULE_AUTHOR("Subhransu S. Prusty, Mengdong Lin"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cht-bsw-rt5672"); -- GitLab From bd01fdc3aa63b7ba0b035f9196d80551ad03f5d4 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Fri, 21 Nov 2014 16:09:17 +0800 Subject: [PATCH 5755/9457] ASoC: Intel: add support for Cherrytrail and Braswell in SST driver This patch add ACPI device ID and platform data for two Cherryview-based platforms, Cherrytrail and Braswell. Also reuse mfld driver ops in sst driver. Signed-off-by: Mengdong Lin Acked-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 1 + sound/soc/intel/sst/sst.h | 1 + sound/soc/intel/sst/sst_acpi.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 9e68a7cefd1b..8a8d56a146e7 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -183,6 +183,7 @@ int sst_driver_ops(struct intel_sst_drv *sst) switch (sst->dev_id) { case SST_MRFLD_PCI_ID: case SST_BYT_ACPI_ID: + case SST_CHV_ACPI_ID: sst->tstamp = SST_TIME_STAMP_MRFLD; sst->ops = &mrfld_ops; return 0; diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index 683dc717e4e8..7f4bbfcbc6f5 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h @@ -30,6 +30,7 @@ #define SST_DRV_NAME "intel_sst_driver" #define SST_MRFLD_PCI_ID 0x119A #define SST_BYT_ACPI_ID 0x80860F28 +#define SST_CHV_ACPI_ID 0x808622A8 #define SST_SUSPEND_DELAY 2000 #define FW_CONTEXT_MEM (64*1024) diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index f94f007a0e49..3f29721625cc 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c @@ -129,6 +129,17 @@ static struct sst_platform_info byt_rvp_platform_data = { .platform = "sst-mfld-platform", }; +/* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail, + * so pdata is same as Baytrail. + */ +struct sst_platform_info chv_platform_data = { + .probe_data = &byt_fwparse_info, + .ipc_info = &byt_ipc_info, + .lib_info = &byt_lib_dnld_info, + .res_info = &byt_rvp_res_info, + .platform = "sst-mfld-platform", +}; + static int sst_platform_get_resources(struct intel_sst_drv *ctx) { struct resource *rsrc; @@ -337,8 +348,16 @@ static struct sst_machines sst_acpi_bytcr[] = { {}, }; +/* Cherryview-based platforms: CherryTrail and Braswell */ +static struct sst_machines sst_acpi_chv[] = { + {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "fw_sst_22a8.bin", + &chv_platform_data }, + {}, +}; + static const struct acpi_device_id sst_acpi_ids[] = { { "80860F28", (unsigned long)&sst_acpi_bytcr}, + { "808622A8", (unsigned long) &sst_acpi_chv}, { }, }; -- GitLab From 075207d24a394bcdb3a864446f391d4014a04cd4 Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Mon, 17 Nov 2014 16:02:57 +0800 Subject: [PATCH 5756/9457] ASoC: soc-pcm: skip dpcm path checking with incapable/unready FE Skip dpcm path checking for playback or capture, if corresponding FE doesn't support playback or capture, or currently is not ready. It can reduce the unnecessary cost to search connected widgets. [Tweaked comments for clarity -- broonie] Signed-off-by: Qiao Zhou Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 002311afdeaa..2f4f074d64a4 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2248,7 +2248,13 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card) fe->dai_link->name); /* skip if FE doesn't have playback capability */ - if (!fe->cpu_dai->driver->playback.channels_min) + if (!fe->cpu_dai->driver->playback.channels_min + || !fe->codec_dai->driver->playback.channels_min) + goto capture; + + /* skip if FE isn't currently playing */ + if (!fe->cpu_dai->playback_active + || !fe->codec_dai->playback_active) goto capture; paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); @@ -2278,7 +2284,13 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card) dpcm_path_put(&list); capture: /* skip if FE doesn't have capture capability */ - if (!fe->cpu_dai->driver->capture.channels_min) + if (!fe->cpu_dai->driver->capture.channels_min + || !fe->codec_dai->driver->capture.channels_min) + continue; + + /* skip if FE isn't currently capturing */ + if (!fe->cpu_dai->capture_active + || !fe->codec_dai->capture_active) continue; paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); -- GitLab From f8b8be8a310a55856fd2c369dade08088d85df3b Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 21 Nov 2014 05:25:16 -0500 Subject: [PATCH 5757/9457] ftrace, kprobes: Support IPMODIFY flag to find IP modify conflict Introduce FTRACE_OPS_FL_IPMODIFY to avoid conflict among ftrace users who may modify regs->ip to change the execution path. If two or more users modify the regs->ip on the same function entry, one of them will be broken. So they must add IPMODIFY flag and make sure that ftrace_set_filter_ip() succeeds. Note that ftrace doesn't allow ftrace_ops which has IPMODIFY flag to have notrace hash, and the ftrace_ops must have a filter hash (so that the ftrace_ops can hook only specific entries), because it strongly depends on the address and must be allowed for only few selected functions. Link: http://lkml.kernel.org/r/20141121102516.11844.27829.stgit@localhost.localdomain Cc: Jiri Kosina Cc: Seth Jennings Cc: Petr Mladek Cc: Vojtech Pavlik Cc: Miroslav Benes Cc: Ingo Molnar Cc: Ananth N Mavinakayanahalli Cc: Josh Poimboeuf Cc: Namhyung Kim Signed-off-by: Masami Hiramatsu [ fixed up some of the comments ] Signed-off-by: Steven Rostedt --- Documentation/trace/ftrace.txt | 5 ++ include/linux/ftrace.h | 16 +++- kernel/trace/ftrace.c | 142 ++++++++++++++++++++++++++++++++- 3 files changed, 159 insertions(+), 4 deletions(-) diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt index 4da42616939f..f10f5f5d260d 100644 --- a/Documentation/trace/ftrace.txt +++ b/Documentation/trace/ftrace.txt @@ -234,6 +234,11 @@ of ftrace. Here is a list of some of the key files: will be displayed on the same line as the function that is returning registers. + If the callback registered to be traced by a function with + the "ip modify" attribute (thus the regs->ip can be changed), + an 'I' will be displayed on the same line as the function that + can be overridden. + function_profile_enabled: When set it will enable all functions with either the function diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 7b2616fa2472..ed501953f0b2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -61,6 +61,11 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops); /* * FTRACE_OPS_FL_* bits denote the state of ftrace_ops struct and are * set in the flags member. + * CONTROL, SAVE_REGS, SAVE_REGS_IF_SUPPORTED, RECURSION_SAFE, STUB and + * IPMODIFY are a kind of attribute flags which can be set only before + * registering the ftrace_ops, and can not be modified while registered. + * Changing those attribute flags after regsitering ftrace_ops will + * cause unexpected results. * * ENABLED - set/unset when ftrace_ops is registered/unregistered * DYNAMIC - set when ftrace_ops is registered to denote dynamically @@ -101,6 +106,10 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops); * The ftrace_ops trampoline can be set by the ftrace users, and * in such cases the arch must not modify it. Only the arch ftrace * core code should set this flag. + * IPMODIFY - The ops can modify the IP register. This can only be set with + * SAVE_REGS. If another ops with this flag set is already registered + * for any of the functions that this ops will be registered for, then + * this ops will fail to register or set_filter_ip. */ enum { FTRACE_OPS_FL_ENABLED = 1 << 0, @@ -116,6 +125,7 @@ enum { FTRACE_OPS_FL_REMOVING = 1 << 10, FTRACE_OPS_FL_MODIFYING = 1 << 11, FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12, + FTRACE_OPS_FL_IPMODIFY = 1 << 13, }; #ifdef CONFIG_DYNAMIC_FTRACE @@ -310,6 +320,7 @@ bool is_ftrace_trampoline(unsigned long addr); * ENABLED - the function is being traced * REGS - the record wants the function to save regs * REGS_EN - the function is set up to save regs. + * IPMODIFY - the record allows for the IP address to be changed. * * When a new ftrace_ops is registered and wants a function to save * pt_regs, the rec->flag REGS is set. When the function has been @@ -323,10 +334,11 @@ enum { FTRACE_FL_REGS_EN = (1UL << 29), FTRACE_FL_TRAMP = (1UL << 28), FTRACE_FL_TRAMP_EN = (1UL << 27), + FTRACE_FL_IPMODIFY = (1UL << 26), }; -#define FTRACE_REF_MAX_SHIFT 27 -#define FTRACE_FL_BITS 5 +#define FTRACE_REF_MAX_SHIFT 26 +#define FTRACE_FL_BITS 6 #define FTRACE_FL_MASKED_BITS ((1UL << FTRACE_FL_BITS) - 1) #define FTRACE_FL_MASK (FTRACE_FL_MASKED_BITS << FTRACE_REF_MAX_SHIFT) #define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 588af40d33db..929a733d302e 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1358,6 +1358,9 @@ ftrace_hash_rec_disable_modify(struct ftrace_ops *ops, int filter_hash); static void ftrace_hash_rec_enable_modify(struct ftrace_ops *ops, int filter_hash); +static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, + struct ftrace_hash *new_hash); + static int ftrace_hash_move(struct ftrace_ops *ops, int enable, struct ftrace_hash **dst, struct ftrace_hash *src) @@ -1368,8 +1371,13 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, struct ftrace_hash *new_hash; int size = src->count; int bits = 0; + int ret; int i; + /* Reject setting notrace hash on IPMODIFY ftrace_ops */ + if (ops->flags & FTRACE_OPS_FL_IPMODIFY && !enable) + return -EINVAL; + /* * If the new source is empty, just free dst and assign it * the empty_hash. @@ -1403,6 +1411,16 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, } update: + /* Make sure this can be applied if it is IPMODIFY ftrace_ops */ + if (enable) { + /* IPMODIFY should be updated only when filter_hash updating */ + ret = ftrace_hash_ipmodify_update(ops, new_hash); + if (ret < 0) { + free_ftrace_hash(new_hash); + return ret; + } + } + /* * Remove the current set, update the hash and add * them back. @@ -1767,6 +1785,114 @@ static void ftrace_hash_rec_enable_modify(struct ftrace_ops *ops, ftrace_hash_rec_update_modify(ops, filter_hash, 1); } +/* + * Try to update IPMODIFY flag on each ftrace_rec. Return 0 if it is OK + * or no-needed to update, -EBUSY if it detects a conflict of the flag + * on a ftrace_rec, and -EINVAL if the new_hash tries to trace all recs. + * Note that old_hash and new_hash has below meanings + * - If the hash is NULL, it hits all recs (if IPMODIFY is set, this is rejected) + * - If the hash is EMPTY_HASH, it hits nothing + * - Anything else hits the recs which match the hash entries. + */ +static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, + struct ftrace_hash *old_hash, + struct ftrace_hash *new_hash) +{ + struct ftrace_page *pg; + struct dyn_ftrace *rec, *end = NULL; + int in_old, in_new; + + /* Only update if the ops has been registered */ + if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) + return 0; + + if (!(ops->flags & FTRACE_OPS_FL_IPMODIFY)) + return 0; + + /* + * Since the IPMODIFY is a very address sensitive action, we do not + * allow ftrace_ops to set all functions to new hash. + */ + if (!new_hash || !old_hash) + return -EINVAL; + + /* Update rec->flags */ + do_for_each_ftrace_rec(pg, rec) { + /* We need to update only differences of filter_hash */ + in_old = !!ftrace_lookup_ip(old_hash, rec->ip); + in_new = !!ftrace_lookup_ip(new_hash, rec->ip); + if (in_old == in_new) + continue; + + if (in_new) { + /* New entries must ensure no others are using it */ + if (rec->flags & FTRACE_FL_IPMODIFY) + goto rollback; + rec->flags |= FTRACE_FL_IPMODIFY; + } else /* Removed entry */ + rec->flags &= ~FTRACE_FL_IPMODIFY; + } while_for_each_ftrace_rec(); + + return 0; + +rollback: + end = rec; + + /* Roll back what we did above */ + do_for_each_ftrace_rec(pg, rec) { + if (rec == end) + goto err_out; + + in_old = !!ftrace_lookup_ip(old_hash, rec->ip); + in_new = !!ftrace_lookup_ip(new_hash, rec->ip); + if (in_old == in_new) + continue; + + if (in_new) + rec->flags &= ~FTRACE_FL_IPMODIFY; + else + rec->flags |= FTRACE_FL_IPMODIFY; + } while_for_each_ftrace_rec(); + +err_out: + return -EBUSY; +} + +static int ftrace_hash_ipmodify_enable(struct ftrace_ops *ops) +{ + struct ftrace_hash *hash = ops->func_hash->filter_hash; + + if (ftrace_hash_empty(hash)) + hash = NULL; + + return __ftrace_hash_update_ipmodify(ops, EMPTY_HASH, hash); +} + +/* Disabling always succeeds */ +static void ftrace_hash_ipmodify_disable(struct ftrace_ops *ops) +{ + struct ftrace_hash *hash = ops->func_hash->filter_hash; + + if (ftrace_hash_empty(hash)) + hash = NULL; + + __ftrace_hash_update_ipmodify(ops, hash, EMPTY_HASH); +} + +static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, + struct ftrace_hash *new_hash) +{ + struct ftrace_hash *old_hash = ops->func_hash->filter_hash; + + if (ftrace_hash_empty(old_hash)) + old_hash = NULL; + + if (ftrace_hash_empty(new_hash)) + new_hash = NULL; + + return __ftrace_hash_update_ipmodify(ops, old_hash, new_hash); +} + static void print_ip_ins(const char *fmt, unsigned char *p) { int i; @@ -2436,6 +2562,15 @@ static int ftrace_startup(struct ftrace_ops *ops, int command) */ ops->flags |= FTRACE_OPS_FL_ENABLED | FTRACE_OPS_FL_ADDING; + ret = ftrace_hash_ipmodify_enable(ops); + if (ret < 0) { + /* Rollback registration process */ + __unregister_ftrace_function(ops); + ftrace_start_up--; + ops->flags &= ~FTRACE_OPS_FL_ENABLED; + return ret; + } + ftrace_hash_rec_enable(ops, 1); ftrace_startup_enable(command); @@ -2464,6 +2599,8 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) */ WARN_ON_ONCE(ftrace_start_up < 0); + /* Disabling ipmodify never fails */ + ftrace_hash_ipmodify_disable(ops); ftrace_hash_rec_disable(ops, 1); ops->flags &= ~FTRACE_OPS_FL_ENABLED; @@ -3058,9 +3195,10 @@ static int t_show(struct seq_file *m, void *v) if (iter->flags & FTRACE_ITER_ENABLED) { struct ftrace_ops *ops = NULL; - seq_printf(m, " (%ld)%s", + seq_printf(m, " (%ld)%s%s", ftrace_rec_count(rec), - rec->flags & FTRACE_FL_REGS ? " R" : " "); + rec->flags & FTRACE_FL_REGS ? " R" : " ", + rec->flags & FTRACE_FL_IPMODIFY ? " I" : " "); if (rec->flags & FTRACE_FL_TRAMP_EN) { ops = ftrace_find_tramp_ops_any(rec); if (ops) -- GitLab From 9c7077622dd917457ced680a23b7f175769471d9 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Wed, 19 Nov 2014 13:10:16 -0500 Subject: [PATCH 5758/9457] packet: make packet_snd fail on len smaller than l2 header When sending packets out with PF_PACKET, SOCK_RAW, ensure that the packet is at least as long as the device's expected link layer header. This check already exists in tpacket_snd, but not in packet_snd. Also rate limit the warning in tpacket_snd. Signed-off-by: Willem de Bruijn Acked-by: Eric Dumazet Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- net/packet/af_packet.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4cd13d8de44b..58af58026dd2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2095,6 +2095,18 @@ static void tpacket_destruct_skb(struct sk_buff *skb) sock_wfree(skb); } +static bool ll_header_truncated(const struct net_device *dev, int len) +{ + /* net device doesn't like empty head */ + if (unlikely(len <= dev->hard_header_len)) { + net_warn_ratelimited("%s: packet size is too short (%d < %d)\n", + current->comm, len, dev->hard_header_len); + return true; + } + + return false; +} + static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, void *frame, struct net_device *dev, int size_max, __be16 proto, unsigned char *addr, int hlen) @@ -2170,12 +2182,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, if (unlikely(err < 0)) return -EINVAL; } else if (dev->hard_header_len) { - /* net device doesn't like empty head */ - if (unlikely(tp_len <= dev->hard_header_len)) { - pr_err("packet size is too short (%d < %d)\n", - tp_len, dev->hard_header_len); + if (ll_header_truncated(dev, tp_len)) return -EINVAL; - } skb_push(skb, dev->hard_header_len); err = skb_store_bits(skb, 0, data, @@ -2500,9 +2508,14 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) skb_set_network_header(skb, reserve); err = -EINVAL; - if (sock->type == SOCK_DGRAM && - (offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len)) < 0) - goto out_free; + if (sock->type == SOCK_DGRAM) { + offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len); + if (unlikely(offset) < 0) + goto out_free; + } else { + if (ll_header_truncated(dev, len)) + goto out_free; + } /* Returns -EFAULT on error */ err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); -- GitLab From 1d70be34df59f34b4562b8c047fc3a5069ce17b4 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 21 Nov 2014 05:25:23 -0500 Subject: [PATCH 5759/9457] kprobes: Add IPMODIFY flag to kprobe_ftrace_ops Add FTRACE_OPS_FL_IPMODIFY flag to kprobe_ftrace_ops since kprobes can changes regs->ip. Link: http://lkml.kernel.org/r/20141121102523.11844.21298.stgit@localhost.localdomain Signed-off-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- kernel/kprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3995f546d0f3..831978cebf1d 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -915,7 +915,7 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) #ifdef CONFIG_KPROBES_ON_FTRACE static struct ftrace_ops kprobe_ftrace_ops __read_mostly = { .func = kprobe_ftrace_handler, - .flags = FTRACE_OPS_FL_SAVE_REGS, + .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY, }; static int kprobe_ftrace_enabled; -- GitLab From 60b4ea1781fd862e9222d082af79a5770440d390 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 19 Nov 2014 10:29:55 -0800 Subject: [PATCH 5760/9457] net: systemport: log RX buffer allocation and RX/TX DMA failures To help troubleshoot heavy memory pressure conditions, add a bunch of statistics counter to log RX buffer allocation and RX/TX DMA mapping failures. These are reported like any other counters through the ethtool stats interface. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 10 +++++++++- drivers/net/ethernet/broadcom/bcmsysport.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 3cb241155dac..c1d255972dae 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -274,6 +274,9 @@ static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = { /* RBUF misc statistics */ STAT_RBUF("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, RBUF_OVFL_DISC_CNTR), STAT_RBUF("rbuf_err_cnt", mib.rbuf_err_cnt, RBUF_ERR_PKT_CNTR), + STAT_MIB_RX("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), + STAT_MIB_RX("rx_dma_failed", mib.rx_dma_failed), + STAT_MIB_TX("tx_dma_failed", mib.tx_dma_failed), }; #define BCM_SYSPORT_STATS_LEN ARRAY_SIZE(bcm_sysport_gstrings_stats) @@ -477,6 +480,7 @@ static int bcm_sysport_rx_refill(struct bcm_sysport_priv *priv, RX_BUF_LENGTH, DMA_FROM_DEVICE); ret = dma_mapping_error(kdev, mapping); if (ret) { + priv->mib.rx_dma_failed++; bcm_sysport_free_cb(cb); netif_err(priv, rx_err, ndev, "DMA mapping failure\n"); return ret; @@ -526,6 +530,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv, unsigned int p_index; u16 len, status; struct bcm_rsb *rsb; + int ret; /* Determine how much we should process since last call */ p_index = rdma_readl(priv, RDMA_PROD_INDEX); @@ -620,7 +625,9 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv, napi_gro_receive(&priv->napi, skb); refill: - bcm_sysport_rx_refill(priv, cb); + ret = bcm_sysport_rx_refill(priv, cb); + if (ret) + priv->mib.alloc_rx_buff_failed++; } return processed; @@ -973,6 +980,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE); if (dma_mapping_error(kdev, mapping)) { + priv->mib.tx_dma_failed++; netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", skb->data, skb_len); ret = NETDEV_TX_OK; diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index b08dab828101..fc19417d82a5 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h @@ -557,6 +557,9 @@ struct bcm_sysport_mib { u32 rxchk_other_pkt_disc; u32 rbuf_ovflow_cnt; u32 rbuf_err_cnt; + u32 alloc_rx_buff_failed; + u32 rx_dma_failed; + u32 tx_dma_failed; }; /* HW maintains a large list of counters */ -- GitLab From 44c8bc3ce39f4cbeb7bf13162666fb6d0aad864d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 19 Nov 2014 10:29:56 -0800 Subject: [PATCH 5761/9457] net: bcmgenet: log RX buffer allocation and RX/TX dma failures To help troubleshoot heavy memory pressure conditions, add a bunch of statistics counter to log RX buffer allocation and RX/TX DMA mapping failures. These are reported like any other counters through the ethtool stats interface. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 10 +++++++++- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index da1a2500c91c..fcbf1255ae5a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -613,6 +613,9 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = { UMAC_RBUF_OVFL_CNT), STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt, UMAC_RBUF_ERR_CNT), STAT_GENET_MISC("mdf_err_cnt", mib.mdf_err_cnt, UMAC_MDF_ERR_CNT), + STAT_GENET_MIB_RX("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), + STAT_GENET_MIB_RX("rx_dma_failed", mib.rx_dma_failed), + STAT_GENET_MIB_TX("tx_dma_failed", mib.tx_dma_failed), }; #define BCMGENET_STATS_LEN ARRAY_SIZE(bcmgenet_gstrings_stats) @@ -989,6 +992,7 @@ static int bcmgenet_xmit_single(struct net_device *dev, mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE); ret = dma_mapping_error(kdev, mapping); if (ret) { + priv->mib.tx_dma_failed++; netif_err(priv, tx_err, dev, "Tx DMA map failed\n"); dev_kfree_skb(skb); return ret; @@ -1035,6 +1039,7 @@ static int bcmgenet_xmit_frag(struct net_device *dev, skb_frag_size(frag), DMA_TO_DEVICE); ret = dma_mapping_error(kdev, mapping); if (ret) { + priv->mib.tx_dma_failed++; netif_err(priv, tx_err, dev, "%s: Tx DMA map failed\n", __func__); return ret; @@ -1231,6 +1236,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb) priv->rx_buf_len, DMA_FROM_DEVICE); ret = dma_mapping_error(kdev, mapping); if (ret) { + priv->mib.rx_dma_failed++; bcmgenet_free_cb(cb); netif_err(priv, rx_err, priv->dev, "%s DMA map failed\n", __func__); @@ -1397,8 +1403,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv, /* refill RX path on the current control block */ refill: err = bcmgenet_rx_refill(priv, cb); - if (err) + if (err) { + priv->mib.alloc_rx_buff_failed++; netif_err(priv, rx_err, dev, "Rx refill failed\n"); + } rxpktprocessed++; priv->rx_read_ptr++; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 31b2da5f9b82..c4ca7282a601 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -143,6 +143,9 @@ struct bcmgenet_mib_counters { u32 rbuf_ovflow_cnt; u32 rbuf_err_cnt; u32 mdf_err_cnt; + u32 alloc_rx_buff_failed; + u32 rx_dma_failed; + u32 tx_dma_failed; }; #define UMAC_HD_BKP_CTRL 0x004 -- GitLab From f869c912869edc2754355af9e10e5aaff8ff5a40 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 20 Nov 2014 01:54:48 +0100 Subject: [PATCH 5762/9457] net: sctp: keep owned chunk in destructor_arg instead of skb->cb It's just silly to hold the skb destructor argument around inside skb->cb[] as we currently do in SCTP. Nowadays, we're sort of cheating on data accounting in the sense that due to commit 4c3a5bdae293 ("sctp: Don't charge for data in sndbuf again when transmitting packet"), we orphan the skb already in the SCTP output path, i.e. giving back charged data memory, and use a different destructor only to make sure the sk doesn't vanish on skb destruction time. Thus, cb[] is still valid here as we operate within the SCTP layer. (It's generally actually a big candidate for future rework, imho.) However, storing the destructor in the cb[] can easily cause issues should an non sctp_packet_set_owner_w()'ed skb ever escape the SCTP layer, since cb[] may get overwritten by lower layers and thus can corrupt the chunk pointer. There are no such issues at present, but lets keep the chunk in destructor_arg, as this is the actual purpose for it. Signed-off-by: Daniel Borkmann Acked-by: Vlad Yasevich Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/sctp/socket.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2120292c842d..85e0b653edd7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -162,7 +162,7 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) chunk->skb->destructor = sctp_wfree; /* Save the chunk pointer in skb for sctp_wfree to use later. */ - *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; + skb_shinfo(chunk->skb)->destructor_arg = chunk; asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) + sizeof(struct sk_buff) + @@ -6870,14 +6870,10 @@ static void sctp_wake_up_waiters(struct sock *sk, */ static void sctp_wfree(struct sk_buff *skb) { - struct sctp_association *asoc; - struct sctp_chunk *chunk; - struct sock *sk; + struct sctp_chunk *chunk = skb_shinfo(skb)->destructor_arg; + struct sctp_association *asoc = chunk->asoc; + struct sock *sk = asoc->base.sk; - /* Get the saved chunk pointer. */ - chunk = *((struct sctp_chunk **)(skb->cb)); - asoc = chunk->asoc; - sk = asoc->base.sk; asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) + sizeof(struct sk_buff) + sizeof(struct sctp_chunk); -- GitLab From a0fccd4860cbd2f88f1fa577af2aca33f399c9d7 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 20 Nov 2014 10:29:05 +0800 Subject: [PATCH 5763/9457] r8152: adjust r8152_submit_rx The behavior of handling the returned status from r8152_submit_rx() is almost same, so let r8152_submit_rx() deal with the error directly. This could avoid the duplicate code. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0a30fd3f673d..3b89229f0737 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1032,7 +1032,6 @@ static void read_bulk_callback(struct urb *urb) int status = urb->status; struct rx_agg *agg; struct r8152 *tp; - int result; agg = urb->context; if (!agg) @@ -1083,16 +1082,7 @@ static void read_bulk_callback(struct urb *urb) break; } - result = r8152_submit_rx(tp, agg, GFP_ATOMIC); - if (result == -ENODEV) { - set_bit(RTL8152_UNPLUG, &tp->flags); - netif_device_detach(tp->netdev); - } else if (result) { - spin_lock(&tp->rx_lock); - list_add_tail(&agg->list, &tp->rx_done); - spin_unlock(&tp->rx_lock); - tasklet_schedule(&tp->tl); - } + r8152_submit_rx(tp, agg, GFP_ATOMIC); } static void write_bulk_callback(struct urb *urb) @@ -1680,7 +1670,6 @@ static void rx_bottom(struct r8152 *tp) int len_used = 0; struct urb *urb; u8 *rx_data; - int ret; list_del_init(cursor); @@ -1733,13 +1722,7 @@ static void rx_bottom(struct r8152 *tp) } submit: - ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); - if (ret && ret != -ENODEV) { - spin_lock_irqsave(&tp->rx_lock, flags); - list_add_tail(&agg->list, &tp->rx_done); - spin_unlock_irqrestore(&tp->rx_lock, flags); - tasklet_schedule(&tp->tl); - } + r8152_submit_rx(tp, agg, GFP_ATOMIC); } } @@ -1806,11 +1789,28 @@ static void bottom_half(unsigned long data) static int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) { + int ret; + usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), agg->head, agg_buf_sz, (usb_complete_t)read_bulk_callback, agg); - return usb_submit_urb(agg->urb, mem_flags); + ret = usb_submit_urb(agg->urb, mem_flags); + if (ret == -ENODEV) { + set_bit(RTL8152_UNPLUG, &tp->flags); + netif_device_detach(tp->netdev); + } else if (ret) { + struct urb *urb = agg->urb; + unsigned long flags; + + urb->actual_length = 0; + spin_lock_irqsave(&tp->rx_lock, flags); + list_add_tail(&agg->list, &tp->rx_done); + spin_unlock_irqrestore(&tp->rx_lock, flags); + tasklet_schedule(&tp->tl); + } + + return ret; } static void rtl_drop_queued_tx(struct r8152 *tp) -- GitLab From 7bcf4f605b4592452fba1e421b930909f7842310 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Thu, 20 Nov 2014 10:29:06 +0800 Subject: [PATCH 5764/9457] r8152: adjust rtl_start_rx If there is a error for r8152_submit_rx(), add the remaining rx buffers to the list. Then the remaining rx buffers could be submitted later. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/usb/r8152.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 3b89229f0737..4a9ece01def6 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2001,6 +2001,25 @@ static int rtl_start_rx(struct r8152 *tp) break; } + if (ret && ++i < RTL8152_MAX_RX) { + struct list_head rx_queue; + unsigned long flags; + + INIT_LIST_HEAD(&rx_queue); + + do { + struct rx_agg *agg = &tp->rx_info[i++]; + struct urb *urb = agg->urb; + + urb->actual_length = 0; + list_add_tail(&agg->list, &rx_queue); + } while (i < RTL8152_MAX_RX); + + spin_lock_irqsave(&tp->rx_lock, flags); + list_splice_tail(&rx_queue, &tp->rx_done); + spin_unlock_irqrestore(&tp->rx_lock, flags); + } + return ret; } -- GitLab From 479163f4608214d18bc3266ab6e4b578897a3052 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 08:13:57 +0000 Subject: [PATCH 5765/9457] mlx5: don't duplicate kvfree() Signed-off-by: Al Viro Acked-by: Eli Cohen Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx5/cq.c | 8 ++++---- drivers/infiniband/hw/mlx5/mr.c | 4 ++-- drivers/infiniband/hw/mlx5/qp.c | 8 ++++---- drivers/infiniband/hw/mlx5/srq.c | 6 +++--- drivers/net/ethernet/mellanox/mlx5/core/eq.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/port.c | 4 ++-- include/linux/mlx5/driver.h | 8 -------- 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 10cfce5119a9..c463e7bba5f4 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -805,14 +805,14 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries, } - mlx5_vfree(cqb); + kvfree(cqb); return &cq->ibcq; err_cmd: mlx5_core_destroy_cq(dev->mdev, &cq->mcq); err_cqb: - mlx5_vfree(cqb); + kvfree(cqb); if (context) destroy_cq_user(cq, context); else @@ -1159,11 +1159,11 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) } mutex_unlock(&cq->resize_mutex); - mlx5_vfree(in); + kvfree(in); return 0; ex_alloc: - mlx5_vfree(in); + kvfree(in); ex_resize: if (udata) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 8ee7cb46e059..4c89b64aa9cf 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -853,14 +853,14 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr, goto err_2; } mr->umem = umem; - mlx5_vfree(in); + kvfree(in); mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmr.key); return mr; err_2: - mlx5_vfree(in); + kvfree(in); err_1: kfree(mr); diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index e261a53f9a02..0e2ef9fe0e29 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -647,7 +647,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, mlx5_ib_db_unmap_user(context, &qp->db); err_free: - mlx5_vfree(*in); + kvfree(*in); err_umem: if (qp->umem) @@ -761,7 +761,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev, kfree(qp->rq.wrid); err_free: - mlx5_vfree(*in); + kvfree(*in); err_buf: mlx5_buf_free(dev->mdev, &qp->buf); @@ -971,7 +971,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, goto err_create; } - mlx5_vfree(in); + kvfree(in); /* Hardware wants QPN written in big-endian order (after * shifting) for send doorbell. Precompute this value to save * a little bit when posting sends. @@ -988,7 +988,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, else if (qp->create_type == MLX5_QP_KERNEL) destroy_qp_kernel(dev, qp); - mlx5_vfree(in); + kvfree(in); return err; } diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c index 97cc1baaa8e3..41fec66217dd 100644 --- a/drivers/infiniband/hw/mlx5/srq.c +++ b/drivers/infiniband/hw/mlx5/srq.c @@ -141,7 +141,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, return 0; err_in: - mlx5_vfree(*in); + kvfree(*in); err_umem: ib_umem_release(srq->umem); @@ -209,7 +209,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq, return 0; err_in: - mlx5_vfree(*in); + kvfree(*in); err_buf: mlx5_buf_free(dev->mdev, &srq->buf); @@ -306,7 +306,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn); in->ctx.db_record = cpu_to_be64(srq->db.dma); err = mlx5_core_create_srq(dev->mdev, &srq->msrq, in, inlen); - mlx5_vfree(in); + kvfree(in); if (err) { mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err); goto err_usr_kern_srq; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index ad2c96a02a53..dfd3ad0a39c1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -390,7 +390,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, */ eq_update_ci(eq, 1); - mlx5_vfree(in); + kvfree(in); return 0; err_irq: @@ -400,7 +400,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, mlx5_cmd_destroy_eq(dev, eq->eqn); err_in: - mlx5_vfree(in); + kvfree(in); err_buf: mlx5_buf_free(dev, &eq->buf); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index d476918ef269..4fdaae9b54d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -349,7 +349,7 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages, for (i--; i >= 0; i--) free_4k(dev, be64_to_cpu(in->pas[i])); out_free: - mlx5_vfree(in); + kvfree(in); return err; } @@ -400,7 +400,7 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages, } out_free: - mlx5_vfree(out); + kvfree(out); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index 313965853e10..72c2d002c3b8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -68,9 +68,9 @@ int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in, memcpy(data_out, out->data, size_out); ex2: - mlx5_vfree(out); + kvfree(out); ex1: - mlx5_vfree(in); + kvfree(in); return err; } EXPORT_SYMBOL_GPL(mlx5_core_access_reg); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 246310dc8bef..b1bf41556b32 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -633,14 +633,6 @@ static inline void *mlx5_vzalloc(unsigned long size) return rtn; } -static inline void mlx5_vfree(const void *addr) -{ - if (addr && is_vmalloc_addr(addr)) - vfree(addr); - else - kfree(addr); -} - static inline u32 mlx5_base_mkey(const u32 key) { return key & 0xffffff00u; -- GitLab From 914efb02befeedbd71a6f115c9d2fb38a34af04d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 08:15:38 +0000 Subject: [PATCH 5766/9457] mlx4: don't duplicate kvfree() Signed-off-by: Al Viro Acked-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/mr.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 193a6adb5d04..d6f549685c0f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -130,10 +130,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) err_out_free: for (i = 0; i <= buddy->max_order; ++i) - if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i])) - vfree(buddy->bits[i]); - else - kfree(buddy->bits[i]); + kvfree(buddy->bits[i]); err_out: kfree(buddy->bits); @@ -147,10 +144,7 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) int i; for (i = 0; i <= buddy->max_order; ++i) - if (is_vmalloc_addr(buddy->bits[i])) - vfree(buddy->bits[i]); - else - kfree(buddy->bits[i]); + kvfree(buddy->bits[i]); kfree(buddy->bits); kfree(buddy->num_free); -- GitLab From 50d9aa99bd35c77200e0e3dd7a72274f8304701f Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 21 Nov 2014 14:52:38 -0500 Subject: [PATCH 5767/9457] Btrfs: make sure logged extents complete in the current transaction V3 Liu Bo pointed out that my previous fix would lose the generation update in the scenario I described. It is actually much worse than that, we could lose the entire extent if we lose power right after the transaction commits. Consider the following write extent 0-4k log extent in log tree commit transaction < power fail happens here ordered extent completes We would lose the 0-4k extent because it hasn't updated the actual fs tree, and the transaction commit will reset the log so it isn't replayed. If we lose power before the transaction commit we are save, otherwise we are not. Fix this by keeping track of all extents we logged in this transaction. Then when we go to commit the transaction make sure we wait for all of those ordered extents to complete before proceeding. This will make sure that if we lose power after the transaction commit we still have our data. This also fixes the problem of the improperly updated extent generation. Thanks, cc: stable@vger.kernel.org Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 20 ++++++++++++++++++++ fs/btrfs/ordered-data.c | 9 +++++++-- fs/btrfs/ordered-data.h | 8 +++++++- fs/btrfs/transaction.c | 33 +++++++++++++++++++++++++++++++++ fs/btrfs/transaction.h | 2 ++ fs/btrfs/tree-log.c | 6 +++--- 6 files changed, 72 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7af9a1978a2f..6efaee8d7739 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -4129,6 +4129,25 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, return 0; } +static void btrfs_free_pending_ordered(struct btrfs_transaction *cur_trans, + struct btrfs_fs_info *fs_info) +{ + struct btrfs_ordered_extent *ordered; + + spin_lock(&fs_info->trans_lock); + while (!list_empty(&cur_trans->pending_ordered)) { + ordered = list_first_entry(&cur_trans->pending_ordered, + struct btrfs_ordered_extent, + trans_list); + list_del_init(&ordered->trans_list); + spin_unlock(&fs_info->trans_lock); + + btrfs_put_ordered_extent(ordered); + spin_lock(&fs_info->trans_lock); + } + spin_unlock(&fs_info->trans_lock); +} + void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, struct btrfs_root *root) { @@ -4140,6 +4159,7 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, cur_trans->state = TRANS_STATE_UNBLOCKED; wake_up(&root->fs_info->transaction_wait); + btrfs_free_pending_ordered(cur_trans, root->fs_info); btrfs_destroy_delayed_inodes(root); btrfs_assert_delayed_root_empty(root); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 1401b1af4f06..9c28eb4da4dd 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -220,6 +220,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, INIT_LIST_HEAD(&entry->work_list); init_completion(&entry->completion); INIT_LIST_HEAD(&entry->log_list); + INIT_LIST_HEAD(&entry->trans_list); trace_btrfs_ordered_extent_add(inode, entry); @@ -443,6 +444,8 @@ void btrfs_get_logged_extents(struct inode *inode, ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node); if (!list_empty(&ordered->log_list)) continue; + if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) + continue; list_add_tail(&ordered->log_list, logged_list); atomic_inc(&ordered->refs); } @@ -472,7 +475,8 @@ void btrfs_submit_logged_extents(struct list_head *logged_list, spin_unlock_irq(&log->log_extents_lock[index]); } -void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid) +void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *log, u64 transid) { struct btrfs_ordered_extent *ordered; int index = transid % 2; @@ -497,7 +501,8 @@ void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid) wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags)); - btrfs_put_ordered_extent(ordered); + if (!test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) + list_add_tail(&ordered->trans_list, &trans->ordered); spin_lock_irq(&log->log_extents_lock[index]); } spin_unlock_irq(&log->log_extents_lock[index]); diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index d81a274d621e..0124bffc775f 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -71,6 +71,8 @@ struct btrfs_ordered_sum { ordered extent */ #define BTRFS_ORDERED_TRUNCATED 9 /* Set when we have to truncate an extent */ +#define BTRFS_ORDERED_LOGGED 10 /* Set when we've waited on this ordered extent + * in the logging code. */ struct btrfs_ordered_extent { /* logical offset in the file */ u64 file_offset; @@ -121,6 +123,9 @@ struct btrfs_ordered_extent { /* If we need to wait on this to be done */ struct list_head log_list; + /* If the transaction needs to wait on this ordered extent */ + struct list_head trans_list; + /* used to wait for the BTRFS_ORDERED_COMPLETE bit */ wait_queue_head_t wait; @@ -197,7 +202,8 @@ void btrfs_get_logged_extents(struct inode *inode, void btrfs_put_logged_extents(struct list_head *logged_list); void btrfs_submit_logged_extents(struct list_head *logged_list, struct btrfs_root *log); -void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid); +void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *log, u64 transid); void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid); int __init ordered_data_init(void); void ordered_data_exit(void); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 16c704b68704..295a135c9c24 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -247,6 +247,7 @@ static noinline int join_transaction(struct btrfs_root *root, unsigned int type) INIT_LIST_HEAD(&cur_trans->pending_snapshots); INIT_LIST_HEAD(&cur_trans->pending_chunks); INIT_LIST_HEAD(&cur_trans->switch_commits); + INIT_LIST_HEAD(&cur_trans->pending_ordered); list_add_tail(&cur_trans->list, &fs_info->trans_list); extent_io_tree_init(&cur_trans->dirty_pages, fs_info->btree_inode->i_mapping); @@ -515,6 +516,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, h->sync = false; INIT_LIST_HEAD(&h->qgroup_ref_list); INIT_LIST_HEAD(&h->new_bgs); + INIT_LIST_HEAD(&h->ordered); smp_mb(); if (cur_trans->state >= TRANS_STATE_BLOCKED && @@ -746,6 +748,12 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, if (!list_empty(&trans->new_bgs)) btrfs_create_pending_block_groups(trans, root); + if (!list_empty(&trans->ordered)) { + spin_lock(&info->trans_lock); + list_splice(&trans->ordered, &cur_trans->pending_ordered); + spin_unlock(&info->trans_lock); + } + trans->delayed_ref_updates = 0; if (!trans->sync) { must_run_delayed_refs = @@ -1715,6 +1723,28 @@ static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) btrfs_wait_ordered_roots(fs_info, -1); } +static inline void +btrfs_wait_pending_ordered(struct btrfs_transaction *cur_trans, + struct btrfs_fs_info *fs_info) +{ + struct btrfs_ordered_extent *ordered; + + spin_lock(&fs_info->trans_lock); + while (!list_empty(&cur_trans->pending_ordered)) { + ordered = list_first_entry(&cur_trans->pending_ordered, + struct btrfs_ordered_extent, + trans_list); + list_del_init(&ordered->trans_list); + spin_unlock(&fs_info->trans_lock); + + wait_event(ordered->wait, test_bit(BTRFS_ORDERED_COMPLETE, + &ordered->flags)); + btrfs_put_ordered_extent(ordered); + spin_lock(&fs_info->trans_lock); + } + spin_unlock(&fs_info->trans_lock); +} + int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { @@ -1765,6 +1795,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, } spin_lock(&root->fs_info->trans_lock); + list_splice(&trans->ordered, &cur_trans->pending_ordered); if (cur_trans->state >= TRANS_STATE_COMMIT_START) { spin_unlock(&root->fs_info->trans_lock); atomic_inc(&cur_trans->use_count); @@ -1817,6 +1848,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, btrfs_wait_delalloc_flush(root->fs_info); + btrfs_wait_pending_ordered(cur_trans, root->fs_info); + btrfs_scrub_pause(root); /* * Ok now we need to make sure to block out any other joins while we diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index b3f5b40aab22..fd400a3668a8 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h @@ -56,6 +56,7 @@ struct btrfs_transaction { wait_queue_head_t commit_wait; struct list_head pending_snapshots; struct list_head pending_chunks; + struct list_head pending_ordered; struct list_head switch_commits; struct btrfs_delayed_ref_root delayed_refs; int aborted; @@ -105,6 +106,7 @@ struct btrfs_trans_handle { */ struct btrfs_root *root; struct seq_list delayed_ref_elem; + struct list_head ordered; struct list_head qgroup_ref_list; struct list_head new_bgs; }; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index fc715ff31d26..7d96cc961663 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2600,7 +2600,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, if (atomic_read(&log_root_tree->log_commit[index2])) { blk_finish_plug(&plug); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); - btrfs_wait_logged_extents(log, log_transid); + btrfs_wait_logged_extents(trans, log, log_transid); wait_log_commit(trans, log_root_tree, root_log_ctx.log_transid); mutex_unlock(&log_root_tree->log_mutex); @@ -2645,7 +2645,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, btrfs_wait_marked_extents(log_root_tree, &log_root_tree->dirty_log_pages, EXTENT_NEW | EXTENT_DIRTY); - btrfs_wait_logged_extents(log, log_transid); + btrfs_wait_logged_extents(trans, log, log_transid); btrfs_set_super_log_root(root->fs_info->super_for_commit, log_root_tree->node->start); @@ -3766,7 +3766,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); - btrfs_set_token_file_extent_generation(leaf, fi, em->generation, + btrfs_set_token_file_extent_generation(leaf, fi, trans->transid, &token); if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) btrfs_set_token_file_extent_type(leaf, fi, -- GitLab From 7cc76f51508219a74dca835745e4f84393820017 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 20 Nov 2014 16:31:05 +0800 Subject: [PATCH 5768/9457] macvtap: advance iov iterator when needed in macvtap_put_user() When mergeable buffer is used, vnet_hdr_sz is greater than sizeof struct virtio_net_hdr. So we need advance the iov iterators in this case. Fixes 6c36d2e26cda1ad3e2c4b90dd843825fc62fe5b4 ("macvtap: Use iovec iterators") Cc: Herbert Xu Signed-off-by: Jason Wang Acked-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index cea99d4a8263..42a80d3de839 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -797,6 +797,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, if (copy_to_iter(&vnet_hdr, sizeof(vnet_hdr), iter) != sizeof(vnet_hdr)) return -EFAULT; + + iov_iter_advance(iter, vnet_hdr_len - sizeof(vnet_hdr)); } total = vnet_hdr_len; total += skb->len; -- GitLab From a28046956c71985046474283fa3bcd256915fb72 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 14 Nov 2014 16:16:30 -0500 Subject: [PATCH 5769/9457] Btrfs: do not move em to modified list when unpinning We use the modified list to keep track of which extents have been modified so we know which ones are candidates for logging at fsync() time. Newly modified extents are added to the list at modification time, around the same time the ordered extent is created. We do this so that we don't have to wait for ordered extents to complete before we know what we need to log. The problem is when something like this happens log extent 0-4k on inode 1 copy csum for 0-4k from ordered extent into log sync log commit transaction log some other extent on inode 1 ordered extent for 0-4k completes and adds itself onto modified list again log changed extents see ordered extent for 0-4k has already been logged at this point we assume the csum has been copied sync log crash On replay we will see the extent 0-4k in the log, drop the original 0-4k extent which is the same one that we are replaying which also drops the csum, and then we won't find the csum in the log for that bytenr. This of course causes us to have errors about not having csums for certain ranges of our inode. So remove the modified list manipulation in unpin_extent_cache, any modified extents should have been added well before now, and we don't want them re-logged. This fixes my test that I could reliably reproduce this problem with. Thanks, cc: stable@vger.kernel.org Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/extent_map.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 225302b39afb..6a98bddd8f33 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -287,8 +287,6 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, if (!em) goto out; - if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) - list_move(&em->list, &tree->modified_extents); em->generation = gen; clear_bit(EXTENT_FLAG_PINNED, &em->flags); em->mod_start = em->start; -- GitLab From 5ab5e44a36164f0366a98b47289c868d8fbcb256 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 13 Nov 2014 16:59:53 +0000 Subject: [PATCH 5770/9457] Btrfs: don't ignore log btree writeback errors If an error happens during writeback of log btree extents, make sure the error is returned to the caller (fsync), so that it takes proper action (commit current transaction) instead of writing a superblock that points to log btrees with all or some nodes that weren't durably persisted. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/tree-log.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 7d96cc961663..afe483cb27b0 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2599,12 +2599,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, index2 = root_log_ctx.log_transid % 2; if (atomic_read(&log_root_tree->log_commit[index2])) { blk_finish_plug(&plug); - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + ret = btrfs_wait_marked_extents(log, &log->dirty_log_pages, + mark); btrfs_wait_logged_extents(trans, log, log_transid); wait_log_commit(trans, log_root_tree, root_log_ctx.log_transid); mutex_unlock(&log_root_tree->log_mutex); - ret = root_log_ctx.log_ret; + if (!ret) + ret = root_log_ctx.log_ret; goto out; } ASSERT(root_log_ctx.log_transid == log_root_tree->log_transid); @@ -2641,10 +2643,17 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, mutex_unlock(&log_root_tree->log_mutex); goto out_wake_log_root; } - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); - btrfs_wait_marked_extents(log_root_tree, - &log_root_tree->dirty_log_pages, - EXTENT_NEW | EXTENT_DIRTY); + ret = btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + if (!ret) + ret = btrfs_wait_marked_extents(log_root_tree, + &log_root_tree->dirty_log_pages, + EXTENT_NEW | EXTENT_DIRTY); + if (ret) { + btrfs_set_log_full_commit(root->fs_info, trans); + btrfs_free_logged_extents(log, log_transid); + mutex_unlock(&log_root_tree->log_mutex); + goto out_wake_log_root; + } btrfs_wait_logged_extents(trans, log, log_transid); btrfs_set_super_log_root(root->fs_info->super_for_commit, -- GitLab From 0870295b2371673b3563735825ad559409d8cedc Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 13 Nov 2014 17:00:35 +0000 Subject: [PATCH 5771/9457] Btrfs: collect only the necessary ordered extents on ranged fsync Instead of collecting all ordered extents from the inode's ordered tree and then wait for all of them to complete, just collect the ones that overlap the fsync range. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ordered-data.c | 16 +++++++++++++--- fs/btrfs/ordered-data.h | 4 +++- fs/btrfs/tree-log.c | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 9c28eb4da4dd..534544e08f76 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -432,21 +432,31 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, /* Needs to either be called under a log transaction or the log_mutex */ void btrfs_get_logged_extents(struct inode *inode, - struct list_head *logged_list) + struct list_head *logged_list, + const loff_t start, + const loff_t end) { struct btrfs_ordered_inode_tree *tree; struct btrfs_ordered_extent *ordered; struct rb_node *n; + struct rb_node *prev; tree = &BTRFS_I(inode)->ordered_tree; spin_lock_irq(&tree->lock); - for (n = rb_first(&tree->tree); n; n = rb_next(n)) { + n = __tree_search(&tree->tree, end, &prev); + if (!n) + n = prev; + for (; n; n = rb_prev(n)) { ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node); + if (ordered->file_offset > end) + continue; + if (entry_end(ordered) <= start) + break; if (!list_empty(&ordered->log_list)) continue; if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) continue; - list_add_tail(&ordered->log_list, logged_list); + list_add(&ordered->log_list, logged_list); atomic_inc(&ordered->refs); } spin_unlock_irq(&tree->lock); diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 0124bffc775f..e96cd4ccd805 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -198,7 +198,9 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr); void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr); void btrfs_get_logged_extents(struct inode *inode, - struct list_head *logged_list); + struct list_head *logged_list, + const loff_t start, + const loff_t end); void btrfs_put_logged_extents(struct list_head *logged_list); void btrfs_submit_logged_extents(struct list_head *logged_list, struct btrfs_root *log); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index afe483cb27b0..3883d0febd82 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3972,7 +3972,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, mutex_lock(&BTRFS_I(inode)->log_mutex); - btrfs_get_logged_extents(inode, &logged_list); + btrfs_get_logged_extents(inode, &logged_list, start, end); /* * a brute force approach to making sure we get the most uptodate -- GitLab From b38ef71cb102208dffcf4e8524e9d5ec4ec0eaa9 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 13 Nov 2014 17:01:45 +0000 Subject: [PATCH 5772/9457] Btrfs: ensure ordered extent errors aren't missed on fsync When doing a fsync with a fast path we have a time window where we can miss the fact that writeback of some file data failed, and therefore we endup returning success (0) from fsync when we should return an error. The steps that lead to this are the following: 1) We start all ordered extents by calling filemap_fdatawrite_range(); 2) We do some other work like locking the inode's i_mutex, start a transaction, start a log transaction, etc; 3) We enter btrfs_log_inode(), acquire the inode's log_mutex and collect all the ordered extents from inode's ordered tree into a list; 4) But by the time we do ordered extent collection, some ordered extents we started at step 1) might have already completed with an error, and therefore we didn't found them in the ordered tree and had no idea they finished with an error. This makes our fsync return success (0) to userspace, but has no bad effects on the log like for example insertion of file extent items into the log that point to unwritten extents, because the invalid extent maps were removed before the ordered extent completed (in inode.c:btrfs_finish_ordered_io). So after collecting the ordered extents just check if the inode's i_mapping has any error flags set (AS_EIO or AS_ENOSPC) and leave with an error if it does. Whenever writeback fails for a page of an ordered extent, we call mapping_set_error (done in extent_io.c:end_extent_writepage, called by extent_io.c:end_bio_extent_writepage) that sets one of those error flags in the inode's i_mapping flags. This change also has the side effect of fixing the issue where for fast fsyncs we never checked/cleared the error flags from the inode's i_mapping flags, which means that a full fsync performed after a fast fsync could get such errors that belonged to the fast fsync - because the full fsync calls btrfs_wait_ordered_range() which calls filemap_fdatawait_range(), and the later checks for and clears those flags, while for fast fsyncs we never call filemap_fdatawait_range() or anything else that checks for and clears the error flags from the inode's i_mapping. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 1 + fs/btrfs/inode.c | 15 +++++++++++++++ fs/btrfs/tree-log.c | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a9466e346358..49d956b2cf30 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3866,6 +3866,7 @@ int btrfs_prealloc_file_range_trans(struct inode *inode, struct btrfs_trans_handle *trans, int mode, u64 start, u64 num_bytes, u64 min_size, loff_t actual_len, u64 *alloc_hint); +int btrfs_inode_check_errors(struct inode *inode); extern const struct dentry_operations btrfs_dentry_operations; /* ioctl.c */ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index cb5978a4a277..a5374c2bb943 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9464,6 +9464,21 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) } +/* Inspired by filemap_check_errors() */ +int btrfs_inode_check_errors(struct inode *inode) +{ + int ret = 0; + + if (test_bit(AS_ENOSPC, &inode->i_mapping->flags) && + test_and_clear_bit(AS_ENOSPC, &inode->i_mapping->flags)) + ret = -ENOSPC; + if (test_bit(AS_EIO, &inode->i_mapping->flags) && + test_and_clear_bit(AS_EIO, &inode->i_mapping->flags)) + ret = -EIO; + + return ret; +} + static const struct inode_operations btrfs_dir_inode_operations = { .getattr = btrfs_getattr, .lookup = btrfs_lookup, diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3883d0febd82..9a02da16f2be 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3635,6 +3635,12 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans, test_bit(BTRFS_ORDERED_IOERR, &ordered->flags))); if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) { + /* + * Clear the AS_EIO/AS_ENOSPC flags from the inode's + * i_mapping flags, so that the next fsync won't get + * an outdated io error too. + */ + btrfs_inode_check_errors(inode); *ordered_io_error = true; break; } @@ -4098,6 +4104,21 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, btrfs_release_path(path); btrfs_release_path(dst_path); if (fast_search) { + /* + * Some ordered extents started by fsync might have completed + * before we collected the ordered extents in logged_list, which + * means they're gone, not in our logged_list nor in the inode's + * ordered tree. We want the application/user space to know an + * error happened while attempting to persist file data so that + * it can take proper action. If such error happened, we leave + * without writing to the log tree and the fsync must report the + * file data write error and not commit the current transaction. + */ + err = btrfs_inode_check_errors(inode); + if (err) { + ctx->io_err = err; + goto out_unlock; + } ret = btrfs_log_changed_extents(trans, root, inode, dst_path, &logged_list, ctx); if (ret) { -- GitLab From 0655f6a8635b1b66f2434d5556b1044c14b1ccaf Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:07 +0100 Subject: [PATCH 5773/9457] tipc: add bearer disable/enable to new netlink api A new netlink API for tipc that can disable or enable a tipc bearer. The new API is separated from the old API because of a bug in the user space client (tipc-config). The problem is that older versions of tipc-config has a very low receive limit and adding commands to the legacy genl_opts struct causes the ctrl_getfamily() response message to grow, subsequently breaking the tool. The new API utilizes netlink policies for input validation. Where the top-level netlink attributes are tipc-logical entities, like bearer. The top level entities then contain nested attributes. In this case a name, nested link properties and a domain. Netlink commands implemented in this patch: TIPC_NL_BEARER_ENABLE TIPC_NL_BEARER_DISABLE Netlink logical layout of bearer enable message: -> bearer -> name [ -> domain ] [ -> properties -> priority ] Netlink logical layout of bearer disable message: -> bearer -> name Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 83 ++++++++++++++++++++++++++ net/tipc/bearer.c | 99 ++++++++++++++++++++++++++++++- net/tipc/bearer.h | 7 ++- net/tipc/core.h | 1 + net/tipc/link.c | 47 +++++++++++++++ net/tipc/link.h | 3 + net/tipc/netlink.c | 42 ++++++++++++- net/tipc/netlink.h | 41 +++++++++++++ 8 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 include/uapi/linux/tipc_netlink.h create mode 100644 net/tipc/netlink.h diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h new file mode 100644 index 000000000000..b9b710faa229 --- /dev/null +++ b/include/uapi/linux/tipc_netlink.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_TIPC_NETLINK_H_ +#define _LINUX_TIPC_NETLINK_H_ + +#define TIPC_GENL_V2_NAME "TIPCv2" +#define TIPC_GENL_V2_VERSION 0x1 + +/* Netlink commands */ +enum { + TIPC_NL_UNSPEC, + TIPC_NL_LEGACY, + TIPC_NL_BEARER_DISABLE, + TIPC_NL_BEARER_ENABLE, + + __TIPC_NL_CMD_MAX, + TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 +}; + +/* Top level netlink attributes */ +enum { + TIPC_NLA_UNSPEC, + TIPC_NLA_BEARER, /* nest */ + + __TIPC_NLA_MAX, + TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 +}; + +/* Bearer info */ +enum { + TIPC_NLA_BEARER_UNSPEC, + TIPC_NLA_BEARER_NAME, /* string */ + TIPC_NLA_BEARER_PROP, /* nest */ + TIPC_NLA_BEARER_DOMAIN, /* u32 */ + + __TIPC_NLA_BEARER_MAX, + TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1 +}; + +/* Nest, link propreties. Valid for link, media and bearer */ +enum { + TIPC_NLA_PROP_UNSPEC, + + TIPC_NLA_PROP_PRIO, /* u32 */ + TIPC_NLA_PROP_TOL, /* u32 */ + TIPC_NLA_PROP_WIN, /* u32 */ + + __TIPC_NLA_PROP_MAX, + TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1 +}; + +#endif diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 264474394f9f..59815be0ab98 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -1,7 +1,7 @@ /* * net/tipc/bearer.c: TIPC bearer code * - * Copyright (c) 1996-2006, 2013, Ericsson AB + * Copyright (c) 1996-2006, 2013-2014, Ericsson AB * Copyright (c) 2004-2006, 2010-2013, Wind River Systems * All rights reserved. * @@ -37,6 +37,7 @@ #include "core.h" #include "config.h" #include "bearer.h" +#include "link.h" #include "discover.h" #define MAX_ADDR_STR 60 @@ -49,6 +50,17 @@ static struct tipc_media * const media_info_array[] = { NULL }; +static const struct nla_policy +tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { + [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_BEARER_NAME] = { + .type = NLA_STRING, + .len = TIPC_MAX_BEARER_NAME + }, + [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, + [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } +}; + struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1]; static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down); @@ -627,3 +639,88 @@ void tipc_bearer_stop(void) } } } + +int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *name; + struct tipc_bearer *bearer; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + + if (!info->attrs[TIPC_NLA_BEARER]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, + info->attrs[TIPC_NLA_BEARER], + tipc_nl_bearer_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_BEARER_NAME]) + return -EINVAL; + + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + rtnl_lock(); + bearer = tipc_bearer_find(name); + if (!bearer) { + rtnl_unlock(); + return -EINVAL; + } + + bearer_disable(bearer, false); + rtnl_unlock(); + + return 0; +} + +int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *bearer; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + u32 domain; + u32 prio; + + prio = TIPC_MEDIA_LINK_PRI; + domain = tipc_own_addr & TIPC_CLUSTER_MASK; + + if (!info->attrs[TIPC_NLA_BEARER]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, + info->attrs[TIPC_NLA_BEARER], + tipc_nl_bearer_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_BEARER_NAME]) + return -EINVAL; + + bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + if (attrs[TIPC_NLA_BEARER_DOMAIN]) + domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]); + + if (attrs[TIPC_NLA_BEARER_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + + err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP], + props); + if (err) + return err; + + if (props[TIPC_NLA_PROP_PRIO]) + prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + } + + rtnl_lock(); + err = tipc_enable_bearer(bearer, domain, prio); + if (err) { + rtnl_unlock(); + return err; + } + rtnl_unlock(); + + return 0; +} diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 78fccc49de23..a87e8c78d862 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -1,7 +1,7 @@ /* * net/tipc/bearer.h: Include file for TIPC bearer code * - * Copyright (c) 1996-2006, 2013, Ericsson AB + * Copyright (c) 1996-2006, 2013-2014, Ericsson AB * Copyright (c) 2005, 2010-2011, Wind River Systems * All rights reserved. * @@ -38,6 +38,8 @@ #define _TIPC_BEARER_H #include "bcast.h" +#include "netlink.h" +#include #define MAX_BEARERS 2 #define MAX_MEDIA 2 @@ -176,6 +178,9 @@ extern struct tipc_media eth_media_info; extern struct tipc_media ib_media_info; #endif +int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); + int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); diff --git a/net/tipc/core.h b/net/tipc/core.h index f773b148722f..b578b10feefa 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -41,6 +41,7 @@ #include #include +#include #include #include #include diff --git a/net/tipc/link.c b/net/tipc/link.c index 7cf8004577f1..e7f365012bd1 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -40,6 +40,7 @@ #include "name_distr.h" #include "discover.h" #include "config.h" +#include "netlink.h" #include @@ -50,6 +51,14 @@ static const char *link_co_err = "Link changeover error, "; static const char *link_rst_msg = "Resetting link "; static const char *link_unk_evt = "Unknown link event "; +/* Properties valid for media, bearar and link */ +static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { + [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 } +}; + /* * Out-of-range value for link session numbers */ @@ -2376,3 +2385,41 @@ static void link_print(struct tipc_link *l_ptr, const char *str) else pr_cont("\n"); } + +/* Parse and validate nested (link) properties valid for media, bearer and link + */ +int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]) +{ + int err; + + err = nla_parse_nested(props, TIPC_NLA_PROP_MAX, prop, + tipc_nl_prop_policy); + if (err) + return err; + + if (props[TIPC_NLA_PROP_PRIO]) { + u32 prio; + + prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + if (prio > TIPC_MAX_LINK_PRI) + return -EINVAL; + } + + if (props[TIPC_NLA_PROP_TOL]) { + u32 tol; + + tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); + if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL)) + return -EINVAL; + } + + if (props[TIPC_NLA_PROP_WIN]) { + u32 win; + + win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + if ((win < TIPC_MIN_LINK_WIN) || (win > TIPC_MAX_LINK_WIN)) + return -EINVAL; + } + + return 0; +} diff --git a/net/tipc/link.h b/net/tipc/link.h index b567a3427fda..4338294f20d4 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -37,6 +37,7 @@ #ifndef _TIPC_LINK_H #define _TIPC_LINK_H +#include #include "msg.h" #include "node.h" @@ -239,6 +240,8 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *start, u32 retransmits); +int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); + /* * Link sequence number manipulation routines (uses modulo 2**16 arithmetic) */ diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index ad844d365340..af506ae0a129 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -1,7 +1,7 @@ /* * net/tipc/netlink.c: TIPC configuration handling * - * Copyright (c) 2005-2006, Ericsson AB + * Copyright (c) 2005-2006, 2014, Ericsson AB * Copyright (c) 2005-2007, Wind River Systems * All rights reserved. * @@ -36,6 +36,7 @@ #include "core.h" #include "config.h" +#include "bearer.h" #include static int handle_cmd(struct sk_buff *skb, struct genl_info *info) @@ -68,6 +69,12 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) return 0; } +static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { + [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, + [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, +}; + +/* Legacy ASCII API */ static struct genl_family tipc_genl_family = { .id = GENL_ID_GENERATE, .name = TIPC_GENL_NAME, @@ -76,6 +83,7 @@ static struct genl_family tipc_genl_family = { .maxattr = 0, }; +/* Legacy ASCII API */ static struct genl_ops tipc_genl_ops[] = { { .cmd = TIPC_GENL_CMD, @@ -83,11 +91,42 @@ static struct genl_ops tipc_genl_ops[] = { }, }; +/* Users of the legacy API (tipc-config) can't handle that we add operations, + * so we have a separate genl handling for the new API. + */ +struct genl_family tipc_genl_v2_family = { + .id = GENL_ID_GENERATE, + .name = TIPC_GENL_V2_NAME, + .version = TIPC_GENL_V2_VERSION, + .hdrsize = 0, + .maxattr = TIPC_NLA_MAX, +}; + +static const struct genl_ops tipc_genl_v2_ops[] = { + { + .cmd = TIPC_NL_BEARER_DISABLE, + .doit = tipc_nl_bearer_disable, + .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_BEARER_ENABLE, + .doit = tipc_nl_bearer_enable, + .policy = tipc_nl_policy, + } +}; + int tipc_netlink_start(void) { int res; res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); + if (res) { + pr_err("Failed to register legacy interface\n"); + return res; + } + + res = genl_register_family_with_ops(&tipc_genl_v2_family, + tipc_genl_v2_ops); if (res) { pr_err("Failed to register netlink interface\n"); return res; @@ -98,4 +137,5 @@ int tipc_netlink_start(void) void tipc_netlink_stop(void) { genl_unregister_family(&tipc_genl_family); + genl_unregister_family(&tipc_genl_v2_family); } diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h new file mode 100644 index 000000000000..e9980c0e2207 --- /dev/null +++ b/net/tipc/netlink.h @@ -0,0 +1,41 @@ +/* + * net/tipc/netlink.h: Include file for TIPC netlink code + * + * Copyright (c) 2014, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIPC_NETLINK_H +#define _TIPC_NETLINK_H + +extern struct genl_family tipc_genl_v2_family; + +#endif -- GitLab From 35b9dd7607f049466a66427e58818b29aeae9ea7 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:08 +0100 Subject: [PATCH 5774/9457] tipc: add bearer get/dump to new netlink api Add TIPC_NL_BEARER_GET command to the new tipc netlink API. This command supports dumping all data about all bearers or getting all information about a specific bearer. The information about a bearer includes name, link priorities and domain. Netlink logical layout of bearer get message: -> bearer -> name Netlink logical layout of returned bearer information: -> bearer -> name -> link properties -> priority -> tolerance -> window -> domain Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 1 + net/tipc/bearer.c | 125 ++++++++++++++++++++++++++++++ net/tipc/bearer.h | 2 + net/tipc/netlink.c | 6 ++ net/tipc/netlink.h | 6 ++ 5 files changed, 140 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index b9b710faa229..249ec7e9952c 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -43,6 +43,7 @@ enum { TIPC_NL_LEGACY, TIPC_NL_BEARER_DISABLE, TIPC_NL_BEARER_ENABLE, + TIPC_NL_BEARER_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 59815be0ab98..d49b8c25dd11 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -640,6 +640,131 @@ void tipc_bearer_stop(void) } } +/* Caller should hold rtnl_lock to protect the bearer */ +int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, struct tipc_bearer *bearer) +{ + void *hdr; + struct nlattr *attrs; + struct nlattr *prop; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_BEARER_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_BEARER); + if (!attrs) + goto msg_full; + + if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name)) + goto attr_msg_full; + + prop = nla_nest_start(msg->skb, TIPC_NLA_BEARER_PROP); + if (!prop) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window)) + goto prop_msg_full; + + nla_nest_end(msg->skb, prop); + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +prop_msg_full: + nla_nest_cancel(msg->skb, prop); +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + int i = cb->args[0]; + struct tipc_bearer *bearer; + struct tipc_nl_msg msg; + + if (i == MAX_BEARERS) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + rtnl_lock(); + for (i = 0; i < MAX_BEARERS; i++) { + bearer = rtnl_dereference(bearer_list[i]); + if (!bearer) + continue; + + err = __tipc_nl_add_bearer(&msg, bearer); + if (err) + break; + } + rtnl_unlock(); + + cb->args[0] = i; + return skb->len; +} + +int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *name; + struct sk_buff *rep; + struct tipc_bearer *bearer; + struct tipc_nl_msg msg; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + + if (!info->attrs[TIPC_NLA_BEARER]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, + info->attrs[TIPC_NLA_BEARER], + tipc_nl_bearer_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_BEARER_NAME]) + return -EINVAL; + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!rep) + return -ENOMEM; + + msg.skb = rep; + msg.portid = info->snd_portid; + msg.seq = info->snd_seq; + + rtnl_lock(); + bearer = tipc_bearer_find(name); + if (!bearer) { + err = -EINVAL; + goto err_out; + } + + err = __tipc_nl_add_bearer(&msg, bearer); + if (err) + goto err_out; + rtnl_unlock(); + + return genlmsg_reply(rep, info); +err_out: + rtnl_unlock(); + nlmsg_free(rep); + + return err; +} + int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) { int err; diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index a87e8c78d862..2d07e35f91fc 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -180,6 +180,8 @@ extern struct tipc_media ib_media_info; int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); +int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index af506ae0a129..0c00422512fa 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -112,6 +112,12 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_BEARER_ENABLE, .doit = tipc_nl_bearer_enable, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_BEARER_GET, + .doit = tipc_nl_bearer_get, + .dumpit = tipc_nl_bearer_dump, + .policy = tipc_nl_policy, } }; diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h index e9980c0e2207..e34a3fca7d3d 100644 --- a/net/tipc/netlink.h +++ b/net/tipc/netlink.h @@ -38,4 +38,10 @@ extern struct genl_family tipc_genl_v2_family; +struct tipc_nl_msg { + struct sk_buff *skb; + u32 portid; + u32 seq; +}; + #endif -- GitLab From 315c00bc9f2bd17f7ad7ed8119ca49b1125af507 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:09 +0100 Subject: [PATCH 5775/9457] tipc: add bearer set to new netlink api Add TIPC_NL_BEARER_SET command to the new tipc netlink API. This command can set one or more link properties for a particular bearer. Netlink logical layout of bearer set message: -> bearer -> name -> link properties [ -> tolerance ] [ -> priority ] [ -> window ] Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 1 + net/tipc/bearer.c | 49 +++++++++++++++++++++++++++++++ net/tipc/bearer.h | 1 + net/tipc/netlink.c | 5 ++++ 4 files changed, 56 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 249ec7e9952c..f446fba6a0c7 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -44,6 +44,7 @@ enum { TIPC_NL_BEARER_DISABLE, TIPC_NL_BEARER_ENABLE, TIPC_NL_BEARER_GET, + TIPC_NL_BEARER_SET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index d49b8c25dd11..6d547d0b3f31 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -849,3 +849,52 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) return 0; } + +int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *name; + struct tipc_bearer *b; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + + if (!info->attrs[TIPC_NLA_BEARER]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, + info->attrs[TIPC_NLA_BEARER], + tipc_nl_bearer_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_BEARER_NAME]) + return -EINVAL; + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + rtnl_lock(); + b = tipc_bearer_find(name); + if (!b) { + rtnl_unlock(); + return -EINVAL; + } + + if (attrs[TIPC_NLA_BEARER_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + + err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP], + props); + if (err) { + rtnl_unlock(); + return err; + } + + if (props[TIPC_NLA_PROP_TOL]) + b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); + if (props[TIPC_NLA_PROP_PRIO]) + b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + if (props[TIPC_NLA_PROP_WIN]) + b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + } + rtnl_unlock(); + + return 0; +} diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 2d07e35f91fc..c6cf9df31375 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -182,6 +182,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 0c00422512fa..a5291314a210 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -118,6 +118,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .doit = tipc_nl_bearer_get, .dumpit = tipc_nl_bearer_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_BEARER_SET, + .doit = tipc_nl_bearer_set, + .policy = tipc_nl_policy, } }; -- GitLab From 34b78a127c4fd57cf3d5c64031693d10a8e0fae1 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:10 +0100 Subject: [PATCH 5776/9457] tipc: add sock dump to new netlink api Add TIPC_NL_SOCK_GET command to the new tipc netlink API. This command supports dumping of all available sockets with their associated connection or publication(s). It could be extended to reply with a single socket if the NLM_F_DUMP isn't set. The information about a socket includes reference, address, connection information / publication information. Netlink logical layout of response message: -> socket -> reference -> address [ -> connection -> node -> socket [ -> connected flag -> type -> instance ] ] [ -> publication flag ] Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 28 +++++++++ net/tipc/netlink.c | 7 +++ net/tipc/socket.c | 101 ++++++++++++++++++++++++++++++ net/tipc/socket.h | 2 + 4 files changed, 138 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index f446fba6a0c7..8c87e2490bc7 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -45,6 +45,7 @@ enum { TIPC_NL_BEARER_ENABLE, TIPC_NL_BEARER_GET, TIPC_NL_BEARER_SET, + TIPC_NL_SOCK_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -54,6 +55,7 @@ enum { enum { TIPC_NLA_UNSPEC, TIPC_NLA_BEARER, /* nest */ + TIPC_NLA_SOCK, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -70,6 +72,32 @@ enum { TIPC_NLA_BEARER_MAX = __TIPC_NLA_BEARER_MAX - 1 }; +/* Socket info */ +enum { + TIPC_NLA_SOCK_UNSPEC, + TIPC_NLA_SOCK_ADDR, /* u32 */ + TIPC_NLA_SOCK_REF, /* u32 */ + TIPC_NLA_SOCK_CON, /* nest */ + TIPC_NLA_SOCK_HAS_PUBL, /* flag */ + + __TIPC_NLA_SOCK_MAX, + TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1 +}; + +/* Nest, connection info */ +enum { + TIPC_NLA_CON_UNSPEC, + + TIPC_NLA_CON_FLAG, /* flag */ + TIPC_NLA_CON_NODE, /* u32 */ + TIPC_NLA_CON_SOCK, /* u32 */ + TIPC_NLA_CON_TYPE, /* u32 */ + TIPC_NLA_CON_INST, /* u32 */ + + __TIPC_NLA_CON_MAX, + TIPC_NLA_CON_MAX = __TIPC_NLA_CON_MAX - 1 +}; + /* Nest, link propreties. Valid for link, media and bearer */ enum { TIPC_NLA_PROP_UNSPEC, diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index a5291314a210..951fabeec8b7 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -36,6 +36,7 @@ #include "core.h" #include "config.h" +#include "socket.h" #include "bearer.h" #include @@ -72,6 +73,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, + [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, }; /* Legacy ASCII API */ @@ -123,6 +125,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_BEARER_SET, .doit = tipc_nl_bearer_set, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_SOCK_GET, + .dumpit = tipc_nl_sk_dump, + .policy = tipc_nl_policy, } }; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 591bbfa082a0..9e95c1ea5564 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2801,3 +2801,104 @@ void tipc_socket_stop(void) sock_unregister(tipc_family_ops.family); proto_unregister(&tipc_proto); } + +/* Caller should hold socket lock for the passed tipc socket. */ +int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk) +{ + u32 peer_node; + u32 peer_port; + struct nlattr *nest; + + peer_node = tsk_peer_node(tsk); + peer_port = tsk_peer_port(tsk); + + nest = nla_nest_start(skb, TIPC_NLA_SOCK_CON); + + if (nla_put_u32(skb, TIPC_NLA_CON_NODE, peer_node)) + goto msg_full; + if (nla_put_u32(skb, TIPC_NLA_CON_SOCK, peer_port)) + goto msg_full; + + if (tsk->conn_type != 0) { + if (nla_put_flag(skb, TIPC_NLA_CON_FLAG)) + goto msg_full; + if (nla_put_u32(skb, TIPC_NLA_CON_TYPE, tsk->conn_type)) + goto msg_full; + if (nla_put_u32(skb, TIPC_NLA_CON_INST, tsk->conn_instance)) + goto msg_full; + } + nla_nest_end(skb, nest); + + return 0; + +msg_full: + nla_nest_cancel(skb, nest); + + return -EMSGSIZE; +} + +/* Caller should hold socket lock for the passed tipc socket. */ +int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, + struct tipc_sock *tsk) +{ + int err; + void *hdr; + struct nlattr *attrs; + + hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, + &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); + if (!hdr) + goto msg_cancel; + + attrs = nla_nest_start(skb, TIPC_NLA_SOCK); + if (!attrs) + goto genlmsg_cancel; + if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->ref)) + goto attr_msg_cancel; + if (nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr)) + goto attr_msg_cancel; + + if (tsk->connected) { + err = __tipc_nl_add_sk_con(skb, tsk); + if (err) + goto attr_msg_cancel; + } else if (!list_empty(&tsk->publications)) { + if (nla_put_flag(skb, TIPC_NLA_SOCK_HAS_PUBL)) + goto attr_msg_cancel; + } + nla_nest_end(skb, attrs); + genlmsg_end(skb, hdr); + + return 0; + +attr_msg_cancel: + nla_nest_cancel(skb, attrs); +genlmsg_cancel: + genlmsg_cancel(skb, hdr); +msg_cancel: + return -EMSGSIZE; +} + +int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + struct tipc_sock *tsk; + u32 prev_ref = cb->args[0]; + u32 ref = prev_ref; + + tsk = tipc_sk_get_next(&ref); + for (; tsk; tsk = tipc_sk_get_next(&ref)) { + lock_sock(&tsk->sk); + err = __tipc_nl_add_sk(skb, cb, tsk); + release_sock(&tsk->sk); + tipc_sk_put(tsk); + if (err) + break; + + prev_ref = ref; + } + + cb->args[0] = prev_ref; + + return skb->len; +} diff --git a/net/tipc/socket.h b/net/tipc/socket.h index baa43d03901e..16dfd62983a8 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -36,6 +36,7 @@ #define _TIPC_SOCK_H #include +#include #define TIPC_CONNACK_INTV 256 #define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2) @@ -47,5 +48,6 @@ void tipc_sk_mcast_rcv(struct sk_buff *buf); void tipc_sk_reinit(void); int tipc_sk_ref_table_init(u32 requested_size, u32 start); void tipc_sk_ref_table_stop(void); +int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb); #endif -- GitLab From 1a1a143daf84db95dd7212086042004a3abb7bc2 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:11 +0100 Subject: [PATCH 5777/9457] tipc: add publication dump to new netlink api Add TIPC_NL_PUBL_GET command to the new tipc netlink API. This command supports dumping of all publications for a specific socket. Netlink logical layout of request message: -> socket -> reference Netlink logical layout of response message: -> publication -> type -> lower -> upper Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 18 ++++ net/tipc/netlink.c | 17 ++++ net/tipc/netlink.h | 1 + net/tipc/socket.c | 135 ++++++++++++++++++++++++++++++ net/tipc/socket.h | 1 + 5 files changed, 172 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 8c87e2490bc7..7e51ff61dccd 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -46,6 +46,7 @@ enum { TIPC_NL_BEARER_GET, TIPC_NL_BEARER_SET, TIPC_NL_SOCK_GET, + TIPC_NL_PUBL_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -56,6 +57,7 @@ enum { TIPC_NLA_UNSPEC, TIPC_NLA_BEARER, /* nest */ TIPC_NLA_SOCK, /* nest */ + TIPC_NLA_PUBL, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -84,6 +86,22 @@ enum { TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1 }; +/* Publication info */ +enum { + TIPC_NLA_PUBL_UNSPEC, + + TIPC_NLA_PUBL_TYPE, /* u32 */ + TIPC_NLA_PUBL_LOWER, /* u32 */ + TIPC_NLA_PUBL_UPPER, /* u32 */ + TIPC_NLA_PUBL_SCOPE, /* u32 */ + TIPC_NLA_PUBL_NODE, /* u32 */ + TIPC_NLA_PUBL_REF, /* u32 */ + TIPC_NLA_PUBL_KEY, /* u32 */ + + __TIPC_NLA_PUBL_MAX, + TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1 +}; + /* Nest, connection info */ enum { TIPC_NLA_CON_UNSPEC, diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 951fabeec8b7..9bc64aaff466 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -74,6 +74,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, + [TIPC_NLA_PUBL] = { .type = NLA_NESTED, } }; /* Legacy ASCII API */ @@ -130,9 +131,25 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_SOCK_GET, .dumpit = tipc_nl_sk_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_PUBL_GET, + .dumpit = tipc_nl_publ_dump, + .policy = tipc_nl_policy, } }; +int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) +{ + u32 maxattr = tipc_genl_v2_family.maxattr; + + *attr = tipc_genl_v2_family.attrbuf; + if (!*attr) + return -EOPNOTSUPP; + + return nlmsg_parse(nlh, GENL_HDRLEN, *attr, maxattr, tipc_nl_policy); +} + int tipc_netlink_start(void) { int res; diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h index e34a3fca7d3d..1425c6869de0 100644 --- a/net/tipc/netlink.h +++ b/net/tipc/netlink.h @@ -37,6 +37,7 @@ #define _TIPC_NETLINK_H extern struct genl_family tipc_genl_v2_family; +int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); struct tipc_nl_msg { struct sk_buff *skb; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 9e95c1ea5564..e91809182c28 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -121,6 +121,14 @@ static const struct proto_ops msg_ops; static struct proto tipc_proto; static struct proto tipc_proto_kern; +static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { + [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 }, + [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 }, + [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED }, + [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } +}; + /* * Revised TIPC socket locking policy: * @@ -2902,3 +2910,130 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } + +/* Caller should hold socket lock for the passed tipc socket. */ +int __tipc_nl_add_sk_publ(struct sk_buff *skb, struct netlink_callback *cb, + struct publication *publ) +{ + void *hdr; + struct nlattr *attrs; + + hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, + &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); + if (!hdr) + goto msg_cancel; + + attrs = nla_nest_start(skb, TIPC_NLA_PUBL); + if (!attrs) + goto genlmsg_cancel; + + if (nla_put_u32(skb, TIPC_NLA_PUBL_KEY, publ->key)) + goto attr_msg_cancel; + if (nla_put_u32(skb, TIPC_NLA_PUBL_TYPE, publ->type)) + goto attr_msg_cancel; + if (nla_put_u32(skb, TIPC_NLA_PUBL_LOWER, publ->lower)) + goto attr_msg_cancel; + if (nla_put_u32(skb, TIPC_NLA_PUBL_UPPER, publ->upper)) + goto attr_msg_cancel; + + nla_nest_end(skb, attrs); + genlmsg_end(skb, hdr); + + return 0; + +attr_msg_cancel: + nla_nest_cancel(skb, attrs); +genlmsg_cancel: + genlmsg_cancel(skb, hdr); +msg_cancel: + return -EMSGSIZE; +} + +/* Caller should hold socket lock for the passed tipc socket. */ +int __tipc_nl_list_sk_publ(struct sk_buff *skb, struct netlink_callback *cb, + struct tipc_sock *tsk, u32 *last_publ) +{ + int err; + struct publication *p; + + if (*last_publ) { + list_for_each_entry(p, &tsk->publications, pport_list) { + if (p->key == *last_publ) + break; + } + if (p->key != *last_publ) { + /* We never set seq or call nl_dump_check_consistent() + * this means that setting prev_seq here will cause the + * consistence check to fail in the netlink callback + * handler. Resulting in the last NLMSG_DONE message + * having the NLM_F_DUMP_INTR flag set. + */ + cb->prev_seq = 1; + *last_publ = 0; + return -EPIPE; + } + } else { + p = list_first_entry(&tsk->publications, struct publication, + pport_list); + } + + list_for_each_entry_from(p, &tsk->publications, pport_list) { + err = __tipc_nl_add_sk_publ(skb, cb, p); + if (err) { + *last_publ = p->key; + return err; + } + } + *last_publ = 0; + + return 0; +} + +int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + u32 tsk_ref = cb->args[0]; + u32 last_publ = cb->args[1]; + u32 done = cb->args[2]; + struct tipc_sock *tsk; + + if (!tsk_ref) { + struct nlattr **attrs; + struct nlattr *sock[TIPC_NLA_SOCK_MAX + 1]; + + err = tipc_nlmsg_parse(cb->nlh, &attrs); + if (err) + return err; + + err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, + attrs[TIPC_NLA_SOCK], + tipc_nl_sock_policy); + if (err) + return err; + + if (!sock[TIPC_NLA_SOCK_REF]) + return -EINVAL; + + tsk_ref = nla_get_u32(sock[TIPC_NLA_SOCK_REF]); + } + + if (done) + return 0; + + tsk = tipc_sk_get(tsk_ref); + if (!tsk) + return -EINVAL; + + lock_sock(&tsk->sk); + err = __tipc_nl_list_sk_publ(skb, cb, tsk, &last_publ); + if (!err) + done = 1; + release_sock(&tsk->sk); + tipc_sk_put(tsk); + + cb->args[0] = tsk_ref; + cb->args[1] = last_publ; + cb->args[2] = done; + + return skb->len; +} diff --git a/net/tipc/socket.h b/net/tipc/socket.h index 16dfd62983a8..d34089387006 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h @@ -49,5 +49,6 @@ void tipc_sk_reinit(void); int tipc_sk_ref_table_init(u32 requested_size, u32 start); void tipc_sk_ref_table_stop(void); int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb); +int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb); #endif -- GitLab From 7be57fc6918470ecacd16b89c0d4f73d8fc265c4 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:12 +0100 Subject: [PATCH 5778/9457] tipc: add link get/dump to new netlink api Add TIPC_NL_LINK_GET command to the new tipc netlink API. This command supports dumping all information about all links (including the broadcast link) or getting all information about a specific link (not the broadcast link). The information about a link includes name, transmission info, properties and link statistics. As the tipc broadcast link is special we unfortunately have to treat it specially. It is a deliberate decision not to abstract the broadcast link on this (API) level. Netlink logical layout of link response message: -> port -> name -> MTU -> RX -> TX -> up flag -> active flag -> properties -> priority -> tolerance -> window -> statistics -> rx_info -> rx_fragments -> rx_fragmented -> rx_bundles -> rx_bundled -> tx_info -> tx_fragments -> tx_fragmented -> tx_bundles -> tx_bundled -> msg_prof_tot -> msg_len_cnt -> msg_len_tot -> msg_len_p0 -> msg_len_p1 -> msg_len_p2 -> msg_len_p3 -> msg_len_p4 -> msg_len_p5 -> msg_len_p6 -> rx_states -> rx_probes -> rx_nacks -> rx_deferred -> tx_states -> tx_probes -> tx_nacks -> tx_acks -> retransmitted -> duplicates -> link_congs -> max_queue -> avg_queue Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 62 +++++++ net/tipc/bcast.c | 111 ++++++++++++ net/tipc/bcast.h | 4 + net/tipc/link.c | 287 ++++++++++++++++++++++++++++++ net/tipc/link.h | 2 + net/tipc/netlink.c | 10 +- 6 files changed, 475 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 7e51ff61dccd..1034fb43d32e 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -47,6 +47,7 @@ enum { TIPC_NL_BEARER_SET, TIPC_NL_SOCK_GET, TIPC_NL_PUBL_GET, + TIPC_NL_LINK_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -58,6 +59,7 @@ enum { TIPC_NLA_BEARER, /* nest */ TIPC_NLA_SOCK, /* nest */ TIPC_NLA_PUBL, /* nest */ + TIPC_NLA_LINK, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -86,6 +88,24 @@ enum { TIPC_NLA_SOCK_MAX = __TIPC_NLA_SOCK_MAX - 1 }; +/* Link info */ +enum { + TIPC_NLA_LINK_UNSPEC, + TIPC_NLA_LINK_NAME, /* string */ + TIPC_NLA_LINK_DEST, /* u32 */ + TIPC_NLA_LINK_MTU, /* u32 */ + TIPC_NLA_LINK_BROADCAST, /* flag */ + TIPC_NLA_LINK_UP, /* flag */ + TIPC_NLA_LINK_ACTIVE, /* flag */ + TIPC_NLA_LINK_PROP, /* nest */ + TIPC_NLA_LINK_STATS, /* nest */ + TIPC_NLA_LINK_RX, /* u32 */ + TIPC_NLA_LINK_TX, /* u32 */ + + __TIPC_NLA_LINK_MAX, + TIPC_NLA_LINK_MAX = __TIPC_NLA_LINK_MAX - 1 +}; + /* Publication info */ enum { TIPC_NLA_PUBL_UNSPEC, @@ -128,4 +148,46 @@ enum { TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1 }; +/* Nest, statistics info */ +enum { + TIPC_NLA_STATS_UNSPEC, + + TIPC_NLA_STATS_RX_INFO, /* u32 */ + TIPC_NLA_STATS_RX_FRAGMENTS, /* u32 */ + TIPC_NLA_STATS_RX_FRAGMENTED, /* u32 */ + TIPC_NLA_STATS_RX_BUNDLES, /* u32 */ + TIPC_NLA_STATS_RX_BUNDLED, /* u32 */ + TIPC_NLA_STATS_TX_INFO, /* u32 */ + TIPC_NLA_STATS_TX_FRAGMENTS, /* u32 */ + TIPC_NLA_STATS_TX_FRAGMENTED, /* u32 */ + TIPC_NLA_STATS_TX_BUNDLES, /* u32 */ + TIPC_NLA_STATS_TX_BUNDLED, /* u32 */ + TIPC_NLA_STATS_MSG_PROF_TOT, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_CNT, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_TOT, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P0, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P1, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P2, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P3, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P4, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P5, /* u32 */ + TIPC_NLA_STATS_MSG_LEN_P6, /* u32 */ + TIPC_NLA_STATS_RX_STATES, /* u32 */ + TIPC_NLA_STATS_RX_PROBES, /* u32 */ + TIPC_NLA_STATS_RX_NACKS, /* u32 */ + TIPC_NLA_STATS_RX_DEFERRED, /* u32 */ + TIPC_NLA_STATS_TX_STATES, /* u32 */ + TIPC_NLA_STATS_TX_PROBES, /* u32 */ + TIPC_NLA_STATS_TX_NACKS, /* u32 */ + TIPC_NLA_STATS_TX_ACKS, /* u32 */ + TIPC_NLA_STATS_RETRANSMITTED, /* u32 */ + TIPC_NLA_STATS_DUPLICATES, /* u32 */ + TIPC_NLA_STATS_LINK_CONGS, /* u32 */ + TIPC_NLA_STATS_MAX_QUEUE, /* u32 */ + TIPC_NLA_STATS_AVG_QUEUE, /* u32 */ + + __TIPC_NLA_STATS_MAX, + TIPC_NLA_STATS_MAX = __TIPC_NLA_STATS_MAX - 1 +}; + #endif diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index b8670bf262e2..dcf3589e3cc5 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -767,6 +767,117 @@ void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action) tipc_bclink_unlock(); } +int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, struct tipc_stats *stats) +{ + int i; + struct nlattr *nest; + + struct nla_map { + __u32 key; + __u32 val; + }; + + struct nla_map map[] = { + {TIPC_NLA_STATS_RX_INFO, stats->recv_info}, + {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments}, + {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented}, + {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles}, + {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled}, + {TIPC_NLA_STATS_TX_INFO, stats->sent_info}, + {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments}, + {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented}, + {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles}, + {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled}, + {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks}, + {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv}, + {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks}, + {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks}, + {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted}, + {TIPC_NLA_STATS_DUPLICATES, stats->duplicates}, + {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs}, + {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz}, + {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ? + (stats->accu_queue_sz / stats->queue_sz_counts) : 0} + }; + + nest = nla_nest_start(skb, TIPC_NLA_LINK_STATS); + if (!nest) + return -EMSGSIZE; + + for (i = 0; i < ARRAY_SIZE(map); i++) + if (nla_put_u32(skb, map[i].key, map[i].val)) + goto msg_full; + + nla_nest_end(skb, nest); + + return 0; +msg_full: + nla_nest_cancel(skb, nest); + + return -EMSGSIZE; +} + +int tipc_nl_add_bc_link(struct tipc_nl_msg *msg) +{ + int err; + void *hdr; + struct nlattr *attrs; + struct nlattr *prop; + + if (!bcl) + return 0; + + tipc_bclink_lock(); + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_LINK_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK); + if (!attrs) + goto msg_full; + + /* The broadcast link is always up */ + if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP)) + goto attr_msg_full; + + if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST)) + goto attr_msg_full; + if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name)) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->next_in_no)) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->next_out_no)) + goto attr_msg_full; + + prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); + if (!prop) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->queue_limit[0])) + goto prop_msg_full; + nla_nest_end(msg->skb, prop); + + err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats); + if (err) + goto attr_msg_full; + + tipc_bclink_unlock(); + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +prop_msg_full: + nla_nest_cancel(msg->skb, prop); +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + tipc_bclink_unlock(); + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} int tipc_bclink_stats(char *buf, const u32 buf_size) { diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index e7b0f85a82bc..443de084d3e8 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -37,6 +37,8 @@ #ifndef _TIPC_BCAST_H #define _TIPC_BCAST_H +#include "netlink.h" + #define MAX_NODES 4096 #define WSIZE 32 #define TIPC_BCLINK_RESET 1 @@ -100,4 +102,6 @@ void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action); uint tipc_bclink_get_mtu(void); int tipc_bclink_xmit(struct sk_buff *buf); void tipc_bclink_wakeup_users(void); +int tipc_nl_add_bc_link(struct tipc_nl_msg *msg); + #endif diff --git a/net/tipc/link.c b/net/tipc/link.c index e7f365012bd1..bdc4b5e5bf56 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -36,6 +36,7 @@ #include "core.h" #include "link.h" +#include "bcast.h" #include "socket.h" #include "name_distr.h" #include "discover.h" @@ -51,6 +52,22 @@ static const char *link_co_err = "Link changeover error, "; static const char *link_rst_msg = "Resetting link "; static const char *link_unk_evt = "Unknown link event "; +static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { + [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_LINK_NAME] = { + .type = NLA_STRING, + .len = TIPC_MAX_LINK_NAME + }, + [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, + [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, + [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG }, + [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG }, + [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED }, + [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED }, + [TIPC_NLA_LINK_RX] = { .type = NLA_U32 }, + [TIPC_NLA_LINK_TX] = { .type = NLA_U32 } +}; + /* Properties valid for media, bearar and link */ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC }, @@ -2423,3 +2440,273 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]) return 0; } + +int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) +{ + int i; + struct nlattr *stats; + + struct nla_map { + u32 key; + u32 val; + }; + + struct nla_map map[] = { + {TIPC_NLA_STATS_RX_INFO, s->recv_info}, + {TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments}, + {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented}, + {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles}, + {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled}, + {TIPC_NLA_STATS_TX_INFO, s->sent_info}, + {TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments}, + {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented}, + {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles}, + {TIPC_NLA_STATS_TX_BUNDLED, s->sent_bundled}, + {TIPC_NLA_STATS_MSG_PROF_TOT, (s->msg_length_counts) ? + s->msg_length_counts : 1}, + {TIPC_NLA_STATS_MSG_LEN_CNT, s->msg_length_counts}, + {TIPC_NLA_STATS_MSG_LEN_TOT, s->msg_lengths_total}, + {TIPC_NLA_STATS_MSG_LEN_P0, s->msg_length_profile[0]}, + {TIPC_NLA_STATS_MSG_LEN_P1, s->msg_length_profile[1]}, + {TIPC_NLA_STATS_MSG_LEN_P2, s->msg_length_profile[2]}, + {TIPC_NLA_STATS_MSG_LEN_P3, s->msg_length_profile[3]}, + {TIPC_NLA_STATS_MSG_LEN_P4, s->msg_length_profile[4]}, + {TIPC_NLA_STATS_MSG_LEN_P5, s->msg_length_profile[5]}, + {TIPC_NLA_STATS_MSG_LEN_P6, s->msg_length_profile[6]}, + {TIPC_NLA_STATS_RX_STATES, s->recv_states}, + {TIPC_NLA_STATS_RX_PROBES, s->recv_probes}, + {TIPC_NLA_STATS_RX_NACKS, s->recv_nacks}, + {TIPC_NLA_STATS_RX_DEFERRED, s->deferred_recv}, + {TIPC_NLA_STATS_TX_STATES, s->sent_states}, + {TIPC_NLA_STATS_TX_PROBES, s->sent_probes}, + {TIPC_NLA_STATS_TX_NACKS, s->sent_nacks}, + {TIPC_NLA_STATS_TX_ACKS, s->sent_acks}, + {TIPC_NLA_STATS_RETRANSMITTED, s->retransmitted}, + {TIPC_NLA_STATS_DUPLICATES, s->duplicates}, + {TIPC_NLA_STATS_LINK_CONGS, s->link_congs}, + {TIPC_NLA_STATS_MAX_QUEUE, s->max_queue_sz}, + {TIPC_NLA_STATS_AVG_QUEUE, s->queue_sz_counts ? + (s->accu_queue_sz / s->queue_sz_counts) : 0} + }; + + stats = nla_nest_start(skb, TIPC_NLA_LINK_STATS); + if (!stats) + return -EMSGSIZE; + + for (i = 0; i < ARRAY_SIZE(map); i++) + if (nla_put_u32(skb, map[i].key, map[i].val)) + goto msg_full; + + nla_nest_end(skb, stats); + + return 0; +msg_full: + nla_nest_cancel(skb, stats); + + return -EMSGSIZE; +} + +/* Caller should hold appropriate locks to protect the link */ +int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link) +{ + int err; + void *hdr; + struct nlattr *attrs; + struct nlattr *prop; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_LINK_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK); + if (!attrs) + goto msg_full; + + if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name)) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST, + tipc_cluster_mask(tipc_own_addr))) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->max_pkt)) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->next_in_no)) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->next_out_no)) + goto attr_msg_full; + + if (tipc_link_is_up(link)) + if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP)) + goto attr_msg_full; + if (tipc_link_is_active(link)) + if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE)) + goto attr_msg_full; + + prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); + if (!prop) + goto attr_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, + link->queue_limit[TIPC_LOW_IMPORTANCE])) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority)) + goto prop_msg_full; + nla_nest_end(msg->skb, prop); + + err = __tipc_nl_add_stats(msg->skb, &link->stats); + if (err) + goto attr_msg_full; + + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +prop_msg_full: + nla_nest_cancel(msg->skb, prop); +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +/* Caller should hold node lock */ +int __tipc_nl_add_node_links(struct tipc_nl_msg *msg, struct tipc_node *node, + u32 *prev_link) +{ + u32 i; + int err; + + for (i = *prev_link; i < MAX_BEARERS; i++) { + *prev_link = i; + + if (!node->links[i]) + continue; + + err = __tipc_nl_add_link(msg, node->links[i]); + if (err) + return err; + } + *prev_link = 0; + + return 0; +} + +int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct tipc_node *node; + struct tipc_nl_msg msg; + u32 prev_node = cb->args[0]; + u32 prev_link = cb->args[1]; + int done = cb->args[2]; + int err; + + if (done) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + rcu_read_lock(); + + if (prev_node) { + node = tipc_node_find(prev_node); + if (!node) { + /* We never set seq or call nl_dump_check_consistent() + * this means that setting prev_seq here will cause the + * consistence check to fail in the netlink callback + * handler. Resulting in the last NLMSG_DONE message + * having the NLM_F_DUMP_INTR flag set. + */ + cb->prev_seq = 1; + goto out; + } + + list_for_each_entry_continue_rcu(node, &tipc_node_list, list) { + tipc_node_lock(node); + err = __tipc_nl_add_node_links(&msg, node, &prev_link); + tipc_node_unlock(node); + if (err) + goto out; + + prev_node = node->addr; + } + } else { + err = tipc_nl_add_bc_link(&msg); + if (err) + goto out; + + list_for_each_entry_rcu(node, &tipc_node_list, list) { + tipc_node_lock(node); + err = __tipc_nl_add_node_links(&msg, node, &prev_link); + tipc_node_unlock(node); + if (err) + goto out; + + prev_node = node->addr; + } + } + done = 1; +out: + rcu_read_unlock(); + + cb->args[0] = prev_node; + cb->args[1] = prev_link; + cb->args[2] = done; + + return skb->len; +} + +int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *ans_skb; + struct tipc_nl_msg msg; + struct tipc_link *link; + struct tipc_node *node; + char *name; + int bearer_id; + int err; + + if (!info->attrs[TIPC_NLA_LINK_NAME]) + return -EINVAL; + + name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]); + node = tipc_link_find_owner(name, &bearer_id); + if (!node) + return -EINVAL; + + ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!ans_skb) + return -ENOMEM; + + msg.skb = ans_skb; + msg.portid = info->snd_portid; + msg.seq = info->snd_seq; + + tipc_node_lock(node); + link = node->links[bearer_id]; + if (!link) { + err = -EINVAL; + goto err_out; + } + + err = __tipc_nl_add_link(&msg, link); + if (err) + goto err_out; + + tipc_node_unlock(node); + + return genlmsg_reply(ans_skb, info); + +err_out: + tipc_node_unlock(node); + nlmsg_free(ans_skb); + + return err; +} diff --git a/net/tipc/link.h b/net/tipc/link.h index 4338294f20d4..8e3542a4a037 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -240,6 +240,8 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *start, u32 retransmits); +int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb); +int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info); int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); /* diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 9bc64aaff466..ea168b889caa 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -38,6 +38,7 @@ #include "config.h" #include "socket.h" #include "bearer.h" +#include "link.h" #include static int handle_cmd(struct sk_buff *skb, struct genl_info *info) @@ -74,7 +75,8 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, - [TIPC_NLA_PUBL] = { .type = NLA_NESTED, } + [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, + [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, }; /* Legacy ASCII API */ @@ -136,6 +138,12 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_PUBL_GET, .dumpit = tipc_nl_publ_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_LINK_GET, + .doit = tipc_nl_link_get, + .dumpit = tipc_nl_link_dump, + .policy = tipc_nl_policy, } }; -- GitLab From f96ce7a20d6972a834202f3cdd6a53fd0ee26a8e Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:13 +0100 Subject: [PATCH 5779/9457] tipc: add link set to new netlink api Add TIPC_NL_LINK_SET to the new tipc netlink API. This command can set one or more link properties for a particular link. Netlink logical layout of link set message: -> link -> name -> properties [ -> tolerance ] [ -> priority ] [ -> window ] Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 1 + net/tipc/link.c | 73 +++++++++++++++++++++++++++++++ net/tipc/link.h | 1 + net/tipc/netlink.c | 5 +++ 4 files changed, 80 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 1034fb43d32e..2deb7fd8d85d 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -48,6 +48,7 @@ enum { TIPC_NL_SOCK_GET, TIPC_NL_PUBL_GET, TIPC_NL_LINK_GET, + TIPC_NL_LINK_SET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 diff --git a/net/tipc/link.c b/net/tipc/link.c index bdc4b5e5bf56..6785dcfd2d23 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2441,6 +2441,79 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]) return 0; } +int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) +{ + int err; + int res = 0; + int bearer_id; + char *name; + struct tipc_link *link; + struct tipc_node *node; + struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; + + if (!info->attrs[TIPC_NLA_LINK]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX, + info->attrs[TIPC_NLA_LINK], + tipc_nl_link_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_LINK_NAME]) + return -EINVAL; + + name = nla_data(attrs[TIPC_NLA_LINK_NAME]); + + node = tipc_link_find_owner(name, &bearer_id); + if (!node) + return -EINVAL; + + tipc_node_lock(node); + + link = node->links[bearer_id]; + if (!link) { + res = -EINVAL; + goto out; + } + + if (attrs[TIPC_NLA_LINK_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + + err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP], + props); + if (err) { + res = err; + goto out; + } + + if (props[TIPC_NLA_PROP_TOL]) { + u32 tol; + + tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); + link_set_supervision_props(link, tol); + tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0, 0); + } + if (props[TIPC_NLA_PROP_PRIO]) { + u32 prio; + + prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + link->priority = prio; + tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio, 0); + } + if (props[TIPC_NLA_PROP_WIN]) { + u32 win; + + win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + tipc_link_set_queue_limits(link, win); + } + } + +out: + tipc_node_unlock(node); + + return res; +} int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) { int i; diff --git a/net/tipc/link.h b/net/tipc/link.h index 8e3542a4a037..3738ba11ce00 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -242,6 +242,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info); int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); /* diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index ea168b889caa..d4444e59bf98 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -144,6 +144,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .doit = tipc_nl_link_get, .dumpit = tipc_nl_link_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_LINK_SET, + .doit = tipc_nl_link_set, + .policy = tipc_nl_policy, } }; -- GitLab From ae36342b50a91cff188e417201452dc075a8f444 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:14 +0100 Subject: [PATCH 5780/9457] tipc: add link stat reset to new netlink api Add TIPC_NL_LINK_RESET_STATS command to the new netlink API. This command resets the link statistics for a particular link. Netlink logical layout of link reset message: -> link -> name Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 1 + net/tipc/link.c | 49 +++++++++++++++++++++++++++++++ net/tipc/link.h | 1 + net/tipc/netlink.c | 5 ++++ 4 files changed, 56 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 2deb7fd8d85d..574882a301bf 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -49,6 +49,7 @@ enum { TIPC_NL_PUBL_GET, TIPC_NL_LINK_GET, TIPC_NL_LINK_SET, + TIPC_NL_LINK_RESET_STATS, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 diff --git a/net/tipc/link.c b/net/tipc/link.c index 6785dcfd2d23..629e8cf393bf 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2783,3 +2783,52 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info) return err; } + +int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *link_name; + unsigned int bearer_id; + struct tipc_link *link; + struct tipc_node *node; + struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; + + if (!info->attrs[TIPC_NLA_LINK]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX, + info->attrs[TIPC_NLA_LINK], + tipc_nl_link_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_LINK_NAME]) + return -EINVAL; + + link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]); + + if (strcmp(link_name, tipc_bclink_name) == 0) { + err = tipc_bclink_reset_stats(); + if (err) + return err; + return 0; + } + + node = tipc_link_find_owner(link_name, &bearer_id); + if (!node) + return -EINVAL; + + tipc_node_lock(node); + + link = node->links[bearer_id]; + if (!link) { + tipc_node_unlock(node); + return -EINVAL; + } + + link_reset_statistics(link); + + tipc_node_unlock(node); + + return 0; +} diff --git a/net/tipc/link.h b/net/tipc/link.h index 3738ba11ce00..f463e7be801c 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -243,6 +243,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info); int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info); int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); /* diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index d4444e59bf98..68bfd11f232d 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -149,6 +149,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_LINK_SET, .doit = tipc_nl_link_set, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_LINK_RESET_STATS, + .doit = tipc_nl_link_reset_stats, + .policy = tipc_nl_policy, } }; -- GitLab From 46f15c6794fb744bb7741d26143a85b9012c10d4 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:15 +0100 Subject: [PATCH 5781/9457] tipc: add media get/dump to new netlink api Add TIPC_NL_MEDIA_GET command to the new tipc netlink API. This command supports dumping all information about all defined media as well as getting all information about a specific media. The information about a media includes name and link properties. Netlink logical layout of media get response message: -> media -> name -> link properties -> tolerance -> priority -> window Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 12 +++ net/tipc/bearer.c | 125 ++++++++++++++++++++++++++++++ net/tipc/bearer.h | 3 + net/tipc/netlink.c | 7 ++ 4 files changed, 147 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 574882a301bf..4101b70991cc 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -50,6 +50,7 @@ enum { TIPC_NL_LINK_GET, TIPC_NL_LINK_SET, TIPC_NL_LINK_RESET_STATS, + TIPC_NL_MEDIA_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -62,6 +63,7 @@ enum { TIPC_NLA_SOCK, /* nest */ TIPC_NLA_PUBL, /* nest */ TIPC_NLA_LINK, /* nest */ + TIPC_NLA_MEDIA, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -108,6 +110,16 @@ enum { TIPC_NLA_LINK_MAX = __TIPC_NLA_LINK_MAX - 1 }; +/* Media info */ +enum { + TIPC_NLA_MEDIA_UNSPEC, + TIPC_NLA_MEDIA_NAME, /* string */ + TIPC_NLA_MEDIA_PROP, /* nest */ + + __TIPC_NLA_MEDIA_MAX, + TIPC_NLA_MEDIA_MAX = __TIPC_NLA_MEDIA_MAX - 1 +}; + /* Publication info */ enum { TIPC_NLA_PUBL_UNSPEC, diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 6d547d0b3f31..26630a51fcae 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -61,6 +61,12 @@ tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } }; +static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = { + [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING }, + [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED } +}; + struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1]; static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down); @@ -898,3 +904,122 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) return 0; } + +int __tipc_nl_add_media(struct tipc_nl_msg *msg, struct tipc_media *media) +{ + void *hdr; + struct nlattr *attrs; + struct nlattr *prop; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_MEDIA_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_MEDIA); + if (!attrs) + goto msg_full; + + if (nla_put_string(msg->skb, TIPC_NLA_MEDIA_NAME, media->name)) + goto attr_msg_full; + + prop = nla_nest_start(msg->skb, TIPC_NLA_MEDIA_PROP); + if (!prop) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, media->priority)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, media->tolerance)) + goto prop_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->window)) + goto prop_msg_full; + + nla_nest_end(msg->skb, prop); + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +prop_msg_full: + nla_nest_cancel(msg->skb, prop); +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + int i = cb->args[0]; + struct tipc_nl_msg msg; + + if (i == MAX_MEDIA) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + rtnl_lock(); + for (; media_info_array[i] != NULL; i++) { + err = __tipc_nl_add_media(&msg, media_info_array[i]); + if (err) + break; + } + rtnl_unlock(); + + cb->args[0] = i; + return skb->len; +} + +int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *name; + struct tipc_nl_msg msg; + struct tipc_media *media; + struct sk_buff *rep; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + + if (!info->attrs[TIPC_NLA_MEDIA]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX, + info->attrs[TIPC_NLA_MEDIA], + tipc_nl_media_policy); + if (err) + return err; + + if (!attrs[TIPC_NLA_MEDIA_NAME]) + return -EINVAL; + name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); + + rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!rep) + return -ENOMEM; + + msg.skb = rep; + msg.portid = info->snd_portid; + msg.seq = info->snd_seq; + + rtnl_lock(); + media = tipc_media_find(name); + if (!media) { + err = -EINVAL; + goto err_out; + } + + err = __tipc_nl_add_media(&msg, media); + if (err) + goto err_out; + rtnl_unlock(); + + return genlmsg_reply(rep, info); +err_out: + rtnl_unlock(); + nlmsg_free(rep); + + return err; +} diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index c6cf9df31375..bacd225bccfb 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -184,6 +184,9 @@ int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb); +int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info); + int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 68bfd11f232d..742e51a0afbb 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -77,6 +77,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, + [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, }; /* Legacy ASCII API */ @@ -154,6 +155,12 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_LINK_RESET_STATS, .doit = tipc_nl_link_reset_stats, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_MEDIA_GET, + .doit = tipc_nl_media_get, + .dumpit = tipc_nl_media_dump, + .policy = tipc_nl_policy, } }; -- GitLab From 1e55417d8fc6f6d93b1cc6995b911d48ded2adfb Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:16 +0100 Subject: [PATCH 5782/9457] tipc: add media set to new netlink api Add TIPC_NL_MEDIA_SET command to the new tipc netlink API. This command can set one or more link properties for a particular media. Netlink logical layout of bearer set message: -> media -> name -> link properties [ -> tolerance ] [ -> priority ] [ -> window ] Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 1 + net/tipc/bearer.c | 47 +++++++++++++++++++++++++++++++ net/tipc/bearer.h | 1 + net/tipc/netlink.c | 5 ++++ 4 files changed, 54 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 4101b70991cc..43beef28d67f 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -51,6 +51,7 @@ enum { TIPC_NL_LINK_SET, TIPC_NL_LINK_RESET_STATS, TIPC_NL_MEDIA_GET, + TIPC_NL_MEDIA_SET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 26630a51fcae..5f6f32369c16 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -1023,3 +1023,50 @@ int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info) return err; } + +int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) +{ + int err; + char *name; + struct tipc_media *m; + struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; + + if (!info->attrs[TIPC_NLA_MEDIA]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX, + info->attrs[TIPC_NLA_MEDIA], + tipc_nl_media_policy); + + if (!attrs[TIPC_NLA_MEDIA_NAME]) + return -EINVAL; + name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); + + rtnl_lock(); + m = tipc_media_find(name); + if (!m) { + rtnl_unlock(); + return -EINVAL; + } + + if (attrs[TIPC_NLA_MEDIA_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + + err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP], + props); + if (err) { + rtnl_unlock(); + return err; + } + + if (props[TIPC_NLA_PROP_TOL]) + m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]); + if (props[TIPC_NLA_PROP_PRIO]) + m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + if (props[TIPC_NLA_PROP_WIN]) + m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + } + rtnl_unlock(); + + return 0; +} diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index bacd225bccfb..b1d905209e83 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -186,6 +186,7 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info); int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info); +int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 742e51a0afbb..8673e370b7ed 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -161,6 +161,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .doit = tipc_nl_media_get, .dumpit = tipc_nl_media_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_MEDIA_SET, + .doit = tipc_nl_media_set, + .policy = tipc_nl_policy, } }; -- GitLab From 3e4b6ab58d614934e7ca99bdf448089695d34ffa Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:17 +0100 Subject: [PATCH 5783/9457] tipc: add node get/dump to new netlink api Add TIPC_NL_NODE_GET to the new tipc netlink API. This command can dump the address and node status of all nodes in the tipc cluster. Netlink logical layout of returned node/address data: -> node -> address -> up flag Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 12 ++++ net/tipc/netlink.c | 7 +++ net/tipc/node.c | 96 +++++++++++++++++++++++++++++++ net/tipc/node.h | 4 +- 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 43beef28d67f..08a793374e8c 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -52,6 +52,7 @@ enum { TIPC_NL_LINK_RESET_STATS, TIPC_NL_MEDIA_GET, TIPC_NL_MEDIA_SET, + TIPC_NL_NODE_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -65,6 +66,7 @@ enum { TIPC_NLA_PUBL, /* nest */ TIPC_NLA_LINK, /* nest */ TIPC_NLA_MEDIA, /* nest */ + TIPC_NLA_NODE, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -121,6 +123,16 @@ enum { TIPC_NLA_MEDIA_MAX = __TIPC_NLA_MEDIA_MAX - 1 }; +/* Node info */ +enum { + TIPC_NLA_NODE_UNSPEC, + TIPC_NLA_NODE_ADDR, /* u32 */ + TIPC_NLA_NODE_UP, /* flag */ + + __TIPC_NLA_NODE_MAX, + TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1 +}; + /* Publication info */ enum { TIPC_NLA_PUBL_UNSPEC, diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 8673e370b7ed..5b0e3c8457d2 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -39,6 +39,7 @@ #include "socket.h" #include "bearer.h" #include "link.h" +#include "node.h" #include static int handle_cmd(struct sk_buff *skb, struct genl_info *info) @@ -78,6 +79,7 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, + [TIPC_NLA_NODE] = { .type = NLA_NESTED, } }; /* Legacy ASCII API */ @@ -166,6 +168,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_MEDIA_SET, .doit = tipc_nl_media_set, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_NODE_GET, + .dumpit = tipc_nl_node_dump, + .policy = tipc_nl_policy, } }; diff --git a/net/tipc/node.c b/net/tipc/node.c index 5781634e957d..72a75d4838b2 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -58,6 +58,12 @@ struct tipc_sock_conn { struct list_head list; }; +static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { + [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, + [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } +}; + /* * A trivial power-of-two bitmask technique is used for speed, since this * operation is done for every incoming TIPC packet. The number of hash table @@ -601,3 +607,93 @@ void tipc_node_unlock(struct tipc_node *node) tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, link_id, addr); } + +/* Caller should hold node lock for the passed node */ +int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) +{ + void *hdr; + struct nlattr *attrs; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_NODE_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE); + if (!attrs) + goto msg_full; + + if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr)) + goto attr_msg_full; + if (tipc_node_is_up(node)) + if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP)) + goto attr_msg_full; + + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + int done = cb->args[0]; + int last_addr = cb->args[1]; + struct tipc_node *node; + struct tipc_nl_msg msg; + + if (done) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + rcu_read_lock(); + + if (last_addr && !tipc_node_find(last_addr)) { + rcu_read_unlock(); + /* We never set seq or call nl_dump_check_consistent() this + * means that setting prev_seq here will cause the consistence + * check to fail in the netlink callback handler. Resulting in + * the NLMSG_DONE message having the NLM_F_DUMP_INTR flag set if + * the node state changed while we released the lock. + */ + cb->prev_seq = 1; + return -EPIPE; + } + + list_for_each_entry_rcu(node, &tipc_node_list, list) { + if (last_addr) { + if (node->addr == last_addr) + last_addr = 0; + else + continue; + } + + tipc_node_lock(node); + err = __tipc_nl_add_node(&msg, node); + if (err) { + last_addr = node->addr; + tipc_node_unlock(node); + goto out; + } + + tipc_node_unlock(node); + } + done = 1; +out: + cb->args[0] = done; + cb->args[1] = last_addr; + rcu_read_unlock(); + + return skb->len; +} diff --git a/net/tipc/node.h b/net/tipc/node.h index 04e91458bb29..005fbcef3212 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -1,7 +1,7 @@ /* * net/tipc/node.h: Include file for TIPC node management routines * - * Copyright (c) 2000-2006, Ericsson AB + * Copyright (c) 2000-2006, 2014, Ericsson AB * Copyright (c) 2005, 2010-2014, Wind River Systems * All rights reserved. * @@ -145,6 +145,8 @@ void tipc_node_unlock(struct tipc_node *node); int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port); void tipc_node_remove_conn(u32 dnode, u32 port); +int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); + static inline void tipc_node_lock(struct tipc_node *node) { spin_lock_bh(&node->lock); -- GitLab From fd3cf2ad519f73c2f7a46460ebedf32ad246520c Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:18 +0100 Subject: [PATCH 5784/9457] tipc: add net dump to new netlink api Add TIPC_NL_NET_GET command to the new tipc netlink API. This command dumps the network id of the node. Netlink logical layout of returned network data: -> net -> id Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 11 ++++++ net/tipc/net.c | 59 +++++++++++++++++++++++++++++++ net/tipc/net.h | 7 +++- net/tipc/netlink.c | 9 ++++- 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index 08a793374e8c..dcfd42002da7 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -53,6 +53,7 @@ enum { TIPC_NL_MEDIA_GET, TIPC_NL_MEDIA_SET, TIPC_NL_NODE_GET, + TIPC_NL_NET_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -67,6 +68,7 @@ enum { TIPC_NLA_LINK, /* nest */ TIPC_NLA_MEDIA, /* nest */ TIPC_NLA_NODE, /* nest */ + TIPC_NLA_NET, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -133,6 +135,15 @@ enum { TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1 }; +/* Net info */ +enum { + TIPC_NLA_NET_UNSPEC, + TIPC_NLA_NET_ID, /* u32 */ + + __TIPC_NLA_NET_MAX, + TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1 +}; + /* Publication info */ enum { TIPC_NLA_PUBL_UNSPEC, diff --git a/net/tipc/net.c b/net/tipc/net.c index 93b9944a6a8b..d9e666a1be9d 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -42,6 +42,11 @@ #include "node.h" #include "config.h" +static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { + [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_NET_ID] = { .type = NLA_U32 } +}; + /* * The TIPC locking policy is designed to ensure a very fine locking * granularity, permitting complete parallel access to individual @@ -138,3 +143,57 @@ void tipc_net_stop(void) pr_info("Left network mode\n"); } + +static int __tipc_nl_add_net(struct tipc_nl_msg *msg) +{ + void *hdr; + struct nlattr *attrs; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, + NLM_F_MULTI, TIPC_NL_NET_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_NET); + if (!attrs) + goto msg_full; + + if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tipc_net_id)) + goto attr_msg_full; + + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + + return 0; + +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + int done = cb->args[0]; + struct tipc_nl_msg msg; + + if (done) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + err = __tipc_nl_add_net(&msg); + if (err) + goto out; + + done = 1; +out: + cb->args[0] = done; + + return skb->len; +} diff --git a/net/tipc/net.h b/net/tipc/net.h index 59ef3388be2c..60dc22fe9267 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h @@ -1,7 +1,7 @@ /* * net/tipc/net.h: Include file for TIPC network routing code * - * Copyright (c) 1995-2006, Ericsson AB + * Copyright (c) 1995-2006, 2014, Ericsson AB * Copyright (c) 2005, 2010-2011, Wind River Systems * All rights reserved. * @@ -37,7 +37,12 @@ #ifndef _TIPC_NET_H #define _TIPC_NET_H +#include + int tipc_net_start(u32 addr); + void tipc_net_stop(void); +int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); + #endif diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 5b0e3c8457d2..c143f9c20f61 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -40,6 +40,7 @@ #include "bearer.h" #include "link.h" #include "node.h" +#include "net.h" #include static int handle_cmd(struct sk_buff *skb, struct genl_info *info) @@ -79,7 +80,8 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, - [TIPC_NLA_NODE] = { .type = NLA_NESTED, } + [TIPC_NLA_NODE] = { .type = NLA_NESTED, }, + [TIPC_NLA_NET] = { .type = NLA_NESTED, } }; /* Legacy ASCII API */ @@ -173,6 +175,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_NODE_GET, .dumpit = tipc_nl_node_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_NET_GET, + .dumpit = tipc_nl_net_dump, + .policy = tipc_nl_policy, } }; -- GitLab From 27c21416727af73df45051acb05331c0f10e50f6 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:19 +0100 Subject: [PATCH 5785/9457] tipc: add net set to new netlink api Add TIPC_NL_NET_SET command to the new tipc netlink API. This command can set the network id and network (tipc) address. Netlink logical layout of network set message: -> net [ -> id ] [ -> address ] Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 2 ++ net/tipc/net.c | 47 +++++++++++++++++++++++++++++++ net/tipc/net.h | 1 + net/tipc/netlink.c | 5 ++++ 4 files changed, 55 insertions(+) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index dcfd42002da7..fb980e27f425 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -54,6 +54,7 @@ enum { TIPC_NL_MEDIA_SET, TIPC_NL_NODE_GET, TIPC_NL_NET_GET, + TIPC_NL_NET_SET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -139,6 +140,7 @@ enum { enum { TIPC_NLA_NET_UNSPEC, TIPC_NLA_NET_ID, /* u32 */ + TIPC_NLA_NET_ADDR, /* u32 */ __TIPC_NLA_NET_MAX, TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1 diff --git a/net/tipc/net.c b/net/tipc/net.c index d9e666a1be9d..cf13df3cde8f 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -197,3 +197,50 @@ int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } + +int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) +{ + int err; + struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; + + if (!info->attrs[TIPC_NLA_NET]) + return -EINVAL; + + err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX, + info->attrs[TIPC_NLA_NET], + tipc_nl_net_policy); + if (err) + return err; + + if (attrs[TIPC_NLA_NET_ID]) { + u32 val; + + /* Can't change net id once TIPC has joined a network */ + if (tipc_own_addr) + return -EPERM; + + val = nla_get_u32(attrs[TIPC_NLA_NET_ID]); + if (val < 1 || val > 9999) + return -EINVAL; + + tipc_net_id = val; + } + + if (attrs[TIPC_NLA_NET_ADDR]) { + u32 addr; + + /* Can't change net addr once TIPC has joined a network */ + if (tipc_own_addr) + return -EPERM; + + addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); + if (!tipc_addr_node_valid(addr)) + return -EINVAL; + + rtnl_lock(); + tipc_net_start(addr); + rtnl_unlock(); + } + + return 0; +} diff --git a/net/tipc/net.h b/net/tipc/net.h index 60dc22fe9267..a81c1b9eb150 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h @@ -44,5 +44,6 @@ int tipc_net_start(u32 addr); void tipc_net_stop(void); int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); +int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); #endif diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index c143f9c20f61..cb37d30378a8 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -180,6 +180,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_NET_GET, .dumpit = tipc_nl_net_dump, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_NET_SET, + .doit = tipc_nl_net_set, + .policy = tipc_nl_policy, } }; -- GitLab From 1593123a6a4914ccac4699d7f93cdf8057a7d822 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Thu, 20 Nov 2014 10:29:20 +0100 Subject: [PATCH 5786/9457] tipc: add name table dump to new netlink api Add TIPC_NL_NAME_TABLE_GET command to the new tipc netlink API. This command supports dumping the name table of all nodes. Netlink logical layout of name table response message: -> name table -> publication -> type -> lower -> upper -> scope -> node -> ref -> key Signed-off-by: Richard Alpe Reviewed-by: Erik Hugne Reviewed-by: Jon Maloy Acked-by: Ying Xue Signed-off-by: David S. Miller --- include/uapi/linux/tipc_netlink.h | 11 ++ net/tipc/name_table.c | 190 +++++++++++++++++++++++++++++- net/tipc/name_table.h | 4 +- net/tipc/netlink.c | 9 +- 4 files changed, 211 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index fb980e27f425..8d723824ad69 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -55,6 +55,7 @@ enum { TIPC_NL_NODE_GET, TIPC_NL_NET_GET, TIPC_NL_NET_SET, + TIPC_NL_NAME_TABLE_GET, __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -70,6 +71,7 @@ enum { TIPC_NLA_MEDIA, /* nest */ TIPC_NLA_NODE, /* nest */ TIPC_NLA_NET, /* nest */ + TIPC_NLA_NAME_TABLE, /* nest */ __TIPC_NLA_MAX, TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 @@ -146,6 +148,15 @@ enum { TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1 }; +/* Name table info */ +enum { + TIPC_NLA_NAME_TABLE_UNSPEC, + TIPC_NLA_NAME_TABLE_PUBL, /* nest */ + + __TIPC_NLA_NAME_TABLE_MAX, + TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1 +}; + /* Publication info */ enum { TIPC_NLA_PUBL_UNSPEC, diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 3a6a0a7c0759..30ca8e0e0f84 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -1,7 +1,7 @@ /* * net/tipc/name_table.c: TIPC name table code * - * Copyright (c) 2000-2006, Ericsson AB + * Copyright (c) 2000-2006, 2014, Ericsson AB * Copyright (c) 2004-2008, 2010-2011, Wind River Systems * All rights reserved. * @@ -42,6 +42,12 @@ #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ +static const struct nla_policy +tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = { + [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC }, + [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED } +}; + /** * struct name_info - name sequence publication info * @node_list: circular list of publications made by own node @@ -995,3 +1001,185 @@ void tipc_nametbl_stop(void) table.types = NULL; write_unlock_bh(&tipc_nametbl_lock); } + +int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, struct name_seq *seq, + struct sub_seq *sseq, u32 *last_publ) +{ + void *hdr; + struct nlattr *attrs; + struct nlattr *publ; + struct publication *p; + + if (*last_publ) { + list_for_each_entry(p, &sseq->info->zone_list, zone_list) + if (p->key == *last_publ) + break; + if (p->key != *last_publ) + return -EPIPE; + } else { + p = list_first_entry(&sseq->info->zone_list, struct publication, + zone_list); + } + + list_for_each_entry_from(p, &sseq->info->zone_list, zone_list) { + *last_publ = p->key; + + hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, + &tipc_genl_v2_family, NLM_F_MULTI, + TIPC_NL_NAME_TABLE_GET); + if (!hdr) + return -EMSGSIZE; + + attrs = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE); + if (!attrs) + goto msg_full; + + publ = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE_PUBL); + if (!publ) + goto attr_msg_full; + + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, seq->type)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sseq->lower)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sseq->upper)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->ref)) + goto publ_msg_full; + if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key)) + goto publ_msg_full; + + nla_nest_end(msg->skb, publ); + nla_nest_end(msg->skb, attrs); + genlmsg_end(msg->skb, hdr); + } + *last_publ = 0; + + return 0; + +publ_msg_full: + nla_nest_cancel(msg->skb, publ); +attr_msg_full: + nla_nest_cancel(msg->skb, attrs); +msg_full: + genlmsg_cancel(msg->skb, hdr); + + return -EMSGSIZE; +} + +int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, + u32 *last_lower, u32 *last_publ) +{ + struct sub_seq *sseq; + struct sub_seq *sseq_start; + int err; + + if (*last_lower) { + sseq_start = nameseq_find_subseq(seq, *last_lower); + if (!sseq_start) + return -EPIPE; + } else { + sseq_start = seq->sseqs; + } + + for (sseq = sseq_start; sseq != &seq->sseqs[seq->first_free]; sseq++) { + err = __tipc_nl_add_nametable_publ(msg, seq, sseq, last_publ); + if (err) { + *last_lower = sseq->lower; + return err; + } + } + *last_lower = 0; + + return 0; +} + +int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, u32 *last_lower, + u32 *last_publ) +{ + struct hlist_head *seq_head; + struct name_seq *seq; + int err; + int i; + + if (*last_type) + i = hash(*last_type); + else + i = 0; + + for (; i < TIPC_NAMETBL_SIZE; i++) { + seq_head = &table.types[i]; + + if (*last_type) { + seq = nametbl_find_seq(*last_type); + if (!seq) + return -EPIPE; + } else { + seq = hlist_entry_safe((seq_head)->first, + struct name_seq, ns_list); + if (!seq) + continue; + } + + hlist_for_each_entry_from(seq, ns_list) { + spin_lock_bh(&seq->lock); + + err = __tipc_nl_subseq_list(msg, seq, last_lower, + last_publ); + + if (err) { + *last_type = seq->type; + spin_unlock_bh(&seq->lock); + return err; + } + spin_unlock_bh(&seq->lock); + } + *last_type = 0; + } + return 0; +} + +int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + int err; + int done = cb->args[3]; + u32 last_type = cb->args[0]; + u32 last_lower = cb->args[1]; + u32 last_publ = cb->args[2]; + struct tipc_nl_msg msg; + + if (done) + return 0; + + msg.skb = skb; + msg.portid = NETLINK_CB(cb->skb).portid; + msg.seq = cb->nlh->nlmsg_seq; + + read_lock_bh(&tipc_nametbl_lock); + + err = __tipc_nl_seq_list(&msg, &last_type, &last_lower, &last_publ); + if (!err) { + done = 1; + } else if (err != -EMSGSIZE) { + /* We never set seq or call nl_dump_check_consistent() this + * means that setting prev_seq here will cause the consistence + * check to fail in the netlink callback handler. Resulting in + * the NLMSG_DONE message having the NLM_F_DUMP_INTR flag set if + * we got an error. + */ + cb->prev_seq = 1; + } + + read_unlock_bh(&tipc_nametbl_lock); + + cb->args[0] = last_type; + cb->args[1] = last_lower; + cb->args[2] = last_publ; + cb->args[3] = done; + + return skb->len; +} diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index f02f48b9a216..b38ebecac766 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h @@ -1,7 +1,7 @@ /* * net/tipc/name_table.h: Include file for TIPC name table code * - * Copyright (c) 2000-2006, Ericsson AB + * Copyright (c) 2000-2006, 2014, Ericsson AB * Copyright (c) 2004-2005, 2010-2011, Wind River Systems * All rights reserved. * @@ -84,6 +84,8 @@ struct publication { extern rwlock_t tipc_nametbl_lock; +int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); + struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space); u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node); int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index cb37d30378a8..b891e3905bc4 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -37,6 +37,7 @@ #include "core.h" #include "config.h" #include "socket.h" +#include "name_table.h" #include "bearer.h" #include "link.h" #include "node.h" @@ -81,7 +82,8 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, [TIPC_NLA_NODE] = { .type = NLA_NESTED, }, - [TIPC_NLA_NET] = { .type = NLA_NESTED, } + [TIPC_NLA_NET] = { .type = NLA_NESTED, }, + [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } }; /* Legacy ASCII API */ @@ -185,6 +187,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .cmd = TIPC_NL_NET_SET, .doit = tipc_nl_net_set, .policy = tipc_nl_policy, + }, + { + .cmd = TIPC_NL_NAME_TABLE_GET, + .dumpit = tipc_nl_name_table_dump, + .policy = tipc_nl_policy, } }; -- GitLab From 541675580ffcd098d746f7f713c7dbcc86744925 Mon Sep 17 00:00:00 2001 From: Tina Johnson Date: Thu, 20 Nov 2014 15:54:54 +0530 Subject: [PATCH 5787/9457] drivers: atm: eni: Add pci_dma_mapping_error() call Added a pci_dma_mapping_error() call to check for mapping errors before further using the dma handle. In case of error, control goes to a new label where the incoming skb is freed. Unchecked dma handles were found using Coccinelle: @rule1@ expression e1; identifier x; @@ *x = pci_map_single(...); ... when != pci_dma_mapping_error(e1,x) Signed-off-by: Tina Johnson Acked-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/atm/eni.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index d65975aba4ec..c7fab3ee14ee 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -356,6 +356,8 @@ static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb, if (skb) { paddr = pci_map_single(eni_dev->pci_dev,skb->data,skb->len, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(eni_dev->pci_dev, paddr)) + goto dma_map_error; ENI_PRV_PADDR(skb) = paddr; if (paddr & 3) printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has " @@ -481,6 +483,7 @@ rx_enqueued++; if (paddr) pci_unmap_single(eni_dev->pci_dev,paddr,skb->len, PCI_DMA_FROMDEVICE); +dma_map_error: if (skb) dev_kfree_skb_irq(skb); return -1; } -- GitLab From 824cb7d13638ebacb3f5c85b01a2aeec6fe14081 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Fri, 21 Nov 2014 22:04:44 +0200 Subject: [PATCH 5788/9457] amdkfd: explicitely include io.h in kfd_doorbell.c This patch fixes a compilation error when using certain configuration by including the file io.h in kfd_doorbell.c Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c index 0dcb78755686..b5791a5c7c06 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c @@ -23,6 +23,7 @@ #include #include #include +#include /* * This extension supports a kernel level doorbells management for -- GitLab From 312df74c712252017f0c2c12289f00b146ca72b3 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Thu, 20 Nov 2014 14:19:44 +0200 Subject: [PATCH 5789/9457] net/mlx4_en: mlx4_en_set_settings() always fails when autoneg is set Fix ethtool set settings to not check AUTONEG_ENABLE mlx4_en_set_settings should not check if cmd->autoneg == AUTONEG_ENABLE, cmd->autoneg can be enabled by default and this check will fail other settings requests. mlx4_en driver doesn't support changing autoneg value, but shouldn't fail the request in case cmd->autoneg was set. Fixes: d48b3ab ("net/mlx4_en: Use PTYS register to set ethtool settings (Speed)") Signed-off-by: Saeed Mahameed Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 710cf309962a..bdff834a2a7e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -756,7 +756,7 @@ static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) speed, cmd->advertising, cmd->autoneg, cmd->duplex); if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL) || - (cmd->autoneg == AUTONEG_ENABLE) || (cmd->duplex == DUPLEX_HALF)) + (cmd->duplex == DUPLEX_HALF)) return -EINVAL; memset(&ptys_reg, 0, sizeof(ptys_reg)); -- GitLab From 5ac0fd00e1681ef6f929f651124da77f5ca7e564 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 14:22:47 +0100 Subject: [PATCH 5790/9457] IBM-EMAC: Deletion of unnecessary checks before the function call "of_dev_put" The of_dev_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/emac/core.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 87bd953cc2ee..3f3fba9e4650 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2323,16 +2323,11 @@ static int emac_check_deps(struct emac_instance *dev, static void emac_put_deps(struct emac_instance *dev) { - if (dev->mal_dev) - of_dev_put(dev->mal_dev); - if (dev->zmii_dev) - of_dev_put(dev->zmii_dev); - if (dev->rgmii_dev) - of_dev_put(dev->rgmii_dev); - if (dev->mdio_dev) - of_dev_put(dev->mdio_dev); - if (dev->tah_dev) - of_dev_put(dev->tah_dev); + of_dev_put(dev->mal_dev); + of_dev_put(dev->zmii_dev); + of_dev_put(dev->rgmii_dev); + of_dev_put(dev->mdio_dev); + of_dev_put(dev->tah_dev); } static int emac_of_bus_notify(struct notifier_block *nb, unsigned long action, @@ -2371,8 +2366,7 @@ static int emac_wait_deps(struct emac_instance *dev) bus_unregister_notifier(&platform_bus_type, &emac_of_bus_notifier); err = emac_check_deps(dev, deps) ? 0 : -ENODEV; for (i = 0; i < EMAC_DEP_COUNT; i++) { - if (deps[i].node) - of_node_put(deps[i].node); + of_node_put(deps[i].node); if (err && deps[i].ofdev) of_dev_put(deps[i].ofdev); } @@ -2383,8 +2377,7 @@ static int emac_wait_deps(struct emac_instance *dev) dev->tah_dev = deps[EMAC_DEP_TAH_IDX].ofdev; dev->mdio_dev = deps[EMAC_DEP_MDIO_IDX].ofdev; } - if (deps[EMAC_DEP_PREV_IDX].ofdev) - of_dev_put(deps[EMAC_DEP_PREV_IDX].ofdev); + of_dev_put(deps[EMAC_DEP_PREV_IDX].ofdev); return err; } @@ -3113,8 +3106,7 @@ static void __exit emac_exit(void) /* Destroy EMAC boot list */ for (i = 0; i < EMAC_BOOT_LIST_SIZE; i++) - if (emac_boot_list[i]) - of_node_put(emac_boot_list[i]); + of_node_put(emac_boot_list[i]); } module_init(emac_init); -- GitLab From 38a90e7ccb6c25a124ef46e1f30f5df1a0375fb6 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 14:47:12 +0100 Subject: [PATCH 5791/9457] net: Xilinx: Deletion of unnecessary checks before two function calls The functions kfree() and of_node_put() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Soren Brinkmann Signed-off-by: David S. Miller --- drivers/net/ethernet/xilinx/ll_temac_main.c | 3 +-- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 629077050fce..9c2d91ea0af4 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -224,8 +224,7 @@ static void temac_dma_bd_release(struct net_device *ndev) dma_free_coherent(ndev->dev.parent, sizeof(*lp->tx_bd_v) * TX_BD_NUM, lp->tx_bd_v, lp->tx_bd_p); - if (lp->rx_skb) - kfree(lp->rx_skb); + kfree(lp->rx_skb); } /** diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 28dbbdc393eb..24858799c204 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1200,8 +1200,7 @@ static int xemaclite_of_remove(struct platform_device *of_dev) unregister_netdev(ndev); - if (lp->phy_node) - of_node_put(lp->phy_node); + of_node_put(lp->phy_node); lp->phy_node = NULL; xemaclite_remove_ndev(ndev); -- GitLab From 91ecee6846704cbd0ec14509b86e99c291cd9bcd Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 16:11:56 +0100 Subject: [PATCH 5792/9457] net: USB: Deletion of unnecessary checks before the function call "kfree" The kfree() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: David S. Miller --- drivers/net/usb/asix_devices.c | 3 +-- drivers/net/usb/hso.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 816d511e34d3..bf49792062a2 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -487,8 +487,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) { - if (dev->driver_priv) - kfree(dev->driver_priv); + kfree(dev->driver_priv); } static const struct ethtool_ops ax88178_ethtool_ops = { diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index babda7d8693e..9c5aa922a9f4 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2746,8 +2746,7 @@ struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface, tty_unregister_device(tty_drv, serial->minor); kfree(serial); } - if (hso_dev) - kfree(hso_dev); + kfree(hso_dev); return NULL; } -- GitLab From 5449e27167c9945d24108690aff86943d79774a7 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:26 -0600 Subject: [PATCH 5793/9457] amd-xgbe: Add a read memory barrier to Tx/Rx path Add a read memory barrier to the Tx and Rx paths where the ownership bit is checked to be sure that all descriptor fields are read after having read the ownership bit for the descriptor. This has not been an issue to date, but it's a good safe-guard to have. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +++ drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index f6014d330b2e..9b1d9fa68257 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1558,6 +1558,9 @@ static int xgbe_dev_read(struct xgbe_channel *channel) if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN)) return 1; + /* Make sure descriptor fields are read after reading the OWN bit */ + rmb(); + #ifdef XGMAC_ENABLE_RX_DESC_DUMP xgbe_dump_rx_desc(ring, rdesc, ring->cur); #endif diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 0544931329d1..eebb787251c4 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1791,6 +1791,10 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) if (!hw_if->tx_complete(rdesc)) break; + /* Make sure descriptor fields are read after reading the OWN + * bit */ + rmb(); + #ifdef XGMAC_ENABLE_TX_DESC_DUMP xgbe_dump_tx_desc(ring, ring->dirty, 1, 0); #endif -- GitLab From 16edd34e9ebb4c0b63c69ada3abe106a309cb431 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:32 -0600 Subject: [PATCH 5794/9457] amd-xgbe: Tx engine must not be active before stopping it If the Tx engine is told to stop while it is actively processing Tx descriptors it is possible that the Tx descriptor(s) will not be closed out properly. When the Tx engine is restarted this could result in the driver being stuck on the improperly closed descriptor. Update the driver to wait for the Tx engine to be in a stopped or suspended state before issuing the stop command. This has not been an issue to date, but it's a good safe-guard to have. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-common.h | 21 +++++--- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 59 +++++++++++++++++++++ drivers/net/ethernet/amd/xgbe/xgbe.h | 1 + 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 2fe8fc71fe01..75b08c63d39f 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -125,9 +125,6 @@ #define DMA_AXIAWCR 0x3018 #define DMA_DSR0 0x3020 #define DMA_DSR1 0x3024 -#define DMA_DSR2 0x3028 -#define DMA_DSR3 0x302c -#define DMA_DSR4 0x3030 /* DMA register entry bit positions and sizes */ #define DMA_AXIARCR_DRC_INDEX 0 @@ -158,10 +155,6 @@ #define DMA_AXIAWCR_TDC_WIDTH 4 #define DMA_AXIAWCR_TDD_INDEX 28 #define DMA_AXIAWCR_TDD_WIDTH 2 -#define DMA_DSR0_RPS_INDEX 8 -#define DMA_DSR0_RPS_WIDTH 4 -#define DMA_DSR0_TPS_INDEX 12 -#define DMA_DSR0_TPS_WIDTH 4 #define DMA_ISR_MACIS_INDEX 17 #define DMA_ISR_MACIS_WIDTH 1 #define DMA_ISR_MTLIS_INDEX 16 @@ -175,6 +168,20 @@ #define DMA_SBMR_UNDEF_INDEX 0 #define DMA_SBMR_UNDEF_WIDTH 1 +/* DMA register values */ +#define DMA_DSR_RPS_WIDTH 4 +#define DMA_DSR_TPS_WIDTH 4 +#define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH) +#define DMA_DSR0_RPS_START 8 +#define DMA_DSR0_TPS_START 12 +#define DMA_DSRX_FIRST_QUEUE 3 +#define DMA_DSRX_INC 4 +#define DMA_DSRX_QPR 4 +#define DMA_DSRX_RPS_START 0 +#define DMA_DSRX_TPS_START 4 +#define DMA_TPS_STOPPED 0x00 +#define DMA_TPS_SUSPENDED 0x06 + /* DMA channel register offsets * Multiple channels can be active. The first channel has registers * that begin at 0x3100. Each subsequent channel has registers that diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 9b1d9fa68257..dcd0347305c0 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -2453,6 +2453,47 @@ static void xgbe_config_mmc(struct xgbe_prv_data *pdata) XGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1); } +static void xgbe_prepare_tx_stop(struct xgbe_prv_data *pdata, + struct xgbe_channel *channel) +{ + unsigned int tx_dsr, tx_pos, tx_qidx; + unsigned int tx_status; + unsigned long tx_timeout; + + /* Calculate the status register to read and the position within */ + if (channel->queue_index < DMA_DSRX_FIRST_QUEUE) { + tx_dsr = DMA_DSR0; + tx_pos = (channel->queue_index * DMA_DSR_Q_WIDTH) + + DMA_DSR0_TPS_START; + } else { + tx_qidx = channel->queue_index - DMA_DSRX_FIRST_QUEUE; + + tx_dsr = DMA_DSR1 + ((tx_qidx / DMA_DSRX_QPR) * DMA_DSRX_INC); + tx_pos = ((tx_qidx % DMA_DSRX_QPR) * DMA_DSR_Q_WIDTH) + + DMA_DSRX_TPS_START; + } + + /* The Tx engine cannot be stopped if it is actively processing + * descriptors. Wait for the Tx engine to enter the stopped or + * suspended state. Don't wait forever though... + */ + tx_timeout = jiffies + (XGBE_DMA_STOP_TIMEOUT * HZ); + while (time_before(jiffies, tx_timeout)) { + tx_status = XGMAC_IOREAD(pdata, tx_dsr); + tx_status = GET_BITS(tx_status, tx_pos, DMA_DSR_TPS_WIDTH); + if ((tx_status == DMA_TPS_STOPPED) || + (tx_status == DMA_TPS_SUSPENDED)) + break; + + usleep_range(500, 1000); + } + + if (!time_before(jiffies, tx_timeout)) + netdev_info(pdata->netdev, + "timed out waiting for Tx DMA channel %u to stop\n", + channel->queue_index); +} + static void xgbe_enable_tx(struct xgbe_prv_data *pdata) { struct xgbe_channel *channel; @@ -2481,6 +2522,15 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata) struct xgbe_channel *channel; unsigned int i; + /* Prepare for Tx DMA channel stop */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + xgbe_prepare_tx_stop(pdata, channel); + } + /* Disable MAC Tx */ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0); @@ -2572,6 +2622,15 @@ static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata) struct xgbe_channel *channel; unsigned int i; + /* Prepare for Tx DMA channel stop */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + xgbe_prepare_tx_stop(pdata, channel); + } + /* Disable MAC Tx */ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 901fb1fe5d0d..46ce54459121 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -147,6 +147,7 @@ #define XGBE_MAX_DMA_CHANNELS 16 #define XGBE_MAX_QUEUES 16 +#define XGBE_DMA_STOP_TIMEOUT 5 /* DMA cache settings - Outer sharable, write-back, write-allocate */ #define XGBE_DMA_OS_AXDOMAIN 0x2 -- GitLab From 7bba35bddadbca599aa8be1618e04c548a58d05a Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:38 -0600 Subject: [PATCH 5795/9457] amd-xgbe: Incorporate Smatch coding suggestion The Smatch tool indicated that one of the if statements in xgbe-dev.c could be rewritten to remove a redundant check for the 'err' variable in an if statement. Change the statement as suggested and add a comment to help clarify. Signed-off-by: Tom Lendacky Reported-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index dcd0347305c0..72425ffd8d2b 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1633,7 +1633,8 @@ static int xgbe_dev_read(struct xgbe_channel *channel) etlt = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ETLT); DBGPR(" err=%u, etlt=%#x\n", err, etlt); - if (!err || (err && !etlt)) { + if (!err || !etlt) { + /* No error if err is 0 or etlt is 0 */ if ((etlt == 0x09) && (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) { XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, -- GitLab From c9f140ebb00891c5bfd6b5cdd0552493bcbeac20 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:44 -0600 Subject: [PATCH 5796/9457] amd-xgbe: Separate Tx/Rx ring data fields into new structs Move the Tx and Rx related fields within the xgbe_ring_data struct into their own structs in order to more easily see what fields are used for each operation. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 36 +++++++++++------------ drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 14 ++++----- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 28 +++++++++--------- drivers/net/ethernet/amd/xgbe/xgbe.h | 22 ++++++++++---- 4 files changed, 54 insertions(+), 46 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c index e6b9f54b9697..3c7c3869d867 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c @@ -335,11 +335,11 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata, } /* Set up the header page info */ - xgbe_set_buffer_data(&rdata->rx_hdr, &ring->rx_hdr_pa, + xgbe_set_buffer_data(&rdata->rx.hdr, &ring->rx_hdr_pa, XGBE_SKB_ALLOC_SIZE); /* Set up the buffer page info */ - xgbe_set_buffer_data(&rdata->rx_buf, &ring->rx_buf_pa, + xgbe_set_buffer_data(&rdata->rx.buf, &ring->rx_buf_pa, pdata->rx_buf_size); return 0; @@ -451,31 +451,29 @@ static void xgbe_unmap_rdata(struct xgbe_prv_data *pdata, rdata->skb = NULL; } - if (rdata->rx_hdr.pa.pages) - put_page(rdata->rx_hdr.pa.pages); + if (rdata->rx.hdr.pa.pages) + put_page(rdata->rx.hdr.pa.pages); - if (rdata->rx_hdr.pa_unmap.pages) { - dma_unmap_page(pdata->dev, rdata->rx_hdr.pa_unmap.pages_dma, - rdata->rx_hdr.pa_unmap.pages_len, + if (rdata->rx.hdr.pa_unmap.pages) { + dma_unmap_page(pdata->dev, rdata->rx.hdr.pa_unmap.pages_dma, + rdata->rx.hdr.pa_unmap.pages_len, DMA_FROM_DEVICE); - put_page(rdata->rx_hdr.pa_unmap.pages); + put_page(rdata->rx.hdr.pa_unmap.pages); } - if (rdata->rx_buf.pa.pages) - put_page(rdata->rx_buf.pa.pages); + if (rdata->rx.buf.pa.pages) + put_page(rdata->rx.buf.pa.pages); - if (rdata->rx_buf.pa_unmap.pages) { - dma_unmap_page(pdata->dev, rdata->rx_buf.pa_unmap.pages_dma, - rdata->rx_buf.pa_unmap.pages_len, + if (rdata->rx.buf.pa_unmap.pages) { + dma_unmap_page(pdata->dev, rdata->rx.buf.pa_unmap.pages_dma, + rdata->rx.buf.pa_unmap.pages_len, DMA_FROM_DEVICE); - put_page(rdata->rx_buf.pa_unmap.pages); + put_page(rdata->rx.buf.pa_unmap.pages); } - memset(&rdata->rx_hdr, 0, sizeof(rdata->rx_hdr)); - memset(&rdata->rx_buf, 0, sizeof(rdata->rx_buf)); + memset(&rdata->tx, 0, sizeof(rdata->tx)); + memset(&rdata->rx, 0, sizeof(rdata->rx)); - rdata->tso_header = 0; - rdata->len = 0; rdata->interrupt = 0; rdata->mapped_as_page = 0; @@ -534,7 +532,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb) } rdata->skb_dma = skb_dma; rdata->skb_dma_len = packet->header_len; - rdata->tso_header = 1; + rdata->tx.tso_header = 1; offset = packet->header_len; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 72425ffd8d2b..2908ad181538 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1085,10 +1085,10 @@ static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata) * Set buffer 2 (hi) address to buffer dma address (hi) and * set control bits OWN and INTE */ - rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->rx_hdr.dma)); - rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->rx_hdr.dma)); - rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx_buf.dma)); - rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx_buf.dma)); + rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->rx.hdr.dma)); + rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->rx.hdr.dma)); + rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx.buf.dma)); + rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx.buf.dma)); XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE, rdata->interrupt ? 1 : 0); @@ -1586,8 +1586,8 @@ static int xgbe_dev_read(struct xgbe_channel *channel) /* Get the header length */ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD)) - rdata->hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, - RX_NORMAL_DESC2, HL); + rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, + RX_NORMAL_DESC2, HL); /* Get the RSS hash */ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, RSV)) { @@ -1610,7 +1610,7 @@ static int xgbe_dev_read(struct xgbe_channel *channel) } /* Get the packet length */ - rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); + rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) { /* Not all the data has been transferred for this packet */ diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index eebb787251c4..46ea423f9a08 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1747,14 +1747,14 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata, u8 *packet; unsigned int copy_len; - skb = netdev_alloc_skb_ip_align(netdev, rdata->rx_hdr.dma_len); + skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len); if (!skb) return NULL; - packet = page_address(rdata->rx_hdr.pa.pages) + - rdata->rx_hdr.pa.pages_offset; - copy_len = (rdata->hdr_len) ? rdata->hdr_len : *len; - copy_len = min(rdata->rx_hdr.dma_len, copy_len); + packet = page_address(rdata->rx.hdr.pa.pages) + + rdata->rx.hdr.pa.pages_offset; + copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : *len; + copy_len = min(rdata->rx.hdr.dma_len, copy_len); skb_copy_to_linear_data(skb, packet, copy_len); skb_put(skb, copy_len); @@ -1900,13 +1900,13 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) } if (!context) { - put_len = rdata->len - len; + put_len = rdata->rx.len - len; len += put_len; if (!skb) { dma_sync_single_for_cpu(pdata->dev, - rdata->rx_hdr.dma, - rdata->rx_hdr.dma_len, + rdata->rx.hdr.dma, + rdata->rx.hdr.dma_len, DMA_FROM_DEVICE); skb = xgbe_create_skb(pdata, rdata, &put_len); @@ -1918,15 +1918,15 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) if (put_len) { dma_sync_single_for_cpu(pdata->dev, - rdata->rx_buf.dma, - rdata->rx_buf.dma_len, + rdata->rx.buf.dma, + rdata->rx.buf.dma_len, DMA_FROM_DEVICE); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - rdata->rx_buf.pa.pages, - rdata->rx_buf.pa.pages_offset, - put_len, rdata->rx_buf.dma_len); - rdata->rx_buf.pa.pages = NULL; + rdata->rx.buf.pa.pages, + rdata->rx.buf.pa.pages_offset, + put_len, rdata->rx.buf.dma_len); + rdata->rx.buf.pa.pages = NULL; } } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 46ce54459121..41ce6e3eb9e6 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -271,6 +271,20 @@ struct xgbe_buffer_data { unsigned int dma_len; }; +/* Tx-related ring data */ +struct xgbe_tx_ring_data { + unsigned int tso_header; /* TSO header indicator */ +}; + +/* Rx-related ring data */ +struct xgbe_rx_ring_data { + struct xgbe_buffer_data hdr; /* Header locations */ + struct xgbe_buffer_data buf; /* Payload locations */ + + unsigned short hdr_len; /* Length of received header */ + unsigned short len; /* Length of received packet */ +}; + /* Structure used to hold information related to the descriptor * and the packet associated with the descriptor (always use * use the XGBE_GET_DESC_DATA macro to access this data from the ring) @@ -282,13 +296,9 @@ struct xgbe_ring_data { struct sk_buff *skb; /* Virtual address of SKB */ dma_addr_t skb_dma; /* DMA address of SKB data */ unsigned int skb_dma_len; /* Length of SKB DMA area */ - unsigned int tso_header; /* TSO header indicator */ - struct xgbe_buffer_data rx_hdr; /* Header locations */ - struct xgbe_buffer_data rx_buf; /* Payload locations */ - - unsigned short hdr_len; /* Length of received header */ - unsigned short len; /* Length of received Rx packet */ + struct xgbe_tx_ring_data tx; /* Tx-related data */ + struct xgbe_rx_ring_data rx; /* Rx-related data */ unsigned int interrupt; /* Interrupt indicator */ -- GitLab From 5fb4b86a66363e275add87b441bf80b24144a0c9 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:50 -0600 Subject: [PATCH 5797/9457] amd-xgbe: Add BQL support Call the appropriate BQL functions to track the number of bytes queued during Tx processing and to track the number of packets and bytes that have been transmitted during Tx complete processing. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 +++ drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 43 +++++++++++++++++++++++- drivers/net/ethernet/amd/xgbe/xgbe.h | 5 +++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 2908ad181538..78db5a657699 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1500,6 +1500,10 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) /* Set LAST bit for the last descriptor */ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1); + /* Save the Tx info to report back during cleanup */ + rdata->tx.packets = packet->tx_packets; + rdata->tx.bytes = packet->tx_bytes; + /* In case the Tx DMA engine is running, make sure everything * is written to the descriptor(s) before setting the OWN bit * for the first descriptor diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 46ea423f9a08..f9635281c7df 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -876,7 +876,10 @@ static int xgbe_start(struct xgbe_prv_data *pdata) static void xgbe_stop(struct xgbe_prv_data *pdata) { struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_channel *channel; struct net_device *netdev = pdata->netdev; + struct netdev_queue *txq; + unsigned int i; DBGPR("-->xgbe_stop\n"); @@ -890,6 +893,15 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) hw_if->disable_tx(pdata); hw_if->disable_rx(pdata); + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + continue; + + txq = netdev_get_tx_queue(netdev, channel->queue_index); + netdev_tx_reset_queue(txq); + } + DBGPR("<--xgbe_stop\n"); } @@ -1156,6 +1168,12 @@ static int xgbe_prep_tso(struct sk_buff *skb, struct xgbe_packet_data *packet) packet->tcp_header_len, packet->tcp_payload_len); DBGPR(" packet->mss=%u\n", packet->mss); + /* Update the number of packets that will ultimately be transmitted + * along with the extra bytes for each extra packet + */ + packet->tx_packets = skb_shinfo(skb)->gso_segs; + packet->tx_bytes += (packet->tx_packets - 1) * packet->header_len; + return 0; } @@ -1184,6 +1202,9 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata, context_desc = 0; packet->rdesc_count = 0; + packet->tx_packets = 1; + packet->tx_bytes = skb->len; + if (xgbe_is_tso(skb)) { /* TSO requires an extra descriptor if mss is different */ if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) { @@ -1400,12 +1421,14 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) struct xgbe_channel *channel; struct xgbe_ring *ring; struct xgbe_packet_data *packet; + struct netdev_queue *txq; unsigned long flags; int ret; DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len); channel = pdata->channel + skb->queue_mapping; + txq = netdev_get_tx_queue(netdev, channel->queue_index); ring = channel->tx_ring; packet = &ring->packet_data; @@ -1447,6 +1470,9 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) xgbe_prep_tx_tstamp(pdata, skb, packet); + /* Report on the actual number of bytes (to be) sent */ + netdev_tx_sent_queue(txq, packet->tx_bytes); + /* Configure required descriptor fields for transmission */ hw_if->dev_xmit(channel); @@ -1772,8 +1798,10 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) struct xgbe_ring_data *rdata; struct xgbe_ring_desc *rdesc; struct net_device *netdev = pdata->netdev; + struct netdev_queue *txq; unsigned long flags; int processed = 0; + unsigned int tx_packets = 0, tx_bytes = 0; DBGPR("-->xgbe_tx_poll\n"); @@ -1781,6 +1809,8 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) if (!ring) return 0; + txq = netdev_get_tx_queue(netdev, channel->queue_index); + spin_lock_irqsave(&ring->lock, flags); while ((processed < XGBE_TX_DESC_MAX_PROC) && @@ -1799,6 +1829,11 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) xgbe_dump_tx_desc(ring, ring->dirty, 1, 0); #endif + if (hw_if->is_last_desc(rdesc)) { + tx_packets += rdata->tx.packets; + tx_bytes += rdata->tx.bytes; + } + /* Free the SKB and reset the descriptor for re-use */ desc_if->unmap_rdata(pdata, rdata); hw_if->tx_desc_reset(rdata); @@ -1807,14 +1842,20 @@ static int xgbe_tx_poll(struct xgbe_channel *channel) ring->dirty++; } + if (!processed) + goto unlock; + + netdev_tx_completed_queue(txq, tx_packets, tx_bytes); + if ((ring->tx.queue_stopped == 1) && (xgbe_tx_avail_desc(ring) > XGBE_TX_DESC_MIN_FREE)) { ring->tx.queue_stopped = 0; - netif_wake_subqueue(netdev, channel->queue_index); + netif_tx_wake_queue(txq); } DBGPR("<--xgbe_tx_poll: processed=%d\n", processed); +unlock: spin_unlock_irqrestore(&ring->lock, flags); return processed; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 41ce6e3eb9e6..98504f1469ed 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -243,6 +243,9 @@ struct xgbe_packet_data { u32 rss_hash; enum pkt_hash_types rss_hash_type; + + unsigned int tx_packets; + unsigned int tx_bytes; }; /* Common Rx and Tx descriptor mapping */ @@ -274,6 +277,8 @@ struct xgbe_buffer_data { /* Tx-related ring data */ struct xgbe_tx_ring_data { unsigned int tso_header; /* TSO header indicator */ + unsigned int packets; /* BQL packet count */ + unsigned int bytes; /* BQL byte count */ }; /* Rx-related ring data */ -- GitLab From 16978eb7bc2f6ecba71916a673a7840d17943b71 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:03:56 -0600 Subject: [PATCH 5798/9457] amd-xgbe: Remove unused variable The tso_header variable in the xgbe_tx_ring_data structure is not used, remove it. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 1 - drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c index 3c7c3869d867..62cb4d3388df 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c @@ -532,7 +532,6 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb) } rdata->skb_dma = skb_dma; rdata->skb_dma_len = packet->header_len; - rdata->tx.tso_header = 1; offset = packet->header_len; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 98504f1469ed..ec0d37a917ae 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -276,7 +276,6 @@ struct xgbe_buffer_data { /* Tx-related ring data */ struct xgbe_tx_ring_data { - unsigned int tso_header; /* TSO header indicator */ unsigned int packets; /* BQL packet count */ unsigned int bytes; /* BQL byte count */ }; -- GitLab From eb79e640fab1fc163e6f04e0cc007c76b6a46f28 Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:04:02 -0600 Subject: [PATCH 5799/9457] amd-xgbe: Perform Tx coalescing on a packet basis The current form of Tx coalescing works on a descriptor basis instead of on a packet basis and doesn't take into account TSO packets. Update the Tx coalescing support to work on a packet basis, taking into account the number of packets associated with a TSO transmit. Also, only activate the Tx timer if a timer value is set. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 46 +++++++++++++----------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 78db5a657699..b3d2433b52bb 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1334,7 +1334,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) struct xgbe_packet_data *packet = &ring->packet_data; unsigned int csum, tso, vlan; unsigned int tso_context, vlan_context; - unsigned int tx_coalesce, tx_frames; + unsigned int tx_set_ic; int start_index = ring->cur; int i; @@ -1357,10 +1357,26 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) else vlan_context = 0; - tx_coalesce = (pdata->tx_usecs || pdata->tx_frames) ? 1 : 0; - tx_frames = pdata->tx_frames; - if (tx_coalesce && !channel->tx_timer_active) - ring->coalesce_count = 0; + /* Determine if an interrupt should be generated for this Tx: + * Interrupt: + * - Tx frame count exceeds the frame count setting + * - Addition of Tx frame count to the frame count since the + * last interrupt was set exceeds the frame count setting + * No interrupt: + * - No frame count setting specified (ethtool -C ethX tx-frames 0) + * - Addition of Tx frame count to the frame count since the + * last interrupt was set does not exceed the frame count setting + */ + ring->coalesce_count += packet->tx_packets; + if (!pdata->tx_frames) + tx_set_ic = 0; + else if (packet->tx_packets > pdata->tx_frames) + tx_set_ic = 1; + else if ((ring->coalesce_count % pdata->tx_frames) < + packet->tx_packets) + tx_set_ic = 1; + else + tx_set_ic = 0; rdata = XGBE_GET_DESC_DATA(ring, ring->cur); rdesc = rdata->rdesc; @@ -1427,13 +1443,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1); - /* Set IC bit based on Tx coalescing settings */ - XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); - if (tx_coalesce && (!tx_frames || - (++ring->coalesce_count % tx_frames))) - /* Clear IC bit */ - XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0); - /* Mark it as First Descriptor */ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1); @@ -1478,13 +1487,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L, rdata->skb_dma_len); - /* Set IC bit based on Tx coalescing settings */ - XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); - if (tx_coalesce && (!tx_frames || - (++ring->coalesce_count % tx_frames))) - /* Clear IC bit */ - XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0); - /* Set OWN bit */ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); @@ -1500,6 +1502,10 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) /* Set LAST bit for the last descriptor */ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1); + /* Set IC bit based on Tx coalescing settings */ + if (tx_set_ic) + XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); + /* Save the Tx info to report back during cleanup */ rdata->tx.packets = packet->tx_packets; rdata->tx.bytes = packet->tx_bytes; @@ -1530,7 +1536,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) lower_32_bits(rdata->rdesc_dma)); /* Start the Tx coalescing timer */ - if (tx_coalesce && !channel->tx_timer_active) { + if (pdata->tx_usecs && !channel->tx_timer_active) { channel->tx_timer_active = 1; hrtimer_start(&channel->tx_timer, ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC), -- GitLab From 16958a2b05def4ed214ae681b7ee4ce8537b00fb Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 20 Nov 2014 11:04:08 -0600 Subject: [PATCH 5800/9457] amd-xgbe: Add support for the skb->xmit_more flag Add support to delay telling the hardware about data that is ready to be transmitted if the skb->xmit_more flag is set. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-desc.c | 5 ++- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 43 ++++++++++++++++------- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 37 +++++++++++++++---- drivers/net/ethernet/amd/xgbe/xgbe.h | 15 ++++++++ 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c index 62cb4d3388df..51b68d1299fe 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c @@ -378,7 +378,7 @@ static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata) ring->cur = 0; ring->dirty = 0; - ring->tx.queue_stopped = 0; + memset(&ring->tx, 0, sizeof(ring->tx)); hw_if->tx_desc_init(channel); } @@ -422,8 +422,7 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata) ring->cur = 0; ring->dirty = 0; - ring->rx.realloc_index = 0; - ring->rx.realloc_threshold = 0; + memset(&ring->rx, 0, sizeof(ring->rx)); hw_if->rx_desc_init(channel); } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index b3d2433b52bb..53f5f66ec2ee 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1325,6 +1325,29 @@ static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata) xgbe_config_flow_control(pdata); } +static void xgbe_tx_start_xmit(struct xgbe_channel *channel, + struct xgbe_ring *ring) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_ring_data *rdata; + + /* Issue a poll command to Tx DMA by writing address + * of next immediate free descriptor */ + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO, + lower_32_bits(rdata->rdesc_dma)); + + /* Start the Tx coalescing timer */ + if (pdata->tx_usecs && !channel->tx_timer_active) { + channel->tx_timer_active = 1; + hrtimer_start(&channel->tx_timer, + ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC), + HRTIMER_MODE_REL); + } + + ring->tx.xmit_more = 0; +} + static void xgbe_dev_xmit(struct xgbe_channel *channel) { struct xgbe_prv_data *pdata = channel->pdata; @@ -1528,20 +1551,13 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) /* Make sure ownership is written to the descriptor */ wmb(); - /* Issue a poll command to Tx DMA by writing address - * of next immediate free descriptor */ ring->cur++; - rdata = XGBE_GET_DESC_DATA(ring, ring->cur); - XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO, - lower_32_bits(rdata->rdesc_dma)); - - /* Start the Tx coalescing timer */ - if (pdata->tx_usecs && !channel->tx_timer_active) { - channel->tx_timer_active = 1; - hrtimer_start(&channel->tx_timer, - ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC), - HRTIMER_MODE_REL); - } + if (!packet->skb->xmit_more || + netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev, + channel->queue_index))) + xgbe_tx_start_xmit(channel, ring); + else + ring->tx.xmit_more = 1; DBGPR(" %s: descriptors %u to %u written\n", channel->name, start_index & (ring->rdesc_count - 1), @@ -2802,6 +2818,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) hw_if->rx_desc_reset = xgbe_rx_desc_reset; hw_if->is_last_desc = xgbe_is_last_desc; hw_if->is_context_desc = xgbe_is_context_desc; + hw_if->tx_start_xmit = xgbe_tx_start_xmit; /* For FLOW ctrl */ hw_if->config_tx_flow_control = xgbe_config_tx_flow_control; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index f9635281c7df..02c104dc2aa4 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -225,6 +225,28 @@ static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring) return (ring->rdesc_count - (ring->cur - ring->dirty)); } +static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel, + struct xgbe_ring *ring, unsigned int count) +{ + struct xgbe_prv_data *pdata = channel->pdata; + + if (count > xgbe_tx_avail_desc(ring)) { + DBGPR(" Tx queue stopped, not enough descriptors available\n"); + netif_stop_subqueue(pdata->netdev, channel->queue_index); + ring->tx.queue_stopped = 1; + + /* If we haven't notified the hardware because of xmit_more + * support, tell it now + */ + if (ring->tx.xmit_more) + pdata->hw_if.tx_start_xmit(channel, ring); + + return NETDEV_TX_BUSY; + } + + return 0; +} + static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu) { unsigned int rx_buf_size; @@ -1199,6 +1221,8 @@ static void xgbe_packet_info(struct xgbe_prv_data *pdata, unsigned int len; unsigned int i; + packet->skb = skb; + context_desc = 0; packet->rdesc_count = 0; @@ -1447,13 +1471,9 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) xgbe_packet_info(pdata, ring, skb, packet); /* Check that there are enough descriptors available */ - if (packet->rdesc_count > xgbe_tx_avail_desc(ring)) { - DBGPR(" Tx queue stopped, not enough descriptors available\n"); - netif_stop_subqueue(netdev, channel->queue_index); - ring->tx.queue_stopped = 1; - ret = NETDEV_TX_BUSY; + ret = xgbe_maybe_stop_tx_queue(channel, ring, packet->rdesc_count); + if (ret) goto tx_netdev_return; - } ret = xgbe_prep_tso(skb, packet); if (ret) { @@ -1480,6 +1500,11 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev) xgbe_print_pkt(netdev, skb, true); #endif + /* Stop the queue in advance if there may not be enough descriptors */ + xgbe_maybe_stop_tx_queue(channel, ring, XGBE_TX_MAX_DESCS); + + ret = NETDEV_TX_OK; + tx_netdev_return: spin_unlock_irqrestore(&ring->lock, flags); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index ec0d37a917ae..eb3387398c6f 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -140,6 +140,17 @@ #define XGBE_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1)) +/* Descriptors required for maximum contigous TSO/GSO packet */ +#define XGBE_TX_MAX_SPLIT ((GSO_MAX_SIZE / XGBE_TX_MAX_BUF_SIZE) + 1) + +/* Maximum possible descriptors needed for an SKB: + * - Maximum number of SKB frags + * - Maximum descriptors for contiguous TSO/GSO packet + * - Possible context descriptor + * - Possible TSO header descriptor + */ +#define XGBE_TX_MAX_DESCS (MAX_SKB_FRAGS + XGBE_TX_MAX_SPLIT + 2) + #define XGBE_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define XGBE_RX_BUF_ALIGN 64 #define XGBE_SKB_ALLOC_SIZE 256 @@ -225,6 +236,8 @@ struct xgbe_prv_data; struct xgbe_packet_data { + struct sk_buff *skb; + unsigned int attributes; unsigned int errors; @@ -360,6 +373,7 @@ struct xgbe_ring { union { struct { unsigned int queue_stopped; + unsigned int xmit_more; unsigned short cur_mss; unsigned short cur_vlan_ctag; } tx; @@ -523,6 +537,7 @@ struct xgbe_hw_if { void (*tx_desc_reset)(struct xgbe_ring_data *); int (*is_last_desc)(struct xgbe_ring_desc *); int (*is_context_desc)(struct xgbe_ring_desc *); + void (*tx_start_xmit)(struct xgbe_channel *, struct xgbe_ring *); /* For FLOW ctrl */ int (*config_tx_flow_control)(struct xgbe_prv_data *); -- GitLab From 4dd14fe6fb8119d1d8c87127ebc74c63deb2ffc8 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 21 Nov 2014 11:18:01 -0500 Subject: [PATCH 5801/9457] drm/msm/mdp4: fix mixer setup for multi-crtc + planes On mdp4 there is a single global LAYERMIXER_IN_CFG register. The previous logic to share that between multiple crtcs didn't actually handle plane-disable very well. Easier just to look at all of the crtcs each time. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 70 ++++++++++++++---------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 7 --- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index fef22e8cabb6..6781aa994613 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -167,34 +167,54 @@ static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -static void blend_setup(struct drm_crtc *crtc) +/* statically (for now) map planes to mixer stage (z-order): */ +static const int idxs[] = { + [VG1] = 1, + [VG2] = 2, + [RGB1] = 0, + [RGB2] = 0, + [RGB3] = 0, + [VG3] = 3, + [VG4] = 4, + +}; + +/* setup mixer config, for which we need to consider all crtc's and + * the planes attached to them + * + * TODO may possibly need some extra locking here + */ +static void setup_mixer(struct mdp4_kms *mdp4_kms) { - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct mdp4_kms *mdp4_kms = get_kms(crtc); - struct drm_plane *plane; - int i, ovlp = mdp4_crtc->ovlp; + struct drm_mode_config *config = &mdp4_kms->dev->mode_config; + struct drm_crtc *crtc; uint32_t mixer_cfg = 0; static const enum mdp_mixer_stage_id stages[] = { STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3, }; - /* statically (for now) map planes to mixer stage (z-order): */ - static const int idxs[] = { - [VG1] = 1, - [VG2] = 2, - [RGB1] = 0, - [RGB2] = 0, - [RGB3] = 0, - [VG3] = 3, - [VG4] = 4, - }; - bool alpha[4]= { false, false, false, false }; + list_for_each_entry(crtc, &config->crtc_list, head) { + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct drm_plane *plane; - /* Don't rely on value read back from hw, but instead use our - * own shadowed value. Possibly disable/reenable looses the - * previous value and goes back to power-on default? - */ - mixer_cfg = mdp4_kms->mixer_cfg; + for_each_plane_on_crtc(crtc, plane) { + enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); + int idx = idxs[pipe_id]; + mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, + pipe_id, stages[idx]); + } + } + + mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); +} + +static void blend_setup(struct drm_crtc *crtc) +{ + struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); + struct mdp4_kms *mdp4_kms = get_kms(crtc); + struct drm_plane *plane; + int i, ovlp = mdp4_crtc->ovlp; + bool alpha[4]= { false, false, false, false }; mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0); mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0); @@ -209,13 +229,8 @@ static void blend_setup(struct drm_crtc *crtc) to_mdp_format(msm_framebuffer_format(plane->fb)); alpha[idx-1] = format->alpha_enable; } - mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer, - pipe_id, stages[idx]); } - /* this shouldn't happen.. and seems to cause underflow: */ - WARN_ON(!mixer_cfg); - for (i = 0; i < 4; i++) { uint32_t op; @@ -238,8 +253,7 @@ static void blend_setup(struct drm_crtc *crtc) mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0); } - mdp4_kms->mixer_cfg = mixer_cfg; - mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg); + setup_mixer(mdp4_kms); } static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 770645296f11..cbd77bc626d5 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -32,13 +32,6 @@ struct mdp4_kms { int rev; - /* Shadow value for MDP4_LAYERMIXER_IN_CFG.. since setup for all - * crtcs/encoders is in one shared register, we need to update it - * via read/modify/write. But to avoid getting confused by power- - * on-default values after resume, use this shadow value instead: - */ - uint32_t mixer_cfg; - /* mapper-id used to request GEM buffer mapped for scanout: */ int id; -- GitLab From 37dd9255b2f6201195946014600a8d857f846cf4 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Fri, 21 Nov 2014 14:16:20 +0100 Subject: [PATCH 5802/9457] vlan: Pass ethtool get_ts_info queries to real device. Commit a6111d3c "vlan: Pass SIOC[SG]HWTSTAMP ioctls to real device" intended to enable hardware time stamping on VLAN interfaces, but passing SIOCSHWTSTAMP is only half of the story. This patch adds the second half, by letting user space find out the time stamping capabilities of the device backing a VLAN interface. Signed-off-by: Richard Cochran Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index d6524b2b206a..376805005cc7 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -669,6 +670,23 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev, strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); } +static int vlan_ethtool_get_ts_info(struct net_device *dev, + struct ethtool_ts_info *info) +{ + const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); + const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops; + + if (ops->get_ts_info) { + return ops->get_ts_info(vlan->real_dev, info); + } else { + info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + info->phc_index = -1; + } + + return 0; +} + static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { struct vlan_pcpu_stats *p; @@ -752,6 +770,7 @@ static const struct ethtool_ops vlan_ethtool_ops = { .get_settings = vlan_ethtool_get_settings, .get_drvinfo = vlan_ethtool_get_drvinfo, .get_link = ethtool_op_get_link, + .get_ts_info = vlan_ethtool_get_ts_info, }; static const struct net_device_ops vlan_netdev_ops = { -- GitLab From a49493b548db635084abbdbdda2c95da9c25356c Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Fri, 21 Nov 2014 22:36:09 +0200 Subject: [PATCH 5803/9457] amdkfd: Remove DRM_AMDGPU dependency from Kconfig This patch removes the dependency of amdkfd upon DRM_AMDGPU symbol in amdkfd's Kconfig file. This is done because amdgpu driver is not yet upstreamed and therefore, DRM_AMDGPU symbol is not present in any Kconfig file. Reviewed-by: Alex Deucher Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/Kconfig b/drivers/gpu/drm/amd/amdkfd/Kconfig index e13c67c8d2c0..8dfac37ff327 100644 --- a/drivers/gpu/drm/amd/amdkfd/Kconfig +++ b/drivers/gpu/drm/amd/amdkfd/Kconfig @@ -4,6 +4,6 @@ config HSA_AMD tristate "HSA kernel driver for AMD GPU devices" - depends on (DRM_RADEON || DRM_AMDGPU) && AMD_IOMMU_V2 && X86_64 + depends on DRM_RADEON && AMD_IOMMU_V2 && X86_64 help Enable this if you want to use HSA features on AMD GPU devices. -- GitLab From 934ce1c23624526d9d784e0499190bb48113e6f4 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 19 Nov 2014 16:41:33 -0500 Subject: [PATCH 5804/9457] drm/atomic: check mode_changed *after* atomic_check The intention is that drivers can set crtc_state->mode_changed in their atomic_check() fxns if they encounter a scenario that requires full modeset. Signed-off-by: Rob Clark Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 690360038dc1..3a74e81a78df 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -331,7 +331,7 @@ mode_fixup(struct drm_atomic_state *state) } static int -drm_atomic_helper_check_prepare(struct drm_device *dev, +drm_atomic_helper_check_modeset(struct drm_device *dev, struct drm_atomic_state *state) { int ncrtcs = dev->mode_config.num_crtc; @@ -428,10 +428,6 @@ int drm_atomic_helper_check(struct drm_device *dev, int ncrtcs = dev->mode_config.num_crtc; int i, ret = 0; - ret = drm_atomic_helper_check_prepare(dev, state); - if (ret) - return ret; - for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; @@ -475,6 +471,10 @@ int drm_atomic_helper_check(struct drm_device *dev, } } + ret = drm_atomic_helper_check_modeset(dev, state); + if (ret) + return ret; + return ret; } EXPORT_SYMBOL(drm_atomic_helper_check); -- GitLab From 46df9adb2e7709e56ab8aacaff2fc997a6d17239 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 20 Nov 2014 15:40:36 -0500 Subject: [PATCH 5805/9457] drm/atomic: shutdown *current* encoder In disable_outputs() we need to shut down the outgoing encoder, not the incoming one (we have already swapped-state at this point). Without this, we end up telling the driver to crtc->dpms(OFF) without first encoder->dpms(OFF), and that makes some hw quite unhappy. v2: missing WARN_ON() hunk and comment Reviewed-by: Daniel Vetter Signed-off-by: Rob Clark --- drivers/gpu/drm/drm_atomic_helper.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 3a74e81a78df..a17b8e9c0a81 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -499,9 +499,12 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) if (!old_conn_state || !old_conn_state->crtc) continue; - encoder = connector->state->best_encoder; + encoder = old_conn_state->best_encoder; - if (!encoder) + /* We shouldn't get this far if we didn't previously have + * an encoder.. but WARN_ON() rather than explode. + */ + if (WARN_ON(!encoder)) continue; funcs = encoder->helper_private; -- GitLab From 5c1b66240b7f4abc29c618a768121d6a00f4c95a Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Sat, 8 Nov 2014 17:48:05 +0300 Subject: [PATCH 5806/9457] security: smack: fix out-of-bounds access in smk_parse_smack() Setting smack label on file (e.g. 'attr -S -s SMACK64 -V "test" test') triggered following spew on the kernel with KASan applied: ================================================================== BUG: AddressSanitizer: out of bounds access in strncpy+0x28/0x60 at addr ffff8800059ad064 ============================================================================= BUG kmalloc-8 (Not tainted): kasan error ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Slab 0xffffea0000166b40 objects=128 used=7 fp=0xffff8800059ad080 flags=0x4000000000000080 INFO: Object 0xffff8800059ad060 @offset=96 fp=0xffff8800059ad080 Bytes b4 ffff8800059ad050: a0 df 9a 05 00 88 ff ff 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ Object ffff8800059ad060: 74 65 73 74 6b 6b 6b a5 testkkk. Redzone ffff8800059ad068: cc cc cc cc cc cc cc cc ........ Padding ffff8800059ad078: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ CPU: 0 PID: 528 Comm: attr Tainted: G B 3.18.0-rc1-mm1+ #5 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 0000000000000000 ffff8800059ad064 ffffffff81534cf2 ffff880005a5bc40 ffffffff8112fe1a 0000000100800006 0000000f059ad060 ffff880006000f90 0000000000000296 ffffea0000166b40 ffffffff8107ca97 ffff880005891060 Call Trace: ? dump_stack (lib/dump_stack.c:52) ? kasan_report_error (mm/kasan/report.c:102 mm/kasan/report.c:178) ? preempt_count_sub (kernel/sched/core.c:2651) ? __asan_load1 (mm/kasan/kasan.h:50 mm/kasan/kasan.c:248 mm/kasan/kasan.c:358) ? strncpy (lib/string.c:121) ? strncpy (lib/string.c:121) ? smk_parse_smack (security/smack/smack_access.c:457) ? setxattr (fs/xattr.c:343) ? smk_import_entry (security/smack/smack_access.c:514) ? smack_inode_setxattr (security/smack/smack_lsm.c:1093 (discriminator 1)) ? security_inode_setxattr (security/security.c:602) ? vfs_setxattr (fs/xattr.c:134) ? setxattr (fs/xattr.c:343) ? setxattr (fs/xattr.c:360) ? get_parent_ip (kernel/sched/core.c:2606) ? preempt_count_sub (kernel/sched/core.c:2651) ? __percpu_counter_add (arch/x86/include/asm/preempt.h:98 lib/percpu_counter.c:90) ? get_parent_ip (kernel/sched/core.c:2606) ? preempt_count_sub (kernel/sched/core.c:2651) ? __mnt_want_write (arch/x86/include/asm/preempt.h:98 fs/namespace.c:359) ? path_setxattr (fs/xattr.c:380) ? SyS_lsetxattr (fs/xattr.c:397) ? system_call_fastpath (arch/x86/kernel/entry_64.S:423) Read of size 1 by task attr: Memory state around the buggy address: ffff8800059ace80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff8800059acf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff8800059acf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff8800059ad000: 00 fc fc fc 00 fc fc fc 05 fc fc fc 04 fc fc fc ^ ffff8800059ad080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8800059ad100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8800059ad180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== strncpy() copies one byte more than the source string has. Fix this by passing the correct length to strncpy(). Now we can remove initialization of the last byte in 'smack' string because kzalloc() already did this for us. Signed-off-by: Andrey Ryabinin --- security/smack/smack_access.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 999224fe8593..1158430f5bb9 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -452,10 +452,9 @@ char *smk_parse_smack(const char *string, int len) return NULL; smack = kzalloc(i + 1, GFP_KERNEL); - if (smack != NULL) { - strncpy(smack, string, i + 1); - smack[i] = '\0'; - } + if (smack != NULL) + strncpy(smack, string, i); + return smack; } -- GitLab From a65da0c3dac6e2d4f8ecf0aee8b0abe10001f2d9 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 21 Nov 2014 14:09:52 +0000 Subject: [PATCH 5807/9457] defxx: Fix DEFPA enable error propagation Correctly propagate the error code from `pci_enable_device' if non zero. Currently a failure of this function is correctly recognized and device initialization abandoned, however a successful completion code returned. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index caed6eee289c..d8d4f3d3ca32 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -542,10 +542,13 @@ static int dfx_register(struct device *bdev) } /* Enable PCI device. */ - if (dfx_bus_pci && pci_enable_device(to_pci_dev(bdev))) { - printk(KERN_ERR "%s: Cannot enable PCI device, aborting\n", - print_name); - goto err_out; + if (dfx_bus_pci) { + err = pci_enable_device(to_pci_dev(bdev)); + if (err) { + pr_err("%s: Cannot enable PCI device, aborting\n", + print_name); + goto err_out; + } } SET_NETDEV_DEV(dev, bdev); -- GitLab From fef85fc466ec1f4400a902049a519948f6b40979 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 21 Nov 2014 14:09:57 +0000 Subject: [PATCH 5808/9457] defxx: Correct DEFEA's ESIC MMIO decoding Use ESIC's memory area 1 (MEMCS1) and its Memory Address High Compare and Memory Address Low Compare registers to set up the MMIO range for decoding accesses to PDQ ASIC registers. Previously the PDQ ASIC was thought to be addressable with the memory area 0 (MEMCS0) and its Memory Address Compare and Memory Address Mask registers. The MMIO range allocated for the option card is preset via ECU (EISA Configuration Utility) and can be disabled, so handle such a case gracefully too. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 61 +++++++++++++++++++++++++--------------- drivers/net/fddi/defxx.h | 2 +- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index d8d4f3d3ca32..75d54ea72c56 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -447,23 +447,24 @@ static void dfx_get_bars(struct device *bdev, } if (dfx_bus_eisa) { unsigned long base_addr = to_eisa_device(bdev)->base_addr; - resource_size_t bar; + resource_size_t bar_lo; + resource_size_t bar_hi; if (dfx_use_mmio) { - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_0); - bar <<= 16; - *bar_start = bar; - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_0); - bar <<= 16; - *bar_len = (bar | PI_MEM_ADD_MASK_M) + 1; + bar_lo = inb(base_addr + PI_ESIC_K_MEM_ADD_LO_CMP_2); + bar_lo <<= 8; + bar_lo |= inb(base_addr + PI_ESIC_K_MEM_ADD_LO_CMP_1); + bar_lo <<= 8; + bar_lo |= inb(base_addr + PI_ESIC_K_MEM_ADD_LO_CMP_0); + bar_lo <<= 8; + *bar_start = bar_lo; + bar_hi = inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_2); + bar_hi <<= 8; + bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_1); + bar_hi <<= 8; + bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_0); + bar_hi <<= 8; + *bar_len = ((bar_hi - bar_lo) | PI_MEM_ADD_MASK_M) + 1; } else { *bar_start = base_addr; *bar_len = PI_ESIC_K_CSR_IO_LEN + @@ -518,6 +519,7 @@ static int dfx_register(struct device *bdev) { static int version_disp; int dfx_bus_pci = dev_is_pci(bdev); + int dfx_bus_eisa = DFX_BUS_EISA(bdev); int dfx_bus_tc = DFX_BUS_TC(bdev); int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; const char *print_name = dev_name(bdev); @@ -558,6 +560,16 @@ static int dfx_register(struct device *bdev) dev_set_drvdata(bdev, dev); dfx_get_bars(bdev, &bar_start, &bar_len); + if (dfx_bus_eisa && dfx_use_mmio && bar_start == 0) { + pr_err("%s: Cannot use MMIO, no address set, aborting\n", + print_name); + pr_err("%s: Run ECU and set adapter's MMIO location\n", + print_name); + pr_err("%s: Or recompile driver with \"CONFIG_DEFXX_MMIO=n\"" + "\n", print_name); + err = -ENXIO; + goto err_out; + } if (dfx_use_mmio) region = request_mem_region(bar_start, bar_len, print_name); @@ -714,13 +726,14 @@ static void dfx_bus_init(struct net_device *dev) } /* - * Enable memory decoding (MEMCS0) and/or port decoding + * Enable memory decoding (MEMCS1) and/or port decoding * (IOCS1/IOCS0) as appropriate in Function Control - * Register. IOCS0 is used for PDQ registers, taking 16 - * 32-bit words, while IOCS1 is used for the Burst Holdoff - * register, taking a single 32-bit word only. We use the - * slot-specific I/O range as per the ESIC spec, that is - * set bits 15:12 in the mask registers to mask them out. + * Register. MEMCS1 or IOCS0 is used for PDQ registers, + * taking 16 32-bit words, while IOCS1 is used for the + * Burst Holdoff register, taking a single 32-bit word + * only. We use the slot-specific I/O range as per the + * ESIC spec, that is set bits 15:12 in the mask registers + * to mask them out. */ /* Set the decode range of the board. */ @@ -745,9 +758,11 @@ static void dfx_bus_init(struct net_device *dev) outb(val, base_addr + PI_ESIC_K_IO_ADD_MASK_1_0); /* Enable the decoders. */ - val = PI_FUNCTION_CNTRL_M_IOCS1 | PI_FUNCTION_CNTRL_M_IOCS0; + val = PI_FUNCTION_CNTRL_M_IOCS1; if (dfx_use_mmio) - val |= PI_FUNCTION_CNTRL_M_MEMCS0; + val |= PI_FUNCTION_CNTRL_M_MEMCS1; + else + val |= PI_FUNCTION_CNTRL_M_IOCS0; outb(val, base_addr + PI_ESIC_K_FUNCTION_CNTRL); /* diff --git a/drivers/net/fddi/defxx.h b/drivers/net/fddi/defxx.h index 9527f0182fd4..16fe8049b238 100644 --- a/drivers/net/fddi/defxx.h +++ b/drivers/net/fddi/defxx.h @@ -1556,7 +1556,7 @@ typedef union #define PI_BURST_HOLDOFF_V_RESERVED 1 #define PI_BURST_HOLDOFF_V_MEM_MAP 0 -/* Define the implicit mask of the Memory Address Mask Register. */ +/* Define the implicit mask of the Memory Address Compare registers. */ #define PI_MEM_ADD_MASK_M 0x3ff -- GitLab From 6a931423c918633d4d0cda96df042d7e44ad06b0 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 21 Nov 2014 14:10:02 +0000 Subject: [PATCH 5809/9457] defxx: Disable DEFEA's ESIC I/O decoding on shutdown Make sure the option card does not respond after shutdown by disabling it via ESIC's Expansion Board Control register. Also disable memory and port I/O decoders, the latter in particular to disable slot-specific I/O decoding that otherwise remains active even in the board is disabled. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index 75d54ea72c56..d057d9c2cf5e 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -856,6 +856,12 @@ static void dfx_bus_uninit(struct net_device *dev) val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); val &= ~PI_CONFIG_STAT_0_M_INT_ENB; outb(val, base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); + + /* Disable the board. */ + outb(0, base_addr + PI_ESIC_K_SLOT_CNTRL); + + /* Disable memory and port decoders. */ + outb(0, base_addr + PI_ESIC_K_FUNCTION_CNTRL); } if (dfx_bus_pci) { /* Disable interrupts at PCI bus interface chip (PFI) */ -- GitLab From 4d0438e56a8f9a1a18ba31bd53b9dc67af224980 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 21 Nov 2014 14:10:08 +0000 Subject: [PATCH 5810/9457] defxx: Clean up DEFEA resource management Reserve DEFEA resources according to actual use. There are three regions, for the ESIC ASIC's CSRs, for the discrete Burst Holdoff register, and for the PDQ ASIC's CSRs. The latter is mapped in the memory or port I/O address space depending on configuration. The two formers are hardwired and always mapped in the port I/O address space. Signed-off-by: Maciej W. Rozycki Signed-off-by: David S. Miller --- drivers/net/fddi/defxx.c | 115 ++++++++++++++++++++++++++------------- drivers/net/fddi/defxx.h | 2 + 2 files changed, 80 insertions(+), 37 deletions(-) diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index d057d9c2cf5e..7f975a2c8990 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c @@ -414,7 +414,7 @@ static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data) * ================ * * Overview: - * Retrieves the address range used to access control and status + * Retrieves the address ranges used to access control and status * registers. * * Returns: @@ -422,8 +422,8 @@ static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data) * * Arguments: * bdev - pointer to device information - * bar_start - pointer to store the start address - * bar_len - pointer to store the length of the area + * bar_start - pointer to store the start addresses + * bar_len - pointer to store the lengths of the areas * * Assumptions: * I am sure there are some. @@ -442,8 +442,10 @@ static void dfx_get_bars(struct device *bdev, if (dfx_bus_pci) { int num = dfx_use_mmio ? 0 : 1; - *bar_start = pci_resource_start(to_pci_dev(bdev), num); - *bar_len = pci_resource_len(to_pci_dev(bdev), num); + bar_start[0] = pci_resource_start(to_pci_dev(bdev), num); + bar_len[0] = pci_resource_len(to_pci_dev(bdev), num); + bar_start[2] = bar_start[1] = 0; + bar_len[2] = bar_len[1] = 0; } if (dfx_bus_eisa) { unsigned long base_addr = to_eisa_device(bdev)->base_addr; @@ -457,24 +459,30 @@ static void dfx_get_bars(struct device *bdev, bar_lo <<= 8; bar_lo |= inb(base_addr + PI_ESIC_K_MEM_ADD_LO_CMP_0); bar_lo <<= 8; - *bar_start = bar_lo; + bar_start[0] = bar_lo; bar_hi = inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_2); bar_hi <<= 8; bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_1); bar_hi <<= 8; bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_0); bar_hi <<= 8; - *bar_len = ((bar_hi - bar_lo) | PI_MEM_ADD_MASK_M) + 1; + bar_len[0] = ((bar_hi - bar_lo) | PI_MEM_ADD_MASK_M) + + 1; } else { - *bar_start = base_addr; - *bar_len = PI_ESIC_K_CSR_IO_LEN + - PI_ESIC_K_BURST_HOLDOFF_LEN; + bar_start[0] = base_addr; + bar_len[0] = PI_ESIC_K_CSR_IO_LEN; } + bar_start[1] = base_addr + PI_DEFEA_K_BURST_HOLDOFF; + bar_len[1] = PI_ESIC_K_BURST_HOLDOFF_LEN; + bar_start[2] = base_addr + PI_ESIC_K_ESIC_CSR; + bar_len[2] = PI_ESIC_K_ESIC_CSR_LEN; } if (dfx_bus_tc) { - *bar_start = to_tc_dev(bdev)->resource.start + - PI_TC_K_CSR_OFFSET; - *bar_len = PI_TC_K_CSR_LEN; + bar_start[0] = to_tc_dev(bdev)->resource.start + + PI_TC_K_CSR_OFFSET; + bar_len[0] = PI_TC_K_CSR_LEN; + bar_start[2] = bar_start[1] = 0; + bar_len[2] = bar_len[1] = 0; } } @@ -525,8 +533,8 @@ static int dfx_register(struct device *bdev) const char *print_name = dev_name(bdev); struct net_device *dev; DFX_board_t *bp; /* board pointer */ - resource_size_t bar_start = 0; /* pointer to port */ - resource_size_t bar_len = 0; /* resource length */ + resource_size_t bar_start[3]; /* pointers to ports */ + resource_size_t bar_len[3]; /* resource length */ int alloc_size; /* total buffer size used */ struct resource *region; int err = 0; @@ -559,8 +567,8 @@ static int dfx_register(struct device *bdev) bp->bus_dev = bdev; dev_set_drvdata(bdev, dev); - dfx_get_bars(bdev, &bar_start, &bar_len); - if (dfx_bus_eisa && dfx_use_mmio && bar_start == 0) { + dfx_get_bars(bdev, bar_start, bar_len); + if (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0) { pr_err("%s: Cannot use MMIO, no address set, aborting\n", print_name); pr_err("%s: Run ECU and set adapter's MMIO location\n", @@ -572,28 +580,49 @@ static int dfx_register(struct device *bdev) } if (dfx_use_mmio) - region = request_mem_region(bar_start, bar_len, print_name); + region = request_mem_region(bar_start[0], bar_len[0], + print_name); else - region = request_region(bar_start, bar_len, print_name); + region = request_region(bar_start[0], bar_len[0], print_name); if (!region) { - printk(KERN_ERR "%s: Cannot reserve I/O resource " - "0x%lx @ 0x%lx, aborting\n", - print_name, (long)bar_len, (long)bar_start); + pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, " + "aborting\n", dfx_use_mmio ? "MMIO" : "I/O", print_name, + (long)bar_len[0], (long)bar_start[0]); err = -EBUSY; goto err_out_disable; } + if (bar_start[1] != 0) { + region = request_region(bar_start[1], bar_len[1], print_name); + if (!region) { + pr_err("%s: Cannot reserve I/O resource " + "0x%lx @ 0x%lx, aborting\n", print_name, + (long)bar_len[1], (long)bar_start[1]); + err = -EBUSY; + goto err_out_csr_region; + } + } + if (bar_start[2] != 0) { + region = request_region(bar_start[2], bar_len[2], print_name); + if (!region) { + pr_err("%s: Cannot reserve I/O resource " + "0x%lx @ 0x%lx, aborting\n", print_name, + (long)bar_len[2], (long)bar_start[2]); + err = -EBUSY; + goto err_out_bh_region; + } + } /* Set up I/O base address. */ if (dfx_use_mmio) { - bp->base.mem = ioremap_nocache(bar_start, bar_len); + bp->base.mem = ioremap_nocache(bar_start[0], bar_len[0]); if (!bp->base.mem) { printk(KERN_ERR "%s: Cannot map MMIO\n", print_name); err = -ENOMEM; - goto err_out_region; + goto err_out_esic_region; } } else { - bp->base.port = bar_start; - dev->base_addr = bar_start; + bp->base.port = bar_start[0]; + dev->base_addr = bar_start[0]; } /* Initialize new device structure */ @@ -602,7 +631,7 @@ static int dfx_register(struct device *bdev) if (dfx_bus_pci) pci_set_master(to_pci_dev(bdev)); - if (dfx_driver_init(dev, print_name, bar_start) != DFX_K_SUCCESS) { + if (dfx_driver_init(dev, print_name, bar_start[0]) != DFX_K_SUCCESS) { err = -ENODEV; goto err_out_unmap; } @@ -630,11 +659,19 @@ static int dfx_register(struct device *bdev) if (dfx_use_mmio) iounmap(bp->base.mem); -err_out_region: +err_out_esic_region: + if (bar_start[2] != 0) + release_region(bar_start[2], bar_len[2]); + +err_out_bh_region: + if (bar_start[1] != 0) + release_region(bar_start[1], bar_len[1]); + +err_out_csr_region: if (dfx_use_mmio) - release_mem_region(bar_start, bar_len); + release_mem_region(bar_start[0], bar_len[0]); else - release_region(bar_start, bar_len); + release_region(bar_start[0], bar_len[0]); err_out_disable: if (dfx_bus_pci) @@ -1085,8 +1122,8 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name, board_name = "DEFEA"; if (dfx_bus_pci) board_name = "DEFPA"; - pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n", - print_name, board_name, dfx_use_mmio ? "" : "I/O ", + pr_info("%s: %s at %s addr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n", + print_name, board_name, dfx_use_mmio ? "MMIO" : "I/O", (long long)bar_start, dev->irq, dev->dev_addr); /* @@ -3660,8 +3697,8 @@ static void dfx_unregister(struct device *bdev) int dfx_bus_pci = dev_is_pci(bdev); int dfx_bus_tc = DFX_BUS_TC(bdev); int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - resource_size_t bar_start = 0; /* pointer to port */ - resource_size_t bar_len = 0; /* resource length */ + resource_size_t bar_start[3]; /* pointers to ports */ + resource_size_t bar_len[3]; /* resource lengths */ int alloc_size; /* total buffer size used */ unregister_netdev(dev); @@ -3679,12 +3716,16 @@ static void dfx_unregister(struct device *bdev) dfx_bus_uninit(dev); - dfx_get_bars(bdev, &bar_start, &bar_len); + dfx_get_bars(bdev, bar_start, bar_len); + if (bar_start[2] != 0) + release_region(bar_start[2], bar_len[2]); + if (bar_start[1] != 0) + release_region(bar_start[1], bar_len[1]); if (dfx_use_mmio) { iounmap(bp->base.mem); - release_mem_region(bar_start, bar_len); + release_mem_region(bar_start[0], bar_len[0]); } else - release_region(bar_start, bar_len); + release_region(bar_start[0], bar_len[0]); if (dfx_bus_pci) pci_disable_device(to_pci_dev(bdev)); diff --git a/drivers/net/fddi/defxx.h b/drivers/net/fddi/defxx.h index 16fe8049b238..9d30fde2ef3c 100644 --- a/drivers/net/fddi/defxx.h +++ b/drivers/net/fddi/defxx.h @@ -1481,9 +1481,11 @@ typedef union #define PI_ESIC_K_CSR_IO_LEN 0x40 /* 64 bytes */ #define PI_ESIC_K_BURST_HOLDOFF_LEN 0x04 /* 4 bytes */ +#define PI_ESIC_K_ESIC_CSR_LEN 0x40 /* 64 bytes */ #define PI_DEFEA_K_CSR_IO 0x000 #define PI_DEFEA_K_BURST_HOLDOFF 0x040 +#define PI_ESIC_K_ESIC_CSR 0xC80 #define PI_ESIC_K_SLOT_ID 0xC80 #define PI_ESIC_K_SLOT_CNTRL 0xC84 -- GitLab From ec5fc1c1bdf0c445d2669ca9e1dbb69c9725856a Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Tue, 18 Nov 2014 16:50:08 -0800 Subject: [PATCH 5811/9457] HID: wacom: Report ABS_TILT_{X,Y} as signed values Centers the ABS_TILT_{X,Y} axes so that a value of zero is reported when the pen is vertical. Combined with resolution information in the next patch, this makes it possible for userspace to calculate the pen angle without needing hardware-specific knowledge. The xf86-input-wacom driver was updated to support signed tilt values in late-2012 (2f2acec). Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index caf035f662b9..74c9fbde5695 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -600,8 +600,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) } input_report_abs(input, ABS_PRESSURE, t); input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); + (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); input_report_key(input, BTN_STYLUS, data[1] & 2); input_report_key(input, BTN_STYLUS2, data[1] & 4); input_report_key(input, BTN_TOUCH, t > 10); @@ -612,8 +612,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom) input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); + (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); } } @@ -915,8 +915,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_EXTRA, data[6] & 0x10); input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); + (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); + input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); } else { /* 2D mouse packet */ input_report_key(input, BTN_LEFT, data[8] & 0x04); @@ -1929,8 +1929,8 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features.distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); } static void wacom_setup_intuos(struct wacom_wac *wacom_wac) -- GitLab From 26fe41245f43c86f65cae272a2851dd792e443f7 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Tue, 18 Nov 2014 16:50:09 -0800 Subject: [PATCH 5812/9457] HID: wacom: Add angular resolution data to some ABS axes Provide the resolution of several angular axes (tilt, pen rotation, puck rotation) to userspace. Because these values are natively degree-based, we need to convert them to into units/radian as required by the input_absinfo struct. To ensure wraparound behaves properly for the rotation axes, the converted value was rounded up rather than rounded nearest. Notably, the touchring axes (ABS_WHEEL and ABS_THROTTLE) are left without a a declared resolution because the their low resolution cannot be accurately represented (the worst-case rounding-induced error would be ~16 degrees). Pre-scaling the values and range by at least 10x would reduce the error in the resolution to acceptable levels, but the xf86-input-wacom driver is not able to use pre-scaled values for these axes at this time. Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 74c9fbde5695..9565d31262ec 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1930,7 +1930,9 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) 0, wacom_wac->features.distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); + input_abs_set_res(input_dev, ABS_TILT_X, 57); input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); + input_abs_set_res(input_dev, ABS_TILT_Y, 57); } static void wacom_setup_intuos(struct wacom_wac *wacom_wac) @@ -1950,6 +1952,7 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) __set_bit(BTN_TOOL_LENS, input_dev->keybit); input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_RZ, 287); input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); } @@ -2092,6 +2095,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case WACOM_24HD: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); /* fall through */ @@ -2106,6 +2110,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case WACOM_BEE: case CINTIQ: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); @@ -2114,6 +2119,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case WACOM_13HD: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); wacom_setup_cintiq(wacom_wac); break; @@ -2122,6 +2128,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case INTUOS3L: case INTUOS3S: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); /* fall through */ case INTUOS: @@ -2144,6 +2151,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, 0, 0); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); wacom_setup_intuos(wacom_wac); } else if (features->device_type == BTN_TOOL_FINGER) { @@ -2162,6 +2170,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case INTUOS4L: case INTUOS4S: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); wacom_setup_intuos(wacom_wac); __set_bit(INPUT_PROP_POINTER, input_dev->propbit); @@ -2264,6 +2273,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case CINTIQ_HYBRID: input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); wacom_setup_cintiq(wacom_wac); -- GitLab From 14cd7923122c7c4473848f7c737604bfe945b81b Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Sat, 22 Nov 2014 04:50:33 +0800 Subject: [PATCH 5813/9457] ASoC: Intel: chv_platform_data can be static sound/soc/intel/sst/sst_acpi.c:135:26: sparse: symbol 'chv_platform_data' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index 3f29721625cc..31124aa4434e 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c @@ -132,7 +132,7 @@ static struct sst_platform_info byt_rvp_platform_data = { /* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail, * so pdata is same as Baytrail. */ -struct sst_platform_info chv_platform_data = { +static struct sst_platform_info chv_platform_data = { .probe_data = &byt_fwparse_info, .ipc_info = &byt_ipc_info, .lib_info = &byt_lib_dnld_info, -- GitLab From 52d21580b3623e0b5f0b8de5d67b5431507720e5 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 22 Oct 2014 21:25:39 +0200 Subject: [PATCH 5814/9457] ktest: Use make -s kernelrelease The previous tail -1 broke with commit 7ff525712acf ("kbuild: fake the "Entering directory ..." message more simply") Link: http://lkml.kernel.org/r/20141022194408.GA20989@pobox.suse.cz Reported-by: Steven Rostedt Signed-off-by: Michal Marek Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index bf1398180785..60fe020a6e80 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -2005,7 +2005,7 @@ sub get_version { # get the release name return if ($have_version); doprint "$make kernelrelease ... "; - $version = `$make kernelrelease | tail -1`; + $version = `$make -s kernelrelease`; chomp($version); doprint "$version\n"; $have_version = 1; -- GitLab From 9972fc0b859e7aaeb6d2d33bdb591959d9a436c0 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 22 Oct 2014 10:11:47 -0400 Subject: [PATCH 5815/9457] ktest: Fix make_min_config to handle new assign_configs call Commit 6071c22e1755 "ktest: Rewrite the config-bisect to actually work" fixed the config-bisect to work nicely but in doing so it broke make_min_config by changing the way assign_configs works. The assign_configs function now adds the config to the hash even if it is disabled, but changes the hash value to be that of the line "# CONFIG_FOO is not set". Unfortunately, the make_min_config test only checks to see if the config is removed. It now needs to check if the config is in the hash and not set to be disabled. Cc: stable@vger.kernel.org # 3.17+ Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 60fe020a6e80..89c2257bed98 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -3571,7 +3571,9 @@ sub test_this_config { undef %configs; assign_configs \%configs, $output_config; - return $config if (!defined($configs{$config})); + if (!defined($configs{$config}) || $configs{$config} =~ /^#/) { + return $config; + } doprint "disabling config $config did not change .config\n"; -- GitLab From 22c37a9ac49d0bf3ec384cdbc60a5600d48e298e Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 21 Nov 2014 16:21:25 -0500 Subject: [PATCH 5816/9457] ktest: Allow tests to undefine default options Tests can set options that override the default ones. But if a test tries to undefine a default option, it is simply ignored and the default option stays as is. For example, if you want to have a test that defines no MIN_CONFIG then the test should be able to do that with: TEST_START MIN_CONFIG = Which should make MIN_CONFIG not defined for that test. But the way the code currently works, undefined options in tests are dropped. This is because the NULL options are evaluated during the reading of the config file and since one can disable default options in the default section with this method, it is evaluated there (the option turns to a undef). But undef options in the test section mean to use the default option. To fix this, keep the empty string in the option during the reading of the config file, and then evaluate it when running the test. This will allow tests to null out default options. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 89c2257bed98..ea43dd2f2fd5 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -684,11 +684,8 @@ sub set_value { } ${$overrides}{$lvalue} = $prvalue; } - if ($rvalue =~ /^\s*$/) { - delete $opt{$lvalue}; - } else { - $opt{$lvalue} = $prvalue; - } + + $opt{$lvalue} = $prvalue; } sub set_eval { @@ -3947,12 +3944,22 @@ for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { } } +sub option_defined { + my ($option) = @_; + + if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) { + return 1; + } + + return 0; +} + sub __set_test_option { my ($name, $i) = @_; my $option = "$name\[$i\]"; - if (defined($opt{$option})) { + if (option_defined($option)) { return $opt{$option}; } @@ -3960,13 +3967,13 @@ sub __set_test_option { if ($i >= $test && $i < $test + $repeat_tests{$test}) { $option = "$name\[$test\]"; - if (defined($opt{$option})) { + if (option_defined($option)) { return $opt{$option}; } } } - if (defined($opt{$name})) { + if (option_defined($name)) { return $opt{$name}; } -- GitLab From 18656c7099c627bdf8579b21dea512e0a8addbb9 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 21 Nov 2014 19:28:24 -0500 Subject: [PATCH 5817/9457] ktest: Add name to running title Instead of just showing the test type of test in the start of the test, like this: RUNNING TEST 1 of 26 with option build defconfig Add the name (if it is defined) as well, like this: RUNNING TEST 1 of 26 (arm64 aarch64-linux) with option build defconfig Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ea43dd2f2fd5..35b118a38c2f 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -4086,8 +4086,14 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { my $installme = ""; $installme = " no_install" if ($no_install); + my $name = ""; + + if (defined($test_name)) { + $name = " ($test_name)"; + } + doprint "\n\n"; - doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n"; if (defined($pre_test)) { run_command $pre_test; -- GitLab From c78b47136f7adebcf953f541c7d9c4c745a54e3f Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 21 Nov 2014 15:16:32 -0700 Subject: [PATCH 5818/9457] NVMe: Update module version major number It's already near impossible to tell what bits someone is running based on a 'modinfo nvme', and I don't want to try guessing if someone is running blk-mq or bio-based. Let's make it obvious with the module version that the blk-mq conversion is a major change. Future bio-based versions can increment to 0.10 in a fork if revisions occur. Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/block/nvme-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index c1541652b7e0..c7ea07ce9372 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -2888,6 +2888,6 @@ static void __exit nvme_exit(void) MODULE_AUTHOR("Matthew Wilcox "); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.9"); +MODULE_VERSION("1.0"); module_init(nvme_init); module_exit(nvme_exit); -- GitLab From 61211b1bda0321803fdedc61158c55eab2685ad6 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:19 +0200 Subject: [PATCH 5819/9457] phy: twl4030: use the new lookup method Creates the lookup separately. Hard coding the consumer as it can't be anything else except musb. Signed-off-by: Heikki Krogerus Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-twl4030-usb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 7b04befd5271..c45a3aa4f2cc 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -644,7 +644,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) struct usb_otg *otg; struct device_node *np = pdev->dev.of_node; struct phy_provider *phy_provider; - struct phy_init_data *init_data = NULL; twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); if (!twl) @@ -655,7 +654,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) (enum twl4030_usb_mode *)&twl->usb_mode); else if (pdata) { twl->usb_mode = pdata->usb_mode; - init_data = pdata->init_data; } else { dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); return -EINVAL; @@ -680,7 +678,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; - phy = devm_phy_create(twl->dev, NULL, &ops, init_data); + phy = devm_phy_create(twl->dev, NULL, &ops, NULL); if (IS_ERR(phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); return PTR_ERR(phy); @@ -733,6 +731,11 @@ static int twl4030_usb_probe(struct platform_device *pdev) return status; } + if (pdata) + err = phy_create_lookup(phy, "usb", "musb-hdrc.0"); + if (err) + return err; + pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(twl->dev); -- GitLab From dbc98635e0d42f0e62ea92813df1e0e4c90f8375 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:21 +0200 Subject: [PATCH 5820/9457] phy: remove the old lookup method The users of the old method are now converted to the new one. Signed-off-by: Heikki Krogerus [ kishon@ti.com : made phy-berlin-usb.c and phy-miphy28lp.c to use the updated devm_phy_create API.] Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-bcm-kona-usb2.c | 2 +- drivers/phy/phy-berlin-sata.c | 2 +- drivers/phy/phy-berlin-usb.c | 3 +- drivers/phy/phy-core.c | 49 +++------------------------- drivers/phy/phy-exynos-dp-video.c | 2 +- drivers/phy/phy-exynos-mipi-video.c | 2 +- drivers/phy/phy-exynos5-usbdrd.c | 3 +- drivers/phy/phy-exynos5250-sata.c | 2 +- drivers/phy/phy-hix5hd2-sata.c | 2 +- drivers/phy/phy-miphy28lp.c | 2 +- drivers/phy/phy-miphy365x.c | 2 +- drivers/phy/phy-mvebu-sata.c | 2 +- drivers/phy/phy-omap-usb2.c | 2 +- drivers/phy/phy-qcom-apq8064-sata.c | 3 +- drivers/phy/phy-qcom-ipq806x-sata.c | 3 +- drivers/phy/phy-rcar-gen2.c | 2 +- drivers/phy/phy-samsung-usb2.c | 3 +- drivers/phy/phy-spear1310-miphy.c | 2 +- drivers/phy/phy-spear1340-miphy.c | 2 +- drivers/phy/phy-stih407-usb.c | 2 +- drivers/phy/phy-stih41x-usb.c | 2 +- drivers/phy/phy-sun4i-usb.c | 2 +- drivers/phy/phy-ti-pipe3.c | 2 +- drivers/phy/phy-twl4030-usb.c | 2 +- drivers/phy/phy-xgene.c | 2 +- drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +-- include/linux/phy/phy.h | 38 +++------------------ 27 files changed, 34 insertions(+), 110 deletions(-) diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c index c1e0ca335c0e..ef2dc1aab2b9 100644 --- a/drivers/phy/phy-bcm-kona-usb2.c +++ b/drivers/phy/phy-bcm-kona-usb2.c @@ -117,7 +117,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev) platform_set_drvdata(pdev, phy); - gphy = devm_phy_create(dev, NULL, &ops, NULL); + gphy = devm_phy_create(dev, NULL, &ops); if (IS_ERR(gphy)) return PTR_ERR(gphy); diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c index 873e7a890fee..3e599dc96164 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/phy-berlin-sata.c @@ -249,7 +249,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev) if (!phy_desc) return -ENOMEM; - phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops, NULL); + phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops); if (IS_ERR(phy)) { dev_err(dev, "failed to create PHY %d\n", phy_id); return PTR_ERR(phy); diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index f9f13067f50f..c8a8d53a6ece 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c @@ -192,8 +192,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) priv->pll_divider = *((u32 *)match->data); - priv->phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops, - NULL); + priv->phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); if (IS_ERR(priv->phy)) { dev_err(&pdev->dev, "failed to create PHY\n"); return PTR_ERR(priv->phy); diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index bc830773fe05..a12d35338313 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -55,36 +55,6 @@ static int devm_phy_match(struct device *dev, void *res, void *match_data) return res == match_data; } -static struct phy *phy_lookup(struct device *device, const char *port) -{ - unsigned int count; - struct phy *phy; - struct device *dev; - struct phy_consumer *consumers; - struct class_dev_iter iter; - - class_dev_iter_init(&iter, phy_class, NULL, NULL); - while ((dev = class_dev_iter_next(&iter))) { - phy = to_phy(dev); - - if (!phy->init_data) - continue; - count = phy->init_data->num_consumers; - consumers = phy->init_data->consumers; - while (count--) { - if (!strcmp(consumers->dev_name, dev_name(device)) && - !strcmp(consumers->port, port)) { - class_dev_iter_exit(&iter); - return phy; - } - consumers++; - } - } - - class_dev_iter_exit(&iter); - return ERR_PTR(-ENODEV); -} - /** * phy_create_lookup() - allocate and register PHY/device association * @phy: the phy of the association @@ -148,7 +118,6 @@ static struct phy *phy_find(struct device *dev, const char *con_id) { const char *dev_id = dev_name(dev); struct phy_lookup *p, *pl = NULL; - struct phy *phy; mutex_lock(&phy_provider_mutex); list_for_each_entry(p, &phys, node) @@ -158,12 +127,7 @@ static struct phy *phy_find(struct device *dev, const char *con_id) } mutex_unlock(&phy_provider_mutex); - phy = pl ? pl->phy : ERR_PTR(-ENODEV); - - /* fall-back to the old lookup method for now */ - if (IS_ERR(phy)) - phy = phy_lookup(dev, con_id); - return phy; + return pl ? pl->phy : ERR_PTR(-ENODEV); } static struct phy_provider *of_phy_provider_lookup(struct device_node *node) @@ -662,13 +626,11 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get); * @dev: device that is creating the new phy * @node: device node of the phy * @ops: function pointers for performing phy operations - * @init_data: contains the list of PHY consumers or NULL * * Called to create a phy using phy framework. */ struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) + const struct phy_ops *ops) { int ret; int id; @@ -706,7 +668,6 @@ struct phy *phy_create(struct device *dev, struct device_node *node, phy->dev.of_node = node ?: dev->of_node; phy->id = id; phy->ops = ops; - phy->init_data = init_data; ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id); if (ret) @@ -741,7 +702,6 @@ EXPORT_SYMBOL_GPL(phy_create); * @dev: device that is creating the new phy * @node: device node of the phy * @ops: function pointers for performing phy operations - * @init_data: contains the list of PHY consumers or NULL * * Creates a new PHY device adding it to the PHY class. * While at that, it also associates the device with the phy using devres. @@ -749,8 +709,7 @@ EXPORT_SYMBOL_GPL(phy_create); * then, devres data is freed. */ struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) + const struct phy_ops *ops) { struct phy **ptr, *phy; @@ -758,7 +717,7 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node, if (!ptr) return ERR_PTR(-ENOMEM); - phy = phy_create(dev, node, ops, init_data); + phy = phy_create(dev, node, ops); if (!IS_ERR(phy)) { *ptr = phy; devres_add(dev, ptr); diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 84f49e5a3f24..f86cbe68ddaf 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c @@ -112,7 +112,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) match = of_match_node(exynos_dp_video_phy_of_match, dev->of_node); state->drvdata = match->data; - phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL); + phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops); if (IS_ERR(phy)) { dev_err(dev, "failed to create Display Port PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 6a9bef138617..943e0f88a120 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c @@ -137,7 +137,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { struct phy *phy = devm_phy_create(dev, NULL, - &exynos_mipi_video_phy_ops, NULL); + &exynos_mipi_video_phy_ops); if (IS_ERR(phy)) { dev_err(dev, "failed to create PHY %d\n", i); return PTR_ERR(phy); diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index f756aca871db..b3ca3bc2314f 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c @@ -637,8 +637,7 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) { struct phy *phy = devm_phy_create(dev, NULL, - &exynos5_usbdrd_phy_ops, - NULL); + &exynos5_usbdrd_phy_ops); if (IS_ERR(phy)) { dev_err(dev, "Failed to create usbdrd_phy phy\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c index 54cf4ae60d29..bc858cc800a1 100644 --- a/drivers/phy/phy-exynos5250-sata.c +++ b/drivers/phy/phy-exynos5250-sata.c @@ -210,7 +210,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) return ret; } - sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops, NULL); + sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops); if (IS_ERR(sata_phy->phy)) { clk_disable_unprepare(sata_phy->phyclk); dev_err(dev, "failed to create PHY\n"); diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c index d5d978085c6d..a80ff9d7fe15 100644 --- a/drivers/phy/phy-hix5hd2-sata.c +++ b/drivers/phy/phy-hix5hd2-sata.c @@ -156,7 +156,7 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev) if (IS_ERR(priv->peri_ctrl)) priv->peri_ctrl = NULL; - phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops, NULL); + phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops); if (IS_ERR(phy)) { dev_err(dev, "failed to create PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 87dcc9ab7f23..e34da13885e8 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1231,7 +1231,7 @@ static int miphy28lp_probe(struct platform_device *pdev) miphy_dev->phys[port] = miphy_phy; - phy = devm_phy_create(&pdev->dev, child, &miphy28lp_ops, NULL); + phy = devm_phy_create(&pdev->dev, child, &miphy28lp_ops); if (IS_ERR(phy)) { dev_err(&pdev->dev, "failed to create PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 801afaf2d449..239930edfe1d 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c @@ -593,7 +593,7 @@ static int miphy365x_probe(struct platform_device *pdev) miphy_dev->phys[port] = miphy_phy; - phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL); + phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops); if (IS_ERR(phy)) { dev_err(&pdev->dev, "failed to create PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c index d395558cb12e..03b94f92e6f1 100644 --- a/drivers/phy/phy-mvebu-sata.c +++ b/drivers/phy/phy-mvebu-sata.c @@ -101,7 +101,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev) if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); - phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL); + phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops); if (IS_ERR(phy)) return PTR_ERR(phy); diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index f091576b6449..5dab3ec71a19 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c @@ -260,7 +260,7 @@ static int omap_usb2_probe(struct platform_device *pdev) platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); - generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL); + generic_phy = devm_phy_create(phy->dev, NULL, &ops); if (IS_ERR(generic_phy)) { pm_runtime_disable(phy->dev); return PTR_ERR(generic_phy); diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/phy-qcom-apq8064-sata.c index 7b3ddfb65898..4b243f7a10e4 100644 --- a/drivers/phy/phy-qcom-apq8064-sata.c +++ b/drivers/phy/phy-qcom-apq8064-sata.c @@ -228,8 +228,7 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev) if (IS_ERR(phy->mmio)) return PTR_ERR(phy->mmio); - generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops, - NULL); + generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops); if (IS_ERR(generic_phy)) { dev_err(dev, "%s: failed to create phy\n", __func__); return PTR_ERR(generic_phy); diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/phy-qcom-ipq806x-sata.c index 759b0bf5b6b3..6f2fe2627916 100644 --- a/drivers/phy/phy-qcom-ipq806x-sata.c +++ b/drivers/phy/phy-qcom-ipq806x-sata.c @@ -150,8 +150,7 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev) if (IS_ERR(phy->mmio)) return PTR_ERR(phy->mmio); - generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops, - NULL); + generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops); if (IS_ERR(generic_phy)) { dev_err(dev, "%s: failed to create phy\n", __func__); return PTR_ERR(generic_phy); diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c index 2793af17799f..778276aba3aa 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/phy-rcar-gen2.c @@ -304,7 +304,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) phy->select_value = select_value[channel_num][n]; phy->phy = devm_phy_create(dev, NULL, - &rcar_gen2_phy_ops, NULL); + &rcar_gen2_phy_ops); if (IS_ERR(phy->phy)) { dev_err(dev, "Failed to create PHY\n"); return PTR_ERR(phy->phy); diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c index 908949dfb4db..4a12f66b7fb5 100644 --- a/drivers/phy/phy-samsung-usb2.c +++ b/drivers/phy/phy-samsung-usb2.c @@ -202,8 +202,7 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev) struct samsung_usb2_phy_instance *p = &drv->instances[i]; dev_dbg(dev, "Creating phy \"%s\"\n", label); - p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops, - NULL); + p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops); if (IS_ERR(p->phy)) { dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n", label); diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c index 5f4c586ee951..9f47fae7eecb 100644 --- a/drivers/phy/phy-spear1310-miphy.c +++ b/drivers/phy/phy-spear1310-miphy.c @@ -227,7 +227,7 @@ static int spear1310_miphy_probe(struct platform_device *pdev) return -EINVAL; } - priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL); + priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops); if (IS_ERR(priv->phy)) { dev_err(dev, "failed to create SATA PCIe PHY\n"); return PTR_ERR(priv->phy); diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c index 1ecd0945bad3..e42bc200275f 100644 --- a/drivers/phy/phy-spear1340-miphy.c +++ b/drivers/phy/phy-spear1340-miphy.c @@ -259,7 +259,7 @@ static int spear1340_miphy_probe(struct platform_device *pdev) return PTR_ERR(priv->misc); } - priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL); + priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops); if (IS_ERR(priv->phy)) { dev_err(dev, "failed to create SATA PCIe PHY\n"); return PTR_ERR(priv->phy); diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/phy-stih407-usb.c index 42428d4181ea..74f0fab3cd8a 100644 --- a/drivers/phy/phy-stih407-usb.c +++ b/drivers/phy/phy-stih407-usb.c @@ -137,7 +137,7 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev) } phy_dev->param = res->start; - phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data, NULL); + phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data); if (IS_ERR(phy)) { dev_err(dev, "failed to create Display Port PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-stih41x-usb.c b/drivers/phy/phy-stih41x-usb.c index 9f16cb8e01f4..4ab581eadacf 100644 --- a/drivers/phy/phy-stih41x-usb.c +++ b/drivers/phy/phy-stih41x-usb.c @@ -148,7 +148,7 @@ static int stih41x_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(phy_dev->clk); } - phy = devm_phy_create(dev, NULL, &stih41x_usb_phy_ops, NULL); + phy = devm_phy_create(dev, NULL, &stih41x_usb_phy_ops); if (IS_ERR(phy)) { dev_err(dev, "failed to create phy\n"); diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index 6bd2b0c972cc..fb02a67c9181 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -298,7 +298,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(phy->pmu); } - phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops, NULL); + phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops); if (IS_ERR(phy->phy)) { dev_err(dev, "failed to create PHY %d\n", i); return PTR_ERR(phy->phy); diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index ab1e22d9a1e8..c297b7a10d30 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -399,7 +399,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); - generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL); + generic_phy = devm_phy_create(phy->dev, NULL, &ops); if (IS_ERR(generic_phy)) return PTR_ERR(generic_phy); diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index c45a3aa4f2cc..d19e4a06b858 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -678,7 +678,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) otg->set_host = twl4030_set_host; otg->set_peripheral = twl4030_set_peripheral; - phy = devm_phy_create(twl->dev, NULL, &ops, NULL); + phy = devm_phy_create(twl->dev, NULL, &ops); if (IS_ERR(phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); return PTR_ERR(phy); diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index f8a51b16ade8..29214a36ea28 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c @@ -1707,7 +1707,7 @@ static int xgene_phy_probe(struct platform_device *pdev) ctx->dev = &pdev->dev; platform_set_drvdata(pdev, ctx); - ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops, NULL); + ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); if (IS_ERR(ctx->phy)) { dev_dbg(&pdev->dev, "Failed to create PHY\n"); rc = PTR_ERR(ctx->phy); diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c index 1631ec94fb02..a84299b922c8 100644 --- a/drivers/pinctrl/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/pinctrl-tegra-xusb.c @@ -910,7 +910,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) goto reset; } - phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL); + phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops); if (IS_ERR(phy)) { err = PTR_ERR(phy); goto unregister; @@ -919,7 +919,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev) padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy; phy_set_drvdata(phy, padctl); - phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL); + phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops); if (IS_ERR(phy)) { err = PTR_ERR(phy); goto unregister; diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 849284e5873f..a0197fa1b116 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -61,7 +61,6 @@ struct phy { struct device dev; int id; const struct phy_ops *ops; - struct phy_init_data *init_data; struct mutex mutex; int init_count; int power_count; @@ -84,32 +83,6 @@ struct phy_provider { struct of_phandle_args *args); }; -/** - * struct phy_consumer - represents the phy consumer - * @dev_name: the device name of the controller that will use this PHY device - * @port: name given to the consumer port - */ -struct phy_consumer { - const char *dev_name; - const char *port; -}; - -/** - * struct phy_init_data - contains the list of PHY consumers - * @num_consumers: number of consumers for this PHY device - * @consumers: list of PHY consumers - */ -struct phy_init_data { - unsigned int num_consumers; - struct phy_consumer *consumers; -}; - -#define PHY_CONSUMER(_dev_name, _port) \ -{ \ - .dev_name = _dev_name, \ - .port = _port, \ -} - struct phy_lookup { struct list_head node; const char *dev_id; @@ -166,10 +139,9 @@ struct phy *of_phy_get(struct device_node *np, const char *con_id); struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args *args); struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); + const struct phy_ops *ops); struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, struct phy_init_data *init_data); + const struct phy_ops *ops); void phy_destroy(struct phy *phy); void devm_phy_destroy(struct device *dev, struct phy *phy); struct phy_provider *__of_phy_provider_register(struct device *dev, @@ -310,16 +282,14 @@ static inline struct phy *of_phy_simple_xlate(struct device *dev, static inline struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) + const struct phy_ops *ops) { return ERR_PTR(-ENOSYS); } static inline struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data) + const struct phy_ops *ops) { return ERR_PTR(-ENOSYS); } -- GitLab From 08f871a3aca252b15107fc37dedcdacbac80fdb5 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:23 +0200 Subject: [PATCH 5821/9457] usb: dwc3: host: convey the PHYs to xhci On some platforms a PHY may need to be handled also in the host controller driver. Exynos5420 SoC requires some "PHY tuning" based on the USB speed. This patch delivers dwc3's PHYs to the xhci platform device when it's created. Signed-off-by: Heikki Krogerus Tested-by: Vivek Gautam Acked-by: Felipe Balbi Signed-off-by: Kishon Vijay Abraham I --- drivers/usb/dwc3/host.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index dcb8ca084598..12bfd3c5405e 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -29,8 +29,7 @@ int dwc3_host_init(struct dwc3 *dwc) xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); if (!xhci) { dev_err(dwc->dev, "couldn't allocate xHCI device\n"); - ret = -ENOMEM; - goto err0; + return -ENOMEM; } dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask); @@ -60,22 +59,33 @@ int dwc3_host_init(struct dwc3 *dwc) goto err1; } + phy_create_lookup(dwc->usb2_generic_phy, "usb2-phy", + dev_name(&xhci->dev)); + phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy", + dev_name(&xhci->dev)); + ret = platform_device_add(xhci); if (ret) { dev_err(dwc->dev, "failed to register xHCI device\n"); - goto err1; + goto err2; } return 0; - +err2: + phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy", + dev_name(&xhci->dev)); + phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy", + dev_name(&xhci->dev)); err1: platform_device_put(xhci); - -err0: return ret; } void dwc3_host_exit(struct dwc3 *dwc) { + phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy", + dev_name(&dwc->xhci->dev)); + phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy", + dev_name(&dwc->xhci->dev)); platform_device_unregister(dwc->xhci); } -- GitLab From 9bde18c1b5d2c9a1b90fc0f3bbe1a314194f6fdf Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:48 +0530 Subject: [PATCH 5822/9457] phy: exynos5-usbdrd: Add pipe-clk, utmi-clk and itp-clk support Exynos7 SoC has now separate gate control for 125MHz pipe3 phy clock, as well as 60MHz utmi phy clock. Additionally, separate gate control is available for the clock used for ITP (Isochronous Transfer Packet) generation. So get the same and control in the phy-exynos5-usbdrd driver. Suggested-by: Anton Tikhomirov Signed-off-by: Vivek Gautam Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/samsung-phy.txt | 6 + drivers/phy/phy-exynos5-usbdrd.c | 104 +++++++++++++++--- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 15e0f2c7130f..d5bad920827f 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -128,6 +128,7 @@ Required properties: - compatible : Should be set to one of the following supported values: - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. + - "samsung,exynos7-usbdrd-phy" - for exynos7 SoC. - reg : Register offset and length of USB DRD PHY register set; - clocks: Clock IDs array as required by the controller - clock-names: names of clocks correseponding to IDs in the clock property; @@ -138,6 +139,11 @@ Required properties: PHY operations, associated by phy name. It is used to determine bit values for clock settings register. For Exynos5420 this is given as 'sclk_usbphy30' in CMU. + - optional clocks: Exynos7 SoC has now following additional + gate clocks available: + - phy_pipe: for PIPE3 phy + - phy_utmi: for UTMI+ phy + - itp: for ITP generation - samsung,pmu-syscon: phandle for PMU system controller interface, used to control pmu registers for power isolation. - #phy-cells : from the generic PHY bindings, must be 1; diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index b3ca3bc2314f..99ba56dc63dd 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c @@ -141,6 +141,7 @@ struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; u32 pmu_offset_usbdrd0_phy; u32 pmu_offset_usbdrd1_phy; + bool has_common_clk_gate; }; /** @@ -148,6 +149,9 @@ struct exynos5_usbdrd_phy_drvdata { * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base * @clk: phy clock for register access + * @pipeclk: clock for pipe3 phy + * @utmiclk: clock for utmi+ phy + * @itpclk: clock for ITP generation * @drv_data: pointer to SoC level driver data structure * @phys[]: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY * instances each with its 'phy' and 'phy_cfg'. @@ -155,12 +159,14 @@ struct exynos5_usbdrd_phy_drvdata { * reference clocks' for SS and HS operations * @ref_clk: reference clock to PHY block from which PHY's * operational clocks are derived - * @ref_rate: rate of above reference clock */ struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; struct clk *clk; + struct clk *pipeclk; + struct clk *utmiclk; + struct clk *itpclk; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct phy_usb_instance { struct phy *phy; @@ -447,6 +453,11 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); clk_prepare_enable(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_prepare_enable(phy_drd->pipeclk); + clk_prepare_enable(phy_drd->utmiclk); + clk_prepare_enable(phy_drd->itpclk); + } /* Enable VBUS supply */ if (phy_drd->vbus) { @@ -464,6 +475,11 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) fail_vbus: clk_disable_unprepare(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_disable_unprepare(phy_drd->itpclk); + clk_disable_unprepare(phy_drd->utmiclk); + clk_disable_unprepare(phy_drd->pipeclk); + } return ret; } @@ -483,6 +499,11 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) regulator_disable(phy_drd->vbus); clk_disable_unprepare(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_disable_unprepare(phy_drd->itpclk); + clk_disable_unprepare(phy_drd->pipeclk); + clk_disable_unprepare(phy_drd->utmiclk); + } return 0; } @@ -506,6 +527,57 @@ static struct phy_ops exynos5_usbdrd_phy_ops = { .owner = THIS_MODULE, }; +static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) +{ + unsigned long ref_rate; + int ret; + + phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); + if (IS_ERR(phy_drd->clk)) { + dev_err(phy_drd->dev, "Failed to get phy clock\n"); + return PTR_ERR(phy_drd->clk); + } + + phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); + if (IS_ERR(phy_drd->ref_clk)) { + dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); + return PTR_ERR(phy_drd->ref_clk); + } + ref_rate = clk_get_rate(phy_drd->ref_clk); + + ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + if (ret) { + dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", + ref_rate); + return ret; + } + + if (!phy_drd->drv_data->has_common_clk_gate) { + phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); + if (IS_ERR(phy_drd->pipeclk)) { + dev_info(phy_drd->dev, + "PIPE3 phy operational clock not specified\n"); + phy_drd->pipeclk = NULL; + } + + phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); + if (IS_ERR(phy_drd->utmiclk)) { + dev_info(phy_drd->dev, + "UTMI phy operational clock not specified\n"); + phy_drd->utmiclk = NULL; + } + + phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); + if (IS_ERR(phy_drd->itpclk)) { + dev_info(phy_drd->dev, + "ITP clock from main OSC not specified\n"); + phy_drd->itpclk = NULL; + } + } + + return 0; +} + static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { { .id = EXYNOS5_DRDPHY_UTMI, @@ -525,11 +597,19 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, + .has_common_clk_gate = true, }; static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .has_common_clk_gate = true, +}; + +static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { + .phy_cfg = phy_cfg_exynos5, + .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .has_common_clk_gate = false, }; static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { @@ -539,6 +619,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { }, { .compatible = "samsung,exynos5420-usbdrd-phy", .data = &exynos5420_usbdrd_phy + }, { + .compatible = "samsung,exynos7-usbdrd-phy", + .data = &exynos7_usbdrd_phy }, { }, }; @@ -555,7 +638,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) const struct exynos5_usbdrd_phy_drvdata *drv_data; struct regmap *reg_pmu; u32 pmu_offset; - unsigned long ref_rate; int i, ret; int channel; @@ -576,23 +658,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) drv_data = match->data; phy_drd->drv_data = drv_data; - phy_drd->clk = devm_clk_get(dev, "phy"); - if (IS_ERR(phy_drd->clk)) { - dev_err(dev, "Failed to get clock of phy controller\n"); - return PTR_ERR(phy_drd->clk); - } - - phy_drd->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(phy_drd->ref_clk)) { - dev_err(dev, "Failed to get reference clock of usbdrd phy\n"); - return PTR_ERR(phy_drd->ref_clk); - } - ref_rate = clk_get_rate(phy_drd->ref_clk); - - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + ret = exynos5_usbdrd_phy_clk_handle(phy_drd); if (ret) { - dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", - ref_rate); + dev_err(dev, "Failed to initialize clocks\n"); return ret; } -- GitLab From a6867836db35d1e178744166765b57288bf4e8e5 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:49 +0530 Subject: [PATCH 5823/9457] phy: exynos5-usbdrd: Add facility for VBUS-BOOST-5V supply Some Exynos boards have a separate regulator controlling a Boost 5V supply which goes as input for VBUS regulator. So adding a control for the same in driver, to enable vbus supply on the port. Signed-off-by: Vivek Gautam Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-exynos5-usbdrd.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index 99ba56dc63dd..04374018425f 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c @@ -159,6 +159,8 @@ struct exynos5_usbdrd_phy_drvdata { * reference clocks' for SS and HS operations * @ref_clk: reference clock to PHY block from which PHY's * operational clocks are derived + * vbus: VBUS regulator for phy + * vbus_boost: Boost regulator for VBUS present on few Exynos boards */ struct exynos5_usbdrd_phy { struct device *dev; @@ -178,6 +180,7 @@ struct exynos5_usbdrd_phy { u32 extrefclk; struct clk *ref_clk; struct regulator *vbus; + struct regulator *vbus_boost; }; static inline @@ -460,11 +463,20 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) } /* Enable VBUS supply */ + if (phy_drd->vbus_boost) { + ret = regulator_enable(phy_drd->vbus_boost); + if (ret) { + dev_err(phy_drd->dev, + "Failed to enable VBUS boost supply\n"); + goto fail_vbus; + } + } + if (phy_drd->vbus) { ret = regulator_enable(phy_drd->vbus); if (ret) { dev_err(phy_drd->dev, "Failed to enable VBUS supply\n"); - goto fail_vbus; + goto fail_vbus_boost; } } @@ -473,6 +485,10 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) return 0; +fail_vbus_boost: + if (phy_drd->vbus_boost) + regulator_disable(phy_drd->vbus_boost); + fail_vbus: clk_disable_unprepare(phy_drd->ref_clk); if (!phy_drd->drv_data->has_common_clk_gate) { @@ -497,6 +513,8 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) /* Disable VBUS supply */ if (phy_drd->vbus) regulator_disable(phy_drd->vbus); + if (phy_drd->vbus_boost) + regulator_disable(phy_drd->vbus_boost); clk_disable_unprepare(phy_drd->ref_clk); if (!phy_drd->drv_data->has_common_clk_gate) { @@ -690,7 +708,7 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) break; } - /* Get Vbus regulator */ + /* Get Vbus regulators */ phy_drd->vbus = devm_regulator_get(dev, "vbus"); if (IS_ERR(phy_drd->vbus)) { ret = PTR_ERR(phy_drd->vbus); @@ -701,6 +719,16 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) phy_drd->vbus = NULL; } + phy_drd->vbus_boost = devm_regulator_get(dev, "vbus-boost"); + if (IS_ERR(phy_drd->vbus_boost)) { + ret = PTR_ERR(phy_drd->vbus_boost); + if (ret == -EPROBE_DEFER) + return ret; + + dev_warn(dev, "Failed to get VBUS boost supply regulator\n"); + phy_drd->vbus_boost = NULL; + } + dev_vdbg(dev, "Creating usbdrd_phy phy\n"); for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) { -- GitLab From 556186a02c441e8fb03aa4c87d39bdc8ef95820e Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:50 +0530 Subject: [PATCH 5824/9457] phy: exynos7-usbdrd: Update dependency for ARCH_EXYNOS This PHY controller is also present on Exynos7 platform in arch-exynos family. So PHY_EXYNOS5_USBDRD should now depend on ARCH_EXYNOS. Signed-off-by: Vivek Gautam Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 4144d250524f..96d43d5acc57 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -208,7 +208,7 @@ config PHY_EXYNOS5250_USB2 config PHY_EXYNOS5_USBDRD tristate "Exynos5 SoC series USB DRD PHY driver" - depends on ARCH_EXYNOS5 && OF + depends on ARCH_EXYNOS && OF depends on HAS_IOMEM depends on USB_DWC3_EXYNOS select GENERIC_PHY -- GitLab From eadac03e898617521f327faf265932b73ecc3e0f Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Fri, 21 Nov 2014 10:05:59 -0500 Subject: [PATCH 5825/9457] percpu: Replace smp_read_barrier_depends() with lockless_dereference() Recently lockless_dereference() was added which can be used in place of hard-coding smp_read_barrier_depends(). The following PATCH makes the change. Signed-off-by: Pranith Kumar Signed-off-by: Tejun Heo --- include/linux/percpu-refcount.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index d5c89e0dd0e6..6b0c81872142 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h @@ -128,10 +128,8 @@ static inline void percpu_ref_kill(struct percpu_ref *ref) static inline bool __ref_is_percpu(struct percpu_ref *ref, unsigned long __percpu **percpu_countp) { - unsigned long percpu_ptr = ACCESS_ONCE(ref->percpu_count_ptr); - /* paired with smp_store_release() in percpu_ref_reinit() */ - smp_read_barrier_depends(); + unsigned long percpu_ptr = lockless_dereference(ref->percpu_count_ptr); if (unlikely(percpu_ptr & __PERCPU_REF_ATOMIC)) return false; -- GitLab From 52c40fca1a80abaffd9f7315de568d89a2064734 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Tue, 11 Nov 2014 11:20:56 -0500 Subject: [PATCH 5826/9457] vt: Fix build breakage when !CONFIG_VT_CONSOLE Commit 68952076e9226cc23ebce66d3fc2fdb8b6c04c30 ("vt: Remove vt_get_kmsg_redirect() from uapi header") fails to compile if !CONFIG_VT_CONSOLE. Move macro definition for vt_get_kmsg_redirect() up with file-scope function declarations. Reported-by: Jim Davis Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 43c2c2495907..ed0136519422 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -156,6 +156,8 @@ static void console_callback(struct work_struct *ignored); static void blank_screen_t(unsigned long dummy); static void set_palette(struct vc_data *vc); +#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) + static int printable; /* Is console ready for printing? */ int default_utf8 = true; module_param(default_utf8, int, S_IRUGO | S_IWUSR); @@ -2513,8 +2515,6 @@ int vt_kmsg_redirect(int new) return kmsg_con; } -#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) - /* * Console on virtual terminal * -- GitLab From a86a659fb67c67b4294b2ea4d941714608b5f6e3 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 8 Nov 2014 16:12:18 +0900 Subject: [PATCH 5827/9457] staging: lustre: Remove unnecessary semicolon This patch remove unnecessary semicolons from macro. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lmv/lmv_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index b911e7643874..852d78721ca9 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -42,8 +42,8 @@ #define LMV_MAX_TGT_COUNT 128 -#define lmv_init_lock(lmv) mutex_lock(&lmv->init_mutex); -#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex); +#define lmv_init_lock(lmv) mutex_lock(&lmv->init_mutex) +#define lmv_init_unlock(lmv) mutex_unlock(&lmv->init_mutex) #define LL_IT2STR(it) \ ((it) ? ldlm_it2str((it)->it_op) : "0") -- GitLab From dbd18138a01b0284eaff31490f84735a72986a34 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 8 Nov 2014 16:12:19 +0900 Subject: [PATCH 5828/9457] staging: lustre: Remove unnecessary parentheses. This patch remove unnecessary parentheses. Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 9543c15f990e..dc170d87851b 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -925,7 +925,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, __u32 index; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - if ((index >= count)) + if (index >= count) return -ENODEV; if (lmv->tgts[index] == NULL || -- GitLab From 1ef3988da44a5bb0e66eab6f97cf8f60b6e624d5 Mon Sep 17 00:00:00 2001 From: Niklas Svensson Date: Sat, 8 Nov 2014 16:49:18 +0100 Subject: [PATCH 5829/9457] staging: skein: fixed sparse warnings related to static declarations drivers/staging/skein/skein_generic.c:30:5: warning: symbol 'skein256_update' was not declared. Should it be static? drivers/staging/skein/skein_generic.c:65:5: warning: symbol 'skein512_update' was not declared. Should it be static? drivers/staging/skein/skein_generic.c:100:5: warning: symbol 'skein1024_update' was not declared. Should it be static? Signed-off-by: Niklas Svensson Acked-by: Jason Cooper Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c index 60d16b639b91..85bd7d0168b0 100644 --- a/drivers/staging/skein/skein_generic.c +++ b/drivers/staging/skein/skein_generic.c @@ -27,7 +27,7 @@ static int skein256_init(struct shash_desc *desc) SKEIN256_DIGEST_BIT_SIZE); } -int skein256_update(struct shash_desc *desc, const u8 *data, +static int skein256_update(struct shash_desc *desc, const u8 *data, unsigned int len) { return skein_256_update((struct skein_256_ctx *)shash_desc_ctx(desc), @@ -62,7 +62,7 @@ static int skein512_init(struct shash_desc *desc) SKEIN512_DIGEST_BIT_SIZE); } -int skein512_update(struct shash_desc *desc, const u8 *data, +static int skein512_update(struct shash_desc *desc, const u8 *data, unsigned int len) { return skein_512_update((struct skein_512_ctx *)shash_desc_ctx(desc), @@ -97,7 +97,7 @@ static int skein1024_init(struct shash_desc *desc) SKEIN1024_DIGEST_BIT_SIZE); } -int skein1024_update(struct shash_desc *desc, const u8 *data, +static int skein1024_update(struct shash_desc *desc, const u8 *data, unsigned int len) { return skein_1024_update((struct skein_1024_ctx *)shash_desc_ctx(desc), -- GitLab From 9d9b211fcf441f813a255534786539a1aeae4e14 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 9 Nov 2014 11:54:06 +0800 Subject: [PATCH 5830/9457] drivers: staging: lustre: Kconfig: Let LUSTRE_LLITE_LLOOP depend on all !"*_64K*" page It does not support 64K page, so let it disabled for 64K page under all architectures. The related error (with allmodconfig under tile): CC [M] drivers/staging/lustre/lustre/llite/lloop.o In file included from drivers/staging/lustre/lustre/llite/../include/../../include/linux/libcfs/libcfs.h:160:0, from drivers/staging/lustre/lustre/llite/../include/lustre_lib.h:52, from drivers/staging/lustre/lustre/llite/lloop.c:106: drivers/staging/lustre/lustre/llite/lloop.c: In function 'loop_set_fd': drivers/staging/lustre/lustre/llite/../include/../../include/linux/libcfs/libcfs_private.h:411:54: error: duplicate case value #define CLASSERT(cond) do {switch (42) {case (cond): case 0: break; } } while (0) ^ drivers/staging/lustre/lustre/llite/lloop.c:525:2: note: in expansion of macro 'CLASSERT' CLASSERT(PAGE_CACHE_SIZE < (1 << (sizeof(unsigned short) * 8))); ^ drivers/staging/lustre/lustre/llite/../include/../../include/linux/libcfs/libcfs_private.h:411:41: error: previously used here #define CLASSERT(cond) do {switch (42) {case (cond): case 0: break; } } while (0) ^ drivers/staging/lustre/lustre/llite/lloop.c:525:2: note: in expansion of macro 'CLASSERT' CLASSERT(PAGE_CACHE_SIZE < (1 << (sizeof(unsigned short) * 8))); ^ Use "find ./ | grep Kconfig | xargs grep --color 64K" to find all 64K page macros. Signed-off-by: Chen Gang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig index 4f65ba1158bf..6725467ef4d0 100644 --- a/drivers/staging/lustre/lustre/Kconfig +++ b/drivers/staging/lustre/lustre/Kconfig @@ -57,5 +57,5 @@ config LUSTRE_TRANSLATE_ERRNOS config LUSTRE_LLITE_LLOOP tristate "Lustre virtual block device" depends on LUSTRE_FS && BLOCK - depends on !PPC_64K_PAGES && !ARM64_64K_PAGES + depends on !PPC_64K_PAGES && !ARM64_64K_PAGES && !MICROBLAZE_64K_PAGES && !PAGE_SIZE_64KB && !IA64_PAGE_SIZE_64KB && !PARISC_PAGE_SIZE_64KB default m -- GitLab From 337832b7919469db17d3ebf60e3875e6915cae75 Mon Sep 17 00:00:00 2001 From: Domagoj Trsan Date: Mon, 17 Nov 2014 09:44:56 +0100 Subject: [PATCH 5831/9457] staging: skein: fix sparse warnings related to shift operator Fix warnings: drivers/staging/skein/skein_base.h:89:30: warning: shift too big (50) for type int ... drivers/staging/skein/skein_base.h:89:30: warning: shift too big (39)for type int drivers/staging/skein/skein_base.h:89:19: warning: too many warnings Signed-off-by: Domagoj Trsan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/skein/skein_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h index 993b951172f6..3c7f8ad3627d 100644 --- a/drivers/staging/skein/skein_base.h +++ b/drivers/staging/skein/skein_base.h @@ -84,7 +84,7 @@ struct skein_1024_ctx { /* 1024-bit Skein hash context structure */ u8 b[SKEIN_1024_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */ }; -static inline int rotl_64(int x, int N) +static inline u64 rotl_64(u64 x, u8 N) { return (x << N) | (x >> (64 - N)); } -- GitLab From 490e0e898ba4c625bbf53d691cb8554a1a494063 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 9 Nov 2014 10:06:32 +0100 Subject: [PATCH 5832/9457] staging: lustre: osc: remove final uses of the GOTO macro The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ identifier lbl; identifier rc; constant c; @@ - GOTO(lbl,\(rc\|c\)); + goto lbl; @@ identifier lbl; expression rc; @@ - GOTO(lbl,rc); + rc; + goto lbl; // In one case (OES_INV), consecutive gotos were factorized and a break was removed. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/osc/osc_cache.c | 168 ++++++++++++------ 1 file changed, 110 insertions(+), 58 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index ec04935c65ea..f8c8b666d4f3 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -178,76 +178,113 @@ static int osc_extent_sanity_check0(struct osc_extent *ext, int page_count; int rc = 0; - if (!osc_object_is_locked(obj)) - GOTO(out, rc = 9); + if (!osc_object_is_locked(obj)) { + rc = 9; + goto out; + } - if (ext->oe_state >= OES_STATE_MAX) - GOTO(out, rc = 10); + if (ext->oe_state >= OES_STATE_MAX) { + rc = 10; + goto out; + } - if (atomic_read(&ext->oe_refc) <= 0) - GOTO(out, rc = 20); + if (atomic_read(&ext->oe_refc) <= 0) { + rc = 20; + goto out; + } - if (atomic_read(&ext->oe_refc) < atomic_read(&ext->oe_users)) - GOTO(out, rc = 30); + if (atomic_read(&ext->oe_refc) < atomic_read(&ext->oe_users)) { + rc = 30; + goto out; + } switch (ext->oe_state) { case OES_INV: if (ext->oe_nr_pages > 0 || !list_empty(&ext->oe_pages)) - GOTO(out, rc = 35); - GOTO(out, rc = 0); - break; + rc = 35; + else + rc = 0; + goto out; case OES_ACTIVE: - if (atomic_read(&ext->oe_users) == 0) - GOTO(out, rc = 40); - if (ext->oe_hp) - GOTO(out, rc = 50); - if (ext->oe_fsync_wait && !ext->oe_urgent) - GOTO(out, rc = 55); + if (atomic_read(&ext->oe_users) == 0) { + rc = 40; + goto out; + } + if (ext->oe_hp) { + rc = 50; + goto out; + } + if (ext->oe_fsync_wait && !ext->oe_urgent) { + rc = 55; + goto out; + } break; case OES_CACHE: - if (ext->oe_grants == 0) - GOTO(out, rc = 60); - if (ext->oe_fsync_wait && !ext->oe_urgent && !ext->oe_hp) - GOTO(out, rc = 65); + if (ext->oe_grants == 0) { + rc = 60; + goto out; + } + if (ext->oe_fsync_wait && !ext->oe_urgent && !ext->oe_hp) { + rc = 65; + goto out; + } default: - if (atomic_read(&ext->oe_users) > 0) - GOTO(out, rc = 70); + if (atomic_read(&ext->oe_users) > 0) { + rc = 70; + goto out; + } } - if (ext->oe_max_end < ext->oe_end || ext->oe_end < ext->oe_start) - GOTO(out, rc = 80); + if (ext->oe_max_end < ext->oe_end || ext->oe_end < ext->oe_start) { + rc = 80; + goto out; + } - if (ext->oe_osclock == NULL && ext->oe_grants > 0) - GOTO(out, rc = 90); + if (ext->oe_osclock == NULL && ext->oe_grants > 0) { + rc = 90; + goto out; + } if (ext->oe_osclock) { struct cl_lock_descr *descr; descr = &ext->oe_osclock->cll_descr; if (!(descr->cld_start <= ext->oe_start && - descr->cld_end >= ext->oe_max_end)) - GOTO(out, rc = 100); + descr->cld_end >= ext->oe_max_end)) { + rc = 100; + goto out; + } } - if (ext->oe_nr_pages > ext->oe_mppr) - GOTO(out, rc = 105); + if (ext->oe_nr_pages > ext->oe_mppr) { + rc = 105; + goto out; + } /* Do not verify page list if extent is in RPC. This is because an * in-RPC extent is supposed to be exclusively accessible w/o lock. */ - if (ext->oe_state > OES_CACHE) - GOTO(out, rc = 0); + if (ext->oe_state > OES_CACHE) { + rc = 0; + goto out; + } - if (!extent_debug) - GOTO(out, rc = 0); + if (!extent_debug) { + rc = 0; + goto out; + } page_count = 0; list_for_each_entry(oap, &ext->oe_pages, oap_pending_item) { pgoff_t index = oap2cl_page(oap)->cp_index; ++page_count; - if (index > ext->oe_end || index < ext->oe_start) - GOTO(out, rc = 110); + if (index > ext->oe_end || index < ext->oe_start) { + rc = 110; + goto out; + } + } + if (page_count != ext->oe_nr_pages) { + rc = 120; + goto out; } - if (page_count != ext->oe_nr_pages) - GOTO(out, rc = 120); out: if (rc != 0) @@ -774,8 +811,10 @@ struct osc_extent *osc_extent_find(const struct lu_env *env, rc = osc_extent_wait(env, conflict, OES_INV); osc_extent_put(env, conflict); conflict = NULL; - if (rc < 0) - GOTO(out, found = ERR_PTR(rc)); + if (rc < 0) { + found = ERR_PTR(rc); + goto out; + } goto restart; } @@ -932,7 +971,7 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, io->ci_obj = cl_object_top(osc2cl(obj)); rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc < 0) - GOTO(out, rc); + goto out; /* discard all pages with index greater then trunc_index */ list_for_each_entry_safe(oap, tmp, &ext->oe_pages, @@ -1112,21 +1151,27 @@ static int osc_extent_expand(struct osc_extent *ext, pgoff_t index, int *grants) osc_object_lock(obj); LASSERT(sanity_check_nolock(ext) == 0); end_chunk = ext->oe_end >> ppc_bits; - if (chunk > end_chunk + 1) - GOTO(out, rc = -ERANGE); + if (chunk > end_chunk + 1) { + rc = -ERANGE; + goto out; + } - if (end_chunk >= chunk) - GOTO(out, rc = 0); + if (end_chunk >= chunk) { + rc = 0; + goto out; + } LASSERT(end_chunk + 1 == chunk); /* try to expand this extent to cover @index */ end_index = min(ext->oe_max_end, ((chunk + 1) << ppc_bits) - 1); next = next_extent(ext); - if (next != NULL && next->oe_start <= end_index) + if (next != NULL && next->oe_start <= end_index) { /* complex mode - overlapped with the next extent, * this case will be handled by osc_extent_find() */ - GOTO(out, rc = -EAGAIN); + rc = -EAGAIN; + goto out; + } ext->oe_end = end_index; ext->oe_grants += chunksize; @@ -1495,12 +1540,16 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, * of queued writes and create a discontiguous rpc stream */ if (OBD_FAIL_CHECK(OBD_FAIL_OSC_NO_GRANT) || cli->cl_dirty_max < PAGE_CACHE_SIZE || - cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync) - GOTO(out, rc = -EDQUOT); + cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync) { + rc = -EDQUOT; + goto out; + } /* Hopefully normal case - cache space and write credits available */ - if (osc_enter_cache_try(cli, oap, bytes, 0)) - GOTO(out, rc = 0); + if (osc_enter_cache_try(cli, oap, bytes, 0)) { + rc = 0; + goto out; + } /* We can get here for two reasons: too many dirty pages in cache, or * run out of grants. In both cases we should write dirty pages out. @@ -1528,16 +1577,18 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli, /* l_wait_event is interrupted by signal */ if (rc < 0) { list_del_init(&ocw.ocw_entry); - GOTO(out, rc); + goto out; } LASSERT(list_empty(&ocw.ocw_entry)); rc = ocw.ocw_rc; if (rc != -EDQUOT) - GOTO(out, rc); - if (osc_enter_cache_try(cli, oap, bytes, 0)) - GOTO(out, rc = 0); + goto out; + if (osc_enter_cache_try(cli, oap, bytes, 0)) { + rc = 0; + goto out; + } } out: client_obd_list_unlock(&cli->cl_loi_list_lock); @@ -2399,14 +2450,15 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io, * one making the extent active, we could deadlock waiting for * the page writeback to clear but it won't because the extent * is active and won't be written out. */ - GOTO(out, rc = -EAGAIN); + rc = -EAGAIN; + goto out; default: break; } rc = cl_page_prep(env, io, cl_page_top(cp), CRT_WRITE); if (rc) - GOTO(out, rc); + goto out; spin_lock(&oap->oap_lock); oap->oap_async_flags |= ASYNC_READY|ASYNC_URGENT; -- GitLab From b4f0065ed344c57370e506e5464fafb66cd27990 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 9 Nov 2014 10:06:34 +0100 Subject: [PATCH 5833/9457] staging: lustre: libcfs: remove final uses of the GOTO macro Remove the goto logging function, as it is no longer used. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/debug.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 2c15a9e7332f..859129d8ddc8 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -460,11 +460,3 @@ void libcfs_debug_set_level(unsigned int debug_level) } EXPORT_SYMBOL(libcfs_debug_set_level); - -void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *label, - long_ptr_t rc) -{ - libcfs_debug_msg(msgdata, "Process leaving via %s (rc=%lu : %ld : %#lx)\n", - label, (ulong_ptr_t)rc, rc, rc); -} -EXPORT_SYMBOL(libcfs_log_goto); -- GitLab From 71583c3ef0acb3b88368353ab6007b2fa1fcd02e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 9 Nov 2014 10:06:33 +0100 Subject: [PATCH 5834/9457] staging: lustre: libcfs_debug.h: remove final uses of the GOTO macro Remove the GOTO macro, as it is no longer used. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/linux/libcfs/libcfs_debug.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h index 8888b2756174..2e5a9e5965b1 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h @@ -242,18 +242,6 @@ do { \ #define LCONSOLE_EMERG(format, ...) CDEBUG(D_CONSOLE | D_EMERG, format, ## __VA_ARGS__) -void libcfs_log_goto(struct libcfs_debug_msg_data *, const char *, long_ptr_t); -#define GOTO(label, rc) \ -do { \ - if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) { \ - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL); \ - libcfs_log_goto(&msgdata, #label, (long_ptr_t)(rc)); \ - } else { \ - (void)(rc); \ - } \ - goto label; \ -} while (0) - int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata, const char *format1, ...) __attribute__ ((format (printf, 2, 3))); -- GitLab From 3ff28049970d3808b44b1e2116f2ebbb08ffa0df Mon Sep 17 00:00:00 2001 From: Balavasu Kuppusammyprathaban Date: Wed, 12 Nov 2014 15:42:34 +0530 Subject: [PATCH 5835/9457] staging: lustre: lustre: ptlrpc: Remove unnecessary braces Fixes the following checkpatch warning: WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Balavasu Kuppusammyprathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/client.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 38cc931a189c..6c8815f4b99b 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -2215,10 +2215,8 @@ EXPORT_SYMBOL(ptlrpc_set_wait); */ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) { - if (request == NULL) { + if (request == NULL) return; - } - LASSERTF(!request->rq_receiving_reply, "req %p\n", request); LASSERTF(request->rq_rqbd == NULL, "req %p\n", request);/* client-side */ LASSERTF(list_empty(&request->rq_list), "req %p\n", request); -- GitLab From 565f3d2fd09a6e9c7615ae369beedabcf0e86b53 Mon Sep 17 00:00:00 2001 From: Thomas Wood Date: Mon, 17 Nov 2014 11:54:40 -0800 Subject: [PATCH 5836/9457] drivers: staging: lustre: lnet: api-nc.c: Fix Style Warnings Remove an unecessary return statement in a void function. Remove an unecessary space between a function name and the parentheses. Signed-off-by: Thomas Wood Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/api-ni.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 5e6e4e22ed31..faceb9505d84 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -277,7 +277,7 @@ lnet_find_lnd_by_type(int type) struct list_head *tmp; /* holding lnd mutex */ - list_for_each (tmp, &the_lnet.ln_lnds) { + list_for_each(tmp, &the_lnet.ln_lnds) { lnd = list_entry(tmp, lnd_t, lnd_list); if ((int)lnd->lnd_type == type) @@ -1645,7 +1645,6 @@ lnet_destroy_ping_info(void) offsetof(lnet_ping_info_t, pi_ni[the_lnet.ln_ping_info->pi_nnis])); the_lnet.ln_ping_info = NULL; - return; } int -- GitLab From 962dbfd6144ab04750018b689eddf0857fbc11cb Mon Sep 17 00:00:00 2001 From: Juston Li Date: Tue, 18 Nov 2014 17:03:51 -0800 Subject: [PATCH 5837/9457] staging: lustre: mdc: use __FMODE_EXEC macro FMODE_EXEC is type fmode_t but is used in operations with integers which leads to sparse warnings: drivers/staging/lustre/lustre/mdc/mdc_lib.c:198:21: warning: restricted fmode_t degrades to integer drivers/staging/lustre/lustre/mdc/mdc_locks.c:300:49: warning: restricted fmode_t degrades to integer Fix by using __FMODE_EXEC macro defined in fs.h. Note the same warnings occurs with other fmode flags here but they don't have a corresponding int macro. Changes since v1: remove ifdefs. FMODE_EXEC and __FMODE_EXEC should always be defined in fs.h Signed-off-by: Juston Li Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 4 +--- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index e8732cc30ce2..4e59995e0042 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -194,10 +194,8 @@ static __u64 mds_pack_open_flags(__u64 flags, __u32 mode) cr_flags |= MDS_OPEN_SYNC; if (flags & O_DIRECTORY) cr_flags |= MDS_OPEN_DIRECTORY; -#ifdef FMODE_EXEC - if (flags & FMODE_EXEC) + if (flags & __FMODE_EXEC) cr_flags |= MDS_FMODE_EXEC; -#endif if (cl_is_lov_delay_create(flags)) cr_flags |= MDS_OPEN_DELAY_CREATE; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index b58147ee62b6..8c9b4f5494e9 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -296,10 +296,8 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp, } else { if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC)) mode = LCK_CW; -#ifdef FMODE_EXEC - else if (it->it_flags & FMODE_EXEC) + else if (it->it_flags & __FMODE_EXEC) mode = LCK_PR; -#endif else mode = LCK_CR; } -- GitLab From 4fc390a198c41a007c02f82f41ad100c7c67b55e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 22 Nov 2014 21:29:01 +0300 Subject: [PATCH 5838/9457] sound: oss: uart401: remove unneeded NULL check "devc" can't be NULL here so there is no need to check. Also I removed the "devc = NULL" assignment because devc is stored on stack so it's a no-op. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/oss/uart401.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index 279bc565ac7e..dae4d4344407 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c @@ -412,13 +412,10 @@ void unload_uart401(struct address_info *hw_config) if (!devc->share_irq) free_irq(devc->irq, devc); - if (devc) - { - kfree(midi_devs[devc->my_dev]->converter); - kfree(midi_devs[devc->my_dev]); - kfree(devc); - devc = NULL; - } + kfree(midi_devs[devc->my_dev]->converter); + kfree(midi_devs[devc->my_dev]); + kfree(devc); + /* This kills midi_devs[x] */ sound_unload_mididev(hw_config->slots[4]); } -- GitLab From e9886ab06c1ef42451307c9367e344b2d8140e0b Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:48 +1300 Subject: [PATCH 5839/9457] ALSA: asihpi: Minor string and dead code cleanup Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index ff9f9f1c0391..0e130dd8732e 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -28,7 +28,6 @@ #include "hpioctl.h" #include "hpicmn.h" - #include #include #include @@ -47,7 +46,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. "); -MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx " +MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx " HPI_VER_STRING); #if defined CONFIG_SND_DEBUG_VERBOSE @@ -87,11 +86,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep, #ifdef KERNEL_ALSA_BUILD static char *build_info = "Built using headers from kernel source"; module_param(build_info, charp, S_IRUGO); -MODULE_PARM_DESC(build_info, "built using headers from kernel source"); +MODULE_PARM_DESC(build_info, "Built using headers from kernel source"); #else static char *build_info = "Built within ALSA source"; module_param(build_info, charp, S_IRUGO); -MODULE_PARM_DESC(build_info, "built within ALSA source"); +MODULE_PARM_DESC(build_info, "Built within ALSA source"); #endif /* set to 1 to dump every control from adapter to log */ @@ -538,7 +537,7 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * int expiry; expiry = HZ / 200; - /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */ + expiry = max(expiry, 1); /* don't let it be zero! */ dpcm->timer.expires = jiffies + expiry; dpcm->respawn_timer = 1; @@ -2932,10 +2931,6 @@ static struct pci_driver driver = { .id_table = asihpi_pci_tbl, .probe = snd_asihpi_probe, .remove = snd_asihpi_remove, -#ifdef CONFIG_PM_SLEEP -/* .suspend = snd_asihpi_suspend, - .resume = snd_asihpi_resume, */ -#endif }; static int __init snd_asihpi_init(void) -- GitLab From 3872f19d96a55ec1d1e7af904d84457d91ef5a63 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:49 +1300 Subject: [PATCH 5840/9457] ALSA: asihpi: New I/O types - AVB & BLUlink, DAB Rf receiver Audio cards wth have AVB or BLU Link IO. Tuner card with DAB receiver Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 25 ++++++++++++++++++------- sound/pci/asihpi/hpi.h | 16 ++++++++++++---- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 0e130dd8732e..628ef7f146d9 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -109,7 +109,7 @@ static int adapter_fs = DEFAULT_SAMPLERATE; struct clk_source { int source; int index; - char *name; + const char *name; }; struct clk_cache { @@ -1292,8 +1292,9 @@ static const char * const asihpi_tuner_band_names[] = { "TV PAL I", "TV PAL DK", "TV SECAM", + "TV DAB", }; - +/* Number of strings must match the enumerations for HPI_TUNER_BAND in hpi.h */ compile_time_assert( (ARRAY_SIZE(asihpi_tuner_band_names) == (HPI_TUNER_BAND_LAST+1)), @@ -1313,9 +1314,11 @@ static const char * const asihpi_src_names[] = { "Analog", "Adapter", "RTP", - "Internal" + "Internal", + "AVB", + "BLU-Link" }; - +/* Number of strings must match the enumerations for HPI_SOURCENODES in hpi.h */ compile_time_assert( (ARRAY_SIZE(asihpi_src_names) == (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), @@ -1331,8 +1334,11 @@ static const char * const asihpi_dst_names[] = { "Net", "Analog", "RTP", + "AVB", + "Internal", + "BLU-Link" }; - +/* Number of strings must match the enumerations for HPI_DESTNODES in hpi.h */ compile_time_assert( (ARRAY_SIZE(asihpi_dst_names) == (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)), @@ -2288,13 +2294,18 @@ static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi, /*------------------------------------------------------------ Sampleclock source controls ------------------------------------------------------------*/ -static char *sampleclock_sources[MAX_CLOCKSOURCES] = { +static const char const *sampleclock_sources[] = { "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header", "SMPTE", "Digital1", "Auto", "Network", "Invalid", - "Prev Module", + "Prev Module", "BLU-Link", "Digital2", "Digital3", "Digital4", "Digital5", "Digital6", "Digital7", "Digital8"}; + /* Number of strings must match expected enumerated values */ + compile_time_assert( + (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES), + assert_sampleclock_sources_size); + static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 20887241a3ae..4466bd2c5272 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h @@ -196,8 +196,10 @@ enum HPI_SOURCENODES { packets of RTP audio samples from other devices. */ HPI_SOURCENODE_RTP_DESTINATION = 112, HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */ + HPI_SOURCENODE_AVB = 114, /**< AVB input stream */ + HPI_SOURCENODE_BLULINK = 115, /**< BLU-link input channel */ /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ - HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */ + HPI_SOURCENODE_LAST_INDEX = 115 /**< largest ID */ /* AX6 max sourcenode types = 15 */ }; @@ -224,8 +226,11 @@ enum HPI_DESTNODES { /** RTP stream output node - This node is a source for packets of RTP audio samples that are sent to other devices. */ HPI_DESTNODE_RTP_SOURCE = 208, + HPI_DESTNODE_AVB = 209, /**< AVB output stream */ + HPI_DESTNODE_INTERNAL = 210, /**< node internal to the device. */ + HPI_DESTNODE_BLULINK = 211, /**< BLU-link output channel. */ /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ - HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */ + HPI_DESTNODE_LAST_INDEX = 211 /**< largest ID */ /* AX6 max destnode types = 15 */ }; @@ -752,7 +757,8 @@ enum HPI_TUNER_BAND { HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/ HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/ HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/ - HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */ + HPI_TUNER_BAND_DAB = 10, + HPI_TUNER_BAND_LAST = 10 /**< the index of the last tuner band. */ }; /** Tuner mode attributes @@ -842,8 +848,10 @@ enum HPI_SAMPLECLOCK_SOURCES { HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, /** From previous adjacent module (ASI2416 only)*/ HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10, +/** Blu link sample clock*/ + HPI_SAMPLECLOCK_SOURCE_BLULINK = 11, /*! Update this if you add a new clock source.*/ - HPI_SAMPLECLOCK_SOURCE_LAST = 10 + HPI_SAMPLECLOCK_SOURCE_LAST = 11 }; /** Equalizer filter types. Used by HPI_ParametricEq_SetBand() -- GitLab From 35a8dc1f66a0fa88144fcbcd562eb2b2c1e36f11 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:50 +1300 Subject: [PATCH 5841/9457] ALSA: asihpi: Logging format improvements Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 85 ++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 46 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 628ef7f146d9..c06903304e12 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -288,21 +288,17 @@ static void print_hwparams(struct snd_pcm_substream *substream, { char name[16]; snd_pcm_debug_name(substream, name, sizeof(name)); - snd_printd("%s HWPARAMS\n", name); - snd_printd(" samplerate %d Hz\n", params_rate(p)); - snd_printd(" channels %d\n", params_channels(p)); - snd_printd(" format %d\n", params_format(p)); - snd_printd(" subformat %d\n", params_subformat(p)); - snd_printd(" buffer %d B\n", params_buffer_bytes(p)); - snd_printd(" period %d B\n", params_period_bytes(p)); - snd_printd(" access %d\n", params_access(p)); - snd_printd(" period_size %d\n", params_period_size(p)); - snd_printd(" periods %d\n", params_periods(p)); - snd_printd(" buffer_size %d\n", params_buffer_size(p)); - snd_printd(" %d B/s\n", params_rate(p) * - params_channels(p) * + snd_printdd("%s HWPARAMS\n", name); + snd_printdd(" samplerate=%dHz channels=%d format=%d subformat=%d\n", + params_rate(p), params_channels(p), + params_format(p), params_subformat(p)); + snd_printdd(" buffer=%dB period=%dB period_size=%dB periods=%d\n", + params_buffer_bytes(p), params_period_bytes(p), + params_period_size(p), params_periods(p)); + snd_printdd(" buffer_size=%d access=%d data_rate=%dB/s\n", + params_buffer_size(p), params_access(p), + params_rate(p) * params_channels(p) * snd_pcm_format_width(params_format(p)) / 8); - } static snd_pcm_format_t hpi_to_alsa_formats[] = { @@ -480,7 +476,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, params_buffer_bytes(params), runtime->dma_addr); if (err == 0) { snd_printdd( - "stream_host_buffer_attach succeeded %u %lu\n", + "stream_host_buffer_attach success %u %lu\n", params_buffer_bytes(params), (unsigned long)runtime->dma_addr); } else { @@ -490,12 +486,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, } err = hpi_stream_get_info_ex(dpcm->h_stream, NULL, - &dpcm->hpi_buffer_attached, - NULL, NULL, NULL); - - snd_printdd("stream_host_buffer_attach status 0x%x\n", - dpcm->hpi_buffer_attached); - + &dpcm->hpi_buffer_attached, NULL, NULL, NULL); } bytes_per_sec = params_rate(params) * params_channels(params); width = snd_pcm_format_width(params_format(params)); @@ -563,10 +554,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, char name[16]; snd_pcm_debug_name(substream, name, sizeof(name)); - snd_printdd("%s trigger\n", name); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + snd_printdd("%s trigger start\n", name); snd_pcm_group_for_each_entry(s, substream) { struct snd_pcm_runtime *runtime = s->runtime; struct snd_card_asihpi_pcm *ds = runtime->private_data; @@ -587,7 +578,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, * data?? */ unsigned int preload = ds->period_bytes * 1; - snd_printddd("%d preload x%x\n", s->number, preload); + snd_printddd("%d preload %d\n", s->number, preload); hpi_handle_error(hpi_outstream_write_buf( ds->h_stream, &runtime->dma_area[0], @@ -610,7 +601,6 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } else break; } - snd_printdd("start\n"); /* start the master stream */ snd_card_asihpi_pcm_timer_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || @@ -619,6 +609,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_STOP: + snd_printdd("%s trigger stop\n", name); snd_card_asihpi_pcm_timer_stop(substream); snd_pcm_group_for_each_entry(s, substream) { if (snd_pcm_substream_chip(s) != card) @@ -637,7 +628,6 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } else break; } - snd_printdd("stop\n"); /* _prepare and _hwparams reset the stream */ hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); @@ -650,12 +640,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_printdd("pause release\n"); + snd_printdd("%s trigger pause release\n", name); hpi_handle_error(hpi_stream_start(dpcm->h_stream)); snd_card_asihpi_pcm_timer_start(substream); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - snd_printdd("pause\n"); + snd_printdd("%s trigger pause push\n", name); snd_card_asihpi_pcm_timer_stop(substream); hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); break; @@ -730,7 +720,6 @@ static void snd_card_asihpi_timer_function(unsigned long data) snd_pcm_debug_name(substream, name, sizeof(name)); - snd_printdd("%s snd_card_asihpi_timer_function\n", name); /* find minimum newdata and buffer pos in group */ snd_pcm_group_for_each_entry(s, substream) { @@ -790,19 +779,20 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } - snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n", + snd_printddd("timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n", + name, s->number, state, + ds->pcm_buf_elapsed_dma_ofs, + ds->pcm_buf_host_rw_ofs, + pcm_buf_dma_ofs, + (int)bytes_avail, + + (int)on_card_bytes, + buffer_size-bytes_avail, (unsigned long)frames_to_bytes(runtime, runtime->status->hw_ptr), (unsigned long)frames_to_bytes(runtime, - runtime->control->appl_ptr)); - - snd_printdd("%d S=%d, " - "rw=0x%04X, dma=0x%04X, left=0x%04X, " - "aux=0x%04X space=0x%04X\n", - s->number, state, - ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, - (int)bytes_avail, - (int)on_card_bytes, buffer_size-bytes_avail); + runtime->control->appl_ptr) + ); loops++; } pcm_buf_dma_ofs = min_buf_pos; @@ -820,7 +810,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) next_jiffies = max(next_jiffies, 1U); dpcm->timer.expires = jiffies + next_jiffies; - snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n", + snd_printddd("timer2, jif=%d, buf_pos=%d, newdata=%d, xfer=%d\n", next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); snd_pcm_group_for_each_entry(s, substream) { @@ -852,7 +842,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) } if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_printddd("P%d write1 0x%04X 0x%04X\n", + snd_printddd("write1, P=%d, xfer=%d, buf_ofs=%d\n", s->number, xfer1, buf_ofs); hpi_handle_error( hpi_outstream_write_buf( @@ -862,7 +852,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) if (xfer2) { pd = s->runtime->dma_area; - snd_printddd("P%d write2 0x%04X 0x%04X\n", + snd_printddd("write2, P=%d, xfer=%d, buf_ofs=%d\n", s->number, xfercount - xfer1, buf_ofs); hpi_handle_error( @@ -872,7 +862,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) &ds->format)); } } else { - snd_printddd("C%d read1 0x%04x\n", + snd_printddd("read1, C=%d, xfer=%d\n", s->number, xfer1); hpi_handle_error( hpi_instream_read_buf( @@ -880,7 +870,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) pd, xfer1)); if (xfer2) { pd = s->runtime->dma_area; - snd_printddd("C%d read2 0x%04x\n", + snd_printddd("read2, C=%d, xfer=%d\n", s->number, xfer2); hpi_handle_error( hpi_instream_read_buf( @@ -933,7 +923,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_debug_name(substream, name, sizeof(name)); ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr); + snd_printddd("%s, pointer=%ld\n", name, (unsigned long)ptr); return ptr; } @@ -1081,9 +1071,10 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; + char name[16]; + snd_pcm_debug_name(substream, name, sizeof(name)); - snd_printddd("capture pointer %d=%d\n", - substream->number, dpcm->pcm_buf_dma_ofs); + snd_printddd("%s, pointer=%d\n", name, dpcm->pcm_buf_dma_ofs); /* NOTE Unlike playback can't use actual samples_played for the capture position, because those samples aren't yet in the local buffer available for reading. @@ -2867,6 +2858,8 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->in_min_chans = 1; } + snd_printk(KERN_INFO "update_interval_frames: %d", + asihpi->update_interval_frames); snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n", asihpi->can_dma, asihpi->support_grouping, -- GitLab From e51c58c982a0f81baa6fdee7331a8700c8586be5 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:51 +1300 Subject: [PATCH 5842/9457] ALSA: asihpi: Use CONFIG_64BIT directly Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpi_internal.h | 16 ++++++++++------ sound/pci/asihpi/hpios.h | 4 ---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index bc86cb726d79..c9bdc284cdaf 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -554,17 +554,21 @@ struct hpi_pci { struct pci_dev *pci_dev; }; +/** Adapter specification resource */ +struct hpi_adapter_specification { + u32 type; + u8 modules[4]; +}; + struct hpi_resource { union { const struct hpi_pci *pci; const char *net_if; + struct hpi_adapter_specification adapter_spec; + const void *sw_if; } r; -#ifndef HPI64BIT /* keep structure size constant */ - u32 pad_to64; -#endif u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */ u16 padding; - }; /** Format info used inside struct hpi_message @@ -582,7 +586,7 @@ struct hpi_msg_format { struct hpi_msg_data { struct hpi_msg_format format; u8 *pb_data; -#ifndef HPI64BIT +#ifndef CONFIG_64BIT u32 padding; #endif u32 data_size; @@ -595,7 +599,7 @@ struct hpi_data_legacy32 { u32 data_size; }; -#ifdef HPI64BIT +#ifdef CONFIG_64BIT /* Compatibility version of struct hpi_data*/ struct hpi_data_compat32 { struct hpi_msg_format format; diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index d3fbd0d76c37..d17d017940d8 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h @@ -41,10 +41,6 @@ HPI Operating System Specific macros for Linux Kernel driver #define HPI_NO_OS_FILE_OPS -#ifdef CONFIG_64BIT -#define HPI64BIT -#endif - /** Details of a memory area allocated with pci_alloc_consistent Need all info for parameters to pci_free_consistent */ -- GitLab From c1464a885444dd7e9c4491177ee102b64adc46c5 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:52 +1300 Subject: [PATCH 5843/9457] ALSA: asihpi: Refactor control cache code. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpicmn.c | 107 ++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 7ed5c26c3737..c7751243dc42 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -206,6 +206,14 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) struct hpi_control_cache_info *info = (struct hpi_control_cache_info *) &p_master_cache[byte_count]; + u16 control_index = info->control_index; + + if (control_index >= pC->control_count) { + HPI_DEBUG_LOG(INFO, + "adap %d control index %d out of range, cache not ready?\n", + pC->adap_idx, control_index); + return 0; + } if (!info->size_in32bit_words) { if (!i) { @@ -225,10 +233,10 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) } if (info->control_type) { - pC->p_info[info->control_index] = info; + pC->p_info[control_index] = info; cached++; } else { /* dummy cache entry */ - pC->p_info[info->control_index] = NULL; + pC->p_info[control_index] = NULL; } byte_count += info->size_in32bit_words * 4; @@ -309,35 +317,18 @@ static const struct pad_ofs_size pad_desc[] = { /** CheckControlCache checks the cache and fills the struct hpi_response * accordingly. It returns one if a cache hit occurred, zero otherwise. */ -short hpi_check_control_cache(struct hpi_control_cache *p_cache, +short hpi_check_control_cache_single(struct hpi_control_cache_single *pC, struct hpi_message *phm, struct hpi_response *phr) { - short found = 1; - struct hpi_control_cache_info *pI; - struct hpi_control_cache_single *pC; size_t response_size; - if (!find_control(phm->obj_index, p_cache, &pI)) { - HPI_DEBUG_LOG(VERBOSE, - "HPICMN find_control() failed for adap %d\n", - phm->adapter_index); - return 0; - } - - phr->error = 0; - phr->specific_error = 0; - phr->version = 0; + short found = 1; /* set the default response size */ response_size = sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res); - /* pC is the default cached control strucure. May be cast to - something else in the following switch statement. - */ - pC = (struct hpi_control_cache_single *)pI; - - switch (pI->control_type) { + switch (pC->u.i.control_type) { case HPI_CONTROL_METER: if (phm->u.c.attribute == HPI_METER_PEAK) { @@ -467,7 +458,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, break; case HPI_CONTROL_PAD:{ struct hpi_control_cache_pad *p_pad; - p_pad = (struct hpi_control_cache_pad *)pI; + p_pad = (struct hpi_control_cache_pad *)pC; if (!(p_pad->field_valid_flags & (1 << HPI_CTL_ATTR_INDEX(phm->u.c. @@ -531,7 +522,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n", found ? "Cached" : "Uncached", phm->adapter_index, - pI->control_index, pI->control_type, phm->u.c.attribute); + pC->u.i.control_index, pC->u.i.control_type, + phm->u.c.attribute); if (found) { phr->size = (u16)response_size; @@ -543,34 +535,36 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, return found; } -/** Updates the cache with Set values. - -Only update if no error. -Volume and Level return the limited values in the response, so use these -Multiplexer does so use sent values -*/ -void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, +short hpi_check_control_cache(struct hpi_control_cache *p_cache, struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_control_cache_single *pC; struct hpi_control_cache_info *pI; - if (phr->error) - return; - if (!find_control(phm->obj_index, p_cache, &pI)) { HPI_DEBUG_LOG(VERBOSE, "HPICMN find_control() failed for adap %d\n", phm->adapter_index); - return; + return 0; } - /* pC is the default cached control strucure. - May be cast to something else in the following switch statement. - */ - pC = (struct hpi_control_cache_single *)pI; + phr->error = 0; + phr->specific_error = 0; + phr->version = 0; + + return hpi_check_control_cache_single((struct hpi_control_cache_single + *)pI, phm, phr); +} + +/** Updates the cache with Set values. - switch (pI->control_type) { +Only update if no error. +Volume and Level return the limited values in the response, so use these +Multiplexer does so use sent values +*/ +void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single + *pC, struct hpi_message *phm, struct hpi_response *phr) +{ + switch (pC->u.i.control_type) { case HPI_CONTROL_VOLUME: if (phm->u.c.attribute == HPI_VOLUME_GAIN) { pC->u.vol.an_log[0] = phr->u.c.an_log_value[0]; @@ -625,6 +619,30 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, } } +void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, + struct hpi_message *phm, struct hpi_response *phr) +{ + struct hpi_control_cache_single *pC; + struct hpi_control_cache_info *pI; + + if (phr->error) + return; + + if (!find_control(phm->obj_index, p_cache, &pI)) { + HPI_DEBUG_LOG(VERBOSE, + "HPICMN find_control() failed for adap %d\n", + phm->adapter_index); + return; + } + + /* pC is the default cached control strucure. + May be cast to something else in the following switch statement. + */ + pC = (struct hpi_control_cache_single *)pI; + + hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr); +} + /** Allocate control cache. \return Cache pointer, or NULL if allocation fails. @@ -637,12 +655,13 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, if (!p_cache) return NULL; - p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info), - GFP_KERNEL); + p_cache->p_info = + kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL); if (!p_cache->p_info) { kfree(p_cache); return NULL; } + p_cache->cache_size_in_bytes = size_in_bytes; p_cache->control_count = control_count; p_cache->p_cache = p_dsp_control_buffer; -- GitLab From f9a376c3f6d77e59d41350901b2bafbaf8791df0 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:53 +1300 Subject: [PATCH 5844/9457] ALSA: asihpi: Add support for stream interrupt. Some cards have a so-called low-latency mode, in which they present a single multichannel stream with no mixing or samplerate conversion. In this mode the card can generate an interrupt per internal processing block (typically 32 or 64 frames) Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 177 ++++++++++++++++++++++++++------ sound/pci/asihpi/hpi6205.c | 43 ++++++-- sound/pci/asihpi/hpi_internal.h | 4 +- sound/pci/asihpi/hpicmn.h | 19 +++- sound/pci/asihpi/hpioctl.c | 124 ++++++++++++++++++++-- sound/pci/asihpi/hpios.h | 4 + 6 files changed, 321 insertions(+), 50 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index c06903304e12..ae29f30547cc 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -1,6 +1,6 @@ /* * Asihpi soundcard - * Copyright (c) by AudioScience Inc + * Copyright (c) by AudioScience Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -124,6 +124,16 @@ struct snd_card_asihpi { struct pci_dev *pci; struct hpi_adapter *hpi; + /* In low latency mode there is only one stream, a pointer to its + * private data is stored here on trigger and cleared on stop. + * The interrupt handler uses it as a parameter when calling + * snd_card_asihpi_timer_function(). + */ + struct snd_card_asihpi_pcm *llmode_streampriv; + struct tasklet_struct t; + void (*pcm_start)(struct snd_pcm_substream *substream); + void (*pcm_stop)(struct snd_pcm_substream *substream); + u32 h_mixer; struct clk_cache cc; @@ -544,6 +554,48 @@ static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream) del_timer(&dpcm->timer); } +static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream) +{ + struct snd_card_asihpi_pcm *dpcm; + struct snd_card_asihpi *card; + + BUG_ON(!substream); + + dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; + card = snd_pcm_substream_chip(substream); + + BUG_ON(in_interrupt()); + tasklet_disable(&card->t); + card->llmode_streampriv = dpcm; + tasklet_enable(&card->t); + + hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, + HPI_ADAPTER_PROPERTY_IRQ_RATE, + card->update_interval_frames, 0)); +} + +static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream) +{ + struct snd_card_asihpi_pcm *dpcm; + struct snd_card_asihpi *card; + + BUG_ON(!substream); + + dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; + card = snd_pcm_substream_chip(substream); + + hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, + HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); + + if (in_interrupt()) + card->llmode_streampriv = NULL; + else { + tasklet_disable(&card->t); + card->llmode_streampriv = NULL; + tasklet_enable(&card->t); + } +} + static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, int cmd) { @@ -602,7 +654,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, break; } /* start the master stream */ - snd_card_asihpi_pcm_timer_start(substream); + card->pcm_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || !card->can_dma) hpi_handle_error(hpi_stream_start(dpcm->h_stream)); @@ -610,7 +662,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: snd_printdd("%s trigger stop\n", name); - snd_card_asihpi_pcm_timer_stop(substream); + card->pcm_stop(substream); snd_pcm_group_for_each_entry(s, substream) { if (snd_pcm_substream_chip(s) != card) continue; @@ -641,12 +693,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: snd_printdd("%s trigger pause release\n", name); + card->pcm_start(substream); hpi_handle_error(hpi_stream_start(dpcm->h_stream)); - snd_card_asihpi_pcm_timer_start(substream); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: snd_printdd("%s trigger pause push\n", name); - snd_card_asihpi_pcm_timer_stop(substream); + card->pcm_stop(substream); hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); break; default: @@ -718,8 +770,8 @@ static void snd_card_asihpi_timer_function(unsigned long data) u32 buffer_size, bytes_avail, samples_played, on_card_bytes; char name[16]; - snd_pcm_debug_name(substream, name, sizeof(name)); + snd_pcm_debug_name(substream, name, sizeof(name)); /* find minimum newdata and buffer pos in group */ snd_pcm_group_for_each_entry(s, substream) { @@ -779,7 +831,8 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } - snd_printddd("timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n", + snd_printddd( + "timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n", name, s->number, state, ds->pcm_buf_elapsed_dma_ofs, ds->pcm_buf_host_rw_ofs, @@ -815,11 +868,13 @@ static void snd_card_asihpi_timer_function(unsigned long data) snd_pcm_group_for_each_entry(s, substream) { struct snd_card_asihpi_pcm *ds = s->runtime->private_data; + runtime = s->runtime; /* don't link Cap and Play */ if (substream->stream != s->stream) continue; + /* Store dma offset for use by pointer callback */ ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; if (xfercount && @@ -878,16 +933,38 @@ static void snd_card_asihpi_timer_function(unsigned long data) pd, xfer2)); } } + /* ? host_rw_ofs always ahead of elapsed_dma_ofs by preload size? */ ds->pcm_buf_host_rw_ofs += xfercount; ds->pcm_buf_elapsed_dma_ofs += xfercount; snd_pcm_period_elapsed(s); } } - if (dpcm->respawn_timer) + if (!card->hpi->interrupt_mode && dpcm->respawn_timer) add_timer(&dpcm->timer); } +static void snd_card_asihpi_int_task(unsigned long data) +{ + struct hpi_adapter *a = (struct hpi_adapter *)data; + struct snd_card_asihpi *asihpi; + + WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); + asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; + if (asihpi->llmode_streampriv) + snd_card_asihpi_timer_function( + (unsigned long)asihpi->llmode_streampriv); +} + +static void snd_card_asihpi_isr(struct hpi_adapter *a) +{ + struct snd_card_asihpi *asihpi; + + WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); + asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; + tasklet_schedule(&asihpi->t); +} + /***************************** PLAYBACK OPS ****************/ static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) @@ -995,13 +1072,22 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) runtime->private_free = snd_card_asihpi_runtime_free; memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback)); - snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; - snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; - /*?snd_card_asihpi_playback.period_bytes_min = - card->out_max_chans * 4096; */ - snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; - snd_card_asihpi_playback.periods_min = PERIODS_MIN; - snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + if (!card->hpi->interrupt_mode) { + snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; + snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_playback.periods_min = PERIODS_MIN; + snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + } else { + size_t pbmin = card->update_interval_frames * + card->out_max_chans; + snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_playback.period_bytes_min = pbmin; + snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_playback.periods_min = PERIODS_MIN; + snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / pbmin; + } + /* snd_card_asihpi_playback.fifo_size = 0; */ snd_card_asihpi_playback.channels_max = card->out_max_chans; snd_card_asihpi_playback.channels_min = card->out_min_chans; @@ -1036,7 +1122,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) card->update_interval_frames); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - card->update_interval_frames * 2, UINT_MAX); + card->update_interval_frames, UINT_MAX); snd_printdd("playback open\n"); @@ -1102,8 +1188,6 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) return 0; } - - static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, u32 h_stream) { @@ -1170,11 +1254,21 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) runtime->private_free = snd_card_asihpi_runtime_free; memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture)); - snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; - snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; - snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; - snd_card_asihpi_capture.periods_min = PERIODS_MIN; - snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + if (!card->hpi->interrupt_mode) { + snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; + snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_capture.periods_min = PERIODS_MIN; + snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + } else { + size_t pbmin = card->update_interval_frames * + card->out_max_chans; + snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_capture.period_bytes_min = pbmin; + snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_capture.periods_min = PERIODS_MIN; + snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / pbmin; + } /* snd_card_asihpi_capture.fifo_size = 0; */ snd_card_asihpi_capture.channels_max = card->in_max_chans; snd_card_asihpi_capture.channels_min = card->in_min_chans; @@ -1199,7 +1293,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - card->update_interval_frames * 2, UINT_MAX); + card->update_interval_frames, UINT_MAX); snd_pcm_set_sync(substream); @@ -2444,15 +2538,19 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol, static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi, struct hpi_control *hpi_ctl) { - struct snd_card *card = asihpi->card; + struct snd_card *card; struct snd_kcontrol_new snd_control; - struct clk_cache *clkcache = &asihpi->cc; + struct clk_cache *clkcache; u32 hSC = hpi_ctl->h_control; int has_aes_in = 0; int i, j; u16 source; + if (snd_BUG_ON(!asihpi)) + return -EINVAL; + card = asihpi->card; + clkcache = &asihpi->cc; snd_control.private_value = hpi_ctl->h_control; clkcache->has_local = 0; @@ -2808,6 +2906,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->card = card; asihpi->pci = pci_dev; asihpi->hpi = hpi; + hpi->snd_card = card; snd_printk(KERN_INFO "adapter ID=%4X index=%d\n", asihpi->hpi->adapter->type, adapter_index); @@ -2830,8 +2929,16 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, if (err) asihpi->update_interval_frames = 512; - if (!asihpi->can_dma) - asihpi->update_interval_frames *= 2; + if (hpi->interrupt_mode) { + asihpi->pcm_start = snd_card_asihpi_pcm_int_start; + asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop; + tasklet_init(&asihpi->t, snd_card_asihpi_int_task, + (unsigned long)hpi); + hpi->interrupt_callback = snd_card_asihpi_isr; + } else { + asihpi->pcm_start = snd_card_asihpi_pcm_timer_start; + asihpi->pcm_stop = snd_card_asihpi_pcm_timer_stop; + } hpi_handle_error(hpi_instream_open(adapter_index, 0, &h_stream)); @@ -2841,6 +2948,9 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, hpi_handle_error(hpi_instream_close(h_stream)); + if (!asihpi->can_dma) + asihpi->update_interval_frames *= 2; + err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_CURCHANNELS, &asihpi->in_max_chans, &asihpi->out_max_chans); @@ -2900,7 +3010,6 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, err = snd_card_register(card); if (!err) { - hpi->snd_card = card; dev++; return 0; } @@ -2914,6 +3023,16 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, static void snd_asihpi_remove(struct pci_dev *pci_dev) { struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); + struct snd_card_asihpi *asihpi = hpi->snd_card->private_data; + + /* Stop interrupts */ + if (hpi->interrupt_mode) { + hpi->interrupt_callback = NULL; + hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index, + HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); + tasklet_kill(&asihpi->t); + } + snd_card_free(hpi->snd_card); hpi->snd_card = NULL; asihpi_adapter_remove(pci_dev); diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 4f2873880b16..8d5abfa4e24b 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -163,6 +163,9 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, static void delete_adapter_obj(struct hpi_adapter_obj *pao); +static int adapter_irq_query_and_clear(struct hpi_adapter_obj *pao, + u32 message); + static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr); @@ -283,7 +286,6 @@ static void adapter_message(struct hpi_adapter_obj *pao, case HPI_ADAPTER_DELETE: adapter_delete(pao, phm, phr); break; - default: hw_message(pao, phm, phr); break; @@ -673,6 +675,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); + pao->irq_query_and_clear = adapter_irq_query_and_clear; + pao->instream_host_buffer_status = + phw->p_interface_buffer->instream_host_buffer_status; + pao->outstream_host_buffer_status = + phw->p_interface_buffer->outstream_host_buffer_status; + return hpi_add_adapter(pao); } @@ -713,6 +721,21 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao) /*****************************************************************************/ /* Adapter functions */ +static int adapter_irq_query_and_clear(struct hpi_adapter_obj *pao, + u32 message) +{ + struct hpi_hw_obj *phw = pao->priv; + u32 hsr = 0; + + hsr = ioread32(phw->prHSR); + if (hsr & C6205_HSR_INTSRC) { + /* reset the interrupt from the DSP */ + iowrite32(C6205_HSR_INTSRC, phw->prHSR); + return HPI_IRQ_MIXER; + } + + return HPI_IRQ_NONE; +} /*****************************************************************************/ /* OutStream Host buffer functions */ @@ -1331,17 +1354,21 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, if (boot_code_id[1] != 0) { /* DSP 1 is a C6713 */ /* CLKX0 <- '1' release the C6205 bootmode pulldowns */ - boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202); + boot_loader_write_mem32(pao, 0, 0x018C0024, 0x00002202); hpios_delay_micro_seconds(100); /* Reset the 6713 #1 - revB */ boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); - - /* dummy read every 4 words for 6205 advisory 1.4.4 */ - boot_loader_read_mem32(pao, 0, 0); - + /* value of bit 3 is unknown after DSP reset, other bits shoudl be 0 */ + if (0 != (boot_loader_read_mem32(pao, 0, + (C6205_BAR0_TIMER1_CTL)) & ~8)) + return HPI6205_ERROR_6205_REG; hpios_delay_micro_seconds(100); + /* Release C6713 from reset - revB */ boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4); + if (4 != (boot_loader_read_mem32(pao, 0, + (C6205_BAR0_TIMER1_CTL)) & ~8)) + return HPI6205_ERROR_6205_REG; hpios_delay_micro_seconds(100); } @@ -2089,7 +2116,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, return 0; } - /* Assume buffer of type struct bus_master_interface + /* Assume buffer of type struct bus_master_interface_62 is allocated "noncacheable" */ if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index c9bdc284cdaf..48380ce2c81b 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -686,8 +686,8 @@ union hpi_adapterx_msg { u16 value; } test_assert; struct { - u32 yes; - } irq_query; + u32 message; + } irq; u32 pad[3]; }; diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index e44121283047..46629c2d101b 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h @@ -1,7 +1,7 @@ /** AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -21,7 +21,11 @@ struct hpi_adapter_obj; /* a function that takes an adapter obj and returns an int */ -typedef int adapter_int_func(struct hpi_adapter_obj *pao); +typedef int adapter_int_func(struct hpi_adapter_obj *pao, u32 message); + +#define HPI_IRQ_NONE (0) +#define HPI_IRQ_MESSAGE (1) +#define HPI_IRQ_MIXER (2) struct hpi_adapter_obj { struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */ @@ -33,6 +37,9 @@ struct hpi_adapter_obj { u16 dsp_crashed; u16 has_control_cache; void *priv; + adapter_int_func *irq_query_and_clear; + struct hpi_hostbuffer_status *instream_host_buffer_status; + struct hpi_hostbuffer_status *outstream_host_buffer_status; }; struct hpi_control_cache { @@ -55,13 +62,21 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao); short hpi_check_control_cache(struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr); + +short hpi_check_control_cache_single(struct hpi_control_cache_single *pC, + struct hpi_message *phm, struct hpi_response *phr); + struct hpi_control_cache *hpi_alloc_control_cache(const u32 number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer); + void hpi_free_control_cache(struct hpi_control_cache *p_cache); void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr); +void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single + *pC, struct hpi_message *phm, struct hpi_response *phr); + u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); hpi_handler_func HPI_COMMON; diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 7f0272032fbb..9454932fc9c0 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -1,7 +1,8 @@ /******************************************************************************* - AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Common Linux HPI ioctl and module probe/remove functions + + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -12,11 +13,6 @@ 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 - -Common Linux HPI ioctl and module probe/remove functions *******************************************************************************/ #define SOURCEFILE_NAME "hpioctl.c" @@ -29,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions #include "hpicmn.h" #include +#include #include #include #include @@ -307,10 +304,38 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return err; } +static int asihpi_irq_count; + +static irqreturn_t asihpi_isr(int irq, void *dev_id) +{ + struct hpi_adapter *a = dev_id; + int handled; + + if (!a->adapter->irq_query_and_clear) { + pr_err("asihpi_isr ASI%04X:%d no handler\n", a->adapter->type, + a->adapter->index); + return IRQ_NONE; + } + + handled = a->adapter->irq_query_and_clear(a->adapter, 0); + + if (!handled) + return IRQ_NONE; + + asihpi_irq_count++; + /* printk(KERN_INFO "asihpi_isr %d ASI%04X:%d irq handled\n", + asihpi_irq_count, a->adapter->type, a->adapter->index); */ + + if (a->interrupt_callback) + a->interrupt_callback(a); + + return IRQ_HANDLED; +} + int asihpi_adapter_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { - int idx, nm; + int idx, nm, low_latency_mode = 0, irq_supported = 0; int adapter_index; unsigned int memlen; struct hpi_message hm; @@ -388,8 +413,39 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, hm.adapter_index = adapter.adapter->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); - if (hr.error) + if (hr.error) { + HPI_DEBUG_LOG(ERROR, "HPI_ADAPTER_OPEN failed, aborting\n"); + goto err; + } + + /* Check if current mode == Low Latency mode */ + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_GET_MODE); + hm.adapter_index = adapter.adapter->index; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); + + if (hr.error) { + HPI_DEBUG_LOG(ERROR, + "HPI_ADAPTER_GET_MODE failed, aborting\n"); goto err; + } + + if (hr.u.ax.mode.adapter_mode == HPI_ADAPTER_MODE_LOW_LATENCY) + low_latency_mode = 1; + + /* Check if IRQs are supported */ + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_GET_PROPERTY); + hm.adapter_index = adapter.adapter->index; + hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); + if (hr.error || !hr.u.ax.property_get.parameter1) { + dev_info(&pci_dev->dev, + "IRQs not supported by adapter at index %d\n", + adapter.adapter->index); + } else { + irq_supported = 1; + } /* WARNING can't init mutex in 'adapter' * and then copy it to adapters[] ?!?! @@ -398,6 +454,44 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, mutex_init(&adapters[adapter_index].mutex); pci_set_drvdata(pci_dev, &adapters[adapter_index]); + if (low_latency_mode && irq_supported) { + if (!adapter.adapter->irq_query_and_clear) { + dev_err(&pci_dev->dev, + "no IRQ handler for adapter %d, aborting\n", + adapter.adapter->index); + goto err; + } + + /* Disable IRQ generation on DSP side by setting the rate to 0 */ + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_SET_PROPERTY); + hm.adapter_index = adapter.adapter->index; + hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_IRQ_RATE; + hm.u.ax.property_set.parameter1 = 0; + hm.u.ax.property_set.parameter2 = 0; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); + if (hr.error) { + HPI_DEBUG_LOG(ERROR, + "HPI_ADAPTER_GET_MODE failed, aborting\n"); + goto err; + } + + /* Note: request_irq calls asihpi_isr here */ + if (request_irq(pci_dev->irq, asihpi_isr, IRQF_SHARED, + "asihpi", &adapters[adapter_index])) { + dev_err(&pci_dev->dev, "request_irq(%d) failed\n", + pci_dev->irq); + goto err; + } + + adapters[adapter_index].interrupt_mode = 1; + + dev_info(&pci_dev->dev, "using irq %d\n", pci_dev->irq); + adapters[adapter_index].irq = pci_dev->irq; + } else { + dev_info(&pci_dev->dev, "using polled mode\n"); + } + dev_info(&pci_dev->dev, "probe succeeded for ASI%04X HPI index %d\n", adapter.adapter->type, adapter_index); @@ -431,6 +525,15 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev) pa = pci_get_drvdata(pci_dev); pci = pa->adapter->pci; + /* Disable IRQ generation on DSP side */ + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_SET_PROPERTY); + hm.adapter_index = pa->adapter->index; + hm.u.ax.property_set.property = HPI_ADAPTER_PROPERTY_IRQ_RATE; + hm.u.ax.property_set.parameter1 = 0; + hm.u.ax.property_set.parameter2 = 0; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, HPI_ADAPTER_DELETE); hm.adapter_index = pa->adapter->index; @@ -442,6 +545,9 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev) iounmap(pci.ap_mem_base[idx]); } + if (pa->irq) + free_irq(pa->irq, pa); + if (pa->p_buffer) vfree(pa->p_buffer); diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index d17d017940d8..4e383601b9cf 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h @@ -151,6 +151,10 @@ struct hpi_adapter { struct hpi_adapter_obj *adapter; struct snd_card *snd_card; + int irq; + int interrupt_mode; + void (*interrupt_callback) (struct hpi_adapter *); + /* mutex prevents contention for one card between multiple user programs (via ioctl) */ struct mutex mutex; -- GitLab From 5bc91f5b3c732bdb3b9e7cc8bd27969d25015bcd Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:54 +1300 Subject: [PATCH 5845/9457] ALSA: asihpi: Turn off msg/resp logging after DSP has crashed. Prevents spewing of useless messages if app keeps trying to access the card. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpimsgx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index d4790ddc225c..736f45337fc7 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -35,6 +35,7 @@ static struct pci_device_id asihpi_pci_tbl[] = { static struct hpios_spinlock msgx_lock; static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS]; +static int logging_enabled = 1; static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci *pci_info) @@ -312,7 +313,9 @@ static void instream_message(struct hpi_message *phm, void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, void *h_owner) { - HPI_DEBUG_MESSAGE(DEBUG, phm); + + if (logging_enabled) + HPI_DEBUG_MESSAGE(DEBUG, phm); if (phm->type != HPI_TYPE_REQUEST) { hpi_init_response(phr, phm->object, phm->function, @@ -352,8 +355,14 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr, hw_entry_point(phm, phr); break; } - HPI_DEBUG_RESPONSE(phr); + if (logging_enabled) + HPI_DEBUG_RESPONSE(phr); + + if (phr->error >= HPI_ERROR_DSP_COMMUNICATION) { + hpi_debug_level_set(HPI_DEBUG_LEVEL_ERROR); + logging_enabled = 0; + } } static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) -- GitLab From 12eb0898741870882ca474708e811983d5a5d768 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:55 +1300 Subject: [PATCH 5846/9457] ALSA: asihpi: Use standard printk helpers Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index ae29f30547cc..e9273fb2a505 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -380,7 +380,7 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, HPI_CONTROL_SAMPLECLOCK, &h_control); if (err) { - snd_printk(KERN_ERR + dev_err(&asihpi->pci->dev, "No local sampleclock, err %d\n", err); } @@ -1438,7 +1438,7 @@ static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, if (err < 0) return err; else if (mixer_dump) - snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index); + dev_info(&asihpi->pci->dev, "added %s(%d)\n", ctl->name, ctl->index); return 0; } @@ -2652,7 +2652,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) if (err) { if (err == HPI_ERROR_CONTROL_DISABLED) { if (mixer_dump) - snd_printk(KERN_INFO + dev_info(&asihpi->pci->dev, "Disabled HPI Control(%d)\n", idx); continue; @@ -2717,9 +2717,8 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) case HPI_CONTROL_COMPANDER: default: if (mixer_dump) - snd_printk(KERN_INFO - "Untranslated HPI Control" - "(%d) %d %d %d %d %d\n", + dev_info(&asihpi->pci->dev, + "Untranslated HPI Control (%d) %d %d %d %d %d\n", idx, hpi_ctl.control_type, hpi_ctl.src_node_type, @@ -2734,7 +2733,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) if (HPI_ERROR_INVALID_OBJ_INDEX != err) hpi_handle_error(err); - snd_printk(KERN_INFO "%d mixer controls found\n", idx); + dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx); return 0; } @@ -2897,8 +2896,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, &card); if (err < 0) return err; - snd_printk(KERN_WARNING - "**** WARNING **** Adapter index %d->ALSA index %d\n", + dev_warn(&pci_dev->dev, "Adapter index %d->ALSA index %d\n", adapter_index, card->number); } @@ -2908,9 +2906,6 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->hpi = hpi; hpi->snd_card = card; - snd_printk(KERN_INFO "adapter ID=%4X index=%d\n", - asihpi->hpi->adapter->type, adapter_index); - err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_CAPS1, NULL, &asihpi->support_grouping); @@ -2968,22 +2963,21 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->in_min_chans = 1; } - snd_printk(KERN_INFO "update_interval_frames: %d", - asihpi->update_interval_frames); - snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n", + dev_info(&pci_dev->dev, "Has dma:%d, grouping:%d, mrx:%d, uif:%d\n", asihpi->can_dma, asihpi->support_grouping, - asihpi->support_mrx + asihpi->support_mrx, + asihpi->update_interval_frames ); err = snd_card_asihpi_pcm_new(asihpi, 0); if (err < 0) { - snd_printk(KERN_ERR "pcm_new failed\n"); + dev_err(&pci_dev->dev, "pcm_new failed\n"); goto __nodev; } err = snd_card_asihpi_mixer_new(asihpi); if (err < 0) { - snd_printk(KERN_ERR "mixer_new failed\n"); + dev_err(&pci_dev->dev, "mixer_new failed\n"); goto __nodev; } @@ -3015,7 +3009,7 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev, } __nodev: snd_card_free(card); - snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err); + dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err); return err; } -- GitLab From dc612838eac746b11bb4e5d923dafeea0ba7e81b Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:56 +1300 Subject: [PATCH 5847/9457] ALSA: asihpi: don't fail probe if adapter mode read fails Only determining if low latency mode is enabled. Failure indicates adapter has no modes Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpioctl.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 9454932fc9c0..e457eb80658b 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -424,14 +424,13 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, hm.adapter_index = adapter.adapter->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); - if (hr.error) { - HPI_DEBUG_LOG(ERROR, - "HPI_ADAPTER_GET_MODE failed, aborting\n"); - goto err; - } - - if (hr.u.ax.mode.adapter_mode == HPI_ADAPTER_MODE_LOW_LATENCY) + if (!hr.error + && hr.u.ax.mode.adapter_mode == HPI_ADAPTER_MODE_LOW_LATENCY) low_latency_mode = 1; + else + dev_info(&pci_dev->dev, + "Adapter at index %d is not in low latency mode\n", + adapter.adapter->index); /* Check if IRQs are supported */ hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, -- GitLab From 51e6f47dd2e3463dac6f37128fd7b7cb40c500de Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Thu, 20 Nov 2014 16:22:57 +1300 Subject: [PATCH 5848/9457] ALSA: asihpi: used parts of message/response are zeroed before use Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpimsginit.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c index 032d563e3708..7eb617175fde 100644 --- a/sound/pci/asihpi/hpimsginit.c +++ b/sound/pci/asihpi/hpimsginit.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2011 AudioScience Inc. + Copyright (C) 1997-2014 AudioScience Inc. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -37,11 +37,15 @@ static u16 gwSSX2_bypass; static void hpi_init_message(struct hpi_message *phm, u16 object, u16 function) { - memset(phm, 0, sizeof(*phm)); + u16 size; + if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) - phm->size = msg_size[object]; + size = msg_size[object]; else - phm->size = sizeof(*phm); + size = sizeof(*phm); + + memset(phm, 0, size); + phm->size = size; if (gwSSX2_bypass) phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; @@ -60,12 +64,16 @@ static void hpi_init_message(struct hpi_message *phm, u16 object, void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, u16 error) { - memset(phr, 0, sizeof(*phr)); - phr->type = HPI_TYPE_RESPONSE; + u16 size; + if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) - phr->size = res_size[object]; + size = res_size[object]; else - phr->size = sizeof(*phr); + size = sizeof(*phr); + + memset(phr, 0, sizeof(*phr)); + phr->size = size; + phr->type = HPI_TYPE_RESPONSE; phr->object = object; phr->function = function; phr->error = error; @@ -86,7 +94,7 @@ void hpi_init_message_response(struct hpi_message *phm, static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, u16 object, u16 function) { - memset(phm, 0, sizeof(*phm)); + memset(phm, 0, size); if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { phm->size = size; phm->type = HPI_TYPE_REQUEST; @@ -100,7 +108,9 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, u16 object, u16 function) { - memset(phr, 0, sizeof(*phr)); + (void)object; + (void)function; + memset(phr, 0, size); phr->size = size; phr->version = 1; phr->type = HPI_TYPE_RESPONSE; -- GitLab From 2f90ade661b3bdcde08e50c02c564e139300e263 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 20 Nov 2014 16:30:02 -0800 Subject: [PATCH 5849/9457] i40e: enable fdb add code, remove unused code The original FDB code submission wasn't correct and the code wasn't enabled. This removes some dead code (can use the common kernel code for fdb_del and fdb_dump) and correctly enables the fdb_add function pointer. The fdb_add functionality is important to i40e because it is needed for a workaround to allow bridges to work correctly on the i40e hardware. Reported-by: Jiri Pirko Signed-off-by: Jesse Brandeburg Acked-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/i40e/i40e_main.c | 71 +++------------------ 1 file changed, 8 insertions(+), 63 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3913329998bf..7262077ad547 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7526,18 +7526,18 @@ static int i40e_get_phys_port_id(struct net_device *netdev, return 0; } -#ifdef HAVE_FDB_OPS -#ifdef USE_CONST_DEV_UC_CHAR +/** + * i40e_ndo_fdb_add - add an entry to the hardware database + * @ndm: the input from the stack + * @tb: pointer to array of nladdr (unused) + * @dev: the net device pointer + * @addr: the MAC address entry being added + * @flags: instructions from stack about fdb operation + */ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev, const unsigned char *addr, u16 flags) -#else -static int i40e_ndo_fdb_add(struct ndmsg *ndm, - struct net_device *dev, - unsigned char *addr, - u16 flags) -#endif { struct i40e_netdev_priv *np = netdev_priv(dev); struct i40e_pf *pf = np->vsi->back; @@ -7568,55 +7568,6 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, return err; } -#ifndef USE_DEFAULT_FDB_DEL_DUMP -#ifdef USE_CONST_DEV_UC_CHAR -static int i40e_ndo_fdb_del(struct ndmsg *ndm, - struct net_device *dev, - const unsigned char *addr) -#else -static int i40e_ndo_fdb_del(struct ndmsg *ndm, - struct net_device *dev, - unsigned char *addr) -#endif -{ - struct i40e_netdev_priv *np = netdev_priv(dev); - struct i40e_pf *pf = np->vsi->back; - int err = -EOPNOTSUPP; - - if (ndm->ndm_state & NUD_PERMANENT) { - netdev_info(dev, "FDB only supports static addresses\n"); - return -EINVAL; - } - - if (pf->flags & I40E_FLAG_SRIOV_ENABLED) { - if (is_unicast_ether_addr(addr)) - err = dev_uc_del(dev, addr); - else if (is_multicast_ether_addr(addr)) - err = dev_mc_del(dev, addr); - else - err = -EINVAL; - } - - return err; -} - -static int i40e_ndo_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, - struct net_device *dev, - struct net_device *filter_dev, - int idx) -{ - struct i40e_netdev_priv *np = netdev_priv(dev); - struct i40e_pf *pf = np->vsi->back; - - if (pf->flags & I40E_FLAG_SRIOV_ENABLED) - idx = ndo_dflt_fdb_dump(skb, cb, dev, filter_dev, idx); - - return idx; -} - -#endif /* USE_DEFAULT_FDB_DEL_DUMP */ -#endif /* HAVE_FDB_OPS */ static const struct net_device_ops i40e_netdev_ops = { .ndo_open = i40e_open, .ndo_stop = i40e_close, @@ -7650,13 +7601,7 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_del_vxlan_port = i40e_del_vxlan_port, #endif .ndo_get_phys_port_id = i40e_get_phys_port_id, -#ifdef HAVE_FDB_OPS .ndo_fdb_add = i40e_ndo_fdb_add, -#ifndef USE_DEFAULT_FDB_DEL_DUMP - .ndo_fdb_del = i40e_ndo_fdb_del, - .ndo_fdb_dump = i40e_ndo_fdb_dump, -#endif -#endif }; /** -- GitLab From 77a80e23cc0d1fb19e611e7108b3f6a233a67901 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 21 Nov 2014 12:52:01 +0530 Subject: [PATCH 5850/9457] RDMA/cxgb4: Cleanup Filter related macros/register defines This patch cleanups all filter related macros/register defines that are defined in t4fw_api.h and the affected files. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 14 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 68 +- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 8 +- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 584 +++++++++--------- 4 files changed, 337 insertions(+), 337 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 83fa16fa4644..0ad8e2acd895 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1762,10 +1762,10 @@ static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) req->le.pport = sin->sin_port; req->le.u.ipv4.pip = sin->sin_addr.s_addr; req->tcb.t_state_to_astid = - htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_SENT) | - V_FW_OFLD_CONNECTION_WR_ASTID(atid)); + htonl(FW_OFLD_CONNECTION_WR_T_STATE_V(TCP_SYN_SENT) | + FW_OFLD_CONNECTION_WR_ASTID_V(atid)); req->tcb.cplrxdataack_cplpassacceptrpl = - htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK); + htons(FW_OFLD_CONNECTION_WR_CPLRXDATAACK_F); req->tcb.tx_max = (__force __be32) jiffies; req->tcb.rcv_adv = htons(1); best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx, @@ -3539,7 +3539,7 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, memset(req, 0, sizeof(*req)); req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL_F); req->len16_pkd = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*req), 16))); - req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL); + req->le.version_cpl = htonl(FW_OFLD_CONNECTION_WR_CPL_F); req->le.filter = (__force __be32) filter; req->le.lport = lport; req->le.pport = rport; @@ -3548,9 +3548,9 @@ static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb, req->tcb.rcv_nxt = htonl(rcv_isn + 1); req->tcb.rcv_adv = htons(window); req->tcb.t_state_to_astid = - htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_RECV) | - V_FW_OFLD_CONNECTION_WR_RCV_SCALE(cpl->tcpopt.wsf) | - V_FW_OFLD_CONNECTION_WR_ASTID( + htonl(FW_OFLD_CONNECTION_WR_T_STATE_V(TCP_SYN_RECV) | + FW_OFLD_CONNECTION_WR_RCV_SCALE_V(cpl->tcpopt.wsf) | + FW_OFLD_CONNECTION_WR_ASTID_V( GET_PASS_OPEN_TID(ntohl(cpl->tos_stid)))); /* diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 19ffe9bc1933..6b6d7e16d4ed 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1342,49 +1342,49 @@ static int set_filter_wr(struct adapter *adapter, int fidx) fwr->op_pkd = htonl(FW_WR_OP_V(FW_FILTER_WR)); fwr->len16_pkd = htonl(FW_WR_LEN16_V(sizeof(*fwr)/16)); fwr->tid_to_iq = - htonl(V_FW_FILTER_WR_TID(ftid) | - V_FW_FILTER_WR_RQTYPE(f->fs.type) | - V_FW_FILTER_WR_NOREPLY(0) | - V_FW_FILTER_WR_IQ(f->fs.iq)); + htonl(FW_FILTER_WR_TID_V(ftid) | + FW_FILTER_WR_RQTYPE_V(f->fs.type) | + FW_FILTER_WR_NOREPLY_V(0) | + FW_FILTER_WR_IQ_V(f->fs.iq)); fwr->del_filter_to_l2tix = - htonl(V_FW_FILTER_WR_RPTTID(f->fs.rpttid) | - V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) | - V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) | - V_FW_FILTER_WR_MASKHASH(f->fs.maskhash) | - V_FW_FILTER_WR_DIRSTEERHASH(f->fs.dirsteerhash) | - V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) | - V_FW_FILTER_WR_DMAC(f->fs.newdmac) | - V_FW_FILTER_WR_SMAC(f->fs.newsmac) | - V_FW_FILTER_WR_INSVLAN(f->fs.newvlan == VLAN_INSERT || + htonl(FW_FILTER_WR_RPTTID_V(f->fs.rpttid) | + FW_FILTER_WR_DROP_V(f->fs.action == FILTER_DROP) | + FW_FILTER_WR_DIRSTEER_V(f->fs.dirsteer) | + FW_FILTER_WR_MASKHASH_V(f->fs.maskhash) | + FW_FILTER_WR_DIRSTEERHASH_V(f->fs.dirsteerhash) | + FW_FILTER_WR_LPBK_V(f->fs.action == FILTER_SWITCH) | + FW_FILTER_WR_DMAC_V(f->fs.newdmac) | + FW_FILTER_WR_SMAC_V(f->fs.newsmac) | + FW_FILTER_WR_INSVLAN_V(f->fs.newvlan == VLAN_INSERT || f->fs.newvlan == VLAN_REWRITE) | - V_FW_FILTER_WR_RMVLAN(f->fs.newvlan == VLAN_REMOVE || + FW_FILTER_WR_RMVLAN_V(f->fs.newvlan == VLAN_REMOVE || f->fs.newvlan == VLAN_REWRITE) | - V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) | - V_FW_FILTER_WR_TXCHAN(f->fs.eport) | - V_FW_FILTER_WR_PRIO(f->fs.prio) | - V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0)); + FW_FILTER_WR_HITCNTS_V(f->fs.hitcnts) | + FW_FILTER_WR_TXCHAN_V(f->fs.eport) | + FW_FILTER_WR_PRIO_V(f->fs.prio) | + FW_FILTER_WR_L2TIX_V(f->l2t ? f->l2t->idx : 0)); fwr->ethtype = htons(f->fs.val.ethtype); fwr->ethtypem = htons(f->fs.mask.ethtype); fwr->frag_to_ovlan_vldm = - (V_FW_FILTER_WR_FRAG(f->fs.val.frag) | - V_FW_FILTER_WR_FRAGM(f->fs.mask.frag) | - V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.ivlan_vld) | - V_FW_FILTER_WR_OVLAN_VLD(f->fs.val.ovlan_vld) | - V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.ivlan_vld) | - V_FW_FILTER_WR_OVLAN_VLDM(f->fs.mask.ovlan_vld)); + (FW_FILTER_WR_FRAG_V(f->fs.val.frag) | + FW_FILTER_WR_FRAGM_V(f->fs.mask.frag) | + FW_FILTER_WR_IVLAN_VLD_V(f->fs.val.ivlan_vld) | + FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) | + FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) | + FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld)); fwr->smac_sel = 0; fwr->rx_chan_rx_rpl_iq = - htons(V_FW_FILTER_WR_RX_CHAN(0) | - V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id)); + htons(FW_FILTER_WR_RX_CHAN_V(0) | + FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id)); fwr->maci_to_matchtypem = - htonl(V_FW_FILTER_WR_MACI(f->fs.val.macidx) | - V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) | - V_FW_FILTER_WR_FCOE(f->fs.val.fcoe) | - V_FW_FILTER_WR_FCOEM(f->fs.mask.fcoe) | - V_FW_FILTER_WR_PORT(f->fs.val.iport) | - V_FW_FILTER_WR_PORTM(f->fs.mask.iport) | - V_FW_FILTER_WR_MATCHTYPE(f->fs.val.matchtype) | - V_FW_FILTER_WR_MATCHTYPEM(f->fs.mask.matchtype)); + htonl(FW_FILTER_WR_MACI_V(f->fs.val.macidx) | + FW_FILTER_WR_MACIM_V(f->fs.mask.macidx) | + FW_FILTER_WR_FCOE_V(f->fs.val.fcoe) | + FW_FILTER_WR_FCOEM_V(f->fs.mask.fcoe) | + FW_FILTER_WR_PORT_V(f->fs.val.iport) | + FW_FILTER_WR_PORTM_V(f->fs.mask.iport) | + FW_FILTER_WR_MATCHTYPE_V(f->fs.val.matchtype) | + FW_FILTER_WR_MATCHTYPEM_V(f->fs.mask.matchtype)); fwr->ptcl = f->fs.val.proto; fwr->ptclm = f->fs.mask.proto; fwr->ttyp = f->fs.val.tos; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 4d32df5041f6..0c78be36601e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2556,11 +2556,11 @@ void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid) memset(wr, 0, sizeof(*wr)); wr->op_pkd = htonl(FW_WR_OP_V(FW_FILTER_WR)); wr->len16_pkd = htonl(FW_WR_LEN16_V(sizeof(*wr) / 16)); - wr->tid_to_iq = htonl(V_FW_FILTER_WR_TID(ftid) | - V_FW_FILTER_WR_NOREPLY(qid < 0)); - wr->del_filter_to_l2tix = htonl(F_FW_FILTER_WR_DEL_FILTER); + wr->tid_to_iq = htonl(FW_FILTER_WR_TID_V(ftid) | + FW_FILTER_WR_NOREPLY_V(qid < 0)); + wr->del_filter_to_l2tix = htonl(FW_FILTER_WR_DEL_FILTER_F); if (qid >= 0) - wr->rx_chan_rx_rpl_iq = htons(V_FW_FILTER_WR_RX_RPL_IQ(qid)); + wr->rx_chan_rx_rpl_iq = htons(FW_FILTER_WR_RX_RPL_IQ_V(qid)); } #define INIT_CMD(var, cmd, rd_wr) do { \ diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 6fc46dc11988..3bc5bdb4d334 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -197,239 +197,239 @@ struct fw_filter_wr { __u8 sma[6]; }; -#define S_FW_FILTER_WR_TID 12 -#define M_FW_FILTER_WR_TID 0xfffff -#define V_FW_FILTER_WR_TID(x) ((x) << S_FW_FILTER_WR_TID) -#define G_FW_FILTER_WR_TID(x) \ - (((x) >> S_FW_FILTER_WR_TID) & M_FW_FILTER_WR_TID) - -#define S_FW_FILTER_WR_RQTYPE 11 -#define M_FW_FILTER_WR_RQTYPE 0x1 -#define V_FW_FILTER_WR_RQTYPE(x) ((x) << S_FW_FILTER_WR_RQTYPE) -#define G_FW_FILTER_WR_RQTYPE(x) \ - (((x) >> S_FW_FILTER_WR_RQTYPE) & M_FW_FILTER_WR_RQTYPE) -#define F_FW_FILTER_WR_RQTYPE V_FW_FILTER_WR_RQTYPE(1U) - -#define S_FW_FILTER_WR_NOREPLY 10 -#define M_FW_FILTER_WR_NOREPLY 0x1 -#define V_FW_FILTER_WR_NOREPLY(x) ((x) << S_FW_FILTER_WR_NOREPLY) -#define G_FW_FILTER_WR_NOREPLY(x) \ - (((x) >> S_FW_FILTER_WR_NOREPLY) & M_FW_FILTER_WR_NOREPLY) -#define F_FW_FILTER_WR_NOREPLY V_FW_FILTER_WR_NOREPLY(1U) - -#define S_FW_FILTER_WR_IQ 0 -#define M_FW_FILTER_WR_IQ 0x3ff -#define V_FW_FILTER_WR_IQ(x) ((x) << S_FW_FILTER_WR_IQ) -#define G_FW_FILTER_WR_IQ(x) \ - (((x) >> S_FW_FILTER_WR_IQ) & M_FW_FILTER_WR_IQ) - -#define S_FW_FILTER_WR_DEL_FILTER 31 -#define M_FW_FILTER_WR_DEL_FILTER 0x1 -#define V_FW_FILTER_WR_DEL_FILTER(x) ((x) << S_FW_FILTER_WR_DEL_FILTER) -#define G_FW_FILTER_WR_DEL_FILTER(x) \ - (((x) >> S_FW_FILTER_WR_DEL_FILTER) & M_FW_FILTER_WR_DEL_FILTER) -#define F_FW_FILTER_WR_DEL_FILTER V_FW_FILTER_WR_DEL_FILTER(1U) - -#define S_FW_FILTER_WR_RPTTID 25 -#define M_FW_FILTER_WR_RPTTID 0x1 -#define V_FW_FILTER_WR_RPTTID(x) ((x) << S_FW_FILTER_WR_RPTTID) -#define G_FW_FILTER_WR_RPTTID(x) \ - (((x) >> S_FW_FILTER_WR_RPTTID) & M_FW_FILTER_WR_RPTTID) -#define F_FW_FILTER_WR_RPTTID V_FW_FILTER_WR_RPTTID(1U) - -#define S_FW_FILTER_WR_DROP 24 -#define M_FW_FILTER_WR_DROP 0x1 -#define V_FW_FILTER_WR_DROP(x) ((x) << S_FW_FILTER_WR_DROP) -#define G_FW_FILTER_WR_DROP(x) \ - (((x) >> S_FW_FILTER_WR_DROP) & M_FW_FILTER_WR_DROP) -#define F_FW_FILTER_WR_DROP V_FW_FILTER_WR_DROP(1U) - -#define S_FW_FILTER_WR_DIRSTEER 23 -#define M_FW_FILTER_WR_DIRSTEER 0x1 -#define V_FW_FILTER_WR_DIRSTEER(x) ((x) << S_FW_FILTER_WR_DIRSTEER) -#define G_FW_FILTER_WR_DIRSTEER(x) \ - (((x) >> S_FW_FILTER_WR_DIRSTEER) & M_FW_FILTER_WR_DIRSTEER) -#define F_FW_FILTER_WR_DIRSTEER V_FW_FILTER_WR_DIRSTEER(1U) - -#define S_FW_FILTER_WR_MASKHASH 22 -#define M_FW_FILTER_WR_MASKHASH 0x1 -#define V_FW_FILTER_WR_MASKHASH(x) ((x) << S_FW_FILTER_WR_MASKHASH) -#define G_FW_FILTER_WR_MASKHASH(x) \ - (((x) >> S_FW_FILTER_WR_MASKHASH) & M_FW_FILTER_WR_MASKHASH) -#define F_FW_FILTER_WR_MASKHASH V_FW_FILTER_WR_MASKHASH(1U) - -#define S_FW_FILTER_WR_DIRSTEERHASH 21 -#define M_FW_FILTER_WR_DIRSTEERHASH 0x1 -#define V_FW_FILTER_WR_DIRSTEERHASH(x) ((x) << S_FW_FILTER_WR_DIRSTEERHASH) -#define G_FW_FILTER_WR_DIRSTEERHASH(x) \ - (((x) >> S_FW_FILTER_WR_DIRSTEERHASH) & M_FW_FILTER_WR_DIRSTEERHASH) -#define F_FW_FILTER_WR_DIRSTEERHASH V_FW_FILTER_WR_DIRSTEERHASH(1U) - -#define S_FW_FILTER_WR_LPBK 20 -#define M_FW_FILTER_WR_LPBK 0x1 -#define V_FW_FILTER_WR_LPBK(x) ((x) << S_FW_FILTER_WR_LPBK) -#define G_FW_FILTER_WR_LPBK(x) \ - (((x) >> S_FW_FILTER_WR_LPBK) & M_FW_FILTER_WR_LPBK) -#define F_FW_FILTER_WR_LPBK V_FW_FILTER_WR_LPBK(1U) - -#define S_FW_FILTER_WR_DMAC 19 -#define M_FW_FILTER_WR_DMAC 0x1 -#define V_FW_FILTER_WR_DMAC(x) ((x) << S_FW_FILTER_WR_DMAC) -#define G_FW_FILTER_WR_DMAC(x) \ - (((x) >> S_FW_FILTER_WR_DMAC) & M_FW_FILTER_WR_DMAC) -#define F_FW_FILTER_WR_DMAC V_FW_FILTER_WR_DMAC(1U) - -#define S_FW_FILTER_WR_SMAC 18 -#define M_FW_FILTER_WR_SMAC 0x1 -#define V_FW_FILTER_WR_SMAC(x) ((x) << S_FW_FILTER_WR_SMAC) -#define G_FW_FILTER_WR_SMAC(x) \ - (((x) >> S_FW_FILTER_WR_SMAC) & M_FW_FILTER_WR_SMAC) -#define F_FW_FILTER_WR_SMAC V_FW_FILTER_WR_SMAC(1U) - -#define S_FW_FILTER_WR_INSVLAN 17 -#define M_FW_FILTER_WR_INSVLAN 0x1 -#define V_FW_FILTER_WR_INSVLAN(x) ((x) << S_FW_FILTER_WR_INSVLAN) -#define G_FW_FILTER_WR_INSVLAN(x) \ - (((x) >> S_FW_FILTER_WR_INSVLAN) & M_FW_FILTER_WR_INSVLAN) -#define F_FW_FILTER_WR_INSVLAN V_FW_FILTER_WR_INSVLAN(1U) - -#define S_FW_FILTER_WR_RMVLAN 16 -#define M_FW_FILTER_WR_RMVLAN 0x1 -#define V_FW_FILTER_WR_RMVLAN(x) ((x) << S_FW_FILTER_WR_RMVLAN) -#define G_FW_FILTER_WR_RMVLAN(x) \ - (((x) >> S_FW_FILTER_WR_RMVLAN) & M_FW_FILTER_WR_RMVLAN) -#define F_FW_FILTER_WR_RMVLAN V_FW_FILTER_WR_RMVLAN(1U) - -#define S_FW_FILTER_WR_HITCNTS 15 -#define M_FW_FILTER_WR_HITCNTS 0x1 -#define V_FW_FILTER_WR_HITCNTS(x) ((x) << S_FW_FILTER_WR_HITCNTS) -#define G_FW_FILTER_WR_HITCNTS(x) \ - (((x) >> S_FW_FILTER_WR_HITCNTS) & M_FW_FILTER_WR_HITCNTS) -#define F_FW_FILTER_WR_HITCNTS V_FW_FILTER_WR_HITCNTS(1U) - -#define S_FW_FILTER_WR_TXCHAN 13 -#define M_FW_FILTER_WR_TXCHAN 0x3 -#define V_FW_FILTER_WR_TXCHAN(x) ((x) << S_FW_FILTER_WR_TXCHAN) -#define G_FW_FILTER_WR_TXCHAN(x) \ - (((x) >> S_FW_FILTER_WR_TXCHAN) & M_FW_FILTER_WR_TXCHAN) - -#define S_FW_FILTER_WR_PRIO 12 -#define M_FW_FILTER_WR_PRIO 0x1 -#define V_FW_FILTER_WR_PRIO(x) ((x) << S_FW_FILTER_WR_PRIO) -#define G_FW_FILTER_WR_PRIO(x) \ - (((x) >> S_FW_FILTER_WR_PRIO) & M_FW_FILTER_WR_PRIO) -#define F_FW_FILTER_WR_PRIO V_FW_FILTER_WR_PRIO(1U) - -#define S_FW_FILTER_WR_L2TIX 0 -#define M_FW_FILTER_WR_L2TIX 0xfff -#define V_FW_FILTER_WR_L2TIX(x) ((x) << S_FW_FILTER_WR_L2TIX) -#define G_FW_FILTER_WR_L2TIX(x) \ - (((x) >> S_FW_FILTER_WR_L2TIX) & M_FW_FILTER_WR_L2TIX) - -#define S_FW_FILTER_WR_FRAG 7 -#define M_FW_FILTER_WR_FRAG 0x1 -#define V_FW_FILTER_WR_FRAG(x) ((x) << S_FW_FILTER_WR_FRAG) -#define G_FW_FILTER_WR_FRAG(x) \ - (((x) >> S_FW_FILTER_WR_FRAG) & M_FW_FILTER_WR_FRAG) -#define F_FW_FILTER_WR_FRAG V_FW_FILTER_WR_FRAG(1U) - -#define S_FW_FILTER_WR_FRAGM 6 -#define M_FW_FILTER_WR_FRAGM 0x1 -#define V_FW_FILTER_WR_FRAGM(x) ((x) << S_FW_FILTER_WR_FRAGM) -#define G_FW_FILTER_WR_FRAGM(x) \ - (((x) >> S_FW_FILTER_WR_FRAGM) & M_FW_FILTER_WR_FRAGM) -#define F_FW_FILTER_WR_FRAGM V_FW_FILTER_WR_FRAGM(1U) - -#define S_FW_FILTER_WR_IVLAN_VLD 5 -#define M_FW_FILTER_WR_IVLAN_VLD 0x1 -#define V_FW_FILTER_WR_IVLAN_VLD(x) ((x) << S_FW_FILTER_WR_IVLAN_VLD) -#define G_FW_FILTER_WR_IVLAN_VLD(x) \ - (((x) >> S_FW_FILTER_WR_IVLAN_VLD) & M_FW_FILTER_WR_IVLAN_VLD) -#define F_FW_FILTER_WR_IVLAN_VLD V_FW_FILTER_WR_IVLAN_VLD(1U) - -#define S_FW_FILTER_WR_OVLAN_VLD 4 -#define M_FW_FILTER_WR_OVLAN_VLD 0x1 -#define V_FW_FILTER_WR_OVLAN_VLD(x) ((x) << S_FW_FILTER_WR_OVLAN_VLD) -#define G_FW_FILTER_WR_OVLAN_VLD(x) \ - (((x) >> S_FW_FILTER_WR_OVLAN_VLD) & M_FW_FILTER_WR_OVLAN_VLD) -#define F_FW_FILTER_WR_OVLAN_VLD V_FW_FILTER_WR_OVLAN_VLD(1U) - -#define S_FW_FILTER_WR_IVLAN_VLDM 3 -#define M_FW_FILTER_WR_IVLAN_VLDM 0x1 -#define V_FW_FILTER_WR_IVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_IVLAN_VLDM) -#define G_FW_FILTER_WR_IVLAN_VLDM(x) \ - (((x) >> S_FW_FILTER_WR_IVLAN_VLDM) & M_FW_FILTER_WR_IVLAN_VLDM) -#define F_FW_FILTER_WR_IVLAN_VLDM V_FW_FILTER_WR_IVLAN_VLDM(1U) - -#define S_FW_FILTER_WR_OVLAN_VLDM 2 -#define M_FW_FILTER_WR_OVLAN_VLDM 0x1 -#define V_FW_FILTER_WR_OVLAN_VLDM(x) ((x) << S_FW_FILTER_WR_OVLAN_VLDM) -#define G_FW_FILTER_WR_OVLAN_VLDM(x) \ - (((x) >> S_FW_FILTER_WR_OVLAN_VLDM) & M_FW_FILTER_WR_OVLAN_VLDM) -#define F_FW_FILTER_WR_OVLAN_VLDM V_FW_FILTER_WR_OVLAN_VLDM(1U) - -#define S_FW_FILTER_WR_RX_CHAN 15 -#define M_FW_FILTER_WR_RX_CHAN 0x1 -#define V_FW_FILTER_WR_RX_CHAN(x) ((x) << S_FW_FILTER_WR_RX_CHAN) -#define G_FW_FILTER_WR_RX_CHAN(x) \ - (((x) >> S_FW_FILTER_WR_RX_CHAN) & M_FW_FILTER_WR_RX_CHAN) -#define F_FW_FILTER_WR_RX_CHAN V_FW_FILTER_WR_RX_CHAN(1U) - -#define S_FW_FILTER_WR_RX_RPL_IQ 0 -#define M_FW_FILTER_WR_RX_RPL_IQ 0x3ff -#define V_FW_FILTER_WR_RX_RPL_IQ(x) ((x) << S_FW_FILTER_WR_RX_RPL_IQ) -#define G_FW_FILTER_WR_RX_RPL_IQ(x) \ - (((x) >> S_FW_FILTER_WR_RX_RPL_IQ) & M_FW_FILTER_WR_RX_RPL_IQ) - -#define S_FW_FILTER_WR_MACI 23 -#define M_FW_FILTER_WR_MACI 0x1ff -#define V_FW_FILTER_WR_MACI(x) ((x) << S_FW_FILTER_WR_MACI) -#define G_FW_FILTER_WR_MACI(x) \ - (((x) >> S_FW_FILTER_WR_MACI) & M_FW_FILTER_WR_MACI) - -#define S_FW_FILTER_WR_MACIM 14 -#define M_FW_FILTER_WR_MACIM 0x1ff -#define V_FW_FILTER_WR_MACIM(x) ((x) << S_FW_FILTER_WR_MACIM) -#define G_FW_FILTER_WR_MACIM(x) \ - (((x) >> S_FW_FILTER_WR_MACIM) & M_FW_FILTER_WR_MACIM) - -#define S_FW_FILTER_WR_FCOE 13 -#define M_FW_FILTER_WR_FCOE 0x1 -#define V_FW_FILTER_WR_FCOE(x) ((x) << S_FW_FILTER_WR_FCOE) -#define G_FW_FILTER_WR_FCOE(x) \ - (((x) >> S_FW_FILTER_WR_FCOE) & M_FW_FILTER_WR_FCOE) -#define F_FW_FILTER_WR_FCOE V_FW_FILTER_WR_FCOE(1U) - -#define S_FW_FILTER_WR_FCOEM 12 -#define M_FW_FILTER_WR_FCOEM 0x1 -#define V_FW_FILTER_WR_FCOEM(x) ((x) << S_FW_FILTER_WR_FCOEM) -#define G_FW_FILTER_WR_FCOEM(x) \ - (((x) >> S_FW_FILTER_WR_FCOEM) & M_FW_FILTER_WR_FCOEM) -#define F_FW_FILTER_WR_FCOEM V_FW_FILTER_WR_FCOEM(1U) - -#define S_FW_FILTER_WR_PORT 9 -#define M_FW_FILTER_WR_PORT 0x7 -#define V_FW_FILTER_WR_PORT(x) ((x) << S_FW_FILTER_WR_PORT) -#define G_FW_FILTER_WR_PORT(x) \ - (((x) >> S_FW_FILTER_WR_PORT) & M_FW_FILTER_WR_PORT) - -#define S_FW_FILTER_WR_PORTM 6 -#define M_FW_FILTER_WR_PORTM 0x7 -#define V_FW_FILTER_WR_PORTM(x) ((x) << S_FW_FILTER_WR_PORTM) -#define G_FW_FILTER_WR_PORTM(x) \ - (((x) >> S_FW_FILTER_WR_PORTM) & M_FW_FILTER_WR_PORTM) - -#define S_FW_FILTER_WR_MATCHTYPE 3 -#define M_FW_FILTER_WR_MATCHTYPE 0x7 -#define V_FW_FILTER_WR_MATCHTYPE(x) ((x) << S_FW_FILTER_WR_MATCHTYPE) -#define G_FW_FILTER_WR_MATCHTYPE(x) \ - (((x) >> S_FW_FILTER_WR_MATCHTYPE) & M_FW_FILTER_WR_MATCHTYPE) - -#define S_FW_FILTER_WR_MATCHTYPEM 0 -#define M_FW_FILTER_WR_MATCHTYPEM 0x7 -#define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM) -#define G_FW_FILTER_WR_MATCHTYPEM(x) \ - (((x) >> S_FW_FILTER_WR_MATCHTYPEM) & M_FW_FILTER_WR_MATCHTYPEM) +#define FW_FILTER_WR_TID_S 12 +#define FW_FILTER_WR_TID_M 0xfffff +#define FW_FILTER_WR_TID_V(x) ((x) << FW_FILTER_WR_TID_S) +#define FW_FILTER_WR_TID_G(x) \ + (((x) >> FW_FILTER_WR_TID_S) & FW_FILTER_WR_TID_M) + +#define FW_FILTER_WR_RQTYPE_S 11 +#define FW_FILTER_WR_RQTYPE_M 0x1 +#define FW_FILTER_WR_RQTYPE_V(x) ((x) << FW_FILTER_WR_RQTYPE_S) +#define FW_FILTER_WR_RQTYPE_G(x) \ + (((x) >> FW_FILTER_WR_RQTYPE_S) & FW_FILTER_WR_RQTYPE_M) +#define FW_FILTER_WR_RQTYPE_F FW_FILTER_WR_RQTYPE_V(1U) + +#define FW_FILTER_WR_NOREPLY_S 10 +#define FW_FILTER_WR_NOREPLY_M 0x1 +#define FW_FILTER_WR_NOREPLY_V(x) ((x) << FW_FILTER_WR_NOREPLY_S) +#define FW_FILTER_WR_NOREPLY_G(x) \ + (((x) >> FW_FILTER_WR_NOREPLY_S) & FW_FILTER_WR_NOREPLY_M) +#define FW_FILTER_WR_NOREPLY_F FW_FILTER_WR_NOREPLY_V(1U) + +#define FW_FILTER_WR_IQ_S 0 +#define FW_FILTER_WR_IQ_M 0x3ff +#define FW_FILTER_WR_IQ_V(x) ((x) << FW_FILTER_WR_IQ_S) +#define FW_FILTER_WR_IQ_G(x) \ + (((x) >> FW_FILTER_WR_IQ_S) & FW_FILTER_WR_IQ_M) + +#define FW_FILTER_WR_DEL_FILTER_S 31 +#define FW_FILTER_WR_DEL_FILTER_M 0x1 +#define FW_FILTER_WR_DEL_FILTER_V(x) ((x) << FW_FILTER_WR_DEL_FILTER_S) +#define FW_FILTER_WR_DEL_FILTER_G(x) \ + (((x) >> FW_FILTER_WR_DEL_FILTER_S) & FW_FILTER_WR_DEL_FILTER_M) +#define FW_FILTER_WR_DEL_FILTER_F FW_FILTER_WR_DEL_FILTER_V(1U) + +#define FW_FILTER_WR_RPTTID_S 25 +#define FW_FILTER_WR_RPTTID_M 0x1 +#define FW_FILTER_WR_RPTTID_V(x) ((x) << FW_FILTER_WR_RPTTID_S) +#define FW_FILTER_WR_RPTTID_G(x) \ + (((x) >> FW_FILTER_WR_RPTTID_S) & FW_FILTER_WR_RPTTID_M) +#define FW_FILTER_WR_RPTTID_F FW_FILTER_WR_RPTTID_V(1U) + +#define FW_FILTER_WR_DROP_S 24 +#define FW_FILTER_WR_DROP_M 0x1 +#define FW_FILTER_WR_DROP_V(x) ((x) << FW_FILTER_WR_DROP_S) +#define FW_FILTER_WR_DROP_G(x) \ + (((x) >> FW_FILTER_WR_DROP_S) & FW_FILTER_WR_DROP_M) +#define FW_FILTER_WR_DROP_F FW_FILTER_WR_DROP_V(1U) + +#define FW_FILTER_WR_DIRSTEER_S 23 +#define FW_FILTER_WR_DIRSTEER_M 0x1 +#define FW_FILTER_WR_DIRSTEER_V(x) ((x) << FW_FILTER_WR_DIRSTEER_S) +#define FW_FILTER_WR_DIRSTEER_G(x) \ + (((x) >> FW_FILTER_WR_DIRSTEER_S) & FW_FILTER_WR_DIRSTEER_M) +#define FW_FILTER_WR_DIRSTEER_F FW_FILTER_WR_DIRSTEER_V(1U) + +#define FW_FILTER_WR_MASKHASH_S 22 +#define FW_FILTER_WR_MASKHASH_M 0x1 +#define FW_FILTER_WR_MASKHASH_V(x) ((x) << FW_FILTER_WR_MASKHASH_S) +#define FW_FILTER_WR_MASKHASH_G(x) \ + (((x) >> FW_FILTER_WR_MASKHASH_S) & FW_FILTER_WR_MASKHASH_M) +#define FW_FILTER_WR_MASKHASH_F FW_FILTER_WR_MASKHASH_V(1U) + +#define FW_FILTER_WR_DIRSTEERHASH_S 21 +#define FW_FILTER_WR_DIRSTEERHASH_M 0x1 +#define FW_FILTER_WR_DIRSTEERHASH_V(x) ((x) << FW_FILTER_WR_DIRSTEERHASH_S) +#define FW_FILTER_WR_DIRSTEERHASH_G(x) \ + (((x) >> FW_FILTER_WR_DIRSTEERHASH_S) & FW_FILTER_WR_DIRSTEERHASH_M) +#define FW_FILTER_WR_DIRSTEERHASH_F FW_FILTER_WR_DIRSTEERHASH_V(1U) + +#define FW_FILTER_WR_LPBK_S 20 +#define FW_FILTER_WR_LPBK_M 0x1 +#define FW_FILTER_WR_LPBK_V(x) ((x) << FW_FILTER_WR_LPBK_S) +#define FW_FILTER_WR_LPBK_G(x) \ + (((x) >> FW_FILTER_WR_LPBK_S) & FW_FILTER_WR_LPBK_M) +#define FW_FILTER_WR_LPBK_F FW_FILTER_WR_LPBK_V(1U) + +#define FW_FILTER_WR_DMAC_S 19 +#define FW_FILTER_WR_DMAC_M 0x1 +#define FW_FILTER_WR_DMAC_V(x) ((x) << FW_FILTER_WR_DMAC_S) +#define FW_FILTER_WR_DMAC_G(x) \ + (((x) >> FW_FILTER_WR_DMAC_S) & FW_FILTER_WR_DMAC_M) +#define FW_FILTER_WR_DMAC_F FW_FILTER_WR_DMAC_V(1U) + +#define FW_FILTER_WR_SMAC_S 18 +#define FW_FILTER_WR_SMAC_M 0x1 +#define FW_FILTER_WR_SMAC_V(x) ((x) << FW_FILTER_WR_SMAC_S) +#define FW_FILTER_WR_SMAC_G(x) \ + (((x) >> FW_FILTER_WR_SMAC_S) & FW_FILTER_WR_SMAC_M) +#define FW_FILTER_WR_SMAC_F FW_FILTER_WR_SMAC_V(1U) + +#define FW_FILTER_WR_INSVLAN_S 17 +#define FW_FILTER_WR_INSVLAN_M 0x1 +#define FW_FILTER_WR_INSVLAN_V(x) ((x) << FW_FILTER_WR_INSVLAN_S) +#define FW_FILTER_WR_INSVLAN_G(x) \ + (((x) >> FW_FILTER_WR_INSVLAN_S) & FW_FILTER_WR_INSVLAN_M) +#define FW_FILTER_WR_INSVLAN_F FW_FILTER_WR_INSVLAN_V(1U) + +#define FW_FILTER_WR_RMVLAN_S 16 +#define FW_FILTER_WR_RMVLAN_M 0x1 +#define FW_FILTER_WR_RMVLAN_V(x) ((x) << FW_FILTER_WR_RMVLAN_S) +#define FW_FILTER_WR_RMVLAN_G(x) \ + (((x) >> FW_FILTER_WR_RMVLAN_S) & FW_FILTER_WR_RMVLAN_M) +#define FW_FILTER_WR_RMVLAN_F FW_FILTER_WR_RMVLAN_V(1U) + +#define FW_FILTER_WR_HITCNTS_S 15 +#define FW_FILTER_WR_HITCNTS_M 0x1 +#define FW_FILTER_WR_HITCNTS_V(x) ((x) << FW_FILTER_WR_HITCNTS_S) +#define FW_FILTER_WR_HITCNTS_G(x) \ + (((x) >> FW_FILTER_WR_HITCNTS_S) & FW_FILTER_WR_HITCNTS_M) +#define FW_FILTER_WR_HITCNTS_F FW_FILTER_WR_HITCNTS_V(1U) + +#define FW_FILTER_WR_TXCHAN_S 13 +#define FW_FILTER_WR_TXCHAN_M 0x3 +#define FW_FILTER_WR_TXCHAN_V(x) ((x) << FW_FILTER_WR_TXCHAN_S) +#define FW_FILTER_WR_TXCHAN_G(x) \ + (((x) >> FW_FILTER_WR_TXCHAN_S) & FW_FILTER_WR_TXCHAN_M) + +#define FW_FILTER_WR_PRIO_S 12 +#define FW_FILTER_WR_PRIO_M 0x1 +#define FW_FILTER_WR_PRIO_V(x) ((x) << FW_FILTER_WR_PRIO_S) +#define FW_FILTER_WR_PRIO_G(x) \ + (((x) >> FW_FILTER_WR_PRIO_S) & FW_FILTER_WR_PRIO_M) +#define FW_FILTER_WR_PRIO_F FW_FILTER_WR_PRIO_V(1U) + +#define FW_FILTER_WR_L2TIX_S 0 +#define FW_FILTER_WR_L2TIX_M 0xfff +#define FW_FILTER_WR_L2TIX_V(x) ((x) << FW_FILTER_WR_L2TIX_S) +#define FW_FILTER_WR_L2TIX_G(x) \ + (((x) >> FW_FILTER_WR_L2TIX_S) & FW_FILTER_WR_L2TIX_M) + +#define FW_FILTER_WR_FRAG_S 7 +#define FW_FILTER_WR_FRAG_M 0x1 +#define FW_FILTER_WR_FRAG_V(x) ((x) << FW_FILTER_WR_FRAG_S) +#define FW_FILTER_WR_FRAG_G(x) \ + (((x) >> FW_FILTER_WR_FRAG_S) & FW_FILTER_WR_FRAG_M) +#define FW_FILTER_WR_FRAG_F FW_FILTER_WR_FRAG_V(1U) + +#define FW_FILTER_WR_FRAGM_S 6 +#define FW_FILTER_WR_FRAGM_M 0x1 +#define FW_FILTER_WR_FRAGM_V(x) ((x) << FW_FILTER_WR_FRAGM_S) +#define FW_FILTER_WR_FRAGM_G(x) \ + (((x) >> FW_FILTER_WR_FRAGM_S) & FW_FILTER_WR_FRAGM_M) +#define FW_FILTER_WR_FRAGM_F FW_FILTER_WR_FRAGM_V(1U) + +#define FW_FILTER_WR_IVLAN_VLD_S 5 +#define FW_FILTER_WR_IVLAN_VLD_M 0x1 +#define FW_FILTER_WR_IVLAN_VLD_V(x) ((x) << FW_FILTER_WR_IVLAN_VLD_S) +#define FW_FILTER_WR_IVLAN_VLD_G(x) \ + (((x) >> FW_FILTER_WR_IVLAN_VLD_S) & FW_FILTER_WR_IVLAN_VLD_M) +#define FW_FILTER_WR_IVLAN_VLD_F FW_FILTER_WR_IVLAN_VLD_V(1U) + +#define FW_FILTER_WR_OVLAN_VLD_S 4 +#define FW_FILTER_WR_OVLAN_VLD_M 0x1 +#define FW_FILTER_WR_OVLAN_VLD_V(x) ((x) << FW_FILTER_WR_OVLAN_VLD_S) +#define FW_FILTER_WR_OVLAN_VLD_G(x) \ + (((x) >> FW_FILTER_WR_OVLAN_VLD_S) & FW_FILTER_WR_OVLAN_VLD_M) +#define FW_FILTER_WR_OVLAN_VLD_F FW_FILTER_WR_OVLAN_VLD_V(1U) + +#define FW_FILTER_WR_IVLAN_VLDM_S 3 +#define FW_FILTER_WR_IVLAN_VLDM_M 0x1 +#define FW_FILTER_WR_IVLAN_VLDM_V(x) ((x) << FW_FILTER_WR_IVLAN_VLDM_S) +#define FW_FILTER_WR_IVLAN_VLDM_G(x) \ + (((x) >> FW_FILTER_WR_IVLAN_VLDM_S) & FW_FILTER_WR_IVLAN_VLDM_M) +#define FW_FILTER_WR_IVLAN_VLDM_F FW_FILTER_WR_IVLAN_VLDM_V(1U) + +#define FW_FILTER_WR_OVLAN_VLDM_S 2 +#define FW_FILTER_WR_OVLAN_VLDM_M 0x1 +#define FW_FILTER_WR_OVLAN_VLDM_V(x) ((x) << FW_FILTER_WR_OVLAN_VLDM_S) +#define FW_FILTER_WR_OVLAN_VLDM_G(x) \ + (((x) >> FW_FILTER_WR_OVLAN_VLDM_S) & FW_FILTER_WR_OVLAN_VLDM_M) +#define FW_FILTER_WR_OVLAN_VLDM_F FW_FILTER_WR_OVLAN_VLDM_V(1U) + +#define FW_FILTER_WR_RX_CHAN_S 15 +#define FW_FILTER_WR_RX_CHAN_M 0x1 +#define FW_FILTER_WR_RX_CHAN_V(x) ((x) << FW_FILTER_WR_RX_CHAN_S) +#define FW_FILTER_WR_RX_CHAN_G(x) \ + (((x) >> FW_FILTER_WR_RX_CHAN_S) & FW_FILTER_WR_RX_CHAN_M) +#define FW_FILTER_WR_RX_CHAN_F FW_FILTER_WR_RX_CHAN_V(1U) + +#define FW_FILTER_WR_RX_RPL_IQ_S 0 +#define FW_FILTER_WR_RX_RPL_IQ_M 0x3ff +#define FW_FILTER_WR_RX_RPL_IQ_V(x) ((x) << FW_FILTER_WR_RX_RPL_IQ_S) +#define FW_FILTER_WR_RX_RPL_IQ_G(x) \ + (((x) >> FW_FILTER_WR_RX_RPL_IQ_S) & FW_FILTER_WR_RX_RPL_IQ_M) + +#define FW_FILTER_WR_MACI_S 23 +#define FW_FILTER_WR_MACI_M 0x1ff +#define FW_FILTER_WR_MACI_V(x) ((x) << FW_FILTER_WR_MACI_S) +#define FW_FILTER_WR_MACI_G(x) \ + (((x) >> FW_FILTER_WR_MACI_S) & FW_FILTER_WR_MACI_M) + +#define FW_FILTER_WR_MACIM_S 14 +#define FW_FILTER_WR_MACIM_M 0x1ff +#define FW_FILTER_WR_MACIM_V(x) ((x) << FW_FILTER_WR_MACIM_S) +#define FW_FILTER_WR_MACIM_G(x) \ + (((x) >> FW_FILTER_WR_MACIM_S) & FW_FILTER_WR_MACIM_M) + +#define FW_FILTER_WR_FCOE_S 13 +#define FW_FILTER_WR_FCOE_M 0x1 +#define FW_FILTER_WR_FCOE_V(x) ((x) << FW_FILTER_WR_FCOE_S) +#define FW_FILTER_WR_FCOE_G(x) \ + (((x) >> FW_FILTER_WR_FCOE_S) & FW_FILTER_WR_FCOE_M) +#define FW_FILTER_WR_FCOE_F FW_FILTER_WR_FCOE_V(1U) + +#define FW_FILTER_WR_FCOEM_S 12 +#define FW_FILTER_WR_FCOEM_M 0x1 +#define FW_FILTER_WR_FCOEM_V(x) ((x) << FW_FILTER_WR_FCOEM_S) +#define FW_FILTER_WR_FCOEM_G(x) \ + (((x) >> FW_FILTER_WR_FCOEM_S) & FW_FILTER_WR_FCOEM_M) +#define FW_FILTER_WR_FCOEM_F FW_FILTER_WR_FCOEM_V(1U) + +#define FW_FILTER_WR_PORT_S 9 +#define FW_FILTER_WR_PORT_M 0x7 +#define FW_FILTER_WR_PORT_V(x) ((x) << FW_FILTER_WR_PORT_S) +#define FW_FILTER_WR_PORT_G(x) \ + (((x) >> FW_FILTER_WR_PORT_S) & FW_FILTER_WR_PORT_M) + +#define FW_FILTER_WR_PORTM_S 6 +#define FW_FILTER_WR_PORTM_M 0x7 +#define FW_FILTER_WR_PORTM_V(x) ((x) << FW_FILTER_WR_PORTM_S) +#define FW_FILTER_WR_PORTM_G(x) \ + (((x) >> FW_FILTER_WR_PORTM_S) & FW_FILTER_WR_PORTM_M) + +#define FW_FILTER_WR_MATCHTYPE_S 3 +#define FW_FILTER_WR_MATCHTYPE_M 0x7 +#define FW_FILTER_WR_MATCHTYPE_V(x) ((x) << FW_FILTER_WR_MATCHTYPE_S) +#define FW_FILTER_WR_MATCHTYPE_G(x) \ + (((x) >> FW_FILTER_WR_MATCHTYPE_S) & FW_FILTER_WR_MATCHTYPE_M) + +#define FW_FILTER_WR_MATCHTYPEM_S 0 +#define FW_FILTER_WR_MATCHTYPEM_M 0x7 +#define FW_FILTER_WR_MATCHTYPEM_V(x) ((x) << FW_FILTER_WR_MATCHTYPEM_S) +#define FW_FILTER_WR_MATCHTYPEM_G(x) \ + (((x) >> FW_FILTER_WR_MATCHTYPEM_S) & FW_FILTER_WR_MATCHTYPEM_M) struct fw_ulptx_wr { __be32 op_to_compl; @@ -491,65 +491,65 @@ struct fw_ofld_connection_wr { } tcb; }; -#define S_FW_OFLD_CONNECTION_WR_VERSION 31 -#define M_FW_OFLD_CONNECTION_WR_VERSION 0x1 -#define V_FW_OFLD_CONNECTION_WR_VERSION(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_VERSION) -#define G_FW_OFLD_CONNECTION_WR_VERSION(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_VERSION) & \ - M_FW_OFLD_CONNECTION_WR_VERSION) -#define F_FW_OFLD_CONNECTION_WR_VERSION \ - V_FW_OFLD_CONNECTION_WR_VERSION(1U) - -#define S_FW_OFLD_CONNECTION_WR_CPL 30 -#define M_FW_OFLD_CONNECTION_WR_CPL 0x1 -#define V_FW_OFLD_CONNECTION_WR_CPL(x) ((x) << S_FW_OFLD_CONNECTION_WR_CPL) -#define G_FW_OFLD_CONNECTION_WR_CPL(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_CPL) & M_FW_OFLD_CONNECTION_WR_CPL) -#define F_FW_OFLD_CONNECTION_WR_CPL V_FW_OFLD_CONNECTION_WR_CPL(1U) - -#define S_FW_OFLD_CONNECTION_WR_T_STATE 28 -#define M_FW_OFLD_CONNECTION_WR_T_STATE 0xf -#define V_FW_OFLD_CONNECTION_WR_T_STATE(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_T_STATE) -#define G_FW_OFLD_CONNECTION_WR_T_STATE(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_T_STATE) & \ - M_FW_OFLD_CONNECTION_WR_T_STATE) - -#define S_FW_OFLD_CONNECTION_WR_RCV_SCALE 24 -#define M_FW_OFLD_CONNECTION_WR_RCV_SCALE 0xf -#define V_FW_OFLD_CONNECTION_WR_RCV_SCALE(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_RCV_SCALE) -#define G_FW_OFLD_CONNECTION_WR_RCV_SCALE(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_RCV_SCALE) & \ - M_FW_OFLD_CONNECTION_WR_RCV_SCALE) - -#define S_FW_OFLD_CONNECTION_WR_ASTID 0 -#define M_FW_OFLD_CONNECTION_WR_ASTID 0xffffff -#define V_FW_OFLD_CONNECTION_WR_ASTID(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_ASTID) -#define G_FW_OFLD_CONNECTION_WR_ASTID(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_ASTID) & M_FW_OFLD_CONNECTION_WR_ASTID) - -#define S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK 15 -#define M_FW_OFLD_CONNECTION_WR_CPLRXDATAACK 0x1 -#define V_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) -#define G_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) & \ - M_FW_OFLD_CONNECTION_WR_CPLRXDATAACK) -#define F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK \ - V_FW_OFLD_CONNECTION_WR_CPLRXDATAACK(1U) - -#define S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL 14 -#define M_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL 0x1 -#define V_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(x) \ - ((x) << S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) -#define G_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(x) \ - (((x) >> S_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) & \ - M_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL) -#define F_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL \ - V_FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL(1U) +#define FW_OFLD_CONNECTION_WR_VERSION_S 31 +#define FW_OFLD_CONNECTION_WR_VERSION_M 0x1 +#define FW_OFLD_CONNECTION_WR_VERSION_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_VERSION_S) +#define FW_OFLD_CONNECTION_WR_VERSION_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_VERSION_S) & \ + FW_OFLD_CONNECTION_WR_VERSION_M) +#define FW_OFLD_CONNECTION_WR_VERSION_F \ + FW_OFLD_CONNECTION_WR_VERSION_V(1U) + +#define FW_OFLD_CONNECTION_WR_CPL_S 30 +#define FW_OFLD_CONNECTION_WR_CPL_M 0x1 +#define FW_OFLD_CONNECTION_WR_CPL_V(x) ((x) << FW_OFLD_CONNECTION_WR_CPL_S) +#define FW_OFLD_CONNECTION_WR_CPL_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_CPL_S) & FW_OFLD_CONNECTION_WR_CPL_M) +#define FW_OFLD_CONNECTION_WR_CPL_F FW_OFLD_CONNECTION_WR_CPL_V(1U) + +#define FW_OFLD_CONNECTION_WR_T_STATE_S 28 +#define FW_OFLD_CONNECTION_WR_T_STATE_M 0xf +#define FW_OFLD_CONNECTION_WR_T_STATE_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_T_STATE_S) +#define FW_OFLD_CONNECTION_WR_T_STATE_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_T_STATE_S) & \ + FW_OFLD_CONNECTION_WR_T_STATE_M) + +#define FW_OFLD_CONNECTION_WR_RCV_SCALE_S 24 +#define FW_OFLD_CONNECTION_WR_RCV_SCALE_M 0xf +#define FW_OFLD_CONNECTION_WR_RCV_SCALE_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_RCV_SCALE_S) +#define FW_OFLD_CONNECTION_WR_RCV_SCALE_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_RCV_SCALE_S) & \ + FW_OFLD_CONNECTION_WR_RCV_SCALE_M) + +#define FW_OFLD_CONNECTION_WR_ASTID_S 0 +#define FW_OFLD_CONNECTION_WR_ASTID_M 0xffffff +#define FW_OFLD_CONNECTION_WR_ASTID_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_ASTID_S) +#define FW_OFLD_CONNECTION_WR_ASTID_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_ASTID_S) & FW_OFLD_CONNECTION_WR_ASTID_M) + +#define FW_OFLD_CONNECTION_WR_CPLRXDATAACK_S 15 +#define FW_OFLD_CONNECTION_WR_CPLRXDATAACK_M 0x1 +#define FW_OFLD_CONNECTION_WR_CPLRXDATAACK_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_CPLRXDATAACK_S) +#define FW_OFLD_CONNECTION_WR_CPLRXDATAACK_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_CPLRXDATAACK_S) & \ + FW_OFLD_CONNECTION_WR_CPLRXDATAACK_M) +#define FW_OFLD_CONNECTION_WR_CPLRXDATAACK_F \ + FW_OFLD_CONNECTION_WR_CPLRXDATAACK_V(1U) + +#define FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_S 14 +#define FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_M 0x1 +#define FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_V(x) \ + ((x) << FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_S) +#define FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_G(x) \ + (((x) >> FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_S) & \ + FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_M) +#define FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_F \ + FW_OFLD_CONNECTION_WR_CPLPASSACCEPTRPL_V(1U) enum fw_flowc_mnem { FW_FLOWC_MNEM_PFNVFN, /* PFN [15:8] VFN [7:0] */ -- GitLab From 5167865aaa70d605bb0771368878cbad0553d854 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 21 Nov 2014 12:52:02 +0530 Subject: [PATCH 5851/9457] RDMA/cxgb4/csiostor: Cleansup FW related macros/register defines for PF/VF and LDST This patch cleanups PF/VF and LDST related macros/register defines that are defined in t4fw_api.h and the affected files. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 2 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 61 ++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 78 ++--- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 270 ++++++++++++------ .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 10 +- .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 72 ++--- drivers/scsi/csiostor/csio_hw.c | 20 +- drivers/scsi/csiostor/csio_mb.c | 30 +- drivers/scsi/csiostor/csio_mb.h | 12 +- 9 files changed, 327 insertions(+), 228 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 0ad8e2acd895..4b8c6116c058 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -478,7 +478,7 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb) 16)) | FW_WR_FLOWID_V(ep->hwtid)); flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN; - flowc->mnemval[0].val = cpu_to_be32(FW_PFVF_CMD_PFN + flowc->mnemval[0].val = cpu_to_be32(FW_PFVF_CMD_PFN_V (ep->com.dev->rdev.lldi.pf)); flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH; flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6b6d7e16d4ed..4caec41f91e2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -141,7 +141,7 @@ static unsigned int pfvfres_pmask(struct adapter *adapter, * Give PF's access to all of the ports. */ if (vf == 0) - return FW_PFVF_CMD_PMASK_MASK; + return FW_PFVF_CMD_PMASK_M; /* * For VFs, we'll assign them access to the ports based purely on the @@ -512,9 +512,10 @@ static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable) u32 name, value; int err; - name = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH) | - FW_PARAMS_PARAM_YZ(txq->q.cntxt_id)); + name = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) | + FW_PARAMS_PARAM_X_V( + FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH) | + FW_PARAMS_PARAM_YZ_V(txq->q.cntxt_id)); value = enable ? i : 0xffffffff; /* Since we can be called while atomic (from "interrupt @@ -2717,9 +2718,10 @@ static int set_rspq_intr_params(struct sge_rspq *q, new_idx = closest_thres(&adap->sge, cnt); if (q->desc && q->pktcnt_idx != new_idx) { /* the queue has already been created, update it */ - v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | - FW_PARAMS_PARAM_YZ(q->cntxt_id); + v = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) | + FW_PARAMS_PARAM_X_V( + FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | + FW_PARAMS_PARAM_YZ_V(q->cntxt_id); err = t4_set_params(adap, adap->fn, adap->fn, 0, 1, &v, &new_idx); if (err) @@ -4870,11 +4872,11 @@ static u32 t4_read_pcie_cfg4(struct adapter *adap, int reg) htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | FW_CMD_READ_F | - FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE)); + FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FUNC_PCIE)); ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd)); - ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1); + ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS_V(1); ldst_cmd.u.pcie.ctrl_to_fn = - (FW_LDST_CMD_LC | FW_LDST_CMD_FN(adap->fn)); + (FW_LDST_CMD_LC_F | FW_LDST_CMD_FN_V(adap->fn)); ldst_cmd.u.pcie.r = reg; ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd), &ldst_cmd); @@ -5148,8 +5150,8 @@ static int adap_init0_config(struct adapter *adapter, int reset) if (cf->size >= FLASH_CFG_MAX_SIZE) ret = -ENOMEM; else { - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CF)); ret = t4_query_params(adapter, adapter->mbox, adapter->fn, 0, 1, params, val); if (ret == 0) { @@ -5167,8 +5169,8 @@ static int adap_init0_config(struct adapter *adapter, int reset) size_t size = cf->size & ~0x3; __be32 *data = (__be32 *)cf->data; - mtype = FW_PARAMS_PARAM_Y_GET(val[0]); - maddr = FW_PARAMS_PARAM_Z_GET(val[0]) << 16; + mtype = FW_PARAMS_PARAM_Y_G(val[0]); + maddr = FW_PARAMS_PARAM_Z_G(val[0]) << 16; spin_lock(&adapter->win0_lock); ret = t4_memory_rw(adapter, 0, mtype, maddr, @@ -5209,9 +5211,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) FW_CMD_REQUEST_F | FW_CMD_READ_F); caps_cmd.cfvalid_to_len16 = - htonl(FW_CAPS_CONFIG_CMD_CFVALID | - FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | - FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | + htonl(FW_CAPS_CONFIG_CMD_CFVALID_F | + FW_CAPS_CONFIG_CMD_MEMTYPE_CF_V(mtype) | + FW_CAPS_CONFIG_CMD_MEMADDR64K_CF_V(maddr >> 16) | FW_LEN16(caps_cmd)); ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), &caps_cmd); @@ -5377,7 +5379,7 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) PFRES_NEQ, PFRES_NETHCTRL, PFRES_NIQFLINT, PFRES_NIQ, PFRES_TC, PFRES_NVI, - FW_PFVF_CMD_CMASK_MASK, + FW_PFVF_CMD_CMASK_M, pfvfres_pmask(adapter, adapter->fn, 0), PFRES_NEXACTF, PFRES_R_CAPS, PFRES_WX_CAPS); @@ -5422,7 +5424,7 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) VFRES_NEQ, VFRES_NETHCTRL, VFRES_NIQFLINT, VFRES_NIQ, VFRES_TC, VFRES_NVI, - FW_PFVF_CMD_CMASK_MASK, + FW_PFVF_CMD_CMASK_M, pfvfres_pmask( adapter, pf, vf), VFRES_NEXACTF, @@ -5686,8 +5688,8 @@ static int adap_init0(struct adapter *adap) * and portvec ... */ v = - FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_PORTVEC); + FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PORTVEC); ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 1, &v, &port_vec); if (ret < 0) goto bye; @@ -5723,8 +5725,9 @@ static int adap_init0(struct adapter *adap) * Find out whether we're dealing with a version of * the firmware which has configuration file support. */ - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V( + FW_PARAMS_PARAM_DEV_CF)); ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 1, params, val); @@ -5784,14 +5787,14 @@ static int adap_init0(struct adapter *adap) * Grab some of our basic fundamental operating parameters. */ #define FW_PARAM_DEV(param) \ - (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) + (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | \ + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_##param)) #define FW_PARAM_PFVF(param) \ - FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)| \ - FW_PARAMS_PARAM_Y(0) | \ - FW_PARAMS_PARAM_Z(0) + FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \ + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param)| \ + FW_PARAMS_PARAM_Y_V(0) | \ + FW_PARAMS_PARAM_Z_V(0) params[0] = FW_PARAM_PFVF(EQ_START); params[1] = FW_PARAM_PFVF(L2T_START); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 0c78be36601e..9f1b3043d003 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -711,8 +711,8 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) * Ask firmware for the Core Clock since it knows how to translate the * Reference Clock ('V2') VPD field into a Core Clock value ... */ - cclk_param = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); + cclk_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK)); ret = t4_query_params(adapter, adapter->mbox, 0, 0, 1, &cclk_param, &cclk_val); @@ -2577,7 +2577,7 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, memset(&c, 0, sizeof(c)); c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE)); + FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FIRMWARE)); c.cycles_to_len16 = htonl(FW_LEN16(c)); c.u.addrval.addr = htonl(addr); c.u.addrval.val = htonl(val); @@ -2604,10 +2604,10 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, memset(&c, 0, sizeof(c)); c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | - FW_CMD_READ_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); + FW_CMD_READ_F | FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO)); c.cycles_to_len16 = htonl(FW_LEN16(c)); - c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | - FW_LDST_CMD_MMD(mmd)); + c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR_V(phy_addr) | + FW_LDST_CMD_MMD_V(mmd)); c.u.mdio.raddr = htons(reg); ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); @@ -2634,10 +2634,10 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, memset(&c, 0, sizeof(c)); c.op_to_addrspace = htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); + FW_CMD_WRITE_F | FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO)); c.cycles_to_len16 = htonl(FW_LEN16(c)); - c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | - FW_LDST_CMD_MMD(mmd)); + c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR_V(phy_addr) | + FW_LDST_CMD_MMD_V(mmd)); c.u.mdio.raddr = htons(reg); c.u.mdio.rval = htons(val); @@ -2774,13 +2774,13 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, memset(&c, 0, sizeof(c)); INIT_CMD(c, HELLO, WRITE); c.err_to_clearinit = htonl( - FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) | - FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) | - FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : - FW_HELLO_CMD_MBMASTER_MASK) | - FW_HELLO_CMD_MBASYNCNOT(evt_mbox) | - FW_HELLO_CMD_STAGE(fw_hello_cmd_stage_os) | - FW_HELLO_CMD_CLEARINIT); + FW_HELLO_CMD_MASTERDIS_V(master == MASTER_CANT) | + FW_HELLO_CMD_MASTERFORCE_V(master == MASTER_MUST) | + FW_HELLO_CMD_MBMASTER_V(master == MASTER_MUST ? mbox : + FW_HELLO_CMD_MBMASTER_M) | + FW_HELLO_CMD_MBASYNCNOT_V(evt_mbox) | + FW_HELLO_CMD_STAGE_V(fw_hello_cmd_stage_os) | + FW_HELLO_CMD_CLEARINIT_F); /* * Issue the HELLO command to the firmware. If it's not successful @@ -2799,11 +2799,11 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, } v = ntohl(c.err_to_clearinit); - master_mbox = FW_HELLO_CMD_MBMASTER_GET(v); + master_mbox = FW_HELLO_CMD_MBMASTER_G(v); if (state) { - if (v & FW_HELLO_CMD_ERR) + if (v & FW_HELLO_CMD_ERR_F) *state = DEV_STATE_ERR; - else if (v & FW_HELLO_CMD_INIT) + else if (v & FW_HELLO_CMD_INIT_F) *state = DEV_STATE_INIT; else *state = DEV_STATE_UNINIT; @@ -2820,7 +2820,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, * this case, the Master PF returned by the firmware will be * FW_PCIE_FW_MASTER_MASK so the test below will work ... */ - if ((v & (FW_HELLO_CMD_ERR|FW_HELLO_CMD_INIT)) == 0 && + if ((v & (FW_HELLO_CMD_ERR_F|FW_HELLO_CMD_INIT_F)) == 0 && master_mbox != mbox) { int waiting = FW_CMD_HELLO_TIMEOUT; @@ -2961,7 +2961,7 @@ static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) memset(&c, 0, sizeof(c)); INIT_CMD(c, RESET, WRITE); c.val = htonl(PIORST | PIORSTMODE); - c.halt_pkd = htonl(FW_RESET_CMD_HALT(1U)); + c.halt_pkd = htonl(FW_RESET_CMD_HALT_F); ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -3252,8 +3252,8 @@ int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | - FW_CMD_READ_F | FW_PARAMS_CMD_PFN(pf) | - FW_PARAMS_CMD_VFN(vf)); + FW_CMD_READ_F | FW_PARAMS_CMD_PFN_V(pf) | + FW_PARAMS_CMD_VFN_V(vf)); c.retval_len16 = htonl(FW_LEN16(c)); for (i = 0; i < nparams; i++, p += 2) *p = htonl(*params++); @@ -3293,8 +3293,8 @@ int t4_set_params_nosleep(struct adapter *adap, unsigned int mbox, memset(&c, 0, sizeof(c)); c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_PARAMS_CMD_PFN(pf) | - FW_PARAMS_CMD_VFN(vf)); + FW_PARAMS_CMD_PFN_V(pf) | + FW_PARAMS_CMD_VFN_V(vf)); c.retval_len16 = cpu_to_be32(FW_LEN16(c)); while (nparams--) { @@ -3330,8 +3330,8 @@ int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_PARAMS_CMD_PFN(pf) | - FW_PARAMS_CMD_VFN(vf)); + FW_CMD_WRITE_F | FW_PARAMS_CMD_PFN_V(pf) | + FW_PARAMS_CMD_VFN_V(vf)); c.retval_len16 = htonl(FW_LEN16(c)); while (nparams--) { *p++ = htonl(*params++); @@ -3372,19 +3372,19 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_PFVF_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_PFVF_CMD_PFN(pf) | - FW_PFVF_CMD_VFN(vf)); + FW_CMD_WRITE_F | FW_PFVF_CMD_PFN_V(pf) | + FW_PFVF_CMD_VFN_V(vf)); c.retval_len16 = htonl(FW_LEN16(c)); - c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) | - FW_PFVF_CMD_NIQ(rxq)); - c.type_to_neq = htonl(FW_PFVF_CMD_CMASK(cmask) | - FW_PFVF_CMD_PMASK(pmask) | - FW_PFVF_CMD_NEQ(txq)); - c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | FW_PFVF_CMD_NVI(vi) | - FW_PFVF_CMD_NEXACTF(nexact)); - c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) | - FW_PFVF_CMD_WX_CAPS(wxcaps) | - FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl)); + c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT_V(rxqi) | + FW_PFVF_CMD_NIQ_V(rxq)); + c.type_to_neq = htonl(FW_PFVF_CMD_CMASK_V(cmask) | + FW_PFVF_CMD_PMASK_V(pmask) | + FW_PFVF_CMD_NEQ_V(txq)); + c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC_V(tc) | FW_PFVF_CMD_NVI_V(vi) | + FW_PFVF_CMD_NEXACTF_V(nexact)); + c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS_V(rcaps) | + FW_PFVF_CMD_WX_CAPS_V(wxcaps) | + FW_PFVF_CMD_NETHCTRL_V(txq_eth_ctrl)); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 3bc5bdb4d334..5839b8077575 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -761,7 +761,8 @@ enum fw_ldst_func_mod_index { struct fw_ldst_cmd { __be32 op_to_addrspace; -#define FW_LDST_CMD_ADDRSPACE(x) ((x) << 0) +#define FW_LDST_CMD_ADDRSPACE_S 0 +#define FW_LDST_CMD_ADDRSPACE_V(x) ((x) << FW_LDST_CMD_ADDRSPACE_S) __be32 cycles_to_len16; union fw_ldst { struct fw_ldst_addrval { @@ -817,15 +818,33 @@ struct fw_ldst_cmd { } u; }; -#define FW_LDST_CMD_MSG(x) ((x) << 31) -#define FW_LDST_CMD_PADDR(x) ((x) << 8) -#define FW_LDST_CMD_MMD(x) ((x) << 0) -#define FW_LDST_CMD_FID(x) ((x) << 15) -#define FW_LDST_CMD_CTL(x) ((x) << 0) -#define FW_LDST_CMD_RPLCPF(x) ((x) << 0) -#define FW_LDST_CMD_LC (1U << 4) -#define FW_LDST_CMD_NACCESS(x) ((x) << 0) -#define FW_LDST_CMD_FN(x) ((x) << 0) +#define FW_LDST_CMD_MSG_S 31 +#define FW_LDST_CMD_MSG_V(x) ((x) << FW_LDST_CMD_MSG_S) + +#define FW_LDST_CMD_PADDR_S 8 +#define FW_LDST_CMD_PADDR_V(x) ((x) << FW_LDST_CMD_PADDR_S) + +#define FW_LDST_CMD_MMD_S 0 +#define FW_LDST_CMD_MMD_V(x) ((x) << FW_LDST_CMD_MMD_S) + +#define FW_LDST_CMD_FID_S 15 +#define FW_LDST_CMD_FID_V(x) ((x) << FW_LDST_CMD_FID_S) + +#define FW_LDST_CMD_CTL_S 0 +#define FW_LDST_CMD_CTL_V(x) ((x) << FW_LDST_CMD_CTL_S) + +#define FW_LDST_CMD_RPLCPF_S 0 +#define FW_LDST_CMD_RPLCPF_V(x) ((x) << FW_LDST_CMD_RPLCPF_S) + +#define FW_LDST_CMD_LC_S 4 +#define FW_LDST_CMD_LC_V(x) ((x) << FW_LDST_CMD_LC_S) +#define FW_LDST_CMD_LC_F FW_LDST_CMD_LC_V(1U) + +#define FW_LDST_CMD_FN_S 0 +#define FW_LDST_CMD_FN_V(x) ((x) << FW_LDST_CMD_FN_S) + +#define FW_LDST_CMD_NACCESS_S 0 +#define FW_LDST_CMD_NACCESS_V(x) ((x) << FW_LDST_CMD_NACCESS_S) struct fw_reset_cmd { __be32 op_to_write; @@ -834,11 +853,12 @@ struct fw_reset_cmd { __be32 halt_pkd; }; -#define FW_RESET_CMD_HALT_SHIFT 31 -#define FW_RESET_CMD_HALT_MASK 0x1 -#define FW_RESET_CMD_HALT(x) ((x) << FW_RESET_CMD_HALT_SHIFT) -#define FW_RESET_CMD_HALT_GET(x) \ - (((x) >> FW_RESET_CMD_HALT_SHIFT) & FW_RESET_CMD_HALT_MASK) +#define FW_RESET_CMD_HALT_S 31 +#define FW_RESET_CMD_HALT_M 0x1 +#define FW_RESET_CMD_HALT_V(x) ((x) << FW_RESET_CMD_HALT_S) +#define FW_RESET_CMD_HALT_G(x) \ + (((x) >> FW_RESET_CMD_HALT_S) & FW_RESET_CMD_HALT_M) +#define FW_RESET_CMD_HALT_F FW_RESET_CMD_HALT_V(1U) enum fw_hellow_cmd { fw_hello_cmd_stage_os = 0x0 @@ -848,22 +868,42 @@ struct fw_hello_cmd { __be32 op_to_write; __be32 retval_len16; __be32 err_to_clearinit; -#define FW_HELLO_CMD_ERR (1U << 31) -#define FW_HELLO_CMD_INIT (1U << 30) -#define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29) -#define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28) -#define FW_HELLO_CMD_MBMASTER_MASK 0xfU -#define FW_HELLO_CMD_MBMASTER_SHIFT 24 -#define FW_HELLO_CMD_MBMASTER(x) ((x) << FW_HELLO_CMD_MBMASTER_SHIFT) -#define FW_HELLO_CMD_MBMASTER_GET(x) \ - (((x) >> FW_HELLO_CMD_MBMASTER_SHIFT) & FW_HELLO_CMD_MBMASTER_MASK) -#define FW_HELLO_CMD_MBASYNCNOTINT(x) ((x) << 23) -#define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20) -#define FW_HELLO_CMD_STAGE(x) ((x) << 17) -#define FW_HELLO_CMD_CLEARINIT (1U << 16) __be32 fwrev; }; +#define FW_HELLO_CMD_ERR_S 31 +#define FW_HELLO_CMD_ERR_V(x) ((x) << FW_HELLO_CMD_ERR_S) +#define FW_HELLO_CMD_ERR_F FW_HELLO_CMD_ERR_V(1U) + +#define FW_HELLO_CMD_INIT_S 30 +#define FW_HELLO_CMD_INIT_V(x) ((x) << FW_HELLO_CMD_INIT_S) +#define FW_HELLO_CMD_INIT_F FW_HELLO_CMD_INIT_V(1U) + +#define FW_HELLO_CMD_MASTERDIS_S 29 +#define FW_HELLO_CMD_MASTERDIS_V(x) ((x) << FW_HELLO_CMD_MASTERDIS_S) + +#define FW_HELLO_CMD_MASTERFORCE_S 28 +#define FW_HELLO_CMD_MASTERFORCE_V(x) ((x) << FW_HELLO_CMD_MASTERFORCE_S) + +#define FW_HELLO_CMD_MBMASTER_S 24 +#define FW_HELLO_CMD_MBMASTER_M 0xfU +#define FW_HELLO_CMD_MBMASTER_V(x) ((x) << FW_HELLO_CMD_MBMASTER_S) +#define FW_HELLO_CMD_MBMASTER_G(x) \ + (((x) >> FW_HELLO_CMD_MBMASTER_S) & FW_HELLO_CMD_MBMASTER_M) + +#define FW_HELLO_CMD_MBASYNCNOTINT_S 23 +#define FW_HELLO_CMD_MBASYNCNOTINT_V(x) ((x) << FW_HELLO_CMD_MBASYNCNOTINT_S) + +#define FW_HELLO_CMD_MBASYNCNOT_S 20 +#define FW_HELLO_CMD_MBASYNCNOT_V(x) ((x) << FW_HELLO_CMD_MBASYNCNOT_S) + +#define FW_HELLO_CMD_STAGE_S 17 +#define FW_HELLO_CMD_STAGE_V(x) ((x) << FW_HELLO_CMD_STAGE_S) + +#define FW_HELLO_CMD_CLEARINIT_S 16 +#define FW_HELLO_CMD_CLEARINIT_V(x) ((x) << FW_HELLO_CMD_CLEARINIT_S) +#define FW_HELLO_CMD_CLEARINIT_F FW_HELLO_CMD_CLEARINIT_V(1U) + struct fw_bye_cmd { __be32 op_to_write; __be32 retval_len16; @@ -974,9 +1014,17 @@ struct fw_caps_config_cmd { __be32 finicsum; }; -#define FW_CAPS_CONFIG_CMD_CFVALID (1U << 27) -#define FW_CAPS_CONFIG_CMD_MEMTYPE_CF(x) ((x) << 24) -#define FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(x) ((x) << 16) +#define FW_CAPS_CONFIG_CMD_CFVALID_S 27 +#define FW_CAPS_CONFIG_CMD_CFVALID_V(x) ((x) << FW_CAPS_CONFIG_CMD_CFVALID_S) +#define FW_CAPS_CONFIG_CMD_CFVALID_F FW_CAPS_CONFIG_CMD_CFVALID_V(1U) + +#define FW_CAPS_CONFIG_CMD_MEMTYPE_CF_S 24 +#define FW_CAPS_CONFIG_CMD_MEMTYPE_CF_V(x) \ + ((x) << FW_CAPS_CONFIG_CMD_MEMTYPE_CF_S) + +#define FW_CAPS_CONFIG_CMD_MEMADDR64K_CF_S 16 +#define FW_CAPS_CONFIG_CMD_MEMADDR64K_CF_V(x) \ + ((x) << FW_CAPS_CONFIG_CMD_MEMADDR64K_CF_S) /* * params command mnemonics @@ -1072,20 +1120,29 @@ enum fw_params_param_dmaq { FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH = 0x13, }; -#define FW_PARAMS_MNEM(x) ((x) << 24) -#define FW_PARAMS_PARAM_X(x) ((x) << 16) -#define FW_PARAMS_PARAM_Y_SHIFT 8 -#define FW_PARAMS_PARAM_Y_MASK 0xffU -#define FW_PARAMS_PARAM_Y(x) ((x) << FW_PARAMS_PARAM_Y_SHIFT) -#define FW_PARAMS_PARAM_Y_GET(x) (((x) >> FW_PARAMS_PARAM_Y_SHIFT) &\ - FW_PARAMS_PARAM_Y_MASK) -#define FW_PARAMS_PARAM_Z_SHIFT 0 -#define FW_PARAMS_PARAM_Z_MASK 0xffu -#define FW_PARAMS_PARAM_Z(x) ((x) << FW_PARAMS_PARAM_Z_SHIFT) -#define FW_PARAMS_PARAM_Z_GET(x) (((x) >> FW_PARAMS_PARAM_Z_SHIFT) &\ - FW_PARAMS_PARAM_Z_MASK) -#define FW_PARAMS_PARAM_XYZ(x) ((x) << 0) -#define FW_PARAMS_PARAM_YZ(x) ((x) << 0) +#define FW_PARAMS_MNEM_S 24 +#define FW_PARAMS_MNEM_V(x) ((x) << FW_PARAMS_MNEM_S) + +#define FW_PARAMS_PARAM_X_S 16 +#define FW_PARAMS_PARAM_X_V(x) ((x) << FW_PARAMS_PARAM_X_S) + +#define FW_PARAMS_PARAM_Y_S 8 +#define FW_PARAMS_PARAM_Y_M 0xffU +#define FW_PARAMS_PARAM_Y_V(x) ((x) << FW_PARAMS_PARAM_Y_S) +#define FW_PARAMS_PARAM_Y_G(x) (((x) >> FW_PARAMS_PARAM_Y_S) &\ + FW_PARAMS_PARAM_Y_M) + +#define FW_PARAMS_PARAM_Z_S 0 +#define FW_PARAMS_PARAM_Z_M 0xffu +#define FW_PARAMS_PARAM_Z_V(x) ((x) << FW_PARAMS_PARAM_Z_S) +#define FW_PARAMS_PARAM_Z_G(x) (((x) >> FW_PARAMS_PARAM_Z_S) &\ + FW_PARAMS_PARAM_Z_M) + +#define FW_PARAMS_PARAM_XYZ_S 0 +#define FW_PARAMS_PARAM_XYZ_V(x) ((x) << FW_PARAMS_PARAM_XYZ_S) + +#define FW_PARAMS_PARAM_YZ_S 0 +#define FW_PARAMS_PARAM_YZ_V(x) ((x) << FW_PARAMS_PARAM_YZ_S) struct fw_params_cmd { __be32 op_to_vfn; @@ -1096,8 +1153,11 @@ struct fw_params_cmd { } param[7]; }; -#define FW_PARAMS_CMD_PFN(x) ((x) << 8) -#define FW_PARAMS_CMD_VFN(x) ((x) << 0) +#define FW_PARAMS_CMD_PFN_S 8 +#define FW_PARAMS_CMD_PFN_V(x) ((x) << FW_PARAMS_CMD_PFN_S) + +#define FW_PARAMS_CMD_VFN_S 0 +#define FW_PARAMS_CMD_VFN_V(x) ((x) << FW_PARAMS_CMD_VFN_S) struct fw_pfvf_cmd { __be32 op_to_vfn; @@ -1111,46 +1171,82 @@ struct fw_pfvf_cmd { __be32 r4; }; -#define FW_PFVF_CMD_PFN(x) ((x) << 8) -#define FW_PFVF_CMD_VFN(x) ((x) << 0) - -#define FW_PFVF_CMD_NIQFLINT(x) ((x) << 20) -#define FW_PFVF_CMD_NIQFLINT_GET(x) (((x) >> 20) & 0xfff) - -#define FW_PFVF_CMD_NIQ(x) ((x) << 0) -#define FW_PFVF_CMD_NIQ_GET(x) (((x) >> 0) & 0xfffff) - -#define FW_PFVF_CMD_TYPE (1 << 31) -#define FW_PFVF_CMD_TYPE_GET(x) (((x) >> 31) & 0x1) - -#define FW_PFVF_CMD_CMASK(x) ((x) << 24) -#define FW_PFVF_CMD_CMASK_MASK 0xf -#define FW_PFVF_CMD_CMASK_GET(x) (((x) >> 24) & FW_PFVF_CMD_CMASK_MASK) - -#define FW_PFVF_CMD_PMASK(x) ((x) << 20) -#define FW_PFVF_CMD_PMASK_MASK 0xf -#define FW_PFVF_CMD_PMASK_GET(x) (((x) >> 20) & FW_PFVF_CMD_PMASK_MASK) - -#define FW_PFVF_CMD_NEQ(x) ((x) << 0) -#define FW_PFVF_CMD_NEQ_GET(x) (((x) >> 0) & 0xfffff) - -#define FW_PFVF_CMD_TC(x) ((x) << 24) -#define FW_PFVF_CMD_TC_GET(x) (((x) >> 24) & 0xff) - -#define FW_PFVF_CMD_NVI(x) ((x) << 16) -#define FW_PFVF_CMD_NVI_GET(x) (((x) >> 16) & 0xff) - -#define FW_PFVF_CMD_NEXACTF(x) ((x) << 0) -#define FW_PFVF_CMD_NEXACTF_GET(x) (((x) >> 0) & 0xffff) - -#define FW_PFVF_CMD_R_CAPS(x) ((x) << 24) -#define FW_PFVF_CMD_R_CAPS_GET(x) (((x) >> 24) & 0xff) - -#define FW_PFVF_CMD_WX_CAPS(x) ((x) << 16) -#define FW_PFVF_CMD_WX_CAPS_GET(x) (((x) >> 16) & 0xff) - -#define FW_PFVF_CMD_NETHCTRL(x) ((x) << 0) -#define FW_PFVF_CMD_NETHCTRL_GET(x) (((x) >> 0) & 0xffff) +#define FW_PFVF_CMD_PFN_S 8 +#define FW_PFVF_CMD_PFN_V(x) ((x) << FW_PFVF_CMD_PFN_S) + +#define FW_PFVF_CMD_VFN_S 0 +#define FW_PFVF_CMD_VFN_V(x) ((x) << FW_PFVF_CMD_VFN_S) + +#define FW_PFVF_CMD_NIQFLINT_S 20 +#define FW_PFVF_CMD_NIQFLINT_M 0xfff +#define FW_PFVF_CMD_NIQFLINT_V(x) ((x) << FW_PFVF_CMD_NIQFLINT_S) +#define FW_PFVF_CMD_NIQFLINT_G(x) \ + (((x) >> FW_PFVF_CMD_NIQFLINT_S) & FW_PFVF_CMD_NIQFLINT_M) + +#define FW_PFVF_CMD_NIQ_S 0 +#define FW_PFVF_CMD_NIQ_M 0xfffff +#define FW_PFVF_CMD_NIQ_V(x) ((x) << FW_PFVF_CMD_NIQ_S) +#define FW_PFVF_CMD_NIQ_G(x) \ + (((x) >> FW_PFVF_CMD_NIQ_S) & FW_PFVF_CMD_NIQ_M) + +#define FW_PFVF_CMD_TYPE_S 31 +#define FW_PFVF_CMD_TYPE_M 0x1 +#define FW_PFVF_CMD_TYPE_V(x) ((x) << FW_PFVF_CMD_TYPE_S) +#define FW_PFVF_CMD_TYPE_G(x) \ + (((x) >> FW_PFVF_CMD_TYPE_S) & FW_PFVF_CMD_TYPE_M) +#define FW_PFVF_CMD_TYPE_F FW_PFVF_CMD_TYPE_V(1U) + +#define FW_PFVF_CMD_CMASK_S 24 +#define FW_PFVF_CMD_CMASK_M 0xf +#define FW_PFVF_CMD_CMASK_V(x) ((x) << FW_PFVF_CMD_CMASK_S) +#define FW_PFVF_CMD_CMASK_G(x) \ + (((x) >> FW_PFVF_CMD_CMASK_S) & FW_PFVF_CMD_CMASK_M) + +#define FW_PFVF_CMD_PMASK_S 20 +#define FW_PFVF_CMD_PMASK_M 0xf +#define FW_PFVF_CMD_PMASK_V(x) ((x) << FW_PFVF_CMD_PMASK_S) +#define FW_PFVF_CMD_PMASK_G(x) \ + (((x) >> FW_PFVF_CMD_PMASK_S) & FW_PFVF_CMD_PMASK_M) + +#define FW_PFVF_CMD_NEQ_S 0 +#define FW_PFVF_CMD_NEQ_M 0xfffff +#define FW_PFVF_CMD_NEQ_V(x) ((x) << FW_PFVF_CMD_NEQ_S) +#define FW_PFVF_CMD_NEQ_G(x) \ + (((x) >> FW_PFVF_CMD_NEQ_S) & FW_PFVF_CMD_NEQ_M) + +#define FW_PFVF_CMD_TC_S 24 +#define FW_PFVF_CMD_TC_M 0xff +#define FW_PFVF_CMD_TC_V(x) ((x) << FW_PFVF_CMD_TC_S) +#define FW_PFVF_CMD_TC_G(x) (((x) >> FW_PFVF_CMD_TC_S) & FW_PFVF_CMD_TC_M) + +#define FW_PFVF_CMD_NVI_S 16 +#define FW_PFVF_CMD_NVI_M 0xff +#define FW_PFVF_CMD_NVI_V(x) ((x) << FW_PFVF_CMD_NVI_S) +#define FW_PFVF_CMD_NVI_G(x) (((x) >> FW_PFVF_CMD_NVI_S) & FW_PFVF_CMD_NVI_M) + +#define FW_PFVF_CMD_NEXACTF_S 0 +#define FW_PFVF_CMD_NEXACTF_M 0xffff +#define FW_PFVF_CMD_NEXACTF_V(x) ((x) << FW_PFVF_CMD_NEXACTF_S) +#define FW_PFVF_CMD_NEXACTF_G(x) \ + (((x) >> FW_PFVF_CMD_NEXACTF_S) & FW_PFVF_CMD_NEXACTF_M) + +#define FW_PFVF_CMD_R_CAPS_S 24 +#define FW_PFVF_CMD_R_CAPS_M 0xff +#define FW_PFVF_CMD_R_CAPS_V(x) ((x) << FW_PFVF_CMD_R_CAPS_S) +#define FW_PFVF_CMD_R_CAPS_G(x) \ + (((x) >> FW_PFVF_CMD_R_CAPS_S) & FW_PFVF_CMD_R_CAPS_M) + +#define FW_PFVF_CMD_WX_CAPS_S 16 +#define FW_PFVF_CMD_WX_CAPS_M 0xff +#define FW_PFVF_CMD_WX_CAPS_V(x) ((x) << FW_PFVF_CMD_WX_CAPS_S) +#define FW_PFVF_CMD_WX_CAPS_G(x) \ + (((x) >> FW_PFVF_CMD_WX_CAPS_S) & FW_PFVF_CMD_WX_CAPS_M) + +#define FW_PFVF_CMD_NETHCTRL_S 0 +#define FW_PFVF_CMD_NETHCTRL_M 0xffff +#define FW_PFVF_CMD_NETHCTRL_V(x) ((x) << FW_PFVF_CMD_NETHCTRL_S) +#define FW_PFVF_CMD_NETHCTRL_G(x) \ + (((x) >> FW_PFVF_CMD_NETHCTRL_S) & FW_PFVF_CMD_NETHCTRL_M) enum fw_iq_type { FW_IQ_TYPE_FL_INT_CAP, diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 0b42bddaf284..7c24b50c7d0b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -1030,10 +1030,10 @@ static int set_rxq_intr_params(struct adapter *adapter, struct sge_rspq *rspq, pktcnt_idx = closest_thres(&adapter->sge, cnt); if (rspq->desc && rspq->pktcnt_idx != pktcnt_idx) { - v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | - FW_PARAMS_PARAM_X( + v = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) | + FW_PARAMS_PARAM_X_V( FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | - FW_PARAMS_PARAM_YZ(rspq->cntxt_id); + FW_PARAMS_PARAM_YZ_V(rspq->cntxt_id); err = t4vf_set_params(adapter, 1, &v, &pktcnt_idx); if (err) return err; @@ -2184,8 +2184,8 @@ static int adap_init0(struct adapter *adapter) * firmware won't understand this and we'll just get * unencapsulated messages ... */ - param = FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP); + param = FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP); val = 1; (void) t4vf_set_params(adapter, 1, ¶m, &val); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index fae0c95e1a6b..f2087eb013c3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -443,20 +443,20 @@ int t4vf_get_sge_params(struct adapter *adapter) u32 params[7], vals[7]; int v; - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_CONTROL)); - params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_HOST_PAGE_SIZE)); - params[2] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE0)); - params[3] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE1)); - params[4] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_0_AND_1)); - params[5] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_2_AND_3)); - params[6] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_4_AND_5)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_CONTROL)); + params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_HOST_PAGE_SIZE)); + params[2] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_FL_BUFFER_SIZE0)); + params[3] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_FL_BUFFER_SIZE1)); + params[4] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_0_AND_1)); + params[5] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_2_AND_3)); + params[6] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_TIMER_VALUE_4_AND_5)); v = t4vf_query_params(adapter, 7, params, vals); if (v) return v; @@ -479,8 +479,8 @@ int t4vf_get_sge_params(struct adapter *adapter) * right value. */ if (!is_t4(adapter->params.chip)) { - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_CONTROL2_A)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_CONTROL2_A)); v = t4vf_query_params(adapter, 1, params, vals); if (v != FW_SUCCESS) { dev_err(adapter->pdev_dev, @@ -491,10 +491,10 @@ int t4vf_get_sge_params(struct adapter *adapter) sge_params->sge_control2 = vals[0]; } - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_INGRESS_RX_THRESHOLD)); - params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | - FW_PARAMS_PARAM_XYZ(SGE_CONM_CTRL)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_INGRESS_RX_THRESHOLD)); + params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_REG) | + FW_PARAMS_PARAM_XYZ_V(SGE_CONM_CTRL)); v = t4vf_query_params(adapter, 2, params, vals); if (v) return v; @@ -517,8 +517,8 @@ int t4vf_get_vpd_params(struct adapter *adapter) u32 params[7], vals[7]; int v; - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK)); v = t4vf_query_params(adapter, 1, params, vals); if (v) return v; @@ -540,10 +540,10 @@ int t4vf_get_dev_params(struct adapter *adapter) u32 params[7], vals[7]; int v; - params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWREV)); - params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_TPREV)); + params[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FWREV)); + params[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_TPREV)); v = t4vf_query_params(adapter, 2, params, vals); if (v) return v; @@ -659,22 +659,22 @@ int t4vf_get_vfres(struct adapter *adapter) * Extract VF resource limits and return success. */ word = be32_to_cpu(rpl.niqflint_niq); - vfres->niqflint = FW_PFVF_CMD_NIQFLINT_GET(word); - vfres->niq = FW_PFVF_CMD_NIQ_GET(word); + vfres->niqflint = FW_PFVF_CMD_NIQFLINT_G(word); + vfres->niq = FW_PFVF_CMD_NIQ_G(word); word = be32_to_cpu(rpl.type_to_neq); - vfres->neq = FW_PFVF_CMD_NEQ_GET(word); - vfres->pmask = FW_PFVF_CMD_PMASK_GET(word); + vfres->neq = FW_PFVF_CMD_NEQ_G(word); + vfres->pmask = FW_PFVF_CMD_PMASK_G(word); word = be32_to_cpu(rpl.tc_to_nexactf); - vfres->tc = FW_PFVF_CMD_TC_GET(word); - vfres->nvi = FW_PFVF_CMD_NVI_GET(word); - vfres->nexactf = FW_PFVF_CMD_NEXACTF_GET(word); + vfres->tc = FW_PFVF_CMD_TC_G(word); + vfres->nvi = FW_PFVF_CMD_NVI_G(word); + vfres->nexactf = FW_PFVF_CMD_NEXACTF_G(word); word = be32_to_cpu(rpl.r_caps_to_nethctrl); - vfres->r_caps = FW_PFVF_CMD_R_CAPS_GET(word); - vfres->wx_caps = FW_PFVF_CMD_WX_CAPS_GET(word); - vfres->nethctrl = FW_PFVF_CMD_NETHCTRL_GET(word); + vfres->r_caps = FW_PFVF_CMD_R_CAPS_G(word); + vfres->wx_caps = FW_PFVF_CMD_WX_CAPS_G(word); + vfres->nethctrl = FW_PFVF_CMD_NETHCTRL_G(word); return 0; } diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 5f06877aa7c4..80ad9c52eebd 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -1170,7 +1170,7 @@ csio_hw_fw_halt(struct csio_hw *hw, uint32_t mbox, int32_t force) } csio_mb_reset(hw, mbp, CSIO_MB_DEFAULT_TMO, - PIORSTMODE | PIORST, FW_RESET_CMD_HALT(1), + PIORSTMODE | PIORST, FW_RESET_CMD_HALT_F, NULL); if (csio_mb_issue(hw, mbp)) { @@ -1374,9 +1374,9 @@ csio_hw_fw_config_file(struct csio_hw *hw, FW_CMD_REQUEST_F | FW_CMD_READ_F); caps_cmd->cfvalid_to_len16 = - htonl(FW_CAPS_CONFIG_CMD_CFVALID | - FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | - FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | + htonl(FW_CAPS_CONFIG_CMD_CFVALID_F | + FW_CAPS_CONFIG_CMD_MEMTYPE_CF_V(mtype) | + FW_CAPS_CONFIG_CMD_MEMADDR64K_CF_V(maddr >> 16) | FW_LEN16(*caps_cmd)); if (csio_mb_issue(hw, mbp)) { @@ -1723,8 +1723,8 @@ csio_hw_check_fwconfig(struct csio_hw *hw, u32 *param) * Find out whether we're dealing with a version of * the firmware which has configuration file support. */ - _param[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CF)); + _param[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CF)); csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO, hw->pfn, 0, ARRAY_SIZE(_param), _param, NULL, false, NULL); @@ -1781,8 +1781,8 @@ csio_hw_flash_config(struct csio_hw *hw, u32 *fw_cfg_param, char *path) goto leave; } - mtype = FW_PARAMS_PARAM_Y_GET(*fw_cfg_param); - maddr = FW_PARAMS_PARAM_Z_GET(*fw_cfg_param) << 16; + mtype = FW_PARAMS_PARAM_Y_G(*fw_cfg_param); + maddr = FW_PARAMS_PARAM_Z_G(*fw_cfg_param) << 16; ret = csio_memory_write(hw, mtype, maddr, cf->size + value_to_add, cfg_data); @@ -1871,8 +1871,8 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) goto bye; } } else { - mtype = FW_PARAMS_PARAM_Y_GET(*fw_cfg_param); - maddr = FW_PARAMS_PARAM_Z_GET(*fw_cfg_param) << 16; + mtype = FW_PARAMS_PARAM_Y_G(*fw_cfg_param); + maddr = FW_PARAMS_PARAM_Z_G(*fw_cfg_param) << 16; using_flash = 0; } diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index ffa848987608..a1e0568b657f 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -85,13 +85,13 @@ csio_mb_hello(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, FW_CMD_REQUEST_F | FW_CMD_WRITE_F); cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->err_to_clearinit = htonl( - FW_HELLO_CMD_MASTERDIS(master == CSIO_MASTER_CANT) | - FW_HELLO_CMD_MASTERFORCE(master == CSIO_MASTER_MUST) | - FW_HELLO_CMD_MBMASTER(master == CSIO_MASTER_MUST ? - m_mbox : FW_HELLO_CMD_MBMASTER_MASK) | - FW_HELLO_CMD_MBASYNCNOT(a_mbox) | - FW_HELLO_CMD_STAGE(fw_hello_cmd_stage_os) | - FW_HELLO_CMD_CLEARINIT); + FW_HELLO_CMD_MASTERDIS_V(master == CSIO_MASTER_CANT) | + FW_HELLO_CMD_MASTERFORCE_V(master == CSIO_MASTER_MUST) | + FW_HELLO_CMD_MBMASTER_V(master == CSIO_MASTER_MUST ? + m_mbox : FW_HELLO_CMD_MBMASTER_M) | + FW_HELLO_CMD_MBASYNCNOT_V(a_mbox) | + FW_HELLO_CMD_STAGE_V(fw_hello_cmd_stage_os) | + FW_HELLO_CMD_CLEARINIT_F); } @@ -118,11 +118,11 @@ csio_mb_process_hello_rsp(struct csio_hw *hw, struct csio_mb *mbp, hw->fwrev = ntohl(rsp->fwrev); value = ntohl(rsp->err_to_clearinit); - *mpfn = FW_HELLO_CMD_MBMASTER_GET(value); + *mpfn = FW_HELLO_CMD_MBMASTER_G(value); - if (value & FW_HELLO_CMD_INIT) + if (value & FW_HELLO_CMD_INIT_F) *state = CSIO_DEV_STATE_INIT; - else if (value & FW_HELLO_CMD_ERR) + else if (value & FW_HELLO_CMD_ERR_F) *state = CSIO_DEV_STATE_ERR; else *state = CSIO_DEV_STATE_UNINIT; @@ -205,8 +205,8 @@ csio_mb_params(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_PARAMS_CMD) | FW_CMD_REQUEST_F | (wr ? FW_CMD_WRITE_F : FW_CMD_READ_F) | - FW_PARAMS_CMD_PFN(pf) | - FW_PARAMS_CMD_VFN(vf)); + FW_PARAMS_CMD_PFN_V(pf) | + FW_PARAMS_CMD_VFN_V(vf)); cmdp->retval_len16 = htonl(FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); /* Write Params */ @@ -274,11 +274,11 @@ csio_mb_ldst(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, int reg) htonl(FW_CMD_OP_V(FW_LDST_CMD) | FW_CMD_REQUEST_F | FW_CMD_READ_F | - FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE)); + FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FUNC_PCIE)); ldst_cmd->cycles_to_len16 = htonl(FW_LEN16(struct fw_ldst_cmd)); - ldst_cmd->u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1); + ldst_cmd->u.pcie.select_naccess = FW_LDST_CMD_NACCESS_V(1); ldst_cmd->u.pcie.ctrl_to_fn = - (FW_LDST_CMD_LC | FW_LDST_CMD_FN(hw->pfn)); + (FW_LDST_CMD_LC_F | FW_LDST_CMD_FN_V(hw->pfn)); ldst_cmd->u.pcie.r = (uint8_t)reg; } diff --git a/drivers/scsi/csiostor/csio_mb.h b/drivers/scsi/csiostor/csio_mb.h index a84179e54ab9..1bc82d0bc260 100644 --- a/drivers/scsi/csiostor/csio_mb.h +++ b/drivers/scsi/csiostor/csio_mb.h @@ -79,14 +79,14 @@ enum csio_dev_state { }; #define FW_PARAM_DEV(param) \ - (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) + (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | \ + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_##param)) #define FW_PARAM_PFVF(param) \ - (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ - FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)| \ - FW_PARAMS_PARAM_Y(0) | \ - FW_PARAMS_PARAM_Z(0)) + (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \ + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param)| \ + FW_PARAMS_PARAM_Y_V(0) | \ + FW_PARAMS_PARAM_Z_V(0)) enum { PAUSE_RX = 1 << 0, -- GitLab From 6e4b51a604f9722f6cf99b7b3d7b79b7b4336ece Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 21 Nov 2014 12:52:03 +0530 Subject: [PATCH 5852/9457] cxgb4/cxgb4vf/csiostor: Cleanup macros/register defines related to queues This patch cleanups all queue related macros/register defines that are defined in t4fw_api.h and the affected files. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 115 +-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 32 +- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 690 +++++++++++++----- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 63 +- .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 8 +- drivers/scsi/csiostor/csio_mb.c | 119 +-- 6 files changed, 684 insertions(+), 343 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 5cc5e19286a1..433560b8cb1b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2299,18 +2299,18 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F | - FW_IQ_CMD_PFN(adap->fn) | FW_IQ_CMD_VFN(0)); - c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) | + FW_IQ_CMD_PFN_V(adap->fn) | FW_IQ_CMD_VFN_V(0)); + c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC_F | FW_IQ_CMD_IQSTART_F | FW_LEN16(c)); - c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) | - FW_IQ_CMD_IQASYNCH(fwevtq) | FW_IQ_CMD_VIID(pi->viid) | - FW_IQ_CMD_IQANDST(intr_idx < 0) | FW_IQ_CMD_IQANUD(1) | - FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx : + c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE_V(FW_IQ_TYPE_FL_INT_CAP) | + FW_IQ_CMD_IQASYNCH_V(fwevtq) | FW_IQ_CMD_VIID_V(pi->viid) | + FW_IQ_CMD_IQANDST_V(intr_idx < 0) | FW_IQ_CMD_IQANUD_V(1) | + FW_IQ_CMD_IQANDSTINDEX_V(intr_idx >= 0 ? intr_idx : -intr_idx - 1)); - c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH(pi->tx_chan) | - FW_IQ_CMD_IQGTSMODE | - FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) | - FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4)); + c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH_V(pi->tx_chan) | + FW_IQ_CMD_IQGTSMODE_F | + FW_IQ_CMD_IQINTCNTTHRESH_V(iq->pktcnt_idx) | + FW_IQ_CMD_IQESIZE_V(ilog2(iq->iqe_len) - 4)); c.iqsize = htons(iq->size); c.iqaddr = cpu_to_be64(iq->phys_addr); @@ -2323,12 +2323,12 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, goto fl_nomem; flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc); - c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN(1) | - FW_IQ_CMD_FL0FETCHRO(1) | - FW_IQ_CMD_FL0DATARO(1) | - FW_IQ_CMD_FL0PADEN(1)); - c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) | - FW_IQ_CMD_FL0FBMAX(3)); + c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN_F | + FW_IQ_CMD_FL0FETCHRO_F | + FW_IQ_CMD_FL0DATARO_F | + FW_IQ_CMD_FL0PADEN_F); + c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN_V(2) | + FW_IQ_CMD_FL0FBMAX_V(3)); c.fl0size = htons(flsz); c.fl0addr = cpu_to_be64(fl->addr); } @@ -2425,19 +2425,20 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_ETH_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F | - FW_EQ_ETH_CMD_PFN(adap->fn) | FW_EQ_ETH_CMD_VFN(0)); - c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | - FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); - c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE | - FW_EQ_ETH_CMD_VIID(pi->viid)); - c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | - FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | - FW_EQ_ETH_CMD_FETCHRO(1) | - FW_EQ_ETH_CMD_IQID(iqid)); - c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) | - FW_EQ_ETH_CMD_FBMAX(3) | - FW_EQ_ETH_CMD_CIDXFTHRESH(5) | - FW_EQ_ETH_CMD_EQSIZE(nentries)); + FW_EQ_ETH_CMD_PFN_V(adap->fn) | + FW_EQ_ETH_CMD_VFN_V(0)); + c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC_F | + FW_EQ_ETH_CMD_EQSTART_F | FW_LEN16(c)); + c.viid_pkd = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE_F | + FW_EQ_ETH_CMD_VIID_V(pi->viid)); + c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE_V(2) | + FW_EQ_ETH_CMD_PCIECHN_V(pi->tx_chan) | + FW_EQ_ETH_CMD_FETCHRO_V(1) | + FW_EQ_ETH_CMD_IQID_V(iqid)); + c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN_V(2) | + FW_EQ_ETH_CMD_FBMAX_V(3) | + FW_EQ_ETH_CMD_CIDXFTHRESH_V(5) | + FW_EQ_ETH_CMD_EQSIZE_V(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); @@ -2451,7 +2452,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, return ret; } - init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_GET(ntohl(c.eqid_pkd))); + init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_G(ntohl(c.eqid_pkd))); txq->txq = netdevq; txq->tso = txq->tx_cso = txq->vlan_ins = 0; txq->mapping_err = 0; @@ -2478,20 +2479,20 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F | - FW_EQ_CTRL_CMD_PFN(adap->fn) | - FW_EQ_CTRL_CMD_VFN(0)); - c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC | - FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c)); - c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid)); + FW_EQ_CTRL_CMD_PFN_V(adap->fn) | + FW_EQ_CTRL_CMD_VFN_V(0)); + c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC_F | + FW_EQ_CTRL_CMD_EQSTART_F | FW_LEN16(c)); + c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID_V(cmplqid)); c.physeqid_pkd = htonl(0); - c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) | - FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) | - FW_EQ_CTRL_CMD_FETCHRO | - FW_EQ_CTRL_CMD_IQID(iqid)); - c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) | - FW_EQ_CTRL_CMD_FBMAX(3) | - FW_EQ_CTRL_CMD_CIDXFTHRESH(5) | - FW_EQ_CTRL_CMD_EQSIZE(nentries)); + c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE_V(2) | + FW_EQ_CTRL_CMD_PCIECHN_V(pi->tx_chan) | + FW_EQ_CTRL_CMD_FETCHRO_F | + FW_EQ_CTRL_CMD_IQID_V(iqid)); + c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN_V(2) | + FW_EQ_CTRL_CMD_FBMAX_V(3) | + FW_EQ_CTRL_CMD_CIDXFTHRESH_V(5) | + FW_EQ_CTRL_CMD_EQSIZE_V(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); @@ -2503,7 +2504,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, return ret; } - init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_GET(ntohl(c.cmpliqid_eqid))); + init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_G(ntohl(c.cmpliqid_eqid))); txq->adap = adap; skb_queue_head_init(&txq->sendq); tasklet_init(&txq->qresume_tsk, restart_ctrlq, (unsigned long)txq); @@ -2532,18 +2533,18 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F | - FW_EQ_OFLD_CMD_PFN(adap->fn) | - FW_EQ_OFLD_CMD_VFN(0)); - c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | - FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); - c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | - FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) | - FW_EQ_OFLD_CMD_FETCHRO(1) | - FW_EQ_OFLD_CMD_IQID(iqid)); - c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) | - FW_EQ_OFLD_CMD_FBMAX(3) | - FW_EQ_OFLD_CMD_CIDXFTHRESH(5) | - FW_EQ_OFLD_CMD_EQSIZE(nentries)); + FW_EQ_OFLD_CMD_PFN_V(adap->fn) | + FW_EQ_OFLD_CMD_VFN_V(0)); + c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC_F | + FW_EQ_OFLD_CMD_EQSTART_F | FW_LEN16(c)); + c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE_V(2) | + FW_EQ_OFLD_CMD_PCIECHN_V(pi->tx_chan) | + FW_EQ_OFLD_CMD_FETCHRO_F | + FW_EQ_OFLD_CMD_IQID_V(iqid)); + c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN_V(2) | + FW_EQ_OFLD_CMD_FBMAX_V(3) | + FW_EQ_OFLD_CMD_CIDXFTHRESH_V(5) | + FW_EQ_OFLD_CMD_EQSIZE_V(nentries)); c.eqaddr = cpu_to_be64(txq->q.phys_addr); ret = t4_wr_mbox(adap, adap->fn, &c, sizeof(c), &c); @@ -2557,7 +2558,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, return ret; } - init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_GET(ntohl(c.eqid_pkd))); + init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_G(ntohl(c.eqid_pkd))); txq->adap = adap; skb_queue_head_init(&txq->sendq); tasklet_init(&txq->qresume_tsk, restart_ofldq, (unsigned long)txq); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 9f1b3043d003..da72814dff3d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3715,10 +3715,10 @@ int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_IQ_CMD_PFN(pf) | - FW_IQ_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c)); - c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype)); + FW_CMD_EXEC_F | FW_IQ_CMD_PFN_V(pf) | + FW_IQ_CMD_VFN_V(vf)); + c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE_F | FW_LEN16(c)); + c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE_V(iqtype)); c.iqid = htons(iqid); c.fl0id = htons(fl0id); c.fl1id = htons(fl1id); @@ -3742,10 +3742,10 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_ETH_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_EQ_ETH_CMD_PFN(pf) | - FW_EQ_ETH_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c)); - c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid)); + FW_CMD_EXEC_F | FW_EQ_ETH_CMD_PFN_V(pf) | + FW_EQ_ETH_CMD_VFN_V(vf)); + c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE_F | FW_LEN16(c)); + c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID_V(eqid)); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -3766,10 +3766,10 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_EQ_CTRL_CMD_PFN(pf) | - FW_EQ_CTRL_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c)); - c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid)); + FW_CMD_EXEC_F | FW_EQ_CTRL_CMD_PFN_V(pf) | + FW_EQ_CTRL_CMD_VFN_V(vf)); + c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE_F | FW_LEN16(c)); + c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID_V(eqid)); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -3790,10 +3790,10 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN(pf) | - FW_EQ_OFLD_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c)); - c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid)); + FW_CMD_EXEC_F | FW_EQ_OFLD_CMD_PFN_V(pf) | + FW_EQ_OFLD_CMD_VFN_V(vf)); + c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE_F | FW_LEN16(c)); + c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID_V(eqid)); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 5839b8077575..92a0df5be28f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -1274,85 +1274,239 @@ struct fw_iq_cmd { __be64 fl1addr; }; -#define FW_IQ_CMD_PFN(x) ((x) << 8) -#define FW_IQ_CMD_VFN(x) ((x) << 0) - -#define FW_IQ_CMD_ALLOC (1U << 31) -#define FW_IQ_CMD_FREE (1U << 30) -#define FW_IQ_CMD_MODIFY (1U << 29) -#define FW_IQ_CMD_IQSTART(x) ((x) << 28) -#define FW_IQ_CMD_IQSTOP(x) ((x) << 27) - -#define FW_IQ_CMD_TYPE(x) ((x) << 29) -#define FW_IQ_CMD_IQASYNCH(x) ((x) << 28) -#define FW_IQ_CMD_VIID(x) ((x) << 16) -#define FW_IQ_CMD_IQANDST(x) ((x) << 15) -#define FW_IQ_CMD_IQANUS(x) ((x) << 14) -#define FW_IQ_CMD_IQANUD(x) ((x) << 12) -#define FW_IQ_CMD_IQANDSTINDEX(x) ((x) << 0) - -#define FW_IQ_CMD_IQDROPRSS (1U << 15) -#define FW_IQ_CMD_IQGTSMODE (1U << 14) -#define FW_IQ_CMD_IQPCIECH(x) ((x) << 12) -#define FW_IQ_CMD_IQDCAEN(x) ((x) << 11) -#define FW_IQ_CMD_IQDCACPU(x) ((x) << 6) -#define FW_IQ_CMD_IQINTCNTTHRESH(x) ((x) << 4) -#define FW_IQ_CMD_IQO (1U << 3) -#define FW_IQ_CMD_IQCPRIO(x) ((x) << 2) -#define FW_IQ_CMD_IQESIZE(x) ((x) << 0) - -#define FW_IQ_CMD_IQNS(x) ((x) << 31) -#define FW_IQ_CMD_IQRO(x) ((x) << 30) -#define FW_IQ_CMD_IQFLINTIQHSEN(x) ((x) << 28) -#define FW_IQ_CMD_IQFLINTCONGEN(x) ((x) << 27) -#define FW_IQ_CMD_IQFLINTISCSIC(x) ((x) << 26) -#define FW_IQ_CMD_FL0CNGCHMAP(x) ((x) << 20) -#define FW_IQ_CMD_FL0CACHELOCK(x) ((x) << 15) -#define FW_IQ_CMD_FL0DBP(x) ((x) << 14) -#define FW_IQ_CMD_FL0DATANS(x) ((x) << 13) -#define FW_IQ_CMD_FL0DATARO(x) ((x) << 12) -#define FW_IQ_CMD_FL0CONGCIF(x) ((x) << 11) -#define FW_IQ_CMD_FL0ONCHIP(x) ((x) << 10) -#define FW_IQ_CMD_FL0STATUSPGNS(x) ((x) << 9) -#define FW_IQ_CMD_FL0STATUSPGRO(x) ((x) << 8) -#define FW_IQ_CMD_FL0FETCHNS(x) ((x) << 7) -#define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6) -#define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4) -#define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3) -#define FW_IQ_CMD_FL0PADEN(x) ((x) << 2) -#define FW_IQ_CMD_FL0PACKEN(x) ((x) << 1) -#define FW_IQ_CMD_FL0CONGEN (1U << 0) - -#define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15) -#define FW_IQ_CMD_FL0DCACPU(x) ((x) << 10) -#define FW_IQ_CMD_FL0FBMIN(x) ((x) << 7) -#define FW_IQ_CMD_FL0FBMAX(x) ((x) << 4) -#define FW_IQ_CMD_FL0CIDXFTHRESHO (1U << 3) -#define FW_IQ_CMD_FL0CIDXFTHRESH(x) ((x) << 0) - -#define FW_IQ_CMD_FL1CNGCHMAP(x) ((x) << 20) -#define FW_IQ_CMD_FL1CACHELOCK(x) ((x) << 15) -#define FW_IQ_CMD_FL1DBP(x) ((x) << 14) -#define FW_IQ_CMD_FL1DATANS(x) ((x) << 13) -#define FW_IQ_CMD_FL1DATARO(x) ((x) << 12) -#define FW_IQ_CMD_FL1CONGCIF(x) ((x) << 11) -#define FW_IQ_CMD_FL1ONCHIP(x) ((x) << 10) -#define FW_IQ_CMD_FL1STATUSPGNS(x) ((x) << 9) -#define FW_IQ_CMD_FL1STATUSPGRO(x) ((x) << 8) -#define FW_IQ_CMD_FL1FETCHNS(x) ((x) << 7) -#define FW_IQ_CMD_FL1FETCHRO(x) ((x) << 6) -#define FW_IQ_CMD_FL1HOSTFCMODE(x) ((x) << 4) -#define FW_IQ_CMD_FL1CPRIO(x) ((x) << 3) -#define FW_IQ_CMD_FL1PADEN (1U << 2) -#define FW_IQ_CMD_FL1PACKEN (1U << 1) -#define FW_IQ_CMD_FL1CONGEN (1U << 0) - -#define FW_IQ_CMD_FL1DCAEN(x) ((x) << 15) -#define FW_IQ_CMD_FL1DCACPU(x) ((x) << 10) -#define FW_IQ_CMD_FL1FBMIN(x) ((x) << 7) -#define FW_IQ_CMD_FL1FBMAX(x) ((x) << 4) -#define FW_IQ_CMD_FL1CIDXFTHRESHO (1U << 3) -#define FW_IQ_CMD_FL1CIDXFTHRESH(x) ((x) << 0) +#define FW_IQ_CMD_PFN_S 8 +#define FW_IQ_CMD_PFN_V(x) ((x) << FW_IQ_CMD_PFN_S) + +#define FW_IQ_CMD_VFN_S 0 +#define FW_IQ_CMD_VFN_V(x) ((x) << FW_IQ_CMD_VFN_S) + +#define FW_IQ_CMD_ALLOC_S 31 +#define FW_IQ_CMD_ALLOC_V(x) ((x) << FW_IQ_CMD_ALLOC_S) +#define FW_IQ_CMD_ALLOC_F FW_IQ_CMD_ALLOC_V(1U) + +#define FW_IQ_CMD_FREE_S 30 +#define FW_IQ_CMD_FREE_V(x) ((x) << FW_IQ_CMD_FREE_S) +#define FW_IQ_CMD_FREE_F FW_IQ_CMD_FREE_V(1U) + +#define FW_IQ_CMD_MODIFY_S 29 +#define FW_IQ_CMD_MODIFY_V(x) ((x) << FW_IQ_CMD_MODIFY_S) +#define FW_IQ_CMD_MODIFY_F FW_IQ_CMD_MODIFY_V(1U) + +#define FW_IQ_CMD_IQSTART_S 28 +#define FW_IQ_CMD_IQSTART_V(x) ((x) << FW_IQ_CMD_IQSTART_S) +#define FW_IQ_CMD_IQSTART_F FW_IQ_CMD_IQSTART_V(1U) + +#define FW_IQ_CMD_IQSTOP_S 27 +#define FW_IQ_CMD_IQSTOP_V(x) ((x) << FW_IQ_CMD_IQSTOP_S) +#define FW_IQ_CMD_IQSTOP_F FW_IQ_CMD_IQSTOP_V(1U) + +#define FW_IQ_CMD_TYPE_S 29 +#define FW_IQ_CMD_TYPE_V(x) ((x) << FW_IQ_CMD_TYPE_S) + +#define FW_IQ_CMD_IQASYNCH_S 28 +#define FW_IQ_CMD_IQASYNCH_V(x) ((x) << FW_IQ_CMD_IQASYNCH_S) + +#define FW_IQ_CMD_VIID_S 16 +#define FW_IQ_CMD_VIID_V(x) ((x) << FW_IQ_CMD_VIID_S) + +#define FW_IQ_CMD_IQANDST_S 15 +#define FW_IQ_CMD_IQANDST_V(x) ((x) << FW_IQ_CMD_IQANDST_S) + +#define FW_IQ_CMD_IQANUS_S 14 +#define FW_IQ_CMD_IQANUS_V(x) ((x) << FW_IQ_CMD_IQANUS_S) + +#define FW_IQ_CMD_IQANUD_S 12 +#define FW_IQ_CMD_IQANUD_V(x) ((x) << FW_IQ_CMD_IQANUD_S) + +#define FW_IQ_CMD_IQANDSTINDEX_S 0 +#define FW_IQ_CMD_IQANDSTINDEX_V(x) ((x) << FW_IQ_CMD_IQANDSTINDEX_S) + +#define FW_IQ_CMD_IQDROPRSS_S 15 +#define FW_IQ_CMD_IQDROPRSS_V(x) ((x) << FW_IQ_CMD_IQDROPRSS_S) +#define FW_IQ_CMD_IQDROPRSS_F FW_IQ_CMD_IQDROPRSS_V(1U) + +#define FW_IQ_CMD_IQGTSMODE_S 14 +#define FW_IQ_CMD_IQGTSMODE_V(x) ((x) << FW_IQ_CMD_IQGTSMODE_S) +#define FW_IQ_CMD_IQGTSMODE_F FW_IQ_CMD_IQGTSMODE_V(1U) + +#define FW_IQ_CMD_IQPCIECH_S 12 +#define FW_IQ_CMD_IQPCIECH_V(x) ((x) << FW_IQ_CMD_IQPCIECH_S) + +#define FW_IQ_CMD_IQDCAEN_S 11 +#define FW_IQ_CMD_IQDCAEN_V(x) ((x) << FW_IQ_CMD_IQDCAEN_S) + +#define FW_IQ_CMD_IQDCACPU_S 6 +#define FW_IQ_CMD_IQDCACPU_V(x) ((x) << FW_IQ_CMD_IQDCACPU_S) + +#define FW_IQ_CMD_IQINTCNTTHRESH_S 4 +#define FW_IQ_CMD_IQINTCNTTHRESH_V(x) ((x) << FW_IQ_CMD_IQINTCNTTHRESH_S) + +#define FW_IQ_CMD_IQO_S 3 +#define FW_IQ_CMD_IQO_V(x) ((x) << FW_IQ_CMD_IQO_S) +#define FW_IQ_CMD_IQO_F FW_IQ_CMD_IQO_V(1U) + +#define FW_IQ_CMD_IQCPRIO_S 2 +#define FW_IQ_CMD_IQCPRIO_V(x) ((x) << FW_IQ_CMD_IQCPRIO_S) + +#define FW_IQ_CMD_IQESIZE_S 0 +#define FW_IQ_CMD_IQESIZE_V(x) ((x) << FW_IQ_CMD_IQESIZE_S) + +#define FW_IQ_CMD_IQNS_S 31 +#define FW_IQ_CMD_IQNS_V(x) ((x) << FW_IQ_CMD_IQNS_S) + +#define FW_IQ_CMD_IQRO_S 30 +#define FW_IQ_CMD_IQRO_V(x) ((x) << FW_IQ_CMD_IQRO_S) + +#define FW_IQ_CMD_IQFLINTIQHSEN_S 28 +#define FW_IQ_CMD_IQFLINTIQHSEN_V(x) ((x) << FW_IQ_CMD_IQFLINTIQHSEN_S) + +#define FW_IQ_CMD_IQFLINTCONGEN_S 27 +#define FW_IQ_CMD_IQFLINTCONGEN_V(x) ((x) << FW_IQ_CMD_IQFLINTCONGEN_S) + +#define FW_IQ_CMD_IQFLINTISCSIC_S 26 +#define FW_IQ_CMD_IQFLINTISCSIC_V(x) ((x) << FW_IQ_CMD_IQFLINTISCSIC_S) + +#define FW_IQ_CMD_FL0CNGCHMAP_S 20 +#define FW_IQ_CMD_FL0CNGCHMAP_V(x) ((x) << FW_IQ_CMD_FL0CNGCHMAP_S) + +#define FW_IQ_CMD_FL0CACHELOCK_S 15 +#define FW_IQ_CMD_FL0CACHELOCK_V(x) ((x) << FW_IQ_CMD_FL0CACHELOCK_S) + +#define FW_IQ_CMD_FL0DBP_S 14 +#define FW_IQ_CMD_FL0DBP_V(x) ((x) << FW_IQ_CMD_FL0DBP_S) + +#define FW_IQ_CMD_FL0DATANS_S 13 +#define FW_IQ_CMD_FL0DATANS_V(x) ((x) << FW_IQ_CMD_FL0DATANS_S) + +#define FW_IQ_CMD_FL0DATARO_S 12 +#define FW_IQ_CMD_FL0DATARO_V(x) ((x) << FW_IQ_CMD_FL0DATARO_S) +#define FW_IQ_CMD_FL0DATARO_F FW_IQ_CMD_FL0DATARO_V(1U) + +#define FW_IQ_CMD_FL0CONGCIF_S 11 +#define FW_IQ_CMD_FL0CONGCIF_V(x) ((x) << FW_IQ_CMD_FL0CONGCIF_S) + +#define FW_IQ_CMD_FL0ONCHIP_S 10 +#define FW_IQ_CMD_FL0ONCHIP_V(x) ((x) << FW_IQ_CMD_FL0ONCHIP_S) + +#define FW_IQ_CMD_FL0STATUSPGNS_S 9 +#define FW_IQ_CMD_FL0STATUSPGNS_V(x) ((x) << FW_IQ_CMD_FL0STATUSPGNS_S) + +#define FW_IQ_CMD_FL0STATUSPGRO_S 8 +#define FW_IQ_CMD_FL0STATUSPGRO_V(x) ((x) << FW_IQ_CMD_FL0STATUSPGRO_S) + +#define FW_IQ_CMD_FL0FETCHNS_S 7 +#define FW_IQ_CMD_FL0FETCHNS_V(x) ((x) << FW_IQ_CMD_FL0FETCHNS_S) + +#define FW_IQ_CMD_FL0FETCHRO_S 6 +#define FW_IQ_CMD_FL0FETCHRO_V(x) ((x) << FW_IQ_CMD_FL0FETCHRO_S) +#define FW_IQ_CMD_FL0FETCHRO_F FW_IQ_CMD_FL0FETCHRO_V(1U) + +#define FW_IQ_CMD_FL0HOSTFCMODE_S 4 +#define FW_IQ_CMD_FL0HOSTFCMODE_V(x) ((x) << FW_IQ_CMD_FL0HOSTFCMODE_S) + +#define FW_IQ_CMD_FL0CPRIO_S 3 +#define FW_IQ_CMD_FL0CPRIO_V(x) ((x) << FW_IQ_CMD_FL0CPRIO_S) + +#define FW_IQ_CMD_FL0PADEN_S 2 +#define FW_IQ_CMD_FL0PADEN_V(x) ((x) << FW_IQ_CMD_FL0PADEN_S) +#define FW_IQ_CMD_FL0PADEN_F FW_IQ_CMD_FL0PADEN_V(1U) + +#define FW_IQ_CMD_FL0PACKEN_S 1 +#define FW_IQ_CMD_FL0PACKEN_V(x) ((x) << FW_IQ_CMD_FL0PACKEN_S) +#define FW_IQ_CMD_FL0PACKEN_F FW_IQ_CMD_FL0PACKEN_V(1U) + +#define FW_IQ_CMD_FL0CONGEN_S 0 +#define FW_IQ_CMD_FL0CONGEN_V(x) ((x) << FW_IQ_CMD_FL0CONGEN_S) +#define FW_IQ_CMD_FL0CONGEN_F FW_IQ_CMD_FL0CONGEN_V(1U) + +#define FW_IQ_CMD_FL0DCAEN_S 15 +#define FW_IQ_CMD_FL0DCAEN_V(x) ((x) << FW_IQ_CMD_FL0DCAEN_S) + +#define FW_IQ_CMD_FL0DCACPU_S 10 +#define FW_IQ_CMD_FL0DCACPU_V(x) ((x) << FW_IQ_CMD_FL0DCACPU_S) + +#define FW_IQ_CMD_FL0FBMIN_S 7 +#define FW_IQ_CMD_FL0FBMIN_V(x) ((x) << FW_IQ_CMD_FL0FBMIN_S) + +#define FW_IQ_CMD_FL0FBMAX_S 4 +#define FW_IQ_CMD_FL0FBMAX_V(x) ((x) << FW_IQ_CMD_FL0FBMAX_S) + +#define FW_IQ_CMD_FL0CIDXFTHRESHO_S 3 +#define FW_IQ_CMD_FL0CIDXFTHRESHO_V(x) ((x) << FW_IQ_CMD_FL0CIDXFTHRESHO_S) +#define FW_IQ_CMD_FL0CIDXFTHRESHO_F FW_IQ_CMD_FL0CIDXFTHRESHO_V(1U) + +#define FW_IQ_CMD_FL0CIDXFTHRESH_S 0 +#define FW_IQ_CMD_FL0CIDXFTHRESH_V(x) ((x) << FW_IQ_CMD_FL0CIDXFTHRESH_S) + +#define FW_IQ_CMD_FL1CNGCHMAP_S 20 +#define FW_IQ_CMD_FL1CNGCHMAP_V(x) ((x) << FW_IQ_CMD_FL1CNGCHMAP_S) + +#define FW_IQ_CMD_FL1CACHELOCK_S 15 +#define FW_IQ_CMD_FL1CACHELOCK_V(x) ((x) << FW_IQ_CMD_FL1CACHELOCK_S) + +#define FW_IQ_CMD_FL1DBP_S 14 +#define FW_IQ_CMD_FL1DBP_V(x) ((x) << FW_IQ_CMD_FL1DBP_S) + +#define FW_IQ_CMD_FL1DATANS_S 13 +#define FW_IQ_CMD_FL1DATANS_V(x) ((x) << FW_IQ_CMD_FL1DATANS_S) + +#define FW_IQ_CMD_FL1DATARO_S 12 +#define FW_IQ_CMD_FL1DATARO_V(x) ((x) << FW_IQ_CMD_FL1DATARO_S) + +#define FW_IQ_CMD_FL1CONGCIF_S 11 +#define FW_IQ_CMD_FL1CONGCIF_V(x) ((x) << FW_IQ_CMD_FL1CONGCIF_S) + +#define FW_IQ_CMD_FL1ONCHIP_S 10 +#define FW_IQ_CMD_FL1ONCHIP_V(x) ((x) << FW_IQ_CMD_FL1ONCHIP_S) + +#define FW_IQ_CMD_FL1STATUSPGNS_S 9 +#define FW_IQ_CMD_FL1STATUSPGNS_V(x) ((x) << FW_IQ_CMD_FL1STATUSPGNS_S) + +#define FW_IQ_CMD_FL1STATUSPGRO_S 8 +#define FW_IQ_CMD_FL1STATUSPGRO_V(x) ((x) << FW_IQ_CMD_FL1STATUSPGRO_S) + +#define FW_IQ_CMD_FL1FETCHNS_S 7 +#define FW_IQ_CMD_FL1FETCHNS_V(x) ((x) << FW_IQ_CMD_FL1FETCHNS_S) + +#define FW_IQ_CMD_FL1FETCHRO_S 6 +#define FW_IQ_CMD_FL1FETCHRO_V(x) ((x) << FW_IQ_CMD_FL1FETCHRO_S) + +#define FW_IQ_CMD_FL1HOSTFCMODE_S 4 +#define FW_IQ_CMD_FL1HOSTFCMODE_V(x) ((x) << FW_IQ_CMD_FL1HOSTFCMODE_S) + +#define FW_IQ_CMD_FL1CPRIO_S 3 +#define FW_IQ_CMD_FL1CPRIO_V(x) ((x) << FW_IQ_CMD_FL1CPRIO_S) + +#define FW_IQ_CMD_FL1PADEN_S 2 +#define FW_IQ_CMD_FL1PADEN_V(x) ((x) << FW_IQ_CMD_FL1PADEN_S) +#define FW_IQ_CMD_FL1PADEN_F FW_IQ_CMD_FL1PADEN_V(1U) + +#define FW_IQ_CMD_FL1PACKEN_S 1 +#define FW_IQ_CMD_FL1PACKEN_V(x) ((x) << FW_IQ_CMD_FL1PACKEN_S) +#define FW_IQ_CMD_FL1PACKEN_F FW_IQ_CMD_FL1PACKEN_V(1U) + +#define FW_IQ_CMD_FL1CONGEN_S 0 +#define FW_IQ_CMD_FL1CONGEN_V(x) ((x) << FW_IQ_CMD_FL1CONGEN_S) +#define FW_IQ_CMD_FL1CONGEN_F FW_IQ_CMD_FL1CONGEN_V(1U) + +#define FW_IQ_CMD_FL1DCAEN_S 15 +#define FW_IQ_CMD_FL1DCAEN_V(x) ((x) << FW_IQ_CMD_FL1DCAEN_S) + +#define FW_IQ_CMD_FL1DCACPU_S 10 +#define FW_IQ_CMD_FL1DCACPU_V(x) ((x) << FW_IQ_CMD_FL1DCACPU_S) + +#define FW_IQ_CMD_FL1FBMIN_S 7 +#define FW_IQ_CMD_FL1FBMIN_V(x) ((x) << FW_IQ_CMD_FL1FBMIN_S) + +#define FW_IQ_CMD_FL1FBMAX_S 4 +#define FW_IQ_CMD_FL1FBMAX_V(x) ((x) << FW_IQ_CMD_FL1FBMAX_S) + +#define FW_IQ_CMD_FL1CIDXFTHRESHO_S 3 +#define FW_IQ_CMD_FL1CIDXFTHRESHO_V(x) ((x) << FW_IQ_CMD_FL1CIDXFTHRESHO_S) +#define FW_IQ_CMD_FL1CIDXFTHRESHO_F FW_IQ_CMD_FL1CIDXFTHRESHO_V(1U) + +#define FW_IQ_CMD_FL1CIDXFTHRESH_S 0 +#define FW_IQ_CMD_FL1CIDXFTHRESH_V(x) ((x) << FW_IQ_CMD_FL1CIDXFTHRESH_S) struct fw_eq_eth_cmd { __be32 op_to_vfn; @@ -1367,40 +1521,102 @@ struct fw_eq_eth_cmd { __be64 r9; }; -#define FW_EQ_ETH_CMD_PFN(x) ((x) << 8) -#define FW_EQ_ETH_CMD_VFN(x) ((x) << 0) -#define FW_EQ_ETH_CMD_ALLOC (1U << 31) -#define FW_EQ_ETH_CMD_FREE (1U << 30) -#define FW_EQ_ETH_CMD_MODIFY (1U << 29) -#define FW_EQ_ETH_CMD_EQSTART (1U << 28) -#define FW_EQ_ETH_CMD_EQSTOP (1U << 27) - -#define FW_EQ_ETH_CMD_EQID(x) ((x) << 0) -#define FW_EQ_ETH_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) -#define FW_EQ_ETH_CMD_PHYSEQID(x) ((x) << 0) -#define FW_EQ_ETH_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff) - -#define FW_EQ_ETH_CMD_FETCHSZM(x) ((x) << 26) -#define FW_EQ_ETH_CMD_STATUSPGNS(x) ((x) << 25) -#define FW_EQ_ETH_CMD_STATUSPGRO(x) ((x) << 24) -#define FW_EQ_ETH_CMD_FETCHNS(x) ((x) << 23) -#define FW_EQ_ETH_CMD_FETCHRO(x) ((x) << 22) -#define FW_EQ_ETH_CMD_HOSTFCMODE(x) ((x) << 20) -#define FW_EQ_ETH_CMD_CPRIO(x) ((x) << 19) -#define FW_EQ_ETH_CMD_ONCHIP(x) ((x) << 18) -#define FW_EQ_ETH_CMD_PCIECHN(x) ((x) << 16) -#define FW_EQ_ETH_CMD_IQID(x) ((x) << 0) - -#define FW_EQ_ETH_CMD_DCAEN(x) ((x) << 31) -#define FW_EQ_ETH_CMD_DCACPU(x) ((x) << 26) -#define FW_EQ_ETH_CMD_FBMIN(x) ((x) << 23) -#define FW_EQ_ETH_CMD_FBMAX(x) ((x) << 20) -#define FW_EQ_ETH_CMD_CIDXFTHRESHO(x) ((x) << 19) -#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) -#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) - -#define FW_EQ_ETH_CMD_AUTOEQUEQE (1U << 30) -#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) +#define FW_EQ_ETH_CMD_PFN_S 8 +#define FW_EQ_ETH_CMD_PFN_V(x) ((x) << FW_EQ_ETH_CMD_PFN_S) + +#define FW_EQ_ETH_CMD_VFN_S 0 +#define FW_EQ_ETH_CMD_VFN_V(x) ((x) << FW_EQ_ETH_CMD_VFN_S) + +#define FW_EQ_ETH_CMD_ALLOC_S 31 +#define FW_EQ_ETH_CMD_ALLOC_V(x) ((x) << FW_EQ_ETH_CMD_ALLOC_S) +#define FW_EQ_ETH_CMD_ALLOC_F FW_EQ_ETH_CMD_ALLOC_V(1U) + +#define FW_EQ_ETH_CMD_FREE_S 30 +#define FW_EQ_ETH_CMD_FREE_V(x) ((x) << FW_EQ_ETH_CMD_FREE_S) +#define FW_EQ_ETH_CMD_FREE_F FW_EQ_ETH_CMD_FREE_V(1U) + +#define FW_EQ_ETH_CMD_MODIFY_S 29 +#define FW_EQ_ETH_CMD_MODIFY_V(x) ((x) << FW_EQ_ETH_CMD_MODIFY_S) +#define FW_EQ_ETH_CMD_MODIFY_F FW_EQ_ETH_CMD_MODIFY_V(1U) + +#define FW_EQ_ETH_CMD_EQSTART_S 28 +#define FW_EQ_ETH_CMD_EQSTART_V(x) ((x) << FW_EQ_ETH_CMD_EQSTART_S) +#define FW_EQ_ETH_CMD_EQSTART_F FW_EQ_ETH_CMD_EQSTART_V(1U) + +#define FW_EQ_ETH_CMD_EQSTOP_S 27 +#define FW_EQ_ETH_CMD_EQSTOP_V(x) ((x) << FW_EQ_ETH_CMD_EQSTOP_S) +#define FW_EQ_ETH_CMD_EQSTOP_F FW_EQ_ETH_CMD_EQSTOP_V(1U) + +#define FW_EQ_ETH_CMD_EQID_S 0 +#define FW_EQ_ETH_CMD_EQID_M 0xfffff +#define FW_EQ_ETH_CMD_EQID_V(x) ((x) << FW_EQ_ETH_CMD_EQID_S) +#define FW_EQ_ETH_CMD_EQID_G(x) \ + (((x) >> FW_EQ_ETH_CMD_EQID_S) & FW_EQ_ETH_CMD_EQID_M) + +#define FW_EQ_ETH_CMD_PHYSEQID_S 0 +#define FW_EQ_ETH_CMD_PHYSEQID_M 0xfffff +#define FW_EQ_ETH_CMD_PHYSEQID_V(x) ((x) << FW_EQ_ETH_CMD_PHYSEQID_S) +#define FW_EQ_ETH_CMD_PHYSEQID_G(x) \ + (((x) >> FW_EQ_ETH_CMD_PHYSEQID_S) & FW_EQ_ETH_CMD_PHYSEQID_M) + +#define FW_EQ_ETH_CMD_FETCHSZM_S 26 +#define FW_EQ_ETH_CMD_FETCHSZM_V(x) ((x) << FW_EQ_ETH_CMD_FETCHSZM_S) +#define FW_EQ_ETH_CMD_FETCHSZM_F FW_EQ_ETH_CMD_FETCHSZM_V(1U) + +#define FW_EQ_ETH_CMD_STATUSPGNS_S 25 +#define FW_EQ_ETH_CMD_STATUSPGNS_V(x) ((x) << FW_EQ_ETH_CMD_STATUSPGNS_S) + +#define FW_EQ_ETH_CMD_STATUSPGRO_S 24 +#define FW_EQ_ETH_CMD_STATUSPGRO_V(x) ((x) << FW_EQ_ETH_CMD_STATUSPGRO_S) + +#define FW_EQ_ETH_CMD_FETCHNS_S 23 +#define FW_EQ_ETH_CMD_FETCHNS_V(x) ((x) << FW_EQ_ETH_CMD_FETCHNS_S) + +#define FW_EQ_ETH_CMD_FETCHRO_S 22 +#define FW_EQ_ETH_CMD_FETCHRO_V(x) ((x) << FW_EQ_ETH_CMD_FETCHRO_S) + +#define FW_EQ_ETH_CMD_HOSTFCMODE_S 20 +#define FW_EQ_ETH_CMD_HOSTFCMODE_V(x) ((x) << FW_EQ_ETH_CMD_HOSTFCMODE_S) + +#define FW_EQ_ETH_CMD_CPRIO_S 19 +#define FW_EQ_ETH_CMD_CPRIO_V(x) ((x) << FW_EQ_ETH_CMD_CPRIO_S) + +#define FW_EQ_ETH_CMD_ONCHIP_S 18 +#define FW_EQ_ETH_CMD_ONCHIP_V(x) ((x) << FW_EQ_ETH_CMD_ONCHIP_S) + +#define FW_EQ_ETH_CMD_PCIECHN_S 16 +#define FW_EQ_ETH_CMD_PCIECHN_V(x) ((x) << FW_EQ_ETH_CMD_PCIECHN_S) + +#define FW_EQ_ETH_CMD_IQID_S 0 +#define FW_EQ_ETH_CMD_IQID_V(x) ((x) << FW_EQ_ETH_CMD_IQID_S) + +#define FW_EQ_ETH_CMD_DCAEN_S 31 +#define FW_EQ_ETH_CMD_DCAEN_V(x) ((x) << FW_EQ_ETH_CMD_DCAEN_S) + +#define FW_EQ_ETH_CMD_DCACPU_S 26 +#define FW_EQ_ETH_CMD_DCACPU_V(x) ((x) << FW_EQ_ETH_CMD_DCACPU_S) + +#define FW_EQ_ETH_CMD_FBMIN_S 23 +#define FW_EQ_ETH_CMD_FBMIN_V(x) ((x) << FW_EQ_ETH_CMD_FBMIN_S) + +#define FW_EQ_ETH_CMD_FBMAX_S 20 +#define FW_EQ_ETH_CMD_FBMAX_V(x) ((x) << FW_EQ_ETH_CMD_FBMAX_S) + +#define FW_EQ_ETH_CMD_CIDXFTHRESHO_S 19 +#define FW_EQ_ETH_CMD_CIDXFTHRESHO_V(x) ((x) << FW_EQ_ETH_CMD_CIDXFTHRESHO_S) + +#define FW_EQ_ETH_CMD_CIDXFTHRESH_S 16 +#define FW_EQ_ETH_CMD_CIDXFTHRESH_V(x) ((x) << FW_EQ_ETH_CMD_CIDXFTHRESH_S) + +#define FW_EQ_ETH_CMD_EQSIZE_S 0 +#define FW_EQ_ETH_CMD_EQSIZE_V(x) ((x) << FW_EQ_ETH_CMD_EQSIZE_S) + +#define FW_EQ_ETH_CMD_AUTOEQUEQE_S 30 +#define FW_EQ_ETH_CMD_AUTOEQUEQE_V(x) ((x) << FW_EQ_ETH_CMD_AUTOEQUEQE_S) +#define FW_EQ_ETH_CMD_AUTOEQUEQE_F FW_EQ_ETH_CMD_AUTOEQUEQE_V(1U) + +#define FW_EQ_ETH_CMD_VIID_S 16 +#define FW_EQ_ETH_CMD_VIID_V(x) ((x) << FW_EQ_ETH_CMD_VIID_S) struct fw_eq_ctrl_cmd { __be32 op_to_vfn; @@ -1412,38 +1628,102 @@ struct fw_eq_ctrl_cmd { __be64 eqaddr; }; -#define FW_EQ_CTRL_CMD_PFN(x) ((x) << 8) -#define FW_EQ_CTRL_CMD_VFN(x) ((x) << 0) - -#define FW_EQ_CTRL_CMD_ALLOC (1U << 31) -#define FW_EQ_CTRL_CMD_FREE (1U << 30) -#define FW_EQ_CTRL_CMD_MODIFY (1U << 29) -#define FW_EQ_CTRL_CMD_EQSTART (1U << 28) -#define FW_EQ_CTRL_CMD_EQSTOP (1U << 27) - -#define FW_EQ_CTRL_CMD_CMPLIQID(x) ((x) << 20) -#define FW_EQ_CTRL_CMD_EQID(x) ((x) << 0) -#define FW_EQ_CTRL_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) -#define FW_EQ_CTRL_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff) - -#define FW_EQ_CTRL_CMD_FETCHSZM (1U << 26) -#define FW_EQ_CTRL_CMD_STATUSPGNS (1U << 25) -#define FW_EQ_CTRL_CMD_STATUSPGRO (1U << 24) -#define FW_EQ_CTRL_CMD_FETCHNS (1U << 23) -#define FW_EQ_CTRL_CMD_FETCHRO (1U << 22) -#define FW_EQ_CTRL_CMD_HOSTFCMODE(x) ((x) << 20) -#define FW_EQ_CTRL_CMD_CPRIO(x) ((x) << 19) -#define FW_EQ_CTRL_CMD_ONCHIP(x) ((x) << 18) -#define FW_EQ_CTRL_CMD_PCIECHN(x) ((x) << 16) -#define FW_EQ_CTRL_CMD_IQID(x) ((x) << 0) - -#define FW_EQ_CTRL_CMD_DCAEN(x) ((x) << 31) -#define FW_EQ_CTRL_CMD_DCACPU(x) ((x) << 26) -#define FW_EQ_CTRL_CMD_FBMIN(x) ((x) << 23) -#define FW_EQ_CTRL_CMD_FBMAX(x) ((x) << 20) -#define FW_EQ_CTRL_CMD_CIDXFTHRESHO(x) ((x) << 19) -#define FW_EQ_CTRL_CMD_CIDXFTHRESH(x) ((x) << 16) -#define FW_EQ_CTRL_CMD_EQSIZE(x) ((x) << 0) +#define FW_EQ_CTRL_CMD_PFN_S 8 +#define FW_EQ_CTRL_CMD_PFN_V(x) ((x) << FW_EQ_CTRL_CMD_PFN_S) + +#define FW_EQ_CTRL_CMD_VFN_S 0 +#define FW_EQ_CTRL_CMD_VFN_V(x) ((x) << FW_EQ_CTRL_CMD_VFN_S) + +#define FW_EQ_CTRL_CMD_ALLOC_S 31 +#define FW_EQ_CTRL_CMD_ALLOC_V(x) ((x) << FW_EQ_CTRL_CMD_ALLOC_S) +#define FW_EQ_CTRL_CMD_ALLOC_F FW_EQ_CTRL_CMD_ALLOC_V(1U) + +#define FW_EQ_CTRL_CMD_FREE_S 30 +#define FW_EQ_CTRL_CMD_FREE_V(x) ((x) << FW_EQ_CTRL_CMD_FREE_S) +#define FW_EQ_CTRL_CMD_FREE_F FW_EQ_CTRL_CMD_FREE_V(1U) + +#define FW_EQ_CTRL_CMD_MODIFY_S 29 +#define FW_EQ_CTRL_CMD_MODIFY_V(x) ((x) << FW_EQ_CTRL_CMD_MODIFY_S) +#define FW_EQ_CTRL_CMD_MODIFY_F FW_EQ_CTRL_CMD_MODIFY_V(1U) + +#define FW_EQ_CTRL_CMD_EQSTART_S 28 +#define FW_EQ_CTRL_CMD_EQSTART_V(x) ((x) << FW_EQ_CTRL_CMD_EQSTART_S) +#define FW_EQ_CTRL_CMD_EQSTART_F FW_EQ_CTRL_CMD_EQSTART_V(1U) + +#define FW_EQ_CTRL_CMD_EQSTOP_S 27 +#define FW_EQ_CTRL_CMD_EQSTOP_V(x) ((x) << FW_EQ_CTRL_CMD_EQSTOP_S) +#define FW_EQ_CTRL_CMD_EQSTOP_F FW_EQ_CTRL_CMD_EQSTOP_V(1U) + +#define FW_EQ_CTRL_CMD_CMPLIQID_S 20 +#define FW_EQ_CTRL_CMD_CMPLIQID_V(x) ((x) << FW_EQ_CTRL_CMD_CMPLIQID_S) + +#define FW_EQ_CTRL_CMD_EQID_S 0 +#define FW_EQ_CTRL_CMD_EQID_M 0xfffff +#define FW_EQ_CTRL_CMD_EQID_V(x) ((x) << FW_EQ_CTRL_CMD_EQID_S) +#define FW_EQ_CTRL_CMD_EQID_G(x) \ + (((x) >> FW_EQ_CTRL_CMD_EQID_S) & FW_EQ_CTRL_CMD_EQID_M) + +#define FW_EQ_CTRL_CMD_PHYSEQID_S 0 +#define FW_EQ_CTRL_CMD_PHYSEQID_M 0xfffff +#define FW_EQ_CTRL_CMD_PHYSEQID_G(x) \ + (((x) >> FW_EQ_CTRL_CMD_PHYSEQID_S) & FW_EQ_CTRL_CMD_PHYSEQID_M) + +#define FW_EQ_CTRL_CMD_FETCHSZM_S 26 +#define FW_EQ_CTRL_CMD_FETCHSZM_V(x) ((x) << FW_EQ_CTRL_CMD_FETCHSZM_S) +#define FW_EQ_CTRL_CMD_FETCHSZM_F FW_EQ_CTRL_CMD_FETCHSZM_V(1U) + +#define FW_EQ_CTRL_CMD_STATUSPGNS_S 25 +#define FW_EQ_CTRL_CMD_STATUSPGNS_V(x) ((x) << FW_EQ_CTRL_CMD_STATUSPGNS_S) +#define FW_EQ_CTRL_CMD_STATUSPGNS_F FW_EQ_CTRL_CMD_STATUSPGNS_V(1U) + +#define FW_EQ_CTRL_CMD_STATUSPGRO_S 24 +#define FW_EQ_CTRL_CMD_STATUSPGRO_V(x) ((x) << FW_EQ_CTRL_CMD_STATUSPGRO_S) +#define FW_EQ_CTRL_CMD_STATUSPGRO_F FW_EQ_CTRL_CMD_STATUSPGRO_V(1U) + +#define FW_EQ_CTRL_CMD_FETCHNS_S 23 +#define FW_EQ_CTRL_CMD_FETCHNS_V(x) ((x) << FW_EQ_CTRL_CMD_FETCHNS_S) +#define FW_EQ_CTRL_CMD_FETCHNS_F FW_EQ_CTRL_CMD_FETCHNS_V(1U) + +#define FW_EQ_CTRL_CMD_FETCHRO_S 22 +#define FW_EQ_CTRL_CMD_FETCHRO_V(x) ((x) << FW_EQ_CTRL_CMD_FETCHRO_S) +#define FW_EQ_CTRL_CMD_FETCHRO_F FW_EQ_CTRL_CMD_FETCHRO_V(1U) + +#define FW_EQ_CTRL_CMD_HOSTFCMODE_S 20 +#define FW_EQ_CTRL_CMD_HOSTFCMODE_V(x) ((x) << FW_EQ_CTRL_CMD_HOSTFCMODE_S) + +#define FW_EQ_CTRL_CMD_CPRIO_S 19 +#define FW_EQ_CTRL_CMD_CPRIO_V(x) ((x) << FW_EQ_CTRL_CMD_CPRIO_S) + +#define FW_EQ_CTRL_CMD_ONCHIP_S 18 +#define FW_EQ_CTRL_CMD_ONCHIP_V(x) ((x) << FW_EQ_CTRL_CMD_ONCHIP_S) + +#define FW_EQ_CTRL_CMD_PCIECHN_S 16 +#define FW_EQ_CTRL_CMD_PCIECHN_V(x) ((x) << FW_EQ_CTRL_CMD_PCIECHN_S) + +#define FW_EQ_CTRL_CMD_IQID_S 0 +#define FW_EQ_CTRL_CMD_IQID_V(x) ((x) << FW_EQ_CTRL_CMD_IQID_S) + +#define FW_EQ_CTRL_CMD_DCAEN_S 31 +#define FW_EQ_CTRL_CMD_DCAEN_V(x) ((x) << FW_EQ_CTRL_CMD_DCAEN_S) + +#define FW_EQ_CTRL_CMD_DCACPU_S 26 +#define FW_EQ_CTRL_CMD_DCACPU_V(x) ((x) << FW_EQ_CTRL_CMD_DCACPU_S) + +#define FW_EQ_CTRL_CMD_FBMIN_S 23 +#define FW_EQ_CTRL_CMD_FBMIN_V(x) ((x) << FW_EQ_CTRL_CMD_FBMIN_S) + +#define FW_EQ_CTRL_CMD_FBMAX_S 20 +#define FW_EQ_CTRL_CMD_FBMAX_V(x) ((x) << FW_EQ_CTRL_CMD_FBMAX_S) + +#define FW_EQ_CTRL_CMD_CIDXFTHRESHO_S 19 +#define FW_EQ_CTRL_CMD_CIDXFTHRESHO_V(x) \ + ((x) << FW_EQ_CTRL_CMD_CIDXFTHRESHO_S) + +#define FW_EQ_CTRL_CMD_CIDXFTHRESH_S 16 +#define FW_EQ_CTRL_CMD_CIDXFTHRESH_V(x) ((x) << FW_EQ_CTRL_CMD_CIDXFTHRESH_S) + +#define FW_EQ_CTRL_CMD_EQSIZE_S 0 +#define FW_EQ_CTRL_CMD_EQSIZE_V(x) ((x) << FW_EQ_CTRL_CMD_EQSIZE_S) struct fw_eq_ofld_cmd { __be32 op_to_vfn; @@ -1455,37 +1735,95 @@ struct fw_eq_ofld_cmd { __be64 eqaddr; }; -#define FW_EQ_OFLD_CMD_PFN(x) ((x) << 8) -#define FW_EQ_OFLD_CMD_VFN(x) ((x) << 0) - -#define FW_EQ_OFLD_CMD_ALLOC (1U << 31) -#define FW_EQ_OFLD_CMD_FREE (1U << 30) -#define FW_EQ_OFLD_CMD_MODIFY (1U << 29) -#define FW_EQ_OFLD_CMD_EQSTART (1U << 28) -#define FW_EQ_OFLD_CMD_EQSTOP (1U << 27) - -#define FW_EQ_OFLD_CMD_EQID(x) ((x) << 0) -#define FW_EQ_OFLD_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) -#define FW_EQ_OFLD_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff) - -#define FW_EQ_OFLD_CMD_FETCHSZM(x) ((x) << 26) -#define FW_EQ_OFLD_CMD_STATUSPGNS(x) ((x) << 25) -#define FW_EQ_OFLD_CMD_STATUSPGRO(x) ((x) << 24) -#define FW_EQ_OFLD_CMD_FETCHNS(x) ((x) << 23) -#define FW_EQ_OFLD_CMD_FETCHRO(x) ((x) << 22) -#define FW_EQ_OFLD_CMD_HOSTFCMODE(x) ((x) << 20) -#define FW_EQ_OFLD_CMD_CPRIO(x) ((x) << 19) -#define FW_EQ_OFLD_CMD_ONCHIP(x) ((x) << 18) -#define FW_EQ_OFLD_CMD_PCIECHN(x) ((x) << 16) -#define FW_EQ_OFLD_CMD_IQID(x) ((x) << 0) - -#define FW_EQ_OFLD_CMD_DCAEN(x) ((x) << 31) -#define FW_EQ_OFLD_CMD_DCACPU(x) ((x) << 26) -#define FW_EQ_OFLD_CMD_FBMIN(x) ((x) << 23) -#define FW_EQ_OFLD_CMD_FBMAX(x) ((x) << 20) -#define FW_EQ_OFLD_CMD_CIDXFTHRESHO(x) ((x) << 19) -#define FW_EQ_OFLD_CMD_CIDXFTHRESH(x) ((x) << 16) -#define FW_EQ_OFLD_CMD_EQSIZE(x) ((x) << 0) +#define FW_EQ_OFLD_CMD_PFN_S 8 +#define FW_EQ_OFLD_CMD_PFN_V(x) ((x) << FW_EQ_OFLD_CMD_PFN_S) + +#define FW_EQ_OFLD_CMD_VFN_S 0 +#define FW_EQ_OFLD_CMD_VFN_V(x) ((x) << FW_EQ_OFLD_CMD_VFN_S) + +#define FW_EQ_OFLD_CMD_ALLOC_S 31 +#define FW_EQ_OFLD_CMD_ALLOC_V(x) ((x) << FW_EQ_OFLD_CMD_ALLOC_S) +#define FW_EQ_OFLD_CMD_ALLOC_F FW_EQ_OFLD_CMD_ALLOC_V(1U) + +#define FW_EQ_OFLD_CMD_FREE_S 30 +#define FW_EQ_OFLD_CMD_FREE_V(x) ((x) << FW_EQ_OFLD_CMD_FREE_S) +#define FW_EQ_OFLD_CMD_FREE_F FW_EQ_OFLD_CMD_FREE_V(1U) + +#define FW_EQ_OFLD_CMD_MODIFY_S 29 +#define FW_EQ_OFLD_CMD_MODIFY_V(x) ((x) << FW_EQ_OFLD_CMD_MODIFY_S) +#define FW_EQ_OFLD_CMD_MODIFY_F FW_EQ_OFLD_CMD_MODIFY_V(1U) + +#define FW_EQ_OFLD_CMD_EQSTART_S 28 +#define FW_EQ_OFLD_CMD_EQSTART_V(x) ((x) << FW_EQ_OFLD_CMD_EQSTART_S) +#define FW_EQ_OFLD_CMD_EQSTART_F FW_EQ_OFLD_CMD_EQSTART_V(1U) + +#define FW_EQ_OFLD_CMD_EQSTOP_S 27 +#define FW_EQ_OFLD_CMD_EQSTOP_V(x) ((x) << FW_EQ_OFLD_CMD_EQSTOP_S) +#define FW_EQ_OFLD_CMD_EQSTOP_F FW_EQ_OFLD_CMD_EQSTOP_V(1U) + +#define FW_EQ_OFLD_CMD_EQID_S 0 +#define FW_EQ_OFLD_CMD_EQID_M 0xfffff +#define FW_EQ_OFLD_CMD_EQID_V(x) ((x) << FW_EQ_OFLD_CMD_EQID_S) +#define FW_EQ_OFLD_CMD_EQID_G(x) \ + (((x) >> FW_EQ_OFLD_CMD_EQID_S) & FW_EQ_OFLD_CMD_EQID_M) + +#define FW_EQ_OFLD_CMD_PHYSEQID_S 0 +#define FW_EQ_OFLD_CMD_PHYSEQID_M 0xfffff +#define FW_EQ_OFLD_CMD_PHYSEQID_G(x) \ + (((x) >> FW_EQ_OFLD_CMD_PHYSEQID_S) & FW_EQ_OFLD_CMD_PHYSEQID_M) + +#define FW_EQ_OFLD_CMD_FETCHSZM_S 26 +#define FW_EQ_OFLD_CMD_FETCHSZM_V(x) ((x) << FW_EQ_OFLD_CMD_FETCHSZM_S) + +#define FW_EQ_OFLD_CMD_STATUSPGNS_S 25 +#define FW_EQ_OFLD_CMD_STATUSPGNS_V(x) ((x) << FW_EQ_OFLD_CMD_STATUSPGNS_S) + +#define FW_EQ_OFLD_CMD_STATUSPGRO_S 24 +#define FW_EQ_OFLD_CMD_STATUSPGRO_V(x) ((x) << FW_EQ_OFLD_CMD_STATUSPGRO_S) + +#define FW_EQ_OFLD_CMD_FETCHNS_S 23 +#define FW_EQ_OFLD_CMD_FETCHNS_V(x) ((x) << FW_EQ_OFLD_CMD_FETCHNS_S) + +#define FW_EQ_OFLD_CMD_FETCHRO_S 22 +#define FW_EQ_OFLD_CMD_FETCHRO_V(x) ((x) << FW_EQ_OFLD_CMD_FETCHRO_S) +#define FW_EQ_OFLD_CMD_FETCHRO_F FW_EQ_OFLD_CMD_FETCHRO_V(1U) + +#define FW_EQ_OFLD_CMD_HOSTFCMODE_S 20 +#define FW_EQ_OFLD_CMD_HOSTFCMODE_V(x) ((x) << FW_EQ_OFLD_CMD_HOSTFCMODE_S) + +#define FW_EQ_OFLD_CMD_CPRIO_S 19 +#define FW_EQ_OFLD_CMD_CPRIO_V(x) ((x) << FW_EQ_OFLD_CMD_CPRIO_S) + +#define FW_EQ_OFLD_CMD_ONCHIP_S 18 +#define FW_EQ_OFLD_CMD_ONCHIP_V(x) ((x) << FW_EQ_OFLD_CMD_ONCHIP_S) + +#define FW_EQ_OFLD_CMD_PCIECHN_S 16 +#define FW_EQ_OFLD_CMD_PCIECHN_V(x) ((x) << FW_EQ_OFLD_CMD_PCIECHN_S) + +#define FW_EQ_OFLD_CMD_IQID_S 0 +#define FW_EQ_OFLD_CMD_IQID_V(x) ((x) << FW_EQ_OFLD_CMD_IQID_S) + +#define FW_EQ_OFLD_CMD_DCAEN_S 31 +#define FW_EQ_OFLD_CMD_DCAEN_V(x) ((x) << FW_EQ_OFLD_CMD_DCAEN_S) + +#define FW_EQ_OFLD_CMD_DCACPU_S 26 +#define FW_EQ_OFLD_CMD_DCACPU_V(x) ((x) << FW_EQ_OFLD_CMD_DCACPU_S) + +#define FW_EQ_OFLD_CMD_FBMIN_S 23 +#define FW_EQ_OFLD_CMD_FBMIN_V(x) ((x) << FW_EQ_OFLD_CMD_FBMIN_S) + +#define FW_EQ_OFLD_CMD_FBMAX_S 20 +#define FW_EQ_OFLD_CMD_FBMAX_V(x) ((x) << FW_EQ_OFLD_CMD_FBMAX_S) + +#define FW_EQ_OFLD_CMD_CIDXFTHRESHO_S 19 +#define FW_EQ_OFLD_CMD_CIDXFTHRESHO_V(x) \ + ((x) << FW_EQ_OFLD_CMD_CIDXFTHRESHO_S) + +#define FW_EQ_OFLD_CMD_CIDXFTHRESH_S 16 +#define FW_EQ_OFLD_CMD_CIDXFTHRESH_V(x) ((x) << FW_EQ_OFLD_CMD_CIDXFTHRESH_S) + +#define FW_EQ_OFLD_CMD_EQSIZE_S 0 +#define FW_EQ_OFLD_CMD_EQSIZE_V(x) ((x) << FW_EQ_OFLD_CMD_EQSIZE_S) /* * Macros for VIID parsing: diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 50b1b34bde6d..045301d336bb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -2092,22 +2092,22 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F); - cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_ALLOC | - FW_IQ_CMD_IQSTART(1) | + cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_ALLOC_F | + FW_IQ_CMD_IQSTART_F | FW_LEN16(cmd)); cmd.type_to_iqandstindex = - cpu_to_be32(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) | - FW_IQ_CMD_IQASYNCH(iqasynch) | - FW_IQ_CMD_VIID(pi->viid) | - FW_IQ_CMD_IQANDST(iqandst) | - FW_IQ_CMD_IQANUS(1) | - FW_IQ_CMD_IQANUD(SGE_UPDATEDEL_INTR) | - FW_IQ_CMD_IQANDSTINDEX(intr_dest)); + cpu_to_be32(FW_IQ_CMD_TYPE_V(FW_IQ_TYPE_FL_INT_CAP) | + FW_IQ_CMD_IQASYNCH_V(iqasynch) | + FW_IQ_CMD_VIID_V(pi->viid) | + FW_IQ_CMD_IQANDST_V(iqandst) | + FW_IQ_CMD_IQANUS_V(1) | + FW_IQ_CMD_IQANUD_V(SGE_UPDATEDEL_INTR) | + FW_IQ_CMD_IQANDSTINDEX_V(intr_dest)); cmd.iqdroprss_to_iqesize = - cpu_to_be16(FW_IQ_CMD_IQPCIECH(pi->port_id) | - FW_IQ_CMD_IQGTSMODE | - FW_IQ_CMD_IQINTCNTTHRESH(rspq->pktcnt_idx) | - FW_IQ_CMD_IQESIZE(ilog2(rspq->iqe_len) - 4)); + cpu_to_be16(FW_IQ_CMD_IQPCIECH_V(pi->port_id) | + FW_IQ_CMD_IQGTSMODE_F | + FW_IQ_CMD_IQINTCNTTHRESH_V(rspq->pktcnt_idx) | + FW_IQ_CMD_IQESIZE_V(ilog2(rspq->iqe_len) - 4)); cmd.iqsize = cpu_to_be16(rspq->size); cmd.iqaddr = cpu_to_be64(rspq->phys_addr); @@ -2141,13 +2141,13 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, */ cmd.iqns_to_fl0congen = cpu_to_be32( - FW_IQ_CMD_FL0HOSTFCMODE(SGE_HOSTFCMODE_NONE) | - FW_IQ_CMD_FL0PACKEN(1) | - FW_IQ_CMD_FL0PADEN(1)); + FW_IQ_CMD_FL0HOSTFCMODE_V(SGE_HOSTFCMODE_NONE) | + FW_IQ_CMD_FL0PACKEN_F | + FW_IQ_CMD_FL0PADEN_F); cmd.fl0dcaen_to_fl0cidxfthresh = cpu_to_be16( - FW_IQ_CMD_FL0FBMIN(SGE_FETCHBURSTMIN_64B) | - FW_IQ_CMD_FL0FBMAX(SGE_FETCHBURSTMAX_512B)); + FW_IQ_CMD_FL0FBMIN_V(SGE_FETCHBURSTMIN_64B) | + FW_IQ_CMD_FL0FBMAX_V(SGE_FETCHBURSTMAX_512B)); cmd.fl0size = cpu_to_be16(flsz); cmd.fl0addr = cpu_to_be64(fl->addr); } @@ -2255,20 +2255,21 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F); - cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC | - FW_EQ_ETH_CMD_EQSTART | + cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_ALLOC_F | + FW_EQ_ETH_CMD_EQSTART_F | FW_LEN16(cmd)); - cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE | - FW_EQ_ETH_CMD_VIID(pi->viid)); + cmd.viid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_AUTOEQUEQE_F | + FW_EQ_ETH_CMD_VIID_V(pi->viid)); cmd.fetchszm_to_iqid = - cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE(SGE_HOSTFCMODE_STPG) | - FW_EQ_ETH_CMD_PCIECHN(pi->port_id) | - FW_EQ_ETH_CMD_IQID(iqid)); + cpu_to_be32(FW_EQ_ETH_CMD_HOSTFCMODE_V(SGE_HOSTFCMODE_STPG) | + FW_EQ_ETH_CMD_PCIECHN_V(pi->port_id) | + FW_EQ_ETH_CMD_IQID_V(iqid)); cmd.dcaen_to_eqsize = - cpu_to_be32(FW_EQ_ETH_CMD_FBMIN(SGE_FETCHBURSTMIN_64B) | - FW_EQ_ETH_CMD_FBMAX(SGE_FETCHBURSTMAX_512B) | - FW_EQ_ETH_CMD_CIDXFTHRESH(SGE_CIDXFLUSHTHRESH_32) | - FW_EQ_ETH_CMD_EQSIZE(nentries)); + cpu_to_be32(FW_EQ_ETH_CMD_FBMIN_V(SGE_FETCHBURSTMIN_64B) | + FW_EQ_ETH_CMD_FBMAX_V(SGE_FETCHBURSTMAX_512B) | + FW_EQ_ETH_CMD_CIDXFTHRESH_V( + SGE_CIDXFLUSHTHRESH_32) | + FW_EQ_ETH_CMD_EQSIZE_V(nentries)); cmd.eqaddr = cpu_to_be64(txq->q.phys_addr); /* @@ -2294,9 +2295,9 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, txq->q.cidx = 0; txq->q.pidx = 0; txq->q.stat = (void *)&txq->q.desc[txq->q.size]; - txq->q.cntxt_id = FW_EQ_ETH_CMD_EQID_GET(be32_to_cpu(rpl.eqid_pkd)); + txq->q.cntxt_id = FW_EQ_ETH_CMD_EQID_G(be32_to_cpu(rpl.eqid_pkd)); txq->q.abs_id = - FW_EQ_ETH_CMD_PHYSEQID_GET(be32_to_cpu(rpl.physeqid_pkd)); + FW_EQ_ETH_CMD_PHYSEQID_G(be32_to_cpu(rpl.physeqid_pkd)); txq->txq = devq; txq->tso = 0; txq->tx_cso = 0; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index f2087eb013c3..5d3bd8db7ea6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -1302,10 +1302,10 @@ int t4vf_iq_free(struct adapter *adapter, unsigned int iqtype, cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F); - cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE | + cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE_F | FW_LEN16(cmd)); cmd.type_to_iqandstindex = - cpu_to_be32(FW_IQ_CMD_TYPE(iqtype)); + cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype)); cmd.iqid = cpu_to_be16(iqid); cmd.fl0id = cpu_to_be16(fl0id); @@ -1328,9 +1328,9 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F); - cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE | + cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE_F | FW_LEN16(cmd)); - cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID(eqid)); + cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID_V(eqid)); return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); } diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index a1e0568b657f..5a514b6bc8ec 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -445,16 +445,16 @@ csio_mb_iq_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv, cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_IQ_CMD_PFN(iq_params->pfn) | - FW_IQ_CMD_VFN(iq_params->vfn)); + FW_IQ_CMD_PFN_V(iq_params->pfn) | + FW_IQ_CMD_VFN_V(iq_params->vfn)); - cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | + cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC_F | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->type_to_iqandstindex = htonl( - FW_IQ_CMD_VIID(iq_params->viid) | - FW_IQ_CMD_TYPE(iq_params->type) | - FW_IQ_CMD_IQASYNCH(iq_params->iqasynch)); + FW_IQ_CMD_VIID_V(iq_params->viid) | + FW_IQ_CMD_TYPE_V(iq_params->type) | + FW_IQ_CMD_IQASYNCH_V(iq_params->iqasynch)); cmdp->fl0size = htons(iq_params->fl0size); cmdp->fl0size = htons(iq_params->fl1size); @@ -488,8 +488,8 @@ csio_mb_iq_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, struct fw_iq_cmd *cmdp = (struct fw_iq_cmd *)(mbp->mb); uint32_t iq_start_stop = (iq_params->iq_start) ? - FW_IQ_CMD_IQSTART(1) : - FW_IQ_CMD_IQSTOP(1); + FW_IQ_CMD_IQSTART_F : + FW_IQ_CMD_IQSTOP_F; /* * If this IQ write is cascaded with IQ alloc request, do not @@ -501,49 +501,49 @@ csio_mb_iq_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, cmdp->op_to_vfn |= htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_IQ_CMD_PFN(iq_params->pfn) | - FW_IQ_CMD_VFN(iq_params->vfn)); + FW_IQ_CMD_PFN_V(iq_params->pfn) | + FW_IQ_CMD_VFN_V(iq_params->vfn)); cmdp->alloc_to_len16 |= htonl(iq_start_stop | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); cmdp->iqid |= htons(iq_params->iqid); cmdp->fl0id |= htons(iq_params->fl0id); cmdp->fl1id |= htons(iq_params->fl1id); cmdp->type_to_iqandstindex |= htonl( - FW_IQ_CMD_IQANDST(iq_params->iqandst) | - FW_IQ_CMD_IQANUS(iq_params->iqanus) | - FW_IQ_CMD_IQANUD(iq_params->iqanud) | - FW_IQ_CMD_IQANDSTINDEX(iq_params->iqandstindex)); + FW_IQ_CMD_IQANDST_V(iq_params->iqandst) | + FW_IQ_CMD_IQANUS_V(iq_params->iqanus) | + FW_IQ_CMD_IQANUD_V(iq_params->iqanud) | + FW_IQ_CMD_IQANDSTINDEX_V(iq_params->iqandstindex)); cmdp->iqdroprss_to_iqesize |= htons( - FW_IQ_CMD_IQPCIECH(iq_params->iqpciech) | - FW_IQ_CMD_IQDCAEN(iq_params->iqdcaen) | - FW_IQ_CMD_IQDCACPU(iq_params->iqdcacpu) | - FW_IQ_CMD_IQINTCNTTHRESH(iq_params->iqintcntthresh) | - FW_IQ_CMD_IQCPRIO(iq_params->iqcprio) | - FW_IQ_CMD_IQESIZE(iq_params->iqesize)); + FW_IQ_CMD_IQPCIECH_V(iq_params->iqpciech) | + FW_IQ_CMD_IQDCAEN_V(iq_params->iqdcaen) | + FW_IQ_CMD_IQDCACPU_V(iq_params->iqdcacpu) | + FW_IQ_CMD_IQINTCNTTHRESH_V(iq_params->iqintcntthresh) | + FW_IQ_CMD_IQCPRIO_V(iq_params->iqcprio) | + FW_IQ_CMD_IQESIZE_V(iq_params->iqesize)); cmdp->iqsize |= htons(iq_params->iqsize); cmdp->iqaddr |= cpu_to_be64(iq_params->iqaddr); if (iq_params->type == 0) { cmdp->iqns_to_fl0congen |= htonl( - FW_IQ_CMD_IQFLINTIQHSEN(iq_params->iqflintiqhsen)| - FW_IQ_CMD_IQFLINTCONGEN(iq_params->iqflintcongen)); + FW_IQ_CMD_IQFLINTIQHSEN_V(iq_params->iqflintiqhsen)| + FW_IQ_CMD_IQFLINTCONGEN_V(iq_params->iqflintcongen)); } if (iq_params->fl0size && iq_params->fl0addr && (iq_params->fl0id != 0xFFFF)) { cmdp->iqns_to_fl0congen |= htonl( - FW_IQ_CMD_FL0HOSTFCMODE(iq_params->fl0hostfcmode)| - FW_IQ_CMD_FL0CPRIO(iq_params->fl0cprio) | - FW_IQ_CMD_FL0PADEN(iq_params->fl0paden) | - FW_IQ_CMD_FL0PACKEN(iq_params->fl0packen)); + FW_IQ_CMD_FL0HOSTFCMODE_V(iq_params->fl0hostfcmode)| + FW_IQ_CMD_FL0CPRIO_V(iq_params->fl0cprio) | + FW_IQ_CMD_FL0PADEN_V(iq_params->fl0paden) | + FW_IQ_CMD_FL0PACKEN_V(iq_params->fl0packen)); cmdp->fl0dcaen_to_fl0cidxfthresh |= htons( - FW_IQ_CMD_FL0DCAEN(iq_params->fl0dcaen) | - FW_IQ_CMD_FL0DCACPU(iq_params->fl0dcacpu) | - FW_IQ_CMD_FL0FBMIN(iq_params->fl0fbmin) | - FW_IQ_CMD_FL0FBMAX(iq_params->fl0fbmax) | - FW_IQ_CMD_FL0CIDXFTHRESH(iq_params->fl0cidxfthresh)); + FW_IQ_CMD_FL0DCAEN_V(iq_params->fl0dcaen) | + FW_IQ_CMD_FL0DCACPU_V(iq_params->fl0dcacpu) | + FW_IQ_CMD_FL0FBMIN_V(iq_params->fl0fbmin) | + FW_IQ_CMD_FL0FBMAX_V(iq_params->fl0fbmax) | + FW_IQ_CMD_FL0CIDXFTHRESH_V(iq_params->fl0cidxfthresh)); cmdp->fl0size |= htons(iq_params->fl0size); cmdp->fl0addr |= cpu_to_be64(iq_params->fl0addr); } @@ -624,11 +624,11 @@ csio_mb_iq_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv, cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_IQ_CMD_PFN(iq_params->pfn) | - FW_IQ_CMD_VFN(iq_params->vfn)); - cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_FREE | + FW_IQ_CMD_PFN_V(iq_params->pfn) | + FW_IQ_CMD_VFN_V(iq_params->vfn)); + cmdp->alloc_to_len16 = htonl(FW_IQ_CMD_FREE_F | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); - cmdp->type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iq_params->type)); + cmdp->type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE_V(iq_params->type)); cmdp->iqid = htons(iq_params->iqid); cmdp->fl0id = htons(iq_params->fl0id); @@ -659,9 +659,9 @@ csio_mb_eq_ofld_alloc(struct csio_hw *hw, struct csio_mb *mbp, void *priv, CSIO_INIT_MBP(mbp, cmdp, mb_tmo, priv, cbfn, 1); cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | - FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); - cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | + FW_EQ_OFLD_CMD_PFN_V(eq_ofld_params->pfn) | + FW_EQ_OFLD_CMD_VFN_V(eq_ofld_params->vfn)); + cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC_F | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); } /* csio_mb_eq_ofld_alloc */ @@ -694,7 +694,8 @@ csio_mb_eq_ofld_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, struct fw_eq_ofld_cmd *cmdp = (struct fw_eq_ofld_cmd *)(mbp->mb); uint32_t eq_start_stop = (eq_ofld_params->eqstart) ? - FW_EQ_OFLD_CMD_EQSTART : FW_EQ_OFLD_CMD_EQSTOP; + FW_EQ_OFLD_CMD_EQSTART_F : + FW_EQ_OFLD_CMD_EQSTOP_F; /* * If this EQ write is cascaded with EQ alloc request, do not @@ -706,27 +707,27 @@ csio_mb_eq_ofld_write(struct csio_hw *hw, struct csio_mb *mbp, void *priv, cmdp->op_to_vfn |= htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | - FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); + FW_EQ_OFLD_CMD_PFN_V(eq_ofld_params->pfn) | + FW_EQ_OFLD_CMD_VFN_V(eq_ofld_params->vfn)); cmdp->alloc_to_len16 |= htonl(eq_start_stop | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); - cmdp->eqid_pkd |= htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid)); + cmdp->eqid_pkd |= htonl(FW_EQ_OFLD_CMD_EQID_V(eq_ofld_params->eqid)); cmdp->fetchszm_to_iqid |= htonl( - FW_EQ_OFLD_CMD_HOSTFCMODE(eq_ofld_params->hostfcmode) | - FW_EQ_OFLD_CMD_CPRIO(eq_ofld_params->cprio) | - FW_EQ_OFLD_CMD_PCIECHN(eq_ofld_params->pciechn) | - FW_EQ_OFLD_CMD_IQID(eq_ofld_params->iqid)); + FW_EQ_OFLD_CMD_HOSTFCMODE_V(eq_ofld_params->hostfcmode) | + FW_EQ_OFLD_CMD_CPRIO_V(eq_ofld_params->cprio) | + FW_EQ_OFLD_CMD_PCIECHN_V(eq_ofld_params->pciechn) | + FW_EQ_OFLD_CMD_IQID_V(eq_ofld_params->iqid)); cmdp->dcaen_to_eqsize |= htonl( - FW_EQ_OFLD_CMD_DCAEN(eq_ofld_params->dcaen) | - FW_EQ_OFLD_CMD_DCACPU(eq_ofld_params->dcacpu) | - FW_EQ_OFLD_CMD_FBMIN(eq_ofld_params->fbmin) | - FW_EQ_OFLD_CMD_FBMAX(eq_ofld_params->fbmax) | - FW_EQ_OFLD_CMD_CIDXFTHRESHO(eq_ofld_params->cidxfthresho) | - FW_EQ_OFLD_CMD_CIDXFTHRESH(eq_ofld_params->cidxfthresh) | - FW_EQ_OFLD_CMD_EQSIZE(eq_ofld_params->eqsize)); + FW_EQ_OFLD_CMD_DCAEN_V(eq_ofld_params->dcaen) | + FW_EQ_OFLD_CMD_DCACPU_V(eq_ofld_params->dcacpu) | + FW_EQ_OFLD_CMD_FBMIN_V(eq_ofld_params->fbmin) | + FW_EQ_OFLD_CMD_FBMAX_V(eq_ofld_params->fbmax) | + FW_EQ_OFLD_CMD_CIDXFTHRESHO_V(eq_ofld_params->cidxfthresho) | + FW_EQ_OFLD_CMD_CIDXFTHRESH_V(eq_ofld_params->cidxfthresh) | + FW_EQ_OFLD_CMD_EQSIZE_V(eq_ofld_params->eqsize)); cmdp->eqaddr |= cpu_to_be64(eq_ofld_params->eqaddr); @@ -776,9 +777,9 @@ csio_mb_eq_ofld_alloc_write_rsp(struct csio_hw *hw, *ret_val = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (*ret_val == FW_SUCCESS) { - eq_ofld_params->eqid = FW_EQ_OFLD_CMD_EQID_GET( + eq_ofld_params->eqid = FW_EQ_OFLD_CMD_EQID_G( ntohl(rsp->eqid_pkd)); - eq_ofld_params->physeqid = FW_EQ_OFLD_CMD_PHYSEQID_GET( + eq_ofld_params->physeqid = FW_EQ_OFLD_CMD_PHYSEQID_G( ntohl(rsp->physeqid_pkd)); } else eq_ofld_params->eqid = 0; @@ -809,11 +810,11 @@ csio_mb_eq_ofld_free(struct csio_hw *hw, struct csio_mb *mbp, void *priv, cmdp->op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_EQ_OFLD_CMD_PFN(eq_ofld_params->pfn) | - FW_EQ_OFLD_CMD_VFN(eq_ofld_params->vfn)); - cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | + FW_EQ_OFLD_CMD_PFN_V(eq_ofld_params->pfn) | + FW_EQ_OFLD_CMD_VFN_V(eq_ofld_params->vfn)); + cmdp->alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE_F | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); - cmdp->eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eq_ofld_params->eqid)); + cmdp->eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID_V(eq_ofld_params->eqid)); } /* csio_mb_eq_ofld_free */ -- GitLab From 2b5fb1f25e7b22cb96fa8662f9c8f8cf34abc109 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 21 Nov 2014 12:52:04 +0530 Subject: [PATCH 5853/9457] cxgb4/cxgb4vf/csiostor: Cleanup macros/register defines related to port and VI This patch cleanups all port and VI related macros/register defines that are defined in t4fw_api.h and the affected files. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- .../net/ethernet/chelsio/cxgb4/cxgb4_dcb.c | 14 +- .../net/ethernet/chelsio/cxgb4/cxgb4_dcb.h | 4 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 8 +- drivers/net/ethernet/chelsio/cxgb4/l2t.c | 4 +- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 106 +++--- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 350 ++++++++++++------ .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 100 ++--- drivers/scsi/csiostor/csio_mb.c | 20 +- 8 files changed, 374 insertions(+), 232 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c index 4fe33606f372..a35d1ec6950e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c @@ -243,7 +243,7 @@ void cxgb4_dcb_handle_fw_update(struct adapter *adap, const struct fw_port_cmd *pcmd) { const union fw_port_dcb *fwdcb = &pcmd->u.dcb; - int port = FW_PORT_CMD_PORTID_GET(be32_to_cpu(pcmd->op_to_portid)); + int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid)); struct net_device *dev = adap->port[port]; struct port_info *pi = netdev_priv(dev); struct port_dcb_info *dcb = &pi->dcb; @@ -256,12 +256,12 @@ void cxgb4_dcb_handle_fw_update(struct adapter *adap, if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) { enum cxgb4_dcb_state_input input = ((pcmd->u.dcb.control.all_syncd_pkd & - FW_PORT_CMD_ALL_SYNCD) + FW_PORT_CMD_ALL_SYNCD_F) ? CXGB4_DCB_STATE_FW_ALLSYNCED : CXGB4_DCB_STATE_FW_INCOMPLETE); if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) { - dcb_running_version = FW_PORT_CMD_DCB_VERSION_GET( + dcb_running_version = FW_PORT_CMD_DCB_VERSION_G( be16_to_cpu( pcmd->u.dcb.control.dcb_version_to_app_state)); if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 || @@ -519,7 +519,7 @@ static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc, INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); if (pi->dcb.state == CXGB4_DCB_STATE_HOST) - pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY); + pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); if (err != FW_PORT_DCB_CFG_SUCCESS) @@ -583,7 +583,7 @@ static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid, INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); if (pi->dcb.state == CXGB4_DCB_STATE_HOST) - pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY); + pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); @@ -623,7 +623,7 @@ static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg) INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); if (pi->dcb.state == CXGB4_DCB_STATE_HOST) - pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY); + pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC; pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen; @@ -842,7 +842,7 @@ static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id, /* write out new app table entry */ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id); if (pi->dcb.state == CXGB4_DCB_STATE_HOST) - pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY); + pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F); pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID; pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h index c0724a5b5942..31ce425616c9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h @@ -45,9 +45,9 @@ cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | \ FW_CMD_REQUEST_F | \ FW_CMD_##__op##_F | \ - FW_PORT_CMD_PORTID(__port)); \ + FW_PORT_CMD_PORTID_V(__port)); \ (__pcmd).action_to_len16 = \ - cpu_to_be32(FW_PORT_CMD_ACTION(__action) | \ + cpu_to_be32(FW_PORT_CMD_ACTION_V(__action) | \ FW_LEN16(pcmd)); \ } while (0) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 4caec41f91e2..4c663cc106f1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -710,7 +710,7 @@ EXPORT_SYMBOL(cxgb4_dcb_enabled); /* Handle a Data Center Bridging update message from the firmware. */ static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd) { - int port = FW_PORT_CMD_PORTID_GET(ntohl(pcmd->op_to_portid)); + int port = FW_PORT_CMD_PORTID_G(ntohl(pcmd->op_to_portid)); struct net_device *dev = adap->port[port]; int old_dcb_enabled = cxgb4_dcb_enabled(dev); int new_dcb_enabled; @@ -835,15 +835,15 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, const struct fw_port_cmd *pcmd = (const void *)p->data; unsigned int cmd = FW_CMD_OP_G(ntohl(pcmd->op_to_portid)); unsigned int action = - FW_PORT_CMD_ACTION_GET(ntohl(pcmd->action_to_len16)); + FW_PORT_CMD_ACTION_G(ntohl(pcmd->action_to_len16)); if (cmd == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { - int port = FW_PORT_CMD_PORTID_GET( + int port = FW_PORT_CMD_PORTID_G( be32_to_cpu(pcmd->op_to_portid)); struct net_device *dev = q->adap->port[port]; int state_input = ((pcmd->u.info.dcbxdis_pkd & - FW_PORT_CMD_DCBXDIS) + FW_PORT_CMD_DCBXDIS_F) ? CXGB4_DCB_INPUT_FW_DISABLED : CXGB4_DCB_INPUT_FW_ENABLED); diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index 1eca0e21f738..a047baa9fd04 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -435,9 +435,9 @@ u64 cxgb4_select_ntuple(struct net_device *dev, if (tp->vnic_shift >= 0) { u32 viid = cxgb4_port_viid(dev); - u32 vf = FW_VIID_VIN_GET(viid); + u32 vf = FW_VIID_VIN_G(viid); u32 pf = FW_VIID_PFN_G(viid); - u32 vld = FW_VIID_VIVLD_GET(viid); + u32 vld = FW_VIID_VIVLD_G(viid); ntuple |= (u64)(V_FT_VNID_ID_VF(vf) | V_FT_VNID_ID_PF(pf) | diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index da72814dff3d..20432e2bb17f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -1237,7 +1237,7 @@ int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc) { struct fw_port_cmd c; - unsigned int fc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO); + unsigned int fc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO); lc->link_ok = 0; if (lc->requested_fc & PAUSE_RX) @@ -1247,8 +1247,8 @@ int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, memset(&c, 0, sizeof(c)); c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + FW_CMD_EXEC_F | FW_PORT_CMD_PORTID_V(port)); + c.action_to_len16 = htonl(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); if (!(lc->supported & FW_PORT_CAP_ANEG)) { @@ -1277,8 +1277,8 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port) memset(&c, 0, sizeof(c)); c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + FW_CMD_EXEC_F | FW_PORT_CMD_PORTID_V(port)); + c.action_to_len16 = htonl(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); @@ -3415,9 +3415,9 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, memset(&c, 0, sizeof(c)); c.op_to_vfn = htonl(FW_CMD_OP_V(FW_VI_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | FW_CMD_EXEC_F | - FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c)); - c.portid_pkd = FW_VI_CMD_PORTID(port); + FW_VI_CMD_PFN_V(pf) | FW_VI_CMD_VFN_V(vf)); + c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC_F | FW_LEN16(c)); + c.portid_pkd = FW_VI_CMD_PORTID_V(port); c.nmac = nmac - 1; ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); @@ -3438,8 +3438,8 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, } } if (rss_size) - *rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd)); - return FW_VI_CMD_VIID_GET(ntohs(c.type_viid)); + *rss_size = FW_VI_CMD_RSSSIZE_G(ntohs(c.rsssize_pkd)); + return FW_VI_CMD_VIID_G(ntohs(c.type_viid)); } /** @@ -3466,23 +3466,23 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, if (mtu < 0) mtu = FW_RXMODE_MTU_NO_CHG; if (promisc < 0) - promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK; + promisc = FW_VI_RXMODE_CMD_PROMISCEN_M; if (all_multi < 0) - all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK; + all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_M; if (bcast < 0) - bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK; + bcast = FW_VI_RXMODE_CMD_BROADCASTEN_M; if (vlanex < 0) - vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK; + vlanex = FW_VI_RXMODE_CMD_VLANEXEN_M; memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_VI_RXMODE_CMD_VIID(viid)); + FW_CMD_WRITE_F | FW_VI_RXMODE_CMD_VIID_V(viid)); c.retval_len16 = htonl(FW_LEN16(c)); - c.mtu_to_vlanexen = htonl(FW_VI_RXMODE_CMD_MTU(mtu) | - FW_VI_RXMODE_CMD_PROMISCEN(promisc) | - FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | - FW_VI_RXMODE_CMD_BROADCASTEN(bcast) | - FW_VI_RXMODE_CMD_VLANEXEN(vlanex)); + c.mtu_to_vlanexen = htonl(FW_VI_RXMODE_CMD_MTU_V(mtu) | + FW_VI_RXMODE_CMD_PROMISCEN_V(promisc) | + FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) | + FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) | + FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex)); return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); } @@ -3525,13 +3525,13 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | (free ? FW_CMD_EXEC_F : 0) | - FW_VI_MAC_CMD_VIID(viid)); - c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) | + FW_VI_MAC_CMD_VIID_V(viid)); + c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS_V(free) | FW_CMD_LEN16_V((naddr + 2) / 2)); for (i = 0, p = c.u.exact; i < naddr; i++, p++) { - p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | - FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); + p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID_F | + FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_ADD_MAC)); memcpy(p->macaddr, addr[i], sizeof(p->macaddr)); } @@ -3540,7 +3540,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, return ret; for (i = 0, p = c.u.exact; i < naddr; i++, p++) { - u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); + u16 index = FW_VI_MAC_CMD_IDX_G(ntohs(p->valid_to_idx)); if (idx) idx[i] = index >= max_naddr ? 0xffff : index; @@ -3587,16 +3587,16 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_VI_MAC_CMD_VIID(viid)); + FW_CMD_WRITE_F | FW_VI_MAC_CMD_VIID_V(viid)); c.freemacs_to_len16 = htonl(FW_CMD_LEN16_V(1)); - p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | - FW_VI_MAC_CMD_SMAC_RESULT(mode) | - FW_VI_MAC_CMD_IDX(idx)); + p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID_F | + FW_VI_MAC_CMD_SMAC_RESULT_V(mode) | + FW_VI_MAC_CMD_IDX_V(idx)); memcpy(p->macaddr, addr, sizeof(p->macaddr)); ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); if (ret == 0) { - ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); + ret = FW_VI_MAC_CMD_IDX_G(ntohs(p->valid_to_idx)); if (ret >= max_mac_addr) ret = -ENOMEM; } @@ -3621,9 +3621,9 @@ int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | - FW_CMD_WRITE_F | FW_VI_ENABLE_CMD_VIID(viid)); - c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN | - FW_VI_MAC_CMD_HASHUNIEN(ucast) | + FW_CMD_WRITE_F | FW_VI_ENABLE_CMD_VIID_V(viid)); + c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN_F | + FW_VI_MAC_CMD_HASHUNIEN_V(ucast) | FW_CMD_LEN16_V(1)); c.u.hash.hashvec = cpu_to_be64(vec); return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); @@ -3648,11 +3648,11 @@ int t4_enable_vi_params(struct adapter *adap, unsigned int mbox, memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID_V(viid)); - c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) | - FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c) | - FW_VI_ENABLE_CMD_DCB_INFO(dcb_en)); + c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN_V(rx_en) | + FW_VI_ENABLE_CMD_EEN_V(tx_en) | FW_LEN16(c) | + FW_VI_ENABLE_CMD_DCB_INFO_V(dcb_en)); return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); } @@ -3688,8 +3688,8 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | - FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID(viid)); - c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); + FW_CMD_EXEC_F | FW_VI_ENABLE_CMD_VIID_V(viid)); + c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED_F | FW_LEN16(c)); c.blinkdur = htons(nblinks); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -3811,25 +3811,25 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) if (opcode == FW_PORT_CMD) { /* link/module state change message */ int speed = 0, fc = 0; const struct fw_port_cmd *p = (void *)rpl; - int chan = FW_PORT_CMD_PORTID_GET(ntohl(p->op_to_portid)); + int chan = FW_PORT_CMD_PORTID_G(ntohl(p->op_to_portid)); int port = adap->chan_map[chan]; struct port_info *pi = adap2pinfo(adap, port); struct link_config *lc = &pi->link_cfg; u32 stat = ntohl(p->u.info.lstatus_to_modtype); - int link_ok = (stat & FW_PORT_CMD_LSTATUS) != 0; - u32 mod = FW_PORT_CMD_MODTYPE_GET(stat); + int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0; + u32 mod = FW_PORT_CMD_MODTYPE_G(stat); - if (stat & FW_PORT_CMD_RXPAUSE) + if (stat & FW_PORT_CMD_RXPAUSE_F) fc |= PAUSE_RX; - if (stat & FW_PORT_CMD_TXPAUSE) + if (stat & FW_PORT_CMD_TXPAUSE_F) fc |= PAUSE_TX; - if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) speed = 100; - else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) speed = 1000; - else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) speed = 10000; - else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) speed = 40000; if (link_ok != lc->link_ok || speed != lc->speed || @@ -4124,9 +4124,9 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) c.op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | FW_CMD_READ_F | - FW_PORT_CMD_PORTID(j)); + FW_PORT_CMD_PORTID_V(j)); c.action_to_len16 = htonl( - FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | + FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | FW_LEN16(c)); ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); if (ret) @@ -4144,9 +4144,9 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf) adap->port[i]->dev_port = j; ret = ntohl(c.u.info.lstatus_to_modtype); - p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ? - FW_PORT_CMD_MDIOADDR_GET(ret) : -1; - p->port_type = FW_PORT_CMD_PTYPE_GET(ret); + p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ? + FW_PORT_CMD_MDIOADDR_G(ret) : -1; + p->port_type = FW_PORT_CMD_PTYPE_G(ret); p->mod_type = FW_PORT_MOD_TYPE_NA; rvc.op_to_viid = htonl(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) | diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 92a0df5be28f..4c8eb875fdea 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -1834,8 +1834,13 @@ struct fw_eq_ofld_cmd { #define FW_VIID_PFN_M 0x7 #define FW_VIID_PFN_G(x) (((x) >> FW_VIID_PFN_S) & FW_VIID_PFN_M) -#define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1) -#define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F) +#define FW_VIID_VIVLD_S 7 +#define FW_VIID_VIVLD_M 0x1 +#define FW_VIID_VIVLD_G(x) (((x) >> FW_VIID_VIVLD_S) & FW_VIID_VIVLD_M) + +#define FW_VIID_VIN_S 0 +#define FW_VIID_VIN_M 0x7F +#define FW_VIID_VIN_G(x) (((x) >> FW_VIID_VIN_S) & FW_VIID_VIN_M) struct fw_vi_cmd { __be32 op_to_vfn; @@ -1855,15 +1860,35 @@ struct fw_vi_cmd { __be64 r10; }; -#define FW_VI_CMD_PFN(x) ((x) << 8) -#define FW_VI_CMD_VFN(x) ((x) << 0) -#define FW_VI_CMD_ALLOC (1U << 31) -#define FW_VI_CMD_FREE (1U << 30) -#define FW_VI_CMD_VIID(x) ((x) << 0) -#define FW_VI_CMD_VIID_GET(x) ((x) & 0xfff) -#define FW_VI_CMD_PORTID(x) ((x) << 4) -#define FW_VI_CMD_PORTID_GET(x) (((x) >> 4) & 0xf) -#define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff) +#define FW_VI_CMD_PFN_S 8 +#define FW_VI_CMD_PFN_V(x) ((x) << FW_VI_CMD_PFN_S) + +#define FW_VI_CMD_VFN_S 0 +#define FW_VI_CMD_VFN_V(x) ((x) << FW_VI_CMD_VFN_S) + +#define FW_VI_CMD_ALLOC_S 31 +#define FW_VI_CMD_ALLOC_V(x) ((x) << FW_VI_CMD_ALLOC_S) +#define FW_VI_CMD_ALLOC_F FW_VI_CMD_ALLOC_V(1U) + +#define FW_VI_CMD_FREE_S 30 +#define FW_VI_CMD_FREE_V(x) ((x) << FW_VI_CMD_FREE_S) +#define FW_VI_CMD_FREE_F FW_VI_CMD_FREE_V(1U) + +#define FW_VI_CMD_VIID_S 0 +#define FW_VI_CMD_VIID_M 0xfff +#define FW_VI_CMD_VIID_V(x) ((x) << FW_VI_CMD_VIID_S) +#define FW_VI_CMD_VIID_G(x) (((x) >> FW_VI_CMD_VIID_S) & FW_VI_CMD_VIID_M) + +#define FW_VI_CMD_PORTID_S 4 +#define FW_VI_CMD_PORTID_M 0xf +#define FW_VI_CMD_PORTID_V(x) ((x) << FW_VI_CMD_PORTID_S) +#define FW_VI_CMD_PORTID_G(x) \ + (((x) >> FW_VI_CMD_PORTID_S) & FW_VI_CMD_PORTID_M) + +#define FW_VI_CMD_RSSSIZE_S 0 +#define FW_VI_CMD_RSSSIZE_M 0x7ff +#define FW_VI_CMD_RSSSIZE_G(x) \ + (((x) >> FW_VI_CMD_RSSSIZE_S) & FW_VI_CMD_RSSSIZE_M) /* Special VI_MAC command index ids */ #define FW_VI_MAC_ADD_MAC 0x3FF @@ -1899,16 +1924,37 @@ struct fw_vi_mac_cmd { } u; }; -#define FW_VI_MAC_CMD_VIID(x) ((x) << 0) -#define FW_VI_MAC_CMD_FREEMACS(x) ((x) << 31) -#define FW_VI_MAC_CMD_HASHVECEN (1U << 23) -#define FW_VI_MAC_CMD_HASHUNIEN(x) ((x) << 22) -#define FW_VI_MAC_CMD_VALID (1U << 15) -#define FW_VI_MAC_CMD_PRIO(x) ((x) << 12) -#define FW_VI_MAC_CMD_SMAC_RESULT(x) ((x) << 10) -#define FW_VI_MAC_CMD_SMAC_RESULT_GET(x) (((x) >> 10) & 0x3) -#define FW_VI_MAC_CMD_IDX(x) ((x) << 0) -#define FW_VI_MAC_CMD_IDX_GET(x) (((x) >> 0) & 0x3ff) +#define FW_VI_MAC_CMD_VIID_S 0 +#define FW_VI_MAC_CMD_VIID_V(x) ((x) << FW_VI_MAC_CMD_VIID_S) + +#define FW_VI_MAC_CMD_FREEMACS_S 31 +#define FW_VI_MAC_CMD_FREEMACS_V(x) ((x) << FW_VI_MAC_CMD_FREEMACS_S) + +#define FW_VI_MAC_CMD_HASHVECEN_S 23 +#define FW_VI_MAC_CMD_HASHVECEN_V(x) ((x) << FW_VI_MAC_CMD_HASHVECEN_S) +#define FW_VI_MAC_CMD_HASHVECEN_F FW_VI_MAC_CMD_HASHVECEN_V(1U) + +#define FW_VI_MAC_CMD_HASHUNIEN_S 22 +#define FW_VI_MAC_CMD_HASHUNIEN_V(x) ((x) << FW_VI_MAC_CMD_HASHUNIEN_S) + +#define FW_VI_MAC_CMD_VALID_S 15 +#define FW_VI_MAC_CMD_VALID_V(x) ((x) << FW_VI_MAC_CMD_VALID_S) +#define FW_VI_MAC_CMD_VALID_F FW_VI_MAC_CMD_VALID_V(1U) + +#define FW_VI_MAC_CMD_PRIO_S 12 +#define FW_VI_MAC_CMD_PRIO_V(x) ((x) << FW_VI_MAC_CMD_PRIO_S) + +#define FW_VI_MAC_CMD_SMAC_RESULT_S 10 +#define FW_VI_MAC_CMD_SMAC_RESULT_M 0x3 +#define FW_VI_MAC_CMD_SMAC_RESULT_V(x) ((x) << FW_VI_MAC_CMD_SMAC_RESULT_S) +#define FW_VI_MAC_CMD_SMAC_RESULT_G(x) \ + (((x) >> FW_VI_MAC_CMD_SMAC_RESULT_S) & FW_VI_MAC_CMD_SMAC_RESULT_M) + +#define FW_VI_MAC_CMD_IDX_S 0 +#define FW_VI_MAC_CMD_IDX_M 0x3ff +#define FW_VI_MAC_CMD_IDX_V(x) ((x) << FW_VI_MAC_CMD_IDX_S) +#define FW_VI_MAC_CMD_IDX_G(x) \ + (((x) >> FW_VI_MAC_CMD_IDX_S) & FW_VI_MAC_CMD_IDX_M) #define FW_RXMODE_MTU_NO_CHG 65535 @@ -1919,17 +1965,30 @@ struct fw_vi_rxmode_cmd { __be32 r4_lo; }; -#define FW_VI_RXMODE_CMD_VIID(x) ((x) << 0) -#define FW_VI_RXMODE_CMD_MTU_MASK 0xffff -#define FW_VI_RXMODE_CMD_MTU(x) ((x) << 16) -#define FW_VI_RXMODE_CMD_PROMISCEN_MASK 0x3 -#define FW_VI_RXMODE_CMD_PROMISCEN(x) ((x) << 14) -#define FW_VI_RXMODE_CMD_ALLMULTIEN_MASK 0x3 -#define FW_VI_RXMODE_CMD_ALLMULTIEN(x) ((x) << 12) -#define FW_VI_RXMODE_CMD_BROADCASTEN_MASK 0x3 -#define FW_VI_RXMODE_CMD_BROADCASTEN(x) ((x) << 10) -#define FW_VI_RXMODE_CMD_VLANEXEN_MASK 0x3 -#define FW_VI_RXMODE_CMD_VLANEXEN(x) ((x) << 8) +#define FW_VI_RXMODE_CMD_VIID_S 0 +#define FW_VI_RXMODE_CMD_VIID_V(x) ((x) << FW_VI_RXMODE_CMD_VIID_S) + +#define FW_VI_RXMODE_CMD_MTU_S 16 +#define FW_VI_RXMODE_CMD_MTU_M 0xffff +#define FW_VI_RXMODE_CMD_MTU_V(x) ((x) << FW_VI_RXMODE_CMD_MTU_S) + +#define FW_VI_RXMODE_CMD_PROMISCEN_S 14 +#define FW_VI_RXMODE_CMD_PROMISCEN_M 0x3 +#define FW_VI_RXMODE_CMD_PROMISCEN_V(x) ((x) << FW_VI_RXMODE_CMD_PROMISCEN_S) + +#define FW_VI_RXMODE_CMD_ALLMULTIEN_S 12 +#define FW_VI_RXMODE_CMD_ALLMULTIEN_M 0x3 +#define FW_VI_RXMODE_CMD_ALLMULTIEN_V(x) \ + ((x) << FW_VI_RXMODE_CMD_ALLMULTIEN_S) + +#define FW_VI_RXMODE_CMD_BROADCASTEN_S 10 +#define FW_VI_RXMODE_CMD_BROADCASTEN_M 0x3 +#define FW_VI_RXMODE_CMD_BROADCASTEN_V(x) \ + ((x) << FW_VI_RXMODE_CMD_BROADCASTEN_S) + +#define FW_VI_RXMODE_CMD_VLANEXEN_S 8 +#define FW_VI_RXMODE_CMD_VLANEXEN_M 0x3 +#define FW_VI_RXMODE_CMD_VLANEXEN_V(x) ((x) << FW_VI_RXMODE_CMD_VLANEXEN_S) struct fw_vi_enable_cmd { __be32 op_to_viid; @@ -1939,11 +1998,21 @@ struct fw_vi_enable_cmd { __be32 r4; }; -#define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0) -#define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31) -#define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30) -#define FW_VI_ENABLE_CMD_DCB_INFO(x) ((x) << 28) -#define FW_VI_ENABLE_CMD_LED (1U << 29) +#define FW_VI_ENABLE_CMD_VIID_S 0 +#define FW_VI_ENABLE_CMD_VIID_V(x) ((x) << FW_VI_ENABLE_CMD_VIID_S) + +#define FW_VI_ENABLE_CMD_IEN_S 31 +#define FW_VI_ENABLE_CMD_IEN_V(x) ((x) << FW_VI_ENABLE_CMD_IEN_S) + +#define FW_VI_ENABLE_CMD_EEN_S 30 +#define FW_VI_ENABLE_CMD_EEN_V(x) ((x) << FW_VI_ENABLE_CMD_EEN_S) + +#define FW_VI_ENABLE_CMD_LED_S 29 +#define FW_VI_ENABLE_CMD_LED_V(x) ((x) << FW_VI_ENABLE_CMD_LED_S) +#define FW_VI_ENABLE_CMD_LED_F FW_VI_ENABLE_CMD_LED_V(1U) + +#define FW_VI_ENABLE_CMD_DCB_INFO_S 28 +#define FW_VI_ENABLE_CMD_DCB_INFO_V(x) ((x) << FW_VI_ENABLE_CMD_DCB_INFO_S) /* VI VF stats offset definitions */ #define VI_VF_NUM_STATS 16 @@ -2043,9 +2112,14 @@ struct fw_vi_stats_cmd { } u; }; -#define FW_VI_STATS_CMD_VIID(x) ((x) << 0) -#define FW_VI_STATS_CMD_NSTATS(x) ((x) << 12) -#define FW_VI_STATS_CMD_IX(x) ((x) << 0) +#define FW_VI_STATS_CMD_VIID_S 0 +#define FW_VI_STATS_CMD_VIID_V(x) ((x) << FW_VI_STATS_CMD_VIID_S) + +#define FW_VI_STATS_CMD_NSTATS_S 12 +#define FW_VI_STATS_CMD_NSTATS_V(x) ((x) << FW_VI_STATS_CMD_NSTATS_S) + +#define FW_VI_STATS_CMD_IX_S 0 +#define FW_VI_STATS_CMD_IX_V(x) ((x) << FW_VI_STATS_CMD_IX_S) struct fw_acl_mac_cmd { __be32 op_to_vfn; @@ -2062,9 +2136,14 @@ struct fw_acl_mac_cmd { u8 macaddr3[6]; }; -#define FW_ACL_MAC_CMD_PFN(x) ((x) << 8) -#define FW_ACL_MAC_CMD_VFN(x) ((x) << 0) -#define FW_ACL_MAC_CMD_EN(x) ((x) << 31) +#define FW_ACL_MAC_CMD_PFN_S 8 +#define FW_ACL_MAC_CMD_PFN_V(x) ((x) << FW_ACL_MAC_CMD_PFN_S) + +#define FW_ACL_MAC_CMD_VFN_S 0 +#define FW_ACL_MAC_CMD_VFN_V(x) ((x) << FW_ACL_MAC_CMD_VFN_S) + +#define FW_ACL_MAC_CMD_EN_S 31 +#define FW_ACL_MAC_CMD_EN_V(x) ((x) << FW_ACL_MAC_CMD_EN_S) struct fw_acl_vlan_cmd { __be32 op_to_vfn; @@ -2075,11 +2154,20 @@ struct fw_acl_vlan_cmd { __be16 vlanid[16]; }; -#define FW_ACL_VLAN_CMD_PFN(x) ((x) << 8) -#define FW_ACL_VLAN_CMD_VFN(x) ((x) << 0) -#define FW_ACL_VLAN_CMD_EN(x) ((x) << 31) -#define FW_ACL_VLAN_CMD_DROPNOVLAN(x) ((x) << 7) -#define FW_ACL_VLAN_CMD_FM(x) ((x) << 6) +#define FW_ACL_VLAN_CMD_PFN_S 8 +#define FW_ACL_VLAN_CMD_PFN_V(x) ((x) << FW_ACL_VLAN_CMD_PFN_S) + +#define FW_ACL_VLAN_CMD_VFN_S 0 +#define FW_ACL_VLAN_CMD_VFN_V(x) ((x) << FW_ACL_VLAN_CMD_VFN_S) + +#define FW_ACL_VLAN_CMD_EN_S 31 +#define FW_ACL_VLAN_CMD_EN_V(x) ((x) << FW_ACL_VLAN_CMD_EN_S) + +#define FW_ACL_VLAN_CMD_DROPNOVLAN_S 7 +#define FW_ACL_VLAN_CMD_DROPNOVLAN_V(x) ((x) << FW_ACL_VLAN_CMD_DROPNOVLAN_S) + +#define FW_ACL_VLAN_CMD_FM_S 6 +#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S) enum fw_port_cap { FW_PORT_CAP_SPEED_100M = 0x0001, @@ -2101,13 +2189,14 @@ enum fw_port_cap { }; enum fw_port_mdi { - FW_PORT_MDI_UNCHANGED, - FW_PORT_MDI_AUTO, - FW_PORT_MDI_F_STRAIGHT, - FW_PORT_MDI_F_CROSSOVER + FW_PORT_CAP_MDI_UNCHANGED, + FW_PORT_CAP_MDI_AUTO, + FW_PORT_CAP_MDI_F_STRAIGHT, + FW_PORT_CAP_MDI_F_CROSSOVER }; -#define FW_PORT_MDI(x) ((x) << 9) +#define FW_PORT_CAP_MDI_S 9 +#define FW_PORT_CAP_MDI_V(x) ((x) << FW_PORT_CAP_MDI_S) enum fw_port_action { FW_PORT_ACTION_L1_CFG = 0x0001, @@ -2267,52 +2356,105 @@ struct fw_port_cmd { } u; }; -#define FW_PORT_CMD_READ (1U << 22) - -#define FW_PORT_CMD_PORTID(x) ((x) << 0) -#define FW_PORT_CMD_PORTID_GET(x) (((x) >> 0) & 0xf) - -#define FW_PORT_CMD_ACTION(x) ((x) << 16) -#define FW_PORT_CMD_ACTION_GET(x) (((x) >> 16) & 0xffff) - -#define FW_PORT_CMD_CTLBF(x) ((x) << 10) -#define FW_PORT_CMD_OVLAN3(x) ((x) << 7) -#define FW_PORT_CMD_OVLAN2(x) ((x) << 6) -#define FW_PORT_CMD_OVLAN1(x) ((x) << 5) -#define FW_PORT_CMD_OVLAN0(x) ((x) << 4) -#define FW_PORT_CMD_IVLAN0(x) ((x) << 3) - -#define FW_PORT_CMD_TXIPG(x) ((x) << 19) - -#define FW_PORT_CMD_LSTATUS (1U << 31) -#define FW_PORT_CMD_LSTATUS_GET(x) (((x) >> 31) & 0x1) -#define FW_PORT_CMD_LSPEED(x) ((x) << 24) -#define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f) -#define FW_PORT_CMD_TXPAUSE (1U << 23) -#define FW_PORT_CMD_RXPAUSE (1U << 22) -#define FW_PORT_CMD_MDIOCAP (1U << 21) -#define FW_PORT_CMD_MDIOADDR_GET(x) (((x) >> 16) & 0x1f) -#define FW_PORT_CMD_LPTXPAUSE (1U << 15) -#define FW_PORT_CMD_LPRXPAUSE (1U << 14) -#define FW_PORT_CMD_PTYPE_MASK 0x1f -#define FW_PORT_CMD_PTYPE_GET(x) (((x) >> 8) & FW_PORT_CMD_PTYPE_MASK) -#define FW_PORT_CMD_MODTYPE_MASK 0x1f -#define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK) - -#define FW_PORT_CMD_DCBXDIS (1U << 7) -#define FW_PORT_CMD_APPLY (1U << 7) -#define FW_PORT_CMD_ALL_SYNCD (1U << 7) -#define FW_PORT_CMD_DCB_VERSION_GET(x) (((x) >> 8) & 0xf) - -#define FW_PORT_CMD_PPPEN(x) ((x) << 31) -#define FW_PORT_CMD_TPSRC(x) ((x) << 28) -#define FW_PORT_CMD_NCSISRC(x) ((x) << 24) - -#define FW_PORT_CMD_CH0(x) ((x) << 20) -#define FW_PORT_CMD_CH1(x) ((x) << 16) -#define FW_PORT_CMD_CH2(x) ((x) << 12) -#define FW_PORT_CMD_CH3(x) ((x) << 8) -#define FW_PORT_CMD_NCSICH(x) ((x) << 4) +#define FW_PORT_CMD_READ_S 22 +#define FW_PORT_CMD_READ_V(x) ((x) << FW_PORT_CMD_READ_S) +#define FW_PORT_CMD_READ_F FW_PORT_CMD_READ_V(1U) + +#define FW_PORT_CMD_PORTID_S 0 +#define FW_PORT_CMD_PORTID_M 0xf +#define FW_PORT_CMD_PORTID_V(x) ((x) << FW_PORT_CMD_PORTID_S) +#define FW_PORT_CMD_PORTID_G(x) \ + (((x) >> FW_PORT_CMD_PORTID_S) & FW_PORT_CMD_PORTID_M) + +#define FW_PORT_CMD_ACTION_S 16 +#define FW_PORT_CMD_ACTION_M 0xffff +#define FW_PORT_CMD_ACTION_V(x) ((x) << FW_PORT_CMD_ACTION_S) +#define FW_PORT_CMD_ACTION_G(x) \ + (((x) >> FW_PORT_CMD_ACTION_S) & FW_PORT_CMD_ACTION_M) + +#define FW_PORT_CMD_OVLAN3_S 7 +#define FW_PORT_CMD_OVLAN3_V(x) ((x) << FW_PORT_CMD_OVLAN3_S) + +#define FW_PORT_CMD_OVLAN2_S 6 +#define FW_PORT_CMD_OVLAN2_V(x) ((x) << FW_PORT_CMD_OVLAN2_S) + +#define FW_PORT_CMD_OVLAN1_S 5 +#define FW_PORT_CMD_OVLAN1_V(x) ((x) << FW_PORT_CMD_OVLAN1_S) + +#define FW_PORT_CMD_OVLAN0_S 4 +#define FW_PORT_CMD_OVLAN0_V(x) ((x) << FW_PORT_CMD_OVLAN0_S) + +#define FW_PORT_CMD_IVLAN0_S 3 +#define FW_PORT_CMD_IVLAN0_V(x) ((x) << FW_PORT_CMD_IVLAN0_S) + +#define FW_PORT_CMD_TXIPG_S 3 +#define FW_PORT_CMD_TXIPG_V(x) ((x) << FW_PORT_CMD_TXIPG_S) + +#define FW_PORT_CMD_LSTATUS_S 31 +#define FW_PORT_CMD_LSTATUS_M 0x1 +#define FW_PORT_CMD_LSTATUS_V(x) ((x) << FW_PORT_CMD_LSTATUS_S) +#define FW_PORT_CMD_LSTATUS_G(x) \ + (((x) >> FW_PORT_CMD_LSTATUS_S) & FW_PORT_CMD_LSTATUS_M) +#define FW_PORT_CMD_LSTATUS_F FW_PORT_CMD_LSTATUS_V(1U) + +#define FW_PORT_CMD_LSPEED_S 24 +#define FW_PORT_CMD_LSPEED_M 0x3f +#define FW_PORT_CMD_LSPEED_V(x) ((x) << FW_PORT_CMD_LSPEED_S) +#define FW_PORT_CMD_LSPEED_G(x) \ + (((x) >> FW_PORT_CMD_LSPEED_S) & FW_PORT_CMD_LSPEED_M) + +#define FW_PORT_CMD_TXPAUSE_S 23 +#define FW_PORT_CMD_TXPAUSE_V(x) ((x) << FW_PORT_CMD_TXPAUSE_S) +#define FW_PORT_CMD_TXPAUSE_F FW_PORT_CMD_TXPAUSE_V(1U) + +#define FW_PORT_CMD_RXPAUSE_S 22 +#define FW_PORT_CMD_RXPAUSE_V(x) ((x) << FW_PORT_CMD_RXPAUSE_S) +#define FW_PORT_CMD_RXPAUSE_F FW_PORT_CMD_RXPAUSE_V(1U) + +#define FW_PORT_CMD_MDIOCAP_S 21 +#define FW_PORT_CMD_MDIOCAP_V(x) ((x) << FW_PORT_CMD_MDIOCAP_S) +#define FW_PORT_CMD_MDIOCAP_F FW_PORT_CMD_MDIOCAP_V(1U) + +#define FW_PORT_CMD_MDIOADDR_S 16 +#define FW_PORT_CMD_MDIOADDR_M 0x1f +#define FW_PORT_CMD_MDIOADDR_G(x) \ + (((x) >> FW_PORT_CMD_MDIOADDR_S) & FW_PORT_CMD_MDIOADDR_M) + +#define FW_PORT_CMD_LPTXPAUSE_S 15 +#define FW_PORT_CMD_LPTXPAUSE_V(x) ((x) << FW_PORT_CMD_LPTXPAUSE_S) +#define FW_PORT_CMD_LPTXPAUSE_F FW_PORT_CMD_LPTXPAUSE_V(1U) + +#define FW_PORT_CMD_LPRXPAUSE_S 14 +#define FW_PORT_CMD_LPRXPAUSE_V(x) ((x) << FW_PORT_CMD_LPRXPAUSE_S) +#define FW_PORT_CMD_LPRXPAUSE_F FW_PORT_CMD_LPRXPAUSE_V(1U) + +#define FW_PORT_CMD_PTYPE_S 8 +#define FW_PORT_CMD_PTYPE_M 0x1f +#define FW_PORT_CMD_PTYPE_G(x) \ + (((x) >> FW_PORT_CMD_PTYPE_S) & FW_PORT_CMD_PTYPE_M) + +#define FW_PORT_CMD_MODTYPE_S 0 +#define FW_PORT_CMD_MODTYPE_M 0x1f +#define FW_PORT_CMD_MODTYPE_V(x) ((x) << FW_PORT_CMD_MODTYPE_S) +#define FW_PORT_CMD_MODTYPE_G(x) \ + (((x) >> FW_PORT_CMD_MODTYPE_S) & FW_PORT_CMD_MODTYPE_M) + +#define FW_PORT_CMD_DCBXDIS_S 7 +#define FW_PORT_CMD_DCBXDIS_V(x) ((x) << FW_PORT_CMD_DCBXDIS_S) +#define FW_PORT_CMD_DCBXDIS_F FW_PORT_CMD_DCBXDIS_V(1U) + +#define FW_PORT_CMD_APPLY_S 7 +#define FW_PORT_CMD_APPLY_V(x) ((x) << FW_PORT_CMD_APPLY_S) +#define FW_PORT_CMD_APPLY_F FW_PORT_CMD_APPLY_V(1U) + +#define FW_PORT_CMD_ALL_SYNCD_S 7 +#define FW_PORT_CMD_ALL_SYNCD_V(x) ((x) << FW_PORT_CMD_ALL_SYNCD_S) +#define FW_PORT_CMD_ALL_SYNCD_F FW_PORT_CMD_ALL_SYNCD_V(1U) + +#define FW_PORT_CMD_DCB_VERSION_S 12 +#define FW_PORT_CMD_DCB_VERSION_M 0x7 +#define FW_PORT_CMD_DCB_VERSION_G(x) \ + (((x) >> FW_PORT_CMD_DCB_VERSION_S) & FW_PORT_CMD_DCB_VERSION_M) enum fw_port_type { FW_PORT_TYPE_FIBER_XFI, @@ -2331,7 +2473,7 @@ enum fw_port_type { FW_PORT_TYPE_QSFP, FW_PORT_TYPE_BP40_BA, - FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK + FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_M }; enum fw_port_module_type { @@ -2342,11 +2484,11 @@ enum fw_port_module_type { FW_PORT_MOD_TYPE_TWINAX_PASSIVE, FW_PORT_MOD_TYPE_TWINAX_ACTIVE, FW_PORT_MOD_TYPE_LRM, - FW_PORT_MOD_TYPE_ERROR = FW_PORT_CMD_MODTYPE_MASK - 3, - FW_PORT_MOD_TYPE_UNKNOWN = FW_PORT_CMD_MODTYPE_MASK - 2, - FW_PORT_MOD_TYPE_NOTSUPPORTED = FW_PORT_CMD_MODTYPE_MASK - 1, + FW_PORT_MOD_TYPE_ERROR = FW_PORT_CMD_MODTYPE_M - 3, + FW_PORT_MOD_TYPE_UNKNOWN = FW_PORT_CMD_MODTYPE_M - 2, + FW_PORT_MOD_TYPE_NOTSUPPORTED = FW_PORT_CMD_MODTYPE_M - 1, - FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK + FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_M }; enum fw_port_mod_sub_type { diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 5d3bd8db7ea6..960d35c6c370 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -291,13 +291,13 @@ int t4vf_port_init(struct adapter *adapter, int pidx) FW_CMD_REQUEST_F | FW_CMD_READ_F); vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd)); - vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(pi->viid)); + vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(pi->viid)); v = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl); if (v) return v; - BUG_ON(pi->port_id != FW_VI_CMD_PORTID_GET(vi_rpl.portid_pkd)); - pi->rss_size = FW_VI_CMD_RSSSIZE_GET(be16_to_cpu(vi_rpl.rsssize_pkd)); + BUG_ON(pi->port_id != FW_VI_CMD_PORTID_G(vi_rpl.portid_pkd)); + pi->rss_size = FW_VI_CMD_RSSSIZE_G(be16_to_cpu(vi_rpl.rsssize_pkd)); t4_os_set_hw_addr(adapter, pidx, vi_rpl.mac); /* @@ -311,9 +311,9 @@ int t4vf_port_init(struct adapter *adapter, int pidx) port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | FW_CMD_READ_F | - FW_PORT_CMD_PORTID(pi->port_id)); + FW_PORT_CMD_PORTID_V(pi->port_id)); port_cmd.action_to_len16 = - cpu_to_be32(FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | + cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | FW_LEN16(port_cmd)); v = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl); if (v) @@ -897,13 +897,13 @@ int t4vf_alloc_vi(struct adapter *adapter, int port_id) FW_CMD_WRITE_F | FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) | - FW_VI_CMD_ALLOC); - cmd.portid_pkd = FW_VI_CMD_PORTID(port_id); + FW_VI_CMD_ALLOC_F); + cmd.portid_pkd = FW_VI_CMD_PORTID_V(port_id); v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); if (v) return v; - return FW_VI_CMD_VIID_GET(be16_to_cpu(rpl.type_viid)); + return FW_VI_CMD_VIID_G(be16_to_cpu(rpl.type_viid)); } /** @@ -926,8 +926,8 @@ int t4vf_free_vi(struct adapter *adapter, int viid) FW_CMD_REQUEST_F | FW_CMD_EXEC_F); cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) | - FW_VI_CMD_FREE); - cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(viid)); + FW_VI_CMD_FREE_F); + cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(viid)); return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); } @@ -949,9 +949,9 @@ int t4vf_enable_vi(struct adapter *adapter, unsigned int viid, cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_VI_ENABLE_CMD_VIID(viid)); - cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN(rx_en) | - FW_VI_ENABLE_CMD_EEN(tx_en) | + FW_VI_ENABLE_CMD_VIID_V(viid)); + cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN_V(rx_en) | + FW_VI_ENABLE_CMD_EEN_V(tx_en) | FW_LEN16(cmd)); return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); } @@ -973,8 +973,8 @@ int t4vf_identify_port(struct adapter *adapter, unsigned int viid, cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST_F | FW_CMD_EXEC_F | - FW_VI_ENABLE_CMD_VIID(viid)); - cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED | + FW_VI_ENABLE_CMD_VIID_V(viid)); + cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED_F | FW_LEN16(cmd)); cmd.blinkdur = cpu_to_be16(nblinks); return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); @@ -1001,28 +1001,28 @@ int t4vf_set_rxmode(struct adapter *adapter, unsigned int viid, /* convert to FW values */ if (mtu < 0) - mtu = FW_VI_RXMODE_CMD_MTU_MASK; + mtu = FW_VI_RXMODE_CMD_MTU_M; if (promisc < 0) - promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK; + promisc = FW_VI_RXMODE_CMD_PROMISCEN_M; if (all_multi < 0) - all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK; + all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_M; if (bcast < 0) - bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK; + bcast = FW_VI_RXMODE_CMD_BROADCASTEN_M; if (vlanex < 0) - vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK; + vlanex = FW_VI_RXMODE_CMD_VLANEXEN_M; memset(&cmd, 0, sizeof(cmd)); cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_VI_RXMODE_CMD_VIID(viid)); + FW_VI_RXMODE_CMD_VIID_V(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); cmd.mtu_to_vlanexen = - cpu_to_be32(FW_VI_RXMODE_CMD_MTU(mtu) | - FW_VI_RXMODE_CMD_PROMISCEN(promisc) | - FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | - FW_VI_RXMODE_CMD_BROADCASTEN(bcast) | - FW_VI_RXMODE_CMD_VLANEXEN(vlanex)); + cpu_to_be32(FW_VI_RXMODE_CMD_MTU_V(mtu) | + FW_VI_RXMODE_CMD_PROMISCEN_V(promisc) | + FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) | + FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) | + FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex)); return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok); } @@ -1076,15 +1076,15 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, FW_CMD_REQUEST_F | FW_CMD_WRITE_F | (free ? FW_CMD_EXEC_F : 0) | - FW_VI_MAC_CMD_VIID(viid)); + FW_VI_MAC_CMD_VIID_V(viid)); cmd.freemacs_to_len16 = - cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) | + cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(free) | FW_CMD_LEN16_V(len16)); for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) { p->valid_to_idx = cpu_to_be16( - FW_VI_MAC_CMD_VALID | - FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); + FW_VI_MAC_CMD_VALID_F | + FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_ADD_MAC)); memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr)); } @@ -1095,7 +1095,7 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, break; for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) { - u16 index = FW_VI_MAC_CMD_IDX_GET( + u16 index = FW_VI_MAC_CMD_IDX_G( be16_to_cpu(p->valid_to_idx)); if (idx) @@ -1164,16 +1164,16 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid, cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_VI_MAC_CMD_VIID(viid)); + FW_VI_MAC_CMD_VIID_V(viid)); cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); - p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID | - FW_VI_MAC_CMD_IDX(idx)); + p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F | + FW_VI_MAC_CMD_IDX_V(idx)); memcpy(p->macaddr, addr, sizeof(p->macaddr)); ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl); if (ret == 0) { p = &rpl.u.exact[0]; - ret = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx)); + ret = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx)); if (ret >= max_naddr) ret = -ENOMEM; } @@ -1201,9 +1201,9 @@ int t4vf_set_addr_hash(struct adapter *adapter, unsigned int viid, cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_VI_ENABLE_CMD_VIID(viid)); - cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN | - FW_VI_MAC_CMD_HASHUNIEN(ucast) | + FW_VI_ENABLE_CMD_VIID_V(viid)); + cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN_F | + FW_VI_MAC_CMD_HASHUNIEN_V(ucast) | FW_CMD_LEN16_V(len16)); cmd.u.hash.hashvec = cpu_to_be64(vec); return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok); @@ -1241,13 +1241,13 @@ int t4vf_get_port_stats(struct adapter *adapter, int pidx, memset(&cmd, 0, sizeof(cmd)); cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_STATS_CMD) | - FW_VI_STATS_CMD_VIID(pi->viid) | + FW_VI_STATS_CMD_VIID_V(pi->viid) | FW_CMD_REQUEST_F | FW_CMD_READ_F); cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(len16)); cmd.u.ctl.nstats_ix = - cpu_to_be16(FW_VI_STATS_CMD_IX(ix) | - FW_VI_STATS_CMD_NSTATS(nstats)); + cpu_to_be16(FW_VI_STATS_CMD_IX_V(ix) | + FW_VI_STATS_CMD_NSTATS_V(nstats)); ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl); if (ret) return ret; @@ -1359,7 +1359,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) /* * Extract various fields from port status change message. */ - action = FW_PORT_CMD_ACTION_GET( + action = FW_PORT_CMD_ACTION_G( be32_to_cpu(port_cmd->action_to_len16)); if (action != FW_PORT_ACTION_GET_PORT_INFO) { dev_err(adapter->pdev_dev, @@ -1368,24 +1368,24 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) break; } - port_id = FW_PORT_CMD_PORTID_GET( + port_id = FW_PORT_CMD_PORTID_G( be32_to_cpu(port_cmd->op_to_portid)); word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); - link_ok = (word & FW_PORT_CMD_LSTATUS) != 0; + link_ok = (word & FW_PORT_CMD_LSTATUS_F) != 0; speed = 0; fc = 0; - if (word & FW_PORT_CMD_RXPAUSE) + if (word & FW_PORT_CMD_RXPAUSE_F) fc |= PAUSE_RX; - if (word & FW_PORT_CMD_TXPAUSE) + if (word & FW_PORT_CMD_TXPAUSE_F) fc |= PAUSE_TX; - if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) speed = 100; - else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) speed = 1000; - else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) speed = 10000; - else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) speed = 40000; /* diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index 5a514b6bc8ec..829887886898 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -347,24 +347,24 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, void (*cbfn) (struct csio_hw *, struct csio_mb *)) { struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb); - unsigned int lfc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO); + unsigned int lfc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO); CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); cmdp->op_to_portid = htonl(FW_CMD_OP_V(FW_PORT_CMD) | FW_CMD_REQUEST_F | (wr ? FW_CMD_EXEC_F : FW_CMD_READ_F) | - FW_PORT_CMD_PORTID(portid)); + FW_PORT_CMD_PORTID_V(portid)); if (!wr) { cmdp->action_to_len16 = htonl( - FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | + FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); return; } /* Set port */ cmdp->action_to_len16 = htonl( - FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); if (fc & PAUSE_RX) @@ -1407,9 +1407,9 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) if (opcode == FW_PORT_CMD) { pcmd = (struct fw_port_cmd *)cmd; - port_id = FW_PORT_CMD_PORTID_GET( + port_id = FW_PORT_CMD_PORTID_G( ntohl(pcmd->op_to_portid)); - action = FW_PORT_CMD_ACTION_GET( + action = FW_PORT_CMD_ACTION_G( ntohl(pcmd->action_to_len16)); if (action != FW_PORT_ACTION_GET_PORT_INFO) { csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n", @@ -1418,15 +1418,15 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) } link_status = ntohl(pcmd->u.info.lstatus_to_modtype); - mod_type = FW_PORT_CMD_MODTYPE_GET(link_status); + mod_type = FW_PORT_CMD_MODTYPE_G(link_status); hw->pport[port_id].link_status = - FW_PORT_CMD_LSTATUS_GET(link_status); + FW_PORT_CMD_LSTATUS_G(link_status); hw->pport[port_id].link_speed = - FW_PORT_CMD_LSPEED_GET(link_status); + FW_PORT_CMD_LSPEED_G(link_status); csio_info(hw, "Port:%x - LINK %s\n", port_id, - FW_PORT_CMD_LSTATUS_GET(link_status) ? "UP" : "DOWN"); + FW_PORT_CMD_LSTATUS_G(link_status) ? "UP" : "DOWN"); if (mod_type != hw->pport[port_id].mod_type) { hw->pport[port_id].mod_type = mod_type; -- GitLab From b2e1a3f091cddd4e81a64d04a6641c2e860ea266 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 21 Nov 2014 12:52:05 +0530 Subject: [PATCH 5854/9457] RDMA/cxgb4/cxgb4vf/csiostor: Cleanup macros/register defines related to PCIE, RSS and FW This patch cleanups all PCIE, RSS & FW related macros/register defines that are defined in t4fw_api.h and the affected files. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/provider.c | 8 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 56 ++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 68 +++--- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 227 +++++++++++++----- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 16 +- .../net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 52 ++-- drivers/scsi/csiostor/csio_hw.c | 18 +- drivers/scsi/csiostor/csio_init.c | 8 +- drivers/scsi/csiostor/csio_mb.c | 2 +- 10 files changed, 282 insertions(+), 181 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index 72e3b69d1b76..66bd6a2ad83b 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -408,10 +408,10 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, PDBG("%s dev 0x%p\n", __func__, dev); return sprintf(buf, "%u.%u.%u.%u\n", - FW_HDR_FW_VER_MAJOR_GET(c4iw_dev->rdev.lldi.fw_vers), - FW_HDR_FW_VER_MINOR_GET(c4iw_dev->rdev.lldi.fw_vers), - FW_HDR_FW_VER_MICRO_GET(c4iw_dev->rdev.lldi.fw_vers), - FW_HDR_FW_VER_BUILD_GET(c4iw_dev->rdev.lldi.fw_vers)); + FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers), + FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers), + FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers), + FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers)); } static ssize_t show_hca(struct device *dev, struct device_attribute *attr, diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index a2196bc94485..e8b09bbdc226 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -318,10 +318,10 @@ struct adapter_params { #include "t4fw_api.h" #define FW_VERSION(chip) ( \ - FW_HDR_FW_VER_MAJOR_GET(chip##FW_VERSION_MAJOR) | \ - FW_HDR_FW_VER_MINOR_GET(chip##FW_VERSION_MINOR) | \ - FW_HDR_FW_VER_MICRO_GET(chip##FW_VERSION_MICRO) | \ - FW_HDR_FW_VER_BUILD_GET(chip##FW_VERSION_BUILD)) + FW_HDR_FW_VER_MAJOR_G(chip##FW_VERSION_MAJOR) | \ + FW_HDR_FW_VER_MINOR_G(chip##FW_VERSION_MINOR) | \ + FW_HDR_FW_VER_MICRO_G(chip##FW_VERSION_MICRO) | \ + FW_HDR_FW_VER_BUILD_G(chip##FW_VERSION_BUILD)) #define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf) struct fw_info { diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 4c663cc106f1..a576da1eedf4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -1616,14 +1616,14 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) if (adapter->params.fw_vers) snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u.%u.%u, TP %u.%u.%u.%u", - FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers), - FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers), - FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers), - FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers), - FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers), - FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers), - FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers), - FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers)); + FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers), + FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers), + FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers), + FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers), + FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers), + FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers), + FW_HDR_FW_VER_MICRO_G(adapter->params.tp_vers), + FW_HDR_FW_VER_BUILD_G(adapter->params.tp_vers)); } static void get_strings(struct net_device *dev, u32 stringset, u8 *data) @@ -2935,7 +2935,7 @@ static int set_flash(struct net_device *netdev, struct ethtool_flash *ef) int ret; const struct firmware *fw; struct adapter *adap = netdev2adap(netdev); - unsigned int mbox = FW_PCIE_FW_MASTER_MASK + 1; + unsigned int mbox = PCIE_FW_MASTER_M + 1; ef->data[sizeof(ef->data) - 1] = '\0'; ret = request_firmware(&fw, ef->data, adap->pdev_dev); @@ -3046,45 +3046,45 @@ static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, info->data = 0; switch (info->flow_type) { case TCP_V4_FLOW: - if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) + if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; - else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; case UDP_V4_FLOW: - if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) && - (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) + if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) && + (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) info->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; - else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; case SCTP_V4_FLOW: case AH_ESP_V4_FLOW: case IPV4_FLOW: - if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) + if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; case TCP_V6_FLOW: - if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) + if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; - else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; case UDP_V6_FLOW: - if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) && - (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) + if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) && + (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) info->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; - else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; case SCTP_V6_FLOW: case AH_ESP_V6_FLOW: case IPV6_FLOW: - if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) + if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) info->data = RXH_IP_SRC | RXH_IP_DST; break; } @@ -3420,7 +3420,7 @@ int cxgb4_clip_get(const struct net_device *dev, memset(&c, 0, sizeof(c)); c.op_to_write = htonl(FW_CMD_OP_V(FW_CLIP_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F); - c.alloc_to_len16 = htonl(F_FW_CLIP_CMD_ALLOC | FW_LEN16(c)); + c.alloc_to_len16 = htonl(FW_CLIP_CMD_ALLOC_F | FW_LEN16(c)); c.ip_hi = *(__be64 *)(lip->s6_addr); c.ip_lo = *(__be64 *)(lip->s6_addr + 8); return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false); @@ -3437,7 +3437,7 @@ int cxgb4_clip_release(const struct net_device *dev, memset(&c, 0, sizeof(c)); c.op_to_write = htonl(FW_CMD_OP_V(FW_CLIP_CMD) | FW_CMD_REQUEST_F | FW_CMD_READ_F); - c.alloc_to_len16 = htonl(F_FW_CLIP_CMD_FREE | FW_LEN16(c)); + c.alloc_to_len16 = htonl(FW_CLIP_CMD_FREE_F | FW_LEN16(c)); c.ip_hi = *(__be64 *)(lip->s6_addr); c.ip_lo = *(__be64 *)(lip->s6_addr + 8); return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false); @@ -4988,8 +4988,8 @@ static int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) ret = t4_config_glbl_rss(adap, adap->fn, FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, - FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | - FW_RSS_GLB_CONFIG_CMD_TNLALLLKP); + FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_F | + FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_F); if (ret < 0) return ret; @@ -5365,10 +5365,10 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) adapter->flags |= RSS_TNLALLLOOKUP; ret = t4_config_glbl_rss(adapter, adapter->mbox, FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, - FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | - FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ | + FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_F | + FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_F | ((adapter->flags & RSS_TNLALLLOOKUP) ? - FW_RSS_GLB_CONFIG_CMD_TNLALLLKP : 0)); + FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_F : 0)); if (ret < 0) goto bye; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 20432e2bb17f..7975d26f50df 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -188,9 +188,9 @@ static void t4_report_fw_error(struct adapter *adap) u32 pcie_fw; pcie_fw = t4_read_reg(adap, MA_PCIE_FW); - if (pcie_fw & FW_PCIE_FW_ERR) + if (pcie_fw & PCIE_FW_ERR) dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n", - reason[FW_PCIE_FW_EVAL_GET(pcie_fw)]); + reason[PCIE_FW_EVAL_G(pcie_fw)]); } /* @@ -993,10 +993,10 @@ static int should_install_fs_fw(struct adapter *adap, int card_fw_usable, install: dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, " "installing firmware %u.%u.%u.%u on card.\n", - FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), - FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), reason, - FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), - FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); + FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c), + FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), reason, + FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k), + FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k)); return 1; } @@ -1068,12 +1068,12 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, "driver compiled with %d.%d.%d.%d, " "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n", state, - FW_HDR_FW_VER_MAJOR_GET(d), FW_HDR_FW_VER_MINOR_GET(d), - FW_HDR_FW_VER_MICRO_GET(d), FW_HDR_FW_VER_BUILD_GET(d), - FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), - FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), - FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), - FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); + FW_HDR_FW_VER_MAJOR_G(d), FW_HDR_FW_VER_MINOR_G(d), + FW_HDR_FW_VER_MICRO_G(d), FW_HDR_FW_VER_BUILD_G(d), + FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c), + FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), + FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k), + FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k)); ret = EINVAL; goto bye; } @@ -1564,7 +1564,7 @@ static void cim_intr_handler(struct adapter *adapter) int fat; - if (t4_read_reg(adapter, MA_PCIE_FW) & FW_PCIE_FW_ERR) + if (t4_read_reg(adapter, MA_PCIE_FW) & PCIE_FW_ERR) t4_report_fw_error(adapter); fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, @@ -2074,7 +2074,7 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, memset(&cmd, 0, sizeof(cmd)); cmd.op_to_viid = htonl(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_RSS_IND_TBL_CMD_VIID(viid)); + FW_RSS_IND_TBL_CMD_VIID_V(viid)); cmd.retval_len16 = htonl(FW_LEN16(cmd)); /* each fw_rss_ind_tbl_cmd takes up to 32 entries */ @@ -2091,13 +2091,13 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, while (nq > 0) { unsigned int v; - v = FW_RSS_IND_TBL_CMD_IQ0(*rsp); + v = FW_RSS_IND_TBL_CMD_IQ0_V(*rsp); if (++rsp >= rsp_end) rsp = rspq; - v |= FW_RSS_IND_TBL_CMD_IQ1(*rsp); + v |= FW_RSS_IND_TBL_CMD_IQ1_V(*rsp); if (++rsp >= rsp_end) rsp = rspq; - v |= FW_RSS_IND_TBL_CMD_IQ2(*rsp); + v |= FW_RSS_IND_TBL_CMD_IQ2_V(*rsp); if (++rsp >= rsp_end) rsp = rspq; @@ -2131,10 +2131,10 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, FW_CMD_REQUEST_F | FW_CMD_WRITE_F); c.retval_len16 = htonl(FW_LEN16(c)); if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) { - c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); + c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode)); } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) { c.u.basicvirtual.mode_pkd = - htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); + htonl(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode)); c.u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags); } else return -EINVAL; @@ -2793,7 +2793,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, if (ret < 0) { if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) goto retry; - if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR) + if (t4_read_reg(adap, MA_PCIE_FW) & PCIE_FW_ERR) t4_report_fw_error(adap); return ret; } @@ -2818,7 +2818,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, * and we wouldn't want to fail pointlessly. (This can happen when an * OS loads lots of different drivers rapidly at the same time). In * this case, the Master PF returned by the firmware will be - * FW_PCIE_FW_MASTER_MASK so the test below will work ... + * PCIE_FW_MASTER_M so the test below will work ... */ if ((v & (FW_HELLO_CMD_ERR_F|FW_HELLO_CMD_INIT_F)) == 0 && master_mbox != mbox) { @@ -2844,7 +2844,7 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, * our retries ... */ pcie_fw = t4_read_reg(adap, MA_PCIE_FW); - if (!(pcie_fw & (FW_PCIE_FW_ERR|FW_PCIE_FW_INIT))) { + if (!(pcie_fw & (PCIE_FW_ERR|PCIE_FW_INIT))) { if (waiting <= 0) { if (retries-- > 0) goto retry; @@ -2859,9 +2859,9 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, * report errors preferentially. */ if (state) { - if (pcie_fw & FW_PCIE_FW_ERR) + if (pcie_fw & PCIE_FW_ERR) *state = DEV_STATE_ERR; - else if (pcie_fw & FW_PCIE_FW_INIT) + else if (pcie_fw & PCIE_FW_INIT) *state = DEV_STATE_INIT; } @@ -2870,9 +2870,9 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, * there's not a valid Master PF, grab its identity * for our caller. */ - if (master_mbox == FW_PCIE_FW_MASTER_MASK && - (pcie_fw & FW_PCIE_FW_MASTER_VLD)) - master_mbox = FW_PCIE_FW_MASTER_GET(pcie_fw); + if (master_mbox == PCIE_FW_MASTER_M && + (pcie_fw & PCIE_FW_MASTER_VLD)) + master_mbox = PCIE_FW_MASTER_G(pcie_fw); break; } } @@ -2940,7 +2940,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) * Issues a RESET command to firmware (if desired) with a HALT indication * and then puts the microprocessor into RESET state. The RESET command * will only be issued if a legitimate mailbox is provided (mbox <= - * FW_PCIE_FW_MASTER_MASK). + * PCIE_FW_MASTER_M). * * This is generally used in order for the host to safely manipulate the * adapter without fear of conflicting with whatever the firmware might @@ -2955,7 +2955,7 @@ static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) * If a legitimate mailbox is provided, issue a RESET command * with a HALT indication. */ - if (mbox <= FW_PCIE_FW_MASTER_MASK) { + if (mbox <= PCIE_FW_MASTER_M) { struct fw_reset_cmd c; memset(&c, 0, sizeof(c)); @@ -2980,8 +2980,8 @@ static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) */ if (ret == 0 || force) { t4_set_reg_field(adap, CIM_BOOT_CFG, UPCRST, UPCRST); - t4_set_reg_field(adap, PCIE_FW, FW_PCIE_FW_HALT, - FW_PCIE_FW_HALT); + t4_set_reg_field(adap, PCIE_FW, PCIE_FW_HALT_F, + PCIE_FW_HALT_F); } /* @@ -3020,7 +3020,7 @@ static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) * doing it automatically, we need to clear the PCIE_FW.HALT * bit. */ - t4_set_reg_field(adap, PCIE_FW, FW_PCIE_FW_HALT, 0); + t4_set_reg_field(adap, PCIE_FW, PCIE_FW_HALT_F, 0); /* * If we've been given a valid mailbox, first try to get the @@ -3029,7 +3029,7 @@ static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) * valid mailbox or the RESET command failed, fall back to * hitting the chip with a hammer. */ - if (mbox <= FW_PCIE_FW_MASTER_MASK) { + if (mbox <= PCIE_FW_MASTER_M) { t4_set_reg_field(adap, CIM_BOOT_CFG, UPCRST, 0); msleep(100); if (t4_fw_reset(adap, mbox, @@ -3044,7 +3044,7 @@ static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset) t4_set_reg_field(adap, CIM_BOOT_CFG, UPCRST, 0); for (ms = 0; ms < FW_CMD_MAX_TIMEOUT; ) { - if (!(t4_read_reg(adap, PCIE_FW) & FW_PCIE_FW_HALT)) + if (!(t4_read_reg(adap, PCIE_FW) & PCIE_FW_HALT_F)) return 0; msleep(100); ms += 100; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 4c8eb875fdea..beaf80a6214b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h @@ -613,7 +613,6 @@ struct fw_ofld_tx_data_wr { struct fw_cmd_wr { __be32 op_dma; -#define FW_CMD_WR_DMA (1U << 17) __be32 len16_pkd; __be64 cookie_daddr; }; @@ -2644,11 +2643,6 @@ struct fw_port_stats_cmd { } u; }; -#define FW_PORT_STATS_CMD_NSTATS(x) ((x) << 4) -#define FW_PORT_STATS_CMD_BG_BM(x) ((x) << 0) -#define FW_PORT_STATS_CMD_TX(x) ((x) << 7) -#define FW_PORT_STATS_CMD_IX(x) ((x) << 0) - /* port loopback stats */ #define FW_NUM_LB_STATS 16 enum fw_port_lb_stats_index { @@ -2704,22 +2698,13 @@ struct fw_port_lb_stats_cmd { } u; }; -#define FW_PORT_LB_STATS_CMD_LBPORT(x) ((x) << 0) -#define FW_PORT_LB_STATS_CMD_NSTATS(x) ((x) << 4) -#define FW_PORT_LB_STATS_CMD_BG_BM(x) ((x) << 0) -#define FW_PORT_LB_STATS_CMD_IX(x) ((x) << 0) - struct fw_rss_ind_tbl_cmd { __be32 op_to_viid; -#define FW_RSS_IND_TBL_CMD_VIID(x) ((x) << 0) __be32 retval_len16; __be16 niqid; __be16 startidx; __be32 r3; __be32 iq0_to_iq2; -#define FW_RSS_IND_TBL_CMD_IQ0(x) ((x) << 20) -#define FW_RSS_IND_TBL_CMD_IQ1(x) ((x) << 10) -#define FW_RSS_IND_TBL_CMD_IQ2(x) ((x) << 0) __be32 iq3_to_iq5; __be32 iq6_to_iq8; __be32 iq9_to_iq11; @@ -2733,6 +2718,18 @@ struct fw_rss_ind_tbl_cmd { __be32 r15_lo; }; +#define FW_RSS_IND_TBL_CMD_VIID_S 0 +#define FW_RSS_IND_TBL_CMD_VIID_V(x) ((x) << FW_RSS_IND_TBL_CMD_VIID_S) + +#define FW_RSS_IND_TBL_CMD_IQ0_S 20 +#define FW_RSS_IND_TBL_CMD_IQ0_V(x) ((x) << FW_RSS_IND_TBL_CMD_IQ0_S) + +#define FW_RSS_IND_TBL_CMD_IQ1_S 10 +#define FW_RSS_IND_TBL_CMD_IQ1_V(x) ((x) << FW_RSS_IND_TBL_CMD_IQ1_S) + +#define FW_RSS_IND_TBL_CMD_IQ2_S 0 +#define FW_RSS_IND_TBL_CMD_IQ2_V(x) ((x) << FW_RSS_IND_TBL_CMD_IQ2_S) + struct fw_rss_glb_config_cmd { __be32 op_to_write; __be32 retval_len16; @@ -2746,27 +2743,75 @@ struct fw_rss_glb_config_cmd { struct fw_rss_glb_config_basicvirtual { __be32 mode_pkd; __be32 synmapen_to_hashtoeplitz; -#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN (1U << 8) -#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 (1U << 7) -#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 (1U << 6) -#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 (1U << 5) -#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 (1U << 4) -#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN (1U << 3) -#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN (1U << 2) -#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP (1U << 1) -#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ (1U << 0) __be64 r8; __be64 r9; } basicvirtual; } u; }; -#define FW_RSS_GLB_CONFIG_CMD_MODE(x) ((x) << 28) -#define FW_RSS_GLB_CONFIG_CMD_MODE_GET(x) (((x) >> 28) & 0xf) +#define FW_RSS_GLB_CONFIG_CMD_MODE_S 28 +#define FW_RSS_GLB_CONFIG_CMD_MODE_M 0xf +#define FW_RSS_GLB_CONFIG_CMD_MODE_V(x) ((x) << FW_RSS_GLB_CONFIG_CMD_MODE_S) +#define FW_RSS_GLB_CONFIG_CMD_MODE_G(x) \ + (((x) >> FW_RSS_GLB_CONFIG_CMD_MODE_S) & FW_RSS_GLB_CONFIG_CMD_MODE_M) #define FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL 0 #define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL 1 +#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_S 8 +#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_S) +#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_F \ + FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_S 7 +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_S) +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_F \ + FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_S 6 +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_S) +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_F \ + FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_S 5 +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_S) +#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_F \ + FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_S 4 +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_S) +#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_F \ + FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_S 3 +#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_S) +#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_F \ + FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_S 2 +#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_S) +#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_F \ + FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_S 1 +#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_S) +#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_F \ + FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_V(1U) + +#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_S 0 +#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_V(x) \ + ((x) << FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_S) +#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_F \ + FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_V(1U) + struct fw_rss_vi_config_cmd { __be32 op_to_viid; #define FW_RSS_VI_CONFIG_CMD_VIID(x) ((x) << 0) @@ -2780,19 +2825,51 @@ struct fw_rss_vi_config_cmd { struct fw_rss_vi_config_basicvirtual { __be32 r6; __be32 defaultq_to_udpen; -#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ(x) ((x) << 16) -#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ_GET(x) (((x) >> 16) & 0x3ff) -#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN (1U << 4) -#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN (1U << 3) -#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN (1U << 2) -#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN (1U << 1) -#define FW_RSS_VI_CONFIG_CMD_UDPEN (1U << 0) __be64 r9; __be64 r10; } basicvirtual; } u; }; +#define FW_RSS_VI_CONFIG_CMD_VIID_S 0 +#define FW_RSS_VI_CONFIG_CMD_VIID_V(x) ((x) << FW_RSS_VI_CONFIG_CMD_VIID_S) + +#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ_S 16 +#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ_M 0x3ff +#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V(x) \ + ((x) << FW_RSS_VI_CONFIG_CMD_DEFAULTQ_S) +#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ_G(x) \ + (((x) >> FW_RSS_VI_CONFIG_CMD_DEFAULTQ_S) & \ + FW_RSS_VI_CONFIG_CMD_DEFAULTQ_M) + +#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_S 4 +#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_V(x) \ + ((x) << FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_S) +#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F \ + FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_V(1U) + +#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_S 3 +#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_V(x) \ + ((x) << FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_S) +#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F \ + FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_V(1U) + +#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_S 2 +#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_V(x) \ + ((x) << FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_S) +#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F \ + FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_V(1U) + +#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_S 1 +#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_V(x) \ + ((x) << FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_S) +#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F \ + FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_V(1U) + +#define FW_RSS_VI_CONFIG_CMD_UDPEN_S 0 +#define FW_RSS_VI_CONFIG_CMD_UDPEN_V(x) ((x) << FW_RSS_VI_CONFIG_CMD_UDPEN_S) +#define FW_RSS_VI_CONFIG_CMD_UDPEN_F FW_RSS_VI_CONFIG_CMD_UDPEN_V(1U) + struct fw_clip_cmd { __be32 op_to_write; __be32 alloc_to_len16; @@ -2801,19 +2878,13 @@ struct fw_clip_cmd { __be32 r4[2]; }; -#define S_FW_CLIP_CMD_ALLOC 31 -#define M_FW_CLIP_CMD_ALLOC 0x1 -#define V_FW_CLIP_CMD_ALLOC(x) ((x) << S_FW_CLIP_CMD_ALLOC) -#define G_FW_CLIP_CMD_ALLOC(x) \ - (((x) >> S_FW_CLIP_CMD_ALLOC) & M_FW_CLIP_CMD_ALLOC) -#define F_FW_CLIP_CMD_ALLOC V_FW_CLIP_CMD_ALLOC(1U) +#define FW_CLIP_CMD_ALLOC_S 31 +#define FW_CLIP_CMD_ALLOC_V(x) ((x) << FW_CLIP_CMD_ALLOC_S) +#define FW_CLIP_CMD_ALLOC_F FW_CLIP_CMD_ALLOC_V(1U) -#define S_FW_CLIP_CMD_FREE 30 -#define M_FW_CLIP_CMD_FREE 0x1 -#define V_FW_CLIP_CMD_FREE(x) ((x) << S_FW_CLIP_CMD_FREE) -#define G_FW_CLIP_CMD_FREE(x) \ - (((x) >> S_FW_CLIP_CMD_FREE) & M_FW_CLIP_CMD_FREE) -#define F_FW_CLIP_CMD_FREE V_FW_CLIP_CMD_FREE(1U) +#define FW_CLIP_CMD_FREE_S 30 +#define FW_CLIP_CMD_FREE_V(x) ((x) << FW_CLIP_CMD_FREE_S) +#define FW_CLIP_CMD_FREE_F FW_CLIP_CMD_FREE_V(1U) enum fw_error_type { FW_ERROR_TYPE_EXCEPTION = 0x0, @@ -2852,7 +2923,6 @@ struct fw_error_cmd { struct fw_debug_cmd { __be32 op_type; -#define FW_DEBUG_CMD_TYPE_GET(x) ((x) & 0xff) __be32 len16_pkd; union fw_debug { struct fw_debug_assert { @@ -2875,19 +2945,35 @@ struct fw_debug_cmd { } u; }; -#define FW_PCIE_FW_ERR (1U << 31) -#define FW_PCIE_FW_INIT (1U << 30) -#define FW_PCIE_FW_HALT (1U << 29) -#define FW_PCIE_FW_MASTER_VLD (1U << 15) -#define FW_PCIE_FW_MASTER_MASK 0x7 -#define FW_PCIE_FW_MASTER_SHIFT 12 -#define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) -#define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ - FW_PCIE_FW_MASTER_MASK) -#define FW_PCIE_FW_EVAL_MASK 0x7 -#define FW_PCIE_FW_EVAL_SHIFT 24 -#define FW_PCIE_FW_EVAL_GET(x) (((x) >> FW_PCIE_FW_EVAL_SHIFT) & \ - FW_PCIE_FW_EVAL_MASK) +#define FW_DEBUG_CMD_TYPE_S 0 +#define FW_DEBUG_CMD_TYPE_M 0xff +#define FW_DEBUG_CMD_TYPE_G(x) \ + (((x) >> FW_DEBUG_CMD_TYPE_S) & FW_DEBUG_CMD_TYPE_M) + +#define PCIE_FW_ERR_S 31 +#define PCIE_FW_ERR_V(x) ((x) << PCIE_FW_ERR_S) +#define PCIE_FW_ERR_F PCIE_FW_ERR_V(1U) + +#define PCIE_FW_INIT_S 30 +#define PCIE_FW_INIT_V(x) ((x) << PCIE_FW_INIT_S) +#define PCIE_FW_INIT_F PCIE_FW_INIT_V(1U) + +#define PCIE_FW_HALT_S 29 +#define PCIE_FW_HALT_V(x) ((x) << PCIE_FW_HALT_S) +#define PCIE_FW_HALT_F PCIE_FW_HALT_V(1U) + +#define PCIE_FW_EVAL_S 24 +#define PCIE_FW_EVAL_M 0x7 +#define PCIE_FW_EVAL_G(x) (((x) >> PCIE_FW_EVAL_S) & PCIE_FW_EVAL_M) + +#define PCIE_FW_MASTER_VLD_S 15 +#define PCIE_FW_MASTER_VLD_V(x) ((x) << PCIE_FW_MASTER_VLD_S) +#define PCIE_FW_MASTER_VLD_F PCIE_FW_MASTER_VLD_V(1U) + +#define PCIE_FW_MASTER_S 12 +#define PCIE_FW_MASTER_M 0x7 +#define PCIE_FW_MASTER_V(x) ((x) << PCIE_FW_MASTER_S) +#define PCIE_FW_MASTER_G(x) (((x) >> PCIE_FW_MASTER_S) & PCIE_FW_MASTER_M) struct fw_hdr { u8 ver; @@ -2915,10 +3001,25 @@ enum fw_hdr_chip { FW_HDR_CHIP_T5 }; -#define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff) -#define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) -#define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) -#define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff) +#define FW_HDR_FW_VER_MAJOR_S 24 +#define FW_HDR_FW_VER_MAJOR_M 0xff +#define FW_HDR_FW_VER_MAJOR_G(x) \ + (((x) >> FW_HDR_FW_VER_MAJOR_S) & FW_HDR_FW_VER_MAJOR_M) + +#define FW_HDR_FW_VER_MINOR_S 16 +#define FW_HDR_FW_VER_MINOR_M 0xff +#define FW_HDR_FW_VER_MINOR_G(x) \ + (((x) >> FW_HDR_FW_VER_MINOR_S) & FW_HDR_FW_VER_MINOR_M) + +#define FW_HDR_FW_VER_MICRO_S 8 +#define FW_HDR_FW_VER_MICRO_M 0xff +#define FW_HDR_FW_VER_MICRO_G(x) \ + (((x) >> FW_HDR_FW_VER_MICRO_S) & FW_HDR_FW_VER_MICRO_M) + +#define FW_HDR_FW_VER_BUILD_S 0 +#define FW_HDR_FW_VER_BUILD_M 0xff +#define FW_HDR_FW_VER_BUILD_G(x) \ + (((x) >> FW_HDR_FW_VER_BUILD_S) & FW_HDR_FW_VER_BUILD_M) enum fw_hdr_intfver { FW_HDR_INTFVER_NIC = 0x00, diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 7c24b50c7d0b..099f7ce056f2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -1230,14 +1230,14 @@ static void cxgb4vf_get_drvinfo(struct net_device *dev, sizeof(drvinfo->bus_info)); snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%u.%u.%u.%u, TP %u.%u.%u.%u", - FW_HDR_FW_VER_MAJOR_GET(adapter->params.dev.fwrev), - FW_HDR_FW_VER_MINOR_GET(adapter->params.dev.fwrev), - FW_HDR_FW_VER_MICRO_GET(adapter->params.dev.fwrev), - FW_HDR_FW_VER_BUILD_GET(adapter->params.dev.fwrev), - FW_HDR_FW_VER_MAJOR_GET(adapter->params.dev.tprev), - FW_HDR_FW_VER_MINOR_GET(adapter->params.dev.tprev), - FW_HDR_FW_VER_MICRO_GET(adapter->params.dev.tprev), - FW_HDR_FW_VER_BUILD_GET(adapter->params.dev.tprev)); + FW_HDR_FW_VER_MAJOR_G(adapter->params.dev.fwrev), + FW_HDR_FW_VER_MINOR_G(adapter->params.dev.fwrev), + FW_HDR_FW_VER_MICRO_G(adapter->params.dev.fwrev), + FW_HDR_FW_VER_BUILD_G(adapter->params.dev.fwrev), + FW_HDR_FW_VER_MAJOR_G(adapter->params.dev.tprev), + FW_HDR_FW_VER_MINOR_G(adapter->params.dev.tprev), + FW_HDR_FW_VER_MICRO_G(adapter->params.dev.tprev), + FW_HDR_FW_VER_BUILD_G(adapter->params.dev.tprev)); } /* diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 960d35c6c370..624a213dea87 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -585,7 +585,7 @@ int t4vf_get_rss_glb_config(struct adapter *adapter) * filtering at this point to weed out modes which don't support * VF Drivers ... */ - rss->mode = FW_RSS_GLB_CONFIG_CMD_MODE_GET( + rss->mode = FW_RSS_GLB_CONFIG_CMD_MODE_G( be32_to_cpu(rpl.u.manual.mode_pkd)); switch (rss->mode) { case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: { @@ -593,26 +593,26 @@ int t4vf_get_rss_glb_config(struct adapter *adapter) rpl.u.basicvirtual.synmapen_to_hashtoeplitz); rss->u.basicvirtual.synmapen = - ((word & FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_SYNMAPEN_F) != 0); rss->u.basicvirtual.syn4tupenipv6 = - ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6_F) != 0); rss->u.basicvirtual.syn2tupenipv6 = - ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6_F) != 0); rss->u.basicvirtual.syn4tupenipv4 = - ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4_F) != 0); rss->u.basicvirtual.syn2tupenipv4 = - ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4_F) != 0); rss->u.basicvirtual.ofdmapen = - ((word & FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_OFDMAPEN_F) != 0); rss->u.basicvirtual.tnlmapen = - ((word & FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_TNLMAPEN_F) != 0); rss->u.basicvirtual.tnlalllookup = - ((word & FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_TNLALLLKP_F) != 0); rss->u.basicvirtual.hashtoeplitz = - ((word & FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0); + ((word & FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ_F) != 0); /* we need at least Tunnel Map Enable to be set */ if (!rss->u.basicvirtual.tnlmapen) @@ -709,17 +709,17 @@ int t4vf_read_rss_vi_config(struct adapter *adapter, unsigned int viid, u32 word = be32_to_cpu(rpl.u.basicvirtual.defaultq_to_udpen); config->basicvirtual.ip6fourtupen = - ((word & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) != 0); + ((word & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) != 0); config->basicvirtual.ip6twotupen = - ((word & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) != 0); + ((word & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) != 0); config->basicvirtual.ip4fourtupen = - ((word & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) != 0); + ((word & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) != 0); config->basicvirtual.ip4twotupen = - ((word & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) != 0); + ((word & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) != 0); config->basicvirtual.udpen = - ((word & FW_RSS_VI_CONFIG_CMD_UDPEN) != 0); + ((word & FW_RSS_VI_CONFIG_CMD_UDPEN_F) != 0); config->basicvirtual.defaultq = - FW_RSS_VI_CONFIG_CMD_DEFAULTQ_GET(word); + FW_RSS_VI_CONFIG_CMD_DEFAULTQ_G(word); break; } @@ -755,16 +755,16 @@ int t4vf_write_rss_vi_config(struct adapter *adapter, unsigned int viid, u32 word = 0; if (config->basicvirtual.ip6fourtupen) - word |= FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN; + word |= FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F; if (config->basicvirtual.ip6twotupen) - word |= FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN; + word |= FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F; if (config->basicvirtual.ip4fourtupen) - word |= FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN; + word |= FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F; if (config->basicvirtual.ip4twotupen) - word |= FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN; + word |= FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F; if (config->basicvirtual.udpen) - word |= FW_RSS_VI_CONFIG_CMD_UDPEN; - word |= FW_RSS_VI_CONFIG_CMD_DEFAULTQ( + word |= FW_RSS_VI_CONFIG_CMD_UDPEN_F; + word |= FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V( config->basicvirtual.defaultq); cmd.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(word); break; @@ -806,7 +806,7 @@ int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid, cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) | FW_CMD_REQUEST_F | FW_CMD_WRITE_F | - FW_RSS_IND_TBL_CMD_VIID(viid)); + FW_RSS_IND_TBL_CMD_VIID_V(viid)); cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); /* @@ -857,9 +857,9 @@ int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid, if (rsp >= rsp_end) rsp = rspq; } - *qp++ = cpu_to_be32(FW_RSS_IND_TBL_CMD_IQ0(qbuf[0]) | - FW_RSS_IND_TBL_CMD_IQ1(qbuf[1]) | - FW_RSS_IND_TBL_CMD_IQ2(qbuf[2])); + *qp++ = cpu_to_be32(FW_RSS_IND_TBL_CMD_IQ0_V(qbuf[0]) | + FW_RSS_IND_TBL_CMD_IQ1_V(qbuf[1]) | + FW_RSS_IND_TBL_CMD_IQ2_V(qbuf[2])); } /* diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 80ad9c52eebd..1e4c4ee9e11e 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -650,10 +650,10 @@ static void csio_hw_print_fw_version(struct csio_hw *hw, char *str) { csio_info(hw, "%s: %u.%u.%u.%u\n", str, - FW_HDR_FW_VER_MAJOR_GET(hw->fwrev), - FW_HDR_FW_VER_MINOR_GET(hw->fwrev), - FW_HDR_FW_VER_MICRO_GET(hw->fwrev), - FW_HDR_FW_VER_BUILD_GET(hw->fwrev)); + FW_HDR_FW_VER_MAJOR_G(hw->fwrev), + FW_HDR_FW_VER_MINOR_G(hw->fwrev), + FW_HDR_FW_VER_MICRO_G(hw->fwrev), + FW_HDR_FW_VER_BUILD_G(hw->fwrev)); } /* @@ -706,9 +706,9 @@ csio_hw_check_fw_version(struct csio_hw *hw) if (ret) return ret; - major = FW_HDR_FW_VER_MAJOR_GET(hw->fwrev); - minor = FW_HDR_FW_VER_MINOR_GET(hw->fwrev); - micro = FW_HDR_FW_VER_MICRO_GET(hw->fwrev); + major = FW_HDR_FW_VER_MAJOR_G(hw->fwrev); + minor = FW_HDR_FW_VER_MINOR_G(hw->fwrev); + micro = FW_HDR_FW_VER_MICRO_G(hw->fwrev); if (major != FW_VERSION_MAJOR(hw)) { /* major mismatch - fail */ csio_err(hw, "card FW has major version %u, driver wants %u\n", @@ -1998,13 +1998,13 @@ csio_hw_flash_fw(struct csio_hw *hw) hdr = (const struct fw_hdr *)fw->data; fw_ver = ntohl(hdr->fw_ver); - if (FW_HDR_FW_VER_MAJOR_GET(fw_ver) != FW_VERSION_MAJOR(hw)) + if (FW_HDR_FW_VER_MAJOR_G(fw_ver) != FW_VERSION_MAJOR(hw)) return -EINVAL; /* wrong major version, won't do */ /* * If the flash FW is unusable or we found something newer, load it. */ - if (FW_HDR_FW_VER_MAJOR_GET(hw->fwrev) != FW_VERSION_MAJOR(hw) || + if (FW_HDR_FW_VER_MAJOR_G(hw->fwrev) != FW_VERSION_MAJOR(hw) || fw_ver > hw->fwrev) { ret = csio_hw_fw_upgrade(hw, hw->pfn, fw->data, fw->size, /*force=*/false); diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 70e1eb6d9640..1ed5b21c0dd8 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -974,10 +974,10 @@ static int csio_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) } sprintf(hw->fwrev_str, "%u.%u.%u.%u\n", - FW_HDR_FW_VER_MAJOR_GET(hw->fwrev), - FW_HDR_FW_VER_MINOR_GET(hw->fwrev), - FW_HDR_FW_VER_MICRO_GET(hw->fwrev), - FW_HDR_FW_VER_BUILD_GET(hw->fwrev)); + FW_HDR_FW_VER_MAJOR_G(hw->fwrev), + FW_HDR_FW_VER_MINOR_G(hw->fwrev), + FW_HDR_FW_VER_MICRO_G(hw->fwrev), + FW_HDR_FW_VER_BUILD_G(hw->fwrev)); for (i = 0; i < hw->num_pports; i++) { ln = csio_shost_init(hw, &pdev->dev, true, NULL); diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index 829887886898..08c265c0f353 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -1126,7 +1126,7 @@ csio_mb_dump_fw_dbg(struct csio_hw *hw, __be64 *cmd) { struct fw_debug_cmd *dbg = (struct fw_debug_cmd *)cmd; - if ((FW_DEBUG_CMD_TYPE_GET(ntohl(dbg->op_type))) == 1) { + if ((FW_DEBUG_CMD_TYPE_G(ntohl(dbg->op_type))) == 1) { csio_info(hw, "FW print message:\n"); csio_info(hw, "\tdebug->dprtstridx = %d\n", ntohs(dbg->u.prt.dprtstridx)); -- GitLab From b7bdb7f45e7b848dc2eb50c2d5c5106af68562c4 Mon Sep 17 00:00:00 2001 From: Julien CHAUVEAU Date: Fri, 21 Nov 2014 10:27:41 +0100 Subject: [PATCH 5855/9457] clk: rockchip: fix clock gate for rk3188 spdif_pre In rk3188 clock branches, spdif_pre gate was set to RK2928_CLKGATE_CON(13) bit 13. This appears to be a copy-paste error because such a register does not exist. We correct it to RK2928_CLKGATE_CON(0) and find out that the rk3188 spdif clock is the same as the rk3066 spdif clock, so we move it to the common clock branches. Signed-off-by: Julien CHAUVEAU Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index e6cd4838cde5..c24986970815 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -330,6 +330,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, + RK2928_CLKSEL_CON(9), 0, + RK2928_CLKGATE_CON(0), 14, GFLAGS), + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), + /* * Clock-Architecture Diagram 4 */ @@ -577,14 +586,6 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 12, GFLAGS), MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, RK2928_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(0), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), @@ -675,14 +676,6 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 10, GFLAGS), MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(13), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), -- GitLab From 12c0a0e81e2f9c03404a3e095517c022991aad43 Mon Sep 17 00:00:00 2001 From: Julien CHAUVEAU Date: Fri, 21 Nov 2014 11:08:47 +0100 Subject: [PATCH 5856/9457] clk: rockchip: fix rk3188 USB HSIC PHY clock divider The USB HSIC PHY clock divider is set in the register RK2928_CLKSEL_CON(11). Signed-off-by: Julien CHAUVEAU Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index c24986970815..22dccc6cd664 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -664,7 +664,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(30), 0, 2, DFLAGS, RK2928_CLKGATE_CON(3), 6, GFLAGS), DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0, - RK2928_CLKGATE_CON(11), 8, 6, DFLAGS), + RK2928_CLKSEL_CON(11), 8, 6, DFLAGS), MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), -- GitLab From f4226d9ea400e7124120571b1e89504c79f2e953 Mon Sep 17 00:00:00 2001 From: Eric Whitney Date: Sun, 23 Nov 2014 00:55:42 -0500 Subject: [PATCH 5857/9457] ext4: fix partial cluster initialization The partial_cluster variable is not always initialized correctly when hole punching on bigalloc file systems. Although commit c06344939422 ("ext4: fix partial cluster handling for bigalloc file systems") addressed the case where the right edge of the punched region and the next extent to its right were within the same leaf, it didn't handle the case where the next extent to its right is in the next leaf. This causes xfstest generic/300 to fail. Fix this by replacing the code in c0634493922 with a more general solution that can continue the search for the first cluster to the right of the punched region into the next leaf if present. If found, partial_cluster is initialized to this cluster's negative value. There's no need to determine if that cluster is actually shared; we simply record it so its blocks won't be freed in the event it does happen to be shared. Also, minimize the burden on non-bigalloc file systems with some minor code simplification. Signed-off-by: Eric Whitney Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 80 +++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0b16fb4c06d3..57794a7a435c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2621,27 +2621,6 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, ex_ee_block = le32_to_cpu(ex->ee_block); ex_ee_len = ext4_ext_get_actual_len(ex); - /* - * If we're starting with an extent other than the last one in the - * node, we need to see if it shares a cluster with the extent to - * the right (towards the end of the file). If its leftmost cluster - * is this extent's rightmost cluster and it is not cluster aligned, - * we'll mark it as a partial that is not to be deallocated. - */ - - if (ex != EXT_LAST_EXTENT(eh)) { - ext4_fsblk_t current_pblk, right_pblk; - long long current_cluster, right_cluster; - - current_pblk = ext4_ext_pblock(ex) + ex_ee_len - 1; - current_cluster = (long long)EXT4_B2C(sbi, current_pblk); - right_pblk = ext4_ext_pblock(ex + 1); - right_cluster = (long long)EXT4_B2C(sbi, right_pblk); - if (current_cluster == right_cluster && - EXT4_PBLK_COFF(sbi, right_pblk)) - *partial_cluster = -right_cluster; - } - trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster); while (ex >= EXT_FIRST_EXTENT(eh) && @@ -2666,14 +2645,16 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, if (end < ex_ee_block) { /* * We're going to skip this extent and move to another, - * so if this extent is not cluster aligned we have - * to mark the current cluster as used to avoid - * accidentally freeing it later on + * so note that its first cluster is in use to avoid + * freeing it when removing blocks. Eventually, the + * right edge of the truncated/punched region will + * be just to the left. */ - pblk = ext4_ext_pblock(ex); - if (EXT4_PBLK_COFF(sbi, pblk)) + if (sbi->s_cluster_ratio > 1) { + pblk = ext4_ext_pblock(ex); *partial_cluster = - -((long long)EXT4_B2C(sbi, pblk)); + -(long long) EXT4_B2C(sbi, pblk); + } ex--; ex_ee_block = le32_to_cpu(ex->ee_block); ex_ee_len = ext4_ext_get_actual_len(ex); @@ -2819,7 +2800,7 @@ ext4_ext_more_to_rm(struct ext4_ext_path *path) int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, ext4_lblk_t end) { - struct super_block *sb = inode->i_sb; + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); int depth = ext_depth(inode); struct ext4_ext_path *path = NULL; long long partial_cluster = 0; @@ -2845,9 +2826,10 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, */ if (end < EXT_MAX_BLOCKS - 1) { struct ext4_extent *ex; - ext4_lblk_t ee_block; + ext4_lblk_t ee_block, ex_end, lblk; + ext4_fsblk_t pblk; - /* find extent for this block */ + /* find extent for or closest extent to this block */ path = ext4_find_extent(inode, end, NULL, EXT4_EX_NOCACHE); if (IS_ERR(path)) { ext4_journal_stop(handle); @@ -2867,6 +2849,7 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, } ee_block = le32_to_cpu(ex->ee_block); + ex_end = ee_block + ext4_ext_get_actual_len(ex) - 1; /* * See if the last block is inside the extent, if so split @@ -2874,8 +2857,19 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, * tail of the first part of the split extent in * ext4_ext_rm_leaf(). */ - if (end >= ee_block && - end < ee_block + ext4_ext_get_actual_len(ex) - 1) { + if (end >= ee_block && end < ex_end) { + + /* + * If we're going to split the extent, note that + * the cluster containing the block after 'end' is + * in use to avoid freeing it when removing blocks. + */ + if (sbi->s_cluster_ratio > 1) { + pblk = ext4_ext_pblock(ex) + end - ee_block + 2; + partial_cluster = + -(long long) EXT4_B2C(sbi, pblk); + } + /* * Split the extent in two so that 'end' is the last * block in the first new extent. Also we should not @@ -2886,6 +2880,24 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, end + 1, 1); if (err < 0) goto out; + + } else if (sbi->s_cluster_ratio > 1 && end >= ex_end) { + /* + * If there's an extent to the right its first cluster + * contains the immediate right boundary of the + * truncated/punched region. Set partial_cluster to + * its negative value so it won't be freed if shared + * with the current extent. The end < ee_block case + * is handled in ext4_ext_rm_leaf(). + */ + lblk = ex_end + 1; + err = ext4_ext_search_right(inode, path, &lblk, &pblk, + &ex); + if (err) + goto out; + if (pblk) + partial_cluster = + -(long long) EXT4_B2C(sbi, pblk); } } /* @@ -3003,8 +3015,8 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, int flags = get_default_free_blocks_flags(inode); ext4_free_blocks(handle, inode, NULL, - EXT4_C2B(EXT4_SB(sb), partial_cluster), - EXT4_SB(sb)->s_cluster_ratio, flags); + EXT4_C2B(sbi, partial_cluster), + sbi->s_cluster_ratio, flags); partial_cluster = 0; } -- GitLab From 5bf43760654fa618fb8bb1612ee2d7ae164f7f94 Mon Sep 17 00:00:00 2001 From: Eric Whitney Date: Sun, 23 Nov 2014 00:58:11 -0500 Subject: [PATCH 5858/9457] ext4: fix end of leaf partial cluster handling The fix in commit ad6599ab3ac9 ("ext4: fix premature freeing of partial clusters split across leaf blocks"), intended to avoid dereferencing an invalid extent pointer when determining whether a partial cluster should be freed, wasn't quite good enough. Assure that at least one extent remains at the start of the leaf once the hole has been punched. Otherwise, the pointer to the extent to the right of the hole will be invalid and a partial cluster will be incorrectly freed. Set partial_cluster to 0 when we can tell we've hit the left edge of the punched region within the leaf. This prevents incorrect freeing of a partial cluster when ext4_ext_rm_leaf is called one last time during extent tree traversal after the punched region has been removed. Adjust comments to reflect code changes and a correction. Remove a bit of dead code. Signed-off-by: Eric Whitney Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 57794a7a435c..859ab37efa6f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2574,15 +2574,16 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, /* * ext4_ext_rm_leaf() Removes the extents associated with the - * blocks appearing between "start" and "end", and splits the extents - * if "start" and "end" appear in the same extent + * blocks appearing between "start" and "end". Both "start" + * and "end" must appear in the same extent or EIO is returned. * * @handle: The journal handle * @inode: The files inode * @path: The path to the leaf * @partial_cluster: The cluster which we'll have to free if all extents - * has been released from it. It gets negative in case - * that the cluster is still used. + * has been released from it. However, if this value is + * negative, it's a cluster just to the right of the + * punched region and it must not be freed. * @start: The first block to remove * @end: The last block to remove */ @@ -2730,8 +2731,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, sizeof(struct ext4_extent)); } le16_add_cpu(&eh->eh_entries, -1); - } else if (*partial_cluster > 0) - *partial_cluster = 0; + } err = ext4_ext_dirty(handle, inode, path + depth); if (err) @@ -2750,20 +2750,18 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, /* * If there's a partial cluster and at least one extent remains in * the leaf, free the partial cluster if it isn't shared with the - * current extent. If there's a partial cluster and no extents - * remain in the leaf, it can't be freed here. It can only be - * freed when it's possible to determine if it's not shared with - * any other extent - when the next leaf is processed or when space - * removal is complete. + * current extent. If it is shared with the current extent + * we zero partial_cluster because we've reached the start of the + * truncated/punched region and we're done removing blocks. */ - if (*partial_cluster > 0 && eh->eh_entries && - (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) != - *partial_cluster)) { - int flags = get_default_free_blocks_flags(inode); - - ext4_free_blocks(handle, inode, NULL, - EXT4_C2B(sbi, *partial_cluster), - sbi->s_cluster_ratio, flags); + if (*partial_cluster > 0 && ex >= EXT_FIRST_EXTENT(eh)) { + pblk = ext4_ext_pblock(ex) + ex_ee_len - 1; + if (*partial_cluster != (long long) EXT4_B2C(sbi, pblk)) { + ext4_free_blocks(handle, inode, NULL, + EXT4_C2B(sbi, *partial_cluster), + sbi->s_cluster_ratio, + get_default_free_blocks_flags(inode)); + } *partial_cluster = 0; } -- GitLab From 345ee947482f1c787b31014008586b8f512af1bd Mon Sep 17 00:00:00 2001 From: Eric Whitney Date: Sun, 23 Nov 2014 00:59:39 -0500 Subject: [PATCH 5859/9457] ext4: miscellaneous partial cluster cleanups Add some casts and rearrange a few statements for improved readability. Some code can also be simplified and made more readable if we set partial_cluster to 0 rather than to a negative value when we can tell we've hit the left edge of the punched region. Signed-off-by: Eric Whitney Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 859ab37efa6f..841adf05e287 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2481,7 +2481,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t from, ext4_lblk_t to) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - unsigned short ee_len = ext4_ext_get_actual_len(ex); + unsigned short ee_len = ext4_ext_get_actual_len(ex); ext4_fsblk_t pblk; int flags = get_default_free_blocks_flags(inode); @@ -2490,7 +2490,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, * at the beginning of the extent. Instead, we make a note * that we tried freeing the cluster, and check to see if we * need to free it on a subsequent call to ext4_remove_blocks, - * or at the end of the ext4_truncate() operation. + * or at the end of ext4_ext_rm_leaf or ext4_ext_remove_space. */ flags |= EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER; @@ -2501,8 +2501,8 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, * partial cluster here. */ pblk = ext4_ext_pblock(ex) + ee_len - 1; - if ((*partial_cluster > 0) && - (EXT4_B2C(sbi, pblk) != *partial_cluster)) { + if (*partial_cluster > 0 && + *partial_cluster != (long long) EXT4_B2C(sbi, pblk)) { ext4_free_blocks(handle, inode, NULL, EXT4_C2B(sbi, *partial_cluster), sbi->s_cluster_ratio, flags); @@ -2528,7 +2528,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, && to == le32_to_cpu(ex->ee_block) + ee_len - 1) { /* tail removal */ ext4_lblk_t num; - unsigned int unaligned; + long long first_cluster; num = le32_to_cpu(ex->ee_block) + ee_len - from; pblk = ext4_ext_pblock(ex) + ee_len - num; @@ -2538,7 +2538,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, * used by any other extent (partial_cluster is negative). */ if (*partial_cluster < 0 && - -(*partial_cluster) == EXT4_B2C(sbi, pblk + num - 1)) + *partial_cluster == -(long long) EXT4_B2C(sbi, pblk+num-1)) flags |= EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER; ext_debug("free last %u blocks starting %llu partial %lld\n", @@ -2549,21 +2549,24 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, * beginning of a cluster, and we removed the entire * extent and the cluster is not used by any other extent, * save the partial cluster here, since we might need to - * delete if we determine that the truncate operation has - * removed all of the blocks in the cluster. + * delete if we determine that the truncate or punch hole + * operation has removed all of the blocks in the cluster. + * If that cluster is used by another extent, preserve its + * negative value so it isn't freed later on. * - * On the other hand, if we did not manage to free the whole - * extent, we have to mark the cluster as used (store negative - * cluster number in partial_cluster). + * If the whole extent wasn't freed, we've reached the + * start of the truncated/punched region and have finished + * removing blocks. If there's a partial cluster here it's + * shared with the remainder of the extent and is no longer + * a candidate for removal. */ - unaligned = EXT4_PBLK_COFF(sbi, pblk); - if (unaligned && (ee_len == num) && - (*partial_cluster != -((long long)EXT4_B2C(sbi, pblk)))) - *partial_cluster = EXT4_B2C(sbi, pblk); - else if (unaligned) - *partial_cluster = -((long long)EXT4_B2C(sbi, pblk)); - else if (*partial_cluster > 0) + if (EXT4_PBLK_COFF(sbi, pblk) && ee_len == num) { + first_cluster = (long long) EXT4_B2C(sbi, pblk); + if (first_cluster != -*partial_cluster) + *partial_cluster = first_cluster; + } else { *partial_cluster = 0; + } } else ext4_error(sbi->s_sb, "strange request: removal(2) " "%u-%u from %u:%u\n", -- GitLab From 0756b908a364c217bc2d8063783992ffe338b143 Mon Sep 17 00:00:00 2001 From: Eric Whitney Date: Sun, 23 Nov 2014 00:59:39 -0500 Subject: [PATCH 5860/9457] ext4: fix end of region partial cluster handling ext4_ext_remove_space() can incorrectly free a partial_cluster if EAGAIN is encountered while truncating or punching. Extent removal should be retried in this case. It also fails to free a partial cluster when the punched region begins at the start of a file on that unaligned cluster and where the entire file has not been punched. Remove the requirement that all blocks in the file must have been freed in order to free the partial cluster. Signed-off-by: Eric Whitney Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 841adf05e287..9eae2f4916ce 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3009,16 +3009,18 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, trace_ext4_ext_remove_space_done(inode, start, end, depth, partial_cluster, path->p_hdr->eh_entries); - /* If we still have something in the partial cluster and we have removed + /* + * If we still have something in the partial cluster and we have removed * even the first extent, then we should free the blocks in the partial - * cluster as well. */ - if (partial_cluster > 0 && path->p_hdr->eh_entries == 0) { - int flags = get_default_free_blocks_flags(inode); - + * cluster as well. (This code will only run when there are no leaves + * to the immediate left of the truncated/punched region.) + */ + if (partial_cluster > 0 && err == 0) { + /* don't zero partial_cluster since it's not used afterwards */ ext4_free_blocks(handle, inode, NULL, EXT4_C2B(sbi, partial_cluster), - sbi->s_cluster_ratio, flags); - partial_cluster = 0; + sbi->s_cluster_ratio, + get_default_free_blocks_flags(inode)); } /* TODO: flexible tree reduction should be here */ -- GitLab From acbcc0f03b15585387f9ca69c2a976b02cb69023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Thu, 6 Nov 2014 11:40:30 +0800 Subject: [PATCH 5861/9457] ARM: dts: sunxi: unify APB1 clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the new factors infrastructure in place, we can unify apb1 and apb1_mux as a single clock now. Signed-off-by: Emilio López [wens@csie.org: Change apb1 node label to "apb1"; reword commit title] Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++---------- arch/arm/boot/dts/sun5i-a10s.dtsi | 12 ++---------- arch/arm/boot/dts/sun5i-a13.dtsi | 12 ++---------- arch/arm/boot/dts/sun7i-a20.dtsi | 12 ++---------- 4 files changed, 8 insertions(+), 40 deletions(-) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 380f914b226d..5e2ec2dd8333 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -174,19 +174,11 @@ "apb0_ir1", "apb0_keypad"; }; - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { + apb1: clk@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; clock-output-names = "apb1"; }; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 531272c0e526..d2a85144d2d9 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -162,19 +162,11 @@ "apb0_ir", "apb0_keypad"; }; - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { + apb1: clk@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; clock-output-names = "apb1"; }; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index b131068f4f35..c35217ea1f64 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -161,19 +161,11 @@ clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir"; }; - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { + apb1: clk@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; clock-output-names = "apb1"; }; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 82097c905c48..6d996c9e282a 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -222,19 +222,11 @@ "apb0_iis2", "apb0_keypad"; }; - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { + apb1: clk@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; clock-output-names = "apb1"; }; -- GitLab From 74c947ab33c9ada5a180315ed218a1f61b5ede0c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 6 Nov 2014 11:40:31 +0800 Subject: [PATCH 5862/9457] ARM: dts: sunxi: Use sun4i-a10-apb1-clk for sun6i/sun8i apb2 clocks. The apb2 clocks are actually the same as apb1 clocks on the other sunxi platforms, hence compatible with "allwinner,sun4i-a10-apb1-clk". Update the dtsi to use the new unified apb1 clk. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun6i-a31.dtsi | 12 ++---------- arch/arm/boot/dts/sun8i-a23.dtsi | 12 ++---------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 543f895d18d3..4083201e93c8 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -217,19 +217,11 @@ "apb1_daudio1"; }; - apb2_mux: apb2_mux@01c20058 { + apb2: clk@01c20058 { #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; + compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; - clock-output-names = "apb2_mux"; - }; - - apb2: apb2@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun6i-a31-apb2-div-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb2_mux>; clock-output-names = "apb2"; }; diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 6146ef15efbe..701960e9d033 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -189,19 +189,11 @@ "apb1_daudio0", "apb1_daudio1"; }; - apb2_mux: apb2_mux_clk@01c20058 { + apb2: clk@01c20058 { #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-apb1-mux-clk"; + compatible = "allwinner,sun4i-a10-apb1-clk"; reg = <0x01c20058 0x4>; clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; - clock-output-names = "apb2_mux"; - }; - - apb2: apb2_clk@01c20058 { - #clock-cells = <0>; - compatible = "allwinner,sun6i-a31-apb2-div-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb2_mux>; clock-output-names = "apb2"; }; -- GitLab From eaa2e9804e9cbd0b46f74e39ca6f92e4834547db Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 6 Nov 2014 11:40:32 +0800 Subject: [PATCH 5863/9457] clk: sunxi: Removed unused/incorrect sun6i-a31-apb2-clk driver This driver does not match the hardware, which is actually compatible to sun4i-a10-apb1-clk. Since we've switch to the correct one, drop this driver. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/clock/sunxi.txt | 1 - drivers/clk/sunxi/clk-sunxi.c | 7 ------- 2 files changed, 8 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 6ddcf6e10eb8..d199f9153e04 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -52,7 +52,6 @@ Required properties: "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 "allwinner,sun8i-a23-apb1-gates-clk" - for the APB1 gates on A23 "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 - "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13 diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 4133e278212b..46d98e3b98ba 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -632,12 +632,6 @@ static const struct div_data sun4i_apb0_data __initconst = { .table = sun4i_apb0_table, }; -static const struct div_data sun6i_a31_apb2_div_data __initconst = { - .shift = 0, - .pow = 0, - .width = 4, -}; - static void __init sunxi_divider_clk_setup(struct device_node *node, struct div_data *data) { @@ -1093,7 +1087,6 @@ static const struct of_device_id clk_div_match[] __initconst = { {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, - {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, {} }; -- GitLab From 13d52f61065dcdbea13aae2f0aea6af43a3abf65 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 13 Nov 2014 02:08:30 +0800 Subject: [PATCH 5864/9457] clk: sunxi: Specify number of child clocks for divs clocks Currently sunxi_divs_clk_setup assumes the number of child clocks to be the same as the number of clock-output-names, and a maximum of SUNXI_DIVS_MAX_QTY child clocks. On sun6i, PLL6 only has 1 child clock, but the parent would be used as well, thereby also having it's own clock-output-names entry. This results in an extra bogus clock being registered. This patch adds an entry for the number of child clocks alongside the data structures for them. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sunxi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 46d98e3b98ba..d46949372762 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -906,6 +906,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, struct divs_data { const struct factors_data *factors; /* data for the factor clock */ + int ndivs; /* number of children */ struct { u8 fixed; /* is it a fixed divisor? if not... */ struct clk_div_table *table; /* is it a table based divisor? */ @@ -925,6 +926,7 @@ static struct clk_div_table pll6_sata_tbl[] = { static const struct divs_data pll5_divs_data __initconst = { .factors = &sun4i_pll5_data, + .ndivs = 2, .div = { { .shift = 0, .pow = 0, }, /* M, DDR */ { .shift = 16, .pow = 1, }, /* P, other */ @@ -933,6 +935,7 @@ static const struct divs_data pll5_divs_data __initconst = { static const struct divs_data pll6_divs_data __initconst = { .factors = &sun4i_pll6_data, + .ndivs = 2, .div = { { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ { .fixed = 2 }, /* P, other */ @@ -963,7 +966,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, struct clk_fixed_factor *fix_factor; struct clk_divider *divider; void __iomem *reg; - int i = 0; + int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; int flags, clkflags; /* Set up factor clock that we will be dividing */ @@ -986,7 +989,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, * our RAM clock! */ clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; - for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) { + /* if number of children known, use it */ + if (data->ndivs) + ndivs = data->ndivs; + + for (i = 0; i < ndivs; i++) { if (of_property_read_string_index(node, "clock-output-names", i, &clk_name) != 0) break; -- GitLab From 95e94c1fadcd1959857db45c2e11810a893badd0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 13 Nov 2014 02:08:31 +0800 Subject: [PATCH 5865/9457] clk: sunxi: Implement A31 PLL6 as a divs clock for 2x output Some clock modules on the A31 use PLL6x2 as one of their inputs. This patch changes the PLL6 implementation for A31 to a divs clock, i.e. clock with multiple outputs that have different dividers. The first output will be the normal PLL6 output, and the second will be PLL6x2. This patch fixes the PLL6 N factor in the clock driver, and removes any /2 dividers in the PLL6 factors clock part. The N factor counts from 1 to 32, mapping to values 0 to 31, as shown in the A31 manual. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- .../devicetree/bindings/clock/sunxi.txt | 19 +++++++++++-- drivers/clk/sunxi/clk-sunxi.c | 28 +++++++++++-------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index d199f9153e04..67b2b99f2b33 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -71,8 +71,9 @@ Required properties for all clocks: multiplexed clocks, the list order must match the hardware programming order. - #clock-cells : from common clock binding; shall be set to 0 except for - "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and - "allwinner,sun4i-pll6-clk" where it shall be set to 1 + the following compatibles where it shall be set to 1: + "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk", + "allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk" - clock-output-names : shall be the corresponding names of the outputs. If the clock module only has one output, the name shall be the module name. @@ -87,6 +88,12 @@ Clock consumers should specify the desired clocks they use with a "clocks" phandle cell. Consumers that are using a gated clock should provide an additional ID in their clock property. This ID is the offset of the bit controlling this particular gate in the register. +For the other clocks with "#clock-cells" = 1, the additional ID shall +refer to the index of the output. + +For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output +is the normal PLL6 output, or "pll6". The second output is rate doubled +PLL6, or "pll6x2". For example: @@ -114,6 +121,14 @@ pll5: clk@01c20020 { clock-output-names = "pll5_ddr", "pll5_other"; }; +pll6: clk@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun6i-a31-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6", "pll6x2"; +}; + cpu: cpu@01c20054 { #clock-cells = <0>; compatible = "allwinner,sun4i-a10-cpu-clk"; diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d46949372762..570202582dcf 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -245,9 +245,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, } /** - * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 - * PLL6 rate is calculated as follows - * rate = parent_rate * n * (k + 1) / 2 + * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2 + * PLL6x2 rate is calculated as follows + * rate = parent_rate * (n + 1) * (k + 1) * parent_rate is always 24Mhz */ @@ -256,13 +256,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, { u8 div; - /* - * We always have 24MHz / 2, so we can just say that our - * parent clock is 12MHz. - */ - parent_rate = parent_rate / 2; - - /* Normalize value to a parent_rate multiple (24M / 2) */ + /* Normalize value to a parent_rate multiple (24M) */ div = *freq / parent_rate; *freq = parent_rate * div; @@ -274,7 +268,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, if (*k > 3) *k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + *n = DIV_ROUND_UP(div, (*k+1)) - 1; } /** @@ -445,6 +439,7 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .nwidth = 5, .kshift = 4, .kwidth = 2, + .n_start = 1, }; static struct clk_factors_config sun4i_apb1_config = { @@ -504,6 +499,7 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { .enable = 31, .table = &sun6i_a31_pll6_config, .getter = sun6i_a31_get_pll6_factors, + .name = "pll6x2", }; static const struct factors_data sun4i_apb1_data __initconst = { @@ -942,6 +938,14 @@ static const struct divs_data pll6_divs_data __initconst = { } }; +static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { + .factors = &sun6i_a31_pll6_data, + .ndivs = 1, + .div = { + { .fixed = 2 }, /* normal output */ + } +}; + /** * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks * @@ -1082,7 +1086,6 @@ static const struct of_device_id clk_factors_match[] __initconst = { {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, {} @@ -1101,6 +1104,7 @@ static const struct of_device_id clk_div_match[] __initconst = { static const struct of_device_id clk_divs_match[] __initconst = { {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, + {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, {} }; -- GitLab From c1ec51603053260b138fc98e2ed18a5a9bea4515 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 16 Nov 2014 13:56:57 +0100 Subject: [PATCH 5866/9457] clk: sunxi: gmac-tx-clk mux is not a CLK_MUX_INDEX_BIT mux A CLK_MUX_INDEX_BIT mux has one bit per parent, but the sun7i-a20-gmac-clk has 2 bits selecting between 3 possible parents using values of 0, 1, 2, which makes it a regular mux which should not have CLK_MUX_INDEX_BIT set in its flag. However we do not support parent 1 (an external clock), so use a table to select parent 0 or 2, which are the 2 parents we support. Note this has not been causing any issues sofar, because we start with a parent setting of parent 0, and only ever re-parent to parent 2 (for which we use an index of 1 as we skip parent 1) and with CLK_MUX_INDEX_BIT set we write a value of 2 for index 1. Tested on both a cubietruck (which uses rgmii mode) as well as a cs908 (an a31s board which uses mii mode). Signed-off-by: Hans de Goede Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-a20-gmac.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 5296fd6dd7b3..0dcf4f205fb8 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -53,6 +53,11 @@ static DEFINE_SPINLOCK(gmac_lock); #define SUN7I_A20_GMAC_MASK 0x3 #define SUN7I_A20_GMAC_PARENTS 2 +static u32 sun7i_a20_gmac_mux_table[SUN7I_A20_GMAC_PARENTS] = { + 0x00, /* Select mii_phy_tx_clk */ + 0x02, /* Select gmac_int_tx_clk */ +}; + static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) { struct clk *clk; @@ -90,7 +95,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) gate->lock = &gmac_lock; mux->reg = reg; mux->mask = SUN7I_A20_GMAC_MASK; - mux->flags = CLK_MUX_INDEX_BIT; + mux->table = sun7i_a20_gmac_mux_table; mux->lock = &gmac_lock; clk = clk_register_composite(NULL, clk_name, -- GitLab From 727f9c2dad9dd3e9aff4f64e92df577f1409a768 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Fri, 21 Nov 2014 14:44:32 +0100 Subject: [PATCH 5867/9457] i2c: at91: enable probe deferring on dma channel request If dma controller is not probed, defer i2c probe. Signed-off-by: Ludovic Desroches Reviewed-by: Arnd Bergmann Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 8790f2332458..87e2f142ae6c 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -650,17 +650,17 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) slave_config.dst_maxburst = 1; slave_config.device_fc = false; - dma->chan_tx = dma_request_slave_channel(dev->dev, "tx"); - if (!dma->chan_tx) { - dev_err(dev->dev, "can't get a DMA channel for tx\n"); - ret = -EBUSY; + dma->chan_tx = dma_request_slave_channel_reason(dev->dev, "tx"); + if (IS_ERR(dma->chan_tx)) { + ret = PTR_ERR(dma->chan_tx); + dma->chan_tx = NULL; goto error; } - dma->chan_rx = dma_request_slave_channel(dev->dev, "rx"); - if (!dma->chan_rx) { - dev_err(dev->dev, "can't get a DMA channel for rx\n"); - ret = -EBUSY; + dma->chan_rx = dma_request_slave_channel_reason(dev->dev, "rx"); + if (IS_ERR(dma->chan_rx)) { + ret = PTR_ERR(dma->chan_rx); + dma->chan_rx = NULL; goto error; } @@ -681,6 +681,7 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) sg_init_table(&dma->sg, 1); dma->buf_mapped = false; dma->xfer_in_progress = false; + dev->use_dma = true; dev_info(dev->dev, "using %s (tx) and %s (rx) for DMA transfers\n", dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx)); @@ -688,7 +689,8 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr) return ret; error: - dev_info(dev->dev, "can't use DMA\n"); + if (ret != -EPROBE_DEFER) + dev_info(dev->dev, "can't use DMA, error %d\n", ret); if (dma->chan_rx) dma_release_channel(dma->chan_rx); if (dma->chan_tx) @@ -757,8 +759,9 @@ static int at91_twi_probe(struct platform_device *pdev) clk_prepare_enable(dev->clk); if (dev->dev->of_node) { - if (at91_twi_configure_dma(dev, phy_addr) == 0) - dev->use_dma = true; + rc = at91_twi_configure_dma(dev, phy_addr); + if (rc == -EPROBE_DEFER) + return rc; } rc = of_property_read_u32(dev->dev->of_node, "clock-frequency", -- GitLab From 249051f49907e7d147228a7d27a8ec37da1ea0fa Mon Sep 17 00:00:00 2001 From: Max Schwarz Date: Thu, 20 Nov 2014 10:26:50 +0100 Subject: [PATCH 5868/9457] i2c: rk3x: handle dynamic clock rate changes correctly The i2c input clock can change dynamically, e.g. on the RK3066 where pclk_i2c0 and pclk_i2c1 are connected to the armclk, which changes rate on cpu frequency scaling. Until now, we incorrectly called clk_get_rate() while holding the i2c->lock in rk3x_i2c_xfer() to adapt to clock rate changes. Thanks to Huang Tao for reporting this issue. Do it properly now using the clk notifier framework. The callback logic was taken from i2c-cadence.c. Also rename all misleading "i2c_rate" variables to "clk_rate", as they describe the *input* clk rate. Signed-off-by: Max Schwarz Tested-by: Doug Anderson on RK3288 Reviewed-by: Doug Anderson Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rk3x.c | 153 ++++++++++++++++++++++++++-------- 1 file changed, 118 insertions(+), 35 deletions(-) diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index e276ffbfbd1a..0ee5802f36d3 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -98,6 +98,7 @@ struct rk3x_i2c { /* Hardware resources */ void __iomem *regs; struct clk *clk; + struct notifier_block clk_rate_nb; /* Settings */ unsigned int scl_frequency; @@ -429,15 +430,27 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) return IRQ_HANDLED; } -static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, - unsigned long *div_low, unsigned long *div_high) +/** + * Calculate divider values for desired SCL frequency + * + * @clk_rate: I2C input clock rate + * @scl_rate: Desired SCL rate + * @div_low: Divider output for low + * @div_high: Divider output for high + * + * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case + * a best-effort divider value is returned in divs. If the target rate is + * too high, we silently use the highest possible rate. + */ +static int rk3x_i2c_calc_divs(unsigned long clk_rate, unsigned long scl_rate, + unsigned long *div_low, unsigned long *div_high) { unsigned long min_low_ns, min_high_ns; unsigned long max_data_hold_ns; unsigned long data_hold_buffer_ns; unsigned long max_low_ns, min_total_ns; - unsigned long i2c_rate_khz, scl_rate_khz; + unsigned long clk_rate_khz, scl_rate_khz; unsigned long min_low_div, min_high_div; unsigned long max_low_div; @@ -445,6 +458,8 @@ static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, unsigned long min_div_for_hold, min_total_div; unsigned long extra_div, extra_low_div, ideal_low_div; + int ret = 0; + /* Only support standard-mode and fast-mode */ if (WARN_ON(scl_rate > 400000)) scl_rate = 400000; @@ -480,25 +495,25 @@ static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, min_total_ns = min_low_ns + min_high_ns; /* Adjust to avoid overflow */ - i2c_rate_khz = DIV_ROUND_UP(i2c_rate, 1000); + clk_rate_khz = DIV_ROUND_UP(clk_rate, 1000); scl_rate_khz = scl_rate / 1000; /* * We need the total div to be >= this number * so we don't clock too fast. */ - min_total_div = DIV_ROUND_UP(i2c_rate_khz, scl_rate_khz * 8); + min_total_div = DIV_ROUND_UP(clk_rate_khz, scl_rate_khz * 8); /* These are the min dividers needed for min hold times. */ - min_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, 8 * 1000000); - min_high_div = DIV_ROUND_UP(i2c_rate_khz * min_high_ns, 8 * 1000000); + min_low_div = DIV_ROUND_UP(clk_rate_khz * min_low_ns, 8 * 1000000); + min_high_div = DIV_ROUND_UP(clk_rate_khz * min_high_ns, 8 * 1000000); min_div_for_hold = (min_low_div + min_high_div); /* * This is the maximum divider so we don't go over the max. * We don't round up here (we round down) since this is a max. */ - max_low_div = i2c_rate_khz * max_low_ns / (8 * 1000000); + max_low_div = clk_rate_khz * max_low_ns / (8 * 1000000); if (min_low_div > max_low_div) { WARN_ONCE(true, @@ -526,7 +541,7 @@ static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, * biasing slightly towards having a higher div * for low (spend more time low). */ - ideal_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, + ideal_low_div = DIV_ROUND_UP(clk_rate_khz * min_low_ns, scl_rate_khz * 8 * min_total_ns); /* Don't allow it to go over the max */ @@ -547,40 +562,99 @@ static int rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate, } /* - * Adjust to the fact that the hardware has an implicit "+1". - * NOTE: Above calculations always produce div_low > 0 and div_high > 0. - */ + * Adjust to the fact that the hardware has an implicit "+1". + * NOTE: Above calculations always produce div_low > 0 and div_high > 0. + */ *div_low = *div_low - 1; *div_high = *div_high - 1; - if (*div_low >= 0xffff || *div_high >= 0xffff) - return -EINVAL; - else - return 0; + /* Maximum divider supported by hw is 0xffff */ + if (*div_low > 0xffff) { + *div_low = 0xffff; + ret = -EINVAL; + } + + if (*div_high > 0xffff) { + *div_high = 0xffff; + ret = -EINVAL; + } + + return ret; } -static int rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate) +static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate) { - unsigned long i2c_rate = clk_get_rate(i2c->clk); unsigned long div_low, div_high; u64 t_low_ns, t_high_ns; - int ret = 0; + int ret; - ret = rk3x_i2c_calc_divs(i2c_rate, scl_rate, &div_low, &div_high); - if (ret < 0) - return ret; + ret = rk3x_i2c_calc_divs(clk_rate, i2c->scl_frequency, &div_low, + &div_high); + WARN_ONCE(ret != 0, "Could not reach SCL freq %u", i2c->scl_frequency); + + clk_enable(i2c->clk); i2c_writel(i2c, (div_high << 16) | (div_low & 0xffff), REG_CLKDIV); + clk_disable(i2c->clk); - t_low_ns = div_u64(((u64)div_low + 1) * 8 * 1000000000, i2c_rate); - t_high_ns = div_u64(((u64)div_high + 1) * 8 * 1000000000, i2c_rate); + t_low_ns = div_u64(((u64)div_low + 1) * 8 * 1000000000, clk_rate); + t_high_ns = div_u64(((u64)div_high + 1) * 8 * 1000000000, clk_rate); dev_dbg(i2c->dev, - "CLK %lukhz, Req %luns, Act low %lluns high %lluns\n", - i2c_rate / 1000, - 1000000000 / scl_rate, + "CLK %lukhz, Req %uns, Act low %lluns high %lluns\n", + clk_rate / 1000, + 1000000000 / i2c->scl_frequency, t_low_ns, t_high_ns); +} - return ret; +/** + * rk3x_i2c_clk_notifier_cb - Clock rate change callback + * @nb: Pointer to notifier block + * @event: Notification reason + * @data: Pointer to notification data object + * + * The callback checks whether a valid bus frequency can be generated after the + * change. If so, the change is acknowledged, otherwise the change is aborted. + * New dividers are written to the HW in the pre- or post change notification + * depending on the scaling direction. + * + * Code adapted from i2c-cadence.c. + * + * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK + * to acknowedge the change, NOTIFY_DONE if the notification is + * considered irrelevant. + */ +static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long + event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct rk3x_i2c *i2c = container_of(nb, struct rk3x_i2c, clk_rate_nb); + unsigned long div_low, div_high; + + switch (event) { + case PRE_RATE_CHANGE: + if (rk3x_i2c_calc_divs(ndata->new_rate, i2c->scl_frequency, + &div_low, &div_high) != 0) { + return NOTIFY_STOP; + } + + /* scale up */ + if (ndata->new_rate > ndata->old_rate) + rk3x_i2c_adapt_div(i2c, ndata->new_rate); + + return NOTIFY_OK; + case POST_RATE_CHANGE: + /* scale down */ + if (ndata->new_rate < ndata->old_rate) + rk3x_i2c_adapt_div(i2c, ndata->new_rate); + return NOTIFY_OK; + case ABORT_RATE_CHANGE: + /* scale up */ + if (ndata->new_rate > ndata->old_rate) + rk3x_i2c_adapt_div(i2c, ndata->old_rate); + return NOTIFY_OK; + default: + return NOTIFY_DONE; + } } /** @@ -677,11 +751,6 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap, clk_enable(i2c->clk); - /* The clock rate might have changed, so setup the divider again */ - ret = rk3x_i2c_set_scl_rate(i2c, i2c->scl_frequency); - if (ret < 0) - goto exit; - i2c->is_last_msg = false; /* @@ -728,7 +797,6 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap, } } -exit: clk_disable(i2c->clk); spin_unlock_irqrestore(&i2c->lock, flags); @@ -768,6 +836,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev) int bus_nr; u32 value; int irq; + unsigned long clk_rate; i2c = devm_kzalloc(&pdev->dev, sizeof(struct rk3x_i2c), GFP_KERNEL); if (!i2c) @@ -868,16 +937,28 @@ static int rk3x_i2c_probe(struct platform_device *pdev) return ret; } + i2c->clk_rate_nb.notifier_call = rk3x_i2c_clk_notifier_cb; + ret = clk_notifier_register(i2c->clk, &i2c->clk_rate_nb); + if (ret != 0) { + dev_err(&pdev->dev, "Unable to register clock notifier\n"); + goto err_clk; + } + + clk_rate = clk_get_rate(i2c->clk); + rk3x_i2c_adapt_div(i2c, clk_rate); + ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { dev_err(&pdev->dev, "Could not register adapter\n"); - goto err_clk; + goto err_clk_notifier; } dev_info(&pdev->dev, "Initialized RK3xxx I2C bus at %p\n", i2c->regs); return 0; +err_clk_notifier: + clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb); err_clk: clk_unprepare(i2c->clk); return ret; @@ -888,6 +969,8 @@ static int rk3x_i2c_remove(struct platform_device *pdev) struct rk3x_i2c *i2c = platform_get_drvdata(pdev); i2c_del_adapter(&i2c->adap); + + clk_notifier_unregister(i2c->clk, &i2c->clk_rate_nb); clk_unprepare(i2c->clk); return 0; -- GitLab From 9fd6ada84fd29c8115f2781b48a6ae7c8c4debe2 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Sat, 22 Nov 2014 23:47:11 +0400 Subject: [PATCH 5869/9457] i2c: omap: cleanup register definitions Delete STAT_AD0 mask as unrelated to current IP (omap1?). Delete DEBUG conditional around SYSTEST masks group. Add SYSTEST functional mode masks for SCL and SDA. Add STAT_BF mask. Signed-off-by: Alexander Kochetkov Tested-by: Felipe Balbi Reviewed-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 26942c159de1..5e79c0d294cd 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -98,7 +98,7 @@ enum { #define OMAP_I2C_STAT_ROVR (1 << 11) /* Receive overrun */ #define OMAP_I2C_STAT_XUDF (1 << 10) /* Transmit underflow */ #define OMAP_I2C_STAT_AAS (1 << 9) /* Address as slave */ -#define OMAP_I2C_STAT_AD0 (1 << 8) /* Address zero */ +#define OMAP_I2C_STAT_BF (1 << 8) /* Bus Free */ #define OMAP_I2C_STAT_XRDY (1 << 4) /* Transmit data ready */ #define OMAP_I2C_STAT_RRDY (1 << 3) /* Receive data ready */ #define OMAP_I2C_STAT_ARDY (1 << 2) /* Register access ready */ @@ -146,16 +146,20 @@ enum { #define OMAP_I2C_SCLH_HSSCLH 8 /* I2C System Test Register (OMAP_I2C_SYSTEST): */ -#ifdef DEBUG #define OMAP_I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */ #define OMAP_I2C_SYSTEST_FREE (1 << 14) /* Free running mode */ #define OMAP_I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */ #define OMAP_I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */ +/* Functional mode */ +#define OMAP_I2C_SYSTEST_SCL_I_FUNC (1 << 8) /* SCL line input value */ +#define OMAP_I2C_SYSTEST_SCL_O_FUNC (1 << 7) /* SCL line output value */ +#define OMAP_I2C_SYSTEST_SDA_I_FUNC (1 << 6) /* SDA line input value */ +#define OMAP_I2C_SYSTEST_SDA_O_FUNC (1 << 5) /* SDA line output value */ +/* SDA/SCL IO mode */ #define OMAP_I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense in */ #define OMAP_I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive out */ #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */ #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */ -#endif /* OCP_SYSSTATUS bit definitions */ #define SYSS_RESETDONE_MASK (1 << 0) -- GitLab From 0f5768bf894f853c21e5f336b5f495599172f39b Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Sat, 22 Nov 2014 23:47:12 +0400 Subject: [PATCH 5870/9457] i2c: omap: implement workaround for handling invalid BB-bit values In a multimaster environment, after IP software reset, BB-bit value doesn't correspond to the current bus state. It may happen what BB-bit will be 0, while the bus is busy due to another I2C master activity. Any transfer started when BB=0 and bus is busy wouldn't be completed by IP and results in controller timeout. More over, in some cases IP could interrupt another master's transfer and corrupt data on wire. The commit implement method allowing to prevent IP from entering into "controller timeout" state and from "data corruption" state. The one drawback is the need to wait for 10ms before the first transfer. Tested on Beagleboard XM C. Tested on BBB and AM437x Starter Kit by Felipe Balbi. Signed-off-by: Alexander Kochetkov Tested-by: Felipe Balbi Reviewed-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 103 ++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5e79c0d294cd..4426e9970e8f 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -54,6 +54,9 @@ /* timeout for pm runtime autosuspend */ #define OMAP_I2C_PM_TIMEOUT 1000 /* ms */ +/* timeout for making decision on bus free status */ +#define OMAP_I2C_BUS_FREE_TIMEOUT (msecs_to_jiffies(10)) + /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ enum { OMAP_I2C_REV_REG = 0, @@ -206,6 +209,9 @@ struct omap_i2c_dev { */ u32 rev; unsigned b_hw:1; /* bad h/w fixes */ + unsigned bb_valid:1; /* true when BB-bit reflects + * the I2C bus state + */ unsigned receiver:1; /* true when we're in receiver mode */ u16 iestate; /* Saved interrupt register */ u16 pscstate; @@ -332,7 +338,10 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev) /* SYSC register is cleared by the reset; rewrite it */ omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, sysc); + /* Schedule I2C-bus monitoring on the next transfer */ + dev->bb_valid = 0; } + return 0; } @@ -445,6 +454,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev->scllstate = scll; dev->sclhstate = sclh; + if (dev->rev < OMAP_I2C_OMAP1_REV_2) { + /* Not implemented */ + dev->bb_valid = 1; + } + __omap_i2c_init(dev); return 0; @@ -469,6 +483,91 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev) return 0; } +/* + * Wait while BB-bit doesn't reflect the I2C bus state + * + * In a multimaster environment, after IP software reset, BB-bit value doesn't + * correspond to the current bus state. It may happen what BB-bit will be 0, + * while the bus is busy due to another I2C master activity. + * Here are BB-bit values after reset: + * SDA SCL BB NOTES + * 0 0 0 1, 2 + * 1 0 0 1, 2 + * 0 1 1 + * 1 1 0 3 + * Later, if IP detect SDA=0 and SCL=1 (ACK) or SDA 1->0 while SCL=1 (START) + * combinations on the bus, it set BB-bit to 1. + * If IP detect SDA 0->1 while SCL=1 (STOP) combination on the bus, + * it set BB-bit to 0 and BF to 1. + * BB and BF bits correctly tracks the bus state while IP is suspended + * BB bit became valid on the next FCLK clock after CON_EN bit set + * + * NOTES: + * 1. Any transfer started when BB=0 and bus is busy wouldn't be + * completed by IP and results in controller timeout. + * 2. Any transfer started when BB=0 and SCL=0 results in IP + * starting to drive SDA low. In that case IP corrupt data + * on the bus. + * 3. Any transfer started in the middle of another master's transfer + * results in unpredictable results and data corruption + */ +static int omap_i2c_wait_for_bb_valid(struct omap_i2c_dev *dev) +{ + unsigned long bus_free_timeout = 0; + unsigned long timeout; + int bus_free = 0; + u16 stat, systest; + + if (dev->bb_valid) + return 0; + + timeout = jiffies + OMAP_I2C_TIMEOUT; + while (1) { + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + /* + * We will see BB or BF event in a case IP had detected any + * activity on the I2C bus. Now IP correctly tracks the bus + * state. BB-bit value is valid. + */ + if (stat & (OMAP_I2C_STAT_BB | OMAP_I2C_STAT_BF)) + break; + + /* + * Otherwise, we must look signals on the bus to make + * the right decision. + */ + systest = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG); + if ((systest & OMAP_I2C_SYSTEST_SCL_I_FUNC) && + (systest & OMAP_I2C_SYSTEST_SDA_I_FUNC)) { + if (!bus_free) { + bus_free_timeout = jiffies + + OMAP_I2C_BUS_FREE_TIMEOUT; + bus_free = 1; + } + + /* + * SDA and SCL lines was high for 10 ms without bus + * activity detected. The bus is free. Consider + * BB-bit value is valid. + */ + if (time_after(jiffies, bus_free_timeout)) + break; + } else { + bus_free = 0; + } + + if (time_after(jiffies, timeout)) { + dev_warn(dev->dev, "timeout waiting for bus ready\n"); + return -ETIMEDOUT; + } + + msleep(1); + } + + dev->bb_valid = 1; + return 0; +} + static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) { u16 buf; @@ -639,6 +738,10 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (r < 0) goto out; + r = omap_i2c_wait_for_bb_valid(dev); + if (r < 0) + goto out; + r = omap_i2c_wait_for_bb(dev); if (r < 0) goto out; -- GitLab From b76911d2fe1462e1fc7c449e3e6aef76331e816e Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Sat, 22 Nov 2014 23:47:13 +0400 Subject: [PATCH 5871/9457] i2c: omap: don't reset controller if Arbitration Lost detected Arbitration Lost is an expected situation in a multimaster environment. I2C controller (IP) correctly detect and report AL. The only one visible reason for resetting IP in the AL case is to avoid advisory 1.94 (omap3) and errata i595 (omap4): "I2C: After an Arbitration is Lost the Module Incorrectly Starts the Next Transfer". Errata workaround states: "The MST and STT bits inside I2C_CON should be set to 1 at the same moment (avoid setting the MST bit to 1 while STT = 0)." The driver never set MST and STT bits separately and doesn't create condition for errata. So the reset is not necessary. Also corrected return value for AL to -EAGAIN. Tested on Beagleboard XM C. Tested on BBB and AM437x Starter Kit by Felipe Balbi. Signed-off-by: Alexander Kochetkov Tested-by: Felipe Balbi Reviewed-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4426e9970e8f..b70270d8efdc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -703,13 +703,15 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, return 0; /* We have an error */ - if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | - OMAP_I2C_STAT_XUDF)) { + if (dev->cmd_err & (OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { omap_i2c_reset(dev); __omap_i2c_init(dev); return -EIO; } + if (dev->cmd_err & OMAP_I2C_STAT_AL) + return -EAGAIN; + if (dev->cmd_err & OMAP_I2C_STAT_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return 0; -- GitLab From 4f734a3a0434ef2bb668716ff28ba677fa0dc929 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Sat, 22 Nov 2014 23:47:14 +0400 Subject: [PATCH 5872/9457] i2c: omap: add notes related to i2c multimaster mode No functional changes. Signed-off-by: Alexander Kochetkov Reviewed-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index b70270d8efdc..9f5b57a50c54 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -299,6 +299,12 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) /* Take the I2C module out of reset: */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + /* + * NOTE: right after setting CON_EN, STAT_BB could be 0 while the + * bus is busy. It will be changed to 1 on the next IP FCLK clock. + * udelay(1) will be enough to fix that. + */ + /* * Don't write to this register if the IE state is 0 as it can * cause deadlock. @@ -660,7 +666,11 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (!dev->b_hw && stop) w |= OMAP_I2C_CON_STP; - + /* + * NOTE: STAT_BB bit could became 1 here if another master occupy + * the bus. IP successfully complete transfer when the bus will be + * free again (BB reset to 0). + */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); /* -- GitLab From c274e03af70544506cd7214fcc2d4c4376c2c6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Fri, 21 Nov 2014 22:21:50 +0100 Subject: [PATCH 5873/9457] kvm: x86: move assigned-dev.c and iommu.c to arch/x86/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that ia64 is gone, we can hide deprecated device assignment in x86. Notable changes: - kvm_vm_ioctl_assigned_device() was moved to x86/kvm_arch_vm_ioctl() The easy parts were removed from generic kvm code, remaining - kvm_iommu_(un)map_pages() would require new code to be moved - struct kvm_assigned_dev_kernel depends on struct kvm_irq_ack_notifier Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 23 +++++++++++++++++++++++ arch/x86/kvm/Makefile | 2 +- {virt => arch/x86}/kvm/assigned-dev.c | 0 {virt => arch/x86}/kvm/iommu.c | 0 arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h | 26 -------------------------- virt/kvm/kvm_main.c | 2 -- 7 files changed, 25 insertions(+), 30 deletions(-) rename {virt => arch/x86}/kvm/assigned-dev.c (100%) rename {virt => arch/x86}/kvm/iommu.c (100%) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 76ff3e2d8fd2..d549cf8bfb69 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1112,4 +1112,27 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data); void kvm_handle_pmu_event(struct kvm_vcpu *vcpu); void kvm_deliver_pmi(struct kvm_vcpu *vcpu); +#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT +int kvm_iommu_map_guest(struct kvm *kvm); +int kvm_iommu_unmap_guest(struct kvm *kvm); + +long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, + unsigned long arg); + +void kvm_free_all_assigned_devices(struct kvm *kvm); +#else +static inline int kvm_iommu_unmap_guest(struct kvm *kvm) +{ + return 0; +} + +static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, + unsigned long arg) +{ + return -ENOTTY; +} + +static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} +#endif + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index ee1cd92b03be..08f790dfadc9 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -9,11 +9,11 @@ KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o -kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(KVM)/assigned-dev.o $(KVM)/iommu.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ i8254.o ioapic.o irq_comm.o cpuid.o pmu.o +kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += assigned-dev.o iommu.o kvm-intel-y += vmx.o kvm-amd-y += svm.o diff --git a/virt/kvm/assigned-dev.c b/arch/x86/kvm/assigned-dev.c similarity index 100% rename from virt/kvm/assigned-dev.c rename to arch/x86/kvm/assigned-dev.c diff --git a/virt/kvm/iommu.c b/arch/x86/kvm/iommu.c similarity index 100% rename from virt/kvm/iommu.c rename to arch/x86/kvm/iommu.c diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5337039427c8..782e4eaf4561 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4007,7 +4007,7 @@ long kvm_arch_vm_ioctl(struct file *filp, } default: - ; + r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg); } out: return r; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ded64cb3a081..aa56894ce839 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -764,8 +764,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); -int kvm_iommu_map_guest(struct kvm *kvm); -int kvm_iommu_unmap_guest(struct kvm *kvm); int kvm_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev); int kvm_deassign_device(struct kvm *kvm, @@ -781,11 +779,6 @@ static inline void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot) { } - -static inline int kvm_iommu_unmap_guest(struct kvm *kvm) -{ - return 0; -} #endif static inline void kvm_guest_enter(void) @@ -1005,25 +998,6 @@ static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; } #endif -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT - -long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, - unsigned long arg); - -void kvm_free_all_assigned_devices(struct kvm *kvm); - -#else - -static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, - unsigned long arg) -{ - return -ENOTTY; -} - -static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} - -#endif - static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) { set_bit(req, &vcpu->requests); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3be43424818b..5b4533079eaa 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2582,8 +2582,6 @@ static long kvm_vm_ioctl(struct file *filp, break; default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); - if (r == -ENOTTY) - r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg); } out: return r; -- GitLab From b65d6e17fe2239c9b2051727903955d922083fbf Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 21 Nov 2014 18:13:26 +0100 Subject: [PATCH 5874/9457] kvm: x86: mask out XSAVES This feature is not supported inside KVM guests yet, because we do not emulate MSR_IA32_XSS. Mask it out. Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 20d83217fb1d..a4f5ac46226c 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -320,6 +320,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) | F(AVX512CD); + /* cpuid 0xD.1.eax */ + const u32 kvm_supported_word10_x86_features = + F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1); + /* all calls to cpuid_count() should be made on the same cpu */ get_cpu(); @@ -456,13 +460,18 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->eax &= supported; entry->edx &= supported >> 32; entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + if (!supported) + break; + for (idx = 1, i = 1; idx < 64; ++idx) { u64 mask = ((u64)1 << idx); if (*nent >= maxnent) goto out; do_cpuid_1_ent(&entry[i], function, idx); - if (entry[i].eax == 0 || !(supported & mask)) + if (idx == 1) + entry[i].eax &= kvm_supported_word10_x86_features; + else if (entry[i].eax == 0 || !(supported & mask)) continue; entry[i].flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; -- GitLab From 66dc527296d8b3061cb7368927b5233f886c6f83 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Tue, 2 Sep 2014 17:55:40 +0300 Subject: [PATCH 5875/9457] iwlwifi: mvm: Insert DS Parameter Set placeholder in probes Since it's too complicated for the fw to insert a DS Parameter Set element in the middle of the frame, it was decided that it should be done by the host. The fw will only parse the frame and update the current channel field. Signed-off-by: Andrei Otcheretianski Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw.h | 4 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 53 ++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 6f7ae5f7bdae..598065b053de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -148,8 +148,8 @@ enum iwl_ucode_tlv_api { * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current * tx power value into TPC Report action frame and Link Measurement Report * action frame - * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports adding DS params - * element in probe requests. + * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports updating current + * channel in DS parameter set element in probe requests. * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in * probe requests. * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index fb2a8628b8fc..8a1f4a8e80e7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -366,6 +366,10 @@ static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm, !is_sched_scan) max_probe_len -= 32; + /* DS parameter set element is added on 2.4GHZ band if required */ + if (iwl_mvm_rrm_scan_needed(mvm)) + max_probe_len -= 3; + return max_probe_len; } @@ -1155,6 +1159,42 @@ iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm, } } +static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies, + size_t len, u8 *const pos) +{ + static const u8 before_ds_params[] = { + WLAN_EID_SSID, + WLAN_EID_SUPP_RATES, + WLAN_EID_REQUEST, + WLAN_EID_EXT_SUPP_RATES, + }; + size_t offs; + u8 *newpos = pos; + + if (!iwl_mvm_rrm_scan_needed(mvm)) { + memcpy(newpos, ies, len); + return newpos + len; + } + + offs = ieee80211_ie_split(ies, len, + before_ds_params, + ARRAY_SIZE(before_ds_params), + 0); + + memcpy(newpos, ies, offs); + newpos += offs; + + /* Add a placeholder for DS Parameter Set element */ + *newpos++ = WLAN_EID_DS_PARAMS; + *newpos++ = 1; + *newpos++ = 0; + + memcpy(newpos, ies + offs, len - offs); + newpos += len - offs; + + return newpos; +} + static void iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_scan_ies *ies, @@ -1164,7 +1204,7 @@ iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, sizeof(struct iwl_scan_channel_cfg_lmac) * mvm->fw->ucode_capa.n_scan_channels); struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf; - u8 *pos; + u8 *pos, *newpos; frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); eth_broadcast_addr(frame->da); @@ -1179,11 +1219,14 @@ iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, preq->mac_header.offset = 0; preq->mac_header.len = cpu_to_le16(24 + 2); - memcpy(pos, ies->ies[IEEE80211_BAND_2GHZ], - ies->len[IEEE80211_BAND_2GHZ]); + /* Insert ds parameter set element on 2.4 GHz band */ + newpos = iwl_mvm_copy_and_insert_ds_elem(mvm, + ies->ies[IEEE80211_BAND_2GHZ], + ies->len[IEEE80211_BAND_2GHZ], + pos); preq->band_data[0].offset = cpu_to_le16(pos - preq->buf); - preq->band_data[0].len = cpu_to_le16(ies->len[IEEE80211_BAND_2GHZ]); - pos += ies->len[IEEE80211_BAND_2GHZ]; + preq->band_data[0].len = cpu_to_le16(newpos - pos); + pos = newpos; memcpy(pos, ies->ies[IEEE80211_BAND_5GHZ], ies->len[IEEE80211_BAND_5GHZ]); -- GitLab From c064ddf318aa51647a30108f7cd151c208c62eef Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Tue, 30 Sep 2014 06:42:06 +0200 Subject: [PATCH 5876/9457] iwlwifi: change max HT and VHT A-MPDU exponent Add two new parameters to iwl_cfg: max_ht_ampdu_exponent and max_vht_ampdu_exponent. These parameters, if set, will set new values to the maximum of HT and VHT A-MPDU exponent for the A-MPDU length exponent. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-7000.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-8000.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-config.h | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 2 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 5 ++++- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index b04b8858c690..b4e9bc7cc929 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -132,8 +132,8 @@ static const struct iwl_ht_params iwl7000_ht_params = { .base_params = &iwl7000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \ - .non_shared_ant = ANT_A - + .non_shared_ant = ANT_A, \ + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl7260_2ac_cfg = { .name = "Intel(R) Dual Band Wireless AC 7260", diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 896ea906549c..091975905cb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -91,6 +91,10 @@ /* Max SDIO RX aggregation size of the ADDBA request/response */ #define MAX_RX_AGG_SIZE_8260_SDIO 28 +/* Max A-MPDU exponent for HT and VHT */ +#define MAX_HT_AMPDU_EXPONENT_8260_SDIO IEEE80211_HT_MAX_AMPDU_32K +#define MAX_VHT_AMPDU_EXPONENT_8260_SDIO IEEE80211_VHT_MAX_AMPDU_32K + static const struct iwl_base_params iwl8000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000, .num_of_queues = IWLAGN_NUM_QUEUES, @@ -137,6 +141,7 @@ const struct iwl_cfg iwl8260_2ac_cfg = { .ht_params = &iwl8000_ht_params, .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, }; const struct iwl_cfg iwl8260_2ac_sdio_cfg = { @@ -149,6 +154,8 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, .disable_dummy_notification = true, + .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, + .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, }; MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index f8aa9cf08279..c6ae4d4ec202 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -257,6 +257,10 @@ struct iwl_pwr_tx_backoff { * @pwr_tx_backoffs: translation table between power limits and backoffs * @max_rx_agg_size: max RX aggregation size of the ADDBA request/response * @max_tx_agg_size: max TX aggregation size of the ADDBA request/response + * @max_ht_ampdu_factor: the exponent of the max length of A-MPDU that the + * station can receive in HT + * @max_vht_ampdu_exponent: the exponent of the max length of A-MPDU that the + * station can receive in VHT * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -297,6 +301,8 @@ struct iwl_cfg { unsigned int max_rx_agg_size; bool disable_dummy_notification; unsigned int max_tx_agg_size; + unsigned int max_ht_ampdu_exponent; + unsigned int max_vht_ampdu_exponent; }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 74b796dc4242..41ff85de7334 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -764,7 +764,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, if (iwlwifi_mod_params.amsdu_size_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; - ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_info->ampdu_factor = cfg->max_ht_ampdu_exponent; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; ht_info->mcs.rx_mask[0] = 0xFF; diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index c302e7468559..06e02fcd6f7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -325,6 +325,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, { int num_rx_ants = num_of_ant(rx_chains); int num_tx_ants = num_of_ant(tx_chains); + unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?: + IEEE80211_VHT_MAX_AMPDU_1024K); vht_cap->vht_supported = true; @@ -332,7 +334,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, IEEE80211_VHT_CAP_RXSTBC_1 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | - 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + max_ampdu_exponent << + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; if (cfg->ht_params->ldpc) vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; -- GitLab From 9b5452fd77c337391e090b1bf2f7036a0b89fd39 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 7 Oct 2014 10:38:53 +0300 Subject: [PATCH 5877/9457] iwlwifi: mvm: add support for WMM Access Control After the corresponding mac80211 patch, we can now report the airtime used for each transmitted packet and mac80211 will be able to implement WMM-AC with that information. To support WMM-AC in the driver then, report the airtime and advertise support. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/sta.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/tx.c | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 92e1810864b1..19aff50648ef 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -423,7 +423,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) NL80211_FEATURE_LOW_PRIORITY_SCAN | NL80211_FEATURE_P2P_GO_OPPPS | NL80211_FEATURE_DYNAMIC_SMPS | - NL80211_FEATURE_STATIC_SMPS; + NL80211_FEATURE_STATIC_SMPS | + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION; if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index d9c0d7b0e9d4..84f37ca9398a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -264,6 +264,7 @@ enum iwl_mvm_agg_state { * the first packet to be sent in legacy HW queue in Tx AGG stop flow. * Basically when next_reclaimed reaches ssn, we can tell mac80211 that * we are ready to finish the Tx AGG stop / start flow. + * @tx_time: medium time consumed by this A-MPDU */ struct iwl_mvm_tid_data { u16 seq_number; @@ -274,6 +275,7 @@ struct iwl_mvm_tid_data { enum iwl_mvm_agg_state state; u16 txq_id; u16 ssn; + u16 tx_time; }; static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data) diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 4789c77632e5..b54708e4d29c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -658,6 +658,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, seq_ctl = le16_to_cpu(hdr->seq_ctrl); } + /* + * TODO: this is not accurate if we are freeing more than one + * packet. + */ + info->status.tx_time = + le16_to_cpu(tx_resp->wireless_media_time); BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1); info->status.status_driver_data[0] = (void *)(uintptr_t)tx_resp->reduced_tpc; @@ -850,6 +856,8 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, mvmsta->tid_data[tid].rate_n_flags = le32_to_cpu(tx_resp->initial_rate); mvmsta->tid_data[tid].reduced_tpc = tx_resp->reduced_tpc; + mvmsta->tid_data[tid].tx_time = + le16_to_cpu(tx_resp->wireless_media_time); } rcu_read_unlock(); @@ -878,6 +886,8 @@ static void iwl_mvm_tx_info_from_ba_notif(struct ieee80211_tx_info *info, info->status.ampdu_len = ba_notif->txed; iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags, info); + /* TODO: not accounted if the whole A-MPDU failed */ + info->status.tx_time = tid_data->tx_time; info->status.status_driver_data[0] = (void *)(uintptr_t)tid_data->reduced_tpc; } -- GitLab From 088070a2f6575402d3dd82e1c5a4a8e1941805f6 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 20 Oct 2014 18:42:58 +0300 Subject: [PATCH 5878/9457] iwlwifi: mvm: move deferred d0i3 exit to resume_complete op The deferred d0i3 exit is currently implemented in the resume op, which is called when mac80211 starts its resume process. However, mac80211 still doesn't handle frames at this stage, which results in frames being dropped. Move the deferred d0i3 handling to the reconfig_complete callback, in order to make sure mac80211 is fully available at this point. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 12 +----------- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index b61075b567ad..faa7d5c365d5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1659,18 +1659,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - if (iwl_mvm_is_d0i3_supported(mvm)) { - bool exit_now; - - mutex_lock(&mvm->d0i3_suspend_mutex); - __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); - exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP, - &mvm->d0i3_suspend_flags); - mutex_unlock(&mvm->d0i3_suspend_mutex); - if (exit_now) - _iwl_mvm_exit_d0i3(mvm); + if (iwl_mvm_is_d0i3_supported(mvm)) return 0; - } return __iwl_mvm_resume(mvm, false); } diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 19aff50648ef..e3259b61b9e8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -941,6 +941,25 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) mutex_unlock(&mvm->mutex); } +static void iwl_mvm_resume_complete(struct iwl_mvm *mvm) +{ + bool exit_now; + + if (!iwl_mvm_is_d0i3_supported(mvm)) + return; + + mutex_lock(&mvm->d0i3_suspend_mutex); + __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); + exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP, + &mvm->d0i3_suspend_flags); + mutex_unlock(&mvm->d0i3_suspend_mutex); + + if (exit_now) { + IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n"); + _iwl_mvm_exit_d0i3(mvm); + } +} + static void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) @@ -952,6 +971,7 @@ iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, iwl_mvm_restart_complete(mvm); break; case IEEE80211_RECONFIG_TYPE_SUSPEND: + iwl_mvm_resume_complete(mvm); break; } } -- GitLab From 886ca9f5dd1129df2ca31ab2f43299658568cbbe Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Thu, 2 Oct 2014 19:46:16 +0200 Subject: [PATCH 5879/9457] iwlwifi: mvm: New skip over dtim policy Our firmware scheduler suffers from false wake-up on 500 time units. that is if the dtim interval exceeds 500 time units, the fw wakes up, understands that the next wake-up event is still ahead, and if this event is more than 10msec in the future - goes back to sleep, otherwise - stay awake. For example, say that the beacon interval is 101 and the dtim period is 5, the dtim interval is 101 x 5 = 505, and we will stay awake for those extra 5msec. So on the one hand the dtim interval should be congruent to the beacon interval times the dtim period, and on the other should minimize the false wake-ups event. This change applies only to D0/D3 power modes. Signed-off-by: Avri Altman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/power.c | 35 ++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5b85b0cc7a2a..cb653ac10412 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -286,6 +286,27 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm, return true; } +static int iwl_mvm_power_get_skip_over_dtim(int dtimper, int bi) +{ + int numerator; + int dtim_interval = dtimper * bi; + + if (WARN_ON(!dtim_interval)) + return 0; + + if (dtimper == 1) { + if (bi > 100) + numerator = 408; + else + numerator = 510; + } else if (dtimper < 10) { + numerator = 612; + } else { + return 0; + } + return max(1, (numerator / dtim_interval)); +} + static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) { struct ieee80211_chanctx_conf *chanctx_conf; @@ -308,7 +329,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mac_power_cmd *cmd) { - int dtimper, dtimper_msec; + int dtimper, dtimper_msec, bi; int keep_alive; bool radar_detect = false; struct iwl_mvm_vif *mvmvif __maybe_unused = @@ -317,6 +338,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); dtimper = vif->bss_conf.dtim_period; + bi = vif->bss_conf.beacon_int; /* * Regardless of power management state the driver must set @@ -324,7 +346,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, * immediately after association. Check that keep alive period * is at least 3 * DTIM */ - dtimper_msec = dtimper * vif->bss_conf.beacon_int; + dtimper_msec = dtimper * bi; keep_alive = max_t(int, 3 * dtimper_msec, MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); @@ -352,11 +374,14 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, radar_detect = iwl_mvm_power_is_radar(vif); /* Check skip over DTIM conditions */ - if (!radar_detect && (dtimper <= 10) && + if (!radar_detect && (dtimper < 10) && (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP || mvm->cur_ucode == IWL_UCODE_WOWLAN)) { - cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); - cmd->skip_dtim_periods = 3; + cmd->skip_dtim_periods = + iwl_mvm_power_get_skip_over_dtim(dtimper, bi); + if (cmd->skip_dtim_periods) + cmd->flags |= + cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); } if (mvm->cur_ucode != IWL_UCODE_WOWLAN) { -- GitLab From 5387b348b7af299c2aa8e0318498fa7d889da4fd Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Tue, 11 Nov 2014 07:29:59 +0200 Subject: [PATCH 5880/9457] iwlwifi: mvm: Fix the keep_alive calculation The driver must set the keep alive period regardless of power management state. The keep alive period must be greater or equal to both the NIC's maximum sleep period, and the listen interval. However, we were confusing time units (TU) and msec, so fix that. Signed-off-by: Avri Altman Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/power.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index cb653ac10412..2620dd0c45f9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -329,7 +329,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mac_power_cmd *cmd) { - int dtimper, dtimper_msec, bi; + int dtimper, bi; int keep_alive; bool radar_detect = false; struct iwl_mvm_vif *mvmvif __maybe_unused = @@ -346,10 +346,9 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, * immediately after association. Check that keep alive period * is at least 3 * DTIM */ - dtimper_msec = dtimper * bi; - keep_alive = max_t(int, 3 * dtimper_msec, - MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); - keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); + keep_alive = DIV_ROUND_UP(ieee80211_tu_to_usec(3 * dtimper * bi), + USEC_PER_SEC); + keep_alive = max(keep_alive, POWER_KEEP_ALIVE_PERIOD_SEC); cmd->keep_alive_seconds = cpu_to_le16(keep_alive); if (mvm->ps_disabled) -- GitLab From d24962214dd5930aa713213654721fe1fd7ed844 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Tue, 20 May 2014 12:46:37 +0300 Subject: [PATCH 5881/9457] iwlwifi: mvm: implement UMAC scan API This API uses second CPU scan commands, and can support multiple simultaneous scans. Adding the new API, and adding new mechanisms to deal with up to 8 simultaneous scans instead of the old scan status. New scan API requires scan configuration for default scan parameters, adding it in _up flow. Also updating scan configuration after updating valid scan antennas via debugfs. Signed-off-by: David Spinadel Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 + drivers/net/wireless/iwlwifi/mvm/debugfs.c | 6 +- .../net/wireless/iwlwifi/mvm/fw-api-scan.h | 253 +++++++ drivers/net/wireless/iwlwifi/mvm/fw-api.h | 6 + drivers/net/wireless/iwlwifi/mvm/fw.c | 6 + drivers/net/wireless/iwlwifi/mvm/mac80211.c | 25 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 16 + drivers/net/wireless/iwlwifi/mvm/ops.c | 17 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 669 +++++++++++++++++- 9 files changed, 942 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 598065b053de..133022a7bf6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -145,6 +145,7 @@ enum iwl_ucode_tlv_api { /** * enum iwl_ucode_tlv_capa - ucode capabilities * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3 + * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan. * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current * tx power value into TPC Report action frame and Link Measurement Report * action frame @@ -158,6 +159,7 @@ enum iwl_ucode_tlv_api { */ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), + IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2), IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8), IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9), IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10), diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 51b7116965ed..8212b00096f9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -936,7 +936,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf, if (scan_rx_ant & ~mvm->fw->valid_rx_ant) return -EINVAL; - mvm->scan_rx_ant = scan_rx_ant; + if (mvm->scan_rx_ant != scan_rx_ant) { + mvm->scan_rx_ant = scan_rx_ant; + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + iwl_mvm_config_scan(mvm); + } return count; } diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 1354c68f6468..7163eb391826 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -794,4 +794,257 @@ struct iwl_periodic_scan_complete { __le32 reserved; } __packed; +/* UMAC Scan API */ + +/** + * struct iwl_mvm_umac_cmd_hdr - Command header for UMAC commands + * @size: size of the command (not including header) + * @reserved0: for future use and alignment + * @ver: API version number + */ +struct iwl_mvm_umac_cmd_hdr { + __le16 size; + u8 reserved0; + u8 ver; +} __packed; + +#define IWL_MVM_MAX_SIMULTANEOUS_SCANS 8 + +enum scan_config_flags { + SCAN_CONFIG_FLAG_ACTIVATE = BIT(0), + SCAN_CONFIG_FLAG_DEACTIVATE = BIT(1), + SCAN_CONFIG_FLAG_FORBID_CHUB_REQS = BIT(2), + SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS = BIT(3), + SCAN_CONFIG_FLAG_SET_TX_CHAINS = BIT(8), + SCAN_CONFIG_FLAG_SET_RX_CHAINS = BIT(9), + SCAN_CONFIG_FLAG_SET_AUX_STA_ID = BIT(10), + SCAN_CONFIG_FLAG_SET_ALL_TIMES = BIT(11), + SCAN_CONFIG_FLAG_SET_EFFECTIVE_TIMES = BIT(12), + SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS = BIT(13), + SCAN_CONFIG_FLAG_SET_LEGACY_RATES = BIT(14), + SCAN_CONFIG_FLAG_SET_MAC_ADDR = BIT(15), + SCAN_CONFIG_FLAG_SET_FRAGMENTED = BIT(16), + SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED = BIT(17), + SCAN_CONFIG_FLAG_SET_CAM_MODE = BIT(18), + SCAN_CONFIG_FLAG_CLEAR_CAM_MODE = BIT(19), + SCAN_CONFIG_FLAG_SET_PROMISC_MODE = BIT(20), + SCAN_CONFIG_FLAG_CLEAR_PROMISC_MODE = BIT(21), + + /* Bits 26-31 are for num of channels in channel_array */ +#define SCAN_CONFIG_N_CHANNELS(n) ((n) << 26) +}; + +enum scan_config_rates { + /* OFDM basic rates */ + SCAN_CONFIG_RATE_6M = BIT(0), + SCAN_CONFIG_RATE_9M = BIT(1), + SCAN_CONFIG_RATE_12M = BIT(2), + SCAN_CONFIG_RATE_18M = BIT(3), + SCAN_CONFIG_RATE_24M = BIT(4), + SCAN_CONFIG_RATE_36M = BIT(5), + SCAN_CONFIG_RATE_48M = BIT(6), + SCAN_CONFIG_RATE_54M = BIT(7), + /* CCK basic rates */ + SCAN_CONFIG_RATE_1M = BIT(8), + SCAN_CONFIG_RATE_2M = BIT(9), + SCAN_CONFIG_RATE_5M = BIT(10), + SCAN_CONFIG_RATE_11M = BIT(11), + + /* Bits 16-27 are for supported rates */ +#define SCAN_CONFIG_SUPPORTED_RATE(rate) ((rate) << 16) +}; + +enum iwl_channel_flags { + IWL_CHANNEL_FLAG_EBS = BIT(0), + IWL_CHANNEL_FLAG_ACCURATE_EBS = BIT(1), + IWL_CHANNEL_FLAG_EBS_ADD = BIT(2), + IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE = BIT(3), +}; + +/** + * struct iwl_scan_config + * @hdr: umac command header + * @flags: enum scan_config_flags + * @tx_chains: valid_tx antenna - ANT_* definitions + * @rx_chains: valid_rx antenna - ANT_* definitions + * @legacy_rates: default legacy rates - enum scan_config_rates + * @out_of_channel_time: default max out of serving channel time + * @suspend_time: default max suspend time + * @dwell_active: default dwell time for active scan + * @dwell_passive: default dwell time for passive scan + * @dwell_fragmented: default dwell time for fragmented scan + * @reserved: for future use and alignment + * @mac_addr: default mac address to be used in probes + * @bcast_sta_id: the index of the station in the fw + * @channel_flags: default channel flags - enum iwl_channel_flags + * scan_config_channel_flag + * @channel_array: default supported channels + */ +struct iwl_scan_config { + struct iwl_mvm_umac_cmd_hdr hdr; + __le32 flags; + __le32 tx_chains; + __le32 rx_chains; + __le32 legacy_rates; + __le32 out_of_channel_time; + __le32 suspend_time; + u8 dwell_active; + u8 dwell_passive; + u8 dwell_fragmented; + u8 reserved; + u8 mac_addr[ETH_ALEN]; + u8 bcast_sta_id; + u8 channel_flags; + u8 channel_array[]; +} __packed; /* SCAN_CONFIG_DB_CMD_API_S */ + +/** + * iwl_umac_scan_flags + *@IWL_UMAC_SCAN_FLAG_PREEMPTIVE: scan process triggered by this scan request + * can be preempted by other scan requests with higher priority. + * The low priority scan is aborted. + *@IWL_UMAC_SCAN_FLAG_START_NOTIF: notification will be sent to the driver + * when scan starts. + */ +enum iwl_umac_scan_flags { + IWL_UMAC_SCAN_FLAG_PREEMPTIVE = BIT(0), + IWL_UMAC_SCAN_FLAG_START_NOTIF = BIT(1), +}; + +enum iwl_umac_scan_uid_offsets { + IWL_UMAC_SCAN_UID_TYPE_OFFSET = 0, + IWL_UMAC_SCAN_UID_SEQ_OFFSET = 8, +}; + +enum iwl_umac_scan_general_flags { + IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC = BIT(0), + IWL_UMAC_SCAN_GEN_FLAGS_OVER_BT = BIT(1), + IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL = BIT(2), + IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE = BIT(3), + IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT = BIT(4), + IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE = BIT(5), + IWL_UMAC_SCAN_GEN_FLAGS_MULTIPLE_SSID = BIT(6), + IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED = BIT(7), + IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED = BIT(8), + IWL_UMAC_SCAN_GEN_FLAGS_MATCH = BIT(9) +}; + +/** + * struct iwl_scan_channel_cfg_umac + * @flags: bitmap - 0-19: directed scan to i'th ssid. + * @channel_num: channel number 1-13 etc. + * @iter_count: repetition count for the channel. + * @iter_interval: interval between two scan interations on one channel. + */ +struct iwl_scan_channel_cfg_umac { + __le32 flags; + u8 channel_num; + u8 iter_count; + __le16 iter_interval; +} __packed; /* SCAN_CHANNEL_CFG_S_VER2 */ + +/** + * struct iwl_scan_umac_schedule + * @interval: interval in seconds between scan iterations + * @iter_count: num of scan iterations for schedule plan, 0xff for infinite loop + * @reserved: for alignment and future use + */ +struct iwl_scan_umac_schedule { + __le16 interval; + u8 iter_count; + u8 reserved; +} __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */ + +/** + * struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command + * parameters following channels configuration array. + * @schedule: two scheduling plans. + * @delay: delay in TUs before starting the first scan iteration + * @reserved: for future use and alignment + * @preq: probe request with IEs blocks + * @direct_scan: list of SSIDs for directed active scan + */ +struct iwl_scan_req_umac_tail { + /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ + struct iwl_scan_umac_schedule schedule[2]; + __le16 delay; + __le16 reserved; + /* SCAN_PROBE_PARAMS_API_S_VER_1 */ + struct iwl_scan_probe_req preq; + struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; +} __packed; + +/** + * struct iwl_scan_req_umac + * @hdr: umac command header + * @flags: &enum iwl_umac_scan_flags + * @uid: scan id, &enum iwl_umac_scan_uid_offsets + * @ooc_priority: out of channel priority - &enum iwl_scan_priority + * @general_flags: &enum iwl_umac_scan_general_flags + * @reserved1: for future use and alignment + * @active_dwell: dwell time for active scan + * @passive_dwell: dwell time for passive scan + * @fragmented_dwell: dwell time for fragmented passive scan + * @max_out_time: max out of serving channel time + * @suspend_time: max suspend time + * @scan_priority: scan internal prioritization &enum iwl_scan_priority + * @channel_flags: &enum iwl_scan_channel_flags + * @n_channels: num of channels in scan request + * @reserved2: for future use and alignment + * @data: &struct iwl_scan_channel_cfg_umac and + * &struct iwl_scan_req_umac_tail + */ +struct iwl_scan_req_umac { + struct iwl_mvm_umac_cmd_hdr hdr; + __le32 flags; + __le32 uid; + __le32 ooc_priority; + /* SCAN_GENERAL_PARAMS_API_S_VER_1 */ + __le32 general_flags; + u8 reserved1; + u8 active_dwell; + u8 passive_dwell; + u8 fragmented_dwell; + __le32 max_out_time; + __le32 suspend_time; + __le32 scan_priority; + /* SCAN_CHANNEL_PARAMS_API_S_VER_1 */ + u8 channel_flags; + u8 n_channels; + __le16 reserved2; + u8 data[]; +} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */ + +/** + * struct iwl_umac_scan_abort + * @hdr: umac command header + * @uid: scan id, &enum iwl_umac_scan_uid_offsets + * @flags: reserved + */ +struct iwl_umac_scan_abort { + struct iwl_mvm_umac_cmd_hdr hdr; + __le32 uid; + __le32 flags; +} __packed; /* SCAN_ABORT_CMD_UMAC_API_S_VER_1 */ + +/** + * struct iwl_umac_scan_complete + * @uid: scan id, &enum iwl_umac_scan_uid_offsets + * @last_schedule: last scheduling line + * @last_iter: last scan iteration number + * @scan status: &enum iwl_scan_offload_complete_status + * @ebs_status: &enum iwl_scan_ebs_status + * @time_from_last_iter: time elapsed from last iteration + * @reserved: for future use + */ +struct iwl_umac_scan_complete { + __le32 uid; + u8 last_schedule; + u8 last_iter; + u8 status; + u8 ebs_status; + __le32 time_from_last_iter; + __le32 reserved; +} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */ + #endif diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index c62575d86bcd..1a67788e55f5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -106,6 +106,12 @@ enum { DBG_CFG = 0x9, ANTENNA_COUPLING_NOTIFICATION = 0xa, + /* UMAC scan commands */ + SCAN_CFG_CMD = 0xc, + SCAN_REQ_UMAC = 0xd, + SCAN_ABORT_UMAC = 0xe, + SCAN_COMPLETE_UMAC = 0xf, + /* station table */ ADD_STA_KEY = 0x17, ADD_STA = 0x18, diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index f12b43d65f66..b4f244f510ed 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -505,6 +505,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { + ret = iwl_mvm_config_scan(mvm); + if (ret) + goto error; + } + /* allow FW/transport low power modes if not during restart */ if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e3259b61b9e8..79ad6958255c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -343,7 +343,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; } - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || + mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; hw->sta_data_size = sizeof(struct iwl_mvm_sta); @@ -1935,9 +1936,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, req->n_channels > mvm->fw->ucode_capa.n_scan_channels) return -EINVAL; - ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED); - if (ret) - return ret; + if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { + ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED); + if (ret) + return ret; + } mutex_lock(&mvm->mutex); @@ -1950,6 +1953,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req); + else if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + ret = iwl_mvm_scan_umac(mvm, vif, hw_req); else ret = iwl_mvm_scan_request(mvm, vif, req); @@ -2247,9 +2252,11 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; - ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS); - if (ret) - return ret; + if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { + ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS); + if (ret) + return ret; + } mutex_lock(&mvm->mutex); @@ -2269,11 +2276,10 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, goto out; } - mvm->scan_status = IWL_MVM_SCAN_SCHED; - ret = iwl_mvm_scan_offload_start(mvm, vif, req, ies); if (ret) mvm->scan_status = IWL_MVM_SCAN_NONE; + out: mutex_unlock(&mvm->mutex); return ret; @@ -2291,6 +2297,7 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, iwl_mvm_wait_for_async_handlers(mvm); return ret; + } static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 09b49b407a5b..cbfba80a0e2f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -588,6 +588,10 @@ struct iwl_mvm { void *scan_cmd; struct iwl_mcast_filter_cmd *mcast_filter_cmd; + /* UMAC scan tracking */ + u32 scan_uid[IWL_MVM_MAX_SIMULTANEOUS_SCANS]; + u8 scan_seq_num, sched_scan_seq_num; + /* rx chain antennas set through debugfs for the scan command */ u8 scan_rx_ant; @@ -943,6 +947,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *disabled_vif); /* Scanning */ +int iwl_mvm_scan_size(struct iwl_mvm *mvm); int iwl_mvm_scan_request(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); @@ -983,6 +988,17 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req, struct ieee80211_scan_ies *ies); +/* UMAC scan */ +int iwl_mvm_config_scan(struct iwl_mvm *mvm); +int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_scan_request *req); +int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_sched_scan_request *req, + struct ieee80211_scan_ies *ies); +int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); + /* MVM debugfs */ #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 53a5a29897b4..5ab10fb9d672 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -244,6 +244,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_rx_scan_offload_complete_notif, true), RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results, false), + RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif, + true), RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), @@ -346,6 +348,10 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), CMD(ANTENNA_COUPLING_NOTIFICATION), CMD(SCD_QUEUE_CFG), + CMD(SCAN_CFG_CMD), + CMD(SCAN_REQ_UMAC), + CMD(SCAN_ABORT_UMAC), + CMD(SCAN_COMPLETE_UMAC), }; #undef CMD @@ -537,16 +543,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, } } - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - scan_size = sizeof(struct iwl_scan_req_unified_lmac) + - sizeof(struct iwl_scan_channel_cfg_lmac) * - mvm->fw->ucode_capa.n_scan_channels + - sizeof(struct iwl_scan_probe_req); - else - scan_size = sizeof(struct iwl_scan_cmd) + - mvm->fw->ucode_capa.max_probe_length + - mvm->fw->ucode_capa.n_scan_channels * - sizeof(struct iwl_scan_channel); + scan_size = iwl_mvm_scan_size(mvm); mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL); if (!mvm->scan_cmd) diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 8a1f4a8e80e7..c440b7b3ea4f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -83,15 +83,29 @@ struct iwl_mvm_scan_params { } dwell[IEEE80211_NUM_BANDS]; }; +enum iwl_umac_scan_uid_type { + IWL_UMAC_SCAN_UID_REG_SCAN = BIT(0), + IWL_UMAC_SCAN_UID_SCHED_SCAN = BIT(1), + IWL_UMAC_SCAN_UID_ALL = IWL_UMAC_SCAN_UID_REG_SCAN | + IWL_UMAC_SCAN_UID_SCHED_SCAN, +}; + +static int iwl_umac_scan_stop(struct iwl_mvm *mvm, + enum iwl_umac_scan_uid_type type, bool notify); + +static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm) +{ + if (mvm->scan_rx_ant != ANT_NONE) + return mvm->scan_rx_ant; + return mvm->fw->valid_rx_ant; +} + static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) { u16 rx_chain; u8 rx_ant; - if (mvm->scan_rx_ant != ANT_NONE) - rx_ant = mvm->scan_rx_ant; - else - rx_ant = mvm->fw->valid_rx_ant; + rx_ant = iwl_mvm_scan_rx_ant(mvm); rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS; @@ -541,23 +555,17 @@ int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - u8 client_bitmap = 0; - if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { + if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) && + !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { struct iwl_sched_scan_results *notif = (void *)pkt->data; - client_bitmap = notif->client_bitmap; + if (!(notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN)) + return 0; } - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || - client_bitmap & SCAN_CLIENT_SCHED_SCAN) { - if (mvm->scan_status == IWL_MVM_SCAN_SCHED) { - IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); - ieee80211_sched_scan_results(mvm->hw); - } else { - IWL_DEBUG_SCAN(mvm, "Scan results\n"); - } - } + IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); + ieee80211_sched_scan_results(mvm->hw); return 0; } @@ -969,6 +977,20 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, return ret; } +static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm, + struct cfg80211_sched_scan_request *req) +{ + if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { + IWL_DEBUG_SCAN(mvm, + "Sending scheduled scan with filtering, n_match_sets %d\n", + req->n_match_sets); + return false; + } + + IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n"); + return true; +} + int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req) { @@ -984,15 +1006,8 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER, }; - if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { - IWL_DEBUG_SCAN(mvm, - "Sending scheduled scan with filtering, filter len %d\n", - req->n_match_sets); - } else { - IWL_DEBUG_SCAN(mvm, - "Sending Scheduled scan without filtering\n"); + if (iwl_mvm_scan_pass_all(mvm, req)) scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL); - } if (mvm->last_ebs_successful && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) @@ -1011,11 +1026,18 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, int ret; if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { + mvm->scan_status = IWL_MVM_SCAN_SCHED; ret = iwl_mvm_config_sched_scan_profiles(mvm, req); if (ret) return ret; ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); + } else if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { + ret = iwl_mvm_config_sched_scan_profiles(mvm, req); + if (ret) + return ret; + ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); } else { + mvm->scan_status = IWL_MVM_SCAN_SCHED; ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); if (ret) return ret; @@ -1072,6 +1094,10 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) lockdep_assert_held(&mvm->mutex); + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, + notify); + if (mvm->scan_status != IWL_MVM_SCAN_SCHED && (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || mvm->scan_status != IWL_MVM_SCAN_OS)) { @@ -1198,11 +1224,8 @@ static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies, static void iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_scan_ies *ies, - struct iwl_scan_req_unified_lmac *cmd) + struct iwl_scan_probe_req *preq) { - struct iwl_scan_probe_req *preq = (void *)(cmd->data + - sizeof(struct iwl_scan_channel_cfg_lmac) * - mvm->fw->ucode_capa.n_scan_channels); struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf; u8 *pos, *newpos; @@ -1287,6 +1310,7 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, .dataflags = { IWL_HCMD_DFL_NOCOPY, }, }; struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd; + struct iwl_scan_probe_req *preq; struct iwl_mvm_scan_params params = {}; u32 flags; int ssid_bitmap = 0; @@ -1348,7 +1372,10 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, req->req.n_channels, ssid_bitmap, cmd); - iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, cmd); + preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * + mvm->fw->ucode_capa.n_scan_channels); + + iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, preq); ret = iwl_mvm_send_cmd(mvm, &hcmd); if (!ret) { @@ -1381,6 +1408,7 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, .dataflags = { IWL_HCMD_DFL_NOCOPY, }, }; struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd; + struct iwl_scan_probe_req *preq; struct iwl_mvm_scan_params params = {}; int ret; u32 flags = 0, ssid_bitmap = 0; @@ -1404,15 +1432,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, cmd->n_channels = (u8)req->n_channels; - if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { - IWL_DEBUG_SCAN(mvm, - "Sending scheduled scan with filtering, n_match_sets %d\n", - req->n_match_sets); - } else { - IWL_DEBUG_SCAN(mvm, - "Sending Scheduled scan without filtering\n"); + if (iwl_mvm_scan_pass_all(mvm, req)) flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; - } if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; @@ -1442,7 +1463,10 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, ssid_bitmap, cmd); - iwl_mvm_build_unified_scan_probe(mvm, vif, ies, cmd); + preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * + mvm->fw->ucode_capa.n_scan_channels); + + iwl_mvm_build_unified_scan_probe(mvm, vif, ies, preq); ret = iwl_mvm_send_cmd(mvm, &hcmd); if (!ret) { @@ -1464,6 +1488,10 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) { + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_REG_SCAN, + true); + if (mvm->scan_status == IWL_MVM_SCAN_NONE) return 0; @@ -1478,3 +1506,568 @@ int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) return iwl_mvm_scan_offload_stop(mvm, true); return iwl_mvm_cancel_regular_scan(mvm); } + +/* UMAC scan API */ + +struct iwl_umac_scan_done { + struct iwl_mvm *mvm; + enum iwl_umac_scan_uid_type type; +}; + +static int rate_to_scan_rate_flag(unsigned int rate) +{ + static const int rate_to_scan_rate[IWL_RATE_COUNT] = { + [IWL_RATE_1M_INDEX] = SCAN_CONFIG_RATE_1M, + [IWL_RATE_2M_INDEX] = SCAN_CONFIG_RATE_2M, + [IWL_RATE_5M_INDEX] = SCAN_CONFIG_RATE_5M, + [IWL_RATE_11M_INDEX] = SCAN_CONFIG_RATE_11M, + [IWL_RATE_6M_INDEX] = SCAN_CONFIG_RATE_6M, + [IWL_RATE_9M_INDEX] = SCAN_CONFIG_RATE_9M, + [IWL_RATE_12M_INDEX] = SCAN_CONFIG_RATE_12M, + [IWL_RATE_18M_INDEX] = SCAN_CONFIG_RATE_18M, + [IWL_RATE_24M_INDEX] = SCAN_CONFIG_RATE_24M, + [IWL_RATE_36M_INDEX] = SCAN_CONFIG_RATE_36M, + [IWL_RATE_48M_INDEX] = SCAN_CONFIG_RATE_48M, + [IWL_RATE_54M_INDEX] = SCAN_CONFIG_RATE_54M, + }; + + return rate_to_scan_rate[rate]; +} + +static __le32 iwl_mvm_scan_config_rates(struct iwl_mvm *mvm) +{ + struct ieee80211_supported_band *band; + unsigned int rates = 0; + int i; + + band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; + for (i = 0; i < band->n_bitrates; i++) + rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value); + band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; + for (i = 0; i < band->n_bitrates; i++) + rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value); + + /* Set both basic rates and supported rates */ + rates |= SCAN_CONFIG_SUPPORTED_RATE(rates); + + return cpu_to_le32(rates); +} + +int iwl_mvm_config_scan(struct iwl_mvm *mvm) +{ + + struct iwl_scan_config *scan_config; + struct ieee80211_supported_band *band; + int num_channels = + mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + + mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; + int ret, i, j = 0, cmd_size, data_size; + struct iwl_host_cmd cmd = { + .id = SCAN_CFG_CMD, + }; + + if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels)) + return -ENOBUFS; + + cmd_size = sizeof(*scan_config) + mvm->fw->ucode_capa.n_scan_channels; + + scan_config = kzalloc(cmd_size, GFP_KERNEL); + if (!scan_config) + return -ENOMEM; + + data_size = cmd_size - sizeof(struct iwl_mvm_umac_cmd_hdr); + scan_config->hdr.size = cpu_to_le16(data_size); + scan_config->flags = cpu_to_le32(SCAN_CONFIG_FLAG_ACTIVATE | + SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS | + SCAN_CONFIG_FLAG_SET_TX_CHAINS | + SCAN_CONFIG_FLAG_SET_RX_CHAINS | + SCAN_CONFIG_FLAG_SET_ALL_TIMES | + SCAN_CONFIG_FLAG_SET_LEGACY_RATES | + SCAN_CONFIG_FLAG_SET_MAC_ADDR | + SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS| + SCAN_CONFIG_N_CHANNELS(num_channels)); + scan_config->tx_chains = cpu_to_le32(mvm->fw->valid_tx_ant); + scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm)); + scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm); + scan_config->out_of_channel_time = cpu_to_le32(170); + scan_config->suspend_time = cpu_to_le32(30); + scan_config->dwell_active = 20; + scan_config->dwell_passive = 110; + scan_config->dwell_fragmented = 20; + + memcpy(&scan_config->mac_addr, &mvm->addresses[0].addr, ETH_ALEN); + + scan_config->bcast_sta_id = mvm->aux_sta.sta_id; + scan_config->channel_flags = IWL_CHANNEL_FLAG_EBS | + IWL_CHANNEL_FLAG_ACCURATE_EBS | + IWL_CHANNEL_FLAG_EBS_ADD | + IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE; + + band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; + for (i = 0; i < band->n_channels; i++, j++) + scan_config->channel_array[j] = band->channels[i].center_freq; + band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; + for (i = 0; i < band->n_channels; i++, j++) + scan_config->channel_array[j] = band->channels[i].center_freq; + + cmd.data[0] = scan_config; + cmd.len[0] = cmd_size; + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; + + IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n"); + + ret = iwl_mvm_send_cmd(mvm, &cmd); + + kfree(scan_config); + return ret; +} + +static int iwl_mvm_find_scan_uid(struct iwl_mvm *mvm, u32 uid) +{ + int i; + + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) + if (mvm->scan_uid[i] == uid) + return i; + + return i; +} + +static int iwl_mvm_find_free_scan_uid(struct iwl_mvm *mvm) +{ + return iwl_mvm_find_scan_uid(mvm, 0); +} + +static bool iwl_mvm_find_scan_type(struct iwl_mvm *mvm, + enum iwl_umac_scan_uid_type type) +{ + int i; + + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) + if (mvm->scan_uid[i] & type) + return true; + + return false; +} + +static u32 iwl_generate_scan_uid(struct iwl_mvm *mvm, + enum iwl_umac_scan_uid_type type) +{ + u32 uid; + + /* make sure exactly one bit is on in scan type */ + WARN_ON(hweight8(type) != 1); + + /* + * Make sure scan uids are unique. If one scan lasts long time while + * others are completing frequently, the seq number will wrap up and + * we may have more than one scan with the same uid. + */ + do { + uid = type | (mvm->scan_seq_num << + IWL_UMAC_SCAN_UID_SEQ_OFFSET); + mvm->scan_seq_num++; + } while (iwl_mvm_find_scan_uid(mvm, uid) < + IWL_MVM_MAX_SIMULTANEOUS_SCANS); + + IWL_DEBUG_SCAN(mvm, "Generated scan UID %u\n", uid); + + return uid; +} + +static void +iwl_mvm_build_generic_umac_scan_cmd(struct iwl_mvm *mvm, + struct iwl_scan_req_umac *cmd, + struct iwl_mvm_scan_params *params) +{ + memset(cmd, 0, ksize(cmd)); + cmd->hdr.size = cpu_to_le16(iwl_mvm_scan_size(mvm) - + sizeof(struct iwl_mvm_umac_cmd_hdr)); + cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active; + cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; + if (params->passive_fragmented) + cmd->fragmented_dwell = + params->dwell[IEEE80211_BAND_2GHZ].passive; + cmd->max_out_time = cpu_to_le32(params->max_out_time); + cmd->suspend_time = cpu_to_le32(params->suspend_time); + cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); +} + +static void +iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm, + struct ieee80211_channel **channels, + int n_channels, u32 ssid_bitmap, + struct iwl_scan_req_umac *cmd) +{ + struct iwl_scan_channel_cfg_umac *channel_cfg = (void *)&cmd->data; + int i; + + for (i = 0; i < n_channels; i++) { + channel_cfg[i].flags = cpu_to_le32(ssid_bitmap); + channel_cfg[i].channel_num = channels[i]->hw_value; + channel_cfg[i].iter_count = 1; + channel_cfg[i].iter_interval = 0; + } +} + +static u32 iwl_mvm_scan_umac_common_flags(struct iwl_mvm *mvm, int n_ssids, + struct cfg80211_ssid *ssids, + int fragmented) +{ + int flags = 0; + + if (n_ssids == 0) + flags = IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE; + + if (n_ssids == 1 && ssids[0].ssid_len != 0) + flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT; + + if (fragmented) + flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED; + + if (iwl_mvm_rrm_scan_needed(mvm)) + flags |= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED; + + return flags; +} + +int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_scan_request *req) +{ + struct iwl_host_cmd hcmd = { + .id = SCAN_REQ_UMAC, + .len = { iwl_mvm_scan_size(mvm), }, + .data = { mvm->scan_cmd, }, + .dataflags = { IWL_HCMD_DFL_NOCOPY, }, + }; + struct iwl_scan_req_umac *cmd = mvm->scan_cmd; + struct iwl_scan_req_umac_tail *sec_part = (void *)&cmd->data + + sizeof(struct iwl_scan_channel_cfg_umac) * + mvm->fw->ucode_capa.n_scan_channels; + struct iwl_mvm_scan_params params = {}; + u32 uid, flags; + int ssid_bitmap = 0; + int ret, i, uid_idx; + + lockdep_assert_held(&mvm->mutex); + + uid_idx = iwl_mvm_find_free_scan_uid(mvm); + if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) + return -EBUSY; + + /* we should have failed registration if scan_cmd was NULL */ + if (WARN_ON(mvm->scan_cmd == NULL)) + return -ENOMEM; + + if (WARN_ON(req->req.n_ssids > PROBE_OPTION_MAX || + req->ies.common_ie_len + + req->ies.len[NL80211_BAND_2GHZ] + + req->ies.len[NL80211_BAND_5GHZ] + 24 + 2 > + SCAN_OFFLOAD_PROBE_REQ_SIZE || req->req.n_channels > + mvm->fw->ucode_capa.n_scan_channels)) + return -ENOBUFS; + + iwl_mvm_scan_calc_params(mvm, vif, req->req.n_ssids, req->req.flags, + ¶ms); + + iwl_mvm_build_generic_umac_scan_cmd(mvm, cmd, ¶ms); + + uid = iwl_generate_scan_uid(mvm, IWL_UMAC_SCAN_UID_REG_SCAN); + mvm->scan_uid[uid_idx] = uid; + cmd->uid = cpu_to_le32(uid); + + cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); + + flags = iwl_mvm_scan_umac_common_flags(mvm, req->req.n_ssids, + req->req.ssids, + params.passive_fragmented); + + flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; + + cmd->general_flags = cpu_to_le32(flags); + cmd->n_channels = req->req.n_channels; + + for (i = 0; i < req->req.n_ssids; i++) + ssid_bitmap |= BIT(i); + + iwl_mvm_umac_scan_cfg_channels(mvm, req->req.channels, + req->req.n_channels, ssid_bitmap, cmd); + + sec_part->schedule[0].iter_count = 1; + sec_part->delay = 0; + + iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, &sec_part->preq); + + iwl_mvm_scan_fill_ssids(sec_part->direct_scan, req->req.ssids, + req->req.n_ssids, 0); + + ret = iwl_mvm_send_cmd(mvm, &hcmd); + if (!ret) { + IWL_DEBUG_SCAN(mvm, + "Scan request was sent successfully\n"); + } else { + /* + * If the scan failed, it usually means that the FW was unable + * to allocate the time events. Warn on it, but maybe we + * should try to send the command again with different params. + */ + IWL_ERR(mvm, "Scan failed! ret %d\n", ret); + } + return ret; +} + +int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_sched_scan_request *req, + struct ieee80211_scan_ies *ies) +{ + + struct iwl_host_cmd hcmd = { + .id = SCAN_REQ_UMAC, + .len = { iwl_mvm_scan_size(mvm), }, + .data = { mvm->scan_cmd, }, + .dataflags = { IWL_HCMD_DFL_NOCOPY, }, + }; + struct iwl_scan_req_umac *cmd = mvm->scan_cmd; + struct iwl_scan_req_umac_tail *sec_part = (void *)&cmd->data + + sizeof(struct iwl_scan_channel_cfg_umac) * + mvm->fw->ucode_capa.n_scan_channels; + struct iwl_mvm_scan_params params = {}; + u32 uid, flags; + int ssid_bitmap = 0; + int ret, uid_idx; + + lockdep_assert_held(&mvm->mutex); + + uid_idx = iwl_mvm_find_free_scan_uid(mvm); + if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) + return -EBUSY; + + /* we should have failed registration if scan_cmd was NULL */ + if (WARN_ON(mvm->scan_cmd == NULL)) + return -ENOMEM; + + if (WARN_ON(req->n_ssids > PROBE_OPTION_MAX || + ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + + ies->len[NL80211_BAND_5GHZ] + 24 + 2 > + SCAN_OFFLOAD_PROBE_REQ_SIZE || req->n_channels > + mvm->fw->ucode_capa.n_scan_channels)) + return -ENOBUFS; + + iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, + ¶ms); + + iwl_mvm_build_generic_umac_scan_cmd(mvm, cmd, ¶ms); + + cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE); + + uid = iwl_generate_scan_uid(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN); + mvm->scan_uid[uid_idx] = uid; + cmd->uid = cpu_to_le32(uid); + + cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_LOW); + + flags = iwl_mvm_scan_umac_common_flags(mvm, req->n_ssids, req->ssids, + params.passive_fragmented); + + flags |= IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC; + + if (iwl_mvm_scan_pass_all(mvm, req)) + flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; + else + flags |= IWL_UMAC_SCAN_GEN_FLAGS_MATCH; + + cmd->general_flags = cpu_to_le32(flags); + + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && + mvm->last_ebs_successful) + cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS | + IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | + IWL_SCAN_CHANNEL_FLAG_CACHE_ADD; + + cmd->n_channels = req->n_channels; + + iwl_scan_offload_build_ssid(req, sec_part->direct_scan, &ssid_bitmap, + false); + + /* This API uses bits 0-19 instead of 1-20. */ + ssid_bitmap = ssid_bitmap >> 1; + + iwl_mvm_umac_scan_cfg_channels(mvm, req->channels, req->n_channels, + ssid_bitmap, cmd); + + sec_part->schedule[0].interval = + cpu_to_le16(req->interval / MSEC_PER_SEC); + sec_part->schedule[0].iter_count = 0xff; + + sec_part->delay = 0; + + iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq); + + ret = iwl_mvm_send_cmd(mvm, &hcmd); + if (!ret) { + IWL_DEBUG_SCAN(mvm, + "Sched scan request was sent successfully\n"); + } else { + /* + * If the scan failed, it usually means that the FW was unable + * to allocate the time events. Warn on it, but maybe we + * should try to send the command again with different params. + */ + IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret); + } + return ret; +} + +int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_umac_scan_complete *notif = (void *)pkt->data; + u32 uid = __le32_to_cpu(notif->uid); + bool sched = !!(uid & IWL_UMAC_SCAN_UID_SCHED_SCAN); + int uid_idx = iwl_mvm_find_scan_uid(mvm, uid); + + if (WARN(uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS, + "Scan notification for uknown scan ID\n")) + return 0; + + IWL_DEBUG_SCAN(mvm, + "Scan completed, uid %u type %s, status %s, EBS status %s\n", + uid, sched ? "sched" : "regular", + notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? + "completed" : "aborted", + notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? + "success" : "failed"); + + mvm->last_ebs_successful = !notif->ebs_status; + mvm->scan_uid[uid_idx] = 0; + + if (!sched) { + ieee80211_scan_completed(mvm->hw, + notif->status == + IWL_SCAN_OFFLOAD_ABORTED); + iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); + } else if (!iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN)) { + ieee80211_sched_scan_stopped(mvm->hw); + } else { + IWL_DEBUG_SCAN(mvm, "Another sched scan is running\n"); + } + + return 0; +} + +static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt, void *data) +{ + struct iwl_umac_scan_done *scan_done = data; + struct iwl_umac_scan_complete *notif = (void *)pkt->data; + u32 uid = __le32_to_cpu(notif->uid); + int uid_idx = iwl_mvm_find_scan_uid(scan_done->mvm, uid); + + if (WARN_ON(pkt->hdr.cmd != SCAN_COMPLETE_UMAC)) + return false; + + if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) + return false; + + /* + * Clear scan uid of scans that was aborted from above and completed + * in FW so the RX handler does nothing. + */ + scan_done->mvm->scan_uid[uid_idx] = 0; + + return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type); +} + +static int iwl_umac_scan_abort_one(struct iwl_mvm *mvm, u32 uid) +{ + struct iwl_umac_scan_abort cmd = { + .hdr.size = cpu_to_le16(sizeof(struct iwl_umac_scan_abort) - + sizeof(struct iwl_mvm_umac_cmd_hdr)), + .uid = cpu_to_le32(uid), + }; + + lockdep_assert_held(&mvm->mutex); + + IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid); + + return iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_UMAC, 0, sizeof(cmd), &cmd); +} + +static int iwl_umac_scan_stop(struct iwl_mvm *mvm, + enum iwl_umac_scan_uid_type type, bool notify) +{ + struct iwl_notification_wait wait_scan_done; + static const u8 scan_done_notif[] = { SCAN_COMPLETE_UMAC, }; + struct iwl_umac_scan_done scan_done = { + .mvm = mvm, + .type = type, + }; + int i, ret = -EIO; + + iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, + scan_done_notif, + ARRAY_SIZE(scan_done_notif), + iwl_scan_umac_done_check, &scan_done); + + IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type); + + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { + if (mvm->scan_uid[i] & type) { + int err; + + if (iwl_mvm_is_radio_killed(mvm) && + (type & IWL_UMAC_SCAN_UID_REG_SCAN)) { + ieee80211_scan_completed(mvm->hw, true); + iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); + break; + } + + err = iwl_umac_scan_abort_one(mvm, mvm->scan_uid[i]); + if (!err) + ret = 0; + } + } + + if (ret) { + IWL_DEBUG_SCAN(mvm, "Couldn't stop scan\n"); + iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); + return ret; + } + + ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); + if (ret) + return ret; + + if (notify) { + if (type & IWL_UMAC_SCAN_UID_SCHED_SCAN) + ieee80211_sched_scan_stopped(mvm->hw); + if (type & IWL_UMAC_SCAN_UID_REG_SCAN) { + ieee80211_scan_completed(mvm->hw, true); + iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); + } + } + + return ret; +} + +int iwl_mvm_scan_size(struct iwl_mvm *mvm) +{ + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + return sizeof(struct iwl_scan_req_umac) + + sizeof(struct iwl_scan_channel_cfg_umac) * + mvm->fw->ucode_capa.n_scan_channels + + sizeof(struct iwl_scan_req_umac_tail); + + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) + return sizeof(struct iwl_scan_req_unified_lmac) + + sizeof(struct iwl_scan_channel_cfg_lmac) * + mvm->fw->ucode_capa.n_scan_channels + + sizeof(struct iwl_scan_probe_req); + + return sizeof(struct iwl_scan_cmd) + + mvm->fw->ucode_capa.max_probe_length + + mvm->fw->ucode_capa.n_scan_channels * + sizeof(struct iwl_scan_channel); +} -- GitLab From 123f515635b12f100ba550b668203159dfb83c82 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 3 Nov 2014 11:43:15 +0200 Subject: [PATCH 5882/9457] iwlwifi: mvm: BT Coex - add support for TTC / RRC The TTC and RRC features are supported by the newer firmwares. It allows to reach better overall WiFi and BT performance. When the RRC is enabled, we don't need to force the AP to send SISO frames, but it can keeps sending MIMO frames. Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 13 ++++++++++++- drivers/net/wireless/iwlwifi/mvm/constants.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h | 9 ++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index cda5111bb775..b3210cfbecc8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -612,7 +612,9 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm) BT_VALID_ANT_ISOLATION_THRS | BT_VALID_TXTX_DELTA_FREQ_THRS | BT_VALID_TXRX_MAX_FREQ_0 | - BT_VALID_SYNC_TO_SCO); + BT_VALID_SYNC_TO_SCO | + BT_VALID_TTC | + BT_VALID_RRC); if (IWL_MVM_BT_COEX_SYNC2SCO) bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); @@ -628,6 +630,12 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm) bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT); } + if (IWL_MVM_BT_COEX_TTC) + bt_cmd->flags |= cpu_to_le32(BT_COEX_TTC); + + if (IWL_MVM_BT_COEX_RRC) + bt_cmd->flags |= cpu_to_le32(BT_COEX_RRC); + if (mvm->cfg->bt_shared_single_ant) memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, sizeof(iwl_single_shared_ant)); @@ -824,6 +832,9 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, if (!vif->bss_conf.assoc) smps_mode = IEEE80211_SMPS_AUTOMATIC; + if (data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) + smps_mode = IEEE80211_SMPS_AUTOMATIC; + IWL_DEBUG_COEX(data->mvm, "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n", mvmvif->id, data->notif->bt_status, bt_activity_grading, diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index 5c1ea80d5e3b..17160313b3a9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -92,6 +92,8 @@ #define IWL_MVM_BT_COEX_SYNC2SCO 1 #define IWL_MVM_BT_COEX_CORUNNING 0 #define IWL_MVM_BT_COEX_MPLUT 1 +#define IWL_MVM_BT_COEX_RRC 1 +#define IWL_MVM_BT_COEX_TTC 1 #define IWL_MVM_BT_COEX_MPLUT_REG0 0x2e402280 #define IWL_MVM_BT_COEX_MPLUT_REG1 0x7711a751 #define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h index 816883f9ff94..f3b11897991e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h @@ -84,6 +84,8 @@ * @BT_COEX_SYNC2SCO: * @BT_COEX_CORUNNING: * @BT_COEX_MPLUT: + * @BT_COEX_TTC: + * @BT_COEX_RRC: * * The COEX_MODE must be set for each command. Even if it is not changed. */ @@ -100,6 +102,8 @@ enum iwl_bt_coex_flags { BT_COEX_SYNC2SCO = BIT(7), BT_COEX_CORUNNING = BIT(8), BT_COEX_MPLUT = BIT(9), + BT_COEX_TTC = BIT(20), + BT_COEX_RRC = BIT(21), }; /* @@ -127,6 +131,8 @@ enum iwl_bt_coex_valid_bit_msk { BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), BT_VALID_SYNC_TO_SCO = BIT(18), + BT_VALID_TTC = BIT(20), + BT_VALID_RRC = BIT(21), }; /** @@ -506,7 +512,8 @@ struct iwl_bt_coex_profile_notif_old { u8 bt_agg_traffic_load; u8 bt_ci_compliance; u8 ttc_enabled; - __le16 reserved; + u8 rrc_enabled; + u8 reserved; __le32 primary_ch_lut; __le32 secondary_ch_lut; -- GitLab From d6bda6671f8fda961f6cce95e644f6a14fe5bd2a Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 12 Nov 2014 13:30:20 +0200 Subject: [PATCH 5883/9457] iwlwifi: mvm: rs: consider a missing BA as a single tx failure The fw now indicates missing BA with ampdu_ack_len=0. This will make the whole aggregation being marked as failed, although it's most likely not the case (and only the BA itself was failed). Consider this case as a single tx failure. Signed-off-by: Eyal Shapira Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index c05f5a509a5d..30ceb67ed7a7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1204,6 +1204,13 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, * first index into rate scale table. */ if (info->flags & IEEE80211_TX_STAT_AMPDU) { + /* ampdu_ack_len = 0 marks no BA was received. In this case + * treat it as a single frame loss as we don't want the success + * ratio to dip too quickly because a BA wasn't received + */ + if (info->status.ampdu_ack_len == 0) + info->status.ampdu_len = 1; + ucode_rate = le32_to_cpu(table->rs_table[0]); rs_rate_from_ucode_rate(ucode_rate, info->band, &rate); rs_collect_tx_data(lq_sta, curr_tbl, rate.index, -- GitLab From b975e55adcda54aa778e9b4f5eb162891f952cde Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 17 Nov 2014 12:30:05 +0200 Subject: [PATCH 5884/9457] iwlwifi: mvm: go to umac scan even if lmac tlv bit is on LMAC TLV bit may be on in FWs that support UMAC scan; so check for UMAC TLV bit first. Signed-off-by: David Spinadel Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 6 +++--- drivers/net/wireless/iwlwifi/mvm/scan.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 79ad6958255c..bc5883a38f05 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1951,10 +1951,10 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN); - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req); - else if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) ret = iwl_mvm_scan_umac(mvm, vif, hw_req); + else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) + ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req); else ret = iwl_mvm_scan_request(mvm, vif, req); diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index c440b7b3ea4f..219174597ff0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1025,17 +1025,17 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, { int ret; - if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { - mvm->scan_status = IWL_MVM_SCAN_SCHED; + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { ret = iwl_mvm_config_sched_scan_profiles(mvm, req); if (ret) return ret; - ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); - } else if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { + ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); + } else if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { + mvm->scan_status = IWL_MVM_SCAN_SCHED; ret = iwl_mvm_config_sched_scan_profiles(mvm, req); if (ret) return ret; - ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); + ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); } else { mvm->scan_status = IWL_MVM_SCAN_SCHED; ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); -- GitLab From effd05ac479b80641835f9126bbe93146686c2b8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Nov 2014 17:21:19 +0100 Subject: [PATCH 5885/9457] iwlwifi: mvm: support random MAC address for scanning For background and scheduled scan, using the new unified scan API, support random MAC address scanning. Unfortunately, the firmware right now doesn't support randomising itself, so for now do it on the host - we'll change this once the firmware supports randomising the address for each scan iteration using the address/mask. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 6 +++- drivers/net/wireless/iwlwifi/mvm/scan.c | 35 +++++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index bc5883a38f05..d37d5a8b383e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -344,8 +344,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) } if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || - mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) + mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; + hw->wiphy->features |= + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + } hw->sta_data_size = sizeof(struct iwl_mvm_sta); hw->vif_data_size = sizeof(struct iwl_mvm_vif); diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 219174597ff0..54303d935c57 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1224,14 +1224,25 @@ static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies, static void iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_scan_ies *ies, - struct iwl_scan_probe_req *preq) + struct iwl_scan_probe_req *preq, + const u8 *mac_addr, const u8 *mac_addr_mask) { struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf; u8 *pos, *newpos; + /* + * Unfortunately, right now the offload scan doesn't support randomising + * within the firmware, so until the firmware API is ready we implement + * it in the driver. This means that the scan iterations won't really be + * random, only when it's restarted, but at least that helps a bit. + */ + if (mac_addr) + get_random_mask_addr(frame->sa, mac_addr, mac_addr_mask); + else + memcpy(frame->sa, vif->addr, ETH_ALEN); + frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); eth_broadcast_addr(frame->da); - memcpy(frame->sa, vif->addr, ETH_ALEN); eth_broadcast_addr(frame->bssid); frame->seq_ctrl = 0; @@ -1375,7 +1386,10 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * mvm->fw->ucode_capa.n_scan_channels); - iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, preq); + iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, preq, + req->req.flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? + req->req.mac_addr : NULL, + req->req.mac_addr_mask); ret = iwl_mvm_send_cmd(mvm, &hcmd); if (!ret) { @@ -1466,7 +1480,10 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * mvm->fw->ucode_capa.n_scan_channels); - iwl_mvm_build_unified_scan_probe(mvm, vif, ies, preq); + iwl_mvm_build_unified_scan_probe(mvm, vif, ies, preq, + req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? + req->mac_addr : NULL, + req->mac_addr_mask); ret = iwl_mvm_send_cmd(mvm, &hcmd); if (!ret) { @@ -1796,7 +1813,10 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, sec_part->schedule[0].iter_count = 1; sec_part->delay = 0; - iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, &sec_part->preq); + iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, &sec_part->preq, + req->req.flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? + req->req.mac_addr : NULL, + req->req.mac_addr_mask); iwl_mvm_scan_fill_ssids(sec_part->direct_scan, req->req.ssids, req->req.n_ssids, 0); @@ -1901,7 +1921,10 @@ int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, sec_part->delay = 0; - iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq); + iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq, + req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? + req->mac_addr : NULL, + req->mac_addr_mask); ret = iwl_mvm_send_cmd(mvm, &hcmd); if (!ret) { -- GitLab From 522713c81e4ec98c554d74bcf8c26ddbfa6a30ee Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 14 Nov 2014 07:29:47 -0800 Subject: [PATCH 5886/9457] iwlwifi: pcie: properly reset the device We were toggling the wrong bit when we reset the device, fix that. Moreover, since the reset can take time, we need to wait before we set the rfkill interrupt. Not doing so can be racy since the driver is enabling the rfkill interrupt while the device is resetting which will clear all the registers including the CSR_INT_MASK. This can basically lead to a situation where we don't enable the rfkill interrupt. If that happens, the user will not be able to re-enable the device when de-asserting rfkill. This scenario happened to the submitter of: https://bugzilla.kernel.org/show_bug.cgi?id=87191 Signed-off-by: Emmanuel Grumbach Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index ee2ec516e30c..b81d1412c352 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -942,7 +942,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) spin_unlock(&trans_pcie->irq_lock); /* stop and reset the on-board processor */ - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + udelay(20); /* clear all status bits */ clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); -- GitLab From cc4c1ab5d22b22b945141edcbb74d0ab8caecbad Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 23:21:55 +0200 Subject: [PATCH 5887/9457] iwlwifi: mvm: make nd_ies part of the mvm struct Instead of allocating nd_ies separately, make it part of the iwl_mvm structure so it's easier to handle its lifetime. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 2 +- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 8 -------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/ops.c | 2 -- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index faa7d5c365d5..0fc72fc6ce2f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1036,7 +1036,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, goto out; ret = iwl_mvm_scan_offload_start(mvm, vif, mvm->nd_config, - mvm->nd_ies); + &mvm->nd_ies); if (ret) goto out; } else { diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 8212b00096f9..5a0f1049e099 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -1198,14 +1198,8 @@ static ssize_t iwl_dbgfs_netdetect_write(struct iwl_mvm *mvm, char *buf, kfree(mvm->nd_config->match_sets); kfree(mvm->nd_config); mvm->nd_config = NULL; - kfree(mvm->nd_ies); - mvm->nd_ies = NULL; } - mvm->nd_ies = kzalloc(sizeof(*mvm->nd_ies), GFP_KERNEL); - if (!mvm->nd_ies) - return -ENOMEM; - mvm->nd_config = kzalloc(sizeof(*mvm->nd_config) + (11 * sizeof(struct ieee80211_channel *)), GFP_KERNEL); @@ -1262,8 +1256,6 @@ static ssize_t iwl_dbgfs_netdetect_write(struct iwl_mvm *mvm, char *buf, kfree(mvm->nd_config->match_sets); kfree(mvm->nd_config); mvm->nd_config = NULL; - kfree(mvm->nd_ies); - mvm->nd_ies = NULL; out: return ret; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index cbfba80a0e2f..db52f65e4660 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -666,7 +666,7 @@ struct iwl_mvm { /* sched scan settings for net detect */ struct cfg80211_sched_scan_request *nd_config; - struct ieee80211_scan_ies *nd_ies; + struct ieee80211_scan_ies nd_ies; #ifdef CONFIG_IWLWIFI_DEBUGFS u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ bool d3_test_active; diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 5ab10fb9d672..b022fc097e78 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -597,8 +597,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) kfree(mvm->nd_config->match_sets); kfree(mvm->nd_config); mvm->nd_config = NULL; - kfree(mvm->nd_ies); - mvm->nd_ies = NULL; } #endif -- GitLab From fb68e1a466e8a114c33b06d51c99872b87d78dfb Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 19 Nov 2014 13:57:52 +0200 Subject: [PATCH 5888/9457] iwlwifi: mvm: disable beacon filtering escape timer There is no reason to pass every 50th beacon if nothing was changed. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 2fd8ad4633e0..430020047b77 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -370,7 +370,7 @@ struct iwl_beacon_filter_cmd { #define IWL_BF_DEBUG_FLAG_DEFAULT 0 #define IWL_BF_DEBUG_FLAG_D0I3 0 -#define IWL_BF_ESCAPE_TIMER_DEFAULT 50 +#define IWL_BF_ESCAPE_TIMER_DEFAULT 0 #define IWL_BF_ESCAPE_TIMER_D0I3 0 #define IWL_BF_ESCAPE_TIMER_MAX 1024 #define IWL_BF_ESCAPE_TIMER_MIN 0 -- GitLab From fe45773b5baa154468416aac1304f6325939f775 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 17 Nov 2014 15:46:37 +0200 Subject: [PATCH 5889/9457] iwlwifi: pcie: support loading FW with extended mem range Toggle the LMPM_CHICK register when writing chunks into the FW's extended SRAM. This tells the FW to put the chunk into a different memory space. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-prph.h | 6 ++++++ drivers/net/wireless/iwlwifi/pcie/trans.c | 26 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 1560f4576c7d..90011b13fc9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -368,4 +368,10 @@ enum secure_load_status_reg { #define MON_BUFF_WRPTR (0xa03c44) #define MON_BUFF_CYCLE_CNT (0xa03c48) +/* FW chicken bits */ +#define LMPM_CHICK 0xA01FF8 +enum { + LMPM_CHICK_EXTENDED_ADDR_SPACE = BIT(0), +}; + #endif /* __iwl_prph_h__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index b81d1412c352..a3b63b77b4ba 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -79,6 +79,10 @@ #include "iwl-fw-error-dump.h" #include "internal.h" +/* extended range in FW SRAM */ +#define IWL_FW_MEM_EXTENDED_START 0x40000 +#define IWL_FW_MEM_EXTENDED_END 0x57FFF + static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -627,14 +631,28 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, } for (offset = 0; offset < section->len; offset += chunk_sz) { - u32 copy_size; + u32 copy_size, dst_addr; + bool extended_addr = false; copy_size = min_t(u32, chunk_sz, section->len - offset); + dst_addr = section->offset + offset; + + if (dst_addr >= IWL_FW_MEM_EXTENDED_START && + dst_addr <= IWL_FW_MEM_EXTENDED_END) + extended_addr = true; + + if (extended_addr) + iwl_set_bits_prph(trans, LMPM_CHICK, + LMPM_CHICK_EXTENDED_ADDR_SPACE); memcpy(v_addr, (u8 *)section->data + offset, copy_size); - ret = iwl_pcie_load_firmware_chunk(trans, - section->offset + offset, - p_addr, copy_size); + ret = iwl_pcie_load_firmware_chunk(trans, dst_addr, p_addr, + copy_size); + + if (extended_addr) + iwl_clear_bits_prph(trans, LMPM_CHICK, + LMPM_CHICK_EXTENDED_ADDR_SPACE); + if (ret) { IWL_ERR(trans, "Could not load the [%d] uCode section\n", -- GitLab From bd635c354de407b3cdca9d0948c7bfdc3c0c63cf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 22 Nov 2014 17:24:19 -0800 Subject: [PATCH 5890/9457] mlx4: fix mlx4_en_set_rxfh() mlx4_en_set_rxfh() can crash if no RSS indir table is provided. While we are at it, allow RSS key to be changed with ethtool -X Tested: myhost:~# cat /proc/sys/net/core/netdev_rss_key b6:89:91:f3:b2:c3:c2:90:11:e8:ce:45:e8:a9:9d:1c:f2:f6:d4:53:61:8b:26:3a:b3:9a:57:97:c3:b6:79:4d:2e:d9:66:5c:72:ed:b6:8e:c5:5d:4d:8c:22:67:30:ab:8a:6e:c3:6a myhost:~# ethtool -x eth0 RX flow hash indirection table for eth0 with 8 RX ring(s): 0: 0 1 2 3 4 5 6 7 RSS hash key: b6:89:91:f3:b2:c3:c2:90:11:e8:ce:45:e8:a9:9d:1c:f2:f6:d4:53:61:8b:26:3a:b3:9a:57:97:c3:b6:79:4d:2e:d9:66:5c:72:ed:b6:8e myhost:~# ethtool -X eth0 hkey \ 03:0e:e2:43:fa:82:0e:73:14:2d:c0:68:21:9e:82:99:b9:84:d0:22:e2:b3:64:9f:4a:af:00:fa:cc:05:b4:4a:17:05:14:73:76:58:bd:2f myhost:~# ethtool -x eth0 RX flow hash indirection table for eth0 with 8 RX ring(s): 0: 0 1 2 3 4 5 6 7 RSS hash key: 03:0e:e2:43:fa:82:0e:73:14:2d:c0:68:21:9e:82:99:b9:84:d0:22:e2:b3:64:9f:4a:af:00:fa:cc:05:b4:4a:17:05:14:73:76:58:bd:2f Reported-by: Ben Hutchings Fixes: b9d1ab7eb42e ("mlx4: use netdev_rss_key_fill() helper") Signed-off-by: Eric Dumazet Cc: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 10 +++++++--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 + drivers/net/ethernet/mellanox/mlx4/en_rx.c | 3 +-- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index bdff834a2a7e..c45e06abc073 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -994,7 +994,7 @@ static int mlx4_en_get_rxfh(struct net_device *dev, u32 *ring_index, u8 *key) rss_map->base_qpn; } if (key) - netdev_rss_key_fill(key, MLX4_EN_RSS_KEY_SIZE); + memcpy(key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE); return err; } @@ -1012,6 +1012,8 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index, * between rings */ for (i = 0; i < priv->rx_ring_num; i++) { + if (!ring_index) + continue; if (i > 0 && !ring_index[i] && !rss_rings) rss_rings = i; @@ -1032,8 +1034,10 @@ static int mlx4_en_set_rxfh(struct net_device *dev, const u32 *ring_index, mlx4_en_stop_port(dev, 1); } - priv->prof->rss_rings = rss_rings; - + if (ring_index) + priv->prof->rss_rings = rss_rings; + if (key) + memcpy(priv->rss_key, key, MLX4_EN_RSS_KEY_SIZE); if (port_up) { err = mlx4_en_start_port(dev); if (err) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 89440cb25ad8..b7c99780aef3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -2493,6 +2493,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up; priv->tx_ring_num = prof->tx_ring_num; priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK; + netdev_rss_key_fill(priv->rss_key, sizeof(priv->rss_key)); priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS, GFP_KERNEL); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index b7bda8956011..946d35280abc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -1223,8 +1223,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) rss_context->flags = rss_mask; rss_context->hash_fn = MLX4_RSS_HASH_TOP; - netdev_rss_key_fill(rss_context->rss_key, MLX4_EN_RSS_KEY_SIZE); - + memcpy(rss_context->rss_key, priv->rss_key, MLX4_EN_RSS_KEY_SIZE); err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); if (err) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index de456749ffae..aaa7efbb9664 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -618,6 +618,7 @@ struct mlx4_en_priv { __be16 vxlan_port; u32 pflags; + u8 rss_key[MLX4_EN_RSS_KEY_SIZE]; }; enum mlx4_en_wol { -- GitLab From db40b3f55a2297eff15f24a4d3d52f70783a6530 Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan <_govind@gmx.com> Date: Sun, 23 Nov 2014 01:22:51 +0530 Subject: [PATCH 5891/9457] enic: use napi_schedule_irqoff() enic_isr_legacy(), enic_isr_msix() & enic_isr_msi() run from hard interrupt context. They can use napi_schedule_irqoff() instead of napi_schedule() Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index b9cda2fc5ae8..b42a48097dbd 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -283,12 +283,10 @@ static irqreturn_t enic_isr_legacy(int irq, void *data) return IRQ_HANDLED; } - if (ENIC_TEST_INTR(pba, io_intr)) { - if (napi_schedule_prep(&enic->napi[0])) - __napi_schedule(&enic->napi[0]); - } else { + if (ENIC_TEST_INTR(pba, io_intr)) + napi_schedule_irqoff(&enic->napi[0]); + else vnic_intr_unmask(&enic->intr[io_intr]); - } return IRQ_HANDLED; } @@ -313,7 +311,7 @@ static irqreturn_t enic_isr_msi(int irq, void *data) * writes). */ - napi_schedule(&enic->napi[0]); + napi_schedule_irqoff(&enic->napi[0]); return IRQ_HANDLED; } @@ -322,7 +320,7 @@ static irqreturn_t enic_isr_msix(int irq, void *data) { struct napi_struct *napi = data; - napi_schedule(napi); + napi_schedule_irqoff(napi); return IRQ_HANDLED; } -- GitLab From 78e2045d3d562e43562e3cbf0e96c26e38a718e9 Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan <_govind@gmx.com> Date: Sun, 23 Nov 2014 01:22:52 +0530 Subject: [PATCH 5892/9457] enic: use spin_lock(wq_lock) instead of spin_lock_irqsave(wq_lock) All the access to wq has been moved out of hardirq context. We no longer need to use spin_lock_irqsave. Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index b42a48097dbd..46647407d585 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -529,7 +529,6 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, { struct enic *enic = netdev_priv(netdev); struct vnic_wq *wq; - unsigned long flags; unsigned int txq_map; struct netdev_queue *txq; @@ -554,14 +553,14 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } - spin_lock_irqsave(&enic->wq_lock[txq_map], flags); + spin_lock(&enic->wq_lock[txq_map]); if (vnic_wq_desc_avail(wq) < skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { netif_tx_stop_queue(txq); /* This is a hard error, log it */ netdev_err(netdev, "BUG! Tx ring full when queue awake!\n"); - spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); + spin_unlock(&enic->wq_lock[txq_map]); return NETDEV_TX_BUSY; } @@ -572,7 +571,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, if (!skb->xmit_more || netif_xmit_stopped(txq)) vnic_wq_doorbell(wq); - spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); + spin_unlock(&enic->wq_lock[txq_map]); return NETDEV_TX_OK; } -- GitLab From 17150fef4ab1f48d838008657cdaa168453a9fa6 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Sun, 23 Nov 2014 15:13:44 -0500 Subject: [PATCH 5893/9457] ktest: Add back "tail -1" to kernelrelease make Commit 52d21580b362 "ktest: Use make -s kernelrelease" fixed commit 7ff525712acf "kbuild: fake the "Entering directory ..." message more simply" as that commit added output after the make kernelrelease. But there's still some build scripts that are used by ktest that has output before the make is executed, and requires that only the last line is printed. Cc: Michal Marek Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 35b118a38c2f..b9cd036f0442 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -2002,7 +2002,7 @@ sub get_version { # get the release name return if ($have_version); doprint "$make kernelrelease ... "; - $version = `$make -s kernelrelease`; + $version = `$make -s kernelrelease | tail -1`; chomp($version); doprint "$version\n"; $have_version = 1; -- GitLab From 2d00bd17a2702fff623ecc005bd0f9c29e6cb508 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 23 Nov 2014 11:28:50 -0800 Subject: [PATCH 5894/9457] staging: lustre: Coalesce string fragments Join the string fragments to make it easier to grep. Ignored all the 80+ column lines. Added many missing spaces when coalescing formats. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- .../lustre/lnet/klnds/o2iblnd/o2iblnd.c | 12 +- .../lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 34 ++-- .../lnet/klnds/o2iblnd/o2iblnd_modparams.c | 3 +- .../lustre/lnet/klnds/socklnd/socklnd.c | 49 +++-- .../lustre/lnet/klnds/socklnd/socklnd_cb.c | 89 ++++------ .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 15 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 82 ++++----- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 3 +- drivers/staging/lustre/lnet/lnet/router.c | 34 ++-- .../staging/lustre/lnet/lnet/router_proc.c | 9 +- .../staging/lustre/lnet/selftest/console.c | 6 +- .../staging/lustre/lnet/selftest/framework.c | 25 +-- drivers/staging/lustre/lnet/selftest/module.c | 4 +- drivers/staging/lustre/lnet/selftest/rpc.c | 29 ++- .../staging/lustre/lustre/include/linux/obd.h | 3 +- .../lustre/lustre/include/lustre_disk.h | 3 +- .../staging/lustre/lustre/ldlm/ldlm_flock.c | 3 +- drivers/staging/lustre/lustre/ldlm/ldlm_lib.c | 4 +- .../staging/lustre/lustre/ldlm/ldlm_lock.c | 168 ++++++++---------- .../staging/lustre/lustre/ldlm/ldlm_lockd.c | 11 +- .../staging/lustre/lustre/ldlm/ldlm_pool.c | 10 +- .../staging/lustre/lustre/ldlm/ldlm_request.c | 37 ++-- .../lustre/lustre/ldlm/ldlm_resource.c | 19 +- drivers/staging/lustre/lustre/libcfs/debug.c | 8 +- drivers/staging/lustre/lustre/libcfs/hash.c | 3 +- .../lustre/lustre/libcfs/linux/linux-cpu.c | 32 ++-- .../lustre/lustre/libcfs/linux/linux-debug.c | 6 +- .../lustre/lustre/libcfs/linux/linux-tcpip.c | 3 +- .../staging/lustre/lustre/libcfs/tracefile.c | 38 ++-- drivers/staging/lustre/lustre/llite/dcache.c | 6 +- drivers/staging/lustre/lustre/llite/dir.c | 25 ++- drivers/staging/lustre/lustre/llite/file.c | 16 +- .../staging/lustre/lustre/llite/llite_capa.c | 3 +- .../staging/lustre/lustre/llite/llite_close.c | 16 +- .../lustre/lustre/llite/llite_internal.h | 12 +- .../staging/lustre/lustre/llite/llite_lib.c | 58 +++--- .../staging/lustre/lustre/llite/llite_mmap.c | 9 +- .../lustre/lustre/llite/llite_rmtacl.c | 7 +- drivers/staging/lustre/lustre/llite/lloop.c | 4 +- .../staging/lustre/lustre/llite/lproc_llite.c | 29 ++- drivers/staging/lustre/lustre/llite/namei.c | 14 +- drivers/staging/lustre/lustre/llite/rw.c | 20 +-- .../staging/lustre/lustre/llite/statahead.c | 11 +- drivers/staging/lustre/lustre/llite/symlink.c | 4 +- drivers/staging/lustre/lustre/llite/vvp_io.c | 5 +- .../staging/lustre/lustre/llite/vvp_page.c | 3 +- drivers/staging/lustre/lustre/llite/xattr.c | 3 +- drivers/staging/lustre/lustre/lmv/lmv_fld.c | 3 +- .../staging/lustre/lustre/lmv/lmv_intent.c | 8 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 36 ++-- drivers/staging/lustre/lustre/lov/lov_ea.c | 5 +- drivers/staging/lustre/lustre/lov/lov_obd.c | 32 ++-- .../staging/lustre/lustre/mgc/mgc_request.c | 6 +- drivers/staging/lustre/lustre/obdclass/capa.c | 8 +- .../staging/lustre/lustre/obdclass/cl_io.c | 3 +- .../staging/lustre/lustre/obdclass/cl_lock.c | 3 +- .../lustre/lustre/obdclass/class_obd.c | 6 +- .../staging/lustre/lustre/obdclass/genops.c | 18 +- .../lustre/obdclass/linux/linux-sysctl.c | 5 +- drivers/staging/lustre/lustre/obdclass/llog.c | 4 +- .../staging/lustre/lustre/obdclass/llog_cat.c | 10 +- .../lustre/lustre/obdclass/llog_swab.c | 3 +- .../lustre/lustre/obdclass/lprocfs_status.c | 10 +- .../lustre/lustre/obdclass/lu_object.c | 3 +- .../lustre/lustre/obdclass/obd_config.c | 9 +- .../lustre/lustre/obdclass/obd_mount.c | 38 ++-- .../lustre/lustre/obdecho/echo_client.c | 3 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 4 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 6 +- .../staging/lustre/lustre/osc/osc_object.c | 3 +- drivers/staging/lustre/lustre/osc/osc_page.c | 11 +- .../staging/lustre/lustre/osc/osc_request.c | 47 +++-- drivers/staging/lustre/lustre/ptlrpc/client.c | 44 ++--- drivers/staging/lustre/lustre/ptlrpc/events.c | 7 +- drivers/staging/lustre/lustre/ptlrpc/import.c | 115 +++++------- drivers/staging/lustre/lustre/ptlrpc/layout.c | 24 ++- .../lustre/lustre/ptlrpc/llog_client.c | 3 +- .../lustre/lustre/ptlrpc/lproc_ptlrpc.c | 13 +- drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 7 +- drivers/staging/lustre/lustre/ptlrpc/nrs.c | 33 ++-- .../lustre/lustre/ptlrpc/pack_generic.c | 33 ++-- drivers/staging/lustre/lustre/ptlrpc/pinger.c | 18 +- .../staging/lustre/lustre/ptlrpc/ptlrpcd.c | 7 +- .../staging/lustre/lustre/ptlrpc/recover.c | 7 +- drivers/staging/lustre/lustre/ptlrpc/sec.c | 22 ++- .../staging/lustre/lustre/ptlrpc/sec_bulk.c | 3 +- .../staging/lustre/lustre/ptlrpc/sec_plain.c | 4 +- .../staging/lustre/lustre/ptlrpc/service.c | 90 ++++------ 88 files changed, 688 insertions(+), 1013 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index bc479a721a60..62b575deac3a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -930,8 +930,7 @@ kiblnd_close_peer_conns_locked (kib_peer_t *peer, int why) list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); - CDEBUG(D_NET, "Closing conn -> %s, " - "version: %x, reason: %d\n", + CDEBUG(D_NET, "Closing conn -> %s, version: %x, reason: %d\n", libcfs_nid2str(peer->ibp_nid), conn->ibc_version, why); @@ -958,8 +957,7 @@ kiblnd_close_stale_conns_locked (kib_peer_t *peer, conn->ibc_incarnation == incarnation) continue; - CDEBUG(D_NET, "Closing stale conn -> %s version: %x, " - "incarnation:%#llx(%x, %#llx)\n", + CDEBUG(D_NET, "Closing stale conn -> %s version: %x, incarnation:%#llx(%x, %#llx)\n", libcfs_nid2str(peer->ibp_nid), conn->ibc_version, conn->ibc_incarnation, version, incarnation); @@ -1599,8 +1597,7 @@ kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages, int npages, if (fps->fps_increasing) { spin_unlock(&fps->fps_lock); - CDEBUG(D_NET, "Another thread is allocating new " - "FMR pool, waiting for her to complete\n"); + CDEBUG(D_NET, "Another thread is allocating new FMR pool, waiting for her to complete\n"); schedule(); goto again; @@ -1801,8 +1798,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps) if (ps->ps_increasing) { /* another thread is allocating a new pool */ spin_unlock(&ps->ps_lock); - CDEBUG(D_NET, "Another thread is allocating new " - "%s pool, waiting for her to complete\n", + CDEBUG(D_NET, "Another thread is allocating new %s pool, waiting for her to complete\n", ps->ps_name); schedule(); goto again; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 14c9c8d18d02..b48d7edf5669 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1116,8 +1116,7 @@ kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type, } if (tx->tx_nwrq == IBLND_RDMA_FRAGS(conn->ibc_version)) { - CERROR("RDMA too fragmented for %s (%d): " - "%d/%d src %d/%d dst frags\n", + CERROR("RDMA too fragmented for %s (%d): %d/%d src %d/%d dst frags\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), IBLND_RDMA_FRAGS(conn->ibc_version), srcidx, srcrd->rd_nfrags, @@ -2254,8 +2253,8 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) if (ni == NULL || /* no matching net */ ni->ni_nid != reqmsg->ibm_dstnid || /* right NET, wrong NID! */ net->ibn_dev != ibdev) { /* wrong device */ - CERROR("Can't accept %s on %s (%s:%d:%pI4h): " - "bad dst nid %s\n", libcfs_nid2str(nid), + CERROR("Can't accept %s on %s (%s:%d:%pI4h): bad dst nid %s\n", + libcfs_nid2str(nid), ni == NULL ? "NA" : libcfs_nid2str(ni->ni_nid), ibdev->ibd_ifname, ibdev->ibd_nnets, &ibdev->ibd_ifip, @@ -2295,8 +2294,7 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) if (reqmsg->ibm_u.connparams.ibcp_max_frags != IBLND_RDMA_FRAGS(version)) { - CERROR("Can't accept %s(version %x): " - "incompatible max_frags %d (%d wanted)\n", + CERROR("Can't accept %s(version %x): incompatible max_frags %d (%d wanted)\n", libcfs_nid2str(nid), version, reqmsg->ibm_u.connparams.ibcp_max_frags, IBLND_RDMA_FRAGS(version)); @@ -2502,8 +2500,7 @@ kiblnd_reconnect (kib_conn_t *conn, int version, break; } - CNETERR("%s: retrying (%s), %x, %x, " - "queue_dep: %d, max_frag: %d, msg_size: %d\n", + CNETERR("%s: retrying (%s), %x, %x, queue_dep: %d, max_frag: %d, msg_size: %d\n", libcfs_nid2str(peer->ibp_nid), reason, IBLND_MSG_VERSION, version, cp != NULL? cp->ibcp_queue_depth :IBLND_MSG_QUEUE_SIZE(version), @@ -2679,8 +2676,7 @@ kiblnd_check_connreply (kib_conn_t *conn, void *priv, int priv_nob) } if (ver != msg->ibm_version) { - CERROR("%s replied version %x is different with " - "requested version %x\n", + CERROR("%s replied version %x is different with requested version %x\n", libcfs_nid2str(peer->ibp_nid), msg->ibm_version, ver); rc = -EPROTO; goto failed; @@ -2724,8 +2720,7 @@ kiblnd_check_connreply (kib_conn_t *conn, void *priv, int priv_nob) read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); if (rc != 0) { - CERROR("Bad connection reply from %s, rc = %d, " - "version: %x max_frags: %d\n", + CERROR("Bad connection reply from %s, rc = %d, version: %x max_frags: %d\n", libcfs_nid2str(peer->ibp_nid), rc, msg->ibm_version, msg->ibm_u.connparams.ibcp_max_frags); goto failed; @@ -3060,8 +3055,7 @@ kiblnd_check_conns (int idx) } if (timedout) { - CERROR("Timed out RDMA with %s (%lu): " - "c: %u, oc: %u, rc: %u\n", + CERROR("Timed out RDMA with %s (%lu): c: %u, oc: %u, rc: %u\n", libcfs_nid2str(peer->ibp_nid), cfs_duration_sec(cfs_time_current() - peer->ibp_last_alive), @@ -3334,10 +3328,8 @@ kiblnd_scheduler(void *arg) rc = cfs_cpt_bind(lnet_cpt_table(), sched->ibs_cpt); if (rc != 0) { - CWARN("Failed to bind on CPT %d, please verify whether " - "all CPUs are healthy and reload modules if necessary, " - "otherwise your system might under risk of low " - "performance\n", sched->ibs_cpt); + CWARN("Failed to bind on CPT %d, please verify whether all CPUs are healthy and reload modules if necessary, otherwise your system might under risk of low performance\n", + sched->ibs_cpt); } spin_lock_irqsave(&sched->ibs_lock, flags); @@ -3369,8 +3361,7 @@ kiblnd_scheduler(void *arg) rc = ib_req_notify_cq(conn->ibc_cq, IB_CQ_NEXT_COMP); if (rc < 0) { - CWARN("%s: ib_req_notify_cq failed: %d, " - "closing connection\n", + CWARN("%s: ib_req_notify_cq failed: %d, closing connection\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); kiblnd_close_conn(conn, -EIO); kiblnd_conn_decref(conn); @@ -3383,8 +3374,7 @@ kiblnd_scheduler(void *arg) } if (rc < 0) { - CWARN("%s: ib_poll_cq failed: %d, " - "closing connection\n", + CWARN("%s: ib_poll_cq failed: %d, closing connection\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); kiblnd_close_conn(conn, -EIO); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index cefdfb6b1bec..8b4a8e9a29b4 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -222,8 +222,7 @@ kiblnd_tunables_init (void) *kiblnd_tunables.kib_concurrent_sends = *kiblnd_tunables.kib_peertxcredits / 2; if (*kiblnd_tunables.kib_concurrent_sends < *kiblnd_tunables.kib_peertxcredits) { - CWARN("Concurrent sends %d is lower than message queue size: %d, " - "performance may drop slightly.\n", + CWARN("Concurrent sends %d is lower than message queue size: %d, performance may drop slightly.\n", *kiblnd_tunables.kib_concurrent_sends, *kiblnd_tunables.kib_peertxcredits); } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 8ac6410e2ae2..9188b34e6948 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -337,8 +337,7 @@ ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn) &route->ksnr_ipaddr, &conn->ksnc_myipaddr); } else { - CDEBUG(D_NET, "Rebinding %s %pI4h from " - "%pI4h to %pI4h\n", + CDEBUG(D_NET, "Rebinding %s %pI4h from %pI4h to %pI4h\n", libcfs_id2str(peer->ksnp_id), &route->ksnr_ipaddr, &route->ksnr_myipaddr, @@ -974,8 +973,7 @@ ksocknal_accept (lnet_ni_t *ni, struct socket *sock) LIBCFS_ALLOC(cr, sizeof(*cr)); if (cr == NULL) { - LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from " - "%pI4h: memory exhausted\n", + LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from %pI4h: memory exhausted\n", &peer_ip); return -ENOMEM; } @@ -1288,8 +1286,7 @@ ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route, * socket callbacks. */ - CDEBUG(D_NET, "New conn %s p %d.x %pI4h -> %pI4h/%d" - " incarnation:%lld sched[%d:%d]\n", + CDEBUG(D_NET, "New conn %s p %d.x %pI4h -> %pI4h/%d incarnation:%lld sched[%d:%d]\n", libcfs_id2str(peerid), conn->ksnc_proto->pro_version, &conn->ksnc_myipaddr, &conn->ksnc_ipaddr, conn->ksnc_port, incarnation, cpt, @@ -1638,37 +1635,32 @@ ksocknal_destroy_conn (ksock_conn_t *conn) case SOCKNAL_RX_LNET_PAYLOAD: last_rcv = conn->ksnc_rx_deadline - cfs_time_seconds(*ksocknal_tunables.ksnd_timeout); - CERROR("Completing partial receive from %s[%d]" - ", ip %pI4h:%d, with error, wanted: %d, left: %d, " - "last alive is %ld secs ago\n", + CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %d, left: %d, last alive is %ld secs ago\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type, &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_rx_nob_wanted, conn->ksnc_rx_nob_left, cfs_duration_sec(cfs_time_sub(cfs_time_current(), - last_rcv))); + last_rcv))); lnet_finalize (conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, -EIO); break; case SOCKNAL_RX_LNET_HEADER: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of lnet header from %s" - ", ip %pI4h:%d, with error, protocol: %d.x.\n", + CERROR("Incomplete receive of lnet header from %s, ip %pI4h:%d, with error, protocol: %d.x.\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_proto->pro_version); break; case SOCKNAL_RX_KSM_HEADER: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of ksock message from %s" - ", ip %pI4h:%d, with error, protocol: %d.x.\n", + CERROR("Incomplete receive of ksock message from %s, ip %pI4h:%d, with error, protocol: %d.x.\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_proto->pro_version); break; case SOCKNAL_RX_SLOP: if (conn->ksnc_rx_started) - CERROR("Incomplete receive of slops from %s" - ", ip %pI4h:%d, with error\n", + CERROR("Incomplete receive of slops from %s, ip %pI4h:%d, with error\n", libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; @@ -2511,22 +2503,21 @@ ksocknal_debug_peerhash (lnet_ni_t *ni) ksock_route_t *route; ksock_conn_t *conn; - CWARN ("Active peer on shutdown: %s, ref %d, scnt %d, " - "closing %d, accepting %d, err %d, zcookie %llu, " - "txq %d, zc_req %d\n", libcfs_id2str(peer->ksnp_id), - atomic_read(&peer->ksnp_refcount), - peer->ksnp_sharecount, peer->ksnp_closing, - peer->ksnp_accepting, peer->ksnp_error, - peer->ksnp_zc_next_cookie, - !list_empty(&peer->ksnp_tx_queue), - !list_empty(&peer->ksnp_zc_req_list)); + CWARN("Active peer on shutdown: %s, ref %d, scnt %d, closing %d, accepting %d, err %d, zcookie %llu, txq %d, zc_req %d\n", + libcfs_id2str(peer->ksnp_id), + atomic_read(&peer->ksnp_refcount), + peer->ksnp_sharecount, peer->ksnp_closing, + peer->ksnp_accepting, peer->ksnp_error, + peer->ksnp_zc_next_cookie, + !list_empty(&peer->ksnp_tx_queue), + !list_empty(&peer->ksnp_zc_req_list)); list_for_each (tmp, &peer->ksnp_routes) { route = list_entry(tmp, ksock_route_t, ksnr_list); - CWARN ("Route: ref %d, schd %d, conn %d, cnted %d, " - "del %d\n", atomic_read(&route->ksnr_refcount), - route->ksnr_scheduled, route->ksnr_connecting, - route->ksnr_connected, route->ksnr_deleted); + CWARN("Route: ref %d, schd %d, conn %d, cnted %d, del %d\n", + atomic_read(&route->ksnr_refcount), + route->ksnr_scheduled, route->ksnr_connecting, + route->ksnr_connected, route->ksnr_deleted); } list_for_each (tmp, &peer->ksnp_conns) { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index d29f5f134b89..e6c1d3647952 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -551,19 +551,16 @@ ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx) if (!conn->ksnc_closing) { switch (rc) { case -ECONNRESET: - LCONSOLE_WARN("Host %pI4h reset our connection " - "while we were sending data; it may have " - "rebooted.\n", + LCONSOLE_WARN("Host %pI4h reset our connection while we were sending data; it may have rebooted.\n", &conn->ksnc_ipaddr); break; default: - LCONSOLE_WARN("There was an unexpected network error " - "while writing to %pI4h: %d.\n", + LCONSOLE_WARN("There was an unexpected network error while writing to %pI4h: %d.\n", &conn->ksnc_ipaddr, rc); break; } - CDEBUG(D_NET, "[%p] Error %d on write to %s" - " ip %pI4h:%d\n", conn, rc, + CDEBUG(D_NET, "[%p] Error %d on write to %s ip %pI4h:%d\n", + conn, rc, libcfs_id2str(conn->ksnc_peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -799,8 +796,7 @@ ksocknal_find_connectable_route_locked (ksock_peer_t *peer) if (!(route->ksnr_retry_interval == 0 || /* first attempt */ cfs_time_aftereq(now, route->ksnr_timeout))) { CDEBUG(D_NET, - "Too soon to retry route %pI4h " - "(cnted %d, interval %ld, %ld secs later)\n", + "Too soon to retry route %pI4h (cnted %d, interval %ld, %ld secs later)\n", &route->ksnr_ipaddr, route->ksnr_connected, route->ksnr_retry_interval, @@ -874,8 +870,8 @@ ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id) write_unlock_bh(g_lock); if ((id.pid & LNET_PID_USERFLAG) != 0) { - CERROR("Refusing to create a connection to " - "userspace process %s\n", libcfs_id2str(id)); + CERROR("Refusing to create a connection to userspace process %s\n", + libcfs_id2str(id)); return -EHOSTUNREACH; } @@ -1132,18 +1128,17 @@ ksocknal_process_receive (ksock_conn_t *conn) LASSERT (rc != -EAGAIN); if (rc == 0) - CDEBUG(D_NET, "[%p] EOF from %s" - " ip %pI4h:%d\n", conn, - libcfs_id2str(conn->ksnc_peer->ksnp_id), - &conn->ksnc_ipaddr, - conn->ksnc_port); + CDEBUG(D_NET, "[%p] EOF from %s ip %pI4h:%d\n", + conn, + libcfs_id2str(conn->ksnc_peer->ksnp_id), + &conn->ksnc_ipaddr, + conn->ksnc_port); else if (!conn->ksnc_closing) - CERROR("[%p] Error %d on read from %s" - " ip %pI4h:%d\n", - conn, rc, - libcfs_id2str(conn->ksnc_peer->ksnp_id), - &conn->ksnc_ipaddr, - conn->ksnc_port); + CERROR("[%p] Error %d on read from %s ip %pI4h:%d\n", + conn, rc, + libcfs_id2str(conn->ksnc_peer->ksnp_id), + &conn->ksnc_ipaddr, + conn->ksnc_port); /* it's not an error if conn is being closed */ ksocknal_close_conn_and_siblings (conn, @@ -1724,10 +1719,10 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, hello->kshm_magic != __swab32(LNET_PROTO_MAGIC) && hello->kshm_magic != le32_to_cpu (LNET_PROTO_TCP_MAGIC)) { /* Unexpected magic! */ - CERROR("Bad magic(1) %#08x (%#08x expected) from " - "%pI4h\n", __cpu_to_le32 (hello->kshm_magic), - LNET_PROTO_TCP_MAGIC, - &conn->ksnc_ipaddr); + CERROR("Bad magic(1) %#08x (%#08x expected) from %pI4h\n", + __cpu_to_le32 (hello->kshm_magic), + LNET_PROTO_TCP_MAGIC, + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1755,10 +1750,9 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, ksocknal_send_hello(ni, conn, ni->ni_nid, hello); } - CERROR("Unknown protocol version (%d.x expected)" - " from %pI4h\n", - conn->ksnc_proto->pro_version, - &conn->ksnc_ipaddr); + CERROR("Unknown protocol version (%d.x expected) from %pI4h\n", + conn->ksnc_proto->pro_version, + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1778,8 +1772,8 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, *incarnation = hello->kshm_src_incarnation; if (hello->kshm_src_nid == LNET_NID_ANY) { - CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY" - "from %pI4h\n", &conn->ksnc_ipaddr); + CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY from %pI4h\n", + &conn->ksnc_ipaddr); return -EPROTO; } @@ -1810,10 +1804,7 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn, if (peerid->pid != recv_id.pid || peerid->nid != recv_id.nid) { - LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host" - " %pI4h, but they claimed they were " - "%s; please check your Lustre " - "configuration.\n", + LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host %pI4h, but they claimed they were %s; please check your Lustre configuration.\n", libcfs_id2str(*peerid), &conn->ksnc_ipaddr, libcfs_id2str(recv_id)); @@ -2199,8 +2190,7 @@ ksocknal_connd (void *arg) if (ksocknal_connect(route)) { /* consecutive retry */ if (cons_retry++ > SOCKNAL_INSANITY_RECONN) { - CWARN("massive consecutive " - "re-connecting to %pI4h\n", + CWARN("massive consecutive re-connecting to %pI4h\n", &route->ksnr_ipaddr); cons_retry = 0; } @@ -2264,25 +2254,20 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) switch (error) { case ECONNRESET: - CNETERR("A connection with %s " - "(%pI4h:%d) was reset; " - "it may have rebooted.\n", + CNETERR("A connection with %s (%pI4h:%d) was reset; it may have rebooted.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; case ETIMEDOUT: - CNETERR("A connection with %s " - "(%pI4h:%d) timed out; the " - "network or node may be down.\n", + CNETERR("A connection with %s (%pI4h:%d) timed out; the network or node may be down.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; default: - CNETERR("An unexpected network error %d " - "occurred with %s " - "(%pI4h:%d\n", error, + CNETERR("An unexpected network error %d occurred with %s (%pI4h:%d\n", + error, libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -2297,8 +2282,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) conn->ksnc_rx_deadline)) { /* Timed out incomplete incoming message */ ksocknal_conn_addref(conn); - CNETERR("Timeout receiving from %s (%pI4h:%d), " - "state %d wanted %d left %d\n", + CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %d left %d\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, @@ -2315,8 +2299,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer) /* Timed out messages queued for sending or * buffered in the socket's send buffer */ ksocknal_conn_addref(conn); - CNETERR("Timeout sending data to %s (%pI4h:%d) " - "the network or that node may be down.\n", + CNETERR("Timeout sending data to %s (%pI4h:%d) the network or that node may be down.\n", libcfs_id2str(peer->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); @@ -2500,9 +2483,7 @@ ksocknal_check_peer_timeouts (int idx) spin_unlock(&peer->ksnp_lock); read_unlock(&ksocknal_data.ksnd_global_lock); - CERROR("Total %d stale ZC_REQs for peer %s detected; the " - "oldest(%p) timed out %ld secs ago, " - "resid: %d, wmem: %d\n", + CERROR("Total %d stale ZC_REQs for peer %s detected; the oldest(%p) timed out %ld secs ago, resid: %d, wmem: %d\n", n, libcfs_nid2str(peer->ksnp_id.nid), tx, cfs_duration_sec(cfs_time_current() - deadline), resid, conn->ksnc_sock->sk->sk_wmem_queued); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index 9dde548070af..ea9d80f40cab 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -515,8 +515,8 @@ ksocknal_send_hello_v1 (ksock_conn_t *conn, ksock_hello_msg_t *hello) hello->kshm_nips * sizeof(__u32), lnet_acceptor_timeout()); if (rc != 0) { - CNETERR("Error %d sending HELLO payload (%d)" - " to %pI4h/%d\n", rc, hello->kshm_nips, + CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", + rc, hello->kshm_nips, &conn->ksnc_ipaddr, conn->ksnc_port); } out: @@ -560,8 +560,8 @@ ksocknal_send_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello) hello->kshm_nips * sizeof(__u32), lnet_acceptor_timeout()); if (rc != 0) { - CNETERR("Error %d sending HELLO payload (%d)" - " to %pI4h/%d\n", rc, hello->kshm_nips, + CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n", + rc, hello->kshm_nips, &conn->ksnc_ipaddr, conn->ksnc_port); } @@ -595,10 +595,9 @@ ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello, /* ...and check we got what we expected */ if (hdr->type != cpu_to_le32 (LNET_MSG_HELLO)) { - CERROR("Expecting a HELLO hdr," - " but got type %d from %pI4h\n", - le32_to_cpu (hdr->type), - &conn->ksnc_ipaddr); + CERROR("Expecting a HELLO hdr, but got type %d from %pI4h\n", + le32_to_cpu(hdr->type), + &conn->ksnc_ipaddr); rc = -EPROTO; goto out; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 5754725f0745..c8c1ed84fe5c 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -668,8 +668,7 @@ lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg) rc = (ni->ni_lnd->lnd_eager_recv)(ni, msg->msg_private, msg, &msg->msg_private); if (rc != 0) { - CERROR("recv from %s / send to %s aborted: " - "eager_recv failed %d\n", + CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", libcfs_nid2str(msg->msg_rxpeer->lp_nid), libcfs_id2str(msg->msg_target), rc); LASSERT(rc < 0); /* required by my callers */ @@ -753,8 +752,7 @@ lnet_peer_alive_locked(lnet_peer_t *lp) if (time_before(now, next_query)) { if (lp->lp_alive) - CWARN("Unexpected aliveness of peer %s: " - "%d < %d (%d/%d)\n", + CWARN("Unexpected aliveness of peer %s: %d < %d (%d/%d)\n", libcfs_nid2str(lp->lp_nid), (int)now, (int)next_query, lnet_queryinterval, @@ -817,8 +815,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send) (msg->msg_md->md_flags & LNET_MD_FLAG_ABORTED) != 0) { lnet_net_unlock(cpt); - CNETERR("Aborting message for %s: LNetM[DE]Unlink() already " - "called on the MD/ME.\n", + CNETERR("Aborting message for %s: LNetM[DE]Unlink() already called on the MD/ME.\n", libcfs_id2str(msg->msg_target)); if (do_send) lnet_finalize(ni, msg, -ECANCELED); @@ -1220,8 +1217,8 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid) src_ni = lnet_nid2ni_locked(src_nid, cpt); if (src_ni == NULL) { lnet_net_unlock(cpt); - LCONSOLE_WARN("Can't send to %s: src %s is not a " - "local nid\n", libcfs_nid2str(dst_nid), + LCONSOLE_WARN("Can't send to %s: src %s is not a local nid\n", + libcfs_nid2str(dst_nid), libcfs_nid2str(src_nid)); return -EINVAL; } @@ -1283,8 +1280,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid) lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); - LCONSOLE_WARN("No route to %s via %s " - "(all routers down)\n", + LCONSOLE_WARN("No route to %s via %s (all routers down)\n", libcfs_id2str(msg->msg_target), libcfs_nid2str(src_nid)); return -EHOSTUNREACH; @@ -1676,8 +1672,7 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_PUT: - CWARN(" Ptl index %d, ack md %#llx.%#llx, " - "match bits %llu\n", + CWARN(" Ptl index %d, ack md %#llx.%#llx, match bits %llu\n", hdr->msg.put.ptl_index, hdr->msg.put.ack_wmd.wh_interface_cookie, hdr->msg.put.ack_wmd.wh_object_cookie, @@ -1688,8 +1683,8 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_GET: - CWARN(" Ptl index %d, return md %#llx.%#llx, " - "match bits %llu\n", hdr->msg.get.ptl_index, + CWARN(" Ptl index %d, return md %#llx.%#llx, match bits %llu\n", + hdr->msg.get.ptl_index, hdr->msg.get.return_wmd.wh_interface_cookie, hdr->msg.get.return_wmd.wh_object_cookie, hdr->msg.get.match_bits); @@ -1699,16 +1694,14 @@ lnet_print_hdr(lnet_hdr_t *hdr) break; case LNET_MSG_ACK: - CWARN(" dst md %#llx.%#llx, " - "manipulated length %d\n", + CWARN(" dst md %#llx.%#llx, manipulated length %d\n", hdr->msg.ack.dst_wmd.wh_interface_cookie, hdr->msg.ack.dst_wmd.wh_object_cookie, hdr->msg.ack.mlength); break; case LNET_MSG_REPLY: - CWARN(" dst md %#llx.%#llx, " - "length %d\n", + CWARN(" dst md %#llx.%#llx, length %d\n", hdr->msg.reply.dst_wmd.wh_interface_cookie, hdr->msg.reply.dst_wmd.wh_object_cookie, hdr->payload_length); @@ -1757,8 +1750,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, case LNET_MSG_REPLY: if (payload_length > (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) { - CERROR("%s, src %s: bad %s payload %d " - "(%d max expected)\n", + CERROR("%s, src %s: bad %s payload %d (%d max expected)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), lnet_msgtyp2str(type), @@ -1794,40 +1786,36 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, if (!for_me) { if (LNET_NIDNET(dest_nid) == LNET_NIDNET(ni->ni_nid)) { /* should have gone direct */ - CERROR("%s, src %s: Bad dest nid %s " - "(should have been sent direct)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad dest nid %s (should have been sent direct)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (lnet_islocalnid(dest_nid)) { /* dest is another local NI; sender should have used * this node's NID on its own network */ - CERROR("%s, src %s: Bad dest nid %s " - "(it's my nid but on a different network)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad dest nid %s (it's my nid but on a different network)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (rdma_req && type == LNET_MSG_GET) { - CERROR("%s, src %s: Bad optimized GET for %s " - "(final destination must be me)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Bad optimized GET for %s (final destination must be me)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); return -EPROTO; } if (!the_lnet.ln_routing) { - CERROR("%s, src %s: Dropping message for %s " - "(routing not enabled)\n", - libcfs_nid2str(from_nid), - libcfs_nid2str(src_nid), - libcfs_nid2str(dest_nid)); + CERROR("%s, src %s: Dropping message for %s (routing not enabled)\n", + libcfs_nid2str(from_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(dest_nid)); goto drop; } } @@ -1882,8 +1870,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid, rc = lnet_nid2peer_locked(&msg->msg_rxpeer, from_nid, cpt); if (rc != 0) { lnet_net_unlock(cpt); - CERROR("%s, src %s: Dropping %s " - "(error %d looking up sender)\n", + CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), lnet_msgtyp2str(type), rc); lnet_msg_free(msg); @@ -2003,12 +1990,11 @@ lnet_recv_delayed_msg_list(struct list_head *head) LASSERT(msg->msg_rxpeer != NULL); LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); - CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d " - "match %llu offset %d length %d.\n", - libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index, - msg->msg_hdr.msg.put.match_bits, - msg->msg_hdr.msg.put.offset, - msg->msg_hdr.payload_length); + CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", + libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index, + msg->msg_hdr.msg.put.match_bits, + msg->msg_hdr.msg.put.offset, + msg->msg_hdr.payload_length); lnet_recv_put(msg->msg_rxpeer->lp_ni, msg); } diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 720c73be4d3c..19ed696344fe 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -192,8 +192,7 @@ lnet_try_match_md(lnet_libmd_t *md, } /* Commit to this ME/MD */ - CDEBUG(D_NET, "Incoming %s index %x from %s of " - "length %d/%d into md %#llx [%d] + %d\n", + CDEBUG(D_NET, "Incoming %s index %x from %s of length %d/%d into md %#llx [%d] + %d\n", (info->mi_opc == LNET_MD_OP_PUT) ? "put" : "get", info->mi_portal, libcfs_id2str(info->mi_id), mlength, info->mi_rlength, md->md_lh.lh_cookie, md->md_niov, offset); diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index b5b8fb576bfb..59fb6bff0266 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -457,8 +457,7 @@ lnet_check_routes(void) lnet_net_unlock(cpt); - CERROR("Routes to %s via %s and %s not " - "supported\n", + CERROR("Routes to %s via %s and %s not supported\n", libcfs_net2str(net), libcfs_nid2str(nid1), libcfs_nid2str(nid2)); @@ -959,8 +958,7 @@ lnet_ping_router_locked (lnet_peer_t *rtr) secs = lnet_router_check_interval(rtr); CDEBUG(D_NET, - "rtr %s %d: deadline %lu ping_notsent %d alive %d " - "alive_count %d lp_ping_timestamp %lu\n", + "rtr %s %d: deadline %lu ping_notsent %d alive %d alive_count %d lp_ping_timestamp %lu\n", libcfs_nid2str(rtr->lp_nid), secs, rtr->lp_ping_deadline, rtr->lp_ping_notsent, rtr->lp_alive, rtr->lp_alive_count, rtr->lp_ping_timestamp); @@ -1010,9 +1008,7 @@ lnet_router_checker_start(void) if (check_routers_before_use && dead_router_check_interval <= 0) { - LCONSOLE_ERROR_MSG(0x10a, "'dead_router_check_interval' must be" - " set if 'check_routers_before_use' is set" - "\n"); + LCONSOLE_ERROR_MSG(0x10a, "'dead_router_check_interval' must be set if 'check_routers_before_use' is set\n"); return -EINVAL; } @@ -1370,8 +1366,8 @@ lnet_nrb_tiny_calculate(int npages) if (tiny_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "tiny_router_buffers=%d invalid when " - "routing enabled\n", tiny_router_buffers); + "tiny_router_buffers=%d invalid when routing enabled\n", + tiny_router_buffers); return -1; } @@ -1389,8 +1385,8 @@ lnet_nrb_small_calculate(int npages) if (small_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "small_router_buffers=%d invalid when " - "routing enabled\n", small_router_buffers); + "small_router_buffers=%d invalid when routing enabled\n", + small_router_buffers); return -1; } @@ -1408,8 +1404,8 @@ lnet_nrb_large_calculate(int npages) if (large_router_buffers < 0) { LCONSOLE_ERROR_MSG(0x10c, - "large_router_buffers=%d invalid when " - "routing enabled\n", large_router_buffers); + "large_router_buffers=%d invalid when routing enabled\n", + large_router_buffers); return -1; } @@ -1442,8 +1438,7 @@ lnet_rtrpools_alloc(int im_a_router) } else if (!strcmp(forwarding, "enabled")) { /* explicitly enabled */ } else { - LCONSOLE_ERROR_MSG(0x10b, "'forwarding' not set to either " - "'enabled' or 'disabled'\n"); + LCONSOLE_ERROR_MSG(0x10b, "'forwarding' not set to either 'enabled' or 'disabled'\n"); return -EINVAL; } @@ -1520,11 +1515,10 @@ lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when) /* can't do predictions... */ if (cfs_time_after(when, now)) { - CWARN ("Ignoring prediction from %s of %s %s " - "%ld seconds in the future\n", - (ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid), - libcfs_nid2str(nid), alive ? "up" : "down", - cfs_duration_sec(cfs_time_sub(when, now))); + CWARN("Ignoring prediction from %s of %s %s %ld seconds in the future\n", + (ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid), + libcfs_nid2str(nid), alive ? "up" : "down", + cfs_duration_sec(cfs_time_sub(when, now))); return -EINVAL; } diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index d9645f6bce49..46cde7036f1d 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -791,20 +791,17 @@ static struct lnet_portal_rotors portal_rotors[] = { { .pr_value = LNET_PTL_ROTOR_ON, .pr_name = "ON", - .pr_desc = "round-robin dispatch all PUT messages for " - "wildcard portals" + .pr_desc = "round-robin dispatch all PUT messages for wildcard portals" }, { .pr_value = LNET_PTL_ROTOR_RR_RT, .pr_name = "RR_RT", - .pr_desc = "round-robin dispatch routed PUT message for " - "wildcard portals" + .pr_desc = "round-robin dispatch routed PUT message for wildcard portals" }, { .pr_value = LNET_PTL_ROTOR_HASH_RT, .pr_name = "HASH_RT", - .pr_desc = "dispatch routed PUT message by hashing source " - "NID for wildcard portals" + .pr_desc = "dispatch routed PUT message by hashing source NID for wildcard portals" }, { .pr_value = -1, diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 5dad9f1f9462..49cb6543d538 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1208,8 +1208,7 @@ lstcon_test_nodes_add(lstcon_test_t *test, struct list_head *result_up) lstcon_rpc_trans_destroy(trans); /* return if any error */ - CDEBUG(D_NET, "Failed to add test %s, " - "RPC error %d, framework error %d\n", + CDEBUG(D_NET, "Failed to add test %s, RPC error %d, framework error %d\n", transop == LST_TRANS_TSBCLIADD ? "client" : "server", lstcon_trans_stat()->trs_rpc_errno, lstcon_trans_stat()->trs_fwk_errno); @@ -1885,8 +1884,7 @@ lstcon_session_feats_check(unsigned feats) spin_unlock(&console_session.ses_rpc_lock); if (rc != 0) { - CERROR("remote features %x do not match with " - "session features %x of console\n", + CERROR("remote features %x do not match with session features %x of console\n", feats, console_session.ses_features); } diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 82cc94b9cef2..cc9d1826ae66 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -291,8 +291,7 @@ sfw_server_rpc_done(struct srpc_server_rpc *rpc) int status = rpc->srpc_status; CDEBUG (D_NET, - "Incoming framework RPC done: " - "service %s, peer %s, status %s:%d\n", + "Incoming framework RPC done: service %s, peer %s, status %s:%d\n", sv->sv_name, libcfs_id2str(rpc->srpc_peer), swi_state2str(rpc->srpc_wi.swi_state), status); @@ -310,8 +309,7 @@ sfw_client_rpc_fini (srpc_client_rpc_t *rpc) LASSERT (atomic_read(&rpc->crpc_refcount) == 0); CDEBUG (D_NET, - "Outgoing framework RPC done: " - "service %d, peer %s, status %s:%d:%d\n", + "Outgoing framework RPC done: service %d, peer %s, status %s:%d:%d\n", rpc->crpc_service, libcfs_id2str(rpc->crpc_dest), swi_state2str(rpc->crpc_wi.swi_state), rpc->crpc_aborted, rpc->crpc_status); @@ -575,8 +573,8 @@ sfw_load_test(struct sfw_test_instance *tsi) rc = srpc_service_add_buffers(svc, nbuf); if (rc != 0) { - CWARN("Failed to reserve enough buffers: " - "service %s, %d needed: %d\n", svc->sv_name, nbuf, rc); + CWARN("Failed to reserve enough buffers: service %s, %d needed: %d\n", + svc->sv_name, nbuf, rc); /* NB: this error handler is not strictly correct, because * it may release more buffers than already allocated, * but it doesn't matter because request portal should @@ -1270,8 +1268,7 @@ sfw_handle_server_rpc(struct srpc_server_rpc *rpc) if (sn != NULL && sn->sn_features != request->msg_ses_feats) { - CNETERR("Features of framework RPC don't match " - "features of current session: %x/%x\n", + CNETERR("Features of framework RPC don't match features of current session: %x/%x\n", request->msg_ses_feats, sn->sn_features); reply->msg_body.reply.status = EPROTO; reply->msg_body.reply.sid = sn->sn_id; @@ -1348,8 +1345,7 @@ sfw_bulk_ready(struct srpc_server_rpc *rpc, int status) spin_lock(&sfw_data.fw_lock); if (status != 0) { - CERROR("Bulk transfer failed for RPC: " - "service %s, peer %s, status %d\n", + CERROR("Bulk transfer failed for RPC: service %s, peer %s, status %d\n", sv->sv_name, libcfs_id2str(rpc->srpc_peer), status); spin_unlock(&sfw_data.fw_lock); return -EIO; @@ -1664,12 +1660,10 @@ sfw_startup (void) } if (session_timeout == 0) - CWARN ("Zero session_timeout specified " - "- test sessions never expire.\n"); + CWARN("Zero session_timeout specified - test sessions never expire.\n"); if (rpc_timeout == 0) - CWARN ("Zero rpc_timeout specified " - "- test RPC never expire.\n"); + CWARN("Zero rpc_timeout specified - test RPC never expire.\n"); memset(&sfw_data, 0, sizeof(struct smoketest_framework)); @@ -1727,8 +1721,7 @@ sfw_startup (void) rc = srpc_service_add_buffers(sv, sv->sv_wi_total); if (rc != 0) { - CWARN("Failed to reserve enough buffers: " - "service %s, %d needed: %d\n", + CWARN("Failed to reserve enough buffers: service %s, %d needed: %d\n", sv->sv_name, sv->sv_wi_total, rc); error = -ENOMEM; } diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 92520c2e08fd..c6ef5b0d8de1 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -119,8 +119,8 @@ lnet_selftest_init(void) rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i, nthrs, &lst_sched_test[i]); if (rc != 0) { - CERROR("Failed to create CPT affinity WI scheduler " - "%d for LST\n", i); + CERROR("Failed to create CPT affinity WI scheduler %d for LST\n", + i); goto error; } } diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index c9a1a45923ed..f753add7bfb3 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -678,9 +678,7 @@ srpc_finish_service(struct srpc_service *sv) rpc = list_entry(scd->scd_rpc_active.next, struct srpc_server_rpc, srpc_list); - CNETERR("Active RPC %p on shutdown: sv %s, peer %s, " - "wi %s scheduled %d running %d, " - "ev fired %d type %d status %d lnet %d\n", + CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s scheduled %d running %d, ev fired %d type %d status %d lnet %d\n", rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer), swi_state2str(rpc->srpc_wi.swi_state), rpc->srpc_wi.swi_workitem.wi_scheduled, @@ -1236,20 +1234,18 @@ srpc_send_rpc (swi_workitem_t *wi) if (reply->msg_type != type || (reply->msg_magic != SRPC_MSG_MAGIC && reply->msg_magic != __swab32(SRPC_MSG_MAGIC))) { - CWARN ("Bad message from %s: type %u (%d expected)," - " magic %u (%d expected).\n", - libcfs_id2str(rpc->crpc_dest), - reply->msg_type, type, - reply->msg_magic, SRPC_MSG_MAGIC); + CWARN("Bad message from %s: type %u (%d expected), magic %u (%d expected).\n", + libcfs_id2str(rpc->crpc_dest), + reply->msg_type, type, + reply->msg_magic, SRPC_MSG_MAGIC); rc = -EBADMSG; break; } if (do_bulk && reply->msg_body.reply.status != 0) { - CWARN ("Remote error %d at %s, unlink bulk buffer in " - "case peer didn't initiate bulk transfer\n", - reply->msg_body.reply.status, - libcfs_id2str(rpc->crpc_dest)); + CWARN("Remote error %d at %s, unlink bulk buffer in case peer didn't initiate bulk transfer\n", + reply->msg_body.reply.status, + libcfs_id2str(rpc->crpc_dest)); LNetMDUnlink(rpc->crpc_bulk.bk_mdh); } @@ -1504,11 +1500,10 @@ srpc_lnet_ev_handler(lnet_event_t *ev) msg->msg_type != __swab32(type)) || (msg->msg_magic != SRPC_MSG_MAGIC && msg->msg_magic != __swab32(SRPC_MSG_MAGIC))) { - CERROR ("Dropping RPC (%s) from %s: " - "status %d mlength %d type %u magic %u.\n", - sv->sv_name, libcfs_id2str(ev->initiator), - ev->status, ev->mlength, - msg->msg_type, msg->msg_magic); + CERROR("Dropping RPC (%s) from %s: status %d mlength %d type %u magic %u.\n", + sv->sv_name, libcfs_id2str(ev->initiator), + ev->status, ev->mlength, + msg->msg_type, msg->msg_magic); /* NB can't call srpc_service_recycle_buffer here since * it may call LNetM[DE]Attach. The invalid magic tells diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h index 9d7e28ace42d..9cd8683573ce 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd.h +++ b/drivers/staging/lustre/lustre/include/linux/obd.h @@ -87,8 +87,7 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock, if (task == NULL) continue; - LCONSOLE_WARN("%s:%d: lock %p was acquired" - " by <%s:%d:%s:%d> for %lu seconds.\n", + LCONSOLE_WARN("%s:%d: lock %p was acquired by <%s:%d:%s:%d> for %lu seconds.\n", current->comm, current->pid, lock, task->comm, task->pid, lock->func, lock->line, diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 515b835ce14d..9b2833131744 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -368,8 +368,7 @@ static inline void check_lcd(char *obd_name, int index, if (strnlen((char*)lcd->lcd_uuid, length) == length) { lcd->lcd_uuid[length - 1] = '\0'; - LCONSOLE_ERROR("the client UUID (%s) on %s for exports" - "stored in last_rcvd(index = %d) is bad!\n", + LCONSOLE_ERROR("the client UUID (%s) on %s for exports stored in last_rcvd(index = %d) is bad!\n", lcd->lcd_uuid, obd_name, index); } } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c index b798daa094bc..e00478b9b50b 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c @@ -619,8 +619,7 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data) return 0; } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "sleeping"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, sleeping"); fwd.fwd_lock = lock; obd = class_exp2obd(lock->l_conn_export); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c index c21e30a074b9..249f3116d74a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c @@ -858,8 +858,8 @@ void ldlm_dump_export_locks(struct obd_export *exp) if (!list_empty(&exp->exp_locks_list)) { struct ldlm_lock *lock; - CERROR("dumping locks for export %p," - "ignore if the unmount doesn't hang\n", exp); + CERROR("dumping locks for export %p,ignore if the unmount doesn't hang\n", + exp); list_for_each_entry(lock, &exp->exp_locks_list, l_exp_refs_link) LDLM_ERROR(lock, "lock:"); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 6140130b6056..2c4af89eee7e 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -811,8 +811,7 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode) /* If we received a blocked AST and this was the last reference, * run the callback. */ if ((lock->l_flags & LDLM_FL_NS_SRV) && lock->l_export) - CERROR("FL_CBPENDING set on non-local lock--just a " - "warning\n"); + CERROR("FL_CBPENDING set on non-local lock--just a warning\n"); LDLM_DEBUG(lock, "final decref done on cbpending lock"); @@ -1641,8 +1640,7 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, ldlm_grant_lock(lock, NULL); goto out; } else { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } @@ -1904,8 +1902,7 @@ void ldlm_reprocess_all(struct ldlm_resource *res) LIST_HEAD(rpc_list); if (!ns_is_client(ldlm_res_to_ns(res))) { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } } @@ -2038,8 +2035,7 @@ int ldlm_cancel_locks_for_export_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, ecl->ecl_loop++; if ((ecl->ecl_loop & -ecl->ecl_loop) == ecl->ecl_loop) { CDEBUG(D_INFO, - "Cancel lock %p for export %p (loop %d), still have " - "%d locks left on hash table.\n", + "Cancel lock %p for export %p (loop %d), still have %d locks left on hash table.\n", lock, exp, ecl->ecl_loop, atomic_read(&hs->hs_count)); } @@ -2169,8 +2165,7 @@ struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode, lock->l_completion_ast(lock, 0, NULL); } } else { - CERROR("This is client-side-only module, cannot handle " - "LDLM_NAMESPACE_SERVER resource type lock.\n"); + CERROR("This is client-side-only module, cannot handle LDLM_NAMESPACE_SERVER resource type lock.\n"); LBUG(); } unlock_res_and_lock(lock); @@ -2229,18 +2224,15 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, if (resource == NULL) { libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lu " - "lvb_type: %d\n", - lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type); + " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type); va_end(args); return; } @@ -2248,90 +2240,78 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, switch (resource->lr_type) { case LDLM_EXTENT: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s [%llu->%llu] " - "(req %llu->%llu) flags: %#llx nid: %s remote: " - "%#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_extent.start, - lock->l_policy_data.l_extent.end, - lock->l_req_extent.start, lock->l_req_extent.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s [%llu->%llu] (req %llu->%llu) flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_extent.start, + lock->l_policy_data.l_extent.end, + lock->l_req_extent.start, lock->l_req_extent.end, + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; case LDLM_FLOCK: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s pid: %d " - "[%llu->%llu] flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lu\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_flock.pid, - lock->l_policy_data.l_flock.start, - lock->l_policy_data.l_flock.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s pid: %d [%llu->%llu] flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu\n", + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_flock.pid, + lock->l_policy_data.l_flock.start, + lock->l_policy_data.l_flock.end, + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout); break; case LDLM_IBITS: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" bits %#llx rrc: %d type: %s " - "flags: %#llx nid: %s remote: %#llx expref: %d " - "pid: %u timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - lock->l_policy_data.l_inodebits.bits, - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " bits %#llx rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + lock->l_policy_data.l_inodebits.bits, + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; default: libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s flags: %#llx " - "nid: %s remote: %#llx expref: %d pid: %u " - "timeout: %lu lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n", + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + atomic_read(&lock->l_refc), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_flags, nid, lock->l_remote_handle.cookie, + exp ? atomic_read(&exp->exp_refcount) : -99, + lock->l_pid, lock->l_callback_timeout, + lock->l_lvb_type); break; } va_end(args); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index 91cf7ebae114..5fb9d842f7b9 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -210,9 +210,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, LASSERT(lock->l_lvb_data != NULL); if (unlikely(lock->l_lvb_len < lvb_len)) { - LDLM_ERROR(lock, "Replied LVB is larger than " - "expectation, expected = %d, " - "replied = %d", + LDLM_ERROR(lock, "Replied LVB is larger than expectation, expected = %d, replied = %d", lock->l_lvb_len, lvb_len); rc = -EINVAL; goto out; @@ -639,8 +637,8 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) lock = ldlm_handle2lock_long(&dlm_req->lock_handle[0], 0); if (!lock) { - CDEBUG(D_DLMTRACE, "callback on lock %#llx - lock " - "disappeared\n", dlm_req->lock_handle[0].cookie); + CDEBUG(D_DLMTRACE, "callback on lock %#llx - lock disappeared\n", + dlm_req->lock_handle[0].cookie); rc = ldlm_callback_reply(req, -EINVAL); ldlm_callback_errmsg(req, "Operate with invalid parameter", rc, &dlm_req->lock_handle[0]); @@ -663,8 +661,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) if (((lock->l_flags & LDLM_FL_CANCELING) && (lock->l_flags & LDLM_FL_BL_DONE)) || (lock->l_flags & LDLM_FL_FAILED)) { - LDLM_DEBUG(lock, "callback on lock " - "%#llx - lock disappeared\n", + LDLM_DEBUG(lock, "callback on lock %#llx - lock disappeared\n", dlm_req->lock_handle[0].cookie); unlock_res_and_lock(lock); LDLM_LOCK_RELEASE(lock); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index c80c76a6e181..0e1ab06d2543 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -614,8 +614,8 @@ int ldlm_pool_shrink(struct ldlm_pool *pl, int nr, lprocfs_counter_add(pl->pl_stats, LDLM_POOL_SHRINK_FREED_STAT, cancel); - CDEBUG(D_DLMTRACE, "%s: request to shrink %d locks, " - "shrunk %d\n", pl->pl_name, nr, cancel); + CDEBUG(D_DLMTRACE, "%s: request to shrink %d locks, shrunk %d\n", + pl->pl_name, nr, cancel); } } return cancel; @@ -1194,10 +1194,8 @@ int ldlm_pools_recalc(ldlm_side_t client) * of limit. */ if (nr_l >= 2 * (LDLM_POOL_HOST_L / 3)) { - CWARN("\"Modest\" pools eat out 2/3 of server locks " - "limit (%d of %lu). This means that you have too " - "many clients for this amount of server RAM. " - "Upgrade server!\n", nr_l, LDLM_POOL_HOST_L); + CWARN("\"Modest\" pools eat out 2/3 of server locks limit (%d of %lu). This means that you have too many clients for this amount of server RAM. Upgrade server!\n", + nr_l, LDLM_POOL_HOST_L); equal = 1; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 9ce437b18793..95e71a0922f3 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -102,9 +102,7 @@ int ldlm_expired_completion_wait(void *data) lock->l_last_activity, cfs_time_sub(get_seconds(), lock->l_last_activity)); - LDLM_DEBUG(lock, "lock timed out (enqueued at "CFS_TIME_T", " - CFS_DURATION_T"s ago); not entering recovery in " - "server code, just going back to sleep", + LDLM_DEBUG(lock, "lock timed out (enqueued at " CFS_TIME_T ", " CFS_DURATION_T "s ago); not entering recovery in server code, just going back to sleep", lock->l_last_activity, cfs_time_sub(get_seconds(), lock->l_last_activity)); @@ -191,8 +189,7 @@ int ldlm_completion_ast_async(struct ldlm_lock *lock, __u64 flags, void *data) return ldlm_completion_tail(lock); } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "going forward"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, going forward"); ldlm_reprocess_all(lock->l_resource); return 0; } @@ -240,8 +237,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data) return 0; } - LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, " - "sleeping"); + LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, sleeping"); noreproc: @@ -324,8 +320,7 @@ int ldlm_blocking_ast_nocheck(struct ldlm_lock *lock) if (rc < 0) CERROR("ldlm_cli_cancel: %d\n", rc); } else { - LDLM_DEBUG(lock, "Lock still has references, will be " - "cancelled later"); + LDLM_DEBUG(lock, "Lock still has references, will be cancelled later"); } return 0; } @@ -483,8 +478,7 @@ static void failed_lock_cleanup(struct ldlm_namespace *ns, if (need_cancel) LDLM_DEBUG(lock, - "setting FL_LOCAL_ONLY | LDLM_FL_FAILED | " - "LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING"); + "setting FL_LOCAL_ONLY | LDLM_FL_FAILED | LDLM_FL_ATOMIC_CB | LDLM_FL_CBPENDING"); else LDLM_DEBUG(lock, "lock was granted or failed in race"); @@ -557,8 +551,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, rc = size; goto cleanup; } else if (unlikely(size > lvb_len)) { - LDLM_ERROR(lock, "Replied LVB is larger than " - "expectation, expected = %d, replied = %d", + LDLM_ERROR(lock, "Replied LVB is larger than expectation, expected = %d, replied = %d", lvb_len, size); rc = -EINVAL; goto cleanup; @@ -1107,8 +1100,7 @@ static __u64 ldlm_cli_cancel_local(struct ldlm_lock *lock) unlock_res_and_lock(lock); if (local_only) { - CDEBUG(D_DLMTRACE, "not sending request (at caller's " - "instruction)\n"); + CDEBUG(D_DLMTRACE, "not sending request (at caller's instruction)\n"); rc = LDLM_FL_LOCAL_ONLY; } ldlm_lock_cancel(lock); @@ -1223,8 +1215,7 @@ int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *cancels, rc = ptlrpc_queue_wait(req); } if (rc == LUSTRE_ESTALE) { - CDEBUG(D_DLMTRACE, "client/server (nid %s) " - "out of sync -- not fatal\n", + CDEBUG(D_DLMTRACE, "client/server (nid %s) out of sync -- not fatal\n", libcfs_nid2str(req->rq_import-> imp_connection->c_peer.nid)); rc = 0; @@ -1235,8 +1226,8 @@ int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *cancels, } else if (rc != ELDLM_OK) { /* -ESHUTDOWN is common on umount */ CDEBUG_LIMIT(rc == -ESHUTDOWN ? D_DLMTRACE : D_ERROR, - "Got rc %d from cancel RPC: " - "canceling anyway\n", rc); + "Got rc %d from cancel RPC: canceling anyway\n", + rc); break; } sent = count; @@ -2114,8 +2105,7 @@ static int replay_lock_interpret(const struct lu_env *env, lock = ldlm_handle2lock(&aa->lock_handle); if (!lock) { - CERROR("received replay ack for unknown local cookie %#llx" - " remote cookie %#llx from server %s id %s\n", + CERROR("received replay ack for unknown local cookie %#llx remote cookie %#llx from server %s id %s\n", aa->lock_handle.cookie, reply->lock_handle.cookie, req->rq_export->exp_client_uuid.uuid, libcfs_id2str(req->rq_peer)); @@ -2243,9 +2233,8 @@ static void ldlm_cancel_unused_locks_for_replay(struct ldlm_namespace *ns) int canceled; LIST_HEAD(cancels); - CDEBUG(D_DLMTRACE, "Dropping as many unused locks as possible before" - "replay for namespace %s (%d)\n", - ldlm_ns_name(ns), ns->ns_nr_unused); + CDEBUG(D_DLMTRACE, "Dropping as many unused locks as possible before replay for namespace %s (%d)\n", + ldlm_ns_name(ns), ns->ns_nr_unused); /* We don't need to care whether or not LRU resize is enabled * because the LDLM_CANCEL_NO_WAIT policy doesn't use the diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 8b20a838b7f2..397adbe3ce0e 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -215,8 +215,8 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, LDLM_CANCEL_PASSED); if (canceled < unused) { CDEBUG(D_DLMTRACE, - "not all requested locks are canceled, " - "requested: %d, canceled: %d\n", unused, + "not all requested locks are canceled, requested: %d, canceled: %d\n", + unused, canceled); return -EINVAL; } @@ -735,8 +735,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q, } else { ldlm_resource_unlink_lock(lock); unlock_res(res); - LDLM_DEBUG(lock, "Freeing a lock still held by a " - "client node"); + LDLM_DEBUG(lock, "Freeing a lock still held by a client node"); ldlm_lock_destroy(lock); } LDLM_LOCK_RELEASE(lock); @@ -818,16 +817,14 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force) /* Forced cleanups should be able to reclaim all references, * so it's safe to wait forever... we can't leak locks... */ if (force && rc == -ETIMEDOUT) { - LCONSOLE_ERROR("Forced cleanup waiting for %s " - "namespace with %d resources in use, " - "(rc=%d)\n", ldlm_ns_name(ns), + LCONSOLE_ERROR("Forced cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n", + ldlm_ns_name(ns), atomic_read(&ns->ns_bref), rc); goto force_wait; } if (atomic_read(&ns->ns_bref)) { - LCONSOLE_ERROR("Cleanup waiting for %s namespace " - "with %d resources in use, (rc=%d)\n", + LCONSOLE_ERROR("Cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n", ldlm_ns_name(ns), atomic_read(&ns->ns_bref), rc); return ELDLM_NAMESPACE_EXISTS; @@ -1404,8 +1401,8 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res) LDLM_DEBUG_LIMIT(level, lock, "###"); if (!(level & D_CANTMASK) && ++granted > ldlm_dump_granted_max) { - CDEBUG(level, "only dump %d granted locks to " - "avoid DDOS.\n", granted); + CDEBUG(level, "only dump %d granted locks to avoid DDOS.\n", + granted); break; } } diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 859129d8ddc8..a7a7ac626aaf 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -318,9 +318,7 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys) if (t >= 1 && matched == n) { /* don't print warning for lctl set_param debug=0 or -1 */ if (m != 0 && m != -1) - CWARN("You are trying to use a numerical value for the " - "mask - this will be deprecated in a future " - "release.\n"); + CWARN("You are trying to use a numerical value for the mask - this will be deprecated in a future release.\n"); *mask = m; return 0; } @@ -375,8 +373,8 @@ void libcfs_debug_dumplog(void) (void *)(long)current_pid(), "libcfs_debug_dumper"); if (IS_ERR(dumper)) - pr_err("LustreError: cannot start log dump thread:" - " %ld\n", PTR_ERR(dumper)); + pr_err("LustreError: cannot start log dump thread: %ld\n", + PTR_ERR(dumper)); else schedule(); diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index 32da78357c7e..2d1e6729e996 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -1121,8 +1121,7 @@ cfs_hash_destroy(struct cfs_hash *hs) cfs_hash_bd_for_each_hlist(hs, &bd, hhead) { hlist_for_each_safe(hnode, pos, hhead) { LASSERTF(!cfs_hash_with_assert_empty(hs), - "hash %s bucket %u(%u) is not " - " empty: %u items left\n", + "hash %s bucket %u(%u) is not empty: %u items left\n", hs->hs_name, bd.bd_bucket->hsb_index, bd.bd_offset, bd.bd_bucket->hsb_count); /* can't assert key valicate, because we diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 224c65b5ce4e..05f7595f18aa 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -333,8 +333,8 @@ cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) /* caller doesn't know the partition ID */ cpt = cptab->ctb_cpu2cpt[cpu]; if (cpt < 0) { /* not set in this CPT-table */ - CDEBUG(D_INFO, "Try to unset cpu %d which is " - "not in CPT-table %p\n", cpt, cptab); + CDEBUG(D_INFO, "Try to unset cpu %d which is not in CPT-table %p\n", + cpt, cptab); return; } @@ -384,8 +384,8 @@ cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) int i; if (cpus_weight(*mask) == 0 || any_online_cpu(*mask) == NR_CPUS) { - CDEBUG(D_INFO, "No online CPU is found in the CPU mask " - "for CPU partition %d\n", cpt); + CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n", + cpt); return 0; } @@ -579,9 +579,8 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) } if (any_online_cpu(*cpumask) == NR_CPUS) { - CERROR("No online CPU found in CPU partition %d, did someone " - "do CPU hotplug on system? You might need to reload " - "Lustre modules to keep system working well.\n", cpt); + CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n", + cpt); return -EINVAL; } @@ -737,16 +736,12 @@ cfs_cpt_table_create(int ncpt) ncpt = rc; if (ncpt > num_online_cpus() || ncpt > 4 * rc) { - CWARN("CPU partition number %d is larger than suggested " - "value (%d), your system may have performance" - "issue or run out of memory while under pressure\n", + CWARN("CPU partition number %d is larger than suggested value (%d), your system may have performance issue or run out of memory while under pressure\n", ncpt, rc); } if (num_online_cpus() % ncpt != 0) { - CERROR("CPU number %d is not multiple of cpu_npartition %d, " - "please try different cpu_npartitions value or" - "set pattern string by cpu_pattern=STRING\n", + CERROR("CPU number %d is not multiple of cpu_npartition %d, please try different cpu_npartitions value or set pattern string by cpu_pattern=STRING\n", (int)num_online_cpus(), ncpt); goto failed; } @@ -796,8 +791,7 @@ cfs_cpt_table_create(int ncpt) if (cpt != ncpt || num != cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)) { - CERROR("Expect %d(%d) CPU partitions but got %d(%d), " - "CPU hotplug/unplug while setting?\n", + CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n", cptab->ctb_nparts, num, cpt, cpus_weight(*cptab->ctb_parts[ncpt - 1].cpt_cpumask)); goto failed; @@ -808,8 +802,7 @@ cfs_cpt_table_create(int ncpt) return cptab; failed: - CERROR("Failed to setup CPU-partition-table with %d " - "CPU-partitions, online HW nodes: %d, HW cpus: %d.\n", + CERROR("Failed to setup CPU-partition-table with %d CPU-partitions, online HW nodes: %d, HW cpus: %d.\n", ncpt, num_online_nodes(), num_online_cpus()); if (mask != NULL) @@ -975,9 +968,8 @@ cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) warn = any_online_cpu(*cpt_data.cpt_cpumask) >= nr_cpu_ids; mutex_unlock(&cpt_data.cpt_mutex); CDEBUG(warn ? D_WARNING : D_INFO, - "Lustre: can't support CPU plug-out well now, " - "performance and stability could be impacted " - "[CPU %u action: %lx]\n", cpu, action); + "Lustre: can't support CPU plug-out well now, performance and stability could be impacted [CPU %u action: %lx]\n", + cpu, action); } return NOTIFY_OK; diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c index 3298ddf6d3be..12005a71aa73 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c @@ -87,8 +87,7 @@ void libcfs_run_debug_log_upcall(char *file) rc = call_usermodehelper(argv[0], argv, envp, 1); if (rc < 0 && rc != -ENOENT) { - CERROR("Error %d invoking LNET debug log upcall %s %s; " - "check /proc/sys/lnet/debug_log_upcall\n", + CERROR("Error %d invoking LNET debug log upcall %s %s; check /proc/sys/lnet/debug_log_upcall\n", rc, argv[0], argv[1]); } else { CDEBUG(D_HA, "Invoked LNET debug log upcall %s %s\n", @@ -114,8 +113,7 @@ void libcfs_run_upcall(char **argv) rc = call_usermodehelper(argv[0], argv, envp, 1); if (rc < 0 && rc != -ENOENT) { - CERROR("Error %d invoking LNET upcall %s %s%s%s%s%s%s%s%s; " - "check /proc/sys/lnet/upcall\n", + CERROR("Error %d invoking LNET upcall %s %s%s%s%s%s%s%s%s; check /proc/sys/lnet/upcall\n", rc, argv[0], argv[1], argc < 3 ? "" : ",", argc < 3 ? "" : argv[2], argc < 4 ? "" : ",", argc < 4 ? "" : argv[3], diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c index 939b33dd6520..b91a1f95bbd0 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c @@ -279,8 +279,7 @@ libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout) rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); if (rc != 0) { - CERROR("Can't set socket send timeout " - "%ld.%06d: %d\n", + CERROR("Can't set socket send timeout %ld.%06d: %d\n", (long)tv.tv_sec, (int)tv.tv_usec, rc); return rc; } diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index 7e3f6a45da00..5fded5a363bd 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -196,8 +196,7 @@ static void cfs_tcd_shrink(struct cfs_trace_cpu_data *tcd) */ if (printk_ratelimit()) - printk(KERN_WARNING "debug daemon buffer overflowed; " - "discarding 10%% of pages (%d of %ld)\n", + printk(KERN_WARNING "debug daemon buffer overflowed; discarding 10%% of pages (%d of %ld)\n", pgcount + 1, tcd->tcd_cur_pages); INIT_LIST_HEAD(&pc.pc_pages); @@ -357,8 +356,8 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata, } if (*(string_buf+needed-1) != '\n') - printk(KERN_INFO "format at %s:%d:%s doesn't end in " - "newline\n", file, msgdata->msg_line, msgdata->msg_fn); + printk(KERN_INFO "format at %s:%d:%s doesn't end in newline\n", + file, msgdata->msg_line, msgdata->msg_fn); header.ph_len = known_size + needed; debug_buf = (char *)page_address(tage->page) + tage->used; @@ -715,8 +714,8 @@ int cfs_tracefile_dump_all_pages(char *filename) kunmap(tage->page); if (rc != (int)tage->used) { - printk(KERN_WARNING "wanted to write %u but wrote " - "%d\n", tage->used, rc); + printk(KERN_WARNING "wanted to write %u but wrote %d\n", + tage->used, rc); put_pages_back(&pc); __LASSERT(list_empty(&pc.pc_pages)); break; @@ -875,8 +874,8 @@ int cfs_trace_daemon_command(char *str) strcpy(cfs_tracefile, str); printk(KERN_INFO - "Lustre: debug daemon will attempt to start writing " - "to %s (%lukB max)\n", cfs_tracefile, + "Lustre: debug daemon will attempt to start writing to %s (%lukB max)\n", + cfs_tracefile, (long)(cfs_tracefile_size >> 10)); cfs_trace_start_thread(); @@ -914,15 +913,15 @@ int cfs_trace_set_debug_mb(int mb) if (mb < num_possible_cpus()) { printk(KERN_WARNING - "Lustre: %d MB is too small for debug buffer size, " - "setting it to %d MB.\n", mb, num_possible_cpus()); + "Lustre: %d MB is too small for debug buffer size, setting it to %d MB.\n", + mb, num_possible_cpus()); mb = num_possible_cpus(); } if (mb > limit) { printk(KERN_WARNING - "Lustre: %d MB is too large for debug buffer size, " - "setting it to %d MB.\n", mb, limit); + "Lustre: %d MB is too large for debug buffer size, setting it to %d MB.\n", + mb, limit); mb = limit; } @@ -1004,8 +1003,8 @@ static int tracefiled(void *arg) if (IS_ERR(filp)) { rc = PTR_ERR(filp); filp = NULL; - printk(KERN_WARNING "couldn't open %s: " - "%d\n", cfs_tracefile, rc); + printk(KERN_WARNING "couldn't open %s: %d\n", + cfs_tracefile, rc); } } cfs_tracefile_read_unlock(); @@ -1034,8 +1033,8 @@ static int tracefiled(void *arg) kunmap(tage->page); if (rc != (int)tage->used) { - printk(KERN_WARNING "wanted to write %u " - "but wrote %d\n", tage->used, rc); + printk(KERN_WARNING "wanted to write %u but wrote %d\n", + tage->used, rc); put_pages_back(&pc); __LASSERT(list_empty(&pc.pc_pages)); } @@ -1047,8 +1046,7 @@ static int tracefiled(void *arg) if (!list_empty(&pc.pc_pages)) { int i; - printk(KERN_ALERT "Lustre: trace pages aren't " - " empty\n"); + printk(KERN_ALERT "Lustre: trace pages aren't empty\n"); printk(KERN_ERR "total cpus(%d): ", num_possible_cpus()); for (i = 0; i < num_possible_cpus(); i++) @@ -1061,8 +1059,8 @@ static int tracefiled(void *arg) i = 0; list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) - printk(KERN_ERR "page %d belongs to cpu " - "%d\n", ++i, tage->cpu); + printk(KERN_ERR "page %d belongs to cpu %d\n", + ++i, tage->cpu); printk(KERN_ERR "There are %d pages unwritten\n", i); } diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 439e4875b05c..5f03c5fbb098 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -259,9 +259,9 @@ void ll_invalidate_aliases(struct inode *inode) ll_lock_dcache(inode); ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { - CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p " - "inode %p flags %d\n", dentry->d_name.len, - dentry->d_name.name, dentry, dentry->d_parent, + CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p inode %p flags %d\n", + dentry->d_name.len, dentry->d_name.name, + dentry, dentry->d_parent, dentry->d_inode, dentry->d_flags); if (unlikely(dentry == dentry->d_sb->s_root)) { diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 661b2cf2f804..1f181c80838c 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -228,8 +228,8 @@ static int ll_dir_filler(void *_hash, struct page *page0) if (ll_pagevec_add(&lru_pvec, page) == 0) ll_pagevec_lru_add_file(&lru_pvec); } else { - CDEBUG(D_VFSTRACE, "page %lu add to page cache failed:" - " %d\n", offset, ret); + CDEBUG(D_VFSTRACE, "page %lu add to page cache failed: %d\n", + offset, ret); } page_cache_release(page); } @@ -600,8 +600,8 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx) int api32 = ll_need_32bit_api(sbi); int rc; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu " - " 32bit_api %d\n", inode->i_ino, inode->i_generation, + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu 32bit_api %d\n", + inode->i_ino, inode->i_generation, inode, (unsigned long)lfd->lfd_pos, i_size_read(inode), api32); if (lfd->lfd_pos == MDS_DIR_END_OFF) { @@ -715,10 +715,9 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, break; } default: { - CDEBUG(D_IOCTL, "bad userland LOV MAGIC:" - " %#08x != %#08x nor %#08x\n", - lump->lmm_magic, LOV_USER_MAGIC_V1, - LOV_USER_MAGIC_V3); + CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n", + lump->lmm_magic, LOV_USER_MAGIC_V1, + LOV_USER_MAGIC_V3); return -EINVAL; } } @@ -814,8 +813,8 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, rc = md_getattr(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr failed on inode " - "%lu/%u: rc %d\n", inode->i_ino, + CDEBUG(D_INFO, "md_getattr failed on inode %lu/%u: rc %d\n", + inode->i_ino, inode->i_generation, rc); goto out; } @@ -1013,8 +1012,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) copy->hc_hai.hai_action == HSMA_ARCHIVE); iput(inode); if (rc) { - CDEBUG(D_HSM, "Could not read file data version. " - "Request could not be confirmed.\n"); + CDEBUG(D_HSM, "Could not read file data version. Request could not be confirmed.\n"); if (hpk.hpk_errval == 0) hpk.hpk_errval = -rc; goto progress; @@ -1028,8 +1026,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) * to check anyway. */ if ((copy->hc_hai.hai_action == HSMA_ARCHIVE) && (copy->hc_data_version != data_version)) { - CDEBUG(D_HSM, "File data version mismatched. " - "File content was changed during archiving. " + CDEBUG(D_HSM, "File data version mismatched. File content was changed during archiving. " DFID", start:%#llx current:%#llx\n", PFID(©->hc_hai.hai_fid), copy->hc_data_version, data_version); diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index a5acc98a1c99..234c7143008a 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -170,8 +170,8 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, * OSTs and send setattr to back to MDS. */ rc = ll_som_update(inode, op_data); if (rc) { - CERROR("inode %lu mdc Size-on-MDS update failed: " - "rc = %d\n", inode->i_ino, rc); + CERROR("inode %lu mdc Size-on-MDS update failed: rc = %d\n", + inode->i_ino, rc); rc = 0; } } else if (rc) { @@ -989,8 +989,8 @@ int ll_inode_getattr(struct inode *inode, struct obdo *obdo, struct ost_id *oi = lsm ? &lsm->lsm_oi : &obdo->o_oi; obdo_refresh_inode(inode, obdo, obdo->o_valid); - CDEBUG(D_INODE, "objid "DOSTID" size %llu, blocks %llu," - " blksize %lu\n", POSTID(oi), i_size_read(inode), + CDEBUG(D_INODE, "objid " DOSTID " size %llu, blocks %llu, blksize %lu\n", + POSTID(oi), i_size_read(inode), (unsigned long long)inode->i_blocks, 1UL << inode->i_blkbits); } @@ -1418,8 +1418,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, rc = md_getattr_name(sbi->ll_md_exp, op_data, &req); ll_finish_md_op_data(op_data); if (rc < 0) { - CDEBUG(D_INFO, "md_getattr_name failed " - "on %s: rc %d\n", filename, rc); + CDEBUG(D_INFO, "md_getattr_name failed on %s: rc %d\n", + filename, rc); goto out; } @@ -2233,8 +2233,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (cmd == LL_IOC_SETFLAGS) { if ((flags & LL_FILE_IGNORE_LOCK) && !(file->f_flags & O_DIRECT)) { - CERROR("%s: unable to disable locking on " - "non-O_DIRECT file\n", current->comm); + CERROR("%s: unable to disable locking on non-O_DIRECT file\n", + current->comm); return -EINVAL; } diff --git a/drivers/staging/lustre/lustre/llite/llite_capa.c b/drivers/staging/lustre/lustre/llite/llite_capa.c index b1e39ee412cd..aec9a44120c0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_capa.c +++ b/drivers/staging/lustre/lustre/llite/llite_capa.c @@ -540,8 +540,7 @@ static int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa) if (rc == -EIO && !capa_is_expired(ocapa)) { delay_capa_renew(ocapa, 120); DEBUG_CAPA(D_ERROR, &ocapa->c_capa, - "renewal failed: -EIO, " - "retry in 2 mins"); + "renewal failed: -EIO, retry in 2 mins"); ll_capa_renewal_retries++; goto retry; } else { diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c index 84e0003f2daf..21b4a5026776 100644 --- a/drivers/staging/lustre/lustre/llite/llite_close.c +++ b/drivers/staging/lustre/lustre/llite/llite_close.c @@ -90,8 +90,7 @@ void ll_queue_done_writing(struct inode *inode, unsigned long flags) struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq; if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CWARN("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", + CWARN("ino %lu/%u(flags %u) som valid it just after recovery\n", inode->i_ino, inode->i_generation, lli->lli_flags); /* DONE_WRITING is allowed and inode has no dirty page. */ @@ -124,8 +123,8 @@ void ll_done_writing_attr(struct inode *inode, struct md_op_data *op_data) op_data->op_flags |= MF_SOM_CHANGE; /* Check if Size-on-MDS attributes are valid. */ if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CERROR("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", inode->i_ino, inode->i_generation, + CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n", + inode->i_ino, inode->i_generation, lli->lli_flags); if (!cl_local_size(inode)) { @@ -218,8 +217,8 @@ int ll_som_update(struct inode *inode, struct md_op_data *op_data) LASSERT(op_data != NULL); if (lli->lli_flags & LLIF_MDS_SIZE_LOCK) - CERROR("ino %lu/%u(flags %u) som valid it just after " - "recovery\n", inode->i_ino, inode->i_generation, + CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n", + inode->i_ino, inode->i_generation, lli->lli_flags); OBDO_ALLOC(oa); @@ -238,9 +237,8 @@ int ll_som_update(struct inode *inode, struct md_op_data *op_data) if (rc) { oa->o_valid = 0; if (rc != -ENOENT) - CERROR("inode_getattr failed (%d): unable to " - "send a Size-on-MDS attribute update " - "for inode %lu/%u\n", rc, inode->i_ino, + CERROR("inode_getattr failed (%d): unable to send a Size-on-MDS attribute update for inode %lu/%u\n", + rc, inode->i_ino, inode->i_generation); } else { CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n", diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 2845aab282ea..79fc29b3710c 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1435,8 +1435,8 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, * case the dcache being cleared */ if (it->d.lustre.it_remote_lock_mode) { handle.cookie = it->d.lustre.it_remote_lock_handle; - CDEBUG(D_DLMTRACE, "setting l_data to inode %p" - "(%lu/%u) for remote lock %#llx\n", inode, + CDEBUG(D_DLMTRACE, "setting l_data to inode %p(%lu/%u) for remote lock %#llx\n", + inode, inode->i_ino, inode->i_generation, handle.cookie); md_set_lock_data(exp, &handle.cookie, inode, NULL); @@ -1444,8 +1444,8 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, handle.cookie = it->d.lustre.it_lock_handle; - CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)" - " for lock %#llx\n", inode, inode->i_ino, + CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u) for lock %#llx\n", + inode, inode->i_ino, inode->i_generation, handle.cookie); md_set_lock_data(exp, &handle.cookie, inode, @@ -1489,8 +1489,8 @@ static inline void __d_lustre_invalidate(struct dentry *dentry) */ static inline void d_lustre_invalidate(struct dentry *dentry, int nested) { - CDEBUG(D_DENTRY, "invalidate dentry %.*s (%p) parent %p inode %p " - "refc %d\n", dentry->d_name.len, dentry->d_name.name, dentry, + CDEBUG(D_DENTRY, "invalidate dentry %.*s (%p) parent %p inode %p refc %d\n", + dentry->d_name.len, dentry->d_name.name, dentry, dentry->d_parent, dentry->d_inode, d_count(dentry)); spin_lock_nested(&dentry->d_lock, diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index afb433a33d25..3b0336029da3 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -253,10 +253,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_connect(NULL, &sbi->ll_md_exp, obd, &sbi->ll_sb_uuid, data, NULL); if (err == -EBUSY) { - LCONSOLE_ERROR_MSG(0x14f, "An MDT (md %s) is performing " - "recovery, of which this client is not a " - "part. Please wait for recovery to complete," - " abort, or time out.\n", md); + LCONSOLE_ERROR_MSG(0x14f, "An MDT (md %s) is performing recovery, of which this client is not a part. Please wait for recovery to complete, abort, or time out.\n", + md); goto out; } else if (err) { CERROR("cannot connect to %s: rc = %d\n", md, err); @@ -268,8 +266,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_fid_init(sbi->ll_md_exp->exp_obd, sbi->ll_md_exp, LUSTRE_SEQ_METADATA); if (err) { - CERROR("%s: Can't init metadata layer FID infrastructure, " - "rc = %d\n", sbi->ll_md_exp->exp_obd->obd_name, err); + CERROR("%s: Can't init metadata layer FID infrastructure, rc = %d\n", + sbi->ll_md_exp->exp_obd->obd_name, err); goto out_md; } @@ -297,10 +295,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, buf = kzalloc(PAGE_CACHE_SIZE, GFP_KERNEL); obd_connect_flags2str(buf, PAGE_CACHE_SIZE, valid ^ CLIENT_CONNECT_MDT_REQD, ","); - LCONSOLE_ERROR_MSG(0x170, "Server %s does not support " - "feature(s) needed for correct operation " - "of this client (%s). Please upgrade " - "server or downgrade client.\n", + LCONSOLE_ERROR_MSG(0x170, "Server %s does not support feature(s) needed for correct operation of this client (%s). Please upgrade server or downgrade client.\n", sbi->ll_md_exp->exp_obd->obd_name, buf); OBD_FREE(buf, PAGE_CACHE_SIZE); err = -EPROTO; @@ -326,8 +321,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if ((sbi->ll_flags & LL_SBI_USER_XATTR) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { - LCONSOLE_INFO("Disabling user_xattr feature because " - "it is not supported on the server\n"); + LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } @@ -352,8 +346,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, } else { if (sbi->ll_flags & LL_SBI_RMT_CLIENT) { sbi->ll_flags &= ~LL_SBI_RMT_CLIENT; - LCONSOLE_INFO("client claims to be remote, but server " - "rejected, forced to be local.\n"); + LCONSOLE_INFO("client claims to be remote, but server rejected, forced to be local.\n"); } } @@ -430,8 +423,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if (sbi->ll_flags & LL_SBI_RMT_CLIENT) data->ocd_connect_flags |= OBD_CONNECT_RMT_CLIENT_FORCE; - CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d " - "ocd_grant: %d\n", data->ocd_connect_flags, + CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d ocd_grant: %d\n", + data->ocd_connect_flags, data->ocd_version, data->ocd_grant); obd->obd_upcall.onu_owner = &sbi->ll_lco; @@ -442,10 +435,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, data, NULL); if (err == -EBUSY) { - LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing " - "recovery, of which this client is not a " - "part. Please wait for recovery to " - "complete, abort, or time out.\n", dt); + LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing recovery, of which this client is not a part. Please wait for recovery to complete, abort, or time out.\n", + dt); goto out_md; } else if (err) { CERROR("%s: Cannot connect to %s: rc = %d\n", @@ -458,8 +449,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, err = obd_fid_init(sbi->ll_dt_exp->exp_obd, sbi->ll_dt_exp, LUSTRE_SEQ_METADATA); if (err) { - CERROR("%s: Can't init data layer FID infrastructure, " - "rc = %d\n", sbi->ll_dt_exp->exp_obd->obd_name, err); + CERROR("%s: Can't init data layer FID infrastructure, rc = %d\n", + sbi->ll_dt_exp->exp_obd->obd_name, err); goto out_dt; } @@ -699,8 +690,8 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) list_for_each(tmp, &dentry->d_subdirs) subdirs++; - CERROR("dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u," - " flags=0x%x, fsdata=%p, %d subdirs\n", dentry, + CERROR("dentry %p dump: name=%.*s parent=%.*s (%p), inode=%p, count=%u, flags=0x%x, fsdata=%p, %d subdirs\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_parent->d_name.len, dentry->d_parent->d_name.name, dentry->d_parent, dentry->d_inode, d_count(dentry), @@ -1023,9 +1014,8 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) /* Profile set with LCFG_MOUNTOPT so we can find our mdc and osc obds */ lprof = class_get_profile(profilenm); if (lprof == NULL) { - LCONSOLE_ERROR_MSG(0x156, "The client profile '%s' could not be" - " read from the MGS. Does that filesystem " - "exist?\n", profilenm); + LCONSOLE_ERROR_MSG(0x156, "The client profile '%s' could not be read from the MGS. Does that filesystem exist?\n", + profilenm); err = -EINVAL; goto out_free; } @@ -1141,8 +1131,7 @@ struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock) } else { inode = lock->l_resource->lr_lvb_inode; LDLM_DEBUG_LIMIT(inode->i_state & I_FREEING ? D_INFO : - D_WARNING, lock, "lr_lvb_inode %p is " - "bogus: magic %08x", + D_WARNING, lock, "lr_lvb_inode %p is bogus: magic %08x", lock->l_resource->lr_lvb_inode, lli->lli_inode_magic); inode = NULL; @@ -1763,9 +1752,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (lli->lli_flags & (LLIF_DONE_WRITING | LLIF_EPOCH_PENDING | LLIF_SOM_DIRTY)) { - CERROR("ino %lu flags %u still has " - "size authority! do not trust " - "the size got from MDS\n", + CERROR("ino %lu flags %u still has size authority! do not trust the size got from MDS\n", inode->i_ino, lli->lli_flags); } else { /* Use old size assignment to avoid @@ -1867,8 +1854,7 @@ void ll_delete_inode(struct inode *inode) spin_lock_irq(&inode->i_data.tree_lock); spin_unlock_irq(&inode->i_data.tree_lock); LASSERTF(inode->i_data.nrpages == 0, - "inode=%lu/%u(%p) nrpages=%lu, see " - "http://jira.whamcloud.com/browse/LU-118\n", + "inode=%lu/%u(%p) nrpages=%lu, see http://jira.whamcloud.com/browse/LU-118\n", inode->i_ino, inode->i_generation, inode, inode->i_data.nrpages); } @@ -2418,8 +2404,8 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret) } CDEBUG(D_WARNING, - "%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted " - "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0), + "%s: dirty page discard: %s/fid: " DFID "/%s may get corrupted (rc %d)\n", + ll_get_fsname(page->mapping->host->i_sb, NULL, 0), s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev, PFID(&obj->cob_header.coh_lu.loh_fid), (path && !IS_ERR(path)) ? path : "", ioret); diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index ae605a6d9dc2..e72b14daccef 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -234,8 +234,7 @@ static int ll_page_mkwrite0(struct vm_area_struct *vma, struct page *vmpage, */ unlock_page(vmpage); - CDEBUG(D_MMAP, "Race on page_mkwrite %p/%lu, page has " - "been written out, retry.\n", + CDEBUG(D_MMAP, "Race on page_mkwrite %p/%lu, page has been written out, retry.\n", vmpage, vmpage->index); *retry = true; @@ -366,8 +365,7 @@ static int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) vmf->page = NULL; if (!printed && ++count > 16) { - CWARN("the page is under heavy contention," - "maybe your app(%s) needs revising :-)\n", + CWARN("the page is under heavy contention, maybe your app(%s) needs revising :-)\n", current->comm); printed = true; } @@ -393,8 +391,7 @@ static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) result = ll_page_mkwrite0(vma, vmf->page, &retry); if (!printed && ++count > 16) { - CWARN("app(%s): the page %lu of file %lu is under heavy" - " contention.\n", + CWARN("app(%s): the page %lu of file %lu is under heavy contention.\n", current->comm, vmf->pgoff, vma->vm_file->f_dentry->d_inode->i_ino); printed = true; diff --git a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c index 586f49a374ec..f4da156f3874 100644 --- a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c +++ b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c @@ -131,8 +131,8 @@ int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops) spin_lock(&rct->rct_lock); e = __rct_search(rct, key); if (unlikely(e != NULL)) { - CWARN("Unexpected stale rmtacl_entry found: " - "[key: %d] [ops: %d]\n", (int)key, ops); + CWARN("Unexpected stale rmtacl_entry found: [key: %d] [ops: %d]\n", + (int)key, ops); rce_free(e); } list_add_tail(&rce->rce_list, &rct->rct_entries[rce_hashfunc(key)]); @@ -263,8 +263,7 @@ int ee_add(struct eacl_table *et, pid_t key, struct lu_fid *fid, int type, spin_lock(&et->et_lock); e = __et_search_del(et, key, fid, type); if (unlikely(e != NULL)) { - CWARN("Unexpected stale eacl_entry found: " - "[key: %d] [fid: "DFID"] [type: %d]\n", + CWARN("Unexpected stale eacl_entry found: [key: %d] [fid: " DFID "] [type: %d]\n", (int)key, PFID(fid), type); ee_free(e); } diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index e0f39fec2787..b6325c01890b 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -778,8 +778,8 @@ static int __init lloop_init(void) if (max_loop < 1 || max_loop > 256) { max_loop = MAX_LOOP_DEFAULT; - CWARN("lloop: invalid max_loop (must be between" - " 1 and 256), using default (%u)\n", max_loop); + CWARN("lloop: invalid max_loop (must be between 1 and 256), using default (%u)\n", + max_loop); } lloop_major = register_blkdev(0, "lloop"); diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 4dc1bfa5c1cf..e6a909e6faf0 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -284,8 +284,7 @@ static ssize_t ll_max_readahead_per_file_mb_seq_write(struct file *file, if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages) { - CERROR("can't set file readahead more than" - "max_read_ahead_mb %lu MB\n", + CERROR("can't set file readahead more than max_read_ahead_mb %lu MB\n", sbi->ll_ra_info.ra_max_pages); return -ERANGE; } @@ -330,9 +329,8 @@ static ssize_t ll_max_read_ahead_whole_mb_seq_write(struct file *file, * algorithm does this anyway so it's pointless to set it larger. */ if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages_per_file) { - CERROR("can't set max_read_ahead_whole_mb more than " - "max_read_ahead_per_file_mb: %lu\n", - sbi->ll_ra_info.ra_max_pages_per_file >> (20 - PAGE_CACHE_SHIFT)); + CERROR("can't set max_read_ahead_whole_mb more than max_read_ahead_per_file_mb: %lu\n", + sbi->ll_ra_info.ra_max_pages_per_file >> (20 - PAGE_CACHE_SHIFT)); return -ERANGE; } @@ -619,8 +617,8 @@ static ssize_t ll_statahead_max_seq_write(struct file *file, if (val >= 0 && val <= LL_SA_RPC_MAX) sbi->ll_sa_max = val; else - CERROR("Bad statahead_max value %d. Valid values are in the " - "range [0, %d]\n", val, LL_SA_RPC_MAX); + CERROR("Bad statahead_max value %d. Valid values are in the range [0, %d]\n", + val, LL_SA_RPC_MAX); return count; } @@ -770,8 +768,8 @@ static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) while (flags != 0) { if (ARRAY_SIZE(str) <= i) { - CERROR("%s: Revise array LL_SBI_FLAGS to match sbi " - "flags please.\n", ll_get_fsname(sb, NULL, 0)); + CERROR("%s: Revise array LL_SBI_FLAGS to match sbi flags please.\n", + ll_get_fsname(sb, NULL, 0)); return -EINVAL; } @@ -1143,8 +1141,8 @@ static void ll_display_extents_info(struct ll_rw_extents_info *io_extents, read_cum += r; write_cum += w; end = 1 << (i + LL_HIST_START - units); - seq_printf(seq, "%4lu%c - %4lu%c%c: %14lu %4lu %4lu | " - "%14lu %4lu %4lu\n", start, *unitp, end, *unitp, + seq_printf(seq, "%4lu%c - %4lu%c%c: %14lu %4lu %4lu | %14lu %4lu %4lu\n", + start, *unitp, end, *unitp, (i == LL_HIST_MAX - 1) ? '+' : ' ', r, pct(r, read_tot), pct(read_cum, read_tot), w, pct(w, write_tot), pct(write_cum, write_tot)); @@ -1170,8 +1168,7 @@ static int ll_rw_extents_stats_pp_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n", @@ -1249,8 +1246,7 @@ static int ll_rw_extents_stats_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n", @@ -1428,8 +1424,7 @@ static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v) if (!sbi->ll_rw_stats_on) { seq_printf(seq, "disabled\n" - "write anything in this file to activate, " - "then 0 or \"[D/d]isabled\" to deactivate\n"); + "write anything in this file to activate, then 0 or \"[D/d]isabled\" to deactivate\n"); return 0; } spin_lock(&sbi->ll_process_lock); diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 2971a26370be..671d0cd2a6a2 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -104,8 +104,8 @@ static int ll_set_inode(struct inode *inode, void *opaque) lli->lli_fid = body->fid1; if (unlikely(!(body->valid & OBD_MD_FLTYPE))) { - CERROR("Can not initialize inode "DFID" without object type: " - "valid = %#llx\n", PFID(&lli->lli_fid), body->valid); + CERROR("Can not initialize inode " DFID " without object type: valid = %#llx\n", + PFID(&lli->lli_fid), body->valid); return -EINVAL; } @@ -619,8 +619,7 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, long long lookup_flags = LOOKUP_OPEN; int rc = 0; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),file %p," - "open_flags %x,mode %x opened %d\n", + CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),file %p,open_flags %x,mode %x opened %d\n", dentry->d_name.len, dentry->d_name.name, dir->i_ino, dir->i_generation, dir, file, open_flags, mode, *opened); @@ -863,8 +862,7 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, { int rc; - CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)," - "flags=%u, excl=%d\n", + CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p),flags=%u, excl=%d\n", dentry->d_name.len, dentry->d_name.name, dir->i_ino, dir->i_generation, dir, mode, want_excl); @@ -1151,8 +1149,8 @@ static int ll_rename_generic(struct inode *src, struct dentry *src_dparent, int err; CDEBUG(D_VFSTRACE, - "VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s," - "tgt_dir=%lu/%u(%p)\n", src_name->len, src_name->name, + "VFS Op:oldname=%.*s,src_dir=%lu/%u(%p),newname=%.*s,tgt_dir=%lu/%u(%p)\n", + src_name->len, src_name->name, src->i_ino, src->i_generation, src, tgt_name->len, tgt_name->name, tgt->i_ino, tgt->i_generation, tgt); diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 613d772357ac..10a0421366d0 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -121,8 +121,8 @@ static struct ll_cl_context *ll_cl_init(struct file *file, /* this is too bad. Someone is trying to write the * page w/o holding inode mutex. This means we can * add dirty pages into cache during truncate */ - CERROR("Proc %s is dirting page w/o inode lock, this" - "will break truncate.\n", current->comm); + CERROR("Proc %s is dirtying page w/o inode lock, this will break truncate\n", + current->comm); dump_stack(); LBUG(); return ERR_PTR(-EIO); @@ -606,8 +606,8 @@ stride_pg_count(pgoff_t st_off, unsigned long st_len, unsigned long st_pgs, else pg_count = start_left + st_pgs * (end - start - 1) + end_left; - CDEBUG(D_READA, "st_off %lu, st_len %lu st_pgs %lu off %lu length %lu" - "pgcount %lu\n", st_off, st_len, st_pgs, off, length, pg_count); + CDEBUG(D_READA, "st_off %lu, st_len %lu st_pgs %lu off %lu length %lu pgcount %lu\n", + st_off, st_len, st_pgs, off, length, pg_count); return pg_count; } @@ -667,10 +667,10 @@ static int ll_read_ahead_pages(const struct lu_env *env, /* FIXME: This assertion only is valid when it is for * forward read-ahead, it will be fixed when backward * read-ahead is implemented */ - LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu" - "rs %lu re %lu ro %lu rl %lu rp %lu\n", page_idx, - ria->ria_start, ria->ria_end, ria->ria_stoff, - ria->ria_length, ria->ria_pages); + LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu rs %lu re %lu ro %lu rl %lu rp %lu\n", + page_idx, + ria->ria_start, ria->ria_end, ria->ria_stoff, + ria->ria_length, ria->ria_pages); offset = page_idx - ria->ria_stoff; offset = offset % (ria->ria_length); if (offset > ria->ria_pages) { @@ -927,8 +927,8 @@ static void ras_stride_increase_window(struct ll_readahead_state *ras, LASSERT(ras->ras_stride_length > 0); LASSERTF(ras->ras_window_start + ras->ras_window_len - >= ras->ras_stride_offset, "window_start %lu, window_len %lu" - " stride_offset %lu\n", ras->ras_window_start, + >= ras->ras_stride_offset, "window_start %lu, window_len %lu stride_offset %lu\n", + ras->ras_window_start, ras->ras_window_len, ras->ras_stride_offset); stride_len = ras->ras_window_start + ras->ras_window_len - diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index 85d451f17c02..c4bd09edb0ce 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -1491,10 +1491,7 @@ ll_sai_unplug(struct ll_statahead_info *sai, struct ll_sa_entry *entry) sai->sai_consecutive_miss++; if (sa_low_hit(sai) && thread_is_running(thread)) { atomic_inc(&sbi->ll_sa_wrong); - CDEBUG(D_READA, "Statahead for dir "DFID" hit " - "ratio too low: hit/miss %llu/%llu" - ", sent/replied %llu/%llu, stopping " - "statahead thread\n", + CDEBUG(D_READA, "Statahead for dir " DFID " hit ratio too low: hit/miss %llu/%llu, sent/replied %llu/%llu, stopping statahead thread\n", PFID(&lli->lli_fid), sai->sai_hit, sai->sai_miss, sai->sai_sent, sai->sai_replied); @@ -1612,8 +1609,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, } else if ((*dentryp)->d_inode != inode) { /* revalidate, but inode is recreated */ CDEBUG(D_READA, - "stale dentry %.*s inode %lu/%u, " - "statahead inode %lu/%u\n", + "stale dentry %.*s inode %lu/%u, statahead inode %lu/%u\n", (*dentryp)->d_name.len, (*dentryp)->d_name.name, (*dentryp)->d_inode->i_ino, @@ -1666,8 +1662,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, if (unlikely(sai->sai_inode != parent->d_inode)) { struct ll_inode_info *nlli = ll_i2info(parent->d_inode); - CWARN("Race condition, someone changed %.*s just now: " - "old parent "DFID", new parent "DFID"\n", + CWARN("Race condition, someone changed %.*s just now: old parent " DFID ", new parent " DFID "\n", (*dentryp)->d_name.len, (*dentryp)->d_name.name, PFID(&lli->lli_fid), PFID(&nlli->lli_fid)); dput(parent); diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c index eccd3a717a4d..686b6a574cc5 100644 --- a/drivers/staging/lustre/lustre/llite/symlink.c +++ b/drivers/staging/lustre/lustre/llite/symlink.c @@ -100,8 +100,8 @@ static int ll_readlink_internal(struct inode *inode, if (*symname == NULL || strnlen(*symname, symlen) != symlen - 1) { /* not full/NULL terminated */ - CERROR("inode %lu: symlink not NULL terminated string" - "of length %d\n", inode->i_ino, symlen - 1); + CERROR("inode %lu: symlink not NULL terminated string of length %d\n", + inode->i_ino, symlen - 1); rc = -EPROTO; goto failed; } diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 168aafb95f25..5675ff0a883f 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -720,9 +720,8 @@ static int vvp_io_fault_start(const struct lu_env *env, last_index = cl_index(obj, size - 1); if (last_index < fio->ft_index) { CDEBUG(D_PAGE, - "llite: mkwrite and truncate race happened: " - "%p: 0x%lx 0x%lx\n", - vmpage->mapping, fio->ft_index, last_index); + "llite: mkwrite and truncate race happened: %p: 0x%lx 0x%lx\n", + vmpage->mapping, fio->ft_index, last_index); /* * We need to return if we are * passed the end of the file. This will propagate diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c index 4626346f6ee1..954ed08c6af2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_page.c +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c @@ -376,8 +376,7 @@ static int vvp_page_print(const struct lu_env *env, struct ccc_page *vp = cl2ccc_page(slice); struct page *vmpage = vp->cpg_page; - (*printer)(env, cookie, LUSTRE_VVP_NAME"-page@%p(%d:%d:%d) " - "vm@%p ", + (*printer)(env, cookie, LUSTRE_VVP_NAME "-page@%p(%d:%d:%d) vm@%p ", vp, vp->cpg_defer_uptodate, vp->cpg_ra_used, vp->cpg_write_queued, vmpage); if (vmpage != NULL) { diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index 3ad979635c60..56ab3e6f83dd 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -201,8 +201,7 @@ int ll_setxattr_common(struct inode *inode, const char *name, #endif if (rc) { if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { - LCONSOLE_INFO("Disabling user_xattr feature because " - "it is not supported on the server\n"); + LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } return rc; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c index e8421f04beda..ee235926f52b 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c @@ -75,8 +75,7 @@ int lmv_fld_lookup(struct lmv_obd *lmv, *mds, PFID(fid)); if (*mds >= lmv->desc.ld_tgt_count) { - CERROR("FLD lookup got invalid mds #%x (max: %x) " - "for fid="DFID"\n", *mds, lmv->desc.ld_tgt_count, + CERROR("FLD lookup got invalid mds #%x (max: %x) for fid=" DFID "\n", *mds, lmv->desc.ld_tgt_count, PFID(fid)); rc = -EINVAL; } diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c index 5106124b7d92..d22d57b4ff38 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c @@ -186,8 +186,8 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, return rc; } - CDEBUG(D_INODE, "OPEN_INTENT with fid1="DFID", fid2="DFID"," - " name='%s' -> mds #%d\n", PFID(&op_data->op_fid1), + CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%d\n", + PFID(&op_data->op_fid1), PFID(&op_data->op_fid2), op_data->op_name, tgt->ltd_idx); rc = md_intent_lock(tgt->ltd_exp, op_data, lmm, lmmsize, it, flags, @@ -226,8 +226,8 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, * this is normal situation, we should not print error here, * only debug info. */ - CDEBUG(D_INODE, "Can't handle remote %s: dir "DFID"("DFID"):" - "%*s: %d\n", LL_IT2STR(it), PFID(&op_data->op_fid2), + CDEBUG(D_INODE, "Can't handle remote %s: dir " DFID "(" DFID "):%*s: %d\n", + LL_IT2STR(it), PFID(&op_data->op_fid2), PFID(&op_data->op_fid1), op_data->op_namelen, op_data->op_name, rc); return rc; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index dc170d87851b..9f3837412cdf 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -325,8 +325,8 @@ static int lmv_init_ea_size(struct obd_export *exp, int easize, rc = md_init_ea_size(lmv->tgts[i]->ltd_exp, easize, def_easize, cookiesize, def_cookiesize); if (rc) { - CERROR("%s: obd_init_ea_size() failed on MDT target %d:" - " rc = %d.\n", obd->obd_name, i, rc); + CERROR("%s: obd_init_ea_size() failed on MDT target %d: rc = %d.\n", + obd->obd_name, i, rc); break; } } @@ -427,8 +427,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt) mdc_obd->obd_type->typ_name, mdc_obd->obd_name); if (mdc_symlink == NULL) { - CERROR("Could not register LMV target " - "/proc/fs/lustre/%s/%s/target_obds/%s.", + CERROR("Could not register LMV target /proc/fs/lustre/%s/%s/target_obds/%s.", obd->obd_type->typ_name, obd->obd_name, mdc_obd->obd_name); lprocfs_remove(&lmv_proc_dir); @@ -474,8 +473,8 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp, if ((index < lmv->tgts_size) && (lmv->tgts[index] != NULL)) { tgt = lmv->tgts[index]; - CERROR("%s: UUID %s already assigned at LOV target index %d:" - " rc = %d\n", obd->obd_name, + CERROR("%s: UUID %s already assigned at LOV target index %d: rc = %d\n", + obd->obd_name, obd_uuid2str(&tgt->ltd_uuid), index, -EEXIST); lmv_init_unlock(lmv); return -EEXIST; @@ -600,8 +599,7 @@ int lmv_check_connect(struct obd_device *obd) --lmv->desc.ld_active_tgt_count; rc2 = obd_disconnect(tgt->ltd_exp); if (rc2) { - CERROR("LMV target %s disconnect on " - "MDC idx %d: error %d\n", + CERROR("LMV target %s disconnect on MDC idx %d: error %d\n", tgt->ltd_uuid.uuid, i, rc2); } } @@ -865,10 +863,9 @@ static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len, if (err) { if (lmv->tgts[i]->ltd_active) { /* permanent error */ - CERROR("error: iocontrol MDC %s on MDT" - "idx %d cmd %x: err = %d\n", - lmv->tgts[i]->ltd_uuid.uuid, - i, cmd, err); + CERROR("error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n", + lmv->tgts[i]->ltd_uuid.uuid, + i, cmd, err); rc = err; lk->lk_flags |= LK_FLG_STOP; /* unregister from previous MDS */ @@ -1147,10 +1144,9 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, return err; } else if (err) { if (lmv->tgts[i]->ltd_active) { - CERROR("error: iocontrol MDC %s on MDT" - "idx %d cmd %x: err = %d\n", - lmv->tgts[i]->ltd_uuid.uuid, - i, cmd, err); + CERROR("error: iocontrol MDC %s on MDTidx %d cmd %x: err = %d\n", + lmv->tgts[i]->ltd_uuid.uuid, + i, cmd, err); if (!rc) rc = err; } @@ -1234,8 +1230,8 @@ static int lmv_placement_policy(struct obd_device *obd, if (lum->lum_type == LMV_STRIPE_TYPE && lum->lum_stripe_offset != -1) { if (lum->lum_stripe_offset >= lmv->desc.ld_tgt_count) { - CERROR("%s: Stripe_offset %d > MDT count %d:" - " rc = %d\n", obd->obd_name, + CERROR("%s: Stripe_offset %d > MDT count %d: rc = %d\n", + obd->obd_name, lum->lum_stripe_offset, lmv->desc.ld_tgt_count, -ERANGE); return -ERANGE; @@ -1298,8 +1294,8 @@ int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, rc = lmv_placement_policy(obd, op_data, &mds); if (rc) { - CERROR("Can't get target for allocating fid, " - "rc %d\n", rc); + CERROR("Can't get target for allocating fid, rc %d\n", + rc); return rc; } diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c index 9e21e5efcdb6..e9ec39c5a6c2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_ea.c +++ b/drivers/staging/lustre/lustre/lov/lov_ea.c @@ -348,9 +348,8 @@ const struct lsm_operations lsm_v3_ops = { void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm) { - CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes %#llx, magic 0x%08X," - " stripe_size %u, stripe_count %u, refc: %d," - " layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm, + CDEBUG(level, "lsm %p, objid " DOSTID ", maxbytes %#llx, magic 0x%08X, stripe_size %u, stripe_count %u, refc: %d, layout_gen %u, pool [" LOV_POOLNAMEF "]\n", + lsm, POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic, lsm->lsm_stripe_size, lsm->lsm_stripe_count, atomic_read(&lsm->lsm_refc), lsm->lsm_layout_gen, diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 71ad166e2cbc..ea503d2a19f8 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -168,8 +168,8 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, if (imp->imp_invalid) { - CDEBUG(D_CONFIG, "not connecting OSC %s; administratively " - "disabled\n", obd_uuid2str(tgt_uuid)); + CDEBUG(D_CONFIG, "not connecting OSC %s; administratively disabled\n", + obd_uuid2str(tgt_uuid)); return 0; } @@ -201,10 +201,9 @@ int lov_connect_obd(struct obd_device *obd, __u32 index, int activate, osc_obd->obd_type->typ_name, osc_obd->obd_name); if (osc_symlink == NULL) { - CERROR("could not register LOV target " - "/proc/fs/lustre/%s/%s/target_obds/%s.", - obd->obd_type->typ_name, obd->obd_name, - osc_obd->obd_name); + CERROR("could not register LOV target /proc/fs/lustre/%s/%s/target_obds/%s.", + obd->obd_type->typ_name, obd->obd_name, + osc_obd->obd_name); lprocfs_remove(&lov_proc_dir); obd->obd_proc_private = NULL; } @@ -726,8 +725,7 @@ void lov_fix_desc_stripe_size(__u64 *val) { if (*val < LOV_MIN_STRIPE_SIZE) { if (*val != 0) - LCONSOLE_INFO("Increasing default stripe size to " - "minimum %u\n", + LCONSOLE_INFO("Increasing default stripe size to minimum %u\n", LOV_DESC_STRIPE_SIZE_DEFAULT); *val = LOV_DESC_STRIPE_SIZE_DEFAULT; } else if (*val & (LOV_MIN_STRIPE_SIZE - 1)) { @@ -899,8 +897,7 @@ static int lov_cleanup(struct obd_device *obd) /* We should never get here - these should have been removed in the disconnect. */ - CERROR("lov tgt %d not cleaned!" - " deathrow=%d, lovrc=%d\n", + CERROR("lov tgt %d not cleaned! deathrow=%d, lovrc=%d\n", i, lov->lov_death_row, atomic_read(&lov->lov_refcount)); lov_del_target(obd, i, NULL, 0); @@ -1175,8 +1172,8 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo, list_for_each(pos, &lovset->set_list) { req = list_entry(pos, struct lov_request, rq_link); - CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx" - "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, + CDEBUG(D_INFO, "objid " DOSTID "[%d] has subobj " DOSTID " at idx%u\n", + POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx); rc = obd_getattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, rqset); @@ -1255,8 +1252,8 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo, if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE) oti->oti_logcookies = set->set_cookies + req->rq_stripe; - CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx" - "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, + CDEBUG(D_INFO, "objid " DOSTID "[%d] has subobj " DOSTID " at idx%u\n", + POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe, POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx); rc = obd_setattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp, @@ -1567,8 +1564,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (lov->lov_tgts[i]->ltd_active) { CDEBUG(err == -ENOTTY ? D_IOCTL : D_WARNING, - "iocontrol OSC %s on OST " - "idx %d cmd %x: err = %d\n", + "iocontrol OSC %s on OST idx %d cmd %x: err = %d\n", lov_uuid2str(lov, i), i, cmd, err); if (!rc) @@ -2265,8 +2261,8 @@ static int lov_quotacheck(struct obd_device *obd, struct obd_export *exp, /* Skip quota check on the administratively disabled OSTs. */ if (!lov->lov_tgts[i]->ltd_activate) { - CWARN("lov idx %d was administratively disabled, " - "skip quotacheck on it.\n", i); + CWARN("lov idx %d was administratively disabled, skip quotacheck on it.\n", + i); continue; } diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index bbef5c96d605..60d2b0f12693 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -734,8 +734,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) rc = PTR_ERR(kthread_run(mgc_requeue_thread, NULL, "ll_cfg_requeue")); if (IS_ERR_VALUE(rc)) { - CERROR("%s: Cannot start requeue thread (%d)," - "no more log updates!\n", + CERROR("%s: Cannot start requeue thread (%d),no more log updates!\n", obd->obd_name, rc); goto err_cleanup; } @@ -1019,8 +1018,7 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, sptlrpc_flavor2name(&cli->cl_flvr_mgc, str, sizeof(str)); - LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but " - "currently %s is in use\n", + LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but currently %s is in use\n", (char *) val, str); rc = -EPERM; } diff --git a/drivers/staging/lustre/lustre/obdclass/capa.c b/drivers/staging/lustre/lustre/obdclass/capa.c index 8d80ea4833c0..d206b1046a18 100644 --- a/drivers/staging/lustre/lustre/obdclass/capa.c +++ b/drivers/staging/lustre/lustre/obdclass/capa.c @@ -272,8 +272,7 @@ int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key) tfm = crypto_alloc_hash(alg->ha_name, 0, 0); if (IS_ERR(tfm)) { - CERROR("crypto_alloc_tfm failed, check whether your kernel" - "has crypto support!\n"); + CERROR("crypto_alloc_tfm failed, check whether your kernel has crypto support!\n"); return PTR_ERR(tfm); } keylen = alg->ha_keylen; @@ -412,9 +411,8 @@ void _debug_capa(struct lustre_capa *c, va_list args; va_start(args, fmt); libcfs_debug_vmsg2(msgdata, fmt, args, - " capability@%p fid "DFID" opc %#llx uid %llu" - " gid %llu flags %u alg %d keyid %u timeout %u " - "expiry %u\n", c, PFID(capa_fid(c)), capa_opc(c), + " capability@%p fid " DFID " opc %#llx uid %llu gid %llu flags %u alg %d keyid %u timeout %u expiry %u\n", + c, PFID(capa_fid(c)), capa_opc(c), capa_uid(c), capa_gid(c), capa_flags(c), capa_alg(c), capa_keyid(c), capa_timeout(c), capa_expiry(c)); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index f2383a497cbe..3141b6043708 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1622,8 +1622,7 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io, atomic_read(&anchor->csi_sync_nr) == 0, &lwi); if (rc < 0) { - CERROR("SYNC IO failed with error: %d, try to cancel " - "%d remaining pages\n", + CERROR("SYNC IO failed with error: %d, try to cancel %d remaining pages\n", rc, atomic_read(&anchor->csi_sync_nr)); (void)cl_io_cancel(env, io, queue); diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index b204531ef710..b081167f9767 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -129,8 +129,7 @@ static void cl_lock_trace0(int level, const struct lu_env *env, const char *func, const int line) { struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj); - CDEBUG(level, "%s: %p@(%d %p %d %d %d %d %d %lx)" - "(%p/%d/%d) at %s():%d\n", + CDEBUG(level, "%s: %p@(%d %p %d %d %d %d %d %lx)(%p/%d/%d) at %s():%d\n", prefix, lock, atomic_read(&lock->cll_ref), lock->cll_guarder, lock->cll_depth, lock->cll_state, lock->cll_error, lock->cll_holds, diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 7265ecbc6f9d..89a3fb2e56b2 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -144,13 +144,11 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, CERROR("%s%salloc of %s (%llu bytes) failed at %s:%d\n", ptr ? "force " :"", type, name, (__u64)size, file, line); - CERROR("%llu total bytes and %llu total pages " - "(%llu bytes) allocated by Lustre, " - "%d total bytes by LNET\n", + CERROR("%llu total bytes and %llu total pages (%llu bytes) allocated by Lustre, %d total bytes by LNET\n", obd_memory_sum(), obd_pages_sum() << PAGE_CACHE_SHIFT, obd_pages_sum(), - atomic_read(&libcfs_kmemory)); + atomic_read(&libcfs_kmemory)); return 1; } return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index ac8db2f98078..736ca410aca3 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -1087,8 +1087,7 @@ void __class_export_del_lock_ref(struct obd_export *exp, struct ldlm_lock *lock) spin_lock(&exp->exp_locks_list_guard); LASSERT(lock->l_exp_refs_nr > 0); if (lock->l_exp_refs_target != exp) { - LCONSOLE_WARN("lock %p, " - "mismatching export pointers: %p, %p\n", + LCONSOLE_WARN("lock %p, mismatching export pointers: %p, %p\n", lock, lock->l_exp_refs_target, exp); } if (-- lock->l_exp_refs_nr == 0) { @@ -1259,8 +1258,7 @@ static void class_disconnect_export_list(struct list_head *list, } class_export_get(exp); - CDEBUG(D_HA, "%s: disconnecting export at %s (%p), " - "last request at "CFS_TIME_T"\n", + CDEBUG(D_HA, "%s: disconnecting export at %s (%p), last request at " CFS_TIME_T "\n", exp->exp_obd->obd_name, obd_export_nid2str(exp), exp, exp->exp_last_request_time); /* release one export reference anyway */ @@ -1284,8 +1282,8 @@ void class_disconnect_exports(struct obd_device *obd) spin_unlock(&obd->obd_dev_lock); if (!list_empty(&work_list)) { - CDEBUG(D_HA, "OBD device %d (%p) has exports, " - "disconnecting them\n", obd->obd_minor, obd); + CDEBUG(D_HA, "OBD device %d (%p) has exports, disconnecting them\n", + obd->obd_minor, obd); class_disconnect_export_list(&work_list, exp_flags_from_obd(obd)); } else @@ -1422,8 +1420,8 @@ int obd_export_evict_by_nid(struct obd_device *obd, const char *nid) LASSERTF(doomed_exp != obd->obd_self_export, "self-export is hashed by NID?\n"); exports_evicted++; - LCONSOLE_WARN("%s: evicting %s (at %s) by administrative " - "request\n", obd->obd_name, + LCONSOLE_WARN("%s: evicting %s (at %s) by administrative request\n", + obd->obd_name, obd_uuid2str(&doomed_exp->exp_client_uuid), obd_export_nid2str(doomed_exp)); class_fail_export(doomed_exp); @@ -1546,9 +1544,7 @@ void obd_exports_barrier(struct obd_device *obd) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(cfs_time_seconds(waited)); if (waited > 5 && IS_PO2(waited)) { - LCONSOLE_WARN("%s is waiting for obd_unlinked_exports " - "more than %d seconds. " - "The obd refcount = %d. Is it stuck?\n", + LCONSOLE_WARN("%s is waiting for obd_unlinked_exports more than %d seconds. The obd refcount = %d. Is it stuck?\n", obd->obd_name, waited, atomic_read(&obd->obd_refcount)); dump_exports(obd, 1); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c index 38a9b319355e..dd46e7358160 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c @@ -202,9 +202,8 @@ static int proc_max_dirty_pages_in_mb(struct ctl_table *table, int write, /* Don't allow them to let dirty pages exceed 90% of system * memory and set a hard minimum of 4MB. */ if (obd_max_dirty_pages > ((totalram_pages / 10) * 9)) { - CERROR("Refusing to set max dirty pages to %u, which " - "is more than 90%% of available RAM; setting " - "to %lu\n", obd_max_dirty_pages, + CERROR("Refusing to set max dirty pages to %u, which is more than 90%% of available RAM; setting to %lu\n", + obd_max_dirty_pages, ((totalram_pages / 10) * 9)); obd_max_dirty_pages = ((totalram_pages / 10) * 9); } else if (obd_max_dirty_pages < 4 << (20 - PAGE_CACHE_SHIFT)) { diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c index 3ab05292152c..114be4a78ccf 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog.c +++ b/drivers/staging/lustre/lustre/obdclass/llog.c @@ -346,8 +346,8 @@ static int llog_process_thread(void *arg) } if (rec->lrh_len == 0 || rec->lrh_len > LLOG_CHUNK_SIZE) { - CWARN("invalid length %d in llog record for " - "index %d/%d\n", rec->lrh_len, + CWARN("invalid length %d in llog record for index %d/%d\n", + rec->lrh_len, rec->lrh_index, index); rc = -EINVAL; goto out; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c index 6e139cf372c4..4b850fc5f5d9 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c @@ -228,8 +228,7 @@ int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle) (llh->llh_count == 1)) { rc = llog_destroy(env, loghandle); if (rc) - CERROR("%s: failure destroying log during " - "cleanup: rc = %d\n", + CERROR("%s: failure destroying log during cleanup: rc = %d\n", loghandle->lgh_ctxt->loc_obd->obd_name, rc); @@ -746,8 +745,7 @@ int llog_cat_cleanup(const struct lu_env *env, struct llog_handle *cathandle, llog_cat_set_first_idx(cathandle, index); rc = llog_cancel_rec(env, cathandle, index); if (rc == 0) - CDEBUG(D_HA, "cancel plain log at index" - " %u of catalog "DOSTID"\n", + CDEBUG(D_HA, "cancel plain log at index %u of catalog " DOSTID "\n", index, POSTID(&cathandle->lgh_id.lgl_oi)); return rc; } @@ -810,8 +808,8 @@ int llog_cat_init_and_process(const struct lu_env *env, rc = llog_process_or_fork(env, llh, cat_cancel_cb, NULL, NULL, false); if (rc) - CERROR("%s: llog_process() with cat_cancel_cb failed: rc = " - "%d\n", llh->lgh_ctxt->loc_obd->obd_name, rc); + CERROR("%s: llog_process() with cat_cancel_cb failed: rc = %d\n", + llh->lgh_ctxt->loc_obd->obd_name, rc); return 0; } EXPORT_SYMBOL(llog_cat_init_and_process); diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c index bfac8387021e..d3ec90e85eb9 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c @@ -400,8 +400,7 @@ void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size) } marker->cm_createtime = createtime; marker->cm_canceltime = canceltime; - CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) " - "for target %s, converting\n", + CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) for target %s, converting\n", marker->cm_tgtname); } else if (swab) { __swab64s(&marker->cm_createtime); diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 686bc182a9bb..3b7dfc367722 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -1400,8 +1400,8 @@ int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats) * LPROCFS_OBD_OP_INIT(.., .., opname) * is missing from the list above. */ LASSERTF(stats->ls_cnt_header[i].lc_name != NULL, - "Missing obd_stat initializer obd_op " - "operation at offset %d.\n", i - num_private_stats); + "Missing obd_stat initializer obd_op operation at offset %d.\n", + i - num_private_stats); } rc = lprocfs_register_stats(obd->obd_proc_entry, "stats", stats); if (rc < 0) { @@ -1486,8 +1486,7 @@ int lprocfs_alloc_md_stats(struct obd_device *obd, for (i = num_private_stats; i < num_stats; i++) { if (stats->ls_cnt_header[i].lc_name == NULL) { - CERROR("Missing md_stat initializer md_op " - "operation at offset %d. Aborting.\n", + CERROR("Missing md_stat initializer md_op operation at offset %d. Aborting.\n", i - num_private_stats); LBUG(); } @@ -1607,8 +1606,7 @@ LPROC_SEQ_FOPS_RO(lproc_exp_hash); int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data) { return seq_printf(m, "%s\n", - "Write into this file to clear all nid stats and " - "stale nid entries"); + "Write into this file to clear all nid stats and stale nid entries"); } EXPORT_SYMBOL(lprocfs_nid_stats_clear_read); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 2fc037cfb62f..83bf168c2939 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -866,8 +866,7 @@ static int lu_htable_order(void) /* clear off unreasonable cache setting. */ if (lu_cache_percent == 0 || lu_cache_percent > LU_CACHE_PERCENT_MAX) { - CWARN("obdclass: invalid lu_cache_percent: %u, it must be in" - " the range of (0, %u]. Will use default value: %u.\n", + CWARN("obdclass: invalid lu_cache_percent: %u, it must be in the range of (0, %u]. Will use default value: %u.\n", lu_cache_percent, LU_CACHE_PERCENT_MAX, LU_CACHE_PERCENT_DEFAULT); diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 47213a970e7d..6ce9adc2f11c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -1443,8 +1443,7 @@ int class_config_llog_handler(const struct lu_env *env, if (!(clli->cfg_flags & CFG_F_COMPAT146) && !(clli->cfg_flags & CFG_F_MARKER) && (lcfg->lcfg_command != LCFG_MARKER)) { - CWARN("Config not inside markers, ignoring! " - "(inst: %p, uuid: %s, flags: %#x)\n", + CWARN("Config not inside markers, ignoring! (inst: %p, uuid: %s, flags: %#x)\n", clli->cfg_instance, clli->cfg_uuid.uuid, clli->cfg_flags); clli->cfg_flags |= CFG_F_SKIP; @@ -1467,14 +1466,12 @@ int class_config_llog_handler(const struct lu_env *env, if ((lcfg->lcfg_command == LCFG_ATTACH && typename && strcmp(typename, "mds") == 0)) { - CWARN("For 1.8 interoperability, rename obd " - "type from mds to mdt\n"); + CWARN("For 1.8 interoperability, rename obd type from mds to mdt\n"); typename[2] = 't'; } if ((lcfg->lcfg_command == LCFG_SETUP && index && strcmp(index, "type") == 0)) { - CDEBUG(D_INFO, "For 1.8 interoperability, " - "set this index to '0'\n"); + CDEBUG(D_INFO, "For 1.8 interoperability, set this index to '0'\n"); index[0] = '0'; index[1] = 0; } diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 1260c8713bc6..4f39cdee1b5c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -100,19 +100,12 @@ int lustre_process_log(struct super_block *sb, char *logname, OBD_FREE_PTR(bufs); if (rc == -EINVAL) - LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s'" - "failed from the MGS (%d). Make sure this " - "client and the MGS are running compatible " - "versions of Lustre.\n", + LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s' failed from the MGS (%d). Make sure this client and the MGS are running compatible versions of Lustre.\n", mgc->obd_name, logname, rc); if (rc) - LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' " - "failed (%d). This may be the result of " - "communication errors between this node and " - "the MGS, a bad configuration, or other " - "errors. See the syslog for more " - "information.\n", mgc->obd_name, logname, + LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' failed (%d). This may be the result of communication errors between this node and the MGS, a bad configuration, or other errors. See the syslog for more information.\n", + mgc->obd_name, logname, rc); /* class_obd_list(); */ @@ -297,11 +290,8 @@ int lustre_start_mgc(struct super_block *sb) if (has_ir ^ !(*flags & LMD_FLG_NOIR)) { /* LMD_FLG_NOIR is for test purpose only */ LCONSOLE_WARN( - "Trying to mount a client with IR setting " - "not compatible with current mgc. " - "Force to use current mgc setting that is " - "IR %s.\n", - has_ir ? "enabled" : "disabled"); + "Trying to mount a client with IR setting not compatible with current mgc. Force to use current mgc setting that is IR %s.\n", + has_ir ? "enabled" : "disabled"); if (has_ir) *flags &= ~LMD_FLG_NOIR; else @@ -998,16 +988,14 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) LASSERT(lmd); if (!options) { - LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that " - "/sbin/mount.lustre is installed.\n"); + LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that /sbin/mount.lustre is installed.\n"); return -EINVAL; } /* Options should be a string - try to detect old lmd data */ if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) { - LCONSOLE_ERROR_MSG(0x163, "You're using an old version of " - "/sbin/mount.lustre. Please install " - "version %s\n", LUSTRE_VERSION_STRING); + LCONSOLE_ERROR_MSG(0x163, "You're using an old version of /sbin/mount.lustre. Please install version %s\n", + LUSTRE_VERSION_STRING); return -EINVAL; } lmd->lmd_magic = LMD_MAGIC; @@ -1139,8 +1127,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) } if (!devname) { - LCONSOLE_ERROR_MSG(0x164, "Can't find the device name " - "(need mount option 'device=...')\n"); + LCONSOLE_ERROR_MSG(0x164, "Can't find the device name (need mount option 'device=...')\n"); goto invalid; } @@ -1232,9 +1219,7 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) if (client_fill_super == NULL) request_module("lustre"); if (client_fill_super == NULL) { - LCONSOLE_ERROR_MSG(0x165, "Nothing registered for " - "client mount! Is the 'lustre' " - "module loaded?\n"); + LCONSOLE_ERROR_MSG(0x165, "Nothing registered for client mount! Is the 'lustre' module loaded?\n"); lustre_put_lsi(sb); rc = -ENODEV; } else { @@ -1249,8 +1234,7 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) /* c_f_s will call lustre_common_put_super on failure */ } } else { - CERROR("This is client-side-only module, " - "cannot handle server mount.\n"); + CERROR("This is client-side-only module, cannot handle server mount.\n"); rc = -EINVAL; } diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index a6ad87557512..5f6d9441bc44 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -871,8 +871,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env, spin_lock(&ec->ec_lock); while (!list_empty(&ec->ec_objects)) { spin_unlock(&ec->ec_lock); - CERROR("echo_client still has objects at cleanup time, " - "wait for 1 second\n"); + CERROR("echo_client still has objects at cleanup time, wait for 1 second\n"); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(cfs_time_seconds(1)); lu_site_purge(env, &ed->ed_site->cs_lu, -1); diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index f8c8b666d4f3..370e6d4896c6 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1611,8 +1611,8 @@ void osc_wake_cache_waiters(struct client_obd *cli) if ((cli->cl_dirty + PAGE_CACHE_SIZE > cli->cl_dirty_max) || (atomic_read(&obd_dirty_pages) + 1 > obd_max_dirty_pages)) { - CDEBUG(D_CACHE, "no dirty room: dirty: %ld " - "osc max %ld, sys max %d\n", cli->cl_dirty, + CDEBUG(D_CACHE, "no dirty room: dirty: %ld osc max %ld, sys max %d\n", + cli->cl_dirty, cli->cl_dirty_max, obd_max_dirty_pages); goto wakeup; } diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index 8138856fda8c..a7f08bc48166 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -1067,14 +1067,12 @@ static int osc_lock_enqueue_wait(const struct lu_env *env, * conflicts, we do not wait but return 0 so the * request is send to the server */ - CDEBUG(D_DLMTRACE, "group lock %p is conflicted " - "with %p, no wait, send to server\n", + CDEBUG(D_DLMTRACE, "group lock %p is conflicted with %p, no wait, send to server\n", lock, conflict); cl_lock_put(env, conflict); rc = 0; } else { - CDEBUG(D_DLMTRACE, "lock %p is conflicted with %p, " - "will wait\n", + CDEBUG(D_DLMTRACE, "lock %p is conflicted with %p, will wait\n", lock, conflict); LASSERT(lock->cll_conflict == NULL); lu_ref_add(&conflict->cll_reference, "cancel-wait", diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index 69000584619d..92c202f70395 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -140,8 +140,7 @@ static int osc_object_print(const struct lu_env *env, void *cookie, struct lov_oinfo *oinfo = osc->oo_oinfo; struct osc_async_rc *ar = &oinfo->loi_ar; - (*p)(env, cookie, "id: "DOSTID" " - "idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", + (*p)(env, cookie, "id: " DOSTID " idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", POSTID(&oinfo->loi_oi), oinfo->loi_ost_idx, oinfo->loi_ost_gen, oinfo->loi_kms_valid, oinfo->loi_kms, ar->ar_rc, ar->ar_force_sync, ar->ar_min_xid); diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index fcd079b1af01..76ba58b09c5d 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -369,12 +369,7 @@ static int osc_page_print(const struct lu_env *env, struct osc_object *obj = cl2osc(slice->cpl_obj); struct client_obd *cli = &osc_export(obj)->exp_obd->u.cli; - return (*printer)(env, cookie, LUSTRE_OSC_NAME"-page@%p: " - "1< %#x %d %u %s %s > " - "2< %llu %u %u %#x %#x | %p %p %p > " - "3< %s %p %d %lu %d > " - "4< %d %d %d %lu %s | %s %s %s %s > " - "5< %s %s %s %s | %d %s | %d %s %s>\n", + return (*printer)(env, cookie, LUSTRE_OSC_NAME "-page@%p: 1< %#x %d %u %s %s > 2< %llu %u %u %#x %#x | %p %p %p > 3< %s %p %d %lu %d > 4< %d %d %d %lu %s | %s %s %s %s > 5< %s %s %s %s | %d %s | %d %s %s>\n", opg, /* 1 */ oap->oap_magic, oap->oap_cmd, @@ -550,8 +545,8 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, LINVRNT(osc_page_protected(env, opg, crt == CRT_WRITE ? CLM_WRITE : CLM_READ, 1)); - LASSERTF(oap->oap_magic == OAP_MAGIC, "Bad oap magic: oap %p, " - "magic 0x%x\n", oap, oap->oap_magic); + LASSERTF(oap->oap_magic == OAP_MAGIC, "Bad oap magic: oap %p, magic 0x%x\n", + oap, oap->oap_magic); LASSERT(oap->oap_async_flags & ASYNC_READY); LASSERT(oap->oap_async_flags & ASYNC_COUNT_STABLE); diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index ca16c081e9df..b9450b95f1c5 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1078,9 +1078,9 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd) cli->cl_chunkbits = max_t(int, PAGE_CACHE_SHIFT, ocd->ocd_blocksize); client_obd_list_unlock(&cli->cl_loi_list_lock); - CDEBUG(D_CACHE, "%s, setting cl_avail_grant: %ld cl_lost_grant: %ld." - "chunk bits: %d.\n", cli->cl_import->imp_obd->obd_name, - cli->cl_avail_grant, cli->cl_lost_grant, cli->cl_chunkbits); + CDEBUG(D_CACHE, "%s, setting cl_avail_grant: %ld cl_lost_grant: %ld chunk bits: %d\n", + cli->cl_import->imp_obd->obd_name, + cli->cl_avail_grant, cli->cl_lost_grant, cli->cl_chunkbits); if (ocd->ocd_connect_flags & OBD_CONNECT_GRANT_SHRINK && list_empty(&cli->cl_grant_shrink_list)) @@ -1171,8 +1171,7 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) /* warn if we try to combine flags that we don't know to be * safe to combine */ if (unlikely((p1->flag & mask) != (p2->flag & mask))) { - CWARN("Saw flags 0x%x and 0x%x in the same brw, please " - "report this at http://bugs.whamcloud.com/\n", + CWARN("Saw flags 0x%x and 0x%x in the same brw, please report this at http://bugs.whamcloud.com/\n", p1->flag, p2->flag); } return 0; @@ -1343,8 +1342,7 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, "i: %d/%d pg: %p off: %llu, count: %u\n", i, page_count, pg, pg->off, pg->count); LASSERTF(i == 0 || pg->off > pg_prev->off, - "i %d p_c %u pg %p [pri %lu ind %lu] off %llu" - " prev_pg %p [pri %lu ind %lu] off %llu\n", + "i %d p_c %u pg %p [pri %lu ind %lu] off %llu prev_pg %p [pri %lu ind %lu] off %llu\n", i, page_count, pg->pg, page_private(pg->pg), pg->pg->index, pg->off, pg_prev->pg, page_private(pg_prev->pg), @@ -1467,16 +1465,16 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, cksum_type); if (cksum_type != client_cksum_type) - msg = "the server did not use the checksum type specified in " - "the original request - likely a protocol problem"; + msg = "the server did not use the checksum type specified in the original request - likely a protocol problem" + ; else if (new_cksum == server_cksum) - msg = "changed on the client after we checksummed it - " - "likely false positive due to mmap IO (bug 11742)"; + msg = "changed on the client after we checksummed it - likely false positive due to mmap IO (bug 11742)" + ; else if (new_cksum == client_cksum) msg = "changed in transit before arrival at OST"; else - msg = "changed in transit AND doesn't match the original - " - "likely false positive due to mmap IO (bug 11742)"; + msg = "changed in transit AND doesn't match the original - likely false positive due to mmap IO (bug 11742)" + ; LCONSOLE_ERROR_MSG(0x132, "BAD WRITE CHECKSUM: %s: from %s inode "DFID " object "DOSTID" extent [%llu-%llu]\n", @@ -1486,8 +1484,8 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, POSTID(&oa->o_oi), pga[0]->off, pga[page_count-1]->off + pga[page_count-1]->count - 1); - CERROR("original client csum %x (type %x), server csum %x (type %x), " - "client csum now %x\n", client_cksum, client_cksum_type, + CERROR("original client csum %x (type %x), server csum %x (type %x), client csum now %x\n", + client_cksum, client_cksum_type, server_cksum, cksum_type, new_cksum); return 1; } @@ -1601,23 +1599,21 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) } if (server_cksum != client_cksum) { - LCONSOLE_ERROR_MSG(0x133, "%s: BAD READ CHECKSUM: from " - "%s%s%s inode "DFID" object "DOSTID - " extent [%llu-%llu]\n", + LCONSOLE_ERROR_MSG(0x133, "%s: BAD READ CHECKSUM: from %s%s%s inode " DFID " object " DOSTID " extent [%llu-%llu]\n", req->rq_import->imp_obd->obd_name, libcfs_nid2str(peer->nid), via, router, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_seq : (__u64)0, + body->oa.o_parent_seq : (__u64)0, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_oid : 0, + body->oa.o_parent_oid : 0, body->oa.o_valid & OBD_MD_FLFID ? - body->oa.o_parent_ver : 0, + body->oa.o_parent_ver : 0, POSTID(&body->oa.o_oi), aa->aa_ppga[0]->off, aa->aa_ppga[aa->aa_page_count-1]->off + aa->aa_ppga[aa->aa_page_count-1]->count - - 1); + 1); CERROR("client %x, server %x, cksum_type %x\n", client_cksum, server_cksum, cksum_type); cksum_counter = 0; @@ -1771,8 +1767,7 @@ static int brw_interpret(const struct lu_env *env, if (osc_recoverable_error(rc)) { if (req->rq_import_generation != req->rq_import->imp_generation) { - CDEBUG(D_HA, "%s: resend cross eviction for object: " - ""DOSTID", rc = %d.\n", + CDEBUG(D_HA, "%s: resend cross eviction for object: " DOSTID ", rc = %d.\n", req->rq_import->imp_obd->obd_name, POSTID(&aa->aa_oa->o_oi), rc); } else if (rc == -EINPROGRESS || @@ -3013,8 +3008,8 @@ static int osc_reconnect(const struct lu_env *env, cli->cl_lost_grant = 0; client_obd_list_unlock(&cli->cl_loi_list_lock); - CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d" - " ocd_grant: %d, lost: %ld.\n", data->ocd_connect_flags, + CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d ocd_grant: %d, lost: %ld.\n", + data->ocd_connect_flags, data->ocd_version, data->ocd_grant, lost_grant); } diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 6c8815f4b99b..dc9e406f3212 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -265,8 +265,7 @@ static void ptlrpc_at_adj_service(struct ptlrpc_request *req, so just keep minimal history here */ oldse = at_measured(&at->iat_service_estimate[idx], serv_est); if (oldse != 0) - CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d " - "has changed from %d to %d\n", + CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d has changed from %d to %d\n", req->rq_import->imp_obd->obd_name, req->rq_request_portal, oldse, at_get(&at->iat_service_estimate[idx])); } @@ -297,8 +296,7 @@ static void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req, oldnl = at_measured(&at->iat_net_latency, nl); if (oldnl != 0) - CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) " - "has changed from %d to %d\n", + CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) has changed from %d to %d\n", req->rq_import->imp_obd->obd_name, obd_uuid2str( &req->rq_import->imp_connection->c_remote_uuid), @@ -371,8 +369,8 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) ptlrpc_at_get_net_latency(req); DEBUG_REQ(D_ADAPTTO, req, - "Early reply #%d, new deadline in "CFS_DURATION_T"s " - "("CFS_DURATION_T"s)", req->rq_early_count, + "Early reply #%d, new deadline in " CFS_DURATION_T "s (" CFS_DURATION_T "s)", + req->rq_early_count, cfs_time_sub(req->rq_deadline, get_seconds()), cfs_time_sub(req->rq_deadline, olddl)); @@ -445,8 +443,8 @@ void ptlrpc_add_rqs_to_pool(struct ptlrpc_request_pool *pool, int num_rq) LASSERTF(list_empty(&pool->prp_req_list) || size == pool->prp_rq_size, - "Trying to change pool size with nonempty pool " - "from %d to %d bytes\n", pool->prp_rq_size, size); + "Trying to change pool size with nonempty pool from %d to %d bytes\n", + pool->prp_rq_size, size); spin_lock(&pool->prp_lock); pool->prp_rq_size = size; @@ -1146,11 +1144,10 @@ static int ptlrpc_check_status(struct ptlrpc_request *req) struct obd_import *imp = req->rq_import; __u32 opc = lustre_msg_get_opc(req->rq_reqmsg); if (ptlrpc_console_allow(req)) - LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s," - " operation %s failed with %d.\n", + LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s, operation %s failed with %d.\n", imp->imp_obd->obd_name, libcfs_nid2str( - imp->imp_connection->c_peer.nid), + imp->imp_connection->c_peer.nid), ll_opcode2str(opc), err); return err < 0 ? err : -EINVAL; } @@ -1206,8 +1203,7 @@ static int after_reply(struct ptlrpc_request *req) if (req->rq_reply_truncate) { if (ptlrpc_no_resend(req)) { - DEBUG_REQ(D_ERROR, req, "reply buffer overflow," - " expected: %d, actual size: %d", + DEBUG_REQ(D_ERROR, req, "reply buffer overflow, expected: %d, actual size: %d", req->rq_nob_received, req->rq_repbuf_len); return -EOVERFLOW; } @@ -1259,8 +1255,7 @@ static int after_reply(struct ptlrpc_request *req) /* new xid is already allocated for bulk in * ptlrpc_check_set() */ req->rq_xid = ptlrpc_next_xid(); - DEBUG_REQ(D_RPCTRACE, req, "Allocating new xid for " - "resend on EINPROGRESS"); + DEBUG_REQ(D_RPCTRACE, req, "Allocating new xid for resend on EINPROGRESS"); } /* Readjust the timeout for current conditions */ @@ -1412,8 +1407,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) req->rq_waiting = 1; spin_unlock(&req->rq_lock); - DEBUG_REQ(D_HA, req, "req from PID %d waiting for recovery: " - "(%s != %s)", lustre_msg_get_status(req->rq_reqmsg), + DEBUG_REQ(D_HA, req, "req from PID %d waiting for recovery: (%s != %s)", + lustre_msg_get_status(req->rq_reqmsg), ptlrpc_import_state_name(req->rq_send_state), ptlrpc_import_state_name(imp->imp_state)); LASSERT(list_empty(&req->rq_list)); @@ -1450,8 +1445,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) } } - CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc" - " %s:%s:%d:%llu:%s:%d\n", current_comm(), + CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + current_comm(), imp->imp_obd->obd_uuid.uuid, lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, libcfs_nid2str(imp->imp_connection->c_peer.nid), @@ -1828,12 +1823,11 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) ptlrpc_rqphase_move(req, RQ_PHASE_COMPLETE); CDEBUG(req->rq_reqmsg != NULL ? D_RPCTRACE : 0, - "Completed RPC pname:cluuid:pid:xid:nid:" - "opc %s:%s:%d:%llu:%s:%d\n", - current_comm(), imp->imp_obd->obd_uuid.uuid, - lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, - libcfs_nid2str(imp->imp_connection->c_peer.nid), - lustre_msg_get_opc(req->rq_reqmsg)); + "Completed RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + current_comm(), imp->imp_obd->obd_uuid.uuid, + lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, + libcfs_nid2str(imp->imp_connection->c_peer.nid), + lustre_msg_get_opc(req->rq_reqmsg)); spin_lock(&imp->imp_lock); /* Request already may be not on sending or delaying list. This diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 32dfffa76a5e..7f8644e01112 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -128,8 +128,8 @@ void reply_in_callback(lnet_event_t *ev) ((lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT))) { /* Early reply */ DEBUG_REQ(D_ADAPTTO, req, - "Early reply received: mlen=%u offset=%d replen=%d " - "replied=%d unlinked=%d", ev->mlength, ev->offset, + "Early reply received: mlen=%u offset=%d replen=%d replied=%d unlinked=%d", + ev->mlength, ev->offset, req->rq_replen, req->rq_replied, ev->unlinked); req->rq_early_count++; /* number received, client side */ @@ -313,8 +313,7 @@ void request_in_callback(lnet_event_t *ev) } req = ptlrpc_request_cache_alloc(GFP_ATOMIC); if (req == NULL) { - CERROR("Can't allocate incoming request descriptor: " - "Dropping %s RPC from %s\n", + CERROR("Can't allocate incoming request descriptor: Dropping %s RPC from %s\n", service->srv_name, libcfs_id2str(ev->initiator)); return; diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index 2e7e7171ca63..4ceb90db02a3 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -157,18 +157,14 @@ int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt) &target_start, &target_len); if (imp->imp_replayable) { - LCONSOLE_WARN("%s: Connection to %.*s (at %s) was " - "lost; in progress operations using this " - "service will wait for recovery to complete\n", - imp->imp_obd->obd_name, target_len, target_start, - libcfs_nid2str(imp->imp_connection->c_peer.nid)); + LCONSOLE_WARN("%s: Connection to %.*s (at %s) was lost; in progress operations using this service will wait for recovery to complete\n", + imp->imp_obd->obd_name, target_len, target_start, + libcfs_nid2str(imp->imp_connection->c_peer.nid)); } else { - LCONSOLE_ERROR_MSG(0x166, "%s: Connection to " - "%.*s (at %s) was lost; in progress " - "operations using this service will fail\n", - imp->imp_obd->obd_name, - target_len, target_start, - libcfs_nid2str(imp->imp_connection->c_peer.nid)); + LCONSOLE_ERROR_MSG(0x166, "%s: Connection to %.*s (at %s) was lost; in progress operations using this service will fail\n", + imp->imp_obd->obd_name, + target_len, target_start, + libcfs_nid2str(imp->imp_connection->c_peer.nid)); } IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_DISCON); spin_unlock(&imp->imp_lock); @@ -328,8 +324,8 @@ void ptlrpc_invalidate_import(struct obd_import *imp) * sluggish nets). Let's check this. If there * is no inflight and unregistering != 0, this * is bug. */ - LASSERTF(count == 0, "Some RPCs are still " - "unregistering: %d\n", count); + LASSERTF(count == 0, "Some RPCs are still unregistering: %d\n", + count); /* Let's save one loop as soon as inflight have * dropped to zero. No new inflights possible at @@ -353,12 +349,11 @@ void ptlrpc_invalidate_import(struct obd_import *imp) "still on delayed list"); } - CERROR("%s: RPCs in \"%s\" phase found (%d). " - "Network is sluggish? Waiting them " - "to error out.\n", cli_tgt, + CERROR("%s: RPCs in \"%s\" phase found (%d). Network is sluggish? Waiting them to error out.\n", + cli_tgt, ptlrpc_phase2str(RQ_PHASE_UNREGISTERING), atomic_read(&imp-> - imp_unregistering)); + imp_unregistering)); } spin_unlock(&imp->imp_lock); } @@ -413,8 +408,7 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt) if (ptlrpc_set_import_discon(imp, conn_cnt)) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, " - "auto-deactivating\n", + CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); @@ -541,8 +535,8 @@ static int import_select_connection(struct obd_import *imp) at_reset(at, CONNECTION_SWITCH_MAX); } LASSERT(imp_conn->oic_last_attempt); - CDEBUG(D_HA, "%s: tried all connections, increasing latency " - "to %ds\n", imp->imp_obd->obd_name, at_get(at)); + CDEBUG(D_HA, "%s: tried all connections, increasing latency to %ds\n", + imp->imp_obd->obd_name, at_get(at)); } imp_conn->oic_last_attempt = cfs_time_current_64(); @@ -564,8 +558,7 @@ static int import_select_connection(struct obd_import *imp) deuuidify(obd2cli_tgt(imp->imp_obd), NULL, &target_start, &target_len); - CDEBUG(D_HA, "%s: Connection changing to" - " %.*s (at %s)\n", + CDEBUG(D_HA, "%s: Connection changing to %.*s (at %s)\n", imp->imp_obd->obd_name, target_len, target_start, libcfs_nid2str(imp_conn->oic_conn->c_peer.nid)); @@ -935,14 +928,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, lustre_msg_get_handle( request->rq_repmsg)->cookie); } else { - LCONSOLE_WARN("Evicted from %s (at %s) " - "after server handle changed from %#llx to %#llx\n", + LCONSOLE_WARN("Evicted from %s (at %s) after server handle changed from %#llx to %#llx\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection-> \ c_remote_uuid.uuid, imp->imp_remote_handle.cookie, lustre_msg_get_handle( - request->rq_repmsg)->cookie); + request->rq_repmsg)->cookie); } @@ -962,8 +954,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, } if (imp->imp_invalid) { - CDEBUG(D_HA, "%s: reconnected but import is invalid; " - "marking evicted\n", imp->imp_obd->obd_name); + CDEBUG(D_HA, "%s: reconnected but import is invalid; marking evicted\n", + imp->imp_obd->obd_name); IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED); } else if (MSG_CONNECT_RECOVERING & msg_flags) { CDEBUG(D_HA, "%s: reconnected to %s during replay\n", @@ -985,8 +977,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, imp->imp_last_replay_transno = 0; IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY); } else { - DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags" - " not set: %x)", imp->imp_obd->obd_name, msg_flags); + DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags not set: %x)", + imp->imp_obd->obd_name, msg_flags); imp->imp_remote_handle = *lustre_msg_get_handle(request->rq_repmsg); IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED); @@ -994,17 +986,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, /* Sanity checks for a reconnected import. */ if (!(imp->imp_replayable) != !(msg_flags & MSG_CONNECT_REPLAYABLE)) { - CERROR("imp_replayable flag does not match server " - "after reconnect. We should LBUG right here.\n"); + CERROR("imp_replayable flag does not match server after reconnect. We should LBUG right here.\n"); } if (lustre_msg_get_last_committed(request->rq_repmsg) > 0 && lustre_msg_get_last_committed(request->rq_repmsg) < aa->pcaa_peer_committed) { - CERROR("%s went back in time (transno %lld" - " was previously committed, server now claims %lld" - ")! See https://bugzilla.lustre.org/show_bug.cgi?" - "id=9646\n", + CERROR("%s went back in time (transno %lld was previously committed, server now claims %lld)! See https://bugzilla.lustre.org/show_bug.cgi?id=9646\n", obd2cli_tgt(imp->imp_obd), aa->pcaa_peer_committed, lustre_msg_get_last_committed(request->rq_repmsg)); } @@ -1013,8 +1001,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, rc = ptlrpc_import_recovery_state_machine(imp); if (rc != 0) { if (rc == -ENOTCONN) { - CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery;" - "invalidating and reconnecting\n", + CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid); ptlrpc_connect_import(imp); @@ -1034,9 +1021,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, if ((imp->imp_connect_flags_orig & OBD_CONNECT_IBITS) && !(ocd->ocd_connect_flags & OBD_CONNECT_IBITS)) { - LCONSOLE_WARN("%s: MDS %s does not support ibits " - "lock, either very old or invalid: " - "requested %llx, replied %llx\n", + LCONSOLE_WARN("%s: MDS %s does not support ibits lock, either very old or invalid: requested %llx, replied %llx\n", imp->imp_obd->obd_name, imp->imp_connection->c_remote_uuid.uuid, imp->imp_connect_flags_orig, @@ -1052,13 +1037,12 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, LUSTRE_VERSION_OFFSET_WARN)) { /* Sigh, some compilers do not like #ifdef in the middle of macro arguments */ - const char *older = "older. Consider upgrading server " - "or downgrading client"; - const char *newer = "newer than client version. " - "Consider upgrading client"; + const char *older = "older. Consider upgrading server or downgrading client" + ; + const char *newer = "newer than client version. Consider upgrading client" + ; - LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) " - "is much %s (%s)\n", + LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) is much %s (%s)\n", obd2cli_tgt(imp->imp_obd), OBD_OCD_VERSION_MAJOR(ocd->ocd_version), OBD_OCD_VERSION_MINOR(ocd->ocd_version), @@ -1095,10 +1079,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, * the checksum types it doesn't support */ if ((ocd->ocd_cksum_types & cksum_types_supported_client()) == 0) { - LCONSOLE_WARN("The negotiation of the checksum " - "algorithm to use with server %s " - "failed (%x/%x), disabling " - "checksums\n", + LCONSOLE_WARN("The negotiation of the checksum algorithm to use with server %s failed (%x/%x), disabling checksums\n", obd2cli_tgt(imp->imp_obd), ocd->ocd_cksum_types, cksum_types_supported_client()); @@ -1191,17 +1172,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, * connection from liblustre clients, so we * should never see this from VFS context */ - LCONSOLE_ERROR_MSG(0x16a, "Server %s version " - "(%d.%d.%d.%d)" - " refused connection from this client " - "with an incompatible version (%s). " - "Client must be recompiled\n", - obd2cli_tgt(imp->imp_obd), - OBD_OCD_VERSION_MAJOR(ocd->ocd_version), - OBD_OCD_VERSION_MINOR(ocd->ocd_version), - OBD_OCD_VERSION_PATCH(ocd->ocd_version), - OBD_OCD_VERSION_FIX(ocd->ocd_version), - LUSTRE_VERSION_STRING); + LCONSOLE_ERROR_MSG(0x16a, "Server %s version (%d.%d.%d.%d) refused connection from this client with an incompatible version (%s). Client must be recompiled\n", + obd2cli_tgt(imp->imp_obd), + OBD_OCD_VERSION_MAJOR(ocd->ocd_version), + OBD_OCD_VERSION_MINOR(ocd->ocd_version), + OBD_OCD_VERSION_PATCH(ocd->ocd_version), + OBD_OCD_VERSION_FIX(ocd->ocd_version), + LUSTRE_VERSION_STRING); ptlrpc_deactivate_import(imp); IMPORT_SET_STATE(imp, LUSTRE_IMP_CLOSED); } @@ -1237,8 +1214,7 @@ static int completed_replay_interpret(const struct lu_env *env, "%s: version recovery fails, reconnecting\n", req->rq_import->imp_obd->obd_name); } else { - CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, " - "reconnecting\n", + CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, reconnecting\n", req->rq_import->imp_obd->obd_name, req->rq_status); } @@ -1343,9 +1319,7 @@ int ptlrpc_import_recovery_state_machine(struct obd_import *imp) /* Don't care about MGC eviction */ if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MGC_NAME) != 0) { - LCONSOLE_ERROR_MSG(0x167, "%s: This client was evicted " - "by %.*s; in progress operations " - "using this service will fail.\n", + LCONSOLE_ERROR_MSG(0x167, "%s: This client was evicted by %.*s; in progress operations using this service will fail.\n", imp->imp_obd->obd_name, target_len, target_start); } @@ -1455,8 +1429,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose) break; default: rc = -EINVAL; - CERROR("%s: don't know how to disconnect from %s " - "(connect_op %d): rc = %d\n", + CERROR("%s: don't know how to disconnect from %s (connect_op %d): rc = %d\n", imp->imp_obd->obd_name, obd2cli_tgt(imp->imp_obd), imp->imp_connect_op, rc); return rc; @@ -1607,8 +1580,8 @@ int at_measured(struct adaptive_timeout *at, unsigned int val) at->at_current = max(at->at_current, at_min); if (at->at_current != old) - CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d " - "(val=%u) hist %u %u %u %u\n", at, + CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d (val=%u) hist %u %u %u %u\n", + at, old, at->at_current, at->at_current - old, val, at->at_hist[0], at->at_hist[1], at->at_hist[2], at->at_hist[3]); diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index 78364ec4fbf0..252f3e13d04a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -1886,8 +1886,8 @@ swabber_dumper_helper(struct req_capsule *pill, swabber(value); ptlrpc_buf_set_swabbed(pill->rc_req, inout, offset); if (dump) { - CDEBUG(D_RPCTRACE, "Dump of swabbed field %s " - "follows\n", field->rmf_name); + CDEBUG(D_RPCTRACE, "Dump of swabbed field %s follows\n", + field->rmf_name); field->rmf_dumper(value); } @@ -1903,8 +1903,7 @@ swabber_dumper_helper(struct req_capsule *pill, i < n; i++, p += field->rmf_size) { if (dump) { - CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, " - "element %d follows\n", + CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, element %d follows\n", do_swab ? "unswabbed " : "", field->rmf_name, i); field->rmf_dumper(p); } @@ -1912,8 +1911,8 @@ swabber_dumper_helper(struct req_capsule *pill, continue; swabber(p); if (dump) { - CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, " - "element %d follows\n", field->rmf_name, i); + CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, element %d follows\n", + field->rmf_name, i); field->rmf_dumper(value); } } @@ -1972,8 +1971,7 @@ static void *__req_capsule_get(struct req_capsule *pill, */ len = lustre_msg_buflen(msg, offset); if ((len % field->rmf_size) != 0) { - CERROR("%s: array field size mismatch " - "%d modulo %d != 0 (%d)\n", + CERROR("%s: array field size mismatch %d modulo %d != 0 (%d)\n", field->rmf_name, len, field->rmf_size, loc); return NULL; } @@ -1986,8 +1984,7 @@ static void *__req_capsule_get(struct req_capsule *pill, if (value == NULL) { DEBUG_REQ(D_ERROR, pill->rc_req, - "Wrong buffer for field `%s' (%d of %d) " - "in format `%s': %d vs. %d (%s)\n", + "Wrong buffer for field `%s' (%d of %d) in format `%s': %d vs. %d (%s)\n", field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name, lustre_msg_buflen(msg, offset), len, rcl_names[loc]); @@ -2020,8 +2017,8 @@ void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) * have a specific dumper */ len = req_capsule_get_size(pill, field, loc); - CDEBUG(D_RPCTRACE, "Field %s has no dumper function;" - "field size is %d\n", field->rmf_name, len); + CDEBUG(D_RPCTRACE, "Field %s has no dumper function; field size is %d\n", + field->rmf_name, len); } else { /* It's the dumping side-effect that we're interested in */ (void) __req_capsule_get(pill, field, loc, NULL, 1); @@ -2173,8 +2170,7 @@ void req_capsule_set_size(struct req_capsule *pill, (size > 0)) { if ((field->rmf_flags & RMF_F_STRUCT_ARRAY) && (size % field->rmf_size != 0)) { - CERROR("%s: array field size mismatch " - "%d %% %d != 0 (%d)\n", + CERROR("%s: array field size mismatch %d %% %d != 0 (%d)\n", field->rmf_name, size, field->rmf_size, loc); LBUG(); } else if (!(field->rmf_flags & RMF_F_STRUCT_ARRAY) && diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c index 56f825fbb17c..e9baf5bbee3a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c @@ -334,8 +334,7 @@ static int llog_client_read_header(const struct lu_env *env, llh_hdr->lrh_type, LLOG_HDR_MAGIC); rc = -EIO; } else if (llh_hdr->lrh_len != LLOG_CHUNK_SIZE) { - CERROR("incorrectly sized log header: %#x " - "(expecting %#x)\n", + CERROR("incorrectly sized log header: %#x (expecting %#x)\n", llh_hdr->lrh_len, LLOG_CHUNK_SIZE); CERROR("you may need to re-run lconf --write_conf.\n"); rc = -EIO; diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index 0c3f667d498f..4011e0050fcb 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -745,8 +745,7 @@ ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt, svcpt->scp_service->srv_name, svcpt->scp_cpt, srhi->srhi_seq, srhi->srhi_req->rq_history_seq); LASSERTF(!list_empty(&svcpt->scp_hist_reqs), - "%s:%d: seek offset %llu, request seq %llu, " - "last culled %llu\n", + "%s:%d: seek offset %llu, request seq %llu, last culled %llu\n", svcpt->scp_service->srv_name, svcpt->scp_cpt, seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled); e = &srhi->srhi_req->rq_history_list; @@ -813,8 +812,8 @@ ptlrpc_lprocfs_svc_req_history_start(struct seq_file *s, loff_t *pos) int i; if (sizeof(loff_t) != sizeof(__u64)) { /* can't support */ - CWARN("Failed to read request history because size of loff_t " - "%d can't match size of u64\n", (int)sizeof(loff_t)); + CWARN("Failed to read request history because size of loff_t %d can't match size of u64\n", + (int)sizeof(loff_t)); return NULL; } @@ -1297,14 +1296,12 @@ int lprocfs_wr_import(struct file *file, const char *buffer, if (*endptr) { CERROR("config: wrong instance # %s\n", ptr); } else if (inst != imp->imp_connect_data.ocd_instance) { - CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted " - "target(%u/%u), reconnecting...\n", + CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n", imp->imp_obd->obd_name, imp->imp_connect_data.ocd_instance, inst); do_reconn = 1; } else { - CDEBUG(D_INFO, "IR: %s has already been connecting to " - "new target(%u)\n", + CDEBUG(D_INFO, "IR: %s has already been connecting to new target(%u)\n", imp->imp_obd->obd_name, inst); } } diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index c1e8aa4d5ec4..f715e9a8b996 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -224,8 +224,8 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) total_md - desc->bd_md_count); spin_unlock(&desc->bd_lock); - CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, " - "xid x%#llx-%#llx, portal %u\n", desc->bd_md_count, + CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, xid x%#llx-%#llx, portal %u\n", + desc->bd_md_count, desc->bd_type == BULK_GET_SOURCE ? "get-source" : "put-sink", desc->bd_iov_count, desc->bd_nob, desc->bd_last_xid, req->rq_xid, desc->bd_portal); @@ -337,8 +337,7 @@ static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) if (req->rq_reqmsg && !(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x " - "req_flags=%#x magic=%d:%x/%x len=%d\n", + CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x req_flags=%#x magic=%d:%x/%x len=%d\n", flags, lustre_msg_get_flags(req->rq_reqmsg), lustre_msg_is_v1(req->rq_reqmsg), lustre_msg_get_magic(req->rq_reqmsg), diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c index 181301bd2083..d5fd7215c72f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c +++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c @@ -770,8 +770,8 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs, tmp = nrs_policy_find_locked(nrs, policy->pol_desc->pd_name); if (tmp != NULL) { - CERROR("NRS policy %s has been registered, can't register it " - "for %s\n", policy->pol_desc->pd_name, + CERROR("NRS policy %s has been registered, can't register it for %s\n", + policy->pol_desc->pd_name, svcpt->scp_service->srv_name); nrs_policy_put_locked(tmp); @@ -882,8 +882,7 @@ static int nrs_register_policies_locked(struct ptlrpc_nrs *nrs) if (nrs_policy_compatible(svc, desc)) { rc = nrs_policy_register(nrs, desc); if (rc != 0) { - CERROR("Failed to register NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to register NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svc->srv_name, rc); /** @@ -1082,8 +1081,7 @@ static int nrs_policy_unregister_locked(struct ptlrpc_nrs_pol_desc *desc) if (rc == -ENOENT) { rc = 0; } else if (rc != 0) { - CERROR("Failed to unregister NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to unregister NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svcpt->scp_service->srv_name, rc); return rc; @@ -1145,18 +1143,15 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) if ((conf->nc_flags & PTLRPC_NRS_FL_REG_EXTERN) && (conf->nc_flags & (PTLRPC_NRS_FL_FALLBACK | PTLRPC_NRS_FL_REG_START))) { - CERROR("NRS: failing to register policy %s. Please check " - "policy flags; external policies cannot act as fallback " - "policies, or be started immediately upon registration " - "without interaction with lprocfs\n", conf->nc_name); + CERROR("NRS: failing to register policy %s. Please check policy flags; external policies cannot act as fallback policies, or be started immediately upon registration without interaction with lprocfs\n", + conf->nc_name); return -EINVAL; } mutex_lock(&nrs_core.nrs_mutex); if (nrs_policy_find_desc_locked(conf->nc_name) != NULL) { - CERROR("NRS: failing to register policy %s which has already " - "been registered with NRS core!\n", + CERROR("NRS: failing to register policy %s which has already been registered with NRS core!\n", conf->nc_name); rc = -EEXIST; goto fail; @@ -1209,8 +1204,7 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf) nrs = nrs_svcpt2nrs(svcpt, hp); rc = nrs_policy_register(nrs, desc); if (rc != 0) { - CERROR("Failed to register NRS policy %s for " - "partition %d of service %s: %d\n", + CERROR("Failed to register NRS policy %s for partition %d of service %s: %d\n", desc->pd_name, svcpt->scp_cpt, svcpt->scp_service->srv_name, rc); @@ -1281,8 +1275,7 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) LASSERT(conf != NULL); if (conf->nc_flags & PTLRPC_NRS_FL_FALLBACK) { - CERROR("Unable to unregister a fallback policy, unless the " - "PTLRPC service is stopping.\n"); + CERROR("Unable to unregister a fallback policy, unless the PTLRPC service is stopping.\n"); return -EPERM; } @@ -1292,8 +1285,7 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) desc = nrs_policy_find_desc_locked(conf->nc_name); if (desc == NULL) { - CERROR("Failing to unregister NRS policy %s which has " - "not been registered with NRS core!\n", + CERROR("Failing to unregister NRS policy %s which has not been registered with NRS core!\n", conf->nc_name); rc = -ENOENT; goto not_exist; @@ -1304,9 +1296,8 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf) rc = nrs_policy_unregister_locked(desc); if (rc < 0) { if (rc == -EBUSY) - CERROR("Please first stop policy %s on all service " - "partitions and then retry to unregister the " - "policy.\n", conf->nc_name); + CERROR("Please first stop policy %s on all service partitions and then retry to unregister the policy.\n", + conf->nc_name); goto fail; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 60552f4e9798..2f45f7657830 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -412,8 +412,8 @@ void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size) buflen = m->lm_buflens[n]; if (unlikely(buflen < min_size)) { - CERROR("msg %p buffer[%d] size %d too small " - "(required %d, opc=%d)\n", m, n, buflen, min_size, + CERROR("msg %p buffer[%d] size %d too small (required %d, opc=%d)\n", + m, n, buflen, min_size, n == MSG_PTLRPC_BODY_OFF ? -1 : lustre_msg_get_opc(m)); return NULL; } @@ -749,21 +749,19 @@ char *lustre_msg_string(struct lustre_msg *m, int index, int max_len) slen = strnlen(str, blen); if (slen == blen) { /* not NULL terminated */ - CERROR("can't unpack non-NULL terminated string in " - "msg %p buffer[%d] len %d\n", m, index, blen); + CERROR("can't unpack non-NULL terminated string in msg %p buffer[%d] len %d\n", + m, index, blen); return NULL; } if (max_len == 0) { if (slen != blen - 1) { - CERROR("can't unpack short string in msg %p " - "buffer[%d] len %d: strlen %d\n", + CERROR("can't unpack short string in msg %p buffer[%d] len %d: strlen %d\n", m, index, blen, slen); return NULL; } } else if (slen > max_len) { - CERROR("can't unpack oversized string in msg %p " - "buffer[%d] len %d strlen %d: max %d expected\n", + CERROR("can't unpack oversized string in msg %p buffer[%d] len %d strlen %d: max %d expected\n", m, index, blen, slen, max_len); return NULL; } @@ -2258,8 +2256,8 @@ void lustre_swab_quota_body(struct quota_body *b) void dump_ioo(struct obd_ioobj *ioo) { CDEBUG(D_RPCTRACE, - "obd_ioobj: ioo_oid="DOSTID", ioo_max_brw=%#x, " - "ioo_bufct=%d\n", POSTID(&ioo->ioo_oid), ioo->ioo_max_brw, + "obd_ioobj: ioo_oid=" DOSTID ", ioo_max_brw=%#x, ioo_bufct=%d\n", + POSTID(&ioo->ioo_oid), ioo->ioo_max_brw, ioo->ioo_bufcnt); } EXPORT_SYMBOL(dump_ioo); @@ -2330,8 +2328,7 @@ void dump_obdo(struct obdo *oa) CDEBUG(D_RPCTRACE, "obdo: o_handle = %lld\n", oa->o_handle.cookie); if (valid & OBD_MD_FLCOOKIE) - CDEBUG(D_RPCTRACE, "obdo: o_lcookie = " - "(llog_cookie dumping not yet implemented)\n"); + CDEBUG(D_RPCTRACE, "obdo: o_lcookie = (llog_cookie dumping not yet implemented)\n"); } EXPORT_SYMBOL(dump_obdo); @@ -2395,17 +2392,15 @@ void _debug_req(struct ptlrpc_request *req, va_start(args, fmt); libcfs_debug_vmsg2(msgdata, fmt, args, - " req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d" - " lens %d/%d e %d to %d dl "CFS_TIME_T" ref %d " - "fl "REQ_FLAGS_FMT"/%x/%x rc %d/%d\n", + " req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d lens %d/%d e %d to %d dl " CFS_TIME_T " ref %d fl " REQ_FLAGS_FMT "/%x/%x rc %d/%d\n", req, req->rq_xid, req->rq_transno, req_ok ? lustre_msg_get_transno(req->rq_reqmsg) : 0, req_ok ? lustre_msg_get_opc(req->rq_reqmsg) : -1, req->rq_import ? - req->rq_import->imp_obd->obd_name : - req->rq_export ? - req->rq_export->exp_client_uuid.uuid : - "", + req->rq_import->imp_obd->obd_name : + req->rq_export ? + req->rq_export->exp_client_uuid.uuid : + "", libcfs_nid2str(nid), req->rq_request_portal, req->rq_reply_portal, req->rq_reqlen, req->rq_replen, diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index b9cbbbd5322e..340d98a64137 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -206,8 +206,7 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, spin_unlock(&imp->imp_lock); - CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u " - "force %u force_next %u deactive %u pingable %u suppress %u\n", + CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u force %u force_next %u deactive %u pingable %u suppress %u\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level), level, force, force_next, imp->imp_deactive, imp->imp_pingable, suppress); @@ -220,8 +219,7 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, } else if (level != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov || imp_is_deactive(imp)) { - CDEBUG(D_HA, "%s->%s: not pinging (in recovery " - "or recovery disabled: %s)\n", + CDEBUG(D_HA, "%s->%s: not pinging (in recovery or recovery disabled: %s)\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level)); if (force) { @@ -334,11 +332,7 @@ int ptlrpc_start_pinger(void) thread_is_running(&pinger_thread), &lwi); if (suppress_pings) - CWARN("Pings will be suppressed at the request of the " - "administrator. The configuration shall meet the " - "additional requirements described in the manual. " - "(Search for the \"suppress_pings\" kernel module " - "parameter.)\n"); + CWARN("Pings will be suppressed at the request of the administrator. The configuration shall meet the additional requirements described in the manual. (Search for the \"suppress_pings\" kernel module parameter.)\n"); return 0; } @@ -623,11 +617,7 @@ static int ping_evictor_main(void *arg) if (expire_time > exp->exp_last_request_time) { class_export_get(exp); spin_unlock(&obd->obd_dev_lock); - LCONSOLE_WARN("%s: haven't heard from client %s" - " (at %s) in %ld seconds. I think" - " it's dead, and I am evicting" - " it. exp %p, cur %ld expire %ld" - " last %ld\n", + LCONSOLE_WARN("%s: haven't heard from client %s (at %s) in %ld seconds. I think it's dead, and I am evicting it. exp %p, cur %ld expire %ld last %ld\n", obd->obd_name, obd_uuid2str(&exp->exp_client_uuid), obd_export_nid2str(exp), diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 357ea9f8bd57..cbcc541cac43 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -356,10 +356,9 @@ static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc) if (atomic_read(&ps->set_new_count)) { rc = ptlrpcd_steal_rqset(set, ps); if (rc > 0) - CDEBUG(D_RPCTRACE, "transfer %d" - " async RPCs [%d->%d]\n", - rc, partner->pc_index, - pc->pc_index); + CDEBUG(D_RPCTRACE, "transfer %d async RPCs [%d->%d]\n", + rc, partner->pc_index, + pc->pc_index); } ptlrpc_reqset_put(ps); } while (rc == 0 && pc->pc_cursor != first); diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c index e1bc77b83ffb..7b1d72947330 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/recover.c +++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c @@ -237,8 +237,7 @@ void ptlrpc_request_handle_notconn(struct ptlrpc_request *failed_req) if (ptlrpc_set_import_discon(imp, lustre_msg_get_conn_cnt(failed_req->rq_reqmsg))) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, " - "auto-deactivating\n", + CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); @@ -274,8 +273,8 @@ int ptlrpc_set_import_active(struct obd_import *imp, int active) /* When deactivating, mark import invalid, and abort in-flight * requests. */ if (!active) { - LCONSOLE_WARN("setting import %s INACTIVE by administrator " - "request\n", obd2cli_tgt(imp->imp_obd)); + LCONSOLE_WARN("setting import %s INACTIVE by administrator request\n", + obd2cli_tgt(imp->imp_obd)); /* set before invalidate to avoid messages about imp_inval * set without imp_deactive in ptlrpc_import_delay_req */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c index 6ac8a8330c7c..21e9dc9d5580 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c @@ -456,8 +456,8 @@ int sptlrpc_req_ctx_switch(struct ptlrpc_request *req, LASSERT(req->rq_reqlen); LASSERT(req->rq_replen); - CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), " - "switch sec %p(%s) -> %p(%s)\n", req, + CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), switch sec %p(%s) -> %p(%s)\n", + req, oldctx, oldctx->cc_vcred.vc_uid, sec2target_str(oldctx->cc_sec), newctx, newctx->cc_vcred.vc_uid, sec2target_str(newctx->cc_sec), oldctx->cc_sec, oldctx->cc_sec->ps_policy->sp_name, @@ -1841,8 +1841,8 @@ int sptlrpc_target_export_check(struct obd_export *exp, req->rq_svc_ctx, &flavor); } else { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, " - "install rvs ctx\n", exp, exp->exp_flvr.sf_rpc, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, install rvs ctx\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc); spin_unlock(&exp->exp_lock); @@ -1855,13 +1855,12 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_expire[0]) { if (exp->exp_flvr_expire[0] >= get_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[0], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the " - "middle one ("CFS_DURATION_T")\n", exp, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the middle one (" CFS_DURATION_T ")\n", exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, exp->exp_flvr_expire[0] - - get_seconds()); + get_seconds()); spin_unlock(&exp->exp_lock); return 0; } @@ -1880,13 +1879,13 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_changed == 0 && exp->exp_flvr_expire[1]) { if (exp->exp_flvr_expire[1] >= get_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[1], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the " - "oldest one ("CFS_DURATION_T")\n", exp, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the oldest one (" CFS_DURATION_T ")\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, exp->exp_flvr_expire[1] - - get_seconds()); + get_seconds()); spin_unlock(&exp->exp_lock); return 0; } @@ -1906,8 +1905,7 @@ int sptlrpc_target_export_check(struct obd_export *exp, spin_unlock(&exp->exp_lock); - CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with " - "unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n", + CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n", exp, exp->exp_obd->obd_name, req, req->rq_auth_gss, req->rq_ctx_init, req->rq_ctx_fini, req->rq_auth_usr_root, req->rq_auth_usr_mdt, req->rq_auth_usr_ost, diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index cc68a1cf24e3..0dabd83fd46f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -772,8 +772,7 @@ void sptlrpc_enc_pool_fini(void) if (page_pools.epp_st_access > 0) { CDEBUG(D_SEC, - "max pages %lu, grows %u, grow fails %u, shrinks %u, " - "access %lu, missing %lu, max qlen %u, max wait " + "max pages %lu, grows %u, grow fails %u, shrinks %u, access %lu, missing %lu, max qlen %u, max wait " CFS_TIME_T"/%d\n", page_pools.epp_st_max_pages, page_pools.epp_st_grows, page_pools.epp_st_grow_fails, diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c index 3d72b810c45c..a79cd53010a4 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c @@ -938,8 +938,8 @@ int plain_svc_wrap_bulk(struct ptlrpc_request *req, rc = plain_generate_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg, tokenv); if (rc) { - CERROR("bulk read: server failed to compute " - "checksum: %d\n", rc); + CERROR("bulk read: server failed to compute checksum: %d\n", + rc); } else { if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE)) corrupt_bulk_data(desc); diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index a8df8a792333..635b12b22cef 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -580,8 +580,7 @@ ptlrpc_server_nthreads_check(struct ptlrpc_service *svc, svc->srv_nthrs_cpt_init = init; if (nthrs * svc->srv_ncpts > tc->tc_nthrs_max) { - CDEBUG(D_OTHER, "%s: This service may have more threads (%d) " - "than the given soft limit (%d)\n", + CDEBUG(D_OTHER, "%s: This service may have more threads (%d) than the given soft limit (%d)\n", svc->srv_name, nthrs * svc->srv_ncpts, tc->tc_nthrs_max); } @@ -1251,8 +1250,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) /* deadline is when the client expects us to reply, margin is the difference between clients' and servers' expectations */ DEBUG_REQ(D_ADAPTTO, req, - "%ssending early reply (deadline %+lds, margin %+lds) for " - "%d+%d", AT_OFF ? "AT off - not " : "", + "%ssending early reply (deadline %+lds, margin %+lds) for %d+%d", + AT_OFF ? "AT off - not " : "", olddl, olddl - at_get(&svcpt->scp_at_estimate), at_get(&svcpt->scp_at_estimate), at_extra); @@ -1260,17 +1259,15 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) return 0; if (olddl < 0) { - DEBUG_REQ(D_WARNING, req, "Already past deadline (%+lds), " - "not sending early reply. Consider increasing " - "at_early_margin (%d)?", olddl, at_early_margin); + DEBUG_REQ(D_WARNING, req, "Already past deadline (%+lds), not sending early reply. Consider increasing at_early_margin (%d)?", + olddl, at_early_margin); /* Return an error so we're not re-added to the timed list. */ return -ETIMEDOUT; } if (!(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, " - "but no AT support"); + DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, but no AT support"); return -ENOSYS; } @@ -1296,8 +1293,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) * we may be past adaptive_max */ if (req->rq_deadline >= req->rq_arrival_time.tv_sec + at_get(&svcpt->scp_at_estimate)) { - DEBUG_REQ(D_WARNING, req, "Couldn't add any time " - "(%ld/%ld), not sending early reply\n", + DEBUG_REQ(D_WARNING, req, "Couldn't add any time (%ld/%ld), not sending early reply\n", olddl, req->rq_arrival_time.tv_sec + at_get(&svcpt->scp_at_estimate) - get_seconds()); @@ -1329,8 +1325,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) LASSERT(atomic_read(&req->rq_refcount)); /** if it is last refcount then early reply isn't needed */ if (atomic_read(&req->rq_refcount) == 1) { - DEBUG_REQ(D_ADAPTTO, reqcopy, "Normal reply already sent out, " - "abort sending early reply\n"); + DEBUG_REQ(D_ADAPTTO, reqcopy, "Normal reply already sent out, abort sending early reply\n"); rc = -EINVAL; goto out; } @@ -1454,16 +1449,14 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt) spin_unlock(&svcpt->scp_at_lock); - CDEBUG(D_ADAPTTO, "timeout in %+ds, asking for %d secs on %d early " - "replies\n", first, at_extra, counter); + CDEBUG(D_ADAPTTO, "timeout in %+ds, asking for %d secs on %d early replies\n", + first, at_extra, counter); if (first < 0) { /* We're already past request deadlines before we even get a chance to send early replies */ - LCONSOLE_WARN("%s: This server is not able to keep up with " - "request traffic (cpu-bound).\n", + LCONSOLE_WARN("%s: This server is not able to keep up with request traffic (cpu-bound).\n", svcpt->scp_service->srv_name); - CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, " - "delay="CFS_DURATION_T"(jiff)\n", + CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=" CFS_DURATION_T "(jiff)\n", counter, svcpt->scp_nreqs_incoming, svcpt->scp_nreqs_active, at_get(&svcpt->scp_at_estimate), delay); @@ -1825,8 +1818,7 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, if (rc == 0) { rc = sptlrpc_target_export_check(req->rq_export, req); if (rc) - DEBUG_REQ(D_ERROR, req, "DROPPING req with " - "illegal security flavor,"); + DEBUG_REQ(D_ERROR, req, "DROPPING req with illegal security flavor,"); } if (rc) @@ -1942,18 +1934,17 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt, /* Discard requests queued for longer than the deadline. The deadline is increased if we send an early reply. */ if (get_seconds() > request->rq_deadline) { - DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s" - ": deadline "CFS_DURATION_T":"CFS_DURATION_T"s ago\n", + DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s: deadline " CFS_DURATION_T ":" CFS_DURATION_T "s ago\n", libcfs_id2str(request->rq_peer), cfs_time_sub(request->rq_deadline, - request->rq_arrival_time.tv_sec), + request->rq_arrival_time.tv_sec), cfs_time_sub(get_seconds(), - request->rq_deadline)); + request->rq_deadline)); goto put_conn; } - CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc " - "%s:%s+%d:%d:x%llu:%s:%d\n", current_comm(), + CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d\n", + current_comm(), (request->rq_export ? (char *)request->rq_export->exp_client_uuid.uuid : "0"), (request->rq_export ? @@ -1986,26 +1977,24 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt, do_gettimeofday(&work_end); timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc " - "%s:%s+%d:%d:x%llu:%s:%d Request processed in " - "%ldus (%ldus total) trans %llu rc %d/%d\n", - current_comm(), - (request->rq_export ? - (char *)request->rq_export->exp_client_uuid.uuid : "0"), - (request->rq_export ? - atomic_read(&request->rq_export->exp_refcount) : -99), - lustre_msg_get_status(request->rq_reqmsg), - request->rq_xid, - libcfs_id2str(request->rq_peer), - lustre_msg_get_opc(request->rq_reqmsg), - timediff, - cfs_timeval_sub(&work_end, &request->rq_arrival_time, NULL), - (request->rq_repmsg ? - lustre_msg_get_transno(request->rq_repmsg) : - request->rq_transno), - request->rq_status, - (request->rq_repmsg ? - lustre_msg_get_status(request->rq_repmsg) : -999)); + CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d Request processed in %ldus (%ldus total) trans %llu rc %d/%d\n", + current_comm(), + (request->rq_export ? + (char *)request->rq_export->exp_client_uuid.uuid : "0"), + (request->rq_export ? + atomic_read(&request->rq_export->exp_refcount) : -99), + lustre_msg_get_status(request->rq_reqmsg), + request->rq_xid, + libcfs_id2str(request->rq_peer), + lustre_msg_get_opc(request->rq_reqmsg), + timediff, + cfs_timeval_sub(&work_end, &request->rq_arrival_time, NULL), + (request->rq_repmsg ? + lustre_msg_get_transno(request->rq_repmsg) : + request->rq_transno), + request->rq_status, + (request->rq_repmsg ? + lustre_msg_get_status(request->rq_repmsg) : -999)); if (likely(svc->srv_stats != NULL && request->rq_reqmsg != NULL)) { __u32 op = lustre_msg_get_opc(request->rq_reqmsg); int opc = opcode_offset(op); @@ -2557,8 +2546,8 @@ static int ptlrpc_start_hr_threads(void) if (!IS_ERR_VALUE(rc)) continue; - CERROR("Reply handling thread %d:%d Failed on starting: " - "rc = %d\n", i, j, rc); + CERROR("Reply handling thread %d:%d Failed on starting: rc = %d\n", + i, j, rc); ptlrpc_stop_hr_threads(); return rc; } @@ -2920,8 +2909,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc) rc = l_wait_event(svcpt->scp_waitq, svcpt->scp_nrqbds_posted == 0, &lwi); if (rc == -ETIMEDOUT) { - CWARN("Service %s waiting for " - "request buffers\n", + CWARN("Service %s waiting for request buffers\n", svcpt->scp_service->srv_name); } spin_lock(&svcpt->scp_lock); -- GitLab From 40e7fcb19293cbdff02c74cb0668413480f82ea1 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Sun, 23 Nov 2014 21:22:54 +0800 Subject: [PATCH 5895/9457] ACPI: Add _DEP support to fix battery issue on Asus T100TA ACPI 5.0 introduces _DEP (Operation Region Dependencies) to designate device objects that OSPM should assign a higher priority in start ordering due to future operation region accesses. On Asus T100TA, ACPI battery info are read from a I2C slave device via I2C operation region. Before I2C operation region handler is installed, battery _STA always returns 0. There is a _DEP method of designating start order under battery device node. This patch is to implement _DEP feature to fix battery issue on the Asus T100TA. Introducing acpi_dep_list and adding dep_unmet count in struct acpi_device. During ACPI namespace scan, create struct acpi_dep_data for a valid pair of master (device pointed to by _DEP)/ slave(device with _DEP), record master's and slave's ACPI handle in it and put it into acpi_dep_list. The dep_unmet count will increase by one if there is a device under its _DEP. Driver's probe() should return EPROBE_DEFER when find dep_unmet is larger than 0. When I2C operation region handler is installed, remove all struct acpi_dep_data on the acpi_dep_list whose master is pointed to I2C host controller and decrease slave's dep_unmet. When dep_unmet decreases to 0, all _DEP conditions are met and then do acpi_bus_attach() for the device in order to resolve battery _STA issue on the Asus T100TA. Link: https://bugzilla.kernel.org/show_bug.cgi?id=69011 Tested-by: Jan-Michael Brummer Tested-by: Adam Williamson Tested-by: Michael Shigorin Acked-by: Wolfram Sang Acked-by: Mika Westerberg Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 4 ++ drivers/acpi/scan.c | 85 +++++++++++++++++++++++++++++++++++++++++ drivers/i2c/i2c-core.c | 1 + include/acpi/acpi_bus.h | 1 + include/linux/acpi.h | 1 + 5 files changed, 92 insertions(+) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 8ec8a89a20ab..d98ba4355819 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1180,6 +1180,10 @@ static int acpi_battery_add(struct acpi_device *device) if (!device) return -EINVAL; + + if (device->dep_unmet) + return -EPROBE_DEFER; + battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); if (!battery) return -ENOMEM; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0476e90b2091..00189ad63c8f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -36,6 +36,8 @@ bool acpi_force_hot_remove; static const char *dummy_hid = "device"; +static LIST_HEAD(acpi_dep_list); +static DEFINE_MUTEX(acpi_dep_list_lock); static LIST_HEAD(acpi_bus_id_list); static DEFINE_MUTEX(acpi_scan_lock); static LIST_HEAD(acpi_scan_handlers_list); @@ -43,6 +45,12 @@ DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); static DEFINE_MUTEX(acpi_hp_context_lock); +struct acpi_dep_data { + struct list_head node; + acpi_handle master; + acpi_handle slave; +}; + struct acpi_device_bus_id{ char bus_id[15]; unsigned int instance_no; @@ -2086,6 +2094,59 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev) } } +static void acpi_device_dep_initialize(struct acpi_device *adev) +{ + struct acpi_dep_data *dep; + struct acpi_handle_list dep_devices; + acpi_status status; + int i; + + if (!acpi_has_method(adev->handle, "_DEP")) + return; + + status = acpi_evaluate_reference(adev->handle, "_DEP", NULL, + &dep_devices); + if (ACPI_FAILURE(status)) { + dev_err(&adev->dev, "Failed to evaluate _DEP.\n"); + return; + } + + for (i = 0; i < dep_devices.count; i++) { + struct acpi_device_info *info; + int skip; + + status = acpi_get_object_info(dep_devices.handles[i], &info); + if (ACPI_FAILURE(status)) { + dev_err(&adev->dev, "Error reading device info\n"); + continue; + } + + /* + * Skip the dependency of Windows System Power + * Management Controller + */ + skip = info->valid & ACPI_VALID_HID && + !strcmp(info->hardware_id.string, "INT3396"); + + kfree(info); + + if (skip) + continue; + + dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL); + if (!dep) + return; + + dep->master = dep_devices.handles[i]; + dep->slave = adev->handle; + adev->dep_unmet++; + + mutex_lock(&acpi_dep_list_lock); + list_add_tail(&dep->node , &acpi_dep_list); + mutex_unlock(&acpi_dep_list_lock); + } +} + static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, void *not_used, void **return_value) { @@ -2112,6 +2173,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_CTRL_DEPTH; acpi_scan_init_hotplug(device); + acpi_device_dep_initialize(device); out: if (!*return_value) @@ -2232,6 +2294,29 @@ static void acpi_bus_attach(struct acpi_device *device) device->handler->hotplug.notify_online(device); } +void acpi_walk_dep_device_list(acpi_handle handle) +{ + struct acpi_dep_data *dep, *tmp; + struct acpi_device *adev; + + mutex_lock(&acpi_dep_list_lock); + list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { + if (dep->master == handle) { + acpi_bus_get_device(dep->slave, &adev); + if (!adev) + continue; + + adev->dep_unmet--; + if (!adev->dep_unmet) + acpi_bus_attach(adev); + list_del(&dep->node); + kfree(dep); + } + } + mutex_unlock(&acpi_dep_list_lock); +} +EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list); + /** * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. * @handle: Root of the namespace scope to scan. diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f43b4e11647a..68aeb8eedae0 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -403,6 +403,7 @@ static int acpi_i2c_install_space_handler(struct i2c_adapter *adapter) return -ENOMEM; } + acpi_walk_dep_device_list(handle); return 0; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f34a0835aa4f..ea3697dc7046 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -359,6 +359,7 @@ struct acpi_device { void *driver_data; struct device dev; unsigned int physical_node_count; + unsigned int dep_unmet; struct list_head physical_node_list; struct mutex physical_node_lock; void (*remove)(struct acpi_device *); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 407a12f663eb..6cb310388c88 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -431,6 +431,7 @@ static inline bool acpi_driver_match_device(struct device *dev, int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *); int acpi_device_modalias(struct device *, char *, int); +void acpi_walk_dep_device_list(acpi_handle handle); struct platform_device *acpi_create_platform_device(struct acpi_device *); #define ACPI_PTR(_ptr) (_ptr) -- GitLab From e5d08d718a7cd72c6aa79b5f0c309d9f0d7e4a95 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Sun, 23 Nov 2014 21:28:43 +0000 Subject: [PATCH 5896/9457] ipv6: coding style improvements (remove assignment in if statements) This change has no functional impact and simply addresses some coding style issues detected by checkpatch. Specifically this change adjusts "if" statements which also include the assignment of a variable. No changes to the resultant object files result as determined by objdiff. Signed-off-by: Ian Morris Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 12 ++++++++---- net/ipv6/ah6.c | 7 ++++--- net/ipv6/esp6.c | 3 ++- net/ipv6/icmp.c | 3 ++- net/ipv6/ip6_flowlabel.c | 6 +++++- net/ipv6/ip6_input.c | 3 ++- net/ipv6/ip6_output.c | 12 ++++++++---- net/ipv6/ip6_tunnel.c | 15 ++++++++------- net/ipv6/ip6_vti.c | 4 ++-- net/ipv6/ndisc.c | 7 ++++--- net/ipv6/reassembly.c | 3 ++- net/ipv6/sit.c | 7 ++++--- net/ipv6/udp.c | 6 ++++-- 13 files changed, 55 insertions(+), 33 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 251fcb48b216..9eac3a7fefa3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2543,7 +2543,8 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags, if (!dev) return -ENODEV; - if ((idev = __in6_dev_get(dev)) == NULL) + idev = __in6_dev_get(dev); + if (idev == NULL) return -ENXIO; read_lock_bh(&idev->lock); @@ -2690,7 +2691,8 @@ static void init_loopback(struct net_device *dev) ASSERT_RTNL(); - if ((idev = ipv6_find_idev(dev)) == NULL) { + idev = ipv6_find_idev(dev); + if (idev == NULL) { pr_debug("%s: add_dev failed\n", __func__); return; } @@ -2813,7 +2815,8 @@ static void addrconf_sit_config(struct net_device *dev) * our v4 addrs in the tunnel */ - if ((idev = ipv6_find_idev(dev)) == NULL) { + idev = ipv6_find_idev(dev); + if (idev == NULL) { pr_debug("%s: add_dev failed\n", __func__); return; } @@ -2837,7 +2840,8 @@ static void addrconf_gre_config(struct net_device *dev) ASSERT_RTNL(); - if ((idev = ipv6_find_idev(dev)) == NULL) { + idev = ipv6_find_idev(dev); + if (idev == NULL) { pr_debug("%s: add_dev failed\n", __func__); return; } diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 8ab1989198f6..a6727add2624 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -353,7 +353,8 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) ahp = x->data; ahash = ahp->ahash; - if ((err = skb_cow_data(skb, 0, &trailer)) < 0) + err = skb_cow_data(skb, 0, &trailer); + if (err < 0) goto out; nfrags = err; @@ -559,8 +560,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) if (!pskb_may_pull(skb, ah_hlen)) goto out; - - if ((err = skb_cow_data(skb, 0, &trailer)) < 0) + err = skb_cow_data(skb, 0, &trailer); + if (err < 0) goto out; nfrags = err; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index d2c2d749b6db..e48f2c7c5c59 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -345,7 +345,8 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) goto out; } - if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) { + nfrags = skb_cow_data(skb, 0, &trailer); + if (nfrags < 0) { ret = -EINVAL; goto out; } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 39b3ff97a504..d674152b6ede 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -243,7 +243,8 @@ int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *icmp6h; int err = 0; - if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + skb = skb_peek(&sk->sk_write_queue); + if (skb == NULL) goto out; icmp6h = icmp6_hdr(skb); diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 7221021b2d97..2f780cba6e12 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -654,7 +654,11 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) goto done; err = -ENOMEM; - if (sfl1 == NULL || (err = mem_check(sk)) != 0) + if (sfl1 == NULL) + goto done; + + err = mem_check(sk); + if (err != 0) goto done; fl1 = fl_intern(net, fl, freq.flr_label); diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index a3084ab5df6c..aacdcb4dc762 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -220,7 +220,8 @@ static int ip6_input_finish(struct sk_buff *skb) nexthdr = skb_network_header(skb)[nhoff]; raw = raw6_local_deliver(skb, nexthdr); - if ((ipprot = rcu_dereference(inet6_protos[nexthdr])) != NULL) { + ipprot = rcu_dereference(inet6_protos[nexthdr]); + if (ipprot != NULL) { int ret; if (ipprot->flags & INET6_PROTO_FINAL) { diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 916d2a166a9b..ce69a12ae48c 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -898,7 +898,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, if (*dst == NULL) *dst = ip6_route_output(net, sk, fl6); - if ((err = (*dst)->error)) + err = (*dst)->error; + if (err) goto out_err_release; if (ipv6_addr_any(&fl6->saddr)) { @@ -946,7 +947,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, memcpy(&fl_gw6, fl6, sizeof(struct flowi6)); memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr)); *dst = ip6_route_output(net, sk, &fl_gw6); - if ((err = (*dst)->error)) + err = (*dst)->error; + if (err) goto out_err_release; } } @@ -1054,7 +1056,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, * device, so create one single skb packet containing complete * udp datagram */ - if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { + skb = skb_peek_tail(&sk->sk_write_queue); + if (skb == NULL) { skb = sock_alloc_send_skb(sk, hh_len + fragheaderlen + transhdrlen + 20, (flags & MSG_DONTWAIT), &err); @@ -1534,7 +1537,8 @@ int ip6_push_pending_frames(struct sock *sk) unsigned char proto = fl6->flowi6_proto; int err = 0; - if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL) + skb = __skb_dequeue(&sk->sk_write_queue); + if (skb == NULL) goto out; tail_skb = &(skb_shinfo(skb)->frag_list); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index e2b6cfba873c..92b3da571980 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -501,8 +501,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, processing of the error. */ rcu_read_lock(); - if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr, - &ipv6h->saddr)) == NULL) + t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr, &ipv6h->saddr); + if (t == NULL) goto out; tproto = ACCESS_ONCE(t->parms.proto); @@ -550,7 +550,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, mtu = IPV6_MIN_MTU; t->dev->mtu = mtu; - if ((len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len)) > mtu) { + len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len); + if (len > mtu) { rel_type = ICMPV6_PKT_TOOBIG; rel_code = 0; rel_info = mtu; @@ -811,9 +812,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, int err; rcu_read_lock(); - - if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, - &ipv6h->daddr)) != NULL) { + t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr); + if (t != NULL) { struct pcpu_sw_netstats *tstats; tproto = ACCESS_ONCE(t->parms.proto); @@ -1069,7 +1069,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb; - if (!(new_skb = skb_realloc_headroom(skb, max_headroom))) + new_skb = skb_realloc_headroom(skb, max_headroom); + if (!new_skb) goto tx_err_dst_release; if (skb->sk) diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index ec84d03491c7..83082168b056 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -287,8 +287,8 @@ static int vti6_rcv(struct sk_buff *skb) const struct ipv6hdr *ipv6h = ipv6_hdr(skb); rcu_read_lock(); - if ((t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, - &ipv6h->daddr)) != NULL) { + t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr); + if (t != NULL) { if (t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) { rcu_read_unlock(); goto discard; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2c9f6bf57325..682866777d53 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -162,7 +162,8 @@ static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data) memcpy(opt+2, data, data_len); data_len += 2; opt += data_len; - if ((space -= data_len) > 0) + space -= data_len; + if (space > 0) memset(opt, 0, space); } @@ -656,8 +657,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1)) saddr = &ipv6_hdr(skb)->saddr; - - if ((probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES)) < 0) { + probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); + if (probes < 0) { if (!(neigh->nud_state & NUD_VALID)) { ND_PRINTK(1, dbg, "%s: trying to ucast probe in NUD_INVALID: %pI6\n", diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 51ab096ae574..d7d70e69973b 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -429,7 +429,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, struct sk_buff *clone; int i, plen = 0; - if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) + clone = alloc_skb(0, GFP_ATOMIC); + if (clone == NULL) goto out_oom; clone->next = head->next; head->next = clone; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 660496de6125..213546bd6d5d 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1241,7 +1241,8 @@ ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) goto done; err = -ENOENT; - if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL) + t = ipip6_tunnel_locate(net, &p, 0); + if (t == NULL) goto done; err = -EPERM; if (t == netdev_priv(sitn->fb_tunnel_dev)) @@ -1836,8 +1837,8 @@ static int __net_init sit_init_net(struct net *net) goto err_dev_free; ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); - - if ((err = register_netdev(sitn->fb_tunnel_dev))) + err = register_netdev(sitn->fb_tunnel_dev); + if (err) goto err_reg_dev; t = netdev_priv(sitn->fb_tunnel_dev); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 0ba3de4f2368..dbc0b042bdd6 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -357,7 +357,8 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, struct sock *sk; const struct ipv6hdr *iph = ipv6_hdr(skb); - if (unlikely(sk = skb_steal_sock(skb))) + sk = skb_steal_sock(skb); + if (unlikely(sk)) return sk; return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport, &iph->daddr, dport, inet6_iif(skb), @@ -1026,7 +1027,8 @@ static int udp_v6_push_pending_frames(struct sock *sk) fl6 = &inet->cork.fl.u.ip6; /* Grab the skbuff where UDP header space exists. */ - if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + skb = skb_peek(&sk->sk_write_queue); + if (skb == NULL) goto out; /* -- GitLab From c33d23c21501f8e3e045e73b55a49167e1f3a721 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 23 Nov 2014 12:27:41 -0800 Subject: [PATCH 5897/9457] enic: use netdev_rss_key_fill() helper Use of well known RSS key might increase attack surface. Switch to a random one, using generic helper so that all ports share a common key. Signed-off-by: Eric Dumazet Cc: Christian Benvenuti Cc: Govindarajulu Varadarajan <_govind@gmx.com> Cc: Sujith Sankar Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic_main.c | 24 ++++++++++----------- drivers/net/ethernet/cisco/enic/vnic_rss.h | 9 ++++++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 46647407d585..86ee350e57f0 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1890,23 +1890,23 @@ static int enic_dev_hang_reset(struct enic *enic) static int enic_set_rsskey(struct enic *enic) { + union vnic_rss_key *rss_key_buf_va; dma_addr_t rss_key_buf_pa; - union vnic_rss_key *rss_key_buf_va = NULL; - union vnic_rss_key rss_key = { - .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101}, - .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101}, - .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115}, - .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108}, - }; - int err; + u8 rss_key[ENIC_RSS_LEN]; + int i, kidx, bidx, err; - rss_key_buf_va = pci_alloc_consistent(enic->pdev, - sizeof(union vnic_rss_key), &rss_key_buf_pa); + rss_key_buf_va = pci_zalloc_consistent(enic->pdev, + sizeof(union vnic_rss_key), + &rss_key_buf_pa); if (!rss_key_buf_va) return -ENOMEM; - memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key)); - + netdev_rss_key_fill(rss_key, ENIC_RSS_LEN); + for (i = 0; i < ENIC_RSS_LEN; i++) { + kidx = i / ENIC_RSS_BYTES_PER_KEY; + bidx = i % ENIC_RSS_BYTES_PER_KEY; + rss_key_buf_va->key[kidx].b[bidx] = rss_key[i]; + } spin_lock_bh(&enic->devcmd_lock); err = enic_set_rss_key(enic, rss_key_buf_pa, diff --git a/drivers/net/ethernet/cisco/enic/vnic_rss.h b/drivers/net/ethernet/cisco/enic/vnic_rss.h index fa421baf45b8..881fa18542b3 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rss.h +++ b/drivers/net/ethernet/cisco/enic/vnic_rss.h @@ -20,11 +20,16 @@ #define _VNIC_RSS_H_ /* RSS key array */ + +#define ENIC_RSS_BYTES_PER_KEY 10 +#define ENIC_RSS_KEYS 4 +#define ENIC_RSS_LEN (ENIC_RSS_BYTES_PER_KEY * ENIC_RSS_KEYS) + union vnic_rss_key { struct { - u8 b[10]; + u8 b[ENIC_RSS_BYTES_PER_KEY]; u8 b_pad[6]; - } key[4]; + } key[ENIC_RSS_KEYS]; u64 raw[8]; }; -- GitLab From 09b8b3c83971c82fd1a0ae32625b3be2aa891688 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 18 Nov 2014 10:50:21 -0800 Subject: [PATCH 5898/9457] f2fs: call flush_dcache_page when the page was updated Whenever f2fs updates mapped pages, it needs to call flush_dcache_page. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index f26fb87da163..914b6d37c5cf 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -106,6 +106,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) src_addr = inline_data_addr(dn->inode_page); dst_addr = kmap_atomic(page); memcpy(dst_addr, src_addr, MAX_INLINE_DATA); + flush_dcache_page(page); kunmap_atomic(dst_addr); SetPageUptodate(page); no_update: -- GitLab From c9ee00857c9630fba14ebe368d06dc3ac2489b84 Mon Sep 17 00:00:00 2001 From: Changman Lee Date: Fri, 21 Nov 2014 15:42:07 +0900 Subject: [PATCH 5899/9457] f2fs: fix wrong data structure when create slab It used nat_entry_set when create slab for sit_entry_set. Signed-off-by: Changman Lee Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index e094675497d8..9de857f6899b 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -2231,7 +2231,7 @@ int __init create_segment_manager_caches(void) goto fail; sit_entry_set_slab = f2fs_kmem_cache_create("sit_entry_set", - sizeof(struct nat_entry_set)); + sizeof(struct sit_entry_set)); if (!sit_entry_set_slab) goto destory_discard_entry; -- GitLab From 9486ba442b00a6b227bfe0d66b0f4dbcd1a2ee91 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 21 Nov 2014 16:36:28 -0800 Subject: [PATCH 5900/9457] f2fs: introduce f2fs_dentry_kunmap to clean up This patch introduces f2fs_dentry_kunmap to clean up dirty codes. Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 3 +-- fs/f2fs/f2fs.h | 6 ++++++ fs/f2fs/namei.c | 30 ++++++++++-------------------- fs/f2fs/recovery.c | 3 +-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 5a49995a666e..b1a7d5737cd0 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -271,8 +271,7 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr) de = f2fs_find_entry(dir, qstr, &page); if (de) { res = le32_to_cpu(de->ino); - if (!f2fs_has_inline_dentry(dir)) - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 418c8524a164..d04281319dbe 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1229,6 +1229,12 @@ static inline void *inline_dentry_addr(struct page *page) return (void *)&(ri->i_addr[1]); } +static inline void f2fs_dentry_kunmap(struct inode *dir, struct page *page) +{ + if (!f2fs_has_inline_dentry(dir)) + kunmap(page); +} + static inline int f2fs_readonly(struct super_block *sb) { return sb->s_flags & MS_RDONLY; diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 2bee559a690f..547a2deeb1ac 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -200,8 +200,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, de = f2fs_find_entry(dir, &dentry->d_name, &page); if (de) { nid_t ino = le32_to_cpu(de->ino); - if (!f2fs_has_inline_dentry(dir)) - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); inode = f2fs_iget(dir->i_sb, ino); @@ -231,8 +230,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) err = acquire_orphan_inode(sbi); if (err) { f2fs_unlock_op(sbi); - if (!f2fs_has_inline_dentry(dir)) - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); goto fail; } @@ -469,8 +467,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, old_dir_page, new_dir); update_inode_page(old_inode); } else { - if (!f2fs_has_inline_dentry(old_inode)) - kunmap(old_dir_page); + f2fs_dentry_kunmap(old_inode, old_dir_page); f2fs_put_page(old_dir_page, 0); } drop_nlink(old_dir); @@ -486,18 +483,15 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, put_out_dir: f2fs_unlock_op(sbi); - if (!f2fs_has_inline_dentry(new_dir)) - kunmap(new_page); + f2fs_dentry_kunmap(new_dir, new_page); f2fs_put_page(new_page, 0); out_dir: if (old_dir_entry) { - if (!f2fs_has_inline_dentry(old_inode)) - kunmap(old_dir_page); + f2fs_dentry_kunmap(old_inode, old_dir_page); f2fs_put_page(old_dir_page, 0); } out_old: - if (!f2fs_has_inline_dentry(old_dir)) - kunmap(old_page); + f2fs_dentry_kunmap(old_dir, old_page); f2fs_put_page(old_page, 0); out: return err; @@ -632,23 +626,19 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, f2fs_unlock_op(sbi); out_new_dir: if (new_dir_entry) { - if (!f2fs_has_inline_dentry(new_inode)) - kunmap(new_dir_page); + f2fs_dentry_kunmap(new_inode, new_dir_page); f2fs_put_page(new_dir_page, 0); } out_old_dir: if (old_dir_entry) { - if (!f2fs_has_inline_dentry(old_inode)) - kunmap(old_dir_page); + f2fs_dentry_kunmap(old_inode, old_dir_page); f2fs_put_page(old_dir_page, 0); } out_new: - if (!f2fs_has_inline_dentry(new_dir)) - kunmap(new_page); + f2fs_dentry_kunmap(new_dir, new_page); f2fs_put_page(new_page, 0); out_old: - if (!f2fs_has_inline_dentry(old_dir)) - kunmap(old_page); + f2fs_dentry_kunmap(old_dir, old_page); f2fs_put_page(old_page, 0); out: return err; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 4b180bbc3a21..9a93a6e29b05 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -129,8 +129,7 @@ static int recover_dentry(struct inode *inode, struct page *ipage) goto out; out_unmap_put: - if (!f2fs_has_inline_dentry(dir)) - kunmap(page); + f2fs_dentry_kunmap(dir, page); f2fs_put_page(page, 0); out_err: iput(dir); -- GitLab From 0341845efcb4a656707b6d551c3057d6dd27009f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 21 Nov 2014 16:37:40 -0800 Subject: [PATCH 5901/9457] f2fs: fix livelock calling f2fs_iget during f2fs_evict_inode In f2fs_evict_inode, commit_inmemory_pages f2fs_gc f2fs_iget iget_locked -> wait for inode free Here, if the inode is same as the one to be evicted, f2fs should wait forever. Actually, we should not call f2fs_balance_fs during f2fs_evict_inode to avoid this. But, the commit_inmem_pages calls f2fs_balance_fs by default, even if f2fs_evict_inode wants to free inmemory pages only. Hence, this patch adds to trigger f2fs_balance_fs only when there is something to write. Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9de857f6899b..9a33e34d26ce 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -230,7 +230,16 @@ void commit_inmem_pages(struct inode *inode, bool abort) .rw = WRITE_SYNC, }; - f2fs_balance_fs(sbi); + /* + * The abort is true only when f2fs_evict_inode is called. + * Basically, the f2fs_evict_inode doesn't produce any data writes, so + * that we don't need to call f2fs_balance_fs. + * Otherwise, f2fs_gc in f2fs_balance_fs can wait forever until this + * inode becomes free by iget_locked in f2fs_iget. + */ + if (!abort) + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); mutex_lock(&fi->inmem_lock); -- GitLab From 3fd0d3c170ad6ba8b64e16938f699d0b43cc782e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Nov 2014 15:39:51 +0100 Subject: [PATCH 5902/9457] iwlwifi: pcie: support 7265-D devices Identify 7265-D devices using the hardware revision (they have the same PCI IDs as 7265) and change the configuration for them taking the differences (currently only the firmware image) into account. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-7000.c | 34 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-config.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-csr.h | 35 ++++++++++++----------- drivers/net/wireless/iwlwifi/pcie/drv.c | 20 +++++++++++++ 4 files changed, 75 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index b4e9bc7cc929..84d2a4280694 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -102,6 +102,9 @@ #define IWL7265_FW_PRE "iwlwifi-7265-" #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" +#define IWL7265D_FW_PRE "iwlwifi-7265D-" +#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" + #define NVM_HW_SECTION_NUM_FAMILY_7000 0 static const struct iwl_base_params iwl7000_base_params = { @@ -267,7 +270,38 @@ const struct iwl_cfg iwl7265_n_cfg = { .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, }; +const struct iwl_cfg iwl7265d_2ac_cfg = { + .name = "Intel(R) Dual Band Wireless AC 7265", + .fw_name_pre = IWL7265D_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7265_ht_params, + .nvm_ver = IWL7265_NVM_VERSION, + .nvm_calib_ver = IWL7265_TX_POWER_VERSION, + .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, +}; + +const struct iwl_cfg iwl7265d_2n_cfg = { + .name = "Intel(R) Dual Band Wireless N 7265", + .fw_name_pre = IWL7265D_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7265_ht_params, + .nvm_ver = IWL7265_NVM_VERSION, + .nvm_calib_ver = IWL7265_TX_POWER_VERSION, + .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, +}; + +const struct iwl_cfg iwl7265d_n_cfg = { + .name = "Intel(R) Wireless N 7265", + .fw_name_pre = IWL7265D_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7265_ht_params, + .nvm_ver = IWL7265_NVM_VERSION, + .nvm_calib_ver = IWL7265_TX_POWER_VERSION, + .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, +}; + MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); MODULE_FIRMWARE(IWL3165_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); +MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index c6ae4d4ec202..d43e90d894ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -364,6 +364,9 @@ extern const struct iwl_cfg iwl3165_2ac_cfg; extern const struct iwl_cfg iwl7265_2ac_cfg; extern const struct iwl_cfg iwl7265_2n_cfg; extern const struct iwl_cfg iwl7265_n_cfg; +extern const struct iwl_cfg iwl7265d_2ac_cfg; +extern const struct iwl_cfg iwl7265d_2n_cfg; +extern const struct iwl_cfg iwl7265d_n_cfg; extern const struct iwl_cfg iwl8260_2n_cfg; extern const struct iwl_cfg iwl8260_2ac_cfg; extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 99657172ab85..aff63c3f5bf8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -309,23 +309,24 @@ enum { }; -#define CSR_HW_REV_TYPE_MSK (0x000FFF0) -#define CSR_HW_REV_TYPE_5300 (0x0000020) -#define CSR_HW_REV_TYPE_5350 (0x0000030) -#define CSR_HW_REV_TYPE_5100 (0x0000050) -#define CSR_HW_REV_TYPE_5150 (0x0000040) -#define CSR_HW_REV_TYPE_1000 (0x0000060) -#define CSR_HW_REV_TYPE_6x00 (0x0000070) -#define CSR_HW_REV_TYPE_6x50 (0x0000080) -#define CSR_HW_REV_TYPE_6150 (0x0000084) -#define CSR_HW_REV_TYPE_6x05 (0x00000B0) -#define CSR_HW_REV_TYPE_6x30 CSR_HW_REV_TYPE_6x05 -#define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 -#define CSR_HW_REV_TYPE_2x30 (0x00000C0) -#define CSR_HW_REV_TYPE_2x00 (0x0000100) -#define CSR_HW_REV_TYPE_105 (0x0000110) -#define CSR_HW_REV_TYPE_135 (0x0000120) -#define CSR_HW_REV_TYPE_NONE (0x00001F0) +#define CSR_HW_REV_TYPE_MSK (0x000FFF0) +#define CSR_HW_REV_TYPE_5300 (0x0000020) +#define CSR_HW_REV_TYPE_5350 (0x0000030) +#define CSR_HW_REV_TYPE_5100 (0x0000050) +#define CSR_HW_REV_TYPE_5150 (0x0000040) +#define CSR_HW_REV_TYPE_1000 (0x0000060) +#define CSR_HW_REV_TYPE_6x00 (0x0000070) +#define CSR_HW_REV_TYPE_6x50 (0x0000080) +#define CSR_HW_REV_TYPE_6150 (0x0000084) +#define CSR_HW_REV_TYPE_6x05 (0x00000B0) +#define CSR_HW_REV_TYPE_6x30 CSR_HW_REV_TYPE_6x05 +#define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 +#define CSR_HW_REV_TYPE_2x30 (0x00000C0) +#define CSR_HW_REV_TYPE_2x00 (0x0000100) +#define CSR_HW_REV_TYPE_105 (0x0000110) +#define CSR_HW_REV_TYPE_135 (0x0000120) +#define CSR_HW_REV_TYPE_7265D (0x0000210) +#define CSR_HW_REV_TYPE_NONE (0x00001F0) /* EEPROM REG */ #define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 6ced8549eb3a..3ee8e3848876 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -499,6 +499,7 @@ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev) {} static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; int ret; @@ -507,6 +508,25 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); +#if IS_ENABLED(CONFIG_IWLMVM) + /* + * special-case 7265D, it has the same PCI IDs. + * + * Note that because we already pass the cfg to the transport above, + * all the parameters that the transport uses must, until that is + * changed, be identical to the ones in the 7265D configuration. + */ + if (cfg == &iwl7265_2ac_cfg) + cfg_7265d = &iwl7265d_2ac_cfg; + else if (cfg == &iwl7265_2n_cfg) + cfg_7265d = &iwl7265d_2n_cfg; + else if (cfg == &iwl7265_n_cfg) + cfg_7265d = &iwl7265d_n_cfg; + if (cfg_7265d && + (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) + cfg = cfg_7265d; +#endif + pci_set_drvdata(pdev, iwl_trans); trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); -- GitLab From c8660dd5e910a8c66c13ef99efd3c0ee88845ba5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 17 Nov 2014 15:06:52 +0100 Subject: [PATCH 5903/9457] iwlwifi: mvm: use unsigned for ssid_bitmap The ssid_bitmap should be unsigned, though it doesn't matter much as the high bits aren't used. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/scan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 54303d935c57..b6719b64ff6d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1324,7 +1324,7 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, struct iwl_scan_probe_req *preq; struct iwl_mvm_scan_params params = {}; u32 flags; - int ssid_bitmap = 0; + u32 ssid_bitmap = 0; int ret, i; lockdep_assert_held(&mvm->mutex); @@ -1763,7 +1763,7 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvm->fw->ucode_capa.n_scan_channels; struct iwl_mvm_scan_params params = {}; u32 uid, flags; - int ssid_bitmap = 0; + u32 ssid_bitmap = 0; int ret, i, uid_idx; lockdep_assert_held(&mvm->mutex); @@ -1853,7 +1853,7 @@ int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvm->fw->ucode_capa.n_scan_channels; struct iwl_mvm_scan_params params = {}; u32 uid, flags; - int ssid_bitmap = 0; + u32 ssid_bitmap = 0; int ret, uid_idx; lockdep_assert_held(&mvm->mutex); -- GitLab From 2992a324e35e49f3ea950938c91b6b2108bbbf4c Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 10 Nov 2014 11:16:53 +0200 Subject: [PATCH 5904/9457] iwlwifi: mvm: remove warning on unknown scan complete Remove warning on scan complete with unknown ID, since this scan could be already cleared in abort flow. Signed-off-by: David Spinadel Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/scan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index b6719b64ff6d..e5294d01181e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1951,8 +1951,10 @@ int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, bool sched = !!(uid & IWL_UMAC_SCAN_UID_SCHED_SCAN); int uid_idx = iwl_mvm_find_scan_uid(mvm, uid); - if (WARN(uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS, - "Scan notification for uknown scan ID\n")) + /* + * Scan uid may be set to zero in case of scan abort request from above. + */ + if (uid_idx >= IWL_MVM_MAX_SIMULTANEOUS_SCANS) return 0; IWL_DEBUG_SCAN(mvm, -- GitLab From bf5da87f60a920599c46382d95b8e9c4ef8da37e Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Sun, 16 Nov 2014 10:25:12 +0200 Subject: [PATCH 5905/9457] iwlwifi: mvm: add remove flow for AUX ROC time events Add a flow that handles the requests to cancel the roc time event, that has been triggered via the aux framework. The roc for bss is different than the roc for p2p devices, and is done via the aux framework using the aux queue, thus requires a different flow to cancel the time event. Signed-off-by: Matti Gottlieb Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.c | 107 ++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/time-event.h | 4 +- 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index d37d5a8b383e..f3379d76f3db 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2652,7 +2652,7 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(mvm, "enter\n"); mutex_lock(&mvm->mutex); - iwl_mvm_stop_p2p_roc(mvm); + iwl_mvm_stop_roc(mvm); mutex_unlock(&mvm->mutex); IWL_DEBUG_MAC80211(mvm, "leave\n"); diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 6dfad230be5e..8cf246b695c4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -549,18 +549,11 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, } } -/* - * Explicit request to remove a time event. The removal of a time event needs to - * be synchronized with the flow of a time event's end notification, which also - * removes the time event from the op mode data structures. - */ -void iwl_mvm_remove_time_event(struct iwl_mvm *mvm, - struct iwl_mvm_vif *mvmvif, - struct iwl_mvm_time_event_data *te_data) +static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, + struct iwl_mvm_time_event_data *te_data, + u32 *uid) { - struct iwl_time_event_cmd time_cmd = {}; - u32 id, uid; - int ret; + u32 id; /* * It is possible that by the time we got to this point the time @@ -569,7 +562,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm, spin_lock_bh(&mvm->time_event_lock); /* Save time event uid before clearing its data */ - uid = te_data->uid; + *uid = te_data->uid; id = te_data->id; /* @@ -584,10 +577,59 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm, * send a removal command. */ if (id == TE_MAX) { - IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", uid); - return; + IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid); + return false; } + return true; +} + +/* + * Explicit request to remove a aux roc time event. The removal of a time + * event needs to be synchronized with the flow of a time event's end + * notification, which also removes the time event from the op mode + * data structures. + */ +static void iwl_mvm_remove_aux_roc_te(struct iwl_mvm *mvm, + struct iwl_mvm_vif *mvmvif, + struct iwl_mvm_time_event_data *te_data) +{ + struct iwl_hs20_roc_req aux_cmd = {}; + u32 uid; + int ret; + + if (!__iwl_mvm_remove_time_event(mvm, te_data, &uid)) + return; + + aux_cmd.event_unique_id = cpu_to_le32(uid); + aux_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE); + aux_cmd.id_and_color = + cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); + IWL_DEBUG_TE(mvm, "Removing BSS AUX ROC TE 0x%x\n", + le32_to_cpu(aux_cmd.event_unique_id)); + ret = iwl_mvm_send_cmd_pdu(mvm, HOT_SPOT_CMD, 0, + sizeof(aux_cmd), &aux_cmd); + + if (WARN_ON(ret)) + return; +} + +/* + * Explicit request to remove a time event. The removal of a time event needs to + * be synchronized with the flow of a time event's end notification, which also + * removes the time event from the op mode data structures. + */ +void iwl_mvm_remove_time_event(struct iwl_mvm *mvm, + struct iwl_mvm_vif *mvmvif, + struct iwl_mvm_time_event_data *te_data) +{ + struct iwl_time_event_cmd time_cmd = {}; + u32 uid; + int ret; + + if (!__iwl_mvm_remove_time_event(mvm, te_data, &uid)) + return; + /* When we remove a TE, the UID is to be set in the id field */ time_cmd.id = cpu_to_le32(uid); time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE); @@ -666,13 +708,17 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); } -void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm) +void iwl_mvm_stop_roc(struct iwl_mvm *mvm) { struct iwl_mvm_vif *mvmvif; struct iwl_mvm_time_event_data *te_data; + bool is_p2p = false; lockdep_assert_held(&mvm->mutex); + mvmvif = NULL; + spin_lock_bh(&mvm->time_event_lock); + /* * Iterate over the list of time events and find the time event that is * associated with a P2P_DEVICE interface. @@ -680,22 +726,41 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm) * event at any given time and this time event coresponds to a ROC * request */ - mvmvif = NULL; - spin_lock_bh(&mvm->time_event_lock); list_for_each_entry(te_data, &mvm->time_event_list, list) { - if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { + if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE && + te_data->running) { mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); - break; + is_p2p = true; + goto remove_te; + } + } + + /* + * Iterate over the list of aux roc time events and find the time + * event that is associated with a BSS interface. + * This assumes that a BSS interface can have only a single time + * event at any given time and this time event coresponds to a ROC + * request + */ + list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { + if (te_data->running) { + mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); + goto remove_te; } } + +remove_te: spin_unlock_bh(&mvm->time_event_lock); if (!mvmvif) { - IWL_WARN(mvm, "P2P_DEVICE no remain on channel event\n"); + IWL_WARN(mvm, "No remain on channel event\n"); return; } - iwl_mvm_remove_time_event(mvm, mvmvif, te_data); + if (is_p2p) + iwl_mvm_remove_time_event(mvm, mvmvif, te_data); + else + iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data); iwl_mvm_roc_finished(mvm); } diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index b350e47e19da..6f6b35db3ab8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -182,14 +182,14 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, int duration, enum ieee80211_roc_type type); /** - * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity + * iwl_mvm_stop_roc - stop remain on channel functionality * @mvm: the mvm component * * This function can be used to cancel an ongoing ROC session. * The function is async, it will instruct the FW to stop serving the ROC * session, but will not wait for the actual stopping of the session. */ -void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm); +void iwl_mvm_stop_roc(struct iwl_mvm *mvm); /** * iwl_mvm_remove_time_event - general function to clean up of time event -- GitLab From 2f6319d1cf5df2bc01637496296d755e3312c030 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Nov 2014 23:39:56 +0100 Subject: [PATCH 5906/9457] iwlwifi: mvm: refactor key add/remove functions Refactor the key add/remove functions to be able to reuse parts of them later for RX WEP keys, which need to be uploaded twice. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/sta.c | 143 ++++++++++++++----------- 1 file changed, 79 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 74a7c9138ce9..f94be3cdeff6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -1072,8 +1072,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvm_sta, struct ieee80211_key_conf *keyconf, - u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, - u32 cmd_flags) + u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags) { struct iwl_mvm_add_sta_key_cmd cmd = {}; __le16 key_flags; @@ -1081,6 +1080,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, u32 status; u16 keyidx; int i; + u8 sta_id = mvm_sta->sta_id; keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & STA_KEY_FLG_KEYID_MSK; @@ -1196,17 +1196,83 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm, return NULL; } +static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *keyconf) +{ + struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); + int ret; + const u8 *addr; + struct ieee80211_key_seq seq; + u16 p1k[5]; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_TKIP: + addr = iwl_mvm_get_mac_addr(mvm, vif, sta); + /* get phase 1 key from mac80211 */ + ieee80211_get_key_rx_seq(keyconf, 0, &seq); + ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + seq.tkip.iv32, p1k, 0); + break; + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + 0, NULL, 0); + break; + default: + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + 0, NULL, 0); + } + + return ret; +} + +static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, + struct ieee80211_key_conf *keyconf) +{ + struct iwl_mvm_add_sta_key_cmd cmd = {}; + __le16 key_flags; + int ret; + u32 status; + + key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & + STA_KEY_FLG_KEYID_MSK); + key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); + key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); + + if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + key_flags |= cpu_to_le16(STA_KEY_MULTICAST); + + cmd.key_flags = key_flags; + cmd.key_offset = keyconf->hw_key_idx; + cmd.sta_id = sta_id; + + status = ADD_STA_SUCCESS; + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd), + &cmd, &status); + + switch (status) { + case ADD_STA_SUCCESS: + IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n"); + break; + default: + ret = -EIO; + IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n"); + break; + } + + return ret; +} + int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *keyconf, bool have_key_offset) { - struct iwl_mvm_sta *mvm_sta; + u8 sta_id; int ret; - u8 *addr, sta_id; - struct ieee80211_key_seq seq; - u16 p1k[5]; lockdep_assert_held(&mvm->mutex); @@ -1235,8 +1301,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, } } - mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv; - if (WARN_ON_ONCE(mvm_sta->vif != vif)) + if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) return -EINVAL; if (!have_key_offset) { @@ -1250,24 +1315,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, return -ENOSPC; } - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - addr = iwl_mvm_get_mac_addr(mvm, vif, sta); - /* get phase 1 key from mac80211 */ - ieee80211_get_key_rx_seq(keyconf, 0, &seq); - ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, - seq.tkip.iv32, p1k, 0); - break; - case WLAN_CIPHER_SUITE_CCMP: - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, - 0, NULL, 0); - break; - default: - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, - sta_id, 0, NULL, 0); - } - + ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf); if (ret) __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); @@ -1283,11 +1331,6 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct ieee80211_key_conf *keyconf) { - struct iwl_mvm_sta *mvm_sta; - struct iwl_mvm_add_sta_key_cmd cmd = {}; - __le16 key_flags; - int ret; - u32 status; u8 sta_id; lockdep_assert_held(&mvm->mutex); @@ -1301,8 +1344,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC) return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); - ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); - if (!ret) { + if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { IWL_ERR(mvm, "offset %d not used in fw key table.\n", keyconf->hw_key_idx); return -ENOENT; @@ -1328,37 +1370,10 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, } } - mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv; - if (WARN_ON_ONCE(mvm_sta->vif != vif)) + if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) return -EINVAL; - key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & - STA_KEY_FLG_KEYID_MSK); - key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); - key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); - - if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - key_flags |= cpu_to_le16(STA_KEY_MULTICAST); - - cmd.key_flags = key_flags; - cmd.key_offset = keyconf->hw_key_idx; - cmd.sta_id = sta_id; - - status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd), - &cmd, &status); - - switch (status) { - case ADD_STA_SUCCESS: - IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n"); - break; - default: - ret = -EIO; - IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n"); - break; - } - - return ret; + return __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf); } void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, @@ -1383,8 +1398,8 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, } } - mvm_sta = (void *)sta->drv_priv; - iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id, + mvm_sta = iwl_mvm_sta_from_mac80211(sta); + iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, iv32, phase1key, CMD_ASYNC); rcu_read_unlock(); } -- GitLab From ba3943b094434ac8e2074bd159c2734e8cc47511 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Nov 2014 23:54:48 +0100 Subject: [PATCH 5907/9457] iwlwifi: mvm: add WEP RX hardware offload support In the original driver, we decided to not implement WEP RX hardware offload because of a quirk with the firmware API - it allows setting global WEP keys that then get used for all virtual interfaces, which is clearly wrong if more than one exists, and it allows setting per- station keys but then separates multicast and unicast keys. In order to implement WEP RX hardware offload, work around these limitations by uploading each WEP key twice, once as multicast and once as unicast, but point them both to the same key slot (offset) and use the same key material so the slot overwrite on the second upload doesn't actually change anything. Upon removal, also remove the key twice so the station no longer references it. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 14 +++-- drivers/net/wireless/iwlwifi/mvm/sta.c | 64 +++++++++++++++++---- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index f3379d76f3db..08976c3a4dfc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2330,12 +2330,16 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - /* - * Support for TX only, at least for now, so accept - * the key and do nothing else. Then mac80211 will - * pass it for TX but we don't have to use it for RX. + /* For non-client mode, only use WEP keys for TX as we probably + * don't have a station yet anyway and would then have to keep + * track of the keys, linking them to each of the clients/peers + * as they appear. For now, don't do that, for performance WEP + * offload doesn't really matter much, but we need it for some + * other offload features in client mode. */ - return 0; + if (vif->type != NL80211_IFTYPE_STATION) + return 0; + break; default: /* currently FW supports only one optional cipher scheme */ if (hw->n_cipher_schemes && diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index f94be3cdeff6..0eb850542af4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -1071,7 +1071,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvm_sta, - struct ieee80211_key_conf *keyconf, + struct ieee80211_key_conf *keyconf, bool mcast, u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags) { struct iwl_mvm_add_sta_key_cmd cmd = {}; @@ -1099,12 +1099,18 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, key_flags |= cpu_to_le16(STA_KEY_FLG_CCM); memcpy(cmd.key, keyconf->key, keyconf->keylen); break; + case WLAN_CIPHER_SUITE_WEP104: + key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES); + case WLAN_CIPHER_SUITE_WEP40: + key_flags |= cpu_to_le16(STA_KEY_FLG_WEP); + memcpy(cmd.key + 3, keyconf->key, keyconf->keylen); + break; default: key_flags |= cpu_to_le16(STA_KEY_FLG_EXT); memcpy(cmd.key, keyconf->key, keyconf->keylen); } - if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + if (mcast) key_flags |= cpu_to_le16(STA_KEY_MULTICAST); cmd.key_offset = keyconf->hw_key_idx; @@ -1199,7 +1205,8 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm, static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *keyconf) + struct ieee80211_key_conf *keyconf, + bool mcast) { struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); int ret; @@ -1213,15 +1220,17 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, /* get phase 1 key from mac80211 */ ieee80211_get_key_rx_seq(keyconf, 0, &seq); ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k); - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, seq.tkip.iv32, p1k, 0); break; case WLAN_CIPHER_SUITE_CCMP: - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, 0, NULL, 0); break; default: - ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, 0, NULL, 0); } @@ -1229,7 +1238,8 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm, } static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, - struct ieee80211_key_conf *keyconf) + struct ieee80211_key_conf *keyconf, + bool mcast) { struct iwl_mvm_add_sta_key_cmd cmd = {}; __le16 key_flags; @@ -1241,7 +1251,7 @@ static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP); key_flags |= cpu_to_le16(STA_KEY_NOT_VALID); - if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + if (mcast) key_flags |= cpu_to_le16(STA_KEY_MULTICAST); cmd.key_flags = key_flags; @@ -1271,6 +1281,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, struct ieee80211_key_conf *keyconf, bool have_key_offset) { + bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); u8 sta_id; int ret; @@ -1315,9 +1326,26 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, return -ENOSPC; } - ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf); - if (ret) + ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, mcast); + if (ret) { __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); + goto end; + } + + /* + * For WEP, the same key is used for multicast and unicast. Upload it + * again, using the same key offset, and now pointing the other one + * to the same key slot (offset). + * If this fails, remove the original as well. + */ + if (keyconf->cipher == WLAN_CIPHER_SUITE_WEP40 || + keyconf->cipher == WLAN_CIPHER_SUITE_WEP104) { + ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, !mcast); + if (ret) { + __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table); + __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); + } + } end: IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n", @@ -1331,7 +1359,9 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct ieee80211_key_conf *keyconf) { + bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); u8 sta_id; + int ret; lockdep_assert_held(&mvm->mutex); @@ -1373,7 +1403,16 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif)) return -EINVAL; - return __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf); + ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast); + if (ret) + return ret; + + /* delete WEP key twice to get rid of (now useless) offset */ + if (keyconf->cipher == WLAN_CIPHER_SUITE_WEP40 || + keyconf->cipher == WLAN_CIPHER_SUITE_WEP104) + ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, !mcast); + + return ret; } void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, @@ -1384,6 +1423,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, { struct iwl_mvm_sta *mvm_sta; u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); + bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE); if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) return; @@ -1399,7 +1439,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, } mvm_sta = iwl_mvm_sta_from_mac80211(sta); - iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, + iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, mcast, iv32, phase1key, CMD_ASYNC); rcu_read_unlock(); } -- GitLab From d0963b5d31cabf98afba1599c73324ce036cd081 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Nov 2014 16:45:12 +0100 Subject: [PATCH 5908/9457] iwlwifi: build mac80211 rx_status in place Instead of building the rx_status on the stack and then copying it to the skb, allocate the skb a bit earlier and then build the rx_status in place. Signed-off-by: Johannes Berg Reviewed-by: IdoX Yariv Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rx.c | 99 +++++++++++++-------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 93d5b692cf92..57052e67ceb8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -96,22 +96,13 @@ int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, * Adds the rxb to a new skb and give it to mac80211 */ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, + struct sk_buff *skb, struct ieee80211_hdr *hdr, u16 len, u32 ampdu_status, - struct iwl_rx_cmd_buffer *rxb, - struct ieee80211_rx_status *stats) + struct iwl_rx_cmd_buffer *rxb) { - struct sk_buff *skb; unsigned int hdrlen, fraglen; - /* Dont use dev_alloc_skb(), we'll have enough headroom once - * ieee80211_hdr pulled. - */ - skb = alloc_skb(128, GFP_ATOMIC); - if (!skb) { - IWL_ERR(mvm, "alloc_skb failed\n"); - return; - } /* If frame is small enough to fit in skb->head, pull it completely. * If not, only pull ieee80211_hdr so that splice() or TCP coalesce * are more efficient. @@ -129,8 +120,6 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, fraglen, rxb->truesize); } - memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); - ieee80211_rx(mvm->hw, skb); } @@ -242,11 +231,12 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct ieee80211_hdr *hdr; - struct ieee80211_rx_status rx_status = {}; + struct ieee80211_rx_status *rx_status; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_phy_info *phy_info; struct iwl_rx_mpdu_res_start *rx_res; struct ieee80211_sta *sta; + struct sk_buff *skb; u32 len; u32 ampdu_status; u32 rate_n_flags; @@ -259,20 +249,31 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, rx_pkt_status = le32_to_cpup((__le32 *) (pkt->data + sizeof(*rx_res) + len)); - memset(&rx_status, 0, sizeof(rx_status)); + /* Dont use dev_alloc_skb(), we'll have enough headroom once + * ieee80211_hdr pulled. + */ + skb = alloc_skb(128, GFP_ATOMIC); + if (!skb) { + IWL_ERR(mvm, "alloc_skb failed\n"); + return 0; + } + + rx_status = IEEE80211_SKB_RXCB(skb); /* * drop the packet if it has failed being decrypted by HW */ - if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) { + if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, rx_status, rx_pkt_status)) { IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n", rx_pkt_status); + kfree_skb(skb); return 0; } if ((unlikely(phy_info->cfg_phy_cnt > 20))) { IWL_DEBUG_DROP(mvm, "dsp size out of range [0,20]: %d\n", phy_info->cfg_phy_cnt); + kfree_skb(skb); return 0; } @@ -283,31 +284,31 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) || !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) { IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status); - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; } /* This will be used in several places later */ rate_n_flags = le32_to_cpu(phy_info->rate_n_flags); /* rx_status carries information about the packet to mac80211 */ - rx_status.mactime = le64_to_cpu(phy_info->timestamp); - rx_status.device_timestamp = le32_to_cpu(phy_info->system_timestamp); - rx_status.band = + rx_status->mactime = le64_to_cpu(phy_info->timestamp); + rx_status->device_timestamp = le32_to_cpu(phy_info->system_timestamp); + rx_status->band = (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - rx_status.freq = + rx_status->freq = ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel), - rx_status.band); + rx_status->band); /* * TSF as indicated by the fw is at INA time, but mac80211 expects the * TSF at the beginning of the MPDU. */ - /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ + /*rx_status->flag |= RX_FLAG_MACTIME_MPDU;*/ - iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status); + iwl_mvm_get_signal_strength(mvm, phy_info, rx_status); - IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, - (unsigned long long)rx_status.mactime); + IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status->signal, + (unsigned long long)rx_status->mactime); rcu_read_lock(); /* @@ -326,15 +327,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, if (sta) { struct iwl_mvm_sta *mvmsta; mvmsta = iwl_mvm_sta_from_mac80211(sta); - rs_update_last_rssi(mvm, &mvmsta->lq_sta, - &rx_status); + rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status); } rcu_read_unlock(); /* set the preamble flag if appropriate */ if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE)) - rx_status.flag |= RX_FLAG_SHORTPRE; + rx_status->flag |= RX_FLAG_SHORTPRE; if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) { /* @@ -342,8 +342,8 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, * together since we get a single PHY response * from the firmware for all of them */ - rx_status.flag |= RX_FLAG_AMPDU_DETAILS; - rx_status.ampdu_reference = mvm->ampdu_ref; + rx_status->flag |= RX_FLAG_AMPDU_DETAILS; + rx_status->ampdu_reference = mvm->ampdu_ref; } /* Set up the HT phy flags */ @@ -351,50 +351,49 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: - rx_status.flag |= RX_FLAG_40MHZ; + rx_status->flag |= RX_FLAG_40MHZ; break; case RATE_MCS_CHAN_WIDTH_80: - rx_status.vht_flag |= RX_VHT_FLAG_80MHZ; + rx_status->vht_flag |= RX_VHT_FLAG_80MHZ; break; case RATE_MCS_CHAN_WIDTH_160: - rx_status.vht_flag |= RX_VHT_FLAG_160MHZ; + rx_status->vht_flag |= RX_VHT_FLAG_160MHZ; break; } if (rate_n_flags & RATE_MCS_SGI_MSK) - rx_status.flag |= RX_FLAG_SHORT_GI; + rx_status->flag |= RX_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) - rx_status.flag |= RX_FLAG_HT_GF; + rx_status->flag |= RX_FLAG_HT_GF; if (rate_n_flags & RATE_MCS_LDPC_MSK) - rx_status.flag |= RX_FLAG_LDPC; + rx_status->flag |= RX_FLAG_LDPC; if (rate_n_flags & RATE_MCS_HT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_HT_STBC_MSK) >> RATE_MCS_STBC_POS; - rx_status.flag |= RX_FLAG_HT; - rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; - rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT; + rx_status->flag |= RX_FLAG_HT; + rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT; } else if (rate_n_flags & RATE_MCS_VHT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_VHT_STBC_MSK) >> RATE_MCS_STBC_POS; - rx_status.vht_nss = + rx_status->vht_nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; - rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; - rx_status.flag |= RX_FLAG_VHT; - rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT; + rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + rx_status->flag |= RX_FLAG_VHT; + rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) - rx_status.vht_flag |= RX_VHT_FLAG_BF; + rx_status->vht_flag |= RX_VHT_FLAG_BF; } else { - rx_status.rate_idx = + rx_status->rate_idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, - rx_status.band); + rx_status->band); } #ifdef CONFIG_IWLWIFI_DEBUGFS iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags, - rx_status.flag & RX_FLAG_AMPDU_DETAILS); + rx_status->flag & RX_FLAG_AMPDU_DETAILS); #endif - iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status, - rxb, &rx_status); + iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, rxb); return 0; } -- GitLab From eb96ccb138fccdedd76c773e476e4a6ce4b3c05c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Nov 2014 17:12:05 +0100 Subject: [PATCH 5909/9457] iwlwifi: mvm: pull crypto header into skb->head When we pre-populate the skb->head for the stack, we only pull in the 802.11 header (assuming the packet isn't short enough to be in there completely.) This is fine, but in many cases we'll pull in the crypto headers pretty much immediately afterwards, so to avoid that pull in the crypto header early. Signed-off-by: Johannes Berg Reviewed-by: IdoX Yariv Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rx.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 57052e67ceb8..69fa765e29b5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -98,16 +98,16 @@ int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_hdr *hdr, u16 len, - u32 ampdu_status, + u32 ampdu_status, u8 crypt_len, struct iwl_rx_cmd_buffer *rxb) { unsigned int hdrlen, fraglen; /* If frame is small enough to fit in skb->head, pull it completely. - * If not, only pull ieee80211_hdr so that splice() or TCP coalesce - * are more efficient. + * If not, only pull ieee80211_hdr (including crypto if present) so + * that splice() or TCP coalesce are more efficient. */ - hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); + hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr) + crypt_len; memcpy(skb_put(skb, hdrlen), hdr, hdrlen); fraglen = len - hdrlen; @@ -174,7 +174,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, struct ieee80211_rx_status *stats, - u32 rx_pkt_status) + u32 rx_pkt_status, + u8 *crypt_len) { if (!ieee80211_has_protected(hdr->frame_control) || (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) == @@ -194,12 +195,14 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, stats->flag |= RX_FLAG_DECRYPTED; IWL_DEBUG_WEP(mvm, "hw decrypted CCMP successfully\n"); + *crypt_len = IEEE80211_CCMP_HDR_LEN; return 0; case RX_MPDU_RES_STATUS_SEC_TKIP_ENC: /* Don't drop the frame and decrypt it in SW */ if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK)) return 0; + *crypt_len = IEEE80211_TKIP_IV_LEN; /* fall through if TTAK OK */ case RX_MPDU_RES_STATUS_SEC_WEP_ENC: @@ -207,6 +210,9 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, return -1; stats->flag |= RX_FLAG_DECRYPTED; + if ((rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) == + RX_MPDU_RES_STATUS_SEC_WEP_ENC) + *crypt_len = IEEE80211_WEP_IV_LEN; return 0; case RX_MPDU_RES_STATUS_SEC_EXT_ENC: @@ -241,6 +247,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, u32 ampdu_status; u32 rate_n_flags; u32 rx_pkt_status; + u8 crypt_len = 0; phy_info = &mvm->last_phy_info; rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; @@ -263,7 +270,8 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, /* * drop the packet if it has failed being decrypted by HW */ - if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, rx_status, rx_pkt_status)) { + if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, rx_status, rx_pkt_status, + &crypt_len)) { IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n", rx_pkt_status); kfree_skb(skb); @@ -393,7 +401,8 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags, rx_status->flag & RX_FLAG_AMPDU_DETAILS); #endif - iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, rxb); + iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, + crypt_len, rxb); return 0; } -- GitLab From 3771a89022bc4aa56bca5e7d3f34eee46ebedfdb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 13 Nov 2014 11:06:43 +0100 Subject: [PATCH 5910/9457] iwlwifi: mvm: pull SNAP header into skb->head When we pre-populate the skb->head for the stack, we only pull in the 802.11 header including crypto (assuming the packet isn't short enough to be in there completely.) This is fine, but in ieee80211_data_to_8023() we later unconditionally pull 8 more bytes for the SNAP header and ethertype field (except for mesh or 4-addr, where it's even more, but we don't care as much about them). Avoid the additional later pull by pulling in those 8 bytes here. Signed-off-by: Johannes Berg Reviewed-by: IdoX Yariv Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 69fa765e29b5..94b6e7297a1e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -104,10 +104,19 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, unsigned int hdrlen, fraglen; /* If frame is small enough to fit in skb->head, pull it completely. - * If not, only pull ieee80211_hdr (including crypto if present) so - * that splice() or TCP coalesce are more efficient. + * If not, only pull ieee80211_hdr (including crypto if present, and + * an additional 8 bytes for SNAP/ethertype, see below) so that + * splice() or TCP coalesce are more efficient. + * + * Since, in addition, ieee80211_data_to_8023() always pull in at + * least 8 bytes (possibly more for mesh) we can do the same here + * to save the cost of doing it later. That still doesn't pull in + * the actual IP header since the typical case has a SNAP header. + * If the latter changes (there are efforts in the standards group + * to do so) we should revisit this and ieee80211_data_to_8023(). */ - hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr) + crypt_len; + hdrlen = (len <= skb_tailroom(skb)) ? len : + sizeof(*hdr) + crypt_len + 8; memcpy(skb_put(skb, hdrlen), hdr, hdrlen); fraglen = len - hdrlen; -- GitLab From d8f1c515708947cbe59973396fa2636099a62452 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 11 May 2014 18:13:04 +0300 Subject: [PATCH 5911/9457] iwlwifi: mvm: declare TDLS support The driver/FW combination now support TDLS. Check the FW support with the TLV bit. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-debug.h | 3 ++- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 0a70bcd241f5..684254553558 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -143,7 +143,7 @@ do { \ #define IWL_DL_INFO 0x00000001 #define IWL_DL_MAC80211 0x00000002 #define IWL_DL_HCMD 0x00000004 -#define IWL_DL_STATE 0x00000008 +#define IWL_DL_TDLS 0x00000008 /* 0x000000F0 - 0x00000010 */ #define IWL_DL_QUOTA 0x00000010 #define IWL_DL_TE 0x00000020 @@ -180,6 +180,7 @@ do { \ #define IWL_DL_TX_QUEUES 0x80000000 #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_TDLS(p, f, a...) IWL_DEBUG(p, IWL_DL_TDLS, f, ## a) #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) #define IWL_DEBUG_EXTERNAL(p, f, a...) IWL_DEBUG(p, IWL_DL_EXTERNAL, f, ## a) #define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 133022a7bf6f..78d3e5f5fff9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -146,6 +146,7 @@ enum iwl_ucode_tlv_api { * enum iwl_ucode_tlv_capa - ucode capabilities * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan. + * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current * tx power value into TPC Report action frame and Link Measurement Report * action frame @@ -160,6 +161,7 @@ enum iwl_ucode_tlv_api { enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2), + IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6), IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8), IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9), IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10), diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 08976c3a4dfc..801abcfbaa7f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -490,6 +490,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) if (ret) return ret; + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_TDLS_SUPPORT) { + IWL_DEBUG_TDLS(mvm, "TDLS supported\n"); + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + } + ret = ieee80211_register_hw(mvm->hw); if (ret) iwl_mvm_leds_exit(mvm); -- GitLab From 77c5d7eff79066b28d92f1b01fa4b6ee7106b923 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 11 Sep 2014 13:10:08 +0300 Subject: [PATCH 5912/9457] iwlwifi: mvm: add TDLS channel switch FW APIs Add a channel-switch command and a switch-start notification. Also add a FW TLV bit indicating TDLS channel switching support. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 + drivers/net/wireless/iwlwifi/mvm/fw-api.h | 83 +++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 + 3 files changed, 87 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 78d3e5f5fff9..a94d244459d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -157,6 +157,7 @@ enum iwl_ucode_tlv_api { * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA), * which also implies support for the scheduler configuration command + * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching */ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), @@ -167,6 +168,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10), IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11), IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12), + IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13), }; /* The default calibrate table size if not specified by firmware file */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 1a67788e55f5..a71fad2ed5d6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -128,6 +128,10 @@ enum { /* global key */ WEP_KEY = 0x20, + /* TDLS */ + TDLS_CHANNEL_SWITCH_CMD = 0x27, + TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa, + /* MAC and Binding commands */ MAC_CONTEXT_CMD = 0x28, TIME_EVENT_CMD = 0x29, /* both CMD and response */ @@ -1717,4 +1721,83 @@ struct iwl_scd_txq_cfg_cmd { u8 flags; } __packed; +/*********************************** + * TDLS API + ***********************************/ + +/* Type of TDLS request */ +enum iwl_tdls_channel_switch_type { + TDLS_SEND_CHAN_SW_REQ = 0, + TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH, + TDLS_MOVE_CH, +}; /* TDLS_STA_CHANNEL_SWITCH_CMD_TYPE_API_E_VER_1 */ + +/** + * Switch timing sub-element in a TDLS channel-switch command + * @frame_timestamp: GP2 timestamp of channel-switch request/response packet + * received from peer + * @max_offchan_duration: What amount of microseconds out of a DTIM is given + * to the TDLS off-channel communication. For instance if the DTIM is + * 200TU and the TDLS peer is to be given 25% of the time, the value + * given will be 50TU, or 50 * 1024 if translated into microseconds. + * @switch_time: switch time the peer sent in its channel switch timing IE + * @switch_timout: switch timeout the peer sent in its channel switch timing IE + */ +struct iwl_tdls_channel_switch_timing { + __le32 frame_timestamp; /* GP2 time of peer packet Rx */ + __le32 max_offchan_duration; /* given in micro-seconds */ + __le32 switch_time; /* given in micro-seconds */ + __le32 switch_timeout; /* given in micro-seconds */ +} __packed; /* TDLS_STA_CHANNEL_SWITCH_TIMING_DATA_API_S_VER_1 */ + +#define IWL_TDLS_CH_SW_FRAME_MAX_SIZE 200 + +/** + * TDLS channel switch frame template + * + * A template representing a TDLS channel-switch request or response frame + * + * @switch_time_offset: offset to the channel switch timing IE in the template + * @tx_cmd: Tx parameters for the frame + * @data: frame data + */ +struct iwl_tdls_channel_switch_frame { + __le32 switch_time_offset; + struct iwl_tx_cmd tx_cmd; + u8 data[IWL_TDLS_CH_SW_FRAME_MAX_SIZE]; +} __packed; /* TDLS_STA_CHANNEL_SWITCH_FRAME_API_S_VER_1 */ + +/** + * TDLS channel switch command + * + * The command is sent to initiate a channel switch and also in response to + * incoming TDLS channel-switch request/response packets from remote peers. + * + * @switch_type: see &enum iwl_tdls_channel_switch_type + * @peer_sta_id: station id of TDLS peer + * @ci: channel we switch to + * @timing: timing related data for command + * @frame: channel-switch request/response template, depending to switch_type + */ +struct iwl_tdls_channel_switch_cmd { + u8 switch_type; + __le32 peer_sta_id; + struct iwl_fw_channel_info ci; + struct iwl_tdls_channel_switch_timing timing; + struct iwl_tdls_channel_switch_frame frame; +} __packed; /* TDLS_STA_CHANNEL_SWITCH_CMD_API_S_VER_1 */ + +/** + * TDLS channel switch start notification + * + * @status: non-zero on success + * @offchannel_duration: duration given in microseconds + * @sta_id: peer currently performing the channel-switch with + */ +struct iwl_tdls_channel_switch_notif { + __le32 status; + __le32 offchannel_duration; + __le32 sta_id; +} __packed; /* TDLS_STA_CHANNEL_SWITCH_NTFY_API_S_VER_1 */ + #endif /* __fw_api_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index b022fc097e78..8ee7362de289 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -352,6 +352,8 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(SCAN_REQ_UMAC), CMD(SCAN_ABORT_UMAC), CMD(SCAN_COMPLETE_UMAC), + CMD(TDLS_CHANNEL_SWITCH_CMD), + CMD(TDLS_CHANNEL_SWITCH_NOTIFICATION), }; #undef CMD -- GitLab From 307e47235a103191e9bf83cdeb8e50c713feae56 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 15 Sep 2014 18:48:59 +0300 Subject: [PATCH 5913/9457] iwlwifi: mvm: configure TDLS peers to FW Send a dedicated TDLS_CONFIG command when a TDLS peer joins/leaves. The fields for the command are mostly place-holders, as most of the FW functionality is not implemented. In the future the dedicated FW TID will be used for channel-switching and buffer-sta functionality. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 63 ++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 7 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 1 + drivers/net/wireless/iwlwifi/mvm/tdls.c | 80 +++++++++++++++++++++-- 4 files changed, 145 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index a71fad2ed5d6..0f3c07a54bfe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -131,6 +131,7 @@ enum { /* TDLS */ TDLS_CHANNEL_SWITCH_CMD = 0x27, TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa, + TDLS_CONFIG_CMD = 0xa7, /* MAC and Binding commands */ MAC_CONTEXT_CMD = 0x28, @@ -1800,4 +1801,66 @@ struct iwl_tdls_channel_switch_notif { __le32 sta_id; } __packed; /* TDLS_STA_CHANNEL_SWITCH_NTFY_API_S_VER_1 */ +/** + * TDLS station info + * + * @sta_id: station id of the TDLS peer + * @tx_to_peer_tid: TID reserved vs. the peer for FW based Tx + * @tx_to_peer_ssn: initial SSN the FW should use for Tx on its TID vs the peer + * @is_initiator: 1 if the peer is the TDLS link initiator, 0 otherwise + */ +struct iwl_tdls_sta_info { + u8 sta_id; + u8 tx_to_peer_tid; + __le16 tx_to_peer_ssn; + __le32 is_initiator; +} __packed; /* TDLS_STA_INFO_VER_1 */ + +/** + * TDLS basic config command + * + * @id_and_color: MAC id and color being configured + * @tdls_peer_count: amount of currently connected TDLS peers + * @tx_to_ap_tid: TID reverved vs. the AP for FW based Tx + * @tx_to_ap_ssn: initial SSN the FW should use for Tx on its TID vs. the AP + * @sta_info: per-station info. Only the first tdls_peer_count entries are set + * @pti_req_data_offset: offset of network-level data for the PTI template + * @pti_req_tx_cmd: Tx parameters for PTI request template + * @pti_req_template: PTI request template data + */ +struct iwl_tdls_config_cmd { + __le32 id_and_color; /* mac id and color */ + u8 tdls_peer_count; + u8 tx_to_ap_tid; + __le16 tx_to_ap_ssn; + struct iwl_tdls_sta_info sta_info[IWL_MVM_TDLS_STA_COUNT]; + + __le32 pti_req_data_offset; + struct iwl_tx_cmd pti_req_tx_cmd; + u8 pti_req_template[0]; +} __packed; /* TDLS_CONFIG_CMD_API_S_VER_1 */ + +/** + * TDLS per-station config information from FW + * + * @sta_id: station id of the TDLS peer + * @tx_to_peer_last_seq: last sequence number used by FW during FW-based Tx to + * the peer + */ +struct iwl_tdls_config_sta_info_res { + __le16 sta_id; + __le16 tx_to_peer_last_seq; +} __packed; /* TDLS_STA_INFO_RSP_VER_1 */ + +/** + * TDLS config information from FW + * + * @tx_to_ap_last_seq: last sequence number used by FW during FW-based Tx to AP + * @sta_info: per-station TDLS config information + */ +struct iwl_tdls_config_res { + __le32 tx_to_ap_last_seq; + struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT]; +} __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */ + #endif /* __fw_api_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index db52f65e4660..be0285d34fd4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1242,6 +1242,13 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool added_vif); /* TDLS */ + +/* + * We use TID 4 (VI) as a FW-used-only TID when TDLS connections are present. + * This TID is marked as used vs the AP and all connected TDLS peers. + */ +#define IWL_MVM_TDLS_FW_TID 4 + int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm); void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 8ee7362de289..9f9c7672b956 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -354,6 +354,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(SCAN_COMPLETE_UMAC), CMD(TDLS_CHANNEL_SWITCH_CMD), CMD(TDLS_CHANNEL_SWITCH_NOTIFICATION), + CMD(TDLS_CONFIG_CMD), }; #undef CMD diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c index 66c82df2d0a1..6dc381bc10f8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c @@ -113,17 +113,85 @@ int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif) return count; } +static void iwl_mvm_tdls_config(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct iwl_rx_packet *pkt; + struct iwl_tdls_config_res *resp; + struct iwl_tdls_config_cmd tdls_cfg_cmd = {}; + struct iwl_host_cmd cmd = { + .id = TDLS_CONFIG_CMD, + .flags = CMD_WANT_SKB, + .data = { &tdls_cfg_cmd, }, + .len = { sizeof(struct iwl_tdls_config_cmd), }, + }; + struct ieee80211_sta *sta; + int ret, i, cnt; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + lockdep_assert_held(&mvm->mutex); + + tdls_cfg_cmd.id_and_color = + cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); + tdls_cfg_cmd.tx_to_ap_tid = IWL_MVM_TDLS_FW_TID; + tdls_cfg_cmd.tx_to_ap_ssn = cpu_to_le16(0); /* not used for now */ + + /* for now the Tx cmd is empty and unused */ + + /* populate TDLS peer data */ + cnt = 0; + for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(sta) || !sta->tdls) + continue; + + tdls_cfg_cmd.sta_info[cnt].sta_id = i; + tdls_cfg_cmd.sta_info[cnt].tx_to_peer_tid = + IWL_MVM_TDLS_FW_TID; + tdls_cfg_cmd.sta_info[cnt].tx_to_peer_ssn = cpu_to_le16(0); + tdls_cfg_cmd.sta_info[cnt].is_initiator = + cpu_to_le32(sta->tdls_initiator ? 1 : 0); + + cnt++; + } + + tdls_cfg_cmd.tdls_peer_count = cnt; + IWL_DEBUG_TDLS(mvm, "send TDLS config to FW for %d peers\n", cnt); + + ret = iwl_mvm_send_cmd(mvm, &cmd); + if (WARN_ON_ONCE(ret)) + return; + + pkt = cmd.resp_pkt; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(mvm, "Bad return from TDLS_CONFIG_COMMAND (0x%08X)\n", + pkt->hdr.flags); + goto exit; + } + + if (WARN_ON_ONCE(iwl_rx_packet_payload_len(pkt) != sizeof(*resp))) + goto exit; + + /* we don't really care about the response at this point */ + +exit: + iwl_free_resp(&cmd); +} + void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool sta_added) { int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif); - /* - * Disable ps when the first TDLS sta is added and re-enable it - * when the last TDLS sta is removed - */ - if ((tdls_sta_cnt == 1 && sta_added) || - (tdls_sta_cnt == 0 && !sta_added)) + /* when the first peer joins, send a power update first */ + if (tdls_sta_cnt == 1 && sta_added) + iwl_mvm_power_update_mac(mvm); + + /* configure the FW with TDLS peer info */ + iwl_mvm_tdls_config(mvm, vif); + + /* when the last peer leaves, send a power update last */ + if (tdls_sta_cnt == 0 && !sta_added) iwl_mvm_power_update_mac(mvm); } -- GitLab From a74346d75de0f69f0843b4bfa8f95eccaf7c0edf Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 21 Sep 2014 19:07:30 +0300 Subject: [PATCH 5914/9457] iwlwifi: mvm: allow private per-STA TFD queues TDLS stations will have private queues, so consider them as well when allocating a new one. Consolidate the HW-queue iterating code into a single exported function, to be used by the TDLS code in the future. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 65 +++++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 + 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index b8ab4a108720..a1dc9b86c2d1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -83,11 +83,15 @@ struct iwl_mvm_mac_iface_iterator_data { struct ieee80211_vif *vif; unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; - u32 used_hw_queues; enum iwl_tsf_id preferred_tsf; bool found_vif; }; +struct iwl_mvm_hw_queues_iface_iterator_data { + struct ieee80211_vif *exclude_vif; + unsigned long used_hw_queues; +}; + static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, struct ieee80211_vif *vif) { @@ -213,6 +217,54 @@ u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif) return qmask; } +static void iwl_mvm_iface_hw_queues_iter(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_hw_queues_iface_iterator_data *data = _data; + + /* exclude the given vif */ + if (vif == data->exclude_vif) + return; + + data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif); +} + +static void iwl_mvm_mac_sta_hw_queues_iter(void *_data, + struct ieee80211_sta *sta) +{ + struct iwl_mvm_hw_queues_iface_iterator_data *data = _data; + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + + /* Mark the queues used by the sta */ + data->used_hw_queues |= mvmsta->tfd_queue_msk; +} + +unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, + struct ieee80211_vif *exclude_vif) +{ + struct iwl_mvm_hw_queues_iface_iterator_data data = { + .exclude_vif = exclude_vif, + .used_hw_queues = + BIT(IWL_MVM_OFFCHANNEL_QUEUE) | + BIT(mvm->aux_queue) | + BIT(IWL_MVM_CMD_QUEUE), + }; + + lockdep_assert_held(&mvm->mutex); + + /* mark all VIF used hw queues */ + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, + iwl_mvm_iface_hw_queues_iter, &data); + + /* don't assign the same hw queues as TDLS stations */ + ieee80211_iterate_stations_atomic(mvm->hw, + iwl_mvm_mac_sta_hw_queues_iter, + &data); + + return data.used_hw_queues; +} + static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { @@ -225,9 +277,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, return; } - /* Mark the queues used by the vif */ - data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(vif); - /* Mark MAC IDs as used by clearing the available bit, and * (below) mark TSFs as used if their existing use is not * compatible with the new interface type. @@ -274,10 +323,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, /* no preference yet */ .preferred_tsf = NUM_TSF_IDS, - .used_hw_queues = - BIT(IWL_MVM_OFFCHANNEL_QUEUE) | - BIT(mvm->aux_queue) | - BIT(IWL_MVM_CMD_QUEUE), .found_vif = false, }; u32 ac; @@ -316,6 +361,8 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, iwl_mvm_mac_iface_iterator, &data); + used_hw_queues = iwl_mvm_get_used_hw_queues(mvm, vif); + /* * In the case we're getting here during resume, it's similar to * firmware restart, and with RESUME_ALL the iterator will find @@ -365,8 +412,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, return 0; } - used_hw_queues = data.used_hw_queues; - /* Find available queues, and allocate them to the ACs */ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { u8 queue = find_first_zero_bit(&used_hw_queues, diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index be0285d34fd4..363be83e283e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -937,6 +937,8 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd); void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, + struct ieee80211_vif *exclude_vif); /* Bindings */ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); -- GitLab From cbd2ae2da6497b507f89849dffd972a474058480 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 14 Sep 2014 19:13:54 +0300 Subject: [PATCH 5915/9457] iwlwifi: mvm: disconnect TDLS peers on reconfig When TDLS peers are present the FW will send packets on a dedicated TID vs. the peer when performing TDLS channel-switches. The driver configures the TID on connection to the peer and the FW is responsible for maintaining the state of QoS seqno and PN/IV for encryption. If the FW asserts, the driver cannot correctly reconfigure the starting seqno/PN to the reloaded FW, thus forcing us to reconnect the peer. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 801abcfbaa7f..3883a86fb719 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -948,6 +948,12 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) /* allow transport/FW low power modes */ iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); + /* + * If we have TDLS peers, remove them. We don't know the last seqno/PN + * of packets the FW sent out, so we must reconnect. + */ + iwl_mvm_teardown_tdls_peers(mvm); + mutex_unlock(&mvm->mutex); } -- GitLab From a0f6bf2a5b018bcee93e4dece903589a8bb6062b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 21 Sep 2014 19:10:04 +0300 Subject: [PATCH 5916/9457] iwlwifi: mvm: use private TFD queues for TDLS stations When adding a TDLS station, allocate 4 new queues for it. Configure them to FW and enable them. On station removal, drain the queues if needed and disable them when empty. Make sure to flush all packets in the private queues of TDLS stations in the mac80211 flush() callback. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 28 ++++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/iwlwifi/mvm/sta.c | 94 ++++++++++++++++++++- drivers/net/wireless/iwlwifi/mvm/sta.h | 2 + drivers/net/wireless/iwlwifi/mvm/tx.c | 7 ++ 5 files changed, 121 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3883a86fb719..64e89e89140c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -876,6 +876,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) iwl_mvm_reset_phy_ctxts(mvm); memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained)); + memset(mvm->tfd_drained, 0, sizeof(mvm->tfd_drained)); memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); memset(&mvm->last_bt_notif_old, 0, sizeof(mvm->last_bt_notif_old)); memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd)); @@ -3113,31 +3114,44 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif; struct iwl_mvm_sta *mvmsta; + struct ieee80211_sta *sta; + int i; + u32 msk = 0; if (!vif || vif->type != NL80211_IFTYPE_STATION) return; mutex_lock(&mvm->mutex); mvmvif = iwl_mvm_vif_from_mac80211(vif); - mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id); - if (WARN_ON_ONCE(!mvmsta)) { - mutex_unlock(&mvm->mutex); - return; + /* flush the AP-station and all TDLS peers */ + for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], + lockdep_is_held(&mvm->mutex)); + if (IS_ERR_OR_NULL(sta)) + continue; + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + if (mvmsta->vif != vif) + continue; + + /* make sure only TDLS peers or the AP are flushed */ + WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls); + + msk |= mvmsta->tfd_queue_msk; } if (drop) { - if (iwl_mvm_flush_tx_path(mvm, mvmsta->tfd_queue_msk, true)) + if (iwl_mvm_flush_tx_path(mvm, msk, true)) IWL_ERR(mvm, "flush request fail\n"); mutex_unlock(&mvm->mutex); } else { - u32 tfd_queue_msk = mvmsta->tfd_queue_msk; mutex_unlock(&mvm->mutex); /* this can take a while, and we may need/want other operations * to succeed while doing this, so do it without the mutex held */ - iwl_trans_wait_tx_queue_empty(mvm->trans, tfd_queue_msk); + iwl_trans_wait_tx_queue_empty(mvm->trans, msk); } } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 363be83e283e..63d2d453f9dd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -578,6 +578,7 @@ struct iwl_mvm { struct work_struct sta_drained_wk; unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; atomic_t pending_frames[IWL_MVM_STATION_COUNT]; + u32 tfd_drained[IWL_MVM_STATION_COUNT]; u8 rx_ba_sessions; /* configured by mac80211 */ diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 0eb850542af4..15afa9a26c8f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -204,6 +204,56 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, return ret; } +static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm, + struct ieee80211_sta *sta) +{ + unsigned long used_hw_queues; + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + u32 ac; + + lockdep_assert_held(&mvm->mutex); + + used_hw_queues = iwl_mvm_get_used_hw_queues(mvm, NULL); + + /* Find available queues, and allocate them to the ACs */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + u8 queue = find_first_zero_bit(&used_hw_queues, + mvm->first_agg_queue); + + if (queue >= mvm->first_agg_queue) { + IWL_ERR(mvm, "Failed to allocate STA queue\n"); + return -EBUSY; + } + + __set_bit(queue, &used_hw_queues); + mvmsta->hw_queue[ac] = queue; + } + + /* Found a place for all queues - enable them */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + iwl_mvm_enable_ac_txq(mvm, mvmsta->hw_queue[ac], + iwl_mvm_ac_to_tx_fifo[ac]); + mvmsta->tfd_queue_msk |= BIT(mvmsta->hw_queue[ac]); + } + + return 0; +} + +static void iwl_mvm_tdls_sta_deinit(struct iwl_mvm *mvm, + struct ieee80211_sta *sta) +{ + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + unsigned long sta_msk; + int i; + + lockdep_assert_held(&mvm->mutex); + + /* disable the TDLS STA-specific queues */ + sta_msk = mvmsta->tfd_queue_msk; + for_each_set_bit(i, &sta_msk, sizeof(sta_msk)) + iwl_mvm_disable_txq(mvm, i); +} + int iwl_mvm_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -237,9 +287,17 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, atomic_set(&mvm->pending_frames[sta_id], 0); mvm_sta->tid_disable_agg = 0; mvm_sta->tfd_queue_msk = 0; - for (i = 0; i < IEEE80211_NUM_ACS; i++) - if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE) - mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]); + + /* allocate new queues for a TDLS station */ + if (sta->tdls) { + ret = iwl_mvm_tdls_sta_init(mvm, sta); + if (ret) + return ret; + } else { + for (i = 0; i < IEEE80211_NUM_ACS; i++) + if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE) + mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]); + } /* for HW restart - reset everything but the sequence number */ for (i = 0; i < IWL_MAX_TID_COUNT; i++) { @@ -251,7 +309,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); if (ret) - return ret; + goto err; if (vif->type == NL80211_IFTYPE_STATION) { if (!sta->tdls) { @@ -265,6 +323,10 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); return 0; + +err: + iwl_mvm_tdls_sta_deinit(mvm, sta); + return ret; } int iwl_mvm_update_sta(struct iwl_mvm *mvm, @@ -398,6 +460,17 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk) } RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL); clear_bit(sta_id, mvm->sta_drained); + + if (mvm->tfd_drained[sta_id]) { + unsigned long i, msk = mvm->tfd_drained[sta_id]; + + for_each_set_bit(i, &msk, sizeof(msk)) + iwl_mvm_disable_txq(mvm, i); + + mvm->tfd_drained[sta_id] = 0; + IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n", + sta_id, msk); + } } mutex_unlock(&mvm->mutex); @@ -443,9 +516,22 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], ERR_PTR(-EBUSY)); spin_unlock_bh(&mvm_sta->lock); + + /* disable TDLS sta queues on drain complete */ + if (sta->tdls) { + mvm->tfd_drained[mvm_sta->sta_id] = + mvm_sta->tfd_queue_msk; + IWL_DEBUG_TDLS(mvm, "Draining TDLS sta %d\n", + mvm_sta->sta_id); + } + ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); } else { spin_unlock_bh(&mvm_sta->lock); + + if (sta->tdls) + iwl_mvm_tdls_sta_deinit(mvm, sta); + ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); } diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 84f37ca9398a..2c869bcb9490 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -288,6 +288,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data) * struct iwl_mvm_sta - representation of a station in the driver * @sta_id: the index of the station in the fw (will be replaced by id_n_color) * @tfd_queue_msk: the tfd queues used by the station + * @hw_queue: per-AC mapping of the TFD queues used by station * @mac_id_n_color: the MAC context this station is linked to * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for * tid. @@ -311,6 +312,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data) struct iwl_mvm_sta { u32 sta_id; u32 tfd_queue_msk; + u8 hw_queue[IEEE80211_NUM_ACS]; u32 mac_id_n_color; u16 tid_disable_agg; u8 max_agg_bufsize; diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index b54708e4d29c..4f15d9decc81 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -424,6 +424,13 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); + if (sta->tdls) { + /* default to TID 0 for non-QoS packets */ + u8 tdls_tid = tid == IWL_MAX_TID_COUNT ? 0 : tid; + + txq_id = mvmsta->hw_queue[tid_to_mac80211_ac[tdls_tid]]; + } + if (is_ampdu) { if (WARN_ON_ONCE(mvmsta->tid_data[tid].state != IWL_AGG_ON)) goto drop_unlock_sta; -- GitLab From 9c126cd6e0ce8f02b7271b59c096598c55aa31d0 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Mon, 6 Oct 2014 19:08:56 +0200 Subject: [PATCH 5917/9457] iwlwifi: mvm: block TID when using TDLS Block TID 4 (VI) on a vif when using TDLS. This TID will be used by FW for TDLS channel-switch requests and PTI requests. Signed-off-by: Liad Kaufman Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 64e89e89140c..5aedf9dbf23c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2186,6 +2186,15 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, out_unlock: mutex_unlock(&mvm->mutex); + if (sta->tdls && ret == 0) { + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + ieee80211_reserve_tid(sta, IWL_MVM_TDLS_FW_TID); + else if (old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) + ieee80211_unreserve_tid(sta, IWL_MVM_TDLS_FW_TID); + } + return ret; } -- GitLab From 1d3c3f63f71ff19076a9bef89aa89bbbcaf44a15 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 23 Oct 2014 18:03:10 +0300 Subject: [PATCH 5918/9457] iwlwifi: mvm: implement mac80211 TDLS channel-switch APIs Maintain a TDLS channel-switch state and update it according to notifications from FW and timeouts. Explicitly check all state transitions are valid. When switching is initiated by mac80211, use a delayed work to periodically reschedule it from iwlwifi. Give the FW mac80211 generated TDLS channel-switch request/response templates. It will change appropriate values (switch timings) and Tx them at appropriate times. Enable the channel switch wiphy capability bit when the FW supports it. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw.c | 2 + drivers/net/wireless/iwlwifi/mvm/mac80211.c | 10 + drivers/net/wireless/iwlwifi/mvm/mvm.h | 43 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 4 + drivers/net/wireless/iwlwifi/mvm/sta.c | 9 + drivers/net/wireless/iwlwifi/mvm/tdls.c | 489 ++++++++++++++++++++ 6 files changed, 557 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index b4f244f510ed..575779086a46 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -466,6 +466,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm) for (i = 0; i < IWL_MVM_STATION_COUNT; i++) RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); + mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT; + /* reset quota debouncing buffer - 0xff will yield invalid data */ memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd)); diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5aedf9dbf23c..3841fcfbee2c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -495,6 +495,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; } + if (mvm->fw->ucode_capa.capa[0] & + IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH) { + IWL_DEBUG_TDLS(mvm, "TDLS channel switch supported\n"); + hw->wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH; + } + ret = ieee80211_register_hw(mvm->hw); if (ret) iwl_mvm_leds_exit(mvm); @@ -3211,6 +3217,10 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .channel_switch_beacon = iwl_mvm_channel_switch_beacon, + .tdls_channel_switch = iwl_mvm_tdls_channel_switch, + .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, + .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, + CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 63d2d453f9dd..44625adae1c5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -519,6 +519,13 @@ enum { #define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100 #define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200 +enum iwl_mvm_tdls_cs_state { + IWL_MVM_TDLS_SW_IDLE = 0, + IWL_MVM_TDLS_SW_REQ_SENT, + IWL_MVM_TDLS_SW_REQ_RCVD, + IWL_MVM_TDLS_SW_ACTIVE, +}; + struct iwl_mvm { /* for logger access */ struct device *dev; @@ -740,6 +747,28 @@ struct iwl_mvm { u32 ap_last_beacon_gp2; u8 low_latency_agg_frame_limit; + + /* TDLS channel switch data */ + struct { + struct delayed_work dwork; + enum iwl_mvm_tdls_cs_state state; + + /* + * Current cs sta - might be different from periodic cs peer + * station. Value is meaningless when the cs-state is idle. + */ + u8 cur_sta_id; + + /* TDLS periodic channel-switch peer */ + struct { + u8 sta_id; + u8 op_class; + bool initiator; /* are we the link initiator */ + struct cfg80211_chan_def chandef; + struct sk_buff *skb; /* ch sw template */ + u32 ch_sw_tm_ie; + } peer; + } tdls_cs; }; /* Extract MVM priv from op_mode and _hw */ @@ -1258,6 +1287,20 @@ void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool sta_added); void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int iwl_mvm_tdls_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u8 oper_class, + struct cfg80211_chan_def *chandef, + struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie); +void iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_tdls_ch_sw_params *params); +void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); +void iwl_mvm_tdls_ch_switch_work(struct work_struct *work); struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 9f9c7672b956..cc83ef54ed50 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -258,6 +258,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_power_uapsd_misbehaving_ap_notif, false), RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true), + RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif, + true), + }; #undef RX_HANDLER #define CMD(x) [x] = #x @@ -453,6 +456,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); INIT_WORK(&mvm->fw_error_dump_wk, iwl_mvm_fw_error_dump_wk); + INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); spin_lock_init(&mvm->d0i3_tx_lock); spin_lock_init(&mvm->refs_lock); diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 15afa9a26c8f..a38f1f151ff5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -503,6 +503,15 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; } + /* + * This shouldn't happen - the TDLS channel switch should be canceled + * before the STA is removed. + */ + if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == mvm_sta->sta_id)) { + mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT; + cancel_delayed_work(&mvm->tdls_cs.dwork); + } + /* * Make sure that the tx response code sees the station as -EBUSY and * calls the drain worker. diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c index 6dc381bc10f8..c0e00bae5bd0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c @@ -61,9 +61,13 @@ * *****************************************************************************/ +#include #include "mvm.h" #include "time-event.h" +#define TU_TO_US(x) (x * 1024) +#define TU_TO_MS(x) (TU_TO_US(x) / 1000) + void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm) { struct ieee80211_sta *sta; @@ -215,3 +219,488 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); } + +static const char * +iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state) +{ + switch (state) { + case IWL_MVM_TDLS_SW_IDLE: + return "IDLE"; + case IWL_MVM_TDLS_SW_REQ_SENT: + return "REQ SENT"; + case IWL_MVM_TDLS_SW_REQ_RCVD: + return "REQ RECEIVED"; + case IWL_MVM_TDLS_SW_ACTIVE: + return "ACTIVE"; + } + + return NULL; +} + +static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm *mvm, + enum iwl_mvm_tdls_cs_state state) +{ + if (mvm->tdls_cs.state == state) + return; + + IWL_DEBUG_TDLS(mvm, "TDLS channel switch state: %s -> %s\n", + iwl_mvm_tdls_cs_state_str(mvm->tdls_cs.state), + iwl_mvm_tdls_cs_state_str(state)); + mvm->tdls_cs.state = state; + + if (state == IWL_MVM_TDLS_SW_IDLE) + mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT; +} + +int iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_tdls_channel_switch_notif *notif = (void *)pkt->data; + struct ieee80211_sta *sta; + unsigned int delay; + struct iwl_mvm_sta *mvmsta; + struct ieee80211_vif *vif; + u32 sta_id = le32_to_cpu(notif->sta_id); + + lockdep_assert_held(&mvm->mutex); + + /* can fail sometimes */ + if (!le32_to_cpu(notif->status)) { + iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE); + goto out; + } + + if (WARN_ON(sta_id >= IWL_MVM_STATION_COUNT)) + goto out; + + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], + lockdep_is_held(&mvm->mutex)); + /* the station may not be here, but if it is, it must be a TDLS peer */ + if (IS_ERR_OR_NULL(sta) || WARN_ON(!sta->tdls)) + goto out; + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + vif = mvmsta->vif; + + /* + * Update state and possibly switch again after this is over (DTIM). + * Also convert TU to msec. + */ + delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int); + mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, + msecs_to_jiffies(delay)); + + iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_ACTIVE); + +out: + return 0; +} + +static int +iwl_mvm_tdls_check_action(struct iwl_mvm *mvm, + enum iwl_tdls_channel_switch_type type, + const u8 *peer, bool peer_initiator) +{ + bool same_peer = false; + int ret = 0; + + /* get the existing peer if it's there */ + if (mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE && + mvm->tdls_cs.cur_sta_id != IWL_MVM_STATION_COUNT) { + struct ieee80211_sta *sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id], + lockdep_is_held(&mvm->mutex)); + if (!IS_ERR_OR_NULL(sta)) + same_peer = ether_addr_equal(peer, sta->addr); + } + + switch (mvm->tdls_cs.state) { + case IWL_MVM_TDLS_SW_IDLE: + /* + * might be spurious packet from the peer after the switch is + * already done + */ + if (type == TDLS_MOVE_CH) + ret = -EINVAL; + break; + case IWL_MVM_TDLS_SW_REQ_SENT: + /* + * We received a ch-switch request while an outgoing one is + * pending. Allow it to proceed if the other peer is the same + * one we sent to, and we are not the link initiator. + */ + if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH) { + if (!same_peer) + ret = -EBUSY; + else if (!peer_initiator) /* we are the initiator */ + ret = -EBUSY; + } + break; + case IWL_MVM_TDLS_SW_REQ_RCVD: + /* as above, allow the link initiator to proceed */ + if (type == TDLS_SEND_CHAN_SW_REQ) { + if (!same_peer) + ret = -EBUSY; + else if (peer_initiator) /* they are the initiator */ + ret = -EBUSY; + } else if (type == TDLS_MOVE_CH) { + ret = -EINVAL; + } + break; + case IWL_MVM_TDLS_SW_ACTIVE: + /* we don't allow initiations during active channel switch */ + if (type == TDLS_SEND_CHAN_SW_REQ) + ret = -EINVAL; + break; + } + + if (ret) + IWL_DEBUG_TDLS(mvm, + "Invalid TDLS action %d state %d peer %pM same_peer %d initiator %d\n", + type, mvm->tdls_cs.state, peer, same_peer, + peer_initiator); + + return ret; +} + +static int +iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + enum iwl_tdls_channel_switch_type type, + const u8 *peer, bool peer_initiator, + u8 oper_class, + struct cfg80211_chan_def *chandef, + u32 timestamp, u16 switch_time, + u16 switch_timeout, struct sk_buff *skb, + u32 ch_sw_tm_ie) +{ + struct ieee80211_sta *sta; + struct iwl_mvm_sta *mvmsta; + struct ieee80211_tx_info *info; + struct ieee80211_hdr *hdr; + struct iwl_tdls_channel_switch_cmd cmd = {0}; + int ret; + + lockdep_assert_held(&mvm->mutex); + + ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator); + if (ret) + return ret; + + if (!skb || WARN_ON(skb->len > IWL_TDLS_CH_SW_FRAME_MAX_SIZE)) { + ret = -EINVAL; + goto out; + } + + cmd.switch_type = type; + cmd.timing.frame_timestamp = cpu_to_le32(timestamp); + cmd.timing.switch_time = cpu_to_le32(switch_time); + cmd.timing.switch_timeout = cpu_to_le32(switch_timeout); + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, peer); + if (!sta) { + rcu_read_unlock(); + ret = -ENOENT; + goto out; + } + mvmsta = iwl_mvm_sta_from_mac80211(sta); + cmd.peer_sta_id = cpu_to_le32(mvmsta->sta_id); + + if (!chandef) { + if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT && + mvm->tdls_cs.peer.chandef.chan) { + /* actually moving to the channel */ + chandef = &mvm->tdls_cs.peer.chandef; + } else if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_ACTIVE && + type == TDLS_MOVE_CH) { + /* we need to return to base channel */ + struct ieee80211_chanctx_conf *chanctx = + rcu_dereference(vif->chanctx_conf); + + if (WARN_ON_ONCE(!chanctx)) { + rcu_read_unlock(); + goto out; + } + + chandef = &chanctx->def; + } + } + + if (chandef) { + cmd.ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ? + PHY_BAND_24 : PHY_BAND_5); + cmd.ci.channel = chandef->chan->hw_value; + cmd.ci.width = iwl_mvm_get_channel_width(chandef); + cmd.ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef); + } + + /* keep quota calculation simple for now - 50% of DTIM for TDLS */ + cmd.timing.max_offchan_duration = + cpu_to_le32(TU_TO_US(vif->bss_conf.dtim_period * + vif->bss_conf.beacon_int) / 2); + + /* Switch time is the first element in the switch-timing IE. */ + cmd.frame.switch_time_offset = cpu_to_le32(ch_sw_tm_ie + 2); + + info = IEEE80211_SKB_CB(skb); + if (info->control.hw_key) + iwl_mvm_set_tx_cmd_crypto(mvm, info, &cmd.frame.tx_cmd, skb); + + iwl_mvm_set_tx_cmd(mvm, skb, &cmd.frame.tx_cmd, info, + mvmsta->sta_id); + + hdr = (void *)skb->data; + iwl_mvm_set_tx_cmd_rate(mvm, &cmd.frame.tx_cmd, info, sta, + hdr->frame_control); + rcu_read_unlock(); + + memcpy(cmd.frame.data, skb->data, skb->len); + + ret = iwl_mvm_send_cmd_pdu(mvm, TDLS_CHANNEL_SWITCH_CMD, 0, + sizeof(cmd), &cmd); + if (ret) { + IWL_ERR(mvm, "Failed to send TDLS_CHANNEL_SWITCH cmd: %d\n", + ret); + goto out; + } + + /* channel switch has started, update state */ + if (type != TDLS_MOVE_CH) { + mvm->tdls_cs.cur_sta_id = mvmsta->sta_id; + iwl_mvm_tdls_update_cs_state(mvm, + type == TDLS_SEND_CHAN_SW_REQ ? + IWL_MVM_TDLS_SW_REQ_SENT : + IWL_MVM_TDLS_SW_REQ_RCVD); + } + +out: + + /* channel switch failed - we are idle */ + if (ret) + iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE); + + return ret; +} + +void iwl_mvm_tdls_ch_switch_work(struct work_struct *work) +{ + struct iwl_mvm *mvm; + struct ieee80211_sta *sta; + struct iwl_mvm_sta *mvmsta; + struct ieee80211_vif *vif; + unsigned int delay; + int ret; + + mvm = container_of(work, struct iwl_mvm, tdls_cs.dwork.work); + mutex_lock(&mvm->mutex); + + /* called after an active channel switch has finished or timed-out */ + iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE); + + /* station might be gone, in that case do nothing */ + if (mvm->tdls_cs.peer.sta_id == IWL_MVM_STATION_COUNT) + goto out; + + sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id], + lockdep_is_held(&mvm->mutex)); + /* the station may not be here, but if it is, it must be a TDLS peer */ + if (!sta || IS_ERR(sta) || WARN_ON(!sta->tdls)) + goto out; + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + vif = mvmsta->vif; + ret = iwl_mvm_tdls_config_channel_switch(mvm, vif, + TDLS_SEND_CHAN_SW_REQ, + sta->addr, + mvm->tdls_cs.peer.initiator, + mvm->tdls_cs.peer.op_class, + &mvm->tdls_cs.peer.chandef, + 0, 0, 0, + mvm->tdls_cs.peer.skb, + mvm->tdls_cs.peer.ch_sw_tm_ie); + if (ret) + IWL_ERR(mvm, "Not sending TDLS channel switch: %d\n", ret); + + /* retry after a DTIM if we failed sending now */ + delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int); + queue_delayed_work(system_wq, &mvm->tdls_cs.dwork, + msecs_to_jiffies(delay)); +out: + mutex_unlock(&mvm->mutex); +} + +int +iwl_mvm_tdls_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u8 oper_class, + struct cfg80211_chan_def *chandef, + struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_mvm_sta *mvmsta; + unsigned int delay; + int ret; + + mutex_lock(&mvm->mutex); + + IWL_DEBUG_TDLS(mvm, "TDLS channel switch with %pM ch %d width %d\n", + sta->addr, chandef->chan->center_freq, chandef->width); + + /* we only support a single peer for channel switching */ + if (mvm->tdls_cs.peer.sta_id != IWL_MVM_STATION_COUNT) { + IWL_DEBUG_TDLS(mvm, + "Existing peer. Can't start switch with %pM\n", + sta->addr); + ret = -EBUSY; + goto out; + } + + ret = iwl_mvm_tdls_config_channel_switch(mvm, vif, + TDLS_SEND_CHAN_SW_REQ, + sta->addr, sta->tdls_initiator, + oper_class, chandef, 0, 0, 0, + tmpl_skb, ch_sw_tm_ie); + if (ret) + goto out; + + /* + * Mark the peer as "in tdls switch" for this vif. We only allow a + * single such peer per vif. + */ + mvm->tdls_cs.peer.skb = skb_copy(tmpl_skb, GFP_KERNEL); + if (!mvm->tdls_cs.peer.skb) { + ret = -ENOMEM; + goto out; + } + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + mvm->tdls_cs.peer.sta_id = mvmsta->sta_id; + mvm->tdls_cs.peer.chandef = *chandef; + mvm->tdls_cs.peer.initiator = sta->tdls_initiator; + mvm->tdls_cs.peer.op_class = oper_class; + mvm->tdls_cs.peer.ch_sw_tm_ie = ch_sw_tm_ie; + + /* + * Wait for 2 DTIM periods before attempting the next switch. The next + * switch will be made sooner if the current one completes before that. + */ + delay = 2 * TU_TO_MS(vif->bss_conf.dtim_period * + vif->bss_conf.beacon_int); + mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, + msecs_to_jiffies(delay)); + +out: + mutex_unlock(&mvm->mutex); + return ret; +} + +void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct ieee80211_sta *cur_sta; + bool wait_for_phy = false; + + mutex_lock(&mvm->mutex); + + IWL_DEBUG_TDLS(mvm, "TDLS cancel channel switch with %pM\n", sta->addr); + + /* we only support a single peer for channel switching */ + if (mvm->tdls_cs.peer.sta_id == IWL_MVM_STATION_COUNT) { + IWL_DEBUG_TDLS(mvm, "No ch switch peer - %pM\n", sta->addr); + goto out; + } + + cur_sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id], + lockdep_is_held(&mvm->mutex)); + /* make sure it's the same peer */ + if (cur_sta != sta) + goto out; + + /* + * If we're currently in a switch because of the now canceled peer, + * wait a DTIM here to make sure the phy is back on the base channel. + * We can't otherwise force it. + */ + if (mvm->tdls_cs.cur_sta_id == mvm->tdls_cs.peer.sta_id && + mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE) + wait_for_phy = true; + + mvm->tdls_cs.peer.sta_id = IWL_MVM_STATION_COUNT; + dev_kfree_skb(mvm->tdls_cs.peer.skb); + mvm->tdls_cs.peer.skb = NULL; + +out: + mutex_unlock(&mvm->mutex); + + /* make sure the phy is on the base channel */ + if (wait_for_phy) + msleep(TU_TO_MS(vif->bss_conf.dtim_period * + vif->bss_conf.beacon_int)); + + /* flush the channel switch state */ + flush_delayed_work(&mvm->tdls_cs.dwork); + + IWL_DEBUG_TDLS(mvm, "TDLS ending channel switch with %pM\n", sta->addr); +} + +void +iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_tdls_ch_sw_params *params) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + enum iwl_tdls_channel_switch_type type; + unsigned int delay; + + mutex_lock(&mvm->mutex); + + IWL_DEBUG_TDLS(mvm, + "Received TDLS ch switch action %d from %pM status %d\n", + params->action_code, params->sta->addr, params->status); + + /* + * we got a non-zero status from a peer we were switching to - move to + * the idle state and retry again later + */ + if (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE && + params->status != 0 && + mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT && + mvm->tdls_cs.cur_sta_id != IWL_MVM_STATION_COUNT) { + struct ieee80211_sta *cur_sta; + + /* make sure it's the same peer */ + cur_sta = rcu_dereference_protected( + mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id], + lockdep_is_held(&mvm->mutex)); + if (cur_sta == params->sta) { + iwl_mvm_tdls_update_cs_state(mvm, + IWL_MVM_TDLS_SW_IDLE); + goto retry; + } + } + + type = (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST) ? + TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH : TDLS_MOVE_CH; + + iwl_mvm_tdls_config_channel_switch(mvm, vif, type, params->sta->addr, + params->sta->tdls_initiator, 0, + params->chandef, params->timestamp, + params->switch_time, + params->switch_timeout, + params->tmpl_skb, + params->ch_sw_tm_ie); + +retry: + /* register a timeout in case we don't succeed in switching */ + delay = vif->bss_conf.dtim_period * vif->bss_conf.beacon_int * + 1024 / 1000; + mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, + msecs_to_jiffies(delay)); + mutex_unlock(&mvm->mutex); +} -- GitLab From f028905c2033137f98d8c0025165644ac63cfe8d Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:06 +0200 Subject: [PATCH 5919/9457] iwlwifi: mvm: use new pre_channel_switch op instead of channel_switch_beacon A new callback has been added to prepare the device for a channel switch. Use the new callback instead of the old channel_switch_beacon operation. This makes it possible to remove the channel_switch_beacon operation from mac80211. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3841fcfbee2c..1f53f81ca69d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3100,27 +3100,34 @@ static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw, } #endif -static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_chan_def *chandef) +static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel_switch *chsw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct ieee80211_vif *csa_vif; + int ret; mutex_lock(&mvm->mutex); csa_vif = rcu_dereference_protected(mvm->csa_vif, lockdep_is_held(&mvm->mutex)); if (WARN(csa_vif && csa_vif->csa_active, - "Another CSA is already in progress")) + "Another CSA is already in progress")) { + ret = -EBUSY; goto out_unlock; + } IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", - chandef->center_freq1); + chsw->chandef.center_freq1); rcu_assign_pointer(mvm->csa_vif, vif); + ret = 0; + out_unlock: mutex_unlock(&mvm->mutex); + + return ret; } static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, @@ -3215,7 +3222,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .set_tim = iwl_mvm_set_tim, - .channel_switch_beacon = iwl_mvm_channel_switch_beacon, + .pre_channel_switch = iwl_mvm_pre_channel_switch, .tdls_channel_switch = iwl_mvm_tdls_channel_switch, .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, -- GitLab From 6b20d774370952790e5cebd8a297251bc1ac2df3 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:07 +0200 Subject: [PATCH 5920/9457] iwlwifi: mvm: only save csa_vif in AP/GO mode We only need the csa_vif in AP/GO modes, and assigning for other interfaces may cause problems, because csa_vif is never cleared. To prevent this, only assign the value if the iftype is NL80211_IFTYPE_AP. Use a switch to do this, even though, for now, only the AP interface type is handled, because soon other interface types will be added as well. Additionally, convert the WARN() in the error case when a channel-switch is already running to WARN_ONCE(). Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 28 +++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 1f53f81ca69d..98bb84613cdf 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3110,17 +3110,25 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); - csa_vif = rcu_dereference_protected(mvm->csa_vif, - lockdep_is_held(&mvm->mutex)); - if (WARN(csa_vif && csa_vif->csa_active, - "Another CSA is already in progress")) { - ret = -EBUSY; - goto out_unlock; - } - - IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", + IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", chsw->chandef.center_freq1); - rcu_assign_pointer(mvm->csa_vif, vif); + + switch (vif->type) { + case NL80211_IFTYPE_AP: + csa_vif = + rcu_dereference_protected(mvm->csa_vif, + lockdep_is_held(&mvm->mutex)); + if (WARN_ONCE(csa_vif && csa_vif->csa_active, + "Another CSA is already in progress")) { + ret = -EBUSY; + goto out_unlock; + } + + rcu_assign_pointer(mvm->csa_vif, vif); + break; + default: + break; + } ret = 0; -- GitLab From 50cc9574d60a507eff92537d8b01b9eb7b6a81bf Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:08 +0200 Subject: [PATCH 5921/9457] iwlwifi: mvm: refactor iwl_mvm_switch_vif_chanctx to support other modes Currently we only support the CHANCTX_SWMODE_SWAP_CONTEXTS mode, but we need to support other modes as well. Spin a new function off in order to make it easier to support other modes. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 40 ++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 98bb84613cdf..1966a6096033 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2954,18 +2954,12 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, mutex_unlock(&mvm->mutex); } -static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif_chanctx_switch *vifs, - int n_vifs, - enum ieee80211_chanctx_switch_mode mode) +static int +iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm, + struct ieee80211_vif_chanctx_switch *vifs) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; - /* we only support SWAP_CONTEXTS and with a single-vif right now */ - if (mode != CHANCTX_SWMODE_SWAP_CONTEXTS || n_vifs > 1) - return -EOPNOTSUPP; - mutex_lock(&mvm->mutex); __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true); __iwl_mvm_remove_chanctx(mvm, vifs[0].old_ctx); @@ -3015,6 +3009,34 @@ static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, out: mutex_unlock(&mvm->mutex); + + return ret; +} + +static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + int ret; + + /* we only support a single-vif right now */ + if (n_vifs > 1) + return -EOPNOTSUPP; + + switch (mode) { + case CHANCTX_SWMODE_SWAP_CONTEXTS: + ret = iwl_mvm_switch_vif_chanctx_swap(mvm, vifs); + break; + case CHANCTX_SWMODE_REASSIGN_VIF: + ret = -EOPNOTSUPP; + break; + default: + ret = -EOPNOTSUPP; + break; + } + return ret; } -- GitLab From 48a256e8aed05df3a90a0e9cdfcc558d139ec7f5 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:09 +0200 Subject: [PATCH 5922/9457] iwlwifi: mvm: add support for CHANCTX_SWMODE_REASSIGN_VIF Add support to reassign vif in switch_vif_chanctx. This is similar to the existing CHANCTX_SWMODE_SWAP_CONTEXTS mode, but doesn't delete the old context nor creates a new one, doing to switch between two existing contexts. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 40 ++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 1966a6096033..542e59f61d1c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3013,6 +3013,44 @@ iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm, return ret; } +static int +iwl_mvm_switch_vif_chanctx_reassign(struct iwl_mvm *mvm, + struct ieee80211_vif_chanctx_switch *vifs) +{ + int ret; + + mutex_lock(&mvm->mutex); + __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true); + + ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].new_ctx, + true); + if (ret) { + IWL_ERR(mvm, + "failed to assign new_ctx during channel switch\n"); + goto out_reassign; + } + + goto out; + +out_reassign: + if (__iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, + true)) { + IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n"); + goto out_restart; + } + + goto out; + +out_restart: + /* things keep failing, better restart the hw */ + iwl_mvm_nic_restart(mvm, false); + +out: + mutex_unlock(&mvm->mutex); + + return ret; +} + static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif_chanctx_switch *vifs, int n_vifs, @@ -3030,7 +3068,7 @@ static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw, ret = iwl_mvm_switch_vif_chanctx_swap(mvm, vifs); break; case CHANCTX_SWMODE_REASSIGN_VIF: - ret = -EOPNOTSUPP; + ret = iwl_mvm_switch_vif_chanctx_reassign(mvm, vifs); break; default: ret = -EOPNOTSUPP; -- GitLab From 6fd1fb63abeb78fd7fe30f08f478732ad601702c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:10 +0200 Subject: [PATCH 5923/9457] iwlwifi: mvm: return the actual error code when switch_vif_chanctx fails We have code to recover and go back to the original channel context if something fails in the middle of switch_vif_chanctx, but we return the error code of the recover calls instead of the original code, so if the recovery succeeds, we will return 0 (success). Fix this by not assigning the return value of the recovery calls to ret. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 542e59f61d1c..1d556173fcb6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2988,15 +2988,13 @@ iwl_mvm_switch_vif_chanctx_swap(struct iwl_mvm *mvm, __iwl_mvm_remove_chanctx(mvm, vifs[0].new_ctx); out_reassign: - ret = __iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx); - if (ret) { + if (__iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx)) { IWL_ERR(mvm, "failed to add old_ctx back after failure.\n"); goto out_restart; } - ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, - true); - if (ret) { + if (__iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, + true)) { IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n"); goto out_restart; } -- GitLab From 7ef0aab66b317ff4d818966b2104c900c7126ec8 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Mon, 10 Nov 2014 11:10:11 +0200 Subject: [PATCH 5924/9457] iwlwifi: mvm: Handle failed beacon transmissions during CSA The spec requires to decrement the CSA counters based on TBTT, regardless if the beacon was actually transmitted. Previously, the fw would send beacon notifications only for successfully transmitted beacons. This behavior resulted in inaccurate CSA countdown. In order to address this issue, the fw was changed to send beacon notifications also for not transmitted beacons. Such notifications have TX_STATUS_INTERNAL_ABORT (0x92). Don't start the CSA countdown before first successfully transmitted beacon, in order to guarantee that the CSA is announced for a required period. Signed-off-by: Andrei Otcheretianski --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 21 +++++++++++++++------ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index a1dc9b86c2d1..0cb79bc06781 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -1263,17 +1263,25 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) } static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm, - struct ieee80211_vif *csa_vif, u32 gp2) + struct ieee80211_vif *csa_vif, u32 gp2, + bool tx_success) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(csa_vif); + /* Don't start to countdown from a failed beacon */ + if (!tx_success && !mvmvif->csa_countdown) + return; + + mvmvif->csa_countdown = true; + if (!ieee80211_csa_is_complete(csa_vif)) { int c = ieee80211_csa_update_counter(csa_vif); iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif); if (csa_vif->p2p && - !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) { + !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2 && + tx_success) { u32 rel_time = (c + 1) * csa_vif->bss_conf.beacon_int - IWL_MVM_CHANNEL_SWITCH_TIME_GO; @@ -1300,6 +1308,7 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, struct ieee80211_vif *csa_vif; struct ieee80211_vif *tx_blocked_vif; u64 tsf; + u16 status; lockdep_assert_held(&mvm->mutex); @@ -1316,18 +1325,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, tsf = le64_to_cpu(beacon->tsf); } + status = le16_to_cpu(beacon_notify_hdr->status.status) & TX_STATUS_MSK; IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n", - le16_to_cpu(beacon_notify_hdr->status.status) & - TX_STATUS_MSK, - beacon_notify_hdr->failure_frame, tsf, + status, beacon_notify_hdr->failure_frame, tsf, mvm->ap_last_beacon_gp2, le32_to_cpu(beacon_notify_hdr->initial_rate)); csa_vif = rcu_dereference_protected(mvm->csa_vif, lockdep_is_held(&mvm->mutex)); if (unlikely(csa_vif && csa_vif->csa_active)) - iwl_mvm_csa_count_down(mvm, csa_vif, mvm->ap_last_beacon_gp2); + iwl_mvm_csa_count_down(mvm, csa_vif, mvm->ap_last_beacon_gp2, + (status == TX_STATUS_SUCCESS)); tx_blocked_vif = rcu_dereference_protected(mvm->csa_tx_blocked_vif, lockdep_is_held(&mvm->mutex)); diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 1d556173fcb6..6098eafcf13a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2909,6 +2909,8 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, if (!vif->csa_active || !mvmvif->ap_ibss_active) goto out; + mvmvif->csa_countdown = false; + /* Set CS bit on all the stations */ iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true); @@ -3164,6 +3166,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct ieee80211_vif *csa_vif; + struct iwl_mvm_vif *mvmvif; int ret; mutex_lock(&mvm->mutex); @@ -3183,6 +3186,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, } rcu_assign_pointer(mvm->csa_vif, vif); + + mvmvif = iwl_mvm_vif_from_mac80211(vif); + if (WARN_ONCE(mvmvif->csa_countdown, + "Previous CSA countdown didn't complete")) { + ret = -EBUSY; + goto out_unlock; + } + break; default: break; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 44625adae1c5..2c54c522b8c6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -399,6 +399,9 @@ struct iwl_mvm_vif { /* FW identified misbehaving AP */ u8 uapsd_misbehaving_bssid[ETH_ALEN]; + + /* Indicates that CSA countdown may be started */ + bool csa_countdown; }; static inline struct iwl_mvm_vif * -- GitLab From f6c34820d36c7d385bd0b87bb2afeb0106e7ab8c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:12 +0200 Subject: [PATCH 5925/9457] iwlwifi: mvm: disable PS during channel switch Disable PS when pre_channel_switch is called and add the post_channel_switch operation to re-enable PS when the channel switch is completed. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 28 ++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 6098eafcf13a..b5365904c38e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3166,7 +3166,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct ieee80211_vif *csa_vif; - struct iwl_mvm_vif *mvmvif; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int ret; mutex_lock(&mvm->mutex); @@ -3187,7 +3187,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, rcu_assign_pointer(mvm->csa_vif, vif); - mvmvif = iwl_mvm_vif_from_mac80211(vif); if (WARN_ONCE(mvmvif->csa_countdown, "Previous CSA countdown didn't complete")) { ret = -EBUSY; @@ -3199,7 +3198,11 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, break; } - ret = 0; + mvmvif->ps_disabled = true; + + ret = iwl_mvm_power_update_ps(mvm); + if (ret) + goto out_unlock; out_unlock: mutex_unlock(&mvm->mutex); @@ -3207,6 +3210,24 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, return ret; } +static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + int ret; + + mutex_lock(&mvm->mutex); + + mvmvif->ps_disabled = false; + + ret = iwl_mvm_power_update_ps(mvm); + + mutex_unlock(&mvm->mutex); + + return ret; +} + static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) { @@ -3300,6 +3321,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .set_tim = iwl_mvm_set_tim, .pre_channel_switch = iwl_mvm_pre_channel_switch, + .post_channel_switch = iwl_mvm_post_channel_switch, .tdls_channel_switch = iwl_mvm_tdls_channel_switch, .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, -- GitLab From 4741dd049a27fa6490e502d42ff51417c58ac7cd Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:13 +0200 Subject: [PATCH 5926/9457] iwlwifi: mvm: use switching_chanctx argument instead of csa_active Now that all CSA flows are using the switch_vif_chanctx op, we can rely on the switching_chanctx boolean that is passed to the __iwl_mvm_assign_vif_chanctx() and __iwl_mvm_unassign_vif_chanctx() functions to decide whether the context switch flows need to be executed. In this way we make the chanctx switch flow more generic, without having to rely on the csa_active flag being set. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index b5365904c38e..fdeaab3457a3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2796,8 +2796,8 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, switch (vif->type) { case NL80211_IFTYPE_AP: - /* Unless it's a CSA flow we have nothing to do here */ - if (vif->csa_active) { + /* only needed if we're switching chanctx (i.e. during CSA) */ + if (switching_chanctx) { mvmvif->ap_ibss_active = true; break; } @@ -2847,7 +2847,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); } - if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) { + if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { struct iwl_mvm_sta *mvmsta; mvmsta = iwl_mvm_sta_from_staid_protected(mvm, @@ -2906,7 +2906,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, break; case NL80211_IFTYPE_AP: /* This part is triggered only during CSA */ - if (!vif->csa_active || !mvmvif->ap_ibss_active) + if (!switching_chanctx || !mvmvif->ap_ibss_active) goto out; mvmvif->csa_countdown = false; -- GitLab From dc88b4baa9d16fdf15f76b6277461e6d9e4eb8e6 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:14 +0200 Subject: [PATCH 5927/9457] iwlwifi: mvm: add CSA absent time event for clients Add an absent time event when pre_channel_switch is called and use the time event started indication to set the disable_tx bit instead of doing it in unassign_vif(). This is done so that the firmware queues are stopped before the actual switch takes place to avoid losing packets while the AP/GO is performing its actual switch. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 ++++++---- drivers/net/wireless/iwlwifi/mvm/mvm.h | 27 ++++++++++++-- drivers/net/wireless/iwlwifi/mvm/sta.c | 15 ++++++++ drivers/net/wireless/iwlwifi/mvm/sta.h | 1 + drivers/net/wireless/iwlwifi/mvm/time-event.c | 37 +++++++++++++++---- 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index fdeaab3457a3..ac1cef6a6b03 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2891,7 +2891,6 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_vif *disabled_vif = NULL; - struct iwl_mvm_sta *mvmsta; lockdep_assert_held(&mvm->mutex); @@ -2925,12 +2924,6 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, disabled_vif = vif; - mvmsta = iwl_mvm_sta_from_staid_protected(mvm, - mvmvif->ap_sta_id); - - if (!WARN_ON(!mvmsta)) - iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true); - iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL); break; default: @@ -3167,6 +3160,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct ieee80211_vif *csa_vif; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + u32 apply_time; int ret; mutex_lock(&mvm->mutex); @@ -3194,6 +3188,17 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, } break; + case NL80211_IFTYPE_STATION: + apply_time = chsw->timestamp + + (vif->bss_conf.beacon_int * chsw->count * 1024); + + if (chsw->block_tx) + iwl_mvm_csa_client_absent(mvm, vif); + + iwl_mvm_schedule_csa_period(mvm, vif, + IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT, + apply_time); + break; default: break; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2c54c522b8c6..2816c6b9222b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -87,11 +87,12 @@ /* A TimeUnit is 1024 microsecond */ #define MSEC_TO_TU(_msec) (_msec*1000/1024) -/* This value represents the number of TUs before CSA "beacon 0" TBTT - * when the CSA time-event needs to be scheduled to start. It must be - * big enough to ensure that we switch in time. +/* These values represent the number of TUs before CSA "beacon 0" TBTT + * when the CSA time-event needs to be scheduled to start. They must + * be big enough to ensure that we switch in time. */ #define IWL_MVM_CHANNEL_SWITCH_TIME_GO 40 +#define IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT 110 /* * This value (in TUs) is used to fine tune the CSA NoA end time which should @@ -797,6 +798,26 @@ static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status); } +/* Must be called with rcu_read_lock() held and it can only be + * released when mvmsta is not needed anymore. + */ +static inline struct iwl_mvm_sta * +iwl_mvm_sta_from_staid_rcu(struct iwl_mvm *mvm, u8 sta_id) +{ + struct ieee80211_sta *sta; + + if (sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)) + return NULL; + + sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); + + /* This can happen if the station has been removed right now */ + if (IS_ERR_OR_NULL(sta)) + return NULL; + + return iwl_mvm_sta_from_mac80211(sta); +} + static inline struct iwl_mvm_sta * iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id) { diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index a38f1f151ff5..d86fe432e51f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -1732,3 +1732,18 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm, iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, disable); } } + +void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_sta *mvmsta; + + rcu_read_lock(); + + mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id); + + if (!WARN_ON(!mvmsta)) + iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true); + + rcu_read_unlock(); +} diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 2c869bcb9490..d8f48975ad08 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -422,5 +422,6 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm, void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif, bool disable); +void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #endif /* __sta_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 8cf246b695c4..1a537be216ce 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -191,6 +191,33 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, return true; } +static void +iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, + struct iwl_mvm_time_event_data *te_data, + struct iwl_time_event_notif *notif) +{ + if (!le32_to_cpu(notif->status)) { + IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); + return; + } + + switch (te_data->vif->type) { + case NL80211_IFTYPE_AP: + iwl_mvm_csa_noa_start(mvm); + break; + case NL80211_IFTYPE_STATION: + iwl_mvm_csa_client_absent(mvm, te_data->vif); + break; + default: + /* should never happen */ + WARN_ON_ONCE(1); + break; + } + + /* we don't need it anymore */ + iwl_mvm_te_clear_data(mvm, te_data); +} + /* * Handles a FW notification for an event that is known to the driver. * @@ -252,14 +279,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); iwl_mvm_ref(mvm, IWL_MVM_REF_ROC); ieee80211_ready_on_channel(mvm->hw); - } else if (te_data->vif->type == NL80211_IFTYPE_AP) { - if (le32_to_cpu(notif->status)) - iwl_mvm_csa_noa_start(mvm); - else - IWL_DEBUG_TE(mvm, "CSA NOA failed to start\n"); - - /* we don't need it anymore */ - iwl_mvm_te_clear_data(mvm, te_data); + } else if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) { + iwl_mvm_te_handle_notify_csa(mvm, te_data, notif); } } else { IWL_WARN(mvm, "Got TE with unknown action\n"); -- GitLab From 4500e13376a14d601a330cab034499ca3fff41bd Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:15 +0200 Subject: [PATCH 5928/9457] iwlwifi: mvm: schedule CSA time event a bit before beacon 1 Instead of using a hardcoded number of TUs before beacon 0 as the time to start the absence and actual channel switch, calculate it in relation to the beacon interval. We use 10 TUs + beacon interval before beacon 0 to target a bit before beacon 1. This gives us enough time to switch to the new channel before the AP/GO switches. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 12 ++++++++---- drivers/net/wireless/iwlwifi/mvm/mvm.h | 13 +++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index ac1cef6a6b03..3ce5831ff206 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3189,14 +3189,18 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_STATION: - apply_time = chsw->timestamp + - (vif->bss_conf.beacon_int * chsw->count * 1024); + /* Schedule the time event to a bit before beacon 1, + * to make sure we're in the new channel when the + * GO/AP arrives. + */ + apply_time = chsw->device_timestamp + + ((vif->bss_conf.beacon_int * (chsw->count - 1) - + IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024); if (chsw->block_tx) iwl_mvm_csa_client_absent(mvm, vif); - iwl_mvm_schedule_csa_period(mvm, vif, - IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT, + iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int, apply_time); break; default: diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2816c6b9222b..99a25906bc92 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -87,12 +87,17 @@ /* A TimeUnit is 1024 microsecond */ #define MSEC_TO_TU(_msec) (_msec*1000/1024) -/* These values represent the number of TUs before CSA "beacon 0" TBTT - * when the CSA time-event needs to be scheduled to start. They must - * be big enough to ensure that we switch in time. +/* For GO, this value represents the number of TUs before CSA "beacon + * 0" TBTT when the CSA time-event needs to be scheduled to start. It + * must be big enough to ensure that we switch in time. */ #define IWL_MVM_CHANNEL_SWITCH_TIME_GO 40 -#define IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT 110 + +/* For client, this value represents the number of TUs before CSA + * "beacon 1" TBTT, instead. This is because we don't know when the + * GO/AP will be in the new channel, so we switch early enough. + */ +#define IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT 10 /* * This value (in TUs) is used to fine tune the CSA NoA end time which should -- GitLab From a57c688d34a05cbc72ec8cf4f05758cbafdd9893 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:16 +0200 Subject: [PATCH 5929/9457] iwlwifi: mvm: finalize on post_switch instead of unassign Now that mac80211 waits for the first beacon on the new channel before calling post_channel_switch, the reconfiguration of the firmware should be done in the post_channel_switch operation instead of when assigning the vif to the new context. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 31 +++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3ce5831ff206..c85c0f12867a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2841,23 +2841,13 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, } /* Handle binding during CSA */ - if ((vif->type == NL80211_IFTYPE_AP) || - (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { + if (vif->type == NL80211_IFTYPE_AP) { iwl_mvm_update_quotas(mvm, NULL); iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); } if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { - struct iwl_mvm_sta *mvmsta; - - mvmsta = iwl_mvm_sta_from_staid_protected(mvm, - mvmvif->ap_sta_id); - - if (WARN_ON(!mvmsta)) - goto out; - - /* TODO: only re-enable after the first beacon */ - iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); + iwl_mvm_update_quotas(mvm, NULL); } goto out; @@ -3228,10 +3218,27 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + if (vif->type == NL80211_IFTYPE_STATION) { + struct iwl_mvm_sta *mvmsta; + + mvmsta = iwl_mvm_sta_from_staid_protected(mvm, + mvmvif->ap_sta_id); + + if (WARN_ON(!mvmsta)) { + ret = -EIO; + goto out_unlock; + } + + iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); + + iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + } + mvmvif->ps_disabled = false; ret = iwl_mvm_power_update_ps(mvm); +out_unlock: mutex_unlock(&mvm->mutex); return ret; -- GitLab From 622e3f9b71f9a97408cd751851c6588d4e6c4fd0 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:17 +0200 Subject: [PATCH 5930/9457] iwlwifi: mvm: add a channel_switch op to bypass mac80211 timer We need to call ieee80211_chswitch_done() ourselves just when the absence TE started, so we perform the actual context switch early enough. To do so, add a dummy channel_switch op, which will cause mac80211 to skip the countdown timer and allow us to call ieee80211_chswitch_done() to complete the operation. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/mvm/time-event.c | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c85c0f12867a..7acdfa700ec1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3143,6 +3143,20 @@ static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw, } #endif +static void iwl_mvm_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel_switch *chsw) +{ + /* By implementing this operation, we prevent mac80211 from + * starting its own channel switch timer, so that we can call + * ieee80211_chswitch_done() ourselves at the right time + * (which is when the absence time event starts). + */ + + IWL_DEBUG_MAC80211(IWL_MAC80211_GET_MVM(hw), + "dummy channel switch op\n"); +} + static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel_switch *chsw) @@ -3336,6 +3350,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .set_tim = iwl_mvm_set_tim, + .channel_switch = iwl_mvm_channel_switch, .pre_channel_switch = iwl_mvm_pre_channel_switch, .post_channel_switch = iwl_mvm_post_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 1a537be216ce..ff631cc5e5e7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -207,6 +207,7 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, break; case NL80211_IFTYPE_STATION: iwl_mvm_csa_client_absent(mvm, te_data->vif); + ieee80211_chswitch_done(te_data->vif, true); break; default: /* should never happen */ -- GitLab From c6e0a3e044acfe451a546d892cce2d4a1253f7bd Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:18 +0200 Subject: [PATCH 5931/9457] iwlwifi: mvm: disable beacon filtering during CSA After a channel switch, transmission on the new channel is only started once we see a beacon on it. Thus, beacon filtering needs to be disabled during channel switch so that mac80211 receives this beacon and finishes the process. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7acdfa700ec1..a62014ee9053 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3206,6 +3206,12 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int, apply_time); + if (mvmvif->bf_data.bf_enabled) { + ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); + if (ret) + goto out_unlock; + } + break; default: break; @@ -3246,6 +3252,10 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + + ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0); + if (ret) + goto out_unlock; } mvmvif->ps_disabled = false; -- GitLab From 0c6505c6ed180ee342c98a6ec2c91e4ee80c1a10 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:20 +0200 Subject: [PATCH 5932/9457] iwlwifi: mvm: clear TE data if CSA time event fails to start If setting the CSA time event fails, we must clear the TE data, otherwise we'll try to remove it when, for instance, a disconnection occurs, causing a SYSASSERT. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/time-event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index ff631cc5e5e7..54fafbf9a711 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -198,6 +198,7 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, { if (!le32_to_cpu(notif->status)) { IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); + iwl_mvm_te_clear_data(mvm, te_data); return; } -- GitLab From 686e7fe1c4389984c5f623ebe1bb636d41841f37 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 10 Nov 2014 11:10:21 +0200 Subject: [PATCH 5933/9457] iwlwifi: mvm: protect session during CSA When another vif is also running during a channel switch, we need to use a session protection when we move to the new channel, so that we don't miss the beacons. Without this, sometimes the other vif repeatedly gets time exactly when we should be hearing the beacons, preventing channel switch from completing. Adding a session protection that lasts from the moment the channel changes until 2 TBTTs later, ensures that we will hear the beacons on the destination channel. Signed-off-by: Luciano Coelho --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 21 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index a62014ee9053..6214133e08a6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2847,6 +2847,25 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, } if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { + u32 duration = 2 * vif->bss_conf.beacon_int; + + /* iwl_mvm_protect_session() reads directly from the + * device (the system time), so make sure it is + * available. + */ + ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA); + if (ret) + goto out_remove_binding; + + /* Protect the session to make sure we hear the first + * beacon on the new channel. + */ + iwl_mvm_protect_session(mvm, vif, duration, duration, + vif->bss_conf.beacon_int / 2, + true); + + iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); + iwl_mvm_update_quotas(mvm, NULL); } @@ -3256,6 +3275,8 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0); if (ret) goto out_unlock; + + iwl_mvm_stop_session_protection(mvm, vif); } mvmvif->ps_disabled = false; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 99a25906bc92..7c62f80414ae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -275,6 +275,7 @@ enum iwl_mvm_ref_type { IWL_MVM_REF_NMI, IWL_MVM_REF_TM_CMD, IWL_MVM_REF_EXIT_WORK, + IWL_MVM_REF_PROTECT_CSA, /* update debugfs.c when changing this */ -- GitLab From c55385f55ccb087e9eb0c2f0108a4fc4c1fef446 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 24 Oct 2014 10:39:51 +0300 Subject: [PATCH 5934/9457] iwlwifi: mvm: add support for net detect Add the net detect WoWLAN flag to indicate support and use the nd_config from the WoWLAN configuration to start net detect, if it is set. The WoWLAN configuration takes precedence over the debugfs configuration. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 8 +++++--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 0fc72fc6ce2f..3c6602870a61 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1030,13 +1030,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif, mvmvif, ap_sta); if (ret) goto out; - } else if (mvm->nd_config) { + } else if (wowlan->nd_config || mvm->nd_config) { ret = iwl_mvm_switch_to_d3(mvm); if (ret) goto out; - ret = iwl_mvm_scan_offload_start(mvm, vif, mvm->nd_config, - &mvm->nd_ies); + ret = iwl_mvm_scan_offload_start( + mvm, vif, + wowlan->nd_config ?: mvm->nd_config, + &mvm->nd_ies); if (ret) goto out; } else { diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 6214133e08a6..d9d8d30e605e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -467,7 +467,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_RFKILL_RELEASE; + WIPHY_WOWLAN_RFKILL_RELEASE | + WIPHY_WOWLAN_NET_DETECT; if (!iwlwifi_mod_params.sw_crypto) mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_GTK_REKEY_FAILURE | @@ -476,6 +477,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; + mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES; mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; hw->wiphy->wowlan = &mvm->wowlan; } -- GitLab From 3acc952b0376556e76752e355a0c885ec530d27f Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 19 Nov 2014 22:35:37 +0200 Subject: [PATCH 5935/9457] iwlwifi: mvm: refactor wowlan and netdetect configuration when suspending We need to send a WOWLAN_CONFIGURATION command also for netdetect and configure the rfkill release trigger if needed. To do so, refactor the code that configures wowlan and netdetect when suspending and send the WOWLAN_CONFIGURATION command also for net_detect. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 67 ++++++++++++++++++--------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 3c6602870a61..fe27193ffba6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -878,6 +878,10 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, }; int ret; + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + return ret; + ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta); if (ret) return ret; @@ -962,6 +966,33 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, return ret; } +static int +iwl_mvm_netdetect_config(struct iwl_mvm *mvm, + struct cfg80211_wowlan *wowlan, + struct cfg80211_sched_scan_request *nd_config, + struct ieee80211_vif *vif) +{ + struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; + int ret; + + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + return ret; + + /* rfkill release can be either for wowlan or netdetect */ + if (wowlan->rfkill_release) + wowlan_config_cmd.common.wakeup_filter |= + cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); + + ret = iwl_mvm_send_wowlan_config_cmd(mvm, &wowlan_config_cmd); + if (ret) + return ret; + + ret = iwl_mvm_scan_offload_start(mvm, vif, nd_config, &mvm->nd_ies); + + return ret; +} + static int __iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan, bool test) @@ -970,7 +1001,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, struct ieee80211_vif *vif = NULL; struct iwl_mvm_vif *mvmvif = NULL; struct ieee80211_sta *ap_sta = NULL; - struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; struct iwl_d3_manager_config d3_cfg_cmd_data = { /* * Program the minimum sleep time to 10 seconds, as many @@ -1007,8 +1037,20 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mvmvif = iwl_mvm_vif_from_mac80211(vif); - /* if we're associated, this is wowlan */ - if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { + if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) { + /* if we're not associated, this must be netdetect */ + if (!wowlan->nd_config && !mvm->nd_config) { + ret = 1; + goto out_noreset; + } + + ret = iwl_mvm_netdetect_config( + mvm, wowlan, wowlan->nd_config ?: mvm->nd_config, vif); + if (ret) + goto out; + } else { + struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; + ap_sta = rcu_dereference_protected( mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], lockdep_is_held(&mvm->mutex)); @@ -1021,29 +1063,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif, mvmvif, ap_sta); if (ret) goto out_noreset; - - ret = iwl_mvm_switch_to_d3(mvm); - if (ret) - goto out; - ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd, vif, mvmvif, ap_sta); if (ret) goto out; - } else if (wowlan->nd_config || mvm->nd_config) { - ret = iwl_mvm_switch_to_d3(mvm); - if (ret) - goto out; - - ret = iwl_mvm_scan_offload_start( - mvm, vif, - wowlan->nd_config ?: mvm->nd_config, - &mvm->nd_ies); - if (ret) - goto out; - } else { - ret = 1; - goto out_noreset; } ret = iwl_mvm_power_update_device(mvm); -- GitLab From ec12f457d6e61148a89e77e48fa0d4b3deab7500 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 20 Nov 2014 10:14:44 +0200 Subject: [PATCH 5936/9457] iwlwifi: mvm: refactor iwl_mvm_query_wakeup_reasons() Refactor the iwl_mvm_query_wakeup_reasons() function to split the part that gets the firmware status from the part that sets up the WoWLAN status. This will allow netdetect to reuse the code. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 73 +++++++++++++++++---------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index fe27193ffba6..c72d2e98c3f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1490,9 +1490,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, return true; } -/* releases the MVM mutex */ -static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) +static struct iwl_wowlan_status * +iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { u32 base = mvm->error_event_table; struct error_table_start { @@ -1504,19 +1503,15 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, .id = WOWLAN_GET_STATUSES, .flags = CMD_WANT_SKB, }; - struct iwl_wowlan_status_data status; - struct iwl_wowlan_status *fw_status; - int ret, len, status_size, i; - bool keep; - struct ieee80211_sta *ap_sta; - struct iwl_mvm_sta *mvm_ap_sta; + struct iwl_wowlan_status *status, *fw_status; + int ret, len, status_size; iwl_trans_read_mem_bytes(mvm->trans, base, &err_info, sizeof(err_info)); if (err_info.valid) { - IWL_INFO(mvm, "error table is valid (%d)\n", - err_info.valid); + IWL_INFO(mvm, "error table is valid (%d) with error (%d)\n", + err_info.valid, err_info.error_id); if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) { struct cfg80211_wowlan_wakeup wakeup = { .rfkill_release = true, @@ -1524,7 +1519,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL); } - goto out_unlock; + return ERR_PTR(-EIO); } /* only for tracing for now */ @@ -1535,22 +1530,53 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret) { IWL_ERR(mvm, "failed to query status (%d)\n", ret); - goto out_unlock; + return ERR_PTR(ret); } /* RF-kill already asserted again... */ - if (!cmd.resp_pkt) - goto out_unlock; + if (!cmd.resp_pkt) { + ret = -ERFKILL; + goto out_free_resp; + } status_size = sizeof(*fw_status); len = iwl_rx_packet_payload_len(cmd.resp_pkt); if (len < status_size) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + ret = -EIO; + goto out_free_resp; + } + + status = (void *)cmd.resp_pkt->data; + if (len != (status_size + + ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4))) { + IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); + ret = -EIO; goto out_free_resp; } - fw_status = (void *)cmd.resp_pkt->data; + fw_status = kmemdup(status, len, GFP_KERNEL); + +out_free_resp: + iwl_free_resp(&cmd); + return ret ? ERR_PTR(ret) : fw_status; +} + +/* releases the MVM mutex */ +static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) +{ + struct iwl_wowlan_status_data status; + struct iwl_wowlan_status *fw_status; + int i; + bool keep; + struct ieee80211_sta *ap_sta; + struct iwl_mvm_sta *mvm_ap_sta; + + fw_status = iwl_mvm_get_wakeup_status(mvm, vif); + if (IS_ERR_OR_NULL(fw_status)) + goto out_unlock; status.pattern_number = le16_to_cpu(fw_status->pattern_number); for (i = 0; i < 8; i++) @@ -1563,17 +1589,12 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, le32_to_cpu(fw_status->wake_packet_bufsize); status.wake_packet = fw_status->wake_packet; - if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) { - IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); - goto out_free_resp; - } - /* still at hard-coded place 0 for D3 image */ ap_sta = rcu_dereference_protected( mvm->fw_id_to_mac_id[0], lockdep_is_held(&mvm->mutex)); if (IS_ERR_OR_NULL(ap_sta)) - goto out_free_resp; + goto out_free; mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; for (i = 0; i < IWL_MAX_TID_COUNT; i++) { @@ -1590,12 +1611,12 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status); - iwl_free_resp(&cmd); + kfree(fw_status); return keep; - out_free_resp: - iwl_free_resp(&cmd); - out_unlock: +out_free: + kfree(fw_status); +out_unlock: mutex_unlock(&mvm->mutex); return false; } -- GitLab From 2021a89d7b8a26d6fdc66daa51e414193b4cf568 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 20 Nov 2014 08:59:51 +0200 Subject: [PATCH 5937/9457] iwlwifi: mvm: treat netdetect wake up separately When the device wakes up due to netdetect, we need to query different things from the firmware than when it wakes up with a normal WoWLAN. To make this easier, separate the netdetect wake up handling from the rest. For now, we don't send netdetect as a wake up reason, treating it as a non-wireless wake up. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 40 ++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c72d2e98c3f1..176556ea63cb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1048,6 +1048,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mvm, wowlan, wowlan->nd_config ?: mvm->nd_config, vif); if (ret) goto out; + + mvm->net_detect = true; } else { struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; @@ -1067,6 +1069,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, vif, mvmvif, ap_sta); if (ret) goto out; + + mvm->net_detect = false; } ret = iwl_mvm_power_update_device(mvm); @@ -1621,6 +1625,32 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, return false; } +static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) +{ + struct cfg80211_wowlan_wakeup wakeup = { + .pattern_idx = -1, + }; + struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; + struct iwl_wowlan_status *fw_status; + u32 reasons = 0; + + fw_status = iwl_mvm_get_wakeup_status(mvm, vif); + if (!IS_ERR_OR_NULL(fw_status)) + reasons = le32_to_cpu(fw_status->wakeup_reasons); + + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) + wakeup.rfkill_release = true; + + if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { + /* TODO: read and check if it was netdetect */ + wakeup_report = NULL; + } + + mutex_unlock(&mvm->mutex); + ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); +} + static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) { #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1678,11 +1708,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* query SRAM first in case we want event logging */ iwl_mvm_read_d3_sram(mvm); - keep = iwl_mvm_query_wakeup_reasons(mvm, vif); + if (mvm->net_detect) { + iwl_mvm_query_netdetect_reasons(mvm, vif); + } else { + keep = iwl_mvm_query_wakeup_reasons(mvm, vif); #ifdef CONFIG_IWLWIFI_DEBUGFS - if (keep) - mvm->keep_vif = vif; + if (keep) + mvm->keep_vif = vif; #endif + } /* has unlocked the mutex, so skip that */ goto out; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 7c62f80414ae..e6079f4dc4e1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -685,6 +685,7 @@ struct iwl_mvm { /* sched scan settings for net detect */ struct cfg80211_sched_scan_request *nd_config; struct ieee80211_scan_ies nd_ies; + bool net_detect; #ifdef CONFIG_IWLWIFI_DEBUGFS u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ bool d3_test_active; -- GitLab From 8e551e503bdb6018ffcc72841de3360557dc3bcd Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 1 Oct 2014 15:21:28 +0300 Subject: [PATCH 5938/9457] iwlwifi: trans: add suspend/resume ops Add suspend/resume trans ops that will be called from mac80211's suspend/resume ops. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-trans.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0768f83e709d..0289803fa381 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -534,6 +534,8 @@ struct iwl_trans_ops { u32 value); void (*ref)(struct iwl_trans *trans); void (*unref)(struct iwl_trans *trans); + void (*suspend)(struct iwl_trans *trans); + void (*resume)(struct iwl_trans *trans); struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans); }; @@ -702,6 +704,18 @@ static inline void iwl_trans_unref(struct iwl_trans *trans) trans->ops->unref(trans); } +static inline void iwl_trans_suspend(struct iwl_trans *trans) +{ + if (trans->ops->suspend) + trans->ops->suspend(trans); +} + +static inline void iwl_trans_resume(struct iwl_trans *trans) +{ + if (trans->ops->resume) + trans->ops->resume(trans); +} + static inline struct iwl_trans_dump_data * iwl_trans_dump_data(struct iwl_trans *trans) { -- GitLab From 465921c841c538d58b1bc0bd16dbac57a5d8edb0 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 30 Sep 2014 10:02:13 +0300 Subject: [PATCH 5939/9457] iwlwifi: mvm: call iwl_trans_suspend/resume call the appropriate iwl_trans_suspend/resume ops on iwl_mvm_suspend/resume calls. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 176556ea63cb..60748bd37954 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1116,6 +1116,7 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + iwl_trans_suspend(mvm->trans); if (iwl_mvm_is_d0i3_supported(mvm)) { mutex_lock(&mvm->d0i3_suspend_mutex); __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); @@ -1739,6 +1740,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + iwl_trans_resume(mvm->trans); + if (iwl_mvm_is_d0i3_supported(mvm)) return 0; -- GitLab From 30269c125b4dc4530e76116baaeb0ed518601a96 Mon Sep 17 00:00:00 2001 From: Chaya Rachel Ivgy Date: Sat, 15 Nov 2014 21:08:29 +0200 Subject: [PATCH 5940/9457] iwlwifi: mvm: add support to MFUART loading notification Add support to MFUART loading notification (print notification data with IWL_DEBUG_INFO) Signed-off-by: Chaya Rachel Ivgy Reviewed-by: Emmanuel Grumbach Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 17 +++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw.c | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 1 + 4 files changed, 36 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 0f3c07a54bfe..2ff4f41d79bd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -201,6 +201,8 @@ enum { /* Power - new power table command */ MAC_PM_POWER_TABLE = 0xa9, + MFUART_LOAD_NOTIFICATION = 0xb1, + REPLY_RX_PHY_CMD = 0xc0, REPLY_RX_MPDU_CMD = 0xc1, BA_NOTIF = 0xc5, @@ -1211,6 +1213,21 @@ struct iwl_missed_beacons_notif { __le32 num_recvd_beacons; } __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */ +/** + * struct iwl_mfuart_load_notif - mfuart image version & status + * ( MFUART_LOAD_NOTIFICATION = 0xb1 ) + * @installed_ver: installed image version + * @external_ver: external image version + * @status: MFUART loading status + * @duration: MFUART loading time +*/ +struct iwl_mfuart_load_notif { + __le32 installed_ver; + __le32 external_ver; + __le32 status; + __le32 duration; +} __packed; /*MFU_LOADER_NTFY_API_S_VER_1*/ + /** * struct iwl_set_calib_default_cmd - set default value for calibration. * ( SET_CALIB_DEFAULT_CMD = 0x8e ) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 575779086a46..bbb78710f237 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -599,3 +599,19 @@ int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, le32_to_cpu(radio_version->radio_dash)); return 0; } + +int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_mfuart_load_notif *mfuart_notif = (void *)pkt->data; + + IWL_DEBUG_INFO(mvm, + "MFUART: installed ver: 0x%08x, external ver: 0x%08x, status: 0x%08x, duration: 0x%08x\n", + le32_to_cpu(mfuart_notif->installed_ver), + le32_to_cpu(mfuart_notif->external_ver), + le32_to_cpu(mfuart_notif->status), + le32_to_cpu(mfuart_notif->duration)); + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e6079f4dc4e1..2ab59b850795 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -964,6 +964,8 @@ int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd); int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); +int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); /* MVM PHY */ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index cc83ef54ed50..b3ae094db907 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -260,6 +260,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif, true), + RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, false), }; #undef RX_HANDLER -- GitLab From 339b30864edbcac656c9ffc9dc3544eca645fc8a Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 18 Nov 2014 16:43:55 +0200 Subject: [PATCH 5941/9457] iwlwifi: mvm: declare support for VHT BF info in radiotap The driver knows whether an rx frame was beamformed and marks it in the radiotap VHT flags. However it should also declare that it knows to extract this info otherwise this gets discarded by sniffers like Wireshark. Signed-off-by: Eyal Shapira Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index d9d8d30e605e..5dbf547ef02a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -323,7 +323,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC | IEEE80211_RADIOTAP_MCS_HAVE_STBC; - hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC; + hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | + IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; hw->rate_control_algorithm = "iwl-mvm-rs"; /* -- GitLab From e198f5e76f4d29a7fed4fd35f4d7dfbaea6a5c08 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 14 Sep 2014 19:13:54 +0300 Subject: [PATCH 5942/9457] iwlwifi: mvm: disconnect TDLS peers before channel switch In case of channel switch, we need to teardown the TDLS peers. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5dbf547ef02a..322d01b90c0e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3245,6 +3245,9 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, if (ret) goto out_unlock; + /* we won't be on this channel any longer */ + iwl_mvm_teardown_tdls_peers(mvm); + out_unlock: mutex_unlock(&mvm->mutex); -- GitLab From 47abce8f2d4a1fcbe1679b1fb8ab8f2aa7be7c98 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 25 Jun 2014 18:09:58 +0300 Subject: [PATCH 5943/9457] iwlwifi: declare d0i3 support for IWL_DEVICE_8000 Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-8000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 091975905cb6..436efad118b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -123,6 +123,7 @@ static const struct iwl_ht_params iwl8000_ht_params = { .base_params = &iwl8000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \ + .d0i3 = true, \ .non_shared_ant = ANT_A const struct iwl_cfg iwl8260_2n_cfg = { -- GitLab From 3c4e2998a4760438c617081bd644b4b7940b90af Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Tue, 14 Oct 2014 11:26:52 +0300 Subject: [PATCH 5944/9457] iwlwifi: sdio: new SDIO card id for 4165 series Add a new SDIO card id intended for the new 4165 series. Signed-off-by: Oren Givon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-8000.c | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-config.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 436efad118b4..d0357b37fd8f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -159,4 +159,19 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, }; +const struct iwl_cfg iwl4265_2ac_sdio_cfg = { + .name = "Intel(R) Dual Band Wireless-AC 4265", + .fw_name_pre = IWL8000_FW_PRE, + IWL_DEVICE_8000, + .ht_params = &iwl8000_ht_params, + .nvm_ver = IWL8000_NVM_VERSION, + .nvm_calib_ver = IWL8000_TX_POWER_VERSION, + .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, + .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, + .bt_shared_single_ant = true, + .disable_dummy_notification = true, + .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, + .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, +}; + MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index d43e90d894ec..e63cafa22ec6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -370,6 +370,7 @@ extern const struct iwl_cfg iwl7265d_n_cfg; extern const struct iwl_cfg iwl8260_2n_cfg; extern const struct iwl_cfg iwl8260_2ac_cfg; extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; +extern const struct iwl_cfg iwl4265_2ac_sdio_cfg; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ -- GitLab From dcad8e4299bf81f8795b44677036dfa490c9fb15 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 23 Nov 2014 21:39:50 +0200 Subject: [PATCH 5945/9457] iwlwifi: update the secure mem space and for the CPUs Also update the timeout for the data verification. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-prph.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 90011b13fc9c..1dae702e97ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -349,10 +349,10 @@ enum secure_load_status_reg { #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000) #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000) -#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) -#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) +#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x404000) +#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x405000) -#define LMPM_SECURE_TIME_OUT (100) +#define LMPM_SECURE_TIME_OUT (50000) /* 5 msec */ /* Rx FIFO */ #define RXF_SIZE_ADDR (0xa00c88) -- GitLab From 635c99070600ff04b4c1d5afe67f051631a8397c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 21 Oct 2014 14:12:49 +0200 Subject: [PATCH 5946/9457] MIPS: Remove useless parentheses Based on the spatch @@ expression e; @@ - return (e); + return e; with heavy hand editing because some of the changes are either whitespace or identation only or result in excessivly long lines. Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/cpu.c | 2 +- arch/mips/kernel/cpu-probe.c | 2 +- arch/mips/kernel/irq-gic.c | 2 +- arch/mips/kernel/process.c | 36 +++++++++++++------------- arch/mips/loongson/common/gpio.c | 2 +- arch/mips/math-emu/ieee754dp.c | 2 +- arch/mips/math-emu/ieee754sp.c | 2 +- arch/mips/mm/sc-r5k.c | 2 +- arch/mips/pci/ops-bcm63xx.c | 2 +- arch/mips/pmcs-msp71xx/msp_prom.c | 2 +- arch/mips/rb532/gpio.c | 2 +- arch/mips/sgi-ip22/ip22-mc.c | 6 ++--- arch/mips/sgi-ip22/ip28-berr.c | 6 ++--- arch/mips/sgi-ip27/ip27-klnuma.c | 5 ++-- arch/mips/sgi-ip27/ip27-memory.c | 5 ++-- arch/mips/sibyte/swarm/rtc_m41t81.c | 4 +-- arch/mips/sibyte/swarm/rtc_xicor1241.c | 4 +-- arch/mips/sibyte/swarm/setup.c | 2 +- 18 files changed, 42 insertions(+), 46 deletions(-) diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 536f64443031..307ec8b8e41c 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c @@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void) if (BCMCPU_IS_6345()) { val = bcm_sdram_readl(SDRAM_MBASE_REG); - return (val * 8 * 1024 * 1024); + return val * 8 * 1024 * 1024; } if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d5a4f380b019..793c86beffa2 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -140,7 +140,7 @@ static inline unsigned long cpu_get_fpu_id(void) */ static inline int __cpu_has_fpu(void) { - return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); + return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE; } static inline unsigned long cpu_get_msa_id(void) diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 9e9d8b9a5b97..582883069ef6 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -98,7 +98,7 @@ unsigned int gic_get_timer_pending(void) GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending); - return (vpe_pending & GIC_VPE_PEND_TIMER_MSK); + return vpe_pending & GIC_VPE_PEND_TIMER_MSK; } void gic_bind_eic_interrupt(int irq, int set) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 636b0745d7c7..d0e77b2470cb 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -187,21 +187,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip) */ if (mm_insn_16bit(ip->halfword[0])) { mmi.word = (ip->halfword[0] << 16); - return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && - mmi.mm16_r5_format.rt == 31) || - (mmi.mm16_m_format.opcode == mm_pool16c_op && - mmi.mm16_m_format.func == mm_swm16_op)); + return (mmi.mm16_r5_format.opcode == mm_swsp16_op && + mmi.mm16_r5_format.rt == 31) || + (mmi.mm16_m_format.opcode == mm_pool16c_op && + mmi.mm16_m_format.func == mm_swm16_op); } else { mmi.halfword[0] = ip->halfword[1]; mmi.halfword[1] = ip->halfword[0]; - return ((mmi.mm_m_format.opcode == mm_pool32b_op && - mmi.mm_m_format.rd > 9 && - mmi.mm_m_format.base == 29 && - mmi.mm_m_format.func == mm_swm32_func) || - (mmi.i_format.opcode == mm_sw32_op && - mmi.i_format.rs == 29 && - mmi.i_format.rt == 31)); + return (mmi.mm_m_format.opcode == mm_pool32b_op && + mmi.mm_m_format.rd > 9 && + mmi.mm_m_format.base == 29 && + mmi.mm_m_format.func == mm_swm32_func) || + (mmi.i_format.opcode == mm_sw32_op && + mmi.i_format.rs == 29 && + mmi.i_format.rt == 31); } #else /* sw / sd $ra, offset($sp) */ @@ -233,7 +233,7 @@ static inline int is_jump_ins(union mips_instruction *ip) if (ip->r_format.opcode != mm_pool32a_op || ip->r_format.func != mm_pool32axf_op) return 0; - return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); + return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op; #else if (ip->j_format.opcode == j_op) return 1; @@ -260,13 +260,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip) union mips_instruction mmi; mmi.word = (ip->halfword[0] << 16); - return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && - mmi.mm16_r3_format.simmediate && mm_addiusp_func) || - (mmi.mm16_r5_format.opcode == mm_pool16d_op && - mmi.mm16_r5_format.rt == 29)); + return (mmi.mm16_r3_format.opcode == mm_pool16d_op && + mmi.mm16_r3_format.simmediate && mm_addiusp_func) || + (mmi.mm16_r5_format.opcode == mm_pool16d_op && + mmi.mm16_r5_format.rt == 29); } - return (ip->mm_i_format.opcode == mm_addiu32_op && - ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); + return ip->mm_i_format.opcode == mm_addiu32_op && + ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; #else /* addiu/daddiu sp,sp,-imm */ if (ip->i_format.rs != 29 || ip->i_format.rt != 29) diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c index 21869908aaa4..29dbaa253061 100644 --- a/arch/mips/loongson/common/gpio.c +++ b/arch/mips/loongson/common/gpio.c @@ -37,7 +37,7 @@ int gpio_get_value(unsigned gpio) val = LOONGSON_GPIODATA; spin_unlock(&gpio_lock); - return ((val & mask) != 0); + return (val & mask) != 0; } EXPORT_SYMBOL(gpio_get_value); diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index fd134675fc2e..068f45a415fc 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c @@ -38,7 +38,7 @@ int ieee754dp_isnan(union ieee754dp x) static inline int ieee754dp_issnan(union ieee754dp x) { assert(ieee754dp_isnan(x)); - return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1)); + return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1); } diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index d348efe91445..ba88301579c2 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c @@ -38,7 +38,7 @@ int ieee754sp_isnan(union ieee754sp x) static inline int ieee754sp_issnan(union ieee754sp x) { assert(ieee754sp_isnan(x)); - return (SPMANT(x) & SP_MBIT(SP_FBITS-1)); + return SPMANT(x) & SP_MBIT(SP_FBITS - 1); } diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index 0216ed6eaa2a..751b5cd18bf2 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c @@ -81,7 +81,7 @@ static inline int __init r5k_sc_probe(void) unsigned long config = read_c0_config(); if (config & CONF_SC) - return(0); + return 0; scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c index 13eea696bbe7..d02eb9d16b55 100644 --- a/arch/mips/pci/ops-bcm63xx.c +++ b/arch/mips/pci/ops-bcm63xx.c @@ -469,7 +469,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) { switch (bus->number) { case PCIE_BUS_BRIDGE: - return (PCI_SLOT(devfn) == 0); + return PCI_SLOT(devfn) == 0; case PCIE_BUS_DEVICE: if (PCI_SLOT(devfn) == 0) return bcm_pcie_readl(PCIE_DLSTATUS_REG) diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c index 1c9897531660..ef620a4c82a5 100644 --- a/arch/mips/pmcs-msp71xx/msp_prom.c +++ b/arch/mips/pmcs-msp71xx/msp_prom.c @@ -295,7 +295,7 @@ char *prom_getenv(char *env_name) while (*var) { if (strncmp(env_name, *var, i) == 0) { - return (*var + strlen(env_name) + 1); + return *var + strlen(env_name) + 1; } var++; } diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index a18007613c30..5aa3df853082 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c @@ -79,7 +79,7 @@ static inline void rb532_set_bit(unsigned bitval, */ static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) { - return (readl(ioaddr) & (1 << offset)); + return readl(ioaddr) & (1 << offset); } /* diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 7cec0a4e527d..6b009c45abed 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c @@ -24,14 +24,12 @@ EXPORT_SYMBOL(sgimc); static inline unsigned long get_bank_addr(unsigned int memconfig) { - return ((memconfig & SGIMC_MCONFIG_BASEADDR) << - ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); + return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22); } static inline unsigned long get_bank_size(unsigned int memconfig) { - return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << - ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); + return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); } static inline unsigned int get_bank_config(int bank) diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index 3f47346608d7..712cc0f6a58d 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c @@ -338,7 +338,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) PHYS_TO_XKSEG_UNCACHED(pte); a = (a & 0x3f) << 6; /* PFN */ a += vaddr & ((1 << pgsz) - 1); - return (cpu_err_addr == a); + return cpu_err_addr == a; } } } @@ -351,7 +351,7 @@ static int check_vdma_memaddr(void) u32 a = sgimc->maddronly; if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ - return (cpu_err_addr == a); + return cpu_err_addr == a; if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || @@ -367,7 +367,7 @@ static int check_vdma_gioaddr(void) if (gio_err_stat & GIO_ERRMASK) { u32 a = sgimc->gio_dma_trans; a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); - return (gio_err_addr == a); + return gio_err_addr == a; } return 0; } diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 7a53b1e28a93..ecbb62f339c5 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c @@ -125,8 +125,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode) #endif offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) - return (TO_NODE(nasid, offset) >> PAGE_SHIFT); + return TO_NODE(nasid, offset) >> PAGE_SHIFT; else - return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> - PAGE_SHIFT); + return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT; } diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index a304bcc37e4f..0b68469e063f 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c @@ -42,8 +42,7 @@ static int fine_mode; static int is_fine_dirmode(void) { - return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) - >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); + return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; } static hubreg_t get_region(cnodeid_t cnode) @@ -288,7 +287,7 @@ static unsigned long __init slot_psize_compute(cnodeid_t node, int slot) if (size <= 128) { if (slot % 4 == 0) { size <<= 20; /* size in bytes */ - return(size >> PAGE_SHIFT); + return size >> PAGE_SHIFT; } else return 0; } else { diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c index b732600b47f5..e62466445f08 100644 --- a/arch/mips/sibyte/swarm/rtc_m41t81.c +++ b/arch/mips/sibyte/swarm/rtc_m41t81.c @@ -109,7 +109,7 @@ static int m41t81_read(uint8_t addr) return -1; } - return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); + return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; } static int m41t81_write(uint8_t addr, int b) @@ -229,5 +229,5 @@ int m41t81_probe(void) tmp = m41t81_read(M41T81REG_SC); m41t81_write(M41T81REG_SC, tmp & 0x7f); - return (m41t81_read(M41T81REG_SC) != -1); + return m41t81_read(M41T81REG_SC) != -1; } diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c index 178a824b28d4..50a82c495427 100644 --- a/arch/mips/sibyte/swarm/rtc_xicor1241.c +++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c @@ -84,7 +84,7 @@ static int xicor_read(uint8_t addr) return -1; } - return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); + return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; } static int xicor_write(uint8_t addr, int b) @@ -206,5 +206,5 @@ unsigned long xicor_get_time(void) int xicor_probe(void) { - return (xicor_read(X1241REG_SC) != -1); + return xicor_read(X1241REG_SC) != -1; } diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 3462c831d0ea..494fb0a475ac 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c @@ -76,7 +76,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) printk("DBE physical address: %010Lx\n", __read_64bit_c0_register($26, 1)); } - return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); + return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; } enum swarm_rtc_type { -- GitLab From 856839b76836a2ee524a8638f568275da57f719c Mon Sep 17 00:00:00 2001 From: Eunbong Song Date: Wed, 22 Oct 2014 06:39:56 +0000 Subject: [PATCH 5947/9457] MIPS: Add arch_trigger_all_cpu_backtrace() function Currently, arch_trigger_all_cpu_backtrace() is defined in only x86 and sparc which have an NMI. But in case of softlockup, it could be possible to dump backtrace of all cpus. and this could be helpful for debugging. for example, if system has 2 cpus. CPU 0 CPU 1 acquire read_lock() try to do write_lock() ,,, missing read_unlock() In this case, softlockup will occur becasuse CPU 0 does not call read_unlock(). And dump_stack() print only backtrace for "CPU 0". If CPU1's backtrace is printed it's very helpful. [ralf@linux-mips.org: Fixed whitespace and formatting issues.] Signed-off-by: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8200/ --- arch/mips/include/asm/irq.h | 3 +++ arch/mips/kernel/process.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 39f07aec640c..5a4e1bb8fb1b 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -48,4 +48,7 @@ extern int cp0_compare_irq; extern int cp0_compare_irq_shift; extern int cp0_perfcount_irq; +void arch_trigger_all_cpu_backtrace(bool); +#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace + #endif /* _ASM_IRQ_H */ diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index d0e77b2470cb..eb76434828e8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_HOTPLUG_CPU void arch_cpu_idle_dead(void) @@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp) return sp & ALMASK; } + +static void arch_dump_stack(void *info) +{ + struct pt_regs *regs; + + regs = get_irq_regs(); + + if (regs) + show_regs(regs); + + dump_stack(); +} + +void arch_trigger_all_cpu_backtrace(bool include_self) +{ + smp_call_function(arch_dump_stack, NULL, 1); +} -- GitLab From 6ff9c2fcfaedd6d60a060e7b478f35b9b9193fed Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Sat, 30 Aug 2014 06:06:24 +0400 Subject: [PATCH 5948/9457] MIPS: NILE4: Remove odd locking in PCI config space access code Caller (generic PCI code) already do proper locking so no need to add another one here. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/7600/ Signed-off-by: Ralf Baechle --- arch/mips/pci/ops-nile4.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c index a1a7c9f4096e..b9d1fd0ff7e2 100644 --- a/arch/mips/pci/ops-nile4.c +++ b/arch/mips/pci/ops-nile4.c @@ -13,8 +13,6 @@ volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; -static DEFINE_SPINLOCK(nile4_pci_lock); - static int nile4_pcibios_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, int where, u32 *val) { @@ -76,7 +74,6 @@ static int nile4_pcibios_config_access(unsigned char access_type, static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - unsigned long flags; u32 data = 0; int err; @@ -85,11 +82,8 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; - spin_lock_irqsave(&nile4_pci_lock, flags); err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, - &data); - spin_unlock_irqrestore(&nile4_pci_lock, flags); - + &data); if (err) return err; @@ -106,7 +100,6 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - unsigned long flags; u32 data = 0; int err; @@ -115,11 +108,8 @@ static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; - spin_lock_irqsave(&nile4_pci_lock, flags); err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data); - spin_unlock_irqrestore(&nile4_pci_lock, flags); - if (err) return err; -- GitLab From c4a305374bbf36414515d2ae00d588c67051e67d Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Sat, 30 Aug 2014 06:06:25 +0400 Subject: [PATCH 5949/9457] MIPS: MSP71xx: remove odd locking in PCI config space access code Caller (generic PCI code) already do proper locking so no need to add another one here. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/7601/ Signed-off-by: Ralf Baechle --- arch/mips/pci/ops-pmcmsp.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 50034f985be1..dd2d9f7e9412 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -193,8 +193,6 @@ static void pci_proc_init(void) } #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ -static DEFINE_SPINLOCK(bpci_lock); - /***************************************************************************** * * STRUCT: pci_io_resource @@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type, struct msp_pci_regs *preg = (void *)PCI_BASE_REG; unsigned char bus_num = bus->number; unsigned char dev_fn = (unsigned char)devfn; - unsigned long flags; unsigned long intr; unsigned long value; static char pciirqflag; @@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type, } #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) - local_irq_save(flags); vpe_status = dvpe(); -#else - spin_lock_irqsave(&bpci_lock, flags); #endif /* @@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type, #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) evpe(vpe_status); - local_irq_restore(flags); -#else - spin_unlock_irqrestore(&bpci_lock, flags); #endif return -1; @@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type, #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) evpe(vpe_status); - local_irq_restore(flags); -#else - spin_unlock_irqrestore(&bpci_lock, flags); #endif return PCIBIOS_SUCCESSFUL; -- GitLab From 490a0ece6c9d7c39c1e6b523ee488f1c913aace7 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Sat, 30 Aug 2014 06:06:26 +0400 Subject: [PATCH 5950/9457] MIPS: pci-ar7{1x, 24}x: remove odd locking in PCI config space access code Caller (generic PCI code) already do proper locking so no need to add another one here. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Cc: Gabor Juhos Patchwork: https://patchwork.linux-mips.org/patch/7602/ Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-ar71xx.c | 13 ------------- arch/mips/pci/pci-ar724x.c | 23 ----------------------- 2 files changed, 36 deletions(-) diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index d471a26dd5f8..2b534aea20e4 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -50,7 +50,6 @@ struct ar71xx_pci_controller { void __iomem *cfg_base; - spinlock_t lock; int irq; int irq_base; struct pci_controller pci_ctrl; @@ -182,7 +181,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, { struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); void __iomem *base = apc->cfg_base; - unsigned long flags; u32 data; int err; int ret; @@ -190,8 +188,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, ret = PCIBIOS_SUCCESSFUL; data = ~0; - spin_lock_irqsave(&apc->lock, flags); - err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, AR71XX_PCI_CFG_CMD_READ); if (err) @@ -199,8 +195,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, else data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); - spin_unlock_irqrestore(&apc->lock, flags); - *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; return ret; @@ -211,15 +205,12 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, { struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); void __iomem *base = apc->cfg_base; - unsigned long flags; int err; int ret; value = value << (8 * (where & 3)); ret = PCIBIOS_SUCCESSFUL; - spin_lock_irqsave(&apc->lock, flags); - err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, AR71XX_PCI_CFG_CMD_WRITE); if (err) @@ -227,8 +218,6 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, else __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); - spin_unlock_irqrestore(&apc->lock, flags); - return ret; } @@ -360,8 +349,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev) if (!apc) return -ENOMEM; - spin_lock_init(&apc->lock); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(apc->cfg_base)) diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 785b2659b519..b7a6fcbb8852 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -9,7 +9,6 @@ * by the Free Software Foundation. */ -#include #include #include #include @@ -48,8 +47,6 @@ struct ar724x_pci_controller { bool bar0_is_cached; u32 bar0_value; - spinlock_t lock; - struct pci_controller pci_controller; struct resource io_res; struct resource mem_res; @@ -75,7 +72,6 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus) static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, int where, int size, u32 value) { - unsigned long flags; void __iomem *base; u32 data; int s; @@ -86,8 +82,6 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, return PCIBIOS_DEVICE_NOT_FOUND; base = apc->crp_base; - - spin_lock_irqsave(&apc->lock, flags); data = __raw_readl(base + (where & ~3)); switch (size) { @@ -105,14 +99,12 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, data = value; break; default: - spin_unlock_irqrestore(&apc->lock, flags); return PCIBIOS_BAD_REGISTER_NUMBER; } __raw_writel(data, base + (where & ~3)); /* flush write */ __raw_readl(base + (where & ~3)); - spin_unlock_irqrestore(&apc->lock, flags); return PCIBIOS_SUCCESSFUL; } @@ -121,7 +113,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, uint32_t *value) { struct ar724x_pci_controller *apc; - unsigned long flags; void __iomem *base; u32 data; @@ -133,8 +124,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_DEVICE_NOT_FOUND; base = apc->devcfg_base; - - spin_lock_irqsave(&apc->lock, flags); data = __raw_readl(base + (where & ~3)); switch (size) { @@ -153,13 +142,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, case 4: break; default: - spin_unlock_irqrestore(&apc->lock, flags); - return PCIBIOS_BAD_REGISTER_NUMBER; } - spin_unlock_irqrestore(&apc->lock, flags); - if (where == PCI_BASE_ADDRESS_0 && size == 4 && apc->bar0_is_cached) { /* use the cached value */ @@ -175,7 +160,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, uint32_t value) { struct ar724x_pci_controller *apc; - unsigned long flags; void __iomem *base; u32 data; int s; @@ -209,8 +193,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, } base = apc->devcfg_base; - - spin_lock_irqsave(&apc->lock, flags); data = __raw_readl(base + (where & ~3)); switch (size) { @@ -228,15 +210,12 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, data = value; break; default: - spin_unlock_irqrestore(&apc->lock, flags); - return PCIBIOS_BAD_REGISTER_NUMBER; } __raw_writel(data, base + (where & ~3)); /* flush write */ __raw_readl(base + (where & ~3)); - spin_unlock_irqrestore(&apc->lock, flags); return PCIBIOS_SUCCESSFUL; } @@ -380,8 +359,6 @@ static int ar724x_pci_probe(struct platform_device *pdev) if (apc->irq < 0) return -EINVAL; - spin_lock_init(&apc->lock); - res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); if (!res) return -EINVAL; -- GitLab From e5067c718b3a6ecc00351861b3655d8cdeb0b6d2 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Sat, 30 Aug 2014 06:06:27 +0400 Subject: [PATCH 5951/9457] MIPS: pci-rt3883: Remove odd locking in PCI config space access code Caller (generic PCI code) already do proper locking so no need to add another one here. Local PCI read/write functions are never called simultaneously, also they do not require synchronization with the PCI controller ops, since they are used before the controller registration. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Cc: Gabor Juhos Patchwork: https://patchwork.linux-mips.org/patch/7603/ Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-rt3883.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 72919aeef42b..0bcc0b1cfddc 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -61,7 +61,6 @@ struct rt3883_pci_controller { void __iomem *base; - spinlock_t lock; struct device_node *intc_of_node; struct irq_domain *irq_domain; @@ -111,10 +110,8 @@ static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); - spin_lock_irqsave(&rpc->lock, flags); rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); - spin_unlock_irqrestore(&rpc->lock, flags); return ret; } @@ -128,10 +125,8 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); - spin_lock_irqsave(&rpc->lock, flags); rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); - spin_unlock_irqrestore(&rpc->lock, flags); } static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) @@ -252,10 +247,8 @@ static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where); - spin_lock_irqsave(&rpc->lock, flags); rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); - spin_unlock_irqrestore(&rpc->lock, flags); switch (size) { case 1: @@ -288,7 +281,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where); - spin_lock_irqsave(&rpc->lock, flags); rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); @@ -307,7 +299,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, } rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); - spin_unlock_irqrestore(&rpc->lock, flags); return PCIBIOS_SUCCESSFUL; } -- GitLab From 7178d2cdd9f5f70902dd0201ebcf01c9489c4afb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 4 Oct 2014 09:50:42 -0700 Subject: [PATCH 5952/9457] mips: Convert pr_warning to pr_warn Use the much more common pr_warn instead of pr_warning with the goal of removing pr_warning eventually. Other miscellanea: o Coalesce formats o Realign arguments Signed-off-by: Joe Perches Cc: linux-mips Cc: LKML Patchwork: https://patchwork.linux-mips.org/patch/7935/ Signed-off-by: Ralf Baechle --- arch/mips/ar7/platform.c | 24 ++++----- arch/mips/include/asm/octeon/cvmx-pow.h | 69 ++++++++++--------------- arch/mips/kernel/crash_dump.c | 4 +- arch/mips/kernel/perf_event_mipsxx.c | 7 ++- arch/mips/kernel/setup.c | 2 +- arch/mips/pci/pci-tx4939.c | 2 +- arch/mips/txx9/generic/setup_tx4927.c | 4 +- arch/mips/txx9/generic/setup_tx4938.c | 4 +- arch/mips/txx9/generic/setup_tx4939.c | 4 +- 9 files changed, 52 insertions(+), 68 deletions(-) diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 7e2356fd5fd6..af2441dbfc12 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr) &dev_addr[0], &dev_addr[1], &dev_addr[2], &dev_addr[3], &dev_addr[4], &dev_addr[5]) != 6) { - pr_warning("cannot parse mac address, " - "using random address\n"); + pr_warn("cannot parse mac address, using random address\n"); eth_random_addr(dev_addr); } } else @@ -665,7 +664,7 @@ static int __init ar7_register_devices(void) res = platform_device_register(&physmap_flash); if (res) - pr_warning("unable to register physmap-flash: %d\n", res); + pr_warn("unable to register physmap-flash: %d\n", res); if (ar7_is_titan()) titan_fixup_devices(); @@ -673,13 +672,13 @@ static int __init ar7_register_devices(void) ar7_device_disable(vlynq_low_data.reset_bit); res = platform_device_register(&vlynq_low); if (res) - pr_warning("unable to register vlynq-low: %d\n", res); + pr_warn("unable to register vlynq-low: %d\n", res); if (ar7_has_high_vlynq()) { ar7_device_disable(vlynq_high_data.reset_bit); res = platform_device_register(&vlynq_high); if (res) - pr_warning("unable to register vlynq-high: %d\n", res); + pr_warn("unable to register vlynq-high: %d\n", res); } if (ar7_has_high_cpmac()) { @@ -689,9 +688,10 @@ static int __init ar7_register_devices(void) res = platform_device_register(&cpmac_high); if (res) - pr_warning("unable to register cpmac-high: %d\n", res); + pr_warn("unable to register cpmac-high: %d\n", + res); } else - pr_warning("unable to add cpmac-high phy: %d\n", res); + pr_warn("unable to add cpmac-high phy: %d\n", res); } else cpmac_low_data.phy_mask = 0xffffffff; @@ -700,18 +700,18 @@ static int __init ar7_register_devices(void) cpmac_get_mac(0, cpmac_low_data.dev_addr); res = platform_device_register(&cpmac_low); if (res) - pr_warning("unable to register cpmac-low: %d\n", res); + pr_warn("unable to register cpmac-low: %d\n", res); } else - pr_warning("unable to add cpmac-low phy: %d\n", res); + pr_warn("unable to add cpmac-low phy: %d\n", res); detect_leds(); res = platform_device_register(&ar7_gpio_leds); if (res) - pr_warning("unable to register leds: %d\n", res); + pr_warn("unable to register leds: %d\n", res); res = platform_device_register(&ar7_udc); if (res) - pr_warning("unable to register usb slave: %d\n", res); + pr_warn("unable to register usb slave: %d\n", res); /* Register watchdog only if enabled in hardware */ bootcr = ioremap_nocache(AR7_REGS_DCL, 4); @@ -726,7 +726,7 @@ static int __init ar7_register_devices(void) ar7_wdt_res.end = ar7_wdt_res.start + 0x20; res = platform_device_register(&ar7_wdt); if (res) - pr_warning("unable to register watchdog: %d\n", res); + pr_warn("unable to register watchdog: %d\n", res); } return 0; diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h index 4b4d0ecfd9eb..2188e65afb86 100644 --- a/arch/mips/include/asm/octeon/cvmx-pow.h +++ b/arch/mips/include/asm/octeon/cvmx-pow.h @@ -1066,7 +1066,7 @@ static inline void __cvmx_pow_warn_if_pending_switch(const char *function) uint64_t switch_complete; CVMX_MF_CHORD(switch_complete); if (!switch_complete) - pr_warning("%s called with tag switch in progress\n", function); + pr_warn("%s called with tag switch in progress\n", function); } /** @@ -1084,8 +1084,7 @@ static inline void cvmx_pow_tag_sw_wait(void) if (unlikely(switch_complete)) break; if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { - pr_warning("Tag switch is taking a long time, " - "possible deadlock\n"); + pr_warn("Tag switch is taking a long time, possible deadlock\n"); start_cycle = -MAX_CYCLES - 1; } } @@ -1296,19 +1295,16 @@ static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, __cvmx_pow_warn_if_pending_switch(__func__); current_tag = cvmx_pow_get_current_tag(); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) - pr_warning("%s called with NULL_NULL tag\n", - __func__); + pr_warn("%s called with NULL_NULL tag\n", __func__); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called with NULL tag\n", __func__); + pr_warn("%s called with NULL tag\n", __func__); if ((current_tag.s.type == tag_type) && (current_tag.s.tag == tag)) - pr_warning("%s called to perform a tag switch to the " - "same tag\n", - __func__); + pr_warn("%s called to perform a tag switch to the same tag\n", + __func__); if (tag_type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called to perform a tag switch to " - "NULL. Use cvmx_pow_tag_sw_null() instead\n", - __func__); + pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", + __func__); } /* @@ -1407,23 +1403,19 @@ static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag, __cvmx_pow_warn_if_pending_switch(__func__); current_tag = cvmx_pow_get_current_tag(); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) - pr_warning("%s called with NULL_NULL tag\n", - __func__); + pr_warn("%s called with NULL_NULL tag\n", __func__); if ((current_tag.s.type == tag_type) && (current_tag.s.tag == tag)) - pr_warning("%s called to perform a tag switch to " - "the same tag\n", - __func__); + pr_warn("%s called to perform a tag switch to the same tag\n", + __func__); if (tag_type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called to perform a tag switch to " - "NULL. Use cvmx_pow_tag_sw_null() instead\n", - __func__); + pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", + __func__); if (wqp != cvmx_phys_to_ptr(0x80)) if (wqp != cvmx_pow_get_current_wqp()) - pr_warning("%s passed WQE(%p) doesn't match " - "the address in the POW(%p)\n", - __func__, wqp, - cvmx_pow_get_current_wqp()); + pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", + __func__, wqp, + cvmx_pow_get_current_wqp()); } /* @@ -1507,12 +1499,10 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void) __cvmx_pow_warn_if_pending_switch(__func__); current_tag = cvmx_pow_get_current_tag(); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) - pr_warning("%s called with NULL_NULL tag\n", - __func__); + pr_warn("%s called with NULL_NULL tag\n", __func__); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called when we already have a " - "NULL tag\n", - __func__); + pr_warn("%s called when we already have a NULL tag\n", + __func__); } tag_req.u64 = 0; @@ -1725,17 +1715,14 @@ static inline void cvmx_pow_tag_sw_desched_nocheck( __cvmx_pow_warn_if_pending_switch(__func__); current_tag = cvmx_pow_get_current_tag(); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) - pr_warning("%s called with NULL_NULL tag\n", - __func__); + pr_warn("%s called with NULL_NULL tag\n", __func__); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called with NULL tag. Deschedule not " - "allowed from NULL state\n", - __func__); + pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", + __func__); if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) - pr_warning("%s called where neither the before or " - "after tag is ATOMIC\n", - __func__); + pr_warn("%s called where neither the before or after tag is ATOMIC\n", + __func__); } tag_req.u64 = 0; @@ -1832,12 +1819,10 @@ static inline void cvmx_pow_desched(uint64_t no_sched) __cvmx_pow_warn_if_pending_switch(__func__); current_tag = cvmx_pow_get_current_tag(); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) - pr_warning("%s called with NULL_NULL tag\n", - __func__); + pr_warn("%s called with NULL_NULL tag\n", __func__); if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) - pr_warning("%s called with NULL tag. Deschedule not " - "expected from NULL state\n", - __func__); + pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", + __func__); } /* Need to make sure any writes to the work queue entry are complete */ diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index f291cf99b03a..6fe7790e5868 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c @@ -38,7 +38,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, kunmap_atomic(vaddr); } else { if (!kdump_buf_page) { - pr_warning("Kdump: Kdump buffer page not allocated\n"); + pr_warn("Kdump: Kdump buffer page not allocated\n"); return -EFAULT; } @@ -57,7 +57,7 @@ static int __init kdump_buf_page_init(void) kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!kdump_buf_page) { - pr_warning("Kdump: Failed to allocate kdump buffer page\n"); + pr_warn("Kdump: Failed to allocate kdump buffer page\n"); ret = -ENOMEM; } diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index a8f9cdc6f8b0..7633d30550e9 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -561,8 +561,8 @@ static int mipspmu_get_irq(void) IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, "mips_perf_pmu", NULL); if (err) { - pr_warning("Unable to request IRQ%d for MIPS " - "performance counters!\n", mipspmu.irq); + pr_warn("Unable to request IRQ%d for MIPS performance counters!\n", + mipspmu.irq); } } else if (cp0_perfcount_irq < 0) { /* @@ -572,8 +572,7 @@ static int mipspmu_get_irq(void) perf_irq = mipsxx_pmu_handle_shared_irq; err = 0; } else { - pr_warning("The platform hasn't properly defined its " - "interrupt controller.\n"); + pr_warn("The platform hasn't properly defined its interrupt controller\n"); err = -ENOENT; } diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index d21ec57b6e95..eacfd7dbe8cc 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -89,7 +89,7 @@ void __init add_memory_region(phys_t start, phys_t size, long type) /* Sanity check */ if (start + size < start) { - pr_warning("Trying to add an invalid memory region, skipped\n"); + pr_warn("Trying to add an invalid memory region, skipped\n"); return; } diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c index c10fbf2a19dc..cd8ed09c4f53 100644 --- a/arch/mips/pci/pci-tx4939.c +++ b/arch/mips/pci/pci-tx4939.c @@ -103,5 +103,5 @@ void __init tx4939_setup_pcierr_irq(void) tx4927_pcierr_interrupt, 0, "PCI error", (void *)TX4939_PCIC_REG)) - pr_warning("Failed to request irq for PCIERR\n"); + pr_warn("Failed to request irq for PCIERR\n"); } diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index e714d6ce9a82..a4664cb6c1e1 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -29,8 +29,8 @@ static void __init tx4927_wdr_init(void) { /* report watchdog reset status */ if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) - pr_warning("Watchdog reset detected at 0x%lx\n", - read_c0_errorepc()); + pr_warn("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); /* clear WatchDogReset (W1C) */ tx4927_ccfg_set(TX4927_CCFG_WDRST); /* do reset on watchdog */ diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 0a3bf2dfaba1..58cdb2aba5e1 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -31,8 +31,8 @@ static void __init tx4938_wdr_init(void) { /* report watchdog reset status */ if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) - pr_warning("Watchdog reset detected at 0x%lx\n", - read_c0_errorepc()); + pr_warn("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); /* clear WatchDogReset (W1C) */ tx4938_ccfg_set(TX4938_CCFG_WDRST); /* do reset on watchdog */ diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index b7eccbd17bf7..e3733cde50d6 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -35,8 +35,8 @@ static void __init tx4939_wdr_init(void) { /* report watchdog reset status */ if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) - pr_warning("Watchdog reset detected at 0x%lx\n", - read_c0_errorepc()); + pr_warn("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); /* clear WatchDogReset (W1C) */ tx4939_ccfg_set(TX4939_CCFG_WDRST); /* do reset on watchdog */ -- GitLab From 97f4ad29dae24861dc08bfea48b1b446fc195d99 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Fri, 29 Aug 2014 09:37:26 +0100 Subject: [PATCH 5953/9457] MIPS: cpu: Add 'noftlb' kernel command line option to disable the FTLB Add new 'noftlb' kernel command line option to disable the FTLB. Since the kernel command line is not available when probing and enabling the CPU features in cpu_probe(), we let the kernel configure the FTLB during the config4 decode operation and we disable the FTLB later on, once the command line has become available to us. This should have no negative effects since FTLB isn't used so early in the boot process. FTLB increases the effective TLB size leading to less TLB misses. However, sometimes it's useful to be able to disable it when debugging memory related core features or other hardware components. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/7586/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 64 ++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 793c86beffa2..b27e7ffd1112 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -69,6 +69,63 @@ static int __init htw_disable(char *s) __setup("nohtw", htw_disable); +static int mips_ftlb_disabled; +static int mips_has_ftlb_configured; + +static void set_ftlb_enable(struct cpuinfo_mips *c, int enable); + +static int __init ftlb_disable(char *s) +{ + unsigned int config4, mmuextdef; + + /* + * If the core hasn't done any FTLB configuration, there is nothing + * for us to do here. + */ + if (!mips_has_ftlb_configured) + return 1; + + /* Disable it in the boot cpu */ + set_ftlb_enable(&cpu_data[0], 0); + + back_to_back_c0_hazard(); + + config4 = read_c0_config4(); + + /* Check that FTLB has been disabled */ + mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; + /* MMUSIZEEXT == VTLB ON, FTLB OFF */ + if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) { + /* This should never happen */ + pr_warn("FTLB could not be disabled!\n"); + return 1; + } + + mips_ftlb_disabled = 1; + mips_has_ftlb_configured = 0; + + /* + * noftlb is mainly used for debug purposes so print + * an informative message instead of using pr_debug() + */ + pr_info("FTLB has been disabled\n"); + + /* + * Some of these bits are duplicated in the decode_config4. + * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case + * once FTLB has been disabled so undo what decode_config4 did. + */ + cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways * + cpu_data[0].tlbsizeftlbsets; + cpu_data[0].tlbsizeftlbsets = 0; + cpu_data[0].tlbsizeftlbways = 0; + + return 1; +} + +__setup("noftlb", ftlb_disable); + + static inline void check_errata(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -368,6 +425,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; /* fall through */ case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: + if (mips_ftlb_disabled) + break; newcf4 = (config4 & ~ftlb_page) | (page_size_ftlb(mmuextdef) << MIPS_CONF4_FTLBPAGESIZE_SHIFT); @@ -387,6 +446,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> MIPS_CONF4_FTLBWAYS_SHIFT) + 2; c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; + mips_has_ftlb_configured = 1; break; } } @@ -422,8 +482,8 @@ static void decode_configs(struct cpuinfo_mips *c) c->scache.flags = MIPS_CACHE_NOT_PRESENT; - /* Enable FTLB if present */ - set_ftlb_enable(c, 1); + /* Enable FTLB if present and not disabled */ + set_ftlb_enable(c, !mips_ftlb_disabled); ok = decode_config0(c); /* Read Config registers. */ BUG_ON(!ok); /* Arch spec violation! */ -- GitLab From 0f84c305351c993e4307e1e8c128d44760314e31 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:07 -0700 Subject: [PATCH 5954/9457] MIPS: Always use IRQ domains for CPU IRQs Use an IRQ domain for the 8 CPU IRQs in both the DT and non-DT cases. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7799/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/kernel/irq_cpu.c | 36 +++++++++++------------------------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f43aa536c517..92033b7e275b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1055,6 +1055,7 @@ config MIPS_HUGE_TLB_SUPPORT config IRQ_CPU bool + select IRQ_DOMAIN config IRQ_CPU_RM7K bool diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index e498f2b3646a..b097f7df7a29 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -94,28 +94,6 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .irq_eoi = unmask_mips_irq, }; -void __init mips_cpu_irq_init(void) -{ - int irq_base = MIPS_CPU_IRQ_BASE; - int i; - - /* Mask interrupts. */ - clear_c0_status(ST0_IM); - clear_c0_cause(CAUSEF_IP); - - /* Software interrupts are used for MT/CMT IPI */ - for (i = irq_base; i < irq_base + 2; i++) - irq_set_chip_and_handler(i, cpu_has_mipsmt ? - &mips_mt_cpu_irq_controller : - &mips_cpu_irq_controller, - handle_percpu_irq); - - for (i = irq_base + 2; i < irq_base + 8; i++) - irq_set_chip_and_handler(i, &mips_cpu_irq_controller, - handle_percpu_irq); -} - -#ifdef CONFIG_IRQ_DOMAIN static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { @@ -138,8 +116,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { .xlate = irq_domain_xlate_onecell, }; -int __init mips_cpu_intc_init(struct device_node *of_node, - struct device_node *parent) +static void __init __mips_cpu_irq_init(struct device_node *of_node) { struct irq_domain *domain; @@ -151,7 +128,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node, &mips_cpu_intc_irq_domain_ops, NULL); if (!domain) panic("Failed to add irqdomain for MIPS CPU"); +} + +void __init mips_cpu_irq_init(void) +{ + __mips_cpu_irq_init(NULL); +} +int __init mips_cpu_intc_init(struct device_node *of_node, + struct device_node *parent) +{ + __mips_cpu_irq_init(of_node); return 0; } -#endif /* CONFIG_IRQ_DOMAIN */ -- GitLab From afe8dc254711b72ba8144295f4a8fcc66d30572d Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:08 -0700 Subject: [PATCH 5955/9457] MIPS: Rename mips_cpu_intc_init() -> mips_cpu_irq_of_init() mips_cpu_intc_init() is used for DT-based initialization of the CPU IRQ domain. Give it a more appropriate name. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7800/ Signed-off-by: Ralf Baechle --- Documentation/devicetree/bindings/mips/cpu_irq.txt | 4 ++-- arch/mips/include/asm/irq_cpu.h | 4 ++-- arch/mips/kernel/irq_cpu.c | 4 ++-- arch/mips/ralink/irq.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/mips/cpu_irq.txt b/Documentation/devicetree/bindings/mips/cpu_irq.txt index 13aa4b62c62a..fc149f326dae 100644 --- a/Documentation/devicetree/bindings/mips/cpu_irq.txt +++ b/Documentation/devicetree/bindings/mips/cpu_irq.txt @@ -1,6 +1,6 @@ MIPS CPU interrupt controller -On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU +On MIPS the mips_cpu_irq_of_init() helper can be used to initialize the 8 CPU IRQs from a devicetree file and create a irq_domain for IRQ controller. With the irq_domain in place we can describe how the 8 IRQs are wired to the @@ -36,7 +36,7 @@ Example devicetree: Example platform irq.c: static struct of_device_id __initdata of_irq_ids[] = { - { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, + { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, {}, }; diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h index 3f11fdb3ed8c..39a160bb41dc 100644 --- a/arch/mips/include/asm/irq_cpu.h +++ b/arch/mips/include/asm/irq_cpu.h @@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void); #ifdef CONFIG_IRQ_DOMAIN struct device_node; -extern int mips_cpu_intc_init(struct device_node *of_node, - struct device_node *parent); +extern int mips_cpu_irq_of_init(struct device_node *of_node, + struct device_node *parent); #endif #endif /* _ASM_IRQ_CPU_H */ diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index b097f7df7a29..ca98a9f837d4 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -135,8 +135,8 @@ void __init mips_cpu_irq_init(void) __mips_cpu_irq_init(NULL); } -int __init mips_cpu_intc_init(struct device_node *of_node, - struct device_node *parent) +int __init mips_cpu_irq_of_init(struct device_node *of_node, + struct device_node *parent) { __mips_cpu_irq_init(of_node); return 0; diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 781b3d14a489..0495011a19df 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c @@ -173,7 +173,7 @@ static int __init intc_of_init(struct device_node *node, } static struct of_device_id __initdata of_irq_ids[] = { - { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, + { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, {}, }; -- GitLab From 85f7cdacbb81db8c4cc8e474837eab1f0e4ff77b Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:09 -0700 Subject: [PATCH 5956/9457] MIPS: Provide a generic plat_irq_dispatch For platforms which boot with device-tree or have correctly chained all external interrupt controllers, a generic plat_irq_dispatch() can be used. Implement a plat_irq_dispatch() which simply handles all the pending interrupts as reported by C0_Cause. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7801/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq_cpu.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index ca98a9f837d4..531b11cbc096 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -94,6 +94,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .irq_eoi = unmask_mips_irq, }; +asmlinkage void __weak plat_irq_dispatch(void) +{ + unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + if (!pending) { + spurious_interrupt(); + return; + } + + pending >>= CAUSEB_IP; + while (pending) { + irq = fls(pending) - 1; + do_IRQ(MIPS_CPU_IRQ_BASE + irq); + pending &= ~BIT(irq); + } +} + static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { -- GitLab From f64e55dcbf84f107a68974a0734b3c31db97f169 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:10 -0700 Subject: [PATCH 5957/9457] MIPS: Set vint handler when mapping CPU interrupts When mapping an interrupt in the CPU IRQ domain, set the vint handler for that interrupt if the CPU uses vectored interrupt handling. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7802/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq_cpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 531b11cbc096..590c2c980fd3 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -36,6 +36,7 @@ #include #include #include +#include static inline void unmask_mips_irq(struct irq_data *d) { @@ -124,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, chip = &mips_cpu_irq_controller; } + if (cpu_has_vint) + set_vi_handler(hw, plat_irq_dispatch); + irq_set_chip_and_handler(irq, chip, handle_percpu_irq); return 0; -- GitLab From 079a4601768e248ba89dd08d4953e6dae607d7bd Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:11 -0700 Subject: [PATCH 5958/9457] MIPS: i8259: Use IRQ domains Create a legacy IRQ domain for the 16 i8259 interrupts. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7804/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/kernel/i8259.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 92033b7e275b..e08aeec7d916 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -975,6 +975,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU config I8259 bool + select IRQ_DOMAIN config MIPS_BONITO64 bool diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 50b364897dda..a74ec3ae557c 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -308,6 +309,19 @@ static struct resource pic2_io_resource = { .flags = IORESOURCE_BUSY }; +static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq); + irq_set_probe(virq); + return 0; +} + +static struct irq_domain_ops i8259A_ops = { + .map = i8259A_irq_domain_map, + .xlate = irq_domain_xlate_onecell, +}; + /* * On systems with i8259-style interrupt controllers we assume for * driver compatibility reasons interrupts 0 - 15 to be the i8259 @@ -315,17 +329,17 @@ static struct resource pic2_io_resource = { */ void __init init_i8259_irqs(void) { - int i; + struct irq_domain *domain; insert_resource(&ioport_resource, &pic1_io_resource); insert_resource(&ioport_resource, &pic2_io_resource); init_8259A(0); - for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { - irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); - irq_set_probe(i); - } + domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0, + &i8259A_ops, NULL); + if (!domain) + panic("Failed to add i8259 IRQ domain"); setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); } -- GitLab From a669efc4a3b49de9226b280bb683f5b1d5a5d143 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:12 -0700 Subject: [PATCH 5959/9457] MIPS: Add hook to get C0 performance counter interrupt The hardware perf event driver and oprofile interpret the global cp0_perfcount_irq differently: in the hardware perf event driver it is an offset from MIPS_CPU_IRQ_BASE and in oprofile it is the actual IRQ number. This still works most of the time since MIPS_CPU_IRQ_BASE is usually 0, but is clearly wrong. Since the performance counter interrupt may vary from platform to platform like the C0 timer interrupt, add the optional get_c0_perfcount_int hook which returns the IRQ number of the performance counter. The hook should return < 0 if the performance counter interrupt is shared with the timer. If the hook is not present, the CPU vector reported in C0_IntCtl (cp0_perfcount_irq) is used. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7805/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/irq.c | 1 - arch/mips/ath79/setup.c | 5 +++++ arch/mips/include/asm/time.h | 1 + arch/mips/kernel/perf_event_mipsxx.c | 23 +++++++---------------- arch/mips/lantiq/irq.c | 8 +++++++- arch/mips/mti-malta/malta-time.c | 16 ++++++---------- arch/mips/mti-sead3/sead3-time.c | 7 ++++--- arch/mips/oprofile/op_model_mipsxx.c | 18 ++++++++++++++---- arch/mips/ralink/irq.c | 8 +++++++- 9 files changed, 51 insertions(+), 36 deletions(-) diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 9c0e1761773f..6adae366f11a 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -359,7 +359,6 @@ void __init arch_init_irq(void) BUG(); } - cp0_perfcount_irq = ATH79_MISC_IRQ(5); mips_cpu_irq_init(); ath79_misc_irq_init(); diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 64807a4809d0..a73c93c3d44a 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -182,6 +182,11 @@ const char *get_system_type(void) return ath79_sys_type; } +int get_c0_perfcount_int(void) +{ + return ATH79_MISC_IRQ(5); +} + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 8f3047d611ee..7969933ba89a 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -46,6 +46,7 @@ extern unsigned int mips_hpt_frequency; * so it lives here. */ extern int (*perf_irq)(void); +extern int __weak get_c0_perfcount_int(void); /* * Initialize the calling CPU's compare interrupt as clockevent device diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 7633d30550e9..9466184d0039 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -1613,22 +1613,13 @@ init_hw_perf_events(void) counters = counters_total_to_per_cpu(counters); #endif -#ifdef MSC01E_INT_BASE - if (cpu_has_veic) { - /* - * Using platform specific interrupt controller defines. - */ - irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else { -#endif - if ((cp0_perfcount_irq >= 0) && - (cp0_compare_irq != cp0_perfcount_irq)) - irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - else - irq = -1; -#ifdef MSC01E_INT_BASE - } -#endif + if (get_c0_perfcount_int) + irq = get_c0_perfcount_int(); + else if ((cp0_perfcount_irq >= 0) && + (cp0_compare_irq != cp0_perfcount_irq)) + irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + else + irq = -1; mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 030568a70ac4..21c38eee0a81 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU]; static void __iomem *ltq_icu_membase[MAX_IM]; static void __iomem *ltq_eiu_membase; static struct irq_domain *ltq_domain; +static int ltq_perfcount_irq; int ltq_eiu_get_irq(int exin) { @@ -449,7 +450,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) #endif /* tell oprofile which irq to use */ - cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); + ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); /* * if the timer irq is not one of the mips irqs we need to @@ -461,6 +462,11 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) return 0; } +int get_c0_perfcount_int(void) +{ + return ltq_perfcount_irq; +} + unsigned int get_c0_compare_int(void) { return MIPS_CPU_TIMER_IRQ; diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 3778a359f3ad..a4e035c8acf6 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -121,22 +121,20 @@ void read_persistent_clock(struct timespec *ts) ts->tv_nsec = 0; } -static void __init plat_perf_setup(void) +int get_c0_perfcount_int(void) { -#ifdef MSC01E_INT_BASE if (cpu_has_veic) { set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else -#endif - if (cp0_perfcount_irq >= 0) { + } else if (cp0_perfcount_irq >= 0) { if (cpu_has_vint) set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; -#ifdef CONFIG_SMP - irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); -#endif + } else { + mips_cpu_perf_irq = -1; } + + return mips_cpu_perf_irq; } unsigned int get_c0_compare_int(void) @@ -201,6 +199,4 @@ void __init plat_time_init(void) #endif } #endif - - plat_perf_setup(); } diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index 678d03d53c60..f090c5177719 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c @@ -81,13 +81,16 @@ void read_persistent_clock(struct timespec *ts) ts->tv_nsec = 0; } -static void __init plat_perf_setup(void) +int get_c0_perfcount_int(void) { if (cp0_perfcount_irq >= 0) { if (cpu_has_vint) set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + } else { + mips_cpu_perf_irq = -1; } + return mips_cpu_perf_irq; } unsigned int get_c0_compare_int(void) @@ -108,6 +111,4 @@ void __init plat_time_init(void) (est_freq % 1000000) * 100 / 1000000); mips_scroll_message(); - - plat_perf_setup(); } diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 42821ae2d77e..01f721a85c5b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "op_impl.h" @@ -35,6 +36,7 @@ #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) static int (*save_perf_irq)(void); +static int perfcount_irq; /* * XLR has only one set of counters per core. Designate the @@ -431,8 +433,16 @@ static int __init mipsxx_init(void) save_perf_irq = perf_irq; perf_irq = mipsxx_perfcount_handler; - if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) - return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, + if (get_c0_perfcount_int) + perfcount_irq = get_c0_perfcount_int(); + else if ((cp0_perfcount_irq >= 0) && + (cp0_compare_irq != cp0_perfcount_irq)) + perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + else + perfcount_irq = -1; + + if (perfcount_irq >= 0) + return request_irq(perfcount_irq, mipsxx_perfcount_int, 0, "Perfcounter", save_perf_irq); return 0; @@ -442,8 +452,8 @@ static void mipsxx_exit(void) { int counters = op_model_mipsxx_ops.num_counters; - if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) - free_irq(cp0_perfcount_irq, save_perf_irq); + if (perfcount_irq >= 0) + free_irq(perfcount_irq, save_perf_irq); counters = counters_per_cpu_to_total(counters); on_each_cpu(reset_counters, (void *)(long)counters, 1); diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 0495011a19df..7634dcd88766 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c @@ -45,6 +45,7 @@ #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) static void __iomem *rt_intc_membase; +static int rt_perfcount_irq; static inline void rt_intc_w32(u32 val, unsigned reg) { @@ -73,6 +74,11 @@ static struct irq_chip ralink_intc_irq_chip = { .irq_mask_ack = ralink_intc_irq_mask, }; +int get_c0_perfcount_int(void) +{ + return rt_perfcount_irq; +} + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -167,7 +173,7 @@ static int __init intc_of_init(struct device_node *node, irq_set_handler_data(irq, domain); /* tell the kernel which irq is used for performance monitoring */ - cp0_perfcount_irq = irq_create_mapping(domain, 9); + rt_perfcount_irq = irq_create_mapping(domain, 9); return 0; } -- GitLab From ff1e29ade4c677c24ee972549d20f07e466d50bf Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:13 -0700 Subject: [PATCH 5960/9457] MIPS: smp-cps: Enable all hardware interrupts on secondary CPUs Currently interrupt vectors 2 and 5 are left disabled on secondary CPUs. Since systems using CPS must also have a GIC, which is responsible for routing all external interrupts and can map them to any hardware interrupt vector, enable the remaining vectors. The two software interrupt vectors are left disabled since they are not used with CPS. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7803/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-cps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index e6e16a1d4add..cd20acad7f17 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -273,8 +273,8 @@ static void cps_init_secondary(void) if (cpu_has_mipsmt) dmt(); - change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | - STATUSF_IP6 | STATUSF_IP7); + change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | + STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); } static void cps_smp_finish(void) -- GitLab From a67b3cf1af7affcf3fc8ad775c90954aa887032c Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:14 -0700 Subject: [PATCH 5961/9457] MIPS: Remove gic_{enable,disable}_interrupt() Nothing calls gic_{enable,disable}_interrupt() any more. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Qais Yousef Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7806/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 2 -- arch/mips/mti-malta/malta-int.c | 10 ---------- arch/mips/mti-sead3/sead3-int.c | 34 --------------------------------- 3 files changed, 46 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index d7699cf7e135..022d83136c5a 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -376,8 +376,6 @@ extern void gic_bind_eic_interrupt(int irq, int set); extern unsigned int gic_get_timer_pending(void); extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); extern unsigned int gic_get_int(void); -extern void gic_enable_interrupt(int irq_vec); -extern void gic_disable_interrupt(int irq_vec); extern void gic_irq_ack(struct irq_data *d); extern void gic_finish_irq(struct irq_data *d); extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e4f43baa8f67..5c3120857987 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -715,16 +715,6 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) return retval; } -void gic_enable_interrupt(int irq_vec) -{ - GIC_SET_INTR_MASK(irq_vec); -} - -void gic_disable_interrupt(int irq_vec) -{ - GIC_CLR_INTR_MASK(irq_vec); -} - void gic_irq_ack(struct irq_data *d) { int irq = (d->irq - gic_irq_base); diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 6a560ac03def..9d5b5bd3a1d2 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -85,40 +85,6 @@ void __init arch_init_irq(void) ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); } -void gic_enable_interrupt(int irq_vec) -{ - unsigned int i, irq_source; - - /* enable all the interrupts associated with this vector */ - for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { - irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; - GIC_SET_INTR_MASK(irq_source); - } - /* enable all local interrupts associated with this vector */ - if (gic_shared_intr_map[irq_vec].local_intr_mask) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), - gic_shared_intr_map[irq_vec].local_intr_mask); - } -} - -void gic_disable_interrupt(int irq_vec) -{ - unsigned int i, irq_source; - - /* disable all the interrupts associated with this vector */ - for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { - irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; - GIC_CLR_INTR_MASK(irq_source); - } - /* disable all local interrupts associated with this vector */ - if (gic_shared_intr_map[irq_vec].local_intr_mask) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), - gic_shared_intr_map[irq_vec].local_intr_mask); - } -} - void gic_irq_ack(struct irq_data *d) { GIC_CLR_INTR_MASK(d->irq - gic_irq_base); -- GitLab From d8725fddfd913129d58f126650afdabebd84d3ca Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:15 -0700 Subject: [PATCH 5962/9457] MIPS: SEAD3: Remove sead3-serial.c It's a duplicate of sead3-platform.c and is not even compiled. Remove it before we start fixing up IRQ assignments. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7807/ Signed-off-by: Ralf Baechle --- arch/mips/mti-sead3/sead3-serial.c | 45 ------------------------------ 1 file changed, 45 deletions(-) delete mode 100644 arch/mips/mti-sead3/sead3-serial.c diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c deleted file mode 100644 index bc52705bbee4..000000000000 --- a/arch/mips/mti-sead3/sead3-serial.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include -#include -#include - -#define UART(base, int) \ -{ \ - .mapbase = base, \ - .irq = int, \ - .uartclk = 14745600, \ - .iotype = UPIO_MEM32, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ - .regshift = 2, \ -} - -static struct plat_serial8250_port uart8250_data[] = { - UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ - UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ - { }, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = uart8250_data, - }, -}; - -static int __init uart8250_init(void) -{ - return platform_device_register(&uart8250_device); -} - -module_init(uart8250_init); - -MODULE_AUTHOR("Chris Dearman "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform"); -- GitLab From dfc94d1b21520093b7b6788ab25c955456ad4493 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:16 -0700 Subject: [PATCH 5963/9457] MIPS: sead3: Do not overlap CPU/GIC IRQ ranges In preparation for GIC IRQ domain support, assign a GIC IRQ base that does not overlap with the CPU IRQs. Note that this breaks SEAD-3 when the GIC is in EIC mode, though I'm not convinced it was working before either. It will be fixed in the following patches. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7813/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mips-boards/sead3int.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 6b17aaf7d901..2320331f1464 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -14,6 +14,6 @@ #define GIC_BASE_ADDR 0x1b1c0000 #define GIC_ADDRSPACE_SZ (128 * 1024) -#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) +#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) #endif /* !(_MIPS_SEAD3INT_H) */ -- GitLab From aa827b748dd169938caf5bb1f6d9e4dcb218cbb9 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:17 -0700 Subject: [PATCH 5964/9457] MIPS: Malta: Move MSC01 interrupt base The GIC on Malta boards supports a total of 47 interrupts (40 shared and 7 local) and is assigned a base of 24. This overlaps with the MSC01 interrupt assignments which have a base of 64, so move the MSC01 interrupt base back a bit to give the GIC some room. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7815/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mips-boards/maltaint.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index e330732ddf98..4186606bef0c 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -33,18 +33,18 @@ #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 /* - * Interrupts 64..127 are used for Soc-it Classic interrupts + * Interrupts 96..127 are used for Soc-it Classic interrupts */ -#define MSC01C_INT_BASE 64 +#define MSC01C_INT_BASE 96 /* SOC-it Classic interrupt offsets */ #define MSC01C_INT_TMR 0 #define MSC01C_INT_PCI 1 /* - * Interrupts 64..127 are used for Soc-it EIC interrupts + * Interrupts 96..127 are used for Soc-it EIC interrupts */ -#define MSC01E_INT_BASE 64 +#define MSC01E_INT_BASE 96 /* SOC-it EIC interrupt offsets */ #define MSC01E_INT_SW0 1 -- GitLab From 8635233ca5987bd42953aeffab1f60a3b8ffc78f Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:18 -0700 Subject: [PATCH 5965/9457] MIPS: Move MIPS_GIC_IRQ_BASE into platform irq.h Define a generic MIPS_GIC_IRQ_BASE which should be suitable for all current boards in . Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jason Cooper Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7808/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-generic/irq.h | 6 ++++++ arch/mips/include/asm/mips-boards/maltaint.h | 2 -- arch/mips/include/asm/mips-boards/sead3int.h | 2 -- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 139cd200e79d..050e18bb1a04 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h @@ -36,4 +36,10 @@ #endif /* CONFIG_IRQ_CPU */ +#ifdef CONFIG_MIPS_GIC +#ifndef MIPS_GIC_IRQ_BASE +#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) +#endif +#endif /* CONFIG_MIPS_GIC */ + #endif /* __ASM_MACH_GENERIC_IRQ_H */ diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index 4186606bef0c..d741628e3397 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -10,8 +10,6 @@ #ifndef _MIPS_MALTAINT_H #define _MIPS_MALTAINT_H -#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) - /* * Interrupts 0..15 are used for Malta ISA compatible interrupts */ diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 2320331f1464..11ebec94f807 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -14,6 +14,4 @@ #define GIC_BASE_ADDR 0x1b1c0000 #define GIC_ADDRSPACE_SZ (128 * 1024) -#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) - #endif /* !(_MIPS_SEAD3INT_H) */ -- GitLab From 8a19b8f19429b86c91e10745bc131bc600e60ede Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:19 -0700 Subject: [PATCH 5966/9457] MIPS: Move GIC to drivers/irqchip/ Move GIC irqchip support to drivers/irqchip/ and rename the Kconfig option from IRQ_GIC to MIPS_GIC to avoid confusion with the ARM GIC. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7812/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 10 +++------- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/cevt-r4k.c | 2 +- arch/mips/kernel/smp-mt.c | 4 ++-- arch/mips/mti-malta/malta-time.c | 10 +++++----- drivers/irqchip/Kconfig | 4 ++++ drivers/irqchip/Makefile | 1 + .../kernel/irq-gic.c => drivers/irqchip/irq-mips-gic.c | 0 8 files changed, 16 insertions(+), 16 deletions(-) rename arch/mips/kernel/irq-gic.c => drivers/irqchip/irq-mips-gic.c (100%) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e08aeec7d916..e0b7c2006900 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -320,7 +320,7 @@ config MIPS_MALTA select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM select IRQ_CPU - select IRQ_GIC + select MIPS_GIC select HW_HAS_PCI select I8253 select I8259 @@ -362,7 +362,7 @@ config MIPS_SEAD3 select CPU_MIPSR2_IRQ_EI select DMA_NONCOHERENT select IRQ_CPU - select IRQ_GIC + select MIPS_GIC select LIBFDT select MIPS_MSC select SYS_HAS_CPU_MIPS32_R1 @@ -1073,10 +1073,6 @@ config IRQ_TXX9 config IRQ_GT641XX bool -config IRQ_GIC - select MIPS_CM - bool - config PCI_GT64XXX_PCI0 bool @@ -1890,7 +1886,7 @@ config FORCE_MAX_ZONEORDER config CEVT_GIC bool "Use GIC global counter for clock events" - depends on IRQ_GIC && !MIPS_SEAD3 + depends on MIPS_GIC && !MIPS_SEAD3 help Use the GIC global counter for the clock events. The R4K clock event driver is always present, so if the platform ends up not diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 008a2fed0584..3982e5138f61 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -68,7 +68,6 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o obj-$(CONFIG_MIPS_MSC) += irq-msc01.o obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o -obj-$(CONFIG_IRQ_GIC) += irq-gic.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_32BIT) += scall32-o32.o diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index bc127e22fdab..5b8f8e32b47d 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -85,7 +85,7 @@ void mips_event_handler(struct clock_event_device *dev) */ static int c0_compare_int_pending(void) { -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (cpu_has_veic) return gic_get_timer_pending(); #endif diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 21f23add04f4..d60475fe5957 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -119,7 +119,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) unsigned long flags; int vpflags; -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (gic_present) { gic_send_ipi_single(cpu, action); return; @@ -158,7 +158,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) static void vsmp_init_secondary(void) { -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC /* This is Malta specific: IPI,performance and timer interrupts */ if (gic_present) change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index a4e035c8acf6..17cfc8a379a6 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -70,7 +70,7 @@ static void __init estimate_frequencies(void) { unsigned long flags; unsigned int count, start; -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC unsigned int giccount = 0, gicstart = 0; #endif @@ -87,7 +87,7 @@ static void __init estimate_frequencies(void) /* Initialize counters. */ start = read_c0_count(); -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (gic_present) GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); #endif @@ -97,7 +97,7 @@ static void __init estimate_frequencies(void) while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (gic_present) GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); #endif @@ -107,7 +107,7 @@ static void __init estimate_frequencies(void) count -= start; mips_hpt_frequency = count; -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (gic_present) { giccount -= gicstart; gic_frequency = giccount; @@ -189,7 +189,7 @@ void __init plat_time_init(void) setup_pit_timer(); #endif -#ifdef CONFIG_IRQ_GIC +#ifdef CONFIG_MIPS_GIC if (gic_present) { freq = freqround(gic_frequency, 5000); printk("GIC frequency %d.%02d MHz\n", freq/1000000, diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index b21f12f1766d..f2dde146bbdb 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -125,3 +125,7 @@ config KEYSTONE_IRQ help Support for Texas Instruments Keystone 2 IRQ controller IP which is part of the Keystone 2 IPC mechanism + +config MIPS_GIC + bool + select MIPS_CM diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 173bb5fa2cc9..021833079c91 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o \ irq-bcm7120-l2.o obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o +obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o diff --git a/arch/mips/kernel/irq-gic.c b/drivers/irqchip/irq-mips-gic.c similarity index 100% rename from arch/mips/kernel/irq-gic.c rename to drivers/irqchip/irq-mips-gic.c -- GitLab From 5561c9e467a91c99ae1d0714e78ad26a2d14c744 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:20 -0700 Subject: [PATCH 5967/9457] irqchip: mips-gic: Remove platform irq_ack/irq_eoi callbacks There's no need for platforms to have their own GIC irq_ack/irq_eoi callbacks. irq_ack need only clear the GIC's edge detector on edge-triggered interrupts and there's no need at all for irq_eoi. Also get rid of the mask_ack callback since it's not necessary either. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7809/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 2 -- arch/mips/mti-malta/malta-int.c | 16 ---------------- arch/mips/mti-sead3/sead3-int.c | 21 --------------------- drivers/irqchip/irq-mips-gic.c | 11 ++++++++--- 4 files changed, 8 insertions(+), 42 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 022d83136c5a..1bf7985f9435 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -376,7 +376,5 @@ extern void gic_bind_eic_interrupt(int irq, int set); extern unsigned int gic_get_timer_pending(void); extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); extern unsigned int gic_get_int(void); -extern void gic_irq_ack(struct irq_data *d); -extern void gic_finish_irq(struct irq_data *d); extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); #endif /* _ASM_GICREGS_H */ diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 5c3120857987..b60adfd2bae6 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -715,22 +715,6 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) return retval; } -void gic_irq_ack(struct irq_data *d) -{ - int irq = (d->irq - gic_irq_base); - - GIC_CLR_INTR_MASK(irq); - - if (gic_irq_flags[irq] & GIC_TRIG_EDGE) - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); -} - -void gic_finish_irq(struct irq_data *d) -{ - /* Enable interrupts. */ - GIC_SET_INTR_MASK(d->irq - gic_irq_base); -} - void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) { int i; diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 9d5b5bd3a1d2..03f9865e0464 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -85,27 +85,6 @@ void __init arch_init_irq(void) ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); } -void gic_irq_ack(struct irq_data *d) -{ - GIC_CLR_INTR_MASK(d->irq - gic_irq_base); -} - -void gic_finish_irq(struct irq_data *d) -{ - unsigned int irq = (d->irq - gic_irq_base); - unsigned int i, irq_source; - - /* Clear edge detectors. */ - for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) { - irq_source = gic_shared_intr_map[irq].intr_list[i]; - if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE) - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source); - } - - /* Enable interrupts. */ - GIC_SET_INTR_MASK(irq); -} - void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) { int i; diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 582883069ef6..76658660ea4f 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -237,6 +237,13 @@ static void gic_unmask_irq(struct irq_data *d) GIC_SET_INTR_MASK(d->irq - gic_irq_base); } +static void gic_ack_irq(struct irq_data *d) +{ + /* Clear edge detector */ + if (gic_irq_flags[d->irq - gic_irq_base] & GIC_TRIG_EDGE) + GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), d->irq - gic_irq_base); +} + #ifdef CONFIG_SMP static DEFINE_SPINLOCK(gic_lock); @@ -272,11 +279,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, static struct irq_chip gic_irq_controller = { .name = "MIPS GIC", - .irq_ack = gic_irq_ack, + .irq_ack = gic_ack_irq, .irq_mask = gic_mask_irq, - .irq_mask_ack = gic_mask_irq, .irq_unmask = gic_unmask_irq, - .irq_eoi = gic_finish_irq, #ifdef CONFIG_SMP .irq_set_affinity = gic_set_affinity, #endif -- GitLab From 95150ae8b330b26e93ed4a0d6e16cd597a12e13d Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:21 -0700 Subject: [PATCH 5968/9457] irqchip: mips-gic: Implement irq_set_type callback Implement an irq_set_type callback for the GIC which is used to set the polarity and trigger type of GIC interrupts. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7810/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 9 ++++++ drivers/irqchip/irq-mips-gic.c | 57 ++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 1bf7985f9435..662b56719263 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -23,6 +23,8 @@ #define GIC_POL_NEG 0 #define GIC_TRIG_EDGE 1 #define GIC_TRIG_LEVEL 0 +#define GIC_TRIG_DUAL_ENABLE 1 +#define GIC_TRIG_DUAL_DISABLE 0 #define MSK(n) ((1 << (n)) - 1) #define REG32(addr) (*(volatile unsigned int *) (addr)) @@ -179,6 +181,13 @@ GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ (trig) << GIC_INTR_BIT(intr)) +/* Dual edge triggering : Reset Value is always 0 */ +#define GIC_SH_SET_DUAL_OFS 0x0200 +#define GIC_SET_DUAL(intr, dual) \ + GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_DUAL_OFS + \ + GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ + (dual) << GIC_INTR_BIT(intr)) + /* Mask manipulation */ #define GIC_SH_SMASK_OFS 0x0380 #define GIC_SET_INTR_MASK(intr) \ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 76658660ea4f..360b323a9862 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -43,6 +43,7 @@ struct gic_intrmask_regs { static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; +static DEFINE_SPINLOCK(gic_lock); #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) @@ -244,9 +245,60 @@ static void gic_ack_irq(struct irq_data *d) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), d->irq - gic_irq_base); } -#ifdef CONFIG_SMP -static DEFINE_SPINLOCK(gic_lock); +static int gic_set_type(struct irq_data *d, unsigned int type) +{ + unsigned int irq = d->irq - gic_irq_base; + unsigned long flags; + bool is_edge; + + spin_lock_irqsave(&gic_lock, flags); + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_FALLING: + GIC_SET_POLARITY(irq, GIC_POL_NEG); + GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); + GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + is_edge = true; + break; + case IRQ_TYPE_EDGE_RISING: + GIC_SET_POLARITY(irq, GIC_POL_POS); + GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); + GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + is_edge = true; + break; + case IRQ_TYPE_EDGE_BOTH: + /* polarity is irrelevant in this case */ + GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); + GIC_SET_DUAL(irq, GIC_TRIG_DUAL_ENABLE); + is_edge = true; + break; + case IRQ_TYPE_LEVEL_LOW: + GIC_SET_POLARITY(irq, GIC_POL_NEG); + GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL); + GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + is_edge = false; + break; + case IRQ_TYPE_LEVEL_HIGH: + default: + GIC_SET_POLARITY(irq, GIC_POL_POS); + GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL); + GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + is_edge = false; + break; + } + if (is_edge) { + gic_irq_flags[irq] |= GIC_TRIG_EDGE; + __irq_set_handler_locked(d->irq, handle_edge_irq); + } else { + gic_irq_flags[irq] &= ~GIC_TRIG_EDGE; + __irq_set_handler_locked(d->irq, handle_level_irq); + } + spin_unlock_irqrestore(&gic_lock, flags); + + return 0; +} + +#ifdef CONFIG_SMP static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) { @@ -282,6 +334,7 @@ static struct irq_chip gic_irq_controller = { .irq_ack = gic_ack_irq, .irq_mask = gic_mask_irq, .irq_unmask = gic_unmask_irq, + .irq_set_type = gic_set_type, #ifdef CONFIG_SMP .irq_set_affinity = gic_set_affinity, #endif -- GitLab From 14d160ab72aaa784219f733fbac6032d3494fc73 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:22 -0700 Subject: [PATCH 5969/9457] irqchip: mips-gic: Fix gic_set_affinity() return value If the online CPU check in gic_set_affinity() fails, return a proper errno value instead of -1. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7814/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 360b323a9862..f02cbf5cd8d6 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -309,7 +309,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, cpumask_and(&tmp, cpumask, cpu_online_mask); if (cpus_empty(tmp)) - return -1; + return -EINVAL; /* Assumption : cpumask refers to a single CPU */ spin_lock_irqsave(&gic_lock, flags); -- GitLab From c49581a4dfaade3a483f3db85581a2cdb6bb85a0 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:23 -0700 Subject: [PATCH 5970/9457] irqchip: mips-gic: Use IRQ domains Use a simple IRQ domain for the MIPS GIC. Remove the gic_platform_init callback as it's no longer necessary for it to set the irqchip. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7811/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 1 - arch/mips/mti-malta/malta-int.c | 8 ------ arch/mips/mti-sead3/sead3-int.c | 15 ----------- drivers/irqchip/irq-mips-gic.c | 48 +++++++++++++++++++++++++++------ 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 662b56719263..efcf4dec1229 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -385,5 +385,4 @@ extern void gic_bind_eic_interrupt(int irq, int set); extern unsigned int gic_get_timer_pending(void); extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); extern unsigned int gic_get_int(void); -extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); #endif /* _ASM_GICREGS_H */ diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index b60adfd2bae6..e56563c6f89e 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -714,11 +714,3 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) return retval; } - -void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) -{ - int i; - - for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) - irq_set_chip(i, irq_controller); -} diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 03f9865e0464..8f3634281ed9 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -85,18 +85,3 @@ void __init arch_init_irq(void) ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); } -void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) -{ - int i; - - /* - * For non-EIC mode, we want to setup the GIC in pass-through - * mode, as if the GIC didn't exist. Do not map any interrupts - * for an external interrupt controller. - */ - if (!cpu_has_veic) - return; - - for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) - irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq); -} diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index f02cbf5cd8d6..79ab99781534 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -44,6 +44,7 @@ static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); +static struct irq_domain *gic_irq_domain; #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) @@ -230,24 +231,26 @@ unsigned int gic_get_int(void) static void gic_mask_irq(struct irq_data *d) { - GIC_CLR_INTR_MASK(d->irq - gic_irq_base); + GIC_CLR_INTR_MASK(d->hwirq); } static void gic_unmask_irq(struct irq_data *d) { - GIC_SET_INTR_MASK(d->irq - gic_irq_base); + GIC_SET_INTR_MASK(d->hwirq); } static void gic_ack_irq(struct irq_data *d) { + unsigned int irq = d->hwirq; + /* Clear edge detector */ - if (gic_irq_flags[d->irq - gic_irq_base] & GIC_TRIG_EDGE) - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), d->irq - gic_irq_base); + if (gic_irq_flags[irq] & GIC_TRIG_EDGE) + GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); } static int gic_set_type(struct irq_data *d, unsigned int type) { - unsigned int irq = d->irq - gic_irq_base; + unsigned int irq = d->hwirq; unsigned long flags; bool is_edge; @@ -302,7 +305,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) { - unsigned int irq = (d->irq - gic_irq_base); + unsigned int irq = d->hwirq; cpumask_t tmp = CPU_MASK_NONE; unsigned long flags; int i; @@ -345,6 +348,7 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, unsigned int flags) { struct gic_shared_intr_map *map_ptr; + int i; /* Setup Intr to Pin mapping */ if (pin & GIC_MAP_TO_NMI_MSK) { @@ -382,6 +386,8 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, GIC_CLR_INTR_MASK(intr); /* Initialise per-cpu Interrupt software masks */ + for (i = 0; i < NR_CPUS; i++) + clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[cpu].pcpu_mask); if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) @@ -433,6 +439,29 @@ static void __init gic_basic_init(int numintrs, int numvpes, vpe_local_setup(numvpes); } +static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + unsigned long flags; + + irq_set_chip_and_handler(virq, &gic_irq_controller, handle_level_irq); + + spin_lock_irqsave(&gic_lock, flags); + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)), + GIC_MAP_TO_PIN_MSK | 0); + /* Map to VPE 0 by default */ + GIC_SH_MAP_TO_VPE_SMASK(hw, 0); + set_bit(hw, pcpu_masks[0].pcpu_mask); + spin_unlock_irqrestore(&gic_lock, flags); + + return 0; +} + +static struct irq_domain_ops gic_irq_domain_ops = { + .map = gic_irq_domain_map, + .xlate = irq_domain_xlate_twocell, +}; + void __init gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, struct gic_intr_map *intr_map, unsigned int intr_map_size, @@ -454,7 +483,10 @@ void __init gic_init(unsigned long gic_base_addr, GIC_SH_CONFIG_NUMVPES_SHF; numvpes = numvpes + 1; - gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); + gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_INTRS, irqbase, + &gic_irq_domain_ops, NULL); + if (!gic_irq_domain) + panic("Failed to add GIC IRQ domain"); - gic_platform_init(numintrs, &gic_irq_controller); + gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); } -- GitLab From 18743d2781d01d34d132f952a2e16353ccb4c3de Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:24 -0700 Subject: [PATCH 5971/9457] irqchip: mips-gic: Stop using per-platform mapping tables Now that the GIC properly uses IRQ domains, kill off the per-platform routing tables that were used to make the GIC appear transparent. This includes: - removing the mapping tables and the support for applying them, - moving GIC IPI support to the GIC driver, - properly routing the i8259 through the GIC on Malta, and - updating IRQ assignments on SEAD-3 when the GIC is present. Platforms no longer will pass an interrupt mapping table to gic_init. Instead, they will pass the CPU interrupt vector (2 - 7) that they expect the GIC to route interrupts to. Note that in EIC mode this value is ignored and all GIC interrupts are routed to EIC vector 1. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7816/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 35 +--- arch/mips/include/asm/mips-boards/maltaint.h | 14 +- arch/mips/include/asm/mips-boards/sead3int.h | 13 ++ arch/mips/kernel/cevt-gic.c | 3 +- arch/mips/mti-malta/malta-int.c | 189 ++++------------- arch/mips/mti-sead3/sead3-ehci.c | 8 +- arch/mips/mti-sead3/sead3-int.c | 28 +-- arch/mips/mti-sead3/sead3-net.c | 14 +- arch/mips/mti-sead3/sead3-platform.c | 18 +- drivers/irqchip/irq-mips-gic.c | 201 ++++++++++--------- 10 files changed, 198 insertions(+), 325 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index efcf4dec1229..cfbf907ebfa5 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -316,31 +316,6 @@ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) -/* - * Interrupt Meta-data specification. The ipiflag helps - * in building ipi_map. - */ -struct gic_intr_map { - unsigned int cpunum; /* Directed to this CPU */ -#define GIC_UNUSED 0xdead /* Dummy data */ - unsigned int pin; /* Directed to this Pin */ - unsigned int polarity; /* Polarity : +/- */ - unsigned int trigtype; /* Trigger : Edge/Levl */ - unsigned int flags; /* Misc flags */ -#define GIC_FLAG_TRANSPARENT 0x01 -}; - -/* - * This is only used in EIC mode. This helps to figure out which - * shared interrupts we need to process when we get a vector interrupt. - */ -#define GIC_MAX_SHARED_INTR 0x5 -struct gic_shared_intr_map { - unsigned int num_shared_intr; - unsigned int intr_list[GIC_MAX_SHARED_INTR]; - unsigned int local_intr_mask; -}; - /* GIC nomenclature for Core Interrupt Pins. */ #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ #define GIC_CPU_INT1 1 /* . */ @@ -349,6 +324,9 @@ struct gic_shared_intr_map { #define GIC_CPU_INT4 4 /* . */ #define GIC_CPU_INT5 5 /* Core Interrupt 7 */ +/* Add 2 to convert GIC CPU pin to core interrupt */ +#define GIC_CPU_PIN_OFFSET 2 + /* Local GIC interrupts. */ #define GIC_INT_TMR (GIC_CPU_INT5) #define GIC_INT_PERFCTR (GIC_CPU_INT5) @@ -365,13 +343,12 @@ struct gic_shared_intr_map { extern unsigned int gic_present; extern unsigned int gic_frequency; extern unsigned long _gic_base; -extern unsigned int gic_irq_base; extern unsigned int gic_irq_flags[]; -extern struct gic_shared_intr_map gic_shared_intr_map[]; +extern unsigned int gic_cpu_pin; extern void gic_init(unsigned long gic_base_addr, - unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, - unsigned int intrmap_size, unsigned int irqbase); + unsigned long gic_addrspace_size, unsigned int cpu_vec, + unsigned int irqbase); extern void gic_clocksource_init(unsigned int); extern unsigned int gic_compare_int (void); extern cycle_t gic_read_count(void); diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index d741628e3397..bdd6f392f160 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -20,11 +20,10 @@ #define MIPSCPU_INT_SW1 1 #define MIPSCPU_INT_MB0 2 #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 +#define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */ #define MIPSCPU_INT_MB1 3 #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 -#define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */ #define MIPSCPU_INT_MB2 4 -#define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */ #define MIPSCPU_INT_MB3 5 #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 #define MIPSCPU_INT_MB4 6 @@ -61,14 +60,7 @@ #define MSC01E_INT_PERFCTR 10 #define MSC01E_INT_CPUCTR 11 -/* External Interrupts used for IPI */ -#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 -#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 -#define GIC_IPI_EXT_INTR_RESCHED_VPE1 18 -#define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19 -#define GIC_IPI_EXT_INTR_RESCHED_VPE2 20 -#define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21 -#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 -#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 +/* GIC external interrupts */ +#define GIC_INT_I8259A 3 #endif /* !(_MIPS_MALTAINT_H) */ diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 11ebec94f807..a2e0095440fe 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -14,4 +14,17 @@ #define GIC_BASE_ADDR 0x1b1c0000 #define GIC_ADDRSPACE_SZ (128 * 1024) +/* CPU interrupt offsets */ +#define CPU_INT_GIC 2 +#define CPU_INT_EHCI 2 +#define CPU_INT_UART0 4 +#define CPU_INT_UART1 4 +#define CPU_INT_NET 6 + +/* GIC interrupt offsets */ +#define GIC_INT_NET 0 +#define GIC_INT_UART1 2 +#define GIC_INT_UART0 3 +#define GIC_INT_EHCI 5 + #endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c index 6093716980b9..a90bd4c81c7d 100644 --- a/arch/mips/kernel/cevt-gic.c +++ b/arch/mips/kernel/cevt-gic.c @@ -91,7 +91,8 @@ int gic_clockevent_init(void) clockevents_register_device(cd); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), + GIC_MAP_TO_PIN_MSK | gic_cpu_pin); GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); if (gic_timer_irq_installed) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e56563c6f89e..3b3bc1d9ebf9 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -38,14 +38,9 @@ #include static unsigned long _msc01_biu_base; -static unsigned int ipi_map[NR_CPUS]; static DEFINE_RAW_SPINLOCK(mips_irq_lock); -#ifdef CONFIG_MIPS_GIC_IPI -DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); -#endif - static inline int mips_pcibios_iack(void) { int irq; @@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void) #endif } -static void malta_ipi_irqdispatch(void) +static irqreturn_t i8259_handler(int irq, void *dev_id) { -#ifdef CONFIG_MIPS_GIC_IPI - unsigned long irq; - DECLARE_BITMAP(pending, GIC_NUM_INTRS); - - gic_get_int_mask(pending, ipi_ints); - - irq = find_first_bit(pending, GIC_NUM_INTRS); - - while (irq < GIC_NUM_INTRS) { - do_IRQ(MIPS_GIC_IRQ_BASE + irq); - - irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); - } -#endif - if (gic_compare_int()) - do_IRQ(MIPS_GIC_IRQ_BASE); + malta_hw0_irqdispatch(); + return IRQ_HANDLED; } static void corehi_irqdispatch(void) @@ -203,6 +184,12 @@ static void corehi_irqdispatch(void) die("CoreHi interrupt", regs); } +static irqreturn_t corehi_handler(int irq, void *dev_id) +{ + corehi_irqdispatch(); + return IRQ_HANDLED; +} + static inline int clz(unsigned long x) { __asm__( @@ -286,10 +273,9 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); - if (irq == MIPSCPU_INT_I8259A) - malta_hw0_irqdispatch(); - else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) - malta_ipi_irqdispatch(); + /* HACK: GIC doesn't properly dispatch local interrupts yet */ + if (gic_present && irq == MIPSCPU_INT_GIC && gic_compare_int()) + do_IRQ(MIPS_GIC_IRQ_BASE); else do_IRQ(MIPS_CPU_IRQ_BASE + irq); } @@ -312,13 +298,6 @@ static void ipi_call_dispatch(void) do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); } -#endif /* CONFIG_MIPS_MT_SMP */ - -#ifdef CONFIG_MIPS_GIC_IPI - -#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 -#define GIC_MIPS_CPU_IPI_CALL_IRQ 4 - static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) { #ifdef CONFIG_MIPS_VPE_APSP_API_CMP @@ -349,31 +328,16 @@ static struct irqaction irq_call = { .flags = IRQF_PERCPU, .name = "IPI_call" }; -#endif /* CONFIG_MIPS_GIC_IPI */ - -static int gic_resched_int_base; -static int gic_call_int_base; -#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) -#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) - -unsigned int plat_ipi_call_int_xlate(unsigned int cpu) -{ - return GIC_CALL_INT(cpu); -} - -unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) -{ - return GIC_RESCHED_INT(cpu); -} +#endif /* CONFIG_MIPS_MT_SMP */ static struct irqaction i8259irq = { - .handler = no_action, + .handler = i8259_handler, .name = "XT-PIC cascade", .flags = IRQF_NO_THREAD, }; static struct irqaction corehi_irqaction = { - .handler = no_action, + .handler = corehi_handler, .name = "CoreHi", .flags = IRQF_NO_THREAD, }; @@ -399,60 +363,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = { static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); -/* - * This GIC specific tabular array defines the association between External - * Interrupts and CPUs/Core Interrupts. The nature of the External - * Interrupts is also defined here - polarity/trigger. - */ - -#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK -#define X GIC_UNUSED - -static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { X, X, X, X, 0 }, - { X, X, X, X, 0 }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { X, X, X, X, 0 }, - /* The remainder of this table is initialised by fill_ipi_map */ -}; -#undef X - -#ifdef CONFIG_MIPS_GIC_IPI -static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) -{ - int intr = baseintr + cpu; - gic_intr_map[intr].cpunum = cpu; - gic_intr_map[intr].pin = cpupin; - gic_intr_map[intr].polarity = GIC_POL_POS; - gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; - gic_intr_map[intr].flags = 0; - ipi_map[cpu] |= (1 << (cpupin + 2)); - bitmap_set(ipi_ints, intr, 1); -} - -static void __init fill_ipi_map(void) -{ - int cpu; - - for (cpu = 0; cpu < nr_cpu_ids; cpu++) { - fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); - fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); - } -} -#endif - void __init arch_init_ipiirq(int irq, struct irqaction *action) { setup_irq(irq, action); @@ -461,6 +371,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action) void __init arch_init_irq(void) { + int corehi_irq, i8259_irq; + init_i8259_irqs(); if (!cpu_has_veic) @@ -507,34 +419,11 @@ void __init arch_init_irq(void) msc_nr_irqs); } - if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); - set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); - setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); - setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); - } else if (cpu_has_vint) { - set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); - set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, - &corehi_irqaction); - } else { - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, - &corehi_irqaction); - } - if (gic_present) { - /* FIXME */ int i; -#if defined(CONFIG_MIPS_GIC_IPI) - gic_call_int_base = GIC_NUM_INTRS - - (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; - gic_resched_int_base = gic_call_int_base - nr_cpu_ids; - fill_ipi_map(); -#endif - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, - ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); + + gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, + MIPS_GIC_IRQ_BASE); if (!mips_cm_present()) { /* Enable the GIC */ i = REG(_msc01_biu_base, MSC01_SC_CFG); @@ -542,28 +431,8 @@ void __init arch_init_irq(void) (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); pr_debug("GIC Enabled\n"); } -#if defined(CONFIG_MIPS_GIC_IPI) - /* set up ipi interrupts */ - if (cpu_has_vint) { - set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); - set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); - } - /* Argh.. this really needs sorting out.. */ - pr_info("CPU%d: status register was %08x\n", - smp_processor_id(), read_c0_status()); - write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); - pr_info("CPU%d: status register now %08x\n", - smp_processor_id(), read_c0_status()); - write_c0_status(0x1100dc00); - pr_info("CPU%d: status register frc %08x\n", - smp_processor_id(), read_c0_status()); - for (i = 0; i < nr_cpu_ids; i++) { - arch_init_ipiirq(MIPS_GIC_IRQ_BASE + - GIC_RESCHED_INT(i), &irq_resched); - arch_init_ipiirq(MIPS_GIC_IRQ_BASE + - GIC_CALL_INT(i), &irq_call); - } -#endif + i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; + corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else { #if defined(CONFIG_MIPS_MT_SMP) /* set up ipi interrupts */ @@ -587,7 +456,21 @@ void __init arch_init_irq(void) arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); #endif + if (cpu_has_veic) { + set_vi_handler(MSC01E_INT_I8259A, + malta_hw0_irqdispatch); + set_vi_handler(MSC01E_INT_COREHI, + corehi_irqdispatch); + i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; + corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; + } else { + i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; + corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; + } } + + setup_irq(i8259_irq, &i8259irq); + setup_irq(corehi_irq, &corehi_irqaction); } void malta_be_init(void) diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c index 772fc056a92d..4ddaa0fd5804 100644 --- a/arch/mips/mti-sead3/sead3-ehci.c +++ b/arch/mips/mti-sead3/sead3-ehci.c @@ -10,6 +10,9 @@ #include #include +#include +#include + struct resource ehci_resources[] = { { .start = 0x1b200000, @@ -17,7 +20,6 @@ struct resource ehci_resources[] = { .flags = IORESOURCE_MEM }, { - .start = MIPS_CPU_IRQ_BASE + 2, .flags = IORESOURCE_IRQ } }; @@ -37,6 +39,10 @@ static struct platform_device ehci_device = { static int __init ehci_init(void) { + if (gic_present) + ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI; + else + ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI; return platform_device_register(&ehci_device); } diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 8f3634281ed9..cb06cd954a13 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -22,30 +22,6 @@ static unsigned long sead3_config_reg; -/* - * This table defines the setup for each external GIC interrupt. It is - * indexed by interrupt number. - */ -#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK -static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { - { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, - { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, -}; - asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; @@ -81,7 +57,7 @@ void __init arch_init_irq(void) (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); if (gic_present) - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, - ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); + gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC, + MIPS_GIC_IRQ_BASE); } diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c index dd11e7eb771c..c9f728a41bdb 100644 --- a/arch/mips/mti-sead3/sead3-net.c +++ b/arch/mips/mti-sead3/sead3-net.c @@ -10,6 +10,9 @@ #include #include +#include +#include + static struct smsc911x_platform_config sead3_smsc911x_data = { .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, @@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = { .phy_interface = PHY_INTERFACE_MODE_MII, }; -struct resource sead3_net_resourcess[] = { +struct resource sead3_net_resources[] = { { .start = 0x1f010000, .end = 0x1f01ffff, .flags = IORESOURCE_MEM }, { - .start = MIPS_CPU_IRQ_BASE + 6, .flags = IORESOURCE_IRQ } }; @@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = { .dev = { .platform_data = &sead3_smsc911x_data, }, - .num_resources = ARRAY_SIZE(sead3_net_resourcess), - .resource = sead3_net_resourcess + .num_resources = ARRAY_SIZE(sead3_net_resources), + .resource = sead3_net_resources }; static int __init sead3_net_init(void) { + if (gic_present) + sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET; + else + sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET; return platform_device_register(&sead3_net_device); } diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 6c3b33dbed18..d9661eb6fd6d 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -9,10 +9,13 @@ #include #include -#define UART(base, int) \ +#include +#include + +#define UART(base) \ { \ .mapbase = base, \ - .irq = int, \ + .irq = -1, \ .uartclk = 14745600, \ .iotype = UPIO_MEM32, \ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ @@ -20,8 +23,8 @@ } static struct plat_serial8250_port uart8250_data[] = { - UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ - UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ + UART(0x1f000900), /* ttyS0 = USB */ + UART(0x1f000800), /* ttyS1 = RS232 */ { }, }; @@ -35,6 +38,13 @@ static struct platform_device uart8250_device = { static int __init uart8250_init(void) { + if (gic_present) { + uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0; + uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1; + } else { + uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0; + uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1; + } return platform_device_register(&uart8250_device); } diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 79ab99781534..633a34639388 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -8,6 +8,8 @@ */ #include #include +#include +#include #include #include #include @@ -22,11 +24,8 @@ unsigned int gic_frequency; unsigned int gic_present; unsigned long _gic_base; -unsigned int gic_irq_base; unsigned int gic_irq_flags[GIC_NUM_INTRS]; - -/* The index into this array is the vector # of the interrupt. */ -struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; +unsigned int gic_cpu_pin; struct gic_pcpu_mask { DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); @@ -46,6 +45,8 @@ static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; +static void __gic_irq_dispatch(void); + #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) { @@ -117,21 +118,6 @@ void gic_send_ipi(unsigned int intr) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); } -static void gic_eic_irq_dispatch(void) -{ - unsigned int cause = read_c0_cause(); - int irq; - - irq = (cause & ST0_IM) >> STATUSB_IP2; - if (irq == 0) - irq = -1; - - if (irq >= 0) - do_IRQ(gic_irq_base + irq); - else - spurious_interrupt(); -} - static void __init vpe_local_setup(unsigned int numvpes) { unsigned long timer_intr = GIC_INT_TMR; @@ -166,16 +152,15 @@ static void __init vpe_local_setup(unsigned int numvpes) GIC_MAP_TO_PIN_MSK | timer_intr); if (cpu_has_veic) { set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET, - gic_eic_irq_dispatch); - gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK; + __gic_irq_dispatch); } if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), GIC_MAP_TO_PIN_MSK | perf_intr); if (cpu_has_veic) { - set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch); - gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK; + set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, + __gic_irq_dispatch); } } } @@ -343,64 +328,100 @@ static struct irq_chip gic_irq_controller = { #endif }; -static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, - unsigned int pin, unsigned int polarity, unsigned int trigtype, - unsigned int flags) +static void __gic_irq_dispatch(void) { - struct gic_shared_intr_map *map_ptr; - int i; - - /* Setup Intr to Pin mapping */ - if (pin & GIC_MAP_TO_NMI_MSK) { - int i; + unsigned int intr, virq; - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); - /* FIXME: hack to route NMI to all cpu's */ - for (i = 0; i < NR_CPUS; i += 32) { - GICWRITE(GIC_REG_ADDR(SHARED, - GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), - 0xffffffff); - } - } else { - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), - GIC_MAP_TO_PIN_MSK | pin); - /* Setup Intr to CPU mapping */ - GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); - if (cpu_has_veic) { - set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET, - gic_eic_irq_dispatch); - map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET]; - if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR) - BUG(); - map_ptr->intr_list[map_ptr->num_shared_intr++] = intr; - } + while ((intr = gic_get_int()) != GIC_NUM_INTRS) { + virq = irq_linear_revmap(gic_irq_domain, intr); + do_IRQ(virq); } +} - /* Setup Intr Polarity */ - GIC_SET_POLARITY(intr, polarity); +static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) +{ + __gic_irq_dispatch(); +} + +#ifdef CONFIG_MIPS_GIC_IPI +static int gic_resched_int_base; +static int gic_call_int_base; + +unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) +{ + return gic_resched_int_base + cpu; +} - /* Setup Intr Trigger Type */ - GIC_SET_TRIGGER(intr, trigtype); +unsigned int plat_ipi_call_int_xlate(unsigned int cpu) +{ + return gic_call_int_base + cpu; +} - /* Init Intr Masks */ - GIC_CLR_INTR_MASK(intr); +static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) +{ + scheduler_ipi(); + + return IRQ_HANDLED; +} + +static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) +{ + smp_call_function_interrupt(); + + return IRQ_HANDLED; +} - /* Initialise per-cpu Interrupt software masks */ +static struct irqaction irq_resched = { + .handler = ipi_resched_interrupt, + .flags = IRQF_PERCPU, + .name = "IPI resched" +}; + +static struct irqaction irq_call = { + .handler = ipi_call_interrupt, + .flags = IRQF_PERCPU, + .name = "IPI call" +}; + +static __init void gic_ipi_init_one(unsigned int intr, int cpu, + struct irqaction *action) +{ + int virq = irq_create_mapping(gic_irq_domain, intr); + int i; + + GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); for (i = 0; i < NR_CPUS; i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[cpu].pcpu_mask); - if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) - GIC_SET_INTR_MASK(intr); - if (trigtype == GIC_TRIG_EDGE) - gic_irq_flags[intr] |= GIC_TRIG_EDGE; + irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING); + + irq_set_handler(virq, handle_percpu_irq); + setup_irq(virq, action); } -static void __init gic_basic_init(int numintrs, int numvpes, - struct gic_intr_map *intrmap, int mapsize) +static __init void gic_ipi_init(void) { - unsigned int i, cpu; - unsigned int pin_offset = 0; + int i; + + /* Use last 2 * NR_CPUS interrupts as IPIs */ + gic_resched_int_base = GIC_NUM_INTRS - nr_cpu_ids; + gic_call_int_base = gic_resched_int_base - nr_cpu_ids; + + for (i = 0; i < nr_cpu_ids; i++) { + gic_ipi_init_one(gic_call_int_base + i, i, &irq_call); + gic_ipi_init_one(gic_resched_int_base + i, i, &irq_resched); + } +} +#else +static inline void gic_ipi_init(void) +{ +} +#endif + +static void __init gic_basic_init(int numintrs, int numvpes) +{ + unsigned int i; board_bind_eic_interrupt = &gic_bind_eic_interrupt; @@ -409,31 +430,8 @@ static void __init gic_basic_init(int numintrs, int numvpes, GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); GIC_CLR_INTR_MASK(i); - if (i < GIC_NUM_INTRS) { + if (i < GIC_NUM_INTRS) gic_irq_flags[i] = 0; - gic_shared_intr_map[i].num_shared_intr = 0; - gic_shared_intr_map[i].local_intr_mask = 0; - } - } - - /* - * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract - * one because the GIC will add one (since 0=no intr). - */ - if (cpu_has_veic) - pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); - - /* Setup specifics */ - for (i = 0; i < mapsize; i++) { - cpu = intrmap[i].cpunum; - if (cpu == GIC_UNUSED) - continue; - gic_setup_intr(i, - intrmap[i].cpunum, - intrmap[i].pin + pin_offset, - intrmap[i].polarity, - intrmap[i].trigtype, - intrmap[i].flags); } vpe_local_setup(numvpes); @@ -448,7 +446,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(&gic_lock, flags); GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)), - GIC_MAP_TO_PIN_MSK | 0); + GIC_MAP_TO_PIN_MSK | gic_cpu_pin); /* Map to VPE 0 by default */ GIC_SH_MAP_TO_VPE_SMASK(hw, 0); set_bit(hw, pcpu_masks[0].pcpu_mask); @@ -463,8 +461,7 @@ static struct irq_domain_ops gic_irq_domain_ops = { }; void __init gic_init(unsigned long gic_base_addr, - unsigned long gic_addrspace_size, - struct gic_intr_map *intr_map, unsigned int intr_map_size, + unsigned long gic_addrspace_size, unsigned int cpu_vec, unsigned int irqbase) { unsigned int gicconfig; @@ -472,7 +469,6 @@ void __init gic_init(unsigned long gic_base_addr, _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, gic_addrspace_size); - gic_irq_base = irqbase; GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> @@ -483,10 +479,23 @@ void __init gic_init(unsigned long gic_base_addr, GIC_SH_CONFIG_NUMVPES_SHF; numvpes = numvpes + 1; + if (cpu_has_veic) { + /* Always use vector 1 in EIC mode */ + gic_cpu_pin = 0; + set_vi_handler(gic_cpu_pin + GIC_PIN_TO_VEC_OFFSET, + __gic_irq_dispatch); + } else { + gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET; + irq_set_chained_handler(MIPS_CPU_IRQ_BASE + cpu_vec, + gic_irq_dispatch); + } + gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_INTRS, irqbase, &gic_irq_domain_ops, NULL); if (!gic_irq_domain) panic("Failed to add GIC IRQ domain"); - gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); + gic_basic_init(numintrs, numvpes); + + gic_ipi_init(); } -- GitLab From fbd552417bf275f6da591a0118a019b3006245fd Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:25 -0700 Subject: [PATCH 5972/9457] irqchip: mips-gic: Probe for number of external interrupts Instead of requiring platforms to define the correct GIC_NUM_INTRS, use the value reported in GIC_SH_CONFIG. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7817/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 2 ++ arch/mips/include/asm/mach-malta/irq.h | 1 - arch/mips/include/asm/mach-sead3/irq.h | 1 - drivers/irqchip/irq-mips-gic.c | 40 +++++++++++++------------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index cfbf907ebfa5..8d1e457c0af9 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -18,6 +18,8 @@ #undef GICISBYTELITTLEENDIAN +#define GIC_MAX_INTRS 256 + /* Constants */ #define GIC_POL_POS 1 #define GIC_POL_NEG 0 diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h index f2c13d211abb..47cfe64efbb0 100644 --- a/arch/mips/include/asm/mach-malta/irq.h +++ b/arch/mips/include/asm/mach-malta/irq.h @@ -2,7 +2,6 @@ #define __ASM_MACH_MIPS_IRQ_H -#define GIC_NUM_INTRS (24 + NR_CPUS * 2) #define NR_IRQS 256 #include_next diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h index d8106f75b9af..5d154cfbcf4c 100644 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ b/arch/mips/include/asm/mach-sead3/irq.h @@ -1,7 +1,6 @@ #ifndef __ASM_MACH_MIPS_IRQ_H #define __ASM_MACH_MIPS_IRQ_H -#define GIC_NUM_INTRS (24 + NR_CPUS * 2) #define NR_IRQS 256 diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 633a34639388..3cd91d34973d 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -28,15 +28,15 @@ unsigned int gic_irq_flags[GIC_NUM_INTRS]; unsigned int gic_cpu_pin; struct gic_pcpu_mask { - DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); + DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); }; struct gic_pending_regs { - DECLARE_BITMAP(pending, GIC_NUM_INTRS); + DECLARE_BITMAP(pending, GIC_MAX_INTRS); }; struct gic_intrmask_regs { - DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); + DECLARE_BITMAP(intrmask, GIC_MAX_INTRS); }; static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; @@ -44,6 +44,7 @@ static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; +static int gic_shared_intrs; static void __gic_irq_dispatch(void); @@ -192,26 +193,26 @@ void gic_get_int_mask(unsigned long *dst, const unsigned long *src) intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, GIC_SH_MASK_31_0_OFS); - for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { + for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) { GICREAD(*pending_abs, pending[i]); GICREAD(*intrmask_abs, intrmask[i]); pending_abs++; intrmask_abs++; } - bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); - bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); - bitmap_and(dst, src, pending, GIC_NUM_INTRS); + bitmap_and(pending, pending, intrmask, gic_shared_intrs); + bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); + bitmap_and(dst, src, pending, gic_shared_intrs); } unsigned int gic_get_int(void) { - DECLARE_BITMAP(interrupts, GIC_NUM_INTRS); + DECLARE_BITMAP(interrupts, GIC_MAX_INTRS); - bitmap_fill(interrupts, GIC_NUM_INTRS); + bitmap_fill(interrupts, gic_shared_intrs); gic_get_int_mask(interrupts, interrupts); - return find_first_bit(interrupts, GIC_NUM_INTRS); + return find_first_bit(interrupts, gic_shared_intrs); } static void gic_mask_irq(struct irq_data *d) @@ -332,7 +333,7 @@ static void __gic_irq_dispatch(void) { unsigned int intr, virq; - while ((intr = gic_get_int()) != GIC_NUM_INTRS) { + while ((intr = gic_get_int()) != gic_shared_intrs) { virq = irq_linear_revmap(gic_irq_domain, intr); do_IRQ(virq); } @@ -405,7 +406,7 @@ static __init void gic_ipi_init(void) int i; /* Use last 2 * NR_CPUS interrupts as IPIs */ - gic_resched_int_base = GIC_NUM_INTRS - nr_cpu_ids; + gic_resched_int_base = gic_shared_intrs - nr_cpu_ids; gic_call_int_base = gic_resched_int_base - nr_cpu_ids; for (i = 0; i < nr_cpu_ids; i++) { @@ -419,19 +420,18 @@ static inline void gic_ipi_init(void) } #endif -static void __init gic_basic_init(int numintrs, int numvpes) +static void __init gic_basic_init(int numvpes) { unsigned int i; board_bind_eic_interrupt = &gic_bind_eic_interrupt; /* Setup defaults */ - for (i = 0; i < numintrs; i++) { + for (i = 0; i < gic_shared_intrs; i++) { GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); GIC_CLR_INTR_MASK(i); - if (i < GIC_NUM_INTRS) - gic_irq_flags[i] = 0; + gic_irq_flags[i] = 0; } vpe_local_setup(numvpes); @@ -471,9 +471,9 @@ void __init gic_init(unsigned long gic_base_addr, gic_addrspace_size); GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); - numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> + gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> GIC_SH_CONFIG_NUMINTRS_SHF; - numintrs = ((numintrs + 1) * 8); + gic_shared_intrs = ((gic_shared_intrs + 1) * 8); numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> GIC_SH_CONFIG_NUMVPES_SHF; @@ -490,12 +490,12 @@ void __init gic_init(unsigned long gic_base_addr, gic_irq_dispatch); } - gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_INTRS, irqbase, + gic_irq_domain = irq_domain_add_simple(NULL, gic_shared_intrs, irqbase, &gic_irq_domain_ops, NULL); if (!gic_irq_domain) panic("Failed to add GIC IRQ domain"); - gic_basic_init(numintrs, numvpes); + gic_basic_init(numvpes); gic_ipi_init(); } -- GitLab From 4a6a3ea392306b04fc687d4314efba562121cc9a Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:26 -0700 Subject: [PATCH 5973/9457] irqchip: mips-gic: Use separate edge/level irq_chips GIC edge-triggered interrupts must be acknowledged by clearing the edge detector via a write to GIC_SH_WEDGE. Create a separate edge-triggered irq_chip with the appropriate irq_ack() callback. This also allows us to get rid of gic_irq_flags. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7818/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 1 - drivers/irqchip/irq-mips-gic.c | 32 +++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 8d1e457c0af9..f2453958cbe5 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -345,7 +345,6 @@ extern unsigned int gic_present; extern unsigned int gic_frequency; extern unsigned long _gic_base; -extern unsigned int gic_irq_flags[]; extern unsigned int gic_cpu_pin; extern void gic_init(unsigned long gic_base_addr, diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 3cd91d34973d..64d7d571df62 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -24,7 +24,6 @@ unsigned int gic_frequency; unsigned int gic_present; unsigned long _gic_base; -unsigned int gic_irq_flags[GIC_NUM_INTRS]; unsigned int gic_cpu_pin; struct gic_pcpu_mask { @@ -45,6 +44,7 @@ static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; static int gic_shared_intrs; +static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; static void __gic_irq_dispatch(void); @@ -229,9 +229,7 @@ static void gic_ack_irq(struct irq_data *d) { unsigned int irq = d->hwirq; - /* Clear edge detector */ - if (gic_irq_flags[irq] & GIC_TRIG_EDGE) - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); + GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); } static int gic_set_type(struct irq_data *d, unsigned int type) @@ -276,11 +274,13 @@ static int gic_set_type(struct irq_data *d, unsigned int type) } if (is_edge) { - gic_irq_flags[irq] |= GIC_TRIG_EDGE; - __irq_set_handler_locked(d->irq, handle_edge_irq); + __irq_set_chip_handler_name_locked(d->irq, + &gic_edge_irq_controller, + handle_edge_irq, NULL); } else { - gic_irq_flags[irq] &= ~GIC_TRIG_EDGE; - __irq_set_handler_locked(d->irq, handle_level_irq); + __irq_set_chip_handler_name_locked(d->irq, + &gic_level_irq_controller, + handle_level_irq, NULL); } spin_unlock_irqrestore(&gic_lock, flags); @@ -318,7 +318,17 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, } #endif -static struct irq_chip gic_irq_controller = { +static struct irq_chip gic_level_irq_controller = { + .name = "MIPS GIC", + .irq_mask = gic_mask_irq, + .irq_unmask = gic_unmask_irq, + .irq_set_type = gic_set_type, +#ifdef CONFIG_SMP + .irq_set_affinity = gic_set_affinity, +#endif +}; + +static struct irq_chip gic_edge_irq_controller = { .name = "MIPS GIC", .irq_ack = gic_ack_irq, .irq_mask = gic_mask_irq, @@ -431,7 +441,6 @@ static void __init gic_basic_init(int numvpes) GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); GIC_CLR_INTR_MASK(i); - gic_irq_flags[i] = 0; } vpe_local_setup(numvpes); @@ -442,7 +451,8 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, { unsigned long flags; - irq_set_chip_and_handler(virq, &gic_irq_controller, handle_level_irq); + irq_set_chip_and_handler(virq, &gic_level_irq_controller, + handle_level_irq); spin_lock_irqsave(&gic_lock, flags); GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)), -- GitLab From e9de688dac6534e72d000e9069be2f929a6087be Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:27 -0700 Subject: [PATCH 5974/9457] irqchip: mips-gic: Support local interrupts The MIPS GIC supports 7 local interrupts, 2 of which are the GIC local watchdog and count/compare timer. The remainder are CPU interrupts which may optionally be re-routed through the GIC. GIC hardware IRQs 0-6 are now used for local interrupts while hardware IRQs 7+ are used for external (shared) interrupts. Note that the 5 CPU interrupts may not be re-routable through the GIC. In that case mapping will fail and the vectors reported in C0_IntCtl should be used instead. gic_get_c0_compare_int() and gic_get_c0_perfcount_int() will return the correct IRQ number to use for the C0 timer and perfcounter interrupts based on the routability of those interrupts through the GIC. A separate irq_chip, with callbacks that mask/unmask the local interrupt on all CPUs, is used for the C0 timer and performance counter interrupts since all other platforms do not use the percpu IRQ API for those interrupts. Malta, SEAD-3, and the GIC clockevent driver have been updated to use local interrupts and the R4K clockevent driver has been updated to poll for C0 timer interrupts through the GIC when the GIC is present. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7819/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 29 +- arch/mips/include/asm/mips-boards/maltaint.h | 4 +- arch/mips/include/asm/mips-boards/sead3int.h | 10 +- arch/mips/kernel/cevt-gic.c | 15 +- arch/mips/kernel/cevt-r4k.c | 2 +- arch/mips/mti-malta/malta-int.c | 6 +- arch/mips/mti-malta/malta-time.c | 13 +- arch/mips/mti-sead3/sead3-time.c | 34 +-- drivers/irqchip/irq-mips-gic.c | 291 ++++++++++++++----- 9 files changed, 279 insertions(+), 125 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index f2453958cbe5..6b996105c4fe 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -209,6 +209,7 @@ #define GIC_VPE_WD_MAP_OFS 0x0040 #define GIC_VPE_COMPARE_MAP_OFS 0x0044 #define GIC_VPE_TIMER_MAP_OFS 0x0048 +#define GIC_VPE_FDC_MAP_OFS 0x004c #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 #define GIC_VPE_SWINT0_MAP_OFS 0x0054 #define GIC_VPE_SWINT1_MAP_OFS 0x0058 @@ -262,6 +263,10 @@ #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) /* GIC_VPE_CTL Masks */ +#define GIC_VPE_CTL_FDC_RTBL_SHF 4 +#define GIC_VPE_CTL_FDC_RTBL_MSK (MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF) +#define GIC_VPE_CTL_SWINT_RTBL_SHF 3 +#define GIC_VPE_CTL_SWINT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF) #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 @@ -329,16 +334,30 @@ /* Add 2 to convert GIC CPU pin to core interrupt */ #define GIC_CPU_PIN_OFFSET 2 -/* Local GIC interrupts. */ -#define GIC_INT_TMR (GIC_CPU_INT5) -#define GIC_INT_PERFCTR (GIC_CPU_INT5) - /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ #define GIC_CPU_TO_VEC_OFFSET (2) /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ #define GIC_PIN_TO_VEC_OFFSET (1) +/* Local GIC interrupts. */ +#define GIC_LOCAL_INT_WD 0 /* GIC watchdog */ +#define GIC_LOCAL_INT_COMPARE 1 /* GIC count and compare timer */ +#define GIC_LOCAL_INT_TIMER 2 /* CPU timer interrupt */ +#define GIC_LOCAL_INT_PERFCTR 3 /* CPU performance counter */ +#define GIC_LOCAL_INT_SWINT0 4 /* CPU software interrupt 0 */ +#define GIC_LOCAL_INT_SWINT1 5 /* CPU software interrupt 1 */ +#define GIC_LOCAL_INT_FDC 6 /* CPU fast debug channel */ +#define GIC_NUM_LOCAL_INTRS 7 + +/* Convert between local/shared IRQ number and GIC HW IRQ number. */ +#define GIC_LOCAL_HWIRQ_BASE 0 +#define GIC_LOCAL_TO_HWIRQ(x) (GIC_LOCAL_HWIRQ_BASE + (x)) +#define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE) +#define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS +#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) +#define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) + #include #include @@ -363,4 +382,6 @@ extern void gic_bind_eic_interrupt(int irq, int set); extern unsigned int gic_get_timer_pending(void); extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); extern unsigned int gic_get_int(void); +extern int gic_get_c0_compare_int(void); +extern int gic_get_c0_perfcount_int(void); #endif /* _ASM_GICREGS_H */ diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index bdd6f392f160..38b06a027437 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -10,6 +10,8 @@ #ifndef _MIPS_MALTAINT_H #define _MIPS_MALTAINT_H +#include + /* * Interrupts 0..15 are used for Malta ISA compatible interrupts */ @@ -61,6 +63,6 @@ #define MSC01E_INT_CPUCTR 11 /* GIC external interrupts */ -#define GIC_INT_I8259A 3 +#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3) #endif /* !(_MIPS_MALTAINT_H) */ diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index a2e0095440fe..59d6c32c7595 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -10,6 +10,8 @@ #ifndef _MIPS_SEAD3INT_H #define _MIPS_SEAD3INT_H +#include + /* SEAD-3 GIC address space definitions. */ #define GIC_BASE_ADDR 0x1b1c0000 #define GIC_ADDRSPACE_SZ (128 * 1024) @@ -22,9 +24,9 @@ #define CPU_INT_NET 6 /* GIC interrupt offsets */ -#define GIC_INT_NET 0 -#define GIC_INT_UART1 2 -#define GIC_INT_UART0 3 -#define GIC_INT_EHCI 5 +#define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) +#define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2) +#define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3) +#define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) #endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c index a90bd4c81c7d..4f9262ab04f9 100644 --- a/arch/mips/kernel/cevt-gic.c +++ b/arch/mips/kernel/cevt-gic.c @@ -68,7 +68,7 @@ int gic_clockevent_init(void) if (!cpu_has_counter || !gic_frequency) return -ENXIO; - irq = MIPS_GIC_IRQ_BASE; + irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); cd = &per_cpu(gic_clockevent_device, cpu); @@ -91,16 +91,13 @@ int gic_clockevent_init(void) clockevents_register_device(cd); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), - GIC_MAP_TO_PIN_MSK | gic_cpu_pin); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); + if (!gic_timer_irq_installed) { + setup_percpu_irq(irq, &gic_compare_irqaction); + gic_timer_irq_installed = 1; + } - if (gic_timer_irq_installed) - return 0; + enable_percpu_irq(irq, IRQ_TYPE_NONE); - gic_timer_irq_installed = 1; - setup_irq(irq, &gic_compare_irqaction); - irq_set_handler(irq, handle_percpu_irq); return 0; } diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 5b8f8e32b47d..fd0ef8d851cc 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -86,7 +86,7 @@ void mips_event_handler(struct clock_event_device *dev) static int c0_compare_int_pending(void) { #ifdef CONFIG_MIPS_GIC - if (cpu_has_veic) + if (gic_present) return gic_get_timer_pending(); #endif return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 3b3bc1d9ebf9..c6b35482505d 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -273,11 +273,7 @@ asmlinkage void plat_irq_dispatch(void) irq = irq_ffs(pending); - /* HACK: GIC doesn't properly dispatch local interrupts yet */ - if (gic_present && irq == MIPSCPU_INT_GIC && gic_compare_int()) - do_IRQ(MIPS_GIC_IRQ_BASE); - else - do_IRQ(MIPS_CPU_IRQ_BASE + irq); + do_IRQ(MIPS_CPU_IRQ_BASE + irq); } #ifdef CONFIG_MIPS_MT_SMP diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 17cfc8a379a6..f6ca8ea4d992 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -126,9 +126,9 @@ int get_c0_perfcount_int(void) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; + } else if (gic_present) { + mips_cpu_perf_irq = gic_get_c0_perfcount_int(); } else if (cp0_perfcount_irq >= 0) { - if (cpu_has_vint) - set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; } else { mips_cpu_perf_irq = -1; @@ -139,15 +139,12 @@ int get_c0_perfcount_int(void) unsigned int get_c0_compare_int(void) { -#ifdef MSC01E_INT_BASE if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } else -#endif - { - if (cpu_has_vint) - set_vi_handler(cp0_compare_irq, mips_timer_dispatch); + } else if (gic_present) { + mips_cpu_timer_irq = gic_get_c0_compare_int(); + } else { mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; } diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index f090c5177719..fd40de352c57 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c @@ -8,24 +8,12 @@ #include #include +#include #include #include #include #include -static int mips_cpu_timer_irq; -static int mips_cpu_perf_irq; - -static void mips_timer_dispatch(void) -{ - do_IRQ(mips_cpu_timer_irq); -} - -static void mips_perf_dispatch(void) -{ - do_IRQ(mips_cpu_perf_irq); -} - static void __iomem *status_reg = (void __iomem *)0xbf000410; /* @@ -83,22 +71,18 @@ void read_persistent_clock(struct timespec *ts) int get_c0_perfcount_int(void) { - if (cp0_perfcount_irq >= 0) { - if (cpu_has_vint) - set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); - mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - } else { - mips_cpu_perf_irq = -1; - } - return mips_cpu_perf_irq; + if (gic_present) + return gic_get_c0_compare_int(); + if (cp0_perfcount_irq >= 0) + return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + return -1; } unsigned int get_c0_compare_int(void) { - if (cpu_has_vint) - set_vi_handler(cp0_compare_irq, mips_timer_dispatch); - mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; - return mips_cpu_timer_irq; + if (gic_present) + return gic_get_c0_compare_int(); + return MIPS_CPU_IRQ_BASE + cp0_compare_irq; } void __init plat_time_init(void) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 64d7d571df62..d4f631ec7338 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -44,6 +44,7 @@ static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; static int gic_shared_intrs; +static int gic_vpes; static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; static void __gic_irq_dispatch(void); @@ -96,12 +97,35 @@ cycle_t gic_read_compare(void) } #endif +static bool gic_local_irq_is_routable(int intr) +{ + u32 vpe_ctl; + + /* All local interrupts are routable in EIC mode. */ + if (cpu_has_veic) + return true; + + GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_CTL), vpe_ctl); + switch (intr) { + case GIC_LOCAL_INT_TIMER: + return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK; + case GIC_LOCAL_INT_PERFCTR: + return vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK; + case GIC_LOCAL_INT_FDC: + return vpe_ctl & GIC_VPE_CTL_FDC_RTBL_MSK; + case GIC_LOCAL_INT_SWINT0: + case GIC_LOCAL_INT_SWINT1: + return vpe_ctl & GIC_VPE_CTL_SWINT_RTBL_MSK; + default: + return true; + } +} + unsigned int gic_get_timer_pending(void) { unsigned int vpe_pending; - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); - GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending); + GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), vpe_pending); return vpe_pending & GIC_VPE_PEND_TIMER_MSK; } @@ -119,53 +143,6 @@ void gic_send_ipi(unsigned int intr) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); } -static void __init vpe_local_setup(unsigned int numvpes) -{ - unsigned long timer_intr = GIC_INT_TMR; - unsigned long perf_intr = GIC_INT_PERFCTR; - unsigned int vpe_ctl; - int i; - - if (cpu_has_veic) { - /* - * GIC timer interrupt -> CPU HW Int X (vector X+2) -> - * map to pin X+2-1 (since GIC adds 1) - */ - timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); - /* - * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) -> - * map to pin X+2-1 (since GIC adds 1) - */ - perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); - } - - /* - * Setup the default performance counter timer interrupts - * for all VPEs - */ - for (i = 0; i < numvpes; i++) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); - - /* Are Interrupts locally routable? */ - GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); - if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), - GIC_MAP_TO_PIN_MSK | timer_intr); - if (cpu_has_veic) { - set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET, - __gic_irq_dispatch); - } - - if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), - GIC_MAP_TO_PIN_MSK | perf_intr); - if (cpu_has_veic) { - set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, - __gic_irq_dispatch); - } - } -} - unsigned int gic_compare_int(void) { unsigned int pending; @@ -177,6 +154,26 @@ unsigned int gic_compare_int(void) return 0; } +int gic_get_c0_compare_int(void) +{ + if (!gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) + return MIPS_CPU_IRQ_BASE + cp0_compare_irq; + return irq_create_mapping(gic_irq_domain, + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_TIMER)); +} + +int gic_get_c0_perfcount_int(void) +{ + if (!gic_local_irq_is_routable(GIC_LOCAL_INT_PERFCTR)) { + /* Is the erformance counter shared with the timer? */ + if (cp0_perfcount_irq < 0) + return -1; + return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + } + return irq_create_mapping(gic_irq_domain, + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR)); +} + void gic_get_int_mask(unsigned long *dst, const unsigned long *src) { unsigned int i; @@ -217,24 +214,24 @@ unsigned int gic_get_int(void) static void gic_mask_irq(struct irq_data *d) { - GIC_CLR_INTR_MASK(d->hwirq); + GIC_CLR_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq)); } static void gic_unmask_irq(struct irq_data *d) { - GIC_SET_INTR_MASK(d->hwirq); + GIC_SET_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq)); } static void gic_ack_irq(struct irq_data *d) { - unsigned int irq = d->hwirq; + unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); } static int gic_set_type(struct irq_data *d, unsigned int type) { - unsigned int irq = d->hwirq; + unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned long flags; bool is_edge; @@ -291,7 +288,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) { - unsigned int irq = d->hwirq; + unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); cpumask_t tmp = CPU_MASK_NONE; unsigned long flags; int i; @@ -339,12 +336,85 @@ static struct irq_chip gic_edge_irq_controller = { #endif }; +static unsigned int gic_get_local_int(void) +{ + unsigned long pending, masked; + + GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); + GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_MASK), masked); + + bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); + + return find_first_bit(&pending, GIC_NUM_LOCAL_INTRS); +} + +static void gic_mask_local_irq(struct irq_data *d) +{ + int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); + + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr); +} + +static void gic_unmask_local_irq(struct irq_data *d) +{ + int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); + + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr); +} + +static struct irq_chip gic_local_irq_controller = { + .name = "MIPS GIC Local", + .irq_mask = gic_mask_local_irq, + .irq_unmask = gic_unmask_local_irq, +}; + +static void gic_mask_local_irq_all_vpes(struct irq_data *d) +{ + int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); + int i; + unsigned long flags; + + spin_lock_irqsave(&gic_lock, flags); + for (i = 0; i < gic_vpes; i++) { + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); + } + spin_unlock_irqrestore(&gic_lock, flags); +} + +static void gic_unmask_local_irq_all_vpes(struct irq_data *d) +{ + int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); + int i; + unsigned long flags; + + spin_lock_irqsave(&gic_lock, flags); + for (i = 0; i < gic_vpes; i++) { + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); + } + spin_unlock_irqrestore(&gic_lock, flags); +} + +static struct irq_chip gic_all_vpes_local_irq_controller = { + .name = "MIPS GIC Local", + .irq_mask = gic_mask_local_irq_all_vpes, + .irq_unmask = gic_unmask_local_irq_all_vpes, +}; + static void __gic_irq_dispatch(void) { unsigned int intr, virq; + while ((intr = gic_get_local_int()) != GIC_NUM_LOCAL_INTRS) { + virq = irq_linear_revmap(gic_irq_domain, + GIC_LOCAL_TO_HWIRQ(intr)); + do_IRQ(virq); + } + while ((intr = gic_get_int()) != gic_shared_intrs) { - virq = irq_linear_revmap(gic_irq_domain, intr); + virq = irq_linear_revmap(gic_irq_domain, + GIC_SHARED_TO_HWIRQ(intr)); do_IRQ(virq); } } @@ -397,7 +467,8 @@ static struct irqaction irq_call = { static __init void gic_ipi_init_one(unsigned int intr, int cpu, struct irqaction *action) { - int virq = irq_create_mapping(gic_irq_domain, intr); + int virq = irq_create_mapping(gic_irq_domain, + GIC_SHARED_TO_HWIRQ(intr)); int i; GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); @@ -430,7 +501,7 @@ static inline void gic_ipi_init(void) } #endif -static void __init gic_basic_init(int numvpes) +static void __init gic_basic_init(void) { unsigned int i; @@ -443,28 +514,112 @@ static void __init gic_basic_init(int numvpes) GIC_CLR_INTR_MASK(i); } - vpe_local_setup(numvpes); + for (i = 0; i < gic_vpes; i++) { + unsigned int j; + + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) { + if (!gic_local_irq_is_routable(j)) + continue; + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j); + } + } } -static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) +static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) { + int intr = GIC_HWIRQ_TO_LOCAL(hw); + int ret = 0; + int i; + unsigned long flags; + + if (!gic_local_irq_is_routable(intr)) + return -EPERM; + + /* + * HACK: These are all really percpu interrupts, but the rest + * of the MIPS kernel code does not use the percpu IRQ API for + * the CP0 timer and performance counter interrupts. + */ + if (intr != GIC_LOCAL_INT_TIMER && intr != GIC_LOCAL_INT_PERFCTR) { + irq_set_chip_and_handler(virq, + &gic_local_irq_controller, + handle_percpu_devid_irq); + irq_set_percpu_devid(virq); + } else { + irq_set_chip_and_handler(virq, + &gic_all_vpes_local_irq_controller, + handle_percpu_irq); + } + + spin_lock_irqsave(&gic_lock, flags); + for (i = 0; i < gic_vpes; i++) { + u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; + + GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + + switch (intr) { + case GIC_LOCAL_INT_WD: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val); + break; + case GIC_LOCAL_INT_COMPARE: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val); + break; + case GIC_LOCAL_INT_TIMER: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val); + break; + case GIC_LOCAL_INT_PERFCTR: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val); + break; + case GIC_LOCAL_INT_SWINT0: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val); + break; + case GIC_LOCAL_INT_SWINT1: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val); + break; + case GIC_LOCAL_INT_FDC: + GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val); + break; + default: + pr_err("Invalid local IRQ %d\n", intr); + ret = -EINVAL; + break; + } + } + spin_unlock_irqrestore(&gic_lock, flags); + + return ret; +} + +static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + int intr = GIC_HWIRQ_TO_SHARED(hw); unsigned long flags; irq_set_chip_and_handler(virq, &gic_level_irq_controller, handle_level_irq); spin_lock_irqsave(&gic_lock, flags); - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)), + GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), GIC_MAP_TO_PIN_MSK | gic_cpu_pin); /* Map to VPE 0 by default */ - GIC_SH_MAP_TO_VPE_SMASK(hw, 0); - set_bit(hw, pcpu_masks[0].pcpu_mask); + GIC_SH_MAP_TO_VPE_SMASK(intr, 0); + set_bit(intr, pcpu_masks[0].pcpu_mask); spin_unlock_irqrestore(&gic_lock, flags); return 0; } +static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, + irq_hw_number_t hw) +{ + if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) + return gic_local_irq_domain_map(d, virq, hw); + return gic_shared_irq_domain_map(d, virq, hw); +} + static struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, .xlate = irq_domain_xlate_twocell, @@ -475,7 +630,6 @@ void __init gic_init(unsigned long gic_base_addr, unsigned int irqbase) { unsigned int gicconfig; - int numvpes, numintrs; _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, gic_addrspace_size); @@ -485,9 +639,9 @@ void __init gic_init(unsigned long gic_base_addr, GIC_SH_CONFIG_NUMINTRS_SHF; gic_shared_intrs = ((gic_shared_intrs + 1) * 8); - numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> + gic_vpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> GIC_SH_CONFIG_NUMVPES_SHF; - numvpes = numvpes + 1; + gic_vpes = gic_vpes + 1; if (cpu_has_veic) { /* Always use vector 1 in EIC mode */ @@ -500,12 +654,13 @@ void __init gic_init(unsigned long gic_base_addr, gic_irq_dispatch); } - gic_irq_domain = irq_domain_add_simple(NULL, gic_shared_intrs, irqbase, + gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_LOCAL_INTRS + + gic_shared_intrs, irqbase, &gic_irq_domain_ops, NULL); if (!gic_irq_domain) panic("Failed to add GIC IRQ domain"); - gic_basic_init(numvpes); + gic_basic_init(); gic_ipi_init(); } -- GitLab From 3263d085ab5beb84c838f99e4259d2eddbb85654 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:28 -0700 Subject: [PATCH 5975/9457] irqchip: mips-gic: Remove unnecessary globals Now that all GIC interrupt routing and handling logic is in the GIC driver itself, un-export variables/functions which are no longer used outside the GIC driver. This also allows us to remove gic_compare_int and combine gic_get_int_mask with gic_get_int since these interfaces are no longer used. Signed-off-by: Andrew Bresticker Acked-by: Jason Cooper Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7820/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 5 ----- drivers/irqchip/irq-mips-gic.c | 28 ++++------------------------ 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 6b996105c4fe..727b7bf903a8 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -364,13 +364,11 @@ extern unsigned int gic_present; extern unsigned int gic_frequency; extern unsigned long _gic_base; -extern unsigned int gic_cpu_pin; extern void gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, unsigned int cpu_vec, unsigned int irqbase); extern void gic_clocksource_init(unsigned int); -extern unsigned int gic_compare_int (void); extern cycle_t gic_read_count(void); extern cycle_t gic_read_compare(void); extern void gic_write_compare(cycle_t cnt); @@ -378,10 +376,7 @@ extern void gic_write_cpu_compare(cycle_t cnt, int cpu); extern void gic_send_ipi(unsigned int intr); extern unsigned int plat_ipi_call_int_xlate(unsigned int); extern unsigned int plat_ipi_resched_int_xlate(unsigned int); -extern void gic_bind_eic_interrupt(int irq, int set); extern unsigned int gic_get_timer_pending(void); -extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); -extern unsigned int gic_get_int(void); extern int gic_get_c0_compare_int(void); extern int gic_get_c0_perfcount_int(void); #endif /* _ASM_GICREGS_H */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index d4f631ec7338..e49a39a8c853 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -24,7 +24,6 @@ unsigned int gic_frequency; unsigned int gic_present; unsigned long _gic_base; -unsigned int gic_cpu_pin; struct gic_pcpu_mask { DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); @@ -45,6 +44,7 @@ static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; static int gic_shared_intrs; static int gic_vpes; +static unsigned int gic_cpu_pin; static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; static void __gic_irq_dispatch(void); @@ -129,7 +129,7 @@ unsigned int gic_get_timer_pending(void) return vpe_pending & GIC_VPE_PEND_TIMER_MSK; } -void gic_bind_eic_interrupt(int irq, int set) +static void gic_bind_eic_interrupt(int irq, int set) { /* Convert irq vector # to hw int # */ irq -= GIC_PIN_TO_VEC_OFFSET; @@ -143,17 +143,6 @@ void gic_send_ipi(unsigned int intr) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); } -unsigned int gic_compare_int(void) -{ - unsigned int pending; - - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); - if (pending & GIC_VPE_PEND_CMP_MSK) - return 1; - else - return 0; -} - int gic_get_c0_compare_int(void) { if (!gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) @@ -174,7 +163,7 @@ int gic_get_c0_perfcount_int(void) GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR)); } -void gic_get_int_mask(unsigned long *dst, const unsigned long *src) +static unsigned int gic_get_int(void) { unsigned int i; unsigned long *pending, *intrmask, *pcpu_mask; @@ -199,17 +188,8 @@ void gic_get_int_mask(unsigned long *dst, const unsigned long *src) bitmap_and(pending, pending, intrmask, gic_shared_intrs); bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); - bitmap_and(dst, src, pending, gic_shared_intrs); -} - -unsigned int gic_get_int(void) -{ - DECLARE_BITMAP(interrupts, GIC_MAX_INTRS); - - bitmap_fill(interrupts, gic_shared_intrs); - gic_get_int_mask(interrupts, interrupts); - return find_first_bit(interrupts, gic_shared_intrs); + return find_first_bit(pending, gic_shared_intrs); } static void gic_mask_irq(struct irq_data *d) -- GitLab From 4203d644e0f724267f70e6f6192b80dbaebc998c Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:29 -0700 Subject: [PATCH 5976/9457] MIPS: Malta: Use generic plat_irq_dispatch The generic plat_irq_dispatch provided in irq_cpu.c is sufficient for dispatching interrupts on Malta in legacy and vectored interrupt modes. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7821/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-int.c | 92 --------------------------------- 1 file changed, 92 deletions(-) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index c6b35482505d..bcab0b197e9f 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -190,92 +190,6 @@ static irqreturn_t corehi_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static inline int clz(unsigned long x) -{ - __asm__( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return -clz(pending) + 31 - CAUSEB_IP; -#else - unsigned int a0 = 7; - unsigned int t0; - - t0 = pending & 0xf000; - t0 = t0 < 1; - t0 = t0 << 2; - a0 = a0 - t0; - pending = pending << t0; - - t0 = pending & 0xc000; - t0 = t0 < 1; - t0 = t0 << 1; - a0 = a0 - t0; - pending = pending << t0; - - t0 = pending & 0x8000; - t0 = t0 < 1; - /* t0 = t0 << 2; */ - a0 = a0 - t0; - /* pending = pending << t0; */ - - return a0; -#endif -} - -/* - * IRQs on the Malta board look basically (barring software IRQs which we - * don't use at all and all external interrupt sources are combined together - * on hardware interrupt 0 (MIPS IRQ 2)) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Combined hardware interrupt (hw0) - * 3 Hardware (ignored) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - if (unlikely(!pending)) { - spurious_interrupt(); - return; - } - - irq = irq_ffs(pending); - - do_IRQ(MIPS_CPU_IRQ_BASE + irq); -} - #ifdef CONFIG_MIPS_MT_SMP #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ @@ -438,12 +352,6 @@ void __init arch_init_irq(void) cpu_ipi_resched_irq = MSC01E_INT_SW0; cpu_ipi_call_irq = MSC01E_INT_SW1; } else { - if (cpu_has_vint) { - set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, - ipi_resched_dispatch); - set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, - ipi_call_dispatch); - } cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + -- GitLab From a393d93059664f73d897d2a7e0c1ed85bf372954 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 18 Sep 2014 14:47:30 -0700 Subject: [PATCH 5977/9457] MIPS: SEAD3: Use generic plat_irq_dispatch The generic plat_irq_dispatch provided in irq_cpu.c is sufficient for dispatching interrupts on SEAD-3 in legacy and vectored interrupt modes. Signed-off-by: Andrew Bresticker Reviewed-by: Qais Yousef Tested-by: Qais Yousef Cc: Thomas Gleixner Cc: Jeffrey Deans Cc: Markos Chandras Cc: Paul Burton Cc: Jonas Gorski Cc: John Crispin Cc: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7822/ Signed-off-by: Ralf Baechle --- arch/mips/mti-sead3/sead3-int.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index cb06cd954a13..69ae185a76c5 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -22,32 +22,11 @@ static unsigned long sead3_config_reg; -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = (fls(pending) - CAUSEB_IP - 1); - if (irq >= 0) - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - else - spurious_interrupt(); -} - void __init arch_init_irq(void) { - int i; - - if (!cpu_has_veic) { + if (!cpu_has_veic) mips_cpu_irq_init(); - if (cpu_has_vint) { - /* install generic handler */ - for (i = 0; i < 8; i++) - set_vi_handler(i, plat_irq_dispatch); - } - } - sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >> -- GitLab From 7d9ad5d8c3639113765a3a0ad78c18a736d9f494 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:48 -0700 Subject: [PATCH 5978/9457] MIPS: Malta: Use gic_read_count() to read GIC timer Instead of reading the GIC registers directly, use the interface the GIC driver already exposes for reading the global timer. Also get rid of the unnecessary #ifdefs. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8123/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-time.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index f6ca8ea4d992..39f3902ed341 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -70,9 +70,7 @@ static void __init estimate_frequencies(void) { unsigned long flags; unsigned int count, start; -#ifdef CONFIG_MIPS_GIC - unsigned int giccount = 0, gicstart = 0; -#endif + cycle_t giccount = 0, gicstart = 0; #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; @@ -87,32 +85,26 @@ static void __init estimate_frequencies(void) /* Initialize counters. */ start = read_c0_count(); -#ifdef CONFIG_MIPS_GIC if (gic_present) - GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); -#endif + gicstart = gic_read_count(); /* Read counter exactly on falling edge of update flag. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); -#ifdef CONFIG_MIPS_GIC if (gic_present) - GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); -#endif + giccount = gic_read_count(); local_irq_restore(flags); count -= start; mips_hpt_frequency = count; -#ifdef CONFIG_MIPS_GIC if (gic_present) { giccount -= gicstart; gic_frequency = giccount; } -#endif } void read_persistent_clock(struct timespec *ts) -- GitLab From 387904ff84caeeff5aa5aad43aef4d0e5ce4bb24 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:49 -0700 Subject: [PATCH 5979/9457] irqchip: mips-gic: Export function to read counter width Export the function gic_get_count_width to read the width of the GIC global counter from GIC_SH_CONFIG. Update the GIC clocksource driver to use this new function. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8124/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 1 + arch/mips/kernel/csrc-gic.c | 9 +-------- drivers/irqchip/irq-mips-gic.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 727b7bf903a8..c88e1fa22365 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -370,6 +370,7 @@ extern void gic_init(unsigned long gic_base_addr, unsigned int irqbase); extern void gic_clocksource_init(unsigned int); extern cycle_t gic_read_count(void); +extern unsigned int gic_get_count_width(void); extern cycle_t gic_read_compare(void); extern void gic_write_compare(cycle_t cnt); extern void gic_write_cpu_compare(cycle_t cnt, int cpu); diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c index e02620901117..ab615c6c51a5 100644 --- a/arch/mips/kernel/csrc-gic.c +++ b/arch/mips/kernel/csrc-gic.c @@ -23,15 +23,8 @@ static struct clocksource gic_clocksource = { void __init gic_clocksource_init(unsigned int frequency) { - unsigned int config, bits; - - /* Calculate the clocksource mask. */ - GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); - bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> - (GIC_SH_CONFIG_COUNTBITS_SHF - 2)); - /* Set clocksource mask. */ - gic_clocksource.mask = CLOCKSOURCE_MASK(bits); + gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); /* Calculate a somewhat reasonable rating value. */ gic_clocksource.rating = 200 + frequency / 10000000; diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index e49a39a8c853..b5fad6377736 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -63,6 +63,17 @@ cycle_t gic_read_count(void) return (((cycle_t) hi) << 32) + lo; } +unsigned int gic_get_count_width(void) +{ + unsigned int bits, config; + + GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); + bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> + GIC_SH_CONFIG_COUNTBITS_SHF); + + return bits; +} + void gic_write_compare(cycle_t cnt) { GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), -- GitLab From 327b8c89d4aec9871626415868c8312b9722f2b8 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:50 -0700 Subject: [PATCH 5980/9457] MIPS: SEAD3: Stop using GIC REG macros Stop using the REG macros from gic.h and instead use proper iomem accessors. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8125/ Patchwork: https://patchwork.linux-mips.org/patch/8228/ Signed-off-by: Ralf Baechle --- arch/mips/mti-sead3/sead3-int.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 69ae185a76c5..02bf0dba1127 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -20,16 +20,16 @@ #define SEAD_CONFIG_BASE 0x1b100110 #define SEAD_CONFIG_SIZE 4 -static unsigned long sead3_config_reg; +static void __iomem *sead3_config_reg; void __init arch_init_irq(void) { if (!cpu_has_veic) mips_cpu_irq_init(); - sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE, - SEAD_CONFIG_SIZE); - gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >> + sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); + gic_present = (__raw_readl(sead3_config_reg) & + SEAD_CONFIG_GIC_PRESENT_MSK) >> SEAD_CONFIG_GIC_PRESENT_SHF; pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); pr_info("EIC: %s\n", -- GitLab From 609ead041b4c607163e7240a8674b608df31d2a8 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:51 -0700 Subject: [PATCH 5981/9457] MIPS: Malta: Stop using GIC REG macros Stop using the REG macros from gic.h and instead use proper iomem accessors. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8126/ Patchwork: https://patchwork.linux-mips.org/patch/8227/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-int.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index bcab0b197e9f..a058e0ba2a26 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -37,7 +37,7 @@ #include #include -static unsigned long _msc01_biu_base; +static void __iomem *_msc01_biu_base; static DEFINE_RAW_SPINLOCK(mips_irq_lock); @@ -293,12 +293,12 @@ void __init arch_init_irq(void) gic_present = 1; } else { if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { - _msc01_biu_base = (unsigned long) - ioremap_nocache(MSC01_BIU_REG_BASE, + _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); - gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & - MSC01_SC_CFG_GICPRES_MSK) >> - MSC01_SC_CFG_GICPRES_SHF; + gic_present = + (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & + MSC01_SC_CFG_GICPRES_MSK) >> + MSC01_SC_CFG_GICPRES_SHF; } } if (gic_present) @@ -336,9 +336,9 @@ void __init arch_init_irq(void) MIPS_GIC_IRQ_BASE); if (!mips_cm_present()) { /* Enable the GIC */ - i = REG(_msc01_biu_base, MSC01_SC_CFG); - REG(_msc01_biu_base, MSC01_SC_CFG) = - (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); + i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); + __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), + _msc01_biu_base + MSC01_SC_CFG_OFS); pr_debug("GIC Enabled\n"); } i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; -- GitLab From 5f68fea09ef1bc36e16d1059a84cf8b833cfb789 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:52 -0700 Subject: [PATCH 5982/9457] irqchip: mips-gic: Use proper iomem accessors Get rid of the ugly GICREAD/GICWRITE/GICBIS macros and use proper iomem accessors instead. Since the GIC registers are not directly accessed outside of the GIC driver any more, make gic_base static and move all the GIC register manipulation macros out of gic.h, converting them to static inline functions. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8127/ Patchwork: https://patchwork.linux-mips.org/patch/8229/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/gic.h | 72 ++---------- drivers/irqchip/irq-mips-gic.c | 206 +++++++++++++++++++++------------ 2 files changed, 142 insertions(+), 136 deletions(-) diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index c88e1fa22365..285944ca9f6c 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -16,8 +16,6 @@ #include -#undef GICISBYTELITTLEENDIAN - #define GIC_MAX_INTRS 256 /* Constants */ @@ -29,36 +27,9 @@ #define GIC_TRIG_DUAL_DISABLE 0 #define MSK(n) ((1 << (n)) - 1) -#define REG32(addr) (*(volatile unsigned int *) (addr)) -#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) -#define REGP(base, phys) REG32((unsigned long)(base) + (phys)) /* Accessors */ -#define GIC_REG(segment, offset) \ - REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) -#define GIC_REG_ADDR(segment, offset) \ - REG32(_gic_base + segment##_##SECTION_OFS + offset) - -#define GIC_ABS_REG(segment, offset) \ - (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) -#define GIC_REG_ABS_ADDR(segment, offset) \ - (_gic_base + segment##_##SECTION_OFS + offset) - -#ifdef GICISBYTELITTLEENDIAN -#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) -#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) -#else -#define GICREAD(reg, data) ((data) = (reg)) -#define GICWRITE(reg, data) ((reg) = (data)) -#endif -#define GICBIS(reg, mask, bits) \ - do { u32 data; \ - GICREAD(reg, data); \ - data &= ~(mask); \ - data |= ((bits) & (mask)); \ - GICWRITE((reg), data); \ - } while (0) - +#define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS) /* GIC Address Space */ #define SHARED_SECTION_OFS 0x0000 @@ -155,14 +126,13 @@ #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 /* Maps Interrupt X to a Pin */ -#define GIC_SH_MAP_TO_PIN(intr) \ - (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) +#define GIC_SH_MAP_TO_PIN(intr) (4 * (intr)) #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 /* Maps Interrupt X to a VPE */ #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ - (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) + ((32 * (intr)) + (((vpe) / 32) * 4)) #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) /* Convert an interrupt number to a byte offset/bit for multi-word registers */ @@ -171,34 +141,16 @@ /* Polarity : Reset Value is always 0 */ #define GIC_SH_SET_POLARITY_OFS 0x0100 -#define GIC_SET_POLARITY(intr, pol) \ - GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ - GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ - (pol) << GIC_INTR_BIT(intr)) /* Triggering : Reset Value is always 0 */ #define GIC_SH_SET_TRIGGER_OFS 0x0180 -#define GIC_SET_TRIGGER(intr, trig) \ - GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ - GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ - (trig) << GIC_INTR_BIT(intr)) /* Dual edge triggering : Reset Value is always 0 */ #define GIC_SH_SET_DUAL_OFS 0x0200 -#define GIC_SET_DUAL(intr, dual) \ - GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_DUAL_OFS + \ - GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ - (dual) << GIC_INTR_BIT(intr)) /* Mask manipulation */ #define GIC_SH_SMASK_OFS 0x0380 -#define GIC_SET_INTR_MASK(intr) \ - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ - GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) #define GIC_SH_RMASK_OFS 0x0300 -#define GIC_CLR_INTR_MASK(intr) \ - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ - GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) /* Register Map for Local Section */ #define GIC_VPE_CTL_OFS 0x0000 @@ -220,13 +172,11 @@ #define GIC_VPE_COMPARE_LO_OFS 0x00a0 #define GIC_VPE_COMPARE_HI_OFS 0x00a4 -#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 -#define GIC_VPE_EIC_SS(intr) \ - (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) +#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100 +#define GIC_VPE_EIC_SS(intr) (4 * (intr)) -#define GIC_VPE_EIC_VEC_BASE 0x0800 -#define GIC_VPE_EIC_VEC(intr) \ - (GIC_VPE_EIC_VEC_BASE + (4 * intr)) +#define GIC_VPE_EIC_VEC_BASE_OFS 0x0800 +#define GIC_VPE_EIC_VEC(intr) (4 * (intr)) #define GIC_VPE_TENABLE_NMI_OFS 0x1000 #define GIC_VPE_TENABLE_YQ_OFS 0x1004 @@ -316,13 +266,6 @@ #define GIC_VPE_SMASK_SWINT1_SHF 5 #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) -/* - * Set the Mapping of Interrupt X to a VPE. - */ -#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ - GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) - /* GIC nomenclature for Core Interrupt Pins. */ #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ #define GIC_CPU_INT1 1 /* . */ @@ -363,7 +306,6 @@ extern unsigned int gic_present; extern unsigned int gic_frequency; -extern unsigned long _gic_base; extern void gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, unsigned int cpu_vec, diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index b5fad6377736..88086d7e7c51 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -23,7 +23,6 @@ unsigned int gic_frequency; unsigned int gic_present; -unsigned long _gic_base; struct gic_pcpu_mask { DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); @@ -37,6 +36,7 @@ struct gic_intrmask_regs { DECLARE_BITMAP(intrmask, GIC_MAX_INTRS); }; +static void __iomem *gic_base; static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; @@ -49,15 +49,82 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; static void __gic_irq_dispatch(void); +static inline unsigned int gic_read(unsigned int reg) +{ + return __raw_readl(gic_base + reg); +} + +static inline void gic_write(unsigned int reg, unsigned int val) +{ + __raw_writel(val, gic_base + reg); +} + +static inline void gic_update_bits(unsigned int reg, unsigned int mask, + unsigned int val) +{ + unsigned int regval; + + regval = gic_read(reg); + regval &= ~mask; + regval |= val; + gic_write(reg, regval); +} + +static inline void gic_reset_mask(unsigned int intr) +{ + gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr), + 1 << GIC_INTR_BIT(intr)); +} + +static inline void gic_set_mask(unsigned int intr) +{ + gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr), + 1 << GIC_INTR_BIT(intr)); +} + +static inline void gic_set_polarity(unsigned int intr, unsigned int pol) +{ + gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) + + GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr), + pol << GIC_INTR_BIT(intr)); +} + +static inline void gic_set_trigger(unsigned int intr, unsigned int trig) +{ + gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) + + GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr), + trig << GIC_INTR_BIT(intr)); +} + +static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual) +{ + gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr), + 1 << GIC_INTR_BIT(intr), + dual << GIC_INTR_BIT(intr)); +} + +static inline void gic_map_to_pin(unsigned int intr, unsigned int pin) +{ + gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) + + GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin); +} + +static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) +{ + gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) + + GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe), + GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); +} + #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; do { - GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); - GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); - GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); + hi = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32)); + lo = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_31_00)); + hi2 = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32)); } while (hi2 != hi); return (((cycle_t) hi) << 32) + lo; @@ -67,7 +134,7 @@ unsigned int gic_get_count_width(void) { unsigned int bits, config; - GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); + config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> GIC_SH_CONFIG_COUNTBITS_SHF); @@ -76,9 +143,9 @@ unsigned int gic_get_count_width(void) void gic_write_compare(cycle_t cnt) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), (int)(cnt >> 32)); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), (int)(cnt & 0xffffffff)); } @@ -88,10 +155,10 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu) local_irq_save(flags); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), (int)(cnt >> 32)); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), (int)(cnt & 0xffffffff)); local_irq_restore(flags); @@ -101,8 +168,8 @@ cycle_t gic_read_compare(void) { unsigned int hi, lo; - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi); - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo); + hi = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI)); + lo = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO)); return (((cycle_t) hi) << 32) + lo; } @@ -116,7 +183,7 @@ static bool gic_local_irq_is_routable(int intr) if (cpu_has_veic) return true; - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_CTL), vpe_ctl); + vpe_ctl = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_CTL)); switch (intr) { case GIC_LOCAL_INT_TIMER: return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK; @@ -136,7 +203,7 @@ unsigned int gic_get_timer_pending(void) { unsigned int vpe_pending; - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), vpe_pending); + vpe_pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); return vpe_pending & GIC_VPE_PEND_TIMER_MSK; } @@ -146,12 +213,13 @@ static void gic_bind_eic_interrupt(int irq, int set) irq -= GIC_PIN_TO_VEC_OFFSET; /* Set irq to use shadow set */ - GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) + + GIC_VPE_EIC_SS(irq), set); } void gic_send_ipi(unsigned int intr) { - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); + gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); } int gic_get_c0_compare_int(void) @@ -178,23 +246,21 @@ static unsigned int gic_get_int(void) { unsigned int i; unsigned long *pending, *intrmask, *pcpu_mask; - unsigned long *pending_abs, *intrmask_abs; + unsigned long pending_reg, intrmask_reg; /* Get per-cpu bitmaps */ pending = pending_regs[smp_processor_id()].pending; intrmask = intrmask_regs[smp_processor_id()].intrmask; pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; - pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, - GIC_SH_PEND_31_0_OFS); - intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, - GIC_SH_MASK_31_0_OFS); + pending_reg = GIC_REG(SHARED, GIC_SH_PEND_31_0); + intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK_31_0); for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) { - GICREAD(*pending_abs, pending[i]); - GICREAD(*intrmask_abs, intrmask[i]); - pending_abs++; - intrmask_abs++; + pending[i] = gic_read(pending_reg); + intrmask[i] = gic_read(intrmask_reg); + pending_reg += 0x4; + intrmask_reg += 0x4; } bitmap_and(pending, pending, intrmask, gic_shared_intrs); @@ -205,19 +271,19 @@ static unsigned int gic_get_int(void) static void gic_mask_irq(struct irq_data *d) { - GIC_CLR_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq)); + gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); } static void gic_unmask_irq(struct irq_data *d) { - GIC_SET_INTR_MASK(GIC_HWIRQ_TO_SHARED(d->hwirq)); + gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); } static void gic_ack_irq(struct irq_data *d) { unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); - GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); + gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), irq); } static int gic_set_type(struct irq_data *d, unsigned int type) @@ -229,34 +295,34 @@ static int gic_set_type(struct irq_data *d, unsigned int type) spin_lock_irqsave(&gic_lock, flags); switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_FALLING: - GIC_SET_POLARITY(irq, GIC_POL_NEG); - GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); - GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + gic_set_polarity(irq, GIC_POL_NEG); + gic_set_trigger(irq, GIC_TRIG_EDGE); + gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); is_edge = true; break; case IRQ_TYPE_EDGE_RISING: - GIC_SET_POLARITY(irq, GIC_POL_POS); - GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); - GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + gic_set_polarity(irq, GIC_POL_POS); + gic_set_trigger(irq, GIC_TRIG_EDGE); + gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); is_edge = true; break; case IRQ_TYPE_EDGE_BOTH: /* polarity is irrelevant in this case */ - GIC_SET_TRIGGER(irq, GIC_TRIG_EDGE); - GIC_SET_DUAL(irq, GIC_TRIG_DUAL_ENABLE); + gic_set_trigger(irq, GIC_TRIG_EDGE); + gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE); is_edge = true; break; case IRQ_TYPE_LEVEL_LOW: - GIC_SET_POLARITY(irq, GIC_POL_NEG); - GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL); - GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + gic_set_polarity(irq, GIC_POL_NEG); + gic_set_trigger(irq, GIC_TRIG_LEVEL); + gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); is_edge = false; break; case IRQ_TYPE_LEVEL_HIGH: default: - GIC_SET_POLARITY(irq, GIC_POL_POS); - GIC_SET_TRIGGER(irq, GIC_TRIG_LEVEL); - GIC_SET_DUAL(irq, GIC_TRIG_DUAL_DISABLE); + gic_set_polarity(irq, GIC_POL_POS); + gic_set_trigger(irq, GIC_TRIG_LEVEL); + gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); is_edge = false; break; } @@ -292,7 +358,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, spin_lock_irqsave(&gic_lock, flags); /* Re-route this IRQ */ - GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); + gic_map_to_vpe(irq, first_cpu(tmp)); /* Update the pcpu_masks */ for (i = 0; i < NR_CPUS; i++) @@ -331,8 +397,8 @@ static unsigned int gic_get_local_int(void) { unsigned long pending, masked; - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); - GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_MASK), masked); + pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); + masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK)); bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); @@ -343,14 +409,14 @@ static void gic_mask_local_irq(struct irq_data *d) { int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr); } static void gic_unmask_local_irq(struct irq_data *d) { int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr); } static struct irq_chip gic_local_irq_controller = { @@ -367,8 +433,8 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d) spin_lock_irqsave(&gic_lock, flags); for (i = 0; i < gic_vpes; i++) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); } spin_unlock_irqrestore(&gic_lock, flags); } @@ -381,8 +447,8 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) spin_lock_irqsave(&gic_lock, flags); for (i = 0; i < gic_vpes; i++) { - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); } spin_unlock_irqrestore(&gic_lock, flags); } @@ -462,7 +528,7 @@ static __init void gic_ipi_init_one(unsigned int intr, int cpu, GIC_SHARED_TO_HWIRQ(intr)); int i; - GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); + gic_map_to_vpe(intr, cpu); for (i = 0; i < NR_CPUS; i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[cpu].pcpu_mask); @@ -500,19 +566,19 @@ static void __init gic_basic_init(void) /* Setup defaults */ for (i = 0; i < gic_shared_intrs; i++) { - GIC_SET_POLARITY(i, GIC_POL_POS); - GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); - GIC_CLR_INTR_MASK(i); + gic_set_polarity(i, GIC_POL_POS); + gic_set_trigger(i, GIC_TRIG_LEVEL); + gic_reset_mask(i); } for (i = 0; i < gic_vpes; i++) { unsigned int j; - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) { if (!gic_local_irq_is_routable(j)) continue; - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j); } } } @@ -548,29 +614,29 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, for (i = 0; i < gic_vpes; i++) { u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; - GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); switch (intr) { case GIC_LOCAL_INT_WD: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val); break; case GIC_LOCAL_INT_COMPARE: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val); break; case GIC_LOCAL_INT_TIMER: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val); break; case GIC_LOCAL_INT_PERFCTR: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val); break; case GIC_LOCAL_INT_SWINT0: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val); break; case GIC_LOCAL_INT_SWINT1: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val); break; case GIC_LOCAL_INT_FDC: - GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val); + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val); break; default: pr_err("Invalid local IRQ %d\n", intr); @@ -593,10 +659,9 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, handle_level_irq); spin_lock_irqsave(&gic_lock, flags); - GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), - GIC_MAP_TO_PIN_MSK | gic_cpu_pin); + gic_map_to_pin(intr, gic_cpu_pin); /* Map to VPE 0 by default */ - GIC_SH_MAP_TO_VPE_SMASK(intr, 0); + gic_map_to_vpe(intr, 0); set_bit(intr, pcpu_masks[0].pcpu_mask); spin_unlock_irqrestore(&gic_lock, flags); @@ -622,10 +687,9 @@ void __init gic_init(unsigned long gic_base_addr, { unsigned int gicconfig; - _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, - gic_addrspace_size); + gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size); - GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); + gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> GIC_SH_CONFIG_NUMINTRS_SHF; gic_shared_intrs = ((gic_shared_intrs + 1) * 8); -- GitLab From 4060bbe9931eca2ed3c2124022a070a75d507472 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:53 -0700 Subject: [PATCH 5983/9457] MIPS: Move gic.h to include/linux/irqchip/mips-gic.h Now that the MIPS GIC irqchip lives in drivers/irqchip/, move its header over to include/linux/irqchip/. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8129/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mips-boards/maltaint.h | 2 +- arch/mips/include/asm/mips-boards/sead3int.h | 2 +- arch/mips/kernel/cevt-gic.c | 2 +- arch/mips/kernel/cevt-r4k.c | 2 +- arch/mips/kernel/csrc-gic.c | 3 +-- arch/mips/kernel/smp-cmp.c | 2 +- arch/mips/kernel/smp-cps.c | 2 +- arch/mips/kernel/smp-gic.c | 2 +- arch/mips/kernel/smp-mt.c | 2 +- arch/mips/mti-malta/malta-int.c | 2 +- arch/mips/mti-malta/malta-time.c | 2 +- arch/mips/mti-sead3/sead3-ehci.c | 2 +- arch/mips/mti-sead3/sead3-int.c | 2 +- arch/mips/mti-sead3/sead3-net.c | 2 +- arch/mips/mti-sead3/sead3-platform.c | 2 +- arch/mips/mti-sead3/sead3-time.c | 2 +- drivers/irqchip/irq-mips-gic.c | 2 +- .../mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h | 0 18 files changed, 17 insertions(+), 18 deletions(-) rename arch/mips/include/asm/gic.h => include/linux/irqchip/mips-gic.h (100%) diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index 38b06a027437..987ff580466b 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -10,7 +10,7 @@ #ifndef _MIPS_MALTAINT_H #define _MIPS_MALTAINT_H -#include +#include /* * Interrupts 0..15 are used for Malta ISA compatible interrupts diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 59d6c32c7595..8932c7de0419 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h @@ -10,7 +10,7 @@ #ifndef _MIPS_SEAD3INT_H #define _MIPS_SEAD3INT_H -#include +#include /* SEAD-3 GIC address space definitions. */ #define GIC_BASE_ADDR 0x1b1c0000 diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c index 4f9262ab04f9..9caa68a2bcdc 100644 --- a/arch/mips/kernel/cevt-gic.c +++ b/arch/mips/kernel/cevt-gic.c @@ -10,9 +10,9 @@ #include #include #include +#include #include -#include #include DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index fd0ef8d851cc..6acaad0480af 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -11,10 +11,10 @@ #include #include #include +#include #include #include -#include static int mips_next_event(unsigned long delta, struct clock_event_device *evt) diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c index ab615c6c51a5..0bf28e6aca7a 100644 --- a/arch/mips/kernel/csrc-gic.c +++ b/arch/mips/kernel/csrc-gic.c @@ -6,10 +6,9 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include +#include #include -#include - static cycle_t gic_hpt_read(struct clocksource *cs) { return gic_read_count(); diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index fc8a51553426..1e0a93c5a3e7 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include static void cmp_init_secondary(void) { diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index cd20acad7f17..bed7590e475f 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -9,13 +9,13 @@ */ #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c index 3b21a96d1ccb..5f0ab5bcd01e 100644 --- a/arch/mips/kernel/smp-gic.c +++ b/arch/mips/kernel/smp-gic.c @@ -12,9 +12,9 @@ * option) any later version. */ +#include #include -#include #include #include diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index d60475fe5957..ad86951b73bd 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,6 @@ #include #include #include -#include static void __init smvp_copy_vpe_config(void) { diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index a058e0ba2a26..d1392f8f5811 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 39f3902ed341..608655f8e6dd 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c index 4ddaa0fd5804..014dd7ba4d68 100644 --- a/arch/mips/mti-sead3/sead3-ehci.c +++ b/arch/mips/mti-sead3/sead3-ehci.c @@ -9,8 +9,8 @@ #include #include #include +#include -#include #include struct resource ehci_resources[] = { diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 02bf0dba1127..e31e17f81eef 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c @@ -7,9 +7,9 @@ */ #include #include +#include #include -#include #include #include diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c index c9f728a41bdb..46176b804576 100644 --- a/arch/mips/mti-sead3/sead3-net.c +++ b/arch/mips/mti-sead3/sead3-net.c @@ -7,10 +7,10 @@ */ #include #include +#include #include #include -#include #include static struct smsc911x_platform_config sead3_smsc911x_data = { diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index d9661eb6fd6d..53ee6f1f018d 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c @@ -7,9 +7,9 @@ */ #include #include +#include #include -#include #include #define UART(base) \ diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index fd40de352c57..ec1dd2491f96 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c @@ -6,9 +6,9 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include +#include #include -#include #include #include #include diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 88086d7e7c51..bf0f7c978086 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -9,13 +9,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/arch/mips/include/asm/gic.h b/include/linux/irqchip/mips-gic.h similarity index 100% rename from arch/mips/include/asm/gic.h rename to include/linux/irqchip/mips-gic.h -- GitLab From 8d602dd0f984e8488ab891344ebdb6e1f3128c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 3 Sep 2014 22:51:06 +0200 Subject: [PATCH 5984/9457] MIPS: BCM47XX: Get rid of calls to KSEG1ADDR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should be using ioremap_nocache helper which handles remaps in a smarter way. Signed-off-by: Rafał Miłecki Cc: linux-mips@linux-mips.org Cc: Hauke Mehrtens Patchwork: http://patchwork.linux-mips.org/patch/7611/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 44 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 2bed73a684ae..e07976bbb739 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -23,13 +23,13 @@ static char nvram_buf[NVRAM_SPACE]; static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; -static u32 find_nvram_size(u32 end) +static u32 find_nvram_size(void __iomem *end) { - struct nvram_header *header; + struct nvram_header __iomem *header; int i; for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { - header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); + header = (struct nvram_header *)(end - nvram_sizes[i]); if (header->magic == NVRAM_HEADER) return nvram_sizes[i]; } @@ -38,35 +38,39 @@ static u32 find_nvram_size(u32 end) } /* Probe for NVRAM header */ -static int nvram_find_and_copy(u32 base, u32 lim) +static int nvram_find_and_copy(void __iomem *iobase, u32 lim) { - struct nvram_header *header; + struct nvram_header __iomem *header; int i; u32 off; u32 *src, *dst; u32 size; + if (nvram_buf[0]) { + pr_warn("nvram already initialized\n"); + return -EEXIST; + } + /* TODO: when nvram is on nand flash check for bad blocks first. */ off = FLASH_MIN; while (off <= lim) { /* Windowed flash access */ - size = find_nvram_size(base + off); + size = find_nvram_size(iobase + off); if (size) { - header = (struct nvram_header *)KSEG1ADDR(base + off - - size); + header = (struct nvram_header *)(iobase + off - size); goto found; } off <<= 1; } /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ - header = (struct nvram_header *) KSEG1ADDR(base + 4096); + header = (struct nvram_header *)(iobase + 4096); if (header->magic == NVRAM_HEADER) { size = NVRAM_SPACE; goto found; } - header = (struct nvram_header *) KSEG1ADDR(base + 1024); + header = (struct nvram_header *)(iobase + 1024); if (header->magic == NVRAM_HEADER) { size = NVRAM_SPACE; goto found; @@ -94,6 +98,22 @@ static int nvram_find_and_copy(u32 base, u32 lim) return 0; } +static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) +{ + void __iomem *iobase; + int err; + + iobase = ioremap_nocache(base, lim); + if (!iobase) + return -ENOMEM; + + err = nvram_find_and_copy(iobase, lim); + + iounmap(iobase); + + return err; +} + #ifdef CONFIG_BCM47XX_SSB static int nvram_init_ssb(void) { @@ -109,7 +129,7 @@ static int nvram_init_ssb(void) return -ENXIO; } - return nvram_find_and_copy(base, lim); + return bcm47xx_nvram_init_from_mem(base, lim); } #endif @@ -139,7 +159,7 @@ static int nvram_init_bcma(void) return -ENXIO; } - return nvram_find_and_copy(base, lim); + return bcm47xx_nvram_init_from_mem(base, lim); } #endif -- GitLab From 21400f252a97755579b43a4dc95dd02cd7f0ca75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 3 Sep 2014 22:59:45 +0200 Subject: [PATCH 5985/9457] MIPS: BCM47XX: Make ssb init NVRAM instead of bcm47xx polling it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes NVRAM code less bcm47xx/ssb specific allowing it to become a standalone driver in the future. A similar patch for bcma will follow when it's ready. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7612/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 30 ++++++------------- .../include/asm/mach-bcm47xx/bcm47xx_nvram.h | 1 + drivers/ssb/driver_mipscore.c | 14 ++++++++- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index e07976bbb739..fecc5aeddd46 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -98,7 +98,14 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim) return 0; } -static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) +/* + * On bcm47xx we need access to the NVRAM very early, so we can't use mtd + * subsystem to access flash. We can't even use platform device / driver to + * store memory offset. + * To handle this we provide following symbol. It's supposed to be called as + * soon as we get info about flash device, before any NVRAM entry is needed. + */ +int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) { void __iomem *iobase; int err; @@ -114,25 +121,6 @@ static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) return err; } -#ifdef CONFIG_BCM47XX_SSB -static int nvram_init_ssb(void) -{ - struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; - u32 base; - u32 lim; - - if (mcore->pflash.present) { - base = mcore->pflash.window; - lim = mcore->pflash.window_size; - } else { - pr_err("Couldn't find supported flash memory\n"); - return -ENXIO; - } - - return bcm47xx_nvram_init_from_mem(base, lim); -} -#endif - #ifdef CONFIG_BCM47XX_BCMA static int nvram_init_bcma(void) { @@ -168,7 +156,7 @@ static int nvram_init(void) switch (bcm47xx_bus_type) { #ifdef CONFIG_BCM47XX_SSB case BCM47XX_BUS_TYPE_SSB: - return nvram_init_ssb(); + break; #endif #ifdef CONFIG_BCM47XX_BCMA case BCM47XX_BUS_TYPE_BCMA: diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index 36a3fc1aa3ae..676be22bcab3 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h @@ -32,6 +32,7 @@ struct nvram_header { #define NVRAM_MAX_VALUE_LEN 255 #define NVRAM_MAX_PARAM_LEN 64 +int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 09077067b0c8..7b986f9f213f 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c @@ -15,6 +15,9 @@ #include #include #include +#ifdef CONFIG_BCM47XX +#include +#endif #include "ssb_private.h" @@ -210,6 +213,7 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore) static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) { struct ssb_bus *bus = mcore->dev->bus; + struct ssb_sflash *sflash = &mcore->sflash; struct ssb_pflash *pflash = &mcore->pflash; /* When there is no chipcommon on the bus there is 4MB flash */ @@ -242,7 +246,15 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) } ssb_pflash: - if (pflash->present) { + if (sflash->present) { +#ifdef CONFIG_BCM47XX + bcm47xx_nvram_init_from_mem(sflash->window, sflash->size); +#endif + } else if (pflash->present) { +#ifdef CONFIG_BCM47XX + bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size); +#endif + ssb_pflash_data.width = pflash->buswidth; ssb_pflash_resource.start = pflash->window; ssb_pflash_resource.end = pflash->window + pflash->window_size; -- GitLab From 7177efc5b030012c54c2e217c9d6decc0bcc1c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 28 Oct 2014 13:30:23 +0100 Subject: [PATCH 5986/9457] MIPS: BCM47XX: Make bcma init NVRAM instead of bcm47xx polling it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This drops ssb/bcma dependency and will allow us to make it a standalone driver. Signed-off-by: Rafał Miłecki Cc: linux-mips@linux-mips.org Cc: Hauke Mehrtens Patchwork: https://patchwork.linux-mips.org/patch/8233/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 42 ++------------------------------------ drivers/bcma/driver_mips.c | 13 ++++++++++-- 2 files changed, 13 insertions(+), 42 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index fecc5aeddd46..21712fb40d72 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -121,48 +121,10 @@ int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) return err; } -#ifdef CONFIG_BCM47XX_BCMA -static int nvram_init_bcma(void) -{ - struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; - u32 base; - u32 lim; - -#ifdef CONFIG_BCMA_NFLASH - if (cc->nflash.boot) { - base = BCMA_SOC_FLASH1; - lim = BCMA_SOC_FLASH1_SZ; - } else -#endif - if (cc->pflash.present) { - base = cc->pflash.window; - lim = cc->pflash.window_size; -#ifdef CONFIG_BCMA_SFLASH - } else if (cc->sflash.present) { - base = cc->sflash.window; - lim = cc->sflash.size; -#endif - } else { - pr_err("Couldn't find supported flash memory\n"); - return -ENXIO; - } - - return bcm47xx_nvram_init_from_mem(base, lim); -} -#endif - static int nvram_init(void) { - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - break; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return nvram_init_bcma(); -#endif - } + /* TODO: Look for MTD "nvram" partition */ + return -ENXIO; } diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 004d6aa671ce..8a653dc49029 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -20,6 +20,9 @@ #include #include #include +#ifdef CONFIG_BCM47XX +#include +#endif enum bcma_boot_dev { BCMA_BOOT_DEV_UNK = 0, @@ -323,10 +326,16 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) switch (boot_dev) { case BCMA_BOOT_DEV_PARALLEL: case BCMA_BOOT_DEV_SERIAL: - /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */ +#ifdef CONFIG_BCM47XX + bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2, + BCMA_SOC_FLASH2_SZ); +#endif break; case BCMA_BOOT_DEV_NAND: - /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */ +#ifdef CONFIG_BCM47XX + bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1, + BCMA_SOC_FLASH1_SZ); +#endif break; default: break; -- GitLab From a59da8fb3b2a1f2df5f871464e43cd5b6ca6ceb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 28 Oct 2014 12:52:02 +0100 Subject: [PATCH 5987/9457] MIPS: BCM47XX: Move SPROM fallback code into sprom.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is some general cleanup as well as preparing sprom.c to become a standalone driver. We will need this for bcm53xx ARM arch support. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8232/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/bcm47xx_private.h | 3 ++ arch/mips/bcm47xx/setup.c | 58 +----------------------- arch/mips/bcm47xx/sprom.c | 68 +++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index f1cc9d0495d8..12a112dd0ae0 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h @@ -6,6 +6,9 @@ /* prom.c */ void __init bcm47xx_prom_highmem_init(void); +/* sprom.c */ +void bcm47xx_sprom_register_fallbacks(void); + /* buttons.c */ int __init bcm47xx_buttons_register(void); diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c00585d915bc..444c65a09970 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) } #ifdef CONFIG_BCM47XX_SSB -static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) -{ - char prefix[10]; - - if (bus->bustype == SSB_BUSTYPE_PCI) { - memset(out, 0, sizeof(struct ssb_sprom)); - snprintf(prefix, sizeof(prefix), "pci/%u/%u/", - bus->host_pci->bus->number + 1, - PCI_SLOT(bus->host_pci->devfn)); - bcm47xx_fill_sprom(out, prefix, false); - return 0; - } else { - printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); - return -EINVAL; - } -} - static int bcm47xx_get_invariants(struct ssb_bus *bus, struct ssb_init_invariants *iv) { @@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) char buf[100]; struct ssb_mipscore *mcore; - err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); - if (err) - printk(KERN_WARNING "bcm47xx: someone else already registered" - " a ssb SPROM callback handler (err %d)\n", err); - err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, bcm47xx_get_invariants); if (err) @@ -171,44 +149,10 @@ static void __init bcm47xx_register_ssb(void) #endif #ifdef CONFIG_BCM47XX_BCMA -static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) -{ - char prefix[10]; - struct bcma_device *core; - - switch (bus->hosttype) { - case BCMA_HOSTTYPE_PCI: - memset(out, 0, sizeof(struct ssb_sprom)); - snprintf(prefix, sizeof(prefix), "pci/%u/%u/", - bus->host_pci->bus->number + 1, - PCI_SLOT(bus->host_pci->devfn)); - bcm47xx_fill_sprom(out, prefix, false); - return 0; - case BCMA_HOSTTYPE_SOC: - memset(out, 0, sizeof(struct ssb_sprom)); - core = bcma_find_core(bus, BCMA_CORE_80211); - if (core) { - snprintf(prefix, sizeof(prefix), "sb/%u/", - core->core_index); - bcm47xx_fill_sprom(out, prefix, true); - } else { - bcm47xx_fill_sprom(out, NULL, false); - } - return 0; - default: - pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); - return -EINVAL; - } -} - static void __init bcm47xx_register_bcma(void) { int err; - err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); - if (err) - pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); - err = bcma_host_soc_register(&bcm47xx_bus.bcma); if (err) panic("Failed to register BCMA bus (err %d)", err); @@ -229,6 +173,7 @@ void __init plat_mem_setup(void) printk(KERN_INFO "bcm47xx: using bcma bus\n"); #ifdef CONFIG_BCM47XX_BCMA bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; + bcm47xx_sprom_register_fallbacks(); bcm47xx_register_bcma(); bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); #ifdef CONFIG_HIGHMEM @@ -239,6 +184,7 @@ void __init plat_mem_setup(void) printk(KERN_INFO "bcm47xx: using ssb bus\n"); #ifdef CONFIG_BCM47XX_SSB bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; + bcm47xx_sprom_register_fallbacks(); bcm47xx_register_ssb(); bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); #endif diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index 41226b68de3d..e772e775c797 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -801,3 +801,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); } #endif + +#if defined(CONFIG_BCM47XX_SSB) +static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) +{ + char prefix[10]; + + if (bus->bustype == SSB_BUSTYPE_PCI) { + memset(out, 0, sizeof(struct ssb_sprom)); + snprintf(prefix, sizeof(prefix), "pci/%u/%u/", + bus->host_pci->bus->number + 1, + PCI_SLOT(bus->host_pci->devfn)); + bcm47xx_fill_sprom(out, prefix, false); + return 0; + } else { + pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); + return -EINVAL; + } +} +#endif + +#if defined(CONFIG_BCM47XX_BCMA) +static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) +{ + char prefix[10]; + struct bcma_device *core; + + switch (bus->hosttype) { + case BCMA_HOSTTYPE_PCI: + memset(out, 0, sizeof(struct ssb_sprom)); + snprintf(prefix, sizeof(prefix), "pci/%u/%u/", + bus->host_pci->bus->number + 1, + PCI_SLOT(bus->host_pci->devfn)); + bcm47xx_fill_sprom(out, prefix, false); + return 0; + case BCMA_HOSTTYPE_SOC: + memset(out, 0, sizeof(struct ssb_sprom)); + core = bcma_find_core(bus, BCMA_CORE_80211); + if (core) { + snprintf(prefix, sizeof(prefix), "sb/%u/", + core->core_index); + bcm47xx_fill_sprom(out, prefix, true); + } else { + bcm47xx_fill_sprom(out, NULL, false); + } + return 0; + default: + pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); + return -EINVAL; + } +} +#endif + +/* + * On bcm47xx we need to register SPROM fallback handler very early, so we can't + * use anything like platform device / driver for this. + */ +void bcm47xx_sprom_register_fallbacks(void) +{ +#if defined(CONFIG_BCM47XX_SSB) + if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) + pr_warn("Failed to registered ssb SPROM handler\n"); +#endif + +#if defined(CONFIG_BCM47XX_BCMA) + if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) + pr_warn("Failed to registered bcma SPROM handler\n"); +#endif +} -- GitLab From e5810fa0c1bed16fdfb408862a2e17e962ec5cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 28 Oct 2014 14:40:38 +0100 Subject: [PATCH 5988/9457] MIPS: BCM47XX: Initialize bcma bus later (with mm available) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initializaion with memory allocator available will be much simpler, this will allow cleanup in the bcma code. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8234/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/bcm47xx_private.h | 3 +++ arch/mips/bcm47xx/irq.c | 8 +++++++ arch/mips/bcm47xx/setup.c | 33 +++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index 12a112dd0ae0..ea909a56a3ee 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h @@ -15,6 +15,9 @@ int __init bcm47xx_buttons_register(void); /* leds.c */ void __init bcm47xx_leds_register(void); +/* setup.c */ +void __init bcm47xx_bus_setup(void); + /* workarounds.c */ void __init bcm47xx_workarounds(void); diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c index e0585b76ec19..21b4497f09be 100644 --- a/arch/mips/bcm47xx/irq.c +++ b/arch/mips/bcm47xx/irq.c @@ -22,6 +22,8 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "bcm47xx_private.h" + #include #include #include @@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) void __init arch_init_irq(void) { + /* + * This is the first arch callback after mm_init (we can use kmalloc), + * so let's finish bus initialization now. + */ + bcm47xx_bus_setup(); + #ifdef CONFIG_BCM47XX_BCMA if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 444c65a09970..e43b5046cb30 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -156,15 +156,14 @@ static void __init bcm47xx_register_bcma(void) err = bcma_host_soc_register(&bcm47xx_bus.bcma); if (err) panic("Failed to register BCMA bus (err %d)", err); - - err = bcma_host_soc_init(&bcm47xx_bus.bcma); - if (err) - panic("Failed to initialize BCMA bus (err %d)", err); - - bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); } #endif +/* + * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed + * to detect memory and record it with add_memory_region. + * Any extra initializaion performed here must not use kmalloc or bootmem. + */ void __init plat_mem_setup(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -193,6 +192,28 @@ void __init plat_mem_setup(void) _machine_restart = bcm47xx_machine_restart; _machine_halt = bcm47xx_machine_halt; pm_power_off = bcm47xx_machine_halt; +} + +/* + * This finishes bus initialization doing things that were not possible without + * kmalloc. Make sure to call it late enough (after mm_init). + */ +void __init bcm47xx_bus_setup(void) +{ +#ifdef CONFIG_BCM47XX_BCMA + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { + int err; + + err = bcma_host_soc_init(&bcm47xx_bus.bcma); + if (err) + panic("Failed to initialize BCMA bus (err %d)", err); + + bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, + NULL); + } +#endif + + /* With bus initialized we can access NVRAM and detect the board */ bcm47xx_board_detect(); mips_set_machine_name(bcm47xx_board_get_name()); } -- GitLab From 4ff3fccd86577c6362153f9eb81221730b408491 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 4 Nov 2014 03:02:16 +0100 Subject: [PATCH 5989/9457] MIPS: Remove __strlen_user(). Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uaccess.h | 27 --------------------------- arch/mips/kernel/mips_ksyms.c | 4 ---- arch/mips/lib/strlen_user.S | 3 --- 3 files changed, 34 deletions(-) diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 133678ab4eb8..486e27b8f479 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -1325,33 +1325,6 @@ strncpy_from_user(char *__to, const char __user *__from, long __len) return res; } -/* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -static inline long __strlen_user(const char __user *s) -{ - long res; - - if (segment_eq(get_fs(), get_ds())) { - __asm__ __volatile__( - "move\t$4, %1\n\t" - __MODULE_JAL(__strlen_kernel_nocheck_asm) - "move\t%0, $2" - : "=r" (res) - : "r" (s) - : "$2", "$4", __UA_t0, "$31"); - } else { - might_fault(); - __asm__ __volatile__( - "move\t$4, %1\n\t" - __MODULE_JAL(__strlen_user_nocheck_asm) - "move\t%0, $2" - : "=r" (res) - : "r" (s) - : "$2", "$4", __UA_t0, "$31"); - } - - return res; -} - /* * strlen_user: - Get the size of a string in user space. * @str: The string to measure. diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 2607c3a4ff7e..17eaf0cf760c 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -24,9 +24,7 @@ extern long __strncpy_from_user_nocheck_asm(char *__to, const char *__from, long __len); extern long __strncpy_from_user_asm(char *__to, const char *__from, long __len); -extern long __strlen_kernel_nocheck_asm(const char *s); extern long __strlen_kernel_asm(const char *s); -extern long __strlen_user_nocheck_asm(const char *s); extern long __strlen_user_asm(const char *s); extern long __strnlen_kernel_nocheck_asm(const char *s); extern long __strnlen_kernel_asm(const char *s); @@ -62,9 +60,7 @@ EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm); EXPORT_SYMBOL(__strncpy_from_kernel_asm); EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); EXPORT_SYMBOL(__strncpy_from_user_asm); -EXPORT_SYMBOL(__strlen_kernel_nocheck_asm); EXPORT_SYMBOL(__strlen_kernel_asm); -EXPORT_SYMBOL(__strlen_user_nocheck_asm); EXPORT_SYMBOL(__strlen_user_asm); EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); EXPORT_SYMBOL(__strnlen_kernel_asm); diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S index bef65c98df59..929bbacd697e 100644 --- a/arch/mips/lib/strlen_user.S +++ b/arch/mips/lib/strlen_user.S @@ -28,7 +28,6 @@ LEAF(__strlen_\func\()_asm) and v0, a0 bnez v0, .Lfault\@ -FEXPORT(__strlen_\func\()_nocheck_asm) move v0, a0 .ifeqs "\func", "kernel" 1: EX(lbu, v1, (v0), .Lfault\@) @@ -48,9 +47,7 @@ FEXPORT(__strlen_\func\()_nocheck_asm) #ifndef CONFIG_EVA /* Set aliases */ .global __strlen_user_asm - .global __strlen_user_nocheck_asm .set __strlen_user_asm, __strlen_kernel_asm - .set __strlen_user_nocheck_asm, __strlen_kernel_nocheck_asm #endif __BUILD_STRLEN_ASM kernel -- GitLab From 80e8bd266cf090b74e53380780371a8507692741 Mon Sep 17 00:00:00 2001 From: Isamu Mogi Date: Thu, 30 Oct 2014 22:07:37 +0900 Subject: [PATCH 5990/9457] MIPS: R3000: Replace magic numbers with macros Also include asm/mmu_context.h for ASID_MASK. Signed-off-by: Isamu Mogi Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8291/ Signed-off-by: Ralf Baechle --- arch/mips/lib/r3k_dump_tlb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 1ef365ab3cd3..c97bb70a06e6 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ static void dump_tlb(int first, int last) unsigned int asid; unsigned long entryhi, entrylo0; - asid = read_c0_entryhi() & 0xfc0; + asid = read_c0_entryhi() & ASID_MASK; for (i = first; i <= last; i++) { write_c0_index(i<<8); @@ -34,8 +35,8 @@ static void dump_tlb(int first, int last) entrylo0 = read_c0_entrylo0(); /* Unused entries have a virtual address of KSEG0. */ - if ((entryhi & 0xfffff000) != 0x80000000 - && (entryhi & 0xfc0) == asid) { + if ((entryhi & PAGE_MASK) != KSEG0 + && (entryhi & ASID_MASK) == asid) { /* * Only print entries in use */ @@ -43,8 +44,8 @@ static void dump_tlb(int first, int last) printk("va=%08lx asid=%08lx" " [pa=%06lx n=%d d=%d v=%d g=%d]", - (entryhi & 0xfffff000), - entryhi & 0xfc0, + (entryhi & PAGE_MASK), + entryhi & ASID_MASK, entrylo0 & PAGE_MASK, (entrylo0 & (1 << 11)) ? 1 : 0, (entrylo0 & (1 << 10)) ? 1 : 0, -- GitLab From 432d9ecb9628bdcb20670b2cf0678f3738bd40a5 Mon Sep 17 00:00:00 2001 From: Isamu Mogi Date: Thu, 30 Oct 2014 22:07:38 +0900 Subject: [PATCH 5991/9457] MIPS: R3000: Remove redundant parentheses Signed-off-by: Isamu Mogi Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8292/ Signed-off-by: Ralf Baechle --- arch/mips/lib/r3k_dump_tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index c97bb70a06e6..975a13855116 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c @@ -44,7 +44,7 @@ static void dump_tlb(int first, int last) printk("va=%08lx asid=%08lx" " [pa=%06lx n=%d d=%d v=%d g=%d]", - (entryhi & PAGE_MASK), + entryhi & PAGE_MASK, entryhi & ASID_MASK, entrylo0 & PAGE_MASK, (entrylo0 & (1 << 11)) ? 1 : 0, -- GitLab From f490682a6b21ffed5acd7a0d49d8371e5e625d7a Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 4 Nov 2014 14:13:24 +0800 Subject: [PATCH 5992/9457] MIPS: Loongson-3: Add PHYS48_TO_HT40 support The width of HT-bus is only 40-bit, but Loongson-3 has 48-bit physical address. This implies only node-0's memory is DMAable because high bits (Node ID) will lost. Fortunately, by configuring address windows in firmware, we can extract 2bit Node ID (bit 44~47, only bit 44~45 used now) from Loongson-3's 48-bit address space and embed it into 40-bit (bit 37~38). Every NUMA node can do DMA now (however, maximum memory of each node is reduced to 2^37 = 128GB). Signed-off-by: Huacai Chen Cc: John Crispin Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/8321/ Signed-off-by: Ralf Baechle --- .../mips/include/asm/mach-loongson/dma-coherence.h | 6 +++--- arch/mips/loongson/Kconfig | 5 +++++ arch/mips/loongson/common/dma-swiotlb.c | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 6a902751cc7f..a90534161bd2 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h @@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { #ifdef CONFIG_CPU_LOONGSON3 - return virt_to_phys(addr); + return phys_to_dma(dev, virt_to_phys(addr)); #else return virt_to_phys(addr) | 0x80000000; #endif @@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { #ifdef CONFIG_CPU_LOONGSON3 - return page_to_phys(page); + return phys_to_dma(dev, page_to_phys(page)); #else return page_to_phys(page) | 0x80000000; #endif @@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) - return dma_addr; + return dma_to_phys(dev, dma_addr); #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); #else diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 1b91fc6a921b..72f830ac0782 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -86,6 +86,7 @@ config LOONGSON_MACH3X select LOONGSON_MC146818 select ZONE_DMA32 select LEFI_FIRMWARE_INTERFACE + select PHYS48_TO_HT40 help Generic Loongson 3 family machines utilize the 3A/3B revision of Loongson processor and RS780/SBX00 chipset. @@ -131,6 +132,10 @@ config SWIOTLB select NEED_SG_DMA_LENGTH select NEED_DMA_MAP_STATE +config PHYS48_TO_HT40 + bool + default y if CPU_LOONGSON3 + config LOONGSON_MC146818 bool default n diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c index c2be01f91575..2c6b989c1bc4 100644 --- a/arch/mips/loongson/common/dma-swiotlb.c +++ b/arch/mips/loongson/common/dma-swiotlb.c @@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask) dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (paddr >> 44) & 0x3; + paddr = ((nid << 44) ^ paddr) | (nid << 37); +#endif return paddr; } phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (daddr >> 37) & 0x3; + daddr = ((nid << 37) ^ daddr) | (nid << 44); +#endif return daddr; } -- GitLab From ec0f8d3fbb7ea12cfd10083e340381b96e7c34f8 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 4 Nov 2014 14:13:26 +0800 Subject: [PATCH 5993/9457] MIPS: Loongson: Allow booting from any core By offering Logical->Physical core id mapping, so as to reserve some physical cores via mask. This allow booting from any core when core-0 has problems. Since the maximun cores supported by Loongson-3 is 16, 32-bit cpu_startup_core_id can be split to 16-bit cpu_startup_core_id and 16-bit reserved_cores_mask for compatibility. Signed-off-by: Huacai Chen Cc: John Crispin Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/8323/ Signed-off-by: Ralf Baechle --- .../include/asm/mach-loongson/boot_param.h | 5 +- arch/mips/include/asm/mach-loongson/irq.h | 3 +- .../mips/include/asm/mach-loongson/topology.h | 2 +- arch/mips/loongson/common/env.c | 2 + arch/mips/loongson/loongson-3/irq.c | 14 ++-- arch/mips/loongson/loongson-3/numa.c | 12 +++- arch/mips/loongson/loongson-3/smp.c | 65 ++++++++++++------- 7 files changed, 67 insertions(+), 36 deletions(-) diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h index 3388fc53599e..11ebf4ca2b41 100644 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ b/arch/mips/include/asm/mach-loongson/boot_param.h @@ -42,7 +42,8 @@ struct efi_cpuinfo_loongson { u32 processor_id; /* PRID, e.g. 6305, 6306 */ u32 cputype; /* Loongson_3A/3B, etc. */ u32 total_node; /* num of total numa nodes */ - u32 cpu_startup_core_id; /* Core id */ + u16 cpu_startup_core_id; /* Boot core id */ + u16 reserved_cores_mask; u32 cpu_clock_freq; /* cpu_clock */ u32 nr_cpus; } __packed; @@ -149,6 +150,8 @@ struct loongson_system_configuration { u32 nr_nodes; int cores_per_node; int cores_per_package; + u16 boot_cpu_id; + u16 reserved_cpus_mask; enum loongson_cpu_type cputype; u64 ht_control_base; u64 pci_mem_start_addr; diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h index 34560bda6626..a281cca5f2fb 100644 --- a/arch/mips/include/asm/mach-loongson/irq.h +++ b/arch/mips/include/asm/mach-loongson/irq.h @@ -32,8 +32,7 @@ #define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) #define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) -#define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ -#define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */ +#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */ #endif diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h index 5598ba77d2ef..0d8f3b55bdbc 100644 --- a/arch/mips/include/asm/mach-loongson/topology.h +++ b/arch/mips/include/asm/mach-loongson/topology.h @@ -3,7 +3,7 @@ #ifdef CONFIG_NUMA -#define cpu_to_node(cpu) ((cpu) >> 2) +#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) #define parent_node(node) (node) #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index f15228550a22..d8be5398105c 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c @@ -119,6 +119,8 @@ void __init prom_init_env(void) } loongson_sysconf.nr_cpus = ecpu->nr_cpus; + loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id; + loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask; if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) loongson_sysconf.nr_cpus = NR_CPUS; loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index ca1c62af5188..5813d941f9fc 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c @@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d) /* Workaround: UART IRQ may deliver to any core */ if (d->irq == LOONGSON_UART_IRQ) { int cpu = smp_processor_id(); - int node_id = cpu / loongson_sysconf.cores_per_node; - int core_id = cpu % loongson_sysconf.cores_per_node; + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; u64 intenclr_addr = smp_group[node_id] | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); u64 introuter_lpc_addr = smp_group[node_id] | @@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d) /* Workaround: UART IRQ may deliver to any core */ if (d->irq == LOONGSON_UART_IRQ) { int cpu = smp_processor_id(); - int node_id = cpu / loongson_sysconf.cores_per_node; - int core_id = cpu % loongson_sysconf.cores_per_node; + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; u64 intenset_addr = smp_group[node_id] | (u64)(&LOONGSON_INT_ROUTER_INTENSET); u64 introuter_lpc_addr = smp_group[node_id] | @@ -102,10 +102,12 @@ void irq_router_init(void) int i; /* route LPC int to cpu core0 int 0 */ - LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; + LOONGSON_INT_ROUTER_LPC = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); /* route HT1 int0 ~ int7 to cpu core0 INT1*/ for (i = 0; i < 8; i++) - LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; + LOONGSON_INT_ROUTER_HT1(i) = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); /* enable HT1 interrupt */ LOONGSON_HT1_INTN_EN(0) = 0xffffffff; /* enable router interrupt intenset */ diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c index 42323bcc5d28..6cae0e75de27 100644 --- a/arch/mips/loongson/loongson-3/numa.c +++ b/arch/mips/loongson/loongson-3/numa.c @@ -224,7 +224,7 @@ static void __init node_mem_init(unsigned int node) static __init void prom_meminit(void) { - unsigned int node, cpu; + unsigned int node, cpu, active_cpu = 0; cpu_node_probe(); init_topology_matrix(); @@ -240,8 +240,14 @@ static __init void prom_meminit(void) node = cpu / loongson_sysconf.cores_per_node; if (node >= num_online_nodes()) node = 0; - pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); - cpu_set(cpu, __node_data[(node)]->cpumask); + + if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); + pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); + + active_cpu++; } } diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index d8c63af6c7cc..94ed8a57353c 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c @@ -239,7 +239,7 @@ static void ipi_mailbox_buf_init(void) */ static void loongson3_send_ipi_single(int cpu, unsigned int action) { - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); } static void @@ -248,7 +248,7 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) unsigned int i; for_each_cpu(i, mask) - loongson3_ipi_write32((u32)action, ipi_set0_regs[i]); + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); } void loongson3_ipi_interrupt(struct pt_regs *regs) @@ -257,10 +257,10 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) unsigned int action, c0count; /* Load the ipi register to figure out what we're supposed to do */ - action = loongson3_ipi_read32(ipi_status0_regs[cpu]); + action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); /* Clear the ipi register to clear the interrupt */ - loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu]); + loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); if (action & SMP_RESCHEDULE_YOURSELF) scheduler_ipi(); @@ -291,12 +291,14 @@ static void loongson3_init_secondary(void) /* Set interrupt mask, but don't enable */ change_c0_status(ST0_IM, imask); - for (i = 0; i < loongson_sysconf.nr_cpus; i++) - loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); + for (i = 0; i < num_possible_cpus(); i++) + loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); - cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package; - cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package; per_cpu(cpu_state, cpu) = CPU_ONLINE; + cpu_data[cpu].core = + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_data[cpu].package = + cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; i = 0; __this_cpu_write(core0_c0count, 0); @@ -314,37 +316,50 @@ static void loongson3_init_secondary(void) static void loongson3_smp_finish(void) { + int cpu = smp_processor_id(); + write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); local_irq_enable(); loongson3_ipi_write64(0, - (void *)(ipi_mailbox_buf[smp_processor_id()]+0x0)); + (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); pr_info("CPU#%d finished, CP0_ST=%x\n", smp_processor_id(), read_c0_status()); } static void __init loongson3_smp_setup(void) { - int i, num; + int i = 0, num = 0; /* i: physical id, num: logical id */ init_cpu_possible(cpu_none_mask); - set_cpu_possible(0, true); - - __cpu_number_map[0] = 0; - __cpu_logical_map[0] = 0; /* For unified kernel, NR_CPUS is the maximum possible value, * loongson_sysconf.nr_cpus is the really present value */ - for (i = 1, num = 0; i < loongson_sysconf.nr_cpus; i++) { - set_cpu_possible(i, true); - __cpu_number_map[i] = ++num; - __cpu_logical_map[num] = i; + while (i < loongson_sysconf.nr_cpus) { + if (loongson_sysconf.reserved_cpus_mask & (1< Date: Tue, 4 Nov 2014 14:13:27 +0800 Subject: [PATCH 5994/9457] MIPS: Loongson: Improve LEFI firmware interface Machtypes of Loongson-3 machines become more and more, but there are only small differences among different machtypes. Keeping a large table of machtypes is very ugly and hard to extend. We found that the major machtype differences are UARTs information (number of UARTs, UART IRQs, UART clocks, etc.), platform devices (EC, temperature sensors, fan controllers, etc.) and some workarounds (because of some CPU bugs or mainboard bugs). In this patch we improve the UEFI-like (LEFI) interface to make all Loongson-3 machines use a same machtype "generic-loongson-machine". Signed-off-by: Huacai Chen Cc: John Crispin Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/8324/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bootinfo.h | 5 +- .../include/asm/mach-loongson/boot_param.h | 44 ++++++++++++++- .../mips/include/asm/mach-loongson/loongson.h | 2 +- .../asm/mach-loongson/loongson_hwmon.h | 55 +++++++++++++++++++ arch/mips/include/asm/mach-loongson/machine.h | 2 +- .../include/asm/mach-loongson/workarounds.h | 7 +++ arch/mips/loongson/common/early_printk.c | 2 +- arch/mips/loongson/common/env.c | 26 ++++++++- arch/mips/loongson/common/machtype.c | 5 +- arch/mips/loongson/common/serial.c | 48 +++++++++++++--- arch/mips/loongson/common/uart_base.c | 30 +++++----- arch/mips/loongson/loongson-3/Makefile | 2 +- arch/mips/loongson/loongson-3/platform.c | 43 +++++++++++++++ arch/mips/loongson/loongson-3/smp.c | 5 +- 14 files changed, 234 insertions(+), 42 deletions(-) create mode 100644 arch/mips/include/asm/mach-loongson/loongson_hwmon.h create mode 100644 arch/mips/include/asm/mach-loongson/workarounds.h create mode 100644 arch/mips/loongson/loongson-3/platform.c diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 1f7ca8b00404..8b2eaa155d18 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -70,10 +70,7 @@ enum loongson_machine_type { MACH_DEXXON_GDIUM2F10, MACH_LEMOTE_NAS, MACH_LEMOTE_LL2F, - MACH_LEMOTE_A1004, - MACH_LEMOTE_A1101, - MACH_LEMOTE_A1201, - MACH_LEMOTE_A1205, + MACH_LOONGSON_GENERIC, MACH_LOONGSON_END }; diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h index 11ebf4ca2b41..fa802926523f 100644 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ b/arch/mips/include/asm/mach-loongson/boot_param.h @@ -10,7 +10,8 @@ #define VIDEO_ROM 7 #define ADAPTER_ROM 8 #define ACPI_TABLE 9 -#define MAX_MEMORY_TYPE 10 +#define SMBIOS_TABLE 10 +#define MAX_MEMORY_TYPE 11 #define LOONGSON3_BOOT_MEM_MAP_MAX 128 struct efi_memory_map_loongson { @@ -48,10 +49,43 @@ struct efi_cpuinfo_loongson { u32 nr_cpus; } __packed; +#define MAX_UARTS 64 +struct uart_device { + u32 iotype; /* see include/linux/serial_core.h */ + u32 uartclk; + u32 int_offset; + u64 uart_base; +} __packed; + +#define MAX_SENSORS 64 +#define SENSOR_TEMPER 0x00000001 +#define SENSOR_VOLTAGE 0x00000002 +#define SENSOR_FAN 0x00000004 +struct sensor_device { + char name[32]; /* a formal name */ + char label[64]; /* a flexible description */ + u32 type; /* SENSOR_* */ + u32 id; /* instance id of a sensor-class */ + u32 fan_policy; /* see loongson_hwmon.h */ + u32 fan_percent;/* only for constant speed policy */ + u64 base_addr; /* base address of device registers */ +} __packed; + struct system_loongson { u16 vers; /* version of system_loongson */ u32 ccnuma_smp; /* 0: no numa; 1: has numa */ u32 sing_double_channel; /* 1:single; 2:double */ + u32 nr_uarts; + struct uart_device uarts[MAX_UARTS]; + u32 nr_sensors; + struct sensor_device sensors[MAX_SENSORS]; + char has_ec; + char ec_name[32]; + u64 ec_base_addr; + char has_tcm; + char tcm_name[32]; + u64 tcm_base_addr; + u64 workarounds; /* see workarounds.h */ } __packed; struct irq_source_routing_table { @@ -162,9 +196,15 @@ struct loongson_system_configuration { u64 suspend_addr; u64 vgabios_addr; u32 dma_mask_bits; + char ecname[32]; + u32 nr_uarts; + struct uart_device uarts[MAX_UARTS]; + u32 nr_sensors; + struct sensor_device sensors[MAX_SENSORS]; + u64 workarounds; }; extern struct efi_memory_map_loongson *loongson_memmap; extern struct loongson_system_configuration loongson_sysconf; -extern int cpuhotplug_workaround; + #endif diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 92bf76c21441..5459ac09679f 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h @@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void); extern void __init prom_init_machtype(void); extern void __init prom_init_env(void); #ifdef CONFIG_LOONGSON_UART_BASE -extern unsigned long _loongson_uart_base, loongson_uart_base; +extern unsigned long _loongson_uart_base[], loongson_uart_base[]; extern void prom_init_loongson_uart_base(void); #endif diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h new file mode 100644 index 000000000000..4431fc54a36c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h @@ -0,0 +1,55 @@ +#ifndef __LOONGSON_HWMON_H_ +#define __LOONGSON_HWMON_H_ + +#include + +#define MIN_TEMP 0 +#define MAX_TEMP 255 +#define NOT_VALID_TEMP 999 + +typedef int (*get_temp_fun)(int); +extern int loongson3_cpu_temp(int); + +/* 0:Max speed, 1:Manual, 2:Auto */ +enum fan_control_mode { + FAN_FULL_MODE = 0, + FAN_MANUAL_MODE = 1, + FAN_AUTO_MODE = 2, + FAN_MODE_END +}; + +struct temp_range { + u8 low; + u8 high; + u8 level; +}; + +#define CONSTANT_SPEED_POLICY 0 /* at constent speed */ +#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */ +#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */ + +#define MAX_STEP_NUM 16 +#define MAX_FAN_LEVEL 255 + +/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */ +struct loongson_fan_policy { + u8 type; + + /* percent only used when type is CONSTANT_SPEED_POLICY */ + u8 percent; + + /* period between two check. (Unit: S) */ + u8 adjust_period; + + /* fan adjust usually depend on a temprature input */ + get_temp_fun depend_temp; + + /* up_step/down_step used when type is STEP_SPEED_POLICY */ + u8 up_step_num; + u8 down_step_num; + struct temp_range up_step[MAX_STEP_NUM]; + struct temp_range down_step[MAX_STEP_NUM]; + struct delayed_work work; +}; + +#endif /* __LOONGSON_HWMON_H_*/ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 228e37847a36..cb2b60249cd2 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h @@ -26,7 +26,7 @@ #ifdef CONFIG_LOONGSON_MACH3X -#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 +#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC #endif /* CONFIG_LOONGSON_MACH3X */ diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h new file mode 100644 index 000000000000..e180c1422eae --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/workarounds.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ +#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ + +#define WORKAROUND_CPUFREQ 0x00000001 +#define WORKAROUND_CPUHOTPLUG 0x00000002 + +#endif diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c index ced461b39069..6ca632e529dc 100644 --- a/arch/mips/loongson/common/early_printk.c +++ b/arch/mips/loongson/common/early_printk.c @@ -30,7 +30,7 @@ void prom_putchar(char c) int timeout; unsigned char *uart_base; - uart_base = (unsigned char *)_loongson_uart_base; + uart_base = (unsigned char *)_loongson_uart_base[0]; timeout = 1024; while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index d8be5398105c..045ea3d47c87 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c @@ -21,6 +21,7 @@ #include #include #include +#include u32 cpu_clock_freq; EXPORT_SYMBOL(cpu_clock_freq); @@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; u64 loongson_freqctrl[MAX_PACKAGES]; unsigned long long smp_group[4]; -int cpuhotplug_workaround = 0; #define parse_even_earlier(res, option, p) \ do { \ @@ -67,6 +67,7 @@ void __init prom_init_env(void) #else struct boot_params *boot_p; struct loongson_params *loongson_p; + struct system_loongson *esys; struct efi_cpuinfo_loongson *ecpu; struct irq_source_routing_table *eirq_source; @@ -74,6 +75,8 @@ void __init prom_init_env(void) boot_p = (struct boot_params *)fw_arg2; loongson_p = &(boot_p->efi.smbios.lp); + esys = (struct system_loongson *) + ((u64)loongson_p + loongson_p->system_offset); ecpu = (struct efi_cpuinfo_loongson *) ((u64)loongson_p + loongson_p->cpu_offset); eirq_source = (struct irq_source_routing_table *) @@ -95,6 +98,7 @@ void __init prom_init_env(void) loongson_chipcfg[2] = 0x900020001fe00180; loongson_chipcfg[3] = 0x900030001fe00180; loongson_sysconf.ht_control_base = 0x90000EFDFB000000; + loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; } else if (ecpu->cputype == Loongson_3B) { loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ loongson_sysconf.cores_per_package = 8; @@ -111,7 +115,7 @@ void __init prom_init_env(void) loongson_freqctrl[2] = 0x900040001fe001d0; loongson_freqctrl[3] = 0x900060001fe001d0; loongson_sysconf.ht_control_base = 0x90001EFDFB000000; - cpuhotplug_workaround = 1; + loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG; } else { loongson_sysconf.cores_per_node = 1; loongson_sysconf.cores_per_package = 1; @@ -143,6 +147,24 @@ void __init prom_init_env(void) pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, loongson_sysconf.vgabios_addr); + + memset(loongson_sysconf.ecname, 0, 32); + if (esys->has_ec) + memcpy(loongson_sysconf.ecname, esys->ec_name, 32); + loongson_sysconf.workarounds |= esys->workarounds; + + loongson_sysconf.nr_uarts = esys->nr_uarts; + if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS) + loongson_sysconf.nr_uarts = 1; + memcpy(loongson_sysconf.uarts, esys->uarts, + sizeof(struct uart_device) * loongson_sysconf.nr_uarts); + + loongson_sysconf.nr_sensors = esys->nr_sensors; + if (loongson_sysconf.nr_sensors > MAX_SENSORS) + loongson_sysconf.nr_sensors = 0; + if (loongson_sysconf.nr_sensors) + memcpy(loongson_sysconf.sensors, esys->sensors, + sizeof(struct sensor_device) * loongson_sysconf.nr_sensors); #endif if (cpu_clock_freq == 0) { processor_id = (¤t_cpu_data)->processor_id; diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 1a4797984b8d..26629abe3f1f 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -27,10 +27,7 @@ static const char *system_types[] = { [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", [MACH_LEMOTE_NAS] "lemote-nas-2f", [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", - [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", - [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101", - [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201", - [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205", + [MACH_LOONGSON_GENERIC] "generic-loongson-machine", [MACH_LOONGSON_END] NULL, }; diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index bd2b7095b6dc..d2f4817a4b45 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -38,7 +38,7 @@ .regshift = 0, \ } -static struct plat_serial8250_port uart8250_data[][2] = { +static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { [MACH_LOONGSON_UNKNOWN] {}, [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, @@ -47,10 +47,7 @@ static struct plat_serial8250_port uart8250_data[][2] = { [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, - [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, - [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} }, - [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} }, - [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} }, + [MACH_LOONGSON_GENERIC] {PORT_M(2, 25000000), {} }, [MACH_LOONGSON_END] {}, }; @@ -61,17 +58,52 @@ static struct platform_device uart8250_device = { static int __init serial_init(void) { + int i; unsigned char iotype; iotype = uart8250_data[mips_machtype][0].iotype; - if (UPIO_MEM == iotype) + if (UPIO_MEM == iotype) { + uart8250_data[mips_machtype][0].mapbase = + loongson_uart_base[0]; uart8250_data[mips_machtype][0].membase = - (void __iomem *)_loongson_uart_base; + (void __iomem *)_loongson_uart_base[0]; + } else if (UPIO_PORT == iotype) uart8250_data[mips_machtype][0].iobase = - loongson_uart_base - LOONGSON_PCIIO_BASE; + loongson_uart_base[0] - LOONGSON_PCIIO_BASE; + if (loongson_sysconf.uarts[0].uartclk) + uart8250_data[mips_machtype][0].uartclk = + loongson_sysconf.uarts[0].uartclk; + + for (i = 1; i < loongson_sysconf.nr_uarts; i++) { + iotype = loongson_sysconf.uarts[i].iotype; + uart8250_data[mips_machtype][i].iotype = iotype; + loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base; + + if (UPIO_MEM == iotype) { + uart8250_data[mips_machtype][i].irq = + MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset; + uart8250_data[mips_machtype][i].mapbase = + loongson_uart_base[i]; + uart8250_data[mips_machtype][i].membase = + ioremap_nocache(loongson_uart_base[i], 8); + } else if (UPIO_PORT == iotype) { + uart8250_data[mips_machtype][i].irq = + loongson_sysconf.uarts[i].int_offset; + uart8250_data[mips_machtype][i].iobase = + loongson_uart_base[i] - LOONGSON_PCIIO_BASE; + } + + uart8250_data[mips_machtype][i].uartclk = + loongson_sysconf.uarts[i].uartclk; + uart8250_data[mips_machtype][i].flags = + UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + } + + memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts], + 0, sizeof(struct plat_serial8250_port)); uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; return platform_device_register(&uart8250_device); diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index 1e1eeea73fde..9de559d58e1f 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c @@ -13,22 +13,27 @@ #include -/* ioremapped */ -unsigned long _loongson_uart_base; -EXPORT_SYMBOL(_loongson_uart_base); /* raw */ -unsigned long loongson_uart_base; +unsigned long loongson_uart_base[MAX_UARTS] = {}; +/* ioremapped */ +unsigned long _loongson_uart_base[MAX_UARTS] = {}; + EXPORT_SYMBOL(loongson_uart_base); +EXPORT_SYMBOL(_loongson_uart_base); void prom_init_loongson_uart_base(void) { switch (mips_machtype) { + case MACH_LOONGSON_GENERIC: + /* The CPU provided serial port (CPU) */ + loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; + break; case MACH_LEMOTE_FL2E: - loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; + loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8; break; case MACH_LEMOTE_FL2F: case MACH_LEMOTE_LL2F: - loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; + loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8; break; case MACH_LEMOTE_ML2F7: case MACH_LEMOTE_YL2F89: @@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void) case MACH_LEMOTE_NAS: default: /* The CPU provided serial port (LPC) */ - loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; - break; - case MACH_LEMOTE_A1004: - case MACH_LEMOTE_A1101: - case MACH_LEMOTE_A1201: - case MACH_LEMOTE_A1205: - /* The CPU provided serial port (CPU) */ - loongson_uart_base = LOONGSON_REG_BASE + 0x1e0; + loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8; break; } - _loongson_uart_base = - (unsigned long)ioremap_nocache(loongson_uart_base, 8); + _loongson_uart_base[0] = + (unsigned long)ioremap_nocache(loongson_uart_base[0], 8); } diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile index b4df775b9f30..69809a3d8f34 100644 --- a/arch/mips/loongson/loongson-3/Makefile +++ b/arch/mips/loongson/loongson-3/Makefile @@ -1,7 +1,7 @@ # # Makefile for Loongson-3 family machines # -obj-y += irq.o cop2-ex.o +obj-y += irq.o cop2-ex.o platform.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c new file mode 100644 index 000000000000..25a97cc0ee33 --- /dev/null +++ b/arch/mips/loongson/loongson-3/platform.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * Xiang Yu, xiangy@lemote.com + * Chen Huacai, chenhc@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int __init loongson3_platform_init(void) +{ + int i; + struct platform_device *pdev; + + if (loongson_sysconf.ecname[0] != '\0') + platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); + + for (i = 0; i < loongson_sysconf.nr_sensors; i++) { + if (loongson_sysconf.sensors[i].type > SENSOR_FAN) + continue; + + pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + pdev->name = loongson_sysconf.sensors[i].name; + pdev->id = loongson_sysconf.sensors[i].id; + pdev->dev.platform_data = &loongson_sysconf.sensors[i]; + platform_device_register(pdev); + } + + return 0; +} + +arch_initcall(loongson3_platform_init); diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index 94ed8a57353c..e2eb688b5434 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "smp.h" @@ -587,7 +588,7 @@ void loongson3_disable_clock(int cpu) if (loongson_sysconf.cputype == Loongson_3A) { LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); } else if (loongson_sysconf.cputype == Loongson_3B) { - if (!cpuhotplug_workaround) + if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); } } @@ -600,7 +601,7 @@ void loongson3_enable_clock(int cpu) if (loongson_sysconf.cputype == Loongson_3A) { LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); } else if (loongson_sysconf.cputype == Loongson_3B) { - if (!cpuhotplug_workaround) + if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); } } -- GitLab From 89467e73d3881a470ce4ffdcba1d5a5ed618379a Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 4 Nov 2014 14:15:07 +0800 Subject: [PATCH 5995/9457] MIPS: Loongson-3: Add oprofile support Loongson-3 has two groups of performance counters, they are 4 sub- registers of CP0's REG25. This patch add oprofile support. REG25, sel 0: Perf Control of group 0; REG25, sel 1: Perf Counter of group 0; REG25, sel 2: Perf Control of group 1; REG25, sel 3: Perf Counter of group 1. Signed-off-by: Huacai Chen Cc: John Crispin Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/8328/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/Makefile | 1 + arch/mips/oprofile/common.c | 4 + arch/mips/oprofile/op_model_loongson3.c | 220 ++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 arch/mips/oprofile/op_model_loongson3.c diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 9c0a6782c091..070afdb297df 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -14,3 +14,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o +oprofile-$(CONFIG_CPU_LOONGSON3) += op_model_loongson3.o diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index e74732449478..feb987981f55 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -18,6 +18,7 @@ extern struct op_mips_model op_model_mipsxx_ops __weak; extern struct op_mips_model op_model_loongson2_ops __weak; +extern struct op_mips_model op_model_loongson3_ops __weak; static struct op_mips_model *model; @@ -104,6 +105,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_LOONGSON2: lmodel = &op_model_loongson2_ops; break; + case CPU_LOONGSON3: + lmodel = &op_model_loongson3_ops; + break; }; if (!lmodel) diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c new file mode 100644 index 000000000000..8bcf7fc40f0d --- /dev/null +++ b/arch/mips/oprofile/op_model_loongson3.c @@ -0,0 +1,220 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "op_impl.h" + +#define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63) + +#define LOONGSON3_PERFCTRL_EXL (1UL << 0) +#define LOONGSON3_PERFCTRL_KERNEL (1UL << 1) +#define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2) +#define LOONGSON3_PERFCTRL_USER (1UL << 3) +#define LOONGSON3_PERFCTRL_ENABLE (1UL << 4) +#define LOONGSON3_PERFCTRL_W (1UL << 30) +#define LOONGSON3_PERFCTRL_M (1UL << 31) +#define LOONGSON3_PERFCTRL_EVENT(idx, event) \ + (((event) & (idx ? 0x0f : 0x3f)) << 5) + +/* Loongson-3 PerfCount performance counter1 register */ +#define read_c0_perflo1() __read_64bit_c0_register($25, 0) +#define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val) +#define read_c0_perfhi1() __read_64bit_c0_register($25, 1) +#define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val) + +/* Loongson-3 PerfCount performance counter2 register */ +#define read_c0_perflo2() __read_64bit_c0_register($25, 2) +#define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val) +#define read_c0_perfhi2() __read_64bit_c0_register($25, 3) +#define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val) + +static int (*save_perf_irq)(void); + +static struct loongson3_register_config { + unsigned int control1; + unsigned int control2; + unsigned long long reset_counter1; + unsigned long long reset_counter2; + int ctr1_enable, ctr2_enable; +} reg; + +static void reset_counters(void *arg) +{ + write_c0_perfhi1(0); + write_c0_perfhi2(0); + write_c0_perflo1(0xc0000000); + write_c0_perflo2(0x40000000); +} + +/* Compute all of the registers in preparation for enabling profiling. */ +static void loongson3_reg_setup(struct op_counter_config *ctr) +{ + unsigned int control1 = 0; + unsigned int control2 = 0; + + reg.reset_counter1 = 0; + reg.reset_counter2 = 0; + /* Compute the performance counter control word. */ + /* For now count kernel and user mode */ + if (ctr[0].enabled) { + control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) | + LOONGSON3_PERFCTRL_ENABLE; + if (ctr[0].kernel) + control1 |= LOONGSON3_PERFCTRL_KERNEL; + if (ctr[0].user) + control1 |= LOONGSON3_PERFCTRL_USER; + reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count; + } + + if (ctr[1].enabled) { + control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) | + LOONGSON3_PERFCTRL_ENABLE; + if (ctr[1].kernel) + control2 |= LOONGSON3_PERFCTRL_KERNEL; + if (ctr[1].user) + control2 |= LOONGSON3_PERFCTRL_USER; + reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count; + } + + if (ctr[0].enabled) + control1 |= LOONGSON3_PERFCTRL_EXL; + if (ctr[1].enabled) + control2 |= LOONGSON3_PERFCTRL_EXL; + + reg.control1 = control1; + reg.control2 = control2; + reg.ctr1_enable = ctr[0].enabled; + reg.ctr2_enable = ctr[1].enabled; +} + +/* Program all of the registers in preparation for enabling profiling. */ +static void loongson3_cpu_setup(void *args) +{ + uint64_t perfcount1, perfcount2; + + perfcount1 = reg.reset_counter1; + perfcount2 = reg.reset_counter2; + write_c0_perfhi1(perfcount1); + write_c0_perfhi2(perfcount2); +} + +static void loongson3_cpu_start(void *args) +{ + /* Start all counters on current CPU */ + reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); + reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); + + if (reg.ctr1_enable) + write_c0_perflo1(reg.control1); + if (reg.ctr2_enable) + write_c0_perflo2(reg.control2); +} + +static void loongson3_cpu_stop(void *args) +{ + /* Stop all counters on current CPU */ + write_c0_perflo1(0xc0000000); + write_c0_perflo2(0x40000000); + memset(®, 0, sizeof(reg)); +} + +static int loongson3_perfcount_handler(void) +{ + unsigned long flags; + uint64_t counter1, counter2; + uint32_t cause, handled = IRQ_NONE; + struct pt_regs *regs = get_irq_regs(); + + cause = read_c0_cause(); + if (!(cause & CAUSEF_PCI)) + return handled; + + counter1 = read_c0_perfhi1(); + counter2 = read_c0_perfhi2(); + + local_irq_save(flags); + + if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) { + if (reg.ctr1_enable) + oprofile_add_sample(regs, 0); + counter1 = reg.reset_counter1; + } + if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) { + if (reg.ctr2_enable) + oprofile_add_sample(regs, 1); + counter2 = reg.reset_counter2; + } + + local_irq_restore(flags); + + write_c0_perfhi1(counter1); + write_c0_perfhi2(counter2); + + if (!(cause & CAUSEF_TI)) + handled = IRQ_HANDLED; + + return handled; +} + +static int loongson3_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + switch (action) { + case CPU_STARTING: + case CPU_STARTING_FROZEN: + write_c0_perflo1(reg.control1); + write_c0_perflo2(reg.control2); + break; + case CPU_DYING: + case CPU_DYING_FROZEN: + write_c0_perflo1(0xc0000000); + write_c0_perflo2(0x40000000); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block loongson3_notifier_block = { + .notifier_call = loongson3_cpu_callback +}; + +static int __init loongson3_init(void) +{ + on_each_cpu(reset_counters, NULL, 1); + register_hotcpu_notifier(&loongson3_notifier_block); + save_perf_irq = perf_irq; + perf_irq = loongson3_perfcount_handler; + + return 0; +} + +static void loongson3_exit(void) +{ + on_each_cpu(reset_counters, NULL, 1); + unregister_hotcpu_notifier(&loongson3_notifier_block); + perf_irq = save_perf_irq; +} + +struct op_mips_model op_model_loongson3_ops = { + .reg_setup = loongson3_reg_setup, + .cpu_setup = loongson3_cpu_setup, + .init = loongson3_init, + .exit = loongson3_exit, + .cpu_start = loongson3_cpu_start, + .cpu_stop = loongson3_cpu_stop, + .cpu_type = "mips/loongson3", + .num_counters = 2 +}; -- GitLab From e292ccde216e571faad475e4331c188f22a28182 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 4 Nov 2014 14:15:31 +0800 Subject: [PATCH 5996/9457] MIPS: Loongson-3: Add RS780/SBX00 HPET support CPUFreq driver need external timer, so add hpet at first. In Loongson 3, only Core-0 can receive external interrupt. As a result, timekeeping cannot absolutely use HPET timer. We use a hybrid solution: Core-0 use HPET as its clock event device, but other cores still use MIPS; clock source is global and doesn't need interrupt, so use HPET. Signed-off-by: Huacai Chen Signed-off-by: Hongliang Tao Cc: John Crispin Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/8329/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/hpet.h | 73 +++++++ arch/mips/loongson/Kconfig | 12 ++ arch/mips/loongson/common/time.c | 5 + arch/mips/loongson/loongson-3/Makefile | 2 + arch/mips/loongson/loongson-3/hpet.c | 257 +++++++++++++++++++++++++ arch/mips/loongson/loongson-3/irq.c | 2 +- 6 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 arch/mips/include/asm/hpet.h create mode 100644 arch/mips/loongson/loongson-3/hpet.c diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h new file mode 100644 index 000000000000..18a8f778bfaa --- /dev/null +++ b/arch/mips/include/asm/hpet.h @@ -0,0 +1,73 @@ +#ifndef _ASM_HPET_H +#define _ASM_HPET_H + +#ifdef CONFIG_RS780_HPET + +#define HPET_MMAP_SIZE 1024 + +#define HPET_ID 0x000 +#define HPET_PERIOD 0x004 +#define HPET_CFG 0x010 +#define HPET_STATUS 0x020 +#define HPET_COUNTER 0x0f0 + +#define HPET_Tn_CFG(n) (0x100 + 0x20 * n) +#define HPET_Tn_CMP(n) (0x108 + 0x20 * n) +#define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n) + +#define HPET_T0_IRS 0x001 +#define HPET_T1_IRS 0x002 +#define HPET_T3_IRS 0x004 + +#define HPET_T0_CFG 0x100 +#define HPET_T0_CMP 0x108 +#define HPET_T0_ROUTE 0x110 +#define HPET_T1_CFG 0x120 +#define HPET_T1_CMP 0x128 +#define HPET_T1_ROUTE 0x130 +#define HPET_T2_CFG 0x140 +#define HPET_T2_CMP 0x148 +#define HPET_T2_ROUTE 0x150 + +#define HPET_ID_REV 0x000000ff +#define HPET_ID_NUMBER 0x00001f00 +#define HPET_ID_64BIT 0x00002000 +#define HPET_ID_LEGSUP 0x00008000 +#define HPET_ID_VENDOR 0xffff0000 +#define HPET_ID_NUMBER_SHIFT 8 +#define HPET_ID_VENDOR_SHIFT 16 + +#define HPET_CFG_ENABLE 0x001 +#define HPET_CFG_LEGACY 0x002 +#define HPET_LEGACY_8254 2 +#define HPET_LEGACY_RTC 8 + +#define HPET_TN_LEVEL 0x0002 +#define HPET_TN_ENABLE 0x0004 +#define HPET_TN_PERIODIC 0x0008 +#define HPET_TN_PERIODIC_CAP 0x0010 +#define HPET_TN_64BIT_CAP 0x0020 +#define HPET_TN_SETVAL 0x0040 +#define HPET_TN_32BIT 0x0100 +#define HPET_TN_ROUTE 0x3e00 +#define HPET_TN_FSB 0x4000 +#define HPET_TN_FSB_CAP 0x8000 +#define HPET_TN_ROUTE_SHIFT 9 + +/* Max HPET Period is 10^8 femto sec as in HPET spec */ +#define HPET_MAX_PERIOD 100000000UL +/* + * Min HPET period is 10^5 femto sec just for safety. If it is less than this, + * then 32 bit HPET counter wrapsaround in less than 0.5 sec. + */ +#define HPET_MIN_PERIOD 100000UL + +#define HPET_ADDR 0x20000 +#define HPET_MMIO_ADDR 0x90000e0000020000 +#define HPET_FREQ 14318780 +#define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ) +#define HPET_T0_IRQ 0 + +extern void __init setup_hpet_timer(void); +#endif /* CONFIG_RS780_HPET */ +#endif /* _ASM_HPET_H */ diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 72f830ac0782..156de85b82cd 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -108,6 +108,18 @@ config CS5536_MFGPT If unsure, say Yes. +config RS780_HPET + bool "RS780/SBX00 HPET Timer" + depends on LOONGSON_MACH3X + select MIPS_EXTERNAL_TIMER + help + This option enables the hpet timer of AMD RS780/SBX00. + + If you want to enable the Loongson3 CPUFreq Driver, Please enable + this option at first, otherwise, You will get wrong system time. + + If unsure, say Yes. + config LOONGSON_SUSPEND bool default y diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c index 262a1f65b05e..e1a5382ad47e 100644 --- a/arch/mips/loongson/common/time.c +++ b/arch/mips/loongson/common/time.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -21,7 +22,11 @@ void __init plat_time_init(void) /* setup mips r4k timer */ mips_hpt_frequency = cpu_clock_freq / 2; +#ifdef CONFIG_RS780_HPET + setup_hpet_timer(); +#else setup_mfgpt0_timer(); +#endif } void read_persistent_clock(struct timespec *ts) diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile index 69809a3d8f34..622fead5ebc9 100644 --- a/arch/mips/loongson/loongson-3/Makefile +++ b/arch/mips/loongson/loongson-3/Makefile @@ -6,3 +6,5 @@ obj-y += irq.o cop2-ex.o platform.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_NUMA) += numa.o + +obj-$(CONFIG_RS780_HPET) += hpet.o diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c new file mode 100644 index 000000000000..e898d68668a9 --- /dev/null +++ b/arch/mips/loongson/loongson-3/hpet.c @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) +#define SMBUS_PCI_REG40 0x40 +#define SMBUS_PCI_REG64 0x64 +#define SMBUS_PCI_REGB4 0xb4 + +static DEFINE_SPINLOCK(hpet_lock); +DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); + +static unsigned int smbus_read(int offset) +{ + return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); +} + +static void smbus_write(int offset, int data) +{ + *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; +} + +static void smbus_enable(int offset, int bit) +{ + unsigned int cfg = smbus_read(offset); + + cfg |= bit; + smbus_write(offset, cfg); +} + +static int hpet_read(int offset) +{ + return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); +} + +static void hpet_write(int offset, int data) +{ + *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; +} + +static void hpet_start_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg |= HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_stop_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg &= ~HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_reset_counter(void) +{ + hpet_write(HPET_COUNTER, 0); + hpet_write(HPET_COUNTER + 4, 0); +} + +static void hpet_restart_counter(void) +{ + hpet_stop_counter(); + hpet_reset_counter(); + hpet_start_counter(); +} + +static void hpet_enable_legacy_int(void) +{ + /* Do nothing on Loongson-3 */ +} + +static void hpet_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + int cfg = 0; + + spin_lock(&hpet_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + pr_info("set clock event to periodic mode!\n"); + /* stop counter */ + hpet_stop_counter(); + + /* enables the timer0 to generate a periodic interrupt */ + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_LEVEL; + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + + /* set the comparator */ + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + udelay(1); + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + + /* start counter */ + hpet_start_counter(); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_ENABLE; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_ONESHOT: + pr_info("set clock event to one shot mode!\n"); + cfg = hpet_read(HPET_T0_CFG); + /* set timer0 type + * 1 : periodic interrupt + * 0 : non-periodic(oneshot) interrupt + */ + cfg &= ~HPET_TN_PERIODIC; + cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_RESUME: + hpet_enable_legacy_int(); + break; + } + spin_unlock(&hpet_lock); +} + +static int hpet_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + unsigned int cnt; + int res; + + cnt = hpet_read(HPET_COUNTER); + cnt += delta; + hpet_write(HPET_T0_CMP, cnt); + + res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; + return res; +} + +static irqreturn_t hpet_irq_handler(int irq, void *data) +{ + int is_irq; + struct clock_event_device *cd; + unsigned int cpu = smp_processor_id(); + + is_irq = hpet_read(HPET_STATUS); + if (is_irq & HPET_T0_IRS) { + /* clear the TIMER0 irq status register */ + hpet_write(HPET_STATUS, HPET_T0_IRS); + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->event_handler(cd); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static struct irqaction hpet_irq = { + .handler = hpet_irq_handler, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .name = "hpet", +}; + +/* + * hpet address assignation and irq setting should be done in bios. + * but pmon don't do this, we just setup here directly. + * The operation under is normal. unfortunately, hpet_setup process + * is before pci initialize. + * + * { + * struct pci_dev *pdev; + * + * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); + * + * ... + * } + */ +static void hpet_setup(void) +{ + /* set hpet base address */ + smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); + + /* enable decodeing of access to HPET MMIO*/ + smbus_enable(SMBUS_PCI_REG40, (1 << 28)); + + /* HPET irq enable */ + smbus_enable(SMBUS_PCI_REG64, (1 << 10)); + + hpet_enable_legacy_int(); +} + +void __init setup_hpet_timer(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + + hpet_setup(); + + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->name = "hpet"; + cd->rating = 320; + cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + cd->set_mode = hpet_set_mode; + cd->set_next_event = hpet_next_event; + cd->irq = HPET_T0_IRQ; + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, HPET_FREQ); + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = 5000; + + clockevents_register_device(cd); + setup_irq(HPET_T0_IRQ, &hpet_irq); + pr_info("hpet clock event device register\n"); +} + +static cycle_t hpet_read_counter(struct clocksource *cs) +{ + return (cycle_t)hpet_read(HPET_COUNTER); +} + +static void hpet_suspend(struct clocksource *cs) +{ +} + +static void hpet_resume(struct clocksource *cs) +{ + hpet_setup(); + hpet_restart_counter(); +} + +static struct clocksource csrc_hpet = { + .name = "hpet", + /* mips clocksource rating is less than 300, so hpet is better. */ + .rating = 300, + .read = hpet_read_counter, + .mask = CLOCKSOURCE_MASK(32), + /* oneshot mode work normal with this flag */ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .suspend = hpet_suspend, + .resume = hpet_resume, + .mult = 0, + .shift = 10, +}; + +int __init init_hpet_clocksource(void) +{ + csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); + return clocksource_register_hz(&csrc_hpet, HPET_FREQ); +} + +arch_initcall(init_hpet_clocksource); diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index 5813d941f9fc..21221edda7a9 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c @@ -9,7 +9,7 @@ #include "smp.h" -unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; +unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; static void ht_irqdispatch(void) { -- GitLab From 6a8d38945cf4e6e819d6b550250615db763065a0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:14 +0100 Subject: [PATCH 5997/9457] binfmt_elf: Hoist ELF program header loading to a function load_elf_binary & load_elf_interp both load program headers from an ELF executable in the same way, duplicating the code. This patch introduces a helper function (load_elf_phdrs) which performs this common task & calls it from both load_elf_binary & load_elf_interp. In addition to reducing code duplication, this is part of preparing to load the ELF interpreter headers earlier such that they can be examined before it's too late to return an error from an exec syscall. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7676/ Signed-off-by: Ralf Baechle --- fs/binfmt_elf.c | 99 ++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index d8fc0605b9d2..2b02d41f78e2 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -386,6 +386,59 @@ static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) ELF_PAGESTART(cmds[first_idx].p_vaddr); } +/** + * load_elf_phdrs() - load ELF program headers + * @elf_ex: ELF header of the binary whose program headers should be loaded + * @elf_file: the opened ELF binary file + * + * Loads ELF program headers from the binary file elf_file, which has the ELF + * header pointed to by elf_ex, into a newly allocated array. The caller is + * responsible for freeing the allocated data. Returns an ERR_PTR upon failure. + */ +static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, + struct file *elf_file) +{ + struct elf_phdr *elf_phdata = NULL; + int retval, size, err = -1; + + /* + * If the size of this structure has changed, then punt, since + * we will be doing the wrong thing. + */ + if (elf_ex->e_phentsize != sizeof(struct elf_phdr)) + goto out; + + /* Sanity check the number of program headers... */ + if (elf_ex->e_phnum < 1 || + elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr)) + goto out; + + /* ...and their total size. */ + size = sizeof(struct elf_phdr) * elf_ex->e_phnum; + if (size > ELF_MIN_ALIGN) + goto out; + + elf_phdata = kmalloc(size, GFP_KERNEL); + if (!elf_phdata) + goto out; + + /* Read in the program headers */ + retval = kernel_read(elf_file, elf_ex->e_phoff, + (char *)elf_phdata, size); + if (retval != size) { + err = (retval < 0) ? retval : -EIO; + goto out; + } + + /* Success! */ + err = 0; +out: + if (err) { + kfree(elf_phdata); + elf_phdata = NULL; + } + return elf_phdata; +} /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function @@ -403,7 +456,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, unsigned long last_bss = 0, elf_bss = 0; unsigned long error = ~0UL; unsigned long total_size; - int retval, i, size; + int i; /* First of all, some simple consistency checks */ if (interp_elf_ex->e_type != ET_EXEC && @@ -414,33 +467,10 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, if (!interpreter->f_op->mmap) goto out; - /* - * If the size of this structure has changed, then punt, since - * we will be doing the wrong thing. - */ - if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) - goto out; - if (interp_elf_ex->e_phnum < 1 || - interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr)) - goto out; - - /* Now read in all of the header information */ - size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; - if (size > ELF_MIN_ALIGN) - goto out; - elf_phdata = kmalloc(size, GFP_KERNEL); + elf_phdata = load_elf_phdrs(interp_elf_ex, interpreter); if (!elf_phdata) goto out; - retval = kernel_read(interpreter, interp_elf_ex->e_phoff, - (char *)elf_phdata, size); - error = -EIO; - if (retval != size) { - if (retval < 0) - error = retval; - goto out_close; - } - total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum); if (!total_size) { error = -EINVAL; @@ -578,7 +608,6 @@ static int load_elf_binary(struct linux_binprm *bprm) struct elf_phdr *elf_ppnt, *elf_phdata; unsigned long elf_bss, elf_brk; int retval, i; - unsigned int size; unsigned long elf_entry; unsigned long interp_load_addr = 0; unsigned long start_code, end_code, start_data, end_data; @@ -611,26 +640,10 @@ static int load_elf_binary(struct linux_binprm *bprm) if (!bprm->file->f_op->mmap) goto out; - /* Now read in all of the header information */ - if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr)) - goto out; - if (loc->elf_ex.e_phnum < 1 || - loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr)) - goto out; - size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr); - retval = -ENOMEM; - elf_phdata = kmalloc(size, GFP_KERNEL); + elf_phdata = load_elf_phdrs(&loc->elf_ex, bprm->file); if (!elf_phdata) goto out; - retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, - (char *)elf_phdata, size); - if (retval != size) { - if (retval >= 0) - retval = -EIO; - goto out_free_ph; - } - elf_ppnt = elf_phdata; elf_bss = 0; elf_brk = 0; -- GitLab From a9d9ef133f443ae91d2d24594e63714c0b53d09f Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:15 +0100 Subject: [PATCH 5998/9457] binfmt_elf: load interpreter program headers earlier Load the program headers of an ELF interpreter early enough in load_elf_binary that they can be examined before it's too late to return an error from an exec syscall. This patch does not perform any such checking, it merely lays the groundwork for a further patch to do so. No functional change is intended. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7675/ Signed-off-by: Ralf Baechle --- fs/binfmt_elf.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 2b02d41f78e2..26a951f115c1 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -447,9 +447,8 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, struct file *interpreter, unsigned long *interp_map_addr, - unsigned long no_base) + unsigned long no_base, struct elf_phdr *interp_elf_phdata) { - struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; unsigned long load_addr = 0; int load_addr_set = 0; @@ -467,17 +466,14 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, if (!interpreter->f_op->mmap) goto out; - elf_phdata = load_elf_phdrs(interp_elf_ex, interpreter); - if (!elf_phdata) - goto out; - - total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum); + total_size = total_mapping_size(interp_elf_phdata, + interp_elf_ex->e_phnum); if (!total_size) { error = -EINVAL; - goto out_close; + goto out; } - eppnt = elf_phdata; + eppnt = interp_elf_phdata; for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { if (eppnt->p_type == PT_LOAD) { int elf_type = MAP_PRIVATE | MAP_DENYWRITE; @@ -504,7 +500,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, *interp_map_addr = map_addr; error = map_addr; if (BAD_ADDR(map_addr)) - goto out_close; + goto out; if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { @@ -523,7 +519,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { error = -ENOMEM; - goto out_close; + goto out; } /* @@ -553,7 +549,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, */ if (padzero(elf_bss)) { error = -EFAULT; - goto out_close; + goto out; } /* What we have mapped so far */ @@ -562,13 +558,10 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, /* Map the last of the bss segment */ error = vm_brk(elf_bss, last_bss - elf_bss); if (BAD_ADDR(error)) - goto out_close; + goto out; } error = load_addr; - -out_close: - kfree(elf_phdata); out: return error; } @@ -605,7 +598,7 @@ static int load_elf_binary(struct linux_binprm *bprm) int load_addr_set = 0; char * elf_interpreter = NULL; unsigned long error; - struct elf_phdr *elf_ppnt, *elf_phdata; + struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; unsigned long elf_bss, elf_brk; int retval, i; unsigned long elf_entry; @@ -729,6 +722,12 @@ static int load_elf_binary(struct linux_binprm *bprm) /* Verify the interpreter has a valid arch */ if (!elf_check_arch(&loc->interp_elf_ex)) goto out_free_dentry; + + /* Load the interpreter program headers */ + interp_elf_phdata = load_elf_phdrs(&loc->interp_elf_ex, + interpreter); + if (!interp_elf_phdata) + goto out_free_dentry; } /* Flush all traces of the currently running executable */ @@ -903,7 +902,7 @@ static int load_elf_binary(struct linux_binprm *bprm) elf_entry = load_elf_interp(&loc->interp_elf_ex, interpreter, &interp_map_addr, - load_bias); + load_bias, interp_elf_phdata); if (!IS_ERR((void *)elf_entry)) { /* * load_elf_interp() returns relocation @@ -994,6 +993,7 @@ static int load_elf_binary(struct linux_binprm *bprm) /* error cleanup */ out_free_dentry: + kfree(interp_elf_phdata); allow_write_access(interpreter); if (interpreter) fput(interpreter); -- GitLab From 774c105ed8d791b709b40082d107f5bb40254374 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:16 +0100 Subject: [PATCH 5999/9457] binfmt_elf: allow arch code to examine PT_LOPROC ... PT_HIPROC headers MIPS is introducing new variants of its O32 ABI which differ in their handling of floating point, in order to enable a gradual transition towards a world where mips32 binaries can take advantage of new hardware features only available when configured for certain FP modes. In order to do this ELF binaries are being augmented with a new section that indicates, amongst other things, the FP mode requirements of the binary. The presence & location of such a section is indicated by a program header in the PT_LOPROC ... PT_HIPROC range. In order to allow the MIPS architecture code to examine the program header & section in question, pass all program headers in this range to an architecture-specific arch_elf_pt_proc function. This function may return an error if the header is deemed invalid or unsuitable for the system, in which case that error will be returned from load_elf_binary and upwards through the execve syscall. A means is required for the architecture code to make a decision once it is known that all such headers have been seen, but before it is too late to return from an execve syscall. For this purpose the arch_check_elf function is added, and called once, after all PT_LOPROC to PT_HIPROC headers have been passed to arch_elf_pt_proc but before the code which invoked execve has been lost. This enables the architecture code to make a decision based upon all the headers present in an ELF binary and its interpreter, as is required to forbid conflicting FP ABI requirements between an ELF & its interpreter. In order to allow data to be stored throughout the calls to the above functions, struct arch_elf_state is introduced. Finally a variant of the SET_PERSONALITY macro is introduced which accepts a pointer to the struct arch_elf_state, allowing it to act based upon state observed from the architecture specific program headers. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7679/ Signed-off-by: Ralf Baechle --- fs/Kconfig.binfmt | 3 ++ fs/binfmt_elf.c | 105 +++++++++++++++++++++++++++++++++++++++++++- include/linux/elf.h | 5 +++ 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 370b24cee4d8..c055d56ec63d 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -30,6 +30,9 @@ config COMPAT_BINFMT_ELF config ARCH_BINFMT_ELF_RANDOMIZE_PIE bool +config ARCH_BINFMT_ELF_STATE + bool + config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 26a951f115c1..a333cd982d33 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -440,6 +440,74 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, return elf_phdata; } +#ifndef CONFIG_ARCH_BINFMT_ELF_STATE + +/** + * struct arch_elf_state - arch-specific ELF loading state + * + * This structure is used to preserve architecture specific data during + * the loading of an ELF file, throughout the checking of architecture + * specific ELF headers & through to the point where the ELF load is + * known to be proceeding (ie. SET_PERSONALITY). + * + * This implementation is a dummy for architectures which require no + * specific state. + */ +struct arch_elf_state { +}; + +#define INIT_ARCH_ELF_STATE {} + +/** + * arch_elf_pt_proc() - check a PT_LOPROC..PT_HIPROC ELF program header + * @ehdr: The main ELF header + * @phdr: The program header to check + * @elf: The open ELF file + * @is_interp: True if the phdr is from the interpreter of the ELF being + * loaded, else false. + * @state: Architecture-specific state preserved throughout the process + * of loading the ELF. + * + * Inspects the program header phdr to validate its correctness and/or + * suitability for the system. Called once per ELF program header in the + * range PT_LOPROC to PT_HIPROC, for both the ELF being loaded and its + * interpreter. + * + * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load + * with that return code. + */ +static inline int arch_elf_pt_proc(struct elfhdr *ehdr, + struct elf_phdr *phdr, + struct file *elf, bool is_interp, + struct arch_elf_state *state) +{ + /* Dummy implementation, always proceed */ + return 0; +} + +/** + * arch_check_elf() - check a PT_LOPROC..PT_HIPROC ELF program header + * @ehdr: The main ELF header + * @has_interp: True if the ELF has an interpreter, else false. + * @state: Architecture-specific state preserved throughout the process + * of loading the ELF. + * + * Provides a final opportunity for architecture code to reject the loading + * of the ELF & cause an exec syscall to return an error. This is called after + * all program headers to be checked by arch_elf_pt_proc have been. + * + * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load + * with that return code. + */ +static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, + struct arch_elf_state *state) +{ + /* Dummy implementation, always proceed */ + return 0; +} + +#endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */ + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have @@ -611,6 +679,7 @@ static int load_elf_binary(struct linux_binprm *bprm) struct elfhdr elf_ex; struct elfhdr interp_elf_ex; } *loc; + struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; loc = kmalloc(sizeof(*loc), GFP_KERNEL); if (!loc) { @@ -705,12 +774,21 @@ static int load_elf_binary(struct linux_binprm *bprm) elf_ppnt = elf_phdata; for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) - if (elf_ppnt->p_type == PT_GNU_STACK) { + switch (elf_ppnt->p_type) { + case PT_GNU_STACK: if (elf_ppnt->p_flags & PF_X) executable_stack = EXSTACK_ENABLE_X; else executable_stack = EXSTACK_DISABLE_X; break; + + case PT_LOPROC ... PT_HIPROC: + retval = arch_elf_pt_proc(&loc->elf_ex, elf_ppnt, + bprm->file, false, + &arch_state); + if (retval) + goto out_free_dentry; + break; } /* Some simple consistency checks for the interpreter */ @@ -728,8 +806,30 @@ static int load_elf_binary(struct linux_binprm *bprm) interpreter); if (!interp_elf_phdata) goto out_free_dentry; + + /* Pass PT_LOPROC..PT_HIPROC headers to arch code */ + elf_ppnt = interp_elf_phdata; + for (i = 0; i < loc->interp_elf_ex.e_phnum; i++, elf_ppnt++) + switch (elf_ppnt->p_type) { + case PT_LOPROC ... PT_HIPROC: + retval = arch_elf_pt_proc(&loc->interp_elf_ex, + elf_ppnt, interpreter, + true, &arch_state); + if (retval) + goto out_free_dentry; + break; + } } + /* + * Allow arch code to reject the ELF at this point, whilst it's + * still possible to return an error to the code that invoked + * the exec syscall. + */ + retval = arch_check_elf(&loc->elf_ex, !!interpreter, &arch_state); + if (retval) + goto out_free_dentry; + /* Flush all traces of the currently running executable */ retval = flush_old_exec(bprm); if (retval) @@ -737,7 +837,7 @@ static int load_elf_binary(struct linux_binprm *bprm) /* Do this immediately, since STACK_TOP as used in setup_arg_pages may depend on the personality. */ - SET_PERSONALITY(loc->elf_ex); + SET_PERSONALITY2(loc->elf_ex, &arch_state); if (elf_read_implies_exec(loc->elf_ex, executable_stack)) current->personality |= READ_IMPLIES_EXEC; @@ -929,6 +1029,7 @@ static int load_elf_binary(struct linux_binprm *bprm) } } + kfree(interp_elf_phdata); kfree(elf_phdata); set_binfmt(&elf_format); diff --git a/include/linux/elf.h b/include/linux/elf.h index 67a5fa7830c4..20fa8d8ae313 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -15,6 +15,11 @@ set_personality(PER_LINUX | (current->personality & (~PER_MASK))) #endif +#ifndef SET_PERSONALITY2 +#define SET_PERSONALITY2(ex, state) \ + SET_PERSONALITY(ex) +#endif + #if ELF_CLASS == ELFCLASS32 extern Elf32_Dyn _DYNAMIC []; -- GitLab From 5ff04a8433b0ff396c4adcc03fe7787e22f57cb1 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:17 +0100 Subject: [PATCH 6000/9457] MIPS: define bits introduced for hybrid FPRs Add definitions for the FRE & UFE bits in Config5, and the FREP bit in FPIR. These bits are used to support a hybrid FPR scheme allowing a mixture of FP32 & FP64 code to execute within a task. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7674/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mipsregs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index b46cd220a018..7ebb6544392e 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -653,6 +653,8 @@ #define MIPS_CONF5_NF (_ULCAST_(1) << 0) #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) +#define MIPS_CONF5_FRE (_ULCAST_(1) << 8) +#define MIPS_CONF5_UFE (_ULCAST_(1) << 9) #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) #define MIPS_CONF5_CV (_ULCAST_(1) << 29) @@ -692,6 +694,7 @@ #define MIPS_FPIR_W (_ULCAST_(1) << 20) #define MIPS_FPIR_L (_ULCAST_(1) << 21) #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) +#define MIPS_FPIR_FREP (_ULCAST_(1) << 29) /* * Bits in the MIPS32 Memory Segmentation registers. -- GitLab From adac5d535d4e364324b92798bfb68336197e815e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:18 +0100 Subject: [PATCH 6001/9457] MIPS: detect presence of the FRE & UFR bits Detect the presence of the Config5 FRE & UFE bits, as indicated by the FREP bit in FPIR. Record this as a CPU option bit, and provide a cpu_has_fre macro to ease checking of that option bit. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7678/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/cpu-features.h | 4 ++++ arch/mips/include/asm/cpu.h | 1 + arch/mips/kernel/cpu-probe.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 3325f3eb248c..2897cfafcaf0 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -344,4 +344,8 @@ # define cpu_has_msa 0 #endif +#ifndef cpu_has_fre +# define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE) +#endif + #endif /* __ASM_CPU_FEATURES_H */ diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index dfdc77ed1839..11025bfbd8db 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -368,6 +368,7 @@ enum cpu_type_enum { #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ +#define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ /* * CPU ASE encodings diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b27e7ffd1112..d76f189291bc 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1317,6 +1317,8 @@ void cpu_probe(void) MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; + if (c->fpu_id & MIPS_FPIR_FREP) + c->options |= MIPS_CPU_FRE; } } -- GitLab From d175ed2bd6544474dcc99d74f8155c2ba44e8db2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:19 +0100 Subject: [PATCH 6002/9457] MIPS: Ensure Config5.UFE is clear on boot As is done for UFR, ensure that userland cannot directly manipulate the mode by clearing the UFE bit during boot. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7677/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d76f189291bc..d68ad96392f8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -461,7 +461,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) unsigned int config5; config5 = read_c0_config5(); - config5 &= ~MIPS_CONF5_UFR; + config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); write_c0_config5(config5); if (config5 & MIPS_CONF5_EVA) -- GitLab From 4227a2d4efc9c84f35826dc4d1e6dc183f6c1c05 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:20 +0100 Subject: [PATCH 6003/9457] MIPS: Support for hybrid FPRs Hybrid FPRs is a scheme where scalar FP registers are 64b wide, but accesses to odd indexed single registers use bits 63:32 of the preceeding even indexed 64b register. In this mode all FP code except that built for the plain FP64 ABI can execute correctly. Most notably a combination of FP64A & FP32 code can execute correctly, allowing for existing FP32 binaries to be linked with new FP64A binaries that can make use of 64 bit FP & MSA. Hybrid FPRs are implemented by setting both the FR & FRE bits, trapping & emulating single precision FP instructions (via Reserved Instruction exceptions) whilst allowing others to execute natively. It therefore has a penalty in terms of execution speed, and should only be used when no fully native mode can be. As more binaries are recompiled to use either the FPXX or FP64(A) ABIs, the need for hybrid FPRs should diminish. However in the short to mid term it allows for a gradual transition towards that world, rather than a complete ABI break which is not feasible for some users & not desirable for many. A task will be executed using the hybrid FPR scheme when its TIF_HYBRID_FPREGS flag is set & TIF_32BIT_FPREGS is clear. A further patch will set the flags as necessary, this patch simply adds the infrastructure necessary for the hybrid FPR mode to work. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7683/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/elf.h | 3 ++ arch/mips/include/asm/fpu.h | 49 ++++++++++++++++++++++++----- arch/mips/include/asm/thread_info.h | 2 ++ arch/mips/kernel/traps.c | 47 +++++++++++++++++++++++++++ arch/mips/math-emu/cp1emu.c | 9 ++++-- 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1d38fe0edd2d..9343529db7bc 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -269,6 +269,8 @@ do { \ else \ set_thread_flag(TIF_32BIT_FPREGS); \ \ + clear_thread_flag(TIF_HYBRID_FPREGS); \ + \ if (personality(current->personality) != PER_LINUX) \ set_personality(PER_LINUX); \ \ @@ -325,6 +327,7 @@ do { \ \ clear_thread_flag(TIF_32BIT_REGS); \ clear_thread_flag(TIF_32BIT_FPREGS); \ + clear_thread_flag(TIF_HYBRID_FPREGS); \ clear_thread_flag(TIF_32BIT_ADDR); \ \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index dd562414cd5e..994d21939676 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *); /* * This enum specifies a mode in which we want the FPU to operate, for cores - * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT - * purposefully have the values 0 & 1 respectively, so that an integer value - * of Status.FR can be trivially casted to the corresponding enum fpu_mode. + * which implement the Status.FR bit. Note that the bottom bit of the value + * purposefully matches the desired value of the Status.FR bit. */ enum fpu_mode { FPU_32BIT = 0, /* FR = 0 */ - FPU_64BIT, /* FR = 1 */ + FPU_64BIT, /* FR = 1, FRE = 0 */ FPU_AS_IS, + FPU_HYBRID, /* FR = 1, FRE = 1 */ + +#define FPU_FR_MASK 0x1 }; static inline int __enable_fpu(enum fpu_mode mode) @@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode) enable_fpu_hazard(); return 0; + case FPU_HYBRID: + if (!cpu_has_fre) + return SIGFPE; + + /* set FRE */ + write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); + goto fr_common; + case FPU_64BIT: #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) /* we only have a 32-bit FPU */ @@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode) #endif /* fall through */ case FPU_32BIT: + /* clear FRE */ + write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); +fr_common: /* set CU1 & change FR appropriately */ - fr = (int)mode; + fr = (int)mode & FPU_FR_MASK; change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); enable_fpu_hazard(); @@ -102,13 +115,17 @@ static inline int __own_fpu(void) enum fpu_mode mode; int ret; - mode = !test_thread_flag(TIF_32BIT_FPREGS); + if (test_thread_flag(TIF_HYBRID_FPREGS)) + mode = FPU_HYBRID; + else + mode = !test_thread_flag(TIF_32BIT_FPREGS); + ret = __enable_fpu(mode); if (ret) return ret; KSTK_STATUS(current) |= ST0_CU1; - if (mode == FPU_64BIT) + if (mode == FPU_64BIT || mode == FPU_HYBRID) KSTK_STATUS(current) |= ST0_FR; else /* mode == FPU_32BIT */ KSTK_STATUS(current) &= ~ST0_FR; @@ -166,8 +183,24 @@ static inline int init_fpu(void) if (cpu_has_fpu) { ret = __own_fpu(); - if (!ret) + if (!ret) { + unsigned int config5 = read_c0_config5(); + + /* + * Ensure FRE is clear whilst running _init_fpu, since + * single precision FP instructions are used. If FRE + * was set then we'll just end up initialising all 32 + * 64b registers. + */ + write_c0_config5(config5 & ~MIPS_CONF5_FRE); + enable_fpu_hazard(); + _init_fpu(); + + /* Restore FRE */ + write_c0_config5(config5); + enable_fpu_hazard(); + } } else fpu_emulator_init_fpu(); diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 7de865805deb..99eea59604e9 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ #define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ +#define TIF_HYBRID_FPREGS 28 /* 64b FP registers, odd singles in bits 63:32 of even doubles */ #define TIF_USEDMSA 29 /* MSA has been used this quantum */ #define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ @@ -135,6 +136,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_FPUBOUND (1<cp0_epc = old_epc; + regs->regs[31] = old_ra; + + /* Save the FP context to struct thread_struct */ + lose_fpu(1); + + /* Run the emulator */ + sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, + &fault_addr); + + /* If something went wrong, signal */ + process_fpemu_return(sig, fault_addr); + + /* Restore the hardware register state */ + own_fpu(1); + + return 0; +} + /* * XXX Delayed fp exceptions when doing a lazy ctx switch XXX */ @@ -1016,6 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *regs) if (status < 0) status = simulate_sync(regs, opcode); + + if (status < 0) + status = simulate_fp(regs, opcode, old_epc, old31); } if (status < 0) diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index cac529a405b8..9dfcd7fc1bc3 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -643,9 +643,14 @@ static inline int cop1_64bit(struct pt_regs *xcp) return !test_thread_flag(TIF_32BIT_FPREGS); } +static inline bool hybrid_fprs(void) +{ + return test_thread_flag(TIF_HYBRID_FPREGS); +} + #define SIFROMREG(si, x) \ do { \ - if (cop1_64bit(xcp)) \ + if (cop1_64bit(xcp) && !hybrid_fprs()) \ (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ else \ (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ @@ -653,7 +658,7 @@ do { \ #define SITOREG(si, x) \ do { \ - if (cop1_64bit(xcp)) { \ + if (cop1_64bit(xcp) && !hybrid_fprs()) { \ unsigned i; \ set_fpr32(&ctx->fpr[x], 0, si); \ for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ -- GitLab From 6cd962292d9eb3b3e7189fde532f7e49f395cccb Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:21 +0100 Subject: [PATCH 6004/9457] MIPS: ELF: Add definition for the .MIPS.abiflags section New toolchains will generate a .MIPS.abiflags section, referenced by a new PT_MIPS_ABIFLAGS program header. This section will provide information about the requirements of the ELF, including the ISA level the code is built for, the ASEs it requires, the size of various registers and its expectations of the floating point mode. This patch introduces a definition of the structure of this section and the program header, for use in a subsequent patch. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7682/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/elf.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 9343529db7bc..bfa4bbd42c6c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -28,6 +28,7 @@ #define PT_MIPS_REGINFO 0x70000000 #define PT_MIPS_RTPROC 0x70000001 #define PT_MIPS_OPTIONS 0x70000002 +#define PT_MIPS_ABIFLAGS 0x70000003 /* Flags in the e_flags field of the header */ #define EF_MIPS_NOREORDER 0x00000001 @@ -174,6 +175,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +struct mips_elf_abiflags_v0 { + uint16_t version; /* Version of flags structure */ + uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */ + uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below, + 1-n otherwise */ + uint8_t gpr_size; /* The size of general purpose registers */ + uint8_t cpr1_size; /* The size of co-processor 1 registers */ + uint8_t cpr2_size; /* The size of co-processor 2 registers */ + uint8_t fp_abi; /* The floating-point ABI */ + uint32_t isa_ext; /* Mask of processor-specific extensions */ + uint32_t ases; /* Mask of ASEs used */ + uint32_t flags1; /* Mask of general flags */ + uint32_t flags2; +}; + +#define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ +#define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ +#define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ +#define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ +#define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ +#define MIPS_ABI_FP_XX 5 /* -mfpxx */ +#define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ +#define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ + #ifdef CONFIG_32BIT /* -- GitLab From 90cee759f08a6b7a8daab9977d3e163ebbcac220 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:22 +0100 Subject: [PATCH 6005/9457] MIPS: ELF: Set FP mode according to .MIPS.abiflags This patch reads the .MIPS.abiflags section when it is present, and sets the FP mode of the task accordingly. Any loaded ELF files which do not contain a .MIPS.abiflags section will continue to observe the previous behaviour, that is FR=1 if EF_MIPS_FP64 is set else FR=0. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7681/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/include/asm/elf.h | 50 +++++++---- arch/mips/kernel/Makefile | 7 +- arch/mips/kernel/elf.c | 173 ++++++++++++++++++++++++++++++++++++ 4 files changed, 211 insertions(+), 20 deletions(-) create mode 100644 arch/mips/kernel/elf.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e0b7c2006900..4a7e0c13c61d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -53,6 +53,7 @@ config MIPS select HAVE_CC_STACKPROTECTOR select CPU_PM if CPU_IDLE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_BINFMT_ELF_STATE menu "Machine selection" diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index bfa4bbd42c6c..eb4d95de619c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -8,6 +8,8 @@ #ifndef _ASM_ELF_H #define _ASM_ELF_H +#include +#include /* ELF header e_flags defines. */ /* MIPS architecture level. */ @@ -287,18 +289,13 @@ extern struct mips_abi mips_abi_n32; #ifdef CONFIG_32BIT -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY2(ex, state) \ do { \ - if ((ex).e_flags & EF_MIPS_FP64) \ - clear_thread_flag(TIF_32BIT_FPREGS); \ - else \ - set_thread_flag(TIF_32BIT_FPREGS); \ - \ - clear_thread_flag(TIF_HYBRID_FPREGS); \ - \ if (personality(current->personality) != PER_LINUX) \ set_personality(PER_LINUX); \ \ + mips_set_personality_fp(state); \ + \ current->thread.abi = &mips_abi; \ } while (0) @@ -318,35 +315,34 @@ do { \ #endif #ifdef CONFIG_MIPS32_O32 -#define __SET_PERSONALITY32_O32(ex) \ +#define __SET_PERSONALITY32_O32(ex, state) \ do { \ set_thread_flag(TIF_32BIT_REGS); \ set_thread_flag(TIF_32BIT_ADDR); \ \ - if (!((ex).e_flags & EF_MIPS_FP64)) \ - set_thread_flag(TIF_32BIT_FPREGS); \ + mips_set_personality_fp(state); \ \ current->thread.abi = &mips_abi_32; \ } while (0) #else -#define __SET_PERSONALITY32_O32(ex) \ +#define __SET_PERSONALITY32_O32(ex, state) \ do { } while (0) #endif #ifdef CONFIG_MIPS32_COMPAT -#define __SET_PERSONALITY32(ex) \ +#define __SET_PERSONALITY32(ex, state) \ do { \ if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ ((ex).e_flags & EF_MIPS_ABI) == 0) \ __SET_PERSONALITY32_N32(); \ else \ - __SET_PERSONALITY32_O32(ex); \ + __SET_PERSONALITY32_O32(ex, state); \ } while (0) #else -#define __SET_PERSONALITY32(ex) do { } while (0) +#define __SET_PERSONALITY32(ex, state) do { } while (0) #endif -#define SET_PERSONALITY(ex) \ +#define SET_PERSONALITY2(ex, state) \ do { \ unsigned int p; \ \ @@ -356,7 +352,7 @@ do { \ clear_thread_flag(TIF_32BIT_ADDR); \ \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ - __SET_PERSONALITY32(ex); \ + __SET_PERSONALITY32(ex, state); \ else \ current->thread.abi = &mips_abi; \ \ @@ -418,4 +414,24 @@ struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk +struct arch_elf_state { + int fp_abi; + int interp_fp_abi; + int overall_abi; +}; + +#define INIT_ARCH_ELF_STATE { \ + .fp_abi = -1, \ + .interp_fp_abi = -1, \ + .overall_abi = -1, \ +} + +extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, + bool is_interp, struct arch_elf_state *state); + +extern int arch_check_elf(void *ehdr, bool has_interpreter, + struct arch_elf_state *state); + +extern void mips_set_personality_fp(struct arch_elf_state *state); + #endif /* _ASM_ELF_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 3982e5138f61..0945d804ec3a 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -4,9 +4,10 @@ extra-y := head.o vmlinux.lds -obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ - prom.o ptrace.o reset.o setup.o signal.o syscall.o \ - time.o topology.o traps.o unaligned.o watch.o vdso.o +obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ + process.o prom.o ptrace.o reset.o setup.o signal.o \ + syscall.o time.o topology.o traps.o unaligned.o watch.o \ + vdso.o ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c new file mode 100644 index 000000000000..0933e0726f64 --- /dev/null +++ b/arch/mips/kernel/elf.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2014 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +enum { + FP_ERROR = -1, + FP_DOUBLE_64A = -2, +}; + +int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, + bool is_interp, struct arch_elf_state *state) +{ + struct elfhdr *ehdr = _ehdr; + struct elf_phdr *phdr = _phdr; + struct mips_elf_abiflags_v0 abiflags; + int ret; + + if (config_enabled(CONFIG_64BIT) && + (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) + return 0; + if (phdr->p_type != PT_MIPS_ABIFLAGS) + return 0; + if (phdr->p_filesz < sizeof(abiflags)) + return -EINVAL; + + ret = kernel_read(elf, phdr->p_offset, (char *)&abiflags, + sizeof(abiflags)); + if (ret < 0) + return ret; + if (ret != sizeof(abiflags)) + return -EIO; + + /* Record the required FP ABIs for use by mips_check_elf */ + if (is_interp) + state->interp_fp_abi = abiflags.fp_abi; + else + state->fp_abi = abiflags.fp_abi; + + return 0; +} + +static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi) +{ + /* If the ABI requirement is provided, simply return that */ + if (in_abi != -1) + return in_abi; + + /* If the EF_MIPS_FP64 flag was set, return MIPS_ABI_FP_64 */ + if (ehdr->e_flags & EF_MIPS_FP64) + return MIPS_ABI_FP_64; + + /* Default to MIPS_ABI_FP_DOUBLE */ + return MIPS_ABI_FP_DOUBLE; +} + +int arch_check_elf(void *_ehdr, bool has_interpreter, + struct arch_elf_state *state) +{ + struct elfhdr *ehdr = _ehdr; + unsigned fp_abi, interp_fp_abi, abi0, abi1; + + /* Ignore non-O32 binaries */ + if (config_enabled(CONFIG_64BIT) && + (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) + return 0; + + fp_abi = get_fp_abi(ehdr, state->fp_abi); + + if (has_interpreter) { + interp_fp_abi = get_fp_abi(ehdr, state->interp_fp_abi); + + abi0 = min(fp_abi, interp_fp_abi); + abi1 = max(fp_abi, interp_fp_abi); + } else { + abi0 = abi1 = fp_abi; + } + + state->overall_abi = FP_ERROR; + + if (abi0 == abi1) { + state->overall_abi = abi0; + } else if (abi0 == MIPS_ABI_FP_ANY) { + state->overall_abi = abi1; + } else if (abi0 == MIPS_ABI_FP_DOUBLE) { + switch (abi1) { + case MIPS_ABI_FP_XX: + state->overall_abi = MIPS_ABI_FP_DOUBLE; + break; + + case MIPS_ABI_FP_64A: + state->overall_abi = FP_DOUBLE_64A; + break; + } + } else if (abi0 == MIPS_ABI_FP_SINGLE || + abi0 == MIPS_ABI_FP_SOFT) { + /* Cannot link with other ABIs */ + } else if (abi0 == MIPS_ABI_FP_OLD_64) { + switch (abi1) { + case MIPS_ABI_FP_XX: + case MIPS_ABI_FP_64: + case MIPS_ABI_FP_64A: + state->overall_abi = MIPS_ABI_FP_64; + break; + } + } else if (abi0 == MIPS_ABI_FP_XX || + abi0 == MIPS_ABI_FP_64 || + abi0 == MIPS_ABI_FP_64A) { + state->overall_abi = MIPS_ABI_FP_64; + } + + switch (state->overall_abi) { + case MIPS_ABI_FP_64: + case MIPS_ABI_FP_64A: + case FP_DOUBLE_64A: + if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) + return -ELIBBAD; + break; + + case FP_ERROR: + return -ELIBBAD; + } + + return 0; +} + +void mips_set_personality_fp(struct arch_elf_state *state) +{ + switch (state->overall_abi) { + case MIPS_ABI_FP_DOUBLE: + case MIPS_ABI_FP_SINGLE: + case MIPS_ABI_FP_SOFT: + /* FR=0 */ + set_thread_flag(TIF_32BIT_FPREGS); + clear_thread_flag(TIF_HYBRID_FPREGS); + break; + + case FP_DOUBLE_64A: + /* FR=1, FRE=1 */ + clear_thread_flag(TIF_32BIT_FPREGS); + set_thread_flag(TIF_HYBRID_FPREGS); + break; + + case MIPS_ABI_FP_64: + case MIPS_ABI_FP_64A: + /* FR=1, FRE=0 */ + clear_thread_flag(TIF_32BIT_FPREGS); + clear_thread_flag(TIF_HYBRID_FPREGS); + break; + + case MIPS_ABI_FP_XX: + case MIPS_ABI_FP_ANY: + if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) + set_thread_flag(TIF_32BIT_FPREGS); + else + clear_thread_flag(TIF_32BIT_FPREGS); + + clear_thread_flag(TIF_HYBRID_FPREGS); + break; + + default: + case FP_ERROR: + BUG(); + } +} -- GitLab From f4af6fb2fc942e84612e8c1a80f0727a797a750a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 11 Sep 2014 08:30:23 +0100 Subject: [PATCH 6006/9457] MIPS: Kconfig option to better exercise/debug hybrid FPRs The hybrid FPR scheme exists to allow for compatibility between existing FP32 code and newly compiled FP64A code. Such code should hopefully be rare in the real world, and for the moment is difficult to come across. All code except that built for the FP64 ABI can correctly execute using the hybrid FPR scheme, so debugging the hybrid FPR implementation can be eased by forcing all such code to use it. This is undesirable in general due to the trap & emulate overhead of the hybrid FPR implementation, but is a very useful option to have for debugging. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7680/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig.debug | 13 +++++++++++++ arch/mips/kernel/elf.c | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 3a2b775e8458..88a9f433f6fc 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -122,4 +122,17 @@ config SPINLOCK_TEST help Add several files to the debugfs to test spinlock speed. +config FP32XX_HYBRID_FPRS + bool "Run FP32 & FPXX code with hybrid FPRs" + depends on MIPS_O32_FP64_SUPPORT + help + The hybrid FPR scheme is normally used only when a program needs to + execute a mix of FP32 & FP64A code, since the trapping & emulation + that it entails is expensive. When enabled, this option will lead + to the kernel running programs which use the FP32 & FPXX FP ABIs + using the hybrid FPR scheme, which can be useful for debugging + purposes. + + If unsure, say N. + endmenu diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 0933e0726f64..c92b15df6893 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -134,6 +134,24 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void mips_set_personality_fp(struct arch_elf_state *state) { + if (config_enabled(CONFIG_FP32XX_HYBRID_FPRS)) { + /* + * Use hybrid FPRs for all code which can correctly execute + * with that mode. + */ + switch (state->overall_abi) { + case MIPS_ABI_FP_DOUBLE: + case MIPS_ABI_FP_SINGLE: + case MIPS_ABI_FP_SOFT: + case MIPS_ABI_FP_XX: + case MIPS_ABI_FP_ANY: + /* FR=1, FRE=1 */ + clear_thread_flag(TIF_32BIT_FPREGS); + set_thread_flag(TIF_HYBRID_FPREGS); + return; + } + } + switch (state->overall_abi) { case MIPS_ABI_FP_DOUBLE: case MIPS_ABI_FP_SINGLE: -- GitLab From 9d1d08646af4491aec41d40341930b9bfd62ffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 29 Oct 2014 10:05:06 +0100 Subject: [PATCH 6007/9457] MIPS: BCM47XX: Use mtd as an alternative way/API to get NVRAM content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NVRAM can be read using magic memory offset, but after all it's just a flash partition. On platforms where NVRAM isn't needed early we can get it using mtd subsystem. Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8266/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 42 +++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 21712fb40d72..8b6499100db3 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -13,12 +13,10 @@ #include #include -#include #include #include -#include +#include #include -#include static char nvram_buf[NVRAM_SPACE]; static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; @@ -123,7 +121,43 @@ int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) static int nvram_init(void) { - /* TODO: Look for MTD "nvram" partition */ +#ifdef CONFIG_MTD + struct mtd_info *mtd; + struct nvram_header header; + size_t bytes_read; + int err, i; + + mtd = get_mtd_device_nm("nvram"); + if (IS_ERR(mtd)) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { + loff_t from = mtd->size - nvram_sizes[i]; + + if (from < 0) + continue; + + err = mtd_read(mtd, from, sizeof(header), &bytes_read, + (uint8_t *)&header); + if (!err && header.magic == NVRAM_HEADER) { + u8 *dst = (uint8_t *)nvram_buf; + size_t len = header.len; + + if (header.len > NVRAM_SPACE) { + pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", + header.len, NVRAM_SPACE); + len = NVRAM_SPACE; + } + + err = mtd_read(mtd, from, len, &bytes_read, dst); + if (err) + return err; + memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read); + + return 0; + } + } +#endif return -ENXIO; } -- GitLab From 341097f17c76b3dd39539526a2af9e7fff43705e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 30 Oct 2014 12:50:03 +0100 Subject: [PATCH 6008/9457] MIPS: BCM47XX: Clean up nvram header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) Move private defines to the .c file 2) Move SPROM helper to the sprom.c 3) Drop unused code 4) Rename magic to the NVRAM_MAGIC 5) Add const to the char pointer we never modify Signed-off-by: Rafał Miłecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8289/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 23 +++++++++--- arch/mips/bcm47xx/sprom.c | 14 ++++++++ .../include/asm/mach-bcm47xx/bcm47xx_nvram.h | 35 +------------------ 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 8b6499100db3..c5c381c43f17 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -18,6 +18,19 @@ #include #include +#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ +#define NVRAM_SPACE 0x8000 + +#define FLASH_MIN 0x00020000 /* Minimum flash size */ + +struct nvram_header { + u32 magic; + u32 len; + u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ + u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ + u32 config_ncdl; /* ncdl values for memc */ +}; + static char nvram_buf[NVRAM_SPACE]; static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; @@ -28,7 +41,7 @@ static u32 find_nvram_size(void __iomem *end) for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { header = (struct nvram_header *)(end - nvram_sizes[i]); - if (header->magic == NVRAM_HEADER) + if (header->magic == NVRAM_MAGIC) return nvram_sizes[i]; } @@ -63,13 +76,13 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim) /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ header = (struct nvram_header *)(iobase + 4096); - if (header->magic == NVRAM_HEADER) { + if (header->magic == NVRAM_MAGIC) { size = NVRAM_SPACE; goto found; } header = (struct nvram_header *)(iobase + 1024); - if (header->magic == NVRAM_HEADER) { + if (header->magic == NVRAM_MAGIC) { size = NVRAM_SPACE; goto found; } @@ -139,7 +152,7 @@ static int nvram_init(void) err = mtd_read(mtd, from, sizeof(header), &bytes_read, (uint8_t *)&header); - if (!err && header.magic == NVRAM_HEADER) { + if (!err && header.magic == NVRAM_MAGIC) { u8 *dst = (uint8_t *)nvram_buf; size_t len = header.len; @@ -162,7 +175,7 @@ static int nvram_init(void) return -ENXIO; } -int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) +int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) { char *var, *value, *end, *eq; int err; diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index e772e775c797..2eff7fe99c6b 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name, *leddc_off_time = (val >> 16) & 0xff; } +static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) +{ + if (strchr(buf, ':')) + sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], + &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], + &macaddr[5]); + else if (strchr(buf, '-')) + sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], + &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], + &macaddr[5]); + else + pr_warn("Can not parse mac address: %s\n", buf); +} + static void nvram_read_macaddr(const char *prefix, const char *name, u8 val[6], bool fallback) { diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index 676be22bcab3..ee59ffe99922 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h @@ -14,41 +14,8 @@ #include #include -struct nvram_header { - u32 magic; - u32 len; - u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ - u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ - u32 config_ncdl; /* ncdl values for memc */ -}; - -#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */ -#define NVRAM_VERSION 1 -#define NVRAM_HEADER_SIZE 20 -#define NVRAM_SPACE 0x8000 - -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -#define NVRAM_MAX_VALUE_LEN 255 -#define NVRAM_MAX_PARAM_LEN 64 - int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); -extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); - -static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) -{ - if (strchr(buf, ':')) - sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], - &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], - &macaddr[5]); - else if (strchr(buf, '-')) - sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], - &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], - &macaddr[5]); - else - printk(KERN_WARNING "Can not parse mac address: %s\n", buf); -} - +int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); int bcm47xx_nvram_gpio_pin(const char *name); #endif /* __BCM47XX_NVRAM_H */ -- GitLab From 0dc294c05d9df09ca4a65071e370247eaab8638d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 11 Nov 2014 22:22:03 +0100 Subject: [PATCH 6009/9457] MIPS: DMA: Explain the lack of special handling for R14000/R16000. Signed-off-by: Ralf Baechle --- arch/mips/mm/dma-default.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 33ba3c558fe4..af5f046e627e 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -61,6 +61,11 @@ static inline struct page *dma_addr_to_page(struct device *dev, * Warning on the terminology - Linux calls an uncached area coherent; * MIPS terminology calls memory areas with hardware maintained coherency * coherent. + * + * Note that the R14000 and R16000 should also be checked for in this + * condition. However this function is only called on non-I/O-coherent + * systems and only the R10000 and R12000 are used in such systems, the + * SGI IP28 Indigo² rsp. SGI IP32 aka O2. */ static inline int cpu_needs_post_dma_flush(struct device *dev) { -- GitLab From a13f0795752389f84bc31b9171cb79ad6759e4db Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Fri, 10 Oct 2014 11:39:59 +0800 Subject: [PATCH 6010/9457] MIPS: Loongson1B: Fix reboot problem on LS1B - Correct the header file of watchdog registers - Use ioremap_nocache() to access watchdog registers instead Signed-off-by: Kelvin Cheung Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8022/ Signed-off-by: Ralf Baechle --- .../include/asm/mach-loongson1/regs-wdt.h | 11 ++++------ arch/mips/loongson1/common/reset.c | 20 +++++++++++++------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h index 6574568c2084..c39ee982ad3b 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h +++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2011 Zhang, Keguang * - * Loongson 1 watchdog register definitions. + * Loongson 1 Watchdog Register Definitions. * * 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 @@ -12,11 +12,8 @@ #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H #define __ASM_MACH_LOONGSON1_REGS_WDT_H -#define LS1X_WDT_REG(x) \ - ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) - -#define LS1X_WDT_EN LS1X_WDT_REG(0x0) -#define LS1X_WDT_SET LS1X_WDT_REG(0x4) -#define LS1X_WDT_TIMER LS1X_WDT_REG(0x8) +#define WDT_EN 0x0 +#define WDT_TIMER 0x4 +#define WDT_SET 0x8 #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c index 547f34b69e4c..c41e4ca56ab4 100644 --- a/arch/mips/loongson1/common/reset.c +++ b/arch/mips/loongson1/common/reset.c @@ -14,12 +14,7 @@ #include -static void ls1x_restart(char *command) -{ - __raw_writel(0x1, LS1X_WDT_EN); - __raw_writel(0x5000000, LS1X_WDT_TIMER); - __raw_writel(0x1, LS1X_WDT_SET); -} +static void __iomem *wdt_base; static void ls1x_halt(void) { @@ -29,6 +24,15 @@ static void ls1x_halt(void) } } +static void ls1x_restart(char *command) +{ + __raw_writel(0x1, wdt_base + WDT_EN); + __raw_writel(0x1, wdt_base + WDT_TIMER); + __raw_writel(0x1, wdt_base + WDT_SET); + + ls1x_halt(); +} + static void ls1x_power_off(void) { ls1x_halt(); @@ -36,6 +40,10 @@ static void ls1x_power_off(void) static int __init ls1x_reboot_setup(void) { + wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); + if (!wdt_base) + panic("Failed to remap watchdog registers"); + _machine_restart = ls1x_restart; _machine_halt = ls1x_halt; pm_power_off = ls1x_power_off; -- GitLab From 813c14108d0f5bbddc125fb7a6a0819fcdcf61e2 Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Fri, 10 Oct 2014 11:40:00 +0800 Subject: [PATCH 6011/9457] MIPS: Loongson1B: Improve early printk - Determine serial port for early printk according to kernel command line. - Move to 8250/16550 serial early printk driver. Signed-off-by: Kelvin Cheung Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8023/ Signed-off-by: Ralf Baechle --- arch/mips/loongson1/Kconfig | 1 + arch/mips/loongson1/common/prom.c | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index e23c25d09963..4ed9744fe051 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig @@ -16,6 +16,7 @@ config LOONGSON1_LS1B select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_MIPS16 select SYS_HAS_EARLY_PRINTK + select USE_GENERIC_EARLY_PRINTK_8250 select COMMON_CLK endchoice diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c index 2a47af5a55c3..68600980ea49 100644 --- a/arch/mips/loongson1/common/prom.c +++ b/arch/mips/loongson1/common/prom.c @@ -27,7 +27,7 @@ char *prom_getenv(char *envname) i = strlen(envname); while (*env) { - if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') + if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') return *env + i + 1; env++; } @@ -49,7 +49,7 @@ void __init prom_init_cmdline(void) for (i = 1; i < prom_argc; i++) { strcpy(c, prom_argv[i]); c += strlen(prom_argv[i]); - if (i < prom_argc-1) + if (i < prom_argc - 1) *c++ = ' '; } *c = 0; @@ -57,6 +57,7 @@ void __init prom_init_cmdline(void) void __init prom_init(void) { + void __iomem *uart_base; prom_argc = fw_arg0; prom_argv = (char **)fw_arg1; prom_envp = (char **)fw_arg2; @@ -65,23 +66,18 @@ void __init prom_init(void) memsize = env_or_default("memsize", DEFAULT_MEMSIZE); highmemsize = env_or_default("highmemsize", 0x0); -} -void __init prom_free_prom_memory(void) -{ + if (strstr(arcs_cmdline, "console=ttyS3")) + uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS2")) + uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS1")) + uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); + else + uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); + setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); } -#define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) - -void prom_putchar(char c) +void __init prom_free_prom_memory(void) { - int timeout; - - timeout = 1024; - - while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0) - && (timeout-- > 0)) - ; - - writeb(c, PORT(UART_TX)); } -- GitLab From f29ad10de6c345c8ae4cb33a99ba8ff29bdcd751 Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Fri, 10 Oct 2014 11:40:01 +0800 Subject: [PATCH 6012/9457] MIPS: Loongson1B: Some fixes/updates for LS1B - Fix hanging ethernet issue of LS1B v2.0 by adding pbl field in plat data. (It seems that the MAC controller of LS1B v2.0 can only accept pbl=1) - Add GMAC1 support and setup MUX in terms of PHY mode. - Add CPUFreq support. - Add MUX Register Definitions. - Add PWM Register Definitions. - Update clock register bitfields according to the latest spec. - Update clock related stuff. Signed-off-by: Kelvin Cheung Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8024/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + .../mips/include/asm/mach-loongson1/cpufreq.h | 23 +++ .../include/asm/mach-loongson1/loongson1.h | 8 +- .../include/asm/mach-loongson1/platform.h | 10 +- .../include/asm/mach-loongson1/regs-clk.h | 23 ++- .../include/asm/mach-loongson1/regs-mux.h | 67 +++++++++ .../include/asm/mach-loongson1/regs-pwm.h | 29 ++++ arch/mips/loongson1/common/platform.c | 141 +++++++++++++++--- arch/mips/loongson1/ls1b/board.c | 12 +- 9 files changed, 283 insertions(+), 31 deletions(-) create mode 100644 arch/mips/include/asm/mach-loongson1/cpufreq.h create mode 100644 arch/mips/include/asm/mach-loongson1/regs-mux.h create mode 100644 arch/mips/include/asm/mach-loongson1/regs-pwm.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4a7e0c13c61d..9ea76ed1c2e4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1573,6 +1573,7 @@ config CPU_LOONGSON1 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_CPUFREQ config CPU_BMIPS32_3300 select SMP_UP if SMP diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h new file mode 100644 index 000000000000..e7765ce30bcf --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/cpufreq.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 CPUFreq platform support. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + + +#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H +#define __ASM_MACH_LOONGSON1_CPUFREQ_H + +struct plat_ls1x_cpufreq { + const char *clk_name; /* CPU clk */ + const char *osc_clk_name; /* OSC clk */ + unsigned int max_freq; /* in kHz */ + unsigned int min_freq; /* in kHz */ +}; + +#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */ diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h index 5c437c2ba6b3..20e0c2b155dd 100644 --- a/arch/mips/include/asm/mach-loongson1/loongson1.h +++ b/arch/mips/include/asm/mach-loongson1/loongson1.h @@ -16,6 +16,7 @@ #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ /* Loongson 1 Register Bases */ +#define LS1X_MUX_BASE 0x1fd00420 #define LS1X_INTC_BASE 0x1fd01040 #define LS1X_EHCI_BASE 0x1fe00000 #define LS1X_OHCI_BASE 0x1fe08000 @@ -31,7 +32,10 @@ #define LS1X_I2C0_BASE 0x1fe58000 #define LS1X_I2C1_BASE 0x1fe68000 #define LS1X_I2C2_BASE 0x1fe70000 -#define LS1X_PWM_BASE 0x1fe5c000 +#define LS1X_PWM0_BASE 0x1fe5c000 +#define LS1X_PWM1_BASE 0x1fe5c010 +#define LS1X_PWM2_BASE 0x1fe5c020 +#define LS1X_PWM3_BASE 0x1fe5c030 #define LS1X_WDT_BASE 0x1fe5c060 #define LS1X_RTC_BASE 0x1fe64000 #define LS1X_AC97_BASE 0x1fe74000 @@ -39,6 +43,8 @@ #define LS1X_CLK_BASE 0x1fe78030 #include +#include +#include #include #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h index 30c13e508fff..47de55e0c835 100644 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ b/arch/mips/include/asm/mach-loongson1/platform.h @@ -13,10 +13,12 @@ #include -extern struct platform_device ls1x_uart_device; -extern struct platform_device ls1x_eth0_device; -extern struct platform_device ls1x_ehci_device; -extern struct platform_device ls1x_rtc_device; +extern struct platform_device ls1x_uart_pdev; +extern struct platform_device ls1x_cpufreq_pdev; +extern struct platform_device ls1x_eth0_pdev; +extern struct platform_device ls1x_eth1_pdev; +extern struct platform_device ls1x_ehci_pdev; +extern struct platform_device ls1x_rtc_pdev; extern void __init ls1x_clk_init(void); extern void __init ls1x_serial_setup(struct platform_device *pdev); diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h index fb6a3ff9318f..ee2445b10fc3 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h @@ -20,15 +20,32 @@ /* Clock PLL Divisor Register Bits */ #define DIV_DC_EN (0x1 << 31) +#define DIV_DC_RST (0x1 << 30) #define DIV_CPU_EN (0x1 << 25) +#define DIV_CPU_RST (0x1 << 24) #define DIV_DDR_EN (0x1 << 19) +#define DIV_DDR_RST (0x1 << 18) +#define RST_DC_EN (0x1 << 5) +#define RST_DC (0x1 << 4) +#define RST_DDR_EN (0x1 << 3) +#define RST_DDR (0x1 << 2) +#define RST_CPU_EN (0x1 << 1) +#define RST_CPU 0x1 #define DIV_DC_SHIFT 26 #define DIV_CPU_SHIFT 20 #define DIV_DDR_SHIFT 14 -#define DIV_DC_WIDTH 5 -#define DIV_CPU_WIDTH 5 -#define DIV_DDR_WIDTH 5 +#define DIV_DC_WIDTH 4 +#define DIV_CPU_WIDTH 4 +#define DIV_DDR_WIDTH 4 + +#define BYPASS_DC_SHIFT 12 +#define BYPASS_DDR_SHIFT 10 +#define BYPASS_CPU_SHIFT 8 + +#define BYPASS_DC_WIDTH 1 +#define BYPASS_DDR_WIDTH 1 +#define BYPASS_CPU_WIDTH 1 #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h new file mode 100644 index 000000000000..fb1e36efaa19 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-mux.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 MUX Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H +#define __ASM_MACH_LOONGSON1_REGS_MUX_H + +#define LS1X_MUX_REG(x) \ + ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) + +#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) +#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) + +/* MUX CTRL0 Register Bits */ +#define UART0_USE_PWM23 (0x1 << 28) +#define UART0_USE_PWM01 (0x1 << 27) +#define UART1_USE_LCD0_5_6_11 (0x1 << 26) +#define I2C2_USE_CAN1 (0x1 << 25) +#define I2C1_USE_CAN0 (0x1 << 24) +#define NAND3_USE_UART5 (0x1 << 23) +#define NAND3_USE_UART4 (0x1 << 22) +#define NAND3_USE_UART1_DAT (0x1 << 21) +#define NAND3_USE_UART1_CTS (0x1 << 20) +#define NAND3_USE_PWM23 (0x1 << 19) +#define NAND3_USE_PWM01 (0x1 << 18) +#define NAND2_USE_UART5 (0x1 << 17) +#define NAND2_USE_UART4 (0x1 << 16) +#define NAND2_USE_UART1_DAT (0x1 << 15) +#define NAND2_USE_UART1_CTS (0x1 << 14) +#define NAND2_USE_PWM23 (0x1 << 13) +#define NAND2_USE_PWM01 (0x1 << 12) +#define NAND1_USE_UART5 (0x1 << 11) +#define NAND1_USE_UART4 (0x1 << 10) +#define NAND1_USE_UART1_DAT (0x1 << 9) +#define NAND1_USE_UART1_CTS (0x1 << 8) +#define NAND1_USE_PWM23 (0x1 << 7) +#define NAND1_USE_PWM01 (0x1 << 6) +#define GMAC1_USE_UART1 (0x1 << 4) +#define GMAC1_USE_UART0 (0x1 << 3) +#define LCD_USE_UART0_DAT (0x1 << 2) +#define LCD_USE_UART15 (0x1 << 1) +#define LCD_USE_UART0 0x1 + +/* MUX CTRL1 Register Bits */ +#define USB_RESET (0x1 << 31) +#define SPI1_CS_USE_PWM01 (0x1 << 24) +#define SPI1_USE_CAN (0x1 << 23) +#define DISABLE_DDR_CONFSPACE (0x1 << 20) +#define DDR32TO16EN (0x1 << 16) +#define GMAC1_SHUT (0x1 << 13) +#define GMAC0_SHUT (0x1 << 12) +#define USB_SHUT (0x1 << 11) +#define UART1_3_USE_CAN1 (0x1 << 5) +#define UART1_2_USE_CAN0 (0x1 << 4) +#define GMAC1_USE_TXCLK (0x1 << 3) +#define GMAC0_USE_TXCLK (0x1 << 2) +#define GMAC1_USE_PWM23 (0x1 << 1) +#define GMAC0_USE_PWM01 0x1 + +#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h new file mode 100644 index 000000000000..99f2bcc586f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-pwm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * Loongson 1 PWM Register Definitions. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H +#define __ASM_MACH_LOONGSON1_REGS_PWM_H + +/* Loongson 1 PWM Timer Register Definitions */ +#define PWM_CNT 0x0 +#define PWM_HRC 0x4 +#define PWM_LRC 0x8 +#define PWM_CTRL 0xc + +/* PWM Control Register Bits */ +#define CNT_RST (0x1 << 7) +#define INT_SR (0x1 << 6) +#define INT_EN (0x1 << 5) +#define PWM_SINGLE (0x1 << 4) +#define PWM_OE (0x1 << 3) +#define CNT_EN 0x1 + +#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */ diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index fdf8cb5987a4..ddf1d4cbf31e 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c @@ -16,8 +16,10 @@ #include #include +#include #include +/* 8250/16550 compatible UART */ #define LS1X_UART(_id) \ { \ .mapbase = LS1X_UART ## _id ## _BASE, \ @@ -27,7 +29,7 @@ .type = PORT_16550A, \ } -static struct plat_serial8250_port ls1x_serial8250_port[] = { +static struct plat_serial8250_port ls1x_serial8250_pdata[] = { LS1X_UART(0), LS1X_UART(1), LS1X_UART(2), @@ -35,11 +37,11 @@ static struct plat_serial8250_port ls1x_serial8250_port[] = { {}, }; -struct platform_device ls1x_uart_device = { +struct platform_device ls1x_uart_pdev = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, .dev = { - .platform_data = ls1x_serial8250_port, + .platform_data = ls1x_serial8250_pdata, }, }; @@ -48,16 +50,97 @@ void __init ls1x_serial_setup(struct platform_device *pdev) struct clk *clk; struct plat_serial8250_port *p; - clk = clk_get(NULL, pdev->name); - if (IS_ERR(clk)) - panic("unable to get %s clock, err=%ld", - pdev->name, PTR_ERR(clk)); + clk = clk_get(&pdev->dev, pdev->name); + if (IS_ERR(clk)) { + pr_err("unable to get %s clock, err=%ld", + pdev->name, PTR_ERR(clk)); + return; + } + clk_prepare_enable(clk); for (p = pdev->dev.platform_data; p->flags != 0; ++p) p->uartclk = clk_get_rate(clk); } +/* CPUFreq */ +static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { + .clk_name = "cpu_clk", + .osc_clk_name = "osc_33m_clk", + .max_freq = 266 * 1000, + .min_freq = 33 * 1000, +}; + +struct platform_device ls1x_cpufreq_pdev = { + .name = "ls1x-cpufreq", + .dev = { + .platform_data = &ls1x_cpufreq_pdata, + }, +}; + /* Synopsys Ethernet GMAC */ +static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { + .phy_mask = 0, +}; + +static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { + .pbl = 1, +}; + +int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) +{ + struct plat_stmmacenet_data *plat_dat = NULL; + u32 val; + + val = __raw_readl(LS1X_MUX_CTRL1); + + plat_dat = dev_get_platdata(&pdev->dev); + if (plat_dat->bus_id) { + __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | + GMAC1_USE_UART0, LS1X_MUX_CTRL0); + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC1_SHUT; + } else { + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC0_SHUT; + } + __raw_writel(val, LS1X_MUX_CTRL1); + + return 0; +} + +static struct plat_stmmacenet_data ls1x_eth0_pdata = { + .bus_id = 0, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .init = ls1x_eth_mux_init, +}; + static struct resource ls1x_eth0_resources[] = { [0] = { .start = LS1X_GMAC0_BASE, @@ -71,25 +154,47 @@ static struct resource ls1x_eth0_resources[] = { }, }; -static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { - .phy_mask = 0, +struct platform_device ls1x_eth0_pdev = { + .name = "stmmaceth", + .id = 0, + .num_resources = ARRAY_SIZE(ls1x_eth0_resources), + .resource = ls1x_eth0_resources, + .dev = { + .platform_data = &ls1x_eth0_pdata, + }, }; -static struct plat_stmmacenet_data ls1x_eth_data = { - .bus_id = 0, +static struct plat_stmmacenet_data ls1x_eth1_pdata = { + .bus_id = 1, .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, .has_gmac = 1, .tx_coe = 1, + .init = ls1x_eth_mux_init, }; -struct platform_device ls1x_eth0_device = { +static struct resource ls1x_eth1_resources[] = { + [0] = { + .start = LS1X_GMAC1_BASE, + .end = LS1X_GMAC1_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "macirq", + .start = LS1X_GMAC1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ls1x_eth1_pdev = { .name = "stmmaceth", - .id = 0, - .num_resources = ARRAY_SIZE(ls1x_eth0_resources), - .resource = ls1x_eth0_resources, + .id = 1, + .num_resources = ARRAY_SIZE(ls1x_eth1_resources), + .resource = ls1x_eth1_resources, .dev = { - .platform_data = &ls1x_eth_data, + .platform_data = &ls1x_eth1_pdata, }, }; @@ -111,7 +216,7 @@ static struct resource ls1x_ehci_resources[] = { static struct usb_ehci_pdata ls1x_ehci_pdata = { }; -struct platform_device ls1x_ehci_device = { +struct platform_device ls1x_ehci_pdev = { .name = "ehci-platform", .id = -1, .num_resources = ARRAY_SIZE(ls1x_ehci_resources), @@ -123,7 +228,7 @@ struct platform_device ls1x_ehci_device = { }; /* Real Time Clock */ -struct platform_device ls1x_rtc_device = { +struct platform_device ls1x_rtc_pdev = { .name = "ls1x-rtc", .id = -1, }; diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c index b26b10dac70a..58daeea25739 100644 --- a/arch/mips/loongson1/ls1b/board.c +++ b/arch/mips/loongson1/ls1b/board.c @@ -10,17 +10,19 @@ #include static struct platform_device *ls1b_platform_devices[] __initdata = { - &ls1x_uart_device, - &ls1x_eth0_device, - &ls1x_ehci_device, - &ls1x_rtc_device, + &ls1x_uart_pdev, + &ls1x_cpufreq_pdev, + &ls1x_eth0_pdev, + &ls1x_eth1_pdev, + &ls1x_ehci_pdev, + &ls1x_rtc_pdev, }; static int __init ls1b_platform_init(void) { int err; - ls1x_serial_setup(&ls1x_uart_device); + ls1x_serial_setup(&ls1x_uart_pdev); err = platform_add_devices(ls1b_platform_devices, ARRAY_SIZE(ls1b_platform_devices)); -- GitLab From c5d58e9e79dd8d687454915fc4e845434f973175 Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Fri, 10 Oct 2014 11:40:02 +0800 Subject: [PATCH 6013/9457] MIPS: Loongson1B: Add a clockevent/clocksource using PWM Timer This patch add a clockevent/clocksource using PWM Timer for Loongson1B, which is based on earlier work by Tang, Haifeng. Signed-off-by: Kelvin Cheung Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8025/ Signed-off-by: Ralf Baechle --- arch/mips/loongson1/Kconfig | 41 ++++- arch/mips/loongson1/common/Makefile | 2 +- arch/mips/loongson1/common/clock.c | 28 ---- arch/mips/loongson1/common/time.c | 226 ++++++++++++++++++++++++++++ 4 files changed, 266 insertions(+), 31 deletions(-) delete mode 100644 arch/mips/loongson1/common/clock.c create mode 100644 arch/mips/loongson1/common/time.c diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index 4ed9744fe051..a2b796eaf3c3 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig @@ -5,8 +5,8 @@ choice config LOONGSON1_LS1B bool "Loongson LS1B board" - select CEVT_R4K - select CSRC_R4K + select CEVT_R4K if !MIPS_EXTERNAL_TIMER + select CSRC_R4K if !MIPS_EXTERNAL_TIMER select SYS_HAS_CPU_LOONGSON1B select DMA_NONCOHERENT select BOOT_ELF32 @@ -21,4 +21,41 @@ config LOONGSON1_LS1B endchoice +menuconfig CEVT_CSRC_LS1X + bool "Use PWM Timer for clockevent/clocksource" + select MIPS_EXTERNAL_TIMER + depends on CPU_LOONGSON1 + help + This option changes the default clockevent/clocksource to PWM Timer, + and is required by Loongson1 CPUFreq support. + + If unsure, say N. + +choice + prompt "Select clockevent/clocksource" + depends on CEVT_CSRC_LS1X + default TIMER_USE_PWM0 + +config TIMER_USE_PWM0 + bool "Use PWM Timer 0" + help + Use PWM Timer 0 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM1 + bool "Use PWM Timer 1" + help + Use PWM Timer 1 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM2 + bool "Use PWM Timer 2" + help + Use PWM Timer 2 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM3 + bool "Use PWM Timer 3" + help + Use PWM Timer 3 as the default clockevent/clocksourcer. + +endchoice + endif # MACH_LOONGSON1 diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile index b2797709ef5b..723b4ce3b8f0 100644 --- a/arch/mips/loongson1/common/Makefile +++ b/arch/mips/loongson1/common/Makefile @@ -2,4 +2,4 @@ # Makefile for common code of loongson1 based machines. # -obj-y += clock.o irq.o platform.o prom.o reset.o setup.o +obj-y += time.o irq.o platform.o prom.o reset.o setup.o diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c deleted file mode 100644 index b4437f19c3d9..000000000000 --- a/arch/mips/loongson1/common/clock.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include - -void __init plat_time_init(void) -{ - struct clk *clk; - - /* Initialize LS1X clocks */ - ls1x_clk_init(); - - /* setup mips r4k timer */ - clk = clk_get(NULL, "cpu"); - if (IS_ERR(clk)) - panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); - - mips_hpt_frequency = clk_get_rate(clk) / 2; -} diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c new file mode 100644 index 000000000000..df0f850d6a5f --- /dev/null +++ b/arch/mips/loongson1/common/time.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include + +#ifdef CONFIG_CEVT_CSRC_LS1X + +#if defined(CONFIG_TIMER_USE_PWM1) +#define LS1X_TIMER_BASE LS1X_PWM1_BASE +#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM2) +#define LS1X_TIMER_BASE LS1X_PWM2_BASE +#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM3) +#define LS1X_TIMER_BASE LS1X_PWM3_BASE +#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ + +#else +#define LS1X_TIMER_BASE LS1X_PWM0_BASE +#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ +#endif + +DEFINE_RAW_SPINLOCK(ls1x_timer_lock); + +static void __iomem *timer_base; +static uint32_t ls1x_jiffies_per_tick; + +static inline void ls1x_pwmtimer_set_period(uint32_t period) +{ + __raw_writel(period, timer_base + PWM_HRC); + __raw_writel(period, timer_base + PWM_LRC); +} + +static inline void ls1x_pwmtimer_restart(void) +{ + __raw_writel(0x0, timer_base + PWM_CNT); + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); +} + +void __init ls1x_pwmtimer_init(void) +{ + timer_base = ioremap(LS1X_TIMER_BASE, 0xf); + if (!timer_base) + panic("Failed to remap timer registers"); + + ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); + + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); +} + +static cycle_t ls1x_clocksource_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + raw_spin_lock_irqsave(&ls1x_timer_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = __raw_readl(timer_base + PWM_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); + + return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; +} + +static struct clocksource ls1x_clocksource = { + .name = "ls1x-pwmtimer", + .read = ls1x_clocksource_read, + .mask = CLOCKSOURCE_MASK(24), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) +{ + struct clock_event_device *cd = devid; + + ls1x_pwmtimer_restart(); + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static void ls1x_clockevent_set_mode(enum clock_event_mode mode, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); + case CLOCK_EVT_MODE_RESUME: + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, + timer_base + PWM_CTRL); + break; + default: + break; + } + raw_spin_unlock(&ls1x_timer_lock); +} + +static int ls1x_clockevent_set_next(unsigned long evt, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + ls1x_pwmtimer_set_period(evt); + ls1x_pwmtimer_restart(); + raw_spin_unlock(&ls1x_timer_lock); + + return 0; +} + +static struct clock_event_device ls1x_clockevent = { + .name = "ls1x-pwmtimer", + .features = CLOCK_EVT_FEAT_PERIODIC, + .rating = 300, + .irq = LS1X_TIMER_IRQ, + .set_next_event = ls1x_clockevent_set_next, + .set_mode = ls1x_clockevent_set_mode, +}; + +static struct irqaction ls1x_pwmtimer_irqaction = { + .name = "ls1x-pwmtimer", + .handler = ls1x_clockevent_isr, + .dev_id = &ls1x_clockevent, + .flags = IRQF_PERCPU | IRQF_TIMER, +}; + +static void __init ls1x_time_init(void) +{ + struct clock_event_device *cd = &ls1x_clockevent; + int ret; + + if (!mips_hpt_frequency) + panic("Invalid timer clock rate"); + + ls1x_pwmtimer_init(); + + clockevent_set_clock(cd, mips_hpt_frequency); + cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); + cd->cpumask = cpumask_of(smp_processor_id()); + clockevents_register_device(cd); + + ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; + ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); + if (ret) + panic(KERN_ERR "Failed to register clocksource: %d\n", ret); + + setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); +} +#endif /* CONFIG_CEVT_CSRC_LS1X */ + +void __init plat_time_init(void) +{ + struct clk *clk = NULL; + + /* initialize LS1X clocks */ + ls1x_clk_init(); + +#ifdef CONFIG_CEVT_CSRC_LS1X + /* setup LS1X PWM timer */ + clk = clk_get(NULL, "ls1x_pwmtimer"); + if (IS_ERR(clk)) + panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk); + ls1x_time_init(); +#else + /* setup mips r4k timer */ + clk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(clk)) + panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk) / 2; +#endif /* CONFIG_CEVT_CSRC_LS1X */ +} -- GitLab From 3526f74fa925e44335b94ed0c9f93648e26058ef Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Fri, 10 Oct 2014 11:42:51 +0800 Subject: [PATCH 6014/9457] clk: ls1x: Update relationship among all clocks - Add clock lookups for APB devices. - Update clock relationship to make it more exact and clear. _____ _______________________| | OSC ___/ | MUX |___ XXX CLK \___ PLL ___ XXX DIV ___| | |_____| Signed-off-by: Kelvin Cheung Cc: linux-kernel@vger.kernel.org Cc: mturquette@linaro.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8026/ Signed-off-by: Ralf Baechle --- drivers/clk/clk-ls1x.c | 109 ++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c index f20b750235f6..ca80103ac188 100644 --- a/drivers/clk/clk-ls1x.c +++ b/drivers/clk/clk-ls1x.c @@ -15,7 +15,8 @@ #include -#define OSC 33 +#define OSC (33 * 1000000) +#define DIV_APB 2 static DEFINE_SPINLOCK(_lock); @@ -29,13 +30,12 @@ static void ls1x_pll_clk_disable(struct clk_hw *hw) } static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) + unsigned long parent_rate) { u32 pll, rate; pll = __raw_readl(LS1X_CLK_PLL_FREQ); - rate = ((12 + (pll & 0x3f)) * 1000000) + - ((((pll >> 8) & 0x3ff) * 1000000) >> 10); + rate = 12 + (pll & 0x3f) + (((pll >> 8) & 0x3ff) >> 10); rate *= OSC; rate >>= 1; @@ -48,8 +48,10 @@ static const struct clk_ops ls1x_pll_clk_ops = { .recalc_rate = ls1x_pll_recalc_rate, }; -static struct clk * __init clk_register_pll(struct device *dev, - const char *name, const char *parent_name, unsigned long flags) +static struct clk *__init clk_register_pll(struct device *dev, + const char *name, + const char *parent_name, + unsigned long flags) { struct clk_hw *hw; struct clk *clk; @@ -78,34 +80,83 @@ static struct clk * __init clk_register_pll(struct device *dev, return clk; } +static const char const *cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; +static const char const *ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", }; +static const char const *dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; + void __init ls1x_clk_init(void) { struct clk *clk; - clk = clk_register_pll(NULL, "pll_clk", NULL, CLK_IS_ROOT); - clk_prepare_enable(clk); - - clk = clk_register_divider(NULL, "cpu_clk", "pll_clk", - CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_CPU_SHIFT, - DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_prepare_enable(clk); - clk_register_clkdev(clk, "cpu", NULL); - - clk = clk_register_divider(NULL, "dc_clk", "pll_clk", - CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, - DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_prepare_enable(clk); - clk_register_clkdev(clk, "dc", NULL); - - clk = clk_register_divider(NULL, "ahb_clk", "pll_clk", - CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, - DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_prepare_enable(clk); - clk_register_clkdev(clk, "ahb", NULL); + clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, CLK_IS_ROOT, + OSC); + clk_register_clkdev(clk, "osc_33m_clk", NULL); + + /* clock derived from 33 MHz OSC clk */ + clk = clk_register_pll(NULL, "pll_clk", "osc_33m_clk", 0); + clk_register_clkdev(clk, "pll_clk", NULL); + + /* clock derived from PLL clk */ + /* _____ + * _______________________| | + * OSC ___/ | MUX |___ CPU CLK + * \___ PLL ___ CPU DIV ___| | + * |_____| + */ + clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk", + CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV, + DIV_CPU_SHIFT, DIV_CPU_WIDTH, + CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ROUND_CLOSEST, &_lock); + clk_register_clkdev(clk, "cpu_clk_div", NULL); + clk = clk_register_mux(NULL, "cpu_clk", cpu_parents, + ARRAY_SIZE(cpu_parents), + CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock); + clk_register_clkdev(clk, "cpu_clk", NULL); + + /* _____ + * _______________________| | + * OSC ___/ | MUX |___ DC CLK + * \___ PLL ___ DC DIV ___| | + * |_____| + */ + clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk", + 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, + DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); + clk_register_clkdev(clk, "dc_clk_div", NULL); + clk = clk_register_mux(NULL, "dc_clk", dc_parents, + ARRAY_SIZE(dc_parents), + CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock); + clk_register_clkdev(clk, "dc_clk", NULL); + + /* _____ + * _______________________| | + * OSC ___/ | MUX |___ DDR CLK + * \___ PLL ___ DDR DIV ___| | + * |_____| + */ + clk = clk_register_divider(NULL, "ahb_clk_div", "pll_clk", + 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, + DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, + &_lock); + clk_register_clkdev(clk, "ahb_clk_div", NULL); + clk = clk_register_mux(NULL, "ahb_clk", ahb_parents, + ARRAY_SIZE(ahb_parents), + CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock); + clk_register_clkdev(clk, "ahb_clk", NULL); clk_register_clkdev(clk, "stmmaceth", NULL); - clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, 2); - clk_prepare_enable(clk); - clk_register_clkdev(clk, "apb", NULL); + /* clock derived from AHB clk */ + /* APB clk is always half of the AHB clk */ + clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, + DIV_APB); + clk_register_clkdev(clk, "apb_clk", NULL); + clk_register_clkdev(clk, "ls1x_i2c", NULL); + clk_register_clkdev(clk, "ls1x_pwmtimer", NULL); + clk_register_clkdev(clk, "ls1x_spi", NULL); + clk_register_clkdev(clk, "ls1x_wdt", NULL); clk_register_clkdev(clk, "serial8250", NULL); } -- GitLab From bdb2e05c900d0c2a14605411dc054f284241d42e Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:52 -0700 Subject: [PATCH 6015/9457] MIPS: BMIPS: Align secondary boot sequence with latest firmware releases On some older BMIPS5200 (dual core / quad thread) platforms, the PROM code set up CPU2/CPU3 so they would be started through an NMI instead of through the ACTION register. But this was incompatible with some power management features that were later added, so the scheme was changed so that Linux is fully responsible for booting CPU2/CPU3. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8157/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-bmips.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 06bb5ed6d80a..4e569113ff56 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -213,17 +213,7 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) set_c0_brcm_cmt_ctrl(0x01); break; case CPU_BMIPS5000: - if (cpu & 0x01) - write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); - else { - /* - * core N thread 0 was already booted; just - * pulse the NMI line - */ - bmips_write_zscm_reg(0x210, 0xc0000000); - udelay(10); - bmips_write_zscm_reg(0x210, 0x00); - } + write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); break; } cpumask_set_cpu(cpu, &bmips_booted_mask); -- GitLab From fc4557879320de99766061a38aaa345c0f72eb31 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:53 -0700 Subject: [PATCH 6016/9457] MIPS: BMIPS: Introduce helper function to change the reset vector This will need to be called from a few different places, and the logic is starting to get a bit hairy (with the need for IPIs, CPU bug workarounds, and hazards). Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8158/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-bmips.c | 65 ++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 4e569113ff56..8383fa460d42 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -35,6 +35,7 @@ #include #include #include +#include static int __maybe_unused max_cpus = 1; @@ -43,6 +44,9 @@ int bmips_smp_enabled = 1; int bmips_cpu_offset; cpumask_t bmips_booted_mask; +#define RESET_FROM_KSEG0 0x80080800 +#define RESET_FROM_KSEG1 0xa0080800 + #ifdef CONFIG_SMP /* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */ @@ -463,10 +467,61 @@ static inline void bmips_nmi_handler_setup(void) &bmips_smp_int_vec_end); } +struct reset_vec_info { + int cpu; + u32 val; +}; + +static void bmips_set_reset_vec_remote(void *vinfo) +{ + struct reset_vec_info *info = vinfo; + int shift = info->cpu & 0x01 ? 16 : 0; + u32 mask = ~(0xffff << shift), val = info->val >> 16; + + preempt_disable(); + if (smp_processor_id() > 0) { + smp_call_function_single(0, &bmips_set_reset_vec_remote, + info, 1); + } else { + if (info->cpu & 0x02) { + /* BMIPS5200 "should" use mask/shift, but it's buggy */ + bmips_write_zscm_reg(0xa0, (val << 16) | val); + bmips_read_zscm_reg(0xa0); + } else { + write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) | + (val << shift)); + } + } + preempt_enable(); +} + +static void bmips_set_reset_vec(int cpu, u32 val) +{ + struct reset_vec_info info; + + if (current_cpu_type() == CPU_BMIPS5000) { + /* this needs to run from CPU0 (which is always online) */ + info.cpu = cpu; + info.val = val; + bmips_set_reset_vec_remote(&info); + } else { + void __iomem *cbr = BMIPS_GET_CBR(); + + if (cpu == 0) + __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0); + else { + if (current_cpu_type() != CPU_BMIPS4380) + return; + __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1); + } + } + __sync(); + back_to_back_c0_hazard(); +} + void bmips_ebase_setup(void) { unsigned long new_ebase = ebase; - void __iomem __maybe_unused *cbr; BUG_ON(ebase != CKSEG0); @@ -492,9 +547,7 @@ void bmips_ebase_setup(void) * 0x8000_0400: normal vectors */ new_ebase = 0x80000400; - cbr = BMIPS_GET_CBR(); - __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0); - __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1); + bmips_set_reset_vec(0, RESET_FROM_KSEG0); break; case CPU_BMIPS5000: /* @@ -502,10 +555,8 @@ void bmips_ebase_setup(void) * 0x8000_1000: normal vectors */ new_ebase = 0x80001000; - write_c0_brcm_bootvec(0xa0088008); + bmips_set_reset_vec(0, RESET_FROM_KSEG0); write_c0_ebase(new_ebase); - if (max_cpus > 2) - bmips_write_zscm_reg(0xa0, 0xa008a008); break; default: return; -- GitLab From fa0106725923eba6497a7348424c97038a571ad9 Mon Sep 17 00:00:00 2001 From: Jon Fraser Date: Mon, 20 Oct 2014 21:27:54 -0700 Subject: [PATCH 6017/9457] MIPS: BMIPS: Allow BMIPS3300 to utilize SMP ebase relocation code BMIPS3300 processors do not have the hardware to support SMP, but with a small tweak, the SMP ebase relocation code allows BMIPS3300-based platforms to reuse the S2/S3 power management code from BMIPS4380-based chips. Normally this is as simple as adding one line to prom_init(): board_ebase_setup = &bmips_ebase_setup; Signed-off-by: Jon Fraser Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8159/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-bmips.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 8383fa460d42..887c3ea0ed57 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -541,6 +541,7 @@ void bmips_ebase_setup(void) &bmips_smp_int_vec, 0x80); __sync(); return; + case CPU_BMIPS3300: case CPU_BMIPS4380: /* * 0x8000_0000: reset/NMI (initially in kseg1) -- GitLab From 230b6ff57552c23a03e1b8d3f4a401261ca981c7 Mon Sep 17 00:00:00 2001 From: Jon Fraser Date: Mon, 20 Oct 2014 21:27:55 -0700 Subject: [PATCH 6018/9457] MIPS: BMIPS: Mask off timer IRQs when hot-unplugging a CPU CPU interrupts need to be disabled on a cpu being taken down. When a cpu is hot-plugged out of the system the following sequence occurs. On the CPU where the hotplug sequence was initiated: cpu_down _cpu_down { __cpu_notify(CPU_DOWN_PREPARE __stop_machine(take_cpu_down wait for cpu to run disable code. __cpu_die } On the CPU being disabled: take_cpu_down __cpu_disable { mp_ops->cpu_disable bmips_cpu_disable clear_c0_status(IE_IRQ5) (added) cpu_notify(CPU_DYING... } Before the cpu_notifier is called with CPU_DYING, all interrupts on the dying cpu must be disabled. This guarantees that before tick_notify is called with the CPU_DYING event and sets the clock device pointer to NULL, there can not be any more clock interrupts. When this wasn't done, an unfortunately-timed timer interrupt sometimes caused hangs immediately prior to system suspend: Debug PM is not enabled. To enable partial suspend, rebuild kernel with CONFIG_PM_DEBUG Pass 1 out of 1,PM: Syncing filesystems ... mode=none, tp1=done. 1, flags=5, cycle_tp=, sleep= Freezing user space processes ... (elapsed 0.01 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. PM: suspend of devices complete after 54.199 msecs PM: late suspend of devices complete after 0.172 msecs Disabling non-boot CPUs ... SMP: CPU1 is offline INFO: rcu_sched detected stalls on CPUs/tasks: { 3} (detected by 0, t=62537 jiffies) Call Trace: [<804baa78>] dump_stack+0x8/0x34 [<8008a2d8>] __rcu_pending+0x4b8/0x55c [<8008adf4>] rcu_check_callbacks+0x78/0x180 [<80037830>] update_process_times+0x40/0x6c [<80072fe4>] tick_sched_timer+0x74/0xe4 [<80050180>] __run_hrtimer.clone.30+0x64/0x140 [<80051150>] hrtimer_interrupt+0x19c/0x4bc [<8000cdb8>] c0_compare_interrupt+0x50/0x88 [<80081b18>] handle_irq_event_percpu+0x5c/0x2f4 [<80086490>] handle_percpu_irq+0x8c/0xc0 [<800811b4>] generic_handle_irq+0x34/0x54 [<800067dc>] do_IRQ+0x18/0x2c [<8000375c>] plat_irq_dispatch+0xd0/0x128 [<80004a04>] ret_from_irq+0x0/0x4 [<80004c40>] r4k_wait+0x20/0x40 [<80006b6c>] cpu_idle+0x98/0xf0 [<805d3988>] start_kernel+0x424/0x440 Signed-off-by: Jon Fraser Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8160/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-bmips.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 887c3ea0ed57..f7b1beef7790 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -375,6 +375,7 @@ static int bmips_cpu_disable(void) set_cpu_online(cpu, false); cpu_clear(cpu, cpu_callin_map); + clear_c0_status(IE_IRQ5); local_flush_tlb_all(); local_flush_icache_range(0, ~0); -- GitLab From 3677a283621446805044a73a36b3539a0b41bc12 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:56 -0700 Subject: [PATCH 6019/9457] MIPS: BMIPS: Explicitly configure reset vectors prior to secondary boot The secondary CPU's reset vector needs to be set to KSEG1 for a cold boot (release from reset), or KSEG0 for a warm restart. On a cold boot KSEG0 may be unavailable (BMIPS4380), and on a warm restart KSEG1 may be unavailable (XKS01 mode on 4380 or 5000). Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8161/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-bmips.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index f7b1beef7790..162391d548b5 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -47,6 +47,8 @@ cpumask_t bmips_booted_mask; #define RESET_FROM_KSEG0 0x80080800 #define RESET_FROM_KSEG1 0xa0080800 +static void bmips_set_reset_vec(int cpu, u32 val); + #ifdef CONFIG_SMP /* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */ @@ -198,6 +200,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) pr_info("SMP: Booting CPU%d...\n", cpu); if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { + /* kseg1 might not exist if this CPU enabled XKS01 */ + bmips_set_reset_vec(cpu, RESET_FROM_KSEG0); + switch (current_cpu_type()) { case CPU_BMIPS4350: case CPU_BMIPS4380: @@ -207,8 +212,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) bmips5000_send_ipi_single(cpu, 0); break; } - } - else { + } else { + bmips_set_reset_vec(cpu, RESET_FROM_KSEG1); + switch (current_cpu_type()) { case CPU_BMIPS4350: case CPU_BMIPS4380: @@ -229,31 +235,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) */ static void bmips_init_secondary(void) { - /* move NMI vector to kseg0, in case XKS01 is enabled */ - - void __iomem *cbr; - unsigned long old_vec; - unsigned long relo_vector; - int boot_cpu; - switch (current_cpu_type()) { case CPU_BMIPS4350: case CPU_BMIPS4380: - cbr = BMIPS_GET_CBR(); - - boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); - relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 : - BMIPS_RELO_VECTOR_CONTROL_1; - - old_vec = __raw_readl(cbr + relo_vector); - __raw_writel(old_vec & ~0x20000000, cbr + relo_vector); - clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); break; case CPU_BMIPS5000: - write_c0_brcm_bootvec(read_c0_brcm_bootvec() & - (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000)); - write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); break; } -- GitLab From a7ef1eaddbf4bd50bfee92d9dfbecadc61467bbf Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:57 -0700 Subject: [PATCH 6020/9457] MIPS: Allow MIPS_CPU_SCACHE to be used with different line sizes CONFIG_MIPS_CPU_SCACHE determines whether to build sc-mips.c. However, it is currently hardwired to use an L1_SHIFT of 6 (64 bytes). Move the L1_SHIFT selection into the CPU or SoC section so that other SoCs can select different values. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8162/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9ea76ed1c2e4..992f98361e5a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -327,6 +327,7 @@ config MIPS_MALTA select I8259 select MIPS_BONITO64 select MIPS_CPU_SCACHE + select MIPS_L1_CACHE_SHIFT_6 select PCI_GT64XXX_PCI0 select MIPS_MSC select SWAP_IO_SPACE @@ -1908,7 +1909,6 @@ config IP22_CPU_SCACHE config MIPS_CPU_SCACHE bool select BOARD_SCACHE - select MIPS_L1_CACHE_SHIFT_6 config R5000_CPU_SCACHE bool -- GitLab From bbf2ba67cdbdb3676a661c3eba5572d1e513627f Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:58 -0700 Subject: [PATCH 6021/9457] MIPS: BMIPS: Select the appropriate L1_CACHE_SHIFT for 438x and 5000 CPUs BMIPS438x has a 64-byte D$ line size and BMIPS5000 has a 128-byte L2 line size. If L1_CACHE_SHIFT is undersized, DMA buffers will not be cacheline-aligned and terrible things will happen. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8164/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 992f98361e5a..002cf4c56ebf 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1587,12 +1587,14 @@ config CPU_BMIPS4350 config CPU_BMIPS4380 bool + select MIPS_L1_CACHE_SHIFT_6 select SYS_SUPPORTS_SMP select SYS_SUPPORTS_HOTPLUG_CPU config CPU_BMIPS5000 bool select MIPS_CPU_SCACHE + select MIPS_L1_CACHE_SHIFT_7 select SYS_SUPPORTS_SMP select SYS_SUPPORTS_HOTPLUG_CPU -- GitLab From d8010ceba66ac8d1953a1fb00ead89f4ee8a76f5 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:27:59 -0700 Subject: [PATCH 6022/9457] MIPS: BMIPS: Let each platform customize the CPU1 IRQ mask On some chips like bcm3384, "other stuff" gets wired up to CPU1's IE_IRQ1 input, generating spurious IRQs. In this case we want the platform code to be able to mask it off. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8163/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bmips.h | 1 + arch/mips/kernel/smp-bmips.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index cbaccebf5065..30939b02e3ff 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h @@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end; extern int bmips_smp_enabled; extern int bmips_cpu_offset; extern cpumask_t bmips_booted_mask; +extern unsigned long bmips_tp1_irqs; extern void bmips_ebase_setup(void); extern asmlinkage void plat_wired_tlb_setup(void); diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 162391d548b5..b8bd9340c9c7 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -43,6 +43,7 @@ static int __maybe_unused max_cpus = 1; int bmips_smp_enabled = 1; int bmips_cpu_offset; cpumask_t bmips_booted_mask; +unsigned long bmips_tp1_irqs = IE_IRQ1; #define RESET_FROM_KSEG0 0x80080800 #define RESET_FROM_KSEG1 0xa0080800 @@ -257,7 +258,7 @@ static void bmips_smp_finish(void) write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); irq_enable_hazard(); - set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); + set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE); irq_enable_hazard(); } @@ -387,7 +388,8 @@ void __ref play_dead(void) * IRQ handlers; this clears ST0_IE and returns immediately. */ clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); - change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, + change_c0_status( + IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); irq_disable_hazard(); -- GitLab From d74b0172e4e2cea34104ba6bdacb3cffe33eaf0f Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:00 -0700 Subject: [PATCH 6023/9457] MIPS: BMIPS: Add special cache handling in c-r4k.c BMIPS435x and BMIPS438x have a single shared L1 D$ and load/store unit, so it isn't necessary to raise IPIs to keep both CPUs coherent. BMIPS5000 has VIPT L1 caches that handle aliases in hardware, and its I$ fills from D$. But a special sequence with 2 SYNCs and 32 NOPs is needed to ensure coherency. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8165/ Signed-off-by: Ralf Baechle --- arch/mips/mm/c-r4k.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fbcd8674ff1d..dd261df005c2 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -917,6 +917,18 @@ static inline void alias_74k_erratum(struct cpuinfo_mips *c) } } +static void b5k_instruction_hazard(void) +{ + __sync(); + __sync(); + __asm__ __volatile__( + " nop; nop; nop; nop; nop; nop; nop; nop\n" + " nop; nop; nop; nop; nop; nop; nop; nop\n" + " nop; nop; nop; nop; nop; nop; nop; nop\n" + " nop; nop; nop; nop; nop; nop; nop; nop\n" + : : : "memory"); +} + static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" }; @@ -1683,6 +1695,37 @@ void r4k_cache_init(void) coherency_setup(); board_cache_error_setup = r4k_cache_error_setup; + + /* + * Per-CPU overrides + */ + switch (current_cpu_type()) { + case CPU_BMIPS4350: + case CPU_BMIPS4380: + /* No IPI is needed because all CPUs share the same D$ */ + flush_data_cache_page = r4k_blast_dcache_page; + break; + case CPU_BMIPS5000: + /* We lose our superpowers if L2 is disabled */ + if (c->scache.flags & MIPS_CACHE_NOT_PRESENT) + break; + + /* I$ fills from D$ just by emptying the write buffers */ + flush_cache_page = (void *)b5k_instruction_hazard; + flush_cache_range = (void *)b5k_instruction_hazard; + flush_cache_sigtramp = (void *)b5k_instruction_hazard; + local_flush_data_cache_page = (void *)b5k_instruction_hazard; + flush_data_cache_page = (void *)b5k_instruction_hazard; + flush_icache_range = (void *)b5k_instruction_hazard; + local_flush_icache_range = (void *)b5k_instruction_hazard; + + /* Cache aliases are handled in hardware; allow HIGHMEM */ + current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES; + + /* Optimization: an L2 flush implicitly flushes the L1 */ + current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; + break; + } } static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, -- GitLab From 68e6a78373a6d3ab6d2811f891596fdd8408efec Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:01 -0700 Subject: [PATCH 6024/9457] MIPS: BMIPS: Add PRId for BMIPS5200 (Whirlwind) This is a dual core (quad thread) BMIPS5000. It needs a little extra code to boot the second core (CPU2/CPU3), but for now we can treat it the same as a single core BMIPS5000. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8166/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/cpu.h | 1 + arch/mips/kernel/cpu-probe.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 11025bfbd8db..33866fce4d63 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -142,6 +142,7 @@ #define PRID_IMP_BMIPS3300_BUG 0x0000 #define PRID_IMP_BMIPS43XX 0xa000 #define PRID_IMP_BMIPS5000 0x5a00 +#define PRID_IMP_BMIPS5200 0x5b00 #define PRID_REV_BMIPS4380_LO 0x0040 #define PRID_REV_BMIPS4380_HI 0x006f diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d68ad96392f8..de8dc4ca1a69 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1087,6 +1087,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) break; } case PRID_IMP_BMIPS5000: + case PRID_IMP_BMIPS5200: c->cputype = CPU_BMIPS5000; __cpu_name[cpu] = "Broadcom BMIPS5000"; set_elf_platform(cpu, "bmips5000"); -- GitLab From 84988c068108c99cf0e7d2391f5bf6bd91e2494c Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:02 -0700 Subject: [PATCH 6025/9457] MIPS: Create a helper function for DT setup A couple of platforms register two buses and call of_platform_populate(). Move this into a common function to reduce duplication. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8167/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/prom.h | 1 + arch/mips/kernel/prom.c | 18 ++++++++++++++++++ arch/mips/lantiq/prom.c | 11 +---------- arch/mips/ralink/of.c | 14 ++------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index a9494c0141fb..eaa26270a5e5 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h @@ -22,6 +22,7 @@ extern void device_tree_init(void); struct boot_param_header; extern void __dt_setup_arch(void *bph); +extern int __dt_register_buses(const char *bus0, const char *bus1); #define dt_setup_arch(sym) \ ({ \ diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 5d39bb85bf35..452d4350ce42 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -54,4 +55,21 @@ void __init __dt_setup_arch(void *bph) mips_set_machine_name(of_flat_dt_get_machine_name()); } + +int __init __dt_register_buses(const char *bus0, const char *bus1) +{ + static struct of_device_id of_ids[3]; + + if (!of_have_populated_dt()) + panic("device tree not present"); + + strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible)); + strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible)); + + if (of_platform_populate(NULL, of_ids, NULL, NULL)) + panic("failed to populate DT"); + + return 0; +} + #endif diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 7447d322d14e..758970e3815b 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -97,16 +97,7 @@ void __init prom_init(void) int __init plat_of_setup(void) { - static struct of_device_id of_ids[3]; - - if (!of_have_populated_dt()) - panic("device tree not present"); - - strlcpy(of_ids[0].compatible, soc_info.compatible, - sizeof(of_ids[0].compatible)); - strncpy(of_ids[1].compatible, "simple-bus", - sizeof(of_ids[1].compatible)); - return of_platform_populate(NULL, of_ids, NULL, NULL); + return __dt_register_buses(soc_info.compatible, "simple-bus"); } arch_initcall(plat_of_setup); diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 7c4598cb6de8..f68115fd98ef 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -74,19 +74,9 @@ void __init plat_mem_setup(void) static int __init plat_of_setup(void) { - static struct of_device_id of_ids[3]; - int len = sizeof(of_ids[0].compatible); + __dt_register_buses(soc_info.compatible, "palmbus"); - if (!of_have_populated_dt()) - panic("device tree not present"); - - strlcpy(of_ids[0].compatible, soc_info.compatible, len); - strlcpy(of_ids[1].compatible, "palmbus", len); - - if (of_platform_populate(NULL, of_ids, NULL, NULL)) - panic("failed to populate DT"); - - /* make sure ithat the reset controller is setup early */ + /* make sure that the reset controller is setup early */ ralink_rst_init(); return 0; -- GitLab From 846deacebfe1c77f6448868ae961c2a6d60e1e45 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:03 -0700 Subject: [PATCH 6026/9457] Documentation: DT: Add entries for BCM3384 and its peripherals This covers the new "brcm,*" devices added in the upcoming bcm3384 commit. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8168/ Signed-off-by: Ralf Baechle --- .../bindings/mips/brcm/bcm3384-intc.txt | 37 +++++++++++++++++++ .../devicetree/bindings/mips/brcm/bmips.txt | 8 ++++ .../devicetree/bindings/mips/brcm/cm-dsl.txt | 11 ++++++ .../devicetree/bindings/mips/brcm/usb.txt | 11 ++++++ 4 files changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt create mode 100644 Documentation/devicetree/bindings/mips/brcm/bmips.txt create mode 100644 Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt create mode 100644 Documentation/devicetree/bindings/mips/brcm/usb.txt diff --git a/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt b/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt new file mode 100644 index 000000000000..d4e0141d3620 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt @@ -0,0 +1,37 @@ +* Interrupt Controller + +Properties: +- compatible: "brcm,bcm3384-intc" + + Compatibility with BCM3384 and possibly other BCM33xx/BCM63xx SoCs. + +- reg: Address/length pairs for each mask/status register set. Length must + be 8. If multiple register sets are specified, the first set will + handle IRQ offsets 0..31, the second set 32..63, and so on. + +- interrupt-controller: This is an interrupt controller. + +- #interrupt-cells: Must be <1>. Just a simple IRQ offset; no level/edge + or polarity configuration is possible with this controller. + +- interrupt-parent: This controller is cascaded from a MIPS CPU HW IRQ, or + from another INTC. + +- interrupts: The IRQ on the parent controller. + +Example: + periph_intc: periph_intc@14e00038 { + compatible = "brcm,bcm3384-intc"; + + /* + * IRQs 0..31: mask reg 0x14e00038, status reg 0x14e0003c + * IRQs 32..63: mask reg 0x14e00340, status reg 0x14e00344 + */ + reg = <0x14e00038 0x8 0x14e00340 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <4>; + }; diff --git a/Documentation/devicetree/bindings/mips/brcm/bmips.txt b/Documentation/devicetree/bindings/mips/brcm/bmips.txt new file mode 100644 index 000000000000..8ef71b4085ca --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/bmips.txt @@ -0,0 +1,8 @@ +* Broadcom MIPS (BMIPS) CPUs + +Required properties: +- compatible: "brcm,bmips3300", "brcm,bmips4350", "brcm,bmips4380", + "brcm,bmips5000" + +- mips-hpt-frequency: This is common to all CPUs in the system so it lives + under the "cpus" node. diff --git a/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt b/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt new file mode 100644 index 000000000000..8a139cb3c0b5 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt @@ -0,0 +1,11 @@ +* Broadcom cable/DSL platforms + +SoCs: + +Required properties: +- compatible: "brcm,bcm3384", "brcm,bcm33843" + +Boards: + +Required properties: +- compatible: "brcm,bcm93384wvg" diff --git a/Documentation/devicetree/bindings/mips/brcm/usb.txt b/Documentation/devicetree/bindings/mips/brcm/usb.txt new file mode 100644 index 000000000000..452c45c7bf29 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/usb.txt @@ -0,0 +1,11 @@ +* Broadcom USB controllers + +Required properties: +- compatible: "brcm,bcm3384-ohci", "brcm,bcm3384-ehci" + + These currently use the generic-ohci and generic-ehci drivers. On some + systems, special handling may be needed in the following cases: + + - Restoring state after systemwide power save modes + - Sharing PHYs with the USBD (UDC) hardware + - Figuring out which controllers are disabled on ASIC bondout variants -- GitLab From ab81ce62178c14e883b8cfa9773b289f22e99489 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:04 -0700 Subject: [PATCH 6027/9457] Documentation: DT: Add "mti" vendor prefix We have a bunch of platforms using "mti,cpu-interrupt-controller" but the "mti" prefix isn't documented. Fix this. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8169/ Signed-off-by: Ralf Baechle --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index a344ec2713a5..88536391916b 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -98,6 +98,7 @@ mitsubishi Mitsubishi Electric Corporation mosaixtech Mosaix Technologies, Inc. moxa Moxa mpl MPL AG +mti Imagination Technologies Ltd. (formerly MIPS Technologies Inc.) mundoreader Mundo Reader S.L. murata Murata Manufacturing Co., Ltd. mxicy Macronix International Co., Ltd. -- GitLab From d666cd0246f78bda9fbf92a7ded20d1932078652 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:05 -0700 Subject: [PATCH 6028/9457] MIPS: bcm3384: Initial commit of bcm3384 platform support This supports SMP Linux running on the BCM3384 Zephyr (BMIPS5000) application processor, with fully functional UART and USB 1.1/2.0. Device Tree is used to configure the following items: - All peripherals - Early console base address - SMP or UP mode - MIPS counter frequency - Memory size / regions - DMA offset - Kernel command line The DT-enabled bootloader and build instructions are posted at https://github.com/Broadcom/aeolus Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8170/ Signed-off-by: Ralf Baechle --- arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 26 +++ arch/mips/bcm3384/Makefile | 1 + arch/mips/bcm3384/Platform | 7 + arch/mips/bcm3384/dma.c | 81 ++++++++ arch/mips/bcm3384/irq.c | 193 ++++++++++++++++++ arch/mips/bcm3384/setup.c | 97 +++++++++ arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/bcm3384.dtsi | 109 ++++++++++ arch/mips/boot/dts/bcm93384wvg.dts | 32 +++ arch/mips/configs/bcm3384_defconfig | 78 +++++++ .../include/asm/mach-bcm3384/dma-coherence.h | 48 +++++ arch/mips/include/asm/mach-bcm3384/war.h | 24 +++ 13 files changed, 698 insertions(+) create mode 100644 arch/mips/bcm3384/Makefile create mode 100644 arch/mips/bcm3384/Platform create mode 100644 arch/mips/bcm3384/dma.c create mode 100644 arch/mips/bcm3384/irq.c create mode 100644 arch/mips/bcm3384/setup.c create mode 100644 arch/mips/boot/dts/bcm3384.dtsi create mode 100644 arch/mips/boot/dts/bcm93384wvg.dts create mode 100644 arch/mips/configs/bcm3384_defconfig create mode 100644 arch/mips/include/asm/mach-bcm3384/dma-coherence.h create mode 100644 arch/mips/include/asm/mach-bcm3384/war.h diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index f5e18bf3275e..7c507212025a 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -3,6 +3,7 @@ platforms += alchemy platforms += ar7 platforms += ath79 +platforms += bcm3384 platforms += bcm47xx platforms += bcm63xx platforms += cavium-octeon diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 002cf4c56ebf..3afb795c0125 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -116,6 +116,32 @@ config ATH79 help Support for the Atheros AR71XX/AR724X/AR913X SoCs. +config BCM3384 + bool "Broadcom BCM3384 based boards" + select BOOT_RAW + select NO_EXCEPT_FILL + select USE_OF + select CEVT_R4K + select CSRC_R4K + select SYNC_R4K + select COMMON_CLK + select DMA_NONCOHERENT + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_CPU_BMIPS5000 + select SWAP_IO_SPACE + select USB_EHCI_BIG_ENDIAN_DESC + select USB_EHCI_BIG_ENDIAN_MMIO + select USB_OHCI_BIG_ENDIAN_DESC + select USB_OHCI_BIG_ENDIAN_MMIO + help + Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem + chipset with a Linux application processor that is often used to + provide Samba services, a CUPS print server, and/or advanced routing + features. + config BCM47XX bool "Broadcom BCM47XX based boards" select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/mips/bcm3384/Makefile b/arch/mips/bcm3384/Makefile new file mode 100644 index 000000000000..a393955cba08 --- /dev/null +++ b/arch/mips/bcm3384/Makefile @@ -0,0 +1 @@ +obj-y += setup.o irq.o dma.o diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform new file mode 100644 index 000000000000..8e1ca0819e1b --- /dev/null +++ b/arch/mips/bcm3384/Platform @@ -0,0 +1,7 @@ +# +# Broadcom BCM3384 boards +# +platform-$(CONFIG_BCM3384) += bcm3384/ +cflags-$(CONFIG_BCM3384) += \ + -I$(srctree)/arch/mips/include/asm/mach-bcm3384/ +load-$(CONFIG_BCM3384) := 0xffffffff80010000 diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c new file mode 100644 index 000000000000..ea42012fd4f5 --- /dev/null +++ b/arch/mips/bcm3384/dma.c @@ -0,0 +1,81 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2014 Kevin Cernekee + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * BCM3384 has configurable address translation windows which allow the + * peripherals' DMA addresses to be different from the Zephyr-visible + * physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000 + * + * If our DT "memory" node has a "dma-xor-mask" property we will enable this + * translation using the provided offset. + */ +static u32 bcm3384_dma_xor_mask; +static u32 bcm3384_dma_xor_limit = 0xffffffff; + +/* + * PCI collapses the memory hole at 0x10000000 - 0x1fffffff. + * On systems with a dma-xor-mask, this range is guaranteed to live above + * the dma-xor-limit. + */ +#define BCM3384_MEM_HOLE_PA 0x10000000 +#define BCM3384_MEM_HOLE_SIZE 0x10000000 + +static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa) +{ + if (dev && dev_is_pci(dev) && + pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE)) + return pa - BCM3384_MEM_HOLE_SIZE; + if (pa <= bcm3384_dma_xor_limit) + return pa ^ bcm3384_dma_xor_mask; + return pa; +} + +dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) +{ + return bcm3384_phys_to_dma(dev, virt_to_phys(addr)); +} + +dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) +{ + return bcm3384_phys_to_dma(dev, page_to_phys(page)); +} + +unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + if (dev && dev_is_pci(dev) && + dma_addr >= BCM3384_MEM_HOLE_PA) + return dma_addr + BCM3384_MEM_HOLE_SIZE; + if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit) + return dma_addr ^ bcm3384_dma_xor_mask; + return dma_addr; +} + +static int __init bcm3384_init_dma_xor(void) +{ + struct device_node *np = of_find_node_by_type(NULL, "memory"); + + if (!np) + return 0; + + of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask); + of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit); + + of_node_put(np); + return 0; +} +arch_initcall(bcm3384_init_dma_xor); diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c new file mode 100644 index 000000000000..0fb5134fb832 --- /dev/null +++ b/arch/mips/bcm3384/irq.c @@ -0,0 +1,193 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Partially based on arch/mips/ralink/irq.c + * + * Copyright (C) 2009 Gabor Juhos + * Copyright (C) 2013 John Crispin + * Copyright (C) 2014 Kevin Cernekee + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* INTC register offsets */ +#define INTC_REG_ENABLE 0x00 +#define INTC_REG_STATUS 0x04 + +#define MAX_WORDS 2 +#define IRQS_PER_WORD 32 + +struct bcm3384_intc { + int n_words; + void __iomem *reg[MAX_WORDS]; + u32 enable[MAX_WORDS]; + spinlock_t lock; +}; + +static void bcm3384_intc_irq_unmask(struct irq_data *d) +{ + struct bcm3384_intc *priv = d->domain->host_data; + unsigned long flags; + int idx = d->hwirq / IRQS_PER_WORD; + int bit = d->hwirq % IRQS_PER_WORD; + + spin_lock_irqsave(&priv->lock, flags); + priv->enable[idx] |= BIT(bit); + __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static void bcm3384_intc_irq_mask(struct irq_data *d) +{ + struct bcm3384_intc *priv = d->domain->host_data; + unsigned long flags; + int idx = d->hwirq / IRQS_PER_WORD; + int bit = d->hwirq % IRQS_PER_WORD; + + spin_lock_irqsave(&priv->lock, flags); + priv->enable[idx] &= ~BIT(bit); + __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static struct irq_chip bcm3384_intc_irq_chip = { + .name = "INTC", + .irq_unmask = bcm3384_intc_irq_unmask, + .irq_mask = bcm3384_intc_irq_mask, + .irq_mask_ack = bcm3384_intc_irq_mask, +}; + +unsigned int get_c0_compare_int(void) +{ + return CP0_LEGACY_COMPARE_IRQ; +} + +static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct irq_domain *domain = irq_get_handler_data(irq); + struct bcm3384_intc *priv = domain->host_data; + unsigned long flags; + unsigned int idx; + + for (idx = 0; idx < priv->n_words; idx++) { + unsigned long pending; + int hwirq; + + spin_lock_irqsave(&priv->lock, flags); + pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) & + priv->enable[idx]; + spin_unlock_irqrestore(&priv->lock, flags); + + for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { + generic_handle_irq(irq_find_mapping(domain, + hwirq + idx * IRQS_PER_WORD)); + } + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long pending = + (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0; + int bit; + + for_each_set_bit(bit, &pending, 8) + do_IRQ(MIPS_CPU_IRQ_BASE + bit); +} + +static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq); + return 0; +} + +static const struct irq_domain_ops irq_domain_ops = { + .xlate = irq_domain_xlate_onecell, + .map = intc_map, +}; + +static int __init ioremap_one_pair(struct bcm3384_intc *priv, + struct device_node *node, + int idx) +{ + struct resource res; + + if (of_address_to_resource(node, idx, &res)) + return 0; + + if (request_mem_region(res.start, resource_size(&res), + res.name) < 0) + pr_err("Failed to request INTC register region\n"); + + priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res)); + if (!priv->reg[idx]) + panic("Failed to ioremap INTC register range"); + + /* start up with everything masked before we hook the parent IRQ */ + __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE); + priv->enable[idx] = 0; + + return IRQS_PER_WORD; +} + +static int __init intc_of_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *domain; + unsigned int parent_irq, n_irqs = 0; + struct bcm3384_intc *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + panic("Failed to allocate bcm3384_intc struct"); + + spin_lock_init(&priv->lock); + + parent_irq = irq_of_parse_and_map(node, 0); + if (!parent_irq) + panic("Failed to get INTC IRQ"); + + n_irqs += ioremap_one_pair(priv, node, 0); + n_irqs += ioremap_one_pair(priv, node, 1); + + if (!n_irqs) + panic("Failed to map INTC registers"); + + priv->n_words = n_irqs / IRQS_PER_WORD; + domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv); + if (!domain) + panic("Failed to add irqdomain"); + + irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler); + irq_set_handler_data(parent_irq, domain); + + return 0; +} + +static struct of_device_id of_irq_ids[] __initdata = { + { .compatible = "mti,cpu-interrupt-controller", + .data = mips_cpu_intc_init }, + { .compatible = "brcm,bcm3384-intc", + .data = intc_of_init }, + {}, +}; + +void __init arch_init_irq(void) +{ + bmips_tp1_irqs = 0; + of_irq_init(of_irq_ids); +} diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c new file mode 100644 index 000000000000..d84b8400b874 --- /dev/null +++ b/arch/mips/bcm3384/setup.c @@ -0,0 +1,97 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon + * Copyright (C) 2014 Kevin Cernekee + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void __init prom_init(void) +{ + register_bmips_smp_ops(); +} + +void __init prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return "BCM3384"; +} + +void __init plat_time_init(void) +{ + struct device_node *np; + u32 freq; + + np = of_find_node_by_name(NULL, "cpus"); + if (!np) + panic("missing 'cpus' DT node"); + if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0) + panic("missing 'mips-hpt-frequency' property"); + of_node_put(np); + + mips_hpt_frequency = freq; +} + +void __init plat_mem_setup(void) +{ + void *dtb = __dtb_start; + + set_io_port_base(0); + ioport_resource.start = 0; + ioport_resource.end = ~0; + + /* intended to somewhat resemble ARM; see Documentation/arm/Booting */ + if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) + dtb = phys_to_virt(fw_arg2); + + __dt_setup_arch(dtb); + + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); +} + +void __init device_tree_init(void) +{ + struct device_node *np; + + unflatten_and_copy_device_tree(); + + /* Disable SMP boot unless both CPUs are listed in DT and !disabled */ + np = of_find_node_by_name(NULL, "cpus"); + if (np && of_get_available_child_count(np) <= 1) + bmips_smp_enabled = 0; + of_node_put(np); +} + +int __init plat_of_setup(void) +{ + return __dt_register_buses("brcm,bcm3384", "simple-bus"); +} + +arch_initcall(plat_of_setup); + +static int __init plat_dev_init(void) +{ + of_clk_init(NULL); + return 0; +} + +device_initcall(plat_dev_init); diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index ca9c90e2cabf..4f49fa477f14 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -1,3 +1,4 @@ +dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi new file mode 100644 index 000000000000..21b074a99c94 --- /dev/null +++ b/arch/mips/boot/dts/bcm3384.dtsi @@ -0,0 +1,109 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm3384", "brcm,bcm33843"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + /* On BMIPS5000 this is 1/8th of the CPU core clock */ + mips-hpt-frequency = <100000000>; + + cpu@0 { + compatible = "brcm,bmips5000"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips5000"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + periph_clk: periph_clk@0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <54000000>; + }; + }; + + aliases { + uart0 = &uart0; + }; + + cpu_intc: cpu_intc@0 { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + periph_intc: periph_intc@14e00038 { + compatible = "brcm,bcm3384-intc"; + reg = <0x14e00038 0x8 0x14e00340 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <4>; + }; + + zmips_intc: zmips_intc@104b0060 { + compatible = "brcm,bcm3384-intc"; + reg = <0x104b0060 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = <29>; + }; + + iop_intc: iop_intc@14e00058 { + compatible = "brcm,bcm3384-intc"; + reg = <0x14e00058 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <6>; + }; + + uart0: serial@14e00520 { + compatible = "brcm,bcm6345-uart"; + reg = <0x14e00520 0x18>; + interrupt-parent = <&periph_intc>; + interrupts = <2>; + clocks = <&periph_clk>; + status = "disabled"; + }; + + ehci0: usb@15400300 { + compatible = "brcm,bcm3384-ehci", "generic-ehci"; + reg = <0x15400300 0x100>; + big-endian; + interrupt-parent = <&periph_intc>; + interrupts = <41>; + status = "disabled"; + }; + + ohci0: usb@15400400 { + compatible = "brcm,bcm3384-ohci", "generic-ohci"; + reg = <0x15400400 0x100>; + big-endian; + no-big-frame-no; + interrupt-parent = <&periph_intc>; + interrupts = <40>; + status = "disabled"; + }; +}; diff --git a/arch/mips/boot/dts/bcm93384wvg.dts b/arch/mips/boot/dts/bcm93384wvg.dts new file mode 100644 index 000000000000..831741179212 --- /dev/null +++ b/arch/mips/boot/dts/bcm93384wvg.dts @@ -0,0 +1,32 @@ +/dts-v1/; + +/include/ "bcm3384.dtsi" + +/ { + compatible = "brcm,bcm93384wvg", "brcm,bcm3384"; + model = "Broadcom BCM93384WVG"; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x04000000>; + dma-xor-mask = <0x08000000>; + dma-xor-limit = <0x0fffffff>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; diff --git a/arch/mips/configs/bcm3384_defconfig b/arch/mips/configs/bcm3384_defconfig new file mode 100644 index 000000000000..88711c28ff32 --- /dev/null +++ b/arch/mips/configs/bcm3384_defconfig @@ -0,0 +1,78 @@ +CONFIG_BCM3384=y +CONFIG_HIGHMEM=y +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +# CONFIG_SECCOMP is not set +CONFIG_MIPS_O32_FP64_SUPPORT=y +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_NO_HZ=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_GZIP is not set +CONFIG_EXPERT=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +CONFIG_MAC80211=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_MTD=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_BLK_DEV is not set +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_NETDEVICES=y +CONFIG_USB_USBNET=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_EARLYCON_FORCE=y +CONFIG_SERIAL_BCM63XX=y +CONFIG_SERIAL_BCM63XX_CONSOLE=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_DNOTIFY is not set +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_CIFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/include/asm/mach-bcm3384/dma-coherence.h b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h new file mode 100644 index 000000000000..a3be8e50e1f0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2006 Ralf Baechle + * Copyright (C) 2009 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H +#define __ASM_MACH_BCM3384_DMA_COHERENCE_H + +struct device; + +extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size); +extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page); +extern unsigned long plat_dma_addr_to_phys(struct device *dev, + dma_addr_t dma_addr); + +static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, + size_t size, enum dma_data_direction direction) +{ +} + +static inline int plat_dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < DMA_BIT_MASK(24)) + return 0; + + return 1; +} + +static inline int plat_device_is_coherent(struct device *dev) +{ + return 0; +} + +#endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h new file mode 100644 index 000000000000..59d7599059b0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/war.h @@ -0,0 +1,24 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_BCM3384_WAR_H +#define __ASM_MIPS_MACH_BCM3384_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */ -- GitLab From a2f6734c5f683afe5c1b7c23bd60e08e8ad719c4 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:06 -0700 Subject: [PATCH 6029/9457] MAINTAINERS: Add entry for BCM33xx cable chips Add myself as a maintainer for the new BCM3384 board support code. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8171/ Signed-off-by: Ralf Baechle --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0ff630de8a6d..42f0199083cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2078,6 +2078,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git S: Maintained N: bcm2835 +BROADCOM BCM33XX MIPS ARCHITECTURE +M: Kevin Cernekee +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/bcm3384/* +F: arch/mips/include/asm/mach-bcm3384/* +F: arch/mips/kernel/*bmips* + BROADCOM BCM5301X ARM ARCHITECTURE M: Hauke Mehrtens L: linux-arm-kernel@lists.infradead.org -- GitLab From 7110e227c86b83446b3b157df2ebb662c9fcb033 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 20 Oct 2014 21:28:07 -0700 Subject: [PATCH 6030/9457] MAINTAINERS: Add entry for bcm63xx/bcm33xx UDC gadget driver This hardware shows up on the newly-supported BCM3384 cable chip, as well as several old BCM63xx DSL chips. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: mbizon@freebox.fr Cc: jogo@openwrt.org Cc: jfraser@broadcom.com Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8172/ Signed-off-by: Ralf Baechle --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 42f0199083cf..680861287cb7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2102,6 +2102,12 @@ S: Maintained F: arch/arm/mach-bcm/bcm63xx.c F: arch/arm/include/debug/bcm63xx.S +BROADCOM BCM63XX/BCM33XX UDC DRIVER +M: Kevin Cernekee +L: linux-usb@vger.kernel.org +S: Maintained +F: drivers/usb/gadget/udc/bcm63xx_udc.* + BROADCOM BCM7XXX ARM ARCHITECTURE M: Marc Carino M: Brian Norris -- GitLab From 824f3f7fa2b441416e3d9aaf1f19feab7db44747 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:54 -0700 Subject: [PATCH 6031/9457] irqchip: mips-gic: Clean up header file Remove duplicate #defines and unnecessary #includes, fix parenthesization, and re-order register definitions in ascending order. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8128/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 4 +- include/linux/irqchip/mips-gic.h | 129 +++++++------------------------ 2 files changed, 29 insertions(+), 104 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index bf0f7c978086..eaebeea36d23 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -253,8 +253,8 @@ static unsigned int gic_get_int(void) intrmask = intrmask_regs[smp_processor_id()].intrmask; pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; - pending_reg = GIC_REG(SHARED, GIC_SH_PEND_31_0); - intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK_31_0); + pending_reg = GIC_REG(SHARED, GIC_SH_PEND); + intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK); for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) { pending[i] = gic_read(pending_reg); diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 285944ca9f6c..0350effb7ccc 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h @@ -4,17 +4,11 @@ * for more details. * * Copyright (C) 2000, 07 MIPS Technologies, Inc. - * - * GIC Register Definitions - * */ -#ifndef _ASM_GICREGS_H -#define _ASM_GICREGS_H - -#include -#include +#ifndef __LINUX_IRQCHIP_MIPS_GIC_H +#define __LINUX_IRQCHIP_MIPS_GIC_H -#include +#include #define GIC_MAX_INTRS 256 @@ -50,108 +44,42 @@ #define GIC_SH_COUNTER_63_32_OFS 0x0014 #define GIC_SH_REVISIONID_OFS 0x0020 -/* Interrupt Polarity */ -#define GIC_SH_POL_31_0_OFS 0x0100 -#define GIC_SH_POL_63_32_OFS 0x0104 -#define GIC_SH_POL_95_64_OFS 0x0108 -#define GIC_SH_POL_127_96_OFS 0x010c -#define GIC_SH_POL_159_128_OFS 0x0110 -#define GIC_SH_POL_191_160_OFS 0x0114 -#define GIC_SH_POL_223_192_OFS 0x0118 -#define GIC_SH_POL_255_224_OFS 0x011c - -/* Edge/Level Triggering */ -#define GIC_SH_TRIG_31_0_OFS 0x0180 -#define GIC_SH_TRIG_63_32_OFS 0x0184 -#define GIC_SH_TRIG_95_64_OFS 0x0188 -#define GIC_SH_TRIG_127_96_OFS 0x018c -#define GIC_SH_TRIG_159_128_OFS 0x0190 -#define GIC_SH_TRIG_191_160_OFS 0x0194 -#define GIC_SH_TRIG_223_192_OFS 0x0198 -#define GIC_SH_TRIG_255_224_OFS 0x019c - -/* Dual Edge Triggering */ -#define GIC_SH_DUAL_31_0_OFS 0x0200 -#define GIC_SH_DUAL_63_32_OFS 0x0204 -#define GIC_SH_DUAL_95_64_OFS 0x0208 -#define GIC_SH_DUAL_127_96_OFS 0x020c -#define GIC_SH_DUAL_159_128_OFS 0x0210 -#define GIC_SH_DUAL_191_160_OFS 0x0214 -#define GIC_SH_DUAL_223_192_OFS 0x0218 -#define GIC_SH_DUAL_255_224_OFS 0x021c +/* Convert an interrupt number to a byte offset/bit for multi-word registers */ +#define GIC_INTR_OFS(intr) (((intr) / 32) * 4) +#define GIC_INTR_BIT(intr) ((intr) % 32) + +/* Polarity : Reset Value is always 0 */ +#define GIC_SH_SET_POLARITY_OFS 0x0100 + +/* Triggering : Reset Value is always 0 */ +#define GIC_SH_SET_TRIGGER_OFS 0x0180 + +/* Dual edge triggering : Reset Value is always 0 */ +#define GIC_SH_SET_DUAL_OFS 0x0200 /* Set/Clear corresponding bit in Edge Detect Register */ #define GIC_SH_WEDGE_OFS 0x0280 -/* Reset Mask - Disables Interrupt */ -#define GIC_SH_RMASK_31_0_OFS 0x0300 -#define GIC_SH_RMASK_63_32_OFS 0x0304 -#define GIC_SH_RMASK_95_64_OFS 0x0308 -#define GIC_SH_RMASK_127_96_OFS 0x030c -#define GIC_SH_RMASK_159_128_OFS 0x0310 -#define GIC_SH_RMASK_191_160_OFS 0x0314 -#define GIC_SH_RMASK_223_192_OFS 0x0318 -#define GIC_SH_RMASK_255_224_OFS 0x031c - -/* Set Mask (WO) - Enables Interrupt */ -#define GIC_SH_SMASK_31_0_OFS 0x0380 -#define GIC_SH_SMASK_63_32_OFS 0x0384 -#define GIC_SH_SMASK_95_64_OFS 0x0388 -#define GIC_SH_SMASK_127_96_OFS 0x038c -#define GIC_SH_SMASK_159_128_OFS 0x0390 -#define GIC_SH_SMASK_191_160_OFS 0x0394 -#define GIC_SH_SMASK_223_192_OFS 0x0398 -#define GIC_SH_SMASK_255_224_OFS 0x039c +/* Mask manipulation */ +#define GIC_SH_RMASK_OFS 0x0300 +#define GIC_SH_SMASK_OFS 0x0380 /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ -#define GIC_SH_MASK_31_0_OFS 0x0400 -#define GIC_SH_MASK_63_32_OFS 0x0404 -#define GIC_SH_MASK_95_64_OFS 0x0408 -#define GIC_SH_MASK_127_96_OFS 0x040c -#define GIC_SH_MASK_159_128_OFS 0x0410 -#define GIC_SH_MASK_191_160_OFS 0x0414 -#define GIC_SH_MASK_223_192_OFS 0x0418 -#define GIC_SH_MASK_255_224_OFS 0x041c +#define GIC_SH_MASK_OFS 0x0400 /* Pending Global Interrupts (RO) */ -#define GIC_SH_PEND_31_0_OFS 0x0480 -#define GIC_SH_PEND_63_32_OFS 0x0484 -#define GIC_SH_PEND_95_64_OFS 0x0488 -#define GIC_SH_PEND_127_96_OFS 0x048c -#define GIC_SH_PEND_159_128_OFS 0x0490 -#define GIC_SH_PEND_191_160_OFS 0x0494 -#define GIC_SH_PEND_223_192_OFS 0x0498 -#define GIC_SH_PEND_255_224_OFS 0x049c - -#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 +#define GIC_SH_PEND_OFS 0x0480 /* Maps Interrupt X to a Pin */ +#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 #define GIC_SH_MAP_TO_PIN(intr) (4 * (intr)) -#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 - /* Maps Interrupt X to a VPE */ +#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ ((32 * (intr)) + (((vpe) / 32) * 4)) #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) -/* Convert an interrupt number to a byte offset/bit for multi-word registers */ -#define GIC_INTR_OFS(intr) (((intr) / 32)*4) -#define GIC_INTR_BIT(intr) ((intr) % 32) - -/* Polarity : Reset Value is always 0 */ -#define GIC_SH_SET_POLARITY_OFS 0x0100 - -/* Triggering : Reset Value is always 0 */ -#define GIC_SH_SET_TRIGGER_OFS 0x0180 - -/* Dual edge triggering : Reset Value is always 0 */ -#define GIC_SH_SET_DUAL_OFS 0x0200 - -/* Mask manipulation */ -#define GIC_SH_SMASK_OFS 0x0380 -#define GIC_SH_RMASK_OFS 0x0300 - /* Register Map for Local Section */ #define GIC_VPE_CTL_OFS 0x0000 #define GIC_VPE_PEND_OFS 0x0004 @@ -200,8 +128,8 @@ #define GIC_SH_CONFIG_NUMVPES_SHF 0 #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) -#define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) -#define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) +#define GIC_SH_WEDGE_SET(intr) ((intr) | (0x1 << 31)) +#define GIC_SH_WEDGE_CLR(intr) ((intr) & ~(0x1 << 31)) #define GIC_MAP_TO_PIN_SHF 31 #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) @@ -278,10 +206,10 @@ #define GIC_CPU_PIN_OFFSET 2 /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ -#define GIC_CPU_TO_VEC_OFFSET (2) +#define GIC_CPU_TO_VEC_OFFSET 2 /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ -#define GIC_PIN_TO_VEC_OFFSET (1) +#define GIC_PIN_TO_VEC_OFFSET 1 /* Local GIC interrupts. */ #define GIC_LOCAL_INT_WD 0 /* GIC watchdog */ @@ -301,9 +229,6 @@ #define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) -#include -#include - extern unsigned int gic_present; extern unsigned int gic_frequency; @@ -322,4 +247,4 @@ extern unsigned int plat_ipi_resched_int_xlate(unsigned int); extern unsigned int gic_get_timer_pending(void); extern int gic_get_c0_compare_int(void); extern int gic_get_c0_perfcount_int(void); -#endif /* _ASM_GICREGS_H */ +#endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ -- GitLab From fb8f7be1299f4b0d86d65e0eada6c9962061c912 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:55 -0700 Subject: [PATCH 6032/9457] irqchip: mips-gic: Clean up #includes Sort the #includes and remove those which are unnecessary. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8130/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index eaebeea36d23..9d7b1db791e4 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -7,19 +7,16 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include +#include #include #include +#include #include #include #include -#include -#include -#include #include #include -#include -#include unsigned int gic_frequency; unsigned int gic_present; -- GitLab From 8f5ee79c92a6b87abea676fd0b94a10953d181f1 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:56 -0700 Subject: [PATCH 6033/9457] irqchip: mips-gic: Remove gic_{pending,itrmask}_regs There's no reason for the pending and masked interrupt bitmasks to be global. Just declare them on the stack in gic_get_int() since they only consume (256*2)/8 = 64 bytes. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8131/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 9d7b1db791e4..5ce11bd7f6a8 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -25,18 +25,8 @@ struct gic_pcpu_mask { DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); }; -struct gic_pending_regs { - DECLARE_BITMAP(pending, GIC_MAX_INTRS); -}; - -struct gic_intrmask_regs { - DECLARE_BITMAP(intrmask, GIC_MAX_INTRS); -}; - static void __iomem *gic_base; static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; -static struct gic_pending_regs pending_regs[NR_CPUS]; -static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static DEFINE_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; static int gic_shared_intrs; @@ -242,12 +232,12 @@ int gic_get_c0_perfcount_int(void) static unsigned int gic_get_int(void) { unsigned int i; - unsigned long *pending, *intrmask, *pcpu_mask; + unsigned long *pcpu_mask; unsigned long pending_reg, intrmask_reg; + DECLARE_BITMAP(pending, GIC_MAX_INTRS); + DECLARE_BITMAP(intrmask, GIC_MAX_INTRS); /* Get per-cpu bitmaps */ - pending = pending_regs[smp_processor_id()].pending; - intrmask = intrmask_regs[smp_processor_id()].intrmask; pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; pending_reg = GIC_REG(SHARED, GIC_SH_PEND); -- GitLab From 53a7bc815a139a524f1d60c32b70455f02b87a6d Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:57 -0700 Subject: [PATCH 6034/9457] irqchip: mips-gic: Use GIC_SH_WEDGE_{SET,CLR} macros Use the GIC_SH_WEDGE_{SET,CLR} macros provided by mips-gic.h. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8134/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 5ce11bd7f6a8..fbe2ceda4928 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -206,7 +206,7 @@ static void gic_bind_eic_interrupt(int irq, int set) void gic_send_ipi(unsigned int intr) { - gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); + gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(intr)); } int gic_get_c0_compare_int(void) @@ -270,7 +270,7 @@ static void gic_ack_irq(struct irq_data *d) { unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); - gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), irq); + gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq)); } static int gic_set_type(struct irq_data *d, unsigned int type) -- GitLab From fa5635a277171021d364f6a3fab4addce8f358d2 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:58 -0700 Subject: [PATCH 6035/9457] MIPS: Move GIC clocksource driver to drivers/clocksource/ Move the GIC clocksource driver to drivers/clocksource/mips-gic-timer.c. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8133/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 8 ++------ arch/mips/kernel/Makefile | 1 - arch/mips/mti-malta/malta-time.c | 2 +- drivers/clocksource/Kconfig | 4 ++++ drivers/clocksource/Makefile | 1 + .../csrc-gic.c => drivers/clocksource/mips-gic-timer.c | 0 drivers/irqchip/irq-mips-gic.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename arch/mips/kernel/csrc-gic.c => drivers/clocksource/mips-gic-timer.c (100%) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3afb795c0125..5b690cf0fec7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -342,7 +342,7 @@ config MIPS_MALTA select BOOT_RAW select CEVT_R4K select CSRC_R4K - select CSRC_GIC + select CLKSRC_MIPS_GIC select DMA_MAYBE_COHERENT select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM @@ -385,7 +385,7 @@ config MIPS_SEAD3 select BUILTIN_DTB select CEVT_R4K select CSRC_R4K - select CSRC_GIC + select CLKSRC_MIPS_GIC select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select DMA_NONCOHERENT @@ -954,10 +954,6 @@ config CSRC_IOASIC config CSRC_R4K bool -config CSRC_GIC - select MIPS_CM - bool - config CSRC_SB1250 bool diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 0945d804ec3a..1aedbf5e4232 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -24,7 +24,6 @@ obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o -obj-$(CONFIG_CSRC_GIC) += csrc-gic.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 608655f8e6dd..028fae077001 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -183,7 +183,7 @@ void __init plat_time_init(void) freq = freqround(gic_frequency, 5000); printk("GIC frequency %d.%02d MHz\n", freq/1000000, (freq%1000000)*100/1000000); -#ifdef CONFIG_CSRC_GIC +#ifdef CONFIG_CLKSRC_MIPS_GIC gic_clocksource_init(gic_frequency); #endif } diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 90420600e1eb..cb7e7f417a60 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -223,4 +223,8 @@ config CLKSRC_VERSATILE ARM Versatile, RealView and Versatile Express reference platforms. +config CLKSRC_MIPS_GIC + bool + depends on MIPS_GIC + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 756f6f10efa0..e23fc2d5fc27 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -46,3 +46,4 @@ obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o +obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o diff --git a/arch/mips/kernel/csrc-gic.c b/drivers/clocksource/mips-gic-timer.c similarity index 100% rename from arch/mips/kernel/csrc-gic.c rename to drivers/clocksource/mips-gic-timer.c diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index fbe2ceda4928..035d5ad435f9 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); } -#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) +#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC) cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; -- GitLab From a331ce63c85080f554e0a19fc4189a520c65267b Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:03:59 -0700 Subject: [PATCH 6036/9457] clocksource: mips-gic: Combine with GIC clockevent driver Combine the GIC clocksource driver with the GIC clockevent driver from arch/mips/kernel/cevt-gic.c and remove the clockevent driver's separate Kconfig symbol. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8132/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 13 ---- arch/mips/include/asm/time.h | 2 +- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/cevt-gic.c | 103 --------------------------- drivers/clocksource/mips-gic-timer.c | 90 +++++++++++++++++++++++ drivers/irqchip/irq-mips-gic.c | 2 +- 6 files changed, 92 insertions(+), 119 deletions(-) delete mode 100644 arch/mips/kernel/cevt-gic.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5b690cf0fec7..97bbb3b09d4b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -935,10 +935,6 @@ config CEVT_GT641XX config CEVT_R4K bool -config CEVT_GIC - select MIPS_CM - bool - config CEVT_SB1250 bool @@ -1911,15 +1907,6 @@ config FORCE_MAX_ZONEORDER The page size is not necessarily 4KB. Keep this in mind when choosing a value for this option. -config CEVT_GIC - bool "Use GIC global counter for clock events" - depends on MIPS_GIC && !MIPS_SEAD3 - help - Use the GIC global counter for the clock events. The R4K clock - event driver is always present, so if the platform ends up not - detecting a GIC, it will fall back to the R4K timer for the - generation of clock events. - config BOARD_SCACHE bool diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 7969933ba89a..5f30aabbb598 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -57,7 +57,7 @@ extern int gic_clockevent_init(void); static inline int mips_clockevent_init(void) { -#if defined(CONFIG_CEVT_GIC) +#if defined(CONFIG_CLKSRC_MIPS_GIC) return (gic_clockevent_init() | r4k_clockevent_init()); #elif defined(CONFIG_CEVT_R4K) return r4k_clockevent_init(); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 1aedbf5e4232..92987d1bbe5f 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -19,7 +19,6 @@ endif obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o -obj-$(CONFIG_CEVT_GIC) += cevt-gic.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c deleted file mode 100644 index 9caa68a2bcdc..000000000000 --- a/arch/mips/kernel/cevt-gic.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2013 Imagination Technologies Ltd. - */ -#include -#include -#include -#include -#include -#include - -#include -#include - -DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -int gic_timer_irq_installed; - - -static int gic_next_event(unsigned long delta, struct clock_event_device *evt) -{ - u64 cnt; - int res; - - cnt = gic_read_count(); - cnt += (u64)delta; - gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); - res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; - return res; -} - -void gic_set_clock_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - /* Nothing to do ... */ -} - -irqreturn_t gic_compare_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *cd; - int cpu = smp_processor_id(); - - gic_write_compare(gic_read_compare()); - cd = &per_cpu(gic_clockevent_device, cpu); - cd->event_handler(cd); - return IRQ_HANDLED; -} - -struct irqaction gic_compare_irqaction = { - .handler = gic_compare_interrupt, - .flags = IRQF_PERCPU | IRQF_TIMER, - .name = "timer", -}; - - -void gic_event_handler(struct clock_event_device *dev) -{ -} - -int gic_clockevent_init(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - unsigned int irq; - - if (!cpu_has_counter || !gic_frequency) - return -ENXIO; - - irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); - - cd = &per_cpu(gic_clockevent_device, cpu); - - cd->name = "MIPS GIC"; - cd->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_C3STOP; - - clockevent_set_clock(cd, gic_frequency); - - /* Calculate the min / max delta */ - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - - cd->rating = 300; - cd->irq = irq; - cd->cpumask = cpumask_of(cpu); - cd->set_next_event = gic_next_event; - cd->set_mode = gic_set_clock_mode; - cd->event_handler = gic_event_handler; - - clockevents_register_device(cd); - - if (!gic_timer_irq_installed) { - setup_percpu_irq(irq, &gic_compare_irqaction); - gic_timer_irq_installed = 1; - } - - enable_percpu_irq(irq, IRQ_TYPE_NONE); - - - return 0; -} diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 0bf28e6aca7a..3cf5912c4054 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -5,10 +5,100 @@ * * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ +#include #include +#include #include +#include +#include #include +#include + +DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); +int gic_timer_irq_installed; + +static int gic_next_event(unsigned long delta, struct clock_event_device *evt) +{ + u64 cnt; + int res; + + cnt = gic_read_count(); + cnt += (u64)delta; + gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); + res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; + return res; +} + +void gic_set_clock_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + /* Nothing to do ... */ +} + +irqreturn_t gic_compare_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *cd; + int cpu = smp_processor_id(); + + gic_write_compare(gic_read_compare()); + cd = &per_cpu(gic_clockevent_device, cpu); + cd->event_handler(cd); + return IRQ_HANDLED; +} + +struct irqaction gic_compare_irqaction = { + .handler = gic_compare_interrupt, + .flags = IRQF_PERCPU | IRQF_TIMER, + .name = "timer", +}; + +void gic_event_handler(struct clock_event_device *dev) +{ +} + +int gic_clockevent_init(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + unsigned int irq; + + if (!cpu_has_counter || !gic_frequency) + return -ENXIO; + + irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + + cd = &per_cpu(gic_clockevent_device, cpu); + + cd->name = "MIPS GIC"; + cd->features = CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_C3STOP; + + clockevent_set_clock(cd, gic_frequency); + + /* Calculate the min / max delta */ + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + + cd->rating = 300; + cd->irq = irq; + cd->cpumask = cpumask_of(cpu); + cd->set_next_event = gic_next_event; + cd->set_mode = gic_set_clock_mode; + cd->event_handler = gic_event_handler; + + clockevents_register_device(cd); + + if (!gic_timer_irq_installed) { + setup_percpu_irq(irq, &gic_compare_irqaction); + gic_timer_irq_installed = 1; + } + + enable_percpu_irq(irq, IRQ_TYPE_NONE); + + return 0; +} + static cycle_t gic_hpt_read(struct clocksource *cs) { return gic_read_count(); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 035d5ad435f9..cb674696810d 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -103,7 +103,7 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); } -#if defined(CONFIG_CLKSRC_MIPS_GIC) || defined(CONFIG_CEVT_GIC) +#ifdef CONFIG_CLKSRC_MIPS_GIC cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; -- GitLab From 5fee56e0ddac14511a4dd33f1240a0f0b94a9d08 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:00 -0700 Subject: [PATCH 6037/9457] clocksource: mips-gic: Staticize local symbols There are a number of variables and functions which are unnecessarily global. Mark them static. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8135/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 3cf5912c4054..2603f50e5706 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -15,8 +15,8 @@ #include -DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -int gic_timer_irq_installed; +static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); +static int gic_timer_irq_installed; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { @@ -30,13 +30,13 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt) return res; } -void gic_set_clock_mode(enum clock_event_mode mode, +static void gic_set_clock_mode(enum clock_event_mode mode, struct clock_event_device *evt) { /* Nothing to do ... */ } -irqreturn_t gic_compare_interrupt(int irq, void *dev_id) +static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) { struct clock_event_device *cd; int cpu = smp_processor_id(); @@ -53,7 +53,7 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -void gic_event_handler(struct clock_event_device *dev) +static void gic_event_handler(struct clock_event_device *dev) { } -- GitLab From b0854514537e4e2f0a599ca05d18fe95dcd3ee42 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:01 -0700 Subject: [PATCH 6038/9457] clocksource: mips-gic: Move gic_frequency to clocksource driver There's no reason for gic_frequency to be global any more and it certainly doesn't belong in the GIC irqchip driver, so move it to the GIC clocksource driver. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8137/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-time.c | 2 ++ drivers/clocksource/mips-gic-timer.c | 3 +++ drivers/irqchip/irq-mips-gic.c | 1 - include/linux/irqchip/mips-gic.h | 1 - 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 028fae077001..ce02dbdedc62 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -46,6 +46,8 @@ static int mips_cpu_timer_irq; static int mips_cpu_perf_irq; extern int cp0_perfcount_irq; +static unsigned int gic_frequency; + static void mips_timer_dispatch(void) { do_IRQ(mips_cpu_timer_irq); diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 2603f50e5706..bced17d2d2c1 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -17,6 +17,7 @@ static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); static int gic_timer_irq_installed; +static unsigned int gic_frequency; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) { @@ -112,6 +113,8 @@ static struct clocksource gic_clocksource = { void __init gic_clocksource_init(unsigned int frequency) { + gic_frequency = frequency; + /* Set clocksource mask. */ gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index cb674696810d..7ec3c18f1330 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -18,7 +18,6 @@ #include #include -unsigned int gic_frequency; unsigned int gic_present; struct gic_pcpu_mask { diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 0350effb7ccc..420f77b34d02 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h @@ -230,7 +230,6 @@ #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) extern unsigned int gic_present; -extern unsigned int gic_frequency; extern void gic_init(unsigned long gic_base_addr, unsigned long gic_addrspace_size, unsigned int cpu_vec, -- GitLab From 001f5fe72cf6434f00fccf2b628f6843de1c3d4f Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:02 -0700 Subject: [PATCH 6039/9457] clocksource: mips-gic: Remove gic_event_handler Remove gic_event_handler since it is completely unnecessary. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8136/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index bced17d2d2c1..763aa1c9130f 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -54,10 +54,6 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -static void gic_event_handler(struct clock_event_device *dev) -{ -} - int gic_clockevent_init(void) { unsigned int cpu = smp_processor_id(); @@ -86,7 +82,6 @@ int gic_clockevent_init(void) cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; - cd->event_handler = gic_event_handler; clockevents_register_device(cd); -- GitLab From f7ea3060b60a8f32794aa094f9216b198083d232 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:03 -0700 Subject: [PATCH 6040/9457] clocksource: mips-gic: Use percpu_dev_id Since the GIC timer IRQ is a percpu IRQ, we can use percpu_dev_id to pass the IRQ handler the correct clock_event_device. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8138/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 763aa1c9130f..05bdfe1e3e03 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -39,17 +39,16 @@ static void gic_set_clock_mode(enum clock_event_mode mode, static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) { - struct clock_event_device *cd; - int cpu = smp_processor_id(); + struct clock_event_device *cd = dev_id; gic_write_compare(gic_read_compare()); - cd = &per_cpu(gic_clockevent_device, cpu); cd->event_handler(cd); return IRQ_HANDLED; } struct irqaction gic_compare_irqaction = { .handler = gic_compare_interrupt, + .percpu_dev_id = &gic_clockevent_device, .flags = IRQF_PERCPU | IRQF_TIMER, .name = "timer", }; -- GitLab From e4752dbbc300939e14029583ba2a0b235b147649 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:04 -0700 Subject: [PATCH 6041/9457] clocksource: mips-gic: Use CPU notifiers to setup the timer Instead of requiring an explicit call to gic_clockevent_init in the SMP startup path, use CPU notifiers to register and enable the GIC timer on CPU startup. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8139/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/time.h | 5 +-- drivers/clocksource/mips-gic-timer.c | 60 ++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 5f30aabbb598..8ab2874225c4 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -53,13 +53,10 @@ extern int __weak get_c0_perfcount_int(void); */ extern unsigned int __weak get_c0_compare_int(void); extern int r4k_clockevent_init(void); -extern int gic_clockevent_init(void); static inline int mips_clockevent_init(void) { -#if defined(CONFIG_CLKSRC_MIPS_GIC) - return (gic_clockevent_init() | r4k_clockevent_init()); -#elif defined(CONFIG_CEVT_R4K) +#ifdef CONFIG_CEVT_R4K return r4k_clockevent_init(); #else return -ENXIO; diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 05bdfe1e3e03..3ce992bc574f 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -6,9 +6,11 @@ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. */ #include +#include #include #include #include +#include #include #include #include @@ -16,7 +18,7 @@ #include static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); -static int gic_timer_irq_installed; +static int gic_timer_irq; static unsigned int gic_frequency; static int gic_next_event(unsigned long delta, struct clock_event_device *evt) @@ -53,18 +55,9 @@ struct irqaction gic_compare_irqaction = { .name = "timer", }; -int gic_clockevent_init(void) +static void gic_clockevent_cpu_init(struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - unsigned int irq; - - if (!cpu_has_counter || !gic_frequency) - return -ENXIO; - - irq = MIPS_GIC_IRQ_BASE + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); - - cd = &per_cpu(gic_clockevent_device, cpu); cd->name = "MIPS GIC"; cd->features = CLOCK_EVT_FEAT_ONESHOT | @@ -77,19 +70,52 @@ int gic_clockevent_init(void) cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->rating = 300; - cd->irq = irq; + cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; clockevents_register_device(cd); - if (!gic_timer_irq_installed) { - setup_percpu_irq(irq, &gic_compare_irqaction); - gic_timer_irq_installed = 1; + enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); +} + +static void gic_clockevent_cpu_exit(struct clock_event_device *cd) +{ + disable_percpu_irq(gic_timer_irq); +} + +static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, + void *data) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); + break; + case CPU_DYING: + gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device)); + break; } - enable_percpu_irq(irq, IRQ_TYPE_NONE); + return NOTIFY_OK; +} + +static struct notifier_block gic_cpu_nb = { + .notifier_call = gic_cpu_notifier, +}; + +static int gic_clockevent_init(void) +{ + if (!cpu_has_counter || !gic_frequency) + return -ENXIO; + + gic_timer_irq = MIPS_GIC_IRQ_BASE + + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); + + register_cpu_notifier(&gic_cpu_nb); + + gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); return 0; } @@ -116,4 +142,6 @@ void __init gic_clocksource_init(unsigned int frequency) gic_clocksource.rating = 200 + frequency / 10000000; clocksource_register_hz(&gic_clocksource, frequency); + + gic_clockevent_init(); } -- GitLab From b695d8e6ad6fba3d72b309b0d62128b04cf57160 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:05 -0700 Subject: [PATCH 6042/9457] clocksource: mips-gic: Use clockevents_config_and_register Use clockevents_config_and_register to setup the clock_event_device based on frequency and min/max ticks instead of doing it ourselves. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8140/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 3ce992bc574f..84fbb7ae4db2 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -15,8 +15,6 @@ #include #include -#include - static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); static int gic_timer_irq; static unsigned int gic_frequency; @@ -63,19 +61,13 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd) cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; - clockevent_set_clock(cd, gic_frequency); - - /* Calculate the min / max delta */ - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - cd->rating = 300; cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; cd->set_mode = gic_set_clock_mode; - clockevents_register_device(cd); + clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff); enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); } -- GitLab From a45da5659852bd4cbe453b49f5b26def65f5a6bf Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Mon, 20 Oct 2014 12:04:06 -0700 Subject: [PATCH 6043/9457] clocksource: mips-gic: Bump up rating of GIC timer Bump up the rating of the GIC timer so that it gets prioritized over the CP0 timer. Signed-off-by: Andrew Bresticker Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Jason Cooper Cc: Paul Burton Cc: Qais Yousef Cc: John Crispin Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8141/ Signed-off-by: Ralf Baechle --- drivers/clocksource/mips-gic-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index 84fbb7ae4db2..a749c812e255 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -61,7 +61,7 @@ static void gic_clockevent_cpu_init(struct clock_event_device *cd) cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; - cd->rating = 300; + cd->rating = 350; cd->irq = gic_timer_irq; cd->cpumask = cpumask_of(cpu); cd->set_next_event = gic_next_event; -- GitLab From 24c71c83ed5994f07aabe137decbe3434791938c Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 20 Oct 2014 15:40:01 +0200 Subject: [PATCH 6044/9457] MIPS: Alchemy: Remove direct access to prepare_count field of struct clk Replacing it with a call to __clk_is_prepared(), which isn't entirely equivalent but in practice shouldn't matter. Signed-off-by: Tomeu Vizoso Reviewed-by: Stephen Boyd Cc: Mike Turquette Cc: Javier Martinez Canillas Cc: Manuel Lauss Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8120/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/clock.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index d7557cde271a..203e4403c366 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, break; /* if this parent is currently unused, remember it. - * XXX: I know it's a layering violation, but it works - * so well.. (if (!clk_has_active_children(pc)) ) + * XXX: we would actually want clk_has_active_children() + * but this is a good-enough approximation for now. */ - if (pc->prepare_count == 0) { + if (!__clk_is_prepared(pc)) { if (!free) free = pc; } -- GitLab From 05637f10e719c164e8a4a221d0987ecc46c9ccc7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 13 Mar 2013 10:04:01 +0100 Subject: [PATCH 6045/9457] MIPS: lantiq: handle vmmc memory reservation The Lantiq SoCs have a 2nd mips core called "voice mips macro core (vmmc)" which is used to run the voice firmware. This driver allows us to register a chunk of memory that the voice driver can later use for the 2nd core. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8042/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/Makefile | 2 + arch/mips/lantiq/xway/vmmc.c | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 arch/mips/lantiq/xway/vmmc.c diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 087497d97357..a2edc538f477 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,3 +1,5 @@ obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o +obj-y += vmmc.o + obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c new file mode 100644 index 000000000000..696cd57f6f13 --- /dev/null +++ b/arch/mips/lantiq/xway/vmmc.c @@ -0,0 +1,69 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Copyright (C) 2012 John Crispin + */ + +#include +#include +#include +#include + +#include + +static unsigned int *cp1_base; + +unsigned int *ltq_get_cp1_base(void) +{ + if (!cp1_base) + panic("no cp1 base was set\n"); + + return cp1_base; +} +EXPORT_SYMBOL(ltq_get_cp1_base); + +static int vmmc_probe(struct platform_device *pdev) +{ +#define CP1_SIZE (1 << 20) + int gpio_count; + dma_addr_t dma; + + cp1_base = + (void *) CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, + &dma, GFP_ATOMIC)); + + gpio_count = of_gpio_count(pdev->dev.of_node); + while (gpio_count > 0) { + enum of_gpio_flags flags; + int gpio = of_get_gpio_flags(pdev->dev.of_node, + --gpio_count, &flags); + if (gpio_request(gpio, "vmmc-relay")) + continue; + dev_info(&pdev->dev, "requested GPIO %d\n", gpio); + gpio_direction_output(gpio, + (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1)); + } + + dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base); + + return 0; +} + +static const struct of_device_id vmmc_match[] = { + { .compatible = "lantiq,vmmc-xway" }, + {}, +}; +MODULE_DEVICE_TABLE(of, vmmc_match); + +static struct platform_driver vmmc_driver = { + .probe = vmmc_probe, + .driver = { + .name = "lantiq,vmmc", + .owner = THIS_MODULE, + .of_match_table = vmmc_match, + }, +}; + +module_platform_driver(vmmc_driver); -- GitLab From c530781c93a55a937d2847efeda744b4e099dfef Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 3 Sep 2013 13:18:12 +0200 Subject: [PATCH 6046/9457] MIPS: lantiq: add reset-controller api support Add a reset-controller binding for the reset registers found on the lantiq SoC. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8043/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 ++ arch/mips/lantiq/xway/reset.c | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 97bbb3b09d4b..9e8317e9b567 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -296,6 +296,8 @@ config LANTIQ select USE_OF select PINCTRL select PINCTRL_LANTIQ + select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER config LASAT bool "LASAT Networks platforms" diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 1fa0f175357e..a1e06b78e15a 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -113,6 +114,66 @@ void ltq_reset_once(unsigned int module, ulong u) ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); } +static int ltq_assert_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 val; + + if (id < 8) + return -1; + + val = ltq_rcu_r32(RCU_RST_REQ); + val |= BIT(id); + ltq_rcu_w32(val, RCU_RST_REQ); + + return 0; +} + +static int ltq_deassert_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 val; + + if (id < 8) + return -1; + + val = ltq_rcu_r32(RCU_RST_REQ); + val &= ~BIT(id); + ltq_rcu_w32(val, RCU_RST_REQ); + + return 0; +} + +static int ltq_reset_device(struct reset_controller_dev *rcdev, + unsigned long id) +{ + ltq_assert_device(rcdev, id); + return ltq_deassert_device(rcdev, id); +} + +static struct reset_control_ops reset_ops = { + .reset = ltq_reset_device, + .assert = ltq_assert_device, + .deassert = ltq_deassert_device, +}; + +static struct reset_controller_dev reset_dev = { + .ops = &reset_ops, + .owner = THIS_MODULE, + .nr_resets = 32, + .of_reset_n_cells = 1, +}; + +void ltq_rst_init(void) +{ + reset_dev.of_node = of_find_compatible_node(NULL, NULL, + "lantiq,xway-reset"); + if (!reset_dev.of_node) + pr_err("Failed to find reset controller node"); + else + reset_controller_register(&reset_dev); +} + static void ltq_machine_restart(char *command) { local_irq_disable(); -- GitLab From 50128fe8164ba2c9e36bc5156eabdfd69225b7d2 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 7 Aug 2014 18:55:57 +0200 Subject: [PATCH 6047/9457] MIPS: lantiq: reboot gphy on restart A reboot sometimes lead to a none working phy. An explicit reboot fixes the problem. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8044/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/reset.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index a1e06b78e15a..fe68f9ae47c1 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -176,8 +176,15 @@ void ltq_rst_init(void) static void ltq_machine_restart(char *command) { + u32 val = ltq_rcu_r32(RCU_RST_REQ); + + if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) + val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200; + + val |= RCU_RD_SRST; + local_irq_disable(); - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); + ltq_rcu_w32(val, RCU_RST_REQ); unreachable(); } -- GitLab From 276229d2a98975d0cca9637d1dfee6a9876b54c5 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 10 Sep 2014 22:39:19 +0200 Subject: [PATCH 6048/9457] MIPS: lantiq: add support for xrx200 firmware depending on soc type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VR9 needs different firmware files for the various phy/soc revisions. Some boards are ship with older and newer SoC revisions. To be able to boot a single image on all versions we need to define both firmware files inside the devicetree. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8045/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/xrx200_phy_fw.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index d4d9d31f152e..7c1e54c6a36c 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c @@ -24,7 +24,28 @@ static dma_addr_t xway_gphy_load(struct platform_device *pdev) void *fw_addr; size_t size; - if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { + if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || + of_get_property(pdev->dev.of_node, "firmware2", NULL)) { + switch (ltq_soc_type()) { + case SOC_TYPE_VR9: + if (of_property_read_string(pdev->dev.of_node, + "firmware1", &fw_name)) { + dev_err(&pdev->dev, + "failed to load firmware filename\n"); + return 0; + } + break; + case SOC_TYPE_VR9_2: + if (of_property_read_string(pdev->dev.of_node, + "firmware2", &fw_name)) { + dev_err(&pdev->dev, + "failed to load firmware filename\n"); + return 0; + } + break; + } + } else if (of_property_read_string(pdev->dev.of_node, + "firmware", &fw_name)) { dev_err(&pdev->dev, "failed to load firmware filename\n"); return 0; } -- GitLab From e8b8ca8cb34486fc27984c402ee89a183ef1b1b7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 10 Sep 2014 22:29:21 +0200 Subject: [PATCH 6049/9457] MIPS: lantiq: export soc type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The voice and dsl drivers need to know which SoC we are running on. Signed-off-by: Álvaro Fernández Rojas Patchwork: http://patchwork.linux-mips.org/patch/8046/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-lantiq/lantiq.h | 2 ++ arch/mips/lantiq/prom.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index f196cceb7322..4e5ae6523cb4 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h @@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void); extern unsigned char ltq_boot_select(void); /* find out what caused the last cpu reset */ extern int ltq_reset_cause(void); +/* find out the soc type */ +extern int ltq_soc_type(void); #define IOPORT_RESOURCE_START 0x10000000 #define IOPORT_RESOURCE_END 0xffffffff diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 758970e3815b..968da50b5111 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -36,6 +36,11 @@ const char *get_system_type(void) return soc_info.sys_type; } +int ltq_soc_type(void) +{ + return soc_info.type; +} + void prom_free_prom_memory(void) { } -- GitLab From d32caf94e0a7029ae3e829d296aa63f9f3c4d9a7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 11 Sep 2014 19:25:25 +0200 Subject: [PATCH 6050/9457] MIPS: lantiq: move eiu init after irq_domain register The eiu init failed as the irq_domain was not yet available. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8047/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 21c38eee0a81..6ab10573490d 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -379,30 +379,6 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) panic("Failed to remap icu memory"); } - /* the external interrupts are optional and xway only */ - eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); - if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { - /* find out how many external irq sources we have */ - exin_avail = of_irq_count(eiu_node); - - if (exin_avail > MAX_EIU) - exin_avail = MAX_EIU; - - ret = of_irq_to_resource_table(eiu_node, - ltq_eiu_irq, exin_avail); - if (ret != exin_avail) - panic("failed to load external irq resources"); - - if (request_mem_region(res.start, resource_size(&res), - res.name) < 0) - pr_err("Failed to request eiu memory"); - - ltq_eiu_membase = ioremap_nocache(res.start, - resource_size(&res)); - if (!ltq_eiu_membase) - panic("Failed to remap eiu memory"); - } - /* turn off all irqs by default */ for (i = 0; i < MAX_IM; i++) { /* make sure all irqs are turned off by default */ @@ -459,6 +435,30 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) if (MIPS_CPU_TIMER_IRQ != 7) irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); + /* the external interrupts are optional and xway only */ + eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); + if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { + /* find out how many external irq sources we have */ + exin_avail = of_irq_count(eiu_node); + + if (exin_avail > MAX_EIU) + exin_avail = MAX_EIU; + + ret = of_irq_to_resource_table(eiu_node, + ltq_eiu_irq, exin_avail); + if (ret != exin_avail) + panic("failed to load external irq resources"); + + if (request_mem_region(res.start, resource_size(&res), + res.name) < 0) + pr_err("Failed to request eiu memory"); + + ltq_eiu_membase = ioremap_nocache(res.start, + resource_size(&res)); + if (!ltq_eiu_membase) + panic("Failed to remap eiu memory"); + } + return 0; } -- GitLab From 17327862f3107b3a2a8ddd586f6b488b3ae37a13 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 10 Oct 2014 23:14:29 +0200 Subject: [PATCH 6051/9457] MIPS: lantiq: copy the commandline from the devicetree This is a regression caused by: commit afb46f7996e91aeb36e07bc92cf96e8045bec00e Author: Rob Herring Date: Wed Apr 2 19:07:24 2014 -0500 mips: ralink: convert to use unflatten_and_copy_device_tree Make the of init code reuse the cmdline defined inside the dts. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8048/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/prom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 968da50b5111..39ab3e786e59 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -77,6 +77,8 @@ void __init plat_mem_setup(void) * parsed resulting in our memory appearing */ __dt_setup_arch(__dtb_start); + + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); } void __init device_tree_init(void) -- GitLab From eb5dbd22b619c01ff15b58b27c8e3409cfc7a20e Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 10 Oct 2014 23:37:52 +0200 Subject: [PATCH 6052/9457] MIPS: lantiq: the detection of the gpe clock is broken The code to detect unfused SoCs was broken due to missing register masking. Signed-off-by: Thomas Langer Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8049/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/falcon/sysctrl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 468ffa043607..7e74760cf2bd 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c @@ -147,12 +147,11 @@ static void falcon_gpe_enable(void) if (status & (1 << (GPPC_OFFSET + 1))) return; - if (status_r32(STATUS_CONFIG) == 0) + freq = (status_r32(STATUS_CONFIG) & + GPEFREQ_MASK) >> + GPEFREQ_OFFSET; + if (freq == 0) freq = 1; /* use 625MHz on unfused chip */ - else - freq = (status_r32(STATUS_CONFIG) & - GPEFREQ_MASK) >> - GPEFREQ_OFFSET; /* apply new frequency */ sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), -- GitLab From 9bc7ebcbf1b963bd8bcbe5c1b8e34f0886656cea Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 10 Oct 2014 23:43:15 +0200 Subject: [PATCH 6053/9457] MIPS: lantiq: add missing spi clock on falcon SoC Signed-off-by: Thomas Langer Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8050/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/falcon/sysctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 7e74760cf2bd..7edcd4946fc1 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c @@ -49,6 +49,7 @@ /* Activation Status Register */ #define ACTS_ASC0_ACT 0x00001000 +#define ACTS_SSC0 0x00002000 #define ACTS_ASC1_ACT 0x00000800 #define ACTS_I2C_ACT 0x00004000 #define ACTS_P0 0x00010000 @@ -259,5 +260,6 @@ void __init ltq_soc_init(void) clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); + clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0); clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); } -- GitLab From 2adf550f2669645eaca7559c9ce7fc2e1dbfc636 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 27 Jul 2014 09:16:50 +0100 Subject: [PATCH 6054/9457] MIPS: ralink: add verbose pmu info Print the PMU and LDO settings on boot. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/7999/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/mt7620.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index a3ad56c2372d..584681709db2 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -20,6 +20,22 @@ #include "common.h" +/* analog */ +#define PMU0_CFG 0x88 +#define PMU_SW_SET BIT(28) +#define A_DCDC_EN BIT(24) +#define A_SSC_PERI BIT(19) +#define A_SSC_GEN BIT(18) +#define A_SSC_M 0x3 +#define A_SSC_S 16 +#define A_DLY_M 0x7 +#define A_DLY_S 8 +#define A_VTUNE_M 0xff + +/* digital */ +#define PMU1_CFG 0x8C +#define DIG_SW_SEL BIT(25) + /* does the board have sdram or ddram */ static int dram_type; @@ -339,6 +355,8 @@ void prom_soc_init(struct ralink_soc_info *soc_info) u32 n1; u32 rev; u32 cfg0; + u32 pmu0; + u32 pmu1; n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); @@ -386,4 +404,12 @@ void prom_soc_init(struct ralink_soc_info *soc_info) BUG(); } soc_info->mem_base = MT7620_DRAM_BASE; + + pmu0 = __raw_readl(sysc + PMU0_CFG); + pmu1 = __raw_readl(sysc + PMU1_CFG); + + pr_info("Analog PMU set to %s control\n", + (pmu0 & PMU_SW_SET) ? ("sw") : ("hw")); + pr_info("Digital PMU set to %s control\n", + (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); } -- GitLab From 2920b83d35e24ec80777625ab809ce7dcf08a84a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 16 Mar 2014 04:53:02 +0000 Subject: [PATCH 6055/9457] MIPS: ralink: add a helper for reading the ECO version Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8000/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ralink/mt7620.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 6f9b24f51157..7ff929005d15 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h @@ -105,4 +105,9 @@ #define MT7620_GPIO_MODE_EPHY BIT(15) #define MT7620_GPIO_MODE_WDT BIT(22) +static inline int mt7620_get_eco(void) +{ + return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; +} + #endif -- GitLab From 47e14d6678306f652d18230c101083e120402d92 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 19 May 2013 00:42:23 +0200 Subject: [PATCH 6056/9457] MIPS: ralink: add rt_sysc_m32 helper We already have a read and write wrapper. This adds the missing mask wrapper. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8001/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ralink/ralink_regs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index 5a508f9f9432..bd93014490df 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h @@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg) return __raw_readl(rt_sysc_membase + reg); } +static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg) +{ + u32 val = rt_sysc_r32(reg) & ~clr; + + __raw_writel(val | set, rt_sysc_membase + reg); +} + static inline void rt_memc_w32(u32 val, unsigned reg) { __raw_writel(val, rt_memc_membase + reg); -- GitLab From 5433acd81e8733ede365ad41318f96175ed16b3a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 16 May 2013 23:28:23 +0200 Subject: [PATCH 6057/9457] MIPS: ralink: add illegal access driver These SoCs have a special irq that fires upon an illegal memmory access. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8003/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/Makefile | 2 + arch/mips/ralink/ill_acc.c | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 arch/mips/ralink/ill_acc.c diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 2c09c8aa0ae2..833fa677e6b8 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile @@ -10,6 +10,8 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o +obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o + obj-$(CONFIG_SOC_RT288X) += rt288x.o obj-$(CONFIG_SOC_RT305X) += rt305x.o obj-$(CONFIG_SOC_RT3883) += rt3883.o diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c new file mode 100644 index 000000000000..e20b02e3ae28 --- /dev/null +++ b/arch/mips/ralink/ill_acc.c @@ -0,0 +1,87 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Copyright (C) 2013 John Crispin + */ + +#include +#include +#include + +#include + +#define REG_ILL_ACC_ADDR 0x10 +#define REG_ILL_ACC_TYPE 0x14 + +#define ILL_INT_STATUS BIT(31) +#define ILL_ACC_WRITE BIT(30) +#define ILL_ACC_LEN_M 0xff +#define ILL_ACC_OFF_M 0xf +#define ILL_ACC_OFF_S 16 +#define ILL_ACC_ID_M 0x7 +#define ILL_ACC_ID_S 8 + +#define DRV_NAME "ill_acc" + +static const char * const ill_acc_ids[] = { + "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb", +}; + +static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) +{ + struct device *dev = (struct device *) _priv; + u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR); + u32 type = rt_memc_r32(REG_ILL_ACC_TYPE); + + dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n", + (type & ILL_ACC_WRITE) ? ("write") : ("read"), + ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M], + addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, + type & ILL_ACC_LEN_M); + + rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); + + return IRQ_HANDLED; +} + +static int __init ill_acc_of_setup(void) +{ + struct platform_device *pdev; + struct device_node *np; + int irq; + + /* somehow this driver breaks on RT5350 */ + if (of_machine_is_compatible("ralink,rt5350-soc")) + return -EINVAL; + + np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc"); + if (!np) + return -EINVAL; + + pdev = of_find_device_by_node(np); + if (!pdev) { + pr_err("%s: failed to lookup pdev\n", np->name); + return -EINVAL; + } + + irq = irq_of_parse_and_map(np, 0); + if (!irq) { + dev_err(&pdev->dev, "failed to get irq\n"); + return -EINVAL; + } + + if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) { + dev_err(&pdev->dev, "failed to request irq\n"); + return -EINVAL; + } + + rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); + + dev_info(&pdev->dev, "irq registered\n"); + + return 0; +} + +arch_initcall(ill_acc_of_setup); -- GitLab From 15d11120703df3e78c766c7247058f4903001c56 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 8 Oct 2014 22:40:02 +0200 Subject: [PATCH 6058/9457] MIPS: ralink: allow manual memory override RT5350 relies on the bootloader setting up the memc correctly. On some boards the setup is incorrect leading to 32 MB being available but only 16 MB being recognized. Allow these boards to manually override the memory range. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8004/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/of.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index f68115fd98ef..f9eda5d8f82c 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -53,6 +53,17 @@ void __init device_tree_init(void) unflatten_and_copy_device_tree(); } +static int memory_dtb; + +static int __init early_init_dt_find_memory(unsigned long node, + const char *uname, int depth, void *data) +{ + if (depth == 1 && !strcmp(uname, "memory@0")) + memory_dtb = 1; + + return 0; +} + void __init plat_mem_setup(void) { set_io_port_base(KSEG1); @@ -63,7 +74,10 @@ void __init plat_mem_setup(void) */ __dt_setup_arch(__dtb_start); - if (soc_info.mem_size) + of_scan_flat_dt(early_init_dt_find_memory, NULL); + if (memory_dtb) + of_scan_flat_dt(early_init_dt_scan_memory, NULL); + else if (soc_info.mem_size) add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, BOOT_MEM_RAM); else -- GitLab From a8b6204761dba0cbf7b859b4f8d3dd52624b4100 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 16 Mar 2014 04:38:07 +0000 Subject: [PATCH 6059/9457] MIPS: ralink: add missing clk_set_rate() to clk.c This function was missing causing make allmod to fail. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8005/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/clk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index 5d0983d47161..feb5a9bf98b4 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c @@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_get_rate); +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return -1; +} +EXPORT_SYMBOL_GPL(clk_set_rate); + void __init plat_time_init(void) { struct clk *clk; -- GitLab From f2a8bd2e924191293984a4b05e49589260a7accf Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 4 Aug 2014 09:52:22 +0200 Subject: [PATCH 6060/9457] MIPS: ralink: add rt2880 wmac clock Register the wireleass mac clock on rt2880. This is required by the wifi driver. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8006/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/rt288x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index f87de1ab2198..90e89349bd18 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c @@ -76,7 +76,7 @@ struct ralink_pinmux rt_gpio_pinmux = { void __init ralink_clk_init(void) { - unsigned long cpu_rate; + unsigned long cpu_rate, wmac_rate = 40000000; u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); @@ -101,6 +101,7 @@ void __init ralink_clk_init(void) ralink_clk_add("300500.uart", cpu_rate / 2); ralink_clk_add("300c00.uartlite", cpu_rate / 2); ralink_clk_add("400000.ethernet", cpu_rate / 2); + ralink_clk_add("480000.wmac", wmac_rate); } void __init ralink_of_remap(void) -- GitLab From 1e209c969a40c1eeb789515d01d8dd1427982a54 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 27 Jul 2014 10:14:30 +0100 Subject: [PATCH 6061/9457] MIPS: ralink: add rt3883 wmac clock Register the wireless mac clock on rti3883. This is required by the wifi driver. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8007/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/rt3883.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index b474ac284b83..58b5b9f464a1 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c @@ -204,6 +204,7 @@ void __init ralink_clk_init(void) ralink_clk_add("10000b00.spi", sys_rate); ralink_clk_add("10000c00.uartlite", 40000000); ralink_clk_add("10100000.ethernet", sys_rate); + ralink_clk_add("10180000.wmac", 40000000); } void __init ralink_of_remap(void) -- GitLab From 7a1a44c909fcb4707b01448a28490d7be366b530 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 21 May 2013 15:50:31 +0200 Subject: [PATCH 6062/9457] MIPS: ralink: add a bootrom dumper module This patch adds a trivial driver that allows userland to extract the bootrom of a SoC via debugfs. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8002/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/Makefile | 2 ++ arch/mips/ralink/bootrom.c | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 arch/mips/ralink/bootrom.c diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 833fa677e6b8..a6c9d0061326 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile @@ -18,3 +18,5 @@ obj-$(CONFIG_SOC_RT3883) += rt3883.o obj-$(CONFIG_SOC_MT7620) += mt7620.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +obj-$(CONFIG_DEBUG_FS) += bootrom.o diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c new file mode 100644 index 000000000000..5403468394fb --- /dev/null +++ b/arch/mips/ralink/bootrom.c @@ -0,0 +1,48 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Copyright (C) 2013 John Crispin + */ + +#include +#include + +#define BOOTROM_OFFSET 0x10118000 +#define BOOTROM_SIZE 0x8000 + +static void __iomem *membase = (void __iomem *) KSEG1ADDR(BOOTROM_OFFSET); + +static int bootrom_show(struct seq_file *s, void *unused) +{ + seq_write(s, membase, BOOTROM_SIZE); + + return 0; +} + +static int bootrom_open(struct inode *inode, struct file *file) +{ + return single_open(file, bootrom_show, NULL); +} + +static const struct file_operations bootrom_file_ops = { + .open = bootrom_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int bootrom_setup(void) +{ + if (!debugfs_create_file("bootrom", 0444, + NULL, NULL, &bootrom_file_ops)) { + pr_err("Failed to create bootrom debugfs file\n"); + + return -EINVAL; + } + + return 0; +} + +postcore_initcall(bootrom_setup); -- GitLab From 4248f7f121b755b272a3c77a1a5601faa6004350 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 8 Oct 2014 23:28:51 +0200 Subject: [PATCH 6063/9457] MIPS: ralink: copy the commandline from the devicetree This is a regression caused by: commit afb46f7996e91aeb36e07bc92cf96e8045bec00e Author: Rob Herring Date: Wed Apr 2 19:07:24 2014 -0500 mips: ralink: convert to use unflatten_and_copy_device_tree Make the of init code reuse the cmdline defined inside the dts. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8008/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/of.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index f9eda5d8f82c..0d30dcd63246 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -74,6 +74,8 @@ void __init plat_mem_setup(void) */ __dt_setup_arch(__dtb_start); + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); + of_scan_flat_dt(early_init_dt_find_memory, NULL); if (memory_dtb) of_scan_flat_dt(early_init_dt_scan_memory, NULL); -- GitLab From f576fb6a0700c76a68ca7b45a3cfbd70399b24ab Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 9 Oct 2014 04:02:53 +0200 Subject: [PATCH 6064/9457] MIPS: ralink: cleanup the soc specific pinmux data Before we had a pinctrl driver we used a custom OF api. This patch converts the soc specific pinmux data to a new set of structs. We also add some new pinmux setings. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8009/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ralink/mt7620.h | 41 +++-- arch/mips/include/asm/mach-ralink/pinmux.h | 55 +++++++ arch/mips/include/asm/mach-ralink/rt305x.h | 35 +++-- arch/mips/include/asm/mach-ralink/rt3883.h | 16 +- arch/mips/ralink/common.h | 19 --- arch/mips/ralink/mt7620.c | 159 ++++++------------- arch/mips/ralink/prom.c | 1 + arch/mips/ralink/rt288x.c | 62 +++----- arch/mips/ralink/rt305x.c | 153 ++++++++---------- arch/mips/ralink/rt3883.c | 173 +++++---------------- 10 files changed, 294 insertions(+), 420 deletions(-) create mode 100644 arch/mips/include/asm/mach-ralink/pinmux.h diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 7ff929005d15..a05c14c23155 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h @@ -82,7 +82,6 @@ #define MT7620_DDR2_SIZE_MIN 32 #define MT7620_DDR2_SIZE_MAX 256 -#define MT7620_GPIO_MODE_I2C BIT(0) #define MT7620_GPIO_MODE_UART0_SHIFT 2 #define MT7620_GPIO_MODE_UART0_MASK 0x7 #define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) @@ -94,16 +93,36 @@ #define MT7620_GPIO_MODE_GPIO_UARTF 0x5 #define MT7620_GPIO_MODE_GPIO_I2S 0x6 #define MT7620_GPIO_MODE_GPIO 0x7 -#define MT7620_GPIO_MODE_UART1 BIT(5) -#define MT7620_GPIO_MODE_MDIO BIT(8) -#define MT7620_GPIO_MODE_RGMII1 BIT(9) -#define MT7620_GPIO_MODE_RGMII2 BIT(10) -#define MT7620_GPIO_MODE_SPI BIT(11) -#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) -#define MT7620_GPIO_MODE_WLED BIT(13) -#define MT7620_GPIO_MODE_JTAG BIT(15) -#define MT7620_GPIO_MODE_EPHY BIT(15) -#define MT7620_GPIO_MODE_WDT BIT(22) + +#define MT7620_GPIO_MODE_NAND 0 +#define MT7620_GPIO_MODE_SD 1 +#define MT7620_GPIO_MODE_ND_SD_GPIO 2 +#define MT7620_GPIO_MODE_ND_SD_MASK 0x3 +#define MT7620_GPIO_MODE_ND_SD_SHIFT 18 + +#define MT7620_GPIO_MODE_PCIE_RST 0 +#define MT7620_GPIO_MODE_PCIE_REF 1 +#define MT7620_GPIO_MODE_PCIE_GPIO 2 +#define MT7620_GPIO_MODE_PCIE_MASK 0x3 +#define MT7620_GPIO_MODE_PCIE_SHIFT 16 + +#define MT7620_GPIO_MODE_WDT_RST 0 +#define MT7620_GPIO_MODE_WDT_REF 1 +#define MT7620_GPIO_MODE_WDT_GPIO 2 +#define MT7620_GPIO_MODE_WDT_MASK 0x3 +#define MT7620_GPIO_MODE_WDT_SHIFT 21 + +#define MT7620_GPIO_MODE_I2C 0 +#define MT7620_GPIO_MODE_UART1 5 +#define MT7620_GPIO_MODE_MDIO 8 +#define MT7620_GPIO_MODE_RGMII1 9 +#define MT7620_GPIO_MODE_RGMII2 10 +#define MT7620_GPIO_MODE_SPI 11 +#define MT7620_GPIO_MODE_SPI_REF_CLK 12 +#define MT7620_GPIO_MODE_WLED 13 +#define MT7620_GPIO_MODE_JTAG 15 +#define MT7620_GPIO_MODE_EPHY 15 +#define MT7620_GPIO_MODE_PA 20 static inline int mt7620_get_eco(void) { diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h new file mode 100644 index 000000000000..be106cb2e26d --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/pinmux.h @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2012 John Crispin + */ + +#ifndef _RT288X_PINMUX_H__ +#define _RT288X_PINMUX_H__ + +#define FUNC(name, value, pin_first, pin_count) \ + { name, value, pin_first, pin_count } + +#define GRP(_name, _func, _mask, _shift) \ + { .name = _name, .mask = _mask, .shift = _shift, \ + .func = _func, .gpio = _mask, \ + .func_count = ARRAY_SIZE(_func) } + +#define GRP_G(_name, _func, _mask, _gpio, _shift) \ + { .name = _name, .mask = _mask, .shift = _shift, \ + .func = _func, .gpio = _gpio, \ + .func_count = ARRAY_SIZE(_func) } + +struct rt2880_pmx_group; + +struct rt2880_pmx_func { + const char *name; + const char value; + + int pin_first; + int pin_count; + int *pins; + + int *groups; + int group_count; + + int enabled; +}; + +struct rt2880_pmx_group { + const char *name; + int enabled; + + const u32 shift; + const char mask; + const char gpio; + + struct rt2880_pmx_func *func; + int func_count; +}; + +extern struct rt2880_pmx_group *rt2880_pinmux_data; + +#endif diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h index 069bf37a6010..96f731bac79a 100644 --- a/arch/mips/include/asm/mach-ralink/rt305x.h +++ b/arch/mips/include/asm/mach-ralink/rt305x.h @@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void) #define RT305X_GPIO_GE0_TXD0 40 #define RT305X_GPIO_GE0_RXCLK 51 -#define RT305X_GPIO_MODE_I2C BIT(0) -#define RT305X_GPIO_MODE_SPI BIT(1) #define RT305X_GPIO_MODE_UART0_SHIFT 2 #define RT305X_GPIO_MODE_UART0_MASK 0x7 #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) -#define RT305X_GPIO_MODE_UARTF 0x0 -#define RT305X_GPIO_MODE_PCM_UARTF 0x1 -#define RT305X_GPIO_MODE_PCM_I2S 0x2 -#define RT305X_GPIO_MODE_I2S_UARTF 0x3 -#define RT305X_GPIO_MODE_PCM_GPIO 0x4 -#define RT305X_GPIO_MODE_GPIO_UARTF 0x5 -#define RT305X_GPIO_MODE_GPIO_I2S 0x6 -#define RT305X_GPIO_MODE_GPIO 0x7 -#define RT305X_GPIO_MODE_UART1 BIT(5) -#define RT305X_GPIO_MODE_JTAG BIT(6) -#define RT305X_GPIO_MODE_MDIO BIT(7) -#define RT305X_GPIO_MODE_SDRAM BIT(8) -#define RT305X_GPIO_MODE_RGMII BIT(9) +#define RT305X_GPIO_MODE_UARTF 0 +#define RT305X_GPIO_MODE_PCM_UARTF 1 +#define RT305X_GPIO_MODE_PCM_I2S 2 +#define RT305X_GPIO_MODE_I2S_UARTF 3 +#define RT305X_GPIO_MODE_PCM_GPIO 4 +#define RT305X_GPIO_MODE_GPIO_UARTF 5 +#define RT305X_GPIO_MODE_GPIO_I2S 6 +#define RT305X_GPIO_MODE_GPIO 7 + +#define RT305X_GPIO_MODE_I2C 0 +#define RT305X_GPIO_MODE_SPI 1 +#define RT305X_GPIO_MODE_UART1 5 +#define RT305X_GPIO_MODE_JTAG 6 +#define RT305X_GPIO_MODE_MDIO 7 +#define RT305X_GPIO_MODE_SDRAM 8 +#define RT305X_GPIO_MODE_RGMII 9 +#define RT5350_GPIO_MODE_PHY_LED 14 +#define RT5350_GPIO_MODE_SPI_CS1 21 +#define RT3352_GPIO_MODE_LNA 18 +#define RT3352_GPIO_MODE_PA 20 #define RT3352_SYSC_REG_SYSCFG0 0x010 #define RT3352_SYSC_REG_SYSCFG1 0x014 diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h index 058382f37f92..0fbe6f9257cd 100644 --- a/arch/mips/include/asm/mach-ralink/rt3883.h +++ b/arch/mips/include/asm/mach-ralink/rt3883.h @@ -112,8 +112,6 @@ #define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) #define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) -#define RT3883_GPIO_MODE_I2C BIT(0) -#define RT3883_GPIO_MODE_SPI BIT(1) #define RT3883_GPIO_MODE_UART0_SHIFT 2 #define RT3883_GPIO_MODE_UART0_MASK 0x7 #define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) @@ -125,11 +123,15 @@ #define RT3883_GPIO_MODE_GPIO_UARTF 0x5 #define RT3883_GPIO_MODE_GPIO_I2S 0x6 #define RT3883_GPIO_MODE_GPIO 0x7 -#define RT3883_GPIO_MODE_UART1 BIT(5) -#define RT3883_GPIO_MODE_JTAG BIT(6) -#define RT3883_GPIO_MODE_MDIO BIT(7) -#define RT3883_GPIO_MODE_GE1 BIT(9) -#define RT3883_GPIO_MODE_GE2 BIT(10) + +#define RT3883_GPIO_MODE_I2C 0 +#define RT3883_GPIO_MODE_SPI 1 +#define RT3883_GPIO_MODE_UART1 5 +#define RT3883_GPIO_MODE_JTAG 6 +#define RT3883_GPIO_MODE_MDIO 7 +#define RT3883_GPIO_MODE_GE1 9 +#define RT3883_GPIO_MODE_GE2 10 + #define RT3883_GPIO_MODE_PCI_SHIFT 11 #define RT3883_GPIO_MODE_PCI_MASK 0x7 #define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 42dfd6100a2d..8e7d8e618fb9 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h @@ -11,25 +11,6 @@ #define RAMIPS_SYS_TYPE_LEN 32 -struct ralink_pinmux_grp { - const char *name; - u32 mask; - int gpio_first; - int gpio_last; -}; - -struct ralink_pinmux { - struct ralink_pinmux_grp *mode; - struct ralink_pinmux_grp *uart; - int uart_shift; - u32 uart_mask; - void (*wdt_reset)(void); - struct ralink_pinmux_grp *pci; - int pci_shift; - u32 pci_mask; -}; -extern struct ralink_pinmux rt_gpio_pinmux; - struct ralink_soc_info { unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; unsigned char *compatible; diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index 584681709db2..24fb40a441ca 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "common.h" @@ -39,118 +40,58 @@ /* does the board have sdram or ddram */ static int dram_type; -static struct ralink_pinmux_grp mode_mux[] = { - { - .name = "i2c", - .mask = MT7620_GPIO_MODE_I2C, - .gpio_first = 1, - .gpio_last = 2, - }, { - .name = "spi", - .mask = MT7620_GPIO_MODE_SPI, - .gpio_first = 3, - .gpio_last = 6, - }, { - .name = "uartlite", - .mask = MT7620_GPIO_MODE_UART1, - .gpio_first = 15, - .gpio_last = 16, - }, { - .name = "wdt", - .mask = MT7620_GPIO_MODE_WDT, - .gpio_first = 17, - .gpio_last = 17, - }, { - .name = "mdio", - .mask = MT7620_GPIO_MODE_MDIO, - .gpio_first = 22, - .gpio_last = 23, - }, { - .name = "rgmii1", - .mask = MT7620_GPIO_MODE_RGMII1, - .gpio_first = 24, - .gpio_last = 35, - }, { - .name = "spi refclk", - .mask = MT7620_GPIO_MODE_SPI_REF_CLK, - .gpio_first = 37, - .gpio_last = 39, - }, { - .name = "jtag", - .mask = MT7620_GPIO_MODE_JTAG, - .gpio_first = 40, - .gpio_last = 44, - }, { - /* shared lines with jtag */ - .name = "ephy", - .mask = MT7620_GPIO_MODE_EPHY, - .gpio_first = 40, - .gpio_last = 44, - }, { - .name = "nand", - .mask = MT7620_GPIO_MODE_JTAG, - .gpio_first = 45, - .gpio_last = 59, - }, { - .name = "rgmii2", - .mask = MT7620_GPIO_MODE_RGMII2, - .gpio_first = 60, - .gpio_last = 71, - }, { - .name = "wled", - .mask = MT7620_GPIO_MODE_WLED, - .gpio_first = 72, - .gpio_last = 72, - }, {0} +static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) }; +static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) }; +static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) }; +static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) }; +static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) }; +static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) }; +static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) }; +static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) }; +static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) }; +static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) }; +static struct rt2880_pmx_func uartf_grp[] = { + FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8), + FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8), + FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8), + FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8), + FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4), + FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4), + FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4), }; - -static struct ralink_pinmux_grp uart_mux[] = { - { - .name = "uartf", - .mask = MT7620_GPIO_MODE_UARTF, - .gpio_first = 7, - .gpio_last = 14, - }, { - .name = "pcm uartf", - .mask = MT7620_GPIO_MODE_PCM_UARTF, - .gpio_first = 7, - .gpio_last = 14, - }, { - .name = "pcm i2s", - .mask = MT7620_GPIO_MODE_PCM_I2S, - .gpio_first = 7, - .gpio_last = 14, - }, { - .name = "i2s uartf", - .mask = MT7620_GPIO_MODE_I2S_UARTF, - .gpio_first = 7, - .gpio_last = 14, - }, { - .name = "pcm gpio", - .mask = MT7620_GPIO_MODE_PCM_GPIO, - .gpio_first = 11, - .gpio_last = 14, - }, { - .name = "gpio uartf", - .mask = MT7620_GPIO_MODE_GPIO_UARTF, - .gpio_first = 7, - .gpio_last = 10, - }, { - .name = "gpio i2s", - .mask = MT7620_GPIO_MODE_GPIO_I2S, - .gpio_first = 7, - .gpio_last = 10, - }, { - .name = "gpio", - .mask = MT7620_GPIO_MODE_GPIO, - }, {0} +static struct rt2880_pmx_func wdt_grp[] = { + FUNC("wdt rst", 0, 17, 1), + FUNC("wdt refclk", 0, 17, 1), + }; +static struct rt2880_pmx_func pcie_rst_grp[] = { + FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1), + FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1) +}; +static struct rt2880_pmx_func nd_sd_grp[] = { + FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15), + FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15) }; -struct ralink_pinmux rt_gpio_pinmux = { - .mode = mode_mux, - .uart = uart_mux, - .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, - .uart_mask = MT7620_GPIO_MODE_UART0_MASK, +static struct rt2880_pmx_group mt7620a_pinmux_data[] = { + GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C), + GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK, + MT7620_GPIO_MODE_UART0_SHIFT), + GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI), + GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1), + GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK, + MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT), + GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO), + GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1), + GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK), + GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK, + MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT), + GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK, + MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT), + GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2), + GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED), + GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY), + GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA), + { 0 } }; static __init u32 diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c index 9c64f029d047..09419f67da39 100644 --- a/arch/mips/ralink/prom.c +++ b/arch/mips/ralink/prom.c @@ -18,6 +18,7 @@ #include "common.h" struct ralink_soc_info soc_info; +struct rt2880_pmx_group *rt2880_pinmux_data = NULL; const char *get_system_type(void) { diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index 90e89349bd18..738cec865f41 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c @@ -17,46 +17,27 @@ #include #include #include +#include #include "common.h" -static struct ralink_pinmux_grp mode_mux[] = { - { - .name = "i2c", - .mask = RT2880_GPIO_MODE_I2C, - .gpio_first = 1, - .gpio_last = 2, - }, { - .name = "spi", - .mask = RT2880_GPIO_MODE_SPI, - .gpio_first = 3, - .gpio_last = 6, - }, { - .name = "uartlite", - .mask = RT2880_GPIO_MODE_UART0, - .gpio_first = 7, - .gpio_last = 14, - }, { - .name = "jtag", - .mask = RT2880_GPIO_MODE_JTAG, - .gpio_first = 17, - .gpio_last = 21, - }, { - .name = "mdio", - .mask = RT2880_GPIO_MODE_MDIO, - .gpio_first = 22, - .gpio_last = 23, - }, { - .name = "sdram", - .mask = RT2880_GPIO_MODE_SDRAM, - .gpio_first = 24, - .gpio_last = 39, - }, { - .name = "pci", - .mask = RT2880_GPIO_MODE_PCI, - .gpio_first = 40, - .gpio_last = 71, - }, {0} +static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; +static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; +static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) }; +static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; +static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; +static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; +static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) }; + +static struct rt2880_pmx_group rt2880_pinmux_data_act[] = { + GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C), + GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI), + GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0), + GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG), + GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO), + GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM), + GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI), + { 0 } }; static void rt288x_wdt_reset(void) @@ -69,11 +50,6 @@ static void rt288x_wdt_reset(void) rt_sysc_w32(t, SYSC_REG_CLKCFG); } -struct ralink_pinmux rt_gpio_pinmux = { - .mode = mode_mux, - .wdt_reset = rt288x_wdt_reset, -}; - void __init ralink_clk_init(void) { unsigned long cpu_rate, wmac_rate = 40000000; @@ -141,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) soc_info->mem_base = RT2880_SDRAM_BASE; soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; + + rt2880_pinmux_data = rt2880_pinmux_data_act; } diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index bb82a82da9e7..c40776ab67db 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c @@ -17,90 +17,78 @@ #include #include #include +#include #include "common.h" enum rt305x_soc_type rt305x_soc; -static struct ralink_pinmux_grp mode_mux[] = { - { - .name = "i2c", - .mask = RT305X_GPIO_MODE_I2C, - .gpio_first = RT305X_GPIO_I2C_SD, - .gpio_last = RT305X_GPIO_I2C_SCLK, - }, { - .name = "spi", - .mask = RT305X_GPIO_MODE_SPI, - .gpio_first = RT305X_GPIO_SPI_EN, - .gpio_last = RT305X_GPIO_SPI_CLK, - }, { - .name = "uartlite", - .mask = RT305X_GPIO_MODE_UART1, - .gpio_first = RT305X_GPIO_UART1_TXD, - .gpio_last = RT305X_GPIO_UART1_RXD, - }, { - .name = "jtag", - .mask = RT305X_GPIO_MODE_JTAG, - .gpio_first = RT305X_GPIO_JTAG_TDO, - .gpio_last = RT305X_GPIO_JTAG_TDI, - }, { - .name = "mdio", - .mask = RT305X_GPIO_MODE_MDIO, - .gpio_first = RT305X_GPIO_MDIO_MDC, - .gpio_last = RT305X_GPIO_MDIO_MDIO, - }, { - .name = "sdram", - .mask = RT305X_GPIO_MODE_SDRAM, - .gpio_first = RT305X_GPIO_SDRAM_MD16, - .gpio_last = RT305X_GPIO_SDRAM_MD31, - }, { - .name = "rgmii", - .mask = RT305X_GPIO_MODE_RGMII, - .gpio_first = RT305X_GPIO_GE0_TXD0, - .gpio_last = RT305X_GPIO_GE0_RXCLK, - }, {0} +static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; +static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; +static struct rt2880_pmx_func uartf_func[] = { + FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8), + FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8), + FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8), + FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8), + FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4), + FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4), + FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4), +}; +static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; +static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; +static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; +static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) }; +static struct rt2880_pmx_func rt5350_cs1_func[] = { + FUNC("spi_cs1", 0, 27, 1), + FUNC("wdg_cs1", 1, 27, 1), +}; +static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; +static struct rt2880_pmx_func rt3352_rgmii_func[] = { + FUNC("rgmii", 0, 24, 12) +}; +static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) }; +static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) }; +static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) }; +static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) }; + +static struct rt2880_pmx_group rt3050_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), + GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), + GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, + RT305X_GPIO_MODE_UART0_SHIFT), + GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), + GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), + GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), + GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII), + GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM), + { 0 } }; -static struct ralink_pinmux_grp uart_mux[] = { - { - .name = "uartf", - .mask = RT305X_GPIO_MODE_UARTF, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, - }, { - .name = "pcm uartf", - .mask = RT305X_GPIO_MODE_PCM_UARTF, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, - }, { - .name = "pcm i2s", - .mask = RT305X_GPIO_MODE_PCM_I2S, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, - }, { - .name = "i2s uartf", - .mask = RT305X_GPIO_MODE_I2S_UARTF, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, - }, { - .name = "pcm gpio", - .mask = RT305X_GPIO_MODE_PCM_GPIO, - .gpio_first = RT305X_GPIO_10, - .gpio_last = RT305X_GPIO_14, - }, { - .name = "gpio uartf", - .mask = RT305X_GPIO_MODE_GPIO_UARTF, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_10, - }, { - .name = "gpio i2s", - .mask = RT305X_GPIO_MODE_GPIO_I2S, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_10, - }, { - .name = "gpio", - .mask = RT305X_GPIO_MODE_GPIO, - }, {0} +static struct rt2880_pmx_group rt3352_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), + GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), + GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, + RT305X_GPIO_MODE_UART0_SHIFT), + GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), + GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), + GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), + GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII), + GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA), + GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA), + GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED), + { 0 } +}; + +static struct rt2880_pmx_group rt5350_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), + GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), + GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, + RT305X_GPIO_MODE_UART0_SHIFT), + GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), + GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), + GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED), + GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1), + { 0 } }; static void rt305x_wdt_reset(void) @@ -114,14 +102,6 @@ static void rt305x_wdt_reset(void) rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); } -struct ralink_pinmux rt_gpio_pinmux = { - .mode = mode_mux, - .uart = uart_mux, - .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, - .uart_mask = RT305X_GPIO_MODE_UART0_MASK, - .wdt_reset = rt305x_wdt_reset, -}; - static unsigned long rt5350_get_mem_size(void) { void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); @@ -290,11 +270,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info) soc_info->mem_base = RT305X_SDRAM_BASE; if (soc_is_rt5350()) { soc_info->mem_size = rt5350_get_mem_size(); + rt2880_pinmux_data = rt5350_pinmux_data; } else if (soc_is_rt305x() || soc_is_rt3350()) { soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; + rt2880_pinmux_data = rt3050_pinmux_data; } else if (soc_is_rt3352()) { soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; + rt2880_pinmux_data = rt3352_pinmux_data; } } diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index 58b5b9f464a1..86a535c770d8 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c @@ -17,132 +17,50 @@ #include #include #include +#include #include "common.h" -static struct ralink_pinmux_grp mode_mux[] = { - { - .name = "i2c", - .mask = RT3883_GPIO_MODE_I2C, - .gpio_first = RT3883_GPIO_I2C_SD, - .gpio_last = RT3883_GPIO_I2C_SCLK, - }, { - .name = "spi", - .mask = RT3883_GPIO_MODE_SPI, - .gpio_first = RT3883_GPIO_SPI_CS0, - .gpio_last = RT3883_GPIO_SPI_MISO, - }, { - .name = "uartlite", - .mask = RT3883_GPIO_MODE_UART1, - .gpio_first = RT3883_GPIO_UART1_TXD, - .gpio_last = RT3883_GPIO_UART1_RXD, - }, { - .name = "jtag", - .mask = RT3883_GPIO_MODE_JTAG, - .gpio_first = RT3883_GPIO_JTAG_TDO, - .gpio_last = RT3883_GPIO_JTAG_TCLK, - }, { - .name = "mdio", - .mask = RT3883_GPIO_MODE_MDIO, - .gpio_first = RT3883_GPIO_MDIO_MDC, - .gpio_last = RT3883_GPIO_MDIO_MDIO, - }, { - .name = "ge1", - .mask = RT3883_GPIO_MODE_GE1, - .gpio_first = RT3883_GPIO_GE1_TXD0, - .gpio_last = RT3883_GPIO_GE1_RXCLK, - }, { - .name = "ge2", - .mask = RT3883_GPIO_MODE_GE2, - .gpio_first = RT3883_GPIO_GE2_TXD0, - .gpio_last = RT3883_GPIO_GE2_RXCLK, - }, { - .name = "pci", - .mask = RT3883_GPIO_MODE_PCI, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, { - .name = "lna a", - .mask = RT3883_GPIO_MODE_LNA_A, - .gpio_first = RT3883_GPIO_LNA_PE_A0, - .gpio_last = RT3883_GPIO_LNA_PE_A2, - }, { - .name = "lna g", - .mask = RT3883_GPIO_MODE_LNA_G, - .gpio_first = RT3883_GPIO_LNA_PE_G0, - .gpio_last = RT3883_GPIO_LNA_PE_G2, - }, {0} +static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; +static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; +static struct rt2880_pmx_func uartf_func[] = { + FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8), + FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8), + FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8), + FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8), + FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4), + FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4), + FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4), }; - -static struct ralink_pinmux_grp uart_mux[] = { - { - .name = "uartf", - .mask = RT3883_GPIO_MODE_UARTF, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_14, - }, { - .name = "pcm uartf", - .mask = RT3883_GPIO_MODE_PCM_UARTF, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_14, - }, { - .name = "pcm i2s", - .mask = RT3883_GPIO_MODE_PCM_I2S, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_14, - }, { - .name = "i2s uartf", - .mask = RT3883_GPIO_MODE_I2S_UARTF, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_14, - }, { - .name = "pcm gpio", - .mask = RT3883_GPIO_MODE_PCM_GPIO, - .gpio_first = RT3883_GPIO_11, - .gpio_last = RT3883_GPIO_14, - }, { - .name = "gpio uartf", - .mask = RT3883_GPIO_MODE_GPIO_UARTF, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_10, - }, { - .name = "gpio i2s", - .mask = RT3883_GPIO_MODE_GPIO_I2S, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_10, - }, { - .name = "gpio", - .mask = RT3883_GPIO_MODE_GPIO, - }, {0} +static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; +static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; +static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; +static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; +static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; +static struct rt2880_pmx_func pci_func[] = { + FUNC("pci-dev", 0, 40, 32), + FUNC("pci-host2", 1, 40, 32), + FUNC("pci-host1", 2, 40, 32), + FUNC("pci-fnc", 3, 40, 32) }; - -static struct ralink_pinmux_grp pci_mux[] = { - { - .name = "pci-dev", - .mask = 0, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, { - .name = "pci-host2", - .mask = 1, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, { - .name = "pci-host1", - .mask = 2, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, { - .name = "pci-fnc", - .mask = 3, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, { - .name = "pci-gpio", - .mask = 7, - .gpio_first = RT3883_GPIO_PCI_AD0, - .gpio_last = RT3883_GPIO_PCI_AD31, - }, {0} +static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; +static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; + +static struct rt2880_pmx_group rt3883_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), + GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI), + GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK, + RT3883_GPIO_MODE_UART0_SHIFT), + GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1), + GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG), + GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO), + GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A), + GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G), + GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK, + RT3883_GPIO_MODE_PCI_SHIFT), + GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1), + GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2), + { 0 } }; static void rt3883_wdt_reset(void) @@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void) rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); } -struct ralink_pinmux rt_gpio_pinmux = { - .mode = mode_mux, - .uart = uart_mux, - .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, - .uart_mask = RT3883_GPIO_MODE_UART0_MASK, - .wdt_reset = rt3883_wdt_reset, - .pci = pci_mux, - .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT, - .pci_mask = RT3883_GPIO_MODE_PCI_MASK, -}; - void __init ralink_clk_init(void) { unsigned long cpu_rate, sys_rate; @@ -244,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) soc_info->mem_base = RT3883_SDRAM_BASE; soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; + + rt2880_pinmux_data = rt3883_pinmux_data; } -- GitLab From a097b13c52a3607123d9c65534b7befe493c6d84 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 24 Jan 2014 17:01:17 +0100 Subject: [PATCH 6065/9457] MIPS: ralink: cleanup early_printk Add support for the new MT7621/8 SoC and kill ifdefs. Cleanup some whitespace error while we are at it. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8028/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/early_printk.c | 45 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c index b46d0419d09b..255d695ec8c6 100644 --- a/arch/mips/ralink/early_printk.c +++ b/arch/mips/ralink/early_printk.c @@ -12,21 +12,24 @@ #include #ifdef CONFIG_SOC_RT288X -#define EARLY_UART_BASE 0x300c00 +#define EARLY_UART_BASE 0x300c00 +#define CHIPID_BASE 0x300004 +#elif defined(CONFIG_SOC_MT7621) +#define EARLY_UART_BASE 0x1E000c00 +#define CHIPID_BASE 0x1E000004 #else -#define EARLY_UART_BASE 0x10000c00 +#define EARLY_UART_BASE 0x10000c00 +#define CHIPID_BASE 0x10000004 #endif -#define UART_REG_RX 0x00 -#define UART_REG_TX 0x04 -#define UART_REG_IER 0x08 -#define UART_REG_IIR 0x0c -#define UART_REG_FCR 0x10 -#define UART_REG_LCR 0x14 -#define UART_REG_MCR 0x18 -#define UART_REG_LSR 0x1c +#define MT7628_CHIP_NAME1 0x20203832 + +#define UART_REG_TX 0x04 +#define UART_REG_LSR 0x14 +#define UART_REG_LSR_RT2880 0x1c static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); +static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE); static inline void uart_w32(u32 val, unsigned reg) { @@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg) return __raw_readl(uart_membase + reg); } +static inline int soc_is_mt7628(void) +{ + return IS_ENABLED(CONFIG_SOC_MT7620) && + (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1); +} + void prom_putchar(unsigned char ch) { - while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) - ; - uart_w32(ch, UART_REG_TX); - while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) - ; + if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) { + uart_w32(ch, UART_TX); + while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) + ; + } else { + while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) + ; + uart_w32(ch, UART_REG_TX); + while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) + ; + } } -- GitLab From 1dc5c2cfc17ec0522eab33913a73726413420410 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 27 Jul 2014 09:23:36 +0100 Subject: [PATCH 6066/9457] MIPS: ralink: add support for MT7620n This is the small version of MT7620a. Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8030/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ralink/mt7620.h | 7 ++----- arch/mips/ralink/mt7620.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index a05c14c23155..863aea5dcf0c 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h @@ -25,11 +25,8 @@ #define SYSC_REG_CPLL_CONFIG0 0x54 #define SYSC_REG_CPLL_CONFIG1 0x58 -#define MT7620N_CHIP_NAME0 0x33365452 -#define MT7620N_CHIP_NAME1 0x20203235 - -#define MT7620A_CHIP_NAME0 0x3637544d -#define MT7620A_CHIP_NAME1 0x20203032 +#define MT7620_CHIP_NAME0 0x3637544d +#define MT7620_CHIP_NAME1 0x20203032 #define SYSCFG0_XTAL_FREQ_SEL BIT(6) diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index 24fb40a441ca..e4b1f8251de1 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -277,6 +277,7 @@ void __init ralink_clk_init(void) ralink_clk_add("10000500.uart", periph_rate); ralink_clk_add("10000b00.spi", sys_rate); ralink_clk_add("10000c00.uartlite", periph_rate); + ralink_clk_add("10180000.wmac", xtal_rate); } void __init ralink_of_remap(void) @@ -298,22 +299,27 @@ void prom_soc_init(struct ralink_soc_info *soc_info) u32 cfg0; u32 pmu0; u32 pmu1; + u32 bga; n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); + rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); + bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK; - if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { - name = "MT7620N"; - soc_info->compatible = "ralink,mt7620n-soc"; - } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { + if (n0 != MT7620_CHIP_NAME0 || n1 != MT7620_CHIP_NAME1) + panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1); + + if (bga) { name = "MT7620A"; soc_info->compatible = "ralink,mt7620a-soc"; } else { - panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); + name = "MT7620N"; + soc_info->compatible = "ralink,mt7620n-soc"; +#ifdef CONFIG_PCI + panic("mt7620n is only supported for non pci kernels"); +#endif } - rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); - snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, "Ralink %s ver:%u eco:%u", name, -- GitLab From 53263a1c68524fd35e2f2ea7f03d0fef362b944d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 8 Oct 2014 23:30:24 +0200 Subject: [PATCH 6067/9457] MIPS: ralink: add mt7628an support Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8031/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ralink/mt7620.h | 11 + arch/mips/ralink/Kconfig | 2 +- arch/mips/ralink/mt7620.c | 276 +++++++++++++++++---- 3 files changed, 243 insertions(+), 46 deletions(-) diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 863aea5dcf0c..1976fb815fd1 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h @@ -13,6 +13,13 @@ #ifndef _MT7620_REGS_H_ #define _MT7620_REGS_H_ +enum mt762x_soc_type { + MT762X_SOC_UNKNOWN = 0, + MT762X_SOC_MT7620A, + MT762X_SOC_MT7620N, + MT762X_SOC_MT7628AN, +}; + #define MT7620_SYSC_BASE 0x10000000 #define SYSC_REG_CHIP_NAME0 0x00 @@ -27,6 +34,7 @@ #define MT7620_CHIP_NAME0 0x3637544d #define MT7620_CHIP_NAME1 0x20203032 +#define MT7628_CHIP_NAME1 0x20203832 #define SYSCFG0_XTAL_FREQ_SEL BIT(6) @@ -71,6 +79,9 @@ #define SYSCFG0_DRAM_TYPE_DDR1 1 #define SYSCFG0_DRAM_TYPE_DDR2 2 +#define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0 +#define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1 + #define MT7620_DRAM_BASE 0x0 #define MT7620_SDRAM_SIZE_MIN 2 #define MT7620_SDRAM_SIZE_MAX 64 diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 77e8a9620e18..699b75dafd7a 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -26,7 +26,7 @@ choice select HW_HAS_PCI config SOC_MT7620 - bool "MT7620" + bool "MT7620/8" endchoice diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index e4b1f8251de1..2ea5ff6dc22e 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -37,6 +37,9 @@ #define PMU1_CFG 0x8C #define DIG_SW_SEL BIT(25) +/* is this a MT7620 or a MT7628 */ +enum mt762x_soc_type mt762x_soc; + /* does the board have sdram or ddram */ static int dram_type; @@ -94,6 +97,136 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = { { 0 } }; +static struct rt2880_pmx_func pwm1_grp_mt7628[] = { + FUNC("sdcx", 3, 19, 1), + FUNC("utif", 2, 19, 1), + FUNC("gpio", 1, 19, 1), + FUNC("pwm", 0, 19, 1), +}; + +static struct rt2880_pmx_func pwm0_grp_mt7628[] = { + FUNC("sdcx", 3, 18, 1), + FUNC("utif", 2, 18, 1), + FUNC("gpio", 1, 18, 1), + FUNC("pwm", 0, 18, 1), +}; + +static struct rt2880_pmx_func uart2_grp_mt7628[] = { + FUNC("sdcx", 3, 20, 2), + FUNC("pwm", 2, 20, 2), + FUNC("gpio", 1, 20, 2), + FUNC("uart", 0, 20, 2), +}; + +static struct rt2880_pmx_func uart1_grp_mt7628[] = { + FUNC("sdcx", 3, 45, 2), + FUNC("pwm", 2, 45, 2), + FUNC("gpio", 1, 45, 2), + FUNC("uart", 0, 45, 2), +}; + +static struct rt2880_pmx_func i2c_grp_mt7628[] = { + FUNC("-", 3, 4, 2), + FUNC("debug", 2, 4, 2), + FUNC("gpio", 1, 4, 2), + FUNC("i2c", 0, 4, 2), +}; + +static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; +static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; +static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) }; +static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; + +static struct rt2880_pmx_func sd_mode_grp_mt7628[] = { + FUNC("jtag", 3, 22, 8), + FUNC("utif", 2, 22, 8), + FUNC("gpio", 1, 22, 8), + FUNC("sdcx", 0, 22, 8), +}; + +static struct rt2880_pmx_func uart0_grp_mt7628[] = { + FUNC("-", 3, 12, 2), + FUNC("-", 2, 12, 2), + FUNC("gpio", 1, 12, 2), + FUNC("uart", 0, 12, 2), +}; + +static struct rt2880_pmx_func i2s_grp_mt7628[] = { + FUNC("antenna", 3, 0, 4), + FUNC("pcm", 2, 0, 4), + FUNC("gpio", 1, 0, 4), + FUNC("i2s", 0, 0, 4), +}; + +static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = { + FUNC("-", 3, 6, 1), + FUNC("refclk", 2, 6, 1), + FUNC("gpio", 1, 6, 1), + FUNC("spi", 0, 6, 1), +}; + +static struct rt2880_pmx_func spis_grp_mt7628[] = { + FUNC("pwm", 3, 14, 4), + FUNC("util", 2, 14, 4), + FUNC("gpio", 1, 14, 4), + FUNC("spis", 0, 14, 4), +}; + +static struct rt2880_pmx_func gpio_grp_mt7628[] = { + FUNC("pcie", 3, 11, 1), + FUNC("refclk", 2, 11, 1), + FUNC("gpio", 1, 11, 1), + FUNC("gpio", 0, 11, 1), +}; + +#define MT7628_GPIO_MODE_MASK 0x3 + +#define MT7628_GPIO_MODE_PWM1 30 +#define MT7628_GPIO_MODE_PWM0 28 +#define MT7628_GPIO_MODE_UART2 26 +#define MT7628_GPIO_MODE_UART1 24 +#define MT7628_GPIO_MODE_I2C 20 +#define MT7628_GPIO_MODE_REFCLK 18 +#define MT7628_GPIO_MODE_PERST 16 +#define MT7628_GPIO_MODE_WDT 14 +#define MT7628_GPIO_MODE_SPI 12 +#define MT7628_GPIO_MODE_SDMODE 10 +#define MT7628_GPIO_MODE_UART0 8 +#define MT7628_GPIO_MODE_I2S 6 +#define MT7628_GPIO_MODE_CS1 4 +#define MT7628_GPIO_MODE_SPIS 2 +#define MT7628_GPIO_MODE_GPIO 0 + +static struct rt2880_pmx_group mt7628an_pinmux_data[] = { + GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_PWM1), + GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_PWM0), + GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_UART2), + GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_UART1), + GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_I2C), + GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK), + GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST), + GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT), + GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI), + GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_SDMODE), + GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_UART0), + GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_I2S), + GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_CS1), + GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_SPIS), + GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, + 1, MT7628_GPIO_MODE_GPIO), + { 0 } +}; + static __init u32 mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div) { @@ -244,29 +377,42 @@ void __init ralink_clk_init(void) xtal_rate = mt7620_get_xtal_rate(); - cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); - pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); - - cpu_rate = mt7620_get_cpu_rate(pll_rate); - dram_rate = mt7620_get_dram_rate(pll_rate); - sys_rate = mt7620_get_sys_rate(cpu_rate); - periph_rate = mt7620_get_periph_rate(xtal_rate); - #define RFMT(label) label ":%lu.%03luMHz " #define RINT(x) ((x) / 1000000) #define RFRAC(x) (((x) / 1000) % 1000) - pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), - RINT(xtal_rate), RFRAC(xtal_rate), - RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), - RINT(pll_rate), RFRAC(pll_rate)); + if (mt762x_soc == MT762X_SOC_MT7628AN) { + if (xtal_rate == MHZ(40)) + cpu_rate = MHZ(580); + else + cpu_rate = MHZ(575); + dram_rate = sys_rate = cpu_rate / 3; + periph_rate = MHZ(40); + + ralink_clk_add("10000d00.uartlite", periph_rate); + ralink_clk_add("10000e00.uartlite", periph_rate); + } else { + cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); + pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); + + cpu_rate = mt7620_get_cpu_rate(pll_rate); + dram_rate = mt7620_get_dram_rate(pll_rate); + sys_rate = mt7620_get_sys_rate(cpu_rate); + periph_rate = mt7620_get_periph_rate(xtal_rate); + + pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), + RINT(xtal_rate), RFRAC(xtal_rate), + RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), + RINT(pll_rate), RFRAC(pll_rate)); + + ralink_clk_add("10000500.uart", periph_rate); + } pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), RINT(cpu_rate), RFRAC(cpu_rate), RINT(dram_rate), RFRAC(dram_rate), RINT(sys_rate), RFRAC(sys_rate), RINT(periph_rate), RFRAC(periph_rate)); - #undef RFRAC #undef RINT #undef RFMT @@ -274,7 +420,6 @@ void __init ralink_clk_init(void) ralink_clk_add("cpu", cpu_rate); ralink_clk_add("10000100.timer", periph_rate); ralink_clk_add("10000120.watchdog", periph_rate); - ralink_clk_add("10000500.uart", periph_rate); ralink_clk_add("10000b00.spi", sys_rate); ralink_clk_add("10000c00.uartlite", periph_rate); ralink_clk_add("10180000.wmac", xtal_rate); @@ -289,6 +434,52 @@ void __init ralink_of_remap(void) panic("Failed to remap core resources"); } +static __init void +mt7620_dram_init(struct ralink_soc_info *soc_info) +{ + switch (dram_type) { + case SYSCFG0_DRAM_TYPE_SDRAM: + pr_info("Board has SDRAM\n"); + soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; + soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR1: + pr_info("Board has DDR1\n"); + soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR2: + pr_info("Board has DDR2\n"); + soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; + break; + default: + BUG(); + } +} + +static __init void +mt7628_dram_init(struct ralink_soc_info *soc_info) +{ + switch (dram_type) { + case SYSCFG0_DRAM_TYPE_DDR1_MT7628: + pr_info("Board has DDR1\n"); + soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; + break; + + case SYSCFG0_DRAM_TYPE_DDR2_MT7628: + pr_info("Board has DDR2\n"); + soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; + soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; + break; + default: + BUG(); + } +} + void prom_soc_init(struct ralink_soc_info *soc_info) { void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); @@ -306,18 +497,25 @@ void prom_soc_init(struct ralink_soc_info *soc_info) rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK; - if (n0 != MT7620_CHIP_NAME0 || n1 != MT7620_CHIP_NAME1) - panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1); - - if (bga) { - name = "MT7620A"; - soc_info->compatible = "ralink,mt7620a-soc"; - } else { - name = "MT7620N"; - soc_info->compatible = "ralink,mt7620n-soc"; + if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) { + if (bga) { + mt762x_soc = MT762X_SOC_MT7620A; + name = "MT7620A"; + soc_info->compatible = "ralink,mt7620a-soc"; + } else { + mt762x_soc = MT762X_SOC_MT7620N; + name = "MT7620N"; + soc_info->compatible = "ralink,mt7620n-soc"; #ifdef CONFIG_PCI - panic("mt7620n is only supported for non pci kernels"); + panic("mt7620n is only supported for non pci kernels"); #endif + } + } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) { + mt762x_soc = MT762X_SOC_MT7628AN; + name = "MT7628AN"; + soc_info->compatible = "ralink,mt7628an-soc"; + } else { + panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); } snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, @@ -329,28 +527,11 @@ void prom_soc_init(struct ralink_soc_info *soc_info) cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; - switch (dram_type) { - case SYSCFG0_DRAM_TYPE_SDRAM: - pr_info("Board has SDRAM\n"); - soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; - soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; - break; - - case SYSCFG0_DRAM_TYPE_DDR1: - pr_info("Board has DDR1\n"); - soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; - soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; - break; - - case SYSCFG0_DRAM_TYPE_DDR2: - pr_info("Board has DDR2\n"); - soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; - soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; - break; - default: - BUG(); - } soc_info->mem_base = MT7620_DRAM_BASE; + if (mt762x_soc == MT762X_SOC_MT7628AN) + mt7628_dram_init(soc_info); + else + mt7620_dram_init(soc_info); pmu0 = __raw_readl(sysc + PMU0_CFG); pmu1 = __raw_readl(sysc + PMU1_CFG); @@ -359,4 +540,9 @@ void prom_soc_init(struct ralink_soc_info *soc_info) (pmu0 & PMU_SW_SET) ? ("sw") : ("hw")); pr_info("Digital PMU set to %s control\n", (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); + + if (mt762x_soc == MT762X_SOC_MT7628AN) + rt2880_pinmux_data = mt7628an_pinmux_data; + else + rt2880_pinmux_data = mt7620a_pinmux_data; } -- GitLab From b96e6e9fd296b85dbbd863157d00994711924b70 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 26 Oct 2014 11:26:04 +0100 Subject: [PATCH 6068/9457] MIPS: ralink: allow loading irq registers from the devicetree Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8029/ Signed-off-by: Ralf Baechle --- arch/mips/ralink/irq.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 7634dcd88766..7cf91b92e9d1 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c @@ -20,14 +20,6 @@ #include "common.h" -/* INTC register offsets */ -#define INTC_REG_STATUS0 0x00 -#define INTC_REG_STATUS1 0x04 -#define INTC_REG_TYPE 0x20 -#define INTC_REG_RAW_STATUS 0x30 -#define INTC_REG_ENABLE 0x34 -#define INTC_REG_DISABLE 0x38 - #define INTC_INT_GLOBAL BIT(31) #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) @@ -44,17 +36,36 @@ #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) +enum rt_intc_regs_enum { + INTC_REG_STATUS0 = 0, + INTC_REG_STATUS1, + INTC_REG_TYPE, + INTC_REG_RAW_STATUS, + INTC_REG_ENABLE, + INTC_REG_DISABLE, +}; + +static u32 rt_intc_regs[] = { + [INTC_REG_STATUS0] = 0x00, + [INTC_REG_STATUS1] = 0x04, + [INTC_REG_TYPE] = 0x20, + [INTC_REG_RAW_STATUS] = 0x30, + [INTC_REG_ENABLE] = 0x34, + [INTC_REG_DISABLE] = 0x38, +}; + static void __iomem *rt_intc_membase; + static int rt_perfcount_irq; static inline void rt_intc_w32(u32 val, unsigned reg) { - __raw_writel(val, rt_intc_membase + reg); + __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]); } static inline u32 rt_intc_r32(unsigned reg) { - return __raw_readl(rt_intc_membase + reg); + return __raw_readl(rt_intc_membase + rt_intc_regs[reg]); } static void ralink_intc_irq_unmask(struct irq_data *d) @@ -140,6 +151,10 @@ static int __init intc_of_init(struct device_node *node, struct irq_domain *domain; int irq; + if (!of_property_read_u32_array(node, "ralink,intc-registers", + rt_intc_regs, 6)) + pr_info("intc: using register map from devicetree\n"); + irq = irq_of_parse_and_map(node, 0); if (!irq) panic("Failed to get INTC IRQ"); -- GitLab From 187c26ddf0b201aeb7e343be19a3da72eef19db4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 9 Oct 2014 03:54:47 +0200 Subject: [PATCH 6069/9457] MIPS: ralink: add rt2880 pci driver Signed-off-by: John Crispin Patchwork: http://patchwork.linux-mips.org/patch/8034/ Signed-off-by: Ralf Baechle --- arch/mips/pci/Makefile | 1 + arch/mips/pci/pci-rt2880.c | 285 +++++++++++++++++++++++++++++++++++++ arch/mips/ralink/Kconfig | 1 + 3 files changed, 287 insertions(+) create mode 100644 arch/mips/pci/pci-rt2880.c diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 6523d558ff5a..64a0caae63b5 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o obj-$(CONFIG_LANTIQ) += fixup-lantiq.o obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o +obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c new file mode 100644 index 000000000000..a4574947e698 --- /dev/null +++ b/arch/mips/pci/pci-rt2880.c @@ -0,0 +1,285 @@ +/* + * Ralink RT288x SoC PCI register definitions + * + * Copyright (C) 2009 John Crispin + * Copyright (C) 2009 Gabor Juhos + * + * Parts of this file are based on Ralink's 2.6.21 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define RT2880_PCI_BASE 0x00440000 +#define RT288X_CPU_IRQ_PCI 4 + +#define RT2880_PCI_MEM_BASE 0x20000000 +#define RT2880_PCI_MEM_SIZE 0x10000000 +#define RT2880_PCI_IO_BASE 0x00460000 +#define RT2880_PCI_IO_SIZE 0x00010000 + +#define RT2880_PCI_REG_PCICFG_ADDR 0x00 +#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c +#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 +#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 +#define RT2880_PCI_REG_CONFIG_ADDR 0x20 +#define RT2880_PCI_REG_CONFIG_DATA 0x24 +#define RT2880_PCI_REG_MEMBASE 0x28 +#define RT2880_PCI_REG_IOBASE 0x2c +#define RT2880_PCI_REG_ID 0x30 +#define RT2880_PCI_REG_CLASS 0x34 +#define RT2880_PCI_REG_SUBID 0x38 +#define RT2880_PCI_REG_ARBCTL 0x80 + +static void __iomem *rt2880_pci_base; +static DEFINE_SPINLOCK(rt2880_pci_lock); + +static u32 rt2880_pci_reg_read(u32 reg) +{ + return readl(rt2880_pci_base + reg); +} + +static void rt2880_pci_reg_write(u32 val, u32 reg) +{ + writel(val, rt2880_pci_base + reg); +} + +static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, + unsigned int func, unsigned int where) +{ + return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | + 0x80000000); +} + +static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + unsigned long flags; + u32 address; + u32 data; + + address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + spin_lock_irqsave(&rt2880_pci_lock, flags); + rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); + data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); + spin_unlock_irqrestore(&rt2880_pci_lock, flags); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + *val = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + *val = data; + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + unsigned long flags; + u32 address; + u32 data; + + address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + spin_lock_irqsave(&rt2880_pci_lock, flags); + rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); + data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); + + switch (size) { + case 1: + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 2: + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + break; + case 4: + data = val; + break; + } + + rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); + spin_unlock_irqrestore(&rt2880_pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rt2880_pci_ops = { + .read = rt2880_pci_config_read, + .write = rt2880_pci_config_write, +}; + +static struct resource rt2880_pci_mem_resource = { + .name = "PCI MEM space", + .start = RT2880_PCI_MEM_BASE, + .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct resource rt2880_pci_io_resource = { + .name = "PCI IO space", + .start = RT2880_PCI_IO_BASE, + .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller rt2880_pci_controller = { + .pci_ops = &rt2880_pci_ops, + .mem_resource = &rt2880_pci_mem_resource, + .io_resource = &rt2880_pci_io_resource, +}; + +static inline u32 rt2880_pci_read_u32(unsigned long reg) +{ + unsigned long flags; + u32 address; + u32 ret; + + address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); + + spin_lock_irqsave(&rt2880_pci_lock, flags); + rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); + ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); + spin_unlock_irqrestore(&rt2880_pci_lock, flags); + + return ret; +} + +static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) +{ + unsigned long flags; + u32 address; + + address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); + + spin_lock_irqsave(&rt2880_pci_lock, flags); + rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); + rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); + spin_unlock_irqrestore(&rt2880_pci_lock, flags); +} + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + u16 cmd; + int irq = -1; + + if (dev->bus->number != 0) + return irq; + + switch (PCI_SLOT(dev->devfn)) { + case 0x00: + rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); + (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); + break; + case 0x11: + irq = RT288X_CPU_IRQ_PCI; + break; + default: + pr_err("%s:%s[%d] trying to alloc unknown pci irq\n", + __FILE__, __func__, __LINE__); + BUG(); + break; + } + + pci_write_config_byte((struct pci_dev *) dev, + PCI_CACHE_LINE_SIZE, 0x14); + pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF); + pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | + PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; + pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd); + pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE, + dev->irq); + return irq; +} + +static int rt288x_pci_probe(struct platform_device *pdev) +{ + void __iomem *io_map_base; + int i; + + rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE); + + io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); + rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; + set_io_port_base((unsigned long) io_map_base); + + ioport_resource.start = RT2880_PCI_IO_BASE; + ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; + + rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); + for (i = 0; i < 0xfffff; i++) + ; + + rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); + rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); + rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); + rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); + rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); + rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); + rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); + rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); + rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); + + rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); + (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); + + register_pci_controller(&rt2880_pci_controller); + return 0; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static const struct of_device_id rt288x_pci_match[] = { + { .compatible = "ralink,rt288x-pci" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rt288x_pci_match); + +static struct platform_driver rt288x_pci_driver = { + .probe = rt288x_pci_probe, + .driver = { + .name = "rt288x-pci", + .owner = THIS_MODULE, + .of_match_table = rt288x_pci_match, + }, +}; + +int __init pcibios_init(void) +{ + int ret = platform_driver_register(&rt288x_pci_driver); + + if (ret) + pr_info("rt288x-pci: Error registering platform driver!"); + + return ret; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 699b75dafd7a..b1c52ca580f9 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -16,6 +16,7 @@ choice config SOC_RT288X bool "RT288x" select MIPS_L1_CACHE_SHIFT_4 + select HW_HAS_PCI config SOC_RT305X bool "RT305x" -- GitLab From e2afb7de6e7dad21f9d709f80f23bbd3c5bdad11 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sun, 6 Apr 2014 20:52:37 +0100 Subject: [PATCH 6070/9457] TC: Error handling clean-ups Rewrite TURBOchannel error handling to use a common failure path, making sure put_device is called for devices that failed initialization. While at it update printk calls to use pr_err rather than KERN_ERR. Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6701/ Signed-off-by: Ralf Baechle --- drivers/tc/tc.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index 946562389ca8..3be9519654e5 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c @@ -83,8 +83,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) /* Found a board, allocate it an entry in the list */ tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); if (!tdev) { - printk(KERN_ERR "tc%x: unable to allocate tc_dev\n", - slot); + pr_err("tc%x: unable to allocate tc_dev\n", slot); goto out_err; } dev_set_name(&tdev->dev, "tc%x", slot); @@ -117,10 +116,10 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) tdev->resource.start = extslotaddr; tdev->resource.end = extslotaddr + devsize - 1; } else { - printk(KERN_ERR "%s: Cannot provide slot space " - "(%dMiB required, up to %dMiB supported)\n", - dev_name(&tdev->dev), devsize >> 20, - max(slotsize, extslotsize) >> 20); + pr_err("%s: Cannot provide slot space " + "(%ldMiB required, up to %ldMiB supported)\n", + dev_name(&tdev->dev), (long)(devsize >> 20), + (long)(max(slotsize, extslotsize) >> 20)); kfree(tdev); goto out_err; } @@ -147,14 +146,12 @@ static int __init tc_init(void) { /* Initialize the TURBOchannel bus */ if (tc_bus_get_info(&tc_bus)) - return 0; + goto out_err; INIT_LIST_HEAD(&tc_bus.devices); dev_set_name(&tc_bus.dev, "tc"); - if (device_register(&tc_bus.dev)) { - put_device(&tc_bus.dev); - return 0; - } + if (device_register(&tc_bus.dev)) + goto out_err_device; if (tc_bus.info.slot_size) { unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; @@ -172,8 +169,8 @@ static int __init tc_init(void) tc_bus.resource[0].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &tc_bus.resource[0]) < 0) { - printk(KERN_ERR "tc: Cannot reserve resource\n"); - return 0; + pr_err("tc: Cannot reserve resource\n"); + goto out_err_device; } if (tc_bus.ext_slot_size) { tc_bus.resource[1].start = tc_bus.ext_slot_base; @@ -184,10 +181,8 @@ static int __init tc_init(void) tc_bus.resource[1].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &tc_bus.resource[1]) < 0) { - printk(KERN_ERR - "tc: Cannot reserve resource\n"); - release_resource(&tc_bus.resource[0]); - return 0; + pr_err("tc: Cannot reserve resource\n"); + goto out_err_resource; } } @@ -195,6 +190,13 @@ static int __init tc_init(void) } return 0; + +out_err_resource: + release_resource(&tc_bus.resource[0]); +out_err_device: + put_device(&tc_bus.dev); +out_err: + return 0; } subsys_initcall(tc_init); -- GitLab From 4a792e56cfdbe000d01c01ce356d13f39f5494e7 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sat, 8 Nov 2014 12:39:38 +0100 Subject: [PATCH 6071/9457] MIPS: FW: Fix parsing u-boot environment When reading u-boot's key=value pairs it should skip the '=' and not use the next argument. Signed-off-by: Alban Bedel Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8357/ Signed-off-by: Ralf Baechle --- arch/mips/fw/lib/cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index ffd0345780ae..a0c361e6a5d2 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c @@ -68,7 +68,7 @@ char *fw_getenv(char *envname) result = fw_envp(index + 1); break; } else if (fw_envp(index)[i] == '=') { - result = (fw_envp(index + 1) + i); + result = fw_envp(index) + i + 1; break; } } -- GitLab From 484c344985ddf8e9ed12b8cf540eba0b1d869236 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sat, 8 Nov 2014 12:39:39 +0100 Subject: [PATCH 6072/9457] MIPS: FW: Use kstrtoul() to parse unsigned long from the fw environment Fix some value corruptions with values that can't be represented in a signed long. Signed-off-by: Alban Bedel Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8358/ Signed-off-by: Ralf Baechle --- arch/mips/fw/lib/cmdline.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index a0c361e6a5d2..6ecda64ad184 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c @@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname) { unsigned long envl = 0UL; char *str; - long val; int tmp; str = fw_getenv(envname); if (str) { - tmp = kstrtol(str, 0, &val); - envl = (unsigned long)val; + tmp = kstrtoul(str, 0, &envl); + if (tmp) + envl = 0; } return envl; -- GitLab From 43cc739fd98b8c517ad45756d869f866e746ba04 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:38 +0400 Subject: [PATCH 6073/9457] MIPS: ath25: add common parts Add common code for Atheros AR5312 and Atheros AR2315 SoCs families. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8237 Signed-off-by: Ralf Baechle --- arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 12 ++++ arch/mips/ath25/Makefile | 11 ++++ arch/mips/ath25/Platform | 6 ++ arch/mips/ath25/board.c | 51 +++++++++++++++ arch/mips/ath25/devices.c | 10 +++ arch/mips/ath25/devices.h | 18 ++++++ arch/mips/ath25/prom.c | 26 ++++++++ .../asm/mach-ath25/cpu-feature-overrides.h | 56 ++++++++++++++++ .../include/asm/mach-ath25/dma-coherence.h | 64 +++++++++++++++++++ arch/mips/include/asm/mach-ath25/gpio.h | 16 +++++ arch/mips/include/asm/mach-ath25/war.h | 25 ++++++++ 12 files changed, 296 insertions(+) create mode 100644 arch/mips/ath25/Makefile create mode 100644 arch/mips/ath25/Platform create mode 100644 arch/mips/ath25/board.c create mode 100644 arch/mips/ath25/devices.c create mode 100644 arch/mips/ath25/devices.h create mode 100644 arch/mips/ath25/prom.c create mode 100644 arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-ath25/dma-coherence.h create mode 100644 arch/mips/include/asm/mach-ath25/gpio.h create mode 100644 arch/mips/include/asm/mach-ath25/war.h diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 7c507212025a..e5fc463b36d0 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -2,6 +2,7 @@ platforms += alchemy platforms += ar7 +platforms += ath25 platforms += ath79 platforms += bcm3384 platforms += bcm47xx diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9e8317e9b567..7db1bfb80f0a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -97,6 +97,18 @@ config AR7 Support for the Texas Instruments AR7 System-on-a-Chip family: TNETD7100, 7200 and 7300. +config ATH25 + bool "Atheros AR231x/AR531x SoC support" + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select IRQ_CPU + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + help + Support for Atheros AR231x and Atheros AR531x based boards + config ATH79 bool "Atheros AR71XX/AR724X/AR913X based boards" select ARCH_REQUIRE_GPIOLIB diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile new file mode 100644 index 000000000000..9199fa1508d2 --- /dev/null +++ b/arch/mips/ath25/Makefile @@ -0,0 +1,11 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2006 FON Technology, SL. +# Copyright (C) 2006 Imre Kaloz +# Copyright (C) 2006-2009 Felix Fietkau +# + +obj-y += board.o prom.o devices.o diff --git a/arch/mips/ath25/Platform b/arch/mips/ath25/Platform new file mode 100644 index 000000000000..ef3f81fa080b --- /dev/null +++ b/arch/mips/ath25/Platform @@ -0,0 +1,6 @@ +# +# Atheros AR531X/AR231X WiSoC +# +platform-$(CONFIG_ATH25) += ath25/ +cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25 +load-$(CONFIG_ATH25) += 0xffffffff80041000 diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c new file mode 100644 index 000000000000..dd70327fd801 --- /dev/null +++ b/arch/mips/ath25/board.c @@ -0,0 +1,51 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006-2009 Felix Fietkau + */ + +#include +#include +#include +#include +#include +#include + +static void ath25_halt(void) +{ + local_irq_disable(); + unreachable(); +} + +void __init plat_mem_setup(void) +{ + _machine_halt = ath25_halt; + pm_power_off = ath25_halt; + + /* Disable data watchpoints */ + write_c0_watchlo0(0); +} + +asmlinkage void plat_irq_dispatch(void) +{ +} + +void __init plat_time_init(void) +{ +} + +unsigned int __cpuinit get_c0_compare_int(void) +{ + return CP0_LEGACY_COMPARE_IRQ; +} + +void __init arch_init_irq(void) +{ + clear_c0_status(ST0_IM); + mips_cpu_irq_init(); +} diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c new file mode 100644 index 000000000000..049ab4477954 --- /dev/null +++ b/arch/mips/ath25/devices.c @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "devices.h" + +const char *get_system_type(void) +{ + return "Atheros (unknown)"; +} diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h new file mode 100644 index 000000000000..e25a3262256d --- /dev/null +++ b/arch/mips/ath25/devices.h @@ -0,0 +1,18 @@ +#ifndef __ATH25_DEVICES_H +#define __ATH25_DEVICES_H + +#include + +#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) + +static inline bool is_ar2315(void) +{ + return (current_cpu_data.cputype == CPU_4KEC); +} + +static inline bool is_ar5312(void) +{ + return !is_ar2315(); +} + +#endif diff --git a/arch/mips/ath25/prom.c b/arch/mips/ath25/prom.c new file mode 100644 index 000000000000..edf82be8870d --- /dev/null +++ b/arch/mips/ath25/prom.c @@ -0,0 +1,26 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright MontaVista Software Inc + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006 Felix Fietkau + */ + +/* + * Prom setup file for AR5312/AR231x SoCs + */ + +#include +#include + +void __init prom_init(void) +{ +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h new file mode 100644 index 000000000000..5fd82d890843 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h @@ -0,0 +1,56 @@ +/* + * Atheros AR231x/AR531x SoC specific CPU feature overrides + * + * Copyright (C) 2008 Gabor Juhos + * + * This file was derived from: include/asm-mips/cpu-features.h + * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) 2004 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ +#ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H + +/* + * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core. + */ +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_sb1_cache 0 +#define cpu_has_fpu 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 1 +#define cpu_has_ejtag 1 + +/* + * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the + * ll/sc instructions. + */ +#define cpu_has_llsc 0 + +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 + +#define cpu_has_mips32r1 1 + +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#define cpu_has_dsp 0 +#define cpu_has_mipsmt 0 + +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 +#define cpu_has_64bit_gp_regs 0 +#define cpu_has_64bit_addresses 0 + +#endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h new file mode 100644 index 000000000000..8b3d0cca4505 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h @@ -0,0 +1,64 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006 Ralf Baechle + * Copyright (C) 2007 Felix Fietkau + * + */ +#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H +#define __ASM_MACH_ATH25_DMA_COHERENCE_H + +#include + +static inline dma_addr_t +plat_map_dma_mem(struct device *dev, void *addr, size_t size) +{ + return virt_to_phys(addr); +} + +static inline dma_addr_t +plat_map_dma_mem_page(struct device *dev, struct page *page) +{ + return page_to_phys(page); +} + +static inline unsigned long +plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr; +} + +static inline void +plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ +} + +static inline int plat_dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +static inline void plat_extra_sync_for_device(struct device *dev) +{ +} + +static inline int plat_dma_mapping_error(struct device *dev, + dma_addr_t dma_addr) +{ + return 0; +} + +static inline int plat_device_is_coherent(struct device *dev) +{ +#ifdef CONFIG_DMA_COHERENT + return 1; +#endif +#ifdef CONFIG_DMA_NONCOHERENT + return 0; +#endif +} + +#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h new file mode 100644 index 000000000000..713564b8e8ef --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/gpio.h @@ -0,0 +1,16 @@ +#ifndef __ASM_MACH_ATH25_GPIO_H +#define __ASM_MACH_ATH25_GPIO_H + +#include + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + +static inline int irq_to_gpio(unsigned irq) +{ + return -EINVAL; +} + +#endif /* __ASM_MACH_ATH25_GPIO_H */ diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h new file mode 100644 index 000000000000..e3a5250ebd67 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/war.h @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Felix Fietkau + */ +#ifndef __ASM_MACH_ATH25_WAR_H +#define __ASM_MACH_ATH25_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MACH_ATH25_WAR_H */ -- GitLab From 3b12308f3337c09b424a2b9cf73c2c06521abe7e Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:39 +0400 Subject: [PATCH 6074/9457] MIPS: ath25: add basic AR5312 SoC support Add basic support for Atheros AR5312/AR2312 SoCs: registers definition file and initial setup code. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8238/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/ath25/Kconfig | 4 + arch/mips/ath25/Makefile | 2 + arch/mips/ath25/ar5312.c | 155 ++++++++++++++++++++++++++ arch/mips/ath25/ar5312.h | 16 +++ arch/mips/ath25/ar5312_regs.h | 201 ++++++++++++++++++++++++++++++++++ arch/mips/ath25/board.c | 8 ++ 7 files changed, 387 insertions(+) create mode 100644 arch/mips/ath25/Kconfig create mode 100644 arch/mips/ath25/ar5312.c create mode 100644 arch/mips/ath25/ar5312.h create mode 100644 arch/mips/ath25/ar5312_regs.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7db1bfb80f0a..4b5a3b962ff4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -877,6 +877,7 @@ config MIPS_PARAVIRT endchoice source "arch/mips/alchemy/Kconfig" +source "arch/mips/ath25/Kconfig" source "arch/mips/ath79/Kconfig" source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig new file mode 100644 index 000000000000..cf933ea38044 --- /dev/null +++ b/arch/mips/ath25/Kconfig @@ -0,0 +1,4 @@ +config SOC_AR5312 + bool "Atheros AR5312/AR2312+ SoC support" + depends on ATH25 + default y diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile index 9199fa1508d2..3361619caa9b 100644 --- a/arch/mips/ath25/Makefile +++ b/arch/mips/ath25/Makefile @@ -9,3 +9,5 @@ # obj-y += board.o prom.o devices.o + +obj-$(CONFIG_SOC_AR5312) += ar5312.o diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c new file mode 100644 index 000000000000..c2adaf2cd73a --- /dev/null +++ b/arch/mips/ath25/ar5312.c @@ -0,0 +1,155 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006-2009 Felix Fietkau + * Copyright (C) 2012 Alexandros C. Couloumbis + */ + +/* + * Platform devices for Atheros AR5312 SoCs + */ + +#include +#include +#include +#include +#include +#include + +#include "devices.h" +#include "ar5312.h" +#include "ar5312_regs.h" + +static void __iomem *ar5312_rst_base; + +static inline u32 ar5312_rst_reg_read(u32 reg) +{ + return __raw_readl(ar5312_rst_base + reg); +} + +static inline void ar5312_rst_reg_write(u32 reg, u32 val) +{ + __raw_writel(val, ar5312_rst_base + reg); +} + +static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) +{ + u32 ret = ar5312_rst_reg_read(reg); + + ret &= ~mask; + ret |= val; + ar5312_rst_reg_write(reg, ret); +} + +static void ar5312_restart(char *command) +{ + /* reset the system */ + local_irq_disable(); + while (1) + ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM); +} + +/* + * This table is indexed by bits 5..4 of the CLOCKCTL1 register + * to determine the predevisor value. + */ +static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; + +static unsigned __init ar5312_cpu_frequency(void) +{ + u32 scratch, devid, clock_ctl1; + u32 predivide_mask, multiplier_mask, doubler_mask; + unsigned predivide_shift, multiplier_shift; + unsigned predivide_select, predivisor, multiplier; + + /* Trust the bootrom's idea of cpu frequency. */ + scratch = ar5312_rst_reg_read(AR5312_SCRATCH); + if (scratch) + return scratch; + + devid = ar5312_rst_reg_read(AR5312_REV); + devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S; + if (devid == AR5312_REV_MAJ_AR2313) { + predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; + predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; + multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; + multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; + doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; + } else { /* AR5312 and AR2312 */ + predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; + predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; + multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; + multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; + doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; + } + + /* + * Clocking is derived from a fixed 40MHz input clock. + * + * cpu_freq = input_clock * MULT (where MULT is PLL multiplier) + * sys_freq = cpu_freq / 4 (used for APB clock, serial, + * flash, Timer, Watchdog Timer) + * + * cnt_freq = cpu_freq / 2 (use for CPU count/compare) + * + * So, for example, with a PLL multiplier of 5, we have + * + * cpu_freq = 200MHz + * sys_freq = 50MHz + * cnt_freq = 100MHz + * + * We compute the CPU frequency, based on PLL settings. + */ + + clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1); + predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift; + predivisor = clockctl1_predivide_table[predivide_select]; + multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift; + + if (clock_ctl1 & doubler_mask) + multiplier <<= 1; + + return (40000000 / predivisor) * multiplier; +} + +static inline unsigned ar5312_sys_frequency(void) +{ + return ar5312_cpu_frequency() / 4; +} + +void __init ar5312_plat_time_init(void) +{ + mips_hpt_frequency = ar5312_cpu_frequency() / 2; +} + +void __init ar5312_plat_mem_setup(void) +{ + void __iomem *sdram_base; + u32 memsize, memcfg, bank0_ac, bank1_ac; + + /* Detect memory size */ + sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE, + AR5312_SDRAMCTL_SIZE); + memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1); + bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0); + bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1); + memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + + (bank1_ac ? (1 << (bank1_ac + 1)) : 0); + memsize <<= 20; + add_memory_region(0, memsize, BOOT_MEM_RAM); + iounmap(sdram_base); + + ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE); + + /* Clear any lingering AHB errors */ + ar5312_rst_reg_read(AR5312_PROCADDR); + ar5312_rst_reg_read(AR5312_DMAADDR); + ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE); + + _machine_restart = ar5312_restart; +} diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h new file mode 100644 index 000000000000..9e1e56e24eed --- /dev/null +++ b/arch/mips/ath25/ar5312.h @@ -0,0 +1,16 @@ +#ifndef __AR5312_H +#define __AR5312_H + +#ifdef CONFIG_SOC_AR5312 + +void ar5312_plat_time_init(void); +void ar5312_plat_mem_setup(void); + +#else + +static inline void ar5312_plat_time_init(void) {} +static inline void ar5312_plat_mem_setup(void) {} + +#endif + +#endif /* __AR5312_H */ diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h new file mode 100644 index 000000000000..ff1201119be0 --- /dev/null +++ b/arch/mips/ath25/ar5312_regs.h @@ -0,0 +1,201 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006 Felix Fietkau + */ + +#ifndef __ASM_MACH_ATH25_AR5312_REGS_H +#define __ASM_MACH_ATH25_AR5312_REGS_H + +/* + * Address Map + * + * The AR5312 supports 2 enet MACS, even though many reference boards only + * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet + * PHY or PHY switch. The AR2312 supports 1 enet MAC. + */ +#define AR5312_WLAN0_BASE 0x18000000 +#define AR5312_ENET0_BASE 0x18100000 +#define AR5312_ENET1_BASE 0x18200000 +#define AR5312_SDRAMCTL_BASE 0x18300000 +#define AR5312_SDRAMCTL_SIZE 0x00000010 +#define AR5312_FLASHCTL_BASE 0x18400000 +#define AR5312_FLASHCTL_SIZE 0x00000010 +#define AR5312_WLAN1_BASE 0x18500000 +#define AR5312_UART0_BASE 0x1c000000 /* UART MMR */ +#define AR5312_GPIO_BASE 0x1c002000 +#define AR5312_GPIO_SIZE 0x00000010 +#define AR5312_RST_BASE 0x1c003000 +#define AR5312_RST_SIZE 0x00000100 +#define AR5312_FLASH_BASE 0x1e000000 +#define AR5312_FLASH_SIZE 0x00800000 + +/* + * Need these defines to determine true number of ethernet MACs + */ +#define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ +#define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ +#define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ + +/* Reset/Timer Block Address Map */ +#define AR5312_TIMER 0x0000 /* countdown timer */ +#define AR5312_RELOAD 0x0004 /* timer reload value */ +#define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */ +#define AR5312_WDT_TIMER 0x000c /* watchdog timer */ +#define AR5312_ISR 0x0010 /* Intr Status Reg */ +#define AR5312_IMR 0x0014 /* Intr Mask Reg */ +#define AR5312_RESET 0x0020 +#define AR5312_CLOCKCTL1 0x0064 +#define AR5312_SCRATCH 0x006c +#define AR5312_PROCADDR 0x0070 +#define AR5312_PROC1 0x0074 +#define AR5312_DMAADDR 0x0078 +#define AR5312_DMA1 0x007c +#define AR5312_ENABLE 0x0080 /* interface enb */ +#define AR5312_REV 0x0090 /* revision */ + +/* AR5312_WDT_CTRL register bit field definitions */ +#define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ +#define AR5312_WDT_CTRL_NMI 0x00000001 +#define AR5312_WDT_CTRL_RESET 0x00000002 + +/* AR5312_ISR register bit field definitions */ +#define AR5312_ISR_TIMER 0x00000001 +#define AR5312_ISR_AHBPROC 0x00000002 +#define AR5312_ISR_AHBDMA 0x00000004 +#define AR5312_ISR_GPIO 0x00000008 +#define AR5312_ISR_UART0 0x00000010 +#define AR5312_ISR_UART0DMA 0x00000020 +#define AR5312_ISR_WD 0x00000040 +#define AR5312_ISR_LOCAL 0x00000080 + +/* AR5312_RESET register bit field definitions */ +#define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */ +#define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */ +#define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */ +#define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ +#define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ +#define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */ +#define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */ +#define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */ +#define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ +#define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */ +#define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ +#define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ +#define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */ +#define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */ +#define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */ +#define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */ +#define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ +#define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */ + +#define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\ + AR5312_RESET_WARM_WLAN0_MAC |\ + AR5312_RESET_WARM_WLAN0_BB) + +#define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\ + AR5312_RESET_WARM_WLAN1_MAC |\ + AR5312_RESET_WARM_WLAN1_BB) + +/* AR5312_CLOCKCTL1 register bit field definitions */ +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 +#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 + +/* Valid for AR5312 and AR2312 */ +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 +#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 + +/* Valid for AR2313 */ +#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 +#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 +#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 +#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 +#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 + +/* AR5312_ENABLE register bit field definitions */ +#define AR5312_ENABLE_WLAN0 0x00000001 +#define AR5312_ENABLE_ENET0 0x00000002 +#define AR5312_ENABLE_ENET1 0x00000004 +#define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */ +#define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */ +#define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\ + AR5312_ENABLE_WLAN1_DMA) + +/* AR5312_REV register bit field definitions */ +#define AR5312_REV_WMAC_MAJ 0x0000f000 +#define AR5312_REV_WMAC_MAJ_S 12 +#define AR5312_REV_WMAC_MIN 0x00000f00 +#define AR5312_REV_WMAC_MIN_S 8 +#define AR5312_REV_MAJ 0x000000f0 +#define AR5312_REV_MAJ_S 4 +#define AR5312_REV_MIN 0x0000000f +#define AR5312_REV_MIN_S 0 +#define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN) + +/* Major revision numbers, bits 7..4 of Revision ID register */ +#define AR5312_REV_MAJ_AR5312 0x4 +#define AR5312_REV_MAJ_AR2313 0x5 + +/* Minor revision numbers, bits 3..0 of Revision ID register */ +#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ +#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ + +/* + * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices + */ +#define AR5312_FLASHCTL0 0x0000 +#define AR5312_FLASHCTL1 0x0004 +#define AR5312_FLASHCTL2 0x0008 + +/* AR5312_FLASHCTL register bit field definitions */ +#define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */ +#define AR5312_FLASHCTL_IDCY_S 0 +#define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ +#define AR5312_FLASHCTL_WST1_S 5 +#define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ +#define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ +#define AR5312_FLASHCTL_WST2_S 11 +#define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */ +#define AR5312_FLASHCTL_AC_S 16 +#define AR5312_FLASHCTL_AC_128K 0x00000000 +#define AR5312_FLASHCTL_AC_256K 0x00010000 +#define AR5312_FLASHCTL_AC_512K 0x00020000 +#define AR5312_FLASHCTL_AC_1M 0x00030000 +#define AR5312_FLASHCTL_AC_2M 0x00040000 +#define AR5312_FLASHCTL_AC_4M 0x00050000 +#define AR5312_FLASHCTL_AC_8M 0x00060000 +#define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ +#define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ +#define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */ +#define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */ +#define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */ +#define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */ +#define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */ +#define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */ +#define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */ +#define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */ +#define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */ +#define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */ +#define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */ + +/* + * ARM SDRAM Controller -- just enough to determine memory size + */ +#define AR5312_MEM_CFG1 0x0004 + +#define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */ +#define AR5312_MEM_CFG1_AC0_S 8 +#define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */ +#define AR5312_MEM_CFG1_AC1_S 12 + +#endif /* __ASM_MACH_ATH25_AR5312_REGS_H */ diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c index dd70327fd801..03baeceb3e35 100644 --- a/arch/mips/ath25/board.c +++ b/arch/mips/ath25/board.c @@ -16,6 +16,9 @@ #include #include +#include "devices.h" +#include "ar5312.h" + static void ath25_halt(void) { local_irq_disable(); @@ -27,6 +30,9 @@ void __init plat_mem_setup(void) _machine_halt = ath25_halt; pm_power_off = ath25_halt; + if (is_ar5312()) + ar5312_plat_mem_setup(); + /* Disable data watchpoints */ write_c0_watchlo0(0); } @@ -37,6 +43,8 @@ asmlinkage void plat_irq_dispatch(void) void __init plat_time_init(void) { + if (is_ar5312()) + ar5312_plat_time_init(); } unsigned int __cpuinit get_c0_compare_int(void) -- GitLab From ba910345034aea52d292bdc26b9c6831ab7b54e8 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:40 +0400 Subject: [PATCH 6075/9457] MIPS: ath25: Add basic AR2315 SoC support Add basic support for Atheros AR2315+ SoCs: registers definition file and initial setup code. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8239/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/Kconfig | 5 + arch/mips/ath25/Makefile | 1 + arch/mips/ath25/ar2315.c | 155 +++++++ arch/mips/ath25/ar2315.h | 16 + arch/mips/ath25/ar2315_regs.h | 387 ++++++++++++++++++ arch/mips/ath25/board.c | 5 + .../asm/mach-ath25/cpu-feature-overrides.h | 10 +- 7 files changed, 578 insertions(+), 1 deletion(-) create mode 100644 arch/mips/ath25/ar2315.c create mode 100644 arch/mips/ath25/ar2315.h create mode 100644 arch/mips/ath25/ar2315_regs.h diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig index cf933ea38044..ca3dde472bef 100644 --- a/arch/mips/ath25/Kconfig +++ b/arch/mips/ath25/Kconfig @@ -2,3 +2,8 @@ config SOC_AR5312 bool "Atheros AR5312/AR2312+ SoC support" depends on ATH25 default y + +config SOC_AR2315 + bool "Atheros AR2315+ SoC support" + depends on ATH25 + default y diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile index 3361619caa9b..201b7d412902 100644 --- a/arch/mips/ath25/Makefile +++ b/arch/mips/ath25/Makefile @@ -11,3 +11,4 @@ obj-y += board.o prom.o devices.o obj-$(CONFIG_SOC_AR5312) += ar5312.o +obj-$(CONFIG_SOC_AR2315) += ar2315.o diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c new file mode 100644 index 000000000000..828943212f03 --- /dev/null +++ b/arch/mips/ath25/ar2315.c @@ -0,0 +1,155 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006 Felix Fietkau + * Copyright (C) 2012 Alexandros C. Couloumbis + */ + +/* + * Platform devices for Atheros AR2315 SoCs + */ + +#include +#include +#include +#include +#include +#include + +#include "devices.h" +#include "ar2315.h" +#include "ar2315_regs.h" + +static void __iomem *ar2315_rst_base; + +static inline u32 ar2315_rst_reg_read(u32 reg) +{ + return __raw_readl(ar2315_rst_base + reg); +} + +static inline void ar2315_rst_reg_write(u32 reg, u32 val) +{ + __raw_writel(val, ar2315_rst_base + reg); +} + +static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) +{ + u32 ret = ar2315_rst_reg_read(reg); + + ret &= ~mask; + ret |= val; + ar2315_rst_reg_write(reg, ret); +} + +static void ar2315_restart(char *command) +{ + void (*mips_reset_vec)(void) = (void *)0xbfc00000; + + local_irq_disable(); + + /* try reset the system via reset control */ + ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); + + /* Cold reset does not work on the AR2315/6, use the GPIO reset bits + * a workaround. Give it some time to attempt a gpio based hardware + * reset (atheros reference design workaround) */ + + /* TODO: implement the GPIO reset workaround */ + + /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic + * workaround. Attempt to jump to the mips reset location - + * the boot loader itself might be able to recover the system */ + mips_reset_vec(); +} + +/* + * This table is indexed by bits 5..4 of the CLOCKCTL1 register + * to determine the predevisor value. + */ +static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; +static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; + +static unsigned __init ar2315_sys_clk(u32 clock_ctl) +{ + unsigned int pllc_ctrl, cpu_div; + unsigned int pllc_out, refdiv, fdiv, divby2; + unsigned int clk_div; + + pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); + refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); + refdiv = clockctl1_predivide_table[refdiv]; + fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); + divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; + pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; + + /* clkm input selected */ + switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { + case 0: + case 1: + clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); + clk_div = pllc_divide_table[clk_div]; + break; + case 2: + clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); + clk_div = pllc_divide_table[clk_div]; + break; + default: + pllc_out = 40000000; + clk_div = 1; + break; + } + + cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); + cpu_div = cpu_div * 2 ?: 1; + + return pllc_out / (clk_div * cpu_div); +} + +static inline unsigned ar2315_cpu_frequency(void) +{ + return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); +} + +static inline unsigned ar2315_apb_frequency(void) +{ + return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); +} + +void __init ar2315_plat_time_init(void) +{ + mips_hpt_frequency = ar2315_cpu_frequency() / 2; +} + +void __init ar2315_plat_mem_setup(void) +{ + void __iomem *sdram_base; + u32 memsize, memcfg; + u32 config; + + /* Detect memory size */ + sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE, + AR2315_SDRAMCTL_SIZE); + memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); + memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); + memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); + memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); + memsize <<= 3; + add_memory_region(0, memsize, BOOT_MEM_RAM); + iounmap(sdram_base); + + ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE); + + /* Clear any lingering AHB errors */ + config = read_c0_config(); + write_c0_config(config & ~0x3); + ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); + ar2315_rst_reg_read(AR2315_AHB_ERR1); + ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); + + _machine_restart = ar2315_restart; +} diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h new file mode 100644 index 000000000000..baeaf847223a --- /dev/null +++ b/arch/mips/ath25/ar2315.h @@ -0,0 +1,16 @@ +#ifndef __AR2315_H +#define __AR2315_H + +#ifdef CONFIG_SOC_AR2315 + +void ar2315_plat_time_init(void); +void ar2315_plat_mem_setup(void); + +#else + +static inline void ar2315_plat_time_init(void) {} +static inline void ar2315_plat_mem_setup(void) {} + +#endif + +#endif /* __AR2315_H */ diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h new file mode 100644 index 000000000000..c97d35127a5d --- /dev/null +++ b/arch/mips/ath25/ar2315_regs.h @@ -0,0 +1,387 @@ +/* + * Register definitions for AR2315+ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz + * Copyright (C) 2006-2008 Felix Fietkau + */ + +#ifndef __ASM_MACH_ATH25_AR2315_REGS_H +#define __ASM_MACH_ATH25_AR2315_REGS_H + +/* + * Address map + */ +#define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */ +#define AR2315_SPI_READ_SIZE 0x01000000 +#define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */ +#define AR2315_PCI_BASE 0x10100000 /* PCI MMR */ +#define AR2315_PCI_SIZE 0x00001000 +#define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */ +#define AR2315_SDRAMCTL_SIZE 0x00000020 +#define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */ +#define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */ +#define AR2315_RST_BASE 0x11000000 /* Reset control MMR */ +#define AR2315_RST_SIZE 0x00000100 +#define AR2315_UART0_BASE 0x11100000 /* UART MMR */ +#define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */ +#define AR2315_SPI_MMR_SIZE 0x00000010 +#define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */ +#define AR2315_PCI_EXT_SIZE 0x40000000 + +/* + * Configuration registers + */ + +/* Cold reset register */ +#define AR2315_COLD_RESET 0x0000 + +#define AR2315_RESET_COLD_AHB 0x00000001 +#define AR2315_RESET_COLD_APB 0x00000002 +#define AR2315_RESET_COLD_CPU 0x00000004 +#define AR2315_RESET_COLD_CPUWARM 0x00000008 +#define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\ + RESET_COLD_APB |\ + RESET_COLD_AHB) /* full system */ +#define AR2317_RESET_SYSTEM 0x00000010 + +/* Reset register */ +#define AR2315_RESET 0x0004 + +#define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ +#define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */ +#define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ +#define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ +#define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */ +#define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */ +#define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ +#define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */ +#define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */ +#define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */ +#define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ +#define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */ + +/* AHB master arbitration control */ +#define AR2315_AHB_ARB_CTL 0x0008 + +#define AR2315_ARB_CPU 0x00000001 /* CPU, default */ +#define AR2315_ARB_WLAN 0x00000002 /* WLAN */ +#define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ +#define AR2315_ARB_LOCAL 0x00000008 /* Local bus */ +#define AR2315_ARB_PCI 0x00000010 /* PCI bus */ +#define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */ +#define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */ + +/* Config Register */ +#define AR2315_ENDIAN_CTL 0x000c + +#define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */ +#define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */ +#define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ +#define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */ +#define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */ +#define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ +#define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ +#define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ +#define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */ +#define AR2315_CONFIG_BIG 0x00000400 +#define AR2315_CONFIG_PCIAHB 0x00000800 +#define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000 +#define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */ +#define AR2315_CONFIG_CPU_DRAM 0x00010000 +#define AR2315_CONFIG_CPU_PCI 0x00020000 +#define AR2315_CONFIG_CPU_MMR 0x00040000 + +/* NMI control */ +#define AR2315_NMI_CTL 0x0010 + +#define AR2315_NMI_EN 1 + +/* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */ +#define AR2315_SREV 0x0014 + +#define AR2315_REV_MAJ 0x000000f0 +#define AR2315_REV_MAJ_S 4 +#define AR2315_REV_MIN 0x0000000f +#define AR2315_REV_MIN_S 0 +#define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN) + +/* Interface Enable */ +#define AR2315_IF_CTL 0x0018 + +#define AR2315_IF_MASK 0x00000007 +#define AR2315_IF_DISABLED 0 /* Disable all */ +#define AR2315_IF_PCI 1 /* PCI */ +#define AR2315_IF_TS_LOCAL 2 /* Local bus */ +#define AR2315_IF_ALL 3 /* Emulation only */ +#define AR2315_IF_LOCAL_HOST 0x00000008 +#define AR2315_IF_PCI_HOST 0x00000010 +#define AR2315_IF_PCI_INTR 0x00000020 +#define AR2315_IF_PCI_CLK_MASK 0x00030000 +#define AR2315_IF_PCI_CLK_INPUT 0 +#define AR2315_IF_PCI_CLK_OUTPUT_LOW 1 +#define AR2315_IF_PCI_CLK_OUTPUT_CLK 2 +#define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3 +#define AR2315_IF_PCI_CLK_SHIFT 16 + +/* APB Interrupt control */ +#define AR2315_ISR 0x0020 +#define AR2315_IMR 0x0024 +#define AR2315_GISR 0x0028 + +#define AR2315_ISR_UART0 0x00000001 /* high speed UART */ +#define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */ +#define AR2315_ISR_SPI 0x00000004 /* SPI bus */ +#define AR2315_ISR_AHB 0x00000008 /* AHB error */ +#define AR2315_ISR_APB 0x00000010 /* APB error */ +#define AR2315_ISR_TIMER 0x00000020 /* Timer */ +#define AR2315_ISR_GPIO 0x00000040 /* GPIO */ +#define AR2315_ISR_WD 0x00000080 /* Watchdog */ +#define AR2315_ISR_IR_RSVD 0x00000100 /* IR */ + +#define AR2315_GISR_MISC 0x00000001 /* Misc */ +#define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */ +#define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ +#define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */ +#define AR2315_GISR_WMACPOLL 0x00000010 +#define AR2315_GISR_TIMER 0x00000020 +#define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */ + +/* Generic timer */ +#define AR2315_TIMER 0x0030 +#define AR2315_RELOAD 0x0034 + +/* Watchdog timer */ +#define AR2315_WDT_TIMER 0x0038 +#define AR2315_WDT_CTRL 0x003c + +#define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ +#define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */ +#define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */ + +/* CPU Performance Counters */ +#define AR2315_PERFCNT0 0x0048 +#define AR2315_PERFCNT1 0x004c + +#define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */ +#define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */ +#define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */ +#define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */ +#define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */ +#define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */ +#define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */ + +#define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */ +#define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */ +#define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */ +#define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */ +#define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/ +#define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/ +#define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */ + +/* AHB Error Reporting */ +#define AR2315_AHB_ERR0 0x0050 /* error */ +#define AR2315_AHB_ERR1 0x0054 /* haddr */ +#define AR2315_AHB_ERR2 0x0058 /* hwdata */ +#define AR2315_AHB_ERR3 0x005c /* hrdata */ +#define AR2315_AHB_ERR4 0x0060 /* status */ + +#define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */ + /* write 1 to clear all bits in ERR0 */ +#define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ +#define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ + +#define AR2315_PROCERR_HMAST 0x0000000f +#define AR2315_PROCERR_HMAST_DFLT 0 +#define AR2315_PROCERR_HMAST_WMAC 1 +#define AR2315_PROCERR_HMAST_ENET 2 +#define AR2315_PROCERR_HMAST_PCIENDPT 3 +#define AR2315_PROCERR_HMAST_LOCAL 4 +#define AR2315_PROCERR_HMAST_CPU 5 +#define AR2315_PROCERR_HMAST_PCITGT 6 +#define AR2315_PROCERR_HMAST_S 0 +#define AR2315_PROCERR_HWRITE 0x00000010 +#define AR2315_PROCERR_HSIZE 0x00000060 +#define AR2315_PROCERR_HSIZE_S 5 +#define AR2315_PROCERR_HTRANS 0x00000180 +#define AR2315_PROCERR_HTRANS_S 7 +#define AR2315_PROCERR_HBURST 0x00000e00 +#define AR2315_PROCERR_HBURST_S 9 + +/* Clock Control */ +#define AR2315_PLLC_CTL 0x0064 +#define AR2315_PLLV_CTL 0x0068 +#define AR2315_CPUCLK 0x006c +#define AR2315_AMBACLK 0x0070 +#define AR2315_SYNCCLK 0x0074 +#define AR2315_DSL_SLEEP_CTL 0x0080 +#define AR2315_DSL_SLEEP_DUR 0x0084 + +/* PLLc Control fields */ +#define AR2315_PLLC_REF_DIV_M 0x00000003 +#define AR2315_PLLC_REF_DIV_S 0 +#define AR2315_PLLC_FDBACK_DIV_M 0x0000007c +#define AR2315_PLLC_FDBACK_DIV_S 2 +#define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080 +#define AR2315_PLLC_ADD_FDBACK_DIV_S 7 +#define AR2315_PLLC_CLKC_DIV_M 0x0001c000 +#define AR2315_PLLC_CLKC_DIV_S 14 +#define AR2315_PLLC_CLKM_DIV_M 0x00700000 +#define AR2315_PLLC_CLKM_DIV_S 20 + +/* CPU CLK Control fields */ +#define AR2315_CPUCLK_CLK_SEL_M 0x00000003 +#define AR2315_CPUCLK_CLK_SEL_S 0 +#define AR2315_CPUCLK_CLK_DIV_M 0x0000000c +#define AR2315_CPUCLK_CLK_DIV_S 2 + +/* AMBA CLK Control fields */ +#define AR2315_AMBACLK_CLK_SEL_M 0x00000003 +#define AR2315_AMBACLK_CLK_SEL_S 0 +#define AR2315_AMBACLK_CLK_DIV_M 0x0000000c +#define AR2315_AMBACLK_CLK_DIV_S 2 + +/* PCI Clock Control */ +#define AR2315_PCICLK 0x00a4 + +#define AR2315_PCICLK_INPUT_M 0x00000003 +#define AR2315_PCICLK_INPUT_S 0 +#define AR2315_PCICLK_PLLC_CLKM 0 +#define AR2315_PCICLK_PLLC_CLKM1 1 +#define AR2315_PCICLK_PLLC_CLKC 2 +#define AR2315_PCICLK_REF_CLK 3 +#define AR2315_PCICLK_DIV_M 0x0000000c +#define AR2315_PCICLK_DIV_S 2 +#define AR2315_PCICLK_IN_FREQ 0 +#define AR2315_PCICLK_IN_FREQ_DIV_6 1 +#define AR2315_PCICLK_IN_FREQ_DIV_8 2 +#define AR2315_PCICLK_IN_FREQ_DIV_10 3 + +/* Observation Control Register */ +#define AR2315_OCR 0x00b0 + +#define AR2315_OCR_GPIO0_IRIN 0x00000040 +#define AR2315_OCR_GPIO1_IROUT 0x00000080 +#define AR2315_OCR_GPIO3_RXCLR 0x00000200 + +/* General Clock Control */ +#define AR2315_MISCCLK 0x00b4 + +#define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001 +#define AR2315_MISCCLK_PROCREFCLK 0x00000002 + +/* + * SDRAM Controller + * - No read or write buffers are included. + */ +#define AR2315_MEM_CFG 0x0000 +#define AR2315_MEM_CTRL 0x000c +#define AR2315_MEM_REF 0x0010 + +#define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000 +#define AR2315_MEM_CFG_DATA_WIDTH_S 13 +#define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00 +#define AR2315_MEM_CFG_COL_WIDTH_S 9 +#define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0 +#define AR2315_MEM_CFG_ROW_WIDTH_S 5 +#define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018 +#define AR2315_MEM_CFG_BANKADDR_BITS_S 3 + +/* + * Local Bus Interface Registers + */ +#define AR2315_LB_CONFIG 0x0000 + +#define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */ +#define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ +#define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ +#define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ +#define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ +#define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ +#define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ +#define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ +#define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ +#define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ +#define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ +#define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ +#define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ +#define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ +#define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ +#define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ +#define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ +#define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */ +#define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ +#define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ +#define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ +#define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */ +#define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ +#define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ +#define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ + +#define AR2315_LB_CLKSEL 0x0004 + +#define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */ + +#define AR2315_LB_1MS 0x0008 + +#define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */ + +#define AR2315_LB_MISCCFG 0x000c + +#define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ +#define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ +#define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ +#define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ +#define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ +#define AR2315_LBM_TIMEOUT_M 0x00ffff80 +#define AR2315_LBM_TIMEOUT_S 7 +#define AR2315_LBM_PORTMUX 0x07000000 + +#define AR2315_LB_RXTSOFF 0x0010 + +#define AR2315_LB_TX_CHAIN_EN 0x0100 + +#define AR2315_LB_TXEN_0 0x00000001 +#define AR2315_LB_TXEN_1 0x00000002 +#define AR2315_LB_TXEN_2 0x00000004 +#define AR2315_LB_TXEN_3 0x00000008 + +#define AR2315_LB_TX_CHAIN_DIS 0x0104 +#define AR2315_LB_TX_DESC_PTR 0x0200 + +#define AR2315_LB_RX_CHAIN_EN 0x0400 + +#define AR2315_LB_RXEN 0x00000001 + +#define AR2315_LB_RX_CHAIN_DIS 0x0404 +#define AR2315_LB_RX_DESC_PTR 0x0408 + +#define AR2315_LB_INT_STATUS 0x0500 + +#define AR2315_LB_INT_TX_DESC 0x00000001 +#define AR2315_LB_INT_TX_OK 0x00000002 +#define AR2315_LB_INT_TX_ERR 0x00000004 +#define AR2315_LB_INT_TX_EOF 0x00000008 +#define AR2315_LB_INT_RX_DESC 0x00000010 +#define AR2315_LB_INT_RX_OK 0x00000020 +#define AR2315_LB_INT_RX_ERR 0x00000040 +#define AR2315_LB_INT_RX_EOF 0x00000080 +#define AR2315_LB_INT_TX_TRUNC 0x00000100 +#define AR2315_LB_INT_TX_STARVE 0x00000200 +#define AR2315_LB_INT_LB_TIMEOUT 0x00000400 +#define AR2315_LB_INT_LB_ERR 0x00000800 +#define AR2315_LB_INT_MBOX_WR 0x00001000 +#define AR2315_LB_INT_MBOX_RD 0x00002000 + +/* Bit definitions for INT MASK are the same as INT_STATUS */ +#define AR2315_LB_INT_MASK 0x0504 + +#define AR2315_LB_INT_EN 0x0508 +#define AR2315_LB_MBOX 0x0600 + +#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */ diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c index 03baeceb3e35..6063bdf9066e 100644 --- a/arch/mips/ath25/board.c +++ b/arch/mips/ath25/board.c @@ -18,6 +18,7 @@ #include "devices.h" #include "ar5312.h" +#include "ar2315.h" static void ath25_halt(void) { @@ -32,6 +33,8 @@ void __init plat_mem_setup(void) if (is_ar5312()) ar5312_plat_mem_setup(); + else + ar2315_plat_mem_setup(); /* Disable data watchpoints */ write_c0_watchlo0(0); @@ -45,6 +48,8 @@ void __init plat_time_init(void) { if (is_ar5312()) ar5312_plat_time_init(); + else + ar2315_plat_time_init(); } unsigned int __cpuinit get_c0_compare_int(void) diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h index 5fd82d890843..ade0356df257 100644 --- a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h @@ -29,11 +29,15 @@ #define cpu_has_counter 1 #define cpu_has_ejtag 1 +#if !defined(CONFIG_SOC_AR5312) +# define cpu_has_llsc 1 +#else /* * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the * ll/sc instructions. */ -#define cpu_has_llsc 0 +# define cpu_has_llsc 0 +#endif #define cpu_has_mips16 0 #define cpu_has_mdmx 0 @@ -42,6 +46,10 @@ #define cpu_has_mips32r1 1 +#if !defined(CONFIG_SOC_AR5312) +# define cpu_has_mips32r2 1 +#endif + #define cpu_has_mips64r1 0 #define cpu_has_mips64r2 0 -- GitLab From 1753e74ed8fa3235174d5baa3421cbf8d693a42d Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:41 +0400 Subject: [PATCH 6076/9457] MIPS: ath25: add interrupts handling routines Add interrupts initialization and handling routines, also add AHB bus error interrupt handlers for both SoCs families. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8240/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/ath25/ar2315.c | 114 ++++++++++++++++++++++++++++++++++ arch/mips/ath25/ar2315.h | 2 + arch/mips/ath25/ar2315_regs.h | 23 +++++++ arch/mips/ath25/ar5312.c | 112 +++++++++++++++++++++++++++++++++ arch/mips/ath25/ar5312.h | 2 + arch/mips/ath25/ar5312_regs.h | 23 +++++++ arch/mips/ath25/board.c | 9 +++ arch/mips/ath25/devices.h | 4 ++ 9 files changed, 290 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4b5a3b962ff4..656916810aae 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -103,6 +103,7 @@ config ATH25 select CSRC_R4K select DMA_NONCOHERENT select IRQ_CPU + select IRQ_DOMAIN select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_32BIT_KERNEL diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index 828943212f03..d92aa91ae75d 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include #include #include @@ -26,6 +29,7 @@ #include "ar2315_regs.h" static void __iomem *ar2315_rst_base; +static struct irq_domain *ar2315_misc_irq_domain; static inline u32 ar2315_rst_reg_read(u32 reg) { @@ -46,6 +50,116 @@ static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) ar2315_rst_reg_write(reg, ret); } +static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) +{ + ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); + ar2315_rst_reg_read(AR2315_AHB_ERR1); + + pr_emerg("AHB fatal error\n"); + machine_restart("AHB error"); /* Catastrophic failure */ + + return IRQ_HANDLED; +} + +static struct irqaction ar2315_ahb_err_interrupt = { + .handler = ar2315_ahb_err_handler, + .name = "ar2315-ahb-error", +}; + +static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc) +{ + u32 pending = ar2315_rst_reg_read(AR2315_ISR) & + ar2315_rst_reg_read(AR2315_IMR); + unsigned nr, misc_irq = 0; + + if (pending) { + struct irq_domain *domain = irq_get_handler_data(irq); + + nr = __ffs(pending); + misc_irq = irq_find_mapping(domain, nr); + } + + if (misc_irq) { + if (nr == AR2315_MISC_IRQ_GPIO) + ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); + else if (nr == AR2315_MISC_IRQ_WATCHDOG) + ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); + generic_handle_irq(misc_irq); + } else { + spurious_interrupt(); + } +} + +static void ar2315_misc_irq_unmask(struct irq_data *d) +{ + ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); +} + +static void ar2315_misc_irq_mask(struct irq_data *d) +{ + ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); +} + +static struct irq_chip ar2315_misc_irq_chip = { + .name = "ar2315-misc", + .irq_unmask = ar2315_misc_irq_unmask, + .irq_mask = ar2315_misc_irq_mask, +}; + +static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); + return 0; +} + +static struct irq_domain_ops ar2315_misc_irq_domain_ops = { + .map = ar2315_misc_irq_map, +}; + +/* + * Called when an interrupt is received, this function + * determines exactly which interrupt it was, and it + * invokes the appropriate handler. + * + * Implicitly, we also define interrupt priority by + * choosing which to dispatch first. + */ +static void ar2315_irq_dispatch(void) +{ + u32 pending = read_c0_status() & read_c0_cause(); + + if (pending & CAUSEF_IP3) + do_IRQ(AR2315_IRQ_WLAN0); + else if (pending & CAUSEF_IP2) + do_IRQ(AR2315_IRQ_MISC); + else if (pending & CAUSEF_IP7) + do_IRQ(ATH25_IRQ_CPU_CLOCK); + else + spurious_interrupt(); +} + +void __init ar2315_arch_init_irq(void) +{ + struct irq_domain *domain; + unsigned irq; + + ath25_irq_dispatch = ar2315_irq_dispatch; + + domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, + &ar2315_misc_irq_domain_ops, NULL); + if (!domain) + panic("Failed to add IRQ domain"); + + irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); + setup_irq(irq, &ar2315_ahb_err_interrupt); + + irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler); + irq_set_handler_data(AR2315_IRQ_MISC, domain); + + ar2315_misc_irq_domain = domain; +} + static void ar2315_restart(char *command) { void (*mips_reset_vec)(void) = (void *)0xbfc00000; diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h index baeaf847223a..da5b843dd3a6 100644 --- a/arch/mips/ath25/ar2315.h +++ b/arch/mips/ath25/ar2315.h @@ -3,11 +3,13 @@ #ifdef CONFIG_SOC_AR2315 +void ar2315_arch_init_irq(void); void ar2315_plat_time_init(void); void ar2315_plat_mem_setup(void); #else +static inline void ar2315_arch_init_irq(void) {} static inline void ar2315_plat_time_init(void) {} static inline void ar2315_plat_mem_setup(void) {} diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h index c97d35127a5d..16e86149cb74 100644 --- a/arch/mips/ath25/ar2315_regs.h +++ b/arch/mips/ath25/ar2315_regs.h @@ -14,6 +14,29 @@ #ifndef __ASM_MACH_ATH25_AR2315_REGS_H #define __ASM_MACH_ATH25_AR2315_REGS_H +/* + * IRQs + */ +#define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ +#define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ +#define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ +#define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ +#define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ + +/* + * Miscellaneous interrupts, which share IP2. + */ +#define AR2315_MISC_IRQ_UART0 0 +#define AR2315_MISC_IRQ_I2C_RSVD 1 +#define AR2315_MISC_IRQ_SPI 2 +#define AR2315_MISC_IRQ_AHB 3 +#define AR2315_MISC_IRQ_APB 4 +#define AR2315_MISC_IRQ_TIMER 5 +#define AR2315_MISC_IRQ_GPIO 6 +#define AR2315_MISC_IRQ_WATCHDOG 7 +#define AR2315_MISC_IRQ_IR_RSVD 8 +#define AR2315_MISC_IRQ_COUNT 9 + /* * Address map */ diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index c2adaf2cd73a..b99a02a9e20e 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include #include #include @@ -26,6 +29,7 @@ #include "ar5312_regs.h" static void __iomem *ar5312_rst_base; +static struct irq_domain *ar5312_misc_irq_domain; static inline u32 ar5312_rst_reg_read(u32 reg) { @@ -46,6 +50,114 @@ static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) ar5312_rst_reg_write(reg, ret); } +static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id) +{ + u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1); + u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */ + u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1); + u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */ + + pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", + proc_addr, proc1, dma_addr, dma1); + + machine_restart("AHB error"); /* Catastrophic failure */ + return IRQ_HANDLED; +} + +static struct irqaction ar5312_ahb_err_interrupt = { + .handler = ar5312_ahb_err_handler, + .name = "ar5312-ahb-error", +}; + +static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) +{ + u32 pending = ar5312_rst_reg_read(AR5312_ISR) & + ar5312_rst_reg_read(AR5312_IMR); + unsigned nr, misc_irq = 0; + + if (pending) { + struct irq_domain *domain = irq_get_handler_data(irq); + + nr = __ffs(pending); + misc_irq = irq_find_mapping(domain, nr); + } + + if (misc_irq) { + generic_handle_irq(misc_irq); + if (nr == AR5312_MISC_IRQ_TIMER) + ar5312_rst_reg_read(AR5312_TIMER); + } else { + spurious_interrupt(); + } +} + +/* Enable the specified AR5312_MISC_IRQ interrupt */ +static void ar5312_misc_irq_unmask(struct irq_data *d) +{ + ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq)); +} + +/* Disable the specified AR5312_MISC_IRQ interrupt */ +static void ar5312_misc_irq_mask(struct irq_data *d) +{ + ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0); + ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */ +} + +static struct irq_chip ar5312_misc_irq_chip = { + .name = "ar5312-misc", + .irq_unmask = ar5312_misc_irq_unmask, + .irq_mask = ar5312_misc_irq_mask, +}; + +static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq); + return 0; +} + +static struct irq_domain_ops ar5312_misc_irq_domain_ops = { + .map = ar5312_misc_irq_map, +}; + +static void ar5312_irq_dispatch(void) +{ + u32 pending = read_c0_status() & read_c0_cause(); + + if (pending & CAUSEF_IP2) + do_IRQ(AR5312_IRQ_WLAN0); + else if (pending & CAUSEF_IP5) + do_IRQ(AR5312_IRQ_WLAN1); + else if (pending & CAUSEF_IP6) + do_IRQ(AR5312_IRQ_MISC); + else if (pending & CAUSEF_IP7) + do_IRQ(ATH25_IRQ_CPU_CLOCK); + else + spurious_interrupt(); +} + +void __init ar5312_arch_init_irq(void) +{ + struct irq_domain *domain; + unsigned irq; + + ath25_irq_dispatch = ar5312_irq_dispatch; + + domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT, + &ar5312_misc_irq_domain_ops, NULL); + if (!domain) + panic("Failed to add IRQ domain"); + + irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); + setup_irq(irq, &ar5312_ahb_err_interrupt); + + irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler); + irq_set_handler_data(AR5312_IRQ_MISC, domain); + + ar5312_misc_irq_domain = domain; +} + static void ar5312_restart(char *command) { /* reset the system */ diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h index 9e1e56e24eed..254f04f371b5 100644 --- a/arch/mips/ath25/ar5312.h +++ b/arch/mips/ath25/ar5312.h @@ -3,11 +3,13 @@ #ifdef CONFIG_SOC_AR5312 +void ar5312_arch_init_irq(void); void ar5312_plat_time_init(void); void ar5312_plat_mem_setup(void); #else +static inline void ar5312_arch_init_irq(void) {} static inline void ar5312_plat_time_init(void) {} static inline void ar5312_plat_mem_setup(void) {} diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h index ff1201119be0..4b947f967439 100644 --- a/arch/mips/ath25/ar5312_regs.h +++ b/arch/mips/ath25/ar5312_regs.h @@ -11,6 +11,29 @@ #ifndef __ASM_MACH_ATH25_AR5312_REGS_H #define __ASM_MACH_ATH25_AR5312_REGS_H +/* + * IRQs + */ +#define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ +#define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ +#define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ +#define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ +#define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ + +/* + * Miscellaneous interrupts, which share IP6. + */ +#define AR5312_MISC_IRQ_TIMER 0 +#define AR5312_MISC_IRQ_AHB_PROC 1 +#define AR5312_MISC_IRQ_AHB_DMA 2 +#define AR5312_MISC_IRQ_GPIO 3 +#define AR5312_MISC_IRQ_UART0 4 +#define AR5312_MISC_IRQ_UART0_DMA 5 +#define AR5312_MISC_IRQ_WATCHDOG 6 +#define AR5312_MISC_IRQ_LOCAL 7 +#define AR5312_MISC_IRQ_SPI 8 +#define AR5312_MISC_IRQ_COUNT 9 + /* * Address Map * diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c index 6063bdf9066e..d4675e04a634 100644 --- a/arch/mips/ath25/board.c +++ b/arch/mips/ath25/board.c @@ -20,6 +20,8 @@ #include "ar5312.h" #include "ar2315.h" +void (*ath25_irq_dispatch)(void); + static void ath25_halt(void) { local_irq_disable(); @@ -42,6 +44,7 @@ void __init plat_mem_setup(void) asmlinkage void plat_irq_dispatch(void) { + ath25_irq_dispatch(); } void __init plat_time_init(void) @@ -61,4 +64,10 @@ void __init arch_init_irq(void) { clear_c0_status(ST0_IM); mips_cpu_irq_init(); + + /* Initialize interrupt controllers */ + if (is_ar5312()) + ar5312_arch_init_irq(); + else + ar2315_arch_init_irq(); } diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index e25a3262256d..2985586a0f2c 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -5,6 +5,10 @@ #define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) +#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ + +extern void (*ath25_irq_dispatch)(void); + static inline bool is_ar2315(void) { return (current_cpu_data.cputype == CPU_4KEC); -- GitLab From 8aaa7278c0c98a77ec36e1fed7d9bede58164a26 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:42 +0400 Subject: [PATCH 6077/9457] MIPS: ath25: add early printk support Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8241/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/ath25/Makefile | 2 ++ arch/mips/ath25/early_printk.c | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 arch/mips/ath25/early_printk.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 656916810aae..3348989008b5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -107,6 +107,7 @@ config ATH25 select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_32BIT_KERNEL + select SYS_HAS_EARLY_PRINTK help Support for Atheros AR231x and Atheros AR531x based boards diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile index 201b7d412902..eabad7da446a 100644 --- a/arch/mips/ath25/Makefile +++ b/arch/mips/ath25/Makefile @@ -10,5 +10,7 @@ obj-y += board.o prom.o devices.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + obj-$(CONFIG_SOC_AR5312) += ar5312.o obj-$(CONFIG_SOC_AR2315) += ar2315.o diff --git a/arch/mips/ath25/early_printk.c b/arch/mips/ath25/early_printk.c new file mode 100644 index 000000000000..36035b628161 --- /dev/null +++ b/arch/mips/ath25/early_printk.c @@ -0,0 +1,44 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2010 Gabor Juhos + */ + +#include +#include +#include + +#include "devices.h" +#include "ar2315_regs.h" +#include "ar5312_regs.h" + +static inline void prom_uart_wr(void __iomem *base, unsigned reg, + unsigned char ch) +{ + __raw_writel(ch, base + 4 * reg); +} + +static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg) +{ + return __raw_readl(base + 4 * reg); +} + +void prom_putchar(unsigned char ch) +{ + static void __iomem *base; + + if (unlikely(base == NULL)) { + if (is_ar2315()) + base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE)); + else + base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE)); + } + + while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) + ; + prom_uart_wr(base, UART_TX, ch); + while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) + ; +} -- GitLab From 1ac91b1f686e9d819b16525baf2e8db3c282edba Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:43 +0400 Subject: [PATCH 6078/9457] MIPS: ath25: add UART support Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8242/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/ar2315.c | 8 ++++++++ arch/mips/ath25/ar2315.h | 2 ++ arch/mips/ath25/ar5312.c | 8 ++++++++ arch/mips/ath25/ar5312.h | 2 ++ arch/mips/ath25/devices.c | 31 +++++++++++++++++++++++++++++++ arch/mips/ath25/devices.h | 2 ++ 6 files changed, 53 insertions(+) diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index d92aa91ae75d..d10eac4cd828 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -267,3 +267,11 @@ void __init ar2315_plat_mem_setup(void) _machine_restart = ar2315_restart; } + +void __init ar2315_arch_init(void) +{ + unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, + AR2315_MISC_IRQ_UART0); + + ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); +} diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h index da5b843dd3a6..4af5f4c75f44 100644 --- a/arch/mips/ath25/ar2315.h +++ b/arch/mips/ath25/ar2315.h @@ -6,12 +6,14 @@ void ar2315_arch_init_irq(void); void ar2315_plat_time_init(void); void ar2315_plat_mem_setup(void); +void ar2315_arch_init(void); #else static inline void ar2315_arch_init_irq(void) {} static inline void ar2315_plat_time_init(void) {} static inline void ar2315_plat_mem_setup(void) {} +static inline void ar2315_arch_init(void) {} #endif diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index b99a02a9e20e..398d4fd4dd2d 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -265,3 +265,11 @@ void __init ar5312_plat_mem_setup(void) _machine_restart = ar5312_restart; } + +void __init ar5312_arch_init(void) +{ + unsigned irq = irq_create_mapping(ar5312_misc_irq_domain, + AR5312_MISC_IRQ_UART0); + + ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency()); +} diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h index 254f04f371b5..86dfc6d04a6d 100644 --- a/arch/mips/ath25/ar5312.h +++ b/arch/mips/ath25/ar5312.h @@ -6,12 +6,14 @@ void ar5312_arch_init_irq(void); void ar5312_plat_time_init(void); void ar5312_plat_mem_setup(void); +void ar5312_arch_init(void); #else static inline void ar5312_arch_init_irq(void) {} static inline void ar5312_plat_time_init(void) {} static inline void ar5312_plat_mem_setup(void) {} +static inline void ar5312_arch_init(void) {} #endif diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c index 049ab4477954..400419d8e7d9 100644 --- a/arch/mips/ath25/devices.c +++ b/arch/mips/ath25/devices.c @@ -1,10 +1,41 @@ #include #include +#include #include #include "devices.h" +#include "ar5312.h" +#include "ar2315.h" const char *get_system_type(void) { return "Atheros (unknown)"; } + +void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) +{ + struct uart_port s; + + memset(&s, 0, sizeof(s)); + + s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP; + s.iotype = UPIO_MEM32; + s.irq = irq; + s.regshift = 2; + s.mapbase = mapbase; + s.uartclk = uartclk; + + early_serial_setup(&s); +} + +static int __init ath25_arch_init(void) +{ + if (is_ar5312()) + ar5312_arch_init(); + else + ar2315_arch_init(); + + return 0; +} + +arch_initcall(ath25_arch_init); diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index 2985586a0f2c..23b53cb71c72 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -9,6 +9,8 @@ extern void (*ath25_irq_dispatch)(void); +void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); + static inline bool is_ar2315(void) { return (current_cpu_data.cputype == CPU_4KEC); -- GitLab From a7473717483ef3bb78563611bf1b3b82c5515b2e Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:44 +0400 Subject: [PATCH 6079/9457] MIPS: ath25: add board configuration detection All boards based on AR5312/AR2315 SoC have a special structure located at the end of flash. This structure contains board-specific data such as Ethernet and Wireless MAC addresses. The flash is mapped to the memmory at predefined location. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8243/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/ar2315.c | 6 + arch/mips/ath25/ar2315.h | 2 + arch/mips/ath25/ar5312.c | 39 +++++ arch/mips/ath25/ar5312.h | 2 + arch/mips/ath25/board.c | 161 ++++++++++++++++++ arch/mips/ath25/devices.c | 15 ++ arch/mips/ath25/devices.h | 2 + .../include/asm/mach-ath25/ath25_platform.h | 73 ++++++++ 8 files changed, 300 insertions(+) create mode 100644 arch/mips/include/asm/mach-ath25/ath25_platform.h diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index d10eac4cd828..3ba8e757add6 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -160,6 +160,12 @@ void __init ar2315_arch_init_irq(void) ar2315_misc_irq_domain = domain; } +void __init ar2315_init_devices(void) +{ + /* Find board configuration */ + ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); +} + static void ar2315_restart(char *command) { void (*mips_reset_vec)(void) = (void *)0xbfc00000; diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h index 4af5f4c75f44..877afe63eed5 100644 --- a/arch/mips/ath25/ar2315.h +++ b/arch/mips/ath25/ar2315.h @@ -4,6 +4,7 @@ #ifdef CONFIG_SOC_AR2315 void ar2315_arch_init_irq(void); +void ar2315_init_devices(void); void ar2315_plat_time_init(void); void ar2315_plat_mem_setup(void); void ar2315_arch_init(void); @@ -11,6 +12,7 @@ void ar2315_arch_init(void); #else static inline void ar2315_arch_init_irq(void) {} +static inline void ar2315_init_devices(void) {} static inline void ar2315_plat_time_init(void) {} static inline void ar2315_plat_mem_setup(void) {} static inline void ar2315_arch_init(void) {} diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index 398d4fd4dd2d..41bd56d6ab23 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -158,6 +158,45 @@ void __init ar5312_arch_init_irq(void) ar5312_misc_irq_domain = domain; } +static void __init ar5312_flash_init(void) +{ + void __iomem *flashctl_base; + u32 ctl; + + flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE, + AR5312_FLASHCTL_SIZE); + + /* + * Configure flash bank 0. + * Assume 8M window size. Flash will be aliased if it's smaller + */ + ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); + ctl &= AR5312_FLASHCTL_MW; + ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; + ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; + ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; + ctl |= 0x07 << AR5312_FLASHCTL_WST2_S; + __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0); + + /* Disable other flash banks */ + ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1); + ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); + __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1); + ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2); + ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); + __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2); + + iounmap(flashctl_base); +} + +void __init ar5312_init_devices(void) +{ + ar5312_flash_init(); + + /* Locate board/radio config data */ + ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); +} + static void ar5312_restart(char *command) { /* reset the system */ diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h index 86dfc6d04a6d..470abb0052bd 100644 --- a/arch/mips/ath25/ar5312.h +++ b/arch/mips/ath25/ar5312.h @@ -4,6 +4,7 @@ #ifdef CONFIG_SOC_AR5312 void ar5312_arch_init_irq(void); +void ar5312_init_devices(void); void ar5312_plat_time_init(void); void ar5312_plat_mem_setup(void); void ar5312_arch_init(void); @@ -11,6 +12,7 @@ void ar5312_arch_init(void); #else static inline void ar5312_arch_init_irq(void) {} +static inline void ar5312_init_devices(void) {} static inline void ar5312_plat_time_init(void) {} static inline void ar5312_plat_mem_setup(void) {} static inline void ar5312_arch_init(void) {} diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c index d4675e04a634..b8bb78282d6a 100644 --- a/arch/mips/ath25/board.c +++ b/arch/mips/ath25/board.c @@ -16,12 +16,173 @@ #include #include +#include #include "devices.h" #include "ar5312.h" #include "ar2315.h" void (*ath25_irq_dispatch)(void); +static inline bool check_radio_magic(const void __iomem *addr) +{ + addr += 0x7a; /* offset for flash magic */ + return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5); +} + +static inline bool check_notempty(const void __iomem *addr) +{ + return __raw_readl(addr) != 0xffffffff; +} + +static inline bool check_board_data(const void __iomem *addr, bool broken) +{ + /* config magic found */ + if (__raw_readl(addr) == ATH25_BD_MAGIC) + return true; + + if (!broken) + return false; + + /* broken board data detected, use radio data to find the + * offset, user will fix this */ + + if (check_radio_magic(addr + 0x1000)) + return true; + if (check_radio_magic(addr + 0xf8)) + return true; + + return false; +} + +static const void __iomem * __init find_board_config(const void __iomem *limit, + const bool broken) +{ + const void __iomem *addr; + const void __iomem *begin = limit - 0x1000; + const void __iomem *end = limit - 0x30000; + + for (addr = begin; addr >= end; addr -= 0x1000) + if (check_board_data(addr, broken)) + return addr; + + return NULL; +} + +static const void __iomem * __init find_radio_config(const void __iomem *limit, + const void __iomem *bcfg) +{ + const void __iomem *rcfg, *begin, *end; + + /* + * Now find the start of Radio Configuration data, using heuristics: + * Search forward from Board Configuration data by 0x1000 bytes + * at a time until we find non-0xffffffff. + */ + begin = bcfg + 0x1000; + end = limit; + for (rcfg = begin; rcfg < end; rcfg += 0x1000) + if (check_notempty(rcfg) && check_radio_magic(rcfg)) + return rcfg; + + /* AR2316 relocates radio config to new location */ + begin = bcfg + 0xf8; + end = limit - 0x1000 + 0xf8; + for (rcfg = begin; rcfg < end; rcfg += 0x1000) + if (check_notempty(rcfg) && check_radio_magic(rcfg)) + return rcfg; + + return NULL; +} + +/* + * NB: Search region size could be larger than the actual flash size, + * but this shouldn't be a problem here, because the flash + * will simply be mapped multiple times. + */ +int __init ath25_find_config(phys_addr_t base, unsigned long size) +{ + const void __iomem *flash_base, *flash_limit; + struct ath25_boarddata *config; + unsigned int rcfg_size; + int broken_boarddata = 0; + const void __iomem *bcfg, *rcfg; + u8 *board_data; + u8 *radio_data; + u8 *mac_addr; + u32 offset; + + flash_base = ioremap_nocache(base, size); + flash_limit = flash_base + size; + + ath25_board.config = NULL; + ath25_board.radio = NULL; + + /* Copy the board and radio data to RAM, because accessing the mapped + * memory of the flash directly after booting is not safe */ + + /* Try to find valid board and radio data */ + bcfg = find_board_config(flash_limit, false); + + /* If that fails, try to at least find valid radio data */ + if (!bcfg) { + bcfg = find_board_config(flash_limit, true); + broken_boarddata = 1; + } + + if (!bcfg) { + pr_warn("WARNING: No board configuration data found!\n"); + goto error; + } + + board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL); + ath25_board.config = (struct ath25_boarddata *)board_data; + memcpy_fromio(board_data, bcfg, 0x100); + if (broken_boarddata) { + pr_warn("WARNING: broken board data detected\n"); + config = ath25_board.config; + if (is_zero_ether_addr(config->enet0_mac)) { + pr_info("Fixing up empty mac addresses\n"); + config->reset_config_gpio = 0xffff; + config->sys_led_gpio = 0xffff; + random_ether_addr(config->wlan0_mac); + config->wlan0_mac[0] &= ~0x06; + random_ether_addr(config->enet0_mac); + random_ether_addr(config->enet1_mac); + } + } + + /* Radio config starts 0x100 bytes after board config, regardless + * of what the physical layout on the flash chip looks like */ + + rcfg = find_radio_config(flash_limit, bcfg); + if (!rcfg) { + pr_warn("WARNING: Could not find Radio Configuration data\n"); + goto error; + } + + radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff); + ath25_board.radio = radio_data; + offset = radio_data - board_data; + pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg, + offset); + rcfg_size = BOARD_CONFIG_BUFSZ - offset; + memcpy_fromio(radio_data, rcfg, rcfg_size); + + mac_addr = &radio_data[0x1d * 2]; + if (is_broadcast_ether_addr(mac_addr)) { + pr_info("Radio MAC is blank; using board-data\n"); + ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac); + } + + iounmap(flash_base); + + return 0; + +error: + iounmap(flash_base); + return -ENODEV; +} + static void ath25_halt(void) { local_irq_disable(); diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c index 400419d8e7d9..d24dbb1ef8ea 100644 --- a/arch/mips/ath25/devices.c +++ b/arch/mips/ath25/devices.c @@ -3,10 +3,13 @@ #include #include +#include #include "devices.h" #include "ar5312.h" #include "ar2315.h" +struct ar231x_board_config ath25_board; + const char *get_system_type(void) { return "Atheros (unknown)"; @@ -28,6 +31,18 @@ void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) early_serial_setup(&s); } +static int __init ath25_register_devices(void) +{ + if (is_ar5312()) + ar5312_init_devices(); + else + ar2315_init_devices(); + + return 0; +} + +device_initcall(ath25_register_devices); + static int __init ath25_arch_init(void) { if (is_ar5312()) diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index 23b53cb71c72..65e86cc46e49 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -7,8 +7,10 @@ #define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ +extern struct ar231x_board_config ath25_board; extern void (*ath25_irq_dispatch)(void); +int ath25_find_config(phys_addr_t offset, unsigned long size); void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); static inline bool is_ar2315(void) diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h new file mode 100644 index 000000000000..4f4ee4f9e5ec --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h @@ -0,0 +1,73 @@ +#ifndef __ASM_MACH_ATH25_PLATFORM_H +#define __ASM_MACH_ATH25_PLATFORM_H + +#include + +/* + * This is board-specific data that is stored in a "fixed" location in flash. + * It is shared across operating systems, so it should not be changed lightly. + * The main reason we need it is in order to extract the ethernet MAC + * address(es). + */ +struct ath25_boarddata { + u32 magic; /* board data is valid */ +#define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */ + u16 cksum; /* checksum (starting with BD_REV 2) */ + u16 rev; /* revision of this struct */ +#define BD_REV 4 + char board_name[64]; /* Name of board */ + u16 major; /* Board major number */ + u16 minor; /* Board minor number */ + u32 flags; /* Board configuration */ +#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ +#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ +#define BD_UART1 0x00000004 /* UART1 is stuffed */ +#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ +#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ +#define BD_SYSLED 0x00000020 /* System LED stuffed */ +#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ +#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ +#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ +#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ +#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */ +#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ +#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ +#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ +#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ +#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ +#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ +#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ + u16 reset_config_gpio; /* Reset factory GPIO pin */ + u16 sys_led_gpio; /* System LED GPIO pin */ + + u32 cpu_freq; /* CPU core frequency in Hz */ + u32 sys_freq; /* System frequency in Hz */ + u32 cnt_freq; /* Calculated C0_COUNT frequency */ + + u8 wlan0_mac[ETH_ALEN]; + u8 enet0_mac[ETH_ALEN]; + u8 enet1_mac[ETH_ALEN]; + + u16 pci_id; /* Pseudo PCIID for common code */ + u16 mem_cap; /* cap bank1 in MB */ + + /* version 3 */ + u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */ +}; + +#define BOARD_CONFIG_BUFSZ 0x1000 + +/* + * Platform device information for the Wireless MAC + */ +struct ar231x_board_config { + u16 devid; + + /* board config data */ + struct ath25_boarddata *config; + + /* radio calibration data */ + const char *radio; +}; + +#endif /* __ASM_MACH_ATH25_PLATFORM_H */ -- GitLab From 1654861f6e02e74a2ba059d1f62dc0356429d7cf Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:45 +0400 Subject: [PATCH 6080/9457] MIPS: ath25: add SoC type detection Detect SoC type based on device ID and board configuration data. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8244/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/ar2315.c | 22 ++++++++++++++++++++++ arch/mips/ath25/ar5312.c | 23 +++++++++++++++++++++++ arch/mips/ath25/devices.c | 17 ++++++++++++++++- arch/mips/ath25/devices.h | 16 ++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index 3ba8e757add6..52805b725a67 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -24,6 +24,8 @@ #include #include +#include + #include "devices.h" #include "ar2315.h" #include "ar2315_regs.h" @@ -249,6 +251,7 @@ void __init ar2315_plat_mem_setup(void) { void __iomem *sdram_base; u32 memsize, memcfg; + u32 devid; u32 config; /* Detect memory size */ @@ -264,6 +267,25 @@ void __init ar2315_plat_mem_setup(void) ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE); + /* Detect the hardware based on the device ID */ + devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; + switch (devid) { + case 0x91: /* Need to check */ + ath25_soc = ATH25_SOC_AR2318; + break; + case 0x90: + ath25_soc = ATH25_SOC_AR2317; + break; + case 0x87: + ath25_soc = ATH25_SOC_AR2316; + break; + case 0x86: + default: + ath25_soc = ATH25_SOC_AR2315; + break; + } + ath25_board.devid = devid; + /* Clear any lingering AHB errors */ config = read_c0_config(); write_c0_config(config & ~0x3); diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index 41bd56d6ab23..26942a2c298d 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -24,6 +24,8 @@ #include #include +#include + #include "devices.h" #include "ar5312.h" #include "ar5312_regs.h" @@ -191,10 +193,25 @@ static void __init ar5312_flash_init(void) void __init ar5312_init_devices(void) { + struct ath25_boarddata *config; + ar5312_flash_init(); /* Locate board/radio config data */ ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); + config = ath25_board.config; + + /* AR2313 has CPU minor rev. 10 */ + if ((current_cpu_data.processor_id & 0xff) == 0x0a) + ath25_soc = ATH25_SOC_AR2313; + + /* AR2312 shares the same Silicon ID as AR5312 */ + else if (config->flags & BD_ISCASPER) + ath25_soc = ATH25_SOC_AR2312; + + /* Everything else is probably AR5312 or compatible */ + else + ath25_soc = ATH25_SOC_AR5312; } static void ar5312_restart(char *command) @@ -282,6 +299,7 @@ void __init ar5312_plat_mem_setup(void) { void __iomem *sdram_base; u32 memsize, memcfg, bank0_ac, bank1_ac; + u32 devid; /* Detect memory size */ sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE, @@ -297,6 +315,11 @@ void __init ar5312_plat_mem_setup(void) ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE); + devid = ar5312_rst_reg_read(AR5312_REV); + devid >>= AR5312_REV_WMAC_MIN_S; + devid &= AR5312_REV_CHIP; + ath25_board.devid = (u16)devid; + /* Clear any lingering AHB errors */ ar5312_rst_reg_read(AR5312_PROCADDR); ar5312_rst_reg_read(AR5312_DMAADDR); diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c index d24dbb1ef8ea..62185472ef28 100644 --- a/arch/mips/ath25/devices.c +++ b/arch/mips/ath25/devices.c @@ -9,10 +9,25 @@ #include "ar2315.h" struct ar231x_board_config ath25_board; +enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; + +static const char * const soc_type_strings[] = { + [ATH25_SOC_AR5312] = "Atheros AR5312", + [ATH25_SOC_AR2312] = "Atheros AR2312", + [ATH25_SOC_AR2313] = "Atheros AR2313", + [ATH25_SOC_AR2315] = "Atheros AR2315", + [ATH25_SOC_AR2316] = "Atheros AR2316", + [ATH25_SOC_AR2317] = "Atheros AR2317", + [ATH25_SOC_AR2318] = "Atheros AR2318", + [ATH25_SOC_UNKNOWN] = "Atheros (unknown)", +}; const char *get_system_type(void) { - return "Atheros (unknown)"; + if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) || + !soc_type_strings[ath25_soc]) + return soc_type_strings[ATH25_SOC_UNKNOWN]; + return soc_type_strings[ath25_soc]; } void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index 65e86cc46e49..55adcf4f2b48 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -7,6 +7,22 @@ #define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ +enum ath25_soc_type { + /* handled by ar5312.c */ + ATH25_SOC_AR2312, + ATH25_SOC_AR2313, + ATH25_SOC_AR5312, + + /* handled by ar2315.c */ + ATH25_SOC_AR2315, + ATH25_SOC_AR2316, + ATH25_SOC_AR2317, + ATH25_SOC_AR2318, + + ATH25_SOC_UNKNOWN +}; + +extern enum ath25_soc_type ath25_soc; extern struct ar231x_board_config ath25_board; extern void (*ath25_irq_dispatch)(void); -- GitLab From d58eaa7ffdcb58ab8bb95927149e2f152ec163c6 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:46 +0400 Subject: [PATCH 6081/9457] MIPS: ath25: register AR5312 flash controller AR5312 SoC flash controller maps the flash content to memory and translates the memory access operations to the flash access operations. Such controller is fully supported by the physmap-flash driver. Signed-off-by: Sergey Ryazanov R5312 SoC flash Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8245/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/ar5312.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index 26942a2c298d..383dd6c38e0a 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -160,6 +162,24 @@ void __init ar5312_arch_init_irq(void) ar5312_misc_irq_domain = domain; } +static struct physmap_flash_data ar5312_flash_data = { + .width = 2, +}; + +static struct resource ar5312_flash_resource = { + .start = AR5312_FLASH_BASE, + .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ar5312_physmap_flash = { + .name = "physmap-flash", + .id = 0, + .dev.platform_data = &ar5312_flash_data, + .resource = &ar5312_flash_resource, + .num_resources = 1, +}; + static void __init ar5312_flash_init(void) { void __iomem *flashctl_base; @@ -168,12 +188,24 @@ static void __init ar5312_flash_init(void) flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE, AR5312_FLASHCTL_SIZE); + ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); + ctl &= AR5312_FLASHCTL_MW; + + /* fixup flash width */ + switch (ctl) { + case AR5312_FLASHCTL_MW16: + ar5312_flash_data.width = 2; + break; + case AR5312_FLASHCTL_MW8: + default: + ar5312_flash_data.width = 1; + break; + } + /* * Configure flash bank 0. * Assume 8M window size. Flash will be aliased if it's smaller */ - ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); - ctl &= AR5312_FLASHCTL_MW; ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; @@ -212,6 +244,8 @@ void __init ar5312_init_devices(void) /* Everything else is probably AR5312 or compatible */ else ath25_soc = ATH25_SOC_AR5312; + + platform_device_register(&ar5312_physmap_flash); } static void ar5312_restart(char *command) -- GitLab From 3ed7a2a702dc0f5bc44d67f27a1a289356b5dc42 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:47 +0400 Subject: [PATCH 6082/9457] MIPS: ath25: add AR2315 PCI host controller driver Add PCI host controller driver and DMA address calculation hook. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8246/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/Kconfig | 7 + arch/mips/ath25/ar2315.c | 57 ++ .../include/asm/mach-ath25/dma-coherence.h | 24 +- arch/mips/pci/Makefile | 1 + arch/mips/pci/pci-ar2315.c | 511 ++++++++++++++++++ 5 files changed, 597 insertions(+), 3 deletions(-) create mode 100644 arch/mips/pci/pci-ar2315.c diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig index ca3dde472bef..fc19dd57e42d 100644 --- a/arch/mips/ath25/Kconfig +++ b/arch/mips/ath25/Kconfig @@ -7,3 +7,10 @@ config SOC_AR2315 bool "Atheros AR2315+ SoC support" depends on ATH25 default y + +config PCI_AR2315 + bool "Atheros AR2315 PCI controller support" + depends on SOC_AR2315 + select HW_HAS_PCI + select PCI + default y diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index 52805b725a67..f02478915afd 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,10 @@ static void ar2315_irq_dispatch(void) if (pending & CAUSEF_IP3) do_IRQ(AR2315_IRQ_WLAN0); +#ifdef CONFIG_PCI_AR2315 + else if (pending & CAUSEF_IP5) + do_IRQ(AR2315_IRQ_LCBUS_PCI); +#endif else if (pending & CAUSEF_IP2) do_IRQ(AR2315_IRQ_MISC); else if (pending & CAUSEF_IP7) @@ -296,10 +301,62 @@ void __init ar2315_plat_mem_setup(void) _machine_restart = ar2315_restart; } +#ifdef CONFIG_PCI_AR2315 +static struct resource ar2315_pci_res[] = { + { + .name = "ar2315-pci-ctrl", + .flags = IORESOURCE_MEM, + .start = AR2315_PCI_BASE, + .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, + }, + { + .name = "ar2315-pci-ext", + .flags = IORESOURCE_MEM, + .start = AR2315_PCI_EXT_BASE, + .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, + }, + { + .name = "ar2315-pci", + .flags = IORESOURCE_IRQ, + .start = AR2315_IRQ_LCBUS_PCI, + .end = AR2315_IRQ_LCBUS_PCI, + }, +}; +#endif + void __init ar2315_arch_init(void) { unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, AR2315_MISC_IRQ_UART0); ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); + +#ifdef CONFIG_PCI_AR2315 + if (ath25_soc == ATH25_SOC_AR2315) { + /* Reset PCI DMA logic */ + ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); + msleep(20); + ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); + msleep(20); + + /* Configure endians */ + ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | + AR2315_CONFIG_PCIAHB_BRIDGE); + + /* Configure as PCI host with DMA */ + ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | + (AR2315_PCICLK_IN_FREQ_DIV_6 << + AR2315_PCICLK_DIV_S)); + ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); + ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | + AR2315_IF_MASK, AR2315_IF_PCI | + AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | + (AR2315_IF_PCI_CLK_OUTPUT_CLK << + AR2315_IF_PCI_CLK_SHIFT)); + + platform_device_register_simple("ar2315-pci", -1, + ar2315_pci_res, + ARRAY_SIZE(ar2315_pci_res)); + } +#endif } diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h index 8b3d0cca4505..d8009c93a465 100644 --- a/arch/mips/include/asm/mach-ath25/dma-coherence.h +++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h @@ -12,22 +12,40 @@ #include +/* + * We need some arbitrary non-zero value to be programmed to the BAR1 register + * of PCI host controller to enable DMA. The same value should be used as the + * offset to calculate the physical address of DMA buffer for PCI devices. + */ +#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000 + +static inline dma_addr_t ath25_dev_offset(struct device *dev) +{ +#ifdef CONFIG_PCI + extern struct bus_type pci_bus_type; + + if (dev && dev->bus == &pci_bus_type) + return AR2315_PCI_HOST_SDRAM_BASEADDR; +#endif + return 0; +} + static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { - return virt_to_phys(addr); + return virt_to_phys(addr) + ath25_dev_offset(dev); } static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { - return page_to_phys(page); + return page_to_phys(page) + ath25_dev_offset(dev); } static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { - return dma_addr; + return dma_addr - ath25_dev_offset(dev); } static inline void diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 64a0caae63b5..300591c6278d 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ ops-bcm63xx.o obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o +obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c new file mode 100644 index 000000000000..bd2b3b60da83 --- /dev/null +++ b/arch/mips/pci/pci-ar2315.c @@ -0,0 +1,511 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/** + * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA + * and interrupt. PCI interface supports MMIO access method, but does not + * seem to support I/O ports. + * + * Read/write operation in the region 0x80000000-0xBFFFFFFF causes + * a memory read/write command on the PCI bus. 30 LSBs of address on + * the bus are taken from memory read/write request and 2 MSBs are + * determined by PCI unit configuration. + * + * To work with the configuration space instead of memory is necessary set + * the CFG_SEL bit in the PCI_MISC_CONFIG register. + * + * Devices on the bus can perform DMA requests via chip BAR1. PCI host + * controller BARs are programmend as if an external device is programmed. + * Which means that during configuration, IDSEL pin of the chip should be + * asserted. + * + * We know (and support) only one board that uses the PCI interface - + * Fonera 2.0g (FON2202). It has a USB EHCI controller connected to the + * AR2315 PCI bus. IDSEL pin of USB controller is connected to AD[13] line + * and IDSEL pin of AR2315 is connected to AD[16] line. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * PCI Bus Interface Registers + */ +#define AR2315_PCI_1MS_REG 0x0008 + +#define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ + +#define AR2315_PCI_MISC_CONFIG 0x000c + +#define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ +#define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */ +#define AR2315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ +#define AR2315_PCIMISC_RST_MODE 0x00000030 +#define AR2315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ +#define AR2315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ +#define AR2315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ +#define AR2315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ +#define AR2315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ +#define AR2315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ +#define AR2315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ +#define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache + * disable */ + +#define AR2315_PCI_OUT_TSTAMP 0x0010 + +#define AR2315_PCI_UNCACHE_CFG 0x0014 + +#define AR2315_PCI_IN_EN 0x0100 + +#define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */ +#define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */ +#define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */ +#define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */ + +#define AR2315_PCI_IN_DIS 0x0104 + +#define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ +#define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ +#define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ +#define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ + +#define AR2315_PCI_IN_PTR 0x0200 + +#define AR2315_PCI_OUT_EN 0x0400 + +#define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ + +#define AR2315_PCI_OUT_DIS 0x0404 + +#define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ + +#define AR2315_PCI_OUT_PTR 0x0408 + +/* PCI interrupt status (write one to clear) */ +#define AR2315_PCI_ISR 0x0500 + +#define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */ +#define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */ +#define AR2315_PCI_INT_TXERR 0x00000004 /* Desc In ERR */ +#define AR2315_PCI_INT_TXEOL 0x00000008 /* Desc In End-of-List */ +#define AR2315_PCI_INT_RX 0x00000010 /* Desc Out Completed */ +#define AR2315_PCI_INT_RXOK 0x00000020 /* Desc Out OK */ +#define AR2315_PCI_INT_RXERR 0x00000040 /* Desc Out ERR */ +#define AR2315_PCI_INT_RXEOL 0x00000080 /* Desc Out EOL */ +#define AR2315_PCI_INT_TXOOD 0x00000200 /* Desc In Out-of-Desc */ +#define AR2315_PCI_INT_DESCMASK 0x0000FFFF /* Desc Mask */ +#define AR2315_PCI_INT_EXT 0x02000000 /* Extern PCI INTA */ +#define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */ + +/* PCI interrupt mask */ +#define AR2315_PCI_IMR 0x0504 + +/* Global PCI interrupt enable */ +#define AR2315_PCI_IER 0x0508 + +#define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */ +#define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */ + +#define AR2315_PCI_HOST_IN_EN 0x0800 +#define AR2315_PCI_HOST_IN_DIS 0x0804 +#define AR2315_PCI_HOST_IN_PTR 0x0810 +#define AR2315_PCI_HOST_OUT_EN 0x0900 +#define AR2315_PCI_HOST_OUT_DIS 0x0904 +#define AR2315_PCI_HOST_OUT_PTR 0x0908 + +/* + * PCI interrupts, which share IP5 + * Keep ordered according to AR2315_PCI_INT_XXX bits + */ +#define AR2315_PCI_IRQ_EXT 25 +#define AR2315_PCI_IRQ_ABORT 26 +#define AR2315_PCI_IRQ_COUNT 27 + +/* Arbitrary size of memory region to access the configuration space */ +#define AR2315_PCI_CFG_SIZE 0x00100000 + +#define AR2315_PCI_HOST_SLOT 3 +#define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) + +/* ??? access BAR */ +#define AR2315_PCI_HOST_MBAR0 0x10000000 +/* RAM access BAR */ +#define AR2315_PCI_HOST_MBAR1 AR2315_PCI_HOST_SDRAM_BASEADDR +/* ??? access BAR */ +#define AR2315_PCI_HOST_MBAR2 0x30000000 + +struct ar2315_pci_ctrl { + void __iomem *cfg_mem; + void __iomem *mmr_mem; + unsigned irq; + unsigned irq_ext; + struct irq_domain *domain; + struct pci_controller pci_ctrl; + struct resource mem_res; + struct resource io_res; +}; + +static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) +{ + struct pci_controller *hose = bus->sysdata; + + return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl); +} + +static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg) +{ + return __raw_readl(apc->mmr_mem + reg); +} + +static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg, + u32 val) +{ + __raw_writel(val, apc->mmr_mem + reg); +} + +static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg, + u32 mask, u32 val) +{ + u32 ret = ar2315_pci_reg_read(apc, reg); + + ret &= ~mask; + ret |= val; + ar2315_pci_reg_write(apc, reg, ret); +} + +static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn, + int where, int size, u32 *ptr, bool write) +{ + int func = PCI_FUNC(devfn); + int dev = PCI_SLOT(devfn); + u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3); + u32 mask = 0xffffffff >> 8 * (4 - size); + u32 sh = (where & 3) * 8; + u32 value, isr; + + /* Prevent access past the remapped area */ + if (addr >= AR2315_PCI_CFG_SIZE || dev > 18) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear pending errors */ + ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); + /* Select Configuration access */ + ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0, + AR2315_PCIMISC_CFG_SEL); + + mb(); /* PCI must see space change before we begin */ + + value = __raw_readl(apc->cfg_mem + addr); + + isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); + + if (isr & AR2315_PCI_INT_ABORT) + goto exit_err; + + if (write) { + value = (value & ~(mask << sh)) | *ptr << sh; + __raw_writel(value, apc->cfg_mem + addr); + isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); + if (isr & AR2315_PCI_INT_ABORT) + goto exit_err; + } else { + *ptr = (value >> sh) & mask; + } + + goto exit; + +exit_err: + ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); + if (!write) + *ptr = 0xffffffff; + +exit: + /* Select Memory access */ + ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, + 0); + + return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : + PCIBIOS_SUCCESSFUL; +} + +static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc, + unsigned devfn, int where, u32 *val) +{ + return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val, + false); +} + +static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc, + unsigned devfn, int where, u32 val) +{ + return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val, + true); +} + +static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where, + int size, u32 *value) +{ + struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); + + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + + return ar2315_pci_cfg_access(apc, devfn, where, size, value, false); +} + +static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where, + int size, u32 value) +{ + struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); + + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + + return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true); +} + +static struct pci_ops ar2315_pci_ops = { + .read = ar2315_pci_cfg_read, + .write = ar2315_pci_cfg_write, +}; + +static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc) +{ + unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); + int res; + u32 id; + + res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id); + if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID) + return -ENODEV; + + /* Program MBARs */ + ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0, + AR2315_PCI_HOST_MBAR0); + ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1, + AR2315_PCI_HOST_MBAR1); + ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2, + AR2315_PCI_HOST_MBAR2); + + /* Run */ + ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | + PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); + + return 0; +} + +static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq); + u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) & + ar2315_pci_reg_read(apc, AR2315_PCI_IMR); + unsigned pci_irq = 0; + + if (pending) + pci_irq = irq_find_mapping(apc->domain, __ffs(pending)); + + if (pci_irq) + generic_handle_irq(pci_irq); + else + spurious_interrupt(); +} + +static void ar2315_pci_irq_mask(struct irq_data *d) +{ + struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + + ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, BIT(d->hwirq), 0); +} + +static void ar2315_pci_irq_mask_ack(struct irq_data *d) +{ + struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + u32 m = BIT(d->hwirq); + + ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0); + ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m); +} + +static void ar2315_pci_irq_unmask(struct irq_data *d) +{ + struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); + + ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, BIT(d->hwirq)); +} + +static struct irq_chip ar2315_pci_irq_chip = { + .name = "AR2315-PCI", + .irq_mask = ar2315_pci_irq_mask, + .irq_mask_ack = ar2315_pci_irq_mask_ack, + .irq_unmask = ar2315_pci_irq_unmask, +}; + +static int ar2315_pci_irq_map(struct irq_domain *d, unsigned irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, handle_level_irq); + irq_set_chip_data(irq, d->host_data); + return 0; +} + +static struct irq_domain_ops ar2315_pci_irq_domain_ops = { + .map = ar2315_pci_irq_map, +}; + +static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc) +{ + ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0); + ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT | + AR2315_PCI_INT_EXT), 0); + + apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT); + + irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler); + irq_set_handler_data(apc->irq, apc); + + /* Clear any pending Abort or external Interrupts + * and enable interrupt processing */ + ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT | + AR2315_PCI_INT_EXT); + ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); +} + +static int ar2315_pci_probe(struct platform_device *pdev) +{ + struct ar2315_pci_ctrl *apc; + struct device *dev = &pdev->dev; + struct resource *res; + int irq, err; + + apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL); + if (!apc) + return -ENOMEM; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -EINVAL; + apc->irq = irq; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ar2315-pci-ctrl"); + apc->mmr_mem = devm_ioremap_resource(dev, res); + if (IS_ERR(apc->mmr_mem)) + return PTR_ERR(apc->mmr_mem); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ar2315-pci-ext"); + if (!res) + return -EINVAL; + + apc->mem_res.name = "AR2315 PCI mem space"; + apc->mem_res.parent = res; + apc->mem_res.start = res->start; + apc->mem_res.end = res->end; + apc->mem_res.flags = IORESOURCE_MEM; + + /* Remap PCI config space */ + apc->cfg_mem = devm_ioremap_nocache(dev, res->start, + AR2315_PCI_CFG_SIZE); + if (!apc->cfg_mem) { + dev_err(dev, "failed to remap PCI config space\n"); + return -ENOMEM; + } + + /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ + ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, + AR2315_PCIMISC_RST_MODE, + AR2315_PCIRST_LOW); + msleep(100); + + /* Bring the PCI out of reset */ + ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, + AR2315_PCIMISC_RST_MODE, + AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); + + ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG, + 0x1E | /* 1GB uncached */ + (1 << 5) | /* Enable uncached */ + (0x2 << 30) /* Base: 0x80000000 */); + ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG); + + msleep(500); + + err = ar2315_pci_host_setup(apc); + if (err) + return err; + + apc->domain = irq_domain_add_linear(NULL, AR2315_PCI_IRQ_COUNT, + &ar2315_pci_irq_domain_ops, apc); + if (!apc->domain) { + dev_err(dev, "failed to add IRQ domain\n"); + return -ENOMEM; + } + + ar2315_pci_irq_init(apc); + + /* PCI controller does not support I/O ports */ + apc->io_res.name = "AR2315 IO space"; + apc->io_res.start = 0; + apc->io_res.end = 0; + apc->io_res.flags = IORESOURCE_IO, + + apc->pci_ctrl.pci_ops = &ar2315_pci_ops; + apc->pci_ctrl.mem_resource = &apc->mem_res, + apc->pci_ctrl.io_resource = &apc->io_res, + + register_pci_controller(&apc->pci_ctrl); + + dev_info(dev, "register PCI controller\n"); + + return 0; +} + +static struct platform_driver ar2315_pci_driver = { + .probe = ar2315_pci_probe, + .driver = { + .name = "ar2315-pci", + .owner = THIS_MODULE, + }, +}; + +static int __init ar2315_pci_init(void) +{ + return platform_driver_register(&ar2315_pci_driver); +} +arch_initcall(ar2315_pci_init); + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(dev->bus); + + return slot ? 0 : apc->irq_ext; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} -- GitLab From 0e5d3ab532dd6bd43406d91b1dacb391973f831f Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:48 +0400 Subject: [PATCH 6083/9457] ath5k: revert AHB bus support removing This reverts commit 093ec3c5337434f40d77c1af06c139da3e5ba6dc. AHB bus code has been removed, since we did not have support Atheros AR231x SoC, required for building the AHB version of ath5k. Now that support WiSoC chips added we can restore functionality back. Signed-off-by: Sergey Ryazanov Acked-by: John W. Linville Cc: Jiri Slaby Cc: Nick Kossifidis Cc: "Luis R. Rodriguez" Cc: linux-wireless@vger.kernel.org Cc: ath5k-devel@lists.ath5k.org Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8247/ Signed-off-by: Ralf Baechle --- drivers/net/wireless/ath/ath5k/Kconfig | 14 +- drivers/net/wireless/ath/ath5k/Makefile | 1 + drivers/net/wireless/ath/ath5k/ahb.c | 234 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath5k/ath5k.h | 28 +++ drivers/net/wireless/ath/ath5k/base.c | 14 ++ drivers/net/wireless/ath/ath5k/led.c | 6 + 6 files changed, 294 insertions(+), 3 deletions(-) create mode 100644 drivers/net/wireless/ath/ath5k/ahb.c diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index 93caf8e68901..c9f81a388f15 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig @@ -1,12 +1,13 @@ config ATH5K tristate "Atheros 5xxx wireless cards support" - depends on PCI && MAC80211 + depends on (PCI || ATHEROS_AR231X) && MAC80211 select ATH_COMMON select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS select AVERAGE - select ATH5K_PCI + select ATH5K_AHB if (ATHEROS_AR231X && !PCI) + select ATH5K_PCI if (!ATHEROS_AR231X && PCI) ---help--- This module adds support for wireless adapters based on Atheros 5xxx chipset. @@ -51,9 +52,16 @@ config ATH5K_TRACER If unsure, say N. +config ATH5K_AHB + bool "Atheros 5xxx AHB bus support" + depends on (ATHEROS_AR231X && !PCI) + ---help--- + This adds support for WiSoC type chipsets of the 5xxx Atheros + family. + config ATH5K_PCI bool "Atheros 5xxx PCI bus support" - depends on PCI + depends on (!ATHEROS_AR231X && PCI) ---help--- This adds support for PCI type chipsets of the 5xxx Atheros family. diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 51e2d8668041..1b3a34f7f224 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -17,5 +17,6 @@ ath5k-y += ani.o ath5k-y += sysfs.o ath5k-y += mac80211-ops.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o +ath5k-$(CONFIG_ATH5K_AHB) += ahb.o ath5k-$(CONFIG_ATH5K_PCI) += pci.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c new file mode 100644 index 000000000000..79bffe165cab --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2009 Gabor Juhos + * Copyright (c) 2009 Imre Kaloz + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "ath5k.h" +#include "debug.h" +#include "base.h" +#include "reg.h" + +/* return bus cachesize in 4B word units */ +static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) +{ + *csz = L1_CACHE_BYTES >> 2; +} + +static bool +ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) +{ + struct ath5k_hw *ah = common->priv; + struct platform_device *pdev = to_platform_device(ah->dev); + struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + u16 *eeprom, *eeprom_end; + + eeprom = (u16 *) bcfg->radio; + eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; + + eeprom += off; + if (eeprom > eeprom_end) + return false; + + *data = *eeprom; + return true; +} + +int ath5k_hw_read_srev(struct ath5k_hw *ah) +{ + struct platform_device *pdev = to_platform_device(ah->dev); + struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + ah->ah_mac_srev = bcfg->devid; + return 0; +} + +static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + struct platform_device *pdev = to_platform_device(ah->dev); + struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + u8 *cfg_mac; + + if (to_platform_device(ah->dev)->id == 0) + cfg_mac = bcfg->config->wlan0_mac; + else + cfg_mac = bcfg->config->wlan1_mac; + + memcpy(mac, cfg_mac, ETH_ALEN); + return 0; +} + +static const struct ath_bus_ops ath_ahb_bus_ops = { + .ath_bus_type = ATH_AHB, + .read_cachesize = ath5k_ahb_read_cachesize, + .eeprom_read = ath5k_ahb_eeprom_read, + .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, +}; + +/*Initialization*/ +static int ath_ahb_probe(struct platform_device *pdev) +{ + struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ath5k_hw *ah; + struct ieee80211_hw *hw; + struct resource *res; + void __iomem *mem; + int irq; + int ret = 0; + u32 reg; + + if (!dev_get_platdata(&pdev->dev)) { + dev_err(&pdev->dev, "no platform data specified\n"); + ret = -EINVAL; + goto err_out; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no memory resource found\n"); + ret = -ENXIO; + goto err_out; + } + + mem = ioremap_nocache(res->start, resource_size(res)); + if (mem == NULL) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -ENOMEM; + goto err_out; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no IRQ resource found\n"); + ret = -ENXIO; + goto err_iounmap; + } + + irq = res->start; + + hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); + ret = -ENOMEM; + goto err_iounmap; + } + + ah = hw->priv; + ah->hw = hw; + ah->dev = &pdev->dev; + ah->iobase = mem; + ah->irq = irq; + ah->devid = bcfg->devid; + + if (bcfg->devid >= AR5K_SREV_AR2315_R6) { + /* Enable WMAC AHB arbitration */ + reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; + iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + + /* Enable global WMAC swapping */ + reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP); + reg |= AR5K_AR2315_BYTESWAP_WMAC; + iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); + } else { + /* Enable WMAC DMA access (assuming 5312 or 231x*/ + /* TODO: check other platforms */ + reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); + if (to_platform_device(ah->dev)->id == 0) + reg |= AR5K_AR5312_ENABLE_WLAN0; + else + reg |= AR5K_AR5312_ENABLE_WLAN1; + iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); + + /* + * On a dual-band AR5312, the multiband radio is only + * used as pass-through. Disable 2 GHz support in the + * driver for it + */ + if (to_platform_device(ah->dev)->id == 0 && + (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) == + (BD_WLAN1 | BD_WLAN0)) + ah->ah_capabilities.cap_needs_2GHz_ovr = true; + else + ah->ah_capabilities.cap_needs_2GHz_ovr = false; + } + + ret = ath5k_init_ah(ah, &ath_ahb_bus_ops); + if (ret != 0) { + dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); + ret = -ENODEV; + goto err_free_hw; + } + + platform_set_drvdata(pdev, hw); + + return 0; + + err_free_hw: + ieee80211_free_hw(hw); + err_iounmap: + iounmap(mem); + err_out: + return ret; +} + +static int ath_ahb_remove(struct platform_device *pdev) +{ + struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ieee80211_hw *hw = platform_get_drvdata(pdev); + struct ath5k_hw *ah; + u32 reg; + + if (!hw) + return 0; + + ah = hw->priv; + + if (bcfg->devid >= AR5K_SREV_AR2315_R6) { + /* Disable WMAC AHB arbitration */ + reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; + iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + } else { + /*Stop DMA access */ + reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); + if (to_platform_device(ah->dev)->id == 0) + reg &= ~AR5K_AR5312_ENABLE_WLAN0; + else + reg &= ~AR5K_AR5312_ENABLE_WLAN1; + iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); + } + + ath5k_deinit_ah(ah); + iounmap(ah->iobase); + ieee80211_free_hw(hw); + + return 0; +} + +static struct platform_driver ath_ahb_driver = { + .probe = ath_ahb_probe, + .remove = ath_ahb_remove, + .driver = { + .name = "ar231x-wmac", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(ath_ahb_driver); diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ed2468220216..85316bb3f8c6 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) return &(ath5k_hw_common(ah)->regulatory); } +#ifdef CONFIG_ATHEROS_AR231X +#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) + +static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) +{ + /* On AR2315 and AR2317 the PCI clock domain registers + * are outside of the WMAC register space */ + if (unlikely((reg >= 0x4000) && (reg < 0x5000) && + (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) + return AR5K_AR2315_PCI_BASE + reg; + + return ah->iobase + reg; +} + +static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) +{ + return ioread32(ath5k_ahb_reg(ah, reg)); +} + +static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) +{ + iowrite32(val, ath5k_ahb_reg(ah, reg)); +} + +#else + static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) { return ioread32(ah->iobase + reg); @@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) iowrite32(val, ah->iobase + reg); } +#endif + static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) { return ath5k_hw_common(ah)->bus_ops->ath_bus_type; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a4a09bb8f2f3..59a87247aac4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { +#ifdef CONFIG_ATHEROS_AR231X + { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, + { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, + { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, + { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, + { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, + { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, + { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, +#else { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, @@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev_names[] = { { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, +#endif { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, @@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev_names[] = { { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, +#ifdef CONFIG_ATHEROS_AR231X + { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, + { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, +#endif { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, }; diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 0beb7e7d6075..2062d1190556 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah) { int ret = 0; struct ieee80211_hw *hw = ah->hw; +#ifndef CONFIG_ATHEROS_AR231X struct pci_dev *pdev = ah->pdev; +#endif char name[ATH5K_LED_MAX_NAME_LEN + 1]; const struct pci_device_id *match; if (!ah->pdev) return 0; +#ifdef CONFIG_ATHEROS_AR231X + match = NULL; +#else match = pci_match_id(&ath5k_led_devices[0], pdev); +#endif if (match) { __set_bit(ATH_STAT_LEDSOFT, ah->status); ah->led_pin = ATH_PIN(match->driver_data); -- GitLab From 164a974889c03cbc6559923b8c1da8762904c560 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:49 +0400 Subject: [PATCH 6084/9457] ath5k: update dependencies - Use config symbol defined in the driver instead of arch specific one for conditional compilation. - Rename the ATHEROS_AR231X config symbol to ATH25. - Fix include (ar231x_platform.h -> ath25_platform.h). - Some of AR231x SoCs (e.g. AR2315) have PCI bus support, so remove !PCI dependency, which block AHB support build. Signed-off-by: Sergey Ryazanov Acked-by: John W. Linville Cc: Jiri Slaby Cc: Nick Kossifidis Cc: "Luis R. Rodriguez" Cc: linux-wireless@vger.kernel.org Cc: ath5k-devel@lists.ath5k.org Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8248/ Signed-off-by: Ralf Baechle --- drivers/net/wireless/ath/ath5k/Kconfig | 10 +++++----- drivers/net/wireless/ath/ath5k/ahb.c | 2 +- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- drivers/net/wireless/ath/ath5k/led.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index c9f81a388f15..2399a3921762 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig @@ -1,13 +1,13 @@ config ATH5K tristate "Atheros 5xxx wireless cards support" - depends on (PCI || ATHEROS_AR231X) && MAC80211 + depends on (PCI || ATH25) && MAC80211 select ATH_COMMON select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS select AVERAGE - select ATH5K_AHB if (ATHEROS_AR231X && !PCI) - select ATH5K_PCI if (!ATHEROS_AR231X && PCI) + select ATH5K_AHB if ATH25 + select ATH5K_PCI if !ATH25 ---help--- This module adds support for wireless adapters based on Atheros 5xxx chipset. @@ -54,14 +54,14 @@ config ATH5K_TRACER config ATH5K_AHB bool "Atheros 5xxx AHB bus support" - depends on (ATHEROS_AR231X && !PCI) + depends on ATH25 ---help--- This adds support for WiSoC type chipsets of the 5xxx Atheros family. config ATH5K_PCI bool "Atheros 5xxx PCI bus support" - depends on (!ATHEROS_AR231X && PCI) + depends on (!ATH25 && PCI) ---help--- This adds support for PCI type chipsets of the 5xxx Atheros family. diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 79bffe165cab..8f387cf67340 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include "ath5k.h" #include "debug.h" #include "base.h" diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 85316bb3f8c6..1ed7a88aeea9 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1647,7 +1647,7 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) return &(ath5k_hw_common(ah)->regulatory); } -#ifdef CONFIG_ATHEROS_AR231X +#ifdef CONFIG_ATH5K_AHB #define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 59a87247aac4..bc9cb356fa69 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -99,7 +99,7 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { -#ifdef CONFIG_ATHEROS_AR231X +#ifdef CONFIG_ATH5K_AHB { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, @@ -142,7 +142,7 @@ static const struct ath5k_srev_name srev_names[] = { { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, -#ifdef CONFIG_ATHEROS_AR231X +#ifdef CONFIG_ATH5K_AHB { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, #endif diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 2062d1190556..ca4b7ccd697f 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -163,7 +163,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) { int ret = 0; struct ieee80211_hw *hw = ah->hw; -#ifndef CONFIG_ATHEROS_AR231X +#ifndef CONFIG_ATH5K_AHB struct pci_dev *pdev = ah->pdev; #endif char name[ATH5K_LED_MAX_NAME_LEN + 1]; @@ -172,7 +172,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) if (!ah->pdev) return 0; -#ifdef CONFIG_ATHEROS_AR231X +#ifdef CONFIG_ATH5K_AHB match = NULL; #else match = pci_match_id(&ath5k_led_devices[0], pdev); -- GitLab From d6a4c72ae4dcf5e6824638e57a8088bd1313a744 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 29 Oct 2014 03:18:50 +0400 Subject: [PATCH 6085/9457] MIPS: ath25: add Wireless device support Atheros AR5312 and AR2315 both have a builtin wireless device, this patch add helper code and register platform device for all supported WiSoCs. Signed-off-by: Sergey Ryazanov Cc: Linux MIPS Patchwork: https://patchwork.linux-mips.org/patch/8249/ Signed-off-by: Ralf Baechle --- arch/mips/ath25/ar2315.c | 2 ++ arch/mips/ath25/ar5312.c | 22 ++++++++++++++++ arch/mips/ath25/devices.c | 54 +++++++++++++++++++++++++++++++++++++++ arch/mips/ath25/devices.h | 1 + 4 files changed, 79 insertions(+) diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index f02478915afd..2befa7d766a6 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -171,6 +171,8 @@ void __init ar2315_init_devices(void) { /* Find board configuration */ ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); + + ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); } static void ar2315_restart(char *command) diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index 383dd6c38e0a..b6887f75144c 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -246,6 +246,28 @@ void __init ar5312_init_devices(void) ath25_soc = ATH25_SOC_AR5312; platform_device_register(&ar5312_physmap_flash); + + switch (ath25_soc) { + case ATH25_SOC_AR5312: + if (!ath25_board.radio) + return; + + if (!(config->flags & BD_WLAN0)) + break; + + ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); + break; + case ATH25_SOC_AR2312: + case ATH25_SOC_AR2313: + if (!ath25_board.radio) + return; + break; + default: + break; + } + + if (config->flags & BD_WLAN1) + ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1); } static void ar5312_restart(char *command) diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c index 62185472ef28..7a64567d1ac3 100644 --- a/arch/mips/ath25/devices.c +++ b/arch/mips/ath25/devices.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -11,6 +12,45 @@ struct ar231x_board_config ath25_board; enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; +static struct resource ath25_wmac0_res[] = { + { + .name = "wmac0_membase", + .flags = IORESOURCE_MEM, + }, + { + .name = "wmac0_irq", + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource ath25_wmac1_res[] = { + { + .name = "wmac1_membase", + .flags = IORESOURCE_MEM, + }, + { + .name = "wmac1_irq", + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device ath25_wmac[] = { + { + .id = 0, + .name = "ar231x-wmac", + .resource = ath25_wmac0_res, + .num_resources = ARRAY_SIZE(ath25_wmac0_res), + .dev.platform_data = &ath25_board, + }, + { + .id = 1, + .name = "ar231x-wmac", + .resource = ath25_wmac1_res, + .num_resources = ARRAY_SIZE(ath25_wmac1_res), + .dev.platform_data = &ath25_board, + }, +}; + static const char * const soc_type_strings[] = { [ATH25_SOC_AR5312] = "Atheros AR5312", [ATH25_SOC_AR2312] = "Atheros AR2312", @@ -46,6 +86,20 @@ void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) early_serial_setup(&s); } +int __init ath25_add_wmac(int nr, u32 base, int irq) +{ + struct resource *res; + + ath25_wmac[nr].dev.platform_data = &ath25_board; + res = &ath25_wmac[nr].resource[0]; + res->start = base; + res->end = base + 0x10000 - 1; + res++; + res->start = irq; + res->end = irq; + return platform_device_register(&ath25_wmac[nr]); +} + static int __init ath25_register_devices(void) { if (is_ar5312()) diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index 55adcf4f2b48..04d414115356 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -28,6 +28,7 @@ extern void (*ath25_irq_dispatch)(void); int ath25_find_config(phys_addr_t offset, unsigned long size); void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); +int ath25_add_wmac(int nr, u32 base, int irq); static inline bool is_ar2315(void) { -- GitLab From 11a0f40bc98d6ae34cb3283e6008abc433e252bb Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Fri, 7 Nov 2014 12:44:35 +0100 Subject: [PATCH 6086/9457] MIPS: ath79: Use the firmware lib to parse the kernel command line No need to duplicate code that is available in the firmware library. It also give us access to the firmware environment which is needed to read the initrd address and size. Signed-off-by: Alban Bedel Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8353/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/prom.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c index e9cbd7c2918f..80a0bffe5e1c 100644 --- a/arch/mips/ath79/prom.c +++ b/arch/mips/ath79/prom.c @@ -16,39 +16,13 @@ #include #include +#include #include "common.h" -static inline int is_valid_ram_addr(void *addr) -{ - if (((u32) addr > KSEG0) && - ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX))) - return 1; - - if (((u32) addr > KSEG1) && - ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX))) - return 1; - - return 0; -} - -static __init void ath79_prom_init_cmdline(int argc, char **argv) -{ - int i; - - if (!is_valid_ram_addr(argv)) - return; - - for (i = 0; i < argc; i++) - if (is_valid_ram_addr(argv[i])) { - strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); - strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); - } -} - void __init prom_init(void) { - ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); + fw_init_cmdline(); } void __init prom_free_prom_memory(void) -- GitLab From ebf71ec7e14bd55d0114f625686304979ecff4d0 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Fri, 7 Nov 2014 12:44:36 +0100 Subject: [PATCH 6087/9457] MIPS: ath79: Read the initrd address from the firmware environment Allow loading an initrd passed by the firmware. Signed-off-by: Alban Bedel Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8354/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/prom.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c index 80a0bffe5e1c..e1fe63051136 100644 --- a/arch/mips/ath79/prom.c +++ b/arch/mips/ath79/prom.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,13 @@ void __init prom_init(void) { fw_init_cmdline(); + + /* Read the initrd address from the firmware environment */ + initrd_start = fw_getenvl("initrd_start"); + if (initrd_start) { + initrd_start = KSEG0ADDR(initrd_start); + initrd_end = initrd_start + fw_getenvl("initrd_size"); + } } void __init prom_free_prom_memory(void) -- GitLab From 2ff404005e9f94ee3d05b6b0dac8204c1fcc2346 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Wed, 12 Nov 2014 11:43:37 -0800 Subject: [PATCH 6088/9457] of: Add binding document for MIPS GIC The Global Interrupt Controller (GIC) present on certain MIPS systems can be used to route external interrupts to individual VPEs and CPU interrupt vectors. It also supports a timer and software-generated interrupts. Signed-off-by: Andrew Bresticker Acked-by: Arnd Bergmann Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Thomas Gleixner Cc: Jason Cooper Cc: Daniel Lezcano Cc: John Crispin Cc: David Daney Cc: Qais Yousef Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8420/ Signed-off-by: Ralf Baechle --- .../interrupt-controller/mips-gic.txt | 55 +++++++++++++++++++ .../interrupt-controller/mips-gic.h | 9 +++ 2 files changed, 64 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt create mode 100644 include/dt-bindings/interrupt-controller/mips-gic.h diff --git a/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt b/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt new file mode 100644 index 000000000000..5a65478e5d40 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt @@ -0,0 +1,55 @@ +MIPS Global Interrupt Controller (GIC) + +The MIPS GIC routes external interrupts to individual VPEs and IRQ pins. +It also supports local (per-processor) interrupts and software-generated +interrupts which can be used as IPIs. The GIC also includes a free-running +global timer, per-CPU count/compare timers, and a watchdog. + +Required properties: +- compatible : Should be "mti,gic". +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt specifier. Should be 3. + - The first cell is the type of interrupt, local or shared. + See . + - The second cell is the GIC interrupt number. + - The third cell encodes the interrupt flags. + See for a list of valid + flags. + +Optional properties: +- reg : Base address and length of the GIC registers. If not present, + the base address reported by the hardware GCR_GIC_BASE will be used. +- mti,reserved-cpu-vectors : Specifies the list of CPU interrupt vectors + to which the GIC may not route interrupts. Valid values are 2 - 7. + This property is ignored if the CPU is started in EIC mode. + +Required properties for timer sub-node: +- compatible : Should be "mti,gic-timer". +- interrupts : Interrupt for the GIC local timer. +- clock-frequency : Clock frequency at which the GIC timers operate. + +Example: + + gic: interrupt-controller@1bdc0000 { + compatible = "mti,gic"; + reg = <0x1bdc0000 0x20000>; + + interrupt-controller; + #interrupt-cells = <3>; + + mti,reserved-cpu-vectors = <7>; + + timer { + compatible = "mti,gic-timer"; + interrupts = ; + clock-frequency = <50000000>; + }; + }; + + uart@18101400 { + ... + interrupt-parent = <&gic>; + interrupts = ; + ... + }; diff --git a/include/dt-bindings/interrupt-controller/mips-gic.h b/include/dt-bindings/interrupt-controller/mips-gic.h new file mode 100644 index 000000000000..cf35a577e371 --- /dev/null +++ b/include/dt-bindings/interrupt-controller/mips-gic.h @@ -0,0 +1,9 @@ +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H + +#include + +#define GIC_SHARED 0 +#define GIC_LOCAL 1 + +#endif -- GitLab From a7057270c280a5904d747f40e53b5402e7dddc0e Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Wed, 12 Nov 2014 11:43:38 -0800 Subject: [PATCH 6089/9457] irqchip: mips-gic: Add device-tree support Add device-tree support for the MIPS GIC. Update the GIC irqdomain's xlate() callback to handle the three-cell specifier described in the MIPS GIC binding document. Signed-off-by: Andrew Bresticker Acked-by: Arnd Bergmann Acked-by: Jason Cooper Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Thomas Gleixner Cc: Daniel Lezcano Cc: John Crispin Cc: David Daney Cc: Qais Yousef Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8422/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 92 ++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 7ec3c18f1330..2b0468e3df6a 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -12,12 +12,18 @@ #include #include #include +#include #include #include +#include #include #include +#include + +#include "irqchip.h" + unsigned int gic_present; struct gic_pcpu_mask { @@ -662,14 +668,34 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, return gic_shared_irq_domain_map(d, virq, hw); } +static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_type) +{ + if (intsize != 3) + return -EINVAL; + + if (intspec[0] == GIC_SHARED) + *out_hwirq = GIC_SHARED_TO_HWIRQ(intspec[1]); + else if (intspec[0] == GIC_LOCAL) + *out_hwirq = GIC_LOCAL_TO_HWIRQ(intspec[1]); + else + return -EINVAL; + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + + return 0; +} + static struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, - .xlate = irq_domain_xlate_twocell, + .xlate = gic_irq_domain_xlate, }; -void __init gic_init(unsigned long gic_base_addr, - unsigned long gic_addrspace_size, unsigned int cpu_vec, - unsigned int irqbase) +static void __init __gic_init(unsigned long gic_base_addr, + unsigned long gic_addrspace_size, + unsigned int cpu_vec, unsigned int irqbase, + struct device_node *node) { unsigned int gicconfig; @@ -695,7 +721,7 @@ void __init gic_init(unsigned long gic_base_addr, gic_irq_dispatch); } - gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_LOCAL_INTRS + + gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS + gic_shared_intrs, irqbase, &gic_irq_domain_ops, NULL); if (!gic_irq_domain) @@ -705,3 +731,59 @@ void __init gic_init(unsigned long gic_base_addr, gic_ipi_init(); } + +void __init gic_init(unsigned long gic_base_addr, + unsigned long gic_addrspace_size, + unsigned int cpu_vec, unsigned int irqbase) +{ + __gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL); +} + +static int __init gic_of_init(struct device_node *node, + struct device_node *parent) +{ + struct resource res; + unsigned int cpu_vec, i = 0, reserved = 0; + phys_addr_t gic_base; + size_t gic_len; + + /* Find the first available CPU vector. */ + while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", + i++, &cpu_vec)) + reserved |= BIT(cpu_vec); + for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) { + if (!(reserved & BIT(cpu_vec))) + break; + } + if (cpu_vec == 8) { + pr_err("No CPU vectors available for GIC\n"); + return -ENODEV; + } + + if (of_address_to_resource(node, 0, &res)) { + /* + * Probe the CM for the GIC base address if not specified + * in the device-tree. + */ + if (mips_cm_present()) { + gic_base = read_gcr_gic_base() & + ~CM_GCR_GIC_BASE_GICEN_MSK; + gic_len = 0x20000; + } else { + pr_err("Failed to get GIC memory range\n"); + return -ENODEV; + } + } else { + gic_base = res.start; + gic_len = resource_size(&res); + } + + if (mips_cm_present()) + write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); + gic_present = true; + + __gic_init(gic_base, gic_len, cpu_vec, 0, node); + + return 0; +} +IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init); -- GitLab From e12aa828ff42bae894e4eb7350d4dbf46eb19084 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Wed, 12 Nov 2014 11:43:39 -0800 Subject: [PATCH 6090/9457] clocksource: mips-gic: Add device-tree support Parse the GIC timer frequency and interrupt from the device-tree. Signed-off-by: Andrew Bresticker Acked-by: Arnd Bergmann Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Thomas Gleixner Cc: Jason Cooper Cc: Daniel Lezcano Cc: John Crispin Cc: David Daney Cc: Qais Yousef Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8421/ Signed-off-by: Ralf Baechle --- drivers/clocksource/Kconfig | 1 + drivers/clocksource/mips-gic-timer.c | 41 +++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cb7e7f417a60..89836dc7cf66 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -226,5 +226,6 @@ config CLKSRC_VERSATILE config CLKSRC_MIPS_GIC bool depends on MIPS_GIC + select CLKSRC_OF endmenu diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c index a749c812e255..3bd31b1321f6 100644 --- a/drivers/clocksource/mips-gic-timer.c +++ b/drivers/clocksource/mips-gic-timer.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -101,8 +102,6 @@ static int gic_clockevent_init(void) if (!cpu_has_counter || !gic_frequency) return -ENXIO; - gic_timer_irq = MIPS_GIC_IRQ_BASE + - GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); register_cpu_notifier(&gic_cpu_nb); @@ -123,17 +122,45 @@ static struct clocksource gic_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -void __init gic_clocksource_init(unsigned int frequency) +static void __init __gic_clocksource_init(void) { - gic_frequency = frequency; - /* Set clocksource mask. */ gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); /* Calculate a somewhat reasonable rating value. */ - gic_clocksource.rating = 200 + frequency / 10000000; + gic_clocksource.rating = 200 + gic_frequency / 10000000; - clocksource_register_hz(&gic_clocksource, frequency); + clocksource_register_hz(&gic_clocksource, gic_frequency); gic_clockevent_init(); } + +void __init gic_clocksource_init(unsigned int frequency) +{ + gic_frequency = frequency; + gic_timer_irq = MIPS_GIC_IRQ_BASE + + GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); + + __gic_clocksource_init(); +} + +static void __init gic_clocksource_of_init(struct device_node *node) +{ + if (WARN_ON(!gic_present || !node->parent || + !of_device_is_compatible(node->parent, "mti,gic"))) + return; + + if (of_property_read_u32(node, "clock-frequency", &gic_frequency)) { + pr_err("GIC frequency not specified.\n"); + return; + } + gic_timer_irq = irq_of_parse_and_map(node, 0); + if (!gic_timer_irq) { + pr_err("GIC timer IRQ not specified.\n"); + return; + } + + __gic_clocksource_init(); +} +CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", + gic_clocksource_of_init); -- GitLab From 314727fe5cea60fb8d1bdd75e54f2491aa079820 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 12 Nov 2014 09:22:15 +0000 Subject: [PATCH 6091/9457] MIPS: traps: Replace printk with pr_err for MC exceptions printk should not be used without a KERN_ facility level Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8399/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 165c275163b8..dde5d8f6c491 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1427,12 +1427,12 @@ asmlinkage void do_mcheck(struct pt_regs *regs) show_regs(regs); if (multi_match) { - printk("Index : %0x\n", read_c0_index()); - printk("Pagemask: %0x\n", read_c0_pagemask()); - printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); - printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); - printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); - printk("\n"); + pr_err("Index : %0x\n", read_c0_index()); + pr_err("Pagemask: %0x\n", read_c0_pagemask()); + pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi()); + pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); + pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); + pr_err("\n"); dump_tlb_all(); } -- GitLab From 31ec86b8549992923c2639fa1841a02e48b93310 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 12 Nov 2014 09:22:42 +0000 Subject: [PATCH 6092/9457] MIPS: traps: Dump the HTW registers on a MC exception The HTW registers can be useful to debug a MC exception. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8400/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index dde5d8f6c491..807def5ab5ed 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1432,6 +1432,11 @@ asmlinkage void do_mcheck(struct pt_regs *regs) pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi()); pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); + if (cpu_has_htw) { + pr_err("PWField : %0*lx\n", field, read_c0_pwfield()); + pr_err("PWSize : %0*lx\n", field, read_c0_pwsize()); + pr_err("PWCtl : %0x\n", read_c0_pwctl()); + } pr_err("\n"); dump_tlb_all(); } -- GitLab From 26b40ef1aa138599af223d08b73fd5d960fdabf7 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 12 Nov 2014 09:23:11 +0000 Subject: [PATCH 6093/9457] MIPS: traps: Dump the PageGrain and Wired registers on MC They can be useful to determine how the MMU is configured on a MC exception. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8401/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 807def5ab5ed..ad3d2031c327 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1432,6 +1432,8 @@ asmlinkage void do_mcheck(struct pt_regs *regs) pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi()); pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); + pr_err("Wired : %0x\n", read_c0_wired()); + pr_err("Pagegrain: %0x\n", read_c0_pagegrain()); if (cpu_has_htw) { pr_err("PWField : %0*lx\n", field, read_c0_pwfield()); pr_err("PWSize : %0*lx\n", field, read_c0_pwsize()); -- GitLab From 1b48142a809ee03f48979fad647245dbe0ce423a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Oct 2014 18:10:25 +0300 Subject: [PATCH 6094/9457] MIPS: oprofile: Enable backtrace on timer-based profiling Allow unsupported CPU types to use backtrace with timer-based profiling. Some CPUs (notably OCTEON) lack architecture-specific oprofile driver. In such case oprofile can fallback to timer-based mode, and arch code can still provide the backtrace functionality. So just set up the backtrace hook always. Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8108/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index feb987981f55..a26cbe372e06 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -110,6 +110,12 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) break; }; + /* + * Always set the backtrace. This allows unsupported CPU types to still + * use timer-based oprofile. + */ + ops->backtrace = op_mips_backtrace; + if (!lmodel) return -ENODEV; @@ -125,7 +131,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->start = op_mips_start; ops->stop = op_mips_stop; ops->cpu_type = lmodel->cpu_type; - ops->backtrace = op_mips_backtrace; printk(KERN_INFO "oprofile: using %s performance monitoring.\n", lmodel->cpu_type); -- GitLab From 569309b42fc67a8b42f57adb68764bd10bcf2178 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Oct 2014 18:10:26 +0300 Subject: [PATCH 6095/9457] MIPS: oprofile: Backtrace: don't fail on leaf functions Continue the backtrace if we cannot find SP adjustment and RA save. In that case, just assume the current RA. This allows us to get samples of frequent callers of e.g. GLIBC memset(). Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8109/ Signed-off-by: Ralf Baechle --- arch/mips/oprofile/backtrace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 83a1dfd8f0e3..5e645c9a3162 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c @@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip) * - handle cases where the stack is adjusted inside a function * (generally doesn't happen) * - find optimal value for max_instr_check - * - try to find a way to handle leaf functions + * - try to find a better way to handle leaf functions */ static inline int unwind_user_frame(struct stackframe *old_frame, @@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, } if (!ra_offset || !stack_size) - return -1; + goto done; if (ra_offset) { new_frame.ra = old_frame->sp + ra_offset; @@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, if (new_frame.sp > old_frame->sp) return -2; +done: new_frame.pc = old_frame->ra; *old_frame = new_frame; -- GitLab From 0f24017a108e7fd4319143bfd0968d5cd026f33d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 8 Sep 2014 18:25:40 +0300 Subject: [PATCH 6096/9457] MIPS: Octeon: Move cvmx_fuse_read_byte() Move cvmx_fuse_read_byte() into a .c file. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Cc: Aaro Koskinen Patchwork: https://patchwork.linux-mips.org/patch/7666/ Signed-off-by: Ralf Baechle --- .../cavium-octeon/executive/octeon-model.c | 20 +++++++++++++++++++ arch/mips/include/asm/octeon/cvmx.h | 20 +------------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index f4c1b36fdf65..e1878723efd8 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -27,6 +27,26 @@ #include +/** + * Read a byte of fuse data + * @byte_addr: address to read + * + * Returns fuse value: 0 or 1 + */ +uint8_t cvmx_fuse_read_byte(int byte_addr) +{ + union cvmx_mio_fus_rcmd read_cmd; + + read_cmd.u64 = 0; + read_cmd.s.addr = byte_addr; + read_cmd.s.pend = 1; + cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); + while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) + && read_cmd.s.pend) + ; + return read_cmd.s.dat; +} + /** * Given the chip processor ID from COP0, this function returns a * string representing the chip model number. The string is of the diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index f991e7701d3d..6852dfa50010 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -451,25 +451,7 @@ static inline uint32_t cvmx_octeon_num_cores(void) return cvmx_pop(ciu_fuse); } -/** - * Read a byte of fuse data - * @byte_addr: address to read - * - * Returns fuse value: 0 or 1 - */ -static uint8_t cvmx_fuse_read_byte(int byte_addr) -{ - union cvmx_mio_fus_rcmd read_cmd; - - read_cmd.u64 = 0; - read_cmd.s.addr = byte_addr; - read_cmd.s.pend = 1; - cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); - while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) - && read_cmd.s.pend) - ; - return read_cmd.s.dat; -} +uint8_t cvmx_fuse_read_byte(int byte_addr); /** * Read a single fuse bit -- GitLab From 4aa16510bffcbd5a1d0c3aa16b05137ac90f58cb Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 8 Sep 2014 18:25:41 +0300 Subject: [PATCH 6097/9457] MIPS: Octeon: Delete potentially dangerous feature checks We should not need to read fuses during normal operation, also the current code has issues with that (not safe for concurrent access). Since there are no in-kernel users for these, just delete them. Drivers should not need such OCTEON_HAS_FEATURE mechanism in any case, instead the information should be passed via device tree. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7665/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/octeon/cvmx.h | 43 --------------- arch/mips/include/asm/octeon/octeon-feature.h | 52 ------------------- 2 files changed, 95 deletions(-) diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 6852dfa50010..b0b544f96b70 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -453,47 +453,4 @@ static inline uint32_t cvmx_octeon_num_cores(void) uint8_t cvmx_fuse_read_byte(int byte_addr); -/** - * Read a single fuse bit - * - * @fuse: Fuse number (0-1024) - * - * Returns fuse value: 0 or 1 - */ -static inline int cvmx_fuse_read(int fuse) -{ - return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1; -} - -static inline int cvmx_octeon_model_CN36XX(void) -{ - return OCTEON_IS_MODEL(OCTEON_CN38XX) - && !cvmx_octeon_is_pass1() - && cvmx_fuse_read(264); -} - -static inline int cvmx_octeon_zip_present(void) -{ - return octeon_has_feature(OCTEON_FEATURE_ZIP); -} - -static inline int cvmx_octeon_dfa_present(void) -{ - if (!OCTEON_IS_MODEL(OCTEON_CN38XX) - && !OCTEON_IS_MODEL(OCTEON_CN31XX) - && !OCTEON_IS_MODEL(OCTEON_CN58XX)) - return 0; - else if (OCTEON_IS_MODEL(OCTEON_CN3020)) - return 0; - else if (cvmx_octeon_is_pass1()) - return 1; - else - return !cvmx_fuse_read(120); -} - -static inline int cvmx_octeon_crypto_present(void) -{ - return octeon_has_feature(OCTEON_FEATURE_CRYPTO); -} - #endif /* __CVMX_H__ */ diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h index 90e05a8d4b15..c4fe81f47f53 100644 --- a/arch/mips/include/asm/octeon/octeon-feature.h +++ b/arch/mips/include/asm/octeon/octeon-feature.h @@ -86,8 +86,6 @@ enum octeon_feature { OCTEON_MAX_FEATURE }; -static inline int cvmx_fuse_read(int fuse); - /** * Determine if the current Octeon supports a specific feature. These * checks have been optimized to be fairly quick, but they should still @@ -105,33 +103,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) case OCTEON_FEATURE_SAAD: return !OCTEON_IS_MODEL(OCTEON_CN3XXX); - case OCTEON_FEATURE_ZIP: - if (OCTEON_IS_MODEL(OCTEON_CN30XX) - || OCTEON_IS_MODEL(OCTEON_CN50XX) - || OCTEON_IS_MODEL(OCTEON_CN52XX)) - return 0; - else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) - return 1; - else - return !cvmx_fuse_read(121); - - case OCTEON_FEATURE_CRYPTO: - if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { - union cvmx_mio_fus_dat2 fus_2; - fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); - if (fus_2.s.nocrypto || fus_2.s.nomul) { - return 0; - } else if (!fus_2.s.dorm_crypto) { - return 1; - } else { - union cvmx_rnm_ctl_status st; - st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS); - return st.s.eer_val; - } - } else { - return !cvmx_fuse_read(90); - } - case OCTEON_FEATURE_DORM_CRYPTO: if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { union cvmx_mio_fus_dat2 fus_2; @@ -188,29 +159,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); - case OCTEON_FEATURE_DFA: - if (!OCTEON_IS_MODEL(OCTEON_CN38XX) - && !OCTEON_IS_MODEL(OCTEON_CN31XX) - && !OCTEON_IS_MODEL(OCTEON_CN58XX)) - return 0; - else if (OCTEON_IS_MODEL(OCTEON_CN3020)) - return 0; - else - return !cvmx_fuse_read(120); - - case OCTEON_FEATURE_HFA: - if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) - return 0; - else - return !cvmx_fuse_read(90); - - case OCTEON_FEATURE_DFM: - if (!(OCTEON_IS_MODEL(OCTEON_CN63XX) - || OCTEON_IS_MODEL(OCTEON_CN66XX))) - return 0; - else - return !cvmx_fuse_read(90); - case OCTEON_FEATURE_MDIO_CLAUSE_45: return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX) -- GitLab From 653e0528810280106b0ceb4c6988e6263ede852b Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 8 Sep 2014 18:25:42 +0300 Subject: [PATCH 6098/9457] MIPS: Octeon: Move code to avoid forward declaration Move code to avoid forward declarations. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7667/ Signed-off-by: Ralf Baechle --- .../cavium-octeon/executive/octeon-model.c | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index e1878723efd8..5105d0d57154 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -47,25 +47,6 @@ uint8_t cvmx_fuse_read_byte(int byte_addr) return read_cmd.s.dat; } -/** - * Given the chip processor ID from COP0, this function returns a - * string representing the chip model number. The string is of the - * form CNXXXXpX.X-FREQ-SUFFIX. - * - XXXX = The chip model number - * - X.X = Chip pass number - * - FREQ = Current frequency in Mhz - * - SUFFIX = NSP, EXP, SCP, SSP, or CP - * - * @chip_id: Chip ID - * - * Returns Model string - */ -const char *octeon_model_get_string(uint32_t chip_id) -{ - static char buffer[32]; - return octeon_model_get_string_buffer(chip_id, buffer); -} - /* * Version of octeon_model_get_string() that takes buffer as argument, * as running early in u-boot static/global variables don't work when @@ -427,3 +408,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); return buffer; } + +/** + * Given the chip processor ID from COP0, this function returns a + * string representing the chip model number. The string is of the + * form CNXXXXpX.X-FREQ-SUFFIX. + * - XXXX = The chip model number + * - X.X = Chip pass number + * - FREQ = Current frequency in Mhz + * - SUFFIX = NSP, EXP, SCP, SSP, or CP + * + * @chip_id: Chip ID + * + * Returns Model string + */ +const char *octeon_model_get_string(uint32_t chip_id) +{ + static char buffer[32]; + return octeon_model_get_string_buffer(chip_id, buffer); +} -- GitLab From da85e364952870db52625c4de7a4b5dfaf74d211 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 8 Sep 2014 18:25:43 +0300 Subject: [PATCH 6099/9457] MIPS: Octeon: Mark octeon_model_get_string() with __init Mark octeon_model_get_string() with __init and make internal functions static. Signed-off-by: Aaro Koskinen Cc: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7668/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/executive/octeon-model.c | 7 ++++--- arch/mips/include/asm/octeon/cvmx.h | 2 -- arch/mips/include/asm/octeon/octeon-model.h | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index 5105d0d57154..e15b049b3bd7 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -33,7 +33,7 @@ * * Returns fuse value: 0 or 1 */ -uint8_t cvmx_fuse_read_byte(int byte_addr) +static uint8_t __init cvmx_fuse_read_byte(int byte_addr) { union cvmx_mio_fus_rcmd read_cmd; @@ -52,7 +52,8 @@ uint8_t cvmx_fuse_read_byte(int byte_addr) * as running early in u-boot static/global variables don't work when * running from flash. */ -const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) +static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, + char *buffer) { const char *family; const char *core_model; @@ -422,7 +423,7 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) * * Returns Model string */ -const char *octeon_model_get_string(uint32_t chip_id) +const char *__init octeon_model_get_string(uint32_t chip_id) { static char buffer[32]; return octeon_model_get_string_buffer(chip_id, buffer); diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index b0b544f96b70..33db1c806b01 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -451,6 +451,4 @@ static inline uint32_t cvmx_octeon_num_cores(void) return cvmx_pop(ciu_fuse); } -uint8_t cvmx_fuse_read_byte(int byte_addr); - #endif /* __CVMX_H__ */ diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h index e2c122c6a657..e8a1c2fd52cd 100644 --- a/arch/mips/include/asm/octeon/octeon-model.h +++ b/arch/mips/include/asm/octeon/octeon-model.h @@ -326,8 +326,7 @@ static inline int __octeon_is_model_runtime__(uint32_t model) #define OCTEON_IS_COMMON_BINARY() 1 #undef OCTEON_MODEL -const char *octeon_model_get_string(uint32_t chip_id); -const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer); +const char *__init octeon_model_get_string(uint32_t chip_id); /* * Return the octeon family, i.e., ProcessorID of the PrID register. -- GitLab From f4f7d86b77d51e32585623272c5a6234f088777c Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Mon, 17 Nov 2014 09:37:43 +0000 Subject: [PATCH 6100/9457] MIPS: lib: mips-atomic.c: Remove obsolete ifdefery Having #ifdefs just to guard comments is not really helpful so drop them. Moreover, the code wasn't really reached anyway since there is a #ifndef CONFIG_CPU_MIPSR2 on the top of the file. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8513/ Signed-off-by: Ralf Baechle --- arch/mips/lib/mips-atomic.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index 57bcdaf1f1c8..be777d9a3f85 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -42,15 +42,11 @@ notrace void arch_local_irq_disable(void) __asm__ __volatile__( " .set push \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else " mfc0 $1,$12 \n" " ori $1,0x1f \n" " xori $1,0x1f \n" " .set noreorder \n" " mtc0 $1,$12 \n" -#endif " " __stringify(__irq_disable_hazard) " \n" " .set pop \n" : /* no outputs */ @@ -72,15 +68,11 @@ notrace unsigned long arch_local_irq_save(void) " .set push \n" " .set reorder \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else " mfc0 %[flags], $12 \n" " ori $1, %[flags], 0x1f \n" " xori $1, 0x1f \n" " .set noreorder \n" " mtc0 $1, $12 \n" -#endif " " __stringify(__irq_disable_hazard) " \n" " .set pop \n" : [flags] "=r" (flags) @@ -103,18 +95,12 @@ notrace void arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) - /* see irqflags.h for inline function */ -#elif defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else " mfc0 $1, $12 \n" " andi %[flags], 1 \n" " ori $1, 0x1f \n" " xori $1, 0x1f \n" " or %[flags], $1 \n" " mtc0 %[flags], $12 \n" -#endif " " __stringify(__irq_disable_hazard) " \n" " .set pop \n" : [flags] "=r" (__tmp1) @@ -136,18 +122,12 @@ notrace void __arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) - /* see irqflags.h for inline function */ -#elif defined(CONFIG_CPU_MIPSR2) - /* see irqflags.h for inline function */ -#else " mfc0 $1, $12 \n" " andi %[flags], 1 \n" " ori $1, 0x1f \n" " xori $1, 0x1f \n" " or %[flags], $1 \n" " mtc0 %[flags], $12 \n" -#endif " " __stringify(__irq_disable_hazard) " \n" " .set pop \n" : [flags] "=r" (__tmp1) -- GitLab From 7893165224c92e4d1a7aea0ea49f1ed8d9949793 Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Tue, 7 Oct 2014 21:33:04 -0400 Subject: [PATCH 6101/9457] MIPS: IP22/IP32: Add line to arch/mips/Makefile archhelp about vmlinux.32 Building a 64bit kernel for the SGI O2 (IP32) and the SGI Indy (IP22) uses the 'vmlinux.32' target, which converts the output 64-bit 'vmlinux' image into a 32-bit wrapped image. This is needed for certain revisions of the IP22 and IP32 ARCS PROMs to boot correctly, but this target is missing from the 'archhelp' info that is emitted by 'make help'. Signed-off-by: Joshua Kinard Cc: Linux MIPS List Patchwork: https://patchwork.linux-mips.org/patch/7991/ Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 58076472bdd8..2563a088d3b8 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -380,6 +380,7 @@ define archhelp echo ' vmlinux.ecoff - ECOFF boot image' echo ' vmlinux.bin - Raw binary boot image' echo ' vmlinux.srec - SREC boot image' + echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)' echo ' vmlinuz - Compressed boot(zboot) image' echo ' vmlinuz.ecoff - ECOFF zboot image' echo ' vmlinuz.bin - Raw binary zboot image' -- GitLab From 80219c6c6f5ac033b3ff96ee40719ffd1ce80d18 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 4 Nov 2014 02:23:45 +0100 Subject: [PATCH 6102/9457] MIPS: uaccess.h: Fix strnlen_user comment. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uaccess.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 486e27b8f479..bf8b32450ef6 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -1395,7 +1395,7 @@ static inline long __strnlen_user(const char __user *s, long n) } /* - * strlen_user: - Get the size of a string in user space. + * strnlen_user: - Get the size of a string in user space. * @str: The string to measure. * * Context: User context only. This function may sleep. @@ -1404,9 +1404,7 @@ static inline long __strnlen_user(const char __user *s, long n) * * Returns the size of the string INCLUDING the terminating NUL. * On exception, returns 0. - * - * If there is a limit on the length of a valid string, you may wish to - * consider using strnlen_user() instead. + * If the string is too long, returns a value greater than @n. */ static inline long strnlen_user(const char __user *s, long n) { -- GitLab From efa386f317eef7840f2298fab2a3062cbed2a93e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:45 +0200 Subject: [PATCH 6103/9457] MIPS: Loongson: common: Fix array initializer syntax. Fix array initializer syntax to get rid of the following sparse warnings: "obsolete array initializer, use C99 syntax". Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8525/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/cs5536/cs5536_pci.c | 24 +++++++++---------- arch/mips/loongson/common/machtype.c | 20 ++++++++-------- arch/mips/loongson/common/serial.c | 20 ++++++++-------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c index 81bed9d18061..ee78d9e1746e 100644 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c @@ -35,21 +35,21 @@ enum { }; static const cs5536_pci_vsm_write vsm_conf_write[] = { - [CS5536_ISA_FUNC] pci_isa_write_reg, - [reserved_func] NULL, - [CS5536_IDE_FUNC] pci_ide_write_reg, - [CS5536_ACC_FUNC] pci_acc_write_reg, - [CS5536_OHCI_FUNC] pci_ohci_write_reg, - [CS5536_EHCI_FUNC] pci_ehci_write_reg, + [CS5536_ISA_FUNC] = pci_isa_write_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_write_reg, + [CS5536_ACC_FUNC] = pci_acc_write_reg, + [CS5536_OHCI_FUNC] = pci_ohci_write_reg, + [CS5536_EHCI_FUNC] = pci_ehci_write_reg, }; static const cs5536_pci_vsm_read vsm_conf_read[] = { - [CS5536_ISA_FUNC] pci_isa_read_reg, - [reserved_func] NULL, - [CS5536_IDE_FUNC] pci_ide_read_reg, - [CS5536_ACC_FUNC] pci_acc_read_reg, - [CS5536_OHCI_FUNC] pci_ohci_read_reg, - [CS5536_EHCI_FUNC] pci_ehci_read_reg, + [CS5536_ISA_FUNC] = pci_isa_read_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_read_reg, + [CS5536_ACC_FUNC] = pci_acc_read_reg, + [CS5536_OHCI_FUNC] = pci_ohci_read_reg, + [CS5536_EHCI_FUNC] = pci_ehci_read_reg, }; /* diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 26629abe3f1f..f2807bc662a3 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -19,16 +19,16 @@ #define MACHTYPE_LEN 50 static const char *system_types[] = { - [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", - [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", - [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", - [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", - [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", - [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", - [MACH_LEMOTE_NAS] "lemote-nas-2f", - [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", - [MACH_LOONGSON_GENERIC] "generic-loongson-machine", - [MACH_LOONGSON_END] NULL, + [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine", + [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box", + [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box", + [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches", + [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches", + [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f", + [MACH_LEMOTE_NAS] = "lemote-nas-2f", + [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", + [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", + [MACH_LOONGSON_END] = NULL, }; const char *get_system_type(void) diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index d2f4817a4b45..c23fa1373729 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c @@ -39,16 +39,16 @@ } static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { - [MACH_LOONGSON_UNKNOWN] {}, - [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, - [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, - [MACH_LEMOTE_ML2F7] {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_YL2F89] {PORT_M(3, 3686400), {} }, - [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, - [MACH_LOONGSON_GENERIC] {PORT_M(2, 25000000), {} }, - [MACH_LOONGSON_END] {}, + [MACH_LOONGSON_UNKNOWN] = {}, + [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} }, + [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} }, + [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} }, + [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, + [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, + [MACH_LOONGSON_END] = {}, }; static struct platform_device uart8250_device = { -- GitLab From fdd6a1fd612962a28ff498e40f41e0fed29bec81 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:46 +0200 Subject: [PATCH 6104/9457] MIPS: Loongson: cs5536_pci: Add a missing include Add a missing include to get rid of the following sparse warnings: warning: symbol 'cs5536_pci_conf_write4' was not declared. Should it be static? warning: symbol 'cs5536_pci_conf_read4' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8526/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/cs5536/cs5536_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c index ee78d9e1746e..b739723205f8 100644 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c @@ -21,6 +21,7 @@ */ #include +#include #include enum { -- GitLab From 15dd8eb0eef3e4b61b5ffc7aa2d829dd3cf2b61c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:47 +0200 Subject: [PATCH 6105/9457] MIPS: loongson: common: Setup: add a missing include Add a missing include to get rid of the following sparse warning: warning: symbol 'plat_mem_setup' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8530/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c index bb4ac922e47a..d477dd6bb326 100644 --- a/arch/mips/loongson/common/setup.c +++ b/arch/mips/loongson/common/setup.c @@ -10,6 +10,7 @@ #include #include +#include #include -- GitLab From 55fa9889ca78cf1cea169ecea22de025c190dac0 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:48 +0200 Subject: [PATCH 6106/9457] MIPS: loongson: lemote-2f: irq: Make internal data static Make internal static to eliminate the following sparse warnings: warning: symbol 'ip6_irqaction' was not declared. Should it be static? warning: symbol 'cascade_irqaction' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8527/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/lemote-2f/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c index 6f8682e44483..cab5f43e0e29 100644 --- a/arch/mips/loongson/lemote-2f/irq.c +++ b/arch/mips/loongson/lemote-2f/irq.c @@ -93,13 +93,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id) return IRQ_HANDLED; } -struct irqaction ip6_irqaction = { +static struct irqaction ip6_irqaction = { .handler = ip6_action, .name = "cascade", .flags = IRQF_SHARED | IRQF_NO_THREAD, }; -struct irqaction cascade_irqaction = { +static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", .flags = IRQF_NO_THREAD, -- GitLab From 65b432de80227f4e09cd2de882d982be5edfa260 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:49 +0200 Subject: [PATCH 6107/9457] MIPS: loongson: lemote-2f: reset: make ml2f_reboot static Make ml2f_reboot static to elimite the following sparse warning: warning: symbol 'ml2f_reboot' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8528/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/lemote-2f/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 79ac694fe744..a26ca7fcd7e0 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c @@ -76,7 +76,7 @@ static void fl2f_shutdown(void) /* reset support for yeeloong2f and mengloong2f notebook */ -void ml2f_reboot(void) +static void ml2f_reboot(void) { reset_cpu(); -- GitLab From 8387efd26a68d0713a03308d09f27dbeecb65981 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:50 +0200 Subject: [PATCH 6108/9457] MIPS: loongson: common: init: Add a missing include Add a missing include to eliminate the following sparse warnings: warning: symbol 'prom_init' was not declared. Should it be static? warning: symbol 'prom_free_prom_memory' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8531/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index f6af3aba4c86..9b987fe98b5b 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c @@ -9,6 +9,7 @@ */ #include +#include #include #include -- GitLab From d47ff0ec0bf20d750c453da187697a7c59817a43 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 19 Nov 2014 23:52:51 +0200 Subject: [PATCH 6109/9457] MIPS: loongson: common: rtc: make loongson_rtc_resources static Make loongson_rtc_resources static to eliminate the following sparse warning: warning: symbol 'loongson_rtc_resources' was not declared. Should it be static? Signed-off-by: Aaro Koskinen Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8529/ Signed-off-by: Ralf Baechle --- arch/mips/loongson/common/rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c index a90d87c01555..b5709af09f7f 100644 --- a/arch/mips/loongson/common/rtc.c +++ b/arch/mips/loongson/common/rtc.c @@ -14,7 +14,7 @@ #include #include -struct resource loongson_rtc_resources[] = { +static struct resource loongson_rtc_resources[] = { { .start = RTC_PORT(0), .end = RTC_PORT(1), -- GitLab From 424ebcdf28001dfe9115d36700fca40424e0e19a Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:07:07 +0000 Subject: [PATCH 6110/9457] MIPS: Kconfig: Enable microMIPS support for Malta Add missing microMIPS support to Malta. Currently the kernel only enables support for the instruction set for the SEAD-3 board despite the fact processor features have nothing to do with the board a processor is installed in. In this case there is no way to run microMIPS software in a fully supported way under Linux on QEMU. QEMU supports the emulation of a Malta board, but does not emulate SEAD-3. Linux supports running microMIPS code on a SEAD-3 board, but hardcodes such support to off on an emulated Malta board even if the processor selected has the microMIPS instruction set implemented. Adding support for the SEAD-3 to QEMU is a major project. Flipping a bit in the kernel that shouldn't have been cleared in the first place is a trivial effort. Thus the answer is plain... Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8478/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3348989008b5..0bc8112c5486 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -384,6 +384,7 @@ config MIPS_MALTA select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_MICROMIPS select SYS_SUPPORTS_MIPS_CMP select SYS_SUPPORTS_MIPS_CPS select SYS_SUPPORTS_MIPS16 -- GitLab From c441d4a54c6ee9f0650a4013da70119d263c7feb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:07:21 +0000 Subject: [PATCH 6111/9457] MIPS: mm: Only build one microassembler that is suitable The microMIPS microassembler is only suitable for configurations where the kernel itself is built to microMIPS machine code and not where only user microMIPS software is supported. The former is controlled with the CPU_MICROMIPS configuration setting, whereas SYS_SUPPORTS_MICROMIPS is used for the latter. Not only that, but with a given microMIPS vs standard MIPS kernel configuration only one microassembler is needed, that matches the ISA selected -- CP0.Config3.ISAOnExc is mandatory on microMIPS processors, so there is never a need to mix microMIPS and standard MIPS code. Consequently build only the microassembler that matches the ISA selected for the kernel. Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8479/ Signed-off-by: Ralf Baechle --- arch/mips/mm/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 7f4f93ab22b7..67ede4ef9b8d 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -4,7 +4,13 @@ obj-y += cache.o dma-default.o extable.o fault.o \ gup.o init.o mmap.o page.o page-funcs.o \ - tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o + tlbex.o tlbex-fault.o tlb-funcs.o + +ifdef CONFIG_CPU_MICROMIPS +obj-y += uasm-micromips.o +else +obj-y += uasm-mips.o +endif obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o @@ -22,5 +28,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o - -obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o -- GitLab From 2fabc7d25da725630acdab7aa80be55559ae4702 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:08:09 +0000 Subject: [PATCH 6112/9457] MIPS: signal.c: Fix an invalid cast in ISA mode bit handling Fix: arch/mips/kernel/signal.c: In function 'handle_signal': arch/mips/kernel/signal.c:533:21: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] unsigned int tmp = (unsigned int)current->mm->context.vdso; ^ arch/mips/kernel/signal.c:536:9: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] vdso = (void *)tmp; ^ cc1: all warnings being treated as errors when building a 64-bit kernel. This is not really a supported configuration, but the cast is wrong either way, Linux makes the assumption that sizeof(void *) equals sizeof(unsigned long) and therefore the latter type is expected to be used where integer operations have to be applied to pointers for some reason. Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8480/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 1d57605e4615..0422bf1f0047 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -530,7 +530,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) struct mips_abi *abi = current->thread.abi; #ifdef CONFIG_CPU_MICROMIPS void *vdso; - unsigned int tmp = (unsigned int)current->mm->context.vdso; + unsigned long tmp = (unsigned long)current->mm->context.vdso; set_isa16_mode(tmp); vdso = (void *)tmp; -- GitLab From aec711d563c135186639443af1c2f0d8452b9709 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:08:23 +0000 Subject: [PATCH 6113/9457] MIPS: Kconfig: Only allow 32-bit microMIPS builds Only allow 32-bit microMIPS builds, we're not ready yet for 64-bit microMIPS support. QEMU does have support for the 64-bit microMIPS ISA and with minor tweaks it is possible to have a 64-bit processor emulated there that runs microMIPS code, so despite the lack of actual 64-bit microMIPS hardware there is a way to run 64-bit microMIPS Linux, but it can all be considered early development and we are not there yet. Userland tools are lacking too, e.g. GCC produces bad code: {standard input}: Assembler messages: {standard input}:380: Warning: wrong size instruction in a 16-bit branch delay slot And our build fails early on, so disable the configuration, for the sake of automatic random config checkers if nothing else. Whoever needs to experiment with 64-bit microMIPS support can revert this change easily. Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8481/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0bc8112c5486..d9393963e6d6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2143,7 +2143,7 @@ config CPU_HAS_SMARTMIPS here. config CPU_MICROMIPS - depends on SYS_SUPPORTS_MICROMIPS + depends on 32BIT && SYS_SUPPORTS_MICROMIPS bool "Build kernel using microMIPS ISA" help When this option is enabled the kernel will be built using the -- GitLab From b0984c43702f0fe2dbb0c344843e36c8b2cd13f1 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:08:48 +0000 Subject: [PATCH 6114/9457] MIPS: Fix microMIPS LL/SC immediate offsets In the microMIPS encoding some memory access instructions have their immediate offset reduced to 12 bits only. That does not match the GCC `R' constraint we use in some places to satisfy the requirement, resulting in build failures like this: {standard input}: Assembler messages: {standard input}:720: Error: macro used $at after ".set noat" {standard input}:720: Warning: macro instruction expanded into multiple instructions Fix the problem by defining a macro, `GCC_OFF12_ASM', that expands to the right constraint depending on whether microMIPS or standard MIPS code is produced. Also apply the fix to where `m' is used as in the worst case this change does nothing, e.g. where the pointer was already in a register such as a function argument and no further offset was requested, and in the best case it avoids an extraneous sequence of up to two instructions to load the high 20 bits of the address in the LL/SC loop. This reduces the risk of lock contention that is the higher the more instructions there are in the critical section between LL and SC. Strictly speaking we could just bulk-replace `R' with `ZC' as the latter constraint adjusts automatically depending on the ISA selected. However it was only introduced with GCC 4.9 and we keep supporing older compilers for the standard MIPS configuration, hence the slightly more complicated approach I chose. The choice of a zero-argument function-like rather than an object-like macro was made so that it does not look like a function call taking the C expression used for the constraint as an argument. This is so as not to confuse the reader or formatting checkers like `checkpatch.pl' and follows previous practice. Signed-off-by: Maciej W. Rozycki Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8482/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/atomic.h | 39 +++++++++------ arch/mips/include/asm/bitops.h | 35 ++++++------- arch/mips/include/asm/cmpxchg.h | 27 +++++----- arch/mips/include/asm/compiler.h | 8 +++ arch/mips/include/asm/edac.h | 6 ++- arch/mips/include/asm/futex.h | 23 ++++++--- .../asm/mach-pmcs-msp71xx/msp_regops.h | 25 +++++----- arch/mips/include/asm/octeon/cvmx-cmd-queue.h | 4 +- arch/mips/include/asm/spinlock.h | 50 ++++++++++--------- 9 files changed, 126 insertions(+), 91 deletions(-) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 6dd6bfc607e9..ec4b4d658bc4 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \ " sc %0, %1 \n" \ " beqzl %0, 1b \n" \ " .set mips0 \n" \ - : "=&r" (temp), "+m" (v->counter) \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } else if (kernel_uses_llsc) { \ int temp; \ @@ -65,7 +66,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \ " " #asm_op " %0, %2 \n" \ " sc %0, %1 \n" \ " .set mips0 \n" \ - : "=&r" (temp), "+m" (v->counter) \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } while (unlikely(!temp)); \ } else { \ @@ -95,7 +96,8 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ " beqzl %0, 1b \n" \ " " #asm_op " %0, %1, %3 \n" \ " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } else if (kernel_uses_llsc) { \ int temp; \ @@ -107,7 +109,8 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ " " #asm_op " %0, %1, %3 \n" \ " sc %0, %2 \n" \ " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } while (unlikely(!result)); \ \ @@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) " .set reorder \n" "1: \n" " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) - : "Ir" (i), "m" (v->counter) + : "=&r" (result), "=&r" (temp), + "+" GCC_OFF12_ASM() (v->counter) + : "Ir" (i), GCC_OFF12_ASM() (v->counter) : "memory"); } else if (kernel_uses_llsc) { int temp; @@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) " .set reorder \n" "1: \n" " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) + : "=&r" (result), "=&r" (temp), + "+" GCC_OFF12_ASM() (v->counter) : "Ir" (i)); } else { unsigned long flags; @@ -328,7 +333,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \ " scd %0, %1 \n" \ " beqzl %0, 1b \n" \ " .set mips0 \n" \ - : "=&r" (temp), "+m" (v->counter) \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } else if (kernel_uses_llsc) { \ long temp; \ @@ -340,7 +345,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \ " " #asm_op " %0, %2 \n" \ " scd %0, %1 \n" \ " .set mips0 \n" \ - : "=&r" (temp), "+m" (v->counter) \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } while (unlikely(!temp)); \ } else { \ @@ -370,7 +375,8 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ " beqzl %0, 1b \n" \ " " #asm_op " %0, %1, %3 \n" \ " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ : "Ir" (i)); \ } else if (kernel_uses_llsc) { \ long temp; \ @@ -382,8 +388,9 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ " " #asm_op " %0, %1, %3 \n" \ " scd %0, %2 \n" \ " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), "=m" (v->counter) \ - : "Ir" (i), "m" (v->counter) \ + : "=&r" (result), "=&r" (temp), \ + "=" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i), GCC_OFF12_ASM() (v->counter) \ : "memory"); \ } while (unlikely(!result)); \ \ @@ -443,8 +450,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) " .set reorder \n" "1: \n" " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) + : "=&r" (result), "=&r" (temp), + "=" GCC_OFF12_ASM() (v->counter) + : "Ir" (i), GCC_OFF12_ASM() (v->counter) : "memory"); } else if (kernel_uses_llsc) { long temp; @@ -461,7 +469,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) " .set reorder \n" "1: \n" " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) + : "=&r" (result), "=&r" (temp), + "+" GCC_OFF12_ASM() (v->counter) : "Ir" (i)); } else { unsigned long flags; diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index bae6b0fa8ab5..6663bcca9d0c 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -17,6 +17,7 @@ #include #include #include /* sigh ... */ +#include #include #include #include @@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n" - : "=&r" (temp), "=m" (*m) - : "ir" (1UL << bit), "m" (*m)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*m) + : "ir" (1UL << bit), GCC_OFF12_ASM() (*m)); #ifdef CONFIG_CPU_MIPSR2 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { do { @@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " " __LL "%0, %1 # set_bit \n" " " __INS "%0, %3, %2, 1 \n" " " __SC "%0, %1 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (bit), "r" (~0)); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 */ @@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) " or %0, %2 \n" " " __SC "%0, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); } else @@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (~(1UL << bit))); #ifdef CONFIG_CPU_MIPSR2 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { @@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " " __LL "%0, %1 # clear_bit \n" " " __INS "%0, $0, %2, 1 \n" " " __SC "%0, %1 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (bit)); } while (unlikely(!temp)); #endif /* CONFIG_CPU_MIPSR2 */ @@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) " and %0, %2 \n" " " __SC "%0, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (~(1UL << bit))); } while (unlikely(!temp)); } else @@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " " __SC "%0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (1UL << bit)); } else if (kernel_uses_llsc) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) " xor %0, %2 \n" " " __SC "%0, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); } else @@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr, " beqzl %2, 1b \n" " and %2, %0, %3 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } else if (kernel_uses_llsc) { @@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr, " or %2, %0, %3 \n" " " __SC "%2, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } while (unlikely(!res)); @@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, " or %2, %0, %3 \n" " " __SC "%2, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } while (unlikely(!res)); @@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr, " beqzl %2, 1b \n" " and %2, %0, %3 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); #ifdef CONFIG_CPU_MIPSR2 @@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr, " " __EXT "%2, %0, %3, 1 \n" " " __INS "%0, $0, %3, 1 \n" " " __SC "%0, %1 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "ir" (bit) : "memory"); } while (unlikely(!temp)); @@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr, " xor %2, %3 \n" " " __SC "%2, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } while (unlikely(!res)); @@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr, " beqzl %2, 1b \n" " and %2, %0, %3 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } else if (kernel_uses_llsc) { @@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr, " xor %2, %0, %3 \n" " " __SC "\t%2, %1 \n" " .set mips0 \n" - : "=&r" (temp), "+m" (*m), "=&r" (res) + : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) : "r" (1UL << bit) : "memory"); } while (unlikely(!res)); diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index eefcaa363a87..28b1edf19501 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -10,6 +10,7 @@ #include #include +#include #include static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) @@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) " sc %2, %1 \n" " beqzl %2, 1b \n" " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) + : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) + : GCC_OFF12_ASM() (*m), "Jr" (val) : "memory"); } else if (kernel_uses_llsc) { unsigned long dummy; @@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) " .set arch=r4000 \n" " sc %2, %1 \n" " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) + : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), + "=&r" (dummy) + : GCC_OFF12_ASM() (*m), "Jr" (val) : "memory"); } while (unlikely(!dummy)); } else { @@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) " scd %2, %1 \n" " beqzl %2, 1b \n" " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) + : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) + : GCC_OFF12_ASM() (*m), "Jr" (val) : "memory"); } else if (kernel_uses_llsc) { unsigned long dummy; @@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) " move %2, %z4 \n" " scd %2, %1 \n" " .set mips0 \n" - : "=&r" (retval), "=m" (*m), "=&r" (dummy) - : "R" (*m), "Jr" (val) + : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), + "=&r" (dummy) + : GCC_OFF12_ASM() (*m), "Jr" (val) : "memory"); } while (unlikely(!dummy)); } else { @@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz " beqzl $1, 1b \n" \ "2: \n" \ " .set pop \n" \ - : "=&r" (__ret), "=R" (*m) \ - : "R" (*m), "Jr" (old), "Jr" (new) \ + : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ + : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ : "memory"); \ } else if (kernel_uses_llsc) { \ __asm__ __volatile__( \ @@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz " beqz $1, 1b \n" \ " .set pop \n" \ "2: \n" \ - : "=&r" (__ret), "=R" (*m) \ - : "R" (*m), "Jr" (old), "Jr" (new) \ + : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ + : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ : "memory"); \ } else { \ unsigned long __flags; \ diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h index 71f5c5cfc58a..c73815e0123a 100644 --- a/arch/mips/include/asm/compiler.h +++ b/arch/mips/include/asm/compiler.h @@ -16,4 +16,12 @@ #define GCC_REG_ACCUM "accum" #endif +#ifndef CONFIG_CPU_MICROMIPS +#define GCC_OFF12_ASM() "R" +#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) +#define GCC_OFF12_ASM() "ZC" +#else +#error "microMIPS compilation unsupported with GCC older than 4.9" +#endif + #endif /* _ASM_COMPILER_H */ diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h index 4da0c1fe30d9..ae6fedcb0060 100644 --- a/arch/mips/include/asm/edac.h +++ b/arch/mips/include/asm/edac.h @@ -1,6 +1,8 @@ #ifndef ASM_EDAC_H #define ASM_EDAC_H +#include + /* ECC atomic, DMA, SMP and interrupt safe scrub function */ static inline void atomic_scrub(void *va, u32 size) @@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size) " sc %0, %1 \n" " beqz %0, 1b \n" " .set mips0 \n" - : "=&r" (temp), "=m" (*virt_addr) - : "m" (*virt_addr)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr) + : GCC_OFF12_ASM() (*virt_addr)); virt_addr++; } diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 194cda0396a3..d0177bf915bb 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -42,8 +43,10 @@ " "__UA_ADDR "\t1b, 4b \n" \ " "__UA_ADDR "\t2b, 4b \n" \ " .previous \n" \ - : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ - : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ + : "=r" (ret), "=&r" (oldval), \ + "=" GCC_OFF12_ASM() (*uaddr) \ + : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ + "i" (-EFAULT) \ : "memory"); \ } else if (cpu_has_llsc) { \ __asm__ __volatile__( \ @@ -68,8 +71,10 @@ " "__UA_ADDR "\t1b, 4b \n" \ " "__UA_ADDR "\t2b, 4b \n" \ " .previous \n" \ - : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ - : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ + : "=r" (ret), "=&r" (oldval), \ + "=" GCC_OFF12_ASM() (*uaddr) \ + : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ + "i" (-EFAULT) \ : "memory"); \ } else \ ret = -ENOSYS; \ @@ -166,8 +171,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " "__UA_ADDR "\t1b, 4b \n" " "__UA_ADDR "\t2b, 4b \n" " .previous \n" - : "+r" (ret), "=&r" (val), "=R" (*uaddr) - : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) + : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) + : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), + "i" (-EFAULT) : "memory"); } else if (cpu_has_llsc) { __asm__ __volatile__( @@ -193,8 +199,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " "__UA_ADDR "\t1b, 4b \n" " "__UA_ADDR "\t2b, 4b \n" " .previous \n" - : "+r" (ret), "=&r" (val), "=R" (*uaddr) - : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) + : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) + : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), + "i" (-EFAULT) : "memory"); } else return -ENOSYS; diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h index fc946c835995..2e54b4bff5cf 100644 --- a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h +++ b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h @@ -49,6 +49,7 @@ #include +#include #include #ifndef R10000_LLSC_WAR @@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr, " "__beqz"%0, 1b \n" " nop \n" " .set pop \n" - : "=&r" (temp), "=m" (*addr) - : "ir" (~mask), "ir" (value), "m" (*addr)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) + : "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr)); } /* @@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr, " "__beqz"%0, 1b \n" " nop \n" " .set pop \n" - : "=&r" (temp), "=m" (*addr) - : "ir" (mask), "m" (*addr)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) + : "ir" (mask), GCC_OFF12_ASM() (*addr)); } /* @@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr, " "__beqz"%0, 1b \n" " nop \n" " .set pop \n" - : "=&r" (temp), "=m" (*addr) - : "ir" (~mask), "m" (*addr)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) + : "ir" (~mask), GCC_OFF12_ASM() (*addr)); } /* @@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr, " "__beqz"%0, 1b \n" " nop \n" " .set pop \n" - : "=&r" (temp), "=m" (*addr) - : "ir" (mask), "m" (*addr)); + : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) + : "ir" (mask), GCC_OFF12_ASM() (*addr)); } /* @@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) " .set arch=r4000 \n" \ "1: ll %0, %1 #custom_read_reg32 \n" \ " .set pop \n" \ - : "=r" (tmp), "=m" (*address) \ - : "m" (*address)) + : "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \ + : GCC_OFF12_ASM() (*address)) #define custom_write_reg32(address, tmp) \ __asm__ __volatile__( \ @@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) " "__beqz"%0, 1b \n" \ " nop \n" \ " .set pop \n" \ - : "=&r" (tmp), "=m" (*address) \ - : "0" (tmp), "m" (*address)) + : "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \ + : "0" (tmp), GCC_OFF12_ASM() (*address)) #endif /* __ASM_REGOPS_H__ */ diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h index 024a71b2bff9..75739c83f07e 100644 --- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h +++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h @@ -76,6 +76,8 @@ #include +#include + #include /** * By default we disable the max depth support. Most programs @@ -273,7 +275,7 @@ static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id, " lbu %[ticket], %[now_serving]\n" "4:\n" ".set pop\n" : - [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), + [ticket_ptr] "=" GCC_OFF12_ASM()(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), [my_ticket] "=r"(my_ticket) ); diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 78d201fb6c87..c6d06d383ef9 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -12,6 +12,7 @@ #include #include +#include #include /* @@ -88,7 +89,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) " subu %[ticket], %[ticket], 1 \n" " .previous \n" " .set pop \n" - : [ticket_ptr] "+m" (lock->lock), + : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), [serving_now_ptr] "+m" (lock->h.serving_now), [ticket] "=&r" (tmp), [my_ticket] "=&r" (my_ticket) @@ -121,7 +122,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) " subu %[ticket], %[ticket], 1 \n" " .previous \n" " .set pop \n" - : [ticket_ptr] "+m" (lock->lock), + : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), [serving_now_ptr] "+m" (lock->h.serving_now), [ticket] "=&r" (tmp), [my_ticket] "=&r" (my_ticket) @@ -163,7 +164,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) " li %[ticket], 0 \n" " .previous \n" " .set pop \n" - : [ticket_ptr] "+m" (lock->lock), + : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), [ticket] "=&r" (tmp), [my_ticket] "=&r" (tmp2), [now_serving] "=&r" (tmp3) @@ -187,7 +188,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) " li %[ticket], 0 \n" " .previous \n" " .set pop \n" - : [ticket_ptr] "+m" (lock->lock), + : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), [ticket] "=&r" (tmp), [my_ticket] "=&r" (tmp2), [now_serving] "=&r" (tmp3) @@ -234,8 +235,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) " beqzl %1, 1b \n" " nop \n" " .set reorder \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } else { do { @@ -244,8 +245,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) " bltz %1, 1b \n" " addu %1, 1 \n" "2: sc %1, %0 \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } while (unlikely(!tmp)); } @@ -268,8 +269,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) " sub %1, 1 \n" " sc %1, %0 \n" " beqzl %1, 1b \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } else { do { @@ -277,8 +278,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) "1: ll %1, %2 # arch_read_unlock \n" " sub %1, 1 \n" " sc %1, %0 \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } while (unlikely(!tmp)); } @@ -298,8 +299,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) " beqzl %1, 1b \n" " nop \n" " .set reorder \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } else { do { @@ -308,8 +309,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) " bnez %1, 1b \n" " lui %1, 0x8000 \n" "2: sc %1, %0 \n" - : "=m" (rw->lock), "=&r" (tmp) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } while (unlikely(!tmp)); } @@ -348,8 +349,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) __WEAK_LLSC_MB " li %2, 1 \n" "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } else { __asm__ __volatile__( @@ -365,8 +366,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) __WEAK_LLSC_MB " li %2, 1 \n" "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } @@ -392,8 +393,8 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) " li %2, 1 \n" " .set reorder \n" "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } else { do { @@ -405,8 +406,9 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) " sc %1, %0 \n" " li %2, 1 \n" "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) + : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), + "=&r" (ret) + : GCC_OFF12_ASM() (rw->lock) : "memory"); } while (unlikely(!tmp)); -- GitLab From 0e525e48f73cc8a4df8da0be77e4146bea85e1a5 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:09:31 +0000 Subject: [PATCH 6115/9457] MIPS: Apply `.insn' to fixup labels throughout Fix the issue with the ISA bit being lost in fixups that jump to labels placed just before a section switch. Such a switch leads to the ISA bit being lost, because GAS concludes there is no code that follows and therefore the label refers to data. Use the `.insn' pseudo-op to convince the tool this is not the case. This lack of label annotation leads to microMIPS compilation errors like: mips-linux-gnu-ld: arch/mips/built-in.o: .fixup+0x3b8: Unsupported jump between ISA modes; consider recompiling with interlinking enabled. mips-linux-gnu-ld: final link failed: Bad value Signed-off-by: Maciej W. Rozycki Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8483/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/futex.h | 4 ++++ arch/mips/include/asm/paccess.h | 2 ++ arch/mips/kernel/syscall.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index d0177bf915bb..ef9987a61d88 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -33,6 +33,7 @@ " beqzl $1, 1b \n" \ __WEAK_LLSC_MB \ "3: \n" \ + " .insn \n" \ " .set pop \n" \ " .set mips0 \n" \ " .section .fixup,\"ax\" \n" \ @@ -61,6 +62,7 @@ " beqz $1, 1b \n" \ __WEAK_LLSC_MB \ "3: \n" \ + " .insn \n" \ " .set pop \n" \ " .set mips0 \n" \ " .section .fixup,\"ax\" \n" \ @@ -162,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " beqzl $1, 1b \n" __WEAK_LLSC_MB "3: \n" + " .insn \n" " .set pop \n" " .section .fixup,\"ax\" \n" "4: li %0, %6 \n" @@ -190,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " beqz $1, 1b \n" __WEAK_LLSC_MB "3: \n" + " .insn \n" " .set pop \n" " .section .fixup,\"ax\" \n" "4: li %0, %6 \n" diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h index 2474fc5d1751..af81ab0da55f 100644 --- a/arch/mips/include/asm/paccess.h +++ b/arch/mips/include/asm/paccess.h @@ -56,6 +56,7 @@ struct __large_pstruct { unsigned long buf[100]; }; "1:\t" insn "\t%1,%2\n\t" \ "move\t%0,$0\n" \ "2:\n\t" \ + ".insn\n\t" \ ".section\t.fixup,\"ax\"\n" \ "3:\tli\t%0,%3\n\t" \ "move\t%1,$0\n\t" \ @@ -94,6 +95,7 @@ extern void __get_dbe_unknown(void); "1:\t" insn "\t%1,%2\n\t" \ "move\t%0,$0\n" \ "2:\n\t" \ + ".insn\n\t" \ ".section\t.fixup,\"ax\"\n" \ "3:\tli\t%0,%3\n\t" \ "j\t2b\n\t" \ diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 4a4f9dda5658..604b558809c4 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -117,6 +117,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) "2: sc %[tmp], (%[addr]) \n" " beqzl %[tmp], 1b \n" "3: \n" + " .insn \n" " .section .fixup,\"ax\" \n" "4: li %[err], %[efault] \n" " j 3b \n" @@ -142,6 +143,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) "2: sc %[tmp], (%[addr]) \n" " bnez %[tmp], 4f \n" "3: \n" + " .insn \n" " .subsection 2 \n" "4: b 1b \n" " .previous \n" -- GitLab From ddb3108e30e45f5d58737f6fb8256df10c2c515b Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 15 Nov 2014 22:09:54 +0000 Subject: [PATCH 6116/9457] MIPS: atomic.h: Reformat to fit in 79 columns Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8484/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/atomic.h | 361 +++++++++++++++++---------------- 1 file changed, 181 insertions(+), 180 deletions(-) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index ec4b4d658bc4..857da84cfc92 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -41,97 +41,97 @@ */ #define atomic_set(v, i) ((v)->counter = (i)) -#define ATOMIC_OP(op, c_op, asm_op) \ -static __inline__ void atomic_##op(int i, atomic_t * v) \ -{ \ - if (kernel_uses_llsc && R10000_LLSC_WAR) { \ - int temp; \ - \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - "1: ll %0, %1 # atomic_" #op " \n" \ - " " #asm_op " %0, %2 \n" \ - " sc %0, %1 \n" \ - " beqzl %0, 1b \n" \ - " .set mips0 \n" \ - : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } else if (kernel_uses_llsc) { \ - int temp; \ - \ - do { \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - " ll %0, %1 # atomic_" #op "\n" \ - " " #asm_op " %0, %2 \n" \ - " sc %0, %1 \n" \ - " .set mips0 \n" \ - : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } while (unlikely(!temp)); \ - } else { \ - unsigned long flags; \ - \ - raw_local_irq_save(flags); \ - v->counter c_op i; \ - raw_local_irq_restore(flags); \ - } \ -} \ - -#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ -static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ -{ \ - int result; \ - \ - smp_mb__before_llsc(); \ - \ - if (kernel_uses_llsc && R10000_LLSC_WAR) { \ - int temp; \ - \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - "1: ll %1, %2 # atomic_" #op "_return \n" \ - " " #asm_op " %0, %1, %3 \n" \ - " sc %0, %2 \n" \ - " beqzl %0, 1b \n" \ - " " #asm_op " %0, %1, %3 \n" \ - " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), \ - "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } else if (kernel_uses_llsc) { \ - int temp; \ - \ - do { \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - " ll %1, %2 # atomic_" #op "_return \n" \ - " " #asm_op " %0, %1, %3 \n" \ - " sc %0, %2 \n" \ - " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), \ - "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } while (unlikely(!result)); \ - \ - result = temp; result c_op i; \ - } else { \ - unsigned long flags; \ - \ - raw_local_irq_save(flags); \ - result = v->counter; \ - result c_op i; \ - v->counter = result; \ - raw_local_irq_restore(flags); \ - } \ - \ - smp_llsc_mb(); \ - \ - return result; \ +#define ATOMIC_OP(op, c_op, asm_op) \ +static __inline__ void atomic_##op(int i, atomic_t * v) \ +{ \ + if (kernel_uses_llsc && R10000_LLSC_WAR) { \ + int temp; \ + \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + "1: ll %0, %1 # atomic_" #op " \n" \ + " " #asm_op " %0, %2 \n" \ + " sc %0, %1 \n" \ + " beqzl %0, 1b \n" \ + " .set mips0 \n" \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } else if (kernel_uses_llsc) { \ + int temp; \ + \ + do { \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + " ll %0, %1 # atomic_" #op "\n" \ + " " #asm_op " %0, %2 \n" \ + " sc %0, %1 \n" \ + " .set mips0 \n" \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } while (unlikely(!temp)); \ + } else { \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + v->counter c_op i; \ + raw_local_irq_restore(flags); \ + } \ } -#define ATOMIC_OPS(op, c_op, asm_op) \ - ATOMIC_OP(op, c_op, asm_op) \ +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ +{ \ + int result; \ + \ + smp_mb__before_llsc(); \ + \ + if (kernel_uses_llsc && R10000_LLSC_WAR) { \ + int temp; \ + \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + "1: ll %1, %2 # atomic_" #op "_return \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " sc %0, %2 \n" \ + " beqzl %0, 1b \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " .set mips0 \n" \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } else if (kernel_uses_llsc) { \ + int temp; \ + \ + do { \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + " ll %1, %2 # atomic_" #op "_return \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " sc %0, %2 \n" \ + " .set mips0 \n" \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } while (unlikely(!result)); \ + \ + result = temp; result c_op i; \ + } else { \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + result = v->counter; \ + result c_op i; \ + v->counter = result; \ + raw_local_irq_restore(flags); \ + } \ + \ + smp_llsc_mb(); \ + \ + return result; \ +} + +#define ATOMIC_OPS(op, c_op, asm_op) \ + ATOMIC_OP(op, c_op, asm_op) \ ATOMIC_OP_RETURN(op, c_op, asm_op) ATOMIC_OPS(add, +=, addu) @@ -320,98 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) */ #define atomic64_set(v, i) ((v)->counter = (i)) -#define ATOMIC64_OP(op, c_op, asm_op) \ -static __inline__ void atomic64_##op(long i, atomic64_t * v) \ -{ \ - if (kernel_uses_llsc && R10000_LLSC_WAR) { \ - long temp; \ - \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - "1: lld %0, %1 # atomic64_" #op " \n" \ - " " #asm_op " %0, %2 \n" \ - " scd %0, %1 \n" \ - " beqzl %0, 1b \n" \ - " .set mips0 \n" \ - : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } else if (kernel_uses_llsc) { \ - long temp; \ - \ - do { \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - " lld %0, %1 # atomic64_" #op "\n" \ - " " #asm_op " %0, %2 \n" \ - " scd %0, %1 \n" \ - " .set mips0 \n" \ - : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } while (unlikely(!temp)); \ - } else { \ - unsigned long flags; \ - \ - raw_local_irq_save(flags); \ - v->counter c_op i; \ - raw_local_irq_restore(flags); \ - } \ -} \ - -#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ -static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ -{ \ - long result; \ - \ - smp_mb__before_llsc(); \ - \ - if (kernel_uses_llsc && R10000_LLSC_WAR) { \ - long temp; \ - \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - "1: lld %1, %2 # atomic64_" #op "_return\n" \ - " " #asm_op " %0, %1, %3 \n" \ - " scd %0, %2 \n" \ - " beqzl %0, 1b \n" \ - " " #asm_op " %0, %1, %3 \n" \ - " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), \ - "+" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i)); \ - } else if (kernel_uses_llsc) { \ - long temp; \ - \ - do { \ - __asm__ __volatile__( \ - " .set arch=r4000 \n" \ - " lld %1, %2 # atomic64_" #op "_return\n" \ - " " #asm_op " %0, %1, %3 \n" \ - " scd %0, %2 \n" \ - " .set mips0 \n" \ - : "=&r" (result), "=&r" (temp), \ - "=" GCC_OFF12_ASM() (v->counter) \ - : "Ir" (i), GCC_OFF12_ASM() (v->counter) \ - : "memory"); \ - } while (unlikely(!result)); \ - \ - result = temp; result c_op i; \ - } else { \ - unsigned long flags; \ - \ - raw_local_irq_save(flags); \ - result = v->counter; \ - result c_op i; \ - v->counter = result; \ - raw_local_irq_restore(flags); \ - } \ - \ - smp_llsc_mb(); \ - \ - return result; \ +#define ATOMIC64_OP(op, c_op, asm_op) \ +static __inline__ void atomic64_##op(long i, atomic64_t * v) \ +{ \ + if (kernel_uses_llsc && R10000_LLSC_WAR) { \ + long temp; \ + \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + "1: lld %0, %1 # atomic64_" #op " \n" \ + " " #asm_op " %0, %2 \n" \ + " scd %0, %1 \n" \ + " beqzl %0, 1b \n" \ + " .set mips0 \n" \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } else if (kernel_uses_llsc) { \ + long temp; \ + \ + do { \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + " lld %0, %1 # atomic64_" #op "\n" \ + " " #asm_op " %0, %2 \n" \ + " scd %0, %1 \n" \ + " .set mips0 \n" \ + : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } while (unlikely(!temp)); \ + } else { \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + v->counter c_op i; \ + raw_local_irq_restore(flags); \ + } \ +} + +#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ +static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ +{ \ + long result; \ + \ + smp_mb__before_llsc(); \ + \ + if (kernel_uses_llsc && R10000_LLSC_WAR) { \ + long temp; \ + \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + "1: lld %1, %2 # atomic64_" #op "_return\n" \ + " " #asm_op " %0, %1, %3 \n" \ + " scd %0, %2 \n" \ + " beqzl %0, 1b \n" \ + " " #asm_op " %0, %1, %3 \n" \ + " .set mips0 \n" \ + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i)); \ + } else if (kernel_uses_llsc) { \ + long temp; \ + \ + do { \ + __asm__ __volatile__( \ + " .set arch=r4000 \n" \ + " lld %1, %2 # atomic64_" #op "_return\n" \ + " " #asm_op " %0, %1, %3 \n" \ + " scd %0, %2 \n" \ + " .set mips0 \n" \ + : "=&r" (result), "=&r" (temp), \ + "=" GCC_OFF12_ASM() (v->counter) \ + : "Ir" (i), GCC_OFF12_ASM() (v->counter) \ + : "memory"); \ + } while (unlikely(!result)); \ + \ + result = temp; result c_op i; \ + } else { \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + result = v->counter; \ + result c_op i; \ + v->counter = result; \ + raw_local_irq_restore(flags); \ + } \ + \ + smp_llsc_mb(); \ + \ + return result; \ } -#define ATOMIC64_OPS(op, c_op, asm_op) \ - ATOMIC64_OP(op, c_op, asm_op) \ +#define ATOMIC64_OPS(op, c_op, asm_op) \ + ATOMIC64_OP(op, c_op, asm_op) \ ATOMIC64_OP_RETURN(op, c_op, asm_op) ATOMIC64_OPS(add, +=, daddu) @@ -422,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu) #undef ATOMIC64_OP /* - * atomic64_sub_if_positive - conditionally subtract integer from atomic variable + * atomic64_sub_if_positive - conditionally subtract integer from atomic + * variable * @i: integer value to subtract * @v: pointer of type atomic64_t * -- GitLab From 85546d7ec827b7b0ff822cc86644c1b081142e53 Mon Sep 17 00:00:00 2001 From: Maarten ter Huurne Date: Tue, 9 Sep 2014 14:04:00 +0200 Subject: [PATCH 6117/9457] MIPS: Remove declaration of obsolete arch_init_clk_ops() Signed-off-by: Maarten ter Huurne Cc: Apelete Seketeli Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7671/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/clock.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h index 778e32d817bc..4809c29a4890 100644 --- a/arch/mips/include/asm/clock.h +++ b/arch/mips/include/asm/clock.h @@ -35,9 +35,6 @@ struct clk { #define CLK_ALWAYS_ENABLED (1 << 0) #define CLK_RATE_PROPAGATES (1 << 1) -/* Should be defined by processor-specific code */ -void arch_init_clk_ops(struct clk_ops **, int type); - int clk_init(void); int __clk_enable(struct clk *); -- GitLab From ac41f9c46282926c92b8bd0dcb1aca29a97d13ab Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 20 Nov 2014 22:45:58 +0100 Subject: [PATCH 6118/9457] MIPS: Remove a temporary hack for debugging cache flushes in SMTC configuration Signed-off-by: Ralf Baechle Cc: Leonid Yegoshin Cc: linux-mips@linux-mips.org Cc: aaro.koskinen@iki.fi Cc: david.daney@cavium.com Cc: linux-kernel@vger.kernel.org Cc: markos.chandras@imgtec.com Cc: dengcheng.zhu@imgtec.com Cc: chenhc@lemote.com Cc: akpm@linux-foundation.org Patchwork: https://patchwork.linux-mips.org/patch/8535/ --- arch/mips/include/asm/r4kcache.h | 59 -------------------------------- 1 file changed, 59 deletions(-) diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 4520adc8699b..617d2b8211f5 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -47,79 +47,20 @@ extern void (*r4k_blast_icache)(void); #ifdef CONFIG_MIPS_MT -/* - * Optionally force single-threaded execution during I-cache flushes. - */ -#define PROTECT_CACHE_FLUSHES 1 - -#ifdef PROTECT_CACHE_FLUSHES - -extern int mt_protiflush; -extern int mt_protdflush; -extern void mt_cflush_lockdown(void); -extern void mt_cflush_release(void); - -#define BEGIN_MT_IPROT \ - unsigned long flags = 0; \ - unsigned long mtflags = 0; \ - if(mt_protiflush) { \ - local_irq_save(flags); \ - ehb(); \ - mtflags = dvpe(); \ - mt_cflush_lockdown(); \ - } - -#define END_MT_IPROT \ - if(mt_protiflush) { \ - mt_cflush_release(); \ - evpe(mtflags); \ - local_irq_restore(flags); \ - } - -#define BEGIN_MT_DPROT \ - unsigned long flags = 0; \ - unsigned long mtflags = 0; \ - if(mt_protdflush) { \ - local_irq_save(flags); \ - ehb(); \ - mtflags = dvpe(); \ - mt_cflush_lockdown(); \ - } - -#define END_MT_DPROT \ - if(mt_protdflush) { \ - mt_cflush_release(); \ - evpe(mtflags); \ - local_irq_restore(flags); \ - } - -#else - -#define BEGIN_MT_IPROT -#define BEGIN_MT_DPROT -#define END_MT_IPROT -#define END_MT_DPROT - -#endif /* PROTECT_CACHE_FLUSHES */ - #define __iflush_prologue \ unsigned long redundance; \ extern int mt_n_iflushes; \ - BEGIN_MT_IPROT \ for (redundance = 0; redundance < mt_n_iflushes; redundance++) { #define __iflush_epilogue \ - END_MT_IPROT \ } #define __dflush_prologue \ unsigned long redundance; \ extern int mt_n_dflushes; \ - BEGIN_MT_DPROT \ for (redundance = 0; redundance < mt_n_dflushes; redundance++) { #define __dflush_epilogue \ - END_MT_DPROT \ } #define __inv_dflush_prologue __dflush_prologue -- GitLab From ccd3988086364837d0c0fb4563d715c691636313 Mon Sep 17 00:00:00 2001 From: Prem Karat Date: Mon, 21 Apr 2014 09:33:16 +0530 Subject: [PATCH 6119/9457] MIPS: Enable VDSO randomization Based on commit 1091458d09e1a (mmap randomization) For 32-bit address spaces randomize within a 16MB space, for 64-bit within a 256MB space. Test Results: ------------ Without Patch (VDSO is not randomized) --------------------------------------- root@Maleo:~# ./aslr vdso FAIL: ASLR not functional (vdso always at 0x7fff7000) root@Maleo:~# ./aslr rekey vdso pre_val==cur_val value=0x7fff7000 With patch:(VDSO is randmoized and doesn't interfere with stack) ---------------------------------------------------------------- root@cavium-octeon2:~# ./aslr rekey vdso pre_val!=cur_val previous_value=0x7f830ea2 current_value=0x776e2000 root@cavium-octeon2:~# ./aslr rekey vdso pre_val!=cur_val previous_value=0x7fb0cea2 current_value=0x77209000 root@cavium-octeon2:~# ./aslr rekey vdso pre_val!=cur_val previous_value=0x7f985ea2 current_value=0x7770c000 root@cavium-octeon2:~# ./aslr rekey vdso pre_val!=cur_val previous_value=0x7fbc6ea2 current_value=0x7fe25000 Maps file output: ------------------------- root@cavium-octeon2:~# ./aslr rekey maps 78584000-785a5000 rwxp 00000000 00:00 0 [heap] 7f9d0000-7f9f1000 rw-p 00000000 00:00 0 [stack] 7ffa5000-7ffa6000 r-xp 00000000 00:00 0 [vdso] root@cavium-octeon2:~# ./aslr rekey maps 77de0000-77e01000 rwxp 00000000 00:00 0 [heap] 7f91b000-7f93c000 rw-p 00000000 00:00 0 [stack] 7ff99000-7ff9a000 r-xp 00000000 00:00 0 [vdso] root@cavium-octeon2:~# ./aslr rekey maps 77d7f000-77da0000 rwxp 00000000 00:00 0 [heap] 7fc2a000-7fc4b000 rw-p 00000000 00:00 0 [stack] 7fe09000-7fe0a000 r-xp 00000000 00:00 0 [vdso] root@cavium-octeon2:~# ./aslr rekey maps 7794c000-7794d000 r-xp 00000000 00:00 0 [vdso] 77e4b000-77e6c000 rwxp 00000000 00:00 0 [heap] 7f6e7000-7f708000 rw-p 00000000 00:00 0 [stack] root@cavium-octeon2:~# Signed-off-by: Prem Karat Cc: linux-mips@linux-mips.org Cc: sergei.shtylyov@cogentembedded.com Cc: ddaney.cavm@gmail.com Patchwork: https://patchwork.linux-mips.org/patch/6812 Signed-off-by: Ralf Baechle --- arch/mips/kernel/vdso.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 0f1af58b036a..ed2a278722a9 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -16,9 +16,11 @@ #include #include #include +#include #include #include +#include /* * Including would give use the 64-bit syscall numbers ... @@ -67,7 +69,18 @@ subsys_initcall(init_vdso); static unsigned long vdso_addr(unsigned long start) { - return STACK_TOP; + unsigned long offset = 0UL; + + if (current->flags & PF_RANDOMIZE) { + offset = get_random_int(); + offset <<= PAGE_SHIFT; + if (TASK_IS_32BIT_ADDR) + offset &= 0xfffffful; + else + offset &= 0xffffffful; + } + + return STACK_TOP + offset; } int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) -- GitLab From 70371cef114ca295a890069e12c1def08bb300f7 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 15 Nov 2014 16:17:45 -0800 Subject: [PATCH 6120/9457] MAINTAINERS: Add entry for BMIPS multiplatform kernel Add myself as a maintainer for the new BMIPS target. Signed-off-by: Kevin Cernekee Cc: f.fainelli@gmail.com Cc: jfraser@broadcom.com Cc: dtor@chromium.org Cc: tglx@linutronix.de Cc: jason@lakedaemon.net Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/8505/ Signed-off-by: Ralf Baechle --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 680861287cb7..eedc64bb1865 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2116,6 +2116,18 @@ S: Maintained F: arch/arm/mach-bcm/*brcmstb* F: arch/arm/boot/dts/bcm7*.dts* +BROADCOM BMIPS MIPS ARCHITECTURE +M: Kevin Cernekee +M: Florian Fainelli +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/bmips/* +F: arch/mips/include/asm/mach-bmips/* +F: arch/mips/kernel/*bmips* +F: arch/mips/boot/dts/bcm*.dts* +F: drivers/irqchip/irq-bcm7* +F: drivers/irqchip/irq-brcmstb* + BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan M: Michael Chan -- GitLab From d98aefc384763813b3085a4a9eff2c6281cb5f56 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 22 Nov 2014 00:24:59 +0100 Subject: [PATCH 6121/9457] MIPS: fix indentation. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index a845aafedee4..247207b9292d 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h @@ -11,7 +11,7 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H -# include +#include #include /* -- GitLab From 0845bb721ebb7b88da4dfe3f3ece67963efc006f Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 2 Apr 2014 09:53:24 +0100 Subject: [PATCH 6122/9457] MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO Using the __raw_{read,write}{b,w,l} functions to perform repeatable MMIO could result in problems if the host bus does not match the endianness of the PCI/ISA. This problem is visible on big-endian SEAD3 configurations after commit 2925f6c0c7af32720dcbadc586463aeceb6baa22 "net: smc911x: use io{read,write}*_rep accessors". This effectively moves away from using the __mem_* variants to __raw_* ones and causes a kernel bug as follows: Call Trace: CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 00000000, ra == 8012b3b0 Oops[#1]: Cpu 0 $ 0 : 00000000 00000065 00000000 00000004 $ 4 : 00000000 00000000 9a82dd60 00000000 $ 8 : 00000000 00000000 a00ae278 00000007 $12 : 0000000e 00000011 804c4228 ffff9411 $16 : 00000100 00000000 80560000 807fc6d0 $20 : 807fc8d0 807fcad0 807fbec0 00000100 $24 : 00009150 80109be0 $28 : 9a82c000 9a82dd28 00000001 8012b3b0 Hi : 00000000 Lo : 00000000 epc : 00000000 (null) Not tainted ra : 8012b3b0 call_timer_fn.isra.39+0x24/0x84 Status: 10009503 KERNEL EXL IE Cause : 00800808 BadVA : 00000000 PrId : 00019c20 (MIPS M14Kc) Modules linked in: Process swapper (pid: 1, threadinfo=9a82c000, task=9a82ba18, tls=00000000) Stack : 00000040 00000000 00000007 8056732c 80580000 00000001 9a82dd60 00200200 80560000 8012b598 8056732c 80580000 00000001 00000000 9a82dd60 9a82dd60 00000000 807fbd44 807fbd40 805664e0 0000000a 80800000 00000004 80125924 0000fda0 000007f0 80000000 00000001 80800000 007f0000 00200140 80166338 00000000 8100fda0 0000fda0 000007f0 80000000 00000001 80800000 007f0000 ... Call Trace: [<8012b598>] run_timer_softirq+0x188/0x1f4 [<80125924>] __do_softirq+0xc4/0x18c [<80166338>] handle_percpu_irq+0x54/0x84 [<80125aa4>] do_softirq+0x68/0x70 [<80103b50>] do_IRQ+0x18/0x28 [<80125d1c>] irq_exit+0x94/0xc0 [<80125aa4>] do_softirq+0x68/0x70 [<80102130>] ret_from_irq+0x0/0x4 [<80102130>] ret_from_irq+0x0/0x4 [<80125d1c>] irq_exit+0x94/0xc0 [<803165b0>] __bzero+0xd4/0x164 [<80346d0c>] mem32_serial_out+0x0/0x1c [<8010d4ac>] free_init_pages+0x98/0xfc [<80180a08>] free_hot_cold_page+0x2c/0x1c4 [<80180bd8>] __free_pages+0x38/0x98 [<8010d4a0>] free_init_pages+0x8c/0xfc [<8010d4ac>] free_init_pages+0x98/0xfc [<8049fb04>] kernel_init+0x28/0x15c [<80147484>] schedule_tail+0x1c/0x60 [<8049fadc>] kernel_init+0x0/0x15c [<80102178>] ret_from_kernel_thread+0x14/0x1c [<8040a06f>] skb_pad+0xe7/0x13c Signed-off-by: Markos Chandras Cc: Steve Glendinning Cc: Ben Boeckel Cc: Jeff Kirsher Cc: David S. Miller Cc: netdev@vger.kernel.org Cc: Jeffrey Deans Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6672/ Signed-off-by: Ralf Baechle --- arch/mips/lib/iomap.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index e3acb2dad33a..8e7e378ce51c 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be); /* * These are the "repeat MMIO read/write" functions. - * Note the "__raw" accesses, since we don't want to - * convert to CPU byte order. We write in "IO byte - * order" (we also don't have IO barriers). + * Note the "__mem" accesses, since we want to convert + * to CPU byte order if the host bus happens to not match the + * endianness of PCI/ISA (see mach-generic/mangle-port.h). */ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) { while (--count >= 0) { - u8 data = __raw_readb(addr); + u8 data = __mem_readb(addr); *dst = data; dst++; } @@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) { while (--count >= 0) { - u16 data = __raw_readw(addr); + u16 data = __mem_readw(addr); *dst = data; dst++; } @@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) { while (--count >= 0) { - u32 data = __raw_readl(addr); + u32 data = __mem_readl(addr); *dst = data; dst++; } @@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) { while (--count >= 0) { - __raw_writeb(*src, addr); + __mem_writeb(*src, addr); src++; } } @@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) { while (--count >= 0) { - __raw_writew(*src, addr); + __mem_writew(*src, addr); src++; } } @@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) { while (--count >= 0) { - __raw_writel(*src, addr); + __mem_writel(*src, addr); src++; } } -- GitLab From dd2adea415f108da37c801d1af384ae7cdf46dce Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 19 Nov 2014 08:58:10 +0000 Subject: [PATCH 6123/9457] MIPS: lib: memset: Clean up some MIPS{EL,EB} ifdefery The toolchain defines exactly one of __MIPSEB__ and __MIPSEL__. As a result, simplify the ifdefery a little bit. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8522/ Signed-off-by: Ralf Baechle --- arch/mips/lib/memset.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 7b0e5462ca51..c8fe6b1968fb 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -114,8 +114,7 @@ R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ -#endif -#ifdef __MIPSEL__ +#else EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ #endif PTR_SUBU a0, t0 /* long align ptr */ @@ -164,8 +163,7 @@ R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) -#endif -#ifdef __MIPSEL__ +#else EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) #endif 1: jr ra -- GitLab From 5cbb37df378dbedfa2b5f542b6d50937736f2427 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Thu, 6 Nov 2014 19:23:35 +0900 Subject: [PATCH 6124/9457] drm/exynos: resolve infinite loop issue on multi-platform This patch resolves temporarily infinite loop issue incurred when Exynos drm driver is enabled and multi-platform kernel is used by registering Exynos drm device object only in case of Exynos SoC. So this patch will be replaced with more generic way later. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index c57466edf45b..d41aae0dcc60 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -741,6 +741,18 @@ static int exynos_drm_init(void) { int ret; + /* + * Register device object only in case of Exynos SoC. + * + * Below codes resolves temporarily infinite loop issue incurred + * by Exynos drm driver when using multi-platform kernel. + * So these codes will be replaced with more generic way later. + */ + if (!of_machine_is_compatible("samsung,exynos3") && + !of_machine_is_compatible("samsung,exynos4") && + !of_machine_is_compatible("samsung,exynos5")) + return -ENODEV; + exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, NULL, 0); if (IS_ERR(exynos_drm_pdev)) -- GitLab From fbdf093d62de4974cd30f170cf76aa14e26b13e4 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Thu, 6 Nov 2014 23:00:37 +0900 Subject: [PATCH 6125/9457] drm/exynos: resolve infinite loop issue on non multi-platform This patch resovles the infinite loop issue incurred when Exyno drm driver is enabled but all kms drivers are disabled on Exynos board by returning -EPROBE_DEFER only in case that there is kms device registered. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index d41aae0dcc60..b8abbc4a3d8b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev) mutex_lock(&drm_component_lock); + /* Do not retry to probe if there is no any kms driver regitered. */ + if (list_empty(&drm_component_list)) { + mutex_unlock(&drm_component_lock); + return ERR_PTR(-ENODEV); + } + list_for_each_entry(cdev, &drm_component_list, list) { /* * Add components to master only in case that crtc and -- GitLab From 2d15118750fd69a50cf286d3fc275546fa0b5857 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Fri, 7 Nov 2014 20:31:08 +0900 Subject: [PATCH 6126/9457] drm/exynos: g2d: fix null pointer dereference This patch fixes a null pointer dereference issue incurred by calling g2d_remove when exynos_drm_platform_probe is failed. cmdlist_pool of g2d is allocated when g2d sub driver is probed. So if exynos_drm_platform_probe is failed, the g2d sub driver is not probed and the cmdlist_pool is still NULL. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index df7a77d3eff8..6ff8599f6cbf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -302,9 +302,12 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d) struct exynos_drm_subdrv *subdrv = &g2d->subdrv; kfree(g2d->cmdlist_node); - dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, - g2d->cmdlist_pool_virt, - g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); + + if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) { + dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, + g2d->cmdlist_pool_virt, + g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); + } } static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) -- GitLab From e9fbdcb45a36c775383dd98d53b4452cdb5e53c0 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Fri, 7 Nov 2014 21:32:34 +0900 Subject: [PATCH 6127/9457] drm/exynos: fix possible infinite loop issue This patch fixes possible infinite loop issue by postponing registration to non kms drivers after component_master_add_with_match call, which can be incurred in all cases that non kms driver is probed and then component bind is failed This patch should be applied on top of below patches, http://comments.gmane.org/gmane.comp.video.dri.devel/117740 http://www.spinics.net/lists/linux-samsung-soc/msg38624.html Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 31 ++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index b8abbc4a3d8b..e5c4c6c8c967 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -591,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) goto err_unregister_mixer_drv; #endif + match = exynos_drm_match_add(&pdev->dev); + if (IS_ERR(match)) { + ret = PTR_ERR(match); + goto err_unregister_hdmi_drv; + } + + ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, + match); + if (ret < 0) + goto err_unregister_hdmi_drv; + #ifdef CONFIG_DRM_EXYNOS_G2D ret = platform_driver_register(&g2d_driver); if (ret < 0) - goto err_unregister_hdmi_drv; + goto err_del_component_master; #endif #ifdef CONFIG_DRM_EXYNOS_FIMC @@ -625,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) goto err_unregister_ipp_drv; #endif - match = exynos_drm_match_add(&pdev->dev); - if (IS_ERR(match)) { - ret = PTR_ERR(match); - goto err_unregister_resources; - } - - ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, - match); - if (ret < 0) - goto err_unregister_resources; - return ret; -err_unregister_resources: - #ifdef CONFIG_DRM_EXYNOS_IPP - exynos_platform_device_ipp_unregister(); err_unregister_ipp_drv: platform_driver_unregister(&ipp_driver); err_unregister_gsc_drv: @@ -664,9 +661,11 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) #ifdef CONFIG_DRM_EXYNOS_G2D platform_driver_unregister(&g2d_driver); -err_unregister_hdmi_drv: +err_del_component_master: #endif + component_master_del(&pdev->dev, &exynos_drm_ops); +err_unregister_hdmi_drv: #ifdef CONFIG_DRM_EXYNOS_HDMI platform_driver_unregister(&hdmi_driver); err_unregister_mixer_drv: -- GitLab From 421ee18d4e040d673f5ce2972efa75c2ce0826d9 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Thu, 13 Nov 2014 16:05:12 +0900 Subject: [PATCH 6128/9457] drm/exynos: fix null pointer dereference issue This patch fixes null pointer dereference issue incurred when ipp driver is enabled and Exynos drm driver is closed. Non kms driver should register its own sub driver to setup necessary resources, which is done by load(). So null pointer dereference occurs when ipp driver is enabled and Exynos drm driver is closed because ipp core device is registered after component_master_add_with_match call. This patch makes exynos_drm_device_subdrv_probe() to be called after all non kms drivers are registered. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index e5c4c6c8c967..f0bcdc61778b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -108,11 +108,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_unbind_all; - /* Probe non kms sub drivers and virtual display driver. */ - ret = exynos_drm_device_subdrv_probe(dev); - if (ret) - goto err_cleanup_vblank; - /* * enable drm irq mode. * - with irq_enabled = true, we can use the vblank feature. @@ -138,8 +133,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) return 0; -err_cleanup_vblank: - drm_vblank_cleanup(dev); err_unbind_all: component_unbind_all(dev->dev, dev); err_mode_config_cleanup: @@ -153,8 +146,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) static int exynos_drm_unload(struct drm_device *dev) { - exynos_drm_device_subdrv_remove(dev); - exynos_drm_fbdev_fini(dev); drm_kms_helper_poll_fini(dev); @@ -636,9 +627,16 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) goto err_unregister_ipp_drv; #endif + /* Probe non kms sub drivers and virtual display driver. */ + ret = exynos_drm_device_subdrv_probe(platform_get_drvdata(pdev)); + if (ret) + goto err_unregister_resources; + return ret; +err_unregister_resources: #ifdef CONFIG_DRM_EXYNOS_IPP + exynos_platform_device_ipp_unregister(); err_unregister_ipp_drv: platform_driver_unregister(&ipp_driver); err_unregister_gsc_drv: @@ -691,6 +689,8 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) static int exynos_drm_platform_remove(struct platform_device *pdev) { + exynos_drm_device_subdrv_remove(platform_get_drvdata(pdev)); + #ifdef CONFIG_DRM_EXYNOS_IPP exynos_platform_device_ipp_unregister(); platform_driver_unregister(&ipp_driver); -- GitLab From 7239067795dc03be5b152034558bed0bb9c73ab3 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 13 Nov 2014 16:37:57 +0900 Subject: [PATCH 6129/9457] drm/exynos: remove ifdeferry from initialization code The patch replaces separate calls to driver (de)registration by loops over the array of drivers. As a result it significantly decreases number of ifdefs. Additionally it moves device registration related ifdefs to header file. Changelog v2: - Rebased. - Consider non kms driver in respect to infinite loop issue. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 196 ++++++++---------------- drivers/gpu/drm/exynos/exynos_drm_drv.h | 25 ++- 2 files changed, 72 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index f0bcdc61778b..8aee62902ec6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -547,85 +547,74 @@ static const struct component_master_ops exynos_drm_ops = { .unbind = exynos_drm_unbind, }; -static int exynos_drm_platform_probe(struct platform_device *pdev) -{ - struct component_match *match; - int ret; - - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls); - +static struct platform_driver *const exynos_drm_kms_drivers[] = { #ifdef CONFIG_DRM_EXYNOS_FIMD - ret = platform_driver_register(&fimd_driver); - if (ret < 0) - return ret; + &fimd_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_DP - ret = platform_driver_register(&dp_driver); - if (ret < 0) - goto err_unregister_fimd_drv; + &dp_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_DSI - ret = platform_driver_register(&dsi_driver); - if (ret < 0) - goto err_unregister_dp_drv; + &dsi_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_HDMI - ret = platform_driver_register(&mixer_driver); - if (ret < 0) - goto err_unregister_dsi_drv; - ret = platform_driver_register(&hdmi_driver); - if (ret < 0) - goto err_unregister_mixer_drv; + &mixer_driver, + &hdmi_driver, #endif +}; - match = exynos_drm_match_add(&pdev->dev); - if (IS_ERR(match)) { - ret = PTR_ERR(match); - goto err_unregister_hdmi_drv; - } - - ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, - match); - if (ret < 0) - goto err_unregister_hdmi_drv; - +static struct platform_driver *const exynos_drm_non_kms_drivers[] = { #ifdef CONFIG_DRM_EXYNOS_G2D - ret = platform_driver_register(&g2d_driver); - if (ret < 0) - goto err_del_component_master; + &g2d_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_FIMC - ret = platform_driver_register(&fimc_driver); - if (ret < 0) - goto err_unregister_g2d_drv; + &fimc_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_ROTATOR - ret = platform_driver_register(&rotator_driver); - if (ret < 0) - goto err_unregister_fimc_drv; + &rotator_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_GSC - ret = platform_driver_register(&gsc_driver); - if (ret < 0) - goto err_unregister_rotator_drv; + &gsc_driver, #endif - #ifdef CONFIG_DRM_EXYNOS_IPP - ret = platform_driver_register(&ipp_driver); + &ipp_driver, +#endif +}; + +static int exynos_drm_platform_probe(struct platform_device *pdev) +{ + struct component_match *match; + int ret, i, j; + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls); + + for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { + ret = platform_driver_register(exynos_drm_kms_drivers[i]); + if (ret < 0) + goto err_unregister_kms_drivers; + } + + match = exynos_drm_match_add(&pdev->dev); + if (IS_ERR(match)) { + ret = PTR_ERR(match); + goto err_unregister_kms_drivers; + } + + ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, + match); if (ret < 0) - goto err_unregister_gsc_drv; + goto err_unregister_kms_drivers; + + for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) { + ret = platform_driver_register(exynos_drm_non_kms_drivers[j]); + if (ret < 0) + goto err_del_component_master; + } ret = exynos_platform_device_ipp_register(); if (ret < 0) - goto err_unregister_ipp_drv; -#endif + goto err_unregister_non_kms_drivers; /* Probe non kms sub drivers and virtual display driver. */ ret = exynos_drm_device_subdrv_probe(platform_get_drvdata(pdev)); @@ -637,98 +626,39 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) err_unregister_resources: #ifdef CONFIG_DRM_EXYNOS_IPP exynos_platform_device_ipp_unregister(); -err_unregister_ipp_drv: - platform_driver_unregister(&ipp_driver); -err_unregister_gsc_drv: #endif +err_unregister_non_kms_drivers: + while (--j >= 0) + platform_driver_unregister(exynos_drm_non_kms_drivers[j]); -#ifdef CONFIG_DRM_EXYNOS_GSC - platform_driver_unregister(&gsc_driver); -err_unregister_rotator_drv: -#endif - -#ifdef CONFIG_DRM_EXYNOS_ROTATOR - platform_driver_unregister(&rotator_driver); -err_unregister_fimc_drv: -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMC - platform_driver_unregister(&fimc_driver); -err_unregister_g2d_drv: -#endif - -#ifdef CONFIG_DRM_EXYNOS_G2D - platform_driver_unregister(&g2d_driver); err_del_component_master: -#endif component_master_del(&pdev->dev, &exynos_drm_ops); -err_unregister_hdmi_drv: -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&hdmi_driver); -err_unregister_mixer_drv: - platform_driver_unregister(&mixer_driver); -err_unregister_dsi_drv: -#endif +err_unregister_kms_drivers: + while (--i >= 0) + platform_driver_unregister(exynos_drm_kms_drivers[i]); -#ifdef CONFIG_DRM_EXYNOS_DSI - platform_driver_unregister(&dsi_driver); -err_unregister_dp_drv: -#endif - -#ifdef CONFIG_DRM_EXYNOS_DP - platform_driver_unregister(&dp_driver); -err_unregister_fimd_drv: -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -#endif return ret; } static int exynos_drm_platform_remove(struct platform_device *pdev) { + int i; + exynos_drm_device_subdrv_remove(platform_get_drvdata(pdev)); #ifdef CONFIG_DRM_EXYNOS_IPP exynos_platform_device_ipp_unregister(); - platform_driver_unregister(&ipp_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_GSC - platform_driver_unregister(&gsc_driver); #endif -#ifdef CONFIG_DRM_EXYNOS_ROTATOR - platform_driver_unregister(&rotator_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMC - platform_driver_unregister(&fimc_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_G2D - platform_driver_unregister(&g2d_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&mixer_driver); - platform_driver_unregister(&hdmi_driver); -#endif + for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i) + platform_driver_unregister(exynos_drm_non_kms_drivers[i]); -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -#endif + component_master_del(&pdev->dev, &exynos_drm_ops); -#ifdef CONFIG_DRM_EXYNOS_DSI - platform_driver_unregister(&dsi_driver); -#endif + for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i) + platform_driver_unregister(exynos_drm_kms_drivers[i]); -#ifdef CONFIG_DRM_EXYNOS_DP - platform_driver_unregister(&dp_driver); -#endif - component_master_del(&pdev->dev, &exynos_drm_ops); return 0; } @@ -763,11 +693,9 @@ static int exynos_drm_init(void) if (IS_ERR(exynos_drm_pdev)) return PTR_ERR(exynos_drm_pdev); -#ifdef CONFIG_DRM_EXYNOS_VIDI ret = exynos_drm_probe_vidi(); if (ret < 0) goto err_unregister_pd; -#endif ret = platform_driver_register(&exynos_drm_platform_driver); if (ret) @@ -776,11 +704,9 @@ static int exynos_drm_init(void) return 0; err_remove_vidi: -#ifdef CONFIG_DRM_EXYNOS_VIDI exynos_drm_remove_vidi(); err_unregister_pd: -#endif platform_device_unregister(exynos_drm_pdev); return ret; @@ -789,9 +715,9 @@ static int exynos_drm_init(void) static void exynos_drm_exit(void) { platform_driver_unregister(&exynos_drm_platform_driver); -#ifdef CONFIG_DRM_EXYNOS_VIDI + exynos_drm_remove_vidi(); -#endif + platform_device_unregister(exynos_drm_pdev); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index d22e640f59a0..3c81c4b60399 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -323,15 +323,14 @@ int exynos_platform_device_hdmi_register(void); */ void exynos_platform_device_hdmi_unregister(void); -/* - * this function registers exynos drm ipp platform device. - */ +#ifdef CONFIG_DRM_EXYNOS_IPP int exynos_platform_device_ipp_register(void); - -/* - * this function unregisters exynos drm ipp platform device if it exists. - */ void exynos_platform_device_ipp_unregister(void); +#else +static inline int exynos_platform_device_ipp_register(void) { return 0; } +static inline void exynos_platform_device_ipp_unregister(void) {} +#endif + #ifdef CONFIG_DRM_EXYNOS_DPI struct exynos_drm_display * exynos_dpi_probe(struct device *dev); @@ -342,15 +341,13 @@ exynos_dpi_probe(struct device *dev) { return NULL; } static inline int exynos_dpi_remove(struct device *dev) { return 0; } #endif -/* - * this function registers exynos drm vidi platform device/driver. - */ +#ifdef CONFIG_DRM_EXYNOS_VIDI int exynos_drm_probe_vidi(void); - -/* - * this function unregister exynos drm vidi platform device/driver. - */ void exynos_drm_remove_vidi(void); +#else +static inline int exynos_drm_probe_vidi(void) { return 0; } +static inline void exynos_drm_remove_vidi(void) {} +#endif /* This function creates a encoder and a connector, and initializes them. */ int exynos_drm_create_enc_conn(struct drm_device *dev, -- GitLab From 2900c69c52079a0340db0f012d2b2e92db7544c4 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 7 Oct 2014 14:01:08 +0200 Subject: [PATCH 6130/9457] drm/exynos: dsi: remove global variable exynos_dsi_display exynos_dsi_display is used by internal Exynos DRM framework for representing pair encoder->connecter. As it should be mapped 1:1 to dsi private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple DSI devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 38 ++++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index f43d25896f3b..c0141b60e8fd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -268,6 +268,7 @@ struct exynos_dsi_driver_data { }; struct exynos_dsi { + struct exynos_drm_display display; struct mipi_dsi_host dsi_host; struct drm_connector connector; struct drm_encoder *encoder; @@ -1531,10 +1532,6 @@ static struct exynos_drm_display_ops exynos_dsi_display_ops = { .dpms = exynos_dsi_dpms }; -static struct exynos_drm_display exynos_dsi_display = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .ops = &exynos_dsi_display_ops, -}; MODULE_DEVICE_TABLE(of, exynos_dsi_of_match); /* of_* functions will be removed after merge of of_graph patches */ @@ -1640,28 +1637,28 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi) static int exynos_dsi_bind(struct device *dev, struct device *master, void *data) { + struct exynos_drm_display *display = dev_get_drvdata(dev); + struct exynos_dsi *dsi = display->ctx; struct drm_device *drm_dev = data; - struct exynos_dsi *dsi; int ret; - ret = exynos_drm_create_enc_conn(drm_dev, &exynos_dsi_display); + ret = exynos_drm_create_enc_conn(drm_dev, display); if (ret) { DRM_ERROR("Encoder create [%d] failed with %d\n", - exynos_dsi_display.type, ret); + display->type, ret); return ret; } - dsi = exynos_dsi_display.ctx; - return mipi_dsi_host_register(&dsi->dsi_host); } static void exynos_dsi_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_dsi *dsi = exynos_dsi_display.ctx; + struct exynos_drm_display *display = dev_get_drvdata(dev); + struct exynos_dsi *dsi = display->ctx; - exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); + exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF); mipi_dsi_host_unregister(&dsi->dsi_host); } @@ -1673,22 +1670,23 @@ static const struct component_ops exynos_dsi_component_ops = { static int exynos_dsi_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct resource *res; struct exynos_dsi *dsi; int ret; - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, - exynos_dsi_display.type); + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; + + dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD; + dsi->display.ops = &exynos_dsi_display_ops; + + ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CONNECTOR, + dsi->display.type); if (ret) return ret; - dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); - if (!dsi) { - dev_err(&pdev->dev, "failed to allocate dsi object.\n"); - ret = -ENOMEM; - goto err_del_component; - } - /* To be checked as invalid one */ dsi->te_gpio = -ENOENT; -- GitLab From e2d2a1e0a264725fd0a62b91422d33ba2263a341 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 7 Oct 2014 14:01:09 +0200 Subject: [PATCH 6131/9457] drm/exynos: dsi: simplify device pointer evaluation The patch replaces multiple evaluation of device address with local variable. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index c0141b60e8fd..926682c7af27 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1695,9 +1695,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) INIT_LIST_HEAD(&dsi->transfer_list); dsi->dsi_host.ops = &exynos_dsi_ops; - dsi->dsi_host.dev = &pdev->dev; + dsi->dsi_host.dev = dev; - dsi->dev = &pdev->dev; + dsi->dev = dev; dsi->driver_data = exynos_dsi_get_driver_data(pdev); ret = exynos_dsi_parse_dt(dsi); @@ -1706,70 +1706,70 @@ static int exynos_dsi_probe(struct platform_device *pdev) dsi->supplies[0].supply = "vddcore"; dsi->supplies[1].supply = "vddio"; - ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(dsi->supplies), + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies), dsi->supplies); if (ret) { - dev_info(&pdev->dev, "failed to get regulators: %d\n", ret); + dev_info(dev, "failed to get regulators: %d\n", ret); return -EPROBE_DEFER; } - dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk"); + dsi->pll_clk = devm_clk_get(dev, "pll_clk"); if (IS_ERR(dsi->pll_clk)) { - dev_info(&pdev->dev, "failed to get dsi pll input clock\n"); + dev_info(dev, "failed to get dsi pll input clock\n"); ret = PTR_ERR(dsi->pll_clk); goto err_del_component; } - dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk"); + dsi->bus_clk = devm_clk_get(dev, "bus_clk"); if (IS_ERR(dsi->bus_clk)) { - dev_info(&pdev->dev, "failed to get dsi bus clock\n"); + dev_info(dev, "failed to get dsi bus clock\n"); ret = PTR_ERR(dsi->bus_clk); goto err_del_component; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); + dsi->reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(dsi->reg_base)) { - dev_err(&pdev->dev, "failed to remap io region\n"); + dev_err(dev, "failed to remap io region\n"); ret = PTR_ERR(dsi->reg_base); goto err_del_component; } - dsi->phy = devm_phy_get(&pdev->dev, "dsim"); + dsi->phy = devm_phy_get(dev, "dsim"); if (IS_ERR(dsi->phy)) { - dev_info(&pdev->dev, "failed to get dsim phy\n"); + dev_info(dev, "failed to get dsim phy\n"); ret = PTR_ERR(dsi->phy); goto err_del_component; } dsi->irq = platform_get_irq(pdev, 0); if (dsi->irq < 0) { - dev_err(&pdev->dev, "failed to request dsi irq resource\n"); + dev_err(dev, "failed to request dsi irq resource\n"); ret = dsi->irq; goto err_del_component; } irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(&pdev->dev, dsi->irq, NULL, + ret = devm_request_threaded_irq(dev, dsi->irq, NULL, exynos_dsi_irq, IRQF_ONESHOT, - dev_name(&pdev->dev), dsi); + dev_name(dev), dsi); if (ret) { - dev_err(&pdev->dev, "failed to request dsi irq\n"); + dev_err(dev, "failed to request dsi irq\n"); goto err_del_component; } - exynos_dsi_display.ctx = dsi; + dsi->display.ctx = dsi; - platform_set_drvdata(pdev, &exynos_dsi_display); + platform_set_drvdata(pdev, &dsi->display); - ret = component_add(&pdev->dev, &exynos_dsi_component_ops); + ret = component_add(dev, &exynos_dsi_component_ops); if (ret) goto err_del_component; return ret; err_del_component: - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); + exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR); return ret; } -- GitLab From e5169723da013eec25e1d52faa8c5058abe1b23e Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 7 Oct 2014 14:01:10 +0200 Subject: [PATCH 6132/9457] drm/exynos: dsi: remove redundant encoder field The patch removes redundant encoder field from private DSI context. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 926682c7af27..c9d1a00971f1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -271,7 +271,6 @@ struct exynos_dsi { struct exynos_drm_display display; struct mipi_dsi_host dsi_host; struct drm_connector connector; - struct drm_encoder *encoder; struct device_node *panel_node; struct drm_panel *panel; struct device *dev; @@ -1105,7 +1104,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id) static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id) { struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id; - struct drm_encoder *encoder = dsi->encoder; + struct drm_encoder *encoder = dsi->display.encoder; if (dsi->state & DSIM_STATE_ENABLED) exynos_drm_crtc_te_handler(encoder->crtc); @@ -1475,7 +1474,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector) { struct exynos_dsi *dsi = connector_to_dsi(connector); - return dsi->encoder; + return dsi->display.encoder; } static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = { @@ -1491,8 +1490,6 @@ static int exynos_dsi_create_connector(struct exynos_drm_display *display, struct drm_connector *connector = &dsi->connector; int ret; - dsi->encoder = encoder; - connector->polled = DRM_CONNECTOR_POLL_HPD; ret = drm_connector_init(encoder->dev, connector, -- GitLab From 5cd5db80402c91d4b5f4ea5f5cf4be5b21864935 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 7 Oct 2014 14:01:11 +0200 Subject: [PATCH 6133/9457] drm/exynos: dsi: stop using display->ctx pointer The patch replaces accesses to display->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index c9d1a00971f1..5e38d158089b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -304,6 +304,11 @@ struct exynos_dsi { #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host) #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector) +static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d) +{ + return container_of(d, struct exynos_dsi, display); +} + static struct exynos_dsi_driver_data exynos3_dsi_driver_data = { .plltmr_reg = 0x50, .has_freqband = 1, @@ -1397,7 +1402,7 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi) static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode) { - struct exynos_dsi *dsi = display->ctx; + struct exynos_dsi *dsi = display_to_dsi(display); if (dsi->panel) { switch (mode) { @@ -1486,7 +1491,7 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = { static int exynos_dsi_create_connector(struct exynos_drm_display *display, struct drm_encoder *encoder) { - struct exynos_dsi *dsi = display->ctx; + struct exynos_dsi *dsi = display_to_dsi(display); struct drm_connector *connector = &dsi->connector; int ret; @@ -1510,7 +1515,7 @@ static int exynos_dsi_create_connector(struct exynos_drm_display *display, static void exynos_dsi_mode_set(struct exynos_drm_display *display, struct drm_display_mode *mode) { - struct exynos_dsi *dsi = display->ctx; + struct exynos_dsi *dsi = display_to_dsi(display); struct videomode *vm = &dsi->vm; vm->hactive = mode->hdisplay; @@ -1635,7 +1640,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, void *data) { struct exynos_drm_display *display = dev_get_drvdata(dev); - struct exynos_dsi *dsi = display->ctx; + struct exynos_dsi *dsi = display_to_dsi(display); struct drm_device *drm_dev = data; int ret; @@ -1653,7 +1658,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, void *data) { struct exynos_drm_display *display = dev_get_drvdata(dev); - struct exynos_dsi *dsi = display->ctx; + struct exynos_dsi *dsi = display_to_dsi(display); exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF); @@ -1755,8 +1760,6 @@ static int exynos_dsi_probe(struct platform_device *pdev) goto err_del_component; } - dsi->display.ctx = dsi; - platform_set_drvdata(pdev, &dsi->display); ret = component_add(dev, &exynos_dsi_component_ops); -- GitLab From ff9c87ce9b9d10d50f42127c0753654af6332157 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:35 +0000 Subject: [PATCH 6134/9457] drm/exynos: remove uneeded declaration of struct dma_iommu_mapping It is not even used in this header anymore. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_iommu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h index 72376d41c512..35d25889b476 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h +++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h @@ -40,7 +40,6 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) #else -struct dma_iommu_mapping; static inline int drm_create_iommu_mapping(struct drm_device *drm_dev) { return 0; -- GitLab From b5b1a4bb1598e3c11d5c74adfcab2055954ebee7 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:36 +0000 Subject: [PATCH 6135/9457] drm/exynos: remove extra declaration of struct exynos_drm_manager The struct is defined in the same file, declare it here is just unnecessary. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_encoder.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index b7a1620a7e79..26305d8dd93a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h @@ -14,8 +14,6 @@ #ifndef _EXYNOS_DRM_ENCODER_H_ #define _EXYNOS_DRM_ENCODER_H_ -struct exynos_drm_manager; - void exynos_drm_encoder_setup(struct drm_device *dev); struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_display *mgr, -- GitLab From f859d6e8594e0a9e11b76407b7f4834f612f0c6d Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:37 +0000 Subject: [PATCH 6136/9457] drm/exynos: remove extra declaration of struct exynos_overlay The struct is defined in the same file, declare it here is just unnecessary Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 3c81c4b60399..3905e309e782 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -37,7 +37,6 @@ #define wait_for(COND, MS) _wait_for(COND, MS) struct drm_device; -struct exynos_drm_overlay; struct drm_connector; /* This enumerates device type. */ -- GitLab From d2c1bba3f6fca60c924996c51d7453c5ddb5cedd Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:38 +0000 Subject: [PATCH 6137/9457] drm/exynos: Replace repeated declaration by include Re-declare struct is not a good practice, let's use the original drm declarations. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 3905e309e782..780698139e67 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -15,6 +15,7 @@ #ifndef _EXYNOS_DRM_DRV_H_ #define _EXYNOS_DRM_DRV_H_ +#include #include #define MAX_CRTC 3 @@ -36,9 +37,6 @@ #define wait_for(COND, MS) _wait_for(COND, MS) -struct drm_device; -struct drm_connector; - /* This enumerates device type. */ enum exynos_drm_device_type { EXYNOS_DEVICE_TYPE_NONE, -- GitLab From cc2d861c5f3421a1b0ba498cb9f0ecb5b3a3eb1c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 13 Nov 2014 17:24:06 +0900 Subject: [PATCH 6138/9457] drm/exynos: Replace repeated declarations by #include "exynos_drm_drv.h" Re-declare struct is not a good practice, let's use the original drm and exynos declarations. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_crtc.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 690dcddab725..e353d353836f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -15,10 +15,7 @@ #ifndef _EXYNOS_DRM_CRTC_H_ #define _EXYNOS_DRM_CRTC_H_ -struct drm_device; -struct drm_crtc; -struct exynos_drm_manager; -struct exynos_drm_overlay; +#include "exynos_drm_drv.h" int exynos_drm_crtc_create(struct exynos_drm_manager *manager); int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); -- GitLab From 5d0e6fec7f012a9518ff042fd6102dda6c79089e Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:40 +0000 Subject: [PATCH 6139/9457] drm/exynos: remove unused wait_for macro This is a leftover, all code using this macro have been removed/ changed already. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 780698139e67..9e4a7e11b6c8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -23,20 +23,6 @@ #define MAX_FB_BUFFER 4 #define DEFAULT_ZPOS -1 -#define _wait_for(COND, MS) ({ \ - unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ - int ret__ = 0; \ - while (!(COND)) { \ - if (time_after(jiffies, timeout__)) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - } \ - ret__; \ -}) - -#define wait_for(COND, MS) _wait_for(COND, MS) - /* This enumerates device type. */ enum exynos_drm_device_type { EXYNOS_DEVICE_TYPE_NONE, -- GitLab From 4a5827fbc26edfce0d8d0839fdf22cd436f0ae5b Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 13 Nov 2014 17:25:53 +0900 Subject: [PATCH 6140/9457] drm/exynos: Save up space using bool var as bitfields Save a few bytes by compiling them all in the same byte. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 9e4a7e11b6c8..f77e6aafd3ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -66,10 +66,10 @@ enum exynos_drm_output_type { * @dma_addr: array of bus(accessed by dma) address to the memory region * allocated for a overlay. * @zpos: order of overlay layer(z position). - * @default_win: a window to be enabled. - * @color_key: color key on or off. * @index_color: if using color key feature then this value would be used * as index color. + * @default_win: a window to be enabled. + * @color_key: color key on or off. * @local_path: in case of lcd type, local path mode on or off. * @transparency: transparency on or off. * @activated: activated or not. @@ -97,13 +97,13 @@ struct exynos_drm_overlay { uint32_t pixel_format; dma_addr_t dma_addr[MAX_FB_BUFFER]; int zpos; - - bool default_win; - bool color_key; unsigned int index_color; - bool local_path; - bool transparency; - bool activated; + + bool default_win:1; + bool color_key:1; + bool local_path:1; + bool transparency:1; + bool activated:1; }; /* -- GitLab From 60cb85862e7c12eff855fece28034f7cd3fa6edd Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:42 +0000 Subject: [PATCH 6141/9457] drm/exynos: update documentation to reflect code changes Description of the @create_connector callback was missing, and the @manager was no longer needed. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index f77e6aafd3ec..e762cbb67aea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -110,6 +110,7 @@ struct exynos_drm_overlay { * Exynos DRM Display Structure. * - this structure is common to analog tv, digital tv and lcd panel. * + * @create_connector: initialize and register a new connector * @remove: cleans up the display for removal * @mode_fixup: fix mode data comparing to hw specific display mode. * @mode_set: convert drm_display_mode to hw specific display mode and @@ -262,8 +263,6 @@ struct exynos_drm_private { * @dev: pointer to device object for subdrv device driver. * @drm_dev: pointer to drm_device and this pointer would be set * when sub driver calls exynos_drm_subdrv_register(). - * @manager: subdrv has its own manager to control a hardware appropriately - * and we can access a hardware drawing on this manager. * @probe: this callback would be called by exynos drm driver after * subdrv is registered to it. * @remove: this callback is used to release resources created -- GitLab From 975588477220cfb32375ace1caafbdbbb9d75e70 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 31 Oct 2014 14:17:43 +0000 Subject: [PATCH 6142/9457] drm/exynos: remove leftover hdmi function declarations They are not implemented anywhere, so wipe them out. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index e762cbb67aea..262a4590ddb2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -294,17 +294,6 @@ int exynos_drm_device_subdrv_remove(struct drm_device *dev); int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); -/* - * this function registers exynos drm hdmi platform device. It ensures only one - * instance of the device is created. - */ -int exynos_platform_device_hdmi_register(void); - -/* - * this function unregisters exynos drm hdmi platform device if it exists. - */ -void exynos_platform_device_hdmi_unregister(void); - #ifdef CONFIG_DRM_EXYNOS_IPP int exynos_platform_device_ipp_register(void); void exynos_platform_device_ipp_unregister(void); -- GitLab From b128aefe0b0409c77123586e5243bee415f84f5b Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Wed, 12 Nov 2014 15:12:10 +0530 Subject: [PATCH 6143/9457] drm/exynos: dp: Remove support for unused dptx-phy Now that we have moved to generic phy based bindings, we don't need to have any code related to older dptx-phy. Nobody is using this dptx-phy anymore, so removing the same. Signed-off-by: Vivek Gautam Acked-by: Jingoo Han Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_dp_core.c | 74 ++++++------------------- drivers/gpu/drm/exynos/exynos_dp_core.h | 2 - 2 files changed, 17 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 6adb1e5cfb08..ed818b9a615a 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_on(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg |= dp->enable_mask; - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_off(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg &= ~(dp->enable_mask); - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_poweron(struct exynos_drm_display *display) @@ -1210,44 +1196,6 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) return dp_video_config; } -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) -{ - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); - u32 phy_base; - int ret = 0; - - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); - if (!dp_phy_node) { - dp->phy = devm_phy_get(dp->dev, "dp"); - return PTR_ERR_OR_ZERO(dp->phy); - } - - if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", - &dp->enable_mask)) { - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - dp->phy_addr = ioremap(phy_base, SZ_4); - if (!dp->phy_addr) { - dev_err(dp->dev, "failed to ioremap dp-phy\n"); - ret = -ENOMEM; - goto err; - } - -err: - of_node_put(dp_phy_node); - - return ret; -} - static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) { int ret; @@ -1277,9 +1225,21 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) if (IS_ERR(dp->video_info)) return PTR_ERR(dp->video_info); - ret = exynos_dp_dt_parse_phydata(dp); - if (ret) - return ret; + dp->phy = devm_phy_get(dp->dev, "dp"); + if (IS_ERR(dp->phy)) { + dev_err(dp->dev, "no DP phy configured\n"); + ret = PTR_ERR(dp->phy); + if (ret) { + /* + * phy itself is not enabled, so we can move forward + * assigning NULL to phy pointer. + */ + if (ret == -ENOSYS || ret == -ENODEV) + dp->phy = NULL; + else + return ret; + } + } if (!dp->panel) { ret = exynos_dp_dt_parse_panel(dp); diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h index a1aee6931bd7..6426201667bc 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.h +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h @@ -153,8 +153,6 @@ struct exynos_dp_device { struct clk *clock; unsigned int irq; void __iomem *reg_base; - void __iomem *phy_addr; - unsigned int enable_mask; struct video_info *video_info; struct link_train link_train; -- GitLab From 4bc6d6445e0c0b724d4232fcc1f127bde3a4ddbd Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Fri, 7 Nov 2014 15:12:24 +0900 Subject: [PATCH 6144/9457] drm/exynos: dsi: support Exynos4415 SoC This patch supports Exynos4415 SoC. Signed-off-by: YoungJun Cho Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- Documentation/devicetree/bindings/video/exynos_dsim.txt | 1 + drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt index e74243b4b317..ca2b4aacd9af 100644 --- a/Documentation/devicetree/bindings/video/exynos_dsim.txt +++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt @@ -4,6 +4,7 @@ Required properties: - compatible: value should be one of the following "samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */ "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */ + "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */ "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */ - reg: physical base address and length of the registers set for the device - interrupts: should contain DSI interrupt diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 5e38d158089b..e0e8c388b107 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -321,6 +321,11 @@ static struct exynos_dsi_driver_data exynos4_dsi_driver_data = { .has_clklane_stop = 1, }; +static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = { + .plltmr_reg = 0x58, + .has_clklane_stop = 1, +}; + static struct exynos_dsi_driver_data exynos5_dsi_driver_data = { .plltmr_reg = 0x58, }; @@ -330,6 +335,8 @@ static struct of_device_id exynos_dsi_of_match[] = { .data = &exynos3_dsi_driver_data }, { .compatible = "samsung,exynos4210-mipi-dsi", .data = &exynos4_dsi_driver_data }, + { .compatible = "samsung,exynos4415-mipi-dsi", + .data = &exynos4415_dsi_driver_data }, { .compatible = "samsung,exynos5410-mipi-dsi", .data = &exynos5_dsi_driver_data }, { } -- GitLab From dcb622aa882b1108c005ebf629014acbf22690e3 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Fri, 7 Nov 2014 15:12:25 +0900 Subject: [PATCH 6145/9457] drm/exynos: fimd: support Exynos4415 SoC This patch supports Exynos4415 SoC. Signed-off-by: YoungJun Cho Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- .../devicetree/bindings/video/samsung-fimd.txt | 1 + drivers/gpu/drm/exynos/exynos_drm_fimd.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt b/Documentation/devicetree/bindings/video/samsung-fimd.txt index 4e6c77c85546..cf1af6371021 100644 --- a/Documentation/devicetree/bindings/video/samsung-fimd.txt +++ b/Documentation/devicetree/bindings/video/samsung-fimd.txt @@ -11,6 +11,7 @@ Required properties: "samsung,s5pv210-fimd"; /* for S5PV210 SoC */ "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */ "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */ + "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */ "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */ - reg: physical base address and length of the FIMD registers set. diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 085b066a9993..5dfbbdba9591 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -120,6 +120,15 @@ static struct fimd_driver_data exynos4_fimd_driver_data = { .has_shadowcon = 1, }; +static struct fimd_driver_data exynos4415_fimd_driver_data = { + .timing_base = 0x20000, + .lcdblk_offset = 0x210, + .lcdblk_vt_shift = 10, + .lcdblk_bypass_shift = 1, + .has_shadowcon = 1, + .has_vidoutcon = 1, +}; + static struct fimd_driver_data exynos5_fimd_driver_data = { .timing_base = 0x20000, .lcdblk_offset = 0x214, @@ -180,6 +189,8 @@ static const struct of_device_id fimd_driver_dt_match[] = { .data = &exynos3_fimd_driver_data }, { .compatible = "samsung,exynos4210-fimd", .data = &exynos4_fimd_driver_data }, + { .compatible = "samsung,exynos4415-fimd", + .data = &exynos4415_fimd_driver_data }, { .compatible = "samsung,exynos5250-fimd", .data = &exynos5_fimd_driver_data }, {}, -- GitLab From bd953de94393ef2a00e893aa948cc7c4cb190d00 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 1 Oct 2014 15:19:07 +0900 Subject: [PATCH 6146/9457] drm/exynos: fimd: remove unnecessary waiting vblank routine The exynos_drm_crtc_dpms() waits until pended page flip queue is empty, calls the drm_vblank_off() then calls manager->ops->dpms() when mode is DRM_MODE_DPMS_OFF. The fimd_dpms() is one of manager->ops->dpms()s and finally calls fimd_window_suspend(). But there is no active window and vblank is already off when it is called. So addtional waiting vblank is not necessary any more. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 5dfbbdba9591..1f46c89f0e08 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -814,7 +814,6 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr) if (win_data->enabled) fimd_win_disable(mgr, i); } - fimd_wait_for_vblank(mgr); } static void fimd_window_resume(struct exynos_drm_manager *mgr) -- GitLab From b301ae24bb22cb6cf762b174426105c85621b1b7 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 1 Oct 2014 15:19:10 +0900 Subject: [PATCH 6147/9457] drm/exynos: fimd: move handle vblank position in TE handler For providing VBLANK information, drm_handle_vblank() should be called properly, but it is blocked by wait_vsync_event condition which is set by manager_ops->wait_for_vblank(). So moves it out from wait_vsync_event routine. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Acked-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 1f46c89f0e08..7593f629c9fb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -982,10 +982,10 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr) if (atomic_read(&ctx->wait_vsync_event)) { atomic_set(&ctx->wait_vsync_event, 0); wake_up(&ctx->wait_vsync_queue); - - if (!atomic_read(&ctx->triggering)) - drm_handle_vblank(ctx->drm_dev, ctx->pipe); } + + if (!atomic_read(&ctx->triggering)) + drm_handle_vblank(ctx->drm_dev, ctx->pipe); } static struct exynos_drm_manager_ops fimd_manager_ops = { -- GitLab From d41bb38f228d98a2e411d59be14a2aee876d8db1 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 1 Oct 2014 15:19:13 +0900 Subject: [PATCH 6148/9457] drm/exynos: dsi: move DSIM_STATE_ENABLED set position The command mode panel should draw image earlier than the display on command execution to prevent showing garbage GRAM screen data. So should set dsi->state as DSIM_STATE_ENABLED between calling exynos_dsi_set_display_enable() and drm_panel_enable() to transmit image data before executing display on command. And moves the display on command execution routine from prepare() to enable() in drm_panel_funcs also. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index e0e8c388b107..44461aa35ccd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1381,16 +1381,17 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi) exynos_dsi_set_display_mode(dsi); exynos_dsi_set_display_enable(dsi, true); + dsi->state |= DSIM_STATE_ENABLED; + ret = drm_panel_enable(dsi->panel); if (ret < 0) { + dsi->state &= ~DSIM_STATE_ENABLED; exynos_dsi_set_display_enable(dsi, false); drm_panel_unprepare(dsi->panel); exynos_dsi_poweroff(dsi); return ret; } - dsi->state |= DSIM_STATE_ENABLED; - return 0; } -- GitLab From 030794a368946b98a8252d3172f5f2a1b0e4fb0e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 7 Nov 2014 14:53:58 +0100 Subject: [PATCH 6149/9457] drm/exynos: Fix DSI resuming fail because power domain being off During system resume from suspend to RAM the Exynos DRM driver forced CRTC mode thus turning display on (DPMS_ON). This lead to runtime resuming of DSI which failed because whole LCD power domain was off and it was not allowed to turn on because of system resume in progress. Forcing mode should not be needed and removing it solves this particular problem. This necessary fix for following scenario reproduced on Exynos DRM: 1. Power domain is off before suspending the system. 2. System is suspended to RAM. 3. Resuming starts. The Exynos DRM driver resume callback is called. 4. The Exynos DRM driver calls drm_helper_resume_force_mode() which turns on the screen by calling exynos_dsi_dpms with DRM_MODE_DPMS_ON. 5. The Exynos DSI driver calls pm_runtime_get. The driver runtime resumes and this should turn LCD power domain on. 6. Unfortunately the domain cannot be turned on because system resume is in progress and genpd->prepared_count is positive. Steps to reproduce: 1. Add runtime PM to Exynos DSI driver. 2. Build Exynos DRM/FB without FRAMEBUFFER_CONSOLE. 3. Enable the connector and screen (e.g. with modeset-vsync). 4. echo 3 > /sys/devices/platform/exynos-drm/graphics/fb0/blank 5. echo mem > /sys/power/state 6. Resume. [ 77.712469] PM: early resume of devices complete after 3.854 msecs [ 77.712739] exynos-dsi 11c80000.dsi: pm_genpd_resume() [ 77.712758] exynos4-fimc 11800000.fimc: pm_genpd_resume() [ 77.712774] exynos4-fimc 11810000.fimc: pm_genpd_resume() [ 77.712787] exynos-drm-fimc 11820000.fimc: pm_genpd_resume() [ 77.712802] exynos-drm-fimc 11830000.fimc: pm_genpd_resume() [ 77.712815] s5p-mipi-csis 11880000.csis: pm_genpd_resume() [ 77.712829] s5p-mipi-csis 11890000.csis: pm_genpd_resume() [ 77.712843] exynos-fimc-lite 12390000.fimc-lite: pm_genpd_resume() [ 77.712856] exynos-fimc-lite 123a0000.fimc-lite: pm_genpd_resume() [ 77.713788] exynos4-fb 11c00000.fimd: pm_genpd_resume() [ 77.713912] wake disabled for irq 184 [ 77.713923] wake disabled for irq 185 [ 77.714082] wake disabled for irq 173 [ 77.715676] wake disabled for irq 176 [ 77.718540] exynos4-fb 11c00000.fimd: pm_genpd_runtime_resume() [ 77.718567] exynos4-fb 11c00000.fimd: state restore latency exceeded, new value 1708 ns [ 77.718636] exynos-dsi 11c80000.dsi: pm_genpd_runtime_resume() [ 77.892366] exynos-dsi 11c80000.dsi: PLL failed to stabilize [ 77.892377] exynos-dsi 11c80000.dsi: failed to configure DSI PLL [ 78.192168] exynos-dsi 11c80000.dsi: timeout waiting for reset [ 78.211578] exynos-dsi 11c80000.dsi: waiting for bus lanes timed out [ 78.307173] exynos-dsi 11c80000.dsi: xfer timed out: d1 00 (null) [ 78.307190] panel_s6e8aa0 11c80000.dsi.0: error -110 reading dcs seq(0xd1) [ 78.307199] panel_s6e8aa0 11c80000.dsi.0: read id failed Signed-off-by: Krzysztof Kozlowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 8aee62902ec6..eab12f084709 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -194,8 +194,6 @@ static int exynos_drm_resume(struct drm_device *dev) } drm_modeset_unlock_all(dev); - drm_helper_resume_force_mode(dev); - return 0; } -- GitLab From 3c3c9c1d904dca30f89882b97822fdf025b115c9 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 14 Nov 2014 11:36:02 +0900 Subject: [PATCH 6150/9457] drm/exynos: add has_vtsel flag The exynos fimd provides video type selection bits from system register but exynos3 series don't has it, so needs has_vtsel flag and we can distinguish whether set video type selection bits. Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 7593f629c9fb..0673a39a5b03 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -96,6 +96,7 @@ struct fimd_driver_data { unsigned int has_clksel:1; unsigned int has_limited_fmt:1; unsigned int has_vidoutcon:1; + unsigned int has_vtsel:1; }; static struct fimd_driver_data s3c64xx_fimd_driver_data = { @@ -118,6 +119,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data = { .lcdblk_vt_shift = 10, .lcdblk_bypass_shift = 1, .has_shadowcon = 1, + .has_vtsel = 1, }; static struct fimd_driver_data exynos4415_fimd_driver_data = { @@ -127,6 +129,7 @@ static struct fimd_driver_data exynos4415_fimd_driver_data = { .lcdblk_bypass_shift = 1, .has_shadowcon = 1, .has_vidoutcon = 1, + .has_vtsel = 1, }; static struct fimd_driver_data exynos5_fimd_driver_data = { @@ -136,6 +139,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { .lcdblk_bypass_shift = 15, .has_shadowcon = 1, .has_vidoutcon = 1, + .has_vtsel = 1, }; struct fimd_win_data { @@ -354,7 +358,8 @@ static void fimd_commit(struct exynos_drm_manager *mgr) writel(0, timing_base + I80IFCONFBx(0)); /* set video type selection to I80 interface */ - if (ctx->sysreg && regmap_update_bits(ctx->sysreg, + if (driver_data->has_vtsel && ctx->sysreg && + regmap_update_bits(ctx->sysreg, driver_data->lcdblk_offset, 0x3 << driver_data->lcdblk_vt_shift, 0x1 << driver_data->lcdblk_vt_shift)) { -- GitLab From 9b67eb7365725ed00dde4714d71d4afe205329b2 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 17 Nov 2014 22:00:08 +0900 Subject: [PATCH 6151/9457] drm/exynos: move triggering checking It's better to be checking whether triggerring in fimd_trigger function. Also it will return if in triggerring on fimd_te_handler, then it can't execute remain codes. Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 0673a39a5b03..ec2d1702b93b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -949,6 +949,13 @@ static void fimd_trigger(struct device *dev) void *timing_base = ctx->regs + driver_data->timing_base; u32 reg; + /* + * Skips to trigger if in triggering state, because multiple triggering + * requests can cause panel reset. + */ + if (atomic_read(&ctx->triggering)) + return; + atomic_set(&ctx->triggering, 1); reg = readl(ctx->regs + VIDINTCON0); @@ -969,13 +976,6 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr) if (ctx->pipe < 0 || !ctx->drm_dev) return; - /* - * Skips to trigger if in triggering state, because multiple triggering - * requests can cause panel reset. - */ - if (atomic_read(&ctx->triggering)) - return; - /* * If there is a page flip request, triggers and handles the page flip * event so that current fb can be updated into panel GRAM. -- GitLab From 74944a58f9def188d506d3eef19fd34f293219f7 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:09 +0900 Subject: [PATCH 6152/9457] drm/exynos: fimd: move shadow unprotection position The C#_EN_F in SHADOWCON register is updated per frame. So it should be protected by fimd_shadow_protect_win(). Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ec2d1702b93b..77ba961e1ddd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -751,15 +751,15 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) val |= WINCONx_ENWIN; writel(val, ctx->regs + WINCON(win)); - /* Enable DMA channel and unprotect windows */ - fimd_shadow_protect_win(ctx, win, false); - if (ctx->driver_data->has_shadowcon) { val = readl(ctx->regs + SHADOWCON); val |= SHADOWCON_CHx_ENABLE(win); writel(val, ctx->regs + SHADOWCON); } + /* Enable DMA channel and unprotect windows */ + fimd_shadow_protect_win(ctx, win, false); + win_data->enabled = true; if (ctx->i80_if) -- GitLab From f181a543c76fdcf240ef39d24520141070701bdc Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:10 +0900 Subject: [PATCH 6153/9457] drm/exynos: fimd: add fimd_enable_video_output() to cleanup This bit is used for video output and logic signal control. So it is better for readability. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 77ba961e1ddd..5cfd25147374 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -229,6 +229,19 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) DRM_DEBUG_KMS("vblank wait timed out.\n"); } +static void fimd_enable_video_output(struct fimd_context *ctx, int win, + bool enable) +{ + u32 val = readl(ctx->regs + WINCON(win)); + + if (enable) + val |= WINCONx_ENWIN; + else + val &= ~WINCONx_ENWIN; + + writel(val, ctx->regs + WINCON(win)); +} + static void fimd_clear_channel(struct exynos_drm_manager *mgr) { struct fimd_context *ctx = mgr->ctx; @@ -241,9 +254,7 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) u32 val = readl(ctx->regs + WINCON(win)); if (val & WINCONx_ENWIN) { - /* wincon */ - val &= ~WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); + fimd_enable_video_output(ctx, win, false); /* unprotect windows */ if (ctx->driver_data->has_shadowcon) { @@ -746,10 +757,7 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) if (win != 0) fimd_win_set_colkey(ctx, win); - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val |= WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); + fimd_enable_video_output(ctx, win, true); if (ctx->driver_data->has_shadowcon) { val = readl(ctx->regs + SHADOWCON); @@ -790,10 +798,7 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) /* protect windows */ fimd_shadow_protect_win(ctx, win, true); - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val &= ~WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); + fimd_enable_video_output(ctx, win, false); /* unprotect windows */ if (ctx->driver_data->has_shadowcon) { -- GitLab From 999d8b31fac3629b8179d7a40b7930deedadeb99 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:11 +0900 Subject: [PATCH 6154/9457] drm/exynos: fimd: add fimd_enable_shadow_channel_path() to cleanup This function is valid only the SoC has SHADOWCON register and it should be used together with fimd_enable_video_output() to match the ENWIN_F bit in WINCON# and C#_EN_F bit in SHADOWCON. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 40 +++++++++++++----------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 5cfd25147374..fd7b46959903 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -242,6 +242,19 @@ static void fimd_enable_video_output(struct fimd_context *ctx, int win, writel(val, ctx->regs + WINCON(win)); } +static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, + bool enable) +{ + u32 val = readl(ctx->regs + SHADOWCON); + + if (enable) + val |= SHADOWCON_CHx_ENABLE(win); + else + val &= ~SHADOWCON_CHx_ENABLE(win); + + writel(val, ctx->regs + SHADOWCON); +} + static void fimd_clear_channel(struct exynos_drm_manager *mgr) { struct fimd_context *ctx = mgr->ctx; @@ -256,12 +269,10 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) if (val & WINCONx_ENWIN) { fimd_enable_video_output(ctx, win, false); - /* unprotect windows */ - if (ctx->driver_data->has_shadowcon) { - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_CHx_ENABLE(win); - writel(val, ctx->regs + SHADOWCON); - } + if (ctx->driver_data->has_shadowcon) + fimd_enable_shadow_channel_path(ctx, win, + false); + ch_enabled = 1; } } @@ -759,11 +770,8 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) fimd_enable_video_output(ctx, win, true); - if (ctx->driver_data->has_shadowcon) { - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_CHx_ENABLE(win); - writel(val, ctx->regs + SHADOWCON); - } + if (ctx->driver_data->has_shadowcon) + fimd_enable_shadow_channel_path(ctx, win, true); /* Enable DMA channel and unprotect windows */ fimd_shadow_protect_win(ctx, win, false); @@ -779,7 +787,6 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) struct fimd_context *ctx = mgr->ctx; struct fimd_win_data *win_data; int win = zpos; - u32 val; if (win == DEFAULT_ZPOS) win = ctx->default_win; @@ -800,13 +807,10 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) fimd_enable_video_output(ctx, win, false); - /* unprotect windows */ - if (ctx->driver_data->has_shadowcon) { - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_CHx_ENABLE(win); - writel(val, ctx->regs + SHADOWCON); - } + if (ctx->driver_data->has_shadowcon) + fimd_enable_shadow_channel_path(ctx, win, false); + /* unprotect windows */ fimd_shadow_protect_win(ctx, win, false); win_data->enabled = false; -- GitLab From 1c905d9508932ed85eee5469519aedc2d820458e Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:12 +0900 Subject: [PATCH 6155/9457] drm/exynos: fimd: modify I80 i/f irq relevant routine For the I80 interface, the video interrupt pending register(VIDINTCON1) should be handled in fimd_irq_handler() and the video interrupt control register(VIDINTCON0) should be handled in fimd_enable_vblank() and fimd_disable_vblank() like RGB interface. So this patch moves each set / unset routines into proper positions. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 53 ++++++++++++------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index fd7b46959903..3c632370e983 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -469,12 +469,19 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) val = readl(ctx->regs + VIDINTCON0); val |= VIDINTCON0_INT_ENABLE; - val |= VIDINTCON0_INT_FRAME; - val &= ~VIDINTCON0_FRAMESEL0_MASK; - val |= VIDINTCON0_FRAMESEL0_VSYNC; - val &= ~VIDINTCON0_FRAMESEL1_MASK; - val |= VIDINTCON0_FRAMESEL1_NONE; + if (ctx->i80_if) { + val |= VIDINTCON0_INT_I80IFDONE; + val |= VIDINTCON0_INT_SYSMAINCON; + val &= ~VIDINTCON0_INT_SYSSUBCON; + } else { + val |= VIDINTCON0_INT_FRAME; + + val &= ~VIDINTCON0_FRAMESEL0_MASK; + val |= VIDINTCON0_FRAMESEL0_VSYNC; + val &= ~VIDINTCON0_FRAMESEL1_MASK; + val |= VIDINTCON0_FRAMESEL1_NONE; + } writel(val, ctx->regs + VIDINTCON0); } @@ -493,9 +500,15 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) if (test_and_clear_bit(0, &ctx->irq_flags)) { val = readl(ctx->regs + VIDINTCON0); - val &= ~VIDINTCON0_INT_FRAME; val &= ~VIDINTCON0_INT_ENABLE; + if (ctx->i80_if) { + val &= ~VIDINTCON0_INT_I80IFDONE; + val &= ~VIDINTCON0_INT_SYSMAINCON; + val &= ~VIDINTCON0_INT_SYSSUBCON; + } else + val &= ~VIDINTCON0_INT_FRAME; + writel(val, ctx->regs + VIDINTCON0); } } @@ -959,19 +972,15 @@ static void fimd_trigger(struct device *dev) u32 reg; /* - * Skips to trigger if in triggering state, because multiple triggering - * requests can cause panel reset. - */ + * Skips triggering if in triggering state, because multiple triggering + * requests can cause panel reset. + */ if (atomic_read(&ctx->triggering)) return; + /* Enters triggering mode */ atomic_set(&ctx->triggering, 1); - reg = readl(ctx->regs + VIDINTCON0); - reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE | - VIDINTCON0_INT_SYSMAINCON); - writel(reg, ctx->regs + VIDINTCON0); - reg = readl(timing_base + TRIGCON); reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE); writel(reg, timing_base + TRIGCON); @@ -1036,21 +1045,13 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) if (ctx->pipe < 0 || !ctx->drm_dev) goto out; - if (ctx->i80_if) { - /* unset I80 frame done interrupt */ - val = readl(ctx->regs + VIDINTCON0); - val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON); - writel(val, ctx->regs + VIDINTCON0); + drm_handle_vblank(ctx->drm_dev, ctx->pipe); + exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); - /* exit triggering mode */ + if (ctx->i80_if) { + /* Exits triggering mode */ atomic_set(&ctx->triggering, 0); - - drm_handle_vblank(ctx->drm_dev, ctx->pipe); - exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); } else { - drm_handle_vblank(ctx->drm_dev, ctx->pipe); - exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); - /* set wait vsync event to zero and wake up queue. */ if (atomic_read(&ctx->wait_vsync_event)) { atomic_set(&ctx->wait_vsync_event, 0); -- GitLab From 87ab85b3ccbc266154268407f85777a74f8bf820 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:13 +0900 Subject: [PATCH 6156/9457] drm/exynos: fimd: add triggering unset routine in fimd_trigger() There is a case like set config which requires triggering but vblank is not enabled yet. So triggering unset routine is required to exit from triggering mode. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 3c632370e983..e488b80bef5e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -984,6 +984,13 @@ static void fimd_trigger(struct device *dev) reg = readl(timing_base + TRIGCON); reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE); writel(reg, timing_base + TRIGCON); + + /* + * Exits triggering mode if vblank is not enabled yet, because when the + * VIDINTCON0 register is not set, it can not exit from triggering mode. + */ + if (!test_bit(0, &ctx->irq_flags)) + atomic_set(&ctx->triggering, 0); } static void fimd_te_handler(struct exynos_drm_manager *mgr) -- GitLab From adf67abff09110b527431512bf05461a60ef2a72 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 17 Nov 2014 22:00:14 +0900 Subject: [PATCH 6157/9457] drm/exynos: use irq_flags instead of triggering The drm_handle_vblank should be called whenever be vsync, te interrupt means vsync on i80 interface. Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index e488b80bef5e..a8ab3ecb202e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1014,7 +1014,7 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr) wake_up(&ctx->wait_vsync_queue); } - if (!atomic_read(&ctx->triggering)) + if (test_bit(0, &ctx->irq_flags)) drm_handle_vblank(ctx->drm_dev, ctx->pipe); } @@ -1052,13 +1052,15 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) if (ctx->pipe < 0 || !ctx->drm_dev) goto out; - drm_handle_vblank(ctx->drm_dev, ctx->pipe); - exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); - if (ctx->i80_if) { + exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); + /* Exits triggering mode */ atomic_set(&ctx->triggering, 0); } else { + drm_handle_vblank(ctx->drm_dev, ctx->pipe); + exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); + /* set wait vsync event to zero and wake up queue. */ if (atomic_read(&ctx->wait_vsync_event)) { atomic_set(&ctx->wait_vsync_event, 0); -- GitLab From ecb84157b5716f80e6569cd379f3bf560116a803 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:15 +0900 Subject: [PATCH 6158/9457] drm/exynos: dsi: move TE irq handler registration position The drm_helper_hpd_irq_event() does dpms control and the panel is initialized and displayed on by it. So the exynos_dsi_te_irq_handler() should be registered beforehand. Signed-off-by: YoungJun Cho Acked-by: Inki Dae Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 44461aa35ccd..156a6389172a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1207,9 +1207,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, dsi->mode_flags = device->mode_flags; dsi->panel_node = device->dev.of_node; - if (dsi->connector.dev) - drm_helper_hpd_irq_event(dsi->connector.dev); - /* * This is a temporary solution and should be made by more generic way. * @@ -1223,6 +1220,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, return ret; } + if (dsi->connector.dev) + drm_helper_hpd_irq_event(dsi->connector.dev); + return 0; } -- GitLab From 0cef83a5fd3aa72ed7bd8661042cd8405062fcef Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 17 Nov 2014 22:00:16 +0900 Subject: [PATCH 6159/9457] drm/exynos: dsi: set TE GPIO IRQ status as IRQ_NOAUTOEN The exynos_dsi_te_irq_handler() works only dsi(DPMS) is on. So it is enough to enable and disable TE GPIO IRQ in exynos_dsi_enable(disable)_irq() like DSI IRQ. Signed-off-by: YoungJun Cho Acked-by: Inki Dae a Acked-by: Kyungmin Park Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 156a6389172a..05fe93dc57a8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1155,6 +1155,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi) { int ret; + int te_gpio_irq; dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0); if (!gpio_is_valid(dsi->te_gpio)) { @@ -1169,14 +1170,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi) goto out; } - /* - * This TE GPIO IRQ should not be set to IRQ_NOAUTOEN, because panel - * calls drm_panel_init() first then calls mipi_dsi_attach() in probe(). - * It means that te_gpio is invalid when exynos_dsi_enable_irq() is - * called by drm_panel_init() before panel is attached. - */ - ret = request_threaded_irq(gpio_to_irq(dsi->te_gpio), - exynos_dsi_te_irq_handler, NULL, + te_gpio_irq = gpio_to_irq(dsi->te_gpio); + + irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN); + ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL, IRQF_TRIGGER_RISING, "TE", dsi); if (ret) { dev_err(dsi->dev, "request interrupt failed with %d\n", ret); -- GitLab From 8103ef1b5f471fe5e50cd4e1fc17cf3be4682d79 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 24 Nov 2014 14:12:46 +0900 Subject: [PATCH 6160/9457] drm/exynos/mixer: embed manager into private context exynos_drm_manager is used by internal Exynos DRM framework for representing crtc. As it should be mapped 1:1 to fimd private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple mixer devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 98 ++++++++++++++------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index a41c84ee3a2d..1b1fd82ec262 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -40,8 +40,6 @@ #include "exynos_drm_iommu.h" #include "exynos_mixer.h" -#define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev)) - #define MIXER_WIN_NR 3 #define MIXER_DEFAULT_WIN 0 @@ -86,6 +84,7 @@ enum mixer_version_id { }; struct mixer_context { + struct exynos_drm_manager manager; struct platform_device *pdev; struct device *dev; struct drm_device *drm_dev; @@ -1187,11 +1186,6 @@ static struct exynos_drm_manager_ops mixer_manager_ops = { .win_disable = mixer_win_disable, }; -static struct exynos_drm_manager mixer_manager = { - .type = EXYNOS_DISPLAY_TYPE_HDMI, - .ops = &mixer_manager_ops, -}; - static struct mixer_drv_data exynos5420_mxr_drv_data = { .version = MXR_VER_128_0_0_184, .is_vp_enabled = 0, @@ -1249,48 +1243,17 @@ MODULE_DEVICE_TABLE(of, mixer_match_types); static int mixer_bind(struct device *dev, struct device *manager, void *data) { - struct platform_device *pdev = to_platform_device(dev); + struct mixer_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; - struct mixer_context *ctx; - struct mixer_drv_data *drv; int ret; - dev_info(dev, "probe start\n"); - - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - DRM_ERROR("failed to alloc mixer context.\n"); - return -ENOMEM; - } - - mutex_init(&ctx->mixer_mutex); - - if (dev->of_node) { - const struct of_device_id *match; - match = of_match_node(mixer_match_types, dev->of_node); - drv = (struct mixer_drv_data *)match->data; - } else { - drv = (struct mixer_drv_data *) - platform_get_device_id(pdev)->driver_data; - } - - ctx->pdev = pdev; - ctx->dev = dev; - ctx->vp_enabled = drv->is_vp_enabled; - ctx->has_sclk = drv->has_sclk; - ctx->mxr_ver = drv->version; - init_waitqueue_head(&ctx->wait_vsync_queue); - atomic_set(&ctx->wait_vsync_event, 0); - - mixer_manager.ctx = ctx; - ret = mixer_initialize(&mixer_manager, drm_dev); + ret = mixer_initialize(&ctx->manager, drm_dev); if (ret) return ret; - platform_set_drvdata(pdev, &mixer_manager); - ret = exynos_drm_crtc_create(&mixer_manager); + ret = exynos_drm_crtc_create(&ctx->manager); if (ret) { - mixer_mgr_remove(&mixer_manager); + mixer_mgr_remove(&ctx->manager); return ret; } @@ -1301,11 +1264,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) static void mixer_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_drm_manager *mgr = dev_get_drvdata(dev); + struct mixer_context *ctx = dev_get_drvdata(dev); - dev_info(dev, "remove successful\n"); - - mixer_mgr_remove(mgr); + mixer_mgr_remove(&ctx->manager); pm_runtime_disable(dev); } @@ -1317,22 +1278,63 @@ static const struct component_ops mixer_component_ops = { static int mixer_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct mixer_drv_data *drv; + struct mixer_context *ctx; int ret; + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + DRM_ERROR("failed to alloc mixer context.\n"); + return -ENOMEM; + } + + mutex_init(&ctx->mixer_mutex); + + ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI; + ctx->manager.ops = &mixer_manager_ops; + + if (dev->of_node) { + const struct of_device_id *match; + + match = of_match_node(mixer_match_types, dev->of_node); + drv = (struct mixer_drv_data *)match->data; + } else { + drv = (struct mixer_drv_data *) + platform_get_device_id(pdev)->driver_data; + } + + ctx->pdev = pdev; + ctx->dev = dev; + ctx->vp_enabled = drv->is_vp_enabled; + ctx->has_sclk = drv->has_sclk; + ctx->mxr_ver = drv->version; + init_waitqueue_head(&ctx->wait_vsync_queue); + atomic_set(&ctx->wait_vsync_event, 0); + ctx->manager.ctx = ctx; + + platform_set_drvdata(pdev, ctx); + ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, - mixer_manager.type); + ctx->manager.type); if (ret) return ret; ret = component_add(&pdev->dev, &mixer_component_ops); - if (ret) + if (ret) { exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); + return ret; + } + + pm_runtime_enable(dev); return ret; } static int mixer_remove(struct platform_device *pdev) { + pm_runtime_disable(&pdev->dev); + component_del(&pdev->dev, &mixer_component_ops); exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); -- GitLab From 8f0be8304defc33d32ed26a7b1eec54270b995a7 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 24 Nov 2014 14:14:49 +0900 Subject: [PATCH 6161/9457] drm/exynos/mixer: stop using manager->ctx pointer The patch replaces accesses to manager->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 1b1fd82ec262..820b76234ef4 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -103,6 +103,11 @@ struct mixer_context { atomic_t wait_vsync_event; }; +static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr) +{ + return container_of(mgr, struct mixer_context, manager); +} + struct mixer_drv_data { enum mixer_version_id version; bool is_vp_enabled; @@ -853,7 +858,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev) { int ret; - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); struct exynos_drm_private *priv; priv = drm_dev->dev_private; @@ -884,7 +889,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, static void mixer_mgr_remove(struct exynos_drm_manager *mgr) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); if (is_drm_iommu_supported(mixer_ctx->drm_dev)) drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); @@ -892,7 +897,7 @@ static void mixer_mgr_remove(struct exynos_drm_manager *mgr) static int mixer_enable_vblank(struct exynos_drm_manager *mgr) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); struct mixer_resources *res = &mixer_ctx->mixer_res; if (!mixer_ctx->powered) { @@ -909,7 +914,7 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr) static void mixer_disable_vblank(struct exynos_drm_manager *mgr) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); struct mixer_resources *res = &mixer_ctx->mixer_res; /* disable vsync interrupt */ @@ -919,7 +924,7 @@ static void mixer_disable_vblank(struct exynos_drm_manager *mgr) static void mixer_win_mode_set(struct exynos_drm_manager *mgr, struct exynos_drm_overlay *overlay) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); struct hdmi_win_data *win_data; int win; @@ -970,7 +975,7 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr, static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; DRM_DEBUG_KMS("win: %d\n", win); @@ -992,7 +997,7 @@ static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); struct mixer_resources *res = &mixer_ctx->mixer_res; int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; unsigned long flags; @@ -1020,7 +1025,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) { - struct mixer_context *mixer_ctx = mgr->ctx; + struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); mutex_lock(&mixer_ctx->mixer_mutex); if (!mixer_ctx->powered) { @@ -1047,7 +1052,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) static void mixer_window_suspend(struct exynos_drm_manager *mgr) { - struct mixer_context *ctx = mgr->ctx; + struct mixer_context *ctx = mgr_to_mixer(mgr); struct hdmi_win_data *win_data; int i; @@ -1061,7 +1066,7 @@ static void mixer_window_suspend(struct exynos_drm_manager *mgr) static void mixer_window_resume(struct exynos_drm_manager *mgr) { - struct mixer_context *ctx = mgr->ctx; + struct mixer_context *ctx = mgr_to_mixer(mgr); struct hdmi_win_data *win_data; int i; @@ -1076,7 +1081,7 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr) static void mixer_poweron(struct exynos_drm_manager *mgr) { - struct mixer_context *ctx = mgr->ctx; + struct mixer_context *ctx = mgr_to_mixer(mgr); struct mixer_resources *res = &ctx->mixer_res; mutex_lock(&ctx->mixer_mutex); @@ -1110,7 +1115,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) static void mixer_poweroff(struct exynos_drm_manager *mgr) { - struct mixer_context *ctx = mgr->ctx; + struct mixer_context *ctx = mgr_to_mixer(mgr); struct mixer_resources *res = &ctx->mixer_res; mutex_lock(&ctx->mixer_mutex); @@ -1311,7 +1316,6 @@ static int mixer_probe(struct platform_device *pdev) ctx->mxr_ver = drv->version; init_waitqueue_head(&ctx->wait_vsync_queue); atomic_set(&ctx->wait_vsync_event, 0); - ctx->manager.ctx = ctx; platform_set_drvdata(pdev, ctx); -- GitLab From f01833cd2b36767d350c4f8b3eaaf48c4d2f7da3 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:16 +0100 Subject: [PATCH 6162/9457] drm/exynos/vidi: embed manager into private context exynos_drm_manager is used by internal Exynos DRM framework for representing crtc. As it should be mapped 1:1 to vidi private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple mixer devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 50faf913e574..f47939c4a303 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -28,7 +28,6 @@ /* vidi has totally three virtual windows. */ #define WINDOWS_NR 3 -#define get_vidi_mgr(dev) platform_get_drvdata(to_platform_device(dev)) #define ctx_from_connector(c) container_of(c, struct vidi_context, \ connector) @@ -47,6 +46,7 @@ struct vidi_win_data { }; struct vidi_context { + struct exynos_drm_manager manager; struct drm_device *drm_dev; struct drm_crtc *crtc; struct drm_encoder *encoder; @@ -316,11 +316,6 @@ static struct exynos_drm_manager_ops vidi_manager_ops = { .win_disable = vidi_win_disable, }; -static struct exynos_drm_manager vidi_manager = { - .type = EXYNOS_DISPLAY_TYPE_VIDI, - .ops = &vidi_manager_ops, -}; - static void vidi_fake_vblank_handler(struct work_struct *work) { struct vidi_context *ctx = container_of(work, struct vidi_context, @@ -349,9 +344,8 @@ static void vidi_fake_vblank_handler(struct work_struct *work) static int vidi_show_connection(struct device *dev, struct device_attribute *attr, char *buf) { + struct vidi_context *ctx = dev_get_drvdata(dev); int rc; - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - struct vidi_context *ctx = mgr->ctx; mutex_lock(&ctx->lock); @@ -366,8 +360,7 @@ static int vidi_store_connection(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = dev_get_drvdata(dev); int ret; ret = kstrtoint(buf, 0, &ctx->connected); @@ -563,14 +556,13 @@ static struct exynos_drm_display vidi_display = { static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) { - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_crtc *crtc = ctx->crtc; int ret; - vidi_mgr_initialize(mgr, drm_dev); + vidi_mgr_initialize(&ctx->manager, drm_dev); - ret = exynos_drm_crtc_create(&vidi_manager); + ret = exynos_drm_crtc_create(&ctx->manager); if (ret) { DRM_ERROR("failed to create crtc.\n"); return ret; @@ -596,16 +588,18 @@ static int vidi_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; + ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI; + ctx->manager.ops = &vidi_manager_ops; ctx->default_win = 0; INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - vidi_manager.ctx = ctx; + ctx->manager.ctx = ctx; vidi_display.ctx = ctx; mutex_init(&ctx->lock); - platform_set_drvdata(pdev, &vidi_manager); + platform_set_drvdata(pdev, ctx); subdrv = &ctx->subdrv; subdrv->dev = &pdev->dev; @@ -628,8 +622,7 @@ static int vidi_probe(struct platform_device *pdev) static int vidi_remove(struct platform_device *pdev) { - struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = platform_get_drvdata(pdev); if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); @@ -668,12 +661,19 @@ int exynos_drm_probe_vidi(void) return ret; } +static int exynos_drm_remove_vidi_device(struct device *dev, void *data) +{ + platform_device_unregister(to_platform_device(dev)); + + return 0; +} + void exynos_drm_remove_vidi(void) { - struct vidi_context *ctx = vidi_manager.ctx; - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct platform_device *pdev = to_platform_device(subdrv->dev); + int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL, + exynos_drm_remove_vidi_device); + /* silence compiler warning */ + (void)ret; platform_driver_unregister(&vidi_driver); - platform_device_unregister(pdev); } -- GitLab From e1819aad14ad6bd799ae5c1f97412b1dd55d2065 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:17 +0100 Subject: [PATCH 6163/9457] drm/exynos/vidi: stop using manager->ctx pointer The patch replaces accesses to manager->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index f47939c4a303..f048a903eb8d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -66,6 +66,11 @@ struct vidi_context { int pipe; }; +static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m) +{ + return container_of(m, struct vidi_context, manager); +} + static const char fake_edid_info[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, @@ -93,7 +98,7 @@ static const char fake_edid_info[] = { static void vidi_apply(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct vidi_win_data *win_data; int i; @@ -110,7 +115,7 @@ static void vidi_apply(struct exynos_drm_manager *mgr) static void vidi_commit(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); if (ctx->suspended) return; @@ -118,7 +123,7 @@ static void vidi_commit(struct exynos_drm_manager *mgr) static int vidi_enable_vblank(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); if (ctx->suspended) return -EPERM; @@ -140,7 +145,7 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr) static void vidi_disable_vblank(struct exynos_drm_manager *mgr) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); if (ctx->suspended) return; @@ -152,7 +157,7 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr) static void vidi_win_mode_set(struct exynos_drm_manager *mgr, struct exynos_drm_overlay *overlay) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); struct vidi_win_data *win_data; int win; unsigned long offset; @@ -204,7 +209,7 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr, static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); struct vidi_win_data *win_data; int win = zpos; @@ -229,7 +234,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); struct vidi_win_data *win_data; int win = zpos; @@ -247,7 +252,7 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); DRM_DEBUG_KMS("%s\n", __FILE__); @@ -271,7 +276,7 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); DRM_DEBUG_KMS("%d\n", mode); @@ -297,7 +302,7 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev) { - struct vidi_context *ctx = mgr->ctx; + struct vidi_context *ctx = manager_to_vidi(mgr); struct exynos_drm_private *priv = drm_dev->dev_private; mgr->drm_dev = ctx->drm_dev = drm_dev; @@ -594,7 +599,6 @@ static int vidi_probe(struct platform_device *pdev) INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - ctx->manager.ctx = ctx; vidi_display.ctx = ctx; mutex_init(&ctx->lock); -- GitLab From e152dbd77bc6388c910a3fd2d2acd2439d24631a Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:18 +0100 Subject: [PATCH 6164/9457] drm/exynos/fimd: embed manager into private context exynos_drm_manager is used by internal Exynos DRM framework for representing crtc. As it should be mapped 1:1 to fimd private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple FIMD devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 62 ++++++++++-------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a8ab3ecb202e..9a5e999d33f5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -84,8 +84,6 @@ /* FIMD has totally five hardware windows. */ #define WINDOWS_NR 5 -#define get_fimd_manager(mgr) platform_get_drvdata(to_platform_device(dev)) - struct fimd_driver_data { unsigned int timing_base; unsigned int lcdblk_offset; @@ -159,6 +157,7 @@ struct fimd_win_data { }; struct fimd_context { + struct exynos_drm_manager manager; struct device *dev; struct drm_device *drm_dev; struct clk *bus_clk; @@ -965,8 +964,7 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) static void fimd_trigger(struct device *dev) { - struct exynos_drm_manager *mgr = get_fimd_manager(dev); - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = dev_get_drvdata(dev); struct fimd_driver_data *driver_data = ctx->driver_data; void *timing_base = ctx->regs + driver_data->timing_base; u32 reg; @@ -1032,11 +1030,6 @@ static struct exynos_drm_manager_ops fimd_manager_ops = { .te_handler = fimd_te_handler, }; -static struct exynos_drm_manager fimd_manager = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .ops = &fimd_manager_ops, -}; - static irqreturn_t fimd_irq_handler(int irq, void *dev_id) { struct fimd_context *ctx = (struct fimd_context *)dev_id; @@ -1074,11 +1067,11 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) static int fimd_bind(struct device *dev, struct device *master, void *data) { - struct fimd_context *ctx = fimd_manager.ctx; + struct fimd_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; - fimd_mgr_initialize(&fimd_manager, drm_dev); - exynos_drm_crtc_create(&fimd_manager); + fimd_mgr_initialize(&ctx->manager, drm_dev); + exynos_drm_crtc_create(&ctx->manager); if (ctx->display) exynos_drm_create_enc_conn(drm_dev, ctx->display); @@ -1089,15 +1082,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) static void fimd_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_drm_manager *mgr = dev_get_drvdata(dev); - struct fimd_context *ctx = fimd_manager.ctx; + struct fimd_context *ctx = dev_get_drvdata(dev); - fimd_dpms(mgr, DRM_MODE_DPMS_OFF); + fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF); if (ctx->display) exynos_dpi_remove(dev); - fimd_mgr_remove(mgr); + fimd_mgr_remove(&ctx->manager); } static const struct component_ops fimd_component_ops = { @@ -1113,21 +1105,20 @@ static int fimd_probe(struct platform_device *pdev) struct resource *res; int ret = -EINVAL; - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, - fimd_manager.type); - if (ret) - return ret; - - if (!dev->of_node) { - ret = -ENODEV; - goto err_del_component; - } + if (!dev->of_node) + return -ENODEV; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - ret = -ENOMEM; - goto err_del_component; - } + if (!ctx) + return -ENOMEM; + + ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD; + ctx->manager.ops = &fimd_manager_ops; + + ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, + ctx->manager.type); + if (ret) + return ret; ctx->dev = dev; ctx->suspended = true; @@ -1215,28 +1206,27 @@ static int fimd_probe(struct platform_device *pdev) init_waitqueue_head(&ctx->wait_vsync_queue); atomic_set(&ctx->wait_vsync_event, 0); + ctx->manager.ctx = ctx; - platform_set_drvdata(pdev, &fimd_manager); - - fimd_manager.ctx = ctx; + platform_set_drvdata(pdev, ctx); ctx->display = exynos_dpi_probe(dev); if (IS_ERR(ctx->display)) return PTR_ERR(ctx->display); - pm_runtime_enable(&pdev->dev); + pm_runtime_enable(dev); - ret = component_add(&pdev->dev, &fimd_component_ops); + ret = component_add(dev, &fimd_component_ops); if (ret) goto err_disable_pm_runtime; return ret; err_disable_pm_runtime: - pm_runtime_disable(&pdev->dev); + pm_runtime_disable(dev); err_del_component: - exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); + exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC); return ret; } -- GitLab From 400c8ac8fc78f51dc7eb187dcf2320fb616c8215 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:19 +0100 Subject: [PATCH 6165/9457] drm/exynos/fimd: stop using manager->ctx pointer The patch replaces accesses to manager->ctx pointer by container_of construct. As fimd was the last user of ctx the patch removes this field as well. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 - drivers/gpu/drm/exynos/exynos_drm_fimd.c | 40 +++++++++++++----------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 262a4590ddb2..f408e49cf0b4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -211,7 +211,6 @@ struct exynos_drm_manager { struct drm_crtc *crtc; int pipe; struct exynos_drm_manager_ops *ops; - void *ctx; }; struct exynos_drm_g2d_private { diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 9a5e999d33f5..b94466146090 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -185,6 +185,11 @@ struct fimd_context { struct exynos_drm_display *display; }; +static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr) +{ + return container_of(mgr, struct fimd_context, manager); +} + static const struct of_device_id fimd_driver_dt_match[] = { { .compatible = "samsung,s3c6400-fimd", .data = &s3c64xx_fimd_driver_data }, @@ -211,7 +216,7 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data( static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); if (ctx->suspended) return; @@ -256,7 +261,7 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, static void fimd_clear_channel(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -289,7 +294,7 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct exynos_drm_private *priv; priv = drm_dev->dev_private; @@ -311,7 +316,7 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, static void fimd_mgr_remove(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); /* detach this sub driver from iommu mapping if supported. */ if (is_drm_iommu_supported(ctx->drm_dev)) @@ -351,14 +356,14 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, static void fimd_mode_set(struct exynos_drm_manager *mgr, const struct drm_display_mode *in_mode) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); drm_mode_copy(&ctx->mode, in_mode); } static void fimd_commit(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct drm_display_mode *mode = &ctx->mode; struct fimd_driver_data *driver_data = ctx->driver_data; void *timing_base = ctx->regs + driver_data->timing_base; @@ -458,7 +463,7 @@ static void fimd_commit(struct exynos_drm_manager *mgr) static int fimd_enable_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); u32 val; if (ctx->suspended) @@ -490,7 +495,7 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) static void fimd_disable_vblank(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); u32 val; if (ctx->suspended) @@ -515,7 +520,7 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) static void fimd_win_mode_set(struct exynos_drm_manager *mgr, struct exynos_drm_overlay *overlay) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int win; unsigned long offset; @@ -673,7 +678,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int win = zpos; unsigned long val, alpha, size; @@ -796,7 +801,7 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int win = zpos; @@ -830,7 +835,7 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) static void fimd_window_suspend(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int i; @@ -844,7 +849,7 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr) static void fimd_window_resume(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int i; @@ -857,7 +862,7 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr) static void fimd_apply(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); struct fimd_win_data *win_data; int i; @@ -874,7 +879,7 @@ static void fimd_apply(struct exynos_drm_manager *mgr) static int fimd_poweron(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); int ret; if (!ctx->suspended) @@ -922,7 +927,7 @@ static int fimd_poweron(struct exynos_drm_manager *mgr) static int fimd_poweroff(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); if (ctx->suspended) return 0; @@ -993,7 +998,7 @@ static void fimd_trigger(struct device *dev) static void fimd_te_handler(struct exynos_drm_manager *mgr) { - struct fimd_context *ctx = mgr->ctx; + struct fimd_context *ctx = mgr_to_fimd(mgr); /* Checks the crtc is detached already from encoder */ if (ctx->pipe < 0 || !ctx->drm_dev) @@ -1206,7 +1211,6 @@ static int fimd_probe(struct platform_device *pdev) init_waitqueue_head(&ctx->wait_vsync_queue); atomic_set(&ctx->wait_vsync_event, 0); - ctx->manager.ctx = ctx; platform_set_drvdata(pdev, ctx); -- GitLab From 930865fbe290411a84da0617a3927e78ba939311 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:20 +0100 Subject: [PATCH 6166/9457] drm/exynos/hdmi: embed display into private context exynos_drm_display is used by internal Exynos DRM framework for representing encoder:connector pair. As it should be mapped 1:1 to hdmi private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple hdmi devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 49 ++++++++++++---------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 563a19e62eb2..2851f89ede0e 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -49,7 +49,6 @@ #include #include -#define get_hdmi_display(dev) platform_get_drvdata(to_platform_device(dev)) #define ctx_from_connector(c) container_of(c, struct hdmi_context, connector) #define HOTPLUG_DEBOUNCE_MS 1100 @@ -182,6 +181,7 @@ struct hdmi_conf_regs { }; struct hdmi_context { + struct exynos_drm_display display; struct device *dev; struct drm_device *drm_dev; struct drm_connector connector; @@ -2143,11 +2143,6 @@ static struct exynos_drm_display_ops hdmi_display_ops = { .commit = hdmi_commit, }; -static struct exynos_drm_display hdmi_display = { - .type = EXYNOS_DISPLAY_TYPE_HDMI, - .ops = &hdmi_display_ops, -}; - static void hdmi_hotplug_work_func(struct work_struct *work) { struct hdmi_context *hdata; @@ -2302,12 +2297,11 @@ MODULE_DEVICE_TABLE (of, hdmi_match_types); static int hdmi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm_dev = data; - struct hdmi_context *hdata; + struct hdmi_context *hdata = dev_get_drvdata(dev); - hdata = hdmi_display.ctx; hdata->drm_dev = drm_dev; - return exynos_drm_create_enc_conn(drm_dev, &hdmi_display); + return exynos_drm_create_enc_conn(drm_dev, &hdata->display); } static void hdmi_unbind(struct device *dev, struct device *master, void *data) @@ -2349,31 +2343,28 @@ static int hdmi_probe(struct platform_device *pdev) struct resource *res; int ret; - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, - hdmi_display.type); - if (ret) - return ret; - - if (!dev->of_node) { - ret = -ENODEV; - goto err_del_component; - } + if (!dev->of_node) + return -ENODEV; pdata = drm_hdmi_dt_parse_pdata(dev); - if (!pdata) { - ret = -EINVAL; - goto err_del_component; - } + if (!pdata) + return -EINVAL; hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL); - if (!hdata) { - ret = -ENOMEM; - goto err_del_component; - } + if (!hdata) + return -ENOMEM; + + hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI; + hdata->display.ops = &hdmi_display_ops; + + ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, + hdata->display.type); + if (ret) + return ret; mutex_init(&hdata->hdmi_mutex); - platform_set_drvdata(pdev, &hdmi_display); + platform_set_drvdata(pdev, hdata); match = of_match_node(hdmi_match_types, dev->of_node); if (!match) { @@ -2485,7 +2476,7 @@ static int hdmi_probe(struct platform_device *pdev) } pm_runtime_enable(dev); - hdmi_display.ctx = hdata; + hdata->display.ctx = hdata; ret = component_add(&pdev->dev, &hdmi_component_ops); if (ret) @@ -2510,7 +2501,7 @@ static int hdmi_probe(struct platform_device *pdev) static int hdmi_remove(struct platform_device *pdev) { - struct hdmi_context *hdata = hdmi_display.ctx; + struct hdmi_context *hdata = platform_get_drvdata(pdev); cancel_delayed_work_sync(&hdata->hotplug_work); -- GitLab From 0d8424f83c31f1839826ea17ffc3ddf3f1b332a4 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:21 +0100 Subject: [PATCH 6167/9457] drm/exynos/hdmi: stop using display->ctx pointer The patch replaces accesses to display->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_hdmi.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 2851f89ede0e..5765a161abdd 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -213,6 +213,11 @@ struct hdmi_context { enum hdmi_type type; }; +static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d) +{ + return container_of(d, struct hdmi_context, display); +} + struct hdmiphy_config { int pixel_clock; u8 conf[32]; @@ -1123,7 +1128,7 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { static int hdmi_create_connector(struct exynos_drm_display *display, struct drm_encoder *encoder) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); struct drm_connector *connector = &hdata->connector; int ret; @@ -2000,7 +2005,7 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata, static void hdmi_mode_set(struct exynos_drm_display *display, struct drm_display_mode *mode) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); struct drm_display_mode *m = mode; DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n", @@ -2019,7 +2024,7 @@ static void hdmi_mode_set(struct exynos_drm_display *display, static void hdmi_commit(struct exynos_drm_display *display) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); mutex_lock(&hdata->hdmi_mutex); if (!hdata->powered) { @@ -2033,7 +2038,7 @@ static void hdmi_commit(struct exynos_drm_display *display) static void hdmi_poweron(struct exynos_drm_display *display) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); struct hdmi_resources *res = &hdata->res; mutex_lock(&hdata->hdmi_mutex); @@ -2064,7 +2069,7 @@ static void hdmi_poweron(struct exynos_drm_display *display) static void hdmi_poweroff(struct exynos_drm_display *display) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); struct hdmi_resources *res = &hdata->res; mutex_lock(&hdata->hdmi_mutex); @@ -2099,7 +2104,7 @@ static void hdmi_poweroff(struct exynos_drm_display *display) static void hdmi_dpms(struct exynos_drm_display *display, int mode) { - struct hdmi_context *hdata = display->ctx; + struct hdmi_context *hdata = display_to_hdmi(display); struct drm_encoder *encoder = hdata->encoder; struct drm_crtc *crtc = encoder->crtc; struct drm_crtc_helper_funcs *funcs = NULL; @@ -2476,7 +2481,6 @@ static int hdmi_probe(struct platform_device *pdev) } pm_runtime_enable(dev); - hdata->display.ctx = hdata; ret = component_add(&pdev->dev, &hdmi_component_ops); if (ret) -- GitLab From 7340426affacb4b5988f9cf1c3dbfc28e9679360 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:22 +0100 Subject: [PATCH 6168/9457] drm/exynos/vidi: embed display into private context exynos_drm_display is used by internal Exynos DRM framework for representing encoder:connector pair. As it should be mapped 1:1 to vidi private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple vidi devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index f048a903eb8d..f58dd52f6d60 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -47,6 +47,7 @@ struct vidi_win_data { struct vidi_context { struct exynos_drm_manager manager; + struct exynos_drm_display display; struct drm_device *drm_dev; struct drm_crtc *crtc; struct drm_encoder *encoder; @@ -554,11 +555,6 @@ static struct exynos_drm_display_ops vidi_display_ops = { .create_connector = vidi_create_connector, }; -static struct exynos_drm_display vidi_display = { - .type = EXYNOS_DISPLAY_TYPE_VIDI, - .ops = &vidi_display_ops, -}; - static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) { struct vidi_context *ctx = dev_get_drvdata(dev); @@ -573,7 +569,7 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) return ret; } - ret = exynos_drm_create_enc_conn(drm_dev, &vidi_display); + ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display); if (ret) { crtc->funcs->destroy(crtc); DRM_ERROR("failed to create encoder and connector.\n"); @@ -595,11 +591,13 @@ static int vidi_probe(struct platform_device *pdev) ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI; ctx->manager.ops = &vidi_manager_ops; + ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI; + ctx->display.ops = &vidi_display_ops; ctx->default_win = 0; INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - vidi_display.ctx = ctx; + ctx->display.ctx = ctx; mutex_init(&ctx->lock); -- GitLab From 2f26bd7227b80d002dfcd3f60e71bfad168e6517 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:23 +0100 Subject: [PATCH 6169/9457] drm/exynos/vidi: stop using display->ctx pointer The patch replaces accesses to display->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index f58dd52f6d60..3b6fdd614584 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -72,6 +72,11 @@ static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m) return container_of(m, struct vidi_context, manager); } +static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d) +{ + return container_of(d, struct vidi_context, display); +} + static const char fake_edid_info[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, @@ -419,7 +424,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, display = exynos_drm_get_display(encoder); if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) { - ctx = display->ctx; + ctx = display_to_vidi(display); break; } } @@ -529,7 +534,7 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = { static int vidi_create_connector(struct exynos_drm_display *display, struct drm_encoder *encoder) { - struct vidi_context *ctx = display->ctx; + struct vidi_context *ctx = display_to_vidi(display); struct drm_connector *connector = &ctx->connector; int ret; @@ -597,8 +602,6 @@ static int vidi_probe(struct platform_device *pdev) INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - ctx->display.ctx = ctx; - mutex_init(&ctx->lock); platform_set_drvdata(pdev, ctx); -- GitLab From 1df6e5fb79f614141f4358587b18695d7acda024 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:24 +0100 Subject: [PATCH 6170/9457] drm/exynos/dp: embed display into private context exynos_drm_display is used by internal Exynos DRM framework for representing encoder:connector pair. As it should be mapped 1:1 to dp private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple dp devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_dp_core.c | 42 +++++++++++-------------- drivers/gpu/drm/exynos/exynos_dp_core.h | 3 ++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index ed818b9a615a..47c6e4798baf 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -30,7 +30,6 @@ #include #include -#include "exynos_drm_drv.h" #include "exynos_dp_core.h" #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ @@ -1133,11 +1132,6 @@ static struct exynos_drm_display_ops exynos_dp_display_ops = { .commit = exynos_dp_commit, }; -static struct exynos_drm_display exynos_dp_display = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .ops = &exynos_dp_display_ops, -}; - static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) { struct device_node *dp_node = dev->of_node; @@ -1211,10 +1205,10 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) static int exynos_dp_bind(struct device *dev, struct device *master, void *data) { + struct exynos_dp_device *dp = dev_get_drvdata(dev); struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm_dev = data; struct resource *res; - struct exynos_dp_device *dp = exynos_dp_display.ctx; unsigned int irq_flags; int ret = 0; @@ -1306,17 +1300,15 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) dp->drm_dev = drm_dev; - platform_set_drvdata(pdev, &exynos_dp_display); - - return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display); + return exynos_drm_create_enc_conn(drm_dev, &dp->display); } static void exynos_dp_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_drm_display *display = dev_get_drvdata(dev); + struct exynos_dp_device *dp = dev_get_drvdata(dev); - exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); + exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF); } static const struct component_ops exynos_dp_ops = { @@ -1331,16 +1323,20 @@ static int exynos_dp_probe(struct platform_device *pdev) struct exynos_dp_device *dp; int ret; - ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, - exynos_dp_display.type); - if (ret) - return ret; - dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; + dp->display.type = EXYNOS_DISPLAY_TYPE_LCD; + dp->display.ops = &exynos_dp_display_ops; + platform_set_drvdata(pdev, dp); + + ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, + dp->display.type); + if (ret) + return ret; + panel_node = of_parse_phandle(dev->of_node, "panel", 0); if (panel_node) { dp->panel = of_drm_find_panel(panel_node); @@ -1349,7 +1345,7 @@ static int exynos_dp_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - exynos_dp_display.ctx = dp; + dp->display.ctx = dp; ret = component_add(&pdev->dev, &exynos_dp_ops); if (ret) @@ -1370,19 +1366,17 @@ static int exynos_dp_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int exynos_dp_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct exynos_drm_display *display = platform_get_drvdata(pdev); + struct exynos_dp_device *dp = dev_get_drvdata(dev); - exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); + exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF); return 0; } static int exynos_dp_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct exynos_drm_display *display = platform_get_drvdata(pdev); + struct exynos_dp_device *dp = dev_get_drvdata(dev); - exynos_dp_dpms(display, DRM_MODE_DPMS_ON); + exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON); return 0; } #endif diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h index 6426201667bc..164f171168e7 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.h +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h @@ -17,6 +17,8 @@ #include #include +#include "exynos_drm_drv.h" + #define DP_TIMEOUT_LOOP_COUNT 100 #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 @@ -145,6 +147,7 @@ struct link_train { }; struct exynos_dp_device { + struct exynos_drm_display display; struct device *dev; struct drm_device *drm_dev; struct drm_connector connector; -- GitLab From 63b3be327048402a39068f188726e3729e061fda Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:25 +0100 Subject: [PATCH 6171/9457] drm/exynos/dp: stop using display->ctx pointer The patch replaces accesses to display->ctx pointer by container_of construct. It will allow to remove ctx field in the future. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_dp_core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 47c6e4798baf..34d46aa75416 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -35,6 +35,12 @@ #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ connector) +static inline struct exynos_dp_device * +display_to_dp(struct exynos_drm_display *d) +{ + return container_of(d, struct exynos_dp_device, display); +} + struct bridge_init { struct i2c_client *client; struct device_node *node; @@ -881,7 +887,7 @@ static void exynos_dp_hotplug(struct work_struct *work) static void exynos_dp_commit(struct exynos_drm_display *display) { - struct exynos_dp_device *dp = display->ctx; + struct exynos_dp_device *dp = display_to_dp(display); int ret; /* Keep the panel disabled while we configure video */ @@ -1019,7 +1025,7 @@ static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, static int exynos_dp_create_connector(struct exynos_drm_display *display, struct drm_encoder *encoder) { - struct exynos_dp_device *dp = display->ctx; + struct exynos_dp_device *dp = display_to_dp(display); struct drm_connector *connector = &dp->connector; int ret; @@ -1063,7 +1069,7 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp) static void exynos_dp_poweron(struct exynos_drm_display *display) { - struct exynos_dp_device *dp = display->ctx; + struct exynos_dp_device *dp = display_to_dp(display); if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; @@ -1084,7 +1090,7 @@ static void exynos_dp_poweron(struct exynos_drm_display *display) static void exynos_dp_poweroff(struct exynos_drm_display *display) { - struct exynos_dp_device *dp = display->ctx; + struct exynos_dp_device *dp = display_to_dp(display); if (dp->dpms_mode != DRM_MODE_DPMS_ON) return; @@ -1109,7 +1115,7 @@ static void exynos_dp_poweroff(struct exynos_drm_display *display) static void exynos_dp_dpms(struct exynos_drm_display *display, int mode) { - struct exynos_dp_device *dp = display->ctx; + struct exynos_dp_device *dp = display_to_dp(display); switch (mode) { case DRM_MODE_DPMS_ON: @@ -1345,8 +1351,6 @@ static int exynos_dp_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - dp->display.ctx = dp; - ret = component_add(&pdev->dev, &exynos_dp_ops); if (ret) exynos_drm_component_del(&pdev->dev, -- GitLab From 4cfde1f2af076547ebe86f8632e65119f28438b8 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:26 +0100 Subject: [PATCH 6172/9457] drm/exynos/dpi: embed display into private context exynos_drm_display is used by internal Exynos DRM framework for representing encoder:connector pair. As it should be mapped 1:1 to dpi private context it seems more reasonable to embed it directly in that context. As a result further code simplification will be possible. Moreover it will be possible to handle multiple dpi devices in the system. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 39 +++++++++++++----------- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 +- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 2 +- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 3dc678ed9949..3acfc288d17c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -22,6 +22,7 @@ #include "exynos_drm_drv.h" struct exynos_dpi { + struct exynos_drm_display display; struct device *dev; struct device_node *panel_node; @@ -35,6 +36,11 @@ struct exynos_dpi { #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector) +static inline struct exynos_dpi *display_to_dpi(struct exynos_drm_display *d) +{ + return container_of(d, struct exynos_dpi, display); +} + static enum drm_connector_status exynos_dpi_detect(struct drm_connector *connector, bool force) { @@ -165,11 +171,6 @@ static struct exynos_drm_display_ops exynos_dpi_display_ops = { .dpms = exynos_dpi_dpms }; -static struct exynos_drm_display exynos_dpi_display = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .ops = &exynos_dpi_display_ops, -}; - /* of_* functions will be removed after merge of of_graph patches */ static struct device_node * of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg) @@ -299,20 +300,22 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) struct exynos_dpi *ctx; int ret; - ret = exynos_drm_component_add(dev, - EXYNOS_DEVICE_TYPE_CONNECTOR, - exynos_dpi_display.type); - if (ret) - return ERR_PTR(ret); - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) - goto err_del_component; + return ERR_PTR(-ENOMEM); + ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD; + ctx->display.ops = &exynos_dpi_display_ops; ctx->dev = dev; - exynos_dpi_display.ctx = ctx; + ctx->display.ctx = ctx; ctx->dpms_mode = DRM_MODE_DPMS_OFF; + ret = exynos_drm_component_add(dev, + EXYNOS_DEVICE_TYPE_CONNECTOR, + ctx->display.type); + if (ret) + return ERR_PTR(ret); + ret = exynos_dpi_parse_dt(ctx); if (ret < 0) { devm_kfree(dev, ctx); @@ -328,7 +331,7 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) } } - return &exynos_dpi_display; + return &ctx->display; err_del_component: exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR); @@ -336,16 +339,16 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) return NULL; } -int exynos_dpi_remove(struct device *dev) +int exynos_dpi_remove(struct exynos_drm_display *display) { - struct exynos_dpi *ctx = exynos_dpi_display.ctx; + struct exynos_dpi *ctx = display_to_dpi(display); - exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); + exynos_dpi_dpms(&ctx->display, DRM_MODE_DPMS_OFF); if (ctx->panel) drm_panel_detach(ctx->panel); - exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR); + exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); return 0; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index f408e49cf0b4..b023f5fea25f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -304,7 +304,7 @@ static inline void exynos_platform_device_ipp_unregister(void) {} #ifdef CONFIG_DRM_EXYNOS_DPI struct exynos_drm_display * exynos_dpi_probe(struct device *dev); -int exynos_dpi_remove(struct device *dev); +int exynos_dpi_remove(struct exynos_drm_display *display); #else static inline struct exynos_drm_display * exynos_dpi_probe(struct device *dev) { return NULL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b94466146090..ef80a3537f35 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1092,7 +1092,7 @@ static void fimd_unbind(struct device *dev, struct device *master, fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF); if (ctx->display) - exynos_dpi_remove(dev); + exynos_dpi_remove(ctx->display); fimd_mgr_remove(&ctx->manager); } -- GitLab From 5af3d9bb78f130819204ef44ac9d2b635e49fc35 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Mon, 17 Nov 2014 09:54:27 +0100 Subject: [PATCH 6173/9457] drm/exynos/dpi: stop using display->ctx pointer The patch replaces accesses to display->ctx pointer by container_of construct. The field is removed as well as dpi was the last user of it. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 5 ++--- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 3acfc288d17c..37678cf4425a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -106,7 +106,7 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = { static int exynos_dpi_create_connector(struct exynos_drm_display *display, struct drm_encoder *encoder) { - struct exynos_dpi *ctx = display->ctx; + struct exynos_dpi *ctx = display_to_dpi(display); struct drm_connector *connector = &ctx->connector; int ret; @@ -147,7 +147,7 @@ static void exynos_dpi_poweroff(struct exynos_dpi *ctx) static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode) { - struct exynos_dpi *ctx = display->ctx; + struct exynos_dpi *ctx = display_to_dpi(display); switch (mode) { case DRM_MODE_DPMS_ON: @@ -307,7 +307,6 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD; ctx->display.ops = &exynos_dpi_display_ops; ctx->dev = dev; - ctx->display.ctx = ctx; ctx->dpms_mode = DRM_MODE_DPMS_OFF; ret = exynos_drm_component_add(dev, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index b023f5fea25f..2e4e91bf9b07 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -152,7 +152,6 @@ struct exynos_drm_display { struct drm_encoder *encoder; struct drm_connector *connector; struct exynos_drm_display_ops *ops; - void *ctx; }; /* -- GitLab From b67139571ec0956eb94a354572df73cf24d4521c Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 20 Nov 2014 21:42:55 -0200 Subject: [PATCH 6174/9457] Revert "drm/exynos: fix null pointer dereference issue" This reverts commit cea24824ab432f8acabb254d6805e9aa756de6af. Moving subdriver probe to exynos_drm_platform_probe() was making exynos_drm_device_subdrv_probe() fail because the platform data wasn't set yet. It only gets set in exynos_drm_load. We need to find a smarter way to fix this issue. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index eab12f084709..2ca0c5dcf80e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -108,6 +108,11 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_unbind_all; + /* Probe non kms sub drivers and virtual display driver. */ + ret = exynos_drm_device_subdrv_probe(dev); + if (ret) + goto err_cleanup_vblank; + /* * enable drm irq mode. * - with irq_enabled = true, we can use the vblank feature. @@ -133,6 +138,8 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) return 0; +err_cleanup_vblank: + drm_vblank_cleanup(dev); err_unbind_all: component_unbind_all(dev->dev, dev); err_mode_config_cleanup: @@ -146,6 +153,8 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) static int exynos_drm_unload(struct drm_device *dev) { + exynos_drm_device_subdrv_remove(dev); + exynos_drm_fbdev_fini(dev); drm_kms_helper_poll_fini(dev); @@ -614,14 +623,8 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) if (ret < 0) goto err_unregister_non_kms_drivers; - /* Probe non kms sub drivers and virtual display driver. */ - ret = exynos_drm_device_subdrv_probe(platform_get_drvdata(pdev)); - if (ret) - goto err_unregister_resources; - return ret; -err_unregister_resources: #ifdef CONFIG_DRM_EXYNOS_IPP exynos_platform_device_ipp_unregister(); #endif @@ -643,8 +646,6 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) { int i; - exynos_drm_device_subdrv_remove(platform_get_drvdata(pdev)); - #ifdef CONFIG_DRM_EXYNOS_IPP exynos_platform_device_ipp_unregister(); #endif -- GitLab From 820687befec471aff3bb59bd69302d34a776e807 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 24 Nov 2014 16:37:26 +0900 Subject: [PATCH 6175/9457] drm/exynos: move Exynos platform drivers registration to init Registering the Exynos DRM subdevices platform drivers in the probe function is causing an infinite loop. Fix this by moving it to the exynos_drm_init() function to register the drivers on module init. Registering drivers in the probe functions causes a deadlock in the parent device lock. See Grant Likely explanation on the topic: "I think the problem is that exynos_drm_init() is registering a normal (non-OF) platform device, so the parent will be /sys/devices/platform. It immediately gets bound against exynos_drm_platform_driver which calls the exynos drm_platform_probe() hook. The driver core obtains device_lock() on the device *and on the device parent*. Inside the probe hook, additional platform_drivers get registered. Each time one does, it tries to bind against every platform device in the system, which includes the ones created by OF. When it attempts to bind, it obtains device_lock() on the device *and on the device parent*. Before the change to move of-generated platform devices into /sys/devices/platform, the devices had different parents. Now both devices have /sys/devices/platform as the parent, so yes they are going to deadlock. The real problem is registering drivers from within a probe hook. That is completely wrong for the above deadlock reason. __driver_attach() will deadlock. Those registrations must be pulled out of .probe(). Registering devices in .probe() is okay because __device_attach() doesn't try to obtain device_lock() on the parent." INFO: task swapper/0:1 blocked for more than 120 seconds. Not tainted 3.18.0-rc3-next-20141105 #794 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. swapper/0 D c052534c 0 1 0 0x00000000 [] (__schedule) from [] (schedule_preempt_disabled+0x14/0x20) [] (schedule_preempt_disabled) from [] (mutex_lock_nested+0x1c4/0x464 [] (mutex_lock_nested) from [] (__driver_attach+0x48/0x98) [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xe4/0x200) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (exynos_drm_platform_probe+0x34/0x234) [] (exynos_drm_platform_probe) from [] (platform_drv_probe+0x48/0xa4) [] (platform_drv_probe) from [] (driver_probe_device+0x13c/0x37c) [] (driver_probe_device) from [] (__driver_attach+0x94/0x98) [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xe4/0x200) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (exynos_drm_init+0x70/0xa0) [] (exynos_drm_init) from [] (do_one_initcall+0xac/0x1f0) [] (do_one_initcall) from [] (kernel_init_freeable+0x10c/0x1d8) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xec) [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) 3 locks held by swapper/0/1: #0: (&dev->mutex){......}, at: [] __driver_attach+0x48/0x98 #1: (&dev->mutex){......}, at: [] __driver_attach+0x58/0x98 #2: (&dev->mutex){......}, at: [] __driver_attach+0x48/0x98 Changelog v2: - call platform_driver_register after all kms and non kms drivers are registered - rebased it to exynos-drm-next Signed-off-by: Javier Martinez Canillas Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 105 +++++++++++------------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 2ca0c5dcf80e..c5cb8b6c85a9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -591,73 +591,22 @@ static struct platform_driver *const exynos_drm_non_kms_drivers[] = { static int exynos_drm_platform_probe(struct platform_device *pdev) { struct component_match *match; - int ret, i, j; pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls); - for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { - ret = platform_driver_register(exynos_drm_kms_drivers[i]); - if (ret < 0) - goto err_unregister_kms_drivers; - } - match = exynos_drm_match_add(&pdev->dev); if (IS_ERR(match)) { - ret = PTR_ERR(match); - goto err_unregister_kms_drivers; + return PTR_ERR(match); } - ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, - match); - if (ret < 0) - goto err_unregister_kms_drivers; - - for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) { - ret = platform_driver_register(exynos_drm_non_kms_drivers[j]); - if (ret < 0) - goto err_del_component_master; - } - - ret = exynos_platform_device_ipp_register(); - if (ret < 0) - goto err_unregister_non_kms_drivers; - - return ret; - -#ifdef CONFIG_DRM_EXYNOS_IPP - exynos_platform_device_ipp_unregister(); -#endif -err_unregister_non_kms_drivers: - while (--j >= 0) - platform_driver_unregister(exynos_drm_non_kms_drivers[j]); - -err_del_component_master: - component_master_del(&pdev->dev, &exynos_drm_ops); - -err_unregister_kms_drivers: - while (--i >= 0) - platform_driver_unregister(exynos_drm_kms_drivers[i]); - - return ret; + return component_master_add_with_match(&pdev->dev, &exynos_drm_ops, + match); } static int exynos_drm_platform_remove(struct platform_device *pdev) { - int i; - -#ifdef CONFIG_DRM_EXYNOS_IPP - exynos_platform_device_ipp_unregister(); -#endif - - for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i) - platform_driver_unregister(exynos_drm_non_kms_drivers[i]); - component_master_del(&pdev->dev, &exynos_drm_ops); - - for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i) - platform_driver_unregister(exynos_drm_kms_drivers[i]); - return 0; } @@ -673,7 +622,7 @@ static struct platform_driver exynos_drm_platform_driver = { static int exynos_drm_init(void) { - int ret; + int ret, i, j; /* * Register device object only in case of Exynos SoC. @@ -696,13 +645,43 @@ static int exynos_drm_init(void) if (ret < 0) goto err_unregister_pd; + for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { + ret = platform_driver_register(exynos_drm_kms_drivers[i]); + if (ret < 0) + goto err_unregister_kms_drivers; + } + + for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) { + ret = platform_driver_register(exynos_drm_non_kms_drivers[j]); + if (ret < 0) + goto err_unregister_non_kms_drivers; + } + +#ifdef CONFIG_DRM_EXYNOS_IPP + ret = exynos_platform_device_ipp_register(); + if (ret < 0) + goto err_unregister_non_kms_drivers; +#endif + ret = platform_driver_register(&exynos_drm_platform_driver); if (ret) - goto err_remove_vidi; + goto err_unregister_resources; return 0; -err_remove_vidi: +err_unregister_resources: +#ifdef CONFIG_DRM_EXYNOS_IPP + exynos_platform_device_ipp_unregister(); +#endif + +err_unregister_non_kms_drivers: + while (--j >= 0) + platform_driver_unregister(exynos_drm_non_kms_drivers[j]); + +err_unregister_kms_drivers: + while (--i >= 0) + platform_driver_unregister(exynos_drm_kms_drivers[i]); + exynos_drm_remove_vidi(); err_unregister_pd: @@ -713,6 +692,18 @@ static int exynos_drm_init(void) static void exynos_drm_exit(void) { + int i; + +#ifdef CONFIG_DRM_EXYNOS_IPP + exynos_platform_device_ipp_unregister(); +#endif + + for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i) + platform_driver_unregister(exynos_drm_non_kms_drivers[i]); + + for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i) + platform_driver_unregister(exynos_drm_kms_drivers[i]); + platform_driver_unregister(&exynos_drm_platform_driver); exynos_drm_remove_vidi(); -- GitLab From 4846e452084945891a770809f94b23f33eebcd8c Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 24 Nov 2014 17:08:00 +0900 Subject: [PATCH 6176/9457] drm/exynos: clean up machine compatible string check Use 'for' statemant instead of hard-coded 'if' statement. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index c5cb8b6c85a9..495826f73c2a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -610,6 +610,12 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) return 0; } +static const char * const strings[] = { + "samsung,exynos3", + "samsung,exynos4", + "samsung,exynos5", +}; + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, @@ -622,6 +628,7 @@ static struct platform_driver exynos_drm_platform_driver = { static int exynos_drm_init(void) { + bool is_exynos = false; int ret, i, j; /* @@ -631,9 +638,14 @@ static int exynos_drm_init(void) * by Exynos drm driver when using multi-platform kernel. * So these codes will be replaced with more generic way later. */ - if (!of_machine_is_compatible("samsung,exynos3") && - !of_machine_is_compatible("samsung,exynos4") && - !of_machine_is_compatible("samsung,exynos5")) + for (i = 0; i < ARRAY_SIZE(strings); i++) { + if (of_machine_is_compatible(strings[i])) { + is_exynos = true; + break; + } + } + + if (!is_exynos) return -ENODEV; exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, -- GitLab From 80f1774f967a16b1909628cd1ca3d5c30a32aac1 Mon Sep 17 00:00:00 2001 From: Max Schwarz Date: Mon, 24 Nov 2014 01:32:27 +0100 Subject: [PATCH 6177/9457] i2c: rk3x: add Kconfig dependency on COMMON_CLK Now that we are using the clk notifier framework we get compile errors without COMMON_CLK. But the driver fails to probe without COMMON_CLK anyways, so just add that as a Kconfig dependency. Signed-off-by: Max Schwarz Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c074df7454d5..39862fd27a72 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -720,7 +720,7 @@ config I2C_RIIC config I2C_RK3X tristate "Rockchip RK3xxx I2C adapter" - depends on OF + depends on OF && COMMON_CLK help Say Y here to include support for the I2C adapter in Rockchip RK3xxx SoCs. -- GitLab From 227158db160449b6513d2e31894a135104b90e90 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 6 Apr 2014 18:47:38 -0400 Subject: [PATCH 6178/9457] new helper: skb_copy_and_csum_datagram_msg() Signed-off-by: Al Viro --- include/linux/skbuff.h | 5 +++++ net/ipv4/udp.c | 5 ++--- net/ipv6/raw.c | 2 +- net/ipv6/udp.c | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 78c299f40bac..cbe4b2078b30 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2651,6 +2651,11 @@ static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset, } int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen, struct iovec *iov); +static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen, + struct msghdr *msg) +{ + return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov); +} int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, const struct iovec *from, int from_offset, int len); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 4a16b9129079..b2d606833ce4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1284,9 +1284,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), msg, copied); else { - err = skb_copy_and_csum_datagram_iovec(skb, - sizeof(struct udphdr), - msg->msg_iov); + err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), + msg); if (err == -EINVAL) goto csum_copy_err; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0cbcf98f2cab..8baa53e17a30 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -492,7 +492,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, goto csum_copy_err; err = skb_copy_datagram_msg(skb, 0, msg, copied); } else { - err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov); + err = skb_copy_and_csum_datagram_msg(skb, 0, msg); if (err == -EINVAL) goto csum_copy_err; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index dbc0b042bdd6..7cfb5d745a2d 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -428,7 +428,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, err = skb_copy_datagram_msg(skb, sizeof(struct udphdr), msg, copied); else { - err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); + err = skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg); if (err == -EINVAL) goto csum_copy_err; } -- GitLab From 6ce8e9ce5989ae13f493062975304700be86d20e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 6 Apr 2014 21:25:44 -0400 Subject: [PATCH 6179/9457] new helper: memcpy_from_msg() Signed-off-by: Al Viro --- crypto/algif_skcipher.c | 10 +++++----- drivers/isdn/mISDN/socket.c | 2 +- drivers/net/ppp/pppoe.c | 2 +- include/linux/skbuff.h | 5 +++++ include/net/sctp/sm.h | 2 +- net/appletalk/ddp.c | 2 +- net/ax25/af_ax25.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/mgmt.c | 2 +- net/bluetooth/rfcomm/sock.c | 2 +- net/bluetooth/sco.c | 2 +- net/caif/caif_socket.c | 4 ++-- net/can/bcm.c | 19 ++++++++----------- net/can/raw.c | 2 +- net/dccp/proto.c | 2 +- net/decnet/af_decnet.c | 2 +- net/ieee802154/dgram.c | 2 +- net/ieee802154/raw.c | 2 +- net/ipv4/ping.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/irda/af_irda.c | 6 +++--- net/iucv/af_iucv.c | 2 +- net/key/af_key.c | 2 +- net/l2tp/l2tp_ip.c | 2 +- net/l2tp/l2tp_ppp.c | 3 +-- net/llc/af_llc.c | 2 +- net/netlink/af_netlink.c | 2 +- net/netrom/af_netrom.c | 2 +- net/nfc/llcp_commands.c | 4 ++-- net/nfc/rawsock.c | 2 +- net/packet/af_packet.c | 5 ++--- net/phonet/datagram.c | 2 +- net/phonet/pep.c | 2 +- net/rose/af_rose.c | 2 +- net/sctp/sm_make_chunk.c | 4 ++-- net/x25/af_x25.c | 2 +- 36 files changed, 57 insertions(+), 57 deletions(-) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 83187f497c7c..c3b482bee208 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -298,9 +298,9 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, len = min_t(unsigned long, len, PAGE_SIZE - sg->offset - sg->length); - err = memcpy_fromiovec(page_address(sg_page(sg)) + - sg->offset + sg->length, - msg->msg_iov, len); + err = memcpy_from_msg(page_address(sg_page(sg)) + + sg->offset + sg->length, + msg, len); if (err) goto unlock; @@ -337,8 +337,8 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, if (!sg_page(sg + i)) goto unlock; - err = memcpy_fromiovec(page_address(sg_page(sg + i)), - msg->msg_iov, plen); + err = memcpy_from_msg(page_address(sg_page(sg + i)), + msg, plen); if (err) { __free_page(sg_page(sg + i)); sg_assign_page(sg + i, NULL); diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index dcbd8589f0c4..84b35925ee4d 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -203,7 +203,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (!skb) goto done; - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { err = -EFAULT; goto done; } diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 443cbbf5c55f..d2408a5e43a6 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -869,7 +869,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr)); start = (char *)&ph->tag[0]; - error = memcpy_fromiovec(start, m->msg_iov, total_len); + error = memcpy_from_msg(start, m, total_len); if (error < 0) { kfree_skb(skb); goto end; diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cbe4b2078b30..97dc5f8123b3 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2687,6 +2687,11 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len); int skb_vlan_pop(struct sk_buff *skb); int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); +static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len) +{ + return memcpy_fromiovec(data, msg->msg_iov, len); +} + struct skb_checksum_ops { __wsum (*update)(const void *mem, int len, __wsum wsum); __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 72a31db47ded..487ef34bbd63 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -219,7 +219,7 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, const struct sctp_chunk *, __u32 tsn); struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, - const struct msghdr *, size_t msg_len); + struct msghdr *, size_t msg_len); struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, const struct sctp_chunk *, const __u8 *, diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 425942db17f6..0d0766ea5ab1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1659,7 +1659,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + err = memcpy_from_msg(skb_put(skb, len), msg, len); if (err) { kfree_skb(skb); err = -EFAULT; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index f4f835e19378..ca049a7c9287 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1549,7 +1549,7 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reserve(skb, size - len); /* User data follows immediately after the AX.25 data */ - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { err = -EFAULT; kfree_skb(skb); goto out; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 5e2cd2535978..2c245fdf319a 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -947,7 +947,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (!skb) goto done; - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { err = -EFAULT; goto drop; } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index cbeef5f62f3b..f3e4a16fb157 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5767,7 +5767,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) if (!buf) return -ENOMEM; - if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) { + if (memcpy_from_msg(buf, msg, msglen)) { err = -EFAULT; goto done; } diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8bbbb5ec468c..2348176401a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -588,7 +588,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, } skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); + err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err) { kfree_skb(skb); if (sent == 0) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 7ee9e4ab00f8..30e5ea3f1ad3 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -285,7 +285,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) if (!skb) return err; - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { kfree_skb(skb); return -EFAULT; } diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index fbcd156099fb..230f14026c11 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -566,7 +566,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, skb_reserve(skb, cf_sk->headroom); - ret = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + ret = memcpy_from_msg(skb_put(skb, len), msg, len); if (ret) goto err; @@ -641,7 +641,7 @@ static int caif_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, */ size = min_t(int, size, skb_tailroom(skb)); - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); + err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err) { kfree_skb(skb); goto out_err; diff --git a/net/can/bcm.c b/net/can/bcm.c index dcb75c0e66c1..b9a1f715df18 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -858,8 +858,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, /* update can_frames content */ for (i = 0; i < msg_head->nframes; i++) { - err = memcpy_fromiovec((u8 *)&op->frames[i], - msg->msg_iov, CFSIZ); + err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ); if (op->frames[i].can_dlc > 8) err = -EINVAL; @@ -894,8 +893,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->frames = &op->sframe; for (i = 0; i < msg_head->nframes; i++) { - err = memcpy_fromiovec((u8 *)&op->frames[i], - msg->msg_iov, CFSIZ); + err = memcpy_from_msg((u8 *)&op->frames[i], msg, CFSIZ); if (op->frames[i].can_dlc > 8) err = -EINVAL; @@ -1024,9 +1022,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, if (msg_head->nframes) { /* update can_frames content */ - err = memcpy_fromiovec((u8 *)op->frames, - msg->msg_iov, - msg_head->nframes * CFSIZ); + err = memcpy_from_msg((u8 *)op->frames, msg, + msg_head->nframes * CFSIZ); if (err < 0) return err; @@ -1072,8 +1069,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, } if (msg_head->nframes) { - err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov, - msg_head->nframes * CFSIZ); + err = memcpy_from_msg((u8 *)op->frames, msg, + msg_head->nframes * CFSIZ); if (err < 0) { if (op->frames != &op->sframe) kfree(op->frames); @@ -1209,7 +1206,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) can_skb_reserve(skb); - err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ); + err = memcpy_from_msg(skb_put(skb, CFSIZ), msg, CFSIZ); if (err < 0) { kfree_skb(skb); return err; @@ -1285,7 +1282,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock, /* read message head information */ - ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ); + ret = memcpy_from_msg((u8 *)&msg_head, msg, MHSIZ); if (ret < 0) return ret; diff --git a/net/can/raw.c b/net/can/raw.c index 081e81fd017f..0e4004fb6876 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -703,7 +703,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, can_skb_reserve(skb); can_skb_prv(skb)->ifindex = dev->ifindex; - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); + err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err < 0) goto free_skb; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 8e6ae9422a7b..19f038739087 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -781,7 +781,7 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out_release; skb_reserve(skb, sk->sk_prot->max_header); - rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + rc = memcpy_from_msg(skb_put(skb, len), msg, len); if (rc != 0) goto out_discard; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 25733d538147..e2e2e3cb9113 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -2032,7 +2032,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER); - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { err = -EFAULT; goto out; } diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index b8555ec71387..2c7a93e7167e 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -276,7 +276,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, if (err < 0) goto out_skb; - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); + err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err < 0) goto out_skb; diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 21c38945ab8b..61e9d2972947 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c @@ -150,7 +150,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, skb_reset_mac_header(skb); skb_reset_network_header(skb); - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); + err = memcpy_from_msg(skb_put(skb, size), msg, size); if (err < 0) goto out_skb; diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index ce2920f5bef3..ef8f6ee90473 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -660,7 +660,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, * Fetch the ICMP header provided by the userland. * iovec is modified! The ICMP header is consumed. */ - if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len)) + if (memcpy_from_msg(user_icmph, msg, icmph_len)) return -EFAULT; if (family == AF_INET) { diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d22a31f27ab4..69de1a1c05c9 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4368,7 +4368,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) goto err_free; - if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) + if (memcpy_from_msg(skb_put(skb, size), msg, size)) goto err_free; TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index e8c409055922..9052462cf42a 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1319,7 +1319,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reserve(skb, self->max_header_size + 16); skb_reset_transport_header(skb); skb_put(skb, len); - err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); + err = memcpy_from_msg(skb_transport_header(skb), msg, len); if (err) { kfree_skb(skb); goto out_err; @@ -1569,7 +1569,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, pr_debug("%s(), appending user data\n", __func__); skb_put(skb, len); - err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); + err = memcpy_from_msg(skb_transport_header(skb), msg, len); if (err) { kfree_skb(skb); goto out; @@ -1678,7 +1678,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, pr_debug("%s(), appending user data\n", __func__); skb_put(skb, len); - err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); + err = memcpy_from_msg(skb_transport_header(skb), msg, len); if (err) { kfree_skb(skb); goto out; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 057b5647ef92..1cd3f8107239 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -1122,7 +1122,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, } if (iucv->transport == AF_IUCV_TRANS_HIPER) skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { err = -EFAULT; goto fail; } diff --git a/net/key/af_key.c b/net/key/af_key.c index e5883091a8c6..f8ac939d52b4 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -3611,7 +3611,7 @@ static int pfkey_sendmsg(struct kiocb *kiocb, goto out; err = -EFAULT; - if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) + if (memcpy_from_msg(skb_put(skb,len), msg, len)) goto out; hdr = pfkey_get_base_msg(skb, &err); diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index a6cc1fed2b52..05dfc8aa36af 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -441,7 +441,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m *((__be32 *) skb_put(skb, 4)) = 0; /* Copy user data into skb */ - rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + rc = memcpy_from_msg(skb_put(skb, len), msg, len); if (rc < 0) { kfree_skb(skb); goto error; diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index c559bcdf4679..cc7a828fc914 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -346,8 +346,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh skb_put(skb, 2); /* Copy user data into skb */ - error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, - total_len); + error = memcpy_from_msg(skb_put(skb, total_len), m, total_len); if (error < 0) { kfree_skb(skb); goto error_put_sess_tun; diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index af662669f951..2c0b83ce43bd 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -921,7 +921,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, skb->dev = llc->dev; skb->protocol = llc_proto_type(addr->sllc_arphrd); skb_reserve(skb, hdrlen); - rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied); + rc = memcpy_from_msg(skb_put(skb, copied), msg, copied); if (rc) goto out; if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) { diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index e1aad6eeac14..63aa5c8acf12 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2325,7 +2325,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, NETLINK_CB(skb).flags = netlink_skb_flags; err = -EFAULT; - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_put(skb, len), msg, len)) { kfree_skb(skb); goto out; } diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 7e13f6afcd1f..69f1d5e9959f 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1113,7 +1113,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, skb_put(skb, len); /* User data follows immediately after the NET/ROM transport header */ - if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) { + if (memcpy_from_msg(skb_transport_header(skb), msg, len)) { kfree_skb(skb); err = -EFAULT; goto out; diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index a3ad69a4c648..c4da0c2d8a14 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -665,7 +665,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, if (msg_data == NULL) return -ENOMEM; - if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { + if (memcpy_from_msg(msg_data, msg, len)) { kfree(msg_data); return -EFAULT; } @@ -731,7 +731,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, if (msg_data == NULL) return -ENOMEM; - if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { + if (memcpy_from_msg(msg_data, msg, len)) { kfree(msg_data); return -EFAULT; } diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 9d7d2b7ba5e4..373e138c0ab6 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -231,7 +231,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, if (skb == NULL) return rc; - rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + rc = memcpy_from_msg(skb_put(skb, len), msg, len); if (rc < 0) { kfree_skb(skb); return rc; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 58af58026dd2..07ac95014ecb 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1676,7 +1676,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, if (len < hhlen) skb_reset_network_header(skb); } - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + err = memcpy_from_msg(skb_put(skb, len), msg, len); if (err) goto out_free; goto retry; @@ -2446,8 +2446,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) len -= vnet_hdr_len; - err = memcpy_fromiovec((void *)&vnet_hdr, msg->msg_iov, - vnet_hdr_len); + err = memcpy_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len); if (err < 0) goto out_unlock; diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index 0918bc21eae6..26054b4b467c 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c @@ -109,7 +109,7 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk, return err; skb_reserve(skb, MAX_PHONET_HEADER); - err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len); + err = memcpy_from_msg((void *)skb_put(skb, len), msg, len); if (err < 0) { kfree_skb(skb); return err; diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 9cd069dfaf65..5d3f2b7507d4 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -1141,7 +1141,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, return err; skb_reserve(skb, MAX_PHONET_HEADER + 3 + pn->aligned); - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + err = memcpy_from_msg(skb_put(skb, len), msg, len); if (err < 0) goto outfree; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 9b600c20a7a3..43bac7c4dd9e 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1121,7 +1121,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reset_transport_header(skb); skb_put(skb, len); - err = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); + err = memcpy_from_msg(skb_transport_header(skb), msg, len); if (err) { kfree_skb(skb); return err; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 9f32741abb1c..e49bccebb0cc 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1001,7 +1001,7 @@ struct sctp_chunk *sctp_make_abort_no_data( /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, - const struct msghdr *msg, + struct msghdr *msg, size_t paylen) { struct sctp_chunk *retval; @@ -1018,7 +1018,7 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, if (!payload) goto err_payload; - err = memcpy_fromiovec(payload, msg->msg_iov, paylen); + err = memcpy_from_msg(payload, msg, paylen); if (err < 0) goto err_copy; } diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 59e785bfde65..d9149b68b9bc 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1170,7 +1170,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reset_transport_header(skb); skb_put(skb, len); - rc = memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len); + rc = memcpy_from_msg(skb_transport_header(skb), msg, len); if (rc) goto out_kfree_skb; -- GitLab From e169371823827dae1fd1d15bceb0fe5497c1a5ba Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 6 Apr 2014 21:28:01 -0400 Subject: [PATCH 6180/9457] switch ipxrtr_route_packet() from iovec to msghdr Signed-off-by: Al Viro --- include/net/ipx.h | 2 +- net/ipx/af_ipx.c | 3 +-- net/ipx/ipx_route.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/net/ipx.h b/include/net/ipx.h index 320f47b64a7a..e5cff6811b30 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -150,7 +150,7 @@ int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, unsigned char *node); void ipxrtr_del_routes(struct ipx_interface *intrfc); int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, - struct iovec *iov, size_t len, int noblock); + struct msghdr *msg, size_t len, int noblock); int ipxrtr_route_skb(struct sk_buff *skb); struct ipx_route *ipxrtr_lookup(__be32 net); int ipxrtr_ioctl(unsigned int cmd, void __user *arg); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 97dc4320ac15..f11ad1d95e0e 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1745,8 +1745,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN); } - rc = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, - flags & MSG_DONTWAIT); + rc = ipxrtr_route_packet(sk, usipx, msg, len, flags & MSG_DONTWAIT); if (rc >= 0) rc = len; out: diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c index 67e7ad3d46b1..3e2a32a9f3bd 100644 --- a/net/ipx/ipx_route.c +++ b/net/ipx/ipx_route.c @@ -165,7 +165,7 @@ int ipxrtr_route_skb(struct sk_buff *skb) * Route an outgoing frame from a socket. */ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, - struct iovec *iov, size_t len, int noblock) + struct msghdr *msg, size_t len, int noblock) { struct sk_buff *skb; struct ipx_sock *ipxs = ipx_sk(sk); @@ -229,7 +229,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN); ipx->ipx_dest.sock = usipx->sipx_port; - rc = memcpy_fromiovec(skb_put(skb, len), iov, len); + rc = memcpy_from_msg(skb_put(skb, len), msg, len); if (rc) { kfree_skb(skb); goto out_put; -- GitLab From 7eab8d9e8a722ca07bc785f73e21c3d3418defa6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 6 Apr 2014 21:51:23 -0400 Subject: [PATCH 6181/9457] new helper: memcpy_to_msg() Signed-off-by: Al Viro --- crypto/algif_hash.c | 2 +- include/linux/skbuff.h | 5 +++++ net/caif/caif_socket.c | 2 +- net/can/bcm.c | 2 +- net/can/raw.c | 2 +- net/decnet/af_decnet.c | 2 +- net/ipv4/tcp.c | 2 +- net/irda/af_irda.c | 2 +- net/packet/af_packet.c | 3 +-- 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 850246206b12..35c93ff11f35 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -174,7 +174,7 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, goto unlock; } - err = memcpy_toiovec(msg->msg_iov, ctx->result, len); + err = memcpy_to_msg(msg, ctx->result, len); unlock: release_sock(sk); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 97dc5f8123b3..d048347a010a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2692,6 +2692,11 @@ static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len) return memcpy_fromiovec(data, msg->msg_iov, len); } +static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len) +{ + return memcpy_toiovec(msg->msg_iov, data, len); +} + struct skb_checksum_ops { __wsum (*update)(const void *mem, int len, __wsum wsum); __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 230f14026c11..ac618b0b8a4f 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -418,7 +418,7 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock, } release_sock(sk); chunk = min_t(unsigned int, skb->len, size); - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + if (memcpy_to_msg(msg, skb->data, chunk)) { skb_queue_head(&sk->sk_receive_queue, skb); if (copied == 0) copied = -EFAULT; diff --git a/net/can/bcm.c b/net/can/bcm.c index b9a1f715df18..01671187e3fe 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -1555,7 +1555,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, if (skb->len < size) size = skb->len; - err = memcpy_toiovec(msg->msg_iov, skb->data, size); + err = memcpy_to_msg(msg, skb->data, size); if (err < 0) { skb_free_datagram(sk, skb); return err; diff --git a/net/can/raw.c b/net/can/raw.c index 0e4004fb6876..dfdcffbb1070 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -750,7 +750,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, else size = skb->len; - err = memcpy_toiovec(msg->msg_iov, skb->data, size); + err = memcpy_to_msg(msg, skb->data, size); if (err < 0) { skb_free_datagram(sk, skb); return err; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index e2e2e3cb9113..810228646de3 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -1760,7 +1760,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, if ((chunk + copied) > size) chunk = size - copied; - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + if (memcpy_to_msg(msg, skb->data, chunk)) { rv = -EFAULT; break; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c239f4740d10..435443bfc3c3 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1349,7 +1349,7 @@ static int tcp_recv_urg(struct sock *sk, struct msghdr *msg, int len, int flags) if (len > 0) { if (!(flags & MSG_TRUNC)) - err = memcpy_toiovec(msg->msg_iov, &c, 1); + err = memcpy_to_msg(msg, &c, 1); len = 1; } else msg->msg_flags |= MSG_TRUNC; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 9052462cf42a..568edc72d737 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1466,7 +1466,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } chunk = min_t(unsigned int, skb->len, size); - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + if (memcpy_to_msg(msg, skb->data, chunk)) { skb_queue_head(&sk->sk_receive_queue, skb); if (copied == 0) copied = -EFAULT; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 07ac95014ecb..108d7f381b87 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2949,8 +2949,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; } /* else everything is zero */ - err = memcpy_toiovec(msg->msg_iov, (void *)&vnet_hdr, - vnet_hdr_len); + err = memcpy_to_msg(msg, (void *)&vnet_hdr, vnet_hdr_len); if (err < 0) goto out_free; } -- GitLab From 9b067034d0cd4ee7bbbc317567f4e38ff7ca65c4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 7 Nov 2014 13:52:07 -0500 Subject: [PATCH 6182/9457] switch drivers/net/tun.c to ->read_iter() Signed-off-by: Al Viro --- drivers/net/tun.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ac53a7316ecd..405dfdf4f8c8 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1339,18 +1339,17 @@ static ssize_t tun_put_user(struct tun_struct *tun, } static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, - const struct iovec *iv, unsigned long segs, - ssize_t len, int noblock) + struct iov_iter *to, + int noblock) { struct sk_buff *skb; - ssize_t ret = 0; + ssize_t ret; int peeked, err, off = 0; - struct iov_iter iter; tun_debug(KERN_INFO, tun, "tun_do_read\n"); - if (!len) - return ret; + if (!iov_iter_count(to)) + return 0; if (tun->dev->reg_state != NETREG_REGISTERED) return -EIO; @@ -1359,37 +1358,27 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, &peeked, &off, &err); if (!skb) - return ret; + return 0; - iov_iter_init(&iter, READ, iv, segs, len); - ret = tun_put_user(tun, tfile, skb, &iter); + ret = tun_put_user(tun, tfile, skb, to); kfree_skb(skb); return ret; } -static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, - unsigned long count, loff_t pos) +static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; struct tun_file *tfile = file->private_data; struct tun_struct *tun = __tun_get(tfile); - ssize_t len, ret; + ssize_t len = iov_iter_count(to), ret; if (!tun) return -EBADFD; - len = iov_length(iv, count); - if (len < 0) { - ret = -EINVAL; - goto out; - } - - ret = tun_do_read(tun, tfile, iv, count, len, - file->f_flags & O_NONBLOCK); + ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; -out: tun_put(tun); return ret; } @@ -1471,6 +1460,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, { struct tun_file *tfile = container_of(sock, struct tun_file, socket); struct tun_struct *tun = __tun_get(tfile); + struct iov_iter to; int ret; if (!tun) @@ -1485,8 +1475,8 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len, - flags & MSG_DONTWAIT); + iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len); + ret = tun_do_read(tun, tfile, &to, flags & MSG_DONTWAIT); if (ret > total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; @@ -2242,8 +2232,8 @@ static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) static const struct file_operations tun_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .read = do_sync_read, - .aio_read = tun_chr_aio_read, + .read = new_sync_read, + .read_iter = tun_chr_read_iter, .write = do_sync_write, .aio_write = tun_chr_aio_write, .poll = tun_chr_poll, -- GitLab From 3af0bfe582322265745114f94d4b7e21e4d2a302 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 7 Nov 2014 14:13:53 -0500 Subject: [PATCH 6183/9457] switch macvtap to ->read_iter() Signed-off-by: Al Viro --- drivers/net/macvtap.c | 61 +++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 42a80d3de839..8f8004552d8e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -831,64 +831,55 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, } static ssize_t macvtap_do_read(struct macvtap_queue *q, - const struct iovec *iv, unsigned long segs, - unsigned long len, + struct iov_iter *to, int noblock) { DEFINE_WAIT(wait); struct sk_buff *skb; ssize_t ret = 0; - struct iov_iter iter; - while (len) { + if (!iov_iter_count(to)) + return 0; + + while (1) { if (!noblock) prepare_to_wait(sk_sleep(&q->sk), &wait, TASK_INTERRUPTIBLE); /* Read frames from the queue */ skb = skb_dequeue(&q->sk.sk_receive_queue); - if (!skb) { - if (noblock) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - /* Nothing to read, let's sleep */ - schedule(); - continue; + if (skb) + break; + if (noblock) { + ret = -EAGAIN; + break; } - iov_iter_init(&iter, READ, iv, segs, len); - ret = macvtap_put_user(q, skb, &iter); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + /* Nothing to read, let's sleep */ + schedule(); + } + if (skb) { + ret = macvtap_put_user(q, skb, to); kfree_skb(skb); - break; } - if (!noblock) finish_wait(sk_sleep(&q->sk), &wait); return ret; } -static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, - unsigned long count, loff_t pos) +static ssize_t macvtap_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; struct macvtap_queue *q = file->private_data; - ssize_t len, ret = 0; + ssize_t len = iov_iter_count(to), ret; - len = iov_length(iv, count); - if (len < 0) { - ret = -EINVAL; - goto out; - } - - ret = macvtap_do_read(q, iv, count, len, file->f_flags & O_NONBLOCK); + ret = macvtap_do_read(q, to, file->f_flags & O_NONBLOCK); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; -out: return ret; } @@ -1089,7 +1080,8 @@ static const struct file_operations macvtap_fops = { .owner = THIS_MODULE, .open = macvtap_open, .release = macvtap_release, - .aio_read = macvtap_aio_read, + .read = new_sync_read, + .read_iter = macvtap_read_iter, .aio_write = macvtap_aio_write, .poll = macvtap_poll, .llseek = no_llseek, @@ -1112,11 +1104,12 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, int flags) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); + struct iov_iter to; int ret; if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) return -EINVAL; - ret = macvtap_do_read(q, m->msg_iov, m->msg_iovlen, total_len, - flags & MSG_DONTWAIT); + iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len); + ret = macvtap_do_read(q, &to, flags & MSG_DONTWAIT); if (ret > total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; -- GitLab From a7750c3ef0122383901ae48396188aa4b861d32b Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Mon, 24 Nov 2014 14:03:38 +0530 Subject: [PATCH 6184/9457] i2c: s3c2410: Handle i2c sys_cfg register in i2c driver Let's handle i2c interrupt re-configuration in i2c driver. This will help us in removing some soc specific checks from machine files and will help in removing static iomapping of SYS register in exynos.c Also handle saving and restoring of SYS_I2C_CFG register during suspend and resume of i2c driver. Signed-off-by: Pankaj Dubey Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-s3c2410.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 65244774bfa3..09a6bace457e 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include @@ -87,6 +89,9 @@ /* Max time to wait for bus to become idle after a xfer (in us) */ #define S3C2410_IDLE_TIMEOUT 5000 +/* Exynos5 Sysreg offset */ +#define EXYNOS5_SYS_I2C_CFG 0x0234 + /* i2c controller state */ enum s3c24xx_i2c_state { STATE_IDLE, @@ -123,6 +128,8 @@ struct s3c24xx_i2c { #if defined(CONFIG_ARM_S3C24XX_CPUFREQ) struct notifier_block freq_transition; #endif + struct regmap *sysreg; + unsigned int sys_i2c_cfg; }; static struct platform_device_id s3c24xx_driver_ids[] = { @@ -1071,6 +1078,7 @@ static void s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c) { struct s3c2410_platform_i2c *pdata = i2c->pdata; + int id; if (!np) return; @@ -1080,6 +1088,21 @@ s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c) of_property_read_u32(np, "samsung,i2c-slave-addr", &pdata->slave_addr); of_property_read_u32(np, "samsung,i2c-max-bus-freq", (u32 *)&pdata->frequency); + /* + * Exynos5's legacy i2c controller and new high speed i2c + * controller have muxed interrupt sources. By default the + * interrupts for 4-channel HS-I2C controller are enabled. + * If nodes for first four channels of legacy i2c controller + * are available then re-configure the interrupts via the + * system register. + */ + id = of_alias_get_id(np, "i2c"); + i2c->sysreg = syscon_regmap_lookup_by_phandle(np, + "samsung,sysreg-phandle"); + if (IS_ERR(i2c->sysreg)) + return; + + regmap_update_bits(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, BIT(id), 0); } #else static void @@ -1260,6 +1283,9 @@ static int s3c24xx_i2c_suspend_noirq(struct device *dev) i2c->suspended = 1; + if (!IS_ERR(i2c->sysreg)) + regmap_read(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, &i2c->sys_i2c_cfg); + return 0; } @@ -1268,6 +1294,9 @@ static int s3c24xx_i2c_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); + if (!IS_ERR(i2c->sysreg)) + regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg); + clk_prepare_enable(i2c->clk); s3c24xx_i2c_init(i2c); clk_disable_unprepare(i2c->clk); -- GitLab From 3a654f975bf99165016fe257a3d2b4e6716e4931 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 19 Jun 2014 14:15:22 -0400 Subject: [PATCH 6185/9457] new helpers: skb_copy_datagram_from_iter() and zerocopy_sg_from_iter() Signed-off-by: Al Viro --- include/linux/skbuff.h | 3 ++ net/core/datagram.c | 116 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d048347a010a..a01cd9ad0b51 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2659,10 +2659,13 @@ static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen, int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, const struct iovec *from, int from_offset, int len); +int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, + struct iov_iter *from, int len); int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm, int offset, size_t count); int skb_copy_datagram_iter(const struct sk_buff *from, int offset, struct iov_iter *to, int size); +int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm); void skb_free_datagram(struct sock *sk, struct sk_buff *skb); void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); diff --git a/net/core/datagram.c b/net/core/datagram.c index 26391a3fe3e5..3ea038431ceb 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -572,6 +572,78 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, } EXPORT_SYMBOL(skb_copy_datagram_from_iovec); +int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, + struct iov_iter *from, + int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + struct sk_buff *frag_iter; + + /* Copy header. */ + if (copy > 0) { + if (copy > len) + copy = len; + if (copy_from_iter(skb->data + offset, copy, from) != copy) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + + /* Copy paged appendix. Hmm... why does this look so complicated? */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + WARN_ON(start > offset + len); + + end = start + skb_frag_size(frag); + if ((copy = end - offset) > 0) { + size_t copied; + + if (copy > len) + copy = len; + copied = copy_page_from_iter(skb_frag_page(frag), + frag->page_offset + offset - start, + copy, from); + if (copied != copy) + goto fault; + + if (!(len -= copy)) + return 0; + offset += copy; + } + start = end; + } + + skb_walk_frags(skb, frag_iter) { + int end; + + WARN_ON(start > offset + len); + + end = start + frag_iter->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_from_iter(frag_iter, + offset - start, + from, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; + } + if (!len) + return 0; + +fault: + return -EFAULT; +} +EXPORT_SYMBOL(skb_copy_datagram_from_iter); + /** * zerocopy_sg_from_iovec - Build a zerocopy datagram from an iovec * @skb: buffer to copy @@ -643,6 +715,50 @@ int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, } EXPORT_SYMBOL(zerocopy_sg_from_iovec); +int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) +{ + int len = iov_iter_count(from); + int copy = min_t(int, skb_headlen(skb), len); + int frag = 0; + + /* copy up to skb headlen */ + if (skb_copy_datagram_from_iter(skb, 0, from, copy)) + return -EFAULT; + + while (iov_iter_count(from)) { + struct page *pages[MAX_SKB_FRAGS]; + size_t start; + ssize_t copied; + unsigned long truesize; + int n = 0; + + if (frag == MAX_SKB_FRAGS) + return -EMSGSIZE; + + copied = iov_iter_get_pages(from, pages, ~0U, + MAX_SKB_FRAGS - frag, &start); + if (copied < 0) + return -EFAULT; + + iov_iter_advance(from, copied); + + truesize = PAGE_ALIGN(copied + start); + skb->data_len += copied; + skb->len += copied; + skb->truesize += truesize; + atomic_add(truesize, &skb->sk->sk_wmem_alloc); + while (copied) { + int size = min_t(int, copied, PAGE_SIZE - start); + skb_fill_page_desc(skb, frag++, pages[n], start, size); + start = 0; + copied -= size; + n++; + } + } + return 0; +} +EXPORT_SYMBOL(zerocopy_sg_from_iter); + static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, u8 __user *to, int len, __wsum *csump) -- GitLab From f5ff53b4d97c62e63ee2868fd4b8d7896643ee03 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 19 Jun 2014 15:36:49 -0400 Subject: [PATCH 6186/9457] {macvtap,tun}_get_user(): switch to iov_iter allows to switch macvtap and tun from ->aio_write() to ->write_iter() Signed-off-by: Al Viro --- drivers/net/macvtap.c | 44 +++++++++++++++++++++---------------------- drivers/net/tun.c | 44 +++++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 8f8004552d8e..22b4cf2fa108 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -640,12 +640,12 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, /* Get packet from user space buffer */ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, - const struct iovec *iv, unsigned long total_len, - size_t count, int noblock) + struct iov_iter *from, int noblock) { int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN); struct sk_buff *skb; struct macvlan_dev *vlan; + unsigned long total_len = iov_iter_count(from); unsigned long len = total_len; int err; struct virtio_net_hdr vnet_hdr = { 0 }; @@ -653,6 +653,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, int copylen = 0; bool zerocopy = false; size_t linear; + ssize_t n; if (q->flags & IFF_VNET_HDR) { vnet_hdr_len = q->vnet_hdr_sz; @@ -662,10 +663,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, goto err; len -= vnet_hdr_len; - err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, - sizeof(vnet_hdr)); - if (err < 0) + err = -EFAULT; + n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from); + if (n != sizeof(vnet_hdr)) goto err; + iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr)); if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 > vnet_hdr.hdr_len) @@ -680,17 +682,16 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, if (unlikely(len < ETH_HLEN)) goto err; - err = -EMSGSIZE; - if (unlikely(count > UIO_MAXIOV)) - goto err; - if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { + struct iov_iter i; + copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; if (copylen > good_linear) copylen = good_linear; linear = copylen; - if (iov_pages(iv, vnet_hdr_len + copylen, count) - <= MAX_SKB_FRAGS) + i = *from; + iov_iter_advance(&i, copylen); + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS) zerocopy = true; } @@ -708,10 +709,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, goto err; if (zerocopy) - err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); + err = zerocopy_sg_from_iter(skb, from); else { - err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, - len); + err = skb_copy_datagram_from_iter(skb, 0, from, len); if (!err && m && m->msg_control) { struct ubuf_info *uarg = m->msg_control; uarg->callback(uarg, false); @@ -764,16 +764,12 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, return err; } -static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv, - unsigned long count, loff_t pos) +static ssize_t macvtap_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; - ssize_t result = -ENOLINK; struct macvtap_queue *q = file->private_data; - result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count, - file->f_flags & O_NONBLOCK); - return result; + return macvtap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK); } /* Put packet to the user space buffer */ @@ -1081,8 +1077,9 @@ static const struct file_operations macvtap_fops = { .open = macvtap_open, .release = macvtap_release, .read = new_sync_read, + .write = new_sync_write, .read_iter = macvtap_read_iter, - .aio_write = macvtap_aio_write, + .write_iter = macvtap_write_iter, .poll = macvtap_poll, .llseek = no_llseek, .unlocked_ioctl = macvtap_ioctl, @@ -1095,8 +1092,9 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock); - return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen, - m->msg_flags & MSG_DONTWAIT); + struct iov_iter from; + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len); + return macvtap_get_user(q, m, &from, m->msg_flags & MSG_DONTWAIT); } static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock, diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 405dfdf4f8c8..4b743c612624 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1012,28 +1012,29 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, /* Get packet from user space buffer */ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, - void *msg_control, const struct iovec *iv, - size_t total_len, size_t count, int noblock) + void *msg_control, struct iov_iter *from, + int noblock) { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; + size_t total_len = iov_iter_count(from); size_t len = total_len, align = NET_SKB_PAD, linear; struct virtio_net_hdr gso = { 0 }; int good_linear; - int offset = 0; int copylen; bool zerocopy = false; int err; u32 rxhash; + ssize_t n; if (!(tun->flags & TUN_NO_PI)) { if (len < sizeof(pi)) return -EINVAL; len -= sizeof(pi); - if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + n = copy_from_iter(&pi, sizeof(pi), from); + if (n != sizeof(pi)) return -EFAULT; - offset += sizeof(pi); } if (tun->flags & TUN_VNET_HDR) { @@ -1041,7 +1042,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, return -EINVAL; len -= tun->vnet_hdr_sz; - if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + n = copy_from_iter(&gso, sizeof(gso), from); + if (n != sizeof(gso)) return -EFAULT; if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && @@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (gso.hdr_len > len) return -EINVAL; - offset += tun->vnet_hdr_sz; + iov_iter_advance(from, tun->vnet_hdr_sz); } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { @@ -1063,6 +1065,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, good_linear = SKB_MAX_HEAD(align); if (msg_control) { + struct iov_iter i = *from; + /* There are 256 bytes to be copied in skb, so there is * enough room for skb expand head in case it is used. * The rest of the buffer is mapped from userspace. @@ -1071,7 +1075,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (copylen > good_linear) copylen = good_linear; linear = copylen; - if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS) + iov_iter_advance(&i, copylen); + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS) zerocopy = true; } @@ -1091,9 +1096,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } if (zerocopy) - err = zerocopy_sg_from_iovec(skb, iv, offset, count); + err = zerocopy_sg_from_iter(skb, from); else { - err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); + err = skb_copy_datagram_from_iter(skb, 0, from, len); if (!err && msg_control) { struct ubuf_info *uarg = msg_control; uarg->callback(uarg, false); @@ -1207,8 +1212,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, return total_len; } -static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, - unsigned long count, loff_t pos) +static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct tun_struct *tun = tun_get(file); @@ -1218,10 +1222,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, if (!tun) return -EBADFD; - tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); - - result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count), - count, file->f_flags & O_NONBLOCK); + result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK); tun_put(tun); return result; @@ -1445,11 +1446,14 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, int ret; struct tun_file *tfile = container_of(sock, struct tun_file, socket); struct tun_struct *tun = __tun_get(tfile); + struct iov_iter from; if (!tun) return -EBADFD; - ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len, - m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); + + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len); + ret = tun_get_user(tun, tfile, m->msg_control, &from, + m->msg_flags & MSG_DONTWAIT); tun_put(tun); return ret; } @@ -2233,9 +2237,9 @@ static const struct file_operations tun_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = new_sync_read, + .write = new_sync_write, .read_iter = tun_chr_read_iter, - .write = do_sync_write, - .aio_write = tun_chr_aio_write, + .write_iter = tun_chr_write_iter, .poll = tun_chr_poll, .unlocked_ioctl = tun_chr_ioctl, #ifdef CONFIG_COMPAT -- GitLab From 195e952d03a797aa953f62ffe24ec58693e17ed8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 6 Nov 2014 00:56:48 -0500 Subject: [PATCH 6187/9457] kill zerocopy_sg_from_iovec() no users left Signed-off-by: Al Viro --- include/linux/skbuff.h | 2 -- net/core/datagram.c | 65 ++---------------------------------------- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a01cd9ad0b51..178cdbde82f0 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2661,8 +2661,6 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, int len); int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, struct iov_iter *from, int len); -int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *frm, - int offset, size_t count); int skb_copy_datagram_iter(const struct sk_buff *from, int offset, struct iov_iter *to, int size); int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm); diff --git a/net/core/datagram.c b/net/core/datagram.c index 3ea038431ceb..c4d832efebb8 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -645,76 +645,15 @@ int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, EXPORT_SYMBOL(skb_copy_datagram_from_iter); /** - * zerocopy_sg_from_iovec - Build a zerocopy datagram from an iovec + * zerocopy_sg_from_iter - Build a zerocopy datagram from an iov_iter * @skb: buffer to copy - * @from: io vector to copy from - * @offset: offset in the io vector to start copying from - * @count: amount of vectors to copy to buffer from + * @from: the source to copy from * * The function will first copy up to headlen, and then pin the userspace * pages and build frags through them. * * Returns 0, -EFAULT or -EMSGSIZE. - * Note: the iovec is not modified during the copy */ -int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, - int offset, size_t count) -{ - int len = iov_length(from, count) - offset; - int copy = min_t(int, skb_headlen(skb), len); - int size; - int i = 0; - - /* copy up to skb headlen */ - if (skb_copy_datagram_from_iovec(skb, 0, from, offset, copy)) - return -EFAULT; - - if (len == copy) - return 0; - - offset += copy; - while (count--) { - struct page *page[MAX_SKB_FRAGS]; - int num_pages; - unsigned long base; - unsigned long truesize; - - /* Skip over from offset and copied */ - if (offset >= from->iov_len) { - offset -= from->iov_len; - ++from; - continue; - } - len = from->iov_len - offset; - base = (unsigned long)from->iov_base + offset; - size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; - if (i + size > MAX_SKB_FRAGS) - return -EMSGSIZE; - num_pages = get_user_pages_fast(base, size, 0, &page[i]); - if (num_pages != size) { - release_pages(&page[i], num_pages, 0); - return -EFAULT; - } - truesize = size * PAGE_SIZE; - skb->data_len += len; - skb->len += len; - skb->truesize += truesize; - atomic_add(truesize, &skb->sk->sk_wmem_alloc); - while (len) { - int off = base & ~PAGE_MASK; - int size = min_t(int, len, PAGE_SIZE - off); - skb_fill_page_desc(skb, i, page[i], off, size); - base += size; - len -= size; - i++; - } - offset = 0; - ++from; - } - return 0; -} -EXPORT_SYMBOL(zerocopy_sg_from_iovec); - int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) { int len = iov_iter_count(from); -- GitLab From 8feb2fb2bb986c533e18037d3c45a5f779421992 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 6 Nov 2014 01:10:59 -0500 Subject: [PATCH 6188/9457] switch AF_PACKET and AF_UNIX to skb_copy_datagram_from_iter() ... and kill skb_copy_datagram_iovec() Signed-off-by: Al Viro --- include/linux/skbuff.h | 3 -- net/core/datagram.c | 88 +----------------------------------------- net/packet/af_packet.c | 11 ++++-- net/unix/af_unix.c | 11 ++++-- 4 files changed, 18 insertions(+), 95 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 178cdbde82f0..7691ad5b4771 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2656,9 +2656,6 @@ static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen, { return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov); } -int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, - const struct iovec *from, int from_offset, - int len); int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, struct iov_iter *from, int len); int skb_copy_datagram_iter(const struct sk_buff *from, int offset, diff --git a/net/core/datagram.c b/net/core/datagram.c index c4d832efebb8..b6e303b0f01f 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -480,98 +480,14 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, EXPORT_SYMBOL(skb_copy_datagram_iter); /** - * skb_copy_datagram_from_iovec - Copy a datagram from an iovec. + * skb_copy_datagram_from_iter - Copy a datagram from an iov_iter. * @skb: buffer to copy * @offset: offset in the buffer to start copying to - * @from: io vector to copy to - * @from_offset: offset in the io vector to start copying from + * @from: the copy source * @len: amount of data to copy to buffer from iovec * * Returns 0 or -EFAULT. - * Note: the iovec is not modified during the copy. */ -int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, - const struct iovec *from, int from_offset, - int len) -{ - int start = skb_headlen(skb); - int i, copy = start - offset; - struct sk_buff *frag_iter; - - /* Copy header. */ - if (copy > 0) { - if (copy > len) - copy = len; - if (memcpy_fromiovecend(skb->data + offset, from, from_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from_offset += copy; - } - - /* Copy paged appendix. Hmm... why does this look so complicated? */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - WARN_ON(start > offset + len); - - end = start + skb_frag_size(frag); - if ((copy = end - offset) > 0) { - int err; - u8 *vaddr; - struct page *page = skb_frag_page(frag); - - if (copy > len) - copy = len; - vaddr = kmap(page); - err = memcpy_fromiovecend(vaddr + frag->page_offset + - offset - start, - from, from_offset, copy); - kunmap(page); - if (err) - goto fault; - - if (!(len -= copy)) - return 0; - offset += copy; - from_offset += copy; - } - start = end; - } - - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_from_iovec(frag_iter, - offset - start, - from, - from_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from_offset += copy; - } - start = end; - } - if (!len) - return 0; - -fault: - return -EFAULT; -} -EXPORT_SYMBOL(skb_copy_datagram_from_iovec); - int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, struct iov_iter *from, int len) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 108d7f381b87..dfb148e9fdaa 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2408,6 +2408,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) unsigned short gso_type = 0; int hlen, tlen; int extra_len = 0; + struct iov_iter from; + ssize_t n; + + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); /* * Get and verify the address. @@ -2446,8 +2450,9 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) len -= vnet_hdr_len; - err = memcpy_from_msg((void *)&vnet_hdr, msg, vnet_hdr_len); - if (err < 0) + err = -EFAULT; + n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from); + if (n != vnet_hdr_len) goto out_unlock; if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && @@ -2517,7 +2522,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) } /* Returns -EFAULT on error */ - err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); + err = skb_copy_datagram_from_iter(skb, offset, &from, len); if (err) goto out_free; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5eee625d113f..4450d6226602 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1459,6 +1459,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, struct scm_cookie tmp_scm; int max_level; int data_len = 0; + struct iov_iter from; + + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); if (NULL == siocb->scm) siocb->scm = &tmp_scm; @@ -1516,7 +1519,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, skb_put(skb, len - data_len); skb->data_len = data_len; skb->len = len; - err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len); + err = skb_copy_datagram_from_iter(skb, 0, &from, len); if (err) goto out_free; @@ -1638,6 +1641,9 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, bool fds_sent = false; int max_level; int data_len; + struct iov_iter from; + + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); if (NULL == siocb->scm) siocb->scm = &tmp_scm; @@ -1694,8 +1700,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, skb_put(skb, size - data_len); skb->data_len = data_len; skb->len = size; - err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, - sent, size); + err = skb_copy_datagram_from_iter(skb, 0, &from, size); if (err) { kfree_skb(skb); goto out_err; -- GitLab From e0eb093e794452791b0f932a0120f410f614ad82 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 15 Nov 2014 01:11:23 -0500 Subject: [PATCH 6189/9457] switch sctp_user_addto_chunk() and sctp_datamsg_from_user() to passing iov_iter Signed-off-by: Al Viro --- include/net/sctp/structs.h | 6 +++--- net/sctp/chunk.c | 9 ++++----- net/sctp/sm_make_chunk.c | 16 ++++++++-------- net/sctp/socket.c | 5 ++++- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 806e3b5b3351..2bb2fcf5b11f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -531,7 +531,7 @@ struct sctp_datamsg { struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, struct sctp_sndrcvinfo *, - struct msghdr *, int len); + struct iov_iter *); void sctp_datamsg_free(struct sctp_datamsg *); void sctp_datamsg_put(struct sctp_datamsg *); void sctp_chunk_fail(struct sctp_chunk *, int error); @@ -647,8 +647,8 @@ struct sctp_chunk { void sctp_chunk_hold(struct sctp_chunk *); void sctp_chunk_put(struct sctp_chunk *); -int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, - struct iovec *data); +int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, + struct iov_iter *from); void sctp_chunk_free(struct sctp_chunk *); void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); struct sctp_chunk *sctp_chunkify(struct sk_buff *, diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 158701da2d31..a3380917f197 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -164,7 +164,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu */ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, struct sctp_sndrcvinfo *sinfo, - struct msghdr *msgh, int msg_len) + struct iov_iter *from) { int max, whole, i, offset, over, err; int len, first_len; @@ -172,6 +172,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, struct sctp_chunk *chunk; struct sctp_datamsg *msg; struct list_head *pos, *temp; + size_t msg_len = iov_iter_count(from); __u8 frag; msg = sctp_datamsg_new(GFP_KERNEL); @@ -279,12 +280,10 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, goto errout; } - err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); + err = sctp_user_addto_chunk(chunk, len, from); if (err < 0) goto errout_chunk_free; - offset += len; - /* Put the chunk->skb back into the form expected by send. */ __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr - (__u8 *)chunk->skb->data); @@ -317,7 +316,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, goto errout; } - err = sctp_user_addto_chunk(chunk, offset, over, msgh->msg_iov); + err = sctp_user_addto_chunk(chunk, over, from); /* Put the chunk->skb back into the form expected by send. */ __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index e49bccebb0cc..e49e231cef52 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1491,26 +1491,26 @@ static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk, * chunk is not big enough. * Returns a kernel err value. */ -int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, - struct iovec *data) +int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len, + struct iov_iter *from) { - __u8 *target; - int err = 0; + void *target; + ssize_t copied; /* Make room in chunk for data. */ target = skb_put(chunk->skb, len); /* Copy data (whole iovec) into chunk */ - if ((err = memcpy_fromiovecend(target, data, off, len))) - goto out; + copied = copy_from_iter(target, len, from); + if (copied != len) + return -EFAULT; /* Adjust the chunk length field. */ chunk->chunk_hdr->length = htons(ntohs(chunk->chunk_hdr->length) + len); chunk->chunk_end = skb_tail_pointer(chunk->skb); -out: - return err; + return 0; } /* Helper function to assign a TSN if needed. This assumes that both diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 85e0b653edd7..0397ac9fd98c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1609,6 +1609,9 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, __u16 sinfo_flags = 0; long timeo; int err; + struct iov_iter from; + + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len); err = 0; sp = sctp_sk(sk); @@ -1947,7 +1950,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, } /* Break the message into multiple chunks of maximum size. */ - datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); + datamsg = sctp_datamsg_from_user(asoc, sinfo, &from); if (IS_ERR(datamsg)) { err = PTR_ERR(datamsg); goto out_free; -- GitLab From 562640f3c3fb64fca24253868dab6e900e305c46 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 15 Nov 2014 01:13:43 -0500 Subject: [PATCH 6190/9457] tipc_sendmsg(): pass msghdr instead of its ->msg_iov Signed-off-by: Al Viro --- net/tipc/socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e91809182c28..2d4b2fa7d628 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -700,7 +700,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, * tipc_sendmcast - send multicast message * @sock: socket structure * @seq: destination address - * @iov: message data to send + * @msg: message to send * @dsz: total length of message data * @timeo: timeout to wait for wakeup * @@ -708,7 +708,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, * Returns the number of bytes sent on success, or errno */ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, - struct iovec *iov, size_t dsz, long timeo) + struct msghdr *msg, size_t dsz, long timeo) { struct sock *sk = sock->sk; struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; @@ -727,7 +727,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, new_mtu: mtu = tipc_bclink_get_mtu(); - rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); + rc = tipc_msg_build(mhdr, msg->msg_iov, 0, dsz, mtu, &buf); if (unlikely(rc < 0)) return rc; @@ -951,7 +951,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); if (dest->addrtype == TIPC_ADDR_MCAST) { - rc = tipc_sendmcast(sock, seq, iov, dsz, timeo); + rc = tipc_sendmcast(sock, seq, m, dsz, timeo); goto exit; } else if (dest->addrtype == TIPC_ADDR_NAME) { u32 type = dest->addr.name.name.type; -- GitLab From 45dcc687f764f89e1e7c41dace52b105494e5dbb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 15 Nov 2014 01:16:27 -0500 Subject: [PATCH 6191/9457] tipc_msg_build(): pass msghdr instead of its ->msg_iov Signed-off-by: Al Viro --- net/tipc/msg.c | 8 ++++---- net/tipc/msg.h | 2 +- net/tipc/socket.c | 7 +++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ec18076e81ec..9155496b8a8a 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -162,14 +162,14 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) /** * tipc_msg_build - create buffer chain containing specified header and data * @mhdr: Message header, to be prepended to data - * @iov: User data + * @m: User message * @offset: Posision in iov to start copying from * @dsz: Total length of user data * @pktmax: Max packet size that can be used * @chain: Buffer or chain of buffers to be returned to caller * Returns message data size or errno: -ENOMEM, -EFAULT */ -int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, +int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, int dsz, int pktmax , struct sk_buff **chain) { int mhsz = msg_hdr_sz(mhdr); @@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, skb_copy_to_linear_data(buf, mhdr, mhsz); pktpos = buf->data + mhsz; TIPC_SKB_CB(buf)->chain_sz = 1; - if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz)) + if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz)) return dsz; rc = -EFAULT; goto error; @@ -223,7 +223,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, if (drem < pktrem) pktrem = drem; - if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) { + if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) { rc = -EFAULT; goto error; } diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 0ea7b695ac4d..d7d2ba2afe6c 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -743,7 +743,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu); bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode); -int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov, +int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, int dsz, int mtu , struct sk_buff **chain); struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain); diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 2d4b2fa7d628..b3415a78da2e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -727,7 +727,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, new_mtu: mtu = tipc_bclink_get_mtu(); - rc = tipc_msg_build(mhdr, msg->msg_iov, 0, dsz, mtu, &buf); + rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf); if (unlikely(rc < 0)) return rc; @@ -905,7 +905,6 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; struct tipc_sock *tsk = tipc_sk(sk); struct tipc_msg *mhdr = &tsk->phdr; - struct iovec *iov = m->msg_iov; u32 dnode, dport; struct sk_buff *buf; struct tipc_name_seq *seq = &dest->addr.nameseq; @@ -982,7 +981,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, new_mtu: mtu = tipc_node_get_mtu(dnode, tsk->ref); - rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf); + rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf); if (rc < 0) goto exit; @@ -1094,7 +1093,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, next: mtu = tsk->max_pkt; send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); - rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf); + rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf); if (unlikely(rc < 0)) goto exit; do { -- GitLab From 0f7db23a07af5de22940f08c3f88a0741d4df0bc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 04:05:34 -0500 Subject: [PATCH 6192/9457] vmci_transport: switch ->enqeue_dgram, ->enqueue_stream and ->dequeue_stream to msghdr Signed-off-by: Al Viro --- include/net/af_vsock.h | 6 +++--- net/vmw_vsock/af_vsock.c | 6 +++--- net/vmw_vsock/vmci_transport.c | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 428277869400..0d87674fb775 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -103,14 +103,14 @@ struct vsock_transport { int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk, struct msghdr *msg, size_t len, int flags); int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *, - struct iovec *, size_t len); + struct msghdr *, size_t len); bool (*dgram_allow)(u32 cid, u32 port); /* STREAM. */ /* TODO: stream_bind() */ - ssize_t (*stream_dequeue)(struct vsock_sock *, struct iovec *, + ssize_t (*stream_dequeue)(struct vsock_sock *, struct msghdr *, size_t len, int flags); - ssize_t (*stream_enqueue)(struct vsock_sock *, struct iovec *, + ssize_t (*stream_enqueue)(struct vsock_sock *, struct msghdr *, size_t len); s64 (*stream_has_data)(struct vsock_sock *); s64 (*stream_has_space)(struct vsock_sock *); diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 85d232bed87d..1d0e39c9a3e2 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1013,7 +1013,7 @@ static int vsock_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, goto out; } - err = transport->dgram_enqueue(vsk, remote_addr, msg->msg_iov, len); + err = transport->dgram_enqueue(vsk, remote_addr, msg, len); out: release_sock(sk); @@ -1617,7 +1617,7 @@ static int vsock_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, */ written = transport->stream_enqueue( - vsk, msg->msg_iov, + vsk, msg, len - total_written); if (written < 0) { err = -ENOMEM; @@ -1739,7 +1739,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb, break; read = transport->stream_dequeue( - vsk, msg->msg_iov, + vsk, msg, len - copied, flags); if (read < 0) { err = -ENOMEM; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a57ddef7d5af..c1c038952973 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -1697,7 +1697,7 @@ static int vmci_transport_dgram_bind(struct vsock_sock *vsk, static int vmci_transport_dgram_enqueue( struct vsock_sock *vsk, struct sockaddr_vm *remote_addr, - struct iovec *iov, + struct msghdr *msg, size_t len) { int err; @@ -1714,7 +1714,7 @@ static int vmci_transport_dgram_enqueue( if (!dg) return -ENOMEM; - memcpy_fromiovec(VMCI_DG_PAYLOAD(dg), iov, len); + memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len); dg->dst = vmci_make_handle(remote_addr->svm_cid, remote_addr->svm_port); @@ -1835,22 +1835,22 @@ static int vmci_transport_connect(struct vsock_sock *vsk) static ssize_t vmci_transport_stream_dequeue( struct vsock_sock *vsk, - struct iovec *iov, + struct msghdr *msg, size_t len, int flags) { if (flags & MSG_PEEK) - return vmci_qpair_peekv(vmci_trans(vsk)->qpair, iov, len, 0); + return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); else - return vmci_qpair_dequev(vmci_trans(vsk)->qpair, iov, len, 0); + return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); } static ssize_t vmci_transport_stream_enqueue( struct vsock_sock *vsk, - struct iovec *iov, + struct msghdr *msg, size_t len) { - return vmci_qpair_enquev(vmci_trans(vsk)->qpair, iov, len, 0); + return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); } static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) -- GitLab From 7424ce65065852bdf7a040bf2490da4a8fc4b464 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 07:01:29 -0500 Subject: [PATCH 6193/9457] [atm] switch vcc_sendmsg() to copy_from_iter() ... and make it handle multi-segment iovecs - deals with that "fix this later" issue for free. A bit of shame, really - it had been there since 2.3.15pre3 when the whole thing went into the tree, practically a historical artefact by now... Signed-off-by: Al Viro --- net/atm/common.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/net/atm/common.c b/net/atm/common.c index 9cd1ccae9a11..f59112944c91 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -570,15 +570,16 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, } int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, - size_t total_len) + size_t size) { struct sock *sk = sock->sk; DEFINE_WAIT(wait); struct atm_vcc *vcc; struct sk_buff *skb; int eff, error; - const void __user *buff; - int size; + struct iov_iter from; + + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size); lock_sock(sk); if (sock->state != SS_CONNECTED) { @@ -589,12 +590,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, error = -EISCONN; goto out; } - if (m->msg_iovlen != 1) { - error = -ENOSYS; /* fix this later @@@ */ - goto out; - } - buff = m->msg_iov->iov_base; - size = m->msg_iov->iov_len; vcc = ATM_SD(sock); if (test_bit(ATM_VF_RELEASED, &vcc->flags) || test_bit(ATM_VF_CLOSE, &vcc->flags) || @@ -607,7 +602,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, error = 0; goto out; } - if (size < 0 || size > vcc->qos.txtp.max_sdu) { + if (size > vcc->qos.txtp.max_sdu) { error = -EMSGSIZE; goto out; } @@ -639,7 +634,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, goto out; skb->dev = NULL; /* for paths shared with net_device interfaces */ ATM_SKB(skb)->atm_options = vcc->atm_options; - if (copy_from_user(skb_put(skb, size), buff, size)) { + if (copy_from_iter(skb_put(skb, size), size, &from) != size) { kfree_skb(skb); error = -EFAULT; goto out; -- GitLab From c310e72c89926e06138e4881f21e4c8da3e7ef18 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 09:21:14 -0500 Subject: [PATCH 6194/9457] rds: switch ->inc_copy_to_user() to passing iov_iter instances get considerably simpler from that... Signed-off-by: Al Viro --- net/rds/ib.h | 3 +-- net/rds/ib_recv.c | 37 +++++++++++-------------------------- net/rds/iw.h | 3 +-- net/rds/iw_recv.c | 37 +++++++++++-------------------------- net/rds/message.c | 35 ++++++++--------------------------- net/rds/rds.h | 6 ++---- net/rds/recv.c | 5 +++-- net/rds/tcp.h | 3 +-- net/rds/tcp_recv.c | 38 +++++++++----------------------------- 9 files changed, 47 insertions(+), 120 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 7280ab8810c2..c36d713229e0 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -316,8 +316,7 @@ int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); void rds_ib_recv_free_caches(struct rds_ib_connection *ic); void rds_ib_recv_refill(struct rds_connection *conn, int prefill); void rds_ib_inc_free(struct rds_incoming *inc); -int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, - size_t size); +int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context); void rds_ib_recv_tasklet_fn(unsigned long data); void rds_ib_recv_init_ring(struct rds_ib_connection *ic); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index d67de453c35a..1b981a4e42c2 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -472,15 +472,12 @@ static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache return head; } -int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, - size_t size) +int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) { struct rds_ib_incoming *ibinc; struct rds_page_frag *frag; - struct iovec *iov = first_iov; unsigned long to_copy; unsigned long frag_off = 0; - unsigned long iov_off = 0; int copied = 0; int ret; u32 len; @@ -489,37 +486,25 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item); len = be32_to_cpu(inc->i_hdr.h_len); - while (copied < size && copied < len) { + while (iov_iter_count(to) && copied < len) { if (frag_off == RDS_FRAG_SIZE) { frag = list_entry(frag->f_item.next, struct rds_page_frag, f_item); frag_off = 0; } - while (iov_off == iov->iov_len) { - iov_off = 0; - iov++; - } - - to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off); - to_copy = min_t(size_t, to_copy, size - copied); + to_copy = min_t(unsigned long, iov_iter_count(to), + RDS_FRAG_SIZE - frag_off); to_copy = min_t(unsigned long, to_copy, len - copied); - rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " - "[%p, %u] + %lu\n", - to_copy, iov->iov_base, iov->iov_len, iov_off, - sg_page(&frag->f_sg), frag->f_sg.offset, frag_off); - /* XXX needs + offset for multiple recvs per page */ - ret = rds_page_copy_to_user(sg_page(&frag->f_sg), - frag->f_sg.offset + frag_off, - iov->iov_base + iov_off, - to_copy); - if (ret) { - copied = ret; - break; - } + rds_stats_add(s_copy_to_user, to_copy); + ret = copy_page_to_iter(sg_page(&frag->f_sg), + frag->f_sg.offset + frag_off, + to_copy, + to); + if (ret != to_copy) + return -EFAULT; - iov_off += to_copy; frag_off += to_copy; copied += to_copy; } diff --git a/net/rds/iw.h b/net/rds/iw.h index 04ce3b193f79..cbe6674e31ee 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -325,8 +325,7 @@ int rds_iw_recv(struct rds_connection *conn); int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, gfp_t page_gfp, int prefill); void rds_iw_inc_free(struct rds_incoming *inc); -int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, - size_t size); +int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context); void rds_iw_recv_tasklet_fn(unsigned long data); void rds_iw_recv_init_ring(struct rds_iw_connection *ic); diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index aa8bf6786008..a66d1794b2d0 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -303,15 +303,12 @@ void rds_iw_inc_free(struct rds_incoming *inc) BUG_ON(atomic_read(&rds_iw_allocation) < 0); } -int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, - size_t size) +int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) { struct rds_iw_incoming *iwinc; struct rds_page_frag *frag; - struct iovec *iov = first_iov; unsigned long to_copy; unsigned long frag_off = 0; - unsigned long iov_off = 0; int copied = 0; int ret; u32 len; @@ -320,37 +317,25 @@ int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, frag = list_entry(iwinc->ii_frags.next, struct rds_page_frag, f_item); len = be32_to_cpu(inc->i_hdr.h_len); - while (copied < size && copied < len) { + while (iov_iter_count(to) && copied < len) { if (frag_off == RDS_FRAG_SIZE) { frag = list_entry(frag->f_item.next, struct rds_page_frag, f_item); frag_off = 0; } - while (iov_off == iov->iov_len) { - iov_off = 0; - iov++; - } - - to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off); - to_copy = min_t(size_t, to_copy, size - copied); + to_copy = min_t(unsigned long, iov_iter_count(to), + RDS_FRAG_SIZE - frag_off); to_copy = min_t(unsigned long, to_copy, len - copied); - rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " - "[%p, %lu] + %lu\n", - to_copy, iov->iov_base, iov->iov_len, iov_off, - frag->f_page, frag->f_offset, frag_off); - /* XXX needs + offset for multiple recvs per page */ - ret = rds_page_copy_to_user(frag->f_page, - frag->f_offset + frag_off, - iov->iov_base + iov_off, - to_copy); - if (ret) { - copied = ret; - break; - } + rds_stats_add(s_copy_to_user, to_copy); + ret = copy_page_to_iter(frag->f_page, + frag->f_offset + frag_off, + to_copy, + to); + if (ret != to_copy) + return -EFAULT; - iov_off += to_copy; frag_off += to_copy; copied += to_copy; } diff --git a/net/rds/message.c b/net/rds/message.c index aba232f9f308..7a546e089a57 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -325,14 +325,11 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, return ret; } -int rds_message_inc_copy_to_user(struct rds_incoming *inc, - struct iovec *first_iov, size_t size) +int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) { struct rds_message *rm; - struct iovec *iov; struct scatterlist *sg; unsigned long to_copy; - unsigned long iov_off; unsigned long vec_off; int copied; int ret; @@ -341,36 +338,20 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, rm = container_of(inc, struct rds_message, m_inc); len = be32_to_cpu(rm->m_inc.i_hdr.h_len); - iov = first_iov; - iov_off = 0; sg = rm->data.op_sg; vec_off = 0; copied = 0; - while (copied < size && copied < len) { - while (iov_off == iov->iov_len) { - iov_off = 0; - iov++; - } - - to_copy = min(iov->iov_len - iov_off, sg->length - vec_off); - to_copy = min_t(size_t, to_copy, size - copied); + while (iov_iter_count(to) && copied < len) { + to_copy = min(iov_iter_count(to), sg->length - vec_off); to_copy = min_t(unsigned long, to_copy, len - copied); - rdsdebug("copying %lu bytes to user iov [%p, %zu] + %lu to " - "sg [%p, %u, %u] + %lu\n", - to_copy, iov->iov_base, iov->iov_len, iov_off, - sg_page(sg), sg->offset, sg->length, vec_off); - - ret = rds_page_copy_to_user(sg_page(sg), sg->offset + vec_off, - iov->iov_base + iov_off, - to_copy); - if (ret) { - copied = ret; - break; - } + rds_stats_add(s_copy_to_user, to_copy); + ret = copy_page_to_iter(sg_page(sg), sg->offset + vec_off, + to_copy, to); + if (ret != to_copy) + return -EFAULT; - iov_off += to_copy; vec_off += to_copy; copied += to_copy; diff --git a/net/rds/rds.h b/net/rds/rds.h index 48f8ffc60f8f..b22dad91697c 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -431,8 +431,7 @@ struct rds_transport { int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); int (*recv)(struct rds_connection *conn); - int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, - size_t size); + int (*inc_copy_to_user)(struct rds_incoming *inc, struct iov_iter *to); void (*inc_free)(struct rds_incoming *inc); int (*cm_handle_connect)(struct rdma_cm_id *cm_id, @@ -667,8 +666,7 @@ int rds_message_add_extension(struct rds_header *hdr, int rds_message_next_extension(struct rds_header *hdr, unsigned int *pos, void *buf, unsigned int *buflen); int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); -int rds_message_inc_copy_to_user(struct rds_incoming *inc, - struct iovec *first_iov, size_t size); +int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); void rds_message_inc_free(struct rds_incoming *inc); void rds_message_addref(struct rds_message *rm); void rds_message_put(struct rds_message *rm); diff --git a/net/rds/recv.c b/net/rds/recv.c index bd82522534fc..47d7b1029b33 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -404,6 +404,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); struct rds_incoming *inc = NULL; + struct iov_iter to; /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ timeo = sock_rcvtimeo(sk, nonblock); @@ -449,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, rdsdebug("copying inc %p from %pI4:%u to user\n", inc, &inc->i_conn->c_faddr, ntohs(inc->i_hdr.h_sport)); - ret = inc->i_conn->c_trans->inc_copy_to_user(inc, msg->msg_iov, - size); + iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size); + ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to); if (ret < 0) break; diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 65637491f728..0dbdd37162da 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -69,8 +69,7 @@ void rds_tcp_recv_exit(void); void rds_tcp_data_ready(struct sock *sk); int rds_tcp_recv(struct rds_connection *conn); void rds_tcp_inc_free(struct rds_incoming *inc); -int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, - size_t size); +int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to); /* tcp_send.c */ void rds_tcp_xmit_prepare(struct rds_connection *conn); diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 9ae6e0a264ec..fbc5ef88bc0e 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -59,50 +59,30 @@ void rds_tcp_inc_free(struct rds_incoming *inc) /* * this is pretty lame, but, whatever. */ -int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, - size_t size) +int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) { struct rds_tcp_incoming *tinc; - struct iovec *iov, tmp; struct sk_buff *skb; - unsigned long to_copy, skb_off; int ret = 0; - if (size == 0) + if (!iov_iter_count(to)) goto out; tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); - iov = first_iov; - tmp = *iov; skb_queue_walk(&tinc->ti_skb_list, skb) { - skb_off = 0; - while (skb_off < skb->len) { - while (tmp.iov_len == 0) { - iov++; - tmp = *iov; - } - - to_copy = min(tmp.iov_len, size); + unsigned long to_copy, skb_off; + for (skb_off = 0; skb_off < skb->len; skb_off += to_copy) { + to_copy = iov_iter_count(to); to_copy = min(to_copy, skb->len - skb_off); - rdsdebug("ret %d size %zu skb %p skb_off %lu " - "skblen %d iov_base %p iov_len %zu cpy %lu\n", - ret, size, skb, skb_off, skb->len, - tmp.iov_base, tmp.iov_len, to_copy); - - /* modifies tmp as it copies */ - if (skb_copy_datagram_iovec(skb, skb_off, &tmp, - to_copy)) { - ret = -EFAULT; - goto out; - } + if (skb_copy_datagram_iter(skb, skb_off, to, to_copy)) + return -EFAULT; rds_stats_add(s_copy_to_user, to_copy); - size -= to_copy; ret += to_copy; - skb_off += to_copy; - if (size == 0) + + if (!iov_iter_count(to)) goto out; } } -- GitLab From 083735f4b01b703184c0e11c2e384b2c60a8aea4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Nov 2014 09:31:08 -0500 Subject: [PATCH 6195/9457] rds: switch rds_message_copy_from_user() to iov_iter Signed-off-by: Al Viro --- net/rds/message.c | 42 ++++++++++++------------------------------ net/rds/rds.h | 3 +-- net/rds/send.c | 4 +++- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/net/rds/message.c b/net/rds/message.c index 7a546e089a57..ff2202218187 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -264,64 +264,46 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in return rm; } -int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, - size_t total_len) +int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from) { unsigned long to_copy; - unsigned long iov_off; unsigned long sg_off; - struct iovec *iov; struct scatterlist *sg; int ret = 0; - rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); + rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from)); /* * now allocate and copy in the data payload. */ sg = rm->data.op_sg; - iov = first_iov; - iov_off = 0; sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ - while (total_len) { + while (iov_iter_count(from)) { if (!sg_page(sg)) { - ret = rds_page_remainder_alloc(sg, total_len, + ret = rds_page_remainder_alloc(sg, iov_iter_count(from), GFP_HIGHUSER); if (ret) - goto out; + return ret; rm->data.op_nents++; sg_off = 0; } - while (iov_off == iov->iov_len) { - iov_off = 0; - iov++; - } - - to_copy = min(iov->iov_len - iov_off, sg->length - sg_off); - to_copy = min_t(size_t, to_copy, total_len); - - rdsdebug("copying %lu bytes from user iov [%p, %zu] + %lu to " - "sg [%p, %u, %u] + %lu\n", - to_copy, iov->iov_base, iov->iov_len, iov_off, - (void *)sg_page(sg), sg->offset, sg->length, sg_off); + to_copy = min_t(unsigned long, iov_iter_count(from), + sg->length - sg_off); - ret = rds_page_copy_from_user(sg_page(sg), sg->offset + sg_off, - iov->iov_base + iov_off, - to_copy); - if (ret) - goto out; + rds_stats_add(s_copy_from_user, to_copy); + ret = copy_page_from_iter(sg_page(sg), sg->offset + sg_off, + to_copy, from); + if (ret != to_copy) + return -EFAULT; - iov_off += to_copy; - total_len -= to_copy; sg_off += to_copy; if (sg_off == sg->length) sg++; } -out: return ret; } diff --git a/net/rds/rds.h b/net/rds/rds.h index b22dad91697c..c2a5eef41343 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -656,8 +656,7 @@ rds_conn_connecting(struct rds_connection *conn) /* message.c */ struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); -int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, - size_t total_len); +int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from); struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); void rds_message_populate_header(struct rds_header *hdr, __be16 sport, __be16 dport, u64 seq); diff --git a/net/rds/send.c b/net/rds/send.c index 0a64541020b0..4de62ead1c71 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -934,7 +934,9 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int queued = 0, allocated_mr = 0; int nonblock = msg->msg_flags & MSG_DONTWAIT; long timeo = sock_sndtimeo(sk, nonblock); + struct iov_iter from; + iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len); /* Mirror Linux UDP mirror of BSD error message compatibility */ /* XXX: Perhaps MSG_MORE someday */ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) { @@ -982,7 +984,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, ret = -ENOMEM; goto out; } - ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); + ret = rds_message_copy_from_user(rm, &from); if (ret) goto out; } -- GitLab From f841afb17476f485900bb6213cf93a64a7dc303f Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 16 Oct 2014 15:11:44 +0200 Subject: [PATCH 6196/9457] extcon: Implement OF-based extcon lookup properly Platform bus is not the only way to have extcon devices, so current implementation of of_extcon_get_extcon_dev() is broken. Also using parent device node only to get device name is quite ugly. This patch reimplements of_extcon_get_extcon_dev() to do exactly the same as extcon_get_extcon_dev() but instead of comparing names, compare node pointers. Signed-off-by: Tomasz Figa [mszyprow: simplified the code] Signed-off-by: Marek Szyprowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-class.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c index 4c2f2c543bb7..043dcd9946c9 100644 --- a/drivers/extcon/extcon-class.c +++ b/drivers/extcon/extcon-class.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -997,13 +998,16 @@ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) return ERR_PTR(-ENODEV); } - edev = extcon_get_extcon_dev(node->name); - if (!edev) { - dev_err(dev, "unable to get extcon device : %s\n", node->name); - return ERR_PTR(-ENODEV); + mutex_lock(&extcon_dev_list_lock); + list_for_each_entry(edev, &extcon_dev_list, entry) { + if (edev->dev.parent && edev->dev.parent->of_node == node) { + mutex_unlock(&extcon_dev_list_lock); + return edev; + } } + mutex_unlock(&extcon_dev_list_lock); - return edev; + return ERR_PTR(-EPROBE_DEFER); } #else struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) -- GitLab From c22159a2d50e677ada77fff164d7682adb3be40f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 22 Oct 2014 10:45:40 +0200 Subject: [PATCH 6197/9457] extcon: max77693: Fix cable name of JIG_UART_ON When JIG was set to "boot on" mode, the UART connection did not work because it was assigned to Dock-Car cable (path: audio), not JIG-UART-ON cable. This was introduced in 39bf369e4ed3 ("extcon: max77693: Add support dock device and buttons") while adding dock features. Assign the JIG-UART-ON back to UART path. Signed-off-by: Krzysztof Kozlowski [cw00.choi: Modify the patch name to remove specific board name] Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 490e27475bac..89ef36f71f60 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -232,7 +232,7 @@ static const char *max77693_extcon_cable[] = { [EXTCON_CABLE_JIG_USB_ON] = "JIG-USB-ON", [EXTCON_CABLE_JIG_USB_OFF] = "JIG-USB-OFF", [EXTCON_CABLE_JIG_UART_OFF] = "JIG-UART-OFF", - [EXTCON_CABLE_JIG_UART_ON] = "Dock-Car", + [EXTCON_CABLE_JIG_UART_ON] = "JIG-UART-ON", [EXTCON_CABLE_DOCK_SMART] = "Dock-Smart", [EXTCON_CABLE_DOCK_DESK] = "Dock-Desk", [EXTCON_CABLE_DOCK_AUDIO] = "Dock-Audio", @@ -532,9 +532,6 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, extcon_set_cable_state(info->edev, "Dock-Smart", attached); extcon_set_cable_state(info->edev, "MHL", attached); goto out; - case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* Dock-Car */ - strcpy(dock_name, "Dock-Car"); - break; case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ strcpy(dock_name, "Dock-Desk"); break; @@ -669,6 +666,11 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info, strcpy(cable_name, "JIG-UART-OFF"); path = CONTROL1_SW_UART; break; + case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* ADC_JIG_UART_ON */ + /* PATH:AP_UART */ + strcpy(cable_name, "JIG-UART-ON"); + path = CONTROL1_SW_UART; + break; default: dev_err(info->dev, "failed to detect %s jig cable\n", attached ? "attached" : "detached"); @@ -708,13 +710,13 @@ static int max77693_muic_adc_handler(struct max77693_muic_info *info) case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: + case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* JIG */ ret = max77693_muic_jig_handler(info, cable_type, attached); if (ret < 0) return ret; break; case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */ - case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* Dock-Car */ case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */ /* -- GitLab From 6ab0b1171b068a1be871184fc704074ad7e5b9e7 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Nov 2014 16:28:09 +0100 Subject: [PATCH 6198/9457] extcon: max14577: Fix obvious typo in company name in copyright Fix a typo in name of company in copyright comment. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max14577.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index 7309743d0da1..e6c0c9b13d31 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c @@ -1,7 +1,7 @@ /* * extcon-max14577.c - MAX14577/77836 extcon driver to support MUIC * - * Copyright (C) 2013,2014 Samsung Electrnoics + * Copyright (C) 2013,2014 Samsung Electronics * Chanwoo Choi * Krzysztof Kozlowski * -- GitLab From 12c27156fdd36d5ac789e96206f4893066375c71 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 21 Nov 2014 18:58:49 +0200 Subject: [PATCH 6199/9457] ath10k: don't rebuild all the time There are better ways to get the kernel information, use the utsname and omit the version code entirely since it's duplicate. The version magic is rather useless anyway Signed-off-by: Johannes Berg Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index a8f5a72ba259..f10721da4980 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -17,9 +17,8 @@ #include #include -#include -#include #include +#include #include "core.h" #include "debug.h" @@ -866,8 +865,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, sizeof(dump_data->fw_ver)); - dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE); - strlcpy(dump_data->kernel_ver, VERMAGIC_STRING, + dump_data->kernel_ver_code = 0; + strlcpy(dump_data->kernel_ver, init_utsname()->release, sizeof(dump_data->kernel_ver)); dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); -- GitLab From 3be004c3aa4341c7c2461b37612a3a7a3323579d Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 23 Sep 2014 14:17:19 -0700 Subject: [PATCH 6200/9457] ath10k: add ATH10K_DBG_WMI_PRINT debug level There are not many of these messages producted by the firmware, but they are generally fairly useful, so make it easy to print them with a separate debug level. kvalo: fix commit log, rename debug level Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.h | 1 + drivers/net/wireless/ath/ath10k/wmi.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 0c934a8378db..815d325ab930 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -35,6 +35,7 @@ enum ath10k_debug_mask { ATH10K_DBG_BMI = 0x00000400, ATH10K_DBG_REGULATORY = 0x00000800, ATH10K_DBG_TESTMODE = 0x00001000, + ATH10K_DBG_WMI_PRINT = 0x00002000, ATH10K_DBG_ANY = 0xffffffff, }; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c2bc8282f6cb..c300a53ed6b0 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2261,7 +2261,7 @@ static void ath10k_wmi_event_debug_print(struct ath10k *ar, /* the last byte is always reserved for the null character */ buf[i] = '\0'; - ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf); + ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf); } static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) -- GitLab From ef24d749f2c8713d333b3e3c4b1d84fbc25bc133 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Mon, 24 Nov 2014 22:31:23 +0800 Subject: [PATCH 6201/9457] usb: gadget: ss_ep_in_comp_desc can be static drivers/usb/gadget/legacy/printer.c:222:34: sparse: symbol 'ss_ep_in_comp_desc' was not declared. Should it be static? drivers/usb/gadget/legacy/printer.c:234:34: sparse: symbol 'ss_ep_out_comp_desc' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/printer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index e0cf1b0d471d..90545980542f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -219,7 +219,7 @@ static struct usb_endpoint_descriptor ss_ep_in_desc = { .wMaxPacketSize = cpu_to_le16(1024), }; -struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { +static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { .bLength = sizeof(ss_ep_in_comp_desc), .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, }; @@ -231,7 +231,7 @@ static struct usb_endpoint_descriptor ss_ep_out_desc = { .wMaxPacketSize = cpu_to_le16(1024), }; -struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { +static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { .bLength = sizeof(ss_ep_out_comp_desc), .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, }; -- GitLab From 6cd6159d4b1695427105d4b8b2e355e1d0509ff4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 22 Nov 2014 15:56:47 +0100 Subject: [PATCH 6202/9457] usb: dwc3: return error code from the most recent call Copy-paste error from the previous block of error handling code. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e,e1; @@ if (IS_ERR(e)) { ... ( ret = PTR_ERR(e); | * ret = PTR_ERR(e1); ) ... return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-st.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index c7602b5362ad..4a1a543deeda 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -243,7 +243,7 @@ static int st_dwc3_probe(struct platform_device *pdev) dwc3_data->rstc_rst = devm_reset_control_get(dev, "softreset"); if (IS_ERR(dwc3_data->rstc_rst)) { dev_err(&pdev->dev, "could not get reset controller\n"); - ret = PTR_ERR(dwc3_data->rstc_pwrdn); + ret = PTR_ERR(dwc3_data->rstc_rst); goto undo_powerdown; } -- GitLab From 690b0543a813b0ecfc51b0374c0ce6c8275435f0 Mon Sep 17 00:00:00 2001 From: Maisa Roponen Date: Mon, 24 Nov 2014 09:54:17 +0200 Subject: [PATCH 6203/9457] Documentation: fix formatting to make 's' happy "That letter [the last s] is sad because all the others have those things [=] below them and it does not." This patch fixes the tragedy so all the letters can be happy again. Signed-off-by: Maisa Roponen [The author being 4 years old needed some assistance] Signed-off-by: Tero Roponen Signed-off-by: Jonathan Corbet --- Documentation/filesystems/proc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index eb8a10e22f7c..aae9dd13c91f 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1272,7 +1272,7 @@ softirq. 1.9 Ext4 file system parameters ------------------------------- +------------------------------- Information about mounted ext4 file systems can be found in /proc/fs/ext4. Each mounted filesystem will have a directory in -- GitLab From 5d4a5e770d97d87082067886e7097c920b338da5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 20 Nov 2014 12:44:32 +0800 Subject: [PATCH 6204/9457] crypto: user - Allow get request with empty driver name Currently all get requests with an empty driver name fail with EINVAL. Since most users actually want to supply an empty driver name this patch removes this check. Signed-off-by: Herbert Xu --- crypto/crypto_user.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index e2a34feec7a4..0bb30ac3a323 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -201,10 +201,7 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) return -EINVAL; - if (!p->cru_driver_name[0]) - return -EINVAL; - - alg = crypto_alg_match(p, 1); + alg = crypto_alg_match(p, 0); if (!alg) return -ENOENT; -- GitLab From 5d26a105b5a73e5635eae0629b42fa0a90e07b7b Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 20 Nov 2014 17:05:53 -0800 Subject: [PATCH 6205/9457] crypto: prefix module autoloading with "crypto-" This prefixes all crypto module loading with "crypto-" so we never run the risk of exposing module auto-loading to userspace via a crypto API, as demonstrated by Mathias Krause: https://lkml.org/lkml/2013/3/4/70 Signed-off-by: Kees Cook Signed-off-by: Herbert Xu --- arch/arm/crypto/aes_glue.c | 4 ++-- arch/arm/crypto/sha1_glue.c | 2 +- arch/arm/crypto/sha1_neon_glue.c | 2 +- arch/arm/crypto/sha512_neon_glue.c | 4 ++-- arch/arm64/crypto/aes-ce-ccm-glue.c | 2 +- arch/arm64/crypto/aes-glue.c | 8 ++++---- arch/powerpc/crypto/sha1.c | 2 +- arch/s390/crypto/aes_s390.c | 2 +- arch/s390/crypto/des_s390.c | 4 ++-- arch/s390/crypto/ghash_s390.c | 2 +- arch/s390/crypto/sha1_s390.c | 2 +- arch/s390/crypto/sha256_s390.c | 4 ++-- arch/s390/crypto/sha512_s390.c | 4 ++-- arch/sparc/crypto/aes_glue.c | 2 +- arch/sparc/crypto/camellia_glue.c | 2 +- arch/sparc/crypto/crc32c_glue.c | 2 +- arch/sparc/crypto/des_glue.c | 2 +- arch/sparc/crypto/md5_glue.c | 2 +- arch/sparc/crypto/sha1_glue.c | 2 +- arch/sparc/crypto/sha256_glue.c | 4 ++-- arch/sparc/crypto/sha512_glue.c | 4 ++-- arch/x86/crypto/aes_glue.c | 4 ++-- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/crypto/blowfish_glue.c | 4 ++-- arch/x86/crypto/camellia_aesni_avx2_glue.c | 4 ++-- arch/x86/crypto/camellia_aesni_avx_glue.c | 4 ++-- arch/x86/crypto/camellia_glue.c | 4 ++-- arch/x86/crypto/cast5_avx_glue.c | 2 +- arch/x86/crypto/cast6_avx_glue.c | 2 +- arch/x86/crypto/crc32-pclmul_glue.c | 4 ++-- arch/x86/crypto/crc32c-intel_glue.c | 4 ++-- arch/x86/crypto/crct10dif-pclmul_glue.c | 4 ++-- arch/x86/crypto/des3_ede_glue.c | 8 ++++---- arch/x86/crypto/ghash-clmulni-intel_glue.c | 2 +- arch/x86/crypto/salsa20_glue.c | 4 ++-- arch/x86/crypto/serpent_avx2_glue.c | 4 ++-- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/crypto/sha1_ssse3_glue.c | 2 +- arch/x86/crypto/sha256_ssse3_glue.c | 4 ++-- arch/x86/crypto/sha512_ssse3_glue.c | 4 ++-- arch/x86/crypto/twofish_avx_glue.c | 2 +- arch/x86/crypto/twofish_glue.c | 4 ++-- arch/x86/crypto/twofish_glue_3way.c | 4 ++-- crypto/842.c | 1 + crypto/aes_generic.c | 2 +- crypto/ansi_cprng.c | 2 +- crypto/anubis.c | 1 + crypto/api.c | 4 ++-- crypto/arc4.c | 1 + crypto/blowfish_generic.c | 2 +- crypto/camellia_generic.c | 2 +- crypto/cast5_generic.c | 2 +- crypto/cast6_generic.c | 2 +- crypto/ccm.c | 4 ++-- crypto/crc32.c | 1 + crypto/crc32c_generic.c | 2 +- crypto/crct10dif_generic.c | 2 +- crypto/crypto_null.c | 6 +++--- crypto/ctr.c | 2 +- crypto/deflate.c | 2 +- crypto/des_generic.c | 2 +- crypto/fcrypt.c | 1 + crypto/gcm.c | 6 +++--- crypto/ghash-generic.c | 2 +- crypto/khazad.c | 1 + crypto/krng.c | 2 +- crypto/lz4.c | 1 + crypto/lz4hc.c | 1 + crypto/lzo.c | 1 + crypto/md4.c | 2 +- crypto/md5.c | 1 + crypto/michael_mic.c | 1 + crypto/rmd128.c | 1 + crypto/rmd160.c | 1 + crypto/rmd256.c | 1 + crypto/rmd320.c | 1 + crypto/salsa20_generic.c | 2 +- crypto/seed.c | 1 + crypto/serpent_generic.c | 4 ++-- crypto/sha1_generic.c | 2 +- crypto/sha256_generic.c | 4 ++-- crypto/sha512_generic.c | 4 ++-- crypto/tea.c | 4 ++-- crypto/tgr192.c | 4 ++-- crypto/twofish_generic.c | 2 +- crypto/wp512.c | 4 ++-- crypto/zlib.c | 1 + drivers/crypto/padlock-aes.c | 2 +- drivers/crypto/padlock-sha.c | 8 ++++---- drivers/crypto/qat/qat_common/adf_ctl_drv.c | 3 ++- drivers/crypto/ux500/cryp/cryp_core.c | 4 ++-- drivers/crypto/ux500/hash/hash_core.c | 8 ++++---- drivers/s390/crypto/ap_bus.c | 3 ++- include/linux/crypto.h | 13 +++++++++++++ 95 files changed, 155 insertions(+), 123 deletions(-) diff --git a/arch/arm/crypto/aes_glue.c b/arch/arm/crypto/aes_glue.c index 3003fa1f6fb4..0409b8f89782 100644 --- a/arch/arm/crypto/aes_glue.c +++ b/arch/arm/crypto/aes_glue.c @@ -93,6 +93,6 @@ module_exit(aes_fini); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm (ASM)"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("aes"); -MODULE_ALIAS("aes-asm"); +MODULE_ALIAS_CRYPTO("aes"); +MODULE_ALIAS_CRYPTO("aes-asm"); MODULE_AUTHOR("David McCullough "); diff --git a/arch/arm/crypto/sha1_glue.c b/arch/arm/crypto/sha1_glue.c index 84f2a756588b..e31b0440c613 100644 --- a/arch/arm/crypto/sha1_glue.c +++ b/arch/arm/crypto/sha1_glue.c @@ -171,5 +171,5 @@ module_exit(sha1_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (ARM)"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); MODULE_AUTHOR("David McCullough "); diff --git a/arch/arm/crypto/sha1_neon_glue.c b/arch/arm/crypto/sha1_neon_glue.c index 6f1b411b1d55..0b0083757d47 100644 --- a/arch/arm/crypto/sha1_neon_glue.c +++ b/arch/arm/crypto/sha1_neon_glue.c @@ -194,4 +194,4 @@ module_exit(sha1_neon_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, NEON accelerated"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); diff --git a/arch/arm/crypto/sha512_neon_glue.c b/arch/arm/crypto/sha512_neon_glue.c index 0d2758ff5e12..f3452c66059d 100644 --- a/arch/arm/crypto/sha512_neon_glue.c +++ b/arch/arm/crypto/sha512_neon_glue.c @@ -301,5 +301,5 @@ module_exit(sha512_neon_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, NEON accelerated"); -MODULE_ALIAS("sha512"); -MODULE_ALIAS("sha384"); +MODULE_ALIAS_CRYPTO("sha512"); +MODULE_ALIAS_CRYPTO("sha384"); diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c index 9e6cdde9b43d..0156a268e163 100644 --- a/arch/arm64/crypto/aes-ce-ccm-glue.c +++ b/arch/arm64/crypto/aes-ce-ccm-glue.c @@ -294,4 +294,4 @@ module_exit(aes_mod_exit); MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("ccm(aes)"); +MODULE_ALIAS_CRYPTO("ccm(aes)"); diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index 79cd911ef88c..5f63a791b2fb 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -38,10 +38,10 @@ MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions"); #define aes_xts_encrypt neon_aes_xts_encrypt #define aes_xts_decrypt neon_aes_xts_decrypt MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON"); -MODULE_ALIAS("ecb(aes)"); -MODULE_ALIAS("cbc(aes)"); -MODULE_ALIAS("ctr(aes)"); -MODULE_ALIAS("xts(aes)"); +MODULE_ALIAS_CRYPTO("ecb(aes)"); +MODULE_ALIAS_CRYPTO("cbc(aes)"); +MODULE_ALIAS_CRYPTO("ctr(aes)"); +MODULE_ALIAS_CRYPTO("xts(aes)"); #endif MODULE_AUTHOR("Ard Biesheuvel "); diff --git a/arch/powerpc/crypto/sha1.c b/arch/powerpc/crypto/sha1.c index f9e8b9491efc..0f88c7b41119 100644 --- a/arch/powerpc/crypto/sha1.c +++ b/arch/powerpc/crypto/sha1.c @@ -154,4 +154,4 @@ module_exit(sha1_powerpc_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); -MODULE_ALIAS("sha1-powerpc"); +MODULE_ALIAS_CRYPTO("sha1-powerpc"); diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 23223cd63e54..1f272b24fc0b 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -979,7 +979,7 @@ static void __exit aes_s390_fini(void) module_init(aes_s390_init); module_exit(aes_s390_fini); -MODULE_ALIAS("aes-all"); +MODULE_ALIAS_CRYPTO("aes-all"); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("GPL"); diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index 7acb77f7ef1a..9e05cc453a40 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c @@ -619,8 +619,8 @@ static void __exit des_s390_exit(void) module_init(des_s390_init); module_exit(des_s390_exit); -MODULE_ALIAS("des"); -MODULE_ALIAS("des3_ede"); +MODULE_ALIAS_CRYPTO("des"); +MODULE_ALIAS_CRYPTO("des3_ede"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c index d43485d142e9..7940dc90e80b 100644 --- a/arch/s390/crypto/ghash_s390.c +++ b/arch/s390/crypto/ghash_s390.c @@ -160,7 +160,7 @@ static void __exit ghash_mod_exit(void) module_init(ghash_mod_init); module_exit(ghash_mod_exit); -MODULE_ALIAS("ghash"); +MODULE_ALIAS_CRYPTO("ghash"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GHASH Message Digest Algorithm, s390 implementation"); diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index a1b3a9dc9d8a..5b2bee323694 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c @@ -103,6 +103,6 @@ static void __exit sha1_s390_fini(void) module_init(sha1_s390_init); module_exit(sha1_s390_fini); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index 9b853809a492..b74ff158108c 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c @@ -143,7 +143,7 @@ static void __exit sha256_s390_fini(void) module_init(sha256_s390_init); module_exit(sha256_s390_fini); -MODULE_ALIAS("sha256"); -MODULE_ALIAS("sha224"); +MODULE_ALIAS_CRYPTO("sha256"); +MODULE_ALIAS_CRYPTO("sha224"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm"); diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c index 32a81383b69c..0c36989ba182 100644 --- a/arch/s390/crypto/sha512_s390.c +++ b/arch/s390/crypto/sha512_s390.c @@ -86,7 +86,7 @@ static struct shash_alg sha512_alg = { } }; -MODULE_ALIAS("sha512"); +MODULE_ALIAS_CRYPTO("sha512"); static int sha384_init(struct shash_desc *desc) { @@ -126,7 +126,7 @@ static struct shash_alg sha384_alg = { } }; -MODULE_ALIAS("sha384"); +MODULE_ALIAS_CRYPTO("sha384"); static int __init init(void) { diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index df922f52d76d..705408766ab0 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c @@ -499,6 +499,6 @@ module_exit(aes_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); -MODULE_ALIAS("aes"); +MODULE_ALIAS_CRYPTO("aes"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c index 888f6260b4ec..641f55cb61c3 100644 --- a/arch/sparc/crypto/camellia_glue.c +++ b/arch/sparc/crypto/camellia_glue.c @@ -322,6 +322,6 @@ module_exit(camellia_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); -MODULE_ALIAS("aes"); +MODULE_ALIAS_CRYPTO("aes"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c index 5162fad912ce..d1064e46efe8 100644 --- a/arch/sparc/crypto/crc32c_glue.c +++ b/arch/sparc/crypto/crc32c_glue.c @@ -176,6 +176,6 @@ module_exit(crc32c_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); -MODULE_ALIAS("crc32c"); +MODULE_ALIAS_CRYPTO("crc32c"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c index 3065bc61f9d3..d11500972994 100644 --- a/arch/sparc/crypto/des_glue.c +++ b/arch/sparc/crypto/des_glue.c @@ -532,6 +532,6 @@ module_exit(des_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); -MODULE_ALIAS("des"); +MODULE_ALIAS_CRYPTO("des"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c index 09a9ea1dfb69..64c7ff5f72a9 100644 --- a/arch/sparc/crypto/md5_glue.c +++ b/arch/sparc/crypto/md5_glue.c @@ -185,6 +185,6 @@ module_exit(md5_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); -MODULE_ALIAS("md5"); +MODULE_ALIAS_CRYPTO("md5"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c index 6cd5f29e1e0d..1b3e47accc74 100644 --- a/arch/sparc/crypto/sha1_glue.c +++ b/arch/sparc/crypto/sha1_glue.c @@ -180,6 +180,6 @@ module_exit(sha1_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c index 04f555ab2680..41f27cca2a22 100644 --- a/arch/sparc/crypto/sha256_glue.c +++ b/arch/sparc/crypto/sha256_glue.c @@ -237,7 +237,7 @@ module_exit(sha256_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 opcode accelerated"); -MODULE_ALIAS("sha224"); -MODULE_ALIAS("sha256"); +MODULE_ALIAS_CRYPTO("sha224"); +MODULE_ALIAS_CRYPTO("sha256"); #include "crop_devid.c" diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c index f04d1994d19a..9fff88541b8c 100644 --- a/arch/sparc/crypto/sha512_glue.c +++ b/arch/sparc/crypto/sha512_glue.c @@ -222,7 +222,7 @@ module_exit(sha512_sparc64_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 opcode accelerated"); -MODULE_ALIAS("sha384"); -MODULE_ALIAS("sha512"); +MODULE_ALIAS_CRYPTO("sha384"); +MODULE_ALIAS_CRYPTO("sha512"); #include "crop_devid.c" diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c index aafe8ce0d65d..e26984f7ab8d 100644 --- a/arch/x86/crypto/aes_glue.c +++ b/arch/x86/crypto/aes_glue.c @@ -66,5 +66,5 @@ module_exit(aes_fini); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, asm optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("aes"); -MODULE_ALIAS("aes-asm"); +MODULE_ALIAS_CRYPTO("aes"); +MODULE_ALIAS_CRYPTO("aes-asm"); diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index bcebf754466c..ae855f4f64b7 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -1546,4 +1546,4 @@ module_exit(aesni_exit); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("aes"); +MODULE_ALIAS_CRYPTO("aes"); diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c index 8af519ed73d1..17c05531dfd1 100644 --- a/arch/x86/crypto/blowfish_glue.c +++ b/arch/x86/crypto/blowfish_glue.c @@ -478,5 +478,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Blowfish Cipher Algorithm, asm optimized"); -MODULE_ALIAS("blowfish"); -MODULE_ALIAS("blowfish-asm"); +MODULE_ALIAS_CRYPTO("blowfish"); +MODULE_ALIAS_CRYPTO("blowfish-asm"); diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c index 4209a76fcdaa..9a07fafe3831 100644 --- a/arch/x86/crypto/camellia_aesni_avx2_glue.c +++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c @@ -582,5 +582,5 @@ module_exit(camellia_aesni_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, AES-NI/AVX2 optimized"); -MODULE_ALIAS("camellia"); -MODULE_ALIAS("camellia-asm"); +MODULE_ALIAS_CRYPTO("camellia"); +MODULE_ALIAS_CRYPTO("camellia-asm"); diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c index 87a041a10f4a..ed38d959add6 100644 --- a/arch/x86/crypto/camellia_aesni_avx_glue.c +++ b/arch/x86/crypto/camellia_aesni_avx_glue.c @@ -574,5 +574,5 @@ module_exit(camellia_aesni_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, AES-NI/AVX optimized"); -MODULE_ALIAS("camellia"); -MODULE_ALIAS("camellia-asm"); +MODULE_ALIAS_CRYPTO("camellia"); +MODULE_ALIAS_CRYPTO("camellia-asm"); diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c index c171dcbf192d..5c8b6266a394 100644 --- a/arch/x86/crypto/camellia_glue.c +++ b/arch/x86/crypto/camellia_glue.c @@ -1725,5 +1725,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, asm optimized"); -MODULE_ALIAS("camellia"); -MODULE_ALIAS("camellia-asm"); +MODULE_ALIAS_CRYPTO("camellia"); +MODULE_ALIAS_CRYPTO("camellia-asm"); diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c index e57e20ab5e0b..60ada677a928 100644 --- a/arch/x86/crypto/cast5_avx_glue.c +++ b/arch/x86/crypto/cast5_avx_glue.c @@ -491,4 +491,4 @@ module_exit(cast5_exit); MODULE_DESCRIPTION("Cast5 Cipher Algorithm, AVX optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("cast5"); +MODULE_ALIAS_CRYPTO("cast5"); diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c index 09f3677393e4..0160f68a57ff 100644 --- a/arch/x86/crypto/cast6_avx_glue.c +++ b/arch/x86/crypto/cast6_avx_glue.c @@ -611,4 +611,4 @@ module_exit(cast6_exit); MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("cast6"); +MODULE_ALIAS_CRYPTO("cast6"); diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c index 9d014a74ef96..1937fc1d8763 100644 --- a/arch/x86/crypto/crc32-pclmul_glue.c +++ b/arch/x86/crypto/crc32-pclmul_glue.c @@ -197,5 +197,5 @@ module_exit(crc32_pclmul_mod_fini); MODULE_AUTHOR("Alexander Boyko "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("crc32"); -MODULE_ALIAS("crc32-pclmul"); +MODULE_ALIAS_CRYPTO("crc32"); +MODULE_ALIAS_CRYPTO("crc32-pclmul"); diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index 6812ad98355c..28640c3d6af7 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c @@ -280,5 +280,5 @@ MODULE_AUTHOR("Austin Zhang , Kent Liu "); MODULE_DESCRIPTION("T10 DIF CRC calculation accelerated with PCLMULQDQ."); MODULE_LICENSE("GPL"); -MODULE_ALIAS("crct10dif"); -MODULE_ALIAS("crct10dif-pclmul"); +MODULE_ALIAS_CRYPTO("crct10dif"); +MODULE_ALIAS_CRYPTO("crct10dif-pclmul"); diff --git a/arch/x86/crypto/des3_ede_glue.c b/arch/x86/crypto/des3_ede_glue.c index 0e9c0668fe4e..38a14f818ef1 100644 --- a/arch/x86/crypto/des3_ede_glue.c +++ b/arch/x86/crypto/des3_ede_glue.c @@ -502,8 +502,8 @@ module_exit(des3_ede_x86_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Triple DES EDE Cipher Algorithm, asm optimized"); -MODULE_ALIAS("des3_ede"); -MODULE_ALIAS("des3_ede-asm"); -MODULE_ALIAS("des"); -MODULE_ALIAS("des-asm"); +MODULE_ALIAS_CRYPTO("des3_ede"); +MODULE_ALIAS_CRYPTO("des3_ede-asm"); +MODULE_ALIAS_CRYPTO("des"); +MODULE_ALIAS_CRYPTO("des-asm"); MODULE_AUTHOR("Jussi Kivilinna "); diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 88bb7ba8b175..8253d85aa165 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -341,4 +341,4 @@ module_exit(ghash_pclmulqdqni_mod_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GHASH Message Digest Algorithm, " "acclerated by PCLMULQDQ-NI"); -MODULE_ALIAS("ghash"); +MODULE_ALIAS_CRYPTO("ghash"); diff --git a/arch/x86/crypto/salsa20_glue.c b/arch/x86/crypto/salsa20_glue.c index 5e8e67739bb5..399a29d067d6 100644 --- a/arch/x86/crypto/salsa20_glue.c +++ b/arch/x86/crypto/salsa20_glue.c @@ -119,5 +119,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm (optimized assembly version)"); -MODULE_ALIAS("salsa20"); -MODULE_ALIAS("salsa20-asm"); +MODULE_ALIAS_CRYPTO("salsa20"); +MODULE_ALIAS_CRYPTO("salsa20-asm"); diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c index 2fae489b1524..437e47a4d302 100644 --- a/arch/x86/crypto/serpent_avx2_glue.c +++ b/arch/x86/crypto/serpent_avx2_glue.c @@ -558,5 +558,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX2 optimized"); -MODULE_ALIAS("serpent"); -MODULE_ALIAS("serpent-asm"); +MODULE_ALIAS_CRYPTO("serpent"); +MODULE_ALIAS_CRYPTO("serpent-asm"); diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c index ff4870870972..7e217398b4eb 100644 --- a/arch/x86/crypto/serpent_avx_glue.c +++ b/arch/x86/crypto/serpent_avx_glue.c @@ -617,4 +617,4 @@ module_exit(serpent_exit); MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("serpent"); +MODULE_ALIAS_CRYPTO("serpent"); diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c index 8c95f8637306..bf025adaea01 100644 --- a/arch/x86/crypto/serpent_sse2_glue.c +++ b/arch/x86/crypto/serpent_sse2_glue.c @@ -618,4 +618,4 @@ module_exit(serpent_sse2_exit); MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("serpent"); +MODULE_ALIAS_CRYPTO("serpent"); diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c index 74d16ef707c7..6c20fe04a738 100644 --- a/arch/x86/crypto/sha1_ssse3_glue.c +++ b/arch/x86/crypto/sha1_ssse3_glue.c @@ -278,4 +278,4 @@ module_exit(sha1_ssse3_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c index f248546da1ca..4dc100d82902 100644 --- a/arch/x86/crypto/sha256_ssse3_glue.c +++ b/arch/x86/crypto/sha256_ssse3_glue.c @@ -318,5 +318,5 @@ module_exit(sha256_ssse3_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated"); -MODULE_ALIAS("sha256"); -MODULE_ALIAS("sha224"); +MODULE_ALIAS_CRYPTO("sha256"); +MODULE_ALIAS_CRYPTO("sha224"); diff --git a/arch/x86/crypto/sha512_ssse3_glue.c b/arch/x86/crypto/sha512_ssse3_glue.c index 8626b03e83b7..26a5898a6f26 100644 --- a/arch/x86/crypto/sha512_ssse3_glue.c +++ b/arch/x86/crypto/sha512_ssse3_glue.c @@ -326,5 +326,5 @@ module_exit(sha512_ssse3_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, Supplemental SSE3 accelerated"); -MODULE_ALIAS("sha512"); -MODULE_ALIAS("sha384"); +MODULE_ALIAS_CRYPTO("sha512"); +MODULE_ALIAS_CRYPTO("sha384"); diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c index 4e3c665be129..1ac531ea9bcc 100644 --- a/arch/x86/crypto/twofish_avx_glue.c +++ b/arch/x86/crypto/twofish_avx_glue.c @@ -579,4 +579,4 @@ module_exit(twofish_exit); MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("twofish"); +MODULE_ALIAS_CRYPTO("twofish"); diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c index 0a5202303501..77e06c2da83d 100644 --- a/arch/x86/crypto/twofish_glue.c +++ b/arch/x86/crypto/twofish_glue.c @@ -96,5 +96,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Twofish Cipher Algorithm, asm optimized"); -MODULE_ALIAS("twofish"); -MODULE_ALIAS("twofish-asm"); +MODULE_ALIAS_CRYPTO("twofish"); +MODULE_ALIAS_CRYPTO("twofish-asm"); diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c index 13e63b3e1dfb..56d8a08ee479 100644 --- a/arch/x86/crypto/twofish_glue_3way.c +++ b/arch/x86/crypto/twofish_glue_3way.c @@ -495,5 +495,5 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized"); -MODULE_ALIAS("twofish"); -MODULE_ALIAS("twofish-asm"); +MODULE_ALIAS_CRYPTO("twofish"); +MODULE_ALIAS_CRYPTO("twofish-asm"); diff --git a/crypto/842.c b/crypto/842.c index 65c7a89cfa09..b48f4f108c47 100644 --- a/crypto/842.c +++ b/crypto/842.c @@ -180,3 +180,4 @@ module_exit(nx842_mod_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("842 Compression Algorithm"); +MODULE_ALIAS_CRYPTO("842"); diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c index fd0d6b454975..9b3c54c1cbe8 100644 --- a/crypto/aes_generic.c +++ b/crypto/aes_generic.c @@ -1474,4 +1474,4 @@ module_exit(aes_fini); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS("aes"); +MODULE_ALIAS_CRYPTO("aes"); diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 666f1962a160..b4485a108389 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -476,4 +476,4 @@ module_param(dbg, int, 0); MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)"); module_init(prng_mod_init); module_exit(prng_mod_fini); -MODULE_ALIAS("stdrng"); +MODULE_ALIAS_CRYPTO("stdrng"); diff --git a/crypto/anubis.c b/crypto/anubis.c index 008c8a4fb67c..4bb187c2a902 100644 --- a/crypto/anubis.c +++ b/crypto/anubis.c @@ -704,3 +704,4 @@ module_exit(anubis_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Anubis Cryptographic Algorithm"); +MODULE_ALIAS_CRYPTO("anubis"); diff --git a/crypto/api.c b/crypto/api.c index a2b39c5f3649..2a81e98a0021 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -216,11 +216,11 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) alg = crypto_alg_lookup(name, type, mask); if (!alg) { - request_module("%s", name); + request_module("crypto-%s", name); if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask & CRYPTO_ALG_NEED_FALLBACK)) - request_module("%s-all", name); + request_module("crypto-%s-all", name); alg = crypto_alg_lookup(name, type, mask); } diff --git a/crypto/arc4.c b/crypto/arc4.c index 5a772c3657d5..f1a81925558f 100644 --- a/crypto/arc4.c +++ b/crypto/arc4.c @@ -166,3 +166,4 @@ module_exit(arc4_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ARC4 Cipher Algorithm"); MODULE_AUTHOR("Jon Oberheide "); +MODULE_ALIAS_CRYPTO("arc4"); diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c index 8baf5447d35b..7bd71f02d0dd 100644 --- a/crypto/blowfish_generic.c +++ b/crypto/blowfish_generic.c @@ -138,4 +138,4 @@ module_exit(blowfish_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Blowfish Cipher Algorithm"); -MODULE_ALIAS("blowfish"); +MODULE_ALIAS_CRYPTO("blowfish"); diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c index 26bcd7a2d6b4..1b74c5a3e891 100644 --- a/crypto/camellia_generic.c +++ b/crypto/camellia_generic.c @@ -1098,4 +1098,4 @@ module_exit(camellia_fini); MODULE_DESCRIPTION("Camellia Cipher Algorithm"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("camellia"); +MODULE_ALIAS_CRYPTO("camellia"); diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c index 5558f630a0eb..84c86db67ec7 100644 --- a/crypto/cast5_generic.c +++ b/crypto/cast5_generic.c @@ -549,4 +549,4 @@ module_exit(cast5_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cast5 Cipher Algorithm"); -MODULE_ALIAS("cast5"); +MODULE_ALIAS_CRYPTO("cast5"); diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index de732528a430..f408f0bd8de2 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c @@ -291,4 +291,4 @@ module_exit(cast6_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cast6 Cipher Algorithm"); -MODULE_ALIAS("cast6"); +MODULE_ALIAS_CRYPTO("cast6"); diff --git a/crypto/ccm.c b/crypto/ccm.c index 1df84217f7c9..647575b41281 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -879,5 +879,5 @@ module_exit(crypto_ccm_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Counter with CBC MAC"); -MODULE_ALIAS("ccm_base"); -MODULE_ALIAS("rfc4309"); +MODULE_ALIAS_CRYPTO("ccm_base"); +MODULE_ALIAS_CRYPTO("rfc4309"); diff --git a/crypto/crc32.c b/crypto/crc32.c index 9d1c41569898..187ded28cb0b 100644 --- a/crypto/crc32.c +++ b/crypto/crc32.c @@ -156,3 +156,4 @@ module_exit(crc32_mod_fini); MODULE_AUTHOR("Alexander Boyko "); MODULE_DESCRIPTION("CRC32 calculations wrapper for lib/crc32"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CRYPTO("crc32"); diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c index d9c7beba8e50..2a062025749d 100644 --- a/crypto/crc32c_generic.c +++ b/crypto/crc32c_generic.c @@ -170,5 +170,5 @@ module_exit(crc32c_mod_fini); MODULE_AUTHOR("Clay Haapala "); MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("crc32c"); +MODULE_ALIAS_CRYPTO("crc32c"); MODULE_SOFTDEP("pre: crc32c"); diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c index 877e7114ec5c..08bb4f504520 100644 --- a/crypto/crct10dif_generic.c +++ b/crypto/crct10dif_generic.c @@ -124,4 +124,4 @@ module_exit(crct10dif_mod_fini); MODULE_AUTHOR("Tim Chen "); MODULE_DESCRIPTION("T10 DIF CRC calculation."); MODULE_LICENSE("GPL"); -MODULE_ALIAS("crct10dif"); +MODULE_ALIAS_CRYPTO("crct10dif"); diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c index 1dc54bb95a87..a20319132e33 100644 --- a/crypto/crypto_null.c +++ b/crypto/crypto_null.c @@ -145,9 +145,9 @@ static struct crypto_alg null_algs[3] = { { .coa_decompress = null_compress } } } }; -MODULE_ALIAS("compress_null"); -MODULE_ALIAS("digest_null"); -MODULE_ALIAS("cipher_null"); +MODULE_ALIAS_CRYPTO("compress_null"); +MODULE_ALIAS_CRYPTO("digest_null"); +MODULE_ALIAS_CRYPTO("cipher_null"); static int __init crypto_null_mod_init(void) { diff --git a/crypto/ctr.c b/crypto/ctr.c index f2b94f27bb2c..3d81ff7e6b48 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c @@ -466,4 +466,4 @@ module_exit(crypto_ctr_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CTR Counter block mode"); -MODULE_ALIAS("rfc3686"); +MODULE_ALIAS_CRYPTO("rfc3686"); diff --git a/crypto/deflate.c b/crypto/deflate.c index b57d70eb156b..95d8d37c5021 100644 --- a/crypto/deflate.c +++ b/crypto/deflate.c @@ -222,4 +222,4 @@ module_exit(deflate_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP"); MODULE_AUTHOR("James Morris "); - +MODULE_ALIAS_CRYPTO("deflate"); diff --git a/crypto/des_generic.c b/crypto/des_generic.c index 298d464ab7d2..42912948776b 100644 --- a/crypto/des_generic.c +++ b/crypto/des_generic.c @@ -983,7 +983,7 @@ static struct crypto_alg des_algs[2] = { { .cia_decrypt = des3_ede_decrypt } } } }; -MODULE_ALIAS("des3_ede"); +MODULE_ALIAS_CRYPTO("des3_ede"); static int __init des_generic_mod_init(void) { diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c index 021d7fec6bc8..77286ea28865 100644 --- a/crypto/fcrypt.c +++ b/crypto/fcrypt.c @@ -420,3 +420,4 @@ module_exit(fcrypt_mod_fini); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("FCrypt Cipher Algorithm"); MODULE_AUTHOR("David Howells "); +MODULE_ALIAS_CRYPTO("fcrypt"); diff --git a/crypto/gcm.c b/crypto/gcm.c index 276cdac567b6..aefb74a3f522 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -1441,6 +1441,6 @@ module_exit(crypto_gcm_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Galois/Counter Mode"); MODULE_AUTHOR("Mikko Herranen "); -MODULE_ALIAS("gcm_base"); -MODULE_ALIAS("rfc4106"); -MODULE_ALIAS("rfc4543"); +MODULE_ALIAS_CRYPTO("gcm_base"); +MODULE_ALIAS_CRYPTO("rfc4106"); +MODULE_ALIAS_CRYPTO("rfc4543"); diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c index 9d3f0c69a86f..4e97fae9666f 100644 --- a/crypto/ghash-generic.c +++ b/crypto/ghash-generic.c @@ -172,4 +172,4 @@ module_exit(ghash_mod_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GHASH Message Digest Algorithm"); -MODULE_ALIAS("ghash"); +MODULE_ALIAS_CRYPTO("ghash"); diff --git a/crypto/khazad.c b/crypto/khazad.c index 60e7cd66facc..873eb5ded6d7 100644 --- a/crypto/khazad.c +++ b/crypto/khazad.c @@ -880,3 +880,4 @@ module_exit(khazad_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Khazad Cryptographic Algorithm"); +MODULE_ALIAS_CRYPTO("khazad"); diff --git a/crypto/krng.c b/crypto/krng.c index a2d2b72fc135..67c88b331210 100644 --- a/crypto/krng.c +++ b/crypto/krng.c @@ -62,4 +62,4 @@ module_exit(krng_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Kernel Random Number Generator"); -MODULE_ALIAS("stdrng"); +MODULE_ALIAS_CRYPTO("stdrng"); diff --git a/crypto/lz4.c b/crypto/lz4.c index 34d072b72a73..aefbceaf3104 100644 --- a/crypto/lz4.c +++ b/crypto/lz4.c @@ -104,3 +104,4 @@ module_exit(lz4_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("LZ4 Compression Algorithm"); +MODULE_ALIAS_CRYPTO("lz4"); diff --git a/crypto/lz4hc.c b/crypto/lz4hc.c index 9218b3fed5e3..a1d3b5bd3d85 100644 --- a/crypto/lz4hc.c +++ b/crypto/lz4hc.c @@ -104,3 +104,4 @@ module_exit(lz4hc_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("LZ4HC Compression Algorithm"); +MODULE_ALIAS_CRYPTO("lz4hc"); diff --git a/crypto/lzo.c b/crypto/lzo.c index a8ff2f778dc4..4b3e92525dac 100644 --- a/crypto/lzo.c +++ b/crypto/lzo.c @@ -107,3 +107,4 @@ module_exit(lzo_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("LZO Compression Algorithm"); +MODULE_ALIAS_CRYPTO("lzo"); diff --git a/crypto/md4.c b/crypto/md4.c index 0477a6a01d58..3515af425cc9 100644 --- a/crypto/md4.c +++ b/crypto/md4.c @@ -255,4 +255,4 @@ module_exit(md4_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD4 Message Digest Algorithm"); - +MODULE_ALIAS_CRYPTO("md4"); diff --git a/crypto/md5.c b/crypto/md5.c index 7febeaab923b..36f5e5b103f3 100644 --- a/crypto/md5.c +++ b/crypto/md5.c @@ -168,3 +168,4 @@ module_exit(md5_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Message Digest Algorithm"); +MODULE_ALIAS_CRYPTO("md5"); diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c index 079b761bc70d..46195e0d0f4d 100644 --- a/crypto/michael_mic.c +++ b/crypto/michael_mic.c @@ -184,3 +184,4 @@ module_exit(michael_mic_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Michael MIC"); MODULE_AUTHOR("Jouni Malinen "); +MODULE_ALIAS_CRYPTO("michael_mic"); diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 8a0f68b7f257..049486ede938 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c @@ -327,3 +327,4 @@ module_exit(rmd128_mod_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Adrian-Ken Rueegsegger "); MODULE_DESCRIPTION("RIPEMD-128 Message Digest"); +MODULE_ALIAS_CRYPTO("rmd128"); diff --git a/crypto/rmd160.c b/crypto/rmd160.c index 525d7bb752cf..de585e51d455 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c @@ -371,3 +371,4 @@ module_exit(rmd160_mod_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Adrian-Ken Rueegsegger "); MODULE_DESCRIPTION("RIPEMD-160 Message Digest"); +MODULE_ALIAS_CRYPTO("rmd160"); diff --git a/crypto/rmd256.c b/crypto/rmd256.c index 69293d9b56e0..4ec02a754e09 100644 --- a/crypto/rmd256.c +++ b/crypto/rmd256.c @@ -346,3 +346,4 @@ module_exit(rmd256_mod_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Adrian-Ken Rueegsegger "); MODULE_DESCRIPTION("RIPEMD-256 Message Digest"); +MODULE_ALIAS_CRYPTO("rmd256"); diff --git a/crypto/rmd320.c b/crypto/rmd320.c index 09f97dfdfbba..770f2cb369f8 100644 --- a/crypto/rmd320.c +++ b/crypto/rmd320.c @@ -395,3 +395,4 @@ module_exit(rmd320_mod_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Adrian-Ken Rueegsegger "); MODULE_DESCRIPTION("RIPEMD-320 Message Digest"); +MODULE_ALIAS_CRYPTO("rmd320"); diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c index 9a4770c02284..3d0f9df30ac9 100644 --- a/crypto/salsa20_generic.c +++ b/crypto/salsa20_generic.c @@ -248,4 +248,4 @@ module_exit(salsa20_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm"); -MODULE_ALIAS("salsa20"); +MODULE_ALIAS_CRYPTO("salsa20"); diff --git a/crypto/seed.c b/crypto/seed.c index 9c904d6d2151..c6ba8438be43 100644 --- a/crypto/seed.c +++ b/crypto/seed.c @@ -476,3 +476,4 @@ module_exit(seed_fini); MODULE_DESCRIPTION("SEED Cipher Algorithm"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Hye-Shik Chang , Kim Hyun "); +MODULE_ALIAS_CRYPTO("seed"); diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c index 7ddbd7e88859..a53b5e2af335 100644 --- a/crypto/serpent_generic.c +++ b/crypto/serpent_generic.c @@ -665,5 +665,5 @@ module_exit(serpent_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm"); MODULE_AUTHOR("Dag Arne Osvik "); -MODULE_ALIAS("tnepres"); -MODULE_ALIAS("serpent"); +MODULE_ALIAS_CRYPTO("tnepres"); +MODULE_ALIAS_CRYPTO("serpent"); diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c index 7bb047432782..039e58cfa155 100644 --- a/crypto/sha1_generic.c +++ b/crypto/sha1_generic.c @@ -153,4 +153,4 @@ module_exit(sha1_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index 65e7b76b057f..5eb21b120033 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c @@ -384,5 +384,5 @@ module_exit(sha256_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm"); -MODULE_ALIAS("sha224"); -MODULE_ALIAS("sha256"); +MODULE_ALIAS_CRYPTO("sha224"); +MODULE_ALIAS_CRYPTO("sha256"); diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 95db67197cd9..8d0b19ed4f4b 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -288,5 +288,5 @@ module_exit(sha512_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); -MODULE_ALIAS("sha384"); -MODULE_ALIAS("sha512"); +MODULE_ALIAS_CRYPTO("sha384"); +MODULE_ALIAS_CRYPTO("sha512"); diff --git a/crypto/tea.c b/crypto/tea.c index 0a572323ee4a..495be2d0077d 100644 --- a/crypto/tea.c +++ b/crypto/tea.c @@ -270,8 +270,8 @@ static void __exit tea_mod_fini(void) crypto_unregister_algs(tea_algs, ARRAY_SIZE(tea_algs)); } -MODULE_ALIAS("xtea"); -MODULE_ALIAS("xeta"); +MODULE_ALIAS_CRYPTO("xtea"); +MODULE_ALIAS_CRYPTO("xeta"); module_init(tea_mod_init); module_exit(tea_mod_fini); diff --git a/crypto/tgr192.c b/crypto/tgr192.c index 3c7af0d1ff7a..6e5651c66cf8 100644 --- a/crypto/tgr192.c +++ b/crypto/tgr192.c @@ -676,8 +676,8 @@ static void __exit tgr192_mod_fini(void) crypto_unregister_shashes(tgr_algs, ARRAY_SIZE(tgr_algs)); } -MODULE_ALIAS("tgr160"); -MODULE_ALIAS("tgr128"); +MODULE_ALIAS_CRYPTO("tgr160"); +MODULE_ALIAS_CRYPTO("tgr128"); module_init(tgr192_mod_init); module_exit(tgr192_mod_fini); diff --git a/crypto/twofish_generic.c b/crypto/twofish_generic.c index 2d5000552d0f..523ad8c4e359 100644 --- a/crypto/twofish_generic.c +++ b/crypto/twofish_generic.c @@ -211,4 +211,4 @@ module_exit(twofish_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Twofish Cipher Algorithm"); -MODULE_ALIAS("twofish"); +MODULE_ALIAS_CRYPTO("twofish"); diff --git a/crypto/wp512.c b/crypto/wp512.c index ec64e7762fbb..0de42eb3d040 100644 --- a/crypto/wp512.c +++ b/crypto/wp512.c @@ -1167,8 +1167,8 @@ static void __exit wp512_mod_fini(void) crypto_unregister_shashes(wp_algs, ARRAY_SIZE(wp_algs)); } -MODULE_ALIAS("wp384"); -MODULE_ALIAS("wp256"); +MODULE_ALIAS_CRYPTO("wp384"); +MODULE_ALIAS_CRYPTO("wp256"); module_init(wp512_mod_init); module_exit(wp512_mod_fini); diff --git a/crypto/zlib.c b/crypto/zlib.c index c9ee681d57fd..0eefa9d237ac 100644 --- a/crypto/zlib.c +++ b/crypto/zlib.c @@ -378,3 +378,4 @@ module_exit(zlib_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Zlib Compression Algorithm"); MODULE_AUTHOR("Sony Corporation"); +MODULE_ALIAS_CRYPTO("zlib"); diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 633ba945e153..c178ed8c3908 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -563,4 +563,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig"); -MODULE_ALIAS("aes"); +MODULE_ALIAS_CRYPTO("aes"); diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index bace885634f2..95f7d27ce491 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -593,7 +593,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support."); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig"); -MODULE_ALIAS("sha1-all"); -MODULE_ALIAS("sha256-all"); -MODULE_ALIAS("sha1-padlock"); -MODULE_ALIAS("sha256-padlock"); +MODULE_ALIAS_CRYPTO("sha1-all"); +MODULE_ALIAS_CRYPTO("sha256-all"); +MODULE_ALIAS_CRYPTO("sha1-padlock"); +MODULE_ALIAS_CRYPTO("sha256-padlock"); diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c index 244d73378f0e..7ee93f881db6 100644 --- a/drivers/crypto/qat/qat_common/adf_ctl_drv.c +++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "adf_accel_devices.h" #include "adf_common_drv.h" @@ -487,4 +488,4 @@ module_exit(adf_unregister_ctl_device_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel"); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); -MODULE_ALIAS("intel_qat"); +MODULE_ALIAS_CRYPTO("intel_qat"); diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 83811aab207e..7c035de9055e 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c @@ -1812,7 +1812,7 @@ module_exit(ux500_cryp_mod_fini); module_param(cryp_mode, int, 0); MODULE_DESCRIPTION("Driver for ST-Ericsson UX500 CRYP crypto engine."); -MODULE_ALIAS("aes-all"); -MODULE_ALIAS("des-all"); +MODULE_ALIAS_CRYPTO("aes-all"); +MODULE_ALIAS_CRYPTO("des-all"); MODULE_LICENSE("GPL"); diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 5af53b5508b0..76ecc8d143d0 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1997,7 +1997,7 @@ module_exit(ux500_hash_mod_fini); MODULE_DESCRIPTION("Driver for ST-Ericsson UX500 HASH engine."); MODULE_LICENSE("GPL"); -MODULE_ALIAS("sha1-all"); -MODULE_ALIAS("sha256-all"); -MODULE_ALIAS("hmac-sha1-all"); -MODULE_ALIAS("hmac-sha256-all"); +MODULE_ALIAS_CRYPTO("sha1-all"); +MODULE_ALIAS_CRYPTO("sha256-all"); +MODULE_ALIAS_CRYPTO("hmac-sha1-all"); +MODULE_ALIAS_CRYPTO("hmac-sha256-all"); diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 99485415dcc2..91e97ec01418 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "ap_bus.h" @@ -71,7 +72,7 @@ MODULE_AUTHOR("IBM Corporation"); MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \ "Copyright IBM Corp. 2006, 2012"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("z90crypt"); +MODULE_ALIAS_CRYPTO("z90crypt"); /* * Module parameter diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 208a63290b23..9c8776d0ada8 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -25,6 +25,19 @@ #include #include +/* + * Autoloaded crypto modules should only use a prefixed name to avoid allowing + * arbitrary modules to be loaded. Loading from userspace may still need the + * unprefixed names, so retains those aliases as well. + * This uses __MODULE_INFO directly instead of MODULE_ALIAS because pre-4.3 + * gcc (e.g. avr32 toolchain) uses __LINE__ for uniqueness, and this macro + * expands twice on the same line. Instead, use a separate base name for the + * alias. + */ +#define MODULE_ALIAS_CRYPTO(name) \ + __MODULE_INFO(alias, alias_userspace, name); \ + __MODULE_INFO(alias, alias_crypto, "crypto-" name) + /* * Algorithm masks and types. */ -- GitLab From be19d9336995241f5c98d0abebff440fef03455e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 23 Nov 2014 14:11:15 +0100 Subject: [PATCH 6206/9457] drm/exynos/ipp: fix error return code Propagate the returned error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 00d74b18f7cb..d5ad17dfc24d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -426,18 +426,21 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, c_node->start_work = ipp_create_cmd_work(); if (IS_ERR(c_node->start_work)) { DRM_ERROR("failed to create start work.\n"); + ret = PTR_ERR(c_node->start_work); goto err_remove_id; } c_node->stop_work = ipp_create_cmd_work(); if (IS_ERR(c_node->stop_work)) { DRM_ERROR("failed to create stop work.\n"); + ret = PTR_ERR(c_node->stop_work); goto err_free_start; } c_node->event_work = ipp_create_event_work(); if (IS_ERR(c_node->event_work)) { DRM_ERROR("failed to create event work.\n"); + ret = PTR_ERR(c_node->event_work); goto err_free_stop; } -- GitLab From b657d7e632e0bc40e5e231332be39d69b2f1a0bb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 24 Nov 2014 09:27:23 +0100 Subject: [PATCH 6207/9457] blk-mq: handle the single queue case in blk_mq_hctx_next_cpu Don't duplicate the code to handle the not cpu bounce case in the caller, do it inside blk_mq_hctx_next_cpu instead. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-mq.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 4347aa2be6ae..27a347fe8f5b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -788,10 +788,11 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) */ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx) { - int cpu = hctx->next_cpu; + if (hctx->queue->nr_hw_queues == 1) + return WORK_CPU_UNBOUND; if (--hctx->next_cpu_batch <= 0) { - int next_cpu; + int cpu = hctx->next_cpu, next_cpu; next_cpu = cpumask_next(hctx->next_cpu, hctx->cpumask); if (next_cpu >= nr_cpu_ids) @@ -799,9 +800,11 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx) hctx->next_cpu = next_cpu; hctx->next_cpu_batch = BLK_MQ_CPU_WORK_BATCH; + + return cpu; } - return cpu; + return hctx->next_cpu; } void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) @@ -820,14 +823,8 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) put_cpu(); } - if (hctx->queue->nr_hw_queues == 1) - kblockd_schedule_delayed_work(&hctx->run_work, 0); - else { - unsigned int cpu; - - cpu = blk_mq_hctx_next_cpu(hctx); - kblockd_schedule_delayed_work_on(cpu, &hctx->run_work, 0); - } + kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), + &hctx->run_work, 0); } void blk_mq_run_queues(struct request_queue *q, bool async) @@ -919,16 +916,8 @@ static void blk_mq_delay_work_fn(struct work_struct *work) void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs) { - unsigned long tmo = msecs_to_jiffies(msecs); - - if (hctx->queue->nr_hw_queues == 1) - kblockd_schedule_delayed_work(&hctx->delay_work, tmo); - else { - unsigned int cpu; - - cpu = blk_mq_hctx_next_cpu(hctx); - kblockd_schedule_delayed_work_on(cpu, &hctx->delay_work, tmo); - } + kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), + &hctx->delay_work, msecs_to_jiffies(msecs)); } EXPORT_SYMBOL(blk_mq_delay_queue); -- GitLab From 394ffa503bc40e32d7f54a9b817264e81ce131b4 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 24 Nov 2014 11:05:22 +0800 Subject: [PATCH 6208/9457] blk: introduce generic io stat accounting help function Many block drivers accounting io stat based on bio (e.g. NVMe...), the blk_account_io_start/end() which is based on request does not make sense to them, so here we introduce the similar help function named generic_start/end_io_acct base on raw sectors, and it can simplify some driver's open io accounting code. Signed-off-by: Gu Zheng Signed-off-by: Jens Axboe --- block/bio.c | 28 ++++++++++++++++++++++++++++ include/linux/bio.h | 5 +++++ 2 files changed, 33 insertions(+) diff --git a/block/bio.c b/block/bio.c index 3e6e1986a5b2..3d4a072375ef 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1739,6 +1739,34 @@ void bio_check_pages_dirty(struct bio *bio) } } +void generic_start_io_acct(int rw, unsigned long sectors, + struct hd_struct *part) +{ + int cpu = part_stat_lock(); + + part_round_stats(cpu, part); + part_stat_inc(cpu, part, ios[rw]); + part_stat_add(cpu, part, sectors[rw], sectors); + part_inc_in_flight(part, rw); + + part_stat_unlock(); +} +EXPORT_SYMBOL(generic_start_io_acct); + +void generic_end_io_acct(int rw, struct hd_struct *part, + unsigned long start_time) +{ + unsigned long duration = jiffies - start_time; + int cpu = part_stat_lock(); + + part_stat_add(cpu, part, ticks[rw], duration); + part_round_stats(cpu, part); + part_dec_in_flight(part, rw); + + part_stat_unlock(); +} +EXPORT_SYMBOL(generic_end_io_acct); + #if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE void bio_flush_dcache_pages(struct bio *bi) { diff --git a/include/linux/bio.h b/include/linux/bio.h index 7347f486ceca..efead0b532c4 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -443,6 +443,11 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int, extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); +void generic_start_io_acct(int rw, unsigned long sectors, + struct hd_struct *part); +void generic_end_io_acct(int rw, struct hd_struct *part, + unsigned long start_time); + #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE # error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform" #endif -- GitLab From aae4933da9488827d341c31b970b2f62ac45a496 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 24 Nov 2014 11:05:24 +0800 Subject: [PATCH 6209/9457] md/bcache: use generic io stats accounting functions to simplify io stat accounting Use generic io stats accounting help functions (generic_{start,end}_io_acct) to simplify io stat accounting. Signed-off-by: Gu Zheng Acked-by: Kent Overstreet Signed-off-by: Jens Axboe --- drivers/md/bcache/request.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 62e6e98186b5..ab43faddb447 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -601,13 +601,8 @@ static void request_endio(struct bio *bio, int error) static void bio_complete(struct search *s) { if (s->orig_bio) { - int cpu, rw = bio_data_dir(s->orig_bio); - unsigned long duration = jiffies - s->start_time; - - cpu = part_stat_lock(); - part_round_stats(cpu, &s->d->disk->part0); - part_stat_add(cpu, &s->d->disk->part0, ticks[rw], duration); - part_stat_unlock(); + generic_end_io_acct(bio_data_dir(s->orig_bio), + &s->d->disk->part0, s->start_time); trace_bcache_request_end(s->d, s->orig_bio); bio_endio(s->orig_bio, s->iop.error); @@ -959,12 +954,9 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio) struct search *s; struct bcache_device *d = bio->bi_bdev->bd_disk->private_data; struct cached_dev *dc = container_of(d, struct cached_dev, disk); - int cpu, rw = bio_data_dir(bio); + int rw = bio_data_dir(bio); - cpu = part_stat_lock(); - part_stat_inc(cpu, &d->disk->part0, ios[rw]); - part_stat_add(cpu, &d->disk->part0, sectors[rw], bio_sectors(bio)); - part_stat_unlock(); + generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0); bio->bi_bdev = dc->bdev; bio->bi_iter.bi_sector += dc->sb.data_offset; @@ -1074,12 +1066,9 @@ static void flash_dev_make_request(struct request_queue *q, struct bio *bio) struct search *s; struct closure *cl; struct bcache_device *d = bio->bi_bdev->bd_disk->private_data; - int cpu, rw = bio_data_dir(bio); + int rw = bio_data_dir(bio); - cpu = part_stat_lock(); - part_stat_inc(cpu, &d->disk->part0, ios[rw]); - part_stat_add(cpu, &d->disk->part0, sectors[rw], bio_sectors(bio)); - part_stat_unlock(); + generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0); s = search_alloc(bio, d); cl = &s->cl; -- GitLab From 244808543e6e9b46ea1135589877f4d4bd2925c5 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 24 Nov 2014 11:05:25 +0800 Subject: [PATCH 6210/9457] drbd: use generic io stats accounting functions to simplify io stat accounting Use generic io stats accounting help functions (generic_{start,end}_io_acct) to simplify io stat accounting. Signed-off-by: Gu Zheng Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 3b797cd5a407..34f2f0ba409b 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -36,29 +36,15 @@ static bool drbd_may_do_local_read(struct drbd_device *device, sector_t sector, /* Update disk stats at start of I/O request */ static void _drbd_start_io_acct(struct drbd_device *device, struct drbd_request *req) { - const int rw = bio_data_dir(req->master_bio); - int cpu; - cpu = part_stat_lock(); - part_round_stats(cpu, &device->vdisk->part0); - part_stat_inc(cpu, &device->vdisk->part0, ios[rw]); - part_stat_add(cpu, &device->vdisk->part0, sectors[rw], req->i.size >> 9); - (void) cpu; /* The macro invocations above want the cpu argument, I do not like - the compiler warning about cpu only assigned but never used... */ - part_inc_in_flight(&device->vdisk->part0, rw); - part_stat_unlock(); + generic_start_io_acct(bio_data_dir(req->master_bio), req->i.size >> 9, + &device->vdisk->part0); } /* Update disk stats when completing request upwards */ static void _drbd_end_io_acct(struct drbd_device *device, struct drbd_request *req) { - int rw = bio_data_dir(req->master_bio); - unsigned long duration = jiffies - req->start_jif; - int cpu; - cpu = part_stat_lock(); - part_stat_add(cpu, &device->vdisk->part0, ticks[rw], duration); - part_round_stats(cpu, &device->vdisk->part0); - part_dec_in_flight(&device->vdisk->part0, rw); - part_stat_unlock(); + generic_end_io_acct(bio_data_dir(req->master_bio), + &device->vdisk->part0, req->start_jif); } static struct drbd_request *drbd_req_new(struct drbd_device *device, -- GitLab From 18c0b223cf9901727ef3b02da6711ac930b4e5d4 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 24 Nov 2014 11:05:26 +0800 Subject: [PATCH 6211/9457] md: use generic io stats accounting functions to simplify io stat accounting Use generic io stats accounting help functions (generic_{start,end}_io_acct) to simplify io stat accounting. Signed-off-by: Gu Zheng Signed-off-by: Jens Axboe --- drivers/md/dm.c | 13 +++---------- drivers/md/md.c | 6 +----- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 58f3927fd7cc..b1cdf69b11e7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -602,13 +602,10 @@ static void end_io_acct(struct dm_io *io) struct mapped_device *md = io->md; struct bio *bio = io->bio; unsigned long duration = jiffies - io->start_time; - int pending, cpu; + int pending; int rw = bio_data_dir(bio); - cpu = part_stat_lock(); - part_round_stats(cpu, &dm_disk(md)->part0); - part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration); - part_stat_unlock(); + generic_end_io_acct(rw, &dm_disk(md)->part0, io->start_time); if (unlikely(dm_stats_used(&md->stats))) dm_stats_account_io(&md->stats, bio->bi_rw, bio->bi_iter.bi_sector, @@ -1648,16 +1645,12 @@ static void _dm_request(struct request_queue *q, struct bio *bio) { int rw = bio_data_dir(bio); struct mapped_device *md = q->queuedata; - int cpu; int srcu_idx; struct dm_table *map; map = dm_get_live_table(md, &srcu_idx); - cpu = part_stat_lock(); - part_stat_inc(cpu, &dm_disk(md)->part0, ios[rw]); - part_stat_add(cpu, &dm_disk(md)->part0, sectors[rw], bio_sectors(bio)); - part_stat_unlock(); + generic_start_io_acct(rw, bio_sectors(bio), &dm_disk(md)->part0); /* if we're suspended, we have to queue this io for later */ if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) { diff --git a/drivers/md/md.c b/drivers/md/md.c index 9233c71138f1..056ccd28c037 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -247,7 +247,6 @@ static void md_make_request(struct request_queue *q, struct bio *bio) { const int rw = bio_data_dir(bio); struct mddev *mddev = q->queuedata; - int cpu; unsigned int sectors; if (mddev == NULL || mddev->pers == NULL @@ -284,10 +283,7 @@ static void md_make_request(struct request_queue *q, struct bio *bio) sectors = bio_sectors(bio); mddev->pers->make_request(mddev, bio); - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors); - part_stat_unlock(); + generic_start_io_acct(rw, sectors, &mddev->gendisk->part0); if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) wake_up(&mddev->sb_wait); -- GitLab From fa573f72790c2c2b9bfd758c5d33959af4a39915 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 24 Nov 2014 11:05:27 +0800 Subject: [PATCH 6212/9457] block/rsxx: use generic io stats accounting functions to simplify io stat accounting Use generic io stats accounting help functions (generic_{start,end}_io_acct) to simplify io stat accounting. Signed-off-by: Gu Zheng Signed-off-by: Jens Axboe --- drivers/block/rsxx/dev.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c index 40ee7705df63..ac8c62cb4875 100644 --- a/drivers/block/rsxx/dev.c +++ b/drivers/block/rsxx/dev.c @@ -112,37 +112,16 @@ static const struct block_device_operations rsxx_fops = { static void disk_stats_start(struct rsxx_cardinfo *card, struct bio *bio) { - struct hd_struct *part0 = &card->gendisk->part0; - int rw = bio_data_dir(bio); - int cpu; - - cpu = part_stat_lock(); - - part_round_stats(cpu, part0); - part_inc_in_flight(part0, rw); - - part_stat_unlock(); + generic_start_io_acct(bio_data_dir(bio), bio_sectors(bio), + &card->gendisk->part0); } static void disk_stats_complete(struct rsxx_cardinfo *card, struct bio *bio, unsigned long start_time) { - struct hd_struct *part0 = &card->gendisk->part0; - unsigned long duration = jiffies - start_time; - int rw = bio_data_dir(bio); - int cpu; - - cpu = part_stat_lock(); - - part_stat_add(cpu, part0, sectors[rw], bio_sectors(bio)); - part_stat_inc(cpu, part0, ios[rw]); - part_stat_add(cpu, part0, ticks[rw], duration); - - part_round_stats(cpu, part0); - part_dec_in_flight(part0, rw); - - part_stat_unlock(); + generic_end_io_acct(bio_data_dir(bio), &card->gendisk->part0, + start_time); } static void bio_dma_done_cb(struct rsxx_cardinfo *card, -- GitLab From e392ba814367797e5676e3a84652877a42cc8b0c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 24 Nov 2014 16:39:03 +0100 Subject: [PATCH 6213/9457] Revert "mac80211_hwsim: VHT add 160MHz width support" This reverts commit c17aa52c5bf571533cc8561292f7316b9216eddc. It was wrong, IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ already implies that 160 MHz is supported, as it isn't a bitmap but rather a value in a 2-bit field. Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index d399a7367ce9..756eea588711 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2388,7 +2388,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, sband->vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | - IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | IEEE80211_VHT_CAP_RXLDPC | IEEE80211_VHT_CAP_SHORT_GI_80 | IEEE80211_VHT_CAP_SHORT_GI_160 | -- GitLab From c9eab58f6466cef3d9cd760a96e4de5e060e5195 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 24 Nov 2014 15:27:17 +0100 Subject: [PATCH 6214/9457] KVM: x86: move device assignment out of kvm_host.h Create a new header, and hide the device assignment functions there. Move struct kvm_assigned_dev_kernel to assigned-dev.c by modifying arch/x86/kvm/iommu.c to take a PCI device struct. Based on a patch by Radim Krcmar . Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 23 ----------------------- arch/x86/kvm/assigned-dev.c | 30 ++++++++++++++++++++++++++++-- arch/x86/kvm/assigned-dev.h | 32 ++++++++++++++++++++++++++++++++ arch/x86/kvm/iommu.c | 11 +++-------- arch/x86/kvm/x86.c | 1 + include/linux/kvm_host.h | 29 ----------------------------- 6 files changed, 64 insertions(+), 62 deletions(-) create mode 100644 arch/x86/kvm/assigned-dev.h diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d549cf8bfb69..76ff3e2d8fd2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1112,27 +1112,4 @@ int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data); void kvm_handle_pmu_event(struct kvm_vcpu *vcpu); void kvm_deliver_pmi(struct kvm_vcpu *vcpu); -#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT -int kvm_iommu_map_guest(struct kvm *kvm); -int kvm_iommu_unmap_guest(struct kvm *kvm); - -long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, - unsigned long arg); - -void kvm_free_all_assigned_devices(struct kvm *kvm); -#else -static inline int kvm_iommu_unmap_guest(struct kvm *kvm) -{ - return 0; -} - -static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, - unsigned long arg) -{ - return -ENOTTY; -} - -static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} -#endif - #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/assigned-dev.c b/arch/x86/kvm/assigned-dev.c index e05000e200d2..6eb5c20ee373 100644 --- a/arch/x86/kvm/assigned-dev.c +++ b/arch/x86/kvm/assigned-dev.c @@ -20,6 +20,32 @@ #include #include #include "irq.h" +#include "assigned-dev.h" + +struct kvm_assigned_dev_kernel { + struct kvm_irq_ack_notifier ack_notifier; + struct list_head list; + int assigned_dev_id; + int host_segnr; + int host_busnr; + int host_devfn; + unsigned int entries_nr; + int host_irq; + bool host_irq_disabled; + bool pci_2_3; + struct msix_entry *host_msix_entries; + int guest_irq; + struct msix_entry *guest_msix_entries; + unsigned long irq_requested_type; + int irq_source_id; + int flags; + struct pci_dev *dev; + struct kvm *kvm; + spinlock_t intx_lock; + spinlock_t intx_mask_lock; + char irq_name[32]; + struct pci_saved_state *pci_saved_state; +}; static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, int assigned_dev_id) @@ -748,7 +774,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, if (r) goto out_list_del; } - r = kvm_assign_device(kvm, match); + r = kvm_assign_device(kvm, match->dev); if (r) goto out_list_del; @@ -790,7 +816,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm, goto out; } - kvm_deassign_device(kvm, match); + kvm_deassign_device(kvm, match->dev); kvm_free_assigned_device(kvm, match); diff --git a/arch/x86/kvm/assigned-dev.h b/arch/x86/kvm/assigned-dev.h new file mode 100644 index 000000000000..a428c1a211b2 --- /dev/null +++ b/arch/x86/kvm/assigned-dev.h @@ -0,0 +1,32 @@ +#ifndef ARCH_X86_KVM_ASSIGNED_DEV_H +#define ARCH_X86_KVM_ASSIGNED_DEV_H + +#include + +#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT +int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev); +int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev); + +int kvm_iommu_map_guest(struct kvm *kvm); +int kvm_iommu_unmap_guest(struct kvm *kvm); + +long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, + unsigned long arg); + +void kvm_free_all_assigned_devices(struct kvm *kvm); +#else +static inline int kvm_iommu_unmap_guest(struct kvm *kvm) +{ + return 0; +} + +static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, + unsigned long arg) +{ + return -ENOTTY; +} + +static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} +#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */ + +#endif /* ARCH_X86_KVM_ASSIGNED_DEV_H */ diff --git a/arch/x86/kvm/iommu.c b/arch/x86/kvm/iommu.c index c1e6ae989a43..17b73eeac8a4 100644 --- a/arch/x86/kvm/iommu.c +++ b/arch/x86/kvm/iommu.c @@ -31,6 +31,7 @@ #include #include #include +#include "assigned-dev.h" static bool allow_unsafe_assigned_interrupts; module_param_named(allow_unsafe_assigned_interrupts, @@ -169,10 +170,8 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) return r; } -int kvm_assign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev) +int kvm_assign_device(struct kvm *kvm, struct pci_dev *pdev) { - struct pci_dev *pdev = NULL; struct iommu_domain *domain = kvm->arch.iommu_domain; int r; bool noncoherent; @@ -181,7 +180,6 @@ int kvm_assign_device(struct kvm *kvm, if (!domain) return 0; - pdev = assigned_dev->dev; if (pdev == NULL) return -ENODEV; @@ -212,17 +210,14 @@ int kvm_assign_device(struct kvm *kvm, return r; } -int kvm_deassign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev) +int kvm_deassign_device(struct kvm *kvm, struct pci_dev *pdev) { struct iommu_domain *domain = kvm->arch.iommu_domain; - struct pci_dev *pdev = NULL; /* check if iommu exists and in use */ if (!domain) return 0; - pdev = assigned_dev->dev; if (pdev == NULL) return -ENODEV; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 782e4eaf4561..c42bca47f7f5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -27,6 +27,7 @@ #include "kvm_cache_regs.h" #include "x86.h" #include "cpuid.h" +#include "assigned-dev.h" #include #include diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index aa56894ce839..231dd9472226 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -718,31 +718,6 @@ struct kvm_irq_ack_notifier { void (*irq_acked)(struct kvm_irq_ack_notifier *kian); }; -struct kvm_assigned_dev_kernel { - struct kvm_irq_ack_notifier ack_notifier; - struct list_head list; - int assigned_dev_id; - int host_segnr; - int host_busnr; - int host_devfn; - unsigned int entries_nr; - int host_irq; - bool host_irq_disabled; - bool pci_2_3; - struct msix_entry *host_msix_entries; - int guest_irq; - struct msix_entry *guest_msix_entries; - unsigned long irq_requested_type; - int irq_source_id; - int flags; - struct pci_dev *dev; - struct kvm *kvm; - spinlock_t intx_lock; - spinlock_t intx_mask_lock; - char irq_name[32]; - struct pci_saved_state *pci_saved_state; -}; - int kvm_irq_map_gsi(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *entries, int gsi); int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin); @@ -764,10 +739,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); -int kvm_assign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev); -int kvm_deassign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev); #else static inline int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) -- GitLab From 2b4a273b4266d9928d5b20154fea96f09ea5cb9a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 24 Nov 2014 14:35:24 +0100 Subject: [PATCH 6215/9457] kvm: x86: avoid warning about potential shift wrapping bug cs.base is declared as a __u64 variable and vector is a u32 so this causes a static checker warning. The user indeed can set "sipi_vector" to any u32 value in kvm_vcpu_ioctl_x86_set_vcpu_events(), but the value should really have 8-bit precision only. Reported-by: Dan Carpenter Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/lapic.c | 2 +- arch/x86/kvm/x86.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 76ff3e2d8fd2..2896dbc18987 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -880,7 +880,7 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); -void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, unsigned int vector); +void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, int reason, bool has_error_code, u32 error_code); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e0e5642dae41..f739f804b3a2 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1954,7 +1954,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) void kvm_apic_accept_events(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; - unsigned int sipi_vector; + u8 sipi_vector; unsigned long pe; if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c42bca47f7f5..08b5657e57ed 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7033,7 +7033,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu) kvm_x86_ops->vcpu_reset(vcpu); } -void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, unsigned int vector) +void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) { struct kvm_segment cs; -- GitLab From 575f05302e6c75fcea8802a779359f8c927b516e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 24 Nov 2014 16:51:33 +0100 Subject: [PATCH 6216/9457] mac80211: disable 80+80/160 in VHT correctly The supported bandwidth field is a two-bit field, not a bitmap, so treat it accordingly when disabling 80+80 or 160 MHz. Note that we can only advertise "80+80 and 160" or "160", not "80+80" by itself, so disabling 160 also disables 80+80. Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d29589a09065..36e39ed4dfd9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -552,13 +552,17 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, cap = vht_cap.cap; if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) { - cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; - cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + u32 bw = cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; + + cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; + if (bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ || + bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) + cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; } if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) { cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160; - cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; } /* -- GitLab From 4cf703a7bca4c29d06028821db60f253390a84a7 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 24 Nov 2014 15:32:35 +0200 Subject: [PATCH 6217/9457] ASoC: max98090: Fix digital microphone Commit e409dfbfccf9 ("ASoC: dapm: Add a few supply widget sanity checks") broke digital microphone support in max98090.c: max98090 i2c-193C9890:00: Conditional paths are not supported for supply widgets (DMICL_ENA -> [DMIC] -> DMIC Mux) max98090 i2c-193C9890:00: ASoC: no dapm match for DMICL_ENA --> DMIC --> DMIC Mux max98090 i2c-193C9890:00: ASoC: Failed to add route DMICL_ENA -> DMIC -> DMIC Mux max98090 i2c-193C9890:00: Conditional paths are not supported for supply widgets (DMICR_ENA -> [DMIC] -> DMIC Mux) max98090 i2c-193C9890:00: ASoC: no dapm match for DMICR_ENA --> DMIC --> DMIC Mux max98090 i2c-193C9890:00: ASoC: Failed to add route DMICR_ENA -> DMIC -> DMIC Mux Problem is partially caused by commit f69e3caa9e18 ("ASoC: max98090: Enable both DMIC channels also when using mono configuration") which connects "DMICL_ENA" and "DMICR_ENA" supply widgets to "DMIC Mux". Fix the breakage by reverting f69e3caa9e18 and then by adding additional "DMICR_ENA" to "DMICL" and "DMICL_ENA" to "DMICR" cross-connections. This disconnects these supply widgets from the mux and makes sure that both DMIC data channels are still enabled together. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 1229554f1464..994d02c1fb69 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1311,6 +1311,10 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { {"MIC1 Input", NULL, "MIC1"}, {"MIC2 Input", NULL, "MIC2"}, + {"DMICL", NULL, "DMICL_ENA"}, + {"DMICL", NULL, "DMICR_ENA"}, + {"DMICR", NULL, "DMICL_ENA"}, + {"DMICR", NULL, "DMICR_ENA"}, {"DMICL", NULL, "AHPF"}, {"DMICR", NULL, "AHPF"}, @@ -1368,8 +1372,6 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { {"DMIC Mux", "ADC", "ADCR"}, {"DMIC Mux", "DMIC", "DMICL"}, {"DMIC Mux", "DMIC", "DMICR"}, - {"DMIC Mux", "DMIC", "DMICL_ENA"}, - {"DMIC Mux", "DMIC", "DMICR_ENA"}, {"LBENL Mux", "Normal", "DMIC Mux"}, {"LBENL Mux", "Loopback", "LTENL Mux"}, -- GitLab From 48826ee590da03e9882922edf96d8d27bdfe9552 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 24 Nov 2014 15:32:36 +0200 Subject: [PATCH 6218/9457] ASoC: max98090: Fix ill-defined sidetone route Commit 5fe5b767dc6f ("ASoC: dapm: Do not pretend to support controls for non mixer/mux widgets") revealed ill-defined control in a route between "STENL Mux" and DACs in max98090.c: max98090 i2c-193C9890:00: Control not supported for path STENL Mux -> [NULL] -> DACL max98090 i2c-193C9890:00: ASoC: no dapm match for STENL Mux --> NULL --> DACL max98090 i2c-193C9890:00: ASoC: Failed to add route STENL Mux -> NULL -> DACL max98090 i2c-193C9890:00: Control not supported for path STENL Mux -> [NULL] -> DACR max98090 i2c-193C9890:00: ASoC: no dapm match for STENL Mux --> NULL --> DACR max98090 i2c-193C9890:00: ASoC: Failed to add route STENL Mux -> NULL -> DACR Since there is no control between "STENL Mux" and DACs the control name must be NULL not "NULL". Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/max98090.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 994d02c1fb69..20b50e46a9e8 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1397,8 +1397,8 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { {"STENL Mux", "Sidetone Left", "DMICL"}, {"STENR Mux", "Sidetone Right", "ADCR"}, {"STENR Mux", "Sidetone Right", "DMICR"}, - {"DACL", "NULL", "STENL Mux"}, - {"DACR", "NULL", "STENL Mux"}, + {"DACL", NULL, "STENL Mux"}, + {"DACR", NULL, "STENL Mux"}, {"AIFINL", NULL, "SHDN"}, {"AIFINR", NULL, "SHDN"}, -- GitLab From 418382f29d99f1faffdd6636f378da41b44815db Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 24 Nov 2014 15:32:37 +0200 Subject: [PATCH 6219/9457] ASoC: max98090: Fix right sidetone connection It is right not left sidetone which goes to "DACR". Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 20b50e46a9e8..34ed9a91f392 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1398,7 +1398,7 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = { {"STENR Mux", "Sidetone Right", "ADCR"}, {"STENR Mux", "Sidetone Right", "DMICR"}, {"DACL", NULL, "STENL Mux"}, - {"DACR", NULL, "STENL Mux"}, + {"DACR", NULL, "STENR Mux"}, {"AIFINL", NULL, "SHDN"}, {"AIFINR", NULL, "SHDN"}, -- GitLab From 6df43c9b4d87b6767debdfa8318c5374415e8fc0 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 12 Nov 2014 14:42:53 +0000 Subject: [PATCH 6220/9457] drivers/base: cacheinfo: remove noisy error boot message On systems that don't support cacheinfo, this error message can be considered noisy and irrelevant. The error messages can be added to the functions that architectures implement overiding the weak default definition if really required. This patch removes the concerned error message in the generic code. Signed-off-by: Sudeep Holla Reported-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 8ed4ea1f3716..6e64563361f0 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -520,10 +520,8 @@ static int __init cacheinfo_sysfs_init(void) for_each_online_cpu(cpu) { rc = detect_cache_attributes(cpu); - if (rc) { - pr_err("error detecting cacheinfo..cpu%d\n", cpu); + if (rc) goto out; - } rc = cache_add_dev(cpu); if (rc) { free_cache_attributes(cpu); -- GitLab From c1b69b1ca1f5a8669034348cee9e495fde99bf69 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 23 Oct 2014 17:56:11 +0200 Subject: [PATCH 6221/9457] nfs: Remove dead case from nfs4_map_errors() NFS4ERR_ACCESS has number 13 and thus is matched and returned immediately at the beginning of nfs4_map_errors() and there's no point in checking it later. Coverity-id: 733891 Signed-off-by: Jan Kara Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 69dc20a743f9..15d5eb52cde8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -158,8 +158,6 @@ static int nfs4_map_errors(int err) return -EACCES; case -NFS4ERR_MINOR_VERS_MISMATCH: return -EPROTONOSUPPORT; - case -NFS4ERR_ACCESS: - return -EACCES; case -NFS4ERR_FILE_OPEN: return -EBUSY; default: -- GitLab From 878ffa9f855e84d35d950f1abeb5a37b8435baea Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 23 Oct 2014 14:00:54 -0400 Subject: [PATCH 6222/9457] NFS: Use nfs_server_capable() for checknig NFS_CAP_SEEK This should make the code easier to maintain in the future. Signed-off-by: Anna Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/nfs42proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 0886f1db5917..056f5aafecc1 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -50,7 +50,7 @@ loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) struct nfs_server *server = NFS_SERVER(inode); int status; - if (!(server->caps & NFS_CAP_SEEK)) + if (!nfs_server_capable(inode, NFS_CAP_SEEK)) return -ENOTSUPP; status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ); -- GitLab From 3c415707b37f1e4483c418c77f57692b89bcfd5e Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Wed, 19 Nov 2014 16:16:16 -0800 Subject: [PATCH 6223/9457] kselftest: Move the docs to the Documentation dir Also, adjust the formatting a bit, and expand the section about using TARGETS= on the make command line. Signed-off-by: Tim Bird Acked-by: Shuah Khan Signed-off-by: Jonathan Corbet --- .../README.txt => Documentation/kselftest.txt | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) rename tools/testing/selftests/README.txt => Documentation/kselftest.txt (73%) diff --git a/tools/testing/selftests/README.txt b/Documentation/kselftest.txt similarity index 73% rename from tools/testing/selftests/README.txt rename to Documentation/kselftest.txt index 2660d5ff9179..a87d840bacfe 100644 --- a/tools/testing/selftests/README.txt +++ b/Documentation/kselftest.txt @@ -15,37 +15,45 @@ Running the selftests (hotplug tests are run in limited mode) ============================================================= To build the tests: - $ make -C tools/testing/selftests To run the tests: - $ make -C tools/testing/selftests run_tests +To build and run the tests with a single command, use: + $ make kselftest + - note that some tests will require root privileges. -To run only tests targeted for a single subsystem: (including -hotplug targets in limited mode) - $ make -C tools/testing/selftests TARGETS=cpu-hotplug run_tests +Running a subset of selftests +======================================== +You can use the "TARGETS" variable on the make command line to specify +single test to run, or a list of tests to run. + +To run only tests targeted for a single subsystem: + $ make -C tools/testing/selftests TARGETS=ptrace run_tests + +You can specify multiple tests to build and run: + $ make TARGETS="size timers" kselftest + +See the top-level tools/testing/selftests/Makefile for the list of all +possible targets. -See the top-level tools/testing/selftests/Makefile for the list of all possible -targets. Running the full range hotplug selftests ======================================== -To build the tests: - +To build the hotplug tests: $ make -C tools/testing/selftests hotplug -To run the tests: - +To run the hotplug tests: $ make -C tools/testing/selftests run_hotplug - note that some tests will require root privileges. + Contributing new tests ====================== -- GitLab From 860a0d9e511f278bedab62d555a457c18e0841d5 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 28 Oct 2014 14:24:12 -0400 Subject: [PATCH 6224/9457] sunrpc: add some tracepoints in svc_rqst handling functions ...just around svc_send, svc_recv and svc_process for now. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/trace/events/sunrpc.h | 55 +++++++++++++++++++++++++++++++++++ net/sunrpc/svc.c | 21 +++++++------ net/sunrpc/svc_xprt.c | 31 +++++++++++++------- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 1fef3e6e9436..6260f5134212 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -306,6 +307,60 @@ DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection); DEFINE_RPC_SOCKET_EVENT(rpc_socket_close); DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown); +TRACE_EVENT(svc_recv, + TP_PROTO(struct svc_rqst *rqst, int status), + + TP_ARGS(rqst, status), + + TP_STRUCT__entry( + __field(struct sockaddr *, addr) + __field(__be32, xid) + __field(int, status) + ), + + TP_fast_assign( + __entry->addr = (struct sockaddr *)&rqst->rq_addr; + __entry->xid = status > 0 ? rqst->rq_xid : 0; + __entry->status = status; + ), + + TP_printk("addr=%pIScp xid=0x%x status=%d", __entry->addr, + be32_to_cpu(__entry->xid), __entry->status) +); + +DECLARE_EVENT_CLASS(svc_rqst_status, + + TP_PROTO(struct svc_rqst *rqst, int status), + + TP_ARGS(rqst, status), + + TP_STRUCT__entry( + __field(struct sockaddr *, addr) + __field(__be32, xid) + __field(int, dropme) + __field(int, status) + ), + + TP_fast_assign( + __entry->addr = (struct sockaddr *)&rqst->rq_addr; + __entry->xid = rqst->rq_xid; + __entry->dropme = (int)rqst->rq_dropme; + __entry->status = status; + ), + + TP_printk("addr=%pIScp rq_xid=0x%x dropme=%d status=%d", + __entry->addr, be32_to_cpu(__entry->xid), __entry->dropme, + __entry->status) +); + +DEFINE_EVENT(svc_rqst_status, svc_process, + TP_PROTO(struct svc_rqst *rqst, int status), + TP_ARGS(rqst, status)); + +DEFINE_EVENT(svc_rqst_status, svc_send, + TP_PROTO(struct svc_rqst *rqst, int status), + TP_ARGS(rqst, status)); + #endif /* _TRACE_SUNRPC_H */ #include diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index ca8a7958f4e6..371a8bbb43d6 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -28,6 +28,8 @@ #include #include +#include + #define RPCDBG_FACILITY RPCDBG_SVCDSP static void svc_unregister(const struct svc_serv *serv, struct net *net); @@ -1314,24 +1316,25 @@ svc_process(struct svc_rqst *rqstp) rqstp->rq_res.tail[0].iov_base = NULL; rqstp->rq_res.tail[0].iov_len = 0; - rqstp->rq_xid = svc_getu32(argv); - dir = svc_getnl(argv); if (dir != 0) { /* direction != CALL */ svc_printk(rqstp, "bad direction %d, dropping request\n", dir); serv->sv_stats->rpcbadfmt++; - svc_drop(rqstp); - return 0; + goto out_drop; } /* Returns 1 for send, 0 for drop */ - if (svc_process_common(rqstp, argv, resv)) - return svc_send(rqstp); - else { - svc_drop(rqstp); - return 0; + if (likely(svc_process_common(rqstp, argv, resv))) { + int ret = svc_send(rqstp); + + trace_svc_process(rqstp, ret); + return ret; } +out_drop: + trace_svc_process(rqstp, 0); + svc_drop(rqstp); + return 0; } #if defined(CONFIG_SUNRPC_BACKCHANNEL) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index c179ca2a5aa4..bbb3b044b877 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -15,6 +15,7 @@ #include #include #include +#include #define RPCDBG_FACILITY RPCDBG_SVCXPRT @@ -773,35 +774,43 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) err = svc_alloc_arg(rqstp); if (err) - return err; + goto out; try_to_freeze(); cond_resched(); + err = -EINTR; if (signalled() || kthread_should_stop()) - return -EINTR; + goto out; xprt = svc_get_next_xprt(rqstp, timeout); - if (IS_ERR(xprt)) - return PTR_ERR(xprt); + if (IS_ERR(xprt)) { + err = PTR_ERR(xprt); + goto out; + } len = svc_handle_xprt(rqstp, xprt); /* No data, incomplete (TCP) read, or accept() */ + err = -EAGAIN; if (len <= 0) - goto out; + goto out_release; clear_bit(XPT_OLD, &xprt->xpt_flags); rqstp->rq_secure = xprt->xpt_ops->xpo_secure_port(rqstp); rqstp->rq_chandle.defer = svc_defer; + rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]); if (serv->sv_stats) serv->sv_stats->netcnt++; + trace_svc_recv(rqstp, len); return len; -out: +out_release: rqstp->rq_res.len = 0; svc_xprt_release(rqstp); - return -EAGAIN; +out: + trace_svc_recv(rqstp, err); + return err; } EXPORT_SYMBOL_GPL(svc_recv); @@ -821,12 +830,12 @@ EXPORT_SYMBOL_GPL(svc_drop); int svc_send(struct svc_rqst *rqstp) { struct svc_xprt *xprt; - int len; + int len = -EFAULT; struct xdr_buf *xb; xprt = rqstp->rq_xprt; if (!xprt) - return -EFAULT; + goto out; /* release the receive skb before sending the reply */ rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp); @@ -849,7 +858,9 @@ int svc_send(struct svc_rqst *rqstp) svc_xprt_release(rqstp); if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) - return 0; + len = 0; +out: + trace_svc_send(rqstp, len); return len; } -- GitLab From 3705ad64f123271b2b88dbff0c9891b7b90299d2 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 28 Oct 2014 14:24:13 -0400 Subject: [PATCH 6225/9457] sunrpc: add new tracepoints in xprt handling code ...so we can keep track of when calls are sent and replies received. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/trace/events/sunrpc.h | 63 +++++++++++++++++++++++++++++++++++ net/sunrpc/xprt.c | 9 ++++- net/sunrpc/xprtsock.c | 8 ++++- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 6260f5134212..5edb16bcd836 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -307,6 +307,69 @@ DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket_reset_connection); DEFINE_RPC_SOCKET_EVENT(rpc_socket_close); DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown); +DECLARE_EVENT_CLASS(rpc_xprt_event, + TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status), + + TP_ARGS(xprt, xid, status), + + TP_STRUCT__entry( + __field(__be32, xid) + __field(int, status) + __string(addr, xprt->address_strings[RPC_DISPLAY_ADDR]) + __string(port, xprt->address_strings[RPC_DISPLAY_PORT]) + ), + + TP_fast_assign( + __entry->xid = xid; + __entry->status = status; + __assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]); + __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]); + ), + + TP_printk("peer=%s/%s xid=0x%x status=%d", __get_str(addr), + __get_str(port), be32_to_cpu(__entry->xid), + __entry->status) +); + +DEFINE_EVENT(rpc_xprt_event, xprt_lookup_rqst, + TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status), + TP_ARGS(xprt, xid, status)); + +DEFINE_EVENT(rpc_xprt_event, xprt_transmit, + TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status), + TP_ARGS(xprt, xid, status)); + +DEFINE_EVENT(rpc_xprt_event, xprt_complete_rqst, + TP_PROTO(struct rpc_xprt *xprt, __be32 xid, int status), + TP_ARGS(xprt, xid, status)); + +TRACE_EVENT(xs_tcp_data_ready, + TP_PROTO(struct rpc_xprt *xprt, int err, unsigned int total), + + TP_ARGS(xprt, err, total), + + TP_STRUCT__entry( + __field(int, err) + __field(unsigned int, total) + __string(addr, xprt ? xprt->address_strings[RPC_DISPLAY_ADDR] : + "(null)") + __string(port, xprt ? xprt->address_strings[RPC_DISPLAY_PORT] : + "(null)") + ), + + TP_fast_assign( + __entry->err = err; + __entry->total = total; + __assign_str(addr, xprt ? + xprt->address_strings[RPC_DISPLAY_ADDR] : "(null)"); + __assign_str(port, xprt ? + xprt->address_strings[RPC_DISPLAY_PORT] : "(null)"); + ), + + TP_printk("peer=[%s]:%s err=%d total=%u", __get_str(addr), + __get_str(port), __entry->err, __entry->total) +); + TRACE_EVENT(svc_recv, TP_PROTO(struct svc_rqst *rqst, int status), diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 56e4e150e80e..1b2e5e616cae 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -49,6 +49,8 @@ #include #include +#include + #include "sunrpc.h" /* @@ -772,11 +774,14 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) struct rpc_rqst *entry; list_for_each_entry(entry, &xprt->recv, rq_list) - if (entry->rq_xid == xid) + if (entry->rq_xid == xid) { + trace_xprt_lookup_rqst(xprt, xid, 0); return entry; + } dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n", ntohl(xid)); + trace_xprt_lookup_rqst(xprt, xid, -ENOENT); xprt->stat.bad_xids++; return NULL; } @@ -810,6 +815,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", task->tk_pid, ntohl(req->rq_xid), copied); + trace_xprt_complete_rqst(xprt, req->rq_xid, copied); xprt->stat.recvs++; req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime); @@ -926,6 +932,7 @@ void xprt_transmit(struct rpc_task *task) req->rq_xtime = ktime_get(); status = xprt->ops->send_request(task); + trace_xprt_transmit(xprt, req->rq_xid, status); if (status != 0) { task->tk_status = status; return; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3b305ab17afe..b63e26272dc2 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1454,12 +1454,15 @@ static void xs_tcp_data_ready(struct sock *sk) struct rpc_xprt *xprt; read_descriptor_t rd_desc; int read; + unsigned long total = 0; dprintk("RPC: xs_tcp_data_ready...\n"); read_lock_bh(&sk->sk_callback_lock); - if (!(xprt = xprt_from_sock(sk))) + if (!(xprt = xprt_from_sock(sk))) { + read = 0; goto out; + } /* Any data means we had a useful conversation, so * the we don't need to delay the next reconnect */ @@ -1471,8 +1474,11 @@ static void xs_tcp_data_ready(struct sock *sk) do { rd_desc.count = 65536; read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); + if (read > 0) + total += read; } while (read > 0); out: + trace_xs_tcp_data_ready(xprt, read, total); read_unlock_bh(&sk->sk_callback_lock); } -- GitLab From 1a867a0898b2e366a1eb5b7fe21413a2b2b1629f Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 28 Oct 2014 14:24:14 -0400 Subject: [PATCH 6226/9457] sunrpc: add tracepoints in xs_tcp_data_recv Add tracepoints inside the main loop on xs_tcp_data_recv that allow us to keep an eye on what's happening during each phase of it. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprtsock.h | 59 +++++++++++++++++++++++++++++++ include/trace/events/sunrpc.h | 44 +++++++++++++++++++++++- net/sunrpc/xprtsock.c | 61 ++------------------------------- 3 files changed, 104 insertions(+), 60 deletions(-) diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index 1ad36cc25b2e..7591788e9fbf 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h @@ -17,6 +17,65 @@ void cleanup_socket_xprt(void); #define RPC_DEF_MIN_RESVPORT (665U) #define RPC_DEF_MAX_RESVPORT (1023U) +struct sock_xprt { + struct rpc_xprt xprt; + + /* + * Network layer + */ + struct socket * sock; + struct sock * inet; + + /* + * State of TCP reply receive + */ + __be32 tcp_fraghdr, + tcp_xid, + tcp_calldir; + + u32 tcp_offset, + tcp_reclen; + + unsigned long tcp_copied, + tcp_flags; + + /* + * Connection of transports + */ + struct delayed_work connect_worker; + struct sockaddr_storage srcaddr; + unsigned short srcport; + + /* + * UDP socket buffer size parameters + */ + size_t rcvsize, + sndsize; + + /* + * Saved socket callback addresses + */ + void (*old_data_ready)(struct sock *); + void (*old_state_change)(struct sock *); + void (*old_write_space)(struct sock *); + void (*old_error_report)(struct sock *); +}; + +/* + * TCP receive state flags + */ +#define TCP_RCV_LAST_FRAG (1UL << 0) +#define TCP_RCV_COPY_FRAGHDR (1UL << 1) +#define TCP_RCV_COPY_XID (1UL << 2) +#define TCP_RCV_COPY_DATA (1UL << 3) +#define TCP_RCV_READ_CALLDIR (1UL << 4) +#define TCP_RCV_COPY_CALLDIR (1UL << 5) + +/* + * TCP RPC flags + */ +#define TCP_RPC_REPLY (1UL << 6) + #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_XPRTSOCK_H */ diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 5edb16bcd836..171ca4ff6d99 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -326,7 +327,7 @@ DECLARE_EVENT_CLASS(rpc_xprt_event, __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]); ), - TP_printk("peer=%s/%s xid=0x%x status=%d", __get_str(addr), + TP_printk("peer=[%s]:%s xid=0x%x status=%d", __get_str(addr), __get_str(port), be32_to_cpu(__entry->xid), __entry->status) ); @@ -370,6 +371,47 @@ TRACE_EVENT(xs_tcp_data_ready, __get_str(port), __entry->err, __entry->total) ); +#define rpc_show_sock_xprt_flags(flags) \ + __print_flags(flags, "|", \ + { TCP_RCV_LAST_FRAG, "TCP_RCV_LAST_FRAG" }, \ + { TCP_RCV_COPY_FRAGHDR, "TCP_RCV_COPY_FRAGHDR" }, \ + { TCP_RCV_COPY_XID, "TCP_RCV_COPY_XID" }, \ + { TCP_RCV_COPY_DATA, "TCP_RCV_COPY_DATA" }, \ + { TCP_RCV_READ_CALLDIR, "TCP_RCV_READ_CALLDIR" }, \ + { TCP_RCV_COPY_CALLDIR, "TCP_RCV_COPY_CALLDIR" }, \ + { TCP_RPC_REPLY, "TCP_RPC_REPLY" }) + +TRACE_EVENT(xs_tcp_data_recv, + TP_PROTO(struct sock_xprt *xs), + + TP_ARGS(xs), + + TP_STRUCT__entry( + __string(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR]) + __string(port, xs->xprt.address_strings[RPC_DISPLAY_PORT]) + __field(__be32, xid) + __field(unsigned long, flags) + __field(unsigned long, copied) + __field(unsigned int, reclen) + __field(unsigned long, offset) + ), + + TP_fast_assign( + __assign_str(addr, xs->xprt.address_strings[RPC_DISPLAY_ADDR]); + __assign_str(port, xs->xprt.address_strings[RPC_DISPLAY_PORT]); + __entry->xid = xs->tcp_xid; + __entry->flags = xs->tcp_flags; + __entry->copied = xs->tcp_copied; + __entry->reclen = xs->tcp_reclen; + __entry->offset = xs->tcp_offset; + ), + + TP_printk("peer=[%s]:%s xid=0x%x flags=%s copied=%lu reclen=%u offset=%lu", + __get_str(addr), __get_str(port), be32_to_cpu(__entry->xid), + rpc_show_sock_xprt_flags(__entry->flags), + __entry->copied, __entry->reclen, __entry->offset) +); + TRACE_EVENT(svc_recv, TP_PROTO(struct svc_rqst *rqst, int status), diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b63e26272dc2..31c015196a29 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -216,65 +216,6 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count) } #endif -struct sock_xprt { - struct rpc_xprt xprt; - - /* - * Network layer - */ - struct socket * sock; - struct sock * inet; - - /* - * State of TCP reply receive - */ - __be32 tcp_fraghdr, - tcp_xid, - tcp_calldir; - - u32 tcp_offset, - tcp_reclen; - - unsigned long tcp_copied, - tcp_flags; - - /* - * Connection of transports - */ - struct delayed_work connect_worker; - struct sockaddr_storage srcaddr; - unsigned short srcport; - - /* - * UDP socket buffer size parameters - */ - size_t rcvsize, - sndsize; - - /* - * Saved socket callback addresses - */ - void (*old_data_ready)(struct sock *); - void (*old_state_change)(struct sock *); - void (*old_write_space)(struct sock *); - void (*old_error_report)(struct sock *); -}; - -/* - * TCP receive state flags - */ -#define TCP_RCV_LAST_FRAG (1UL << 0) -#define TCP_RCV_COPY_FRAGHDR (1UL << 1) -#define TCP_RCV_COPY_XID (1UL << 2) -#define TCP_RCV_COPY_DATA (1UL << 3) -#define TCP_RCV_READ_CALLDIR (1UL << 4) -#define TCP_RCV_COPY_CALLDIR (1UL << 5) - -/* - * TCP RPC flags - */ -#define TCP_RPC_REPLY (1UL << 6) - static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) { return (struct rpc_xprt *) sk->sk_user_data; @@ -1415,6 +1356,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns dprintk("RPC: xs_tcp_data_recv started\n"); do { + trace_xs_tcp_data_recv(transport); /* Read in a new fragment marker if necessary */ /* Can we ever really expect to get completely empty fragments? */ if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) { @@ -1439,6 +1381,7 @@ static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, uns /* Skip over any trailing bytes on short reads */ xs_tcp_read_discard(transport, &desc); } while (desc.count); + trace_xs_tcp_data_recv(transport); dprintk("RPC: xs_tcp_data_recv done\n"); return len - desc.count; } -- GitLab From a6e4599f8d232b5911c46bb16f5a79b86f3dfb75 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 15:04:12 +0100 Subject: [PATCH 6227/9457] ASoC: uda134x: Remove is_powered_on_standby from platform data According to its documentation the is_powered_on_standby field of the uda134x platform data is supposed to prevent the the driver from shutting down the ADC and DAC in standby mode. This behavior was broken in commit commit f0fba2ad1b6b ("ASoC: multi-component - ASoC Multi-Component Support") almost 5 years ago and all the flag does now is cause the driver to go to SND_SOC_BIAS_ON in probe, just for the ASoC core to put it back into SND_SOC_BIAS_STANDBY right after probe. Apparently the intended behavior has not been missed, so just remove is_powered_on_standby from the platform data struct. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/uda134x.h | 12 ------------ sound/soc/codecs/uda134x.c | 5 +---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/include/sound/uda134x.h b/include/sound/uda134x.h index e475659bd3be..509efb050176 100644 --- a/include/sound/uda134x.h +++ b/include/sound/uda134x.h @@ -18,18 +18,6 @@ struct uda134x_platform_data { struct l3_pins l3; void (*power) (int); int model; - /* - ALSA SOC usually puts the device in standby mode when it's not used - for sometime. If you unset is_powered_on_standby the driver will - turn off the ADC/DAC when this callback is invoked and turn it back - on when needed. Unfortunately this will result in a very light bump - (it can be audible only with good earphones). If this bothers you - set is_powered_on_standby, you will have slightly higher power - consumption. Please note that sending the L3 command for ADC is - enough to make the bump, so it doesn't make difference if you - completely take off power from the codec. - */ - int is_powered_on_standby; #define UDA134X_UDA1340 1 #define UDA134X_UDA1341 2 #define UDA134X_UDA1344 3 diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 32b2f78aa62c..54240f14211f 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -518,10 +518,7 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) uda134x_reset(codec); - if (pd->is_powered_on_standby) - uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); - else - uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); if (pd->model == UDA134X_UDA1341) { widgets = uda1341_dapm_widgets; -- GitLab From e03b975506545d21b1daa5c8310b59d66e74919c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 15:04:13 +0100 Subject: [PATCH 6228/9457] ASoC: uda134x: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/uda134x.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 54240f14211f..4056260a502e 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -518,8 +518,6 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) uda134x_reset(codec); - uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (pd->model == UDA134X_UDA1341) { widgets = uda1341_dapm_widgets; num_widgets = ARRAY_SIZE(uda1341_dapm_widgets); @@ -571,44 +569,21 @@ static int uda134x_soc_remove(struct snd_soc_codec *codec) { struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); - uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); - kfree(uda134x); return 0; } -#if defined(CONFIG_PM) -static int uda134x_soc_suspend(struct snd_soc_codec *codec) -{ - uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int uda134x_soc_resume(struct snd_soc_codec *codec) -{ - uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); - return 0; -} -#else -#define uda134x_soc_suspend NULL -#define uda134x_soc_resume NULL -#endif /* CONFIG_PM */ - static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, .remove = uda134x_soc_remove, - .suspend = uda134x_soc_suspend, - .resume = uda134x_soc_resume, .reg_cache_size = sizeof(uda134x_reg), .reg_word_size = sizeof(u8), .reg_cache_default = uda134x_reg, .reg_cache_step = 1, .read = uda134x_read_reg_cache, - .write = uda134x_write, .set_bias_level = uda134x_set_bias_level, + .suspend_bias_off = true, + .dapm_widgets = uda134x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), .dapm_routes = uda134x_dapm_routes, -- GitLab From e8125f04421f7757df0017a59cd9b756148ee769 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 15:04:14 +0100 Subject: [PATCH 6229/9457] ASoC: uda1380: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/uda1380.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index e62e70781ec2..dc7778b6dd7f 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -693,18 +693,6 @@ static struct snd_soc_dai_driver uda1380_dai[] = { }, }; -static int uda1380_suspend(struct snd_soc_codec *codec) -{ - uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int uda1380_resume(struct snd_soc_codec *codec) -{ - uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int uda1380_probe(struct snd_soc_codec *codec) { struct uda1380_platform_data *pdata =codec->dev->platform_data; @@ -739,8 +727,6 @@ static int uda1380_probe(struct snd_soc_codec *codec) INIT_WORK(&uda1380->work, uda1380_flush_work); - /* power on device */ - uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* set clock input */ switch (pdata->dac_clk) { case UDA1380_DAC_CLK_SYSCLK: @@ -766,8 +752,6 @@ static int uda1380_remove(struct snd_soc_codec *codec) { struct uda1380_platform_data *pdata =codec->dev->platform_data; - uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); - gpio_free(pdata->gpio_reset); gpio_free(pdata->gpio_power); @@ -777,11 +761,11 @@ static int uda1380_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .probe = uda1380_probe, .remove = uda1380_remove, - .suspend = uda1380_suspend, - .resume = uda1380_resume, .read = uda1380_read_reg_cache, .write = uda1380_write, .set_bias_level = uda1380_set_bias_level, + .suspend_bias_off = true, + .reg_cache_size = ARRAY_SIZE(uda1380_reg), .reg_word_size = sizeof(u16), .reg_cache_default = uda1380_reg, -- GitLab From 2849bde56aac38645c5ed2af3971358b89a929f6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:47:50 +0100 Subject: [PATCH 6230/9457] ASoC: alc5623: Cleanup bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Also remove the manual sequencing back to SND_SOC_BIAS_ON in resume as this is already handled by the ASoC core. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/alc5623.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 9d0755aa1d16..bdf8c5ac8ca4 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -866,7 +866,6 @@ static int alc5623_suspend(struct snd_soc_codec *codec) { struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); - alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); regcache_cache_only(alc5623->regmap, true); return 0; @@ -887,15 +886,6 @@ static int alc5623_resume(struct snd_soc_codec *codec) return ret; } - alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* charge alc5623 caps */ - if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { - alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - codec->dapm.bias_level = SND_SOC_BIAS_ON; - alc5623_set_bias_level(codec, codec->dapm.bias_level); - } - return 0; } @@ -906,9 +896,6 @@ static int alc5623_probe(struct snd_soc_codec *codec) alc5623_reset(codec); - /* power on device */ - alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (alc5623->add_ctrl) { snd_soc_write(codec, ALC5623_ADD_CTRL_REG, alc5623->add_ctrl); @@ -964,19 +951,12 @@ static int alc5623_probe(struct snd_soc_codec *codec) return 0; } -/* power down chip */ -static int alc5623_remove(struct snd_soc_codec *codec) -{ - alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_device_alc5623 = { .probe = alc5623_probe, - .remove = alc5623_remove, .suspend = alc5623_suspend, .resume = alc5623_resume, .set_bias_level = alc5623_set_bias_level, + .suspend_bias_off = true, }; static const struct regmap_config alc5623_regmap = { -- GitLab From 5c9dc0898f343473efa3056fff9d5a9fbd577272 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:47:51 +0100 Subject: [PATCH 6231/9457] ASoC: alc5632: Cleanup bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/alc5632.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 85942ca36cbf..d1fdbc266631 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1038,23 +1038,15 @@ static struct snd_soc_dai_driver alc5632_dai = { }; #ifdef CONFIG_PM -static int alc5632_suspend(struct snd_soc_codec *codec) -{ - alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int alc5632_resume(struct snd_soc_codec *codec) { struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); regcache_sync(alc5632->regmap); - alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } #else -#define alc5632_suspend NULL #define alc5632_resume NULL #endif @@ -1062,9 +1054,6 @@ static int alc5632_probe(struct snd_soc_codec *codec) { struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); - /* power on device */ - alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - switch (alc5632->id) { case 0x5c: snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls, @@ -1077,19 +1066,12 @@ static int alc5632_probe(struct snd_soc_codec *codec) return 0; } -/* power down chip */ -static int alc5632_remove(struct snd_soc_codec *codec) -{ - alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_device_alc5632 = { .probe = alc5632_probe, - .remove = alc5632_remove, - .suspend = alc5632_suspend, .resume = alc5632_resume, .set_bias_level = alc5632_set_bias_level, + .suspend_bias_off = true, + .controls = alc5632_snd_controls, .num_controls = ARRAY_SIZE(alc5632_snd_controls), .dapm_widgets = alc5632_dapm_widgets, -- GitLab From e2dce944cc2bf22d0295330cbdcbd2ad7bd47cb4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:47:52 +0100 Subject: [PATCH 6232/9457] ASoC: rt5631: Cleanup bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/rt5631.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 9425545e8403..6d7b7ca7d530 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1612,29 +1612,6 @@ static int rt5631_probe(struct snd_soc_codec *codec) return 0; } -static int rt5631_remove(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -#ifdef CONFIG_PM -static int rt5631_suspend(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int rt5631_resume(struct snd_soc_codec *codec) -{ - rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define rt5631_suspend NULL -#define rt5631_resume NULL -#endif - #define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000 #define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \ @@ -1672,10 +1649,8 @@ static struct snd_soc_dai_driver rt5631_dai[] = { static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { .probe = rt5631_probe, - .remove = rt5631_remove, - .suspend = rt5631_suspend, - .resume = rt5631_resume, .set_bias_level = rt5631_set_bias_level, + .suspend_bias_off = true, .controls = rt5631_snd_controls, .num_controls = ARRAY_SIZE(rt5631_snd_controls), .dapm_widgets = rt5631_dapm_widgets, -- GitLab From 21a942fdd85efde65512f1458bcb952fda88886e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:17 +0100 Subject: [PATCH 6233/9457] ASoC: wm8350: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 628ec774cf22..87f664b9cc7d 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1242,19 +1242,6 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8350_suspend(struct snd_soc_codec *codec) -{ - wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8350_resume(struct snd_soc_codec *codec) -{ - wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - static void wm8350_hp_work(struct wm8350_data *priv, struct wm8350_jack_data *jack, u16 mask) @@ -1565,9 +1552,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, wm8350_mic_handler, 0, "Microphone detect", priv); - - wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; } @@ -1596,8 +1580,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) * wait for its completion */ flush_delayed_work(&codec->dapm.delayed_work); - wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); - wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); return 0; @@ -1613,10 +1595,9 @@ static struct regmap *wm8350_get_regmap(struct device *dev) static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .probe = wm8350_codec_probe, .remove = wm8350_codec_remove, - .suspend = wm8350_suspend, - .resume = wm8350_resume, .get_regmap = wm8350_get_regmap, .set_bias_level = wm8350_set_bias_level, + .suspend_bias_off = true, .controls = wm8350_snd_controls, .num_controls = ARRAY_SIZE(wm8350_snd_controls), -- GitLab From 098f6f17c3f1beeccdce78f9722ccaa7925b8041 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:18 +0100 Subject: [PATCH 6234/9457] ASoC: wm8400: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual asynchronous transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Also running this asynchronously has the problem of potential race conditions with the core. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8400.c | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 72471bef2e9a..385894f6e264 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -58,12 +58,10 @@ static struct regulator_bulk_data power[] = { /* codec private data */ struct wm8400_priv { - struct snd_soc_codec *codec; struct wm8400 *wm8400; u16 fake_register; unsigned int sysclk; unsigned int pcmclk; - struct work_struct work; int fll_in, fll_out; }; @@ -1278,30 +1276,6 @@ static struct snd_soc_dai_driver wm8400_dai = { .ops = &wm8400_dai_ops, }; -static int wm8400_suspend(struct snd_soc_codec *codec) -{ - wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8400_resume(struct snd_soc_codec *codec) -{ - wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static void wm8400_probe_deferred(struct work_struct *work) -{ - struct wm8400_priv *priv = container_of(work, struct wm8400_priv, - work); - struct snd_soc_codec *codec = priv->codec; - - /* charge output caps */ - wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); -} - static int wm8400_codec_probe(struct snd_soc_codec *codec) { struct wm8400 *wm8400 = dev_get_platdata(codec->dev); @@ -1316,7 +1290,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, priv); priv->wm8400 = wm8400; - priv->codec = codec; ret = devm_regulator_bulk_get(wm8400->dev, ARRAY_SIZE(power), &power[0]); @@ -1325,8 +1298,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) return ret; } - INIT_WORK(&priv->work, wm8400_probe_deferred); - wm8400_codec_reset(codec); reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1); @@ -1343,8 +1314,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - if (!schedule_work(&priv->work)) - return -EINVAL; return 0; } @@ -1369,10 +1338,9 @@ static struct regmap *wm8400_get_regmap(struct device *dev) static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { .probe = wm8400_codec_probe, .remove = wm8400_codec_remove, - .suspend = wm8400_suspend, - .resume = wm8400_resume, .get_regmap = wm8400_get_regmap, .set_bias_level = wm8400_set_bias_level, + .suspend_bias_off = true, .controls = wm8400_snd_controls, .num_controls = ARRAY_SIZE(wm8400_snd_controls), -- GitLab From 99b108c73f3876d71ac6631e85e0f093e53b7e66 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:19 +0100 Subject: [PATCH 6235/9457] ASoC: wm8510: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8510.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index e11127f9069e..8736ad094b24 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -575,41 +575,17 @@ static struct snd_soc_dai_driver wm8510_dai = { .symmetric_rates = 1, }; -static int wm8510_suspend(struct snd_soc_codec *codec) -{ - wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8510_resume(struct snd_soc_codec *codec) -{ - wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8510_probe(struct snd_soc_codec *codec) { wm8510_reset(codec); - /* power on device */ - wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -/* power down chip */ -static int wm8510_remove(struct snd_soc_codec *codec) -{ - wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { .probe = wm8510_probe, - .remove = wm8510_remove, - .suspend = wm8510_suspend, - .resume = wm8510_resume, .set_bias_level = wm8510_set_bias_level, + .suspend_bias_off = true, .controls = wm8510_snd_controls, .num_controls = ARRAY_SIZE(wm8510_snd_controls), -- GitLab From ca5e7c6afff94b4e103d79db835bc2990d3d340e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:20 +0100 Subject: [PATCH 6236/9457] ASoC: wm8523: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8523.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index ec1f5740dbd0..b1cc94f5fc4b 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -372,23 +372,6 @@ static struct snd_soc_dai_driver wm8523_dai = { .ops = &wm8523_dai_ops, }; -#ifdef CONFIG_PM -static int wm8523_suspend(struct snd_soc_codec *codec) -{ - wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8523_resume(struct snd_soc_codec *codec) -{ - wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8523_suspend NULL -#define wm8523_resume NULL -#endif - static int wm8523_probe(struct snd_soc_codec *codec) { struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); @@ -402,23 +385,13 @@ static int wm8523_probe(struct snd_soc_codec *codec) WM8523_DACR_VU, WM8523_DACR_VU); snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC); - wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int wm8523_remove(struct snd_soc_codec *codec) -{ - wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { .probe = wm8523_probe, - .remove = wm8523_remove, - .suspend = wm8523_suspend, - .resume = wm8523_resume, .set_bias_level = wm8523_set_bias_level, + .suspend_bias_off = true, .controls = wm8523_controls, .num_controls = ARRAY_SIZE(wm8523_controls), -- GitLab From 4d0a4c3c6dd2359c3d5facac7a306d513d79bff2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:21 +0100 Subject: [PATCH 6237/9457] ASoC: wm8580: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8580.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 911605ee25b0..0a887c5ec83a 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -882,8 +882,6 @@ static int wm8580_probe(struct snd_soc_codec *codec) goto err_regulator_enable; } - wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; err_regulator_enable: @@ -897,8 +895,6 @@ static int wm8580_remove(struct snd_soc_codec *codec) { struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); - wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF); - regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); return 0; -- GitLab From 0bd324b1ad5c0922ac3f157763123d1550bdffd7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:22 +0100 Subject: [PATCH 6238/9457] ASoC: wm8711: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Also remove the extra write that sets the WM8711_ACTIVE register to 0x00 in the suspend handler since this write is already done when transitioning to SND_SOC_BIAS_OFF. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8711.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 32187e739b4f..121e46d53779 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -350,19 +350,6 @@ static struct snd_soc_dai_driver wm8711_dai = { .ops = &wm8711_ops, }; -static int wm8711_suspend(struct snd_soc_codec *codec) -{ - snd_soc_write(codec, WM8711_ACTIVE, 0x0); - wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8711_resume(struct snd_soc_codec *codec) -{ - wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8711_probe(struct snd_soc_codec *codec) { int ret; @@ -373,8 +360,6 @@ static int wm8711_probe(struct snd_soc_codec *codec) return ret; } - wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Latch the update bits */ snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100); @@ -383,19 +368,11 @@ static int wm8711_probe(struct snd_soc_codec *codec) } -/* power down chip */ -static int wm8711_remove(struct snd_soc_codec *codec) -{ - wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { .probe = wm8711_probe, - .remove = wm8711_remove, - .suspend = wm8711_suspend, - .resume = wm8711_resume, .set_bias_level = wm8711_set_bias_level, + .suspend_bias_off = true, + .controls = wm8711_snd_controls, .num_controls = ARRAY_SIZE(wm8711_snd_controls), .dapm_widgets = wm8711_dapm_widgets, -- GitLab From d4d41436ff3b1fddf2f8feafa6772647eac6b61d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:23 +0100 Subject: [PATCH 6239/9457] ASoC: wm8728: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8728.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 38ff826f589a..55c7fb4fc786 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -212,40 +212,10 @@ static struct snd_soc_dai_driver wm8728_dai = { .ops = &wm8728_dai_ops, }; -static int wm8728_suspend(struct snd_soc_codec *codec) -{ - wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8728_resume(struct snd_soc_codec *codec) -{ - wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int wm8728_probe(struct snd_soc_codec *codec) -{ - /* power on device */ - wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int wm8728_remove(struct snd_soc_codec *codec) -{ - wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { - .probe = wm8728_probe, - .remove = wm8728_remove, - .suspend = wm8728_suspend, - .resume = wm8728_resume, .set_bias_level = wm8728_set_bias_level, + .suspend_bias_off = true, + .controls = wm8728_snd_controls, .num_controls = ARRAY_SIZE(wm8728_snd_controls), .dapm_widgets = wm8728_dapm_widgets, -- GitLab From 2081b2cf05d022ac6245334e8baa25f589e5635a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:24 +0100 Subject: [PATCH 6240/9457] ASoC: wm8731: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8731.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 2c9f2a7005c3..3b3786e5c271 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -559,25 +559,6 @@ static struct snd_soc_dai_driver wm8731_dai = { .symmetric_rates = 1, }; -#ifdef CONFIG_PM -static int wm8731_suspend(struct snd_soc_codec *codec) -{ - wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8731_resume(struct snd_soc_codec *codec) -{ - wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm8731_suspend NULL -#define wm8731_resume NULL -#endif - static int wm8731_probe(struct snd_soc_codec *codec) { struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); @@ -633,8 +614,6 @@ static int wm8731_remove(struct snd_soc_codec *codec) { struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); - wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); - regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); return 0; @@ -643,9 +622,9 @@ static int wm8731_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { .probe = wm8731_probe, .remove = wm8731_remove, - .suspend = wm8731_suspend, - .resume = wm8731_resume, .set_bias_level = wm8731_set_bias_level, + .suspend_bias_off = true, + .dapm_widgets = wm8731_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), .dapm_routes = wm8731_intercon, -- GitLab From 67cac3a351b9d411f8736a180767f0e898b50423 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:25 +0100 Subject: [PATCH 6241/9457] ASoC: wm8737: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8737.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index fe41dd2b9b45..ada9ac1ba2c6 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -537,23 +537,6 @@ static struct snd_soc_dai_driver wm8737_dai = { .ops = &wm8737_dai_ops, }; -#ifdef CONFIG_PM -static int wm8737_suspend(struct snd_soc_codec *codec) -{ - wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8737_resume(struct snd_soc_codec *codec) -{ - wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8737_suspend NULL -#define wm8737_resume NULL -#endif - static int wm8737_probe(struct snd_soc_codec *codec) { struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); @@ -590,18 +573,10 @@ static int wm8737_probe(struct snd_soc_codec *codec) return ret; } -static int wm8737_remove(struct snd_soc_codec *codec) -{ - wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { .probe = wm8737_probe, - .remove = wm8737_remove, - .suspend = wm8737_suspend, - .resume = wm8737_resume, .set_bias_level = wm8737_set_bias_level, + .suspend_bias_off = true, .controls = wm8737_snd_controls, .num_controls = ARRAY_SIZE(wm8737_snd_controls), -- GitLab From d12cbf956f428229bb29fb58dee8729e16873ca7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:26 +0100 Subject: [PATCH 6242/9457] ASoC: wm8750: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8750.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 67653a2db223..f6847fdd6ddd 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -686,18 +686,6 @@ static struct snd_soc_dai_driver wm8750_dai = { .ops = &wm8750_dai_ops, }; -static int wm8750_suspend(struct snd_soc_codec *codec) -{ - wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8750_resume(struct snd_soc_codec *codec) -{ - wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8750_probe(struct snd_soc_codec *codec) { int ret; @@ -708,9 +696,6 @@ static int wm8750_probe(struct snd_soc_codec *codec) return ret; } - /* charge output caps */ - wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* set the update bits */ snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100); @@ -724,18 +709,10 @@ static int wm8750_probe(struct snd_soc_codec *codec) return ret; } -static int wm8750_remove(struct snd_soc_codec *codec) -{ - wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { .probe = wm8750_probe, - .remove = wm8750_remove, - .suspend = wm8750_suspend, - .resume = wm8750_resume, .set_bias_level = wm8750_set_bias_level, + .suspend_bias_off = true, .controls = wm8750_snd_controls, .num_controls = ARRAY_SIZE(wm8750_snd_controls), -- GitLab From 6c286afb01cc641e2a78e485467e4a90aedfbd75 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:27 +0100 Subject: [PATCH 6243/9457] ASoC: wm8776: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8776.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 70952ceb278b..c13050b77931 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -408,24 +408,6 @@ static struct snd_soc_dai_driver wm8776_dai[] = { }, }; -#ifdef CONFIG_PM -static int wm8776_suspend(struct snd_soc_codec *codec) -{ - wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm8776_resume(struct snd_soc_codec *codec) -{ - wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8776_suspend NULL -#define wm8776_resume NULL -#endif - static int wm8776_probe(struct snd_soc_codec *codec) { int ret = 0; @@ -436,8 +418,6 @@ static int wm8776_probe(struct snd_soc_codec *codec) return ret; } - wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Latch the update bits; right channel only since we always * update both. */ snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100); @@ -446,19 +426,10 @@ static int wm8776_probe(struct snd_soc_codec *codec) return ret; } -/* power down chip */ -static int wm8776_remove(struct snd_soc_codec *codec) -{ - wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { .probe = wm8776_probe, - .remove = wm8776_remove, - .suspend = wm8776_suspend, - .resume = wm8776_resume, .set_bias_level = wm8776_set_bias_level, + .suspend_bias_off = true, .controls = wm8776_snd_controls, .num_controls = ARRAY_SIZE(wm8776_snd_controls), -- GitLab From 6962ad52a5971dc2c91b3afe7b8124c4a197bef0 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 24 Nov 2014 12:58:58 +0800 Subject: [PATCH 6244/9457] dt-bindings: document Rockchip thermal This add the necessary binding documentation for the thermal found on Rockchip SoCs Signed-off-by: zhaoyifeng Signed-off-by: Caesar Wang Reviewed-by: Dmitry Torokhov Signed-off-by: Eduardo Valentin --- .../bindings/thermal/rockchip-thermal.txt | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/rockchip-thermal.txt diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt new file mode 100644 index 000000000000..ef802de4957a --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt @@ -0,0 +1,68 @@ +* Temperature Sensor ADC (TSADC) on rockchip SoCs + +Required properties: +- compatible : "rockchip,rk3288-tsadc" +- reg : physical base address of the controller and length of memory mapped + region. +- interrupts : The interrupt number to the cpu. The interrupt specifier format + depends on the interrupt controller. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Shall be "tsadc" for the converter-clock, and "apb_pclk" for + the peripheral clock. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the name "tsadc-apb". +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. +- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value. +- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO. +- rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW + 1:HIGH. + +Exiample: +tsadc: tsadc@ff280000 { + compatible = "rockchip,rk3288-tsadc"; + reg = <0xff280000 0x100>; + interrupts = ; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + pinctrl-names = "default"; + pinctrl-0 = <&otp_out>; + #thermal-sensor-cells = <1>; + rockchip,hw-tshut-temp = <95000>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; +}; + +Example: referring to thermal sensors: +thermal-zones { + cpu_thermal: cpu_thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 1>; + + trips { + cpu_alert0: cpu_alert { + temperature = <70000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; -- GitLab From a4235a14bef979752fb2ddb4dafdb696f622beb0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:28 +0100 Subject: [PATCH 6245/9457] ASoC: wm8804: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 3addc5fe5cb2..1315f7642503 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -524,7 +524,6 @@ static int wm8804_remove(struct snd_soc_codec *codec) int i; wm8804 = snd_soc_codec_get_drvdata(codec); - wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF); for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) regulator_unregister_notifier(wm8804->supplies[i].consumer, @@ -606,8 +605,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) goto err_reg_enable; } - wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; err_reg_enable: -- GitLab From d2a9bc68512696a896abf7a94852c5fb5e6733a1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:29 +0100 Subject: [PATCH 6246/9457] ASoC: wm8900: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8900.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 44a5f1511f0f..3a0d4b7d692f 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1209,16 +1209,8 @@ static int wm8900_probe(struct snd_soc_codec *codec) return 0; } -/* power down chip */ -static int wm8900_remove(struct snd_soc_codec *codec) -{ - wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { .probe = wm8900_probe, - .remove = wm8900_remove, .suspend = wm8900_suspend, .resume = wm8900_resume, .set_bias_level = wm8900_set_bias_level, -- GitLab From b0d55b1a63ea3c3d694c58694d93f74bea61215f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:30 +0100 Subject: [PATCH 6247/9457] ASoC: wm8903: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Also remove the unused codec field from the wm8903_priv struct so we can remove the whole probe callback. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index c038b3e04398..9758d2ed542e 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -117,7 +117,6 @@ static const struct reg_default wm8903_reg_defaults[] = { struct wm8903_priv { struct wm8903_platform_data *pdata; struct device *dev; - struct snd_soc_codec *codec; struct regmap *regmap; int sysclk; @@ -1757,21 +1756,12 @@ static struct snd_soc_dai_driver wm8903_dai = { .symmetric_rates = 1, }; -static int wm8903_suspend(struct snd_soc_codec *codec) -{ - wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - static int wm8903_resume(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); regcache_sync(wm8903->regmap); - wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; } @@ -1889,33 +1879,12 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903) } #endif -static int wm8903_probe(struct snd_soc_codec *codec) -{ - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - - wm8903->codec = codec; - - /* power on device */ - wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -/* power down chip */ -static int wm8903_remove(struct snd_soc_codec *codec) -{ - wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { - .probe = wm8903_probe, - .remove = wm8903_remove, - .suspend = wm8903_suspend, .resume = wm8903_resume, .set_bias_level = wm8903_set_bias_level, .seq_notifier = wm8903_seq_notifier, + .suspend_bias_off = true, + .controls = wm8903_snd_controls, .num_controls = ARRAY_SIZE(wm8903_snd_controls), .dapm_widgets = wm8903_dapm_widgets, -- GitLab From 5fdf082b43995ae31d746d3d9e3b616afa24c542 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:31 +0100 Subject: [PATCH 6248/9457] ASoC: wm8940: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8940.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 52011043e54c..e4142b4309eb 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -695,17 +695,6 @@ static struct snd_soc_dai_driver wm8940_dai = { .symmetric_rates = 1, }; -static int wm8940_suspend(struct snd_soc_codec *codec) -{ - return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); -} - -static int wm8940_resume(struct snd_soc_codec *codec) -{ - wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8940_probe(struct snd_soc_codec *codec) { struct wm8940_setup_data *pdata = codec->dev->platform_data; @@ -736,18 +725,11 @@ static int wm8940_probe(struct snd_soc_codec *codec) return ret; } -static int wm8940_remove(struct snd_soc_codec *codec) -{ - wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { .probe = wm8940_probe, - .remove = wm8940_remove, - .suspend = wm8940_suspend, - .resume = wm8940_resume, .set_bias_level = wm8940_set_bias_level, + .suspend_bias_off = true, + .controls = wm8940_snd_controls, .num_controls = ARRAY_SIZE(wm8940_snd_controls), .dapm_widgets = wm8940_dapm_widgets, -- GitLab From bf68a0470876b5bf43758c50a7585eb5f6e177ea Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:32 +0100 Subject: [PATCH 6249/9457] ASoC: wm8955: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Also remove the regcache_mark_dirty() from the suspend handler since this is already done by the ASoC core. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8955.c | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 09d91d9dc4ee..1173f7fef5a7 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -866,29 +866,6 @@ static struct snd_soc_dai_driver wm8955_dai = { .ops = &wm8955_dai_ops, }; -#ifdef CONFIG_PM -static int wm8955_suspend(struct snd_soc_codec *codec) -{ - struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); - - wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); - - regcache_mark_dirty(wm8955->regmap); - - return 0; -} - -static int wm8955_resume(struct snd_soc_codec *codec) -{ - wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm8955_suspend NULL -#define wm8955_resume NULL -#endif - static int wm8955_probe(struct snd_soc_codec *codec) { struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); @@ -964,18 +941,10 @@ static int wm8955_probe(struct snd_soc_codec *codec) return ret; } -static int wm8955_remove(struct snd_soc_codec *codec) -{ - wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { .probe = wm8955_probe, - .remove = wm8955_remove, - .suspend = wm8955_suspend, - .resume = wm8955_resume, .set_bias_level = wm8955_set_bias_level, + .suspend_bias_off = true, .controls = wm8955_snd_controls, .num_controls = ARRAY_SIZE(wm8955_snd_controls), -- GitLab From 0a87a6e1c09c3b93d91bf65809e79cf6cf358785 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:33 +0100 Subject: [PATCH 6250/9457] ASoC: wm8960: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8960.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 99d6457c87ba..bc8793cd1d72 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -943,22 +943,6 @@ static struct snd_soc_dai_driver wm8960_dai = { .symmetric_rates = 1, }; -static int wm8960_suspend(struct snd_soc_codec *codec) -{ - struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - - wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8960_resume(struct snd_soc_codec *codec) -{ - struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - - wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8960_probe(struct snd_soc_codec *codec) { struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); @@ -976,8 +960,6 @@ static int wm8960_probe(struct snd_soc_codec *codec) return ret; } - wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Latch the update bits */ snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100); @@ -997,21 +979,10 @@ static int wm8960_probe(struct snd_soc_codec *codec) return 0; } -/* power down chip */ -static int wm8960_remove(struct snd_soc_codec *codec) -{ - struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); - - wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { .probe = wm8960_probe, - .remove = wm8960_remove, - .suspend = wm8960_suspend, - .resume = wm8960_resume, .set_bias_level = wm8960_set_bias_level, + .suspend_bias_off = true, }; static const struct regmap_config wm8960_regmap = { -- GitLab From 7bea32c5b2493044d31a2116328c71c7048de0e3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:34 +0100 Subject: [PATCH 6251/9457] ASoC: wm8961: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8961.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index e077bb2f0740..eeffd05384b4 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -870,44 +870,26 @@ static int wm8961_probe(struct snd_soc_codec *codec) reg &= ~WM8961_MANUAL_MODE; snd_soc_write(codec, WM8961_CLOCKING_3, reg); - wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int wm8961_remove(struct snd_soc_codec *codec) -{ - wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } #ifdef CONFIG_PM -static int wm8961_suspend(struct snd_soc_codec *codec) -{ - wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} static int wm8961_resume(struct snd_soc_codec *codec) { snd_soc_cache_sync(codec); - wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; } #else -#define wm8961_suspend NULL #define wm8961_resume NULL #endif static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { .probe = wm8961_probe, - .remove = wm8961_remove, - .suspend = wm8961_suspend, .resume = wm8961_resume, .set_bias_level = wm8961_set_bias_level, + .suspend_bias_off = true, .controls = wm8961_snd_controls, .num_controls = ARRAY_SIZE(wm8961_snd_controls), -- GitLab From cbac8f63943773218f7f804754209aaa4fae33f9 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 24 Nov 2014 12:58:59 +0800 Subject: [PATCH 6252/9457] thermal: rockchip: add driver for thermal Thermal is TS-ADC Controller module supports user-defined mode and automatic mode. User-defined mode refers,TSADC all the control signals entirely by software writing to register for direct control. Automaic mode refers to the module automatically poll TSADC output, and the results were checked.If you find that the temperature High in a period of time,an interrupt is generated to the processor down-measures taken;If the temperature over a period of time High, the resulting TSHUT gave CRU module,let it reset the entire chip, or via GPIO give PMIC. Signed-off-by: zhaoyifeng Signed-off-by: Caesar Wang Reviewed-by: Dmitry Torokhov Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 10 + drivers/thermal/Makefile | 1 + drivers/thermal/rockchip_thermal.c | 693 +++++++++++++++++++++++++++++ 3 files changed, 704 insertions(+) create mode 100644 drivers/thermal/rockchip_thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 911c38aba6ef..af40db0df58e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -155,6 +155,16 @@ config SPEAR_THERMAL Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework. +config ROCKCHIP_THERMAL + tristate "Rockchip thermal driver" + depends on ARCH_ROCKCHIP + depends on RESET_CONTROLLER + help + Rockchip thermal driver provides support for Temperature sensor + ADC (TS-ADC) found on Rockchip SoCs. It supports one critical + trip point. Cpufreq is used as the cooling device and will throttle + CPUs when the Temperature crosses the passive trip point. + config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_SHMOBILE || COMPILE_TEST diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 2b18e3ac581f..fa0dc486790f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -23,6 +23,7 @@ thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o # platform thermal drivers obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o obj-y += samsung/ diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c new file mode 100644 index 000000000000..1bcddfc60e91 --- /dev/null +++ b/drivers/thermal/rockchip_thermal.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * If the temperature over a period of time High, + * the resulting TSHUT gave CRU module,let it reset the entire chip, + * or via GPIO give PMIC. + */ +enum tshut_mode { + TSHUT_MODE_CRU = 0, + TSHUT_MODE_GPIO, +}; + +/** + * the system Temperature Sensors tshut(tshut) polarity + * the bit 8 is tshut polarity. + * 0: low active, 1: high active + */ +enum tshut_polarity { + TSHUT_LOW_ACTIVE = 0, + TSHUT_HIGH_ACTIVE, +}; + +/** + * The system has three Temperature Sensors. channel 0 is reserved, + * channel 1 is for CPU, and channel 2 is for GPU. + */ +enum sensor_id { + SENSOR_CPU = 1, + SENSOR_GPU, +}; + +struct rockchip_tsadc_chip { + /* The hardware-controlled tshut property */ + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; + + /* Chip-wide methods */ + void (*initialize)(void __iomem *reg, enum tshut_polarity p); + void (*irq_ack)(void __iomem *reg); + void (*control)(void __iomem *reg, bool on); + + /* Per-sensor methods */ + int (*get_temp)(int chn, void __iomem *reg, long *temp); + void (*set_tshut_temp)(int chn, void __iomem *reg, long temp); + void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); +}; + +struct rockchip_thermal_sensor { + struct rockchip_thermal_data *thermal; + struct thermal_zone_device *tzd; + enum sensor_id id; +}; + +#define NUM_SENSORS 2 /* Ignore unused sensor 0 */ + +struct rockchip_thermal_data { + const struct rockchip_tsadc_chip *chip; + struct platform_device *pdev; + struct reset_control *reset; + + struct rockchip_thermal_sensor sensors[NUM_SENSORS]; + + struct clk *clk; + struct clk *pclk; + + void __iomem *regs; + + long tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; +}; + +/* TSADC V2 Sensor info define: */ +#define TSADCV2_AUTO_CON 0x04 +#define TSADCV2_INT_EN 0x08 +#define TSADCV2_INT_PD 0x0c +#define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04) +#define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04) +#define TSADCV2_HIGHT_INT_DEBOUNCE 0x60 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64 +#define TSADCV2_AUTO_PERIOD 0x68 +#define TSADCV2_AUTO_PERIOD_HT 0x6c + +#define TSADCV2_AUTO_EN BIT(0) +#define TSADCV2_AUTO_DISABLE ~BIT(0) +#define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) +#define TSADCV2_AUTO_TSHUT_POLARITY_LOW ~BIT(8) + +#define TSADCV2_INT_SRC_EN(chn) BIT(chn) +#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) +#define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) + +#define TSADCV2_INT_PD_CLEAR ~BIT(8) + +#define TSADCV2_DATA_MASK 0xfff +#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 +#define TSADCV2_AUTO_PERIOD_TIME 250 /* msec */ +#define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* msec */ + +struct tsadc_table { + unsigned long code; + long temp; +}; + +static const struct tsadc_table v2_code_table[] = { + {TSADCV2_DATA_MASK, -40000}, + {3800, -40000}, + {3792, -35000}, + {3783, -30000}, + {3774, -25000}, + {3765, -20000}, + {3756, -15000}, + {3747, -10000}, + {3737, -5000}, + {3728, 0}, + {3718, 5000}, + {3708, 10000}, + {3698, 15000}, + {3688, 20000}, + {3678, 25000}, + {3667, 30000}, + {3656, 35000}, + {3645, 40000}, + {3634, 45000}, + {3623, 50000}, + {3611, 55000}, + {3600, 60000}, + {3588, 65000}, + {3575, 70000}, + {3563, 75000}, + {3550, 80000}, + {3537, 85000}, + {3524, 90000}, + {3510, 95000}, + {3496, 100000}, + {3482, 105000}, + {3467, 110000}, + {3452, 115000}, + {3437, 120000}, + {3421, 125000}, + {0, 125000}, +}; + +static u32 rk_tsadcv2_temp_to_code(long temp) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (temp < v2_code_table[low].temp || temp > v2_code_table[high].temp) + return 0; + + while (low <= high) { + if (temp == v2_code_table[mid].temp) + return v2_code_table[mid].code; + else if (temp < v2_code_table[mid].temp) + high = mid - 1; + else + low = mid + 1; + mid = (low + high) / 2; + } + + return 0; +} + +static long rk_tsadcv2_code_to_temp(u32 code) +{ + int high, low, mid; + + low = 0; + high = ARRAY_SIZE(v2_code_table) - 1; + mid = (high + low) / 2; + + if (code > v2_code_table[low].code || code < v2_code_table[high].code) + return 125000; /* No code available, return max temperature */ + + while (low <= high) { + if (code >= v2_code_table[mid].code && code < + v2_code_table[mid - 1].code) + return v2_code_table[mid].temp; + else if (code < v2_code_table[mid].code) + low = mid + 1; + else + high = mid - 1; + mid = (low + high) / 2; + } + + return 125000; +} + +/** + * rk_tsadcv2_initialize - initialize TASDC Controller + * (1) Set TSADCV2_AUTO_PERIOD, configure the interleave between + * every two accessing of TSADC in normal operation. + * (2) Set TSADCV2_AUTO_PERIOD_HT, configure the interleave between + * every two accessing of TSADC after the temperature is higher + * than COM_SHUT or COM_INT. + * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE, + * if the temperature is higher than COMP_INT or COMP_SHUT for + * "debounce" times, TSADC controller will generate interrupt or TSHUT. + */ +static void rk_tsadcv2_initialize(void __iomem *regs, + enum tshut_polarity tshut_polarity) +{ + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH), + regs + TSADCV2_AUTO_CON); + else + writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW), + regs + TSADCV2_AUTO_CON); + + writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD); + writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_INT_DEBOUNCE); + writel_relaxed(TSADCV2_AUTO_PERIOD_HT_TIME, + regs + TSADCV2_AUTO_PERIOD_HT); + writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, + regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); +} + +static void rk_tsadcv2_irq_ack(void __iomem *regs) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_PD); + writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD); +} + +static void rk_tsadcv2_control(void __iomem *regs, bool enable) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + if (enable) + val |= TSADCV2_AUTO_EN; + else + val &= ~TSADCV2_AUTO_EN; + + writel_relaxed(val, regs + TSADCV2_AUTO_CON); +} + +static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, long *temp) +{ + u32 val; + + /* the A/D value of the channel last conversion need some time */ + val = readl_relaxed(regs + TSADCV2_DATA(chn)); + if (val == 0) + return -EAGAIN; + + *temp = rk_tsadcv2_code_to_temp(val); + + return 0; +} + +static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp) +{ + u32 tshut_value, val; + + tshut_value = rk_tsadcv2_temp_to_code(temp); + writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); + + /* TSHUT will be valid */ + val = readl_relaxed(regs + TSADCV2_AUTO_CON); + writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON); +} + +static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, + enum tshut_mode mode) +{ + u32 val; + + val = readl_relaxed(regs + TSADCV2_INT_EN); + if (mode == TSHUT_MODE_GPIO) { + val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn); + val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn); + } else { + val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn); + val |= TSADCV2_SHUT_2CRU_SRC_EN(chn); + } + + writel_relaxed(val, regs + TSADCV2_INT_EN); +} + +static const struct rockchip_tsadc_chip rk3288_tsadc_data = { + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv2_irq_ack, + .control = rk_tsadcv2_control, + .get_temp = rk_tsadcv2_get_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, +}; + +static const struct of_device_id of_rockchip_thermal_match[] = { + { + .compatible = "rockchip,rk3288-tsadc", + .data = (void *)&rk3288_tsadc_data, + }, + { /* end */ }, +}; +MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); + +static void +rockchip_thermal_toggle_sensor(struct rockchip_thermal_sensor *sensor, bool on) +{ + struct thermal_zone_device *tzd = sensor->tzd; + + tzd->ops->set_mode(tzd, + on ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED); +} + +static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev) +{ + struct rockchip_thermal_data *thermal = dev; + int i; + + dev_dbg(&thermal->pdev->dev, "thermal alarm\n"); + + thermal->chip->irq_ack(thermal->regs); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + thermal_zone_device_update(thermal->sensors[i].tzd); + + return IRQ_HANDLED; +} + +static int rockchip_thermal_get_temp(void *_sensor, long *out_temp) +{ + struct rockchip_thermal_sensor *sensor = _sensor; + struct rockchip_thermal_data *thermal = sensor->thermal; + const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; + int retval; + + retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp); + dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %ld, retval: %d\n", + sensor->id, *out_temp, retval); + + return retval; +} + +static const struct thermal_zone_of_device_ops rockchip_of_thermal_ops = { + .get_temp = rockchip_thermal_get_temp, +}; + +static int rockchip_configure_from_dt(struct device *dev, + struct device_node *np, + struct rockchip_thermal_data *thermal) +{ + u32 shut_temp, tshut_mode, tshut_polarity; + + if (of_property_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) { + dev_warn(dev, + "Missing tshut temp property, using default %ld\n", + thermal->chip->tshut_temp); + thermal->tshut_temp = thermal->chip->tshut_temp; + } else { + thermal->tshut_temp = shut_temp; + } + + if (thermal->tshut_temp > INT_MAX) { + dev_err(dev, "Invalid tshut temperature specified: %ld\n", + thermal->tshut_temp); + return -ERANGE; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) { + dev_warn(dev, + "Missing tshut mode property, using default (%s)\n", + thermal->chip->tshut_mode == TSHUT_MODE_GPIO ? + "gpio" : "cru"); + thermal->tshut_mode = thermal->chip->tshut_mode; + } else { + thermal->tshut_mode = tshut_mode; + } + + if (thermal->tshut_mode > 1) { + dev_err(dev, "Invalid tshut mode specified: %d\n", + thermal->tshut_mode); + return -EINVAL; + } + + if (of_property_read_u32(np, "rockchip,hw-tshut-polarity", + &tshut_polarity)) { + dev_warn(dev, + "Missing tshut-polarity property, using default (%s)\n", + thermal->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? + "low" : "high"); + thermal->tshut_polarity = thermal->chip->tshut_polarity; + } else { + thermal->tshut_polarity = tshut_polarity; + } + + if (thermal->tshut_polarity > 1) { + dev_err(dev, "Invalid tshut-polarity specified: %d\n", + thermal->tshut_polarity); + return -EINVAL; + } + + return 0; +} + +static int +rockchip_thermal_register_sensor(struct platform_device *pdev, + struct rockchip_thermal_data *thermal, + struct rockchip_thermal_sensor *sensor, + enum sensor_id id) +{ + const struct rockchip_tsadc_chip *tsadc = thermal->chip; + int error; + + tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); + tsadc->set_tshut_temp(id, thermal->regs, thermal->tshut_temp); + + sensor->thermal = thermal; + sensor->id = id; + sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev, id, sensor, + &rockchip_of_thermal_ops); + if (IS_ERR(sensor->tzd)) { + error = PTR_ERR(sensor->tzd); + dev_err(&pdev->dev, "failed to register sensor %d: %d\n", + id, error); + return error; + } + + return 0; +} + +/* + * Reset TSADC Controller, reset all tsadc registers. + */ +static void rockchip_thermal_reset_controller(struct reset_control *reset) +{ + reset_control_assert(reset); + usleep_range(10, 20); + reset_control_deassert(reset); +} + +static int rockchip_thermal_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct rockchip_thermal_data *thermal; + const struct of_device_id *match; + struct resource *res; + int irq; + int i; + int error; + + match = of_match_node(of_rockchip_thermal_match, np); + if (!match) + return -ENXIO; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return -EINVAL; + } + + thermal = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_thermal_data), + GFP_KERNEL); + if (!thermal) + return -ENOMEM; + + thermal->pdev = pdev; + + thermal->chip = (const struct rockchip_tsadc_chip *)match->data; + if (!thermal->chip) + return -EINVAL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + thermal->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(thermal->regs)) + return PTR_ERR(thermal->regs); + + thermal->reset = devm_reset_control_get(&pdev->dev, "tsadc-apb"); + if (IS_ERR(thermal->reset)) { + error = PTR_ERR(thermal->reset); + dev_err(&pdev->dev, "failed to get tsadc reset: %d\n", error); + return error; + } + + thermal->clk = devm_clk_get(&pdev->dev, "tsadc"); + if (IS_ERR(thermal->clk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get tsadc clock: %d\n", error); + return error; + } + + thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(thermal->pclk)) { + error = PTR_ERR(thermal->clk); + dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->clk); + if (error) { + dev_err(&pdev->dev, "failed to enable converter clock: %d\n", + error); + return error; + } + + error = clk_prepare_enable(thermal->pclk); + if (error) { + dev_err(&pdev->dev, "failed to enable pclk: %d\n", error); + goto err_disable_clk; + } + + rockchip_thermal_reset_controller(thermal->reset); + + error = rockchip_configure_from_dt(&pdev->dev, np, thermal); + if (error) { + dev_err(&pdev->dev, "failed to parse device tree data: %d\n", + error); + goto err_disable_pclk; + } + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[0], + SENSOR_CPU); + if (error) { + dev_err(&pdev->dev, + "failed to register CPU thermal sensor: %d\n", error); + goto err_disable_pclk; + } + + error = rockchip_thermal_register_sensor(pdev, thermal, + &thermal->sensors[1], + SENSOR_GPU); + if (error) { + dev_err(&pdev->dev, + "failed to register GPU thermal sensor: %d\n", error); + goto err_unregister_cpu_sensor; + } + + error = devm_request_threaded_irq(&pdev->dev, irq, NULL, + &rockchip_thermal_alarm_irq_thread, + IRQF_ONESHOT, + "rockchip_thermal", thermal); + if (error) { + dev_err(&pdev->dev, + "failed to request tsadc irq: %d\n", error); + goto err_unregister_gpu_sensor; + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + platform_set_drvdata(pdev, thermal); + + return 0; + +err_unregister_gpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[1].tzd); +err_unregister_cpu_sensor: + thermal_zone_of_sensor_unregister(&pdev->dev, thermal->sensors[0].tzd); +err_disable_pclk: + clk_disable_unprepare(thermal->pclk); +err_disable_clk: + clk_disable_unprepare(thermal->clk); + + return error; +} + +static int rockchip_thermal_remove(struct platform_device *pdev) +{ + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; + + rockchip_thermal_toggle_sensor(sensor, false); + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd); + } + + thermal->chip->control(thermal->regs, false); + + clk_disable_unprepare(thermal->pclk); + clk_disable_unprepare(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], false); + + thermal->chip->control(thermal->regs, false); + + clk_disable(thermal->pclk); + clk_disable(thermal->clk); + + return 0; +} + +static int __maybe_unused rockchip_thermal_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct rockchip_thermal_data *thermal = platform_get_drvdata(pdev); + int i; + int error; + + error = clk_enable(thermal->clk); + if (error) + return error; + + error = clk_enable(thermal->pclk); + if (error) + return error; + + rockchip_thermal_reset_controller(thermal->reset); + + thermal->chip->initialize(thermal->regs, thermal->tshut_polarity); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) { + enum sensor_id id = thermal->sensors[i].id; + + thermal->chip->set_tshut_mode(id, thermal->regs, + thermal->tshut_mode); + thermal->chip->set_tshut_temp(id, thermal->regs, + thermal->tshut_temp); + } + + thermal->chip->control(thermal->regs, true); + + for (i = 0; i < ARRAY_SIZE(thermal->sensors); i++) + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops, + rockchip_thermal_suspend, rockchip_thermal_resume); + +static struct platform_driver rockchip_thermal_driver = { + .driver = { + .name = "rockchip-thermal", + .owner = THIS_MODULE, + .pm = &rockchip_thermal_pm_ops, + .of_match_table = of_rockchip_thermal_match, + }, + .probe = rockchip_thermal_probe, + .remove = rockchip_thermal_remove, +}; + +module_platform_driver(rockchip_thermal_driver); + +MODULE_DESCRIPTION("ROCKCHIP THERMAL Driver"); +MODULE_AUTHOR("Rockchip, Inc."); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:rockchip-thermal"); -- GitLab From 387fe80fb13ed9f5f3741a661f96e409a2c959b5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:37 +0100 Subject: [PATCH 6253/9457] ASoC: wm8983: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8983.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index ac5defda8824..5d1cf08a72b8 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -967,29 +967,6 @@ static int wm8983_set_bias_level(struct snd_soc_codec *codec, return 0; } -#ifdef CONFIG_PM -static int wm8983_suspend(struct snd_soc_codec *codec) -{ - wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8983_resume(struct snd_soc_codec *codec) -{ - wm8983_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8983_suspend NULL -#define wm8983_resume NULL -#endif - -static int wm8983_remove(struct snd_soc_codec *codec) -{ - wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int wm8983_probe(struct snd_soc_codec *codec) { int ret; @@ -1055,10 +1032,8 @@ static struct snd_soc_dai_driver wm8983_dai = { static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { .probe = wm8983_probe, - .remove = wm8983_remove, - .suspend = wm8983_suspend, - .resume = wm8983_resume, .set_bias_level = wm8983_set_bias_level, + .suspend_bias_off = true, .controls = wm8983_snd_controls, .num_controls = ARRAY_SIZE(wm8983_snd_controls), .dapm_widgets = wm8983_dapm_widgets, -- GitLab From d02486fd42a3295edbec4db8f7f81c1432fa60a4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:36 +0100 Subject: [PATCH 6254/9457] ASoC: wm8978: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8978.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index ee2ba574952b..cf7032911721 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -991,21 +991,11 @@ static int wm8978_probe(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(update_reg); i++) snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100); - wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -/* power down chip */ -static int wm8978_remove(struct snd_soc_codec *codec) -{ - wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { .probe = wm8978_probe, - .remove = wm8978_remove, .suspend = wm8978_suspend, .resume = wm8978_resume, .set_bias_level = wm8978_set_bias_level, -- GitLab From ed1358f508e1ebcb01e1e545c5330599098b7687 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:35 +0100 Subject: [PATCH 6255/9457] ASoC: wm8974: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8974.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 682e9eda1019..ff0e4646b934 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -568,18 +568,6 @@ static struct snd_soc_dai_driver wm8974_dai = { .symmetric_rates = 1, }; -static int wm8974_suspend(struct snd_soc_codec *codec) -{ - wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8974_resume(struct snd_soc_codec *codec) -{ - wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static const struct regmap_config wm8974_regmap = { .reg_bits = 7, .val_bits = 9, @@ -599,24 +587,13 @@ static int wm8974_probe(struct snd_soc_codec *codec) return ret; } - wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return ret; -} - -/* power down chip */ -static int wm8974_remove(struct snd_soc_codec *codec) -{ - wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { .probe = wm8974_probe, - .remove = wm8974_remove, - .suspend = wm8974_suspend, - .resume = wm8974_resume, .set_bias_level = wm8974_set_bias_level, + .suspend_bias_off = true, .controls = wm8974_snd_controls, .num_controls = ARRAY_SIZE(wm8974_snd_controls), -- GitLab From a5dde8c42ef6b3cb47c69905ee51520e18ac6515 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:38 +0100 Subject: [PATCH 6256/9457] ASoC: wm8985: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8985.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index ee380190399f..0b3b54c9971d 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -961,29 +961,6 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, return 0; } -#ifdef CONFIG_PM -static int wm8985_suspend(struct snd_soc_codec *codec) -{ - wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8985_resume(struct snd_soc_codec *codec) -{ - wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} -#else -#define wm8985_suspend NULL -#define wm8985_resume NULL -#endif - -static int wm8985_remove(struct snd_soc_codec *codec) -{ - wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int wm8985_probe(struct snd_soc_codec *codec) { size_t i; @@ -1023,7 +1000,6 @@ static int wm8985_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT, WM8985_BIASCUT); - wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; err_reg_enable: @@ -1064,10 +1040,8 @@ static struct snd_soc_dai_driver wm8985_dai = { static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { .probe = wm8985_probe, - .remove = wm8985_remove, - .suspend = wm8985_suspend, - .resume = wm8985_resume, .set_bias_level = wm8985_set_bias_level, + .suspend_bias_off = true, .controls = wm8985_snd_controls, .num_controls = ARRAY_SIZE(wm8985_snd_controls), -- GitLab From 1f07b8de451f5f4f6a268a95a34183e528cda711 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:39 +0100 Subject: [PATCH 6257/9457] ASoC: wm8988: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Also remove the regcache_mark_dirty() from the suspend handler since it is already called by the ASoC core. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8988.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index a5130d965146..e418199155a8 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -793,21 +793,6 @@ static struct snd_soc_dai_driver wm8988_dai = { .symmetric_rates = 1, }; -static int wm8988_suspend(struct snd_soc_codec *codec) -{ - struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); - - wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); - regcache_mark_dirty(wm8988->regmap); - return 0; -} - -static int wm8988_resume(struct snd_soc_codec *codec) -{ - wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - static int wm8988_probe(struct snd_soc_codec *codec) { int ret = 0; @@ -825,23 +810,13 @@ static int wm8988_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100); - wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static int wm8988_remove(struct snd_soc_codec *codec) -{ - wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { .probe = wm8988_probe, - .remove = wm8988_remove, - .suspend = wm8988_suspend, - .resume = wm8988_resume, .set_bias_level = wm8988_set_bias_level, + .suspend_bias_off = true, .controls = wm8988_snd_controls, .num_controls = ARRAY_SIZE(wm8988_snd_controls), -- GitLab From 955efc8f50eb11d1c85daca6db7943c63dc5c2e7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:40 +0100 Subject: [PATCH 6258/9457] ASoC: wm8990: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8990.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 03e43e3f395e..8a584229310a 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1271,18 +1271,6 @@ static struct snd_soc_dai_driver wm8990_dai = { .ops = &wm8990_dai_ops, }; -static int wm8990_suspend(struct snd_soc_codec *codec) -{ - wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8990_resume(struct snd_soc_codec *codec) -{ - wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - /* * initialise the WM8990 driver * register the mixer and dsp interfaces with the kernel @@ -1309,19 +1297,11 @@ static int wm8990_probe(struct snd_soc_codec *codec) return 0; } -/* power down chip */ -static int wm8990_remove(struct snd_soc_codec *codec) -{ - wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { .probe = wm8990_probe, - .remove = wm8990_remove, - .suspend = wm8990_suspend, - .resume = wm8990_resume, .set_bias_level = wm8990_set_bias_level, + .suspend_bias_off = true, + .controls = wm8990_snd_controls, .num_controls = ARRAY_SIZE(wm8990_snd_controls), .dapm_widgets = wm8990_dapm_widgets, -- GitLab From 497b900f83c56d513794ccf56b7a87c50a34a454 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:41 +0100 Subject: [PATCH 6259/9457] ASoC: wm8991: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8991.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index d0be89731cdb..b0ac2c3e31b9 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1227,32 +1227,6 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8991_suspend(struct snd_soc_codec *codec) -{ - wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8991_resume(struct snd_soc_codec *codec) -{ - wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -/* power down chip */ -static int wm8991_remove(struct snd_soc_codec *codec) -{ - wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8991_probe(struct snd_soc_codec *codec) -{ - wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - #define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) @@ -1293,11 +1267,9 @@ static struct snd_soc_dai_driver wm8991_dai = { }; static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { - .probe = wm8991_probe, - .remove = wm8991_remove, - .suspend = wm8991_suspend, - .resume = wm8991_resume, .set_bias_level = wm8991_set_bias_level, + .suspend_bias_off = true, + .controls = wm8991_snd_controls, .num_controls = ARRAY_SIZE(wm8991_snd_controls), .dapm_widgets = wm8991_dapm_widgets, -- GitLab From 77d05e7f81da95eb2b6c7ae24ae0fb3272c49282 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:42 +0100 Subject: [PATCH 6260/9457] ASoC: wm8993: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8993.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 93b14eda355a..53c6fe359496 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1486,7 +1486,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; wm8993->hubs_data.hp_startup_mode = 1; wm8993->hubs_data.dcs_codes_l = -2; @@ -1518,10 +1517,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) wm8993->pdata.micbias1_lvl, wm8993->pdata.micbias2_lvl); - ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (ret != 0) - return ret; - snd_soc_add_codec_controls(codec, wm8993_snd_controls, ARRAY_SIZE(wm8993_snd_controls)); if (wm8993->pdata.num_retune_configs != 0) { @@ -1550,12 +1545,6 @@ static int wm8993_probe(struct snd_soc_codec *codec) } -static int wm8993_remove(struct snd_soc_codec *codec) -{ - wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - #ifdef CONFIG_PM static int wm8993_suspend(struct snd_soc_codec *codec) { @@ -1629,7 +1618,6 @@ static const struct regmap_config wm8993_regmap = { static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { .probe = wm8993_probe, - .remove = wm8993_remove, .suspend = wm8993_suspend, .resume = wm8993_resume, .set_bias_level = wm8993_set_bias_level, -- GitLab From 49d9ac383cddc3e8d4cae8bc7a8f4da9dc071121 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:43 +0100 Subject: [PATCH 6261/9457] ASoC: wm8994: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1fcb9f3f3097..c3a2e751513f 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4391,8 +4391,6 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) struct wm8994 *control = wm8994->wm8994; int i; - wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); - for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, &wm8994->fll_locked[i]); -- GitLab From aee9ffabec81d96d68d8537ccc6fedfbb0e6c468 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:44 +0100 Subject: [PATCH 6262/9457] ASoC: wm8995: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8995.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index e40c8a662183..c280f0a3a424 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2004,7 +2004,6 @@ static int wm8995_remove(struct snd_soc_codec *codec) int i; wm8995 = snd_soc_codec_get_drvdata(codec); - wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i) regulator_unregister_notifier(wm8995->supplies[i].consumer, @@ -2078,8 +2077,6 @@ static int wm8995_probe(struct snd_soc_codec *codec) goto err_reg_enable; } - wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* Latch volume updates (right only; we always do left then right). */ snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME, WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU); -- GitLab From 68201d6998a0d7701f7c3009130c5d8cd6ad7562 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:45 +0100 Subject: [PATCH 6263/9457] ASoC: wm9081: Cleanup manual bias level transitions Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9081.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 0cdc9e2184ab..b1d946facd57 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1277,15 +1277,8 @@ static int wm9081_probe(struct snd_soc_codec *codec) return 0; } -static int wm9081_remove(struct snd_soc_codec *codec) -{ - wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { .probe = wm9081_probe, - .remove = wm9081_remove, .set_sysclk = wm9081_set_sysclk, .set_bias_level = wm9081_set_bias_level, -- GitLab From a70cf928ca396447416422c2ec1697a530534ac9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:46 +0100 Subject: [PATCH 6264/9457] ASoC: wm9090: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend and SND_SOC_BIAS_STANDBY in resume. This makes the code a bit shorter and cleaner. Since the ASoC core now takes care of setting the bias level to SND_SOC_BIAS_OFF when removing the CODEC there is no need to do it manually anymore either. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9090.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index a13f0725611a..6ffe8dc4f3fa 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -550,45 +550,15 @@ static int wm9090_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM9090_CLOCKING_1, WM9090_TOCLK_ENA, WM9090_TOCLK_ENA); - wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - wm9090_add_controls(codec); return 0; } -#ifdef CONFIG_PM -static int wm9090_suspend(struct snd_soc_codec *codec) -{ - wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm9090_resume(struct snd_soc_codec *codec) -{ - wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm9090_suspend NULL -#define wm9090_resume NULL -#endif - -static int wm9090_remove(struct snd_soc_codec *codec) -{ - wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { .probe = wm9090_probe, - .remove = wm9090_remove, - .suspend = wm9090_suspend, - .resume = wm9090_resume, .set_bias_level = wm9090_set_bias_level, + .suspend_bias_off = true, }; static const struct regmap_config wm9090_regmap = { -- GitLab From ab492b86b89be6c98bdca71cfc97b411ca42e140 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:47 +0100 Subject: [PATCH 6265/9457] ASoC: wm9712: Cleanup manual bias level transitions Set the CODEC driver's suspend_bias_off flag rather than manually going to SND_SOC_BIAS_OFF in suspend. This makes the code a bit shorter and cleaner. The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index f3aab6e1d92a..30f4b1773070 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -599,12 +599,6 @@ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) return -EIO; } -static int wm9712_soc_suspend(struct snd_soc_codec *codec) -{ - wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - static int wm9712_soc_resume(struct snd_soc_codec *codec) { int i, ret; @@ -646,8 +640,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) /* set alc mux to none */ ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); - wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; reset_err: @@ -664,11 +656,11 @@ static int wm9712_soc_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .probe = wm9712_soc_probe, .remove = wm9712_soc_remove, - .suspend = wm9712_soc_suspend, .resume = wm9712_soc_resume, .read = ac97_read, .write = ac97_write, .set_bias_level = wm9712_set_bias_level, + .suspend_bias_off = true, .reg_cache_size = ARRAY_SIZE(wm9712_reg), .reg_word_size = sizeof(u16), .reg_cache_step = 2, -- GitLab From 0cb6b1419ec864996835991a62788c588693f27d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 23 Nov 2014 13:37:48 +0100 Subject: [PATCH 6266/9457] ASoC: wm9713: Cleanup manual bias level transitions The manual transition to SND_SOC_BIAS_STANDBY at the end of CODEC probe() can also be removed as the core will automatically do this after the CODEC has been probed. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ac13fc8f5c70..e977b13bacfa 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1203,8 +1203,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) if (ret < 0) goto reset_err; - wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* unmute the adc - move to kcontrol */ reg = ac97_read(codec, AC97_CD) & 0x7fff; ac97_write(codec, AC97_CD, reg); -- GitLab From bbc686b34650b0f54affe9d9a637ccbe02b03760 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 24 Nov 2014 20:37:12 +0200 Subject: [PATCH 6267/9457] ASoC: tlv320aic31xx: Fix off by one error in the loop stucture. Fix off by one read beyond the end of a table. Reported-by: David Binderman Signed-off-by: Jyri Sarha Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/tlv320aic31xx.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 145fe5b253d4..93de5dd0a7b9 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -911,12 +911,13 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, } aic31xx->p_div = i; - for (i = 0; aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) { - if (i == ARRAY_SIZE(aic31xx_divs)) { - dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", - __func__, freq); - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(aic31xx_divs) && + aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) + ; + if (i == ARRAY_SIZE(aic31xx_divs)) { + dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", + __func__, freq); + return -EINVAL; } /* set clock on MCLK, BCLK, or GPIO1 as PLL input */ -- GitLab From b671358ad7916beb7ca9e5c304ae88afc7da4557 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 22 Nov 2014 16:21:39 +0100 Subject: [PATCH 6268/9457] spi: core: Add spi_transfer_is_last() helper This adds the function spi_transfer_is_last() which can be used by drivers to know whether a given transfer is the last one in the current message. Signed-off-by: Beniamino Galvani Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 46d188a9947c..a6ef2a8e6de4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1049,4 +1049,10 @@ spi_unregister_device(struct spi_device *spi) extern const struct spi_device_id * spi_get_device_id(const struct spi_device *sdev); +static inline bool +spi_transfer_is_last(struct spi_master *master, struct spi_transfer *xfer) +{ + return list_is_last(&xfer->transfer_list, &master->cur_msg->transfers); +} + #endif /* __LINUX_SPI_H */ -- GitLab From 56da2aafe0a6db710c38a2fbf6aa9352a7b9fa4d Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 22 Nov 2014 16:21:40 +0100 Subject: [PATCH 6269/9457] spi: meson: Add device tree bindings documentation for SPIFC This adds documentation of device tree bindings for the Amlogic Meson SPIFC (SPI Flash Controller). Signed-off-by: Beniamino Galvani Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-meson.txt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-meson.txt diff --git a/Documentation/devicetree/bindings/spi/spi-meson.txt b/Documentation/devicetree/bindings/spi/spi-meson.txt new file mode 100644 index 000000000000..bb52a86f3365 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-meson.txt @@ -0,0 +1,22 @@ +Amlogic Meson SPI controllers + +* SPIFC (SPI Flash Controller) + +The Meson SPIFC is a controller optimized for communication with SPI +NOR memories, without DMA support and a 64-byte unified transmit / +receive buffer. + +Required properties: + - compatible: should be "amlogic,meson6-spifc" + - reg: physical base address and length of the controller registers + - clocks: phandle of the input clock for the baud rate generator + - #address-cells: should be 1 + - #size-cells: should be 0 + + spi@c1108c80 { + compatible = "amlogic,meson6-spifc"; + reg = <0xc1108c80 0x80>; + clocks = <&clk81>; + #address-cells = <1>; + #size-cells = <0>; + }; -- GitLab From c3e4bc5434d2999ec3b00eadd1945eadf13fd0de Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 22 Nov 2014 16:21:41 +0100 Subject: [PATCH 6270/9457] spi: meson: Add support for Amlogic Meson SPIFC This is a driver for the Amlogic Meson SPIFC (SPI flash controller), which is one of the two SPI controllers available on the SoC. It doesn't support DMA and has a 64-byte unified transmit/receive buffer. The device is optimized for interfacing with SPI NOR memories and allows the execution of standard operations such as read, page program, sector erase, etc. in a simplified way, toggling a bit in a dedicated register. The driver doesn't use those predefined commands and relies only on custom transfers. Signed-off-by: Beniamino Galvani Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi-meson-spifc.c | 462 ++++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 drivers/spi/spi-meson-spifc.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 84e7c9e6ccef..70f20b99e5ff 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -301,6 +301,13 @@ config SPI_FSL_ESPI From MPC8536, 85xx platform uses the controller, and all P10xx, P20xx, P30xx,P40xx, P50xx uses this controller. +config SPI_MESON_SPIFC + tristate "Amlogic Meson SPIFC controller" + depends on ARCH_MESON || COMPILE_TEST + help + This enables master mode support for the SPIFC (SPI flash + controller) available in Amlogic Meson SoCs. + config SPI_OC_TINY tristate "OpenCores tiny SPI" depends on GPIOLIB diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 78f24ca36fcf..9b8a7472b5b8 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o +obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c new file mode 100644 index 000000000000..f536476710ad --- /dev/null +++ b/drivers/spi/spi-meson-spifc.c @@ -0,0 +1,462 @@ +/* + * Driver for Amlogic Meson SPI flash controller (SPIFC) + * + * Copyright (C) 2014 Beniamino Galvani + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* register map */ +#define REG_CMD 0x00 +#define REG_ADDR 0x04 +#define REG_CTRL 0x08 +#define REG_CTRL1 0x0c +#define REG_STATUS 0x10 +#define REG_CTRL2 0x14 +#define REG_CLOCK 0x18 +#define REG_USER 0x1c +#define REG_USER1 0x20 +#define REG_USER2 0x24 +#define REG_USER3 0x28 +#define REG_USER4 0x2c +#define REG_SLAVE 0x30 +#define REG_SLAVE1 0x34 +#define REG_SLAVE2 0x38 +#define REG_SLAVE3 0x3c +#define REG_C0 0x40 +#define REG_B8 0x60 +#define REG_MAX 0x7c + +/* register fields */ +#define CMD_USER BIT(18) +#define CTRL_ENABLE_AHB BIT(17) +#define CLOCK_SOURCE BIT(31) +#define CLOCK_DIV_SHIFT 12 +#define CLOCK_DIV_MASK (0x3f << CLOCK_DIV_SHIFT) +#define CLOCK_CNT_HIGH_SHIFT 6 +#define CLOCK_CNT_HIGH_MASK (0x3f << CLOCK_CNT_HIGH_SHIFT) +#define CLOCK_CNT_LOW_SHIFT 0 +#define CLOCK_CNT_LOW_MASK (0x3f << CLOCK_CNT_LOW_SHIFT) +#define USER_DIN_EN_MS BIT(0) +#define USER_CMP_MODE BIT(2) +#define USER_UC_DOUT_SEL BIT(27) +#define USER_UC_DIN_SEL BIT(28) +#define USER_UC_MASK ((BIT(5) - 1) << 27) +#define USER1_BN_UC_DOUT_SHIFT 17 +#define USER1_BN_UC_DOUT_MASK (0xff << 16) +#define USER1_BN_UC_DIN_SHIFT 8 +#define USER1_BN_UC_DIN_MASK (0xff << 8) +#define USER4_CS_ACT BIT(30) +#define SLAVE_TRST_DONE BIT(4) +#define SLAVE_OP_MODE BIT(30) +#define SLAVE_SW_RST BIT(31) + +#define SPIFC_BUFFER_SIZE 64 + +/** + * struct meson_spifc + * @master: the SPI master + * @regmap: regmap for device registers + * @clk: input clock of the built-in baud rate generator + * @device: the device structure + */ +struct meson_spifc { + struct spi_master *master; + struct regmap *regmap; + struct clk *clk; + struct device *dev; +}; + +static struct regmap_config spifc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = REG_MAX, +}; + +/** + * meson_spifc_wait_ready() - wait for the current operation to terminate + * @spifc: the Meson SPI device + * Return: 0 on success, a negative value on error + */ +static int meson_spifc_wait_ready(struct meson_spifc *spifc) +{ + unsigned long deadline = jiffies + msecs_to_jiffies(5); + u32 data; + + do { + regmap_read(spifc->regmap, REG_SLAVE, &data); + if (data & SLAVE_TRST_DONE) + return 0; + cond_resched(); + } while (!time_after(jiffies, deadline)); + + return -ETIMEDOUT; +} + +/** + * meson_spifc_drain_buffer() - copy data from device buffer to memory + * @spifc: the Meson SPI device + * @buf: the destination buffer + * @len: number of bytes to copy + */ +static void meson_spifc_drain_buffer(struct meson_spifc *spifc, u8 *buf, + int len) +{ + u32 data; + int i = 0; + + while (i < len) { + regmap_read(spifc->regmap, REG_C0 + i, &data); + + if (len - i >= 4) { + *((u32 *)buf) = data; + buf += 4; + } else { + memcpy(buf, &data, len - i); + break; + } + i += 4; + } +} + +/** + * meson_spifc_fill_buffer() - copy data from memory to device buffer + * @spifc: the Meson SPI device + * @buf: the source buffer + * @len: number of bytes to copy + */ +static void meson_spifc_fill_buffer(struct meson_spifc *spifc, const u8 *buf, + int len) +{ + u32 data; + int i = 0; + + while (i < len) { + if (len - i >= 4) + data = *(u32 *)buf; + else + memcpy(&data, buf, len - i); + + regmap_write(spifc->regmap, REG_C0 + i, data); + + buf += 4; + i += 4; + } +} + +/** + * meson_spifc_setup_speed() - program the clock divider + * @spifc: the Meson SPI device + * @speed: desired speed in Hz + */ +void meson_spifc_setup_speed(struct meson_spifc *spifc, u32 speed) +{ + unsigned long parent, value; + int n; + + parent = clk_get_rate(spifc->clk); + n = max_t(int, parent / speed - 1, 1); + + dev_dbg(spifc->dev, "parent %lu, speed %u, n %d\n", parent, + speed, n); + + value = (n << CLOCK_DIV_SHIFT) & CLOCK_DIV_MASK; + value |= (n << CLOCK_CNT_LOW_SHIFT) & CLOCK_CNT_LOW_MASK; + value |= (((n + 1) / 2 - 1) << CLOCK_CNT_HIGH_SHIFT) & + CLOCK_CNT_HIGH_MASK; + + regmap_write(spifc->regmap, REG_CLOCK, value); +} + +/** + * meson_spifc_txrx() - transfer a chunk of data + * @spifc: the Meson SPI device + * @xfer: the current SPI transfer + * @offset: offset of the data to transfer + * @len: length of the data to transfer + * @last_xfer: whether this is the last transfer of the message + * @last_chunk: whether this is the last chunk of the transfer + * Return: 0 on success, a negative value on error + */ +static int meson_spifc_txrx(struct meson_spifc *spifc, + struct spi_transfer *xfer, + int offset, int len, bool last_xfer, + bool last_chunk) +{ + bool keep_cs = true; + int ret; + + if (xfer->tx_buf) + meson_spifc_fill_buffer(spifc, xfer->tx_buf + offset, len); + + /* enable DOUT stage */ + regmap_update_bits(spifc->regmap, REG_USER, USER_UC_MASK, + USER_UC_DOUT_SEL); + regmap_write(spifc->regmap, REG_USER1, + (8 * len - 1) << USER1_BN_UC_DOUT_SHIFT); + + /* enable data input during DOUT */ + regmap_update_bits(spifc->regmap, REG_USER, USER_DIN_EN_MS, + USER_DIN_EN_MS); + + if (last_chunk) { + if (last_xfer) + keep_cs = xfer->cs_change; + else + keep_cs = !xfer->cs_change; + } + + regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_ACT, + keep_cs ? USER4_CS_ACT : 0); + + /* clear transition done bit */ + regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_TRST_DONE, 0); + /* start transfer */ + regmap_update_bits(spifc->regmap, REG_CMD, CMD_USER, CMD_USER); + + ret = meson_spifc_wait_ready(spifc); + + if (!ret && xfer->rx_buf) + meson_spifc_drain_buffer(spifc, xfer->rx_buf + offset, len); + + return ret; +} + +/** + * meson_spifc_transfer_one() - perform a single transfer + * @master: the SPI master + * @spi: the SPI device + * @xfer: the current SPI transfer + * Return: 0 on success, a negative value on error + */ +static int meson_spifc_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct meson_spifc *spifc = spi_master_get_devdata(master); + int len, done = 0, ret = 0; + + meson_spifc_setup_speed(spifc, xfer->speed_hz); + + regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 0); + + while (done < xfer->len && !ret) { + len = min_t(int, xfer->len - done, SPIFC_BUFFER_SIZE); + ret = meson_spifc_txrx(spifc, xfer, done, len, + spi_transfer_is_last(master, xfer), + done + len >= xfer->len); + done += len; + } + + regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, + CTRL_ENABLE_AHB); + + return ret; +} + +/** + * meson_spifc_hw_init() - reset and initialize the SPI controller + * @spifc: the Meson SPI device + */ +static void meson_spifc_hw_init(struct meson_spifc *spifc) +{ + /* reset device */ + regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_SW_RST, + SLAVE_SW_RST); + /* disable compatible mode */ + regmap_update_bits(spifc->regmap, REG_USER, USER_CMP_MODE, 0); + /* set master mode */ + regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_OP_MODE, 0); +} + +static int meson_spifc_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct meson_spifc *spifc; + struct resource *res; + void __iomem *base; + unsigned int rate; + int ret = 0; + + master = spi_alloc_master(&pdev->dev, sizeof(struct meson_spifc)); + if (!master) + return -ENOMEM; + + platform_set_drvdata(pdev, master); + + spifc = spi_master_get_devdata(master); + spifc->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(spifc->dev, res); + if (IS_ERR(base)) { + ret = PTR_ERR(base); + goto out_err; + } + + spifc->regmap = devm_regmap_init_mmio(spifc->dev, base, + &spifc_regmap_config); + if (IS_ERR(spifc->regmap)) { + ret = PTR_ERR(spifc->regmap); + goto out_err; + } + + spifc->clk = devm_clk_get(spifc->dev, NULL); + if (IS_ERR(spifc->clk)) { + dev_err(spifc->dev, "missing clock\n"); + ret = PTR_ERR(spifc->clk); + goto out_err; + } + + ret = clk_prepare_enable(spifc->clk); + if (ret) { + dev_err(spifc->dev, "can't prepare clock\n"); + goto out_err; + } + + rate = clk_get_rate(spifc->clk); + + master->num_chipselect = 1; + master->dev.of_node = pdev->dev.of_node; + master->bits_per_word_mask = SPI_BPW_MASK(8); + master->auto_runtime_pm = true; + master->transfer_one = meson_spifc_transfer_one; + master->min_speed_hz = rate >> 6; + master->max_speed_hz = rate >> 1; + + meson_spifc_hw_init(spifc); + + pm_runtime_set_active(spifc->dev); + pm_runtime_enable(spifc->dev); + + ret = devm_spi_register_master(spifc->dev, master); + if (ret) { + dev_err(spifc->dev, "failed to register spi master\n"); + goto out_clk; + } + + return 0; +out_clk: + clk_disable_unprepare(spifc->clk); +out_err: + spi_master_put(master); + return ret; +} + +static int meson_spifc_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + struct meson_spifc *spifc = spi_master_get_devdata(master); + + pm_runtime_get_sync(&pdev->dev); + clk_disable_unprepare(spifc->clk); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int meson_spifc_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct meson_spifc *spifc = spi_master_get_devdata(master); + int ret; + + ret = spi_master_suspend(master); + if (ret) + return ret; + + if (!pm_runtime_suspended(dev)) + clk_disable_unprepare(spifc->clk); + + return 0; +} + +static int meson_spifc_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct meson_spifc *spifc = spi_master_get_devdata(master); + int ret; + + if (!pm_runtime_suspended(dev)) { + ret = clk_prepare_enable(spifc->clk); + if (ret) + return ret; + } + + meson_spifc_hw_init(spifc); + + ret = spi_master_resume(master); + if (ret) + clk_disable_unprepare(spifc->clk); + + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM_RUNTIME +static int meson_spifc_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct meson_spifc *spifc = spi_master_get_devdata(master); + + clk_disable_unprepare(spifc->clk); + + return 0; +} + +static int meson_spifc_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct meson_spifc *spifc = spi_master_get_devdata(master); + + return clk_prepare_enable(spifc->clk); +} +#endif /* CONFIG_PM_RUNTIME */ + +static const struct dev_pm_ops meson_spifc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(meson_spifc_suspend, meson_spifc_resume) + SET_RUNTIME_PM_OPS(meson_spifc_runtime_suspend, + meson_spifc_runtime_resume, + NULL) +}; + +static const struct of_device_id meson_spifc_dt_match[] = { + { .compatible = "amlogic,meson6-spifc", }, + { }, +}; + +static struct platform_driver meson_spifc_driver = { + .probe = meson_spifc_probe, + .remove = meson_spifc_remove, + .driver = { + .name = "meson-spifc", + .of_match_table = of_match_ptr(meson_spifc_dt_match), + .pm = &meson_spifc_pm_ops, + }, +}; + +module_platform_driver(meson_spifc_driver); + +MODULE_AUTHOR("Beniamino Galvani "); +MODULE_DESCRIPTION("Amlogic Meson SPIFC driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 7758e390699fb25bf91642d52734200db38e764b Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Fri, 14 Nov 2014 17:12:53 +0100 Subject: [PATCH 6271/9457] spi: atmel: remove compat for non DT board when requesting dma chan All boards with a dma controller have DT support so using dma_request_slave_channel_compat is no more needed. Signed-off-by: Ludovic Desroches Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 6ed18934dffe..3370a3dfd883 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -417,23 +417,6 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, return err; } -static bool filter(struct dma_chan *chan, void *pdata) -{ - struct atmel_spi_dma *sl_pdata = pdata; - struct at_dma_slave *sl; - - if (!sl_pdata) - return false; - - sl = &sl_pdata->dma_slave; - if (sl->dma_dev == chan->device->dev) { - chan->private = sl; - return true; - } else { - return false; - } -} - static int atmel_spi_configure_dma(struct atmel_spi *as) { struct dma_slave_config slave_config; @@ -444,9 +427,7 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - as->dma.chan_tx = dma_request_slave_channel_compat(mask, filter, - &as->dma, - dev, "tx"); + as->dma.chan_tx = dma_request_slave_channel(dev, "tx"); if (!as->dma.chan_tx) { dev_err(dev, "DMA TX channel not available, SPI unable to use DMA\n"); @@ -454,9 +435,7 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) goto error; } - as->dma.chan_rx = dma_request_slave_channel_compat(mask, filter, - &as->dma, - dev, "rx"); + as->dma.chan_rx = dma_request_slave_channel(dev, "rx"); if (!as->dma.chan_rx) { dev_err(dev, -- GitLab From 5e9af37e46bceea9f950d2f2ae769f1aa6b6d7a6 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Fri, 14 Nov 2014 17:12:54 +0100 Subject: [PATCH 6272/9457] spi: atmel: introduce probe deferring Return probe defer if requesting a dma channel without a dma controller probed. Signed-off-by: Ludovic Desroches Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 3370a3dfd883..e4193ccc4970 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -427,14 +427,23 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - as->dma.chan_tx = dma_request_slave_channel(dev, "tx"); - if (!as->dma.chan_tx) { + as->dma.chan_tx = dma_request_slave_channel_reason(dev, "tx"); + if (IS_ERR(as->dma.chan_tx)) { + err = PTR_ERR(as->dma.chan_tx); + if (err == -EPROBE_DEFER) { + dev_warn(dev, "no DMA channel available at the moment\n"); + return err; + } dev_err(dev, "DMA TX channel not available, SPI unable to use DMA\n"); err = -EBUSY; goto error; } + /* + * No reason to check EPROBE_DEFER here since we have already requested + * tx channel. If it fails here, it's for another reason. + */ as->dma.chan_rx = dma_request_slave_channel(dev, "rx"); if (!as->dma.chan_rx) { @@ -456,7 +465,7 @@ static int atmel_spi_configure_dma(struct atmel_spi *as) error: if (as->dma.chan_rx) dma_release_channel(as->dma.chan_rx); - if (as->dma.chan_tx) + if (!IS_ERR(as->dma.chan_tx)) dma_release_channel(as->dma.chan_tx); return err; } @@ -1328,8 +1337,11 @@ static int atmel_spi_probe(struct platform_device *pdev) as->use_dma = false; as->use_pdc = false; if (as->caps.has_dma_support) { - if (atmel_spi_configure_dma(as) == 0) + ret = atmel_spi_configure_dma(as); + if (ret == 0) as->use_dma = true; + else if (ret == -EPROBE_DEFER) + return ret; } else { as->use_pdc = true; } -- GitLab From 9e8987acf051e48fc0e228b6f38c47a75352c58b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 17 Nov 2014 09:14:32 +0000 Subject: [PATCH 6273/9457] spi: spi-mxs: Fix mapping from vmalloc-ed buffer to scatter list We can only use page_address on memory that has been mapped using kmap, when the buffer passed to the SPI has been allocated by vmalloc the page has not necessarily been mapped through kmap. This means sometimes page_address will return NULL causing the pointer we pass to sg_init_one to be invalid. Currently, this issue doesn't show up on the MXS architecture as the defconfig defines CONFIG_HIGHMEM=n which means all pages are mapped. For the sake of robustness though it is best to correct the issue. As we only call page_address so that we can pass a virtual address to sg_init_one which will eventually call virt_to_page on it, fix this by calling sg_set_page directly rather then relying on the sg_init_one helper. Note this patch is only build tested as I don't have an MXS system to test on. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/spi/spi-mxs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index a9e72f9d385e..06a11546a1a7 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -182,7 +182,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int min, ret; u32 ctrl0; struct page *vm_page; - void *sg_buf; struct { u32 pio[4]; struct scatterlist sg; @@ -232,13 +231,14 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, ret = -ENOMEM; goto err_vmalloc; } - sg_buf = page_address(vm_page) + - ((size_t)buf & ~PAGE_MASK); + + sg_init_table(&dma_xfer[sg_count].sg, 1); + sg_set_page(&dma_xfer[sg_count].sg, vm_page, + min, offset_in_page(buf)); } else { - sg_buf = buf; + sg_init_one(&dma_xfer[sg_count].sg, buf, min); } - sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min); ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); -- GitLab From 4fdb2424cc4499237197a8c9d35b34d68c750475 Mon Sep 17 00:00:00 2001 From: Weike Chen Date: Wed, 8 Oct 2014 08:50:22 -0700 Subject: [PATCH 6274/9457] spi: spi-pxa2xx: Add helpers for regiseters' accessing There are several registers for SPI, and the registers of 'SSCR0' and 'SSCR1' are accessed frequently. This path is to introduce helper functions to simplify the accessing of 'SSCR0' and 'SSCR1'. Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Weike Chen Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 107 ++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 9e9e0f971e6c..d4d29c594156 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -80,6 +80,73 @@ static bool is_lpss_ssp(const struct driver_data *drv_data) return drv_data->ssp_type == LPSS_SSP; } +static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) +{ + switch (drv_data->ssp_type) { + default: + return SSCR1_CHANGE_MASK; + } +} + +static u32 +pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data) +{ + switch (drv_data->ssp_type) { + default: + return RX_THRESH_DFLT; + } +} + +static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data) +{ + void __iomem *reg = drv_data->ioaddr; + u32 mask; + + switch (drv_data->ssp_type) { + default: + mask = SSSR_TFL_MASK; + break; + } + + return (read_SSSR(reg) & mask) == mask; +} + +static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data, + u32 *sccr1_reg) +{ + u32 mask; + + switch (drv_data->ssp_type) { + default: + mask = SSCR1_RFT; + break; + } + *sccr1_reg &= ~mask; +} + +static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data, + u32 *sccr1_reg, u32 threshold) +{ + switch (drv_data->ssp_type) { + default: + *sccr1_reg |= SSCR1_RxTresh(threshold); + break; + } +} + +static u32 pxa2xx_configure_sscr0(const struct driver_data *drv_data, + u32 clk_div, u8 bits) +{ + switch (drv_data->ssp_type) { + default: + return clk_div + | SSCR0_Motorola + | SSCR0_DataSize(bits > 16 ? bits - 16 : bits) + | SSCR0_SSE + | (bits > 16 ? SSCR0_EDSS : 0); + } +} + /* * Read and write LPSS SSP private registers. Caller must first check that * is_lpss_ssp() returns true before these can be called. @@ -234,7 +301,7 @@ static int null_writer(struct driver_data *drv_data) void __iomem *reg = drv_data->ioaddr; u8 n_bytes = drv_data->n_bytes; - if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) + if (pxa2xx_spi_txfifo_full(drv_data) || (drv_data->tx == drv_data->tx_end)) return 0; @@ -262,7 +329,7 @@ static int u8_writer(struct driver_data *drv_data) { void __iomem *reg = drv_data->ioaddr; - if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) + if (pxa2xx_spi_txfifo_full(drv_data) || (drv_data->tx == drv_data->tx_end)) return 0; @@ -289,7 +356,7 @@ static int u16_writer(struct driver_data *drv_data) { void __iomem *reg = drv_data->ioaddr; - if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) + if (pxa2xx_spi_txfifo_full(drv_data) || (drv_data->tx == drv_data->tx_end)) return 0; @@ -316,7 +383,7 @@ static int u32_writer(struct driver_data *drv_data) { void __iomem *reg = drv_data->ioaddr; - if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) + if (pxa2xx_spi_txfifo_full(drv_data) || (drv_data->tx == drv_data->tx_end)) return 0; @@ -508,8 +575,9 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) * remaining RX bytes. */ if (pxa25x_ssp_comp(drv_data)) { + u32 rx_thre; - sccr1_reg &= ~SSCR1_RFT; + pxa2xx_spi_clear_rx_thre(drv_data, &sccr1_reg); bytes_left = drv_data->rx_end - drv_data->rx; switch (drv_data->n_bytes) { @@ -519,10 +587,11 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) bytes_left >>= 1; } - if (bytes_left > RX_THRESH_DFLT) - bytes_left = RX_THRESH_DFLT; + rx_thre = pxa2xx_spi_get_rx_default_thre(drv_data); + if (rx_thre > bytes_left) + rx_thre = bytes_left; - sccr1_reg |= SSCR1_RxTresh(bytes_left); + pxa2xx_spi_set_rx_thre(drv_data, &sccr1_reg, rx_thre); } write_SSCR1(sccr1_reg, reg); } @@ -613,6 +682,7 @@ static void pump_transfers(unsigned long data) u32 cr1; u32 dma_thresh = drv_data->cur_chip->dma_threshold; u32 dma_burst = drv_data->cur_chip->dma_burst_size; + u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); /* Get current state information */ message = drv_data->cur_msg; @@ -731,11 +801,7 @@ static void pump_transfers(unsigned long data) "pump_transfers: DMA burst size reduced to match bits_per_word\n"); } - cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(bits > 16 ? bits - 16 : bits) - | SSCR0_SSE - | (bits > 16 ? SSCR0_EDSS : 0); + cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits); } message->state = RUNNING_STATE; @@ -772,16 +838,15 @@ static void pump_transfers(unsigned long data) } /* see if we need to reload the config registers */ - if ((read_SSCR0(reg) != cr0) - || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != - (cr1 & SSCR1_CHANGE_MASK)) { + if ((read_SSCR0(reg) != cr0) || + (read_SSCR1(reg) & change_mask) != (cr1 & change_mask)) { /* stop the SSP, and update the other bits */ write_SSCR0(cr0 & ~SSCR0_SSE, reg); if (!pxa25x_ssp_comp(drv_data)) write_SSTO(chip->timeout, reg); /* first set CR1 without interrupt and service enables */ - write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); + write_SSCR1(cr1 & change_mask, reg); /* restart the SSP */ write_SSCR0(cr0, reg); @@ -959,12 +1024,8 @@ static int setup(struct spi_device *spi) clk_div = ssp_get_clk_div(drv_data, spi->max_speed_hz); chip->speed_hz = spi->max_speed_hz; - chip->cr0 = clk_div - | SSCR0_Motorola - | SSCR0_DataSize(spi->bits_per_word > 16 ? - spi->bits_per_word - 16 : spi->bits_per_word) - | SSCR0_SSE - | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); + chip->cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, + spi->bits_per_word); chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); -- GitLab From c15d789e3cfa94f90f86766bb2302dd643ef4621 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 20 Nov 2014 22:26:59 +0100 Subject: [PATCH 6275/9457] brcmfmac: fix static checker warning in pmklist handling The patch fixes a static checker warning: drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c:2965 brcmf_cfg80211_set_pmksa() warn: can 'pmkid_len' be negative? The answer to the question above is likely no so changing its type to unsigned is sufficient. Reported-by: Dan Carpenter Reviewed-by: Hante Meuleman Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index f8a9dfa657ba..d1928de895f9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c @@ -2932,7 +2932,7 @@ brcmf_update_pmklist(struct net_device *ndev, struct brcmf_cfg80211_pmk_list *pmk_list, s32 err) { int i, j; - int pmkid_len; + u32 pmkid_len; pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid); @@ -2960,8 +2960,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(ndev); struct pmkid_list *pmkids = &cfg->pmk_list->pmkids; s32 err = 0; - int i; - int pmkid_len; + u32 pmkid_len, i; brcmf_dbg(TRACE, "Enter\n"); if (!check_vif_up(ifp->vif)) @@ -3000,7 +2999,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(ndev); struct pmkid_list pmkid; s32 err = 0; - int i, pmkid_len; + u32 pmkid_len, i; brcmf_dbg(TRACE, "Enter\n"); if (!check_vif_up(ifp->vif)) -- GitLab From 8d213de7ffff614e3aa751a31a8980e1be3036e1 Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Fri, 21 Nov 2014 20:50:46 +0100 Subject: [PATCH 6276/9457] ASoC: rockchip: i2s: Fix Kconfig for I2S device driver Currently, CONFIG_SND_SOC_ROCKCHIP_I2S could also be selected without having CONFIG_SND_SOC_ROCKCHIP enabled. As this makes no sense, a Kconfig dependency is added to CONFIG_SND_SOC_ROCKCHIP_I2S. This will make the item visible only if CONFIG_SND_SOC_ROCKCHIP is enabled. Additionally, as the code connected to CONFIG_SND_SOC_ROCKCHIP_I2S depends on CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM, the dependency is moved to reflect this more clearly. Signed-off-by: Andreas Ruprecht Reported-by: Jim Davis Signed-off-by: Mark Brown --- sound/soc/rockchip/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index b1fc0ca3e617..e18182699d83 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -1,7 +1,6 @@ config SND_SOC_ROCKCHIP tristate "ASoC support for Rockchip" depends on COMPILE_TEST || ARCH_ROCKCHIP - select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the Rockchip SoCs' Audio interfaces. You will also need to @@ -9,7 +8,8 @@ config SND_SOC_ROCKCHIP config SND_SOC_ROCKCHIP_I2S tristate "Rockchip I2S Device Driver" - depends on CLKDEV_LOOKUP + depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for I2S driver for Rockchip I2S device. The device supports upto maximum of -- GitLab From 7920408b0c8292831f064ea33f56aa307b221a2c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 14 Nov 2014 10:39:21 -0800 Subject: [PATCH 6277/9457] tty: serial: msm_serial: Don't require DT aliases If there isn't a DT alias then of_alias_get_id() will return -ENODEV. This will cause the msm_serial driver to fail probe, when we want to keep the previous behavior where we generated a dynamic line number at probe time. Restore this behavior by generating a dynamic id if the line number is still negative after checking for an alias or in the non-DT case looking at the .id field of the platform device. Reported-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/msm_serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 09364dd8cf3a..d1bc6b6cbc70 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1046,14 +1046,14 @@ static int msm_serial_probe(struct platform_device *pdev) const struct of_device_id *id; int irq, line; - if (pdev->id == -1) - pdev->id = atomic_inc_return(&msm_uart_next_id) - 1; - if (pdev->dev.of_node) line = of_alias_get_id(pdev->dev.of_node, "serial"); else line = pdev->id; + if (line < 0) + line = atomic_inc_return(&msm_uart_next_id) - 1; + if (unlikely(line < 0 || line >= UART_NR)) return -ENXIO; -- GitLab From bbac3297c6712f061853e3e11d5e21aa4164968f Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Fri, 14 Nov 2014 14:07:15 -0800 Subject: [PATCH 6278/9457] tty: serial: msm_serial: document DT alias Update devicetree binding for msm_serial to reflect msm_serial_probe() getting line id (port number) from the serialN alias. Signed-off-by: Frank Rowand Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/qcom,msm-uartdm.txt | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt index ffa5b784c66e..a2114c217376 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt @@ -27,27 +27,52 @@ Optional properties: - dmas: Should contain dma specifiers for transmit and receive channels - dma-names: Should contain "tx" for transmit and "rx" for receive channels +Note: Aliases may be defined to ensure the correct ordering of the UARTs. +The alias serialN will result in the UART being assigned port N. If any +serialN alias exists, then an alias must exist for each enabled UART. The +serialN aliases should be in a .dts file instead of in a .dtsi file. + Examples: -A uartdm v1.4 device with dma capabilities. - -serial@f991e000 { - compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0xf991e000 0x1000>; - interrupts = <0 108 0x0>; - clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; - clock-names = "core", "iface"; - dmas = <&dma0 0>, <&dma0 1>; - dma-names = "tx", "rx"; -}; - -A uartdm v1.3 device without dma capabilities and part of a GSBI complex. - -serial@19c40000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x19c40000 0x1000>, - <0x19c00000 0x1000>; - interrupts = <0 195 0x0>; - clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; - clock-names = "core", "iface"; -}; +- A uartdm v1.4 device with dma capabilities. + + serial@f991e000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0xf991e000 0x1000>; + interrupts = <0 108 0x0>; + clocks = <&blsp1_uart2_apps_cxc>, <&blsp1_ahb_cxc>; + clock-names = "core", "iface"; + dmas = <&dma0 0>, <&dma0 1>; + dma-names = "tx", "rx"; + }; + +- A uartdm v1.3 device without dma capabilities and part of a GSBI complex. + + serial@19c40000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x19c40000 0x1000>, + <0x19c00000 0x1000>; + interrupts = <0 195 0x0>; + clocks = <&gsbi5_uart_cxc>, <&gsbi5_ahb_cxc>; + clock-names = "core", "iface"; + }; + +- serialN alias. + + aliases { + serial0 = &uarta; + serial1 = &uartc; + serial2 = &uartb; + }; + + uarta: serial@12490000 { + status = "ok"; + }; + + uartb: serial@16340000 { + status = "ok"; + }; + + uartc: serial@1a240000 { + status = "ok"; + }; -- GitLab From 62a207d748dd9224140a634786b274fdb6ece0b9 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 24 Nov 2014 14:58:17 -0500 Subject: [PATCH 6279/9457] ftrace/x86: Have static function tracing always test for function graph New updates to the ftrace generic code had ftrace_stub not always being called when ftrace is off. This causes the static tracer to always save and restore functions. But it also showed that when function tracing is running, the function graph tracer can not. We should always check to see if function graph tracing is running even if the function tracer is running too. The function tracer code is not the only one that uses the hook to function mcount. Cc: Markos Chandras Signed-off-by: Steven Rostedt --- arch/x86/kernel/mcount_64.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S index 35a793fa4bba..6dc134b8dc70 100644 --- a/arch/x86/kernel/mcount_64.S +++ b/arch/x86/kernel/mcount_64.S @@ -194,6 +194,7 @@ ENTRY(function_hook) cmpq $ftrace_stub, ftrace_trace_function jnz trace +fgraph_trace: #ifdef CONFIG_FUNCTION_GRAPH_TRACER cmpq $ftrace_stub, ftrace_graph_return jnz ftrace_graph_caller @@ -220,7 +221,7 @@ trace: MCOUNT_RESTORE_FRAME - jmp ftrace_stub + jmp fgraph_trace END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */ -- GitLab From d543a76295a7f83ab990970f68c9501a0bb4bcb5 Mon Sep 17 00:00:00 2001 From: Nimrod Andy Date: Sun, 23 Nov 2014 17:23:06 +0800 Subject: [PATCH 6280/9457] net: fec: init maximum receive buffer size for ring1 and ring2 i.MX6SX fec support three rx ring1, the current driver lost to init ring1 and ring2 maximum receive buffer size, that cause receving frame date length error. The driver reports "rcv is not +last" error log in user case. Signed-off-by: Fugang Duan Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 11 +++++++++-- drivers/net/ethernet/freescale/fec_main.c | 4 +--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 7aa9388a3aa8..469691ad4a1e 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -53,11 +53,13 @@ #define FEC_R_FSTART 0x150 /* FIFO receive start reg */ #define FEC_R_DES_START_1 0x160 /* Receive descriptor ring 1 */ #define FEC_X_DES_START_1 0x164 /* Transmit descriptor ring 1 */ +#define FEC_R_BUFF_SIZE_1 0x168 /* Maximum receive buff ring1 size */ #define FEC_R_DES_START_2 0x16c /* Receive descriptor ring 2 */ #define FEC_X_DES_START_2 0x170 /* Transmit descriptor ring 2 */ +#define FEC_R_BUFF_SIZE_2 0x174 /* Maximum receive buff ring2 size */ #define FEC_R_DES_START_0 0x180 /* Receive descriptor ring */ #define FEC_X_DES_START_0 0x184 /* Transmit descriptor ring */ -#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */ +#define FEC_R_BUFF_SIZE_0 0x188 /* Maximum receive buff size */ #define FEC_R_FIFO_RSFL 0x190 /* Receive FIFO section full threshold */ #define FEC_R_FIFO_RSEM 0x194 /* Receive FIFO section empty threshold */ #define FEC_R_FIFO_RAEM 0x198 /* Receive FIFO almost empty threshold */ @@ -165,7 +167,9 @@ #define FEC_X_DES_START_0 0x3d4 /* Transmit descriptor ring */ #define FEC_X_DES_START_1 FEC_X_DES_START_0 #define FEC_X_DES_START_2 FEC_X_DES_START_0 -#define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */ +#define FEC_R_BUFF_SIZE_0 0x3d8 /* Maximum receive buff size */ +#define FEC_R_BUFF_SIZE_1 FEC_R_BUFF_SIZE_0 +#define FEC_R_BUFF_SIZE_2 FEC_R_BUFF_SIZE_0 #define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */ /* Not existed in real chip * Just for pass build. @@ -285,6 +289,9 @@ struct bufdesc_ex { #define FEC_X_DES_START(X) (((X) == 1) ? FEC_X_DES_START_1 : \ (((X) == 2) ? \ FEC_X_DES_START_2 : FEC_X_DES_START_0)) +#define FEC_R_BUFF_SIZE(X) (((X) == 1) ? FEC_R_BUFF_SIZE_1 : \ + (((X) == 2) ? \ + FEC_R_BUFF_SIZE_2 : FEC_R_BUFF_SIZE_0)) #define FEC_R_DES_ACTIVE(X) (((X) == 1) ? FEC_R_DES_ACTIVE_1 : \ (((X) == 2) ? \ FEC_R_DES_ACTIVE_2 : FEC_R_DES_ACTIVE_0)) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1b6d26b00826..d2955ce24d0b 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -867,6 +867,7 @@ static void fec_enet_enable_ring(struct net_device *ndev) for (i = 0; i < fep->num_rx_queues; i++) { rxq = fep->rx_queue[i]; writel(rxq->bd_dma, fep->hwp + FEC_R_DES_START(i)); + writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE(i)); /* enable DMA1/2 */ if (i) @@ -941,9 +942,6 @@ fec_restart(struct net_device *ndev) /* Clear any outstanding interrupt. */ writel(0xffc00000, fep->hwp + FEC_IEVENT); - /* Set maximum receive buffer size. */ - writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - fec_enet_bd_init(ndev); fec_enet_enable_ring(ndev); -- GitLab From 2bbea0a885079a095c252a927a174a0bfec9e3e9 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sun, 23 Nov 2014 13:07:54 +0100 Subject: [PATCH 6281/9457] 8139too: The maximum MTU should allow for VLAN headers As pointed out by Ben Hutchings drivers that allow using VLAN have to provide enough headroom for the VLAN tags. Signed-off-by: Alban Bedel Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/8139too.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index e157541b842b..63dc0f95d050 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -112,6 +112,7 @@ #include #include #include +#include #include #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION @@ -182,13 +183,13 @@ static int debug = -1; /* Number of Tx descriptor registers. */ #define NUM_TX_DESC 4 -/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/ +/* max supported ethernet frame size -- must be at least (dev->mtu+18+4).*/ #define MAX_ETH_FRAME_SIZE 1792 /* max supported payload size */ -#define MAX_ETH_DATA_SIZE (MAX_ETH_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN) +#define MAX_ETH_DATA_SIZE (MAX_ETH_FRAME_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN) -/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */ +/* Size of the Tx bounce buffers -- must be at least (dev->mtu+18+4). */ #define TX_BUF_SIZE MAX_ETH_FRAME_SIZE #define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC) -- GitLab From 2ad7bf3638411cb547f2823df08166c13ab04269 Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Sun, 23 Nov 2014 23:07:46 -0800 Subject: [PATCH 6282/9457] ipvlan: Initial check-in of the IPVLAN driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver is very similar to the macvlan driver except that it uses L3 on the frame to determine the logical interface while functioning as packet dispatcher. It inherits L2 of the master device hence the packets on wire will have the same L2 for all the packets originating from all virtual devices off of the same master device. This driver was developed keeping the namespace use-case in mind. Hence most of the examples given here take that as the base setup where main-device belongs to the default-ns and virtual devices are assigned to the additional namespaces. The device operates in two different modes and the difference in these two modes in primarily in the TX side. (a) L2 mode : In this mode, the device behaves as a L2 device. TX processing upto L2 happens on the stack of the virtual device associated with (namespace). Packets are switched after that into the main device (default-ns) and queued for xmit. RX processing is simple and all multicast, broadcast (if applicable), and unicast belonging to the address(es) are delivered to the virtual devices. (b) L3 mode : In this mode, the device behaves like a L3 device. TX processing upto L3 happens on the stack of the virtual device associated with (namespace). Packets are switched to the main-device (default-ns) for the L2 processing. Hence the routing table of the default-ns will be used in this mode. RX processins is somewhat similar to the L2 mode except that in this mode only Unicast packets are delivered to the virtual device while main-dev will handle all other packets. The devices can be added using the "ip" command from the iproute2 package - ip link add link type ipvlan mode [ l2 | l3 ] Signed-off-by: Mahesh Bandewar Cc: Eric Dumazet Cc: Maciej Żenczykowski Cc: Laurent Chavey Cc: Tim Hockin Cc: Brandon Philips Cc: Pavel Emelianov Signed-off-by: David S. Miller --- Documentation/networking/ipvlan.txt | 107 ++++ drivers/net/Kconfig | 18 + drivers/net/Makefile | 1 + drivers/net/ipvlan/Makefile | 7 + drivers/net/ipvlan/ipvlan.h | 130 +++++ drivers/net/ipvlan/ipvlan_core.c | 607 +++++++++++++++++++++ drivers/net/ipvlan/ipvlan_main.c | 789 ++++++++++++++++++++++++++++ include/linux/netdevice.h | 4 + include/uapi/linux/if_link.h | 15 + 9 files changed, 1678 insertions(+) create mode 100644 Documentation/networking/ipvlan.txt create mode 100644 drivers/net/ipvlan/Makefile create mode 100644 drivers/net/ipvlan/ipvlan.h create mode 100644 drivers/net/ipvlan/ipvlan_core.c create mode 100644 drivers/net/ipvlan/ipvlan_main.c diff --git a/Documentation/networking/ipvlan.txt b/Documentation/networking/ipvlan.txt new file mode 100644 index 000000000000..cf996394e466 --- /dev/null +++ b/Documentation/networking/ipvlan.txt @@ -0,0 +1,107 @@ + + IPVLAN Driver HOWTO + +Initial Release: + Mahesh Bandewar + +1. Introduction: + This is conceptually very similar to the macvlan driver with one major +exception of using L3 for mux-ing /demux-ing among slaves. This property makes +the master device share the L2 with it's slave devices. I have developed this +driver in conjuntion with network namespaces and not sure if there is use case +outside of it. + + +2. Building and Installation: + In order to build the driver, please select the config item CONFIG_IPVLAN. +The driver can be built into the kernel (CONFIG_IPVLAN=y) or as a module +(CONFIG_IPVLAN=m). + + +3. Configuration: + There are no module parameters for this driver and it can be configured +using IProute2/ip utility. + + ip link add link type ipvlan mode { l2 | L3 } + + e.g. ip link add link ipvl0 eth0 type ipvlan mode l2 + + +4. Operating modes: + IPvlan has two modes of operation - L2 and L3. For a given master device, +you can select one of these two modes and all slaves on that master will +operate in the same (selected) mode. The RX mode is almost identical except +that in L3 mode the slaves wont receive any multicast / broadcast traffic. +L3 mode is more restrictive since routing is controlled from the other (mostly) +default namespace. + +4.1 L2 mode: + In this mode TX processing happens on the stack instance attached to the +slave device and packets are switched and queued to the master device to send +out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) +as well. + +4.2 L3 mode: + In this mode TX processing upto L3 happens on the stack instance attached +to the slave device and packets are switched to the stack instance of the +master device for the L2 processing and routing from that instance will be +used before packets are queued on the outbound device. In this mode the slaves +will not receive nor can send multicast / broadcast traffic. + + +5. What to choose (macvlan vs. ipvlan)? + These two devices are very similar in many regards and the specific use +case could very well define which device to choose. if one of the following +situations defines your use case then you can choose to use ipvlan - + (a) The Linux host that is connected to the external switch / router has +policy configured that allows only one mac per port. + (b) No of virtual devices created on a master exceed the mac capacity and +puts the NIC in promiscous mode and degraded performance is a concern. + (c) If the slave device is to be put into the hostile / untrusted network +namespace where L2 on the slave could be changed / misused. + + +6. Example configuration: + + +=============================================================+ + | Host: host1 | + | | + | +----------------------+ +----------------------+ | + | | NS:ns0 | | NS:ns1 | | + | | | | | | + | | | | | | + | | ipvl0 | | ipvl1 | | + | +----------#-----------+ +-----------#----------+ | + | # # | + | ################################ | + | # eth0 | + +==============================#==============================+ + + + (a) Create two network namespaces - ns0, ns1 + ip netns add ns0 + ip netns add ns1 + + (b) Create two ipvlan slaves on eth0 (master device) + ip link add link eth0 ipvl0 type ipvlan mode l2 + ip link add link eth0 ipvl1 type ipvlan mode l2 + + (c) Assign slaves to the respective network namespaces + ip link set dev ipvl0 netns ns0 + ip link set dev ipvl1 netns ns1 + + (d) Now switch to the namespace (ns0 or ns1) to configure the slave devices + - For ns0 + (1) ip netns exec ns0 bash + (2) ip link set dev ipvl0 up + (3) ip link set dev lo up + (4) ip -4 addr add 127.0.0.1 dev lo + (5) ip -4 addr add $IPADDR dev ipvl0 + (6) ip -4 route add default via $ROUTER dev ipvl0 + - For ns1 + (1) ip netns exec ns1 bash + (2) ip link set dev ipvl1 up + (3) ip link set dev lo up + (4) ip -4 addr add 127.0.0.1 dev lo + (5) ip -4 addr add $IPADDR dev ipvl1 + (6) ip -4 route add default via $ROUTER dev ipvl1 diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f9009be3f307..b6d64f546574 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -145,6 +145,24 @@ config MACVTAP To compile this driver as a module, choose M here: the module will be called macvtap. + +config IPVLAN + tristate "IP-VLAN support" + ---help--- + This allows one to create virtual devices off of a main interface + and packets will be delivered based on the dest L3 (IPv6/IPv4 addr) + on packets. All interfaces (including the main interface) share L2 + making it transparent to the connected L2 switch. + + Ipvlan devices can be added using the "ip" command from the + iproute2 package starting with the iproute2-X.Y.ZZ release: + + "ip link add link [ NAME ] type ipvlan" + + To compile this driver as a module, choose M here: the module + will be called ipvlan. + + config VXLAN tristate "Virtual eXtensible Local Area Network (VXLAN)" depends on INET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 61aefdd1e173..e25fdd7d905e 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -6,6 +6,7 @@ # Networking Core Drivers # obj-$(CONFIG_BONDING) += bonding/ +obj-$(CONFIG_IPVLAN) += ipvlan/ obj-$(CONFIG_DUMMY) += dummy.o obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_IFB) += ifb.o diff --git a/drivers/net/ipvlan/Makefile b/drivers/net/ipvlan/Makefile new file mode 100644 index 000000000000..df79910192d6 --- /dev/null +++ b/drivers/net/ipvlan/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the Ethernet Ipvlan driver +# + +obj-$(CONFIG_IPVLAN) += ipvlan.o + +ipvlan-objs := ipvlan_core.o ipvlan_main.o diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h new file mode 100644 index 000000000000..ab3e7614ed71 --- /dev/null +++ b/drivers/net/ipvlan/ipvlan.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014 Mahesh Bandewar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + */ +#ifndef __IPVLAN_H +#define __IPVLAN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPVLAN_DRV "ipvlan" +#define IPV_DRV_VER "0.1" + +#define IPVLAN_HASH_SIZE (1 << BITS_PER_BYTE) +#define IPVLAN_HASH_MASK (IPVLAN_HASH_SIZE - 1) + +#define IPVLAN_MAC_FILTER_BITS 8 +#define IPVLAN_MAC_FILTER_SIZE (1 << IPVLAN_MAC_FILTER_BITS) +#define IPVLAN_MAC_FILTER_MASK (IPVLAN_MAC_FILTER_SIZE - 1) + +typedef enum { + IPVL_IPV6 = 0, + IPVL_ICMPV6, + IPVL_IPV4, + IPVL_ARP, +} ipvl_hdr_type; + +struct ipvl_pcpu_stats { + u64 rx_pkts; + u64 rx_bytes; + u64 rx_mcast; + u64 tx_pkts; + u64 tx_bytes; + struct u64_stats_sync syncp; + u32 rx_errs; + u32 tx_drps; +}; + +struct ipvl_port; + +struct ipvl_dev { + struct net_device *dev; + struct list_head pnode; + struct ipvl_port *port; + struct net_device *phy_dev; + struct list_head addrs; + int ipv4cnt; + int ipv6cnt; + struct ipvl_pcpu_stats *pcpu_stats; + DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE); + netdev_features_t sfeatures; + u32 msg_enable; + u16 mtu_adj; +}; + +struct ipvl_addr { + struct ipvl_dev *master; /* Back pointer to master */ + union { + struct in6_addr ip6; /* IPv6 address on logical interface */ + struct in_addr ip4; /* IPv4 address on logical interface */ + } ipu; +#define ip6addr ipu.ip6 +#define ip4addr ipu.ip4 + struct hlist_node hlnode; /* Hash-table linkage */ + struct list_head anode; /* logical-interface linkage */ + struct rcu_head rcu; + ipvl_hdr_type atype; +}; + +struct ipvl_port { + struct net_device *dev; + struct hlist_head hlhead[IPVLAN_HASH_SIZE]; + struct list_head ipvlans; + struct rcu_head rcu; + int count; + u16 mode; +}; + +static inline struct ipvl_port *ipvlan_port_get_rcu(const struct net_device *d) +{ + return rcu_dereference(d->rx_handler_data); +} + +static inline struct ipvl_port *ipvlan_port_get_rtnl(const struct net_device *d) +{ + return rtnl_dereference(d->rx_handler_data); +} + +static inline bool ipvlan_dev_master(struct net_device *d) +{ + return d->priv_flags & IFF_IPVLAN_MASTER; +} + +static inline bool ipvlan_dev_slave(struct net_device *d) +{ + return d->priv_flags & IFF_IPVLAN_SLAVE; +} + +void ipvlan_adjust_mtu(struct ipvl_dev *ipvlan, struct net_device *dev); +void ipvlan_set_port_mode(struct ipvl_port *port, u32 nval); +void ipvlan_init_secret(void); +unsigned int ipvlan_mac_hash(const unsigned char *addr); +rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb); +int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev); +void ipvlan_ht_addr_add(struct ipvl_dev *ipvlan, struct ipvl_addr *addr); +bool ipvlan_addr_busy(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6); +struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port, + const void *iaddr, bool is_v6); +void ipvlan_ht_addr_del(struct ipvl_addr *addr, bool sync); +#endif /* __IPVLAN_H */ diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c new file mode 100644 index 000000000000..a14d87783245 --- /dev/null +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -0,0 +1,607 @@ +/* Copyright (c) 2014 Mahesh Bandewar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + */ + +#include "ipvlan.h" + +static u32 ipvlan_jhash_secret; + +void ipvlan_init_secret(void) +{ + net_get_random_once(&ipvlan_jhash_secret, sizeof(ipvlan_jhash_secret)); +} + +static void ipvlan_count_rx(const struct ipvl_dev *ipvlan, + unsigned int len, bool success, bool mcast) +{ + if (!ipvlan) + return; + + if (likely(success)) { + struct ipvl_pcpu_stats *pcptr; + + pcptr = this_cpu_ptr(ipvlan->pcpu_stats); + u64_stats_update_begin(&pcptr->syncp); + pcptr->rx_pkts++; + pcptr->rx_bytes += len; + if (mcast) + pcptr->rx_mcast++; + u64_stats_update_end(&pcptr->syncp); + } else { + this_cpu_inc(ipvlan->pcpu_stats->rx_errs); + } +} + +static u8 ipvlan_get_v6_hash(const void *iaddr) +{ + const struct in6_addr *ip6_addr = iaddr; + + return __ipv6_addr_jhash(ip6_addr, ipvlan_jhash_secret) & + IPVLAN_HASH_MASK; +} + +static u8 ipvlan_get_v4_hash(const void *iaddr) +{ + const struct in_addr *ip4_addr = iaddr; + + return jhash_1word(ip4_addr->s_addr, ipvlan_jhash_secret) & + IPVLAN_HASH_MASK; +} + +struct ipvl_addr *ipvlan_ht_addr_lookup(const struct ipvl_port *port, + const void *iaddr, bool is_v6) +{ + struct ipvl_addr *addr; + u8 hash; + + hash = is_v6 ? ipvlan_get_v6_hash(iaddr) : + ipvlan_get_v4_hash(iaddr); + hlist_for_each_entry_rcu(addr, &port->hlhead[hash], hlnode) { + if (is_v6 && addr->atype == IPVL_IPV6 && + ipv6_addr_equal(&addr->ip6addr, iaddr)) + return addr; + else if (!is_v6 && addr->atype == IPVL_IPV4 && + addr->ip4addr.s_addr == + ((struct in_addr *)iaddr)->s_addr) + return addr; + } + return NULL; +} + +void ipvlan_ht_addr_add(struct ipvl_dev *ipvlan, struct ipvl_addr *addr) +{ + struct ipvl_port *port = ipvlan->port; + u8 hash; + + hash = (addr->atype == IPVL_IPV6) ? + ipvlan_get_v6_hash(&addr->ip6addr) : + ipvlan_get_v4_hash(&addr->ip4addr); + hlist_add_head_rcu(&addr->hlnode, &port->hlhead[hash]); +} + +void ipvlan_ht_addr_del(struct ipvl_addr *addr, bool sync) +{ + hlist_del_rcu(&addr->hlnode); + if (sync) + synchronize_rcu(); +} + +bool ipvlan_addr_busy(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) +{ + struct ipvl_port *port = ipvlan->port; + struct ipvl_addr *addr; + + list_for_each_entry(addr, &ipvlan->addrs, anode) { + if ((is_v6 && addr->atype == IPVL_IPV6 && + ipv6_addr_equal(&addr->ip6addr, iaddr)) || + (!is_v6 && addr->atype == IPVL_IPV4 && + addr->ip4addr.s_addr == ((struct in_addr *)iaddr)->s_addr)) + return true; + } + + if (ipvlan_ht_addr_lookup(port, iaddr, is_v6)) + return true; + + return false; +} + +static void *ipvlan_get_L3_hdr(struct sk_buff *skb, int *type) +{ + void *lyr3h = NULL; + + switch (skb->protocol) { + case htons(ETH_P_ARP): { + struct arphdr *arph; + + if (unlikely(!pskb_may_pull(skb, sizeof(*arph)))) + return NULL; + + arph = arp_hdr(skb); + *type = IPVL_ARP; + lyr3h = arph; + break; + } + case htons(ETH_P_IP): { + u32 pktlen; + struct iphdr *ip4h; + + if (unlikely(!pskb_may_pull(skb, sizeof(*ip4h)))) + return NULL; + + ip4h = ip_hdr(skb); + pktlen = ntohs(ip4h->tot_len); + if (ip4h->ihl < 5 || ip4h->version != 4) + return NULL; + if (skb->len < pktlen || pktlen < (ip4h->ihl * 4)) + return NULL; + + *type = IPVL_IPV4; + lyr3h = ip4h; + break; + } + case htons(ETH_P_IPV6): { + struct ipv6hdr *ip6h; + + if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h)))) + return NULL; + + ip6h = ipv6_hdr(skb); + if (ip6h->version != 6) + return NULL; + + *type = IPVL_IPV6; + lyr3h = ip6h; + /* Only Neighbour Solicitation pkts need different treatment */ + if (ipv6_addr_any(&ip6h->saddr) && + ip6h->nexthdr == NEXTHDR_ICMP) { + *type = IPVL_ICMPV6; + lyr3h = ip6h + 1; + } + break; + } + default: + return NULL; + } + + return lyr3h; +} + +unsigned int ipvlan_mac_hash(const unsigned char *addr) +{ + u32 hash = jhash_1word(__get_unaligned_cpu32(addr+2), + ipvlan_jhash_secret); + + return hash & IPVLAN_MAC_FILTER_MASK; +} + +static void ipvlan_multicast_frame(struct ipvl_port *port, struct sk_buff *skb, + const struct ipvl_dev *in_dev, bool local) +{ + struct ethhdr *eth = eth_hdr(skb); + struct ipvl_dev *ipvlan; + struct sk_buff *nskb; + unsigned int len; + unsigned int mac_hash; + int ret; + + if (skb->protocol == htons(ETH_P_PAUSE)) + return; + + list_for_each_entry(ipvlan, &port->ipvlans, pnode) { + if (local && (ipvlan == in_dev)) + continue; + + mac_hash = ipvlan_mac_hash(eth->h_dest); + if (!test_bit(mac_hash, ipvlan->mac_filters)) + continue; + + ret = NET_RX_DROP; + len = skb->len + ETH_HLEN; + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + goto mcast_acct; + + if (ether_addr_equal(eth->h_dest, ipvlan->phy_dev->broadcast)) + nskb->pkt_type = PACKET_BROADCAST; + else + nskb->pkt_type = PACKET_MULTICAST; + + nskb->dev = ipvlan->dev; + if (local) + ret = dev_forward_skb(ipvlan->dev, nskb); + else + ret = netif_rx(nskb); +mcast_acct: + ipvlan_count_rx(ipvlan, len, ret == NET_RX_SUCCESS, true); + } + + /* Locally generated? ...Forward a copy to the main-device as + * well. On the RX side we'll ignore it (wont give it to any + * of the virtual devices. + */ + if (local) { + nskb = skb_clone(skb, GFP_ATOMIC); + if (nskb) { + if (ether_addr_equal(eth->h_dest, port->dev->broadcast)) + nskb->pkt_type = PACKET_BROADCAST; + else + nskb->pkt_type = PACKET_MULTICAST; + + dev_forward_skb(port->dev, nskb); + } + } +} + +static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb, + bool local) +{ + struct ipvl_dev *ipvlan = addr->master; + struct net_device *dev = ipvlan->dev; + unsigned int len; + rx_handler_result_t ret = RX_HANDLER_CONSUMED; + bool success = false; + + len = skb->len + ETH_HLEN; + if (unlikely(!(dev->flags & IFF_UP))) { + kfree_skb(skb); + goto out; + } + + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto out; + + skb->dev = dev; + skb->pkt_type = PACKET_HOST; + + if (local) { + if (dev_forward_skb(ipvlan->dev, skb) == NET_RX_SUCCESS) + success = true; + } else { + ret = RX_HANDLER_ANOTHER; + success = true; + } + +out: + ipvlan_count_rx(ipvlan, len, success, false); + return ret; +} + +static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, + void *lyr3h, int addr_type, + bool use_dest) +{ + struct ipvl_addr *addr = NULL; + + if (addr_type == IPVL_IPV6) { + struct ipv6hdr *ip6h; + struct in6_addr *i6addr; + + ip6h = (struct ipv6hdr *)lyr3h; + i6addr = use_dest ? &ip6h->daddr : &ip6h->saddr; + addr = ipvlan_ht_addr_lookup(port, i6addr, true); + } else if (addr_type == IPVL_ICMPV6) { + struct nd_msg *ndmh; + struct in6_addr *i6addr; + + /* Make sure that the NeighborSolicitation ICMPv6 packets + * are handled to avoid DAD issue. + */ + ndmh = (struct nd_msg *)lyr3h; + if (ndmh->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { + i6addr = &ndmh->target; + addr = ipvlan_ht_addr_lookup(port, i6addr, true); + } + } else if (addr_type == IPVL_IPV4) { + struct iphdr *ip4h; + __be32 *i4addr; + + ip4h = (struct iphdr *)lyr3h; + i4addr = use_dest ? &ip4h->daddr : &ip4h->saddr; + addr = ipvlan_ht_addr_lookup(port, i4addr, false); + } else if (addr_type == IPVL_ARP) { + struct arphdr *arph; + unsigned char *arp_ptr; + __be32 dip; + + arph = (struct arphdr *)lyr3h; + arp_ptr = (unsigned char *)(arph + 1); + if (use_dest) + arp_ptr += (2 * port->dev->addr_len) + 4; + else + arp_ptr += port->dev->addr_len; + + memcpy(&dip, arp_ptr, 4); + addr = ipvlan_ht_addr_lookup(port, &dip, false); + } + + return addr; +} + +static int ipvlan_process_v4_outbound(struct sk_buff *skb) +{ + const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; + struct rtable *rt; + int err, ret = NET_XMIT_DROP; + struct flowi4 fl4 = { + .flowi4_oif = dev->iflink, + .flowi4_tos = RT_TOS(ip4h->tos), + .flowi4_flags = FLOWI_FLAG_ANYSRC, + .daddr = ip4h->daddr, + .saddr = ip4h->saddr, + }; + + rt = ip_route_output_flow(dev_net(dev), &fl4, NULL); + if (IS_ERR(rt)) + goto err; + + if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) { + ip_rt_put(rt); + goto err; + } + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + err = ip_local_out(skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; + else + ret = NET_XMIT_SUCCESS; + goto out; +err: + dev->stats.tx_errors++; + kfree_skb(skb); +out: + return ret; +} + +static int ipvlan_process_v6_outbound(struct sk_buff *skb) +{ + const struct ipv6hdr *ip6h = ipv6_hdr(skb); + struct net_device *dev = skb->dev; + struct dst_entry *dst; + int err, ret = NET_XMIT_DROP; + struct flowi6 fl6 = { + .flowi6_iif = skb->dev->ifindex, + .daddr = ip6h->daddr, + .saddr = ip6h->saddr, + .flowi6_flags = FLOWI_FLAG_ANYSRC, + .flowlabel = ip6_flowinfo(ip6h), + .flowi6_mark = skb->mark, + .flowi6_proto = ip6h->nexthdr, + }; + + dst = ip6_route_output(dev_net(dev), NULL, &fl6); + if (IS_ERR(dst)) + goto err; + + skb_dst_drop(skb); + skb_dst_set(skb, dst); + err = ip6_local_out(skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; + else + ret = NET_XMIT_SUCCESS; + goto out; +err: + dev->stats.tx_errors++; + kfree_skb(skb); +out: + return ret; +} + +static int ipvlan_process_outbound(struct sk_buff *skb, + const struct ipvl_dev *ipvlan) +{ + struct ethhdr *ethh = eth_hdr(skb); + int ret = NET_XMIT_DROP; + + /* In this mode we dont care about multicast and broadcast traffic */ + if (is_multicast_ether_addr(ethh->h_dest)) { + pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n", + ntohs(skb->protocol)); + kfree_skb(skb); + goto out; + } + + /* The ipvlan is a pseudo-L2 device, so the packets that we receive + * will have L2; which need to discarded and processed further + * in the net-ns of the main-device. + */ + if (skb_mac_header_was_set(skb)) { + skb_pull(skb, sizeof(*ethh)); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb_reset_network_header(skb); + } + + if (skb->protocol == htons(ETH_P_IPV6)) + ret = ipvlan_process_v6_outbound(skb); + else if (skb->protocol == htons(ETH_P_IP)) + ret = ipvlan_process_v4_outbound(skb); + else { + pr_warn_ratelimited("Dropped outbound packet type=%x\n", + ntohs(skb->protocol)); + kfree_skb(skb); + } +out: + return ret; +} + +static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + void *lyr3h; + struct ipvl_addr *addr; + int addr_type; + + lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); + if (!lyr3h) + goto out; + + addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); + if (addr) + return ipvlan_rcv_frame(addr, skb, true); + +out: + skb->dev = ipvlan->phy_dev; + return ipvlan_process_outbound(skb, ipvlan); +} + +static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ethhdr *eth = eth_hdr(skb); + struct ipvl_addr *addr; + void *lyr3h; + int addr_type; + + if (ether_addr_equal(eth->h_dest, eth->h_source)) { + lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); + if (lyr3h) { + addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); + if (addr) + return ipvlan_rcv_frame(addr, skb, true); + } + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + return NET_XMIT_DROP; + + /* Packet definitely does not belong to any of the + * virtual devices, but the dest is local. So forward + * the skb for the main-dev. At the RX side we just return + * RX_PASS for it to be processed further on the stack. + */ + return dev_forward_skb(ipvlan->phy_dev, skb); + + } else if (is_multicast_ether_addr(eth->h_dest)) { + u8 ip_summed = skb->ip_summed; + + skb->ip_summed = CHECKSUM_UNNECESSARY; + ipvlan_multicast_frame(ipvlan->port, skb, ipvlan, true); + skb->ip_summed = ip_summed; + } + + skb->dev = ipvlan->phy_dev; + return dev_queue_xmit(skb); +} + +int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port = ipvlan_port_get_rcu(ipvlan->phy_dev); + + if (!port) + goto out; + + if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) + goto out; + + switch(port->mode) { + case IPVLAN_MODE_L2: + return ipvlan_xmit_mode_l2(skb, dev); + case IPVLAN_MODE_L3: + return ipvlan_xmit_mode_l3(skb, dev); + } + + /* Should not reach here */ + WARN_ONCE(true, "ipvlan_queue_xmit() called for mode = [%hx]\n", + port->mode); +out: + kfree_skb(skb); + return NET_XMIT_DROP; +} + +static bool ipvlan_external_frame(struct sk_buff *skb, struct ipvl_port *port) +{ + struct ethhdr *eth = eth_hdr(skb); + struct ipvl_addr *addr; + void *lyr3h; + int addr_type; + + if (ether_addr_equal(eth->h_source, skb->dev->dev_addr)) { + lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); + if (!lyr3h) + return true; + + addr = ipvlan_addr_lookup(port, lyr3h, addr_type, false); + if (addr) + return false; + } + + return true; +} + +static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb, + struct ipvl_port *port) +{ + void *lyr3h; + int addr_type; + struct ipvl_addr *addr; + struct sk_buff *skb = *pskb; + rx_handler_result_t ret = RX_HANDLER_PASS; + + lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); + if (!lyr3h) + goto out; + + addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); + if (addr) + ret = ipvlan_rcv_frame(addr, skb, false); + +out: + return ret; +} + +static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb, + struct ipvl_port *port) +{ + struct sk_buff *skb = *pskb; + struct ethhdr *eth = eth_hdr(skb); + rx_handler_result_t ret = RX_HANDLER_PASS; + void *lyr3h; + int addr_type; + + if (is_multicast_ether_addr(eth->h_dest)) { + if (ipvlan_external_frame(skb, port)) + ipvlan_multicast_frame(port, skb, NULL, false); + } else { + struct ipvl_addr *addr; + + lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); + if (!lyr3h) + return ret; + + addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); + if (addr) + ret = ipvlan_rcv_frame(addr, skb, false); + } + + return ret; +} + +rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct ipvl_port *port = ipvlan_port_get_rcu(skb->dev); + + if (!port) + return RX_HANDLER_PASS; + + switch (port->mode) { + case IPVLAN_MODE_L2: + return ipvlan_handle_mode_l2(pskb, port); + case IPVLAN_MODE_L3: + return ipvlan_handle_mode_l3(pskb, port); + } + + /* Should not reach here */ + WARN_ONCE(true, "ipvlan_handle_frame() called for mode = [%hx]\n", + port->mode); + kfree_skb(skb); + return NET_RX_DROP; +} diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c new file mode 100644 index 000000000000..c3df84bd2857 --- /dev/null +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -0,0 +1,789 @@ +/* Copyright (c) 2014 Mahesh Bandewar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + */ + +#include "ipvlan.h" + +void ipvlan_adjust_mtu(struct ipvl_dev *ipvlan, struct net_device *dev) +{ + ipvlan->dev->mtu = dev->mtu - ipvlan->mtu_adj; +} + +void ipvlan_set_port_mode(struct ipvl_port *port, u32 nval) +{ + struct ipvl_dev *ipvlan; + + if (port->mode != nval) { + list_for_each_entry(ipvlan, &port->ipvlans, pnode) { + if (nval == IPVLAN_MODE_L3) + ipvlan->dev->flags |= IFF_NOARP; + else + ipvlan->dev->flags &= ~IFF_NOARP; + } + port->mode = nval; + } +} + +static int ipvlan_port_create(struct net_device *dev) +{ + struct ipvl_port *port; + int err, idx; + + if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK) { + netdev_err(dev, "Master is either lo or non-ether device\n"); + return -EINVAL; + } + port = kzalloc(sizeof(struct ipvl_port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + port->dev = dev; + port->mode = IPVLAN_MODE_L3; + INIT_LIST_HEAD(&port->ipvlans); + for (idx = 0; idx < IPVLAN_HASH_SIZE; idx++) + INIT_HLIST_HEAD(&port->hlhead[idx]); + + err = netdev_rx_handler_register(dev, ipvlan_handle_frame, port); + if (err) + goto err; + + dev->priv_flags |= IFF_IPVLAN_MASTER; + return 0; + +err: + kfree_rcu(port, rcu); + return err; +} + +static void ipvlan_port_destroy(struct net_device *dev) +{ + struct ipvl_port *port = ipvlan_port_get_rtnl(dev); + + dev->priv_flags &= ~IFF_IPVLAN_MASTER; + netdev_rx_handler_unregister(dev); + kfree_rcu(port, rcu); +} + +/* ipvlan network devices have devices nesting below it and are a special + * "super class" of normal network devices; split their locks off into a + * separate class since they always nest. + */ +static struct lock_class_key ipvlan_netdev_xmit_lock_key; +static struct lock_class_key ipvlan_netdev_addr_lock_key; + +#define IPVLAN_FEATURES \ + (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ + NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ + NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \ + NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER) + +#define IPVLAN_STATE_MASK \ + ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) + +static void ipvlan_set_lockdep_class_one(struct net_device *dev, + struct netdev_queue *txq, + void *_unused) +{ + lockdep_set_class(&txq->_xmit_lock, &ipvlan_netdev_xmit_lock_key); +} + +static void ipvlan_set_lockdep_class(struct net_device *dev) +{ + lockdep_set_class(&dev->addr_list_lock, &ipvlan_netdev_addr_lock_key); + netdev_for_each_tx_queue(dev, ipvlan_set_lockdep_class_one, NULL); +} + +static int ipvlan_init(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + const struct net_device *phy_dev = ipvlan->phy_dev; + + dev->state = (dev->state & ~IPVLAN_STATE_MASK) | + (phy_dev->state & IPVLAN_STATE_MASK); + dev->features = phy_dev->features & IPVLAN_FEATURES; + dev->features |= NETIF_F_LLTX; + dev->gso_max_size = phy_dev->gso_max_size; + dev->iflink = phy_dev->ifindex; + dev->hard_header_len = phy_dev->hard_header_len; + + ipvlan_set_lockdep_class(dev); + + ipvlan->pcpu_stats = alloc_percpu(struct ipvl_pcpu_stats); + if (!ipvlan->pcpu_stats) + return -ENOMEM; + + return 0; +} + +static void ipvlan_uninit(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port = ipvlan->port; + + if (ipvlan->pcpu_stats) + free_percpu(ipvlan->pcpu_stats); + + port->count -= 1; + if (!port->count) + ipvlan_port_destroy(port->dev); +} + +static int ipvlan_open(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_addr *addr; + + if (ipvlan->port->mode == IPVLAN_MODE_L3) + dev->flags |= IFF_NOARP; + else + dev->flags &= ~IFF_NOARP; + + if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { + list_for_each_entry(addr, &ipvlan->addrs, anode) + ipvlan_ht_addr_add(ipvlan, addr); + } + return dev_uc_add(phy_dev, phy_dev->dev_addr); +} + +static int ipvlan_stop(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_addr *addr; + + dev_uc_unsync(phy_dev, dev); + dev_mc_unsync(phy_dev, dev); + + dev_uc_del(phy_dev, phy_dev->dev_addr); + + if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { + list_for_each_entry(addr, &ipvlan->addrs, anode) + ipvlan_ht_addr_del(addr, !dev->dismantle); + } + return 0; +} + +netdev_tx_t ipvlan_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + int skblen = skb->len; + int ret; + + ret = ipvlan_queue_xmit(skb, dev); + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { + struct ipvl_pcpu_stats *pcptr; + + pcptr = this_cpu_ptr(ipvlan->pcpu_stats); + + u64_stats_update_begin(&pcptr->syncp); + pcptr->tx_pkts++; + pcptr->tx_bytes += skblen; + u64_stats_update_end(&pcptr->syncp); + } else { + this_cpu_inc(ipvlan->pcpu_stats->tx_drps); + } + return ret; +} + +static netdev_features_t ipvlan_fix_features(struct net_device *dev, + netdev_features_t features) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + return features & (ipvlan->sfeatures | ~IPVLAN_FEATURES); +} + +static void ipvlan_change_rx_flags(struct net_device *dev, int change) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + + if (change & IFF_ALLMULTI) + dev_set_allmulti(phy_dev, dev->flags & IFF_ALLMULTI? 1 : -1); +} + +static void ipvlan_set_broadcast_mac_filter(struct ipvl_dev *ipvlan, bool set) +{ + struct net_device *dev = ipvlan->dev; + unsigned int hashbit = ipvlan_mac_hash(dev->broadcast); + + if (set && !test_bit(hashbit, ipvlan->mac_filters)) + __set_bit(hashbit, ipvlan->mac_filters); + else if (!set && test_bit(hashbit, ipvlan->mac_filters)) + __clear_bit(hashbit, ipvlan->mac_filters); +} + +static void ipvlan_set_multicast_mac_filter(struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) { + bitmap_fill(ipvlan->mac_filters, IPVLAN_MAC_FILTER_SIZE); + } else { + struct netdev_hw_addr *ha; + DECLARE_BITMAP(mc_filters, IPVLAN_MAC_FILTER_SIZE); + + bitmap_zero(mc_filters, IPVLAN_MAC_FILTER_SIZE); + netdev_for_each_mc_addr(ha, dev) + __set_bit(ipvlan_mac_hash(ha->addr), mc_filters); + + bitmap_copy(ipvlan->mac_filters, mc_filters, + IPVLAN_MAC_FILTER_SIZE); + } + dev_uc_sync(ipvlan->phy_dev, dev); + dev_mc_sync(ipvlan->phy_dev, dev); +} + +static struct rtnl_link_stats64 *ipvlan_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *s) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + if (ipvlan->pcpu_stats) { + struct ipvl_pcpu_stats *pcptr; + u64 rx_pkts, rx_bytes, rx_mcast, tx_pkts, tx_bytes; + u32 rx_errs = 0, tx_drps = 0; + u32 strt; + int idx; + + for_each_possible_cpu(idx) { + pcptr = per_cpu_ptr(ipvlan->pcpu_stats, idx); + do { + strt= u64_stats_fetch_begin_irq(&pcptr->syncp); + rx_pkts = pcptr->rx_pkts; + rx_bytes = pcptr->rx_bytes; + rx_mcast = pcptr->rx_mcast; + tx_pkts = pcptr->tx_pkts; + tx_bytes = pcptr->tx_bytes; + } while (u64_stats_fetch_retry_irq(&pcptr->syncp, + strt)); + + s->rx_packets += rx_pkts; + s->rx_bytes += rx_bytes; + s->multicast += rx_mcast; + s->tx_packets += tx_pkts; + s->tx_bytes += tx_bytes; + + /* u32 values are updated without syncp protection. */ + rx_errs += pcptr->rx_errs; + tx_drps += pcptr->tx_drps; + } + s->rx_errors = rx_errs; + s->rx_dropped = rx_errs; + s->tx_dropped = tx_drps; + } + return s; +} + +static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + + return vlan_vid_add(phy_dev, proto, vid); +} + +static int ipvlan_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, + u16 vid) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + + vlan_vid_del(phy_dev, proto, vid); + return 0; +} + +static const struct net_device_ops ipvlan_netdev_ops = { + .ndo_init = ipvlan_init, + .ndo_uninit = ipvlan_uninit, + .ndo_open = ipvlan_open, + .ndo_stop = ipvlan_stop, + .ndo_start_xmit = ipvlan_start_xmit, + .ndo_fix_features = ipvlan_fix_features, + .ndo_change_rx_flags = ipvlan_change_rx_flags, + .ndo_set_rx_mode = ipvlan_set_multicast_mac_filter, + .ndo_get_stats64 = ipvlan_get_stats64, + .ndo_vlan_rx_add_vid = ipvlan_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = ipvlan_vlan_rx_kill_vid, +}; + +static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + struct net_device *phy_dev = ipvlan->phy_dev; + + /* TODO Probably use a different field than dev_addr so that the + * mac-address on the virtual device is portable and can be carried + * while the packets use the mac-addr on the physical device. + */ + return dev_hard_header(skb, phy_dev, type, daddr, + saddr ? : dev->dev_addr, len); +} + +static const struct header_ops ipvlan_header_ops = { + .create = ipvlan_hard_header, + .rebuild = eth_rebuild_header, + .parse = eth_header_parse, + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, +}; + +static int ipvlan_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + + return __ethtool_get_settings(ipvlan->phy_dev, cmd); +} + +static void ipvlan_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *drvinfo) +{ + strlcpy(drvinfo->driver, IPVLAN_DRV, sizeof(drvinfo->driver)); + strlcpy(drvinfo->version, IPV_DRV_VER, sizeof(drvinfo->version)); +} + +static u32 ipvlan_ethtool_get_msglevel(struct net_device *dev) +{ + const struct ipvl_dev *ipvlan = netdev_priv(dev); + + return ipvlan->msg_enable; +} + +static void ipvlan_ethtool_set_msglevel(struct net_device *dev, u32 value) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + + ipvlan->msg_enable = value; +} + +static const struct ethtool_ops ipvlan_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_settings = ipvlan_ethtool_get_settings, + .get_drvinfo = ipvlan_ethtool_get_drvinfo, + .get_msglevel = ipvlan_ethtool_get_msglevel, + .set_msglevel = ipvlan_ethtool_set_msglevel, +}; + +static int ipvlan_nl_changelink(struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port = ipvlan_port_get_rtnl(ipvlan->phy_dev); + + if (data && data[IFLA_IPVLAN_MODE]) { + u16 nmode = nla_get_u16(data[IFLA_IPVLAN_MODE]); + + ipvlan_set_port_mode(port, nmode); + } + return 0; +} + +static size_t ipvlan_nl_getsize(const struct net_device *dev) +{ + return (0 + + nla_total_size(2) /* IFLA_IPVLAN_MODE */ + ); +} + +static int ipvlan_nl_validate(struct nlattr *tb[], struct nlattr *data[]) +{ + if (data && data[IFLA_IPVLAN_MODE]) { + u16 mode = nla_get_u16(data[IFLA_IPVLAN_MODE]); + + if (mode < IPVLAN_MODE_L2 || mode >= IPVLAN_MODE_MAX) + return -EINVAL; + } + return 0; +} + +static int ipvlan_nl_fillinfo(struct sk_buff *skb, + const struct net_device *dev) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port = ipvlan_port_get_rtnl(ipvlan->phy_dev); + int ret = -EINVAL; + + if (!port) + goto err; + + ret = -EMSGSIZE; + if (nla_put_u16(skb, IFLA_IPVLAN_MODE, port->mode)) + goto err; + + return 0; + +err: + return ret; +} + +static int ipvlan_link_new(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port; + struct net_device *phy_dev; + int err; + + if (!tb[IFLA_LINK]) + return -EINVAL; + + phy_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); + if (!phy_dev) + return -ENODEV; + + if (ipvlan_dev_slave(phy_dev)) { + struct ipvl_dev *tmp = netdev_priv(phy_dev); + + phy_dev = tmp->phy_dev; + } else if (!ipvlan_dev_master(phy_dev)) { + err = ipvlan_port_create(phy_dev); + if (err < 0) + return err; + } + + port = ipvlan_port_get_rtnl(phy_dev); + if (data && data[IFLA_IPVLAN_MODE]) + port->mode = nla_get_u16(data[IFLA_IPVLAN_MODE]); + + ipvlan->phy_dev = phy_dev; + ipvlan->dev = dev; + ipvlan->port = port; + ipvlan->sfeatures = IPVLAN_FEATURES; + INIT_LIST_HEAD(&ipvlan->addrs); + ipvlan->ipv4cnt = 0; + ipvlan->ipv6cnt = 0; + + /* TODO Probably put random address here to be presented to the + * world but keep using the physical-dev address for the outgoing + * packets. + */ + memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN); + + dev->priv_flags |= IFF_IPVLAN_SLAVE; + + port->count += 1; + err = register_netdevice(dev); + if (err < 0) + goto ipvlan_destroy_port; + + err = netdev_upper_dev_link(phy_dev, dev); + if (err) + goto ipvlan_destroy_port; + + list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans); + netif_stacked_transfer_operstate(phy_dev, dev); + return 0; + +ipvlan_destroy_port: + port->count -= 1; + if (!port->count) + ipvlan_port_destroy(phy_dev); + + return err; +} + +static void ipvlan_link_delete(struct net_device *dev, struct list_head *head) +{ + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_addr *addr, *next; + + if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { + list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { + ipvlan_ht_addr_del(addr, !dev->dismantle); + list_del_rcu(&addr->anode); + } + } + list_del_rcu(&ipvlan->pnode); + unregister_netdevice_queue(dev, head); + netdev_upper_dev_unlink(ipvlan->phy_dev, dev); +} + +static void ipvlan_link_setup(struct net_device *dev) +{ + ether_setup(dev); + + dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->priv_flags |= IFF_UNICAST_FLT; + dev->netdev_ops = &ipvlan_netdev_ops; + dev->destructor = free_netdev; + dev->header_ops = &ipvlan_header_ops; + dev->ethtool_ops = &ipvlan_ethtool_ops; + dev->tx_queue_len = 0; +} + +static const struct nla_policy ipvlan_nl_policy[IFLA_IPVLAN_MAX + 1] = +{ + [IFLA_IPVLAN_MODE] = { .type = NLA_U16 }, +}; + +static struct rtnl_link_ops ipvlan_link_ops = { + .kind = "ipvlan", + .priv_size = sizeof(struct ipvl_dev), + + .get_size = ipvlan_nl_getsize, + .policy = ipvlan_nl_policy, + .validate = ipvlan_nl_validate, + .fill_info = ipvlan_nl_fillinfo, + .changelink = ipvlan_nl_changelink, + .maxtype = IFLA_IPVLAN_MAX, + + .setup = ipvlan_link_setup, + .newlink = ipvlan_link_new, + .dellink = ipvlan_link_delete, +}; + +int ipvlan_link_register(struct rtnl_link_ops *ops) +{ + return rtnl_link_register(ops); +} + +static int ipvlan_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct ipvl_dev *ipvlan, *next; + struct ipvl_port *port; + LIST_HEAD(lst_kill); + + if (!ipvlan_dev_master(dev)) + return NOTIFY_DONE; + + port = ipvlan_port_get_rtnl(dev); + + switch (event) { + case NETDEV_CHANGE: + list_for_each_entry(ipvlan, &port->ipvlans, pnode) + netif_stacked_transfer_operstate(ipvlan->phy_dev, + ipvlan->dev); + break; + + case NETDEV_UNREGISTER: + if (dev->reg_state != NETREG_UNREGISTERING) + break; + + list_for_each_entry_safe(ipvlan, next, &port->ipvlans, + pnode) + ipvlan->dev->rtnl_link_ops->dellink(ipvlan->dev, + &lst_kill); + unregister_netdevice_many(&lst_kill); + break; + + case NETDEV_FEAT_CHANGE: + list_for_each_entry(ipvlan, &port->ipvlans, pnode) { + ipvlan->dev->features = dev->features & IPVLAN_FEATURES; + ipvlan->dev->gso_max_size = dev->gso_max_size; + netdev_features_change(ipvlan->dev); + } + break; + + case NETDEV_CHANGEMTU: + list_for_each_entry(ipvlan, &port->ipvlans, pnode) + ipvlan_adjust_mtu(ipvlan, dev); + break; + + case NETDEV_PRE_TYPE_CHANGE: + /* Forbid underlying device to change its type. */ + return NOTIFY_BAD; + } + return NOTIFY_DONE; +} + +static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) +{ + struct ipvl_addr *addr; + + if (ipvlan_addr_busy(ipvlan, ip6_addr, true)) { + netif_err(ipvlan, ifup, ipvlan->dev, + "Failed to add IPv6=%pI6c addr for %s intf\n", + ip6_addr, ipvlan->dev->name); + return -EINVAL; + } + addr = kzalloc(sizeof(struct ipvl_addr), GFP_ATOMIC); + if (!addr) + return -ENOMEM; + + addr->master = ipvlan; + memcpy(&addr->ip6addr, ip6_addr, sizeof(struct in6_addr)); + addr->atype = IPVL_IPV6; + list_add_tail_rcu(&addr->anode, &ipvlan->addrs); + ipvlan->ipv6cnt++; + ipvlan_ht_addr_add(ipvlan, addr); + + return 0; +} + +static void ipvlan_del_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) +{ + struct ipvl_addr *addr; + + addr = ipvlan_ht_addr_lookup(ipvlan->port, ip6_addr, true); + if (!addr) + return; + + ipvlan_ht_addr_del(addr, true); + list_del_rcu(&addr->anode); + ipvlan->ipv6cnt--; + WARN_ON(ipvlan->ipv6cnt < 0); + kfree_rcu(addr, rcu); + + return; +} + +static int ipvlan_addr6_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct inet6_ifaddr *if6 = (struct inet6_ifaddr *)ptr; + struct net_device *dev = (struct net_device *)if6->idev->dev; + struct ipvl_dev *ipvlan = netdev_priv(dev); + + if (!ipvlan_dev_slave(dev)) + return NOTIFY_DONE; + + if (!ipvlan || !ipvlan->port) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + if (ipvlan_add_addr6(ipvlan, &if6->addr)) + return NOTIFY_BAD; + break; + + case NETDEV_DOWN: + ipvlan_del_addr6(ipvlan, &if6->addr); + break; + } + + return NOTIFY_OK; +} + +static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) +{ + struct ipvl_addr *addr; + + if (ipvlan_addr_busy(ipvlan, ip4_addr, false)) { + netif_err(ipvlan, ifup, ipvlan->dev, + "Failed to add IPv4=%pI4 on %s intf.\n", + ip4_addr, ipvlan->dev->name); + return -EINVAL; + } + addr = kzalloc(sizeof(struct ipvl_addr), GFP_KERNEL); + if (!addr) + return -ENOMEM; + + addr->master = ipvlan; + memcpy(&addr->ip4addr, ip4_addr, sizeof(struct in_addr)); + addr->atype = IPVL_IPV4; + list_add_tail_rcu(&addr->anode, &ipvlan->addrs); + ipvlan->ipv4cnt++; + ipvlan_ht_addr_add(ipvlan, addr); + ipvlan_set_broadcast_mac_filter(ipvlan, true); + + return 0; +} + +static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) +{ + struct ipvl_addr *addr; + + addr = ipvlan_ht_addr_lookup(ipvlan->port, ip4_addr, false); + if (!addr) + return; + + ipvlan_ht_addr_del(addr, true); + list_del_rcu(&addr->anode); + ipvlan->ipv4cnt--; + WARN_ON(ipvlan->ipv4cnt < 0); + if (!ipvlan->ipv4cnt) + ipvlan_set_broadcast_mac_filter(ipvlan, false); + kfree_rcu(addr, rcu); + + return; +} + +static int ipvlan_addr4_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct in_ifaddr *if4 = (struct in_ifaddr *)ptr; + struct net_device *dev = (struct net_device *)if4->ifa_dev->dev; + struct ipvl_dev *ipvlan = netdev_priv(dev); + struct in_addr ip4_addr; + + if (!ipvlan_dev_slave(dev)) + return NOTIFY_DONE; + + if (!ipvlan || !ipvlan->port) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + ip4_addr.s_addr = if4->ifa_address; + if (ipvlan_add_addr4(ipvlan, &ip4_addr)) + return NOTIFY_BAD; + break; + + case NETDEV_DOWN: + ip4_addr.s_addr = if4->ifa_address; + ipvlan_del_addr4(ipvlan, &ip4_addr); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block ipvlan_addr4_notifier_block __read_mostly = { + .notifier_call = ipvlan_addr4_event, +}; + +static struct notifier_block ipvlan_notifier_block __read_mostly = { + .notifier_call = ipvlan_device_event, +}; + +static struct notifier_block ipvlan_addr6_notifier_block __read_mostly = { + .notifier_call = ipvlan_addr6_event, +}; + +static int __init ipvlan_init_module(void) +{ + int err; + + ipvlan_init_secret(); + register_netdevice_notifier(&ipvlan_notifier_block); + register_inet6addr_notifier(&ipvlan_addr6_notifier_block); + register_inetaddr_notifier(&ipvlan_addr4_notifier_block); + + err = ipvlan_link_register(&ipvlan_link_ops); + if (err < 0) + goto error; + + return 0; +error: + unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); + unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); + unregister_netdevice_notifier(&ipvlan_notifier_block); + return err; +} + +static void __exit ipvlan_cleanup_module(void) +{ + rtnl_link_unregister(&ipvlan_link_ops); + unregister_netdevice_notifier(&ipvlan_notifier_block); + unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); + unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); +} + +module_init(ipvlan_init_module); +module_exit(ipvlan_cleanup_module); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mahesh Bandewar "); +MODULE_DESCRIPTION("Driver for L3 (IPv6/IPv4) based VLANs"); +MODULE_ALIAS_RTNL_LINK("ipvlan"); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5cd508787572..2cb772495f7a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1230,6 +1230,8 @@ enum netdev_priv_flags { IFF_LIVE_ADDR_CHANGE = 1<<20, IFF_MACVLAN = 1<<21, IFF_XMIT_DST_RELEASE_PERM = 1<<22, + IFF_IPVLAN_MASTER = 1<<23, + IFF_IPVLAN_SLAVE = 1<<24, }; #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN @@ -1255,6 +1257,8 @@ enum netdev_priv_flags { #define IFF_LIVE_ADDR_CHANGE IFF_LIVE_ADDR_CHANGE #define IFF_MACVLAN IFF_MACVLAN #define IFF_XMIT_DST_RELEASE_PERM IFF_XMIT_DST_RELEASE_PERM +#define IFF_IPVLAN_MASTER IFF_IPVLAN_MASTER +#define IFF_IPVLAN_SLAVE IFF_IPVLAN_SLAVE /** * struct net_device - The DEVICE structure. diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 7072d8325016..36bddc233633 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -330,6 +330,21 @@ enum macvlan_macaddr_mode { #define MACVLAN_FLAG_NOPROMISC 1 +/* IPVLAN section */ +enum { + IFLA_IPVLAN_UNSPEC, + IFLA_IPVLAN_MODE, + __IFLA_IPVLAN_MAX +}; + +#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) + +enum ipvlan_mode { + IPVLAN_MODE_L2 = 0, + IPVLAN_MODE_L3, + IPVLAN_MODE_MAX +}; + /* VXLAN section */ enum { IFLA_VXLAN_UNSPEC, -- GitLab From e920f9b632a687834de5a78c60ac5c4c62327b1d Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 4 Nov 2014 13:00:38 -0300 Subject: [PATCH 6283/9457] thermal: armada: Remove support for A375-Z1 SoC The Armada 375 Z1 SoC revision is no longer supported. This commit removes the quirk needed for the thermal sensor. Acked-by: Jason Cooper Signed-off-by: Ezequiel Garcia Signed-off-by: Eduardo Valentin --- .../bindings/thermal/armada-thermal.txt | 8 -------- drivers/thermal/armada_thermal.c | 20 ------------------- 2 files changed, 28 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index 4cf024929a3f..4698e0edc205 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt @@ -5,17 +5,9 @@ Required properties: - compatible: Should be set to one of the following: marvell,armada370-thermal marvell,armada375-thermal - marvell,armada375-z1-thermal marvell,armada380-thermal marvell,armadaxp-thermal - Note: As the name suggests, "marvell,armada375-z1-thermal" - applies for the SoC Z1 stepping only. On such stepping - some quirks need to be done and the register offset differs - from the one in the A0 stepping. - The operating system may auto-detect the SoC stepping and - update the compatible and register offsets at runtime. - - reg: Device's register space. Two entries are expected, see the examples below. The first one is required for the sensor register; diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c index 9d1420acb391..9c8e7834e4ae 100644 --- a/drivers/thermal/armada_thermal.c +++ b/drivers/thermal/armada_thermal.c @@ -35,10 +35,6 @@ #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) #define PMU_TDC0_START_CAL_MASK (0x1 << 25) -#define A375_Z1_CAL_RESET_LSB 0x8011e214 -#define A375_Z1_CAL_RESET_MSB 0x30a88019 -#define A375_Z1_WORKAROUND_BIT BIT(9) - #define A375_UNIT_CONTROL_SHIFT 27 #define A375_UNIT_CONTROL_MASK 0x7 #define A375_READOUT_INVERT BIT(15) @@ -124,24 +120,12 @@ static void armada375_init_sensor(struct platform_device *pdev, struct armada_thermal_priv *priv) { unsigned long reg; - bool quirk_needed = - !!of_device_is_compatible(pdev->dev.of_node, - "marvell,armada375-z1-thermal"); - - if (quirk_needed) { - /* Ensure these registers have the default (reset) values */ - writel(A375_Z1_CAL_RESET_LSB, priv->control); - writel(A375_Z1_CAL_RESET_MSB, priv->control + 0x4); - } reg = readl(priv->control + 4); reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT); reg &= ~A375_READOUT_INVERT; reg &= ~A375_HW_RESETn; - if (quirk_needed) - reg |= A375_Z1_WORKAROUND_BIT; - writel(reg, priv->control + 4); mdelay(20); @@ -259,10 +243,6 @@ static const struct of_device_id armada_thermal_id_table[] = { .compatible = "marvell,armada375-thermal", .data = &armada375_data, }, - { - .compatible = "marvell,armada375-z1-thermal", - .data = &armada375_data, - }, { .compatible = "marvell,armada380-thermal", .data = &armada380_data, -- GitLab From 7426977c8efeaedf0a7ca00e1c1a5f52ef6b950f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Oct 2014 15:18:24 -0200 Subject: [PATCH 6284/9457] bugon.cocci: fix Options at the macro The comma after --no-includes makes coccinelle to not run the script: /usr/bin/spatch -D report --very-quiet --no-show-diff --cocci-file ./scripts/coccinelle/misc/bugon.cocci --no-includes, --include-headers --patch . --dir drivers/media/platform/coda/ -I ./arch/x86/include -I arch/x86/include/generated -I include -I ./arch/x86/include/uapi -I arch/x86/include/generated/uapi -I ./include/uapi -I include/generated/uapi -I ./include/linux/kconfig.h Usage: spatch.opt --sp-file [-o ] [--iso-file ] [options] Options are: --sp-file the semantic patch file -o the output file --in-place do the modification on the file directly --backup-suffix suffix to use when making a backup for inplace ... At least with Fedora 20 coccinelle package: coccinelle-1.0.0-0.rc20.1.fc21.x86_64 Signed-off-by: Mauro Carvalho Chehab Acked-by: Julia Lawall Tested-by: Wolfram Sang Fixes: 5be1df66 (Coccinelle: Script to replace if and BUG with BUG_ON) Cc: stable@vger.kernel.org Signed-off-by: Michal Marek --- scripts/coccinelle/misc/bugon.cocci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/coccinelle/misc/bugon.cocci b/scripts/coccinelle/misc/bugon.cocci index 556456ca761c..3b7eec24fb5a 100644 --- a/scripts/coccinelle/misc/bugon.cocci +++ b/scripts/coccinelle/misc/bugon.cocci @@ -8,7 +8,7 @@ // Confidence: High // Copyright: (C) 2014 Himangi Saraogi. GPLv2. // Comments: -// Options: --no-includes, --include-headers +// Options: --no-includes --include-headers virtual patch virtual context -- GitLab From d8182804cfd6503e73dc1c0a409903412a389541 Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 24 Nov 2014 11:10:29 +0100 Subject: [PATCH 6285/9457] tipc: fix sparse warnings in new nl api Fix sparse warnings about non-static declaration of static functions in the new tipc netlink API. Signed-off-by: Richard Alpe Signed-off-by: David S. Miller --- net/tipc/bcast.c | 3 ++- net/tipc/bearer.c | 6 ++++-- net/tipc/link.c | 10 ++++++---- net/tipc/name_table.c | 13 +++++++------ net/tipc/node.c | 2 +- net/tipc/socket.c | 16 +++++++++------- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index dcf3589e3cc5..556b26ad4b1e 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -767,7 +767,8 @@ void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action) tipc_bclink_unlock(); } -int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, struct tipc_stats *stats) +static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, + struct tipc_stats *stats) { int i; struct nlattr *nest; diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 5f6f32369c16..463db5b15b8b 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -647,7 +647,8 @@ void tipc_bearer_stop(void) } /* Caller should hold rtnl_lock to protect the bearer */ -int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, struct tipc_bearer *bearer) +static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, + struct tipc_bearer *bearer) { void *hdr; struct nlattr *attrs; @@ -905,7 +906,8 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) return 0; } -int __tipc_nl_add_media(struct tipc_nl_msg *msg, struct tipc_media *media) +static int __tipc_nl_add_media(struct tipc_nl_msg *msg, + struct tipc_media *media) { void *hdr; struct nlattr *attrs; diff --git a/net/tipc/link.c b/net/tipc/link.c index 629e8cf393bf..4738cb1bf7c0 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2514,7 +2514,8 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) return res; } -int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) + +static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) { int i; struct nlattr *stats; @@ -2580,7 +2581,7 @@ int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) } /* Caller should hold appropriate locks to protect the link */ -int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link) +static int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link) { int err; void *hdr; @@ -2649,8 +2650,9 @@ int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link) } /* Caller should hold node lock */ -int __tipc_nl_add_node_links(struct tipc_nl_msg *msg, struct tipc_node *node, - u32 *prev_link) +static int __tipc_nl_add_node_links(struct tipc_nl_msg *msg, + struct tipc_node *node, + u32 *prev_link) { u32 i; int err; diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 30ca8e0e0f84..7cfb7a4aa58f 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -1002,8 +1002,9 @@ void tipc_nametbl_stop(void) write_unlock_bh(&tipc_nametbl_lock); } -int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, struct name_seq *seq, - struct sub_seq *sseq, u32 *last_publ) +static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, + struct name_seq *seq, + struct sub_seq *sseq, u32 *last_publ) { void *hdr; struct nlattr *attrs; @@ -1071,8 +1072,8 @@ int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, struct name_seq *seq, return -EMSGSIZE; } -int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, - u32 *last_lower, u32 *last_publ) +static int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, + u32 *last_lower, u32 *last_publ) { struct sub_seq *sseq; struct sub_seq *sseq_start; @@ -1098,8 +1099,8 @@ int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, return 0; } -int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, u32 *last_lower, - u32 *last_publ) +static int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, + u32 *last_lower, u32 *last_publ) { struct hlist_head *seq_head; struct name_seq *seq; diff --git a/net/tipc/node.c b/net/tipc/node.c index 72a75d4838b2..82e5edddc376 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -609,7 +609,7 @@ void tipc_node_unlock(struct tipc_node *node) } /* Caller should hold node lock for the passed node */ -int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) +static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) { void *hdr; struct nlattr *attrs; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e91809182c28..6aa8c6a1ab10 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2811,7 +2811,7 @@ void tipc_socket_stop(void) } /* Caller should hold socket lock for the passed tipc socket. */ -int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk) +static int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk) { u32 peer_node; u32 peer_port; @@ -2846,8 +2846,8 @@ int __tipc_nl_add_sk_con(struct sk_buff *skb, struct tipc_sock *tsk) } /* Caller should hold socket lock for the passed tipc socket. */ -int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, - struct tipc_sock *tsk) +static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb, + struct tipc_sock *tsk) { int err; void *hdr; @@ -2912,8 +2912,9 @@ int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb) } /* Caller should hold socket lock for the passed tipc socket. */ -int __tipc_nl_add_sk_publ(struct sk_buff *skb, struct netlink_callback *cb, - struct publication *publ) +static int __tipc_nl_add_sk_publ(struct sk_buff *skb, + struct netlink_callback *cb, + struct publication *publ) { void *hdr; struct nlattr *attrs; @@ -2950,8 +2951,9 @@ int __tipc_nl_add_sk_publ(struct sk_buff *skb, struct netlink_callback *cb, } /* Caller should hold socket lock for the passed tipc socket. */ -int __tipc_nl_list_sk_publ(struct sk_buff *skb, struct netlink_callback *cb, - struct tipc_sock *tsk, u32 *last_publ) +static int __tipc_nl_list_sk_publ(struct sk_buff *skb, + struct netlink_callback *cb, + struct tipc_sock *tsk, u32 *last_publ) { int err; struct publication *p; -- GitLab From 08dcf9fd194cf19d3b282a81cc3539202e768ca4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 24 Nov 2014 11:30:26 +0100 Subject: [PATCH 6286/9457] tc_vlan: fix type of tcfv_push_vid Should be u16. So fix it to kill the sparse warning. Fixes: c7e2b9689ef8136 "sched: introduce vlan action" Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/tc_act/tc_vlan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h index c809c1d2cea5..93b70ade1ff3 100644 --- a/include/net/tc_act/tc_vlan.h +++ b/include/net/tc_act/tc_vlan.h @@ -18,7 +18,7 @@ struct tcf_vlan { struct tcf_common common; int tcfv_action; - __be16 tcfv_push_vid; + u16 tcfv_push_vid; __be16 tcfv_push_proto; }; #define to_vlan(a) \ -- GitLab From 3e7b2ec4fe8ef4b05b33db3e84d1b1fbccde250e Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Mon, 24 Nov 2014 12:37:58 +0100 Subject: [PATCH 6287/9457] rhashtable: Check for count mismatch while iterating in selftest Verify whether both the lock and RCU protected iterators see all test entries before and after expanding and shrinking has been performed. Also verify whether the number of entries in the hashtable remains stable during expansion and shrinking. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- lib/rhashtable.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/rhashtable.c b/lib/rhashtable.c index e5f5e69c7a7b..c7e987ab3361 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -653,15 +653,15 @@ static int __init test_rht_lookup(struct rhashtable *ht) return 0; } -static void test_bucket_stats(struct rhashtable *ht, - struct bucket_table *tbl, - bool quiet) +static void test_bucket_stats(struct rhashtable *ht, bool quiet) { - unsigned int cnt, i, total = 0; + unsigned int cnt, rcu_cnt, i, total = 0; struct test_obj *obj; + struct bucket_table *tbl; + tbl = rht_dereference_rcu(ht->tbl, ht); for (i = 0; i < tbl->size; i++) { - cnt = 0; + rcu_cnt = cnt = 0; if (!quiet) pr_info(" [%#4x/%zu]", i, tbl->size); @@ -673,6 +673,13 @@ static void test_bucket_stats(struct rhashtable *ht, pr_cont(" [%p],", obj); } + rht_for_each_entry_rcu(obj, tbl->buckets[i], node) + rcu_cnt++; + + if (rcu_cnt != cnt) + pr_warn("Test failed: Chain count mismach %d != %d", + cnt, rcu_cnt); + if (!quiet) pr_cont("\n [%#x] first element: %p, chain length: %u\n", i, tbl->buckets[i], cnt); @@ -680,6 +687,9 @@ static void test_bucket_stats(struct rhashtable *ht, pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", total, ht->nelems, TEST_ENTRIES); + + if (total != ht->nelems || total != TEST_ENTRIES) + pr_warn("Test failed: Total count mismatch ^^^"); } static int __init test_rhashtable(struct rhashtable *ht) @@ -710,8 +720,7 @@ static int __init test_rhashtable(struct rhashtable *ht) } rcu_read_lock(); - tbl = rht_dereference_rcu(ht->tbl, ht); - test_bucket_stats(ht, tbl, true); + test_bucket_stats(ht, true); test_rht_lookup(ht); rcu_read_unlock(); @@ -735,6 +744,10 @@ static int __init test_rhashtable(struct rhashtable *ht) rcu_read_unlock(); } + rcu_read_lock(); + test_bucket_stats(ht, true); + rcu_read_unlock(); + pr_info(" Deleting %d keys\n", TEST_ENTRIES); for (i = 0; i < TEST_ENTRIES; i++) { u32 key = i * 2; -- GitLab From 4f0372150b1fbf2167cfe21d2e6eac1933fb36ac Mon Sep 17 00:00:00 2001 From: Richard Alpe Date: Mon, 24 Nov 2014 14:24:54 +0100 Subject: [PATCH 6288/9457] tipc: add tipc_netlink.h to uapi Kbuild tipc_netlink.h is the user-space header for the new netlink api. It was accidentally left out of the uapi Kbuild list when the api was added. Signed-off-by: Richard Alpe Signed-off-by: David S. Miller --- include/uapi/linux/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 72298b6887ac..a1e8175cc488 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -389,6 +389,7 @@ header-y += times.h header-y += timex.h header-y += tiocl.h header-y += tipc_config.h +header-y += tipc_netlink.h header-y += tipc.h header-y += toshiba.h header-y += tty_flags.h -- GitLab From 3a611e26e958b0372d2e7600b87bbb4a84c7704b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 24 Nov 2014 19:58:17 +0100 Subject: [PATCH 6289/9457] net/smsc911x: Add minimal runtime PM support Add minimal runtime PM support (enable on probe, disable on remove), to ensure proper operation with a parent device that uses runtime PM. This is needed on systems where the external bus controller module of the SoC is contained in a PM domain and/or has a gateable functional clock. In such cases, before accessing any device connected to the external bus, the PM domain must be powered up, and/or the functional clock must be enabled, which is typically handled through runtime PM by the bus controller driver. An example of this is the kzm9g development board, where an smsc9220 Ethernet controller is connected to the Bus State Controller (BSC) of a Renesas sh73a0 SoC. Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 77ed74561e5f..f9c87624a0af 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -59,6 +59,8 @@ #include #include #include +#include + #include "smsc911x.h" #define SMSC_CHIPNAME "smsc911x" @@ -2338,6 +2340,9 @@ static int smsc911x_drv_remove(struct platform_device *pdev) free_netdev(dev); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return 0; } @@ -2491,6 +2496,9 @@ static int smsc911x_drv_probe(struct platform_device *pdev) if (pdata->config.shift) pdata->ops = &shifted_smsc911x_ops; + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + retval = smsc911x_init(dev); if (retval < 0) goto out_disable_resources; @@ -2572,6 +2580,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev) out_free_irq: free_irq(dev->irq, dev); out_disable_resources: + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); (void)smsc911x_disable_resources(pdev); out_enable_resources_fail: smsc911x_free_resources(pdev); -- GitLab From f98614072c5d43421a2cfa6f9b911a071e6e6d5f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 24 Nov 2014 22:45:05 +0100 Subject: [PATCH 6290/9457] PCMCIA: Alchemy Don't select 64BIT_PHYS_ADDR in Kconfig. For Alchemy 64BIT_PHYS_ADDR is already always set in arch/mips/Kconfig. Also 64BIT_PHYS_ADDR is about to be removed. Signed-off-by: Ralf Baechle --- drivers/pcmcia/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index b0ce7cdee0c2..910e90bf16c6 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -147,7 +147,6 @@ config TCIC config PCMCIA_ALCHEMY_DEVBOARD tristate "Alchemy Db/Pb1xxx PCMCIA socket services" depends on MIPS_ALCHEMY && PCMCIA - select 64BIT_PHYS_ADDR help Enable this driver of you want PCMCIA support on your Alchemy Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 @@ -158,7 +157,6 @@ config PCMCIA_ALCHEMY_DEVBOARD config PCMCIA_XXS1500 tristate "MyCable XXS1500 PCMCIA socket support" depends on PCMCIA && MIPS_XXS1500 - select 64BIT_PHYS_ADDR help Support for the PCMCIA/CF socket interface on MyCable XXS1500 systems. -- GitLab From 34adb28d500e644cc260da4ceb66ba6dc0beaf93 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 22 Nov 2014 00:16:48 +0100 Subject: [PATCH 6291/9457] MIPS: Replace MIPS-specific 64BIT_PHYS_ADDR with generic PHYS_ADDR_T_64BIT Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 15 ++++++--------- arch/mips/alchemy/common/setup.c | 2 +- arch/mips/include/asm/mach-au1x00/ioremap.h | 2 +- arch/mips/include/asm/page.h | 2 +- arch/mips/include/asm/pgtable-32.h | 14 +++++++------- arch/mips/include/asm/pgtable-bits.h | 4 ++-- arch/mips/include/asm/pgtable.h | 8 ++++---- arch/mips/include/asm/types.h | 2 +- arch/mips/mm/gup.c | 2 +- arch/mips/mm/init.c | 2 +- arch/mips/mm/tlb-r4k.c | 2 +- arch/mips/mm/tlbex.c | 18 +++++++++--------- arch/mips/sibyte/common/cfe.c | 4 ++-- drivers/dma/txx9dmac.c | 2 +- drivers/dma/txx9dmac.h | 4 ++-- 15 files changed, 40 insertions(+), 43 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d9393963e6d6..0a8e88d06b99 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -63,7 +63,7 @@ choice config MIPS_ALCHEMY bool "Alchemy processor based machines" - select 64BIT_PHYS_ADDR + select ARCH_PHYS_ADDR_T_64BIT select CEVT_R4K select CSRC_R4K select IRQ_CPU @@ -771,7 +771,7 @@ config MIKROTIK_RB532 config CAVIUM_OCTEON_SOC bool "Cavium Networks Octeon SoC based boards" select CEVT_R4K - select 64BIT_PHYS_ADDR + select ARCH_PHYS_ADDR_T_64BIT select DMA_COHERENT select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -813,7 +813,7 @@ config NLM_XLR_BOARD select SWAP_IO_SPACE select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL - select 64BIT_PHYS_ADDR + select ARCH_PHYS_ADDR_T_64BIT select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM select DMA_COHERENT @@ -839,7 +839,7 @@ config NLM_XLP_BOARD select HW_HAS_PCI select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL - select 64BIT_PHYS_ADDR + select ARCH_PHYS_ADDR_T_64BIT select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM @@ -979,7 +979,7 @@ config FW_CFE bool config ARCH_DMA_ADDR_T_64BIT - def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT + def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT config DMA_MAYBE_COHERENT select DMA_NONCOHERENT @@ -2124,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS default y -config 64BIT_PHYS_ADDR - bool - config ARCH_PHYS_ADDR_T_64BIT - def_bool 64BIT_PHYS_ADDR + bool config CPU_HAS_SMARTMIPS depends on SYS_SUPPORTS_SMARTMIPS diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index ea8f41869e56..a97707e1b4ab 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -70,7 +70,7 @@ void __init plat_mem_setup(void) iomem_resource.end = IOMEM_RESOURCE_END; } -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) /* This routine should be valid for all Au1x based boards */ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) { diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h index 75a94ad3ac91..c63c81bc4bcc 100644 --- a/arch/mips/include/asm/mach-au1x00/ioremap.h +++ b/arch/mips/include/asm/mach-au1x00/ioremap.h @@ -11,7 +11,7 @@ #include -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) extern phys_t __fixup_bigphys_addr(phys_t, phys_t); #else static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 3be81803595d..154b70a10483 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -116,7 +116,7 @@ extern void copy_user_highpage(struct page *to, struct page *from, /* * These are used to make use of C type-checking.. */ -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT #ifdef CONFIG_CPU_MIPS32 typedef struct { unsigned long pte_low, pte_high; } pte_t; #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index cd7d6064bcbe..3021a9459f7f 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h @@ -69,7 +69,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) #endif -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT #define pte_ERROR(e) \ printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) #else @@ -103,7 +103,7 @@ static inline void pmd_clear(pmd_t *pmdp) pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); } -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) #define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) static inline pte_t @@ -126,7 +126,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) #endif -#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ +#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ #define __pgd_offset(address) pgd_index(address) #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) @@ -177,7 +177,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #else /* Swap entries must have VALID and GLOBAL bits cleared. */ -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) #define __swp_type(x) (((x).val >> 2) & 0x1f) #define __swp_offset(x) ((x).val >> 7) #define __swp_entry(type,offset) \ @@ -187,9 +187,9 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #define __swp_offset(x) ((x).val >> 13) #define __swp_entry(type,offset) \ ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) -#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ +#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) /* * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... */ @@ -216,7 +216,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #endif -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) #else diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index e747bfa0be7e..29ba35954e2e 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -32,7 +32,7 @@ * unpredictable things. The code (when it is written) to deal with * this problem will be in the update_mmu_cache() code for the r4k. */ -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) /* * The following bits are directly used by the TLB hardware @@ -172,7 +172,7 @@ #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) -#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ +#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ #ifndef _PFN_SHIFT #define _PFN_SHIFT PAGE_SHIFT diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index d6d1928539b1..1ccc573e4983 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -125,7 +125,7 @@ do { \ extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) @@ -227,7 +227,7 @@ extern pgd_t swapper_pg_dir[]; * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } @@ -382,7 +382,7 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) */ #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte.pte_low &= _PAGE_CHG_MASK; @@ -419,7 +419,7 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, #define kern_addr_valid(addr) (1) -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); static inline int io_remap_pfn_range(struct vm_area_struct *vma, diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index 247207b9292d..f1fb285d211c 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h @@ -22,7 +22,7 @@ /* * Don't use phys_t. You've been warned. */ -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT typedef unsigned long long phys_t; #else typedef unsigned long phys_t; diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 06ce17c2a905..7cba480568c8 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -17,7 +17,7 @@ static inline pte_t gup_get_pte(pte_t *ptep) { -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) pte_t pte; retry: diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index f42e35e42790..448cde372af0 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -95,7 +95,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) idx += in_interrupt() ? FIX_N_COLOURS : 0; vaddr = __fix_to_virt(FIX_CMAP_END - idx); pte = mk_pte(page, prot); -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) entrylo = pte.pte_high; #else entrylo = pte_to_entrylo(pte_val(pte)); diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c3917e251f59..e90b2e899291 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -332,7 +332,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) { ptep = pte_offset_map(pmdp, address); -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) write_c0_entrylo0(ptep->pte_high); ptep++; write_c0_entrylo1(ptep->pte_high); diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index b5f228e7eae6..7994368f96c4 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -637,7 +637,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, if (cpu_has_rixi) { UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); } else { -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); #else UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); @@ -1009,7 +1009,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) * 64bit address support (36bit on a 32bit CPU) in a 32bit * Kernel is a special case. Only a few CPUs use it. */ -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT if (cpu_has_64bits) { uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ @@ -1510,14 +1510,14 @@ static void iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) { #ifdef CONFIG_SMP -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (cpu_has_64bits) uasm_i_lld(p, pte, 0, ptr); else # endif UASM_i_LL(p, pte, 0, ptr); #else -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (cpu_has_64bits) uasm_i_ld(p, pte, 0, ptr); else @@ -1530,13 +1530,13 @@ static void iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, unsigned int mode) { -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); #endif uasm_i_ori(p, pte, pte, mode); #ifdef CONFIG_SMP -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (cpu_has_64bits) uasm_i_scd(p, pte, 0, ptr); else @@ -1548,7 +1548,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, else uasm_il_beqz(p, r, pte, label_smp_pgtable_change); -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (!cpu_has_64bits) { /* no uasm_i_nop needed */ uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); @@ -1563,14 +1563,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, uasm_i_nop(p); # endif #else -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (cpu_has_64bits) uasm_i_sd(p, pte, 0, ptr); else # endif UASM_i_SW(p, pte, 0, ptr); -# ifdef CONFIG_64BIT_PHYS_ADDR +# ifdef CONFIG_PHYS_ADDR_T_64BIT if (!cpu_has_64bits) { uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); uasm_i_ori(p, pte, pte, hwmode); diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index 588e1806a1a3..d3eea3c1b18c 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -38,7 +38,7 @@ #define MAX_RAM_SIZE (~0ULL) #else #ifdef CONFIG_HIGHMEM -#ifdef CONFIG_64BIT_PHYS_ADDR +#ifdef CONFIG_PHYS_ADDR_T_64BIT #define MAX_RAM_SIZE (~0ULL) #else #define MAX_RAM_SIZE (0xffffffffULL) @@ -96,7 +96,7 @@ static void __noreturn cfe_linux_halt(void) static __init void prom_meminit(void) { - u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ + u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */ int mem_flags = 0; unsigned int idx; int rd_flag; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 17686caf64d5..0659ec9c4488 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -76,7 +76,7 @@ static void channel64_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val) static void channel64_clear_CHAR(const struct txx9dmac_chan *dc) { -#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) +#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) channel64_writel(dc, CHAR, 0); channel64_writel(dc, __pad_CHAR, 0); #else diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h index f5a760598882..f6517b928bab 100644 --- a/drivers/dma/txx9dmac.h +++ b/drivers/dma/txx9dmac.h @@ -67,7 +67,7 @@ static inline bool txx9_dma_have_SMPCHN(void) /* Hardware register definitions. */ struct txx9dmac_cregs { -#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) +#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) TXX9_DMA_REG32(CHAR); /* Chain Address Register */ #else u64 CHAR; /* Chain Address Register */ @@ -201,7 +201,7 @@ static inline bool is_dmac64(const struct txx9dmac_chan *dc) #ifdef TXX9_DMA_USE_SIMPLE_CHAIN /* Hardware descriptor definition. (for simple-chain) */ struct txx9dmac_hwdesc { -#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) +#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) TXX9_DMA_REG32(CHAR); #else u64 CHAR; -- GitLab From 15d45cce3a0e0716fa49c768f887c6406dfb91f7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 22 Nov 2014 00:22:09 +0100 Subject: [PATCH 6292/9457] MIPS: Replace use of phys_t with phys_addr_t. Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/setup.c | 4 ++-- arch/mips/cavium-octeon/dma-octeon.c | 4 ++-- arch/mips/include/asm/bootinfo.h | 8 ++++---- arch/mips/include/asm/io.h | 8 ++++---- arch/mips/include/asm/mach-au1x00/ioremap.h | 8 ++++---- arch/mips/include/asm/mach-bcm63xx/ioremap.h | 6 +++--- arch/mips/include/asm/mach-generic/ioremap.h | 4 ++-- arch/mips/include/asm/mach-tx39xx/ioremap.h | 4 ++-- arch/mips/include/asm/mach-tx49xx/ioremap.h | 4 ++-- arch/mips/include/asm/mips-cm.h | 2 +- arch/mips/include/asm/mips-cpc.h | 4 ++-- arch/mips/include/asm/pci.h | 2 +- arch/mips/include/asm/pgtable.h | 2 +- arch/mips/include/asm/types.h | 6 +++--- arch/mips/jz4740/setup.c | 2 +- arch/mips/kernel/mips-cm.c | 12 ++++++------ arch/mips/kernel/mips-cpc.c | 4 ++-- arch/mips/kernel/setup.c | 10 +++++----- arch/mips/mm/ioremap.c | 18 +++++++++--------- arch/mips/mti-malta/malta-init.c | 2 +- arch/mips/rb532/prom.c | 8 ++++---- arch/mips/sibyte/common/cfe.c | 4 ++-- arch/mips/sibyte/swarm/platform.c | 2 +- 23 files changed, 64 insertions(+), 64 deletions(-) diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index a97707e1b4ab..4e72daf12c32 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -72,7 +72,7 @@ void __init plat_mem_setup(void) #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) /* This routine should be valid for all Au1x based boards */ -phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) +phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { unsigned long start = ALCHEMY_PCI_MEMWIN_START; unsigned long end = ALCHEMY_PCI_MEMWIN_END; @@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) /* Check for PCI memory window */ if (phys_addr >= start && (phys_addr + size - 1) <= end) - return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); + return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); /* default nop */ return phys_addr; diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 02f244475207..3778655c4a37 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -262,8 +262,8 @@ char *octeon_swiotlb; void __init plat_swiotlb_setup(void) { int i; - phys_t max_addr; - phys_t addr_size; + phys_addr_t max_addr; + phys_addr_t addr_size; size_t swiotlbsize; unsigned long swiotlb_nslabs; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 8b2eaa155d18..b603804caac5 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -98,16 +98,16 @@ extern unsigned long mips_machtype; struct boot_mem_map { int nr_map; struct boot_mem_map_entry { - phys_t addr; /* start of memory segment */ - phys_t size; /* size of memory segment */ + phys_addr_t addr; /* start of memory segment */ + phys_addr_t size; /* size of memory segment */ long type; /* type of memory segment */ } map[BOOT_MEM_MAP_MAX]; }; extern struct boot_mem_map boot_mem_map; -extern void add_memory_region(phys_t start, phys_t size, long type); -extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); +extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); +extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); extern void prom_init(void); extern void prom_free_prom_memory(void); diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 933b50e125a0..9e777cd42b67 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address) */ #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) -extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); +extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags); extern void __iounmap(const volatile void __iomem *addr); #ifndef CONFIG_PCI @@ -175,7 +175,7 @@ struct pci_dev; static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} #endif -static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, +static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size, unsigned long flags) { void __iomem *addr = plat_ioremap(offset, size, flags); @@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, if (addr) return addr; -#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) +#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) if (cpu_has_64bit_addresses) { u64 base = UNCAC_BASE; @@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, return (void __iomem *) (unsigned long) (base + offset); } else if (__builtin_constant_p(offset) && __builtin_constant_p(size) && __builtin_constant_p(flags)) { - phys_t phys_addr, last_addr; + phys_addr_t phys_addr, last_addr; phys_addr = fixup_bigphys_addr(offset, size); diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h index c63c81bc4bcc..99fea1fbb4f5 100644 --- a/arch/mips/include/asm/mach-au1x00/ioremap.h +++ b/arch/mips/include/asm/mach-au1x00/ioremap.h @@ -12,9 +12,9 @@ #include #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) -extern phys_t __fixup_bigphys_addr(phys_t, phys_t); +extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t); #else -static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return phys_addr; } @@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) /* * Allow physical addresses to be fixed up to help 36-bit peripherals. */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return __fixup_bigphys_addr(phys_addr, size); } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, unsigned long flags) { return NULL; diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index ff15e3b14e7a..aea6e64b828f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h @@ -3,12 +3,12 @@ #include -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return phys_addr; } -static inline int is_bcm63xx_internal_registers(phys_t offset) +static inline int is_bcm63xx_internal_registers(phys_addr_t offset) { switch (bcm63xx_get_cpu_id()) { case BCM3368_CPU_ID: @@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset) return 0; } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, unsigned long flags) { if (is_bcm63xx_internal_registers(offset)) diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h index b379938d47f0..513371f7c39c 100644 --- a/arch/mips/include/asm/mach-generic/ioremap.h +++ b/arch/mips/include/asm/mach-generic/ioremap.h @@ -15,12 +15,12 @@ * Allow physical addresses to be fixed up to help peripherals located * outside the low 32-bit range -- generic pass-through version. */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return phys_addr; } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, unsigned long flags) { return NULL; diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h index 93c6c04ffda3..0874cd2b06d7 100644 --- a/arch/mips/include/asm/mach-tx39xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h @@ -15,12 +15,12 @@ * Allow physical addresses to be fixed up to help peripherals located * outside the low 32-bit range -- generic pass-through version. */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return phys_addr; } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, unsigned long flags) { #define TXX9_DIRECTMAP_BASE 0xff000000ul diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h index 1e7beae72229..4b6a8441b25f 100644 --- a/arch/mips/include/asm/mach-tx49xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h @@ -15,12 +15,12 @@ * Allow physical addresses to be fixed up to help peripherals located * outside the low 32-bit range -- generic pass-through version. */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) { return phys_addr; } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, unsigned long flags) { #ifdef CONFIG_64BIT diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 6a9d2dd005ca..b95a827d763e 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -30,7 +30,7 @@ extern void __iomem *mips_cm_l2sync_base; * different way by defining a function with the same prototype except for the * name mips_cm_phys_base (without underscores). */ -extern phys_t __mips_cm_phys_base(void); +extern phys_addr_t __mips_cm_phys_base(void); /** * mips_cm_probe - probe for a Coherence Manager diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index e139a534e0fd..1cebe8c79051 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h @@ -25,7 +25,7 @@ extern void __iomem *mips_cpc_base; * memory mapped registers. This is platform dependant & must therefore be * implemented per-platform. */ -extern phys_t mips_cpc_default_phys_base(void); +extern phys_addr_t mips_cpc_default_phys_base(void); /** * mips_cpc_phys_base - retrieve the physical base address of the CPC @@ -35,7 +35,7 @@ extern phys_t mips_cpc_default_phys_base(void); * is present. It may be overriden by individual platforms which determine * this address in a different way. */ -extern phys_t __weak mips_cpc_phys_base(void); +extern phys_addr_t __weak mips_cpc_phys_base(void); /** * mips_cpc_probe - probe for a Cluster Power Controller diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 974b0e308963..69529624a005 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -84,7 +84,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, resource_size_t *start, resource_size_t *end) { - phys_t size = resource_size(rsrc); + phys_addr_t size = resource_size(rsrc); *start = fixup_bigphys_addr(rsrc->start, size); *end = rsrc->start + size; diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 1ccc573e4983..e87aea9494aa 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -428,7 +428,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long size, pgprot_t prot) { - phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); + phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); } #define io_remap_pfn_range io_remap_pfn_range diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index f1fb285d211c..cffc9545dfd2 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h @@ -20,12 +20,12 @@ #ifndef __ASSEMBLY__ /* - * Don't use phys_t. You've been warned. + * Don't use phys_addr_t. You've been warned. */ #ifdef CONFIG_PHYS_ADDR_T_64BIT -typedef unsigned long long phys_t; +typedef unsigned long long phys_addr_t; #else -typedef unsigned long phys_t; +typedef unsigned long phys_addr_t; #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 76eafcb79c89..ef796f97b996 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -32,7 +32,7 @@ static void __init jz4740_detect_mem(void) { void __iomem *jz_emc_base; u32 ctrl, bus, bank, rows, cols; - phys_t size; + phys_addr_t size; jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index f76f7a08412d..85bbe9b96759 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -16,7 +16,7 @@ void __iomem *mips_cm_base; void __iomem *mips_cm_l2sync_base; -phys_t __mips_cm_phys_base(void) +phys_addr_t __mips_cm_phys_base(void) { u32 config3 = read_c0_config3(); u32 cmgcr; @@ -30,10 +30,10 @@ phys_t __mips_cm_phys_base(void) return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); } -phys_t mips_cm_phys_base(void) +phys_addr_t mips_cm_phys_base(void) __attribute__((weak, alias("__mips_cm_phys_base"))); -phys_t __mips_cm_l2sync_phys_base(void) +phys_addr_t __mips_cm_l2sync_phys_base(void) { u32 base_reg; @@ -49,13 +49,13 @@ phys_t __mips_cm_l2sync_phys_base(void) return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; } -phys_t mips_cm_l2sync_phys_base(void) +phys_addr_t mips_cm_l2sync_phys_base(void) __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); static void mips_cm_probe_l2sync(void) { unsigned major_rev; - phys_t addr; + phys_addr_t addr; /* L2-only sync was introduced with CM major revision 6 */ major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> @@ -78,7 +78,7 @@ static void mips_cm_probe_l2sync(void) int mips_cm_probe(void) { - phys_t addr; + phys_addr_t addr; u32 base_reg; addr = mips_cm_phys_base(); diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index ba473608a347..11964501c4b0 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -21,7 +21,7 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock); static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); -phys_t __weak mips_cpc_phys_base(void) +phys_addr_t __weak mips_cpc_phys_base(void) { u32 cpc_base; @@ -44,7 +44,7 @@ phys_t __weak mips_cpc_phys_base(void) int mips_cpc_probe(void) { - phys_t addr; + phys_addr_t addr; unsigned cpu; for_each_possible_cpu(cpu) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index eacfd7dbe8cc..a51c023d0707 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -82,7 +82,7 @@ static struct resource data_resource = { .name = "Kernel data", }; static void *detect_magic __initdata = detect_memory_region; -void __init add_memory_region(phys_t start, phys_t size, long type) +void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) { int x = boot_mem_map.nr_map; int i; @@ -127,10 +127,10 @@ void __init add_memory_region(phys_t start, phys_t size, long type) boot_mem_map.nr_map++; } -void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) +void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) { void *dm = &detect_magic; - phys_t size; + phys_addr_t size; for (size = sz_min; size < sz_max; size <<= 1) { if (!memcmp(dm, dm + size, sizeof(detect_magic))) @@ -545,9 +545,9 @@ static int __init early_parse_elfcorehdr(char *p) early_param("elfcorehdr", early_parse_elfcorehdr); #endif -static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) +static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) { - phys_t size; + phys_addr_t size; int i; size = end - mem; diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 7f840bc08abf..8d5008cbdc0f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -17,9 +17,9 @@ #include static inline void remap_area_pte(pte_t * pte, unsigned long address, - phys_t size, phys_t phys_addr, unsigned long flags) + phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) { - phys_t end; + phys_addr_t end; unsigned long pfn; pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE | __WRITEABLE | flags); @@ -43,9 +43,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, } static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, - phys_t size, phys_t phys_addr, unsigned long flags) + phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) { - phys_t end; + phys_addr_t end; address &= ~PGDIR_MASK; end = address + size; @@ -64,8 +64,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, return 0; } -static int remap_area_pages(unsigned long address, phys_t phys_addr, - phys_t size, unsigned long flags) +static int remap_area_pages(unsigned long address, phys_addr_t phys_addr, + phys_addr_t size, unsigned long flags) { int error; pgd_t * dir; @@ -111,13 +111,13 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr, * caller shouldn't need to know that small detail. */ -#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) +#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) -void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) +void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags) { struct vm_struct * area; unsigned long offset; - phys_t last_addr; + phys_addr_t last_addr; void * addr; phys_addr = fixup_bigphys_addr(phys_addr, size); diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 0f60256d3784..6849f533154f 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -111,7 +111,7 @@ static void __init mips_ejtag_setup(void) flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } -phys_t mips_cpc_default_phys_base(void) +phys_addr_t mips_cpc_default_phys_base(void) { return CPC_BASE_ADDR; } diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index a757ded437cd..657210e767c2 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c @@ -122,8 +122,8 @@ void __init prom_setup_cmdline(void) void __init prom_init(void) { struct ddr_ram __iomem *ddr; - phys_t memsize; - phys_t ddrbase; + phys_addr_t memsize; + phys_addr_t ddrbase; ddr = ioremap_nocache(ddr_reg[0].start, ddr_reg[0].end - ddr_reg[0].start); @@ -133,8 +133,8 @@ void __init prom_init(void) return; } - ddrbase = (phys_t)&ddr->ddrbase; - memsize = (phys_t)&ddr->ddrmask; + ddrbase = (phys_addr_t)&ddr->ddrbase; + memsize = (phys_addr_t)&ddr->ddrmask; memsize = 0 - memsize; prom_setup_cmdline(); diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index d3eea3c1b18c..c1a11a11db7f 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -49,8 +49,8 @@ #endif #define SIBYTE_MAX_MEM_REGIONS 8 -phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; -phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; +phys_addr_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; +phys_addr_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; unsigned int board_mem_region_count; int cfe_cons_handle; diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c index 9480c14ec66a..1cecdcf85cf1 100644 --- a/arch/mips/sibyte/swarm/platform.c +++ b/arch/mips/sibyte/swarm/platform.c @@ -50,7 +50,7 @@ static struct platform_device swarm_pata_device = { static int __init swarm_pata_init(void) { u8 __iomem *base; - phys_t offset, size; + phys_addr_t offset, size; struct resource *r; if (!SIBYTE_HAVE_IDE) -- GitLab From 1ca1f8f6b3aaf6d7f93262594578dfad404bd94e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 22 Nov 2014 00:24:19 +0100 Subject: [PATCH 6293/9457] MIPS: Remove now unused definition of phys_t. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/types.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index cffc9545dfd2..148d42a17f30 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h @@ -14,20 +14,4 @@ #include #include -/* - * These aren't exported outside the kernel to avoid name space clashes - */ -#ifndef __ASSEMBLY__ - -/* - * Don't use phys_addr_t. You've been warned. - */ -#ifdef CONFIG_PHYS_ADDR_T_64BIT -typedef unsigned long long phys_addr_t; -#else -typedef unsigned long phys_addr_t; -#endif - -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_TYPES_H */ -- GitLab From 23d06e4fb7138e29ef77edf2fa918acc20ad5f8d Mon Sep 17 00:00:00 2001 From: "Steven J. Hill" Date: Thu, 13 Nov 2014 09:51:59 -0600 Subject: [PATCH 6294/9457] MIPS: Add CP0 macros for extended EntryLo registers Add read/write macros to access the upper bits of the extended EntryLo0 and EntryLo1 registers used by XPA. Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8455/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mipsregs.h | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 7ebb6544392e..087b2af00150 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -653,6 +653,7 @@ #define MIPS_CONF5_NF (_ULCAST_(1) << 0) #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) +#define MIPS_CONF5_MVH (_ULCAST_(1) << 5) #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) @@ -995,6 +996,39 @@ do { \ local_irq_restore(__flags); \ } while (0) +#define __readx_32bit_c0_register(source) \ +({ \ + unsigned int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " .set mips32r2 \n" \ + " .insn \n" \ + " # mfhc0 $1, %1 \n" \ + " .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__res) \ + : "i" (source)); \ + __res; \ +}) + +#define __writex_32bit_c0_register(register, value) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " .set mips32r2 \n" \ + " move $1, %0 \n" \ + " # mthc0 $1, %1 \n" \ + " .insn \n" \ + " .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \ + " .set pop \n" \ + : \ + : "r" (value), "i" (register)); \ +} while (0) + #define read_c0_index() __read_32bit_c0_register($0, 0) #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) @@ -1004,9 +1038,15 @@ do { \ #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) +#define readx_c0_entrylo0() __readx_32bit_c0_register(2) +#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val) + #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) +#define readx_c0_entrylo1() __readx_32bit_c0_register(3) +#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val) + #define read_c0_conf() __read_32bit_c0_register($3, 0) #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) -- GitLab From 77a5c59332aa75e66f0d95f9eeb69baf3c68970d Mon Sep 17 00:00:00 2001 From: "Steven J. Hill" Date: Thu, 13 Nov 2014 09:52:01 -0600 Subject: [PATCH 6295/9457] MIPS: Cosmetic cleanups of page table headers. * Clean up white spaces and tabs. * Remove _PAGE_R4KBUG which is no longer used. * Get rid of hardcoded values and calculate shifts and masks where possible. Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8457/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/pgtable-32.h | 98 ++++++++++++++-------------- arch/mips/include/asm/pgtable-bits.h | 32 ++++----- arch/mips/include/asm/pgtable.h | 8 +-- 3 files changed, 71 insertions(+), 67 deletions(-) diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index 3021a9459f7f..68984b612f9d 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h @@ -155,73 +155,75 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) /* Swap entries must have VALID bit cleared. */ -#define __swp_type(x) (((x).val >> 10) & 0x1f) -#define __swp_offset(x) ((x).val >> 15) -#define __swp_entry(type,offset) \ - ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) +#define __swp_type(x) (((x).val >> 10) & 0x1f) +#define __swp_offset(x) ((x).val >> 15) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* - * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: + * Encode and decode a nonlinear file mapping entry */ -#define PTE_FILE_MAX_BITS 28 - -#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ - (((_pte).pte >> 2 ) & 0x38) | \ - (((_pte).pte >> 10) << 6 )) +#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ + (((_pte).pte >> 2 ) & 0x38) | \ + (((_pte).pte >> 10) << 6 )) -#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ - (((off) & 0x38) << 2 ) | \ - (((off) >> 6 ) << 10) | \ - _PAGE_FILE }) +#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ + (((off) & 0x38) << 2 ) | \ + (((off) >> 6 ) << 10) | \ + _PAGE_FILE }) +/* + * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: + */ +#define PTE_FILE_MAX_BITS 28 #else -/* Swap entries must have VALID and GLOBAL bits cleared. */ #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) -#define __swp_type(x) (((x).val >> 2) & 0x1f) -#define __swp_offset(x) ((x).val >> 7) -#define __swp_entry(type,offset) \ - ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) -#else -#define __swp_type(x) (((x).val >> 8) & 0x1f) -#define __swp_offset(x) ((x).val >> 13) -#define __swp_entry(type,offset) \ - ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) -#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ -#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) +/* Swap entries must have VALID and GLOBAL bits cleared. */ +#define __swp_type(x) (((x).val >> 2) & 0x1f) +#define __swp_offset(x) ((x).val >> 7) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) +#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) + /* * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... */ -#define PTE_FILE_MAX_BITS 30 - -#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) -#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) +#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) +#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) +#define PTE_FILE_MAX_BITS 30 #else /* - * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: + * Constraints: + * _PAGE_PRESENT at bit 0 + * _PAGE_MODIFIED at bit 4 + * _PAGE_GLOBAL at bit 6 + * _PAGE_VALID at bit 7 */ -#define PTE_FILE_MAX_BITS 28 +#define __swp_type(x) (((x).val >> 8) & 0x1f) +#define __swp_offset(x) ((x).val >> 13) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ - (((_pte).pte >> 2) & 0x8) | \ - (((_pte).pte >> 8) << 4)) +/* + * Encode and decode a nonlinear file mapping entry + */ +#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ + (((_pte).pte >> 2) & 0x8) | \ + (((_pte).pte >> 8) << 4)) -#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ - (((off) & 0x8) << 2) | \ - (((off) >> 4) << 8) | \ - _PAGE_FILE }) -#endif +#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ + (((off) & 0x8) << 2) | \ + (((off) >> 4) << 8) | \ + _PAGE_FILE }) -#endif +#define PTE_FILE_MAX_BITS 28 +#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ -#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) -#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) -#else -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#endif +#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */ #endif /* _ASM_PGTABLE_32_H */ diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 29ba35954e2e..ca11f14f40a3 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -37,34 +37,36 @@ /* * The following bits are directly used by the TLB hardware */ -#define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ -#define _PAGE_GLOBAL (1 << 0) -#define _PAGE_VALID_SHIFT 1 +#define _PAGE_GLOBAL_SHIFT 0 +#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) +#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) -#define _PAGE_SILENT_READ (1 << 1) /* synonym */ -#define _PAGE_DIRTY_SHIFT 2 -#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1 << 2) -#define _CACHE_SHIFT 3 -#define _CACHE_MASK (7 << 3) +#define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) +#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) +#define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1) +#define _CACHE_MASK (7 << _CACHE_SHIFT) /* * The following bits are implemented in software * * _PAGE_FILE semantics: set:pagecache unset:swap */ -#define _PAGE_PRESENT_SHIFT 6 +#define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3) #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) -#define _PAGE_READ_SHIFT 7 +#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) #define _PAGE_READ (1 << _PAGE_READ_SHIFT) -#define _PAGE_WRITE_SHIFT 8 +#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) -#define _PAGE_ACCESSED_SHIFT 9 +#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) -#define _PAGE_MODIFIED_SHIFT 10 +#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) -#define _PAGE_FILE (1 << 10) +#define _PAGE_SILENT_READ _PAGE_VALID +#define _PAGE_SILENT_WRITE _PAGE_DIRTY +#define _PAGE_FILE _PAGE_MODIFIED + +#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index e87aea9494aa..62a6ba383d4f 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -297,13 +297,13 @@ static inline pte_t pte_wrprotect(pte_t pte) static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); + pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); return pte; } static inline pte_t pte_mkold(pte_t pte) { - pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); + pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ); return pte; } @@ -386,9 +386,9 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte.pte_low &= _PAGE_CHG_MASK; - pte.pte_high &= ~0x3f; + pte.pte_high &= (_PFN_MASK | _CACHE_MASK); pte.pte_low |= pgprot_val(newprot); - pte.pte_high |= pgprot_val(newprot) & 0x3f; + pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK); return pte; } #else -- GitLab From e2965cd0003f222bd49f67907c2bc6ed691c6d20 Mon Sep 17 00:00:00 2001 From: "Steven J. Hill" Date: Thu, 13 Nov 2014 09:52:02 -0600 Subject: [PATCH 6296/9457] MIPS: Add MFHC0 and MTHC0 instructions to uasm. New instructions for Extended Physical Addressing (XPA) functionality. Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8453/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uasm.h | 2 ++ arch/mips/include/uapi/asm/inst.h | 7 ++++--- arch/mips/mm/uasm-mips.c | 2 ++ arch/mips/mm/uasm.c | 14 ++++++++------ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 708c5d414905..fc1cdd25fcda 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -136,9 +136,11 @@ Ip_u1s2(_lui); Ip_u2s3u1(_lw); Ip_u3u1u2(_lwx); Ip_u1u2u3(_mfc0); +Ip_u1u2u3(_mfhc0); Ip_u1(_mfhi); Ip_u1(_mflo); Ip_u1u2u3(_mtc0); +Ip_u1u2u3(_mthc0); Ip_u3u1u2(_mul); Ip_u3u1u2(_or); Ip_u2u1u3(_ori); diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 4bfdb9d4c186..89c22433b1c6 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h @@ -108,9 +108,10 @@ enum rt_op { */ enum cop_op { mfc_op = 0x00, dmfc_op = 0x01, - cfc_op = 0x02, mfhc_op = 0x03, - mtc_op = 0x04, dmtc_op = 0x05, - ctc_op = 0x06, mthc_op = 0x07, + cfc_op = 0x02, mfhc0_op = 0x02, + mfhc_op = 0x03, mtc_op = 0x04, + dmtc_op = 0x05, ctc_op = 0x06, + mthc0_op = 0x06, mthc_op = 0x07, bc_op = 0x08, cop_op = 0x10, copm_op = 0x18 }; diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 6708a2dbf934..8e02291cfc0c 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c @@ -96,9 +96,11 @@ static struct insn insn_table[] = { { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, + { insn_mfhc0, M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET}, { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, + { insn_mthc0, M(cop0_op, mthc0_op, 0, 0, 0, 0), RT | RD | SET}, { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index a01b0d6cedd2..4adf30284813 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -51,12 +51,12 @@ enum opcode { insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, - insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul, - insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, - insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra, - insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, - insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, - insn_xor, insn_xori, insn_yield, + insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, insn_mflo, insn_mtc0, + insn_mthc0, insn_mul, insn_or, insn_ori, insn_pref, insn_rfe, + insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, insn_sllv, insn_slt, + insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu, + insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, + insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, }; struct insn { @@ -284,9 +284,11 @@ I_u2s3u1(_lld) I_u1s2(_lui) I_u2s3u1(_lw) I_u1u2u3(_mfc0) +I_u1u2u3(_mfhc0) I_u1(_mfhi) I_u1(_mflo) I_u1u2u3(_mtc0) +I_u1u2u3(_mthc0) I_u3u1u2(_mul) I_u2u1u3(_ori) I_u3u1u2(_or) -- GitLab From 99958588fce8f570d1d48bd67775b8e6c5f92623 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 22 Nov 2014 12:18:26 +0100 Subject: [PATCH 6297/9457] rtlwifi: update RCR register in rtl_op_configure_filter() Reconfigure RCR register in rtl_op_configure_filter() in order to apply RX filter configuration Signed-off-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index af52f0bdb71e..5fc6f52641bd 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -786,6 +786,7 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *new_flags, u64 multicast) { + bool update_rcr = false; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -806,6 +807,7 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "Disable receive multicast frame\n"); } + update_rcr = true; } if (changed_flags & FIF_FCSFAIL) { @@ -818,6 +820,8 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "Disable receive FCS error frame\n"); } + if (!update_rcr) + update_rcr = true; } /* if ssid not set to hw don't check bssid @@ -832,6 +836,8 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_chk_bssid(hw, false); else rtlpriv->cfg->ops->set_chk_bssid(hw, true); + if (update_rcr) + update_rcr = false; } } @@ -846,6 +852,8 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "Disable receive control frame.\n"); } + if (!update_rcr) + update_rcr = true; } if (changed_flags & FIF_OTHER_BSS) { @@ -858,7 +866,13 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "Disable receive other BSS's frame.\n"); } + if (!update_rcr) + update_rcr = true; } + + if (update_rcr) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(&mac->rx_conf)); } static int rtl_op_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- GitLab From a831f20b6d6460640b83644d1c1df6e7e8ca9f68 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado Date: Mon, 24 Nov 2014 11:19:51 +0100 Subject: [PATCH 6298/9457] wireless/p54: Remove duplicated net2280 header The usb gadget driver net2280 has exported a header file with the register definition of the net2280 chip. Remove the custom/duplicated header file in favor of that header file in include/linux Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: John W. Linville --- drivers/net/wireless/p54/net2280.h | 451 ----------------------------- drivers/net/wireless/p54/p54usb.h | 13 +- 2 files changed, 12 insertions(+), 452 deletions(-) delete mode 100644 drivers/net/wireless/p54/net2280.h diff --git a/drivers/net/wireless/p54/net2280.h b/drivers/net/wireless/p54/net2280.h deleted file mode 100644 index aedfaf24f386..000000000000 --- a/drivers/net/wireless/p54/net2280.h +++ /dev/null @@ -1,451 +0,0 @@ -#ifndef NET2280_H -#define NET2280_H -/* - * NetChip 2280 high/full speed USB device controller. - * Unlike many such controllers, this one talks PCI. - */ - -/* - * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) - * Copyright (C) 2003 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -/*-------------------------------------------------------------------------*/ - -/* NET2280 MEMORY MAPPED REGISTERS - * - * The register layout came from the chip documentation, and the bit - * number definitions were extracted from chip specification. - * - * Use the shift operator ('<<') to build bit masks, with readl/writel - * to access the registers through PCI. - */ - -/* main registers, BAR0 + 0x0000 */ -struct net2280_regs { - /* offset 0x0000 */ - __le32 devinit; -#define LOCAL_CLOCK_FREQUENCY 8 -#define FORCE_PCI_RESET 7 -#define PCI_ID 6 -#define PCI_ENABLE 5 -#define FIFO_SOFT_RESET 4 -#define CFG_SOFT_RESET 3 -#define PCI_SOFT_RESET 2 -#define USB_SOFT_RESET 1 -#define M8051_RESET 0 - __le32 eectl; -#define EEPROM_ADDRESS_WIDTH 23 -#define EEPROM_CHIP_SELECT_ACTIVE 22 -#define EEPROM_PRESENT 21 -#define EEPROM_VALID 20 -#define EEPROM_BUSY 19 -#define EEPROM_CHIP_SELECT_ENABLE 18 -#define EEPROM_BYTE_READ_START 17 -#define EEPROM_BYTE_WRITE_START 16 -#define EEPROM_READ_DATA 8 -#define EEPROM_WRITE_DATA 0 - __le32 eeclkfreq; - u32 _unused0; - /* offset 0x0010 */ - - __le32 pciirqenb0; /* interrupt PCI master ... */ -#define SETUP_PACKET_INTERRUPT_ENABLE 7 -#define ENDPOINT_F_INTERRUPT_ENABLE 6 -#define ENDPOINT_E_INTERRUPT_ENABLE 5 -#define ENDPOINT_D_INTERRUPT_ENABLE 4 -#define ENDPOINT_C_INTERRUPT_ENABLE 3 -#define ENDPOINT_B_INTERRUPT_ENABLE 2 -#define ENDPOINT_A_INTERRUPT_ENABLE 1 -#define ENDPOINT_0_INTERRUPT_ENABLE 0 - __le32 pciirqenb1; -#define PCI_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - __le32 cpu_irqenb0; /* ... or onboard 8051 */ -#define SETUP_PACKET_INTERRUPT_ENABLE 7 -#define ENDPOINT_F_INTERRUPT_ENABLE 6 -#define ENDPOINT_E_INTERRUPT_ENABLE 5 -#define ENDPOINT_D_INTERRUPT_ENABLE 4 -#define ENDPOINT_C_INTERRUPT_ENABLE 3 -#define ENDPOINT_B_INTERRUPT_ENABLE 2 -#define ENDPOINT_A_INTERRUPT_ENABLE 1 -#define ENDPOINT_0_INTERRUPT_ENABLE 0 - __le32 cpu_irqenb1; -#define CPU_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_INTA_INTERRUPT_ENABLE 24 -#define PCI_PME_INTERRUPT_ENABLE 23 -#define PCI_SERR_INTERRUPT_ENABLE 22 -#define PCI_PERR_INTERRUPT_ENABLE 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - - /* offset 0x0020 */ - u32 _unused1; - __le32 usbirqenb1; -#define USB_INTERRUPT_ENABLE 31 -#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26 -#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25 -#define PCI_INTA_INTERRUPT_ENABLE 24 -#define PCI_PME_INTERRUPT_ENABLE 23 -#define PCI_SERR_INTERRUPT_ENABLE 22 -#define PCI_PERR_INTERRUPT_ENABLE 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19 -#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16 -#define GPIO_INTERRUPT_ENABLE 13 -#define DMA_D_INTERRUPT_ENABLE 12 -#define DMA_C_INTERRUPT_ENABLE 11 -#define DMA_B_INTERRUPT_ENABLE 10 -#define DMA_A_INTERRUPT_ENABLE 9 -#define EEPROM_DONE_INTERRUPT_ENABLE 8 -#define VBUS_INTERRUPT_ENABLE 7 -#define CONTROL_STATUS_INTERRUPT_ENABLE 6 -#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4 -#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2 -#define RESUME_INTERRUPT_ENABLE 1 -#define SOF_INTERRUPT_ENABLE 0 - __le32 irqstat0; -#define INTA_ASSERTED 12 -#define SETUP_PACKET_INTERRUPT 7 -#define ENDPOINT_F_INTERRUPT 6 -#define ENDPOINT_E_INTERRUPT 5 -#define ENDPOINT_D_INTERRUPT 4 -#define ENDPOINT_C_INTERRUPT 3 -#define ENDPOINT_B_INTERRUPT 2 -#define ENDPOINT_A_INTERRUPT 1 -#define ENDPOINT_0_INTERRUPT 0 - __le32 irqstat1; -#define POWER_STATE_CHANGE_INTERRUPT 27 -#define PCI_ARBITER_TIMEOUT_INTERRUPT 26 -#define PCI_PARITY_ERROR_INTERRUPT 25 -#define PCI_INTA_INTERRUPT 24 -#define PCI_PME_INTERRUPT 23 -#define PCI_SERR_INTERRUPT 22 -#define PCI_PERR_INTERRUPT 21 -#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20 -#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 -#define PCI_RETRY_ABORT_INTERRUPT 17 -#define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 -#define GPIO_INTERRUPT 13 -#define DMA_D_INTERRUPT 12 -#define DMA_C_INTERRUPT 11 -#define DMA_B_INTERRUPT 10 -#define DMA_A_INTERRUPT 9 -#define EEPROM_DONE_INTERRUPT 8 -#define VBUS_INTERRUPT 7 -#define CONTROL_STATUS_INTERRUPT 6 -#define ROOT_PORT_RESET_INTERRUPT 4 -#define SUSPEND_REQUEST_INTERRUPT 3 -#define SUSPEND_REQUEST_CHANGE_INTERRUPT 2 -#define RESUME_INTERRUPT 1 -#define SOF_INTERRUPT 0 - /* offset 0x0030 */ - __le32 idxaddr; - __le32 idxdata; - __le32 fifoctl; -#define PCI_BASE2_RANGE 16 -#define IGNORE_FIFO_AVAILABILITY 3 -#define PCI_BASE2_SELECT 2 -#define FIFO_CONFIGURATION_SELECT 0 - u32 _unused2; - /* offset 0x0040 */ - __le32 memaddr; -#define START 28 -#define DIRECTION 27 -#define FIFO_DIAGNOSTIC_SELECT 24 -#define MEMORY_ADDRESS 0 - __le32 memdata0; - __le32 memdata1; - u32 _unused3; - /* offset 0x0050 */ - __le32 gpioctl; -#define GPIO3_LED_SELECT 12 -#define GPIO3_INTERRUPT_ENABLE 11 -#define GPIO2_INTERRUPT_ENABLE 10 -#define GPIO1_INTERRUPT_ENABLE 9 -#define GPIO0_INTERRUPT_ENABLE 8 -#define GPIO3_OUTPUT_ENABLE 7 -#define GPIO2_OUTPUT_ENABLE 6 -#define GPIO1_OUTPUT_ENABLE 5 -#define GPIO0_OUTPUT_ENABLE 4 -#define GPIO3_DATA 3 -#define GPIO2_DATA 2 -#define GPIO1_DATA 1 -#define GPIO0_DATA 0 - __le32 gpiostat; -#define GPIO3_INTERRUPT 3 -#define GPIO2_INTERRUPT 2 -#define GPIO1_INTERRUPT 1 -#define GPIO0_INTERRUPT 0 -} __packed; - -/* usb control, BAR0 + 0x0080 */ -struct net2280_usb_regs { - /* offset 0x0080 */ - __le32 stdrsp; -#define STALL_UNSUPPORTED_REQUESTS 31 -#define SET_TEST_MODE 16 -#define GET_OTHER_SPEED_CONFIGURATION 15 -#define GET_DEVICE_QUALIFIER 14 -#define SET_ADDRESS 13 -#define ENDPOINT_SET_CLEAR_HALT 12 -#define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11 -#define GET_STRING_DESCRIPTOR_2 10 -#define GET_STRING_DESCRIPTOR_1 9 -#define GET_STRING_DESCRIPTOR_0 8 -#define GET_SET_INTERFACE 6 -#define GET_SET_CONFIGURATION 5 -#define GET_CONFIGURATION_DESCRIPTOR 4 -#define GET_DEVICE_DESCRIPTOR 3 -#define GET_ENDPOINT_STATUS 2 -#define GET_INTERFACE_STATUS 1 -#define GET_DEVICE_STATUS 0 - __le32 prodvendid; -#define PRODUCT_ID 16 -#define VENDOR_ID 0 - __le32 relnum; - __le32 usbctl; -#define SERIAL_NUMBER_INDEX 16 -#define PRODUCT_ID_STRING_ENABLE 13 -#define VENDOR_ID_STRING_ENABLE 12 -#define USB_ROOT_PORT_WAKEUP_ENABLE 11 -#define VBUS_PIN 10 -#define TIMED_DISCONNECT 9 -#define SUSPEND_IMMEDIATELY 7 -#define SELF_POWERED_USB_DEVICE 6 -#define REMOTE_WAKEUP_SUPPORT 5 -#define PME_POLARITY 4 -#define USB_DETECT_ENABLE 3 -#define PME_WAKEUP_ENABLE 2 -#define DEVICE_REMOTE_WAKEUP_ENABLE 1 -#define SELF_POWERED_STATUS 0 - /* offset 0x0090 */ - __le32 usbstat; -#define HIGH_SPEED 7 -#define FULL_SPEED 6 -#define GENERATE_RESUME 5 -#define GENERATE_DEVICE_REMOTE_WAKEUP 4 - __le32 xcvrdiag; -#define FORCE_HIGH_SPEED_MODE 31 -#define FORCE_FULL_SPEED_MODE 30 -#define USB_TEST_MODE 24 -#define LINE_STATE 16 -#define TRANSCEIVER_OPERATION_MODE 2 -#define TRANSCEIVER_SELECT 1 -#define TERMINATION_SELECT 0 - __le32 setup0123; - __le32 setup4567; - /* offset 0x0090 */ - u32 _unused0; - __le32 ouraddr; -#define FORCE_IMMEDIATE 7 -#define OUR_USB_ADDRESS 0 - __le32 ourconfig; -} __packed; - -/* pci control, BAR0 + 0x0100 */ -struct net2280_pci_regs { - /* offset 0x0100 */ - __le32 pcimstctl; -#define PCI_ARBITER_PARK_SELECT 13 -#define PCI_MULTI LEVEL_ARBITER 12 -#define PCI_RETRY_ABORT_ENABLE 11 -#define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10 -#define DMA_READ_MULTIPLE_ENABLE 9 -#define DMA_READ_LINE_ENABLE 8 -#define PCI_MASTER_COMMAND_SELECT 6 -#define MEM_READ_OR_WRITE 0 -#define IO_READ_OR_WRITE 1 -#define CFG_READ_OR_WRITE 2 -#define PCI_MASTER_START 5 -#define PCI_MASTER_READ_WRITE 4 -#define PCI_MASTER_WRITE 0 -#define PCI_MASTER_READ 1 -#define PCI_MASTER_BYTE_WRITE_ENABLES 0 - __le32 pcimstaddr; - __le32 pcimstdata; - __le32 pcimststat; -#define PCI_ARBITER_CLEAR 2 -#define PCI_EXTERNAL_ARBITER 1 -#define PCI_HOST_MODE 0 -} __packed; - -/* dma control, BAR0 + 0x0180 ... array of four structs like this, - * for channels 0..3. see also struct net2280_dma: descriptor - * that can be loaded into some of these registers. - */ -struct net2280_dma_regs { /* [11.7] */ - /* offset 0x0180, 0x01a0, 0x01c0, 0x01e0, */ - __le32 dmactl; -#define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25 -#define DMA_CLEAR_COUNT_ENABLE 21 -#define DESCRIPTOR_POLLING_RATE 19 -#define POLL_CONTINUOUS 0 -#define POLL_1_USEC 1 -#define POLL_100_USEC 2 -#define POLL_1_MSEC 3 -#define DMA_VALID_BIT_POLLING_ENABLE 18 -#define DMA_VALID_BIT_ENABLE 17 -#define DMA_SCATTER_GATHER_ENABLE 16 -#define DMA_OUT_AUTO_START_ENABLE 4 -#define DMA_PREEMPT_ENABLE 3 -#define DMA_FIFO_VALIDATE 2 -#define DMA_ENABLE 1 -#define DMA_ADDRESS_HOLD 0 - __le32 dmastat; -#define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 -#define DMA_TRANSACTION_DONE_INTERRUPT 24 -#define DMA_ABORT 1 -#define DMA_START 0 - u32 _unused0[2]; - /* offset 0x0190, 0x01b0, 0x01d0, 0x01f0, */ - __le32 dmacount; -#define VALID_BIT 31 -#define DMA_DIRECTION 30 -#define DMA_DONE_INTERRUPT_ENABLE 29 -#define END_OF_CHAIN 28 -#define DMA_BYTE_COUNT_MASK ((1<<24)-1) -#define DMA_BYTE_COUNT 0 - __le32 dmaaddr; - __le32 dmadesc; - u32 _unused1; -} __packed; - -/* dedicated endpoint registers, BAR0 + 0x0200 */ - -struct net2280_dep_regs { /* [11.8] */ - /* offset 0x0200, 0x0210, 0x220, 0x230, 0x240 */ - __le32 dep_cfg; - /* offset 0x0204, 0x0214, 0x224, 0x234, 0x244 */ - __le32 dep_rsp; - u32 _unused[2]; -} __packed; - -/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs - * like this, for ep0 then the configurable endpoints A..F - * ep0 reserved for control; E and F have only 64 bytes of fifo - */ -struct net2280_ep_regs { /* [11.9] */ - /* offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0 */ - __le32 ep_cfg; -#define ENDPOINT_BYTE_COUNT 16 -#define ENDPOINT_ENABLE 10 -#define ENDPOINT_TYPE 8 -#define ENDPOINT_DIRECTION 7 -#define ENDPOINT_NUMBER 0 - __le32 ep_rsp; -#define SET_NAK_OUT_PACKETS 15 -#define SET_EP_HIDE_STATUS_PHASE 14 -#define SET_EP_FORCE_CRC_ERROR 13 -#define SET_INTERRUPT_MODE 12 -#define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11 -#define SET_NAK_OUT_PACKETS_MODE 10 -#define SET_ENDPOINT_TOGGLE 9 -#define SET_ENDPOINT_HALT 8 -#define CLEAR_NAK_OUT_PACKETS 7 -#define CLEAR_EP_HIDE_STATUS_PHASE 6 -#define CLEAR_EP_FORCE_CRC_ERROR 5 -#define CLEAR_INTERRUPT_MODE 4 -#define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3 -#define CLEAR_NAK_OUT_PACKETS_MODE 2 -#define CLEAR_ENDPOINT_TOGGLE 1 -#define CLEAR_ENDPOINT_HALT 0 - __le32 ep_irqenb; -#define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6 -#define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5 -#define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3 -#define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2 -#define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1 -#define DATA_IN_TOKEN_INTERRUPT_ENABLE 0 - __le32 ep_stat; -#define FIFO_VALID_COUNT 24 -#define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22 -#define TIMEOUT 21 -#define USB_STALL_SENT 20 -#define USB_IN_NAK_SENT 19 -#define USB_IN_ACK_RCVD 18 -#define USB_OUT_PING_NAK_SENT 17 -#define USB_OUT_ACK_SENT 16 -#define FIFO_OVERFLOW 13 -#define FIFO_UNDERFLOW 12 -#define FIFO_FULL 11 -#define FIFO_EMPTY 10 -#define FIFO_FLUSH 9 -#define SHORT_PACKET_OUT_DONE_INTERRUPT 6 -#define SHORT_PACKET_TRANSFERRED_INTERRUPT 5 -#define NAK_OUT_PACKETS 4 -#define DATA_PACKET_RECEIVED_INTERRUPT 3 -#define DATA_PACKET_TRANSMITTED_INTERRUPT 2 -#define DATA_OUT_PING_TOKEN_INTERRUPT 1 -#define DATA_IN_TOKEN_INTERRUPT 0 - /* offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0 */ - __le32 ep_avail; - __le32 ep_data; - u32 _unused0[2]; -} __packed; - -struct net2280_reg_write { - __le16 port; - __le32 addr; - __le32 val; -} __packed; - -struct net2280_reg_read { - __le16 port; - __le32 addr; -} __packed; -#endif /* NET2280_H */ diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h index d273be7272b9..a5f5f0fea3bd 100644 --- a/drivers/net/wireless/p54/p54usb.h +++ b/drivers/net/wireless/p54/p54usb.h @@ -16,7 +16,7 @@ /* for isl3886 register definitions used on ver 1 devices */ #include "p54pci.h" -#include "net2280.h" +#include /* pci */ #define NET2280_BASE 0x10000000 @@ -93,6 +93,17 @@ enum net2280_op_type { NET2280_DEV_CFG_U16 = 0x0883 }; +struct net2280_reg_write { + __le16 port; + __le32 addr; + __le32 val; +} __packed; + +struct net2280_reg_read { + __le16 port; + __le32 addr; +} __packed; + #define P54U_FW_BLOCK 2048 #define X2_SIGNATURE "x2 " -- GitLab From 34b5d778b583104d91534b4673472b7820e0c0b3 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Mon, 24 Nov 2014 17:26:22 +0530 Subject: [PATCH 6299/9457] ath: Fix a false radar detection pattern For FCC and JP, in one of the radar patterns, PPB and PRF seems to be interchanged leading to frequent incorrect radar detections. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/dfs_pattern_detector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c index 650be79c7ac9..cfd0554cf140 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/dfs_pattern_detector.c @@ -86,7 +86,7 @@ static const struct radar_detector_specs fcc_radar_ref_types[] = { FCC_PATTERN(1, 0, 5, 150, 230, 1, 23), FCC_PATTERN(2, 6, 10, 200, 500, 1, 16), FCC_PATTERN(3, 11, 20, 200, 500, 1, 12), - FCC_PATTERN(4, 50, 100, 1000, 2000, 20, 1), + FCC_PATTERN(4, 50, 100, 1000, 2000, 1, 20), FCC_PATTERN(5, 0, 1, 333, 333, 1, 9), }; @@ -105,7 +105,7 @@ static const struct radar_detector_specs jp_radar_ref_types[] = { JP_PATTERN(4, 0, 5, 150, 230, 1, 23), JP_PATTERN(5, 6, 10, 200, 500, 1, 16), JP_PATTERN(6, 11, 20, 200, 500, 1, 12), - JP_PATTERN(7, 50, 100, 1000, 2000, 20, 1), + JP_PATTERN(7, 50, 100, 1000, 2000, 1, 20), JP_PATTERN(5, 0, 1, 333, 333, 1, 9), }; -- GitLab From 927a70874c34e862f6aea5ad9c4a5d2c3f140bcd Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Mon, 24 Nov 2014 19:34:31 +0100 Subject: [PATCH 6300/9457] net: wireless: rtlwifi: Do not always include drivers in obj-m In four of the rtlwifi drivers, the Makefile contains superfluous statements indicating the compilation of the driver as an LKM regardless of the corresponding Kconfig option. If the corresponding option is set to 'y', the build system will then see the object file in obj-m and obj-y, which leads to a compilation as a built-in only. Even though this leads to the desired behavior, the unconditional appearance in obj-m is confusing for someone reading the Makefile. This patch removes the superfluous Makefile statements. Signed-off-by: Andreas Ruprecht Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ee/Makefile | 3 --- drivers/net/wireless/rtlwifi/rtl8723ae/Makefile | 3 --- drivers/net/wireless/rtlwifi/rtl8723be/Makefile | 3 --- drivers/net/wireless/rtlwifi/rtl8821ae/Makefile | 3 --- 4 files changed, 12 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile index 11952b99daf8..6bd46a9314ca 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile @@ -1,6 +1,3 @@ -obj-m := rtl8192ee.o - - rtl8192ee-objs := \ dm.o \ fw.o \ diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile index 9c34a85fdb89..6220672a96f4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile @@ -1,6 +1,3 @@ -obj-m := rtl8723ae.o - - rtl8723ae-objs := \ dm.o \ fw.o \ diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile index 59e416abd93a..a77c34102792 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile @@ -1,6 +1,3 @@ -obj-m := rtl8723be.o - - rtl8723be-objs := \ dm.o \ fw.o \ diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile index 87ad604a1eb3..f7a26f71197e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/Makefile @@ -1,6 +1,3 @@ -obj-m := rtl8821ae.o - - rtl8821ae-objs := \ dm.o \ fw.o \ -- GitLab From b880c6deabacc415488984f6a79918ec0fa2e53d Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Mon, 24 Nov 2014 19:34:32 +0100 Subject: [PATCH 6301/9457] net: wireless: rtlwifi: rtl8192ee: Fix compilation of the driver In the Makefile for this driver, the wrong Kconfig option is used to trigger the compilation of the object file. This leads to the driver only being included into the kernel when both CONFIG_RTL8821AE and CONFIG_RTL8192AE are set to "y". Signed-off-by: Andreas Ruprecht Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ee/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile index 6bd46a9314ca..0315eeda9b60 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ee/Makefile @@ -11,6 +11,6 @@ rtl8192ee-objs := \ trx.o \ -obj-$(CONFIG_RTL8821AE) += rtl8192ee.o +obj-$(CONFIG_RTL8192EE) += rtl8192ee.o ccflags-y += -D__CHECK_ENDIAN__ -- GitLab From 6a74c0c9402b85647793da70edc9d6b097d54472 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 24 Nov 2014 16:47:02 -0500 Subject: [PATCH 6302/9457] pnfs/blocklayout: fix end calculation in pnfs_num_cont_bytes Use the number of pages in the pagecache mapping instead of the number of pnfs requests which is only slightly related. Reported-by: Weston Andros Adamson Signed-off-by: Christoph Hellwig Signed-off-by: Trond Myklebust --- fs/nfs/blocklayout/blocklayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 4f46f7a05289..77fec6a55f57 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -812,7 +812,7 @@ static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx) /* Optimize common case that writes from 0 to end of file */ end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE); - if (end != NFS_I(inode)->npages) { + if (end != inode->i_mapping->nrpages) { rcu_read_lock(); end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX); rcu_read_unlock(); -- GitLab From cb1410c71e0b6b2eba8c1890645a76ff86169d24 Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Wed, 12 Nov 2014 12:08:00 -0500 Subject: [PATCH 6303/9457] NFS: fix subtle change in COMMIT behavior Recent work in the pgio layer made it possible for there to be more than one request per page. This caused a subtle change in commit behavior, because write.c:nfs_commit_unstable_pages compares the number of *pages* waiting for writeback against the number of requests on a commit list to choose when to send a COMMIT in a non-blocking flush. This is probably hard to hit in normal operation - you have to be using rsize/wsize < PAGE_SIZE, or pnfs with lots of boundaries that are not page aligned to have a noticeable change in behavior. Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 2 +- fs/nfs/inode.c | 8 ++++---- fs/nfs/pagelist.c | 11 ++++++++--- fs/nfs/write.c | 17 ++++++++++++----- include/linux/nfs_fs.h | 4 ++-- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 73466b934090..e36a9d78ea49 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -49,7 +49,7 @@ __be32 nfs4_callback_getattr(struct cb_getattrargs *args, goto out_iput; res->size = i_size_read(inode); res->change_attr = delegation->change_attr; - if (nfsi->npages != 0) + if (nfsi->nrequests != 0) res->change_attr++; res->ctime = inode->i_ctime; res->mtime = inode->i_mtime; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 00689a8a85e4..2b48ce58a584 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1149,7 +1149,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) && (fattr->valid & NFS_ATTR_FATTR_SIZE) && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) - && nfsi->npages == 0) { + && nfsi->nrequests == 0) { i_size_write(inode, nfs_size_to_loff_t(fattr->size)); ret |= NFS_INO_INVALID_ATTR; } @@ -1192,7 +1192,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat if (fattr->valid & NFS_ATTR_FATTR_SIZE) { cur_size = i_size_read(inode); new_isize = nfs_size_to_loff_t(fattr->size); - if (cur_size != new_isize && nfsi->npages == 0) + if (cur_size != new_isize && nfsi->nrequests == 0) invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; } @@ -1619,7 +1619,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) if (new_isize != cur_isize) { /* Do we perhaps have any outstanding writes, or has * the file grown beyond our last write? */ - if ((nfsi->npages == 0) || new_isize > cur_isize) { + if ((nfsi->nrequests == 0) || new_isize > cur_isize) { i_size_write(inode, new_isize); invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; invalid &= ~NFS_INO_REVAL_PAGECACHE; @@ -1784,7 +1784,7 @@ static void init_once(void *foo) INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); INIT_LIST_HEAD(&nfsi->commit_info.list); - nfsi->npages = 0; + nfsi->nrequests = 0; nfsi->commit_info.ncommit = 0; atomic_set(&nfsi->commit_info.rpcs_out, 0); atomic_set(&nfsi->silly_count, 1); diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index ed0db61f8543..2b5e769beb16 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -258,6 +258,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit) static inline void nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev) { + struct inode *inode; WARN_ON_ONCE(prev == req); if (!prev) { @@ -276,12 +277,16 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev) * nfs_page_group_destroy is called */ kref_get(&req->wb_head->wb_kref); - /* grab extra ref if head request has extra ref from - * the write/commit path to handle handoff between write - * and commit lists */ + /* grab extra ref and bump the request count if head request + * has extra ref from the write/commit path to handle handoff + * between write and commit lists. */ if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) { + inode = page_file_mapping(req->wb_page)->host; set_bit(PG_INODE_REF, &req->wb_flags); kref_get(&req->wb_kref); + spin_lock(&inode->i_lock); + NFS_I(inode)->nrequests++; + spin_unlock(&inode->i_lock); } } } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f83b02dc9166..d489ff3f438f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -670,7 +670,8 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) nfs_lock_request(req); spin_lock(&inode->i_lock); - if (!nfsi->npages && NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) + if (!nfsi->nrequests && + NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) inode->i_version++; /* * Swap-space should not get truncated. Hence no need to plug the race @@ -681,9 +682,11 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); } - nfsi->npages++; + nfsi->nrequests++; /* this a head request for a page group - mark it as having an - * extra reference so sub groups can follow suit */ + * extra reference so sub groups can follow suit. + * This flag also informs pgio layer when to bump nrequests when + * adding subrequests. */ WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags)); kref_get(&req->wb_kref); spin_unlock(&inode->i_lock); @@ -709,7 +712,11 @@ static void nfs_inode_remove_request(struct nfs_page *req) wake_up_page(head->wb_page, PG_private); clear_bit(PG_MAPPED, &head->wb_flags); } - nfsi->npages--; + nfsi->nrequests--; + spin_unlock(&inode->i_lock); + } else { + spin_lock(&inode->i_lock); + nfsi->nrequests--; spin_unlock(&inode->i_lock); } @@ -1735,7 +1742,7 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr /* Don't commit yet if this is a non-blocking flush and there * are a lot of outstanding writes for this mapping. */ - if (nfsi->commit_info.ncommit <= (nfsi->npages >> 1)) + if (nfsi->commit_info.ncommit <= (nfsi->nrequests >> 1)) goto out_mark_dirty; /* don't wait for the COMMIT response */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c72d1ad41ad4..6d627b92df53 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -163,7 +163,7 @@ struct nfs_inode { */ __be32 cookieverf[2]; - unsigned long npages; + unsigned long nrequests; struct nfs_mds_commit_info commit_info; /* Open contexts for shared mmap writes */ @@ -520,7 +520,7 @@ extern void nfs_commit_free(struct nfs_commit_data *data); static inline int nfs_have_writebacks(struct inode *inode) { - return NFS_I(inode)->npages != 0; + return NFS_I(inode)->nrequests != 0; } /* -- GitLab From a33c1ba2913802b6fb23e974bb2f6a4e73c8b7ce Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 24 Nov 2014 15:02:42 -0700 Subject: [PATCH 6304/9457] blk-mq: use 'nr_cpu_ids' as highest CPU ID count for hwq <-> cpu map We currently use num_possible_cpus(), but that breaks on sparc64 where the CPU ID space is discontig. Use nr_cpu_ids as the highest CPU ID instead, so we don't end up reading from invalid memory. Cc: stable@kernel.org # 3.13+ Signed-off-by: Jens Axboe --- block/blk-mq-cpumap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c index 1065d7c65fa1..72e5ed691e37 100644 --- a/block/blk-mq-cpumap.c +++ b/block/blk-mq-cpumap.c @@ -90,7 +90,7 @@ unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set) unsigned int *map; /* If cpus are offline, map them to first hctx */ - map = kzalloc_node(sizeof(*map) * num_possible_cpus(), GFP_KERNEL, + map = kzalloc_node(sizeof(*map) * nr_cpu_ids, GFP_KERNEL, set->numa_node); if (!map) return NULL; -- GitLab From 75f9c2939a157c77d8342c53d3d4f016d3b067a3 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 24 Nov 2014 19:56:38 +0800 Subject: [PATCH 6305/9457] ACPI / PM: Fixed a typo in a comment Signed-off-by: Huang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 7db193160766..076af8149566 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -201,7 +201,7 @@ int acpi_device_set_power(struct acpi_device *device, int state) * Transition Power * ---------------- * In accordance with the ACPI specification first apply power (via - * power resources) and then evalute _PSx. + * power resources) and then evaluate _PSx. */ if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); -- GitLab From 4bd5a980de87d2b5af417485bde97b8eb3d6cf6a Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Mon, 17 Nov 2014 11:05:17 +0800 Subject: [PATCH 6306/9457] nfs41: fix nfs4_proc_layoutget error handling nfs4_layoutget_release() drops layout hdr refcnt. Grab the refcnt early so that it is safe to call .release in case nfs4_alloc_pages fails. Signed-off-by: Peng Tao Fixes: a47970ff78147 ("NFSv4.1: Hold reference to layout hdr in layoutget") Cc: stable@vger.kernel.org # 3.9+ Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 15d5eb52cde8..3138913d1cdf 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7702,6 +7702,9 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) dprintk("--> %s\n", __func__); + /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ + pnfs_get_layout_hdr(NFS_I(inode)->layout); + lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); if (!lgp->args.layout.pages) { nfs4_layoutget_release(lgp); @@ -7714,9 +7717,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) lgp->res.seq_res.sr_slot = NULL; nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); - /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ - pnfs_get_layout_hdr(NFS_I(inode)->layout); - task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) return ERR_CAST(task); -- GitLab From ef8bbd73a76197cf8362a2b43aaadc5717bd0746 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 14 Nov 2014 15:33:07 +0000 Subject: [PATCH 6307/9457] of: Use vargs in __of_node_alloc The overlay code needs to construct a new full_name from the parent name and the node name, but the current method has to allocate and then free an temporary string which is wasteful. Fix this problem by using vargs to pass in a format and arguments into __of_node_alloc(). At the same time remove the allocflags argument to __of_node_alloc(). The only users all use GFP_KERNEL, so there is no need to provide it as an option. If there is ever a need later it can be added back. Signed-off-by: Grant Likely --- drivers/of/dynamic.c | 16 ++++++++-------- drivers/of/of_private.h | 2 +- drivers/of/unittest.c | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index d43f3059963b..af1b1ecd6a3d 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -274,33 +274,33 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) /** * __of_node_alloc() - Create an empty device node dynamically. * @full_name: Full name of the new device node - * @allocflags: Allocation flags (typically pass GFP_KERNEL) * * Create an empty device tree node, suitable for further modification. * The node data are dynamically allocated and all the node flags * have the OF_DYNAMIC & OF_DETACHED bits set. * Returns the newly allocated node or NULL on out of memory error. */ -struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags) +struct device_node *__of_node_alloc(const char *fmt, ...) { + va_list vargs; struct device_node *node; - node = kzalloc(sizeof(*node), allocflags); + node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) return NULL; - - node->full_name = kstrdup(full_name, allocflags); - of_node_set_flag(node, OF_DYNAMIC); - of_node_set_flag(node, OF_DETACHED); + va_start(vargs, fmt); + node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs); + va_end(vargs); if (!node->full_name) goto err_free; + of_node_set_flag(node, OF_DYNAMIC); + of_node_set_flag(node, OF_DETACHED); of_node_init(node); return node; err_free: - kfree(node->full_name); kfree(node); return NULL; } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 858e0a5d9a11..618abcad307e 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -61,7 +61,7 @@ static inline int of_property_notify(int action, struct device_node *np, * own the devtree lock or work on detached trees only. */ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); -struct device_node *__of_node_alloc(const char *full_name, gfp_t allocflags); +__printf(1, 2) struct device_node *__of_node_alloc(const char *fmt, ...); extern const void *__of_get_property(const struct device_node *np, const char *name, int *lenp); diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 46af7019d291..7634a17af1d5 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -449,11 +449,11 @@ static void __init of_selftest_changeset(void) struct of_changeset chgset; of_changeset_init(&chgset); - n1 = __of_node_alloc("/testcase-data/changeset/n1", GFP_KERNEL); + n1 = __of_node_alloc("/testcase-data/changeset/n1"); selftest(n1, "testcase setup failure\n"); - n2 = __of_node_alloc("/testcase-data/changeset/n2", GFP_KERNEL); + n2 = __of_node_alloc("/testcase-data/changeset/n2"); selftest(n2, "testcase setup failure\n"); - n21 = __of_node_alloc("/testcase-data/changeset/n2/n21", GFP_KERNEL); + n21 = __of_node_alloc("/testcase-data/changeset/n2/n21"); selftest(n21, "testcase setup failure %p\n", n21); nremove = of_find_node_by_path("/testcase-data/changeset/node-remove"); selftest(nremove, "testcase setup failure\n"); -- GitLab From 10b89567db51e143c2f0828839332502916d012d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 17 Nov 2014 16:58:03 -0500 Subject: [PATCH 6308/9457] lockd: eliminate LOCKD_DEBUG LOCKD_DEBUG is always the same value as CONFIG_SUNRPC_DEBUG, so we can just use it instead. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/lockd/svclock.c | 2 +- include/linux/lockd/debug.h | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 13db95f54176..56598742dde4 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -53,7 +53,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops; static LIST_HEAD(nlm_blocked); static DEFINE_SPINLOCK(nlm_blocked_lock); -#ifdef LOCKD_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) { /* diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h index 257d3779f2ab..0ca8109934e4 100644 --- a/include/linux/lockd/debug.h +++ b/include/linux/lockd/debug.h @@ -17,12 +17,8 @@ * Enable lockd debugging. * Requires RPC_DEBUG. */ -#ifdef RPC_DEBUG -# define LOCKD_DEBUG 1 -#endif - #undef ifdebug -#if defined(RPC_DEBUG) && defined(LOCKD_DEBUG) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define ifdebug(flag) if (unlikely(nlm_debug & NLMDBG_##flag)) #else # define ifdebug(flag) if (0) -- GitLab From e51795815ef1a7adc018cbaf05aac46e3d24eda8 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 17 Nov 2014 22:31:32 +0000 Subject: [PATCH 6309/9457] of: Refactor __of_node_alloc() into __of_node_dup() Add a node argument to __of_node_alloc() and rename it to __of_node_dup() so that it can also be used to duplicate a node with its properties. This is important for the overlay code so that it can create new nodes without using separate changeset items for every single property. At the same time rework the overlay code to use the new function and drop the extra changeset items. Signed-off-by: Grant Likely --- drivers/of/dynamic.c | 40 +++++++++++++++++++++++++++++----------- drivers/of/of_private.h | 2 +- drivers/of/unittest.c | 14 ++++++++++---- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index af1b1ecd6a3d..661ad2f5c00c 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -272,15 +272,16 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) } /** - * __of_node_alloc() - Create an empty device node dynamically. - * @full_name: Full name of the new device node + * __of_node_dup() - Duplicate or create an empty device node dynamically. + * @fmt: Format string (plus vargs) for new full name of the device node * - * Create an empty device tree node, suitable for further modification. - * The node data are dynamically allocated and all the node flags - * have the OF_DYNAMIC & OF_DETACHED bits set. - * Returns the newly allocated node or NULL on out of memory error. + * Create an device tree node, either by duplicating an empty node or by allocating + * an empty one suitable for further modification. The node data are + * dynamically allocated and all the node flags have the OF_DYNAMIC & + * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of + * memory error. */ -struct device_node *__of_node_alloc(const char *fmt, ...) +struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...) { va_list vargs; struct device_node *node; @@ -291,17 +292,34 @@ struct device_node *__of_node_alloc(const char *fmt, ...) va_start(vargs, fmt); node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs); va_end(vargs); - if (!node->full_name) - goto err_free; + if (!node->full_name) { + kfree(node); + return NULL; + } of_node_set_flag(node, OF_DYNAMIC); of_node_set_flag(node, OF_DETACHED); of_node_init(node); + /* Iterate over and duplicate all properties */ + if (np) { + struct property *pp, *new_pp; + for_each_property_of_node(np, pp) { + new_pp = __of_prop_dup(pp, GFP_KERNEL); + if (!new_pp) + goto err_prop; + if (__of_add_property(node, new_pp)) { + kfree(new_pp->name); + kfree(new_pp->value); + kfree(new_pp); + goto err_prop; + } + } + } return node; - err_free: - kfree(node); + err_prop: + of_node_put(node); /* Frees the node and properties */ return NULL; } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 618abcad307e..8e882e706cd8 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -61,7 +61,7 @@ static inline int of_property_notify(int action, struct device_node *np, * own the devtree lock or work on detached trees only. */ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); -__printf(1, 2) struct device_node *__of_node_alloc(const char *fmt, ...); +__printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...); extern const void *__of_get_property(const struct device_node *np, const char *name, int *lenp); diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 7634a17af1d5..1720b039cac7 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -445,15 +445,15 @@ static void __init of_selftest_changeset(void) struct property *ppadd, padd = { .name = "prop-add", .length = 0, .value = "" }; struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" }; struct property *ppremove; - struct device_node *n1, *n2, *n21, *nremove, *parent; + struct device_node *n1, *n2, *n21, *nremove, *parent, *np; struct of_changeset chgset; of_changeset_init(&chgset); - n1 = __of_node_alloc("/testcase-data/changeset/n1"); + n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1"); selftest(n1, "testcase setup failure\n"); - n2 = __of_node_alloc("/testcase-data/changeset/n2"); + n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2"); selftest(n2, "testcase setup failure\n"); - n21 = __of_node_alloc("/testcase-data/changeset/n2/n21"); + n21 = __of_node_dup(NULL, "%s/%s", "/testcase-data/changeset/n2", "n21"); selftest(n21, "testcase setup failure %p\n", n21); nremove = of_find_node_by_path("/testcase-data/changeset/node-remove"); selftest(nremove, "testcase setup failure\n"); @@ -481,6 +481,12 @@ static void __init of_selftest_changeset(void) selftest(!of_changeset_apply(&chgset), "apply failed\n"); mutex_unlock(&of_mutex); + /* Make sure node names are constructed correctly */ + selftest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), + "'%s' not added\n", n21->full_name); + if (np) + of_node_put(np); + mutex_lock(&of_mutex); selftest(!of_changeset_revert(&chgset), "revert failed\n"); mutex_unlock(&of_mutex); -- GitLab From da56d04c806a3e9986c66a061d7363ca3157c37b Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:33:49 +0200 Subject: [PATCH 6310/9457] of/resolver: Switch to new local fixups format. The original resolver format is way too cryptic, switch to using a tree based format that gets rid of repetitions, is more compact and readable. At the same time, update the selftests to using the new local fixups format. Signed-off-by: Pantelis Antoniou [grant.likely: Squashed in testcase changes and merged similar functions] Signed-off-by: Grant Likely --- drivers/of/resolver.c | 128 ++++++++++++++++++++----- drivers/of/unittest-data/testcases.dts | 61 +++++++----- 2 files changed, 139 insertions(+), 50 deletions(-) diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index aed7959f800d..640eb4cb46e3 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -111,7 +111,8 @@ static void __of_adjust_tree_phandles(struct device_node *node, __of_adjust_tree_phandles(child, phandle_delta); } -static int __of_adjust_phandle_ref(struct device_node *node, struct property *rprop, int value, bool is_delta) +static int __of_adjust_phandle_ref(struct device_node *node, + struct property *rprop, int value) { phandle phandle; struct device_node *refnode; @@ -181,7 +182,7 @@ static int __of_adjust_phandle_ref(struct device_node *node, struct property *rp goto err_fail; } - phandle = is_delta ? be32_to_cpup(sprop->value + offset) + value : value; + phandle = value; *(__be32 *)(sprop->value + offset) = cpu_to_be32(phandle); } @@ -190,36 +191,97 @@ static int __of_adjust_phandle_ref(struct device_node *node, struct property *rp return err; } +/* compare nodes taking into account that 'name' strips out the @ part */ +static int __of_node_name_cmp(const struct device_node *dn1, + const struct device_node *dn2) +{ + const char *n1 = strrchr(dn1->full_name, '/') ? : "/"; + const char *n2 = strrchr(dn2->full_name, '/') ? : "/"; + + return of_node_cmp(n1, n2); +} + /* * Adjust the local phandle references by the given phandle delta. - * Assumes the existances of a __local_fixups__ node at the root - * of the tree. Does not take any devtree locks so make sure you - * call this on a tree which is at the detached state. + * Assumes the existances of a __local_fixups__ node at the root. + * Assumes that __of_verify_tree_phandle_references has been called. + * Does not take any devtree locks so make sure you call this on a tree + * which is at the detached state. */ static int __of_adjust_tree_phandle_references(struct device_node *node, - int phandle_delta) + struct device_node *target, int phandle_delta) { - struct device_node *child; - struct property *rprop; - int err; - - /* locate the symbols & fixups nodes on resolve */ - for_each_child_of_node(node, child) - if (of_node_cmp(child->name, "__local_fixups__") == 0) - break; + struct device_node *child, *childtarget; + struct property *rprop, *sprop; + int err, i, count; + unsigned int off; + phandle phandle; - /* no local fixups */ - if (!child) + if (node == NULL) return 0; - /* find the local fixups property */ - for_each_property_of_node(child, rprop) { + for_each_property_of_node(node, rprop) { + /* skip properties added automatically */ - if (of_prop_cmp(rprop->name, "name") == 0) + if (of_prop_cmp(rprop->name, "name") == 0 || + of_prop_cmp(rprop->name, "phandle") == 0 || + of_prop_cmp(rprop->name, "linux,phandle") == 0) continue; - err = __of_adjust_phandle_ref(node, rprop, phandle_delta, true); - if (err) + if ((rprop->length % 4) != 0 || rprop->length == 0) { + pr_err("%s: Illegal property (size) '%s' @%s\n", + __func__, rprop->name, node->full_name); + return -EINVAL; + } + count = rprop->length / sizeof(__be32); + + /* now find the target property */ + for_each_property_of_node(target, sprop) { + if (of_prop_cmp(sprop->name, rprop->name) == 0) + break; + } + + if (sprop == NULL) { + pr_err("%s: Could not find target property '%s' @%s\n", + __func__, rprop->name, node->full_name); + return -EINVAL; + } + + for (i = 0; i < count; i++) { + off = be32_to_cpu(((__be32 *)rprop->value)[i]); + /* make sure the offset doesn't overstep (even wrap) */ + if (off >= sprop->length || + (off + 4) > sprop->length) { + pr_err("%s: Illegal property '%s' @%s\n", + __func__, rprop->name, + node->full_name); + return -EINVAL; + } + + if (phandle_delta) { + /* adjust */ + phandle = be32_to_cpu(*(__be32 *)(sprop->value + off)); + phandle += phandle_delta; + *(__be32 *)(sprop->value + off) = cpu_to_be32(phandle); + } + } + } + + for_each_child_of_node(node, child) { + + for_each_child_of_node(target, childtarget) + if (__of_node_name_cmp(child, childtarget) == 0) + break; + + if (!childtarget) { + pr_err("%s: Could not find target child '%s' @%s\n", + __func__, child->name, node->full_name); + return -EINVAL; + } + + err = __of_adjust_tree_phandle_references(child, childtarget, + phandle_delta); + if (err != 0) return err; } @@ -241,7 +303,7 @@ static int __of_adjust_tree_phandle_references(struct device_node *node, */ int of_resolve_phandles(struct device_node *resolve) { - struct device_node *child, *refnode; + struct device_node *child, *childroot, *refnode; struct device_node *root_sym, *resolve_sym, *resolve_fix; struct property *rprop; const char *refpath; @@ -255,9 +317,23 @@ int of_resolve_phandles(struct device_node *resolve) /* first we need to adjust the phandles */ phandle_delta = of_get_tree_max_phandle() + 1; __of_adjust_tree_phandles(resolve, phandle_delta); - err = __of_adjust_tree_phandle_references(resolve, phandle_delta); - if (err != 0) - return err; + + /* locate the local fixups */ + childroot = NULL; + for_each_child_of_node(resolve, childroot) + if (of_node_cmp(childroot->name, "__local_fixups__") == 0) + break; + + if (childroot != NULL) { + /* resolve root is guaranteed to be the '/' */ + err = __of_adjust_tree_phandle_references(childroot, + resolve, 0); + if (err != 0) + return err; + + BUG_ON(__of_adjust_tree_phandle_references(childroot, + resolve, phandle_delta)); + } root_sym = NULL; resolve_sym = NULL; @@ -322,7 +398,7 @@ int of_resolve_phandles(struct device_node *resolve) pr_debug("%s: %s phandle is 0x%08x\n", __func__, rprop->name, phandle); - err = __of_adjust_phandle_ref(resolve, rprop, phandle, false); + err = __of_adjust_phandle_ref(resolve, rprop, phandle); if (err) break; } diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts index 6994e15c24bf..b6bc41b2a185 100644 --- a/drivers/of/unittest-data/testcases.dts +++ b/drivers/of/unittest-data/testcases.dts @@ -23,28 +23,41 @@ * this a kernel-internal data format. */ / { __local_fixups__ { - fixup = "/testcase-data/testcase-device2:interrupt-parent:0", - "/testcase-data/testcase-device1:interrupt-parent:0", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:60", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:52", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:44", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:36", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:24", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:8", - "/testcase-data/interrupts/interrupts-extended0:interrupts-extended:0", - "/testcase-data/interrupts/interrupts1:interrupt-parent:0", - "/testcase-data/interrupts/interrupts0:interrupt-parent:0", - "/testcase-data/interrupts/intmap1:interrupt-map:12", - "/testcase-data/interrupts/intmap0:interrupt-map:52", - "/testcase-data/interrupts/intmap0:interrupt-map:36", - "/testcase-data/interrupts/intmap0:interrupt-map:16", - "/testcase-data/interrupts/intmap0:interrupt-map:4", - "/testcase-data/phandle-tests/consumer-a:phandle-list-bad-args:12", - "/testcase-data/phandle-tests/consumer-a:phandle-list-bad-args:0", - "/testcase-data/phandle-tests/consumer-a:phandle-list:56", - "/testcase-data/phandle-tests/consumer-a:phandle-list:52", - "/testcase-data/phandle-tests/consumer-a:phandle-list:40", - "/testcase-data/phandle-tests/consumer-a:phandle-list:24", - "/testcase-data/phandle-tests/consumer-a:phandle-list:8", - "/testcase-data/phandle-tests/consumer-a:phandle-list:0"; + testcase-data { + phandle-tests { + consumer-a { + phandle-list = <0x00000000 0x00000008 + 0x00000018 0x00000028 + 0x00000034 0x00000038>; + phandle-list-bad-args = <0x00000000 0x0000000c>; + }; + }; + interrupts { + intmap0 { + interrupt-map = <0x00000004 0x00000010 + 0x00000024 0x00000034>; + }; + intmap1 { + interrupt-map = <0x0000000c>; + }; + interrupts0 { + interrupt-parent = <0x00000000>; + }; + interrupts1 { + interrupt-parent = <0x00000000>; + }; + interrupts-extended0 { + interrupts-extended = <0x00000000 0x00000008 + 0x00000018 0x00000024 + 0x0000002c 0x00000034 + 0x0000003c>; + }; + }; + testcase-device1 { + interrupt-parent = <0x00000000>; + }; + testcase-device2 { + interrupt-parent = <0x00000000>; + }; + }; }; }; -- GitLab From b53a2340d0d30468b7315992ba77fe188c3bc5c8 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:33:53 +0200 Subject: [PATCH 6311/9457] of/reconfig: Add of_reconfig_get_state_change() of notifier helper. Introduce of_reconfig_get_state_change() which allows an of notifier to query about device state changes. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely --- drivers/of/dynamic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 7 ++++ 2 files changed, 103 insertions(+) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 661ad2f5c00c..6659c39ab3aa 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -85,6 +85,102 @@ int of_reconfig_notify(unsigned long action, void *p) return notifier_to_errno(rc); } +/* + * of_reconfig_get_state_change() - Returns new state of device + * @action - action of the of notifier + * @arg - argument of the of notifier + * + * Returns the new state of a device based on the notifier used. + * Returns 0 on device going from enabled to disabled, 1 on device + * going from disabled to enabled and -1 on no change. + */ +int of_reconfig_get_state_change(unsigned long action, void *arg) +{ + struct device_node *dn; + struct property *prop, *old_prop; + struct of_prop_reconfig *pr; + int is_status, status_state, old_status_state, prev_state, new_state; + + /* figure out if a device should be created or destroyed */ + dn = NULL; + prop = old_prop = NULL; + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + case OF_RECONFIG_DETACH_NODE: + dn = arg; + prop = of_find_property(dn, "status", NULL); + break; + case OF_RECONFIG_ADD_PROPERTY: + case OF_RECONFIG_REMOVE_PROPERTY: + pr = arg; + dn = pr->dn; + prop = pr->prop; + break; + case OF_RECONFIG_UPDATE_PROPERTY: + pr = arg; + dn = pr->dn; + prop = pr->prop; + old_prop = pr->old_prop; + break; + default: + return OF_RECONFIG_NO_CHANGE; + } + + is_status = 0; + status_state = -1; + old_status_state = -1; + prev_state = -1; + new_state = -1; + + if (prop && !strcmp(prop->name, "status")) { + is_status = 1; + status_state = !strcmp(prop->value, "okay") || + !strcmp(prop->value, "ok"); + if (old_prop) + old_status_state = !strcmp(old_prop->value, "okay") || + !strcmp(old_prop->value, "ok"); + } + + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + prev_state = 0; + /* -1 & 0 status either missing or okay */ + new_state = status_state != 0; + break; + case OF_RECONFIG_DETACH_NODE: + /* -1 & 0 status either missing or okay */ + prev_state = status_state != 0; + new_state = 0; + break; + case OF_RECONFIG_ADD_PROPERTY: + if (is_status) { + /* no status property -> enabled (legacy) */ + prev_state = 1; + new_state = status_state; + } + break; + case OF_RECONFIG_REMOVE_PROPERTY: + if (is_status) { + prev_state = status_state; + /* no status property -> enabled (legacy) */ + new_state = 1; + } + break; + case OF_RECONFIG_UPDATE_PROPERTY: + if (is_status) { + prev_state = old_status_state != 0; + new_state = status_state != 0; + } + break; + } + + if (prev_state == new_state) + return OF_RECONFIG_NO_CHANGE; + + return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE; +} +EXPORT_SYMBOL_GPL(of_reconfig_get_state_change); + int of_property_notify(int action, struct device_node *np, struct property *prop, struct property *oldprop) { diff --git a/include/linux/of.h b/include/linux/of.h index 27635c89d8c2..8e3a264c869c 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -327,6 +327,7 @@ struct of_prop_reconfig { extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_unregister(struct notifier_block *); extern int of_reconfig_notify(unsigned long, void *); +extern int of_reconfig_get_state_change(unsigned long action, void *arg); extern int of_attach_node(struct device_node *); extern int of_detach_node(struct device_node *); @@ -887,6 +888,12 @@ struct of_changeset { struct list_head entries; }; +enum of_reconfig_change { + OF_RECONFIG_NO_CHANGE = 0, + OF_RECONFIG_CHANGE_ADD, + OF_RECONFIG_CHANGE_REMOVE, +}; + #ifdef CONFIG_OF_DYNAMIC extern void of_changeset_init(struct of_changeset *ocs); extern void of_changeset_destroy(struct of_changeset *ocs); -- GitLab From f6892d193fb9d694a1b50550649ba6e82f8abec1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 21 Nov 2014 15:14:58 +0000 Subject: [PATCH 6312/9457] of/reconfig: Add empty stubs for the of_reconfig methods To simplify subsystem setup code, make empty stubs for the of_reconfig_*() methods. This is particularly useful for registering and unregistering the notifiers so that it doesn't impact the flow of the subsystem setup code. Signed-off-by: Grant Likely --- include/linux/of.h | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/include/linux/of.h b/include/linux/of.h index 8e3a264c869c..b59ee21933a4 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -324,11 +324,6 @@ struct of_prop_reconfig { struct property *old_prop; }; -extern int of_reconfig_notifier_register(struct notifier_block *); -extern int of_reconfig_notifier_unregister(struct notifier_block *); -extern int of_reconfig_notify(unsigned long, void *); -extern int of_reconfig_get_state_change(unsigned long action, void *arg); - extern int of_attach_node(struct device_node *); extern int of_detach_node(struct device_node *); @@ -895,6 +890,11 @@ enum of_reconfig_change { }; #ifdef CONFIG_OF_DYNAMIC +extern int of_reconfig_notifier_register(struct notifier_block *); +extern int of_reconfig_notifier_unregister(struct notifier_block *); +extern int of_reconfig_notify(unsigned long, void *); +extern int of_reconfig_get_state_change(unsigned long action, void *arg); + extern void of_changeset_init(struct of_changeset *ocs); extern void of_changeset_destroy(struct of_changeset *ocs); extern int of_changeset_apply(struct of_changeset *ocs); @@ -932,7 +932,24 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, { return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); } -#endif +#else /* CONFIG_OF_DYNAMIC */ +static inline int of_reconfig_notifier_register(struct notifier_block *nb) +{ + return -EINVAL; +} +static inline int of_reconfig_notifier_unregister(struct notifier_block *nb) +{ + return -EINVAL; +} +static inline int of_reconfig_notify(unsigned long action, void *arg) +{ + return -EINVAL; +} +static inline int of_reconfig_get_state_change(unsigned long action, void *arg) +{ + return -EINVAL; +} +#endif /* CONFIG_OF_DYNAMIC */ /* CONFIG_OF_RESOLVE api */ extern int of_resolve_phandles(struct device_node *tree); -- GitLab From 00aa37206e1a54dae61a0dba96bf2ee0938b99d7 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 14 Nov 2014 14:34:55 +0000 Subject: [PATCH 6313/9457] of/reconfig: Add debug output for OF_RECONFIG notifiers Add some additional debug output to cover OF_RECONFIG notifier activity. At the same time, refactor the changeset debug output to use the same strings as the notifier debug output. Signed-off-by: Grant Likely --- drivers/of/dynamic.c | 48 +++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 6659c39ab3aa..cc106529dca8 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -77,10 +77,38 @@ int of_reconfig_notifier_unregister(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister); +#ifdef DEBUG +const char *action_names[] = { + [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE", + [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE", + [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY", + [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY", + [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY", +}; +#endif + int of_reconfig_notify(unsigned long action, void *p) { int rc; +#ifdef DEBUG + struct device_node *dn = p; + struct of_prop_reconfig *pr = p; + + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + case OF_RECONFIG_DETACH_NODE: + pr_debug("of/notify %-15s %s\n", action_names[action], + dn->full_name); + break; + case OF_RECONFIG_ADD_PROPERTY: + case OF_RECONFIG_REMOVE_PROPERTY: + case OF_RECONFIG_UPDATE_PROPERTY: + pr_debug("of/notify %-15s %s:%s\n", action_names[action], + pr->dn->full_name, pr->prop->name); + break; + } +#endif rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); return notifier_to_errno(rc); } @@ -431,27 +459,15 @@ static void __of_changeset_entry_dump(struct of_changeset_entry *ce) { switch (ce->action) { case OF_RECONFIG_ADD_PROPERTY: - pr_debug("%p: %s %s/%s\n", - ce, "ADD_PROPERTY ", ce->np->full_name, - ce->prop->name); - break; case OF_RECONFIG_REMOVE_PROPERTY: - pr_debug("%p: %s %s/%s\n", - ce, "REMOVE_PROPERTY", ce->np->full_name, - ce->prop->name); - break; case OF_RECONFIG_UPDATE_PROPERTY: - pr_debug("%p: %s %s/%s\n", - ce, "UPDATE_PROPERTY", ce->np->full_name, - ce->prop->name); + pr_debug("of/cset<%p> %-15s %s/%s\n", ce, action_names[ce->action], + ce->np->full_name, ce->prop->name); break; case OF_RECONFIG_ATTACH_NODE: - pr_debug("%p: %s %s\n", - ce, "ATTACH_NODE ", ce->np->full_name); - break; case OF_RECONFIG_DETACH_NODE: - pr_debug("%p: %s %s\n", - ce, "DETACH_NODE ", ce->np->full_name); + pr_debug("of/cset<%p> %-15s %s\n", ce, action_names[ce->action], + ce->np->full_name); break; } } -- GitLab From f5242e5a883bf1c1aba6bfd87b85e7dda0e62191 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 24 Nov 2014 17:58:01 +0000 Subject: [PATCH 6314/9457] of/reconfig: Always use the same structure for notifiers The OF_RECONFIG notifier callback uses a different structure depending on whether it is a node change or a property change. This is silly, and not very safe. Rework the code to use the same data structure regardless of the type of notifier. Signed-off-by: Grant Likely Cc: Benjamin Herrenschmidt Cc: Rob Herring Cc: Pantelis Antoniou Cc: --- arch/powerpc/mm/numa.c | 3 +- arch/powerpc/platforms/pseries/hotplug-cpu.c | 7 ++-- .../platforms/pseries/hotplug-memory.c | 15 ++++--- arch/powerpc/platforms/pseries/iommu.c | 5 ++- arch/powerpc/platforms/pseries/setup.c | 5 ++- drivers/crypto/nx/nx-842.c | 4 +- drivers/of/dynamic.c | 41 ++++++++++--------- include/linux/of.h | 23 ++++++----- 8 files changed, 54 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b9d1dfdbe5bb..9fe6002c1d5a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1711,12 +1711,11 @@ static void stage_topology_update(int core_id) static int dt_update_callback(struct notifier_block *nb, unsigned long action, void *data) { - struct of_prop_reconfig *update; + struct of_reconfig_data *update = data; int rc = NOTIFY_DONE; switch (action) { case OF_RECONFIG_UPDATE_PROPERTY: - update = (struct of_prop_reconfig *)data; if (!of_prop_cmp(update->dn->type, "cpu") && !of_prop_cmp(update->prop->name, "ibm,associativity")) { u32 core_id; diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 5c375f93c669..f30cf4d136a4 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -340,16 +340,17 @@ static void pseries_remove_processor(struct device_node *np) } static int pseries_smp_notifier(struct notifier_block *nb, - unsigned long action, void *node) + unsigned long action, void *data) { + struct of_reconfig_data *rd = data; int err = 0; switch (action) { case OF_RECONFIG_ATTACH_NODE: - err = pseries_add_processor(node); + err = pseries_add_processor(rd->dn); break; case OF_RECONFIG_DETACH_NODE: - pseries_remove_processor(node); + pseries_remove_processor(rd->dn); break; } return notifier_from_errno(err); diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 3c4c0dcd90d3..1bbb78fab530 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -183,7 +183,7 @@ static int pseries_add_mem_node(struct device_node *np) return (ret < 0) ? -EINVAL : 0; } -static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) +static int pseries_update_drconf_memory(struct of_reconfig_data *pr) { struct of_drconf_cell *new_drmem, *old_drmem; unsigned long memblock_size; @@ -232,22 +232,21 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) } static int pseries_memory_notifier(struct notifier_block *nb, - unsigned long action, void *node) + unsigned long action, void *data) { - struct of_prop_reconfig *pr; + struct of_reconfig_data *rd = data; int err = 0; switch (action) { case OF_RECONFIG_ATTACH_NODE: - err = pseries_add_mem_node(node); + err = pseries_add_mem_node(rd->dn); break; case OF_RECONFIG_DETACH_NODE: - err = pseries_remove_mem_node(node); + err = pseries_remove_mem_node(rd->dn); break; case OF_RECONFIG_UPDATE_PROPERTY: - pr = (struct of_prop_reconfig *)node; - if (!strcmp(pr->prop->name, "ibm,dynamic-memory")) - err = pseries_update_drconf_memory(pr); + if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) + err = pseries_update_drconf_memory(rd); break; } return notifier_from_errno(err); diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index e32e00976a94..3e5bfdafee63 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1251,10 +1251,11 @@ static struct notifier_block iommu_mem_nb = { .notifier_call = iommu_mem_notifier, }; -static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) +static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data) { int err = NOTIFY_OK; - struct device_node *np = node; + struct of_reconfig_data *rd = data; + struct device_node *np = rd->dn; struct pci_dn *pci = PCI_DN(np); struct direct_window *window; diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 125c589eeef5..ed8a90022a3d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -251,9 +251,10 @@ static void __init pseries_discover_pic(void) " interrupt-controller\n"); } -static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) +static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data) { - struct device_node *np = node; + struct of_reconfig_data *rd = data; + struct device_node *np = rd->dn; struct pci_dn *pci = NULL; int err = NOTIFY_OK; diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index 061407d59520..887196e9b50c 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -1009,9 +1009,9 @@ static int nx842_OF_upd(struct property *new_prop) * notifier_to_errno() to decode this value */ static int nx842_OF_notifier(struct notifier_block *np, unsigned long action, - void *update) + void *data) { - struct of_prop_reconfig *upd = update; + struct of_reconfig_data *upd = data; struct nx842_devdata *local_devdata; struct device_node *node = NULL; diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index cc106529dca8..3351ef408125 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -87,18 +87,17 @@ const char *action_names[] = { }; #endif -int of_reconfig_notify(unsigned long action, void *p) +int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) { int rc; #ifdef DEBUG - struct device_node *dn = p; - struct of_prop_reconfig *pr = p; + struct of_reconfig_data *pr = p; switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: pr_debug("of/notify %-15s %s\n", action_names[action], - dn->full_name); + pr->dn->full_name); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: @@ -122,31 +121,22 @@ int of_reconfig_notify(unsigned long action, void *p) * Returns 0 on device going from enabled to disabled, 1 on device * going from disabled to enabled and -1 on no change. */ -int of_reconfig_get_state_change(unsigned long action, void *arg) +int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) { - struct device_node *dn; - struct property *prop, *old_prop; - struct of_prop_reconfig *pr; + struct property *prop, *old_prop = NULL; int is_status, status_state, old_status_state, prev_state, new_state; /* figure out if a device should be created or destroyed */ - dn = NULL; - prop = old_prop = NULL; switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: - dn = arg; - prop = of_find_property(dn, "status", NULL); + prop = of_find_property(pr->dn, "status", NULL); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: - pr = arg; - dn = pr->dn; prop = pr->prop; break; case OF_RECONFIG_UPDATE_PROPERTY: - pr = arg; - dn = pr->dn; prop = pr->prop; old_prop = pr->old_prop; break; @@ -212,7 +202,7 @@ EXPORT_SYMBOL_GPL(of_reconfig_get_state_change); int of_property_notify(int action, struct device_node *np, struct property *prop, struct property *oldprop) { - struct of_prop_reconfig pr; + struct of_reconfig_data pr; /* only call notifiers if the node is attached */ if (!of_node_is_attached(np)) @@ -250,8 +240,12 @@ void __of_attach_node(struct device_node *np) */ int of_attach_node(struct device_node *np) { + struct of_reconfig_data rd; unsigned long flags; + memset(&rd, 0, sizeof(rd)); + rd.dn = np; + mutex_lock(&of_mutex); raw_spin_lock_irqsave(&devtree_lock, flags); __of_attach_node(np); @@ -260,7 +254,7 @@ int of_attach_node(struct device_node *np) __of_attach_node_sysfs(np); mutex_unlock(&of_mutex); - of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); + of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd); return 0; } @@ -298,9 +292,13 @@ void __of_detach_node(struct device_node *np) */ int of_detach_node(struct device_node *np) { + struct of_reconfig_data rd; unsigned long flags; int rc = 0; + memset(&rd, 0, sizeof(rd)); + rd.dn = np; + mutex_lock(&of_mutex); raw_spin_lock_irqsave(&devtree_lock, flags); __of_detach_node(np); @@ -309,7 +307,7 @@ int of_detach_node(struct device_node *np) __of_detach_node_sysfs(np); mutex_unlock(&of_mutex); - of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); + of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); return rc; } @@ -505,6 +503,7 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) { + struct of_reconfig_data rd; struct of_changeset_entry ce_inverted; int ret; @@ -516,7 +515,9 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve switch (ce->action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: - ret = of_reconfig_notify(ce->action, ce->np); + memset(&rd, 0, sizeof(rd)); + rd.dn = ce->np; + ret = of_reconfig_notify(ce->action, &rd); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: diff --git a/include/linux/of.h b/include/linux/of.h index b59ee21933a4..fe1dec87fd68 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -73,6 +73,12 @@ struct of_phandle_args { uint32_t args[MAX_PHANDLE_ARGS]; }; +struct of_reconfig_data { + struct device_node *dn; + struct property *prop; + struct property *old_prop; +}; + /* initialize a node */ extern struct kobj_type of_node_ktype; static inline void of_node_init(struct device_node *node) @@ -318,12 +324,6 @@ extern int of_update_property(struct device_node *np, struct property *newprop); #define OF_RECONFIG_REMOVE_PROPERTY 0x0004 #define OF_RECONFIG_UPDATE_PROPERTY 0x0005 -struct of_prop_reconfig { - struct device_node *dn; - struct property *prop; - struct property *old_prop; -}; - extern int of_attach_node(struct device_node *); extern int of_detach_node(struct device_node *); @@ -892,8 +892,9 @@ enum of_reconfig_change { #ifdef CONFIG_OF_DYNAMIC extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_unregister(struct notifier_block *); -extern int of_reconfig_notify(unsigned long, void *); -extern int of_reconfig_get_state_change(unsigned long action, void *arg); +extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd); +extern int of_reconfig_get_state_change(unsigned long action, + struct of_reconfig_data *arg); extern void of_changeset_init(struct of_changeset *ocs); extern void of_changeset_destroy(struct of_changeset *ocs); @@ -941,11 +942,13 @@ static inline int of_reconfig_notifier_unregister(struct notifier_block *nb) { return -EINVAL; } -static inline int of_reconfig_notify(unsigned long action, void *arg) +static inline int of_reconfig_notify(unsigned long action, + struct of_reconfig_data *arg) { return -EINVAL; } -static inline int of_reconfig_get_state_change(unsigned long action, void *arg) +static inline int of_reconfig_get_state_change(unsigned long action, + struct of_reconfig_data *arg) { return -EINVAL; } -- GitLab From 801d728c10db4b28e01590b46bf1f0df930760cc Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:36:01 +0200 Subject: [PATCH 6315/9457] of/reconfig: Add OF_DYNAMIC notifier for platform_bus_type Add OF notifier handler needed for creating/destroying platform devices according to dynamic runtime changes in the DT live tree. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely --- drivers/base/platform.c | 1 + drivers/of/platform.c | 55 +++++++++++++++++++++++++++++++++++++ include/linux/of_platform.h | 6 ++++ 3 files changed, 62 insertions(+) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index b2afc29403f9..233ececd15a3 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1006,6 +1006,7 @@ int __init platform_bus_init(void) error = bus_register(&platform_bus_type); if (error) device_unregister(&platform_bus); + of_platform_register_reconfig_notifier(); return error; } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 656cccf0e680..cd87a36495be 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -550,4 +550,59 @@ void of_platform_depopulate(struct device *parent) } EXPORT_SYMBOL_GPL(of_platform_depopulate); +#ifdef CONFIG_OF_DYNAMIC +static int of_platform_notify(struct notifier_block *nb, + unsigned long action, void *arg) +{ + struct of_reconfig_data *rd = arg; + struct platform_device *pdev_parent, *pdev; + bool children_left; + + switch (of_reconfig_get_state_change(action, rd)) { + case OF_RECONFIG_CHANGE_ADD: + /* verify that the parent is a bus */ + if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) + return NOTIFY_OK; /* not for us */ + + /* pdev_parent may be NULL when no bus platform device */ + pdev_parent = of_find_device_by_node(rd->dn->parent); + pdev = of_platform_device_create(rd->dn, NULL, + pdev_parent ? &pdev_parent->dev : NULL); + of_dev_put(pdev_parent); + + if (pdev == NULL) { + pr_err("%s: failed to create for '%s'\n", + __func__, rd->dn->full_name); + /* of_platform_device_create tosses the error code */ + return notifier_from_errno(-EINVAL); + } + break; + + case OF_RECONFIG_CHANGE_REMOVE: + /* find our device by node */ + pdev = of_find_device_by_node(rd->dn); + if (pdev == NULL) + return NOTIFY_OK; /* no? not meant for us */ + + /* unregister takes one ref away */ + of_platform_device_destroy(&pdev->dev, &children_left); + + /* and put the reference of the find */ + of_dev_put(pdev); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block platform_of_notifier = { + .notifier_call = of_platform_notify, +}; + +void of_platform_register_reconfig_notifier(void) +{ + WARN_ON(of_reconfig_notifier_register(&platform_of_notifier)); +} +#endif /* CONFIG_OF_DYNAMIC */ + #endif /* CONFIG_OF_ADDRESS */ diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index c2b0627a2317..8a860f096c35 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -84,4 +84,10 @@ static inline int of_platform_populate(struct device_node *root, static inline void of_platform_depopulate(struct device *parent) { } #endif +#ifdef CONFIG_OF_DYNAMIC +extern void of_platform_register_reconfig_notifier(void); +#else +static inline void of_platform_register_reconfig_notifier(void) { } +#endif + #endif /* _LINUX_OF_PLATFORM_H */ -- GitLab From 7518b5890d8ac366faa2326ce2356ef6392ce63d Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:35:58 +0200 Subject: [PATCH 6316/9457] of/overlay: Introduce DT overlay support Overlays are a method to dynamically modify part of the kernel's device tree with dynamically loaded data. Add the core functionality to parse, apply and remove an overlay changeset. The core functionality takes care of managing the overlay data format and performing the add and remove. Drivers are expected to use the overlay functionality to support custom expansion busses commonly found on consumer development boards like the BeagleBone or Raspberry Pi. The overlay code uses CONFIG_OF_DYNAMIC changesets to perform the low level work of modifying the devicetree. Documentation about internal and APIs is provided in Documentation/devicetree/overlay-notes.txt v2: - Switch from __of_node_alloc() to __of_node_dup() - Documentation fixups - Remove 2-pass processing of properties - Remove separate ov_lock; just use the DT mutex. v1: - Drop delete capability using '-' prefix. The '-' prefixed names are valid properties and nodes and there is no need for it just yet. - Do not update special properties - name & phandle ones. - Change order of node attachment, so that the special property update works. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely --- Documentation/devicetree/overlay-notes.txt | 133 +++++ drivers/of/Kconfig | 7 + drivers/of/Makefile | 1 + drivers/of/overlay.c | 562 +++++++++++++++++++++ include/linux/of.h | 31 ++ 5 files changed, 734 insertions(+) create mode 100644 Documentation/devicetree/overlay-notes.txt create mode 100644 drivers/of/overlay.c diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt new file mode 100644 index 000000000000..30ae758e3eef --- /dev/null +++ b/Documentation/devicetree/overlay-notes.txt @@ -0,0 +1,133 @@ +Device Tree Overlay Notes +------------------------- + +This document describes the implementation of the in-kernel +device tree overlay functionality residing in drivers/of/overlay.c and is a +companion document to Documentation/devicetree/dt-object-internal.txt[1] & +Documentation/devicetree/dynamic-resolution-notes.txt[2] + +How overlays work +----------------- + +A Device Tree's overlay purpose is to modify the kernel's live tree, and +have the modification affecting the state of the the kernel in a way that +is reflecting the changes. +Since the kernel mainly deals with devices, any new device node that result +in an active device should have it created while if the device node is either +disabled or removed all together, the affected device should be deregistered. + +Lets take an example where we have a foo board with the following base tree +which is taken from [1]. + +---- foo.dts ----------------------------------------------------------------- + /* FOO platform */ + / { + compatible = "corp,foo"; + + /* shared resources */ + res: res { + }; + + /* On chip peripherals */ + ocp: ocp { + /* peripherals that are always instantiated */ + peripheral1 { ... }; + } + }; +---- foo.dts ----------------------------------------------------------------- + +The overlay bar.dts, when loaded (and resolved as described in [2]) should + +---- bar.dts ----------------------------------------------------------------- +/plugin/; /* allow undefined label references and record them */ +/ { + .... /* various properties for loader use; i.e. part id etc. */ + fragment@0 { + target = <&ocp>; + __overlay__ { + /* bar peripheral */ + bar { + compatible = "corp,bar"; + ... /* various properties and child nodes */ + } + }; + }; +}; +---- bar.dts ----------------------------------------------------------------- + +result in foo+bar.dts + +---- foo+bar.dts ------------------------------------------------------------- + /* FOO platform + bar peripheral */ + / { + compatible = "corp,foo"; + + /* shared resources */ + res: res { + }; + + /* On chip peripherals */ + ocp: ocp { + /* peripherals that are always instantiated */ + peripheral1 { ... }; + + /* bar peripheral */ + bar { + compatible = "corp,bar"; + ... /* various properties and child nodes */ + } + } + }; +---- foo+bar.dts ------------------------------------------------------------- + +As a result of the the overlay, a new device node (bar) has been created +so a bar platform device will be registered and if a matching device driver +is loaded the device will be created as expected. + +Overlay in-kernel API +-------------------------------- + +The API is quite easy to use. + +1. Call of_overlay_create() to create and apply an overlay. The return value +is a cookie identifying this overlay. + +2. Call of_overlay_destroy() to remove and cleanup the overlay previously +created via the call to of_overlay_create(). Removal of an overlay that +is stacked by another will not be permitted. + +Finally, if you need to remove all overlays in one-go, just call +of_overlay_destroy_all() which will remove every single one in the correct +order. + +Overlay DTS Format +------------------ + +The DTS of an overlay should have the following format: + +{ + /* ignored properties by the overlay */ + + fragment@0 { /* first child node */ + + target=; /* phandle target of the overlay */ + or + target-path="/path"; /* target path of the overlay */ + + __overlay__ { + property-a; /* add property-a to the target */ + node-a { /* add to an existing, or create a node-a */ + ... + }; + }; + } + fragment@1 { /* second child node */ + ... + }; + /* more fragments follow */ +} + +Using the non-phandle based target method allows one to use a base DT which does +not contain a __symbols__ node, i.e. it was not compiled with the -@ option. +The __symbols__ node is only required for the target= method, since it +contains the information required to map from a phandle to a tree location. diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index fbe8f8d418f7..18b2e2539f84 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -84,4 +84,11 @@ config OF_RESERVED_MEM config OF_RESOLVE bool +config OF_OVERLAY + bool + depends on OF + select OF_DYNAMIC + select OF_DEVICE + select OF_RESOLVE + endmenu # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index d90553fcd37f..7563f36c71db 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_MTD) += of_mtd.o obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o obj-$(CONFIG_OF_RESOLVE) += resolver.o +obj-$(CONFIG_OF_OVERLAY) += overlay.o CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt CFLAGS_fdt_address.o = -I$(src)/../../scripts/dtc/libfdt diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c new file mode 100644 index 000000000000..ea63fbd228ed --- /dev/null +++ b/drivers/of/overlay.c @@ -0,0 +1,562 @@ +/* + * Functions for working with device tree overlays + * + * Copyright (C) 2012 Pantelis Antoniou + * Copyright (C) 2012 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ +#undef DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "of_private.h" + +/** + * struct of_overlay_info - Holds a single overlay info + * @target: target of the overlay operation + * @overlay: pointer to the overlay contents node + * + * Holds a single overlay state, including all the overlay logs & + * records. + */ +struct of_overlay_info { + struct device_node *target; + struct device_node *overlay; +}; + +/** + * struct of_overlay - Holds a complete overlay transaction + * @node: List on which we are located + * @count: Count of ovinfo structures + * @ovinfo_tab: Overlay info table (count sized) + * @cset: Changeset to be used + * + * Holds a complete overlay transaction + */ +struct of_overlay { + int id; + struct list_head node; + int count; + struct of_overlay_info *ovinfo_tab; + struct of_changeset cset; +}; + +static int of_overlay_apply_one(struct of_overlay *ov, + struct device_node *target, const struct device_node *overlay); + +static int of_overlay_apply_single_property(struct of_overlay *ov, + struct device_node *target, struct property *prop) +{ + struct property *propn, *tprop; + + /* NOTE: Multiple changes of single properties not supported */ + tprop = of_find_property(target, prop->name, NULL); + + /* special properties are not meant to be updated (silent NOP) */ + if (of_prop_cmp(prop->name, "name") == 0 || + of_prop_cmp(prop->name, "phandle") == 0 || + of_prop_cmp(prop->name, "linux,phandle") == 0) + return 0; + + propn = __of_prop_dup(prop, GFP_KERNEL); + if (propn == NULL) + return -ENOMEM; + + /* not found? add */ + if (tprop == NULL) + return of_changeset_add_property(&ov->cset, target, propn); + + /* found? update */ + return of_changeset_update_property(&ov->cset, target, propn); +} + +static int of_overlay_apply_single_device_node(struct of_overlay *ov, + struct device_node *target, struct device_node *child) +{ + const char *cname; + struct device_node *tchild, *grandchild; + int ret = 0; + + cname = kbasename(child->full_name); + if (cname == NULL) + return -ENOMEM; + + /* NOTE: Multiple mods of created nodes not supported */ + tchild = of_get_child_by_name(target, cname); + if (tchild != NULL) { + /* apply overlay recursively */ + ret = of_overlay_apply_one(ov, tchild, child); + of_node_put(tchild); + } else { + /* create empty tree as a target */ + tchild = __of_node_dup(child, "%s/%s", target->full_name, cname); + if (!tchild) + return -ENOMEM; + + /* point to parent */ + tchild->parent = target; + + ret = of_changeset_attach_node(&ov->cset, tchild); + if (ret) + return ret; + + ret = of_overlay_apply_one(ov, tchild, child); + if (ret) + return ret; + + /* The properties are already copied, now do the child nodes */ + for_each_child_of_node(child, grandchild) { + ret = of_overlay_apply_single_device_node(ov, tchild, grandchild); + if (ret) { + pr_err("%s: Failed to apply single node @%s/%s\n", + __func__, tchild->full_name, + grandchild->name); + return ret; + } + } + } + + return ret; +} + +/* + * Apply a single overlay node recursively. + * + * Note that the in case of an error the target node is left + * in a inconsistent state. Error recovery should be performed + * by using the changeset. + */ +static int of_overlay_apply_one(struct of_overlay *ov, + struct device_node *target, const struct device_node *overlay) +{ + struct device_node *child; + struct property *prop; + int ret; + + for_each_property_of_node(overlay, prop) { + ret = of_overlay_apply_single_property(ov, target, prop); + if (ret) { + pr_err("%s: Failed to apply prop @%s/%s\n", + __func__, target->full_name, prop->name); + return ret; + } + } + + for_each_child_of_node(overlay, child) { + ret = of_overlay_apply_single_device_node(ov, target, child); + if (ret != 0) { + pr_err("%s: Failed to apply single node @%s/%s\n", + __func__, target->full_name, + child->name); + return ret; + } + } + + return 0; +} + +/** + * of_overlay_apply() - Apply @count overlays pointed at by @ovinfo_tab + * @ov: Overlay to apply + * + * Applies the overlays given, while handling all error conditions + * appropriately. Either the operation succeeds, or if it fails the + * live tree is reverted to the state before the attempt. + * Returns 0, or an error if the overlay attempt failed. + */ +static int of_overlay_apply(struct of_overlay *ov) +{ + int i, err; + + /* first we apply the overlays atomically */ + for (i = 0; i < ov->count; i++) { + struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; + + err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay); + if (err != 0) { + pr_err("%s: overlay failed '%s'\n", + __func__, ovinfo->target->full_name); + return err; + } + } + + return 0; +} + +/* + * Find the target node using a number of different strategies + * in order of preference + * + * "target" property containing the phandle of the target + * "target-path" property containing the path of the target + */ +static struct device_node *find_target_node(struct device_node *info_node) +{ + const char *path; + u32 val; + int ret; + + /* first try to go by using the target as a phandle */ + ret = of_property_read_u32(info_node, "target", &val); + if (ret == 0) + return of_find_node_by_phandle(val); + + /* now try to locate by path */ + ret = of_property_read_string(info_node, "target-path", &path); + if (ret == 0) + return of_find_node_by_path(path); + + pr_err("%s: Failed to find target for node %p (%s)\n", __func__, + info_node, info_node->name); + + return NULL; +} + +/** + * of_fill_overlay_info() - Fill an overlay info structure + * @ov Overlay to fill + * @info_node: Device node containing the overlay + * @ovinfo: Pointer to the overlay info structure to fill + * + * Fills an overlay info structure with the overlay information + * from a device node. This device node must have a target property + * which contains a phandle of the overlay target node, and an + * __overlay__ child node which has the overlay contents. + * Both ovinfo->target & ovinfo->overlay have their references taken. + * + * Returns 0 on success, or a negative error value. + */ +static int of_fill_overlay_info(struct of_overlay *ov, + struct device_node *info_node, struct of_overlay_info *ovinfo) +{ + ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__"); + if (ovinfo->overlay == NULL) + goto err_fail; + + ovinfo->target = find_target_node(info_node); + if (ovinfo->target == NULL) + goto err_fail; + + return 0; + +err_fail: + of_node_put(ovinfo->target); + of_node_put(ovinfo->overlay); + + memset(ovinfo, 0, sizeof(*ovinfo)); + return -EINVAL; +} + +/** + * of_build_overlay_info() - Build an overlay info array + * @ov Overlay to build + * @tree: Device node containing all the overlays + * + * Helper function that given a tree containing overlay information, + * allocates and builds an overlay info array containing it, ready + * for use using of_overlay_apply. + * + * Returns 0 on success with the @cntp @ovinfop pointers valid, + * while on error a negative error value is returned. + */ +static int of_build_overlay_info(struct of_overlay *ov, + struct device_node *tree) +{ + struct device_node *node; + struct of_overlay_info *ovinfo; + int cnt, err; + + /* worst case; every child is a node */ + cnt = 0; + for_each_child_of_node(tree, node) + cnt++; + + ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL); + if (ovinfo == NULL) + return -ENOMEM; + + cnt = 0; + for_each_child_of_node(tree, node) { + memset(&ovinfo[cnt], 0, sizeof(*ovinfo)); + err = of_fill_overlay_info(ov, node, &ovinfo[cnt]); + if (err == 0) + cnt++; + } + + /* if nothing filled, return error */ + if (cnt == 0) { + kfree(ovinfo); + return -ENODEV; + } + + ov->count = cnt; + ov->ovinfo_tab = ovinfo; + + return 0; +} + +/** + * of_free_overlay_info() - Free an overlay info array + * @ov Overlay to free the overlay info from + * @ovinfo_tab: Array of overlay_info's to free + * + * Releases the memory of a previously allocated ovinfo array + * by of_build_overlay_info. + * Returns 0, or an error if the arguments are bogus. + */ +static int of_free_overlay_info(struct of_overlay *ov) +{ + struct of_overlay_info *ovinfo; + int i; + + /* do it in reverse */ + for (i = ov->count - 1; i >= 0; i--) { + ovinfo = &ov->ovinfo_tab[i]; + + of_node_put(ovinfo->target); + of_node_put(ovinfo->overlay); + } + kfree(ov->ovinfo_tab); + + return 0; +} + +static LIST_HEAD(ov_list); +static DEFINE_IDR(ov_idr); + +/** + * of_overlay_create() - Create and apply an overlay + * @tree: Device node containing all the overlays + * + * Creates and applies an overlay while also keeping track + * of the overlay in a list. This list can be used to prevent + * illegal overlay removals. + * + * Returns the id of the created overlay, or an negative error number + */ +int of_overlay_create(struct device_node *tree) +{ + struct of_overlay *ov; + int err, id; + + /* allocate the overlay structure */ + ov = kzalloc(sizeof(*ov), GFP_KERNEL); + if (ov == NULL) + return -ENOMEM; + ov->id = -1; + + INIT_LIST_HEAD(&ov->node); + + of_changeset_init(&ov->cset); + + mutex_lock(&of_mutex); + + id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL); + if (id < 0) { + pr_err("%s: idr_alloc() failed for tree@%s\n", + __func__, tree->full_name); + err = id; + goto err_destroy_trans; + } + ov->id = id; + + /* build the overlay info structures */ + err = of_build_overlay_info(ov, tree); + if (err) { + pr_err("%s: of_build_overlay_info() failed for tree@%s\n", + __func__, tree->full_name); + goto err_free_idr; + } + + /* apply the overlay */ + err = of_overlay_apply(ov); + if (err) { + pr_err("%s: of_overlay_apply() failed for tree@%s\n", + __func__, tree->full_name); + goto err_abort_trans; + } + + /* apply the changeset */ + err = of_changeset_apply(&ov->cset); + if (err) { + pr_err("%s: of_changeset_apply() failed for tree@%s\n", + __func__, tree->full_name); + goto err_revert_overlay; + } + + /* add to the tail of the overlay list */ + list_add_tail(&ov->node, &ov_list); + + mutex_unlock(&of_mutex); + + return id; + +err_revert_overlay: +err_abort_trans: + of_free_overlay_info(ov); +err_free_idr: + idr_remove(&ov_idr, ov->id); +err_destroy_trans: + of_changeset_destroy(&ov->cset); + kfree(ov); + mutex_unlock(&of_mutex); + + return err; +} +EXPORT_SYMBOL_GPL(of_overlay_create); + +/* check whether the given node, lies under the given tree */ +static int overlay_subtree_check(struct device_node *tree, + struct device_node *dn) +{ + struct device_node *child; + + /* match? */ + if (tree == dn) + return 1; + + for_each_child_of_node(tree, child) { + if (overlay_subtree_check(child, dn)) + return 1; + } + + return 0; +} + +/* check whether this overlay is the topmost */ +static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn) +{ + struct of_overlay *ovt; + struct of_changeset_entry *ce; + + list_for_each_entry_reverse(ovt, &ov_list, node) { + /* if we hit ourselves, we're done */ + if (ovt == ov) + break; + + /* check against each subtree affected by this overlay */ + list_for_each_entry(ce, &ovt->cset.entries, node) { + if (overlay_subtree_check(ce->np, dn)) { + pr_err("%s: #%d clashes #%d @%s\n", + __func__, ov->id, ovt->id, + dn->full_name); + return 0; + } + } + } + + /* overlay is topmost */ + return 1; +} + +/* + * We can safely remove the overlay only if it's the top-most one. + * Newly applied overlays are inserted at the tail of the overlay list, + * so a top most overlay is the one that is closest to the tail. + * + * The topmost check is done by exploiting this property. For each + * affected device node in the log list we check if this overlay is + * the one closest to the tail. If another overlay has affected this + * device node and is closest to the tail, then removal is not permited. + */ +static int overlay_removal_is_ok(struct of_overlay *ov) +{ + struct of_changeset_entry *ce; + + list_for_each_entry(ce, &ov->cset.entries, node) { + if (!overlay_is_topmost(ov, ce->np)) { + pr_err("%s: overlay #%d is not topmost\n", + __func__, ov->id); + return 0; + } + } + + return 1; +} + +/** + * of_overlay_destroy() - Removes an overlay + * @id: Overlay id number returned by a previous call to of_overlay_create + * + * Removes an overlay if it is permissible. + * + * Returns 0 on success, or an negative error number + */ +int of_overlay_destroy(int id) +{ + struct of_overlay *ov; + int err; + + mutex_lock(&of_mutex); + + ov = idr_find(&ov_idr, id); + if (ov == NULL) { + err = -ENODEV; + pr_err("%s: Could not find overlay #%d\n", + __func__, id); + goto out; + } + + /* check whether the overlay is safe to remove */ + if (!overlay_removal_is_ok(ov)) { + err = -EBUSY; + pr_err("%s: removal check failed for overlay #%d\n", + __func__, id); + goto out; + } + + + list_del(&ov->node); + of_changeset_revert(&ov->cset); + of_free_overlay_info(ov); + idr_remove(&ov_idr, id); + of_changeset_destroy(&ov->cset); + kfree(ov); + + err = 0; + +out: + mutex_unlock(&of_mutex); + + return err; +} +EXPORT_SYMBOL_GPL(of_overlay_destroy); + +/** + * of_overlay_destroy_all() - Removes all overlays from the system + * + * Removes all overlays from the system in the correct order. + * + * Returns 0 on success, or an negative error number + */ +int of_overlay_destroy_all(void) +{ + struct of_overlay *ov, *ovn; + + mutex_lock(&of_mutex); + + /* the tail of list is guaranteed to be safe to remove */ + list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) { + list_del(&ov->node); + of_changeset_revert(&ov->cset); + of_free_overlay_info(ov); + idr_remove(&ov_idr, ov->id); + kfree(ov); + } + + mutex_unlock(&of_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(of_overlay_destroy_all); diff --git a/include/linux/of.h b/include/linux/of.h index fe1dec87fd68..aa01cf5852f8 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -957,4 +958,34 @@ static inline int of_reconfig_get_state_change(unsigned long action, /* CONFIG_OF_RESOLVE api */ extern int of_resolve_phandles(struct device_node *tree); +/** + * Overlay support + */ + +#ifdef CONFIG_OF_OVERLAY + +/* ID based overlays; the API for external users */ +int of_overlay_create(struct device_node *tree); +int of_overlay_destroy(int id); +int of_overlay_destroy_all(void); + +#else + +static inline int of_overlay_create(struct device_node *tree) +{ + return -ENOTSUPP; +} + +static inline int of_overlay_destroy(int id) +{ + return -ENOTSUPP; +} + +static inline int of_overlay_destroy_all(void) +{ + return -ENOTSUPP; +} + +#endif + #endif /* _LINUX_OF_H */ -- GitLab From 177d271cf3171bb6826ee5189f67dc1f7d34f1da Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:35:59 +0200 Subject: [PATCH 6317/9457] of/overlay: Add overlay unittests Add unittests for OF overlays. It tests overlay device addition/removal and whether the apply revert sequence is correct. Changes since V1: * Added local fixups entries. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely --- .../devicetree/bindings/unittest.txt | 14 + drivers/of/unittest-data/testcases.dts | 16 + drivers/of/unittest-data/tests-overlay.dtsi | 180 +++++++ drivers/of/unittest.c | 481 ++++++++++++++++++ 4 files changed, 691 insertions(+) create mode 100644 Documentation/devicetree/bindings/unittest.txt create mode 100644 drivers/of/unittest-data/tests-overlay.dtsi diff --git a/Documentation/devicetree/bindings/unittest.txt b/Documentation/devicetree/bindings/unittest.txt new file mode 100644 index 000000000000..0f92a22fddfa --- /dev/null +++ b/Documentation/devicetree/bindings/unittest.txt @@ -0,0 +1,14 @@ +* OF selftest platform device + +** selftest + +Required properties: +- compatible: must be "selftest" + +All other properties are optional. + +Example: + selftest { + compatible = "selftest"; + status = "okay"; + }; diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts index b6bc41b2a185..12f7c3d649c8 100644 --- a/drivers/of/unittest-data/testcases.dts +++ b/drivers/of/unittest-data/testcases.dts @@ -13,6 +13,7 @@ #include "tests-interrupts.dtsi" #include "tests-match.dtsi" #include "tests-platform.dtsi" +#include "tests-overlay.dtsi" /* * phandle fixup data - generated by dtc patches that aren't upstream. @@ -59,5 +60,20 @@ testcase-device2 { interrupt-parent = <0x00000000>; }; + overlay2 { + fragment@0 { + target = <0x00000000>; + }; + }; + overlay3 { + fragment@0 { + target = <0x00000000>; + }; + }; + overlay4 { + fragment@0 { + target = <0x00000000>; + }; + }; }; }; }; diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi new file mode 100644 index 000000000000..75976da22b2e --- /dev/null +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -0,0 +1,180 @@ + +/ { + testcase-data { + overlay-node { + + /* test bus */ + selftestbus: test-bus { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + selftest100: test-selftest100 { + compatible = "selftest"; + status = "okay"; + reg = <100>; + }; + + selftest101: test-selftest101 { + compatible = "selftest"; + status = "disabled"; + reg = <101>; + }; + + selftest0: test-selftest0 { + compatible = "selftest"; + status = "disabled"; + reg = <0>; + }; + + selftest1: test-selftest1 { + compatible = "selftest"; + status = "okay"; + reg = <1>; + }; + + selftest2: test-selftest2 { + compatible = "selftest"; + status = "disabled"; + reg = <2>; + }; + + selftest3: test-selftest3 { + compatible = "selftest"; + status = "okay"; + reg = <3>; + }; + + selftest5: test-selftest5 { + compatible = "selftest"; + status = "disabled"; + reg = <5>; + }; + + selftest6: test-selftest6 { + compatible = "selftest"; + status = "disabled"; + reg = <6>; + }; + + selftest7: test-selftest7 { + compatible = "selftest"; + status = "disabled"; + reg = <7>; + }; + + selftest8: test-selftest8 { + compatible = "selftest"; + status = "disabled"; + reg = <8>; + }; + }; + }; + + /* test enable using absolute target path */ + overlay0 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest0"; + __overlay__ { + status = "okay"; + }; + }; + }; + + /* test disable using absolute target path */ + overlay1 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest1"; + __overlay__ { + status = "disabled"; + }; + }; + }; + + /* test enable using label */ + overlay2 { + fragment@0 { + target = <&selftest2>; + __overlay__ { + status = "okay"; + }; + }; + }; + + /* test disable using label */ + overlay3 { + fragment@0 { + target = <&selftest3>; + __overlay__ { + status = "disabled"; + }; + }; + }; + + /* test insertion of a full node */ + overlay4 { + fragment@0 { + target = <&selftestbus>; + __overlay__ { + + /* suppress DTC warning */ + #address-cells = <1>; + #size-cells = <0>; + + test-selftest4 { + compatible = "selftest"; + status = "okay"; + reg = <4>; + }; + }; + }; + }; + + /* test overlay apply revert */ + overlay5 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest5"; + __overlay__ { + status = "okay"; + }; + }; + }; + + /* test overlays application and removal in sequence */ + overlay6 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest6"; + __overlay__ { + status = "okay"; + }; + }; + }; + overlay7 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest7"; + __overlay__ { + status = "okay"; + }; + }; + }; + + /* test overlays application and removal in bad sequence */ + overlay8 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest8"; + __overlay__ { + status = "okay"; + }; + }; + }; + overlay9 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus/test-selftest8"; + __overlay__ { + property-foo = "bar"; + }; + }; + }; + + }; +}; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 1720b039cac7..cc0c5ec5d464 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "of_private.h" @@ -933,6 +935,484 @@ static void selftest_data_remove(void) } } +#ifdef CONFIG_OF_OVERLAY + +static int selftest_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + + if (np == NULL) { + dev_err(dev, "No OF data for device\n"); + return -EINVAL; + + } + + dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + return 0; +} + +static int selftest_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + + dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + return 0; +} + +static struct of_device_id selftest_match[] = { + { .compatible = "selftest", }, + {}, +}; +MODULE_DEVICE_TABLE(of, altera_jtaguart_match); + +static struct platform_driver selftest_driver = { + .probe = selftest_probe, + .remove = selftest_remove, + .driver = { + .name = "selftest", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(selftest_match), + }, +}; + +/* get the platform device instantiated at the path */ +static struct platform_device *of_path_to_platform_device(const char *path) +{ + struct device_node *np; + struct platform_device *pdev; + + np = of_find_node_by_path(path); + if (np == NULL) + return NULL; + + pdev = of_find_device_by_node(np); + of_node_put(np); + + return pdev; +} + +/* find out if a platform device exists at that path */ +static int of_path_platform_device_exists(const char *path) +{ + struct platform_device *pdev; + + pdev = of_path_to_platform_device(path); + platform_device_put(pdev); + return pdev != NULL; +} + +static const char *selftest_path(int nr) +{ + static char buf[256]; + + snprintf(buf, sizeof(buf) - 1, + "/testcase-data/overlay-node/test-bus/test-selftest%d", nr); + buf[sizeof(buf) - 1] = '\0'; + + return buf; +} + +static const char *overlay_path(int nr) +{ + static char buf[256]; + + snprintf(buf, sizeof(buf) - 1, + "/testcase-data/overlay%d", nr); + buf[sizeof(buf) - 1] = '\0'; + + return buf; +} + +static const char *bus_path = "/testcase-data/overlay-node/test-bus"; + +static int of_selftest_apply_overlay(int selftest_nr, int overlay_nr, + int *overlay_id) +{ + struct device_node *np = NULL; + int ret, id = -1; + + np = of_find_node_by_path(overlay_path(overlay_nr)); + if (np == NULL) { + selftest(0, "could not find overlay node @\"%s\"\n", + overlay_path(overlay_nr)); + ret = -EINVAL; + goto out; + } + + ret = of_overlay_create(np); + if (ret < 0) { + selftest(0, "could not create overlay from \"%s\"\n", + overlay_path(overlay_nr)); + goto out; + } + id = ret; + + ret = 0; + +out: + of_node_put(np); + + if (overlay_id) + *overlay_id = id; + + return ret; +} + +/* apply an overlay while checking before and after states */ +static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr, + int before, int after) +{ + int ret; + + /* selftest device must not be in before state */ + if (of_path_platform_device_exists(selftest_path(selftest_nr)) + != before) { + selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr), + !before ? "enabled" : "disabled"); + return -EINVAL; + } + + ret = of_selftest_apply_overlay(overlay_nr, selftest_nr, NULL); + if (ret != 0) { + /* of_selftest_apply_overlay already called selftest() */ + return ret; + } + + /* selftest device must be to set to after state */ + if (of_path_platform_device_exists(selftest_path(selftest_nr)) + != after) { + selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr), + !after ? "enabled" : "disabled"); + return -EINVAL; + } + + return 0; +} + +/* apply an overlay and then revert it while checking before, after states */ +static int of_selftest_apply_revert_overlay_check(int overlay_nr, + int selftest_nr, int before, int after) +{ + int ret, ov_id; + + /* selftest device must be in before state */ + if (of_path_platform_device_exists(selftest_path(selftest_nr)) + != before) { + selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr), + !before ? "enabled" : "disabled"); + return -EINVAL; + } + + /* apply the overlay */ + ret = of_selftest_apply_overlay(overlay_nr, selftest_nr, &ov_id); + if (ret != 0) { + /* of_selftest_apply_overlay already called selftest() */ + return ret; + } + + /* selftest device must be in after state */ + if (of_path_platform_device_exists(selftest_path(selftest_nr)) + != after) { + selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr), + !after ? "enabled" : "disabled"); + return -EINVAL; + } + + ret = of_overlay_destroy(ov_id); + if (ret != 0) { + selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr)); + return ret; + } + + /* selftest device must be again in before state */ + if (of_path_platform_device_exists(selftest_path(selftest_nr)) + != before) { + selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", + overlay_path(overlay_nr), + selftest_path(selftest_nr), + !before ? "enabled" : "disabled"); + return -EINVAL; + } + + return 0; +} + +/* test activation of device */ +static void of_selftest_overlay_0(void) +{ + int ret; + + /* device should enable */ + ret = of_selftest_apply_overlay_check(0, 0, 0, 1); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 0); +} + +/* test deactivation of device */ +static void of_selftest_overlay_1(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_overlay_check(1, 1, 1, 0); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 1); +} + +/* test activation of device */ +static void of_selftest_overlay_2(void) +{ + int ret; + + /* device should enable */ + ret = of_selftest_apply_overlay_check(2, 2, 0, 1); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 2); +} + +/* test deactivation of device */ +static void of_selftest_overlay_3(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_overlay_check(3, 3, 1, 0); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 3); +} + +/* test activation of a full device node */ +static void of_selftest_overlay_4(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_overlay_check(4, 4, 0, 1); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 4); +} + +/* test overlay apply/revert sequence */ +static void of_selftest_overlay_5(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_revert_overlay_check(5, 5, 0, 1); + if (ret != 0) + return; + + selftest(1, "overlay test %d passed\n", 5); +} + +/* test overlay application in sequence */ +static void of_selftest_overlay_6(void) +{ + struct device_node *np; + int ret, i, ov_id[2]; + int overlay_nr = 6, selftest_nr = 6; + int before = 0, after = 1; + + /* selftest device must be in before state */ + for (i = 0; i < 2; i++) { + if (of_path_platform_device_exists( + selftest_path(selftest_nr + i)) + != before) { + selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", + overlay_path(overlay_nr + i), + selftest_path(selftest_nr + i), + !before ? "enabled" : "disabled"); + return; + } + } + + /* apply the overlays */ + for (i = 0; i < 2; i++) { + + np = of_find_node_by_path(overlay_path(overlay_nr + i)); + if (np == NULL) { + selftest(0, "could not find overlay node @\"%s\"\n", + overlay_path(overlay_nr + i)); + return; + } + + ret = of_overlay_create(np); + if (ret < 0) { + selftest(0, "could not create overlay from \"%s\"\n", + overlay_path(overlay_nr + i)); + return; + } + ov_id[i] = ret; + } + + for (i = 0; i < 2; i++) { + /* selftest device must be in after state */ + if (of_path_platform_device_exists( + selftest_path(selftest_nr + i)) + != after) { + selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n", + overlay_path(overlay_nr + i), + selftest_path(selftest_nr + i), + !after ? "enabled" : "disabled"); + return; + } + } + + for (i = 1; i >= 0; i--) { + ret = of_overlay_destroy(ov_id[i]); + if (ret != 0) { + selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n", + overlay_path(overlay_nr + i), + selftest_path(selftest_nr + i)); + return; + } + } + + for (i = 0; i < 2; i++) { + /* selftest device must be again in before state */ + if (of_path_platform_device_exists( + selftest_path(selftest_nr + i)) + != before) { + selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n", + overlay_path(overlay_nr + i), + selftest_path(selftest_nr + i), + !before ? "enabled" : "disabled"); + return; + } + } + + selftest(1, "overlay test %d passed\n", 6); +} + +/* test overlay application in sequence */ +static void of_selftest_overlay_8(void) +{ + struct device_node *np; + int ret, i, ov_id[2]; + int overlay_nr = 8, selftest_nr = 8; + + /* we don't care about device state in this test */ + + /* apply the overlays */ + for (i = 0; i < 2; i++) { + + np = of_find_node_by_path(overlay_path(overlay_nr + i)); + if (np == NULL) { + selftest(0, "could not find overlay node @\"%s\"\n", + overlay_path(overlay_nr + i)); + return; + } + + ret = of_overlay_create(np); + if (ret < 0) { + selftest(0, "could not create overlay from \"%s\"\n", + overlay_path(overlay_nr + i)); + return; + } + ov_id[i] = ret; + } + + /* now try to remove first overlay (it should fail) */ + ret = of_overlay_destroy(ov_id[0]); + if (ret == 0) { + selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n", + overlay_path(overlay_nr + 0), + selftest_path(selftest_nr)); + return; + } + + /* removing them in order should work */ + for (i = 1; i >= 0; i--) { + ret = of_overlay_destroy(ov_id[i]); + if (ret != 0) { + selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n", + overlay_path(overlay_nr + i), + selftest_path(selftest_nr)); + return; + } + } + + selftest(1, "overlay test %d passed\n", 8); +} + +static void __init of_selftest_overlay(void) +{ + struct device_node *bus_np = NULL; + int ret; + + ret = platform_driver_register(&selftest_driver); + if (ret != 0) { + selftest(0, "could not register selftest driver\n"); + goto out; + } + + bus_np = of_find_node_by_path(bus_path); + if (bus_np == NULL) { + selftest(0, "could not find bus_path \"%s\"\n", bus_path); + goto out; + } + + ret = of_platform_populate(bus_np, of_default_bus_match_table, + NULL, NULL); + if (ret != 0) { + selftest(0, "could not populate bus @ \"%s\"\n", bus_path); + goto out; + } + + if (!of_path_platform_device_exists(selftest_path(100))) { + selftest(0, "could not find selftest0 @ \"%s\"\n", + selftest_path(100)); + goto out; + } + + if (of_path_platform_device_exists(selftest_path(101))) { + selftest(0, "selftest1 @ \"%s\" should not exist\n", + selftest_path(101)); + goto out; + } + + selftest(1, "basic infrastructure of overlays passed"); + + /* tests in sequence */ + of_selftest_overlay_0(); + of_selftest_overlay_1(); + of_selftest_overlay_2(); + of_selftest_overlay_3(); + of_selftest_overlay_4(); + of_selftest_overlay_5(); + of_selftest_overlay_6(); + of_selftest_overlay_8(); + +out: + of_node_put(bus_np); +} + +#else +static inline void __init of_selftest_overlay(void) { } +#endif + static int __init of_selftest(void) { struct device_node *np; @@ -965,6 +1445,7 @@ static int __init of_selftest(void) of_selftest_parse_interrupts_extended(); of_selftest_match_node(); of_selftest_platform_populate(); + of_selftest_overlay(); /* removing selftest data from live tree */ selftest_data_remove(); -- GitLab From f895b252d4edf66b2895fb5a7b17a638665f3e1f Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 17 Nov 2014 16:58:04 -0500 Subject: [PATCH 6318/9457] sunrpc: eliminate RPC_DEBUG It's always set to whatever CONFIG_SUNRPC_DEBUG is, so just use that. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 2 +- include/linux/sunrpc/debug.h | 9 +++------ include/linux/sunrpc/sched.h | 8 ++++---- include/uapi/linux/nfsd/debug.h | 2 +- net/sunrpc/auth.c | 4 ++-- net/sunrpc/auth_generic.c | 2 +- net/sunrpc/auth_gss/auth_gss.c | 2 +- net/sunrpc/auth_gss/gss_generic_token.c | 2 +- net/sunrpc/auth_gss/gss_krb5_crypto.c | 2 +- net/sunrpc/auth_gss/gss_krb5_keys.c | 2 +- net/sunrpc/auth_gss/gss_krb5_mech.c | 2 +- net/sunrpc/auth_gss/gss_krb5_seal.c | 2 +- net/sunrpc/auth_gss/gss_krb5_seqnum.c | 2 +- net/sunrpc/auth_gss/gss_krb5_unseal.c | 2 +- net/sunrpc/auth_gss/gss_krb5_wrap.c | 2 +- net/sunrpc/auth_gss/gss_mech_switch.c | 2 +- net/sunrpc/auth_gss/gss_rpc_xdr.h | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- net/sunrpc/auth_null.c | 4 ++-- net/sunrpc/auth_unix.c | 2 +- net/sunrpc/backchannel_rqst.c | 2 +- net/sunrpc/clnt.c | 6 +++--- net/sunrpc/rpcb_clnt.c | 2 +- net/sunrpc/sched.c | 4 ++-- net/sunrpc/sunrpc_syms.c | 4 ++-- net/sunrpc/svc.c | 2 +- net/sunrpc/sysctl.c | 2 +- net/sunrpc/xprt.c | 2 +- net/sunrpc/xprtrdma/rpc_rdma.c | 4 ++-- net/sunrpc/xprtrdma/transport.c | 8 ++++---- net/sunrpc/xprtrdma/verbs.c | 8 ++++---- net/sunrpc/xprtsock.c | 8 ++++---- 32 files changed, 53 insertions(+), 56 deletions(-) diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 8e030075fe79..a7cbb570cc5c 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -53,7 +53,7 @@ struct rpc_cred { struct rcu_head cr_rcu; struct rpc_auth * cr_auth; const struct rpc_credops *cr_ops; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) unsigned long cr_magic; /* 0x0f4aa4f0 */ #endif unsigned long cr_expire; /* when to gc */ diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 9385bd74c860..51143757b8f7 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h @@ -14,9 +14,6 @@ /* * Enable RPC debugging/profiling. */ -#ifdef CONFIG_SUNRPC_DEBUG -#define RPC_DEBUG -#endif #ifdef CONFIG_TRACEPOINTS #define RPC_TRACEPOINTS #endif @@ -25,7 +22,7 @@ /* * Debugging macros etc */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) extern unsigned int rpc_debug; extern unsigned int nfs_debug; extern unsigned int nfsd_debug; @@ -36,7 +33,7 @@ extern unsigned int nlm_debug; #define dprintk_rcu(args...) dfprintk_rcu(FACILITY, ## args) #undef ifdebug -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac)) # define dfprintk(fac, args...) \ @@ -65,7 +62,7 @@ extern unsigned int nlm_debug; /* * Sysctl interface for RPC debugging */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) void rpc_register_sysctl(void); void rpc_unregister_sysctl(void); #endif diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 1a8959944c5f..fecdbf1b4797 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -79,7 +79,7 @@ struct rpc_task { unsigned short tk_flags; /* misc flags */ unsigned short tk_timeouts; /* maj timeouts */ -#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) unsigned short tk_pid; /* debugging aid */ #endif unsigned char tk_priority : 2,/* Task priority */ @@ -187,7 +187,7 @@ struct rpc_wait_queue { unsigned char nr; /* # tasks remaining for cookie */ unsigned short qlen; /* total # tasks waiting in queue */ struct rpc_timer timer_list; -#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) const char * name; #endif }; @@ -237,7 +237,7 @@ void rpc_free(void *); int rpciod_up(void); void rpciod_down(void); int __rpc_wait_for_completion_task(struct rpc_task *task, wait_bit_action_f *); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) struct net; void rpc_show_tasks(struct net *); #endif @@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task) return __rpc_wait_for_completion_task(task, NULL); } -#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS) static inline const char * rpc_qname(const struct rpc_wait_queue *q) { return ((q && q->name) ? q->name : "unknown"); diff --git a/include/uapi/linux/nfsd/debug.h b/include/uapi/linux/nfsd/debug.h index a6f453c740b8..1fdc95bb2375 100644 --- a/include/uapi/linux/nfsd/debug.h +++ b/include/uapi/linux/nfsd/debug.h @@ -15,7 +15,7 @@ * Enable debugging for nfsd. * Requires RPC_DEBUG. */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define NFSD_DEBUG 1 #endif diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 383eb919ac0b..47f38be4155f 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -16,7 +16,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -646,7 +646,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, cred->cr_auth = auth; cred->cr_ops = ops; cred->cr_expire = jiffies; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) cred->cr_magic = RPCAUTH_CRED_MAGIC; #endif cred->cr_uid = acred->uid; diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c index 6f6b829c9e8e..41248b1820c7 100644 --- a/net/sunrpc/auth_generic.c +++ b/net/sunrpc/auth_generic.c @@ -14,7 +14,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 53ed8d3f8897..dace13d7638e 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -66,7 +66,7 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; #define GSS_KEY_EXPIRE_TIMEO 240 static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c index c586e92bcf76..254defe446a7 100644 --- a/net/sunrpc/auth_gss/gss_generic_token.c +++ b/net/sunrpc/auth_gss/gss_generic_token.c @@ -38,7 +38,7 @@ #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index f5ed9f6ece06..b5408e8a37f2 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -45,7 +45,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 24589bd2a4b6..234fa8d0fd9b 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -61,7 +61,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 0d3c158ef8fa..28db442a0034 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -45,7 +45,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index 42768e5c3994..1d74d653e6c0 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -64,7 +64,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c index 62ac90c62cb1..20d55c793eb6 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c +++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c @@ -35,7 +35,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index 6c981ddc19f8..dcf9515d9aef 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -62,7 +62,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 4b614c604fe0..ca7e92a32f84 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -35,7 +35,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 92d5ab99fbf3..7063d856a598 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -46,7 +46,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h index 685a688f3d8a..9d88c6239f01 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.h +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h @@ -25,7 +25,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index c548ab213f76..de856ddf5fed 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -51,7 +51,7 @@ #include "gss_rpc_upcall.h" -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index 712c123e04e9..c2a2b584a056 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -10,7 +10,7 @@ #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -138,7 +138,7 @@ struct rpc_cred null_cred = { .cr_ops = &null_credops, .cr_count = ATOMIC_INIT(1), .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE, -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) .cr_magic = RPCAUTH_CRED_MAGIC, #endif }; diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index d5d692366294..4feda2d0a833 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -25,7 +25,7 @@ struct unx_cred { #define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 9761a0da964d..651f49ab601f 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) #define RPCDBG_FACILITY RPCDBG_TRANS #endif diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9acd6ce88db7..36c64ef460cf 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -42,7 +42,7 @@ #include "sunrpc.h" #include "netns.h" -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_CALL #endif @@ -1396,7 +1396,7 @@ rpc_restart_call(struct rpc_task *task) } EXPORT_SYMBOL_GPL(rpc_restart_call); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static const char *rpc_proc_name(const struct rpc_task *task) { const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; @@ -2421,7 +2421,7 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int } EXPORT_SYMBOL_GPL(rpc_call_null); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static void rpc_show_header(void) { printk(KERN_INFO "-pid- flgs status -client- --rqstp- " diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 1891a1022c17..05202012bcfc 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -32,7 +32,7 @@ #include "netns.h" -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_BIND #endif diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index fe3441abdbe5..574b2977fc4b 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -24,7 +24,7 @@ #include "sunrpc.h" -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) #define RPCDBG_FACILITY RPCDBG_SCHED #endif @@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key) return 0; } -#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) static void rpc_task_set_debuginfo(struct rpc_task *task) { static atomic_t rpc_pid; diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index cd30120de9e4..f632e476ab6c 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -97,7 +97,7 @@ init_sunrpc(void) err = register_rpc_pipefs(); if (err) goto out4; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) rpc_register_sysctl(); #endif svc_init_xprt_sock(); /* svc sock transport */ @@ -123,7 +123,7 @@ cleanup_sunrpc(void) unregister_rpc_pipefs(); rpc_destroy_mempool(); unregister_pernet_subsys(&sunrpc_net_ops); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) rpc_unregister_sysctl(); #endif rcu_barrier(); /* Wait for completion of call_rcu()'s */ diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 371a8bbb43d6..2783fd80c229 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1042,7 +1042,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net) /* * dprintk the given error with the address of the client that caused it. */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static __printf(2, 3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) { diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index c99c58e2ee66..887f0183b4c6 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c @@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(nfsd_debug); unsigned int nlm_debug; EXPORT_SYMBOL_GPL(nlm_debug); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static struct ctl_table_header *sunrpc_table_header; static struct ctl_table sunrpc_table[]; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 1b2e5e616cae..894d071426b2 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -57,7 +57,7 @@ * Local variables */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_XPRT #endif diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 6166c985fe24..df01d124936c 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -49,11 +49,11 @@ #include -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_TRANS #endif -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static const char transfertypes[][12] = { "pure inline", /* no chunks */ " read chunk", /* some argument via rdma read */ diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 6a4615dd0261..ef58ebadb3ae 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -55,7 +55,7 @@ #include "xprt_rdma.h" -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_TRANS #endif @@ -75,7 +75,7 @@ static unsigned int xprt_rdma_inline_write_padding; static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; int xprt_rdma_pad_optimize = 0; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE; static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE; @@ -705,7 +705,7 @@ static void __exit xprt_rdma_cleanup(void) int rc; dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n"); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) if (sunrpc_table_header) { unregister_sysctl_table(sunrpc_table_header); sunrpc_table_header = NULL; @@ -736,7 +736,7 @@ static int __init xprt_rdma_init(void) dprintk("\tPadding %d\n\tMemreg %d\n", xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy); -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) if (!sunrpc_table_header) sunrpc_table_header = register_sysctl_table(sunrpc_table); #endif diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 61c41298b4ea..b92b04083e40 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -57,7 +57,7 @@ * Globals/Macros */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_TRANS #endif @@ -313,7 +313,7 @@ rpcrdma_flush_cqs(struct rpcrdma_ep *ep) rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep); } -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static const char * const conn[] = { "address resolved", "address error", @@ -344,7 +344,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) struct rpcrdma_xprt *xprt = id->context; struct rpcrdma_ia *ia = &xprt->rx_ia; struct rpcrdma_ep *ep = &xprt->rx_ep; -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr; #endif struct ib_qp_attr attr; @@ -408,7 +408,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) break; } -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) if (connstate == 1) { int ird = attr.max_dest_rd_atomic; int tird = ep->rep_remote_cma.responder_resources; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 31c015196a29..87ce7e8bb8dc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -75,7 +75,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO; * someone else's file names! */ -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; @@ -186,7 +186,7 @@ static struct ctl_table sunrpc_table[] = { */ #define XS_IDLE_DISC_TO (5U * 60 * HZ) -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # undef RPC_DEBUG_DATA # define RPCDBG_FACILITY RPCDBG_TRANS #endif @@ -2991,7 +2991,7 @@ static struct xprt_class xs_bc_tcp_transport = { */ int init_socket_xprt(void) { -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) if (!sunrpc_table_header) sunrpc_table_header = register_sysctl_table(sunrpc_table); #endif @@ -3010,7 +3010,7 @@ int init_socket_xprt(void) */ void cleanup_socket_xprt(void) { -#ifdef RPC_DEBUG +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) if (sunrpc_table_header) { unregister_sysctl_table(sunrpc_table_header); sunrpc_table_header = NULL; -- GitLab From 1306729b0d4f4a0bd0d098711ed3d938dc5a1a28 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 17 Nov 2014 16:58:05 -0500 Subject: [PATCH 6319/9457] sunrpc: eliminate RPC_TRACEPOINTS It's always set to the same value as CONFIG_TRACEPOINTS, so we can just use that instead. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/linux/sunrpc/debug.h | 9 --------- include/linux/sunrpc/sched.h | 6 +++--- net/sunrpc/sched.c | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 51143757b8f7..43f38ee9668c 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h @@ -10,15 +10,6 @@ #include - -/* - * Enable RPC debugging/profiling. - */ -#ifdef CONFIG_TRACEPOINTS -#define RPC_TRACEPOINTS -#endif -/* #define RPC_PROFILE */ - /* * Debugging macros etc */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index fecdbf1b4797..5f1e6bd4c316 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -79,7 +79,7 @@ struct rpc_task { unsigned short tk_flags; /* misc flags */ unsigned short tk_timeouts; /* maj timeouts */ -#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS) unsigned short tk_pid; /* debugging aid */ #endif unsigned char tk_priority : 2,/* Task priority */ @@ -187,7 +187,7 @@ struct rpc_wait_queue { unsigned char nr; /* # tasks remaining for cookie */ unsigned short qlen; /* total # tasks waiting in queue */ struct rpc_timer timer_list; -#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS) const char * name; #endif }; @@ -251,7 +251,7 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task) return __rpc_wait_for_completion_task(task, NULL); } -#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined (RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS) static inline const char * rpc_qname(const struct rpc_wait_queue *q) { return ((q && q->name) ? q->name : "unknown"); diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 574b2977fc4b..d20f2329eea3 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -258,7 +258,7 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key) return 0; } -#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || defined(RPC_TRACEPOINTS) +#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS) static void rpc_task_set_debuginfo(struct rpc_task *task) { static atomic_t rpc_pid; -- GitLab From 70114c393ccaa43ca38e6b36b9469ed2c35acc49 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 24 Nov 2014 15:52:30 -0700 Subject: [PATCH 6320/9457] blk-mq: cleanup tag free handling We only call __blk_mq_put_tag() and __blk_mq_put_reserved_tag() from blk_mq_put_tag(), so just inline the two calls instead of having them as separate functions. Signed-off-by: Jens Axboe --- block/blk-mq-tag.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 8317175a3009..230ef3056b72 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -360,21 +360,6 @@ static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag) } } -static void __blk_mq_put_tag(struct blk_mq_tags *tags, unsigned int tag) -{ - BUG_ON(tag >= tags->nr_tags); - - bt_clear_tag(&tags->bitmap_tags, tag); -} - -static void __blk_mq_put_reserved_tag(struct blk_mq_tags *tags, - unsigned int tag) -{ - BUG_ON(tag >= tags->nr_reserved_tags); - - bt_clear_tag(&tags->breserved_tags, tag); -} - void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag, unsigned int *last_tag) { @@ -383,10 +368,13 @@ void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag, if (tag >= tags->nr_reserved_tags) { const int real_tag = tag - tags->nr_reserved_tags; - __blk_mq_put_tag(tags, real_tag); + BUG_ON(real_tag >= tags->nr_tags); + bt_clear_tag(&tags->bitmap_tags, real_tag); *last_tag = real_tag; - } else - __blk_mq_put_reserved_tag(tags, tag); + } else { + BUG_ON(tag >= tags->nr_reserved_tags); + bt_clear_tag(&tags->breserved_tags, tag); + } } static void bt_for_each(struct blk_mq_hw_ctx *hctx, -- GitLab From fe0bf1185ddf7e9d193cfe397ed1414d91526e19 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 18 Nov 2014 13:23:43 +0100 Subject: [PATCH 6321/9457] NFS: Deletion of unnecessary checks before the function call "nfs_put_client" The nfs_put_client() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Trond Myklebust --- fs/nfs/filelayout/filelayoutdev.c | 3 +-- fs/nfs/nfs4client.c | 15 +++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c index 9bb806a76d99..bfecac781f19 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c @@ -204,8 +204,7 @@ destroy_ds(struct nfs4_pnfs_ds *ds) ifdebug(FACILITY) print_ds(ds); - if (ds->ds_clp) - nfs_put_client(ds->ds_clp); + nfs_put_client(ds->ds_clp); while (!list_empty(&ds->ds_addrs)) { da = list_first_entry(&ds->ds_addrs, diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index ffdb28d86cf8..5f07a0ed9188 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -498,8 +498,7 @@ int nfs40_walk_client_list(struct nfs_client *new, atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); - if (prev) - nfs_put_client(prev); + nfs_put_client(prev); prev = pos; status = nfs_wait_client_init_complete(pos); @@ -517,8 +516,7 @@ int nfs40_walk_client_list(struct nfs_client *new, atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); - if (prev) - nfs_put_client(prev); + nfs_put_client(prev); prev = pos; status = nfs4_proc_setclientid_confirm(pos, &clid, cred); @@ -549,8 +547,7 @@ int nfs40_walk_client_list(struct nfs_client *new, /* No match found. The server lost our clientid */ out: - if (prev) - nfs_put_client(prev); + nfs_put_client(prev); dprintk("NFS: <-- %s status = %d\n", __func__, status); return status; } @@ -641,8 +638,7 @@ int nfs41_walk_client_list(struct nfs_client *new, atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); - if (prev) - nfs_put_client(prev); + nfs_put_client(prev); prev = pos; status = nfs_wait_client_init_complete(pos); @@ -675,8 +671,7 @@ int nfs41_walk_client_list(struct nfs_client *new, /* No matching nfs_client found. */ spin_unlock(&nn->nfs_client_lock); dprintk("NFS: <-- %s status = %d\n", __func__, status); - if (prev) - nfs_put_client(prev); + nfs_put_client(prev); return status; } #endif /* CONFIG_NFS_V4_1 */ -- GitLab From 5a254d08b086d80cbead2ebcee6d2a4b3a15587a Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Sun, 23 Nov 2014 12:47:17 +0800 Subject: [PATCH 6322/9457] nfs: replace nfs_add_stats with nfs_inc_stats when add one Signed-off-by: Li RongQing Signed-off-by: Trond Myklebust --- fs/nfs/read.c | 2 +- fs/nfs/write.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/read.c b/fs/nfs/read.c index beff2769c5c5..c91a4799c562 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -269,7 +269,7 @@ int nfs_readpage(struct file *file, struct page *page) dprintk("NFS: nfs_readpage (%p %ld@%lu)\n", page, PAGE_CACHE_SIZE, page_file_index(page)); nfs_inc_stats(inode, NFSIOS_VFSREADPAGE); - nfs_add_stats(inode, NFSIOS_READPAGES, 1); + nfs_inc_stats(inode, NFSIOS_READPAGES); /* * Try to flush any pending writes to the file.. diff --git a/fs/nfs/write.c b/fs/nfs/write.c index d489ff3f438f..af3af685a9e3 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -575,7 +575,7 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st int ret; nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); - nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); + nfs_inc_stats(inode, NFSIOS_WRITEPAGES); nfs_pageio_cond_complete(pgio, page_file_index(page)); ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE); -- GitLab From e9f456ca50e579dfacd996f50637f0bb0a585dfc Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Sun, 23 Nov 2014 12:47:41 +0800 Subject: [PATCH 6323/9457] nfs: define nfs_inc_fscache_stats and using it as possible Define and use nfs_inc_fscache_stats when plus one, which can save to pass one parameter. Signed-off-by: Li RongQing Signed-off-by: Trond Myklebust --- fs/nfs/fscache.c | 24 ++++++++++++------------ fs/nfs/iostat.h | 5 +++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 3ef01f0ba0bc..d63bea8bbfbb 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -269,8 +269,8 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp) if (!fscache_maybe_release_page(cookie, page, gfp)) return 0; - nfs_add_fscache_stats(page->mapping->host, - NFSIOS_FSCACHE_PAGES_UNCACHED, 1); + nfs_inc_fscache_stats(page->mapping->host, + NFSIOS_FSCACHE_PAGES_UNCACHED); } return 1; @@ -293,8 +293,8 @@ void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode) BUG_ON(!PageLocked(page)); fscache_uncache_page(cookie, page); - nfs_add_fscache_stats(page->mapping->host, - NFSIOS_FSCACHE_PAGES_UNCACHED, 1); + nfs_inc_fscache_stats(page->mapping->host, + NFSIOS_FSCACHE_PAGES_UNCACHED); } /* @@ -343,19 +343,19 @@ int __nfs_readpage_from_fscache(struct nfs_open_context *ctx, case 0: /* read BIO submitted (page in fscache) */ dfprintk(FSCACHE, "NFS: readpage_from_fscache: BIO submitted\n"); - nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK, 1); + nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK); return ret; case -ENOBUFS: /* inode not in cache */ case -ENODATA: /* page not in cache */ - nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1); + nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL); dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret); return 1; default: dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret); - nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1); + nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL); } return ret; } @@ -429,11 +429,11 @@ void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync) if (ret != 0) { fscache_uncache_page(nfs_i_fscache(inode), page); - nfs_add_fscache_stats(inode, - NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1); - nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1); + nfs_inc_fscache_stats(inode, + NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL); + nfs_inc_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED); } else { - nfs_add_fscache_stats(inode, - NFSIOS_FSCACHE_PAGES_WRITTEN_OK, 1); + nfs_inc_fscache_stats(inode, + NFSIOS_FSCACHE_PAGES_WRITTEN_OK); } } diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index c5832487c456..0cb806fbd4c4 100644 --- a/fs/nfs/iostat.h +++ b/fs/nfs/iostat.h @@ -55,6 +55,11 @@ static inline void nfs_add_fscache_stats(struct inode *inode, { this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend); } +static inline void nfs_inc_fscache_stats(struct inode *inode, + enum nfs_stat_fscachecounters stat) +{ + this_cpu_inc(NFS_SERVER(inode)->io_stats->fscache[stat]); +} #endif static inline struct nfs_iostats __percpu *nfs_alloc_iostats(void) -- GitLab From d908f8478a8d18e66c80a12adb27764920c1f1ca Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 20 Nov 2014 14:54:35 +0100 Subject: [PATCH 6324/9457] cdc-acm: memory leak in error case If probe() fails not only the attributes need to be removed but also the memory freed. Reported-by: Ahmed Tamrawi Signed-off-by: Oliver Neukum CC: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index c74fd3a3f657..6c6a5c4cc68c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1473,6 +1473,7 @@ static int acm_probe(struct usb_interface *intf, &dev_attr_wCountryCodes); device_remove_file(&acm->control->dev, &dev_attr_iCountryCodeRelDate); + kfree(acm->country_codes); } device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); alloc_fail7: -- GitLab From 403dff4e2c94f275e24fd85f40b2732ffec268a1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Nov 2014 08:48:15 -0800 Subject: [PATCH 6325/9457] USB: cdc-acm: check for valid interfaces We need to check that we have both a valid data and control inteface for both types of headers (union and not union.) References: https://bugzilla.kernel.org/show_bug.cgi?id=83551 Reported-by: Simon Schubert <2+kernel@0x2c.org> Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6c6a5c4cc68c..546a17e8ad5b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1195,10 +1195,11 @@ static int acm_probe(struct usb_interface *intf, } else { control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); - if (!control_interface || !data_interface) { - dev_dbg(&intf->dev, "no interfaces\n"); - return -ENODEV; - } + } + + if (!control_interface || !data_interface) { + dev_dbg(&intf->dev, "no interfaces\n"); + return -ENODEV; } if (data_interface_num != call_interface_num) -- GitLab From 782614b80edf97dad35fa93f9981883c3e117c29 Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Thu, 13 Nov 2014 00:49:50 +0100 Subject: [PATCH 6326/9457] usb: ehci-orion: enable big-endian support This commit fixes ehci-orion operation in big-endian mode by enabling byteswap when accessing registers using 'rdl' and 'wrl' macros. Signed-off-by: Grzegorz Jaszczyk Signed-off-by: Marcin Wojtas Reviewed-by: Gregory CLEMENT Tested-by: Thomas Petazzoni Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-orion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 36b46576e5b3..3c76489ea61a 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -25,8 +25,8 @@ #include "ehci.h" -#define rdl(off) __raw_readl(hcd->regs + (off)) -#define wrl(off, val) __raw_writel((val), hcd->regs + (off)) +#define rdl(off) readl_relaxed(hcd->regs + (off)) +#define wrl(off, val) writel_relaxed((val), hcd->regs + (off)) #define USB_CMD 0x140 #define USB_MODE 0x1a8 -- GitLab From eab77694098469d80e1186fdda9f965045730a3e Mon Sep 17 00:00:00 2001 From: Mark Knibbs Date: Fri, 7 Nov 2014 22:02:19 +0000 Subject: [PATCH 6327/9457] storage: Enable multi-target mode as vendor driver does for SCM eUSCSI bridge usb_stor_euscsi_init() enables multi-target mode for SCM eUSB SCSI bridge devices. The control message it sends has wLength = 1 and the byte sent is 0x01. While that works, the SCM Windows driver does it with wLength = 0. We may as well match what the SCM driver does. Signed-off-by: Mark Knibbs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/initializers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 73f125e0cb58..31fa2e92065b 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -49,10 +49,9 @@ int usb_stor_euscsi_init(struct us_data *us) int result; usb_stor_dbg(us, "Attempting to init eUSCSI bridge...\n"); - us->iobuf[0] = 0x1; result = usb_stor_control_msg(us, us->send_ctrl_pipe, 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, - 0x01, 0x0, us->iobuf, 0x1, 5 * HZ); + 0x01, 0x0, NULL, 0x0, 5 * HZ); usb_stor_dbg(us, "-- result is %d\n", result); return 0; -- GitLab From 646a3843177b2ae0cb81813ec0f830fe64e81bf1 Mon Sep 17 00:00:00 2001 From: Mark Knibbs Date: Sat, 8 Nov 2014 21:39:55 +0000 Subject: [PATCH 6328/9457] storage: Fix bus scan and multi-LUN support for SCM eUSCSI devices This patch does two things for SCM eUSCSI USB-SCSI converters: 1. SCM eUSCSI bridge devices are hard-wired to use SCSI ID 7. On connecting the converter, access to that ID is attempted during the bus scan. Asking the converter to issue INQUIRY commands to itself isn't very polite and wastes time. Set this_id to 7 so __scsi_scan_target() skips it in the scan. 2. Enable multi-LUN support. eUSCSI devices don't support Get Max LUN requests, returning an error (-32). [Different targets could have different numbers of LUNs, so it wouldn't make sense to return a particular value in response to Get Max LUN.] usb_stor_scan_dwork() does this: /* For bulk-only devices, determine the max LUN value */ if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { mutex_lock(&us->dev_mutex); us->max_lun = usb_stor_Bulk_max_lun(us); mutex_unlock(&us->dev_mutex); It avoids calling usb_stor_Bulk_max_lun() if US_FL_SINGLE_LUN, but not for US_FL_SCM_MULT_TARG. Since usb_stor_Bulk_max_lun() returns 0 in the error case, us->max_lun was always set to 0. [If the user doesn't want multi-LUN support (perhaps there are SCSI devices which respond to commands on all LUNs?), the US_FL_SINGLE_LUN quirk can be specified on the kernel command line.] Signed-off-by: Mark Knibbs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 9d66ce62542e..d468d02179f4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -884,7 +884,9 @@ static void usb_stor_scan_dwork(struct work_struct *work) dev_dbg(dev, "starting scan\n"); /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { + if (us->protocol == USB_PR_BULK && + !(us->fflags & US_FL_SINGLE_LUN) && + !(us->fflags & US_FL_SCM_MULT_TARG)) { mutex_lock(&us->dev_mutex); us->max_lun = usb_stor_Bulk_max_lun(us); mutex_unlock(&us->dev_mutex); @@ -983,21 +985,31 @@ int usb_stor_probe2(struct us_data *us) usb_stor_dbg(us, "Transport: %s\n", us->transport_name); usb_stor_dbg(us, "Protocol: %s\n", us->protocol_name); + if (us->fflags & US_FL_SCM_MULT_TARG) { + /* + * SCM eUSCSI bridge devices can have different numbers + * of LUNs on different targets; allow all to be probed. + */ + us->max_lun = 7; + /* The eUSCSI itself has ID 7, so avoid scanning that */ + us_to_host(us)->this_id = 7; + /* max_id is 8 initially, so no need to set it here */ + } else { + /* In the normal case there is only a single target */ + us_to_host(us)->max_id = 1; + /* + * Like Windows, we won't store the LUN bits in CDB[1] for + * SCSI-2 devices using the Bulk-Only transport (even though + * this violates the SCSI spec). + */ + if (us->transport == usb_stor_Bulk_transport) + us_to_host(us)->no_scsi2_lun_in_cdb = 1; + } + /* fix for single-lun devices */ if (us->fflags & US_FL_SINGLE_LUN) us->max_lun = 0; - if (!(us->fflags & US_FL_SCM_MULT_TARG)) - us_to_host(us)->max_id = 1; - - /* - * Like Windows, we won't store the LUN bits in CDB[1] for SCSI-2 - * devices using the Bulk-Only transport (even though this violates - * the SCSI spec). - */ - if (us->transport == usb_stor_Bulk_transport) - us_to_host(us)->no_scsi2_lun_in_cdb = 1; - /* Find the endpoints and calculate pipe values */ result = get_pipes(us); if (result) -- GitLab From 0bfed505447dd5a47e6097a32d216d7df7cf70aa Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 20 Nov 2014 18:34:01 +0100 Subject: [PATCH 6329/9457] host: ehci-w90x900: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-w90x900.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 4717bf207595..c305732e8634 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -75,8 +75,10 @@ static int usb_w90x900_probe(const struct hc_driver *driver, __raw_writel(val, ehci->regs+PHY1_CTR); irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + retval = irq; goto err2; + } retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval != 0) -- GitLab From 03f3df817dd3bf988c6d56e10e99b5b4553f5044 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 16:33:18 +0100 Subject: [PATCH 6330/9457] USB-IP: Deletion of unnecessary checks before the function call "usb_put_dev" The usb_put_dev() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Valentina Manea Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vhci_hcd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c02374b6049c..cc1b03eccf4a 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -518,8 +518,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, dev_info(dev, "SetAddress Request (%d) to port %d\n", ctrlreq->wValue, vdev->rhport); - if (vdev->udev) - usb_put_dev(vdev->udev); + usb_put_dev(vdev->udev); vdev->udev = usb_get_dev(urb->dev); spin_lock(&vdev->ud.lock); @@ -539,8 +538,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, usbip_dbg_vhci_hc( "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); - if (vdev->udev) - usb_put_dev(vdev->udev); + usb_put_dev(vdev->udev); vdev->udev = usb_get_dev(urb->dev); goto out; @@ -831,8 +829,7 @@ static void vhci_device_reset(struct usbip_device *ud) vdev->speed = 0; vdev->devid = 0; - if (vdev->udev) - usb_put_dev(vdev->udev); + usb_put_dev(vdev->udev); vdev->udev = NULL; if (ud->tcp_socket) { -- GitLab From bb2d43e0919ad89077dc756167c2bcc3e4cc97ab Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 15:50:44 +0100 Subject: [PATCH 6331/9457] USB-SIS: Deletion of an unnecessary check before the function call "usb_put_dev" The usb_put_dev() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 633caf643122..022dc0008f2a 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -2472,8 +2472,7 @@ sisusb_delete(struct kref *kref) if (!sisusb) return; - if (sisusb->sisusb_dev) - usb_put_dev(sisusb->sisusb_dev); + usb_put_dev(sisusb->sisusb_dev); sisusb->sisusb_dev = NULL; sisusb_free_buffers(sisusb); -- GitLab From f910b6cba27af4c5e1b0de1225a268448c2e82be Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 21 Nov 2014 15:20:12 +0100 Subject: [PATCH 6332/9457] USB: PCI-quirks: Deletion of unnecessary checks before the function call "pci_dev_put" The pci_dev_put() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2f3acebb577a..dd483c13565b 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -233,10 +233,8 @@ int usb_amd_find_chipset_info(void) spin_unlock_irqrestore(&amd_lock, flags); - if (info.nb_dev) - pci_dev_put(info.nb_dev); - if (info.smbus_dev) - pci_dev_put(info.smbus_dev); + pci_dev_put(info.nb_dev); + pci_dev_put(info.smbus_dev); } else { /* no race - commit the result */ @@ -447,10 +445,8 @@ void usb_amd_dev_put(void) spin_unlock_irqrestore(&amd_lock, flags); - if (nb) - pci_dev_put(nb); - if (smbus) - pci_dev_put(smbus); + pci_dev_put(nb); + pci_dev_put(smbus); } EXPORT_SYMBOL_GPL(usb_amd_dev_put); -- GitLab From 33e2192fb1e329c26847c92edbd90f7e93eecacf Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 24 Nov 2014 16:58:48 +0900 Subject: [PATCH 6333/9457] drm/exynos: fix exynos_drm_component_del This patch resolves the issue that component object isn't removed correctly. A given component object couldn't be placed to head of drm_component_list so all component objects added to the drm_component_list should be checked to remove the given component object. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 495826f73c2a..d71fb54582d2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -473,8 +473,6 @@ void exynos_drm_component_del(struct device *dev, list_del(&cdev->list); kfree(cdev); } - - break; } mutex_unlock(&drm_component_lock); -- GitLab From 1d50aa9c6fb01356238ec21039f145fc2d81f7e7 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 24 Nov 2014 14:55:41 +0900 Subject: [PATCH 6334/9457] drm/exynos: vidi: add component support This patch adds component support for vidi driver. vidi driver is a kms driver so it doesn't need to be registered to exynos_drm_subdrv_list. For this, it changes for the component framework to be used for vidi driver. This patch fixes below error also, # echo 1 > /sys/devices/platform/exynos-drm-vidi/connection [ 55.618529] ------------[ cut here ]------------ [ 55.621960] WARNING: CPU: 0 PID: 1397 at drivers/gpu/drm/drm_irq.c:1203 exynos_drm_crtc_dpms+0x88/0x17c() [ 55.631268] Modules linked in: [ 55.634278] CPU: 0 PID: 1397 Comm: sh Not tainted 3.18.0-rc2-146253-g31449d7 #1154 [ 55.641885] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 55.649597] [] (show_stack) from [] (dump_stack+0x84/0xc4) [ 55.656802] [] (dump_stack) from [] (warn_slowpath_common+0x6c/0x88) [ 55.664866] [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [ 55.673632] [] (warn_slowpath_null) from [] (exynos_drm_crtc_dpms+0x88/0x17c) [ 55.682482] [] (exynos_drm_crtc_dpms) from [] (exynos_drm_crtc_commit+0x14/0x44) [ 55.691622] [] (exynos_drm_crtc_commit) from [] (drm_crtc_helper_set_mode+0x3d0/0x51c) [ 55.701233] [] (drm_crtc_helper_set_mode) from [] (drm_crtc_helper_set_config+0x87c/0x9dc) [ 55.711230] [] (drm_crtc_helper_set_config) from [] (drm_mode_set_config_internal+0x58/0xd4) [ 55.721380] [] (drm_mode_set_config_internal) from [] (restore_fbdev_mode+0xcc/0xec) [ 55.730834] [] (restore_fbdev_mode) from [] (drm_fb_helper_restore_fbdev_mode_unlocked+0x1c/0x30) [ 55.741424] [] (drm_fb_helper_restore_fbdev_mode_unlocked) from [] (drm_fb_helper_set_par+0x1c/0x60) [ 55.752271] [] (drm_fb_helper_set_par) from [] (drm_fb_helper_hotplug_event+0x88/0xc4) [ 55.761906] [] (drm_fb_helper_hotplug_event) from [] (drm_helper_hpd_irq_event+0xc8/0x134) [ 55.771898] [] (drm_helper_hpd_irq_event) from [] (vidi_store_connection+0x90/0xc8) [ 55.781268] [] (vidi_store_connection) from [] (kernfs_fop_write+0xc0/0x180) [ 55.790045] [] (kernfs_fop_write) from [] (vfs_write+0xa0/0x1ac) [ 55.797757] [] (vfs_write) from [] (SyS_write+0x44/0x9c) [ 55.804790] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x30) [ 55.812328] ---[ end trace 3c0fe4386702d4dd ]--- This issue occurs when modeset to vidi is tried in case that drm_vblank_init is called prior to crtc creation of vidi driver. In this case, crtc number of vidi is invalid so any requests with the crtc number will fail. This patch guarantees drm_vblank_init to be called after all kms drivers are ready by using component framework. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 61 +++++++++++++++++------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 3b6fdd614584..45899fb63272 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -14,6 +14,7 @@ #include #include +#include #include @@ -48,11 +49,11 @@ struct vidi_win_data { struct vidi_context { struct exynos_drm_manager manager; struct exynos_drm_display display; + struct platform_device *pdev; struct drm_device *drm_dev; struct drm_crtc *crtc; struct drm_encoder *encoder; struct drm_connector connector; - struct exynos_drm_subdrv subdrv; struct vidi_win_data win_data[WINDOWS_NR]; struct edid *raw_edid; unsigned int clkdiv; @@ -560,9 +561,10 @@ static struct exynos_drm_display_ops vidi_display_ops = { .create_connector = vidi_create_connector, }; -static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) +static int vidi_bind(struct device *dev, struct device *master, void *data) { struct vidi_context *ctx = dev_get_drvdata(dev); + struct drm_device *drm_dev = data; struct drm_crtc *crtc = ctx->crtc; int ret; @@ -584,9 +586,18 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) return 0; } + +static void vidi_unbind(struct device *dev, struct device *master, void *data) +{ +} + +static const struct component_ops vidi_component_ops = { + .bind = vidi_bind, + .unbind = vidi_unbind, +}; + static int vidi_probe(struct platform_device *pdev) { - struct exynos_drm_subdrv *subdrv; struct vidi_context *ctx; int ret; @@ -599,6 +610,17 @@ static int vidi_probe(struct platform_device *pdev) ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI; ctx->display.ops = &vidi_display_ops; ctx->default_win = 0; + ctx->pdev = pdev; + + ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, + ctx->manager.type); + if (ret) + return ret; + + ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR, + ctx->display.type); + if (ret) + goto err_del_crtc_component; INIT_WORK(&ctx->work, vidi_fake_vblank_handler); @@ -606,23 +628,26 @@ static int vidi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - subdrv = &ctx->subdrv; - subdrv->dev = &pdev->dev; - subdrv->probe = vidi_subdrv_probe; - - ret = exynos_drm_subdrv_register(subdrv); - if (ret < 0) { - dev_err(&pdev->dev, "failed to register drm vidi device\n"); - return ret; - } - ret = device_create_file(&pdev->dev, &dev_attr_connection); if (ret < 0) { - exynos_drm_subdrv_unregister(subdrv); - DRM_INFO("failed to create connection sysfs.\n"); + DRM_ERROR("failed to create connection sysfs.\n"); + goto err_del_conn_component; } - return 0; + ret = component_add(&pdev->dev, &vidi_component_ops); + if (ret) + goto err_remove_file; + + return ret; + +err_remove_file: + device_remove_file(&pdev->dev, &dev_attr_connection); +err_del_conn_component: + exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); +err_del_crtc_component: + exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); + + return ret; } static int vidi_remove(struct platform_device *pdev) @@ -636,6 +661,10 @@ static int vidi_remove(struct platform_device *pdev) return -EINVAL; } + component_del(&pdev->dev, &vidi_component_ops); + exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR); + exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); + return 0; } -- GitLab From 1c9ff4ab43a83f2b412f81ad4db862e5533c745d Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 24 Nov 2014 15:19:49 -0200 Subject: [PATCH 6335/9457] drm/exynos: Fix exynos_dpi_remove() parameter exynos_dpi_remove() should receive a exynos_drm_display but when DRM_EXYNOS_DPI was disabled it was receiving a struct device resulting in ia compiler warning. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 2e4e91bf9b07..2e5063488c50 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -307,7 +307,10 @@ int exynos_dpi_remove(struct exynos_drm_display *display); #else static inline struct exynos_drm_display * exynos_dpi_probe(struct device *dev) { return NULL; } -static inline int exynos_dpi_remove(struct device *dev) { return 0; } +static inline int exynos_dpi_remove(struct exynos_drm_display *display) +{ + return 0; +} #endif #ifdef CONFIG_DRM_EXYNOS_VIDI -- GitLab From 5baf5d44fbcde002d7f3f8148e69305f520770dd Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Mon, 24 Nov 2014 16:23:30 -0200 Subject: [PATCH 6336/9457] drm/exynos: avoid leak if exynos_dpi_probe() fails The component must be deleted if the probe fails. Signed-off-by: Gustavo Padovan Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ef80a3537f35..e5810d13bf9c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1215,8 +1215,10 @@ static int fimd_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); ctx->display = exynos_dpi_probe(dev); - if (IS_ERR(ctx->display)) - return PTR_ERR(ctx->display); + if (IS_ERR(ctx->display)) { + ret = PTR_ERR(ctx->display); + goto err_del_component; + } pm_runtime_enable(dev); -- GitLab From 4f8a7c549f373f33c065c9cbb5a5f3f1a9d8f56c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 20 Nov 2014 20:38:50 +0100 Subject: [PATCH 6337/9457] clk: rockchip: add ability to specify pll-specific flags This adds a flag parameter to plls that allows us to create special flags to tweak the behaviour of the plls if necessary. Signed-off-by: Heiko Stuebner Reviewed-by: Kever Yang Tested-by: Kever Yang --- drivers/clk/rockchip/clk-pll.c | 4 +++- drivers/clk/rockchip/clk-rk3188.c | 8 ++++---- drivers/clk/rockchip/clk-rk3288.c | 10 +++++----- drivers/clk/rockchip/clk.c | 3 ++- drivers/clk/rockchip/clk.h | 7 +++++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index a3e886a38480..feb9cad3e676 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -39,6 +39,7 @@ struct rockchip_clk_pll { int lock_offset; unsigned int lock_shift; enum rockchip_pll_type type; + u8 flags; const struct rockchip_pll_rate_table *rate_table; unsigned int rate_count; spinlock_t *lock; @@ -282,7 +283,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock) + u8 clk_pll_flags, spinlock_t *lock) { const char *pll_parents[3]; struct clk_init_data init; @@ -345,6 +346,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->reg_base = base + con_offset; pll->lock_offset = grf_lock_offset; pll->lock_shift = lock_shift; + pll->flags = clk_pll_flags; pll->lock = lock; pll_clk = clk_register(NULL, &pll->hw); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 22dccc6cd664..dc028b754c9e 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -212,13 +212,13 @@ PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), - RK2928_MODE_CON, 0, 6, rk3188_pll_rates), + RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), - RK2928_MODE_CON, 4, 5, NULL), + RK2928_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), - RK2928_MODE_CON, 8, 7, rk3188_pll_rates), + RK2928_MODE_CON, 8, 7, 0, rk3188_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), - RK2928_MODE_CON, 12, 8, rk3188_pll_rates), + RK2928_MODE_CON, 12, 8, 0, rk3188_pll_rates), }; #define MFLAGS CLK_MUX_HIWORD_MASK diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 174589c95e33..2d31a22c0273 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -202,15 +202,15 @@ PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), - RK3288_MODE_CON, 0, 6, rk3288_pll_rates), + RK3288_MODE_CON, 0, 6, 0, rk3288_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), - RK3288_MODE_CON, 4, 5, NULL), + RK3288_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), - RK3288_MODE_CON, 8, 7, rk3288_pll_rates), + RK3288_MODE_CON, 8, 7, 0, rk3288_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), - RK3288_MODE_CON, 12, 8, rk3288_pll_rates), + RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates), [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), - RK3288_MODE_CON, 14, 9, rk3288_pll_rates), + RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), }; static struct clk_div_table div_hclk_cpu_t[] = { diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index dec6f8d6dc13..3b8f26e2cd1a 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -199,7 +199,8 @@ void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, list->parent_names, list->num_parents, reg_base, list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, - list->mode_shift, list->rate_table, &clk_lock); + list->mode_shift, list->rate_table, + list->pll_flags, &clk_lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 6baf6655b5c3..eefd39a3820b 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -90,6 +90,7 @@ struct rockchip_pll_rate_table { * @mode_shift: offset inside the mode-register for the mode of this pll. * @lock_shift: offset inside the lock register for the lock status. * @type: Type of PLL to be registered. + * @pll_flags: hardware-specific flags * @rate_table: Table of usable pll rates */ struct rockchip_pll_clock { @@ -103,11 +104,12 @@ struct rockchip_pll_clock { int mode_shift; int lock_shift; enum rockchip_pll_type type; + u8 pll_flags; struct rockchip_pll_rate_table *rate_table; }; #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ - _lshift, _rtable) \ + _lshift, _pflags, _rtable) \ { \ .id = _id, \ .type = _type, \ @@ -119,6 +121,7 @@ struct rockchip_pll_clock { .mode_offset = _mode, \ .mode_shift = _mshift, \ .lock_shift = _lshift, \ + .pll_flags = _pflags, \ .rate_table = _rtable, \ } @@ -127,7 +130,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int reg_mode, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock); + u8 clk_pll_flags, spinlock_t *lock); struct rockchip_cpuclk_clksel { int reg; -- GitLab From d0e7a0ca4b57483e424334c453818529148baafd Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 20 Nov 2014 20:38:51 +0100 Subject: [PATCH 6338/9457] clk: rockchip: setup pll_mux data earlier In some cases we might need to access the data of the pll mux before the actual mux gets registered - like in the following patch adding an init-callback. Therefore populate pll_mux before registering the core pll-clock. Signed-off-by: Heiko Stuebner Reviewed-by: Kever Yang Tested-by: Kever Yang --- drivers/clk/rockchip/clk-pll.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index feb9cad3e676..1bb68910a76b 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -349,6 +349,19 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->flags = clk_pll_flags; pll->lock = lock; + /* create the mux on top of the real pll */ + pll->pll_mux_ops = &clk_mux_ops; + pll_mux = &pll->pll_mux; + pll_mux->reg = base + mode_offset; + pll_mux->shift = mode_shift; + pll_mux->mask = PLL_MODE_MASK; + pll_mux->flags = 0; + pll_mux->lock = lock; + pll_mux->hw.init = &init; + + if (pll_type == pll_rk3066) + pll_mux->flags |= CLK_MUX_HIWORD_MASK; + pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { pr_err("%s: failed to register pll clock %s : %ld\n", @@ -357,10 +370,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, goto err_pll; } - /* create the mux on top of the real pll */ - pll->pll_mux_ops = &clk_mux_ops; - pll_mux = &pll->pll_mux; - /* the actual muxing is xin24m, pll-output, xin32k */ pll_parents[0] = parent_names[0]; pll_parents[1] = pll_name; @@ -372,16 +381,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, init.parent_names = pll_parents; init.num_parents = ARRAY_SIZE(pll_parents); - pll_mux->reg = base + mode_offset; - pll_mux->shift = mode_shift; - pll_mux->mask = PLL_MODE_MASK; - pll_mux->flags = 0; - pll_mux->lock = lock; - pll_mux->hw.init = &init; - - if (pll_type == pll_rk3066) - pll_mux->flags |= CLK_MUX_HIWORD_MASK; - mux_clk = clk_register(NULL, &pll_mux->hw); if (IS_ERR(mux_clk)) goto err_mux; -- GitLab From 0bb66d3b6e78168f8f49c7a41060508707f04d1d Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 20 Nov 2014 20:38:52 +0100 Subject: [PATCH 6339/9457] clk: rockchip: add optional sync to pll rate parameters In some cases firmware brings up plls with different parameters than the ones noted in the rate table for the specific frequency. These firmware-selected parameters are worse than the tested ones in the pll rate tables but cannot be changed by a simple clk_set_rate call when the rate stays the same. Therefore add a ROCKCHIP_PLL_SYNC_RATE flag and implement an init callback that checks the runtime-parameters against the matching rate table entry and adjusts them to the table-ones if necessary. If no rate table is set or the current rate does not match any rate-table entry no changes are made. Being able to limit this adjustment to specific plls is necessary to not touch the ones supplying core components like the apll and dpll supplying the armcores and dram. Signed-off-by: Heiko Stuebner Reviewed-by: Kever Yang Tested-by: Kever Yang --- drivers/clk/rockchip/clk-pll.c | 50 ++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 6 ++++ 2 files changed, 56 insertions(+) diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 1bb68910a76b..f8d3baf275b2 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -258,6 +258,55 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3066_PLLCON3_PWRDOWN); } +static void rockchip_rk3066_pll_init(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + const struct rockchip_pll_rate_table *rate; + unsigned int nf, nr, no, bwadj; + unsigned long drate; + u32 pllcon; + + if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) + return; + + drate = __clk_get_rate(hw->clk); + rate = rockchip_get_pll_settings(pll, drate); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + return; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); + nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1; + no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); + nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); + bwadj = (pllcon >> RK3066_PLLCON2_BWADJ_SHIFT) & RK3066_PLLCON2_BWADJ_MASK; + + pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), bwadj(%d:%d)\n", + __func__, __clk_get_name(hw->clk), drate, rate->nr, nr, + rate->no, no, rate->nf, nf, rate->bwadj, bwadj); + if (rate->nr != nr || rate->no != no || rate->nf != nf + || rate->bwadj != bwadj) { + struct clk *parent = __clk_get_parent(hw->clk); + unsigned long prate; + + if (!parent) { + pr_warn("%s: parent of %s not available\n", + __func__, __clk_get_name(hw->clk)); + return; + } + + pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", + __func__, __clk_get_name(hw->clk)); + prate = __clk_get_rate(parent); + rockchip_rk3066_pll_set_rate(hw, drate, prate); + } +} + static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { .recalc_rate = rockchip_rk3066_pll_recalc_rate, .enable = rockchip_rk3066_pll_enable, @@ -272,6 +321,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { .enable = rockchip_rk3066_pll_enable, .disable = rockchip_rk3066_pll_disable, .is_enabled = rockchip_rk3066_pll_is_enabled, + .init = rockchip_rk3066_pll_init, }; /* diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index eefd39a3820b..dc9468132ef1 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -92,6 +92,10 @@ struct rockchip_pll_rate_table { * @type: Type of PLL to be registered. * @pll_flags: hardware-specific flags * @rate_table: Table of usable pll rates + * + * Flags: + * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the + * rate_table parameters and ajust them if necessary. */ struct rockchip_pll_clock { unsigned int id; @@ -108,6 +112,8 @@ struct rockchip_pll_clock { struct rockchip_pll_rate_table *rate_table; }; +#define ROCKCHIP_PLL_SYNC_RATE BIT(0) + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ _lshift, _pflags, _rtable) \ { \ -- GitLab From dd79c0bea70516f52edc01c32e3f1ac7f20751a5 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 20 Nov 2014 20:38:53 +0100 Subject: [PATCH 6340/9457] clk: rockchip: add ROCKCHIP_PLL_SYNC_RATE flag to some plls Add the new flag to gpll and cpll on rk3188 and similar and to gpll, cpll and npll on rk3288. Signed-off-by: Heiko Stuebner Reviewed-by: Kever Yang Tested-by: Kever Yang --- drivers/clk/rockchip/clk-rk3188.c | 4 ++-- drivers/clk/rockchip/clk-rk3288.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index dc028b754c9e..c54078960847 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -216,9 +216,9 @@ static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), RK2928_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), - RK2928_MODE_CON, 8, 7, 0, rk3188_pll_rates), + RK2928_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), - RK2928_MODE_CON, 12, 8, 0, rk3188_pll_rates), + RK2928_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), }; #define MFLAGS CLK_MUX_HIWORD_MASK diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 2d31a22c0273..ad8a27a9cd50 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -206,11 +206,11 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), RK3288_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), - RK3288_MODE_CON, 8, 7, 0, rk3288_pll_rates), + RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), - RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), - RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), + RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), }; static struct clk_div_table div_hclk_cpu_t[] = { -- GitLab From ea9eba6a8b6b5d7a48b902d92dc2adb63b4371c0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 21 Nov 2014 15:24:31 +0100 Subject: [PATCH 6341/9457] cfg80211: remove pointless channel lookup in survey code We have a channel pointer, and we use its center frequency to look up a channel pointer - which will thus be exactly the same as the original pointer. Remove that pointless lookup and just use the pointer. Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6e4177701d86..b5e3c489239d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6562,8 +6562,6 @@ static int nl80211_dump_survey(struct sk_buff *skb, } while (1) { - struct ieee80211_channel *chan; - res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey); if (res == -ENOENT) break; @@ -6576,9 +6574,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, goto out; } - chan = ieee80211_get_channel(&rdev->wiphy, - survey.channel->center_freq); - if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { + if (survey.channel->flags & IEEE80211_CHAN_DISABLED) { survey_idx++; continue; } -- GitLab From 40a11ca83de91f6bb2306580e7732ad3d97f201a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 24 Nov 2014 15:49:44 +0100 Subject: [PATCH 6342/9457] mac80211: check if channels allow 80 MHz for VHT probe requests If there are no channels allowing 80 MHz to be used, then the station isn't really VHT capable even if the driver and device support it in general. In this case, exclude the VHT capability IE from probe request frames. Signed-off-by: Johannes Berg --- net/mac80211/util.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bb9664cb8831..974ebe70f5b0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1339,6 +1339,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, int ext_rates_len; int shift; u32 rate_flags; + bool have_80mhz = false; *offset = 0; @@ -1467,7 +1468,15 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, *offset = noffset; } - if (sband->vht_cap.vht_supported) { + /* Check if any channel in this sband supports at least 80 MHz */ + for (i = 0; i < sband->n_channels; i++) { + if (!(sband->channels[i].flags & IEEE80211_CHAN_NO_80MHZ)) { + have_80mhz = true; + break; + } + } + + if (sband->vht_cap.vht_supported && have_80mhz) { if (end - pos < 2 + sizeof(struct ieee80211_vht_cap)) goto out_err; pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, -- GitLab From a48ff17dbb8e1c11f2856ee318170b018d5aa6df Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2014 10:31:18 -0300 Subject: [PATCH 6343/9457] [media] staging/media/Makefile: drop omap24xx reference The omap2 media driver got removed. Remove a left-over for tcm825x driver that were also at omap2 tree. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 97bfef97f838..30fb352fc4a9 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ -obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/ obj-$(CONFIG_DVB_MN88472) += mn88472/ obj-$(CONFIG_DVB_MN88473) += mn88473/ -- GitLab From 6dfa5131804e8cc0866e2f21ed79ce4b08976cff Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Tue, 18 Nov 2014 08:23:39 -0300 Subject: [PATCH 6344/9457] [media] media: vivid: use vb2_ops_wait_prepare/finish helper Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 19 +++++-------------- drivers/media/platform/vivid/vivid-core.h | 3 --- drivers/media/platform/vivid/vivid-sdr-cap.c | 4 ++-- drivers/media/platform/vivid/vivid-vbi-cap.c | 4 ++-- drivers/media/platform/vivid/vivid-vbi-out.c | 4 ++-- drivers/media/platform/vivid/vivid-vid-cap.c | 4 ++-- drivers/media/platform/vivid/vivid-vid-out.c | 4 ++-- 7 files changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 686c3c2ad05b..987a46cdea5e 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -195,20 +195,6 @@ static const u8 vivid_hdmi_edid[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7 }; -void vivid_lock(struct vb2_queue *vq) -{ - struct vivid_dev *dev = vb2_get_drv_priv(vq); - - mutex_lock(&dev->mutex); -} - -void vivid_unlock(struct vb2_queue *vq) -{ - struct vivid_dev *dev = vb2_get_drv_priv(vq); - - mutex_unlock(&dev->mutex); -} - static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -1018,6 +1004,7 @@ static int __init vivid_create_instance(int inst) q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 2; + q->lock = &dev->mutex; ret = vb2_queue_init(q); if (ret) @@ -1036,6 +1023,7 @@ static int __init vivid_create_instance(int inst) q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 2; + q->lock = &dev->mutex; ret = vb2_queue_init(q); if (ret) @@ -1054,6 +1042,7 @@ static int __init vivid_create_instance(int inst) q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 2; + q->lock = &dev->mutex; ret = vb2_queue_init(q); if (ret) @@ -1072,6 +1061,7 @@ static int __init vivid_create_instance(int inst) q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 2; + q->lock = &dev->mutex; ret = vb2_queue_init(q); if (ret) @@ -1089,6 +1079,7 @@ static int __init vivid_create_instance(int inst) q->mem_ops = &vb2_vmalloc_memops; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 8; + q->lock = &dev->mutex; ret = vb2_queue_init(q); if (ret) diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 811c286491a5..6f4445ad7d4d 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -514,7 +514,4 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev) return dev->output_type[dev->output] == HDMI; } -void vivid_lock(struct vb2_queue *vq); -void vivid_unlock(struct vb2_queue *vq); - #endif diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c index 8c5d661cfc49..4af55f18829f 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.c +++ b/drivers/media/platform/vivid/vivid-sdr-cap.c @@ -297,8 +297,8 @@ const struct vb2_ops vivid_sdr_cap_qops = { .buf_queue = sdr_cap_buf_queue, .start_streaming = sdr_cap_start_streaming, .stop_streaming = sdr_cap_stop_streaming, - .wait_prepare = vivid_unlock, - .wait_finish = vivid_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band) diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c b/drivers/media/platform/vivid/vivid-vbi-cap.c index 2166d0bf6fe2..ef81b01b53d2 100644 --- a/drivers/media/platform/vivid/vivid-vbi-cap.c +++ b/drivers/media/platform/vivid/vivid-vbi-cap.c @@ -236,8 +236,8 @@ const struct vb2_ops vivid_vbi_cap_qops = { .buf_queue = vbi_cap_buf_queue, .start_streaming = vbi_cap_start_streaming, .stop_streaming = vbi_cap_stop_streaming, - .wait_prepare = vivid_unlock, - .wait_finish = vivid_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c b/drivers/media/platform/vivid/vivid-vbi-out.c index 9d00a07ecdcd..4e4c70e1e04a 100644 --- a/drivers/media/platform/vivid/vivid-vbi-out.c +++ b/drivers/media/platform/vivid/vivid-vbi-out.c @@ -131,8 +131,8 @@ const struct vb2_ops vivid_vbi_out_qops = { .buf_queue = vbi_out_buf_queue, .start_streaming = vbi_out_start_streaming, .stop_streaming = vbi_out_stop_streaming, - .wait_prepare = vivid_unlock, - .wait_finish = vivid_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; int vidioc_g_fmt_vbi_out(struct file *file, void *priv, diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 331c54429b40..1309d311c627 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -288,8 +288,8 @@ const struct vb2_ops vivid_vid_cap_qops = { .buf_queue = vid_cap_buf_queue, .start_streaming = vid_cap_start_streaming, .stop_streaming = vid_cap_stop_streaming, - .wait_prepare = vivid_unlock, - .wait_finish = vivid_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 69c2dbd2d165..078bc35571b4 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -209,8 +209,8 @@ const struct vb2_ops vivid_vid_out_qops = { .buf_queue = vid_out_buf_queue, .start_streaming = vid_out_start_streaming, .stop_streaming = vid_out_stop_streaming, - .wait_prepare = vivid_unlock, - .wait_finish = vivid_lock, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* -- GitLab From 872dfcfe82438f5211f5fa1dc6406d033a8a2448 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Nov 2014 07:57:12 -0300 Subject: [PATCH 6345/9457] [media] bttv/cx25821/cx88/ivtv: use sg_next instead of sg++ Never use sg++, always use sg = sg_next(sg). Scatterlist entries can be combined if the memory is contiguous but sg++ won't know about that. As far as I can tell cx88 and ivtv are really broken because of this, and bttv and cx25821 are OK because vb1 doesn't combine scatterlist entries. But regardless, sg++ should never be used, only sg_next is safe. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-risc.c | 12 ++++++------ drivers/media/pci/cx25821/cx25821-core.c | 12 ++++++------ drivers/media/pci/cx88/cx88-core.c | 6 +++--- drivers/media/pci/ivtv/ivtv-udma.c | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c index 82cc47d2e3fa..4d3f05a19af3 100644 --- a/drivers/media/pci/bt8xx/bttv-risc.c +++ b/drivers/media/pci/bt8xx/bttv-risc.c @@ -84,7 +84,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, continue; while (offset && offset >= sg_dma_len(sg)) { offset -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } if (bpl <= sg_dma_len(sg)-offset) { /* fits into current chunk */ @@ -100,13 +100,13 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); todo -= (sg_dma_len(sg)-offset); offset = 0; - sg++; + sg = sg_next(sg); while (todo > sg_dma_len(sg)) { *(rp++)=cpu_to_le32(BT848_RISC_WRITE| sg_dma_len(sg)); *(rp++)=cpu_to_le32(sg_dma_address(sg)); todo -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| todo); @@ -187,15 +187,15 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, /* go to next sg entry if needed */ while (yoffset && yoffset >= sg_dma_len(ysg)) { yoffset -= sg_dma_len(ysg); - ysg++; + ysg = sg_next(ysg); } while (uoffset && uoffset >= sg_dma_len(usg)) { uoffset -= sg_dma_len(usg); - usg++; + usg = sg_next(usg); } while (voffset && voffset >= sg_dma_len(vsg)) { voffset -= sg_dma_len(vsg); - vsg++; + vsg = sg_next(vsg); } /* calculate max number of bytes we can write */ diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index e81173c41e5a..389fffd2f36f 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -996,7 +996,7 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, for (line = 0; line < lines; line++) { while (offset && offset >= sg_dma_len(sg)) { offset -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } if (bpl <= sg_dma_len(sg) - offset) { /* fits into current chunk */ @@ -1014,14 +1014,14 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= (sg_dma_len(sg) - offset); offset = 0; - sg++; + sg = sg_next(sg); while (todo > sg_dma_len(sg)) { *(rp++) = cpu_to_le32(RISC_WRITE | sg_dma_len(sg)); *(rp++) = cpu_to_le32(sg_dma_address(sg)); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo); *(rp++) = cpu_to_le32(sg_dma_address(sg)); @@ -1101,7 +1101,7 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, for (line = 0; line < lines; line++) { while (offset && offset >= sg_dma_len(sg)) { offset -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } if (lpi && line > 0 && !(line % lpi)) @@ -1125,14 +1125,14 @@ static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist, *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= (sg_dma_len(sg) - offset); offset = 0; - sg++; + sg = sg_next(sg); while (todo > sg_dma_len(sg)) { *(rp++) = cpu_to_le32(RISC_WRITE | sg_dma_len(sg)); *(rp++) = cpu_to_le32(sg_dma_address(sg)); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ todo -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo); *(rp++) = cpu_to_le32(sg_dma_address(sg)); diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 9fa4acbdcab8..dee177ed5fe9 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -95,7 +95,7 @@ static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, for (line = 0; line < lines; line++) { while (offset && offset >= sg_dma_len(sg)) { offset -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } if (lpi && line>0 && !(line % lpi)) sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; @@ -114,13 +114,13 @@ static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); todo -= (sg_dma_len(sg)-offset); offset = 0; - sg++; + sg = sg_next(sg); while (todo > sg_dma_len(sg)) { *(rp++)=cpu_to_le32(RISC_WRITE| sg_dma_len(sg)); *(rp++)=cpu_to_le32(sg_dma_address(sg)); todo -= sg_dma_len(sg); - sg++; + sg = sg_next(sg); } *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); *(rp++)=cpu_to_le32(sg_dma_address(sg)); diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c index 7338cb2d0a38..bee2329e0b2e 100644 --- a/drivers/media/pci/ivtv/ivtv-udma.c +++ b/drivers/media/pci/ivtv/ivtv-udma.c @@ -76,7 +76,7 @@ void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32 int i; struct scatterlist *sg; - for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) { + for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg = sg_next(sg)) { dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg)); dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg)); dma->SGarray[i].dst = cpu_to_le32(buffer_offset); -- GitLab From 66333cb3d7d4ff853b6945f01e68d8986d821235 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 Nov 2014 13:21:30 +0300 Subject: [PATCH 6346/9457] amdkfd: fix some error handling in ioctl There is a typo here so the errors from kfd_bind_process_to_device() are not detected. Reviewed-by: Oded Gabbay Signed-off-by: Dan Carpenter Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 3b3fce733136..102cd36799b1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -242,7 +242,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, mutex_lock(&p->mutex); pdd = kfd_bind_process_to_device(dev, p); - if (IS_ERR(pdd) < 0) { + if (IS_ERR(pdd)) { err = PTR_ERR(pdd); goto err_bind_process; } @@ -389,7 +389,7 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, mutex_lock(&p->mutex); pdd = kfd_bind_process_to_device(dev, p); - if (IS_ERR(pdd) < 0) { + if (IS_ERR(pdd)) { err = PTR_ERR(pdd); goto out; } -- GitLab From d9bfbcc0c2bc15b9ce79e71a0b3d7e69a714d621 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2014 09:14:01 -0300 Subject: [PATCH 6347/9457] [media] v4l2-dev: vdev->v4l2_dev is always set, so simplify code These days vdev->v4l2_dev must always be set. This means that some old code that still tests for a NULL vdev->v4l2_dev can be removed or simplified. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 34 ++++++++++++------------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 33617c365acc..9aa530a8bea9 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -194,7 +194,7 @@ static void v4l2_device_release(struct device *cd) mutex_unlock(&videodev_lock); #if defined(CONFIG_MEDIA_CONTROLLER) - if (v4l2_dev && v4l2_dev->mdev && + if (v4l2_dev->mdev && vdev->vfl_type != VFL_TYPE_SUBDEV) media_device_unregister_entity(&vdev->entity); #endif @@ -207,7 +207,7 @@ static void v4l2_device_release(struct device *cd) * TODO: In the long run all drivers that use v4l2_device should use the * v4l2_device release callback. This check will then be unnecessary. */ - if (v4l2_dev && v4l2_dev->release == NULL) + if (v4l2_dev->release == NULL) v4l2_dev = NULL; /* Release video_device and perform other @@ -360,27 +360,22 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) * hack but it will have to do for those drivers that are not * yet converted to use unlocked_ioctl. * - * There are two options: if the driver implements struct - * v4l2_device, then the lock defined there is used to - * serialize the ioctls. Otherwise the v4l2 core lock defined - * below is used. This lock is really bad since it serializes - * completely independent devices. + * All drivers implement struct v4l2_device, so we use the + * lock defined there to serialize the ioctls. * - * Both variants suffer from the same problem: if the driver - * sleeps, then it blocks all ioctls since the lock is still - * held. This is very common for VIDIOC_DQBUF since that - * normally waits for a frame to arrive. As a result any other - * ioctl calls will proceed very, very slowly since each call - * will have to wait for the VIDIOC_QBUF to finish. Things that - * should take 0.01s may now take 10-20 seconds. + * However, if the driver sleeps, then it blocks all ioctls + * since the lock is still held. This is very common for + * VIDIOC_DQBUF since that normally waits for a frame to arrive. + * As a result any other ioctl calls will proceed very, very + * slowly since each call will have to wait for the VIDIOC_QBUF + * to finish. Things that should take 0.01s may now take 10-20 + * seconds. * * The workaround is to *not* take the lock for VIDIOC_DQBUF. * This actually works OK for videobuf-based drivers, since * videobuf will take its own internal lock. */ - static DEFINE_MUTEX(v4l2_ioctl_mutex); - struct mutex *m = vdev->v4l2_dev ? - &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex; + struct mutex *m = &vdev->v4l2_dev->ioctl_lock; if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) return -ERESTARTSYS; @@ -938,12 +933,11 @@ int __video_register_device(struct video_device *vdev, int type, int nr, name_base, nr, video_device_node_name(vdev)); /* Increase v4l2_device refcount */ - if (vdev->v4l2_dev) - v4l2_device_get(vdev->v4l2_dev); + v4l2_device_get(vdev->v4l2_dev); #if defined(CONFIG_MEDIA_CONTROLLER) /* Part 5: Register the entity. */ - if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && + if (vdev->v4l2_dev->mdev && vdev->vfl_type != VFL_TYPE_SUBDEV) { vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; vdev->entity.name = vdev->name; -- GitLab From 4ed0d6a9cf80a4a1f74e18d36a2ee5ef391a8f27 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2014 09:39:53 -0300 Subject: [PATCH 6348/9457] [media] v4l2-common: remove unused helper functions Several control helper functions are no longer needed since most drivers are now converted to the control framework. So we can delete them. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-common.c | 95 --------------------------- include/media/v4l2-common.h | 10 --- 2 files changed, 105 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 2e9d81f4c1a5..849320932657 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -135,101 +135,6 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _ } EXPORT_SYMBOL(v4l2_ctrl_query_fill); -/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and - the menu. The qctrl pointer may be NULL, in which case it is ignored. - If menu_items is NULL, then the menu items are retrieved using - v4l2_ctrl_get_menu. */ -int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, - const char * const *menu_items) -{ - int i; - - qmenu->reserved = 0; - if (menu_items == NULL) - menu_items = v4l2_ctrl_get_menu(qmenu->id); - if (menu_items == NULL || - (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) - return -EINVAL; - for (i = 0; i < qmenu->index && menu_items[i]; i++) ; - if (menu_items[i] == NULL || menu_items[i][0] == '\0') - return -EINVAL; - strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name)); - return 0; -} -EXPORT_SYMBOL(v4l2_ctrl_query_menu); - -/* Fill in a struct v4l2_querymenu based on the specified array of valid - menu items (terminated by V4L2_CTRL_MENU_IDS_END). - Use this if there are 'holes' in the list of valid menu items. */ -int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) -{ - const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id); - - qmenu->reserved = 0; - if (menu_items == NULL || ids == NULL) - return -EINVAL; - while (*ids != V4L2_CTRL_MENU_IDS_END) { - if (*ids++ == qmenu->index) { - strlcpy(qmenu->name, menu_items[qmenu->index], - sizeof(qmenu->name)); - return 0; - } - } - return -EINVAL; -} -EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items); - -/* ctrl_classes points to an array of u32 pointers, the last element is - a NULL pointer. Each u32 array is a 0-terminated array of control IDs. - Each array must be sorted low to high and belong to the same control - class. The array of u32 pointers must also be sorted, from low class IDs - to high class IDs. - - This function returns the first ID that follows after the given ID. - When no more controls are available 0 is returned. */ -u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) -{ - u32 ctrl_class = V4L2_CTRL_ID2CLASS(id); - const u32 *pctrl; - - if (ctrl_classes == NULL) - return 0; - - /* if no query is desired, then check if the ID is part of ctrl_classes */ - if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) { - /* find class */ - while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class) - ctrl_classes++; - if (*ctrl_classes == NULL) - return 0; - pctrl = *ctrl_classes; - /* find control ID */ - while (*pctrl && *pctrl != id) pctrl++; - return *pctrl ? id : 0; - } - id &= V4L2_CTRL_ID_MASK; - id++; /* select next control */ - /* find first class that matches (or is greater than) the class of - the ID */ - while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class) - ctrl_classes++; - /* no more classes */ - if (*ctrl_classes == NULL) - return 0; - pctrl = *ctrl_classes; - /* find first ctrl within the class that is >= ID */ - while (*pctrl && *pctrl < id) pctrl++; - if (*pctrl) - return *pctrl; - /* we are at the end of the controls of the current class. */ - /* continue with next class if available */ - ctrl_classes++; - if (*ctrl_classes == NULL) - return 0; - return **ctrl_classes; -} -EXPORT_SYMBOL(v4l2_ctrl_next); - /* I2C Helper functions */ #if IS_ENABLED(CONFIG_I2C) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 48f974866f13..6b4951de7592 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -88,16 +88,6 @@ const char *v4l2_ctrl_get_name(u32 id); const char * const *v4l2_ctrl_get_menu(u32 id); const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len); int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def); -int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, - struct v4l2_queryctrl *qctrl, const char * const *menu_items); -#define V4L2_CTRL_MENU_IDS_END (0xffffffff) -int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids); - -/* Note: ctrl_classes points to an array of u32 pointers. Each u32 array is a - 0-terminated array of control IDs. Each array must be sorted low to high - and belong to the same control class. The array of u32 pointers must also - be sorted, from low class IDs to high class IDs. */ -u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id); /* ------------------------------------------------------------------------- */ -- GitLab From 79fbc209f11b82d8cad37e20da71851fdceecfbd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2014 09:39:54 -0300 Subject: [PATCH 6349/9457] [media] v4l2-ctrl: move function prototypes from common.h to ctrls.h For some unknown reason several control prototypes where in v4l2-common.c instead of in v4l2-ctrls.h. Move them and document them. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 3 --- include/media/v4l2-ctrls.h | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 6b4951de7592..c69d91d32e59 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -84,9 +84,6 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, const char * const *menu_items); -const char *v4l2_ctrl_get_name(u32 id); -const char * const *v4l2_ctrl_get_menu(u32 id); -const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len); int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def); /* ------------------------------------------------------------------------- */ diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index b7cd7a665e35..911f3e542834 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -670,6 +670,31 @@ static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, */ void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv); +/** v4l2_ctrl_get_name() - Get the name of the control + * @id: The control ID. + * + * This function returns the name of the given control ID or NULL if it isn't + * a known control. + */ +const char *v4l2_ctrl_get_name(u32 id); + +/** v4l2_ctrl_get_menu() - Get the menu string array of the control + * @id: The control ID. + * + * This function returns the NULL-terminated menu string array name of the + * given control ID or NULL if it isn't a known menu control. + */ +const char * const *v4l2_ctrl_get_menu(u32 id); + +/** v4l2_ctrl_get_int_menu() - Get the integer menu array of the control + * @id: The control ID. + * @len: The size of the integer array. + * + * This function returns the integer array of the given control ID or NULL if it + * if it isn't a known integer menu control. + */ +const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len); + /** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. * @ctrl: The control. * -- GitLab From e048a0b26033b35eb36c20e4d36fb466a2570c27 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 Nov 2014 13:24:51 +0300 Subject: [PATCH 6350/9457] amdkfd: fix an error handling bug in pqm_create_queue() The call to kernel_queue_uninit(NULL) will trigger a BUG(), and also the error code is incorrect. Fixes: 45102048f77e ('amdkfd: Add process queue manager module') Reviewed-by: Oded Gabbay Signed-off-by: Dan Carpenter Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index de2c16345693..47526780d736 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -208,7 +208,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, case KFD_QUEUE_TYPE_DIQ: kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ); if (kq == NULL) { - kernel_queue_uninit(kq); + retval = -ENOMEM; goto err_create_queue; } kq->queue->properties.queue_id = *qid; -- GitLab From 4daee77976718b3e8136e37872d7ad5c36754e25 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2014 09:39:55 -0300 Subject: [PATCH 6351/9457] [media] v4l2-common: move v4l2_ctrl_check to cx2341x The v4l2_ctrl_check() helper function is now only used in cx2341x. Move it there and make it static. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/cx2341x.c | 29 ++++++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-common.c | 30 --------------------------- include/media/v4l2-common.h | 4 +--- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/drivers/media/common/cx2341x.c b/drivers/media/common/cx2341x.c index be763150b8aa..c07b9db51b05 100644 --- a/drivers/media/common/cx2341x.c +++ b/drivers/media/common/cx2341x.c @@ -931,6 +931,35 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) } } +/* Check for correctness of the ctrl's value based on the data from + struct v4l2_queryctrl and the available menu items. Note that + menu_items may be NULL, in that case it is ignored. */ +static int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, + const char * const *menu_items) +{ + if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) + return -EINVAL; + if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED) + return -EBUSY; + if (qctrl->type == V4L2_CTRL_TYPE_STRING) + return 0; + if (qctrl->type == V4L2_CTRL_TYPE_BUTTON || + qctrl->type == V4L2_CTRL_TYPE_INTEGER64 || + qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) + return 0; + if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum) + return -ERANGE; + if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) { + if (menu_items[ctrl->value] == NULL || + menu_items[ctrl->value][0] == '\0') + return -EINVAL; + } + if (qctrl->type == V4L2_CTRL_TYPE_BITMASK && + (ctrl->value & ~qctrl->maximum)) + return -ERANGE; + return 0; +} + int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, struct v4l2_ext_controls *ctrls, unsigned int cmd) { diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 849320932657..5b808500e7e7 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -80,36 +80,6 @@ MODULE_LICENSE("GPL"); /* Helper functions for control handling */ -/* Check for correctness of the ctrl's value based on the data from - struct v4l2_queryctrl and the available menu items. Note that - menu_items may be NULL, in that case it is ignored. */ -int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, - const char * const *menu_items) -{ - if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) - return -EINVAL; - if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED) - return -EBUSY; - if (qctrl->type == V4L2_CTRL_TYPE_STRING) - return 0; - if (qctrl->type == V4L2_CTRL_TYPE_BUTTON || - qctrl->type == V4L2_CTRL_TYPE_INTEGER64 || - qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) - return 0; - if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum) - return -ERANGE; - if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) { - if (menu_items[ctrl->value] == NULL || - menu_items[ctrl->value][0] == '\0') - return -EINVAL; - } - if (qctrl->type == V4L2_CTRL_TYPE_BITMASK && - (ctrl->value & ~qctrl->maximum)) - return -ERANGE; - return 0; -} -EXPORT_SYMBOL(v4l2_ctrl_check); - /* Fill in a struct v4l2_queryctrl */ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def) { diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index c69d91d32e59..1cc0c5ba16b3 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -80,10 +80,8 @@ /* ------------------------------------------------------------------------- */ -/* Control helper functions */ +/* Control helper function */ -int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, - const char * const *menu_items); int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def); /* ------------------------------------------------------------------------- */ -- GitLab From e1b78a335996031fea81d3dcbea9724ed3dd4a80 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 6 Aug 2014 17:50:49 -0300 Subject: [PATCH 6352/9457] [media] uvcvideo: Add quirk to force the Oculus DK2 IR tracker to grayscale This patch adds a quirk to force Y8 pixel format even if the camera reports half-width YUYV. Signed-off-by: Philipp Zabel Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 27 ++++++++++++++++++++++++++- drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 7c8322d4fc63..b7e111df5c3c 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -331,6 +331,7 @@ static int uvc_parse_format(struct uvc_device *dev, struct uvc_format_desc *fmtdesc; struct uvc_frame *frame; const unsigned char *start = buffer; + unsigned int width_multiplier = 1; unsigned int interval; unsigned int i, n; __u8 ftype; @@ -366,6 +367,20 @@ static int uvc_parse_format(struct uvc_device *dev, } format->bpp = buffer[21]; + + /* Some devices report a format that doesn't match what they + * really send. + */ + if (dev->quirks & UVC_QUIRK_FORCE_Y8) { + if (format->fcc == V4L2_PIX_FMT_YUYV) { + strlcpy(format->name, "Greyscale 8-bit (Y8 )", + sizeof(format->name)); + format->fcc = V4L2_PIX_FMT_GREY; + format->bpp = 8; + width_multiplier = 2; + } + } + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { @@ -474,7 +489,8 @@ static int uvc_parse_format(struct uvc_device *dev, frame->bFrameIndex = buffer[3]; frame->bmCapabilities = buffer[4]; - frame->wWidth = get_unaligned_le16(&buffer[5]); + frame->wWidth = get_unaligned_le16(&buffer[5]) + * width_multiplier; frame->wHeight = get_unaligned_le16(&buffer[7]); frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); @@ -2504,6 +2520,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT }, + /* Oculus VR Positional Tracker DK2 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x2833, + .idProduct = 0x0201, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FORCE_Y8 }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 864ada740360..2600c9667a64 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -148,6 +148,7 @@ #define UVC_QUIRK_PROBE_DEF 0x00000100 #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 +#define UVC_QUIRK_FORCE_Y8 0x00000800 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -- GitLab From 2228d80dd05a4fc5a410fde847677b8fb3eb23d7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 24 Oct 2014 05:10:20 -0300 Subject: [PATCH 6353/9457] [media] uvcvideo: Fix destruction order in uvc_delete() We've got a bug report at disconnecting a Webcam, where the kernel spews warnings like below: WARNING: CPU: 0 PID: 8385 at ../fs/sysfs/group.c:219 sysfs_remove_group+0x87/0x90() sysfs group c0b2350c not found for kobject 'event3' CPU: 0 PID: 8385 Comm: queue2:src Not tainted 3.16.2-1.gdcee397-default #1 Hardware name: ASUSTeK Computer INC. A7N8X-E/A7N8X-E, BIOS ASUS A7N8X-E Deluxe ACPI BIOS Rev 1013 11/12/2004 c08d0705 ddc75cbc c0718c5b ddc75ccc c024b654 c08c6d44 ddc75ce8 000020c1 c08d0705 000000db c03d1ec7 c03d1ec7 00000009 00000000 c0b2350c d62c9064 ddc75cd4 c024b6a3 00000009 ddc75ccc c08c6d44 ddc75ce8 ddc75cfc c03d1ec7 Call Trace: [] try_stack_unwind+0x156/0x170 [] dump_trace+0x53/0x180 [] show_trace_log_lvl+0x46/0x50 [] show_stack_log_lvl+0x51/0xe0 [] show_stack+0x27/0x50 [] dump_stack+0x3e/0x4e [] warn_slowpath_common+0x84/0xa0 [] warn_slowpath_fmt+0x33/0x40 [] sysfs_remove_group+0x87/0x90 [] device_del+0x34/0x180 [] evdev_disconnect+0x19/0x50 [] __input_unregister_device+0x9a/0x140 [] input_unregister_device+0x45/0x80 [] uvc_delete+0x26/0x110 [uvcvideo] [] v4l2_device_release+0x98/0xc0 [videodev] [] device_release+0x2b/0x90 [] kobject_cleanup+0x6f/0x1a0 [] v4l2_release+0x43/0x70 [videodev] [] __fput+0xb1/0x1b0 [] task_work_run+0x91/0xb0 [] do_exit+0x265/0x910 [] do_group_exit+0x34/0xa0 [] get_signal_to_deliver+0x17f/0x590 [] do_signal+0x3a/0x960 [] do_notify_resume+0x67/0x90 [] work_notifysig+0x30/0x3b [] 0xb7739e5f ---[ end trace b1e56095a485b631 ]--- The cause is that uvc_status_cleanup() is called after usb_put_*() in uvc_delete(). usb_put_*() removes the sysfs parent and eventually removes the children recursively, so the later device_del() can't find its sysfs. The fix is simply rearrange the call orders in uvc_delete() so that the child is removed before the parent. Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=897736 Reported-and-tested-by: Martin Pluskal Cc: Signed-off-by: Takashi Iwai Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index b7e111df5c3c..a327f3d09420 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1639,12 +1639,12 @@ static void uvc_delete(struct uvc_device *dev) { struct list_head *p, *n; - usb_put_intf(dev->intf); - usb_put_dev(dev->udev); - uvc_status_cleanup(dev); uvc_ctrl_cleanup_device(dev); + usb_put_intf(dev->intf); + usb_put_dev(dev->udev); + if (dev->vdev.dev) v4l2_device_unregister(&dev->vdev); #ifdef CONFIG_MEDIA_CONTROLLER -- GitLab From 59b702ea9f4467bf6b6281d5d21cebfc1fa11e8d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 31 Oct 2014 10:01:49 -0300 Subject: [PATCH 6354/9457] [media] v4l2: get/set prio using video_dev prio structure The v4l2_device structure embed a v4l2_prio_state structure used by default for priority handling, but drivers can override that default by setting the video_dev prio pointer to a different v4l2_prio_state instance. However, the VIDIO_G_PRIORITY and VIDIOC_S_PRIORITY implementations use the prio state embedded in v4l2_device unconditionally, breaking drivers that need to override the default. Fix them. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 9ccb19a435ef..1bf84a584242 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1040,7 +1040,7 @@ static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, if (ops->vidioc_g_priority) return ops->vidioc_g_priority(file, fh, arg); vfd = video_devdata(file); - *p = v4l2_prio_max(&vfd->v4l2_dev->prio); + *p = v4l2_prio_max(vfd->prio); return 0; } @@ -1055,7 +1055,7 @@ static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, return ops->vidioc_s_priority(file, fh, *p); vfd = video_devdata(file); vfh = file->private_data; - return v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p); + return v4l2_prio_change(vfd->prio, &vfh->prio, *p); } static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, -- GitLab From d5e90b7a6cd1ce9512f8a2c9b1be70155300d2da Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Sep 2010 10:17:54 -0300 Subject: [PATCH 6355/9457] [media] uvcvideo: Move to video_ioctl2 Simplify ioctl handling by using video_ioctl2. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 1 + drivers/media/usb/uvc/uvc_v4l2.c | 1010 +++++++++++++++------------- drivers/media/usb/uvc/uvcvideo.h | 2 +- 3 files changed, 559 insertions(+), 454 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index a327f3d09420..30163432a711 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1760,6 +1760,7 @@ static int uvc_register_video(struct uvc_device *dev, */ vdev->v4l2_dev = &dev->vdev; vdev->fops = &uvc_fops; + vdev->ioctl_ops = &uvc_ioctl_ops; vdev->release = uvc_release; vdev->prio = &stream->chain->prio; if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 378ae02e593b..a16fe2167976 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -551,553 +551,635 @@ static int uvc_v4l2_release(struct file *file) return 0; } -static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static int uvc_ioctl_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct uvc_fh *handle = file->private_data; struct uvc_video_chain *chain = handle->chain; struct uvc_streaming *stream = handle->stream; - long ret = 0; - switch (cmd) { - /* Query capabilities */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof *cap); - strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); - strlcpy(cap->card, vdev->name, sizeof cap->card); - usb_make_path(stream->dev->udev, - cap->bus_info, sizeof(cap->bus_info)); - cap->version = LINUX_VERSION_CODE; - cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING - | chain->caps; - if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE - | V4L2_CAP_STREAMING; - else - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; - break; - } + strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver)); + strlcpy(cap->card, vdev->name, sizeof(cap->card)); + usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING + | chain->caps; + if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + else + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; - /* Priority */ - case VIDIOC_G_PRIORITY: - *(u32 *)arg = v4l2_prio_max(vdev->prio); - break; + return 0; +} - case VIDIOC_S_PRIORITY: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_format *format; + enum v4l2_buf_type type = fmt->type; + __u32 index = fmt->index; - return v4l2_prio_change(vdev->prio, &handle->vfh.prio, - *(u32 *)arg); + if (fmt->type != stream->type || fmt->index >= stream->nformats) + return -EINVAL; - /* Get, Set & Query control */ - case VIDIOC_QUERYCTRL: - return uvc_query_v4l2_ctrl(chain, arg); + memset(fmt, 0, sizeof(*fmt)); + fmt->index = index; + fmt->type = type; + + format = &stream->format[fmt->index]; + fmt->flags = 0; + if (format->flags & UVC_FMT_FLAG_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + strlcpy(fmt->description, format->name, sizeof(fmt->description)); + fmt->description[sizeof(fmt->description) - 1] = 0; + fmt->pixelformat = format->fcc; + return 0; +} - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; +static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; + return uvc_ioctl_enum_fmt(stream, fmt); +} - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; +static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = uvc_ctrl_get(chain, &xctrl); - uvc_ctrl_rollback(handle); - if (ret >= 0) - ctrl->value = xctrl.value; - break; - } + return uvc_ioctl_enum_fmt(stream, fmt); +} - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; +static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + return uvc_v4l2_get_format(stream, fmt); +} - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; - xctrl.value = ctrl->value; +static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; + return uvc_v4l2_get_format(stream, fmt); +} - ret = uvc_ctrl_set(chain, &xctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - return ret; - } - ret = uvc_ctrl_commit(handle, &xctrl, 1); - if (ret == 0) - ctrl->value = xctrl.value; - break; - } +static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - case VIDIOC_QUERYMENU: - return uvc_query_v4l2_menu(chain, arg); + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; + return uvc_v4l2_set_format(stream, fmt); +} - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; +static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_get(chain, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - ctrls->error_idx = i; - return ret; - } - } - ctrls->error_idx = 0; - ret = uvc_ctrl_rollback(handle); - break; - } + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_S_EXT_CTRLS: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; - /* Fall through */ - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; - - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; + return uvc_v4l2_set_format(stream, fmt); +} - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_set(chain, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - ctrls->error_idx = cmd == VIDIOC_S_EXT_CTRLS - ? ctrls->count : i; - return ret; - } - } +static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_streaming_control probe; - ctrls->error_idx = 0; + return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL); +} - if (cmd == VIDIOC_S_EXT_CTRLS) - ret = uvc_ctrl_commit(handle, - ctrls->controls, ctrls->count); - else - ret = uvc_ctrl_rollback(handle); - break; - } +static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_streaming_control probe; - /* Get, Set & Enum input */ - case VIDIOC_ENUMINPUT: - { - const struct uvc_entity *selector = chain->selector; - struct v4l2_input *input = arg; - struct uvc_entity *iterm = NULL; - u32 index = input->index; - int pin = 0; - - if (selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (index != 0) - return -EINVAL; - list_for_each_entry(iterm, &chain->entities, chain) { - if (UVC_ENTITY_IS_ITERM(iterm)) - break; - } - pin = iterm->id; - } else if (index < selector->bNrInPins) { - pin = selector->baSourceID[index]; - list_for_each_entry(iterm, &chain->entities, chain) { - if (!UVC_ENTITY_IS_ITERM(iterm)) - continue; - if (iterm->id == pin) - break; - } - } + return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL); +} - if (iterm == NULL || iterm->id != pin) - return -EINVAL; +static int uvc_ioctl_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *rb) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - memset(input, 0, sizeof *input); - input->index = index; - strlcpy(input->name, iterm->name, sizeof input->name); - if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) - input->type = V4L2_INPUT_TYPE_CAMERA; - break; - } + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_G_INPUT: - { - u8 input; + mutex_lock(&stream->mutex); + ret = uvc_alloc_buffers(&stream->queue, rb); + mutex_unlock(&stream->mutex); + if (ret < 0) + return ret; - if (chain->selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - *(int *)arg = 0; - break; - } + if (ret == 0) + uvc_dismiss_privileges(handle); - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, - chain->selector->id, chain->dev->intfnum, - UVC_SU_INPUT_SELECT_CONTROL, &input, 1); - if (ret < 0) - return ret; + return 0; +} - *(int *)arg = input - 1; - break; - } +static int uvc_ioctl_querybuf(struct file *file, void *fh, + struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - case VIDIOC_S_INPUT: - { - u32 input = *(u32 *)arg + 1; + if (!uvc_has_privileges(handle)) + return -EBUSY; - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + return uvc_query_buffer(&stream->queue, buf); +} - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; +static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - if (chain->selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (input != 1) - return -EINVAL; - break; - } + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (input == 0 || input > chain->selector->bNrInPins) - return -EINVAL; + return uvc_queue_buffer(&stream->queue, buf); +} - return uvc_query_ctrl(chain->dev, UVC_SET_CUR, - chain->selector->id, chain->dev->intfnum, - UVC_SU_INPUT_SELECT_CONTROL, &input, 1); - } +static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - /* Try, Get, Set & Enum format */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - struct uvc_format *format; - enum v4l2_buf_type type = fmt->type; - __u32 index = fmt->index; + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (fmt->type != stream->type || - fmt->index >= stream->nformats) - return -EINVAL; + return uvc_dequeue_buffer(&stream->queue, buf, + file->f_flags & O_NONBLOCK); +} - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - - format = &stream->format[fmt->index]; - fmt->flags = 0; - if (format->flags & UVC_FMT_FLAG_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - strlcpy(fmt->description, format->name, - sizeof fmt->description); - fmt->description[sizeof fmt->description - 1] = 0; - fmt->pixelformat = format->fcc; - break; - } +static int uvc_ioctl_create_bufs(struct file *file, void *fh, + struct v4l2_create_buffers *cb) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - case VIDIOC_TRY_FMT: - { - struct uvc_streaming_control probe; + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); - } + return uvc_create_buffers(&stream->queue, cb); +} - case VIDIOC_S_FMT: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_streamon(struct file *file, void *fh, + enum v4l2_buf_type type) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; + if (type != stream->type) + return -EINVAL; + + if (!uvc_has_privileges(handle)) + return -EBUSY; + + mutex_lock(&stream->mutex); + ret = uvc_video_enable(stream, 1); + mutex_unlock(&stream->mutex); - return uvc_v4l2_set_format(stream, arg); + return ret; +} - case VIDIOC_G_FMT: - return uvc_v4l2_get_format(stream, arg); +static int uvc_ioctl_streamoff(struct file *file, void *fh, + enum v4l2_buf_type type) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - /* Frame size enumeration */ - case VIDIOC_ENUM_FRAMESIZES: - { - struct v4l2_frmsizeenum *fsize = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame; - int i; + if (type != stream->type) + return -EINVAL; - /* Look for the given pixel format */ - for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == - fsize->pixel_format) { - format = &stream->format[i]; - break; - } - } - if (format == NULL) - return -EINVAL; + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (fsize->index >= format->nframes) - return -EINVAL; + mutex_lock(&stream->mutex); + ret = uvc_video_enable(stream, 0); + mutex_unlock(&stream->mutex); - frame = &format->frame[fsize->index]; - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = frame->wWidth; - fsize->discrete.height = frame->wHeight; - break; - } + return ret; +} - /* Frame interval enumeration */ - case VIDIOC_ENUM_FRAMEINTERVALS: - { - struct v4l2_frmivalenum *fival = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; - int i; - - /* Look for the given pixel format and frame size */ - for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == - fival->pixel_format) { - format = &stream->format[i]; - break; - } - } - if (format == NULL) +static int uvc_ioctl_enum_input(struct file *file, void *fh, + struct v4l2_input *input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + const struct uvc_entity *selector = chain->selector; + struct uvc_entity *iterm = NULL; + u32 index = input->index; + int pin = 0; + + if (selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + if (index != 0) return -EINVAL; - - for (i = 0; i < format->nframes; i++) { - if (format->frame[i].wWidth == fival->width && - format->frame[i].wHeight == fival->height) { - frame = &format->frame[i]; + list_for_each_entry(iterm, &chain->entities, chain) { + if (UVC_ENTITY_IS_ITERM(iterm)) break; - } } - if (frame == NULL) - return -EINVAL; - - if (frame->bFrameIntervalType) { - if (fival->index >= frame->bFrameIntervalType) - return -EINVAL; - - fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; - fival->discrete.numerator = - frame->dwFrameInterval[fival->index]; - fival->discrete.denominator = 10000000; - uvc_simplify_fraction(&fival->discrete.numerator, - &fival->discrete.denominator, 8, 333); - } else { - fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; - fival->stepwise.min.numerator = - frame->dwFrameInterval[0]; - fival->stepwise.min.denominator = 10000000; - fival->stepwise.max.numerator = - frame->dwFrameInterval[1]; - fival->stepwise.max.denominator = 10000000; - fival->stepwise.step.numerator = - frame->dwFrameInterval[2]; - fival->stepwise.step.denominator = 10000000; - uvc_simplify_fraction(&fival->stepwise.min.numerator, - &fival->stepwise.min.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.max.numerator, - &fival->stepwise.max.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.step.numerator, - &fival->stepwise.step.denominator, 8, 333); + pin = iterm->id; + } else if (index < selector->bNrInPins) { + pin = selector->baSourceID[index]; + list_for_each_entry(iterm, &chain->entities, chain) { + if (!UVC_ENTITY_IS_ITERM(iterm)) + continue; + if (iterm->id == pin) + break; } - break; } - /* Get & Set streaming parameters */ - case VIDIOC_G_PARM: - return uvc_v4l2_get_streamparm(stream, arg); + if (iterm == NULL || iterm->id != pin) + return -EINVAL; - case VIDIOC_S_PARM: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + memset(input, 0, sizeof(*input)); + input->index = index; + strlcpy(input->name, iterm->name, sizeof(input->name)); + if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) + input->type = V4L2_INPUT_TYPE_CAMERA; - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; + return 0; +} - return uvc_v4l2_set_streamparm(stream, arg); +static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + int ret; + u8 i; - /* Cropping and scaling */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *ccap = arg; + if (chain->selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + *input = 0; + return 0; + } - if (ccap->type != stream->type) - return -EINVAL; + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + &i, 1); + if (ret < 0) + return ret; - ccap->bounds.left = 0; - ccap->bounds.top = 0; + *input = i - 1; + return 0; +} - mutex_lock(&stream->mutex); - ccap->bounds.width = stream->cur_frame->wWidth; - ccap->bounds.height = stream->cur_frame->wHeight; - mutex_unlock(&stream->mutex); +static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + int ret; + u32 i; - ccap->defrect = ccap->bounds; + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - ccap->pixelaspect.numerator = 1; - ccap->pixelaspect.denominator = 1; - break; + if (chain->selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + if (input) + return -EINVAL; + return 0; } - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - return -ENOTTY; + if (input >= chain->selector->bNrInPins) + return -EINVAL; - /* Buffers & streaming */ - case VIDIOC_REQBUFS: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + i = input + 1; + return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + &i, 1); +} - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; +static int uvc_ioctl_queryctrl(struct file *file, void *fh, + struct v4l2_queryctrl *qc) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; - mutex_lock(&stream->mutex); - ret = uvc_alloc_buffers(&stream->queue, arg); - mutex_unlock(&stream->mutex); - if (ret < 0) - return ret; + return uvc_query_v4l2_ctrl(chain, qc); +} - if (ret == 0) - uvc_dismiss_privileges(handle); +static int uvc_ioctl_g_ctrl(struct file *file, void *fh, + struct v4l2_control *ctrl) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control xctrl; + int ret; - ret = 0; - break; + memset(&xctrl, 0, sizeof(xctrl)); + xctrl.id = ctrl->id; - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - if (!uvc_has_privileges(handle)) - return -EBUSY; + ret = uvc_ctrl_get(chain, &xctrl); + uvc_ctrl_rollback(handle); + if (ret < 0) + return ret; - return uvc_query_buffer(&stream->queue, buf); - } + ctrl->value = xctrl.value; + return 0; +} - case VIDIOC_CREATE_BUFS: - { - struct v4l2_create_buffers *cb = arg; +static int uvc_ioctl_s_ctrl(struct file *file, void *fh, + struct v4l2_control *ctrl) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control xctrl; + int ret; - ret = uvc_acquire_privileges(handle); - if (ret < 0) - return ret; + memset(&xctrl, 0, sizeof(xctrl)); + xctrl.id = ctrl->id; + xctrl.value = ctrl->value; - return uvc_create_buffers(&stream->queue, cb); + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; + + ret = uvc_ctrl_set(chain, &xctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + return ret; } - case VIDIOC_QBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; + ret = uvc_ctrl_commit(handle, &xctrl, 1); + if (ret < 0) + return ret; - return uvc_queue_buffer(&stream->queue, arg); + ctrl->value = xctrl.value; + return 0; +} - case VIDIOC_DQBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; +static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control *ctrl = ctrls->controls; + unsigned int i; + int ret; - return uvc_dequeue_buffer(&stream->queue, arg, - file->f_flags & O_NONBLOCK); + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - case VIDIOC_STREAMON: - { - int *type = arg; + for (i = 0; i < ctrls->count; ++ctrl, ++i) { + ret = uvc_ctrl_get(chain, ctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + ctrls->error_idx = i; + return ret; + } + } - if (*type != stream->type) - return -EINVAL; + ctrls->error_idx = 0; - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + return uvc_ctrl_rollback(handle); +} - if (!uvc_has_privileges(handle)) - return -EBUSY; +static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle, + struct v4l2_ext_controls *ctrls, + bool commit) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + struct uvc_video_chain *chain = handle->chain; + unsigned int i; + int ret; - mutex_lock(&stream->mutex); - ret = uvc_video_enable(stream, 1); - mutex_unlock(&stream->mutex); - if (ret < 0) + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; + + for (i = 0; i < ctrls->count; ++ctrl, ++i) { + ret = uvc_ctrl_set(chain, ctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + ctrls->error_idx = commit ? ctrls->count : i; return ret; - break; + } } - case VIDIOC_STREAMOFF: - { - int *type = arg; + ctrls->error_idx = 0; - if (*type != stream->type) - return -EINVAL; + if (commit) + return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count); + else + return uvc_ctrl_rollback(handle); +} - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; - if (!uvc_has_privileges(handle)) - return -EBUSY; + return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, true); +} + +static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; + + return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, false); +} - return uvc_video_enable(stream, 0); +static int uvc_ioctl_querymenu(struct file *file, void *fh, + struct v4l2_querymenu *qm) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + + return uvc_query_v4l2_menu(chain, qm); +} + +static int uvc_ioctl_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *ccap) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + + if (ccap->type != stream->type) + return -EINVAL; + + ccap->bounds.left = 0; + ccap->bounds.top = 0; + mutex_lock(&stream->mutex); + ccap->bounds.width = stream->cur_frame->wWidth; + ccap->bounds.height = stream->cur_frame->wHeight; + mutex_unlock(&stream->mutex); + + ccap->defrect = ccap->bounds; + + ccap->pixelaspect.numerator = 1; + ccap->pixelaspect.denominator = 1; + return 0; +} + +static int uvc_ioctl_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + + return uvc_v4l2_get_streamparm(stream, parm); +} + +static int uvc_ioctl_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; + + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; + + return uvc_v4l2_set_streamparm(stream, parm); +} + +static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_format *format = NULL; + struct uvc_frame *frame; + int i; + + /* Look for the given pixel format */ + for (i = 0; i < stream->nformats; i++) { + if (stream->format[i].fcc == fsize->pixel_format) { + format = &stream->format[i]; + break; + } } + if (format == NULL) + return -EINVAL; - case VIDIOC_SUBSCRIBE_EVENT: - { - struct v4l2_event_subscription *sub = arg; + if (fsize->index >= format->nframes) + return -EINVAL; - switch (sub->type) { - case V4L2_EVENT_CTRL: - return v4l2_event_subscribe(&handle->vfh, sub, 0, - &uvc_ctrl_sub_ev_ops); - default: - return -EINVAL; + frame = &format->frame[fsize->index]; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frame->wWidth; + fsize->discrete.height = frame->wHeight; + return 0; +} + +static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, + struct v4l2_frmivalenum *fival) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_format *format = NULL; + struct uvc_frame *frame = NULL; + int i; + + /* Look for the given pixel format and frame size */ + for (i = 0; i < stream->nformats; i++) { + if (stream->format[i].fcc == fival->pixel_format) { + format = &stream->format[i]; + break; } } + if (format == NULL) + return -EINVAL; - case VIDIOC_UNSUBSCRIBE_EVENT: - return v4l2_event_unsubscribe(&handle->vfh, arg); + for (i = 0; i < format->nframes; i++) { + if (format->frame[i].wWidth == fival->width && + format->frame[i].wHeight == fival->height) { + frame = &format->frame[i]; + break; + } + } + if (frame == NULL) + return -EINVAL; - case VIDIOC_DQEVENT: - return v4l2_event_dequeue(&handle->vfh, arg, - file->f_flags & O_NONBLOCK); + if (frame->bFrameIntervalType) { + if (fival->index >= frame->bFrameIntervalType) + return -EINVAL; - /* Analog video standards make no sense for digital cameras. */ - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + fival->discrete.numerator = + frame->dwFrameInterval[fival->index]; + fival->discrete.denominator = 10000000; + uvc_simplify_fraction(&fival->discrete.numerator, + &fival->discrete.denominator, 8, 333); + } else { + fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; + fival->stepwise.min.numerator = frame->dwFrameInterval[0]; + fival->stepwise.min.denominator = 10000000; + fival->stepwise.max.numerator = frame->dwFrameInterval[1]; + fival->stepwise.max.denominator = 10000000; + fival->stepwise.step.numerator = frame->dwFrameInterval[2]; + fival->stepwise.step.denominator = 10000000; + uvc_simplify_fraction(&fival->stepwise.min.numerator, + &fival->stepwise.min.denominator, 8, 333); + uvc_simplify_fraction(&fival->stepwise.max.numerator, + &fival->stepwise.max.denominator, 8, 333); + uvc_simplify_fraction(&fival->stepwise.step.numerator, + &fival->stepwise.step.denominator, 8, 333); + } - case VIDIOC_OVERLAY: + return 0; +} - case VIDIOC_ENUMAUDIO: - case VIDIOC_ENUMAUDOUT: +static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_CTRL: + return v4l2_event_subscribe(fh, sub, 0, &uvc_ctrl_sub_ev_ops); + default: + return -EINVAL; + } +} - case VIDIOC_ENUMOUTPUT: - uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); - return -ENOTTY; +static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio, + unsigned int cmd, void *arg) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + switch (cmd) { + /* Dynamic controls. */ case UVCIOC_CTRL_MAP: return uvc_ioctl_ctrl_map(chain, arg); @@ -1105,23 +1187,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) return uvc_xu_ctrl_query(chain, arg); default: - uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); return -ENOTTY; } - - return ret; -} - -static long uvc_v4l2_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - if (uvc_trace_param & UVC_TRACE_IOCTL) { - uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl("); - v4l_printk_ioctl(NULL, cmd); - printk(")\n"); - } - - return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); } #ifdef CONFIG_COMPAT @@ -1304,7 +1371,7 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, old_fs = get_fs(); set_fs(KERNEL_DS); - ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg); + ret = video_ioctl2(file, cmd, (unsigned long)&karg); set_fs(old_fs); if (ret < 0) @@ -1365,11 +1432,48 @@ static unsigned long uvc_v4l2_get_unmapped_area(struct file *file, } #endif +const struct v4l2_ioctl_ops uvc_ioctl_ops = { + .vidioc_querycap = uvc_ioctl_querycap, + .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap, + .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out, + .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap, + .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out, + .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out, + .vidioc_reqbufs = uvc_ioctl_reqbufs, + .vidioc_querybuf = uvc_ioctl_querybuf, + .vidioc_qbuf = uvc_ioctl_qbuf, + .vidioc_dqbuf = uvc_ioctl_dqbuf, + .vidioc_create_bufs = uvc_ioctl_create_bufs, + .vidioc_streamon = uvc_ioctl_streamon, + .vidioc_streamoff = uvc_ioctl_streamoff, + .vidioc_enum_input = uvc_ioctl_enum_input, + .vidioc_g_input = uvc_ioctl_g_input, + .vidioc_s_input = uvc_ioctl_s_input, + .vidioc_queryctrl = uvc_ioctl_queryctrl, + .vidioc_g_ctrl = uvc_ioctl_g_ctrl, + .vidioc_s_ctrl = uvc_ioctl_s_ctrl, + .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls, + .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls, + .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls, + .vidioc_querymenu = uvc_ioctl_querymenu, + .vidioc_cropcap = uvc_ioctl_cropcap, + .vidioc_g_parm = uvc_ioctl_g_parm, + .vidioc_s_parm = uvc_ioctl_s_parm, + .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes, + .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals, + .vidioc_subscribe_event = uvc_ioctl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_default = uvc_ioctl_default, +}; + const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, - .unlocked_ioctl = uvc_v4l2_ioctl, + .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl32 = uvc_v4l2_compat_ioctl32, #endif diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 2600c9667a64..53db7ed1e472 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -580,7 +580,6 @@ struct uvc_driver { #define UVC_TRACE_FORMAT (1 << 3) #define UVC_TRACE_CAPTURE (1 << 4) #define UVC_TRACE_CALLS (1 << 5) -#define UVC_TRACE_IOCTL (1 << 6) #define UVC_TRACE_FRAME (1 << 7) #define UVC_TRACE_SUSPEND (1 << 8) #define UVC_TRACE_STATUS (1 << 9) @@ -654,6 +653,7 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue) } /* V4L2 interface */ +extern const struct v4l2_ioctl_ops uvc_ioctl_ops; extern const struct v4l2_file_operations uvc_fops; /* Media controller */ -- GitLab From aa3d17df6470338223f7ae6893647453e8f8e98e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 31 Oct 2014 09:56:16 -0300 Subject: [PATCH 6356/9457] [media] uvcvideo: Set buffer field to V4L2_FIELD_NONE The driver doesn't support interlaced video, set field to V4L2_FIELD_NONE for all vb2 buffers. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_video.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index df81b9c4faf1..b9c7dee8e7b3 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1021,6 +1021,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, uvc_video_get_ts(&ts); + buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; buf->buf.v4l2_buf.sequence = stream->sequence; buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; buf->buf.v4l2_buf.timestamp.tv_usec = -- GitLab From b83bba24a29c44b696b5977e3874bc07b13dc3c0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 13 Oct 2014 10:11:35 -0300 Subject: [PATCH 6357/9457] [media] uvcvideo: Separate video and queue enable/disable operations In order to make use of the vb2 queue start/stop_streaming operations the video and queue enable/disable operations need to be split, as the vb2 queue will need to enable and disable video instead of the other way around. Also move buffer queue disable outside of uvc_video_resume() to remove all queue disable operations out of uvc_video.c. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 16 ++++++++++++---- drivers/media/usb/uvc/uvc_v4l2.c | 15 ++++++++++++--- drivers/media/usb/uvc/uvc_video.c | 22 ++-------------------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 30163432a711..ab1e2fd0a599 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1734,6 +1734,11 @@ static int uvc_register_video(struct uvc_device *dev, struct video_device *vdev; int ret; + /* Initialize the video buffers queue. */ + ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param); + if (ret) + return ret; + /* Initialize the streaming interface with default streaming * parameters. */ @@ -2008,14 +2013,13 @@ static int __uvc_resume(struct usb_interface *intf, int reset) { struct uvc_device *dev = usb_get_intfdata(intf); struct uvc_streaming *stream; + int ret = 0; uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceSubClass == UVC_SC_VIDEOCONTROL) { - int ret = 0; - if (reset) { ret = uvc_ctrl_restore_values(dev); if (ret < 0) @@ -2031,8 +2035,12 @@ static int __uvc_resume(struct usb_interface *intf, int reset) } list_for_each_entry(stream, &dev->streams, list) { - if (stream->intf == intf) - return uvc_video_resume(stream, reset); + if (stream->intf == intf) { + ret = uvc_video_resume(stream, reset); + if (ret < 0) + uvc_queue_enable(&stream->queue, 0); + return ret; + } } uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index a16fe2167976..e8bf4f149a26 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -532,6 +532,7 @@ static int uvc_v4l2_release(struct file *file) /* Only free resources if this is a privileged handle. */ if (uvc_has_privileges(handle)) { uvc_video_enable(stream, 0); + uvc_queue_enable(&stream->queue, 0); uvc_free_buffers(&stream->queue); } @@ -766,7 +767,15 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, return -EBUSY; mutex_lock(&stream->mutex); + ret = uvc_queue_enable(&stream->queue, 1); + if (ret < 0) + goto done; + ret = uvc_video_enable(stream, 1); + if (ret < 0) + uvc_queue_enable(&stream->queue, 0); + +done: mutex_unlock(&stream->mutex); return ret; @@ -777,7 +786,6 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, { struct uvc_fh *handle = fh; struct uvc_streaming *stream = handle->stream; - int ret; if (type != stream->type) return -EINVAL; @@ -786,10 +794,11 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, return -EBUSY; mutex_lock(&stream->mutex); - ret = uvc_video_enable(stream, 0); + uvc_video_enable(stream, 0); + uvc_queue_enable(&stream->queue, 0); mutex_unlock(&stream->mutex); - return ret; + return 0; } static int uvc_ioctl_enum_input(struct file *file, void *fh, diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index b9c7dee8e7b3..9637e8b86949 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1735,19 +1735,13 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) uvc_video_clock_reset(stream); ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) { - uvc_queue_enable(&stream->queue, 0); + if (ret < 0) return ret; - } if (!uvc_queue_streaming(&stream->queue)) return 0; - ret = uvc_init_video(stream, GFP_NOIO); - if (ret < 0) - uvc_queue_enable(&stream->queue, 0); - - return ret; + return uvc_init_video(stream, GFP_NOIO); } /* ------------------------------------------------------------------------ @@ -1779,11 +1773,6 @@ int uvc_video_init(struct uvc_streaming *stream) atomic_set(&stream->active, 0); - /* Initialize the video buffers queue. */ - ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param); - if (ret) - return ret; - /* Alternate setting 0 should be the default, yet the XBox Live Vision * Cam (and possibly other devices) crash or otherwise misbehave if * they don't receive a SET_INTERFACE request before any other video @@ -1890,7 +1879,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) usb_clear_halt(stream->dev->udev, pipe); } - uvc_queue_enable(&stream->queue, 0); uvc_video_clock_cleanup(stream); return 0; } @@ -1899,10 +1887,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) if (ret < 0) return ret; - ret = uvc_queue_enable(&stream->queue, 1); - if (ret < 0) - goto error_queue; - /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) @@ -1917,8 +1901,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) error_video: usb_set_interface(stream->dev->udev, stream->intfnum, 0); error_commit: - uvc_queue_enable(&stream->queue, 0); -error_queue: uvc_video_clock_cleanup(stream); return ret; -- GitLab From bc75d5a0097b4100b4a4e06db62b2afb80d96393 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 12:58:35 -0300 Subject: [PATCH 6358/9457] [media] uvcvideo: Add function to convert from queue to stream Factorize the container_of() call into an inline function and update callers. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 6e92d2080255..97036559bb92 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -36,6 +36,12 @@ * the driver. */ +static inline struct uvc_streaming * +uvc_queue_to_stream(struct uvc_video_queue *queue) +{ + return container_of(queue, struct uvc_streaming, queue); +} + /* ----------------------------------------------------------------------------- * videobuf2 queue operations */ @@ -45,8 +51,7 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int sizes[], void *alloc_ctxs[]) { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); - struct uvc_streaming *stream = - container_of(queue, struct uvc_streaming, queue); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); /* Make sure the image size is large enough. */ if (fmt && fmt->fmt.pix.sizeimage < stream->ctrl.dwMaxVideoFrameSize) @@ -109,8 +114,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) static void uvc_buffer_finish(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_streaming *stream = - container_of(queue, struct uvc_streaming, queue); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); if (vb->state == VB2_BUF_STATE_DONE) -- GitLab From a11a03e50b73234444f7d439fb8ee6eaec3cffd1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 13:03:08 -0300 Subject: [PATCH 6359/9457] [media] uvcvideo: Implement vb2 queue start and stop stream operations To work propertly the videobuf2 core code needs to be in charge of stream start/stop control. Implement the start_streaming and stop_streaming vb2 operations and move video enable/disable code to them. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 43 ++++++++++++++++++++----------- drivers/media/usb/uvc/uvc_v4l2.c | 10 ------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 97036559bb92..758247048ee1 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -135,6 +135,29 @@ static void uvc_wait_finish(struct vb2_queue *vq) mutex_lock(&queue->mutex); } +static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct uvc_video_queue *queue = vb2_get_drv_priv(vq); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); + + queue->buf_used = 0; + + return uvc_video_enable(stream, 1); +} + +static void uvc_stop_streaming(struct vb2_queue *vq) +{ + struct uvc_video_queue *queue = vb2_get_drv_priv(vq); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); + unsigned long flags; + + uvc_video_enable(stream, 0); + + spin_lock_irqsave(&queue->irqlock, flags); + INIT_LIST_HEAD(&queue->irqqueue); + spin_unlock_irqrestore(&queue->irqlock, flags); +} + static struct vb2_ops uvc_queue_qops = { .queue_setup = uvc_queue_setup, .buf_prepare = uvc_buffer_prepare, @@ -142,6 +165,8 @@ static struct vb2_ops uvc_queue_qops = { .buf_finish = uvc_buffer_finish, .wait_prepare = uvc_wait_prepare, .wait_finish = uvc_wait_finish, + .start_streaming = uvc_start_streaming, + .stop_streaming = uvc_stop_streaming, }; int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, @@ -310,27 +335,15 @@ int uvc_queue_allocated(struct uvc_video_queue *queue) */ int uvc_queue_enable(struct uvc_video_queue *queue, int enable) { - unsigned long flags; int ret; mutex_lock(&queue->mutex); - if (enable) { - ret = vb2_streamon(&queue->queue, queue->queue.type); - if (ret < 0) - goto done; - queue->buf_used = 0; - } else { + if (enable) + ret = vb2_streamon(&queue->queue, queue->queue.type); + else ret = vb2_streamoff(&queue->queue, queue->queue.type); - if (ret < 0) - goto done; - - spin_lock_irqsave(&queue->irqlock, flags); - INIT_LIST_HEAD(&queue->irqqueue); - spin_unlock_irqrestore(&queue->irqlock, flags); - } -done: mutex_unlock(&queue->mutex); return ret; } diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index e8bf4f149a26..4619fd6b0494 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -531,7 +531,6 @@ static int uvc_v4l2_release(struct file *file) /* Only free resources if this is a privileged handle. */ if (uvc_has_privileges(handle)) { - uvc_video_enable(stream, 0); uvc_queue_enable(&stream->queue, 0); uvc_free_buffers(&stream->queue); } @@ -768,14 +767,6 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, mutex_lock(&stream->mutex); ret = uvc_queue_enable(&stream->queue, 1); - if (ret < 0) - goto done; - - ret = uvc_video_enable(stream, 1); - if (ret < 0) - uvc_queue_enable(&stream->queue, 0); - -done: mutex_unlock(&stream->mutex); return ret; @@ -794,7 +785,6 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, return -EBUSY; mutex_lock(&stream->mutex); - uvc_video_enable(stream, 0); uvc_queue_enable(&stream->queue, 0); mutex_unlock(&stream->mutex); -- GitLab From 3f02de275e5c4374ffeba554c7b9fa85ea13ecc5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 16:07:15 -0300 Subject: [PATCH 6360/9457] [media] uvcvideo: Don't stop the stream twice at file handle release When releasing the file handle the driver calls the vb2_queue_release which turns the stream off. There's thus no need to turn the stream off explicitly beforehand. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 14 +++++++------- drivers/media/usb/uvc/uvc_v4l2.c | 6 ++---- drivers/media/usb/uvc/uvcvideo.h | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 758247048ee1..708478f958e9 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -194,6 +194,13 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, return 0; } +void uvc_queue_release(struct uvc_video_queue *queue) +{ + mutex_lock(&queue->mutex); + vb2_queue_release(&queue->queue); + mutex_unlock(&queue->mutex); +} + /* ----------------------------------------------------------------------------- * V4L2 queue operations */ @@ -210,13 +217,6 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, return ret ? ret : rb->count; } -void uvc_free_buffers(struct uvc_video_queue *queue) -{ - mutex_lock(&queue->mutex); - vb2_queue_release(&queue->queue); - mutex_unlock(&queue->mutex); -} - int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) { int ret; diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 4619fd6b0494..1b6b6db30d98 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -530,10 +530,8 @@ static int uvc_v4l2_release(struct file *file) uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); /* Only free resources if this is a privileged handle. */ - if (uvc_has_privileges(handle)) { - uvc_queue_enable(&stream->queue, 0); - uvc_free_buffers(&stream->queue); - } + if (uvc_has_privileges(handle)) + uvc_queue_release(&stream->queue); /* Release the file handle. */ uvc_dismiss_privileges(handle); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 53db7ed1e472..344aedec9dfb 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -623,9 +623,9 @@ extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); /* Video buffers queue management. */ extern int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, int drop_corrupted); +extern void uvc_queue_release(struct uvc_video_queue *queue); extern int uvc_alloc_buffers(struct uvc_video_queue *queue, struct v4l2_requestbuffers *rb); -extern void uvc_free_buffers(struct uvc_video_queue *queue); extern int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_create_buffers(struct uvc_video_queue *queue, -- GitLab From 1b7f9c989ee7684dc70f0a75a037ecb1d437d3c2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 16:02:00 -0300 Subject: [PATCH 6361/9457] [media] uvcvideo: Rename uvc_alloc_buffers to uvc_request_buffers This brings the function name in line with the V4L2 API terminology. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 4 ++-- drivers/media/usb/uvc/uvc_v4l2.c | 2 +- drivers/media/usb/uvc/uvcvideo.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 708478f958e9..5c11de0df4b6 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -205,8 +205,8 @@ void uvc_queue_release(struct uvc_video_queue *queue) * V4L2 queue operations */ -int uvc_alloc_buffers(struct uvc_video_queue *queue, - struct v4l2_requestbuffers *rb) +int uvc_request_buffers(struct uvc_video_queue *queue, + struct v4l2_requestbuffers *rb) { int ret; diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 1b6b6db30d98..5ba023be3926 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -690,7 +690,7 @@ static int uvc_ioctl_reqbufs(struct file *file, void *fh, return ret; mutex_lock(&stream->mutex); - ret = uvc_alloc_buffers(&stream->queue, rb); + ret = uvc_request_buffers(&stream->queue, rb); mutex_unlock(&stream->mutex); if (ret < 0) return ret; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 344aedec9dfb..2dc247a0ce34 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -624,7 +624,7 @@ extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); extern int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, int drop_corrupted); extern void uvc_queue_release(struct uvc_video_queue *queue); -extern int uvc_alloc_buffers(struct uvc_video_queue *queue, +extern int uvc_request_buffers(struct uvc_video_queue *queue, struct v4l2_requestbuffers *rb); extern int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); -- GitLab From 0da4ab984b1753b160b5fa840ae98b87228ac3dc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 16:19:04 -0300 Subject: [PATCH 6362/9457] [media] uvcvideo: Rename and split uvc_queue_enable to uvc_queue_stream(on|off) This brings the function name in line with the V4L2 API terminology and allows removing the duplicate queue type check. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 3 +- drivers/media/usb/uvc/uvc_queue.c | 53 +++++++++++++----------------- drivers/media/usb/uvc/uvc_v4l2.c | 10 ++---- drivers/media/usb/uvc/uvcvideo.h | 5 ++- 4 files changed, 30 insertions(+), 41 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index ab1e2fd0a599..6a4b0b8cd270 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2038,7 +2038,8 @@ static int __uvc_resume(struct usb_interface *intf, int reset) if (stream->intf == intf) { ret = uvc_video_resume(stream, reset); if (ret < 0) - uvc_queue_enable(&stream->queue, 0); + uvc_queue_streamoff(&stream->queue, + stream->queue.queue.type); return ret; } } diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 5c11de0df4b6..c295c5c719c8 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -263,6 +263,28 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, return ret; } +int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type) +{ + int ret; + + mutex_lock(&queue->mutex); + ret = vb2_streamon(&queue->queue, type); + mutex_unlock(&queue->mutex); + + return ret; +} + +int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type) +{ + int ret; + + mutex_lock(&queue->mutex); + ret = vb2_streamoff(&queue->queue, type); + mutex_unlock(&queue->mutex); + + return ret; +} + int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) { int ret; @@ -317,37 +339,6 @@ int uvc_queue_allocated(struct uvc_video_queue *queue) return allocated; } -/* - * Enable or disable the video buffers queue. - * - * The queue must be enabled before starting video acquisition and must be - * disabled after stopping it. This ensures that the video buffers queue - * state can be properly initialized before buffers are accessed from the - * interrupt handler. - * - * Enabling the video queue returns -EBUSY if the queue is already enabled. - * - * Disabling the video queue cancels the queue and removes all buffers from - * the main queue. - * - * This function can't be called from interrupt context. Use - * uvc_queue_cancel() instead. - */ -int uvc_queue_enable(struct uvc_video_queue *queue, int enable) -{ - int ret; - - mutex_lock(&queue->mutex); - - if (enable) - ret = vb2_streamon(&queue->queue, queue->queue.type); - else - ret = vb2_streamoff(&queue->queue, queue->queue.type); - - mutex_unlock(&queue->mutex); - return ret; -} - /* * Cancel the video buffers queue. * diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 5ba023be3926..9c5cbcf16529 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -757,14 +757,11 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, struct uvc_streaming *stream = handle->stream; int ret; - if (type != stream->type) - return -EINVAL; - if (!uvc_has_privileges(handle)) return -EBUSY; mutex_lock(&stream->mutex); - ret = uvc_queue_enable(&stream->queue, 1); + ret = uvc_queue_streamon(&stream->queue, type); mutex_unlock(&stream->mutex); return ret; @@ -776,14 +773,11 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, struct uvc_fh *handle = fh; struct uvc_streaming *stream = handle->stream; - if (type != stream->type) - return -EINVAL; - if (!uvc_has_privileges(handle)) return -EBUSY; mutex_lock(&stream->mutex); - uvc_queue_enable(&stream->queue, 0); + uvc_queue_streamoff(&stream->queue, type); mutex_unlock(&stream->mutex); return 0; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 2dc247a0ce34..f0a04b532ede 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -634,7 +634,10 @@ extern int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf, int nonblocking); -extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); +extern int uvc_queue_streamon(struct uvc_video_queue *queue, + enum v4l2_buf_type type); +extern int uvc_queue_streamoff(struct uvc_video_queue *queue, + enum v4l2_buf_type type); extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); -- GitLab From ef33d901db3026643f1c415562d633dfc6c5e9bb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 21 Oct 2014 16:37:55 -0300 Subject: [PATCH 6363/9457] [media] uvcvideo: Return all buffers to vb2 at stream stop and start failure videobuf2 requires drivers to give back ownership of all queue buffers in the stop_streaming operation, as well as in the start_streaming operation in case of failure. Mark all queued buffers as done in the error or queued state. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 45 ++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index c295c5c719c8..cc960723b926 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -42,6 +42,28 @@ uvc_queue_to_stream(struct uvc_video_queue *queue) return container_of(queue, struct uvc_streaming, queue); } +/* + * Return all queued buffers to videobuf2 in the requested state. + * + * This function must be called with the queue spinlock held. + */ +static void uvc_queue_return_buffers(struct uvc_video_queue *queue, + enum uvc_buffer_state state) +{ + enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR + ? VB2_BUF_STATE_ERROR + : VB2_BUF_STATE_QUEUED; + + while (!list_empty(&queue->irqqueue)) { + struct uvc_buffer *buf = list_first_entry(&queue->irqqueue, + struct uvc_buffer, + queue); + list_del(&buf->queue); + buf->state = state; + vb2_buffer_done(&buf->buf, vb2_state); + } +} + /* ----------------------------------------------------------------------------- * videobuf2 queue operations */ @@ -139,10 +161,20 @@ static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); struct uvc_streaming *stream = uvc_queue_to_stream(queue); + unsigned long flags; + int ret; queue->buf_used = 0; - return uvc_video_enable(stream, 1); + ret = uvc_video_enable(stream, 1); + if (ret == 0) + return 0; + + spin_lock_irqsave(&queue->irqlock, flags); + uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED); + spin_unlock_irqrestore(&queue->irqlock, flags); + + return ret; } static void uvc_stop_streaming(struct vb2_queue *vq) @@ -154,7 +186,7 @@ static void uvc_stop_streaming(struct vb2_queue *vq) uvc_video_enable(stream, 0); spin_lock_irqsave(&queue->irqlock, flags); - INIT_LIST_HEAD(&queue->irqqueue); + uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); spin_unlock_irqrestore(&queue->irqlock, flags); } @@ -353,17 +385,10 @@ int uvc_queue_allocated(struct uvc_video_queue *queue) */ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) { - struct uvc_buffer *buf; unsigned long flags; spin_lock_irqsave(&queue->irqlock, flags); - while (!list_empty(&queue->irqqueue)) { - buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - list_del(&buf->queue); - buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); - } + uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); /* This must be protected by the irqlock spinlock to avoid race * conditions between uvc_buffer_queue and the disconnection event that * could result in an interruptible wait in uvc_dequeue_buffer. Do not -- GitLab From cf227429c74778cc9f8caf734d1f161f8f021915 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:50:57 -0300 Subject: [PATCH 6364/9457] [media] videobuf2-core.h: improve documentation Document that drivers can access/modify the buffer contents in buf_prepare and buf_finish. That was not clearly stated before. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-core.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 6ef2d01197da..70ace7cc6087 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -270,22 +270,24 @@ struct vb2_buffer { * queue setup from completing successfully; optional. * @buf_prepare: called every time the buffer is queued from userspace * and from the VIDIOC_PREPARE_BUF ioctl; drivers may - * perform any initialization required before each hardware - * operation in this callback; drivers that support - * VIDIOC_CREATE_BUFS must also validate the buffer size; - * if an error is returned, the buffer will not be queued - * in driver; optional. + * perform any initialization required before each + * hardware operation in this callback; drivers can + * access/modify the buffer here as it is still synced for + * the CPU; drivers that support VIDIOC_CREATE_BUFS must + * also validate the buffer size; if an error is returned, + * the buffer will not be queued in driver; optional. * @buf_finish: called before every dequeue of the buffer back to - * userspace; drivers may perform any operations required - * before userspace accesses the buffer; optional. The - * buffer state can be one of the following: DONE and - * ERROR occur while streaming is in progress, and the - * PREPARED state occurs when the queue has been canceled - * and all pending buffers are being returned to their - * default DEQUEUED state. Typically you only have to do - * something if the state is VB2_BUF_STATE_DONE, since in - * all other cases the buffer contents will be ignored - * anyway. + * userspace; the buffer is synced for the CPU, so drivers + * can access/modify the buffer contents; drivers may + * perform any operations required before userspace + * accesses the buffer; optional. The buffer state can be + * one of the following: DONE and ERROR occur while + * streaming is in progress, and the PREPARED state occurs + * when the queue has been canceled and all pending + * buffers are being returned to their default DEQUEUED + * state. Typically you only have to do something if the + * state is VB2_BUF_STATE_DONE, since in all other cases + * the buffer contents will be ignored anyway. * @buf_cleanup: called once before the buffer is freed; drivers may * perform any additional cleanup; optional. * @start_streaming: called once to enter 'streaming' state; the driver may -- GitLab From cd474037c4a9a9c15cab46ff26ceeed1bbda6abb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:50:58 -0300 Subject: [PATCH 6365/9457] [media] vb2: replace 'write' by 'dma_dir' The 'write' argument is very ambiguous. I first assumed that if it is 1, then we're doing video output but instead it meant the reverse. Since it is used to setup the dma_dir value anyway it is now replaced by the correct dma_dir value which is unambiguous. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 10 +++-- .../media/v4l2-core/videobuf2-dma-contig.c | 40 ++++++++++--------- drivers/media/v4l2-core/videobuf2-dma-sg.c | 13 +++--- drivers/media/v4l2-core/videobuf2-vmalloc.c | 16 ++++---- include/media/videobuf2-core.h | 6 ++- 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index f2e43de3dd87..573f6fb9b40f 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1358,7 +1358,8 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) void *mem_priv; unsigned int plane; int ret; - int write = !V4L2_TYPE_IS_OUTPUT(q->type); + enum dma_data_direction dma_dir = + V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); @@ -1400,7 +1401,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) /* Acquire each plane's memory */ mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_ctx[plane], planes[plane].m.userptr, - planes[plane].length, write); + planes[plane].length, dma_dir); if (IS_ERR_OR_NULL(mem_priv)) { dprintk(1, "failed acquiring userspace " "memory for plane %d\n", plane); @@ -1461,7 +1462,8 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) void *mem_priv; unsigned int plane; int ret; - int write = !V4L2_TYPE_IS_OUTPUT(q->type); + enum dma_data_direction dma_dir = + V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); @@ -1509,7 +1511,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) /* Acquire each plane's memory */ mem_priv = call_ptr_memop(vb, attach_dmabuf, q->alloc_ctx[plane], - dbuf, planes[plane].length, write); + dbuf, planes[plane].length, dma_dir); if (IS_ERR(mem_priv)) { dprintk(1, "failed to attach dmabuf\n"); ret = PTR_ERR(mem_priv); diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 4a02ade14b4f..2bdffd383572 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -229,7 +229,7 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) struct vb2_dc_attachment { struct sg_table sgt; - enum dma_data_direction dir; + enum dma_data_direction dma_dir; }; static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, @@ -264,7 +264,7 @@ static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, wr = sg_next(wr); } - attach->dir = DMA_NONE; + attach->dma_dir = DMA_NONE; dbuf_attach->priv = attach; return 0; @@ -282,16 +282,16 @@ static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf, sgt = &attach->sgt; /* release the scatterlist cache */ - if (attach->dir != DMA_NONE) + if (attach->dma_dir != DMA_NONE) dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, - attach->dir); + attach->dma_dir); sg_free_table(sgt); kfree(attach); db_attach->priv = NULL; } static struct sg_table *vb2_dc_dmabuf_ops_map( - struct dma_buf_attachment *db_attach, enum dma_data_direction dir) + struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir) { struct vb2_dc_attachment *attach = db_attach->priv; /* stealing dmabuf mutex to serialize map/unmap operations */ @@ -303,27 +303,27 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( sgt = &attach->sgt; /* return previously mapped sg table */ - if (attach->dir == dir) { + if (attach->dma_dir == dma_dir) { mutex_unlock(lock); return sgt; } /* release any previous cache */ - if (attach->dir != DMA_NONE) { + if (attach->dma_dir != DMA_NONE) { dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, - attach->dir); - attach->dir = DMA_NONE; + attach->dma_dir); + attach->dma_dir = DMA_NONE; } /* mapping to the client with new direction */ - ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir); + ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); if (ret <= 0) { pr_err("failed to map scatterlist\n"); mutex_unlock(lock); return ERR_PTR(-EIO); } - attach->dir = dir; + attach->dma_dir = dma_dir; mutex_unlock(lock); @@ -331,7 +331,7 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( } static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach, - struct sg_table *sgt, enum dma_data_direction dir) + struct sg_table *sgt, enum dma_data_direction dma_dir) { /* nothing to be done here */ } @@ -460,7 +460,8 @@ static int vb2_dc_get_user_pfn(unsigned long start, int n_pages, } static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, - int n_pages, struct vm_area_struct *vma, int write) + int n_pages, struct vm_area_struct *vma, + enum dma_data_direction dma_dir) { if (vma_is_io(vma)) { unsigned int i; @@ -482,7 +483,7 @@ static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, int n; n = get_user_pages(current, current->mm, start & PAGE_MASK, - n_pages, write, 1, pages, NULL); + n_pages, dma_dir == DMA_FROM_DEVICE, 1, pages, NULL); /* negative error means that no page was pinned */ n = max(n, 0); if (n != n_pages) { @@ -551,7 +552,7 @@ static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn #endif static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write) + unsigned long size, enum dma_data_direction dma_dir) { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; @@ -582,7 +583,7 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, return ERR_PTR(-ENOMEM); buf->dev = conf->dev; - buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + buf->dma_dir = dma_dir; start = vaddr & PAGE_MASK; offset = vaddr & ~PAGE_MASK; @@ -618,7 +619,8 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, } /* extract page list from userspace mapping */ - ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write); + ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, + dma_dir == DMA_FROM_DEVICE); if (ret) { unsigned long pfn; if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { @@ -782,7 +784,7 @@ static void vb2_dc_detach_dmabuf(void *mem_priv) } static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, - unsigned long size, int write) + unsigned long size, enum dma_data_direction dma_dir) { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; @@ -804,7 +806,7 @@ static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, return dba; } - buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + buf->dma_dir = dma_dir; buf->size = size; buf->db_attach = dba; diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 9b163a440f89..6b54a14ee827 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -33,8 +33,8 @@ module_param(debug, int, 0644); struct vb2_dma_sg_buf { void *vaddr; struct page **pages; - int write; int offset; + enum dma_data_direction dma_dir; struct sg_table sg_table; size_t size; unsigned int num_pages; @@ -97,7 +97,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla return NULL; buf->vaddr = NULL; - buf->write = 0; + buf->dma_dir = DMA_NONE; buf->offset = 0; buf->size = size; /* size is already page aligned */ @@ -162,7 +162,8 @@ static inline int vma_is_io(struct vm_area_struct *vma) } static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write) + unsigned long size, + enum dma_data_direction dma_dir) { struct vb2_dma_sg_buf *buf; unsigned long first, last; @@ -174,7 +175,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, return NULL; buf->vaddr = NULL; - buf->write = write; + buf->dma_dir = dma_dir; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; @@ -221,7 +222,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, num_pages_from_user = get_user_pages(current, current->mm, vaddr & PAGE_MASK, buf->num_pages, - write, + buf->dma_dir == DMA_FROM_DEVICE, 1, /* force */ buf->pages, NULL); @@ -265,7 +266,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(&buf->sg_table); while (--i >= 0) { - if (buf->write) + if (buf->dma_dir == DMA_FROM_DEVICE) set_page_dirty_lock(buf->pages[i]); if (!vma_is_io(buf->vma)) put_page(buf->pages[i]); diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 313d9771b2bc..fc1eb45a6143 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -25,7 +25,7 @@ struct vb2_vmalloc_buf { void *vaddr; struct page **pages; struct vm_area_struct *vma; - int write; + enum dma_data_direction dma_dir; unsigned long size; unsigned int n_pages; atomic_t refcount; @@ -70,7 +70,8 @@ static void vb2_vmalloc_put(void *buf_priv) } static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write) + unsigned long size, + enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; unsigned long first, last; @@ -82,7 +83,7 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf) return NULL; - buf->write = write; + buf->dma_dir = dma_dir; offset = vaddr & ~PAGE_MASK; buf->size = size; @@ -107,7 +108,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, /* current->mm->mmap_sem is taken by videobuf2 core */ n_pages = get_user_pages(current, current->mm, vaddr & PAGE_MASK, buf->n_pages, - write, 1, /* force */ + dma_dir == DMA_FROM_DEVICE, + 1, /* force */ buf->pages, NULL); if (n_pages != buf->n_pages) goto fail_get_user_pages; @@ -144,7 +146,7 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) if (vaddr) vm_unmap_ram((void *)vaddr, buf->n_pages); for (i = 0; i < buf->n_pages; ++i) { - if (buf->write) + if (buf->dma_dir == DMA_FROM_DEVICE) set_page_dirty_lock(buf->pages[i]); put_page(buf->pages[i]); } @@ -240,7 +242,7 @@ static void vb2_vmalloc_detach_dmabuf(void *mem_priv) } static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, - unsigned long size, int write) + unsigned long size, enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; @@ -252,7 +254,7 @@ static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, return ERR_PTR(-ENOMEM); buf->dbuf = dbuf; - buf->write = write; + buf->dma_dir = dma_dir; buf->size = size; return buf; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 70ace7cc6087..d607871749c7 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -87,14 +87,16 @@ struct vb2_mem_ops { struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr, - unsigned long size, int write); + unsigned long size, + enum dma_data_direction dma_dir); void (*put_userptr)(void *buf_priv); void (*prepare)(void *buf_priv); void (*finish)(void *buf_priv); void *(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf, - unsigned long size, int write); + unsigned long size, + enum dma_data_direction dma_dir); void (*detach_dmabuf)(void *buf_priv); int (*map_dmabuf)(void *buf_priv); void (*unmap_dmabuf)(void *buf_priv); -- GitLab From d935c57e8fb6902a9ede603bb55d9e158f75f09a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:50:59 -0300 Subject: [PATCH 6366/9457] [media] vb2: add dma_dir to the alloc memop This is needed for the next patch where the dma-sg alloc memop needs to know the dma_dir. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 4 +++- drivers/media/v4l2-core/videobuf2-dma-contig.c | 4 +++- drivers/media/v4l2-core/videobuf2-dma-sg.c | 5 +++-- drivers/media/v4l2-core/videobuf2-vmalloc.c | 4 +++- include/media/videobuf2-core.h | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 573f6fb9b40f..7aed8f22e075 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -189,6 +189,8 @@ static void __vb2_queue_cancel(struct vb2_queue *q); static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) { struct vb2_queue *q = vb->vb2_queue; + enum dma_data_direction dma_dir = + V4L2_TYPE_IS_OUTPUT(q->type) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; void *mem_priv; int plane; @@ -200,7 +202,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]); mem_priv = call_ptr_memop(vb, alloc, q->alloc_ctx[plane], - size, q->gfp_flags); + size, dma_dir, q->gfp_flags); if (IS_ERR_OR_NULL(mem_priv)) goto free; diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 2bdffd383572..c4305bf3dbed 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -155,7 +155,8 @@ static void vb2_dc_put(void *buf_priv) kfree(buf); } -static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) +static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size, + enum dma_data_direction dma_dir, gfp_t gfp_flags) { struct vb2_dc_conf *conf = alloc_ctx; struct device *dev = conf->dev; @@ -176,6 +177,7 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) /* Prevent the device from being released while the buffer is used */ buf->dev = get_device(dev); buf->size = size; + buf->dma_dir = dma_dir; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dc_put; diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 6b54a14ee827..2529b831725b 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -86,7 +86,8 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, return 0; } -static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) +static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, + enum dma_data_direction dma_dir, gfp_t gfp_flags) { struct vb2_dma_sg_buf *buf; int ret; @@ -97,7 +98,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla return NULL; buf->vaddr = NULL; - buf->dma_dir = DMA_NONE; + buf->dma_dir = dma_dir; buf->offset = 0; buf->size = size; /* size is already page aligned */ diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index fc1eb45a6143..bba2460961df 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -35,7 +35,8 @@ struct vb2_vmalloc_buf { static void vb2_vmalloc_put(void *buf_priv); -static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) +static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size, + enum dma_data_direction dma_dir, gfp_t gfp_flags) { struct vb2_vmalloc_buf *buf; @@ -45,6 +46,7 @@ static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fl buf->size = size; buf->vaddr = vmalloc_user(buf->size); + buf->dma_dir = dma_dir; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_vmalloc_put; buf->handler.arg = buf; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index d607871749c7..bd2cec2d6c3d 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -82,7 +82,9 @@ struct vb2_threadio_data; * unmap_dmabuf. */ struct vb2_mem_ops { - void *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags); + void *(*alloc)(void *alloc_ctx, unsigned long size, + enum dma_data_direction dma_dir, + gfp_t gfp_flags); void (*put)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); -- GitLab From e5ae8fa739f8a1d5c292c5b13fa33ac64166e5a0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:00 -0300 Subject: [PATCH 6367/9457] [media] vb2: don't free alloc context if it is ERR_PTR Don't try to free a pointer containing an ERR_PTR(). Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index c4305bf3dbed..0bfc488c8812 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -854,7 +854,8 @@ EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx); void vb2_dma_contig_cleanup_ctx(void *alloc_ctx) { - kfree(alloc_ctx); + if (!IS_ERR_OR_NULL(alloc_ctx)) + kfree(alloc_ctx); } EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx); -- GitLab From 9e09d00f55496faa07659f8c3bd8bfd89b4510ec Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 24 Nov 2014 15:50:15 +0100 Subject: [PATCH 6368/9457] video: fbdev-MMP: Fix typos for the word "destroy" Two mistyped words were corrected in the description for the mmp_unregister_path() function. Signed-off-by: Markus Elfring Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/mmp/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c index b563b920f159..43ed576f76fb 100644 --- a/drivers/video/fbdev/mmp/core.c +++ b/drivers/video/fbdev/mmp/core.c @@ -223,10 +223,10 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info) EXPORT_SYMBOL_GPL(mmp_register_path); /* - * mmp_unregister_path - unregister and destory path + * mmp_unregister_path - unregister and destroy path * @p: path to be destoried. * - * this function registers path and destorys it. + * this function registers path and destroys it. */ void mmp_unregister_path(struct mmp_path *path) { -- GitLab From 23c12eac482e87e5db078975e06ca723181d19e5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 24 Nov 2014 15:55:23 +0100 Subject: [PATCH 6369/9457] video: fbdev-MMP: Fix a typo for the word "destroyed" A word was corrected in the description for a parameter of the mmp_unregister_path() function. Signed-off-by: Markus Elfring Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/mmp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c index 43ed576f76fb..a0f496049db7 100644 --- a/drivers/video/fbdev/mmp/core.c +++ b/drivers/video/fbdev/mmp/core.c @@ -224,7 +224,7 @@ EXPORT_SYMBOL_GPL(mmp_register_path); /* * mmp_unregister_path - unregister and destroy path - * @p: path to be destoried. + * @p: path to be destroyed. * * this function registers path and destroys it. */ -- GitLab From 0c3a14c177aa85afb991e7c2be3921aa9a52a893 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:01 -0300 Subject: [PATCH 6370/9457] [media] vb2-dma-sg: add allocation context to dma-sg Require that dma-sg also uses an allocation context. This is in preparation for adding prepare/finish memops to sync the memory between DMA and CPU. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-417.c | 1 + drivers/media/pci/cx23885/cx23885-core.c | 10 +++++- drivers/media/pci/cx23885/cx23885-dvb.c | 1 + drivers/media/pci/cx23885/cx23885-vbi.c | 1 + drivers/media/pci/cx23885/cx23885-video.c | 1 + drivers/media/pci/cx23885/cx23885.h | 1 + drivers/media/pci/saa7134/saa7134-core.c | 18 ++++++++--- drivers/media/pci/saa7134/saa7134-ts.c | 1 + drivers/media/pci/saa7134/saa7134-vbi.c | 1 + drivers/media/pci/saa7134/saa7134-video.c | 1 + drivers/media/pci/saa7134/saa7134.h | 1 + .../media/pci/solo6x10/solo6x10-v4l2-enc.c | 10 ++++++ drivers/media/pci/solo6x10/solo6x10.h | 1 + drivers/media/pci/tw68/tw68-core.c | 15 +++++++-- drivers/media/pci/tw68/tw68-video.c | 1 + drivers/media/pci/tw68/tw68.h | 1 + .../media/platform/marvell-ccic/mcam-core.c | 13 +++++++- .../media/platform/marvell-ccic/mcam-core.h | 1 + drivers/media/v4l2-core/videobuf2-dma-sg.c | 32 +++++++++++++++++++ include/media/videobuf2-dma-sg.h | 3 ++ 20 files changed, 104 insertions(+), 10 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index 3948db386fb5..d72a3ec348ef 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -1148,6 +1148,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, dev->ts1.ts_packet_count = mpeglines; *num_planes = 1; sizes[0] = mpeglinesize * mpeglines; + alloc_ctxs[0] = dev->alloc_ctx; *num_buffers = mpegbufs; return 0; } diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 331eddac7222..d452b5c076e6 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -1997,9 +1997,14 @@ static int cx23885_initdev(struct pci_dev *pci_dev, if (!pci_dma_supported(pci_dev, 0xffffffff)) { printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); err = -EIO; - goto fail_irq; + goto fail_context; } + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail_context; + } err = request_irq(pci_dev->irq, cx23885_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { @@ -2028,6 +2033,8 @@ static int cx23885_initdev(struct pci_dev *pci_dev, return 0; fail_irq: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); +fail_context: cx23885_dev_unregister(dev); fail_ctrl: v4l2_ctrl_handler_free(hdl); @@ -2053,6 +2060,7 @@ static void cx23885_finidev(struct pci_dev *pci_dev) free_irq(pci_dev->irq, dev); cx23885_dev_unregister(dev); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); v4l2_ctrl_handler_free(&dev->ctrl_handler); v4l2_device_unregister(v4l2_dev); kfree(dev); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 1ed92eeb46d1..44fafba65c6f 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -102,6 +102,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, port->ts_packet_count = 32; *num_planes = 1; sizes[0] = port->ts_packet_size * port->ts_packet_count; + alloc_ctxs[0] = port->dev->alloc_ctx; *num_buffers = 32; return 0; } diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c index a7c6ef8f3ea3..1d339a69f0c8 100644 --- a/drivers/media/pci/cx23885/cx23885-vbi.c +++ b/drivers/media/pci/cx23885/cx23885-vbi.c @@ -132,6 +132,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, lines = VBI_NTSC_LINE_COUNT; *num_planes = 1; sizes[0] = lines * VBI_LINE_LENGTH * 2; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 091f5dbe65a8..371eecfe7b32 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -323,6 +323,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, *num_planes = 1; sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index cf4efa461ce2..f55cd12da0fd 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -425,6 +425,7 @@ struct cx23885_dev { struct vb2_queue vb2_vidq; struct cx23885_dmaqueue vbiq; struct vb2_queue vb2_vbiq; + void *alloc_ctx; spinlock_t slock; diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 236ed725f933..a349e964e0bc 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -1001,13 +1001,18 @@ static int saa7134_initdev(struct pci_dev *pci_dev, saa7134_board_init1(dev); saa7134_hwinit1(dev); + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail3; + } /* get irq */ err = request_irq(pci_dev->irq, saa7134_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,pci_dev->irq); - goto fail3; + goto fail4; } /* wait a bit, register i2c bus */ @@ -1065,7 +1070,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (err < 0) { printk(KERN_INFO "%s: can't register video device\n", dev->name); - goto fail4; + goto fail5; } printk(KERN_INFO "%s: registered device %s [v4l2]\n", dev->name, video_device_node_name(dev->video_dev)); @@ -1078,7 +1083,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[dev->nr]); if (err < 0) - goto fail4; + goto fail5; printk(KERN_INFO "%s: registered device %s\n", dev->name, video_device_node_name(dev->vbi_dev)); @@ -1089,7 +1094,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, radio_nr[dev->nr]); if (err < 0) - goto fail4; + goto fail5; printk(KERN_INFO "%s: registered device %s\n", dev->name, video_device_node_name(dev->radio_dev)); } @@ -1103,10 +1108,12 @@ static int saa7134_initdev(struct pci_dev *pci_dev, request_submodules(dev); return 0; - fail4: + fail5: saa7134_unregister_video(dev); saa7134_i2c_unregister(dev); free_irq(pci_dev->irq, dev); + fail4: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); fail3: saa7134_hwfini(dev); iounmap(dev->lmmio); @@ -1173,6 +1180,7 @@ static void saa7134_finidev(struct pci_dev *pci_dev) /* release resources */ free_irq(pci_dev->irq, dev); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); iounmap(dev->lmmio); release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index bd25323bd947..8eff4a7d8ba3 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -142,6 +142,7 @@ int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, *nbuffers = 3; *nplanes = 1; sizes[0] = size; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup); diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index 4f0b1012e4f3..e2cc684a7c12 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -156,6 +156,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, *nbuffers = saa7134_buffer_count(size, *nbuffers); *nplanes = 1; sizes[0] = size; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index fc4a427cb51f..ba029953db9d 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -932,6 +932,7 @@ static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, *nbuffers = saa7134_buffer_count(size, *nbuffers); *nplanes = 1; sizes[0] = size; + alloc_ctxs[0] = dev->alloc_ctx; return 0; } diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 1a82dd07205b..c644c7da6859 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -588,6 +588,7 @@ struct saa7134_dev { /* video+ts+vbi capture */ + void *alloc_ctx; struct saa7134_dmaqueue video_q; struct vb2_queue video_vbq; struct saa7134_dmaqueue vbi_q; diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 30e09d935ce1..4f6bfba58065 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -718,7 +718,10 @@ static int solo_enc_queue_setup(struct vb2_queue *q, unsigned int *num_planes, unsigned int sizes[], void *alloc_ctxs[]) { + struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); + sizes[0] = FRAME_BUF_SIZE; + alloc_ctxs[0] = solo_enc->alloc_ctx; *num_planes = 1; if (*num_buffers < MIN_VID_BUFFERS) @@ -1266,6 +1269,11 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, return ERR_PTR(-ENOMEM); hdl = &solo_enc->hdl; + solo_enc->alloc_ctx = vb2_dma_sg_init_ctx(&solo_dev->pdev->dev); + if (IS_ERR(solo_enc->alloc_ctx)) { + ret = PTR_ERR(solo_enc->alloc_ctx); + goto hdl_free; + } v4l2_ctrl_handler_init(hdl, 10); v4l2_ctrl_new_std(hdl, &solo_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); @@ -1369,6 +1377,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, solo_enc->desc_items, solo_enc->desc_dma); hdl_free: v4l2_ctrl_handler_free(hdl); + vb2_dma_sg_cleanup_ctx(solo_enc->alloc_ctx); kfree(solo_enc); return ERR_PTR(ret); } @@ -1383,6 +1392,7 @@ static void solo_enc_free(struct solo_enc_dev *solo_enc) solo_enc->desc_items, solo_enc->desc_dma); video_unregister_device(solo_enc->vfd); v4l2_ctrl_handler_free(&solo_enc->hdl); + vb2_dma_sg_cleanup_ctx(solo_enc->alloc_ctx); kfree(solo_enc); } diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h index 72017b7f0a75..bd8edfa319b8 100644 --- a/drivers/media/pci/solo6x10/solo6x10.h +++ b/drivers/media/pci/solo6x10/solo6x10.h @@ -180,6 +180,7 @@ struct solo_enc_dev { u32 sequence; struct vb2_queue vidq; struct list_head vidq_active; + void *alloc_ctx; int desc_count; int desc_nelts; struct solo_p2m_desc *desc_items; diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c index 63f0b64057cb..c135165a8b26 100644 --- a/drivers/media/pci/tw68/tw68-core.c +++ b/drivers/media/pci/tw68/tw68-core.c @@ -304,13 +304,19 @@ static int tw68_initdev(struct pci_dev *pci_dev, /* Then do any initialisation wanted before interrupts are on */ tw68_hw_init1(dev); + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail3; + } + /* get irq */ err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw68_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); - goto fail3; + goto fail4; } /* @@ -324,7 +330,7 @@ static int tw68_initdev(struct pci_dev *pci_dev, if (err < 0) { pr_err("%s: can't register video device\n", dev->name); - goto fail4; + goto fail5; } tw_setl(TW68_INTMASK, dev->pci_irqmask); @@ -333,8 +339,10 @@ static int tw68_initdev(struct pci_dev *pci_dev, return 0; -fail4: +fail5: video_unregister_device(&dev->vdev); +fail4: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); fail3: iounmap(dev->lmmio); fail2: @@ -358,6 +366,7 @@ static void tw68_finidev(struct pci_dev *pci_dev) /* unregister */ video_unregister_device(&dev->vdev); v4l2_ctrl_handler_free(&dev->hdl); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); /* release resources */ iounmap(dev->lmmio); diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c index 5c94ac7c88d9..50dcce6251f6 100644 --- a/drivers/media/pci/tw68/tw68-video.c +++ b/drivers/media/pci/tw68/tw68-video.c @@ -384,6 +384,7 @@ static int tw68_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned tot_bufs = q->num_buffers + *num_buffers; sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3; + alloc_ctxs[0] = dev->alloc_ctx; /* * We allow create_bufs, but only if the sizeimage is the same as the * current sizeimage. The tw68_buffer_count calculation becomes quite diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h index 2c8abe26b13b..7a7501bd165f 100644 --- a/drivers/media/pci/tw68/tw68.h +++ b/drivers/media/pci/tw68/tw68.h @@ -181,6 +181,7 @@ struct tw68_dev { unsigned field; struct vb2_queue vidq; struct list_head active; + void *alloc_ctx; /* various v4l controls */ const struct tw68_tvnorm *tvnorm; /* video */ diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index f0eeb6cd262c..c3ff5388aeb3 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1079,6 +1079,8 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq, *nbufs = minbufs; if (cam->buffer_mode == B_DMA_contig) alloc_ctxs[0] = cam->vb_alloc_ctx; + else if (cam->buffer_mode == B_DMA_sg) + alloc_ctxs[0] = cam->vb_alloc_ctx_sg; return 0; } @@ -1286,10 +1288,12 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_dma_contig_memops; vq->buf_struct_size = sizeof(struct mcam_vb_buffer); - cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); vq->io_modes = VB2_MMAP | VB2_USERPTR; cam->dma_setup = mcam_ctlr_dma_contig; cam->frame_complete = mcam_dma_contig_done; + cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); + if (IS_ERR(cam->vb_alloc_ctx)) + return PTR_ERR(cam->vb_alloc_ctx); #endif break; case B_DMA_sg: @@ -1300,6 +1304,9 @@ static int mcam_setup_vb2(struct mcam_camera *cam) vq->io_modes = VB2_MMAP | VB2_USERPTR; cam->dma_setup = mcam_ctlr_dma_sg; cam->frame_complete = mcam_dma_sg_done; + cam->vb_alloc_ctx_sg = vb2_dma_sg_init_ctx(cam->dev); + if (IS_ERR(cam->vb_alloc_ctx_sg)) + return PTR_ERR(cam->vb_alloc_ctx_sg); #endif break; case B_vmalloc: @@ -1325,6 +1332,10 @@ static void mcam_cleanup_vb2(struct mcam_camera *cam) if (cam->buffer_mode == B_DMA_contig) vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx); #endif +#ifdef MCAM_MODE_DMA_SG + if (cam->buffer_mode == B_DMA_sg) + vb2_dma_sg_cleanup_ctx(cam->vb_alloc_ctx_sg); +#endif } diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h index 60a8e1cfeff7..aa0c6eac254a 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.h +++ b/drivers/media/platform/marvell-ccic/mcam-core.h @@ -176,6 +176,7 @@ struct mcam_camera { /* DMA buffers - DMA modes */ struct mcam_vb_buffer *vb_bufs[MAX_DMA_BUFS]; struct vb2_alloc_ctx *vb_alloc_ctx; + struct vb2_alloc_ctx *vb_alloc_ctx_sg; /* Mode-specific ops, set at open time */ void (*dma_setup)(struct mcam_camera *cam); diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 2529b831725b..2bf13dc4df34 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -30,7 +30,12 @@ module_param(debug, int, 0644); printk(KERN_DEBUG "vb2-dma-sg: " fmt, ## arg); \ } while (0) +struct vb2_dma_sg_conf { + struct device *dev; +}; + struct vb2_dma_sg_buf { + struct device *dev; void *vaddr; struct page **pages; int offset; @@ -89,10 +94,13 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, enum dma_data_direction dma_dir, gfp_t gfp_flags) { + struct vb2_dma_sg_conf *conf = alloc_ctx; struct vb2_dma_sg_buf *buf; int ret; int num_pages; + if (WARN_ON(alloc_ctx == NULL)) + return NULL; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) return NULL; @@ -118,6 +126,8 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, if (ret) goto fail_table_alloc; + /* Prevent the device from being released while the buffer is used */ + buf->dev = get_device(conf->dev); buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; buf->handler.arg = buf; @@ -153,6 +163,7 @@ static void vb2_dma_sg_put(void *buf_priv) while (--i >= 0) __free_page(buf->pages[i]); kfree(buf->pages); + put_device(buf->dev); kfree(buf); } } @@ -356,6 +367,27 @@ const struct vb2_mem_ops vb2_dma_sg_memops = { }; EXPORT_SYMBOL_GPL(vb2_dma_sg_memops); +void *vb2_dma_sg_init_ctx(struct device *dev) +{ + struct vb2_dma_sg_conf *conf; + + conf = kzalloc(sizeof(*conf), GFP_KERNEL); + if (!conf) + return ERR_PTR(-ENOMEM); + + conf->dev = dev; + + return conf; +} +EXPORT_SYMBOL_GPL(vb2_dma_sg_init_ctx); + +void vb2_dma_sg_cleanup_ctx(void *alloc_ctx) +{ + if (!IS_ERR_OR_NULL(alloc_ctx)) + kfree(alloc_ctx); +} +EXPORT_SYMBOL_GPL(vb2_dma_sg_cleanup_ctx); + MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2"); MODULE_AUTHOR("Andrzej Pietrasiewicz"); MODULE_LICENSE("GPL"); diff --git a/include/media/videobuf2-dma-sg.h b/include/media/videobuf2-dma-sg.h index 7b89852779af..14ce3068b642 100644 --- a/include/media/videobuf2-dma-sg.h +++ b/include/media/videobuf2-dma-sg.h @@ -21,6 +21,9 @@ static inline struct sg_table *vb2_dma_sg_plane_desc( return (struct sg_table *)vb2_plane_cookie(vb, plane_no); } +void *vb2_dma_sg_init_ctx(struct device *dev); +void vb2_dma_sg_cleanup_ctx(void *alloc_ctx); + extern const struct vb2_mem_ops vb2_dma_sg_memops; #endif -- GitLab From d790b7eda953df474f470169ebdf111c02fa7a2d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 24 Nov 2014 08:50:31 -0300 Subject: [PATCH 6371/9457] [media] vb2-dma-sg: move dma_(un)map_sg here This moves dma_(un)map_sg to the get_userptr/put_userptr and alloc/put memops of videobuf2-dma-sg.c and adds dma_sync_sg_for_device/cpu to the prepare/finish memops. Now that vb2-dma-sg will sync the buffers for you in the prepare/finish memops we can drop that from the drivers that use dma-sg. For the solo6x10 driver that was a bit more involved because it needs to copy JPEG or MPEG headers to the buffer before returning it to userspace, and that cannot be done in the old place since the buffer there is still setup for DMA access, not for CPU access. However, the buf_finish op is the ideal place to do this. By the time buf_finish is called the buffer is available for CPU access, so copying to the buffer is fine. [mchehab@osg.samsung.com: Fix a compilation breakage: drivers/media/v4l2-core/videobuf2-dma-sg.c:150:19: error: 'struct vb2_dma_sg_buf' has no member named 'dma_sgt'] Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-417.c | 3 -- drivers/media/pci/cx23885/cx23885-core.c | 5 -- drivers/media/pci/cx23885/cx23885-dvb.c | 3 -- drivers/media/pci/cx23885/cx23885-vbi.c | 9 ---- drivers/media/pci/cx23885/cx23885-video.c | 9 ---- drivers/media/pci/saa7134/saa7134-empress.c | 1 - drivers/media/pci/saa7134/saa7134-ts.c | 16 ------ drivers/media/pci/saa7134/saa7134-vbi.c | 15 ------ drivers/media/pci/saa7134/saa7134-video.c | 15 ------ drivers/media/pci/saa7134/saa7134.h | 1 - .../media/pci/solo6x10/solo6x10-v4l2-enc.c | 50 ++++++++----------- drivers/media/pci/tw68/tw68-video.c | 8 --- .../media/platform/marvell-ccic/mcam-core.c | 18 +------ drivers/media/v4l2-core/videobuf2-dma-sg.c | 41 +++++++++++++++ 14 files changed, 64 insertions(+), 130 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index d72a3ec348ef..e4901a503c73 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -1167,11 +1167,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx23885_dev *dev = vb->vb2_queue->drv_priv; struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); cx23885_free_buffer(dev, buf); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index d452b5c076e6..d07b04a5ce36 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -1453,17 +1453,12 @@ int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port) struct cx23885_dev *dev = port->dev; int size = port->ts_packet_size * port->ts_packet_count; struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0); - int rc; dprintk(1, "%s: %p\n", __func__, buf); if (vb2_plane_size(&buf->vb, 0) < size) return -EINVAL; vb2_set_plane_payload(&buf->vb, 0, size); - rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!rc) - return -EIO; - cx23885_risc_databuffer(dev->pci, &buf->risc, sgt->sgl, port->ts_packet_size, port->ts_packet_count, 0); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 44fafba65c6f..c47d18270cfc 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -123,11 +123,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx23885_dev *dev = port->dev; struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); cx23885_free_buffer(dev, buf); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } static void buffer_queue(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c index 1d339a69f0c8..d362d3838c84 100644 --- a/drivers/media/pci/cx23885/cx23885-vbi.c +++ b/drivers/media/pci/cx23885/cx23885-vbi.c @@ -143,7 +143,6 @@ static int buffer_prepare(struct vb2_buffer *vb) struct cx23885_buffer, vb); struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); unsigned lines = VBI_PAL_LINE_COUNT; - int ret; if (dev->tvnorm & V4L2_STD_525_60) lines = VBI_NTSC_LINE_COUNT; @@ -152,10 +151,6 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EINVAL; vb2_set_plane_payload(vb, 0, lines * VBI_LINE_LENGTH * 2); - ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!ret) - return -EIO; - cx23885_risc_vbibuffer(dev->pci, &buf->risc, sgt->sgl, 0, VBI_LINE_LENGTH * lines, @@ -166,14 +161,10 @@ static int buffer_prepare(struct vb2_buffer *vb) static void buffer_finish(struct vb2_buffer *vb) { - struct cx23885_dev *dev = vb->vb2_queue->drv_priv; struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); cx23885_free_buffer(vb->vb2_queue->drv_priv, buf); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } /* diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 371eecfe7b32..5e93c682a3f5 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -335,7 +335,6 @@ static int buffer_prepare(struct vb2_buffer *vb) u32 line0_offset, line1_offset; struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); int field_tff; - int ret; buf->bpl = (dev->width * dev->fmt->depth) >> 3; @@ -343,10 +342,6 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EINVAL; vb2_set_plane_payload(vb, 0, dev->height * buf->bpl); - ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); - if (!ret) - return -EIO; - switch (dev->field) { case V4L2_FIELD_TOP: cx23885_risc_buffer(dev->pci, &buf->risc, @@ -414,14 +409,10 @@ static int buffer_prepare(struct vb2_buffer *vb) static void buffer_finish(struct vb2_buffer *vb) { - struct cx23885_dev *dev = vb->vb2_queue->drv_priv; struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb); - struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0); cx23885_free_buffer(vb->vb2_queue->drv_priv, buf); - - dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE); } /* diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 8b3bb78b503b..594dc3ad4750 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -96,7 +96,6 @@ static struct vb2_ops saa7134_empress_qops = { .queue_setup = saa7134_ts_queue_setup, .buf_init = saa7134_ts_buffer_init, .buf_prepare = saa7134_ts_buffer_prepare, - .buf_finish = saa7134_ts_buffer_finish, .buf_queue = saa7134_vb2_buffer_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 8eff4a7d8ba3..2709b83d57b1 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -94,7 +94,6 @@ int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0); unsigned int lines, llength, size; - int ret; dprintk("buffer_prepare [%p]\n", buf); @@ -108,25 +107,11 @@ int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) vb2_set_plane_payload(vb2, 0, size); vb2->v4l2_buf.field = dev->field; - ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); - if (!ret) - return -EIO; return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, saa7134_buffer_startpage(buf)); } EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare); -void saa7134_ts_buffer_finish(struct vb2_buffer *vb2) -{ - struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; - struct saa7134_dev *dev = dmaq->dev; - struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); - struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); - - dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); -} -EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish); - int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) @@ -188,7 +173,6 @@ struct vb2_ops saa7134_ts_qops = { .queue_setup = saa7134_ts_queue_setup, .buf_init = saa7134_ts_buffer_init, .buf_prepare = saa7134_ts_buffer_prepare, - .buf_finish = saa7134_ts_buffer_finish, .buf_queue = saa7134_vb2_buffer_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index e2cc684a7c12..5306e549e526 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -120,7 +120,6 @@ static int buffer_prepare(struct vb2_buffer *vb2) struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); unsigned int size; - int ret; if (dma->sgl->offset) { pr_err("The buffer is not page-aligned\n"); @@ -132,9 +131,6 @@ static int buffer_prepare(struct vb2_buffer *vb2) vb2_set_plane_payload(vb2, 0, size); - ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); - if (!ret) - return -EIO; return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, saa7134_buffer_startpage(buf)); } @@ -170,21 +166,10 @@ static int buffer_init(struct vb2_buffer *vb2) return 0; } -static void buffer_finish(struct vb2_buffer *vb2) -{ - struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; - struct saa7134_dev *dev = dmaq->dev; - struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); - struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); - - dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); -} - struct vb2_ops saa7134_vbi_qops = { .queue_setup = queue_setup, .buf_init = buffer_init, .buf_prepare = buffer_prepare, - .buf_finish = buffer_finish, .buf_queue = saa7134_vb2_buffer_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index ba029953db9d..701b52f34689 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -883,7 +883,6 @@ static int buffer_prepare(struct vb2_buffer *vb2) struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); unsigned int size; - int ret; if (dma->sgl->offset) { pr_err("The buffer is not page-aligned\n"); @@ -896,23 +895,10 @@ static int buffer_prepare(struct vb2_buffer *vb2) vb2_set_plane_payload(vb2, 0, size); vb2->v4l2_buf.field = dev->field; - ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); - if (!ret) - return -EIO; return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, saa7134_buffer_startpage(buf)); } -static void buffer_finish(struct vb2_buffer *vb2) -{ - struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; - struct saa7134_dev *dev = dmaq->dev; - struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); - struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); - - dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); -} - static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) @@ -1005,7 +991,6 @@ static struct vb2_ops vb2_qops = { .queue_setup = queue_setup, .buf_init = buffer_init, .buf_prepare = buffer_prepare, - .buf_finish = buffer_finish, .buf_queue = saa7134_vb2_buffer_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index c644c7da6859..8bf0553b8d2f 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -815,7 +815,6 @@ void saa7134_video_fini(struct saa7134_dev *dev); int saa7134_ts_buffer_init(struct vb2_buffer *vb2); int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2); -void saa7134_ts_buffer_finish(struct vb2_buffer *vb2); int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]); diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 4f6bfba58065..6e933d383fa2 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -463,7 +463,6 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct solo_dev *solo_dev = solo_enc->solo_dev; struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_size; - int ret; vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; @@ -473,22 +472,10 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN); vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); - /* may discard all previous data in vbuf->sgl */ - if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE)) - return -ENOMEM; - ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, + return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), SOLO_JPEG_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE); - - /* add the header only after dma_unmap_sg() */ - sg_copy_from_buffer(vbuf->sgl, vbuf->nents, - solo_enc->jpeg_header, solo_enc->jpeg_len); - - return ret; } static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, @@ -498,7 +485,6 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); int frame_off, frame_size; int skip = 0; - int ret; if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh)) return -EIO; @@ -521,21 +507,9 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN); - /* may discard all previous data in vbuf->sgl */ - if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE)) - return -ENOMEM; - ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, + return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, SOLO_MP4E_EXT_ADDR(solo_dev), SOLO_MP4E_EXT_SIZE(solo_dev)); - dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, - DMA_FROM_DEVICE); - - /* add the header only after dma_unmap_sg() */ - if (!vop_type(vh)) - sg_copy_from_buffer(vbuf->sgl, vbuf->nents, - solo_enc->vop, solo_enc->vop_len); - return ret; } static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, @@ -793,9 +767,29 @@ static void solo_enc_stop_streaming(struct vb2_queue *q) spin_unlock_irqrestore(&solo_enc->av_lock, flags); } +static void solo_enc_buf_finish(struct vb2_buffer *vb) +{ + struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue); + struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); + + switch (solo_enc->fmt) { + case V4L2_PIX_FMT_MPEG4: + case V4L2_PIX_FMT_H264: + if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->vop, solo_enc->vop_len); + break; + default: /* V4L2_PIX_FMT_MJPEG */ + sg_copy_from_buffer(vbuf->sgl, vbuf->nents, + solo_enc->jpeg_header, solo_enc->jpeg_len); + break; + } +} + static struct vb2_ops solo_enc_video_qops = { .queue_setup = solo_enc_queue_setup, .buf_queue = solo_enc_buf_queue, + .buf_finish = solo_enc_buf_finish, .start_streaming = solo_enc_start_streaming, .stop_streaming = solo_enc_stop_streaming, .wait_prepare = vb2_ops_wait_prepare, diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c index 50dcce6251f6..8355e55b4e8e 100644 --- a/drivers/media/pci/tw68/tw68-video.c +++ b/drivers/media/pci/tw68/tw68-video.c @@ -462,17 +462,12 @@ static int tw68_buf_prepare(struct vb2_buffer *vb) struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb); struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0); unsigned size, bpl; - int rc; size = (dev->width * dev->height * dev->fmt->depth) >> 3; if (vb2_plane_size(vb, 0) < size) return -EINVAL; vb2_set_plane_payload(vb, 0, size); - rc = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); - if (!rc) - return -EIO; - bpl = (dev->width * dev->fmt->depth) >> 3; switch (dev->field) { case V4L2_FIELD_TOP: @@ -506,11 +501,8 @@ static void tw68_buf_finish(struct vb2_buffer *vb) { struct vb2_queue *vq = vb->vb2_queue; struct tw68_dev *dev = vb2_get_drv_priv(vq); - struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0); struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb); - dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); - pci_free_consistent(dev->pci, buf->size, buf->cpu, buf->dma); } diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index c3ff5388aeb3..ce00cbaf850e 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1220,17 +1220,12 @@ static int mcam_vb_sg_buf_init(struct vb2_buffer *vb) static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) { struct mcam_vb_buffer *mvb = vb_to_mvb(vb); - struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0); struct mcam_dma_desc *desc = mvb->dma_desc; struct scatterlist *sg; int i; - mvb->dma_desc_nent = dma_map_sg(cam->dev, sg_table->sgl, - sg_table->nents, DMA_FROM_DEVICE); - if (mvb->dma_desc_nent <= 0) - return -EIO; /* Not sure what's right here */ - for_each_sg(sg_table->sgl, sg, mvb->dma_desc_nent, i) { + for_each_sg(sg_table->sgl, sg, sg_table->nents, i) { desc->dma_addr = sg_dma_address(sg); desc->segment_len = sg_dma_len(sg); desc++; @@ -1238,16 +1233,6 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) return 0; } -static void mcam_vb_sg_buf_finish(struct vb2_buffer *vb) -{ - struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); - struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0); - - if (sg_table) - dma_unmap_sg(cam->dev, sg_table->sgl, - sg_table->nents, DMA_FROM_DEVICE); -} - static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb) { struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); @@ -1264,7 +1249,6 @@ static const struct vb2_ops mcam_vb2_sg_ops = { .buf_init = mcam_vb_sg_buf_init, .buf_prepare = mcam_vb_sg_buf_prepare, .buf_queue = mcam_vb_buf_queue, - .buf_finish = mcam_vb_sg_buf_finish, .buf_cleanup = mcam_vb_sg_buf_cleanup, .start_streaming = mcam_vb_start_streaming, .stop_streaming = mcam_vb_stop_streaming, diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 2bf13dc4df34..346e39b2aae8 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -96,6 +96,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, { struct vb2_dma_sg_conf *conf = alloc_ctx; struct vb2_dma_sg_buf *buf; + struct sg_table *sgt; int ret; int num_pages; @@ -128,6 +129,12 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, /* Prevent the device from being released while the buffer is used */ buf->dev = get_device(conf->dev); + + sgt = &buf->sg_table; + if (dma_map_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir) == 0) + goto fail_map; + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; buf->handler.arg = buf; @@ -138,6 +145,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, __func__, buf->num_pages); return buf; +fail_map: + put_device(buf->dev); + sg_free_table(sgt); fail_table_alloc: num_pages = buf->num_pages; while (num_pages--) @@ -152,11 +162,13 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, static void vb2_dma_sg_put(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; + struct sg_table *sgt = &buf->sg_table; int i = buf->num_pages; if (atomic_dec_and_test(&buf->refcount)) { dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, buf->num_pages); + dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(&buf->sg_table); @@ -168,6 +180,22 @@ static void vb2_dma_sg_put(void *buf_priv) } } +static void vb2_dma_sg_prepare(void *buf_priv) +{ + struct vb2_dma_sg_buf *buf = buf_priv; + struct sg_table *sgt = &buf->sg_table; + + dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + +static void vb2_dma_sg_finish(void *buf_priv) +{ + struct vb2_dma_sg_buf *buf = buf_priv; + struct sg_table *sgt = &buf->sg_table; + + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); +} + static inline int vma_is_io(struct vm_area_struct *vma) { return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); @@ -177,16 +205,19 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, enum dma_data_direction dma_dir) { + struct vb2_dma_sg_conf *conf = alloc_ctx; struct vb2_dma_sg_buf *buf; unsigned long first, last; int num_pages_from_user; struct vm_area_struct *vma; + struct sg_table *sgt; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) return NULL; buf->vaddr = NULL; + buf->dev = conf->dev; buf->dma_dir = dma_dir; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; @@ -246,8 +277,14 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, buf->num_pages, buf->offset, size, 0)) goto userptr_fail_alloc_table_from_pages; + sgt = &buf->sg_table; + if (dma_map_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir) == 0) + goto userptr_fail_map; + dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); return buf; +userptr_fail_map: + sg_free_table(&buf->sg_table); userptr_fail_alloc_table_from_pages: userptr_fail_get_user_pages: dprintk(1, "get_user_pages requested/got: %d/%d]\n", @@ -270,10 +307,12 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, static void vb2_dma_sg_put_userptr(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; + struct sg_table *sgt = &buf->sg_table; int i = buf->num_pages; dprintk(1, "%s: Releasing userspace buffer of %d pages\n", __func__, buf->num_pages); + dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(&buf->sg_table); @@ -360,6 +399,8 @@ const struct vb2_mem_ops vb2_dma_sg_memops = { .put = vb2_dma_sg_put, .get_userptr = vb2_dma_sg_get_userptr, .put_userptr = vb2_dma_sg_put_userptr, + .prepare = vb2_dma_sg_prepare, + .finish = vb2_dma_sg_finish, .vaddr = vb2_dma_sg_vaddr, .mmap = vb2_dma_sg_mmap, .num_users = vb2_dma_sg_num_users, -- GitLab From e078b79d8aa70a48fb3fa684e6a6548c5127646b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:03 -0300 Subject: [PATCH 6372/9457] [media] vb2-dma-sg: add dmabuf import support Add support for importing dmabuf to videobuf2-dma-sg. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 151 +++++++++++++++++++-- 1 file changed, 137 insertions(+), 14 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 346e39b2aae8..81e88a067882 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -41,11 +41,19 @@ struct vb2_dma_sg_buf { int offset; enum dma_data_direction dma_dir; struct sg_table sg_table; + /* + * This will point to sg_table when used with the MMAP or USERPTR + * memory model, and to the dma_buf sglist when used with the + * DMABUF memory model. + */ + struct sg_table *dma_sgt; size_t size; unsigned int num_pages; atomic_t refcount; struct vb2_vmarea_handler handler; struct vm_area_struct *vma; + + struct dma_buf_attachment *db_attach; }; static void vb2_dma_sg_put(void *buf_priv); @@ -112,6 +120,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, buf->size = size; /* size is already page aligned */ buf->num_pages = size >> PAGE_SHIFT; + buf->dma_sgt = &buf->sg_table; buf->pages = kzalloc(buf->num_pages * sizeof(struct page *), GFP_KERNEL); @@ -122,7 +131,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, if (ret) goto fail_pages_alloc; - ret = sg_alloc_table_from_pages(&buf->sg_table, buf->pages, + ret = sg_alloc_table_from_pages(buf->dma_sgt, buf->pages, buf->num_pages, 0, size, GFP_KERNEL); if (ret) goto fail_table_alloc; @@ -147,7 +156,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, fail_map: put_device(buf->dev); - sg_free_table(sgt); + sg_free_table(buf->dma_sgt); fail_table_alloc: num_pages = buf->num_pages; while (num_pages--) @@ -171,7 +180,7 @@ static void vb2_dma_sg_put(void *buf_priv) dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); - sg_free_table(&buf->sg_table); + sg_free_table(buf->dma_sgt); while (--i >= 0) __free_page(buf->pages[i]); kfree(buf->pages); @@ -183,7 +192,11 @@ static void vb2_dma_sg_put(void *buf_priv) static void vb2_dma_sg_prepare(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; - struct sg_table *sgt = &buf->sg_table; + struct sg_table *sgt = buf->dma_sgt; + + /* DMABUF exporter will flush the cache for us */ + if (buf->db_attach) + return; dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); } @@ -191,7 +204,11 @@ static void vb2_dma_sg_prepare(void *buf_priv) static void vb2_dma_sg_finish(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; - struct sg_table *sgt = &buf->sg_table; + struct sg_table *sgt = buf->dma_sgt; + + /* DMABUF exporter will flush the cache for us */ + if (buf->db_attach) + return; dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); } @@ -221,6 +238,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, buf->dma_dir = dma_dir; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; + buf->dma_sgt = &buf->sg_table; first = (vaddr & PAGE_MASK) >> PAGE_SHIFT; last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT; @@ -273,7 +291,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, if (num_pages_from_user != buf->num_pages) goto userptr_fail_get_user_pages; - if (sg_alloc_table_from_pages(&buf->sg_table, buf->pages, + if (sg_alloc_table_from_pages(buf->dma_sgt, buf->pages, buf->num_pages, buf->offset, size, 0)) goto userptr_fail_alloc_table_from_pages; @@ -315,7 +333,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); - sg_free_table(&buf->sg_table); + sg_free_table(buf->dma_sgt); while (--i >= 0) { if (buf->dma_dir == DMA_FROM_DEVICE) set_page_dirty_lock(buf->pages[i]); @@ -333,14 +351,16 @@ static void *vb2_dma_sg_vaddr(void *buf_priv) BUG_ON(!buf); - if (!buf->vaddr) - buf->vaddr = vm_map_ram(buf->pages, - buf->num_pages, - -1, - PAGE_KERNEL); + if (!buf->vaddr) { + if (buf->db_attach) + buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf); + else + buf->vaddr = vm_map_ram(buf->pages, + buf->num_pages, -1, PAGE_KERNEL); + } /* add offset in case userptr is not page-aligned */ - return buf->vaddr + buf->offset; + return buf->vaddr ? buf->vaddr + buf->offset : NULL; } static unsigned int vb2_dma_sg_num_users(void *buf_priv) @@ -387,11 +407,110 @@ static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*********************************************/ +/* callbacks for DMABUF buffers */ +/*********************************************/ + +static int vb2_dma_sg_map_dmabuf(void *mem_priv) +{ + struct vb2_dma_sg_buf *buf = mem_priv; + struct sg_table *sgt; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to pin a non attached buffer\n"); + return -EINVAL; + } + + if (WARN_ON(buf->dma_sgt)) { + pr_err("dmabuf buffer is already pinned\n"); + return 0; + } + + /* get the associated scatterlist for this buffer */ + sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); + if (IS_ERR(sgt)) { + pr_err("Error getting dmabuf scatterlist\n"); + return -EINVAL; + } + + buf->dma_sgt = sgt; + buf->vaddr = NULL; + + return 0; +} + +static void vb2_dma_sg_unmap_dmabuf(void *mem_priv) +{ + struct vb2_dma_sg_buf *buf = mem_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to unpin a not attached buffer\n"); + return; + } + + if (WARN_ON(!sgt)) { + pr_err("dmabuf buffer is already unpinned\n"); + return; + } + + if (buf->vaddr) { + dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr); + buf->vaddr = NULL; + } + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + + buf->dma_sgt = NULL; +} + +static void vb2_dma_sg_detach_dmabuf(void *mem_priv) +{ + struct vb2_dma_sg_buf *buf = mem_priv; + + /* if vb2 works correctly you should never detach mapped buffer */ + if (WARN_ON(buf->dma_sgt)) + vb2_dma_sg_unmap_dmabuf(buf); + + /* detach this attachment */ + dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach); + kfree(buf); +} + +static void *vb2_dma_sg_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, enum dma_data_direction dma_dir) +{ + struct vb2_dma_sg_conf *conf = alloc_ctx; + struct vb2_dma_sg_buf *buf; + struct dma_buf_attachment *dba; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dev = conf->dev; + /* create attachment for the dmabuf with the user device */ + dba = dma_buf_attach(dbuf, buf->dev); + if (IS_ERR(dba)) { + pr_err("failed to attach dmabuf\n"); + kfree(buf); + return dba; + } + + buf->dma_dir = dma_dir; + buf->size = size; + buf->db_attach = dba; + + return buf; +} + static void *vb2_dma_sg_cookie(void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; - return &buf->sg_table; + return buf->dma_sgt; } const struct vb2_mem_ops vb2_dma_sg_memops = { @@ -404,6 +523,10 @@ const struct vb2_mem_ops vb2_dma_sg_memops = { .vaddr = vb2_dma_sg_vaddr, .mmap = vb2_dma_sg_mmap, .num_users = vb2_dma_sg_num_users, + .map_dmabuf = vb2_dma_sg_map_dmabuf, + .unmap_dmabuf = vb2_dma_sg_unmap_dmabuf, + .attach_dmabuf = vb2_dma_sg_attach_dmabuf, + .detach_dmabuf = vb2_dma_sg_detach_dmabuf, .cookie = vb2_dma_sg_cookie, }; EXPORT_SYMBOL_GPL(vb2_dma_sg_memops); -- GitLab From 041c7b6ac74ee7a4375faf80e2864fc2bce78edc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:04 -0300 Subject: [PATCH 6373/9457] [media] vb2-dma-sg: add support for dmabuf exports Add DMABUF export support to vb2-dma-sg. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 170 +++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 81e88a067882..0566e94a5a1d 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -407,6 +407,175 @@ static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*********************************************/ +/* DMABUF ops for exporters */ +/*********************************************/ + +struct vb2_dma_sg_attachment { + struct sg_table sgt; + enum dma_data_direction dma_dir; +}; + +static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, + struct dma_buf_attachment *dbuf_attach) +{ + struct vb2_dma_sg_attachment *attach; + unsigned int i; + struct scatterlist *rd, *wr; + struct sg_table *sgt; + struct vb2_dma_sg_buf *buf = dbuf->priv; + int ret; + + attach = kzalloc(sizeof(*attach), GFP_KERNEL); + if (!attach) + return -ENOMEM; + + sgt = &attach->sgt; + /* Copy the buf->base_sgt scatter list to the attachment, as we can't + * map the same scatter list to multiple attachments at the same time. + */ + ret = sg_alloc_table(sgt, buf->dma_sgt->orig_nents, GFP_KERNEL); + if (ret) { + kfree(attach); + return -ENOMEM; + } + + rd = buf->dma_sgt->sgl; + wr = sgt->sgl; + for (i = 0; i < sgt->orig_nents; ++i) { + sg_set_page(wr, sg_page(rd), rd->length, rd->offset); + rd = sg_next(rd); + wr = sg_next(wr); + } + + attach->dma_dir = DMA_NONE; + dbuf_attach->priv = attach; + + return 0; +} + +static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *db_attach) +{ + struct vb2_dma_sg_attachment *attach = db_attach->priv; + struct sg_table *sgt; + + if (!attach) + return; + + sgt = &attach->sgt; + + /* release the scatterlist cache */ + if (attach->dma_dir != DMA_NONE) + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dma_dir); + sg_free_table(sgt); + kfree(attach); + db_attach->priv = NULL; +} + +static struct sg_table *vb2_dma_sg_dmabuf_ops_map( + struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir) +{ + struct vb2_dma_sg_attachment *attach = db_attach->priv; + /* stealing dmabuf mutex to serialize map/unmap operations */ + struct mutex *lock = &db_attach->dmabuf->lock; + struct sg_table *sgt; + int ret; + + mutex_lock(lock); + + sgt = &attach->sgt; + /* return previously mapped sg table */ + if (attach->dma_dir == dma_dir) { + mutex_unlock(lock); + return sgt; + } + + /* release any previous cache */ + if (attach->dma_dir != DMA_NONE) { + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dma_dir); + attach->dma_dir = DMA_NONE; + } + + /* mapping to the client with new direction */ + ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); + if (ret <= 0) { + pr_err("failed to map scatterlist\n"); + mutex_unlock(lock); + return ERR_PTR(-EIO); + } + + attach->dma_dir = dma_dir; + + mutex_unlock(lock); + + return sgt; +} + +static void vb2_dma_sg_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach, + struct sg_table *sgt, enum dma_data_direction dma_dir) +{ + /* nothing to be done here */ +} + +static void vb2_dma_sg_dmabuf_ops_release(struct dma_buf *dbuf) +{ + /* drop reference obtained in vb2_dma_sg_get_dmabuf */ + vb2_dma_sg_put(dbuf->priv); +} + +static void *vb2_dma_sg_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum) +{ + struct vb2_dma_sg_buf *buf = dbuf->priv; + + return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL; +} + +static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf) +{ + struct vb2_dma_sg_buf *buf = dbuf->priv; + + return vb2_dma_sg_vaddr(buf); +} + +static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf, + struct vm_area_struct *vma) +{ + return vb2_dma_sg_mmap(dbuf->priv, vma); +} + +static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { + .attach = vb2_dma_sg_dmabuf_ops_attach, + .detach = vb2_dma_sg_dmabuf_ops_detach, + .map_dma_buf = vb2_dma_sg_dmabuf_ops_map, + .unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap, + .kmap = vb2_dma_sg_dmabuf_ops_kmap, + .kmap_atomic = vb2_dma_sg_dmabuf_ops_kmap, + .vmap = vb2_dma_sg_dmabuf_ops_vmap, + .mmap = vb2_dma_sg_dmabuf_ops_mmap, + .release = vb2_dma_sg_dmabuf_ops_release, +}; + +static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags) +{ + struct vb2_dma_sg_buf *buf = buf_priv; + struct dma_buf *dbuf; + + if (WARN_ON(!buf->dma_sgt)) + return NULL; + + dbuf = dma_buf_export(buf, &vb2_dma_sg_dmabuf_ops, buf->size, flags, NULL); + if (IS_ERR(dbuf)) + return NULL; + + /* dmabuf keeps reference to vb2 buffer */ + atomic_inc(&buf->refcount); + + return dbuf; +} + /*********************************************/ /* callbacks for DMABUF buffers */ /*********************************************/ @@ -523,6 +692,7 @@ const struct vb2_mem_ops vb2_dma_sg_memops = { .vaddr = vb2_dma_sg_vaddr, .mmap = vb2_dma_sg_mmap, .num_users = vb2_dma_sg_num_users, + .get_dmabuf = vb2_dma_sg_get_dmabuf, .map_dmabuf = vb2_dma_sg_map_dmabuf, .unmap_dmabuf = vb2_dma_sg_unmap_dmabuf, .attach_dmabuf = vb2_dma_sg_attach_dmabuf, -- GitLab From 4650635069dfc9f7d59a55e048560bf05e3ca442 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:05 -0300 Subject: [PATCH 6374/9457] [media] vb2-vmalloc: add support for dmabuf exports Add support for DMABUF exporting to the vb2-vmalloc implementation. All memory models now have support for both importing and exporting of DMABUFs. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 171 ++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index bba2460961df..3966b121e466 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -212,6 +212,176 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*********************************************/ +/* DMABUF ops for exporters */ +/*********************************************/ + +struct vb2_vmalloc_attachment { + struct sg_table sgt; + enum dma_data_direction dma_dir; +}; + +static int vb2_vmalloc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev, + struct dma_buf_attachment *dbuf_attach) +{ + struct vb2_vmalloc_attachment *attach; + struct vb2_vmalloc_buf *buf = dbuf->priv; + int num_pages = PAGE_ALIGN(buf->size) / PAGE_SIZE; + struct sg_table *sgt; + struct scatterlist *sg; + void *vaddr = buf->vaddr; + int ret; + int i; + + attach = kzalloc(sizeof(*attach), GFP_KERNEL); + if (!attach) + return -ENOMEM; + + sgt = &attach->sgt; + ret = sg_alloc_table(sgt, num_pages, GFP_KERNEL); + if (ret) { + kfree(attach); + return ret; + } + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + struct page *page = vmalloc_to_page(vaddr); + + if (!page) { + sg_free_table(sgt); + kfree(attach); + return -ENOMEM; + } + sg_set_page(sg, page, PAGE_SIZE, 0); + vaddr += PAGE_SIZE; + } + + attach->dma_dir = DMA_NONE; + dbuf_attach->priv = attach; + return 0; +} + +static void vb2_vmalloc_dmabuf_ops_detach(struct dma_buf *dbuf, + struct dma_buf_attachment *db_attach) +{ + struct vb2_vmalloc_attachment *attach = db_attach->priv; + struct sg_table *sgt; + + if (!attach) + return; + + sgt = &attach->sgt; + + /* release the scatterlist cache */ + if (attach->dma_dir != DMA_NONE) + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dma_dir); + sg_free_table(sgt); + kfree(attach); + db_attach->priv = NULL; +} + +static struct sg_table *vb2_vmalloc_dmabuf_ops_map( + struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir) +{ + struct vb2_vmalloc_attachment *attach = db_attach->priv; + /* stealing dmabuf mutex to serialize map/unmap operations */ + struct mutex *lock = &db_attach->dmabuf->lock; + struct sg_table *sgt; + int ret; + + mutex_lock(lock); + + sgt = &attach->sgt; + /* return previously mapped sg table */ + if (attach->dma_dir == dma_dir) { + mutex_unlock(lock); + return sgt; + } + + /* release any previous cache */ + if (attach->dma_dir != DMA_NONE) { + dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, + attach->dma_dir); + attach->dma_dir = DMA_NONE; + } + + /* mapping to the client with new direction */ + ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir); + if (ret <= 0) { + pr_err("failed to map scatterlist\n"); + mutex_unlock(lock); + return ERR_PTR(-EIO); + } + + attach->dma_dir = dma_dir; + + mutex_unlock(lock); + + return sgt; +} + +static void vb2_vmalloc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach, + struct sg_table *sgt, enum dma_data_direction dma_dir) +{ + /* nothing to be done here */ +} + +static void vb2_vmalloc_dmabuf_ops_release(struct dma_buf *dbuf) +{ + /* drop reference obtained in vb2_vmalloc_get_dmabuf */ + vb2_vmalloc_put(dbuf->priv); +} + +static void *vb2_vmalloc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum) +{ + struct vb2_vmalloc_buf *buf = dbuf->priv; + + return buf->vaddr + pgnum * PAGE_SIZE; +} + +static void *vb2_vmalloc_dmabuf_ops_vmap(struct dma_buf *dbuf) +{ + struct vb2_vmalloc_buf *buf = dbuf->priv; + + return buf->vaddr; +} + +static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf, + struct vm_area_struct *vma) +{ + return vb2_vmalloc_mmap(dbuf->priv, vma); +} + +static struct dma_buf_ops vb2_vmalloc_dmabuf_ops = { + .attach = vb2_vmalloc_dmabuf_ops_attach, + .detach = vb2_vmalloc_dmabuf_ops_detach, + .map_dma_buf = vb2_vmalloc_dmabuf_ops_map, + .unmap_dma_buf = vb2_vmalloc_dmabuf_ops_unmap, + .kmap = vb2_vmalloc_dmabuf_ops_kmap, + .kmap_atomic = vb2_vmalloc_dmabuf_ops_kmap, + .vmap = vb2_vmalloc_dmabuf_ops_vmap, + .mmap = vb2_vmalloc_dmabuf_ops_mmap, + .release = vb2_vmalloc_dmabuf_ops_release, +}; + +static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flags) +{ + struct vb2_vmalloc_buf *buf = buf_priv; + struct dma_buf *dbuf; + + if (WARN_ON(!buf->vaddr)) + return NULL; + + dbuf = dma_buf_export(buf, &vb2_vmalloc_dmabuf_ops, buf->size, flags, NULL); + if (IS_ERR(dbuf)) + return NULL; + + /* dmabuf keeps reference to vb2 buffer */ + atomic_inc(&buf->refcount); + + return dbuf; +} + /*********************************************/ /* callbacks for DMABUF buffers */ /*********************************************/ @@ -268,6 +438,7 @@ const struct vb2_mem_ops vb2_vmalloc_memops = { .put = vb2_vmalloc_put, .get_userptr = vb2_vmalloc_get_userptr, .put_userptr = vb2_vmalloc_put_userptr, + .get_dmabuf = vb2_vmalloc_get_dmabuf, .map_dmabuf = vb2_vmalloc_map_dmabuf, .unmap_dmabuf = vb2_vmalloc_unmap_dmabuf, .attach_dmabuf = vb2_vmalloc_attach_dmabuf, -- GitLab From 952768c41a993dc1d813baa29d87ecb3da9b266e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:06 -0300 Subject: [PATCH 6375/9457] [media] vivid: enable vb2_expbuf support Now that vb2 supports DMABUF export for dma-sg and vmalloc memory modes, we can enable the vb2_expbuf support in vivid. Signed-off-by: Hans Verkuil Reviewed-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 987a46cdea5e..a7e033a5d291 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -572,7 +572,7 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_querybuf = vb2_ioctl_querybuf, .vidioc_qbuf = vb2_ioctl_qbuf, .vidioc_dqbuf = vb2_ioctl_dqbuf, -/* Not yet .vidioc_expbuf = vb2_ioctl_expbuf,*/ + .vidioc_expbuf = vb2_ioctl_expbuf, .vidioc_streamon = vb2_ioctl_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, -- GitLab From 141f87d4d6ab36bfcd4c5683cf90abf83b306d90 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Tue, 25 Nov 2014 04:49:44 +0800 Subject: [PATCH 6376/9457] ASoC: sigmadsp: fix simple_return.cocci warnings sound/soc/codecs/sigmadsp.c:656:1-4: WARNING: end returns can be simpified and declaration on line 636 can be dropped Simplify a trivial if-return sequence. Possibly combine with a preceding function call. Generated by: scripts/coccinelle/misc/simple_return.cocci Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- sound/soc/codecs/sigmadsp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 6abefd27b86c..34fdc402c1cc 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -633,7 +633,6 @@ static int sigmadsp_alloc_control(struct sigmadsp *sigmadsp, { struct snd_kcontrol_new template; struct snd_kcontrol *kcontrol; - int ret; memset(&template, 0, sizeof(template)); template.iface = SNDRV_CTL_ELEM_IFACE_MIXER; @@ -653,11 +652,7 @@ static int sigmadsp_alloc_control(struct sigmadsp *sigmadsp, kcontrol->private_free = sigmadsp_control_free; ctrl->kcontrol = kcontrol; - ret = snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol); - if (ret) - return ret; - - return 0; + return snd_ctl_add(sigmadsp->component->card->snd_card, kcontrol); } static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp, -- GitLab From f5294f455afd30bdc90f31d6d0101bb773e9ddba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:07 -0300 Subject: [PATCH 6377/9457] [media] vim2m: support expbuf Signed-off-by: Hans Verkuil Reviewed-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vim2m.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 87af47ae1f76..1105c111cc10 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -697,6 +697,7 @@ static const struct v4l2_ioctl_ops vim2m_ioctl_ops = { .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -- GitLab From 251a79f8f5adfd816de4e052b5e3619a5a1d0910 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 18 Nov 2014 09:51:08 -0300 Subject: [PATCH 6378/9457] [media] vb2: use dma_map_sg_attrs to prevent unnecessary sync By default dma_map_sg syncs the mapped buffer to the device. But buf_prepare expects a buffer syncs for the cpu and the buffer will be synced to the device in the prepare memop. The reverse is true for dma_unmap_sg, buf_finish and the finish memop. To prevent unnecessary syncs we ask dma_(un)map_sg to skip the sync. Signed-off-by: Hans Verkuil Acked-by: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l2-core/videobuf2-dma-contig.c | 24 +++++++++++--- drivers/media/v4l2-core/videobuf2-dma-sg.c | 33 +++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 0bfc488c8812..b481d20c8372 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -511,7 +511,15 @@ static void vb2_dc_put_userptr(void *buf_priv) struct sg_table *sgt = buf->dma_sgt; if (sgt) { - dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); + /* + * No need to sync to CPU, it's already synced to the CPU + * since the finish() memop will have been called before this. + */ + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, + buf->dma_dir, &attrs); if (!vma_is_io(buf->vma)) vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); @@ -568,6 +576,9 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, struct sg_table *sgt; unsigned long contig_size; unsigned long dma_align = dma_get_cache_alignment(); + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); /* Only cache aligned DMA transfers are reliable */ if (!IS_ALIGNED(vaddr | size, dma_align)) { @@ -654,8 +665,12 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, kfree(pages); pages = NULL; - sgt->nents = dma_map_sg(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir); + /* + * No need to sync to the device, this will happen later when the + * prepare() memop is called. + */ + sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, + buf->dma_dir, &attrs); if (sgt->nents <= 0) { pr_err("failed to map scatterlist\n"); ret = -EIO; @@ -677,7 +692,8 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, return buf; fail_map_sg: - dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, + buf->dma_dir, &attrs); fail_sgt_init: if (!vma_is_io(buf->vma)) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 0566e94a5a1d..b1838abb6d00 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -107,6 +107,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, struct sg_table *sgt; int ret; int num_pages; + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); if (WARN_ON(alloc_ctx == NULL)) return NULL; @@ -140,9 +143,13 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, buf->dev = get_device(conf->dev); sgt = &buf->sg_table; - if (dma_map_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir) == 0) + /* + * No need to sync to the device, this will happen later when the + * prepare() memop is called. + */ + if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents, + buf->dma_dir, &attrs) == 0) goto fail_map; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; @@ -175,9 +182,13 @@ static void vb2_dma_sg_put(void *buf_priv) int i = buf->num_pages; if (atomic_dec_and_test(&buf->refcount)) { + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, buf->num_pages); - dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents, + buf->dma_dir, &attrs); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(buf->dma_sgt); @@ -228,6 +239,9 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, int num_pages_from_user; struct vm_area_struct *vma; struct sg_table *sgt; + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) @@ -296,9 +310,13 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, goto userptr_fail_alloc_table_from_pages; sgt = &buf->sg_table; - if (dma_map_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir) == 0) + /* + * No need to sync to the device, this will happen later when the + * prepare() memop is called. + */ + if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents, + buf->dma_dir, &attrs) == 0) goto userptr_fail_map; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); return buf; userptr_fail_map: @@ -327,10 +345,13 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) struct vb2_dma_sg_buf *buf = buf_priv; struct sg_table *sgt = &buf->sg_table; int i = buf->num_pages; + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs); dprintk(1, "%s: Releasing userspace buffer of %d pages\n", __func__, buf->num_pages); - dma_unmap_sg(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); + dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir, &attrs); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(buf->dma_sgt); -- GitLab From 073f38494ab9bad6edf589c74a1f09c358c5068c Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 24 Nov 2014 03:57:33 -0300 Subject: [PATCH 6379/9457] [media] si2157: Add support for Si2146-A10 The Silicon Labs Si2146 tuner seems to work with the same driver as the Si2157, but there a few exceptions. The powerup command seems to be quite a bit different. In addition there's a property 0207 that requires a different value. Thus another entry is created in the si2157_id table to support also si2146 in this driver. The datasheet is available on manufacturer's website: http://www.silabs.com/support%20documents/technicaldocs/Si2146-short.pdf Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/si2157.c | 29 ++++++++++++++++++++++------- drivers/media/tuners/si2157.h | 2 +- drivers/media/tuners/si2157_priv.h | 8 ++++++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index b086b87d0890..a8f2edb92b60 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * @@ -93,8 +93,13 @@ static int si2157_init(struct dvb_frontend *fe) goto warm; /* power up */ - memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); - cmd.wlen = 15; + if (s->chiptype == SI2157_CHIPTYPE_SI2146) { + memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); + cmd.wlen = 9; + } else { + memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); + cmd.wlen = 15; + } cmd.rlen = 1; ret = si2157_cmd_execute(s, &cmd); if (ret) @@ -114,6 +119,7 @@ static int si2157_init(struct dvb_frontend *fe) #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0) #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) + #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0) switch (chip_id) { case SI2158_A20: @@ -121,6 +127,7 @@ static int si2157_init(struct dvb_frontend *fe) break; case SI2157_A30: case SI2147_A30: + case SI2146_A10: goto skip_fw_download; break; default: @@ -275,7 +282,10 @@ static int si2157_set_params(struct dvb_frontend *fe) if (ret) goto err; - memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6); + if (s->chiptype == SI2157_CHIPTYPE_SI2146) + memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6); + else + memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6); cmd.wlen = 6; cmd.rlen = 4; ret = si2157_cmd_execute(s, &cmd); @@ -308,7 +318,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) static const struct dvb_tuner_ops si2157_ops = { .info = { - .name = "Silicon Labs Si2157/Si2158", + .name = "Silicon Labs Si2146/2147/2157/2158", .frequency_min = 110000000, .frequency_max = 862000000, }, @@ -339,6 +349,7 @@ static int si2157_probe(struct i2c_client *client, s->fe = cfg->fe; s->inversion = cfg->inversion; s->fw_loaded = false; + s->chiptype = (u8)id->driver_data; mutex_init(&s->i2c_mutex); /* check if the tuner is there */ @@ -355,7 +366,10 @@ static int si2157_probe(struct i2c_client *client, i2c_set_clientdata(client, s); dev_info(&s->client->dev, - "Silicon Labs Si2157/Si2158 successfully attached\n"); + "Silicon Labs %s successfully attached\n", + s->chiptype == SI2157_CHIPTYPE_SI2146 ? + "Si2146" : "Si2147/2157/2158"); + return 0; err: dev_dbg(&client->dev, "failed=%d\n", ret); @@ -380,6 +394,7 @@ static int si2157_remove(struct i2c_client *client) static const struct i2c_device_id si2157_id[] = { {"si2157", 0}, + {"si2146", 1}, {} }; MODULE_DEVICE_TABLE(i2c, si2157_id); @@ -396,7 +411,7 @@ static struct i2c_driver si2157_driver = { module_i2c_driver(si2157_driver); -MODULE_DESCRIPTION("Silicon Labs Si2157/Si2158 silicon tuner driver"); +MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2157/2158 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(SI2158_A20_FIRMWARE); diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h index d3b19cadb4a1..8467d08036de 100644 --- a/drivers/media/tuners/si2157.h +++ b/drivers/media/tuners/si2157.h @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h index e71ffafed951..c1ea82111cd5 100644 --- a/drivers/media/tuners/si2157_priv.h +++ b/drivers/media/tuners/si2157_priv.h @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * @@ -28,9 +28,13 @@ struct si2157 { bool active; bool fw_loaded; bool inversion; + u8 chiptype; }; -/* firmare command struct */ +#define SI2157_CHIPTYPE_SI2157 0 +#define SI2157_CHIPTYPE_SI2146 1 + +/* firmware command struct */ #define SI2157_ARGLEN 30 struct si2157_cmd { u8 args[SI2157_ARGLEN]; -- GitLab From fc30dd7647e502b757c47c2a1b7163face9e0272 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 24 Nov 2014 03:57:34 -0300 Subject: [PATCH 6380/9457] [media] em28xx: Add support for Terratec Cinergy T2 Stick HD Terratec Cinergy T2 Stick HD [eb1a:8179] is a USB DVB-T/T2/C tuner that contains following components: * Empia EM28178 USB bridge * Silicon Labs Si2168-A30 demodulator * Silicon Labs Si2146-A10 tuner I don't have the remote, so the RC_MAP is a best guess based on the pictures of the remote controllers and other supported Terratec devices with a similar remote. [Antti: Resolved conflict caused by Leadtek VC100 patch] Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 27 +++++++++++ drivers/media/usb/em28xx/em28xx-dvb.c | 59 +++++++++++++++++++++++++ drivers/media/usb/em28xx/em28xx.h | 1 + 3 files changed, 87 insertions(+) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 3c97bf106442..5f747a5e2463 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -479,6 +479,20 @@ static struct em28xx_reg_seq pctv_292e[] = { {-1, -1, -1, -1}, }; +static struct em28xx_reg_seq terratec_t2_stick_hd[] = { + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, + {0x0d, 0xff, 0xff, 600}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, + {EM2874_R80_GPIO_P0_CTRL, 0xbc, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 300}, + {EM2874_R80_GPIO_P0_CTRL, 0xf8, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 300}, + {0x0d, 0x42, 0xff, 1000}, + {EM2874_R5F_TS_ENABLE, 0x85, 0xff, 0}, + {-1, -1, -1, -1}, +}; + /* * Button definitions */ @@ -2257,6 +2271,17 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + /* eb1a:8179 Terratec Cinergy T2 Stick HD. + * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 */ + [EM28178_BOARD_TERRATEC_T2_STICK_HD] = { + .name = "Terratec Cinergy T2 Stick HD", + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .tuner_type = TUNER_ABSENT, + .tuner_gpio = terratec_t2_stick_hd, + .has_dvb = 1, + .ir_codes = RC_MAP_TERRATEC_SLIM_2, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2440,6 +2465,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PCTV_292E }, { USB_DEVICE(0x0413, 0x6f07), .driver_info = EM2861_BOARD_LEADTEK_VC100 }, + { USB_DEVICE(0xeb1a, 0x8179), + .driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 5a94f174cc74..0b8823d7f7ec 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1604,6 +1604,65 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; } break; + case EM28178_BOARD_TERRATEC_T2_STICK_HD: + { + struct i2c_adapter *adapter; + struct i2c_client *client; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod = client; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = dvb->fe[0]; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2146", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module("si2157"); + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_tuner = client; + } + break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 05e7f7c77ea1..8c970be8ad33 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -142,6 +142,7 @@ #define EM2874_BOARD_KWORLD_UB435Q_V3 93 #define EM28178_BOARD_PCTV_292E 94 #define EM2861_BOARD_LEADTEK_VC100 95 +#define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- GitLab From b7fca5b06d320250c2c9e48bffb19e42104e5952 Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Mon, 24 Nov 2014 03:57:35 -0300 Subject: [PATCH 6381/9457] [media] si2157: make checkpatch.pl happy (remove break after goto) Break after goto is unnecessary. Signed-off-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/si2157.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index a8f2edb92b60..3bdf00a0ca0e 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -129,7 +129,6 @@ static int si2157_init(struct dvb_frontend *fe) case SI2147_A30: case SI2146_A10: goto skip_fw_download; - break; default: dev_err(&s->client->dev, "unknown chip version Si21%d-%c%c%c\n", -- GitLab From 17ad09f110a080aa16dab21005ab1d5d88f3e254 Mon Sep 17 00:00:00 2001 From: CrazyCat Date: Fri, 14 Nov 2014 18:19:37 -0300 Subject: [PATCH 6382/9457] [media] si2157: Si2148 support Si2148-A20 silicon tuner support. [Antti: Resolved conflict] Signed-off-by: Evgeny Plehov Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/si2157.c | 10 ++++++---- drivers/media/tuners/si2157.h | 2 +- drivers/media/tuners/si2157_priv.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index 3bdf00a0ca0e..8e576960a1df 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * @@ -117,12 +117,14 @@ static int si2157_init(struct dvb_frontend *fe) cmd.args[4] << 0; #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0) + #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0) #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0) switch (chip_id) { case SI2158_A20: + case SI2148_A20: fw_file = SI2158_A20_FIRMWARE; break; case SI2157_A30: @@ -317,7 +319,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) static const struct dvb_tuner_ops si2157_ops = { .info = { - .name = "Silicon Labs Si2146/2147/2157/2158", + .name = "Silicon Labs Si2146/2147/2148/2157/2158", .frequency_min = 110000000, .frequency_max = 862000000, }, @@ -367,7 +369,7 @@ static int si2157_probe(struct i2c_client *client, dev_info(&s->client->dev, "Silicon Labs %s successfully attached\n", s->chiptype == SI2157_CHIPTYPE_SI2146 ? - "Si2146" : "Si2147/2157/2158"); + "Si2146" : "Si2147/2148/2157/2158"); return 0; err: @@ -410,7 +412,7 @@ static struct i2c_driver si2157_driver = { module_i2c_driver(si2157_driver); -MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2157/2158 silicon tuner driver"); +MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(SI2158_A20_FIRMWARE); diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h index 8467d08036de..a564c4a9fba7 100644 --- a/drivers/media/tuners/si2157.h +++ b/drivers/media/tuners/si2157.h @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h index c1ea82111cd5..d6e07cdd2a07 100644 --- a/drivers/media/tuners/si2157_priv.h +++ b/drivers/media/tuners/si2157_priv.h @@ -1,5 +1,5 @@ /* - * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver + * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver * * Copyright (C) 2014 Antti Palosaari * -- GitLab From 52791979e919a212b8197919b11380cffa1bf9b4 Mon Sep 17 00:00:00 2001 From: CrazyCat Date: Fri, 14 Nov 2014 18:22:10 -0300 Subject: [PATCH 6383/9457] [media] si2168: TS clock inversion control TS clock polarity control implemented. [Antti: Resolved simple conflict] Signed-off-by: Evgeny Plehov Reviewed-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 7 +++++-- drivers/media/dvb-frontends/si2168.h | 4 ++++ drivers/media/dvb-frontends/si2168_priv.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 7bac74835d73..16a347aa27f7 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -308,14 +308,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe) if (ret) goto err; - memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); + memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6); + cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10; cmd.wlen = 6; cmd.rlen = 4; ret = si2168_cmd_execute(s, &cmd); if (ret) goto err; - memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); + memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6); + cmd.args[5] |= s->ts_clock_inv ? 0x00 : 0x10; cmd.wlen = 6; cmd.rlen = 4; ret = si2168_cmd_execute(s, &cmd); @@ -669,6 +671,7 @@ static int si2168_probe(struct i2c_client *client, *config->i2c_adapter = s->adapter; *config->fe = &s->fe; s->ts_mode = config->ts_mode; + s->ts_clock_inv = config->ts_clock_inv; s->fw_loaded = false; i2c_set_clientdata(client, s); diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h index e086d6719451..87bc12146667 100644 --- a/drivers/media/dvb-frontends/si2168.h +++ b/drivers/media/dvb-frontends/si2168.h @@ -37,6 +37,10 @@ struct si2168_config { /* TS mode */ u8 ts_mode; + + /* TS clock inverted */ + bool ts_clock_inv; + }; #define SI2168_TS_PARALLEL 0x06 diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index e13983ed4be1..60bc3349b6c3 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -38,6 +38,7 @@ struct si2168 { bool active; bool fw_loaded; u8 ts_mode; + bool ts_clock_inv; }; /* firmare command struct */ -- GitLab From a0f629b975e0c99b4d9ccb9eaa1dbaf8ef8af15e Mon Sep 17 00:00:00 2001 From: CrazyCat Date: Fri, 14 Nov 2014 18:24:28 -0300 Subject: [PATCH 6384/9457] [media] cxusb: Geniatech T230 support Geniatech Mygica T230 DVB-T/T2/C USB stick support. Signed-off-by: Evgeny Plehov Reviewed-by: Olli Salonen Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb-usb-ids.h | 1 + drivers/media/usb/dvb-usb/cxusb.c | 127 +++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index e07a84e7bc56..80ab8d0ff6e0 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h @@ -356,6 +356,7 @@ #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 #define USB_PID_SONY_PLAYTV 0x0003 #define USB_PID_MYGICA_D689 0xd811 +#define USB_PID_MYGICA_T230 0xc688 #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 #define USB_PID_ELGATO_EYETV_DTT 0x0021 #define USB_PID_ELGATO_EYETV_DTT_2 0x003f diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index abece57aa2ea..643d88f95b39 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1408,6 +1408,76 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) return 0; } +static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dvb_usb_device *d = adap->dev; + struct cxusb_state *st = d->priv; + struct i2c_adapter *adapter; + struct i2c_client *client_demod; + struct i2c_client *client_tuner; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* Select required USB configuration */ + if (usb_set_interface(d->udev, 0, 0) < 0) + err("set interface failed"); + + /* Unblock all USB pipes */ + usb_clear_halt(d->udev, + usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); + + /* attach frontend */ + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &adap->fe_adap[0].fe; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + si2168_config.ts_clock_inv = 1; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client_demod = i2c_new_device(&d->i2c_adap, &info); + if (client_demod == NULL || client_demod->dev.driver == NULL) + return -ENODEV; + + if (!try_module_get(client_demod->dev.driver->owner)) { + i2c_unregister_device(client_demod); + return -ENODEV; + } + + st->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = adap->fe_adap[0].fe; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client_tuner = i2c_new_device(adapter, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + return -ENODEV; + } + if (!try_module_get(client_tuner->dev.driver->owner)) { + i2c_unregister_device(client_tuner); + module_put(client_demod->dev.driver->owner); + i2c_unregister_device(client_demod); + return -ENODEV; + } + + st->i2c_client_tuner = client_tuner; + + return 0; +} + static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) { struct dvb_usb_device *d = adap->dev; @@ -1610,6 +1680,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static struct dvb_usb_device_properties cxusb_mygica_d689_properties; +static struct dvb_usb_device_properties cxusb_mygica_t230_properties; static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties; static int cxusb_probe(struct usb_interface *intf, @@ -1641,6 +1712,8 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, + THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties, THIS_MODULE, NULL, adapter_nr) || 0) @@ -1702,6 +1775,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) }, { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) }, + { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -2408,6 +2482,59 @@ static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = { } }; +static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .streaming_ctrl = cxusb_streaming_ctrl, + .frontend_attach = cxusb_mygica_t230_frontend_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 5, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 8192, + } + } + }, + } }, + }, + }, + + .power_ctrl = cxusb_d680_dmb_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .rc.legacy = { + .rc_interval = 100, + .rc_map_table = rc_map_d680_dmb_table, + .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), + .rc_query = cxusb_d680_dmb_rc_query, + }, + + .num_device_descs = 1, + .devices = { + { + "Mygica T230 DVB-T/T2/C", + { NULL }, + { &cxusb_table[22], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, -- GitLab From d442b15fb4deb2b5d516e2dae1f569b1d5472399 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 25 Nov 2014 09:17:13 -0200 Subject: [PATCH 6385/9457] [media] lmed04: add missing breaks drivers/media/usb/dvb-usb-v2/lmedm04.c:828 lme_firmware_switch() warn: missing break? reassigning 'st->dvb_usb_lme2510_firmware' drivers/media/usb/dvb-usb-v2/lmedm04.c:849 lme_firmware_switch() warn: missing break? reassigning 'st->dvb_usb_lme2510_firmware' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 9f2c5459b73a..99587418f4f0 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -826,6 +826,7 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) break; } st->dvb_usb_lme2510_firmware = TUNER_LG; + break; case TUNER_LG: fw_lme = fw_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); @@ -847,6 +848,7 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) break; } st->dvb_usb_lme2510_firmware = TUNER_LG; + break; case TUNER_LG: fw_lme = fw_c_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); -- GitLab From 9bc2dd7ec0db76c7159d8124cd2bf8d1ff2a2ede Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 18:27:24 -0300 Subject: [PATCH 6386/9457] [media] DVB-frontends: Deletion of unnecessary checks before the function call "release_firmware" GIT_AUTHOR_DATE=1416472432 The release_firmware() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drx39xyj/drxj.c | 3 +-- drivers/media/dvb-frontends/drxk_hard.c | 3 +-- drivers/media/dvb-frontends/m88ds3103.c | 3 +-- drivers/media/dvb-frontends/si2168.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 5ec221ffdfca..2bfa7a435974 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -12255,8 +12255,7 @@ static void drx39xxj_release(struct dvb_frontend *fe) kfree(demod->my_ext_attr); kfree(demod->my_common_attr); kfree(demod->my_i2c_dev_addr); - if (demod->firmware) - release_firmware(demod->firmware); + release_firmware(demod->firmware); kfree(demod); kfree(state); } diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index f140b835c414..d46cf5f7cd2e 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -6310,8 +6310,7 @@ static void drxk_release(struct dvb_frontend *fe) struct drxk_state *state = fe->demodulator_priv; dprintk(1, "\n"); - if (state->fw) - release_firmware(state->fw); + release_firmware(state->fw); kfree(state); } diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 0cd445cfeff6..843e669a3d7c 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -687,8 +687,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) return 0; err: - if (fw) - release_firmware(fw); + release_firmware(fw); dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 16a347aa27f7..34206f3fe497 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -507,8 +507,7 @@ static int si2168_init(struct dvb_frontend *fe) return 0; err: - if (fw) - release_firmware(fw); + release_firmware(fw); dev_dbg(&s->client->dev, "failed=%d\n", ret); return ret; -- GitLab From 008c2a2ef0af9a31a848948034d7d59b37f9a9e1 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Tue, 25 Nov 2014 08:36:12 +0800 Subject: [PATCH 6387/9457] spi: meson: meson_spifc_setup_speed() can be static drivers/spi/spi-meson-spifc.c:171:6: sparse: symbol 'meson_spifc_setup_speed' was not declared. Should it be static? Signed-off-by: Fengguang Wu Signed-off-by: Mark Brown --- drivers/spi/spi-meson-spifc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index f536476710ad..0e48f8c2037d 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c @@ -168,7 +168,7 @@ static void meson_spifc_fill_buffer(struct meson_spifc *spifc, const u8 *buf, * @spifc: the Meson SPI device * @speed: desired speed in Hz */ -void meson_spifc_setup_speed(struct meson_spifc *spifc, u32 speed) +static void meson_spifc_setup_speed(struct meson_spifc *spifc, u32 speed) { unsigned long parent, value; int n; -- GitLab From 2d4e2d020516632288e8c8d1f8be2f3042d6b8de Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 18 Nov 2014 16:50:18 +0800 Subject: [PATCH 6388/9457] ASoC: rt5645: multiple JD mode support There are 3 JD modes in RT5645. This patch configure register values according to platform data. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- include/sound/rt5645.h | 1 + sound/soc/codecs/rt5645.c | 35 ++++++++++++++++++++++++++++++++++- sound/soc/codecs/rt5645.h | 7 +++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h index 937f421bc66b..120d9610054e 100644 --- a/include/sound/rt5645.h +++ b/include/sound/rt5645.h @@ -26,6 +26,7 @@ struct rt5645_platform_data { /* true if codec's jd function is used */ bool en_jd_func; + unsigned int jd_mode; }; #endif diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index ef88b506a017..6e9cd8e743a7 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2239,7 +2239,8 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(&codec->dapm, "micbias1"); snd_soc_dapm_disable_pin(&codec->dapm, "micbias2"); - snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); + if (rt5645->pdata.jd_mode == 0) + snd_soc_dapm_disable_pin(&codec->dapm, "LDO2"); snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_sync(&codec->dapm); } @@ -2543,6 +2544,38 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, RT5645_IRQ_CLK_INT, RT5645_IRQ_CLK_INT); } + if (rt5645->pdata.jd_mode) { + regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, + RT5645_IRQ_JD_1_1_EN, RT5645_IRQ_JD_1_1_EN); + regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3, + RT5645_JD_PSV_MODE, RT5645_JD_PSV_MODE); + regmap_update_bits(rt5645->regmap, RT5645_HPO_MIXER, + RT5645_IRQ_PSV_MODE, RT5645_IRQ_PSV_MODE); + regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, + RT5645_MIC2_OVCD_EN, RT5645_MIC2_OVCD_EN); + regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, + RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ); + switch (rt5645->pdata.jd_mode) { + case 1: + regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, + RT5645_JD1_MODE_MASK, + RT5645_JD1_MODE_0); + break; + case 2: + regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, + RT5645_JD1_MODE_MASK, + RT5645_JD1_MODE_1); + break; + case 3: + regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, + RT5645_JD1_MODE_MASK, + RT5645_JD1_MODE_2); + break; + default: + break; + } + } + if (rt5645->i2c->irq) { ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index c72220abdbc0..a815e36a2bdb 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -594,6 +594,7 @@ #define RT5645_M_DAC1_HM_SFT 14 #define RT5645_M_HPVOL_HM (0x1 << 13) #define RT5645_M_HPVOL_HM_SFT 13 +#define RT5645_IRQ_PSV_MODE (0x1 << 12) /* SPK Left Mixer Control (0x46) */ #define RT5645_G_RM_L_SM_L_MASK (0x3 << 14) @@ -1350,6 +1351,10 @@ #define RT5645_PWR_CLK25M_PU (0x1 << 4) #define RT5645_IRQ_CLK_MCLK (0x0 << 3) #define RT5645_IRQ_CLK_INT (0x1 << 3) +#define RT5645_JD1_MODE_MASK (0x3 << 0) +#define RT5645_JD1_MODE_0 (0x0 << 0) +#define RT5645_JD1_MODE_1 (0x1 << 0) +#define RT5645_JD1_MODE_2 (0x2 << 0) /* VAD Control 4 (0x9d) */ #define RT5645_VAD_SEL_MASK (0x3 << 8) @@ -1638,6 +1643,7 @@ #define RT5645_OT_P_SFT 10 #define RT5645_OT_P_NOR (0x0 << 10) #define RT5645_OT_P_INV (0x1 << 10) +#define RT5645_IRQ_JD_1_1_EN (0x1 << 9) /* IRQ Control 2 (0xbe) */ #define RT5645_IRQ_MB1_OC_MASK (0x1 << 15) @@ -2120,6 +2126,7 @@ enum { #define RT5645_RXDP2_SEL_SFT (3) /* General Control3 (0xfc) */ +#define RT5645_JD_PSV_MODE (0x1 << 12) #define RT5645_IRQ_CLK_GATE_CTRL (0x1 << 11) #define RT5645_MICINDET_MANU (0x1 << 7) -- GitLab From 8284731eb59e843a0608baf18828e0ad0d7f9d79 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 25 Nov 2014 12:13:30 +0100 Subject: [PATCH 6389/9457] simplefb: Fix build errors when CONFIG_COMMON_CLK is not defined Both CONFIG_OF and CONFIG_COMMON_CLK must be defined to be able to use of clocks. Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/simplefb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 8be9754c9fe9..b2ae9254fd75 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -169,13 +169,13 @@ static int simplefb_parse_pd(struct platform_device *pdev, struct simplefb_par { u32 palette[PSEUDO_PALETTE_SIZE]; -#ifdef CONFIG_OF +#if defined CONFIG_OF && defined CONFIG_COMMON_CLK int clk_count; struct clk **clks; #endif }; -#ifdef CONFIG_OF +#if defined CONFIG_OF && defined CONFIG_COMMON_CLK /* * Clock handling code. * -- GitLab From b0ff4b93f646c39900ead9f6f7b6da78b5978273 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 24 Nov 2014 20:01:58 +0100 Subject: [PATCH 6390/9457] drm: Document that drm_dev_alloc doesn't need a parent Possible for purely virtual debug devices. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 2e5c7d941313..4f41377b0b80 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -535,6 +535,8 @@ static void drm_fs_inode_free(struct inode *inode) * The initial ref-count of the object is 1. Use drm_dev_ref() and * drm_dev_unref() to take and drop further ref-counts. * + * Note that for purely virtual devices @parent can be NULL. + * * RETURNS: * Pointer to new DRM device, or NULL if out of memory. */ -- GitLab From ab58e3384b9f9863bfd029b458ff337d381bf6d2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 24 Nov 2014 20:42:42 +0100 Subject: [PATCH 6391/9457] drm/atomic-helper: Skip vblank waits for unchanged fbs Especially with legacy cursor ioctls existing userspace assumes that you can pile up lots of updates in one go. The super-proper way to support this would be a special commit mode which overwrites the last update. But getting there will be quite a bit of work. Meanwhile do what pretty much all the drivers have done for the plane update functions: Simply skip the vblank wait for the buffer cleanup if the buffer is the same. Since the universal cursor plane code will not recreate framebuffers needlessly this allows us to not slow down legacy pageflip events while someone moves the cursor around. v2: Drop the async plane update hunk from a previous attempt at this issue. v3: Fix up kerneldoc. v4: Don't oops so badly. Reported by Jasper. Cc: Rob Clark Cc: "Jasper St. Pierre" Reviewed-by: Rob Clark Reviewed-by: Jasper St. Pierre Tested-by: Jasper St. Pierre Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index a17b8e9c0a81..4368581ac1eb 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -751,6 +751,33 @@ static void wait_for_fences(struct drm_device *dev, } } +static bool framebuffer_changed(struct drm_device *dev, + struct drm_atomic_state *old_state, + struct drm_crtc *crtc) +{ + struct drm_plane *plane; + struct drm_plane_state *old_plane_state; + int nplanes = old_state->dev->mode_config.num_total_plane; + int i; + + for (i = 0; i < nplanes; i++) { + plane = old_state->planes[i]; + old_plane_state = old_state->plane_states[i]; + + if (!plane) + continue; + + if (plane->state->crtc != crtc && + old_plane_state->crtc != crtc) + continue; + + if (plane->state->fb != old_plane_state->fb) + return true; + } + + return false; +} + /** * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs * @dev: DRM device @@ -758,7 +785,9 @@ static void wait_for_fences(struct drm_device *dev, * * Helper to, after atomic commit, wait for vblanks on all effected * crtcs (ie. before cleaning up old framebuffers using - * drm_atomic_helper_cleanup_planes()) + * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where the + * framebuffers have actually changed to optimize for the legacy cursor and + * plane update use-case. */ void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, @@ -784,6 +813,9 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, if (!crtc->state->enable) continue; + if (!framebuffer_changed(dev, old_state, crtc)) + continue; + ret = drm_crtc_vblank_get(crtc); if (ret != 0) continue; -- GitLab From 9c04b7e3698a2e77b3473ef91a26ecb384459a04 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 24 Nov 2014 20:51:21 +0100 Subject: [PATCH 6392/9457] drm/atomic: Drop per-plane locking TODO I've forgotten to remove that in my per-plane locking patch. Reported-by: Rob Clark Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d3b46746b611..ba49b5ca822f 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -243,12 +243,6 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, if (state->plane_states[index]) return state->plane_states[index]; - /* - * TODO: We currently don't have per-plane mutexes. So instead of trying - * crazy tricks with deferring plane->crtc and hoping for the best just - * grab all crtc locks. Once we have per-plane locks we must update this - * to only take the plane mutex. - */ ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx); if (ret) return ERR_PTR(ret); -- GitLab From aa54e2ee80b4f653f75b9139ae7500ee8cd5ad5f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Nov 2014 19:59:15 -0800 Subject: [PATCH 6393/9457] drm/atomic_helper: Cope with plane->crtc == NULL in disable helper The drm core can call the plane disable hook multiple times, which means it can get called when plane->crtc is already NULL. That in turn means we can't get at the implicit acquire ctx we use in the atomic helpers for legacy entries points. We could try to pass drm_modeset_legacy_acquire_ctx a drm_device pointer so that it can cope with a NULL crtc. But that still doesn't work since the cursor ioctls (remapped with the universal cursor plane support code) only grabs the crtc locks. So the global acquire context isn't set eitehr. The real solution here would be to bite the bullet and wire up explicit acquire context parameters to all relevant functions. We need to do that anyway (to be able to get rid of some small allocations which we can't cope with failing). But that's a lot of work and better done once atomic has settled a bit. So meanwhile just catch this case in the helper and bail out. Signed-off-by: Jasper St. Pierre Reviewed-by: Rob Clark Cc: Daniel Vetter [danvet: Completely rewrite commit message and comment but keep Jasper's logic and author credits since his patch is the only short-term solution that works.] Tested-by: Thierry Reding Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 4368581ac1eb..d981d07d50cd 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1275,6 +1275,17 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane) struct drm_plane_state *plane_state; int ret = 0; + /* + * FIXME: Without plane->crtc set we can't get at the implicit legacy + * acquire context. The real fix will be to wire the acquire ctx through + * everywhere we need it, but meanwhile prevent chaos by just skipping + * this noop. The critical case is the cursor ioctls which a) only grab + * crtc/cursor-plane locks (so we need the crtc to get at the right + * acquire context) and b) can try to disable the plane multiple times. + */ + if (!plane->crtc) + return 0; + state = drm_atomic_state_alloc(plane->dev); if (!state) return -ENOMEM; -- GitLab From e50334d4e1c3bacfeb3bb1530f73a419d4ec6832 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 17 Nov 2014 15:27:21 +0800 Subject: [PATCH 6394/9457] ASoC: rt5670: check if asrc is useable To use ASRC, the sysclk should be faster than 384 times sample rate of I2S1. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 5e54ac957e47..3ddb34ef77d7 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -576,6 +576,18 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, } +static int can_use_asrc(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); + struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); + + if (rt5670->sysclk > rt5670->lrck[RT5670_AIF1] * 384) + return 1; + + return 0; +} + /* Digital Mixer */ static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = { SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER, @@ -1639,8 +1651,8 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = { { "DAC Mono Right Filter", NULL, "DAC MONO R ASRC", is_using_asrc }, { "DAC Stereo1 Filter", NULL, "DAC STO ASRC", is_using_asrc }, - { "I2S1", NULL, "I2S1 ASRC" }, - { "I2S2", NULL, "I2S2 ASRC" }, + { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, + { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, { "DMIC1", NULL, "DMIC L1" }, { "DMIC1", NULL, "DMIC R1" }, -- GitLab From ff4541c3f48781f84e1cc162d73013aa32a09a41 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 17 Nov 2014 15:27:22 +0800 Subject: [PATCH 6395/9457] ASoC: rt5670: add DMIC ASRC support This patch will enable ASRC for DMIC if ASRC is useable. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 3ddb34ef77d7..8bf3a5686dd7 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -1294,6 +1294,14 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { 9, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5670_ASRC_1, 8, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5670_ASRC_1, + 7, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5670_ASRC_1, + 6, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5670_ASRC_1, + 5, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5670_ASRC_1, + 4, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5670_ASRC_1, 3, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5670_ASRC_1, @@ -1650,6 +1658,10 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = { { "DAC Mono Left Filter", NULL, "DAC MONO L ASRC", is_using_asrc }, { "DAC Mono Right Filter", NULL, "DAC MONO R ASRC", is_using_asrc }, { "DAC Stereo1 Filter", NULL, "DAC STO ASRC", is_using_asrc }, + { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc }, + { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc }, + { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc }, + { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc }, { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, -- GitLab From f1c37e1adc6eca1fb492c74d466141d9b01e0428 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 25 Nov 2014 12:09:44 +0100 Subject: [PATCH 6396/9457] drm/plane: Pass old state to ->atomic_update() In most situations it will be useful to have the old state passed to the ->atomic_update() callback. For example if a plane is being disabled the new state's .crtc field will be NULL, but some drivers may rely on this field to program the CRTCs registers. v2: rename variable to old_plane_state and remove redundant comment as suggested by Daniel Vetter, remove an Exynos hunk that doesn't apply to drm-next and add a hunk for pending MSM mdp5 changes Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 5 ++++- drivers/gpu/drm/drm_plane_helper.c | 2 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 3 ++- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 ++- include/drm/drm_plane_helper.h | 3 ++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index d981d07d50cd..2fa0840694d0 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1046,6 +1046,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = old_state->planes[i]; + struct drm_plane_state *old_plane_state; if (!plane) continue; @@ -1055,7 +1056,9 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (!funcs || !funcs->atomic_update) continue; - funcs->atomic_update(plane); + old_plane_state = old_state->plane_states[i]; + + funcs->atomic_update(plane, old_plane_state); } for (i = 0; i < ncrtcs; i++) { diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 93c6533c25da..18a1ac6ac22f 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -443,7 +443,7 @@ int drm_plane_helper_commit(struct drm_plane *plane, crtc_funcs[i]->atomic_begin(crtc[i]); } - plane_funcs->atomic_update(plane); + plane_funcs->atomic_update(plane, plane_state); for (i = 0; i < 2; i++) { if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 76d0a40c7138..1e5ebe83647d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -107,7 +107,8 @@ static int mdp4_plane_atomic_check(struct drm_plane *plane, return 0; } -static void mdp4_plane_atomic_update(struct drm_plane *plane) +static void mdp4_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) { struct drm_plane_state *state = plane->state; int ret; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 533df7caa310..26e5fdea6594 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -213,7 +213,8 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, return 0; } -static void mdp5_plane_atomic_update(struct drm_plane *plane) +static void mdp5_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) { struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); struct drm_plane_state *state = plane->state; diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index c48f14d88690..fcfa969523fb 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -60,7 +60,8 @@ struct drm_plane_helper_funcs { int (*atomic_check)(struct drm_plane *plane, struct drm_plane_state *state); - void (*atomic_update)(struct drm_plane *plane); + void (*atomic_update)(struct drm_plane *plane, + struct drm_plane_state *old_state); }; static inline void drm_plane_helper_add(struct drm_plane *plane, -- GitLab From 5d571690154cbe7e7b4d24ea8af2393146609b0e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 25 Nov 2014 12:09:45 +0100 Subject: [PATCH 6397/9457] drm/plane: Add missing kerneldoc The plane helpers aren't pulled into the DocBook yet, so these weren't noticed. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- include/drm/drm_plane_helper.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index fcfa969523fb..a185392cafeb 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -49,6 +49,10 @@ extern int drm_crtc_init(struct drm_device *dev, /** * drm_plane_helper_funcs - helper operations for CRTCs + * @prepare_fb: prepare a framebuffer for use by the plane + * @cleanup_fb: cleanup a framebuffer when it's no longer used by the plane + * @atomic_check: check that a given atomic state is valid and can be applied + * @atomic_update: apply an atomic state to the plane * * The helper operations are called by the mid-layer CRTC helper. */ -- GitLab From 0254951d9c581ea21f989f7c8248079fb414a152 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 25 Nov 2014 12:09:47 +0100 Subject: [PATCH 6398/9457] drm: Make drm_atomic_helper.h standalone includible This header uses a bunch of declarations from the drm/drm_crtc.h header, so make sure to include that as well so that drm_atomic_helper.h can be included standalone. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 64b4e91b93bc..70a83197ef66 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -28,6 +28,8 @@ #ifndef DRM_ATOMIC_HELPER_H_ #define DRM_ATOMIC_HELPER_H_ +#include + int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state); int drm_atomic_helper_commit(struct drm_device *dev, -- GitLab From 37cc0148773abbd8e7dbf8b2cb3399e887233fc2 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 25 Nov 2014 12:09:48 +0100 Subject: [PATCH 6399/9457] drm: Make drm_atomic.h standalone includible This header file makes use of a bunch of structures declared in the drm_crtc.h header file. Include that to make sure the drm_atomic.h header can be included standalone. Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- include/drm/drm_atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 9d919168bc11..e224ccfa11ca 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -28,6 +28,8 @@ #ifndef DRM_ATOMIC_H_ #define DRM_ATOMIC_H_ +#include + struct drm_atomic_state * __must_check drm_atomic_state_alloc(struct drm_device *dev); void drm_atomic_state_clear(struct drm_atomic_state *state); -- GitLab From 3009c0377f25c29852b218a6933a969d02cbdc5d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 25 Nov 2014 12:09:49 +0100 Subject: [PATCH 6400/9457] drm: Free atomic state during cleanup The current state of CRTCs, planes and connectors currently leaks during DRM driver ->unload() unless drivers explicitly clean it up. Since there is nothing driver-specific about it, that cleanup can be done within the DRM core. Reviewed-by: Daniel Vetter Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 589a921d4313..e4e7b92f6d32 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -721,6 +721,10 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) drm_mode_object_put(dev, &crtc->base); list_del(&crtc->head); dev->mode_config.num_crtc--; + + WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state); + if (crtc->state && crtc->funcs->atomic_destroy_state) + crtc->funcs->atomic_destroy_state(crtc, crtc->state); } EXPORT_SYMBOL(drm_crtc_cleanup); @@ -918,6 +922,11 @@ void drm_connector_cleanup(struct drm_connector *connector) connector->name = NULL; list_del(&connector->head); dev->mode_config.num_connector--; + + WARN_ON(connector->state && !connector->funcs->atomic_destroy_state); + if (connector->state && connector->funcs->atomic_destroy_state) + connector->funcs->atomic_destroy_state(connector, + connector->state); } EXPORT_SYMBOL(drm_connector_cleanup); @@ -1244,6 +1253,10 @@ void drm_plane_cleanup(struct drm_plane *plane) if (plane->type == DRM_PLANE_TYPE_OVERLAY) dev->mode_config.num_overlay_plane--; drm_modeset_unlock_all(dev); + + WARN_ON(plane->state && !plane->funcs->atomic_destroy_state); + if (plane->state && plane->funcs->atomic_destroy_state) + plane->funcs->atomic_destroy_state(plane, plane->state); } EXPORT_SYMBOL(drm_plane_cleanup); -- GitLab From 6fe17da00ba7046db2d3a952a930e127dcd7f06e Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Tue, 25 Nov 2014 09:51:41 +0800 Subject: [PATCH 6401/9457] ASoC: rt5677: Fix the issue that the regmap_range "rt5677_ranges" cannot be accessed After the patch "ASoC: rt5677: Use specific r/w function for DSP mode", the regmap_range "rt5677_ranges" was not registered in rt5677_regmap_physical, and it caused that the regmap_range "rt5677_ranges" cannot be accessed by the specific r/w function. The patch fixes this issue. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 37 ++++++++++++++++++++++++++++++------- sound/soc/codecs/rt5677.h | 2 +- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index f2211f14ba41..133010dd9f34 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -4287,6 +4287,7 @@ static int rt5677_probe(struct snd_soc_codec *codec) } mutex_init(&rt5677->dsp_cmd_lock); + mutex_init(&rt5677->dsp_pri_lock); return 0; } @@ -4344,10 +4345,19 @@ static int rt5677_read(void *context, unsigned int reg, unsigned int *val) struct i2c_client *client = context; struct rt5677_priv *rt5677 = i2c_get_clientdata(client); - if (rt5677->is_dsp_mode) - rt5677_dsp_mode_i2c_read(rt5677, reg, val); - else + if (rt5677->is_dsp_mode) { + if (reg > 0xff) { + mutex_lock(&rt5677->dsp_pri_lock); + rt5677_dsp_mode_i2c_write(rt5677, RT5677_PRIV_INDEX, + reg & 0xff); + rt5677_dsp_mode_i2c_read(rt5677, RT5677_PRIV_DATA, val); + mutex_unlock(&rt5677->dsp_pri_lock); + } else { + rt5677_dsp_mode_i2c_read(rt5677, reg, val); + } + } else { regmap_read(rt5677->regmap_physical, reg, val); + } return 0; } @@ -4357,10 +4367,20 @@ static int rt5677_write(void *context, unsigned int reg, unsigned int val) struct i2c_client *client = context; struct rt5677_priv *rt5677 = i2c_get_clientdata(client); - if (rt5677->is_dsp_mode) - rt5677_dsp_mode_i2c_write(rt5677, reg, val); - else + if (rt5677->is_dsp_mode) { + if (reg > 0xff) { + mutex_lock(&rt5677->dsp_pri_lock); + rt5677_dsp_mode_i2c_write(rt5677, RT5677_PRIV_INDEX, + reg & 0xff); + rt5677_dsp_mode_i2c_write(rt5677, RT5677_PRIV_DATA, + val); + mutex_unlock(&rt5677->dsp_pri_lock); + } else { + rt5677_dsp_mode_i2c_write(rt5677, reg, val); + } + } else { regmap_write(rt5677->regmap_physical, reg, val); + } return 0; } @@ -4495,10 +4515,13 @@ static const struct regmap_config rt5677_regmap_physical = { .reg_bits = 8, .val_bits = 16, - .max_register = RT5677_VENDOR_ID2 + 1, + .max_register = RT5677_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5677_ranges) * + RT5677_PR_SPACING), .readable_reg = rt5677_readable_register, .cache_type = REGCACHE_NONE, + .ranges = rt5677_ranges, + .num_ranges = ARRAY_SIZE(rt5677_ranges), }; static const struct regmap_config rt5677_regmap = { diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index a02f64c23596..dbd9ffde50dc 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -1670,7 +1670,7 @@ struct rt5677_priv { struct rt5677_platform_data pdata; struct regmap *regmap, *regmap_physical; const struct firmware *fw1, *fw2; - struct mutex dsp_cmd_lock; + struct mutex dsp_cmd_lock, dsp_pri_lock; int sysclk; int sysclk_src; -- GitLab From 86ea522b369abbbe92b4d66a238e79319ca46ba5 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 24 Oct 2014 16:48:12 -0700 Subject: [PATCH 6402/9457] ASoC: fsl_esai: Use dynamic slot width as default The driver previously used 32-bit fixed slot width as default. In result, ESAI might use 32-bit length to capture 16-bit width audio slot from CODEC side when ESAI is running as DAI slave. So this patch just removes the default slot_width so as to use dynamic slot width. If there comes a specific situation that needs a fixed width, the machine driver shall set slot_width via set_tdm_slot() so as to let the ESAI driver replace the dynamic width policy with the fixed value. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index a645e296199e..ca319d59f843 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -513,10 +513,15 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, u32 width = snd_pcm_format_width(params_format(params)); u32 channels = params_channels(params); u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); + u32 slot_width = width; u32 bclk, mask, val; int ret; - bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots; + /* Override slot_width if being specifially set */ + if (esai_priv->slot_width) + slot_width = esai_priv->slot_width; + + bclk = params_rate(params) * slot_width * esai_priv->slots; ret = fsl_esai_set_bclk(dai, tx, bclk); if (ret) @@ -538,7 +543,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0); - val = ESAI_xCR_xSWS(esai_priv->slot_width, width) | (tx ? ESAI_xCR_PADC : 0); + val = ESAI_xCR_xSWS(slot_width, width) | (tx ? ESAI_xCR_PADC : 0); regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val); @@ -780,9 +785,6 @@ static int fsl_esai_probe(struct platform_device *pdev) return ret; } - /* Set a default slot size */ - esai_priv->slot_width = 32; - /* Set a default slot number */ esai_priv->slots = 2; -- GitLab From cb3fc1ff46667ee4ab23ef22c9e391aa7d014cdf Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 24 Oct 2014 16:48:13 -0700 Subject: [PATCH 6403/9457] ASoC: fsl-asoc-card: Add slot_width setting for cpu-dai ESAI may need to use fixed slot width to comply with external CODEC. So this set_tdm_slot() call will allow the ESAI driver to override its default dynamic slot width policy. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl-asoc-card.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 14572e62dd51..3f6959c8e2f7 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -51,6 +51,7 @@ struct codec_priv { * @sysclk_freq[2]: SYSCLK rates for set_sysclk() * @sysclk_dir[2]: SYSCLK directions for set_sysclk() * @sysclk_id[2]: SYSCLK ids for set_sysclk() + * @slot_width: Slot width of each frame * * Note: [1] for tx and [0] for rx */ @@ -58,6 +59,7 @@ struct cpu_priv { unsigned long sysclk_freq[2]; u32 sysclk_dir[2]; u32 sysclk_id[2]; + u32 slot_width; }; /** @@ -142,6 +144,15 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, return ret; } + if (cpu_priv->slot_width) { + ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, + cpu_priv->slot_width); + if (ret) { + dev_err(dev, "failed to set TDM slot for cpu dai\n"); + return ret; + } + } + return 0; } @@ -453,6 +464,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq; priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT; priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT; + priv->cpu_priv.slot_width = 32; priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) { priv->codec_priv.mclk_id = SGTL5000_SYSCLK; -- GitLab From f1e5982546edf96e4537ba689cfad83b90b70143 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Tue, 25 Nov 2014 21:00:53 +0800 Subject: [PATCH 6404/9457] ASoC: Intel: Fix stream volume set no effect issue on Broadwell The volume setting control for capture stream doesn't take effect on intel Broadwell platform. Root cause it at 2 points: 1. set stream volume with channel=2 is wrongly bapassed; 2. the saved stream volume should be restored after stream is commit. Here correct these 2 items to fix the stream volume set issue. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 35 +++++++++++++++++++++++-------- sound/soc/intel/sst-haswell-ipc.h | 1 + sound/soc/intel/sst-haswell-pcm.c | 21 +++++++++++-------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index ffd5728d55c3..3f8c48231364 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1042,14 +1042,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, trace_ipc_request("set stream volume", stream->reply.stream_hw_id); - if (channel > 1) + if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) return -EINVAL; - if (stream->mute[channel]) { - stream->mute_volume[channel] = volume; - return 0; - } - header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); @@ -1057,9 +1052,28 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, header |= (stage_id << IPC_STG_ID_SHIFT); req = &stream->vol_req; - req->channel = channel; req->target_volume = volume; + /* set both at same time ? */ + if (channel == SST_HSW_CHANNELS_ALL) { + if (hsw->mute[0] && hsw->mute[1]) { + hsw->mute_volume[0] = hsw->mute_volume[1] = volume; + return 0; + } else if (hsw->mute[0]) + req->channel = 1; + else if (hsw->mute[1]) + req->channel = 0; + else + req->channel = SST_HSW_CHANNELS_ALL; + } else { + /* set only 1 channel */ + if (hsw->mute[channel]) { + hsw->mute_volume[channel] = volume; + return 0; + } + req->channel = channel; + } + ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0); if (ret < 0) { dev_err(hsw->dev, "error: set stream volume failed\n"); @@ -1138,8 +1152,11 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, trace_ipc_request("set mixer volume", volume); + if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) + return -EINVAL; + /* set both at same time ? */ - if (channel == 2) { + if (channel == SST_HSW_CHANNELS_ALL) { if (hsw->mute[0] && hsw->mute[1]) { hsw->mute_volume[0] = hsw->mute_volume[1] = volume; return 0; @@ -1148,7 +1165,7 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, else if (hsw->mute[1]) req.channel = 0; else - req.channel = 0xffffffff; + req.channel = SST_HSW_CHANNELS_ALL; } else { /* set only 1 channel */ if (hsw->mute[channel]) { diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index 387511f12d85..138e894ab413 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h @@ -24,6 +24,7 @@ #define SST_HSW_NO_CHANNELS 4 #define SST_HSW_MAX_DX_REGIONS 14 #define SST_HSW_DX_CONTEXT_SIZE (640 * 1024) +#define SST_HSW_CHANNELS_ALL 0xffffffff #define SST_HSW_FW_LOG_CONFIG_DWORDS 12 #define SST_HSW_GLOBAL_LOG 15 diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index e7a3b6af87ba..13c01002994e 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -189,7 +189,8 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, if (ucontrol->value.integer.value[0] == ucontrol->value.integer.value[1]) { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); - sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume); + /* apply volume value to all channels */ + sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, SST_HSW_CHANNELS_ALL, volume); } else { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume); @@ -255,7 +256,7 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[1]) { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); - sst_hsw_mixer_set_volume(hsw, 0, 2, volume); + sst_hsw_mixer_set_volume(hsw, 0, SST_HSW_CHANNELS_ALL, volume); } else { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); @@ -525,7 +526,15 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); return ret; } - pcm_data->allocated = true; + + if (!pcm_data->allocated) { + /* Set previous saved volume */ + sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, + 0, pcm_data->volume[0]); + sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, + 1, pcm_data->volume[1]); + pcm_data->allocated = true; + } ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); if (ret < 0) @@ -632,12 +641,6 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream) return -EINVAL; } - /* Set previous saved volume */ - sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, - 0, pcm_data->volume[0]); - sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, - 1, pcm_data->volume[1]); - mutex_unlock(&pcm_data->mutex); return 0; } -- GitLab From 6f9d54fd6e0125b17fb286e1e54e934dd11f60d3 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 25 Nov 2014 15:16:38 +0200 Subject: [PATCH 6405/9457] amdkfd: Fix memory leak of mqds on dqm fini The mqds array members are not freed when dqm is uninitialized. Reviewed-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 904eb38e3b9f..924e90c072e5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -575,11 +575,15 @@ static int initialize_nocpsch(struct device_queue_manager *dqm) static void uninitialize_nocpsch(struct device_queue_manager *dqm) { + int i; + BUG_ON(!dqm); BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0); kfree(dqm->allocated_queues); + for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++) + kfree(dqm->mqds[i]); mutex_destroy(&dqm->lock); kfd2kgd->free_mem(dqm->dev->kgd, (struct kgd_mem *) dqm->pipeline_mem); -- GitLab From 93b0f3eeebdce6f32417187b5d24ea218a3e7fb4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 25 Nov 2014 13:16:12 +0100 Subject: [PATCH 6406/9457] ASoC: core: add multi-codec support in DT This patch exports a core function which handles the DT description of multi-codec links (as: "sound-dai = <&hdmi 0>, <&spdif_codec>;") and creates a CODEC component array in the DAI link. Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- include/sound/soc.h | 3 ++ sound/soc/soc-core.c | 110 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7ba7130037a0..2750e6ad0128 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1451,6 +1451,9 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, struct device_node **framemaster); int snd_soc_of_get_dai_name(struct device_node *of_node, const char **dai_name); +int snd_soc_of_get_dai_link_codecs(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link); #include diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c8f8a23a0e9..72a3ad047048 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4750,36 +4750,30 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); -int snd_soc_of_get_dai_name(struct device_node *of_node, - const char **dai_name) +static int snd_soc_get_dai_name(struct of_phandle_args *args, + const char **dai_name) { struct snd_soc_component *pos; - struct of_phandle_args args; - int ret; - - ret = of_parse_phandle_with_args(of_node, "sound-dai", - "#sound-dai-cells", 0, &args); - if (ret) - return ret; - - ret = -EPROBE_DEFER; + int ret = -EPROBE_DEFER; mutex_lock(&client_mutex); list_for_each_entry(pos, &component_list, list) { - if (pos->dev->of_node != args.np) + if (pos->dev->of_node != args->np) continue; if (pos->driver->of_xlate_dai_name) { - ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name); + ret = pos->driver->of_xlate_dai_name(pos, + args, + dai_name); } else { int id = -1; - switch (args.args_count) { + switch (args->args_count) { case 0: id = 0; /* same as dai_drv[0] */ break; case 1: - id = args.args[0]; + id = args->args[0]; break; default: /* not supported */ @@ -4801,6 +4795,21 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, break; } mutex_unlock(&client_mutex); + return ret; +} + +int snd_soc_of_get_dai_name(struct device_node *of_node, + const char **dai_name) +{ + struct of_phandle_args args; + int ret; + + ret = of_parse_phandle_with_args(of_node, "sound-dai", + "#sound-dai-cells", 0, &args); + if (ret) + return ret; + + ret = snd_soc_get_dai_name(&args, dai_name); of_node_put(args.np); @@ -4808,6 +4817,77 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, } EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name); +/* + * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree + * @dev: Card device + * @of_node: Device node + * @dai_link: DAI link + * + * Builds an array of CODEC DAI components from the DAI link property + * 'sound-dai'. + * The array is set in the DAI link and the number of DAIs is set accordingly. + * The device nodes in the array (of_node) must be dereferenced by the caller. + * + * Returns 0 for success + */ +int snd_soc_of_get_dai_link_codecs(struct device *dev, + struct device_node *of_node, + struct snd_soc_dai_link *dai_link) +{ + struct of_phandle_args args; + struct snd_soc_dai_link_component *component; + char *name; + int index, num_codecs, ret; + + /* Count the number of CODECs */ + name = "sound-dai"; + num_codecs = of_count_phandle_with_args(of_node, name, + "#sound-dai-cells"); + if (num_codecs <= 0) { + if (num_codecs == -ENOENT) + dev_err(dev, "No 'sound-dai' property\n"); + else + dev_err(dev, "Bad phandle in 'sound-dai'\n"); + return num_codecs; + } + component = devm_kzalloc(dev, + sizeof *component * num_codecs, + GFP_KERNEL); + if (!component) + return -ENOMEM; + dai_link->codecs = component; + dai_link->num_codecs = num_codecs; + + /* Parse the list */ + for (index = 0, component = dai_link->codecs; + index < dai_link->num_codecs; + index++, component++) { + ret = of_parse_phandle_with_args(of_node, name, + "#sound-dai-cells", + index, &args); + if (ret) + goto err; + component->of_node = args.np; + ret = snd_soc_get_dai_name(&args, &component->dai_name); + if (ret < 0) + goto err; + } + return 0; +err: + for (index = 0, component = dai_link->codecs; + index < dai_link->num_codecs; + index++, component++) { + if (!component->of_node) + break; + of_node_put(component->of_node); + component->of_node = NULL; + } + dai_link->codecs = NULL; + dai_link->num_codecs = 0; + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs); + static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS -- GitLab From 7195d920bd6094f6810e20a903027cd438bc6d8e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 25 Nov 2014 13:22:45 +0100 Subject: [PATCH 6407/9457] ASoC: simple-card: Remove useless function argument The device node pointer 'cpu' is not used in the function asoc_simple_card_parse_daifmt(). Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 3e3fec4e5c4e..ece22d55ba82 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -232,7 +232,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np, static int asoc_simple_card_parse_daifmt(struct device_node *node, struct simple_card_data *priv, - struct device_node *cpu, struct device_node *codec, char *prefix, int idx) { @@ -309,7 +308,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, } ret = asoc_simple_card_parse_daifmt(node, priv, - cpu, codec, prefix, idx); + codec, prefix, idx); if (ret < 0) goto dai_link_of_err; -- GitLab From 084b6e7c7607bbeb28544da659c3f5981a4689b0 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 30 Oct 2014 16:52:31 +0800 Subject: [PATCH 6408/9457] btrfs: Fix a lockdep warning when running xfstest. The following lockdep warning is triggered during xfstests: [ 1702.980872] ========================================================= [ 1702.981181] [ INFO: possible irq lock inversion dependency detected ] [ 1702.981482] 3.18.0-rc1 #27 Not tainted [ 1702.981781] --------------------------------------------------------- [ 1702.982095] kswapd0/77 just changed the state of lock: [ 1702.982415] (&delayed_node->mutex){+.+.-.}, at: [] __btrfs_release_delayed_node+0x41/0x1f0 [btrfs] [ 1702.982794] but this lock took another, RECLAIM_FS-unsafe lock in the past: [ 1702.983160] (&fs_info->dev_replace.lock){+.+.+.} and interrupts could create inverse lock ordering between them. [ 1702.984675] other info that might help us debug this: [ 1702.985524] Chain exists of: &delayed_node->mutex --> &found->groups_sem --> &fs_info->dev_replace.lock [ 1702.986799] Possible interrupt unsafe locking scenario: [ 1702.987681] CPU0 CPU1 [ 1702.988137] ---- ---- [ 1702.988598] lock(&fs_info->dev_replace.lock); [ 1702.989069] local_irq_disable(); [ 1702.989534] lock(&delayed_node->mutex); [ 1702.990038] lock(&found->groups_sem); [ 1702.990494] [ 1702.990938] lock(&delayed_node->mutex); [ 1702.991407] *** DEADLOCK *** It is because the btrfs_kobj_{add/rm}_device() will call memory allocation with GFP_KERNEL, which may flush fs page cache to free space, waiting for it self to do the commit, causing the deadlock. To solve the problem, move btrfs_kobj_{add/rm}_device() out of the dev_replace lock range, also involing split the btrfs_rm_dev_replace_srcdev() function into remove and free parts. Now only btrfs_rm_dev_replace_remove_srcdev() is called in dev_replace lock range, and kobj_{add/rm} and btrfs_rm_dev_replace_free_srcdev() are called out of the lock range. Signed-off-by: Qu Wenruo Signed-off-by: Chris Mason --- fs/btrfs/dev-replace.c | 11 ++++++----- fs/btrfs/volumes.c | 10 ++++++++-- fs/btrfs/volumes.h | 6 ++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 971c061eb1ce..3fbd0628620b 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -577,15 +577,11 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); fs_info->fs_devices->rw_devices++; - /* replace the sysfs entry */ - btrfs_kobj_rm_device(fs_info, src_device); - btrfs_kobj_add_device(fs_info, tgt_device); - btrfs_dev_replace_unlock(dev_replace); btrfs_rm_dev_replace_blocked(fs_info); - btrfs_rm_dev_replace_srcdev(fs_info, src_device); + btrfs_rm_dev_replace_remove_srcdev(fs_info, src_device); btrfs_rm_dev_replace_unblocked(fs_info); @@ -600,6 +596,11 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); mutex_unlock(&uuid_mutex); + /* replace the sysfs entry */ + btrfs_kobj_rm_device(fs_info, src_device); + btrfs_kobj_add_device(fs_info, tgt_device); + btrfs_rm_dev_replace_free_srcdev(fs_info, src_device); + /* write back the superblocks */ trans = btrfs_start_transaction(root, 0); if (!IS_ERR(trans)) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d47289c715c8..01920515f90d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1800,8 +1800,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) goto error_brelse; } -void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, - struct btrfs_device *srcdev) +void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, + struct btrfs_device *srcdev) { struct btrfs_fs_devices *fs_devices; @@ -1829,6 +1829,12 @@ void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, if (srcdev->bdev) fs_devices->open_devices--; +} + +void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info, + struct btrfs_device *srcdev) +{ + struct btrfs_fs_devices *fs_devices = srcdev->fs_devices; call_rcu(&srcdev->rcu, free_device); diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 08980fa23039..4cc00e64427e 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -448,8 +448,10 @@ void btrfs_init_devices_late(struct btrfs_fs_info *fs_info); int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info); int btrfs_run_dev_stats(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); -void btrfs_rm_dev_replace_srcdev(struct btrfs_fs_info *fs_info, - struct btrfs_device *srcdev); +void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info, + struct btrfs_device *srcdev); +void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info, + struct btrfs_device *srcdev); void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, struct btrfs_device *tgtdev); void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info, -- GitLab From 7d39f9e32c761abaa84bef7c4a4d9349ba8638e0 Mon Sep 17 00:00:00 2001 From: wanghaibin Date: Mon, 17 Nov 2014 09:27:37 +0000 Subject: [PATCH 6409/9457] KVM: ARM: VGIC: Optimize the vGIC vgic_update_irq_pending function. When vgic_update_irq_pending with level-sensitive false, it is need to deactivates an interrupt, and, it can go to out directly. Here return a false value, because it will be not need to kick. Signed-off-by: wanghaibin Signed-off-by: Marc Zyngier --- virt/kvm/arm/vgic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 3aaca49de325..5acf2c93f616 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1646,6 +1646,9 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, } else { vgic_dist_irq_clear_pending(vcpu, irq_num); } + + ret = false; + goto out; } enabled = vgic_irq_is_enabled(vcpu, irq_num); -- GitLab From 07a9748c78cfc39b54f06125a216b67b9c8f09ed Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 10 Nov 2014 08:33:55 +0000 Subject: [PATCH 6410/9457] arm/arm64: kvm: drop inappropriate use of kvm_is_mmio_pfn() Instead of using kvm_is_mmio_pfn() to decide whether a host region should be stage 2 mapped with device attributes, add a new static function kvm_is_device_pfn() that disregards RAM pages with the reserved bit set, as those should usually not be mapped as device memory. Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- arch/arm/kvm/mmu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 57a403a5c22b..b007438242e2 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -834,6 +834,11 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) return kvm_vcpu_dabt_iswrite(vcpu); } +static bool kvm_is_device_pfn(unsigned long pfn) +{ + return !pfn_valid(pfn); +} + static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_memory_slot *memslot, unsigned long hva, unsigned long fault_status) @@ -904,7 +909,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (is_error_pfn(pfn)) return -EFAULT; - if (kvm_is_mmio_pfn(pfn)) + if (kvm_is_device_pfn(pfn)) mem_type = PAGE_S2_DEVICE; spin_lock(&kvm->mmu_lock); -- GitLab From bf4bea8e9a9058319a19f8c2710a6f0ef2459983 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 10 Nov 2014 08:33:56 +0000 Subject: [PATCH 6411/9457] kvm: fix kvm_is_mmio_pfn() and rename to kvm_is_reserved_pfn() This reverts commit 85c8555ff0 ("KVM: check for !is_zero_pfn() in kvm_is_mmio_pfn()") and renames the function to kvm_is_reserved_pfn. The problem being addressed by the patch above was that some ARM code based the memory mapping attributes of a pfn on the return value of kvm_is_mmio_pfn(), whose name indeed suggests that such pfns should be mapped as device memory. However, kvm_is_mmio_pfn() doesn't do quite what it says on the tin, and the existing non-ARM users were already using it in a way which suggests that its name should probably have been 'kvm_is_reserved_pfn' from the beginning, e.g., whether or not to call get_page/put_page on it etc. This means that returning false for the zero page is a mistake and the patch above should be reverted. Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- arch/ia64/kvm/kvm-ia64.c | 2 +- arch/x86/kvm/mmu.c | 6 +++--- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 16 ++++++++-------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index ec6b9acb6bea..dbe46f43884d 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1563,7 +1563,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, for (i = 0; i < npages; i++) { pfn = gfn_to_pfn(kvm, base_gfn + i); - if (!kvm_is_mmio_pfn(pfn)) { + if (!kvm_is_reserved_pfn(pfn)) { kvm_set_pmt_entry(kvm, base_gfn + i, pfn << PAGE_SHIFT, _PAGE_AR_RWX | _PAGE_MA_WB); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ac1c4de3a484..978f402006ee 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -630,7 +630,7 @@ static int mmu_spte_clear_track_bits(u64 *sptep) * kvm mmu, before reclaiming the page, we should * unmap it from mmu first. */ - WARN_ON(!kvm_is_mmio_pfn(pfn) && !page_count(pfn_to_page(pfn))); + WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn))); if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) kvm_set_pfn_accessed(pfn); @@ -2461,7 +2461,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, spte |= PT_PAGE_SIZE_MASK; if (tdp_enabled) spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, - kvm_is_mmio_pfn(pfn)); + kvm_is_reserved_pfn(pfn)); if (host_writable) spte |= SPTE_HOST_WRITEABLE; @@ -2737,7 +2737,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, * PT_PAGE_TABLE_LEVEL and there would be no adjustment done * here. */ - if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn) && + if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) && level == PT_PAGE_TABLE_LEVEL && PageTransCompound(pfn_to_page(pfn)) && !has_wrprotected_page(vcpu->kvm, gfn, PT_DIRECTORY_LEVEL)) { diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ea53b04993f2..a6059bdf7b03 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -703,7 +703,7 @@ void kvm_arch_sync_events(struct kvm *kvm); int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); -bool kvm_is_mmio_pfn(pfn_t pfn); +bool kvm_is_reserved_pfn(pfn_t pfn); struct kvm_irq_ack_notifier { struct hlist_node link; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 25ffac9e947d..3cee7b167052 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -107,10 +107,10 @@ EXPORT_SYMBOL_GPL(kvm_rebooting); static bool largepages_enabled = true; -bool kvm_is_mmio_pfn(pfn_t pfn) +bool kvm_is_reserved_pfn(pfn_t pfn) { if (pfn_valid(pfn)) - return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)); + return PageReserved(pfn_to_page(pfn)); return true; } @@ -1321,7 +1321,7 @@ static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async, else if ((vma->vm_flags & VM_PFNMAP)) { pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - BUG_ON(!kvm_is_mmio_pfn(pfn)); + BUG_ON(!kvm_is_reserved_pfn(pfn)); } else { if (async && vma_is_valid(vma, write_fault)) *async = true; @@ -1427,7 +1427,7 @@ static struct page *kvm_pfn_to_page(pfn_t pfn) if (is_error_noslot_pfn(pfn)) return KVM_ERR_PTR_BAD_PAGE; - if (kvm_is_mmio_pfn(pfn)) { + if (kvm_is_reserved_pfn(pfn)) { WARN_ON(1); return KVM_ERR_PTR_BAD_PAGE; } @@ -1456,7 +1456,7 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean); void kvm_release_pfn_clean(pfn_t pfn) { - if (!is_error_noslot_pfn(pfn) && !kvm_is_mmio_pfn(pfn)) + if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn)) put_page(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_release_pfn_clean); @@ -1477,7 +1477,7 @@ static void kvm_release_pfn_dirty(pfn_t pfn) void kvm_set_pfn_dirty(pfn_t pfn) { - if (!kvm_is_mmio_pfn(pfn)) { + if (!kvm_is_reserved_pfn(pfn)) { struct page *page = pfn_to_page(pfn); if (!PageReserved(page)) SetPageDirty(page); @@ -1487,14 +1487,14 @@ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty); void kvm_set_pfn_accessed(pfn_t pfn) { - if (!kvm_is_mmio_pfn(pfn)) + if (!kvm_is_reserved_pfn(pfn)) mark_page_accessed(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed); void kvm_get_pfn(pfn_t pfn) { - if (!kvm_is_mmio_pfn(pfn)) + if (!kvm_is_reserved_pfn(pfn)) get_page(pfn_to_page(pfn)); } EXPORT_SYMBOL_GPL(kvm_get_pfn); -- GitLab From 1050dcda3052912984b26fb6d2695a3f41792000 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 17 Nov 2014 14:58:51 +0000 Subject: [PATCH 6412/9457] kvm: add a memslot flag for incoherent memory regions Memory regions may be incoherent with the caches, typically when the guest has mapped a host system RAM backed memory region as uncached. Add a flag KVM_MEMSLOT_INCOHERENT so that we can tag these memslots and handle them appropriately when mapping them. Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- include/linux/kvm_host.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a6059bdf7b03..e4d8f705fecd 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -43,6 +43,7 @@ * include/linux/kvm_h. */ #define KVM_MEMSLOT_INVALID (1UL << 16) +#define KVM_MEMSLOT_INCOHERENT (1UL << 17) /* Two fragments for cross MMIO pages. */ #define KVM_MAX_MMIO_FRAGMENTS 2 -- GitLab From 840f4bfbe03f1ce94ade8fdf84e8cd925ef15a48 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 17 Nov 2014 14:58:52 +0000 Subject: [PATCH 6413/9457] arm, arm64: KVM: allow forced dcache flush on page faults To allow handling of incoherent memslots in a subsequent patch, this patch adds a paramater 'ipa_uncached' to cache_coherent_guest_page() so that we can instruct it to flush the page's contents to DRAM even if the guest has caching globally enabled. Signed-off-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- arch/arm/include/asm/kvm_mmu.h | 5 +++-- arch/arm/kvm/mmu.c | 9 +++++++-- arch/arm64/include/asm/kvm_mmu.h | 5 +++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index acb0d5712716..f867060035ec 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -161,9 +161,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) } static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, - unsigned long size) + unsigned long size, + bool ipa_uncached) { - if (!vcpu_has_cache_enabled(vcpu)) + if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) kvm_flush_dcache_to_poc((void *)hva, size); /* diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index b007438242e2..cb924c6d56a6 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -852,6 +852,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct vm_area_struct *vma; pfn_t pfn; pgprot_t mem_type = PAGE_S2; + bool fault_ipa_uncached; write_fault = kvm_is_write_fault(vcpu); if (fault_status == FSC_PERM && !write_fault) { @@ -918,6 +919,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (!hugetlb && !force_pte) hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); + fault_ipa_uncached = false; + if (hugetlb) { pmd_t new_pmd = pfn_pmd(pfn, mem_type); new_pmd = pmd_mkhuge(new_pmd); @@ -925,7 +928,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, kvm_set_s2pmd_writable(&new_pmd); kvm_set_pfn_dirty(pfn); } - coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); + coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE, + fault_ipa_uncached); ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); } else { pte_t new_pte = pfn_pte(pfn, mem_type); @@ -933,7 +937,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, kvm_set_s2pte_writable(&new_pte); kvm_set_pfn_dirty(pfn); } - coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); + coherent_cache_guest_page(vcpu, hva, PAGE_SIZE, + fault_ipa_uncached); ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); } diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 0caf7a59f6a1..123b521a9908 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -243,9 +243,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) } static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva, - unsigned long size) + unsigned long size, + bool ipa_uncached) { - if (!vcpu_has_cache_enabled(vcpu)) + if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached) kvm_flush_dcache_to_poc((void *)hva, size); if (!icache_is_aliasing()) { /* PIPT */ -- GitLab From 849260c72c6b8bd53850cb00b80027db3a273c2c Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 17 Nov 2014 14:58:53 +0000 Subject: [PATCH 6414/9457] arm, arm64: KVM: handle potential incoherency of readonly memslots Readonly memslots are often used to implement emulation of ROMs and NOR flashes, in which case the guest may legally map these regions as uncached. To deal with the incoherency associated with uncached guest mappings, treat all readonly memslots as incoherent, and ensure that pages that belong to regions tagged as such are flushed to DRAM before being passed to the guest. Signed-off-by: Ard Biesheuvel Signed-off-by: Marc Zyngier --- arch/arm/kvm/mmu.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index cb924c6d56a6..f2a9874ff5cb 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -919,7 +919,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (!hugetlb && !force_pte) hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); - fault_ipa_uncached = false; + fault_ipa_uncached = memslot->flags & KVM_MEMSLOT_INCOHERENT; if (hugetlb) { pmd_t new_pmd = pfn_pmd(pfn, mem_type); @@ -1298,11 +1298,12 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, hva = vm_end; } while (hva < reg_end); - if (ret) { - spin_lock(&kvm->mmu_lock); + spin_lock(&kvm->mmu_lock); + if (ret) unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); - spin_unlock(&kvm->mmu_lock); - } + else + stage2_flush_memslot(kvm, memslot); + spin_unlock(&kvm->mmu_lock); return ret; } @@ -1314,6 +1315,15 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, unsigned long npages) { + /* + * Readonly memslots are not incoherent with the caches by definition, + * but in practice, they are used mostly to emulate ROMs or NOR flashes + * that the guest may consider devices and hence map as uncached. + * To prevent incoherency issues in these cases, tag all readonly + * regions as incoherent. + */ + if (slot->flags & KVM_MEM_READONLY) + slot->flags |= KVM_MEMSLOT_INCOHERENT; return 0; } -- GitLab From 5100f9833e1881c800bc088e70afa4b9a1409f51 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 6 Nov 2014 12:11:45 +0000 Subject: [PATCH 6415/9457] arm/arm64: KVM: avoid unnecessary guest register mangling on MMIO read Currently we mangle the endianness of the guest's register even on an MMIO _read_, where it is completely useless, because we will not use the value of that register. Rework the io_mem_abort() function to clearly separate between reads and writes and only do the endianness mangling on MMIO writes. Signed-off-by: Andre Przywara Signed-off-by: Marc Zyngier --- arch/arm/kvm/mmio.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 4cb5a93182e9..5d3bfc0eb3f0 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c @@ -187,15 +187,18 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, } rt = vcpu->arch.mmio_decode.rt; - data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), mmio.len); - trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE : - KVM_TRACE_MMIO_READ_UNSATISFIED, - mmio.len, fault_ipa, - (mmio.is_write) ? data : 0); + if (mmio.is_write) { + data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), + mmio.len); - if (mmio.is_write) + trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, mmio.len, + fault_ipa, data); mmio_write_buf(mmio.data, mmio.len, data); + } else { + trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, mmio.len, + fault_ipa, 0); + } if (vgic_handle_mmio(vcpu, run, &mmio)) return 1; -- GitLab From b1e952b4e484ebc9ffad674c361d261a1af02a13 Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Mon, 24 Nov 2014 10:41:56 +0100 Subject: [PATCH 6416/9457] arm/arm64: vgic: Remove unreachable irq_clear_pending When 'injecting' an edge-triggered interrupt with a falling edge we shouldn't clear the pending state on the distributor. In fact, we don't, because the check in vgic_validate_injection would prevent us from ever reaching this bit of code. Remove the unreachable snippet. Signed-off-by: Christoffer Dall Signed-off-by: Marc Zyngier --- virt/kvm/arm/vgic.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 5acf2c93f616..631a472e41cf 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1643,8 +1643,6 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, vgic_dist_irq_clear_level(vcpu, irq_num); if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) vgic_dist_irq_clear_pending(vcpu, irq_num); - } else { - vgic_dist_irq_clear_pending(vcpu, irq_num); } ret = false; -- GitLab From 8f608de699ec3dd0618795c42734e5db3b20353d Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 25 Nov 2014 05:58:23 -0800 Subject: [PATCH 6417/9457] Btrfs: include vmalloc.h in check-integrity.c Fengguang's build monster reported warnings on some arches because we don't have vmalloc.h included Signed-off-by: Chris Mason Reported-by: fengguang.wu@intel.com --- fs/btrfs/check-integrity.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 47cb267b8ac7..d897ef803b3b 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -94,6 +94,7 @@ #include #include #include +#include #include "ctree.h" #include "disk-io.h" #include "hash.h" -- GitLab From 5ed0cf8800c4da58e1e501f7143154897d34e9c2 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 19:20:51 -0300 Subject: [PATCH 6418/9457] [media] m88ds3103: One function call less in m88ds3103_init() after error detection GIT_AUTHOR_DATE=1416472158 The release_firmware() function was called in some cases by the m88ds3103_init() function during error handling even if the passed variable contained still a null pointer. This implementation detail could be improved by the introduction of another jump label. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/m88ds3103.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 843e669a3d7c..ba4ee0b48834 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -640,7 +640,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) ret = m88ds3103_wr_reg(priv, 0xb2, 0x01); if (ret) - goto err; + goto error_fw_release; for (remaining = fw->size; remaining > 0; remaining -= (priv->cfg->i2c_wr_max - 1)) { @@ -654,13 +654,13 @@ static int m88ds3103_init(struct dvb_frontend *fe) dev_err(&priv->i2c->dev, "%s: firmware download failed=%d\n", KBUILD_MODNAME, ret); - goto err; + goto error_fw_release; } } ret = m88ds3103_wr_reg(priv, 0xb2, 0x00); if (ret) - goto err; + goto error_fw_release; release_firmware(fw); fw = NULL; @@ -686,9 +686,10 @@ static int m88ds3103_init(struct dvb_frontend *fe) priv->warm = true; return 0; -err: - release_firmware(fw); +error_fw_release: + release_firmware(fw); +err: dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); return ret; } -- GitLab From 034e1ec0ce299b9e90056793dcb3187e7add6b62 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 19 Nov 2014 19:23:15 -0300 Subject: [PATCH 6419/9457] [media] si2168: One function call less in si2168_init() after error detection GIT_AUTHOR_DATE=1416472767 The release_firmware() function was called in some cases by the si2168_init() function during error handling even if the passed variable contained still a null pointer. This implementation detail could be improved by the introduction of another jump label. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/si2168.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 34206f3fe497..bec3aa5ed0a0 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -455,7 +455,7 @@ static int si2168_init(struct dvb_frontend *fe) dev_err(&s->client->dev, "firmware file '%s' not found\n", fw_file); - goto err; + goto error_fw_release; } } @@ -475,7 +475,7 @@ static int si2168_init(struct dvb_frontend *fe) dev_err(&s->client->dev, "firmware download failed=%d\n", ret); - goto err; + goto error_fw_release; } } @@ -506,9 +506,10 @@ static int si2168_init(struct dvb_frontend *fe) s->active = true; return 0; -err: - release_firmware(fw); +error_fw_release: + release_firmware(fw); +err: dev_dbg(&s->client->dev, "failed=%d\n", ret); return ret; } -- GitLab From b43a590d44d2678dc26c93a02aba88411acd18cf Mon Sep 17 00:00:00 2001 From: Nibble Max Date: Thu, 13 Nov 2014 05:10:41 -0300 Subject: [PATCH 6420/9457] [media] dvb-usb-dvbsky: add T680CI dvb-t2/t/c usb ci box support DVBSky T680CI dvb-t2/t/c usb ci box: 1>dvb frontend: SI2158A20(tuner), SI2168A30(demod) 2>usb controller: CY7C86013A 3>ci controller: CIMAX SP2 or its clone. Signed-off-by: Nibble Max Reviewed-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/Kconfig | 2 + drivers/media/usb/dvb-usb-v2/dvbsky.c | 122 ++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 74230339f62b..0982e734fab5 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -145,7 +145,9 @@ config DVB_USB_DVBSKY tristate "DVBSky USB support" depends on DVB_USB_V2 select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT help Say Y here to support the USB receivers from DVBSky. diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 8be8447fb2be..b6326c6dac13 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -22,6 +22,8 @@ #include "m88ds3103.h" #include "m88ts2022.h" #include "sp2.h" +#include "si2168.h" +#include "si2157.h" #define DVBSKY_MSG_DELAY 0/*2000*/ #define DVBSKY_BUF_LEN 64 @@ -37,6 +39,7 @@ struct dvbsky_state { u8 ibuf[DVBSKY_BUF_LEN]; u8 obuf[DVBSKY_BUF_LEN]; u8 last_lock; + struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; struct i2c_client *i2c_client_ci; @@ -517,6 +520,90 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) return ret; } +static int dvbsky_t680c_attach(struct dvb_usb_adapter *adap) +{ + struct dvbsky_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + int ret = 0; + struct i2c_adapter *i2c_adapter; + struct i2c_client *client_demod, *client_tuner, *client_ci; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + struct sp2_config sp2_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &i2c_adapter; + si2168_config.fe = &adap->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + + request_module(info.type); + client_demod = i2c_new_device(&d->i2c_adap, &info); + if (client_demod == NULL || + client_demod->dev.driver == NULL) + goto fail_demod_device; + if (!try_module_get(client_demod->dev.driver->owner)) + goto fail_demod_module; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = adap->fe[0]; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + + request_module(info.type); + client_tuner = i2c_new_device(i2c_adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) + goto fail_tuner_device; + if (!try_module_get(client_tuner->dev.driver->owner)) + goto fail_tuner_module; + + /* attach ci controller */ + memset(&sp2_config, 0, sizeof(sp2_config)); + sp2_config.dvb_adap = &adap->dvb_adap; + sp2_config.priv = d; + sp2_config.ci_control = dvbsky_ci_ctrl; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "sp2", I2C_NAME_SIZE); + info.addr = 0x40; + info.platform_data = &sp2_config; + + request_module(info.type); + client_ci = i2c_new_device(&d->i2c_adap, &info); + + if (client_ci == NULL || client_ci->dev.driver == NULL) + goto fail_ci_device; + + if (!try_module_get(client_ci->dev.driver->owner)) + goto fail_ci_module; + + state->i2c_client_demod = client_demod; + state->i2c_client_tuner = client_tuner; + state->i2c_client_ci = client_ci; + return ret; +fail_ci_module: + i2c_unregister_device(client_ci); +fail_ci_device: + module_put(client_tuner->dev.driver->owner); +fail_tuner_module: + i2c_unregister_device(client_tuner); +fail_tuner_device: + module_put(client_demod->dev.driver->owner); +fail_demod_module: + i2c_unregister_device(client_demod); +fail_demod_device: + ret = -ENODEV; + return ret; +} + static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name) { dvbsky_gpio_ctrl(d, 0x04, 1); @@ -559,6 +646,12 @@ static void dvbsky_exit(struct dvb_usb_device *d) module_put(client->dev.driver->owner); i2c_unregister_device(client); } + client = state->i2c_client_demod; + /* remove I2C demod */ + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } client = state->i2c_client_ci; /* remove I2C ci */ if (client) { @@ -622,11 +715,40 @@ static struct dvb_usb_device_properties dvbsky_s960c_props = { } }; +static struct dvb_usb_device_properties dvbsky_t680c_props = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct dvbsky_state), + + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY, + + .i2c_algo = &dvbsky_i2c_algo, + .frontend_attach = dvbsky_t680c_attach, + .init = dvbsky_init, + .get_rc_config = dvbsky_get_rc_config, + .streaming_ctrl = dvbsky_streaming_ctrl, + .identify_state = dvbsky_identify_state, + .exit = dvbsky_exit, + .read_mac_address = dvbsky_read_mac_addr, + + .num_adapters = 1, + .adapter = { + { + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096), + } + } +}; + static const struct usb_device_id dvbsky_id_table[] = { { DVB_USB_DEVICE(0x0572, 0x6831, &dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) }, { DVB_USB_DEVICE(0x0572, 0x960c, &dvbsky_s960c_props, "DVBSky S960CI", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(0x0572, 0x680c, + &dvbsky_t680c_props, "DVBSky T680CI", RC_MAP_DVBSKY) }, { } }; MODULE_DEVICE_TABLE(usb, dvbsky_id_table); -- GitLab From 6296f4a8eb86f9abcc370fb7a1a116b8441c17fd Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Maneyrol Date: Thu, 20 Nov 2014 00:46:37 +0800 Subject: [PATCH 6421/9457] HID: i2c-hid: fix race condition reading reports Current driver uses a common buffer for reading reports either synchronously in i2c_hid_get_raw_report() and asynchronously in the interrupt handler. There is race condition if an interrupt arrives immediately after the report is received in i2c_hid_get_raw_report(); the common buffer is modified by the interrupt handler with the new report and then i2c_hid_get_raw_report() proceed using wrong data. Fix it by using a separate buffers for synchronous reports. Signed-off-by: Jean-Baptiste Maneyrol [Antonio Borneo: cleanup, rebase to v3.17, submit mainline] Signed-off-by: Antonio Borneo Reviewed-by: Benjamin Tissoires Cc: stable@vger.kernel.org Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 933bf1052ec0..c66e6acf7152 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -137,6 +137,7 @@ struct i2c_hid { * descriptor. */ unsigned int bufsize; /* i2c buffer size */ char *inbuf; /* Input buffer */ + char *rawbuf; /* Raw Input buffer */ char *cmdbuf; /* Command buffer */ char *argsbuf; /* Command arguments buffer */ @@ -504,9 +505,11 @@ static void i2c_hid_find_max_report(struct hid_device *hid, unsigned int type, static void i2c_hid_free_buffers(struct i2c_hid *ihid) { kfree(ihid->inbuf); + kfree(ihid->rawbuf); kfree(ihid->argsbuf); kfree(ihid->cmdbuf); ihid->inbuf = NULL; + ihid->rawbuf = NULL; ihid->cmdbuf = NULL; ihid->argsbuf = NULL; ihid->bufsize = 0; @@ -522,10 +525,11 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) report_size; /* report */ ihid->inbuf = kzalloc(report_size, GFP_KERNEL); + ihid->rawbuf = kzalloc(report_size, GFP_KERNEL); ihid->argsbuf = kzalloc(args_len, GFP_KERNEL); ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL); - if (!ihid->inbuf || !ihid->argsbuf || !ihid->cmdbuf) { + if (!ihid->inbuf || !ihid->rawbuf || !ihid->argsbuf || !ihid->cmdbuf) { i2c_hid_free_buffers(ihid); return -ENOMEM; } @@ -552,12 +556,12 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, ret = i2c_hid_get_report(client, report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, - report_number, ihid->inbuf, ask_count); + report_number, ihid->rawbuf, ask_count); if (ret < 0) return ret; - ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8); + ret_count = ihid->rawbuf[0] | (ihid->rawbuf[1] << 8); if (ret_count <= 2) return 0; @@ -566,7 +570,7 @@ static int i2c_hid_get_raw_report(struct hid_device *hid, /* The query buffer contains the size, dropping it in the reply */ count = min(count, ret_count - 2); - memcpy(buf, ihid->inbuf + 2, count); + memcpy(buf, ihid->rawbuf + 2, count); return count; } -- GitLab From da10bc252476a8d1d1bdf7b94502ad2cbd7f30b1 Mon Sep 17 00:00:00 2001 From: Mathieu Magnaudet Date: Sat, 22 Nov 2014 12:02:07 +0100 Subject: [PATCH 6422/9457] HID: multitouch: Add quirk for VTL touch panels VTL panels do not switch to the multitouch mode until the input mode feature is read by the host. This should normally be done by usbhid, but it looks like an other bug prevents usbhid to properly retrieve the feature state. As a workaround, we force the reading of the feature in mt_set_input_mode for such devices. Reviewed-by: Benjamin Tissoires Signed-off-by: Mathieu Magnaudet Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-multitouch.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7c863738e419..d6cc6a9cf10f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -931,6 +931,9 @@ #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 #define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 +#define USB_VENDOR_ID_VTL 0x0306 +#define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F 0xff3f + #define USB_VENDOR_ID_WACOM 0x056a #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 51e25b9407f2..683cda6c60ce 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -67,6 +67,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) #define MT_QUIRK_HOVERING (1 << 11) #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) +#define MT_QUIRK_FORCE_GET_FEATURE (1 << 13) #define MT_INPUTMODE_TOUCHSCREEN 0x02 #define MT_INPUTMODE_TOUCHPAD 0x03 @@ -150,6 +151,7 @@ static void mt_post_parse(struct mt_device *td); #define MT_CLS_FLATFROG 0x0107 #define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 +#define MT_CLS_VTL 0x0110 #define MT_DEFAULT_MAXCONTACT 10 #define MT_MAX_MAXCONTACT 250 @@ -255,6 +257,11 @@ static struct mt_class mt_classes[] = { .sn_move = 2048, .maxcontacts = 40, }, + { .name = MT_CLS_VTL, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_FORCE_GET_FEATURE, + }, { } }; @@ -809,6 +816,9 @@ static void mt_set_input_mode(struct hid_device *hdev) struct mt_device *td = hid_get_drvdata(hdev); struct hid_report *r; struct hid_report_enum *re; + struct mt_class *cls = &td->mtclass; + char *buf; + int report_len; if (td->inputmode < 0) return; @@ -816,6 +826,18 @@ static void mt_set_input_mode(struct hid_device *hdev) re = &(hdev->report_enum[HID_FEATURE_REPORT]); r = re->report_id_hash[td->inputmode]; if (r) { + if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) { + report_len = ((r->size - 1) >> 3) + 1 + (r->id > 0); + buf = hid_alloc_report_buf(r, GFP_KERNEL); + if (!buf) { + hid_err(hdev, "failed to allocate buffer for report\n"); + return; + } + hid_hw_raw_request(hdev, r->id, buf, report_len, + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + kfree(buf); + } r->field[0]->value[td->inputmode_index] = td->inputmode_value; hid_hw_request(hdev, r, HID_REQ_SET_REPORT); } @@ -1281,6 +1303,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, + /* VTL panels */ + { .driver_data = MT_CLS_VTL, + MT_USB_DEVICE(USB_VENDOR_ID_VTL, + USB_DEVICE_ID_VTL_MULTITOUCH_FF3F) }, + /* Wistron panels */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_WISTRON, -- GitLab From 344e2e5ed7b3c82ac5f7a7641e4179f3215266b0 Mon Sep 17 00:00:00 2001 From: Nibble Max Date: Sat, 8 Nov 2014 08:35:08 -0300 Subject: [PATCH 6423/9457] [media] smipcie: use add_i2c_client and del_i2c_client functions v2: -no change, just resend with other patches. "add_i2c_client" and "del_i2c_client" functions make code shorter and easy to maintain. Signed-off-by: Nibble Max Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/smipcie/smipcie.c | 69 +++++++++++++++++------------ 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 8dc6afa50edb..39614a47af1e 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -477,6 +477,33 @@ static irqreturn_t smi_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter, + struct i2c_board_info *info) +{ + struct i2c_client *client; + + request_module(info->type); + client = i2c_new_device(adapter, info); + if (client == NULL || client->dev.driver == NULL) + goto err_add_i2c_client; + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + goto err_add_i2c_client; + } + return client; + +err_add_i2c_client: + client = NULL; + return client; +} + +static void smi_del_i2c_client(struct i2c_client *client) +{ + module_put(client->dev.driver->owner); + i2c_unregister_device(client); +} + static const struct m88ds3103_config smi_dvbsky_m88ds3103_cfg = { .i2c_addr = 0x68, .clock = 27000000, @@ -517,18 +544,12 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) strlcpy(tuner_info.type, "m88ts2022", I2C_NAME_SIZE); tuner_info.addr = 0x60; tuner_info.platform_data = &m88ts2022_config; - request_module("m88ts2022"); - tuner_client = i2c_new_device(tuner_i2c_adapter, &tuner_info); - if (tuner_client == NULL || tuner_client->dev.driver == NULL) { + tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info); + if (!tuner_client) { ret = -ENODEV; goto err_tuner_i2c_device; } - if (!try_module_get(tuner_client->dev.driver->owner)) { - ret = -ENODEV; - goto err_tuner_i2c_module; - } - /* delegate signal strength measurement to tuner */ port->fe->ops.read_signal_strength = port->fe->ops.tuner_ops.get_rf_strength; @@ -536,8 +557,6 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) port->i2c_client_tuner = tuner_client; return ret; -err_tuner_i2c_module: - i2c_unregister_device(tuner_client); err_tuner_i2c_device: dvb_frontend_detach(port->fe); return ret; @@ -581,18 +600,12 @@ static int smi_dvbsky_m88rs6000_fe_attach(struct smi_port *port) strlcpy(tuner_info.type, "m88rs6000t", I2C_NAME_SIZE); tuner_info.addr = 0x21; tuner_info.platform_data = &m88rs6000t_config; - request_module("m88rs6000t"); - tuner_client = i2c_new_device(tuner_i2c_adapter, &tuner_info); - if (tuner_client == NULL || tuner_client->dev.driver == NULL) { + tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info); + if (!tuner_client) { ret = -ENODEV; goto err_tuner_i2c_device; } - if (!try_module_get(tuner_client->dev.driver->owner)) { - ret = -ENODEV; - goto err_tuner_i2c_module; - } - /* delegate signal strength measurement to tuner */ port->fe->ops.read_signal_strength = port->fe->ops.tuner_ops.get_rf_strength; @@ -600,8 +613,6 @@ static int smi_dvbsky_m88rs6000_fe_attach(struct smi_port *port) port->i2c_client_tuner = tuner_client; return ret; -err_tuner_i2c_module: - i2c_unregister_device(tuner_client); err_tuner_i2c_device: dvb_frontend_detach(port->fe); return ret; @@ -631,7 +642,10 @@ static int smi_fe_init(struct smi_port *port) /* register dvb frontend */ ret = dvb_register_frontend(adap, port->fe); if (ret < 0) { - i2c_unregister_device(port->i2c_client_tuner); + if (port->i2c_client_tuner) + smi_del_i2c_client(port->i2c_client_tuner); + if (port->i2c_client_demod) + smi_del_i2c_client(port->i2c_client_demod); dvb_frontend_detach(port->fe); return ret; } @@ -645,15 +659,12 @@ static int smi_fe_init(struct smi_port *port) static void smi_fe_exit(struct smi_port *port) { - struct i2c_client *tuner_client; - dvb_unregister_frontend(port->fe); - /* remove I2C tuner */ - tuner_client = port->i2c_client_tuner; - if (tuner_client) { - module_put(tuner_client->dev.driver->owner); - i2c_unregister_device(tuner_client); - } + /* remove I2C demod and tuner */ + if (port->i2c_client_tuner) + smi_del_i2c_client(port->i2c_client_tuner); + if (port->i2c_client_demod) + smi_del_i2c_client(port->i2c_client_demod); dvb_frontend_detach(port->fe); } -- GitLab From 460c8a7c25fef0712abdeeefd07bf02a8e8cb9e1 Mon Sep 17 00:00:00 2001 From: Nibble Max Date: Sat, 8 Nov 2014 08:35:20 -0300 Subject: [PATCH 6424/9457] [media] smipcie: add DVBSky T9580 V3 support v2: - Update Kconfig file. DVBSky T9580 V3 card is the dual tuner card, which supports S/S2 and T2/T/C. 1>DVB-S/S2 frontend: M88DS3103/M88TS2022 2>DVB-T2/T/C frontend: SI2168B40/SI2157A30 2>PCIe bridge: SMI PCIe Signed-off-by: Nibble Max Reviewed-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/smipcie/Kconfig | 3 ++ drivers/media/pci/smipcie/smipcie.c | 67 +++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig index 57dd124079fc..c8de53f5ea28 100644 --- a/drivers/media/pci/smipcie/Kconfig +++ b/drivers/media/pci/smipcie/Kconfig @@ -3,12 +3,15 @@ config DVB_SMIPCIE depends on DVB_CORE && PCI && I2C select I2C_ALGOBIT select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT help Support for cards with SMI PCIe bridge: - DVBSky S950 V3 - DVBSky S952 V3 + - DVBSky T9580 V3 Say Y or M if you own such a device and want to use it. If unsure say N. diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 39614a47af1e..f773350e67b9 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -18,6 +18,8 @@ #include "m88ds3103.h" #include "m88ts2022.h" #include "m88rs6000t.h" +#include "si2168.h" +#include "si2157.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -618,6 +620,58 @@ static int smi_dvbsky_m88rs6000_fe_attach(struct smi_port *port) return ret; } +static int smi_dvbsky_sit2_fe_attach(struct smi_port *port) +{ + int ret = 0; + struct smi_dev *dev = port->dev; + struct i2c_adapter *i2c; + struct i2c_adapter *tuner_i2c_adapter; + struct i2c_client *client_tuner, *client_demod; + struct i2c_board_info client_info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* select i2c bus */ + i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &tuner_i2c_adapter; + si2168_config.fe = &port->fe; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + + memset(&client_info, 0, sizeof(struct i2c_board_info)); + strlcpy(client_info.type, "si2168", I2C_NAME_SIZE); + client_info.addr = 0x64; + client_info.platform_data = &si2168_config; + + client_demod = smi_add_i2c_client(i2c, &client_info); + if (!client_demod) { + ret = -ENODEV; + return ret; + } + port->i2c_client_demod = client_demod; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = port->fe; + + memset(&client_info, 0, sizeof(struct i2c_board_info)); + strlcpy(client_info.type, "si2157", I2C_NAME_SIZE); + client_info.addr = 0x60; + client_info.platform_data = &si2157_config; + + client_tuner = smi_add_i2c_client(tuner_i2c_adapter, &client_info); + if (!client_tuner) { + smi_del_i2c_client(port->i2c_client_demod); + port->i2c_client_demod = NULL; + ret = -ENODEV; + return ret; + } + port->i2c_client_tuner = client_tuner; + return ret; +} + static int smi_fe_init(struct smi_port *port) { int ret = 0; @@ -635,6 +689,9 @@ static int smi_fe_init(struct smi_port *port) case DVBSKY_FE_M88RS6000: ret = smi_dvbsky_m88rs6000_fe_attach(port); break; + case DVBSKY_FE_SIT2: + ret = smi_dvbsky_sit2_fe_attach(port); + break; } if (ret < 0) return ret; @@ -1005,6 +1062,15 @@ static struct smi_cfg_info dvbsky_s952_cfg = { .fe_1 = DVBSKY_FE_M88RS6000, }; +static struct smi_cfg_info dvbsky_t9580_cfg = { + .type = SMI_DVBSKY_T9580, + .name = "DVBSky T9580 V3", + .ts_0 = SMI_TS_DMA_BOTH, + .ts_1 = SMI_TS_DMA_BOTH, + .fe_0 = DVBSKY_FE_SIT2, + .fe_1 = DVBSKY_FE_M88DS3103, +}; + /* PCI IDs */ #define SMI_ID(_subvend, _subdev, _driverdata) { \ .vendor = SMI_VID, .device = SMI_PID, \ @@ -1014,6 +1080,7 @@ static struct smi_cfg_info dvbsky_s952_cfg = { static const struct pci_device_id smi_id_table[] = { SMI_ID(0x4254, 0x0550, dvbsky_s950_cfg), SMI_ID(0x4254, 0x0552, dvbsky_s952_cfg), + SMI_ID(0x4254, 0x5580, dvbsky_t9580_cfg), {0} }; MODULE_DEVICE_TABLE(pci, smi_id_table); -- GitLab From 23fba80a9b1a36654078e29f4df73f07793154fa Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 24 Nov 2014 08:39:10 -0600 Subject: [PATCH 6425/9457] usb: gadget: udc: lpc32xx: remove unnecessary NULL check debugfs_remove() is safe against NULL pointers, so let's remove the unnecessary NULL check before calling it. Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/lpc32xx_udc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 4be497d39d91..976529631c19 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -582,8 +582,7 @@ static void create_debug_file(struct lpc32xx_udc *udc) static void remove_debug_file(struct lpc32xx_udc *udc) { - if (udc->pde) - debugfs_remove(udc->pde); + debugfs_remove(udc->pde); } #else -- GitLab From 4db9917b641d18d24932ee2ec95b23a1e26c3f7e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 24 Nov 2014 08:40:01 -0600 Subject: [PATCH 6426/9457] usb: gadget: udc: pxa25x: remove unnecessary NULL check debugfs_remove() is safe against NULL pointers, so let's remove the unnecessary NULL check before calling it. Reviewed-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pxa25x_udc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 8664b99f147f..347a05b5afc1 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1134,11 +1134,7 @@ static const struct file_operations debug_fops = { dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ S_IRUGO, NULL, dev, &debug_fops); \ } while (0) -#define remove_debug_files(dev) \ - do { \ - if (dev->debugfs_udc) \ - debugfs_remove(dev->debugfs_udc); \ - } while (0) +#define remove_debug_files(dev) debugfs_remove(dev->debugfs_udc) #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ -- GitLab From da9f3289c74f93b63c5ca741caa4e2d728ccafba Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 19 Nov 2014 12:37:53 -0200 Subject: [PATCH 6427/9457] usb: dwc2: Fix build warning when CONFIG_PM_SLEEP=n Building with bcm2835_defconfig, which has CONFIG_PM_SLEEP=n causes the following build warning: drivers/usb/dwc2/platform.c:227:12: warning: 'dwc2_suspend' defined but not used [-Wunused-function] drivers/usb/dwc2/platform.c:237:12: warning: 'dwc2_resume' defined but not used [-Wunused-function] Annotate these functions with '__maybe_unused' to prevent the warnings. Reported-by: Olof's autobuilder Signed-off-by: Fabio Estevam Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ec5658ac52ba..6a795aa2ff05 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -226,7 +226,7 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } -static int dwc2_suspend(struct device *dev) +static int __maybe_unused dwc2_suspend(struct device *dev) { struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; @@ -236,7 +236,7 @@ static int dwc2_suspend(struct device *dev) return ret; } -static int dwc2_resume(struct device *dev) +static int __maybe_unused dwc2_resume(struct device *dev) { struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; -- GitLab From f415fbd17f0438913339fd043779f306ee3587b0 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 24 Nov 2014 11:02:11 -0600 Subject: [PATCH 6428/9457] usb: dwc2: remove early return on clock query Since we have assigned clk=NULL, which is a valid clk, we should not be returning when a clock node is not provide. Instead, we should return only when we cannot enable the clock. Signed-off-by: Dinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 05b05221d677..407f55cf83aa 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3451,8 +3451,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->clk = devm_clk_get(dev, "otg"); if (IS_ERR(hsotg->clk)) { hsotg->clk = NULL; - dev_err(dev, "cannot get otg clock\n"); - return PTR_ERR(hsotg->clk); + dev_dbg(dev, "cannot get otg clock\n"); } hsotg->gadget.max_speed = USB_SPEED_HIGH; @@ -3461,7 +3460,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* reset the system */ - clk_prepare_enable(hsotg->clk); + ret = clk_prepare_enable(hsotg->clk); + if (ret) { + dev_err(dev, "failed to enable otg clk\n"); + goto err_clk; + } + /* regulators */ -- GitLab From b20f3f9e8e537ee25bfb86940903cba4b5abbde6 Mon Sep 17 00:00:00 2001 From: Kiran Raparthy Date: Mon, 24 Nov 2014 22:54:59 +0530 Subject: [PATCH 6429/9457] usb: phy: Handle per-PHY event for connnect and disconnect events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When usb is connected and enumerated in device mode or when usb is disconnected, call usb_phy_set_event() from phy drivers to handle per-PHY event. [ toddpoynor@google.com : Original patch in Android ] Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: Android Kernel Team Cc: John Stultz Cc: Sumit Semwal Cc: Arve Hjønnevåg Cc: Benoit Goby Cc: Todd Poynor Signed-off-by: Kiran Raparthy Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-ab8500-usb.c | 15 +++++++++++++++ drivers/usb/phy/phy-gpio-vbus-usb.c | 2 ++ drivers/usb/phy/phy-mv-usb.c | 2 ++ drivers/usb/phy/phy-tahvo.c | 2 ++ 4 files changed, 21 insertions(+) diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 30c96f08308b..8cd7d193c2ca 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -445,6 +445,7 @@ static int ab9540_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_NONE; /* Fallback to default B_IDLE as nothing is connected. */ ab->phy.otg->state = OTG_STATE_B_IDLE; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); break; case USB_LINK_ACA_RID_C_NM_9540: @@ -459,12 +460,14 @@ static int ab9540_usb_link_status_update(struct ab8500_usb *ab, ab8500_usb_peri_phy_en(ab); atomic_notifier_call_chain(&ab->phy.notifier, UX500_MUSB_PREPARE, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); } if (ab->mode == USB_IDLE) { ab->mode = USB_PERIPHERAL; ab8500_usb_peri_phy_en(ab); atomic_notifier_call_chain(&ab->phy.notifier, UX500_MUSB_PREPARE, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); } if (event != UX500_MUSB_RIDC) event = UX500_MUSB_VBUS; @@ -500,6 +503,7 @@ static int ab9540_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_CHARGER; atomic_notifier_call_chain(&ab->phy.notifier, event, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); break; case USB_LINK_PHYEN_NO_VBUS_NO_IDGND_9540: @@ -524,6 +528,7 @@ static int ab9540_usb_link_status_update(struct ab8500_usb *ab, ab->mode = USB_IDLE; ab->phy.otg->default_a = false; ab->vbus_draw = 0; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); } } break; @@ -583,6 +588,7 @@ static int ab8540_usb_link_status_update(struct ab8500_usb *ab, * is connected */ ab->phy.otg->state = OTG_STATE_B_IDLE; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); break; case USB_LINK_ACA_RID_C_NM_8540: @@ -596,6 +602,7 @@ static int ab8540_usb_link_status_update(struct ab8500_usb *ab, ab8500_usb_peri_phy_en(ab); atomic_notifier_call_chain(&ab->phy.notifier, UX500_MUSB_PREPARE, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); } if (event != UX500_MUSB_RIDC) event = UX500_MUSB_VBUS; @@ -624,6 +631,7 @@ static int ab8540_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_CHARGER; atomic_notifier_call_chain(&ab->phy.notifier, event, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); break; case USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8540: @@ -646,6 +654,7 @@ static int ab8540_usb_link_status_update(struct ab8500_usb *ab, ab->mode = USB_IDLE; ab->phy.otg->default_a = false; ab->vbus_draw = 0; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); } break; @@ -692,6 +701,7 @@ static int ab8505_usb_link_status_update(struct ab8500_usb *ab, * is connected */ ab->phy.otg->state = OTG_STATE_B_IDLE; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); break; case USB_LINK_ACA_RID_C_NM_8505: @@ -705,6 +715,7 @@ static int ab8505_usb_link_status_update(struct ab8500_usb *ab, ab8500_usb_peri_phy_en(ab); atomic_notifier_call_chain(&ab->phy.notifier, UX500_MUSB_PREPARE, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); } if (event != UX500_MUSB_RIDC) event = UX500_MUSB_VBUS; @@ -732,6 +743,7 @@ static int ab8505_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_CHARGER; atomic_notifier_call_chain(&ab->phy.notifier, event, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); break; default: @@ -775,6 +787,7 @@ static int ab8500_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_NONE; /* Fallback to default B_IDLE as nothing is connected */ ab->phy.otg->state = OTG_STATE_B_IDLE; + usb_phy_set_event(&ab->phy, USB_EVENT_NONE); break; case USB_LINK_ACA_RID_C_NM_8500: @@ -792,6 +805,7 @@ static int ab8500_usb_link_status_update(struct ab8500_usb *ab, ab8500_usb_peri_phy_en(ab); atomic_notifier_call_chain(&ab->phy.notifier, UX500_MUSB_PREPARE, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED); } if (event != UX500_MUSB_RIDC) event = UX500_MUSB_VBUS; @@ -818,6 +832,7 @@ static int ab8500_usb_link_status_update(struct ab8500_usb *ab, event = UX500_MUSB_CHARGER; atomic_notifier_call_chain(&ab->phy.notifier, event, &ab->vbus_draw); + usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER); break; case USB_LINK_RESERVED_8500: diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index 9fcf19ba1416..54511725caaf 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -134,6 +134,7 @@ static void gpio_vbus_work(struct work_struct *work) atomic_notifier_call_chain(&gpio_vbus->phy.notifier, status, gpio_vbus->phy.otg->gadget); + usb_phy_set_event(&gpio_vbus->phy, USB_EVENT_ENUMERATED); } else { /* optionally disable D+ pullup */ if (gpio_is_valid(gpio)) @@ -148,6 +149,7 @@ static void gpio_vbus_work(struct work_struct *work) atomic_notifier_call_chain(&gpio_vbus->phy.notifier, status, gpio_vbus->phy.otg->gadget); + usb_phy_set_event(&gpio_vbus->phy, USB_EVENT_NONE); } } diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 81d934fdd0c3..b234d46cd58b 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -441,10 +441,12 @@ static void mv_otg_work(struct work_struct *work) mv_otg_start_periphrals(mvotg, 0); mv_otg_reset(mvotg); mv_otg_disable(mvotg); + usb_phy_set_event(&mvotg->phy, USB_EVENT_NONE); break; case OTG_STATE_B_PERIPHERAL: mv_otg_enable(mvotg); mv_otg_start_periphrals(mvotg, 1); + usb_phy_set_event(&mvotg->phy, USB_EVENT_ENUMERATED); break; case OTG_STATE_A_IDLE: otg->default_a = 1; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index 9cabc1a20d1c..d391c79a542a 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -87,6 +87,7 @@ static void check_vbus_state(struct tahvo_usb *tu) if (tu->phy.otg->gadget) usb_gadget_vbus_connect(tu->phy.otg->gadget); tu->phy.otg->state = OTG_STATE_B_PERIPHERAL; + usb_phy_set_event(&tu->phy, USB_EVENT_ENUMERATED); break; case OTG_STATE_A_IDLE: /* @@ -105,6 +106,7 @@ static void check_vbus_state(struct tahvo_usb *tu) if (tu->phy.otg->gadget) usb_gadget_vbus_disconnect(tu->phy.otg->gadget); tu->phy.otg->state = OTG_STATE_B_IDLE; + usb_phy_set_event(&tu->phy, USB_EVENT_NONE); break; case OTG_STATE_A_HOST: tu->phy.otg->state = OTG_STATE_A_IDLE; -- GitLab From 5450ac88dcf09b258d0404b45316583806799ef4 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:04:59 -0800 Subject: [PATCH 6430/9457] usb: musb: Add function pointers for IO access functions MUSB currently breaks badly if we try to build in support for multiple platforms. This also happens if done as loadable modules, which is not nice for distros. Let's fix the issue by adding new struct musb_io for the IO access functions that the platform code can populate. Note that we don't want to use the current ops as that's really platform_data and and set as a const. This should allow eventually adding function pointers also for the DMA code to struct musb_io, but that's a whole different set of patches. For now, let's just fix the PIO access. Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 40 ++++++++++++++++++++++++++++++++++++ drivers/usb/musb/musb_io.h | 18 ++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 803a997e56d2..e5410bc67df6 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -173,8 +173,25 @@ enum musb_g_ep0_state { /******************************** TYPES *************************************/ +struct musb_io; + /** * struct musb_platform_ops - Operations passed to musb_core by HW glue layer + * @quirks: flags for platform specific quirks + * @enable: enable device + * @disable: disable device + * @ep_offset: returns the end point offset + * @ep_select: selects the specified end point + * @fifo_mode: sets the fifo mode + * @fifo_offset: returns the fifo offset + * @readb: read 8 bits + * @writeb: write 8 bits + * @readw: read 16 bits + * @writew: write 16 bits + * @readl: read 32 bits + * @writel: write 32 bits + * @read_fifo: reads the fifo + * @write_fifo: writes to fifo * @init: turns on clocks, sets up platform-specific registers, etc * @exit: undoes @init * @set_mode: forcefully changes operating mode @@ -184,12 +201,34 @@ enum musb_g_ep0_state { * @adjust_channel_params: pre check for standard dma channel_program func */ struct musb_platform_ops { + +#define MUSB_DMA_UX500 BIT(6) +#define MUSB_DMA_CPPI41 BIT(5) +#define MUSB_DMA_CPPI BIT(4) +#define MUSB_DMA_TUSB_OMAP BIT(3) +#define MUSB_DMA_INVENTRA BIT(2) +#define MUSB_IN_TUSB BIT(1) +#define MUSB_INDEXED_EP BIT(0) + u32 quirks; + int (*init)(struct musb *musb); int (*exit)(struct musb *musb); void (*enable)(struct musb *musb); void (*disable)(struct musb *musb); + u32 (*ep_offset)(u8 epnum, u16 offset); + void (*ep_select)(void __iomem *mbase, u8 epnum); + u16 fifo_mode; + u32 (*fifo_offset)(u8 epnum); + u8 (*readb)(const void __iomem *addr, unsigned offset); + void (*writeb)(void __iomem *addr, unsigned offset, u8 data); + u16 (*readw)(const void __iomem *addr, unsigned offset); + void (*writew)(void __iomem *addr, unsigned offset, u16 data); + u32 (*readl)(const void __iomem *addr, unsigned offset); + void (*writel)(void __iomem *addr, unsigned offset, u32 data); + void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); + void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); int (*set_mode)(struct musb *musb, u8 mode); void (*try_idle)(struct musb *musb, unsigned long timeout); int (*reset)(struct musb *musb); @@ -292,6 +331,7 @@ struct musb { /* device lock */ spinlock_t lock; + struct musb_io io; const struct musb_platform_ops *ops; struct musb_context_registers context; diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index eebeed78edd6..46c01c81a2a6 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h @@ -37,6 +37,24 @@ #include +/** + * struct musb_io - IO functions for MUSB + * @quirks: platform specific flags + * @ep_offset: platform specific function to get end point offset + * @ep_select: platform specific function to select end point + * @fifo_offset: platform specific function to get fifo offset + * @read_fifo: platform specific function to read fifo + * @write_fifo: platform specific function to write fifo + */ +struct musb_io { + u32 quirks; + u32 (*ep_offset)(u8 epnum, u16 offset); + void (*ep_select)(void __iomem *mbase, u8 epnum); + u32 (*fifo_offset)(u8 epnum); + void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); + void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); +}; + #ifndef CONFIG_BLACKFIN /* NOTE: these offsets are all in bytes */ -- GitLab From 9d506fc6d2cdafdec5ce605036f5eeec9fd59657 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:00 -0800 Subject: [PATCH 6431/9457] usb: musb: Populate new IO functions for tusb6010 Let's populate the new IO functions for tusb6010 but not use them yet. Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.c | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 69ca92d6032f..42e0cf9b170f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -126,6 +126,41 @@ static void tusb_wbus_quirk(struct musb *musb, int enabled) } } +static u32 tusb_fifo_offset(u8 epnum) +{ + return 0x200 + (epnum * 0x20); +} + +/* + * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. + */ +static u8 tusb_readb(const void __iomem *addr, unsigned offset) +{ + u16 tmp; + u8 val; + + tmp = __raw_readw(addr + (offset & ~1)); + if (offset & 1) + val = (tmp >> 8); + else + val = tmp & 0xff; + + return val; +} + +static void tusb_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + u16 tmp; + + tmp = __raw_readw(addr + (offset & ~1)); + if (offset & 1) + tmp = (data << 8) | (tmp & 0xff); + else + tmp = (tmp & 0xff00) | data; + + __raw_writew(tmp, addr + (offset & ~1)); +} + /* * TUSB 6010 may use a parallel bus that doesn't support byte ops; * so both loading and unloading FIFOs need explicit byte counts. @@ -1135,9 +1170,15 @@ static int tusb_musb_exit(struct musb *musb) } static const struct musb_platform_ops tusb_ops = { + .quirks = MUSB_IN_TUSB, .init = tusb_musb_init, .exit = tusb_musb_exit, + .fifo_offset = tusb_fifo_offset, + .readb = tusb_readb, + .writeb = tusb_writeb, + .read_fifo = musb_read_fifo, + .write_fifo = musb_write_fifo, .enable = tusb_musb_enable, .disable = tusb_musb_disable, -- GitLab From cc92f6818f6e771d02ab5025262760d1a21aae95 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:01 -0800 Subject: [PATCH 6432/9457] usb: musb: Populate new IO functions for blackfin Populate new IO functions for blackfin Cc: Bryan Wu Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/blackfin.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index f23ce40b4d64..ed1524a40642 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -33,6 +33,41 @@ struct bfin_glue { }; #define glue_to_musb(g) platform_get_drvdata(g->musb) +static u32 bfin_fifo_offset(u8 epnum) +{ + return USB_OFFSET(USB_EP0_FIFO) + (epnum * 8); +} + +static u8 bfin_readb(const void __iomem *addr, unsigned offset) +{ + return (u8)(bfin_read16(addr + offset)); +} + +static u16 bfin_readw(const void __iomem *addr, unsigned offset) +{ + return bfin_read16(addr + offset); +} + +static u32 bfin_readl(const void __iomem *addr, unsigned offset) +{ + return (u32)(bfin_read16(addr + offset)); +} + +static void bfin_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + bfin_write16(addr + offset, (u16)data); +} + +static void bfin_writew(void __iomem *addr, unsigned offset, u16 data) +{ + bfin_write16(addr + offset, data); +} + +static void binf_writel(void __iomem *addr, unsigned offset, u32 data) +{ + bfin_write16(addr + offset, (u16)data); +} + /* * Load an endpoint's FIFO */ @@ -433,6 +468,14 @@ static const struct musb_platform_ops bfin_ops = { .init = bfin_musb_init, .exit = bfin_musb_exit, + .readb = bfin_readb, + .writeb = bfin_writeb, + .readw = bfin_readw, + .writew = bfin_writew, + .readl = bfin_readl, + .writel = bfin_writel, + .read_fifo = musb_read_fifo, + .write_fifo = musb_write_fifo, .enable = bfin_musb_enable, .disable = bfin_musb_disable, -- GitLab From 1b40fc57a517878cf4c2e16ce29cc9a066dc1064 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:02 -0800 Subject: [PATCH 6433/9457] usb: musb: Change to use new IO access Change to use new IO access. This allows us to build in multiple MUSB glue layers. [ balbi@ti.com : switch to EXPORT_SYMBOL_GPL() fix long lines ] Cc: Fabio Baltieri Cc: Lee Jones Cc: Linus Walleij Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 3 +- drivers/usb/musb/blackfin.c | 8 +- drivers/usb/musb/musb_core.c | 143 +++++++++++++++++++++++++++++++---- drivers/usb/musb/musb_io.h | 88 ++------------------- drivers/usb/musb/musb_regs.h | 12 --- drivers/usb/musb/tusb6010.c | 8 +- drivers/usb/musb/ux500_dma.c | 4 +- 7 files changed, 146 insertions(+), 120 deletions(-) diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index d836a3e1f8ec..7fc8d47ce18e 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -408,7 +408,7 @@ static int am35x_musb_exit(struct musb *musb) } /* AM35x supports only 32bit read operation */ -void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) +static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { void __iomem *fifo = hw_ep->fifo; u32 val; @@ -441,6 +441,7 @@ static const struct musb_platform_ops am35x_ops = { .init = am35x_musb_init, .exit = am35x_musb_exit, + .read_fifo = am35x_read_fifo, .enable = am35x_musb_enable, .disable = am35x_musb_disable, diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index ed1524a40642..77f9f5535a88 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -71,7 +71,7 @@ static void binf_writel(void __iomem *addr, unsigned offset, u32 data) /* * Load an endpoint's FIFO */ -void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) +static void bfin_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) { struct musb *musb = hw_ep->musb; void __iomem *fifo = hw_ep->fifo; @@ -135,7 +135,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) /* * Unload an endpoint's FIFO */ -void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) +static void bfin_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { struct musb *musb = hw_ep->musb; void __iomem *fifo = hw_ep->fifo; @@ -474,8 +474,8 @@ static const struct musb_platform_ops bfin_ops = { .writew = bfin_writew, .readl = bfin_readl, .writel = bfin_writel, - .read_fifo = musb_read_fifo, - .write_fifo = musb_write_fifo, + .read_fifo = bfin_read_fifo, + .write_fifo = bfin_write_fifo, .enable = bfin_musb_enable, .disable = bfin_musb_disable, diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 5257928425ce..1c1a9a12fdc7 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -224,12 +224,46 @@ static struct usb_phy_io_ops musb_ulpi_access = { /*-------------------------------------------------------------------------*/ -#if !defined(CONFIG_USB_MUSB_TUSB6010) && !defined(CONFIG_USB_MUSB_BLACKFIN) +static u32 musb_default_fifo_offset(u8 epnum) +{ + return 0x20 + (epnum * 4); +} + +static u8 musb_default_readb(const void __iomem *addr, unsigned offset) +{ + return __raw_readb(addr + offset); +} + +static void musb_default_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + __raw_writeb(data, addr + offset); +} + +static u16 musb_default_readw(const void __iomem *addr, unsigned offset) +{ + return __raw_readw(addr + offset); +} + +static void musb_default_writew(void __iomem *addr, unsigned offset, u16 data) +{ + __raw_writew(data, addr + offset); +} + +static u32 musb_default_readl(const void __iomem *addr, unsigned offset) +{ + return __raw_readl(addr + offset); +} + +static void musb_default_writel(void __iomem *addr, unsigned offset, u32 data) +{ + __raw_writel(data, addr + offset); +} /* * Load an endpoint's FIFO */ -void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) +static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len, + const u8 *src) { struct musb *musb = hw_ep->musb; void __iomem *fifo = hw_ep->fifo; @@ -270,11 +304,10 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) } } -#if !defined(CONFIG_USB_MUSB_AM35X) /* * Unload an endpoint's FIFO */ -void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) +static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) { struct musb *musb = hw_ep->musb; void __iomem *fifo = hw_ep->fifo; @@ -312,10 +345,40 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) ioread8_rep(fifo, dst, len); } } -#endif -#endif /* normal PIO */ +/* + * Old style IO functions + */ +u8 (*musb_readb)(const void __iomem *addr, unsigned offset); +EXPORT_SYMBOL_GPL(musb_readb); + +void (*musb_writeb)(void __iomem *addr, unsigned offset, u8 data); +EXPORT_SYMBOL_GPL(musb_writeb); +u16 (*musb_readw)(const void __iomem *addr, unsigned offset); +EXPORT_SYMBOL_GPL(musb_readw); + +void (*musb_writew)(void __iomem *addr, unsigned offset, u16 data); +EXPORT_SYMBOL_GPL(musb_writew); + +u32 (*musb_readl)(const void __iomem *addr, unsigned offset); +EXPORT_SYMBOL_GPL(musb_readl); + +void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data); +EXPORT_SYMBOL_GPL(musb_writel); + +/* + * New style IO functions + */ +void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) +{ + return hw_ep->musb->io.read_fifo(hw_ep, len, dst); +} + +void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) +{ + return hw_ep->musb->io.write_fifo(hw_ep, len, src); +} /*-------------------------------------------------------------------------*/ @@ -1456,17 +1519,22 @@ static int musb_core_init(u16 musb_type, struct musb *musb) for (i = 0; i < musb->nr_endpoints; i++) { struct musb_hw_ep *hw_ep = musb->endpoints + i; - hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase; + hw_ep->fifo = musb->io.fifo_offset(i) + mbase; #if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE) - hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i); - hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i); - hw_ep->fifo_sync_va = - musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i); - - if (i == 0) - hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF; - else - hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2); + if (musb->io.quirks & MUSB_IN_TUSB) { + hw_ep->fifo_async = musb->async + 0x400 + + musb->io.fifo_offset(i); + hw_ep->fifo_sync = musb->sync + 0x400 + + musb->io.fifo_offset(i); + hw_ep->fifo_sync_va = + musb->sync_va + 0x400 + musb->io.fifo_offset(i); + + if (i == 0) + hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF; + else + hw_ep->conf = mbase + 0x400 + + (((i - 1) & 0xf) << 2); + } #endif hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; @@ -1903,6 +1971,18 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->ops = plat->platform_ops; musb->port_mode = plat->mode; + /* + * Initialize the default IO functions. At least omap2430 needs + * these early. We initialize the platform specific IO functions + * later on. + */ + musb_readb = musb_default_readb; + musb_writeb = musb_default_writeb; + musb_readw = musb_default_readw; + musb_writew = musb_default_writew; + musb_readl = musb_default_readl; + musb_writel = musb_default_writel; + /* The musb_platform_init() call: * - adjusts musb->mregs * - sets the musb->isr @@ -1924,6 +2004,37 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail2; } + if (musb->ops->quirks) + musb->io.quirks = musb->ops->quirks; + + if (musb->ops->fifo_offset) + musb->io.fifo_offset = musb->ops->fifo_offset; + else + musb->io.fifo_offset = musb_default_fifo_offset; + + if (musb->ops->readb) + musb_readb = musb->ops->readb; + if (musb->ops->writeb) + musb_writeb = musb->ops->writeb; + if (musb->ops->readw) + musb_readw = musb->ops->readw; + if (musb->ops->writew) + musb_writew = musb->ops->writew; + if (musb->ops->readl) + musb_readl = musb->ops->readl; + if (musb->ops->writel) + musb_writel = musb->ops->writel; + + if (musb->ops->read_fifo) + musb->io.read_fifo = musb->ops->read_fifo; + else + musb->io.read_fifo = musb_default_read_fifo; + + if (musb->ops->write_fifo) + musb->io.write_fifo = musb->ops->write_fifo; + else + musb->io.write_fifo = musb_default_write_fifo; + if (!musb->xceiv->io_ops) { musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 46c01c81a2a6..14aa21747b0a 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h @@ -55,86 +55,12 @@ struct musb_io { void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); }; -#ifndef CONFIG_BLACKFIN - -/* NOTE: these offsets are all in bytes */ - -static inline u16 musb_readw(const void __iomem *addr, unsigned offset) - { return __raw_readw(addr + offset); } - -static inline u32 musb_readl(const void __iomem *addr, unsigned offset) - { return __raw_readl(addr + offset); } - - -static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) - { __raw_writew(data, addr + offset); } - -static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) - { __raw_writel(data, addr + offset); } - - -#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE) - -/* - * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. - */ -static inline u8 musb_readb(const void __iomem *addr, unsigned offset) -{ - u16 tmp; - u8 val; - - tmp = __raw_readw(addr + (offset & ~1)); - if (offset & 1) - val = (tmp >> 8); - else - val = tmp & 0xff; - - return val; -} - -static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) -{ - u16 tmp; - - tmp = __raw_readw(addr + (offset & ~1)); - if (offset & 1) - tmp = (data << 8) | (tmp & 0xff); - else - tmp = (tmp & 0xff00) | data; - - __raw_writew(tmp, addr + (offset & ~1)); -} - -#else - -static inline u8 musb_readb(const void __iomem *addr, unsigned offset) - { return __raw_readb(addr + offset); } - -static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) - { __raw_writeb(data, addr + offset); } - -#endif /* CONFIG_USB_MUSB_TUSB6010 */ - -#else - -static inline u8 musb_readb(const void __iomem *addr, unsigned offset) - { return (u8) (bfin_read16(addr + offset)); } - -static inline u16 musb_readw(const void __iomem *addr, unsigned offset) - { return bfin_read16(addr + offset); } - -static inline u32 musb_readl(const void __iomem *addr, unsigned offset) - { return (u32) (bfin_read16(addr + offset)); } - -static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) - { bfin_write16(addr + offset, (u16) data); } - -static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) - { bfin_write16(addr + offset, data); } - -static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) - { bfin_write16(addr + offset, (u16) data); } - -#endif /* CONFIG_BLACKFIN */ +/* Do not add new entries here, add them the struct musb_io instead */ +extern u8 (*musb_readb)(const void __iomem *addr, unsigned offset); +extern void (*musb_writeb)(void __iomem *addr, unsigned offset, u8 data); +extern u16 (*musb_readw)(const void __iomem *addr, unsigned offset); +extern void (*musb_writew)(void __iomem *addr, unsigned offset, u16 data); +extern u32 (*musb_readl)(const void __iomem *addr, unsigned offset); +extern void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data); #endif diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 37122a480bc1..b2b1f736392e 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -239,14 +239,6 @@ #define MUSB_INDEX 0x0E /* 8 bit */ #define MUSB_TESTMODE 0x0F /* 8 bit */ -/* Get offset for a given FIFO from musb->mregs */ -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) -#define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) -#else -#define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) -#endif - /* * Additional Control Registers */ @@ -480,10 +472,6 @@ static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) #define MUSB_INDEX USB_OFFSET(USB_INDEX) /* 8 bit */ #define MUSB_TESTMODE USB_OFFSET(USB_TESTMODE)/* 8 bit */ -/* Get offset for a given FIFO from musb->mregs */ -#define MUSB_FIFO_OFFSET(epnum) \ - (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8)) - /* * Additional Control Registers */ diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 42e0cf9b170f..16c4475e640c 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -208,7 +208,7 @@ static inline void tusb_fifo_read_unaligned(void __iomem *fifo, } } -void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) +static void tusb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) { struct musb *musb = hw_ep->musb; void __iomem *ep_conf = hw_ep->conf; @@ -258,7 +258,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf) tusb_fifo_write_unaligned(fifo, buf, len); } -void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) +static void tusb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) { struct musb *musb = hw_ep->musb; void __iomem *ep_conf = hw_ep->conf; @@ -1177,8 +1177,8 @@ static const struct musb_platform_ops tusb_ops = { .fifo_offset = tusb_fifo_offset, .readb = tusb_readb, .writeb = tusb_writeb, - .read_fifo = musb_read_fifo, - .write_fifo = musb_write_fifo, + .read_fifo = tusb_read_fifo, + .write_fifo = tusb_write_fifo, .enable = tusb_musb_enable, .disable = tusb_musb_disable, diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 734dc8408d54..e93845c26bdb 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -91,9 +91,9 @@ static bool ux500_configure_channel(struct dma_channel *channel, struct scatterlist sg; struct dma_slave_config slave_conf; enum dma_slave_buswidth addr_width; - dma_addr_t usb_fifo_addr = (MUSB_FIFO_OFFSET(hw_ep->epnum) + - ux500_channel->controller->phy_base); struct musb *musb = ux500_channel->controller->private_data; + dma_addr_t usb_fifo_addr = (musb->io.fifo_offset(hw_ep->epnum) + + ux500_channel->controller->phy_base); dev_dbg(musb->controller, "packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n", -- GitLab From d026e9c76aac3632af174cf02d5c94defa5e6026 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:03 -0800 Subject: [PATCH 6434/9457] usb: musb: Change end point selection to use new IO access This allows the endpoints to work when multiple MUSB glue layers are built in. Cc: Fabio Baltieri Cc: Lee Jones Cc: Lars-Peter Clausen Acked-by: Linus Walleij Acked-by: Apelete Seketeli Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 1 + drivers/usb/musb/da8xx.c | 1 + drivers/usb/musb/jz4740.c | 1 + drivers/usb/musb/musb_core.c | 38 +++++++++++++++++++++++++++++++++++- drivers/usb/musb/musb_core.h | 37 +---------------------------------- drivers/usb/musb/musb_dsps.c | 1 + drivers/usb/musb/musb_io.h | 2 ++ drivers/usb/musb/musb_regs.h | 11 ----------- drivers/usb/musb/musbhsdma.c | 7 ++++--- drivers/usb/musb/tusb6010.c | 13 ++++++++++++ drivers/usb/musb/ux500.c | 1 + 11 files changed, 62 insertions(+), 51 deletions(-) diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 7fc8d47ce18e..220fd4d3b41c 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -438,6 +438,7 @@ static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) } static const struct musb_platform_ops am35x_ops = { + .quirks = MUSB_INDEXED_EP, .init = am35x_musb_init, .exit = am35x_musb_exit, diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 527c7fe60ece..9a6171300931 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -458,6 +458,7 @@ static int da8xx_musb_exit(struct musb *musb) } static const struct musb_platform_ops da8xx_ops = { + .quirks = MUSB_INDEXED_EP, .init = da8xx_musb_init, .exit = da8xx_musb_exit, diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index d1187290d4e3..40e98747d17f 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -106,6 +106,7 @@ static int jz4740_musb_exit(struct musb *musb) } static const struct musb_platform_ops jz4740_musb_ops = { + .quirks = MUSB_INDEXED_EP, .init = jz4740_musb_init, .exit = jz4740_musb_exit, }; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1c1a9a12fdc7..1ff944a07359 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -229,6 +229,27 @@ static u32 musb_default_fifo_offset(u8 epnum) return 0x20 + (epnum * 4); } +/* "flat" mapping: each endpoint has its own i/o address */ +static void musb_flat_ep_select(void __iomem *mbase, u8 epnum) +{ +} + +static u32 musb_flat_ep_offset(u8 epnum, u16 offset) +{ + return 0x100 + (0x10 * epnum) + offset; +} + +/* "indexed" mapping: INDEX register controls register bank select */ +static void musb_indexed_ep_select(void __iomem *mbase, u8 epnum) +{ + musb_writeb(mbase, MUSB_INDEX, epnum); +} + +static u32 musb_indexed_ep_offset(u8 epnum, u16 offset) +{ + return 0x10 + offset; +} + static u8 musb_default_readb(const void __iomem *addr, unsigned offset) { return __raw_readb(addr + offset); @@ -1537,7 +1558,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) } #endif - hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; + hw_ep->regs = musb->io.ep_offset(i, 0) + mbase; hw_ep->target_regs = musb_read_target_reg_base(i, mbase); hw_ep->rx_reinit = 1; hw_ep->tx_reinit = 1; @@ -2007,6 +2028,21 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (musb->ops->quirks) musb->io.quirks = musb->ops->quirks; + /* At least tusb6010 has it's own offsets.. */ + if (musb->ops->ep_offset) + musb->io.ep_offset = musb->ops->ep_offset; + if (musb->ops->ep_select) + musb->io.ep_select = musb->ops->ep_select; + + /* ..and some devices use indexed offset or flat offset */ + if (musb->io.quirks & MUSB_INDEXED_EP) { + musb->io.ep_offset = musb_indexed_ep_offset; + musb->io.ep_select = musb_indexed_ep_select; + } else { + musb->io.ep_offset = musb_flat_ep_offset; + musb->io.ep_select = musb_flat_ep_select; + } + if (musb->ops->fifo_offset) musb->io.fifo_offset = musb->ops->fifo_offset; else diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index e5410bc67df6..d9248fdd9158 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -124,41 +124,6 @@ enum musb_g_ep0_state { #define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */ #define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */ - -/*************************** REGISTER ACCESS ********************************/ - -/* Endpoint registers (other than dynfifo setup) can be accessed either - * directly with the "flat" model, or after setting up an index register. - */ - -#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_SOC_OMAP2430) \ - || defined(CONFIG_SOC_OMAP3430) || defined(CONFIG_BLACKFIN) \ - || defined(CONFIG_ARCH_OMAP4) -/* REVISIT indexed access seemed to - * misbehave (on DaVinci) for at least peripheral IN ... - */ -#define MUSB_FLAT_REG -#endif - -/* TUSB mapping: "flat" plus ep0 special cases */ -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) -#define musb_ep_select(_mbase, _epnum) \ - musb_writeb((_mbase), MUSB_INDEX, (_epnum)) -#define MUSB_EP_OFFSET MUSB_TUSB_OFFSET - -/* "flat" mapping: each endpoint has its own i/o address */ -#elif defined(MUSB_FLAT_REG) -#define musb_ep_select(_mbase, _epnum) (((void)(_mbase)), ((void)(_epnum))) -#define MUSB_EP_OFFSET MUSB_FLAT_OFFSET - -/* "indexed" mapping: INDEX register controls register bank select */ -#else -#define musb_ep_select(_mbase, _epnum) \ - musb_writeb((_mbase), MUSB_INDEX, (_epnum)) -#define MUSB_EP_OFFSET MUSB_INDEXED_OFFSET -#endif - /****************************** FUNCTIONS ********************************/ #define MUSB_HST_MODE(_musb)\ @@ -515,7 +480,7 @@ static inline int musb_read_fifosize(struct musb *musb, u8 reg = 0; /* read from core using indexed model */ - reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE)); + reg = musb_readb(mbase, musb->io.ep_offset(epnum, MUSB_FIFOSIZE)); /* 0's returned when no more endpoints */ if (!reg) return -ENODEV; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 440333fcf3a7..53bd0e71d19f 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -633,6 +633,7 @@ static int dsps_musb_reset(struct musb *musb) } static struct musb_platform_ops dsps_ops = { + .quirks = MUSB_INDEXED_EP, .init = dsps_musb_init, .exit = dsps_musb_exit, diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 14aa21747b0a..8a57a6f4b3a6 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h @@ -37,6 +37,8 @@ #include +#define musb_ep_select(_mbase, _epnum) musb->io.ep_select((_mbase), (_epnum)) + /** * struct musb_io - IO functions for MUSB * @quirks: platform specific flags diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index b2b1f736392e..92b4c3df9ffa 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -287,19 +287,8 @@ #define MUSB_FIFOSIZE 0x0F #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ -/* Offsets to endpoint registers in indexed model (using INDEX register) */ -#define MUSB_INDEXED_OFFSET(_epnum, _offset) \ - (0x10 + (_offset)) - -/* Offsets to endpoint registers in flat models */ -#define MUSB_FLAT_OFFSET(_epnum, _offset) \ - (0x100 + (0x10*(_epnum)) + (_offset)) - #if defined(CONFIG_USB_MUSB_TUSB6010) || \ defined(CONFIG_USB_MUSB_TUSB6010_MODULE) -/* TUSB6010 EP0 configuration register is special */ -#define MUSB_TUSB_OFFSET(_epnum, _offset) \ - (0x10 + _offset) #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ #endif diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index e8e9f9aab203..ab7ec09a8afe 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -195,6 +195,7 @@ static int dma_channel_abort(struct dma_channel *channel) { struct musb_dma_channel *musb_channel = channel->private_data; void __iomem *mbase = musb_channel->controller->base; + struct musb *musb = musb_channel->controller->private_data; u8 bchannel = musb_channel->idx; int offset; @@ -202,7 +203,7 @@ static int dma_channel_abort(struct dma_channel *channel) if (channel->status == MUSB_DMA_STATUS_BUSY) { if (musb_channel->transmit) { - offset = MUSB_EP_OFFSET(musb_channel->epnum, + offset = musb->io.ep_offset(musb_channel->epnum, MUSB_TXCSR); /* @@ -215,7 +216,7 @@ static int dma_channel_abort(struct dma_channel *channel) csr &= ~MUSB_TXCSR_DMAMODE; musb_writew(mbase, offset, csr); } else { - offset = MUSB_EP_OFFSET(musb_channel->epnum, + offset = musb->io.ep_offset(musb_channel->epnum, MUSB_RXCSR); csr = musb_readw(mbase, offset); @@ -326,7 +327,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) (musb_channel->max_packet_sz - 1))) ) { u8 epnum = musb_channel->epnum; - int offset = MUSB_EP_OFFSET(epnum, + int offset = musb->io.ep_offset(epnum, MUSB_TXCSR); u16 txcsr; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 16c4475e640c..3a5ffd575438 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -131,6 +131,17 @@ static u32 tusb_fifo_offset(u8 epnum) return 0x200 + (epnum * 0x20); } +static u32 tusb_ep_offset(u8 epnum, u16 offset) +{ + return 0x10 + offset; +} + +/* TUSB mapping: "flat" plus ep0 special cases */ +static void tusb_ep_select(void __iomem *mbase, u8 epnum) +{ + musb_writeb(mbase, MUSB_INDEX, epnum); +} + /* * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. */ @@ -1174,6 +1185,8 @@ static const struct musb_platform_ops tusb_ops = { .init = tusb_musb_init, .exit = tusb_musb_exit, + .ep_offset = tusb_ep_offset, + .ep_select = tusb_ep_select, .fifo_offset = tusb_fifo_offset, .readb = tusb_readb, .writeb = tusb_writeb, diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 1d631d5f4a27..06e8b3523a0a 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -188,6 +188,7 @@ static int ux500_musb_exit(struct musb *musb) } static const struct musb_platform_ops ux500_ops = { + .quirks = MUSB_INDEXED_EP, .init = ux500_musb_init, .exit = ux500_musb_exit, -- GitLab From 8a77f05aa39be879535f22a9757e703581fa1392 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:04 -0800 Subject: [PATCH 6435/9457] usb: musb: Pass fifo_mode in platform data This allows setting the correct fifo_mode when multiple MUSB glue layers are built-in. Cc: Fabio Baltieri Cc: Lee Jones Cc: Linus Walleij Cc: Lars-Peter Clausen Acked-by: Apelete Seketeli Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/blackfin.c | 1 + drivers/usb/musb/da8xx.c | 1 + drivers/usb/musb/jz4740.c | 1 + drivers/usb/musb/musb_core.c | 21 ++++++--------------- drivers/usb/musb/ux500.c | 1 + 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 77f9f5535a88..a441a2de8619 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -474,6 +474,7 @@ static const struct musb_platform_ops bfin_ops = { .writew = bfin_writew, .readl = bfin_readl, .writel = bfin_writel, + .fifo_mode = 2, .read_fifo = bfin_read_fifo, .write_fifo = bfin_write_fifo, .enable = bfin_musb_enable, diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 9a6171300931..9a9c82a4d35d 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -462,6 +462,7 @@ static const struct musb_platform_ops da8xx_ops = { .init = da8xx_musb_init, .exit = da8xx_musb_exit, + .fifo_mode = 2, .enable = da8xx_musb_enable, .disable = da8xx_musb_disable, diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 40e98747d17f..bb7b26325a74 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -107,6 +107,7 @@ static int jz4740_musb_exit(struct musb *musb) static const struct musb_platform_ops jz4740_musb_ops = { .quirks = MUSB_INDEXED_EP, + .fifo_mode = 2, .init = jz4740_musb_init, .exit = jz4740_musb_exit, }; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1ff944a07359..1388d99b39e0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1116,21 +1116,7 @@ static void musb_shutdown(struct platform_device *pdev) * We don't currently use dynamic fifo setup capability to do anything * more than selecting one of a bunch of predefined configurations. */ -#if defined(CONFIG_USB_MUSB_TUSB6010) \ - || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) \ - || defined(CONFIG_USB_MUSB_OMAP2PLUS) \ - || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE) \ - || defined(CONFIG_USB_MUSB_AM35X) \ - || defined(CONFIG_USB_MUSB_AM35X_MODULE) \ - || defined(CONFIG_USB_MUSB_DSPS) \ - || defined(CONFIG_USB_MUSB_DSPS_MODULE) -static ushort fifo_mode = 4; -#elif defined(CONFIG_USB_MUSB_UX500) \ - || defined(CONFIG_USB_MUSB_UX500_MODULE) -static ushort fifo_mode = 5; -#else -static ushort fifo_mode = 2; -#endif +static ushort fifo_mode; /* "modprobe ... fifo_mode=1" etc */ module_param(fifo_mode, ushort, 0); @@ -2043,6 +2029,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->io.ep_select = musb_flat_ep_select; } + if (musb->ops->fifo_mode) + fifo_mode = musb->ops->fifo_mode; + else + fifo_mode = 4; + if (musb->ops->fifo_offset) musb->io.fifo_offset = musb->ops->fifo_offset; else diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 06e8b3523a0a..abf72728825f 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -191,6 +191,7 @@ static const struct musb_platform_ops ux500_ops = { .quirks = MUSB_INDEXED_EP, .init = ux500_musb_init, .exit = ux500_musb_exit, + .fifo_mode = 5, .set_vbus = ux500_musb_set_vbus, }; -- GitLab From 82c02f58ba3a1ee0a067c0f90513e826d6152ba6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:05 -0800 Subject: [PATCH 6436/9457] usb: musb: Allow multiple glue layers to be built in There's no reason any longer to keep it as a choice now that the IO access has been fixed. Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 06cc5d6ea681..9d68372dd9aa 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -58,8 +58,7 @@ config USB_MUSB_DUAL_ROLE endchoice -choice - prompt "Platform Glue Layer" +comment "Platform Glue Layer" config USB_MUSB_DAVINCI tristate "DaVinci" @@ -101,8 +100,6 @@ config USB_MUSB_JZ4740 depends on USB_MUSB_GADGET depends on USB_OTG_BLACKLIST_HUB -endchoice - config USB_MUSB_AM335X_CHILD tristate -- GitLab From ebf3992061db1f7b3aa093f37fb308acc74fbc82 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 24 Nov 2014 11:05:06 -0800 Subject: [PATCH 6437/9457] usb: musb: Use IS_ENABLED for tusb6010 This removes the ifdef clutter a bit and saves few lines. It also makes it easier to detect the remaining places where we have conditional building of code done based on if defined for things like DMA. Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_core.h | 9 +++------ drivers/usb/musb/musb_regs.h | 3 --- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 1388d99b39e0..55fe0ff6fd87 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1527,7 +1527,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) struct musb_hw_ep *hw_ep = musb->endpoints + i; hw_ep->fifo = musb->io.fifo_offset(i) + mbase; -#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE) +#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) if (musb->io.quirks & MUSB_IN_TUSB) { hw_ep->fifo_async = musb->async + 0x400 + musb->io.fifo_offset(i); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d9248fdd9158..5e65958f7915 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -216,8 +216,7 @@ struct musb_hw_ep { void __iomem *fifo; void __iomem *regs; -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) void __iomem *conf; #endif @@ -234,8 +233,7 @@ struct musb_hw_ep { struct dma_channel *tx_channel; struct dma_channel *rx_channel; -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) /* TUSB has "asynchronous" and "synchronous" dma modes */ dma_addr_t fifo_async; dma_addr_t fifo_sync; @@ -339,8 +337,7 @@ struct musb { void __iomem *ctrl_base; void __iomem *mregs; -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) dma_addr_t async; dma_addr_t sync; void __iomem *sync_va; diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 92b4c3df9ffa..11f0be07491e 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -287,10 +287,7 @@ #define MUSB_FIFOSIZE 0x0F #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ -#if defined(CONFIG_USB_MUSB_TUSB6010) || \ - defined(CONFIG_USB_MUSB_TUSB6010_MODULE) #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ -#endif #define MUSB_TXCSR_MODE 0x2000 -- GitLab From 9a7a848df1995f05f750b4ed491ac80a459c912f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 14 Nov 2014 19:09:50 -0300 Subject: [PATCH 6438/9457] [media] exynos4-is: fix error handling of irq_of_parse_and_map Return value of irq_of_parse_and_map() is unsigned int, with 0 indicating failure, so testing for negative result never works. Signed-off-by: Dmitry Torokhov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-is.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 22162b2567da..3d49ce03b176 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -814,9 +814,9 @@ static int fimc_is_probe(struct platform_device *pdev) return -ENOMEM; is->irq = irq_of_parse_and_map(dev->of_node, 0); - if (is->irq < 0) { + if (!is->irq) { dev_err(dev, "no irq found\n"); - return is->irq; + return -EINVAL; } ret = fimc_is_get_clocks(is); -- GitLab From 79e886599e6416d0de26e8562e4464577d081c3d Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Wed, 19 Nov 2014 17:13:11 +0100 Subject: [PATCH 6439/9457] crypto: algif - add and use sock_kzfree_s() instead of memzero_explicit() Commit e1bd95bf7c25 ("crypto: algif - zeroize IV buffer") and 2a6af25befd0 ("crypto: algif - zeroize message digest buffer") added memzero_explicit() calls on buffers that are later on passed back to sock_kfree_s(). This is a discussed follow-up that, instead, extends the sock API and adds sock_kzfree_s(), which internally uses kzfree() instead of kfree() for passing the buffers back to slab. Having sock_kzfree_s() allows to keep the changes more minimal by just having a drop-in replacement instead of adding memzero_explicit() calls everywhere before sock_kfree_s(). In kzfree(), the compiler is not allowed to optimize the memset() away and thus there's no need for memzero_explicit(). Both, sock_kfree_s() and sock_kzfree_s() are wrappers for __sock_kfree_s() and call into kfree() resp. kzfree(); here, __sock_kfree_s() needs to be explicitly inlined as we want the compiler to optimize the call and condition away and thus it produces e.g. on x86_64 the _same_ assembler output for sock_kfree_s() before and after, and thus also allows for avoiding code duplication. Cc: David S. Miller Signed-off-by: Daniel Borkmann Signed-off-by: Herbert Xu --- crypto/algif_hash.c | 6 ++---- crypto/algif_skcipher.c | 3 +-- include/net/sock.h | 1 + net/core/sock.c | 24 ++++++++++++++++++++---- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index f75db4ce48bf..e6050396a3b3 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -258,10 +258,8 @@ static void hash_sock_destruct(struct sock *sk) struct alg_sock *ask = alg_sk(sk); struct hash_ctx *ctx = ask->private; - memzero_explicit(ctx->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); - sock_kfree_s(sk, ctx->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); + sock_kzfree_s(sk, ctx->result, + crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); sock_kfree_s(sk, ctx, ctx->len); af_alg_release_parent(sk); } diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 85e3bdbe214c..34389964000d 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -566,8 +566,7 @@ static void skcipher_sock_destruct(struct sock *sk) struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); skcipher_free_sgl(sk); - memzero_explicit(ctx->iv, crypto_ablkcipher_ivsize(tfm)); - sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); + sock_kzfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); sock_kfree_s(sk, ctx, ctx->len); af_alg_release_parent(sk); } diff --git a/include/net/sock.h b/include/net/sock.h index 7db3db112baa..37d6cc5dcf33 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1588,6 +1588,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, int *errcode, int max_page_order); void *sock_kmalloc(struct sock *sk, int size, gfp_t priority); void sock_kfree_s(struct sock *sk, void *mem, int size); +void sock_kzfree_s(struct sock *sk, void *mem, int size); void sk_send_sigurg(struct sock *sk); /* diff --git a/net/core/sock.c b/net/core/sock.c index 15e0c67b1069..04ce26a996bd 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1713,18 +1713,34 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) } EXPORT_SYMBOL(sock_kmalloc); -/* - * Free an option memory block. +/* Free an option memory block. Note, we actually want the inline + * here as this allows gcc to detect the nullify and fold away the + * condition entirely. */ -void sock_kfree_s(struct sock *sk, void *mem, int size) +static inline void __sock_kfree_s(struct sock *sk, void *mem, int size, + const bool nullify) { if (WARN_ON_ONCE(!mem)) return; - kfree(mem); + if (nullify) + kzfree(mem); + else + kfree(mem); atomic_sub(size, &sk->sk_omem_alloc); } + +void sock_kfree_s(struct sock *sk, void *mem, int size) +{ + __sock_kfree_s(sk, mem, size, false); +} EXPORT_SYMBOL(sock_kfree_s); +void sock_kzfree_s(struct sock *sk, void *mem, int size) +{ + __sock_kfree_s(sk, mem, size, true); +} +EXPORT_SYMBOL(sock_kzfree_s); + /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. I think, these locks should be removed for datagram sockets. */ -- GitLab From b1c9952afeae3e7da798ca08cab0e97caaba0706 Mon Sep 17 00:00:00 2001 From: "Struk, Tadeusz" Date: Fri, 21 Nov 2014 09:25:57 -0800 Subject: [PATCH 6440/9457] crytpo: qat - Fix 64 bytes requests Fix invalid inflights calculation for 64 bytes requests. Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- .../crypto/qat/qat_common/adf_transport_access_macros.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/qat/qat_common/adf_transport_access_macros.h b/drivers/crypto/qat/qat_common/adf_transport_access_macros.h index 91d88d676580..160c9a36c919 100644 --- a/drivers/crypto/qat/qat_common/adf_transport_access_macros.h +++ b/drivers/crypto/qat/qat_common/adf_transport_access_macros.h @@ -83,14 +83,14 @@ #define ADF_MAX_RING_SIZE ADF_RING_SIZE_4M #define ADF_DEFAULT_RING_SIZE ADF_RING_SIZE_16K -/* Valid internal msg size values internal */ +/* Valid internal msg size values */ #define ADF_MSG_SIZE_32 0x01 #define ADF_MSG_SIZE_64 0x02 #define ADF_MSG_SIZE_128 0x04 #define ADF_MIN_MSG_SIZE ADF_MSG_SIZE_32 #define ADF_MAX_MSG_SIZE ADF_MSG_SIZE_128 -/* Size to bytes conversion macros for ring and msg values */ +/* Size to bytes conversion macros for ring and msg size values */ #define ADF_MSG_SIZE_TO_BYTES(SIZE) (SIZE << 5) #define ADF_BYTES_TO_MSG_SIZE(SIZE) (SIZE >> 5) #define ADF_SIZE_TO_RING_SIZE_IN_BYTES(SIZE) ((1 << (SIZE - 1)) << 7) @@ -100,8 +100,11 @@ #define ADF_RING_SIZE_BYTES_MIN(SIZE) ((SIZE < ADF_RING_SIZE_4K) ? \ ADF_RING_SIZE_4K : SIZE) #define ADF_RING_SIZE_MODULO(SIZE) (SIZE + 0x6) +#define ADF_SIZE_TO_POW(SIZE) ((((SIZE & 0x4) >> 1) | ((SIZE & 0x4) >> 2) | \ + SIZE) & ~0x4) +/* Max outstanding requests */ #define ADF_MAX_INFLIGHTS(RING_SIZE, MSG_SIZE) \ - ((((1 << (RING_SIZE - 1)) << 4) >> MSG_SIZE) - 1) + ((((1 << (RING_SIZE - 1)) << 3) >> ADF_SIZE_TO_POW(MSG_SIZE)) - 1) #define BUILD_RING_CONFIG(size) \ ((ADF_RING_NEAR_WATERMARK_0 << ADF_RING_CONFIG_NEAR_FULL_WM) \ | (ADF_RING_NEAR_WATERMARK_0 << ADF_RING_CONFIG_NEAR_EMPTY_WM) \ -- GitLab From 5d1b3c98ec2015036349c57289711f26c2d5fe01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 22 Nov 2014 21:36:28 +0300 Subject: [PATCH 6441/9457] crypto: sha-mb - remove a bogus NULL check This can't be NULL and we dereferenced it earlier. Smatch used to ignore these things where the pointer was obviously non-NULL but I've found that sometimes the intention was to check something else so we were maybe missing bugs. Signed-off-by: Dan Carpenter Acked-by: Tim Chen Signed-off-by: Herbert Xu --- arch/x86/crypto/sha-mb/sha1_mb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c index 99eefd812958..a225a5ca1037 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb.c +++ b/arch/x86/crypto/sha-mb/sha1_mb.c @@ -204,8 +204,7 @@ static struct sha1_hash_ctx *sha1_ctx_mgr_resubmit(struct sha1_ctx_mgr *mgr, str continue; } - if (ctx) - ctx->status = HASH_CTX_STS_IDLE; + ctx->status = HASH_CTX_STS_IDLE; return ctx; } -- GitLab From d3fe22fab76ef71da78971dddab7545f5591e2d8 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 06:49:07 -0300 Subject: [PATCH 6442/9457] [media] firewire: Deletion of an unnecessary check before the function call "dvb_unregister_device" The dvb_unregister_device() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Stefan Richter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/firewire/firedtv-ci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c index e5ebdbfe8c19..e63f582378bf 100644 --- a/drivers/media/firewire/firedtv-ci.c +++ b/drivers/media/firewire/firedtv-ci.c @@ -253,6 +253,5 @@ int fdtv_ca_register(struct firedtv *fdtv) void fdtv_ca_release(struct firedtv *fdtv) { - if (fdtv->cadev) - dvb_unregister_device(fdtv->cadev); + dvb_unregister_device(fdtv->cadev); } -- GitLab From 8f1aeedf78f5528a4471b019a39952aeb52dfa5b Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 07:13:16 -0300 Subject: [PATCH 6443/9457] [media] i2c: Deletion of an unnecessary check before the function call "rc_unregister_device" The rc_unregister_device() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ir-kbd-i2c.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index 8311f1a9a38e..175a76114953 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -464,8 +464,7 @@ static int ir_remove(struct i2c_client *client) cancel_delayed_work_sync(&ir->work); /* unregister device */ - if (ir->rc) - rc_unregister_device(ir->rc); + rc_unregister_device(ir->rc); /* free memory */ return 0; -- GitLab From 3dd94f00f07f013259dc221d6307ef699661f7ea Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 09:01:32 -0300 Subject: [PATCH 6444/9457] [media] rc: Deletion of unnecessary checks before two function calls The functions input_free_device() and rc_close() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 3 +-- drivers/media/rc/rc-main.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 249d2fbc8f37..1e0545a67959 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -518,8 +518,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) WARN_ON(mutex_lock_killable(&lirc_dev_lock)); - if (ir->d.rdev) - rc_close(ir->d.rdev); + rc_close(ir->d.rdev); ir->open--; if (ir->attached) { diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 97dd6921edbe..86ffcd54339e 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1298,8 +1298,7 @@ void rc_free_device(struct rc_dev *dev) if (!dev) return; - if (dev->input_dev) - input_free_device(dev->input_dev); + input_free_device(dev->input_dev); put_device(&dev->dev); -- GitLab From 332b295d107466df8b05a99a914adbe21401449b Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 07:44:20 -0300 Subject: [PATCH 6445/9457] [media] platform: Deletion of unnecessary checks before two function calls The functions i2c_put_adapter() and release_firmware() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-is.c | 6 ++---- drivers/media/platform/s3c-camif/camif-core.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 3d49ce03b176..2a0cbeff0324 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -428,8 +428,7 @@ static void fimc_is_load_firmware(const struct firmware *fw, void *context) * needed around for copying to the IS working memory every * time before the Cortex-A5 is restarted. */ - if (is->fw.f_w) - release_firmware(is->fw.f_w); + release_firmware(is->fw.f_w); is->fw.f_w = fw; done: mutex_unlock(&is->lock); @@ -937,8 +936,7 @@ static int fimc_is_remove(struct platform_device *pdev) vb2_dma_contig_cleanup_ctx(is->alloc_ctx); fimc_is_put_clocks(is); fimc_is_debugfs_remove(is); - if (is->fw.f_w) - release_firmware(is->fw.f_w); + release_firmware(is->fw.f_w); fimc_is_free_cpu_memory(is); return 0; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index b38574702fe9..3b09b5b6ad51 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -256,8 +256,7 @@ static void camif_unregister_sensor(struct camif_dev *camif) v4l2_device_unregister_subdev(sd); camif->sensor.sd = NULL; i2c_unregister_device(client); - if (adapter) - i2c_put_adapter(adapter); + i2c_put_adapter(adapter); } static int camif_create_media_links(struct camif_dev *camif) -- GitLab From 83f56f7cbd070c0d9772221aa61198ef74c96cc4 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 09:26:36 -0300 Subject: [PATCH 6446/9457] [media] USB: Deletion of unnecessary checks before three function calls GIT_AUTHOR_DATE=1416486805 The functions pvr2_hdw_destroy(), rc_unregister_device() and vfree() perform also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-input.c | 3 +-- drivers/media/usb/em28xx/em28xx-input.c | 3 +-- drivers/media/usb/pvrusb2/pvrusb2-context.c | 2 +- drivers/media/usb/s2255/s2255drv.c | 3 +-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 63995f97dc65..11a8daec5939 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -363,8 +363,7 @@ void au0828_rc_unregister(struct au0828_dev *dev) if (!ir) return; - if (ir->rc) - rc_unregister_device(ir->rc); + rc_unregister_device(ir->rc); /* done */ kfree(ir); diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 23f8f6afa2e0..85ac7dd15700 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -841,8 +841,7 @@ static int em28xx_ir_fini(struct em28xx *dev) if (!ir) goto ref_put; - if (ir->rc) - rc_unregister_device(ir->rc); + rc_unregister_device(ir->rc); kfree(ir->i2c_client); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c index 7c19ff72e6b3..c8761c71c9d2 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -80,7 +80,7 @@ static void pvr2_context_set_notify(struct pvr2_context *mp, int fl) static void pvr2_context_destroy(struct pvr2_context *mp) { pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp); - if (mp->hdw) pvr2_hdw_destroy(mp->hdw); + pvr2_hdw_destroy(mp->hdw); pvr2_context_set_notify(mp, 0); mutex_lock(&pvr2_context_mutex); if (mp->exist_next) { diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index a56a05b0c4e1..e03b155fa5c7 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -1974,8 +1974,7 @@ static int s2255_release_sys_buffers(struct s2255_vc *vc) { unsigned long i; for (i = 0; i < SYS_FRAMES; i++) { - if (vc->buffer.frame[i].lpvbits) - vfree(vc->buffer.frame[i].lpvbits); + vfree(vc->buffer.frame[i].lpvbits); vc->buffer.frame[i].lpvbits = NULL; } return 0; -- GitLab From eb336eab3e6ccb9b100b934a2d5677dfaa66d4de Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 21 Nov 2014 21:17:08 -0300 Subject: [PATCH 6447/9457] [media] media/au0828: Fix IR stop, poll to not access device during disconnect au0828 IR stop and poll routines continue to access device while usb disconnect is in progress. There is small window between device disconnect and usb interface is set to null. This results in filling the log with several of the following error messages. Fix it to detect device disconnect condition and avoid device access. Nov 20 18:58:02 anduin kernel: [ 102.949819] au0828: au0828_usb_disconnect() Nov 20 18:58:02 anduin kernel: [ 102.950046] au0828: send_control_msg() Failed sending control message, error -71. Nov 20 18:58:02 anduin kernel: [ 102.950052] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950056] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950061] au0828: send_control_msg() Failed sending control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950065] au0828: recv_control_msg() Failed receiving control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950069] au0828: recv_control_msg() Failed receiving control message, error -19. Nov 20 18:58:02 anduin kernel: [ 102.950072] au0828: recv_control_msg() Failed receiving control message, error -19. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 8 ++++++++ drivers/media/usb/au0828/au0828-input.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index bc064803b6c7..082ae6ba492f 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -153,6 +153,14 @@ static void au0828_usb_disconnect(struct usb_interface *interface) dprintk(1, "%s()\n", __func__); + /* there is a small window after disconnect, before + dev->usbdev is NULL, for poll (e.g: IR) try to access + the device and fill the dmesg with error messages. + Set the status so poll routines can check and avoid + access after disconnect. + */ + dev->dev_state = DEV_DISCONNECTED; + au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 11a8daec5939..b0f067971979 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -129,6 +129,10 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) int prv_bit, bit, width; bool first = true; + /* do nothing if device is disconnected */ + if (ir->dev->dev_state == DEV_DISCONNECTED) + return 0; + /* Check IR int */ rc = au8522_rc_read(ir, 0xe1, -1, buf, 1); if (rc < 0 || !(buf[0] & (1 << 4))) { @@ -255,8 +259,11 @@ static void au0828_rc_stop(struct rc_dev *rc) cancel_delayed_work_sync(&ir->work); - /* Disable IR */ - au8522_rc_clear(ir, 0xe0, 1 << 4); + /* do nothing if device is disconnected */ + if (ir->dev->dev_state != DEV_DISCONNECTED) { + /* Disable IR */ + au8522_rc_clear(ir, 0xe0, 1 << 4); + } } static int au0828_probe_i2c_ir(struct au0828_dev *dev) -- GitLab From a430a3455f2c48995e06b359a82a1109a419e9ef Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:36:02 +0200 Subject: [PATCH 6448/9457] i2c/of: Factor out Devicetree registration code Dynamically inserting i2c client device nodes requires the use of a single device registration method. Factor out the loop body of of_i2c_register_devices() so that it can be called for individual device_nodes instead of for all the children of a node. Note: The diff of this commit looks far more complicated than it actually is due the indentation being changed for a large block of code. When viewed using the diff -w flag to ignore whitespace changes it can be seen that the change is actually quite simple. Signed-off-by: Pantelis Antoniou [grant.likely: Made new function static and removed changes to header] Signed-off-by: Grant Likely Reviewed-by: Wolfram Sang Cc: Rob Herring Cc: linux-i2c@vger.kernel.org --- drivers/i2c/i2c-core.c | 97 ++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f43b4e11647a..15ba6185dba5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "i2c-core.h" @@ -1368,63 +1369,69 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) /* OF support code */ #if IS_ENABLED(CONFIG_OF) -static void of_i2c_register_devices(struct i2c_adapter *adap) +static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, + struct device_node *node) { - void *result; - struct device_node *node; + struct i2c_client *result; + struct i2c_board_info info = {}; + struct dev_archdata dev_ad = {}; + const __be32 *addr; + int len; - /* Only register child devices if the adapter has a node pointer set */ - if (!adap->dev.of_node) - return; + dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); - dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { + dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", + node->full_name); + return ERR_PTR(-EINVAL); + } - for_each_available_child_of_node(adap->dev.of_node, node) { - struct i2c_board_info info = {}; - struct dev_archdata dev_ad = {}; - const __be32 *addr; - int len; + addr = of_get_property(node, "reg", &len); + if (!addr || (len < sizeof(int))) { + dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", + node->full_name); + return ERR_PTR(-EINVAL); + } - dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); + info.addr = be32_to_cpup(addr); + if (info.addr > (1 << 10) - 1) { + dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", + info.addr, node->full_name); + return ERR_PTR(-EINVAL); + } - if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { - dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", - node->full_name); - continue; - } + info.irq = irq_of_parse_and_map(node, 0); + info.of_node = of_node_get(node); + info.archdata = &dev_ad; - addr = of_get_property(node, "reg", &len); - if (!addr || (len < sizeof(int))) { - dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", - node->full_name); - continue; - } + if (of_get_property(node, "wakeup-source", NULL)) + info.flags |= I2C_CLIENT_WAKE; - info.addr = be32_to_cpup(addr); - if (info.addr > (1 << 10) - 1) { - dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", - info.addr, node->full_name); - continue; - } + request_module("%s%s", I2C_MODULE_PREFIX, info.type); - info.irq = irq_of_parse_and_map(node, 0); - info.of_node = of_node_get(node); - info.archdata = &dev_ad; + result = i2c_new_device(adap, &info); + if (result == NULL) { + dev_err(&adap->dev, "of_i2c: Failure registering %s\n", + node->full_name); + of_node_put(node); + irq_dispose_mapping(info.irq); + return ERR_PTR(-EINVAL); + } + return result; +} - if (of_get_property(node, "wakeup-source", NULL)) - info.flags |= I2C_CLIENT_WAKE; +static void of_i2c_register_devices(struct i2c_adapter *adap) +{ + struct device_node *node; - request_module("%s%s", I2C_MODULE_PREFIX, info.type); + /* Only register child devices if the adapter has a node pointer set */ + if (!adap->dev.of_node) + return; - result = i2c_new_device(adap, &info); - if (result == NULL) { - dev_err(&adap->dev, "of_i2c: Failure registering %s\n", - node->full_name); - of_node_put(node); - irq_dispose_mapping(info.irq); - continue; - } - } + dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); + + for_each_available_child_of_node(adap->dev.of_node, node) + of_i2c_register_device(adap, node); } static int of_dev_node_match(struct device *dev, void *data) -- GitLab From ea7513bbc04170f1cbf42953187a4d8b731c71c4 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:36:03 +0200 Subject: [PATCH 6449/9457] i2c/of: Add OF_RECONFIG notifier handler CONFIG_OF_DYNAMIC enables runtime changes to the device tree which in turn may trigger addition or removal of devices from Linux. Add an OF_RECONFIG notifier handler to receive tree change events and to creating or destroy i2c devices as required. Signed-off-by: Pantelis Antoniou [grant.likely: clean up #ifdefs and drop unneeded error handling] Signed-off-by: Grant Likely Reviewed-by: Wolfram Sang Cc: Rob Herring Cc: linux-i2c@vger.kernel.org --- drivers/i2c/i2c-core.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 15ba6185dba5..d8afd3f28ca4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1951,6 +1951,52 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) } EXPORT_SYMBOL(i2c_clients_command); +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +static int of_i2c_notify(struct notifier_block *nb, unsigned long action, + void *arg) +{ + struct of_reconfig_data *rd = arg; + struct i2c_adapter *adap; + struct i2c_client *client; + + switch (of_reconfig_get_state_change(action, rd)) { + case OF_RECONFIG_CHANGE_ADD: + adap = of_find_i2c_adapter_by_node(rd->dn->parent); + if (adap == NULL) + return NOTIFY_OK; /* not for us */ + + client = of_i2c_register_device(adap, rd->dn); + put_device(&adap->dev); + + if (IS_ERR(client)) { + pr_err("%s: failed to create for '%s'\n", + __func__, rd->dn->full_name); + return notifier_from_errno(PTR_ERR(client)); + } + break; + case OF_RECONFIG_CHANGE_REMOVE: + /* find our device by node */ + client = of_find_i2c_device_by_node(rd->dn); + if (client == NULL) + return NOTIFY_OK; /* no? not meant for us */ + + /* unregister takes one ref away */ + i2c_unregister_device(client); + + /* and put the reference of the find */ + put_device(&client->dev); + break; + } + + return NOTIFY_OK; +} +static struct notifier_block i2c_of_notifier = { + .notifier_call = of_i2c_notify, +}; +#else +extern struct notifier_block i2c_of_notifier; +#endif /* CONFIG_OF_DYNAMIC */ + static int __init i2c_init(void) { int retval; @@ -1968,6 +2014,10 @@ static int __init i2c_init(void) retval = i2c_add_driver(&dummy_driver); if (retval) goto class_err; + + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_register(&i2c_of_notifier)); + return 0; class_err: @@ -1981,6 +2031,8 @@ static int __init i2c_init(void) static void __exit i2c_exit(void) { + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_unregister(&i2c_of_notifier)); i2c_del_driver(&dummy_driver); #ifdef CONFIG_I2C_COMPAT class_compat_unregister(i2c_adapter_compat_class); -- GitLab From aff5e3f89a0b07e7edf9243f913378cc27e4110d Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 29 Oct 2014 10:40:37 +0200 Subject: [PATCH 6450/9457] spi/of: Create new device registration method and accessors Dynamically inserting spi device nodes requires the use of a single device registration method. Refactor the existing of_register_spi_devices() to split out the core functionality for a single device into a separate function; of_register_spi_device(). This function will be used by the OF_DYNAMIC overlay code to make live modifications to the tree. Methods to lookup a device/master using a device node are added as well, of_find_spi_master_by_node() & of_find_spi_device_by_node(). Signed-off-by: Pantelis Antoniou [grant.likely] Split patch into two pieces for clarity Signed-off-by: Grant Likely Reviewed-by: Mark Brown Cc: --- drivers/spi/spi.c | 222 ++++++++++++++++++++++++---------------------- 1 file changed, 118 insertions(+), 104 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ebcb33df2eb2..a3557c57d4f7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1220,6 +1220,121 @@ static int spi_master_initialize_queue(struct spi_master *master) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_OF) +static struct spi_device * +of_register_spi_device(struct spi_master *master, struct device_node *nc) +{ + struct spi_device *spi; + int rc; + u32 value; + + /* Alloc an spi_device */ + spi = spi_alloc_device(master); + if (!spi) { + dev_err(&master->dev, "spi_device alloc error for %s\n", + nc->full_name); + rc = -ENOMEM; + goto err_out; + } + + /* Select device driver */ + rc = of_modalias_node(nc, spi->modalias, + sizeof(spi->modalias)); + if (rc < 0) { + dev_err(&master->dev, "cannot find modalias for %s\n", + nc->full_name); + goto err_out; + } + + /* Device address */ + rc = of_property_read_u32(nc, "reg", &value); + if (rc) { + dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", + nc->full_name, rc); + goto err_out; + } + spi->chip_select = value; + + /* Mode (clock phase/polarity/etc.) */ + if (of_find_property(nc, "spi-cpha", NULL)) + spi->mode |= SPI_CPHA; + if (of_find_property(nc, "spi-cpol", NULL)) + spi->mode |= SPI_CPOL; + if (of_find_property(nc, "spi-cs-high", NULL)) + spi->mode |= SPI_CS_HIGH; + if (of_find_property(nc, "spi-3wire", NULL)) + spi->mode |= SPI_3WIRE; + if (of_find_property(nc, "spi-lsb-first", NULL)) + spi->mode |= SPI_LSB_FIRST; + + /* Device DUAL/QUAD mode */ + if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { + switch (value) { + case 1: + break; + case 2: + spi->mode |= SPI_TX_DUAL; + break; + case 4: + spi->mode |= SPI_TX_QUAD; + break; + default: + dev_warn(&master->dev, + "spi-tx-bus-width %d not supported\n", + value); + break; + } + } + + if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { + switch (value) { + case 1: + break; + case 2: + spi->mode |= SPI_RX_DUAL; + break; + case 4: + spi->mode |= SPI_RX_QUAD; + break; + default: + dev_warn(&master->dev, + "spi-rx-bus-width %d not supported\n", + value); + break; + } + } + + /* Device speed */ + rc = of_property_read_u32(nc, "spi-max-frequency", &value); + if (rc) { + dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", + nc->full_name, rc); + goto err_out; + } + spi->max_speed_hz = value; + + /* IRQ */ + spi->irq = irq_of_parse_and_map(nc, 0); + + /* Store a pointer to the node in the device structure */ + of_node_get(nc); + spi->dev.of_node = nc; + + /* Register the new device */ + request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias); + rc = spi_add_device(spi); + if (rc) { + dev_err(&master->dev, "spi_device register error %s\n", + nc->full_name); + goto err_out; + } + + return spi; + +err_out: + spi_dev_put(spi); + return ERR_PTR(rc); +} + /** * of_register_spi_devices() - Register child devices onto the SPI bus * @master: Pointer to spi_master device @@ -1231,116 +1346,15 @@ static void of_register_spi_devices(struct spi_master *master) { struct spi_device *spi; struct device_node *nc; - int rc; - u32 value; if (!master->dev.of_node) return; for_each_available_child_of_node(master->dev.of_node, nc) { - /* Alloc an spi_device */ - spi = spi_alloc_device(master); - if (!spi) { - dev_err(&master->dev, "spi_device alloc error for %s\n", + spi = of_register_spi_device(master, nc); + if (IS_ERR(spi)) + dev_warn(&master->dev, "Failed to create SPI device for %s\n", nc->full_name); - spi_dev_put(spi); - continue; - } - - /* Select device driver */ - if (of_modalias_node(nc, spi->modalias, - sizeof(spi->modalias)) < 0) { - dev_err(&master->dev, "cannot find modalias for %s\n", - nc->full_name); - spi_dev_put(spi); - continue; - } - - /* Device address */ - rc = of_property_read_u32(nc, "reg", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", - nc->full_name, rc); - spi_dev_put(spi); - continue; - } - spi->chip_select = value; - - /* Mode (clock phase/polarity/etc.) */ - if (of_find_property(nc, "spi-cpha", NULL)) - spi->mode |= SPI_CPHA; - if (of_find_property(nc, "spi-cpol", NULL)) - spi->mode |= SPI_CPOL; - if (of_find_property(nc, "spi-cs-high", NULL)) - spi->mode |= SPI_CS_HIGH; - if (of_find_property(nc, "spi-3wire", NULL)) - spi->mode |= SPI_3WIRE; - if (of_find_property(nc, "spi-lsb-first", NULL)) - spi->mode |= SPI_LSB_FIRST; - - /* Device DUAL/QUAD mode */ - if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { - switch (value) { - case 1: - break; - case 2: - spi->mode |= SPI_TX_DUAL; - break; - case 4: - spi->mode |= SPI_TX_QUAD; - break; - default: - dev_warn(&master->dev, - "spi-tx-bus-width %d not supported\n", - value); - break; - } - } - - if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) { - switch (value) { - case 1: - break; - case 2: - spi->mode |= SPI_RX_DUAL; - break; - case 4: - spi->mode |= SPI_RX_QUAD; - break; - default: - dev_warn(&master->dev, - "spi-rx-bus-width %d not supported\n", - value); - break; - } - } - - /* Device speed */ - rc = of_property_read_u32(nc, "spi-max-frequency", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", - nc->full_name, rc); - spi_dev_put(spi); - continue; - } - spi->max_speed_hz = value; - - /* IRQ */ - spi->irq = irq_of_parse_and_map(nc, 0); - - /* Store a pointer to the node in the device structure */ - of_node_get(nc); - spi->dev.of_node = nc; - - /* Register the new device */ - request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias); - rc = spi_add_device(spi); - if (rc) { - dev_err(&master->dev, "spi_device register error %s\n", - nc->full_name); - spi_dev_put(spi); - } - } } #else -- GitLab From ce79d54ae447d65117303ca9f61ffe9dcbc2465d Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 28 Oct 2014 22:36:05 +0200 Subject: [PATCH 6451/9457] spi/of: Add OF notifier handler Add OF notifier handler needed for creating/destroying spi devices according to dynamic runtime changes in the DT live tree. This code is enabled when CONFIG_OF_DYNAMIC is selected. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely Reviewed-by: Mark Brown Cc: --- drivers/spi/spi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a3557c57d4f7..bf1cab0fad66 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2317,6 +2317,86 @@ EXPORT_SYMBOL_GPL(spi_write_then_read); /*-------------------------------------------------------------------------*/ +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +static int __spi_of_device_match(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +/* must call put_device() when done with returned spi_device device */ +static struct spi_device *of_find_spi_device_by_node(struct device_node *node) +{ + struct device *dev = bus_find_device(&spi_bus_type, NULL, node, + __spi_of_device_match); + return dev ? to_spi_device(dev) : NULL; +} + +static int __spi_of_master_match(struct device *dev, const void *data) +{ + return dev->of_node == data; +} + +/* the spi masters are not using spi_bus, so we find it with another way */ +static struct spi_master *of_find_spi_master_by_node(struct device_node *node) +{ + struct device *dev; + + dev = class_find_device(&spi_master_class, NULL, node, + __spi_of_master_match); + if (!dev) + return NULL; + + /* reference got in class_find_device */ + return container_of(dev, struct spi_master, dev); +} + +static int of_spi_notify(struct notifier_block *nb, unsigned long action, + void *arg) +{ + struct of_reconfig_data *rd = arg; + struct spi_master *master; + struct spi_device *spi; + + switch (of_reconfig_get_state_change(action, arg)) { + case OF_RECONFIG_CHANGE_ADD: + master = of_find_spi_master_by_node(rd->dn->parent); + if (master == NULL) + return NOTIFY_OK; /* not for us */ + + spi = of_register_spi_device(master, rd->dn); + put_device(&master->dev); + + if (IS_ERR(spi)) { + pr_err("%s: failed to create for '%s'\n", + __func__, rd->dn->full_name); + return notifier_from_errno(PTR_ERR(spi)); + } + break; + + case OF_RECONFIG_CHANGE_REMOVE: + /* find our device by node */ + spi = of_find_spi_device_by_node(rd->dn); + if (spi == NULL) + return NOTIFY_OK; /* no? not meant for us */ + + /* unregister takes one ref away */ + spi_unregister_device(spi); + + /* and put the reference of the find */ + put_device(&spi->dev); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block spi_of_notifier = { + .notifier_call = of_spi_notify, +}; +#else /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ +extern struct notifier_block spi_of_notifier; +#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ + static int __init spi_init(void) { int status; @@ -2334,6 +2414,10 @@ static int __init spi_init(void) status = class_register(&spi_master_class); if (status < 0) goto err2; + + if (IS_ENABLED(CONFIG_OF)) + WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); + return 0; err2: -- GitLab From 6b213e81ddf8b265383c9a1a1884432df88f701e Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 24 Nov 2014 09:07:45 -0300 Subject: [PATCH 6452/9457] [media] omap: Fix typo "HAS_MMU" Commit 38a073116525 ("[media] omap: be sure that MMU is there for COMPILE_TEST") added a dependency on HAS_MMU. There's no Kconfig symbol HAS_MMU. Use MMU instead. Signed-off-by: Paul Bolle Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig index 05de442d24e4..8f27cdadf8b8 100644 --- a/drivers/media/platform/omap/Kconfig +++ b/drivers/media/platform/omap/Kconfig @@ -3,7 +3,8 @@ config VIDEO_OMAP2_VOUT_VRFB config VIDEO_OMAP2_VOUT tristate "OMAP2/OMAP3 V4L2-Display driver" - depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && HAS_MMU) + depends on MMU + depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST select VIDEOBUF_GEN select VIDEOBUF_DMA_CONTIG select OMAP2_DSS if HAS_IOMEM && ARCH_OMAP2PLUS -- GitLab From 1cc6adfef42615478e9af1228377acbc9f54f00f Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 25 Nov 2014 05:54:27 -0300 Subject: [PATCH 6453/9457] [media] media: v4l2-image-sizes.h: add SVGA, XGA and UXGA size definitions Add SVGA, UXGA and XGA size definitions to v4l2-image-sizes.h. The definitions are sorted by alphabet order. Signed-off-by: Josh Wu Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-image-sizes.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/media/v4l2-image-sizes.h b/include/media/v4l2-image-sizes.h index 10daf92ff1ab..c70c917b97a8 100644 --- a/include/media/v4l2-image-sizes.h +++ b/include/media/v4l2-image-sizes.h @@ -25,10 +25,19 @@ #define QVGA_WIDTH 320 #define QVGA_HEIGHT 240 +#define SVGA_WIDTH 800 +#define SVGA_HEIGHT 680 + #define SXGA_WIDTH 1280 #define SXGA_HEIGHT 1024 #define VGA_WIDTH 640 #define VGA_HEIGHT 480 +#define UXGA_WIDTH 1600 +#define UXGA_HEIGHT 1200 + +#define XGA_WIDTH 1024 +#define XGA_HEIGHT 768 + #endif /* _IMAGE_SIZES_H */ -- GitLab From 758eb51e7184f95a235b549092f50a1921bce06c Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 3 Nov 2014 14:08:39 +0000 Subject: [PATCH 6454/9457] Btrfs: fix freeing used extent after removing empty block group Due to ignoring errors returned by clear_extent_bits (at the moment only -ENOMEM is possible), we can end up freeing an extent that is actually in use (i.e. return the extent to the free space cache). The sequence of steps that lead to this: 1) Cleaner thread starts execution and calls btrfs_delete_unused_bgs(), with the goal of freeing empty block groups; 2) btrfs_delete_unused_bgs() finds an empty block group, joins the current transaction (or starts a new one if none is running) and attempts to clear the EXTENT_DIRTY bit for the block group's range from freed_extents[0] and freed_extents[1] (of which one corresponds to fs_info->pinned_extents); 3) Clearing the EXTENT_DIRTY bit (via clear_extent_bits()) fails with -ENOMEM, but such error is ignored and btrfs_delete_unused_bgs() proceeds to delete the block group and the respective chunk, while pinned_extents remains with that bit set for the whole (or a part of the) range covered by the block group; 4) Later while the transaction is still running, the chunk ends up being reused for a new block group (maybe for different purpose, data or metadata), and extents belonging to the new block group are allocated for file data or btree nodes/leafs; 5) The current transaction is committed, meaning that we unpinned one or more extents from the new block group (through btrfs_finish_extent_commit() and unpin_extent_range()) which are now being used for new file data or new metadata (through btrfs_finish_extent_commit() and unpin_extent_range()). And unpinning means we returned the extents to the free space cache of the new block group, which implies those extents can be used for future allocations while they're still in use. Alternatively, we can hit a BUG_ON() when doing a lookup for a block group's cache object in unpin_extent_range() if a new block group didn't end up being allocated for the same chunk (step 4 above). Fix this by not freeing the block group and chunk if we fail to clear the dirty bit. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cf3460e9b122..5e81e3694d92 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -9513,10 +9513,18 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) */ start = block_group->key.objectid; end = start + block_group->key.offset - 1; - clear_extent_bits(&fs_info->freed_extents[0], start, end, + ret = clear_extent_bits(&fs_info->freed_extents[0], start, end, EXTENT_DIRTY, GFP_NOFS); - clear_extent_bits(&fs_info->freed_extents[1], start, end, + if (ret) { + btrfs_set_block_group_rw(root, block_group); + goto end_trans; + } + ret = clear_extent_bits(&fs_info->freed_extents[1], start, end, EXTENT_DIRTY, GFP_NOFS); + if (ret) { + btrfs_set_block_group_rw(root, block_group); + goto end_trans; + } /* Reset pinned so btrfs_put_block_group doesn't complain */ block_group->pinned = 0; @@ -9527,6 +9535,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) */ ret = btrfs_remove_chunk(trans, root, block_group->key.objectid); +end_trans: btrfs_end_transaction(trans, root); next: btrfs_put_block_group(block_group); -- GitLab From e5fa8f865b3324aebd055e4054bf479cbab37e5a Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 21 Oct 2014 11:11:41 +0100 Subject: [PATCH 6455/9457] Btrfs: ensure send always works on roots without orphans Move the logic from the snapshot creation ioctl into send. This avoids doing the transaction commit if send isn't used, and ensures that if a crash/reboot happens after the transaction commit that created the snapshot and before the transaction commit that switched the commit root, send will not get a commit root that differs from the main root (that has orphan items). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 29 ---------------------------- fs/btrfs/send.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4399f0c3a4ce..3abc068c5543 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -717,35 +717,6 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, if (ret) goto fail; - /* - * If orphan cleanup did remove any orphans, it means the tree was - * modified and therefore the commit root is not the same as the - * current root anymore. This is a problem, because send uses the - * commit root and therefore can see inode items that don't exist - * in the current root anymore, and for example make calls to - * btrfs_iget, which will do tree lookups based on the current root - * and not on the commit root. Those lookups will fail, returning a - * -ESTALE error, and making send fail with that error. So make sure - * a send does not see any orphans we have just removed, and that it - * will see the same inodes regardless of whether a transaction - * commit happened before it started (meaning that the commit root - * will be the same as the current root) or not. - */ - if (readonly && pending_snapshot->snap->node != - pending_snapshot->snap->commit_root) { - trans = btrfs_join_transaction(pending_snapshot->snap); - if (IS_ERR(trans) && PTR_ERR(trans) != -ENOENT) { - ret = PTR_ERR(trans); - goto fail; - } - if (!IS_ERR(trans)) { - ret = btrfs_commit_transaction(trans, - pending_snapshot->snap); - if (ret) - goto fail; - } - } - inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); if (IS_ERR(inode)) { ret = PTR_ERR(inode); diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 874828dd0a86..804432dbc351 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -5507,6 +5507,51 @@ static int send_subvol(struct send_ctx *sctx) return ret; } +/* + * If orphan cleanup did remove any orphans from a root, it means the tree + * was modified and therefore the commit root is not the same as the current + * root anymore. This is a problem, because send uses the commit root and + * therefore can see inode items that don't exist in the current root anymore, + * and for example make calls to btrfs_iget, which will do tree lookups based + * on the current root and not on the commit root. Those lookups will fail, + * returning a -ESTALE error, and making send fail with that error. So make + * sure a send does not see any orphans we have just removed, and that it will + * see the same inodes regardless of whether a transaction commit happened + * before it started (meaning that the commit root will be the same as the + * current root) or not. + */ +static int ensure_commit_roots_uptodate(struct send_ctx *sctx) +{ + int i; + struct btrfs_trans_handle *trans = NULL; + +again: + if (sctx->parent_root && + sctx->parent_root->node != sctx->parent_root->commit_root) + goto commit_trans; + + for (i = 0; i < sctx->clone_roots_cnt; i++) + if (sctx->clone_roots[i].root->node != + sctx->clone_roots[i].root->commit_root) + goto commit_trans; + + if (trans) + return btrfs_end_transaction(trans, sctx->send_root); + + return 0; + +commit_trans: + /* Use any root, all fs roots will get their commit roots updated. */ + if (!trans) { + trans = btrfs_join_transaction(sctx->send_root); + if (IS_ERR(trans)) + return PTR_ERR(trans); + goto again; + } + + return btrfs_commit_transaction(trans, sctx->send_root); +} + static void btrfs_root_dec_send_in_progress(struct btrfs_root* root) { spin_lock(&root->root_item_lock); @@ -5728,6 +5773,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) NULL); sort_clone_roots = 1; + ret = ensure_commit_roots_uptodate(sctx); + if (ret) + goto out; + current->journal_info = BTRFS_SEND_TRANS_STUB; ret = send_subvol(sctx); current->journal_info = NULL; -- GitLab From 9ea24bbe17a29f937e7f48e4b15fd52e89e9d386 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 29 Oct 2014 11:57:59 +0000 Subject: [PATCH 6456/9457] Btrfs: fix snapshot inconsistency after a file write followed by truncate If right after starting the snapshot creation ioctl we perform a write against a file followed by a truncate, with both operations increasing the file's size, we can get a snapshot tree that reflects a state of the source subvolume's tree where the file truncation happened but the write operation didn't. This leaves a gap between 2 file extent items of the inode, which makes btrfs' fsck complain about it. For example, if we perform the following file operations: $ mkfs.btrfs -f /dev/vdd $ mount /dev/vdd /mnt $ xfs_io -f \ -c "pwrite -S 0xaa -b 32K 0 32K" \ -c "fsync" \ -c "pwrite -S 0xbb -b 32770 16K 32770" \ -c "truncate 90123" \ /mnt/foobar and the snapshot creation ioctl was just called before the second write, we often can get the following inode items in the snapshot's btree: item 120 key (257 INODE_ITEM 0) itemoff 7987 itemsize 160 inode generation 146 transid 7 size 90123 block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 flags 0x0 item 121 key (257 INODE_REF 256) itemoff 7967 itemsize 20 inode ref index 282 namelen 10 name: foobar item 122 key (257 EXTENT_DATA 0) itemoff 7914 itemsize 53 extent data disk byte 1104855040 nr 32768 extent data offset 0 nr 32768 ram 32768 extent compression 0 item 123 key (257 EXTENT_DATA 53248) itemoff 7861 itemsize 53 extent data disk byte 0 nr 0 extent data offset 0 nr 40960 ram 40960 extent compression 0 There's a file range, corresponding to the interval [32K; ALIGN(16K + 32770, 4096)[ for which there's no file extent item covering it. This is because the file write and file truncate operations happened both right after the snapshot creation ioctl called btrfs_start_delalloc_inodes(), which means we didn't start and wait for the ordered extent that matches the write and, in btrfs_setsize(), we were able to call btrfs_cont_expand() before being able to commit the current transaction in the snapshot creation ioctl. So this made it possibe to insert the hole file extent item in the source subvolume (which represents the region added by the truncate) right before the transaction commit from the snapshot creation ioctl. Btrfs' fsck tool complains about such cases with a message like the following: "root 331 inode 257 errors 100, file extent discount" >From a user perspective, the expectation when a snapshot is created while those file operations are being performed is that the snapshot will have a file that either: 1) is empty 2) only the first write was captured 3) only the 2 writes were captured 4) both writes and the truncation were captured But never capture a state where only the first write and the truncation were captured (since the second write was performed before the truncation). A test case for xfstests follows. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 4 ++-- fs/btrfs/extent-tree.c | 16 +++++++------- fs/btrfs/file.c | 10 ++++----- fs/btrfs/inode.c | 47 +++++++++++++++++++++++++++++++++++------- fs/btrfs/ioctl.c | 7 ++++--- 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9918ba3ec2b2..fc73e86235e8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3480,8 +3480,8 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info); int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int __get_raid_index(u64 flags); -int btrfs_start_nocow_write(struct btrfs_root *root); -void btrfs_end_nocow_write(struct btrfs_root *root); +int btrfs_start_write_no_snapshoting(struct btrfs_root *root); +void btrfs_end_write_no_snapshoting(struct btrfs_root *root); /* ctree.c */ int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, int level, int *slot); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5e81e3694d92..b4e3ab115f5f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -9656,12 +9656,14 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) } /* - * btrfs_{start,end}_write() is similar to mnt_{want, drop}_write(), - * they are used to prevent the some tasks writing data into the page cache - * by nocow before the subvolume is snapshoted, but flush the data into - * the disk after the snapshot creation. + * btrfs_{start,end}_write_no_snapshoting() are similar to + * mnt_{want,drop}_write(), they are used to prevent some tasks from writing + * data into the page cache through nocow before the subvolume is snapshoted, + * but flush the data into disk after the snapshot creation, or to prevent + * operations while snapshoting is ongoing and that cause the snapshot to be + * inconsistent (writes followed by expanding truncates for example). */ -void btrfs_end_nocow_write(struct btrfs_root *root) +void btrfs_end_write_no_snapshoting(struct btrfs_root *root) { percpu_counter_dec(&root->subv_writers->counter); /* @@ -9673,7 +9675,7 @@ void btrfs_end_nocow_write(struct btrfs_root *root) wake_up(&root->subv_writers->wait); } -int btrfs_start_nocow_write(struct btrfs_root *root) +int btrfs_start_write_no_snapshoting(struct btrfs_root *root) { if (atomic_read(&root->will_be_snapshoted)) return 0; @@ -9684,7 +9686,7 @@ int btrfs_start_nocow_write(struct btrfs_root *root) */ smp_mb(); if (atomic_read(&root->will_be_snapshoted)) { - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); return 0; } return 1; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 0fbf0e7bc606..e4090259569b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1428,7 +1428,7 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos, u64 num_bytes; int ret; - ret = btrfs_start_nocow_write(root); + ret = btrfs_start_write_no_snapshoting(root); if (!ret) return -ENOSPC; @@ -1451,7 +1451,7 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos, ret = can_nocow_extent(inode, lockstart, &num_bytes, NULL, NULL, NULL); if (ret <= 0) { ret = 0; - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); } else { *write_bytes = min_t(size_t, *write_bytes , num_bytes - pos + lockstart); @@ -1543,7 +1543,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, btrfs_free_reserved_data_space(inode, reserve_bytes); else - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); break; } @@ -1632,7 +1632,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, release_bytes = 0; if (only_release_metadata) - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); if (only_release_metadata && copied > 0) { u64 lockstart = round_down(pos, root->sectorsize); @@ -1661,7 +1661,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (release_bytes) { if (only_release_metadata) { - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); btrfs_delalloc_release_metadata(inode, release_bytes); } else { btrfs_delalloc_release_space(inode, release_bytes); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a5374c2bb943..8de23355f6cf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1337,7 +1337,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, * we fall into common COW way. */ if (!nolock) { - err = btrfs_start_nocow_write(root); + err = btrfs_start_write_no_snapshoting(root); if (!err) goto out_check; } @@ -1361,7 +1361,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (extent_end <= start) { path->slots[0]++; if (!nolock && nocow) - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); goto next_slot; } if (!nocow) { @@ -1381,7 +1381,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, page_started, nr_written, 1); if (ret) { if (!nolock && nocow) - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); goto error; } cow_start = (u64)-1; @@ -1432,7 +1432,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, num_bytes); if (ret) { if (!nolock && nocow) - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); goto error; } } @@ -1443,7 +1443,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, EXTENT_DELALLOC, PAGE_UNLOCK | PAGE_SET_PRIVATE2); if (!nolock && nocow) - btrfs_end_nocow_write(root); + btrfs_end_write_no_snapshoting(root); cur_offset = extent_end; if (cur_offset > end) break; @@ -4599,6 +4599,26 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) return err; } +static int wait_snapshoting_atomic_t(atomic_t *a) +{ + schedule(); + return 0; +} + +static void wait_for_snapshot_creation(struct btrfs_root *root) +{ + while (true) { + int ret; + + ret = btrfs_start_write_no_snapshoting(root); + if (ret) + break; + wait_on_atomic_t(&root->will_be_snapshoted, + wait_snapshoting_atomic_t, + TASK_UNINTERRUPTIBLE); + } +} + static int btrfs_setsize(struct inode *inode, struct iattr *attr) { struct btrfs_root *root = BTRFS_I(inode)->root; @@ -4623,17 +4643,30 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) if (newsize > oldsize) { truncate_pagecache(inode, newsize); + /* + * Don't do an expanding truncate while snapshoting is ongoing. + * This is to ensure the snapshot captures a fully consistent + * state of this file - if the snapshot captures this expanding + * truncation, it must capture all writes that happened before + * this truncation. + */ + wait_for_snapshot_creation(root); ret = btrfs_cont_expand(inode, oldsize, newsize); - if (ret) + if (ret) { + btrfs_end_write_no_snapshoting(root); return ret; + } trans = btrfs_start_transaction(root, 1); - if (IS_ERR(trans)) + if (IS_ERR(trans)) { + btrfs_end_write_no_snapshoting(root); return PTR_ERR(trans); + } i_size_write(inode, newsize); btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); ret = btrfs_update_inode(trans, root, inode); + btrfs_end_write_no_snapshoting(root); btrfs_end_transaction(trans, root); } else { diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3abc068c5543..b590e23fa03e 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -617,7 +617,7 @@ static noinline int create_subvol(struct inode *dir, return ret; } -static void btrfs_wait_nocow_write(struct btrfs_root *root) +static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root) { s64 writers; DEFINE_WAIT(wait); @@ -649,7 +649,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, atomic_inc(&root->will_be_snapshoted); smp_mb__after_atomic(); - btrfs_wait_nocow_write(root); + btrfs_wait_for_no_snapshoting_writes(root); ret = btrfs_start_delalloc_inodes(root, 0); if (ret) @@ -732,7 +732,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, free: kfree(pending_snapshot); out: - atomic_dec(&root->will_be_snapshoted); + if (atomic_dec_and_test(&root->will_be_snapshoted)) + wake_up_atomic_t(&root->will_be_snapshoted); return ret; } -- GitLab From 6b281d830f09a4f58651839030b39571dea1b56d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 24 Nov 2014 18:32:30 -0300 Subject: [PATCH 6457/9457] [media] siano: unnecessary check before rc_unregister_device() The rc_unregister_device() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 273043ea8f47..35d0e887bd65 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -107,8 +107,7 @@ int sms_ir_init(struct smscore_device_t *coredev) void sms_ir_exit(struct smscore_device_t *coredev) { - if (coredev->ir.dev) - rc_unregister_device(coredev->ir.dev); + rc_unregister_device(coredev->ir.dev); sms_log(""); } -- GitLab From cbd7584e6ead1b79fb0b81573f158b57fa1f0b49 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 11:41:49 -0500 Subject: [PATCH 6458/9457] ext4: fix block reservation for bigalloc filesystems For bigalloc filesystems we have to check whether newly requested inode block isn't already part of a cluster for which we already have delayed allocation reservation. This check happens in ext4_ext_map_blocks() and that function sets EXT4_MAP_FROM_CLUSTER if that's the case. However if ext4_da_map_blocks() finds in extent cache information about the block, we don't call into ext4_ext_map_blocks() and thus we always end up getting new reservation even if the space for cluster is already reserved. This results in overreservation and premature ENOSPC reports. Fix the problem by checking for existing cluster reservation already in ext4_da_map_blocks(). That simplifies the logic and actually allows us to get rid of the EXT4_MAP_FROM_CLUSTER flag completely. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/ext4.h | 21 +-------------------- fs/ext4/extents.c | 12 ++++-------- fs/ext4/inode.c | 27 ++++----------------------- include/trace/events/ext4.h | 3 +-- 4 files changed, 10 insertions(+), 53 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 21a3b38395ff..7b3f3b1decff 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -158,17 +158,8 @@ struct ext4_allocation_request { #define EXT4_MAP_MAPPED (1 << BH_Mapped) #define EXT4_MAP_UNWRITTEN (1 << BH_Unwritten) #define EXT4_MAP_BOUNDARY (1 << BH_Boundary) -/* Sometimes (in the bigalloc case, from ext4_da_get_block_prep) the caller of - * ext4_map_blocks wants to know whether or not the underlying cluster has - * already been accounted for. EXT4_MAP_FROM_CLUSTER conveys to the caller that - * the requested mapping was from previously mapped (or delayed allocated) - * cluster. We use BH_AllocFromCluster only for this flag. BH_AllocFromCluster - * should never appear on buffer_head's state flags. - */ -#define EXT4_MAP_FROM_CLUSTER (1 << BH_AllocFromCluster) #define EXT4_MAP_FLAGS (EXT4_MAP_NEW | EXT4_MAP_MAPPED |\ - EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY |\ - EXT4_MAP_FROM_CLUSTER) + EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY) struct ext4_map_blocks { ext4_fsblk_t m_pblk; @@ -2789,16 +2780,6 @@ extern int ext4_bio_write_page(struct ext4_io_submit *io, /* mmp.c */ extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t); -/* - * Note that these flags will never ever appear in a buffer_head's state flag. - * See EXT4_MAP_... to see where this is used. - */ -enum ext4_state_bits { - BH_AllocFromCluster /* allocated blocks were part of already - * allocated cluster. */ - = BH_JBDPrivateStart -}; - /* * Add new method to test whether block and inode bitmaps are properly * initialized. With uninit_bg reading the block from disk is not enough diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 9eae2f4916ce..7ef2f11aca56 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4282,6 +4282,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, ext4_io_end_t *io = ext4_inode_aio(inode); ext4_lblk_t cluster_offset; int set_unwritten = 0; + bool map_from_cluster = false; ext_debug("blocks %u/%u requested for inode %lu\n", map->m_lblk, map->m_len, inode->i_ino); @@ -4358,10 +4359,6 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, } } - if ((sbi->s_cluster_ratio > 1) && - ext4_find_delalloc_cluster(inode, map->m_lblk)) - map->m_flags |= EXT4_MAP_FROM_CLUSTER; - /* * requested block isn't allocated yet; * we couldn't try to create block if create flag is zero @@ -4379,7 +4376,6 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, /* * Okay, we need to do block allocation. */ - map->m_flags &= ~EXT4_MAP_FROM_CLUSTER; newex.ee_block = cpu_to_le32(map->m_lblk); cluster_offset = EXT4_LBLK_COFF(sbi, map->m_lblk); @@ -4391,7 +4387,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, get_implied_cluster_alloc(inode->i_sb, map, ex, path)) { ar.len = allocated = map->m_len; newblock = map->m_pblk; - map->m_flags |= EXT4_MAP_FROM_CLUSTER; + map_from_cluster = true; goto got_allocated_blocks; } @@ -4412,7 +4408,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, get_implied_cluster_alloc(inode->i_sb, map, ex2, path)) { ar.len = allocated = map->m_len; newblock = map->m_pblk; - map->m_flags |= EXT4_MAP_FROM_CLUSTER; + map_from_cluster = true; goto got_allocated_blocks; } @@ -4538,7 +4534,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, */ reserved_clusters = get_reserved_cluster_alloc(inode, map->m_lblk, allocated); - if (map->m_flags & EXT4_MAP_FROM_CLUSTER) { + if (map_from_cluster) { if (reserved_clusters) { /* * We have clusters reserved for this range. diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3356ab5395f4..2315e45161ee 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -416,11 +416,6 @@ static void ext4_map_blocks_es_recheck(handle_t *handle, } if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) up_read((&EXT4_I(inode)->i_data_sem)); - /* - * Clear EXT4_MAP_FROM_CLUSTER and EXT4_MAP_BOUNDARY flag - * because it shouldn't be marked in es_map->m_flags. - */ - map->m_flags &= ~(EXT4_MAP_FROM_CLUSTER | EXT4_MAP_BOUNDARY); /* * We don't check m_len because extent will be collpased in status @@ -1434,19 +1429,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, * file system block. */ down_read(&EXT4_I(inode)->i_data_sem); - if (ext4_has_inline_data(inode)) { - /* - * We will soon create blocks for this page, and let - * us pretend as if the blocks aren't allocated yet. - * In case of clusters, we have to handle the work - * of mapping from cluster so that the reserved space - * is calculated properly. - */ - if ((EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) && - ext4_find_delalloc_cluster(inode, map->m_lblk)) - map->m_flags |= EXT4_MAP_FROM_CLUSTER; + if (ext4_has_inline_data(inode)) retval = 0; - } else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) + else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) retval = ext4_ext_map_blocks(NULL, inode, map, EXT4_GET_BLOCKS_NO_PUT_HOLE); else @@ -1465,7 +1450,8 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, * then we don't need to reserve it again. However we still need * to reserve metadata for every block we're going to write. */ - if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) { + if (EXT4_SB(inode->i_sb)->s_cluster_ratio <= 1 || + !ext4_find_delalloc_cluster(inode, map->m_lblk)) { ret = ext4_da_reserve_space(inode, iblock); if (ret) { /* not enough space to reserve */ @@ -1481,11 +1467,6 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, goto out_unlock; } - /* Clear EXT4_MAP_FROM_CLUSTER flag since its purpose is served - * and it should not appear on the bh->b_state. - */ - map->m_flags &= ~EXT4_MAP_FROM_CLUSTER; - map_bh(bh, inode->i_sb, invalid_block); set_buffer_new(bh); set_buffer_delay(bh); diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index ff4bd1b35246..bb7dcbe99652 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -50,8 +50,7 @@ struct extent_status; { EXT4_MAP_NEW, "N" }, \ { EXT4_MAP_MAPPED, "M" }, \ { EXT4_MAP_UNWRITTEN, "U" }, \ - { EXT4_MAP_BOUNDARY, "B" }, \ - { EXT4_MAP_FROM_CLUSTER, "C" }) + { EXT4_MAP_BOUNDARY, "B" }) #define show_free_flags(flags) __print_flags(flags, "|", \ { EXT4_FREE_BLOCKS_METADATA, "METADATA" }, \ -- GitLab From 9cf4a281314c9345c13c7bbb5786d7b8a72553f0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 Nov 2014 19:43:29 +0300 Subject: [PATCH 6459/9457] amdkfd: delete some dead code This is dead code. We don't need to unbind here, we can just return directly. Reviewed-by: Oded Gabbay Signed-off-by: Dan Carpenter Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index a17e2dd0f489..b4f49ac13334 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -348,11 +348,6 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, if (err < 0) return ERR_PTR(err); - if (err < 0) { - amd_iommu_unbind_pasid(dev->pdev, p->pasid); - return ERR_PTR(err); - } - pdd->bound = true; return pdd; -- GitLab From 2f8e0a7c6c89f850ebd5d6c0b9a08317030d1b89 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Tue, 25 Nov 2014 11:44:37 -0500 Subject: [PATCH 6460/9457] ext4: cache extent hole in extent status tree for ext4_da_map_blocks() Currently extent status tree doesn't cache extent hole when a write looks up in extent tree to make sure whether a block has been allocated or not. In this case, we don't put extent hole in extent cache because later this extent might be removed and a new delayed extent might be added back. But it will cause a defect when we do a lot of writes. If we don't put extent hole in extent cache, the following writes also need to access extent tree to look at whether or not a block has been allocated. It brings a cache miss. This commit fixes this defect. Also if the inode doesn't have any extent, this extent hole will be cached as well. Cc: Andreas Dilger Signed-off-by: Zheng Liu Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/ext4.h | 4 +--- fs/ext4/extents.c | 31 ++++++++++++++++--------------- fs/ext4/inode.c | 6 ++---- include/trace/events/ext4.h | 3 +-- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 7b3f3b1decff..98da4cda9d18 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -556,10 +556,8 @@ enum { #define EXT4_GET_BLOCKS_KEEP_SIZE 0x0080 /* Do not take i_data_sem locking in ext4_map_blocks */ #define EXT4_GET_BLOCKS_NO_LOCK 0x0100 - /* Do not put hole in extent cache */ -#define EXT4_GET_BLOCKS_NO_PUT_HOLE 0x0200 /* Convert written extents to unwritten */ -#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN 0x0400 +#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN 0x0200 /* * The bit position of these flags must not overlap with any of the diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7ef2f11aca56..1ee24d74270f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2306,16 +2306,16 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block) { int depth = ext_depth(inode); - unsigned long len = 0; - ext4_lblk_t lblock = 0; + ext4_lblk_t len; + ext4_lblk_t lblock; struct ext4_extent *ex; + struct extent_status es; ex = path[depth].p_ext; if (ex == NULL) { - /* - * there is no extent yet, so gap is [0;-] and we - * don't cache it - */ + /* there is no extent yet, so gap is [0;-] */ + lblock = 0; + len = EXT_MAX_BLOCKS; ext_debug("cache gap(whole file):"); } else if (block < le32_to_cpu(ex->ee_block)) { lblock = block; @@ -2324,9 +2324,6 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, block, le32_to_cpu(ex->ee_block), ext4_ext_get_actual_len(ex)); - if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1)) - ext4_es_insert_extent(inode, lblock, len, ~0, - EXTENT_STATUS_HOLE); } else if (block >= le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex)) { ext4_lblk_t next; @@ -2340,14 +2337,19 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, block); BUG_ON(next == lblock); len = next - lblock; - if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1)) - ext4_es_insert_extent(inode, lblock, len, ~0, - EXTENT_STATUS_HOLE); } else { BUG(); } - ext_debug(" -> %u:%lu\n", lblock, len); + ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es); + if (es.es_len) { + /* There's delayed extent containing lblock? */ + if (es.es_lblk <= lblock) + return; + len = min(es.es_lblk - lblock, len); + } + ext_debug(" -> %u:%u\n", lblock, len); + ext4_es_insert_extent(inode, lblock, len, ~0, EXTENT_STATUS_HOLE); } /* @@ -4368,8 +4370,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, * put just found gap into cache to speed up * subsequent requests */ - if ((flags & EXT4_GET_BLOCKS_NO_PUT_HOLE) == 0) - ext4_ext_put_gap_in_cache(inode, path, map->m_lblk); + ext4_ext_put_gap_in_cache(inode, path, map->m_lblk); goto out2; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2315e45161ee..d5a46a8df70b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1432,11 +1432,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, if (ext4_has_inline_data(inode)) retval = 0; else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) - retval = ext4_ext_map_blocks(NULL, inode, map, - EXT4_GET_BLOCKS_NO_PUT_HOLE); + retval = ext4_ext_map_blocks(NULL, inode, map, 0); else - retval = ext4_ind_map_blocks(NULL, inode, map, - EXT4_GET_BLOCKS_NO_PUT_HOLE); + retval = ext4_ind_map_blocks(NULL, inode, map, 0); add_delayed: if (retval == 0) { diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index bb7dcbe99652..cd37a584ee88 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -43,8 +43,7 @@ struct extent_status; { EXT4_GET_BLOCKS_METADATA_NOFAIL, "METADATA_NOFAIL" }, \ { EXT4_GET_BLOCKS_NO_NORMALIZE, "NO_NORMALIZE" }, \ { EXT4_GET_BLOCKS_KEEP_SIZE, "KEEP_SIZE" }, \ - { EXT4_GET_BLOCKS_NO_LOCK, "NO_LOCK" }, \ - { EXT4_GET_BLOCKS_NO_PUT_HOLE, "NO_PUT_HOLE" }) + { EXT4_GET_BLOCKS_NO_LOCK, "NO_LOCK" }) #define show_mflags(flags) __print_flags(flags, "", \ { EXT4_MAP_NEW, "N" }, \ -- GitLab From edaa53cac8fd4b96ed4b8f96c4933158ff2dd337 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Tue, 25 Nov 2014 11:45:37 -0500 Subject: [PATCH 6461/9457] ext4: change LRU to round-robin in extent status tree shrinker In this commit we discard the lru algorithm for inodes with extent status tree because it takes significant effort to maintain a lru list in extent status tree shrinker and the shrinker can take a long time to scan this lru list in order to reclaim some objects. We replace the lru ordering with a simple round-robin. After that we never need to keep a lru list. That means that the list needn't be sorted if the shrinker can not reclaim any objects in the first round. Cc: Andreas Dilger Signed-off-by: Zheng Liu Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/ext4.h | 10 +- fs/ext4/extents.c | 4 +- fs/ext4/extents_status.c | 224 ++++++++++++++++-------------------- fs/ext4/extents_status.h | 7 +- fs/ext4/inode.c | 4 +- fs/ext4/ioctl.c | 4 +- fs/ext4/super.c | 7 +- include/trace/events/ext4.h | 11 +- 8 files changed, 118 insertions(+), 153 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 98da4cda9d18..ab6caf55f5bf 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -878,10 +878,9 @@ struct ext4_inode_info { /* extents status tree */ struct ext4_es_tree i_es_tree; rwlock_t i_es_lock; - struct list_head i_es_lru; + struct list_head i_es_list; unsigned int i_es_all_nr; /* protected by i_es_lock */ - unsigned int i_es_lru_nr; /* protected by i_es_lock */ - unsigned long i_touch_when; /* jiffies of last accessing */ + unsigned int i_es_shk_nr; /* protected by i_es_lock */ /* ialloc */ ext4_group_t i_last_alloc_group; @@ -1322,10 +1321,11 @@ struct ext4_sb_info { /* Reclaim extents from extent status tree */ struct shrinker s_es_shrinker; - struct list_head s_es_lru; + struct list_head s_es_list; + long s_es_nr_inode; struct ext4_es_stats s_es_stats; struct mb_cache *s_mb_cache; - spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp; + spinlock_t s_es_lock ____cacheline_aligned_in_smp; /* Ratelimit ext4 messages. */ struct ratelimit_state s_err_ratelimit_state; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1ee24d74270f..e406f66a903f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4632,7 +4632,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, trace_ext4_ext_map_blocks_exit(inode, flags, map, err ? err : allocated); - ext4_es_lru_add(inode); + ext4_es_list_add(inode); return err ? err : allocated; } @@ -5191,7 +5191,7 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, error = ext4_fill_fiemap_extents(inode, start_blk, len_blks, fieinfo); } - ext4_es_lru_add(inode); + ext4_es_list_add(inode); return error; } diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 94e7855ae71b..0193ca107396 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -149,8 +149,8 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t end); static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, int nr_to_scan); -static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, - struct ext4_inode_info *locked_ei); +static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, + struct ext4_inode_info *locked_ei); int __init ext4_init_es(void) { @@ -298,6 +298,36 @@ void ext4_es_find_delayed_extent_range(struct inode *inode, trace_ext4_es_find_delayed_extent_range_exit(inode, es); } +void ext4_es_list_add(struct inode *inode) +{ + struct ext4_inode_info *ei = EXT4_I(inode); + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + + if (!list_empty(&ei->i_es_list)) + return; + + spin_lock(&sbi->s_es_lock); + if (list_empty(&ei->i_es_list)) { + list_add_tail(&ei->i_es_list, &sbi->s_es_list); + sbi->s_es_nr_inode++; + } + spin_unlock(&sbi->s_es_lock); +} + +void ext4_es_list_del(struct inode *inode) +{ + struct ext4_inode_info *ei = EXT4_I(inode); + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + + spin_lock(&sbi->s_es_lock); + if (!list_empty(&ei->i_es_list)) { + list_del_init(&ei->i_es_list); + sbi->s_es_nr_inode--; + WARN_ON_ONCE(sbi->s_es_nr_inode < 0); + } + spin_unlock(&sbi->s_es_lock); +} + static struct extent_status * ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, ext4_fsblk_t pblk) @@ -314,9 +344,9 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, * We don't count delayed extent because we never try to reclaim them */ if (!ext4_es_is_delayed(es)) { - EXT4_I(inode)->i_es_lru_nr++; + EXT4_I(inode)->i_es_shk_nr++; percpu_counter_inc(&EXT4_SB(inode->i_sb)-> - s_es_stats.es_stats_lru_cnt); + s_es_stats.es_stats_shk_cnt); } EXT4_I(inode)->i_es_all_nr++; @@ -330,12 +360,12 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) EXT4_I(inode)->i_es_all_nr--; percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt); - /* Decrease the lru counter when this es is not delayed */ + /* Decrease the shrink counter when this es is not delayed */ if (!ext4_es_is_delayed(es)) { - BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0); - EXT4_I(inode)->i_es_lru_nr--; + BUG_ON(EXT4_I(inode)->i_es_shk_nr == 0); + EXT4_I(inode)->i_es_shk_nr--; percpu_counter_dec(&EXT4_SB(inode->i_sb)-> - s_es_stats.es_stats_lru_cnt); + s_es_stats.es_stats_shk_cnt); } kmem_cache_free(ext4_es_cachep, es); @@ -683,8 +713,8 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, goto error; retry: err = __es_insert_extent(inode, &newes); - if (err == -ENOMEM && __ext4_es_shrink(EXT4_SB(inode->i_sb), 1, - EXT4_I(inode))) + if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb), + 1, EXT4_I(inode))) goto retry; if (err == -ENOMEM && !ext4_es_is_delayed(&newes)) err = 0; @@ -841,8 +871,8 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, es->es_lblk = orig_es.es_lblk; es->es_len = orig_es.es_len; if ((err == -ENOMEM) && - __ext4_es_shrink(EXT4_SB(inode->i_sb), 1, - EXT4_I(inode))) + __es_shrink(EXT4_SB(inode->i_sb), + 1, EXT4_I(inode))) goto retry; goto out; } @@ -914,6 +944,11 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, end = lblk + len - 1; BUG_ON(end < lblk); + /* + * ext4_clear_inode() depends on us taking i_es_lock unconditionally + * so that we are sure __es_shrink() is done with the inode before it + * is reclaimed. + */ write_lock(&EXT4_I(inode)->i_es_lock); err = __es_remove_extent(inode, lblk, end); write_unlock(&EXT4_I(inode)->i_es_lock); @@ -921,114 +956,80 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, return err; } -static int ext4_inode_touch_time_cmp(void *priv, struct list_head *a, - struct list_head *b) -{ - struct ext4_inode_info *eia, *eib; - eia = list_entry(a, struct ext4_inode_info, i_es_lru); - eib = list_entry(b, struct ext4_inode_info, i_es_lru); - - if (ext4_test_inode_state(&eia->vfs_inode, EXT4_STATE_EXT_PRECACHED) && - !ext4_test_inode_state(&eib->vfs_inode, EXT4_STATE_EXT_PRECACHED)) - return 1; - if (!ext4_test_inode_state(&eia->vfs_inode, EXT4_STATE_EXT_PRECACHED) && - ext4_test_inode_state(&eib->vfs_inode, EXT4_STATE_EXT_PRECACHED)) - return -1; - if (eia->i_touch_when == eib->i_touch_when) - return 0; - if (time_after(eia->i_touch_when, eib->i_touch_when)) - return 1; - else - return -1; -} - -static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, - struct ext4_inode_info *locked_ei) +static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, + struct ext4_inode_info *locked_ei) { struct ext4_inode_info *ei; struct ext4_es_stats *es_stats; - struct list_head *cur, *tmp; - LIST_HEAD(skipped); ktime_t start_time; u64 scan_time; + int nr_to_walk; int nr_shrunk = 0; - int retried = 0, skip_precached = 1, nr_skipped = 0; + int retried = 0, nr_skipped = 0; es_stats = &sbi->s_es_stats; start_time = ktime_get(); - spin_lock(&sbi->s_es_lru_lock); retry: - list_for_each_safe(cur, tmp, &sbi->s_es_lru) { + spin_lock(&sbi->s_es_lock); + nr_to_walk = sbi->s_es_nr_inode; + while (nr_to_walk-- > 0) { int shrunk; - /* - * If we have already reclaimed all extents from extent - * status tree, just stop the loop immediately. - */ - if (percpu_counter_read_positive( - &es_stats->es_stats_lru_cnt) == 0) - break; - - ei = list_entry(cur, struct ext4_inode_info, i_es_lru); + if (list_empty(&sbi->s_es_list)) { + spin_unlock(&sbi->s_es_lock); + goto out; + } + ei = list_first_entry(&sbi->s_es_list, struct ext4_inode_info, + i_es_list); + /* Move the inode to the tail */ + list_move(&ei->i_es_list, sbi->s_es_list.prev); /* - * Skip the inode that is newer than the last_sorted - * time. Normally we try hard to avoid shrinking - * precached inodes, but we will as a last resort. + * Normally we try hard to avoid shrinking precached inodes, + * but we will as a last resort. */ - if ((es_stats->es_stats_last_sorted < ei->i_touch_when) || - (skip_precached && ext4_test_inode_state(&ei->vfs_inode, - EXT4_STATE_EXT_PRECACHED))) { + if (!retried && ext4_test_inode_state(&ei->vfs_inode, + EXT4_STATE_EXT_PRECACHED)) { nr_skipped++; - list_move_tail(cur, &skipped); continue; } - if (ei->i_es_lru_nr == 0 || ei == locked_ei || - !write_trylock(&ei->i_es_lock)) + if (ei == locked_ei || !write_trylock(&ei->i_es_lock)) { + nr_skipped++; continue; + } + /* + * Now we hold i_es_lock which protects us from inode reclaim + * freeing inode under us + */ + spin_unlock(&sbi->s_es_lock); shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan); - if (ei->i_es_lru_nr == 0) - list_del_init(&ei->i_es_lru); write_unlock(&ei->i_es_lock); nr_shrunk += shrunk; nr_to_scan -= shrunk; + if (nr_to_scan == 0) - break; + goto out; + spin_lock(&sbi->s_es_lock); } - - /* Move the newer inodes into the tail of the LRU list. */ - list_splice_tail(&skipped, &sbi->s_es_lru); - INIT_LIST_HEAD(&skipped); + spin_unlock(&sbi->s_es_lock); /* * If we skipped any inodes, and we weren't able to make any - * forward progress, sort the list and try again. + * forward progress, try again to scan precached inodes. */ if ((nr_shrunk == 0) && nr_skipped && !retried) { retried++; - list_sort(NULL, &sbi->s_es_lru, ext4_inode_touch_time_cmp); - es_stats->es_stats_last_sorted = jiffies; - ei = list_first_entry(&sbi->s_es_lru, struct ext4_inode_info, - i_es_lru); - /* - * If there are no non-precached inodes left on the - * list, start releasing precached extents. - */ - if (ext4_test_inode_state(&ei->vfs_inode, - EXT4_STATE_EXT_PRECACHED)) - skip_precached = 0; goto retry; } - spin_unlock(&sbi->s_es_lru_lock); - if (locked_ei && nr_shrunk == 0) nr_shrunk = __es_try_to_reclaim_extents(locked_ei, nr_to_scan); +out: scan_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); if (likely(es_stats->es_stats_scan_time)) es_stats->es_stats_scan_time = (scan_time + @@ -1043,7 +1044,7 @@ static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, else es_stats->es_stats_shrunk = nr_shrunk; - trace_ext4_es_shrink(sbi->s_sb, nr_shrunk, scan_time, skip_precached, + trace_ext4_es_shrink(sbi->s_sb, nr_shrunk, scan_time, nr_skipped, retried); return nr_shrunk; } @@ -1055,7 +1056,7 @@ static unsigned long ext4_es_count(struct shrinker *shrink, struct ext4_sb_info *sbi; sbi = container_of(shrink, struct ext4_sb_info, s_es_shrinker); - nr = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_lru_cnt); + nr = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt); trace_ext4_es_shrink_count(sbi->s_sb, sc->nr_to_scan, nr); return nr; } @@ -1068,13 +1069,13 @@ static unsigned long ext4_es_scan(struct shrinker *shrink, int nr_to_scan = sc->nr_to_scan; int ret, nr_shrunk; - ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_lru_cnt); + ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt); trace_ext4_es_shrink_scan_enter(sbi->s_sb, nr_to_scan, ret); if (!nr_to_scan) return ret; - nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL); + nr_shrunk = __es_shrink(sbi, nr_to_scan, NULL); trace_ext4_es_shrink_scan_exit(sbi->s_sb, nr_shrunk, ret); return nr_shrunk; @@ -1102,28 +1103,24 @@ static int ext4_es_seq_shrinker_info_show(struct seq_file *seq, void *v) return 0; /* here we just find an inode that has the max nr. of objects */ - spin_lock(&sbi->s_es_lru_lock); - list_for_each_entry(ei, &sbi->s_es_lru, i_es_lru) { + spin_lock(&sbi->s_es_lock); + list_for_each_entry(ei, &sbi->s_es_list, i_es_list) { inode_cnt++; if (max && max->i_es_all_nr < ei->i_es_all_nr) max = ei; else if (!max) max = ei; } - spin_unlock(&sbi->s_es_lru_lock); + spin_unlock(&sbi->s_es_lock); seq_printf(seq, "stats:\n %lld objects\n %lld reclaimable objects\n", percpu_counter_sum_positive(&es_stats->es_stats_all_cnt), - percpu_counter_sum_positive(&es_stats->es_stats_lru_cnt)); + percpu_counter_sum_positive(&es_stats->es_stats_shk_cnt)); seq_printf(seq, " %lu/%lu cache hits/misses\n", es_stats->es_stats_cache_hits, es_stats->es_stats_cache_misses); - if (es_stats->es_stats_last_sorted != 0) - seq_printf(seq, " %u ms last sorted interval\n", - jiffies_to_msecs(jiffies - - es_stats->es_stats_last_sorted)); if (inode_cnt) - seq_printf(seq, " %d inodes on lru list\n", inode_cnt); + seq_printf(seq, " %d inodes on list\n", inode_cnt); seq_printf(seq, "average:\n %llu us scan time\n", div_u64(es_stats->es_stats_scan_time, 1000)); @@ -1132,7 +1129,7 @@ static int ext4_es_seq_shrinker_info_show(struct seq_file *seq, void *v) seq_printf(seq, "maximum:\n %lu inode (%u objects, %u reclaimable)\n" " %llu us max scan time\n", - max->vfs_inode.i_ino, max->i_es_all_nr, max->i_es_lru_nr, + max->vfs_inode.i_ino, max->i_es_all_nr, max->i_es_shk_nr, div_u64(es_stats->es_stats_max_scan_time, 1000)); return 0; @@ -1181,9 +1178,9 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi) { int err; - INIT_LIST_HEAD(&sbi->s_es_lru); - spin_lock_init(&sbi->s_es_lru_lock); - sbi->s_es_stats.es_stats_last_sorted = 0; + INIT_LIST_HEAD(&sbi->s_es_list); + sbi->s_es_nr_inode = 0; + spin_lock_init(&sbi->s_es_lock); sbi->s_es_stats.es_stats_shrunk = 0; sbi->s_es_stats.es_stats_cache_hits = 0; sbi->s_es_stats.es_stats_cache_misses = 0; @@ -1192,7 +1189,7 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi) err = percpu_counter_init(&sbi->s_es_stats.es_stats_all_cnt, 0, GFP_KERNEL); if (err) return err; - err = percpu_counter_init(&sbi->s_es_stats.es_stats_lru_cnt, 0, GFP_KERNEL); + err = percpu_counter_init(&sbi->s_es_stats.es_stats_shk_cnt, 0, GFP_KERNEL); if (err) goto err1; @@ -1210,7 +1207,7 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi) return 0; err2: - percpu_counter_destroy(&sbi->s_es_stats.es_stats_lru_cnt); + percpu_counter_destroy(&sbi->s_es_stats.es_stats_shk_cnt); err1: percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt); return err; @@ -1221,37 +1218,10 @@ void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi) if (sbi->s_proc) remove_proc_entry("es_shrinker_info", sbi->s_proc); percpu_counter_destroy(&sbi->s_es_stats.es_stats_all_cnt); - percpu_counter_destroy(&sbi->s_es_stats.es_stats_lru_cnt); + percpu_counter_destroy(&sbi->s_es_stats.es_stats_shk_cnt); unregister_shrinker(&sbi->s_es_shrinker); } -void ext4_es_lru_add(struct inode *inode) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - - ei->i_touch_when = jiffies; - - if (!list_empty(&ei->i_es_lru)) - return; - - spin_lock(&sbi->s_es_lru_lock); - if (list_empty(&ei->i_es_lru)) - list_add_tail(&ei->i_es_lru, &sbi->s_es_lru); - spin_unlock(&sbi->s_es_lru_lock); -} - -void ext4_es_lru_del(struct inode *inode) -{ - struct ext4_inode_info *ei = EXT4_I(inode); - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - - spin_lock(&sbi->s_es_lru_lock); - if (!list_empty(&ei->i_es_lru)) - list_del_init(&ei->i_es_lru); - spin_unlock(&sbi->s_es_lru_lock); -} - static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, int nr_to_scan) { @@ -1263,7 +1233,7 @@ static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - if (ei->i_es_lru_nr == 0) + if (ei->i_es_shk_nr == 0) return 0; if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED) && diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index efd5f970b501..0e6a33e81e5f 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h @@ -65,14 +65,13 @@ struct ext4_es_tree { }; struct ext4_es_stats { - unsigned long es_stats_last_sorted; unsigned long es_stats_shrunk; unsigned long es_stats_cache_hits; unsigned long es_stats_cache_misses; u64 es_stats_scan_time; u64 es_stats_max_scan_time; struct percpu_counter es_stats_all_cnt; - struct percpu_counter es_stats_lru_cnt; + struct percpu_counter es_stats_shk_cnt; }; extern int __init ext4_init_es(void); @@ -151,7 +150,7 @@ static inline void ext4_es_store_pblock_status(struct extent_status *es, extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi); extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi); -extern void ext4_es_lru_add(struct inode *inode); -extern void ext4_es_lru_del(struct inode *inode); +extern void ext4_es_list_add(struct inode *inode); +extern void ext4_es_list_del(struct inode *inode); #endif /* _EXT4_EXTENTS_STATUS_H */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d5a46a8df70b..540b0b0481a5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -486,7 +486,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { - ext4_es_lru_add(inode); + ext4_es_list_add(inode); if (ext4_es_is_written(&es) || ext4_es_is_unwritten(&es)) { map->m_pblk = ext4_es_pblock(&es) + map->m_lblk - es.es_lblk; @@ -1388,7 +1388,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, iblock, &es)) { - ext4_es_lru_add(inode); + ext4_es_list_add(inode); if (ext4_es_is_hole(&es)) { retval = 0; down_read(&EXT4_I(inode)->i_data_sem); diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bfda18a15592..7b377c41dd81 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -78,8 +78,8 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); - ext4_es_lru_del(inode1); - ext4_es_lru_del(inode2); + ext4_es_list_del(inode1); + ext4_es_list_del(inode2); isize = i_size_read(inode1); i_size_write(inode1, i_size_read(inode2)); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4b79f39ebf66..32df08e99ca9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -871,10 +871,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) spin_lock_init(&ei->i_prealloc_lock); ext4_es_init_tree(&ei->i_es_tree); rwlock_init(&ei->i_es_lock); - INIT_LIST_HEAD(&ei->i_es_lru); + INIT_LIST_HEAD(&ei->i_es_list); ei->i_es_all_nr = 0; - ei->i_es_lru_nr = 0; - ei->i_touch_when = 0; + ei->i_es_shk_nr = 0; ei->i_reserved_data_blocks = 0; ei->i_reserved_meta_blocks = 0; ei->i_allocated_meta_blocks = 0; @@ -963,7 +962,7 @@ void ext4_clear_inode(struct inode *inode) dquot_drop(inode); ext4_discard_preallocations(inode); ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS); - ext4_es_lru_del(inode); + ext4_es_list_del(inode); if (EXT4_I(inode)->jinode) { jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode), EXT4_I(inode)->jinode); diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index cd37a584ee88..6cfb841fea7c 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -2450,15 +2450,14 @@ TRACE_EVENT(ext4_collapse_range, TRACE_EVENT(ext4_es_shrink, TP_PROTO(struct super_block *sb, int nr_shrunk, u64 scan_time, - int skip_precached, int nr_skipped, int retried), + int nr_skipped, int retried), - TP_ARGS(sb, nr_shrunk, scan_time, skip_precached, nr_skipped, retried), + TP_ARGS(sb, nr_shrunk, scan_time, nr_skipped, retried), TP_STRUCT__entry( __field( dev_t, dev ) __field( int, nr_shrunk ) __field( unsigned long long, scan_time ) - __field( int, skip_precached ) __field( int, nr_skipped ) __field( int, retried ) ), @@ -2467,16 +2466,14 @@ TRACE_EVENT(ext4_es_shrink, __entry->dev = sb->s_dev; __entry->nr_shrunk = nr_shrunk; __entry->scan_time = div_u64(scan_time, 1000); - __entry->skip_precached = skip_precached; __entry->nr_skipped = nr_skipped; __entry->retried = retried; ), - TP_printk("dev %d,%d nr_shrunk %d, scan_time %llu skip_precached %d " + TP_printk("dev %d,%d nr_shrunk %d, scan_time %llu " "nr_skipped %d retried %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->nr_shrunk, - __entry->scan_time, __entry->skip_precached, - __entry->nr_skipped, __entry->retried) + __entry->scan_time, __entry->nr_skipped, __entry->retried) ); #endif /* _TRACE_EXT4_H */ -- GitLab From b0dea4c1651f3cdb6d17604fa473e72cb74cdc6b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 11:49:25 -0500 Subject: [PATCH 6462/9457] ext4: move handling of list of shrinkable inodes into extent status code Currently callers adding extents to extent status tree were responsible for adding the inode to the list of inodes with freeable extents. This is error prone and puts list handling in unnecessarily many places. Just add inode to the list automatically when the first non-delay extent is added to the tree and remove inode from the list when the last non-delay extent is removed. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 2 -- fs/ext4/extents_status.c | 10 ++++++---- fs/ext4/extents_status.h | 2 -- fs/ext4/inode.c | 2 -- fs/ext4/ioctl.c | 2 -- fs/ext4/super.c | 1 - 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e406f66a903f..e2424bafd6fe 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4632,7 +4632,6 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, trace_ext4_ext_map_blocks_exit(inode, flags, map, err ? err : allocated); - ext4_es_list_add(inode); return err ? err : allocated; } @@ -5191,7 +5190,6 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, error = ext4_fill_fiemap_extents(inode, start_blk, len_blks, fieinfo); } - ext4_es_list_add(inode); return error; } diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 0193ca107396..de2d9d8bf22f 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -298,7 +298,7 @@ void ext4_es_find_delayed_extent_range(struct inode *inode, trace_ext4_es_find_delayed_extent_range_exit(inode, es); } -void ext4_es_list_add(struct inode *inode) +static void ext4_es_list_add(struct inode *inode) { struct ext4_inode_info *ei = EXT4_I(inode); struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); @@ -314,7 +314,7 @@ void ext4_es_list_add(struct inode *inode) spin_unlock(&sbi->s_es_lock); } -void ext4_es_list_del(struct inode *inode) +static void ext4_es_list_del(struct inode *inode) { struct ext4_inode_info *ei = EXT4_I(inode); struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); @@ -344,7 +344,8 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, * We don't count delayed extent because we never try to reclaim them */ if (!ext4_es_is_delayed(es)) { - EXT4_I(inode)->i_es_shk_nr++; + if (!EXT4_I(inode)->i_es_shk_nr++) + ext4_es_list_add(inode); percpu_counter_inc(&EXT4_SB(inode->i_sb)-> s_es_stats.es_stats_shk_cnt); } @@ -363,7 +364,8 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) /* Decrease the shrink counter when this es is not delayed */ if (!ext4_es_is_delayed(es)) { BUG_ON(EXT4_I(inode)->i_es_shk_nr == 0); - EXT4_I(inode)->i_es_shk_nr--; + if (!--EXT4_I(inode)->i_es_shk_nr) + ext4_es_list_del(inode); percpu_counter_dec(&EXT4_SB(inode->i_sb)-> s_es_stats.es_stats_shk_cnt); } diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index 0e6a33e81e5f..b0b78b95f481 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h @@ -150,7 +150,5 @@ static inline void ext4_es_store_pblock_status(struct extent_status *es, extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi); extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi); -extern void ext4_es_list_add(struct inode *inode); -extern void ext4_es_list_del(struct inode *inode); #endif /* _EXT4_EXTENTS_STATUS_H */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 540b0b0481a5..b416b461fa50 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -486,7 +486,6 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { - ext4_es_list_add(inode); if (ext4_es_is_written(&es) || ext4_es_is_unwritten(&es)) { map->m_pblk = ext4_es_pblock(&es) + map->m_lblk - es.es_lblk; @@ -1388,7 +1387,6 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, iblock, &es)) { - ext4_es_list_add(inode); if (ext4_es_is_hole(&es)) { retval = 0; down_read(&EXT4_I(inode)->i_data_sem); diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 7b377c41dd81..f58a0d106726 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -78,8 +78,6 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); - ext4_es_list_del(inode1); - ext4_es_list_del(inode2); isize = i_size_read(inode1); i_size_write(inode1, i_size_read(inode2)); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 32df08e99ca9..e2a17f8b7adc 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -962,7 +962,6 @@ void ext4_clear_inode(struct inode *inode) dquot_drop(inode); ext4_discard_preallocations(inode); ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS); - ext4_es_list_del(inode); if (EXT4_I(inode)->jinode) { jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode), EXT4_I(inode)->jinode); -- GitLab From dd4759255188771e60cf3455982959a1ba04f4eb Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 11:51:23 -0500 Subject: [PATCH 6463/9457] ext4: limit number of scanned extents in status tree shrinker Currently we scan extent status trees of inodes until we reclaim nr_to_scan extents. This can however require a lot of scanning when there are lots of delayed extents (as those cannot be reclaimed). Change shrinker to work as shrinkers are supposed to and *scan* only nr_to_scan extents regardless of how many extents did we actually reclaim. We however need to be careful and avoid scanning each status tree from the beginning - that could lead to a situation where we would not be able to reclaim anything at all when first nr_to_scan extents in the tree are always unreclaimable. We remember with each inode offset where we stopped scanning and continue from there when we next come across the inode. Note that we also need to update places calling __es_shrink() manually to pass reasonable nr_to_scan to have a chance of reclaiming anything and not just 1. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/ext4.h | 5 ++- fs/ext4/extents_status.c | 91 ++++++++++++++++++++++++++-------------- fs/ext4/super.c | 1 + 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ab6caf55f5bf..4186ec84f835 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -881,6 +881,9 @@ struct ext4_inode_info { struct list_head i_es_list; unsigned int i_es_all_nr; /* protected by i_es_lock */ unsigned int i_es_shk_nr; /* protected by i_es_lock */ + ext4_lblk_t i_es_shrink_lblk; /* Offset where we start searching for + extents to shrink. Protected by + i_es_lock */ /* ialloc */ ext4_group_t i_last_alloc_group; @@ -1321,7 +1324,7 @@ struct ext4_sb_info { /* Reclaim extents from extent status tree */ struct shrinker s_es_shrinker; - struct list_head s_es_list; + struct list_head s_es_list; /* List of inodes with reclaimable extents */ long s_es_nr_inode; struct ext4_es_stats s_es_stats; struct mb_cache *s_mb_cache; diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index de2d9d8bf22f..8f2aac4006d2 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -147,8 +147,7 @@ static struct kmem_cache *ext4_es_cachep; static int __es_insert_extent(struct inode *inode, struct extent_status *newes); static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t end); -static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, - int nr_to_scan); +static int es_reclaim_extents(struct ext4_inode_info *ei, int *nr_to_scan); static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, struct ext4_inode_info *locked_ei); @@ -716,7 +715,7 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, retry: err = __es_insert_extent(inode, &newes); if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb), - 1, EXT4_I(inode))) + 128, EXT4_I(inode))) goto retry; if (err == -ENOMEM && !ext4_es_is_delayed(&newes)) err = 0; @@ -874,7 +873,7 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, es->es_len = orig_es.es_len; if ((err == -ENOMEM) && __es_shrink(EXT4_SB(inode->i_sb), - 1, EXT4_I(inode))) + 128, EXT4_I(inode))) goto retry; goto out; } @@ -976,8 +975,6 @@ static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, spin_lock(&sbi->s_es_lock); nr_to_walk = sbi->s_es_nr_inode; while (nr_to_walk-- > 0) { - int shrunk; - if (list_empty(&sbi->s_es_list)) { spin_unlock(&sbi->s_es_lock); goto out; @@ -985,7 +982,7 @@ static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, ei = list_first_entry(&sbi->s_es_list, struct ext4_inode_info, i_es_list); /* Move the inode to the tail */ - list_move(&ei->i_es_list, sbi->s_es_list.prev); + list_move_tail(&ei->i_es_list, &sbi->s_es_list); /* * Normally we try hard to avoid shrinking precached inodes, @@ -1007,13 +1004,10 @@ static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, */ spin_unlock(&sbi->s_es_lock); - shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan); + nr_shrunk += es_reclaim_extents(ei, &nr_to_scan); write_unlock(&ei->i_es_lock); - nr_shrunk += shrunk; - nr_to_scan -= shrunk; - - if (nr_to_scan == 0) + if (nr_to_scan <= 0) goto out; spin_lock(&sbi->s_es_lock); } @@ -1029,7 +1023,7 @@ static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, } if (locked_ei && nr_shrunk == 0) - nr_shrunk = __es_try_to_reclaim_extents(locked_ei, nr_to_scan); + nr_shrunk = es_reclaim_extents(locked_ei, &nr_to_scan); out: scan_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); @@ -1224,27 +1218,33 @@ void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi) unregister_shrinker(&sbi->s_es_shrinker); } -static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, - int nr_to_scan) +/* + * Shrink extents in given inode from ei->i_es_shrink_lblk till end. Scan at + * most *nr_to_scan extents, update *nr_to_scan accordingly. + * + * Return 0 if we hit end of tree / interval, 1 if we exhausted nr_to_scan. + * Increment *nr_shrunk by the number of reclaimed extents. Also update + * ei->i_es_shrink_lblk to where we should continue scanning. + */ +static int es_do_reclaim_extents(struct ext4_inode_info *ei, ext4_lblk_t end, + int *nr_to_scan, int *nr_shrunk) { struct inode *inode = &ei->vfs_inode; struct ext4_es_tree *tree = &ei->i_es_tree; - struct rb_node *node; struct extent_status *es; - unsigned long nr_shrunk = 0; - static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, - DEFAULT_RATELIMIT_BURST); - - if (ei->i_es_shk_nr == 0) - return 0; + struct rb_node *node; - if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED) && - __ratelimit(&_rs)) - ext4_warning(inode->i_sb, "forced shrink of precached extents"); + es = __es_tree_search(&tree->root, ei->i_es_shrink_lblk); + if (!es) + goto out_wrap; + node = &es->rb_node; + while (*nr_to_scan > 0) { + if (es->es_lblk > end) { + ei->i_es_shrink_lblk = end + 1; + return 0; + } - node = rb_first(&tree->root); - while (node != NULL) { - es = rb_entry(node, struct extent_status, rb_node); + (*nr_to_scan)--; node = rb_next(&es->rb_node); /* * We can't reclaim delayed extent from status tree because @@ -1253,11 +1253,38 @@ static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, if (!ext4_es_is_delayed(es)) { rb_erase(&es->rb_node, &tree->root); ext4_es_free_extent(inode, es); - nr_shrunk++; - if (--nr_to_scan == 0) - break; + (*nr_shrunk)++; } + if (!node) + goto out_wrap; + es = rb_entry(node, struct extent_status, rb_node); } - tree->cache_es = NULL; + ei->i_es_shrink_lblk = es->es_lblk; + return 1; +out_wrap: + ei->i_es_shrink_lblk = 0; + return 0; +} + +static int es_reclaim_extents(struct ext4_inode_info *ei, int *nr_to_scan) +{ + struct inode *inode = &ei->vfs_inode; + int nr_shrunk = 0; + ext4_lblk_t start = ei->i_es_shrink_lblk; + static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + + if (ei->i_es_shk_nr == 0) + return 0; + + if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED) && + __ratelimit(&_rs)) + ext4_warning(inode->i_sb, "forced shrink of precached extents"); + + if (!es_do_reclaim_extents(ei, EXT_MAX_BLOCKS, nr_to_scan, &nr_shrunk) && + start != 0) + es_do_reclaim_extents(ei, start - 1, nr_to_scan, &nr_shrunk); + + ei->i_es_tree.cache_es = NULL; return nr_shrunk; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e2a17f8b7adc..48318497e8e9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -874,6 +874,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&ei->i_es_list); ei->i_es_all_nr = 0; ei->i_es_shk_nr = 0; + ei->i_es_shrink_lblk = 0; ei->i_reserved_data_blocks = 0; ei->i_reserved_meta_blocks = 0; ei->i_allocated_meta_blocks = 0; -- GitLab From 624d0f1dd7c80d2bac4fc3066b2ff3947f890883 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 11:53:47 -0500 Subject: [PATCH 6464/9457] ext4: cleanup flag definitions for extent status tree Currently flags for extent status tree are defined twice, once shifted and once without a being shifted. Consolidate these definitions into one place and make some computations automatic to make adding flags less error prone. Compiler should be clever enough to figure out these are constants and generate the same code. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/extents_status.c | 2 ++ fs/ext4/extents_status.h | 58 ++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 8f2aac4006d2..30596498ed0b 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -1174,6 +1174,8 @@ int ext4_es_register_shrinker(struct ext4_sb_info *sbi) { int err; + /* Make sure we have enough bits for physical block number */ + BUILD_BUG_ON(ES_SHIFT < 48); INIT_LIST_HEAD(&sbi->s_es_list); sbi->s_es_nr_inode = 0; spin_lock_init(&sbi->s_es_lock); diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index b0b78b95f481..e86b1f34cfec 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h @@ -29,25 +29,21 @@ /* * These flags live in the high bits of extent_status.es_pblk */ -#define ES_SHIFT 60 - -#define EXTENT_STATUS_WRITTEN (1 << 3) -#define EXTENT_STATUS_UNWRITTEN (1 << 2) -#define EXTENT_STATUS_DELAYED (1 << 1) -#define EXTENT_STATUS_HOLE (1 << 0) - -#define EXTENT_STATUS_FLAGS (EXTENT_STATUS_WRITTEN | \ - EXTENT_STATUS_UNWRITTEN | \ - EXTENT_STATUS_DELAYED | \ - EXTENT_STATUS_HOLE) +enum { + ES_WRITTEN_B, + ES_UNWRITTEN_B, + ES_DELAYED_B, + ES_HOLE_B, + ES_FLAGS +}; -#define ES_WRITTEN (1ULL << 63) -#define ES_UNWRITTEN (1ULL << 62) -#define ES_DELAYED (1ULL << 61) -#define ES_HOLE (1ULL << 60) +#define ES_SHIFT (sizeof(ext4_fsblk_t)*8 - ES_FLAGS) +#define ES_MASK (~((ext4_fsblk_t)0) << ES_SHIFT) -#define ES_MASK (ES_WRITTEN | ES_UNWRITTEN | \ - ES_DELAYED | ES_HOLE) +#define EXTENT_STATUS_WRITTEN (1 << ES_WRITTEN_B) +#define EXTENT_STATUS_UNWRITTEN (1 << ES_UNWRITTEN_B) +#define EXTENT_STATUS_DELAYED (1 << ES_DELAYED_B) +#define EXTENT_STATUS_HOLE (1 << ES_HOLE_B) struct ext4_sb_info; struct ext4_extent; @@ -92,29 +88,29 @@ extern void ext4_es_find_delayed_extent_range(struct inode *inode, extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, struct extent_status *es); +static inline unsigned int ext4_es_status(struct extent_status *es) +{ + return es->es_pblk >> ES_SHIFT; +} + static inline int ext4_es_is_written(struct extent_status *es) { - return (es->es_pblk & ES_WRITTEN) != 0; + return (ext4_es_status(es) & EXTENT_STATUS_WRITTEN) != 0; } static inline int ext4_es_is_unwritten(struct extent_status *es) { - return (es->es_pblk & ES_UNWRITTEN) != 0; + return (ext4_es_status(es) & EXTENT_STATUS_UNWRITTEN) != 0; } static inline int ext4_es_is_delayed(struct extent_status *es) { - return (es->es_pblk & ES_DELAYED) != 0; + return (ext4_es_status(es) & EXTENT_STATUS_DELAYED) != 0; } static inline int ext4_es_is_hole(struct extent_status *es) { - return (es->es_pblk & ES_HOLE) != 0; -} - -static inline unsigned int ext4_es_status(struct extent_status *es) -{ - return es->es_pblk >> ES_SHIFT; + return (ext4_es_status(es) & EXTENT_STATUS_HOLE) != 0; } static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es) @@ -134,18 +130,16 @@ static inline void ext4_es_store_pblock(struct extent_status *es, static inline void ext4_es_store_status(struct extent_status *es, unsigned int status) { - es->es_pblk = (((ext4_fsblk_t) - (status & EXTENT_STATUS_FLAGS) << ES_SHIFT) | - (es->es_pblk & ~ES_MASK)); + es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) | + (es->es_pblk & ~ES_MASK); } static inline void ext4_es_store_pblock_status(struct extent_status *es, ext4_fsblk_t pb, unsigned int status) { - es->es_pblk = (((ext4_fsblk_t) - (status & EXTENT_STATUS_FLAGS) << ES_SHIFT) | - (pb & ~ES_MASK)); + es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) | + (pb & ~ES_MASK); } extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi); -- GitLab From 2be12de98a1cc21c4de4e2d6fb2bf5aa0a279947 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 11:55:24 -0500 Subject: [PATCH 6465/9457] ext4: introduce aging to extent status tree Introduce a simple aging to extent status tree. Each extent has a REFERENCED bit which gets set when the extent is used. Shrinker then skips entries with referenced bit set and clears the bit. Thus frequently used extents have higher chances of staying in memory. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/extents_status.c | 22 +++++++++++++++++----- fs/ext4/extents_status.h | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 30596498ed0b..e04d45733976 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -382,7 +382,7 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) static int ext4_es_can_be_merged(struct extent_status *es1, struct extent_status *es2) { - if (ext4_es_status(es1) != ext4_es_status(es2)) + if (ext4_es_type(es1) != ext4_es_type(es2)) return 0; if (((__u64) es1->es_len) + es2->es_len > EXT_MAX_BLOCKS) { @@ -425,6 +425,8 @@ ext4_es_try_to_merge_left(struct inode *inode, struct extent_status *es) es1 = rb_entry(node, struct extent_status, rb_node); if (ext4_es_can_be_merged(es1, es)) { es1->es_len += es->es_len; + if (ext4_es_is_referenced(es)) + ext4_es_set_referenced(es1); rb_erase(&es->rb_node, &tree->root); ext4_es_free_extent(inode, es); es = es1; @@ -447,6 +449,8 @@ ext4_es_try_to_merge_right(struct inode *inode, struct extent_status *es) es1 = rb_entry(node, struct extent_status, rb_node); if (ext4_es_can_be_merged(es, es1)) { es->es_len += es1->es_len; + if (ext4_es_is_referenced(es1)) + ext4_es_set_referenced(es); rb_erase(node, &tree->root); ext4_es_free_extent(inode, es1); } @@ -813,6 +817,8 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, es->es_lblk = es1->es_lblk; es->es_len = es1->es_len; es->es_pblk = es1->es_pblk; + if (!ext4_es_is_referenced(es)) + ext4_es_set_referenced(es); stats->es_stats_cache_hits++; } else { stats->es_stats_cache_misses++; @@ -1252,11 +1258,17 @@ static int es_do_reclaim_extents(struct ext4_inode_info *ei, ext4_lblk_t end, * We can't reclaim delayed extent from status tree because * fiemap, bigallic, and seek_data/hole need to use it. */ - if (!ext4_es_is_delayed(es)) { - rb_erase(&es->rb_node, &tree->root); - ext4_es_free_extent(inode, es); - (*nr_shrunk)++; + if (ext4_es_is_delayed(es)) + goto next; + if (ext4_es_is_referenced(es)) { + ext4_es_clear_referenced(es); + goto next; } + + rb_erase(&es->rb_node, &tree->root); + ext4_es_free_extent(inode, es); + (*nr_shrunk)++; +next: if (!node) goto out_wrap; es = rb_entry(node, struct extent_status, rb_node); diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index e86b1f34cfec..691b52613ce4 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h @@ -34,6 +34,7 @@ enum { ES_UNWRITTEN_B, ES_DELAYED_B, ES_HOLE_B, + ES_REFERENCED_B, ES_FLAGS }; @@ -44,6 +45,12 @@ enum { #define EXTENT_STATUS_UNWRITTEN (1 << ES_UNWRITTEN_B) #define EXTENT_STATUS_DELAYED (1 << ES_DELAYED_B) #define EXTENT_STATUS_HOLE (1 << ES_HOLE_B) +#define EXTENT_STATUS_REFERENCED (1 << ES_REFERENCED_B) + +#define ES_TYPE_MASK ((ext4_fsblk_t)(EXTENT_STATUS_WRITTEN | \ + EXTENT_STATUS_UNWRITTEN | \ + EXTENT_STATUS_DELAYED | \ + EXTENT_STATUS_HOLE) << ES_SHIFT) struct ext4_sb_info; struct ext4_extent; @@ -93,24 +100,44 @@ static inline unsigned int ext4_es_status(struct extent_status *es) return es->es_pblk >> ES_SHIFT; } +static inline unsigned int ext4_es_type(struct extent_status *es) +{ + return (es->es_pblk & ES_TYPE_MASK) >> ES_SHIFT; +} + static inline int ext4_es_is_written(struct extent_status *es) { - return (ext4_es_status(es) & EXTENT_STATUS_WRITTEN) != 0; + return (ext4_es_type(es) & EXTENT_STATUS_WRITTEN) != 0; } static inline int ext4_es_is_unwritten(struct extent_status *es) { - return (ext4_es_status(es) & EXTENT_STATUS_UNWRITTEN) != 0; + return (ext4_es_type(es) & EXTENT_STATUS_UNWRITTEN) != 0; } static inline int ext4_es_is_delayed(struct extent_status *es) { - return (ext4_es_status(es) & EXTENT_STATUS_DELAYED) != 0; + return (ext4_es_type(es) & EXTENT_STATUS_DELAYED) != 0; } static inline int ext4_es_is_hole(struct extent_status *es) { - return (ext4_es_status(es) & EXTENT_STATUS_HOLE) != 0; + return (ext4_es_type(es) & EXTENT_STATUS_HOLE) != 0; +} + +static inline void ext4_es_set_referenced(struct extent_status *es) +{ + es->es_pblk |= ((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT; +} + +static inline void ext4_es_clear_referenced(struct extent_status *es) +{ + es->es_pblk &= ~(((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT); +} + +static inline int ext4_es_is_referenced(struct extent_status *es) +{ + return (ext4_es_status(es) & EXTENT_STATUS_REFERENCED) != 0; } static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es) -- GitLab From 2193dda5eec60373c7a061c129c6ab9d658f78e9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 25 Nov 2014 12:28:46 +0100 Subject: [PATCH 6466/9457] USB: host: Remove ehci-octeon and ohci-octeon drivers Remove special-purpose octeon drivers and instead use ehci-platform and ohci-platform as suggested with http://marc.info/?l=linux-mips&m=140139694721623&w=2 [andreas.herrmann: fixed compile error] Cc: David Daney Cc: Alex Smith Signed-off-by: Alan Stern Signed-off-by: Andreas Herrmann Acked-by: Ralf Baechle Tested-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- arch/mips/cavium-octeon/octeon-platform.c | 274 +++++++++++++++++++++- arch/mips/configs/cavium_octeon_defconfig | 3 + drivers/usb/host/Kconfig | 18 +- drivers/usb/host/Makefile | 1 - drivers/usb/host/ehci-hcd.c | 5 - drivers/usb/host/ehci-octeon.c | 182 -------------- drivers/usb/host/octeon2-common.c | 200 ---------------- drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-octeon.c | 196 ---------------- 9 files changed, 285 insertions(+), 599 deletions(-) delete mode 100644 drivers/usb/host/ehci-octeon.c delete mode 100644 drivers/usb/host/octeon2-common.c delete mode 100644 drivers/usb/host/ohci-octeon.c diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index 6df0f4d8f197..b67ddf0f8bcd 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -7,22 +7,27 @@ * Copyright (C) 2008 Wind River Systems */ +#include #include #include #include #include #include #include +#include #include #include #include #include #include +#include +#include #include #include #include #include +#include /* Octeon Random Number Generator. */ static int __init octeon_rng_device_init(void) @@ -68,6 +73,229 @@ device_initcall(octeon_rng_device_init); #ifdef CONFIG_USB +static DEFINE_MUTEX(octeon2_usb_clocks_mutex); + +static int octeon2_usb_clock_start_cnt; + +static void octeon2_usb_clocks_start(void) +{ + u64 div; + union cvmx_uctlx_if_ena if_ena; + union cvmx_uctlx_clk_rst_ctl clk_rst_ctl; + union cvmx_uctlx_uphy_ctl_status uphy_ctl_status; + union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; + int i; + unsigned long io_clk_64_to_ns; + + + mutex_lock(&octeon2_usb_clocks_mutex); + + octeon2_usb_clock_start_cnt++; + if (octeon2_usb_clock_start_cnt != 1) + goto exit; + + io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); + + /* + * Step 1: Wait for voltages stable. That surely happened + * before starting the kernel. + * + * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1 + */ + if_ena.u64 = 0; + if_ena.s.en = 1; + cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); + + /* Step 3: Configure the reference clock, PHY, and HCLK */ + clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); + + /* + * If the UCTL looks like it has already been started, skip + * the initialization, otherwise bus errors are obtained. + */ + if (clk_rst_ctl.s.hrst) + goto end_clock; + /* 3a */ + clk_rst_ctl.s.p_por = 1; + clk_rst_ctl.s.hrst = 0; + clk_rst_ctl.s.p_prst = 0; + clk_rst_ctl.s.h_clkdiv_rst = 0; + clk_rst_ctl.s.o_clkdiv_rst = 0; + clk_rst_ctl.s.h_clkdiv_en = 0; + clk_rst_ctl.s.o_clkdiv_en = 0; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* 3b */ + /* 12MHz crystal. */ + clk_rst_ctl.s.p_refclk_sel = 0; + clk_rst_ctl.s.p_refclk_div = 0; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* 3c */ + div = octeon_get_io_clock_rate() / 130000000ull; + + switch (div) { + case 0: + div = 1; + break; + case 1: + case 2: + case 3: + case 4: + break; + case 5: + div = 4; + break; + case 6: + case 7: + div = 6; + break; + case 8: + case 9: + case 10: + case 11: + div = 8; + break; + default: + div = 12; + break; + } + clk_rst_ctl.s.h_div = div; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + /* Read it back, */ + clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); + clk_rst_ctl.s.h_clkdiv_en = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + /* 3d */ + clk_rst_ctl.s.h_clkdiv_rst = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* 3e: delay 64 io clocks */ + ndelay(io_clk_64_to_ns); + + /* + * Step 4: Program the power-on reset field in the UCTL + * clock-reset-control register. + */ + clk_rst_ctl.s.p_por = 0; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* Step 5: Wait 1 ms for the PHY clock to start. */ + mdelay(1); + + /* + * Step 6: Program the reset input from automatic test + * equipment field in the UPHY CSR + */ + uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0)); + uphy_ctl_status.s.ate_reset = 1; + cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); + + /* Step 7: Wait for at least 10ns. */ + ndelay(10); + + /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */ + uphy_ctl_status.s.ate_reset = 0; + cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); + + /* + * Step 9: Wait for at least 20ns for UPHY to output PHY clock + * signals and OHCI_CLK48 + */ + ndelay(20); + + /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */ + /* 10a */ + clk_rst_ctl.s.o_clkdiv_rst = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* 10b */ + clk_rst_ctl.s.o_clkdiv_en = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* 10c */ + ndelay(io_clk_64_to_ns); + + /* + * Step 11: Program the PHY reset field: + * UCTL0_CLK_RST_CTL[P_PRST] = 1 + */ + clk_rst_ctl.s.p_prst = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + + /* Step 12: Wait 1 uS. */ + udelay(1); + + /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */ + clk_rst_ctl.s.hrst = 1; + cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); + +end_clock: + /* Now we can set some other registers. */ + + for (i = 0; i <= 1; i++) { + port_ctl_status.u64 = + cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); + /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */ + port_ctl_status.s.txvreftune = 15; + port_ctl_status.s.txrisetune = 1; + port_ctl_status.s.txpreemphasistune = 1; + cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), + port_ctl_status.u64); + } + + /* Set uSOF cycle period to 60,000 bits. */ + cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull); +exit: + mutex_unlock(&octeon2_usb_clocks_mutex); +} + +static void octeon2_usb_clocks_stop(void) +{ + mutex_lock(&octeon2_usb_clocks_mutex); + octeon2_usb_clock_start_cnt--; + mutex_unlock(&octeon2_usb_clocks_mutex); +} + +static int octeon_ehci_power_on(struct platform_device *pdev) +{ + octeon2_usb_clocks_start(); + return 0; +} + +static void octeon_ehci_power_off(struct platform_device *pdev) +{ + octeon2_usb_clocks_stop(); +} + +static struct usb_ehci_pdata octeon_ehci_pdata = { + /* Octeon EHCI matches CPU endianness. */ +#ifdef __BIG_ENDIAN + .big_endian_mmio = 1, +#endif + .power_on = octeon_ehci_power_on, + .power_off = octeon_ehci_power_off, +}; + +static void __init octeon_ehci_hw_start(void) +{ + union cvmx_uctlx_ehci_ctl ehci_ctl; + + octeon2_usb_clocks_start(); + + ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); + /* Use 64-bit addressing. */ + ehci_ctl.s.ehci_64b_addr_en = 1; + ehci_ctl.s.l2c_addr_msb = 0; + ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ + ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ + cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64); + + octeon2_usb_clocks_stop(); +} + +static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64); + static int __init octeon_ehci_device_init(void) { struct platform_device *pd; @@ -88,7 +316,7 @@ static int __init octeon_ehci_device_init(void) if (octeon_is_simulation() || usb_disabled()) return 0; /* No USB in the simulator. */ - pd = platform_device_alloc("octeon-ehci", 0); + pd = platform_device_alloc("ehci-platform", 0); if (!pd) { ret = -ENOMEM; goto out; @@ -105,6 +333,10 @@ static int __init octeon_ehci_device_init(void) if (ret) goto fail; + pd->dev.dma_mask = &octeon_ehci_dma_mask; + pd->dev.platform_data = &octeon_ehci_pdata; + octeon_ehci_hw_start(); + ret = platform_device_add(pd); if (ret) goto fail; @@ -117,6 +349,41 @@ static int __init octeon_ehci_device_init(void) } device_initcall(octeon_ehci_device_init); +static int octeon_ohci_power_on(struct platform_device *pdev) +{ + octeon2_usb_clocks_start(); + return 0; +} + +static void octeon_ohci_power_off(struct platform_device *pdev) +{ + octeon2_usb_clocks_stop(); +} + +static struct usb_ohci_pdata octeon_ohci_pdata = { + /* Octeon OHCI matches CPU endianness. */ +#ifdef __BIG_ENDIAN + .big_endian_mmio = 1, +#endif + .power_on = octeon_ohci_power_on, + .power_off = octeon_ohci_power_off, +}; + +static void __init octeon_ohci_hw_start(void) +{ + union cvmx_uctlx_ohci_ctl ohci_ctl; + + octeon2_usb_clocks_start(); + + ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); + ohci_ctl.s.l2c_addr_msb = 0; + ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ + ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ + cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64); + + octeon2_usb_clocks_stop(); +} + static int __init octeon_ohci_device_init(void) { struct platform_device *pd; @@ -137,7 +404,7 @@ static int __init octeon_ohci_device_init(void) if (octeon_is_simulation() || usb_disabled()) return 0; /* No USB in the simulator. */ - pd = platform_device_alloc("octeon-ohci", 0); + pd = platform_device_alloc("ohci-platform", 0); if (!pd) { ret = -ENOMEM; goto out; @@ -154,6 +421,9 @@ static int __init octeon_ohci_device_init(void) if (ret) goto fail; + pd->dev.platform_data = &octeon_ohci_pdata; + octeon_ohci_hw_start(); + ret = platform_device_add(pd); if (ret) goto fail; diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index b2476a1c4aaa..e57058d4ec22 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -120,6 +120,9 @@ CONFIG_SPI_OCTEON=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_USB_SUPPORT is not set +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_STAGING=y diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a3ca1375dd52..fafc628480e0 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -292,11 +292,15 @@ config USB_EHCI_HCD_PLATFORM If unsure, say N. config USB_OCTEON_EHCI - bool "Octeon on-chip EHCI support" + bool "Octeon on-chip EHCI support (DEPRECATED)" depends on CAVIUM_OCTEON_SOC default n select USB_EHCI_BIG_ENDIAN_MMIO + select USB_EHCI_HCD_PLATFORM help + This option is deprecated now and the driver was removed, use + USB_EHCI_HCD_PLATFORM instead. + Enable support for the Octeon II SOC's on-chip EHCI controller. It is needed for high-speed (480Mbit/sec) USB 2.0 device support. All CN6XXX based chips with USB are @@ -575,12 +579,16 @@ config USB_OHCI_HCD_PLATFORM If unsure, say N. config USB_OCTEON_OHCI - bool "Octeon on-chip OHCI support" + bool "Octeon on-chip OHCI support (DEPRECATED)" depends on CAVIUM_OCTEON_SOC default USB_OCTEON_EHCI select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_LITTLE_ENDIAN + select USB_OHCI_HCD_PLATFORM help + This option is deprecated now and the driver was removed, use + USB_OHCI_HCD_PLATFORM instead. + Enable support for the Octeon II SOC's on-chip OHCI controller. It is needed for low-speed USB 1.0 device support. All CN6XXX based chips with USB are supported. @@ -754,12 +762,6 @@ config USB_IMX21_HCD To compile this driver as a module, choose M here: the module will be called "imx21-hcd". - - -config USB_OCTEON2_COMMON - bool - default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI - config USB_HCD_BCMA tristate "BCMA usb host driver" depends on BCMA diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 348c24321562..d6216a493bab 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -73,7 +73,6 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o -obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index df75b8e7d157..38bfeedae1d0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1275,11 +1275,6 @@ MODULE_LICENSE ("GPL"); #define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif -#ifdef CONFIG_USB_OCTEON_EHCI -#include "ehci-octeon.c" -#define PLATFORM_DRIVER ehci_octeon_driver -#endif - #ifdef CONFIG_TILE_USB #include "ehci-tilegx.c" #define PLATFORM_DRIVER ehci_hcd_tilegx_driver diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c deleted file mode 100644 index 2d0c4bcba579..000000000000 --- a/drivers/usb/host/ehci-octeon.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include - -#include -#include - -#define OCTEON_EHCI_HCD_NAME "octeon-ehci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ehci_octeon_start(void) -{ - union cvmx_uctlx_ehci_ctl ehci_ctl; - - octeon2_usb_clocks_start(); - - ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); - /* Use 64-bit addressing. */ - ehci_ctl.s.ehci_64b_addr_en = 1; - ehci_ctl.s.l2c_addr_msb = 0; - ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64); -} - -static void ehci_octeon_stop(void) -{ - octeon2_usb_clocks_stop(); -} - -static const struct hc_driver ehci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, - - /* - * basic lifecycle operations - */ - .reset = ehci_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64); - -static int ehci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - /* - * We can DMA from anywhere. But the descriptors must be in - * the lower 4GB. - */ - pdev->dev.dma_mask = &ehci_octeon_dma_mask; - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem); - if (IS_ERR(hcd->regs)) { - ret = PTR_ERR(hcd->regs); - goto err1; - } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - - ehci_octeon_start(); - - ehci = hcd_to_ehci(hcd); - - /* Octeon EHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ehci->big_endian_mmio = 1; -#endif - - ehci->caps = hcd->regs; - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err2; - } - device_wakeup_enable(hcd->self.controller); - - platform_set_drvdata(pdev, hcd); - - return 0; -err2: - ehci_octeon_stop(); - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ehci_octeon_stop(); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ehci_octeon_driver = { - .probe = ehci_octeon_drv_probe, - .remove = ehci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_EHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME); diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c deleted file mode 100644 index d9df423f3d12..000000000000 --- a/drivers/usb/host/octeon2-common.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010, 2011 Cavium Networks - */ - -#include -#include -#include - -#include -#include - -static DEFINE_MUTEX(octeon2_usb_clocks_mutex); - -static int octeon2_usb_clock_start_cnt; - -void octeon2_usb_clocks_start(void) -{ - u64 div; - union cvmx_uctlx_if_ena if_ena; - union cvmx_uctlx_clk_rst_ctl clk_rst_ctl; - union cvmx_uctlx_uphy_ctl_status uphy_ctl_status; - union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; - int i; - unsigned long io_clk_64_to_ns; - - - mutex_lock(&octeon2_usb_clocks_mutex); - - octeon2_usb_clock_start_cnt++; - if (octeon2_usb_clock_start_cnt != 1) - goto exit; - - io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); - - /* - * Step 1: Wait for voltages stable. That surely happened - * before starting the kernel. - * - * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1 - */ - if_ena.u64 = 0; - if_ena.s.en = 1; - cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); - - /* Step 3: Configure the reference clock, PHY, and HCLK */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - - /* - * If the UCTL looks like it has already been started, skip - * the initialization, otherwise bus errors are obtained. - */ - if (clk_rst_ctl.s.hrst) - goto end_clock; - /* 3a */ - clk_rst_ctl.s.p_por = 1; - clk_rst_ctl.s.hrst = 0; - clk_rst_ctl.s.p_prst = 0; - clk_rst_ctl.s.h_clkdiv_rst = 0; - clk_rst_ctl.s.o_clkdiv_rst = 0; - clk_rst_ctl.s.h_clkdiv_en = 0; - clk_rst_ctl.s.o_clkdiv_en = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3b */ - /* 12MHz crystal. */ - clk_rst_ctl.s.p_refclk_sel = 0; - clk_rst_ctl.s.p_refclk_div = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3c */ - div = octeon_get_io_clock_rate() / 130000000ull; - - switch (div) { - case 0: - div = 1; - break; - case 1: - case 2: - case 3: - case 4: - break; - case 5: - div = 4; - break; - case 6: - case 7: - div = 6; - break; - case 8: - case 9: - case 10: - case 11: - div = 8; - break; - default: - div = 12; - break; - } - clk_rst_ctl.s.h_div = div; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* Read it back, */ - clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); - clk_rst_ctl.s.h_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - /* 3d */ - clk_rst_ctl.s.h_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 3e: delay 64 io clocks */ - ndelay(io_clk_64_to_ns); - - /* - * Step 4: Program the power-on reset field in the UCTL - * clock-reset-control register. - */ - clk_rst_ctl.s.p_por = 0; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 5: Wait 1 ms for the PHY clock to start. */ - mdelay(1); - - /* - * Step 6: Program the reset input from automatic test - * equipment field in the UPHY CSR - */ - uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0)); - uphy_ctl_status.s.ate_reset = 1; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* Step 7: Wait for at least 10ns. */ - ndelay(10); - - /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */ - uphy_ctl_status.s.ate_reset = 0; - cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64); - - /* - * Step 9: Wait for at least 20ns for UPHY to output PHY clock - * signals and OHCI_CLK48 - */ - ndelay(20); - - /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */ - /* 10a */ - clk_rst_ctl.s.o_clkdiv_rst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10b */ - clk_rst_ctl.s.o_clkdiv_en = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* 10c */ - ndelay(io_clk_64_to_ns); - - /* - * Step 11: Program the PHY reset field: - * UCTL0_CLK_RST_CTL[P_PRST] = 1 - */ - clk_rst_ctl.s.p_prst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - - /* Step 12: Wait 1 uS. */ - udelay(1); - - /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */ - clk_rst_ctl.s.hrst = 1; - cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); - -end_clock: - /* Now we can set some other registers. */ - - for (i = 0; i <= 1; i++) { - port_ctl_status.u64 = - cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); - /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */ - port_ctl_status.s.txvreftune = 15; - port_ctl_status.s.txrisetune = 1; - port_ctl_status.s.txpreemphasistune = 1; - cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), - port_ctl_status.u64); - } - - /* Set uSOF cycle period to 60,000 bits. */ - cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull); -exit: - mutex_unlock(&octeon2_usb_clocks_mutex); -} -EXPORT_SYMBOL(octeon2_usb_clocks_start); - -void octeon2_usb_clocks_stop(void) -{ - mutex_lock(&octeon2_usb_clocks_mutex); - octeon2_usb_clock_start_cnt--; - mutex_unlock(&octeon2_usb_clocks_mutex); -} -EXPORT_SYMBOL(octeon2_usb_clocks_stop); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d664edabf14e..1dab9dfbca6a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1249,11 +1249,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_jz4740_driver #endif -#ifdef CONFIG_USB_OCTEON_OHCI -#include "ohci-octeon.c" -#define PLATFORM_DRIVER ohci_octeon_driver -#endif - #ifdef CONFIG_TILE_USB #include "ohci-tilegx.c" #define PLATFORM_DRIVER ohci_hcd_tilegx_driver diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c deleted file mode 100644 index 20d861b6192f..000000000000 --- a/drivers/usb/host/ohci-octeon.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * EHCI HCD glue for Cavium Octeon II SOCs. - * - * Loosely based on ehci-au1xxx.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2010 Cavium Networks - * - */ - -#include - -#include -#include - -#define OCTEON_OHCI_HCD_NAME "octeon-ohci" - -/* Common clock init code. */ -void octeon2_usb_clocks_start(void); -void octeon2_usb_clocks_stop(void); - -static void ohci_octeon_hw_start(void) -{ - union cvmx_uctlx_ohci_ctl ohci_ctl; - - octeon2_usb_clocks_start(); - - ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); - ohci_ctl.s.l2c_addr_msb = 0; - ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */ - ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */ - cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64); - -} - -static void ohci_octeon_hw_stop(void) -{ - /* Undo ohci_octeon_start() */ - octeon2_usb_clocks_stop(); -} - -static int ohci_octeon_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ret = ohci_init(ohci); - - if (ret < 0) - return ret; - - ret = ohci_run(ohci); - - if (ret < 0) { - ohci_err(ohci, "can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_octeon_hc_driver = { - .description = hcd_name, - .product_desc = "Octeon OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_octeon_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, - - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_octeon_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct ohci_hcd *ohci; - void *reg_base; - struct resource *res_mem; - int irq; - int ret; - - if (usb_disabled()) - return -ENODEV; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No irq assigned\n"); - return -ENODEV; - } - - /* Ohci is a 32-bit device. */ - ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon"); - if (!hcd) - return -ENOMEM; - - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg_base = devm_ioremap_resource(&pdev->dev, res_mem); - if (IS_ERR(reg_base)) { - ret = PTR_ERR(reg_base); - goto err1; - } - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - - ohci_octeon_hw_start(); - - hcd->regs = reg_base; - - ohci = hcd_to_ohci(hcd); - - /* Octeon OHCI matches CPU endianness. */ -#ifdef __BIG_ENDIAN - ohci->flags |= OHCI_QUIRK_BE_MMIO; -#endif - - ohci_hcd_init(ohci); - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); - goto err2; - } - - device_wakeup_enable(hcd->self.controller); - - platform_set_drvdata(pdev, hcd); - - return 0; - -err2: - ohci_octeon_hw_stop(); - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ohci_octeon_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - ohci_octeon_hw_stop(); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ohci_octeon_driver = { - .probe = ohci_octeon_drv_probe, - .remove = ohci_octeon_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = OCTEON_OHCI_HCD_NAME, - .owner = THIS_MODULE, - } -}; - -MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME); -- GitLab From 4fdb5543183d027a19805b72025b859af73d0863 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Tue, 25 Nov 2014 13:08:04 -0500 Subject: [PATCH 6467/9457] ext4: cleanup GFP flags inside resize path We must use GFP_NOFS instead GFP_KERNEL inside ext4_mb_add_groupinfo and ext4_calculate_overhead() because they are called from inside a journal transaction. Call trace: ioctl ->ext4_group_add ->journal_start ->ext4_setup_new_descs ->ext4_mb_add_groupinfo -> GFP_KERNEL ->ext4_flex_group_add ->ext4_update_super ->ext4_calculate_overhead -> GFP_KERNEL ->journal_stop Signed-off-by: Dmitry Monakhov Signed-off-by: Theodore Ts'o --- fs/ext4/mballoc.c | 6 +++--- fs/ext4/super.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 004d0ff8325f..f1c25f83fc7d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2385,7 +2385,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, if (group % EXT4_DESC_PER_BLOCK(sb) == 0) { metalen = sizeof(*meta_group_info) << EXT4_DESC_PER_BLOCK_BITS(sb); - meta_group_info = kmalloc(metalen, GFP_KERNEL); + meta_group_info = kmalloc(metalen, GFP_NOFS); if (meta_group_info == NULL) { ext4_msg(sb, KERN_ERR, "can't allocate mem " "for a buddy group"); @@ -2399,7 +2399,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)]; i = group & (EXT4_DESC_PER_BLOCK(sb) - 1); - meta_group_info[i] = kmem_cache_zalloc(cachep, GFP_KERNEL); + meta_group_info[i] = kmem_cache_zalloc(cachep, GFP_NOFS); if (meta_group_info[i] == NULL) { ext4_msg(sb, KERN_ERR, "can't allocate buddy mem"); goto exit_group_info; @@ -2428,7 +2428,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, { struct buffer_head *bh; meta_group_info[i]->bb_bitmap = - kmalloc(sb->s_blocksize, GFP_KERNEL); + kmalloc(sb->s_blocksize, GFP_NOFS); BUG_ON(meta_group_info[i]->bb_bitmap == NULL); bh = ext4_read_block_bitmap(sb, group); BUG_ON(bh == NULL); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 48318497e8e9..b643009fddfe 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3300,7 +3300,7 @@ int ext4_calculate_overhead(struct super_block *sb) struct ext4_super_block *es = sbi->s_es; ext4_group_t i, ngroups = ext4_get_groups_count(sb); ext4_fsblk_t overhead = 0; - char *buf = (char *) get_zeroed_page(GFP_KERNEL); + char *buf = (char *) get_zeroed_page(GFP_NOFS); if (!buf) return -ENOMEM; -- GitLab From 92b98361f119a6919061d067c6584de9ae2de9f4 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:12 -0500 Subject: [PATCH 6468/9457] xprtrdma: Return an errno from rpcrdma_register_external() The RPC/RDMA send_request method and the chunk registration code expects an errno from the registration function. This allows the upper layers to distinguish between a recoverable failure (for example, temporary memory exhaustion) and a hard failure (for example, a bug in the registration logic). Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 61c41298b4ea..6ea29420f0ac 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1918,10 +1918,10 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg, break; default: - return -1; + return -EIO; } if (rc) - return -1; + return rc; return nsegs; } -- GitLab From e7104a2a96069975d489c60a30564372c6273a85 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:20 -0500 Subject: [PATCH 6469/9457] xprtrdma: Cap req_cqinit Recent work made FRMR registration and invalidation completions unsignaled. This greatly reduces the adapter interrupt rate. Every so often, however, a posted send Work Request is allowed to signal. Otherwise, the provider's Work Queue will wrap and the workload will hang. The number of Work Requests that are allowed to remain unsignaled is determined by the value of req_cqinit. Currently, this is set to the size of the send Work Queue divided by two, minus 1. For FRMR, the send Work Queue is the maximum number of concurrent RPCs (currently 32) times the maximum number of Work Requests an RPC might use (currently 7, though some adapters may need more). For mlx4, this is 224 entries. This leaves completion signaling disabled for 111 send Work Requests. Some providers hold back dispatching Work Requests until a CQE is generated. If completions are disabled, then no CQEs are generated for quite some time, and that can stall the Work Queue. I've seen this occur running xfstests generic/113 over NFSv4, where eventually, posting a FAST_REG_MR Work Request fails with -ENOMEM because the Work Queue has overflowed. The connection is dropped and re-established. Cap the rep_cqinit setting so completions are not left turned off for too long. BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=269 Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 4 +++- net/sunrpc/xprtrdma/xprt_rdma.h | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 6ea29420f0ac..af45cf390126 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -733,7 +733,9 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, /* set trigger for requesting send completion */ ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 - 1; - if (ep->rep_cqinit <= 2) + if (ep->rep_cqinit > RPCRDMA_MAX_UNSIGNALED_SENDS) + ep->rep_cqinit = RPCRDMA_MAX_UNSIGNALED_SENDS; + else if (ep->rep_cqinit <= 2) ep->rep_cqinit = 0; INIT_CQCOUNT(ep); ep->rep_ia = ia; diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index ac7fc9a31342..b799041b75bf 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -97,6 +97,12 @@ struct rpcrdma_ep { struct ib_wc rep_recv_wcs[RPCRDMA_POLLSIZE]; }; +/* + * Force a signaled SEND Work Request every so often, + * in case the provider needs to do some housekeeping. + */ +#define RPCRDMA_MAX_UNSIGNALED_SENDS (32) + #define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit) #define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount) -- GitLab From 467c9674bccc073684ee34f4bd205cf1b135d76e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:29 -0500 Subject: [PATCH 6470/9457] xprtrdma: unmap all FMRs during transport disconnect When using RPCRDMA_MTHCAFMR memory registration, after a few transport disconnect / reconnect cycles, ib_map_phys_fmr() starts to return EINVAL because the provider has exhausted its map pool. Make sure that all FMRs are unmapped during transport disconnect, and that ->send_request remarshals them during an RPC retransmit. This resets the transport's MRs to ensure that none are leaked during a disconnect. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/transport.c | 2 +- net/sunrpc/xprtrdma/verbs.c | 42 ++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 6a4615dd0261..cfe9a810e6bc 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task) if (req->rl_niovs == 0) rc = rpcrdma_marshal_req(rqst); - else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR) + else if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_ALLPHYSICAL) rc = rpcrdma_marshal_chunks(rqst, 0); if (rc < 0) goto failed_marshal; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index af45cf390126..3c88276090e3 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -62,6 +62,7 @@ #endif static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); +static void rpcrdma_reset_fmrs(struct rpcrdma_ia *); /* * internal functions @@ -868,8 +869,19 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia) rpcrdma_ep_disconnect(ep, ia); rpcrdma_flush_cqs(ep); - if (ia->ri_memreg_strategy == RPCRDMA_FRMR) + switch (ia->ri_memreg_strategy) { + case RPCRDMA_FRMR: rpcrdma_reset_frmrs(ia); + break; + case RPCRDMA_MTHCAFMR: + rpcrdma_reset_fmrs(ia); + break; + case RPCRDMA_ALLPHYSICAL: + break; + default: + rc = -EIO; + goto out; + } xprt = container_of(ia, struct rpcrdma_xprt, rx_ia); id = rpcrdma_create_id(xprt, ia, @@ -1289,6 +1301,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) kfree(buf->rb_pool); } +/* After a disconnect, unmap all FMRs. + * + * This is invoked only in the transport connect worker in order + * to serialize with rpcrdma_register_fmr_external(). + */ +static void +rpcrdma_reset_fmrs(struct rpcrdma_ia *ia) +{ + struct rpcrdma_xprt *r_xprt = + container_of(ia, struct rpcrdma_xprt, rx_ia); + struct rpcrdma_buffer *buf = &r_xprt->rx_buf; + struct list_head *pos; + struct rpcrdma_mw *r; + LIST_HEAD(l); + int rc; + + list_for_each(pos, &buf->rb_all) { + r = list_entry(pos, struct rpcrdma_mw, mw_all); + + INIT_LIST_HEAD(&l); + list_add(&r->r.fmr->list, &l); + rc = ib_unmap_fmr(&l); + if (rc) + dprintk("RPC: %s: ib_unmap_fmr failed %i\n", + __func__, rc); + } +} + /* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in * an unusable state. Find FRMRs in this state and dereg / reg * each. FRMRs that are VALID and attached to an rpcrdma_req are -- GitLab From f1a03b76fecdb23983e2ad7e817e98d093ece9f7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:37 -0500 Subject: [PATCH 6471/9457] xprtrdma: Refactor tasklet scheduling Restore the separate function that schedules the reply handling tasklet. I need to call it from two different paths. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 3c88276090e3..478b2fda83a6 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -106,6 +106,17 @@ rpcrdma_run_tasklet(unsigned long data) static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); +static void +rpcrdma_schedule_tasklet(struct list_head *sched_list) +{ + unsigned long flags; + + spin_lock_irqsave(&rpcrdma_tk_lock_g, flags); + list_splice_tail(sched_list, &rpcrdma_tasklets_g); + spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags); + tasklet_schedule(&rpcrdma_tasklet_g); +} + static void rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) { @@ -244,7 +255,6 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep) struct list_head sched_list; struct ib_wc *wcs; int budget, count, rc; - unsigned long flags; INIT_LIST_HEAD(&sched_list); budget = RPCRDMA_WC_BUDGET / RPCRDMA_POLLSIZE; @@ -262,10 +272,7 @@ rpcrdma_recvcq_poll(struct ib_cq *cq, struct rpcrdma_ep *ep) rc = 0; out_schedule: - spin_lock_irqsave(&rpcrdma_tk_lock_g, flags); - list_splice_tail(&sched_list, &rpcrdma_tasklets_g); - spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags); - tasklet_schedule(&rpcrdma_tasklet_g); + rpcrdma_schedule_tasklet(&sched_list); return rc; } -- GitLab From 5c166bef4fa138da45d756dc77a8cb29fced1714 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:45 -0500 Subject: [PATCH 6472/9457] xprtrdma: Re-write rpcrdma_flush_cqs() Currently rpcrdma_flush_cqs() attempts to avoid code duplication, and simply invokes rpcrdma_recvcq_upcall and rpcrdma_sendcq_upcall. 1. rpcrdma_flush_cqs() can run concurrently with provider upcalls. Both flush_cqs() and the upcalls were invoking ib_poll_cq() in different threads using the same wc buffers (ep->rep_recv_wcs and ep->rep_send_wcs), added by commit 1c00dd077654 ("xprtrmda: Reduce calls to ib_poll_cq() in completion handlers"). During transport disconnect processing, this sometimes resulted in the same reply getting added to the rpcrdma_tasklets_g list more than once, which corrupted the list. 2. The upcall functions drain only a limited number of CQEs, thanks to the poll budget added by commit 8301a2c047cc ("xprtrdma: Limit work done by completion handler"). Fixes: a7bc211ac926 ("xprtrdma: On disconnect, don't ignore ... ") BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=276 Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 478b2fda83a6..e6ac9643fe56 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -317,8 +317,15 @@ rpcrdma_recvcq_upcall(struct ib_cq *cq, void *cq_context) static void rpcrdma_flush_cqs(struct rpcrdma_ep *ep) { - rpcrdma_recvcq_upcall(ep->rep_attr.recv_cq, ep); - rpcrdma_sendcq_upcall(ep->rep_attr.send_cq, ep); + struct ib_wc wc; + LIST_HEAD(sched_list); + + while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0) + rpcrdma_recvcq_process_wc(&wc, &sched_list); + if (!list_empty(&sched_list)) + rpcrdma_schedule_tasklet(&sched_list); + while (ib_poll_cq(ep->rep_attr.send_cq, 1, &wc) > 0) + rpcrdma_sendcq_process_wc(&wc); } #ifdef RPC_DEBUG -- GitLab From d5440e27d3e572272db957d6b9661a902b7c339f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:14:53 -0500 Subject: [PATCH 6473/9457] xprtrdma: Enable pad optimization The Linux NFS/RDMA server used to reject NFSv3 WRITE requests when pad optimization was enabled. That bug was fixed by commit e560e3b510d2 ("svcrdma: Add zero padding if the client doesn't send it"). We can now enable pad optimization on the client, which helps performance and is supported now by both Linux and Solaris servers. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index cfe9a810e6bc..8ed25760764b 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -73,7 +73,7 @@ static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE; static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; static unsigned int xprt_rdma_inline_write_padding; static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR; - int xprt_rdma_pad_optimize = 0; + int xprt_rdma_pad_optimize = 1; #ifdef RPC_DEBUG -- GitLab From 7ff11de1bae02a41cac6503f858218ac1b9a3cbe Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:15:01 -0500 Subject: [PATCH 6474/9457] xprtrdma: Display async errors An async error upcall is a hard error, and should be reported in the system log. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index e6ac9643fe56..5783c1a55b09 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -106,6 +106,32 @@ rpcrdma_run_tasklet(unsigned long data) static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL); +static const char * const async_event[] = { + "CQ error", + "QP fatal error", + "QP request error", + "QP access error", + "communication established", + "send queue drained", + "path migration successful", + "path mig error", + "device fatal error", + "port active", + "port error", + "LID change", + "P_key change", + "SM change", + "SRQ error", + "SRQ limit reached", + "last WQE reached", + "client reregister", + "GID change", +}; + +#define ASYNC_MSG(status) \ + ((status) < ARRAY_SIZE(async_event) ? \ + async_event[(status)] : "unknown async error") + static void rpcrdma_schedule_tasklet(struct list_head *sched_list) { @@ -122,8 +148,9 @@ rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) { struct rpcrdma_ep *ep = context; - dprintk("RPC: %s: QP error %X on device %s ep %p\n", - __func__, event->event, event->device->name, context); + pr_err("RPC: %s: %s on device %s ep %p\n", + __func__, ASYNC_MSG(event->event), + event->device->name, context); if (ep->rep_connected == 1) { ep->rep_connected = -EIO; ep->rep_func(ep); @@ -136,8 +163,9 @@ rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context) { struct rpcrdma_ep *ep = context; - dprintk("RPC: %s: CQ error %X on device %s ep %p\n", - __func__, event->event, event->device->name, context); + pr_err("RPC: %s: %s on device %s ep %p\n", + __func__, ASYNC_MSG(event->event), + event->device->name, context); if (ep->rep_connected == 1) { ep->rep_connected = -EIO; ep->rep_func(ep); -- GitLab From 3fedeab10b3bb09744a6467fe7cd157f055137c3 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Tue, 25 Nov 2014 08:33:58 +0530 Subject: [PATCH 6475/9457] cxgb4/cxgb4vf/csiostor: Add T4/T5 PCI ID Table Add a new file t4_pci_id_tbl.h that contains T4/T5 PCI ID Table so that for all drivers that uses T4/T5 PCI functions changes can be done in one place. checkpatch.pl script reports following error, which if tried to fix ends up in compilation error. ERROR: Macros with complex values should be enclosed in parentheses +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \ + { 0, } \ + } WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? new file mode 100644 ERROR: Macros with complex values should be enclosed in parentheses +#define CH_PCI_ID_TABLE_FENTRY(devid) \ + CH_PCI_ID_TABLE_ENTRY((devid) | \ + ((CH_PCI_DEVICE_ID_FUNCTION) << 8)), \ + CH_PCI_ID_TABLE_ENTRY((devid) | \ + ((CH_PCI_DEVICE_ID_FUNCTION2) << 8)) ERROR: Macros with complex values should be enclosed in parentheses +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END { 0, } } ERROR: Macros with complex values should be enclosed in parentheses +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END { 0, } } Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 127 +++----------- .../ethernet/chelsio/cxgb4/t4_pci_id_tbl.h | 160 ++++++++++++++++++ .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 73 ++------ drivers/scsi/csiostor/csio_hw_chip.h | 49 +----- drivers/scsi/csiostor/csio_init.c | 64 ++----- 5 files changed, 210 insertions(+), 263 deletions(-) create mode 100644 drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index a576da1eedf4..3aea82bb9039 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -210,114 +210,25 @@ struct filter_entry { NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) -#define CH_DEVICE(devid, data) { PCI_VDEVICE(CHELSIO, devid), (data) } - -static const struct pci_device_id cxgb4_pci_tbl[] = { - CH_DEVICE(0xa000, 0), /* PE10K */ - CH_DEVICE(0x4001, -1), - CH_DEVICE(0x4002, -1), - CH_DEVICE(0x4003, -1), - CH_DEVICE(0x4004, -1), - CH_DEVICE(0x4005, -1), - CH_DEVICE(0x4006, -1), - CH_DEVICE(0x4007, -1), - CH_DEVICE(0x4008, -1), - CH_DEVICE(0x4009, -1), - CH_DEVICE(0x400a, -1), - CH_DEVICE(0x400d, -1), - CH_DEVICE(0x400e, -1), - CH_DEVICE(0x4080, -1), - CH_DEVICE(0x4081, -1), - CH_DEVICE(0x4082, -1), - CH_DEVICE(0x4083, -1), - CH_DEVICE(0x4084, -1), - CH_DEVICE(0x4085, -1), - CH_DEVICE(0x4086, -1), - CH_DEVICE(0x4087, -1), - CH_DEVICE(0x4088, -1), - CH_DEVICE(0x4401, 4), - CH_DEVICE(0x4402, 4), - CH_DEVICE(0x4403, 4), - CH_DEVICE(0x4404, 4), - CH_DEVICE(0x4405, 4), - CH_DEVICE(0x4406, 4), - CH_DEVICE(0x4407, 4), - CH_DEVICE(0x4408, 4), - CH_DEVICE(0x4409, 4), - CH_DEVICE(0x440a, 4), - CH_DEVICE(0x440d, 4), - CH_DEVICE(0x440e, 4), - CH_DEVICE(0x4480, 4), - CH_DEVICE(0x4481, 4), - CH_DEVICE(0x4482, 4), - CH_DEVICE(0x4483, 4), - CH_DEVICE(0x4484, 4), - CH_DEVICE(0x4485, 4), - CH_DEVICE(0x4486, 4), - CH_DEVICE(0x4487, 4), - CH_DEVICE(0x4488, 4), - CH_DEVICE(0x5001, 4), - CH_DEVICE(0x5002, 4), - CH_DEVICE(0x5003, 4), - CH_DEVICE(0x5004, 4), - CH_DEVICE(0x5005, 4), - CH_DEVICE(0x5006, 4), - CH_DEVICE(0x5007, 4), - CH_DEVICE(0x5008, 4), - CH_DEVICE(0x5009, 4), - CH_DEVICE(0x500A, 4), - CH_DEVICE(0x500B, 4), - CH_DEVICE(0x500C, 4), - CH_DEVICE(0x500D, 4), - CH_DEVICE(0x500E, 4), - CH_DEVICE(0x500F, 4), - CH_DEVICE(0x5010, 4), - CH_DEVICE(0x5011, 4), - CH_DEVICE(0x5012, 4), - CH_DEVICE(0x5013, 4), - CH_DEVICE(0x5014, 4), - CH_DEVICE(0x5015, 4), - CH_DEVICE(0x5080, 4), - CH_DEVICE(0x5081, 4), - CH_DEVICE(0x5082, 4), - CH_DEVICE(0x5083, 4), - CH_DEVICE(0x5084, 4), - CH_DEVICE(0x5085, 4), - CH_DEVICE(0x5086, 4), - CH_DEVICE(0x5087, 4), - CH_DEVICE(0x5088, 4), - CH_DEVICE(0x5401, 4), - CH_DEVICE(0x5402, 4), - CH_DEVICE(0x5403, 4), - CH_DEVICE(0x5404, 4), - CH_DEVICE(0x5405, 4), - CH_DEVICE(0x5406, 4), - CH_DEVICE(0x5407, 4), - CH_DEVICE(0x5408, 4), - CH_DEVICE(0x5409, 4), - CH_DEVICE(0x540A, 4), - CH_DEVICE(0x540B, 4), - CH_DEVICE(0x540C, 4), - CH_DEVICE(0x540D, 4), - CH_DEVICE(0x540E, 4), - CH_DEVICE(0x540F, 4), - CH_DEVICE(0x5410, 4), - CH_DEVICE(0x5411, 4), - CH_DEVICE(0x5412, 4), - CH_DEVICE(0x5413, 4), - CH_DEVICE(0x5414, 4), - CH_DEVICE(0x5415, 4), - CH_DEVICE(0x5480, 4), - CH_DEVICE(0x5481, 4), - CH_DEVICE(0x5482, 4), - CH_DEVICE(0x5483, 4), - CH_DEVICE(0x5484, 4), - CH_DEVICE(0x5485, 4), - CH_DEVICE(0x5486, 4), - CH_DEVICE(0x5487, 4), - CH_DEVICE(0x5488, 4), - { 0, } -}; +/* Macros needed to support the PCI Device ID Table ... + */ +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \ + static struct pci_device_id cxgb4_pci_tbl[] = { +#define CH_PCI_DEVICE_ID_FUNCTION 0x4 + +/* Include PCI Device IDs for both PF4 and PF0-3 so our PCI probe() routine is + * called for both. + */ +#define CH_PCI_DEVICE_ID_FUNCTION2 0x0 + +#define CH_PCI_ID_TABLE_ENTRY(devid) \ + {PCI_VDEVICE(CHELSIO, (devid)), 4} + +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \ + { 0, } \ + } + +#include "t4_pci_id_tbl.h" #define FW4_FNAME "cxgb4/t4fw.bin" #define FW5_FNAME "cxgb4/t5fw.bin" diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h new file mode 100644 index 000000000000..9e4f95a91fb4 --- /dev/null +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -0,0 +1,160 @@ +/* + * This file is part of the Chelsio T4/T5 Ethernet driver for Linux. + * + * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __T4_PCI_ID_TBL_H__ +#define __T4_PCI_ID_TBL_H__ + +/* The code can defined cpp macros for creating a PCI Device ID Table. This is + * useful because it allows the PCI ID Table to be maintained in a single place. + * + * The macros are: + * + * CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN + * -- Used to start the definition of the PCI ID Table. + * + * CH_PCI_DEVICE_ID_FUNCTION + * -- The PCI Function Number to use in the PCI Device ID Table. "0" + * -- for drivers attaching to PF0-3, "4" for drivers attaching to PF4, + * -- "8" for drivers attaching to SR-IOV Virtual Functions, etc. + * + * CH_PCI_DEVICE_ID_FUNCTION2 [optional] + * -- If defined, create a PCI Device ID Table with both + * -- CH_PCI_DEVICE_ID_FUNCTION and CH_PCI_DEVICE_ID_FUNCTION2 populated. + * + * CH_PCI_ID_TABLE_ENTRY(DeviceID) + * -- Used for the individual PCI Device ID entries. Note that we will + * -- be adding a trailing comma (",") after all of the entries (and + * -- between the pairs of entries if CH_PCI_DEVICE_ID_FUNCTION2 is defined). + * + * CH_PCI_DEVICE_ID_TABLE_DEFINE_END + * -- Used to finish the definition of the PCI ID Table. Note that we + * -- will be adding a trailing semi-colon (";") here. + */ +#ifdef CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN + +#ifndef CH_PCI_DEVICE_ID_FUNCTION +#error CH_PCI_DEVICE_ID_FUNCTION not defined! +#endif +#ifndef CH_PCI_ID_TABLE_ENTRY +#error CH_PCI_ID_TABLE_ENTRY not defined! +#endif +#ifndef CH_PCI_DEVICE_ID_TABLE_DEFINE_END +#error CH_PCI_DEVICE_ID_TABLE_DEFINE_END not defined! +#endif + +/* T4 and later ASICs use a PCI Device ID scheme of 0xVFPP where: + * + * V = "4" for T4; "5" for T5, etc. + * F = "0" for PF 0..3; "4".."7" for PF4..7; and "8" for VFs + * PP = adapter product designation + * + * We use this consistency in order to create the proper PCI Device IDs + * for the specified CH_PCI_DEVICE_ID_FUNCTION. + */ +#ifndef CH_PCI_DEVICE_ID_FUNCTION2 +#define CH_PCI_ID_TABLE_FENTRY(devid) \ + CH_PCI_ID_TABLE_ENTRY((devid) | \ + ((CH_PCI_DEVICE_ID_FUNCTION) << 8)) +#else +#define CH_PCI_ID_TABLE_FENTRY(devid) \ + CH_PCI_ID_TABLE_ENTRY((devid) | \ + ((CH_PCI_DEVICE_ID_FUNCTION) << 8)), \ + CH_PCI_ID_TABLE_ENTRY((devid) | \ + ((CH_PCI_DEVICE_ID_FUNCTION2) << 8)) +#endif + +CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN + /* T4 adapters: + */ + CH_PCI_ID_TABLE_FENTRY(0x4000), /* T440-dbg */ + CH_PCI_ID_TABLE_FENTRY(0x4001), /* T420-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4002), /* T422-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4003), /* T440-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4004), /* T420-bch */ + CH_PCI_ID_TABLE_FENTRY(0x4005), /* T440-bch */ + CH_PCI_ID_TABLE_FENTRY(0x4006), /* T440-ch */ + CH_PCI_ID_TABLE_FENTRY(0x4007), /* T420-so */ + CH_PCI_ID_TABLE_FENTRY(0x4008), /* T420-cx */ + CH_PCI_ID_TABLE_FENTRY(0x4009), /* T420-bt */ + CH_PCI_ID_TABLE_FENTRY(0x400a), /* T404-bt */ + CH_PCI_ID_TABLE_FENTRY(0x400b), /* B420-sr */ + CH_PCI_ID_TABLE_FENTRY(0x400c), /* B404-bt */ + CH_PCI_ID_TABLE_FENTRY(0x400d), /* T480-cr */ + CH_PCI_ID_TABLE_FENTRY(0x400e), /* T440-LP-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4080), /* Custom T480-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4081), /* Custom T440-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4082), /* Custom T420-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4083), /* Custom T420-xaui */ + CH_PCI_ID_TABLE_FENTRY(0x4084), /* Custom T440-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4085), /* Custom T420-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4086), /* Custom T440-bt */ + CH_PCI_ID_TABLE_FENTRY(0x4087), /* Custom T440-cr */ + CH_PCI_ID_TABLE_FENTRY(0x4088), /* Custom T440 2-xaui, 2-xfi */ + + /* T5 adapters: + */ + CH_PCI_ID_TABLE_FENTRY(0x5000), /* T580-dbg */ + CH_PCI_ID_TABLE_FENTRY(0x5001), /* T520-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5002), /* T522-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5003), /* T540-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5004), /* T520-bch */ + CH_PCI_ID_TABLE_FENTRY(0x5005), /* T540-bch */ + CH_PCI_ID_TABLE_FENTRY(0x5006), /* T540-ch */ + CH_PCI_ID_TABLE_FENTRY(0x5007), /* T520-so */ + CH_PCI_ID_TABLE_FENTRY(0x5008), /* T520-cx */ + CH_PCI_ID_TABLE_FENTRY(0x5009), /* T520-bt */ + CH_PCI_ID_TABLE_FENTRY(0x500a), /* T504-bt */ + CH_PCI_ID_TABLE_FENTRY(0x500b), /* B520-sr */ + CH_PCI_ID_TABLE_FENTRY(0x500c), /* B504-bt */ + CH_PCI_ID_TABLE_FENTRY(0x500d), /* T580-cr */ + CH_PCI_ID_TABLE_FENTRY(0x500e), /* T540-LP-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5010), /* T580-LP-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5011), /* T520-LL-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5012), /* T560-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5013), /* T580-chr */ + CH_PCI_ID_TABLE_FENTRY(0x5014), /* T580-so */ + CH_PCI_ID_TABLE_FENTRY(0x5015), /* T502-bt */ + CH_PCI_ID_TABLE_FENTRY(0x5080), /* Custom T540-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5081), /* Custom T540-LL-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5082), /* Custom T504-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5083), /* Custom T540-LP-CR */ + CH_PCI_ID_TABLE_FENTRY(0x5084), /* Custom T580-cr */ + CH_PCI_ID_TABLE_FENTRY(0x5085), /* Custom 3x T580-CR */ + CH_PCI_ID_TABLE_FENTRY(0x5086), /* Custom 2x T580-CR */ + CH_PCI_ID_TABLE_FENTRY(0x5087), /* Custom T580-CR */ + CH_PCI_ID_TABLE_FENTRY(0x5088), /* Custom T570-CR */ +CH_PCI_DEVICE_ID_TABLE_DEFINE_END; + +#endif /* CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN */ + +#endif /* __T4_PCI_ID_TBL_H__ */ diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 099f7ce056f2..ad88246a428e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2908,67 +2908,18 @@ static void cxgb4vf_pci_shutdown(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -/* - * PCI Device registration data structures. - */ -#define CH_DEVICE(devid) \ - { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 } - -static const struct pci_device_id cxgb4vf_pci_tbl[] = { - CH_DEVICE(0xb000), /* PE10K FPGA */ - CH_DEVICE(0x4801), /* T420-cr */ - CH_DEVICE(0x4802), /* T422-cr */ - CH_DEVICE(0x4803), /* T440-cr */ - CH_DEVICE(0x4804), /* T420-bch */ - CH_DEVICE(0x4805), /* T440-bch */ - CH_DEVICE(0x4806), /* T460-ch */ - CH_DEVICE(0x4807), /* T420-so */ - CH_DEVICE(0x4808), /* T420-cx */ - CH_DEVICE(0x4809), /* T420-bt */ - CH_DEVICE(0x480a), /* T404-bt */ - CH_DEVICE(0x480d), /* T480-cr */ - CH_DEVICE(0x480e), /* T440-lp-cr */ - CH_DEVICE(0x4880), - CH_DEVICE(0x4881), - CH_DEVICE(0x4882), - CH_DEVICE(0x4883), - CH_DEVICE(0x4884), - CH_DEVICE(0x4885), - CH_DEVICE(0x4886), - CH_DEVICE(0x4887), - CH_DEVICE(0x4888), - CH_DEVICE(0x5801), /* T520-cr */ - CH_DEVICE(0x5802), /* T522-cr */ - CH_DEVICE(0x5803), /* T540-cr */ - CH_DEVICE(0x5804), /* T520-bch */ - CH_DEVICE(0x5805), /* T540-bch */ - CH_DEVICE(0x5806), /* T540-ch */ - CH_DEVICE(0x5807), /* T520-so */ - CH_DEVICE(0x5808), /* T520-cx */ - CH_DEVICE(0x5809), /* T520-bt */ - CH_DEVICE(0x580a), /* T504-bt */ - CH_DEVICE(0x580b), /* T520-sr */ - CH_DEVICE(0x580c), /* T504-bt */ - CH_DEVICE(0x580d), /* T580-cr */ - CH_DEVICE(0x580e), /* T540-lp-cr */ - CH_DEVICE(0x580f), /* Amsterdam */ - CH_DEVICE(0x5810), /* T580-lp-cr */ - CH_DEVICE(0x5811), /* T520-lp-cr */ - CH_DEVICE(0x5812), /* T560-cr */ - CH_DEVICE(0x5813), /* T580-cr */ - CH_DEVICE(0x5814), /* T580-so-cr */ - CH_DEVICE(0x5815), /* T502-bt */ - CH_DEVICE(0x5880), - CH_DEVICE(0x5881), - CH_DEVICE(0x5882), - CH_DEVICE(0x5883), - CH_DEVICE(0x5884), - CH_DEVICE(0x5885), - CH_DEVICE(0x5886), - CH_DEVICE(0x5887), - CH_DEVICE(0x5888), - { 0, } -}; +/* Macros needed to support the PCI Device ID Table ... + */ +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \ + static struct pci_device_id cxgb4vf_pci_tbl[] = { +#define CH_PCI_DEVICE_ID_FUNCTION 0x8 + +#define CH_PCI_ID_TABLE_ENTRY(devid) \ + { PCI_VDEVICE(CHELSIO, (devid)), 0 } + +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END { 0, } } + +#include "../cxgb4/t4_pci_id_tbl.h" MODULE_DESCRIPTION(DRV_DESC); MODULE_AUTHOR("Chelsio Communications"); diff --git a/drivers/scsi/csiostor/csio_hw_chip.h b/drivers/scsi/csiostor/csio_hw_chip.h index bca0de61ae80..4752fed476df 100644 --- a/drivers/scsi/csiostor/csio_hw_chip.h +++ b/drivers/scsi/csiostor/csio_hw_chip.h @@ -36,60 +36,13 @@ #include "csio_defs.h" -/* FCoE device IDs for T4 */ -#define CSIO_DEVID_T440DBG_FCOE 0x4600 -#define CSIO_DEVID_T420CR_FCOE 0x4601 -#define CSIO_DEVID_T422CR_FCOE 0x4602 -#define CSIO_DEVID_T440CR_FCOE 0x4603 -#define CSIO_DEVID_T420BCH_FCOE 0x4604 -#define CSIO_DEVID_T440BCH_FCOE 0x4605 -#define CSIO_DEVID_T440CH_FCOE 0x4606 -#define CSIO_DEVID_T420SO_FCOE 0x4607 -#define CSIO_DEVID_T420CX_FCOE 0x4608 -#define CSIO_DEVID_T420BT_FCOE 0x4609 -#define CSIO_DEVID_T404BT_FCOE 0x460A -#define CSIO_DEVID_B420_FCOE 0x460B -#define CSIO_DEVID_B404_FCOE 0x460C -#define CSIO_DEVID_T480CR_FCOE 0x460D -#define CSIO_DEVID_T440LPCR_FCOE 0x460E -#define CSIO_DEVID_AMSTERDAM_T4_FCOE 0x460F -#define CSIO_DEVID_HUAWEI_T480_FCOE 0x4680 -#define CSIO_DEVID_HUAWEI_T440_FCOE 0x4681 -#define CSIO_DEVID_HUAWEI_STG310_FCOE 0x4682 -#define CSIO_DEVID_ACROMAG_XMC_XAUI 0x4683 -#define CSIO_DEVID_ACROMAG_XMC_SFP_FCOE 0x4684 -#define CSIO_DEVID_QUANTA_MEZZ_SFP_FCOE 0x4685 -#define CSIO_DEVID_HUAWEI_10GT_FCOE 0x4686 -#define CSIO_DEVID_HUAWEI_T440_TOE_FCOE 0x4687 - -/* FCoE device IDs for T5 */ -#define CSIO_DEVID_T580DBG_FCOE 0x5600 -#define CSIO_DEVID_T520CR_FCOE 0x5601 -#define CSIO_DEVID_T522CR_FCOE 0x5602 -#define CSIO_DEVID_T540CR_FCOE 0x5603 -#define CSIO_DEVID_T520BCH_FCOE 0x5604 -#define CSIO_DEVID_T540BCH_FCOE 0x5605 -#define CSIO_DEVID_T540CH_FCOE 0x5606 -#define CSIO_DEVID_T520SO_FCOE 0x5607 -#define CSIO_DEVID_T520CX_FCOE 0x5608 -#define CSIO_DEVID_T520BT_FCOE 0x5609 -#define CSIO_DEVID_T504BT_FCOE 0x560A -#define CSIO_DEVID_B520_FCOE 0x560B -#define CSIO_DEVID_B504_FCOE 0x560C -#define CSIO_DEVID_T580CR2_FCOE 0x560D -#define CSIO_DEVID_T540LPCR_FCOE 0x560E -#define CSIO_DEVID_AMSTERDAM_T5_FCOE 0x560F -#define CSIO_DEVID_T580LPCR_FCOE 0x5610 -#define CSIO_DEVID_T520LLCR_FCOE 0x5611 -#define CSIO_DEVID_T560CR_FCOE 0x5612 -#define CSIO_DEVID_T580CR_FCOE 0x5613 - /* Define MACRO values */ #define CSIO_HW_T4 0x4000 #define CSIO_T4_FCOE_ASIC 0x4600 #define CSIO_HW_T5 0x5000 #define CSIO_T5_FCOE_ASIC 0x5600 #define CSIO_HW_CHIP_MASK 0xF000 + #define T4_REGMAP_SIZE (160 * 1024) #define T5_REGMAP_SIZE (332 * 1024) #define FW_FNAME_T4 "cxgb4/t4fw.bin" diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 1ed5b21c0dd8..34d20cc3e110 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -955,6 +955,10 @@ static int csio_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) struct csio_hw *hw; struct csio_lnode *ln; + /* probe only T5 cards */ + if (!csio_is_t5((pdev->device & CSIO_HW_CHIP_MASK))) + return -ENODEV; + rv = csio_pci_init(pdev, &bars); if (rv) goto err; @@ -1167,53 +1171,21 @@ static struct pci_error_handlers csio_err_handler = { .resume = csio_pci_resume, }; -static const struct pci_device_id csio_pci_tbl[] = { - CSIO_DEVICE(CSIO_DEVID_T440DBG_FCOE, 0), /* T4 DEBUG FCOE */ - CSIO_DEVICE(CSIO_DEVID_T420CR_FCOE, 0), /* T420CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T422CR_FCOE, 0), /* T422CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T440CR_FCOE, 0), /* T440CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T420BCH_FCOE, 0), /* T420BCH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T440BCH_FCOE, 0), /* T440BCH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T440CH_FCOE, 0), /* T440CH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T420SO_FCOE, 0), /* T420SO FCOE */ - CSIO_DEVICE(CSIO_DEVID_T420CX_FCOE, 0), /* T420CX FCOE */ - CSIO_DEVICE(CSIO_DEVID_T420BT_FCOE, 0), /* T420BT FCOE */ - CSIO_DEVICE(CSIO_DEVID_T404BT_FCOE, 0), /* T404BT FCOE */ - CSIO_DEVICE(CSIO_DEVID_B420_FCOE, 0), /* B420 FCOE */ - CSIO_DEVICE(CSIO_DEVID_B404_FCOE, 0), /* B404 FCOE */ - CSIO_DEVICE(CSIO_DEVID_T480CR_FCOE, 0), /* T480 CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T440LPCR_FCOE, 0), /* T440 LP-CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_AMSTERDAM_T4_FCOE, 0), /* AMSTERDAM T4 FCOE */ - CSIO_DEVICE(CSIO_DEVID_HUAWEI_T480_FCOE, 0), /* HUAWEI T480 FCOE */ - CSIO_DEVICE(CSIO_DEVID_HUAWEI_T440_FCOE, 0), /* HUAWEI T440 FCOE */ - CSIO_DEVICE(CSIO_DEVID_HUAWEI_STG310_FCOE, 0), /* HUAWEI STG FCOE */ - CSIO_DEVICE(CSIO_DEVID_ACROMAG_XMC_XAUI, 0), /* ACROMAG XAUI FCOE */ - CSIO_DEVICE(CSIO_DEVID_QUANTA_MEZZ_SFP_FCOE, 0),/* QUANTA MEZZ FCOE */ - CSIO_DEVICE(CSIO_DEVID_HUAWEI_10GT_FCOE, 0), /* HUAWEI 10GT FCOE */ - CSIO_DEVICE(CSIO_DEVID_HUAWEI_T440_TOE_FCOE, 0),/* HUAWEI T4 TOE FCOE */ - CSIO_DEVICE(CSIO_DEVID_T580DBG_FCOE, 0), /* T5 DEBUG FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520CR_FCOE, 0), /* T520CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T522CR_FCOE, 0), /* T522CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T540CR_FCOE, 0), /* T540CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520BCH_FCOE, 0), /* T520BCH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T540BCH_FCOE, 0), /* T540BCH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T540CH_FCOE, 0), /* T540CH FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520SO_FCOE, 0), /* T520SO FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520CX_FCOE, 0), /* T520CX FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520BT_FCOE, 0), /* T520BT FCOE */ - CSIO_DEVICE(CSIO_DEVID_T504BT_FCOE, 0), /* T504BT FCOE */ - CSIO_DEVICE(CSIO_DEVID_B520_FCOE, 0), /* B520 FCOE */ - CSIO_DEVICE(CSIO_DEVID_B504_FCOE, 0), /* B504 FCOE */ - CSIO_DEVICE(CSIO_DEVID_T580CR2_FCOE, 0), /* T580 CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T540LPCR_FCOE, 0), /* T540 LP-CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_AMSTERDAM_T5_FCOE, 0), /* AMSTERDAM T5 FCOE */ - CSIO_DEVICE(CSIO_DEVID_T580LPCR_FCOE, 0), /* T580 LP-CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T520LLCR_FCOE, 0), /* T520 LL-CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T560CR_FCOE, 0), /* T560 CR FCOE */ - CSIO_DEVICE(CSIO_DEVID_T580CR_FCOE, 0), /* T580 CR FCOE */ - { 0, 0, 0, 0, 0, 0, 0 } -}; +/* + * Macros needed to support the PCI Device ID Table ... + */ +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \ + static struct pci_device_id csio_pci_tbl[] = { +/* Define for iSCSI uses PF5, FCoE uses PF6 */ +#define CH_PCI_DEVICE_ID_FUNCTION 0x5 +#define CH_PCI_DEVICE_ID_FUNCTION2 0x6 + +#define CH_PCI_ID_TABLE_ENTRY(devid) \ + { PCI_VDEVICE(CHELSIO, (devid)), 0 } + +#define CH_PCI_DEVICE_ID_TABLE_DEFINE_END { 0, } } +#include "t4_pci_id_tbl.h" static struct pci_driver csio_pci_driver = { .name = KBUILD_MODNAME, -- GitLab From 4f3fff148679d5850994e53c57eb798cd201c88c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 20 Nov 2014 22:27:02 +0100 Subject: [PATCH 6476/9457] brcmfmac: correct .disconnect() callback while connecting When the driver has sent a join iovar to the firmware it waits for the events to report result of the connection. However, the wpa_supplicant will request a .disconnect() after a timeout. So upon calling .disconnect() the interface state may still be CONNECTING. Clear the CONNECTING bit as well. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index d1928de895f9..0ea312546635 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c @@ -1815,6 +1815,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, return -EIO; clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); + clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL); memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); -- GitLab From 23f53dd3062628d2215cab810e4cfc22c29d47ee Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 25 Nov 2014 00:21:40 +0100 Subject: [PATCH 6477/9457] ath9k: add TX power per-rate tables Add TX power per-rate tables for different MIMO modes (e.g STBC) in order to cap the maximum TX power value per-rate in the TX descriptor path. Cap TX power for self generated frames (ACK, RTS/CTS). Currently TPC is supported just by AR9003 based chips Signed-off-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 47 +++++ drivers/net/wireless/ath/ath9k/ar9003_phy.c | 174 ++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 6 + drivers/net/wireless/ath/ath9k/reg.h | 2 + 4 files changed, 229 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index e726e405152c..08225a0067c2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4377,6 +4377,25 @@ static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah, targetPowerArray, numPiers); } +static void ar9003_hw_selfgen_tpc_txpower(struct ath_hw *ah, + struct ath9k_channel *chan, + u8 *pwr_array) +{ + u32 val; + + /* target power values for self generated frames (ACK,RTS/CTS) */ + if (IS_CHAN_2GHZ(chan)) { + val = SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) | + SM(pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) | + SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT); + } else { + val = SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) | + SM(pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) | + SM(0x3f, AR_TPC_CHIRP) | SM(0x3f, AR_TPC_RPT); + } + REG_WRITE(ah, AR_TPC, val); +} + /* Set tx power registers to array of values passed in */ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) { @@ -5312,6 +5331,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, struct ar9300_modal_eep_header *modal_hdr; u8 targetPowerValT2[ar9300RateSize]; u8 target_power_val_t2_eep[ar9300RateSize]; + u8 targetPowerValT2_tpc[ar9300RateSize]; unsigned int i = 0, paprd_scale_factor = 0; u8 pwr_idx, min_pwridx = 0; @@ -5363,6 +5383,9 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, twiceAntennaReduction, powerLimit); + memcpy(targetPowerValT2_tpc, targetPowerValT2, + sizeof(targetPowerValT2)); + if (ar9003_is_paprd_enabled(ah)) { for (i = 0; i < ar9300RateSize; i++) { if ((ah->paprd_ratemask & (1 << i)) && @@ -5396,6 +5419,30 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); ar9003_hw_calibration_apply(ah, chan->channel); ar9003_paprd_set_txpower(ah, chan, targetPowerValT2); + + ar9003_hw_selfgen_tpc_txpower(ah, chan, targetPowerValT2); + + /* TPC initializations */ + if (ah->tpc_enabled) { + u32 val; + + ar9003_hw_init_rate_txpower(ah, targetPowerValT2_tpc, chan); + + /* Enable TPC */ + REG_WRITE(ah, AR_PHY_PWRTX_MAX, + AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE); + /* Disable per chain power reduction */ + val = REG_READ(ah, AR_PHY_POWER_TX_SUB); + if (AR_SREV_9340(ah)) + REG_WRITE(ah, AR_PHY_POWER_TX_SUB, + val & 0xFFFFFFC0); + else + REG_WRITE(ah, AR_PHY_POWER_TX_SUB, + val & 0xFFFFF000); + } else { + /* Disable TPC */ + REG_WRITE(ah, AR_PHY_PWRTX_MAX, 0); + } } static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2df6d2ee70c2..ae6cde273414 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -18,6 +18,21 @@ #include "hw.h" #include "ar9003_phy.h" +#define AR9300_OFDM_RATES 8 +#define AR9300_HT_SS_RATES 8 +#define AR9300_HT_DS_RATES 8 +#define AR9300_HT_TS_RATES 8 + +#define AR9300_11NA_OFDM_SHIFT 0 +#define AR9300_11NA_HT_SS_SHIFT 8 +#define AR9300_11NA_HT_DS_SHIFT 16 +#define AR9300_11NA_HT_TS_SHIFT 24 + +#define AR9300_11NG_OFDM_SHIFT 4 +#define AR9300_11NG_HT_SS_SHIFT 12 +#define AR9300_11NG_HT_DS_SHIFT 20 +#define AR9300_11NG_HT_TS_SHIFT 28 + static const int firstep_table[] = /* level: 0 1 2 3 4 5 6 7 8 */ { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ @@ -40,6 +55,71 @@ static const int m2ThreshLowExt_off = 127; static const int m1ThreshExt_off = 127; static const int m2ThreshExt_off = 127; +static const u8 ofdm2pwr[] = { + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_36, + ALL_TARGET_LEGACY_48, + ALL_TARGET_LEGACY_54 +}; + +static const u8 mcs2pwr_ht20[] = { + ALL_TARGET_HT20_0_8_16, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_4, + ALL_TARGET_HT20_5, + ALL_TARGET_HT20_6, + ALL_TARGET_HT20_7, + ALL_TARGET_HT20_0_8_16, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_12, + ALL_TARGET_HT20_13, + ALL_TARGET_HT20_14, + ALL_TARGET_HT20_15, + ALL_TARGET_HT20_0_8_16, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_1_3_9_11_17_19, + ALL_TARGET_HT20_20, + ALL_TARGET_HT20_21, + ALL_TARGET_HT20_22, + ALL_TARGET_HT20_23 +}; + +static const u8 mcs2pwr_ht40[] = { + ALL_TARGET_HT40_0_8_16, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_4, + ALL_TARGET_HT40_5, + ALL_TARGET_HT40_6, + ALL_TARGET_HT40_7, + ALL_TARGET_HT40_0_8_16, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_12, + ALL_TARGET_HT40_13, + ALL_TARGET_HT40_14, + ALL_TARGET_HT40_15, + ALL_TARGET_HT40_0_8_16, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_1_3_9_11_17_19, + ALL_TARGET_HT40_20, + ALL_TARGET_HT40_21, + ALL_TARGET_HT40_22, + ALL_TARGET_HT40_23, +}; + /** * ar9003_hw_set_channel - set channel on single-chip device * @ah: atheros hardware structure @@ -1799,6 +1879,100 @@ static void ar9003_hw_tx99_set_txpower(struct ath_hw *ah, u8 txpower) ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0)); } +static void ar9003_hw_init_txpower_cck(struct ath_hw *ah, u8 *rate_array) +{ + ah->tx_power[0] = rate_array[ALL_TARGET_LEGACY_1L_5L]; + ah->tx_power[1] = rate_array[ALL_TARGET_LEGACY_1L_5L]; + ah->tx_power[2] = min(rate_array[ALL_TARGET_LEGACY_1L_5L], + rate_array[ALL_TARGET_LEGACY_5S]); + ah->tx_power[3] = min(rate_array[ALL_TARGET_LEGACY_11L], + rate_array[ALL_TARGET_LEGACY_11S]); +} + +static void ar9003_hw_init_txpower_ofdm(struct ath_hw *ah, u8 *rate_array, + int offset) +{ + int i, j; + + for (i = offset; i < offset + AR9300_OFDM_RATES; i++) { + /* OFDM rate to power table idx */ + j = ofdm2pwr[i - offset]; + ah->tx_power[i] = rate_array[j]; + } +} + +static void ar9003_hw_init_txpower_ht(struct ath_hw *ah, u8 *rate_array, + int ss_offset, int ds_offset, + int ts_offset, bool is_40) +{ + int i, j, mcs_idx = 0; + const u8 *mcs2pwr = (is_40) ? mcs2pwr_ht40 : mcs2pwr_ht20; + + for (i = ss_offset; i < ss_offset + AR9300_HT_SS_RATES; i++) { + j = mcs2pwr[mcs_idx]; + ah->tx_power[i] = rate_array[j]; + mcs_idx++; + } + + for (i = ds_offset; i < ds_offset + AR9300_HT_DS_RATES; i++) { + j = mcs2pwr[mcs_idx]; + ah->tx_power[i] = rate_array[j]; + mcs_idx++; + } + + for (i = ts_offset; i < ts_offset + AR9300_HT_TS_RATES; i++) { + j = mcs2pwr[mcs_idx]; + ah->tx_power[i] = rate_array[j]; + mcs_idx++; + } +} + +static void ar9003_hw_init_txpower_stbc(struct ath_hw *ah, int ss_offset, + int ds_offset, int ts_offset) +{ + memcpy(&ah->tx_power_stbc[ss_offset], &ah->tx_power[ss_offset], + AR9300_HT_SS_RATES); + memcpy(&ah->tx_power_stbc[ds_offset], &ah->tx_power[ds_offset], + AR9300_HT_DS_RATES); + memcpy(&ah->tx_power_stbc[ts_offset], &ah->tx_power[ts_offset], + AR9300_HT_TS_RATES); +} + +void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array, + struct ath9k_channel *chan) +{ + if (IS_CHAN_5GHZ(chan)) { + ar9003_hw_init_txpower_ofdm(ah, rate_array, + AR9300_11NA_OFDM_SHIFT); + if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) { + ar9003_hw_init_txpower_ht(ah, rate_array, + AR9300_11NA_HT_SS_SHIFT, + AR9300_11NA_HT_DS_SHIFT, + AR9300_11NA_HT_TS_SHIFT, + IS_CHAN_HT40(chan)); + ar9003_hw_init_txpower_stbc(ah, + AR9300_11NA_HT_SS_SHIFT, + AR9300_11NA_HT_DS_SHIFT, + AR9300_11NA_HT_TS_SHIFT); + } + } else { + ar9003_hw_init_txpower_cck(ah, rate_array); + ar9003_hw_init_txpower_ofdm(ah, rate_array, + AR9300_11NG_OFDM_SHIFT); + if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) { + ar9003_hw_init_txpower_ht(ah, rate_array, + AR9300_11NG_HT_SS_SHIFT, + AR9300_11NG_HT_DS_SHIFT, + AR9300_11NG_HT_TS_SHIFT, + IS_CHAN_HT40(chan)); + ar9003_hw_init_txpower_stbc(ah, + AR9300_11NG_HT_SS_SHIFT, + AR9300_11NG_HT_DS_SHIFT, + AR9300_11NG_HT_TS_SHIFT); + } + } +} + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4cf9e0ac0743..96c6401cdf29 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -940,6 +940,10 @@ struct ath_hw { const struct firmware *eeprom_blob; struct ath_dynack dynack; + + bool tpc_enabled; + u8 tx_power[Ar5416RateSize]; + u8 tx_power_stbc[Ar5416RateSize]; }; struct ath_bus_ops { @@ -1080,6 +1084,8 @@ int ar9003_paprd_init_table(struct ath_hw *ah); bool ar9003_paprd_is_done(struct ath_hw *ah); bool ar9003_is_paprd_enabled(struct ath_hw *ah); void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); +void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array, + struct ath9k_channel *chan); /* Hardware family op attach helpers */ int ar5008_hw_attach_phy_ops(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index ced36b475acc..fb11a9172f38 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1724,6 +1724,8 @@ enum { #define AR_TPC_CTS_S 8 #define AR_TPC_CHIRP 0x003f0000 #define AR_TPC_CHIRP_S 16 +#define AR_TPC_RPT 0x3f000000 +#define AR_TPC_RPT_S 24 #define AR_QUIET1 0x80fc #define AR_QUIET1_NEXT_QUIET_S 0 -- GitLab From 8b537686a116b060475d94b6f548c78289935fef Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 25 Nov 2014 00:21:41 +0100 Subject: [PATCH 6478/9457] ath9k: add TPC capability to TX descriptor path Add TPC capability to TX descriptor path. Cap per-packet TX power according to TX power per-rate tables. Currently TPC is supported just by AR9003 based chips Signed-off-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 8 ++--- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 ++--- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/beacon.c | 5 +-- drivers/net/wireless/ath/ath9k/mac.h | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 37 ++++++++++++++++++++- 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 2a93519f4bdf..f816909d9474 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -281,7 +281,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(i->txpower, AR_XmitPower0) + | SM(i->txpower[0], AR_XmitPower0) | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) @@ -307,9 +307,9 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) | set11nRateFlags(i->rates, 3) | SM(i->rtscts_rate, AR_RTSCTSRate); - ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1); - ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2); - ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3); + ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower[1], AR_XmitPower1); + ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower[2], AR_XmitPower2); + ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower[3], AR_XmitPower3); } static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 057b1657c428..da84b705cbcd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -101,7 +101,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen) | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(i->txpower, AR_XmitPower0) + | SM(i->txpower[0], AR_XmitPower0) | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0) @@ -152,9 +152,9 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding; - ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1); - ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2); - ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3); + ACCESS_ONCE(ads->ctl20) = SM(i->txpower[1], AR_XmitPower1); + ACCESS_ONCE(ads->ctl21) = SM(i->txpower[2], AR_XmitPower2); + ACCESS_ONCE(ads->ctl22) = SM(i->txpower[3], AR_XmitPower3); } static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index abe8bd6b972d..1a9fe0983a6b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -189,6 +189,7 @@ struct ath_frame_info { u8 rtscts_rate; u8 retries : 7; u8 baw_tracked : 1; + u8 tx_power; }; struct ath_rxbuf { diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index ecb783beeec2..cb366adc820b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -78,7 +78,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, struct ath_tx_info info; struct ieee80211_supported_band *sband; u8 chainmask = ah->txchainmask; - u8 rate = 0; + u8 i, rate = 0; sband = &common->sbands[sc->cur_chandef.chan->band]; rate = sband->bitrates[rateidx].hw_value; @@ -88,7 +88,8 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, memset(&info, 0, sizeof(info)); info.pkt_len = skb->len + FCS_LEN; info.type = ATH9K_PKT_TYPE_BEACON; - info.txpower = MAX_RATE_POWER; + for (i = 0; i < 4; i++) + info.txpower[i] = MAX_RATE_POWER; info.keyix = ATH9K_TXKEYIX_INVALID; info.keytype = ATH9K_KEY_TYPE_CLEAR; info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK; diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index aa69ceaad0be..e55fa11894b6 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -704,7 +704,7 @@ struct ath_tx_info { enum ath9k_pkt_type type; enum ath9k_key_type keytype; u8 keyix; - u8 txpower; + u8 txpower[4]; }; struct ath_hw; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d6e54a3c88f6..e9bd02c2e844 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1096,6 +1096,37 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop) } } +static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, + u8 rateidx) +{ + u8 max_power; + struct ath_hw *ah = sc->sc_ah; + + if (sc->tx99_state) + return MAX_RATE_POWER; + + if (!AR_SREV_9300_20_OR_LATER(ah)) { + /* ar9002 is not sipported for the moment */ + return MAX_RATE_POWER; + } + + if (!bf->bf_state.bfs_paprd) { + struct sk_buff *skb = bf->bf_mpdu; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ath_frame_info *fi = get_frame_info(skb); + + if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) + max_power = min(ah->tx_power_stbc[rateidx], + fi->tx_power); + else + max_power = min(ah->tx_power[rateidx], fi->tx_power); + } else { + max_power = ah->paprd_training_power; + } + + return max_power; +} + static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_info *info, int len, bool rts) { @@ -1166,6 +1197,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; + + info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); continue; } @@ -1193,6 +1226,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, phy, rate->bitrate * 100, len, rix, is_sp); + + info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); } /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ @@ -1239,7 +1274,6 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, memset(&info, 0, sizeof(info)); info.is_first = true; info.is_last = true; - info.txpower = MAX_RATE_POWER; info.qcu = txq->axq_qnum; while (bf) { @@ -2063,6 +2097,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; + fi->tx_power = MAX_RATE_POWER; if (!rate) return; -- GitLab From 51974611154038f1aaf6ce843bdc6445d5684ee3 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 25 Nov 2014 06:43:02 -0800 Subject: [PATCH 6479/9457] mwifiex: fix sparse warning This patch fixes following sparse warnings: drivers/net/wireless/mwifiex/util.c:152:19: warning: cast from restricted __le16 drivers/net/wireless/mwifiex/util.c:152:19: warning: restricted __le16 degrades to integer Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index a113ef8f0b8b..b1768fbf98f2 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -149,7 +149,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, u8 category, action_code; struct ieee80211_hdr *ieee_hdr = (void *)payload; - stype = (cpu_to_le16(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); + stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); switch (stype) { case IEEE80211_STYPE_ACTION: -- GitLab From 798ea8eec16d33e0553b6be7175a23e8ddf60eee Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 25 Nov 2014 06:43:03 -0800 Subject: [PATCH 6480/9457] mwifiex: fix scan problem on big endian platforms This patch adds missing endian conversion for beacon size while processing scan response. Reported-by: Daniel Mosquera Tested-by: Daniel Mosquera Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 3a17821157d7..984a7a4fa93b 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1623,7 +1623,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, if (*bytes_left >= sizeof(beacon_size)) { /* Extract & convert beacon size from command buffer */ - memcpy(&beacon_size, *bss_info, sizeof(beacon_size)); + beacon_size = le16_to_cpu(*(__le16 *)(*bss_info)); *bytes_left -= sizeof(beacon_size); *bss_info += sizeof(beacon_size); } -- GitLab From 381e9fffe6b8343c2479939178ef7ded50bf32d3 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 25 Nov 2014 06:43:04 -0800 Subject: [PATCH 6481/9457] mwifiex: skip delay main work logic for USB interface. We had introduced delay main work logic to avoid processing interrupts when Rx pending packet count reaches high threshold. interrupt processing is restarted later when packet count reduces lower threashold. This helped to reduce unnecessary overhead and improve throughput for SD and PCIe chipsets. As there are no interrupts for USB, we will skip this logic for USB chipsets. Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 0e50120eb807..cf07279bf602 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -149,7 +149,8 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter) /* Check for Rx data */ while ((skb = skb_dequeue(&adapter->rx_data_q))) { atomic_dec(&adapter->rx_pending); - if (adapter->delay_main_work && + if ((adapter->delay_main_work || + adapter->iface_type == MWIFIEX_USB) && (atomic_read(&adapter->rx_pending) < LOW_RX_PENDING)) { if (adapter->if_ops.submit_rem_rx_urbs) adapter->if_ops.submit_rem_rx_urbs(adapter); @@ -202,12 +203,15 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) break; - /* If we process interrupts first, it would increase RX pending - * even further. Avoid this by checking if rx_pending has - * crossed high threshold and schedule rx work queue - * and then process interrupts + /* For non-USB interfaces, If we process interrupts first, it + * would increase RX pending even further. Avoid this by + * checking if rx_pending has crossed high threshold and + * schedule rx work queue and then process interrupts. + * For USB interface, there are no interrupts. We already have + * HIGH_RX_PENDING check in usb.c */ - if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING) { + if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING && + adapter->iface_type != MWIFIEX_USB) { adapter->delay_main_work = true; if (!adapter->rx_processing) queue_work(adapter->rx_workqueue, -- GitLab From 808bbebcc8fcbcb2b93aefd8b181a0fdccb407c6 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 25 Nov 2014 06:43:05 -0800 Subject: [PATCH 6482/9457] mwifiex: add Tx status support for EAPOL packets Firmware notifies the driver through event if EAPOL data packet has been acked or not. We will inform this status to userspace listening on a socket. Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 3 ++ drivers/net/wireless/mwifiex/decl.h | 2 + drivers/net/wireless/mwifiex/fw.h | 17 +++++++-- drivers/net/wireless/mwifiex/init.c | 3 ++ drivers/net/wireless/mwifiex/main.c | 48 ++++++++++++++++++++++++ drivers/net/wireless/mwifiex/main.h | 7 ++++ drivers/net/wireless/mwifiex/sta_event.c | 5 +++ drivers/net/wireless/mwifiex/sta_tx.c | 5 +++ drivers/net/wireless/mwifiex/txrx.c | 20 ++++++++++ drivers/net/wireless/mwifiex/uap_event.c | 4 ++ drivers/net/wireless/mwifiex/uap_txrx.c | 7 +++- drivers/net/wireless/mwifiex/wmm.c | 10 +++++ 12 files changed, 127 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 17f0ee02d6e7..68d5874adc94 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2988,6 +2988,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) NL80211_FEATURE_INACTIVITY_TIMER | NL80211_FEATURE_NEED_OBSS_SCAN; + if (adapter->fw_api_ver == MWIFIEX_FW_V15) + wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; + /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index fc0b1ed80a6a..9daa88a61377 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -76,6 +76,7 @@ #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) #define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) #define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2) +#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3) #define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 #define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 @@ -159,6 +160,7 @@ struct mwifiex_txinfo { u8 bss_num; u8 bss_type; u32 pkt_len; + u8 ack_frame_id; }; enum mwifiex_wmm_ac_e { diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index e095f371545a..fb5936eb82e3 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -494,6 +494,7 @@ enum P2P_MODES { #define EVENT_TDLS_GENERIC_EVENT 0x00000052 #define EVENT_EXT_SCAN_REPORT 0x00000058 #define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f +#define EVENT_TX_STATUS_REPORT 0x00000074 #define EVENT_ID_MASK 0xffff #define BSS_NUM_MASK 0xf @@ -542,6 +543,7 @@ struct mwifiex_ie_types_data { #define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08 #define MWIFIEX_TXPD_FLAGS_TDLS_PACKET 0x10 #define MWIFIEX_RXPD_FLAGS_TDLS_PACKET 0x01 +#define MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS 0x20 struct txpd { u8 bss_type; @@ -553,7 +555,9 @@ struct txpd { u8 priority; u8 flags; u8 pkt_delay_2ms; - u8 reserved1; + u8 reserved1[2]; + u8 tx_token_id; + u8 reserved[2]; } __packed; struct rxpd { @@ -598,8 +602,9 @@ struct uap_txpd { u8 priority; u8 flags; u8 pkt_delay_2ms; - u8 reserved1; - __le32 reserved2; + u8 reserved1[2]; + u8 tx_token_id; + u8 reserved[2]; }; struct uap_rxpd { @@ -1224,6 +1229,12 @@ struct mwifiex_event_scan_result { u8 num_of_set; } __packed; +struct tx_status_event { + u8 packet_type; + u8 tx_token_id; + u8 status; +} __packed; + #define MWIFIEX_USER_SCAN_CHAN_MAX 50 #define MWIFIEX_MAX_SSID_LIST_LENGTH 10 diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index cc15ab81aa66..520ad4a3018b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -473,6 +473,9 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) spin_lock_init(&priv->tx_ba_stream_tbl_lock); spin_lock_init(&priv->rx_reorder_tbl_lock); + + spin_lock_init(&priv->ack_status_lock); + idr_init(&priv->ack_status_frames); } return 0; diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index cf07279bf602..cf31d36a9fdd 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -608,6 +608,44 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) return 0; } +static struct sk_buff * +mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, + struct sk_buff *skb, u8 flag) +{ + struct sk_buff *orig_skb = skb; + struct mwifiex_txinfo *tx_info, *orig_tx_info; + + skb = skb_clone(skb, GFP_ATOMIC); + if (skb) { + unsigned long flags; + int id; + + spin_lock_irqsave(&priv->ack_status_lock, flags); + id = idr_alloc(&priv->ack_status_frames, orig_skb, + 1, 0xff, GFP_ATOMIC); + spin_unlock_irqrestore(&priv->ack_status_lock, flags); + + if (id >= 0) { + tx_info = MWIFIEX_SKB_TXCB(skb); + tx_info->ack_frame_id = id; + tx_info->flags |= flag; + orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb); + orig_tx_info->ack_frame_id = id; + orig_tx_info->flags |= flag; + } else if (skb_shared(skb)) { + kfree_skb(orig_skb); + } else { + kfree_skb(skb); + skb = orig_skb; + } + } else { + /* couldn't clone -- lose tx status ... */ + skb = orig_skb; + } + + return skb; +} + /* * CFG802.11 network device handler for data transmission. */ @@ -617,6 +655,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; + bool multicast; dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", jiffies, priv->bss_type, priv->bss_num); @@ -657,6 +696,15 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_info->bss_type = priv->bss_type; tx_info->pkt_len = skb->len; + multicast = is_multicast_ether_addr(skb->data); + + if (unlikely(!multicast && skb->sk && + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && + priv->adapter->fw_api_ver == MWIFIEX_FW_V15)) + skb = mwifiex_clone_skb_for_tx_status(priv, + skb, + MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS); + /* Record the current time the packet was queued; used to * determine the amount of time the packet was queued in * the driver before it was sent to the firmware. diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 5a690d5210f0..e19fc2f87436 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "decl.h" #include "ioctl.h" @@ -578,6 +579,9 @@ struct mwifiex_private { u8 check_tdls_tx; struct timer_list auto_tdls_timer; bool auto_tdls_timer_active; + struct idr ack_status_frames; + /* spin lock for ack status */ + spinlock_t ack_status_lock; }; enum mwifiex_ba_status { @@ -1335,6 +1339,9 @@ void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac); void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv); void mwifiex_clean_auto_tdls(struct mwifiex_private *priv); +void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, + void *event_body); + #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); void mwifiex_debugfs_remove(void); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 204ecc8faa5b..b8c171df6223 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -504,6 +504,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) ret = mwifiex_parse_tdls_event(priv, adapter->event_skb); break; + case EVENT_TX_STATUS_REPORT: + dev_dbg(adapter->dev, "event: TX_STATUS Report\n"); + mwifiex_parse_tx_status_event(priv, adapter->event_body); + break; + default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", eventcause); diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index dab7b33c54be..c69ecbc1d63f 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -77,6 +77,11 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, local_tx_pd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { + local_tx_pd->tx_token_id = tx_info->ack_frame_id; + local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; + } + if (local_tx_pd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) /* diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index a5983fc4e83a..782bfd61c300 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -203,3 +203,23 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, } EXPORT_SYMBOL_GPL(mwifiex_write_data_complete); +void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, + void *event_body) +{ + struct tx_status_event *tx_status = (void *)priv->adapter->event_body; + struct sk_buff *ack_skb; + unsigned long flags; + + if (!tx_status->tx_token_id) + return; + + spin_lock_irqsave(&priv->ack_status_lock, flags); + ack_skb = idr_find(&priv->ack_status_frames, tx_status->tx_token_id); + if (ack_skb) + idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); + spin_unlock_irqrestore(&priv->ack_status_lock, flags); + + /* consumes ack_skb */ + if (ack_skb) + skb_complete_wifi_ack(ack_skb, !tx_status->status); +} diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index 7c2b97660a03..38390cb85a90 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -172,6 +172,10 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) return mwifiex_handle_event_ext_scan_report(priv, adapter->event_skb->data); break; + case EVENT_TX_STATUS_REPORT: + dev_dbg(adapter->dev, "event: TX_STATUS Report\n"); + mwifiex_parse_tx_status_event(priv, adapter->event_body); + break; default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", eventcause); diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index ec7309d096ab..4580942f6e80 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c @@ -370,10 +370,15 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv, txpd->bss_num = priv->bss_num; txpd->bss_type = priv->bss_type; txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len)); - txpd->priority = (u8)skb->priority; + txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { + txpd->tx_token_id = tx_info->ack_frame_id; + txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; + } + if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) /* * Set the priority specific tx_control field, setting of 0 will diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 94c98a86ebbe..dc1f2adfafc2 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -523,6 +523,13 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) } } +static int mwifiex_free_ack_frame(int id, void *p, void *data) +{ + pr_warn("Have pending ack frames!\n"); + kfree_skb(p); + return 0; +} + /* * This function cleans up the Tx and Rx queues. * @@ -558,6 +565,9 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) mwifiex_write_data_complete(priv->adapter, skb, 0, -1); + + idr_for_each(&priv->ack_status_frames, mwifiex_free_ack_frame, NULL); + idr_destroy(&priv->ack_status_frames); } /* -- GitLab From 18ca43823f3ce111c6efb8cc90d9f35246527727 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 25 Nov 2014 06:43:06 -0800 Subject: [PATCH 6483/9457] mwifiex: add Tx status support for ACTION frames ACK status (0/1) for ACTION frames is informed to cfg80211. We will extend existing logic used for EAPOL frames. The cfg80211 API is different here. Also, we need to explicitly free cloned skb. Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 13 ++++++++++--- drivers/net/wireless/mwifiex/decl.h | 2 ++ drivers/net/wireless/mwifiex/main.c | 10 +++++++--- drivers/net/wireless/mwifiex/main.h | 4 ++++ drivers/net/wireless/mwifiex/sta_tx.c | 3 ++- drivers/net/wireless/mwifiex/txrx.c | 17 ++++++++++++++--- drivers/net/wireless/mwifiex/uap_txrx.c | 3 ++- 7 files changed, 41 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 68d5874adc94..f881044e450d 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -194,10 +194,17 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, tx_info->pkt_len = pkt_len; mwifiex_form_mgmt_frame(skb, buf, len); - mwifiex_queue_tx_pkt(priv, skb); - *cookie = prandom_u32() | 1; - cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC); + + if (ieee80211_is_action(mgmt->frame_control)) + skb = mwifiex_clone_skb_for_tx_status(priv, + skb, + MWIFIEX_BUF_FLAG_ACTION_TX_STATUS, cookie); + else + cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, + GFP_ATOMIC); + + mwifiex_queue_tx_pkt(priv, skb); wiphy_dbg(wiphy, "info: management frame transmitted\n"); return 0; diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 9daa88a61377..2269acf41ad8 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -77,6 +77,7 @@ #define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) #define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2) #define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3) +#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4) #define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 #define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 @@ -161,6 +162,7 @@ struct mwifiex_txinfo { u8 bss_type; u32 pkt_len; u8 ack_frame_id; + u64 cookie; }; enum mwifiex_wmm_ac_e { diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index cf31d36a9fdd..d4d2223d1f31 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -608,9 +608,9 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) return 0; } -static struct sk_buff * +struct sk_buff * mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, - struct sk_buff *skb, u8 flag) + struct sk_buff *skb, u8 flag, u64 *cookie) { struct sk_buff *orig_skb = skb; struct mwifiex_txinfo *tx_info, *orig_tx_info; @@ -632,6 +632,10 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb); orig_tx_info->ack_frame_id = id; orig_tx_info->flags |= flag; + + if (flag == MWIFIEX_BUF_FLAG_ACTION_TX_STATUS && cookie) + orig_tx_info->cookie = *cookie; + } else if (skb_shared(skb)) { kfree_skb(orig_skb); } else { @@ -703,7 +707,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) priv->adapter->fw_api_ver == MWIFIEX_FW_V15)) skb = mwifiex_clone_skb_for_tx_status(priv, skb, - MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS); + MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS, NULL); /* Record the current time the packet was queued; used to * determine the amount of time the packet was queued in diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index e19fc2f87436..bdba37b7015d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1342,6 +1342,10 @@ void mwifiex_clean_auto_tdls(struct mwifiex_private *priv); void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, void *event_body); +struct sk_buff * +mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, + struct sk_buff *skb, u8 flag, u64 *cookie); + #ifdef CONFIG_DEBUG_FS void mwifiex_debugfs_init(void); void mwifiex_debugfs_remove(void); diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index c69ecbc1d63f..b896d7375b52 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -77,7 +77,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, local_tx_pd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); - if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { + if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS || + tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) { local_tx_pd->tx_token_id = tx_info->ack_frame_id; local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; } diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 782bfd61c300..6ae133333363 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -209,6 +209,7 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, struct tx_status_event *tx_status = (void *)priv->adapter->event_body; struct sk_buff *ack_skb; unsigned long flags; + struct mwifiex_txinfo *tx_info; if (!tx_status->tx_token_id) return; @@ -219,7 +220,17 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); spin_unlock_irqrestore(&priv->ack_status_lock, flags); - /* consumes ack_skb */ - if (ack_skb) - skb_complete_wifi_ack(ack_skb, !tx_status->status); + if (ack_skb) { + tx_info = MWIFIEX_SKB_TXCB(ack_skb); + + if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { + /* consumes ack_skb */ + skb_complete_wifi_ack(ack_skb, !tx_status->status); + } else { + cfg80211_mgmt_tx_status(priv->wdev, tx_info->cookie, + ack_skb->data, ack_skb->len, + !tx_status->status, GFP_ATOMIC); + dev_kfree_skb_any(ack_skb); + } + } } diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 4580942f6e80..e7d326f5b96e 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c @@ -374,7 +374,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv, txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); - if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { + if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS || + tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) { txpd->tx_token_id = tx_info->ack_frame_id; txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; } -- GitLab From db0865543739b3edb2ee9bf340380cf4986b58ff Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 25 Nov 2014 11:06:00 -0500 Subject: [PATCH 6484/9457] x86/nmi: Fix use of unallocated cpumask_var_t Commit "x86/nmi: Perform a safe NMI stack trace on all CPUs" has introduced a cpumask_var_t variable: +static cpumask_var_t printtrace_mask; But never allocated it before using it, which caused a NULL ptr deref when trying to print the stack trace: [ 1110.296154] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1110.296169] IP: __memcpy (arch/x86/lib/memcpy_64.S:151) [ 1110.296178] PGD 4c34b3067 PUD 4c351b067 PMD 0 [ 1110.296186] Oops: 0002 [#1] PREEMPT SMP KASAN [ 1110.296234] Dumping ftrace buffer: [ 1110.296330] (ftrace buffer empty) [ 1110.296339] Modules linked in: [ 1110.296345] CPU: 1 PID: 10538 Comm: trinity-c99 Not tainted 3.18.0-rc5-next-20141124-sasha-00058-ge2a8c09-dirty #1499 [ 1110.296348] task: ffff880152650000 ti: ffff8804c3560000 task.ti: ffff8804c3560000 [ 1110.296357] RIP: __memcpy (arch/x86/lib/memcpy_64.S:151) [ 1110.296360] RSP: 0000:ffff8804c3563870 EFLAGS: 00010246 [ 1110.296363] RAX: 0000000000000000 RBX: ffffe8fff3c4a809 RCX: 0000000000000000 [ 1110.296366] RDX: 0000000000000008 RSI: ffffffff9e254040 RDI: 0000000000000000 [ 1110.296369] RBP: ffff8804c3563908 R08: 0000000000ffffff R09: 0000000000ffffff [ 1110.296371] R10: 0000000000000000 R11: 0000000000000006 R12: 0000000000000000 [ 1110.296375] R13: 0000000000000000 R14: ffffffff9e254040 R15: ffffe8fff3c4a809 [ 1110.296379] FS: 00007f9e43b0b700(0000) GS:ffff880107e00000(0000) knlGS:0000000000000000 [ 1110.296382] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 1110.296385] CR2: 0000000000000000 CR3: 00000004e4334000 CR4: 00000000000006a0 [ 1110.296400] Stack: [ 1110.296406] ffffffff81b1e46c 0000000000000000 ffff880107e03fb8 000000000000000b [ 1110.296413] ffff880107dfffc0 ffff880107e03fc0 0000000000000008 ffffffff93f2e9c8 [ 1110.296419] 0000000000000000 ffffda0020fc07f7 0000000000000008 ffff8804c3563901 [ 1110.296420] Call Trace: [ 1110.296429] ? memcpy (mm/kasan/kasan.c:275) [ 1110.296437] ? arch_trigger_all_cpu_backtrace (include/linux/bitmap.h:215 include/linux/cpumask.h:506 arch/x86/kernel/apic/hw_nmi.c:76) [ 1110.296444] arch_trigger_all_cpu_backtrace (include/linux/bitmap.h:215 include/linux/cpumask.h:506 arch/x86/kernel/apic/hw_nmi.c:76) [ 1110.296451] ? dump_stack (./arch/x86/include/asm/preempt.h:95 lib/dump_stack.c:55) [ 1110.296458] do_raw_spin_lock (./arch/x86/include/asm/spinlock.h:86 kernel/locking/spinlock_debug.c:130 kernel/locking/spinlock_debug.c:137) [ 1110.296468] _raw_spin_lock (include/linux/spinlock_api_smp.h:143 kernel/locking/spinlock.c:151) [ 1110.296474] ? __page_check_address (include/linux/spinlock.h:309 mm/rmap.c:630) [ 1110.296481] __page_check_address (include/linux/spinlock.h:309 mm/rmap.c:630) [ 1110.296487] ? preempt_count_sub (kernel/sched/core.c:2615) [ 1110.296493] try_to_unmap_one (include/linux/rmap.h:202 mm/rmap.c:1146) [ 1110.296504] ? anon_vma_interval_tree_iter_next (mm/interval_tree.c:72 mm/interval_tree.c:103) [ 1110.296514] rmap_walk (mm/rmap.c:1653 mm/rmap.c:1725) [ 1110.296521] ? page_get_anon_vma (include/linux/rcupdate.h:423 include/linux/rcupdate.h:935 mm/rmap.c:435) [ 1110.296530] try_to_unmap (mm/rmap.c:1545) [ 1110.296536] ? page_get_anon_vma (mm/rmap.c:437) [ 1110.296545] ? try_to_unmap_nonlinear (mm/rmap.c:1138) [ 1110.296551] ? SyS_msync (mm/rmap.c:1501) [ 1110.296558] ? page_remove_rmap (mm/rmap.c:1409) [ 1110.296565] ? page_get_anon_vma (mm/rmap.c:448) [ 1110.296571] ? anon_vma_ctor (mm/rmap.c:1496) [ 1110.296579] migrate_pages (mm/migrate.c:913 mm/migrate.c:956 mm/migrate.c:1136) [ 1110.296586] ? _raw_spin_unlock_irq (./arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:169 kernel/locking/spinlock.c:199) [ 1110.296593] ? buffer_migrate_lock_buffers (mm/migrate.c:1584) [ 1110.296601] ? handle_mm_fault (mm/memory.c:3163 mm/memory.c:3223 mm/memory.c:3336 mm/memory.c:3365) [ 1110.296607] migrate_misplaced_page (mm/migrate.c:1738) [ 1110.296614] handle_mm_fault (mm/memory.c:3170 mm/memory.c:3223 mm/memory.c:3336 mm/memory.c:3365) [ 1110.296623] __do_page_fault (arch/x86/mm/fault.c:1246) [ 1110.296630] ? vtime_account_user (kernel/sched/cputime.c:701) [ 1110.296638] ? get_parent_ip (kernel/sched/core.c:2559) [ 1110.296646] ? context_tracking_user_exit (kernel/context_tracking.c:144) [ 1110.296656] trace_do_page_fault (arch/x86/mm/fault.c:1329 include/linux/jump_label.h:114 include/linux/context_tracking_state.h:27 include/linux/context_tracking.h:45 arch/x86/mm/fault.c:1330) [ 1110.296664] do_async_page_fault (arch/x86/kernel/kvm.c:280) [ 1110.296670] async_page_fault (arch/x86/kernel/entry_64.S:1285) [ 1110.296755] Code: 08 4c 8b 54 16 f0 4c 8b 5c 16 f8 4c 89 07 4c 89 4f 08 4c 89 54 17 f0 4c 89 5c 17 f8 c3 90 83 fa 08 72 1b 4c 8b 06 4c 8b 4c 16 f8 <4c> 89 07 4c 89 4c 17 f8 c3 66 2e 0f 1f 84 00 00 00 00 00 83 fa All code ======== 0: 08 4c 8b 54 or %cl,0x54(%rbx,%rcx,4) 4: 16 (bad) 5: f0 4c 8b 5c 16 f8 lock mov -0x8(%rsi,%rdx,1),%r11 b: 4c 89 07 mov %r8,(%rdi) e: 4c 89 4f 08 mov %r9,0x8(%rdi) 12: 4c 89 54 17 f0 mov %r10,-0x10(%rdi,%rdx,1) 17: 4c 89 5c 17 f8 mov %r11,-0x8(%rdi,%rdx,1) 1c: c3 retq 1d: 90 nop 1e: 83 fa 08 cmp $0x8,%edx 21: 72 1b jb 0x3e 23: 4c 8b 06 mov (%rsi),%r8 26: 4c 8b 4c 16 f8 mov -0x8(%rsi,%rdx,1),%r9 2b:* 4c 89 07 mov %r8,(%rdi) <-- trapping instruction 2e: 4c 89 4c 17 f8 mov %r9,-0x8(%rdi,%rdx,1) 33: c3 retq 34: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 3b: 00 00 00 3e: 83 fa 00 cmp $0x0,%edx Code starting with the faulting instruction =========================================== 0: 4c 89 07 mov %r8,(%rdi) 3: 4c 89 4c 17 f8 mov %r9,-0x8(%rdi,%rdx,1) 8: c3 retq 9: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 10: 00 00 00 13: 83 fa 00 cmp $0x0,%edx [ 1110.296760] RIP __memcpy (arch/x86/lib/memcpy_64.S:151) [ 1110.296763] RSP [ 1110.296765] CR2: 0000000000000000 Link: http://lkml.kernel.org/r/1416931560-10603-1-git-send-email-sasha.levin@oracle.com Signed-off-by: Sasha Levin Signed-off-by: Steven Rostedt --- arch/x86/kernel/apic/hw_nmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index c95c3e9ce196..6873ab925d00 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -30,7 +30,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh) #ifdef arch_trigger_all_cpu_backtrace /* For reliability, we're prepared to waste bits here. */ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; -static cpumask_var_t printtrace_mask; +static cpumask_t printtrace_mask; #define NMI_BUF_SIZE 4096 @@ -73,7 +73,7 @@ void arch_trigger_all_cpu_backtrace(bool include_self) if (!include_self) cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); - cpumask_copy(printtrace_mask, to_cpumask(backtrace_mask)); + cpumask_copy(&printtrace_mask, to_cpumask(backtrace_mask)); /* * Set up per_cpu seq_buf buffers that the NMIs running on the other * CPUs will write to. @@ -101,7 +101,7 @@ void arch_trigger_all_cpu_backtrace(bool include_self) * Now that all the NMIs have triggered, we can dump out their * back traces safely to the console. */ - for_each_cpu(cpu, printtrace_mask) { + for_each_cpu(cpu, &printtrace_mask) { int last_i = 0; s = &per_cpu(nmi_print_seq, cpu); -- GitLab From 69b93607a9862b1db2f0f2e078e1396f8e20fa9b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 25 Nov 2014 20:29:40 +0100 Subject: [PATCH 6485/9457] ASoC: qi_lb60: Pass flags to gpiod_get() Pass flags to gpiod_get() to automatically configure the GPIOs. This is shorter and not passing any flags to gpiod_get() will eventually no longer be supported. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/jz4740/qi_lb60.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 5cb91f9e8626..0fb7d2a91c3a 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -77,25 +77,18 @@ static int qi_lb60_probe(struct platform_device *pdev) { struct qi_lb60 *qi_lb60; struct snd_soc_card *card = &qi_lb60_card; - int ret; qi_lb60 = devm_kzalloc(&pdev->dev, sizeof(*qi_lb60), GFP_KERNEL); if (!qi_lb60) return -ENOMEM; - qi_lb60->snd_gpio = devm_gpiod_get(&pdev->dev, "snd"); + qi_lb60->snd_gpio = devm_gpiod_get(&pdev->dev, "snd", GPIOD_OUT_LOW); if (IS_ERR(qi_lb60->snd_gpio)) return PTR_ERR(qi_lb60->snd_gpio); - ret = gpiod_direction_output(qi_lb60->snd_gpio, 0); - if (ret) - return ret; - qi_lb60->amp_gpio = devm_gpiod_get(&pdev->dev, "amp"); + qi_lb60->amp_gpio = devm_gpiod_get(&pdev->dev, "amp", GPIOD_OUT_LOW); if (IS_ERR(qi_lb60->amp_gpio)) return PTR_ERR(qi_lb60->amp_gpio); - ret = gpiod_direction_output(qi_lb60->amp_gpio, 0); - if (ret) - return ret; card->dev = &pdev->dev; -- GitLab From ce3e6d25f3fbaf48a3e1914d5ac0ddfdc1b38349 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 24 Nov 2014 15:52:00 +0100 Subject: [PATCH 6486/9457] f2fs: fix typos for the word "destroy" in jump labels Two jump labels were adjusted in the implementation of the create_node_manager_caches() function because these identifiers contained typos. Signed-off-by: Markus Elfring Acked-by: Randy Dunlap Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index dbf49cc80297..36656add1c9b 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -2083,17 +2083,17 @@ int __init create_node_manager_caches(void) free_nid_slab = f2fs_kmem_cache_create("free_nid", sizeof(struct free_nid)); if (!free_nid_slab) - goto destory_nat_entry; + goto destroy_nat_entry; nat_entry_set_slab = f2fs_kmem_cache_create("nat_entry_set", sizeof(struct nat_entry_set)); if (!nat_entry_set_slab) - goto destory_free_nid; + goto destroy_free_nid; return 0; -destory_free_nid: +destroy_free_nid: kmem_cache_destroy(free_nid_slab); -destory_nat_entry: +destroy_nat_entry: kmem_cache_destroy(nat_entry_slab); fail: return -ENOMEM; -- GitLab From 5f72739583a29bfaa57448ec2c9b122995d0ae4f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 25 Nov 2014 10:59:45 -0800 Subject: [PATCH 6487/9457] f2fs: fix deadlock during inline_data conversion A deadlock can be occurred: Thread 1] Thread 2] - f2fs_write_data_pages - f2fs_write_begin - lock_page(page #0) - grab_cache_page(page #X) - get_node_page(inode_page) - grab_cache_page(page #0) : to convert inline_data - f2fs_write_data_page - f2fs_write_inline_data - get_node_page(inode_page) In this case, trying to lock inode_page and page #0 causes deadlock. In order to avoid this, this patch adds a rule for this locking policy, which is that page #0 should be locked followed by inode_page lock. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 12dd58aa569a..c7bc62641103 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -936,6 +936,17 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, trace_f2fs_write_begin(inode, pos, len, flags); f2fs_balance_fs(sbi); + + /* + * We should check this at this moment to avoid deadlock on inode page + * and #0 page. The locking rule for inline_data conversion should be: + * lock_page(page #0) -> lock_page(inode_page) + */ + if (index != 0) { + err = f2fs_convert_inline_inode(inode); + if (err) + goto fail; + } repeat: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { @@ -960,21 +971,10 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, set_inode_flag(F2FS_I(inode), FI_DATA_EXIST); sync_inode_page(&dn); goto put_next; - } else if (page->index == 0) { - err = f2fs_convert_inline_page(&dn, page); - if (err) - goto put_fail; - } else { - struct page *p = grab_cache_page(inode->i_mapping, 0); - if (!p) { - err = -ENOMEM; - goto put_fail; - } - err = f2fs_convert_inline_page(&dn, p); - f2fs_put_page(p, 1); - if (err) - goto put_fail; } + err = f2fs_convert_inline_page(&dn, page); + if (err) + goto put_fail; } err = f2fs_reserve_block(&dn, index); if (err) -- GitLab From dfe0487249e57baec0acccaa81fadad186b489b3 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 25 Nov 2014 18:42:54 +0200 Subject: [PATCH 6488/9457] .gitignore: Add Kdevelop4 project files I'm not sure what is the costume with such IDE project files. Most might be dot-files. It is kind of annoying for the Kdevelop4 user. So please consider adding *.kdev4 files to be ignored? Signed-off-by: Boaz Harrosh [mmarek: Moved at the and and added a comment] Signed-off-by: Michal Marek --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e213b27f3921..ce57b79670a5 100644 --- a/.gitignore +++ b/.gitignore @@ -96,3 +96,6 @@ x509.genkey # Kconfig presets all.config + +# Kdevelop4 +*.kdev4 -- GitLab From 23173eae7b9a5389d3f7031b77cde34f63b814a2 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Tue, 25 Nov 2014 02:20:55 +0400 Subject: [PATCH 6489/9457] omap: i2c: don't check bus state IP rev3.3 and earlier Commit 0f5768bf894f ("i2c: omap: implement workaround for handling invalid BB-bit values") introduce the error result in boot test fault on OMAP3530 boards. The patch fix the error (disable i2c bus test for OMAP3530). Reported-by: Kevin Hilman Signed-off-by: Alexander Kochetkov Fixes: 0f5768bf894f ("i2c: omap: implement workaround for handling invalid BB-bit values") Tested-by: Tony Lindgren Tested-by: Kevin Hilman Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 9f5b57a50c54..94c2259e9af2 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -344,8 +344,10 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev) /* SYSC register is cleared by the reset; rewrite it */ omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, sysc); - /* Schedule I2C-bus monitoring on the next transfer */ - dev->bb_valid = 0; + if (dev->rev > OMAP_I2C_REV_ON_3430_3530) { + /* Schedule I2C-bus monitoring on the next transfer */ + dev->bb_valid = 0; + } } return 0; @@ -460,7 +462,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev->scllstate = scll; dev->sclhstate = sclh; - if (dev->rev < OMAP_I2C_OMAP1_REV_2) { + if (dev->rev <= OMAP_I2C_REV_ON_3430_3530) { /* Not implemented */ dev->bb_valid = 1; } -- GitLab From 86261fdd65ce076c0aa05dbf3f5f5fe10aab1bcf Mon Sep 17 00:00:00 2001 From: Petr Cvek Date: Tue, 25 Nov 2014 06:05:33 +0100 Subject: [PATCH 6490/9457] i2c: pxa: add support for SCCB devices Add support for SCCB by implementing I2C_M_IGNORE_NAK and I2C_M_STOP flags and advertising functionality flag I2C_FUNC_PROTOCOL_MANGLING. Also fixed missing functionality flag I2C_FUNC_NOSTART. Signed-off-by: Petr Cvek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-pxa.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index be671f7a0e06..f80df8f84609 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -885,7 +885,9 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr) return; /* ignore */ } - if (isr & ISR_BED) { + if ((isr & ISR_BED) && + (!((i2c->msg->flags & I2C_M_IGNORE_NAK) && + (isr & ISR_ACKNAK)))) { int ret = BUS_ERROR; /* @@ -919,12 +921,14 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr) icr |= ICR_ALDIE | ICR_TB; /* - * If this is the last byte of the last message, send - * a STOP. + * If this is the last byte of the last message or last byte + * of any message with I2C_M_STOP (e.g. SCCB), send a STOP. */ - if (i2c->msg_ptr == i2c->msg->len && - i2c->msg_idx == i2c->msg_num - 1) - icr |= ICR_STOP; + if ((i2c->msg_ptr == i2c->msg->len) && + ((i2c->msg->flags & I2C_M_STOP) || + (i2c->msg_idx == i2c->msg_num - 1))) + icr |= ICR_STOP; + } else if (i2c->msg_idx < i2c->msg_num - 1) { /* * Next segment of the message. @@ -1071,7 +1075,8 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num static u32 i2c_pxa_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART; } static const struct i2c_algorithm i2c_pxa_algorithm = { -- GitLab From e874bf5f7647a9fdf14d72dbb376ec95327e3a81 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 25 Nov 2014 21:41:03 +0100 Subject: [PATCH 6491/9457] ASoC: Disable regmap helpers if regmap is disabled If regmap is disabled there will be no users of the ASoC regmap helpers. Furthermore regmap_exit() will no be defined causing the following compile error: sound/soc/soc-core.c: In function 'snd_soc_component_exit_regmap': sound/soc/soc-core.c:2645:2: error: implicit declaration of function 'regmap_exit' [-Werror=implicit-function-declaration] So disable the helpers if regmap is disabled. Reported-by: kbuild test robot Fixes: 20feb881988c ASoC: Add helper functions for deferred regmap setup") Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ++++ sound/soc/soc-core.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 80ca937a20da..b53234835936 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1286,6 +1286,8 @@ void snd_soc_component_async_complete(struct snd_soc_component *component); int snd_soc_component_test_bits(struct snd_soc_component *component, unsigned int reg, unsigned int mask, unsigned int value); +#ifdef CONFIG_REGMAP + void snd_soc_component_init_regmap(struct snd_soc_component *component, struct regmap *regmap); void snd_soc_component_exit_regmap(struct snd_soc_component *component); @@ -1321,6 +1323,8 @@ static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec) snd_soc_component_exit_regmap(&codec->component); } +#endif + /* device driver data */ static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index db74c061f520..1edc519d6286 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3661,6 +3661,8 @@ static void snd_soc_component_setup_regmap(struct snd_soc_component *component) component->val_bytes = val_bytes; } +#ifdef CONFIG_REGMAP + /** * snd_soc_component_init_regmap() - Initialize regmap instance for the component * @component: The component for which to initialize the regmap instance @@ -3696,6 +3698,8 @@ void snd_soc_component_exit_regmap(struct snd_soc_component *component) } EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap); +#endif + static void snd_soc_component_add_unlocked(struct snd_soc_component *component) { if (!component->write && !component->read) { -- GitLab From 58d86a50eee6f8d5a4768f739d10d94f9994180f Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Tue, 25 Nov 2014 16:17:29 -0500 Subject: [PATCH 6492/9457] ext4: update comments regarding ext4_delete_inode() ext4_delete_inode() has been renamed for a long time, update comments for this. Signed-off-by: Wang Shilong Signed-off-by: Theodore Ts'o --- fs/ext4/inode.c | 2 +- fs/ext4/migrate.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b416b461fa50..5653fa42930b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3620,7 +3620,7 @@ void ext4_truncate(struct inode *inode) * If this was a simple ftruncate() and the file will remain alive, * then we need to clear up the orphan record which we created above. * However, if this was a real unlink then we were called by - * ext4_delete_inode(), and we allow that function to clean up the + * ext4_evict_inode(), and we allow that function to clean up the * orphan info for us. */ if (inode->i_nlink) diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index a432634f2e6a..3cb267aee802 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -592,7 +592,7 @@ int ext4_ext_migrate(struct inode *inode) /* * set the i_blocks count to zero - * so that the ext4_delete_inode does the + * so that the ext4_evict_inode() does the * right job * * We don't need to take the i_lock because -- GitLab From c6d3d56dd0ef6c15fc007413c9d024021c178cf9 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 25 Nov 2014 16:20:50 -0500 Subject: [PATCH 6493/9457] ext4: create nojournal_checksum mount option Create a mount option to disable journal checksumming (because the metadata_csum feature turns it on by default now), and fix remount not to allow changing the journal checksumming option, since changing the mount options has no effect on the journal. Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o --- fs/ext4/super.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b643009fddfe..3bd2982da36d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1136,7 +1136,7 @@ enum { Opt_inode_readahead_blks, Opt_journal_ioprio, Opt_dioread_nolock, Opt_dioread_lock, Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, - Opt_max_dir_size_kb, + Opt_max_dir_size_kb, Opt_nojournal_checksum, }; static const match_table_t tokens = { @@ -1170,6 +1170,7 @@ static const match_table_t tokens = { {Opt_journal_dev, "journal_dev=%u"}, {Opt_journal_path, "journal_path=%s"}, {Opt_journal_checksum, "journal_checksum"}, + {Opt_nojournal_checksum, "nojournal_checksum"}, {Opt_journal_async_commit, "journal_async_commit"}, {Opt_abort, "abort"}, {Opt_data_journal, "data=journal"}, @@ -1351,6 +1352,8 @@ static const struct mount_opts { MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, MOPT_EXT4_ONLY | MOPT_CLEAR}, + {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, + MOPT_EXT4_ONLY | MOPT_CLEAR}, {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_EXT4_ONLY | MOPT_SET}, {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | @@ -4844,6 +4847,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } + if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^ + test_opt(sb, JOURNAL_CHECKSUM)) { + ext4_msg(sb, KERN_ERR, "changing journal_checksum " + "during remount not supported"); + err = -EINVAL; + goto restore_opts; + } + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { if (test_opt2(sb, EXPLICIT_DELALLOC)) { ext4_msg(sb, KERN_ERR, "can't mount with " -- GitLab From edef1297f33a4546559d905457b435a5ea160bab Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:15:09 -0500 Subject: [PATCH 6494/9457] SUNRPC: serialize iostats updates Occasionally mountstats reports a negative retransmission rate. Ensure that two RPCs completing concurrently don't confuse the sums in the transport's op_metrics array. Since pNFS filelayout can invoke rpc_count_iostats() on another transport from xprt_release(), we can't rely on simply holding the transport_lock in xprt_release(). There's nothing for it but hard serialization. One spin lock per RPC operation should make this as painless as it can be. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/linux/sunrpc/metrics.h | 3 +++ net/sunrpc/stats.c | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h index 1565bbe86d51..eecb5a71e6c0 100644 --- a/include/linux/sunrpc/metrics.h +++ b/include/linux/sunrpc/metrics.h @@ -27,10 +27,13 @@ #include #include +#include #define RPC_IOSTATS_VERS "1.0" struct rpc_iostats { + spinlock_t om_lock; + /* * These counters give an idea about how many request * transmissions are required, on average, to complete that diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 54530490944e..9711a155bc50 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -116,7 +116,15 @@ EXPORT_SYMBOL_GPL(svc_seq_show); */ struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { - return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); + struct rpc_iostats *stats; + int i; + + stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL); + if (stats) { + for (i = 0; i < clnt->cl_maxproc; i++) + spin_lock_init(&stats[i].om_lock); + } + return stats; } EXPORT_SYMBOL_GPL(rpc_alloc_iostats); @@ -135,20 +143,21 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats); * rpc_count_iostats - tally up per-task stats * @task: completed rpc_task * @stats: array of stat structures - * - * Relies on the caller for serialization. */ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) { struct rpc_rqst *req = task->tk_rqstp; struct rpc_iostats *op_metrics; - ktime_t delta; + ktime_t delta, now; if (!stats || !req) return; + now = ktime_get(); op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; + spin_lock(&op_metrics->om_lock); + op_metrics->om_ops++; op_metrics->om_ntrans += req->rq_ntrans; op_metrics->om_timeouts += task->tk_timeouts; @@ -161,8 +170,10 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt); - delta = ktime_sub(ktime_get(), task->tk_start); + delta = ktime_sub(now, task->tk_start); op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta); + + spin_unlock(&op_metrics->om_lock); } EXPORT_SYMBOL_GPL(rpc_count_iostats); -- GitLab From 6dd3436b9dc0df4b9ae7bb4e0076996a5ffda219 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:15:18 -0500 Subject: [PATCH 6495/9457] NFS: SETCLIENTID XDR buffer sizes are incorrect Use the correct calculation of the maximum size of a clientaddr4 when encoding and decoding SETCLIENTID operations. clientaddr4 is defined in section 2.2.10 of RFC3530bis-31. The usage in encode_setclientid_maxsz is missing the 4-byte length in both strings, but is otherwise correct. decode_setclientid_maxsz simply asks for a page of receive buffer space, which is unnecessarily large (more than 4KB). Note that a SETCLIENTID reply is either clientid+verifier, or clientaddr4, depending on the returned NFS status. It doesn't hurt to allocate enough space for both. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/nfs4xdr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 206c08a60c7f..f8afa6783fb8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -141,13 +141,15 @@ static int nfs4_stat_to_errno(int); XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \ XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \ 1 /* sc_prog */ + \ - XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ - XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \ + 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ + 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \ 1) /* sc_cb_ident */ #define decode_setclientid_maxsz \ (op_decode_hdr_maxsz + \ - 2 + \ - 1024) /* large value for CLID_INUSE */ + 2 /* clientid */ + \ + XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \ + 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ + 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN)) #define encode_setclientid_confirm_maxsz \ (op_encode_hdr_maxsz + \ 3 + (NFS4_VERIFIER_SIZE >> 2)) -- GitLab From c2ef47b7f518f5eae5ffed11b8ac754fb263d398 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 8 Nov 2014 20:15:26 -0500 Subject: [PATCH 6496/9457] NFS: Clean up nfs4_init_callback() nfs4_init_callback() is never invoked for NFS versions other than 4. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/nfs4client.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index ffdb28d86cf8..5f4b818182f9 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -241,28 +241,25 @@ void nfs4_free_client(struct nfs_client *clp) */ static int nfs4_init_callback(struct nfs_client *clp) { + struct rpc_xprt *xprt; int error; - if (clp->rpc_ops->version == 4) { - struct rpc_xprt *xprt; + xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt); - xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt); - - if (nfs4_has_session(clp)) { - error = xprt_setup_backchannel(xprt, - NFS41_BC_MIN_CALLBACKS); - if (error < 0) - return error; - } - - error = nfs_callback_up(clp->cl_mvops->minor_version, xprt); - if (error < 0) { - dprintk("%s: failed to start callback. Error = %d\n", - __func__, error); + if (nfs4_has_session(clp)) { + error = xprt_setup_backchannel(xprt, NFS41_BC_MIN_CALLBACKS); + if (error < 0) return error; - } - __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state); } + + error = nfs_callback_up(clp->cl_mvops->minor_version, xprt); + if (error < 0) { + dprintk("%s: failed to start callback. Error = %d\n", + __func__, error); + return error; + } + __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state); + return 0; } -- GitLab From 733ded2a803523f9e082282820821343679cadc6 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 16:23:48 -0500 Subject: [PATCH 6497/9457] ext4: remove never taken branch from ext4_ext_shift_path_extents() path[depth].p_hdr can never be NULL for a path passed to us (and even if it could, EXT_LAST_EXTENT() would make something != NULL from it). So just remove the branch. Coverity-id: 1196498 Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/extents.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e2424bafd6fe..c3a1fa1398f5 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5249,8 +5249,6 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, return -EIO; ex_last = EXT_LAST_EXTENT(path[depth].p_hdr); - if (!ex_last) - return -EIO; err = ext4_access_path(handle, inode, path + depth); if (err) -- GitLab From b003b52496b9bea9b186b127aea730b79d2a83bd Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 25 Nov 2014 16:27:44 -0500 Subject: [PATCH 6498/9457] ext4: don't count external journal blocks as overhead This was fixed for ext3 with: e6d8fb3 ext3: Count internal journal as bsddf overhead in ext3_statfs but was never fixed for ext4. With a large external journal and no used disk blocks, df comes out negative without this, as journal blocks are added to the overhead & subtracted from used blocks unconditionally. Signed-off-by: Eric Sandeen Signed-off-by: Theodore Ts'o --- fs/ext4/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3bd2982da36d..f8ad756bb852 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3331,8 +3331,8 @@ int ext4_calculate_overhead(struct super_block *sb) memset(buf, 0, PAGE_SIZE); cond_resched(); } - /* Add the journal blocks as well */ - if (sbi->s_journal) + /* Add the internal journal blocks as well */ + if (sbi->s_journal && !sbi->journal_bdev) overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); sbi->s_overhead = overhead; -- GitLab From 31fc006b12f2c7e88fa5ee8f7f17ed0f85c9e4b8 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 25 Nov 2014 16:34:38 -0500 Subject: [PATCH 6499/9457] ext4: remove unneeded code in ext4_unlink Setting retval to zero is not needed in ext4_unlink. Remove unneeded code. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Signed-off-by: Theodore Ts'o --- fs/ext4/namei.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 426211882f72..2291923dae4e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2814,7 +2814,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) ext4_orphan_add(handle, inode); inode->i_ctime = ext4_current_time(inode); ext4_mark_inode_dirty(handle, inode); - retval = 0; end_unlink: brelse(bh); -- GitLab From f4ac1674f5da420ef17896f0f222c5215ebcde80 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 25 Nov 2014 13:18:15 -0500 Subject: [PATCH 6500/9457] nfs: Add ALLOCATE support This patch adds support for using the NFS v4.2 operation ALLOCATE to preallocate data in a file. Signed-off-by: Anna Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 1 + fs/nfs/nfs42.h | 1 + fs/nfs/nfs42proc.c | 58 ++++++++++++++++++++++++++++++ fs/nfs/nfs42xdr.c | 75 +++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4file.c | 28 +++++++++++++++ fs/nfs/nfs4proc.c | 3 +- fs/nfs/nfs4xdr.c | 1 + include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 14 ++++++++ 11 files changed, 183 insertions(+), 1 deletion(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2b48ce58a584..4bffe637ea32 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode) nfs_zap_caches_locked(inode); spin_unlock(&inode->i_lock); } +EXPORT_SYMBOL_GPL(nfs_zap_caches); void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) { diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index d10333a197bf..42656a9cf485 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -6,6 +6,7 @@ #define __LINUX_FS_NFS_NFS4_2_H /* nfs4.2proc.c */ +int nfs42_proc_allocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); /* nfs4.2xdr.h */ diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 056f5aafecc1..581f34e9d8a0 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -32,6 +32,64 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file, return ret; } +static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, + loff_t offset, loff_t len) +{ + struct inode *inode = file_inode(filep); + struct nfs42_falloc_args args = { + .falloc_fh = NFS_FH(inode), + .falloc_offset = offset, + .falloc_length = len, + }; + struct nfs42_falloc_res res; + struct nfs_server *server = NFS_SERVER(inode); + int status; + + msg->rpc_argp = &args; + msg->rpc_resp = &res; + + status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE); + if (status) + return status; + + return nfs4_call_sync(server->client, server, msg, + &args.seq_args, &res.seq_res, 0); +} + +static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, + loff_t offset, loff_t len) +{ + struct nfs_server *server = NFS_SERVER(file_inode(filep)); + struct nfs4_exception exception = { }; + int err; + + do { + err = _nfs42_proc_fallocate(msg, filep, offset, len); + if (err == -ENOTSUPP) + return -EOPNOTSUPP; + err = nfs4_handle_exception(server, err, &exception); + } while (exception.retry); + + return err; +} + +int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len) +{ + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE], + }; + struct inode *inode = file_inode(filep); + int err; + + if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE)) + return -EOPNOTSUPP; + + err = nfs42_proc_fallocate(&msg, filep, offset, len); + if (err == -EOPNOTSUPP) + NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE; + return err; +} + loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) { struct inode *inode = file_inode(filep); diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index c90469b604b8..4248d034479c 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -4,6 +4,12 @@ #ifndef __LINUX_FS_NFS_NFS4_2XDR_H #define __LINUX_FS_NFS_NFS4_2XDR_H +#define encode_fallocate_maxsz (encode_stateid_maxsz + \ + 2 /* offset */ + \ + 2 /* length */) +#define encode_allocate_maxsz (op_encode_hdr_maxsz + \ + encode_fallocate_maxsz) +#define decode_allocate_maxsz (op_decode_hdr_maxsz) #define encode_seek_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + \ 2 /* offset */ + \ @@ -14,6 +20,12 @@ 2 /* offset */ + \ 2 /* length */) +#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_allocate_maxsz) +#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_allocate_maxsz) #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_seek_maxsz) @@ -22,6 +34,22 @@ decode_seek_maxsz) +static void encode_fallocate(struct xdr_stream *xdr, + struct nfs42_falloc_args *args) +{ + encode_nfs4_stateid(xdr, &args->falloc_stateid); + encode_uint64(xdr, args->falloc_offset); + encode_uint64(xdr, args->falloc_length); +} + +static void encode_allocate(struct xdr_stream *xdr, + struct nfs42_falloc_args *args, + struct compound_hdr *hdr) +{ + encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); + encode_fallocate(xdr, args); +} + static void encode_seek(struct xdr_stream *xdr, struct nfs42_seek_args *args, struct compound_hdr *hdr) @@ -32,6 +60,24 @@ static void encode_seek(struct xdr_stream *xdr, encode_uint32(xdr, args->sa_what); } +/* + * Encode ALLOCATE request + */ +static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs42_falloc_args *args) +{ + struct compound_hdr hdr = { + .minorversion = nfs4_xdr_minorversion(&args->seq_args), + }; + + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->falloc_fh, &hdr); + encode_allocate(xdr, args, &hdr); + encode_nops(&hdr); +} + /* * Encode SEEK request */ @@ -50,6 +96,11 @@ static void nfs4_xdr_enc_seek(struct rpc_rqst *req, encode_nops(&hdr); } +static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) +{ + return decode_op_hdr(xdr, OP_ALLOCATE); +} + static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) { int status; @@ -72,6 +123,30 @@ static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) return -EIO; } +/* + * Decode ALLOCATE request + */ +static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs42_falloc_res *res) +{ + struct compound_hdr hdr; + int status; + + status = decode_compound_hdr(xdr, &hdr); + if (status) + goto out; + status = decode_sequence(xdr, &res->seq_res, rqstp); + if (status) + goto out; + status = decode_putfh(xdr); + if (status) + goto out; + status = decode_allocate(xdr, res); +out: + return status; +} + /* * Decode SEEK request */ diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index be6cac37ea10..a08178764cf9 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -226,6 +226,7 @@ int nfs4_replace_transport(struct nfs_server *server, const struct nfs4_fs_locations *locations); /* nfs4proc.c */ +extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *); extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *, struct rpc_message *, struct nfs4_sequence_args *, struct nfs4_sequence_res *, int); diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index c51fb4db9bfe..f78e9fd0735a 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -3,6 +3,8 @@ * * Copyright (C) 1992 Rick Sladkey */ +#include +#include #include #include "internal.h" #include "fscache.h" @@ -134,6 +136,29 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) return nfs_file_llseek(filep, offset, whence); } } + +static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len) +{ + struct inode *inode = file_inode(filep); + long ret; + + if (!S_ISREG(inode->i_mode)) + return -EOPNOTSUPP; + + if (mode != 0) + return -EOPNOTSUPP; + + ret = inode_newsize_ok(inode, offset + len); + if (ret < 0) + return ret; + + mutex_lock(&inode->i_mutex); + ret = nfs42_proc_allocate(filep, offset, len); + mutex_unlock(&inode->i_mutex); + + nfs_zap_caches(inode); + return ret; +} #endif /* CONFIG_NFS_V4_2 */ const struct file_operations nfs4_file_operations = { @@ -155,6 +180,9 @@ const struct file_operations nfs4_file_operations = { .flock = nfs_flock, .splice_read = nfs_file_splice_read, .splice_write = iter_file_splice_write, +#ifdef CONFIG_NFS_V4_2 + .fallocate = nfs42_fallocate, +#endif /* CONFIG_NFS_V4_2 */ .check_flags = nfs_check_flags, .setlease = simple_nosetlease, }; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3138913d1cdf..b1b403b0ca0d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -342,7 +342,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) /* This is the error handling routine for processes that are allowed * to sleep. */ -static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) +int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) { struct nfs_client *clp = server->nfs_client; struct nfs4_state *state = exception->state; @@ -8424,6 +8424,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | NFS_CAP_POSIX_LOCK | NFS_CAP_STATEID_NFSV41 | NFS_CAP_ATOMIC_OPEN_V1 + | NFS_CAP_ALLOCATE | NFS_CAP_SEEK, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 206c08a60c7f..0a1484561e4b 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7394,6 +7394,7 @@ struct rpc_procinfo nfs4_procedures[] = { #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 PROC(SEEK, enc_seek, dec_seek), + PROC(ALLOCATE, enc_allocate, dec_allocate), #endif /* CONFIG_NFS_V4_2 */ }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 356acc2846fd..2b28a21edcd0 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -490,6 +490,7 @@ enum { /* nfs42 */ NFSPROC4_CLNT_SEEK, + NFSPROC4_CLNT_ALLOCATE, }; /* nfs41 types */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index a32ba0d7a98f..df6ed429b406 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -231,5 +231,6 @@ struct nfs_server { #define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17) #define NFS_CAP_SECURITY_LABEL (1U << 18) #define NFS_CAP_SEEK (1U << 19) +#define NFS_CAP_ALLOCATE (1U << 20) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 47ebb4fafd87..467c84efb596 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1243,6 +1243,20 @@ nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo) #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 +struct nfs42_falloc_args { + struct nfs4_sequence_args seq_args; + + struct nfs_fh *falloc_fh; + nfs4_stateid falloc_stateid; + u64 falloc_offset; + u64 falloc_length; +}; + +struct nfs42_falloc_res { + struct nfs4_sequence_res seq_res; + unsigned int status; +}; + struct nfs42_seek_args { struct nfs4_sequence_args seq_args; -- GitLab From 624bd5b7b683c978c6d5f4e9f6142cfb3470983d Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 25 Nov 2014 13:18:16 -0500 Subject: [PATCH 6501/9457] nfs: Add DEALLOCATE support This patch adds support for using the NFS v4.2 operation DEALLOCATE to punch holes in a file. Signed-off-by: Anna Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/nfs42.h | 1 + fs/nfs/nfs42proc.c | 17 +++++++++++ fs/nfs/nfs42xdr.c | 64 +++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4file.c | 7 +++-- fs/nfs/nfs4proc.c | 1 + fs/nfs/nfs4xdr.c | 1 + include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 1 + 8 files changed, 91 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index 42656a9cf485..7afb8947dfdf 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -7,6 +7,7 @@ /* nfs4.2proc.c */ int nfs42_proc_allocate(struct file *, loff_t, loff_t); +int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); /* nfs4.2xdr.h */ diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 581f34e9d8a0..cb170722769c 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -90,6 +90,23 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len) return err; } +int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) +{ + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE], + }; + struct inode *inode = file_inode(filep); + int err; + + if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE)) + return -EOPNOTSUPP; + + err = nfs42_proc_fallocate(&msg, filep, offset, len); + if (err == -EOPNOTSUPP) + NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE; + return err; +} + loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) { struct inode *inode = file_inode(filep); diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 4248d034479c..038a7e1521fa 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -10,6 +10,9 @@ #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ encode_fallocate_maxsz) #define decode_allocate_maxsz (op_decode_hdr_maxsz) +#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ + encode_fallocate_maxsz) +#define decode_deallocate_maxsz (op_decode_hdr_maxsz) #define encode_seek_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + \ 2 /* offset */ + \ @@ -26,6 +29,12 @@ #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ decode_putfh_maxsz + \ decode_allocate_maxsz) +#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_deallocate_maxsz) +#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ + decode_putfh_maxsz + \ + decode_deallocate_maxsz) #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ encode_putfh_maxsz + \ encode_seek_maxsz) @@ -50,6 +59,14 @@ static void encode_allocate(struct xdr_stream *xdr, encode_fallocate(xdr, args); } +static void encode_deallocate(struct xdr_stream *xdr, + struct nfs42_falloc_args *args, + struct compound_hdr *hdr) +{ + encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); + encode_fallocate(xdr, args); +} + static void encode_seek(struct xdr_stream *xdr, struct nfs42_seek_args *args, struct compound_hdr *hdr) @@ -78,6 +95,24 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, encode_nops(&hdr); } +/* + * Encode DEALLOCATE request + */ +static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs42_falloc_args *args) +{ + struct compound_hdr hdr = { + .minorversion = nfs4_xdr_minorversion(&args->seq_args), + }; + + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->falloc_fh, &hdr); + encode_deallocate(xdr, args, &hdr); + encode_nops(&hdr); +} + /* * Encode SEEK request */ @@ -101,6 +136,11 @@ static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) return decode_op_hdr(xdr, OP_ALLOCATE); } +static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) +{ + return decode_op_hdr(xdr, OP_DEALLOCATE); +} + static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) { int status; @@ -147,6 +187,30 @@ static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, return status; } +/* + * Decode DEALLOCATE request + */ +static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs42_falloc_res *res) +{ + struct compound_hdr hdr; + int status; + + status = decode_compound_hdr(xdr, &hdr); + if (status) + goto out; + status = decode_sequence(xdr, &res->seq_res, rqstp); + if (status) + goto out; + status = decode_putfh(xdr); + if (status) + goto out; + status = decode_deallocate(xdr, res); +out: + return status; +} + /* * Decode SEEK request */ diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index f78e9fd0735a..8b46389c4c5b 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -145,7 +145,7 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t if (!S_ISREG(inode->i_mode)) return -EOPNOTSUPP; - if (mode != 0) + if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE))) return -EOPNOTSUPP; ret = inode_newsize_ok(inode, offset + len); @@ -153,7 +153,10 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t return ret; mutex_lock(&inode->i_mutex); - ret = nfs42_proc_allocate(filep, offset, len); + if (mode & FALLOC_FL_PUNCH_HOLE) + ret = nfs42_proc_deallocate(filep, offset, len); + else + ret = nfs42_proc_allocate(filep, offset, len); mutex_unlock(&inode->i_mutex); nfs_zap_caches(inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b1b403b0ca0d..e7f8d5ff2581 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8425,6 +8425,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | NFS_CAP_STATEID_NFSV41 | NFS_CAP_ATOMIC_OPEN_V1 | NFS_CAP_ALLOCATE + | NFS_CAP_DEALLOCATE | NFS_CAP_SEEK, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 0a1484561e4b..03d0fa62a06e 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7395,6 +7395,7 @@ struct rpc_procinfo nfs4_procedures[] = { #ifdef CONFIG_NFS_V4_2 PROC(SEEK, enc_seek, dec_seek), PROC(ALLOCATE, enc_allocate, dec_allocate), + PROC(DEALLOCATE, enc_deallocate, dec_deallocate), #endif /* CONFIG_NFS_V4_2 */ }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 2b28a21edcd0..022b761dbf0a 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -491,6 +491,7 @@ enum { /* nfs42 */ NFSPROC4_CLNT_SEEK, NFSPROC4_CLNT_ALLOCATE, + NFSPROC4_CLNT_DEALLOCATE, }; /* nfs41 types */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index df6ed429b406..1e37fbb78f7a 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -232,5 +232,6 @@ struct nfs_server { #define NFS_CAP_SECURITY_LABEL (1U << 18) #define NFS_CAP_SEEK (1U << 19) #define NFS_CAP_ALLOCATE (1U << 20) +#define NFS_CAP_DEALLOCATE (1U << 21) #endif -- GitLab From 6d4e81ed89c092cb156c8d19cb68c8733cd502b3 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 24 Nov 2014 10:08:03 +0100 Subject: [PATCH 6502/9457] cpufreq: Ref the policy object sooner Do it before it's assigned to cpufreq_cpu_data, otherwise when a driver tries to get the cpu frequency during initialization the policy kobj is referenced and we get this warning: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 64 at include/linux/kref.h:47 kobject_get+0x64/0x70() Modules linked in: CPU: 1 PID: 64 Comm: irq/77-tegra-ac Not tainted 3.18.0-rc4-next-20141114ccu-00050-g3eff942 #326 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x98/0xd8) [] (dump_stack) from [] (warn_slowpath_common+0x84/0xb4) [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [] (warn_slowpath_null) from [] (kobject_get+0x64/0x70) [] (kobject_get) from [] (cpufreq_cpu_get+0x88/0xc8) [] (cpufreq_cpu_get) from [] (cpufreq_get+0xc/0x64) [] (cpufreq_get) from [] (actmon_thread_isr+0x134/0x198) [] (actmon_thread_isr) from [] (irq_thread_fn+0x1c/0x40) [] (irq_thread_fn) from [] (irq_thread+0x134/0x174) [] (irq_thread) from [] (kthread+0xdc/0xf4) [] (kthread) from [] (ret_from_fork+0x14/0x3c) ---[ end trace b7bd64a81b340c59 ]--- Signed-off-by: Tomeu Vizoso Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c9701e9e53e4..de2c3e198b62 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -900,46 +900,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, struct freq_attr **drv_attr; int ret = 0; - /* prepare interface data */ - ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, - &dev->kobj, "cpufreq"); - if (ret) - return ret; - /* set up files for this cpu device */ drv_attr = cpufreq_driver->attr; while ((drv_attr) && (*drv_attr)) { ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); if (ret) - goto err_out_kobj_put; + return ret; drv_attr++; } if (cpufreq_driver->get) { ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); if (ret) - goto err_out_kobj_put; + return ret; } ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); if (ret) - goto err_out_kobj_put; + return ret; if (cpufreq_driver->bios_limit) { ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); if (ret) - goto err_out_kobj_put; + return ret; } - ret = cpufreq_add_dev_symlink(policy); - if (ret) - goto err_out_kobj_put; - - return ret; - -err_out_kobj_put: - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - return ret; + return cpufreq_add_dev_symlink(policy); } static void cpufreq_init_policy(struct cpufreq_policy *policy) @@ -1198,6 +1183,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) goto err_set_policy_cpu; } + down_write(&policy->rwsem); + /* related cpus should atleast have policy->cpus */ cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); @@ -1210,9 +1197,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) if (!recover_policy) { policy->user_policy.min = policy->min; policy->user_policy.max = policy->max; + + /* prepare interface data */ + ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, + &dev->kobj, "cpufreq"); + if (ret) { + pr_err("%s: failed to init policy->kobj: %d\n", + __func__, ret); + goto err_init_policy_kobj; + } } - down_write(&policy->rwsem); write_lock_irqsave(&cpufreq_driver_lock, flags); for_each_cpu(j, policy->cpus) per_cpu(cpufreq_cpu_data, j) = policy; @@ -1303,6 +1298,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) per_cpu(cpufreq_cpu_data, j) = NULL; write_unlock_irqrestore(&cpufreq_driver_lock, flags); + if (!recover_policy) { + kobject_put(&policy->kobj); + wait_for_completion(&policy->kobj_unregister); + } +err_init_policy_kobj: up_write(&policy->rwsem); if (cpufreq_driver->exit) -- GitLab From aa99c47933d2c9a7622440d1b08ebb46ad8bd741 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 25 Nov 2014 22:33:45 +0100 Subject: [PATCH 6503/9457] net: Hyper-V: Deletion of an unnecessary check before the function call "vfree" The vfree() function performs also input parameter validation. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Haiyang Zhang Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 6b463117dcac..6fc834e4306d 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -561,9 +561,7 @@ int netvsc_device_remove(struct hv_device *device) vmbus_close(device->channel); /* Release all resources */ - if (net_device->sub_cb_buf) - vfree(net_device->sub_cb_buf); - + vfree(net_device->sub_cb_buf); free_netvsc_device(net_device); return 0; } -- GitLab From c362effe5cda4df02aa7670d58636ea73979e304 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 25 Nov 2014 12:14:48 +0100 Subject: [PATCH 6504/9457] ASoC: Remove 'const' from the device_node pointers As Russell King's explained it, there should not be pointers to struct device_node: "struct device_node is a ref-counted structure. That means if you store a reference to it, you should "get" it, and you should "put" it once you've done. The act of "put"ing the pointed-to structure involves writing to that structure, so it is totally unappropriate to store a device_node structure as a const pointer. It forces you to have to cast it back to a non-const pointer at various points in time to use various OF function calls." [This isn't quite the application here, we're not geting or putting the pointer though we did add some other users who call non-const OF functions -- broonie] Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- include/sound/soc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index edbb07ba4cb5..d1f3dac91b3e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -881,7 +881,7 @@ struct snd_soc_platform_driver { struct snd_soc_dai_link_component { const char *name; - const struct device_node *of_node; + struct device_node *of_node; const char *dai_name; }; @@ -983,7 +983,7 @@ struct snd_soc_codec_conf { * DT/OF node, but not both. */ const char *dev_name; - const struct device_node *of_node; + struct device_node *of_node; /* * optional map of kcontrol, widget and path name prefixes that are @@ -1000,7 +1000,7 @@ struct snd_soc_aux_dev { * DT/OF node, but not both. */ const char *codec_name; - const struct device_node *codec_of_node; + struct device_node *codec_of_node; /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_component *component); -- GitLab From bccac16eeaa8c2428981891d09380672b229f48b Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 25 Nov 2014 14:48:49 +0000 Subject: [PATCH 6505/9457] ACPI / processor: remove unused variabled from acpi_processor_power structure Few elements in the acpi_processor_power structure are unused. It could be remnant in the header missed while the code got removed from the corresponding driver file. This patch removes those unused variables in the structure declaration. Signed-off-by: Sudeep Holla Signed-off-by: Rafael J. Wysocki --- include/acpi/processor.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/acpi/processor.h b/include/acpi/processor.h index cbb6cd3a98d7..3ca9b751f122 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -67,9 +67,6 @@ struct acpi_processor_cx { }; struct acpi_processor_power { - struct acpi_processor_cx *state; - unsigned long bm_check_timestamp; - u32 default_state; int count; struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; int timer_broadcast_on_state; -- GitLab From 6fd8050a35475259c444afc6856d57f4bbd74231 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 25 Nov 2014 14:48:50 +0000 Subject: [PATCH 6506/9457] ACPI / cpuidle: avoid assigning signed errno to acpi_status It's incorrect to assign a signed value to an unsigned acpi_status variable. This patch fixes it by using a signed integer to return error values. Signed-off-by: Sudeep Holla Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 17f9ec501972..38472fd5d104 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -334,10 +334,10 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) { - acpi_status status = 0; + acpi_status status; u64 count; int current_count; - int i; + int i, ret = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *cst; @@ -358,7 +358,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) /* There must be at least 2 elements */ if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { printk(KERN_ERR PREFIX "not enough elements in _CST\n"); - status = -EFAULT; + ret = -EFAULT; goto end; } @@ -367,7 +367,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) /* Validate number of power states. */ if (count < 1 || count != cst->package.count - 1) { printk(KERN_ERR PREFIX "count given by _CST is not valid\n"); - status = -EFAULT; + ret = -EFAULT; goto end; } @@ -489,12 +489,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) /* Validate number of power states discovered */ if (current_count < 2) - status = -EFAULT; + ret = -EFAULT; end: kfree(buffer.pointer); - return status; + return ret; } static void acpi_processor_power_verify_c3(struct acpi_processor *pr, @@ -1111,7 +1111,7 @@ static int acpi_processor_registered; int acpi_processor_power_init(struct acpi_processor *pr) { - acpi_status status = 0; + acpi_status status; int retval; struct cpuidle_device *dev; static int first_run; -- GitLab From 6556f7f82b9c401950d703072c0d8137b6f9f516 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 24 Nov 2014 16:33:34 +0100 Subject: [PATCH 6507/9457] drm: imx: Move imx-drm driver out of staging The imx-drm driver was put into staging mostly for the following reasons, all of which have been addressed or superseded: - convert the irq driver to use linear irq domains - work out the device tree bindings, this lead to the common of_graph bindings being used - factor out common helper functions, this mostly resulted in the component framework and drm of_graph helpers. Before adding new fixes, and certainly before adding new features, move it into its proper place below drivers/gpu/drm. Signed-off-by: Philipp Zabel Signed-off-by: Dave Airlie --- .../imx-drm => drm/imx}/fsl-imx-drm.txt | 0 .../{staging/imx-drm => drm/imx}/hdmi.txt | 0 .../{staging/imx-drm => drm/imx}/ldb.txt | 0 drivers/gpu/drm/Kconfig | 2 ++ drivers/gpu/drm/Makefile | 1 + .../{staging/imx-drm => gpu/drm/imx}/Kconfig | 0 .../{staging/imx-drm => gpu/drm/imx}/Makefile | 0 .../imx-drm => gpu/drm/imx}/imx-drm-core.c | 0 .../{staging/imx-drm => gpu/drm/imx}/imx-drm.h | 0 .../{staging/imx-drm => gpu/drm/imx}/imx-hdmi.c | 0 .../{staging/imx-drm => gpu/drm/imx}/imx-hdmi.h | 0 .../{staging/imx-drm => gpu/drm/imx}/imx-ldb.c | 0 .../{staging/imx-drm => gpu/drm/imx}/imx-tve.c | 0 .../imx-drm => gpu/drm/imx}/ipuv3-crtc.c | 0 .../imx-drm => gpu/drm/imx}/ipuv3-plane.c | 0 .../imx-drm => gpu/drm/imx}/ipuv3-plane.h | 0 .../imx-drm => gpu/drm/imx}/parallel-display.c | 0 drivers/staging/Kconfig | 2 -- drivers/staging/Makefile | 1 - drivers/staging/imx-drm/TODO | 17 ----------------- 20 files changed, 3 insertions(+), 20 deletions(-) rename Documentation/devicetree/bindings/{staging/imx-drm => drm/imx}/fsl-imx-drm.txt (100%) rename Documentation/devicetree/bindings/{staging/imx-drm => drm/imx}/hdmi.txt (100%) rename Documentation/devicetree/bindings/{staging/imx-drm => drm/imx}/ldb.txt (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/Kconfig (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/Makefile (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-drm-core.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-drm.h (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-hdmi.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-hdmi.h (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-ldb.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/imx-tve.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/ipuv3-crtc.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/ipuv3-plane.c (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/ipuv3-plane.h (100%) rename drivers/{staging/imx-drm => gpu/drm/imx}/parallel-display.c (100%) delete mode 100644 drivers/staging/imx-drm/TODO diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt similarity index 100% rename from Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt rename to Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt diff --git a/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt b/Documentation/devicetree/bindings/drm/imx/hdmi.txt similarity index 100% rename from Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt rename to Documentation/devicetree/bindings/drm/imx/hdmi.txt diff --git a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt b/Documentation/devicetree/bindings/drm/imx/ldb.txt similarity index 100% rename from Documentation/devicetree/bindings/staging/imx-drm/ldb.txt rename to Documentation/devicetree/bindings/drm/imx/ldb.txt diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 37c5a6ea5bdf..24c2d7caedd5 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -202,3 +202,5 @@ source "drivers/gpu/drm/panel/Kconfig" source "drivers/gpu/drm/sti/Kconfig" source "drivers/gpu/drm/amd/amdkfd/Kconfig" + +source "drivers/gpu/drm/imx/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index dd9d35bfa690..47d89869c5df 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_DRM_BOCHS) += bochs/ obj-$(CONFIG_DRM_MSM) += msm/ obj-$(CONFIG_DRM_TEGRA) += tegra/ obj-$(CONFIG_DRM_STI) += sti/ +obj-$(CONFIG_DRM_IMX) += imx/ obj-y += i2c/ obj-y += panel/ obj-y += bridge/ diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/gpu/drm/imx/Kconfig similarity index 100% rename from drivers/staging/imx-drm/Kconfig rename to drivers/gpu/drm/imx/Kconfig diff --git a/drivers/staging/imx-drm/Makefile b/drivers/gpu/drm/imx/Makefile similarity index 100% rename from drivers/staging/imx-drm/Makefile rename to drivers/gpu/drm/imx/Makefile diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c similarity index 100% rename from drivers/staging/imx-drm/imx-drm-core.c rename to drivers/gpu/drm/imx/imx-drm-core.c diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h similarity index 100% rename from drivers/staging/imx-drm/imx-drm.h rename to drivers/gpu/drm/imx/imx-drm.h diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c similarity index 100% rename from drivers/staging/imx-drm/imx-hdmi.c rename to drivers/gpu/drm/imx/imx-hdmi.c diff --git a/drivers/staging/imx-drm/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h similarity index 100% rename from drivers/staging/imx-drm/imx-hdmi.h rename to drivers/gpu/drm/imx/imx-hdmi.h diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c similarity index 100% rename from drivers/staging/imx-drm/imx-ldb.c rename to drivers/gpu/drm/imx/imx-ldb.c diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c similarity index 100% rename from drivers/staging/imx-drm/imx-tve.c rename to drivers/gpu/drm/imx/imx-tve.c diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c similarity index 100% rename from drivers/staging/imx-drm/ipuv3-crtc.c rename to drivers/gpu/drm/imx/ipuv3-crtc.c diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c similarity index 100% rename from drivers/staging/imx-drm/ipuv3-plane.c rename to drivers/gpu/drm/imx/ipuv3-plane.c diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h similarity index 100% rename from drivers/staging/imx-drm/ipuv3-plane.h rename to drivers/gpu/drm/imx/ipuv3-plane.h diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c similarity index 100% rename from drivers/staging/imx-drm/parallel-display.c rename to drivers/gpu/drm/imx/parallel-display.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4690ae9a267f..9425728b7eb5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -86,8 +86,6 @@ source "drivers/staging/gdm72xx/Kconfig" source "drivers/staging/gdm724x/Kconfig" -source "drivers/staging/imx-drm/Kconfig" - source "drivers/staging/fwserial/Kconfig" source "drivers/staging/goldfish/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c780a0e70e15..bc233dd98a95 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_STAGING_BOARD) += board/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ obj-$(CONFIG_LTE_GDM724X) += gdm724x/ -obj-$(CONFIG_DRM_IMX) += imx-drm/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_LUSTRE_FS) += lustre/ diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO deleted file mode 100644 index 29636fb13959..000000000000 --- a/drivers/staging/imx-drm/TODO +++ /dev/null @@ -1,17 +0,0 @@ -TODO: -- get DRM Maintainer review for this code -- decide where to put the base driver. It is not specific to a subsystem - and would be used by DRM/KMS and media/V4L2 - -Missing features (not necessarily for moving out of staging): - -- Add support for IC (Image converter) -- Add support for CSI (CMOS Sensor interface) -- Add support for VDIC (Video Deinterlacer) - -Many work-in-progress patches for the above features exist. Contact -Sascha Hauer if you are interested in working -on a specific feature. - -Please send any patches to Greg Kroah-Hartman and -Sascha Hauer -- GitLab From 0a3d775fb2c951d1bd3f5f916eee55face0eaada Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 24 Nov 2014 16:33:35 +0100 Subject: [PATCH 6508/9457] MAINTAINERS: add maintainer for i.MX DRM driver Add myself as the maintainer of the i.MX DRM driver. Signed-off-by: Philipp Zabel Acked-by: Shawn Guo Signed-off-by: Dave Airlie --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3c69a3c73028..b29325d4a072 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3202,6 +3202,13 @@ F: drivers/gpu/drm/exynos/ F: include/drm/exynos* F: include/uapi/drm/exynos* +DRM DRIVERS FOR FREESCALE IMX +M: Philipp Zabel +L: dri-devel@lists.freedesktop.org +S: Maintained +F: drivers/gpu/drm/imx/ +F: Documentation/devicetree/bindings/drm/imx/ + DRM DRIVERS FOR NVIDIA TEGRA M: Thierry Reding M: Terje Bergström -- GitLab From 4bc158e0be4b03b320db9f3b91a84c898ae928a0 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Tue, 25 Nov 2014 12:04:02 -0800 Subject: [PATCH 6509/9457] drm/udl: handle page mapping in dmabuf export. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes dmabuf export failure with -E_NOMEM when the page is not mapped. Signed-off-by: Haixia Shi Reviewed-by: Stéphane Marchesin Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_dmabuf.c | 7 +++++-- drivers/gpu/drm/udl/udl_drv.h | 2 ++ drivers/gpu/drm/udl/udl_gem.c | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c index 1d85c3a9151d..2425b76dc44c 100644 --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -90,8 +90,11 @@ static struct sg_table *udl_map_dma_buf(struct dma_buf_attachment *attach, return &udl_attach->sgt; if (!obj->pages) { - DRM_ERROR("pages is null.\n"); - return ERR_PTR(-ENOMEM); + ret = udl_gem_get_pages(obj); + if (ret) { + DRM_ERROR("failed to map pages.\n"); + return ERR_PTR(ret); + } } page_count = obj->base.size / PAGE_SIZE; diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 1b132d779621..80adbac82bde 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -129,6 +129,8 @@ struct dma_buf *udl_gem_prime_export(struct drm_device *dev, struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); +int udl_gem_get_pages(struct udl_gem_object *obj); +void udl_gem_put_pages(struct udl_gem_object *obj); int udl_gem_vmap(struct udl_gem_object *obj); void udl_gem_vunmap(struct udl_gem_object *obj); int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index cd3482de5cab..2a0a784ab6ee 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -127,7 +127,7 @@ int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } } -static int udl_gem_get_pages(struct udl_gem_object *obj) +int udl_gem_get_pages(struct udl_gem_object *obj) { struct page **pages; @@ -143,7 +143,7 @@ static int udl_gem_get_pages(struct udl_gem_object *obj) return 0; } -static void udl_gem_put_pages(struct udl_gem_object *obj) +void udl_gem_put_pages(struct udl_gem_object *obj) { if (obj->base.import_attach) { drm_free_large(obj->pages); -- GitLab From e38648f95d197b2296dec4b8c1f9a163c362f31e Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Tue, 25 Nov 2014 12:04:03 -0800 Subject: [PATCH 6510/9457] drm/udl: properly check for error pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drm_prime_pages_to_sg() function never returns NULL pointers, only error pointers and valid pointers. Signed-off-by: Haixia Shi Reviewed-by: Stéphane Marchesin Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_dmabuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c index 2425b76dc44c..ac8a66b4dfc2 100644 --- a/drivers/gpu/drm/udl/udl_dmabuf.c +++ b/drivers/gpu/drm/udl/udl_dmabuf.c @@ -99,9 +99,9 @@ static struct sg_table *udl_map_dma_buf(struct dma_buf_attachment *attach, page_count = obj->base.size / PAGE_SIZE; obj->sg = drm_prime_pages_to_sg(obj->pages, page_count); - if (!obj->sg) { - DRM_ERROR("sg is null.\n"); - return ERR_PTR(-ENOMEM); + if (IS_ERR(obj->sg)) { + DRM_ERROR("failed to allocate sgt.\n"); + return ERR_CAST(obj->sg); } sgt = &udl_attach->sgt; -- GitLab From 504febc3f98c87a8bebd8f2f274f32c0724131e4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 25 Nov 2014 15:46:13 -0200 Subject: [PATCH 6511/9457] Revert "[media] lmed04: add missing breaks" According with Malcolm, the missing breaks are intentional. So, let's revert commit d442b15fb4deb2b5d516e2dae1f569b1d5472399, add some comments to document it and fix the two smatch warnings: drivers/media/usb/dvb-usb-v2/lmedm04.c:828 lme_firmware_switch() warn: missing break? reassigning 'st->dvb_usb_lme2510_firmware' drivers/media/usb/dvb-usb-v2/lmedm04.c:850 lme_firmware_switch() warn: missing break? reassigning 'st->dvb_usb_lme2510_firmware' using a different strategy to avoid reassign values to st->dvb_usb_lme2510_firmware. Acked-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 99587418f4f0..994de53a574b 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -817,21 +817,22 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) case 0x1122: switch (st->dvb_usb_lme2510_firmware) { default: - st->dvb_usb_lme2510_firmware = TUNER_S0194; case TUNER_S0194: fw_lme = fw_s0194; ret = request_firmware(&fw, fw_lme, &udev->dev); if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S0194; cold = 0; break; } - st->dvb_usb_lme2510_firmware = TUNER_LG; - break; + /* fall through */ case TUNER_LG: fw_lme = fw_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_LG; break; + } st->dvb_usb_lme2510_firmware = TUNER_DEFAULT; break; } @@ -839,27 +840,30 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) case 0x1120: switch (st->dvb_usb_lme2510_firmware) { default: - st->dvb_usb_lme2510_firmware = TUNER_S7395; case TUNER_S7395: fw_lme = fw_c_s7395; ret = request_firmware(&fw, fw_lme, &udev->dev); if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S7395; cold = 0; break; } - st->dvb_usb_lme2510_firmware = TUNER_LG; - break; + /* fall through */ case TUNER_LG: fw_lme = fw_c_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_LG; break; - st->dvb_usb_lme2510_firmware = TUNER_S0194; + } + /* fall through */ case TUNER_S0194: fw_lme = fw_c_s0194; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S0194; break; + } st->dvb_usb_lme2510_firmware = TUNER_DEFAULT; cold = 0; break; -- GitLab From bfcba2d0352f7916e98a1cec54c1c2473da6f4d6 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 25 Nov 2014 20:01:37 -0500 Subject: [PATCH 6512/9457] ext4: Remove an unnecessary check for NULL before iput() The iput() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Theodore Ts'o --- fs/ext4/mballoc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index f1c25f83fc7d..8d1e60214ef0 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2712,8 +2712,7 @@ int ext4_mb_release(struct super_block *sb) } kfree(sbi->s_mb_offsets); kfree(sbi->s_mb_maxs); - if (sbi->s_buddy_cache) - iput(sbi->s_buddy_cache); + iput(sbi->s_buddy_cache); if (sbi->s_mb_stats) { ext4_msg(sb, KERN_INFO, "mballoc: %u blocks %u reqs (%u success)", -- GitLab From d9f39d1e44c43fba26becc4145fabf9d767ff1cd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 25 Nov 2014 20:02:37 -0500 Subject: [PATCH 6513/9457] jbd2: remove unnecessary NULL check before iput() Signed-off-by: Theodore Ts'o --- fs/jbd2/journal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index e4dc74713a43..56dde1e85c24 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1714,8 +1714,7 @@ int jbd2_journal_destroy(journal_t *journal) if (journal->j_proc_entry) jbd2_stats_proc_exit(journal); - if (journal->j_inode) - iput(journal->j_inode); + iput(journal->j_inode); if (journal->j_revoke) jbd2_journal_destroy_revoke(journal); if (journal->j_chksum_driver) -- GitLab From c556522e89fb00ee1e1efd2e1d29ed092243cf66 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 14 Nov 2014 16:59:31 +0100 Subject: [PATCH 6514/9457] serial: sh-sci: Add device tree support for r8a7794 Simply document the new compat string. There appears to be no need for a driver update. Signed-off-by: Ulrich Hecht [geert: Reworded to match previous commits] Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/renesas,sci-serial.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index b3556609a06f..7b87eb2c66be 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -20,6 +20,10 @@ Required properties: - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2) SCIFA compatible UART. - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2) SCIFB compatible UART. - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2) HSCIF compatible UART. + - "renesas,scif-r8a7794" for R8A7794 (R-Car E2) SCIF compatible UART. + - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. + - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. + - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. -- GitLab From 681b05f58f0cd13ea21ee46600a9ad679199214c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 14 Nov 2014 16:59:32 +0100 Subject: [PATCH 6515/9457] serial: sh-sci: Add device tree support for r7s72100 Simply document the new compat string (and keep the list sorted by SoC). There appears to be no need for a driver update. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/renesas,sci-serial.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 7b87eb2c66be..ae73bb0e9ad9 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -4,8 +4,7 @@ Required properties: - compatible: Must contain one of the following: - - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. + - "renesas,scif-r7s72100" for R7S72100 (RZ/A1H) SCIF compatible UART. - "renesas,scifa-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFA compatible UART. - "renesas,scifb-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFB compatible UART. - "renesas,scifa-r8a7740" for R8A7740 (R-Mobile A1) SCIFA compatible UART. @@ -24,6 +23,8 @@ Required properties: - "renesas,scifa-r8a7794" for R8A7794 (R-Car E2) SCIFA compatible UART. - "renesas,scifb-r8a7794" for R8A7794 (R-Car E2) SCIFB compatible UART. - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. + - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. + - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. -- GitLab From f53297fb99c8d2381a94cbaacc3e81c0c5db4cfd Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 20 Nov 2014 07:58:27 +0900 Subject: [PATCH 6516/9457] serial: sh-sci: Change checking for error rate of HSCIF This changes negative values of error rate to be checked, because these values are valid as error rate. And this changes in the process of adopting a value close to 0. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index eb17c7124e72..fccebbdf449f 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1812,9 +1812,6 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr * (1 << (2 * c + 1)) / 1000)) - 1000; - if (err < 0) - continue; - /* Calc recv margin * M: Receive margin (%) * N: Ratio of bit rate to clock (N = sampling rate) @@ -1829,7 +1826,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, */ recv_margin = abs((500 - DIV_ROUND_CLOSEST(1000, sr << 1)) / 10); - if (min_err > err) { + if (abs(min_err) > abs(err)) { min_err = err; recv_max_margin = recv_margin; } else if ((min_err == err) && -- GitLab From 333f4eb1ba46b2d75fb3dc46ebed13aa1d0c9639 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sun, 9 Nov 2014 02:22:16 +0100 Subject: [PATCH 6517/9457] serial: jsm: Remove unnecessary parameter from clear_break() The 'force' parameter to the {cls,neo}_send_break() function has been removed because it has not been used. The client to this API (the tty code) always called this function with only one value. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm.h | 2 +- drivers/tty/serial/jsm/jsm_cls.c | 2 +- drivers/tty/serial/jsm/jsm_neo.c | 2 +- drivers/tty/serial/jsm/jsm_tty.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 72ed5c106d26..39b325bdb835 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -120,7 +120,7 @@ struct board_ops { void (*disable_receiver) (struct jsm_channel *ch); void (*enable_receiver) (struct jsm_channel *ch); void (*send_break) (struct jsm_channel *ch); - void (*clear_break) (struct jsm_channel *ch, int); + void (*clear_break) (struct jsm_channel *ch); void (*send_start_character) (struct jsm_channel *ch); void (*send_stop_character) (struct jsm_channel *ch); void (*copy_data_from_queue_to_uart) (struct jsm_channel *ch); diff --git a/drivers/tty/serial/jsm/jsm_cls.c b/drivers/tty/serial/jsm/jsm_cls.c index 4cb927563cf1..3df9112daa38 100644 --- a/drivers/tty/serial/jsm/jsm_cls.c +++ b/drivers/tty/serial/jsm/jsm_cls.c @@ -311,7 +311,7 @@ static void cls_set_no_input_flow_control(struct jsm_channel *ch) * No locks are assumed to be held when calling this function. * channel lock is held and released in this function. */ -static void cls_clear_break(struct jsm_channel *ch, int force) +static void cls_clear_break(struct jsm_channel *ch) { unsigned long lock_flags; diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index dc2cd9040d64..b9faee77a0ca 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -689,7 +689,7 @@ static void neo_flush_uart_read(struct jsm_channel *ch) /* * No locks are assumed to be held when calling this function. */ -static void neo_clear_break(struct jsm_channel *ch, int force) +static void neo_clear_break(struct jsm_channel *ch) { unsigned long lock_flags; diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index c60e4542c050..524e86ab3cae 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -188,7 +188,7 @@ static void jsm_tty_break(struct uart_port *port, int break_state) if (break_state == -1) channel->ch_bd->bd_ops->send_break(channel); else - channel->ch_bd->bd_ops->clear_break(channel, 0); + channel->ch_bd->bd_ops->clear_break(channel); spin_unlock_irqrestore(&port->lock, lock_flags); } -- GitLab From b6501dd86ff085a8687d157c016f46a34e46bf5b Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sun, 9 Nov 2014 02:22:17 +0100 Subject: [PATCH 6518/9457] serial: jsm: Remove unnecessary if statement The flow of {neo,cls}_param() shows that at this stage the baud rate has a non-zero value. This fact makes the if clausule obsolete and acknowledges it's removal. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_cls.c | 3 --- drivers/tty/serial/jsm/jsm_neo.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm_cls.c b/drivers/tty/serial/jsm/jsm_cls.c index 3df9112daa38..bfb0681195b6 100644 --- a/drivers/tty/serial/jsm/jsm_cls.c +++ b/drivers/tty/serial/jsm/jsm_cls.c @@ -767,9 +767,6 @@ static void cls_param(struct jsm_channel *ch) ier = readb(&ch->ch_cls_uart->ier); uart_lcr = readb(&ch->ch_cls_uart->lcr); - if (baud == 0) - baud = 9600; - quot = ch->ch_bd->bd_dividend / baud; if (quot != 0) { diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index b9faee77a0ca..4b8196db02f3 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -1037,9 +1037,6 @@ static void neo_param(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); uart_lcr = readb(&ch->ch_neo_uart->lcr); - if (baud == 0) - baud = 9600; - quot = ch->ch_bd->bd_dividend / baud; if (quot != 0) { -- GitLab From 245ae51cec684aa1a3e6e35afdf2a6c93d371b32 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sun, 9 Nov 2014 02:22:18 +0100 Subject: [PATCH 6519/9457] serial: jsm: Fix the alignment of the switch satement This commit fixes the alignment of the 'case's i the switch statement. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_neo.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 4b8196db02f3..5de6dffbdc0c 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -1019,19 +1019,19 @@ static void neo_param(struct jsm_channel *ch) lcr |= UART_LCR_STOP; switch (ch->ch_c_cflag & CSIZE) { - case CS5: - lcr |= UART_LCR_WLEN5; - break; - case CS6: - lcr |= UART_LCR_WLEN6; - break; - case CS7: - lcr |= UART_LCR_WLEN7; - break; - case CS8: - default: - lcr |= UART_LCR_WLEN8; + case CS5: + lcr |= UART_LCR_WLEN5; + break; + case CS6: + lcr |= UART_LCR_WLEN6; + break; + case CS7: + lcr |= UART_LCR_WLEN7; break; + case CS8: + default: + lcr |= UART_LCR_WLEN8; + break; } ier = readb(&ch->ch_neo_uart->ier); -- GitLab From 5b05e2cbf5b38dfb2410d23adc26703fd37f84f9 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sun, 9 Nov 2014 02:22:19 +0100 Subject: [PATCH 6520/9457] serial: jsm: Replace magic value with the proper define The changed function flushes the tx UART and the '4' corresponds to the UART_FCR_CLEAR_XMIT value. This commit replaces the magic number with this define. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_neo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 5de6dffbdc0c..7291c2117daa 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -644,7 +644,7 @@ static void neo_flush_uart_write(struct jsm_channel *ch) /* Check to see if the UART feels it completely flushed the FIFO. */ tmp = readb(&ch->ch_neo_uart->isr_fcr); - if (tmp & 4) { + if (tmp & UART_FCR_CLEAR_XMIT) { jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "Still flushing TX UART... i: %d\n", i); udelay(10); -- GitLab From 483e91a503064c104326a6bb55d4505ff467cd92 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sun, 9 Nov 2014 02:22:20 +0100 Subject: [PATCH 6521/9457] serial: jsm: Fix unnecessary space before function ptr arguments This commit deals with the checkpatch warning "Unnecessary space before function pointer arguments". Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 39b325bdb835..0b79b87df47d 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -111,21 +111,21 @@ struct jsm_channel; ************************************************************************/ struct board_ops { irq_handler_t intr; - void (*uart_init) (struct jsm_channel *ch); - void (*uart_off) (struct jsm_channel *ch); - void (*param) (struct jsm_channel *ch); - void (*assert_modem_signals) (struct jsm_channel *ch); - void (*flush_uart_write) (struct jsm_channel *ch); - void (*flush_uart_read) (struct jsm_channel *ch); - void (*disable_receiver) (struct jsm_channel *ch); - void (*enable_receiver) (struct jsm_channel *ch); - void (*send_break) (struct jsm_channel *ch); - void (*clear_break) (struct jsm_channel *ch); - void (*send_start_character) (struct jsm_channel *ch); - void (*send_stop_character) (struct jsm_channel *ch); - void (*copy_data_from_queue_to_uart) (struct jsm_channel *ch); - u32 (*get_uart_bytes_left) (struct jsm_channel *ch); - void (*send_immediate_char) (struct jsm_channel *ch, unsigned char); + void (*uart_init)(struct jsm_channel *ch); + void (*uart_off)(struct jsm_channel *ch); + void (*param)(struct jsm_channel *ch); + void (*assert_modem_signals)(struct jsm_channel *ch); + void (*flush_uart_write)(struct jsm_channel *ch); + void (*flush_uart_read)(struct jsm_channel *ch); + void (*disable_receiver)(struct jsm_channel *ch); + void (*enable_receiver)(struct jsm_channel *ch); + void (*send_break)(struct jsm_channel *ch); + void (*clear_break)(struct jsm_channel *ch); + void (*send_start_character)(struct jsm_channel *ch); + void (*send_stop_character)(struct jsm_channel *ch); + void (*copy_data_from_queue_to_uart)(struct jsm_channel *ch); + u32 (*get_uart_bytes_left)(struct jsm_channel *ch); + void (*send_immediate_char)(struct jsm_channel *ch, unsigned char); }; -- GitLab From e620e54884ceb983c38f979a22fd04ae0820c725 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 9 Nov 2014 22:46:35 -0800 Subject: [PATCH 6522/9457] tty: pr_warning->pr_warn and logging neatening Convert the pr_warning to the more common pr_warn. Other miscellanea: o Convert unusual PR_FMT define and uses to pr_fmt o Remove unnecessary OOM message o Fix grammar in an error message o Convert a pr_warning with a KERN_ERR to pr_err Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ehv_bytechan.c | 4 ++-- drivers/tty/isicom.c | 14 +++++++------- drivers/tty/serial/bfin_sport_uart.c | 5 +++-- drivers/tty/serial/mfd.c | 2 +- drivers/tty/serial/mrst_max3110.c | 27 ++++++++++++--------------- drivers/tty/vt/keyboard.c | 6 +++--- drivers/tty/vt/vt.c | 4 ++-- 7 files changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4f485e88f60c..9d29d7e4b28c 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -309,8 +309,8 @@ static int __init ehv_bc_console_init(void) * handle for udbg. */ if (stdout_bc != CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE) - pr_warning("ehv-bc: udbg handle %u is not the stdout handle\n", - CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); + pr_warn("ehv-bc: udbg handle %u is not the stdout handle\n", + CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE); #endif /* add_preferred_console() must be called before register_console(), diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 858291ca889c..59ed783c4bcd 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -249,7 +249,7 @@ static int lock_card(struct isi_board *card) spin_unlock_irqrestore(&card->card_lock, card->flags); msleep(10); } - pr_warning("Failed to lock Card (0x%lx)\n", card->base); + pr_warn("Failed to lock Card (0x%lx)\n", card->base); return 0; /* Failed to acquire the card! */ } @@ -378,13 +378,13 @@ static inline int __isicom_paranoia_check(struct isi_port const *port, char *name, const char *routine) { if (!port) { - pr_warning("Warning: bad isicom magic for dev %s in %s.\n", - name, routine); + pr_warn("Warning: bad isicom magic for dev %s in %s\n", + name, routine); return 1; } if (port->magic != ISICOM_MAGIC) { - pr_warning("Warning: NULL isicom port for dev %s in %s.\n", - name, routine); + pr_warn("Warning: NULL isicom port for dev %s in %s\n", + name, routine); return 1; } @@ -546,8 +546,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) byte_count = header & 0xff; if (channel + 1 > card->port_count) { - pr_warning("%s(0x%lx): %d(channel) > port_count.\n", - __func__, base, channel+1); + pr_warn("%s(0x%lx): %d(channel) > port_count\n", + __func__, base, channel + 1); outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index d62d8daac8ab..984e1c050096 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c @@ -517,14 +517,15 @@ static void sport_set_termios(struct uart_port *port, up->csize = 5; break; default: - pr_warning("requested word length not supported\n"); + pr_warn("requested word length not supported\n"); + break; } if (termios->c_cflag & CSTOPB) { up->stopb = 1; } if (termios->c_cflag & PARENB) { - pr_warning("PAREN bits is not supported yet\n"); + pr_warn("PAREN bit is not supported yet\n"); /* up->parib = 1; */ } diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 445799dc9846..e1f4fdad02c9 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -1371,7 +1371,7 @@ static void hsu_global_init(void) hsu->iolen = 0x1000; if (!(request_mem_region(hsu->paddr, hsu->iolen, "HSU global"))) - pr_warning("HSU: error in request mem region\n"); + pr_warn("HSU: error in request mem region\n"); hsu->reg = ioremap_nocache((unsigned long)hsu->paddr, hsu->iolen); if (!hsu->reg) { diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 1504a14ec1a6..77239d5e620d 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -27,6 +27,8 @@ * interrupt for a low speed UART device */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #ifdef CONFIG_MAGIC_SYSRQ #define SUPPORT_SYSRQ #endif @@ -47,8 +49,6 @@ #include "mrst_max3110.h" -#define PR_FMT "mrst_max3110: " - #define UART_TX_NEEDED 1 #define CON_TX_NEEDED 2 #define BIT_IRQ_PENDING 3 @@ -127,8 +127,8 @@ static int max3110_out(struct uart_max3110 *max, const u16 out) *obuf = out; ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); if (ret) { - pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", - __func__, ret, out); + pr_warn("%s: get err msg %d when sending 0x%x\n", + __func__, ret, out); goto exit; } @@ -153,10 +153,8 @@ static int max3110_read_multi(struct uart_max3110 *max) blen = M3110_RX_FIFO_DEPTH * sizeof(u16); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); - if (!buf) { - pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); + if (!buf) return 0; - } /* tx/rx always have the same length */ obuf = buf; @@ -212,13 +210,13 @@ serial_m3110_con_setup(struct console *co, char *options) int parity = 'n'; int flow = 'n'; - pr_info(PR_FMT "setting up console\n"); + pr_info("setting up console\n"); if (co->index == -1) co->index = 0; if (!max) { - pr_err(PR_FMT "pmax is NULL, return"); + pr_err("pmax is NULL, return\n"); return -ENODEV; } @@ -296,8 +294,7 @@ static void send_circ_buf(struct uart_max3110 *max, ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); if (ret) - pr_warning(PR_FMT "%s(): get err msg %d\n", - __func__, ret); + pr_warn("%s: get err msg %d\n", __func__, ret); receive_chars(max, ibuf, len); @@ -411,7 +408,7 @@ static int max3110_main_thread(void *_max) int ret = 0; struct circ_buf *xmit = &max->con_xmit; - pr_info(PR_FMT "start main thread\n"); + pr_info("start main thread\n"); do { wait_event_interruptible(*wq, @@ -455,7 +452,7 @@ static int max3110_read_thread(void *_max) { struct uart_max3110 *max = _max; - pr_info(PR_FMT "start read thread\n"); + pr_info("start read thread\n"); do { /* * If can't acquire the mutex, it means the main thread @@ -481,7 +478,7 @@ static int serial_m3110_startup(struct uart_port *port) int ret = 0; if (port->line != 0) { - pr_err(PR_FMT "uart port startup failed\n"); + pr_err("uart port startup failed\n"); return -1; } @@ -504,7 +501,7 @@ static int serial_m3110_startup(struct uart_port *port) if (IS_ERR(max->read_thread)) { ret = PTR_ERR(max->read_thread); max->read_thread = NULL; - pr_err(PR_FMT "Can't create read thread!\n"); + pr_err("Can't create read thread!\n"); return ret; } } diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index c039cfea5b11..8a89f6e7715d 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -924,7 +924,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) if (kbd->kbdmode != VC_UNICODE) { if (!up_flag) - pr_warning("keyboard mode must be unicode for braille patterns\n"); + pr_warn("keyboard mode must be unicode for braille patterns\n"); return; } @@ -1253,8 +1253,8 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if (raw_mode && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) if (keycode < BTN_MISC && printk_ratelimit()) - pr_warning("can't emulate rawmode for keycode %d\n", - keycode); + pr_warn("can't emulate rawmode for keycode %d\n", + keycode); #ifdef CONFIG_SPARC if (keycode == KEY_A && sparc_l1_a_state) { diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index ed0136519422..f3fbbbca9bde 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3855,8 +3855,8 @@ void do_unblank_screen(int leaving_gfx) return; if (!vc_cons_allocated(fg_console)) { /* impossible */ - pr_warning("unblank_screen: tty %d not allocated ??\n", - fg_console+1); + pr_warn("unblank_screen: tty %d not allocated ??\n", + fg_console + 1); return; } vc = vc_cons[fg_console].d; -- GitLab From 52bec4ed4ef83f1a14dbcfd1a97e35f77c6e261e Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Tue, 11 Nov 2014 20:44:58 +0800 Subject: [PATCH 6523/9457] serial: sirf: add a new uart type support in CSR A7DA SoC, uart6 located at BT module and it need multiple clock sources, so for "sirf,marco-bt-uart" compatible uarts, drivers take 3 clock sources and enable them. this patch also replaces clk_get by devm_clk_get function and fix DT binding document in which we missed to fix when we added marco platform in commit 909102db44f "serial: sirf: add support for Marco chip". Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/sirf-uart.txt | 16 ++++++++- drivers/tty/serial/sirfsoc_uart.c | 34 +++++++++++++++---- drivers/tty/serial/sirfsoc_uart.h | 4 +++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/sirf-uart.txt b/Documentation/devicetree/bindings/serial/sirf-uart.txt index a2dfc6522a91..3acdd969edf1 100644 --- a/Documentation/devicetree/bindings/serial/sirf-uart.txt +++ b/Documentation/devicetree/bindings/serial/sirf-uart.txt @@ -1,7 +1,9 @@ * CSR SiRFprimaII/atlasVI Universal Synchronous Asynchronous Receiver/Transmitter * Required properties: -- compatible : Should be "sirf,prima2-uart" or "sirf, prima2-usp-uart" +- compatible : Should be "sirf,prima2-uart", "sirf, prima2-usp-uart", + "sirf,marco-uart" or "sirf,marco-bt-uart" which means + uart located in BT module and used for BT. - reg : Offset and length of the register set for the device - interrupts : Should contain uart interrupt - fifosize : Should define hardware rx/tx fifo size @@ -31,3 +33,15 @@ usp@b0090000 { rts-gpios = <&gpio 15 0>; cts-gpios = <&gpio 46 0>; }; + +for uart use in BT module, +uart6: uart@11000000 { + cell-index = <6>; + compatible = "sirf,marco-bt-uart", "sirf,marco-uart"; + reg = <0x11000000 0x1000>; + interrupts = <0 100 0>; + clocks = <&clks 138>, <&clks 140>, <&clks 141>; + clock-names = "uart", "general", "noc"; + fifosize = <128>; + status = "disabled"; +} diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 4102192687ee..2f6c6b04cc8d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -1032,10 +1032,19 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { struct sirfsoc_uart_port *sirfport = to_sirfport(port); - if (!state) + if (!state) { + if (sirfport->is_bt_uart) { + clk_prepare_enable(sirfport->clk_noc); + clk_prepare_enable(sirfport->clk_general); + } clk_prepare_enable(sirfport->clk); - else + } else { clk_disable_unprepare(sirfport->clk); + if (sirfport->is_bt_uart) { + clk_disable_unprepare(sirfport->clk_general); + clk_disable_unprepare(sirfport->clk_noc); + } + } } static int sirfsoc_uart_startup(struct uart_port *port) @@ -1378,12 +1387,26 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) } port->irq = res->start; - sirfport->clk = clk_get(&pdev->dev, NULL); + sirfport->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(sirfport->clk)) { ret = PTR_ERR(sirfport->clk); goto err; } port->uartclk = clk_get_rate(sirfport->clk); + if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-bt-uart")) { + sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); + if (IS_ERR(sirfport->clk_general)) { + ret = PTR_ERR(sirfport->clk_general); + goto err; + } + sirfport->clk_noc = devm_clk_get(&pdev->dev, "noc"); + if (IS_ERR(sirfport->clk_noc)) { + ret = PTR_ERR(sirfport->clk_noc); + goto err; + } + sirfport->is_bt_uart = true; + } else + sirfport->is_bt_uart = false; port->ops = &sirfsoc_uart_ops; spin_lock_init(&port->lock); @@ -1392,7 +1415,7 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) ret = uart_add_one_port(&sirfsoc_uart_drv, port); if (ret != 0) { dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); - goto port_err; + goto err; } sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); @@ -1421,8 +1444,6 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) sirfport->rx_dma_items[j].xmit.buf, sirfport->rx_dma_items[j].dma_addr); dma_release_channel(sirfport->rx_dma_chan); -port_err: - clk_put(sirfport->clk); err: return ret; } @@ -1431,7 +1452,6 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) { struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); struct uart_port *port = &sirfport->port; - clk_put(sirfport->clk); uart_remove_one_port(&sirfsoc_uart_drv, port); if (sirfport->rx_dma_chan) { int i; diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6a7ebf7ef130..275d03893990 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -417,6 +417,10 @@ struct sirfsoc_uart_port { struct uart_port port; struct clk *clk; + /* UART6 for BT usage in A7DA platform need multi-clock source */ + bool is_bt_uart; + struct clk *clk_general; + struct clk *clk_noc; /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ bool is_marco; struct sirfsoc_uart_register *uart_reg; -- GitLab From 6b1f40cf4840820051d69646af0b6503878cb1bc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Nov 2014 16:05:03 +0800 Subject: [PATCH 6524/9457] tty: serial: men_z135_uart: Add terminating entry for men_z135_ids The mcb_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/men_z135_uart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 30e9e60bc5cd..517cd073dc08 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -809,6 +809,7 @@ static void men_z135_remove(struct mcb_device *mdev) static const struct mcb_device_id men_z135_ids[] = { { .device = 0x87 }, + { } }; MODULE_DEVICE_TABLE(mcb, men_z135_ids); -- GitLab From 54178fe6b3443249ec2dcd6eec9f2c3ebcdc3142 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 12 Nov 2014 10:28:33 +0100 Subject: [PATCH 6525/9457] tty: serial: 8250: omap: line is unsigned, don't check < 0 Dan Carpenter reported: |drivers/tty/serial/8250/8250_omap.c:1025 omap8250_probe() |warn: unsigned 'up.port.line' is never less than zero. |1025 if (up.port.line < 0) { I (wrongly) assumed that line is an int and compiler didn't complain nor did sparse. Since of_alias_get_id() and pdev->id can get negative I check for the error via ret variable. Reported-by: Dan Carpenter Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 57a8b1241b85..336602eb453e 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1014,19 +1014,20 @@ static int omap8250_probe(struct platform_device *pdev) up.port.unthrottle = omap_8250_unthrottle; if (pdev->dev.of_node) { - up.port.line = of_alias_get_id(pdev->dev.of_node, "serial"); + ret = of_alias_get_id(pdev->dev.of_node, "serial"); + of_property_read_u32(pdev->dev.of_node, "clock-frequency", &up.port.uartclk); priv->wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); } else { - up.port.line = pdev->id; + ret = pdev->id; } - - if (up.port.line < 0) { - dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", - up.port.line); - return -ENODEV; + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias/pdev id\n"); + return ret; } + up.port.line = ret; + if (!up.port.uartclk) { up.port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, -- GitLab From 3c59958d5868f77741930402dfcb27e9dc8968d2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 12 Nov 2014 10:28:34 +0100 Subject: [PATCH 6526/9457] tty: serial: omap_serial: line is unsigned, don't check < 0 Dan Carpenter reported: |drivers/tty/serial/8250/8250_omap.c:1025 omap8250_probe() |warn: unsigned 'up.port.line' is never less than zero. |1025 if (up.port.line < 0) { Since of_alias_get_id() and pdev->id can get negative I check for the error via ret variable. Reported-by: Dan Carpenter Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index e0bec06a5f60..435478a245d3 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1653,16 +1653,16 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.ops = &serial_omap_pops; if (pdev->dev.of_node) - up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); + ret = of_alias_get_id(pdev->dev.of_node, "serial"); else - up->port.line = pdev->id; + ret = pdev->id; - if (up->port.line < 0) { + if (ret < 0) { dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", - up->port.line); - ret = -ENODEV; + ret); goto err_port_line; } + up->port.line = ret; if (up->port.line >= OMAP_MAX_HSUART_PORTS) { dev_err(&pdev->dev, "uart ID %d > MAX %d.\n", up->port.line, -- GitLab From b725680f4818e1244449f2db2e9892b26784ed16 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Nov 2014 11:55:25 +0100 Subject: [PATCH 6527/9457] tty: bfin, define inlined structures struct bfin_serial_port contains structs circ_buf, timer_list, and work_struct directly (not pointers). This means that these structures have to be defined completely to be inlined in struct bfin_serial_port. So instead of struct declarations, define the structures by including proper headers. They were pulled in by linux/serial_core.h or others until now. But experimenting with circ_buf removal from serial_core, struct circ_buf becomes undefined in bfin_serial: In file included from arch/blackfin/kernel/debug-mmrs.c:21:0: arch/blackfin/include/asm/bfin_serial.h:44:18: error: field 'rx_dma_buf' has incomplete type Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/blackfin/include/asm/bfin_serial.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index 2d90d62edc97..d00d732784b1 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h @@ -9,8 +9,11 @@ #ifndef __BFIN_ASM_SERIAL_H__ #define __BFIN_ASM_SERIAL_H__ +#include #include #include +#include +#include #include #include @@ -25,10 +28,6 @@ # endif #endif -struct circ_buf; -struct timer_list; -struct work_struct; - struct bfin_serial_port { struct uart_port port; unsigned int old_status; -- GitLab From 93d94b37fd044674e4e495bed82a45c38bde865a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 12 Nov 2014 15:55:07 -0200 Subject: [PATCH 6528/9457] serial: imx: Fix warning when building 'allmodconfig' When CONFIG_SERIAL_IMX_CONSOLE=n and CONFIG_CONSOLE_POLL=y we get the following build warning: drivers/tty/serial/imx.c:306:13: warning: 'imx_port_ucrs_save' defined but not used [-Wunused-function] drivers/tty/serial/imx.c:315:13: warning: 'imx_port_ucrs_restore' defined but not used [-Wunused-function] imx_port_ucrs_save/restore are only used under CONFIG_SERIAL_IMX_CONSOLE, so their definitions should be also be protected only by CONFIG_SERIAL_IMX_CONSOLE. This was detected when building 'allmodconfig'. Reported-by: Olof's autobuilder Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 062e7614c986..c53968e5439c 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -302,7 +302,7 @@ static inline int is_imx6q_uart(struct imx_port *sport) /* * Save and restore functions for UCR1, UCR2 and UCR3 registers */ -#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_IMX_CONSOLE) +#if defined(CONFIG_SERIAL_IMX_CONSOLE) static void imx_port_ucrs_save(struct uart_port *port, struct imx_port_ucrs *ucr) { -- GitLab From bca2092d78970df3959462d2aae1941e6b24ebdf Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 14 Nov 2014 17:26:19 +0300 Subject: [PATCH 6529/9457] serial: 8250_dw: Use 64-bit access for OCTEON. Although the existing code appears to work on most hardware, the hardware designers tell us that 8-bit access to the registers is not guaranteed to be reliable. Also the OCTEON simulation environments prohibit 8-bit accesses. For these reasons, we use __raw_readq/__raw_writeq for OCTEON. This code is protected with #ifdef CONFIG_64BIT so it still builds under configurations lacking readq/writeq. We can get rid of the #ifdef __BIG_ENDIAN, as under 64-bit accesses, OCTEON is byte order invariant. Signed-off-by: David Daney Signed-off-by: Aleksey Makarov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 55 +++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 18ff53298d2f..f4fd362f6da2 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -122,13 +122,44 @@ static unsigned int dw8250_serial_in(struct uart_port *p, int offset) return dw8250_modify_msr(p, offset, value); } -/* Read Back (rb) version to ensure register access ording. */ -static void dw8250_serial_out_rb(struct uart_port *p, int offset, int value) +#ifdef CONFIG_64BIT +static unsigned int dw8250_serial_inq(struct uart_port *p, int offset) { - dw8250_serial_out(p, offset, value); - dw8250_serial_in(p, UART_LCR); + unsigned int value; + + value = (u8)__raw_readq(p->membase + (offset << p->regshift)); + + return dw8250_modify_msr(p, offset, value); } +static void dw8250_serial_outq(struct uart_port *p, int offset, int value) +{ + struct dw8250_data *d = p->private_data; + + if (offset == UART_MCR) + d->last_mcr = value; + + value &= 0xff; + __raw_writeq(value, p->membase + (offset << p->regshift)); + /* Read back to ensure register write ordering. */ + __raw_readq(p->membase + (UART_LCR << p->regshift)); + + /* Make sure LCR write wasn't ignored */ + if (offset == UART_LCR) { + int tries = 1000; + while (tries--) { + unsigned int lcr = p->serial_in(p, UART_LCR); + if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) + return; + dw8250_force_idle(p); + __raw_writeq(value & 0xff, + p->membase + (UART_LCR << p->regshift)); + } + dev_err(p->dev, "Couldn't set LCR to %d\n", value); + } +} +#endif /* CONFIG_64BIT */ + static void dw8250_serial_out32(struct uart_port *p, int offset, int value) { struct dw8250_data *d = p->private_data; @@ -260,21 +291,17 @@ static int dw8250_probe_of(struct uart_port *p, bool has_ucv = true; int id; +#ifdef CONFIG_64BIT if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { -#ifdef __BIG_ENDIAN - /* - * Low order bits of these 64-bit registers, when - * accessed as a byte, are 7 bytes further down in the - * address space in big endian mode. - */ - p->membase += 7; -#endif - p->serial_out = dw8250_serial_out_rb; + p->serial_in = dw8250_serial_inq; + p->serial_out = dw8250_serial_outq; p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; data->usr_reg = 0x27; has_ucv = false; - } else if (!of_property_read_u32(np, "reg-io-width", &val)) { + } else +#endif + if (!of_property_read_u32(np, "reg-io-width", &val)) { switch (val) { case 1: break; -- GitLab From f3006e44dd3dc0f2d0ce636585ed95d5b4ad6f35 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 12 Nov 2014 20:32:49 -0200 Subject: [PATCH 6530/9457] serial: mxs-auart: Fix mxs_auart_set_ldisc() Commit 732a84a037a4 ("serial: core: Pass termios to set_ldisc() notifications") changed the set_ldisc prototype. At the time of this commit the mxs_auart driver did not implement set_ldisc, so that's why it has not been converted. Adapt also mxs_auart_set_ldisc() so that the following build warning can be fixed: drivers/tty/serial/mxs-auart.c:962:2: warning: initialization from incompatible pointer type .set_ldisc = mxs_auart_set_ldisc, ^ drivers/tty/serial/mxs-auart.c:962:2: warning: (near initialization for 'mxs_auart_ops.set_ldisc') Signed-off-by: Fabio Estevam Tested-by: Janusz Uzycki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 386b52894056..0262a6a50834 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -784,9 +784,10 @@ static void mxs_auart_settermios(struct uart_port *u, mxs_auart_disable_ms(u); } -static void mxs_auart_set_ldisc(struct uart_port *port, int new) +static void mxs_auart_set_ldisc(struct uart_port *port, + struct ktermios *termios) { - if (new == N_PPS) { + if (termios->c_line == N_PPS) { port->flags |= UPF_HARDPPS_CD; mxs_auart_enable_ms(port); } else { -- GitLab From 08f937f4bcbe156773834935018c9bf7874a42f3 Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Fri, 14 Nov 2014 23:24:33 +0100 Subject: [PATCH 6531/9457] serial: mxs-auart: fix gpio change detection on interrupt mxs_auart_modem_status() did't detect gpio's state change because s->mctrl_prev was modified before by mctrl_gpio_get(). The patch introduces mctrl_temp variable to fix the bug. Signed-off-by: Janusz Uzycki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 0262a6a50834..21b3b3569461 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -799,6 +799,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) { u32 istat; struct mxs_auart_port *s = context; + u32 mctrl_temp = s->mctrl_prev; u32 stat = readl(s->port.membase + AUART_STAT); istat = readl(s->port.membase + AUART_INTR); @@ -818,7 +819,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) irq == s->gpio_irq[UART_GPIO_DSR] || irq == s->gpio_irq[UART_GPIO_RI]) mxs_auart_modem_status(s, - mctrl_gpio_get(s->gpios, &s->mctrl_prev)); + mctrl_gpio_get(s->gpios, &mctrl_temp)); if (istat & AUART_INTR_CTSMIS) { if (CTS_AT_AUART() && s->ms_irq_enabled) -- GitLab From 2b310ec7934f69c6e9a49dd675f413e112b82e5c Mon Sep 17 00:00:00 2001 From: Janusz Uzycki Date: Tue, 18 Nov 2014 18:37:13 +0100 Subject: [PATCH 6532/9457] serial: mxs-auart: fix tx_empty against shift register tx_empty() should test whether both the transmitter fifo and shifter for the port is empty, ie. the whole last char was transmitted. The shift register is empty if AUART_STAT_BUSY is cleared. The patch fixes the function against the shift register. According to i.MX23 and i.MX28 Reference Manual: AUART_STAT_TXFE: TX FIFO or transmit holding register is empty. AUART_STAT_BUSY: AUART still transmits bits. The BUSY signal goes HIGH as soon as the data is written to the transmit FIFO (that is, the FIFO is non-empty) and remains asserted HIGH while data is being transmitted. BUSY is negated only when the transmit FIFO is empty, and the last character has been transmitted from the shift register, including the stop bits. Signed-off-by: Janusz Uzycki Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 21b3b3569461..b7a5aaa6271a 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -913,10 +913,11 @@ static void mxs_auart_shutdown(struct uart_port *u) static unsigned int mxs_auart_tx_empty(struct uart_port *u) { - if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE) + if ((readl(u->membase + AUART_STAT) & + (AUART_STAT_TXFE | AUART_STAT_BUSY)) == AUART_STAT_TXFE) return TIOCSER_TEMT; - else - return 0; + + return 0; } static void mxs_auart_start_tx(struct uart_port *u) -- GitLab From cb8ee9f08c4abfd8744eabffc467c06795c835d9 Mon Sep 17 00:00:00 2001 From: Peter Hung Date: Wed, 19 Nov 2014 13:22:27 +0800 Subject: [PATCH 6533/9457] serial: Fix io address assign flow with Fintek PCI-to-UART Product The original driver fixed the io address with 0xe000+idx*8, but real io address assigned from BIOS is dynamically from read PCI configure space 0x24, 0x20, 0x1c. The Fintek F81504/F81508/F81512 maybe malfunction without this patch and malfunction surely when more then 1 PCI card. Signed-off-by: Peter Hung Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 61 ++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 0468e15e6f10..31feeb2d0a66 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1554,25 +1554,48 @@ static int pci_fintek_setup(struct serial_private *priv, unsigned long iobase; unsigned long ciobase = 0; u8 config_base; + u32 bar_data[3]; /* - * We are supposed to be able to read these from the PCI config space, - * but the values there don't seem to match what we need to use, so - * just use these hard-coded values for now, as they are correct. + * Find each UARTs offset in PCI configuraion space */ switch (idx) { - case 0: iobase = 0xe000; config_base = 0x40; break; - case 1: iobase = 0xe008; config_base = 0x48; break; - case 2: iobase = 0xe010; config_base = 0x50; break; - case 3: iobase = 0xe018; config_base = 0x58; break; - case 4: iobase = 0xe020; config_base = 0x60; break; - case 5: iobase = 0xe028; config_base = 0x68; break; - case 6: iobase = 0xe030; config_base = 0x70; break; - case 7: iobase = 0xe038; config_base = 0x78; break; - case 8: iobase = 0xe040; config_base = 0x80; break; - case 9: iobase = 0xe048; config_base = 0x88; break; - case 10: iobase = 0xe050; config_base = 0x90; break; - case 11: iobase = 0xe058; config_base = 0x98; break; + case 0: + config_base = 0x40; + break; + case 1: + config_base = 0x48; + break; + case 2: + config_base = 0x50; + break; + case 3: + config_base = 0x58; + break; + case 4: + config_base = 0x60; + break; + case 5: + config_base = 0x68; + break; + case 6: + config_base = 0x70; + break; + case 7: + config_base = 0x78; + break; + case 8: + config_base = 0x80; + break; + case 9: + config_base = 0x88; + break; + case 10: + config_base = 0x90; + break; + case 11: + config_base = 0x98; + break; default: /* Unknown number of ports, get out of here */ return -EINVAL; @@ -1583,6 +1606,14 @@ static int pci_fintek_setup(struct serial_private *priv, ciobase = (int)(base + (0x8 * idx)); } + /* Get the io address dispatch from the BIOS */ + pci_read_config_dword(pdev, 0x24, &bar_data[0]); + pci_read_config_dword(pdev, 0x20, &bar_data[1]); + pci_read_config_dword(pdev, 0x1c, &bar_data[2]); + + /* Calculate Real IO Port */ + iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8; + dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", __func__, idx, iobase, ciobase, config_base); -- GitLab From f0c1e460452138df03cb7a7f0e7546b74950b783 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2014 11:18:02 +0100 Subject: [PATCH 6534/9457] serial: tegra: clean up tty-flag assignments The tty break and error flags are not bit masks so do not to use bitwise OR when assigning them. Note that there is no functional change due to the if-else construct and flag having been initialised to zero (TTY_NORMAL). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 78a5cf65bf02..48e6e41636b2 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -319,16 +319,16 @@ static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { if (lsr & UART_LSR_OE) { /* Overrrun error */ - flag |= TTY_OVERRUN; + flag = TTY_OVERRUN; tup->uport.icount.overrun++; dev_err(tup->uport.dev, "Got overrun errors\n"); } else if (lsr & UART_LSR_PE) { /* Parity error */ - flag |= TTY_PARITY; + flag = TTY_PARITY; tup->uport.icount.parity++; dev_err(tup->uport.dev, "Got Parity errors\n"); } else if (lsr & UART_LSR_FE) { - flag |= TTY_FRAME; + flag = TTY_FRAME; tup->uport.icount.frame++; dev_err(tup->uport.dev, "Got frame errors\n"); } else if (lsr & UART_LSR_BI) { -- GitLab From ddcbad929510bcad640693fe3cf299632823f61c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 20 Nov 2014 18:33:59 +0100 Subject: [PATCH 6535/9457] serial: icom: fix error return code Return a negative error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/icom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index d4620fe5da2e..45fc323b95e6 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1550,8 +1550,10 @@ static int icom_probe(struct pci_dev *dev, icom_adapter->base_addr = pci_ioremap_bar(dev, 0); - if (!icom_adapter->base_addr) + if (!icom_adapter->base_addr) { + retval = -ENOMEM; goto probe_exit1; + } /* save off irq and request irq line */ if ( (retval = request_irq(dev->irq, icom_interrupt, -- GitLab From 1ff383a4c3eda8893ec61b02831826e1b1f46b41 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 24 Nov 2014 07:56:21 +0100 Subject: [PATCH 6536/9457] serial: samsung: wait for transfer completion before clock disable This patch adds waiting until transmit buffer and shifter will be empty before clock disabling. Without this fix it's possible to have clock disabled while data was not transmited yet, which causes unproper state of TX line and problems in following data transfers. Cc: # v2.6.26+ Signed-off-by: Robert Baldyga Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 796c04c77dc1..d36b2bd39e30 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -559,11 +559,15 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, unsigned int old) { struct s3c24xx_uart_port *ourport = to_ourport(port); + int timeout = 10000; ourport->pm_level = level; switch (level) { case 3: + while (--timeout && !s3c24xx_serial_txempty_nofifo(port)) + udelay(100); + if (!IS_ERR(ourport->baudclk)) clk_disable_unprepare(ourport->baudclk); -- GitLab From ef4aca704836920fe16f50e4d859e22162f6e8f7 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 24 Nov 2014 07:56:22 +0100 Subject: [PATCH 6537/9457] serial: samsung: fix style problems Split lines longer than 80 chars and remove unnecessary whitespaces. Signed-off-by: Robert Baldyga Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 46 ++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d36b2bd39e30..33a953e4cf16 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -199,12 +199,14 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) } } -static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port) +static inline struct s3c24xx_uart_info + *s3c24xx_port_to_info(struct uart_port *port) { return to_ourport(port)->info; } -static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) +static inline struct s3c2410_uartcfg + *s3c24xx_port_to_cfg(struct uart_port *port) { struct s3c24xx_uart_port *ourport; @@ -311,14 +313,14 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); - ignore_char: +ignore_char: continue; } spin_unlock_irqrestore(&port->lock, flags); tty_flip_buffer_push(&port->state->port); - out: +out: return IRQ_HANDLED; } @@ -368,7 +370,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) if (uart_circ_empty(xmit)) s3c24xx_serial_stop_tx(port); - out: +out: spin_unlock_irqrestore(&port->lock, flags); return IRQ_HANDLED; } @@ -519,7 +521,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) return ret; - err: +err: s3c24xx_serial_shutdown(port); return ret; } @@ -845,8 +847,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, */ port->read_status_mask = S3C2410_UERSTAT_OVERRUN; if (termios->c_iflag & INPCK) - port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY; - + port->read_status_mask |= S3C2410_UERSTAT_FRAME | + S3C2410_UERSTAT_PARITY; /* * Which character status flags should we ignore? */ @@ -973,10 +975,13 @@ static struct uart_driver s3c24xx_uart_drv = { .minor = S3C24XX_SERIAL_MINOR, }; -static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { +#define __PORT_LOCK_UNLOCKED(i) \ + __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock) +static struct s3c24xx_uart_port +s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { [0] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), + .lock = __PORT_LOCK_UNLOCKED(0), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -987,7 +992,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS }, [1] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), + .lock = __PORT_LOCK_UNLOCKED(1), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -1000,7 +1005,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS [2] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), + .lock = __PORT_LOCK_UNLOCKED(2), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -1013,7 +1018,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 [3] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), + .lock = __PORT_LOCK_UNLOCKED(3), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -1024,6 +1029,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS } #endif }; +#undef __PORT_LOCK_UNLOCKED /* s3c24xx_serial_resetport * @@ -1106,11 +1112,12 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, s3c24xx_serial_set_termios(uport, termios, NULL); } - exit: +exit: return 0; } -static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) +static inline int +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; @@ -1118,19 +1125,22 @@ static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port CPUFREQ_TRANSITION_NOTIFIER); } -static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) +static inline void +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else -static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) +static inline int +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { return 0; } -static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) +static inline void +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { } #endif -- GitLab From 2f1ba72d23a2fa0cdcb4f034a059ce97e6a17696 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 24 Nov 2014 07:56:23 +0100 Subject: [PATCH 6538/9457] serial: samsung: prefer to use fifosize from driver data If we have fifosize set in driver data we prefer to use it instead of default fifosize value (which is always 16). If there is defined fifosize for particular serial we prefer to use it, otherwise we use value from info, which is common for all serials on given platform. Signed-off-by: Robert Baldyga Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 33a953e4cf16..34db16715efc 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1292,11 +1292,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize); - if (!ourport->port.fifosize) { - ourport->port.fifosize = (ourport->info->fifosize) ? - ourport->info->fifosize : - ourport->drv_data->fifosize[index]; - } + if (ourport->drv_data->fifosize[index]) + ourport->port.fifosize = ourport->drv_data->fifosize[index]; + else if (ourport->info->fifosize) + ourport->port.fifosize = ourport->info->fifosize; probe_index++; -- GitLab From 57850a50c1f91c6136fe0b4b27301ebbe848b2ce Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 24 Nov 2014 07:56:24 +0100 Subject: [PATCH 6539/9457] serial: samsung: use port->fifosize instead of hardcoded values Hardcoded FIFO size can cause hardware performance limitation. Using real size value provides better FIFO usage. Signed-off-by: Robert Baldyga Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 34db16715efc..7ed76773c274 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -239,7 +239,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) struct uart_port *port = &ourport->port; unsigned int ufcon, ch, flag, ufstat, uerstat; unsigned long flags; - int max_count = 64; + int max_count = port->fifosize; spin_lock_irqsave(&port->lock, flags); @@ -330,7 +330,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) struct uart_port *port = &ourport->port; struct circ_buf *xmit = &port->state->xmit; unsigned long flags; - int count = 256; + int count = port->fifosize; spin_lock_irqsave(&port->lock, flags); -- GitLab From 3ffb1a8193bead7bf4ef0fec2dae050c70e4c1c1 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 12 Nov 2014 12:53:59 -0800 Subject: [PATCH 6540/9457] serial: core: Add big-endian iotype Since most drivers interpret UPIO_MEM32 to mean "little-endian" and use readl/writel to access the registers, add a parallel UPIO_MEM32BE to request the use of big-endian MMIO accessors (ioread32be/iowrite32be). Signed-off-by: Kevin Cernekee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 ++ include/linux/serial_core.h | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 5c8b8f50f787..57ca61b14670 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2153,6 +2153,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) break; case UPIO_MEM: case UPIO_MEM32: + case UPIO_MEM32BE: case UPIO_AU: case UPIO_TSI: snprintf(address, sizeof(address), @@ -2796,6 +2797,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) (port1->hub6 == port2->hub6); case UPIO_MEM: case UPIO_MEM32: + case UPIO_MEM32BE: case UPIO_AU: case UPIO_TSI: return (port1->mapbase == port2->mapbase); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3231a43f6acf..057038cf2788 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -142,12 +142,13 @@ struct uart_port { unsigned char iotype; /* io access style */ unsigned char unused1; -#define UPIO_PORT (0) -#define UPIO_HUB6 (1) -#define UPIO_MEM (2) -#define UPIO_MEM32 (3) -#define UPIO_AU (4) /* Au1x00 and RT288x type IO */ -#define UPIO_TSI (5) /* Tsi108/109 type IO */ +#define UPIO_PORT (0) /* 8b I/O port access */ +#define UPIO_HUB6 (1) /* Hub6 ISA card */ +#define UPIO_MEM (2) /* 8b MMIO access */ +#define UPIO_MEM32 (3) /* 32b little endian */ +#define UPIO_MEM32BE (4) /* 32b big endian */ +#define UPIO_AU (5) /* Au1x00 and RT288x type IO */ +#define UPIO_TSI (6) /* Tsi108/109 type IO */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ -- GitLab From 6fad18fa51392c9847a4e3a95134b2e57155e563 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 14 Nov 2014 19:00:41 +0100 Subject: [PATCH 6541/9457] serial: 8250: don't attempt a trylock if in sysrq Attempting to use SysRq via the 8250 serial port with spin lock debugging on on a uniprocessor system results in the following splat: SysRq : BUG: spinlock trylock failure on UP on CPU#0, swapper/0 lock: serial8250_ports+0x0/0x8c0, .magic: dead4ead, .owner: swapper/0, .owner_cpu: 0 CPU: 0 PID: 0 Comm: swapper Not tainted 3.18.0-rc4+ #37 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 ffffffff8245ba00 ffffffff81628b28 ffffffff812c8d27 ffffffff81628b48 ffffffff8106812e ffffffff8245ba00 ffffffff814e22ed ffffffff81628b68 ffffffff810681a6 0000000000000000 0000000000000000 ffffffff81628b88 Call Trace: [] dump_stack+0x19/0x1b [] spin_dump+0x7e/0xd0 [] spin_bug+0x26/0x30 [] do_raw_spin_trylock+0x4c/0x60 [] _raw_spin_trylock+0x1d/0x60 [] serial8250_console_write+0x68/0x190 [] ? sprintf+0x40/0x50 [] call_console_drivers.constprop.11+0x9e/0xf0 [] console_unlock+0x3e6/0x490 [] vprintk_emit+0x275/0x530 [] printk+0x4d/0x4f [] __handle_sysrq+0x62/0x1b0 [] ? __handle_sysrq+0x5/0x1b0 [] handle_sysrq+0x26/0x30 [] serial8250_rx_chars+0x1d7/0x250 [] serial8250_handle_irq+0x7b/0x90 [] serial8250_default_handle_irq+0x23/0x30 [] serial8250_interrupt+0x63/0xe0 [] handle_irq_event_percpu+0x4e/0x200 [] handle_irq_event+0x41/0x70 [] ? handle_edge_irq+0x1e/0x110 [] handle_edge_irq+0x9e/0x110 [] handle_irq+0x22/0x40 [] do_IRQ+0x4e/0xf0 [] common_interrupt+0x6d/0x6d [] ? default_idle+0x1f/0xd0 [] ? default_idle+0x1d/0xd0 [] arch_cpu_idle+0xf/0x20 [] cpu_startup_entry+0x25b/0x360 [] rest_init+0xbe/0xd0 [] start_kernel+0x339/0x346 [] x86_64_start_reservations+0x2a/0x2c [] x86_64_start_kernel+0xf2/0xf6 HELP : loglevel(0-9) reboot(b) crash(c) show-all-locks(d) te... Before ebade5e833eda30 ("serial: 8250: Clean up the locking for -rt") this was handled by not even attempting to try the lock if port->sysrq, since it is known to be taken by the interrupt handler; see https://bugzilla.kernel.org/show_bug.cgi?id=6716#c1. Restore that behavior. Signed-off-by: Rabin Vincent Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index d0d0c3b6af02..9515924b7f38 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -3191,7 +3191,9 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) serial8250_rpm_get(up); - if (port->sysrq || oops_in_progress) + if (port->sysrq) + locked = 0; + else if (oops_in_progress) locked = spin_trylock_irqsave(&port->lock, flags); else spin_lock_irqsave(&port->lock, flags); -- GitLab From 962b0a884a4d18326596e0434d813c17d7f688ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 25 Nov 2014 12:58:50 -0800 Subject: [PATCH 6542/9457] Revert "serial: of-serial: fix up PM ops on no_console_suspend and port type" This reverts commit 513e438581020334e0345561adeeeaefa36701be. It's broken :( Cc: Jingchang Lu Cc: Joseph Lo Cc: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 53 +++++----------------------------- 1 file changed, 7 insertions(+), 46 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index fd00e2521584..088907053ea1 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. * */ -#include #include #include #include @@ -249,48 +248,13 @@ static int of_platform_serial_remove(struct platform_device *ofdev) } #ifdef CONFIG_PM_SLEEP -#ifdef CONFIG_SERIAL_8250 -static void of_serial_suspend_8250(struct of_serial_info *info) -{ - struct uart_8250_port *port8250 = serial8250_get_port(info->line); - struct uart_port *port = &port8250->port; - - serial8250_suspend_port(info->line); - if (info->clk && (!uart_console(port) || console_suspend_enabled)) - clk_disable_unprepare(info->clk); -} - -static void of_serial_resume_8250(struct of_serial_info *info) -{ - struct uart_8250_port *port8250 = serial8250_get_port(info->line); - struct uart_port *port = &port8250->port; - - if (info->clk && (!uart_console(port) || console_suspend_enabled)) - clk_prepare_enable(info->clk); - - serial8250_resume_port(info->line); -} -#else -static inline void of_serial_suspend_8250(struct of_serial_info *info) -{ -} - -static inline void of_serial_resume_8250(struct of_serial_info *info) -{ -} -#endif - static int of_serial_suspend(struct device *dev) { struct of_serial_info *info = dev_get_drvdata(dev); - switch(info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_suspend_8250(info); - break; - default: - break; - } + serial8250_suspend_port(info->line); + if (info->clk) + clk_disable_unprepare(info->clk); return 0; } @@ -299,13 +263,10 @@ static int of_serial_resume(struct device *dev) { struct of_serial_info *info = dev_get_drvdata(dev); - switch(info->type) { - case PORT_8250 ... PORT_MAX_8250: - of_serial_resume_8250(info); - break; - default: - break; - } + if (info->clk) + clk_prepare_enable(info->clk); + + serial8250_resume_port(info->line); return 0; } -- GitLab From 261119f727a4c7cfc001eed0d94cea70e662433a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 25 Nov 2014 12:46:39 -0800 Subject: [PATCH 6543/9457] Revert "serial: of-serial: add PM suspend/resume support" This reverts commit 2dea53bf57783f243c892e99c10c6921e956aa7e. Turns out to be broken :( Cc: Jingchang Lu Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 088907053ea1..12c95cc64c00 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -247,32 +247,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int of_serial_suspend(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - serial8250_suspend_port(info->line); - if (info->clk) - clk_disable_unprepare(info->clk); - - return 0; -} - -static int of_serial_resume(struct device *dev) -{ - struct of_serial_info *info = dev_get_drvdata(dev); - - if (info->clk) - clk_prepare_enable(info->clk); - - serial8250_resume_port(info->line); - - return 0; -} -#endif -static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); - /* * A few common types, add more as needed. */ @@ -305,7 +279,6 @@ static struct platform_driver of_platform_serial_driver = { .name = "of_serial", .owner = THIS_MODULE, .of_match_table = of_platform_serial_table, - .pm = &of_serial_pm_ops, }, .probe = of_platform_serial_probe, .remove = of_platform_serial_remove, -- GitLab From 8ad3b1352693972b737607c7b9c89b56d45fea9b Mon Sep 17 00:00:00 2001 From: Jingchang Lu Date: Tue, 11 Nov 2014 15:09:05 +0800 Subject: [PATCH 6544/9457] serial: of-serial: add PM suspend/resume support This adds suspend/resume support for the of-serial driver to provide power management support on devices attatched. The handling may vary since not every of_serial device is an 8250 port. Currently only 8250 port handling is added in the suspend/resume function based on the type switch. Signed-off-by: Jingchang Lu Acked-by: Arnd Bergmann Tested-by: Joseph Lo Reviewed-by: Peter Hurley Tested-by: Florina Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 12c95cc64c00..58830bcddb7f 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. * */ +#include #include #include #include @@ -247,6 +248,70 @@ static int of_platform_serial_remove(struct platform_device *ofdev) return 0; } +#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_SERIAL_8250 +static void of_serial_suspend_8250(struct of_serial_info *info) +{ + struct uart_8250_port *port8250 = serial8250_get_port(info->line); + struct uart_port *port = &port8250->port; + + serial8250_suspend_port(info->line); + if (info->clk && (!uart_console(port) || console_suspend_enabled)) + clk_disable_unprepare(info->clk); +} + +static void of_serial_resume_8250(struct of_serial_info *info) +{ + struct uart_8250_port *port8250 = serial8250_get_port(info->line); + struct uart_port *port = &port8250->port; + + if (info->clk && (!uart_console(port) || console_suspend_enabled)) + clk_prepare_enable(info->clk); + + serial8250_resume_port(info->line); +} +#else +static inline void of_serial_suspend_8250(struct of_serial_info *info) +{ +} + +static inline void of_serial_resume_8250(struct of_serial_info *info) +{ +} +#endif + +static int of_serial_suspend(struct device *dev) +{ + struct of_serial_info *info = dev_get_drvdata(dev); + + switch (info->type) { + case PORT_8250 ... PORT_MAX_8250: + of_serial_suspend_8250(info); + break; + default: + break; + } + + return 0; +} + +static int of_serial_resume(struct device *dev) +{ + struct of_serial_info *info = dev_get_drvdata(dev); + + switch (info->type) { + case PORT_8250 ... PORT_MAX_8250: + of_serial_resume_8250(info); + break; + default: + break; + } + + return 0; +} +#endif +static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); + /* * A few common types, add more as needed. */ @@ -279,6 +344,7 @@ static struct platform_driver of_platform_serial_driver = { .name = "of_serial", .owner = THIS_MODULE, .of_match_table = of_platform_serial_table, + .pm = &of_serial_pm_ops, }, .probe = of_platform_serial_probe, .remove = of_platform_serial_remove, -- GitLab From d4f761074353b9aa42a3bdd039d78e1af5f5f29f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 25 Nov 2014 20:19:17 -0500 Subject: [PATCH 6545/9457] ext4: forbid journal_async_commit in data=ordered mode Option journal_async_commit breaks gurantees of data=ordered mode as it sends only a single cache flush after writing a transaction commit block. Thus even though the transaction including the commit block is fully stored on persistent storage, file data may still linger in drives caches and will be lost on power failure. Since all checksums match on journal recovery, we replay the transaction thus possibly exposing stale user data. To fix this data exposure issue, remove the possibility to use journal_async_commit in data=ordered mode. Signed-off-by: Jan Kara Signed-off-by: Theodore Ts'o --- fs/ext4/super.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f8ad756bb852..4fca81cc8fce 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1695,6 +1695,12 @@ static int parse_options(char *options, struct super_block *sb, return 0; } } + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA && + test_opt(sb, JOURNAL_ASYNC_COMMIT)) { + ext4_msg(sb, KERN_ERR, "can't mount with journal_async_commit " + "in data=ordered mode"); + return 0; + } return 1; } -- GitLab From 20d047c87621090152c89f9581f78a69b02e0e35 Mon Sep 17 00:00:00 2001 From: Changman Lee Date: Tue, 25 Nov 2014 12:44:23 +0900 Subject: [PATCH 6546/9457] f2fs: check dirty_nat_cnt before flushing nat entries in journal It's meaningless to check dirty_nat_cnt after re-dirtying nat entries in journal. And although there are rooms for dirty nat entires if dirty_nat_cnt is zero, it's also meaningless to check __has_cursum_space. Signed-off-by: Changman Lee Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 36656add1c9b..4af3feef2884 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -171,7 +171,7 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i, static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i, struct nat_entry *ne) { - nid_t set = ne->ni.nid / NAT_ENTRY_PER_BLOCK; + nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid); struct nat_entry_set *head; head = radix_tree_lookup(&nm_i->nat_set_root, set); @@ -1945,6 +1945,8 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) nid_t set_idx = 0; LIST_HEAD(sets); + if (!nm_i->dirty_nat_cnt) + return; /* * if there are no enough space in journal to store dirty nat * entries, remove all entries from journal and merge them @@ -1953,9 +1955,6 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) remove_nats_in_journal(sbi); - if (!nm_i->dirty_nat_cnt) - return; - while ((found = __gang_lookup_nat_set(nm_i, set_idx, NATVEC_SIZE, setvec))) { unsigned idx; -- GitLab From 80ec2e914d7e1a1edb93d89cce96dd145c85636a Mon Sep 17 00:00:00 2001 From: Changman Lee Date: Tue, 25 Nov 2014 12:44:24 +0900 Subject: [PATCH 6547/9457] f2fs: no more dirty_nat_entires when flushing After flushing dirty nat entries, it has to be no more dirty nat entries. Signed-off-by: Changman Lee Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 4af3feef2884..b1466cf79d07 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1925,10 +1925,10 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, else f2fs_put_page(page, 1); - if (!set->entry_cnt) { - radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); - kmem_cache_free(nat_entry_set_slab, set); - } + f2fs_bug_on(sbi, set->entry_cnt); + + radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); + kmem_cache_free(nat_entry_set_slab, set); } /* -- GitLab From 250d07d1e782e68e9b2e7b637703b3739f0ec1b1 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 26 Nov 2014 07:45:12 +0800 Subject: [PATCH 6548/9457] clk: clk-s2mps11: fix semicolon.cocci warnings drivers/clk/clk-s2mps11.c:181:2-3: Unneeded semicolon Removes unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci CC: Tushar Behera Signed-off-by: Fengguang Wu Signed-off-by: Michael Turquette --- drivers/clk/clk-s2mps11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index b7797fb12e12..f16ab25e12c0 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -195,7 +195,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "Invalid device type\n"); return -EINVAL; - }; + } /* Store clocks of_node in first element of s2mps11_clks array */ s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); -- GitLab From 158c194c375be1b82149f9de80fd90e522979dc5 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 25 Nov 2014 11:34:02 -0800 Subject: [PATCH 6549/9457] f2fs: make clean the page before writing If a page is set to be written to the disk, we can make clean the page. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 914b6d37c5cf..e27f290cb3ef 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -84,7 +84,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) .type = DATA, .rw = WRITE_SYNC | REQ_PRIO, }; - int err; + int dirty, err; f2fs_bug_on(F2FS_I_SB(dn->inode), page->index); @@ -110,12 +110,17 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) kunmap_atomic(dst_addr); SetPageUptodate(page); no_update: + /* clear dirty state */ + dirty = clear_page_dirty_for_io(page); + /* write data page to try to make data consistent */ set_page_writeback(page); write_data_page(page, dn, &new_blk_addr, &fio); update_extent_cache(new_blk_addr, dn); f2fs_wait_on_page_writeback(page, DATA); + if (dirty) + inode_dec_dirty_pages(dn->inode); /* clear inline data and flag after data writeback */ truncate_inline_data(dn->inode_page, 0); -- GitLab From 95f5b0fc5e25d94ace84dbf5bb4acb8b80b4f062 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 25 Nov 2014 17:27:38 -0800 Subject: [PATCH 6550/9457] f2fs: fix to recover converted inline_data If an inode has converted inline_data which was written to the disk, we should set its inode flag for further fsync so that this inline_data can be recovered from sudden power off. Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index e27f290cb3ef..f2d3c581e776 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -122,6 +122,9 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) if (dirty) inode_dec_dirty_pages(dn->inode); + /* this converted inline_data should be recovered. */ + set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE); + /* clear inline data and flag after data writeback */ truncate_inline_data(dn->inode_page, 0); clear_out: -- GitLab From 3755a99157d3b038f9dfe9bb203c520cb9728b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 21 Oct 2014 00:01:04 +0200 Subject: [PATCH 6551/9457] mtd: nand: print erase size on init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It may be useful info, e.g. if someone wants to use ubinize. Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 755995ed87fe..4cbd14552d48 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3765,9 +3765,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, type->name); - pr_info("%dMiB, %s, page size: %d, OOB size: %d\n", + pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", - mtd->writesize, mtd->oobsize); + mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); return type; } -- GitLab From 90eed0ee5588ad3b3a5dbeb5a127b5c5ba5323ae Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:47 +0100 Subject: [PATCH 6552/9457] ARM: mvebu: add Device Tree description of USB cluster controller on Armada 375 On Armada 375, the USB cluster allows to control the cluster composed of the USB2 and USB3 host controllers. Acked-by: Kishon Vijay Abraham I Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1415879269-29711-6-git-send-email-gregory.clement@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-375.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 9721e55384ce..ff376387a798 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -348,6 +348,12 @@ #clock-cells = <1>; }; + usbcluster: usb-cluster@18400 { + compatible = "marvell,armada-375-usb-cluster"; + reg = <0x18400 0x4>; + #phy-cells = <1>; + }; + mbusc: mbus-controller@20000 { compatible = "marvell,mbus-controller"; reg = <0x20000 0x100>, <0x20180 0x20>; -- GitLab From 623394def7ef023aa44e338de680222cdc93c4a5 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:48 +0100 Subject: [PATCH 6553/9457] ARM: mvebu: add PHY support to the dts for the USB controllers on Armada 375 Now that the USB cluster node has been added, use it as a PHY provider for the USB controller linked to it: the first EHCI and the xHCI. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1415879269-29711-7-git-send-email-gregory.clement@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-375.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index ff376387a798..50096d3427eb 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -14,6 +14,7 @@ #include "skeleton.dtsi" #include #include +#include #define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) @@ -404,6 +405,8 @@ reg = <0x50000 0x500>; interrupts = ; clocks = <&gateclk 18>; + phys = <&usbcluster PHY_TYPE_USB2>; + phy-names = "usb"; status = "disabled"; }; @@ -420,6 +423,8 @@ reg = <0x58000 0x20000>,<0x5b880 0x80>; interrupts = ; clocks = <&gateclk 16>; + phys = <&usbcluster PHY_TYPE_USB3>; + phy-names = "usb"; status = "disabled"; }; -- GitLab From 641519cb61bc766c3b4a70fd9ef14fc9509bf8bf Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 4 Nov 2014 11:32:45 -0800 Subject: [PATCH 6554/9457] mtd: nand: add ATO manufacturer info Tested with ATO AFND1G08U3, 128MiB NAND. Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_ids.c | 1 + include/linux/mtd/nand.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index fbde89105245..dd620c19c619 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -178,6 +178,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_EON, "Eon"}, {NAND_MFR_SANDISK, "SanDisk"}, {NAND_MFR_INTEL, "Intel"}, + {NAND_MFR_ATO, "ATO"}, {0x0, "Unknown"} }; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b14d190b593a..3d4ea7eb2b68 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -736,6 +736,7 @@ struct nand_chip { #define NAND_MFR_EON 0x92 #define NAND_MFR_SANDISK 0x45 #define NAND_MFR_INTEL 0x89 +#define NAND_MFR_ATO 0x9b /* The maximum expected count of bytes in the NAND ID sequence */ #define NAND_MAX_ID_LEN 8 -- GitLab From 69bb631ef9505df1eb4123bc01d2218f7b48c577 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 25 Nov 2014 10:04:57 +0530 Subject: [PATCH 6555/9457] ieee802154: fix spelling mistakes Signed-off-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 2 +- net/ieee802154/netlink.c | 2 +- net/ieee802154/nl-mac.c | 2 +- net/ieee802154/nl-phy.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 290e14f2e92e..16f5e91bd390 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -597,7 +597,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, entry->ldev = dev; - /* Set the lowpan harware address to the wpan hardware address. */ + /* Set the lowpan hardware address to the wpan hardware address. */ memcpy(dev->dev_addr, real_dev->dev_addr, IEEE802154_ADDR_LEN); mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 63ee7d66950e..6ad0da38ba9d 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c @@ -1,5 +1,5 @@ /* - * Netlink inteface for IEEE 802.15.4 stack + * Netlink interface for IEEE 802.15.4 stack * * Copyright 2007, 2008 Siemens AG * diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index fe77f0c770b8..1f085ed944d2 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c @@ -1,5 +1,5 @@ /* - * Netlink inteface for IEEE 802.15.4 stack + * Netlink interface for IEEE 802.15.4 stack * * Copyright 2007, 2008 Siemens AG * diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c index 80a946dddd90..62463544d056 100644 --- a/net/ieee802154/nl-phy.c +++ b/net/ieee802154/nl-phy.c @@ -1,5 +1,5 @@ /* - * Netlink inteface for IEEE 802.15.4 stack + * Netlink interface for IEEE 802.15.4 stack * * Copyright 2007, 2008 Siemens AG * -- GitLab From 473f3766b5c2145f4c70bed39f4595b15c889ae2 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Tue, 25 Nov 2014 16:34:43 +0530 Subject: [PATCH 6556/9457] mac802154: remove unnecessary if statement Removes unnecessary if statement check for net device. Error check performed after alloc_netdev(). ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, name, NET_NAME_UNKNOWN, ieee802154_if_setup); if (!ndev) return ERR_PTR(-ENOMEM); .. Signed-off-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/iface.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 38dfc72d24b6..9ae893057dd7 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c @@ -510,11 +510,9 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name, if (ret) goto err; - if (ndev) { - ret = register_netdevice(ndev); - if (ret < 0) - goto err; - } + ret = register_netdevice(ndev); + if (ret < 0) + goto err; mutex_lock(&local->iflist_mtx); list_add_tail_rcu(&sdata->list, &local->interfaces); -- GitLab From c1fc0050102150481ad4ba7e6449b3aa6e88d6e5 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:43 +0100 Subject: [PATCH 6557/9457] phy: Use PTR_ERR_OR_ZERO to fix warning raised by coccinelle Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: coccinelle/api/ptr_ret.cocci Signed-off-by: Gregory CLEMENT Acked-by: Jason Cooper Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-berlin-sata.c | 5 +---- drivers/phy/phy-hix5hd2-sata.c | 5 +---- drivers/phy/phy-miphy365x.c | 5 +---- drivers/phy/phy-stih41x-usb.c | 5 +---- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c index 3e599dc96164..099eee8851e5 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/phy-berlin-sata.c @@ -268,10 +268,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev) phy_provider = devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; + return PTR_ERR_OR_ZERO(phy_provider); } static const struct of_device_id phy_berlin_sata_of_match[] = { diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c index a80ff9d7fe15..34915b4202f1 100644 --- a/drivers/phy/phy-hix5hd2-sata.c +++ b/drivers/phy/phy-hix5hd2-sata.c @@ -164,10 +164,7 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev) phy_set_drvdata(phy, priv); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; + return PTR_ERR_OR_ZERO(phy_provider); } static const struct of_device_id hix5hd2_sata_phy_of_match[] = { diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 239930edfe1d..6ab43a814ad2 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c @@ -610,10 +610,7 @@ static int miphy365x_probe(struct platform_device *pdev) } provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate); - if (IS_ERR(provider)) - return PTR_ERR(provider); - - return 0; + return PTR_ERR_OR_ZERO(provider); } static const struct of_device_id miphy365x_of_match[] = { diff --git a/drivers/phy/phy-stih41x-usb.c b/drivers/phy/phy-stih41x-usb.c index 4ab581eadacf..a603801293ff 100644 --- a/drivers/phy/phy-stih41x-usb.c +++ b/drivers/phy/phy-stih41x-usb.c @@ -160,10 +160,7 @@ static int stih41x_usb_phy_probe(struct platform_device *pdev) phy_set_drvdata(phy, phy_dev); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); - - return 0; + return PTR_ERR_OR_ZERO(phy_provider); } static const struct of_device_id stih41x_usb_phy_of_match[] = { -- GitLab From aa1facbd2847263cf168ec7d66e6c8951c413905 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 13 Nov 2014 12:47:44 +0100 Subject: [PATCH 6558/9457] Phy: DT binding documentation for Marvell MVEBU SATA phy. Describe the binding for the Marvell MVEBU SATA phy. This driver can be used at least with Kirkwood, Dove and maybe others. Additionally, update the SATA binding with the properties to link to the phy nodes. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/ata/marvell.txt | 6 +++++ .../devicetree/bindings/phy/phy-mvebu.txt | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-mvebu.txt diff --git a/Documentation/devicetree/bindings/ata/marvell.txt b/Documentation/devicetree/bindings/ata/marvell.txt index 1c8351604d38..b460edd12766 100644 --- a/Documentation/devicetree/bindings/ata/marvell.txt +++ b/Documentation/devicetree/bindings/ata/marvell.txt @@ -6,11 +6,17 @@ Required Properties: - interrupts : Interrupt controller is using - nr-ports : Number of SATA ports in use. +Optional Properties: +- phys : List of phandles to sata phys +- phy-names : Should be "0", "1", etc, one number per phandle + Example: sata@80000 { compatible = "marvell,orion-sata"; reg = <0x80000 0x5000>; interrupts = <21>; + phys = <&sata_phy0>, <&sata_phy1>; + phy-names = "0", "1"; nr-ports = <2>; } diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt new file mode 100644 index 000000000000..6cb3364aeafb --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -0,0 +1,22 @@ +* Marvell MVEBU SATA PHY + +Power control for the SATA phy found on Marvell MVEBU SoCs. + +This document extends the binding described in phy-bindings.txt + +Required properties : + + - reg : Offset and length of the register set for the SATA device + - compatible : Should be "marvell,mvebu-sata-phy" + - clocks : phandle of clock and specifier that supplies the device + - clock-names : Should be "sata" + +Example: + sata-phy@84000 { + compatible = "marvell,mvebu-sata-phy"; + reg = <0x84000 0x0334>; + clocks = <&gate_clk 15>; + clock-names = "sata"; + #phy-cells = <0>; + status = "ok"; + }; -- GitLab From 1a6ab1c0e844041524f8edd1acf0de94df991aaa Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:45 +0100 Subject: [PATCH 6559/9457] Phy: DT binding documentation for the Armada 375 USB cluster binding Armada 375 comes with an USB2 host and device controller and an USB3 controller. The USB cluster control register allows to manage common features of both USB controllers. This commit adds the Device Tree binding documentation for this piece of hardware. Signed-off-by: Gregory CLEMENT Acked-by: Jason Cooper Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/phy-mvebu.txt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt index 6cb3364aeafb..f95b6260a3b3 100644 --- a/Documentation/devicetree/bindings/phy/phy-mvebu.txt +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -20,3 +20,24 @@ Example: #phy-cells = <0>; status = "ok"; }; + +Armada 375 USB cluster +---------------------- + +Armada 375 comes with an USB2 host and device controller and an USB3 +controller. The USB cluster control register allows to manage common +features of both USB controllers. + +Required properties: + +- compatible: "marvell,armada-375-usb-cluster" +- reg: Should contain usb cluster register location and length. +- #phy-cells : from the generic phy bindings, must be 1. Possible +values are 1 (USB2), 2 (USB3). + +Example: + usbcluster: usb-cluster@18400 { + compatible = "marvell,armada-375-usb-cluster"; + reg = <0x18400 0x4>; + #phy-cells = <1> + }; -- GitLab From eee47538ec1f26198cf5da675975b61d7f16135b Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:46 +0100 Subject: [PATCH 6560/9457] phy: add support for USB cluster on the Armada 375 SoC The Armada 375 SoC comes with an USB2 host and device controller and an USB3 controller. The USB cluster control register allows to manage common features of both USB controllers. This commit adds a driver integrated in the generic PHY framework to control this USB cluster feature. Signed-off-by: Gregory CLEMENT Signed-off-by: Thomas Petazzoni [ kishon@ti.com : Made it to use the updated devm_phy_create API and soem cosmentic changes in Kconfig file.] Signed-off-by: Kishon Vijay Abraham I Acked-by: Jason Cooper --- drivers/phy/Kconfig | 6 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-armada375-usb2.c | 158 +++++++++++++++++++++++++++++++ include/dt-bindings/phy/phy.h | 1 + 4 files changed, 166 insertions(+) create mode 100644 drivers/phy/phy-armada375-usb2.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 96d43d5acc57..ccad8809ecb1 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -29,6 +29,12 @@ config PHY_BERLIN_SATA help Enable this to support the SATA PHY on Marvell Berlin SoCs. +config ARMADA375_USBCLUSTER_PHY + def_bool y + depends on MACH_ARMADA_375 || COMPILE_TEST + depends on OF + select GENERIC_PHY + config PHY_EXYNOS_MIPI_VIDEO tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" depends on HAS_IOMEM diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 68022f698f51..aa74f961e44e 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o +obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o diff --git a/drivers/phy/phy-armada375-usb2.c b/drivers/phy/phy-armada375-usb2.c new file mode 100644 index 000000000000..ac7d99d01cb3 --- /dev/null +++ b/drivers/phy/phy-armada375-usb2.c @@ -0,0 +1,158 @@ +/* + * USB cluster support for Armada 375 platform. + * + * Copyright (C) 2014 Marvell + * + * Gregory CLEMENT + * + * This file is licensed under the terms of the GNU General Public + * License version 2 or later. This program is licensed "as is" + * without any warranty of any kind, whether express or implied. + * + * Armada 375 comes with an USB2 host and device controller and an + * USB3 controller. The USB cluster control register allows to manage + * common features of both USB controllers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB2_PHY_CONFIG_DISABLE BIT(0) + +struct armada375_cluster_phy { + struct phy *phy; + void __iomem *reg; + bool use_usb3; + int phy_provided; +}; + +static int armada375_usb_phy_init(struct phy *phy) +{ + struct armada375_cluster_phy *cluster_phy; + u32 reg; + + cluster_phy = dev_get_drvdata(phy->dev.parent); + if (!cluster_phy) + return -ENODEV; + + reg = readl(cluster_phy->reg); + if (cluster_phy->use_usb3) + reg |= USB2_PHY_CONFIG_DISABLE; + else + reg &= ~USB2_PHY_CONFIG_DISABLE; + writel(reg, cluster_phy->reg); + + return 0; +} + +static struct phy_ops armada375_usb_phy_ops = { + .init = armada375_usb_phy_init, + .owner = THIS_MODULE, +}; + +/* + * Only one controller can use this PHY. We shouldn't have the case + * when two controllers want to use this PHY. But if this case occurs + * then we provide a phy to the first one and return an error for the + * next one. This error has also to be an error returned by + * devm_phy_optional_get() so different from ENODEV for USB2. In the + * USB3 case it still optional and we use ENODEV. + */ +static struct phy *armada375_usb_phy_xlate(struct device *dev, + struct of_phandle_args *args) +{ + struct armada375_cluster_phy *cluster_phy = dev_get_drvdata(dev); + + if (!cluster_phy) + return ERR_PTR(-ENODEV); + + /* + * Either the phy had never been requested and then the first + * usb claiming it can get it, or it had already been + * requested in this case, we only allow to use it with the + * same configuration. + */ + if (WARN_ON((cluster_phy->phy_provided != PHY_NONE) && + (cluster_phy->phy_provided != args->args[0]))) { + dev_err(dev, "This PHY has already been provided!\n"); + dev_err(dev, "Check your device tree, only one controller can use it\n."); + if (args->args[0] == PHY_TYPE_USB2) + return ERR_PTR(-EBUSY); + else + return ERR_PTR(-ENODEV); + } + + if (args->args[0] == PHY_TYPE_USB2) + cluster_phy->use_usb3 = false; + else if (args->args[0] == PHY_TYPE_USB3) + cluster_phy->use_usb3 = true; + else { + dev_err(dev, "Invalid PHY mode\n"); + return ERR_PTR(-ENODEV); + } + + /* Store which phy mode is used for next test */ + cluster_phy->phy_provided = args->args[0]; + + return cluster_phy->phy; +} + +static int armada375_usb_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct phy *phy; + struct phy_provider *phy_provider; + void __iomem *usb_cluster_base; + struct resource *res; + struct armada375_cluster_phy *cluster_phy; + + cluster_phy = devm_kzalloc(dev, sizeof(*cluster_phy), GFP_KERNEL); + if (!cluster_phy) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); + if (!usb_cluster_base) + return -ENOMEM; + + phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create PHY\n"); + return PTR_ERR(phy); + } + + cluster_phy->phy = phy; + cluster_phy->reg = usb_cluster_base; + + dev_set_drvdata(dev, cluster_phy); + + phy_provider = devm_of_phy_provider_register(&pdev->dev, + armada375_usb_phy_xlate); + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id of_usb_cluster_table[] = { + { .compatible = "marvell,armada-375-usb-cluster", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, of_usb_cluster_table); + +static struct platform_driver armada375_usb_phy_driver = { + .probe = armada375_usb_phy_probe, + .driver = { + .of_match_table = of_usb_cluster_table, + .name = "armada-375-usb-cluster", + .owner = THIS_MODULE, + } +}; +module_platform_driver(armada375_usb_phy_driver); + +MODULE_DESCRIPTION("Armada 375 USB cluster driver"); +MODULE_AUTHOR("Gregory CLEMENT "); +MODULE_LICENSE("GPL"); diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h index e8c6a3f04b85..6c901930eb3e 100644 --- a/include/dt-bindings/phy/phy.h +++ b/include/dt-bindings/phy/phy.h @@ -10,6 +10,7 @@ #ifndef _DT_BINDINGS_PHY #define _DT_BINDINGS_PHY +#define PHY_NONE 0 #define PHY_TYPE_SATA 1 #define PHY_TYPE_PCIE 2 #define PHY_TYPE_USB2 3 -- GitLab From 5572a95b4b5768187652a346356e39e7542ca6e0 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 24 Nov 2014 16:22:10 +0200 Subject: [PATCH 6561/9457] ath10k: apply chainmask settings to vdev on creation It appears it takes more than just setting the hardware's chainmask to make things work well. Without this patch, a vdev would only use 1x1 rates when chainmask was set to 0x3. Setting the 'nss' (number of spatial streams) on the vdev helps the firmware's rate-control algorithm work properly. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1245ac8c5c6f..7df23794ecd5 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2414,12 +2414,28 @@ static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) return 0; } +static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg) +{ + /* It is not clear that allowing gaps in chainmask + * is helpful. Probably it will not do what user + * is hoping for, so warn in that case. + */ + if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0) + return; + + ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n", + dbg, cm); +} + static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) { int ret; lockdep_assert_held(&ar->conf_mutex); + ath10k_check_chain_mask(ar, tx_ant, "tx"); + ath10k_check_chain_mask(ar, rx_ant, "rx"); + ar->cfg_tx_chainmask = tx_ant; ar->cfg_rx_chainmask = rx_ant; @@ -2782,6 +2798,17 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) return ret; } +static u32 get_nss_from_chainmask(u16 chain_mask) +{ + if ((chain_mask & 0x15) == 0x15) + return 4; + else if ((chain_mask & 0x7) == 0x7) + return 3; + else if ((chain_mask & 0x3) == 0x3) + return 2; + return 1; +} + /* * TODO: * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE, @@ -2914,6 +2941,20 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, goto err_vdev_delete; } + if (ar->cfg_tx_chainmask) { + u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask); + + vdev_param = ar->wmi.vdev_param->nss; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + nss); + if (ret) { + ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n", + arvif->vdev_id, ar->cfg_tx_chainmask, nss, + ret); + goto err_vdev_delete; + } + } + if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr); if (ret) { -- GitLab From b116ea190be57f44c95f511d2ee7afb814c1d288 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 24 Nov 2014 16:22:10 +0200 Subject: [PATCH 6562/9457] ath10k: use configured nss instead of max nss When re-associating a station, the nss was set back to maximum value even if user had configured small number of tx chains. So, pay attention to user's config in this case as well. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 7df23794ecd5..21931e147fff 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4147,6 +4147,10 @@ ath10k_default_bitrate_mask(struct ath10k *ar, u32 legacy = 0x00ff; u8 ht = 0xff, i; u16 vht = 0x3ff; + u16 nrf = ar->num_rf_chains; + + if (ar->cfg_tx_chainmask) + nrf = get_nss_from_chainmask(ar->cfg_tx_chainmask); switch (band) { case IEEE80211_BAND_2GHZ: @@ -4162,11 +4166,11 @@ ath10k_default_bitrate_mask(struct ath10k *ar, if (mask->control[band].legacy != legacy) return false; - for (i = 0; i < ar->num_rf_chains; i++) + for (i = 0; i < nrf; i++) if (mask->control[band].ht_mcs[i] != ht) return false; - for (i = 0; i < ar->num_rf_chains; i++) + for (i = 0; i < nrf; i++) if (mask->control[band].vht_mcs[i] != vht) return false; @@ -4417,6 +4421,9 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw, u8 fixed_nss = ar->num_rf_chains; u8 force_sgi; + if (ar->cfg_tx_chainmask) + fixed_nss = get_nss_from_chainmask(ar->cfg_tx_chainmask); + force_sgi = mask->control[band].gi; if (force_sgi == NL80211_TXRATE_FORCE_LGI) return -EINVAL; -- GitLab From dbdcc2620b627072657bd8df4422d11ae3aa056b Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 24 Nov 2014 15:04:46 +0100 Subject: [PATCH 6563/9457] ath10k: remove extra_tx_headroom Comment was out-of-date. The headroom is no longer necessary because HTT Tx fragment list is stored in dma pool item associated with each sk_buff. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 21931e147fff..9ca22cb3b0ab 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4953,10 +4953,6 @@ int ath10k_mac_register(struct ath10k *ar) IEEE80211_HW_AP_LINK_PS | IEEE80211_HW_SPECTRUM_MGMT; - /* MSDU can have HTT TX fragment pushed in front. The additional 4 - * bytes is used for padding/alignment if necessary. */ - ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; - ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) -- GitLab From 8d6d36243610e42bc005ca7f5a81d8385050677e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 24 Nov 2014 14:58:31 +0100 Subject: [PATCH 6564/9457] ath10k: fix offchan reliability New firmware revisions don't need peer creation when doing offchannel tx. Earlier revisions would queue and never release frames without a peer. This prevent new firmware revisions from stopping replenishing wmi-htc tx credits and improves reliability of offchannel tx which would sometimes silently fail. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/htt.h | 4 +++- drivers/net/wireless/ath/ath10k/htt_tx.c | 7 +++--- drivers/net/wireless/ath/ath10k/mac.c | 29 +++++++++++++++++++----- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 8f86bd34e823..c5107854a8f6 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -83,6 +83,7 @@ struct ath10k_skb_cb { struct { u8 tid; + u16 freq; bool is_offchan; struct ath10k_htt_txbuf *txbuf; u32 txbuf_paddr; diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 15c58e884b6a..17ca6acbe1c1 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -126,6 +126,7 @@ enum htt_data_tx_ext_tid { * (HL hosts manage queues on the host ) * more_in_batch: only for HL hosts. indicates if more packets are * pending. this allows target to wait and aggregate + * freq: 0 means home channel of given vdev. intended for offchannel */ struct htt_data_tx_desc { u8 flags0; /* %HTT_DATA_TX_DESC_FLAGS0_ */ @@ -133,7 +134,8 @@ struct htt_data_tx_desc { __le16 len; __le16 id; __le32 frags_paddr; - __le32 peerid; + __le16 peerid; + __le16 freq; u8 prefetch[0]; /* start of frame, for FW classification engine */ } __packed; diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 5b7e42f7377c..4bc51d8a14a3 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -554,13 +554,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len); skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id); skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); - skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); + skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID); + skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq); trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid); ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", + "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n", flags0, flags1, msdu->len, msdu_id, frags_paddr, - (u32)skb_cb->paddr, vdev_id, tid); + (u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq); ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", msdu->data, msdu->len); trace_ath10k_tx_hdr(ar, msdu->data, msdu->len); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 9ca22cb3b0ab..c012c75507d5 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1997,6 +1997,18 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, } } +static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar) +{ + /* FIXME: Not really sure since when the behaviour changed. At some + * point new firmware stopped requiring creation of peer entries for + * offchannel tx (and actually creating them causes issues with wmi-htc + * tx credit replenishment and reliability). Assuming it's at least 3.4 + * because that's when the `freq` was introduced to TX_FRM HTT command. + */ + return !(ar->htt.target_version_major >= 3 && + ar->htt.target_version_minor >= 4); +} + static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -2341,16 +2353,21 @@ static void ath10k_tx(struct ieee80211_hw *hw, if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { spin_lock_bh(&ar->data_lock); - ATH10K_SKB_CB(skb)->htt.is_offchan = true; + ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq; ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id; spin_unlock_bh(&ar->data_lock); - ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n", - skb); + if (ath10k_mac_need_offchan_tx_work(ar)) { + ATH10K_SKB_CB(skb)->htt.freq = 0; + ATH10K_SKB_CB(skb)->htt.is_offchan = true; - skb_queue_tail(&ar->offchan_tx_queue, skb); - ieee80211_queue_work(hw, &ar->offchan_tx_work); - return; + ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n", + skb); + + skb_queue_tail(&ar->offchan_tx_queue, skb); + ieee80211_queue_work(hw, &ar->offchan_tx_work); + return; + } } ath10k_tx_htt(ar, skb); -- GitLab From dcca0bdb48f94a09ac66f4bc42d1023086fc0d6f Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 24 Nov 2014 14:58:32 +0100 Subject: [PATCH 6565/9457] ath10k: make hw roc more reliable With P2P concurrency requested hw roc duration time can be very small. Some firmware revisions refuse scan requests with too small channel dwell time. This prevents messages like, e.g. with connected STA vif and performing P2P Find: ath10k_pci 0000:00:05.0: failed to switch to channel for roc scan ieee80211 phy3: failed to start next HW ROC (-110) Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 2 ++ drivers/net/wireless/ath/ath10k/wmi.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c012c75507d5..770d2b59d734 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3848,6 +3848,8 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, if (ret) goto exit; + duration = max(duration, WMI_SCAN_CHAN_MIN_TIME_MSEC); + memset(&arg, 0, sizeof(arg)); ath10k_wmi_start_scan_init(ar, &arg); arg.vdev_id = arvif->vdev_id; diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index a38d788a6101..1b7141a6c030 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -1952,6 +1952,11 @@ struct wmi_ssid_list { #define WLAN_SCAN_PARAMS_MAX_BSSID 4 #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 +/* Values lower than this may be refused by some firmware revisions with a scan + * completion with a timedout reason. + */ +#define WMI_SCAN_CHAN_MIN_TIME_MSEC 40 + /* Scan priority numbers must be sequential, starting with 0 */ enum wmi_scan_priority { WMI_SCAN_PRIORITY_VERY_LOW = 0, -- GitLab From 7305d3e02da0ba62298d08b2883a537174a6b595 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 24 Nov 2014 14:58:33 +0100 Subject: [PATCH 6566/9457] ath10k: fix offchannel cancel failures When mac80211 requests driver to cancel a hw roc the driver must not call the expired() callback or else roc will fail in some cases depending on how things get scheduled. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 770d2b59d734..8d07f77e34de 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2184,10 +2184,10 @@ void __ath10k_scan_finish(struct ath10k *ar) case ATH10K_SCAN_IDLE: break; case ATH10K_SCAN_RUNNING: - case ATH10K_SCAN_ABORTING: if (ar->scan.is_roc) ieee80211_remain_on_channel_expired(ar->hw); - else + case ATH10K_SCAN_ABORTING: + if (!ar->scan.is_roc) ieee80211_scan_completed(ar->hw, (ar->scan.state == ATH10K_SCAN_ABORTING)); -- GitLab From d67d0a02042867491051f766a3ad8389f5b307c2 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 24 Nov 2014 15:34:08 +0100 Subject: [PATCH 6567/9457] ath10k: don't drop corrupted mgmt frames Some firmware revisions don't seem to deilver management frames with FCS error via WMI so narrow down the HTT rule to not drop corrupted management frames. This basically increases number of frames ath10k reports while sniffing. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 13 +++++++++++-- drivers/net/wireless/ath/ath10k/wmi.c | 7 +++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 75b229345beb..85910b2a2373 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1381,6 +1381,8 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, { struct sk_buff *msdu; struct htt_rx_desc *rxd; + bool is_mgmt; + bool has_fcs_err; msdu = skb_peek(amsdu); rxd = (void *)msdu->data - sizeof(*rxd); @@ -1394,12 +1396,19 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, return false; } + is_mgmt = !!(rxd->attention.flags & + __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE)); + has_fcs_err = !!(rxd->attention.flags & + __cpu_to_le32(RX_ATTENTION_FLAGS_FCS_ERR)); + /* Management frames are handled via WMI events. The pros of such * approach is that channel is explicitly provided in WMI events * whereas HTT doesn't provide channel information for Rxed frames. + * + * However some firmware revisions don't report corrupted frames via + * WMI so don't drop them. */ - if (rxd->attention.flags & - __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE)) { + if (is_mgmt && !has_fcs_err) { ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); return false; } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c300a53ed6b0..cd1e5e546a24 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1166,8 +1166,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) return 0; } - if (rx_status & WMI_RX_STATUS_ERR_CRC) - status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (rx_status & WMI_RX_STATUS_ERR_CRC) { + dev_kfree_skb(skb); + return 0; + } + if (rx_status & WMI_RX_STATUS_ERR_MIC) status->flag |= RX_FLAG_MMIC_ERROR; -- GitLab From 504f6cdf4ac3dfcf645453b5cd65dcc9aed0e1b9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 25 Nov 2014 11:46:58 +0530 Subject: [PATCH 6568/9457] ath10k: fix shared WEP When static keys are used in shared WEP, when a station is associated, message 3 is sent with an encrypted payload. But, for subsequent authentications that are triggered without a deauth, the auth frame is decrypted by the HW. To handle this, check if the WEP keys have already been set for the peer and if so, mark the frame as decrypted. This scenario can happen when a station changes its default TX key and initiates a new authentication sequence. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 25 +++++++++++++++++++ drivers/net/wireless/ath/ath10k/mac.h | 4 +++ drivers/net/wireless/ath/ath10k/wmi.c | 36 +++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 8d07f77e34de..c6c09c1d421e 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -179,6 +179,31 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, return first_errno; } +bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, + u8 keyidx) +{ + struct ath10k_peer *peer; + int i; + + lockdep_assert_held(&ar->data_lock); + + /* We don't know which vdev this peer belongs to, + * since WMI doesn't give us that information. + * + * FIXME: multi-bss needs to be handled. + */ + peer = ath10k_peer_find(ar, 0, addr); + if (!peer) + return false; + + for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { + if (peer->keys[i] && peer->keys[i]->keyidx == keyidx) + return true; + } + + return false; +} + static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, struct ieee80211_key_conf *key) { diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index 4e3c989aa841..68296117d203 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -21,6 +21,8 @@ #include #include "core.h" +#define WEP_KEYID_SHIFT 6 + struct ath10k_generic_iter { struct ath10k *ar; int ret; @@ -41,6 +43,8 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_halt(struct ath10k *ar); void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif); void ath10k_drain_tx(struct ath10k *ar); +bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, + u8 keyidx); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index cd1e5e546a24..7dd7c78ec195 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1113,6 +1113,40 @@ static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band) return rate_idx; } +/* If keys are configured, HW decrypts all frames + * with protected bit set. Mark such frames as decrypted. + */ +static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar, + struct sk_buff *skb, + struct ieee80211_rx_status *status) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + unsigned int hdrlen; + bool peer_key; + u8 *addr, keyidx; + + if (!ieee80211_is_auth(hdr->frame_control) || + !ieee80211_has_protected(hdr->frame_control)) + return; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + if (skb->len < (hdrlen + IEEE80211_WEP_IV_LEN)) + return; + + keyidx = skb->data[hdrlen + (IEEE80211_WEP_IV_LEN - 1)] >> WEP_KEYID_SHIFT; + addr = ieee80211_get_SA(hdr); + + spin_lock_bh(&ar->data_lock); + peer_key = ath10k_mac_is_peer_wep_key_set(ar, addr, keyidx); + spin_unlock_bh(&ar->data_lock); + + if (peer_key) { + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac wep key present for peer %pM\n", addr); + status->flag |= RX_FLAG_DECRYPTED; + } +} + static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_mgmt_rx_event_v1 *ev_v1; @@ -1203,6 +1237,8 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); + ath10k_wmi_handle_wep_reauth(ar, skb, status); + /* FW delivers WEP Shared Auth frame with Protected Bit set and * encrypted payload. However in case of PMF it delivers decrypted * frames with Protected Bit set. */ -- GitLab From ae1671318e602860970c7020f3b23f2349dda757 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 25 Nov 2014 11:46:59 +0530 Subject: [PATCH 6569/9457] ath10k: fix locking for WEP keys peer->keys needs to be protected by data_lock since it is also accessed from the WMI path. Both install() and clear() routines for peer keys modify the key contents, so use the data_lock to avoid races. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 ++ drivers/net/wireless/ath/ath10k/mac.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index c5107854a8f6..90775a5358b8 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -219,6 +219,8 @@ struct ath10k_peer { int vdev_id; u8 addr[ETH_ALEN]; DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS); + + /* protected by ar->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; }; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c6c09c1d421e..d5aaaa0b9e15 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -136,7 +136,9 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, if (ret) return ret; + spin_lock_bh(&ar->data_lock); peer->keys[i] = arvif->wep_keys[i]; + spin_unlock_bh(&ar->data_lock); } return 0; @@ -173,7 +175,9 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, ath10k_warn(ar, "failed to remove peer wep key %d: %d\n", i, ret); + spin_lock_bh(&ar->data_lock); peer->keys[i] = NULL; + spin_unlock_bh(&ar->data_lock); } return first_errno; -- GitLab From 5d011f5c1f93a9ef6955874c3607e36b32713015 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 25 Nov 2014 11:47:00 +0530 Subject: [PATCH 6570/9457] ath10k: fix bug reported by lockdep ath10k_tx_wep_key_work() acquires conf_mutex, so cancelling it when conf_mutex is already taken in ath10k_remove_interface() is incorrect, so move it outside the lock. Snippet from the lockdep report: kernel: ====================================================== kernel: [ INFO: possible circular locking dependency detected ] kernel: 3.18.0-rc5-wl-debug #34 Tainted: G O kernel: ------------------------------------------------------- kernel: hostapd/451 is trying to acquire lock: kernel: ((&arvif->wep_key_work)){+.+...}, at: [] flush_work+0x5/0x290 kernel: but task is already holding lock: kernel: (&ar->conf_mutex){+.+.+.}, at: [] ath10k_remove_interface+0x40/0x290 [ath10k_core] kernel: which lock already depends on the new lock. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index d5aaaa0b9e15..982bd48227e5 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3101,10 +3101,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); int ret; - mutex_lock(&ar->conf_mutex); - cancel_work_sync(&arvif->wep_key_work); + mutex_lock(&ar->conf_mutex); + spin_lock_bh(&ar->data_lock); ath10k_mac_vif_beacon_cleanup(arvif); spin_unlock_bh(&ar->data_lock); -- GitLab From 077a380447160d94031c51e863ca4c53d2c74730 Mon Sep 17 00:00:00 2001 From: Yanbo Li Date: Tue, 25 Nov 2014 12:24:33 +0200 Subject: [PATCH 6571/9457] ath10k: add register access debugfs interface Debugfs files reg_addr and reg_val are used for reading and writing to the firmware (target) registers. reg_addr contains the address to be accessed, which also needs to be set first, and reg_value is when used for reading and writing the actual value in ASCII. To read a value from the firmware register 0x100000: # echo 0x100000 > reg_addr # cat reg_value 0x00100000:0x000002d3 To write value 0x2400 to address 0x100000: # echo 0x100000 > reg_addr # echo 0x2400 > reg_value # Signed-off-by: Yanbo Li Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/debug.c | 125 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/hif.h | 26 +++++ drivers/net/wireless/ath/ath10k/pci.c | 2 + 4 files changed, 154 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 90775a5358b8..cd8815a35a44 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -323,6 +323,7 @@ struct ath10k_debug { /* protected by conf_mutex */ u32 fw_dbglog_mask; u32 pktlog_filter; + u32 reg_addr; u8 htt_max_amsdu; u8 htt_max_ampdu; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index f10721da4980..d0397d119862 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -928,6 +928,125 @@ static const struct file_operations fops_fw_crash_dump = { .llseek = default_llseek, }; +static ssize_t ath10k_reg_addr_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 buf[32]; + unsigned int len = 0; + u32 reg_addr; + + mutex_lock(&ar->conf_mutex); + reg_addr = ar->debug.reg_addr; + mutex_unlock(&ar->conf_mutex); + + len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath10k_reg_addr_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u32 reg_addr; + int ret; + + ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); + if (ret) + return ret; + + if (!IS_ALIGNED(reg_addr, 4)) + return -EFAULT; + + mutex_lock(&ar->conf_mutex); + ar->debug.reg_addr = reg_addr; + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static const struct file_operations fops_reg_addr = { + .read = ath10k_reg_addr_read, + .write = ath10k_reg_addr_write, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t ath10k_reg_value_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 buf[48]; + unsigned int len; + u32 reg_addr, reg_val; + int ret; + + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + reg_addr = ar->debug.reg_addr; + + reg_val = ath10k_hif_read32(ar, reg_addr); + len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + +exit: + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static ssize_t ath10k_reg_value_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u32 reg_addr, reg_val; + int ret; + + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + reg_addr = ar->debug.reg_addr; + + ret = kstrtou32_from_user(user_buf, count, 0, ®_val); + if (ret) + goto exit; + + ath10k_hif_write32(ar, reg_addr, reg_val); + + ret = count; + +exit: + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static const struct file_operations fops_reg_value = { + .read = ath10k_reg_value_read, + .write = ath10k_reg_value_write, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static int ath10k_debug_htt_stats_req(struct ath10k *ar) { u64 cookie; @@ -1629,6 +1748,12 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_fw_crash_dump); + debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_reg_addr); + + debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_reg_value); + debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_chip_id); diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h index 30301f5b6051..bad071906540 100644 --- a/drivers/net/wireless/ath/ath10k/hif.h +++ b/drivers/net/wireless/ath/ath10k/hif.h @@ -20,6 +20,7 @@ #include #include "core.h" +#include "debug.h" struct ath10k_hif_sg_item { u16 transfer_id; @@ -84,6 +85,10 @@ struct ath10k_hif_ops { u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id); + u32 (*read32)(struct ath10k *ar, u32 address); + + void (*write32)(struct ath10k *ar, u32 address, u32 value); + /* Power up the device and enter BMI transfer mode for FW download */ int (*power_up)(struct ath10k *ar); @@ -187,4 +192,25 @@ static inline int ath10k_hif_resume(struct ath10k *ar) return ar->hif.ops->resume(ar); } +static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address) +{ + if (!ar->hif.ops->read32) { + ath10k_warn(ar, "hif read32 not supported\n"); + return 0xdeaddead; + } + + return ar->hif.ops->read32(ar, address); +} + +static inline void ath10k_hif_write32(struct ath10k *ar, + u32 address, u32 data) +{ + if (!ar->hif.ops->write32) { + ath10k_warn(ar, "hif write32 not supported\n"); + return; + } + + ar->hif.ops->write32(ar, address, data); +} + #endif /* _HIF_H_ */ diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 3a6b8a5ca96c..328ab6c5d053 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1998,6 +1998,8 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = { .get_free_queue_number = ath10k_pci_hif_get_free_queue_number, .power_up = ath10k_pci_hif_power_up, .power_down = ath10k_pci_hif_power_down, + .read32 = ath10k_pci_read32, + .write32 = ath10k_pci_write32, #ifdef CONFIG_PM .suspend = ath10k_pci_hif_suspend, .resume = ath10k_pci_hif_resume, -- GitLab From 9f65ad25b0ac725286250191d86b3238313fa55d Mon Sep 17 00:00:00 2001 From: Yanbo Li Date: Tue, 25 Nov 2014 12:24:48 +0200 Subject: [PATCH 6572/9457] ath10k: add memory dump debugfs interface Add mem_val debugfs file for dumping the firmware (target) memory and also for writing to the memory. The firmware memory is accessed through one file which uses position of the file as the firmware memory address. For example, with dd use skip parameter for the address. Beucase target memory width is 32 bits it's strongly recommended to use blocksize divisable with 4 when using this interface. For example, when using dd use bs=4 to set the block size to 4 and remember to divide both count and skip values with four. To read 4 kB chunk from address 0x400000: dd if=mem_value bs=4 count=1024 skip=1048576 | xxd -g1 To write value 0x01020304 to address 0x400400: echo 0x01020304 | xxd -r | dd of=mem_value bs=4 seek=1048832 To read 4 KB chunk of memory and then write back after edit: dd if=mem_value of=tmp.bin bs=4 count=1024 skip=1048576 emacs tmp.bin dd if=tmp.bin of=mem_value bs=4 count=1024 seek=1048576 Signed-off-by: Yanbo Li Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 114 ++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/hif.h | 11 +++ drivers/net/wireless/ath/ath10k/pci.c | 1 + 3 files changed, 126 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index d0397d119862..ff831ca507f7 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1047,6 +1047,117 @@ static const struct file_operations fops_reg_value = { .llseek = default_llseek, }; +static ssize_t ath10k_mem_value_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 *buf; + int ret; + + if (*ppos < 0) + return -EINVAL; + + if (!count) + return 0; + + mutex_lock(&ar->conf_mutex); + + buf = vmalloc(count); + if (!buf) { + ret = -ENOMEM; + goto exit; + } + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + ret = ath10k_hif_diag_read(ar, *ppos, buf, count); + if (ret) { + ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", + (u32)(*ppos), ret); + goto exit; + } + + ret = copy_to_user(user_buf, buf, count); + if (ret) { + ret = -EFAULT; + goto exit; + } + + count -= ret; + *ppos += count; + ret = count; + +exit: + vfree(buf); + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static ssize_t ath10k_mem_value_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u8 *buf; + int ret; + + if (*ppos < 0) + return -EINVAL; + + if (!count) + return 0; + + mutex_lock(&ar->conf_mutex); + + buf = vmalloc(count); + if (!buf) { + ret = -ENOMEM; + goto exit; + } + + if (ar->state != ATH10K_STATE_ON && + ar->state != ATH10K_STATE_UTF) { + ret = -ENETDOWN; + goto exit; + } + + ret = copy_from_user(buf, user_buf, count); + if (ret) { + ret = -EFAULT; + goto exit; + } + + ret = ath10k_hif_diag_write(ar, *ppos, buf, count); + if (ret) { + ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", + (u32)(*ppos), ret); + goto exit; + } + + *ppos += count; + ret = count; + +exit: + vfree(buf); + mutex_unlock(&ar->conf_mutex); + + return ret; +} + +static const struct file_operations fops_mem_value = { + .read = ath10k_mem_value_read, + .write = ath10k_mem_value_write, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static int ath10k_debug_htt_stats_req(struct ath10k *ar) { u64 cookie; @@ -1754,6 +1865,9 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_reg_value); + debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_mem_value); + debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_chip_id); diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h index bad071906540..6ac552304546 100644 --- a/drivers/net/wireless/ath/ath10k/hif.h +++ b/drivers/net/wireless/ath/ath10k/hif.h @@ -48,6 +48,8 @@ struct ath10k_hif_ops { int (*diag_read)(struct ath10k *ar, u32 address, void *buf, size_t buf_len); + int (*diag_write)(struct ath10k *ar, u32 address, const void *data, + int nbytes); /* * API to handle HIF-specific BMI message exchanges, this API is * synchronous and only allowed to be called from a context that @@ -113,6 +115,15 @@ static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf return ar->hif.ops->diag_read(ar, address, buf, buf_len); } +static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address, + const void *data, int nbytes) +{ + if (!ar->hif.ops->diag_write) + return -EOPNOTSUPP; + + return ar->hif.ops->diag_write(ar, address, data, nbytes); +} + static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, void *request, u32 request_len, void *response, u32 *response_len) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 328ab6c5d053..0816098af578 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1988,6 +1988,7 @@ static int ath10k_pci_hif_resume(struct ath10k *ar) static const struct ath10k_hif_ops ath10k_pci_hif_ops = { .tx_sg = ath10k_pci_hif_tx_sg, .diag_read = ath10k_pci_hif_diag_read, + .diag_write = ath10k_pci_diag_write_mem, .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, .start = ath10k_pci_hif_start, .stop = ath10k_pci_hif_stop, -- GitLab From a52c0282721e8e2a39679f865dc5ec72005a948f Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 25 Nov 2014 15:16:03 +0100 Subject: [PATCH 6573/9457] ath10k: add missing goto This prevents warning spamming if peer creation fails during sta_state in some cases. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 982bd48227e5..f364b845d991 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3646,9 +3646,11 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, arvif->vdev_id, sta->addr, ar->num_peers); ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); - if (ret) + if (ret) { ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n", sta->addr, arvif->vdev_id, ret); + goto exit; + } if (vif->type == NL80211_IFTYPE_STATION) { WARN_ON(arvif->is_started); -- GitLab From 775a9134f4398ca98a10af8cc3cf9b664017267f Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 19 Nov 2014 14:22:23 +0200 Subject: [PATCH 6574/9457] mtd: nand: omap: Fix NAND enumeration on 3430 LDP 3430LDP has NAND flash with 32 bytes OOB size which is sufficient to hold BCH8 codes but the small page check introduced in commit b491da7233d5 ("mtd: nand: omap: clean-up ecc layout for BCH ecc schemes") considers anything below 64 bytes unsuitable for BCH4/8/16. There is another bug in that code where it doesn't skip the check for OMAP_ECC_HAM1_CODE_SW. Get rid of that small page check code as it is insufficient and redundant because we are checking for OOB available bytes vs ecc layout before calling nand_scan_tail(). Fixes: b491da7233d5 ("mtd: nand: omap: clean-up ecc layout for BCH ecc schemes") Reported-by: Tony Lindgren Signed-off-by: Roger Quadros Signed-off-by: Brian Norris --- drivers/mtd/nand/omap2.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1ec0a1dbed3d..80250ad7d061 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -1742,13 +1742,6 @@ static int omap_nand_probe(struct platform_device *pdev) goto return_error; } - /* check for small page devices */ - if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) { - dev_err(&info->pdev->dev, "small page devices are not supported\n"); - err = -EINVAL; - goto return_error; - } - /* re-populate low-level callbacks based on xfer modes */ switch (pdata->xfer_type) { case NAND_OMAP_PREFETCH_POLLED: -- GitLab From 292a753d4b184ba6303d026edfe4e34145ce6905 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 25 Nov 2014 15:16:04 +0100 Subject: [PATCH 6575/9457] ath10k: clean up num_peers locking The var was supposed to be protected by data_lock but it wasn't so in all instances. It's actually not necessary to have a spinlock protected num_peers so drop it. All instances of num_peers are already within conf_mutex sections so use that. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index cd8815a35a44..0a0182107dc9 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -564,7 +564,7 @@ struct ath10k { struct list_head peers; wait_queue_head_t peer_mapping_wq; - /* number of created peers; protected by data_lock */ + /* protected by conf_mutex */ int num_peers; struct work_struct offchan_tx_work; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f364b845d991..bb138ceca2b9 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -368,9 +368,8 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) addr, vdev_id, ret); return ret; } - spin_lock_bh(&ar->data_lock); + ar->num_peers++; - spin_unlock_bh(&ar->data_lock); return 0; } @@ -461,9 +460,7 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) if (ret) return ret; - spin_lock_bh(&ar->data_lock); ar->num_peers--; - spin_unlock_bh(&ar->data_lock); return 0; } @@ -500,8 +497,9 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) list_del(&peer->list); kfree(peer); } - ar->num_peers = 0; spin_unlock_bh(&ar->data_lock); + + ar->num_peers = 0; } /************************/ -- GitLab From 05a221bb1f49e6eebc9a3858cb45506f403b3ab6 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 20 Nov 2014 13:50:43 +0100 Subject: [PATCH 6576/9457] mtd: delete unnecessary checks before two function calls The functions kfree() and pci_dev_put() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0001.c | 3 +-- drivers/mtd/devices/pmc551.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 3096f3ded3ad..286b97a304cf 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2654,8 +2654,7 @@ static void cfi_intelext_destroy(struct mtd_info *mtd) kfree(cfi); for (i = 0; i < mtd->numeraseregions; i++) { region = &mtd->eraseregions[i]; - if (region->lockmap) - kfree(region->lockmap); + kfree(region->lockmap); } kfree(mtd->eraseregions); } diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index f02603e1bfeb..708b7e8c8b18 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -812,8 +812,7 @@ static int __init init_pmc551(void) } /* Exited early, reference left over */ - if (PCI_Device) - pci_dev_put(PCI_Device); + pci_dev_put(PCI_Device); if (!pmc551list) { printk(KERN_NOTICE "pmc551: not detected\n"); -- GitLab From cfd1061e9b52407175c94bbc4214fa0d5c3fe2e9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 25 Nov 2014 15:16:05 +0100 Subject: [PATCH 6577/9457] ath10k: fix station count enforcement The number of peers isn't directly translatable to the number of stations because ath10k needs to reserve a few extra peers for special cases like multi-vif concurrency. The previous limit was 126 and 15 stations in AP mode for 10.x and main firmware branches respectively. The limit is now 128 and 16 which was the original intention. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 13 ++++++ drivers/net/wireless/ath/ath10k/core.h | 4 ++ drivers/net/wireless/ath/ath10k/debug.c | 5 ++- drivers/net/wireless/ath/ath10k/hw.h | 15 ++++--- drivers/net/wireless/ath/ath10k/mac.c | 60 +++++++++++++++++++------ drivers/net/wireless/ath/ath10k/wmi.c | 2 +- 6 files changed, 78 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index f660553c6c48..7762061a1944 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -799,6 +799,17 @@ static void ath10k_core_restart(struct work_struct *work) mutex_unlock(&ar->conf_mutex); } +static void ath10k_core_init_max_sta_count(struct ath10k *ar) +{ + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + ar->max_num_peers = TARGET_10X_NUM_PEERS; + ar->max_num_stations = TARGET_10X_NUM_STATIONS; + } else { + ar->max_num_peers = TARGET_NUM_PEERS; + ar->max_num_stations = TARGET_NUM_STATIONS; + } +} + int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) { int status; @@ -1035,6 +1046,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar) return ret; } + ath10k_core_init_max_sta_count(ar); + mutex_lock(&ar->conf_mutex); ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 0a0182107dc9..4a294987736c 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -566,6 +566,10 @@ struct ath10k { /* protected by conf_mutex */ int num_peers; + int num_stations; + + int max_num_peers; + int max_num_stations; struct work_struct offchan_tx_work; struct sk_buff_head offchan_tx_queue; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index ff831ca507f7..c096d00aab97 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -123,7 +123,7 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { - ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s\n", + ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n", ar->hw_params.name, ar->target_version, ar->chip_id, @@ -135,7 +135,8 @@ void ath10k_print_driver_info(struct ath10k *ar) ar->fw_version_minor, ar->fw_version_release, ar->fw_version_build, - ath10k_cal_mode_str(ar->cal_mode)); + ath10k_cal_mode_str(ar->cal_mode), + ar->max_num_stations); ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", config_enabled(CONFIG_ATH10K_DEBUG), config_enabled(CONFIG_ATH10K_DEBUGFS), diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 392c2501d0a1..dfedfd0e0f34 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -97,11 +97,13 @@ struct ath10k_pktlog_hdr { #define TARGET_DMA_BURST_SIZE 0 #define TARGET_MAC_AGGR_DELIM 0 #define TARGET_AST_SKID_LIMIT 16 -#define TARGET_NUM_PEERS 16 +#define TARGET_NUM_STATIONS 16 +#define TARGET_NUM_PEERS ((TARGET_NUM_STATIONS) + \ + (TARGET_NUM_VDEVS)) #define TARGET_NUM_OFFLOAD_PEERS 0 #define TARGET_NUM_OFFLOAD_REORDER_BUFS 0 #define TARGET_NUM_PEER_KEYS 2 -#define TARGET_NUM_TIDS (2 * ((TARGET_NUM_PEERS) + (TARGET_NUM_VDEVS))) +#define TARGET_NUM_TIDS ((TARGET_NUM_PEERS) * 2) #define TARGET_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) #define TARGET_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) #define TARGET_RX_TIMEOUT_LO_PRI 100 @@ -132,12 +134,15 @@ struct ath10k_pktlog_hdr { #define TARGET_10X_DMA_BURST_SIZE 0 #define TARGET_10X_MAC_AGGR_DELIM 0 #define TARGET_10X_AST_SKID_LIMIT 16 -#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) -#define TARGET_10X_NUM_PEERS_MAX 128 +#define TARGET_10X_NUM_STATIONS 128 +#define TARGET_10X_NUM_PEERS ((TARGET_10X_NUM_STATIONS) + \ + (TARGET_10X_NUM_VDEVS)) #define TARGET_10X_NUM_OFFLOAD_PEERS 0 #define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 #define TARGET_10X_NUM_PEER_KEYS 2 -#define TARGET_10X_NUM_TIDS 256 +#define TARGET_10X_NUM_TIDS_MAX 256 +#define TARGET_10X_NUM_TIDS min((TARGET_10X_NUM_TIDS_MAX), \ + (TARGET_10X_NUM_PEERS) * 2) #define TARGET_10X_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) #define TARGET_10X_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) #define TARGET_10X_RX_TIMEOUT_LO_PRI 100 diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index bb138ceca2b9..e475cc4095b6 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -355,6 +355,9 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) lockdep_assert_held(&ar->conf_mutex); + if (ar->num_peers >= ar->max_num_peers) + return -ENOBUFS; + ret = ath10k_wmi_peer_create(ar, vdev_id, addr); if (ret) { ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n", @@ -500,6 +503,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar) spin_unlock_bh(&ar->data_lock); ar->num_peers = 0; + ar->num_stations = 0; } /************************/ @@ -3596,6 +3600,37 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) mutex_unlock(&ar->conf_mutex); } +static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif) +{ + struct ath10k *ar = arvif->ar; + + lockdep_assert_held(&ar->conf_mutex); + + if (arvif->vdev_type != WMI_VDEV_TYPE_AP && + arvif->vdev_type != WMI_VDEV_TYPE_IBSS) + return 0; + + if (ar->num_stations >= ar->max_num_stations) + return -ENOBUFS; + + ar->num_stations++; + + return 0; +} + +static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif) +{ + struct ath10k *ar = arvif->ar; + + lockdep_assert_held(&ar->conf_mutex); + + if (arvif->vdev_type != WMI_VDEV_TYPE_AP && + arvif->vdev_type != WMI_VDEV_TYPE_IBSS) + return; + + ar->num_stations--; +} + static int ath10k_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -3605,7 +3640,6 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; - int max_num_peers; int ret = 0; if (old_state == IEEE80211_STA_NOTEXIST && @@ -3627,26 +3661,24 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, /* * New station addition. */ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1; - else - max_num_peers = TARGET_NUM_PEERS; + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n", + arvif->vdev_id, sta->addr, + ar->num_stations + 1, ar->max_num_stations, + ar->num_peers + 1, ar->max_num_peers); - if (ar->num_peers >= max_num_peers) { - ath10k_warn(ar, "number of peers exceeded: peers number %d (max peers %d)\n", - ar->num_peers, max_num_peers); - ret = -ENOBUFS; + ret = ath10k_mac_inc_num_stations(arvif); + if (ret) { + ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n", + ar->max_num_stations); goto exit; } - ath10k_dbg(ar, ATH10K_DBG_MAC, - "mac vdev %d peer create %pM (new sta) num_peers %d\n", - arvif->vdev_id, sta->addr, ar->num_peers); - ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); if (ret) { ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n", sta->addr, arvif->vdev_id, ret); + ath10k_mac_dec_num_stations(arvif); goto exit; } @@ -3659,6 +3691,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, arvif->vdev_id, ret); WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id, sta->addr)); + ath10k_mac_dec_num_stations(arvif); goto exit; } @@ -3689,6 +3722,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", sta->addr, arvif->vdev_id, ret); + ath10k_mac_dec_num_stations(arvif); } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 7dd7c78ec195..23fee9a0530a 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3181,7 +3181,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) u32 len, val; config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); - config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS); + config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS); config.num_offload_peers = __cpu_to_le32(TARGET_NUM_OFFLOAD_PEERS); config.num_offload_reorder_bufs = -- GitLab From a95ce92e4b289228c51114dd19f714388093d52b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 5 Nov 2014 02:32:03 -0800 Subject: [PATCH 6578/9457] mtd: spi-nor: improve wait-till-ready timeout loop There are a few small issues with the timeout loop in spi_nor_wait_till_ready(): * The first operation should not be a reschedule; we should check the status register at least once to see if we're complete! * We should check the status register one last time after declaring the deadline has passed, to prevent a premature timeout error (this is theoretically possible if we sleep for a long time after the previous status register check). * Add an error message, so it's obvious if we ever hit a timeout. Signed-off-by: Brian Norris Acked-by: Huang Shijie Reviewed-by: Ezequiel Garcia --- drivers/mtd/spi-nor/spi-nor.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index eafaeeb2e580..2bda622d4621 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -202,19 +202,24 @@ static int spi_nor_ready(struct spi_nor *nor) static int spi_nor_wait_till_ready(struct spi_nor *nor) { unsigned long deadline; - int ret; + int timeout = 0, ret; deadline = jiffies + MAX_READY_WAIT_JIFFIES; - do { - cond_resched(); + while (!timeout) { + if (time_after_eq(jiffies, deadline)) + timeout = 1; ret = spi_nor_ready(nor); if (ret < 0) return ret; if (ret) return 0; - } while (!time_after_eq(jiffies, deadline)); + + cond_resched(); + } + + dev_err(nor->dev, "flash operation timed out\n"); return -ETIMEDOUT; } -- GitLab From 834b686552d9018e2d17bd56ac5361b78bcc75b8 Mon Sep 17 00:00:00 2001 From: Alison Chaiken Date: Mon, 10 Nov 2014 16:54:54 +0100 Subject: [PATCH 6579/9457] MTD: m25p80: fix inconsistency in m25p_ids compared to spi_nor_ids As stated in a5b7616c5, "mtd: m25p80,spi-nor: Fix module aliases for m25p80", m25p_ids[] in m25p80.c needs to be kept in sync with spi_nor_ids[] in spi-nor.c. The change here corrects a misalignment. (We were missing m25px80 and we had a duplicate w25q128.) Signed-off-by: Alison Chaiken Signed-off-by: Brian Norris Cc: # 3.18+ --- drivers/mtd/devices/m25p80.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 35e7e9896b17..363590d5234b 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -292,11 +292,11 @@ static const struct spi_device_id m25p_ids[] = { {"m45pe10"}, {"m45pe80"}, {"m45pe16"}, {"m25pe20"}, {"m25pe80"}, {"m25pe16"}, {"m25px16"}, {"m25px32"}, {"m25px32-s0"}, {"m25px32-s1"}, - {"m25px64"}, + {"m25px64"}, {"m25px80"}, {"w25x10"}, {"w25x20"}, {"w25x40"}, {"w25x80"}, {"w25x16"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"}, - {"w25x64"}, {"w25q64"}, {"w25q128"}, {"w25q80"}, - {"w25q80bl"}, {"w25q128"}, {"w25q256"}, {"cat25c11"}, + {"w25x64"}, {"w25q64"}, {"w25q80"}, {"w25q80bl"}, + {"w25q128"}, {"w25q256"}, {"cat25c11"}, {"cat25c03"}, {"cat25c09"}, {"cat25c17"}, {"cat25128"}, { }, }; -- GitLab From 3e38933dd894b48d422113cb26fd3510fd2a80bd Mon Sep 17 00:00:00 2001 From: Knut Wohlrab Date: Mon, 10 Nov 2014 16:54:53 +0100 Subject: [PATCH 6580/9457] mtd: m25p80: Add support for serial flash Spansion S25FL132K Signed-off-by: Knut Wohlrab Signed-off-by: Alison Chaiken Reviewed-by: Jagannadha Sutradharudu Teki Signed-off-by: Brian Norris --- drivers/mtd/devices/m25p80.c | 4 +--- drivers/mtd/spi-nor/spi-nor.c | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 363590d5234b..f5cb8d57bbd1 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -252,7 +252,6 @@ static int m25p_remove(struct spi_device *spi) return mtd_device_unregister(&flash->mtd); } - /* * XXX This needs to be kept in sync with spi_nor_ids. We can't share * it with spi-nor, because if this is built as a module then modpost @@ -279,7 +278,7 @@ static const struct spi_device_id m25p_ids[] = { {"s25fl512s"}, {"s70fl01gs"}, {"s25sl12800"}, {"s25sl12801"}, {"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"}, {"s25sl008a"}, {"s25sl016a"}, {"s25sl032a"}, {"s25sl064a"}, {"s25fl008k"}, - {"s25fl016k"}, {"s25fl064k"}, + {"s25fl016k"}, {"s25fl064k"}, {"s25fl132k"}, {"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"}, {"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"}, {"sst25wf040"}, @@ -302,7 +301,6 @@ static const struct spi_device_id m25p_ids[] = { }; MODULE_DEVICE_TABLE(spi, m25p_ids); - static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 2bda622d4621..3f2a3ccb37d5 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -564,6 +564,7 @@ static const struct spi_device_id spi_nor_ids[] = { { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) }, { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, 0) }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, -- GitLab From 6710247706bfc4e6ad22a124c097964bb713fb8d Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 10 Nov 2014 13:06:04 -0800 Subject: [PATCH 6581/9457] mtd: cafe_nand: drop duplicate .write_page implementation This write_page() function is functionally equivalent to the default in nand_base.c. Its only difference is in subpage programming support, which cafe_nand.c does not advertise, so the difference is negligible. Signed-off-by: Brian Norris --- drivers/mtd/nand/cafe_nand.c | 45 ------------------------------------ 1 file changed, 45 deletions(-) diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 4e66726da9aa..9a0f45f1d932 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -529,50 +529,6 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, return 0; } -static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, - uint32_t offset, int data_len, const uint8_t *buf, - int oob_required, int page, int cached, int raw) -{ - int status; - - chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); - - if (unlikely(raw)) - status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required); - else - status = chip->ecc.write_page(mtd, chip, buf, oob_required); - - if (status < 0) - return status; - - /* - * Cached progamming disabled for now, Not sure if its worth the - * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s) - */ - cached = 0; - - if (!cached || !(chip->options & NAND_CACHEPRG)) { - - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); - status = chip->waitfunc(mtd, chip); - /* - * See if operation failed and additional status checks are - * available - */ - if ((status & NAND_STATUS_FAIL) && (chip->errstat)) - status = chip->errstat(mtd, chip, FL_WRITING, status, - page); - - if (status & NAND_STATUS_FAIL) - return -EIO; - } else { - chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); - status = chip->waitfunc(mtd, chip); - } - - return 0; -} - static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { return 0; @@ -800,7 +756,6 @@ static int cafe_nand_probe(struct pci_dev *pdev, cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; cafe->nand.ecc.calculate = (void *)cafe_nand_bug; cafe->nand.ecc.correct = (void *)cafe_nand_bug; - cafe->nand.write_page = cafe_nand_write_page; cafe->nand.ecc.write_page = cafe_nand_write_page_lowlevel; cafe->nand.ecc.write_oob = cafe_nand_write_oob; cafe->nand.ecc.read_page = cafe_nand_read_page; -- GitLab From 068b44b714952092e0791b321b05be79de9baa1e Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Fri, 7 Nov 2014 15:26:09 +0800 Subject: [PATCH 6582/9457] mtd: atmel_nand: replace memcpy32_toio/memcpy32_fromio with memcpy There is no need to use memcpy32_toio/memcpy32_fromio to transfer data between memory and NFC sram. As the NFC sram is a also a memory space not an I/O space, we can just use memcpy(). We remove the __iomem prefix for NFC sram to avoid sparse warnings. Signed-off-by: Josh Wu Reviewed-by: Brian Norris Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 39 +++++++++-------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 5c1423a2ffb5..9c28d010dbd9 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -92,7 +92,7 @@ static struct nand_ecclayout atmel_oobinfo_small = { struct atmel_nfc { void __iomem *base_cmd_regs; void __iomem *hsmc_regs; - void __iomem *sram_bank0; + void *sram_bank0; dma_addr_t sram_bank0_phys; bool use_nfc_sram; bool write_by_sram; @@ -105,7 +105,7 @@ struct atmel_nfc { struct completion comp_xfer_done; /* Point to the sram bank which include readed data via NFC */ - void __iomem *data_in_sram; + void *data_in_sram; bool will_write_sram; }; static struct atmel_nfc nand_nfc; @@ -257,26 +257,6 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) return res; } -static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) -{ - int i; - u32 *t = trg; - const __iomem u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - *t++ = readl_relaxed(s++); -} - -static void memcpy32_toio(void __iomem *trg, const void *src, int size) -{ - int i; - u32 __iomem *t = trg; - const u32 *s = src; - - for (i = 0; i < (size >> 2); i++) - writel_relaxed(*s++, t++); -} - /* * Minimal-overhead PIO for data access. */ @@ -286,7 +266,7 @@ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsb(nand_chip->IO_ADDR_R, buf, len); @@ -299,7 +279,7 @@ static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) struct atmel_nand_host *host = nand_chip->priv; if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { - memcpy32_fromio(buf, host->nfc->data_in_sram, len); + memcpy(buf, host->nfc->data_in_sram, len); host->nfc->data_in_sram += len; } else { __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); @@ -1972,7 +1952,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, int cfg, len; int status = 0; struct atmel_nand_host *host = chip->priv; - void __iomem *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); + void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); /* Subpage write is not supported */ if (offset || (data_len < mtd->writesize)) @@ -1983,14 +1963,14 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (use_dma) { if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) != 0) /* Fall back to use cpu copy */ - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } else { - memcpy32_toio(sram, buf, len); + memcpy(sram, buf, len); } cfg = nfc_readl(host->nfc->hsmc_regs, CFG); if (unlikely(raw) && oob_required) { - memcpy32_toio(sram + len, chip->oob_poi, mtd->oobsize); + memcpy(sram + len, chip->oob_poi, mtd->oobsize); len += mtd->oobsize; nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); } else { @@ -2333,7 +2313,8 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev) nfc_sram = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (nfc_sram) { - nfc->sram_bank0 = devm_ioremap_resource(&pdev->dev, nfc_sram); + nfc->sram_bank0 = (void * __force) + devm_ioremap_resource(&pdev->dev, nfc_sram); if (IS_ERR(nfc->sram_bank0)) { dev_warn(&pdev->dev, "Fail to ioremap the NFC sram with error: %ld. So disable NFC sram.\n", PTR_ERR(nfc->sram_bank0)); -- GitLab From 5d85a8478ec8a1956f08ad72d1601a3c5cb60b1e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 18 Nov 2014 12:10:50 +0100 Subject: [PATCH 6583/9457] dt-bindings: simplefb: Drop the advice about using a specific path for nodes This goes contrary to how devicetree usually works, so drop it. Instead if the firmware needs to be able to find a specific node it should use a platform specific compatible + properties for this. Signed-off-by: Hans de Goede Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- .../devicetree/bindings/video/simple-framebuffer.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt index f8fb7e6e5609..4474ef6e0b95 100644 --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -31,12 +31,10 @@ enable them. This way if e.g. later on support for more display clocks get added, the simplefb nodes will already contain this info and the firmware does not need to be updated. -If pre-filled framebuffer nodes are used, they should be named -"framebuffer#-", e.g. "framebuffer0-hdmi". The output should be -included in the name since different outputs typically require different -clocks and the clocks are part of the pre-populated nodes. The firmware must -rename the nodes to the standard "framebuffer@
" name using the -runtime chosen address when enabling the nodes. +If pre-filled framebuffer nodes are used, the firmware may need extra +information to find the right node. In that case an extra platform specific +compatible and platform specific properties should be used and documented, +see e.g. simple-framebuffer-sunxi.txt . Required properties: - compatible: "simple-framebuffer" -- GitLab From b14c99299b9e11615f512ddadd6ca98dc41f2cb8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 18 Nov 2014 12:10:51 +0100 Subject: [PATCH 6584/9457] dt-bindings: simplefb-sunxi: Add sunxi simplefb extensions If pre-filled framebuffer nodes are used, the firmware may need extra properties to find the right node. This documents the properties to use for this on sunxi platforms. Signed-off-by: Hans de Goede Acked-by: Grant Likely Signed-off-by: Tomi Valkeinen --- .../video/simple-framebuffer-sunxi.txt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt new file mode 100644 index 000000000000..c46ba641a1df --- /dev/null +++ b/Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt @@ -0,0 +1,33 @@ +Sunxi specific Simple Framebuffer bindings + +This binding documents sunxi specific extensions to the simple-framebuffer +bindings. The sunxi simplefb u-boot code relies on the devicetree containing +pre-populated simplefb nodes. + +These extensions are intended so that u-boot can select the right node based +on which pipeline is being used. As such they are solely intended for +firmware / bootloader use, and the OS should ignore them. + +Required properties: +- compatible: "allwinner,simple-framebuffer" +- allwinner,pipeline, one of: + "de_be0-lcd0" + "de_be1-lcd1" + "de_be0-lcd0-hdmi" + "de_be1-lcd1-hdmi" + +Example: + +chosen { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer@0 { + compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-hdmi"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, + <&ahb_gates 44>; + status = "disabled"; + }; +}; -- GitLab From 086f8281ca91436da0b4d6738fdde173a89f65a7 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 4 Nov 2014 18:58:27 +0200 Subject: [PATCH 6585/9457] OMAPDSS: hdmi_wp: Protect reserved bits in hdmi_wp_audio_config_format() Only OMAP4 DSS has non reserved bits above 6th bit in HDMI_WP_AUDIO_CFG. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi_wp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c index 496327e2b21b..71b499ec33f6 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c @@ -194,8 +194,12 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, DSSDBG("Enter hdmi_wp_audio_config_format\n"); r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG); - r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); - r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); + if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 || + omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 || + omapdss_get_version() == OMAPDSS_VER_OMAP4) { + r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); + r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); + } r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); r = FLD_MOD(r, aud_fmt->type, 4, 4); r = FLD_MOD(r, aud_fmt->justification, 3, 3); -- GitLab From de0ab1f3f832654b968228cb1fce003920e89ad9 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 4 Nov 2014 18:54:40 +0200 Subject: [PATCH 6586/9457] OMAPDSS: hdmi5_core: Initialize mandatory sample_order parameter The hdmi_wp_audio_config_format() expects sample_order of struct hdmi_audio_format to be initialized. The only allowed value is HDMI_AUDIO_SAMPLE_LEFT_FIRST. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi5_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c index 83acbf7a8c89..9ffa805bf6e8 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c @@ -879,6 +879,9 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, /* only LPCM atm */ audio_format.type = HDMI_AUDIO_TYPE_LPCM; + /* only allowed option */ + audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; + /* disable start/stop signals of IEC 60958 blocks */ audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; -- GitLab From 652ce0434b82dc27ae851ee60d9863d04e5f7fa7 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 10 Apr 2014 10:36:26 +0300 Subject: [PATCH 6587/9457] OMAPDSS: hdmi.h: Add HDMI_AUDIO_LAYOUT_6CH enum value The OMAP5 HDMI audio implementation needs HDMI_AUDIO_LAYOUT_6CH in hdmi_core_audio_layout enum. I found the correct value from ti-linux 3.8 tree. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 3c42823e934b..2c385a229e89 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -153,7 +153,8 @@ enum hdmi_audio_blk_strt_end_sig { enum hdmi_core_audio_layout { HDMI_AUDIO_LAYOUT_2CH = 0, - HDMI_AUDIO_LAYOUT_8CH = 1 + HDMI_AUDIO_LAYOUT_8CH = 1, + HDMI_AUDIO_LAYOUT_6CH = 2 }; enum hdmi_core_cts_mode { -- GitLab From 12d3ea9a17783f3a56906b0e02efcad979955f3b Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 22 Aug 2014 15:15:47 +0300 Subject: [PATCH 6588/9457] OMAPDSS: hdmi: Remove most of OMAP[45]_DSS_HDMI_AUDIO ifdefs It does not waste too many bytes to compile all audio related core functions always in with HDMI support. It should help readability and in keeping the audio code in working shape. Leave the options just for disabling and enabling the functionality in hdmi[45].c. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 3 +-- drivers/video/fbdev/omap2/dss/hdmi4_core.c | 5 ----- drivers/video/fbdev/omap2/dss/hdmi4_core.h | 2 -- drivers/video/fbdev/omap2/dss/hdmi5_core.c | 6 ------ drivers/video/fbdev/omap2/dss/hdmi5_core.h | 2 -- drivers/video/fbdev/omap2/dss/hdmi_common.c | 2 -- drivers/video/fbdev/omap2/dss/hdmi_wp.c | 2 -- 7 files changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 2c385a229e89..aa2edd880ff3 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -321,7 +321,7 @@ int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes); int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, struct hdmi_phy_data *phy); -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +/* Audio funcs */ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); @@ -334,4 +334,3 @@ static inline bool hdmi_mode_has_audio(int mode) return mode == HDMI_HDMI ? true : false; } #endif -#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c index 4ad39cfce254..3b448d9ecd31 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c @@ -31,10 +31,8 @@ #include #include #include -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) #include #include -#endif #include "hdmi4_core.h" #include "dss_features.h" @@ -530,7 +528,6 @@ void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s) DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); } -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) static void hdmi_core_audio_config(struct hdmi_core_data *core, struct hdmi_core_audio_config *cfg) { @@ -886,8 +883,6 @@ int hdmi4_audio_get_dma_port(u32 *offset, u32 *size) return 0; } -#endif - int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) { struct resource *res; diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h index 827909eb6c50..c1959f7df7df 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h @@ -266,12 +266,10 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s); int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct omap_dss_audio *audio, u32 pclk); int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); -#endif #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c index 9ffa805bf6e8..a71157935e33 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c @@ -30,10 +30,8 @@ #include #include #include -#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) #include #include -#endif #include "hdmi5_core.h" @@ -644,9 +642,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, hdmi_core_enable_interrupts(core); } - -#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) - static void hdmi5_core_audio_config(struct hdmi_core_data *core, struct hdmi_core_audio_config *cfg) { @@ -897,7 +892,6 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, return 0; } -#endif int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core) { diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.h b/drivers/video/fbdev/omap2/dss/hdmi5_core.h index ce7e9f376f04..f2f1022c5516 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5_core.h +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.h @@ -299,8 +299,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct hdmi_config *cfg); int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core); -#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct omap_dss_audio *audio, u32 pclk); #endif -#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c index 7d5f1039de9f..1b8fcc6c4ba1 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_common.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c @@ -48,7 +48,6 @@ int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, return 0; } -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) { u32 deep_color; @@ -147,4 +146,3 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) return 0; } -#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c index 71b499ec33f6..4ead96218a31 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c @@ -185,7 +185,6 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, timings->interlace = param->timings.interlace; } -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, struct hdmi_audio_format *aud_fmt) { @@ -240,7 +239,6 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable) return 0; } -#endif int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) { -- GitLab From a42808c7470a4e45f640138dad8effa272de27c1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 22 Aug 2014 20:26:00 +0300 Subject: [PATCH 6589/9457] OMAPDSS: hdmi4_core: Remove unused hdmi4_audio_get_dma_port() hdmi4_audio_get_dma_port() is unused and and broken. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi4_core.c | 9 --------- drivers/video/fbdev/omap2/dss/hdmi4_core.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c index 3b448d9ecd31..7eafea5b8e19 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c @@ -874,15 +874,6 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp) hdmi_wp_audio_core_req_enable(wp, false); } -int hdmi4_audio_get_dma_port(u32 *offset, u32 *size) -{ - if (!offset || !size) - return -EINVAL; - *offset = HDMI_WP_AUDIO_DATA; - *size = 4; - return 0; -} - int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) { struct resource *res; diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h index c1959f7df7df..a069f96ec6f6 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h @@ -270,6 +270,4 @@ int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, struct omap_dss_audio *audio, u32 pclk); -int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); - #endif -- GitLab From 58652163f6cad5180aaa1e82612c1f87cd2e22b8 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 23 May 2014 16:13:57 +0300 Subject: [PATCH 6590/9457] OMAPDSS: hdmi_wp: Add function for getting audio dma address The audio dma port is found in the hdmi_wp physical address space. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 2 ++ drivers/video/fbdev/omap2/dss/hdmi_wp.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index aa2edd880ff3..5e0df84a736a 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -232,6 +232,7 @@ struct hdmi_core_audio_config { struct hdmi_wp_data { void __iomem *base; + phys_addr_t phys_base; }; struct hdmi_pll_data { @@ -301,6 +302,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, struct omap_video_timings *timings, struct hdmi_config *param); int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); +phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp); /* HDMI PLL funcs */ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c index 4ead96218a31..c15377e242cc 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c @@ -249,6 +249,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) DSSERR("can't get WP mem resource\n"); return -EINVAL; } + wp->phys_base = res->start; wp->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wp->base)) { @@ -258,3 +259,8 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) return 0; } + +phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp) +{ + return wp->phys_base + HDMI_WP_AUDIO_DATA; +} -- GitLab From 945514b5e1e5f93172a67d4b19b7fce8c8c1fead Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 27 Jun 2014 16:47:00 +0300 Subject: [PATCH 6591/9457] OMAPDSS: hdmi: Make hdmi structure public Unify the private anonymous struct in hdmi4.c and hdmi5.c, name it as struct omap_hdmi, and make it public in hdmi.h. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 20 ++++++++++++++++++ drivers/video/fbdev/omap2/dss/hdmi4.c | 30 +++++++-------------------- drivers/video/fbdev/omap2/dss/hdmi5.c | 20 ++---------------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 5e0df84a736a..a7d6474c69ad 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -335,4 +335,24 @@ static inline bool hdmi_mode_has_audio(int mode) { return mode == HDMI_HDMI ? true : false; } + +/* HDMI DRV data */ +struct omap_hdmi { + struct mutex lock; + struct platform_device *pdev; + + struct hdmi_wp_data wp; + struct hdmi_pll_data pll; + struct hdmi_phy_data phy; + struct hdmi_core_data core; + + struct hdmi_config cfg; + + struct regulator *vdda_reg; + + bool core_enabled; + + struct omap_dss_device output; +}; + #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 46dcc71ce058..1005cea38ff0 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -37,24 +37,9 @@ #include "hdmi4_core.h" #include "dss.h" #include "dss_features.h" +#include "hdmi.h" -static struct { - struct mutex lock; - struct platform_device *pdev; - - struct hdmi_wp_data wp; - struct hdmi_pll_data pll; - struct hdmi_phy_data phy; - struct hdmi_core_data core; - - struct hdmi_config cfg; - - struct regulator *vdda_hdmi_dac_reg; - - bool core_enabled; - - struct omap_dss_device output; -} hdmi; +static struct omap_hdmi hdmi; static int hdmi_runtime_get(void) { @@ -116,7 +101,7 @@ static int hdmi_init_regulator(void) int r; struct regulator *reg; - if (hdmi.vdda_hdmi_dac_reg != NULL) + if (hdmi.vdda_reg != NULL) return 0; reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); @@ -136,7 +121,7 @@ static int hdmi_init_regulator(void) } } - hdmi.vdda_hdmi_dac_reg = reg; + hdmi.vdda_reg = reg; return 0; } @@ -145,7 +130,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) { int r; - r = regulator_enable(hdmi.vdda_hdmi_dac_reg); + r = regulator_enable(hdmi.vdda_reg); if (r) return r; @@ -161,7 +146,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) return 0; err_runtime_get: - regulator_disable(hdmi.vdda_hdmi_dac_reg); + regulator_disable(hdmi.vdda_reg); return r; } @@ -171,7 +156,7 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev) hdmi.core_enabled = false; hdmi_runtime_put(); - regulator_disable(hdmi.vdda_hdmi_dac_reg); + regulator_disable(hdmi.vdda_reg); } static int hdmi_power_on_full(struct omap_dss_device *dssdev) @@ -666,6 +651,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) int irq; hdmi.pdev = pdev; + dev_set_drvdata(&pdev->dev, &hdmi); mutex_init(&hdmi.lock); diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index 67facf87b370..6e5894fb96ce 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -43,24 +43,7 @@ #include "dss.h" #include "dss_features.h" -static struct { - struct mutex lock; - struct platform_device *pdev; - - struct hdmi_wp_data wp; - struct hdmi_pll_data pll; - struct hdmi_phy_data phy; - struct hdmi_core_data core; - - struct hdmi_config cfg; - - struct regulator *vdda_reg; - struct clk *sys_clk; - - bool core_enabled; - - struct omap_dss_device output; -} hdmi; +static struct omap_hdmi hdmi; static int hdmi_runtime_get(void) { @@ -696,6 +679,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) int irq; hdmi.pdev = pdev; + dev_set_drvdata(&pdev->dev, &hdmi); mutex_init(&hdmi.lock); -- GitLab From 29c047b747d52d77abea65659b49a18955d632ed Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 15 Sep 2014 22:34:20 +0300 Subject: [PATCH 6592/9457] OMAPDSS: hdmi: Add pdev pointer for audio_pdev in HDMI DRV data This is used to store omap-hdmi-audio pdev for unregistering it. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index a7d6474c69ad..fd80774ac162 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -353,6 +353,8 @@ struct omap_hdmi { bool core_enabled; struct omap_dss_device output; + + struct platform_device *audio_pdev; }; #endif -- GitLab From 954df6ad00ea2ba732e2e7ae6a68b3111eee4e09 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 20 Nov 2014 16:31:12 -0800 Subject: [PATCH 6593/9457] HID: wacom: PAD is independent with pen/touch PAD can be on pen interface (Intuos Pro and Cintiq series) or touch interface (Bamboo PT and Intuos PT series) or its own interface (Bamboo pen-only and Intuos Pen M/S). We need to mark it independently. Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 8 +++++--- drivers/hid/wacom_wac.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 68b6cd66f9c3..eb5531657e41 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1135,7 +1135,7 @@ static void wacom_clean_inputs(struct wacom *wacom) input_free_device(wacom->wacom_wac.input); } if (wacom->wacom_wac.pad_input) { - if (wacom->wacom_wac.input_registered) + if (wacom->wacom_wac.pad_registered) input_unregister_device(wacom->wacom_wac.pad_input); else input_free_device(wacom->wacom_wac.pad_input); @@ -1162,6 +1162,7 @@ static int wacom_register_inputs(struct wacom *wacom) error = input_register_device(input_dev); if (error) return error; + wacom_wac->input_registered = true; } error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); @@ -1174,22 +1175,23 @@ static int wacom_register_inputs(struct wacom *wacom) error = input_register_device(pad_input_dev); if (error) goto fail_register_pad_input; + wacom_wac->pad_registered = true; error = wacom_initialize_leds(wacom); if (error) goto fail_leds; } - wacom_wac->input_registered = true; - return 0; fail_leds: input_unregister_device(pad_input_dev); pad_input_dev = NULL; + wacom_wac->pad_registered = false; fail_register_pad_input: input_unregister_device(input_dev); wacom_wac->input = NULL; + wacom_wac->input_registered = false; return error; } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 0f0b85ec1322..128cbb337ff6 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -183,6 +183,7 @@ struct wacom_wac { struct input_dev *input; struct input_dev *pad_input; bool input_registered; + bool pad_registered; int pid; int battery_capacity; int num_contacts_left; -- GitLab From 016ed39c54b8a3db680e5c6a43419f806133caf2 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Wed, 19 Nov 2014 10:11:25 +0000 Subject: [PATCH 6594/9457] arm/arm64: KVM: vgic: kick the specific vcpu instead of iterating through all When call kvm_vgic_inject_irq to inject interrupt, we can known which vcpu the interrupt for by the irq_num and the cpuid. So we should just kick this vcpu to avoid iterating through all. Reviewed-by: Christoffer Dall Signed-off-by: Shannon Zhao Signed-off-by: Marc Zyngier --- virt/kvm/arm/vgic.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 631a472e41cf..21e035cc5460 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1607,7 +1607,7 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level) } } -static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, +static int vgic_update_irq_pending(struct kvm *kvm, int cpuid, unsigned int irq_num, bool level) { struct vgic_dist *dist = &kvm->arch.vgic; @@ -1673,7 +1673,7 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, out: spin_unlock(&dist->lock); - return ret; + return ret ? cpuid : -EINVAL; } /** @@ -1693,9 +1693,14 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, bool level) { - if (likely(vgic_initialized(kvm)) && - vgic_update_irq_pending(kvm, cpuid, irq_num, level)) - vgic_kick_vcpus(kvm); + int vcpu_id; + + if (likely(vgic_initialized(kvm))) { + vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level); + if (vcpu_id >= 0) + /* kick the specified vcpu */ + kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id)); + } return 0; } -- GitLab From 5872b35aaf78ad5dcaab15f2bc874058226615a1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 7 Oct 2014 12:24:10 +0300 Subject: [PATCH 6595/9457] OMAPDSS: hdmi.h: Add members to hdmi drvdata for audio implementation Adds display_enabled flag and audio_abort_cb callback to struct hdmi. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index fd80774ac162..87bd551df696 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -351,10 +351,12 @@ struct omap_hdmi { struct regulator *vdda_reg; bool core_enabled; + bool display_enabled; struct omap_dss_device output; struct platform_device *audio_pdev; + void (*audio_abort_cb)(struct device *dev); }; #endif -- GitLab From 5b97f49d653d366d8cb03cab40f8c45eb59dc70c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 26 Nov 2014 12:37:43 +0100 Subject: [PATCH 6596/9457] cfg80211: refactor the various CQM event sending code Much of the code can be shared by moving it into helper functions for the CQM event sending. Also move the code closer together, even in the header file. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 54 +++++----- net/wireless/nl80211.c | 222 ++++++++++++++++++----------------------- 2 files changed, 126 insertions(+), 150 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bb748c4da5af..1d15f1dfdaa7 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4642,33 +4642,6 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -/** - * cfg80211_radar_event - radar detection event - * @wiphy: the wiphy - * @chandef: chandef for the current channel - * @gfp: context flags - * - * This function is called when a radar is detected on the current chanenl. - */ -void cfg80211_radar_event(struct wiphy *wiphy, - struct cfg80211_chan_def *chandef, gfp_t gfp); - -/** - * cfg80211_cac_event - Channel availability check (CAC) event - * @netdev: network device - * @chandef: chandef for the current channel - * @event: type of event - * @gfp: context flags - * - * This function is called when a Channel availability check (CAC) is finished - * or aborted. This must be called to notify the completion of a CAC process, - * also by full-MAC drivers. - */ -void cfg80211_cac_event(struct net_device *netdev, - const struct cfg80211_chan_def *chandef, - enum nl80211_radar_event event, gfp_t gfp); - - /** * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer * @dev: network device @@ -4696,6 +4669,33 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, u32 num_packets, u32 rate, u32 intvl, gfp_t gfp); +/** + * cfg80211_radar_event - radar detection event + * @wiphy: the wiphy + * @chandef: chandef for the current channel + * @gfp: context flags + * + * This function is called when a radar is detected on the current chanenl. + */ +void cfg80211_radar_event(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef, gfp_t gfp); + +/** + * cfg80211_cac_event - Channel availability check (CAC) event + * @netdev: network device + * @chandef: chandef for the current channel + * @event: type of event + * @gfp: context flags + * + * This function is called when a Channel availability check (CAC) is finished + * or aborted. This must be called to notify the completion of a CAC process, + * also by full-MAC drivers. + */ +void cfg80211_cac_event(struct net_device *netdev, + const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, gfp_t gfp); + + /** * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying * @dev: network device diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b5e3c489239d..9c4d0102d34d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11766,55 +11766,132 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, } EXPORT_SYMBOL(cfg80211_mgmt_tx_status); -void cfg80211_cqm_rssi_notify(struct net_device *dev, - enum nl80211_cqm_rssi_threshold_event rssi_event, - gfp_t gfp) +static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev, + const char *mac, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct sk_buff *msg; - struct nlattr *pinfoattr; - void *hdr; - - trace_cfg80211_cqm_rssi_notify(dev, rssi_event); + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + void **cb; - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); if (!msg) - return; + return NULL; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); - if (!hdr) { + cb = (void **)msg->cb; + + cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); + if (!cb[0]) { nlmsg_free(msg); - return; + return NULL; } if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; - pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); - if (!pinfoattr) + if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac)) goto nla_put_failure; - if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, - rssi_event)) + cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM); + if (!cb[1]) goto nla_put_failure; - nla_nest_end(msg, pinfoattr); + cb[2] = rdev; - genlmsg_end(msg, hdr); + return msg; + nla_put_failure: + nlmsg_free(msg); + return NULL; +} + +static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp) +{ + void **cb = (void **)msg->cb; + struct cfg80211_registered_device *rdev = cb[2]; + + nla_nest_end(msg, cb[1]); + genlmsg_end(msg, cb[0]); + + memset(msg->cb, 0, sizeof(msg->cb)); genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, NL80211_MCGRP_MLME, gfp); +} + +void cfg80211_cqm_rssi_notify(struct net_device *dev, + enum nl80211_cqm_rssi_threshold_event rssi_event, + gfp_t gfp) +{ + struct sk_buff *msg; + + trace_cfg80211_cqm_rssi_notify(dev, rssi_event); + + msg = cfg80211_prepare_cqm(dev, NULL, gfp); + if (!msg) + return; + + if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, + rssi_event)) + goto nla_put_failure; + + cfg80211_send_cqm(msg, gfp); + return; nla_put_failure: - genlmsg_cancel(msg, hdr); nlmsg_free(msg); } EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); +void cfg80211_cqm_txe_notify(struct net_device *dev, + const u8 *peer, u32 num_packets, + u32 rate, u32 intvl, gfp_t gfp) +{ + struct sk_buff *msg; + + msg = cfg80211_prepare_cqm(dev, peer, gfp); + if (!msg) + return; + + if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets)) + goto nla_put_failure; + + if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate)) + goto nla_put_failure; + + if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl)) + goto nla_put_failure; + + cfg80211_send_cqm(msg, gfp); + return; + + nla_put_failure: + nlmsg_free(msg); +} +EXPORT_SYMBOL(cfg80211_cqm_txe_notify); + +void cfg80211_cqm_pktloss_notify(struct net_device *dev, + const u8 *peer, u32 num_packets, gfp_t gfp) +{ + struct sk_buff *msg; + + trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets); + + msg = cfg80211_prepare_cqm(dev, peer, gfp); + if (!msg) + return; + + if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets)) + goto nla_put_failure; + + cfg80211_send_cqm(msg, gfp); + return; + + nla_put_failure: + nlmsg_free(msg); +} +EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); + static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *replay_ctr, gfp_t gfp) @@ -12003,59 +12080,6 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev, } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); -void cfg80211_cqm_txe_notify(struct net_device *dev, - const u8 *peer, u32 num_packets, - u32 rate, u32 intvl, gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct sk_buff *msg; - struct nlattr *pinfoattr; - void *hdr; - - msg = nlmsg_new(NLMSG_GOODSIZE, gfp); - if (!msg) - return; - - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); - if (!hdr) { - nlmsg_free(msg); - return; - } - - if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || - nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) - goto nla_put_failure; - - pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); - if (!pinfoattr) - goto nla_put_failure; - - if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets)) - goto nla_put_failure; - - if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate)) - goto nla_put_failure; - - if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl)) - goto nla_put_failure; - - nla_nest_end(msg, pinfoattr); - - genlmsg_end(msg, hdr); - - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - NL80211_MCGRP_MLME, gfp); - return; - - nla_put_failure: - genlmsg_cancel(msg, hdr); - nlmsg_free(msg); -} -EXPORT_SYMBOL(cfg80211_cqm_txe_notify); - void nl80211_radar_notify(struct cfg80211_registered_device *rdev, const struct cfg80211_chan_def *chandef, @@ -12104,54 +12128,6 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } -void cfg80211_cqm_pktloss_notify(struct net_device *dev, - const u8 *peer, u32 num_packets, gfp_t gfp) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - struct sk_buff *msg; - struct nlattr *pinfoattr; - void *hdr; - - trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets); - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); - if (!msg) - return; - - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); - if (!hdr) { - nlmsg_free(msg); - return; - } - - if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || - nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) - goto nla_put_failure; - - pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); - if (!pinfoattr) - goto nla_put_failure; - - if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets)) - goto nla_put_failure; - - nla_nest_end(msg, pinfoattr); - - genlmsg_end(msg, hdr); - - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - NL80211_MCGRP_MLME, gfp); - return; - - nla_put_failure: - genlmsg_cancel(msg, hdr); - nlmsg_free(msg); -} -EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); - void cfg80211_probe_status(struct net_device *dev, const u8 *addr, u64 cookie, bool acked, gfp_t gfp) { -- GitLab From 476c7fe20f30818e16339391aeeb01b29818f708 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Mon, 24 Nov 2014 17:12:45 +0100 Subject: [PATCH 6597/9457] crypto: user - add MODULE_ALIAS To allow automatic loading of the crypto_user kernel module, the netlink MODULE_ALIAS is added. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/crypto_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 0bb30ac3a323..c5148a35ae0a 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -534,3 +534,4 @@ module_exit(crypto_user_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert "); MODULE_DESCRIPTION("Crypto userspace configuration API"); +MODULE_ALIAS("net-pf-16-proto-21"); -- GitLab From 4943ba16bbc2db05115707b3ff7b4874e9e3c560 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 24 Nov 2014 16:32:38 -0800 Subject: [PATCH 6598/9457] crypto: include crypto- module prefix in template This adds the module loading prefix "crypto-" to the template lookup as well. For example, attempting to load 'vfat(blowfish)' via AF_ALG now correctly includes the "crypto-" prefix at every level, correctly rejecting "vfat": net-pf-38 algif-hash crypto-vfat(blowfish) crypto-vfat(blowfish)-all crypto-vfat Reported-by: Mathias Krause Signed-off-by: Kees Cook Acked-by: Mathias Krause Signed-off-by: Herbert Xu --- arch/x86/crypto/fpu.c | 3 +++ crypto/algapi.c | 4 ++-- crypto/authenc.c | 1 + crypto/authencesn.c | 1 + crypto/cbc.c | 1 + crypto/ccm.c | 1 + crypto/chainiv.c | 1 + crypto/cmac.c | 1 + crypto/cryptd.c | 1 + crypto/ctr.c | 1 + crypto/cts.c | 1 + crypto/ecb.c | 1 + crypto/eseqiv.c | 1 + crypto/gcm.c | 1 + crypto/hmac.c | 1 + crypto/lrw.c | 1 + crypto/mcryptd.c | 1 + crypto/pcbc.c | 1 + crypto/pcrypt.c | 1 + crypto/seqiv.c | 1 + crypto/vmac.c | 1 + crypto/xcbc.c | 1 + crypto/xts.c | 1 + 23 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c index 98d7a188f46b..f368ba261739 100644 --- a/arch/x86/crypto/fpu.c +++ b/arch/x86/crypto/fpu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include struct crypto_fpu_ctx { @@ -159,3 +160,5 @@ void __exit crypto_fpu_exit(void) { crypto_unregister_template(&crypto_fpu_tmpl); } + +MODULE_ALIAS_CRYPTO("fpu"); diff --git a/crypto/algapi.c b/crypto/algapi.c index e8d3a7dca8c4..71a8143e23b1 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -509,8 +509,8 @@ static struct crypto_template *__crypto_lookup_template(const char *name) struct crypto_template *crypto_lookup_template(const char *name) { - return try_then_request_module(__crypto_lookup_template(name), "%s", - name); + return try_then_request_module(__crypto_lookup_template(name), + "crypto-%s", name); } EXPORT_SYMBOL_GPL(crypto_lookup_template); diff --git a/crypto/authenc.c b/crypto/authenc.c index e1223559d5df..78fb16cab13f 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -721,3 +721,4 @@ module_exit(crypto_authenc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Simple AEAD wrapper for IPsec"); +MODULE_ALIAS_CRYPTO("authenc"); diff --git a/crypto/authencesn.c b/crypto/authencesn.c index 4be0dd4373a9..024bff2344fc 100644 --- a/crypto/authencesn.c +++ b/crypto/authencesn.c @@ -814,3 +814,4 @@ module_exit(crypto_authenc_esn_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert "); MODULE_DESCRIPTION("AEAD wrapper for IPsec with extended sequence numbers"); +MODULE_ALIAS_CRYPTO("authencesn"); diff --git a/crypto/cbc.c b/crypto/cbc.c index 61ac42e1e32b..780ee27b2d43 100644 --- a/crypto/cbc.c +++ b/crypto/cbc.c @@ -289,3 +289,4 @@ module_exit(crypto_cbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CBC block cipher algorithm"); +MODULE_ALIAS_CRYPTO("cbc"); diff --git a/crypto/ccm.c b/crypto/ccm.c index 647575b41281..003bbbd21a2b 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -881,3 +881,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Counter with CBC MAC"); MODULE_ALIAS_CRYPTO("ccm_base"); MODULE_ALIAS_CRYPTO("rfc4309"); +MODULE_ALIAS_CRYPTO("ccm"); diff --git a/crypto/chainiv.c b/crypto/chainiv.c index 9c294c8f9a07..63c17d5992f7 100644 --- a/crypto/chainiv.c +++ b/crypto/chainiv.c @@ -359,3 +359,4 @@ module_exit(chainiv_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Chain IV Generator"); +MODULE_ALIAS_CRYPTO("chainiv"); diff --git a/crypto/cmac.c b/crypto/cmac.c index 50880cf17fad..7a8bfbd548f6 100644 --- a/crypto/cmac.c +++ b/crypto/cmac.c @@ -313,3 +313,4 @@ module_exit(crypto_cmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CMAC keyed hash algorithm"); +MODULE_ALIAS_CRYPTO("cmac"); diff --git a/crypto/cryptd.c b/crypto/cryptd.c index e592c90abebb..650afac10fd7 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -955,3 +955,4 @@ module_exit(cryptd_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Software async crypto daemon"); +MODULE_ALIAS_CRYPTO("cryptd"); diff --git a/crypto/ctr.c b/crypto/ctr.c index 3d81ff7e6b48..2386f7313952 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c @@ -467,3 +467,4 @@ module_exit(crypto_ctr_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CTR Counter block mode"); MODULE_ALIAS_CRYPTO("rfc3686"); +MODULE_ALIAS_CRYPTO("ctr"); diff --git a/crypto/cts.c b/crypto/cts.c index 133f0874c95e..bd9405820e8a 100644 --- a/crypto/cts.c +++ b/crypto/cts.c @@ -351,3 +351,4 @@ module_exit(crypto_cts_module_exit); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC"); +MODULE_ALIAS_CRYPTO("cts"); diff --git a/crypto/ecb.c b/crypto/ecb.c index 935cfef4aa84..12011aff0971 100644 --- a/crypto/ecb.c +++ b/crypto/ecb.c @@ -185,3 +185,4 @@ module_exit(crypto_ecb_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ECB block cipher algorithm"); +MODULE_ALIAS_CRYPTO("ecb"); diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index bf7ab4a89493..f116fae766f8 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c @@ -267,3 +267,4 @@ module_exit(eseqiv_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Encrypted Sequence Number IV Generator"); +MODULE_ALIAS_CRYPTO("eseqiv"); diff --git a/crypto/gcm.c b/crypto/gcm.c index aefb74a3f522..2e403f6138c1 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -1444,3 +1444,4 @@ MODULE_AUTHOR("Mikko Herranen "); MODULE_ALIAS_CRYPTO("gcm_base"); MODULE_ALIAS_CRYPTO("rfc4106"); MODULE_ALIAS_CRYPTO("rfc4543"); +MODULE_ALIAS_CRYPTO("gcm"); diff --git a/crypto/hmac.c b/crypto/hmac.c index e392219ddc61..72e38c098bb3 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -268,3 +268,4 @@ module_exit(hmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("HMAC hash algorithm"); +MODULE_ALIAS_CRYPTO("hmac"); diff --git a/crypto/lrw.c b/crypto/lrw.c index ba42acc4deba..6f9908a7ebcb 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -400,3 +400,4 @@ module_exit(crypto_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("LRW block cipher mode"); +MODULE_ALIAS_CRYPTO("lrw"); diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c index b39fbd530102..a8e870444ea9 100644 --- a/crypto/mcryptd.c +++ b/crypto/mcryptd.c @@ -703,3 +703,4 @@ module_exit(mcryptd_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Software async multibuffer crypto daemon"); +MODULE_ALIAS_CRYPTO("mcryptd"); diff --git a/crypto/pcbc.c b/crypto/pcbc.c index d1b8bdfb5855..f654965f0933 100644 --- a/crypto/pcbc.c +++ b/crypto/pcbc.c @@ -295,3 +295,4 @@ module_exit(crypto_pcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PCBC block cipher algorithm"); +MODULE_ALIAS_CRYPTO("pcbc"); diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index 309d345ead95..c305d4112735 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c @@ -565,3 +565,4 @@ module_exit(pcrypt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert "); MODULE_DESCRIPTION("Parallel crypto wrapper"); +MODULE_ALIAS_CRYPTO("pcrypt"); diff --git a/crypto/seqiv.c b/crypto/seqiv.c index ee190fcedcd2..9daa854cc485 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -362,3 +362,4 @@ module_exit(seqiv_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Sequence Number IV Generator"); +MODULE_ALIAS_CRYPTO("seqiv"); diff --git a/crypto/vmac.c b/crypto/vmac.c index d84c24bd7ff7..df76a816cfb2 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -713,3 +713,4 @@ module_exit(vmac_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VMAC hash algorithm"); +MODULE_ALIAS_CRYPTO("vmac"); diff --git a/crypto/xcbc.c b/crypto/xcbc.c index a5fbdf3738cf..df90b332554c 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -286,3 +286,4 @@ module_exit(crypto_xcbc_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XCBC keyed hash algorithm"); +MODULE_ALIAS_CRYPTO("xcbc"); diff --git a/crypto/xts.c b/crypto/xts.c index ca1608f44cb5..f6fd43f100c8 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -362,3 +362,4 @@ module_exit(crypto_module_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("XTS block cipher mode"); +MODULE_ALIAS_CRYPTO("xts"); -- GitLab From 0653a7cf6fa49bc769628b6078c3ea9e1489cb7b Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 25 Nov 2014 09:28:43 +0100 Subject: [PATCH 6599/9457] crypto: drbg - use MODULE_ALIAS_CRYPTO Use the crypto- prefix for the DRBG implementations. Signed-off-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/drbg.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index 9fb38a55118a..c90e3cf5967f 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -291,12 +291,12 @@ static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf) #ifdef CONFIG_CRYPTO_DRBG_CTR #define CRYPTO_DRBG_CTR_STRING "CTR " -MODULE_ALIAS("drbg_pr_ctr_aes256"); -MODULE_ALIAS("drbg_nopr_ctr_aes256"); -MODULE_ALIAS("drbg_pr_ctr_aes192"); -MODULE_ALIAS("drbg_nopr_ctr_aes192"); -MODULE_ALIAS("drbg_pr_ctr_aes128"); -MODULE_ALIAS("drbg_nopr_ctr_aes128"); +MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes256"); +MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes256"); +MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes192"); +MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192"); +MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128"); +MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128"); static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key, unsigned char *outval, const struct drbg_string *in); @@ -658,14 +658,14 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg); #ifdef CONFIG_CRYPTO_DRBG_HMAC #define CRYPTO_DRBG_HMAC_STRING "HMAC " -MODULE_ALIAS("drbg_pr_hmac_sha512"); -MODULE_ALIAS("drbg_nopr_hmac_sha512"); -MODULE_ALIAS("drbg_pr_hmac_sha384"); -MODULE_ALIAS("drbg_nopr_hmac_sha384"); -MODULE_ALIAS("drbg_pr_hmac_sha256"); -MODULE_ALIAS("drbg_nopr_hmac_sha256"); -MODULE_ALIAS("drbg_pr_hmac_sha1"); -MODULE_ALIAS("drbg_nopr_hmac_sha1"); +MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha512"); +MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512"); +MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha384"); +MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha384"); +MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha256"); +MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha256"); +MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha1"); +MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha1"); /* update function of HMAC DRBG as defined in 10.1.2.2 */ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed, @@ -778,14 +778,14 @@ static struct drbg_state_ops drbg_hmac_ops = { #ifdef CONFIG_CRYPTO_DRBG_HASH #define CRYPTO_DRBG_HASH_STRING "HASH " -MODULE_ALIAS("drbg_pr_sha512"); -MODULE_ALIAS("drbg_nopr_sha512"); -MODULE_ALIAS("drbg_pr_sha384"); -MODULE_ALIAS("drbg_nopr_sha384"); -MODULE_ALIAS("drbg_pr_sha256"); -MODULE_ALIAS("drbg_nopr_sha256"); -MODULE_ALIAS("drbg_pr_sha1"); -MODULE_ALIAS("drbg_nopr_sha1"); +MODULE_ALIAS_CRYPTO("drbg_pr_sha512"); +MODULE_ALIAS_CRYPTO("drbg_nopr_sha512"); +MODULE_ALIAS_CRYPTO("drbg_pr_sha384"); +MODULE_ALIAS_CRYPTO("drbg_nopr_sha384"); +MODULE_ALIAS_CRYPTO("drbg_pr_sha256"); +MODULE_ALIAS_CRYPTO("drbg_nopr_sha256"); +MODULE_ALIAS_CRYPTO("drbg_pr_sha1"); +MODULE_ALIAS_CRYPTO("drbg_nopr_sha1"); /* * Increment buffer -- GitLab From d7c5925487d6352240be7ef1c4f3a02886688b4b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 25 Nov 2014 23:41:09 -0200 Subject: [PATCH 6600/9457] [media] omap: disable COMPILE_TEST This causes lots of errors, because of sub-arch specific dependencies: All error/warnings: >> ERROR: "omapdss_compat_init" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_overlay_manager" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_num_overlay_managers" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_overlay" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omapdss_is_initialized" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dispc_register_isr" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omapdss_get_version" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_put_device" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_next_device" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dispc_unregister_isr" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omapdss_compat_uninit" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_device" [drivers/media/platform/omap/omap-vout.ko] undefined! >> ERROR: "omap_dss_get_num_overlays" [drivers/media/platform/omap/omap-vout.ko] undefined! Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig index 8f27cdadf8b8..dc2aaab54aef 100644 --- a/drivers/media/platform/omap/Kconfig +++ b/drivers/media/platform/omap/Kconfig @@ -4,7 +4,7 @@ config VIDEO_OMAP2_VOUT_VRFB config VIDEO_OMAP2_VOUT tristate "OMAP2/OMAP3 V4L2-Display driver" depends on MMU - depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST + depends on ARCH_OMAP2 || ARCH_OMAP3 select VIDEOBUF_GEN select VIDEOBUF_DMA_CONTIG select OMAP2_DSS if HAS_IOMEM && ARCH_OMAP2PLUS -- GitLab From 371fdc77af44f4cb32475fd499e1d912ccc30890 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 26 Nov 2014 19:31:13 +0900 Subject: [PATCH 6601/9457] kbuild: collect shorthands into scripts/Kbuild.include The shorthand "clean" is defined in both the top Makefile and scripts/Makefile.clean. Likewise, the "hdr-inst" is defined in both the top Makefile and scripts/Makefile.headersinst. To reduce code duplication, this commit collects them into scripts/Kbuild.include like the "build" and "modbuiltin" shorthands. It requires scripts/Makefile.clean to include scripts/Kbuild.include, but its impact on the performance of "make clean" should be negligible. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- Makefile | 7 ------- scripts/Kbuild.include | 12 ++++++++++++ scripts/Makefile.clean | 5 +---- scripts/Makefile.headersinst | 1 - 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 05d67af376c5..0032d1ca4e49 100644 --- a/Makefile +++ b/Makefile @@ -1035,8 +1035,6 @@ firmware_install: FORCE #Default location for installed headers export INSTALL_HDR_PATH = $(objtree)/usr -hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj - # If we do an all arch process set dst to asm-$(hdr-arch) hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) @@ -1580,11 +1578,6 @@ ifneq ($(cmd_files),) include $(cmd_files) endif -# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir -# Usage: -# $(Q)$(MAKE) $(clean)=dir -clean := -f $(srctree)/scripts/Makefile.clean obj - endif # skip-makefile PHONY += FORCE diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 65e7b08bb2cc..0f909814edfc 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -179,6 +179,18 @@ build := -f $(srctree)/scripts/Makefile.build obj # $(Q)$(MAKE) $(modbuiltin)=dir modbuiltin := -f $(srctree)/scripts/Makefile.modbuiltin obj +### +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj= +# Usage: +# $(Q)$(MAKE) $(clean)=dir +clean := -f $(srctree)/scripts/Makefile.clean obj + +### +# Shorthand for $(Q)$(MAKE) -rR -f scripts/Makefile.headersinst obj= +# Usage: +# $(Q)$(MAKE) $(hdr-inst)=dir +hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj + # Prefix -I with $(srctree) if it is not an absolute path. # skip if -I has no parameter addtree = $(if $(patsubst -I%,%,$(1)), \ diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index b1c668dc6815..0aa91a07d968 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -7,10 +7,7 @@ src := $(obj) PHONY := __clean __clean: -# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir -# Usage: -# $(Q)$(MAKE) $(clean)=dir -clean := -f $(srctree)/scripts/Makefile.clean obj +include scripts/Kbuild.include # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index 8ccf83056a7a..1106d6ca3a38 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst @@ -122,7 +122,6 @@ $(check-file): scripts/headers_check.pl $(output-files) FORCE endif # Recursion -hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj .PHONY: $(subdirs) $(subdirs): $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@ -- GitLab From a29b82326ed4eb5567b03c85b52c6891578d5a03 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 26 Nov 2014 15:09:24 +0100 Subject: [PATCH 6602/9457] kbuild: Remove duplicate $(cmd) definition in Makefile.clean Makefile.clean includes Kbuild.include since commit 371fdc77 (kbuild: collect shorthands into scripts/Kbuild.include), so there is no need for a local copy. Signed-off-by: Michal Marek --- scripts/Makefile.clean | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 0aa91a07d968..1bca180db8ad 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -88,11 +88,6 @@ PHONY += $(subdir-ymn) $(subdir-ymn): $(Q)$(MAKE) $(clean)=$@ -# If quiet is set, only print short version of command - -cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1)) - - # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable se we can use it in if_changed and friends. -- GitLab From 65d473b8007b4ef9f2a5e52f39c52d2141dfd421 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 26 Nov 2014 15:19:43 +0000 Subject: [PATCH 6603/9457] of: remove select of non-existant OF_DEVICE config symbol The OF_OVERLAY option selects OF_DEVICE, but OF_DEVICE was removed in commit ba166e900b, "of: remove CONFIG_OF_DEVICE". Remove the unnecessary select. Signed-off-by: Grant Likely Reported-by: Paul Bolle Cc: Pantelis Antoniou --- drivers/of/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 18b2e2539f84..b5e0c873d4e1 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -88,7 +88,6 @@ config OF_OVERLAY bool depends on OF select OF_DYNAMIC - select OF_DEVICE select OF_RESOLVE endmenu # OF -- GitLab From 36cdfa76635b502c8c7bb7df695d7d5117eca7de Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 18 Nov 2014 17:22:33 -0300 Subject: [PATCH 6604/9457] [media] media: rc: meson: document device tree bindings This adds binding documentation for the infrared remote control receiver available in Amlogic Meson SoCs. Signed-off-by: Beniamino Galvani Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/meson-ir.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/meson-ir.txt diff --git a/Documentation/devicetree/bindings/media/meson-ir.txt b/Documentation/devicetree/bindings/media/meson-ir.txt new file mode 100644 index 000000000000..407848e85f31 --- /dev/null +++ b/Documentation/devicetree/bindings/media/meson-ir.txt @@ -0,0 +1,14 @@ +* Amlogic Meson IR remote control receiver + +Required properties: + - compatible : should be "amlogic,meson6-ir" + - reg : physical base address and length of the device registers + - interrupts : a single specifier for the interrupt from the device + +Example: + + ir-receiver@c8100480 { + compatible= "amlogic,meson6-ir"; + reg = <0xc8100480 0x20>; + interrupts = <0 15 1>; + }; -- GitLab From 12ddbadf383d551e2681eb361b4f5c400363b5cd Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 18 Nov 2014 17:22:34 -0300 Subject: [PATCH 6605/9457] [media] media: rc: add driver for Amlogic Meson IR remote receiver Amlogic Meson SoCs include a infrared remote control receiver that can operate in two modes: "NEC" mode in which the hardware decodes frames using the NEC IR protocol, and "general" mode in which the receiver simply reports the duration of pulses and spaces for software decoding. This is a driver for the IR receiver that implements software decoding of received frames. Signed-off-by: Beniamino Galvani Acked-by: Carlo Caione Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 1 + drivers/media/rc/Kconfig | 11 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/meson-ir.c | 216 ++++++++++++++++++++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 drivers/media/rc/meson-ir.c diff --git a/MAINTAINERS b/MAINTAINERS index a6288cacde10..f6058ceb297d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -850,6 +850,7 @@ ARM/Amlogic MesonX SoC support M: Carlo Caione L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: drivers/media/rc/meson-ir.c N: meson[x68] ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 1aea7320f52a..ddfab256b9a5 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -223,6 +223,17 @@ config IR_FINTEK To compile this driver as a module, choose M here: the module will be called fintek-cir. +config IR_MESON + tristate "Amlogic Meson IR remote receiver" + depends on RC_CORE + depends on ARCH_MESON || COMPILE_TEST + ---help--- + Say Y if you want to use the IR remote receiver available + on Amlogic Meson SoCs. + + To compile this driver as a module, choose M here: the + module will be called meson-ir. + config IR_NUVOTON tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" depends on PNP diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 8f509e0d92cf..379a5c0f1379 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_IR_IMON) += imon.o obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o obj-$(CONFIG_IR_MCEUSB) += mceusb.o obj-$(CONFIG_IR_FINTEK) += fintek-cir.o +obj-$(CONFIG_IR_MESON) += meson-ir.o obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o obj-$(CONFIG_IR_ENE) += ene_ir.o obj-$(CONFIG_IR_REDRAT3) += redrat3.o diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c new file mode 100644 index 000000000000..fcc3b82d1454 --- /dev/null +++ b/drivers/media/rc/meson-ir.c @@ -0,0 +1,216 @@ +/* + * Driver for Amlogic Meson IR remote receiver + * + * Copyright (C) 2014 Beniamino Galvani + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "meson-ir" + +#define IR_DEC_LDR_ACTIVE 0x00 +#define IR_DEC_LDR_IDLE 0x04 +#define IR_DEC_LDR_REPEAT 0x08 +#define IR_DEC_BIT_0 0x0c +#define IR_DEC_REG0 0x10 +#define IR_DEC_FRAME 0x14 +#define IR_DEC_STATUS 0x18 +#define IR_DEC_REG1 0x1c + +#define REG0_RATE_MASK (BIT(11) - 1) + +#define REG1_MODE_MASK (BIT(7) | BIT(8)) +#define REG1_MODE_NEC (0 << 7) +#define REG1_MODE_GENERAL (2 << 7) + +#define REG1_TIME_IV_SHIFT 16 +#define REG1_TIME_IV_MASK ((BIT(13) - 1) << REG1_TIME_IV_SHIFT) + +#define REG1_IRQSEL_MASK (BIT(2) | BIT(3)) +#define REG1_IRQSEL_NEC_MODE (0 << 2) +#define REG1_IRQSEL_RISE_FALL (1 << 2) +#define REG1_IRQSEL_FALL (2 << 2) +#define REG1_IRQSEL_RISE (3 << 2) + +#define REG1_RESET BIT(0) +#define REG1_ENABLE BIT(15) + +#define STATUS_IR_DEC_IN BIT(8) + +#define MESON_TRATE 10 /* us */ + +struct meson_ir { + void __iomem *reg; + struct rc_dev *rc; + int irq; + spinlock_t lock; +}; + +static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg, + u32 mask, u32 value) +{ + u32 data; + + data = readl(ir->reg + reg); + data &= ~mask; + data |= (value & mask); + writel(data, ir->reg + reg); +} + +static irqreturn_t meson_ir_irq(int irqno, void *dev_id) +{ + struct meson_ir *ir = dev_id; + u32 duration; + DEFINE_IR_RAW_EVENT(rawir); + + spin_lock(&ir->lock); + + duration = readl(ir->reg + IR_DEC_REG1); + duration = (duration & REG1_TIME_IV_MASK) >> REG1_TIME_IV_SHIFT; + rawir.duration = US_TO_NS(duration * MESON_TRATE); + + rawir.pulse = !!(readl(ir->reg + IR_DEC_STATUS) & STATUS_IR_DEC_IN); + + ir_raw_event_store_with_filter(ir->rc, &rawir); + ir_raw_event_handle(ir->rc); + + spin_unlock(&ir->lock); + + return IRQ_HANDLED; +} + +static int meson_ir_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct resource *res; + const char *map_name; + struct meson_ir *ir; + int ret; + + ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ir->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(ir->reg)) { + dev_err(dev, "failed to map registers\n"); + return PTR_ERR(ir->reg); + } + + ir->irq = platform_get_irq(pdev, 0); + if (ir->irq < 0) { + dev_err(dev, "no irq resource\n"); + return ir->irq; + } + + ir->rc = rc_allocate_device(); + if (!ir->rc) { + dev_err(dev, "failed to allocate rc device\n"); + return -ENOMEM; + } + + ir->rc->priv = ir; + ir->rc->input_name = DRIVER_NAME; + ir->rc->input_phys = DRIVER_NAME "/input0"; + ir->rc->input_id.bustype = BUS_HOST; + map_name = of_get_property(node, "linux,rc-map-name", NULL); + ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; + ir->rc->dev.parent = dev; + ir->rc->driver_type = RC_DRIVER_IR_RAW; + ir->rc->allowed_protocols = RC_BIT_ALL; + ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); + ir->rc->timeout = MS_TO_NS(200); + ir->rc->driver_name = DRIVER_NAME; + + spin_lock_init(&ir->lock); + platform_set_drvdata(pdev, ir); + + ret = rc_register_device(ir->rc); + if (ret) { + dev_err(dev, "failed to register rc device\n"); + goto out_free; + } + + ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir); + if (ret) { + dev_err(dev, "failed to request irq\n"); + goto out_unreg; + } + + /* Reset the decoder */ + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET); + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0); + /* Set general operation mode */ + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, REG1_MODE_GENERAL); + /* Set rate */ + meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1); + /* IRQ on rising and falling edges */ + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK, + REG1_IRQSEL_RISE_FALL); + /* Enable the decoder */ + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE); + + dev_info(dev, "receiver initialized\n"); + + return 0; +out_unreg: + rc_unregister_device(ir->rc); + ir->rc = NULL; +out_free: + rc_free_device(ir->rc); + + return ret; +} + +static int meson_ir_remove(struct platform_device *pdev) +{ + struct meson_ir *ir = platform_get_drvdata(pdev); + unsigned long flags; + + /* Disable the decoder */ + spin_lock_irqsave(&ir->lock, flags); + meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0); + spin_unlock_irqrestore(&ir->lock, flags); + + rc_unregister_device(ir->rc); + + return 0; +} + +static const struct of_device_id meson_ir_match[] = { + { .compatible = "amlogic,meson6-ir" }, + { }, +}; + +static struct platform_driver meson_ir_driver = { + .probe = meson_ir_probe, + .remove = meson_ir_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = meson_ir_match, + }, +}; + +module_platform_driver(meson_ir_driver); + +MODULE_DESCRIPTION("Amlogic Meson IR remote receiver driver"); +MODULE_AUTHOR("Beniamino Galvani "); +MODULE_LICENSE("GPL v2"); -- GitLab From ac61e3787315a50d6e30bee47ab315f098ab0d39 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 18 Nov 2014 17:22:35 -0300 Subject: [PATCH 6606/9457] [media] ARM: dts: meson: add IR receiver node This adds a node for the IR remote control receiver to the Amlogic Meson DTS. Signed-off-by: Beniamino Galvani Signed-off-by: Mauro Carvalho Chehab --- arch/arm/boot/dts/meson.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi index e6539ea5a711..6a37f15e8627 100644 --- a/arch/arm/boot/dts/meson.dtsi +++ b/arch/arm/boot/dts/meson.dtsi @@ -106,5 +106,12 @@ clocks = <&clk81>; status = "disabled"; }; + + ir_receiver: ir-receiver@c8100480 { + compatible= "amlogic,meson6-ir"; + reg = <0xc8100480 0x20>; + interrupts = <0 15 1>; + status = "disabled"; + }; }; }; /* end of / */ -- GitLab From be091d468a0a09a7f4b1645e20cd6d36a353e51a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:08 +0000 Subject: [PATCH 6607/9457] arm64: PCI/MSI: Use asm-generic/msi.h In order to support CONFIG_GENERIC_MSI_IRQ_DOMAIN, we need to define msi_alloc_info_t. As the generic version exposed in asm-generic/msi.h is perfectly convenient, import this file as asm/msi.h. Acked-by: Will Deacon Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-2-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm64/include/asm/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index dc770bd4f5a5..e315bd833c10 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -28,6 +28,7 @@ generic-y += local64.h generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h +generic-y += msi.h generic-y += mutex.h generic-y += pci.h generic-y += pci-bridge.h -- GitLab From 443acc4f37f61e343f3577dc28d7e7fd8b499465 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:09 +0000 Subject: [PATCH 6608/9457] irqchip: GICv3: Convert to domain hierarchy In order to start supporting stacked domains, convert the GICv3 code base to the new domain hierarchy framework, which mostly amounts to supporting the new alloc/free callbacks. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-3-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/Kconfig | 1 + drivers/irqchip/irq-gic-v3.c | 42 +++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index b21f12f1766d..4631685dfe43 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -14,6 +14,7 @@ config ARM_GIC_V3 bool select IRQ_DOMAIN select MULTI_IRQ_HANDLER + select IRQ_DOMAIN_HIERARCHY config ARM_NVIC bool diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index aa17ae805a70..4cb355aff3c6 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -594,14 +594,14 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, /* PPIs */ if (hw < 32) { irq_set_percpu_devid(irq); - irq_set_chip_and_handler(irq, &gic_chip, - handle_percpu_devid_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_percpu_devid_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); } /* SPIs */ if (hw >= 32 && hw < gic_data.irq_nr) { - irq_set_chip_and_handler(irq, &gic_chip, - handle_fasteoi_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } irq_set_chip_data(irq, d->host_data); @@ -633,9 +633,41 @@ static int gic_irq_domain_xlate(struct irq_domain *d, return 0; } +static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i, ret; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + struct of_phandle_args *irq_data = arg; + + ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, + irq_data->args_count, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) + gic_irq_domain_map(domain, virq + i, hwirq + i); + + return 0; +} + +static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + int i; + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + } +} + static const struct irq_domain_ops gic_irq_domain_ops = { - .map = gic_irq_domain_map, .xlate = gic_irq_domain_xlate, + .alloc = gic_irq_domain_alloc, + .free = gic_irq_domain_free, }; static int __init gic_of_init(struct device_node *node, struct device_node *parent) -- GitLab From f5c1434c217fd72ac0d24d3142d09e49a3d4e72e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:10 +0000 Subject: [PATCH 6609/9457] irqchip: GICv3: rework redistributor structure The basic GICv3 driver has almost no use for the redistributor (other than the basic per-CPU interrupts), but the ITS needs a lot more from them. As such, rework the set of data structures. The behaviour of the GICv3 driver is otherwise unaffected. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-4-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3.c | 73 ++++++++++++++++++------------ include/linux/irqchip/arm-gic-v3.h | 15 ++++++ 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 4cb355aff3c6..43e57da0d80e 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -34,20 +34,25 @@ #include "irq-gic-common.h" #include "irqchip.h" +struct redist_region { + void __iomem *redist_base; + phys_addr_t phys_base; +}; + struct gic_chip_data { void __iomem *dist_base; - void __iomem **redist_base; - void __iomem * __percpu *rdist; + struct redist_region *redist_regions; + struct rdists rdists; struct irq_domain *domain; u64 redist_stride; - u32 redist_regions; + u32 nr_redist_regions; unsigned int irq_nr; }; static struct gic_chip_data gic_data __read_mostly; -#define gic_data_rdist() (this_cpu_ptr(gic_data.rdist)) -#define gic_data_rdist_rd_base() (*gic_data_rdist()) +#define gic_data_rdist() (this_cpu_ptr(gic_data.rdists.rdist)) +#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) #define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K) /* Our default, arbitrary priority value. Linux only uses one anyway. */ @@ -333,8 +338,8 @@ static int gic_populate_rdist(void) MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | MPIDR_AFFINITY_LEVEL(mpidr, 0)); - for (i = 0; i < gic_data.redist_regions; i++) { - void __iomem *ptr = gic_data.redist_base[i]; + for (i = 0; i < gic_data.nr_redist_regions; i++) { + void __iomem *ptr = gic_data.redist_regions[i].redist_base; u32 reg; reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK; @@ -347,10 +352,13 @@ static int gic_populate_rdist(void) do { typer = readq_relaxed(ptr + GICR_TYPER); if ((typer >> 32) == aff) { + u64 offset = ptr - gic_data.redist_regions[i].redist_base; gic_data_rdist_rd_base() = ptr; - pr_info("CPU%d: found redistributor %llx @%p\n", + gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset; + pr_info("CPU%d: found redistributor %llx region %d:%pa\n", smp_processor_id(), - (unsigned long long)mpidr, ptr); + (unsigned long long)mpidr, + i, &gic_data_rdist()->phys_base); return 0; } @@ -673,9 +681,10 @@ static const struct irq_domain_ops gic_irq_domain_ops = { static int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *dist_base; - void __iomem **redist_base; + struct redist_region *rdist_regs; u64 redist_stride; - u32 redist_regions; + u32 nr_redist_regions; + u32 typer; u32 reg; int gic_irqs; int err; @@ -696,48 +705,54 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare goto out_unmap_dist; } - if (of_property_read_u32(node, "#redistributor-regions", &redist_regions)) - redist_regions = 1; + if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) + nr_redist_regions = 1; - redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL); - if (!redist_base) { + rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL); + if (!rdist_regs) { err = -ENOMEM; goto out_unmap_dist; } - for (i = 0; i < redist_regions; i++) { - redist_base[i] = of_iomap(node, 1 + i); - if (!redist_base[i]) { + for (i = 0; i < nr_redist_regions; i++) { + struct resource res; + int ret; + + ret = of_address_to_resource(node, 1 + i, &res); + rdist_regs[i].redist_base = of_iomap(node, 1 + i); + if (ret || !rdist_regs[i].redist_base) { pr_err("%s: couldn't map region %d\n", node->full_name, i); err = -ENODEV; goto out_unmap_rdist; } + rdist_regs[i].phys_base = res.start; } if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) redist_stride = 0; gic_data.dist_base = dist_base; - gic_data.redist_base = redist_base; - gic_data.redist_regions = redist_regions; + gic_data.redist_regions = rdist_regs; + gic_data.nr_redist_regions = nr_redist_regions; gic_data.redist_stride = redist_stride; /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) */ - gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f; - gic_irqs = (gic_irqs + 1) * 32; + typer = readl_relaxed(gic_data.dist_base + GICD_TYPER); + gic_data.rdists.id_bits = GICD_TYPER_ID_BITS(typer); + gic_irqs = GICD_TYPER_IRQS(typer); if (gic_irqs > 1020) gic_irqs = 1020; gic_data.irq_nr = gic_irqs; gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, &gic_data); - gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist)); + gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist)); - if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) { + if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) { err = -ENOMEM; goto out_free; } @@ -754,12 +769,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare out_free: if (gic_data.domain) irq_domain_remove(gic_data.domain); - free_percpu(gic_data.rdist); + free_percpu(gic_data.rdists.rdist); out_unmap_rdist: - for (i = 0; i < redist_regions; i++) - if (redist_base[i]) - iounmap(redist_base[i]); - kfree(redist_base); + for (i = 0; i < nr_redist_regions; i++) + if (rdist_regs[i].redist_base) + iounmap(rdist_regs[i].redist_base); + kfree(rdist_regs); out_unmap_dist: iounmap(dist_base); return err; diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 03a4ea37ba86..040615a48bf5 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -49,6 +49,10 @@ #define GICD_CTLR_ENABLE_G1A (1U << 1) #define GICD_CTLR_ENABLE_G1 (1U << 0) +#define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1) +#define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32) +#define GICD_TYPER_LPIS (1U << 17) + #define GICD_IROUTER_SPI_MODE_ONE (0U << 31) #define GICD_IROUTER_SPI_MODE_ANY (1U << 31) @@ -189,6 +193,17 @@ #include +struct rdists { + struct { + void __iomem *rd_base; + struct page *pend_page; + phys_addr_t phys_base; + } __percpu *rdist; + struct page *prop_page; + int id_bits; + u64 flags; +}; + static inline void gic_write_eoir(u64 irq) { asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq)); -- GitLab From cc2d3216f53c9fff0030eb71cacc4ce5f39d1d7e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:11 +0000 Subject: [PATCH 6610/9457] irqchip: GICv3: ITS command queue The ITS is configured through a number commands that the driver issues to the HW using a memory-based circular buffer. This patch implements the subset of commands that are required for Linux. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-5-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 511 +++++++++++++++++++++++++++++ include/linux/irqchip/arm-gic-v3.h | 102 ++++++ 2 files changed, 613 insertions(+) create mode 100644 drivers/irqchip/irq-gic-v3-its.c diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c new file mode 100644 index 000000000000..a5ab12c7d7fc --- /dev/null +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -0,0 +1,511 @@ +/* + * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. + * Author: Marc Zyngier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "irqchip.h" + +#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) + +/* + * Collection structure - just an ID, and a redistributor address to + * ping. We use one per CPU as a bag of interrupts assigned to this + * CPU. + */ +struct its_collection { + u64 target_address; + u16 col_id; +}; + +/* + * The ITS structure - contains most of the infrastructure, with the + * msi_controller, the command queue, the collections, and the list of + * devices writing to it. + */ +struct its_node { + raw_spinlock_t lock; + struct list_head entry; + struct msi_controller msi_chip; + struct irq_domain *domain; + void __iomem *base; + unsigned long phys_base; + struct its_cmd_block *cmd_base; + struct its_cmd_block *cmd_write; + void *tables[GITS_BASER_NR_REGS]; + struct its_collection *collections; + struct list_head its_device_list; + u64 flags; + u32 ite_size; +}; + +#define ITS_ITT_ALIGN SZ_256 + +/* + * The ITS view of a device - belongs to an ITS, a collection, owns an + * interrupt translation table, and a list of interrupts. + */ +struct its_device { + struct list_head entry; + struct its_node *its; + struct its_collection *collection; + void *itt; + unsigned long *lpi_map; + irq_hw_number_t lpi_base; + int nr_lpis; + u32 nr_ites; + u32 device_id; +}; + +/* + * ITS command descriptors - parameters to be encoded in a command + * block. + */ +struct its_cmd_desc { + union { + struct { + struct its_device *dev; + u32 event_id; + } its_inv_cmd; + + struct { + struct its_device *dev; + u32 event_id; + } its_int_cmd; + + struct { + struct its_device *dev; + int valid; + } its_mapd_cmd; + + struct { + struct its_collection *col; + int valid; + } its_mapc_cmd; + + struct { + struct its_device *dev; + u32 phys_id; + u32 event_id; + } its_mapvi_cmd; + + struct { + struct its_device *dev; + struct its_collection *col; + u32 id; + } its_movi_cmd; + + struct { + struct its_device *dev; + u32 event_id; + } its_discard_cmd; + + struct { + struct its_collection *col; + } its_invall_cmd; + }; +}; + +/* + * The ITS command block, which is what the ITS actually parses. + */ +struct its_cmd_block { + u64 raw_cmd[4]; +}; + +#define ITS_CMD_QUEUE_SZ SZ_64K +#define ITS_CMD_QUEUE_NR_ENTRIES (ITS_CMD_QUEUE_SZ / sizeof(struct its_cmd_block)) + +typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *, + struct its_cmd_desc *); + +static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr) +{ + cmd->raw_cmd[0] &= ~0xffUL; + cmd->raw_cmd[0] |= cmd_nr; +} + +static void its_encode_devid(struct its_cmd_block *cmd, u32 devid) +{ + cmd->raw_cmd[0] &= ~(0xffffUL << 32); + cmd->raw_cmd[0] |= ((u64)devid) << 32; +} + +static void its_encode_event_id(struct its_cmd_block *cmd, u32 id) +{ + cmd->raw_cmd[1] &= ~0xffffffffUL; + cmd->raw_cmd[1] |= id; +} + +static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id) +{ + cmd->raw_cmd[1] &= 0xffffffffUL; + cmd->raw_cmd[1] |= ((u64)phys_id) << 32; +} + +static void its_encode_size(struct its_cmd_block *cmd, u8 size) +{ + cmd->raw_cmd[1] &= ~0x1fUL; + cmd->raw_cmd[1] |= size & 0x1f; +} + +static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) +{ + cmd->raw_cmd[2] &= ~0xffffffffffffUL; + cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00UL; +} + +static void its_encode_valid(struct its_cmd_block *cmd, int valid) +{ + cmd->raw_cmd[2] &= ~(1UL << 63); + cmd->raw_cmd[2] |= ((u64)!!valid) << 63; +} + +static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) +{ + cmd->raw_cmd[2] &= ~(0xffffffffUL << 16); + cmd->raw_cmd[2] |= (target_addr & (0xffffffffUL << 16)); +} + +static void its_encode_collection(struct its_cmd_block *cmd, u16 col) +{ + cmd->raw_cmd[2] &= ~0xffffUL; + cmd->raw_cmd[2] |= col; +} + +static inline void its_fixup_cmd(struct its_cmd_block *cmd) +{ + /* Let's fixup BE commands */ + cmd->raw_cmd[0] = cpu_to_le64(cmd->raw_cmd[0]); + cmd->raw_cmd[1] = cpu_to_le64(cmd->raw_cmd[1]); + cmd->raw_cmd[2] = cpu_to_le64(cmd->raw_cmd[2]); + cmd->raw_cmd[3] = cpu_to_le64(cmd->raw_cmd[3]); +} + +static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + unsigned long itt_addr; + u8 size = order_base_2(desc->its_mapd_cmd.dev->nr_ites); + + itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt); + itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN); + + its_encode_cmd(cmd, GITS_CMD_MAPD); + its_encode_devid(cmd, desc->its_mapd_cmd.dev->device_id); + its_encode_size(cmd, size - 1); + its_encode_itt(cmd, itt_addr); + its_encode_valid(cmd, desc->its_mapd_cmd.valid); + + its_fixup_cmd(cmd); + + return desc->its_mapd_cmd.dev->collection; +} + +static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MAPC); + its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id); + its_encode_target(cmd, desc->its_mapc_cmd.col->target_address); + its_encode_valid(cmd, desc->its_mapc_cmd.valid); + + its_fixup_cmd(cmd); + + return desc->its_mapc_cmd.col; +} + +static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MAPVI); + its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id); + its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id); + its_encode_collection(cmd, desc->its_mapvi_cmd.dev->collection->col_id); + + its_fixup_cmd(cmd); + + return desc->its_mapvi_cmd.dev->collection; +} + +static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_MOVI); + its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_movi_cmd.id); + its_encode_collection(cmd, desc->its_movi_cmd.col->col_id); + + its_fixup_cmd(cmd); + + return desc->its_movi_cmd.dev->collection; +} + +static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_DISCARD); + its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_discard_cmd.event_id); + + its_fixup_cmd(cmd); + + return desc->its_discard_cmd.dev->collection; +} + +static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_INV); + its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id); + its_encode_event_id(cmd, desc->its_inv_cmd.event_id); + + its_fixup_cmd(cmd); + + return desc->its_inv_cmd.dev->collection; +} + +static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd, + struct its_cmd_desc *desc) +{ + its_encode_cmd(cmd, GITS_CMD_INVALL); + its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id); + + its_fixup_cmd(cmd); + + return NULL; +} + +static u64 its_cmd_ptr_to_offset(struct its_node *its, + struct its_cmd_block *ptr) +{ + return (ptr - its->cmd_base) * sizeof(*ptr); +} + +static int its_queue_full(struct its_node *its) +{ + int widx; + int ridx; + + widx = its->cmd_write - its->cmd_base; + ridx = readl_relaxed(its->base + GITS_CREADR) / sizeof(struct its_cmd_block); + + /* This is incredibly unlikely to happen, unless the ITS locks up. */ + if (((widx + 1) % ITS_CMD_QUEUE_NR_ENTRIES) == ridx) + return 1; + + return 0; +} + +static struct its_cmd_block *its_allocate_entry(struct its_node *its) +{ + struct its_cmd_block *cmd; + u32 count = 1000000; /* 1s! */ + + while (its_queue_full(its)) { + count--; + if (!count) { + pr_err_ratelimited("ITS queue not draining\n"); + return NULL; + } + cpu_relax(); + udelay(1); + } + + cmd = its->cmd_write++; + + /* Handle queue wrapping */ + if (its->cmd_write == (its->cmd_base + ITS_CMD_QUEUE_NR_ENTRIES)) + its->cmd_write = its->cmd_base; + + return cmd; +} + +static struct its_cmd_block *its_post_commands(struct its_node *its) +{ + u64 wr = its_cmd_ptr_to_offset(its, its->cmd_write); + + writel_relaxed(wr, its->base + GITS_CWRITER); + + return its->cmd_write; +} + +static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd) +{ + /* + * Make sure the commands written to memory are observable by + * the ITS. + */ + if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING) + __flush_dcache_area(cmd, sizeof(*cmd)); + else + dsb(ishst); +} + +static void its_wait_for_range_completion(struct its_node *its, + struct its_cmd_block *from, + struct its_cmd_block *to) +{ + u64 rd_idx, from_idx, to_idx; + u32 count = 1000000; /* 1s! */ + + from_idx = its_cmd_ptr_to_offset(its, from); + to_idx = its_cmd_ptr_to_offset(its, to); + + while (1) { + rd_idx = readl_relaxed(its->base + GITS_CREADR); + if (rd_idx >= to_idx || rd_idx < from_idx) + break; + + count--; + if (!count) { + pr_err_ratelimited("ITS queue timeout\n"); + return; + } + cpu_relax(); + udelay(1); + } +} + +static void its_send_single_command(struct its_node *its, + its_cmd_builder_t builder, + struct its_cmd_desc *desc) +{ + struct its_cmd_block *cmd, *sync_cmd, *next_cmd; + struct its_collection *sync_col; + + raw_spin_lock(&its->lock); + + cmd = its_allocate_entry(its); + if (!cmd) { /* We're soooooo screewed... */ + pr_err_ratelimited("ITS can't allocate, dropping command\n"); + raw_spin_unlock(&its->lock); + return; + } + sync_col = builder(cmd, desc); + its_flush_cmd(its, cmd); + + if (sync_col) { + sync_cmd = its_allocate_entry(its); + if (!sync_cmd) { + pr_err_ratelimited("ITS can't SYNC, skipping\n"); + goto post; + } + its_encode_cmd(sync_cmd, GITS_CMD_SYNC); + its_encode_target(sync_cmd, sync_col->target_address); + its_fixup_cmd(sync_cmd); + its_flush_cmd(its, sync_cmd); + } + +post: + next_cmd = its_post_commands(its); + raw_spin_unlock(&its->lock); + + its_wait_for_range_completion(its, cmd, next_cmd); +} + +static void its_send_inv(struct its_device *dev, u32 event_id) +{ + struct its_cmd_desc desc; + + desc.its_inv_cmd.dev = dev; + desc.its_inv_cmd.event_id = event_id; + + its_send_single_command(dev->its, its_build_inv_cmd, &desc); +} + +static void its_send_mapd(struct its_device *dev, int valid) +{ + struct its_cmd_desc desc; + + desc.its_mapd_cmd.dev = dev; + desc.its_mapd_cmd.valid = !!valid; + + its_send_single_command(dev->its, its_build_mapd_cmd, &desc); +} + +static void its_send_mapc(struct its_node *its, struct its_collection *col, + int valid) +{ + struct its_cmd_desc desc; + + desc.its_mapc_cmd.col = col; + desc.its_mapc_cmd.valid = !!valid; + + its_send_single_command(its, its_build_mapc_cmd, &desc); +} + +static void its_send_mapvi(struct its_device *dev, u32 irq_id, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_mapvi_cmd.dev = dev; + desc.its_mapvi_cmd.phys_id = irq_id; + desc.its_mapvi_cmd.event_id = id; + + its_send_single_command(dev->its, its_build_mapvi_cmd, &desc); +} + +static void its_send_movi(struct its_device *dev, + struct its_collection *col, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_movi_cmd.dev = dev; + desc.its_movi_cmd.col = col; + desc.its_movi_cmd.id = id; + + its_send_single_command(dev->its, its_build_movi_cmd, &desc); +} + +static void its_send_discard(struct its_device *dev, u32 id) +{ + struct its_cmd_desc desc; + + desc.its_discard_cmd.dev = dev; + desc.its_discard_cmd.event_id = id; + + its_send_single_command(dev->its, its_build_discard_cmd, &desc); +} + +static void its_send_invall(struct its_node *its, struct its_collection *col) +{ + struct its_cmd_desc desc; + + desc.its_invall_cmd.col = col; + + its_send_single_command(its, its_build_invall_cmd, &desc); +} diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 040615a48bf5..21c9d70426d1 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -80,9 +80,27 @@ #define GICR_MOVALLR 0x0110 #define GICR_PIDR2 GICD_PIDR2 +#define GICR_CTLR_ENABLE_LPIS (1UL << 0) + +#define GICR_TYPER_CPU_NUMBER(r) (((r) >> 8) & 0xffff) + #define GICR_WAKER_ProcessorSleep (1U << 1) #define GICR_WAKER_ChildrenAsleep (1U << 2) +#define GICR_PROPBASER_NonShareable (0U << 10) +#define GICR_PROPBASER_InnerShareable (1U << 10) +#define GICR_PROPBASER_OuterShareable (2U << 10) +#define GICR_PROPBASER_SHAREABILITY_MASK (3UL << 10) +#define GICR_PROPBASER_nCnB (0U << 7) +#define GICR_PROPBASER_nC (1U << 7) +#define GICR_PROPBASER_RaWt (2U << 7) +#define GICR_PROPBASER_RaWb (3U << 7) +#define GICR_PROPBASER_WaWt (4U << 7) +#define GICR_PROPBASER_WaWb (5U << 7) +#define GICR_PROPBASER_RaWaWt (6U << 7) +#define GICR_PROPBASER_RaWaWb (7U << 7) +#define GICR_PROPBASER_IDBITS_MASK (0x1f) + /* * Re-Distributor registers, offsets from SGI_base */ @@ -95,9 +113,93 @@ #define GICR_IPRIORITYR0 GICD_IPRIORITYR #define GICR_ICFGR0 GICD_ICFGR +#define GICR_TYPER_PLPIS (1U << 0) #define GICR_TYPER_VLPIS (1U << 1) #define GICR_TYPER_LAST (1U << 4) +#define LPI_PROP_GROUP1 (1 << 1) +#define LPI_PROP_ENABLED (1 << 0) + +/* + * ITS registers, offsets from ITS_base + */ +#define GITS_CTLR 0x0000 +#define GITS_IIDR 0x0004 +#define GITS_TYPER 0x0008 +#define GITS_CBASER 0x0080 +#define GITS_CWRITER 0x0088 +#define GITS_CREADR 0x0090 +#define GITS_BASER 0x0100 +#define GITS_PIDR2 GICR_PIDR2 + +#define GITS_TRANSLATER 0x10040 + +#define GITS_TYPER_PTA (1UL << 19) + +#define GITS_CBASER_VALID (1UL << 63) +#define GITS_CBASER_nCnB (0UL << 59) +#define GITS_CBASER_nC (1UL << 59) +#define GITS_CBASER_RaWt (2UL << 59) +#define GITS_CBASER_RaWb (3UL << 59) +#define GITS_CBASER_WaWt (4UL << 59) +#define GITS_CBASER_WaWb (5UL << 59) +#define GITS_CBASER_RaWaWt (6UL << 59) +#define GITS_CBASER_RaWaWb (7UL << 59) +#define GITS_CBASER_NonShareable (0UL << 10) +#define GITS_CBASER_InnerShareable (1UL << 10) +#define GITS_CBASER_OuterShareable (2UL << 10) +#define GITS_CBASER_SHAREABILITY_MASK (3UL << 10) + +#define GITS_BASER_NR_REGS 8 + +#define GITS_BASER_VALID (1UL << 63) +#define GITS_BASER_nCnB (0UL << 59) +#define GITS_BASER_nC (1UL << 59) +#define GITS_BASER_RaWt (2UL << 59) +#define GITS_BASER_RaWb (3UL << 59) +#define GITS_BASER_WaWt (4UL << 59) +#define GITS_BASER_WaWb (5UL << 59) +#define GITS_BASER_RaWaWt (6UL << 59) +#define GITS_BASER_RaWaWb (7UL << 59) +#define GITS_BASER_TYPE_SHIFT (56) +#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) +#define GITS_BASER_ENTRY_SIZE_SHIFT (48) +#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0xff) + 1) +#define GITS_BASER_NonShareable (0UL << 10) +#define GITS_BASER_InnerShareable (1UL << 10) +#define GITS_BASER_OuterShareable (2UL << 10) +#define GITS_BASER_SHAREABILITY_SHIFT (10) +#define GITS_BASER_SHAREABILITY_MASK (3UL << GITS_BASER_SHAREABILITY_SHIFT) +#define GITS_BASER_PAGE_SIZE_SHIFT (8) +#define GITS_BASER_PAGE_SIZE_4K (0UL << GITS_BASER_PAGE_SIZE_SHIFT) +#define GITS_BASER_PAGE_SIZE_16K (1UL << GITS_BASER_PAGE_SIZE_SHIFT) +#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT) +#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT) + +#define GITS_BASER_TYPE_NONE 0 +#define GITS_BASER_TYPE_DEVICE 1 +#define GITS_BASER_TYPE_VCPU 2 +#define GITS_BASER_TYPE_CPU 3 +#define GITS_BASER_TYPE_COLLECTION 4 +#define GITS_BASER_TYPE_RESERVED5 5 +#define GITS_BASER_TYPE_RESERVED6 6 +#define GITS_BASER_TYPE_RESERVED7 7 + +/* + * ITS commands + */ +#define GITS_CMD_MAPD 0x08 +#define GITS_CMD_MAPC 0x09 +#define GITS_CMD_MAPVI 0x0a +#define GITS_CMD_MOVI 0x01 +#define GITS_CMD_DISCARD 0x0f +#define GITS_CMD_INV 0x0c +#define GITS_CMD_MOVALL 0x0e +#define GITS_CMD_INVALL 0x0d +#define GITS_CMD_INT 0x03 +#define GITS_CMD_CLEAR 0x04 +#define GITS_CMD_SYNC 0x05 + /* * CPU interface registers */ -- GitLab From c48ed51c0d101ec4351530bdd6e1a01808f0a441 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:12 +0000 Subject: [PATCH 6611/9457] irqchip: GICv3: ITS: irqchip implementation The usual methods that are used to present an irqchip to the rest of the kernel Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-6-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index a5ab12c7d7fc..d24bebdfb064 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -40,6 +40,8 @@ #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) +#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) + /* * Collection structure - just an ID, and a redistributor address to * ping. We use one per CPU as a bag of interrupts assigned to this @@ -509,3 +511,78 @@ static void its_send_invall(struct its_node *its, struct its_collection *col) its_send_single_command(its, its_build_invall_cmd, &desc); } + +/* + * irqchip functions - assumes MSI, mostly. + */ + +static inline u32 its_get_event_id(struct irq_data *d) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + return d->hwirq - its_dev->lpi_base; +} + +static void lpi_set_config(struct irq_data *d, bool enable) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = d->hwirq; + u32 id = its_get_event_id(d); + u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192; + + if (enable) + *cfg |= LPI_PROP_ENABLED; + else + *cfg &= ~LPI_PROP_ENABLED; + + /* + * Make the above write visible to the redistributors. + * And yes, we're flushing exactly: One. Single. Byte. + * Humpf... + */ + if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING) + __flush_dcache_area(cfg, sizeof(*cfg)); + else + dsb(ishst); + its_send_inv(its_dev, id); +} + +static void its_mask_irq(struct irq_data *d) +{ + lpi_set_config(d, false); +} + +static void its_unmask_irq(struct irq_data *d) +{ + lpi_set_config(d, true); +} + +static void its_eoi_irq(struct irq_data *d) +{ + gic_write_eoir(d->hwirq); +} + +static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, + bool force) +{ + unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + struct its_collection *target_col; + u32 id = its_get_event_id(d); + + if (cpu >= nr_cpu_ids) + return -EINVAL; + + target_col = &its_dev->its->collections[cpu]; + its_send_movi(its_dev, target_col, id); + its_dev->collection = target_col; + + return IRQ_SET_MASK_OK_DONE; +} + +static struct irq_chip its_irq_chip = { + .name = "ITS", + .irq_mask = its_mask_irq, + .irq_unmask = its_unmask_irq, + .irq_eoi = its_eoi_irq, + .irq_set_affinity = its_set_affinity, +}; -- GitLab From bf9529f8c80c2ec61eacb677eba06a6bd0466be2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:13 +0000 Subject: [PATCH 6612/9457] irqchip: GICv3: ITS: LPI allocator LPIs are the type of interrupts that are used by the ITS. Given the size of the namespace (anywhere between 16 and 32bit), interrupt IDs are allocated in chunks of 32. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-7-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 103 +++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d24bebdfb064..4154a1613dba 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -586,3 +586,106 @@ static struct irq_chip its_irq_chip = { .irq_eoi = its_eoi_irq, .irq_set_affinity = its_set_affinity, }; + +/* + * How we allocate LPIs: + * + * The GIC has id_bits bits for interrupt identifiers. From there, we + * must subtract 8192 which are reserved for SGIs/PPIs/SPIs. Then, as + * we allocate LPIs by chunks of 32, we can shift the whole thing by 5 + * bits to the right. + * + * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. + */ +#define IRQS_PER_CHUNK_SHIFT 5 +#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) + +static unsigned long *lpi_bitmap; +static u32 lpi_chunks; +static DEFINE_SPINLOCK(lpi_lock); + +static int its_lpi_to_chunk(int lpi) +{ + return (lpi - 8192) >> IRQS_PER_CHUNK_SHIFT; +} + +static int its_chunk_to_lpi(int chunk) +{ + return (chunk << IRQS_PER_CHUNK_SHIFT) + 8192; +} + +static int its_lpi_init(u32 id_bits) +{ + lpi_chunks = its_lpi_to_chunk(1UL << id_bits); + + lpi_bitmap = kzalloc(BITS_TO_LONGS(lpi_chunks) * sizeof(long), + GFP_KERNEL); + if (!lpi_bitmap) { + lpi_chunks = 0; + return -ENOMEM; + } + + pr_info("ITS: Allocated %d chunks for LPIs\n", (int)lpi_chunks); + return 0; +} + +static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids) +{ + unsigned long *bitmap = NULL; + int chunk_id; + int nr_chunks; + int i; + + nr_chunks = DIV_ROUND_UP(nr_irqs, IRQS_PER_CHUNK); + + spin_lock(&lpi_lock); + + do { + chunk_id = bitmap_find_next_zero_area(lpi_bitmap, lpi_chunks, + 0, nr_chunks, 0); + if (chunk_id < lpi_chunks) + break; + + nr_chunks--; + } while (nr_chunks > 0); + + if (!nr_chunks) + goto out; + + bitmap = kzalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * sizeof (long), + GFP_ATOMIC); + if (!bitmap) + goto out; + + for (i = 0; i < nr_chunks; i++) + set_bit(chunk_id + i, lpi_bitmap); + + *base = its_chunk_to_lpi(chunk_id); + *nr_ids = nr_chunks * IRQS_PER_CHUNK; + +out: + spin_unlock(&lpi_lock); + + return bitmap; +} + +static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids) +{ + int lpi; + + spin_lock(&lpi_lock); + + for (lpi = base; lpi < (base + nr_ids); lpi += IRQS_PER_CHUNK) { + int chunk = its_lpi_to_chunk(lpi); + BUG_ON(chunk > lpi_chunks); + if (test_bit(chunk, lpi_bitmap)) { + clear_bit(chunk, lpi_bitmap); + } else { + pr_err("Bad LPI chunk %d\n", chunk); + } + } + + spin_unlock(&lpi_lock); + + kfree(bitmap); +} -- GitLab From 1ac19ca6bf97392a3a631551bac223893d24d21f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:14 +0000 Subject: [PATCH 6613/9457] irqchip: GICv3: ITS: tables allocators The interrupt translation is driven by a set of tables (device, ITT, and collection) to be in the end delivered to a CPU. Also, the redistributors rely on a couple of tables (configuration, and pending) to deliver the interrupts to the CPUs. This patch adds the required allocators for these tables. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-8-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 292 +++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 4154a1613dba..03f9831da7b1 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -91,6 +91,14 @@ struct its_device { u32 device_id; }; +static LIST_HEAD(its_nodes); +static DEFINE_SPINLOCK(its_lock); +static struct device_node *gic_root_node; +static struct rdists *gic_rdists; + +#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) +#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) + /* * ITS command descriptors - parameters to be encoded in a command * block. @@ -689,3 +697,287 @@ static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids) kfree(bitmap); } + +/* + * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to + * deal with (one configuration byte per interrupt). PENDBASE has to + * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI). + */ +#define LPI_PROPBASE_SZ SZ_64K +#define LPI_PENDBASE_SZ (LPI_PROPBASE_SZ / 8 + SZ_1K) + +/* + * This is how many bits of ID we need, including the useless ones. + */ +#define LPI_NRBITS ilog2(LPI_PROPBASE_SZ + SZ_8K) + +#define LPI_PROP_DEFAULT_PRIO 0xa0 + +static int __init its_alloc_lpi_tables(void) +{ + phys_addr_t paddr; + + gic_rdists->prop_page = alloc_pages(GFP_NOWAIT, + get_order(LPI_PROPBASE_SZ)); + if (!gic_rdists->prop_page) { + pr_err("Failed to allocate PROPBASE\n"); + return -ENOMEM; + } + + paddr = page_to_phys(gic_rdists->prop_page); + pr_info("GIC: using LPI property table @%pa\n", &paddr); + + /* Priority 0xa0, Group-1, disabled */ + memset(page_address(gic_rdists->prop_page), + LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1, + LPI_PROPBASE_SZ); + + /* Make sure the GIC will observe the written configuration */ + __flush_dcache_area(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ); + + return 0; +} + +static const char *its_base_type_string[] = { + [GITS_BASER_TYPE_DEVICE] = "Devices", + [GITS_BASER_TYPE_VCPU] = "Virtual CPUs", + [GITS_BASER_TYPE_CPU] = "Physical CPUs", + [GITS_BASER_TYPE_COLLECTION] = "Interrupt Collections", + [GITS_BASER_TYPE_RESERVED5] = "Reserved (5)", + [GITS_BASER_TYPE_RESERVED6] = "Reserved (6)", + [GITS_BASER_TYPE_RESERVED7] = "Reserved (7)", +}; + +static void its_free_tables(struct its_node *its) +{ + int i; + + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + if (its->tables[i]) { + free_page((unsigned long)its->tables[i]); + its->tables[i] = NULL; + } + } +} + +static int its_alloc_tables(struct its_node *its) +{ + int err; + int i; + int psz = PAGE_SIZE; + u64 shr = GITS_BASER_InnerShareable; + + for (i = 0; i < GITS_BASER_NR_REGS; i++) { + u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); + u64 type = GITS_BASER_TYPE(val); + u64 entry_size = GITS_BASER_ENTRY_SIZE(val); + u64 tmp; + void *base; + + if (type == GITS_BASER_TYPE_NONE) + continue; + + /* We're lazy and only allocate a single page for now */ + base = (void *)get_zeroed_page(GFP_KERNEL); + if (!base) { + err = -ENOMEM; + goto out_free; + } + + its->tables[i] = base; + +retry_baser: + val = (virt_to_phys(base) | + (type << GITS_BASER_TYPE_SHIFT) | + ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | + GITS_BASER_WaWb | + shr | + GITS_BASER_VALID); + + switch (psz) { + case SZ_4K: + val |= GITS_BASER_PAGE_SIZE_4K; + break; + case SZ_16K: + val |= GITS_BASER_PAGE_SIZE_16K; + break; + case SZ_64K: + val |= GITS_BASER_PAGE_SIZE_64K; + break; + } + + val |= (PAGE_SIZE / psz) - 1; + + writeq_relaxed(val, its->base + GITS_BASER + i * 8); + tmp = readq_relaxed(its->base + GITS_BASER + i * 8); + + if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) { + /* + * Shareability didn't stick. Just use + * whatever the read reported, which is likely + * to be the only thing this redistributor + * supports. + */ + shr = tmp & GITS_BASER_SHAREABILITY_MASK; + goto retry_baser; + } + + if ((val ^ tmp) & GITS_BASER_PAGE_SIZE_MASK) { + /* + * Page size didn't stick. Let's try a smaller + * size and retry. If we reach 4K, then + * something is horribly wrong... + */ + switch (psz) { + case SZ_16K: + psz = SZ_4K; + goto retry_baser; + case SZ_64K: + psz = SZ_16K; + goto retry_baser; + } + } + + if (val != tmp) { + pr_err("ITS: %s: GITS_BASER%d doesn't stick: %lx %lx\n", + its->msi_chip.of_node->full_name, i, + (unsigned long) val, (unsigned long) tmp); + err = -ENXIO; + goto out_free; + } + + pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n", + (int)(PAGE_SIZE / entry_size), + its_base_type_string[type], + (unsigned long)virt_to_phys(base), + psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT); + } + + return 0; + +out_free: + its_free_tables(its); + + return err; +} + +static int its_alloc_collections(struct its_node *its) +{ + its->collections = kzalloc(nr_cpu_ids * sizeof(*its->collections), + GFP_KERNEL); + if (!its->collections) + return -ENOMEM; + + return 0; +} + +static void its_cpu_init_lpis(void) +{ + void __iomem *rbase = gic_data_rdist_rd_base(); + struct page *pend_page; + u64 val, tmp; + + /* If we didn't allocate the pending table yet, do it now */ + pend_page = gic_data_rdist()->pend_page; + if (!pend_page) { + phys_addr_t paddr; + /* + * The pending pages have to be at least 64kB aligned, + * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below. + */ + pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO, + get_order(max(LPI_PENDBASE_SZ, SZ_64K))); + if (!pend_page) { + pr_err("Failed to allocate PENDBASE for CPU%d\n", + smp_processor_id()); + return; + } + + /* Make sure the GIC will observe the zero-ed page */ + __flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ); + + paddr = page_to_phys(pend_page); + pr_info("CPU%d: using LPI pending table @%pa\n", + smp_processor_id(), &paddr); + gic_data_rdist()->pend_page = pend_page; + } + + /* Disable LPIs */ + val = readl_relaxed(rbase + GICR_CTLR); + val &= ~GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + + /* + * Make sure any change to the table is observable by the GIC. + */ + dsb(sy); + + /* set PROPBASE */ + val = (page_to_phys(gic_rdists->prop_page) | + GICR_PROPBASER_InnerShareable | + GICR_PROPBASER_WaWb | + ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); + + writeq_relaxed(val, rbase + GICR_PROPBASER); + tmp = readq_relaxed(rbase + GICR_PROPBASER); + + if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { + pr_info_once("GIC: using cache flushing for LPI property table\n"); + gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; + } + + /* set PENDBASE */ + val = (page_to_phys(pend_page) | + GICR_PROPBASER_InnerShareable | + GICR_PROPBASER_WaWb); + + writeq_relaxed(val, rbase + GICR_PENDBASER); + + /* Enable LPIs */ + val = readl_relaxed(rbase + GICR_CTLR); + val |= GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + + /* Make sure the GIC has seen the above */ + dsb(sy); +} + +static void its_cpu_init_collection(void) +{ + struct its_node *its; + int cpu; + + spin_lock(&its_lock); + cpu = smp_processor_id(); + + list_for_each_entry(its, &its_nodes, entry) { + u64 target; + + /* + * We now have to bind each collection to its target + * redistributor. + */ + if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) { + /* + * This ITS wants the physical address of the + * redistributor. + */ + target = gic_data_rdist()->phys_base; + } else { + /* + * This ITS wants a linear CPU number. + */ + target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER); + target = GICR_TYPER_CPU_NUMBER(target); + } + + /* Perform collection mapping */ + its->collections[cpu].target_address = target; + its->collections[cpu].col_id = cpu; + + its_send_mapc(its, &its->collections[cpu], 1); + its_send_invall(its, &its->collections[cpu]); + } + + spin_unlock(&its_lock); +} -- GitLab From 84a6a2e7fc18dae444c5c88cc6af8878552867a5 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:15 +0000 Subject: [PATCH 6614/9457] irqchip: GICv3: ITS: device allocation and configuration The ITS has a notion of "device" that can write to it in order to generate an interrupt. Conversly, the driver maintains a per-ITS list of devices, together with their configuration information, and uses this to configure the HW. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-9-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 03f9831da7b1..d687fd43fbbb 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -981,3 +981,77 @@ static void its_cpu_init_collection(void) spin_unlock(&its_lock); } + +static struct its_device *its_find_device(struct its_node *its, u32 dev_id) +{ + struct its_device *its_dev = NULL, *tmp; + + raw_spin_lock(&its->lock); + + list_for_each_entry(tmp, &its->its_device_list, entry) { + if (tmp->device_id == dev_id) { + its_dev = tmp; + break; + } + } + + raw_spin_unlock(&its->lock); + + return its_dev; +} + +static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + int nvecs) +{ + struct its_device *dev; + unsigned long *lpi_map; + void *itt; + int lpi_base; + int nr_lpis; + int cpu; + int sz; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + sz = nvecs * its->ite_size; + sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; + itt = kmalloc(sz, GFP_KERNEL); + lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); + + if (!dev || !itt || !lpi_map) { + kfree(dev); + kfree(itt); + kfree(lpi_map); + return NULL; + } + + dev->its = its; + dev->itt = itt; + dev->nr_ites = nvecs; + dev->lpi_map = lpi_map; + dev->lpi_base = lpi_base; + dev->nr_lpis = nr_lpis; + dev->device_id = dev_id; + INIT_LIST_HEAD(&dev->entry); + + raw_spin_lock(&its->lock); + list_add(&dev->entry, &its->its_device_list); + raw_spin_unlock(&its->lock); + + /* Bind the device to the first possible CPU */ + cpu = cpumask_first(cpu_online_mask); + dev->collection = &its->collections[cpu]; + + /* Map device to its ITT */ + its_send_mapd(dev, 1); + + return dev; +} + +static void its_free_device(struct its_device *its_dev) +{ + raw_spin_lock(&its_dev->its->lock); + list_del(&its_dev->entry); + raw_spin_unlock(&its_dev->its->lock); + kfree(its_dev->itt); + kfree(its_dev); +} -- GitLab From b48ac83d6bbc20a973c3e8133fd1ebda873d026a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:16 +0000 Subject: [PATCH 6615/9457] irqchip: GICv3: ITS: MSI support Now, the bit of code that allow us to use the ITS as a MSI controller. Both MSI and MSI-X are supported. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-10-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 176 +++++++++++++++++++++++++++++ include/linux/irqchip/arm-gic-v3.h | 6 + 2 files changed, 182 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d687fd43fbbb..532c6df89992 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -587,12 +587,47 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val, return IRQ_SET_MASK_OK_DONE; } +static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) +{ + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + struct its_node *its; + u64 addr; + + its = its_dev->its; + addr = its->phys_base + GITS_TRANSLATER; + + msg->address_lo = addr & ((1UL << 32) - 1); + msg->address_hi = addr >> 32; + msg->data = its_get_event_id(d); +} + static struct irq_chip its_irq_chip = { .name = "ITS", .irq_mask = its_mask_irq, .irq_unmask = its_unmask_irq, .irq_eoi = its_eoi_irq, .irq_set_affinity = its_set_affinity, + .irq_compose_msi_msg = its_irq_compose_msi_msg, +}; + +static void its_mask_msi_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void its_unmask_msi_irq(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip its_msi_irq_chip = { + .name = "ITS-MSI", + .irq_unmask = its_unmask_msi_irq, + .irq_mask = its_mask_msi_irq, + .irq_eoi = irq_chip_eoi_parent, + .irq_write_msi_msg = pci_msi_domain_write_msg, }; /* @@ -1055,3 +1090,144 @@ static void its_free_device(struct its_device *its_dev) kfree(its_dev->itt); kfree(its_dev); } + +static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) +{ + int idx; + + idx = find_first_zero_bit(dev->lpi_map, dev->nr_lpis); + if (idx == dev->nr_lpis) + return -ENOSPC; + + *hwirq = dev->lpi_base + idx; + set_bit(idx, dev->lpi_map); + + /* Map the GIC irq ID to the device */ + its_send_mapvi(dev, *hwirq, idx); + + return 0; +} + +static int its_msi_prepare(struct irq_domain *domain, struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + struct pci_dev *pdev; + struct its_node *its; + u32 dev_id; + struct its_device *its_dev; + + if (!dev_is_pci(dev)) + return -EINVAL; + + pdev = to_pci_dev(dev); + dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn); + its = domain->parent->host_data; + + its_dev = its_find_device(its, dev_id); + if (WARN_ON(its_dev)) + return -EINVAL; + + its_dev = its_create_device(its, dev_id, nvec); + if (!its_dev) + return -ENOMEM; + + dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec)); + + info->scratchpad[0].ptr = its_dev; + info->scratchpad[1].ptr = dev; + return 0; +} + +static struct msi_domain_ops its_pci_msi_ops = { + .msi_prepare = its_msi_prepare, +}; + +static struct msi_domain_info its_pci_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), + .ops = &its_pci_msi_ops, + .chip = &its_msi_irq_chip, +}; + +static int its_irq_gic_domain_alloc(struct irq_domain *domain, + unsigned int virq, + irq_hw_number_t hwirq) +{ + struct of_phandle_args args; + + args.np = domain->parent->of_node; + args.args_count = 3; + args.args[0] = GIC_IRQ_TYPE_LPI; + args.args[1] = hwirq; + args.args[2] = IRQ_TYPE_EDGE_RISING; + + return irq_domain_alloc_irqs_parent(domain, virq, 1, &args); +} + +static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + msi_alloc_info_t *info = args; + struct its_device *its_dev = info->scratchpad[0].ptr; + irq_hw_number_t hwirq; + int err; + int i; + + for (i = 0; i < nr_irqs; i++) { + err = its_alloc_device_irq(its_dev, &hwirq); + if (err) + return err; + + err = its_irq_gic_domain_alloc(domain, virq + i, hwirq); + if (err) + return err; + + irq_domain_set_hwirq_and_chip(domain, virq + i, + hwirq, &its_irq_chip, its_dev); + dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n", + (int)(hwirq - its_dev->lpi_base), (int)hwirq, virq + i); + } + + return 0; +} + +static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct its_device *its_dev = irq_data_get_irq_chip_data(d); + int i; + + for (i = 0; i < nr_irqs; i++) { + struct irq_data *data = irq_domain_get_irq_data(domain, + virq + i); + int event = its_get_event_id(data); + + /* Stop the delivery of interrupts */ + its_send_discard(its_dev, event); + + /* Mark interrupt index as unused */ + clear_bit(event, its_dev->lpi_map); + + /* Nuke the entry in the domain */ + irq_domain_reset_irq_data(d); + } + + /* If all interrupts have been freed, start mopping the floor */ + if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) { + its_lpi_free(its_dev->lpi_map, + its_dev->lpi_base, + its_dev->nr_lpis); + + /* Unmap device/itt */ + its_send_mapd(its_dev, 0); + its_free_device(its_dev); + } + + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + +static const struct irq_domain_ops its_domain_ops = { + .alloc = its_irq_domain_alloc, + .free = its_irq_domain_free, +}; diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 21c9d70426d1..0ed30d7d9338 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -295,6 +295,12 @@ #include +/* + * We need a value to serve as a irq-type for LPIs. Choose one that will + * hopefully pique the interest of the reviewer. + */ +#define GIC_IRQ_TYPE_LPI 0xa110c8ed + struct rdists { struct { void __iomem *rd_base; -- GitLab From 4c21f3c26ecc25c5520628eef8e900a36e6c6ab4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:17 +0000 Subject: [PATCH 6616/9457] irqchip: GICv3: ITS: DT probing and initialization Add the code that probes the ITS from the device tree, and initialize it. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-11-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3-its.c | 169 +++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 532c6df89992..e9d16151eed6 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1231,3 +1231,172 @@ static const struct irq_domain_ops its_domain_ops = { .alloc = its_irq_domain_alloc, .free = its_irq_domain_free, }; + +static int its_probe(struct device_node *node, struct irq_domain *parent) +{ + struct resource res; + struct its_node *its; + void __iomem *its_base; + u32 val; + u64 baser, tmp; + int err; + + err = of_address_to_resource(node, 0, &res); + if (err) { + pr_warn("%s: no regs?\n", node->full_name); + return -ENXIO; + } + + its_base = ioremap(res.start, resource_size(&res)); + if (!its_base) { + pr_warn("%s: unable to map registers\n", node->full_name); + return -ENOMEM; + } + + val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK; + if (val != 0x30 && val != 0x40) { + pr_warn("%s: no ITS detected, giving up\n", node->full_name); + err = -ENODEV; + goto out_unmap; + } + + pr_info("ITS: %s\n", node->full_name); + + its = kzalloc(sizeof(*its), GFP_KERNEL); + if (!its) { + err = -ENOMEM; + goto out_unmap; + } + + raw_spin_lock_init(&its->lock); + INIT_LIST_HEAD(&its->entry); + INIT_LIST_HEAD(&its->its_device_list); + its->base = its_base; + its->phys_base = res.start; + its->msi_chip.of_node = node; + its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; + + its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); + if (!its->cmd_base) { + err = -ENOMEM; + goto out_free_its; + } + its->cmd_write = its->cmd_base; + + err = its_alloc_tables(its); + if (err) + goto out_free_cmd; + + err = its_alloc_collections(its); + if (err) + goto out_free_tables; + + baser = (virt_to_phys(its->cmd_base) | + GITS_CBASER_WaWb | + GITS_CBASER_InnerShareable | + (ITS_CMD_QUEUE_SZ / SZ_4K - 1) | + GITS_CBASER_VALID); + + writeq_relaxed(baser, its->base + GITS_CBASER); + tmp = readq_relaxed(its->base + GITS_CBASER); + writeq_relaxed(0, its->base + GITS_CWRITER); + writel_relaxed(1, its->base + GITS_CTLR); + + if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) { + pr_info("ITS: using cache flushing for cmd queue\n"); + its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; + } + + if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { + its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); + if (!its->domain) { + err = -ENOMEM; + goto out_free_tables; + } + + its->domain->parent = parent; + + its->msi_chip.domain = pci_msi_create_irq_domain(node, + &its_pci_msi_domain_info, + its->domain); + if (!its->msi_chip.domain) { + err = -ENOMEM; + goto out_free_domains; + } + + err = of_pci_msi_chip_add(&its->msi_chip); + if (err) + goto out_free_domains; + } + + spin_lock(&its_lock); + list_add(&its->entry, &its_nodes); + spin_unlock(&its_lock); + + return 0; + +out_free_domains: + if (its->msi_chip.domain) + irq_domain_remove(its->msi_chip.domain); + if (its->domain) + irq_domain_remove(its->domain); +out_free_tables: + its_free_tables(its); +out_free_cmd: + kfree(its->cmd_base); +out_free_its: + kfree(its); +out_unmap: + iounmap(its_base); + pr_err("ITS: failed probing %s (%d)\n", node->full_name, err); + return err; +} + +static bool gic_rdists_supports_plpis(void) +{ + return !!(readl_relaxed(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); +} + +int its_cpu_init(void) +{ + if (!gic_rdists_supports_plpis()) { + pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); + return -ENXIO; + } + + if (!list_empty(&its_nodes)) { + its_cpu_init_lpis(); + its_cpu_init_collection(); + } + + return 0; +} + +static struct of_device_id its_device_id[] = { + { .compatible = "arm,gic-v3-its", }, + {}, +}; + +int its_init(struct device_node *node, struct rdists *rdists, + struct irq_domain *parent_domain) +{ + struct device_node *np; + + for (np = of_find_matching_node(node, its_device_id); np; + np = of_find_matching_node(np, its_device_id)) { + its_probe(np, parent_domain); + } + + if (list_empty(&its_nodes)) { + pr_warn("ITS: No ITS available, not enabling LPIs\n"); + return -ENXIO; + } + + gic_rdists = rdists; + gic_root_node = node; + + its_alloc_lpi_tables(); + its_lpi_init(rdists->id_bits); + + return 0; +} -- GitLab From da33f31de3e1eebb198109c1cccdc3a094e369c4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:18 +0000 Subject: [PATCH 6617/9457] irqchip: GICv3: ITS: plug ITS init into main GICv3 code As the ITS is always a subsystem if GICv3, its probing/init is driven by the main GICv3 code. Plug that code in (guarded by a config option). Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-12-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3.c | 41 +++++++++++++++++++++++++----- include/linux/irqchip/arm-gic-v3.h | 5 ++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 43e57da0d80e..1a146ccee701 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -76,9 +76,6 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) if (d->hwirq <= 1023) /* SPI -> dist_base */ return gic_data.dist_base; - if (d->hwirq >= 8192) - BUG(); /* LPI Detected!!! */ - return NULL; } @@ -276,11 +273,11 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs do { irqnr = gic_read_iar(); - if (likely(irqnr > 15 && irqnr < 1020)) { + if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) { int err; err = handle_domain_irq(gic_data.domain, irqnr, regs); if (err) { - WARN_ONCE(true, "Unexpected SPI received!\n"); + WARN_ONCE(true, "Unexpected interrupt received!\n"); gic_write_eoir(irqnr); } continue; @@ -393,6 +390,11 @@ static void gic_cpu_sys_reg_init(void) gic_write_grpen1(1); } +static int gic_dist_supports_lpis(void) +{ + return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS); +} + static void gic_cpu_init(void) { void __iomem *rbase; @@ -407,6 +409,10 @@ static void gic_cpu_init(void) gic_cpu_config(rbase, gic_redist_wait_for_rwp); + /* Give LPIs a spin */ + if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) + its_cpu_init(); + /* initialise system registers */ gic_cpu_sys_reg_init(); } @@ -593,12 +599,21 @@ static struct irq_chip gic_chip = { .irq_set_affinity = gic_set_affinity, }; +#define GIC_ID_NR (1U << gic_data.rdists.id_bits) + static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { /* SGIs are private to the core kernel */ if (hw < 16) return -EPERM; + /* Nothing here */ + if (hw >= gic_data.irq_nr && hw < 8192) + return -EPERM; + /* Off limits */ + if (hw >= GIC_ID_NR) + return -EPERM; + /* PPIs */ if (hw < 32) { irq_set_percpu_devid(irq); @@ -612,7 +627,15 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - irq_set_chip_data(irq, d->host_data); + /* LPIs */ + if (hw >= 8192 && hw < GIC_ID_NR) { + if (!gic_dist_supports_lpis()) + return -EPERM; + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); + set_irq_flags(irq, IRQF_VALID); + } + return 0; } @@ -633,6 +656,9 @@ static int gic_irq_domain_xlate(struct irq_domain *d, case 1: /* PPI */ *out_hwirq = intspec[1] + 16; break; + case GIC_IRQ_TYPE_LPI: /* LPI */ + *out_hwirq = intspec[1]; + break; default: return -EINVAL; } @@ -759,6 +785,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare set_handle_irq(gic_handle_irq); + if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) + its_init(node, &gic_data.rdists, gic_data.domain); + gic_smp_init(); gic_dist_init(); gic_cpu_init(); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 0ed30d7d9338..1e8b0cf30792 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -318,6 +318,11 @@ static inline void gic_write_eoir(u64 irq) isb(); } +struct irq_domain; +int its_cpu_init(void); +int its_init(struct device_node *node, struct rdists *rdists, + struct irq_domain *domain); + #endif #endif -- GitLab From 1981272912c211d668c0f62ffee4f5acc55c3bdd Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:19 +0000 Subject: [PATCH 6618/9457] irqchip: GICv3: ITS: enable compilation of the ITS driver Get the show on the road... Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-13-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm64/Kconfig | 1 + drivers/irqchip/Kconfig | 4 ++++ drivers/irqchip/Makefile | 1 + 3 files changed, 6 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ac9afde76dea..1f49c288457b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -13,6 +13,7 @@ config ARM64 select ARM_GIC select AUDIT_ARCH_COMPAT_GENERIC select ARM_GIC_V3 + select ARM_GIC_V3_ITS if PCI_MSI select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS select COMMON_CLK diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 4631685dfe43..aaa260b89a2a 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -16,6 +16,10 @@ config ARM_GIC_V3 select MULTI_IRQ_HANDLER select IRQ_DOMAIN_HIERARCHY +config ARM_GIC_V3_ITS + bool + select PCI_MSI_IRQ_DOMAIN + config ARM_NVIC bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 173bb5fa2cc9..ec3621d5ca87 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o +obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o -- GitLab From b3a92e2c4441affceca9e05905723532e4a61e4d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 Nov 2014 14:35:20 +0000 Subject: [PATCH 6619/9457] irqchip: GICv3: Binding updates for ITS Add the documentation for the bindings describing the GICv3 ITS. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416839720-18400-14-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- .../devicetree/bindings/arm/gic-v3.txt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/gic-v3.txt b/Documentation/devicetree/bindings/arm/gic-v3.txt index 33cd05e6c125..ddfade40ac59 100644 --- a/Documentation/devicetree/bindings/arm/gic-v3.txt +++ b/Documentation/devicetree/bindings/arm/gic-v3.txt @@ -49,11 +49,29 @@ Optional occupied by the redistributors. Required if more than one such region is present. +Sub-nodes: + +GICv3 has one or more Interrupt Translation Services (ITS) that are +used to route Message Signalled Interrupts (MSI) to the CPUs. + +These nodes must have the following properties: +- compatible : Should at least contain "arm,gic-v3-its". +- msi-controller : Boolean property. Identifies the node as an MSI controller +- reg: Specifies the base physical address and size of the ITS + registers. + +The main GIC node must contain the appropriate #address-cells, +#size-cells and ranges properties for the reg property of all ITS +nodes. + Examples: gic: interrupt-controller@2cf00000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; interrupt-controller; reg = <0x0 0x2f000000 0 0x10000>, // GICD <0x0 0x2f100000 0 0x200000>, // GICR @@ -61,11 +79,20 @@ Examples: <0x0 0x2c010000 0 0x2000>, // GICH <0x0 0x2c020000 0 0x2000>; // GICV interrupts = <1 9 4>; + + gic-its@2c200000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2c200000 0 0x200000>; + }; }; gic: interrupt-controller@2c010000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; interrupt-controller; redistributor-stride = <0x0 0x40000>; // 256kB stride #redistributor-regions = <2>; @@ -76,4 +103,16 @@ Examples: <0x0 0x2c060000 0 0x2000>, // GICH <0x0 0x2c080000 0 0x2000>; // GICV interrupts = <1 9 4>; + + gic-its@2c200000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2c200000 0 0x200000>; + }; + + gic-its@2c400000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2c400000 0 0x200000>; + }; }; -- GitLab From 9a1091ef0017c40ab63e7fc0326b2dcfd4dde3a4 Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Tue, 25 Nov 2014 16:04:19 +0800 Subject: [PATCH 6620/9457] irqchip: gic: Support hierarchy irq domain. Add support to use gic as a parent for stacked irq domain. Signed-off-by: Yingjoe Chen Acked-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416902662-19281-2-git-send-email-yingjoe.chen@mediatek.com Signed-off-by: Jason Cooper --- drivers/irqchip/Kconfig | 1 + drivers/irqchip/irq-gic.c | 77 +++++++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index aaa260b89a2a..d47fa846763b 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -5,6 +5,7 @@ config IRQCHIP config ARM_GIC bool select IRQ_DOMAIN + select IRQ_DOMAIN_HIERARCHY select MULTI_IRQ_HANDLER config GIC_NON_BANKED diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 38493ff28fa5..ab6069b09c94 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -788,17 +788,16 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, { if (hw < 32) { irq_set_percpu_devid(irq); - irq_set_chip_and_handler(irq, &gic_chip, - handle_percpu_devid_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_percpu_devid_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); } else { - irq_set_chip_and_handler(irq, &gic_chip, - handle_fasteoi_irq); + irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, + handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); gic_routable_irq_domain_ops->map(d, irq, hw); } - irq_set_chip_data(irq, d->host_data); return 0; } @@ -858,6 +857,31 @@ static struct notifier_block gic_cpu_notifier = { }; #endif +static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i, ret; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + struct of_phandle_args *irq_data = arg; + + ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, + irq_data->args_count, &hwirq, &type); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) + gic_irq_domain_map(domain, virq + i, hwirq + i); + + return 0; +} + +static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { + .xlate = gic_irq_domain_xlate, + .alloc = gic_irq_domain_alloc, + .free = irq_domain_free_irqs_top, +}; + static const struct irq_domain_ops gic_irq_domain_ops = { .map = gic_irq_domain_map, .unmap = gic_irq_domain_unmap, @@ -947,18 +971,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, for (i = 0; i < NR_GIC_CPU_IF; i++) gic_cpu_map[i] = 0xff; - /* - * For primary GICs, skip over SGIs. - * For secondary GICs, skip over PPIs, too. - */ - if (gic_nr == 0 && (irq_start & 31) > 0) { - hwirq_base = 16; - if (irq_start != -1) - irq_start = (irq_start & ~31) + 16; - } else { - hwirq_base = 32; - } - /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources. @@ -969,10 +981,31 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic_irqs = 1020; gic->gic_irqs = gic_irqs; - gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ + if (node) { /* DT case */ + const struct irq_domain_ops *ops = &gic_irq_domain_hierarchy_ops; + + if (!of_property_read_u32(node, "arm,routable-irqs", + &nr_routable_irqs)) { + ops = &gic_irq_domain_ops; + gic_irqs = nr_routable_irqs; + } + + gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic); + } else { /* Non-DT case */ + /* + * For primary GICs, skip over SGIs. + * For secondary GICs, skip over PPIs, too. + */ + if (gic_nr == 0 && (irq_start & 31) > 0) { + hwirq_base = 16; + if (irq_start != -1) + irq_start = (irq_start & ~31) + 16; + } else { + hwirq_base = 32; + } + + gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ - if (of_property_read_u32(node, "arm,routable-irqs", - &nr_routable_irqs)) { irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); if (IS_ERR_VALUE(irq_base)) { @@ -983,10 +1016,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, hwirq_base, &gic_irq_domain_ops, gic); - } else { - gic->domain = irq_domain_add_linear(node, nr_routable_irqs, - &gic_irq_domain_ops, - gic); } if (WARN_ON(!gic->domain)) -- GitLab From 5fe3bba3088c4efab32a18649643b5075755b4b3 Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Tue, 25 Nov 2014 16:04:20 +0800 Subject: [PATCH 6621/9457] irqchip: mtk-sysirq: Add sysirq interrupt polarity support Mediatek SoCs have interrupt polarity support in sysirq which allows to invert polarity for given interrupt. Add this support using hierarchy irq domain. Signed-off-by: Yingjoe Chen Link: https://lkml.kernel.org/r/1416902662-19281-3-git-send-email-yingjoe.chen@mediatek.com Signed-off-by: Jason Cooper --- drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-mtk-sysirq.c | 163 +++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 drivers/irqchip/irq-mtk-sysirq.c diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index ec3621d5ca87..2029e79c07a9 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o \ irq-bcm7120-l2.o obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o +obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c new file mode 100644 index 000000000000..7e342df6a62f --- /dev/null +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Joe.C + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "irqchip.h" + +#define MT6577_SYS_INTPOL_NUM (224) + +struct mtk_sysirq_chip_data { + spinlock_t lock; + void __iomem *intpol_base; +}; + +static int mtk_sysirq_set_type(struct irq_data *data, unsigned int type) +{ + irq_hw_number_t hwirq = data->hwirq; + struct mtk_sysirq_chip_data *chip_data = data->chip_data; + u32 offset, reg_index, value; + unsigned long flags; + int ret; + + offset = hwirq & 0x1f; + reg_index = hwirq >> 5; + + spin_lock_irqsave(&chip_data->lock, flags); + value = readl_relaxed(chip_data->intpol_base + reg_index * 4); + if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) { + if (type == IRQ_TYPE_LEVEL_LOW) + type = IRQ_TYPE_LEVEL_HIGH; + else + type = IRQ_TYPE_EDGE_RISING; + value |= (1 << offset); + } else { + value &= ~(1 << offset); + } + writel(value, chip_data->intpol_base + reg_index * 4); + + data = data->parent_data; + ret = data->chip->irq_set_type(data, type); + spin_unlock_irqrestore(&chip_data->lock, flags); + return ret; +} + +static struct irq_chip mtk_sysirq_chip = { + .name = "MT_SYSIRQ", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_type = mtk_sysirq_set_type, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + +static int mtk_sysirq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (intsize != 3) + return -EINVAL; + + /* sysirq doesn't support PPI */ + if (intspec[0]) + return -EINVAL; + + *out_hwirq = intspec[1]; + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + return 0; +} + +static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + int i; + irq_hw_number_t hwirq; + struct of_phandle_args *irq_data = arg; + struct of_phandle_args gic_data = *irq_data; + + if (irq_data->args_count != 3) + return -EINVAL; + + /* sysirq doesn't support PPI */ + if (irq_data->args[0]) + return -EINVAL; + + hwirq = irq_data->args[1]; + for (i = 0; i < nr_irqs; i++) + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &mtk_sysirq_chip, + domain->host_data); + + gic_data.np = domain->parent->of_node; + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); +} + +static struct irq_domain_ops sysirq_domain_ops = { + .xlate = mtk_sysirq_domain_xlate, + .alloc = mtk_sysirq_domain_alloc, + .free = irq_domain_free_irqs_common, +}; + +static int __init mtk_sysirq_of_init(struct device_node *node, + struct device_node *parent) +{ + struct irq_domain *domain, *domain_parent; + struct mtk_sysirq_chip_data *chip_data; + int ret = 0; + + domain_parent = irq_find_host(parent); + if (!domain_parent) { + pr_err("mtk_sysirq: interrupt-parent not found\n"); + return -EINVAL; + } + + chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); + if (!chip_data) + return -ENOMEM; + + chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); + if (!chip_data->intpol_base) { + pr_err("mtk_sysirq: unable to map sysirq register\n"); + ret = -ENOMEM; + goto out_free; + } + + domain = irq_domain_add_hierarchy(domain_parent, 0, + MT6577_SYS_INTPOL_NUM, node, + &sysirq_domain_ops, chip_data); + if (!domain) { + ret = -ENOMEM; + goto out_unmap; + } + spin_lock_init(&chip_data->lock); + + return 0; + +out_unmap: + iounmap(chip_data->intpol_base); +out_free: + kfree(chip_data); + return ret; +} +IRQCHIP_DECLARE(mtk_sysirq, "mediatek,mt6577-sysirq", mtk_sysirq_of_init); -- GitLab From f4e27e30b3663a8652746d1c7d1649a5fa8c0e6c Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Tue, 25 Nov 2014 16:04:22 +0800 Subject: [PATCH 6622/9457] irqchip: mtk-sysirq: dt-bindings: Add bindings for mediatek sysirq Add binding documentation for Mediatek SoC SYSIRQ. Signed-off-by: Yingjoe Chen Link: https://lkml.kernel.org/r/1416902662-19281-5-git-send-email-yingjoe.chen@mediatek.com Signed-off-by: Jason Cooper --- .../bindings/arm/mediatek/mediatek,sysirq.txt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt new file mode 100644 index 000000000000..d680b07ec6e8 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt @@ -0,0 +1,28 @@ +Mediatek 65xx/81xx sysirq + +Mediatek SOCs sysirq support controllable irq inverter for each GIC SPI +interrupt. + +Required properties: +- compatible: should be one of: + "mediatek,mt8135-sysirq" + "mediatek,mt8127-sysirq" + "mediatek,mt6589-sysirq" + "mediatek,mt6582-sysirq" + "mediatek,mt6577-sysirq" +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Use the same format as specified by GIC in + Documentation/devicetree/bindings/arm/gic.txt +- interrupt-parent: phandle of irq parent for sysirq. The parent must + use the same interrupt-cells format as GIC. +- reg: Physical base address of the intpol registers and length of memory + mapped region. + +Example: + sysirq: interrupt-controller@10200100 { + compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200100 0 0x1c>; + }; -- GitLab From 853a33ce6932601030f550653aea91a0e0a71511 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Tue, 25 Nov 2014 18:47:22 +0000 Subject: [PATCH 6623/9457] irqchip: gic-v2m: Add support for ARM GICv2m MSI(-X) doorbell ARM GICv2m specification extends GICv2 to support MSI(-X) with a new register frame. This allows a GICv2 based system to support MSI with minimal changes. Signed-off-by: Suravee Suthikulpanit [maz: converted the driver to use stacked irq domains, updated changelog] Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416941243-7181-2-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm64/Kconfig | 1 + drivers/irqchip/Kconfig | 6 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic-v2m.c | 333 ++++++++++++++++++++++++++++++++ drivers/irqchip/irq-gic.c | 4 + include/linux/irqchip/arm-gic.h | 2 + 6 files changed, 347 insertions(+) create mode 100644 drivers/irqchip/irq-gic-v2m.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1f49c288457b..e06e1a99eafa 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -12,6 +12,7 @@ config ARM64 select ARM_ARCH_TIMER select ARM_GIC select AUDIT_ARCH_COMPAT_GENERIC + select ARM_GIC_V2M if PCI_MSI select ARM_GIC_V3 select ARM_GIC_V3_ITS if PCI_MSI select BUILDTIME_EXTABLE_SORT diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index d47fa846763b..e72e23960632 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -8,6 +8,12 @@ config ARM_GIC select IRQ_DOMAIN_HIERARCHY select MULTI_IRQ_HANDLER +config ARM_GIC_V2M + bool + depends on ARM_GIC + depends on PCI && PCI_MSI + select PCI_MSI_IRQ_DOMAIN + config GIC_NON_BANKED bool diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 2029e79c07a9..983634d61b25 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o +obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c new file mode 100644 index 000000000000..fdf706555d72 --- /dev/null +++ b/drivers/irqchip/irq-gic-v2m.c @@ -0,0 +1,333 @@ +/* + * ARM GIC v2m MSI(-X) support + * Support for Message Signaled Interrupts for systems that + * implement ARM Generic Interrupt Controller: GICv2m. + * + * Copyright (C) 2014 Advanced Micro Devices, Inc. + * Authors: Suravee Suthikulpanit + * Harish Kasiviswanathan + * Brandon Anderson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#define pr_fmt(fmt) "GICv2m: " fmt + +#include +#include +#include +#include +#include +#include +#include + +/* +* MSI_TYPER: +* [31:26] Reserved +* [25:16] lowest SPI assigned to MSI +* [15:10] Reserved +* [9:0] Numer of SPIs assigned to MSI +*/ +#define V2M_MSI_TYPER 0x008 +#define V2M_MSI_TYPER_BASE_SHIFT 16 +#define V2M_MSI_TYPER_BASE_MASK 0x3FF +#define V2M_MSI_TYPER_NUM_MASK 0x3FF +#define V2M_MSI_SETSPI_NS 0x040 +#define V2M_MIN_SPI 32 +#define V2M_MAX_SPI 1019 + +#define V2M_MSI_TYPER_BASE_SPI(x) \ + (((x) >> V2M_MSI_TYPER_BASE_SHIFT) & V2M_MSI_TYPER_BASE_MASK) + +#define V2M_MSI_TYPER_NUM_SPI(x) ((x) & V2M_MSI_TYPER_NUM_MASK) + +struct v2m_data { + spinlock_t msi_cnt_lock; + struct msi_controller mchip; + struct resource res; /* GICv2m resource */ + void __iomem *base; /* GICv2m virt address */ + u32 spi_start; /* The SPI number that MSIs start */ + u32 nr_spis; /* The number of SPIs for MSIs */ + unsigned long *bm; /* MSI vector bitmap */ + struct irq_domain *domain; +}; + +static void gicv2m_mask_msi_irq(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void gicv2m_unmask_msi_irq(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip gicv2m_msi_irq_chip = { + .name = "MSI", + .irq_mask = gicv2m_mask_msi_irq, + .irq_unmask = gicv2m_unmask_msi_irq, + .irq_eoi = irq_chip_eoi_parent, + .irq_write_msi_msg = pci_msi_domain_write_msg, +}; + +static struct msi_domain_info gicv2m_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSIX), + .chip = &gicv2m_msi_irq_chip, +}; + +static int gicv2m_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) +{ + int ret; + + ret = irq_chip_set_affinity_parent(irq_data, mask, force); + if (ret == IRQ_SET_MASK_OK) + ret = IRQ_SET_MASK_OK_DONE; + + return ret; +} + +static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + struct v2m_data *v2m = irq_data_get_irq_chip_data(data); + phys_addr_t addr = v2m->res.start + V2M_MSI_SETSPI_NS; + + msg->address_hi = (u32) (addr >> 32); + msg->address_lo = (u32) (addr); + msg->data = data->hwirq; +} + +static struct irq_chip gicv2m_irq_chip = { + .name = "GICv2m", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = gicv2m_set_affinity, + .irq_compose_msi_msg = gicv2m_compose_msi_msg, +}; + +static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain, + unsigned int virq, + irq_hw_number_t hwirq) +{ + struct of_phandle_args args; + struct irq_data *d; + int err; + + args.np = domain->parent->of_node; + args.args_count = 3; + args.args[0] = 0; + args.args[1] = hwirq - 32; + args.args[2] = IRQ_TYPE_EDGE_RISING; + + err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args); + if (err) + return err; + + /* Configure the interrupt line to be edge */ + d = irq_domain_get_irq_data(domain->parent, virq); + d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING); + return 0; +} + +static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq) +{ + int pos; + + pos = hwirq - v2m->spi_start; + if (pos < 0 || pos >= v2m->nr_spis) { + pr_err("Failed to teardown msi. Invalid hwirq %d\n", hwirq); + return; + } + + spin_lock(&v2m->msi_cnt_lock); + __clear_bit(pos, v2m->bm); + spin_unlock(&v2m->msi_cnt_lock); +} + +static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + struct v2m_data *v2m = domain->host_data; + int hwirq, offset, err = 0; + + spin_lock(&v2m->msi_cnt_lock); + offset = find_first_zero_bit(v2m->bm, v2m->nr_spis); + if (offset < v2m->nr_spis) + __set_bit(offset, v2m->bm); + else + err = -ENOSPC; + spin_unlock(&v2m->msi_cnt_lock); + + if (err) + return err; + + hwirq = v2m->spi_start + offset; + + err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq); + if (err) { + gicv2m_unalloc_msi(v2m, hwirq); + return err; + } + + irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &gicv2m_irq_chip, v2m); + + return 0; +} + +static void gicv2m_irq_domain_free(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct v2m_data *v2m = irq_data_get_irq_chip_data(d); + + BUG_ON(nr_irqs != 1); + gicv2m_unalloc_msi(v2m, d->hwirq); + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + +static const struct irq_domain_ops gicv2m_domain_ops = { + .alloc = gicv2m_irq_domain_alloc, + .free = gicv2m_irq_domain_free, +}; + +static bool is_msi_spi_valid(u32 base, u32 num) +{ + if (base < V2M_MIN_SPI) { + pr_err("Invalid MSI base SPI (base:%u)\n", base); + return false; + } + + if ((num == 0) || (base + num > V2M_MAX_SPI)) { + pr_err("Number of SPIs (%u) exceed maximum (%u)\n", + num, V2M_MAX_SPI - V2M_MIN_SPI + 1); + return false; + } + + return true; +} + +static int __init gicv2m_init_one(struct device_node *node, + struct irq_domain *parent) +{ + int ret; + struct v2m_data *v2m; + + v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); + if (!v2m) { + pr_err("Failed to allocate struct v2m_data.\n"); + return -ENOMEM; + } + + ret = of_address_to_resource(node, 0, &v2m->res); + if (ret) { + pr_err("Failed to allocate v2m resource.\n"); + goto err_free_v2m; + } + + v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res)); + if (!v2m->base) { + pr_err("Failed to map GICv2m resource\n"); + ret = -ENOMEM; + goto err_free_v2m; + } + + if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) && + !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) { + pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n", + v2m->spi_start, v2m->nr_spis); + } else { + u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER); + + v2m->spi_start = V2M_MSI_TYPER_BASE_SPI(typer); + v2m->nr_spis = V2M_MSI_TYPER_NUM_SPI(typer); + } + + if (!is_msi_spi_valid(v2m->spi_start, v2m->nr_spis)) { + ret = -EINVAL; + goto err_iounmap; + } + + v2m->bm = kzalloc(sizeof(long) * BITS_TO_LONGS(v2m->nr_spis), + GFP_KERNEL); + if (!v2m->bm) { + ret = -ENOMEM; + goto err_iounmap; + } + + v2m->domain = irq_domain_add_tree(NULL, &gicv2m_domain_ops, v2m); + if (!v2m->domain) { + pr_err("Failed to create GICv2m domain\n"); + ret = -ENOMEM; + goto err_free_bm; + } + + v2m->domain->parent = parent; + v2m->mchip.of_node = node; + v2m->mchip.domain = pci_msi_create_irq_domain(node, + &gicv2m_msi_domain_info, + v2m->domain); + if (!v2m->mchip.domain) { + pr_err("Failed to create MSI domain\n"); + ret = -ENOMEM; + goto err_free_domains; + } + + spin_lock_init(&v2m->msi_cnt_lock); + + ret = of_pci_msi_chip_add(&v2m->mchip); + if (ret) { + pr_err("Failed to add msi_chip.\n"); + goto err_free_domains; + } + + pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name, + (unsigned long)v2m->res.start, (unsigned long)v2m->res.end, + v2m->spi_start, (v2m->spi_start + v2m->nr_spis)); + + return 0; + +err_free_domains: + if (v2m->mchip.domain) + irq_domain_remove(v2m->mchip.domain); + if (v2m->domain) + irq_domain_remove(v2m->domain); +err_free_bm: + kfree(v2m->bm); +err_iounmap: + iounmap(v2m->base); +err_free_v2m: + kfree(v2m); + return ret; +} + +static struct of_device_id gicv2m_device_id[] = { + { .compatible = "arm,gic-v2m-frame", }, + {}, +}; + +int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent) +{ + int ret = 0; + struct device_node *child; + + for (child = of_find_matching_node(node, gicv2m_device_id); child; + child = of_find_matching_node(child, gicv2m_device_id)) { + if (!of_find_property(child, "msi-controller", NULL)) + continue; + + ret = gicv2m_init_one(child, parent); + if (ret) { + of_node_put(node); + break; + } + } + + return ret; +} diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index ab6069b09c94..5a71be79786d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -1066,6 +1066,10 @@ gic_of_init(struct device_node *node, struct device_node *parent) irq = irq_of_parse_and_map(node, 0); gic_cascade_irq(gic_cnt, irq); } + + if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) + gicv2m_of_init(node, gic_data[gic_cnt].domain); + gic_cnt++; return 0; } diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 13eed92c7d24..60b09ed58cae 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -106,6 +106,8 @@ static inline void gic_init(unsigned int nr, int start, gic_init_bases(nr, start, dist, cpu, 0, NULL); } +int gicv2m_of_init(struct device_node *node, struct irq_domain *parent); + void gic_send_sgi(unsigned int cpu_id, unsigned int irq); int gic_get_cpu_id(unsigned int cpu); void gic_migrate_target(unsigned int new_cpu_id); -- GitLab From e684e258d831781fd89d2047a272fdb0b0ffe7f4 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Tue, 25 Nov 2014 18:47:23 +0000 Subject: [PATCH 6624/9457] irqchip: gic-v2m: Add DT bindings for GICv2m Update the GIC DT bindings to support GICv2m. Signed-off-by: Suravee Suthikulpanit [maz: split DT patch from main driver, updated changelog] Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1416941243-7181-3-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- Documentation/devicetree/bindings/arm/gic.txt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index c7d2fa156678..375147e5a5fb 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt @@ -96,3 +96,56 @@ Example: <0x2c006000 0x2000>; interrupts = <1 9 0xf04>; }; + + +* GICv2m extension for MSI/MSI-x support (Optional) + +Certain revisions of GIC-400 supports MSI/MSI-x via V2M register frame(s). +This is enabled by specifying v2m sub-node(s). + +Required properties: + +- compatible : The value here should contain "arm,gic-v2m-frame". + +- msi-controller : Identifies the node as an MSI controller. + +- reg : GICv2m MSI interface register base and size + +Optional properties: + +- arm,msi-base-spi : When the MSI_TYPER register contains an incorrect + value, this property should contain the SPI base of + the MSI frame, overriding the HW value. + +- arm,msi-num-spis : When the MSI_TYPER register contains an incorrect + value, this property should contain the number of + SPIs assigned to the frame, overriding the HW value. + +Example: + + interrupt-controller@e1101000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + interrupt-controller; + interrupts = <1 8 0xf04>; + ranges = <0 0 0 0xe1100000 0 0x100000>; + reg = <0x0 0xe1110000 0 0x01000>, + <0x0 0xe112f000 0 0x02000>, + <0x0 0xe1140000 0 0x10000>, + <0x0 0xe1160000 0 0x10000>; + v2m0: v2m@0x8000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x0 0x80000 0 0x1000>; + }; + + .... + + v2mN: v2m@0x9000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x0 0x90000 0 0x1000>; + }; + }; -- GitLab From b1b9891441fa33fd0d49b5cb3aa7f04bca1cc1db Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 16 Sep 2014 13:33:07 -0500 Subject: [PATCH 6625/9457] rpmsg: use less buffers when vrings are small Adjust the number of rpmsg buffers to rely on the size of the vring, instead of using the hard coded value of 512 (256 per direction). This is needed when small vrings are being used, where 256 buffers are too much to fit in a vring. While considering the vring size, keep using the 512 hard coded value as an upper limit to avoid wacky resource tables consuming unreasonable amount of memory. NOTE: The number of buffers is already assumed to be symmetrical in each direction, and that logic is unchanged. Signed-off-by: Suman Anna [edit commit message, small code and comment simplification] Signed-off-by: Ohad Ben-Cohen --- drivers/rpmsg/virtio_rpmsg_bus.c | 44 ++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index b6135d4d54eb..92f6af6da699 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -41,6 +41,7 @@ * @svq: tx virtqueue * @rbufs: kernel address of rx buffers * @sbufs: kernel address of tx buffers + * @num_bufs: total number of buffers for rx and tx * @last_sbuf: index of last tx buffer used * @bufs_dma: dma base addr of the buffers * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. @@ -60,6 +61,7 @@ struct virtproc_info { struct virtio_device *vdev; struct virtqueue *rvq, *svq; void *rbufs, *sbufs; + unsigned int num_bufs; int last_sbuf; dma_addr_t bufs_dma; struct mutex tx_lock; @@ -86,13 +88,14 @@ struct rpmsg_channel_info { #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) /* - * We're allocating 512 buffers of 512 bytes for communications, and then - * using the first 256 buffers for RX, and the last 256 buffers for TX. + * We're allocating buffers of 512 bytes each for communications. The + * number of buffers will be computed from the number of buffers supported + * by the vring, upto a maximum of 512 buffers (256 in each direction). * * Each buffer will have 16 bytes for the msg header and 496 bytes for * the payload. * - * This will require a total space of 256KB for the buffers. + * This will utilize a maximum total space of 256KB for the buffers. * * We might also want to add support for user-provided buffers in time. * This will allow bigger buffer size flexibility, and can also be used @@ -102,9 +105,8 @@ struct rpmsg_channel_info { * can change this without changing anything in the firmware of the remote * processor. */ -#define RPMSG_NUM_BUFS (512) +#define MAX_RPMSG_NUM_BUFS (512) #define RPMSG_BUF_SIZE (512) -#define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE) /* * Local addresses are dynamically allocated on-demand. @@ -579,7 +581,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp) * either pick the next unused tx buffer * (half of our buffers are used for sending messages) */ - if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2) + if (vrp->last_sbuf < vrp->num_bufs / 2) ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; /* or recycle a used one */ else @@ -948,6 +950,7 @@ static int rpmsg_probe(struct virtio_device *vdev) struct virtproc_info *vrp; void *bufs_va; int err = 0, i; + size_t total_buf_space; vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); if (!vrp) @@ -968,10 +971,22 @@ static int rpmsg_probe(struct virtio_device *vdev) vrp->rvq = vqs[0]; vrp->svq = vqs[1]; + /* we expect symmetric tx/rx vrings */ + WARN_ON(virtqueue_get_vring_size(vrp->rvq) != + virtqueue_get_vring_size(vrp->svq)); + + /* we need less buffers if vrings are small */ + if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2) + vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2; + else + vrp->num_bufs = MAX_RPMSG_NUM_BUFS; + + total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE; + /* allocate coherent memory for the buffers */ bufs_va = dma_alloc_coherent(vdev->dev.parent->parent, - RPMSG_TOTAL_BUF_SPACE, - &vrp->bufs_dma, GFP_KERNEL); + total_buf_space, &vrp->bufs_dma, + GFP_KERNEL); if (!bufs_va) { err = -ENOMEM; goto vqs_del; @@ -984,10 +999,10 @@ static int rpmsg_probe(struct virtio_device *vdev) vrp->rbufs = bufs_va; /* and half is dedicated for TX */ - vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2; + vrp->sbufs = bufs_va + total_buf_space / 2; /* set up the receive buffers */ - for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) { + for (i = 0; i < vrp->num_bufs / 2; i++) { struct scatterlist sg; void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; @@ -1023,8 +1038,8 @@ static int rpmsg_probe(struct virtio_device *vdev) return 0; free_coherent: - dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, - bufs_va, vrp->bufs_dma); + dma_free_coherent(vdev->dev.parent->parent, total_buf_space, + bufs_va, vrp->bufs_dma); vqs_del: vdev->config->del_vqs(vrp->vdev); free_vrp: @@ -1042,6 +1057,7 @@ static int rpmsg_remove_device(struct device *dev, void *data) static void rpmsg_remove(struct virtio_device *vdev) { struct virtproc_info *vrp = vdev->priv; + size_t total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE; int ret; vdev->config->reset(vdev); @@ -1057,8 +1073,8 @@ static void rpmsg_remove(struct virtio_device *vdev) vdev->config->del_vqs(vrp->vdev); - dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, - vrp->rbufs, vrp->bufs_dma); + dma_free_coherent(vdev->dev.parent->parent, total_buf_space, + vrp->rbufs, vrp->bufs_dma); kfree(vrp); } -- GitLab From d683d0b690c13437d752ccce47963ac64119b07a Mon Sep 17 00:00:00 2001 From: Krishna Mohan Dani Date: Wed, 26 Nov 2014 14:53:04 +0530 Subject: [PATCH 6626/9457] ASoC: Samsung: Add arndale_rt5631 machine driver and binding Adding machine driver to instantiate I2S based realtek's ALC5631 sound card on Arndale board. There are other variants of Audio Daughter Cards for Arndale Board for which support already exists but there is no support for Realtek's alc5631 codec hence support for ALC5631 based machine driver is being added. This patch also documents the device tree binding for the Arndale board based machine driver. Signed-off-by: Claude Youn Signed-off-by: Krishna Mohan Dani Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/arndale.txt | 24 +++ sound/soc/samsung/Kconfig | 6 + sound/soc/samsung/Makefile | 2 + sound/soc/samsung/arndale_rt5631.c | 150 ++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/arndale.txt create mode 100644 sound/soc/samsung/arndale_rt5631.c diff --git a/Documentation/devicetree/bindings/sound/arndale.txt b/Documentation/devicetree/bindings/sound/arndale.txt new file mode 100644 index 000000000000..0e76946385ae --- /dev/null +++ b/Documentation/devicetree/bindings/sound/arndale.txt @@ -0,0 +1,24 @@ +Audio Binding for Arndale boards + +Required properties: +- compatible : Can be the following, + "samsung,arndale-rt5631" + +- samsung,audio-cpu: The phandle of the Samsung I2S controller +- samsung,audio-codec: The phandle of the audio codec + +Optional: +- samsung,model: The name of the sound-card + +Arndale Boards has many audio daughter cards, one of them is +rt5631/alc5631. Below example shows audio bindings for rt5631/ +alc5631 based codec. + +Example: + +sound { + compatible = "samsung,arndale-rt5631"; + + samsung,audio-cpu = <&i2s0> + samsung,audio-codec = <&rt5631>; +}; diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e0e737faadd9..fc67f97f19f6 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -239,3 +239,9 @@ config SND_SOC_ODROIDX2 select SND_SAMSUNG_I2S help Say Y here to enable audio support for the Odroid-X2/U3. + +config SND_SOC_ARNDALE_RT5631_ALC5631 + tristate "Audio support for RT5631(ALC5631) on Arndale Board" + depends on SND_SOC_SAMSUNG + select SND_SAMSUNG_I2S + select SND_SOC_RT5631 diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 91505ddaaf95..31e3dba7e3b5 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -45,6 +45,7 @@ snd-soc-lowland-objs := lowland.o snd-soc-littlemill-objs := littlemill.o snd-soc-bells-objs := bells.o snd-soc-odroidx2-max98090-objs := odroidx2_max98090.o +snd-soc-arndale-rt5631-objs := arndale_rt5631.o obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o @@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o obj-$(CONFIG_SND_SOC_ODROIDX2) += snd-soc-odroidx2-max98090.o +obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c new file mode 100644 index 000000000000..1e2b61ca8db2 --- /dev/null +++ b/sound/soc/samsung/arndale_rt5631.c @@ -0,0 +1,150 @@ +/* + * arndale_rt5631.c + * + * Copyright (c) 2014, Insignal Co., Ltd. + * + * Author: Claude + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "i2s.h" + +static int arndale_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int rfs, ret; + unsigned long rclk; + + rfs = 256; + + rclk = params_rate(params) * rfs; + + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_OUT); + + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk, SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops arndale_ops = { + .hw_params = arndale_hw_params, +}; + +static struct snd_soc_dai_link arndale_rt5631_dai[] = { + { + .name = "RT5631 HiFi", + .stream_name = "Primary", + .codec_dai_name = "rt5631-hifi", + .dai_fmt = SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .ops = &arndale_ops, + }, +}; + +static struct snd_soc_card arndale_rt5631 = { + .name = "Arndale RT5631", + .dai_link = arndale_rt5631_dai, + .num_links = ARRAY_SIZE(arndale_rt5631_dai), +}; + +static int arndale_audio_probe(struct platform_device *pdev) +{ + int n, ret; + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &arndale_rt5631; + + card->dev = &pdev->dev; + + for (n = 0; np && n < ARRAY_SIZE(arndale_rt5631_dai); n++) { + if (!arndale_rt5631_dai[n].cpu_dai_name) { + arndale_rt5631_dai[n].cpu_of_node = of_parse_phandle(np, + "samsung,audio-cpu", n); + + if (!arndale_rt5631_dai[n].cpu_of_node) { + dev_err(&pdev->dev, + "Property 'samsung,audio-cpu' missing or invalid\n"); + return -EINVAL; + } + } + if (!arndale_rt5631_dai[n].platform_name) + arndale_rt5631_dai[n].platform_of_node = + arndale_rt5631_dai[n].cpu_of_node; + + arndale_rt5631_dai[n].codec_name = NULL; + arndale_rt5631_dai[n].codec_of_node = of_parse_phandle(np, + "samsung,audio-codec", n); + if (!arndale_rt5631_dai[0].codec_of_node) { + dev_err(&pdev->dev, + "Property 'samsung,audio-codec' missing or invalid\n"); + return -EINVAL; + } + } + + ret = devm_snd_soc_register_card(card->dev, card); + + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); + + return ret; +} + +static int arndale_audio_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static const struct of_device_id samsung_arndale_rt5631_of_match[] __maybe_unused = { + { .compatible = "samsung,arndale-rt5631", }, + { .compatible = "samsung,arndale-alc5631", }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_arndale_rt5631_of_match); + +static struct platform_driver arndale_audio_driver = { + .driver = { + .name = "arndale-audio", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), + }, + .probe = arndale_audio_probe, + .remove = arndale_audio_remove, +}; + +module_platform_driver(arndale_audio_driver); + +MODULE_AUTHOR("Claude "); +MODULE_DESCRIPTION("ALSA SoC Driver for Arndale Board"); +MODULE_LICENSE("GPL"); -- GitLab From ced7a04e394fe1df41d13b833baab5cfcb1d03b3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 25 Nov 2014 08:57:29 -0800 Subject: [PATCH 6627/9457] pkt_sched: fq: increase max delay from 125 ms to one second FQ/pacing has a clamp of delay of 125 ms, to avoid some possible harm. It turns out this delay is too small to allow pacing low rates : Some ISP setup very aggressive policers as low as 16kbit. Now TCP stack has spurious rtx prevention, it seems safe to increase this fixed parameter, without adding a qdisc attribute. Signed-off-by: Eric Dumazet Cc: Yang Yingliang Signed-off-by: David S. Miller --- net/sched/sch_fq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index cbd7e1fd23b4..9b05924cc386 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -481,12 +481,11 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch) if (likely(rate)) do_div(len, rate); /* Since socket rate can change later, - * clamp the delay to 125 ms. - * TODO: maybe segment the too big skb, as in commit - * e43ac79a4bc ("sch_tbf: segment too big GSO packets") + * clamp the delay to 1 second. + * Really, providers of too big packets should be fixed ! */ - if (unlikely(len > 125 * NSEC_PER_MSEC)) { - len = 125 * NSEC_PER_MSEC; + if (unlikely(len > NSEC_PER_SEC)) { + len = NSEC_PER_SEC; q->stat_pkts_too_long++; } -- GitLab From 7c967b224a9a7061009ccbc47e1a0b605f1b6d81 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 25 Nov 2014 11:21:19 -0800 Subject: [PATCH 6628/9457] net: Add remcsum_adjust as common function for remote checksum offload This function does the work to update a checksum field as part of remote checksum offload. remcsum_adjust does the following: 1) Subtract out the calculated checksum from the beginning of the packet (ptr arg) to the start offset. 2) Adjust the checksum field indicated by offset based on the modified checksum value from above step. 3) Return the difference in the old checksum field value and the new one. The caller will use this to update skb->csum and NAPI csum. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/net/checksum.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/net/checksum.h b/include/net/checksum.h index 6465bae80a4f..e339a9513e29 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -151,4 +151,20 @@ static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, (__force __be32)to, pseudohdr); } +static inline __wsum remcsum_adjust(void *ptr, __wsum csum, + int start, int offset) +{ + __sum16 *psum = (__sum16 *)(ptr + offset); + __wsum delta; + + /* Subtract out checksum up to start */ + csum = csum_sub(csum, csum_partial(ptr, start, 0)); + + /* Set derived checksum in packet */ + delta = csum_sub(csum_fold(csum), *psum); + *psum = csum_fold(csum); + + return delta; +} + #endif -- GitLab From 4fd671ded14f92cb8db0bf72747f4df508ba5e3d Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 25 Nov 2014 11:21:20 -0800 Subject: [PATCH 6629/9457] gue: Call remcsum_adjust Change remote checksum offload to call remcsum_adjust. This also eliminates the optimization to skip an IP header as part of the adjustment (really does not seem to be much of a win). Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- net/ipv4/fou.c | 84 ++++++++++---------------------------------------- 1 file changed, 17 insertions(+), 67 deletions(-) diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index 3dfe9828e7ef..b986298a7ba3 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c @@ -64,15 +64,13 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb) } static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, - void *data, int hdrlen, u8 ipproto) + void *data, size_t hdrlen, u8 ipproto) { __be16 *pd = data; - u16 start = ntohs(pd[0]); - u16 offset = ntohs(pd[1]); - u16 poffset = 0; - u16 plen; - __wsum csum, delta; - __sum16 *psum; + size_t start = ntohs(pd[0]); + size_t offset = ntohs(pd[1]); + size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); + __wsum delta; if (skb->remcsum_offload) { /* Already processed in GRO path */ @@ -80,35 +78,15 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr, return guehdr; } - if (start > skb->len - hdrlen || - offset > skb->len - hdrlen - sizeof(u16)) - return NULL; - - if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) - __skb_checksum_complete(skb); - - plen = hdrlen + offset + sizeof(u16); if (!pskb_may_pull(skb, plen)) return NULL; guehdr = (struct guehdr *)&udp_hdr(skb)[1]; - if (ipproto == IPPROTO_IP && sizeof(struct iphdr) < plen) { - struct iphdr *ip = (struct iphdr *)(skb->data + hdrlen); - - /* If next header happens to be IP we can skip that for the - * checksum calculation since the IP header checksum is zero - * if correct. - */ - poffset = ip->ihl * 4; - } - - csum = csum_sub(skb->csum, skb_checksum(skb, poffset + hdrlen, - start - poffset - hdrlen, 0)); + if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) + __skb_checksum_complete(skb); - /* Set derived checksum in packet */ - psum = (__sum16 *)(skb->data + hdrlen + offset); - delta = csum_sub(csum_fold(csum), *psum); - *psum = csum_fold(csum); + delta = remcsum_adjust((void *)guehdr + hdrlen, + skb->csum, start, offset); /* Adjust skb->csum since we changed the packet */ skb->csum = csum_add(skb->csum, delta); @@ -158,9 +136,6 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(skb)->tot_len) - len); - /* Pull UDP header now, skb->data points to guehdr */ - __skb_pull(skb, sizeof(struct udphdr)); - /* Pull csum through the guehdr now . This can be used if * there is a remote checksum offload. */ @@ -188,7 +163,7 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) if (unlikely(guehdr->control)) return gue_control_message(skb, guehdr); - __skb_pull(skb, hdrlen); + __skb_pull(skb, sizeof(struct udphdr) + hdrlen); skb_reset_transport_header(skb); return -guehdr->proto_ctype; @@ -248,24 +223,17 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, size_t hdrlen, u8 ipproto) { __be16 *pd = data; - u16 start = ntohs(pd[0]); - u16 offset = ntohs(pd[1]); - u16 poffset = 0; - u16 plen; - void *ptr; - __wsum csum, delta; - __sum16 *psum; + size_t start = ntohs(pd[0]); + size_t offset = ntohs(pd[1]); + size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start); + __wsum delta; if (skb->remcsum_offload) return guehdr; - if (start > skb_gro_len(skb) - hdrlen || - offset > skb_gro_len(skb) - hdrlen - sizeof(u16) || - !NAPI_GRO_CB(skb)->csum_valid || skb->remcsum_offload) + if (!NAPI_GRO_CB(skb)->csum_valid) return NULL; - plen = hdrlen + offset + sizeof(u16); - /* Pull checksum that will be written */ if (skb_gro_header_hard(skb, off + plen)) { guehdr = skb_gro_header_slow(skb, off + plen, off); @@ -273,26 +241,8 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off, return NULL; } - ptr = (void *)guehdr + hdrlen; - - if (ipproto == IPPROTO_IP && - (hdrlen + sizeof(struct iphdr) < plen)) { - struct iphdr *ip = (struct iphdr *)(ptr + hdrlen); - - /* If next header happens to be IP we can skip - * that for the checksum calculation since the - * IP header checksum is zero if correct. - */ - poffset = ip->ihl * 4; - } - - csum = csum_sub(NAPI_GRO_CB(skb)->csum, - csum_partial(ptr + poffset, start - poffset, 0)); - - /* Set derived checksum in packet */ - psum = (__sum16 *)(ptr + offset); - delta = csum_sub(csum_fold(csum), *psum); - *psum = csum_fold(csum); + delta = remcsum_adjust((void *)guehdr + hdrlen, + NAPI_GRO_CB(skb)->csum, start, offset); /* Adjust skb->csum since we changed the packet */ skb->csum = csum_add(skb->csum, delta); -- GitLab From 73cf0e923d685a6a1b7754c7d29cc14944f271d9 Mon Sep 17 00:00:00 2001 From: zhuyj Date: Wed, 26 Nov 2014 10:25:58 +0800 Subject: [PATCH 6630/9457] ipv6: Remove unnecessary test The "init_net" test in function addrconf_exit_net is introduced in commit 44a6bd29 [Create ipv6 devconf-s for namespaces] to avoid freeing init_net. In commit c900a800 [ipv6: fix bad free of addrconf_init_net], function addrconf_init_net will allocate memory for every net regardless of init_net. In this case, it is unnecessary to make "init_net" test. CC: Hong Zhiguo CC: Octavian Purdila CC: Pavel Emelyanov CC: Cong Wang Suggested-by: David S. Miller Signed-off-by: Zhu Yanjun Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9eac3a7fefa3..f7c8bbeb27b7 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -5380,10 +5380,8 @@ static void __net_exit addrconf_exit_net(struct net *net) __addrconf_sysctl_unregister(net->ipv6.devconf_dflt); __addrconf_sysctl_unregister(net->ipv6.devconf_all); #endif - if (!net_eq(net, &init_net)) { - kfree(net->ipv6.devconf_dflt); - kfree(net->ipv6.devconf_all); - } + kfree(net->ipv6.devconf_dflt); + kfree(net->ipv6.devconf_all); } static struct pernet_operations addrconf_ops = { -- GitLab From 4c503dd5fbdc33118d27f60e5c364d364980d4fd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:22 +0800 Subject: [PATCH 6631/9457] usb: chipidea: using devm_request_irq to instead of request_irq Using devm_request_irq to instead of request_irq. Suggested-by: Arnd Bergmann Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 60578d9c896d..5de1507b798c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -759,8 +759,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ci); - ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, - ci); + ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, + ci->platdata->name, ci); if (ret) goto stop; @@ -771,7 +771,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ret) return 0; - free_irq(ci->irq, ci); stop: ci_role_destroy(ci); deinit_phy: @@ -785,7 +784,6 @@ static int ci_hdrc_remove(struct platform_device *pdev) struct ci_hdrc *ci = platform_get_drvdata(pdev); dbg_remove_files(ci); - free_irq(ci->irq, ci); ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); ci_usb_phy_exit(ci); -- GitLab From d0f992498e82e656646ad833e3f32ad69cd093e7 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:23 +0800 Subject: [PATCH 6632/9457] usb: chipidea: core: Remove unneeded OOM message MM core code already complains when devm_kzalloc() fails, so no need to print the error locally. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5de1507b798c..cde3d24ebd10 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -633,10 +633,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) return PTR_ERR(base); ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL); - if (!ci) { - dev_err(dev, "can't allocate device\n"); + if (!ci) return -ENOMEM; - } ci->dev = dev; ci->platdata = dev_get_platdata(dev); -- GitLab From 73529828cf896df5017255136b4dc2386dff0850 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:24 +0800 Subject: [PATCH 6633/9457] usb: chipidea: ci_hdrc_imx.c: Remove unneeded OOM message MM core code already complains when devm_kzalloc() fails, so no need to print the error locally. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 6f8b1b1045b5..8b1482aa1291 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -115,10 +115,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(&pdev->dev, "Failed to allocate ci_hdrc-imx data!\n"); + if (!data) return -ENOMEM; - } data->usbmisc_data = usbmisc_get_init_data(&pdev->dev); if (IS_ERR(data->usbmisc_data)) -- GitLab From 8d1dc4d055faafafca3edd8499aeeef3f77803e4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:25 +0800 Subject: [PATCH 6634/9457] usb: chipidea: usbmisc_imx: Move the reading of USB_PHY_CTRL If 'evdo' property is not defined, then reading the MX25_USB_PHY_CTRL_OFFSET register is an unneeded operation. Move the reading of MX25_USB_PHY_CTRL_OFFSET inside the 'evdo' if block code, where it is actually used. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 926c997ef310..29200ebdd357 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -117,10 +117,9 @@ static int usbmisc_imx25_post(struct imx_usbmisc_data *data) if (data->index > 2) return -EINVAL; - reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; - if (data->evdo) { spin_lock_irqsave(&usbmisc->lock, flags); + reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; val = readl(reg); writel(val | MX25_BM_EXTERNAL_VBUS_DIVIDER, reg); spin_unlock_irqrestore(&usbmisc->lock, flags); -- GitLab From 4a1d6cf156dcf436e5037375007116197f03bfb1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 26 Nov 2014 13:44:26 +0800 Subject: [PATCH 6635/9457] usb: chipidea: usbmisc_imx: Read MX53_USB_OTG_PHY_CTRL_1_OFFSET directly There is no need to do an intermediate step for reading the MX53_USB_OTG_PHY_CTRL_1_OFFSET register. Read it directly instead. Signed-off-by: Fabio Estevam Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/usbmisc_imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 29200ebdd357..58591e9dcede 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -171,8 +171,7 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) return -EINVAL; /* Select a 24 MHz reference clock for the PHY */ - reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET; - val = readl(reg); + val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; val |= MX53_USB_PLL_DIV_24_MHZ; writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); -- GitLab From 6d037db6409c33738c7153e87ae1cf682ca2851b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:27 +0800 Subject: [PATCH 6636/9457] usb: chipidea: remove the unnecessary delay after clear portsc.phcd The individual PHY driver should take this responsibility if it needs to delay between clear portsc.phcd and let the phy leave low power mode. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index cde3d24ebd10..d87caea261d9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -196,18 +196,12 @@ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable) enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC; bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm))); - if (enable && !lpm) { + if (enable && !lpm) hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), PORTSC_PHCD(ci->hw_bank.lpm)); - } else if (!enable && lpm) { + else if (!enable && lpm) hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 0); - /* - * the PHY needs some time (less - * than 1ms) to leave low power mode. - */ - usleep_range(1000, 1100); - } } static int hw_device_init(struct ci_hdrc *ci, void __iomem *base) -- GitLab From b82613cf09455d9a50fbb144ef07b68225f2b452 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:28 +0800 Subject: [PATCH 6637/9457] usb: chipidea: add hw_wait_phy_stable for getting stable status The phy needs some delay to output the stable status from low power mode. And for OTGSC, the status inputs are debounced using a 1 ms time constant, so, delay 2ms for controller to get the stable status(like vbus and id) when the phy leaves low power. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index d87caea261d9..fe3880541efd 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -190,6 +190,17 @@ u8 hw_port_test_get(struct ci_hdrc *ci) return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC); } +static void hw_wait_phy_stable(void) +{ + /* + * The phy needs some delay to output the stable status from low + * power mode. And for OTGSC, the status inputs are debounced + * using a 1 ms time constant, so, delay 2ms for controller to get + * the stable status, like vbus and id when the phy leaves low power. + */ + usleep_range(2000, 2500); +} + /* The PHY enters/leaves low power mode */ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable) { @@ -351,7 +362,9 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) case USBPHY_INTERFACE_MODE_UTMIW: case USBPHY_INTERFACE_MODE_HSIC: ret = _ci_usb_phy_init(ci); - if (ret) + if (!ret) + hw_wait_phy_stable(); + else return ret; hw_phymode_configure(ci); break; @@ -364,6 +377,8 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) break; default: ret = _ci_usb_phy_init(ci); + if (!ret) + hw_wait_phy_stable(); } return ret; @@ -667,13 +682,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); return ret; - } else { - /* - * The delay to sync PHY's status, the maximum delay is - * 2ms since the otgsc uses 1ms timer to debounce the - * PHY's input - */ - usleep_range(2000, 2500); } ci->hw_bank.phys = res->start; -- GitLab From 8076932ff2fc0f6db0172420e6b148a8b2e8c805 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:29 +0800 Subject: [PATCH 6638/9457] usb: chipidea: add system power management support Add system power management support Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index fe3880541efd..bd74f27a95e5 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -791,11 +791,59 @@ static int ci_hdrc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static void ci_controller_suspend(struct ci_hdrc *ci) +{ + ci_hdrc_enter_lpm(ci, true); + + if (ci->usb_phy) + usb_phy_set_suspend(ci->usb_phy, 1); +} + +static int ci_controller_resume(struct device *dev) +{ + struct ci_hdrc *ci = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + ci_hdrc_enter_lpm(ci, false); + + if (ci->usb_phy) { + usb_phy_set_suspend(ci->usb_phy, 0); + usb_phy_set_wakeup(ci->usb_phy, false); + hw_wait_phy_stable(); + } + + return 0; +} + +static int ci_suspend(struct device *dev) +{ + struct ci_hdrc *ci = dev_get_drvdata(dev); + + if (ci->wq) + flush_workqueue(ci->wq); + + ci_controller_suspend(ci); + + return 0; +} + +static int ci_resume(struct device *dev) +{ + return ci_controller_resume(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops ci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume) +}; static struct platform_driver ci_hdrc_driver = { .probe = ci_hdrc_probe, .remove = ci_hdrc_remove, .driver = { .name = "ci_hdrc", + .pm = &ci_pm_ops, .owner = THIS_MODULE, }, }; -- GitLab From 2558c1f53bbbb5848fd5910918b97b03249d3885 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:30 +0800 Subject: [PATCH 6639/9457] usb: chipidea: imx: add system power management support Add basic system power management support Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 8b1482aa1291..75421c2187f5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -208,6 +208,41 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int imx_controller_suspend(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + clk_disable_unprepare(data->clk); + + return 0; +} + +static int imx_controller_resume(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + + dev_dbg(dev, "at %s\n", __func__); + + return clk_prepare_enable(data->clk); +} + +static int ci_hdrc_imx_suspend(struct device *dev) +{ + return imx_controller_suspend(dev); +} + +static int ci_hdrc_imx_resume(struct device *dev) +{ + return imx_controller_resume(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume) +}; static struct platform_driver ci_hdrc_imx_driver = { .probe = ci_hdrc_imx_probe, .remove = ci_hdrc_imx_remove, @@ -215,6 +250,7 @@ static struct platform_driver ci_hdrc_imx_driver = { .name = "imx_usb", .owner = THIS_MODULE, .of_match_table = ci_hdrc_imx_dt_ids, + .pm = &ci_hdrc_imx_pm_ops, }, }; -- GitLab From 947c88592f17bd299ff677049c3cda36cc6f93dd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:31 +0800 Subject: [PATCH 6640/9457] usb: chipidea: remove flag CI_HDRC_REQUIRE_TRANSCEIVER Now, USB PHY is mandatory for chipidea core, the flag CI_HDRC_REQUIRE_TRANSCEIVER is useless. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci_hdrc_imx.c | 3 +-- drivers/usb/chipidea/ci_hdrc_msm.c | 1 - include/linux/usb/chipidea.h | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 75421c2187f5..450a168974d5 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -106,8 +106,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) struct ci_hdrc_platform_data pdata = { .name = dev_name(&pdev->dev), .capoffset = DEF_CAPOFFSET, - .flags = CI_HDRC_REQUIRE_TRANSCEIVER | - CI_HDRC_DISABLE_STREAMING, + .flags = CI_HDRC_DISABLE_STREAMING, }; int ret; const struct of_device_id *of_id = diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 3edf969ed797..d79ecc08a1be 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -46,7 +46,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { .name = "ci_hdrc_msm", .capoffset = DEF_CAPOFFSET, .flags = CI_HDRC_REGS_SHARED | - CI_HDRC_REQUIRE_TRANSCEIVER | CI_HDRC_DISABLE_STREAMING, .notify_event = ci_hdrc_msm_notify_event, diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index c01bf4ea27b9..535997a6681b 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -19,7 +19,6 @@ struct ci_hdrc_platform_data { enum usb_phy_interface phy_mode; unsigned long flags; #define CI_HDRC_REGS_SHARED BIT(0) -#define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1) #define CI_HDRC_DISABLE_STREAMING BIT(3) /* * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, -- GitLab From cdd278f21eea55412dd0c5bc468bbdfb0639879b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:32 +0800 Subject: [PATCH 6641/9457] usb: chipidea: add controller reset API Add controller reset API, currently it is used for device mode only. It may be used for host/otg driver in future. Ususally, we need this API for dual-role switch and back from hibernation suspend to let the controller at default state. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index bd74f27a95e5..48b25d9ebf82 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -385,20 +385,44 @@ static int ci_usb_phy_init(struct ci_hdrc *ci) } /** - * hw_device_reset: resets chip (execute without interruption) + * hw_controller_reset: do controller reset * @ci: the controller * * This function returns an error code */ +static int hw_controller_reset(struct ci_hdrc *ci) +{ + int count = 0; + + hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST); + while (hw_read(ci, OP_USBCMD, USBCMD_RST)) { + udelay(10); + if (count++ > 1000) + return -ETIMEDOUT; + } + + return 0; +} + +/** + * hw_device_reset: resets chip (execute without interruption) + * @ci: the controller + * + * This function returns an error code + */ int hw_device_reset(struct ci_hdrc *ci, u32 mode) { + int ret; + /* should flush & stop before reset */ hw_write(ci, OP_ENDPTFLUSH, ~0, ~0); hw_write(ci, OP_USBCMD, USBCMD_RS, 0); - hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST); - while (hw_read(ci, OP_USBCMD, USBCMD_RST)) - udelay(10); /* not RTOS friendly */ + ret = hw_controller_reset(ci); + if (ret) { + dev_err(ci->dev, "error resetting controller, ret=%d\n", ret); + return ret; + } if (ci->platdata->notify_event) ci->platdata->notify_event(ci, -- GitLab From 5b1573005a91dc448e6919d6bec076bedc7e1919 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:33 +0800 Subject: [PATCH 6642/9457] usb: chipidea: parameter 'mode' isn't needed for hw_device_reset The hw_device_reset is dedicated to be used at device mode initializaiton, so delete the parameter 'mode'. For host driver, the ehci driver will handle all things. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci.h | 2 +- drivers/usb/chipidea/core.c | 8 ++++---- drivers/usb/chipidea/otg_fsm.c | 2 +- drivers/usb/chipidea/udc.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 5bbfcc73cf70..65913d48f0c8 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -352,7 +352,7 @@ u32 hw_read_intr_enable(struct ci_hdrc *ci); u32 hw_read_intr_status(struct ci_hdrc *ci); -int hw_device_reset(struct ci_hdrc *ci, u32 mode); +int hw_device_reset(struct ci_hdrc *ci); int hw_port_test_set(struct ci_hdrc *ci, u8 mode); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 48b25d9ebf82..e43be34f04b9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -410,7 +410,7 @@ static int hw_controller_reset(struct ci_hdrc *ci) * * This function returns an error code */ -int hw_device_reset(struct ci_hdrc *ci, u32 mode) +int hw_device_reset(struct ci_hdrc *ci) { int ret; @@ -440,12 +440,12 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode) /* USBMODE should be configured step by step */ hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); - hw_write(ci, OP_USBMODE, USBMODE_CM, mode); + hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC); /* HW >= 2.3 */ hw_write(ci, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); - if (hw_read(ci, OP_USBMODE, USBMODE_CM) != mode) { - pr_err("cannot enter in %s mode", ci_role(ci)->name); + if (hw_read(ci, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DC) { + pr_err("cannot enter in %s device mode", ci_role(ci)->name); pr_err("lpm = %i", ci->hw_bank.lpm); return -ENODEV; } diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 368cc8e94fd6..7ef124db657a 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -543,7 +543,7 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on) ci_role_start(ci, CI_ROLE_HOST); } else { ci_role_stop(ci); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); ci_role_start(ci, CI_ROLE_GADGET); } mutex_lock(&fsm->lock); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index bdaa7bac6f4a..4fe18ce3bd5a 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1471,7 +1471,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) if (gadget_ready) { if (is_active) { pm_runtime_get_sync(&_gadget->dev); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); hw_device_state(ci, ci->ep0out->qh.dma); usb_gadget_set_state(_gadget, USB_STATE_POWERED); } else { @@ -1660,7 +1660,7 @@ static int ci_udc_start(struct usb_gadget *gadget, pm_runtime_get_sync(&ci->gadget.dev); if (ci->vbus_active) { spin_lock_irqsave(&ci->lock, flags); - hw_device_reset(ci, USBMODE_CM_DC); + hw_device_reset(ci); } else { pm_runtime_put_sync(&ci->gadget.dev); return retval; -- GitLab From 14b4099c074f2ddf4d84b22d370170e61b527529 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 26 Nov 2014 13:44:34 +0800 Subject: [PATCH 6643/9457] usb: chipidea: remove duplicate dev_set_drvdata for host_start The core driver has already done it, besides, move set driver data operation just after ci has allocated successfully in case some code (like ci_role_start) want to access this driver data. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/host.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index e43be34f04b9..de1e4a84aa93 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -669,6 +669,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ci) return -ENOMEM; + platform_set_drvdata(pdev, ci); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & @@ -782,7 +783,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) } } - platform_set_drvdata(pdev, ci); ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, ci); if (ret) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 48731d0bab35..c1694cff1eaf 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -91,7 +91,6 @@ static int host_start(struct ci_hdrc *ci) if (!hcd) return -ENOMEM; - dev_set_drvdata(ci->dev, ci); hcd->rsrc_start = ci->hw_bank.phys; hcd->rsrc_len = ci->hw_bank.size; hcd->regs = ci->hw_bank.abs; -- GitLab From 21a5b579cb63364b90e545e7e0a4bccb027711e8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:35 +0800 Subject: [PATCH 6644/9457] usb: chipidea: fix phy handling The generic plaftorm device for ChipIdea drivers is probed by calling ci_hdrc_probe. The device structure used is not the one of the specific ChipIdea driver but the one of the generic ChipIdea platform device. This results in not being able to probe the PHYs as we're not using the right device structure. Since all ChipIdea drivers are retrieving their PHYs in their specific driver code, this didn't impact any of them yet. Fixes it using the right device structure (dev->parent). Signed-off-by: Antoine Tenart Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index de1e4a84aa93..068e0c6acc3f 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -686,8 +686,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } else if (ci->platdata->usb_phy) { ci->usb_phy = ci->platdata->usb_phy; } else { - ci->phy = devm_phy_get(dev, "usb-phy"); - ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + ci->phy = devm_phy_get(dev->parent, "usb-phy"); + ci->usb_phy = devm_usb_get_phy(dev->parent, USB_PHY_TYPE_USB2); /* if both generic PHY and USB PHY layers aren't enabled */ if (PTR_ERR(ci->phy) == -ENOSYS && -- GitLab From 10a062cefcfb1f6154a66f9872efc11543eeb3f8 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:36 +0800 Subject: [PATCH 6645/9457] usb: chipidea: add a usb2 driver for ci13xxx Add a USB2 ChipIdea driver for ci13xxx, with optional PHY, clock and DMA mask, to support USB2 ChipIdea controllers that don't need specific functions. Tested on the Marvell Berlin SoCs USB controllers. Signed-off-by: Antoine Tenart Tested-by: Soren Brinkmann Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/Makefile | 1 + drivers/usb/chipidea/ci_hdrc_usb2.c | 116 ++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 drivers/usb/chipidea/ci_hdrc_usb2.c diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 2f099c7df7b5..1fc86a2ca22d 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -10,6 +10,7 @@ ci_hdrc-$(CONFIG_USB_OTG_FSM) += otg_fsm.o # Glue/Bridge layers go here +obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_usb2.o obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_msm.o obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c new file mode 100644 index 000000000000..61d8e55df1bd --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ci.h" + +struct ci_hdrc_usb2_priv { + struct platform_device *ci_pdev; + struct clk *clk; +}; + +static struct ci_hdrc_platform_data ci_default_pdata = { + .capoffset = DEF_CAPOFFSET, + .flags = CI_HDRC_DISABLE_STREAMING, +}; + +static int ci_hdrc_usb2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ci_hdrc_usb2_priv *priv; + struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); + int ret; + + if (!ci_pdata) + ci_pdata = &ci_default_pdata; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->clk = devm_clk_get(dev, NULL); + if (!IS_ERR(priv->clk)) { + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "failed to enable the clock: %d\n", ret); + return ret; + } + } + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + goto clk_err; + + ci_pdata->name = dev_name(dev); + + priv->ci_pdev = ci_hdrc_add_device(dev, pdev->resource, + pdev->num_resources, ci_pdata); + if (IS_ERR(priv->ci_pdev)) { + ret = PTR_ERR(priv->ci_pdev); + if (ret != -EPROBE_DEFER) + dev_err(dev, + "failed to register ci_hdrc platform device: %d\n", + ret); + goto clk_err; + } + + platform_set_drvdata(pdev, priv); + + pm_runtime_no_callbacks(dev); + pm_runtime_enable(dev); + + return 0; + +clk_err: + if (!IS_ERR(priv->clk)) + clk_disable_unprepare(priv->clk); + return ret; +} + +static int ci_hdrc_usb2_remove(struct platform_device *pdev) +{ + struct ci_hdrc_usb2_priv *priv = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + ci_hdrc_remove_device(priv->ci_pdev); + clk_disable_unprepare(priv->clk); + + return 0; +} + +static const struct of_device_id ci_hdrc_usb2_of_match[] = { + { .compatible = "chipidea,usb2" }, + { } +}; +MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match); + +static struct platform_driver ci_hdrc_usb2_driver = { + .probe = ci_hdrc_usb2_probe, + .remove = ci_hdrc_usb2_remove, + .driver = { + .name = "chipidea-usb2", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ci_hdrc_usb2_of_match), + }, +}; +module_platform_driver(ci_hdrc_usb2_driver); + +MODULE_DESCRIPTION("ChipIdea HDRC USB2 binding for ci13xxx"); +MODULE_AUTHOR("Antoine Tenart "); +MODULE_LICENSE("GPL"); -- GitLab From d7d30c911dd957e274c3da6910d4286862ab1d78 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:37 +0800 Subject: [PATCH 6646/9457] Documentation: bindings: add doc for the USB2 ChipIdea USB driver Document the USB2 ChipIdea driver (ci13xxx) bindings. Signed-off-by: Antoine Tenart Acked-by: Peter Chen Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/ci-hdrc-usb2.txt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt new file mode 100644 index 000000000000..27f8b1e5ee46 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -0,0 +1,24 @@ +* USB2 ChipIdea USB controller for ci13xxx + +Required properties: +- compatible: should be "chipidea,usb2" +- reg: base address and length of the registers +- interrupts: interrupt for the USB controller + +Optional properties: +- clocks: reference to the USB clock +- phys: reference to the USB PHY +- phy-names: should be "usb-phy" +- vbus-supply: reference to the VBUS regulator + +Example: + + usb@f7ed0000 { + compatible = "chipidea,usb2"; + reg = <0xf7ed0000 0x10000>; + interrupts = ; + clocks = <&chip CLKID_USB0>; + phys = <&usb_phy0>; + phy-names = "usb-phy"; + vbus-supply = <®_usb0_vbus>; + }; -- GitLab From 6629467ba5502cac22d31950e207a0334f2a0de5 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Wed, 26 Nov 2014 13:44:38 +0800 Subject: [PATCH 6647/9457] usb: chipidea: Fixed a few typos in comments Fixed typos in comments of 2 drivers/usb/chipidea files Signed-off-by: Mickael Maison Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/otg_fsm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 068e0c6acc3f..e14eafb2a05e 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -549,7 +549,7 @@ static int ci_get_platdata(struct device *dev, if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) { - /* no vbus regualator is needed */ + /* no vbus regulator is needed */ platdata->reg_vbus = NULL; } else if (IS_ERR(platdata->reg_vbus)) { dev_err(dev, "Getting regulator error: %ld\n", diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 7ef124db657a..562e581f6765 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -303,7 +303,7 @@ static void a_wait_vfall_tmout_func(void *ptr, unsigned long indicator) set_tmout(ci, indicator); /* Disable port power */ hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP, 0); - /* Clear exsiting DP irq */ + /* Clear existing DP irq */ hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS); /* Enable data pulse irq */ hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE); @@ -663,7 +663,7 @@ static void ci_otg_fsm_event(struct ci_hdrc *ci) fsm->b_bus_suspend = 1; /* * Init a timer to know how long this suspend - * will contine, if time out, indicates B no longer + * will continue, if time out, indicates B no longer * wants to be host role */ ci_otg_add_timer(ci, A_BIDL_ADIS); -- GitLab From a8f48af587b0f257c49dce5b49a62554a4b8627e Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:45 +0800 Subject: [PATCH 6648/9457] tipc: remove node subscription infrastructure The node subscribe infrastructure represents a virtual base class, so its users, such as struct tipc_port and struct publication, can derive its implemented functionalities. However, after the removal of struct tipc_port, struct publication is left as its only single user now. So defining an abstract infrastructure for one user becomes no longer reasonable. If corresponding new functions associated with the infrastructure are moved to name_table.c file, the node subscription infrastructure can be removed as well. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/Makefile | 4 +- net/tipc/name_distr.c | 52 ++++++++++++++++++++--- net/tipc/name_distr.h | 1 + net/tipc/name_table.c | 2 +- net/tipc/name_table.h | 6 +-- net/tipc/node.c | 6 +-- net/tipc/node.h | 5 +-- net/tipc/node_subscr.c | 96 ------------------------------------------ net/tipc/node_subscr.h | 63 --------------------------- 9 files changed, 56 insertions(+), 179 deletions(-) delete mode 100644 net/tipc/node_subscr.c delete mode 100644 net/tipc/node_subscr.h diff --git a/net/tipc/Makefile b/net/tipc/Makefile index b8a13caad59a..333e4592772c 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -7,8 +7,8 @@ obj-$(CONFIG_TIPC) := tipc.o tipc-y += addr.o bcast.o bearer.o config.o \ core.o link.o discover.o msg.o \ name_distr.o subscr.o name_table.o net.o \ - netlink.o node.o node_subscr.o \ - socket.o log.o eth_media.o server.o + netlink.o node.o socket.o log.o eth_media.o \ + server.o tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o tipc-$(CONFIG_SYSCTL) += sysctl.o diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 376d2bb51d8d..6c2638d3c659 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -250,13 +250,45 @@ void tipc_named_node_up(u32 dnode) tipc_link_xmit(buf_chain, dnode, dnode); } +static void tipc_publ_subscribe(struct publication *publ, u32 addr) +{ + struct tipc_node *node; + + if (in_own_node(addr)) + return; + + node = tipc_node_find(addr); + if (!node) { + pr_warn("Node subscription rejected, unknown node 0x%x\n", + addr); + return; + } + + tipc_node_lock(node); + list_add_tail(&publ->nodesub_list, &node->publ_list); + tipc_node_unlock(node); +} + +static void tipc_publ_unsubscribe(struct publication *publ, u32 addr) +{ + struct tipc_node *node; + + node = tipc_node_find(addr); + if (!node) + return; + + tipc_node_lock(node); + list_del_init(&publ->nodesub_list); + tipc_node_unlock(node); +} + /** - * named_purge_publ - remove publication associated with a failed node + * tipc_publ_purge - remove publication associated with a failed node * * Invoked for each publication issued by a newly failed node. * Removes publication structure from name table & deletes it. */ -static void named_purge_publ(struct publication *publ) +static void tipc_publ_purge(struct publication *publ, u32 addr) { struct publication *p; @@ -264,7 +296,7 @@ static void named_purge_publ(struct publication *publ) p = tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, publ->ref, publ->key); if (p) - tipc_nodesub_unsubscribe(&p->subscr); + tipc_publ_unsubscribe(p, addr); write_unlock_bh(&tipc_nametbl_lock); if (p != publ) { @@ -277,6 +309,14 @@ static void named_purge_publ(struct publication *publ) kfree(p); } +void tipc_publ_notify(struct list_head *nsub_list, u32 addr) +{ + struct publication *publ, *tmp; + + list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) + tipc_publ_purge(publ, addr); +} + /** * tipc_update_nametbl - try to process a nametable update and notify * subscribers @@ -294,9 +334,7 @@ static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype) TIPC_CLUSTER_SCOPE, node, ntohl(i->ref), ntohl(i->key)); if (publ) { - tipc_nodesub_subscribe(&publ->subscr, node, publ, - (net_ev_handler) - named_purge_publ); + tipc_publ_subscribe(publ, node); return true; } } else if (dtype == WITHDRAWAL) { @@ -304,7 +342,7 @@ static bool tipc_update_nametbl(struct distr_item *i, u32 node, u32 dtype) node, ntohl(i->ref), ntohl(i->key)); if (publ) { - tipc_nodesub_unsubscribe(&publ->subscr); + tipc_publ_unsubscribe(publ, node); kfree(publ); return true; } diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h index b9e75feb3434..cef55cedcfb2 100644 --- a/net/tipc/name_distr.h +++ b/net/tipc/name_distr.h @@ -74,5 +74,6 @@ void tipc_named_node_up(u32 dnode); void tipc_named_rcv(struct sk_buff *buf); void tipc_named_reinit(void); void tipc_named_process_backlog(void); +void tipc_publ_notify(struct list_head *nsub_list, u32 addr); #endif diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 7cfb7a4aa58f..772be1cd8bf6 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -144,7 +144,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, publ->key = key; INIT_LIST_HEAD(&publ->local_list); INIT_LIST_HEAD(&publ->pport_list); - INIT_LIST_HEAD(&publ->subscr.nodesub_list); + INIT_LIST_HEAD(&publ->nodesub_list); return publ; } diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index b38ebecac766..c62877826655 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h @@ -37,8 +37,6 @@ #ifndef _TIPC_NAME_TABLE_H #define _TIPC_NAME_TABLE_H -#include "node_subscr.h" - struct tipc_subscription; struct tipc_port_list; @@ -56,7 +54,7 @@ struct tipc_port_list; * @node: network address of publishing port's node * @ref: publishing port * @key: publication key - * @subscr: subscription to "node down" event (for off-node publications only) + * @nodesub_list: subscription to "node down" event (off-node publication only) * @local_list: adjacent entries in list of publications made by this node * @pport_list: adjacent entries in list of publications made by this port * @node_list: adjacent matching name seq publications with >= node scope @@ -73,7 +71,7 @@ struct publication { u32 node; u32 ref; u32 key; - struct tipc_node_subscr subscr; + struct list_head nodesub_list; struct list_head local_list; struct list_head pport_list; struct list_head node_list; diff --git a/net/tipc/node.c b/net/tipc/node.c index 82e5edddc376..17b8092f9c40 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -113,7 +113,7 @@ struct tipc_node *tipc_node_create(u32 addr) spin_lock_init(&n_ptr->lock); INIT_HLIST_NODE(&n_ptr->hash); INIT_LIST_HEAD(&n_ptr->list); - INIT_LIST_HEAD(&n_ptr->nsub); + INIT_LIST_HEAD(&n_ptr->publ_list); INIT_LIST_HEAD(&n_ptr->conn_sks); __skb_queue_head_init(&n_ptr->waiting_sks); @@ -574,7 +574,7 @@ void tipc_node_unlock(struct tipc_node *node) skb_queue_splice_init(&node->waiting_sks, &waiting_sks); if (flags & TIPC_NOTIFY_NODE_DOWN) { - list_replace_init(&node->nsub, &nsub_list); + list_replace_init(&node->publ_list, &nsub_list); list_replace_init(&node->conn_sks, &conn_sks); } node->action_flags &= ~(TIPC_WAKEUP_USERS | TIPC_NOTIFY_NODE_DOWN | @@ -591,7 +591,7 @@ void tipc_node_unlock(struct tipc_node *node) tipc_node_abort_sock_conns(&conn_sks); if (!list_empty(&nsub_list)) - tipc_nodesub_notify(&nsub_list); + tipc_publ_notify(&nsub_list, addr); if (flags & TIPC_WAKEUP_BCAST_USERS) tipc_bclink_wakeup_users(); diff --git a/net/tipc/node.h b/net/tipc/node.h index 005fbcef3212..f1994511f033 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -37,7 +37,6 @@ #ifndef _TIPC_NODE_H #define _TIPC_NODE_H -#include "node_subscr.h" #include "addr.h" #include "net.h" #include "bearer.h" @@ -104,7 +103,7 @@ struct tipc_node_bclink { * @link_cnt: number of links to node * @signature: node instance identifier * @link_id: local and remote bearer ids of changing link, if any - * @nsub: list of "node down" subscriptions monitoring node + * @publ_list: list of publications * @rcu: rcu struct for tipc_node */ struct tipc_node { @@ -121,7 +120,7 @@ struct tipc_node { int working_links; u32 signature; u32 link_id; - struct list_head nsub; + struct list_head publ_list; struct sk_buff_head waiting_sks; struct list_head conn_sks; struct rcu_head rcu; diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c deleted file mode 100644 index 2d13eea8574a..000000000000 --- a/net/tipc/node_subscr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * net/tipc/node_subscr.c: TIPC "node down" subscription handling - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, 2010-2011, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "node_subscr.h" -#include "node.h" - -/** - * tipc_nodesub_subscribe - create "node down" subscription for specified node - */ -void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, - void *usr_handle, net_ev_handler handle_down) -{ - if (in_own_node(addr)) { - node_sub->node = NULL; - return; - } - - node_sub->node = tipc_node_find(addr); - if (!node_sub->node) { - pr_warn("Node subscription rejected, unknown node 0x%x\n", - addr); - return; - } - node_sub->handle_node_down = handle_down; - node_sub->usr_handle = usr_handle; - - tipc_node_lock(node_sub->node); - list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub); - tipc_node_unlock(node_sub->node); -} - -/** - * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any) - */ -void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub) -{ - if (!node_sub->node) - return; - - tipc_node_lock(node_sub->node); - list_del_init(&node_sub->nodesub_list); - tipc_node_unlock(node_sub->node); -} - -/** - * tipc_nodesub_notify - notify subscribers that a node is unreachable - * - * Note: node is locked by caller - */ -void tipc_nodesub_notify(struct list_head *nsub_list) -{ - struct tipc_node_subscr *ns, *safe; - net_ev_handler handle_node_down; - - list_for_each_entry_safe(ns, safe, nsub_list, nodesub_list) { - handle_node_down = ns->handle_node_down; - if (handle_node_down) { - ns->handle_node_down = NULL; - handle_node_down(ns->usr_handle); - } - } -} diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h deleted file mode 100644 index d91b8cc81e3d..000000000000 --- a/net/tipc/node_subscr.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, 2010-2011, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NODE_SUBSCR_H -#define _TIPC_NODE_SUBSCR_H - -#include "addr.h" - -typedef void (*net_ev_handler) (void *usr_handle); - -/** - * struct tipc_node_subscr - "node down" subscription entry - * @node: ptr to node structure of interest (or NULL, if none) - * @handle_node_down: routine to invoke when node fails - * @usr_handle: argument to pass to routine when node fails - * @nodesub_list: adjacent entries in list of subscriptions for the node - */ -struct tipc_node_subscr { - struct tipc_node *node; - net_ev_handler handle_node_down; - void *usr_handle; - struct list_head nodesub_list; -}; - -void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, - void *usr_handle, net_ev_handler handle_down); -void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub); -void tipc_nodesub_notify(struct list_head *nsub_list); - -#endif -- GitLab From 8965d250c28f588d2a6dca2a0b00e4bb895b58e0 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:46 +0800 Subject: [PATCH 6649/9457] tipc: remove protocol message queue TIPC protocol message queue is intended to save one protocol message when bearer is congested so that the message stored in the queue can be immediately transmitted when bearer congestion is released. However, as now the protocol queue has no mission any more with the removal of bearer congestion mechanism, it should be removed. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.c | 22 ---------------------- net/tipc/link.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 4738cb1bf7c0..450ed0ce9071 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -421,8 +421,6 @@ void tipc_link_purge_queues(struct tipc_link *l_ptr) kfree_skb_list(l_ptr->oldest_deferred_in); kfree_skb_list(l_ptr->first_out); tipc_link_reset_fragments(l_ptr); - kfree_skb(l_ptr->proto_msg_queue); - l_ptr->proto_msg_queue = NULL; } void tipc_link_reset(struct tipc_link *l_ptr) @@ -455,8 +453,6 @@ void tipc_link_reset(struct tipc_link *l_ptr) /* Clean up all queues: */ link_release_outqueue(l_ptr); - kfree_skb(l_ptr->proto_msg_queue); - l_ptr->proto_msg_queue = NULL; kfree_skb_list(l_ptr->oldest_deferred_in); if (!skb_queue_empty(&l_ptr->waiting_sks)) { skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks); @@ -904,18 +900,6 @@ static u32 tipc_link_push_packet(struct tipc_link *l_ptr) return 0; } - /* Send deferred protocol message, if any: */ - buf = l_ptr->proto_msg_queue; - if (buf) { - msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); - tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr); - l_ptr->unacked_window = 0; - kfree_skb(buf); - l_ptr->proto_msg_queue = NULL; - return 0; - } - /* Send one deferred data message, if send window not full: */ buf = l_ptr->next_out; if (buf) { @@ -1446,12 +1430,6 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg, u32 msg_size = sizeof(l_ptr->proto_msg); int r_flag; - /* Discard any previous message that was deferred due to congestion */ - if (l_ptr->proto_msg_queue) { - kfree_skb(l_ptr->proto_msg_queue); - l_ptr->proto_msg_queue = NULL; - } - /* Don't send protocol message during link changeover */ if (l_ptr->exp_msg_count) return; diff --git a/net/tipc/link.h b/net/tipc/link.h index f463e7be801c..fb3f99b6e928 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -130,7 +130,6 @@ struct tipc_stats { * @oldest_deferred_in: ptr to first inbound message in queue * @newest_deferred_in: ptr to last inbound message in queue * @unacked_window: # of inbound messages rx'd without ack'ing back to peer - * @proto_msg_queue: ptr to (single) outbound control message * @retransm_queue_size: number of messages to retransmit * @retransm_queue_head: sequence number of first message to retransmit * @next_out: ptr to first unsent outbound message in queue @@ -191,7 +190,6 @@ struct tipc_link { u32 unacked_window; /* Congestion handling */ - struct sk_buff *proto_msg_queue; u32 retransm_queue_size; u32 retransm_queue_head; struct sk_buff *next_out; -- GitLab From 7b6f087f98107617e0535a6ed378c561f1ae84d7 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:47 +0800 Subject: [PATCH 6650/9457] tipc: remove retransmission queue TIPC retransmission queue is intended to record which messages should be retransmitted when bearer is not congested. However, as the retransmission queue becomes useless with the removal of bearer congestion mechanism, it should be removed. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.c | 35 +---------------------------------- net/tipc/link.h | 4 ---- 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 450ed0ce9071..4b7cbfd57714 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -458,8 +458,6 @@ void tipc_link_reset(struct tipc_link *l_ptr) skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks); owner->action_flags |= TIPC_WAKEUP_USERS; } - l_ptr->retransm_queue_head = 0; - l_ptr->retransm_queue_size = 0; l_ptr->last_out = NULL; l_ptr->first_out = NULL; l_ptr->next_out = NULL; @@ -870,38 +868,9 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf) */ static u32 tipc_link_push_packet(struct tipc_link *l_ptr) { - struct sk_buff *buf = l_ptr->first_out; - u32 r_q_size = l_ptr->retransm_queue_size; - u32 r_q_head = l_ptr->retransm_queue_head; - - /* Step to position where retransmission failed, if any, */ - /* consider that buffers may have been released in meantime */ - if (r_q_size && buf) { - u32 last = lesser(mod(r_q_head + r_q_size), - link_last_sent(l_ptr)); - u32 first = buf_seqno(buf); - - while (buf && less(first, r_q_head)) { - first = mod(first + 1); - buf = buf->next; - } - l_ptr->retransm_queue_head = r_q_head = first; - l_ptr->retransm_queue_size = r_q_size = mod(last - first); - } - - /* Continue retransmission now, if there is anything: */ - if (r_q_size && buf) { - msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); - tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr); - l_ptr->retransm_queue_head = mod(++r_q_head); - l_ptr->retransm_queue_size = --r_q_size; - l_ptr->stats.retransmitted++; - return 0; - } + struct sk_buff *buf = l_ptr->next_out; /* Send one deferred data message, if send window not full: */ - buf = l_ptr->next_out; if (buf) { struct tipc_msg *msg = buf_msg(buf); u32 next = msg_seqno(msg); @@ -1025,8 +994,6 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, retransmits--; l_ptr->stats.retransmitted++; } - - l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; } /** diff --git a/net/tipc/link.h b/net/tipc/link.h index fb3f99b6e928..cc816aacb16e 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -130,8 +130,6 @@ struct tipc_stats { * @oldest_deferred_in: ptr to first inbound message in queue * @newest_deferred_in: ptr to last inbound message in queue * @unacked_window: # of inbound messages rx'd without ack'ing back to peer - * @retransm_queue_size: number of messages to retransmit - * @retransm_queue_head: sequence number of first message to retransmit * @next_out: ptr to first unsent outbound message in queue * @waiting_sks: linked list of sockets waiting for link congestion to abate * @long_msg_seq_no: next identifier to use for outbound fragmented messages @@ -190,8 +188,6 @@ struct tipc_link { u32 unacked_window; /* Congestion handling */ - u32 retransm_queue_size; - u32 retransm_queue_head; struct sk_buff *next_out; struct sk_buff_head waiting_sks; -- GitLab From 47b4c9a82f2ed0c00aa1c20899b41f54d6f8a07a Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:48 +0800 Subject: [PATCH 6651/9457] tipc: clean up the process of link pushing packets In original tipc_link_push_packet(), it pushes messages from protocol message queue, retransmission queue and next_out queue. But as the two first queues are removed, we can simplify its relevant code through deleting tipc_link_push_queue(). Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bcast.c | 2 +- net/tipc/link.c | 62 +++++++++++++++++------------------------------- net/tipc/link.h | 2 +- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 556b26ad4b1e..27648841e7ff 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -307,7 +307,7 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) /* Try resolving broadcast link congestion, if necessary */ if (unlikely(bcl->next_out)) { - tipc_link_push_queue(bcl); + tipc_link_push_packets(bcl); bclink_set_last_sent(); } if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks))) diff --git a/net/tipc/link.c b/net/tipc/link.c index 4b7cbfd57714..470f05383d43 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -149,18 +149,6 @@ static void link_init_max_pkt(struct tipc_link *l_ptr) l_ptr->max_pkt_probes = 0; } -static u32 link_next_sent(struct tipc_link *l_ptr) -{ - if (l_ptr->next_out) - return buf_seqno(l_ptr->next_out); - return mod(l_ptr->next_out_no); -} - -static u32 link_last_sent(struct tipc_link *l_ptr) -{ - return mod(link_next_sent(l_ptr) - 1); -} - /* * Simple non-static link routines (i.e. referenced outside this file) */ @@ -222,7 +210,7 @@ static void link_timeout(struct tipc_link *l_ptr) link_state_event(l_ptr, TIMEOUT_EVT); if (l_ptr->next_out) - tipc_link_push_queue(l_ptr); + tipc_link_push_packets(l_ptr); tipc_node_unlock(l_ptr->owner); } @@ -864,43 +852,37 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf) } /* - * tipc_link_push_packet: Push one unsent packet to the media + * tipc_link_push_packets - push unsent packets to bearer + * + * Push out the unsent messages of a link where congestion + * has abated. Node is locked. + * + * Called with node locked */ -static u32 tipc_link_push_packet(struct tipc_link *l_ptr) +void tipc_link_push_packets(struct tipc_link *l_ptr) { - struct sk_buff *buf = l_ptr->next_out; + struct sk_buff *skb; + struct tipc_msg *msg; + u32 next, first; - /* Send one deferred data message, if send window not full: */ - if (buf) { - struct tipc_msg *msg = buf_msg(buf); - u32 next = msg_seqno(msg); - u32 first = buf_seqno(l_ptr->first_out); + while (l_ptr->next_out) { + skb = l_ptr->next_out; + msg = buf_msg(skb); + next = msg_seqno(msg); + first = buf_seqno(l_ptr->first_out); if (mod(next - first) < l_ptr->queue_limit[0]) { msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - tipc_bearer_send(l_ptr->bearer_id, buf, - &l_ptr->media_addr); if (msg_user(msg) == MSG_BUNDLER) msg_set_type(msg, BUNDLE_CLOSED); - l_ptr->next_out = buf->next; - return 0; + tipc_bearer_send(l_ptr->bearer_id, skb, + &l_ptr->media_addr); + l_ptr->next_out = skb->next; + } else { + break; } } - return 1; -} - -/* - * push_queue(): push out the unsent messages of a link where - * congestion has abated. Node is locked - */ -void tipc_link_push_queue(struct tipc_link *l_ptr) -{ - u32 res; - - do { - res = tipc_link_push_packet(l_ptr); - } while (!res); } void tipc_link_reset_all(struct tipc_node *node) @@ -1164,7 +1146,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) /* Try sending any messages link endpoint has pending */ if (unlikely(l_ptr->next_out)) - tipc_link_push_queue(l_ptr); + tipc_link_push_packets(l_ptr); if (released && !skb_queue_empty(&l_ptr->waiting_sks)) { link_prepare_wakeup(l_ptr); diff --git a/net/tipc/link.h b/net/tipc/link.h index cc816aacb16e..1681076cb339 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -227,7 +227,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector); void tipc_link_bundle_rcv(struct sk_buff *buf); void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob, u32 gap, u32 tolerance, u32 priority, u32 acked_mtu); -void tipc_link_push_queue(struct tipc_link *l_ptr); +void tipc_link_push_packets(struct tipc_link *l_ptr); u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, struct sk_buff *buf); void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); -- GitLab From 58311d169083f1940c7ce64cb6bf736e2a023cd0 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:49 +0800 Subject: [PATCH 6652/9457] tipc: eliminate two pseudo message types of BUNDLE_OPEN and BUNDLE_CLOSED The pseudo message types of BUNDLE_CLOSED as well as BUNDLE_OPEN are used to flag whether or not more messages can be bundled into a data packet in the outgoing transmission queue. Obviously, no more messages can be appended after the packet has been sent and is waiting to be acknowledged and deleted. These message types do in reality represent a send-side local implementation flag, and are not defined as part of the protocol. It is therefore safe to move it to to where it belongs, that is, the control area (TIPC_SKB_CB) of the buffer. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/core.h | 1 + net/tipc/link.c | 2 +- net/tipc/msg.c | 5 +++-- net/tipc/msg.h | 5 ----- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/net/tipc/core.h b/net/tipc/core.h index b578b10feefa..84602137ce20 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -192,6 +192,7 @@ struct tipc_skb_cb { struct sk_buff *tail; bool deferred; bool wakeup_pending; + bool bundling; u16 chain_sz; u16 chain_imp; }; diff --git a/net/tipc/link.c b/net/tipc/link.c index 470f05383d43..8eb885eb1433 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -875,7 +875,7 @@ void tipc_link_push_packets(struct tipc_link *l_ptr) msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); if (msg_user(msg) == MSG_BUNDLER) - msg_set_type(msg, BUNDLE_CLOSED); + TIPC_SKB_CB(skb)->bundling = false; tipc_bearer_send(l_ptr->bearer_id, skb, &l_ptr->media_addr); l_ptr->next_out = skb->next; diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 9155496b8a8a..94db39217248 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -289,7 +289,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu) return false; if (likely(msg_user(bmsg) != MSG_BUNDLER)) return false; - if (likely(msg_type(bmsg) != BUNDLE_OPEN)) + if (likely(!TIPC_SKB_CB(bbuf)->bundling)) return false; if (unlikely(skb_tailroom(bbuf) < (pad + msz))) return false; @@ -336,11 +336,12 @@ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode) skb_trim(bbuf, INT_H_SIZE); bmsg = buf_msg(bbuf); - tipc_msg_init(bmsg, MSG_BUNDLER, BUNDLE_OPEN, INT_H_SIZE, dnode); + tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode); msg_set_seqno(bmsg, msg_seqno(msg)); msg_set_ack(bmsg, msg_ack(msg)); msg_set_bcast_ack(bmsg, msg_bcast_ack(msg)); bbuf->next = (*buf)->next; + TIPC_SKB_CB(bbuf)->bundling = true; tipc_msg_bundle(bbuf, *buf, mtu); *buf = bbuf; return true; diff --git a/net/tipc/msg.h b/net/tipc/msg.h index d7d2ba2afe6c..8ca874d6b4dc 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -464,11 +464,6 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) #define FRAGMENT 1 #define LAST_FRAGMENT 2 -/* Bundling protocol message types - */ -#define BUNDLE_OPEN 0 -#define BUNDLE_CLOSED 1 - /* * Link management protocol message types */ -- GitLab From 99315ad43d92a8df0e4a30a0694336cdcdb7965f Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:50 +0800 Subject: [PATCH 6653/9457] tipc: remove unused between routine Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/net/tipc/link.h b/net/tipc/link.h index 1681076cb339..771123413d5f 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -253,15 +253,6 @@ static inline u32 mod(u32 x) return x & 0xffffu; } -static inline int between(u32 lower, u32 upper, u32 n) -{ - if ((lower < n) && (n < upper)) - return 1; - if ((upper < lower) && ((n > lower) || (n < upper))) - return 1; - return 0; -} - static inline int less_eq(u32 left, u32 right) { return mod(right - left) < 32768u; -- GitLab From 58d78b328a70f4b5ed1c00010499aaedb715ea5b Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:51 +0800 Subject: [PATCH 6654/9457] tipc: use skb_queue_walk_safe marco to simplify link_prepare_wakeup routine Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 8eb885eb1433..ddee498e74bc 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -367,15 +367,15 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport, */ static void link_prepare_wakeup(struct tipc_link *link) { - struct sk_buff_head *wq = &link->waiting_sks; - struct sk_buff *buf; uint pend_qsz = link->out_queue_size; + struct sk_buff *skb, *tmp; - for (buf = skb_peek(wq); buf; buf = skb_peek(wq)) { - if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(buf)->chain_imp]) + skb_queue_walk_safe(&link->waiting_sks, skb, tmp) { + if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(skb)->chain_imp]) break; - pend_qsz += TIPC_SKB_CB(buf)->chain_sz; - __skb_queue_tail(&link->owner->waiting_sks, __skb_dequeue(wq)); + pend_qsz += TIPC_SKB_CB(skb)->chain_sz; + __skb_unlink(skb, &link->waiting_sks); + __skb_queue_tail(&link->owner->waiting_sks, skb); } } -- GitLab From 58dc55f25631178ee74cd27185956a8f7dcb3e32 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:52 +0800 Subject: [PATCH 6655/9457] tipc: use generic SKB list APIs to manage link transmission queue Use standard SKB list APIs associated with struct sk_buff_head to manage link transmission queue, having relevant code more clean. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bcast.c | 67 ++++++++--------- net/tipc/link.c | 190 +++++++++++++++++++++-------------------------- net/tipc/link.h | 17 +++-- net/tipc/msg.c | 50 ++++++------- net/tipc/msg.h | 5 +- 5 files changed, 153 insertions(+), 176 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 27648841e7ff..4a1a3c8627d0 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -217,12 +217,13 @@ struct tipc_node *tipc_bclink_retransmit_to(void) */ static void bclink_retransmit_pkt(u32 after, u32 to) { - struct sk_buff *buf; + struct sk_buff *skb; - buf = bcl->first_out; - while (buf && less_eq(buf_seqno(buf), after)) - buf = buf->next; - tipc_link_retransmit(bcl, buf, mod(to - after)); + skb_queue_walk(&bcl->outqueue, skb) { + if (more(buf_seqno(skb), after)) + break; + } + tipc_link_retransmit(bcl, skb, mod(to - after)); } /** @@ -245,14 +246,14 @@ void tipc_bclink_wakeup_users(void) */ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) { - struct sk_buff *crs; + struct sk_buff *skb, *tmp; struct sk_buff *next; unsigned int released = 0; tipc_bclink_lock(); /* Bail out if tx queue is empty (no clean up is required) */ - crs = bcl->first_out; - if (!crs) + skb = skb_peek(&bcl->outqueue); + if (!skb) goto exit; /* Determine which messages need to be acknowledged */ @@ -271,41 +272,41 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) * Bail out if specified sequence number does not correspond * to a message that has been sent and not yet acknowledged */ - if (less(acked, buf_seqno(crs)) || + if (less(acked, buf_seqno(skb)) || less(bcl->fsm_msg_cnt, acked) || less_eq(acked, n_ptr->bclink.acked)) goto exit; } /* Skip over packets that node has previously acknowledged */ - while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) - crs = crs->next; + skb_queue_walk(&bcl->outqueue, skb) { + if (more(buf_seqno(skb), n_ptr->bclink.acked)) + break; + } /* Update packets that node is now acknowledging */ + skb_queue_walk_from_safe(&bcl->outqueue, skb, tmp) { + if (more(buf_seqno(skb), acked)) + break; - while (crs && less_eq(buf_seqno(crs), acked)) { - next = crs->next; - - if (crs != bcl->next_out) - bcbuf_decr_acks(crs); - else { - bcbuf_set_acks(crs, 0); + next = tipc_skb_queue_next(&bcl->outqueue, skb); + if (skb != bcl->next_out) { + bcbuf_decr_acks(skb); + } else { + bcbuf_set_acks(skb, 0); bcl->next_out = next; bclink_set_last_sent(); } - if (bcbuf_acks(crs) == 0) { - bcl->first_out = next; - bcl->out_queue_size--; - kfree_skb(crs); + if (bcbuf_acks(skb) == 0) { + __skb_unlink(skb, &bcl->outqueue); + kfree_skb(skb); released = 1; } - crs = next; } n_ptr->bclink.acked = acked; /* Try resolving broadcast link congestion, if necessary */ - if (unlikely(bcl->next_out)) { tipc_link_push_packets(bcl); bclink_set_last_sent(); @@ -327,19 +328,16 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent) struct sk_buff *buf; /* Ignore "stale" link state info */ - if (less_eq(last_sent, n_ptr->bclink.last_in)) return; /* Update link synchronization state; quit if in sync */ - bclink_update_last_sent(n_ptr, last_sent); if (n_ptr->bclink.last_sent == n_ptr->bclink.last_in) return; /* Update out-of-sync state; quit if loss is still unconfirmed */ - if ((++n_ptr->bclink.oos_state) == 1) { if (n_ptr->bclink.deferred_size < (TIPC_MIN_LINK_WIN / 2)) return; @@ -347,12 +345,10 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent) } /* Don't NACK if one has been recently sent (or seen) */ - if (n_ptr->bclink.oos_state & 0x1) return; /* Send NACK */ - buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { struct tipc_msg *msg = buf_msg(buf); @@ -425,9 +421,11 @@ int tipc_bclink_xmit(struct sk_buff *buf) if (likely(bclink->bcast_nodes.count)) { rc = __tipc_link_xmit(bcl, buf); if (likely(!rc)) { + u32 len = skb_queue_len(&bcl->outqueue); + bclink_set_last_sent(); bcl->stats.queue_sz_counts++; - bcl->stats.accu_queue_sz += bcl->out_queue_size; + bcl->stats.accu_queue_sz += len; } bc = 1; } @@ -462,7 +460,6 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno) * Unicast an ACK periodically, ensuring that * all nodes in the cluster don't ACK at the same time */ - if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) { tipc_link_proto_xmit(node->active_links[node->addr & 1], STATE_MSG, 0, 0, 0, 0, 0); @@ -484,7 +481,6 @@ void tipc_bclink_rcv(struct sk_buff *buf) int deferred = 0; /* Screen out unwanted broadcast messages */ - if (msg_mc_netid(msg) != tipc_net_id) goto exit; @@ -497,7 +493,6 @@ void tipc_bclink_rcv(struct sk_buff *buf) goto unlock; /* Handle broadcast protocol message */ - if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { if (msg_type(msg) != STATE_MSG) goto unlock; @@ -518,14 +513,12 @@ void tipc_bclink_rcv(struct sk_buff *buf) } /* Handle in-sequence broadcast message */ - seqno = msg_seqno(msg); next_in = mod(node->bclink.last_in + 1); if (likely(seqno == next_in)) { receive: /* Deliver message to destination */ - if (likely(msg_isdata(msg))) { tipc_bclink_lock(); bclink_accept_pkt(node, seqno); @@ -574,7 +567,6 @@ void tipc_bclink_rcv(struct sk_buff *buf) buf = NULL; /* Determine new synchronization state */ - tipc_node_lock(node); if (unlikely(!tipc_node_is_up(node))) goto unlock; @@ -594,7 +586,6 @@ void tipc_bclink_rcv(struct sk_buff *buf) goto unlock; /* Take in-sequence message from deferred queue & deliver it */ - buf = node->bclink.deferred_head; node->bclink.deferred_head = buf->next; buf->next = NULL; @@ -603,7 +594,6 @@ void tipc_bclink_rcv(struct sk_buff *buf) } /* Handle out-of-sequence broadcast message */ - if (less(next_in, seqno)) { deferred = tipc_link_defer_pkt(&node->bclink.deferred_head, &node->bclink.deferred_tail, @@ -963,6 +953,7 @@ int tipc_bclink_init(void) sprintf(bcbearer->media.name, "tipc-broadcast"); spin_lock_init(&bclink->lock); + __skb_queue_head_init(&bcl->outqueue); __skb_queue_head_init(&bcl->waiting_sks); bcl->next_out_no = 1; spin_lock_init(&bclink->node.lock); diff --git a/net/tipc/link.c b/net/tipc/link.c index ddee498e74bc..9e94bf935e48 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -171,14 +171,17 @@ int tipc_link_is_active(struct tipc_link *l_ptr) */ static void link_timeout(struct tipc_link *l_ptr) { + struct sk_buff *skb; + tipc_node_lock(l_ptr->owner); /* update counters used in statistical profiling of send traffic */ - l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; + l_ptr->stats.accu_queue_sz += skb_queue_len(&l_ptr->outqueue); l_ptr->stats.queue_sz_counts++; - if (l_ptr->first_out) { - struct tipc_msg *msg = buf_msg(l_ptr->first_out); + skb = skb_peek(&l_ptr->outqueue); + if (skb) { + struct tipc_msg *msg = buf_msg(skb); u32 length = msg_size(msg); if ((msg_user(msg) == MSG_FRAGMENTER) && @@ -206,7 +209,6 @@ static void link_timeout(struct tipc_link *l_ptr) } /* do all other link processing performed on a periodic basis */ - link_state_event(l_ptr, TIMEOUT_EVT); if (l_ptr->next_out) @@ -289,6 +291,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, link_init_max_pkt(l_ptr); l_ptr->next_out_no = 1; + __skb_queue_head_init(&l_ptr->outqueue); __skb_queue_head_init(&l_ptr->waiting_sks); link_reset_statistics(l_ptr); @@ -367,7 +370,7 @@ static bool link_schedule_user(struct tipc_link *link, u32 oport, */ static void link_prepare_wakeup(struct tipc_link *link) { - uint pend_qsz = link->out_queue_size; + uint pend_qsz = skb_queue_len(&link->outqueue); struct sk_buff *skb, *tmp; skb_queue_walk_safe(&link->waiting_sks, skb, tmp) { @@ -379,17 +382,6 @@ static void link_prepare_wakeup(struct tipc_link *link) } } -/** - * link_release_outqueue - purge link's outbound message queue - * @l_ptr: pointer to link - */ -static void link_release_outqueue(struct tipc_link *l_ptr) -{ - kfree_skb_list(l_ptr->first_out); - l_ptr->first_out = NULL; - l_ptr->out_queue_size = 0; -} - /** * tipc_link_reset_fragments - purge link's inbound message fragments queue * @l_ptr: pointer to link @@ -407,7 +399,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr) void tipc_link_purge_queues(struct tipc_link *l_ptr) { kfree_skb_list(l_ptr->oldest_deferred_in); - kfree_skb_list(l_ptr->first_out); + __skb_queue_purge(&l_ptr->outqueue); tipc_link_reset_fragments(l_ptr); } @@ -440,14 +432,12 @@ void tipc_link_reset(struct tipc_link *l_ptr) } /* Clean up all queues: */ - link_release_outqueue(l_ptr); + __skb_queue_purge(&l_ptr->outqueue); kfree_skb_list(l_ptr->oldest_deferred_in); if (!skb_queue_empty(&l_ptr->waiting_sks)) { skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks); owner->action_flags |= TIPC_WAKEUP_USERS; } - l_ptr->last_out = NULL; - l_ptr->first_out = NULL; l_ptr->next_out = NULL; l_ptr->unacked_window = 0; l_ptr->checkpoint = 1; @@ -703,18 +693,17 @@ static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf) /** * __tipc_link_xmit(): same as tipc_link_xmit, but destlink is known & locked * @link: link to use - * @buf: chain of buffers containing message + * @skb: chain of buffers containing message * Consumes the buffer chain, except when returning -ELINKCONG * Returns 0 if success, otherwise errno: -ELINKCONG, -EMSGSIZE (plain socket * user data messages) or -EHOSTUNREACH (all other messages/senders) * Only the socket functions tipc_send_stream() and tipc_send_packet() need * to act on the return value, since they may need to do more send attempts. */ -int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *buf) +int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb) { - struct tipc_msg *msg = buf_msg(buf); + struct tipc_msg *msg = buf_msg(skb); uint psz = msg_size(msg); - uint qsz = link->out_queue_size; uint sndlim = link->queue_limit[0]; uint imp = tipc_msg_tot_importance(msg); uint mtu = link->max_pkt; @@ -722,58 +711,50 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *buf) uint seqno = link->next_out_no; uint bc_last_in = link->owner->bclink.last_in; struct tipc_media_addr *addr = &link->media_addr; - struct sk_buff *next = buf->next; + struct sk_buff_head *outqueue = &link->outqueue; + struct sk_buff *next; /* Match queue limits against msg importance: */ - if (unlikely(qsz >= link->queue_limit[imp])) - return tipc_link_cong(link, buf); + if (unlikely(skb_queue_len(outqueue) >= link->queue_limit[imp])) + return tipc_link_cong(link, skb); /* Has valid packet limit been used ? */ if (unlikely(psz > mtu)) { - kfree_skb_list(buf); + kfree_skb_list(skb); return -EMSGSIZE; } /* Prepare each packet for sending, and add to outqueue: */ - while (buf) { - next = buf->next; - msg = buf_msg(buf); + while (skb) { + next = skb->next; + msg = buf_msg(skb); msg_set_word(msg, 2, ((ack << 16) | mod(seqno))); msg_set_bcast_ack(msg, bc_last_in); - if (!link->first_out) { - link->first_out = buf; - } else if (qsz < sndlim) { - link->last_out->next = buf; - } else if (tipc_msg_bundle(link->last_out, buf, mtu)) { + if (skb_queue_len(outqueue) < sndlim) { + __skb_queue_tail(outqueue, skb); + tipc_bearer_send(link->bearer_id, skb, addr); + link->next_out = NULL; + link->unacked_window = 0; + } else if (tipc_msg_bundle(outqueue, skb, mtu)) { link->stats.sent_bundled++; - buf = next; - next = buf->next; + skb = next; continue; - } else if (tipc_msg_make_bundle(&buf, mtu, link->addr)) { + } else if (tipc_msg_make_bundle(outqueue, skb, mtu, + link->addr)) { link->stats.sent_bundled++; link->stats.sent_bundles++; - link->last_out->next = buf; if (!link->next_out) - link->next_out = buf; + link->next_out = skb_peek_tail(outqueue); } else { - link->last_out->next = buf; + __skb_queue_tail(outqueue, skb); if (!link->next_out) - link->next_out = buf; - } - - /* Send packet if possible: */ - if (likely(++qsz <= sndlim)) { - tipc_bearer_send(link->bearer_id, buf, addr); - link->next_out = next; - link->unacked_window = 0; + link->next_out = skb; } seqno++; - link->last_out = buf; - buf = next; + skb = next; } link->next_out_no = seqno; - link->out_queue_size = qsz; return 0; } @@ -851,6 +832,14 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf) kfree_skb(buf); } +struct sk_buff *tipc_skb_queue_next(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + if (skb_queue_is_last(list, skb)) + return NULL; + return skb->next; +} + /* * tipc_link_push_packets - push unsent packets to bearer * @@ -861,15 +850,15 @@ static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf) */ void tipc_link_push_packets(struct tipc_link *l_ptr) { - struct sk_buff *skb; + struct sk_buff_head *outqueue = &l_ptr->outqueue; + struct sk_buff *skb = l_ptr->next_out; struct tipc_msg *msg; u32 next, first; - while (l_ptr->next_out) { - skb = l_ptr->next_out; + skb_queue_walk_from(outqueue, skb) { msg = buf_msg(skb); next = msg_seqno(msg); - first = buf_seqno(l_ptr->first_out); + first = buf_seqno(skb_peek(outqueue)); if (mod(next - first) < l_ptr->queue_limit[0]) { msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); @@ -878,7 +867,7 @@ void tipc_link_push_packets(struct tipc_link *l_ptr) TIPC_SKB_CB(skb)->bundling = false; tipc_bearer_send(l_ptr->bearer_id, skb, &l_ptr->media_addr); - l_ptr->next_out = skb->next; + l_ptr->next_out = tipc_skb_queue_next(outqueue, skb); } else { break; } @@ -946,20 +935,20 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, } } -void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, +void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb, u32 retransmits) { struct tipc_msg *msg; - if (!buf) + if (!skb) return; - msg = buf_msg(buf); + msg = buf_msg(skb); /* Detect repeated retransmit failures */ if (l_ptr->last_retransmitted == msg_seqno(msg)) { if (++l_ptr->stale_count > 100) { - link_retransmit_failure(l_ptr, buf); + link_retransmit_failure(l_ptr, skb); return; } } else { @@ -967,12 +956,13 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, l_ptr->stale_count = 1; } - while (retransmits && (buf != l_ptr->next_out) && buf) { - msg = buf_msg(buf); + skb_queue_walk_from(&l_ptr->outqueue, skb) { + if (!retransmits || skb == l_ptr->next_out) + break; + msg = buf_msg(skb); msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr); - buf = buf->next; + tipc_bearer_send(l_ptr->bearer_id, skb, &l_ptr->media_addr); retransmits--; l_ptr->stats.retransmitted++; } @@ -1067,12 +1057,12 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) while (head) { struct tipc_node *n_ptr; struct tipc_link *l_ptr; - struct sk_buff *crs; struct sk_buff *buf = head; + struct sk_buff *skb1, *tmp; struct tipc_msg *msg; u32 seq_no; u32 ackd; - u32 released = 0; + u32 released; head = head->next; buf->next = NULL; @@ -1131,17 +1121,14 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) if (n_ptr->bclink.recv_permitted) tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); - crs = l_ptr->first_out; - while ((crs != l_ptr->next_out) && - less_eq(buf_seqno(crs), ackd)) { - struct sk_buff *next = crs->next; - kfree_skb(crs); - crs = next; - released++; - } - if (released) { - l_ptr->first_out = crs; - l_ptr->out_queue_size -= released; + released = 0; + skb_queue_walk_safe(&l_ptr->outqueue, skb1, tmp) { + if (skb1 == l_ptr->next_out || + more(buf_seqno(skb1), ackd)) + break; + __skb_unlink(skb1, &l_ptr->outqueue); + kfree_skb(skb1); + released = 1; } /* Try sending any messages link endpoint has pending */ @@ -1590,7 +1577,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf) } if (msg_seq_gap(msg)) { l_ptr->stats.recv_nacks++; - tipc_link_retransmit(l_ptr, l_ptr->first_out, + tipc_link_retransmit(l_ptr, skb_peek(&l_ptr->outqueue), msg_seq_gap(msg)); } break; @@ -1637,10 +1624,10 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr, */ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) { - u32 msgcount = l_ptr->out_queue_size; - struct sk_buff *crs = l_ptr->first_out; + u32 msgcount = skb_queue_len(&l_ptr->outqueue); struct tipc_link *tunnel = l_ptr->owner->active_links[0]; struct tipc_msg tunnel_hdr; + struct sk_buff *skb; int split_bundles; if (!tunnel) @@ -1651,14 +1638,12 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); msg_set_msgcnt(&tunnel_hdr, msgcount); - if (!l_ptr->first_out) { - struct sk_buff *buf; - - buf = tipc_buf_acquire(INT_H_SIZE); - if (buf) { - skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); + if (skb_queue_empty(&l_ptr->outqueue)) { + skb = tipc_buf_acquire(INT_H_SIZE); + if (skb) { + skb_copy_to_linear_data(skb, &tunnel_hdr, INT_H_SIZE); msg_set_size(&tunnel_hdr, INT_H_SIZE); - __tipc_link_xmit(tunnel, buf); + __tipc_link_xmit(tunnel, skb); } else { pr_warn("%sunable to send changeover msg\n", link_co_err); @@ -1669,8 +1654,8 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) split_bundles = (l_ptr->owner->active_links[0] != l_ptr->owner->active_links[1]); - while (crs) { - struct tipc_msg *msg = buf_msg(crs); + skb_queue_walk(&l_ptr->outqueue, skb) { + struct tipc_msg *msg = buf_msg(skb); if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { struct tipc_msg *m = msg_get_wrapped(msg); @@ -1688,7 +1673,6 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) tipc_link_tunnel_xmit(l_ptr, &tunnel_hdr, msg, msg_link_selector(msg)); } - crs = crs->next; } } @@ -1704,17 +1688,16 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, struct tipc_link *tunnel) { - struct sk_buff *iter; + struct sk_buff *skb; struct tipc_msg tunnel_hdr; tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr); - msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); + msg_set_msgcnt(&tunnel_hdr, skb_queue_len(&l_ptr->outqueue)); msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); - iter = l_ptr->first_out; - while (iter) { - struct sk_buff *outbuf; - struct tipc_msg *msg = buf_msg(iter); + skb_queue_walk(&l_ptr->outqueue, skb) { + struct sk_buff *outskb; + struct tipc_msg *msg = buf_msg(skb); u32 length = msg_size(msg); if (msg_user(msg) == MSG_BUNDLER) @@ -1722,19 +1705,18 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); msg_set_size(&tunnel_hdr, length + INT_H_SIZE); - outbuf = tipc_buf_acquire(length + INT_H_SIZE); - if (outbuf == NULL) { + outskb = tipc_buf_acquire(length + INT_H_SIZE); + if (outskb == NULL) { pr_warn("%sunable to send duplicate msg\n", link_co_err); return; } - skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); - skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, + skb_copy_to_linear_data(outskb, &tunnel_hdr, INT_H_SIZE); + skb_copy_to_linear_data_offset(outskb, INT_H_SIZE, skb->data, length); - __tipc_link_xmit(tunnel, outbuf); + __tipc_link_xmit(tunnel, outskb); if (!tipc_link_is_up(l_ptr)) return; - iter = iter->next; } } diff --git a/net/tipc/link.h b/net/tipc/link.h index 771123413d5f..96f1e1bf0798 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -119,9 +119,7 @@ struct tipc_stats { * @max_pkt: current maximum packet size for this link * @max_pkt_target: desired maximum packet size for this link * @max_pkt_probes: # of probes based on current (max_pkt, max_pkt_target) - * @out_queue_size: # of messages in outbound message queue - * @first_out: ptr to first outbound message in queue - * @last_out: ptr to last outbound message in queue + * @outqueue: outbound message queue * @next_out_no: next sequence number to use for outbound messages * @last_retransmitted: sequence number of most recently retransmitted message * @stale_count: # of identical retransmit requests made by peer @@ -173,9 +171,7 @@ struct tipc_link { u32 max_pkt_probes; /* Sending */ - u32 out_queue_size; - struct sk_buff *first_out; - struct sk_buff *last_out; + struct sk_buff_head outqueue; u32 next_out_no; u32 last_retransmitted; u32 stale_count; @@ -233,6 +229,8 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *start, u32 retransmits); +struct sk_buff *tipc_skb_queue_next(const struct sk_buff_head *list, + const struct sk_buff *skb); int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb); int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info); @@ -258,6 +256,11 @@ static inline int less_eq(u32 left, u32 right) return mod(right - left) < 32768u; } +static inline int more(u32 left, u32 right) +{ + return !less_eq(left, right); +} + static inline int less(u32 left, u32 right) { return less_eq(left, right) && (mod(right) != mod(left)); @@ -294,7 +297,7 @@ static inline int link_reset_reset(struct tipc_link *l_ptr) static inline int link_congested(struct tipc_link *l_ptr) { - return l_ptr->out_queue_size >= l_ptr->queue_limit[0]; + return skb_queue_len(&l_ptr->outqueue) >= l_ptr->queue_limit[0]; } #endif diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 94db39217248..ce7514ae6bf3 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -265,16 +265,17 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, /** * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one - * @bbuf: the existing buffer ("bundle") - * @buf: buffer to be appended + * @list: the buffer chain of the existing buffer ("bundle") + * @skb: buffer to be appended * @mtu: max allowable size for the bundle buffer * Consumes buffer if successful * Returns true if bundling could be performed, otherwise false */ -bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu) +bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu) { - struct tipc_msg *bmsg = buf_msg(bbuf); - struct tipc_msg *msg = buf_msg(buf); + struct sk_buff *bskb = skb_peek_tail(list); + struct tipc_msg *bmsg = buf_msg(bskb); + struct tipc_msg *msg = buf_msg(skb); unsigned int bsz = msg_size(bmsg); unsigned int msz = msg_size(msg); u32 start = align(bsz); @@ -289,35 +290,36 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu) return false; if (likely(msg_user(bmsg) != MSG_BUNDLER)) return false; - if (likely(!TIPC_SKB_CB(bbuf)->bundling)) + if (likely(!TIPC_SKB_CB(bskb)->bundling)) return false; - if (unlikely(skb_tailroom(bbuf) < (pad + msz))) + if (unlikely(skb_tailroom(bskb) < (pad + msz))) return false; if (unlikely(max < (start + msz))) return false; - skb_put(bbuf, pad + msz); - skb_copy_to_linear_data_offset(bbuf, start, buf->data, msz); + skb_put(bskb, pad + msz); + skb_copy_to_linear_data_offset(bskb, start, skb->data, msz); msg_set_size(bmsg, start + msz); msg_set_msgcnt(bmsg, msg_msgcnt(bmsg) + 1); - bbuf->next = buf->next; - kfree_skb(buf); + kfree_skb(skb); return true; } /** * tipc_msg_make_bundle(): Create bundle buf and append message to its tail - * @buf: buffer to be appended and replaced - * @mtu: max allowable size for the bundle buffer, inclusive header + * @list: the buffer chain + * @skb: buffer to be appended and replaced + * @mtu: max allowable size for the bundle buffer, inclusive header * @dnode: destination node for message. (Not always present in header) * Replaces buffer if successful * Returns true if success, otherwise false */ -bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode) +bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, + u32 mtu, u32 dnode) { - struct sk_buff *bbuf; + struct sk_buff *bskb; struct tipc_msg *bmsg; - struct tipc_msg *msg = buf_msg(*buf); + struct tipc_msg *msg = buf_msg(skb); u32 msz = msg_size(msg); u32 max = mtu - INT_H_SIZE; @@ -330,21 +332,19 @@ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode) if (msz > (max / 2)) return false; - bbuf = tipc_buf_acquire(max); - if (!bbuf) + bskb = tipc_buf_acquire(max); + if (!bskb) return false; - skb_trim(bbuf, INT_H_SIZE); - bmsg = buf_msg(bbuf); + skb_trim(bskb, INT_H_SIZE); + bmsg = buf_msg(bskb); tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode); msg_set_seqno(bmsg, msg_seqno(msg)); msg_set_ack(bmsg, msg_ack(msg)); msg_set_bcast_ack(bmsg, msg_bcast_ack(msg)); - bbuf->next = (*buf)->next; - TIPC_SKB_CB(bbuf)->bundling = true; - tipc_msg_bundle(bbuf, *buf, mtu); - *buf = bbuf; - return true; + TIPC_SKB_CB(bskb)->bundling = true; + __skb_queue_tail(list, bskb); + return tipc_msg_bundle(list, skb, mtu); } /** diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 8ca874d6b4dc..53e425f12343 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -734,9 +734,10 @@ struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf); -bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu); +bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu); -bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode); +bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, + u32 mtu, u32 dnode); int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, int dsz, int mtu , struct sk_buff **chain); -- GitLab From bc6fecd4098df2d21b056486e5b418c84be95032 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:53 +0800 Subject: [PATCH 6656/9457] tipc: use generic SKB list APIs to manage deferred queue of link Use standard SKB list APIs associated with struct sk_buff_head to manage link's deferred queue, simplifying relevant code. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bcast.c | 20 ++++++------- net/tipc/link.c | 74 +++++++++++++++++++++--------------------------- net/tipc/link.h | 11 ++----- net/tipc/node.c | 4 +-- net/tipc/node.h | 7 ++--- 5 files changed, 47 insertions(+), 69 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 4a1a3c8627d0..7b238b1f339b 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -352,6 +352,8 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent) buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { struct tipc_msg *msg = buf_msg(buf); + struct sk_buff *skb = skb_peek(&n_ptr->bclink.deferred_queue); + u32 to = skb ? buf_seqno(skb) - 1 : n_ptr->bclink.last_sent; tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, n_ptr->addr); @@ -359,9 +361,7 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent) msg_set_mc_netid(msg, tipc_net_id); msg_set_bcast_ack(msg, n_ptr->bclink.last_in); msg_set_bcgap_after(msg, n_ptr->bclink.last_in); - msg_set_bcgap_to(msg, n_ptr->bclink.deferred_head - ? buf_seqno(n_ptr->bclink.deferred_head) - 1 - : n_ptr->bclink.last_sent); + msg_set_bcgap_to(msg, to); tipc_bclink_lock(); tipc_bearer_send(MAX_BEARERS, buf, NULL); @@ -574,31 +574,26 @@ void tipc_bclink_rcv(struct sk_buff *buf) if (node->bclink.last_in == node->bclink.last_sent) goto unlock; - if (!node->bclink.deferred_head) { + if (skb_queue_empty(&node->bclink.deferred_queue)) { node->bclink.oos_state = 1; goto unlock; } - msg = buf_msg(node->bclink.deferred_head); + msg = buf_msg(skb_peek(&node->bclink.deferred_queue)); seqno = msg_seqno(msg); next_in = mod(next_in + 1); if (seqno != next_in) goto unlock; /* Take in-sequence message from deferred queue & deliver it */ - buf = node->bclink.deferred_head; - node->bclink.deferred_head = buf->next; - buf->next = NULL; - node->bclink.deferred_size--; + buf = __skb_dequeue(&node->bclink.deferred_queue); goto receive; } /* Handle out-of-sequence broadcast message */ if (less(next_in, seqno)) { - deferred = tipc_link_defer_pkt(&node->bclink.deferred_head, - &node->bclink.deferred_tail, + deferred = tipc_link_defer_pkt(&node->bclink.deferred_queue, buf); - node->bclink.deferred_size += deferred; bclink_update_last_sent(node, seqno); buf = NULL; } @@ -954,6 +949,7 @@ int tipc_bclink_init(void) spin_lock_init(&bclink->lock); __skb_queue_head_init(&bcl->outqueue); + __skb_queue_head_init(&bcl->deferred_queue); __skb_queue_head_init(&bcl->waiting_sks); bcl->next_out_no = 1; spin_lock_init(&bclink->node.lock); diff --git a/net/tipc/link.c b/net/tipc/link.c index 9e94bf935e48..d9c2310e417d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -292,6 +292,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, l_ptr->next_out_no = 1; __skb_queue_head_init(&l_ptr->outqueue); + __skb_queue_head_init(&l_ptr->deferred_queue); __skb_queue_head_init(&l_ptr->waiting_sks); link_reset_statistics(l_ptr); @@ -398,7 +399,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr) */ void tipc_link_purge_queues(struct tipc_link *l_ptr) { - kfree_skb_list(l_ptr->oldest_deferred_in); + __skb_queue_purge(&l_ptr->deferred_queue); __skb_queue_purge(&l_ptr->outqueue); tipc_link_reset_fragments(l_ptr); } @@ -433,7 +434,7 @@ void tipc_link_reset(struct tipc_link *l_ptr) /* Clean up all queues: */ __skb_queue_purge(&l_ptr->outqueue); - kfree_skb_list(l_ptr->oldest_deferred_in); + __skb_queue_purge(&l_ptr->deferred_queue); if (!skb_queue_empty(&l_ptr->waiting_sks)) { skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks); owner->action_flags |= TIPC_WAKEUP_USERS; @@ -442,9 +443,6 @@ void tipc_link_reset(struct tipc_link *l_ptr) l_ptr->unacked_window = 0; l_ptr->checkpoint = 1; l_ptr->next_out_no = 1; - l_ptr->deferred_inqueue_sz = 0; - l_ptr->oldest_deferred_in = NULL; - l_ptr->newest_deferred_in = NULL; l_ptr->fsm_msg_cnt = 0; l_ptr->stale_count = 0; link_reset_statistics(l_ptr); @@ -974,19 +972,23 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb, static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr, struct sk_buff *buf) { + struct sk_buff_head head; + struct sk_buff *skb = NULL; u32 seq_no; - if (l_ptr->oldest_deferred_in == NULL) + if (skb_queue_empty(&l_ptr->deferred_queue)) return buf; - seq_no = buf_seqno(l_ptr->oldest_deferred_in); + seq_no = buf_seqno(skb_peek(&l_ptr->deferred_queue)); if (seq_no == mod(l_ptr->next_in_no)) { - l_ptr->newest_deferred_in->next = buf; - buf = l_ptr->oldest_deferred_in; - l_ptr->oldest_deferred_in = NULL; - l_ptr->deferred_inqueue_sz = 0; + __skb_queue_head_init(&head); + skb_queue_splice_tail_init(&l_ptr->deferred_queue, &head); + skb = head.next; + skb->prev = NULL; + head.prev->next = buf; + head.prev->prev = NULL; } - return buf; + return skb; } /** @@ -1170,7 +1172,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) continue; } l_ptr->next_in_no++; - if (unlikely(l_ptr->oldest_deferred_in)) + if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue))) head = link_insert_deferred_queue(l_ptr, head); if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) { @@ -1273,48 +1275,37 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf) * * Returns increase in queue length (i.e. 0 or 1) */ -u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, - struct sk_buff *buf) +u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb) { - struct sk_buff *queue_buf; - struct sk_buff **prev; - u32 seq_no = buf_seqno(buf); - - buf->next = NULL; + struct sk_buff *skb1; + u32 seq_no = buf_seqno(skb); /* Empty queue ? */ - if (*head == NULL) { - *head = *tail = buf; + if (skb_queue_empty(list)) { + __skb_queue_tail(list, skb); return 1; } /* Last ? */ - if (less(buf_seqno(*tail), seq_no)) { - (*tail)->next = buf; - *tail = buf; + if (less(buf_seqno(skb_peek_tail(list)), seq_no)) { + __skb_queue_tail(list, skb); return 1; } /* Locate insertion point in queue, then insert; discard if duplicate */ - prev = head; - queue_buf = *head; - for (;;) { - u32 curr_seqno = buf_seqno(queue_buf); + skb_queue_walk(list, skb1) { + u32 curr_seqno = buf_seqno(skb1); if (seq_no == curr_seqno) { - kfree_skb(buf); + kfree_skb(skb); return 0; } if (less(seq_no, curr_seqno)) break; - - prev = &queue_buf->next; - queue_buf = queue_buf->next; } - buf->next = queue_buf; - *prev = buf; + __skb_queue_before(list, skb1, skb); return 1; } @@ -1344,15 +1335,14 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, return; } - if (tipc_link_defer_pkt(&l_ptr->oldest_deferred_in, - &l_ptr->newest_deferred_in, buf)) { - l_ptr->deferred_inqueue_sz++; + if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) { l_ptr->stats.deferred_recv++; TIPC_SKB_CB(buf)->deferred = true; - if ((l_ptr->deferred_inqueue_sz % 16) == 1) + if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1) tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); - } else + } else { l_ptr->stats.duplicates++; + } } /* @@ -1388,8 +1378,8 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg, if (l_ptr->next_out) next_sent = buf_seqno(l_ptr->next_out); msg_set_next_sent(msg, next_sent); - if (l_ptr->oldest_deferred_in) { - u32 rec = buf_seqno(l_ptr->oldest_deferred_in); + if (!skb_queue_empty(&l_ptr->deferred_queue)) { + u32 rec = buf_seqno(skb_peek(&l_ptr->deferred_queue)); gap = mod(rec - mod(l_ptr->next_in_no)); } msg_set_seq_gap(msg, gap); diff --git a/net/tipc/link.h b/net/tipc/link.h index 96f1e1bf0798..de7b8833641a 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -124,9 +124,7 @@ struct tipc_stats { * @last_retransmitted: sequence number of most recently retransmitted message * @stale_count: # of identical retransmit requests made by peer * @next_in_no: next sequence number to expect for inbound messages - * @deferred_inqueue_sz: # of messages in inbound message queue - * @oldest_deferred_in: ptr to first inbound message in queue - * @newest_deferred_in: ptr to last inbound message in queue + * @deferred_queue: deferred queue saved OOS b'cast message received from node * @unacked_window: # of inbound messages rx'd without ack'ing back to peer * @next_out: ptr to first unsent outbound message in queue * @waiting_sks: linked list of sockets waiting for link congestion to abate @@ -178,9 +176,7 @@ struct tipc_link { /* Reception */ u32 next_in_no; - u32 deferred_inqueue_sz; - struct sk_buff *oldest_deferred_in; - struct sk_buff *newest_deferred_in; + struct sk_buff_head deferred_queue; u32 unacked_window; /* Congestion handling */ @@ -224,8 +220,7 @@ void tipc_link_bundle_rcv(struct sk_buff *buf); void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob, u32 gap, u32 tolerance, u32 priority, u32 acked_mtu); void tipc_link_push_packets(struct tipc_link *l_ptr); -u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, - struct sk_buff *buf); +u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *buf); void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window); void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *start, u32 retransmits); diff --git a/net/tipc/node.c b/net/tipc/node.c index 17b8092f9c40..69b96be09a86 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -116,6 +116,7 @@ struct tipc_node *tipc_node_create(u32 addr) INIT_LIST_HEAD(&n_ptr->publ_list); INIT_LIST_HEAD(&n_ptr->conn_sks); __skb_queue_head_init(&n_ptr->waiting_sks); + __skb_queue_head_init(&n_ptr->bclink.deferred_queue); hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); @@ -381,8 +382,7 @@ static void node_lost_contact(struct tipc_node *n_ptr) /* Flush broadcast link info associated with lost node */ if (n_ptr->bclink.recv_permitted) { - kfree_skb_list(n_ptr->bclink.deferred_head); - n_ptr->bclink.deferred_size = 0; + __skb_queue_purge(&n_ptr->bclink.deferred_queue); if (n_ptr->bclink.reasm_buf) { kfree_skb(n_ptr->bclink.reasm_buf); diff --git a/net/tipc/node.h b/net/tipc/node.h index f1994511f033..cbe0e950f1cc 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -71,9 +71,7 @@ enum { * @last_in: sequence # of last in-sequence b'cast message received from node * @last_sent: sequence # of last b'cast message sent by node * @oos_state: state tracker for handling OOS b'cast messages - * @deferred_size: number of OOS b'cast messages in deferred queue - * @deferred_head: oldest OOS b'cast message received from node - * @deferred_tail: newest OOS b'cast message received from node + * @deferred_queue: deferred queue saved OOS b'cast message received from node * @reasm_buf: broadcast reassembly queue head from node * @recv_permitted: true if node is allowed to receive b'cast messages */ @@ -83,8 +81,7 @@ struct tipc_node_bclink { u32 last_sent; u32 oos_state; u32 deferred_size; - struct sk_buff *deferred_head; - struct sk_buff *deferred_tail; + struct sk_buff_head deferred_queue; struct sk_buff *reasm_buf; bool recv_permitted; }; -- GitLab From f03273f1e2fc8a59c3831200dd1532cf29e37e35 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:54 +0800 Subject: [PATCH 6657/9457] tipc: use generic SKB list APIs to manage link receive queue Use standard SKB list APIs associated with struct sk_buff_head to manage link's receive queue to simplify its relevant code cemplexity. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bearer.h | 2 +- net/tipc/link.c | 85 ++++++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 50 deletions(-) diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index b1d905209e83..2c1230ac5dfe 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -165,7 +165,7 @@ extern struct tipc_bearer __rcu *bearer_list[]; * TIPC routines available to supported media types */ -void tipc_rcv(struct sk_buff *buf, struct tipc_bearer *tb_ptr); +void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *tb_ptr); int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority); int tipc_disable_bearer(const char *name); diff --git a/net/tipc/link.c b/net/tipc/link.c index d9c2310e417d..0e04508cdba4 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -966,29 +966,17 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb, } } -/** - * link_insert_deferred_queue - insert deferred messages back into receive chain - */ -static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr, - struct sk_buff *buf) +static void link_retrieve_defq(struct tipc_link *link, + struct sk_buff_head *list) { - struct sk_buff_head head; - struct sk_buff *skb = NULL; u32 seq_no; - if (skb_queue_empty(&l_ptr->deferred_queue)) - return buf; - - seq_no = buf_seqno(skb_peek(&l_ptr->deferred_queue)); - if (seq_no == mod(l_ptr->next_in_no)) { - __skb_queue_head_init(&head); - skb_queue_splice_tail_init(&l_ptr->deferred_queue, &head); - skb = head.next; - skb->prev = NULL; - head.prev->next = buf; - head.prev->prev = NULL; - } - return skb; + if (skb_queue_empty(&link->deferred_queue)) + return; + + seq_no = buf_seqno(skb_peek(&link->deferred_queue)); + if (seq_no == mod(link->next_in_no)) + skb_queue_splice_tail_init(&link->deferred_queue, list); } /** @@ -1048,43 +1036,43 @@ static int link_recv_buf_validate(struct sk_buff *buf) /** * tipc_rcv - process TIPC packets/messages arriving from off-node - * @head: pointer to message buffer chain + * @skb: TIPC packet * @b_ptr: pointer to bearer message arrived on * * Invoked with no locks held. Bearer pointer must point to a valid bearer * structure (i.e. cannot be NULL), but bearer can be inactive. */ -void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) +void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *b_ptr) { - while (head) { - struct tipc_node *n_ptr; - struct tipc_link *l_ptr; - struct sk_buff *buf = head; - struct sk_buff *skb1, *tmp; - struct tipc_msg *msg; - u32 seq_no; - u32 ackd; - u32 released; + struct sk_buff_head head; + struct tipc_node *n_ptr; + struct tipc_link *l_ptr; + struct sk_buff *skb1, *tmp; + struct tipc_msg *msg; + u32 seq_no; + u32 ackd; + u32 released; - head = head->next; - buf->next = NULL; + __skb_queue_head_init(&head); + __skb_queue_tail(&head, skb); + while ((skb = __skb_dequeue(&head))) { /* Ensure message is well-formed */ - if (unlikely(!link_recv_buf_validate(buf))) + if (unlikely(!link_recv_buf_validate(skb))) goto discard; /* Ensure message data is a single contiguous unit */ - if (unlikely(skb_linearize(buf))) + if (unlikely(skb_linearize(skb))) goto discard; /* Handle arrival of a non-unicast link message */ - msg = buf_msg(buf); + msg = buf_msg(skb); if (unlikely(msg_non_seq(msg))) { if (msg_user(msg) == LINK_CONFIG) - tipc_disc_rcv(buf, b_ptr); + tipc_disc_rcv(skb, b_ptr); else - tipc_bclink_rcv(buf); + tipc_bclink_rcv(skb); continue; } @@ -1145,8 +1133,8 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) /* Process the incoming packet */ if (unlikely(!link_working_working(l_ptr))) { if (msg_user(msg) == LINK_PROTOCOL) { - tipc_link_proto_rcv(l_ptr, buf); - head = link_insert_deferred_queue(l_ptr, head); + tipc_link_proto_rcv(l_ptr, skb); + link_retrieve_defq(l_ptr, &head); tipc_node_unlock(n_ptr); continue; } @@ -1156,8 +1144,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) if (link_working_working(l_ptr)) { /* Re-insert buffer in front of queue */ - buf->next = head; - head = buf; + __skb_queue_head(&head, skb); tipc_node_unlock(n_ptr); continue; } @@ -1166,33 +1153,33 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) /* Link is now in state WORKING_WORKING */ if (unlikely(seq_no != mod(l_ptr->next_in_no))) { - link_handle_out_of_seq_msg(l_ptr, buf); - head = link_insert_deferred_queue(l_ptr, head); + link_handle_out_of_seq_msg(l_ptr, skb); + link_retrieve_defq(l_ptr, &head); tipc_node_unlock(n_ptr); continue; } l_ptr->next_in_no++; if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue))) - head = link_insert_deferred_queue(l_ptr, head); + link_retrieve_defq(l_ptr, &head); if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) { l_ptr->stats.sent_acks++; tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); } - if (tipc_link_prepare_input(l_ptr, &buf)) { + if (tipc_link_prepare_input(l_ptr, &skb)) { tipc_node_unlock(n_ptr); continue; } tipc_node_unlock(n_ptr); - msg = buf_msg(buf); - if (tipc_link_input(l_ptr, buf) != 0) + + if (tipc_link_input(l_ptr, skb) != 0) goto discard; continue; unlock_discard: tipc_node_unlock(n_ptr); discard: - kfree_skb(buf); + kfree_skb(skb); } } -- GitLab From a6ca109443842e7251c68451f8137ae68ae6d8a6 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Wed, 26 Nov 2014 11:41:55 +0800 Subject: [PATCH 6658/9457] tipc: use generic SKB list APIs to manage TIPC outgoing packet chains Use standard SKB list APIs associated with struct sk_buff_head to manage socket outgoing packet chain and name table outgoing packet chain, having relevant code simpler and more readable. Signed-off-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/bcast.c | 20 +++---- net/tipc/bcast.h | 2 +- net/tipc/link.c | 98 ++++++++++++++++++++------------ net/tipc/link.h | 5 +- net/tipc/msg.c | 74 ++++++++++++------------ net/tipc/msg.h | 6 +- net/tipc/name_distr.c | 46 ++++++++------- net/tipc/socket.c | 127 ++++++++++++++++++++++-------------------- 8 files changed, 203 insertions(+), 175 deletions(-) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 7b238b1f339b..f0761c771734 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -398,20 +398,20 @@ static void bclink_peek_nack(struct tipc_msg *msg) /* tipc_bclink_xmit - broadcast buffer chain to all nodes in cluster * and to identified node local sockets - * @buf: chain of buffers containing message + * @list: chain of buffers containing message * Consumes the buffer chain, except when returning -ELINKCONG * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE */ -int tipc_bclink_xmit(struct sk_buff *buf) +int tipc_bclink_xmit(struct sk_buff_head *list) { int rc = 0; int bc = 0; - struct sk_buff *clbuf; + struct sk_buff *skb; /* Prepare clone of message for local node */ - clbuf = tipc_msg_reassemble(buf); - if (unlikely(!clbuf)) { - kfree_skb_list(buf); + skb = tipc_msg_reassemble(list); + if (unlikely(!skb)) { + __skb_queue_purge(list); return -EHOSTUNREACH; } @@ -419,7 +419,7 @@ int tipc_bclink_xmit(struct sk_buff *buf) if (likely(bclink)) { tipc_bclink_lock(); if (likely(bclink->bcast_nodes.count)) { - rc = __tipc_link_xmit(bcl, buf); + rc = __tipc_link_xmit(bcl, list); if (likely(!rc)) { u32 len = skb_queue_len(&bcl->outqueue); @@ -433,13 +433,13 @@ int tipc_bclink_xmit(struct sk_buff *buf) } if (unlikely(!bc)) - kfree_skb_list(buf); + __skb_queue_purge(list); /* Deliver message clone */ if (likely(!rc)) - tipc_sk_mcast_rcv(clbuf); + tipc_sk_mcast_rcv(skb); else - kfree_skb(clbuf); + kfree_skb(skb); return rc; } diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index 443de084d3e8..644d79129fba 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -100,7 +100,7 @@ int tipc_bclink_reset_stats(void); int tipc_bclink_set_queue_limits(u32 limit); void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action); uint tipc_bclink_get_mtu(void); -int tipc_bclink_xmit(struct sk_buff *buf); +int tipc_bclink_xmit(struct sk_buff_head *list); void tipc_bclink_wakeup_users(void); int tipc_nl_add_bc_link(struct tipc_nl_msg *msg); diff --git a/net/tipc/link.c b/net/tipc/link.c index 0e04508cdba4..34bf15c90c78 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -664,9 +664,10 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) * - For all other messages we discard the buffer and return -EHOSTUNREACH * - For TIPC internal messages we also reset the link */ -static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf) +static int tipc_link_cong(struct tipc_link *link, struct sk_buff_head *list) { - struct tipc_msg *msg = buf_msg(buf); + struct sk_buff *skb = skb_peek(list); + struct tipc_msg *msg = buf_msg(skb); uint imp = tipc_msg_tot_importance(msg); u32 oport = msg_tot_origport(msg); @@ -679,28 +680,29 @@ static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf) goto drop; if (unlikely(msg_reroute_cnt(msg))) goto drop; - if (TIPC_SKB_CB(buf)->wakeup_pending) + if (TIPC_SKB_CB(skb)->wakeup_pending) return -ELINKCONG; - if (link_schedule_user(link, oport, TIPC_SKB_CB(buf)->chain_sz, imp)) + if (link_schedule_user(link, oport, skb_queue_len(list), imp)) return -ELINKCONG; drop: - kfree_skb_list(buf); + __skb_queue_purge(list); return -EHOSTUNREACH; } /** * __tipc_link_xmit(): same as tipc_link_xmit, but destlink is known & locked * @link: link to use - * @skb: chain of buffers containing message + * @list: chain of buffers containing message + * * Consumes the buffer chain, except when returning -ELINKCONG * Returns 0 if success, otherwise errno: -ELINKCONG, -EMSGSIZE (plain socket * user data messages) or -EHOSTUNREACH (all other messages/senders) * Only the socket functions tipc_send_stream() and tipc_send_packet() need * to act on the return value, since they may need to do more send attempts. */ -int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb) +int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list) { - struct tipc_msg *msg = buf_msg(skb); + struct tipc_msg *msg = buf_msg(skb_peek(list)); uint psz = msg_size(msg); uint sndlim = link->queue_limit[0]; uint imp = tipc_msg_tot_importance(msg); @@ -710,21 +712,21 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb) uint bc_last_in = link->owner->bclink.last_in; struct tipc_media_addr *addr = &link->media_addr; struct sk_buff_head *outqueue = &link->outqueue; - struct sk_buff *next; + struct sk_buff *skb, *tmp; /* Match queue limits against msg importance: */ if (unlikely(skb_queue_len(outqueue) >= link->queue_limit[imp])) - return tipc_link_cong(link, skb); + return tipc_link_cong(link, list); /* Has valid packet limit been used ? */ if (unlikely(psz > mtu)) { - kfree_skb_list(skb); + __skb_queue_purge(list); return -EMSGSIZE; } /* Prepare each packet for sending, and add to outqueue: */ - while (skb) { - next = skb->next; + skb_queue_walk_safe(list, skb, tmp) { + __skb_unlink(skb, list); msg = buf_msg(skb); msg_set_word(msg, 2, ((ack << 16) | mod(seqno))); msg_set_bcast_ack(msg, bc_last_in); @@ -736,7 +738,6 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb) link->unacked_window = 0; } else if (tipc_msg_bundle(outqueue, skb, mtu)) { link->stats.sent_bundled++; - skb = next; continue; } else if (tipc_msg_make_bundle(outqueue, skb, mtu, link->addr)) { @@ -750,22 +751,43 @@ int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *skb) link->next_out = skb; } seqno++; - skb = next; } link->next_out_no = seqno; return 0; } +static void skb2list(struct sk_buff *skb, struct sk_buff_head *list) +{ + __skb_queue_head_init(list); + __skb_queue_tail(list, skb); +} + +static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb) +{ + struct sk_buff_head head; + + skb2list(skb, &head); + return __tipc_link_xmit(link, &head); +} + +int tipc_link_xmit_skb(struct sk_buff *skb, u32 dnode, u32 selector) +{ + struct sk_buff_head head; + + skb2list(skb, &head); + return tipc_link_xmit(&head, dnode, selector); +} + /** * tipc_link_xmit() is the general link level function for message sending - * @buf: chain of buffers containing message + * @list: chain of buffers containing message * @dsz: amount of user data to be sent * @dnode: address of destination node * @selector: a number used for deterministic link selection * Consumes the buffer chain, except when returning -ELINKCONG * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE */ -int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector) +int tipc_link_xmit(struct sk_buff_head *list, u32 dnode, u32 selector) { struct tipc_link *link = NULL; struct tipc_node *node; @@ -776,17 +798,22 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector) tipc_node_lock(node); link = node->active_links[selector & 1]; if (link) - rc = __tipc_link_xmit(link, buf); + rc = __tipc_link_xmit(link, list); tipc_node_unlock(node); } if (link) return rc; - if (likely(in_own_node(dnode))) - return tipc_sk_rcv(buf); + if (likely(in_own_node(dnode))) { + /* As a node local message chain never contains more than one + * buffer, we just need to dequeue one SKB buffer from the + * head list. + */ + return tipc_sk_rcv(__skb_dequeue(list)); + } + __skb_queue_purge(list); - kfree_skb_list(buf); return rc; } @@ -800,17 +827,17 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dnode, u32 selector) */ static void tipc_link_sync_xmit(struct tipc_link *link) { - struct sk_buff *buf; + struct sk_buff *skb; struct tipc_msg *msg; - buf = tipc_buf_acquire(INT_H_SIZE); - if (!buf) + skb = tipc_buf_acquire(INT_H_SIZE); + if (!skb) return; - msg = buf_msg(buf); + msg = buf_msg(skb); tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, link->addr); msg_set_last_bcast(msg, link->owner->bclink.acked); - __tipc_link_xmit(link, buf); + __tipc_link_xmit_skb(link, skb); } /* @@ -1053,8 +1080,7 @@ void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *b_ptr) u32 ackd; u32 released; - __skb_queue_head_init(&head); - __skb_queue_tail(&head, skb); + skb2list(skb, &head); while ((skb = __skb_dequeue(&head))) { /* Ensure message is well-formed */ @@ -1573,7 +1599,7 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr, u32 selector) { struct tipc_link *tunnel; - struct sk_buff *buf; + struct sk_buff *skb; u32 length = msg_size(msg); tunnel = l_ptr->owner->active_links[selector & 1]; @@ -1582,14 +1608,14 @@ static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr, return; } msg_set_size(tunnel_hdr, length + INT_H_SIZE); - buf = tipc_buf_acquire(length + INT_H_SIZE); - if (!buf) { + skb = tipc_buf_acquire(length + INT_H_SIZE); + if (!skb) { pr_warn("%sunable to send tunnel msg\n", link_co_err); return; } - skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); - skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); - __tipc_link_xmit(tunnel, buf); + skb_copy_to_linear_data(skb, tunnel_hdr, INT_H_SIZE); + skb_copy_to_linear_data_offset(skb, INT_H_SIZE, msg, length); + __tipc_link_xmit_skb(tunnel, skb); } @@ -1620,7 +1646,7 @@ void tipc_link_failover_send_queue(struct tipc_link *l_ptr) if (skb) { skb_copy_to_linear_data(skb, &tunnel_hdr, INT_H_SIZE); msg_set_size(&tunnel_hdr, INT_H_SIZE); - __tipc_link_xmit(tunnel, skb); + __tipc_link_xmit_skb(tunnel, skb); } else { pr_warn("%sunable to send changeover msg\n", link_co_err); @@ -1691,7 +1717,7 @@ void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, skb_copy_to_linear_data(outskb, &tunnel_hdr, INT_H_SIZE); skb_copy_to_linear_data_offset(outskb, INT_H_SIZE, skb->data, length); - __tipc_link_xmit(tunnel, outskb); + __tipc_link_xmit_skb(tunnel, outskb); if (!tipc_link_is_up(l_ptr)) return; } diff --git a/net/tipc/link.h b/net/tipc/link.h index de7b8833641a..55812e87ca1e 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -213,8 +213,9 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, void tipc_link_reset_all(struct tipc_node *node); void tipc_link_reset(struct tipc_link *l_ptr); void tipc_link_reset_list(unsigned int bearer_id); -int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); -int __tipc_link_xmit(struct tipc_link *link, struct sk_buff *buf); +int tipc_link_xmit_skb(struct sk_buff *skb, u32 dest, u32 selector); +int tipc_link_xmit(struct sk_buff_head *list, u32 dest, u32 selector); +int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list); u32 tipc_link_get_max_pkt(u32 dest, u32 selector); void tipc_link_bundle_rcv(struct sk_buff *buf); void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob, diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ce7514ae6bf3..5b0659791c07 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -166,11 +166,12 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) * @offset: Posision in iov to start copying from * @dsz: Total length of user data * @pktmax: Max packet size that can be used - * @chain: Buffer or chain of buffers to be returned to caller + * @list: Buffer or chain of buffers to be returned to caller + * * Returns message data size or errno: -ENOMEM, -EFAULT */ -int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, - int offset, int dsz, int pktmax , struct sk_buff **chain) +int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, + int dsz, int pktmax, struct sk_buff_head *list) { int mhsz = msg_hdr_sz(mhdr); int msz = mhsz + dsz; @@ -179,22 +180,22 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int pktrem = pktmax; int drem = dsz; struct tipc_msg pkthdr; - struct sk_buff *buf, *prev; + struct sk_buff *skb; char *pktpos; int rc; - uint chain_sz = 0; + msg_set_size(mhdr, msz); /* No fragmentation needed? */ if (likely(msz <= pktmax)) { - buf = tipc_buf_acquire(msz); - *chain = buf; - if (unlikely(!buf)) + skb = tipc_buf_acquire(msz); + if (unlikely(!skb)) return -ENOMEM; - skb_copy_to_linear_data(buf, mhdr, mhsz); - pktpos = buf->data + mhsz; - TIPC_SKB_CB(buf)->chain_sz = 1; - if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz)) + __skb_queue_tail(list, skb); + skb_copy_to_linear_data(skb, mhdr, mhsz); + pktpos = skb->data + mhsz; + if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, + dsz)) return dsz; rc = -EFAULT; goto error; @@ -207,15 +208,15 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, msg_set_fragm_no(&pkthdr, pktno); /* Prepare first fragment */ - *chain = buf = tipc_buf_acquire(pktmax); - if (!buf) + skb = tipc_buf_acquire(pktmax); + if (!skb) return -ENOMEM; - chain_sz = 1; - pktpos = buf->data; - skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); + __skb_queue_tail(list, skb); + pktpos = skb->data; + skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); pktpos += INT_H_SIZE; pktrem -= INT_H_SIZE; - skb_copy_to_linear_data_offset(buf, INT_H_SIZE, mhdr, mhsz); + skb_copy_to_linear_data_offset(skb, INT_H_SIZE, mhdr, mhsz); pktpos += mhsz; pktrem -= mhsz; @@ -238,28 +239,25 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, pktsz = drem + INT_H_SIZE; else pktsz = pktmax; - prev = buf; - buf = tipc_buf_acquire(pktsz); - if (!buf) { + skb = tipc_buf_acquire(pktsz); + if (!skb) { rc = -ENOMEM; goto error; } - chain_sz++; - prev->next = buf; + __skb_queue_tail(list, skb); msg_set_type(&pkthdr, FRAGMENT); msg_set_size(&pkthdr, pktsz); msg_set_fragm_no(&pkthdr, ++pktno); - skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); - pktpos = buf->data + INT_H_SIZE; + skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE); + pktpos = skb->data + INT_H_SIZE; pktrem = pktsz - INT_H_SIZE; } while (1); - TIPC_SKB_CB(*chain)->chain_sz = chain_sz; - msg_set_type(buf_msg(buf), LAST_FRAGMENT); + msg_set_type(buf_msg(skb), LAST_FRAGMENT); return dsz; error: - kfree_skb_list(*chain); - *chain = NULL; + __skb_queue_purge(list); + __skb_queue_head_init(list); return rc; } @@ -430,22 +428,23 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode) /* tipc_msg_reassemble() - clone a buffer chain of fragments and * reassemble the clones into one message */ -struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain) +struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list) { - struct sk_buff *buf = chain; - struct sk_buff *frag = buf; + struct sk_buff *skb; + struct sk_buff *frag = NULL; struct sk_buff *head = NULL; int hdr_sz; /* Copy header if single buffer */ - if (!buf->next) { - hdr_sz = skb_headroom(buf) + msg_hdr_sz(buf_msg(buf)); - return __pskb_copy(buf, hdr_sz, GFP_ATOMIC); + if (skb_queue_len(list) == 1) { + skb = skb_peek(list); + hdr_sz = skb_headroom(skb) + msg_hdr_sz(buf_msg(skb)); + return __pskb_copy(skb, hdr_sz, GFP_ATOMIC); } /* Clone all fragments and reassemble */ - while (buf) { - frag = skb_clone(buf, GFP_ATOMIC); + skb_queue_walk(list, skb) { + frag = skb_clone(skb, GFP_ATOMIC); if (!frag) goto error; frag->next = NULL; @@ -453,7 +452,6 @@ struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain) break; if (!head) goto error; - buf = buf->next; } return frag; error: diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 53e425f12343..d5c83d7ecb47 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -739,9 +739,9 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu); bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu, u32 dnode); -int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, - int offset, int dsz, int mtu , struct sk_buff **chain); +int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, + int dsz, int mtu, struct sk_buff_head *list); -struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain); +struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list); #endif diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 6c2638d3c659..56248db75274 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -114,9 +114,9 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) return buf; } -void named_cluster_distribute(struct sk_buff *buf) +void named_cluster_distribute(struct sk_buff *skb) { - struct sk_buff *obuf; + struct sk_buff *oskb; struct tipc_node *node; u32 dnode; @@ -127,15 +127,15 @@ void named_cluster_distribute(struct sk_buff *buf) continue; if (!tipc_node_active_links(node)) continue; - obuf = skb_copy(buf, GFP_ATOMIC); - if (!obuf) + oskb = skb_copy(skb, GFP_ATOMIC); + if (!oskb) break; - msg_set_destnode(buf_msg(obuf), dnode); - tipc_link_xmit(obuf, dnode, dnode); + msg_set_destnode(buf_msg(oskb), dnode); + tipc_link_xmit_skb(oskb, dnode, dnode); } rcu_read_unlock(); - kfree_skb(buf); + kfree_skb(skb); } /** @@ -190,15 +190,15 @@ struct sk_buff *tipc_named_withdraw(struct publication *publ) /** * named_distribute - prepare name info for bulk distribution to another node - * @msg_list: list of messages (buffers) to be returned from this function + * @list: list of messages (buffers) to be returned from this function * @dnode: node to be updated * @pls: linked list of publication items to be packed into buffer chain */ -static void named_distribute(struct list_head *msg_list, u32 dnode, +static void named_distribute(struct sk_buff_head *list, u32 dnode, struct publ_list *pls) { struct publication *publ; - struct sk_buff *buf = NULL; + struct sk_buff *skb = NULL; struct distr_item *item = NULL; uint dsz = pls->size * ITEM_SIZE; uint msg_dsz = (tipc_node_get_mtu(dnode, 0) / ITEM_SIZE) * ITEM_SIZE; @@ -207,15 +207,15 @@ static void named_distribute(struct list_head *msg_list, u32 dnode, list_for_each_entry(publ, &pls->list, local_list) { /* Prepare next buffer: */ - if (!buf) { + if (!skb) { msg_rem = min_t(uint, rem, msg_dsz); rem -= msg_rem; - buf = named_prepare_buf(PUBLICATION, msg_rem, dnode); - if (!buf) { + skb = named_prepare_buf(PUBLICATION, msg_rem, dnode); + if (!skb) { pr_warn("Bulk publication failure\n"); return; } - item = (struct distr_item *)msg_data(buf_msg(buf)); + item = (struct distr_item *)msg_data(buf_msg(skb)); } /* Pack publication into message: */ @@ -225,8 +225,8 @@ static void named_distribute(struct list_head *msg_list, u32 dnode, /* Append full buffer to list: */ if (!msg_rem) { - list_add_tail((struct list_head *)buf, msg_list); - buf = NULL; + __skb_queue_tail(list, skb); + skb = NULL; } } } @@ -236,18 +236,16 @@ static void named_distribute(struct list_head *msg_list, u32 dnode, */ void tipc_named_node_up(u32 dnode) { - LIST_HEAD(msg_list); - struct sk_buff *buf_chain; + struct sk_buff_head head; + + __skb_queue_head_init(&head); read_lock_bh(&tipc_nametbl_lock); - named_distribute(&msg_list, dnode, &publ_cluster); - named_distribute(&msg_list, dnode, &publ_zone); + named_distribute(&head, dnode, &publ_cluster); + named_distribute(&head, dnode, &publ_zone); read_unlock_bh(&tipc_nametbl_lock); - /* Convert circular list to linear list and send: */ - buf_chain = (struct sk_buff *)msg_list.next; - ((struct sk_buff *)msg_list.prev)->next = NULL; - tipc_link_xmit(buf_chain, dnode, dnode); + tipc_link_xmit(&head, dnode, dnode); } static void tipc_publ_subscribe(struct publication *publ, u32 addr) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 341fbd1b5f74..9658d9b63876 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -244,12 +244,12 @@ static void tsk_advance_rx_queue(struct sock *sk) */ static void tsk_rej_rx_queue(struct sock *sk) { - struct sk_buff *buf; + struct sk_buff *skb; u32 dnode; - while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { - if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) - tipc_link_xmit(buf, dnode, 0); + while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { + if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) + tipc_link_xmit_skb(skb, dnode, 0); } } @@ -462,7 +462,7 @@ static int tipc_release(struct socket *sock) { struct sock *sk = sock->sk; struct tipc_sock *tsk; - struct sk_buff *buf; + struct sk_buff *skb; u32 dnode; /* @@ -481,11 +481,11 @@ static int tipc_release(struct socket *sock) */ dnode = tsk_peer_node(tsk); while (sock->state != SS_DISCONNECTING) { - buf = __skb_dequeue(&sk->sk_receive_queue); - if (buf == NULL) + skb = __skb_dequeue(&sk->sk_receive_queue); + if (skb == NULL) break; - if (TIPC_SKB_CB(buf)->handle != NULL) - kfree_skb(buf); + if (TIPC_SKB_CB(skb)->handle != NULL) + kfree_skb(skb); else { if ((sock->state == SS_CONNECTING) || (sock->state == SS_CONNECTED)) { @@ -493,8 +493,8 @@ static int tipc_release(struct socket *sock) tsk->connected = 0; tipc_node_remove_conn(dnode, tsk->ref); } - if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) - tipc_link_xmit(buf, dnode, 0); + if (tipc_msg_reverse(skb, &dnode, TIPC_ERR_NO_PORT)) + tipc_link_xmit_skb(skb, dnode, 0); } } @@ -502,12 +502,12 @@ static int tipc_release(struct socket *sock) tipc_sk_ref_discard(tsk->ref); k_cancel_timer(&tsk->timer); if (tsk->connected) { - buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, + skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, tipc_own_addr, tsk_peer_port(tsk), tsk->ref, TIPC_ERR_NO_PORT); - if (buf) - tipc_link_xmit(buf, dnode, tsk->ref); + if (skb) + tipc_link_xmit_skb(skb, dnode, tsk->ref); tipc_node_remove_conn(dnode, tsk->ref); } k_term_timer(&tsk->timer); @@ -712,7 +712,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, { struct sock *sk = sock->sk; struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; - struct sk_buff *buf; + struct sk_buff_head head; uint mtu; int rc; @@ -727,12 +727,13 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, new_mtu: mtu = tipc_bclink_get_mtu(); - rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf); + __skb_queue_head_init(&head); + rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &head); if (unlikely(rc < 0)) return rc; do { - rc = tipc_bclink_xmit(buf); + rc = tipc_bclink_xmit(&head); if (likely(rc >= 0)) { rc = dsz; break; @@ -744,7 +745,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, tipc_sk(sk)->link_cong = 1; rc = tipc_wait_for_sndmsg(sock, &timeo); if (rc) - kfree_skb_list(buf); + __skb_queue_purge(&head); } while (!rc); return rc; } @@ -906,7 +907,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, struct tipc_sock *tsk = tipc_sk(sk); struct tipc_msg *mhdr = &tsk->phdr; u32 dnode, dport; - struct sk_buff *buf; + struct sk_buff_head head; + struct sk_buff *skb; struct tipc_name_seq *seq = &dest->addr.nameseq; u32 mtu; long timeo; @@ -981,13 +983,15 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, new_mtu: mtu = tipc_node_get_mtu(dnode, tsk->ref); - rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf); + __skb_queue_head_init(&head); + rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &head); if (rc < 0) goto exit; do { - TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong; - rc = tipc_link_xmit(buf, dnode, tsk->ref); + skb = skb_peek(&head); + TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; + rc = tipc_link_xmit(&head, dnode, tsk->ref); if (likely(rc >= 0)) { if (sock->state != SS_READY) sock->state = SS_CONNECTING; @@ -1001,7 +1005,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, tsk->link_cong = 1; rc = tipc_wait_for_sndmsg(sock, &timeo); if (rc) - kfree_skb_list(buf); + __skb_queue_purge(&head); } while (!rc); exit: if (iocb) @@ -1058,7 +1062,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; struct tipc_sock *tsk = tipc_sk(sk); struct tipc_msg *mhdr = &tsk->phdr; - struct sk_buff *buf; + struct sk_buff_head head; DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); u32 ref = tsk->ref; int rc = -EINVAL; @@ -1093,12 +1097,13 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, next: mtu = tsk->max_pkt; send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); - rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf); + __skb_queue_head_init(&head); + rc = tipc_msg_build(mhdr, m, sent, send, mtu, &head); if (unlikely(rc < 0)) goto exit; do { if (likely(!tsk_conn_cong(tsk))) { - rc = tipc_link_xmit(buf, dnode, ref); + rc = tipc_link_xmit(&head, dnode, ref); if (likely(!rc)) { tsk->sent_unacked++; sent += send; @@ -1116,7 +1121,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, } rc = tipc_wait_for_sndpkt(sock, &timeo); if (rc) - kfree_skb_list(buf); + __skb_queue_purge(&head); } while (!rc); exit: if (iocb) @@ -1261,20 +1266,20 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg, static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack) { - struct sk_buff *buf = NULL; + struct sk_buff *skb = NULL; struct tipc_msg *msg; u32 peer_port = tsk_peer_port(tsk); u32 dnode = tsk_peer_node(tsk); if (!tsk->connected) return; - buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode, + skb = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode, tipc_own_addr, peer_port, tsk->ref, TIPC_OK); - if (!buf) + if (!skb) return; - msg = buf_msg(buf); + msg = buf_msg(skb); msg_set_msgcnt(msg, ack); - tipc_link_xmit(buf, dnode, msg_link_selector(msg)); + tipc_link_xmit_skb(skb, dnode, msg_link_selector(msg)); } static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) @@ -1729,20 +1734,20 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf) /** * tipc_backlog_rcv - handle incoming message from backlog queue * @sk: socket - * @buf: message + * @skb: message * * Caller must hold socket lock, but not port lock. * * Returns 0 */ -static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) +static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) { int rc; u32 onode; struct tipc_sock *tsk = tipc_sk(sk); - uint truesize = buf->truesize; + uint truesize = skb->truesize; - rc = filter_rcv(sk, buf); + rc = filter_rcv(sk, skb); if (likely(!rc)) { if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) @@ -1750,25 +1755,25 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) return 0; } - if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc)) + if ((rc < 0) && !tipc_msg_reverse(skb, &onode, -rc)) return 0; - tipc_link_xmit(buf, onode, 0); + tipc_link_xmit_skb(skb, onode, 0); return 0; } /** * tipc_sk_rcv - handle incoming message - * @buf: buffer containing arriving message + * @skb: buffer containing arriving message * Consumes buffer * Returns 0 if success, or errno: -EHOSTUNREACH */ -int tipc_sk_rcv(struct sk_buff *buf) +int tipc_sk_rcv(struct sk_buff *skb) { struct tipc_sock *tsk; struct sock *sk; - u32 dport = msg_destport(buf_msg(buf)); + u32 dport = msg_destport(buf_msg(skb)); int rc = TIPC_OK; uint limit; u32 dnode; @@ -1776,7 +1781,7 @@ int tipc_sk_rcv(struct sk_buff *buf) /* Validate destination and message */ tsk = tipc_sk_get(dport); if (unlikely(!tsk)) { - rc = tipc_msg_eval(buf, &dnode); + rc = tipc_msg_eval(skb, &dnode); goto exit; } sk = &tsk->sk; @@ -1785,12 +1790,12 @@ int tipc_sk_rcv(struct sk_buff *buf) spin_lock_bh(&sk->sk_lock.slock); if (!sock_owned_by_user(sk)) { - rc = filter_rcv(sk, buf); + rc = filter_rcv(sk, skb); } else { if (sk->sk_backlog.len == 0) atomic_set(&tsk->dupl_rcvcnt, 0); - limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt); - if (sk_add_backlog(sk, buf, limit)) + limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt); + if (sk_add_backlog(sk, skb, limit)) rc = -TIPC_ERR_OVERLOAD; } spin_unlock_bh(&sk->sk_lock.slock); @@ -1798,10 +1803,10 @@ int tipc_sk_rcv(struct sk_buff *buf) if (likely(!rc)) return 0; exit: - if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc)) + if ((rc < 0) && !tipc_msg_reverse(skb, &dnode, -rc)) return -EHOSTUNREACH; - tipc_link_xmit(buf, dnode, 0); + tipc_link_xmit_skb(skb, dnode, 0); return (rc < 0) ? -EHOSTUNREACH : 0; } @@ -2059,7 +2064,7 @@ static int tipc_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; struct tipc_sock *tsk = tipc_sk(sk); - struct sk_buff *buf; + struct sk_buff *skb; u32 dnode; int res; @@ -2074,23 +2079,23 @@ static int tipc_shutdown(struct socket *sock, int how) restart: /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ - buf = __skb_dequeue(&sk->sk_receive_queue); - if (buf) { - if (TIPC_SKB_CB(buf)->handle != NULL) { - kfree_skb(buf); + skb = __skb_dequeue(&sk->sk_receive_queue); + if (skb) { + if (TIPC_SKB_CB(skb)->handle != NULL) { + kfree_skb(skb); goto restart; } - if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN)) - tipc_link_xmit(buf, dnode, tsk->ref); + if (tipc_msg_reverse(skb, &dnode, TIPC_CONN_SHUTDOWN)) + tipc_link_xmit_skb(skb, dnode, tsk->ref); tipc_node_remove_conn(dnode, tsk->ref); } else { dnode = tsk_peer_node(tsk); - buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, + skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode, tipc_own_addr, tsk_peer_port(tsk), tsk->ref, TIPC_CONN_SHUTDOWN); - tipc_link_xmit(buf, dnode, tsk->ref); + tipc_link_xmit_skb(skb, dnode, tsk->ref); } tsk->connected = 0; sock->state = SS_DISCONNECTING; @@ -2119,7 +2124,7 @@ static void tipc_sk_timeout(unsigned long ref) { struct tipc_sock *tsk; struct sock *sk; - struct sk_buff *buf = NULL; + struct sk_buff *skb = NULL; u32 peer_port, peer_node; tsk = tipc_sk_get(ref); @@ -2137,20 +2142,20 @@ static void tipc_sk_timeout(unsigned long ref) if (tsk->probing_state == TIPC_CONN_PROBING) { /* Previous probe not answered -> self abort */ - buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, + skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, SHORT_H_SIZE, 0, tipc_own_addr, peer_node, ref, peer_port, TIPC_ERR_NO_PORT); } else { - buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, + skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE, 0, peer_node, tipc_own_addr, peer_port, ref, TIPC_OK); tsk->probing_state = TIPC_CONN_PROBING; k_start_timer(&tsk->timer, tsk->probing_interval); } bh_unlock_sock(sk); - if (buf) - tipc_link_xmit(buf, peer_node, ref); + if (skb) + tipc_link_xmit_skb(skb, peer_node, ref); exit: tipc_sk_put(tsk); } -- GitLab From 1ae2b01658a5ae00786d4bda191fbf6f38e5dbb0 Mon Sep 17 00:00:00 2001 From: Jeff Chen Date: Tue, 25 Nov 2014 16:13:02 -0800 Subject: [PATCH 6659/9457] clk: rockchip: add binding ID for DMC (memory controller) clocks on rk3288 The DMC clocks need to be turned off at runtime, so we should have IDs so we can export them. Signed-off-by: Jeff Chen [dianders: split into two patches; adjusted commit msg] Signed-off-by: Doug Anderson Signed-off-by: Heiko Stuebner --- include/dt-bindings/clock/rk3288-cru.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index 100a08c47692..8e19ed58db33 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -141,6 +141,10 @@ #define PCLK_VIO2_H2P 361 #define PCLK_CPU 362 #define PCLK_PERI 363 +#define PCLK_DDRUPCTL0 364 +#define PCLK_PUBL0 365 +#define PCLK_DDRUPCTL1 366 +#define PCLK_PUBL1 367 /* hclk gates */ #define HCLK_GPS 448 -- GitLab From a72da7c1666b4464f1610fb9e90ac64ca2ea7a44 Mon Sep 17 00:00:00 2001 From: Jeff Chen Date: Tue, 25 Nov 2014 16:13:03 -0800 Subject: [PATCH 6660/9457] clk: rockchip: use clock ID for DMC (memory controller) on rk3288 The DMC clocks need to be turned off at runtime. Use the newly assigned clock IDs to export them. Signed-off-by: Jeff Chen [dianders: split into two patches; adjusted commit msg] Signed-off-by: Doug Anderson Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index ad8a27a9cd50..232809725c55 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -625,10 +625,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), - GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), - GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), - GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), - GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), + GATE(PCLK_DDRUPCTL0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), + GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), + GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), -- GitLab From 3bb30a7cdf9242aca90d49aa41baebf9458f96f0 Mon Sep 17 00:00:00 2001 From: Dmitry Tunin Date: Tue, 25 Nov 2014 20:19:52 +0300 Subject: [PATCH 6661/9457] Bluetooth: ath3k: Add support of MCI 13d3:3408 bt device Add support for Bluetooth MCI WB335 (AR9565) Wi-Fi+bt module. This Bluetooth module requires loading patch and sysconfig by ath3k driver. T: Bus=01 Lev=02 Prnt=03 Port=00 Cnt=01 Dev#= 20 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3408 Rev= 0.02 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Dmitry Tunin Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 25c874da5f2b..fce758896280 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -106,6 +106,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x13d3, 0x3393) }, { USB_DEVICE(0x13d3, 0x3402) }, + { USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3432) }, /* Atheros AR5BBU12 with sflash firmware */ @@ -158,6 +159,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7c13d7a8d83c..9efdace85e15 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -185,6 +185,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ -- GitLab From e5262d0568dc9e10de79a726dfd7edb712a2c10b Mon Sep 17 00:00:00 2001 From: Weike Chen Date: Wed, 26 Nov 2014 02:35:10 -0800 Subject: [PATCH 6662/9457] spi: spi-pxa2xx: SPI support for Intel Quark X1000 There are two SPI controllers exported by PCI subsystem for Intel Quark X1000. The SPI memory mapped I/O registers supported by Quark are different from the current implementation, and Quark only supports the registers of 'SSCR0', 'SSCR1', 'SSSR', 'SSDR', and 'DDS_RATE'. This patch is to enable the SPI for Intel Quark X1000. This piece of work is derived from Dan O'Donovan's initial work for Intel Quark X1000 SPI enabling. Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Weike Chen Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 8 ++ drivers/spi/spi-pxa2xx.c | 197 ++++++++++++++++++++++++++++++++--- drivers/spi/spi-pxa2xx.h | 16 ++- include/linux/pxa2xx_ssp.h | 20 ++++ 4 files changed, 219 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 6beee8ce2d68..fa7399e84bbb 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -19,6 +19,7 @@ enum { PORT_BSW0, PORT_BSW1, PORT_BSW2, + PORT_QUARK_X1000, }; struct pxa_spi_info { @@ -92,6 +93,12 @@ static struct pxa_spi_info spi_info_configs[] = { .tx_param = &bsw2_tx_param, .rx_param = &bsw2_rx_param, }, + [PORT_QUARK_X1000] = { + .type = QUARK_X1000_SSP, + .port_id = -1, + .num_chipselect = 1, + .max_clk_rate = 50000000, + }, }; static int pxa2xx_spi_pci_probe(struct pci_dev *dev, @@ -191,6 +198,7 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) static const struct pci_device_id pxa2xx_spi_pci_devices[] = { { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, + { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index d4d29c594156..1a1df5092aca 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -63,10 +63,64 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) +#define QUARK_X1000_SSCR1_CHANGE_MASK (QUARK_X1000_SSCR1_STRF \ + | QUARK_X1000_SSCR1_EFWR \ + | QUARK_X1000_SSCR1_RFT \ + | QUARK_X1000_SSCR1_TFT \ + | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) + #define LPSS_RX_THRESH_DFLT 64 #define LPSS_TX_LOTHRESH_DFLT 160 #define LPSS_TX_HITHRESH_DFLT 224 +struct quark_spi_rate { + u32 bitrate; + u32 dds_clk_rate; + u32 clk_div; +}; + +/* + * 'rate', 'dds', 'clk_div' lookup table, which is defined in + * the Quark SPI datasheet. + */ +static const struct quark_spi_rate quark_spi_rate_table[] = { +/* bitrate, dds_clk_rate, clk_div */ + {50000000, 0x800000, 0}, + {40000000, 0x666666, 0}, + {25000000, 0x400000, 0}, + {20000000, 0x666666, 1}, + {16667000, 0x800000, 2}, + {13333000, 0x666666, 2}, + {12500000, 0x200000, 0}, + {10000000, 0x800000, 4}, + {8000000, 0x666666, 4}, + {6250000, 0x400000, 3}, + {5000000, 0x400000, 4}, + {4000000, 0x666666, 9}, + {3125000, 0x80000, 0}, + {2500000, 0x400000, 9}, + {2000000, 0x666666, 19}, + {1563000, 0x40000, 0}, + {1250000, 0x200000, 9}, + {1000000, 0x400000, 24}, + {800000, 0x666666, 49}, + {781250, 0x20000, 0}, + {625000, 0x200000, 19}, + {500000, 0x400000, 49}, + {400000, 0x666666, 99}, + {390625, 0x10000, 0}, + {250000, 0x400000, 99}, + {200000, 0x666666, 199}, + {195313, 0x8000, 0}, + {125000, 0x100000, 49}, + {100000, 0x200000, 124}, + {50000, 0x100000, 124}, + {25000, 0x80000, 124}, + {10016, 0x20000, 77}, + {5040, 0x20000, 154}, + {1002, 0x8000, 194}, +}; + /* Offset from drv_data->lpss_base */ #define GENERAL_REG 0x08 #define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) @@ -80,9 +134,16 @@ static bool is_lpss_ssp(const struct driver_data *drv_data) return drv_data->ssp_type == LPSS_SSP; } +static bool is_quark_x1000_ssp(const struct driver_data *drv_data) +{ + return drv_data->ssp_type == QUARK_X1000_SSP; +} + static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) { switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + return QUARK_X1000_SSCR1_CHANGE_MASK; default: return SSCR1_CHANGE_MASK; } @@ -92,6 +153,8 @@ static u32 pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data) { switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + return RX_THRESH_QUARK_X1000_DFLT; default: return RX_THRESH_DFLT; } @@ -103,6 +166,9 @@ static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data) u32 mask; switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + mask = QUARK_X1000_SSSR_TFL_MASK; + break; default: mask = SSSR_TFL_MASK; break; @@ -117,6 +183,9 @@ static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data, u32 mask; switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + mask = QUARK_X1000_SSCR1_RFT; + break; default: mask = SSCR1_RFT; break; @@ -128,6 +197,9 @@ static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data, u32 *sccr1_reg, u32 threshold) { switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + *sccr1_reg |= QUARK_X1000_SSCR1_RxTresh(threshold); + break; default: *sccr1_reg |= SSCR1_RxTresh(threshold); break; @@ -138,6 +210,11 @@ static u32 pxa2xx_configure_sscr0(const struct driver_data *drv_data, u32 clk_div, u8 bits) { switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + return clk_div + | QUARK_X1000_SSCR0_Motorola + | QUARK_X1000_SSCR0_DataSize(bits > 32 ? 8 : bits) + | SSCR0_SSE; default: return clk_div | SSCR0_Motorola @@ -654,6 +731,28 @@ static irqreturn_t ssp_int(int irq, void *dev_id) return drv_data->transfer_handler(drv_data); } +/* + * The Quark SPI data sheet gives a table, and for the given 'rate', + * the 'dds' and 'clk_div' can be found in the table. + */ +static u32 quark_x1000_set_clk_regvals(u32 rate, u32 *dds, u32 *clk_div) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(quark_spi_rate_table); i++) { + if (rate >= quark_spi_rate_table[i].bitrate) { + *dds = quark_spi_rate_table[i].dds_clk_rate; + *clk_div = quark_spi_rate_table[i].clk_div; + return quark_spi_rate_table[i].bitrate; + } + } + + *dds = quark_spi_rate_table[i-1].dds_clk_rate; + *clk_div = quark_spi_rate_table[i-1].clk_div; + + return quark_spi_rate_table[i-1].bitrate; +} + static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) { unsigned long ssp_clk = drv_data->max_clk_rate; @@ -667,6 +766,20 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) return ((ssp_clk / rate - 1) & 0xfff) << 8; } +static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, + struct chip_data *chip, int rate) +{ + u32 clk_div; + + switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + quark_x1000_set_clk_regvals(rate, &chip->dds_rate, &clk_div); + return clk_div << 8; + default: + return ssp_get_clk_div(drv_data, rate); + } +} + static void pump_transfers(unsigned long data) { struct driver_data *drv_data = (struct driver_data *)data; @@ -769,7 +882,7 @@ static void pump_transfers(unsigned long data) if (transfer->bits_per_word) bits = transfer->bits_per_word; - clk_div = ssp_get_clk_div(drv_data, speed); + clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, speed); if (bits <= 8) { drv_data->n_bytes = 1; @@ -837,6 +950,10 @@ static void pump_transfers(unsigned long data) write_SSITF(chip->lpss_tx_threshold, reg); } + if (is_quark_x1000_ssp(drv_data) && + (read_DDS_RATE(reg) != chip->dds_rate)) + write_DDS_RATE(chip->dds_rate, reg); + /* see if we need to reload the config registers */ if ((read_SSCR0(reg) != cr0) || (read_SSCR1(reg) & change_mask) != (cr1 & change_mask)) { @@ -940,14 +1057,22 @@ static int setup(struct spi_device *spi) unsigned int clk_div; uint tx_thres, tx_hi_thres, rx_thres; - if (is_lpss_ssp(drv_data)) { + switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + tx_thres = TX_THRESH_QUARK_X1000_DFLT; + tx_hi_thres = 0; + rx_thres = RX_THRESH_QUARK_X1000_DFLT; + break; + case LPSS_SSP: tx_thres = LPSS_TX_LOTHRESH_DFLT; tx_hi_thres = LPSS_TX_HITHRESH_DFLT; rx_thres = LPSS_RX_THRESH_DFLT; - } else { + break; + default: tx_thres = TX_THRESH_DFLT; tx_hi_thres = 0; rx_thres = RX_THRESH_DFLT; + break; } /* Only alloc on first setup */ @@ -1000,9 +1125,6 @@ static int setup(struct spi_device *spi) chip->enable_dma = drv_data->master_info->enable_dma; } - chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | - (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); - chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres); chip->lpss_tx_threshold = SSITF_TxLoThresh(tx_thres) | SSITF_TxHiThresh(tx_hi_thres); @@ -1021,11 +1143,24 @@ static int setup(struct spi_device *spi) } } - clk_div = ssp_get_clk_div(drv_data, spi->max_speed_hz); + clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, spi->max_speed_hz); chip->speed_hz = spi->max_speed_hz; chip->cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, spi->bits_per_word); + switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + chip->threshold = (QUARK_X1000_SSCR1_RxTresh(rx_thres) + & QUARK_X1000_SSCR1_RFT) + | (QUARK_X1000_SSCR1_TxTresh(tx_thres) + & QUARK_X1000_SSCR1_TFT); + break; + default: + chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) | + (SSCR1_TxTresh(tx_thres) & SSCR1_TFT); + break; + } + chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); @@ -1054,7 +1189,8 @@ static int setup(struct spi_device *spi) chip->read = u16_reader; chip->write = u16_writer; } else if (spi->bits_per_word <= 32) { - chip->cr0 |= SSCR0_EDSS; + if (!is_quark_x1000_ssp(drv_data)) + chip->cr0 |= SSCR0_EDSS; chip->n_bytes = 4; chip->read = u32_reader; chip->write = u32_writer; @@ -1205,7 +1341,15 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) drv_data->ioaddr = ssp->mmio_base; drv_data->ssdr_physical = ssp->phys_base + SSDR; if (pxa25x_ssp_comp(drv_data)) { - master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); + switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); + break; + default: + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); + break; + } + drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; drv_data->dma_cr1 = 0; drv_data->clear_sr = SSSR_ROR; @@ -1243,16 +1387,35 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) /* Load default SSP configuration */ write_SSCR0(0, drv_data->ioaddr); - write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) | - SSCR1_TxTresh(TX_THRESH_DFLT), - drv_data->ioaddr); - write_SSCR0(SSCR0_SCR(2) - | SSCR0_Motorola - | SSCR0_DataSize(8), - drv_data->ioaddr); + switch (drv_data->ssp_type) { + case QUARK_X1000_SSP: + write_SSCR1(QUARK_X1000_SSCR1_RxTresh( + RX_THRESH_QUARK_X1000_DFLT) | + QUARK_X1000_SSCR1_TxTresh( + TX_THRESH_QUARK_X1000_DFLT), + drv_data->ioaddr); + + /* using the Motorola SPI protocol and use 8 bit frame */ + write_SSCR0(QUARK_X1000_SSCR0_Motorola + | QUARK_X1000_SSCR0_DataSize(8), + drv_data->ioaddr); + break; + default: + write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) | + SSCR1_TxTresh(TX_THRESH_DFLT), + drv_data->ioaddr); + write_SSCR0(SSCR0_SCR(2) + | SSCR0_Motorola + | SSCR0_DataSize(8), + drv_data->ioaddr); + break; + } + if (!pxa25x_ssp_comp(drv_data)) write_SSTO(0, drv_data->ioaddr); - write_SSPSP(0, drv_data->ioaddr); + + if (!is_quark_x1000_ssp(drv_data)) + write_SSPSP(0, drv_data->ioaddr); lpss_ssp_setup(drv_data); diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 5adc2a11c7bc..6bec59c90cd4 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -93,6 +93,7 @@ struct driver_data { struct chip_data { u32 cr0; u32 cr1; + u32 dds_rate; u32 psp; u32 timeout; u8 n_bytes; @@ -126,6 +127,7 @@ DEFINE_SSP_REG(SSCR1, 0x04) DEFINE_SSP_REG(SSSR, 0x08) DEFINE_SSP_REG(SSITR, 0x0c) DEFINE_SSP_REG(SSDR, 0x10) +DEFINE_SSP_REG(DDS_RATE, 0x28) /* DDS Clock Rate */ DEFINE_SSP_REG(SSTO, 0x28) DEFINE_SSP_REG(SSPSP, 0x2c) DEFINE_SSP_REG(SSITF, SSITF) @@ -141,18 +143,22 @@ DEFINE_SSP_REG(SSIRF, SSIRF) static inline int pxa25x_ssp_comp(struct driver_data *drv_data) { - if (drv_data->ssp_type == PXA25x_SSP) + switch (drv_data->ssp_type) { + case PXA25x_SSP: + case CE4100_SSP: + case QUARK_X1000_SSP: return 1; - if (drv_data->ssp_type == CE4100_SSP) - return 1; - return 0; + default: + return 0; + } } static inline void write_SSSR_CS(struct driver_data *drv_data, u32 val) { void __iomem *reg = drv_data->ioaddr; - if (drv_data->ssp_type == CE4100_SSP) + if (drv_data->ssp_type == CE4100_SSP || + drv_data->ssp_type == QUARK_X1000_SSP) val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK; write_SSSR(val, reg); diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index f2b405116166..77aed9ea1d26 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -108,6 +108,25 @@ #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ #endif +/* QUARK_X1000 SSCR0 bit definition */ +#define QUARK_X1000_SSCR0_DSS (0x1F) /* Data Size Select (mask) */ +#define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */ +#define QUARK_X1000_SSCR0_FRF (0x3 << 5) /* FRame Format (mask) */ +#define QUARK_X1000_SSCR0_Motorola (0x0 << 5) /* Motorola's Serial Peripheral Interface (SPI) */ + +#define RX_THRESH_QUARK_X1000_DFLT 1 +#define TX_THRESH_QUARK_X1000_DFLT 16 + +#define QUARK_X1000_SSSR_TFL_MASK (0x1F << 8) /* Transmit FIFO Level mask */ +#define QUARK_X1000_SSSR_RFL_MASK (0x1F << 13) /* Receive FIFO Level mask */ + +#define QUARK_X1000_SSCR1_TFT (0x1F << 6) /* Transmit FIFO Threshold (mask) */ +#define QUARK_X1000_SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..32] */ +#define QUARK_X1000_SSCR1_RFT (0x1F << 11) /* Receive FIFO Threshold (mask) */ +#define QUARK_X1000_SSCR1_RxTresh(x) (((x) - 1) << 11) /* level [1..32] */ +#define QUARK_X1000_SSCR1_STRF (1 << 17) /* Select FIFO or EFWR */ +#define QUARK_X1000_SSCR1_EFWR (1 << 16) /* Enable FIFO Write/Read */ + /* extra bits in PXA255, PXA26x and PXA27x SSP ports */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ @@ -175,6 +194,7 @@ enum pxa_ssp_type { PXA910_SSP, CE4100_SSP, LPSS_SSP, + QUARK_X1000_SSP, }; struct ssp_device { -- GitLab From 6512f5fb0a28e26f473085b890ada519e0f37d70 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 23 Nov 2014 14:11:17 +0100 Subject: [PATCH 6663/9457] drm: rcar-du: fix error return code Propagate the error code on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier ret; expression e1,e2; @@ ( if (\(ret < 0\|ret != 0\)) { ... return ret; } | ret = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 088bfd875d29..23cc910951f4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -586,7 +586,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) if (irq < 0) { dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index); - return ret; + return irq; } ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags, -- GitLab From 2378ad1228d2cdae0ea5448beb4fb2b42ebaf99c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 17 Sep 2014 02:07:52 +0300 Subject: [PATCH 6664/9457] drm: rcar-du: Remove platform data support All platforms now instantiate the DU through DT, platform data support isn't needed anymore. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 10 ++- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 - drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 8 +-- drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 10 ++- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 52 +++------------- drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 26 ++++---- drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h | 2 - drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h | 1 - include/linux/platform_data/rcar-du.h | 74 ----------------------- 10 files changed, 38 insertions(+), 151 deletions(-) delete mode 100644 include/linux/platform_data/rcar-du.h diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index e97ae502dec5..984e6083699f 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -15,7 +15,6 @@ #define __RCAR_DU_CRTC_H__ #include -#include #include #include @@ -41,6 +40,15 @@ struct rcar_du_crtc { #define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) +enum rcar_du_output { + RCAR_DU_OUTPUT_DPAD0, + RCAR_DU_OUTPUT_DPAD1, + RCAR_DU_OUTPUT_LVDS0, + RCAR_DU_OUTPUT_LVDS1, + RCAR_DU_OUTPUT_TCON, + RCAR_DU_OUTPUT_MAX, +}; + int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index d212efa6a495..967ae8f20233 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -146,12 +146,11 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) { struct platform_device *pdev = dev->platformdev; struct device_node *np = pdev->dev.of_node; - struct rcar_du_platform_data *pdata = pdev->dev.platform_data; struct rcar_du_device *rcdu; struct resource *mem; int ret; - if (pdata == NULL && np == NULL) { + if (np == NULL) { dev_err(dev->dev, "no platform data\n"); return -ENODEV; } @@ -163,7 +162,6 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) } rcdu->dev = &pdev->dev; - rcdu->pdata = pdata; rcdu->info = np ? of_match_device(rcar_du_of_table, rcdu->dev)->data : (void *)platform_get_device_id(pdev)->driver_data; rcdu->ddev = dev; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 8e494633c3b3..0a724669f02d 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h @@ -15,7 +15,6 @@ #define __RCAR_DU_DRV_H__ #include -#include #include "rcar_du_crtc.h" #include "rcar_du_group.h" @@ -67,7 +66,6 @@ struct rcar_du_device_info { struct rcar_du_device { struct device *dev; - const struct rcar_du_platform_data *pdata; const struct rcar_du_device_info *info; void __iomem *mmio; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index 7c0ec95915ef..89ed4a929f7b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -142,7 +142,6 @@ static const struct drm_encoder_funcs encoder_funcs = { int rcar_du_encoder_init(struct rcar_du_device *rcdu, enum rcar_du_encoder_type type, enum rcar_du_output output, - const struct rcar_du_encoder_data *data, struct device_node *np) { struct rcar_du_encoder *renc; @@ -190,11 +189,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); switch (encoder_type) { - case DRM_MODE_ENCODER_LVDS: { - const struct rcar_du_panel_data *pdata = - data ? &data->connector.lvds.panel : NULL; - return rcar_du_lvds_connector_init(rcdu, renc, pdata, np); - } + case DRM_MODE_ENCODER_LVDS: + return rcar_du_lvds_connector_init(rcdu, renc, np); case DRM_MODE_ENCODER_DAC: return rcar_du_vga_connector_init(rcdu, renc); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h index bd624135ef1f..c37ed9499542 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h @@ -14,13 +14,18 @@ #ifndef __RCAR_DU_ENCODER_H__ #define __RCAR_DU_ENCODER_H__ -#include - #include struct rcar_du_device; struct rcar_du_lvdsenc; +enum rcar_du_encoder_type { + RCAR_DU_ENCODER_UNUSED = 0, + RCAR_DU_ENCODER_NONE, + RCAR_DU_ENCODER_VGA, + RCAR_DU_ENCODER_LVDS, +}; + struct rcar_du_encoder { struct drm_encoder encoder; enum rcar_du_output output; @@ -44,7 +49,6 @@ rcar_du_connector_best_encoder(struct drm_connector *connector); int rcar_du_encoder_init(struct rcar_du_device *rcdu, enum rcar_du_encoder_type type, enum rcar_du_output output, - const struct rcar_du_encoder_data *data, struct device_node *np); #endif /* __RCAR_DU_ENCODER_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 6289e3797bc5..704827269a2e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -190,43 +190,9 @@ static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { .output_poll_changed = rcar_du_output_poll_changed, }; -static int rcar_du_encoders_init_pdata(struct rcar_du_device *rcdu) -{ - unsigned int num_encoders = 0; - unsigned int i; - int ret; - - for (i = 0; i < rcdu->pdata->num_encoders; ++i) { - const struct rcar_du_encoder_data *pdata = - &rcdu->pdata->encoders[i]; - const struct rcar_du_output_routing *route = - &rcdu->info->routes[pdata->output]; - - if (pdata->type == RCAR_DU_ENCODER_UNUSED) - continue; - - if (pdata->output >= RCAR_DU_OUTPUT_MAX || - route->possible_crtcs == 0) { - dev_warn(rcdu->dev, - "encoder %u references unexisting output %u, skipping\n", - i, pdata->output); - continue; - } - - ret = rcar_du_encoder_init(rcdu, pdata->type, pdata->output, - pdata, NULL); - if (ret < 0) - return ret; - - num_encoders++; - } - - return num_encoders; -} - -static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu, - enum rcar_du_output output, - struct of_endpoint *ep) +static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, + enum rcar_du_output output, + struct of_endpoint *ep) { static const struct { const char *compatible; @@ -323,14 +289,14 @@ static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu, connector = entity; } - ret = rcar_du_encoder_init(rcdu, enc_type, output, NULL, connector); + ret = rcar_du_encoder_init(rcdu, enc_type, output, connector); of_node_put(encoder); of_node_put(connector); return ret < 0 ? ret : 1; } -static int rcar_du_encoders_init_dt(struct rcar_du_device *rcdu) +static int rcar_du_encoders_init(struct rcar_du_device *rcdu) { struct device_node *np = rcdu->dev->of_node; struct device_node *prev = NULL; @@ -377,7 +343,7 @@ static int rcar_du_encoders_init_dt(struct rcar_du_device *rcdu) } /* Process the output pipeline. */ - ret = rcar_du_encoders_init_dt_one(rcdu, output, &ep); + ret = rcar_du_encoders_init_one(rcdu, output, &ep); if (ret < 0) { of_node_put(ep_node); return ret; @@ -442,11 +408,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) if (ret < 0) return ret; - if (rcdu->pdata) - ret = rcar_du_encoders_init_pdata(rcdu); - else - ret = rcar_du_encoders_init_dt(rcdu); - + ret = rcar_du_encoders_init(rcdu); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c index 115eed20db12..80dc02166c88 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c @@ -27,7 +27,11 @@ struct rcar_du_lvds_connector { struct rcar_du_connector connector; - struct rcar_du_panel_data panel; + struct { + unsigned int width_mm; /* Panel width in mm */ + unsigned int height_mm; /* Panel height in mm */ + struct videomode mode; + } panel; }; #define to_rcar_lvds_connector(c) \ @@ -78,31 +82,25 @@ static const struct drm_connector_funcs connector_funcs = { int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, - const struct rcar_du_panel_data *panel, /* TODO const */ struct device_node *np) { struct rcar_du_lvds_connector *lvdscon; struct drm_connector *connector; + struct display_timing timing; int ret; lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL); if (lvdscon == NULL) return -ENOMEM; - if (panel) { - lvdscon->panel = *panel; - } else { - struct display_timing timing; - - ret = of_get_display_timing(np, "panel-timing", &timing); - if (ret < 0) - return ret; + ret = of_get_display_timing(np, "panel-timing", &timing); + if (ret < 0) + return ret; - videomode_from_timing(&timing, &lvdscon->panel.mode); + videomode_from_timing(&timing, &lvdscon->panel.mode); - of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm); - of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm); - } + of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm); + of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm); connector = &lvdscon->connector.connector; connector->display_info.width_mm = lvdscon->panel.width_mm; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h index d11424d537f9..d4881ee0be7e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h @@ -16,11 +16,9 @@ struct rcar_du_device; struct rcar_du_encoder; -struct rcar_du_panel_data; int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, - const struct rcar_du_panel_data *panel, struct device_node *np); #endif /* __RCAR_DU_LVDSCON_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h index 3303a55cec79..f65aabda0796 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h @@ -16,7 +16,6 @@ #include #include -#include struct rcar_drm_crtc; struct rcar_du_lvdsenc; diff --git a/include/linux/platform_data/rcar-du.h b/include/linux/platform_data/rcar-du.h deleted file mode 100644 index a5f045e1d8fe..000000000000 --- a/include/linux/platform_data/rcar-du.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * rcar_du.h -- R-Car Display Unit DRM driver - * - * Copyright (C) 2013 Renesas Corporation - * - * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __RCAR_DU_H__ -#define __RCAR_DU_H__ - -#include